diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/boot/bootp.c linux-libre-2.6.33-gnu1/arch/alpha/boot/bootp.c
--- linux-libre-2.6.32-gnu1/arch/alpha/boot/bootp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/boot/bootp.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/mm.h>
 
 #include <asm/system.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/boot/bootpz.c linux-libre-2.6.33-gnu1/arch/alpha/boot/bootpz.c
--- linux-libre-2.6.32-gnu1/arch/alpha/boot/bootpz.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/boot/bootpz.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,7 +11,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/mm.h>
 
 #include <asm/system.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/boot/main.c linux-libre-2.6.33-gnu1/arch/alpha/boot/main.c
--- linux-libre-2.6.32-gnu1/arch/alpha/boot/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/boot/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/mm.h>
 
 #include <asm/system.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,8 @@
 		"call_pal %0  # bugchk\n\t"				\
 		".long %1\n\t.8byte %2"					\
 		: : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__));	\
-	for ( ; ; ); } while (0)
+	unreachable();							\
+  } while (0)
 
 #define HAVE_ARCH_BUG
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/core_t2.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_t2.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/core_t2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/core_t2.h	2010-02-24 13:52:17.000000000 -0500
@@ -435,7 +435,7 @@ extern inline void t2_outl(u32 b, unsign
 	set_hae(msb); \
 }
 
-extern spinlock_t t2_hae_lock;
+extern raw_spinlock_t t2_hae_lock;
 
 /*
  * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
@@ -448,12 +448,12 @@ __EXTERN_INLINE u8 t2_readb(const volati
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long result, msb;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 	return __kernel_extbl(result, addr & 3);
 }
 
@@ -462,12 +462,12 @@ __EXTERN_INLINE u16 t2_readw(const volat
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long result, msb;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 	return __kernel_extwl(result, addr & 3);
 }
 
@@ -480,12 +480,12 @@ __EXTERN_INLINE u32 t2_readl(const volat
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long result, msb;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 	return result & 0xffffffffUL;
 }
 
@@ -494,14 +494,14 @@ __EXTERN_INLINE u64 t2_readq(const volat
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long r0, r1, work, msb;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	work = (addr << 5) + T2_SPARSE_MEM + 0x18;
 	r0 = *(vuip)(work);
 	r1 = *(vuip)(work + (4 << 5));
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 	return r1 << 32 | r0;
 }
 
@@ -510,13 +510,13 @@ __EXTERN_INLINE void t2_writeb(u8 b, vol
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long msb, w;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	w = __kernel_insbl(b, addr & 3);
 	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 }
 
 __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
@@ -524,13 +524,13 @@ __EXTERN_INLINE void t2_writew(u16 b, vo
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long msb, w;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	w = __kernel_inswl(b, addr & 3);
 	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 }
 
 /*
@@ -542,12 +542,12 @@ __EXTERN_INLINE void t2_writel(u32 b, vo
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long msb;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 }
 
 __EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
@@ -555,14 +555,14 @@ __EXTERN_INLINE void t2_writeq(u64 b, vo
 	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
 	unsigned long msb, work;
 	unsigned long flags;
-	spin_lock_irqsave(&t2_hae_lock, flags);
+	raw_spin_lock_irqsave(&t2_hae_lock, flags);
 
 	t2_set_hae;
 
 	work = (addr << 5) + T2_SPARSE_MEM + 0x18;
 	*(vuip)work = b;
 	*(vuip)(work + (4 << 5)) = b >> 32;
-	spin_unlock_irqrestore(&t2_hae_lock, flags);
+	raw_spin_unlock_irqrestore(&t2_hae_lock, flags);
 }
 
 __EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr)
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
 #define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_ALPHA
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	8192
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/fcntl.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/fcntl.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/fcntl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/fcntl.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,6 @@
 #ifndef _ALPHA_FCNTL_H
 #define _ALPHA_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_CREAT		 01000	/* not fcntl */
 #define O_TRUNC		 02000	/* not fcntl */
 #define O_EXCL		 04000	/* not fcntl */
@@ -10,13 +8,28 @@
 
 #define O_NONBLOCK	 00004
 #define O_APPEND	 00010
-#define O_SYNC		040000
+#define O_DSYNC		040000	/* used to be O_SYNC, see below */
 #define O_DIRECTORY	0100000	/* must be a directory */
 #define O_NOFOLLOW	0200000 /* don't follow links */
 #define O_LARGEFILE	0400000 /* will be set by the kernel on every open */
 #define O_DIRECT	02000000 /* direct disk access - should check with OSF/1 */
 #define O_NOATIME	04000000
 #define O_CLOEXEC	010000000 /* set close_on_exec */
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	020000000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define F_GETLK		7
 #define F_SETLK		8
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/perf_event.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/perf_event.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/perf_event.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/perf_event.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,9 @@
+#ifndef __ASM_ALPHA_PERF_EVENT_H
+#define __ASM_ALPHA_PERF_EVENT_H
+
+/* Alpha only supports software events through this interface. */
+static inline void set_perf_event_pending(void) { }
+
+#define PERF_EVENT_INDEX_OFFSET 0
+
+#endif /* __ASM_ALPHA_PERF_EVENT_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,8 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_RXQ_OVFL             40
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,18 +12,18 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_spin_is_locked(x)	((x)->lock != 0)
-#define __raw_spin_unlock_wait(x) \
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_is_locked(x)	((x)->lock != 0)
+#define arch_spin_unlock_wait(x) \
 		do { cpu_relax(); } while ((x)->lock)
 
-static inline void __raw_spin_unlock(raw_spinlock_t * lock)
+static inline void arch_spin_unlock(arch_spinlock_t * lock)
 {
 	mb();
 	lock->lock = 0;
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t * lock)
+static inline void arch_spin_lock(arch_spinlock_t * lock)
 {
 	long tmp;
 
@@ -43,24 +43,24 @@ static inline void __raw_spin_lock(raw_s
 	: "m"(lock->lock) : "memory");
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	return !test_and_set_bit(0, &lock->lock);
 }
 
 /***********************************************************/
 
-static inline int __raw_read_can_lock(raw_rwlock_t *lock)
+static inline int arch_read_can_lock(arch_rwlock_t *lock)
 {
 	return (lock->lock & 1) == 0;
 }
 
-static inline int __raw_write_can_lock(raw_rwlock_t *lock)
+static inline int arch_write_can_lock(arch_rwlock_t *lock)
 {
 	return lock->lock == 0;
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *lock)
+static inline void arch_read_lock(arch_rwlock_t *lock)
 {
 	long regx;
 
@@ -80,7 +80,7 @@ static inline void __raw_read_lock(raw_r
 	: "m" (*lock) : "memory");
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *lock)
+static inline void arch_write_lock(arch_rwlock_t *lock)
 {
 	long regx;
 
@@ -100,7 +100,7 @@ static inline void __raw_write_lock(raw_
 	: "m" (*lock) : "memory");
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t * lock)
+static inline int arch_read_trylock(arch_rwlock_t * lock)
 {
 	long regx;
 	int success;
@@ -122,7 +122,7 @@ static inline int __raw_read_trylock(raw
 	return success;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t * lock)
+static inline int arch_write_trylock(arch_rwlock_t * lock)
 {
 	long regx;
 	int success;
@@ -144,7 +144,7 @@ static inline int __raw_write_trylock(ra
 	return success;
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t * lock)
+static inline void arch_read_unlock(arch_rwlock_t * lock)
 {
 	long regx;
 	__asm__ __volatile__(
@@ -160,17 +160,17 @@ static inline void __raw_read_unlock(raw
 	: "m" (*lock) : "memory");
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t * lock)
+static inline void arch_write_unlock(arch_rwlock_t * lock)
 {
 	mb();
 	lock->lock = 0;
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#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 linux-libre-2.6.32-gnu1/arch/alpha/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,14 +7,14 @@
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/topology.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/topology.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,9 @@ static const struct cpumask *cpumask_of_
 {
 	int cpu;
 
+	if (node == -1)
+		return cpu_all_mask;
+
 	cpumask_clear(&node_to_cpumask_map[node]);
 
 	for_each_online_cpu(cpu) {
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/alpha/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/alpha/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -247,6 +247,7 @@
 #define __IGNORE_pause
 #define __IGNORE_time
 #define __IGNORE_utime
+#define __IGNORE_umount2
 
 /*
  * Linux-specific system calls begin at 300
@@ -433,10 +434,25 @@
 #define __NR_signalfd			476
 #define __NR_timerfd			477
 #define __NR_eventfd			478
+#define __NR_recvmmsg			479
+#define __NR_fallocate			480
+#define __NR_timerfd_create		481
+#define __NR_timerfd_settime		482
+#define __NR_timerfd_gettime		483
+#define __NR_signalfd4			484
+#define __NR_eventfd2			485
+#define __NR_epoll_create1		486
+#define __NR_dup3			487
+#define __NR_pipe2			488
+#define __NR_inotify_init1		489
+#define __NR_preadv			490
+#define __NR_pwritev			491
+#define __NR_rt_tgsigqueueinfo		492
+#define __NR_perf_event_open		493
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS			479
+#define NR_SYSCALLS			494
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/Kconfig linux-libre-2.6.33-gnu1/arch/alpha/Kconfig
--- linux-libre-2.6.32-gnu1/arch/alpha/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@ config ALPHA
 	select HAVE_IDE
 	select HAVE_OPROFILE
 	select HAVE_SYSCALL_WRAPPERS
+	select HAVE_PERF_EVENTS
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/kernel/core_t2.c linux-libre-2.6.33-gnu1/arch/alpha/kernel/core_t2.c
--- linux-libre-2.6.32-gnu1/arch/alpha/kernel/core_t2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/kernel/core_t2.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@
 # define DBG(args)
 #endif
 
-DEFINE_SPINLOCK(t2_hae_lock);
+DEFINE_RAW_SPINLOCK(t2_hae_lock);
 
 static volatile unsigned int t2_mcheck_any_expected;
 static volatile unsigned int t2_mcheck_last_taken;
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/kernel/irq.c linux-libre-2.6.33-gnu1/arch/alpha/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/alpha/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ show_interrupts(struct seq_file *p, void
 #endif
 
 	if (irq < ACTUAL_NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[irq].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
 		action = irq_desc[irq].action;
 		if (!action) 
 			goto unlock;
@@ -105,7 +105,7 @@ show_interrupts(struct seq_file *p, void
 
 		seq_putc(p, '\n');
 unlock:
-		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
 	} else if (irq == ACTUAL_NR_IRQS) {
 #ifdef CONFIG_SMP
 		seq_puts(p, "IPI: ");
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/kernel/osf_sys.c linux-libre-2.6.33-gnu1/arch/alpha/kernel/osf_sys.c
--- linux-libre-2.6.32-gnu1/arch/alpha/kernel/osf_sys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/kernel/osf_sys.c	2010-02-24 13:52:17.000000000 -0500
@@ -178,25 +178,18 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long,
 		unsigned long, prot, unsigned long, flags, unsigned long, fd,
 		unsigned long, off)
 {
-	struct file *file = NULL;
-	unsigned long ret = -EBADF;
+	unsigned long ret = -EINVAL;
 
 #if 0
 	if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED))
 		printk("%s: unimplemented OSF mmap flags %04lx\n", 
 			current->comm, flags);
 #endif
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	if ((off + PAGE_ALIGN(len)) < off)
+		goto out;
+	if (off & ~PAGE_MASK)
+		goto out;
+	ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
  out:
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/kernel/srm_env.c linux-libre-2.6.33-gnu1/arch/alpha/kernel/srm_env.c
--- linux-libre-2.6.32-gnu1/arch/alpha/kernel/srm_env.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/kernel/srm_env.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <asm/console.h>
 #include <asm/uaccess.h>
 #include <asm/machvec.h>
@@ -79,42 +80,41 @@ static srm_env_t	srm_named_entries[] = {
 static srm_env_t	srm_numbered_entries[256];
 
 
-static int
-srm_env_read(char *page, char **start, off_t off, int count, int *eof,
-		void *data)
+static int srm_env_proc_show(struct seq_file *m, void *v)
 {
-	int		nbytes;
 	unsigned long	ret;
 	srm_env_t	*entry;
+	char		*page;
 
-	if (off != 0) {
-		*eof = 1;
-		return 0;
-	}
+	entry = (srm_env_t *)m->private;
+	page = (char *)__get_free_page(GFP_USER);
+	if (!page)
+		return -ENOMEM;
 
-	entry	= (srm_env_t *) data;
-	ret	= callback_getenv(entry->id, page, count);
+	ret = callback_getenv(entry->id, page, PAGE_SIZE);
 
 	if ((ret >> 61) == 0) {
-		nbytes = (int) ret;
-		*eof = 1;
+		seq_write(m, page, ret);
+		ret = 0;
 	} else
-		nbytes = -EFAULT;
+		ret = -EFAULT;
+	free_page((unsigned long)page);
+	return ret;
+}
 
-	return nbytes;
+static int srm_env_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, srm_env_proc_show, PDE(inode)->data);
 }
 
-static int
-srm_env_write(struct file *file, const char __user *buffer, unsigned long count,
-		void *data)
+static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
+				  size_t count, loff_t *pos)
 {
 	int res;
-	srm_env_t	*entry;
+	srm_env_t	*entry = PDE(file->f_path.dentry->d_inode)->data;
 	char		*buf = (char *) __get_free_page(GFP_USER);
 	unsigned long	ret1, ret2;
 
-	entry = (srm_env_t *) data;
-
 	if (!buf)
 		return -ENOMEM;
 
@@ -140,6 +140,15 @@ srm_env_write(struct file *file, const c
 	return res;
 }
 
+static const struct file_operations srm_env_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= srm_env_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= srm_env_proc_write,
+};
+
 static void
 srm_env_cleanup(void)
 {
@@ -245,15 +254,10 @@ srm_env_init(void)
 	 */
 	entry = srm_named_entries;
 	while (entry->name && entry->id) {
-		entry->proc_entry = create_proc_entry(entry->name,
-				0644, named_dir);
+		entry->proc_entry = proc_create_data(entry->name, 0644, named_dir,
+						     &srm_env_proc_fops, entry);
 		if (!entry->proc_entry)
 			goto cleanup;
-
-		entry->proc_entry->data		= (void *) entry;
-		entry->proc_entry->read_proc	= srm_env_read;
-		entry->proc_entry->write_proc	= srm_env_write;
-
 		entry++;
 	}
 
@@ -264,15 +268,12 @@ srm_env_init(void)
 		entry = &srm_numbered_entries[var_num];
 		entry->name = number[var_num];
 
-		entry->proc_entry = create_proc_entry(entry->name,
-				0644, numbered_dir);
+		entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir,
+						     &srm_env_proc_fops, entry);
 		if (!entry->proc_entry)
 			goto cleanup;
 
 		entry->id			= var_num;
-		entry->proc_entry->data		= (void *) entry;
-		entry->proc_entry->read_proc	= srm_env_read;
-		entry->proc_entry->write_proc	= srm_env_write;
 	}
 
 	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/kernel/systbls.S linux-libre-2.6.33-gnu1/arch/alpha/kernel/systbls.S
--- linux-libre-2.6.32-gnu1/arch/alpha/kernel/systbls.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/kernel/systbls.S	2010-02-24 13:52:17.000000000 -0500
@@ -495,8 +495,23 @@ sys_call_table:
 	.quad sys_epoll_pwait
 	.quad sys_utimensat			/* 475 */
 	.quad sys_signalfd
-	.quad sys_ni_syscall
+	.quad sys_ni_syscall			/* sys_timerfd */
 	.quad sys_eventfd
+	.quad sys_recvmmsg
+	.quad sys_fallocate				/* 480 */
+	.quad sys_timerfd_create
+	.quad sys_timerfd_settime
+	.quad sys_timerfd_gettime
+	.quad sys_signalfd4
+	.quad sys_eventfd2				/* 485 */
+	.quad sys_epoll_create1
+	.quad sys_dup3
+	.quad sys_pipe2
+	.quad sys_inotify_init1
+	.quad sys_preadv				/* 490 */
+	.quad sys_pwritev
+	.quad sys_rt_tgsigqueueinfo
+	.quad sys_perf_event_open
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff -druNp linux-libre-2.6.32-gnu1/arch/alpha/mm/numa.c linux-libre-2.6.33-gnu1/arch/alpha/mm/numa.c
--- linux-libre-2.6.32-gnu1/arch/alpha/mm/numa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/alpha/mm/numa.c	2010-02-24 13:52:17.000000000 -0500
@@ -197,7 +197,7 @@ setup_memory_node(int nid, void *kernel_
 	}
 
 	if (bootmap_start == -1)
-		panic("couldn't find a contigous place for the bootmap");
+		panic("couldn't find a contiguous place for the bootmap");
 
 	/* Allocate the bootmap and mark the whole MM as reserved.  */
 	bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/head.S linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/head.S
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,14 @@
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c0, c5, 0
 		.endm
+#elif defined(CONFIG_CPU_V7)
+		.macro	loadsp, rb
+		.endm
+		.macro	writeb, ch, rb
+wait:		mrc	p14, 0, pc, c0, c1, 0
+		bcs	wait
+		mcr	p14, 0, \ch, c0, c5, 0
+		.endm
 #elif defined(CONFIG_CPU_XSCALE)
 		.macro	loadsp, rb
 		.endm
@@ -742,6 +750,12 @@ proc_types:
 		W(b)	__armv4_mmu_cache_on
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
+
+		.word	0x560f5810		@ Marvell PJ4 ARMv6
+		.word	0xff0ffff0
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv6_mmu_cache_flush
 
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/Makefile linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -63,8 +63,12 @@ endif
 
 SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 
-targets       := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
-		 head.o misc.o $(OBJS)
+suffix_$(CONFIG_KERNEL_GZIP) = gzip
+suffix_$(CONFIG_KERNEL_LZO)  = lzo
+
+targets       := vmlinux vmlinux.lds \
+		 piggy.$(suffix_y) piggy.$(suffix_y).o \
+		 font.o font.c head.o misc.o $(OBJS)
 
 ifeq ($(CONFIG_FUNCTION_TRACER),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
@@ -87,22 +91,34 @@ endif
 ifneq ($(PARAMS_PHYS),)
 LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
 endif
-LDFLAGS_vmlinux += -p --no-undefined -X \
-	$(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T
+# ?
+LDFLAGS_vmlinux += -p
+# Report unresolved symbol references
+LDFLAGS_vmlinux += --no-undefined
+# Delete all temporary local symbols
+LDFLAGS_vmlinux += -X
+# Next argument is a linker script
+LDFLAGS_vmlinux += -T
+
+# For __aeabi_uidivmod
+lib1funcs = $(obj)/lib1funcs.o
+
+$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
+	$(call cmd,shipped)
 
 # Don't allow any static data in misc.o, which
 # would otherwise mess up our GOT table
 CFLAGS_misc.o := -Dstatic=
 
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
-	 	$(addprefix $(obj)/, $(OBJS)) FORCE
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
+	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
 	$(call if_changed,ld)
 	@:
 
-$(obj)/piggy.gz: $(obj)/../Image FORCE
-	$(call if_changed,gzip)
+$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
+	$(call if_changed,$(suffix_y))
 
-$(obj)/piggy.o:  $(obj)/piggy.gz FORCE
+$(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE
 
 CFLAGS_font.o := -Dstatic=
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/misc.c linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/misc.c
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/misc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,10 +18,15 @@
 
 unsigned int __machine_arch_type;
 
+#define _LINUX_STRING_H_
+
 #include <linux/compiler.h>	/* for inline */
 #include <linux/types.h>	/* for size_t */
 #include <linux/stddef.h>	/* for NULL */
 #include <asm/string.h>
+#include <linux/linkage.h>
+
+#include <asm/unaligned.h>
 
 #ifdef STANDALONE_DEBUG
 #define putstr printf
@@ -48,6 +53,18 @@ static void icedcc_putc(int ch)
 
 	asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 }
+
+#elif defined(CONFIG_CPU_V7)
+
+static void icedcc_putc(int ch)
+{
+	asm(
+	"wait:	mrc	p14, 0, pc, c0, c1, 0			\n\
+		bcs	wait					\n\
+		mcr     p14, 0, %0, c0, c5, 0			"
+	: : "r" (ch));
+}
+
 #elif defined(CONFIG_CPU_XSCALE)
 
 static void icedcc_putc(int ch)
@@ -83,7 +100,6 @@ static void icedcc_putc(int ch)
 #endif
 
 #define putc(ch)	icedcc_putc(ch)
-#define flush()	do { } while (0)
 #endif
 
 static void putstr(const char *ptr)
@@ -188,34 +204,8 @@ static inline __ptr_t memcpy(__ptr_t __d
 /*
  * gzip delarations
  */
-#define OF(args)  args
 #define STATIC static
 
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000		/* Window size must be at least 32k, */
-				/* and a power of two */
-
-static uch *inbuf;		/* input buffer */
-static uch window[WSIZE];	/* Sliding window buffer */
-
-static unsigned insize;		/* valid bytes in inbuf */
-static unsigned inptr;		/* index of next byte to be processed in inbuf */
-static unsigned outcnt;		/* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
-#define COMMENT      0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0 /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
 /* Diagnostic functions */
 #ifdef DEBUG
 #  define Assert(cond,msg) {if(!(cond)) error(msg);}
@@ -233,24 +223,20 @@ static unsigned outcnt;		/* bytes in out
 #  define Tracecv(c,x)
 #endif
 
-static int  fill_inbuf(void);
-static void flush_window(void);
 static void error(char *m);
 
 extern char input_data[];
 extern char input_data_end[];
 
-static uch *output_data;
-static ulg output_ptr;
-static ulg bytes_out;
+static unsigned char *output_data;
+static unsigned long output_ptr;
 
 static void error(char *m);
 
 static void putstr(const char *);
 
-extern int end;
-static ulg free_mem_ptr;
-static ulg free_mem_end_ptr;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
 
 #ifdef STANDALONE_DEBUG
 #define NO_INFLATE_MALLOC
@@ -258,46 +244,13 @@ static ulg free_mem_end_ptr;
 
 #define ARCH_HAS_DECOMP_WDOG
 
-#include "../../../../lib/inflate.c"
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-int fill_inbuf(void)
-{
-	if (insize != 0)
-		error("ran out of input data");
-
-	inbuf = input_data;
-	insize = &input_data_end[0] - &input_data[0];
-
-	inptr = 1;
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-void flush_window(void)
-{
-	ulg c = crc;
-	unsigned n;
-	uch *in, *out, ch;
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
 
-	in = window;
-	out = &output_data[output_ptr];
-	for (n = 0; n < outcnt; n++) {
-		ch = *out++ = *in++;
-		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-	}
-	crc = c;
-	bytes_out += (ulg)outcnt;
-	output_ptr += (ulg)outcnt;
-	outcnt = 0;
-	putstr(".");
-}
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
 
 #ifndef arch_error
 #define arch_error(x)
@@ -314,22 +267,33 @@ static void error(char *x)
 	while(1);	/* Halt */
 }
 
+asmlinkage void __div0(void)
+{
+	error("Attempting division by 0!");
+}
+
 #ifndef STANDALONE_DEBUG
 
-ulg
-decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
-		  int arch_id)
+unsigned long
+decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
+		unsigned long free_mem_ptr_end_p,
+		int arch_id)
 {
-	output_data		= (uch *)output_start;	/* Points to kernel start */
+	unsigned char *tmp;
+
+	output_data		= (unsigned char *)output_start;
 	free_mem_ptr		= free_mem_ptr_p;
 	free_mem_end_ptr	= free_mem_ptr_end_p;
 	__machine_arch_type	= arch_id;
 
 	arch_decomp_setup();
 
-	makecrc();
+	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
+	output_ptr = get_unaligned_le32(tmp);
+
 	putstr("Uncompressing Linux...");
-	gunzip();
+	decompress(input_data, input_data_end - input_data,
+			NULL, NULL, output_data, NULL, error);
 	putstr(" done, booting the kernel.\n");
 	return output_ptr;
 }
@@ -341,11 +305,10 @@ int main()
 {
 	output_data = output_buffer;
 
-	makecrc();
 	putstr("Uncompressing Linux...");
-	gunzip();
+	decompress(input_data, input_data_end - input_data,
+			NULL, NULL, output_data, NULL, error);
 	putstr("done.\n");
 	return 0;
 }
 #endif
-	
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.gzip.S linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.gzip.S
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.gzip.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.gzip.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/arm/boot/compressed/piggy.gzip"
+	.globl	input_data_end
+input_data_end:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.lzo.S linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.lzo.S
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.lzo.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.lzo.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/arm/boot/compressed/piggy.lzo"
+	.globl	input_data_end
+input_data_end:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.S linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.S
--- linux-libre-2.6.32-gnu1/arch/arm/boot/compressed/piggy.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/boot/compressed/piggy.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-	.section .piggydata,#alloc
-	.globl	input_data
-input_data:
-	.incbin	"arch/arm/boot/compressed/piggy.gz"
-	.globl	input_data_end
-input_data_end:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/common/dmabounce.c linux-libre-2.6.33-gnu1/arch/arm/common/dmabounce.c
--- linux-libre-2.6.32-gnu1/arch/arm/common/dmabounce.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/common/dmabounce.c	2010-02-24 13:52:17.000000000 -0500
@@ -308,15 +308,11 @@ static inline void unmap_single(struct d
 			memcpy(ptr, buf->safe, size);
 
 			/*
-			 * DMA buffers must have the same cache properties
-			 * as if they were really used for DMA - which means
-			 * data must be written back to RAM.  Note that
-			 * we don't use dmac_flush_range() here for the
-			 * bidirectional case because we know the cache
-			 * lines will be coherent with the data written.
+			 * Since we may have written to a page cache page,
+			 * we need to ensure that the data will be coherent
+			 * with user mappings.
 			 */
-			dmac_clean_range(ptr, ptr + size);
-			outer_clean_range(__pa(ptr), __pa(ptr) + size);
+			__cpuc_flush_dcache_area(ptr, size);
 		}
 		free_safe_buffer(dev->archdata.dmabounce, buf);
 	}
@@ -342,6 +338,22 @@ dma_addr_t dma_map_single(struct device
 }
 EXPORT_SYMBOL(dma_map_single);
 
+/*
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer.  (basically return things back to the way they
+ * should be)
+ */
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		enum dma_data_direction dir)
+{
+	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, dir);
+
+	unmap_single(dev, dma_addr, size, dir);
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
 dma_addr_t dma_map_page(struct device *dev, struct page *page,
 		unsigned long offset, size_t size, enum dma_data_direction dir)
 {
@@ -366,8 +378,7 @@ EXPORT_SYMBOL(dma_map_page);
  * the safe buffer.  (basically return things back to the way they
  * should be)
  */
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
 		enum dma_data_direction dir)
 {
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -375,7 +386,7 @@ void dma_unmap_single(struct device *dev
 
 	unmap_single(dev, dma_addr, size, dir);
 }
-EXPORT_SYMBOL(dma_unmap_single);
+EXPORT_SYMBOL(dma_unmap_page);
 
 int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
 		unsigned long off, size_t sz, enum dma_data_direction dir)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/common/scoop.c linux-libre-2.6.33-gnu1/arch/arm/common/scoop.c
--- linux-libre-2.6.32-gnu1/arch/arm/common/scoop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/common/scoop.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,7 @@ static int scoop_gpio_get(struct gpio_ch
 {
 	struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
 
-	/* XXX: I'm usure,  but it seems so */
+	/* XXX: I'm unsure, but it seems so */
 	return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/acs5k_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/acs5k_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/acs5k_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/acs5k_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -187,7 +187,6 @@ CONFIG_MACH_ACS5K=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM922T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/acs5k_tiny_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/acs5k_tiny_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/acs5k_tiny_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/acs5k_tiny_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,6 @@ CONFIG_MACH_ACS5K=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM922T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/afeb9260_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/afeb9260_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/afeb9260_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/afeb9260_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -227,7 +227,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/am200epdkit_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/am200epdkit_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/am200epdkit_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/am200epdkit_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,6 @@ CONFIG_PXA25x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/am3517_evm_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/am3517_evm_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/am3517_evm_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/am3517_evm_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1206 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Wed Oct 28 15:47:47 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+# CONFIG_OMAP_MUX is not set
+# CONFIG_OMAP_MCBSP is not set
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+CONFIG_MACH_OMAP3517EVM=y
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_CM_T35 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ams_delta_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ams_delta_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ams_delta_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ams_delta_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_150MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/assabet_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/assabet_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/assabet_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/assabet_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -101,7 +101,6 @@ CONFIG_SA1100_ASSABET=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91cap9adk_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91cap9adk_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91cap9adk_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91cap9adk_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91rm9200dk_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91rm9200dk_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91rm9200dk_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91rm9200dk_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -120,6 +120,7 @@ CONFIG_ARCH_AT91RM9200DK=y
 # CONFIG_MACH_CARMEVA is not set
 # CONFIG_MACH_KB9200 is not set
 # CONFIG_MACH_ATEB9200 is not set
+CONFIG_MACH_ECO920=y
 
 #
 # AT91RM9200 Feature Selections
@@ -129,7 +130,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91rm9200ek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91rm9200ek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91rm9200ek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91rm9200ek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -129,7 +129,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9260ek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9260ek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9260ek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9260ek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -188,7 +188,6 @@ CONFIG_AT91_TIMER_HZ=100
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9261ek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9261ek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9261ek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9261ek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9263ek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9263ek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9263ek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9263ek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,6 @@ CONFIG_AT91_TIMER_HZ=100
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9g20ek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9g20ek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9g20ek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9g20ek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -187,7 +187,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9rlek_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9rlek_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/at91sam9rlek_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/at91sam9rlek_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -179,7 +179,6 @@ CONFIG_AT91_TIMER_HZ=100
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ateb9200_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ateb9200_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ateb9200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ateb9200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -132,7 +132,6 @@ CONFIG_MACH_ATEB9200=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/badge4_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/badge4_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/badge4_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/badge4_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,6 @@ CONFIG_SA1100_BADGE4=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/bcmring_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/bcmring_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/bcmring_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/bcmring_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,6 @@ CONFIG_BCM_ZRELADDR=0x8000
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cam60_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cam60_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cam60_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cam60_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/carmeva_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/carmeva_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/carmeva_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/carmeva_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -97,7 +97,6 @@ CONFIG_MACH_CARMEVA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cerfcube_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cerfcube_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cerfcube_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cerfcube_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -105,7 +105,6 @@ CONFIG_SA1100_CERF_FLASH_16MB=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cm_t35_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cm_t35_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cm_t35_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cm_t35_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1732 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc4
+# Tue Oct 13 17:10:40 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+CONFIG_MACH_CM_T35=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+# CONFIG_LIB80211_DEBUG is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_OMAP_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_PREFETCH=y
+# CONFIG_MTD_NAND_OMAP_PREFETCH_DMA is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_TWL4030=m
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=y
+# CONFIG_TWL4030_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=y
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cm_x2xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cm_x2xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cm_x2xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cm_x2xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -205,7 +205,6 @@ CONFIG_PXA_SSP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cm_x300_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cm_x300_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cm_x300_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cm_x300_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,15 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc8
-# Thu Jun  4 09:53:21 2009
+# Linux kernel version: 2.6.32-rc4
+# Tue Oct 13 19:03:13 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,14 +16,14 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ARCH_MTD_XIP=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -46,11 +44,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
@@ -83,7 +82,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -96,6 +94,10 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -103,13 +105,17 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_CLK=y
-# CONFIG_SLOW_WORK is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -117,11 +123,11 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -142,19 +148,22 @@ CONFIG_FREEZER=y
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -163,25 +172,27 @@ CONFIG_FREEZER=y
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # Intel PXA2xx/PXA3xx Implementations
@@ -191,16 +202,19 @@ CONFIG_ARCH_PXA=y
 # Supported PXA3xx Processor Variants
 #
 CONFIG_CPU_PXA300=y
-# CONFIG_CPU_PXA310 is not set
+CONFIG_CPU_PXA310=y
 # CONFIG_CPU_PXA320 is not set
 # CONFIG_CPU_PXA930 is not set
 # CONFIG_CPU_PXA935 is not set
+# CONFIG_CPU_PXA950 is not set
 # CONFIG_ARCH_GUMSTIX is not set
 # CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_MACH_STARGATE2 is not set
 # CONFIG_ARCH_LUBBOCK is not set
 # CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
 # CONFIG_MACH_MP900C is not set
+# CONFIG_MACH_BALLOON3 is not set
 # CONFIG_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
 # CONFIG_ARCH_VIPER is not set
@@ -218,6 +232,7 @@ CONFIG_CPU_PXA300=y
 # CONFIG_MACH_SAAR is not set
 # CONFIG_MACH_ARMCORE is not set
 CONFIG_MACH_CM_X300=y
+# CONFIG_MACH_H4700 is not set
 # CONFIG_MACH_MAGICIAN is not set
 # CONFIG_MACH_HIMALAYA is not set
 # CONFIG_MACH_MIOA701 is not set
@@ -225,18 +240,17 @@ CONFIG_MACH_CM_X300=y
 # CONFIG_ARCH_PXA_PALM is not set
 # CONFIG_MACH_CSB726 is not set
 # CONFIG_PXA_EZX is not set
+# CONFIG_MACH_XCEP is not set
 CONFIG_PXA3xx=y
-# CONFIG_PXA_PWM is not set
 CONFIG_PLAT_PXA=y
 
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
 CONFIG_CPU_CP15=y
@@ -246,11 +260,12 @@ CONFIG_IO_36=y
 #
 # Processor Features
 #
-# CONFIG_ARM_THUMB is not set
+CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_OUTER_CACHE=y
 CONFIG_CACHE_XSC3L2=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_IWMMXT=y
 CONFIG_COMMON_CLKDEV=y
 
@@ -272,11 +287,12 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 CONFIG_HIGHMEM=y
@@ -292,17 +308,19 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mtdblock5 rootfstype=jffs2 console=ttyS2,38400"
+CONFIG_CMDLINE="root=/dev/mtdblock5 rootfstype=ubifs console=ttyS2,38400"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -355,6 +373,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -396,6 +415,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -410,6 +430,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -433,22 +454,27 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
-# CONFIG_BT_HCIBTUSB is not set
+CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIBTSDIO is not set
 # CONFIG_BT_HCIUART is not set
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=m
 # CONFIG_LIB80211_DEBUG is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -461,6 +487,7 @@ CONFIG_LIB80211=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -472,9 +499,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
@@ -521,6 +548,9 @@ CONFIG_MTD_CFI_I2=y
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -556,7 +586,15 @@ CONFIG_MTD_NAND_PXA3xx=y
 #
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -570,6 +608,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -593,10 +632,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -621,7 +656,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -636,6 +670,7 @@ CONFIG_MII=y
 CONFIG_DM9000=y
 CONFIG_DM9000_DEBUGLEVEL=0
 CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_ENC28J60 is not set
 # CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
@@ -648,20 +683,20 @@ CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 CONFIG_LIBERTAS=m
 # CONFIG_LIBERTAS_USB is not set
 CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_SPI is not set
 # CONFIG_LIBERTAS_DEBUG is not set
 # CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_HOSTAP is not set
 
 #
@@ -683,6 +718,7 @@ CONFIG_LIBERTAS_SDIO=m
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -706,33 +742,51 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 CONFIG_KEYBOARD_PXA27x=m
-# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DA9034 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+CONFIG_TOUCHSCREEN_WM9712=y
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -760,6 +814,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
@@ -774,6 +829,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -784,6 +840,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
@@ -807,19 +864,36 @@ CONFIG_I2C_PXA=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+# CONFIG_SPI_PXA2XX is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
+CONFIG_GPIO_SYSFS=y
 
 #
 # Memory mapped GPIO expanders:
@@ -839,11 +913,17 @@ CONFIG_GPIO_PCA953X=y
 #
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -860,32 +940,33 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
+CONFIG_PMIC_DA903X=y
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_DA903X=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -925,7 +1006,17 @@ CONFIG_FB_PXA=y
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
 # CONFIG_FB_BROADSHEET is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+CONFIG_LCD_TDO24M=y
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_DA903X=m
 
 #
 # Display device support
@@ -956,38 +1047,48 @@ CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
 CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
 CONFIG_SND_ARM=y
 CONFIG_SND_PXA2XX_LIB=m
+CONFIG_SND_PXA2XX_LIB_AC97=y
 # CONFIG_SND_PXA2XX_AC97 is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
 CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_AC97=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
 CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_WM9712=m
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-CONFIG_HID_DEBUG=y
 # CONFIG_HIDRAW is not set
 
 #
@@ -1006,10 +1107,12 @@ CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
 # CONFIG_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
 CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
 CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
@@ -1023,9 +1126,15 @@ CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
 # CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
 CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
 # CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_WACOM=m
+CONFIG_HID_ZEROPLUS=y
 # CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1054,6 +1163,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1151,8 +1261,9 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 CONFIG_MMC_PXA=m
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
@@ -1162,8 +1273,10 @@ CONFIG_LEDS_CLASS=y
 # CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DA903X is not set
+# CONFIG_LEDS_DAC124S085 is not set
 # CONFIG_LEDS_BD2802 is not set
 
 #
@@ -1179,6 +1292,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 #
 # iptables trigger is under Netfilter config (LED target)
 #
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1210,10 +1324,19 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1233,12 +1356,15 @@ CONFIG_RTC_DRV_V3020=y
 #
 # on-CPU RTC drivers
 #
-CONFIG_RTC_DRV_SA1100=y
-# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_RTC_DRV_SA1100 is not set
+CONFIG_RTC_DRV_PXA=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1256,10 +1382,13 @@ CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1319,6 +1448,12 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1329,12 +1464,12 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1378,7 +1513,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1428,6 +1563,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1441,6 +1577,7 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1460,32 +1597,20 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1509,7 +1634,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1551,11 +1675,13 @@ CONFIG_CRYPTO_ECB=m
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
@@ -1591,9 +1717,9 @@ CONFIG_CRYPTO_DES=y
 #
 # Compression
 #
-# CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_LZO=y
 
 #
 # Random Number Generation
@@ -1608,7 +1734,7 @@ CONFIG_CRYPTO_DES=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
@@ -1616,6 +1742,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/colibri_pxa270_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/colibri_pxa270_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/colibri_pxa270_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/colibri_pxa270_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,6 @@ CONFIG_PXA27x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/colibri_pxa300_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/colibri_pxa300_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/colibri_pxa300_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/colibri_pxa300_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,6 @@ CONFIG_PXA3xx=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/collie_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/collie_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/collie_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/collie_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -125,7 +125,6 @@ CONFIG_SA1100_COLLIE=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/corgi_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/corgi_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/corgi_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/corgi_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cpu9260_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cpu9260_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cpu9260_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cpu9260_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -229,7 +229,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cpu9g20_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cpu9g20_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cpu9g20_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cpu9g20_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -219,7 +219,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/cpuat91_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/cpuat91_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/cpuat91_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/cpuat91_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -230,7 +230,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/csb337_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/csb337_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/csb337_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/csb337_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -193,7 +193,6 @@ CONFIG_AT91_TIMER_HZ=128
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/csb637_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/csb637_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/csb637_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/csb637_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -215,7 +215,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/da830_omapl137_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/da830_omapl137_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/da830_omapl137_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/da830_omapl137_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1254 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2-davinci1
-# Wed May 13 15:33:29 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_COMPAT_BRK=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_CLK=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-CONFIG_ARCH_DAVINCI=y
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
-CONFIG_CP_INTC=y
-
-#
-# TI DaVinci Implementations
-#
-
-#
-# DaVinci Core Type
-#
-# CONFIG_ARCH_DAVINCI_DM644x is not set
-# CONFIG_ARCH_DAVINCI_DM646x is not set
-# CONFIG_ARCH_DAVINCI_DM355 is not set
-CONFIG_ARCH_DAVINCI_DA830=y
-
-#
-# DaVinci Board Type
-#
-CONFIG_MACH_DAVINCI_DA830_EVM=y
-CONFIG_DAVINCI_MUX=y
-# CONFIG_DAVINCI_MUX_DEBUG is not set
-# CONFIG_DAVINCI_MUX_WARNINGS is not set
-CONFIG_DAVINCI_RESET_CLOCKS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-CONFIG_CPU_DCACHE_WRITETHROUGH=y
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_LEDS=y
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-CONFIG_LXT_PHY=y
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-CONFIG_LSI_ET1011C_PHY=y
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-CONFIG_TI_DAVINCI_EMAC=y
-# CONFIG_DM9000 is not set
-# CONFIG_ETHOC is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_XTKBD=m
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-CONFIG_I2C_DAVINCI=y
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_DAVINCI_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SOC=m
-CONFIG_SND_DAVINCI_SOC=m
-CONFIG_SND_SOC_I2C_AND_SPI=m
-# CONFIG_SND_SOC_ALL_CODECS is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_USB_MUSB_HOST is not set
-# CONFIG_USB_MUSB_PERIPHERAL is not set
-# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
-# CONFIG_USB_GADGET_AT91 is not set
-# CONFIG_USB_GADGET_ATMEL_USBA is not set
-# CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_IMX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_AMD5536UDC is not set
-# CONFIG_USB_GADGET_FSL_QE is not set
-# CONFIG_USB_GADGET_CI13XXX is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=m
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_PI_LIST=y
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_PAGE_POISONING is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=m
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/da850_omapl138_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/da850_omapl138_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/da850_omapl138_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/da850_omapl138_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1229 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-davinci1
-# Mon Jun 29 07:54:15 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_COMPAT_BRK=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_CLK=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-CONFIG_ARCH_DAVINCI=y
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
-CONFIG_CP_INTC=y
-
-#
-# TI DaVinci Implementations
-#
-
-#
-# DaVinci Core Type
-#
-# CONFIG_ARCH_DAVINCI_DM644x is not set
-# CONFIG_ARCH_DAVINCI_DM355 is not set
-# CONFIG_ARCH_DAVINCI_DM646x is not set
-# CONFIG_ARCH_DAVINCI_DA830 is not set
-CONFIG_ARCH_DAVINCI_DA850=y
-CONFIG_ARCH_DAVINCI_DA8XX=y
-# CONFIG_ARCH_DAVINCI_DM365 is not set
-
-#
-# DaVinci Board Type
-#
-CONFIG_MACH_DAVINCI_DA850_EVM=y
-CONFIG_DAVINCI_MUX=y
-# CONFIG_DAVINCI_MUX_DEBUG is not set
-# CONFIG_DAVINCI_MUX_WARNINGS is not set
-CONFIG_DAVINCI_RESET_CLOCKS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_LEDS=y
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_PHONET is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-CONFIG_LXT_PHY=y
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-CONFIG_LSI_ET1011C_PHY=y
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_TI_DAVINCI_EMAC is not set
-# CONFIG_DM9000 is not set
-# CONFIG_ETHOC is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_XTKBD=m
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-CONFIG_I2C_DAVINCI=y
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_DAVINCI_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_JACK=y
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SOC=m
-CONFIG_SND_DAVINCI_SOC=m
-CONFIG_SND_SOC_I2C_AND_SPI=m
-# CONFIG_SND_SOC_ALL_CODECS is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_MINIX_FS=m
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_PI_LIST=y
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_PAGE_POISONING is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=m
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/da8xx_omapl_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/da8xx_omapl_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/da8xx_omapl_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/da8xx_omapl_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1331 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 22 12:19:19 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+CONFIG_ARCH_DAVINCI=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CP_INTC=y
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+# CONFIG_ARCH_DAVINCI_DM644x is not set
+# CONFIG_ARCH_DAVINCI_DM355 is not set
+# CONFIG_ARCH_DAVINCI_DM646x is not set
+CONFIG_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_ARCH_DAVINCI_DA8XX=y
+# CONFIG_ARCH_DAVINCI_DM365 is not set
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_DAVINCI_DA830_EVM=y
+CONFIG_DA830_UI=y
+CONFIG_DA830_UI_LCD=y
+# CONFIG_DA830_UI_NAND is not set
+CONFIG_MACH_DAVINCI_DA850_EVM=y
+CONFIG_DA850_UI_EXP=y
+CONFIG_DA850_UI_NONE=y
+# CONFIG_DA850_UI_RMII is not set
+CONFIG_DAVINCI_MUX=y
+# CONFIG_DAVINCI_MUX_DEBUG is not set
+# CONFIG_DAVINCI_MUX_WARNINGS is not set
+CONFIG_DAVINCI_RESET_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_CPU_DCACHE_WRITETHROUGH=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+CONFIG_LXT_PHY=y
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+CONFIG_LSI_ET1011C_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+CONFIG_TI_DAVINCI_EMAC=y
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DAVINCI=y
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCF857X=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DAVINCI_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+CONFIG_REGULATOR_TPS6507X=y
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_DAVINCI is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FB_DA8XX=y
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+# CONFIG_SND_DA830_SOC_EVM is not set
+# CONFIG_SND_DA850_SOC_EVM is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/davinci_all_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/davinci_all_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/davinci_all_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/davinci_all_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3-davinci1
-# Fri Jul 17 08:26:52 2009
+# Linux kernel version: 2.6.32-rc4
+# Mon Oct 12 14:13:12 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -46,11 +45,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -91,17 +91,15 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -145,6 +143,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
@@ -159,6 +158,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -181,11 +181,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
 CONFIG_ARCH_DAVINCI=y
 # CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
 CONFIG_AINTC=y
 CONFIG_ARCH_DAVINCI_DMx=y
 
@@ -208,6 +210,7 @@ CONFIG_ARCH_DAVINCI_DM365=y
 #
 CONFIG_MACH_DAVINCI_EVM=y
 CONFIG_MACH_SFFSDR=y
+CONFIG_MACH_NEUROS_OSD2=y
 CONFIG_MACH_DAVINCI_DM355_EVM=y
 CONFIG_MACH_DM355_LEOPARD=y
 CONFIG_MACH_DAVINCI_DM6467_EVM=y
@@ -220,11 +223,10 @@ CONFIG_DAVINCI_RESET_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
@@ -239,6 +241,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -259,6 +262,8 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -280,6 +285,7 @@ CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_LEDS=y
 # CONFIG_LEDS_CPU is not set
@@ -412,6 +418,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_IP6_NF_IPTABLES is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -452,6 +459,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -461,9 +469,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=m
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -499,7 +507,7 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_INTELEXT=m
 CONFIG_MTD_CFI_AMDSTD=m
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=m
@@ -694,12 +702,10 @@ CONFIG_DM9000_DEBUGLEVEL=4
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -734,6 +740,7 @@ CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -745,10 +752,7 @@ CONFIG_INPUT=y
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 CONFIG_INPUT_EVDEV=m
 CONFIG_INPUT_EVBUG=m
@@ -757,12 +761,16 @@ CONFIG_INPUT_EVBUG=m
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_KEYBOARD_MATRIX is not set
 # CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 CONFIG_KEYBOARD_XTKBD=m
@@ -777,6 +785,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
 # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -787,7 +796,17 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_TOUCHSCREEN_TSC2007 is not set
 # CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+CONFIG_INPUT_DM355EVM=m
+CONFIG_INPUT_DM365EVM=m
 
 #
 # Hardware I/O ports
@@ -828,13 +847,13 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -868,13 +887,17 @@ CONFIG_I2C_DAVINCI=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -889,7 +912,7 @@ CONFIG_GPIOLIB=y
 #
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
-CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_PCF857X=y
 
 #
 # PCI GPIO expanders:
@@ -898,10 +921,19 @@ CONFIG_GPIO_PCF857X=m
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -950,6 +982,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -959,9 +992,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -988,7 +1019,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
-# CONFIG_MFD_DM355EVM_MSP is not set
+CONFIG_MFD_DM355EVM_MSP=y
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
@@ -999,9 +1030,11 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -1013,9 +1046,9 @@ CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 # CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
@@ -1032,6 +1065,7 @@ CONFIG_FIRMWARE_EDID=y
 # Frame buffer hardware drivers
 #
 # CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_DAVINCI=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1101,7 +1135,6 @@ CONFIG_SND_SOC_TLV320AIC3X=m
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1130,6 +1163,7 @@ CONFIG_HID_CYPRESS=m
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
@@ -1176,6 +1210,7 @@ CONFIG_USB_MON=m
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
@@ -1269,6 +1304,7 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
 # CONFIG_USB_GADGET_S3C_HSOTG is not set
 # CONFIG_USB_GADGET_IMX is not set
@@ -1286,6 +1322,7 @@ CONFIG_USB_ZERO=m
 # CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
@@ -1316,8 +1353,10 @@ CONFIG_MMC_BLOCK=m
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_DAVINCI=m
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 
@@ -1345,6 +1384,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 #
 # iptables trigger is under Netfilter config (LED target)
 #
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=m
 
@@ -1370,6 +1410,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_DM355EVM is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1399,8 +1440,11 @@ CONFIG_RTC_INTF_DEV=y
 #
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1429,6 +1473,7 @@ CONFIG_XFS_FS=m
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1500,7 +1545,6 @@ CONFIG_MINIX_FS=m
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1596,6 +1640,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1634,11 +1679,14 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1663,7 +1711,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-CONFIG_ARM_UNWIND=y
+# CONFIG_ARM_UNWIND is not set
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1681,7 +1729,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1713,11 +1760,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/dove_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/dove_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/dove_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/dove_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1619 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc6
+# Tue Nov 24 13:53:37 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_DOVE=y
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# Marvell Dove Implementations
+#
+CONFIG_MACH_DOVE_DB=y
+CONFIG_PLAT_ORION=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_TAUROS2=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 is not set
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+CONFIG_MV643XX_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MV64XXX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_ORION=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_MV_XOR=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_UBIFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_BLOWFISH=y
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_MV_CESA is not set
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ebsa110_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ebsa110_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ebsa110_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ebsa110_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,6 @@ CONFIG_ARCH_EBSA110=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA110=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ecbat91_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ecbat91_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ecbat91_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ecbat91_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/edb7211_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/edb7211_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/edb7211_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/edb7211_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -90,7 +90,6 @@ CONFIG_ARCH_EP7211=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_LV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/em_x270_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/em_x270_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/em_x270_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/em_x270_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -202,7 +202,6 @@ CONFIG_PXA_SSP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ep93xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ep93xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ep93xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ep93xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -198,7 +198,6 @@ CONFIG_EP93XX_EARLY_UART1=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/eseries_pxa_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/eseries_pxa_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/eseries_pxa_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/eseries_pxa_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -203,7 +203,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ezx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ezx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ezx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ezx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc3
-# Mon Jul  7 17:52:21 2008
+# Linux kernel version: 2.6.32-rc5
+# Mon Nov  2 13:18:50 2009
 #
 CONFIG_ARM=y
 CONFIG_HAVE_PWM=y
@@ -9,24 +9,22 @@ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
 CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -35,7 +33,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION="-ezxdev"
+CONFIG_LOCALVERSION="-ezx200910312315"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
@@ -44,56 +42,78 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -101,12 +121,10 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -120,25 +138,27 @@ CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -146,39 +166,64 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM7X00A is not set
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # Intel PXA2xx/PXA3xx Implementations
 #
 # CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_MACH_STARGATE2 is not set
 # CONFIG_ARCH_LUBBOCK is not set
 # CONFIG_MACH_LOGICPD_PXA270 is not set
 # CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_MACH_BALLOON3 is not set
 # CONFIG_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_VIPER is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
-# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
 # CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
 # CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
 # CONFIG_MACH_ZYLONITE is not set
 # CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
 # CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_H4700 is not set
 # CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MIOA701 is not set
 # CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_MACH_CSB726 is not set
 CONFIG_PXA_EZX=y
 CONFIG_MACH_EZX_A780=y
 CONFIG_MACH_EZX_E680=y
@@ -186,26 +231,19 @@ CONFIG_MACH_EZX_A1200=y
 CONFIG_MACH_EZX_A910=y
 CONFIG_MACH_EZX_E6=y
 CONFIG_MACH_EZX_E2=y
+# CONFIG_MACH_XCEP is not set
 CONFIG_PXA27x=y
 CONFIG_PXA_SSP=y
-CONFIG_PXA_PWM=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_PXA_HAVE_BOARD_IRQS=y
+CONFIG_PLAT_PXA=y
 
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
 CONFIG_CPU_CP15=y
@@ -216,9 +254,10 @@ CONFIG_CPU_CP15_MMU=y
 #
 CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -231,44 +270,71 @@ CONFIG_XSCALE_PMU=y
 # Kernel Features
 #
 CONFIG_TICK_ONESHOT=y
-# CONFIG_NO_HZ is not set
+CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=1 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
 # CONFIG_XIP_KERNEL is not set
 CONFIG_KEXEC=y
 CONFIG_ATAGS_PROC=y
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
 
 #
 # Floating point emulation
@@ -285,6 +351,8 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
 
@@ -297,11 +365,8 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -315,6 +380,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -342,7 +408,6 @@ CONFIG_INET_TUNNEL=m
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -393,18 +458,22 @@ CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NF_CT_NETLINK=m
+# CONFIG_NETFILTER_TPROXY is not set
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 # CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
 # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
 # CONFIG_NETFILTER_XT_TARGET_TRACE is not set
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -413,20 +482,23 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
 # CONFIG_NETFILTER_XT_MATCH_OWNER is not set
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
 # CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
 CONFIG_NETFILTER_XT_MATCH_QUOTA=m
 # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
 CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
@@ -434,20 +506,21 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
@@ -455,8 +528,8 @@ CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_NF_NAT=m
 CONFIG_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_NF_NAT_PROTO_GRE=m
 CONFIG_NF_NAT_PROTO_UDPLITE=m
@@ -469,9 +542,9 @@ CONFIG_NF_NAT_PPTP=m
 CONFIG_NF_NAT_H323=m
 CONFIG_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
@@ -483,30 +556,29 @@ CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
-
-#
-# Bridge: Netfilter Configuration
-#
 # CONFIG_BRIDGE_NF_EBTABLES is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
@@ -517,9 +589,11 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -529,64 +603,34 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 CONFIG_BT=y
-CONFIG_BT_L2CAP=m
+CONFIG_BT_L2CAP=y
 CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM=y
 CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP=y
 CONFIG_BT_BNEP_MC_FILTER=y
 CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
+CONFIG_BT_HIDP=y
 
 #
 # Bluetooth device drivers
 #
-# CONFIG_BT_HCIUSB is not set
-# CONFIG_BT_HCIBTUSB is not set
-# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
 CONFIG_BT_HCIUART=y
 CONFIG_BT_HCIUART_H4=y
 # CONFIG_BT_HCIUART_BCSP is not set
 # CONFIG_BT_HCIUART_LL is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIVHCI is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
-
-#
-# Wireless
-#
-CONFIG_CFG80211=m
-CONFIG_NL80211=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_MAC80211=m
-
-#
-# Rate control algorithm selection
-#
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
-
-#
-# Selecting 'y' for an algorithm will
-#
-
-#
-# build the algorithm into mac80211.
-#
-CONFIG_MAC80211_RC_DEFAULT="pid"
-CONFIG_MAC80211_RC_PID=y
-# CONFIG_MAC80211_MESH is not set
-CONFIG_MAC80211_LEDS=y
-# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
-# CONFIG_MAC80211_DEBUG is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -598,13 +642,19 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -616,9 +666,9 @@ CONFIG_MTD_PARTITIONS=y
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLKDEVS is not set
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_HAVE_MTD_OTP=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -647,7 +697,7 @@ CONFIG_MTD_CFI_I1=y
 # CONFIG_MTD_CFI_I2 is not set
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_OTP is not set
+CONFIG_MTD_OTP=y
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
@@ -655,19 +705,15 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-CONFIG_MTD_XIP=y
+# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_PXA2XX is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PXA2XX=y
 # CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_SHARP_SL is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -675,6 +721,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -690,6 +737,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -700,15 +752,14 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -722,7 +773,6 @@ CONFIG_HAVE_IDE=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -732,13 +782,11 @@ CONFIG_DUMMY=y
 # CONFIG_NET_ETHERNET is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -765,6 +813,7 @@ CONFIG_SLHC=m
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -786,29 +835,45 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 CONFIG_KEYBOARD_PXA27x=y
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 CONFIG_TOUCHSCREEN_PCAP=y
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_ATI_REMOTE is not set
@@ -816,7 +881,10 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_KEYSPAN_REMOTE is not set
 # CONFIG_INPUT_POWERMATE is not set
 # CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
 CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+CONFIG_INPUT_PCAP=y
 
 #
 # Hardware I/O ports
@@ -828,6 +896,7 @@ CONFIG_INPUT_UINPUT=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
@@ -842,92 +911,130 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=8
 # CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
 
 #
 # SPI Master Controller Drivers
 #
 # CONFIG_SPI_BITBANG is not set
-CONFIG_SPI_PXA2XX=m
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PXA2XX=y
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
-CONFIG_HAVE_GPIO_LIB=y
 
 #
-# GPIO Support
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
 #
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+
+#
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
 # CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -938,54 +1045,170 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
 CONFIG_EZX_PCAP=y
-
-#
-# Multimedia devices
-#
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+CONFIG_REGULATOR_PCAP=y
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_MEDIA_SUPPORT=y
 
 #
 # Multimedia core support
 #
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
 CONFIG_VIDEO_ALLOW_V4L1=y
 CONFIG_VIDEO_V4L1_COMPAT=y
 # CONFIG_DVB_CORE is not set
-CONFIG_VIDEO_MEDIA=m
+CONFIG_VIDEO_MEDIA=y
 
 #
 # Multimedia drivers
 #
 # CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=m
-CONFIG_MEDIA_TUNER_TDA8290=m
-CONFIG_MEDIA_TUNER_TDA9887=m
-CONFIG_MEDIA_TUNER_TEA5761=m
-CONFIG_MEDIA_TUNER_TEA5767=m
-CONFIG_MEDIA_TUNER_MT20XX=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEO_V4L1=m
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_SG=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=y
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_PXA27x=y
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
 # CONFIG_V4L_USB_DRIVERS is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_VIDEO_PXA27x is not set
 CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
 # CONFIG_USB_DSBR is not set
-# CONFIG_USB_SI470X is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+CONFIG_RADIO_TEA5764=y
+CONFIG_RADIO_TEA5764_XTAL=y
 # CONFIG_DAB is not set
 
 #
@@ -996,6 +1219,7 @@ CONFIG_RADIO_ADAPTERS=y
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -1017,15 +1241,19 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_UVESA is not set
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
 # CONFIG_FB_PXA_SMARTPANEL is not set
 CONFIG_FB_PXA_PARAMETERS=y
 # CONFIG_FB_MBX is not set
-# CONFIG_FB_AM200EPD is not set
+# CONFIG_FB_W100 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
 CONFIG_BACKLIGHT_PWM=y
 
 #
@@ -1053,85 +1281,60 @@ CONFIG_FONT_MINI_4x6=y
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
 # CONFIG_LOGO is not set
-
-#
-# Sound
-#
 CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ALSA ARM devices
-#
-# CONFIG_SND_PXA2XX_AC97 is not set
-
-#
-# SPI devices
-#
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-
-#
-# System on Chip audio support
-#
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_PXA2XX_LIB=y
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
 CONFIG_SND_SOC=y
 CONFIG_SND_PXA2XX_SOC=y
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
 #
 # CONFIG_USB_HID is not set
+# CONFIG_HID_PID is not set
 
 #
 # USB HID Boot Protocol drivers
 #
 # CONFIG_USB_KBD is not set
 # CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_APPLE=m
+# CONFIG_HID_WACOM is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1150,32 +1353,42 @@ CONFIG_USB=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -1183,7 +1396,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1196,7 +1408,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1204,62 +1416,94 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
 # CONFIG_USB_GADGET_ATMEL_USBA is not set
 # CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 CONFIG_USB_GADGET_PXA27X=y
 CONFIG_USB_PXA27X=y
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 # CONFIG_USB_GADGET_DUALSPEED is not set
 # CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=y
 # CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_ETH_EEM is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 CONFIG_MMC_UNSAFE_RESUME=y
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
-CONFIG_SDIO_UART=y
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 CONFIG_MMC_PXA=y
-# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
 # CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_LP3944=y
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -1267,7 +1511,14 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1297,45 +1548,67 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
-CONFIG_RTC_DRV_SA1100=m
+# CONFIG_RTC_DRV_SA1100 is not set
+# CONFIG_RTC_DRV_PXA is not set
+CONFIG_RTC_DRV_PCAP=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=m
-CONFIG_FS_MBCACHE=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=m
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -1350,6 +1623,10 @@ CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_DEBUG is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1357,6 +1634,12 @@ CONFIG_INOTIFY_USER=y
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1381,15 +1664,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1397,13 +1678,35 @@ CONFIG_TMPFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
 CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
@@ -1411,19 +1714,18 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=m
 CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
 CONFIG_NFSD_V3_ACL=y
 # CONFIG_NFSD_V4 is not set
-# CONFIG_ROOT_NFS is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1490,25 +1792,83 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
-# CONFIG_PRINTK_TIME is not set
+CONFIG_PRINTK_TIME=y
 CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
@@ -1516,12 +1876,20 @@ CONFIG_CRYPTO=y
 # Crypto core or helper
 #
 CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
 CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=m
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
 CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
 CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
 CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
@@ -1549,14 +1917,20 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=m
 CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1587,28 +1961,40 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/footbridge_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/footbridge_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/footbridge_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/footbridge_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -95,7 +95,6 @@ CONFIG_ARCH_EBSA285=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA110=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/fortunet_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/fortunet_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/fortunet_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/fortunet_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -88,7 +88,6 @@ CONFIG_ARCH_FORTUNET=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_LV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/h3600_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/h3600_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/h3600_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/h3600_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,86 +1,189 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc4
-# Thu Jun  9 01:59:03 2005
+# Linux kernel version: 2.6.32-rc5
+# Sat Oct 24 00:09:30 2009
 #
 CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# 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_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
+CONFIG_AIO=y
 
 #
-# Loadable module support
+# Kernel Performance Events And Counters
 #
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_FREEZER=y
 
 #
 # System Type
 #
-# CONFIG_ARCH_CLPS7500 is not set
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # SA11x0 Implementations
@@ -102,31 +205,34 @@ CONFIG_SA1100_H3600=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
 
 #
 # Processor Features
 #
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
 
 #
 # Bus support
 #
 CONFIG_ISA=y
-CONFIG_ISA_DMA_API=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
 
 #
 # PC-card bridges
@@ -138,11 +244,41 @@ CONFIG_PCMCIA_SA1100=y
 #
 # Kernel Features
 #
-# CONFIG_SMP is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_DISCONTIGMEM=y
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -151,22 +287,26 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE=""
 # CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
 CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
-CONFIG_CPU_FREQ_STAT=y
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_STAT is not set
 # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
 # CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 CONFIG_CPU_FREQ_SA1100=y
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -183,6 +323,8 @@ CONFIG_FPE_NWFPE=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_ARTHUR is not set
@@ -191,8 +333,120 @@ CONFIG_BINFMT_ELF=y
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_APM is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_SA1100_FIR=m
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -201,15 +455,17 @@ CONFIG_PM=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
@@ -218,15 +474,20 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -249,6 +510,7 @@ CONFIG_MTD_MAP_BANK_WIDTH_4=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
@@ -265,7 +527,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 CONFIG_MTD_SA1100=y
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -273,7 +535,6 @@ CONFIG_MTD_SA1100=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -282,26 +543,21 @@ CONFIG_MTD_SA1100=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# Parallel port support
+# LPDDR flash memory drivers
 #
-# CONFIG_PARPORT is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Plug and Play support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
 # CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_XD is not set
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -309,212 +565,58 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
 
 #
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
-CONFIG_BLK_DEV_IDECD=m
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-# CONFIG_IRDA_FAST_RR is not set
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-# CONFIG_IRTTY_SIR is not set
-
-#
-# Dongle support
-#
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
-
-#
-# FIR device drivers
-#
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-CONFIG_SA1100_FIR=m
-# CONFIG_VIA_FIR is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 # CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
+# CONFIG_WLAN is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# PCMCIA network device support
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
@@ -525,10 +627,6 @@ CONFIG_PCMCIA_PCNET=y
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -537,20 +635,23 @@ CONFIG_PPP_ASYNC=m
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
+CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -560,7 +661,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -568,47 +668,42 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=m
-# CONFIG_SERIAL_8250_CS is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
@@ -618,71 +713,125 @@ CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
 
 #
-# IPMI
+# PCMCIA character devices
 #
-# CONFIG_IPMI_HANDLER is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
 
 #
-# Watchdog Cards
+# PPS support
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
 
 #
-# Ftape, the floppy tape device driver
+# Memory mapped GPIO expanders:
 #
-# CONFIG_DRM is not set
 
 #
-# PCMCIA character devices
+# I2C GPIO expanders:
 #
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
 
 #
-# TPM devices
+# PCI GPIO expanders:
 #
 
 #
-# I2C support
+# SPI GPIO expanders:
 #
-# CONFIG_I2C is not set
 
 #
-# Misc devices
+# AC97 GPIO expanders:
 #
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multimedia devices
+# Sonics Silicon Backplane
 #
-# CONFIG_VIDEO_DEV is not set
+# CONFIG_SSB is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multifunction device drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+CONFIG_HTC_EGPIO=y
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP_SA11X0 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
 CONFIG_FB_SA1100=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -691,65 +840,54 @@ CONFIG_FB_SA1100=y
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
-
-#
-# Logo configuration
-#
 # CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
 
 #
-# MMC/SD Card support
+# TI VLYNQ
 #
-# CONFIG_MMC is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -771,16 +909,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -788,34 +923,37 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=m
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
-CONFIG_NFSD_TCP=y
+# CONFIG_NFSD_V4 is not set
 CONFIG_LOCKD=y
 CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -831,10 +969,6 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
@@ -875,20 +1009,34 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_DEBUG_USER is not set
 
 #
@@ -896,21 +1044,120 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
 
 #
-# Cryptographic options
+# Crypto core or helper
 #
-# CONFIG_CRYPTO is not set
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
 
 #
-# Hardware crypto devices
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
 #
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/h5000_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/h5000_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/h5000_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/h5000_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -206,7 +206,6 @@ CONFIG_PXA25x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/h7201_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/h7201_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/h7201_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/h7201_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,6 @@ CONFIG_CPU_H7201=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_LV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/h7202_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/h7202_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/h7202_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/h7202_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -91,7 +91,6 @@ CONFIG_CPU_H7202=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_LV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/hackkit_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/hackkit_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/hackkit_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/hackkit_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,6 @@ CONFIG_SA1100_HACKKIT=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/htcherald_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/htcherald_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/htcherald_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/htcherald_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1144 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Sat Dec  5 12:16:24 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# 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_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+CONFIG_ARCH_OMAP1=y
+# CONFIG_ARCH_OMAP2 is not set
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+CONFIG_OMAP_MPU_TIMER=y
+# CONFIG_OMAP_32K_TIMER is not set
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+# CONFIG_OMAP_LL_DEBUG_NONE is not set
+CONFIG_OMAP_SERIAL_WAKE=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+
+#
+# OMAP Core Type
+#
+# CONFIG_ARCH_OMAP730 is not set
+CONFIG_ARCH_OMAP850=y
+# CONFIG_ARCH_OMAP15XX is not set
+# CONFIG_ARCH_OMAP16XX is not set
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP_HTCWIZARD is not set
+CONFIG_MACH_HERALD=y
+
+#
+# OMAP CPU Speed
+#
+# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set
+CONFIG_OMAP_ARM_195MHZ=y
+# CONFIG_OMAP_ARM_182MHZ is not set
+# CONFIG_OMAP_ARM_168MHZ is not set
+# CONFIG_OMAP_ARM_120MHZ is not set
+# CONFIG_OMAP_ARM_60MHZ is not set
+# CONFIG_OMAP_ARM_30MHZ is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM925T=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_CPU_DCACHE_WRITETHROUGH=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 ip=dhcp"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_OMAP=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_OMAP=y
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+# CONFIG_FB_OMAP_DMA_TUNE is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_OMAP=y
+CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_OMAP=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_PCOMP=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/igep0020_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/igep0020_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/igep0020_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/igep0020_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1553 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc6
+# Fri Nov 13 12:01:17 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_NONE is not set
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3517EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+# CONFIG_MACH_OMAP_3630SDP is not set
+CONFIG_MACH_IGEP0020=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+CONFIG_LIB80211_CRYPT_WEP=m
+CONFIG_LIB80211_CRYPT_CCMP=m
+CONFIG_LIB80211_CRYPT_TKIP=m
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=m
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_EEPROM_93CX6=m
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+CONFIG_AT76C50X_USB=m
+CONFIG_USB_ZD1201=m
+CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_RTL8187=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+CONFIG_P54_SPI=m
+CONFIG_ATH_COMMON=m
+CONFIG_AR9170_USB=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_B43=m
+# CONFIG_B43_SDIO is not set
+# CONFIG_B43_PHY_LP is not set
+CONFIG_B43_HWRNG=y
+# CONFIG_B43_DEBUG is not set
+CONFIG_B43LEGACY=m
+CONFIG_B43LEGACY_HWRNG=y
+# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_B43LEGACY_DMA=y
+CONFIG_B43LEGACY_PIO=y
+CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
+# CONFIG_B43LEGACY_DMA_MODE is not set
+# CONFIG_B43LEGACY_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2X00_LIB_USB=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_HT=y
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+# CONFIG_RT2X00_DEBUG is not set
+CONFIG_WL12XX=m
+# CONFIG_WL1251 is not set
+# CONFIG_WL1271 is not set
+# CONFIG_IWM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+# CONFIG_USB_ALI_M5632 is not set
+# CONFIG_USB_AN2720 is not set
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+# CONFIG_USB_EPSON2888 is not set
+# CONFIG_USB_KC2190 is not set
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SDIOHOST_POSSIBLE=y
+# CONFIG_SSB_SDIOHOST is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_OMAP=y
+CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/integrator_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/integrator_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/integrator_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/integrator_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -92,7 +92,6 @@ CONFIG_ARCH_INTEGRATOR_AP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_ARM920T=y
 # CONFIG_CPU_ARM922T is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/iop13xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/iop13xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/iop13xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/iop13xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -163,7 +163,6 @@ CONFIG_PLAT_IOP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/iop32x_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/iop32x_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/iop32x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/iop32x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -168,7 +168,6 @@ CONFIG_PLAT_IOP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/iop33x_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/iop33x_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/iop33x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/iop33x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -198,7 +198,6 @@ CONFIG_PLAT_IOP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ixp2000_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ixp2000_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ixp2000_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ixp2000_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -151,7 +151,6 @@ CONFIG_ARCH_IXDP2X01=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ixp23xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ixp23xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ixp23xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ixp23xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,6 @@ CONFIG_MACH_ROADRUNNER=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ixp4xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ixp4xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ixp4xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ixp4xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,6 @@ CONFIG_IXP4XX_NPE=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/jornada720_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/jornada720_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/jornada720_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/jornada720_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -202,7 +202,6 @@ CONFIG_SA1100_SSP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/kafa_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/kafa_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/kafa_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/kafa_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -132,7 +132,6 @@ CONFIG_MACH_KAFA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/kb9202_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/kb9202_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/kb9202_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/kb9202_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -230,7 +230,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/kirkwood_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/kirkwood_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/kirkwood_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/kirkwood_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,7 +201,6 @@ CONFIG_PLAT_ORION=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_FEROCEON=y
 # CONFIG_CPU_FEROCEON_OLD_ID is not set
 CONFIG_CPU_32v5=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/ks8695_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/ks8695_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/ks8695_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/ks8695_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,6 @@ CONFIG_MACH_DSM320=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM922T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lart_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lart_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lart_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lart_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -99,7 +99,6 @@ CONFIG_SA1100_LART=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/loki_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/loki_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/loki_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/loki_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -174,7 +174,6 @@ CONFIG_PLAT_ORION=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_FEROCEON=y
 # CONFIG_CPU_FEROCEON_OLD_ID is not set
 CONFIG_CPU_32v5=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lpd270_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lpd270_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lpd270_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lpd270_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -143,7 +143,6 @@ CONFIG_PXA27x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lpd7a400_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lpd7a400_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lpd7a400_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lpd7a400_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -95,7 +95,6 @@ CONFIG_LPD7A40X_CPLD_SSP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM922T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lpd7a404_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lpd7a404_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lpd7a404_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lpd7a404_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,6 @@ CONFIG_ARCH_LH7A404=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM922T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lubbock_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lubbock_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lubbock_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lubbock_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -92,7 +92,6 @@ CONFIG_PXA25x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/lusl7200_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/lusl7200_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/lusl7200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/lusl7200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,6 @@ CONFIG_ARCH_L7200=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_LV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/magician_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/magician_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/magician_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/magician_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,6 @@ CONFIG_PXA_HAVE_BOARD_IRQS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mainstone_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mainstone_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mainstone_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mainstone_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -93,7 +93,6 @@ CONFIG_IWMMXT=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mini2440_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mini2440_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mini2440_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mini2440_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -256,7 +256,6 @@ CONFIG_MACH_MINI2440=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/msm_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/msm_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/msm_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/msm_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -155,7 +155,6 @@ CONFIG_MSM_SMD=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mv78xx0_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mv78xx0_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mv78xx0_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mv78xx0_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,6 @@ CONFIG_PLAT_ORION=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_FEROCEON=y
 CONFIG_CPU_FEROCEON_OLD_ID=y
 CONFIG_CPU_32v5=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx1ads_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx1ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx1ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx1ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -88,7 +88,6 @@ CONFIG_ARCH_MX1ADS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx1_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx1_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -190,7 +190,6 @@ CONFIG_MXC_IRQ_PRIOR=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx21_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx21_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx21_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx21_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -185,7 +185,6 @@ CONFIG_MXC_PWM=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx27_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx27_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx27_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx27_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -207,7 +207,6 @@ CONFIG_MXC_PWM=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx31pdk_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx31pdk_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx31pdk_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx31pdk_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -173,7 +173,6 @@ CONFIG_MACH_MX31_3DS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/mx3_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/mx3_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/mx3_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/mx3_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Tue Jul 28 14:11:34 2009
+# Linux kernel version: 2.6.32-rc5
+# Sun Nov  1 22:56:24 2009
 #
 CONFIG_ARM=y
 CONFIG_HAVE_PWM=y
@@ -9,7 +9,6 @@ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -46,11 +45,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -87,16 +87,14 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -139,6 +137,7 @@ CONFIG_FREEZER=y
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
@@ -153,6 +152,7 @@ CONFIG_ARCH_MXC=y
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -175,18 +175,22 @@ CONFIG_ARCH_MXC=y
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # Freescale MXC Implementations
 #
 # CONFIG_ARCH_MX1 is not set
 # CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
 CONFIG_ARCH_MX3=y
+# CONFIG_ARCH_MXC91231 is not set
 CONFIG_ARCH_MX31=y
 CONFIG_ARCH_MX35=y
 
@@ -205,6 +209,7 @@ CONFIG_MACH_QONG=y
 CONFIG_MACH_PCM043=y
 CONFIG_MACH_ARMADILLO5X0=y
 CONFIG_MACH_MX35_3DS=y
+CONFIG_MACH_KZM_ARM11_01=y
 CONFIG_MXC_IRQ_PRIOR=y
 CONFIG_MXC_PWM=y
 CONFIG_ARCH_HAS_RNGA=y
@@ -213,12 +218,11 @@ CONFIG_ARCH_MXC_IOMUX_V3=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
 CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -236,6 +240,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_OUTER_CACHE=y
 CONFIG_CACHE_L2X0=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -257,6 +262,8 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -277,6 +284,7 @@ CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
 # CONFIG_UACCESS_WITH_MEMCPY is not set
@@ -326,6 +334,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -367,6 +376,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -407,6 +417,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
@@ -416,9 +427,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
@@ -587,14 +598,12 @@ CONFIG_DNET=y
 # CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC=y
 # CONFIG_FEC2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -608,6 +617,7 @@ CONFIG_FEC=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -630,7 +640,14 @@ CONFIG_DEVKMEM=y
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -649,6 +666,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -681,15 +699,17 @@ CONFIG_I2C_IMX=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
@@ -712,6 +732,10 @@ CONFIG_GPIOLIB=y
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 CONFIG_W1=y
 
 #
@@ -734,7 +758,6 @@ CONFIG_W1_SLAVE_THERM=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -759,12 +782,24 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 CONFIG_MFD_WM8350=y
 CONFIG_MFD_WM8350_CONFIG_MODE_0=y
 CONFIG_MFD_WM8352_CONFIG_MODE_0=y
 CONFIG_MFD_WM8350_I2C=y
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_WM8350=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
 CONFIG_MEDIA_SUPPORT=y
 
 #
@@ -874,10 +909,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_MXC=y
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 CONFIG_DMADEVICES=y
@@ -896,16 +933,11 @@ CONFIG_DMA_ENGINE=y
 # CONFIG_ASYNC_TX_DMA is not set
 # CONFIG_DMATEST is not set
 # CONFIG_AUXDISPLAY is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-CONFIG_REGULATOR_WM8350=y
-# CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -921,6 +953,7 @@ CONFIG_REGULATOR_WM8350=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -995,7 +1028,6 @@ CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1033,6 +1065,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1062,7 +1095,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1104,11 +1136,13 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/n770_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/n770_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/n770_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/n770_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_216MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/n8x0_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/n8x0_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/n8x0_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/n8x0_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,6 @@ CONFIG_MACH_NOKIA_N8X0=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/neocore926_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/neocore926_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/neocore926_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/neocore926_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -218,7 +218,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/neponset_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/neponset_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/neponset_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/neponset_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,6 @@ CONFIG_ASSABET_NEPONSET=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/netwinder_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/netwinder_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/netwinder_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/netwinder_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -89,7 +89,6 @@ CONFIG_FOOTBRIDGE_HOST=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA110=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/netx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/netx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/netx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/netx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -122,7 +122,6 @@ CONFIG_MACH_NXEB500HMI=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/nhk8815_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/nhk8815_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/nhk8815_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/nhk8815_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,6 @@ CONFIG_I2C_BITBANG_8815NHK=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/nuc910_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/nuc910_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/nuc910_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/nuc910_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,904 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30
+# Wed Jun 10 22:09:25 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_ARCH_W90X900=y
+CONFIG_CPU_W90P910=y
+
+#
+# W90P910 Machines
+#
+CONFIG_MACH_W90P910EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/nuc950_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/nuc950_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/nuc950_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/nuc950_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,921 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc7
+# Tue Nov 17 12:31:33 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_W90X900=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CPU_NUC950=y
+
+#
+# W90P910 Machines
+#
+# CONFIG_MACH_W90P910EVB is not set
+
+#
+# NUC950 Machines
+#
+CONFIG_MACH_W90P950EVB=y
+
+#
+# NUC960 Machines
+#
+# CONFIG_MACH_W90N960EVB is not set
+
+#
+# NUC932 Machines
+#
+# CONFIG_MACH_NUC932EVB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/nuc960_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/nuc960_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/nuc960_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/nuc960_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,921 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc7
+# Tue Nov 17 12:20:11 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_W90X900=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CPU_NUC960=y
+
+#
+# W90P910 Machines
+#
+# CONFIG_MACH_W90P910EVB is not set
+
+#
+# NUC950 Machines
+#
+# CONFIG_MACH_W90P950EVB is not set
+
+#
+# NUC960 Machines
+#
+CONFIG_MACH_W90N960EVB=y
+
+#
+# NUC932 Machines
+#
+# CONFIG_MACH_NUC932EVB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_2430sdp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_2430sdp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_2430sdp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_2430sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -197,7 +197,6 @@ CONFIG_MACH_OMAP_2430SDP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_3430sdp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3430sdp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_3430sdp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3430sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-omap1
-# Tue Jun 23 10:36:45 2009
+# Linux kernel version: 2.6.31-rc9-omap1
+# Tue Sep 15 16:48:34 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,14 +17,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_OPROFILE_ARMV7=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -61,12 +58,15 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -79,7 +79,7 @@ CONFIG_KALLSYMS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
-# CONFIG_ELF_CORE is not set
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -88,21 +88,29 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
+# CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
-CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -110,12 +118,11 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -126,11 +133,11 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_FREEZER=y
 
 #
@@ -142,12 +149,14 @@ CONFIG_FREEZER=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -156,24 +165,25 @@ CONFIG_FREEZER=y
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
 
 #
 # TI OMAP Implementations
@@ -182,17 +192,19 @@ CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_ARCH_OMAP1 is not set
 # CONFIG_ARCH_OMAP2 is not set
 CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
 
 #
 # OMAP Feature Selections
 #
 # CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
 # CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
-# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX=y
 CONFIG_OMAP_MUX_DEBUG=y
 CONFIG_OMAP_MUX_WARNINGS=y
 CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
@@ -200,7 +212,8 @@ CONFIG_OMAP_DM_TIMER=y
 CONFIG_OMAP_LL_DEBUG_UART1=y
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
 # CONFIG_OMAP_LL_DEBUG_UART3 is not set
-CONFIG_OMAP_SERIAL_WAKE=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
 CONFIG_ARCH_OMAP34XX=y
 CONFIG_ARCH_OMAP3430=y
 
@@ -210,13 +223,15 @@ CONFIG_ARCH_OMAP3430=y
 # CONFIG_MACH_OMAP3_BEAGLE is not set
 # CONFIG_MACH_OMAP_LDP is not set
 # CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
 # CONFIG_MACH_OMAP3_PANDORA is not set
 CONFIG_MACH_OMAP_3430SDP=y
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
 
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
@@ -234,12 +249,15 @@ CONFIG_CPU_CP15_MMU=y
 # Processor Features
 #
 CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
+# CONFIG_ARM_THUMBEE is not set
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
-# CONFIG_OUTER_CACHE is not set
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -262,10 +280,10 @@ CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=128
 CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+CONFIG_OABI_COMPAT=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -277,9 +295,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_LEDS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -288,8 +309,7 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyS2,115200 root=/dev/mmcblk0p3 rootwait debug"
 # CONFIG_XIP_KERNEL is not set
-CONFIG_KEXEC=y
-CONFIG_ATAGS_PROC=y
+# CONFIG_KEXEC is not set
 
 #
 # CPU Power Management
@@ -318,6 +338,9 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 #
 # At least one emulation must be selected
 #
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
 CONFIG_VFP=y
 CONFIG_VFPv3=y
 CONFIG_NEON=y
@@ -326,8 +349,9 @@ CONFIG_NEON=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_HAVE_AOUT=y
-CONFIG_BINFMT_AOUT=m
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=y
 
 #
@@ -345,9 +369,8 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
+# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -372,7 +395,7 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
@@ -383,25 +406,7 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MROUTE is not set
+# CONFIG_IPV6 is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -419,6 +424,8 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -429,56 +436,9 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BT_HCIBTUSB is not set
-# CONFIG_BT_HCIBTSDIO is not set
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-# CONFIG_BT_HCIUART_LL is not set
-CONFIG_BT_HCIBCM203X=y
-CONFIG_BT_HCIBPA10X=y
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-CONFIG_CFG80211=y
-# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
-CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-CONFIG_LIB80211=y
-CONFIG_LIB80211_CRYPT_WEP=m
-CONFIG_LIB80211_CRYPT_CCMP=m
-CONFIG_LIB80211_CRYPT_TKIP=m
-CONFIG_MAC80211=y
-
-#
-# Rate control algorithm selection
-#
-CONFIG_MAC80211_RC_PID=y
-# CONFIG_MAC80211_RC_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT="pid"
-# CONFIG_MAC80211_MESH is not set
-CONFIG_MAC80211_LEDS=y
-# CONFIG_MAC80211_DEBUGFS is not set
-# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -493,9 +453,7 @@ CONFIG_MAC80211_LEDS=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -506,7 +464,7 @@ CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
 
@@ -526,8 +484,10 @@ CONFIG_MTD_BLOCK=y
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -538,6 +498,10 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -546,6 +510,9 @@ CONFIG_MTD_CFI_I2=y
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_OMAP_NOR=y
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -569,6 +536,7 @@ CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_ECC_SMC is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
 # CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_OMAP2 is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
@@ -589,20 +557,21 @@ CONFIG_MTD_NAND_IDS=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
+# CONFIG_OMAP_STI is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -611,14 +580,15 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_AT24 is not set
 # CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_LEGACY is not set
-CONFIG_EEPROM_93CX6=m
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
@@ -632,12 +602,8 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -655,34 +621,18 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_DELAY=m
-# CONFIG_DM_UEVENT is not set
+# CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
+# CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
+# CONFIG_TUN is not set
 # CONFIG_VETH is not set
 CONFIG_PHYLIB=y
 
@@ -695,7 +645,7 @@ CONFIG_PHYLIB=y
 # CONFIG_LXT_PHY is not set
 # CONFIG_CICADA_PHY is not set
 # CONFIG_VITESSE_PHY is not set
-CONFIG_SMSC_PHY=y
+# CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
@@ -710,8 +660,10 @@ CONFIG_MII=y
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
-CONFIG_SMC911X=m
-CONFIG_SMSC911X=m
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -720,33 +672,16 @@ CONFIG_SMSC911X=m
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-CONFIG_LIBERTAS=y
-CONFIG_LIBERTAS_USB=y
-CONFIG_LIBERTAS_SDIO=y
-CONFIG_LIBERTAS_DEBUG=y
-# CONFIG_LIBERTAS_THINFIRM is not set
-CONFIG_USB_ZD1201=m
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-CONFIG_RTL8187=m
-# CONFIG_MAC80211_HWSIM is not set
-CONFIG_P54_COMMON=m
-CONFIG_P54_USB=m
-# CONFIG_IWLWIFI_LEDS is not set
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_RT2X00 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -755,41 +690,14 @@ CONFIG_HOSTAP_FIRMWARE_NVRAM=y
 #
 # USB Network Adapters
 #
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_AX8817X=y
-CONFIG_USB_NET_CDCETHER=y
-CONFIG_USB_NET_DM9601=m
-# CONFIG_USB_NET_SMSC95XX is not set
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_CDC_SUBSET=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-# CONFIG_PPPOL2TP is not set
+# CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -805,10 +713,7 @@ CONFIG_INPUT=y
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
@@ -818,47 +723,54 @@ CONFIG_INPUT_EVDEV=y
 #
 CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_GPIO is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
 CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
@@ -878,6 +790,7 @@ CONFIG_SERIAL_8250_RSA=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -885,6 +798,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -900,6 +814,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_OMAP=y
@@ -925,8 +840,6 @@ CONFIG_I2C_OMAP=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -975,68 +888,8 @@ CONFIG_GPIO_TWL4030=y
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
 # CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=m
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -1046,7 +899,8 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_OMAP_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_TWL4030_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
@@ -1077,237 +931,9 @@ CONFIG_TWL4030_CORE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L2_COMMON=m
-CONFIG_VIDEO_ALLOW_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-CONFIG_DVB_CORE=m
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=m
-CONFIG_MEDIA_TUNER_TDA8290=m
-CONFIG_MEDIA_TUNER_TDA827X=m
-CONFIG_MEDIA_TUNER_TDA18271=m
-CONFIG_MEDIA_TUNER_TDA9887=m
-CONFIG_MEDIA_TUNER_TEA5761=m
-CONFIG_MEDIA_TUNER_TEA5767=m
-CONFIG_MEDIA_TUNER_MT20XX=m
-CONFIG_MEDIA_TUNER_MT2060=m
-CONFIG_MEDIA_TUNER_MT2266=m
-CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_MXL5005S=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEO_V4L1=m
-CONFIG_VIDEO_TVEEPROM=m
-CONFIG_VIDEO_TUNER=m
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-CONFIG_VIDEO_MSP3400=m
-CONFIG_VIDEO_CS53L32A=m
-CONFIG_VIDEO_WM8775=m
-CONFIG_VIDEO_SAA711X=m
-CONFIG_VIDEO_CX25840=m
-CONFIG_VIDEO_CX2341X=m
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_VIDEO_AU0828 is not set
-# CONFIG_SOC_CAMERA is not set
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=m
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_GSPCA is not set
-CONFIG_VIDEO_PVRUSB2=m
-CONFIG_VIDEO_PVRUSB2_SYSFS=y
-CONFIG_VIDEO_PVRUSB2_DVB=y
-# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
-# CONFIG_VIDEO_EM28XX is not set
-CONFIG_VIDEO_USBVISION=m
-CONFIG_VIDEO_USBVIDEO=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_QUICKCAM_MESSENGER=m
-# CONFIG_USB_ET61X251 is not set
-CONFIG_VIDEO_OVCAMCHIP=m
-CONFIG_USB_W9968CF=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-# CONFIG_USB_ZC0301 is not set
-CONFIG_USB_PWC=m
-# CONFIG_USB_PWC_DEBUG is not set
-CONFIG_USB_ZR364XX=m
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_S2255 is not set
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_SI470X is not set
-# CONFIG_USB_MR800 is not set
-# CONFIG_RADIO_TEA5764 is not set
-# CONFIG_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-# CONFIG_TTPCI_EEPROM is not set
-
-#
-# Supported USB Adapters
-#
-CONFIG_DVB_USB=m
-# CONFIG_DVB_USB_DEBUG is not set
-CONFIG_DVB_USB_A800=m
-CONFIG_DVB_USB_DIBUSB_MB=m
-# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
-CONFIG_DVB_USB_DIBUSB_MC=m
-CONFIG_DVB_USB_DIB0700=m
-CONFIG_DVB_USB_UMT_010=m
-CONFIG_DVB_USB_CXUSB=m
-CONFIG_DVB_USB_M920X=m
-CONFIG_DVB_USB_GL861=m
-CONFIG_DVB_USB_AU6610=m
-CONFIG_DVB_USB_DIGITV=m
-CONFIG_DVB_USB_VP7045=m
-CONFIG_DVB_USB_VP702X=m
-CONFIG_DVB_USB_GP8PSK=m
-CONFIG_DVB_USB_NOVA_T_USB2=m
-CONFIG_DVB_USB_TTUSB2=m
-CONFIG_DVB_USB_DTT200U=m
-CONFIG_DVB_USB_OPERA1=m
-CONFIG_DVB_USB_AF9005=m
-CONFIG_DVB_USB_AF9005_REMOTE=m
-# CONFIG_DVB_USB_DW2102 is not set
-# CONFIG_DVB_USB_CINERGY_T2 is not set
-# CONFIG_DVB_USB_ANYSEE is not set
-# CONFIG_DVB_USB_DTV5100 is not set
-# CONFIG_DVB_USB_AF9015 is not set
-# CONFIG_DVB_SIANO_SMS1XXX is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_FLEXCOP is not set
-
-#
-# Supported DVB Frontends
-#
-
-#
-# Customise DVB Frontends
-#
-# CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# Multistandard (satellite) frontends
-#
-# CONFIG_DVB_STB0899 is not set
-# CONFIG_DVB_STB6100 is not set
-
-#
-# DVB-S (satellite) frontends
-#
-CONFIG_DVB_CX24110=m
-CONFIG_DVB_CX24123=m
-CONFIG_DVB_MT312=m
-CONFIG_DVB_S5H1420=m
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-CONFIG_DVB_STV0299=m
-CONFIG_DVB_TDA8083=m
-CONFIG_DVB_TDA10086=m
-# CONFIG_DVB_TDA8261 is not set
-CONFIG_DVB_VES1X93=m
-CONFIG_DVB_TUNER_ITD1000=m
-# CONFIG_DVB_TUNER_CX24113 is not set
-CONFIG_DVB_TDA826X=m
-CONFIG_DVB_TUA6100=m
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-CONFIG_DVB_SP8870=m
-CONFIG_DVB_SP887X=m
-CONFIG_DVB_CX22700=m
-CONFIG_DVB_CX22702=m
-# CONFIG_DVB_DRX397XD is not set
-CONFIG_DVB_L64781=m
-CONFIG_DVB_TDA1004X=m
-CONFIG_DVB_NXT6000=m
-CONFIG_DVB_MT352=m
-CONFIG_DVB_ZL10353=m
-CONFIG_DVB_DIB3000MB=m
-CONFIG_DVB_DIB3000MC=m
-CONFIG_DVB_DIB7000M=m
-CONFIG_DVB_DIB7000P=m
-CONFIG_DVB_TDA10048=m
-
-#
-# DVB-C (cable) frontends
-#
-CONFIG_DVB_VES1820=m
-CONFIG_DVB_TDA10021=m
-CONFIG_DVB_TDA10023=m
-CONFIG_DVB_STV0297=m
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-CONFIG_DVB_NXT200X=m
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-CONFIG_DVB_BCM3510=m
-CONFIG_DVB_LGDT330X=m
-# CONFIG_DVB_LGDT3304 is not set
-CONFIG_DVB_S5H1409=m
-CONFIG_DVB_AU8522=m
-CONFIG_DVB_S5H1411=m
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-CONFIG_DVB_PLL=m
-CONFIG_DVB_TUNER_DIB0070=m
-
-#
-# SEC control devices for DVB-S
-#
-CONFIG_DVB_LNBP21=m
-# CONFIG_DVB_ISL6405 is not set
-CONFIG_DVB_ISL6421=m
-# CONFIG_DVB_LGS8GL5 is not set
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_AF9013 is not set
-# CONFIG_DAB is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1336,10 +962,32 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 #
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
-CONFIG_FB_OMAP=y
-# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_LCD_VGA is not set
 # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
-CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=4
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_RFBI is not set
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP2_DSS_SDI is not set
+# CONFIG_OMAP2_DSS_DSI is not set
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC=y
+CONFIG_PANEL_SHARP_LS037V7DW01=y
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1366,53 +1014,10 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_SEQUENCER=m
-# CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_PCM_OSS_PLUGINS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_DEBUG=y
-# CONFIG_SND_DEBUG_VERBOSE is not set
-# CONFIG_SND_PCM_XRUN_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SPI=y
-CONFIG_SND_USB=y
-CONFIG_SND_USB_AUDIO=y
-CONFIG_SND_USB_CAIAQ=m
-CONFIG_SND_USB_CAIAQ_INPUT=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_MCBSP=y
-# CONFIG_SND_OMAP_SOC_OVERO is not set
-CONFIG_SND_OMAP_SOC_SDP3430=y
-# CONFIG_SND_OMAP_SOC_OMAP3_PANDORA is not set
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_TWL4030=y
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-CONFIG_HID_DEBUG=y
+# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1425,35 +1030,35 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
-CONFIG_HID_A4TECH=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_BELKIN=y
-CONFIG_HID_CHERRY=y
-CONFIG_HID_CHICONY=y
-CONFIG_HID_CYPRESS=y
-CONFIG_HID_EZKEY=y
-CONFIG_HID_GYRATION=y
-CONFIG_HID_LOGITECH=y
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MONTEREY=y
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
-CONFIG_HID_PANTHERLORD=y
-# CONFIG_PANTHERLORD_FF is not set
-CONFIG_HID_PETALYNX=y
-CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
-CONFIG_HID_SUNPLUS=y
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
 # CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -1461,9 +1066,9 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 #
 # Miscellaneous USB options
 #
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_OTG=y
 # CONFIG_USB_OTG_WHITELIST is not set
@@ -1476,8 +1081,12 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_OHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
@@ -1493,23 +1102,25 @@ CONFIG_USB_MUSB_SOC=y
 CONFIG_USB_MUSB_OTG=y
 CONFIG_USB_GADGET_MUSB_HDRC=y
 CONFIG_USB_MUSB_HDRC_HCD=y
-CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=y
-CONFIG_USB_WDM=y
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1551,14 +1162,14 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
+CONFIG_USB_TEST=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
@@ -1574,25 +1185,29 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
 # CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
 # CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
 # CONFIG_USB_GADGET_M66592 is not set
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 # CONFIG_USB_GADGET_FSL_QE is not set
 # CONFIG_USB_GADGET_CI13XXX is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_USB_CDC_COMPOSITE=m
 
 #
 # OTG and related infrastructure
@@ -1601,6 +1216,7 @@ CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_ISP1301_OMAP is not set
 CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -1617,7 +1233,6 @@ CONFIG_SDIO_UART=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_OMAP is not set
 CONFIG_MMC_OMAP_HS=y
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
@@ -1628,9 +1243,16 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_OMAP_DEBUG is not set
+# CONFIG_LEDS_OMAP is not set
+# CONFIG_LEDS_OMAP_PWM is not set
 # CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -1639,7 +1261,12 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1672,6 +1299,7 @@ CONFIG_RTC_DRV_TWL4030=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1703,6 +1331,7 @@ CONFIG_RTC_DRV_TWL4030=y
 # on-CPU RTC drivers
 #
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
@@ -1711,32 +1340,36 @@ CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
 CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
 #
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1749,16 +1382,18 @@ CONFIG_QFMT_V2=y
 CONFIG_QUOTACTL=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
 
 #
 # DOS/FAT/NT Filesystems
@@ -1793,15 +1428,13 @@ CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_JFFS2_CMODE_NONE is not set
 CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_JFFS2_CMODE_SIZE is not set
@@ -1816,20 +1449,20 @@ CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1917,12 +1550,15 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1932,10 +1568,9 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
@@ -1950,30 +1585,20 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
-CONFIG_NOP_TRACER=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_RING_BUFFER=y
-CONFIG_TRACING=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
 
 #
 # Security options
@@ -1982,10 +1607,6 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_XOR_BLOCKS=m
-CONFIG_ASYNC_CORE=m
-CONFIG_ASYNC_MEMCPY=m
-CONFIG_ASYNC_XOR=m
 CONFIG_CRYPTO=y
 
 #
@@ -2000,13 +1621,15 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
-CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Authenticated Encryption with Associated Data
@@ -2021,58 +1644,58 @@ CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CBC=y
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_XTS is not set
 
 #
 # Hash modes
 #
-CONFIG_CRYPTO_HMAC=m
-CONFIG_CRYPTO_XCBC=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_MD4=m
+# CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_RMD128 is not set
 # CONFIG_CRYPTO_RMD160 is not set
 # CONFIG_CRYPTO_RMD256 is not set
 # CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
 
 #
 # Ciphers
 #
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
 CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_SALSA20 is not set
 # CONFIG_CRYPTO_SEED is not set
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
 
 #
 # Compression
 #
-CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -2080,6 +1703,7 @@ CONFIG_CRYPTO_DEFLATE=m
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -2087,17 +1711,16 @@ CONFIG_CRYPTO_HW=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=y
-CONFIG_CRC16=m
-CONFIG_CRC_T10DIF=y
-CONFIG_CRC_ITU_T=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
-CONFIG_CRC7=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_3630sdp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3630sdp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_3630sdp_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_3630sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1610 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc6
+# Thu Nov 12 12:21:37 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+# CONFIG_OMAP_LL_DEBUG_NONE is not set
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+CONFIG_MACH_OMAP_3630SDP=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+# CONFIG_HDQ_MASTER_OMAP is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_OMAP_WATCHDOG is not set
+# CONFIG_TWL4030_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_USB_MUSB_DEBUG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_TWL4030 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_beagle_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_beagle_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_beagle_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_beagle_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -52,8 +52,8 @@ CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -213,7 +213,6 @@ CONFIG_MACH_OMAP3_BEAGLE=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2118 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Tue Dec  1 14:04:02 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_LL_DEBUG_NONE=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP3_BEAGLE=y
+CONFIG_MACH_OMAP_LDP=y
+CONFIG_MACH_OVERO=y
+CONFIG_MACH_OMAP3EVM=y
+CONFIG_MACH_OMAP3517EVM=y
+CONFIG_MACH_OMAP3_PANDORA=y
+CONFIG_MACH_OMAP_3430SDP=y
+CONFIG_MACH_NOKIA_RX51=y
+CONFIG_MACH_OMAP_ZOOM2=y
+CONFIG_MACH_OMAP_ZOOM3=y
+CONFIG_MACH_CM_T35=y
+CONFIG_MACH_IGEP0020=y
+CONFIG_MACH_OMAP_3630SDP=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_CFG80211_DEBUGFS is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+CONFIG_MTD_OOPS=y
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_OMAP_NOR=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_PREFETCH=y
+# CONFIG_MTD_NAND_OMAP_PREFETCH_DMA is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+# CONFIG_MTD_ONENAND_GENERIC is not set
+CONFIG_MTD_ONENAND_OMAP2=y
+# CONFIG_MTD_ONENAND_OTP is not set
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_DM is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_USB=y
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
+CONFIG_LIBERTAS_DEBUG=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+# CONFIG_USB_NET_CDC_EEM is not set
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=y
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+CONFIG_USB_NET_CDC_SUBSET=y
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=y
+# CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_TWL4030=y
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_TWL4030_PWRBUTTON=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+# CONFIG_HDQ_MASTER_OMAP is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_TWL4030_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_TWL4030_CODEC is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_OMAP=y
+CONFIG_FB_OMAP_LCD_VGA=y
+# CONFIG_FB_OMAP_031M3R is not set
+# CONFIG_FB_OMAP_048M3R is not set
+CONFIG_FB_OMAP_079M3R=y
+# CONFIG_FB_OMAP_092M9R is not set
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_LCD_MIPID is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_PCM_XRUN_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+# CONFIG_SND_OMAP_SOC_OVERO is not set
+# CONFIG_SND_OMAP_SOC_OMAP3EVM is not set
+# CONFIG_SND_OMAP_SOC_SDP3430 is not set
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
+# CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE is not set
+# CONFIG_SND_OMAP_SOC_ZOOM2 is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_TWL4030=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_USB_MUSB_DEBUG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+CONFIG_USB_WDM=y
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=y
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=y
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+CONFIG_LOCK_STAT=y
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_evm_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_evm_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_evm_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_evm_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -59,8 +59,8 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -220,7 +220,6 @@ CONFIG_MACH_OMAP3EVM=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
@@ -617,8 +616,8 @@ CONFIG_MII=y
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
 # CONFIG_ETHOC is not set
-CONFIG_SMC911X=y
-# CONFIG_SMSC911X is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -676,13 +675,19 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_TWL4030=y
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -1126,7 +1131,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_OMAP is not set
-CONFIG_MMC_OMAP_HS=m
+CONFIG_MMC_OMAP_HS=y
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_ACCESSIBILITY is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_pandora_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_pandora_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_pandora_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_pandora_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -51,8 +51,9 @@ CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
+
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -210,7 +211,6 @@ CONFIG_MACH_OMAP3_PANDORA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_touchbook_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_touchbook_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap3_touchbook_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap3_touchbook_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2430 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Fri Dec  4 16:02:17 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_NONE is not set
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3517EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+CONFIG_MACH_OMAP3_TOUCHBOOK=y
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_OMAP_ZOOM3 is not set
+# CONFIG_MACH_CM_T35 is not set
+# CONFIG_MACH_IGEP0020 is not set
+# CONFIG_MACH_OMAP_3630SDP is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=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_NET_IPGRE=m
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+# CONFIG_DEFAULT_BIC is not set
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+# CONFIG_IPV6_PIMSM_V2 is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_DEBUG=y
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_DCCP=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+CONFIG_BT_HCIBTSDIO=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+CONFIG_BT_HCIBFUSB=y
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+CONFIG_AF_RXRPC=m
+# CONFIG_AF_RXRPC_DEBUG is not set
+# CONFIG_RXKAD is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_WIMAX=m
+CONFIG_WIMAX_DEBUG_LEVEL=8
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_OMAP2=y
+CONFIG_MTD_NAND_OMAP_PREFETCH=y
+# CONFIG_MTD_NAND_OMAP_PREFETCH_DMA is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+CONFIG_EEPROM_93CX6=y
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+CONFIG_ISCSI_TCP=m
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID6_PQ=m
+# CONFIG_ASYNC_RAID6_TEST is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+# CONFIG_DM_LOG_USERSPACE is not set
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_QL is not set
+# CONFIG_DM_MULTIPATH_ST is not set
+CONFIG_DM_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
+
+#
+# WiMAX Wireless Broadband devices
+#
+# CONFIG_WIMAX_I2400M_USB is not set
+# CONFIG_WIMAX_I2400M_SDIO is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_ATM_DRIVERS is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOATM is not set
+CONFIG_PPPOL2TP=m
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_TWL4030 is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_TWL4030_PWRBUTTON=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+CONFIG_BATTERY_BQ27x00=y
+# CONFIG_BATTERY_MAX17040 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=y
+# CONFIG_TWL4030_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_TWL4030_CODEC is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_JACK=y
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_RAWMIDI_SEQ=m
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_OXU210HP_HCD=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP210X is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_IUU=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+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_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_MOTOROLA=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+CONFIG_USB_SERIAL_SIEMENS_MPI=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+# CONFIG_USB_SERIAL_SYMBOL is not set
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_OPTICON=m
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_ATM is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ZERO_HNPTEST=y
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+CONFIG_USB_GPIO_VBUS=y
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=m
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_W35UND is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_OTUS is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_INPUT_MIMIO is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_DST is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_PLAN9AUTH is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_USB_SERIAL_QUATECH2 is not set
+# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_FB_UDL is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+# CONFIG_REISERFS_FS_POSIX_ACL is not set
+# CONFIG_REISERFS_FS_SECURITY is not set
+CONFIG_JFS_FS=m
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+# CONFIG_JFFS2_CMODE_PRIORITY is not set
+# CONFIG_JFFS2_CMODE_SIZE is not set
+CONFIG_JFFS2_CMODE_FAVOURLZO=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_XATTR=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_UPCALL is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+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_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=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_4430sdp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_4430sdp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_4430sdp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_4430sdp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,26 +1,29 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc7
-# Tue Jun  9 12:36:23 2009
+# Linux kernel version: 2.6.32
+# Sun Dec  6 23:37:45 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -39,11 +42,12 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -52,8 +56,7 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -70,7 +73,6 @@ CONFIG_UID16=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -83,6 +85,10 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -90,13 +96,16 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -110,7 +119,7 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -131,6 +140,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
@@ -142,8 +152,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -166,10 +178,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # TI OMAP Implementations
@@ -190,9 +205,12 @@ CONFIG_ARCH_OMAP4=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
-# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_NONE is not set
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
 
 #
 # OMAP Board Type
@@ -202,12 +220,11 @@ CONFIG_MACH_OMAP_4430SDP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
 CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_PABRT_V7=y
 CONFIG_CPU_CACHE_V7=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -222,9 +239,10 @@ CONFIG_CPU_CP15_MMU=y
 # CONFIG_ARM_THUMB is not set
 # CONFIG_ARM_THUMBEE is not set
 # CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_DCACHE_DISABLE=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
 # CONFIG_ARM_ERRATA_460075 is not set
@@ -245,18 +263,20 @@ CONFIG_ARM_GIC=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_SMP=y
 CONFIG_HAVE_ARM_SCU=y
-CONFIG_HAVE_ARM_TWD=y
 CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_NR_CPUS=2
 # CONFIG_HOTPLUG_CPU is not set
-CONFIG_LOCAL_TIMERS=y
-# CONFIG_PREEMPT is not set
+# CONFIG_LOCAL_TIMERS is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
 CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
 CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
+CONFIG_OABI_COMPAT=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
@@ -271,10 +291,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-# CONFIG_UNEVICTABLE_LRU is not set
 CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -298,9 +321,11 @@ CONFIG_CMDLINE="root=/dev/ram0 rw mem=12
 #
 # At least one emulation must be selected
 #
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
 CONFIG_VFP=y
 CONFIG_VFPv3=y
-# CONFIG_NEON is not set
+CONFIG_NEON=y
 
 #
 # Userspace binary formats
@@ -325,6 +350,7 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -342,6 +368,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -355,6 +382,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -427,6 +455,11 @@ CONFIG_HW_RANDOM=y
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -447,11 +480,14 @@ CONFIG_GPIOLIB=y
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -472,21 +508,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -511,14 +534,17 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -535,9 +561,12 @@ CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -601,7 +630,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 
 #
 # Partition Types
@@ -673,23 +701,24 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_DETECT_SOFTLOCKUP is not set
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
 CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -708,31 +737,22 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -754,7 +774,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -796,11 +815,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_apollon_2420_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_apollon_2420_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_apollon_2420_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_apollon_2420_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,6 @@ CONFIG_MACH_OMAP_APOLLON=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1510_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1510_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1510_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1510_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -205,7 +205,6 @@ CONFIG_OMAP_ARM_168MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1610_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1610_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1610_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1610_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -207,7 +207,6 @@ CONFIG_OMAP_ARM_192MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1710_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1710_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_1710_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_1710_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,7 +201,6 @@ CONFIG_OMAP_ARM_192MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_2420_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_2420_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_generic_2420_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_generic_2420_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,6 @@ CONFIG_ARCH_OMAP2420=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_h2_1610_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h2_1610_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_h2_1610_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h2_1610_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -231,7 +231,6 @@ CONFIG_OMAP_ARM_60MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_h4_2420_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h4_2420_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_h4_2420_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_h4_2420_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,7 +201,6 @@ CONFIG_MACH_OMAP_H4=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_innovator_1510_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_innovator_1510_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_innovator_1510_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_innovator_1510_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -205,7 +205,6 @@ CONFIG_OMAP_ARM_168MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_innovator_1610_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_innovator_1610_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_innovator_1610_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_innovator_1610_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -206,7 +206,6 @@ CONFIG_OMAP_ARM_192MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_ldp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_ldp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_ldp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_ldp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -49,8 +49,8 @@ CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -214,7 +214,6 @@ CONFIG_MACH_OMAP_LDP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_osk_5912_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_osk_5912_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_osk_5912_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_osk_5912_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,6 @@ CONFIG_OMAP_ARM_192MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_perseus2_730_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_perseus2_730_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_perseus2_730_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_perseus2_730_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -199,7 +199,6 @@ CONFIG_OMAP_ARM_182MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_zoom2_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom2_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_zoom2_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom2_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -59,8 +59,8 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -202,7 +202,8 @@ CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
 # CONFIG_OMAP_LL_DEBUG_UART1 is not set
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_LL_DEBUG_NONE=y
 CONFIG_ARCH_OMAP34XX=y
 CONFIG_ARCH_OMAP3430=y
 
@@ -221,7 +222,6 @@ CONFIG_MACH_OMAP_ZOOM2=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
@@ -609,7 +609,8 @@ CONFIG_INPUT_EVDEV=y
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_TWL4030=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/omap_zoom3_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom3_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/omap_zoom3_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/omap_zoom3_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1610 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc6
+# Thu Nov 12 13:04:07 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_LL_DEBUG_NONE=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
+# CONFIG_MACH_OMAP_ZOOM2 is not set
+# CONFIG_MACH_CM_T35 is not set
+CONFIG_MACH_OMAP_ZOOM3=y
+# CONFIG_MACH_OMAP_3630SDP is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_TWL4030=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+# CONFIG_HDQ_MASTER_OMAP is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_OMAP_WATCHDOG is not set
+# CONFIG_TWL4030_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_TWL4030=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_USB_MUSB_DEBUG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_TWL4030 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/onearm_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/onearm_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/onearm_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/onearm_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -161,7 +161,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/orion5x_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/orion5x_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/orion5x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/orion5x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,6 @@ CONFIG_PLAT_ORION=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_FEROCEON=y
 CONFIG_CPU_FEROCEON_OLD_ID=y
 CONFIG_CPU_32v5=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/overo_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/overo_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/overo_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/overo_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -54,8 +54,8 @@ CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED=y is not set
+# CONFIG_SYSFS_DEPRECATED_V2=y is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -217,7 +217,6 @@ CONFIG_MACH_OVERO=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/palmte_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/palmte_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/palmte_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/palmte_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/palmtt_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/palmtt_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/palmtt_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/palmtt_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -176,7 +176,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/palmz71_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/palmz71_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/palmz71_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/palmz71_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -200,7 +200,6 @@ CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/palmz72_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/palmz72_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/palmz72_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/palmz72_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -209,7 +209,6 @@ CONFIG_PXA_PWM=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pcm027_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pcm027_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pcm027_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pcm027_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -168,7 +168,6 @@ CONFIG_PXA27x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/picotux200_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/picotux200_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/picotux200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/picotux200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -168,7 +168,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pleb_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pleb_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pleb_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pleb_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -100,7 +100,6 @@ CONFIG_SA1100_PLEB=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pnx4008_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pnx4008_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pnx4008_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pnx4008_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -121,7 +121,6 @@ CONFIG_ARCH_PNX4008=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pxa168_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pxa168_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pxa168_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pxa168_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -184,7 +184,6 @@ CONFIG_PLAT_PXA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_MOHAWK=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pxa255-idp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pxa255-idp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pxa255-idp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pxa255-idp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -92,7 +92,6 @@ CONFIG_PXA25x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pxa3xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pxa3xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pxa3xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pxa3xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -240,7 +240,6 @@ CONFIG_PLAT_PXA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSC3=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/pxa910_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/pxa910_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/pxa910_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/pxa910_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -184,7 +184,6 @@ CONFIG_PLAT_PXA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_MOHAWK=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/qil-a9260_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/qil-a9260_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/qil-a9260_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/qil-a9260_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -195,7 +195,6 @@ CONFIG_AT91_EARLY_USART0=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/realview_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/realview_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/realview_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/realview_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -184,7 +184,6 @@ CONFIG_MACH_REALVIEW_PB1176=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 # CONFIG_CPU_ARM926T is not set
 CONFIG_CPU_V6=y
 # CONFIG_CPU_32v6K is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/realview-smp_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/realview-smp_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/realview-smp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/realview-smp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,6 @@ CONFIG_REALVIEW_HIGH_PHYS_OFFSET=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 # CONFIG_CPU_ARM926T is not set
 CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/rpc_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/rpc_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/rpc_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/rpc_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -150,7 +150,6 @@ CONFIG_ARCH_ACORN=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM610=y
 CONFIG_CPU_ARM710=y
 CONFIG_CPU_SA110=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/rx51_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/rx51_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/rx51_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/rx51_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,6 @@ CONFIG_MACH_NOKIA_RX51=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
@@ -784,7 +783,7 @@ CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_KEYBOARD_GPIO=m
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/s3c2410_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/s3c2410_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/s3c2410_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/s3c2410_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -277,7 +277,6 @@ CONFIG_MACH_SMDK2443=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/s3c6400_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/s3c6400_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/s3c6400_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/s3c6400_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -192,7 +192,6 @@ CONFIG_SMDK6410_SD_CH0=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/s5pc100_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/s5pc100_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/s5pc100_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/s5pc100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -202,7 +202,6 @@ CONFIG_MACH_SMDKC100=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_V7=y
 CONFIG_CPU_32v7=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/sam9_l9260_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/sam9_l9260_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/sam9_l9260_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/sam9_l9260_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -175,7 +175,6 @@ CONFIG_MTD_AT91_DATAFLASH_CARD=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/shannon_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/shannon_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/shannon_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/shannon_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -99,7 +99,6 @@ CONFIG_SA1100_SHANNON=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/shark_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/shark_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/shark_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/shark_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -173,7 +173,6 @@ CONFIG_ARCH_SHARK=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA110=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/simpad_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/simpad_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/simpad_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/simpad_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -101,7 +101,6 @@ CONFIG_SA1100_SIMPAD=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_SA1100=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/spitz_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/spitz_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/spitz_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/spitz_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,6 @@ CONFIG_PXA_SSP=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/stmp378x_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/stmp378x_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/stmp378x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/stmp378x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -193,7 +193,6 @@ CONFIG_MACH_STMP378X=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/stmp37xx_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/stmp37xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/stmp37xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/stmp37xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -182,7 +182,6 @@ CONFIG_MACH_STMP37XX=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/sx1_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/sx1_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/sx1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/sx1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,6 @@ CONFIG_OMAP_ARM_168MHZ=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM925T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/tct_hammer_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/tct_hammer_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/tct_hammer_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/tct_hammer_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -215,7 +215,6 @@ CONFIG_MACH_TCT_HAMMER=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/trizeps4_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/trizeps4_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/trizeps4_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/trizeps4_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -156,7 +156,6 @@ CONFIG_PXA27x=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/u300_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/u300_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/u300_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/u300_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Sat Oct 17 23:32:24 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Jan  6 00:01:36 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -46,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -119,14 +120,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +183,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -177,6 +206,7 @@ CONFIG_ARCH_U300=y
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
 
 #
 # ST-Ericsson AB U300/U330/U335/U365 Platform
@@ -207,7 +237,6 @@ CONFIG_MACH_U300_SPIDUMMY=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
@@ -266,12 +295,10 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
@@ -500,14 +527,21 @@ CONFIG_MTD_NAND_IDS=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -518,6 +552,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -540,6 +575,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -646,7 +682,6 @@ CONFIG_I2C_STU300=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -662,6 +697,8 @@ CONFIG_SPI_MASTER=y
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_GPIO is not set
 CONFIG_SPI_PL022=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -709,6 +746,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -717,6 +755,8 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_AB3100_CORE=y
 CONFIG_AB3100_OTP=y
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
@@ -724,6 +764,7 @@ CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
 # CONFIG_REGULATOR_LP3971 is not set
 CONFIG_REGULATOR_AB3100=y
 # CONFIG_REGULATOR_TPS65023 is not set
@@ -841,7 +882,9 @@ CONFIG_LEDS_CLASS=y
 # CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -883,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -912,7 +956,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 CONFIG_RTC_DRV_AB3100=y
 
@@ -927,6 +973,15 @@ CONFIG_DMADEVICES=y
 #
 # DMA Devices
 #
+CONFIG_COH901318=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -1019,7 +1074,7 @@ CONFIG_MISC_FILESYSTEMS=y
 CONFIG_MSDOS_PARTITION=y
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
 # CONFIG_NLS_CODEPAGE_850 is not set
@@ -1136,6 +1191,7 @@ CONFIG_ARM_UNWIND=y
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -1143,7 +1199,11 @@ CONFIG_ARM_UNWIND=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/u8500_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/u8500_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/u8500_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/u8500_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,679 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Mon Nov 30 11:11:29 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# 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_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_ARCH_U8500=y
+CONFIG_PLAT_NOMADIK=y
+CONFIG_HAS_MTU=y
+
+#
+# ST-Ericsson platform type
+#
+
+#
+# ST-Ericsson Multicore Mobile Platforms
+#
+CONFIG_MACH_U8500_MOP=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PL022=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/usb-a9260_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/usb-a9260_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/usb-a9260_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/usb-a9260_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -195,7 +195,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/usb-a9263_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/usb-a9263_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/usb-a9263_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/usb-a9263_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -187,7 +187,6 @@ CONFIG_AT91_EARLY_DBGU=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/versatile_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/versatile_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/versatile_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/versatile_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,6 @@ CONFIG_MACH_VERSATILE_AB=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/viper_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/viper_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/viper_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/viper_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,6 @@ CONFIG_PXA_HAVE_ISA_IRQS=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/w90p910_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/w90p910_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/w90p910_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/w90p910_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,905 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Wed Jun 10 22:09:25 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-CONFIG_USER_NS=y
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
-# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
-# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-# CONFIG_EMBEDDED is not set
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_COMPAT_BRK=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_TRACEPOINTS=y
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-# CONFIG_MODULES is not set
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-CONFIG_ARCH_W90X900=y
-CONFIG_CPU_W90P910=y
-
-#
-# W90P910 Machines
-#
-CONFIG_MACH_W90P910EVB=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
-# CONFIG_XIP_KERNEL is not set
-CONFIG_KEXEC=y
-CONFIG_ATAGS_PROC=y
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_NET is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_PROC_FS is not set
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TC6393XB is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
-CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-CONFIG_GENERIC_ACL=y
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=y
-CONFIG_ROMFS_BACKED_BY_BLOCK=y
-# CONFIG_ROMFS_BACKED_BY_MTD is not set
-# CONFIG_ROMFS_BACKED_BY_BOTH is not set
-CONFIG_ROMFS_ON_BLOCK=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_MEMORY_INIT=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_RING_BUFFER=y
-CONFIG_TRACING=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-CONFIG_BLK_DEV_IO_TRACE=y
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_ARM_UNWIND=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
-
-#
-# Library routines
-#
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC32 is not set
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/xcep_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/xcep_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/xcep_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/xcep_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -208,7 +208,6 @@ CONFIG_PLAT_PXA=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/yl9200_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/yl9200_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/yl9200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/yl9200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -183,7 +183,6 @@ CONFIG_MACH_YL9200=y
 #
 # Processor Type
 #
-CONFIG_CPU_32=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_32v4T=y
 CONFIG_CPU_ABRT_EV4T=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/configs/zeus_defconfig linux-libre-2.6.33-gnu1/arch/arm/configs/zeus_defconfig
--- linux-libre-2.6.32-gnu1/arch/arm/configs/zeus_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/configs/zeus_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2031 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Dec  8 20:27:05 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=13
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# 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_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Intel/Marvell Dev Platforms (sorted by hardware release time)
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_ZYLONITE300 is not set
+# CONFIG_MACH_ZYLONITE320 is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+
+#
+# Third Party Dev Platforms (sorted by vendor name)
+#
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_ARCH_VIPER is not set
+CONFIG_MACH_ARCOM_ZEUS=y
+# CONFIG_MACH_BALLOON3 is not set
+# CONFIG_MACH_CSB726 is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_MACH_STARGATE2 is not set
+# CONFIG_MACH_XCEP is not set
+# CONFIG_TRIZEPS_PXA is not set
+CONFIG_ARCOM_PCMCIA=y
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
+
+#
+# End-user Products (sorted by vendor name)
+#
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_PXA_EZX is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+CONFIG_PXA_HAVE_BOARD_IRQS=y
+CONFIG_PXA_HAVE_ISA_IRQS=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ISA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=m
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_SOC_COMMON=m
+CONFIG_PCMCIA_PXA2XX=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA_PROBE=y
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=31:02 rootfstype=jffs2 ro console=ttyS0,115200"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+# CONFIG_BT_SCO is not set
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=m
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_LEGACY is not set
+CONFIG_PATA_PCMCIA=m
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_WINBOND_VLB is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=4
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DNET is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+CONFIG_HERMES=m
+CONFIG_HERMES_CACHE_FW_ON_INIT=y
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+# CONFIG_P54_COMMON is not set
+CONFIG_RT2X00=m
+# CONFIG_RT2500USB is not set
+CONFIG_RT73USB=m
+# CONFIG_RT2800USB is not set
+CONFIG_RT2X00_LIB_USB=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+# CONFIG_RT2X00_DEBUG is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+CONFIG_TOUCHSCREEN_FUJITSU=m
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+CONFIG_TOUCHSCREEN_ELO=m
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_HTCPEN=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=7
+CONFIG_SERIAL_8250_RUNTIME_UARTS=7
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_PXA is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PXA2XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+CONFIG_SENSORS_LM75=m
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=m
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_GENERIC=m
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_LIB=m
+CONFIG_SND_PXA2XX_LIB_AC97=y
+CONFIG_SND_PXA2XX_AC97=m
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=m
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+CONFIG_RTC_DRV_ISL1208=m
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SA1100 is not set
+CONFIG_RTC_DRV_PXA=m
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,8 @@
 #endif
 
 #if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
-    defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020)
+    defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
+    defined(CONFIG_CPU_ARM1026)
 # define MULTI_CACHE 1
 #endif
 
@@ -154,16 +155,16 @@
  *	Please note that the implementation of these, and the required
  *	effects are cache-type (VIVT/VIPT/PIPT) specific.
  *
- *	flush_cache_kern_all()
+ *	flush_kern_all()
  *
  *		Unconditionally clean and invalidate the entire cache.
  *
- *	flush_cache_user_mm(mm)
+ *	flush_user_all()
  *
  *		Clean and invalidate all user space cache entries
  *		before a change of page tables.
  *
- *	flush_cache_user_range(start, end, flags)
+ *	flush_user_range(start, end, flags)
  *
  *		Clean and invalidate a range of cache entries in the
  *		specified address space before a change of page tables.
@@ -179,6 +180,20 @@
  *		- start  - virtual start address
  *		- end    - virtual end address
  *
+ *	coherent_user_range(start, end)
+ *
+ *		Ensure coherency between the Icache and the Dcache in the
+ *		region described by start, end.  If you have non-snooping
+ *		Harvard caches, you need to implement this function.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ *
+ *	flush_kern_dcache_area(kaddr, size)
+ *
+ *		Ensure that the data held in page is written back.
+ *		- kaddr  - page address
+ *		- size   - region size
+ *
  *	DMA Cache Coherency
  *	===================
  *
@@ -211,7 +226,7 @@ struct cpu_cache_fns {
 
 	void (*coherent_kern_range)(unsigned long, unsigned long);
 	void (*coherent_user_range)(unsigned long, unsigned long);
-	void (*flush_kern_dcache_page)(void *);
+	void (*flush_kern_dcache_area)(void *, size_t);
 
 	void (*dma_inv_range)(const void *, const void *);
 	void (*dma_clean_range)(const void *, const void *);
@@ -236,7 +251,7 @@ extern struct cpu_cache_fns cpu_cache;
 #define __cpuc_flush_user_range		cpu_cache.flush_user_range
 #define __cpuc_coherent_kern_range	cpu_cache.coherent_kern_range
 #define __cpuc_coherent_user_range	cpu_cache.coherent_user_range
-#define __cpuc_flush_dcache_page	cpu_cache.flush_kern_dcache_page
+#define __cpuc_flush_dcache_area	cpu_cache.flush_kern_dcache_area
 
 /*
  * These are private to the dma-mapping API.  Do not use directly.
@@ -255,14 +270,14 @@ extern struct cpu_cache_fns cpu_cache;
 #define __cpuc_flush_user_range		__glue(_CACHE,_flush_user_cache_range)
 #define __cpuc_coherent_kern_range	__glue(_CACHE,_coherent_kern_range)
 #define __cpuc_coherent_user_range	__glue(_CACHE,_coherent_user_range)
-#define __cpuc_flush_dcache_page	__glue(_CACHE,_flush_kern_dcache_page)
+#define __cpuc_flush_dcache_area	__glue(_CACHE,_flush_kern_dcache_area)
 
 extern void __cpuc_flush_kern_all(void);
 extern void __cpuc_flush_user_all(void);
 extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
 extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
 extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
-extern void __cpuc_flush_dcache_page(void *);
+extern void __cpuc_flush_dcache_area(void *, size_t);
 
 /*
  * These are private to the dma-mapping API.  Do not use directly.
@@ -331,15 +346,15 @@ static inline void outer_flush_range(uns
  * Convert calls to our calling convention.
  */
 #define flush_cache_all()		__cpuc_flush_kern_all()
-#ifndef CONFIG_CPU_CACHE_VIPT
-static inline void flush_cache_mm(struct mm_struct *mm)
+
+static inline void vivt_flush_cache_mm(struct mm_struct *mm)
 {
 	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
 		__cpuc_flush_user_all();
 }
 
 static inline void
-flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
 	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
 		__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
@@ -347,7 +362,7 @@ flush_cache_range(struct vm_area_struct
 }
 
 static inline void
-flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
 {
 	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
 		unsigned long addr = user_addr & PAGE_MASK;
@@ -356,7 +371,7 @@ flush_cache_page(struct vm_area_struct *
 }
 
 static inline void
-flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
 			 unsigned long uaddr, void *kaddr,
 			 unsigned long len, int write)
 {
@@ -365,6 +380,16 @@ flush_ptrace_access(struct vm_area_struc
 		__cpuc_coherent_kern_range(addr, addr + len);
 	}
 }
+
+#ifndef CONFIG_CPU_CACHE_VIPT
+#define flush_cache_mm(mm) \
+		vivt_flush_cache_mm(mm)
+#define flush_cache_range(vma,start,end) \
+		vivt_flush_cache_range(vma,start,end)
+#define flush_cache_page(vma,addr,pfn) \
+		vivt_flush_cache_page(vma,addr,pfn)
+#define flush_ptrace_access(vma,page,ua,ka,len,write) \
+		vivt_flush_ptrace_access(vma,page,ua,ka,len,write)
 #else
 extern void flush_cache_mm(struct mm_struct *mm);
 extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
@@ -408,10 +433,9 @@ extern void flush_ptrace_access(struct v
  * about to change to user space.  This is the same method as used on SPARC64.
  * See update_mmu_cache for the user space part.
  */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *);
 
-extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
-
 static inline void __flush_icache_all(void)
 {
 #ifdef CONFIG_ARM_ERRATA_411920
@@ -439,7 +463,7 @@ static inline void flush_kernel_dcache_p
 {
 	/* highmem pages are always flushed upon kunmap already */
 	if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page))
-		__cpuc_flush_dcache_page(page_address(page));
+		__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
 }
 
 #define flush_dcache_mmap_lock(mapping) \
@@ -456,13 +480,6 @@ static inline void flush_kernel_dcache_p
  */
 #define flush_icache_page(vma,page)	do { } while (0)
 
-static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt,
-	unsigned offset, size_t size)
-{
-	const void *start = (void __force *)virt + offset;
-	dmac_inv_range(start, start + size);
-}
-
 /*
  * flush_cache_vmap() is used when creating mappings (eg, via vmap,
  * vmalloc, ioremap etc) in kernel space for pages.  On non-VIPT
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/cpu.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/cpu.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/cpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/cpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #define __ASM_ARM_CPU_H
 
 #include <linux/percpu.h>
+#include <linux/cpu.h>
 
 struct cpuinfo_arm {
 	struct cpu	cpu;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/dma.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -138,12 +138,12 @@ extern int  get_dma_residue(unsigned int
 #define NO_DMA	255
 #endif
 
+#endif /* CONFIG_ISA_DMA_API */
+
 #ifdef CONFIG_PCI
 extern int isa_dma_bridge_buggy;
 #else
 #define isa_dma_bridge_buggy    (0)
 #endif
 
-#endif /* CONFIG_ISA_DMA_API */
-
 #endif /* __ASM_ARM_DMA_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,20 +15,15 @@
  * must not be used by drivers.
  */
 #ifndef __arch_page_to_dma
-
-#if !defined(CONFIG_HIGHMEM)
 static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
 {
-	return (dma_addr_t)__virt_to_bus((unsigned long)page_address(page));
+	return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
 }
-#elif defined(__pfn_to_bus)
-static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+
+static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
 {
-	return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+	return pfn_to_page(__bus_to_pfn(addr));
 }
-#else
-#error "this machine class needs to define __arch_page_to_dma to use HIGHMEM"
-#endif
 
 static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
 {
@@ -45,6 +40,11 @@ static inline dma_addr_t page_to_dma(str
 	return __arch_page_to_dma(dev, page);
 }
 
+static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
+{
+	return __arch_dma_to_page(dev, addr);
+}
+
 static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
 {
 	return __arch_dma_to_virt(dev, addr);
@@ -257,9 +257,11 @@ extern int dma_needs_bounce(struct devic
  */
 extern dma_addr_t dma_map_single(struct device *, void *, size_t,
 		enum dma_data_direction);
+extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+		enum dma_data_direction);
 extern dma_addr_t dma_map_page(struct device *, struct page *,
 		unsigned long, size_t, enum dma_data_direction);
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+extern void dma_unmap_page(struct device *, dma_addr_t, size_t,
 		enum dma_data_direction);
 
 /*
@@ -352,7 +354,6 @@ static inline void dma_unmap_single(stru
 {
 	/* nothing to do */
 }
-#endif /* CONFIG_DMABOUNCE */
 
 /**
  * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
@@ -371,8 +372,9 @@ static inline void dma_unmap_single(stru
 static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir)
 {
-	dma_unmap_single(dev, handle, size, dir);
+	/* nothing to do */
 }
+#endif /* CONFIG_DMABOUNCE */
 
 /**
  * dma_sync_single_range_for_cpu
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -101,7 +101,6 @@ extern int arm_elf_read_implies_exec(con
 int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #define ELF_CORE_COPY_TASK_REGS dump_task_regs
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/cache-tauros2.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/cache-tauros2.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/cache-tauros2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/cache-tauros2.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/include/asm/hardware/cache-tauros2.h
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * 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.
+ */
+
+extern void __init tauros2_init(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/coresight.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/coresight.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/coresight.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/coresight.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,165 @@
+/*
+ * linux/arch/arm/include/asm/hardware/coresight.h
+ *
+ * CoreSight components' registers
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This 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_HARDWARE_CORESIGHT_H
+#define __ASM_HARDWARE_CORESIGHT_H
+
+#define TRACER_ACCESSED_BIT	0
+#define TRACER_RUNNING_BIT	1
+#define TRACER_CYCLE_ACC_BIT	2
+#define TRACER_ACCESSED		BIT(TRACER_ACCESSED_BIT)
+#define TRACER_RUNNING		BIT(TRACER_RUNNING_BIT)
+#define TRACER_CYCLE_ACC	BIT(TRACER_CYCLE_ACC_BIT)
+
+struct tracectx {
+	unsigned int	etb_bufsz;
+	void __iomem	*etb_regs;
+	void __iomem	*etm_regs;
+	unsigned long	flags;
+	int		ncmppairs;
+	int		etm_portsz;
+	struct device	*dev;
+	struct clk	*emu_clk;
+	struct mutex	mutex;
+};
+
+#define TRACER_TIMEOUT 10000
+
+#define etm_writel(t, v, x) \
+	(__raw_writel((v), (t)->etm_regs + (x)))
+#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+
+/* CoreSight Management Registers */
+#define CSMR_LOCKACCESS 0xfb0
+#define CSMR_LOCKSTATUS 0xfb4
+#define CSMR_AUTHSTATUS 0xfb8
+#define CSMR_DEVID	0xfc8
+#define CSMR_DEVTYPE	0xfcc
+/* CoreSight Component Registers */
+#define CSCR_CLASS	0xff4
+
+#define CSCR_PRSR	0x314
+
+#define UNLOCK_MAGIC	0xc5acce55
+
+/* ETM control register, "ETM Architecture", 3.3.1 */
+#define ETMR_CTRL		0
+#define ETMCTRL_POWERDOWN	1
+#define ETMCTRL_PROGRAM		(1 << 10)
+#define ETMCTRL_PORTSEL		(1 << 11)
+#define ETMCTRL_DO_CONTEXTID	(3 << 14)
+#define ETMCTRL_PORTMASK1	(7 << 4)
+#define ETMCTRL_PORTMASK2	(1 << 21)
+#define ETMCTRL_PORTMASK	(ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
+#define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21)
+#define ETMCTRL_DO_CPRT		(1 << 1)
+#define ETMCTRL_DATAMASK	(3 << 2)
+#define ETMCTRL_DATA_DO_DATA	(1 << 2)
+#define ETMCTRL_DATA_DO_ADDR	(1 << 3)
+#define ETMCTRL_DATA_DO_BOTH	(ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
+#define ETMCTRL_BRANCH_OUTPUT	(1 << 8)
+#define ETMCTRL_CYCLEACCURATE	(1 << 12)
+
+/* ETM configuration code register */
+#define ETMR_CONFCODE		(0x04)
+
+/* ETM trace start/stop resource control register */
+#define ETMR_TRACESSCTRL	(0x18)
+
+/* ETM trigger event register */
+#define ETMR_TRIGEVT		(0x08)
+
+/* address access type register bits, "ETM architecture",
+ * table 3-27 */
+/* - access type */
+#define ETMAAT_IFETCH		0
+#define ETMAAT_IEXEC		1
+#define ETMAAT_IEXECPASS	2
+#define ETMAAT_IEXECFAIL	3
+#define ETMAAT_DLOADSTORE	4
+#define ETMAAT_DLOAD		5
+#define ETMAAT_DSTORE		6
+/* - comparison access size */
+#define ETMAAT_JAVA		(0 << 3)
+#define ETMAAT_THUMB		(1 << 3)
+#define ETMAAT_ARM		(3 << 3)
+/* - data value comparison control */
+#define ETMAAT_NOVALCMP		(0 << 5)
+#define ETMAAT_VALMATCH		(1 << 5)
+#define ETMAAT_VALNOMATCH	(3 << 5)
+/* - exact match */
+#define ETMAAT_EXACTMATCH	(1 << 7)
+/* - context id comparator control */
+#define ETMAAT_IGNCONTEXTID	(0 << 8)
+#define ETMAAT_VALUE1		(1 << 8)
+#define ETMAAT_VALUE2		(2 << 8)
+#define ETMAAT_VALUE3		(3 << 8)
+/* - security level control */
+#define ETMAAT_IGNSECURITY	(0 << 10)
+#define ETMAAT_NSONLY		(1 << 10)
+#define ETMAAT_SONLY		(2 << 10)
+
+#define ETMR_COMP_VAL(x)	(0x40 + (x) * 4)
+#define ETMR_COMP_ACC_TYPE(x)	(0x80 + (x) * 4)
+
+/* ETM status register, "ETM Architecture", 3.3.2 */
+#define ETMR_STATUS		(0x10)
+#define ETMST_OVERFLOW		(1 << 0)
+#define ETMST_PROGBIT		(1 << 1)
+#define ETMST_STARTSTOP		(1 << 2)
+#define ETMST_TRIGGER		(1 << 3)
+
+#define etm_progbit(t)		(etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT)
+#define etm_started(t)		(etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP)
+#define etm_triggered(t)	(etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER)
+
+#define ETMR_TRACEENCTRL2	0x1c
+#define ETMR_TRACEENCTRL	0x24
+#define ETMTE_INCLEXCL		(1 << 24)
+#define ETMR_TRACEENEVT		0x20
+#define ETMCTRL_OPTS		(ETMCTRL_DO_CPRT | \
+				ETMCTRL_DATA_DO_ADDR | \
+				ETMCTRL_BRANCH_OUTPUT | \
+				ETMCTRL_DO_CONTEXTID)
+
+/* ETB registers, "CoreSight Components TRM", 9.3 */
+#define ETBR_DEPTH		0x04
+#define ETBR_STATUS		0x0c
+#define ETBR_READMEM		0x10
+#define ETBR_READADDR		0x14
+#define ETBR_WRITEADDR		0x18
+#define ETBR_TRIGGERCOUNT	0x1c
+#define ETBR_CTRL		0x20
+#define ETBR_FORMATTERCTRL	0x304
+#define ETBFF_ENFTC		1
+#define ETBFF_ENFCONT		(1 << 1)
+#define ETBFF_FONFLIN		(1 << 4)
+#define ETBFF_MANUAL_FLUSH	(1 << 6)
+#define ETBFF_TRIGIN		(1 << 8)
+#define ETBFF_TRIGEVT		(1 << 9)
+#define ETBFF_TRIGFL		(1 << 10)
+
+#define etb_writel(t, v, x) \
+	(__raw_writel((v), (t)->etb_regs + (x)))
+#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
+
+#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
+#define etm_unlock(t) \
+	do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+
+#define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
+#define etb_unlock(t) \
+	do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+
+#endif /* __ASM_HARDWARE_CORESIGHT_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/iop3xx.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/iop3xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/hardware/iop3xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/hardware/iop3xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -234,7 +234,13 @@ extern int iop3xx_get_init_atu(void);
 void iop3xx_map_io(void);
 void iop_init_cp6_handler(void);
 void iop_init_time(unsigned long tickrate);
-unsigned long iop_gettimeoffset(void);
+
+static inline u32 read_tmr0(void)
+{
+	u32 val;
+	asm volatile("mrc p6, 0, %0, c0, c1, 0" : "=r" (val));
+	return val;
+}
 
 static inline void write_tmr0(u32 val)
 {
@@ -253,6 +259,11 @@ static inline u32 read_tcr0(void)
 	return val;
 }
 
+static inline void write_tcr0(u32 val)
+{
+	asm volatile("mcr p6, 0, %0, c2, c1, 0" : : "r" (val));
+}
+
 static inline u32 read_tcr1(void)
 {
 	u32 val;
@@ -260,6 +271,11 @@ static inline u32 read_tcr1(void)
 	return val;
 }
 
+static inline void write_tcr1(u32 val)
+{
+	asm volatile("mcr p6, 0, %0, c3, c1, 0" : : "r" (val));
+}
+
 static inline void write_trr0(u32 val)
 {
 	asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/mach/irq.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach/irq.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/mach/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,9 +26,9 @@ extern int show_fiq_list(struct seq_file
  */
 #define do_bad_IRQ(irq,desc)				\
 do {							\
-	spin_lock(&desc->lock);				\
+	raw_spin_lock(&desc->lock);			\
 	handle_bad_irq(irq, desc);			\
-	spin_unlock(&desc->lock);			\
+	raw_spin_unlock(&desc->lock);			\
 } while(0)
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/mach-types.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach-types.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/mach-types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/mach-types.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/mach-types.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/memory.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -125,8 +125,10 @@
  * private definitions which should NOT be used outside memory.h
  * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
  */
+#ifndef __virt_to_phys
 #define __virt_to_phys(x)	((x) - PAGE_OFFSET + PHYS_OFFSET)
 #define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
 
 /*
  * Convert a physical address to a Page Frame Number and back
@@ -134,6 +136,12 @@
 #define	__phys_to_pfn(paddr)	((paddr) >> PAGE_SHIFT)
 #define	__pfn_to_phys(pfn)	((pfn) << PAGE_SHIFT)
 
+/*
+ * Convert a page to/from a physical address
+ */
+#define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
+#define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -194,7 +202,8 @@ static inline void *phys_to_virt(unsigne
 #ifndef __virt_to_bus
 #define __virt_to_bus	__virt_to_phys
 #define __bus_to_virt	__phys_to_virt
-#define __pfn_to_bus(x)	((x) << PAGE_SHIFT)
+#define __pfn_to_bus(x)	__pfn_to_phys(x)
+#define __bus_to_pfn(x)	__phys_to_pfn(x)
 #endif
 
 static inline __deprecated unsigned long virt_to_bus(void *x)
@@ -293,11 +302,6 @@ static inline __deprecated void *bus_to_
 #endif /* !CONFIG_DISCONTIGMEM */
 
 /*
- * For BIO.  "will die".  Kill me when bio_to_phys() and bvec_to_phys() die.
- */
-#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
-
-/*
  * Optional coherency support.  Currently used only by selected
  * Intel XSC3-based systems.
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/mman.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/mman.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/mman.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/mman.h	2010-02-24 13:52:17.000000000 -0500
@@ -1 +1,4 @@
 #include <asm-generic/mman.h>
+
+#define arch_mmap_check(addr, len, flags) \
+	(((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -304,13 +304,23 @@ PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
 
 static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 
+#define __pgprot_modify(prot,mask,bits)		\
+	__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
+
 /*
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-	__pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED)
+	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
 #define pgprot_writecombine(prot) \
-	__pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE)
+	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
+#if __LINUX_ARM_ARCH__ >= 7
+#define pgprot_dmacoherent(prot) \
+	__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
+#else
+#define pgprot_dmacoherent(prot) \
+	__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
+#endif
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define pmd_present(pmd)	(pmd_val(pmd))
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/proc-fns.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/proc-fns.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/proc-fns.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/proc-fns.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,206 +24,228 @@
  * CPU_NAME - the prefix for CPU related functions
  */
 
-#ifdef CONFIG_CPU_32
-# ifdef CONFIG_CPU_ARM610
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm6
-#  endif
+#ifdef CONFIG_CPU_ARM610
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm6
 # endif
-# ifdef CONFIG_CPU_ARM7TDMI
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm7tdmi
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM7TDMI
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm7tdmi
 # endif
-# ifdef CONFIG_CPU_ARM710
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm7
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM710
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm7
 # endif
-# ifdef CONFIG_CPU_ARM720T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm720
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM720T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm720
 # endif
-# ifdef CONFIG_CPU_ARM740T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm740
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM740T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm740
 # endif
-# ifdef CONFIG_CPU_ARM9TDMI
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm9tdmi
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM9TDMI
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm9tdmi
 # endif
-# ifdef CONFIG_CPU_ARM920T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm920
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM920T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm920
 # endif
-# ifdef CONFIG_CPU_ARM922T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm922
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM922T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm922
 # endif
-# ifdef CONFIG_CPU_FA526
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_fa526
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_FA526
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_fa526
 # endif
-# ifdef CONFIG_CPU_ARM925T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm925
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm925
 # endif
-# ifdef CONFIG_CPU_ARM926T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm926
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm926
 # endif
-# ifdef CONFIG_CPU_ARM940T
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm940
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM940T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm940
 # endif
-# ifdef CONFIG_CPU_ARM946E
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm946
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm946
 # endif
-# ifdef CONFIG_CPU_SA110
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_sa110
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_SA110
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_sa110
 # endif
-# ifdef CONFIG_CPU_SA1100
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_sa1100
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_sa1100
 # endif
-# ifdef CONFIG_CPU_ARM1020
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm1020
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1020
 # endif
-# ifdef CONFIG_CPU_ARM1020E
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm1020e
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1020e
 # endif
-# ifdef CONFIG_CPU_ARM1022
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm1022
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1022
 # endif
-# ifdef CONFIG_CPU_ARM1026
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_arm1026
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1026
 # endif
-# ifdef CONFIG_CPU_XSCALE
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_xscale
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_xscale
 # endif
-# ifdef CONFIG_CPU_XSC3
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_xsc3
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_xsc3
 # endif
-# ifdef CONFIG_CPU_MOHAWK
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_mohawk
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_MOHAWK
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_mohawk
 # endif
-# ifdef CONFIG_CPU_FEROCEON
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_feroceon
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_FEROCEON
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_feroceon
 # endif
-# ifdef CONFIG_CPU_V6
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_v6
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_V6
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v6
 # endif
-# ifdef CONFIG_CPU_V7
-#  ifdef CPU_NAME
-#   undef  MULTI_CPU
-#   define MULTI_CPU
-#  else
-#   define CPU_NAME cpu_v7
-#  endif
+#endif
+
+#ifdef CONFIG_CPU_V7
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v7
 # endif
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -97,9 +97,15 @@
  * stack during a system call.  Note that sizeof(struct pt_regs)
  * has to be a multiple of 8.
  */
+#ifndef __KERNEL__
 struct pt_regs {
 	long uregs[18];
 };
+#else /* __KERNEL__ */
+struct pt_regs {
+	unsigned long uregs[18];
+};
+#endif /* __KERNEL__ */
 
 #define ARM_cpsr	uregs[16]
 #define ARM_pc		uregs[15]
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,13 +17,13 @@
  * Locked value: 1
  */
 
-#define __raw_spin_is_locked(x)		((x)->lock != 0)
-#define __raw_spin_unlock_wait(lock) \
-	do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define arch_spin_is_locked(x)		((x)->lock != 0)
+#define arch_spin_unlock_wait(lock) \
+	do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -43,7 +43,7 @@ static inline void __raw_spin_lock(raw_s
 	smp_mb();
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -63,7 +63,7 @@ static inline int __raw_spin_trylock(raw
 	}
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	smp_mb();
 
@@ -86,7 +86,7 @@ static inline void __raw_spin_unlock(raw
  * just write zero since the lock is exclusively held.
  */
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
@@ -106,7 +106,7 @@ static inline void __raw_write_lock(raw_
 	smp_mb();
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
@@ -126,7 +126,7 @@ static inline int __raw_write_trylock(ra
 	}
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	smp_mb();
 
@@ -142,7 +142,7 @@ static inline void __raw_write_unlock(ra
 }
 
 /* write_can_lock - would write_trylock() succeed? */
-#define __raw_write_can_lock(x)		((x)->lock == 0)
+#define arch_write_can_lock(x)		((x)->lock == 0)
 
 /*
  * Read locks are a bit more hairy:
@@ -156,7 +156,7 @@ static inline void __raw_write_unlock(ra
  * currently active.  However, we know we won't have any write
  * locks.
  */
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp, tmp2;
 
@@ -176,7 +176,7 @@ static inline void __raw_read_lock(raw_r
 	smp_mb();
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp, tmp2;
 
@@ -198,7 +198,7 @@ static inline void __raw_read_unlock(raw
 	: "cc");
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned long tmp, tmp2 = 1;
 
@@ -215,13 +215,13 @@ static inline int __raw_read_trylock(raw
 }
 
 /* read_can_lock - would read_trylock() succeed? */
-#define __raw_read_can_lock(x)		((x)->lock < 0x80000000)
+#define arch_read_can_lock(x)		((x)->lock < 0x80000000)
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* __ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,14 +7,14 @@
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/swab.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/swab.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/swab.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/swab.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,24 @@
 #  define __SWAB_64_THRU_32__
 #endif
 
+#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6
+
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
+{
+	__asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
+	return x;
+}
+#define __arch_swab16 __arch_swab16
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+	__asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+	return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#else
+
 static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 {
 	__u32 t;
@@ -48,3 +66,4 @@ static inline __attribute_const__ __u32
 
 #endif
 
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/system.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -138,21 +138,26 @@ extern unsigned int user_debug;
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#ifndef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#define mb()		dmb()
+#define rmb()		dmb()
+#define wmb()		dmb()
+#else
 #define mb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define wmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#endif
+
+#ifndef CONFIG_SMP
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
 #define smp_wmb()	barrier()
 #else
-#define mb()		dmb()
-#define rmb()		dmb()
-#define wmb()		dmb()
-#define smp_mb()	dmb()
-#define smp_rmb()	dmb()
-#define smp_wmb()	dmb()
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
 #endif
+
 #define read_barrier_depends()		do { } while(0)
 #define smp_read_barrier_depends()	do { } while(0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/thread_notify.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/thread_notify.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/thread_notify.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/thread_notify.h	2010-02-24 13:52:17.000000000 -0500
@@ -41,7 +41,7 @@ static inline void thread_notify(unsigne
  * These are the reason codes for the thread notifier.
  */
 #define THREAD_NOTIFY_FLUSH	0
-#define THREAD_NOTIFY_RELEASE	1
+#define THREAD_NOTIFY_EXIT	1
 #define THREAD_NOTIFY_SWITCH	2
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/arm/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/arm/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -391,6 +391,7 @@
 #define __NR_pwritev			(__NR_SYSCALL_BASE+362)
 #define __NR_rt_tgsigqueueinfo		(__NR_SYSCALL_BASE+363)
 #define __NR_perf_event_open		(__NR_SYSCALL_BASE+364)
+#define __NR_recvmmsg			(__NR_SYSCALL_BASE+365)
 
 /*
  * The following SWIs are ARM private.
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/Kconfig linux-libre-2.6.33-gnu1/arch/arm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,8 @@ config ARM
 	select HAVE_KRETPROBES if (HAVE_KPROBES)
 	select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
 	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZO
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -433,6 +435,17 @@ config ARCH_L7200
 	  If you have any questions or comments about the Linux kernel port
 	  to this board, send e-mail to <sjhill@cotw.com>.
 
+config ARCH_DOVE
+	bool "Marvell Dove"
+	select PCI
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select PLAT_ORION
+	help
+	  Support for the Marvell Dove SoC 88AP510
+
 config ARCH_KIRKWOOD
 	bool "Marvell Kirkwood"
 	select CPU_FEROCEON
@@ -592,6 +605,7 @@ config ARCH_SA1100
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_MTD_XIP
 	select ARCH_HAS_CPUFREQ
+	select CPU_FREQ
 	select GENERIC_GPIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
@@ -676,6 +690,7 @@ config ARCH_DAVINCI
 	select HAVE_IDE
 	select COMMON_CLKDEV
 	select GENERIC_ALLOCATOR
+	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Support for TI's DaVinci platform.
 
@@ -687,6 +702,7 @@ config ARCH_OMAP
 	select ARCH_HAS_CPUFREQ
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
@@ -702,16 +718,38 @@ config ARCH_BCMRING
 	help
 	  Support for Broadcom's BCMRing platform.
 
+config ARCH_U8500
+	bool "ST-Ericsson U8500 Series"
+	select CPU_V7
+	select ARM_AMBA
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select COMMON_CLKDEV
+	help
+	  Support for ST-Ericsson's Ux500 architecture
+
 endchoice
 
+source "arch/arm/mach-aaec2000/Kconfig"
+
+source "arch/arm/mach-at91/Kconfig"
+
+source "arch/arm/mach-bcmring/Kconfig"
+
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-davinci/Kconfig"
+
+source "arch/arm/mach-dove/Kconfig"
+
 source "arch/arm/mach-ep93xx/Kconfig"
 
 source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-gemini/Kconfig"
 
+source "arch/arm/mach-h720x/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
 source "arch/arm/mach-iop32x/Kconfig"
@@ -726,16 +764,26 @@ source "arch/arm/mach-ixp2000/Kconfig"
 
 source "arch/arm/mach-ixp23xx/Kconfig"
 
+source "arch/arm/mach-kirkwood/Kconfig"
+
+source "arch/arm/mach-ks8695/Kconfig"
+
+source "arch/arm/mach-lh7a40x/Kconfig"
+
 source "arch/arm/mach-loki/Kconfig"
 
+source "arch/arm/mach-msm/Kconfig"
+
 source "arch/arm/mach-mv78xx0/Kconfig"
 
-source "arch/arm/mach-pxa/Kconfig"
-source "arch/arm/plat-pxa/Kconfig"
+source "arch/arm/plat-mxc/Kconfig"
 
-source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-netx/Kconfig"
 
-source "arch/arm/mach-sa1100/Kconfig"
+source "arch/arm/mach-nomadik/Kconfig"
+source "arch/arm/plat-nomadik/Kconfig"
+
+source "arch/arm/mach-ns9xxx/Kconfig"
 
 source "arch/arm/plat-omap/Kconfig"
 
@@ -745,8 +793,16 @@ source "arch/arm/mach-omap2/Kconfig"
 
 source "arch/arm/mach-orion5x/Kconfig"
 
-source "arch/arm/mach-kirkwood/Kconfig"
+source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
+
+source "arch/arm/mach-mmp/Kconfig"
 
+source "arch/arm/mach-realview/Kconfig"
+
+source "arch/arm/mach-sa1100/Kconfig"
+
+source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s3c64xx/Kconfig"
 source "arch/arm/plat-s3c/Kconfig"
@@ -772,44 +828,22 @@ if ARCH_S5PC1XX
 source "arch/arm/mach-s5pc100/Kconfig"
 endif
 
-source "arch/arm/mach-lh7a40x/Kconfig"
+source "arch/arm/mach-u300/Kconfig"
 
-source "arch/arm/mach-h720x/Kconfig"
+source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
-source "arch/arm/mach-aaec2000/Kconfig"
-
-source "arch/arm/mach-realview/Kconfig"
-
-source "arch/arm/mach-at91/Kconfig"
-
-source "arch/arm/plat-mxc/Kconfig"
-
-source "arch/arm/mach-nomadik/Kconfig"
-
-source "arch/arm/mach-netx/Kconfig"
-
-source "arch/arm/mach-ns9xxx/Kconfig"
-
-source "arch/arm/mach-davinci/Kconfig"
-
-source "arch/arm/mach-ks8695/Kconfig"
-
-source "arch/arm/mach-msm/Kconfig"
-
-source "arch/arm/mach-u300/Kconfig"
-
 source "arch/arm/mach-w90x900/Kconfig"
 
-source "arch/arm/mach-bcmring/Kconfig"
-
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
 
 config PLAT_IOP
 	bool
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_TIME
 
 config PLAT_ORION
 	bool
@@ -955,10 +989,10 @@ source "kernel/time/Kconfig"
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
-		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
+		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
 	depends on GENERIC_CLOCKEVENTS
 	select USE_GENERIC_SMP_HELPERS
-	select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4)
+	select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -1027,9 +1061,9 @@ config HOTPLUG_CPU
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
 	depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
-		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
+		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
 	default y
-	select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4)
+	select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
@@ -1330,13 +1364,9 @@ source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_SA1100
 	bool
-	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
-	default y
 
 config CPU_FREQ_SA1110
 	bool
-	depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3)
-	default y
 
 config CPU_FREQ_INTEGRATOR
 	tristate "CPUfreq driver for ARM Integrator CPUs"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/Kconfig.debug linux-libre-2.6.33-gnu1/arch/arm/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/arm/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,14 @@ config DEBUG_LL
 	  in the kernel.  This is helpful if you are debugging code that
 	  executes before the console is initialized.
 
+config EARLY_PRINTK
+	bool "Early printk"
+	depends on DEBUG_LL
+	help
+	  Say Y here if you want to have an early console using the
+	  kernel low-level debugging functions. Add earlyprintk to your
+	  kernel parameters to enable this console.
+
 config DEBUG_ICEDCC
 	bool "Kernel low-level debugging via EmbeddedICE DCC channel"
 	depends on DEBUG_LL
@@ -83,6 +91,14 @@ config DEBUG_ICEDCC
 	  It does include a timeout to ensure that the system does not
 	  totally freeze when there is nothing connected to read.
 
+config OC_ETM
+	bool "On-chip ETM and ETB"
+	select ARM_AMBA
+	help
+	  Enables the on-chip embedded trace macrocell and embedded trace
+	  buffer driver that will allow you to collect traces of the
+	  kernel code.
+
 config DEBUG_DC21285_PORT
 	bool "Kernel low-level debugging messages via footbridge serial port"
 	depends on DEBUG_LL && FOOTBRIDGE
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/armksyms.c linux-libre-2.6.33-gnu1/arch/arm/kernel/armksyms.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/armksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/armksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,27 +48,7 @@ extern void __aeabi_uidivmod(void);
 extern void __aeabi_ulcmp(void);
 
 extern void fpundefinstr(void);
-extern void fp_enter(void);
-
-/*
- * This has a special calling convention; it doesn't
- * modify any of the usual registers, except for LR.
- */
-#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "")
-
-#define EXPORT_SYMBOL_ALIAS(sym,orig)		\
- EXPORT_CRC_ALIAS(sym)				\
- static const struct kernel_symbol __ksymtab_##sym	\
-  __used __attribute__((section("__ksymtab"))) =	\
-    { (unsigned long)&orig, #sym };
 
-/*
- * floating point math emulator support.
- * These symbols will never change their calling convention...
- */
-EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
-EXPORT_SYMBOL_ALIAS(fp_printk,printk);
-EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
 
 EXPORT_SYMBOL(__backtrace);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/calls.S linux-libre-2.6.33-gnu1/arch/arm/kernel/calls.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/calls.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/calls.S	2010-02-24 13:52:17.000000000 -0500
@@ -172,7 +172,7 @@
 /* 160 */	CALL(sys_sched_get_priority_min)
 		CALL(sys_sched_rr_get_interval)
 		CALL(sys_nanosleep)
-		CALL(sys_arm_mremap)
+		CALL(sys_mremap)
 		CALL(sys_setresuid16)
 /* 165 */	CALL(sys_getresuid16)
 		CALL(sys_ni_syscall)		/* vm86 */
@@ -374,6 +374,7 @@
 		CALL(sys_pwritev)
 		CALL(sys_rt_tgsigqueueinfo)
 		CALL(sys_perf_event_open)
+/* 365 */	CALL(sys_recvmmsg)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/crunch.c linux-libre-2.6.33-gnu1/arch/arm/kernel/crunch.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/crunch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/crunch.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ static int crunch_do(struct notifier_blo
 		 * initialised state information on the first fault.
 		 */
 
-	case THREAD_NOTIFY_RELEASE:
+	case THREAD_NOTIFY_EXIT:
 		crunch_task_release(thread);
 		break;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/debug.S linux-libre-2.6.33-gnu1/arch/arm/kernel/debug.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/debug.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/debug.S	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,26 @@
 1002:
 		.endm
 
+#elif defined(CONFIG_CPU_V7)
+
+		.macro	addruart, rx
+		.endm
+
+		.macro	senduart, rd, rx
+		mcr	p14, 0, \rd, c0, c5, 0
+		.endm
+
+		.macro	busyuart, rd, rx
+busy:		mrc	p14, 0, pc, c0, c1, 0
+		bcs	busy
+		.endm
+
+		.macro	waituart, rd, rx
+wait:		mrc	p14, 0, pc, c0, c1, 0
+		bcs	wait
+
+		.endm
+
 #elif defined(CONFIG_CPU_XSCALE)
 
 		.macro	addruart, rx
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/dma-isa.c linux-libre-2.6.33-gnu1/arch/arm/kernel/dma-isa.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/dma-isa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/dma-isa.c	2010-02-24 13:52:17.000000000 -0500
@@ -207,8 +207,6 @@ void __init isa_init_dma(void)
 		outb(0x32, 0x4d6);
 		outb(0x33, 0x4d6);
 
-		request_dma(DMA_ISA_CASCADE, "cascade");
-
 		for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
 			request_resource(&ioport_resource, dma_resources + i);
 
@@ -218,5 +216,7 @@ void __init isa_init_dma(void)
 				printk(KERN_ERR "ISADMA%u: unable to register: %d\n",
 					chan, ret);
 		}
+
+		request_dma(DMA_ISA_CASCADE, "cascade");
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/early_printk.c linux-libre-2.6.33-gnu1/arch/arm/kernel/early_printk.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/early_printk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/early_printk.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ *  linux/arch/arm/kernel/early_printk.c
+ *
+ *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.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/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+extern void printch(int);
+
+static void early_write(const char *s, unsigned n)
+{
+	while (n-- > 0) {
+		if (*s == '\n')
+			printch('\r');
+		printch(*s);
+		s++;
+	}
+}
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+	early_write(s, n);
+}
+
+static struct console early_console = {
+	.name =		"earlycon",
+	.write =	early_console_write,
+	.flags =	CON_PRINTBUFFER | CON_BOOT,
+	.index =	-1,
+};
+
+asmlinkage void early_printk(const char *fmt, ...)
+{
+	char buf[512];
+	int n;
+	va_list ap;
+
+	va_start(ap, fmt);
+	n = vscnprintf(buf, sizeof(buf), fmt, ap);
+	early_write(buf, n);
+	va_end(ap);
+}
+
+static int __init setup_early_printk(char *buf)
+{
+	register_console(&early_console);
+	return 0;
+}
+
+early_param("earlyprintk", setup_early_printk);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/elf.c linux-libre-2.6.33-gnu1/arch/arm/kernel/elf.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/elf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/elf.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,15 +78,6 @@ int arm_elf_read_implies_exec(const stru
 		return 1;
 	if (cpu_architecture() < CPU_ARCH_ARMv6)
 		return 1;
-#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
-	/*
-	 * If we have support for OABI programs, we can never allow NX
-	 * support - our signal syscall restart mechanism relies upon
-	 * being able to execute code placed on the user stack.
-	 */
-	return 1;
-#else
 	return 0;
-#endif
 }
 EXPORT_SYMBOL(arm_elf_read_implies_exec);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/entry-armv.S linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-armv.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/entry-armv.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-armv.S	2010-02-24 13:52:17.000000000 -0500
@@ -957,9 +957,7 @@ kuser_cmpxchg_fixup:
 
 #else
 
-#ifdef CONFIG_SMP
-	mcr	p15, 0, r0, c7, c10, 5	@ dmb
-#endif
+	smp_dmb
 1:	ldrex	r3, [r2]
 	subs	r3, r3, r0
 	strexeq	r3, r1, [r2]
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/entry-common.S linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-common.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/entry-common.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/entry-common.S	2010-02-24 13:52:17.000000000 -0500
@@ -416,12 +416,12 @@ sys_mmap2:
 		tst	r5, #PGOFF_MASK
 		moveq	r5, r5, lsr #PAGE_SHIFT - 12
 		streq	r5, [sp, #4]
-		beq	do_mmap2
+		beq	sys_mmap_pgoff
 		mov	r0, #-EINVAL
 		mov	pc, lr
 #else
 		str	r5, [sp, #4]
-		b	do_mmap2
+		b	sys_mmap_pgoff
 #endif
 ENDPROC(sys_mmap2)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/etm.c linux-libre-2.6.33-gnu1/arch/arm/kernel/etm.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/etm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/etm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,641 @@
+/*
+ * linux/arch/arm/kernel/etm.c
+ *
+ * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This 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/types.h>
+#include <linux/io.h>
+#include <linux/sysrq.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/amba/bus.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/mutex.h>
+#include <asm/hardware/coresight.h>
+#include <asm/sections.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+static struct tracectx tracer;
+
+static inline bool trace_isrunning(struct tracectx *t)
+{
+	return !!(t->flags & TRACER_RUNNING);
+}
+
+static int etm_setup_address_range(struct tracectx *t, int n,
+		unsigned long start, unsigned long end, int exclude, int data)
+{
+	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
+		    ETMAAT_NOVALCMP;
+
+	if (n < 1 || n > t->ncmppairs)
+		return -EINVAL;
+
+	/* comparators and ranges are numbered starting with 1 as opposed
+	 * to bits in a word */
+	n--;
+
+	if (data)
+		flags |= ETMAAT_DLOADSTORE;
+	else
+		flags |= ETMAAT_IEXEC;
+
+	/* first comparator for the range */
+	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
+	etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+
+	/* second comparator is right next to it */
+	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
+	etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
+
+	flags = exclude ? ETMTE_INCLEXCL : 0;
+	etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+
+	return 0;
+}
+
+static int trace_start(struct tracectx *t)
+{
+	u32 v;
+	unsigned long timeout = TRACER_TIMEOUT;
+
+	etb_unlock(t);
+
+	etb_writel(t, 0, ETBR_FORMATTERCTRL);
+	etb_writel(t, 1, ETBR_CTRL);
+
+	etb_lock(t);
+
+	/* configure etm */
+	v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
+
+	if (t->flags & TRACER_CYCLE_ACC)
+		v |= ETMCTRL_CYCLEACCURATE;
+
+	etm_unlock(t);
+
+	etm_writel(t, v, ETMR_CTRL);
+
+	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+		;
+	if (!timeout) {
+		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+		etm_lock(t);
+		return -EFAULT;
+	}
+
+	etm_setup_address_range(t, 1, (unsigned long)_stext,
+			(unsigned long)_etext, 0, 0);
+	etm_writel(t, 0, ETMR_TRACEENCTRL2);
+	etm_writel(t, 0, ETMR_TRACESSCTRL);
+	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
+
+	v &= ~ETMCTRL_PROGRAM;
+	v |= ETMCTRL_PORTSEL;
+
+	etm_writel(t, v, ETMR_CTRL);
+
+	timeout = TRACER_TIMEOUT;
+	while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
+		;
+	if (!timeout) {
+		dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
+		etm_lock(t);
+		return -EFAULT;
+	}
+
+	etm_lock(t);
+
+	t->flags |= TRACER_RUNNING;
+
+	return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+	unsigned long timeout = TRACER_TIMEOUT;
+
+	etm_unlock(t);
+
+	etm_writel(t, 0x440, ETMR_CTRL);
+	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+		;
+	if (!timeout) {
+		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+		etm_lock(t);
+		return -EFAULT;
+	}
+
+	etm_lock(t);
+
+	etb_unlock(t);
+	etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
+
+	timeout = TRACER_TIMEOUT;
+	while (etb_readl(t, ETBR_FORMATTERCTRL) &
+			ETBFF_MANUAL_FLUSH && --timeout)
+		;
+	if (!timeout) {
+		dev_dbg(t->dev, "Waiting for formatter flush to commence "
+				"timed out\n");
+		etb_lock(t);
+		return -EFAULT;
+	}
+
+	etb_writel(t, 0, ETBR_CTRL);
+
+	etb_lock(t);
+
+	t->flags &= ~TRACER_RUNNING;
+
+	return 0;
+}
+
+static int etb_getdatalen(struct tracectx *t)
+{
+	u32 v;
+	int rp, wp;
+
+	v = etb_readl(t, ETBR_STATUS);
+
+	if (v & 1)
+		return t->etb_bufsz;
+
+	rp = etb_readl(t, ETBR_READADDR);
+	wp = etb_readl(t, ETBR_WRITEADDR);
+
+	if (rp > wp) {
+		etb_writel(t, 0, ETBR_READADDR);
+		etb_writel(t, 0, ETBR_WRITEADDR);
+
+		return 0;
+	}
+
+	return wp - rp;
+}
+
+/* sysrq+v will always stop the running trace and leave it at that */
+static void etm_dump(void)
+{
+	struct tracectx *t = &tracer;
+	u32 first = 0;
+	int length;
+
+	if (!t->etb_regs) {
+		printk(KERN_INFO "No tracing hardware found\n");
+		return;
+	}
+
+	if (trace_isrunning(t))
+		trace_stop(t);
+
+	etb_unlock(t);
+
+	length = etb_getdatalen(t);
+
+	if (length == t->etb_bufsz)
+		first = etb_readl(t, ETBR_WRITEADDR);
+
+	etb_writel(t, first, ETBR_READADDR);
+
+	printk(KERN_INFO "Trace buffer contents length: %d\n", length);
+	printk(KERN_INFO "--- ETB buffer begin ---\n");
+	for (; length; length--)
+		printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
+	printk(KERN_INFO "\n--- ETB buffer end ---\n");
+
+	/* deassert the overflow bit */
+	etb_writel(t, 1, ETBR_CTRL);
+	etb_writel(t, 0, ETBR_CTRL);
+
+	etb_writel(t, 0, ETBR_TRIGGERCOUNT);
+	etb_writel(t, 0, ETBR_READADDR);
+	etb_writel(t, 0, ETBR_WRITEADDR);
+
+	etb_lock(t);
+}
+
+static void sysrq_etm_dump(int key, struct tty_struct *tty)
+{
+	dev_dbg(tracer.dev, "Dumping ETB buffer\n");
+	etm_dump();
+}
+
+static struct sysrq_key_op sysrq_etm_op = {
+	.handler = sysrq_etm_dump,
+	.help_msg = "ETM buffer dump",
+	.action_msg = "etm",
+};
+
+static int etb_open(struct inode *inode, struct file *file)
+{
+	if (!tracer.etb_regs)
+		return -ENODEV;
+
+	file->private_data = &tracer;
+
+	return nonseekable_open(inode, file);
+}
+
+static ssize_t etb_read(struct file *file, char __user *data,
+		size_t len, loff_t *ppos)
+{
+	int total, i;
+	long length;
+	struct tracectx *t = file->private_data;
+	u32 first = 0;
+	u32 *buf;
+
+	mutex_lock(&t->mutex);
+
+	if (trace_isrunning(t)) {
+		length = 0;
+		goto out;
+	}
+
+	etb_unlock(t);
+
+	total = etb_getdatalen(t);
+	if (total == t->etb_bufsz)
+		first = etb_readl(t, ETBR_WRITEADDR);
+
+	etb_writel(t, first, ETBR_READADDR);
+
+	length = min(total * 4, (int)len);
+	buf = vmalloc(length);
+
+	dev_dbg(t->dev, "ETB buffer length: %d\n", total);
+	dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
+	for (i = 0; i < length / 4; i++)
+		buf[i] = etb_readl(t, ETBR_READMEM);
+
+	/* the only way to deassert overflow bit in ETB status is this */
+	etb_writel(t, 1, ETBR_CTRL);
+	etb_writel(t, 0, ETBR_CTRL);
+
+	etb_writel(t, 0, ETBR_WRITEADDR);
+	etb_writel(t, 0, ETBR_READADDR);
+	etb_writel(t, 0, ETBR_TRIGGERCOUNT);
+
+	etb_lock(t);
+
+	length -= copy_to_user(data, buf, length);
+	vfree(buf);
+
+out:
+	mutex_unlock(&t->mutex);
+
+	return length;
+}
+
+static int etb_release(struct inode *inode, struct file *file)
+{
+	/* there's nothing to do here, actually */
+	return 0;
+}
+
+static const struct file_operations etb_fops = {
+	.owner = THIS_MODULE,
+	.read = etb_read,
+	.open = etb_open,
+	.release = etb_release,
+};
+
+static struct miscdevice etb_miscdev = {
+	.name = "tracebuf",
+	.minor = 0,
+	.fops = &etb_fops,
+};
+
+static int __init etb_probe(struct amba_device *dev, struct amba_id *id)
+{
+	struct tracectx *t = &tracer;
+	int ret = 0;
+
+	ret = amba_request_regions(dev, NULL);
+	if (ret)
+		goto out;
+
+	t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
+	if (!t->etb_regs) {
+		ret = -ENOMEM;
+		goto out_release;
+	}
+
+	amba_set_drvdata(dev, t);
+
+	etb_miscdev.parent = &dev->dev;
+
+	ret = misc_register(&etb_miscdev);
+	if (ret)
+		goto out_unmap;
+
+	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
+	if (IS_ERR(t->emu_clk)) {
+		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
+		return -EFAULT;
+	}
+
+	clk_enable(t->emu_clk);
+
+	etb_unlock(t);
+	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
+	dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
+
+	/* make sure trace capture is disabled */
+	etb_writel(t, 0, ETBR_CTRL);
+	etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
+	etb_lock(t);
+
+	dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
+
+out:
+	return ret;
+
+out_unmap:
+	amba_set_drvdata(dev, NULL);
+	iounmap(t->etb_regs);
+
+out_release:
+	amba_release_regions(dev);
+
+	return ret;
+}
+
+static int etb_remove(struct amba_device *dev)
+{
+	struct tracectx *t = amba_get_drvdata(dev);
+
+	amba_set_drvdata(dev, NULL);
+
+	iounmap(t->etb_regs);
+	t->etb_regs = NULL;
+
+	clk_disable(t->emu_clk);
+	clk_put(t->emu_clk);
+
+	amba_release_regions(dev);
+
+	return 0;
+}
+
+static struct amba_id etb_ids[] = {
+	{
+		.id	= 0x0003b907,
+		.mask	= 0x0007ffff,
+	},
+	{ 0, 0 },
+};
+
+static struct amba_driver etb_driver = {
+	.drv		= {
+		.name	= "etb",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= etb_probe,
+	.remove		= etb_remove,
+	.id_table	= etb_ids,
+};
+
+/* use a sysfs file "trace_running" to start/stop tracing */
+static ssize_t trace_running_show(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  char *buf)
+{
+	return sprintf(buf, "%x\n", trace_isrunning(&tracer));
+}
+
+static ssize_t trace_running_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t n)
+{
+	unsigned int value;
+	int ret;
+
+	if (sscanf(buf, "%u", &value) != 1)
+		return -EINVAL;
+
+	mutex_lock(&tracer.mutex);
+	ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+	mutex_unlock(&tracer.mutex);
+
+	return ret ? : n;
+}
+
+static struct kobj_attribute trace_running_attr =
+	__ATTR(trace_running, 0644, trace_running_show, trace_running_store);
+
+static ssize_t trace_info_show(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  char *buf)
+{
+	u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
+	int datalen;
+
+	etb_unlock(&tracer);
+	datalen = etb_getdatalen(&tracer);
+	etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
+	etb_ra = etb_readl(&tracer, ETBR_READADDR);
+	etb_st = etb_readl(&tracer, ETBR_STATUS);
+	etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
+	etb_lock(&tracer);
+
+	etm_unlock(&tracer);
+	etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
+	etm_st = etm_readl(&tracer, ETMR_STATUS);
+	etm_lock(&tracer);
+
+	return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+			"ETBR_WRITEADDR:\t%08x\n"
+			"ETBR_READADDR:\t%08x\n"
+			"ETBR_STATUS:\t%08x\n"
+			"ETBR_FORMATTERCTRL:\t%08x\n"
+			"ETMR_CTRL:\t%08x\n"
+			"ETMR_STATUS:\t%08x\n",
+			datalen,
+			tracer.ncmppairs,
+			etb_wa,
+			etb_ra,
+			etb_st,
+			etb_fc,
+			etm_ctrl,
+			etm_st
+			);
+}
+
+static struct kobj_attribute trace_info_attr =
+	__ATTR(trace_info, 0444, trace_info_show, NULL);
+
+static ssize_t trace_mode_show(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  char *buf)
+{
+	return sprintf(buf, "%d %d\n",
+			!!(tracer.flags & TRACER_CYCLE_ACC),
+			tracer.etm_portsz);
+}
+
+static ssize_t trace_mode_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t n)
+{
+	unsigned int cycacc, portsz;
+
+	if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2)
+		return -EINVAL;
+
+	mutex_lock(&tracer.mutex);
+	if (cycacc)
+		tracer.flags |= TRACER_CYCLE_ACC;
+	else
+		tracer.flags &= ~TRACER_CYCLE_ACC;
+
+	tracer.etm_portsz = portsz & 0x0f;
+	mutex_unlock(&tracer.mutex);
+
+	return n;
+}
+
+static struct kobj_attribute trace_mode_attr =
+	__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+
+static int __init etm_probe(struct amba_device *dev, struct amba_id *id)
+{
+	struct tracectx *t = &tracer;
+	int ret = 0;
+
+	if (t->etm_regs) {
+		dev_dbg(&dev->dev, "ETM already initialized\n");
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = amba_request_regions(dev, NULL);
+	if (ret)
+		goto out;
+
+	t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
+	if (!t->etm_regs) {
+		ret = -ENOMEM;
+		goto out_release;
+	}
+
+	amba_set_drvdata(dev, t);
+
+	mutex_init(&t->mutex);
+	t->dev = &dev->dev;
+	t->flags = TRACER_CYCLE_ACC;
+	t->etm_portsz = 1;
+
+	etm_unlock(t);
+	ret = etm_readl(t, CSCR_PRSR);
+
+	t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+	etm_writel(t, 0x440, ETMR_CTRL);
+	etm_lock(t);
+
+	ret = sysfs_create_file(&dev->dev.kobj,
+			&trace_running_attr.attr);
+	if (ret)
+		goto out_unmap;
+
+	/* failing to create any of these two is not fatal */
+	ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
+	if (ret)
+		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
+
+	ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
+	if (ret)
+		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
+
+	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
+
+out:
+	return ret;
+
+out_unmap:
+	amba_set_drvdata(dev, NULL);
+	iounmap(t->etm_regs);
+
+out_release:
+	amba_release_regions(dev);
+
+	return ret;
+}
+
+static int etm_remove(struct amba_device *dev)
+{
+	struct tracectx *t = amba_get_drvdata(dev);
+
+	amba_set_drvdata(dev, NULL);
+
+	iounmap(t->etm_regs);
+	t->etm_regs = NULL;
+
+	amba_release_regions(dev);
+
+	sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
+	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
+	sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+
+	return 0;
+}
+
+static struct amba_id etm_ids[] = {
+	{
+		.id	= 0x0003b921,
+		.mask	= 0x0007ffff,
+	},
+	{ 0, 0 },
+};
+
+static struct amba_driver etm_driver = {
+	.drv		= {
+		.name   = "etm",
+		.owner  = THIS_MODULE,
+	},
+	.probe		= etm_probe,
+	.remove		= etm_remove,
+	.id_table	= etm_ids,
+};
+
+static int __init etm_init(void)
+{
+	int retval;
+
+	retval = amba_driver_register(&etb_driver);
+	if (retval) {
+		printk(KERN_ERR "Failed to register etb\n");
+		return retval;
+	}
+
+	retval = amba_driver_register(&etm_driver);
+	if (retval) {
+		amba_driver_unregister(&etb_driver);
+		printk(KERN_ERR "Failed to probe etm\n");
+		return retval;
+	}
+
+	/* not being able to install this handler is not fatal */
+	(void)register_sysrq_key('v', &sysrq_etm_op);
+
+	return 0;
+}
+
+device_initcall(etm_init);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/head-nommu.S linux-libre-2.6.33-gnu1/arch/arm/kernel/head-nommu.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/head-nommu.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/head-nommu.S	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@
  * numbers for r1.
  *
  */
-	.section ".text.head", "ax"
+	__HEAD
 ENTRY(stext)
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/head.S linux-libre-2.6.33-gnu1/arch/arm/kernel/head.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@
  * crap here - that's what the boot loader (or in extreme, well justified
  * circumstances, zImage) is for.
  */
-	.section ".text.head", "ax"
+	__HEAD
 ENTRY(stext)
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/irq.c linux-libre-2.6.33-gnu1/arch/arm/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto unlock;
@@ -84,7 +84,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 unlock:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 #ifdef CONFIG_FIQ
 		show_fiq_list(p, v);
@@ -139,7 +139,7 @@ void set_irq_flags(unsigned int irq, uns
 	}
 
 	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
 	if (iflags & IRQF_VALID)
 		desc->status &= ~IRQ_NOREQUEST;
@@ -147,7 +147,7 @@ void set_irq_flags(unsigned int irq, uns
 		desc->status &= ~IRQ_NOPROBE;
 	if (!(iflags & IRQF_NOAUTOEN))
 		desc->status &= ~IRQ_NOAUTOEN;
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 void __init init_IRQ(void)
@@ -166,9 +166,9 @@ static void route_irq(struct irq_desc *d
 {
 	pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->node, cpu);
 
-	spin_lock_irq(&desc->lock);
+	raw_spin_lock_irq(&desc->lock);
 	desc->chip->set_affinity(irq, cpumask_of(cpu));
-	spin_unlock_irq(&desc->lock);
+	raw_spin_unlock_irq(&desc->lock);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/isa.c linux-libre-2.6.33-gnu1/arch/arm/kernel/isa.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/isa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/isa.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,47 +22,42 @@ static unsigned int isa_membase, isa_por
 
 static ctl_table ctl_isa_vars[4] = {
 	{
-		.ctl_name	= BUS_ISA_MEM_BASE,
 		.procname	= "membase",
 		.data		= &isa_membase, 
 		.maxlen		= sizeof(isa_membase),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	}, {
-		.ctl_name	= BUS_ISA_PORT_BASE,
 		.procname	= "portbase",
 		.data		= &isa_portbase, 
 		.maxlen		= sizeof(isa_portbase),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	}, {
-		.ctl_name	= BUS_ISA_PORT_SHIFT,
 		.procname	= "portshift",
 		.data		= &isa_portshift, 
 		.maxlen		= sizeof(isa_portshift),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
-	}, {0}
+		.proc_handler	= proc_dointvec,
+	}, {}
 };
 
 static struct ctl_table_header *isa_sysctl_header;
 
 static ctl_table ctl_isa[2] = {
 	{
-		.ctl_name	= CTL_BUS_ISA,
 		.procname	= "isa",
 		.mode		= 0555,
 		.child		= ctl_isa_vars,
-	}, {0}
+	}, {}
 };
 
 static ctl_table ctl_bus[2] = {
 	{
-		.ctl_name	= CTL_BUS,
 		.procname	= "bus",
 		.mode		= 0555,
 		.child		= ctl_isa,
-	}, {0}
+	}, {}
 };
 
 void __init
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/Makefile linux-libre-2.6.33-gnu1/arch/arm/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,8 @@ obj-y		:= compat.o elf.o entry-armv.o en
 		   process.o ptrace.o return_address.o setup.o signal.o \
 		   sys_arm.o stacktrace.o time.o traps.o
 
+obj-$(CONFIG_OC_ETM)		+= etm.o
+
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
 obj-$(CONFIG_FIQ)		+= fiq.o
@@ -52,5 +54,6 @@ endif
 
 head-y			:= head$(MMUEXT).o
 obj-$(CONFIG_DEBUG_LL)	+= debug.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 extra-y := $(head-y) init_task.o vmlinux.lds
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/process.c linux-libre-2.6.33-gnu1/arch/arm/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,8 @@ void __show_regs(struct pt_regs *regs)
 	char buf[64];
 
 	printk("CPU: %d    %s  (%s %.*s)\n",
-		smp_processor_id(), print_tainted(), init_utsname()->release,
+		raw_smp_processor_id(), print_tainted(),
+		init_utsname()->release,
 		(int)strcspn(init_utsname()->version, " "),
 		init_utsname()->version);
 	print_symbol("PC is at %s\n", instruction_pointer(regs));
@@ -274,17 +275,18 @@ void show_regs(struct pt_regs * regs)
 	__backtrace();
 }
 
+ATOMIC_NOTIFIER_HEAD(thread_notify_head);
+
+EXPORT_SYMBOL_GPL(thread_notify_head);
+
 /*
  * Free current thread data structures etc..
  */
 void exit_thread(void)
 {
+	thread_notify(THREAD_NOTIFY_EXIT, current_thread_info());
 }
 
-ATOMIC_NOTIFIER_HEAD(thread_notify_head);
-
-EXPORT_SYMBOL_GPL(thread_notify_head);
-
 void flush_thread(void)
 {
 	struct thread_info *thread = current_thread_info();
@@ -299,9 +301,6 @@ void flush_thread(void)
 
 void release_thread(struct task_struct *dead_task)
 {
-	struct thread_info *thread = task_thread_info(dead_task);
-
-	thread_notify(THREAD_NOTIFY_RELEASE, thread);
 }
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/setup.c linux-libre-2.6.33-gnu1/arch/arm/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -102,6 +102,7 @@ struct cpu_cache_fns cpu_cache;
 #endif
 #ifdef CONFIG_OUTER_CACHE
 struct outer_cache_fns outer_cache;
+EXPORT_SYMBOL(outer_cache);
 #endif
 
 struct stack {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/smp_twd.c linux-libre-2.6.33-gnu1/arch/arm/kernel/smp_twd.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/smp_twd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/smp_twd.c	2010-02-24 13:52:17.000000000 -0500
@@ -160,6 +160,7 @@ void __cpuinit twd_timer_setup(struct cl
 
 	/* Make sure our local interrupt controller has this enabled */
 	local_irq_save(flags);
+	irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
 	get_irq_chip(clk->irq)->unmask(clk->irq);
 	local_irq_restore(flags);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/sys_arm.c linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_arm.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/sys_arm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/sys_arm.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,41 +28,6 @@
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
 
-extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
-			       unsigned long new_len, unsigned long flags,
-			       unsigned long new_addr);
-
-/* common code for old and new mmaps */
-inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EINVAL;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS)
-		goto out;
-
-	error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 struct mmap_arg_struct {
 	unsigned long addr;
 	unsigned long len;
@@ -84,29 +49,11 @@ asmlinkage int old_mmap(struct mmap_arg_
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
 
-asmlinkage unsigned long
-sys_arm_mremap(unsigned long addr, unsigned long old_len,
-	       unsigned long new_len, unsigned long flags,
-	       unsigned long new_addr)
-{
-	unsigned long ret = -EINVAL;
-
-	if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
-		goto out;
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-
-out:
-	return ret;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls.
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/arm/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -24,13 +24,11 @@ SECTIONS
 #else
 	. = PAGE_OFFSET + TEXT_OFFSET;
 #endif
-	.text.head : {
-		_stext = .;
-		_sinittext = .;
-		*(.text.head)
-	}
 
 	.init : {			/* Init code and data		*/
+		_stext = .;
+		_sinittext = .;
+			HEAD_TEXT
 			INIT_TEXT
 		_einittext = .;
 		__proc_info_begin = .;
@@ -42,48 +40,36 @@ SECTIONS
 		__tagtable_begin = .;
 			*(.taglist.init)
 		__tagtable_end = .;
-		. = ALIGN(16);
-		__setup_start = .;
-			*(.init.setup)
-		__setup_end = .;
+
+		INIT_SETUP(16)
+
 		__early_begin = .;
 			*(.early_param.init)
 		__early_end = .;
-		__initcall_start = .;
-			INITCALLS
-		__initcall_end = .;
-		__con_initcall_start = .;
-			*(.con_initcall.init)
-		__con_initcall_end = .;
-		__security_initcall_start = .;
-			*(.security_initcall.init)
-		__security_initcall_end = .;
-#ifdef CONFIG_BLK_DEV_INITRD
-		. = ALIGN(32);
-		__initramfs_start = .;
-			usr/built-in.o(.init.ramfs)
-		__initramfs_end = .;
-#endif
-		. = ALIGN(PAGE_SIZE);
-		__per_cpu_load = .;
-		__per_cpu_start = .;
-			*(.data.percpu.page_aligned)
-			*(.data.percpu)
-			*(.data.percpu.shared_aligned)
-		__per_cpu_end = .;
+
+		INIT_CALLS
+		CON_INITCALL
+		SECURITY_INITCALL
+		INIT_RAM_FS
+
 #ifndef CONFIG_XIP_KERNEL
 		__init_begin = _stext;
 		INIT_DATA
-		. = ALIGN(PAGE_SIZE);
-		__init_end = .;
 #endif
 	}
 
-	/DISCARD/ : {			/* Exit code and data		*/
-		EXIT_TEXT
-		EXIT_DATA
-		*(.exitcall.exit)
-		*(.discard)
+	PERCPU(PAGE_SIZE)
+
+#ifndef CONFIG_XIP_KERNEL
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
+#endif
+
+	/*
+	 * unwind exit sections must be discarded before the rest of the
+	 * unwind sections get included.
+	 */
+	/DISCARD/ : {
 		*(.ARM.exidx.exit.text)
 		*(.ARM.extab.exit.text)
 #ifndef CONFIG_HOTPLUG_CPU
@@ -157,7 +143,7 @@ SECTIONS
 		 * first, the init task union, aligned
 		 * to an 8192 byte boundary.
 		 */
-		*(.data.init_task)
+		INIT_TASK_DATA(THREAD_SIZE)
 
 #ifdef CONFIG_XIP_KERNEL
 		. = ALIGN(PAGE_SIZE);
@@ -167,17 +153,8 @@ SECTIONS
 		__init_end = .;
 #endif
 
-		. = ALIGN(PAGE_SIZE);
-		__nosave_begin = .;
-		*(.data.nosave)
-		. = ALIGN(PAGE_SIZE);
-		__nosave_end = .;
-
-		/*
-		 * then the cacheline aligned data
-		 */
-		. = ALIGN(32);
-		*(.data.cacheline_aligned)
+		NOSAVE_DATA
+		CACHELINE_ALIGNED_DATA(32)
 
 		/*
 		 * The exception fixup table (might need resorting at runtime)
@@ -256,21 +233,14 @@ SECTIONS
 	}
 #endif
 
-	.bss : {
-		__bss_start = .;	/* BSS				*/
-		*(.bss)
-		*(COMMON)
-		__bss_stop = .;
-		_end = .;
-	}
-					/* Stabs debugging sections.	*/
-	.stab 0 : { *(.stab) }
-	.stabstr 0 : { *(.stabstr) }
-	.stab.excl 0 : { *(.stab.excl) }
-	.stab.exclstr 0 : { *(.stab.exclstr) }
-	.stab.index 0 : { *(.stab.index) }
-	.stab.indexstr 0 : { *(.stab.indexstr) }
+	BSS_SECTION(0, 0, 0)
+	_end = .;
+
+	STABS_DEBUG
 	.comment 0 : { *(.comment) }
+
+	/* Default discards */
+	DISCARDS
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/kernel/xscale-cp0.c linux-libre-2.6.33-gnu1/arch/arm/kernel/xscale-cp0.c
--- linux-libre-2.6.32-gnu1/arch/arm/kernel/xscale-cp0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/kernel/xscale-cp0.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ static int iwmmxt_do(struct notifier_blo
 		 * initialised state information on the first fault.
 		 */
 
-	case THREAD_NOTIFY_RELEASE:
+	case THREAD_NOTIFY_EXIT:
 		iwmmxt_task_release(thread);
 		break;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,6 +131,62 @@ void __init at91_add_device_usbh_ohci(st
 
 
 /* --------------------------------------------------------------------
+ *  USB Host HS (EHCI)
+ *  Needs an OHCI host for low and full speed management
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ehci_data;
+
+static struct resource usbh_ehci_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_EHCI_BASE,
+		.end	= AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_UHPHS,
+		.end	= AT91SAM9G45_ID_UHPHS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_usbh_ehci_device = {
+	.name		= "atmel-ehci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ehci_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &usbh_ehci_data,
+	},
+	.resource	= usbh_ehci_resources,
+	.num_resources	= ARRAY_SIZE(usbh_ehci_resources),
+};
+
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
+{
+	int i;
+
+	if (!data)
+		return;
+
+	/* Enable VBus control for UHP ports */
+	for (i = 0; i < data->ports; i++) {
+		if (data->vbus_pin[i])
+			at91_set_gpio_output(data->vbus_pin[i], 0);
+	}
+
+	usbh_ehci_data = *data;
+	at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk");
+	platform_device_register(&at91_usbh_ehci_device);
+}
+#else
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
 
@@ -809,6 +865,57 @@ static void __init at91_add_device_rtc(v
 #endif
 
 
+/* --------------------------------------------------------------------
+ *  Touchscreen
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
+
+static struct resource tsadcc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TSC,
+		.end	= AT91SAM9G45_BASE_TSC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TSC,
+		.end	= AT91SAM9G45_ID_TSC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device at91sam9g45_tsadcc_device = {
+	.name		= "atmel_tsadcc",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &tsadcc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &tsadcc_data,
+	},
+	.resource	= tsadcc_resources,
+	.num_resources	= ARRAY_SIZE(tsadcc_resources),
+};
+
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
+{
+	if (!data)
+		return;
+
+	at91_set_gpio_input(AT91_PIN_PD20, 0);	/* AD0_XR */
+	at91_set_gpio_input(AT91_PIN_PD21, 0);	/* AD1_XL */
+	at91_set_gpio_input(AT91_PIN_PD22, 0);	/* AD2_YT */
+	at91_set_gpio_input(AT91_PIN_PD23, 0);	/* AD3_TB */
+
+	tsadcc_data = *data;
+	platform_device_register(&at91sam9g45_tsadcc_device);
+}
+#else
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
+#endif
+
+
 /* --------------------------------------------------------------------
  *  RTT
  * -------------------------------------------------------------------- */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/at91sam9rl_devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam9rl_devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/at91sam9rl_devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/at91sam9rl_devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -622,6 +622,7 @@ static void __init at91_add_device_tc(vo
 
 #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
 static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
 
 static struct resource tsadcc_resources[] = {
 	[0] = {
@@ -642,22 +643,27 @@ static struct platform_device at91sam9rl
 	.dev		= {
 				.dma_mask		= &tsadcc_dmamask,
 				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &tsadcc_data,
 	},
 	.resource	= tsadcc_resources,
 	.num_resources	= ARRAY_SIZE(tsadcc_resources),
 };
 
-void __init at91_add_device_tsadcc(void)
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
 {
+	if (!data)
+		return;
+
 	at91_set_A_periph(AT91_PIN_PA17, 0);	/* AD0_XR */
 	at91_set_A_periph(AT91_PIN_PA18, 0);	/* AD1_XL */
 	at91_set_A_periph(AT91_PIN_PA19, 0);	/* AD2_YT */
 	at91_set_A_periph(AT91_PIN_PA20, 0);	/* AD3_TB */
 
+	tsadcc_data = *data;
 	platform_device_register(&at91sam9rl_tsadcc_device);
 }
 #else
-void __init at91_add_device_tsadcc(void) {}
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
 #endif
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-eco920.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-eco920.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-eco920.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-eco920.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * 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/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board.h>
+#include <mach/at91rm9200_mc.h>
+#include "generic.h"
+
+static void __init eco920_map_io(void)
+{
+	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+
+	/* Setup the LEDs */
+	at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
+
+	/* DBGU on ttyS0. (Rx & Tx only */
+	at91_register_uart(0, 0, 0);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init eco920_init_irq(void)
+{
+	at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata eco920_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC2,
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata eco920_usbh_data = {
+	.ports		= 1,
+};
+
+static struct at91_udc_data __initdata eco920_udc_data = {
+	.vbus_pin	= AT91_PIN_PB12,
+	.pullup_pin	= AT91_PIN_PB13,
+};
+
+static struct at91_mmc_data __initdata eco920_mmc_data = {
+	.slot_b		= 0,
+	.wire4		= 0,
+};
+
+static struct physmap_flash_data eco920_flash_data = {
+	.width  = 2,
+};
+
+static struct resource eco920_flash_resource = {
+	.start          = 0x11000000,
+	.end            = 0x11ffffff,
+	.flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device eco920_flash = {
+	.name           = "physmap-flash",
+	.id             = 0,
+	.dev            = {
+		.platform_data  = &eco920_flash_data,
+	},
+	.resource       = &eco920_flash_resource,
+	.num_resources  = 1,
+};
+
+static struct resource at91_beeper_resources[] = {
+	[0] = {
+		.start          = AT91RM9200_BASE_TC3,
+		.end            = AT91RM9200_BASE_TC3 + 0x39,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device at91_beeper = {
+	.name           = "at91_beeper",
+	.id             = 0,
+	.resource       = at91_beeper_resources,
+	.num_resources  = ARRAY_SIZE(at91_beeper_resources),
+};
+
+static struct spi_board_info eco920_spi_devices[] = {
+	{	/* CAN controller */
+		.modalias	= "tlv5638",
+		.chip_select	= 3,
+		.max_speed_hz	= 20 * 1000 * 1000,
+		.mode		= SPI_CPHA,
+	},
+};
+
+static void __init eco920_board_init(void)
+{
+	at91_add_device_serial();
+	at91_add_device_eth(&eco920_eth_data);
+	at91_add_device_usbh(&eco920_usbh_data);
+	at91_add_device_udc(&eco920_udc_data);
+
+	at91_add_device_mmc(0, &eco920_mmc_data);
+	platform_device_register(&eco920_flash);
+
+	at91_sys_write(AT91_SMC_CSR(7),	AT91_SMC_RWHOLD_(1)
+				| AT91_SMC_RWSETUP_(1)
+				| AT91_SMC_DBW_8
+				| AT91_SMC_WSEN
+				| AT91_SMC_NWS_(15));
+
+	at91_set_A_periph(AT91_PIN_PC6, 1);
+
+	at91_set_gpio_input(AT91_PIN_PA23, 0);
+	at91_set_deglitch(AT91_PIN_PA23, 1);
+
+/* Initialization of the Static Memory Controller for Chip Select 3 */
+	at91_sys_write(AT91_SMC_CSR(3),
+		AT91_SMC_DBW_16  |	/* 16 bit */
+		AT91_SMC_WSEN    |
+		AT91_SMC_NWS_(5) |	/* wait states */
+		AT91_SMC_TDF_(1)	/* float time */
+	);
+
+	at91_clock_associate("tc3_clk", &at91_beeper.dev, "at91_beeper");
+	at91_set_B_periph(AT91_PIN_PB6, 0);
+	platform_device_register(&at91_beeper);
+
+	at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
+}
+
+MACHINE_START(ECO920, "eco920")
+	/* Maintainer: Sascha Hauer */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= eco920_map_io,
+	.init_irq	= eco920_init_irq,
+	.init_machine	= eco920_board_init,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-sam9m10g45ek.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9m10g45ek.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-sam9m10g45ek.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9m10g45ek.c	2010-02-24 13:52:17.000000000 -0500
@@ -229,6 +229,16 @@ static struct atmel_lcdfb_info __initdat
 
 
 /*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+	.adc_clock		= 300000,
+	.pendet_debounce	= 0x0d,
+	.ts_sample_hold_time	= 0x0a,
+};
+
+
+/*
  * GPIO Buttons
  */
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
@@ -366,6 +376,7 @@ static void __init ek_board_init(void)
 	at91_add_device_serial();
 	/* USB HS Host */
 	at91_add_device_usbh_ohci(&ek_usbh_hs_data);
+	at91_add_device_usbh_ehci(&ek_usbh_hs_data);
 	/* USB HS Device */
 	at91_add_device_usba(&ek_usba_udc_data);
 	/* SPI */
@@ -378,6 +389,8 @@ static void __init ek_board_init(void)
 	at91_add_device_i2c(0, NULL, 0);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
+	/* Touch Screen */
+	at91_add_device_tsadcc(&ek_tsadcc_data);
 	/* Push Buttons */
 	ek_add_device_buttons();
 	/* AC97 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-sam9rlek.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9rlek.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/board-sam9rlek.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/board-sam9rlek.c	2010-02-24 13:52:17.000000000 -0500
@@ -243,6 +243,16 @@ static struct gpio_led ek_leds[] = {
 
 
 /*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+	.adc_clock		= 1000000,
+	.pendet_debounce	= 0x0f,
+	.ts_sample_hold_time	= 0x03,
+};
+
+
+/*
  * GPIO Buttons
  */
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
@@ -310,7 +320,7 @@ static void __init ek_board_init(void)
 	/* AC97 */
 	at91_add_device_ac97(&ek_ac97_data);
 	/* Touch Screen Controller */
-	at91_add_device_tsadcc();
+	at91_add_device_tsadcc(&ek_tsadcc_data);
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 	/* Push Buttons */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/cpuidle.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/cpuidle.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/cpuidle.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/cpuidle.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,94 @@
+/*
+ * based on arch/arm/mach-kirkwood/cpuidle.c
+ *
+ * CPU idle support for AT91 SoC
+ *
+ * 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.
+ *
+ * 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
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <linux/io.h>
+
+#include "pm.h"
+
+#define AT91_MAX_STATES	2
+
+static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
+
+static struct cpuidle_driver at91_idle_driver = {
+	.name =         "at91_idle",
+	.owner =        THIS_MODULE,
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int at91_enter_idle(struct cpuidle_device *dev,
+			       struct cpuidle_state *state)
+{
+	struct timeval before, after;
+	int idle_time;
+	u32 saved_lpr;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+	if (state == &dev->states[0])
+		/* Wait for interrupt state */
+		cpu_do_idle();
+	else if (state == &dev->states[1]) {
+		asm("b 1f; .align 5; 1:");
+		asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
+		saved_lpr = sdram_selfrefresh_enable();
+		cpu_do_idle();
+		sdram_selfrefresh_disable(saved_lpr);
+	}
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+			(after.tv_usec - before.tv_usec);
+	return idle_time;
+}
+
+/* Initialize CPU idle by registering the idle states */
+static int at91_init_cpuidle(void)
+{
+	struct cpuidle_device *device;
+
+	cpuidle_register_driver(&at91_idle_driver);
+
+	device = &per_cpu(at91_cpuidle_device, smp_processor_id());
+	device->state_count = AT91_MAX_STATES;
+
+	/* Wait for interrupt state */
+	device->states[0].enter = at91_enter_idle;
+	device->states[0].exit_latency = 1;
+	device->states[0].target_residency = 10000;
+	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[0].name, "WFI");
+	strcpy(device->states[0].desc, "Wait for interrupt");
+
+	/* Wait for interrupt and RAM self refresh state */
+	device->states[1].enter = at91_enter_idle;
+	device->states[1].exit_latency = 10;
+	device->states[1].target_residency = 10000;
+	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[1].name, "RAM_SR");
+	strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
+
+	if (cpuidle_register_device(device)) {
+		printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+device_initcall(at91_init_cpuidle);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/include/mach/atmel-mci.h linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/atmel-mci.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/include/mach/atmel-mci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/atmel-mci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+#ifndef __MACH_ATMEL_MCI_H
+#define __MACH_ATMEL_MCI_H
+
+#include <mach/at_hdmac.h>
+
+/**
+ * struct mci_dma_data - DMA data for MCI interface
+ */
+struct mci_dma_data {
+	struct at_dma_slave	sdata;
+};
+
+/* accessor macros */
+#define	slave_data_ptr(s)	(&(s)->sdata)
+#define find_slave_dev(s)	((s)->sdata.dma_dev)
+
+#define	setup_dma_addr(s, t, r)	do {		\
+	if (s) {				\
+		(s)->sdata.tx_reg = (t);	\
+		(s)->sdata.rx_reg = (r);	\
+	}					\
+} while (0)
+
+#endif /* __MACH_ATMEL_MCI_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/include/mach/board.h linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/board.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/include/mach/board.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/include/mach/board.h	2010-02-24 13:52:17.000000000 -0500
@@ -98,6 +98,7 @@ struct at91_usbh_data {
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
 
  /* NAND / SmartMedia */
 struct atmel_nand_data {
@@ -186,7 +187,12 @@ extern void __init at91_add_device_ac97(
 extern void __init at91_add_device_isi(void);
 
  /* Touchscreen Controller */
-extern void __init at91_add_device_tsadcc(void);
+struct at91_tsadcc_data {
+	unsigned int    adc_clock;
+	u8		pendet_debounce;
+	u8		ts_sample_hold_time;
+};
+extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data);
 
 /* CAN */
 struct at91_can_data {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,20 @@
 if ARCH_AT91
 
+config HAVE_AT91_DATAFLASH_CARD
+	bool
+
+config HAVE_NAND_ATMEL_BUSWIDTH_16
+	bool
+
+config HAVE_AT91_USART3
+	bool
+
+config HAVE_AT91_USART4
+	bool
+
+config HAVE_AT91_USART5
+	bool
+
 menu "Atmel AT91 System-on-Chip"
 
 choice
@@ -10,54 +25,69 @@ config ARCH_AT91RM9200
 	select CPU_ARM920T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_AT91_USART3
 
 config ARCH_AT91SAM9260
 	bool "AT91SAM9260 or AT91SAM9XE"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_AT91_USART3
+	select HAVE_AT91_USART4
+	select HAVE_AT91_USART5
 
 config ARCH_AT91SAM9261
 	bool "AT91SAM9261"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9G10
 	bool "AT91SAM9G10"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9263
 	bool "AT91SAM9263"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_AT91_USART3
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9G20
 	bool "AT91SAM9G20"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_AT91_USART3
+	select HAVE_AT91_USART4
+	select HAVE_AT91_USART5
 
 config ARCH_AT91SAM9G45
 	bool "AT91SAM9G45"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_AT91_USART3
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91CAP9
 	bool "AT91CAP9"
 	select CPU_ARM926T
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select HAVE_FB_ATMEL
 
 config ARCH_AT91X40
 	bool "AT91x40"
@@ -76,93 +106,88 @@ comment "AT91RM9200 Board Type"
 
 config MACH_ONEARM
 	bool "Ajeco 1ARM Single Board Computer"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Ajeco's 1ARM Single Board Computer.
 	  <http://www.ajeco.fi/products.htm>
 
 config ARCH_AT91RM9200DK
 	bool "Atmel AT91RM9200-DK Development board"
-	depends on ARCH_AT91RM9200
+	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"
-	depends on ARCH_AT91RM9200
+	select HAVE_AT91_DATAFLASH_CARD
 	help
 	  Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507>
 
 config MACH_CSB337
 	bool "Cogent CSB337"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Cogent's CSB337 board.
 	  <http://www.cogcomp.com/csb_csb337.htm>
 
 config MACH_CSB637
 	bool "Cogent CSB637"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Cogent's CSB637 board.
 	  <http://www.cogcomp.com/csb_csb637.htm>
 
 config MACH_CARMEVA
 	bool "Conitec ARM&EVA"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Conitec's AT91RM9200-MCU-Module.
 	  <http://www.conitec.net/english/linuxboard.htm>
 
 config MACH_ATEB9200
 	bool "Embest ATEB9200"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Embest's ATEB9200 board.
 	  <http://www.embedinfo.com/english/product/ATEB9200.asp>
 
 config MACH_KB9200
 	bool "KwikByte KB920x"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using KwikByte's KB920x board.
 	  <http://kwikbyte.com/KB9202_description_new.htm>
 
 config MACH_PICOTUX2XX
 	bool "picotux 200"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using a picotux 200.
 	  <http://www.picotux.com/>
 
 config MACH_KAFA
 	bool "Sperry-Sun KAFA board"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using Sperry-Sun's KAFA board.
 
 config MACH_ECBAT91
 	bool "emQbit ECB_AT91 SBC"
-	depends on ARCH_AT91RM9200
+	select HAVE_AT91_DATAFLASH_CARD
 	help
 	  Select this if you are using emQbit's ECB_AT91 board.
 	  <http://wiki.emqbit.com/free-ecb-at91>
 
 config MACH_YL9200
 	bool "ucDragon YL-9200"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using the ucDragon YL-9200 board.
 
 config MACH_CPUAT91
 	bool "Eukrea CPUAT91"
-	depends on ARCH_AT91RM9200
 	help
 	  Select this if you are using the Eukrea Electromatique's
 	  CPUAT91 board <http://www.eukrea.com/>.
 
+config MACH_ECO920
+	bool "eco920"
+	help
+	  Select this if you are using the eco920 board
+
 endif
 
 # ----------------------------------------------------------
@@ -173,7 +198,6 @@ comment "AT91SAM9260 Variants"
 
 config ARCH_AT91SAM9260_SAM9XE
 	bool "AT91SAM9XE"
-	depends on ARCH_AT91SAM9260
 	help
 	  Select this if you are using Atmel's AT91SAM9XE System-on-Chip.
 	  They are basically AT91SAM9260s with various sizes of embedded Flash.
@@ -182,28 +206,27 @@ comment "AT91SAM9260 / AT91SAM9XE Board
 
 config MACH_AT91SAM9260EK
 	bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit"
-	depends on ARCH_AT91SAM9260
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
 
 config MACH_CAM60
 	bool "KwikByte KB9260 (CAM60) board"
-	depends on ARCH_AT91SAM9260
 	help
 	  Select this if you are using KwikByte's KB9260 (CAM60) board based on the Atmel AT91SAM9260.
 	  <http://www.kwikbyte.com/KB9260.html>
 
 config MACH_SAM9_L9260
 	bool "Olimex SAM9-L9260 board"
-	depends on ARCH_AT91SAM9260
+	select HAVE_AT91_DATAFLASH_CARD
 	help
 	  Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260.
 	  <http://www.olimex.com/dev/sam9-L9260.html>
 
 config MACH_AFEB9260
 	bool "Custom afeb9260 board v1"
-	depends on ARCH_AT91SAM9260
 	help
 	  Select this if you are using custom afeb9260 board based on
 	  open hardware design. Select this for revision 1 of the board.
@@ -212,21 +235,18 @@ config MACH_AFEB9260
 
 config MACH_USB_A9260
 	bool "CALAO USB-A9260"
-	depends on ARCH_AT91SAM9260
 	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"
-	depends on ARCH_AT91SAM9260
 	help
 	  Select this if you are using a Calao Systems QIL-A9260 Board.
 	  <http://www.calao-systems.com>
 
 config MACH_CPU9260
 	bool "Eukrea CPU9260 board"
-	depends on ARCH_AT91SAM9260
 	help
 	  Select this if you are using a Eukrea Electromatique's
 	  CPU9260 Board <http://www.eukrea.com/>
@@ -241,7 +261,8 @@ comment "AT91SAM9261 Board Type"
 
 config MACH_AT91SAM9261EK
 	bool "Atmel AT91SAM9261-EK Evaluation Kit"
-	depends on ARCH_AT91SAM9261
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	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>
@@ -256,7 +277,8 @@ comment "AT91SAM9G10 Board Type"
 
 config MACH_AT91SAM9G10EK
 	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
-	depends on ARCH_AT91SAM9G10
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	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>
@@ -271,21 +293,21 @@ comment "AT91SAM9263 Board Type"
 
 config MACH_AT91SAM9263EK
 	bool "Atmel AT91SAM9263-EK Evaluation Kit"
-	depends on ARCH_AT91SAM9263
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	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"
-	depends on ARCH_AT91SAM9263
 	help
 	  Select this if you are using a Calao Systems USB-A9263.
 	  <http://www.calao-systems.com>
 
 config MACH_NEOCORE926
 	bool "Adeneo NEOCORE926"
-	depends on ARCH_AT91SAM9263
+	select HAVE_AT91_DATAFLASH_CARD
 	help
 	  Select this if you are using the Adeneo Neocore 926 board.
 
@@ -299,7 +321,6 @@ comment "AT91SAM9RL Board Type"
 
 config MACH_AT91SAM9RLEK
 	bool "Atmel AT91SAM9RL-EK Evaluation Kit"
-	depends on ARCH_AT91SAM9RL
 	help
 	  Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit.
 
@@ -313,14 +334,15 @@ comment "AT91SAM9G20 Board Type"
 
 config MACH_AT91SAM9G20EK
 	bool "Atmel AT91SAM9G20-EK Evaluation Kit"
-	depends on ARCH_AT91SAM9G20
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
 	  that embeds only one SD/MMC slot.
 
 config MACH_AT91SAM9G20EK_2MMC
 	bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
-	depends on ARCH_AT91SAM9G20
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
 	  with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
@@ -328,7 +350,6 @@ config MACH_AT91SAM9G20EK_2MMC
 
 config MACH_CPU9G20
 	bool "Eukrea CPU9G20 board"
-	depends on ARCH_AT91SAM9G20
 	help
 	  Select this if you are using a Eukrea Electromatique's
 	  CPU9G20 Board <http://www.eukrea.com/>
@@ -343,7 +364,7 @@ comment "AT91SAM9G45 Board Type"
 
 config MACH_AT91SAM9G45EKES
 	bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
-	depends on ARCH_AT91SAM9G45
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
 	  "ES" at the end of the name means that this board is an
@@ -359,7 +380,8 @@ comment "AT91CAP9 Board Type"
 
 config MACH_AT91CAP9ADK
 	bool "Atmel AT91CAP9A-DK Evaluation Kit"
-	depends on ARCH_AT91CAP9
+	select HAVE_AT91_DATAFLASH_CARD
+	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
@@ -388,13 +410,13 @@ comment "AT91 Board Options"
 
 config MTD_AT91_DATAFLASH_CARD
 	bool "Enable DataFlash Card support"
-	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
+	depends on HAVE_AT91_DATAFLASH_CARD
 	help
 	  Enable support for the DataFlash card.
 
 config MTD_NAND_ATMEL_BUSWIDTH_16
 	bool "Enable 16-bit data bus interface to NAND flash"
-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G20EK_2MMC || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
+	depends on HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  On AT91SAM926x boards both types of NAND flash can be present
 	  (8 and 16 bit data bus width).
@@ -456,15 +478,15 @@ config AT91_EARLY_USART2
 
 config AT91_EARLY_USART3
 	bool "USART3"
-	depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45)
+	depends on HAVE_AT91_USART3
 
 config AT91_EARLY_USART4
 	bool "USART4"
-	depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20
+	depends on HAVE_AT91_USART4
 
 config AT91_EARLY_USART5
 	bool "USART5"
-	depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20
+	depends on HAVE_AT91_USART5
 
 endchoice
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@ obj-$(CONFIG_MACH_PICOTUX2XX)	+= board-p
 obj-$(CONFIG_MACH_ECBAT91)	+= board-ecbat91.o
 obj-$(CONFIG_MACH_YL9200)	+= board-yl-9200.o
 obj-$(CONFIG_MACH_CPUAT91)	+= board-cpuat91.o
+obj-$(CONFIG_MACH_ECO920)	+= board-eco920.o
 
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -77,6 +78,7 @@ obj-y				+= leds.o
 # Power Management
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_AT91_SLOW_CLOCK)	+= pm_slowclock.o
+obj-$(CONFIG_CPU_IDLE)	+= cpuidle.o
 
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/pm.c linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,62 +29,7 @@
 #include <mach/cpu.h>
 
 #include "generic.h"
-
-#ifdef CONFIG_ARCH_AT91RM9200
-#include <mach/at91rm9200_mc.h>
-
-/*
- * The AT91RM9200 goes into self-refresh mode with this command, and will
- * terminate self-refresh automatically on the next SDRAM access.
- */
-#define sdram_selfrefresh_enable()	at91_sys_write(AT91_SDRAMC_SRR, 1)
-#define sdram_selfrefresh_disable()	do {} while (0)
-
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9_ddrsdr.h>
-
-static u32 saved_lpr;
-
-static inline void sdram_selfrefresh_enable(void)
-{
-	u32 lpr;
-
-	saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
-
-	lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-	at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
-}
-
-#define sdram_selfrefresh_disable()	at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
-
-#else
-#include <mach/at91sam9_sdramc.h>
-
-#ifdef CONFIG_ARCH_AT91SAM9263
-/*
- * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
- * handle those cases both here and in the Suspend-To-RAM support.
- */
-#define	AT91_SDRAMC	AT91_SDRAMC0
-#warning Assuming EB1 SDRAM controller is *NOT* used
-#endif
-
-static u32 saved_lpr;
-
-static inline void sdram_selfrefresh_enable(void)
-{
-	u32 lpr;
-
-	saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
-
-	lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
-	at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
-}
-
-#define sdram_selfrefresh_disable()	at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
-
-#endif
-
+#include "pm.h"
 
 /*
  * Show the reason for the previous system reset.
@@ -260,6 +205,7 @@ extern u32 at91_slow_clock_sz;
 
 static int at91_pm_enter(suspend_state_t state)
 {
+	u32 saved_lpr;
 	at91_gpio_suspend();
 	at91_irq_suspend();
 
@@ -315,9 +261,9 @@ static int at91_pm_enter(suspend_state_t
 			 */
 			asm("b 1f; .align 5; 1:");
 			asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
-			sdram_selfrefresh_enable();
+			saved_lpr = sdram_selfrefresh_enable();
 			asm("mcr p15, 0, r0, c7, c0, 4");	/* wait for interrupt */
-			sdram_selfrefresh_disable();
+			sdram_selfrefresh_disable(saved_lpr);
 			break;
 
 		case PM_SUSPEND_ON:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-at91/pm.h linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-at91/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-at91/pm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,67 @@
+#ifdef CONFIG_ARCH_AT91RM9200
+#include <mach/at91rm9200_mc.h>
+
+/*
+ * The AT91RM9200 goes into self-refresh mode with this command, and will
+ * terminate self-refresh automatically on the next SDRAM access.
+ *
+ * Self-refresh mode is exited as soon as a memory access is made, but we don't
+ * know for sure when that happens. However, we need to restore the low-power
+ * mode if it was enabled before going idle. Restoring low-power mode while
+ * still in self-refresh is "not recommended", but seems to work.
+ */
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+	u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+	at91_sys_write(AT91_SDRAMC_LPR, 0);
+	at91_sys_write(AT91_SDRAMC_SRR, 1);
+	return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9_ddrsdr.h>
+
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+	u32 saved_lpr, lpr;
+
+	saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
+
+	lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
+	at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+	return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
+
+#else
+#include <mach/at91sam9_sdramc.h>
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+/*
+ * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
+ * handle those cases both here and in the Suspend-To-RAM support.
+ */
+#define	AT91_SDRAMC	AT91_SDRAMC0
+#warning Assuming EB1 SDRAM controller is *NOT* used
+#endif
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+	u32 saved_lpr, lpr;
+
+	saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+	lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
+	at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+	return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/arch.c linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/arch.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/arch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/arch.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,10 +47,6 @@ HW_DECLARE_SPINLOCK(gpio)
     EXPORT_SYMBOL(bcmring_gpio_reg_lock);
 #endif
 
-/* FIXME: temporary solution */
-#define BCM_SYSCTL_REBOOT_WARM               1
-#define CTL_BCM_REBOOT                 112
-
 /* sysctl */
 int bcmring_arch_warm_reboot;	/* do a warm reboot on hard reset */
 
@@ -58,27 +54,35 @@ static struct ctl_table_header *bcmring_
 
 static struct ctl_table bcmring_sysctl_warm_reboot[] = {
 	{
-	 .ctl_name = BCM_SYSCTL_REBOOT_WARM,
 	 .procname = "warm",
 	 .data = &bcmring_arch_warm_reboot,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = &proc_dointvec},
+	 .proc_handler = proc_dointvec},
 	{}
 };
 
 static struct ctl_table bcmring_sysctl_reboot[] = {
 	{
-	 .ctl_name = CTL_BCM_REBOOT,
 	 .procname = "reboot",
 	 .mode = 0555,
 	 .child = bcmring_sysctl_warm_reboot},
 	{}
 };
 
+static struct resource nand_resource[] = {
+	[0] = {
+		.start = MM_ADDR_IO_NAND,
+		.end = MM_ADDR_IO_NAND + 0x1000 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 static struct platform_device nand_device = {
 	.name = "bcm-nand",
 	.id = -1,
+	.resource = nand_resource,
+	.num_resources	= ARRAY_SIZE(nand_resource),
 };
 
 static struct platform_device *devices[] __initdata = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/csp/reg.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/csp/reg.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/csp/reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/csp/reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 /**
 *  @file    reg.h
 *
-*  @brief   Generic register defintions used in CSP
+*  @brief   Generic register definitions used in CSP
 */
 /****************************************************************************/
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,7 @@ typedef struct {
 *  @brief   Get next available transaction width
 *
 *
-*  @return  On sucess  : Next avail able transaction width
+*  @return  On success  : Next available transaction width
 *           On failure : dmacHw_TRANSACTION_WIDTH_8
 *
 *  @note
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 /**
 *  @file    mm_addr.h
 *
-*  @brief   Memory Map address defintions
+*  @brief   Memory Map address definitions
 *
 *  @note
 *     None
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/dma.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -651,7 +651,7 @@ int dma_map_add_region(DMA_MemMap_t *mem
 /**
 *   Creates a descriptor ring from a memory mapping.
 *
-*   @return 0 on sucess, error code otherwise.
+*   @return 0 on success, error code otherwise.
 */
 /****************************************************************************/
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,34 +23,11 @@
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-#define __io(a)         ((void __iomem *)HW_IO_PHYS_TO_VIRT(a))
-
-/* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */
-/* happen in readw/writew etc. */
-
-#define readb(c)        __raw_readb(c)
-#define readw(c)        __raw_readw(c)
-#define readl(c)        __raw_readl(c)
-#define readb_relaxed(addr) readb(addr)
-#define readw_relaxed(addr) readw(addr)
-#define readl_relaxed(addr) readl(addr)
-
-#define readsb(p, d, l)   __raw_readsb(p, d, l)
-#define readsw(p, d, l)   __raw_readsw(p, d, l)
-#define readsl(p, d, l)   __raw_readsl(p, d, l)
-
-#define writeb(v, c)     __raw_writeb(v, c)
-#define writew(v, c)     __raw_writew(v, c)
-#define writel(v, c)     __raw_writel(v, c)
-
-#define writesb(p, d, l)  __raw_writesb(p, d, l)
-#define writesw(p, d, l)  __raw_writesw(p, d, l)
-#define writesl(p, d, l)  __raw_writesl(p, d, l)
-
-#define memset_io(c, v, l)    _memset_io((c), (v), (l))
-#define memcpy_fromio(a, c, l)    _memcpy_fromio((a), (c), (l))
-#define memcpy_toio(c, a, l)  _memcpy_toio((c), (a), (l))
-
-#define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b))
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/reg_nand.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/reg_nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/reg_nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/reg_nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,66 @@
+/*****************************************************************************
+* Copyright 2001 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+*  REG_NAND.h
+*
+*  PURPOSE:
+*
+*     This file contains definitions for the nand registers:
+*
+*  NOTES:
+*
+*****************************************************************************/
+
+#if !defined(__ASM_ARCH_REG_NAND_H)
+#define __ASM_ARCH_REG_NAND_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/reg.h>
+#include <mach/reg_umi.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+#define HW_NAND_BASE       MM_IO_BASE_NAND	/* NAND Flash */
+
+/* DMA accesses by the bootstrap need hard nonvirtual addresses */
+#define REG_NAND_CMD            __REG16(HW_NAND_BASE + 0)
+#define REG_NAND_ADDR           __REG16(HW_NAND_BASE + 4)
+
+#define REG_NAND_PHYS_DATA16   (HW_NAND_BASE + 8)
+#define REG_NAND_PHYS_DATA8    (HW_NAND_BASE + 8)
+#define REG_NAND_DATA16         __REG16(REG_NAND_PHYS_DATA16)
+#define REG_NAND_DATA8          __REG8(REG_NAND_PHYS_DATA8)
+
+/* use appropriate offset to make sure it start at the 1K boundary */
+#define REG_NAND_PHYS_DATA_DMA   (HW_NAND_BASE + 0x400)
+#define REG_NAND_DATA_DMA         __REG32(REG_NAND_PHYS_DATA_DMA)
+
+/* Linux DMA requires physical address of the data register */
+#define REG_NAND_DATA16_PADDR    HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA16)
+#define REG_NAND_DATA8_PADDR     HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA8)
+#define REG_NAND_DATA_PADDR      HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA_DMA)
+
+#define NAND_BUS_16BIT()        (0)
+#define NAND_BUS_8BIT()         (!NAND_BUS_16BIT())
+
+/* Register offsets */
+#define REG_NAND_CMD_OFFSET     (0)
+#define REG_NAND_ADDR_OFFSET    (4)
+#define REG_NAND_DATA8_OFFSET   (8)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/reg_umi.h linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/reg_umi.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-bcmring/include/mach/reg_umi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-bcmring/include/mach/reg_umi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,237 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+*  REG_UMI.h
+*
+*  PURPOSE:
+*
+*     This file contains definitions for the nand registers:
+*
+*  NOTES:
+*
+*****************************************************************************/
+
+#if !defined(__ASM_ARCH_REG_UMI_H)
+#define __ASM_ARCH_REG_UMI_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/reg.h>
+#include <mach/csp/mm_io.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/* Unified Memory Interface Ctrl Register */
+#define HW_UMI_BASE       MM_IO_BASE_UMI
+
+/* Flash bank 0 timing and control register */
+#define REG_UMI_FLASH0_TCR         __REG32(HW_UMI_BASE  + 0x00)
+/* Flash bank 1 timing and control register */
+#define REG_UMI_FLASH1_TCR         __REG32(HW_UMI_BASE  + 0x04)
+/* Flash bank 2 timing and control register */
+#define REG_UMI_FLASH2_TCR         __REG32(HW_UMI_BASE  + 0x08)
+/* MMD interface and control register */
+#define REG_UMI_MMD_ICR            __REG32(HW_UMI_BASE  + 0x0c)
+/* NAND timing and control register */
+#define REG_UMI_NAND_TCR           __REG32(HW_UMI_BASE  + 0x18)
+/* NAND ready/chip select register */
+#define REG_UMI_NAND_RCSR          __REG32(HW_UMI_BASE  + 0x1c)
+/* NAND ECC control & status register */
+#define REG_UMI_NAND_ECC_CSR       __REG32(HW_UMI_BASE  + 0x20)
+/* NAND ECC data register XXB2B1B0 */
+#define REG_UMI_NAND_ECC_DATA      __REG32(HW_UMI_BASE  + 0x24)
+/* BCH ECC Parameter N */
+#define REG_UMI_BCH_N              __REG32(HW_UMI_BASE  + 0x40)
+/* BCH ECC Parameter T */
+#define REG_UMI_BCH_K              __REG32(HW_UMI_BASE  + 0x44)
+/* BCH ECC Parameter K */
+#define REG_UMI_BCH_T              __REG32(HW_UMI_BASE  + 0x48)
+/* BCH ECC Contro Status */
+#define REG_UMI_BCH_CTRL_STATUS    __REG32(HW_UMI_BASE  + 0x4C)
+/* BCH WR ECC 31:0 */
+#define REG_UMI_BCH_WR_ECC_0       __REG32(HW_UMI_BASE  + 0x50)
+/* BCH WR ECC 63:32 */
+#define REG_UMI_BCH_WR_ECC_1       __REG32(HW_UMI_BASE  + 0x54)
+/* BCH WR ECC 95:64 */
+#define REG_UMI_BCH_WR_ECC_2       __REG32(HW_UMI_BASE  + 0x58)
+/* BCH WR ECC 127:96 */
+#define REG_UMI_BCH_WR_ECC_3       __REG32(HW_UMI_BASE  + 0x5c)
+/* BCH WR ECC 155:128 */
+#define REG_UMI_BCH_WR_ECC_4       __REG32(HW_UMI_BASE  + 0x60)
+/* BCH Read Error Location 1,0 */
+#define REG_UMI_BCH_RD_ERR_LOC_1_0 __REG32(HW_UMI_BASE  + 0x64)
+/* BCH Read Error Location 3,2 */
+#define REG_UMI_BCH_RD_ERR_LOC_3_2 __REG32(HW_UMI_BASE  + 0x68)
+/* BCH Read Error Location 5,4 */
+#define REG_UMI_BCH_RD_ERR_LOC_5_4 __REG32(HW_UMI_BASE  + 0x6c)
+/* BCH Read Error Location 7,6 */
+#define REG_UMI_BCH_RD_ERR_LOC_7_6 __REG32(HW_UMI_BASE  + 0x70)
+/* BCH Read Error Location 9,8 */
+#define REG_UMI_BCH_RD_ERR_LOC_9_8 __REG32(HW_UMI_BASE  + 0x74)
+/* BCH Read Error Location 11,10 */
+#define REG_UMI_BCH_RD_ERR_LOC_B_A __REG32(HW_UMI_BASE  + 0x78)
+
+/* REG_UMI_FLASH0/1/2_TCR, REG_UMI_SRAM0/1_TCR bits */
+/* Enable wait pin during burst write or read */
+#define REG_UMI_TCR_WAITEN              0x80000000
+/* Enable mem ctrlr to work iwth ext mem of lower freq than AHB clk */
+#define REG_UMI_TCR_LOWFREQ             0x40000000
+/* 1=synch write, 0=async write */
+#define REG_UMI_TCR_MEMTYPE_SYNCWRITE   0x20000000
+/* 1=synch read, 0=async read */
+#define REG_UMI_TCR_MEMTYPE_SYNCREAD    0x10000000
+/* 1=page mode read, 0=normal mode read */
+#define REG_UMI_TCR_MEMTYPE_PAGEREAD    0x08000000
+/* page size/burst size (wrap only) */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_MASK   0x07000000
+/* 4 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_4      0x00000000
+/* 8 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_8      0x01000000
+/* 16 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_16     0x02000000
+/* 32 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_32     0x03000000
+/* 64 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_64     0x04000000
+/* 128 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_128    0x05000000
+/* 256 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_256    0x06000000
+/* 512 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_512    0x07000000
+/* Page read access cycle / Burst write latency (n+2 / n+1) */
+#define REG_UMI_TCR_TPRC_TWLC_MASK      0x00f80000
+/* Bus turnaround cycle (n) */
+#define REG_UMI_TCR_TBTA_MASK           0x00070000
+/* Write pulse width cycle (n+1) */
+#define REG_UMI_TCR_TWP_MASK            0x0000f800
+/* Write recovery cycle (n+1) */
+#define REG_UMI_TCR_TWR_MASK            0x00000600
+/* Write address setup cycle (n+1) */
+#define REG_UMI_TCR_TAS_MASK            0x00000180
+/* Output enable delay cycle (n) */
+#define REG_UMI_TCR_TOE_MASK            0x00000060
+/* Read access cycle / Burst read latency (n+2 / n+1) */
+#define REG_UMI_TCR_TRC_TLC_MASK        0x0000001f
+
+/* REG_UMI_MMD_ICR bits */
+/* Flash write protection pin control */
+#define REG_UMI_MMD_ICR_FLASH_WP            0x8000
+/* Extend hold time for sram0, sram1 csn (39 MHz operation) */
+#define REG_UMI_MMD_ICR_XHCS                0x4000
+/* Enable SDRAM 2 interface control */
+#define REG_UMI_MMD_ICR_SDRAM2EN            0x2000
+/* Enable merge of flash banks 0/1 to 512 MBit bank */
+#define REG_UMI_MMD_ICR_INST512             0x1000
+/* Enable merge of flash banks 1/2 to 512 MBit bank */
+#define REG_UMI_MMD_ICR_DATA512             0x0800
+/* Enable SDRAM interface control */
+#define REG_UMI_MMD_ICR_SDRAMEN             0x0400
+/* Polarity of busy state of Burst Wait Signal */
+#define REG_UMI_MMD_ICR_WAITPOL             0x0200
+/* Enable burst clock stopped when not accessing external burst flash/sram */
+#define REG_UMI_MMD_ICR_BCLKSTOP            0x0100
+/* Enable the peri1_csn to replace flash1_csn in 512 Mb flash mode */
+#define REG_UMI_MMD_ICR_PERI1EN             0x0080
+/* Enable the peri2_csn to replace sdram_csn */
+#define REG_UMI_MMD_ICR_PERI2EN             0x0040
+/* Enable the peri3_csn to replace sdram2_csn */
+#define REG_UMI_MMD_ICR_PERI3EN             0x0020
+/* Enable sram bank1 for H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSB1               0x0010
+/* Enable sram bank0 for H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSB0               0x0008
+/* Polarity for assert3ed state of H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSPOL              0x0004
+/* 0: S/W controllable ZZ/MRS/CRE/P-Mode pin */
+/* 1: H/W controlled ZZ/MRS/CRE/P-Mode, same timing as CS */
+#define REG_UMI_MMD_ICR_MRSMODE             0x0002
+/* MRS state for S/W controlled mode */
+#define REG_UMI_MMD_ICR_MRSSTATE            0x0001
+
+/* REG_UMI_NAND_TCR bits */
+/* Enable software to control CS */
+#define REG_UMI_NAND_TCR_CS_SWCTRL          0x80000000
+/* 16-bit nand wordsize if set */
+#define REG_UMI_NAND_TCR_WORD16             0x40000000
+/* Bus turnaround cycle (n) */
+#define REG_UMI_NAND_TCR_TBTA_MASK          0x00070000
+/* Write pulse width cycle (n+1) */
+#define REG_UMI_NAND_TCR_TWP_MASK           0x0000f800
+/* Write recovery cycle (n+1) */
+#define REG_UMI_NAND_TCR_TWR_MASK           0x00000600
+/* Write address setup cycle (n+1) */
+#define REG_UMI_NAND_TCR_TAS_MASK           0x00000180
+/* Output enable delay cycle (n) */
+#define REG_UMI_NAND_TCR_TOE_MASK           0x00000060
+/* Read access cycle (n+2) */
+#define REG_UMI_NAND_TCR_TRC_TLC_MASK       0x0000001f
+
+/* REG_UMI_NAND_RCSR bits */
+/* Status: Ready=1, Busy=0 */
+#define REG_UMI_NAND_RCSR_RDY               0x02
+/* Keep CS asserted during operation */
+#define REG_UMI_NAND_RCSR_CS_ASSERTED       0x01
+
+/* REG_UMI_NAND_ECC_CSR bits */
+/* Interrupt status - read-only */
+#define REG_UMI_NAND_ECC_CSR_NANDINT        0x80000000
+/* Read: Status of ECC done, Write: clear ECC interrupt */
+#define REG_UMI_NAND_ECC_CSR_ECCINT_RAW     0x00800000
+/* Read: Status of R/B, Write: clear R/B interrupt */
+#define REG_UMI_NAND_ECC_CSR_RBINT_RAW      0x00400000
+/* 1 = Enable ECC Interrupt */
+#define REG_UMI_NAND_ECC_CSR_ECCINT_ENABLE  0x00008000
+/* 1 = Assert interrupt at rising edge of R/B_ */
+#define REG_UMI_NAND_ECC_CSR_RBINT_ENABLE   0x00004000
+/* Calculate ECC by 0=512 bytes, 1=256 bytes */
+#define REG_UMI_NAND_ECC_CSR_256BYTE        0x00000080
+/* Enable ECC in hardware */
+#define REG_UMI_NAND_ECC_CSR_ECC_ENABLE     0x00000001
+
+/* REG_UMI_BCH_CTRL_STATUS bits */
+/* Shift to Indicate Number of correctable errors detected */
+#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR_SHIFT 20
+/* Indicate Number of correctable errors detected */
+#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR 0x00F00000
+/* Indicate Errors detected during read but uncorrectable */
+#define REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR    0x00080000
+/* Indicate Errors detected during read and are correctable */
+#define REG_UMI_BCH_CTRL_STATUS_CORR_ERR      0x00040000
+/* Flag indicates BCH's ECC status of read process are valid */
+#define REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID  0x00020000
+/* Flag indicates BCH's ECC status of write process are valid */
+#define REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID  0x00010000
+/* Pause ECC calculation */
+#define REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC 0x00000010
+/* Enable Interrupt */
+#define REG_UMI_BCH_CTRL_STATUS_INT_EN        0x00000004
+/* Enable ECC during read */
+#define REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN     0x00000002
+/* Enable ECC during write */
+#define REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN     0x00000001
+/* Mask for location */
+#define REG_UMI_BCH_ERR_LOC_MASK              0x00001FFF
+/* location within a byte */
+#define REG_UMI_BCH_ERR_LOC_BYTE              0x00000007
+/* location within a word */
+#define REG_UMI_BCH_ERR_LOC_WORD              0x00000018
+/* location within a page (512 byte) */
+#define REG_UMI_BCH_ERR_LOC_PAGE              0x00001FE0
+#define REG_UMI_BCH_ERR_LOC_ADDR(index)     (__REG32(HW_UMI_BASE + 0x64 + (index / 2)*4) >> ((index % 2) * 16))
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-clps711x/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-clps711x/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-clps711x/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-clps711x/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,8 @@
 
 #define __virt_to_bus(x)	((x) - PAGE_OFFSET)
 #define __bus_to_virt(x)	((x) + PAGE_OFFSET)
+#define __pfn_to_bus(x)		(__pfn_to_phys(x) - PHYS_OFFSET)
+#define __bus_to_pfn(x)		__phys_to_pfn((x) + PHYS_OFFSET)
 
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-da830-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da830-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-da830-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da830-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,51 +10,194 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
 #include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
 #include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/irqs.h>
 #include <mach/cp_intc.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
 #include <mach/da8xx.h>
-#include <mach/asp.h>
+#include <mach/usb.h>
 
 #define DA830_EVM_PHY_MASK		0x0
 #define DA830_EVM_MDIO_FREQUENCY	2200000	/* PHY bus frequency */
 
-static struct at24_platform_data da830_evm_i2c_eeprom_info = {
-	.byte_len	= SZ_256K / 8,
-	.page_size	= 64,
-	.flags		= AT24_FLAG_ADDR16,
-	.setup		= davinci_get_mac_addr,
-	.context	= (void *)0x7f00,
-};
+#define DA830_EMIF25_ASYNC_DATA_CE3_BASE	0x62000000
+#define DA830_EMIF25_CONTROL_BASE		0x68000000
 
-static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("24c256", 0x50),
-		.platform_data	= &da830_evm_i2c_eeprom_info,
-	},
-	{
-		I2C_BOARD_INFO("tlv320aic3x", 0x18),
-	}
+/*
+ * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
+ */
+#define ON_BD_USB_DRV	GPIO_TO_PIN(1, 15)
+#define ON_BD_USB_OVC	GPIO_TO_PIN(2, 4)
+
+static const short da830_evm_usb11_pins[] = {
+	DA830_GPIO1_15, DA830_GPIO2_4,
+	-1
 };
 
-static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
-	.bus_freq	= 100,	/* kHz */
-	.bus_delay	= 0,	/* usec */
+static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
+
+static int da830_evm_usb_set_power(unsigned port, int on)
+{
+	gpio_set_value(ON_BD_USB_DRV, on);
+	return 0;
+}
+
+static int da830_evm_usb_get_power(unsigned port)
+{
+	return gpio_get_value(ON_BD_USB_DRV);
+}
+
+static int da830_evm_usb_get_oci(unsigned port)
+{
+	return !gpio_get_value(ON_BD_USB_OVC);
+}
+
+static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
+
+static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+	int irq 	= gpio_to_irq(ON_BD_USB_OVC);
+	int error	= 0;
+
+	if (handler != NULL) {
+		da830_evm_usb_ocic_handler = handler;
+
+		error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
+				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				    "OHCI over-current indicator", NULL);
+		if (error)
+			printk(KERN_ERR "%s: could not request IRQ to watch "
+			       "over-current indicator changes\n", __func__);
+	} else
+		free_irq(irq, NULL);
+
+	return error;
+}
+
+static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
+	.set_power	= da830_evm_usb_set_power,
+	.get_power	= da830_evm_usb_get_power,
+	.get_oci	= da830_evm_usb_get_oci,
+	.ocic_notify	= da830_evm_usb_ocic_notify,
+
+	/* TPS2065 switch @ 5V */
+	.potpgt		= (3 + 1) / 2,	/* 3 ms max */
 };
 
+static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
+{
+	da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
+	return IRQ_HANDLED;
+}
+
+static __init void da830_evm_usb_init(void)
+{
+	u32 cfgchip2;
+	int ret;
+
+	/*
+	 * Set up USB clock/mode in the CFGCHIP2 register.
+	 * FYI:  CFGCHIP2 is 0x0000ef00 initially.
+	 */
+	cfgchip2 = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+
+	/* USB2.0 PHY reference clock is 24 MHz */
+	cfgchip2 &= ~CFGCHIP2_REFFREQ;
+	cfgchip2 |=  CFGCHIP2_REFFREQ_24MHZ;
+
+	/*
+	 * Select internal reference clock for USB 2.0 PHY
+	 * and use it as a clock source for USB 1.1 PHY
+	 * (this is the default setting anyway).
+	 */
+	cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
+	cfgchip2 |=  CFGCHIP2_USB2PHYCLKMUX;
+
+	/*
+	 * We have to override VBUS/ID signals when MUSB is configured into the
+	 * host-only mode -- ID pin will float if no cable is connected, so the
+	 * controller won't be able to drive VBUS thinking that it's a B-device.
+	 * Otherwise, we want to use the OTG mode and enable VBUS comparators.
+	 */
+	cfgchip2 &= ~CFGCHIP2_OTGMODE;
+#ifdef	CONFIG_USB_MUSB_HOST
+	cfgchip2 |=  CFGCHIP2_FORCE_HOST;
+#else
+	cfgchip2 |=  CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
+#endif
+
+	__raw_writel(cfgchip2, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG));
+
+	/* USB_REFCLKIN is not used. */
+	ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
+	if (ret)
+		pr_warning("%s: USB 2.0 PinMux setup failed: %d\n",
+			   __func__, ret);
+	else {
+		/*
+		 * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A),
+		 * with the power on to power good time of 3 ms.
+		 */
+		ret = da8xx_register_usb20(1000, 3);
+		if (ret)
+			pr_warning("%s: USB 2.0 registration failed: %d\n",
+				   __func__, ret);
+	}
+
+	ret = da8xx_pinmux_setup(da830_evm_usb11_pins);
+	if (ret) {
+		pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+			   __func__, ret);
+		return;
+	}
+
+	ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
+	if (ret) {
+		printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+		       "power control: %d\n", __func__, ret);
+		return;
+	}
+	gpio_direction_output(ON_BD_USB_DRV, 0);
+
+	ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
+	if (ret) {
+		printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+		       "over-current indicator: %d\n", __func__, ret);
+		return;
+	}
+	gpio_direction_input(ON_BD_USB_OVC);
+
+	ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
+	if (ret)
+		pr_warning("%s: USB 1.1 registration failed: %d\n",
+			   __func__, ret);
+}
+
 static struct davinci_uart_config da830_evm_uart_config __initdata = {
 	.enabled_uarts = 0x7,
 };
 
+static const short da830_evm_mcasp1_pins[] = {
+	DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, DA830_AHCLKR1, DA830_AFSR1,
+	DA830_AMUTE1, DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_5,
+	DA830_ACLKR1, DA830_AXR1_6, DA830_AXR1_7, DA830_AXR1_8, DA830_AXR1_10,
+	DA830_AXR1_11,
+	-1
+};
+
 static u8 da830_iis_serializer_direction[] = {
 	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
 	INACTIVE_MODE,	TX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
@@ -74,6 +217,271 @@ static struct snd_platform_data da830_ev
 	.rxnumevt	= 1,
 };
 
+/*
+ * GPIO2[1] is used as MMC_SD_WP and GPIO2[2] as MMC_SD_INS.
+ */
+static const short da830_evm_mmc_sd_pins[] = {
+	DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+	DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+	DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+	DA830_MMCSD_CMD,   DA830_GPIO2_1,     DA830_GPIO2_2,
+	-1
+};
+
+#define DA830_MMCSD_WP_PIN		GPIO_TO_PIN(2, 1)
+
+static int da830_evm_mmc_get_ro(int index)
+{
+	return gpio_get_value(DA830_MMCSD_WP_PIN);
+}
+
+static struct davinci_mmc_config da830_evm_mmc_config = {
+	.get_ro			= da830_evm_mmc_get_ro,
+	.wires			= 4,
+	.max_freq		= 50000000,
+	.caps			= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+	.version		= MMC_CTLR_VERSION_2,
+};
+
+static inline void da830_evm_init_mmc(void)
+{
+	int ret;
+
+	ret = da8xx_pinmux_setup(da830_evm_mmc_sd_pins);
+	if (ret) {
+		pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n",
+				ret);
+		return;
+	}
+
+	ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
+	if (ret) {
+		pr_warning("da830_evm_init: can not open GPIO %d\n",
+			   DA830_MMCSD_WP_PIN);
+		return;
+	}
+	gpio_direction_input(DA830_MMCSD_WP_PIN);
+
+	ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
+	if (ret) {
+		pr_warning("da830_evm_init: mmc/sd registration failed: %d\n",
+				ret);
+		gpio_free(DA830_MMCSD_WP_PIN);
+	}
+}
+
+/*
+ * UI board NAND/NOR flashes only use 8-bit data bus.
+ */
+static const short da830_evm_emif25_pins[] = {
+	DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+	DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+	DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+	DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+	DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+	DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
+	DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
+	-1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC	1
+#else
+#define HAS_MMC	0
+#endif
+
+#ifdef CONFIG_DA830_UI_NAND
+static struct mtd_partition da830_evm_nand_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	[0] = {
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	/* bootloader params in the next sector */
+	[1] = {
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	/* kernel */
+	[2] = {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_2M,
+		.mask_flags	= 0,
+	},
+	/* file system */
+	[3] = {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+};
+
+/* flash bbt decriptors */
+static uint8_t da830_evm_nand_bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t da830_evm_nand_mirror_pattern[] = { '1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr da830_evm_nand_bbt_main_descr = {
+	.options	= NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+			  NAND_BBT_WRITE | NAND_BBT_2BIT |
+			  NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs		= 2,
+	.len		= 4,
+	.veroffs	= 16,
+	.maxblocks	= 4,
+	.pattern	= da830_evm_nand_bbt_pattern
+};
+
+static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = {
+	.options	= NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+			  NAND_BBT_WRITE | NAND_BBT_2BIT |
+			  NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs		= 2,
+	.len		= 4,
+	.veroffs	= 16,
+	.maxblocks	= 4,
+	.pattern	= da830_evm_nand_mirror_pattern
+};
+
+static struct davinci_nand_pdata da830_evm_nand_pdata = {
+	.parts		= da830_evm_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(da830_evm_nand_partitions),
+	.ecc_mode	= NAND_ECC_HW,
+	.ecc_bits	= 4,
+	.options	= NAND_USE_FLASH_BBT,
+	.bbt_td		= &da830_evm_nand_bbt_main_descr,
+	.bbt_md		= &da830_evm_nand_bbt_mirror_descr,
+};
+
+static struct resource da830_evm_nand_resources[] = {
+	[0] = {		/* First memory resource is NAND I/O window */
+		.start	= DA830_EMIF25_ASYNC_DATA_CE3_BASE,
+		.end	= DA830_EMIF25_ASYNC_DATA_CE3_BASE + PAGE_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {		/* Second memory resource is AEMIF control registers */
+		.start	= DA830_EMIF25_CONTROL_BASE,
+		.end	= DA830_EMIF25_CONTROL_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device da830_evm_nand_device = {
+	.name		= "davinci_nand",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &da830_evm_nand_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(da830_evm_nand_resources),
+	.resource	= da830_evm_nand_resources,
+};
+
+static inline void da830_evm_init_nand(int mux_mode)
+{
+	int ret;
+
+	if (HAS_MMC) {
+		pr_warning("WARNING: both MMC/SD and NAND are "
+				"enabled, but they share AEMIF pins.\n"
+				"\tDisable MMC/SD for NAND support.\n");
+		return;
+	}
+
+	ret = da8xx_pinmux_setup(da830_evm_emif25_pins);
+	if (ret)
+		pr_warning("da830_evm_init: emif25 mux setup failed: %d\n",
+				ret);
+
+	ret = platform_device_register(&da830_evm_nand_device);
+	if (ret)
+		pr_warning("da830_evm_init: NAND device not registered.\n");
+
+	gpio_direction_output(mux_mode, 1);
+}
+#else
+static inline void da830_evm_init_nand(int mux_mode) { }
+#endif
+
+#ifdef CONFIG_DA830_UI_LCD
+static inline void da830_evm_init_lcdc(int mux_mode)
+{
+	int ret;
+
+	ret = da8xx_pinmux_setup(da830_lcdcntl_pins);
+	if (ret)
+		pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata);
+	if (ret)
+		pr_warning("da830_evm_init: lcd setup failed: %d\n", ret);
+
+	gpio_direction_output(mux_mode, 0);
+}
+#else
+static inline void da830_evm_init_lcdc(int mux_mode) { }
+#endif
+
+static struct at24_platform_data da830_evm_i2c_eeprom_info = {
+	.byte_len	= SZ_256K / 8,
+	.page_size	= 64,
+	.flags		= AT24_FLAG_ADDR16,
+	.setup		= davinci_get_mac_addr,
+	.context	= (void *)0x7f00,
+};
+
+static int __init da830_evm_ui_expander_setup(struct i2c_client *client,
+		int gpio, unsigned ngpio, void *context)
+{
+	gpio_request(gpio + 6, "UI MUX_MODE");
+
+	/* Drive mux mode low to match the default without UI card */
+	gpio_direction_output(gpio + 6, 0);
+
+	da830_evm_init_lcdc(gpio + 6);
+
+	da830_evm_init_nand(gpio + 6);
+
+	return 0;
+}
+
+static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
+		unsigned ngpio, void *context)
+{
+	gpio_free(gpio + 6);
+	return 0;
+}
+
+static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = {
+	.gpio_base	= DAVINCI_N_GPIO,
+	.setup		= da830_evm_ui_expander_setup,
+	.teardown	= da830_evm_ui_expander_teardown,
+};
+
+static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &da830_evm_i2c_eeprom_info,
+	},
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x3f),
+		.platform_data	= &da830_evm_ui_expander_info,
+	},
+};
+
+static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
+	.bus_freq	= 100,	/* kHz */
+	.bus_delay	= 0,	/* usec */
+};
+
 static __init void da830_evm_init(void)
 {
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -94,6 +502,8 @@ static __init void da830_evm_init(void)
 		pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
 				ret);
 
+	da830_evm_usb_init();
+
 	soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
 	soc_info->emac_pdata->rmii_en = 1;
@@ -117,12 +527,18 @@ static __init void da830_evm_init(void)
 	i2c_register_board_info(1, da830_evm_i2c_devices,
 			ARRAY_SIZE(da830_evm_i2c_devices));
 
-	ret = da8xx_pinmux_setup(da830_mcasp1_pins);
+	ret = da8xx_pinmux_setup(da830_evm_mcasp1_pins);
 	if (ret)
 		pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
 				ret);
 
-	da8xx_init_mcasp(1, &da830_evm_snd_data);
+	da8xx_register_mcasp(1, &da830_evm_snd_data);
+
+	da830_evm_init_mmc();
+
+	ret = da8xx_register_rtc();
+	if (ret)
+		pr_warning("da830_evm_init: rtc setup failed: %d\n", ret);
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
@@ -146,7 +562,7 @@ static void __init da830_evm_map_io(void
 	da830_init();
 }
 
-MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP L137 EVM")
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM")
 	.phys_io	= IO_PHYS,
 	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
 	.boot_params	= (DA8XX_DDR_BASE + 0x100),
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-da850-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da850-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,36 +12,38 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
+#include <linux/i2c/pca953x.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/irqs.h>
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <mach/nand.h>
+#include <mach/mux.h>
 
 #define DA850_EVM_PHY_MASK		0x1
 #define DA850_EVM_MDIO_FREQUENCY	2200000 /* PHY bus frequency */
 
+#define DA850_LCD_PWR_PIN		GPIO_TO_PIN(2, 8)
 #define DA850_LCD_BL_PIN		GPIO_TO_PIN(2, 15)
-#define DA850_LCD_PWR_PIN		GPIO_TO_PIN(8, 10)
 
 #define DA850_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
 #define DA850_MMCSD_WP_PIN		GPIO_TO_PIN(4, 1)
 
+#define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
+
 static struct mtd_partition da850_evm_norflash_partition[] = {
 	{
 		.name           = "NOR filesystem",
@@ -143,10 +145,149 @@ static struct platform_device da850_evm_
 	.resource	= da850_evm_nandflash_resource,
 };
 
+static struct platform_device *da850_evm_devices[] __initdata = {
+	&da850_evm_nandflash_device,
+	&da850_evm_norflash_device,
+};
+
+#define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
+#define DA8XX_AEMIF_ASIZE_16BIT		0x1
+
+static void __init da850_evm_init_nor(void)
+{
+	void __iomem *aemif_addr;
+
+	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+
+	/* Configure data bus width of CS2 to 16 bit */
+	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
+		DA8XX_AEMIF_ASIZE_16BIT,
+		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+
+	iounmap(aemif_addr);
+}
+
+static u32 ui_card_detected;
+
+#if defined(CONFIG_MMC_DAVINCI) || \
+    defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+static __init void da850_evm_setup_nor_nand(void)
+{
+	int ret = 0;
+
+	if (ui_card_detected & !HAS_MMC) {
+		ret = da8xx_pinmux_setup(da850_nand_pins);
+		if (ret)
+			pr_warning("da850_evm_init: nand mux setup failed: "
+					"%d\n", ret);
+
+		ret = da8xx_pinmux_setup(da850_nor_pins);
+		if (ret)
+			pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+				ret);
+
+		da850_evm_init_nor();
+
+		platform_add_devices(da850_evm_devices,
+					ARRAY_SIZE(da850_evm_devices));
+	}
+}
+
+#ifdef CONFIG_DA850_UI_RMII
+static inline void da850_evm_setup_emac_rmii(int rmii_sel)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+	soc_info->emac_pdata->rmii_en = 1;
+	gpio_set_value(rmii_sel, 0);
+}
+#else
+static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
+#endif
+
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
+						unsigned ngpio, void *c)
+{
+	int sel_a, sel_b, sel_c, ret;
+
+	sel_a = gpio + 7;
+	sel_b = gpio + 6;
+	sel_c = gpio + 5;
+
+	ret = gpio_request(sel_a, "sel_a");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_a);
+		goto exp_setup_sela_fail;
+	}
+
+	ret = gpio_request(sel_b, "sel_b");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_b);
+		goto exp_setup_selb_fail;
+	}
+
+	ret = gpio_request(sel_c, "sel_c");
+	if (ret) {
+		pr_warning("Cannot open UI expander pin %d\n", sel_c);
+		goto exp_setup_selc_fail;
+	}
+
+	/* deselect all functionalities */
+	gpio_direction_output(sel_a, 1);
+	gpio_direction_output(sel_b, 1);
+	gpio_direction_output(sel_c, 1);
+
+	ui_card_detected = 1;
+	pr_info("DA850/OMAP-L138 EVM UI card detected\n");
+
+	da850_evm_setup_nor_nand();
+
+	da850_evm_setup_emac_rmii(sel_a);
+
+	return 0;
+
+exp_setup_selc_fail:
+	gpio_free(sel_b);
+exp_setup_selb_fail:
+	gpio_free(sel_a);
+exp_setup_sela_fail:
+	return ret;
+}
+
+static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+					unsigned gpio, unsigned ngpio, void *c)
+{
+	/* deselect all functionalities */
+	gpio_set_value(gpio + 5, 1);
+	gpio_set_value(gpio + 6, 1);
+	gpio_set_value(gpio + 7, 1);
+
+	gpio_free(gpio + 5);
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 7);
+
+	return 0;
+}
+
+static struct pca953x_platform_data da850_evm_ui_expander_info = {
+	.gpio_base	= DAVINCI_N_GPIO,
+	.setup		= da850_evm_ui_expander_setup,
+	.teardown	= da850_evm_ui_expander_teardown,
+};
+
 static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("tlv320aic3x", 0x18),
-	}
+	},
+	{
+		I2C_BOARD_INFO("tca6416", 0x20),
+		.platform_data = &da850_evm_ui_expander_info,
+	},
 };
 
 static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
@@ -158,11 +299,6 @@ static struct davinci_uart_config da850_
 	.enabled_uarts = 0x7,
 };
 
-static struct platform_device *da850_evm_devices[] __initdata = {
-	&da850_evm_nandflash_device,
-	&da850_evm_norflash_device,
-};
-
 /* davinci da850 evm audio machine driver */
 static u8 da850_iis_serializer_direction[] = {
 	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
@@ -198,9 +334,20 @@ static struct davinci_mmc_config da850_m
 	.get_ro		= da850_evm_mmc_get_ro,
 	.get_cd		= da850_evm_mmc_get_cd,
 	.wires		= 4,
+	.max_freq	= 50000000,
+	.caps		= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
 	.version	= MMC_CTLR_VERSION_2,
 };
 
+static void da850_panel_power_ctrl(int val)
+{
+	/* lcd backlight */
+	gpio_set_value(DA850_LCD_BL_PIN, val);
+
+	/* lcd power */
+	gpio_set_value(DA850_LCD_PWR_PIN, val);
+}
+
 static int da850_lcd_hw_init(void)
 {
 	int status;
@@ -218,71 +365,236 @@ static int da850_lcd_hw_init(void)
 	gpio_direction_output(DA850_LCD_BL_PIN, 0);
 	gpio_direction_output(DA850_LCD_PWR_PIN, 0);
 
-	/* disable lcd backlight */
-	gpio_set_value(DA850_LCD_BL_PIN, 0);
-
-	/* disable lcd power */
-	gpio_set_value(DA850_LCD_PWR_PIN, 0);
-
-	/* enable lcd power */
-	gpio_set_value(DA850_LCD_PWR_PIN, 1);
+	/* Switch off panel power and backlight */
+	da850_panel_power_ctrl(0);
 
-	/* enable lcd backlight */
-	gpio_set_value(DA850_LCD_BL_PIN, 1);
+	/* Switch on panel power and backlight */
+	da850_panel_power_ctrl(1);
 
 	return 0;
 }
 
-#define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
-#define DA8XX_AEMIF_ASIZE_16BIT		0x1
+/* TPS65070 voltage regulator support */
 
-static void __init da850_evm_init_nor(void)
-{
-	void __iomem *aemif_addr;
+/* 3.3V */
+struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
+	{
+		.supply = "usb0_vdda33",
+	},
+	{
+		.supply = "usb1_vdda33",
+	},
+};
 
-	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+/* 3.3V or 1.8V */
+struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
+	{
+		.supply = "dvdd3318_a",
+	},
+	{
+		.supply = "dvdd3318_b",
+	},
+	{
+		.supply = "dvdd3318_c",
+	},
+};
 
-	/* Configure data bus width of CS2 to 16 bit */
-	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
-		DA8XX_AEMIF_ASIZE_16BIT,
-		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+/* 1.2V */
+struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
+	{
+		.supply = "cvdd",
+	},
+};
 
-	iounmap(aemif_addr);
-}
+/* 1.8V LDO */
+struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
+	{
+		.supply = "sata_vddr",
+	},
+	{
+		.supply = "usb0_vdda18",
+	},
+	{
+		.supply = "usb1_vdda18",
+	},
+	{
+		.supply = "ddr_dvdd18",
+	},
+};
 
-#if defined(CONFIG_MTD_PHYSMAP) || \
-    defined(CONFIG_MTD_PHYSMAP_MODULE)
-#define HAS_NOR 1
-#else
-#define HAS_NOR 0
-#endif
+/* 1.2V LDO */
+struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
+	{
+		.supply = "sata_vdd",
+	},
+	{
+		.supply = "pll0_vdda",
+	},
+	{
+		.supply = "pll1_vdda",
+	},
+	{
+		.supply = "usbs_cvdd",
+	},
+	{
+		.supply = "vddarnwa1",
+	},
+};
 
-#if defined(CONFIG_MMC_DAVINCI) || \
-    defined(CONFIG_MMC_DAVINCI_MODULE)
-#define HAS_MMC 1
-#else
-#define HAS_MMC 0
-#endif
+struct regulator_init_data tps65070_regulator_data[] = {
+	/* dcdc1 */
+	{
+		.constraints = {
+			.min_uV = 3150000,
+			.max_uV = 3450000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers),
+		.consumer_supplies = tps65070_dcdc1_consumers,
+	},
 
-static __init void da850_evm_init(void)
+	/* dcdc2 */
+	{
+		.constraints = {
+			.min_uV = 1710000,
+			.max_uV = 3450000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
+		.consumer_supplies = tps65070_dcdc2_consumers,
+	},
+
+	/* dcdc3 */
+	{
+		.constraints = {
+			.min_uV = 950000,
+			.max_uV = 1320000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
+		.consumer_supplies = tps65070_dcdc3_consumers,
+	},
+
+	/* ldo1 */
+	{
+		.constraints = {
+			.min_uV = 1710000,
+			.max_uV = 1890000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers),
+		.consumer_supplies = tps65070_ldo1_consumers,
+	},
+
+	/* ldo2 */
+	{
+		.constraints = {
+			.min_uV = 1140000,
+			.max_uV = 1320000,
+			.valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS),
+			.boot_on = 1,
+		},
+		.num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers),
+		.consumer_supplies = tps65070_ldo2_consumers,
+	},
+};
+
+static struct i2c_board_info __initdata da850evm_tps65070_info[] = {
+	{
+		I2C_BOARD_INFO("tps6507x", 0x48),
+		.platform_data = &tps65070_regulator_data[0],
+	},
+};
+
+static int __init pmic_tps65070_init(void)
 {
-	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	return i2c_register_board_info(1, da850evm_tps65070_info,
+					ARRAY_SIZE(da850evm_tps65070_info));
+}
+
+static const short da850_evm_lcdc_pins[] = {
+	DA850_GPIO2_8, DA850_GPIO2_15,
+	-1
+};
+
+static int __init da850_evm_config_emac(void)
+{
+	void __iomem *cfg_chip3_base;
 	int ret;
+	u32 val;
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	u8 rmii_en = soc_info->emac_pdata->rmii_en;
+
+	if (!machine_is_davinci_da850_evm())
+		return 0;
+
+	cfg_chip3_base = DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG);
+
+	val = __raw_readl(cfg_chip3_base);
+
+	if (rmii_en) {
+		val |= BIT(8);
+		ret = da8xx_pinmux_setup(da850_rmii_pins);
+		pr_info("EMAC: RMII PHY configured, MII PHY will not be"
+							" functional\n");
+	} else {
+		val &= ~BIT(8);
+		ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+		pr_info("EMAC: MII PHY configured, RMII PHY will not be"
+							" functional\n");
+	}
 
-	ret = da8xx_pinmux_setup(da850_nand_pins);
 	if (ret)
-		pr_warning("da850_evm_init: nand mux setup failed: %d\n",
+		pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
 				ret);
 
-	ret = da8xx_pinmux_setup(da850_nor_pins);
+	/* configure the CFGCHIP3 register for RMII or MII */
+	__raw_writel(val, cfg_chip3_base);
+
+	ret = davinci_cfg_reg(DA850_GPIO2_6);
 	if (ret)
-		pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+		pr_warning("da850_evm_init:GPIO(2,6) mux setup "
+							"failed\n");
+
+	ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+	if (ret) {
+		pr_warning("Cannot open GPIO %d\n",
+					DA850_MII_MDIO_CLKEN_PIN);
+		return ret;
+	}
+
+	/* Enable/Disable MII MDIO clock */
+	gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
+
+	soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
+
+	ret = da8xx_register_emac();
+	if (ret)
+		pr_warning("da850_evm_init: emac registration failed: %d\n",
 				ret);
 
-	da850_evm_init_nor();
+	return 0;
+}
+device_initcall(da850_evm_config_emac);
 
-	platform_add_devices(da850_evm_devices,
-				ARRAY_SIZE(da850_evm_devices));
+static __init void da850_evm_init(void)
+{
+	int ret;
+
+	ret = pmic_tps65070_init();
+	if (ret)
+		pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
+				ret);
 
 	ret = da8xx_register_edma();
 	if (ret)
@@ -299,19 +611,6 @@ static __init void da850_evm_init(void)
 		pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
 				ret);
 
-	soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
-	soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
-	soc_info->emac_pdata->rmii_en = 0;
-
-	ret = da8xx_pinmux_setup(da850_cpgmac_pins);
-	if (ret)
-		pr_warning("da850_evm_init: cpgmac mux setup failed: %d\n",
-				ret);
-
-	ret = da8xx_register_emac();
-	if (ret)
-		pr_warning("da850_evm_init: emac registration failed: %d\n",
-				ret);
 
 	ret = da8xx_register_watchdog();
 	if (ret)
@@ -319,11 +618,6 @@ static __init void da850_evm_init(void)
 				ret);
 
 	if (HAS_MMC) {
-		if (HAS_NOR)
-			pr_warning("WARNING: both NOR Flash and MMC/SD are "
-				"enabled, but they share AEMIF pins.\n"
-				"\tDisable one of them.\n");
-
 		ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
 		if (ret)
 			pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
@@ -365,22 +659,43 @@ static __init void da850_evm_init(void)
 		pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
 				ret);
 
-	da8xx_init_mcasp(0, &da850_evm_snd_data);
+	da8xx_register_mcasp(0, &da850_evm_snd_data);
 
 	ret = da8xx_pinmux_setup(da850_lcdcntl_pins);
 	if (ret)
 		pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
 				ret);
 
+	/* Handle board specific muxing for LCD here */
+	ret = da8xx_pinmux_setup(da850_evm_lcdc_pins);
+	if (ret)
+		pr_warning("da850_evm_init: evm specific lcd mux setup "
+				"failed: %d\n",	ret);
+
 	ret = da850_lcd_hw_init();
 	if (ret)
 		pr_warning("da850_evm_init: lcd initialization failed: %d\n",
 				ret);
 
-	ret = da8xx_register_lcdc();
+	sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
+	ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
 	if (ret)
 		pr_warning("da850_evm_init: lcdc registration failed: %d\n",
 				ret);
+
+	ret = da8xx_register_rtc();
+	if (ret)
+		pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
+
+	ret = da850_register_cpufreq();
+	if (ret)
+		pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
+				ret);
+
+	ret = da8xx_register_cpuidle();
+	if (ret)
+		pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
+				ret);
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm355-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm355-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,15 +9,13 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
-#include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/videodev2.h>
@@ -25,20 +23,15 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
-#include <mach/hardware.h>
 #include <mach/dm355.h>
-#include <mach/psc.h>
-#include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x01e10000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
@@ -86,8 +79,9 @@ static struct davinci_nand_pdata davinci
 	.mask_chipsel		= BIT(14),
 	.parts			= davinci_nand_partitions,
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
-	.ecc_mode		= NAND_ECC_HW_SYNDROME,
+	.ecc_mode		= NAND_ECC_HW,
 	.options		= NAND_USE_FLASH_BBT,
+	.ecc_bits		= 4,
 };
 
 static struct resource davinci_nand_resources[] = {
@@ -242,6 +236,7 @@ static struct vpfe_subdev_info vpfe_sub_
 
 static struct vpfe_config vpfe_cfg = {
 	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+	.i2c_adapter_id = 1,
 	.sub_devs = vpfe_sub_devs,
 	.card_name = "DM355 EVM",
 	.ccdc = "DM355 CCDC",
@@ -344,7 +339,7 @@ static __init void dm355_evm_init(void)
 	gpio_request(2, "usb_id_toggle");
 	gpio_direction_output(2, USB_ID_VALUE);
 	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	davinci_setup_mmc(0, &dm355evm_mmc_config);
 	davinci_setup_mmc(1, &dm355evm_mmc_config);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm355-leopard.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-leopard.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm355-leopard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm355-leopard.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,34 +8,27 @@
  * warranty of any kind, whether express or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
-#include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
-#include <mach/hardware.h>
 #include <mach/dm355.h>
-#include <mach/psc.h>
-#include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x01e10000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
@@ -270,7 +263,7 @@ static __init void dm355_leopard_init(vo
 	gpio_request(2, "usb_id_toggle");
 	gpio_direction_output(2, USB_ID_VALUE);
 	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	davinci_setup_mmc(0, &dm355leopard_mmc_config);
 	davinci_setup_mmc(1, &dm355leopard_mmc_config);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm365-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm365-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,9 +13,8 @@
  * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/clk.h>
@@ -24,20 +23,19 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
-#include <asm/setup.h>
+#include <linux/input.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
+
 #include <mach/mux.h>
-#include <mach/hardware.h>
 #include <mach/dm365.h>
-#include <mach/psc.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mmc.h>
 #include <mach/nand.h>
-
+#include <mach/keyscan.h>
 
 static inline int have_imager(void)
 {
@@ -144,6 +142,7 @@ static struct davinci_nand_pdata davinci
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
 	.ecc_mode		= NAND_ECC_HW,
 	.options		= NAND_USE_FLASH_BBT,
+	.ecc_bits		= 4,
 };
 
 static struct resource davinci_nand_resources[] = {
@@ -176,11 +175,16 @@ static struct at24_platform_data eeprom_
 	.context	= (void *)0x7f00,
 };
 
+static struct snd_platform_data dm365_evm_snd_data;
+
 static struct i2c_board_info i2c_info[] = {
 	{
 		I2C_BOARD_INFO("24c256", 0x50),
 		.platform_data	= &eeprom_info,
 	},
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	},
 };
 
 static struct davinci_i2c_platform_data i2c_pdata = {
@@ -188,6 +192,42 @@ static struct davinci_i2c_platform_data
 	.bus_delay	= 0	/* usec */,
 };
 
+static int dm365evm_keyscan_enable(struct device *dev)
+{
+	return davinci_cfg_reg(DM365_KEYSCAN);
+}
+
+static unsigned short dm365evm_keymap[] = {
+	KEY_KP2,
+	KEY_LEFT,
+	KEY_EXIT,
+	KEY_DOWN,
+	KEY_ENTER,
+	KEY_UP,
+	KEY_KP1,
+	KEY_RIGHT,
+	KEY_MENU,
+	KEY_RECORD,
+	KEY_REWIND,
+	KEY_KPMINUS,
+	KEY_STOP,
+	KEY_FASTFORWARD,
+	KEY_KPPLUS,
+	KEY_PLAYPAUSE,
+	0
+};
+
+static struct davinci_ks_platform_data dm365evm_ks_data = {
+	.device_enable	= dm365evm_keyscan_enable,
+	.keymap		= dm365evm_keymap,
+	.keymapsize	= ARRAY_SIZE(dm365evm_keymap),
+	.rep		= 1,
+	/* Scan period = strobe + interval */
+	.strobe		= 0x5,
+	.interval	= 0x2,
+	.matrix_type	= DAVINCI_KEYSCAN_MATRIX_4X4,
+};
+
 static int cpld_mmc_get_cd(int module)
 {
 	if (!cpld)
@@ -472,6 +512,10 @@ static __init void dm365_evm_init(void)
 
 	/* maybe setup mmc1/etc ... _after_ mmc0 */
 	evm_init_cpld();
+
+	dm365_init_asp(&dm365_evm_snd_data);
+	dm365_init_rtc();
+	dm365_init_ks(&dm365evm_ks_data);
 }
 
 static __init void dm365_evm_irq_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,45 +9,34 @@
  * or implied.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/memory.h>
-
 #include <linux/i2c.h>
 #include <linux/i2c/pcf857x.h>
 #include <linux/i2c/at24.h>
-#include <linux/etherdevice.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
-#include <linux/io.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
 #include <linux/videodev2.h>
 
 #include <media/tvp514x.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
-
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mux.h>
-#include <mach/psc.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
-#include <mach/emac.h>
+#include <mach/usb.h>
 
 #define DM644X_EVM_PHY_MASK		(0x2)
 #define DM644X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
@@ -258,6 +247,7 @@ static struct vpfe_subdev_info vpfe_sub_
 
 static struct vpfe_config vpfe_cfg = {
 	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+	.i2c_adapter_id = 1,
 	.sub_devs = vpfe_sub_devs,
 	.card_name = "DM6446 EVM",
 	.ccdc = "DM6446 CCDC",
@@ -477,7 +467,7 @@ evm_u35_setup(struct i2c_client *client,
 	/* irlml6401 switches over 1A, in under 8 msec;
 	 * now it can be managed by nDRV_VBUS ...
 	 */
-	setup_usb(500, 8);
+	davinci_setup_usb(1000, 8);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,38 +17,28 @@
  **************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-#include <linux/dma-mapping.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
-#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
 #include <linux/i2c/pcf857x.h>
-#include <linux/etherdevice.h>
 
 #include <media/tvp514x.h>
 
-#include <asm/setup.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/flash.h>
 
 #include <mach/dm646x.h>
 #include <mach/common.h>
-#include <mach/psc.h>
 #include <mach/serial.h>
 #include <mach/i2c.h>
-#include <mach/mmc.h>
-#include <mach/emac.h>
+#include <mach/nand.h>
 
 #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
@@ -57,6 +47,11 @@
 #define HAS_ATA 0
 #endif
 
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE		0x20008000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x42000000
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
 /* CPLD Register 0 bits to control ATA */
 #define DM646X_EVM_ATA_RST		BIT(0)
 #define DM646X_EVM_ATA_PWD		BIT(1)
@@ -92,6 +87,63 @@ static struct davinci_uart_config uart_c
 	.enabled_uarts = (1 << 0),
 };
 
+/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
+ * and U-Boot environment this avoids dependency on any particular combination
+ * of UBL, U-Boot or flashing tools etc.
+ */
+static struct mtd_partition davinci_nand_partitions[] = {
+	{
+		/* UBL, U-Boot with environment */
+		.name		= "bootloader",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 16 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+	.mask_cle 		= 0x80000,
+	.mask_ale 		= 0x40000,
+	.parts			= davinci_nand_partitions,
+	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
+	.ecc_mode		= NAND_ECC_HW,
+	.options		= 0,
+};
+
+static struct resource davinci_nand_resources[] = {
+	{
+		.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device davinci_nand_device = {
+	.name			= "davinci_nand",
+	.id			= 0,
+
+	.num_resources		= ARRAY_SIZE(davinci_nand_resources),
+	.resource		= davinci_nand_resources,
+
+	.dev			= {
+		.platform_data	= &davinci_nand_data,
+	},
+};
+
 /* CPLD Register 0 Client: used for I/O Control */
 static int cpld_reg0_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -142,7 +194,7 @@ static struct gpio_led evm_leds[] = {
 	{ .name = "DS4", .active_low = 1, },
 };
 
-static __initconst struct gpio_led_platform_data evm_led_data = {
+static const struct gpio_led_platform_data evm_led_data = {
 	.num_leds = ARRAY_SIZE(evm_leds),
 	.leds     = evm_leds,
 };
@@ -647,6 +699,8 @@ static __init void evm_init(void)
 	dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
 	dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
 
+	platform_device_register(&davinci_nand_device);
+
 	if (HAS_ATA)
 		dm646x_init_ide();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-neuros-osd2.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-neuros-osd2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-neuros-osd2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-neuros-osd2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,323 @@
+/*
+ * Neuros Technologies OSD2 board support
+ *
+ * Modified from original 644X-EVM board support.
+ * 2008 (c) Neuros Technology, LLC.
+ * 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+ * 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com>
+ *
+ * The Neuros OSD 2.0 is the hardware component of the Neuros Open
+ * Internet Television Platform. Hardware is very close to TI
+ * DM644X-EVM board. It has:
+ * 	DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC,
+ * 	USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video.
+ * 	Additionaly realtime clock, IR remote control receiver,
+ * 	IR Blaster based on MSP430 (firmware although is different
+ * 	from used in DM644X-EVM), internal ATA-6 3.5” HDD drive
+ * 	with PATA interface, two muxed red-green leds.
+ *
+ * For more information please refer to
+ * 		http://wiki.neurostechnology.com/index.php/OSD_2.0_HD
+ *
+ * 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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+#define NEUROS_OSD2_PHY_MASK		0x2
+#define NEUROS_OSD2_MDIO_FREQUENCY	2200000 /* PHY bus frequency */
+
+#define DAVINCI_CFC_ATA_BASE		 0x01C66000
+
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE	 0x01e00000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+#define LXT971_PHY_ID			0x001378e2
+#define LXT971_PHY_MASK			0xfffffff0
+
+#define	NTOSD2_AUDIOSOC_I2C_ADDR	0x18
+#define	NTOSD2_MSP430_I2C_ADDR		0x59
+#define	NTOSD2_MSP430_IRQ		2
+
+/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA,
+ * 2048 blocks in the device, 64 pages per block, 2048 bytes per
+ * page.
+ */
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
+struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
+	{
+		/* UBL (a few copies) plus U-Boot */
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= 15 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	}, {
+		/* U-Boot environment */
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 1 * NAND_BLOCK_SIZE,
+		.mask_flags	= 0,
+	}, {
+		/* Kernel */
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	}, {
+		/* File System */
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+	/* A few blocks at end hold a flash Bad Block Table. */
+};
+
+static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
+	.parts		= davinci_ntosd2_nandflash_partition,
+	.nr_parts	= ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
+	.ecc_mode	= NAND_ECC_HW,
+	.options	= NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_ntosd2_nandflash_resource[] = {
+	{
+		.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+		.end		= DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device davinci_ntosd2_nandflash_device = {
+	.name		= "davinci_nand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &davinci_ntosd2_nandflash_data,
+	},
+	.num_resources	= ARRAY_SIZE(davinci_ntosd2_nandflash_resource),
+	.resource	= davinci_ntosd2_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+	.name		= "davincifb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &davinci_fb_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources = 0,
+};
+
+static struct resource ide_resources[] = {
+	{
+		.start		= DAVINCI_CFC_ATA_BASE,
+		.end		= DAVINCI_CFC_ATA_BASE + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_IDE,
+		.end		= IRQ_IDE,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_dev = {
+	.name		= "palm_bk3710",
+	.id		= -1,
+	.resource	= ide_resources,
+	.num_resources	= ARRAY_SIZE(ide_resources),
+	.dev = {
+		.dma_mask		= &ide_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+static struct snd_platform_data dm644x_ntosd2_snd_data;
+
+static struct gpio_led ntosd2_leds[] = {
+	{ .name = "led1_green", .gpio = GPIO(10), },
+	{ .name = "led1_red",   .gpio = GPIO(11), },
+	{ .name = "led2_green", .gpio = GPIO(12), },
+	{ .name = "led2_red",   .gpio = GPIO(13), },
+};
+
+static struct gpio_led_platform_data ntosd2_leds_data = {
+	.num_leds	= ARRAY_SIZE(ntosd2_leds),
+	.leds		= ntosd2_leds,
+};
+
+static struct platform_device ntosd2_leds_dev = {
+	.name = "leds-gpio",
+	.id   = -1,
+	.dev = {
+		.platform_data 		= &ntosd2_leds_data,
+	},
+};
+
+
+static struct platform_device *davinci_ntosd2_devices[] __initdata = {
+	&davinci_fb_device,
+	&ntosd2_leds_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_ntosd2_map_io(void)
+{
+	dm644x_init();
+}
+
+/*
+ I2C initialization
+*/
+static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
+	.bus_freq	= 20 /* kHz */,
+	.bus_delay	= 100 /* usec */,
+};
+
+static struct i2c_board_info __initdata ntosd2_i2c_info[] =  {
+};
+
+static	int ntosd2_init_i2c(void)
+{
+	int	status;
+
+	davinci_init_i2c(&ntosd2_i2c_pdata);
+	status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
+	if (status == 0) {
+		status = gpio_direction_input(NTOSD2_MSP430_IRQ);
+		if (status == 0) {
+			status = gpio_to_irq(NTOSD2_MSP430_IRQ);
+			if (status > 0) {
+				ntosd2_i2c_info[0].irq = status;
+				i2c_register_board_info(1,
+					ntosd2_i2c_info,
+					ARRAY_SIZE(ntosd2_i2c_info));
+			}
+		}
+	}
+	return status;
+}
+
+static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
+	.wires		= 4,
+	.version	= MMC_CTLR_VERSION_1
+};
+
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+	defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+	defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_ntosd2_init(void)
+{
+	struct clk *aemif_clk;
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	int	status;
+
+	aemif_clk = clk_get(NULL, "aemif");
+	clk_enable(aemif_clk);
+
+	if (HAS_ATA) {
+		if (HAS_NAND)
+			pr_warning("WARNING: both IDE and Flash are "
+				"enabled, but they share AEMIF pins.\n"
+				"\tDisable IDE for NAND/NOR support.\n");
+		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+		davinci_cfg_reg(DM644X_ATAEN);
+		davinci_cfg_reg(DM644X_HDIREN);
+		platform_device_register(&ide_dev);
+	} else if (HAS_NAND) {
+		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+		davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+		/* only one device will be jumpered and detected */
+		if (HAS_NAND)
+			platform_device_register(
+					&davinci_ntosd2_nandflash_device);
+	}
+
+	platform_add_devices(davinci_ntosd2_devices,
+				ARRAY_SIZE(davinci_ntosd2_devices));
+
+	/* Initialize I2C interface specific for this board */
+	status = ntosd2_init_i2c();
+	if (status < 0)
+		pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
+						"	 %d\n", status);
+
+	davinci_serial_init(&uart_config);
+	dm644x_init_asp(&dm644x_ntosd2_snd_data);
+
+	soc_info->emac_pdata->phy_mask = NEUROS_OSD2_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = NEUROS_OSD2_MDIO_FREQUENCY;
+
+	davinci_setup_usb(1000, 8);
+	/*
+	 * Mux the pins to be GPIOs, VLYNQEN is already done at startup.
+	 * The AEAWx are five new AEAW pins that can be muxed by separately.
+	 * They are a bitmask for GPIO management. According TI
+	 * documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ
+	 * gpio(10,11,12,13) for leds any combination of bits works except
+	 * four last. So we are to reset all five.
+	 */
+	davinci_cfg_reg(DM644X_AEAW0);
+	davinci_cfg_reg(DM644X_AEAW1);
+	davinci_cfg_reg(DM644X_AEAW2);
+	davinci_cfg_reg(DM644X_AEAW3);
+	davinci_cfg_reg(DM644X_AEAW4);
+
+	davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
+}
+
+static __init void davinci_ntosd2_irq_init(void)
+{
+	davinci_irq_init();
+}
+
+MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
+	/* Maintainer: Neuros Technologies <neuros@groups.google.com> */
+	.phys_io	= IO_PHYS,
+	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params	= (DAVINCI_DDR_BASE + 0x100),
+	.map_io		 = davinci_ntosd2_map_io,
+	.init_irq	= davinci_ntosd2_irq_init,
+	.timer		= &davinci_timer,
+	.init_machine = davinci_ntosd2_init,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-sffsdr.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-sffsdr.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/board-sffsdr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/board-sffsdr.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,35 +23,24 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
-
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
-#include <linux/etherdevice.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
 
-#include <asm/setup.h>
 #include <asm/mach-types.h>
-
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
 #include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
-#include <mach/psc.h>
 #include <mach/mux.h>
+#include <mach/usb.h>
 
 #define SFFSDR_PHY_MASK		(0x2)
 #define SFFSDR_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
@@ -107,11 +96,6 @@ static struct platform_device davinci_sf
 	.resource	= davinci_sffsdr_nandflash_resource,
 };
 
-static struct emac_platform_data sffsdr_emac_pdata = {
-	.phy_mask	= SFFSDR_PHY_MASK,
-	.mdio_max_freq	= SFFSDR_MDIO_FREQUENCY,
-};
-
 static struct at24_platform_data eeprom_info = {
 	.byte_len	= (64*1024) / 8,
 	.page_size	= 32,
@@ -164,7 +148,7 @@ static __init void davinci_sffsdr_init(v
 	davinci_serial_init(&uart_config);
 	soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
-	setup_usb(0, 0); /* We support only peripheral mode. */
+	davinci_setup_usb(0, 0); /* We support only peripheral mode. */
 
 	/* mux VLYNQ pins */
 	davinci_cfg_reg(DM644X_VLYNQEN);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,8 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 
@@ -42,8 +42,7 @@ static void __clk_enable(struct clk *clk
 	if (clk->parent)
 		__clk_enable(clk->parent);
 	if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
-		davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
-				clk->lpsc, 1);
+		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1);
 }
 
 static void __clk_disable(struct clk *clk)
@@ -51,8 +50,7 @@ static void __clk_disable(struct clk *cl
 	if (WARN_ON(clk->usecount == 0))
 		return;
 	if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
-		davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
-				clk->lpsc, 0);
+		davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
 	if (clk->parent)
 		__clk_disable(clk->parent);
 }
@@ -99,20 +97,74 @@ long clk_round_rate(struct clk *clk, uns
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	if (clk->round_rate)
+		return clk->round_rate(clk, rate);
+
 	return clk->rate;
 }
 EXPORT_SYMBOL(clk_round_rate);
 
+/* Propagate rate to children */
+static void propagate_rate(struct clk *root)
+{
+	struct clk *clk;
+
+	list_for_each_entry(clk, &root->children, childnode) {
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
+		propagate_rate(clk);
+	}
+}
+
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
+	unsigned long flags;
+	int ret = -EINVAL;
+
 	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
+		return ret;
 
-	/* changing the clk rate is not supported */
-	return -EINVAL;
+	spin_lock_irqsave(&clockfw_lock, flags);
+	if (clk->set_rate)
+		ret = clk->set_rate(clk, rate);
+	if (ret == 0) {
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
+		propagate_rate(clk);
+	}
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return ret;
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	/* Cannot change parent on enabled clock */
+	if (WARN_ON(clk->usecount))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	clk->parent = parent;
+	list_del_init(&clk->childnode);
+	list_add(&clk->childnode, &clk->parent->children);
+	mutex_unlock(&clocks_mutex);
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	if (clk->recalc)
+		clk->rate = clk->recalc(clk);
+	propagate_rate(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
 int clk_register(struct clk *clk)
 {
 	if (clk == NULL || IS_ERR(clk))
@@ -123,16 +175,24 @@ int clk_register(struct clk *clk)
 			clk->name, clk->parent->name))
 		return -EINVAL;
 
+	INIT_LIST_HEAD(&clk->children);
+
 	mutex_lock(&clocks_mutex);
 	list_add_tail(&clk->node, &clocks);
+	if (clk->parent)
+		list_add_tail(&clk->childnode, &clk->parent->children);
 	mutex_unlock(&clocks_mutex);
 
 	/* If rate is already set, use it */
 	if (clk->rate)
 		return 0;
 
+	/* Else, see if there is a way to calculate it */
+	if (clk->recalc)
+		clk->rate = clk->recalc(clk);
+
 	/* Otherwise, default to parent rate */
-	if (clk->parent)
+	else if (clk->parent)
 		clk->rate = clk->parent->rate;
 
 	return 0;
@@ -146,6 +206,7 @@ void clk_unregister(struct clk *clk)
 
 	mutex_lock(&clocks_mutex);
 	list_del(&clk->node);
+	list_del(&clk->childnode);
 	mutex_unlock(&clocks_mutex);
 }
 EXPORT_SYMBOL(clk_unregister);
@@ -166,11 +227,11 @@ static int __init clk_disable_unused(voi
 			continue;
 
 		/* ignore if in Disabled or SwRstDisable states */
-		if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc))
+		if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
 			continue;
 
 		pr_info("Clocks: disable unused %s\n", ck->name);
-		davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0);
+		davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 0);
 	}
 	spin_unlock_irq(&clockfw_lock);
 
@@ -179,50 +240,62 @@ static int __init clk_disable_unused(voi
 late_initcall(clk_disable_unused);
 #endif
 
-static void clk_sysclk_recalc(struct clk *clk)
+static unsigned long clk_sysclk_recalc(struct clk *clk)
 {
 	u32 v, plldiv;
 	struct pll_data *pll;
+	unsigned long rate = clk->rate;
 
 	/* If this is the PLL base clock, no more calculations needed */
 	if (clk->pll_data)
-		return;
+		return rate;
 
 	if (WARN_ON(!clk->parent))
-		return;
+		return rate;
 
-	clk->rate = clk->parent->rate;
+	rate = clk->parent->rate;
 
 	/* Otherwise, the parent must be a PLL */
 	if (WARN_ON(!clk->parent->pll_data))
-		return;
+		return rate;
 
 	pll = clk->parent->pll_data;
 
 	/* If pre-PLL, source clock is before the multiplier and divider(s) */
 	if (clk->flags & PRE_PLL)
-		clk->rate = pll->input_rate;
+		rate = pll->input_rate;
 
 	if (!clk->div_reg)
-		return;
+		return rate;
 
 	v = __raw_readl(pll->base + clk->div_reg);
 	if (v & PLLDIV_EN) {
 		plldiv = (v & PLLDIV_RATIO_MASK) + 1;
 		if (plldiv)
-			clk->rate /= plldiv;
+			rate /= plldiv;
 	}
+
+	return rate;
 }
 
-static void __init clk_pll_init(struct clk *clk)
+static unsigned long clk_leafclk_recalc(struct clk *clk)
+{
+	if (WARN_ON(!clk->parent))
+		return clk->rate;
+
+	return clk->parent->rate;
+}
+
+static unsigned long clk_pllclk_recalc(struct clk *clk)
 {
 	u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
 	u8 bypass;
 	struct pll_data *pll = clk->pll_data;
+	unsigned long rate = clk->rate;
 
 	pll->base = IO_ADDRESS(pll->phys_base);
 	ctrl = __raw_readl(pll->base + PLLCTL);
-	clk->rate = pll->input_rate = clk->parent->rate;
+	rate = pll->input_rate = clk->parent->rate;
 
 	if (ctrl & PLLCTL_PLLEN) {
 		bypass = 0;
@@ -255,9 +328,9 @@ static void __init clk_pll_init(struct c
 	}
 
 	if (!bypass) {
-		clk->rate /= prediv;
-		clk->rate *= mult;
-		clk->rate /= postdiv;
+		rate /= prediv;
+		rate *= mult;
+		rate /= postdiv;
 	}
 
 	pr_debug("PLL%d: input = %lu MHz [ ",
@@ -270,9 +343,91 @@ static void __init clk_pll_init(struct c
 		pr_debug("* %d ", mult);
 	if (postdiv > 1)
 		pr_debug("/ %d ", postdiv);
-	pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
+	pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+	return rate;
 }
 
+/**
+ * davinci_set_pllrate - set the output rate of a given PLL.
+ *
+ * Note: Currently tested to work with OMAP-L138 only.
+ *
+ * @pll: pll whose rate needs to be changed.
+ * @prediv: The pre divider value. Passing 0 disables the pre-divider.
+ * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
+ * @postdiv: The post divider value. Passing 0 disables the post-divider.
+ */
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+					unsigned int mult, unsigned int postdiv)
+{
+	u32 ctrl;
+	unsigned int locktime;
+
+	if (pll->base == NULL)
+		return -EINVAL;
+
+	/*
+	 *  PLL lock time required per OMAP-L138 datasheet is
+	 * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
+	 * as 4 and OSCIN cycle as 25 MHz.
+	 */
+	if (prediv) {
+		locktime = ((2000 * prediv) / 100);
+		prediv = (prediv - 1) | PLLDIV_EN;
+	} else {
+		locktime = 20;
+	}
+	if (postdiv)
+		postdiv = (postdiv - 1) | PLLDIV_EN;
+	if (mult)
+		mult = mult - 1;
+
+	ctrl = __raw_readl(pll->base + PLLCTL);
+
+	/* Switch the PLL to bypass mode */
+	ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	/*
+	 * Wait for 4 OSCIN/CLKIN cycles to ensure that the PLLC has switched
+	 * to bypass mode. Delay of 1us ensures we are good for all > 4MHz
+	 * OSCIN/CLKIN inputs. Typically the input is ~25MHz.
+	 */
+	udelay(1);
+
+	/* Reset and enable PLL */
+	ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	if (pll->flags & PLL_HAS_PREDIV)
+		__raw_writel(prediv, pll->base + PREDIV);
+
+	__raw_writel(mult, pll->base + PLLM);
+
+	if (pll->flags & PLL_HAS_POSTDIV)
+		__raw_writel(postdiv, pll->base + POSTDIV);
+
+	/*
+	 * Wait for PLL to reset properly, OMAP-L138 datasheet says
+	 * 'min' time = 125ns
+	 */
+	udelay(1);
+
+	/* Bring PLL out of reset */
+	ctrl |= PLLCTL_PLLRST;
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	udelay(locktime);
+
+	/* Remove PLL from bypass mode */
+	ctrl |= PLLCTL_PLLEN;
+	__raw_writel(ctrl, pll->base + PLLCTL);
+
+	return 0;
+}
+EXPORT_SYMBOL(davinci_set_pllrate);
+
 int __init davinci_clk_init(struct davinci_clk *clocks)
   {
 	struct davinci_clk *c;
@@ -281,12 +436,23 @@ int __init davinci_clk_init(struct davin
 	for (c = clocks; c->lk.clk; c++) {
 		clk = c->lk.clk;
 
-		if (clk->pll_data)
-			clk_pll_init(clk);
+		if (!clk->recalc) {
 
-		/* Calculate rates for PLL-derived clocks */
-		else if (clk->flags & CLK_PLL)
-			clk_sysclk_recalc(clk);
+			/* Check if clock is a PLL */
+			if (clk->pll_data)
+				clk->recalc = clk_pllclk_recalc;
+
+			/* Else, if it is a PLL-derived clock */
+			else if (clk->flags & CLK_PLL)
+				clk->recalc = clk_sysclk_recalc;
+
+			/* Otherwise, it is a leaf clock (PSC clock) */
+			else if (clk->parent)
+				clk->recalc = clk_leafclk_recalc;
+		}
+
+		if (clk->recalc)
+			clk->rate = clk->recalc(clk);
 
 		if (clk->lpsc)
 			clk->flags |= CLK_PSC;
@@ -352,9 +518,8 @@ dump_clock(struct seq_file *s, unsigned
 	/* REVISIT show device associations too */
 
 	/* cost is now small, but not linear... */
-	list_for_each_entry(clk, &clocks, node) {
-		if (clk->parent == parent)
-			dump_clock(s, nest + NEST_DELTA, clk);
+	list_for_each_entry(clk, &parent->children, childnode) {
+		dump_clock(s, nest + NEST_DELTA, clk);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,10 @@
 /* PLL/Reset register offsets */
 #define PLLCTL          0x100
 #define PLLCTL_PLLEN    BIT(0)
+#define PLLCTL_PLLPWRDN	BIT(1)
+#define PLLCTL_PLLRST	BIT(3)
+#define PLLCTL_PLLDIS	BIT(4)
+#define PLLCTL_PLLENSRC	BIT(5)
 #define PLLCTL_CLKMODE  BIT(8)
 
 #define PLLM		0x110
@@ -65,15 +69,20 @@ struct clk {
 	const char		*name;
 	unsigned long		rate;
 	u8			usecount;
-	u8			flags;
 	u8			lpsc;
-	u8			psc_ctlr;
+	u8			gpsc;
+	u32			flags;
 	struct clk              *parent;
+	struct list_head	children; 	/* list of children */
+	struct list_head	childnode;	/* parent's child list node */
 	struct pll_data         *pll_data;
 	u32                     div_reg;
+	unsigned long (*recalc) (struct clk *);
+	int (*set_rate) (struct clk *clk, unsigned long rate);
+	int (*round_rate) (struct clk *clk, unsigned long rate);
 };
 
-/* Clock flags */
+/* Clock flags: SoC-specific flags start at BIT(16) */
 #define ALWAYS_ENABLED		BIT(1)
 #define CLK_PSC                 BIT(2)
 #define PSC_DSP                 BIT(3) /* PSC uses DSP domain, not ARM */
@@ -94,6 +103,8 @@ struct davinci_clk {
 	}
 
 int davinci_clk_init(struct davinci_clk *clocks);
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+				unsigned int mult, unsigned int postdiv);
 
 extern struct platform_device davinci_wdt_device;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/common.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/common.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,6 +86,8 @@ void __init davinci_common_init(struct d
 	dip = davinci_get_id(davinci_soc_info.jtag_id);
 	if (!dip) {
 		ret = -EINVAL;
+		pr_err("Unknown DaVinci JTAG ID 0x%x\n",
+						davinci_soc_info.jtag_id);
 		goto err;
 	}
 
@@ -104,5 +106,5 @@ void __init davinci_common_init(struct d
 	return;
 
 err:
-	pr_err("davinci_common_init: SoC Initialization failed\n");
+	panic("davinci_common_init: SoC Initialization failed\n");
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cp_intc.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cp_intc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cp_intc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cp_intc.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,9 +10,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 
@@ -84,12 +81,23 @@ static int cp_intc_set_irq_type(unsigned
 	return 0;
 }
 
+/*
+ * Faking this allows us to to work with suspend functions of
+ * generic drivers which call {enable|disable}_irq_wake for
+ * wake up interrupt sources (eg RTC on DA850).
+ */
+static int cp_intc_set_wake(unsigned int irq, unsigned int on)
+{
+	return 0;
+}
+
 static struct irq_chip cp_intc_irq_chip = {
 	.name		= "cp_intc",
 	.ack		= cp_intc_ack_irq,
 	.mask		= cp_intc_mask_irq,
 	.unmask		= cp_intc_unmask_irq,
 	.set_type	= cp_intc_set_irq_type,
+	.set_wake	= cp_intc_set_wake,
 };
 
 void __init cp_intc_init(void __iomem *base, unsigned short num_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cpufreq.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,226 @@
+/*
+ * CPU frequency scaling for DaVinci
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows:
+ *
+ *  Copyright (C) 2005 Nokia Corporation
+ *  Written by Tony Lindgren <tony@atomide.com>
+ *
+ *  Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@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/types.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/cpufreq.h>
+#include <mach/common.h>
+
+#include "clock.h"
+
+struct davinci_cpufreq {
+	struct device *dev;
+	struct clk *armclk;
+};
+static struct davinci_cpufreq cpufreq;
+
+static int davinci_verify_speed(struct cpufreq_policy *policy)
+{
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+	struct clk *armclk = cpufreq.armclk;
+
+	if (freq_table)
+		return cpufreq_frequency_table_verify(policy, freq_table);
+
+	if (policy->cpu)
+		return -EINVAL;
+
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+
+	policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
+	policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+						policy->cpuinfo.max_freq);
+	return 0;
+}
+
+static unsigned int davinci_getspeed(unsigned int cpu)
+{
+	if (cpu)
+		return 0;
+
+	return clk_get_rate(cpufreq.armclk) / 1000;
+}
+
+static int davinci_target(struct cpufreq_policy *policy,
+				unsigned int target_freq, unsigned int relation)
+{
+	int ret = 0;
+	unsigned int idx;
+	struct cpufreq_freqs freqs;
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct clk *armclk = cpufreq.armclk;
+
+	/*
+	 * Ensure desired rate is within allowed range.  Some govenors
+	 * (ondemand) will just pass target_freq=0 to get the minimum.
+	 */
+	if (target_freq < policy->cpuinfo.min_freq)
+		target_freq = policy->cpuinfo.min_freq;
+	if (target_freq > policy->cpuinfo.max_freq)
+		target_freq = policy->cpuinfo.max_freq;
+
+	freqs.old = davinci_getspeed(0);
+	freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
+	freqs.cpu = 0;
+
+	if (freqs.old == freqs.new)
+		return ret;
+
+	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
+			dev_driver_string(cpufreq.dev),
+			"transition: %u --> %u\n", freqs.old, freqs.new);
+
+	ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
+						freqs.new, relation, &idx);
+	if (ret)
+		return -EINVAL;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* if moving to higher frequency, up the voltage beforehand */
+	if (pdata->set_voltage && freqs.new > freqs.old)
+		pdata->set_voltage(idx);
+
+	ret = clk_set_rate(armclk, idx);
+
+	/* if moving to lower freq, lower the voltage after lowering freq */
+	if (pdata->set_voltage && freqs.new < freqs.old)
+		pdata->set_voltage(idx);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return ret;
+}
+
+static int __init davinci_cpu_init(struct cpufreq_policy *policy)
+{
+	int result = 0;
+	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+	struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	/* Finish platform specific initialization */
+	if (pdata->init) {
+		result = pdata->init();
+		if (result)
+			return result;
+	}
+
+	policy->cur = policy->min = policy->max = davinci_getspeed(0);
+
+	if (freq_table) {
+		result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+		if (!result)
+			cpufreq_frequency_table_get_attr(freq_table,
+							policy->cpu);
+	} else {
+		policy->cpuinfo.min_freq = policy->min;
+		policy->cpuinfo.max_freq = policy->max;
+	}
+
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+	policy->cur = davinci_getspeed(0);
+
+	/*
+	 * Time measurement across the target() function yields ~1500-1800us
+	 * time taken with no drivers on notification list.
+	 * Setting the latency to 2000 us to accomodate addition of drivers
+	 * to pre/post change notification list.
+	 */
+	policy->cpuinfo.transition_latency = 2000 * 1000;
+	return 0;
+}
+
+static int davinci_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static struct freq_attr *davinci_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver davinci_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= davinci_verify_speed,
+	.target		= davinci_target,
+	.get		= davinci_getspeed,
+	.init		= davinci_cpu_init,
+	.exit		= davinci_cpu_exit,
+	.name		= "davinci",
+	.attr		= davinci_cpufreq_attr,
+};
+
+static int __init davinci_cpufreq_probe(struct platform_device *pdev)
+{
+	struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return -EINVAL;
+	if (!pdata->freq_table)
+		return -EINVAL;
+
+	cpufreq.dev = &pdev->dev;
+
+	cpufreq.armclk = clk_get(NULL, "arm");
+	if (IS_ERR(cpufreq.armclk)) {
+		dev_err(cpufreq.dev, "Unable to get ARM clock\n");
+		return PTR_ERR(cpufreq.armclk);
+	}
+
+	return cpufreq_register_driver(&davinci_driver);
+}
+
+static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
+{
+	clk_put(cpufreq.armclk);
+
+	return cpufreq_unregister_driver(&davinci_driver);
+}
+
+static struct platform_driver davinci_cpufreq_driver = {
+	.driver = {
+		.name	 = "cpufreq-davinci",
+		.owner	 = THIS_MODULE,
+	},
+	.remove = __exit_p(davinci_cpufreq_remove),
+};
+
+static int __init davinci_cpufreq_init(void)
+{
+	return platform_driver_probe(&davinci_cpufreq_driver,
+							davinci_cpufreq_probe);
+}
+late_initcall(davinci_cpufreq_init);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cpuidle.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpuidle.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/cpuidle.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/cpuidle.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,197 @@
+/*
+ * CPU idle for DaVinci SoCs
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * Derived from Marvell Kirkwood CPU idle code
+ * (arch/arm/mach-kirkwood/cpuidle.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/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#include <mach/cpuidle.h>
+
+#define DAVINCI_CPUIDLE_MAX_STATES	2
+
+struct davinci_ops {
+	void (*enter) (u32 flags);
+	void (*exit) (u32 flags);
+	u32 flags;
+};
+
+/* fields in davinci_ops.flags */
+#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN	BIT(0)
+
+static struct cpuidle_driver davinci_idle_driver = {
+	.name	= "cpuidle-davinci",
+	.owner	= THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
+static void __iomem *ddr2_reg_base;
+
+#define DDR2_SDRCR_OFFSET	0xc
+#define DDR2_SRPD_BIT		BIT(23)
+#define DDR2_LPMODEN_BIT	BIT(31)
+
+static void davinci_save_ddr_power(int enter, bool pdown)
+{
+	u32 val;
+
+	val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET);
+
+	if (enter) {
+		if (pdown)
+			val |= DDR2_SRPD_BIT;
+		else
+			val &= ~DDR2_SRPD_BIT;
+		val |= DDR2_LPMODEN_BIT;
+	} else {
+		val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT);
+	}
+
+	__raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
+}
+
+static void davinci_c2state_enter(u32 flags)
+{
+	davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static void davinci_c2state_exit(u32 flags)
+{
+	davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
+	[1] = {
+		.enter	= davinci_c2state_enter,
+		.exit	= davinci_c2state_exit,
+	},
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int davinci_enter_idle(struct cpuidle_device *dev,
+						struct cpuidle_state *state)
+{
+	struct davinci_ops *ops = cpuidle_get_statedata(state);
+	struct timeval before, after;
+	int idle_time;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	if (ops && ops->enter)
+		ops->enter(ops->flags);
+	/* Wait for interrupt state */
+	cpu_do_idle();
+	if (ops && ops->exit)
+		ops->exit(ops->flags);
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+			(after.tv_usec - before.tv_usec);
+	return idle_time;
+}
+
+static int __init davinci_cpuidle_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct cpuidle_device *device;
+	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
+	struct resource *ddr2_regs;
+	resource_size_t len;
+
+	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "cannot get platform data\n");
+		return -ENOENT;
+	}
+
+	ddr2_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!ddr2_regs) {
+		dev_err(&pdev->dev, "cannot get DDR2 controller register base");
+		return -ENODEV;
+	}
+
+	len = resource_size(ddr2_regs);
+
+	ddr2_regs = request_mem_region(ddr2_regs->start, len, ddr2_regs->name);
+	if (!ddr2_regs)
+		return -EBUSY;
+
+	ddr2_reg_base = ioremap(ddr2_regs->start, len);
+	if (!ddr2_reg_base) {
+		ret = -ENOMEM;
+		goto ioremap_fail;
+	}
+
+	ret = cpuidle_register_driver(&davinci_idle_driver);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register driver\n");
+		goto driver_register_fail;
+	}
+
+	/* Wait for interrupt state */
+	device->states[0].enter = davinci_enter_idle;
+	device->states[0].exit_latency = 1;
+	device->states[0].target_residency = 10000;
+	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[0].name, "WFI");
+	strcpy(device->states[0].desc, "Wait for interrupt");
+
+	/* Wait for interrupt and DDR self refresh state */
+	device->states[1].enter = davinci_enter_idle;
+	device->states[1].exit_latency = 10;
+	device->states[1].target_residency = 10000;
+	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+	strcpy(device->states[1].name, "DDR SR");
+	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+	if (pdata->ddr2_pdown)
+		davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
+	cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
+
+	device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+
+	ret = cpuidle_register_device(device);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register device\n");
+		goto device_register_fail;
+	}
+
+	return 0;
+
+device_register_fail:
+	cpuidle_unregister_driver(&davinci_idle_driver);
+driver_register_fail:
+	iounmap(ddr2_reg_base);
+ioremap_fail:
+	release_mem_region(ddr2_regs->start, len);
+	return ret;
+}
+
+static struct platform_driver davinci_cpuidle_driver = {
+	.driver = {
+		.name	= "cpuidle-davinci",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init davinci_cpuidle_init(void)
+{
+	return platform_driver_probe(&davinci_cpuidle_driver,
+						davinci_cpuidle_probe);
+}
+device_initcall(davinci_cpuidle_init);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/da830.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da830.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/da830.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da830.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,22 +8,17 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/platform_device.h>
 
 #include <asm/mach/map.h>
 
-#include <mach/clock.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <mach/asp.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -193,14 +188,14 @@ static struct clk uart1_clk = {
 	.name		= "uart1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk uart2_clk = {
 	.name		= "uart2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk spi0_clk = {
@@ -213,98 +208,98 @@ static struct clk spi1_clk = {
 	.name		= "spi1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_SPI1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap0_clk = {
 	.name		= "ecap0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap1_clk = {
 	.name		= "ecap1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk ecap2_clk = {
 	.name		= "ecap2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_ECAP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm0_clk = {
 	.name		= "pwm0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm1_clk = {
 	.name		= "pwm1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk pwm2_clk = {
 	.name		= "pwm2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_PWM,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk eqep0_clk = {
 	.name		= "eqep0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk eqep1_clk = {
 	.name		= "eqep1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_EQEP,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk lcdc_clk = {
 	.name		= "lcdc",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_LCDC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp0_clk = {
 	.name		= "mcasp0",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_McASP0,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp1_clk = {
 	.name		= "mcasp1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_McASP1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp2_clk = {
 	.name		= "mcasp2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA830_LPSC1_McASP2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk usb20_clk = {
 	.name		= "usb20",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_USB20,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk aemif_clk = {
@@ -332,36 +327,36 @@ static struct clk emac_clk = {
 	.name		= "emac",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_CPGMAC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk gpio_clk = {
 	.name		= "gpio",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_GPIO,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk i2c1_clk = {
 	.name		= "i2c1",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_I2C,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk usb11_clk = {
 	.name		= "usb11",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_USB11,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk emif3_clk = {
 	.name		= "emif3",
 	.parent		= &pll0_sysclk5,
 	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk arm_clk = {
@@ -411,7 +406,7 @@ static struct davinci_clk da830_clks[] =
 	CLK(NULL,		"pwm2",		&pwm2_clk),
 	CLK("eqep.0",		NULL,		&eqep0_clk),
 	CLK("eqep.1",		NULL,		&eqep1_clk),
-	CLK("da830_lcdc",	NULL,		&lcdc_clk),
+	CLK("da8xx_lcdc.0",	NULL,		&lcdc_clk),
 	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
 	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
 	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
@@ -1143,7 +1138,21 @@ static struct davinci_id da830_ids[] = {
 		.part_no	= 0xb7df,
 		.manufacturer	= 0x017,	/* 0x02f >> 1 */
 		.cpu_id		= DAVINCI_CPU_ID_DA830,
-		.name		= "da830/omap l137",
+		.name		= "da830/omap-l137 rev1.0",
+	},
+	{
+		.variant	= 0x8,
+		.part_no	= 0xb7df,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DA830,
+		.name		= "da830/omap-l137 rev1.1",
+	},
+	{
+		.variant	= 0x9,
+		.part_no	= 0xb7df,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DA830,
+		.name		= "da830/omap-l137 rev2.0",
 	},
 };
 
@@ -1178,13 +1187,11 @@ static struct davinci_timer_info da830_t
 static struct davinci_soc_info davinci_soc_info_da830 = {
 	.io_desc		= da830_io_desc,
 	.io_desc_num		= ARRAY_SIZE(da830_io_desc),
-	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
 	.ids			= da830_ids,
 	.ids_num		= ARRAY_SIZE(da830_ids),
 	.cpu_clks		= da830_clks,
 	.psc_bases		= da830_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
-	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
 	.pinmux_pins		= da830_pins,
 	.pinmux_pins_num	= ARRAY_SIZE(da830_pins),
 	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
@@ -1201,5 +1208,13 @@ static struct davinci_soc_info davinci_s
 
 void __init da830_init(void)
 {
+	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+		return;
+
+	davinci_soc_info_da830.jtag_id_base =
+					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+
 	davinci_common_init(&davinci_soc_info_da830);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/da850.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da850.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/da850.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/da850.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,31 +11,41 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
 
 #include <asm/mach/map.h>
 
-#include <mach/clock.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
+#include <mach/cpufreq.h>
 
 #include "clock.h"
 #include "mux.h"
 
+/* SoC specific clock flags */
+#define DA850_CLK_ASYNC3	BIT(16)
+
 #define DA850_PLL1_BASE		0x01e1a000
 #define DA850_TIMER64P2_BASE	0x01f0c000
 #define DA850_TIMER64P3_BASE	0x01f0d000
 
 #define DA850_REF_FREQ		24000000
 
+#define CFGCHIP3_ASYNC3_CLKSRC	BIT(4)
+#define CFGCHIP0_PLL_MASTER_LOCK	BIT(4)
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate);
+static int da850_round_armrate(struct clk *clk, unsigned long rate);
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
+
 static struct pll_data pll0_data = {
 	.num		= 1,
 	.phys_base	= DA8XX_PLL0_BASE,
@@ -52,6 +62,7 @@ static struct clk pll0_clk = {
 	.parent		= &ref_clk,
 	.pll_data	= &pll0_data,
 	.flags		= CLK_PLL,
+	.set_rate	= da850_set_pll0rate,
 };
 
 static struct clk pll0_aux_clk = {
@@ -210,16 +221,16 @@ static struct clk tpcc1_clk = {
 	.name		= "tpcc1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA850_LPSC1_TPCC1,
+	.gpsc		= 1,
 	.flags		= CLK_PSC | ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk tptc2_clk = {
 	.name		= "tptc2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA850_LPSC1_TPTC2,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk uart0_clk = {
@@ -232,14 +243,16 @@ static struct clk uart1_clk = {
 	.name		= "uart1",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART1,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk uart2_clk = {
 	.name		= "uart2",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_UART2,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk aintc_clk = {
@@ -253,22 +266,22 @@ static struct clk gpio_clk = {
 	.name		= "gpio",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_GPIO,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk i2c1_clk = {
 	.name		= "i2c1",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_I2C,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk emif3_clk = {
 	.name		= "emif3",
 	.parent		= &pll0_sysclk5,
 	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.gpsc		= 1,
 	.flags		= ALWAYS_ENABLED,
-	.psc_ctlr	= 1,
 };
 
 static struct clk arm_clk = {
@@ -276,6 +289,8 @@ static struct clk arm_clk = {
 	.parent		= &pll0_sysclk6,
 	.lpsc		= DA8XX_LPSC0_ARM,
 	.flags		= ALWAYS_ENABLED,
+	.set_rate	= da850_set_armrate,
+	.round_rate	= da850_round_armrate,
 };
 
 static struct clk rmii_clk = {
@@ -287,21 +302,22 @@ static struct clk emac_clk = {
 	.name		= "emac",
 	.parent		= &pll0_sysclk4,
 	.lpsc		= DA8XX_LPSC1_CPGMAC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mcasp_clk = {
 	.name		= "mcasp",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_McASP0,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
+	.flags		= DA850_CLK_ASYNC3,
 };
 
 static struct clk lcdc_clk = {
 	.name		= "lcdc",
 	.parent		= &pll0_sysclk2,
 	.lpsc		= DA8XX_LPSC1_LCDC,
-	.psc_ctlr	= 1,
+	.gpsc		= 1,
 };
 
 static struct clk mmcsd_clk = {
@@ -404,6 +420,14 @@ static const struct mux_config da850_pin
 	MUX_CFG(DA850, MII_RXD_0,	3,	28,	15,	8,	false)
 	MUX_CFG(DA850, MDIO_CLK,	4,	0,	15,	8,	false)
 	MUX_CFG(DA850, MDIO_D,		4,	4,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXD_0,	14,	12,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXD_1,	14,	8,	15,	8,	false)
+	MUX_CFG(DA850, RMII_TXEN,	14,	16,	15,	8,	false)
+	MUX_CFG(DA850, RMII_CRS_DV,	15,	4,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXD_0,	14,	24,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXD_1,	14,	20,	15,	8,	false)
+	MUX_CFG(DA850, RMII_RXER,	14,	28,	15,	8,	false)
+	MUX_CFG(DA850, RMII_MHZ_50_CLK,	15,	0,	15,	0,	false)
 	/* McASP function */
 	MUX_CFG(DA850,	ACLKR,		0,	0,	15,	1,	false)
 	MUX_CFG(DA850,	ACLKX,		0,	4,	15,	1,	false)
@@ -506,8 +530,9 @@ static const struct mux_config da850_pin
 	MUX_CFG(DA850, EMA_WAIT_1,	6,	24,	15,	1,	false)
 	MUX_CFG(DA850, NEMA_CS_2,	7,	0,	15,	1,	false)
 	/* GPIO function */
+	MUX_CFG(DA850, GPIO2_6,		6,	4,	15,	8,	false)
+	MUX_CFG(DA850, GPIO2_8,		5,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO2_15,	5,	0,	15,	8,	false)
-	MUX_CFG(DA850, GPIO8_10,	18,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_0,		10,	28,	15,	8,	false)
 	MUX_CFG(DA850, GPIO4_1,		10,	24,	15,	8,	false)
 #endif
@@ -547,6 +572,14 @@ const short da850_cpgmac_pins[] __initda
 	-1
 };
 
+const short da850_rmii_pins[] __initdata = {
+	DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+	DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+	DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+	DA850_MDIO_D,
+	-1
+};
+
 const short da850_mcasp_pins[] __initdata = {
 	DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
 	DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
@@ -555,12 +588,11 @@ const short da850_mcasp_pins[] __initdat
 };
 
 const short da850_lcdcntl_pins[] __initdata = {
-	DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, DA850_LCD_D_4,
-	DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, DA850_LCD_D_8,
-	DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, DA850_LCD_D_12,
-	DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15, DA850_LCD_PCLK,
-	DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS, DA850_GPIO2_15,
-	DA850_GPIO8_10,
+	DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3,
+	DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7,
+	DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11,
+	DA850_LCD_D_12, DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15,
+	DA850_LCD_PCLK, DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS,
 	-1
 };
 
@@ -790,16 +822,221 @@ static struct davinci_timer_info da850_t
 	.clocksource_id	= T0_TOP,
 };
 
+static void da850_set_async3_src(int pllnum)
+{
+	struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
+	struct davinci_clk *c;
+	unsigned int v;
+	int ret;
+
+	for (c = da850_clks; c->lk.clk; c++) {
+		clk = c->lk.clk;
+		if (clk->flags & DA850_CLK_ASYNC3) {
+			ret = clk_set_parent(clk, newparent);
+			WARN(ret, "DA850: unable to re-parent clock %s",
+								clk->name);
+		}
+       }
+
+	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+	if (pllnum)
+		v |= CFGCHIP3_ASYNC3_CLKSRC;
+	else
+		v &= ~CFGCHIP3_ASYNC3_CLKSRC;
+	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Notes:
+ * According to the TRM, minimum PLLM results in maximum power savings.
+ * The OPP definitions below should keep the PLLM as low as possible.
+ *
+ * The output of the PLLM must be between 400 to 600 MHz.
+ * This rules out prediv of anything but divide-by-one for 24Mhz OSC input.
+ */
+struct da850_opp {
+	unsigned int	freq;	/* in KHz */
+	unsigned int	prediv;
+	unsigned int	mult;
+	unsigned int	postdiv;
+	unsigned int	cvdd_min; /* in uV */
+	unsigned int	cvdd_max; /* in uV */
+};
+
+static const struct da850_opp da850_opp_300 = {
+	.freq		= 300000,
+	.prediv		= 1,
+	.mult		= 25,
+	.postdiv	= 2,
+	.cvdd_min	= 1140000,
+	.cvdd_max	= 1320000,
+};
+
+static const struct da850_opp da850_opp_200 = {
+	.freq		= 200000,
+	.prediv		= 1,
+	.mult		= 25,
+	.postdiv	= 3,
+	.cvdd_min	= 1050000,
+	.cvdd_max	= 1160000,
+};
+
+static const struct da850_opp da850_opp_96 = {
+	.freq		= 96000,
+	.prediv		= 1,
+	.mult		= 20,
+	.postdiv	= 5,
+	.cvdd_min	= 950000,
+	.cvdd_max	= 1050000,
+};
+
+#define OPP(freq) 		\
+	{				\
+		.index = (unsigned int) &da850_opp_##freq,	\
+		.frequency = freq * 1000, \
+	}
+
+static struct cpufreq_frequency_table da850_freq_table[] = {
+	OPP(300),
+	OPP(200),
+	OPP(96),
+	{
+		.index		= 0,
+		.frequency	= CPUFREQ_TABLE_END,
+	},
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator *cvdd;
+
+static int da850_set_voltage(unsigned int index)
+{
+	struct da850_opp *opp;
+
+	if (!cvdd)
+		return -ENODEV;
+
+	opp = (struct da850_opp *) da850_freq_table[index].index;
+
+	return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
+}
+
+static int da850_regulator_init(void)
+{
+	cvdd = regulator_get(NULL, "cvdd");
+	if (WARN(IS_ERR(cvdd), "Unable to obtain voltage regulator for CVDD;"
+					" voltage scaling unsupported\n")) {
+		return PTR_ERR(cvdd);
+	}
+
+	return 0;
+}
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+	.freq_table = &da850_freq_table[0],
+#ifdef CONFIG_REGULATOR
+	.init = da850_regulator_init,
+	.set_voltage = da850_set_voltage,
+#endif
+};
+
+static struct platform_device da850_cpufreq_device = {
+	.name			= "cpufreq-davinci",
+	.dev = {
+		.platform_data	= &cpufreq_info,
+	},
+};
+
+int __init da850_register_cpufreq(void)
+{
+	return platform_device_register(&da850_cpufreq_device);
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+	int i, ret = 0, diff;
+	unsigned int best = (unsigned int) -1;
+
+	rate /= 1000; /* convert to kHz */
+
+	for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		diff = da850_freq_table[i].frequency - rate;
+		if (diff < 0)
+			diff = -diff;
+
+		if (diff < best) {
+			best = diff;
+			ret = da850_freq_table[i].frequency;
+		}
+	}
+
+	return ret * 1000;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long index)
+{
+	struct clk *pllclk = &pll0_clk;
+
+	return clk_set_rate(pllclk, index);
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long index)
+{
+	unsigned int prediv, mult, postdiv;
+	struct da850_opp *opp;
+	struct pll_data *pll = clk->pll_data;
+	unsigned int v;
+	int ret;
+
+	opp = (struct da850_opp *) da850_freq_table[index].index;
+	prediv = opp->prediv;
+	mult = opp->mult;
+	postdiv = opp->postdiv;
+
+	/* Unlock writing to PLL registers */
+	v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
+	v &= ~CFGCHIP0_PLL_MASTER_LOCK;
+	__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
+
+	ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
+	if (WARN_ON(ret))
+		return ret;
+
+	return 0;
+}
+#else
+int __init da850_register_cpufreq(void)
+{
+	return 0;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate)
+{
+	return -EINVAL;
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
+{
+	return -EINVAL;
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+	return clk->rate;
+}
+#endif
+
+
 static struct davinci_soc_info davinci_soc_info_da850 = {
 	.io_desc		= da850_io_desc,
 	.io_desc_num		= ARRAY_SIZE(da850_io_desc),
-	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
 	.ids			= da850_ids,
 	.ids_num		= ARRAY_SIZE(da850_ids),
 	.cpu_clks		= da850_clks,
 	.psc_bases		= da850_psc_bases,
 	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
-	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
 	.pinmux_pins		= da850_pins,
 	.pinmux_pins_num	= ARRAY_SIZE(da850_pins),
 	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
@@ -816,5 +1053,22 @@ static struct davinci_soc_info davinci_s
 
 void __init da850_init(void)
 {
+	da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
+	if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module"))
+		return;
+
+	davinci_soc_info_da850.jtag_id_base =
+					DA8XX_SYSCFG_VIRT(DA8XX_JTAG_ID_REG);
+	davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG_VIRT(0x120);
+
 	davinci_common_init(&davinci_soc_info_da850);
+
+	/*
+	 * Move the clock source of Async3 domain to PLL1 SYSCLK2.
+	 * This helps keeping the peripherals on this domain insulated
+	 * from CPU frequency changes caused by DVFS. The firmware sets
+	 * both PLL0 and PLL1 to the same frequency so, there should not
+	 * be any noticible change even in non-DVFS use cases.
+	 */
+	da850_set_async3_src(1);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,15 +9,11 @@
  * (at your option) any later version.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 
-#include <asm/mach/map.h>
-
 #include <mach/hardware.h>
 #include <mach/i2c.h>
 #include <mach/irqs.h>
@@ -177,7 +173,7 @@ void __init davinci_setup_mmc(int module
 			mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
 			mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
 							SZ_4K - 1;
-			mmcsd0_resources[2].start = IRQ_DM365_SDIOINT1;
+			mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
 		} else
 			break;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/devices-da8xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices-da8xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/devices-da8xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/devices-da8xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,8 +10,6 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
@@ -21,7 +19,7 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <video/da8xx-fb.h>
+#include <mach/cpuidle.h>
 
 #include "clock.h"
 
@@ -30,6 +28,7 @@
 #define DA8XX_TPTC1_BASE		0x01c08400
 #define DA8XX_WDOG_BASE			0x01c21000 /* DA8XX_TIMER64P1_BASE */
 #define DA8XX_I2C0_BASE			0x01c22000
+#define DA8XX_RTC_BASE			0x01C23000
 #define DA8XX_EMAC_CPPI_PORT_BASE	0x01e20000
 #define DA8XX_EMAC_CPGMACSS_BASE	0x01e22000
 #define DA8XX_EMAC_CPGMAC_BASE		0x01e23000
@@ -43,6 +42,8 @@
 #define DA8XX_MDIO_REG_OFFSET		0x4000
 #define DA8XX_EMAC_CTRL_RAM_SIZE	SZ_8K
 
+void __iomem *da8xx_syscfg_base;
+
 static struct plat_serial8250_port da8xx_serial_pdata[] = {
 	{
 		.mapbase	= DA8XX_UART0_BASE,
@@ -282,6 +283,11 @@ static struct platform_device da8xx_emac
 	.resource	= da8xx_emac_resources,
 };
 
+int __init da8xx_register_emac(void)
+{
+	return platform_device_register(&da8xx_emac_device);
+}
+
 static struct resource da830_mcasp1_resources[] = {
 	{
 		.name	= "mcasp1",
@@ -338,12 +344,7 @@ static struct platform_device da850_mcas
 	.resource	= da850_mcasp_resources,
 };
 
-int __init da8xx_register_emac(void)
-{
-	return platform_device_register(&da8xx_emac_device);
-}
-
-void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata)
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
 {
 	/* DA830/OMAP-L137 has 3 instances of McASP */
 	if (cpu_is_davinci_da830() && id == 1) {
@@ -379,10 +380,16 @@ static struct lcd_ctrl_config lcd_cfg =
 	.raster_order		= 0,
 };
 
-static struct da8xx_lcdc_platform_data da850_evm_lcdc_pdata = {
-	.manu_name = "sharp",
-	.controller_data = &lcd_cfg,
-	.type = "Sharp_LK043T1DG01",
+struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
+	.manu_name		= "sharp",
+	.controller_data	= &lcd_cfg,
+	.type			= "Sharp_LCD035Q3DG01",
+};
+
+struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = {
+	.manu_name		= "sharp",
+	.controller_data	= &lcd_cfg,
+	.type			= "Sharp_LK043T1DG01",
 };
 
 static struct resource da8xx_lcdc_resources[] = {
@@ -398,19 +405,17 @@ static struct resource da8xx_lcdc_resour
 	},
 };
 
-static struct platform_device da850_lcdc_device = {
+static struct platform_device da8xx_lcdc_device = {
 	.name		= "da8xx_lcdc",
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(da8xx_lcdc_resources),
 	.resource	= da8xx_lcdc_resources,
-	.dev = {
-		.platform_data = &da850_evm_lcdc_pdata,
-	}
 };
 
-int __init da8xx_register_lcdc(void)
+int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
 {
-	return platform_device_register(&da850_lcdc_device);
+	da8xx_lcdc_device.dev.platform_data = pdata;
+	return platform_device_register(&da8xx_lcdc_device);
 }
 
 static struct resource da8xx_mmcsd0_resources[] = {
@@ -448,3 +453,73 @@ int __init da8xx_register_mmcsd0(struct
 	da8xx_mmcsd0_device.dev.platform_data = config;
 	return platform_device_register(&da8xx_mmcsd0_device);
 }
+
+static struct resource da8xx_rtc_resources[] = {
+	{
+		.start		= DA8XX_RTC_BASE,
+		.end		= DA8XX_RTC_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{ /* timer irq */
+		.start		= IRQ_DA8XX_RTC,
+		.end		= IRQ_DA8XX_RTC,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{ /* alarm irq */
+		.start		= IRQ_DA8XX_RTC,
+		.end		= IRQ_DA8XX_RTC,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da8xx_rtc_device = {
+	.name           = "omap_rtc",
+	.id             = -1,
+	.num_resources	= ARRAY_SIZE(da8xx_rtc_resources),
+	.resource	= da8xx_rtc_resources,
+};
+
+int da8xx_register_rtc(void)
+{
+	int ret;
+
+	/* Unlock the rtc's registers */
+	__raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c));
+	__raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70));
+
+	ret = platform_device_register(&da8xx_rtc_device);
+	if (!ret)
+		/* Atleast on DA850, RTC is a wakeup source */
+		device_init_wakeup(&da8xx_rtc_device.dev, true);
+
+	return ret;
+}
+
+static struct resource da8xx_cpuidle_resources[] = {
+	{
+		.start		= DA8XX_DDR2_CTL_BASE,
+		.end		= DA8XX_DDR2_CTL_BASE + SZ_32K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+/* DA8XX devices support DDR2 power down */
+static struct davinci_cpuidle_config da8xx_cpuidle_pdata = {
+	.ddr2_pdown	= 1,
+};
+
+
+static struct platform_device da8xx_cpuidle_device = {
+	.name			= "cpuidle-davinci",
+	.num_resources		= ARRAY_SIZE(da8xx_cpuidle_resources),
+	.resource		= da8xx_cpuidle_resources,
+	.dev = {
+		.platform_data	= &da8xx_cpuidle_pdata,
+	},
+};
+
+int __init da8xx_register_cpuidle(void)
+{
+	return platform_device_register(&da8xx_cpuidle_device);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm355.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm355.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm355.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm355.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -21,7 +20,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm355.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm365.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm365.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm365.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm365.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,6 @@
  * 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/clk.h>
 #include <linux/serial_8250.h>
@@ -23,7 +22,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm365.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
@@ -32,6 +30,8 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -369,7 +369,7 @@ static struct clk timer3_clk = {
 
 static struct clk usb_clk = {
 	.name		= "usb",
-	.parent		= &pll2_sysclk1,
+	.parent		= &pll1_aux_clk,
 	.lpsc		= DAVINCI_LPSC_USB,
 };
 
@@ -456,7 +456,7 @@ static struct davinci_clk dm365_clks[] =
 	CLK(NULL, "usb", &usb_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("voice_codec", NULL, &voicecodec_clk),
-	CLK("soc-audio.0", NULL, &asp0_clk),
+	CLK("davinci-asp.0", NULL, &asp0_clk),
 	CLK(NULL, "rto", &rto_clk),
 	CLK(NULL, "mjcp", &mjcp_clk),
 	CLK(NULL, NULL, NULL),
@@ -531,7 +531,7 @@ MUX_CFG(DM365,  EMAC_CRS,	3,   2,     1,
 MUX_CFG(DM365,  EMAC_MDIO,	3,   1,     1,    1,     false)
 MUX_CFG(DM365,  EMAC_MDCLK,	3,   0,     1,    1,     false)
 
-MUX_CFG(DM365,	KEYPAD,		2,   0,     0x3f, 0x3f,  false)
+MUX_CFG(DM365,	KEYSCAN,	2,   0,     0x3f, 0x3f,  false)
 
 MUX_CFG(DM365,	PWM0,		1,   0,     3,    2,     false)
 MUX_CFG(DM365,	PWM0_G23,	3,   26,    3,    3,     false)
@@ -603,6 +603,9 @@ INT_CFG(DM365,  INT_IMX1_ENABLE,     24,
 INT_CFG(DM365,  INT_IMX1_DISABLE,    24,    1,    0,     false)
 INT_CFG(DM365,  INT_NSF_ENABLE,      25,    1,    1,     false)
 INT_CFG(DM365,  INT_NSF_DISABLE,     25,    1,    0,     false)
+
+EVT_CFG(DM365,	EVT2_ASP_TX,         0,     1,    0,     false)
+EVT_CFG(DM365,	EVT3_ASP_RX,         1,     1,    0,     false)
 #endif
 };
 
@@ -696,6 +699,7 @@ static u8 dm365_default_priorities[DAVIN
 	[IRQ_I2C]			= 3,
 	[IRQ_UARTINT0]			= 3,
 	[IRQ_UARTINT1]			= 3,
+	[IRQ_DM365_RTCINT]		= 3,
 	[IRQ_DM365_SPIINT0_0]		= 3,
 	[IRQ_DM365_SPIINT3_0]		= 3,
 	[IRQ_DM365_GPIO0]		= 3,
@@ -806,6 +810,50 @@ static struct platform_device dm365_edma
 	.resource		= edma_resources,
 };
 
+static struct resource dm365_asp_resources[] = {
+	{
+		.start	= DAVINCI_DM365_ASP0_BASE,
+		.end	= DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_TX,
+		.end	= DAVINCI_DMA_ASP0_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_RX,
+		.end	= DAVINCI_DMA_ASP0_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm365_asp_device = {
+	.name		= "davinci-asp",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm365_asp_resources),
+	.resource	= dm365_asp_resources,
+};
+
+static struct resource dm365_rtc_resources[] = {
+	{
+		.start = DM365_RTC_BASE,
+		.end = DM365_RTC_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_DM365_RTCINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm365_rtc_device = {
+	.name = "rtc_davinci",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(dm365_rtc_resources),
+	.resource = dm365_rtc_resources,
+};
+
 static struct map_desc dm365_io_desc[] = {
 	{
 		.virtual	= IO_VIRT,
@@ -822,6 +870,28 @@ static struct map_desc dm365_io_desc[] =
 	},
 };
 
+static struct resource dm365_ks_resources[] = {
+	{
+		/* registers */
+		.start = DM365_KEYSCAN_BASE,
+		.end = DM365_KEYSCAN_BASE + SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		/* interrupt */
+		.start = IRQ_DM365_KEYINT,
+		.end = IRQ_DM365_KEYINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm365_ks_device = {
+	.name		= "davinci_keyscan",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm365_ks_resources),
+	.resource	= dm365_ks_resources,
+};
+
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id dm365_ids[] = {
 	{
@@ -907,6 +977,32 @@ static struct davinci_soc_info davinci_s
 	.sram_len		= SZ_32K,
 };
 
+void __init dm365_init_asp(struct snd_platform_data *pdata)
+{
+	davinci_cfg_reg(DM365_MCBSP0_BDX);
+	davinci_cfg_reg(DM365_MCBSP0_X);
+	davinci_cfg_reg(DM365_MCBSP0_BFSX);
+	davinci_cfg_reg(DM365_MCBSP0_BDR);
+	davinci_cfg_reg(DM365_MCBSP0_R);
+	davinci_cfg_reg(DM365_MCBSP0_BFSR);
+	davinci_cfg_reg(DM365_EVT2_ASP_TX);
+	davinci_cfg_reg(DM365_EVT3_ASP_RX);
+	dm365_asp_device.dev.platform_data = pdata;
+	platform_device_register(&dm365_asp_device);
+}
+
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
+{
+	dm365_ks_device.dev.platform_data = pdata;
+	platform_device_register(&dm365_ks_device);
+}
+
+void __init dm365_init_rtc(void)
+{
+	davinci_cfg_reg(DM365_INT_PRTCSS);
+	platform_device_register(&dm365_rtc_device);
+}
+
 void __init dm365_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm365);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm644x.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm644x.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm644x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm644x.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -18,7 +17,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm644x.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
@@ -370,6 +368,11 @@ MUX_CFG(DM644X, ATAEN_DISABLE,	0,   17,
 MUX_CFG(DM644X, HPIEN_DISABLE,	0,   29,    1,	  0,	 true)
 
 MUX_CFG(DM644X, AEAW,		0,   0,     31,	  31,	 true)
+MUX_CFG(DM644X, AEAW0,		0,   0,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW1,		0,   1,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW2,		0,   2,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW3,		0,   3,     1,	  0,	 true)
+MUX_CFG(DM644X, AEAW4,		0,   4,     1,	  0,	 true)
 
 MUX_CFG(DM644X, MSTK,		1,   9,     1,	  0,	 false)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm646x.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm646x.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dm646x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dm646x.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,6 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
@@ -18,7 +17,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/dm646x.h>
-#include <mach/clock.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
@@ -789,7 +787,14 @@ static struct davinci_id dm646x_ids[] =
 		.part_no	= 0xb770,
 		.manufacturer	= 0x017,
 		.cpu_id		= DAVINCI_CPU_ID_DM6467,
-		.name		= "dm6467",
+		.name		= "dm6467_rev1.x",
+	},
+	{
+		.variant	= 0x1,
+		.part_no	= 0xb770,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DM6467,
+		.name		= "dm6467_rev3.x",
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dma.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,22 +18,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
 #include <linux/io.h>
 
-#include <mach/cputype.h>
-#include <mach/memory.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
 #include <mach/edma.h>
-#include <mach/mux.h>
-
 
 /* Offsets matching "struct edmacc_param" */
 #define PARM_OPT		0x00
@@ -509,43 +500,59 @@ static irqreturn_t dma_tc1err_handler(in
 	return IRQ_HANDLED;
 }
 
-static int reserve_contiguous_params(int ctlr, unsigned int id,
-				     unsigned int num_params,
-				     unsigned int start_param)
+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_params;
+	unsigned int count = num_slots;
+	int stop_slot = start_slot;
+	DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
 
-	for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) {
+	for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) {
 		j = EDMA_CHAN_SLOT(i);
-		if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse))
+		if (!test_and_set_bit(j, edma_info[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 if (id == EDMA_CONT_PARAMS_FIXED_EXACT)
-			break;
-		else
-			count = num_params;
+		} 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 RAMs, i.e we do find a set
-	 * of contiguous parameter RAMs but do not find the exact number
-	 * requested as we may reach the total number of parameter RAMs
+	 * 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 (count) {
-		for (j = i - num_params + count + 1; j <= i ; ++j)
+	if (i == edma_info[ctlr]->num_slots)
+		stop_slot = i;
+
+	for (j = start_slot; j < stop_slot; j++)
+		if (test_bit(j, tmp_inuse))
 			clear_bit(j, edma_info[ctlr]->edma_inuse);
 
+	if (count)
 		return -EBUSY;
-	}
 
-	for (j = i - num_params + 1; j <= i; ++j)
+	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_params + 1);
+	return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
 }
 
 /*-----------------------------------------------------------------------*/
@@ -743,26 +750,27 @@ 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 PARAM's that have been requested
+ * 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's
- * @param  - the start value of Parameter RAM that should be passed if id
+ * @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 RAMs from parameter RAM 64 in the case of DaVinci SOCs
- * and 32 in the case of Primus
+ * 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 RAMs from the "param" that is passed as an
+ * 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 "param"
+ * 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 RAMs in the remaining Parameter RAMs
+ * 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)
 {
@@ -771,12 +779,13 @@ int edma_alloc_cont_slots(unsigned ctlr,
 	 * the number of channels and lesser than the total number
 	 * of slots
 	 */
-	if (slot < edma_info[ctlr]->num_channels ||
-		slot >= edma_info[ctlr]->num_slots)
+	if ((id != EDMA_CONT_PARAMS_ANY) &&
+		(slot < edma_info[ctlr]->num_channels ||
+		slot >= edma_info[ctlr]->num_slots))
 		return -EINVAL;
 
 	/*
-	 * The number of parameter RAMs requested cannot be less than 1
+	 * 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
 	 */
@@ -786,11 +795,11 @@ int edma_alloc_cont_slots(unsigned ctlr,
 
 	switch (id) {
 	case EDMA_CONT_PARAMS_ANY:
-		return reserve_contiguous_params(ctlr, id, count,
+		return reserve_contiguous_slots(ctlr, id, count,
 						 edma_info[ctlr]->num_channels);
 	case EDMA_CONT_PARAMS_FIXED_EXACT:
 	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
-		return reserve_contiguous_params(ctlr, id, count, slot);
+		return reserve_contiguous_slots(ctlr, id, count, slot);
 	default:
 		return -EINVAL;
 	}
@@ -799,21 +808,21 @@ int edma_alloc_cont_slots(unsigned ctlr,
 EXPORT_SYMBOL(edma_alloc_cont_slots);
 
 /**
- * edma_free_cont_slots - deallocate DMA parameter RAMs
- * @slot: first parameter RAM of a set of parameter RAMs to be freed
- * @count: the number of contiguous parameter RAMs to be freed
+ * 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 RAMs that have been allocated using the edma_alloc_cont_slots
+ * 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;
+	unsigned ctlr, slot_to_free;
 	int i;
 
 	ctlr = EDMA_CTLR(slot);
@@ -826,11 +835,11 @@ int edma_free_cont_slots(unsigned slot,
 
 	for (i = slot; i < slot + count; ++i) {
 		ctlr = EDMA_CTLR(i);
-		slot = EDMA_CHAN_SLOT(i);
+		slot_to_free = EDMA_CHAN_SLOT(i);
 
-		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
 			&dummy_paramset, PARM_SIZE);
-		clear_bit(slot, edma_info[ctlr]->edma_inuse);
+		clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/gpio.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,23 +12,14 @@
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/bitops.h>
 
-#include <mach/cputype.h>
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
 #include <mach/gpio.h>
 
 #include <asm/mach/irq.h>
 
-
 static DEFINE_SPINLOCK(gpio_lock);
 
 struct davinci_gpio {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/asp.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/asp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/asp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/asp.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,9 @@
 #define DAVINCI_ASP0_BASE	0x01E02000
 #define DAVINCI_ASP1_BASE	0x01E04000
 
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE	0x01D02000
+
 /* Bases of dm646x register banks */
 #define	DAVINCI_DM646X_MCASP0_REG_BASE		0x01D01000
 #define DAVINCI_DM646X_MCASP1_REG_BASE		0x01D01800
@@ -51,6 +54,14 @@ struct snd_platform_data {
 	u32 rx_dma_offset;
 	enum dma_event_q eventq_no;	/* event queue number */
 	unsigned int codec_fmt;
+	/*
+	 * Allowing this is more efficient and eliminates left and right swaps
+	 * caused by underruns, but will swap the left and right channels
+	 * when compared to previous behavior.
+	 */
+	unsigned enable_channel_combine:1;
+	unsigned sram_size_playback;
+	unsigned sram_size_capture;
 
 	/* McASP specific fields */
 	int tdm_slots;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/common.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/common.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,12 +20,6 @@ extern void davinci_irq_init(void);
 extern void __iomem *davinci_intc_base;
 extern int davinci_intc_type;
 
-/* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
-
-/* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
-
 struct davinci_timer_instance {
 	void __iomem	*base;
 	u32		bottom_irq;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/cpufreq.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpufreq.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/cpufreq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpufreq.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ * TI DaVinci CPUFreq platform support.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. 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.
+ */
+#ifndef _MACH_DAVINCI_CPUFREQ_H
+#define _MACH_DAVINCI_CPUFREQ_H
+
+#include <linux/cpufreq.h>
+
+struct davinci_cpufreq_config {
+	struct cpufreq_frequency_table *freq_table;
+	int (*set_voltage) (unsigned int index);
+	int (*init) (void);
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/cpuidle.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,17 @@
+/*
+ * TI DaVinci cpuidle platform support
+ *
+ * 2009 (C) Texas Instruments, Inc. 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.
+ */
+#ifndef _MACH_DAVINCI_CPUIDLE_H
+#define _MACH_DAVINCI_CPUIDLE_H
+
+struct davinci_cpuidle_config {
+	u32 ddr2_pdown;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/da8xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,12 +11,17 @@
 #ifndef __ASM_ARCH_DAVINCI_DA8XX_H
 #define __ASM_ARCH_DAVINCI_DA8XX_H
 
+#include <video/da8xx-fb.h>
+
 #include <mach/serial.h>
 #include <mach/edma.h>
 #include <mach/i2c.h>
 #include <mach/emac.h>
 #include <mach/asp.h>
 #include <mach/mmc.h>
+#include <mach/usb.h>
+
+extern void __iomem *da8xx_syscfg_base;
 
 /*
  * The cp_intc interrupt controller for the da8xx isn't in the same
@@ -29,11 +34,15 @@
 #define DA8XX_CP_INTC_SIZE	SZ_8K
 #define DA8XX_CP_INTC_VIRT	(IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
 
-#define DA8XX_BOOT_CFG_BASE	(IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG_BASE	(IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG_VIRT(x)	(da8xx_syscfg_base + (x))
+#define DA8XX_JTAG_ID_REG	0x18
+#define DA8XX_CFGCHIP0_REG	0x17c
+#define DA8XX_CFGCHIP2_REG	0x184
+#define DA8XX_CFGCHIP3_REG	0x188
 
 #define DA8XX_PSC0_BASE		0x01c10000
 #define DA8XX_PLL0_BASE		0x01c11000
-#define DA8XX_JTAG_ID_REG	0x01c14018
 #define DA8XX_TIMER64P0_BASE	0x01c20000
 #define DA8XX_TIMER64P1_BASE	0x01c21000
 #define DA8XX_GPIO_BASE		0x01e26000
@@ -43,6 +52,7 @@
 #define DA8XX_AEMIF_CS2_BASE	0x60000000
 #define DA8XX_AEMIF_CS3_BASE	0x62000000
 #define DA8XX_AEMIF_CTL_BASE	0x68000000
+#define DA8XX_DDR2_CTL_BASE	0xb0000000
 
 #define PINMUX0			0x00
 #define PINMUX1			0x04
@@ -71,13 +81,20 @@ void __init da850_init(void);
 int da8xx_register_edma(void);
 int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
 int da8xx_register_watchdog(void);
+int da8xx_register_usb20(unsigned mA, unsigned potpgt);
+int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
 int da8xx_register_emac(void);
-int da8xx_register_lcdc(void);
+int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
 int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
-void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata);
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+int da8xx_register_rtc(void);
+int da850_register_cpufreq(void);
+int da8xx_register_cpuidle(void);
 
 extern struct platform_device da8xx_serial_device;
 extern struct emac_platform_data da8xx_emac_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
 
 extern const short da830_emif25_pins[];
 extern const short da830_spi0_pins[];
@@ -110,6 +127,7 @@ extern const short da850_uart2_pins[];
 extern const short da850_i2c0_pins[];
 extern const short da850_i2c1_pins[];
 extern const short da850_cpgmac_pins[];
+extern const short da850_rmii_pins[];
 extern const short da850_mcasp_pins[];
 extern const short da850_lcdcntl_pins[];
 extern const short da850_mmcsd0_pins[];
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/dm365.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm365.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/dm365.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm365.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,8 @@
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
 #include <mach/emac.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
 
 #define DM365_EMAC_BASE			(0x01D07000)
 #define DM365_EMAC_CNTRL_OFFSET		(0x0000)
@@ -24,6 +26,14 @@
 #define DM365_EMAC_MDIO_OFFSET		(0x4000)
 #define DM365_EMAC_CNTRL_RAM_SIZE	(0x2000)
 
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE		(0x01C69400)
+
+#define DM365_RTC_BASE			(0x01C69000)
+
 void __init dm365_init(void);
+void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void __init dm365_init_rtc(void);
 
 #endif /* __ASM_ARCH_DM365_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@
 #ifndef __ASM_ARCH_DM644X_H
 #define __ASM_ARCH_DM644X_H
 
-#include <linux/platform_device.h>
 #include <mach/hardware.h>
 #include <mach/emac.h>
 #include <mach/asp.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -217,6 +217,7 @@
 #define IRQ_DM365_SDIOINT0	23
 #define IRQ_DM365_MMCINT1	27
 #define IRQ_DM365_PWMINT3	28
+#define IRQ_DM365_RTCINT	29
 #define IRQ_DM365_SDIOINT1	31
 #define IRQ_DM365_SPIINT0_0	42
 #define IRQ_DM365_SPIINT3_0	43
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/keyscan.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/keyscan.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/keyscan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/keyscan.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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
+ */
+
+#ifndef DAVINCI_KEYSCAN_H
+#define DAVINCI_KEYSCAN_H
+
+#include <linux/io.h>
+
+enum davinci_matrix_types {
+	DAVINCI_KEYSCAN_MATRIX_4X4,
+	DAVINCI_KEYSCAN_MATRIX_5X3,
+};
+
+struct davinci_ks_platform_data {
+	int		(*device_enable)(struct device *dev);
+	unsigned short	*keymap;
+	u32		keymapsize;
+	u8		rep:1;
+	u8		strobe;
+	u8		interval;
+	u8		matrix_type;
+};
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/mux.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/mux.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,11 @@ enum davinci_dm644x_index {
 
 	/* AEAW functions */
 	DM644X_AEAW,
+	DM644X_AEAW0,
+	DM644X_AEAW1,
+	DM644X_AEAW2,
+	DM644X_AEAW3,
+	DM644X_AEAW4,
 
 	/* Memory Stick */
 	DM644X_MSTK,
@@ -237,8 +242,8 @@ enum davinci_dm365_index {
 	DM365_EMAC_MDIO,
 	DM365_EMAC_MDCLK,
 
-	/* Keypad */
-	DM365_KEYPAD,
+	/* Key Scan */
+	DM365_KEYSCAN,
 
 	/* PWM */
 	DM365_PWM0,
@@ -774,6 +779,14 @@ enum davinci_da850_index {
 	DA850_MII_RXD_0,
 	DA850_MDIO_CLK,
 	DA850_MDIO_D,
+	DA850_RMII_TXD_0,
+	DA850_RMII_TXD_1,
+	DA850_RMII_TXEN,
+	DA850_RMII_CRS_DV,
+	DA850_RMII_RXD_0,
+	DA850_RMII_RXD_1,
+	DA850_RMII_RXER,
+	DA850_RMII_MHZ_50_CLK,
 
 	/* McASP function */
 	DA850_ACLKR,
@@ -881,8 +894,9 @@ enum davinci_da850_index {
 	DA850_NEMA_CS_2,
 
 	/* GPIO function */
+	DA850_GPIO2_6,
+	DA850_GPIO2_8,
 	DA850_GPIO2_15,
-	DA850_GPIO8_10,
 	DA850_GPIO4_0,
 	DA850_GPIO4_1,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/nand.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,10 @@ struct davinci_nand_pdata {		/* platform
 
 	/* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
 	unsigned		options;
+
+	/* Main and mirror bbt descriptor overrides */
+	struct nand_bbt_descr	*bbt_td;
+	struct nand_bbt_descr	*bbt_md;
 };
 
 #endif	/* __ARCH_ARM_DAVINCI_NAND_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,9 +11,6 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <linux/io.h>
-#include <mach/hardware.h>
-
 extern void davinci_watchdog_reset(void);
 
 static inline void arch_idle(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/usb.h linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/usb.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/include/mach/usb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/include/mach/usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,59 @@
+/*
+ * USB related definitions
+ *
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.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 __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
+#define CFGCHIP2_PHYCLKGD	(1 << 17)
+#define CFGCHIP2_VBUSSENSE	(1 << 16)
+#define CFGCHIP2_RESET		(1 << 15)
+#define CFGCHIP2_OTGMODE	(3 << 13)
+#define CFGCHIP2_NO_OVERRIDE	(0 << 13)
+#define CFGCHIP2_FORCE_HOST	(1 << 13)
+#define CFGCHIP2_FORCE_DEVICE 	(2 << 13)
+#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
+#define CFGCHIP2_USB1PHYCLKMUX	(1 << 12)
+#define CFGCHIP2_USB2PHYCLKMUX	(1 << 11)
+#define CFGCHIP2_PHYPWRDN	(1 << 10)
+#define CFGCHIP2_OTGPWRDN	(1 << 9)
+#define CFGCHIP2_DATPOL 	(1 << 8)
+#define CFGCHIP2_USB1SUSPENDM	(1 << 7)
+#define CFGCHIP2_PHY_PLLON	(1 << 6)	/* override PLL suspend */
+#define CFGCHIP2_SESENDEN	(1 << 5)	/* Vsess_end comparator */
+#define CFGCHIP2_VBDTCTEN	(1 << 4)	/* Vbus comparator */
+#define CFGCHIP2_REFFREQ	(0xf << 0)
+#define CFGCHIP2_REFFREQ_12MHZ	(1 << 0)
+#define CFGCHIP2_REFFREQ_24MHZ	(2 << 0)
+#define CFGCHIP2_REFFREQ_48MHZ	(3 << 0)
+
+struct	da8xx_ohci_root_hub;
+
+typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
+				     unsigned port);
+
+/* Passed as the platform data to the OHCI driver */
+struct	da8xx_ohci_root_hub {
+	/* Switch the port power on/off */
+	int	(*set_power)(unsigned port, int on);
+	/* Read the port power status */
+	int	(*get_power)(unsigned port);
+	/* Read the port over-current indicator */
+	int	(*get_oci)(unsigned port);
+	/* Over-current indicator change notification (pass NULL to disable) */
+	int	(*ocic_notify)(da8xx_ocic_handler_t handler);
+
+	/* Time from power on to power good (in 2 ms units) */
+	u8	potpgt;
+};
+
+void davinci_setup_usb(unsigned mA, unsigned potpgt_ms);
+
+#endif	/* ifndef __ASM_ARCH_USB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -32,11 +32,13 @@ config ARCH_DAVINCI_DA830
         bool "DA830/OMAP-L137 based system"
 	select CP_INTC
 	select ARCH_DAVINCI_DA8XX
+	select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
 
 config ARCH_DAVINCI_DA850
 	bool "DA850/OMAP-L138 based system"
 	select CP_INTC
 	select ARCH_DAVINCI_DA8XX
+	select ARCH_HAS_CPUFREQ
 
 config ARCH_DAVINCI_DA8XX
 	bool
@@ -63,6 +65,13 @@ config MACH_SFFSDR
 	  Say Y here to select the Lyrtech Small Form Factor
 	  Software Defined Radio (SFFSDR) board.
 
+config MACH_NEUROS_OSD2
+	bool "Neuros OSD2 Open Television Set Top Box"
+	depends on ARCH_DAVINCI_DM644x
+	help
+	  Configure this option to specify the whether the board used
+	  for development is a Neuros OSD2 Open Set Top Box.
+
 config MACH_DAVINCI_DM355_EVM
 	bool "TI DM355 EVM"
 	default ARCH_DAVINCI_DM355
@@ -98,16 +107,66 @@ config MACH_DAVINCI_DA830_EVM
 	bool "TI DA830/OMAP-L137 Reference Platform"
 	default ARCH_DAVINCI_DA830
 	depends on ARCH_DAVINCI_DA830
+	select GPIO_PCF857X
 	help
 	  Say Y here to select the TI DA830/OMAP-L137 Evaluation Module.
 
+choice
+	prompt "Select DA830/OMAP-L137 UI board peripheral"
+	depends on MACH_DAVINCI_DA830_EVM
+	help
+	  The presence of UI card on the DA830/OMAP-L137 EVM is detected
+	  automatically based on successful probe of the I2C based GPIO
+	  expander on that board. This option selected in this menu has
+	  an effect only in case of a successful UI card detection.
+
+config DA830_UI_LCD
+	bool "LCD"
+	help
+	  Say Y here to use the LCD as a framebuffer or simple character
+	  display.
+
+config DA830_UI_NAND
+	bool "NAND flash"
+	help
+	  Say Y here to use the NAND flash.  Do not forget to setup
+	  the switch correctly.
+endchoice
+
 config MACH_DAVINCI_DA850_EVM
 	bool "TI DA850/OMAP-L138 Reference Platform"
 	default ARCH_DAVINCI_DA850
 	depends on ARCH_DAVINCI_DA850
+	select GPIO_PCA953X
 	help
 	  Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
 
+choice
+	prompt "Select peripherals connected to expander on UI board"
+	depends on MACH_DAVINCI_DA850_EVM
+	help
+	  The presence of User Interface (UI) card on the DA850/OMAP-L138
+	  EVM is detected automatically based on successful probe of the I2C
+	  based GPIO expander on that card. This option selected in this
+	  menu has an effect only in case of a successful UI card detection.
+
+config DA850_UI_NONE
+	bool "No peripheral is enabled"
+	help
+	  Say Y if you do not want to enable any of the peripherals connected
+	  to TCA6416 expander on DA850/OMAP-L138 EVM UI card
+
+config DA850_UI_RMII
+	bool "RMII Ethernet PHY"
+	help
+	  Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM.
+	  This PHY is found on the UI daughter card that is supplied with
+	  the EVM.
+	  NOTE: Please take care while choosing this option, MII PHY will
+	  not be functional if RMII mode is selected.
+
+endchoice
+
 config DAVINCI_MUX
 	bool "DAVINCI multiplexing support"
 	depends on ARCH_DAVINCI
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -23,9 +23,14 @@ obj-$(CONFIG_CP_INTC)			+= cp_intc.o
 # Board specific
 obj-$(CONFIG_MACH_DAVINCI_EVM)  	+= board-dm644x-evm.o
 obj-$(CONFIG_MACH_SFFSDR)		+= board-sffsdr.o
+obj-$(CONFIG_MACH_NEUROS_OSD2)		+= board-neuros-osd2.o
 obj-$(CONFIG_MACH_DAVINCI_DM355_EVM)	+= board-dm355-evm.o
 obj-$(CONFIG_MACH_DM355_LEOPARD)	+= board-dm355-leopard.o
 obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM)	+= board-dm646x-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DM365_EVM)	+= board-dm365-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA830_EVM)	+= board-da830-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+= board-da850-evm.o
+
+# Power Management
+obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/mux.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/mux.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/mux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/mux.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,6 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 
-#include <mach/hardware.h>
 #include <mach/mux.h>
 #include <mach/common.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/psc.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/psc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/psc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/psc.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,14 +19,11 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/cputype.h>
-#include <mach/hardware.h>
 #include <mach/psc.h>
-#include <mach/mux.h>
 
 /* PSC register offsets */
 #define EPCPR		0x070
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/serial.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/serial.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/serial.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/serial.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,14 +28,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <asm/irq.h>
-#include <mach/hardware.h>
 #include <mach/serial.h>
-#include <mach/irqs.h>
 #include <mach/cputype.h>
-#include <mach/common.h>
-
-#include "clock.h"
 
 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
 					   int offset)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/sram.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/sram.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/sram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/sram.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,15 +9,12 @@
  * (at your option) any later version.
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/genalloc.h>
 
 #include <mach/common.h>
-#include <mach/memory.h>
 #include <mach/sram.h>
 
-
 static struct gen_pool *sram_pool;
 
 void *sram_alloc(size_t len, dma_addr_t *dma)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/time.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/time.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,20 +14,14 @@
 #include <linux/interrupt.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
-#include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/device.h>
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <asm/errno.h>
-#include <mach/io.h>
 #include <mach/cputype.h>
 #include <mach/time.h>
 #include "clock.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/usb.c linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/usb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-davinci/usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-davinci/usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,21 +1,21 @@
 /*
  * USB
  */
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <linux/usb/musb.h>
-#include <linux/usb/otg.h>
 
 #include <mach/common.h>
-#include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
+#include <mach/usb.h>
 
-#define DAVINCI_USB_OTG_BASE 0x01C64000
+#define DAVINCI_USB_OTG_BASE	0x01c64000
+
+#define DA8XX_USB0_BASE 	0x01e00000
+#define DA8XX_USB1_BASE 	0x01e25000
 
 #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 static struct musb_hdrc_eps_bits musb_eps[] = {
@@ -85,10 +85,10 @@ static struct platform_device usb_dev =
 	.num_resources  = ARRAY_SIZE(usb_resources),
 };
 
-void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
 {
-	usb_data.power = mA / 2;
-	usb_data.potpgt = potpgt_msec / 2;
+	usb_data.power = mA > 510 ? 255 : mA / 2;
+	usb_data.potpgt = (potpgt_ms + 1) / 2;
 
 	if (cpu_is_davinci_dm646x()) {
 		/* Override the defaults as DM6467 uses different IRQs. */
@@ -100,11 +100,77 @@ void __init setup_usb(unsigned mA, unsig
 	platform_device_register(&usb_dev);
 }
 
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb20_resources[] = {
+	{
+		.start		= DA8XX_USB0_BASE,
+		.end		= DA8XX_USB0_BASE + SZ_64K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_DA8XX_USB_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+	usb_data.clock  = "usb20";
+	usb_data.power	= mA > 510 ? 255 : mA / 2;
+	usb_data.potpgt = (potpgt + 1) / 2;
+
+	usb_dev.resource = da8xx_usb20_resources;
+	usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources);
+
+	return platform_device_register(&usb_dev);
+}
+#endif	/* CONFIG_DAVINCI_DA8XX */
+
 #else
 
-void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
 {
 }
 
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+	return 0;
+}
+#endif
+
 #endif  /* CONFIG_USB_MUSB_HDRC */
 
+#ifdef	CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb11_resources[] = {
+	[0] = {
+		.start	= DA8XX_USB1_BASE,
+		.end	= DA8XX_USB1_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_DA8XX_IRQN,
+		.end	= IRQ_DA8XX_IRQN,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device da8xx_usb11_device = {
+	.name		= "ohci",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= &da8xx_usb11_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(da8xx_usb11_resources),
+	.resource	= da8xx_usb11_resources,
+};
+
+int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
+{
+	da8xx_usb11_device.dev.platform_data = pdata;
+	return platform_device_register(&da8xx_usb11_device);
+}
+#endif	/* CONFIG_DAVINCI_DA8XX */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/addr-map.c linux-libre-2.6.33-gnu1/arch/arm/mach-dove/addr-map.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/addr-map.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/addr-map.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mach-dove/addr-map.c
+ *
+ * Address map functions for Marvell Dove 88AP510 SoC
+ *
+ * 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/mbus.h>
+#include <linux/io.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR		0x0
+#define TARGET_BOOTROM		0x1
+#define TARGET_CESA		0x3
+#define TARGET_PCIE0		0x4
+#define TARGET_PCIE1		0x8
+#define TARGET_SCRATCHPAD	0xd
+
+#define ATTR_CESA		0x01
+#define ATTR_BOOTROM		0xfd
+#define ATTR_DEV_SPI0_ROM	0xfe
+#define ATTR_DEV_SPI1_ROM	0xfb
+#define ATTR_PCIE_IO		0xe0
+#define ATTR_PCIE_MEM		0xe8
+#define ATTR_SCRATCHPAD		0x0
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_CTRL(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
+#define WIN_BASE(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
+#define WIN_REMAP_LO(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
+#define WIN_REMAP_HI(n)	(BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
+
+struct mbus_dram_target_info dove_mbus_dram_info;
+
+static inline void __iomem *ddr_map_sc(int i)
+{
+	return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
+}
+
+static int cpu_win_can_remap(int win)
+{
+	if (win < 4)
+		return 1;
+
+	return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+				 u8 target, u8 attr, int remap)
+{
+	u32 ctrl;
+
+	base &= 0xffff0000;
+	ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+	writel(base, WIN_BASE(win));
+	writel(ctrl, WIN_CTRL(win));
+	if (cpu_win_can_remap(win)) {
+		if (remap < 0)
+			remap = base;
+		writel(remap & 0xffff0000, WIN_REMAP_LO(win));
+		writel(0, WIN_REMAP_HI(win));
+	}
+}
+
+void __init dove_setup_cpu_mbus(void)
+{
+	int i;
+	int cs;
+
+	/*
+	 * First, disable and clear windows.
+	 */
+	for (i = 0; i < 8; i++) {
+		writel(0, WIN_BASE(i));
+		writel(0, WIN_CTRL(i));
+		if (cpu_win_can_remap(i)) {
+			writel(0, WIN_REMAP_LO(i));
+			writel(0, WIN_REMAP_HI(i));
+		}
+	}
+
+	/*
+	 * Setup windows for PCIe IO+MEM space.
+	 */
+	setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
+		      TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE);
+	setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
+		      TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
+	setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
+		      TARGET_PCIE0, ATTR_PCIE_MEM, -1);
+	setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
+		      TARGET_PCIE1, ATTR_PCIE_MEM, -1);
+
+	/*
+	 * Setup window for CESA engine.
+	 */
+	setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
+		      TARGET_CESA, ATTR_CESA, -1);
+
+	/*
+	 * Setup the Window to the BootROM for Standby and Sleep Resume
+	 */
+	setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
+		      TARGET_BOOTROM, ATTR_BOOTROM, -1);
+
+	/*
+	 * Setup the Window to the PMU Scratch Pad space
+	 */
+	setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
+		      TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
+
+	/*
+	 * Setup MBUS dram target info.
+	 */
+	dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+	for (i = 0, cs = 0; i < 2; i++) {
+		u32 map = readl(ddr_map_sc(i));
+
+		/*
+		 * Chip select enabled?
+		 */
+		if (map & 1) {
+			struct mbus_dram_window *w;
+
+			w = &dove_mbus_dram_info.cs[cs++];
+			w->cs_index = i;
+			w->mbus_attr = 0; /* CS address decoding done inside */
+					  /* the DDR controller, no need to  */
+					  /* provide attributes */
+			w->base = map & 0xff800000;
+			w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+		}
+	}
+	dove_mbus_dram_info.num_cs = cs;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/common.c linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,781 @@
+/*
+ * arch/arm/mach-dove/common.c
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * 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/delay.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/mbus.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/gpio.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/timex.h>
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/pci.h>
+#include <mach/dove.h>
+#include <mach/bridge-regs.h>
+#include <asm/mach/arch.h>
+#include <linux/irq.h>
+#include <plat/mv_xor.h>
+#include <plat/ehci-orion.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc dove_io_desc[] __initdata = {
+	{
+		.virtual	= DOVE_SB_REGS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
+		.length		= DOVE_SB_REGS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_NB_REGS_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
+		.length		= DOVE_NB_REGS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_PCIE0_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
+		.length		= DOVE_PCIE0_IO_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= DOVE_PCIE1_IO_VIRT_BASE,
+		.pfn		= __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
+		.length		= DOVE_PCIE1_IO_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init dove_map_io(void)
+{
+	iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
+}
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+static struct orion_ehci_data dove_ehci_data = {
+	.dram		= &dove_mbus_dram_info,
+	.phy_version	= EHCI_PHY_NA,
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+static struct resource dove_ehci0_resources[] = {
+	{
+		.start	= DOVE_USB0_PHYS_BASE,
+		.end	= DOVE_USB0_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_USB0,
+		.end	= IRQ_DOVE_USB0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ehci0 = {
+	.name		= "orion-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &dove_ehci_data,
+	},
+	.resource	= dove_ehci0_resources,
+	.num_resources	= ARRAY_SIZE(dove_ehci0_resources),
+};
+
+void __init dove_ehci0_init(void)
+{
+	platform_device_register(&dove_ehci0);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource dove_ehci1_resources[] = {
+	{
+		.start	= DOVE_USB1_PHYS_BASE,
+		.end	= DOVE_USB1_PHYS_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_USB1,
+		.end	= IRQ_DOVE_USB1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ehci1 = {
+	.name		= "orion-ehci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &dove_ehci_data,
+	},
+	.resource	= dove_ehci1_resources,
+	.num_resources	= ARRAY_SIZE(dove_ehci1_resources),
+};
+
+void __init dove_ehci1_init(void)
+{
+	platform_device_register(&dove_ehci1);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data dove_ge00_shared_data = {
+	.t_clk		= 0,
+	.dram		= &dove_mbus_dram_info,
+};
+
+static struct resource dove_ge00_shared_resources[] = {
+	{
+		.name	= "ge00 base",
+		.start	= DOVE_GE00_PHYS_BASE + 0x2000,
+		.end	= DOVE_GE00_PHYS_BASE + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_ge00_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &dove_ge00_shared_data,
+	},
+	.num_resources	= 1,
+	.resource	= dove_ge00_shared_resources,
+};
+
+static struct resource dove_ge00_resources[] = {
+	{
+		.name	= "ge00 irq",
+		.start	= IRQ_DOVE_GE00_SUM,
+		.end	= IRQ_DOVE_GE00_SUM,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_ge00 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= dove_ge00_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+	eth_data->shared = &dove_ge00_shared;
+	dove_ge00.dev.platform_data = eth_data;
+
+	platform_device_register(&dove_ge00_shared);
+	platform_device_register(&dove_ge00);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static struct resource dove_rtc_resource[] = {
+	{
+		.start	= DOVE_RTC_PHYS_BASE,
+		.end	= DOVE_RTC_PHYS_BASE + 32 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_RTC,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+void __init dove_rtc_init(void)
+{
+	platform_device_register_simple("rtc-mv", -1, dove_rtc_resource, 2);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct resource dove_sata_resources[] = {
+	{
+		.name	= "sata base",
+		.start	= DOVE_SATA_PHYS_BASE,
+		.end	= DOVE_SATA_PHYS_BASE + 0x5000 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "sata irq",
+		.start	= IRQ_DOVE_SATA,
+		.end	= IRQ_DOVE_SATA,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_sata = {
+	.name		= "sata_mv",
+	.id		= 0,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(dove_sata_resources),
+	.resource	= dove_sata_resources,
+};
+
+void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
+{
+	sata_data->dram = &dove_mbus_dram_info;
+	dove_sata.dev.platform_data = sata_data;
+	platform_device_register(&dove_sata);
+}
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart0_data[] = {
+	{
+		.mapbase	= DOVE_UART0_PHYS_BASE,
+		.membase	= (char *)DOVE_UART0_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_0,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart0_resources[] = {
+	{
+		.start		= DOVE_UART0_PHYS_BASE,
+		.end		= DOVE_UART0_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_0,
+		.end		= IRQ_DOVE_UART_0,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart0 = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= dove_uart0_data,
+	},
+	.resource		= dove_uart0_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart0_resources),
+};
+
+void __init dove_uart0_init(void)
+{
+	platform_device_register(&dove_uart0);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart1_data[] = {
+	{
+		.mapbase	= DOVE_UART1_PHYS_BASE,
+		.membase	= (char *)DOVE_UART1_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_1,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart1_resources[] = {
+	{
+		.start		= DOVE_UART1_PHYS_BASE,
+		.end		= DOVE_UART1_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_1,
+		.end		= IRQ_DOVE_UART_1,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart1 = {
+	.name			= "serial8250",
+	.id			= 1,
+	.dev			= {
+		.platform_data	= dove_uart1_data,
+	},
+	.resource		= dove_uart1_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart1_resources),
+};
+
+void __init dove_uart1_init(void)
+{
+	platform_device_register(&dove_uart1);
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart2_data[] = {
+	{
+		.mapbase	= DOVE_UART2_PHYS_BASE,
+		.membase	= (char *)DOVE_UART2_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_2,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart2_resources[] = {
+	{
+		.start		= DOVE_UART2_PHYS_BASE,
+		.end		= DOVE_UART2_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_2,
+		.end		= IRQ_DOVE_UART_2,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart2 = {
+	.name			= "serial8250",
+	.id			= 2,
+	.dev			= {
+		.platform_data	= dove_uart2_data,
+	},
+	.resource		= dove_uart2_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart2_resources),
+};
+
+void __init dove_uart2_init(void)
+{
+	platform_device_register(&dove_uart2);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+static struct plat_serial8250_port dove_uart3_data[] = {
+	{
+		.mapbase	= DOVE_UART3_PHYS_BASE,
+		.membase	= (char *)DOVE_UART3_VIRT_BASE,
+		.irq		= IRQ_DOVE_UART_3,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 0,
+	}, {
+	},
+};
+
+static struct resource dove_uart3_resources[] = {
+	{
+		.start		= DOVE_UART3_PHYS_BASE,
+		.end		= DOVE_UART3_PHYS_BASE + SZ_256 - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IRQ_DOVE_UART_3,
+		.end		= IRQ_DOVE_UART_3,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_uart3 = {
+	.name			= "serial8250",
+	.id			= 3,
+	.dev			= {
+		.platform_data	= dove_uart3_data,
+	},
+	.resource		= dove_uart3_resources,
+	.num_resources		= ARRAY_SIZE(dove_uart3_resources),
+};
+
+void __init dove_uart3_init(void)
+{
+	platform_device_register(&dove_uart3);
+}
+
+/*****************************************************************************
+ * SPI0
+ ****************************************************************************/
+static struct orion_spi_info dove_spi0_data = {
+	.tclk		= 0,
+};
+
+static struct resource dove_spi0_resources[] = {
+	{
+		.start	= DOVE_SPI0_PHYS_BASE,
+		.end	= DOVE_SPI0_PHYS_BASE + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_SPI0,
+		.end	= IRQ_DOVE_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_spi0 = {
+	.name		= "orion_spi",
+	.id		= 0,
+	.resource	= dove_spi0_resources,
+	.dev		= {
+		.platform_data	= &dove_spi0_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_spi0_resources),
+};
+
+void __init dove_spi0_init(void)
+{
+	platform_device_register(&dove_spi0);
+}
+
+/*****************************************************************************
+ * SPI1
+ ****************************************************************************/
+static struct orion_spi_info dove_spi1_data = {
+	.tclk		= 0,
+};
+
+static struct resource dove_spi1_resources[] = {
+	{
+		.start	= DOVE_SPI1_PHYS_BASE,
+		.end	= DOVE_SPI1_PHYS_BASE + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_DOVE_SPI1,
+		.end	= IRQ_DOVE_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_spi1 = {
+	.name		= "orion_spi",
+	.id		= 1,
+	.resource	= dove_spi1_resources,
+	.dev		= {
+		.platform_data	= &dove_spi1_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_spi1_resources),
+};
+
+void __init dove_spi1_init(void)
+{
+	platform_device_register(&dove_spi1);
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata dove_i2c_data = {
+	.freq_m		= 10, /* assumes 166 MHz TCLK gets 94.3kHz */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource dove_i2c_resources[] = {
+	{
+		.name	= "i2c base",
+		.start	= DOVE_I2C_PHYS_BASE,
+		.end	= DOVE_I2C_PHYS_BASE + 0x20 - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "i2c irq",
+		.start	= IRQ_DOVE_I2C,
+		.end	= IRQ_DOVE_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dove_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dove_i2c_resources),
+	.resource	= dove_i2c_resources,
+	.dev		= {
+		.platform_data = &dove_i2c_data,
+	},
+};
+
+void __init dove_i2c_init(void)
+{
+	platform_device_register(&dove_i2c);
+}
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+static int get_tclk(void)
+{
+	/* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
+	return 166666667;
+}
+
+static void dove_timer_init(void)
+{
+	orion_time_init(IRQ_DOVE_BRIDGE, get_tclk());
+}
+
+struct sys_timer dove_timer = {
+	.init = dove_timer_init,
+};
+
+/*****************************************************************************
+ * XOR
+ ****************************************************************************/
+static struct mv_xor_platform_shared_data dove_xor_shared_data = {
+	.dram		= &dove_mbus_dram_info,
+};
+
+/*****************************************************************************
+ * XOR 0
+ ****************************************************************************/
+static u64 dove_xor0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource dove_xor0_shared_resources[] = {
+	{
+		.name	= "xor 0 low",
+		.start	= DOVE_XOR0_PHYS_BASE,
+		.end	= DOVE_XOR0_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 0 high",
+		.start	= DOVE_XOR0_HIGH_PHYS_BASE,
+		.end	= DOVE_XOR0_HIGH_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_xor0_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data = &dove_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_xor0_shared_resources),
+	.resource	= dove_xor0_shared_resources,
+};
+
+static struct resource dove_xor00_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_00,
+		.end	= IRQ_DOVE_XOR_00,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor00_data = {
+	.shared		= &dove_xor0_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor00_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dove_xor00_resources),
+	.resource	= dove_xor00_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor00_data,
+	},
+};
+
+static struct resource dove_xor01_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_01,
+		.end	= IRQ_DOVE_XOR_01,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor01_data = {
+	.shared		= &dove_xor0_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor01_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(dove_xor01_resources),
+	.resource	= dove_xor01_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor01_data,
+	},
+};
+
+void __init dove_xor0_init(void)
+{
+	platform_device_register(&dove_xor0_shared);
+
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, dove_xor00_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor00_data.cap_mask);
+	platform_device_register(&dove_xor00_channel);
+
+	dma_cap_set(DMA_MEMCPY, dove_xor01_data.cap_mask);
+	dma_cap_set(DMA_MEMSET, dove_xor01_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor01_data.cap_mask);
+	platform_device_register(&dove_xor01_channel);
+}
+
+/*****************************************************************************
+ * XOR 1
+ ****************************************************************************/
+static u64 dove_xor1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource dove_xor1_shared_resources[] = {
+	{
+		.name	= "xor 0 low",
+		.start	= DOVE_XOR1_PHYS_BASE,
+		.end	= DOVE_XOR1_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 0 high",
+		.start	= DOVE_XOR1_HIGH_PHYS_BASE,
+		.end	= DOVE_XOR1_HIGH_PHYS_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dove_xor1_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data = &dove_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(dove_xor1_shared_resources),
+	.resource	= dove_xor1_shared_resources,
+};
+
+static struct resource dove_xor10_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_10,
+		.end	= IRQ_DOVE_XOR_10,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor10_data = {
+	.shared		= &dove_xor1_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor10_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(dove_xor10_resources),
+	.resource	= dove_xor10_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor10_data,
+	},
+};
+
+static struct resource dove_xor11_resources[] = {
+	[0] = {
+		.start	= IRQ_DOVE_XOR_11,
+		.end	= IRQ_DOVE_XOR_11,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data dove_xor11_data = {
+	.shared		= &dove_xor1_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device dove_xor11_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(dove_xor11_resources),
+	.resource	= dove_xor11_resources,
+	.dev		= {
+		.dma_mask		= &dove_xor1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= (void *)&dove_xor11_data,
+	},
+};
+
+void __init dove_xor1_init(void)
+{
+	platform_device_register(&dove_xor1_shared);
+
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, dove_xor10_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor10_data.cap_mask);
+	platform_device_register(&dove_xor10_channel);
+
+	dma_cap_set(DMA_MEMCPY, dove_xor11_data.cap_mask);
+	dma_cap_set(DMA_MEMSET, dove_xor11_data.cap_mask);
+	dma_cap_set(DMA_XOR, dove_xor11_data.cap_mask);
+	platform_device_register(&dove_xor11_channel);
+}
+
+void __init dove_init(void)
+{
+	int tclk;
+
+	tclk = get_tclk();
+
+	printk(KERN_INFO "Dove 88AP510 SoC, ");
+	printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+
+#ifdef CONFIG_CACHE_TAUROS2
+	tauros2_init();
+#endif
+	dove_setup_cpu_mbus();
+
+	dove_ge00_shared_data.t_clk = tclk;
+	dove_uart0_data[0].uartclk = tclk;
+	dove_uart1_data[0].uartclk = tclk;
+	dove_uart2_data[0].uartclk = tclk;
+	dove_uart3_data[0].uartclk = tclk;
+	dove_spi0_data.tclk = tclk;
+	dove_spi1_data.tclk = tclk;
+
+	/* internal devices that every board has */
+	dove_rtc_init();
+	dove_xor0_init();
+	dove_xor1_init();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/common.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-dove/common.h
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * 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 __ARCH_DOVE_COMMON_H
+#define __ARCH_DOVE_COMMON_H
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+extern struct sys_timer dove_timer;
+extern struct mbus_dram_target_info dove_mbus_dram_info;
+
+/*
+ * Basic Dove init functions used early by machine-setup.
+ */
+void dove_map_io(void);
+void dove_init(void);
+void dove_init_irq(void);
+void dove_setup_cpu_mbus(void);
+void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void dove_sata_init(struct mv_sata_platform_data *sata_data);
+void dove_pcie_init(int init_port0, int init_port1);
+void dove_ehci0_init(void);
+void dove_ehci1_init(void);
+void dove_uart0_init(void);
+void dove_uart1_init(void);
+void dove_uart2_init(void);
+void dove_uart3_init(void);
+void dove_spi0_init(void);
+void dove_spi1_init(void);
+void dove_i2c_init(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/dove-db-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-dove/dove-db-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/dove-db-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/dove-db-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/mach-dove/dove-db-setup.c
+ *
+ * Marvell DB-MV88AP510-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/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/pci.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/dove.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data dove_db_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static struct mv_sata_platform_data dove_db_sata_data = {
+	.n_ports        = 1,
+};
+
+/*****************************************************************************
+ * SPI Devices:
+ * 	SPI0: 4M Flash ST-M25P32-VMF6P
+ ****************************************************************************/
+static const struct flash_platform_data dove_db_spi_flash_data = {
+	.type		= "m25p64",
+};
+
+static struct spi_board_info __initdata dove_db_spi_flash_info[] = {
+	{
+		.modalias       = "m25p80",
+		.platform_data  = &dove_db_spi_flash_data,
+		.irq            = -1,
+		.max_speed_hz   = 20000000,
+		.bus_num        = 0,
+		.chip_select    = 0,
+	},
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+static int __init dove_db_pci_init(void)
+{
+	if (machine_is_dove_db())
+		dove_pcie_init(1, 1);
+
+	return 0;
+}
+
+subsys_initcall(dove_db_pci_init);
+
+/*****************************************************************************
+ * Board Init
+ ****************************************************************************/
+static void __init dove_db_init(void)
+{
+	/*
+	 * Basic Dove setup. Needs to be called early.
+	 */
+	dove_init();
+
+	dove_ge00_init(&dove_db_ge00_data);
+	dove_ehci0_init();
+	dove_ehci1_init();
+	dove_sata_init(&dove_db_sata_data);
+	dove_spi0_init();
+	dove_spi1_init();
+	dove_uart0_init();
+	dove_uart1_init();
+	dove_i2c_init();
+	spi_register_board_info(dove_db_spi_flash_info,
+				ARRAY_SIZE(dove_db_spi_flash_info));
+}
+
+MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
+	.phys_io	= DOVE_SB_REGS_PHYS_BASE,
+	.io_pg_offst	= ((DOVE_SB_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= dove_db_init,
+	.map_io		= dove_map_io,
+	.init_irq	= dove_init_irq,
+	.timer		= &dove_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/bridge-regs.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/bridge-regs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/bridge-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/bridge-regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-dove/include/mach/bridge-regs.h
+ *
+ * Mbus-L to Mbus Bridge Registers
+ *
+ * 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 __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/dove.h>
+
+#define CPU_CONFIG		(BRIDGE_VIRT_BASE | 0x0000)
+
+#define CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
+#define  CPU_CTRL_PCIE0_LINK	0x00000001
+#define  CPU_RESET		0x00000002
+#define  CPU_CTRL_PCIE1_LINK	0x00000008
+
+#define RSTOUTn_MASK		(BRIDGE_VIRT_BASE | 0x0108)
+#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 BRIDGE_MASK		(BRIDGE_VIRT_BASE | 0x0114)
+#define  BRIDGE_INT_TIMER0	0x0002
+#define  BRIDGE_INT_TIMER1	0x0004
+#define  BRIDGE_INT_TIMER1_CLR	(~0x0004)
+
+#define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_CAUSE_LOW_OFF	0x0000
+#define IRQ_MASK_LOW_OFF	0x0004
+#define FIQ_MASK_LOW_OFF	0x0008
+#define ENDPOINT_MASK_LOW_OFF	0x000c
+#define IRQ_CAUSE_HIGH_OFF	0x0010
+#define IRQ_MASK_HIGH_OFF	0x0014
+#define FIQ_MASK_HIGH_OFF	0x0018
+#define ENDPOINT_MASK_HIGH_OFF	0x001c
+#define PCIE_INTERRUPT_MASK_OFF	0x0020
+
+#define IRQ_MASK_LOW		(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)
+#define FIQ_MASK_LOW		(IRQ_VIRT_BASE + FIQ_MASK_LOW_OFF)
+#define ENDPOINT_MASK_LOW	(IRQ_VIRT_BASE + ENDPOINT_MASK_LOW_OFF)
+#define IRQ_MASK_HIGH		(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)
+#define FIQ_MASK_HIGH		(IRQ_VIRT_BASE + FIQ_MASK_HIGH_OFF)
+#define ENDPOINT_MASK_HIGH	(IRQ_VIRT_BASE + ENDPOINT_MASK_HIGH_OFF)
+#define PCIE_INTERRUPT_MASK	(IRQ_VIRT_BASE + PCIE_INTERRUPT_MASK_OFF)
+
+#define POWER_MANAGEMENT	(BRIDGE_VIRT_BASE | 0x011c)
+
+#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-dove/include/mach/debug-macro.S
+ *
+ * This 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 <mach/bridge-regs.h>
+
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1					@ MMU enabled?
+	ldreq	\rx, =DOVE_SB_REGS_PHYS_BASE
+	ldrne	\rx, =DOVE_SB_REGS_VIRT_BASE
+	orr	\rx, \rx, #0x00012000
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/dove.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/dove.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/dove.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/dove.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-dove/include/mach/dove.h
+ *
+ * Generic definitions for Marvell Dove 88AP510 SoC
+ *
+ * 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 __ASM_ARCH_DOVE_H
+#define __ASM_ARCH_DOVE_H
+
+#include <mach/vmalloc.h>
+
+/*
+ * Marvell Dove address maps.
+ *
+ * phys		virt		size
+ * c8000000	fdb00000	1M	Cryptographic SRAM
+ * e0000000	@runtime	128M	PCIe-0 Memory space
+ * e8000000	@runtime	128M	PCIe-1 Memory space
+ * f1000000	fde00000	8M	on-chip south-bridge registers
+ * f1800000	fe600000	8M	on-chip north-bridge registers
+ * f2000000	fee00000	1M	PCIe-0 I/O space
+ * f2100000	fef00000	1M	PCIe-1 I/O space
+ */
+
+#define DOVE_CESA_PHYS_BASE		0xc8000000
+#define DOVE_CESA_VIRT_BASE		0xfdb00000
+#define DOVE_CESA_SIZE			SZ_1M
+
+#define DOVE_PCIE0_MEM_PHYS_BASE	0xe0000000
+#define DOVE_PCIE0_MEM_SIZE		SZ_128M
+
+#define DOVE_PCIE1_MEM_PHYS_BASE	0xe8000000
+#define DOVE_PCIE1_MEM_SIZE		SZ_128M
+
+#define DOVE_BOOTROM_PHYS_BASE		0xf8000000
+#define DOVE_BOOTROM_SIZE		SZ_128M
+
+#define DOVE_SCRATCHPAD_PHYS_BASE	0xf0000000
+#define DOVE_SCRATCHPAD_VIRT_BASE	0xfdd00000
+#define DOVE_SCRATCHPAD_SIZE		SZ_1M
+
+#define DOVE_SB_REGS_PHYS_BASE		0xf1000000
+#define DOVE_SB_REGS_VIRT_BASE		0xfde00000
+#define DOVE_SB_REGS_SIZE		SZ_8M
+
+#define DOVE_NB_REGS_PHYS_BASE		0xf1800000
+#define DOVE_NB_REGS_VIRT_BASE		0xfe600000
+#define DOVE_NB_REGS_SIZE		SZ_8M
+
+#define DOVE_PCIE0_IO_PHYS_BASE		0xf2000000
+#define DOVE_PCIE0_IO_VIRT_BASE		0xfee00000
+#define DOVE_PCIE0_IO_BUS_BASE		0x00000000
+#define DOVE_PCIE0_IO_SIZE		SZ_1M
+
+#define DOVE_PCIE1_IO_PHYS_BASE		0xf2100000
+#define DOVE_PCIE1_IO_VIRT_BASE		0xfef00000
+#define DOVE_PCIE1_IO_BUS_BASE		0x00100000
+#define DOVE_PCIE1_IO_SIZE		SZ_1M
+
+/*
+ * Dove Core Registers Map
+ */
+
+/* SPI, I2C, UART */
+#define DOVE_I2C_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x11000)
+#define DOVE_UART0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12000)
+#define DOVE_UART0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12000)
+#define DOVE_UART1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12100)
+#define DOVE_UART1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12100)
+#define DOVE_UART2_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12200)
+#define DOVE_UART2_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12200)
+#define DOVE_UART3_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x12300)
+#define DOVE_UART3_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x12300)
+#define DOVE_SPI0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x10600)
+#define DOVE_SPI1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x14600)
+
+/* North-South Bridge */
+#define BRIDGE_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x20000)
+
+/* Cryptographic Engine */
+#define DOVE_CRYPT_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x30000)
+
+/* PCIe 0 */
+#define DOVE_PCIE0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x40000)
+
+/* USB */
+#define DOVE_USB0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x50000)
+#define DOVE_USB1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x51000)
+
+/* XOR 0 Engine */
+#define DOVE_XOR0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60800)
+#define DOVE_XOR0_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60800)
+#define DOVE_XOR0_HIGH_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60A00)
+#define DOVE_XOR0_HIGH_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60A00)
+
+/* XOR 1 Engine */
+#define DOVE_XOR1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60900)
+#define DOVE_XOR1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60900)
+#define DOVE_XOR1_HIGH_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x60B00)
+#define DOVE_XOR1_HIGH_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x60B00)
+
+/* Gigabit Ethernet */
+#define DOVE_GE00_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x70000)
+
+/* PCIe 1 */
+#define DOVE_PCIE1_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0x80000)
+
+/* CAFE */
+#define DOVE_SDIO0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x92000)
+#define DOVE_SDIO1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x90000)
+#define DOVE_CAM_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x94000)
+#define DOVE_CAFE_WIN_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0x98000)
+
+/* SATA */
+#define DOVE_SATA_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xa0000)
+
+/* I2S/SPDIF */
+#define DOVE_AUD0_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xb0000)
+#define DOVE_AUD1_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xb4000)
+
+/* NAND Flash Controller */
+#define DOVE_NFC_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xc0000)
+
+/* MPP, GPIO, Reset Sampling */
+#define DOVE_MPP_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
+#define DOVE_RESET_SAMPLE_LO	(DOVE_MPP_VIRT_BASE | 0x014)
+#define DOVE_RESET_SAMPLE_HI	(DOVE_MPP_VIRT_BASE | 0x018)
+#define DOVE_GPIO_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_MPP_GENERAL_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define  DOVE_AU1_SPDIFO_GPIO_EN	(1 << 1)
+#define  DOVE_NAND_GPIO_EN		(1 << 0)
+#define DOVE_MPP_CTRL4_VIRT_BASE	(DOVE_GPIO_VIRT_BASE + 0x40)
+
+
+/* Power Management */
+#define DOVE_PMU_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xd0000)
+
+/* Real Time Clock */
+#define DOVE_RTC_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xd8500)
+
+/* AC97 */
+#define DOVE_AC97_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xe0000)
+#define DOVE_AC97_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe0000)
+
+/* Peripheral DMA */
+#define DOVE_PDMA_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xe4000)
+#define DOVE_PDMA_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe4000)
+
+#define DOVE_GLOBAL_CONFIG_1	(DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define  DOVE_TWSI_ENABLE_OPTION1	(1 << 7)
+#define DOVE_GLOBAL_CONFIG_2	(DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define  DOVE_TWSI_ENABLE_OPTION2	(1 << 20)
+#define  DOVE_TWSI_ENABLE_OPTION3	(1 << 21)
+#define  DOVE_TWSI_OPTION3_GPIO		(1 << 22)
+#define DOVE_SSP_PHYS_BASE	(DOVE_SB_REGS_PHYS_BASE | 0xec000)
+#define DOVE_SSP_CTRL_STATUS_1	(DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define  DOVE_SSP_ON_AU1		(1 << 0)
+#define  DOVE_SSP_CLOCK_ENABLE		(1 << 1)
+#define  DOVE_SSP_BPB_CLOCK_SRC_SSP	(1 << 11)
+/* Memory Controller */
+#define DOVE_MC_VIRT_BASE	(DOVE_NB_REGS_VIRT_BASE | 0x00000)
+
+/* LCD Controller */
+#define DOVE_LCD_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD1_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x20000)
+#define DOVE_LCD2_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD_DCON_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x30000)
+
+/* Graphic Engine */
+#define DOVE_GPU_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x40000)
+
+/* Video Engine */
+#define DOVE_VPU_PHYS_BASE	(DOVE_NB_REGS_PHYS_BASE | 0x400000)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/entry-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/entry-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-dove/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell Dove platforms
+ *
+ * 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 <mach/bridge-regs.h>
+
+	.macro  disable_fiq
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+	ldr	\base, =IRQ_VIRT_BASE
+	.endm
+
+	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+	@ check low interrupts
+	ldr	\irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
+	ldr	\tmp, [\base, #IRQ_MASK_LOW_OFF]
+	mov	\irqnr, #31
+	ands	\irqstat, \irqstat, \tmp
+
+	@ if no low interrupts set, check high interrupts
+	ldreq	\irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+	ldreq	\tmp, [\base, #IRQ_MASK_HIGH_OFF]
+	moveq	\irqnr, #63
+	andeqs	\irqstat, \irqstat, \tmp
+
+	@ find first active interrupt source
+	clzne	\irqstat, \irqstat
+	subne	\irqnr, \irqnr, \irqstat
+	.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-dove/include/mach/gpio.h
+ *
+ * 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 __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <asm/errno.h>
+#include <mach/irqs.h>
+#include <plat/gpio.h>
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+#define GPIO_MAX	64
+
+#define GPIO_BASE_LO		(DOVE_GPIO_VIRT_BASE + 0x00)
+#define GPIO_BASE_HI		(DOVE_GPIO_VIRT_BASE + 0x20)
+
+#define GPIO_BASE(pin)		((pin < 32) ? GPIO_BASE_LO : GPIO_BASE_HI)
+
+#define GPIO_OUT(pin)		(GPIO_BASE(pin) + 0x00)
+#define GPIO_IO_CONF(pin)	(GPIO_BASE(pin) + 0x04)
+#define GPIO_BLINK_EN(pin)	(GPIO_BASE(pin) + 0x08)
+#define GPIO_IN_POL(pin)	(GPIO_BASE(pin) + 0x0c)
+#define GPIO_DATA_IN(pin)	(GPIO_BASE(pin) + 0x10)
+#define GPIO_EDGE_CAUSE(pin)	(GPIO_BASE(pin) + 0x14)
+#define GPIO_EDGE_MASK(pin)	(GPIO_BASE(pin) + 0x18)
+#define GPIO_LEVEL_MASK(pin)	(GPIO_BASE(pin) + 0x1c)
+
+static inline int gpio_to_irq(int pin)
+{
+	if (pin < NR_GPIO_IRQS)
+		return pin + IRQ_DOVE_GPIO_START;
+
+	return -EINVAL;
+}
+
+static inline int irq_to_gpio(int irq)
+{
+	if (IRQ_DOVE_GPIO_START < irq && irq < NR_IRQS)
+		return irq - IRQ_DOVE_GPIO_START;
+
+	return -EINVAL;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-dove/include/mach/hardware.h
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "dove.h"
+
+#define pcibios_assign_all_busses()	1
+
+#define PCIBIOS_MIN_IO			0x1000
+#define PCIBIOS_MIN_MEM			0x01000000
+#define PCIMEM_BASE			DOVE_PCIE0_MEM_PHYS_BASE
+
+
+/* Macros below are required for compatibility with PXA AC'97 driver.	*/
+#define __REG(x)	(*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \
+				DOVE_SB_REGS_VIRT_BASE)))
+#define __PREG(x)	(((u32)&(x)) - DOVE_SB_REGS_VIRT_BASE + \
+		DOVE_SB_REGS_PHYS_BASE)
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-dove/include/mach/io.h
+ *
+ * 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 __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "dove.h"
+
+#define IO_SPACE_LIMIT		0xffffffff
+
+#define __io(a)  ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\
+				   DOVE_PCIE0_IO_VIRT_BASE))
+#define __mem_pci(a)		(a)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mach-dove/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell Dove 88AP510 SoC
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * Dove Low Interrupt Controller
+ */
+#define IRQ_DOVE_BRIDGE		0
+#define IRQ_DOVE_H2C		1
+#define IRQ_DOVE_C2H		2
+#define IRQ_DOVE_NAND		3
+#define IRQ_DOVE_PDMA		4
+#define IRQ_DOVE_SPI1		5
+#define IRQ_DOVE_SPI0		6
+#define IRQ_DOVE_UART_0		7
+#define IRQ_DOVE_UART_1		8
+#define IRQ_DOVE_UART_2		9
+#define IRQ_DOVE_UART_3		10
+#define IRQ_DOVE_I2C		11
+#define IRQ_DOVE_GPIO_0_7	12
+#define IRQ_DOVE_GPIO_8_15	13
+#define IRQ_DOVE_GPIO_16_23	14
+#define IRQ_DOVE_PCIE0_ERR	15
+#define IRQ_DOVE_PCIE0		16
+#define IRQ_DOVE_PCIE1_ERR	17
+#define IRQ_DOVE_PCIE1		18
+#define IRQ_DOVE_I2S0		19
+#define IRQ_DOVE_I2S0_ERR	20
+#define IRQ_DOVE_I2S1		21
+#define IRQ_DOVE_I2S1_ERR	22
+#define IRQ_DOVE_USB_ERR	23
+#define IRQ_DOVE_USB0		24
+#define IRQ_DOVE_USB1		25
+#define IRQ_DOVE_GE00_RX	26
+#define IRQ_DOVE_GE00_TX	27
+#define IRQ_DOVE_GE00_MISC	28
+#define IRQ_DOVE_GE00_SUM	29
+#define IRQ_DOVE_GE00_ERR	30
+#define IRQ_DOVE_CRYPTO		31
+
+/*
+ * Dove High Interrupt Controller
+ */
+#define IRQ_DOVE_AC97		32
+#define IRQ_DOVE_PMU		33
+#define IRQ_DOVE_CAM		34
+#define IRQ_DOVE_SDIO0		35
+#define IRQ_DOVE_SDIO1		36
+#define IRQ_DOVE_SDIO0_WAKEUP	37
+#define IRQ_DOVE_SDIO1_WAKEUP	38
+#define IRQ_DOVE_XOR_00		39
+#define IRQ_DOVE_XOR_01		40
+#define IRQ_DOVE_XOR0_ERR	41
+#define IRQ_DOVE_XOR_10		42
+#define IRQ_DOVE_XOR_11		43
+#define IRQ_DOVE_XOR1_ERR	44
+#define IRQ_DOVE_LCD_DCON	45
+#define IRQ_DOVE_LCD1		46
+#define IRQ_DOVE_LCD0		47
+#define IRQ_DOVE_GPU		48
+#define IRQ_DOVE_PERFORM_MNTR	49
+#define IRQ_DOVE_VPRO_DMA1	51
+#define IRQ_DOVE_SSP_TIMER	54
+#define IRQ_DOVE_SSP		55
+#define IRQ_DOVE_MC_L2_ERR	56
+#define IRQ_DOVE_CRYPTO_ERR	59
+#define IRQ_DOVE_GPIO_24_31	60
+#define IRQ_DOVE_HIGH_GPIO	61
+#define IRQ_DOVE_SATA		62
+
+/*
+ * DOVE General Purpose Pins
+ */
+#define IRQ_DOVE_GPIO_START	64
+#define NR_GPIO_IRQS		64
+
+/*
+ * PMU interrupts
+ */
+#define IRQ_DOVE_PMU_START	(IRQ_DOVE_GPIO_START + NR_GPIO_IRQS)
+#define NR_PMU_IRQS		7
+#define IRQ_DOVE_RTC		(IRQ_DOVE_PMU_START + 5)
+
+#define NR_IRQS			(IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+
+/* Required for compatability with PXA AC97 driver.	*/
+#define IRQ_AC97		IRQ_DOVE_AC97
+/* Required for compatability with PXA DMA driver.	*/
+#define IRQ_DMA			IRQ_DOVE_PDMA
+/* Required for compatability with PXA NAND driver 	*/
+#define IRQ_NAND		IRQ_DOVE_NAND
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-dove/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x00000000)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/pm.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/pm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-dove/include/mach/pm.h
+ *
+ * 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 __ASM_ARCH_PM_H
+#define __ASM_ARCH_PM_H
+
+#include <asm/errno.h>
+#include <mach/irqs.h>
+
+#define CLOCK_GATING_CONTROL	(DOVE_PMU_VIRT_BASE + 0x38)
+#define  CLOCK_GATING_USB0_MASK		(1 << 0)
+#define  CLOCK_GATING_USB1_MASK		(1 << 1)
+#define  CLOCK_GATING_GBE_MASK		(1 << 2)
+#define  CLOCK_GATING_SATA_MASK		(1 << 3)
+#define  CLOCK_GATING_PCIE0_MASK	(1 << 4)
+#define  CLOCK_GATING_PCIE1_MASK	(1 << 5)
+#define  CLOCK_GATING_SDIO0_MASK	(1 << 8)
+#define  CLOCK_GATING_SDIO1_MASK	(1 << 9)
+#define  CLOCK_GATING_NAND_MASK		(1 << 10)
+#define  CLOCK_GATING_CAMERA_MASK	(1 << 11)
+#define  CLOCK_GATING_I2S0_MASK		(1 << 12)
+#define  CLOCK_GATING_I2S1_MASK		(1 << 13)
+#define  CLOCK_GATING_CRYPTO_MASK	(1 << 15)
+#define  CLOCK_GATING_AC97_MASK		(1 << 21)
+#define  CLOCK_GATING_PDMA_MASK		(1 << 22)
+#define  CLOCK_GATING_XOR0_MASK		(1 << 23)
+#define  CLOCK_GATING_XOR1_MASK		(1 << 24)
+#define  CLOCK_GATING_GIGA_PHY_MASK	(1 << 30)
+
+#define PMU_INTERRUPT_CAUSE	(DOVE_PMU_VIRT_BASE + 0x50)
+#define PMU_INTERRUPT_MASK	(DOVE_PMU_VIRT_BASE + 0x54)
+
+static inline int pmu_to_irq(int pin)
+{
+	if (pin < NR_PMU_IRQS)
+		return pin + IRQ_DOVE_PMU_START;
+
+	return -EINVAL;
+}
+
+static inline int irq_to_pmu(int irq)
+{
+	if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+		return irq - IRQ_DOVE_PMU_START;
+
+	return -EINVAL;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-dove/include/mach/system.h
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	/*
+	 * Enable soft reset to assert RSTOUTn.
+	 */
+	writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+	/*
+	 * Assert soft reset.
+	 */
+	writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+	while (1)
+		;
+}
+
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-dove/include/mach/timex.h
+ *
+ * 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.
+ */
+
+#define CLOCK_TICK_RATE		(100 * HZ)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-dove/include/mach/uncompress.h
+ *
+ * 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 <mach/dove.h>
+
+#define UART_THR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x0))
+#define UART_LSR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x14))
+
+#define LSR_THRE	0x20
+
+static void putc(const char c)
+{
+	int i;
+
+	for (i = 0; i < 0x1000; i++) {
+		/* Transmit fifo not full? */
+		if (*UART_LSR & LSR_THRE)
+			break;
+	}
+
+	*UART_THR = c;
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-dove/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END	0xfd800000
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-dove/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,133 @@
+/*
+ * arch/arm/mach-dove/irq.c
+ *
+ * Dove IRQ handling.
+ *
+ * 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/irq.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <asm/mach/arch.h>
+#include <plat/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/pm.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int irqoff;
+	BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
+
+	irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
+		3 + irq - IRQ_DOVE_GPIO_24_31;
+
+	orion_gpio_irq_handler(irqoff << 3);
+	if (irq == IRQ_DOVE_HIGH_GPIO) {
+		orion_gpio_irq_handler(40);
+		orion_gpio_irq_handler(48);
+		orion_gpio_irq_handler(56);
+	}
+}
+
+static void pmu_irq_mask(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = readl(PMU_INTERRUPT_MASK);
+	u &= ~(1 << (pin & 31));
+	writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_unmask(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = readl(PMU_INTERRUPT_MASK);
+	u |= 1 << (pin & 31);
+	writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_ack(unsigned int irq)
+{
+	int pin = irq_to_pmu(irq);
+	u32 u;
+
+	u = ~(1 << (pin & 31));
+	writel(u, PMU_INTERRUPT_CAUSE);
+}
+
+static struct irq_chip pmu_irq_chip = {
+	.name		= "pmu_irq",
+	.mask		= pmu_irq_mask,
+	.unmask		= pmu_irq_unmask,
+	.ack		= pmu_irq_ack,
+};
+
+static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
+
+	cause &= readl(PMU_INTERRUPT_MASK);
+	if (cause == 0) {
+		do_bad_IRQ(irq, desc);
+		return;
+	}
+
+	for (irq = 0; irq < NR_PMU_IRQS; irq++) {
+		if (!(cause & (1 << irq)))
+			continue;
+		irq = pmu_to_irq(irq);
+		desc = irq_desc + irq;
+		desc_handle_irq(irq, desc);
+	}
+}
+
+void __init dove_init_irq(void)
+{
+	int i;
+
+	orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
+	orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+
+	/*
+	 * Mask and clear GPIO IRQ interrupts.
+	 */
+	writel(0, GPIO_LEVEL_MASK(0));
+	writel(0, GPIO_EDGE_MASK(0));
+	writel(0, GPIO_EDGE_CAUSE(0));
+
+	/*
+	 * Mask and clear PMU interrupts
+	 */
+	writel(0, PMU_INTERRUPT_MASK);
+	writel(0, PMU_INTERRUPT_CAUSE);
+
+	for (i = IRQ_DOVE_GPIO_START; i < IRQ_DOVE_PMU_START; i++) {
+		set_irq_chip(i, &orion_gpio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		irq_desc[i].status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
+	set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
+
+	for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
+		set_irq_chip(i, &pmu_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		irq_desc[i].status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,14 @@
+if ARCH_DOVE
+
+menu "Marvell Dove Implementations"
+
+config MACH_DOVE_DB
+	bool "Marvell DB-MV88AP510 Development Board"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell DB-MV88AP510 Development Board.
+
+endmenu
+
+endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3 @@
+obj-y				+= common.o addr-map.o irq.o pcie.o
+
+obj-$(CONFIG_MACH_DOVE_DB)	+= dove-db-setup.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Makefile.boot linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Makefile.boot
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/Makefile.boot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-dove/pcie.c linux-libre-2.6.33-gnu1/arch/arm/mach-dove/pcie.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-dove/pcie.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-dove/pcie.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/mach-dove/pcie.c
+ *
+ * PCIe functions for Marvell Dove 88AP510 SoC
+ *
+ * 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/mbus.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include <asm/delay.h>
+#include <plat/pcie.h>
+#include <mach/irqs.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+struct pcie_port {
+	u8			index;
+	u8			root_bus_nr;
+	void __iomem		*base;
+	spinlock_t		conf_lock;
+	char			io_space_name[16];
+	char			mem_space_name[16];
+	struct resource		res[2];
+};
+
+static struct pcie_port pcie_port[2];
+static int num_pcie_ports;
+
+
+static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	struct pcie_port *pp;
+
+	if (nr >= num_pcie_ports)
+		return 0;
+
+	pp = &pcie_port[nr];
+	pp->root_bus_nr = sys->busnr;
+
+	/*
+	 * Generic PCIe unit setup.
+	 */
+	orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+
+	orion_pcie_setup(pp->base, &dove_mbus_dram_info);
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+		 "PCIe %d I/O", pp->index);
+	pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+	pp->res[0].name = pp->io_space_name;
+	if (pp->index == 0) {
+		pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
+		pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
+	} else {
+		pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
+		pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
+	}
+	pp->res[0].flags = IORESOURCE_IO;
+	if (request_resource(&ioport_resource, &pp->res[0]))
+		panic("Request PCIe IO resource failed\n");
+	sys->resource[0] = &pp->res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+		 "PCIe %d MEM", pp->index);
+	pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+	pp->res[1].name = pp->mem_space_name;
+	if (pp->index == 0) {
+		pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
+		pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
+	} else {
+		pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
+		pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
+	}
+	pp->res[1].flags = IORESOURCE_MEM;
+	if (request_resource(&iomem_resource, &pp->res[1]))
+		panic("Request PCIe Memory resource failed\n");
+	sys->resource[1] = &pp->res[1];
+
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static struct pcie_port *bus_to_port(int bus)
+{
+	int i;
+
+	for (i = num_pcie_ports - 1; i >= 0; i--) {
+		int rbus = pcie_port[i].root_bus_nr;
+		if (rbus != -1 && rbus <= bus)
+			break;
+	}
+
+	return i >= 0 ? pcie_port + i : NULL;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+	/*
+	 * Don't go out when trying to access nonexisting devices
+	 * on the local bus.
+	 */
+	if (bus == pp->root_bus_nr && dev > 1)
+		return 0;
+
+	return 1;
+}
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+			int size, u32 *val)
+{
+	struct pcie_port *pp = bus_to_port(bus->number);
+	unsigned long flags;
+	int ret;
+
+	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+			int where, int size, u32 val)
+{
+	struct pcie_port *pp = bus_to_port(bus->number);
+	unsigned long flags;
+	int ret;
+
+	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static struct pci_ops pcie_ops = {
+	.read = pcie_rd_conf,
+	.write = pcie_wr_conf,
+};
+
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+	/*
+	 * Prevent enumeration of root complex.
+	 */
+	if (dev->bus->parent == NULL && dev->devfn == 0) {
+		int i;
+
+		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static struct pci_bus __init *
+dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct pci_bus *bus;
+
+	if (nr < num_pcie_ports) {
+		bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+	} else {
+		bus = NULL;
+		BUG();
+	}
+
+	return bus;
+}
+
+static int __init dove_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+	return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
+}
+
+static struct hw_pci dove_pci __initdata = {
+	.nr_controllers	= 2,
+	.swizzle	= pci_std_swizzle,
+	.setup		= dove_pcie_setup,
+	.scan		= dove_pcie_scan_bus,
+	.map_irq	= dove_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int index, unsigned long base)
+{
+	printk(KERN_INFO "Dove PCIe port %d: ", index);
+
+	if (orion_pcie_link_up((void __iomem *)base)) {
+		struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+		printk(KERN_INFO "link up\n");
+
+		pp->index = index;
+		pp->root_bus_nr = -1;
+		pp->base = (void __iomem *)base;
+		spin_lock_init(&pp->conf_lock);
+		memset(pp->res, 0, sizeof(pp->res));
+	} else {
+		printk(KERN_INFO "link down, ignoring\n");
+	}
+}
+
+void __init dove_pcie_init(int init_port0, int init_port1)
+{
+	if (init_port0)
+		add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
+
+	if (init_port1)
+		add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
+
+	pci_common_init(&dove_pci);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/core.c linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/core.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 
 #include <mach/hardware.h>
 #include <mach/fb.h>
+#include <mach/ep93xx_keypad.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -728,6 +729,82 @@ void __init ep93xx_register_fb(struct ep
 	platform_device_register(&ep93xx_fb_device);
 }
 
+
+/*************************************************************************
+ * EP93xx matrix keypad peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_keypad_resource[] = {
+	{
+		.start	= EP93XX_KEY_MATRIX_PHYS_BASE,
+		.end	= EP93XX_KEY_MATRIX_PHYS_BASE + 0x0c - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_EP93XX_KEY,
+		.end	= IRQ_EP93XX_KEY,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ep93xx_keypad_device = {
+	.name			= "ep93xx-keypad",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(ep93xx_keypad_resource),
+	.resource		= ep93xx_keypad_resource,
+};
+
+void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
+{
+	ep93xx_keypad_device.dev.platform_data = data;
+	platform_device_register(&ep93xx_keypad_device);
+}
+
+int ep93xx_keypad_acquire_gpio(struct platform_device *pdev)
+{
+	int err;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		err = gpio_request(EP93XX_GPIO_LINE_C(i), dev_name(&pdev->dev));
+		if (err)
+			goto fail_gpio_c;
+		err = gpio_request(EP93XX_GPIO_LINE_D(i), dev_name(&pdev->dev));
+		if (err)
+			goto fail_gpio_d;
+	}
+
+	/* Enable the keypad controller; GPIO ports C and D used for keypad */
+	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+				 EP93XX_SYSCON_DEVCFG_GONK);
+
+	return 0;
+
+fail_gpio_d:
+	gpio_free(EP93XX_GPIO_LINE_C(i));
+fail_gpio_c:
+	for ( ; i >= 0; --i) {
+		gpio_free(EP93XX_GPIO_LINE_C(i));
+		gpio_free(EP93XX_GPIO_LINE_D(i));
+	}
+	return err;
+}
+EXPORT_SYMBOL(ep93xx_keypad_acquire_gpio);
+
+void ep93xx_keypad_release_gpio(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		gpio_free(EP93XX_GPIO_LINE_C(i));
+		gpio_free(EP93XX_GPIO_LINE_D(i));
+	}
+
+	/* Disable the keypad controller; GPIO ports C and D used for GPIO */
+	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+			       EP93XX_SYSCON_DEVCFG_GONK);
+}
+EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
+
+
 extern void ep93xx_gpio_init(void);
 
 void __init ep93xx_init_devices(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/clkdev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/clkdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,7 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/clkdev.h
+ */
+
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,7 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/dma.h
+ */
+
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,9 +5,6 @@
 #ifndef __ASM_ARCH_EP93XX_KEYPAD_H
 #define __ASM_ARCH_EP93XX_KEYPAD_H
 
-#define MAX_MATRIX_KEY_ROWS		(8)
-#define MAX_MATRIX_KEY_COLS		(8)
-
 /* flags for the ep93xx_keypad driver */
 #define EP93XX_KEYPAD_DISABLE_3_KEY	(1<<0)	/* disable 3-key reset */
 #define EP93XX_KEYPAD_DIAG_MODE		(1<<1)	/* diagnostic mode */
@@ -18,8 +15,6 @@
 
 /**
  * struct ep93xx_keypad_platform_data - platform specific device structure
- * @matrix_key_rows:		number of rows in the keypad matrix
- * @matrix_key_cols:		number of columns in the keypad matrix
  * @matrix_key_map:		array of keycodes defining the keypad matrix
  * @matrix_key_map_size:	ARRAY_SIZE(matrix_key_map)
  * @debounce:			debounce start count; terminal count is 0xff
@@ -27,8 +22,6 @@
  * @flags:			see above
  */
 struct ep93xx_keypad_platform_data {
-	unsigned int	matrix_key_rows;
-	unsigned int	matrix_key_cols;
 	unsigned int	*matrix_key_map;
 	int		matrix_key_map_size;
 	unsigned int	debounce;
@@ -36,7 +29,7 @@ struct ep93xx_keypad_platform_data {
 	unsigned int	flags;
 };
 
-/* macro for creating the matrix_key_map table */
-#define KEY(row, col, val)	(((row) << 28) | ((col) << 24) | (val))
+#define EP93XX_MATRIX_ROWS		(8)
+#define EP93XX_MATRIX_COLS		(8)
 
 #endif	/* __ASM_ARCH_EP93XX_KEYPAD_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -134,6 +134,7 @@
 #define EP93XX_UART3_PHYS_BASE		EP93XX_APB_PHYS(0x000e0000)
 #define EP93XX_UART3_BASE		EP93XX_APB_IOMEM(0x000e0000)
 
+#define EP93XX_KEY_MATRIX_PHYS_BASE	EP93XX_APB_PHYS(0x000f0000)
 #define EP93XX_KEY_MATRIX_BASE		EP93XX_APB_IOMEM(0x000f0000)
 
 #define EP93XX_ADC_BASE			EP93XX_APB_IOMEM(0x00100000)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/hardware.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
 /*
  * arch/arm/mach-ep93xx/include/mach/hardware.h
  */
+
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
 /*
  * arch/arm/mach-ep93xx/include/mach/io.h
  */
+
 #ifndef __ASM_MACH_IO_H
 #define __ASM_MACH_IO_H
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/platform.h linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/platform.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ep93xx/include/mach/platform.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ep93xx/include/mach/platform.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@ struct i2c_gpio_platform_data;
 struct i2c_board_info;
 struct platform_device;
 struct ep93xxfb_mach_info;
+struct ep93xx_keypad_platform_data;
 
 struct ep93xx_eth_data
 {
@@ -39,6 +40,9 @@ void ep93xx_register_fb(struct ep93xxfb_
 void ep93xx_register_pwm(int pwm0, int pwm1);
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
 void ep93xx_pwm_release_gpio(struct platform_device *pdev);
+void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
+int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
+void ep93xx_keypad_release_gpio(struct platform_device *pdev);
 
 void ep93xx_init_devices(void);
 extern struct sys_timer ep93xx_timer;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/common.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/common.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -201,6 +201,11 @@ void __init footbridge_map_io(void)
 
 #ifdef CONFIG_FOOTBRIDGE_ADDIN
 
+static inline unsigned long fb_bus_sdram_offset(void)
+{
+	return *CSR_PCISDRAMBASE & 0xfffffff0;
+}
+
 /*
  * These two functions convert virtual addresses to PCI addresses and PCI
  * addresses to virtual addresses.  Note that it is only legal to use these
@@ -210,14 +215,13 @@ unsigned long __virt_to_bus(unsigned lon
 {
 	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
 
-	return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0);
+	return res + (fb_bus_sdram_offset() - PAGE_OFFSET);
 }
 EXPORT_SYMBOL(__virt_to_bus);
 
 unsigned long __bus_to_virt(unsigned long res)
 {
-	res -= (*CSR_PCISDRAMBASE & 0xfffffff0);
-	res += PAGE_OFFSET;
+	res = res - (fb_bus_sdram_offset() - PAGE_OFFSET);
 
 	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
 
@@ -225,4 +229,16 @@ unsigned long __bus_to_virt(unsigned lon
 }
 EXPORT_SYMBOL(__bus_to_virt);
 
+unsigned long __pfn_to_bus(unsigned long pfn)
+{
+	return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET));
+}
+EXPORT_SYMBOL(__pfn_to_bus);
+
+unsigned long __bus_to_pfn(unsigned long bus)
+{
+	return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET));
+}
+EXPORT_SYMBOL(__bus_to_pfn);
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/dc21285-timer.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/dc21285-timer.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/dc21285-timer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/dc21285-timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,8 +56,6 @@ static void __init footbridge_timer_init
 	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
 
 	setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
-
-	isa_rtc_init();
 }
 
 struct sys_timer footbridge_timer = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,8 @@
 #ifndef __ASSEMBLY__
 extern unsigned long __virt_to_bus(unsigned long);
 extern unsigned long __bus_to_virt(unsigned long);
+extern unsigned long __pfn_to_bus(unsigned long);
+extern unsigned long __bus_to_pfn(unsigned long);
 #endif
 #define __virt_to_bus	__virt_to_bus
 #define __bus_to_virt	__bus_to_virt
@@ -36,14 +38,15 @@ extern unsigned long __bus_to_virt(unsig
 #elif defined(CONFIG_FOOTBRIDGE_HOST)
 
 /*
- * The footbridge is programmed to expose the system RAM at the corresponding
- * address.  So, if PAGE_OFFSET is 0xc0000000, RAM appears at 0xe0000000.
- * If 0x80000000, then its exposed at 0xa0000000 on the bus. etc.
- * The only requirement is that the RAM isn't placed at bus address 0 which
+ * The footbridge is programmed to expose the system RAM at 0xe0000000.
+ * The requirement is that the RAM isn't placed at bus address 0, which
  * would clash with VGA cards.
  */
-#define __virt_to_bus(x)	((x) - 0xe0000000)
-#define __bus_to_virt(x)	((x) + 0xe0000000)
+#define BUS_OFFSET		0xe0000000
+#define __virt_to_bus(x)	((x) + (BUS_OFFSET - PAGE_OFFSET))
+#define __bus_to_virt(x)	((x) - (BUS_OFFSET - PAGE_OFFSET))
+#define __pfn_to_bus(x)		(__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
+#define __bus_to_pfn(x)		__phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
 
 #else
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,9 @@
 #include <linux/serial_8250.h>
 
 #include <asm/irq.h>
+#include <asm/hardware/dec21285.h>
+
+#include "common.h"
 
 static struct resource rtc_resources[] = {
 	[0] = {
@@ -77,11 +80,18 @@ static struct platform_device serial_dev
 
 static int __init footbridge_isa_init(void)
 {
-	int err;
+	int err = 0;
 
-	err = platform_device_register(&rtc_device);
-	if (err)
-		printk(KERN_ERR "Unable to register RTC device: %d\n", err);
+	if (!footbridge_cfn_mode())
+		return 0;
+
+	/* Personal server doesn't have RTC */
+	if (!machine_is_personal_server()) {
+		isa_rtc_init();
+		err = platform_device_register(&rtc_device);
+		if (err)
+			printk(KERN_ERR "Unable to register RTC device: %d\n", err);
+	}
 	err = platform_device_register(&serial_device);
 	if (err)
 		printk(KERN_ERR "Unable to register serial device: %d\n", err);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa-rtc.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa-rtc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa-rtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa-rtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ *  arch/arm/mach-footbridge/isa-rtc.c
+ *
+ *  Copyright (C) 1998 Russell King.
+ *  Copyright (C) 1998 Phil Blundell
+ *
+ * CATS has a real-time clock, though the evaluation board doesn't.
+ *
+ * Changelog:
+ *  21-Mar-1998	RMK	Created
+ *  27-Aug-1998	PJB	CATS support
+ *  28-Dec-1998	APH	Made leds optional
+ *  20-Jan-1999	RMK	Started merge of EBSA285, CATS and NetWinder
+ *  16-Mar-1999	RMK	More support for EBSA285-like machines with RTCs in
+ */
+
+#define RTC_PORT(x)		(0x70+(x))
+#define RTC_ALWAYS_BCD		0
+
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+#include <linux/bcd.h>
+#include <linux/io.h>
+
+#include "common.h"
+
+void __init isa_rtc_init(void)
+{
+	int reg_d, reg_b;
+
+	/*
+	 * Probe for the RTC.
+	 */
+	reg_d = CMOS_READ(RTC_REG_D);
+
+	/*
+	 * make sure the divider is set
+	 */
+	CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
+
+	/*
+	 * Set control reg B
+	 *   (24 hour mode, update enabled)
+	 */
+	reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
+	reg_b |= 2;
+	CMOS_WRITE(reg_b, RTC_REG_B);
+
+	if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
+	    CMOS_READ(RTC_REG_B) == reg_b) {
+		/*
+		 * We have a RTC.  Check the battery
+		 */
+		if ((reg_d & 0x80) == 0)
+			printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa-timer.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa-timer.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/isa-timer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/isa-timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,8 +76,6 @@ static struct irqaction isa_timer_irq =
 
 static void __init isa_timer_init(void)
 {
-	isa_rtc_init();
-
 	/* enable PIT timer */
 	/* set for periodic (4) and LSB/MSB write (0x30) */
 	outb(0x34, 0x43);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y			:= common.o dc21285.o dma.o isa-irq.o time.o
+obj-y			:= common.o dc21285.o dma.o isa-irq.o
 obj-m			:=
 obj-n			:=
 obj-			:=
@@ -25,4 +25,4 @@ obj-$(CONFIG_ARCH_PERSONAL_SERVER) += pe
 obj-$(CONFIG_PCI)	+=$(pci-y)
 obj-$(CONFIG_LEDS)	+=$(leds-y)
 
-obj-$(CONFIG_ISA)	+= isa.o
+obj-$(CONFIG_ISA)	+= isa.o isa-rtc.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/time.c linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/time.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-footbridge/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-footbridge/time.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,164 +0,0 @@
-/*
- *  arch/arm/mach-footbridge/include/mach/time.h
- *
- *  Copyright (C) 1998 Russell King.
- *  Copyright (C) 1998 Phil Blundell
- *
- * CATS has a real-time clock, though the evaluation board doesn't.
- *
- * Changelog:
- *  21-Mar-1998	RMK	Created
- *  27-Aug-1998	PJB	CATS support
- *  28-Dec-1998	APH	Made leds optional
- *  20-Jan-1999	RMK	Started merge of EBSA285, CATS and NetWinder
- *  16-Mar-1999	RMK	More support for EBSA285-like machines with RTCs in
- */
-
-#define RTC_PORT(x)		(rtc_base+(x))
-#define RTC_ALWAYS_BCD		0
-
-#include <linux/timex.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
-#include <linux/bcd.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#include <asm/mach/time.h>
-#include "common.h"
-
-static int rtc_base;
-
-static unsigned long __init get_isa_cmos_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec;
-
-	// check to see if the RTC makes sense.....
-	if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
-		return mktime(1970, 1, 1, 0, 0, 0);
-
-	do {
-		sec  = CMOS_READ(RTC_SECONDS);
-		min  = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day  = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon  = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-	} while (sec != CMOS_READ(RTC_SECONDS));
-
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		sec = bcd2bin(sec);
-		min = bcd2bin(min);
-		hour = bcd2bin(hour);
-		day = bcd2bin(day);
-		mon = bcd2bin(mon);
-		year = bcd2bin(year);
-	}
-	if ((year += 1900) < 1970)
-		year += 100;
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-static int set_isa_cmos_time(void)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-	unsigned long nowtime = xtime.tv_sec;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		cmos_minutes = bcd2bin(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-			real_seconds = bin2bcd(real_seconds);
-			real_minutes = bin2bcd(real_minutes);
-		}
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else
-		retval = -1;
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-void __init isa_rtc_init(void)
-{
-	if (machine_is_personal_server())
-		/*
-		 * Add-in 21285s shouldn't access the RTC
-		 */
-		rtc_base = 0;
-	else
-		rtc_base = 0x70;
-
-	if (rtc_base) {
-		int reg_d, reg_b;
-
-		/*
-		 * Probe for the RTC.
-		 */
-		reg_d = CMOS_READ(RTC_REG_D);
-
-		/*
-		 * make sure the divider is set
-		 */
-		CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
-
-		/*
-		 * Set control reg B
-		 *   (24 hour mode, update enabled)
-		 */
-		reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
-		reg_b |= 2;
-		CMOS_WRITE(reg_b, RTC_REG_B);
-
-		if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
-		    CMOS_READ(RTC_REG_B) == reg_b) {
-			struct timespec tv;
-
-			/*
-			 * We have a RTC.  Check the battery
-			 */
-			if ((reg_d & 0x80) == 0)
-				printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
-
-			tv.tv_nsec = 0;
-			tv.tv_sec = get_isa_cmos_time();
-			do_settimeofday(&tv);
-			set_rtc = set_isa_cmos_time;
-		} else
-			rtc_base = 0;
-	}
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-gemini/gpio.c linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-gemini/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,7 +86,7 @@ static int gpio_set_irq_type(unsigned in
 	unsigned int reg_both, reg_level, reg_type;
 
 	reg_type = __raw_readl(base + GPIO_INT_TYPE);
-	reg_level = __raw_readl(base + GPIO_INT_BOTH_EDGE);
+	reg_level = __raw_readl(base + GPIO_INT_LEVEL);
 	reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);
 
 	switch (type) {
@@ -117,7 +117,7 @@ static int gpio_set_irq_type(unsigned in
 	}
 
 	__raw_writel(reg_type, base + GPIO_INT_TYPE);
-	__raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE);
+	__raw_writel(reg_level, base + GPIO_INT_LEVEL);
 	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
 
 	gpio_ack_irq(irq);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,9 @@ static inline void putc(char c)
 	UART[UART_TX] = c;
 }
 
-#define flush() do { } while (0)
+static inline void flush(void)
+{
+}
 
 /*
  * nothing to do
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-integrator/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-integrator/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-integrator/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #define BUS_OFFSET	UL(0x80000000)
 #define __virt_to_bus(x)	((x) - PAGE_OFFSET + BUS_OFFSET)
 #define __bus_to_virt(x)	((x) - BUS_OFFSET + PAGE_OFFSET)
-#define __pfn_to_bus(x)		(((x) << PAGE_SHIFT) + BUS_OFFSET)
+#define __pfn_to_bus(x)		(__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
+#define __bus_to_pfn(x)		__phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,6 +64,8 @@ static inline unsigned long __lbus_to_vi
 		(dma_addr_t)page_to_phys(page);				\
 	})
 
+#define __arch_dma_to_page(dev, addr)	phys_to_page(addr)
+
 #endif /* CONFIG_ARCH_IOP13XX */
 #endif /* !ASSEMBLY */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/include/mach/time.h linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/time.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/include/mach/time.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/include/mach/time.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,6 @@
 #define IOP13XX_CORE_FREQ_1200		(5 << 16)
 
 void iop_init_time(unsigned long tickrate);
-unsigned long iop_gettimeoffset(void);
 
 static inline unsigned long iop13xx_core_freq(void)
 {
@@ -66,6 +65,13 @@ static inline unsigned long iop13xx_xsi_
 	return 2;
 }
 
+static inline u32 read_tmr0(void)
+{
+	u32 val;
+	asm volatile("mrc p6, 0, %0, c0, c9, 0" : "=r" (val));
+	return val;
+}
+
 static inline void write_tmr0(u32 val)
 {
 	asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val));
@@ -83,6 +89,11 @@ static inline u32 read_tcr0(void)
 	return val;
 }
 
+static inline void write_tcr0(u32 val)
+{
+	asm volatile("mcr p6, 0, %0, c2, c9, 0" : : "r" (val));
+}
+
 static inline u32 read_tcr1(void)
 {
 	u32 val;
@@ -90,6 +101,11 @@ static inline u32 read_tcr1(void)
 	return val;
 }
 
+static inline void write_tcr1(u32 val)
+{
+	asm volatile("mcr p6, 0, %0, c3, c9, 0" : : "r" (val));
+}
+
 static inline void write_trr0(u32 val)
 {
 	asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/iq81340mc.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/iq81340mc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/iq81340mc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/iq81340mc.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,6 @@ static void __init iq81340mc_timer_init(
 
 static struct sys_timer iq81340mc_timer = {
        .init       = iq81340mc_timer_init,
-       .offset     = iop_gettimeoffset,
 };
 
 MACHINE_START(IQ81340MC, "Intel IQ81340MC")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/iq81340sc.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/iq81340sc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop13xx/iq81340sc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop13xx/iq81340sc.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,7 +89,6 @@ static void __init iq81340sc_timer_init(
 
 static struct sys_timer iq81340sc_timer = {
        .init       = iq81340sc_timer_init,
-       .offset     = iop_gettimeoffset,
 };
 
 MACHINE_START(IQ81340SC, "Intel IQ81340SC")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/em7210.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/em7210.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/em7210.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/em7210.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,6 @@ static void __init em7210_timer_init(voi
 
 static struct sys_timer em7210_timer = {
 	.init		= em7210_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/glantank.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/glantank.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/glantank.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/glantank.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,6 @@ static void __init glantank_timer_init(v
 
 static struct sys_timer glantank_timer = {
 	.init		= glantank_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/iq31244.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq31244.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/iq31244.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq31244.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,7 +78,6 @@ static void __init iq31244_timer_init(vo
 
 static struct sys_timer iq31244_timer = {
 	.init		= iq31244_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/iq80321.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq80321.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/iq80321.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/iq80321.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,6 @@ static void __init iq80321_timer_init(vo
 
 static struct sys_timer iq80321_timer = {
 	.init		= iq80321_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/n2100.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/n2100.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop32x/n2100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop32x/n2100.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,6 @@ static void __init n2100_timer_init(void
 
 static struct sys_timer n2100_timer = {
 	.init		= n2100_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop33x/iq80331.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80331.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop33x/iq80331.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80331.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,6 @@ static void __init iq80331_timer_init(vo
 
 static struct sys_timer iq80331_timer = {
 	.init		= iq80331_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-iop33x/iq80332.c linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80332.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-iop33x/iq80332.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-iop33x/iq80332.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,6 @@ static void __init iq80332_timer_init(vo
 
 static struct sys_timer iq80332_timer = {
 	.init		= iq80332_timer_init,
-	.offset		= iop_gettimeoffset,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp2000/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp2000/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp2000/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,11 +17,15 @@
 
 #include <mach/ixp2000-regs.h>
 
-#define __virt_to_bus(v) \
-	(((__virt_to_phys(v) - 0x0) + (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)))
+#define IXP2000_PCI_SDRAM_OFFSET	(*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)
 
-#define __bus_to_virt(b) \
-	__phys_to_virt((((b - (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)) + 0x0)))
+#define __phys_to_bus(x)	((x) + (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+#define __bus_to_phys(x)	((x) - (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+
+#define __virt_to_bus(v)	__phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b)	__phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p)		__phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b)		__phys_to_pfn(__bus_to_phys(b))
 
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp23xx/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,16 +19,15 @@
  */
 #define PHYS_OFFSET		(0x00000000)
 
-#define __virt_to_bus(v)						\
-	({ unsigned int ret;						\
-	ret = ((__virt_to_phys(v) - 0x00000000) +			\
-	 (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)); 	\
-	ret; })
+#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0))
 
-#define __bus_to_virt(b)						\
-	({ unsigned int data;						\
-	data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR);		\
-	 __phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
+#define __phys_to_bus(x)	((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+#define __bus_to_phys(x)	((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+
+#define __virt_to_bus(v)	__phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b)	__phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p)		__phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b)		__phys_to_pfn(__bus_to_phys(b))
 
 #define arch_is_coherent()	1
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/avila-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/avila-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,40 +22,45 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
-
 #include <asm/mach/pci.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#define AVILA_MAX_DEV	4
+#define LOFT_MAX_DEV	6
+#define IRQ_LINES	4
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		11
+#define INTB		10
+#define INTC		9
+#define INTD		8
+
 void __init avila_pci_preinit(void)
 {
-	set_irq_type(IRQ_AVILA_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_AVILA_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_AVILA_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_AVILA_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[AVILA_PCI_IRQ_LINES] = {
-		IRQ_AVILA_PCI_INTA,
-		IRQ_AVILA_PCI_INTB,
-		IRQ_AVILA_PCI_INTC,
-		IRQ_AVILA_PCI_INTD
+	static int pci_irq_table[IRQ_LINES] = {
+		IXP4XX_GPIO_IRQ(INTA),
+		IXP4XX_GPIO_IRQ(INTB),
+		IXP4XX_GPIO_IRQ(INTC),
+		IXP4XX_GPIO_IRQ(INTD)
 	};
 
-	int irq = -1;
-
 	if (slot >= 1 &&
-	slot <= (machine_is_loft() ? LOFT_PCI_MAX_DEV : AVILA_PCI_MAX_DEV) &&
-		pin >= 1 && pin <= AVILA_PCI_IRQ_LINES) {
-		irq = pci_irq_table[(slot + pin - 2) % 4];
-	}
+	    slot <= (machine_is_loft() ? LOFT_MAX_DEV : AVILA_MAX_DEV) &&
+	    pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[(slot + pin - 2) % 4];
 
-	return irq;
+	return -1;
 }
 
 struct hw_pci avila_pci __initdata = {
@@ -75,4 +80,3 @@ int __init avila_pci_init(void)
 }
 
 subsys_initcall(avila_pci_init);
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/avila-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/avila-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/avila-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,6 @@
 #include <linux/serial_8250.h>
 #include <linux/slab.h>
 #include <linux/i2c-gpio.h>
-
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -29,6 +28,9 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#define AVILA_SDA_PIN	7
+#define AVILA_SCL_PIN	6
+
 static struct flash_platform_data avila_flash_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/common.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,7 @@ int gpio_to_irq(int gpio)
 }
 EXPORT_SYMBOL(gpio_to_irq);
 
-int irq_to_gpio(int irq)
+int irq_to_gpio(unsigned int irq)
 {
 	int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/common-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -481,11 +481,7 @@ int ixp4xx_setup(int nr, struct pci_sys_
 
 	res[1].name = "PCI Memory Space";
 	res[1].start = PCIBIOS_MIN_MEM;
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-	res[1].end = 0x4bffffff;
-#else
-	res[1].end = 0x4fffffff;
-#endif
+	res[1].end = PCIBIOS_MAX_MEM;
 	res[1].flags = IORESOURCE_MEM;
 
 	request_resource(&ioport_resource, &res[0]);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/coyote-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/coyote-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,27 +18,31 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-
 #include <asm/mach/pci.h>
 
+#define SLOT0_DEVID	14
+#define SLOT1_DEVID	15
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define SLOT0_INTA	6
+#define SLOT1_INTA	11
+
 void __init coyote_pci_preinit(void)
 {
-	set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	if (slot == COYOTE_PCI_SLOT0_DEVID)
-		return IRQ_COYOTE_PCI_SLOT0;
-	else if (slot == COYOTE_PCI_SLOT1_DEVID)
-		return IRQ_COYOTE_PCI_SLOT1;
+	if (slot == SLOT0_DEVID)
+		return IXP4XX_GPIO_IRQ(SLOT0_INTA);
+	else if (slot == SLOT1_DEVID)
+		return IXP4XX_GPIO_IRQ(SLOT1_INTA);
 	else return -1;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/coyote-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,15 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#define COYOTE_IDE_BASE_PHYS	IXP4XX_EXP_BUS_BASE(3)
+#define COYOTE_IDE_BASE_VIRT	0xFFFE1000
+#define COYOTE_IDE_REGION_SIZE	0x1000
+
+#define COYOTE_IDE_DATA_PORT	0xFFFE10E0
+#define COYOTE_IDE_CTRL_PORT	0xFFFE10FC
+#define COYOTE_IDE_ERROR_PORT	0xFFFE10E2
+#define IRQ_COYOTE_IDE		IRQ_IXP4XX_GPIO5
+
 static struct flash_platform_data coyote_flash_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/dsmg600-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/dsmg600-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/dsmg600-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/dsmg600-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,39 +19,45 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#define MAX_DEV		4
+#define IRQ_LINES	3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		11
+#define INTB		10
+#define INTC		9
+#define INTD		8
+#define INTE		7
+#define INTF		6
+
 void __init dsmg600_pci_preinit(void)
 {
-	set_irq_type(IRQ_DSMG600_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_DSMG600_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_DSMG600_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_DSMG600_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_DSMG600_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_DSMG600_PCI_INTF, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] =
-	{
-		{ IRQ_DSMG600_PCI_INTE, -1, -1 },
-		{ IRQ_DSMG600_PCI_INTA, -1, -1 },
-		{ IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD },
-		{ IRQ_DSMG600_PCI_INTF, -1, -1 },
+	static int pci_irq_table[MAX_DEV][IRQ_LINES] = {
+		{ IXP4XX_GPIO_IRQ(INTE), -1, -1 },
+		{ IXP4XX_GPIO_IRQ(INTA), -1, -1 },
+		{ IXP4XX_GPIO_IRQ(INTB), IXP4XX_GPIO_IRQ(INTC),
+		  IXP4XX_GPIO_IRQ(INTD) },
+		{ IXP4XX_GPIO_IRQ(INTF), -1, -1 },
 	};
 
-	int irq = -1;
-
-	if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV &&
-		pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES)
-		irq = pci_irq_table[slot-1][pin-1];
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[slot - 1][pin - 1];
 
-	return irq;
+	return -1;
 }
 
 struct hw_pci __initdata dsmg600_pci = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/dsmg600-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/dsmg600-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/dsmg600-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/dsmg600-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,23 @@
 #include <asm/mach/time.h>
 #include <asm/gpio.h>
 
+#define DSMG600_SDA_PIN		5
+#define DSMG600_SCL_PIN		4
+
+/* DSM-G600 Timer Setting */
+#define DSMG600_FREQ		66000000
+
+/* Buttons */
+#define DSMG600_PB_GPIO		15	/* power button */
+#define DSMG600_RB_GPIO		3	/* reset button */
+
+/* Power control */
+#define DSMG600_PO_GPIO		2	/* power off */
+
+/* LEDs */
+#define DSMG600_LED_PWR_GPIO	0
+#define DSMG600_LED_WLAN_GPIO	14
+
 static struct flash_platform_data dsmg600_flash_data = {
 	.map_name		= "cfi_probe",
 	.width			= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/fsg-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/fsg-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/fsg-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/fsg-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,33 +19,38 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#define MAX_DEV		3
+#define IRQ_LINES	3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA	6
+#define INTB	7
+#define INTC	5
+
 void __init fsg_pci_preinit(void)
 {
-	set_irq_type(IRQ_FSG_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_FSG_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_FSG_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[FSG_PCI_IRQ_LINES] = {
-		IRQ_FSG_PCI_INTC,
-		IRQ_FSG_PCI_INTB,
-		IRQ_FSG_PCI_INTA,
+	static int pci_irq_table[IRQ_LINES] = {
+		IXP4XX_GPIO_IRQ(INTC),
+		IXP4XX_GPIO_IRQ(INTB),
+		IXP4XX_GPIO_IRQ(INTA),
 	};
 
 	int irq = -1;
-	slot = slot - 11;
+	slot -= 11;
 
-	if (slot >= 1 && slot <= FSG_PCI_MAX_DEV &&
-	    pin >= 1 && pin <= FSG_PCI_IRQ_LINES)
-		irq = pci_irq_table[(slot - 1)];
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		irq = pci_irq_table[slot - 1];
 	printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
 	       __func__, slot, pin, irq);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/fsg-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/fsg-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/fsg-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/fsg-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,12 +24,18 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/gpio.h>
 
+#define FSG_SDA_PIN		12
+#define FSG_SCL_PIN		13
+
+#define FSG_SB_GPIO		4	/* sync button */
+#define FSG_RB_GPIO		9	/* reset button */
+#define FSG_UB_GPIO		10	/* usb button */
+
 static struct flash_platform_data fsg_flash_data = {
 	.map_name		= "cfi_probe",
 	.width			= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/goramo_mlr.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/goramo_mlr.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/goramo_mlr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/goramo_mlr.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,29 +17,28 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/pci.h>
 
-#define xgpio_irq(n)		(IRQ_IXP4XX_GPIO ## n)
-#define gpio_irq(n)		xgpio_irq(n)
-
 #define SLOT_ETHA		0x0B	/* IDSEL = AD21 */
 #define SLOT_ETHB		0x0C	/* IDSEL = AD20 */
 #define SLOT_MPCI		0x0D	/* IDSEL = AD19 */
 #define SLOT_NEC		0x0E	/* IDSEL = AD18 */
 
-#define IRQ_ETHA		IRQ_IXP4XX_GPIO4
-#define IRQ_ETHB		IRQ_IXP4XX_GPIO5
-#define IRQ_NEC			IRQ_IXP4XX_GPIO3
-#define IRQ_MPCI		IRQ_IXP4XX_GPIO12
-
 /* GPIO lines */
 #define GPIO_SCL		0
 #define GPIO_SDA		1
 #define GPIO_STR		2
+#define GPIO_IRQ_NEC		3
+#define GPIO_IRQ_ETHA		4
+#define GPIO_IRQ_ETHB		5
 #define GPIO_HSS0_DCD_N		6
 #define GPIO_HSS1_DCD_N		7
+#define GPIO_UART0_DCD		8
+#define GPIO_UART1_DCD		9
 #define GPIO_HSS0_CTS_N		10
 #define GPIO_HSS1_CTS_N		11
+#define GPIO_IRQ_MPCI		12
 #define GPIO_HSS1_RTS_N		13
 #define GPIO_HSS0_RTS_N		14
+/* GPIO15 is not connected */
 
 /* Control outputs from 74HC4094 */
 #define CONTROL_HSS0_CLK_INT	0
@@ -152,7 +151,7 @@ static int hss_set_clock(int port, unsig
 
 static irqreturn_t hss_dcd_irq(int irq, void *pdev)
 {
-	int i, port = (irq == gpio_irq(GPIO_HSS1_DCD_N));
+	int i, port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
 	gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
 	set_carrier_cb_tab[port](pdev, !i);
 	return IRQ_HANDLED;
@@ -165,9 +164,9 @@ static int hss_open(int port, void *pdev
 	int i, irq;
 
 	if (!port)
-		irq = gpio_irq(GPIO_HSS0_DCD_N);
+		irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
 	else
-		irq = gpio_irq(GPIO_HSS1_DCD_N);
+		irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
 
 	gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
 	set_carrier_cb(pdev, !i);
@@ -188,8 +187,8 @@ static int hss_open(int port, void *pdev
 
 static void hss_close(int port, void *pdev)
 {
-	free_irq(port ? gpio_irq(GPIO_HSS1_DCD_N) : gpio_irq(GPIO_HSS0_DCD_N),
-		 pdev);
+	free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
+		 IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
 	set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
 
 	set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
@@ -421,8 +420,8 @@ static void __init gmlr_init(void)
 	gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
 	gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
 	gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
-	set_irq_type(gpio_irq(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
-	set_irq_type(gpio_irq(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
 
 	set_control(CONTROL_HSS0_DTR_N, 1);
 	set_control(CONTROL_HSS1_DTR_N, 1);
@@ -442,10 +441,10 @@ static void __init gmlr_init(void)
 #ifdef CONFIG_PCI
 static void __init gmlr_pci_preinit(void)
 {
-	set_irq_type(IRQ_ETHA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_ETHB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NEC, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_MPCI, IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
@@ -466,10 +465,10 @@ static void __init gmlr_pci_postinit(voi
 static int __init gmlr_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
 	switch(slot) {
-	case SLOT_ETHA:	return IRQ_ETHA;
-	case SLOT_ETHB:	return IRQ_ETHB;
-	case SLOT_NEC:	return IRQ_NEC;
-	default:	return IRQ_MPCI;
+	case SLOT_ETHA:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
+	case SLOT_ETHB:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
+	case SLOT_NEC:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
+	default:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/gtwx5715-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/gtwx5715-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,14 +26,16 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
-#include <mach/gtwx5715.h>
 #include <asm/mach/pci.h>
 
+#define SLOT0_DEVID	0
+#define SLOT1_DEVID	1
+#define INTA		10 /* slot 1 has INTA and INTB crossed */
+#define INTB		11
+
 /*
- * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
  * Slot 0 isn't actually populated with a card connector but
  * we initialize it anyway in case a future version has the
  * slot populated or someone with good soldering skills has
@@ -41,32 +43,26 @@
  */
 void __init gtwx5715_pci_preinit(void)
 {
-	set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 
 static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	int rc;
-	static int gtwx5715_irqmap
-			[GTWX5715_PCI_SLOT_COUNT]
-			[GTWX5715_PCI_INT_PIN_COUNT] = {
-	{GTWX5715_PCI_SLOT0_INTA_IRQ, GTWX5715_PCI_SLOT0_INTB_IRQ},
-	{GTWX5715_PCI_SLOT1_INTA_IRQ, GTWX5715_PCI_SLOT1_INTB_IRQ},
-};
+	int rc = -1;
 
-	if (slot >= GTWX5715_PCI_SLOT_COUNT ||
-			pin >= GTWX5715_PCI_INT_PIN_COUNT) rc = -1;
-	else
-		rc = gtwx5715_irqmap[slot][pin-1];
+	if ((slot == SLOT0_DEVID && pin == 1) ||
+	    (slot == SLOT1_DEVID && pin == 2))
+		rc = IXP4XX_GPIO_IRQ(INTA);
+	else if ((slot == SLOT0_DEVID && pin == 2) ||
+		 (slot == SLOT1_DEVID && pin == 1))
+		rc = IXP4XX_GPIO_IRQ(INTB);
 
-	printk("%s: Mapped slot %d pin %d to IRQ %d\n", __func__, slot, pin, rc);
-	return(rc);
+	printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
+	       __func__, slot, pin, rc);
+	return rc;
 }
 
 struct hw_pci gtwx5715_pci __initdata = {
@@ -81,9 +77,7 @@ struct hw_pci gtwx5715_pci __initdata =
 int __init gtwx5715_pci_init(void)
 {
 	if (machine_is_gtwx5715())
-	{
 		pci_common_init(&gtwx5715_pci);
-	}
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/gtwx5715-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,6 @@
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/slab.h>
-
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -37,7 +36,34 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <mach/gtwx5715.h>
+
+/* GPIO 5,6,7 and 12 are hard wired to the Kendin KS8995M Switch
+   and operate as an SPI type interface.  The details of the interface
+   are available on Kendin/Micrel's web site. */
+
+#define GTWX5715_KSSPI_SELECT	5
+#define GTWX5715_KSSPI_TXD	6
+#define GTWX5715_KSSPI_CLOCK	7
+#define GTWX5715_KSSPI_RXD	12
+
+/* The "reset" button is wired to GPIO 3.
+   The GPIO is brought "low" when the button is pushed. */
+
+#define GTWX5715_BUTTON_GPIO	3
+
+/* Board Label      Front Label
+   LED1             Power
+   LED2             Wireless-G
+   LED3             not populated but could be
+   LED4             Internet
+   LED5 - LED8      Controlled by KS8995M Switch
+   LED9             DMZ */
+
+#define GTWX5715_LED1_GPIO	2
+#define GTWX5715_LED2_GPIO	9
+#define GTWX5715_LED3_GPIO	8
+#define GTWX5715_LED4_GPIO	1
+#define GTWX5715_LED9_GPIO	4
 
 /*
  * Xscale UART registers are 32 bits wide with only the least
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/avila.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/avila.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/avila.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/avila.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/avila.h
- *
- * Gateworks Avila platform specific definitions
- *
- * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
- *
- * Based on ixdp425.h
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define	AVILA_SDA_PIN		7
-#define	AVILA_SCL_PIN		6
-
-/*
- * AVILA PCI IRQs
- */
-#define AVILA_PCI_MAX_DEV	4
-#define LOFT_PCI_MAX_DEV    6
-#define AVILA_PCI_IRQ_LINES	4
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define AVILA_PCI_INTA_PIN	11
-#define AVILA_PCI_INTB_PIN	10
-#define AVILA_PCI_INTC_PIN	9
-#define AVILA_PCI_INTD_PIN	8
-
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/coyote.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/coyote.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/coyote.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/coyote.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/coyote.h
- *
- * ADI Engineering platform specific definitions
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define	COYOTE_PCI_SLOT0_PIN	6
-#define	COYOTE_PCI_SLOT1_PIN	11
-
-#define	COYOTE_PCI_SLOT0_DEVID	14
-#define	COYOTE_PCI_SLOT1_DEVID	15
-
-#define	COYOTE_IDE_BASE_PHYS	IXP4XX_EXP_BUS_BASE(3)
-#define	COYOTE_IDE_BASE_VIRT	0xFFFE1000
-#define	COYOTE_IDE_REGION_SIZE	0x1000
-
-#define	COYOTE_IDE_DATA_PORT	0xFFFE10E0
-#define	COYOTE_IDE_CTRL_PORT	0xFFFE10FC
-#define	COYOTE_IDE_ERROR_PORT	0xFFFE10E2
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/dsmg600.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/dsmg600.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/dsmg600.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/dsmg600.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * DSM-G600 platform specific definitions
- *
- * Copyright (C) 2006 Tower Technologies
- * Author: Alessandro Zummo <a.zummo@towertech.it>
- *
- * based on ixdp425.h:
- *	Copyright 2004 (C) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define DSMG600_SDA_PIN		5
-#define DSMG600_SCL_PIN		4
-
-/*
- * DSMG600 PCI IRQs
- */
-#define DSMG600_PCI_MAX_DEV	4
-#define DSMG600_PCI_IRQ_LINES	3
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define DSMG600_PCI_INTA_PIN	11
-#define DSMG600_PCI_INTB_PIN	10
-#define DSMG600_PCI_INTC_PIN	9
-#define DSMG600_PCI_INTD_PIN	8
-#define DSMG600_PCI_INTE_PIN	7
-#define DSMG600_PCI_INTF_PIN	6
-
-/* DSM-G600 Timer Setting */
-#define DSMG600_FREQ 66000000
-
-/* Buttons */
-
-#define DSMG600_PB_GPIO		15	/* power button */
-#define DSMG600_RB_GPIO		3	/* reset button */
-
-/* Power control */
-
-#define DSMG600_PO_GPIO		2	/* power off */
-
-/* LEDs */
-
-#define DSMG600_LED_PWR_GPIO	0
-#define DSMG600_LED_WLAN_GPIO	14
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/fsg.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/fsg.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/fsg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/fsg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/fsg.h
- *
- * Freecom FSG-3 platform specific definitions
- *
- * Author: Rod Whitby <rod@whitby.id.au>
- * Author: Tomasz Chmielewski <mangoo@wpkg.org>
- * Maintainers: http://www.nslu2-linux.org
- *
- * Based on coyote.h by
- * Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define FSG_SDA_PIN		12
-#define FSG_SCL_PIN		13
-
-/*
- * FSG PCI IRQs
- */
-#define FSG_PCI_MAX_DEV		3
-#define FSG_PCI_IRQ_LINES	3
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define FSG_PCI_INTA_PIN	6
-#define FSG_PCI_INTB_PIN	7
-#define FSG_PCI_INTC_PIN	5
-
-/* Buttons */
-
-#define FSG_SB_GPIO		4	/* sync button */
-#define FSG_RB_GPIO		9	/* reset button */
-#define FSG_UB_GPIO		10	/* usb button */
-
-/* LEDs */
-
-#define FSG_LED_WLAN_BIT	0
-#define FSG_LED_WAN_BIT		1
-#define FSG_LED_SATA_BIT	2
-#define FSG_LED_USB_BIT		4
-#define FSG_LED_RING_BIT	5
-#define FSG_LED_SYNC_BIT	7
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ static inline void gpio_set_value(unsign
 #include <asm-generic/gpio.h>			/* cansleep wrappers */
 
 extern int gpio_to_irq(int gpio);
-extern int irq_to_gpio(int gpio);
+extern int irq_to_gpio(unsigned int irq);
 
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/gtwx5715.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/gtwx5715.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/gtwx5715.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/gtwx5715.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/gtwx5715.h
- *
- * Gemtek GTWX5715 Gateway (Linksys WRV54G)
- *
- * Copyright 2004 (c) George T. Joseph
- *
- * 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_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-#include "irqs.h"
-
-#define GTWX5715_GPIO0	0
-#define GTWX5715_GPIO1	1
-#define GTWX5715_GPIO2	2
-#define GTWX5715_GPIO3	3
-#define GTWX5715_GPIO4	4
-#define GTWX5715_GPIO5	5
-#define GTWX5715_GPIO6	6
-#define GTWX5715_GPIO7	7
-#define GTWX5715_GPIO8	8
-#define GTWX5715_GPIO9	9
-#define GTWX5715_GPIO10	10
-#define GTWX5715_GPIO11	11
-#define GTWX5715_GPIO12	12
-#define GTWX5715_GPIO13	13
-#define GTWX5715_GPIO14	14
-
-#define GTWX5715_GPIO0_IRQ			IRQ_IXP4XX_GPIO0
-#define GTWX5715_GPIO1_IRQ			IRQ_IXP4XX_GPIO1
-#define GTWX5715_GPIO2_IRQ			IRQ_IXP4XX_GPIO2
-#define GTWX5715_GPIO3_IRQ			IRQ_IXP4XX_GPIO3
-#define GTWX5715_GPIO4_IRQ			IRQ_IXP4XX_GPIO4
-#define GTWX5715_GPIO5_IRQ			IRQ_IXP4XX_GPIO5
-#define GTWX5715_GPIO6_IRQ			IRQ_IXP4XX_GPIO6
-#define GTWX5715_GPIO7_IRQ			IRQ_IXP4XX_GPIO7
-#define GTWX5715_GPIO8_IRQ			IRQ_IXP4XX_GPIO8
-#define GTWX5715_GPIO9_IRQ			IRQ_IXP4XX_GPIO9
-#define GTWX5715_GPIO10_IRQ		IRQ_IXP4XX_GPIO10
-#define GTWX5715_GPIO11_IRQ		IRQ_IXP4XX_GPIO11
-#define GTWX5715_GPIO12_IRQ		IRQ_IXP4XX_GPIO12
-#define GTWX5715_GPIO13_IRQ		IRQ_IXP4XX_SW_INT1
-#define GTWX5715_GPIO14_IRQ		IRQ_IXP4XX_SW_INT2
-
-/* PCI controller GPIO to IRQ pin mappings
-
-			INTA	INTB
-SLOT 0	10		11
-SLOT 1	11		10
-
-*/
-
-#define	GTWX5715_PCI_SLOT0_DEVID	0
-#define	GTWX5715_PCI_SLOT0_INTA_GPIO	GTWX5715_GPIO10
-#define	GTWX5715_PCI_SLOT0_INTB_GPIO	GTWX5715_GPIO11
-#define	GTWX5715_PCI_SLOT0_INTA_IRQ	GTWX5715_GPIO10_IRQ
-#define	GTWX5715_PCI_SLOT0_INTB_IRQ	GTWX5715_GPIO11_IRQ
-
-#define	GTWX5715_PCI_SLOT1_DEVID	1
-#define	GTWX5715_PCI_SLOT1_INTA_GPIO	GTWX5715_GPIO11
-#define	GTWX5715_PCI_SLOT1_INTB_GPIO	GTWX5715_GPIO10
-#define	GTWX5715_PCI_SLOT1_INTA_IRQ	GTWX5715_GPIO11_IRQ
-#define	GTWX5715_PCI_SLOT1_INTB_IRQ	GTWX5715_GPIO10_IRQ
-
-#define GTWX5715_PCI_SLOT_COUNT			2
-#define GTWX5715_PCI_INT_PIN_COUNT		2
-
-/*
- * GPIO 5,6,7 and12 are hard wired to the Kendin KS8995M Switch
- * and operate as an SPI type interface.  The details of the interface
- * are available on Kendin/Micrel's web site.
- */
-
-#define GTWX5715_KSSPI_SELECT	GTWX5715_GPIO5
-#define GTWX5715_KSSPI_TXD		GTWX5715_GPIO6
-#define GTWX5715_KSSPI_CLOCK	GTWX5715_GPIO7
-#define GTWX5715_KSSPI_RXD		GTWX5715_GPIO12
-
-/*
- * The "reset" button is wired to GPIO 3.
- * The GPIO is brought "low" when the button is pushed.
- */
-
-#define GTWX5715_BUTTON_GPIO	GTWX5715_GPIO3
-#define GTWX5715_BUTTON_IRQ	GTWX5715_GPIO3_IRQ
-
-/*
- *  Board Label      Front Label
- *  LED1             Power
- *  LED2             Wireless-G
- *  LED3             not populated but could be
- *  LED4             Internet
- *  LED5 - LED8      Controlled by KS8995M Switch
- *  LED9             DMZ
- */
-
-#define GTWX5715_LED1_GPIO		GTWX5715_GPIO2
-#define GTWX5715_LED2_GPIO		GTWX5715_GPIO9
-#define GTWX5715_LED3_GPIO		GTWX5715_GPIO8
-#define GTWX5715_LED4_GPIO		GTWX5715_GPIO1
-#define GTWX5715_LED9_GPIO		GTWX5715_GPIO4
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,13 @@
 #define __ASM_ARCH_HARDWARE_H__
 
 #define PCIBIOS_MIN_IO		0x00001000
-#define PCIBIOS_MIN_MEM		(cpu_is_ixp43x() ? 0x40000000 : 0x48000000)
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+#define PCIBIOS_MIN_MEM		0x10000000 /* 1 GB of indirect PCI MMIO space */
+#define PCIBIOS_MAX_MEM		0x4FFFFFFF
+#else
+#define PCIBIOS_MIN_MEM		0x48000000 /* 64 MB of PCI MMIO space */
+#define PCIBIOS_MAX_MEM		0x4BFFFFFF
+#endif
 
 /*
  * We override the standard dma-mask routines for bouncing.
@@ -37,14 +43,4 @@
 /* Platform helper functions and definitions */
 #include "platform.h"
 
-/* Platform specific details */
-#include "ixdp425.h"
-#include "avila.h"
-#include "coyote.h"
-#include "prpmc1100.h"
-#include "nslu2.h"
-#include "nas100d.h"
-#include "dsmg600.h"
-#include "fsg.h"
-
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,22 +26,20 @@ extern int ixp4xx_pci_write(u32 addr, u3
 /*
  * IXP4xx provides two methods of accessing PCI memory space:
  *
- * 1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
+ * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
  *    To access PCI via this space, we simply ioremap() the BAR
  *    into the kernel and we can use the standard read[bwl]/write[bwl]
  *    macros. This is the preffered method due to speed but it
- *    limits the system to just 64MB of PCI memory. This can be 
- *    problamatic if using video cards and other memory-heavy
- *    targets.
- *
- * 2) If > 64MB of memory space is required, the IXP4xx can be configured
- *    to use indirect registers to access PCI (as we do below for I/O
- *    transactions). This allows for up to 128MB (0x48000000 to 0x4fffffff)
- *    of memory on the bus. The disadvantage of this is that every 
- *    PCI access requires three local register accesses plus a spinlock,
- *    but in some cases the performance hit is acceptable. In addition,
- *    you cannot mmap() PCI devices in this case.
+ *    limits the system to just 64MB of PCI memory. This can be
+ *    problematic if using video cards and other memory-heavy targets.
  *
+ * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
+ *    registers to access the whole 4 GB of PCI memory space (as we do below
+ *    for I/O transactions). This allows currently for up to 1 GB (0x10000000
+ *    to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
+ *    every PCI access requires three local register accesses plus a spinlock,
+ *    but in some cases the performance hit is acceptable. In addition, you
+ *    cannot mmap() PCI devices in this case.
  */
 #ifndef	CONFIG_IXP4XX_INDIRECT_PCI
 
@@ -55,48 +53,52 @@ extern int ixp4xx_pci_write(u32 addr, u3
  * access registers. If something outside of PCI is ioremap'd, we
  * fallback to the default.
  */
-static inline void __iomem *
-__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype)
+
+static inline int is_pci_memory(u32 addr)
 {
-	if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff))
+	return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF);
+}
+
+static inline void __iomem * __indirect_ioremap(unsigned long addr, size_t size,
+						unsigned int mtype)
+{
+	if (!is_pci_memory(addr))
 		return __arm_ioremap(addr, size, mtype);
 
 	return (void __iomem *)addr;
 }
 
-static inline void
-__ixp4xx_iounmap(void __iomem *addr)
+static inline void __indirect_iounmap(void __iomem *addr)
 {
-	if ((__force u32)addr >= VMALLOC_START)
+	if (!is_pci_memory((__force u32)addr))
 		__iounmap(addr);
 }
 
-#define __arch_ioremap(a, s, f)		__ixp4xx_ioremap(a, s, f)
-#define	__arch_iounmap(a)		__ixp4xx_iounmap(a)
+#define __arch_ioremap(a, s, f)		__indirect_ioremap(a, s, f)
+#define __arch_iounmap(a)		__indirect_iounmap(a)
 
-#define	writeb(v, p)			__ixp4xx_writeb(v, p)
-#define	writew(v, p)			__ixp4xx_writew(v, p)
-#define	writel(v, p)			__ixp4xx_writel(v, p)
+#define writeb(v, p)			__indirect_writeb(v, p)
+#define writew(v, p)			__indirect_writew(v, p)
+#define writel(v, p)			__indirect_writel(v, p)
 
-#define	writesb(p, v, l)		__ixp4xx_writesb(p, v, l)
-#define	writesw(p, v, l)		__ixp4xx_writesw(p, v, l)
-#define	writesl(p, v, l)		__ixp4xx_writesl(p, v, l)
-	
-#define	readb(p)			__ixp4xx_readb(p)
-#define	readw(p)			__ixp4xx_readw(p)
-#define	readl(p)			__ixp4xx_readl(p)
-	
-#define	readsb(p, v, l)			__ixp4xx_readsb(p, v, l)
-#define	readsw(p, v, l)			__ixp4xx_readsw(p, v, l)
-#define	readsl(p, v, l)			__ixp4xx_readsl(p, v, l)
+#define writesb(p, v, l)		__indirect_writesb(p, v, l)
+#define writesw(p, v, l)		__indirect_writesw(p, v, l)
+#define writesl(p, v, l)		__indirect_writesl(p, v, l)
 
-static inline void 
-__ixp4xx_writeb(u8 value, volatile void __iomem *p)
+#define readb(p)			__indirect_readb(p)
+#define readw(p)			__indirect_readw(p)
+#define readl(p)			__indirect_readl(p)
+
+#define readsb(p, v, l)			__indirect_readsb(p, v, l)
+#define readsw(p, v, l)			__indirect_readsw(p, v, l)
+#define readsl(p, v, l)			__indirect_readsl(p, v, l)
+
+static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
 {
 	u32 addr = (u32)p;
 	u32 n, byte_enables, data;
 
-	if (addr >= VMALLOC_START) {
+	if (!is_pci_memory(addr)) {
 		__raw_writeb(value, addr);
 		return;
 	}
@@ -107,20 +109,19 @@ __ixp4xx_writeb(u8 value, volatile void
 	ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
 }
 
-static inline void
-__ixp4xx_writesb(volatile void __iomem *bus_addr, const u8 *vaddr, int count)
+static inline void __indirect_writesb(volatile void __iomem *bus_addr,
+				      const u8 *vaddr, int count)
 {
 	while (count--)
 		writeb(*vaddr++, bus_addr);
 }
 
-static inline void 
-__ixp4xx_writew(u16 value, volatile void __iomem *p)
+static inline void __indirect_writew(u16 value, volatile void __iomem *p)
 {
 	u32 addr = (u32)p;
 	u32 n, byte_enables, data;
 
-	if (addr >= VMALLOC_START) {
+	if (!is_pci_memory(addr)) {
 		__raw_writew(value, addr);
 		return;
 	}
@@ -131,18 +132,18 @@ __ixp4xx_writew(u16 value, volatile void
 	ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
 }
 
-static inline void
-__ixp4xx_writesw(volatile void __iomem *bus_addr, const u16 *vaddr, int count)
+static inline void __indirect_writesw(volatile void __iomem *bus_addr,
+				      const u16 *vaddr, int count)
 {
 	while (count--)
 		writew(*vaddr++, bus_addr);
 }
 
-static inline void 
-__ixp4xx_writel(u32 value, volatile void __iomem *p)
+static inline void __indirect_writel(u32 value, volatile void __iomem *p)
 {
 	u32 addr = (__force u32)p;
-	if (addr >= VMALLOC_START) {
+
+	if (!is_pci_memory(addr)) {
 		__raw_writel(value, p);
 		return;
 	}
@@ -150,20 +151,19 @@ __ixp4xx_writel(u32 value, volatile void
 	ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
 }
 
-static inline void
-__ixp4xx_writesl(volatile void __iomem *bus_addr, const u32 *vaddr, int count)
+static inline void __indirect_writesl(volatile void __iomem *bus_addr,
+				      const u32 *vaddr, int count)
 {
 	while (count--)
 		writel(*vaddr++, bus_addr);
 }
 
-static inline unsigned char 
-__ixp4xx_readb(const volatile void __iomem *p)
+static inline unsigned char __indirect_readb(const volatile void __iomem *p)
 {
 	u32 addr = (u32)p;
 	u32 n, byte_enables, data;
 
-	if (addr >= VMALLOC_START)
+	if (!is_pci_memory(addr))
 		return __raw_readb(addr);
 
 	n = addr % 4;
@@ -174,20 +174,19 @@ __ixp4xx_readb(const volatile void __iom
 	return data >> (8*n);
 }
 
-static inline void
-__ixp4xx_readsb(const volatile void __iomem *bus_addr, u8 *vaddr, u32 count)
+static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
+				     u8 *vaddr, u32 count)
 {
 	while (count--)
 		*vaddr++ = readb(bus_addr);
 }
 
-static inline unsigned short 
-__ixp4xx_readw(const volatile void __iomem *p)
+static inline unsigned short __indirect_readw(const volatile void __iomem *p)
 {
 	u32 addr = (u32)p;
 	u32 n, byte_enables, data;
 
-	if (addr >= VMALLOC_START)
+	if (!is_pci_memory(addr))
 		return __raw_readw(addr);
 
 	n = addr % 4;
@@ -198,20 +197,19 @@ __ixp4xx_readw(const volatile void __iom
 	return data>>(8*n);
 }
 
-static inline void 
-__ixp4xx_readsw(const volatile void __iomem *bus_addr, u16 *vaddr, u32 count)
+static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
+				     u16 *vaddr, u32 count)
 {
 	while (count--)
 		*vaddr++ = readw(bus_addr);
 }
 
-static inline unsigned long 
-__ixp4xx_readl(const volatile void __iomem *p)
+static inline unsigned long __indirect_readl(const volatile void __iomem *p)
 {
 	u32 addr = (__force u32)p;
 	u32 data;
 
-	if (addr >= VMALLOC_START)
+	if (!is_pci_memory(addr))
 		return __raw_readl(p);
 
 	if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
@@ -220,8 +218,8 @@ __ixp4xx_readl(const volatile void __iom
 	return data;
 }
 
-static inline void 
-__ixp4xx_readsl(const volatile void __iomem *bus_addr, u32 *vaddr, u32 count)
+static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
+				     u32 *vaddr, u32 count)
 {
 	while (count--)
 		*vaddr++ = readl(bus_addr);
@@ -235,7 +233,7 @@ __ixp4xx_readsl(const volatile void __io
 #define memcpy_fromio(a,c,l)		_memcpy_fromio((a),(c),(l))
 #define memcpy_toio(c,a,l)		_memcpy_toio((c),(a),(l))
 
-#endif
+#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
 
 #ifndef CONFIG_PCI
 
@@ -250,25 +248,8 @@ __ixp4xx_readsl(const volatile void __io
  * transaction.  This means that we need to override the default
  * I/O functions.
  */
-#define	outb(p, v)			__ixp4xx_outb(p, v)
-#define	outw(p, v)			__ixp4xx_outw(p, v)
-#define	outl(p, v)			__ixp4xx_outl(p, v)
-	
-#define	outsb(p, v, l)			__ixp4xx_outsb(p, v, l)
-#define	outsw(p, v, l)			__ixp4xx_outsw(p, v, l)
-#define	outsl(p, v, l)			__ixp4xx_outsl(p, v, l)
 
-#define	inb(p)				__ixp4xx_inb(p)
-#define	inw(p)				__ixp4xx_inw(p)
-#define	inl(p)				__ixp4xx_inl(p)
-
-#define	insb(p, v, l)			__ixp4xx_insb(p, v, l)
-#define	insw(p, v, l)			__ixp4xx_insw(p, v, l)
-#define	insl(p, v, l)			__ixp4xx_insl(p, v, l)
-
-
-static inline void 
-__ixp4xx_outb(u8 value, u32 addr)
+static inline void outb(u8 value, u32 addr)
 {
 	u32 n, byte_enables, data;
 	n = addr % 4;
@@ -277,15 +258,13 @@ __ixp4xx_outb(u8 value, u32 addr)
 	ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 }
 
-static inline void 
-__ixp4xx_outsb(u32 io_addr, const u8 *vaddr, u32 count)
+static inline void outsb(u32 io_addr, const u8 *vaddr, u32 count)
 {
 	while (count--)
 		outb(*vaddr++, io_addr);
 }
 
-static inline void 
-__ixp4xx_outw(u16 value, u32 addr)
+static inline void outw(u16 value, u32 addr)
 {
 	u32 n, byte_enables, data;
 	n = addr % 4;
@@ -294,28 +273,24 @@ __ixp4xx_outw(u16 value, u32 addr)
 	ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
 }
 
-static inline void 
-__ixp4xx_outsw(u32 io_addr, const u16 *vaddr, u32 count)
+static inline void outsw(u32 io_addr, const u16 *vaddr, u32 count)
 {
 	while (count--)
 		outw(cpu_to_le16(*vaddr++), io_addr);
 }
 
-static inline void 
-__ixp4xx_outl(u32 value, u32 addr)
+static inline void outl(u32 value, u32 addr)
 {
 	ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
 }
 
-static inline void 
-__ixp4xx_outsl(u32 io_addr, const u32 *vaddr, u32 count)
+static inline void outsl(u32 io_addr, const u32 *vaddr, u32 count)
 {
 	while (count--)
-		outl(*vaddr++, io_addr);
+		outl(cpu_to_le32(*vaddr++), io_addr);
 }
 
-static inline u8 
-__ixp4xx_inb(u32 addr)
+static inline u8 inb(u32 addr)
 {
 	u32 n, byte_enables, data;
 	n = addr % 4;
@@ -326,15 +301,13 @@ __ixp4xx_inb(u32 addr)
 	return data >> (8*n);
 }
 
-static inline void 
-__ixp4xx_insb(u32 io_addr, u8 *vaddr, u32 count)
+static inline void insb(u32 io_addr, u8 *vaddr, u32 count)
 {
 	while (count--)
 		*vaddr++ = inb(io_addr);
 }
 
-static inline u16 
-__ixp4xx_inw(u32 addr)
+static inline u16 inw(u32 addr)
 {
 	u32 n, byte_enables, data;
 	n = addr % 4;
@@ -345,15 +318,13 @@ __ixp4xx_inw(u32 addr)
 	return data>>(8*n);
 }
 
-static inline void 
-__ixp4xx_insw(u32 io_addr, u16 *vaddr, u32 count)
+static inline void insw(u32 io_addr, u16 *vaddr, u32 count)
 {
 	while (count--)
 		*vaddr++ = le16_to_cpu(inw(io_addr));
 }
 
-static inline u32 
-__ixp4xx_inl(u32 addr)
+static inline u32 inl(u32 addr)
 {
 	u32 data;
 	if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
@@ -362,11 +333,10 @@ __ixp4xx_inl(u32 addr)
 	return data;
 }
 
-static inline void 
-__ixp4xx_insl(u32 io_addr, u32 *vaddr, u32 count)
+static inline void insl(u32 io_addr, u32 *vaddr, u32 count)
 {
 	while (count--)
-		*vaddr++ = inl(io_addr);
+		*vaddr++ = le32_to_cpu(inl(io_addr));
 }
 
 #define PIO_OFFSET      0x10000UL
@@ -374,194 +344,183 @@ __ixp4xx_insl(u32 io_addr, u32 *vaddr, u
 
 #define	__is_io_address(p)	(((unsigned long)p >= PIO_OFFSET) && \
 					((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
-static inline unsigned int
-__ixp4xx_ioread8(const void __iomem *addr)
+
+#define	ioread8(p)			ioread8(p)
+static inline unsigned int ioread8(const void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		return	(unsigned int)__ixp4xx_inb(port & PIO_MASK);
+		return (unsigned int)inb(port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		return (unsigned int)__raw_readb(port);
 #else
-		return (unsigned int)__ixp4xx_readb(addr);
+		return (unsigned int)__indirect_readb(addr);
 #endif
 }
 
-static inline void
-__ixp4xx_ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
+#define	ioread8_rep(p, v, c)		ioread8_rep(p, v, c)
+static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_insb(port & PIO_MASK, vaddr, count);
+		insb(port & PIO_MASK, vaddr, count);
 	else
 #ifndef	CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_readsb(addr, vaddr, count);
 #else
-		__ixp4xx_readsb(addr, vaddr, count);
+		__indirect_readsb(addr, vaddr, count);
 #endif
 }
 
-static inline unsigned int
-__ixp4xx_ioread16(const void __iomem *addr)
+#define	ioread16(p)			ioread16(p)
+static inline unsigned int ioread16(const void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		return	(unsigned int)__ixp4xx_inw(port & PIO_MASK);
+		return	(unsigned int)inw(port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		return le16_to_cpu(__raw_readw((u32)port));
 #else
-		return (unsigned int)__ixp4xx_readw(addr);
+		return (unsigned int)__indirect_readw(addr);
 #endif
 }
 
-static inline void
-__ixp4xx_ioread16_rep(const void __iomem *addr, void *vaddr, u32 count)
+#define	ioread16_rep(p, v, c)		ioread16_rep(p, v, c)
+static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
+				u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_insw(port & PIO_MASK, vaddr, count);
+		insw(port & PIO_MASK, vaddr, count);
 	else
 #ifndef	CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_readsw(addr, vaddr, count);
 #else
-		__ixp4xx_readsw(addr, vaddr, count);
+		__indirect_readsw(addr, vaddr, count);
 #endif
 }
 
-static inline unsigned int
-__ixp4xx_ioread32(const void __iomem *addr)
+#define	ioread32(p)			ioread32(p)
+static inline unsigned int ioread32(const void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		return	(unsigned int)__ixp4xx_inl(port & PIO_MASK);
+		return	(unsigned int)inl(port & PIO_MASK);
 	else {
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		return le32_to_cpu((__force __le32)__raw_readl(addr));
 #else
-		return (unsigned int)__ixp4xx_readl(addr);
+		return (unsigned int)__indirect_readl(addr);
 #endif
 	}
 }
 
-static inline void
-__ixp4xx_ioread32_rep(const void __iomem *addr, void *vaddr, u32 count)
+#define	ioread32_rep(p, v, c)		ioread32_rep(p, v, c)
+static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
+				u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_insl(port & PIO_MASK, vaddr, count);
+		insl(port & PIO_MASK, vaddr, count);
 	else
 #ifndef	CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_readsl(addr, vaddr, count);
 #else
-		__ixp4xx_readsl(addr, vaddr, count);
+		__indirect_readsl(addr, vaddr, count);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite8(u8 value, void __iomem *addr)
+#define	iowrite8(v, p)			iowrite8(v, p)
+static inline void iowrite8(u8 value, void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outb(value, port & PIO_MASK);
+		outb(value, port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writeb(value, port);
 #else
-		__ixp4xx_writeb(value, addr);
+		__indirect_writeb(value, addr);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite8_rep(void __iomem *addr, const void *vaddr, u32 count)
+#define	iowrite8_rep(p, v, c)		iowrite8_rep(p, v, c)
+static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
+				u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outsb(port & PIO_MASK, vaddr, count);
+		outsb(port & PIO_MASK, vaddr, count);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writesb(addr, vaddr, count);
 #else
-		__ixp4xx_writesb(addr, vaddr, count);
+		__indirect_writesb(addr, vaddr, count);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite16(u16 value, void __iomem *addr)
+#define	iowrite16(v, p)			iowrite16(v, p)
+static inline void iowrite16(u16 value, void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outw(value, port & PIO_MASK);
+		outw(value, port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writew(cpu_to_le16(value), addr);
 #else
-		__ixp4xx_writew(value, addr);
+		__indirect_writew(value, addr);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite16_rep(void __iomem *addr, const void *vaddr, u32 count)
+#define	iowrite16_rep(p, v, c)		iowrite16_rep(p, v, c)
+static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
+				 u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outsw(port & PIO_MASK, vaddr, count);
+		outsw(port & PIO_MASK, vaddr, count);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writesw(addr, vaddr, count);
 #else
-		__ixp4xx_writesw(addr, vaddr, count);
+		__indirect_writesw(addr, vaddr, count);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite32(u32 value, void __iomem *addr)
+#define	iowrite32(v, p)			iowrite32(v, p)
+static inline void iowrite32(u32 value, void __iomem *addr)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outl(value, port & PIO_MASK);
+		outl(value, port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writel((u32 __force)cpu_to_le32(value), addr);
 #else
-		__ixp4xx_writel(value, addr);
+		__indirect_writel(value, addr);
 #endif
 }
 
-static inline void
-__ixp4xx_iowrite32_rep(void __iomem *addr, const void *vaddr, u32 count)
+#define	iowrite32_rep(p, v, c)		iowrite32_rep(p, v, c)
+static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
+				 u32 count)
 {
 	unsigned long port = (unsigned long __force)addr;
 	if (__is_io_address(port))
-		__ixp4xx_outsl(port & PIO_MASK, vaddr, count);
+		outsl(port & PIO_MASK, vaddr, count);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
 		__raw_writesl(addr, vaddr, count);
 #else
-		__ixp4xx_writesl(addr, vaddr, count);
+		__indirect_writesl(addr, vaddr, count);
 #endif
 }
 
-#define	ioread8(p)			__ixp4xx_ioread8(p)
-#define	ioread16(p)			__ixp4xx_ioread16(p)
-#define	ioread32(p)			__ixp4xx_ioread32(p)
-
-#define	ioread8_rep(p, v, c)		__ixp4xx_ioread8_rep(p, v, c)
-#define	ioread16_rep(p, v, c)		__ixp4xx_ioread16_rep(p, v, c)
-#define	ioread32_rep(p, v, c)		__ixp4xx_ioread32_rep(p, v, c)
-
-#define	iowrite8(v,p)			__ixp4xx_iowrite8(v,p)
-#define	iowrite16(v,p)			__ixp4xx_iowrite16(v,p)
-#define	iowrite32(v,p)			__ixp4xx_iowrite32(v,p)
-
-#define	iowrite8_rep(p, v, c)		__ixp4xx_iowrite8_rep(p, v, c)
-#define	iowrite16_rep(p, v, c)		__ixp4xx_iowrite16_rep(p, v, c)
-#define	iowrite32_rep(p, v, c)		__ixp4xx_iowrite32_rep(p, v, c)
-
 #define	ioport_map(port, nr)		((void __iomem*)(port + PIO_OFFSET))
 #define	ioport_unmap(addr)
-#endif	// !CONFIG_PCI
-
-#endif	//  __ASM_ARM_ARCH_IO_H
+#endif /* CONFIG_PCI */
 
+#endif /* __ASM_ARM_ARCH_IO_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,6 @@
 #ifndef _ARCH_IXP4XX_IRQS_H_
 #define _ARCH_IXP4XX_IRQS_H_
 
-
 #define IRQ_IXP4XX_NPEA		0
 #define IRQ_IXP4XX_NPEB		1
 #define IRQ_IXP4XX_NPEC		2
@@ -59,6 +58,9 @@
 #define IRQ_IXP4XX_MCU_ECC	61
 #define IRQ_IXP4XX_EXP_PE	62
 
+#define _IXP4XX_GPIO_IRQ(n)	(IRQ_IXP4XX_GPIO ## n)
+#define IXP4XX_GPIO_IRQ(n)	_IXP4XX_GPIO_IRQ(n)
+
 /*
  * Only first 32 sources are valid if running on IXP42x systems
  */
@@ -70,69 +72,4 @@
 
 #define	XSCALE_PMU_IRQ		(IRQ_IXP4XX_XSCALE_PMU)
 
-/*
- * IXDP425 board IRQs
- */
-#define	IRQ_IXDP425_PCI_INTA	IRQ_IXP4XX_GPIO11
-#define	IRQ_IXDP425_PCI_INTB	IRQ_IXP4XX_GPIO10
-#define	IRQ_IXDP425_PCI_INTC	IRQ_IXP4XX_GPIO9
-#define	IRQ_IXDP425_PCI_INTD	IRQ_IXP4XX_GPIO8
-
-/*
- * Gateworks Avila board IRQs
- */
-#define	IRQ_AVILA_PCI_INTA	IRQ_IXP4XX_GPIO11
-#define	IRQ_AVILA_PCI_INTB	IRQ_IXP4XX_GPIO10
-#define	IRQ_AVILA_PCI_INTC	IRQ_IXP4XX_GPIO9
-#define	IRQ_AVILA_PCI_INTD	IRQ_IXP4XX_GPIO8
-
-
-/*
- * PrPMC1100 Board IRQs
- */
-#define	IRQ_PRPMC1100_PCI_INTA	IRQ_IXP4XX_GPIO11
-#define	IRQ_PRPMC1100_PCI_INTB	IRQ_IXP4XX_GPIO10
-#define	IRQ_PRPMC1100_PCI_INTC	IRQ_IXP4XX_GPIO9
-#define	IRQ_PRPMC1100_PCI_INTD	IRQ_IXP4XX_GPIO8
-
-/*
- * ADI Coyote Board IRQs
- */
-#define	IRQ_COYOTE_PCI_SLOT0	IRQ_IXP4XX_GPIO6
-#define	IRQ_COYOTE_PCI_SLOT1	IRQ_IXP4XX_GPIO11
-#define	IRQ_COYOTE_IDE		IRQ_IXP4XX_GPIO5
-
-/*
- * NSLU2 board IRQs
- */
-#define        IRQ_NSLU2_PCI_INTA      IRQ_IXP4XX_GPIO11
-#define        IRQ_NSLU2_PCI_INTB      IRQ_IXP4XX_GPIO10
-#define        IRQ_NSLU2_PCI_INTC      IRQ_IXP4XX_GPIO9
-
-/*
- * NAS100D board IRQs
- */
-#define        IRQ_NAS100D_PCI_INTA    IRQ_IXP4XX_GPIO11
-#define        IRQ_NAS100D_PCI_INTB    IRQ_IXP4XX_GPIO10
-#define        IRQ_NAS100D_PCI_INTC    IRQ_IXP4XX_GPIO9
-#define        IRQ_NAS100D_PCI_INTD    IRQ_IXP4XX_GPIO8
-#define        IRQ_NAS100D_PCI_INTE    IRQ_IXP4XX_GPIO7
-
-/*
- * D-Link DSM-G600 RevA board IRQs
- */
-#define        IRQ_DSMG600_PCI_INTA    IRQ_IXP4XX_GPIO11
-#define        IRQ_DSMG600_PCI_INTB    IRQ_IXP4XX_GPIO10
-#define        IRQ_DSMG600_PCI_INTC    IRQ_IXP4XX_GPIO9
-#define        IRQ_DSMG600_PCI_INTD    IRQ_IXP4XX_GPIO8
-#define        IRQ_DSMG600_PCI_INTE    IRQ_IXP4XX_GPIO7
-#define        IRQ_DSMG600_PCI_INTF    IRQ_IXP4XX_GPIO6
-
-/*
- * Freecom FSG-3 Board IRQs
- */
-#define        IRQ_FSG_PCI_INTA        IRQ_IXP4XX_GPIO6
-#define        IRQ_FSG_PCI_INTB        IRQ_IXP4XX_GPIO7
-#define        IRQ_FSG_PCI_INTC        IRQ_IXP4XX_GPIO5
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/ixdp425.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/ixdp425.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/ixdp425.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/ixdp425.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/ixdp425.h
- *
- * IXDP425 platform specific definitions
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define	IXDP425_SDA_PIN		7
-#define	IXDP425_SCL_PIN		6
-
-/*
- * IXDP425 PCI IRQs
- */
-#define IXDP425_PCI_MAX_DEV	4
-#define IXDP425_PCI_IRQ_LINES	4
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define IXDP425_PCI_INTA_PIN	11
-#define IXDP425_PCI_INTB_PIN	10
-#define	IXDP425_PCI_INTC_PIN	9
-#define	IXDP425_PCI_INTD_PIN	8
-
-/* NAND Flash pins */
-#define	IXDP425_NAND_NCE_PIN	12
-
-#define	IXDP425_NAND_CMD_BYTE	0x01
-#define	IXDP425_NAND_ADDR_BYTE	0x02
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/nas100d.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/nas100d.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/nas100d.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/nas100d.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/nas100d.h
- *
- * NAS100D platform specific definitions
- *
- * Copyright (c) 2005 Tower Technologies
- *
- * Author: Alessandro Zummo <a.zummo@towertech.it>
- *
- * based on ixdp425.h:
- *	Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define NAS100D_SDA_PIN		5
-#define NAS100D_SCL_PIN		6
-
-/*
- * NAS100D PCI IRQs
- */
-#define NAS100D_PCI_MAX_DEV	3
-#define NAS100D_PCI_IRQ_LINES	3
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define NAS100D_PCI_INTA_PIN	11
-#define NAS100D_PCI_INTB_PIN	10
-#define NAS100D_PCI_INTC_PIN	9
-#define NAS100D_PCI_INTD_PIN	8
-#define NAS100D_PCI_INTE_PIN	7
-
-/* Buttons */
-
-#define NAS100D_PB_GPIO         14   /* power button */
-#define NAS100D_RB_GPIO         4    /* reset button */
-
-/* Power control */
-
-#define NAS100D_PO_GPIO         12   /* power off */
-
-/* LEDs */
-
-#define NAS100D_LED_WLAN_GPIO	0
-#define NAS100D_LED_DISK_GPIO	3
-#define NAS100D_LED_PWR_GPIO	15
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/npe.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/npe.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/npe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/npe.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,7 @@ int npe_send_message(struct npe *npe, co
 int npe_recv_message(struct npe *npe, void *msg, const char *what);
 int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
 int npe_load_firmware(struct npe *npe, const char *name, struct device *dev);
-struct npe *npe_request(int id);
+struct npe *npe_request(unsigned id);
 void npe_release(struct npe *npe);
 
 #endif /* __IXP4XX_NPE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/nslu2.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/nslu2.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/nslu2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/nslu2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/nslu2.h
- *
- * NSLU2 platform specific definitions
- *
- * Author: Mark Rakes <mrakes AT mac.com>
- * Maintainers: http://www.nslu2-linux.org
- *
- * based on ixdp425.h:
- *	Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define NSLU2_SDA_PIN		7
-#define NSLU2_SCL_PIN		6
-
-/*
- * NSLU2 PCI IRQs
- */
-#define NSLU2_PCI_MAX_DEV	3
-#define NSLU2_PCI_IRQ_LINES	3
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define NSLU2_PCI_INTA_PIN	11
-#define NSLU2_PCI_INTB_PIN	10
-#define NSLU2_PCI_INTC_PIN	9
-#define NSLU2_PCI_INTD_PIN	8
-
-/* NSLU2 Timer */
-#define NSLU2_FREQ 66000000
-
-/* Buttons */
-
-#define NSLU2_PB_GPIO		5	/* power button */
-#define NSLU2_PO_GPIO		8	/* power off */
-#define NSLU2_RB_GPIO		12	/* reset button */
-
-/* Buzzer */
-
-#define NSLU2_GPIO_BUZZ		4
-
-/* LEDs */
-
-#define NSLU2_LED_RED_GPIO	0
-#define NSLU2_LED_GRN_GPIO	1
-#define NSLU2_LED_DISK1_GPIO	3
-#define NSLU2_LED_DISK2_GPIO	2
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/prpmc1100.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/prpmc1100.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/prpmc1100.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/prpmc1100.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/prpmc1100.h
- *
- * Motorolla PrPMC1100 platform specific definitions
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2004 (c) MontaVista, Software, 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.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#define	PRPMC1100_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define	PRPMC1100_FLASH_SIZE	IXP4XX_EXP_BUS_CSX_REGION_SIZE
-
-#define	PRPMC1100_PCI_MIN_DEVID	10
-#define	PRPMC1100_PCI_MAX_DEVID	16
-#define	PRPMC1100_PCI_IRQ_LINES	4
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define PRPMC1100_PCI_INTA_PIN	11
-#define PRPMC1100_PCI_INTB_PIN	10
-#define	PRPMC1100_PCI_INTC_PIN	9
-#define	PRPMC1100_PCI_INTD_PIN	8
-
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/include/mach/timex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,6 @@
  * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
  * timer register ignores the bottom 2 bits of the LATCH value.
  */
-#define FREQ 66666666
+#define FREQ 66666000
 #define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixdp425-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixdp425-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-ixp4xx/ixdp425-pci.c 
+ * arch/arm/mach-ixp4xx/ixdp425-pci.c
  *
  * IXDP425 board-level PCI initialization
  *
@@ -19,39 +19,43 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
-
 #include <asm/mach/pci.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#define MAX_DEV		4
+#define IRQ_LINES	4
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		11
+#define INTB		10
+#define INTC		9
+#define INTD		8
+
+
 void __init ixdp425_pci_preinit(void)
 {
-	set_irq_type(IRQ_IXDP425_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_IXDP425_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_IXDP425_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_IXDP425_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[IXDP425_PCI_IRQ_LINES] = {
-		IRQ_IXDP425_PCI_INTA,
-		IRQ_IXDP425_PCI_INTB,
-		IRQ_IXDP425_PCI_INTC,
-		IRQ_IXDP425_PCI_INTD
+	static int pci_irq_table[IRQ_LINES] = {
+		IXP4XX_GPIO_IRQ(INTA),
+		IXP4XX_GPIO_IRQ(INTB),
+		IXP4XX_GPIO_IRQ(INTC),
+		IXP4XX_GPIO_IRQ(INTD)
 	};
 
-	int irq = -1;
-
-	if (slot >= 1 && slot <= IXDP425_PCI_MAX_DEV && 
-		pin >= 1 && pin <= IXDP425_PCI_IRQ_LINES) {
-		irq = pci_irq_table[(slot + pin - 2) % 4];
-	}
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[(slot + pin - 2) % 4];
 
-	return irq;
+	return -1;
 }
 
 struct hw_pci ixdp425_pci __initdata = {
@@ -72,4 +76,3 @@ int __init ixdp425_pci_init(void)
 }
 
 subsys_initcall(ixdp425_pci_init);
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-ixp4xx/ixdp425-setup.c
  *
- * IXDP425/IXCDP1100 board-setup 
+ * IXDP425/IXCDP1100 board-setup
  *
  * Copyright (C) 2003-2005 MontaVista Software, Inc.
  *
@@ -21,7 +21,6 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
-
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -31,6 +30,15 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#define IXDP425_SDA_PIN		7
+#define IXDP425_SCL_PIN		6
+
+/* NAND Flash pins */
+#define IXDP425_NAND_NCE_PIN	12
+
+#define IXDP425_NAND_CMD_BYTE	0x01
+#define IXDP425_NAND_ADDR_BYTE	0x02
+
 static struct flash_platform_data ixdp425_flash_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 13:54:55.000000000 -0400
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 12:02:43.000000000 -0400
@@ -665,7 +665,7 @@ err:
 }
 
 
-struct npe *npe_request(int id)
+struct npe *npe_request(unsigned id)
 {
 	if (id < NPE_COUNT)
 		if (npe_tab[id].valid)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -179,21 +179,21 @@ config IXP4XX_INDIRECT_PCI
 	help
           IXP4xx provides two methods of accessing PCI memory space:
 
-          1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
+          1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
              To access PCI via this space, we simply ioremap() the BAR
              into the kernel and we can use the standard read[bwl]/write[bwl]
              macros. This is the preferred method due to speed but it
-             limits the system to just 64MB of PCI memory. This can be 
+             limits the system to just 64MB of PCI memory. This can be
              problematic if using video cards and other memory-heavy devices.
-          
-          2) If > 64MB of memory space is required, the IXP4xx can be 
-	     configured to use indirect registers to access PCI This allows 
-	     for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus. 
-	     The disadvantage of this is that every PCI access requires 
-	     three local register accesses plus a spinlock, but in some 
-	     cases the performance hit is acceptable. In addition, you cannot 
-	     mmap() PCI devices in this case due to the indirect nature
-	     of the PCI window.
+
+	  2) If > 64MB of memory space is required, the IXP4xx can be
+	     configured to use indirect registers to access the whole PCI
+	     memory space. This currently allows for up to 1 GB (0x10000000
+	     to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
+	     is that every PCI access requires three local register accesses
+	     plus a spinlock, but in some cases the performance hit is
+	     acceptable. In addition, you cannot mmap() PCI devices in this
+	     case due to the indirect nature of the PCI window.
 
 	  By default, the direct method is used. Choose this option if you
 	  need to use the indirect method instead. If you don't know
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nas100d-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nas100d-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nas100d-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nas100d-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,37 +18,42 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#define MAX_DEV		3
+#define IRQ_LINES	3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		11
+#define INTB		10
+#define INTC		9
+#define INTD		8
+#define INTE		7
+
 void __init nas100d_pci_preinit(void)
 {
-	set_irq_type(IRQ_NAS100D_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NAS100D_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NAS100D_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NAS100D_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NAS100D_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[NAS100D_PCI_MAX_DEV][NAS100D_PCI_IRQ_LINES] =
-	{
-		{ IRQ_NAS100D_PCI_INTA, -1, -1 },
-		{ IRQ_NAS100D_PCI_INTB, -1, -1 },
-		{ IRQ_NAS100D_PCI_INTC, IRQ_NAS100D_PCI_INTD, IRQ_NAS100D_PCI_INTE },
+	static int pci_irq_table[MAX_DEV][IRQ_LINES] = {
+		{ IXP4XX_GPIO_IRQ(INTA), -1, -1 },
+		{ IXP4XX_GPIO_IRQ(INTB), -1, -1 },
+		{ IXP4XX_GPIO_IRQ(INTC), IXP4XX_GPIO_IRQ(INTD),
+		  IXP4XX_GPIO_IRQ(INTE) },
 	};
 
-	int irq = -1;
-
-	if (slot >= 1 && slot <= NAS100D_PCI_MAX_DEV &&
-		pin >= 1 && pin <= NAS100D_PCI_IRQ_LINES)
-		irq = pci_irq_table[slot-1][pin-1];
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[slot - 1][pin - 1];
 
-	return irq;
+	return -1;
 }
 
 struct hw_pci __initdata nas100d_pci = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nas100d-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nas100d-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nas100d-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nas100d-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,12 +29,26 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/gpio.h>
 
+#define NAS100D_SDA_PIN		5
+#define NAS100D_SCL_PIN		6
+
+/* Buttons */
+#define NAS100D_PB_GPIO         14   /* power button */
+#define NAS100D_RB_GPIO         4    /* reset button */
+
+/* Power control */
+#define NAS100D_PO_GPIO         12   /* power off */
+
+/* LEDs */
+#define NAS100D_LED_WLAN_GPIO	0
+#define NAS100D_LED_DISK_GPIO	3
+#define NAS100D_LED_PWR_GPIO	15
+
 static struct flash_platform_data nas100d_flash_data = {
 	.map_name		= "cfi_probe",
 	.width			= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nslu2-pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nslu2-pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nslu2-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nslu2-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,35 +18,38 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#define MAX_DEV		3
+#define IRQ_LINES	3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA		11
+#define INTB		10
+#define INTC		9
+#define INTD		8
+
 void __init nslu2_pci_preinit(void)
 {
-	set_irq_type(IRQ_NSLU2_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NSLU2_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
-	set_irq_type(IRQ_NSLU2_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
-
+	set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+	set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
 	ixp4xx_pci_preinit();
 }
 
 static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
-		IRQ_NSLU2_PCI_INTA,
-		IRQ_NSLU2_PCI_INTB,
-		IRQ_NSLU2_PCI_INTC,
+	static int pci_irq_table[IRQ_LINES] = {
+		IXP4XX_GPIO_IRQ(INTA),
+		IXP4XX_GPIO_IRQ(INTB),
+		IXP4XX_GPIO_IRQ(INTC),
 	};
 
-	int irq = -1;
-
-	if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
-		pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
-			irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
-	}
+	if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+		return pci_irq_table[(slot + pin - 2) % IRQ_LINES];
 
-	return irq;
+	return -1;
 }
 
 struct hw_pci __initdata nslu2_pci = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nslu2-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nslu2-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ixp4xx/nslu2-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ixp4xx/nslu2-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,13 +26,32 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
 #include <asm/gpio.h>
 
+#define NSLU2_SDA_PIN		7
+#define NSLU2_SCL_PIN		6
+
+/* NSLU2 Timer */
+#define NSLU2_FREQ 66000000
+
+/* Buttons */
+#define NSLU2_PB_GPIO		5	/* power button */
+#define NSLU2_PO_GPIO		8	/* power off */
+#define NSLU2_RB_GPIO		12	/* reset button */
+
+/* Buzzer */
+#define NSLU2_GPIO_BUZZ		4
+
+/* LEDs */
+#define NSLU2_LED_RED_GPIO	0
+#define NSLU2_LED_GRN_GPIO	1
+#define NSLU2_LED_DISK1_GPIO	3
+#define NSLU2_LED_DISK2_GPIO	2
+
 static struct flash_platform_data nslu2_flash_data = {
 	.map_name		= "cfi_probe",
 	.width			= 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -33,10 +33,18 @@ config MACH_SHEEVAPLUG
 	  Marvell SheevaPlug Reference Board.
 
 config MACH_TS219
-	bool "QNAP TS-119 and TS-219 Turbo NAS"
+	bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
 	help
 	  Say 'Y' here if you want your kernel to support the
-	  QNAP TS-119 and TS-219 Turbo NAS devices.
+	  QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS
+	  devices.
+
+config MACH_TS41X
+	bool "QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
+	  devices.
 
 config MACH_OPENRD_BASE
 	bool "Marvell OpenRD Base Board"
@@ -44,6 +52,12 @@ config MACH_OPENRD_BASE
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell OpenRD Base Board.
 
+config MACH_NETSPACE_V2
+	bool "LaCie Network Space v2 NAS Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie Network Space v2 NAS.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,9 @@ obj-$(CONFIG_MACH_RD88F6192_NAS)	+= rd88
 obj-$(CONFIG_MACH_RD88F6281)		+= rd88f6281-setup.o
 obj-$(CONFIG_MACH_MV88F6281GTW_GE)	+= mv88f6281gtw_ge-setup.o
 obj-$(CONFIG_MACH_SHEEVAPLUG)		+= sheevaplug-setup.o
-obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o
+obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o tsx1x-common.o
+obj-$(CONFIG_MACH_TS41X)		+= ts41x-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_OPENRD_BASE)		+= openrd_base-setup.o
+obj-$(CONFIG_MACH_NETSPACE_V2)		+= netspace_v2-setup.o
 
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/netspace_v2-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,325 @@
+/*
+ * arch/arm/mach-kirkwood/netspace_v2-setup.c
+ *
+ * LaCie Network Space v2 board setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ * Copyright (C) 2009 BenoÃ®t Canet <benoit.canet@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <plat/time.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition netspace_v2_flash_parts[] = {
+	{
+		.name = "u-boot",
+		.size = MTDPART_SIZ_FULL,
+		.offset = 0,
+		.mask_flags = MTD_WRITEABLE, /* force read-only */
+	},
+};
+
+static const struct flash_platform_data netspace_v2_flash = {
+	.type		= "mx25l4005a",
+	.name		= "spi_flash",
+	.parts		= netspace_v2_flash_parts,
+	.nr_parts	= ARRAY_SIZE(netspace_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = {
+	{
+		.modalias	= "m25p80",
+		.platform_data	= &netspace_v2_flash,
+		.irq		= -1,
+		.max_speed_hz	= 20000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+	},
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data netspace_v2_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+	.byte_len	= SZ_4K / 8,
+	.page_size	= 16,
+};
+
+/*
+ * i2c addr | chip         | description
+ * 0x50     | HT24LC04     | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata netspace_v2_i2c_info[] = {
+	{
+		I2C_BOARD_INFO("24c04", 0x50),
+		.platform_data  = &at24c04,
+	}
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data netspace_v2_sata_data = {
+	.n_ports	= 2,
+};
+
+#define NETSPACE_V2_GPIO_SATA0_POWER	16
+#define NETSPACE_V2_GPIO_SATA1_POWER	17
+
+static void __init netspace_v2_sata_power_init(void)
+{
+	int err;
+
+	err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power");
+	if (err == 0) {
+		err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1);
+		if (err)
+			gpio_free(NETSPACE_V2_GPIO_SATA0_POWER);
+	}
+	if (err)
+		pr_err("netspace_v2: failed to setup SATA0 power\n");
+}
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NETSPACE_V2_PUSH_BUTTON		32
+
+static struct gpio_keys_button netspace_v2_buttons[] = {
+	[0] = {
+		.code		= KEY_POWER,
+		.gpio		= NETSPACE_V2_PUSH_BUTTON,
+		.desc		= "Power push button",
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_keys_platform_data netspace_v2_button_data = {
+	.buttons	= netspace_v2_buttons,
+	.nbuttons	= ARRAY_SIZE(netspace_v2_buttons),
+};
+
+static struct platform_device netspace_v2_gpio_buttons = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data 	= &netspace_v2_button_data,
+	},
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+/*
+ * The blue front LED is wired to a CPLD and can blink in relation with the
+ * SATA activity.
+ *
+ * The following array detail the different LED registers and the combination
+ * of their possible values:
+ *
+ *  cmd_led   |  slow_led  | /SATA active | LED state
+ *            |            |              |
+ *     1      |     0      |      x       |  off
+ *     -      |     1      |      x       |  on
+ *     0      |     0      |      1       |  on
+ *     0      |     0      |      0       |  blink (rate 300ms)
+ */
+
+#define NETSPACE_V2_GPIO_RED_LED	12
+#define NETSPACE_V2_GPIO_BLUE_LED_SLOW	29
+#define NETSPACE_V2_GPIO_BLUE_LED_CMD	30
+
+
+static struct gpio_led netspace_v2_gpio_led_pins[] = {
+	{
+		.name	= "ns_v2:red:fail",
+		.gpio	= NETSPACE_V2_GPIO_RED_LED,
+	},
+};
+
+static struct gpio_led_platform_data netspace_v2_gpio_leds_data = {
+	.num_leds	= ARRAY_SIZE(netspace_v2_gpio_led_pins),
+	.leds		= netspace_v2_gpio_led_pins,
+};
+
+static struct platform_device netspace_v2_gpio_leds = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &netspace_v2_gpio_leds_data,
+	},
+};
+
+static void __init netspace_v2_gpio_leds_init(void)
+{
+	platform_device_register(&netspace_v2_gpio_leds);
+
+	/*
+	 * Configure the front blue LED to blink in relation with the SATA
+	 * activity.
+	 */
+	if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW,
+			 "SATA blue LED slow") != 0)
+		return;
+	if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0)
+		goto err_free_1;
+	if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD,
+			 "SATA blue LED command") != 0)
+		goto err_free_1;
+	if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0)
+		goto err_free_2;
+
+	return;
+
+err_free_2:
+	gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD);
+err_free_1:
+	gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW);
+	pr_err("netspace_v2: failed to configure SATA blue LED\n");
+}
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void netspace_v2_timer_init(void)
+{
+	kirkwood_tclk = 166666667;
+	orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer netspace_v2_timer = {
+	.init = netspace_v2_timer_init,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int netspace_v2_mpp_config[] __initdata = {
+	MPP0_SPI_SCn,
+	MPP1_SPI_MOSI,
+	MPP2_SPI_SCK,
+	MPP3_SPI_MISO,
+	MPP4_NF_IO6,
+	MPP5_NF_IO7,
+	MPP6_SYSRST_OUTn,
+	MPP8_TW_SDA,
+	MPP9_TW_SCK,
+	MPP10_UART0_TXD,
+	MPP11_UART0_RXD,
+	MPP12_GPO,		/* Red led */
+	MPP14_GPIO,		/* USB fuse */
+	MPP16_GPIO,		/* SATA 0 power */
+	MPP18_NF_IO0,
+	MPP19_NF_IO1,
+	MPP20_SATA1_ACTn,
+	MPP21_SATA0_ACTn,
+	MPP24_GPIO,		/* USB mode select */
+	MPP25_GPIO,		/* Fan rotation fail */
+	MPP26_GPIO,		/* USB device vbus */
+	MPP28_GPIO,		/* USB enable host vbus */
+	MPP29_GPIO,		/* Blue led (slow register) */
+	MPP30_GPIO,		/* Blue led (command register) */
+	MPP31_GPIO,		/* Board power off */
+	MPP32_GPIO, 		/* Power button (0 = Released, 1 = Pushed) */
+	0
+};
+
+#define NETSPACE_V2_GPIO_POWER_OFF	31
+
+static void netspace_v2_power_off(void)
+{
+	gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init netspace_v2_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(netspace_v2_mpp_config);
+
+	netspace_v2_sata_power_init();
+
+	kirkwood_ehci_init();
+	kirkwood_ge00_init(&netspace_v2_ge00_data);
+	kirkwood_sata_init(&netspace_v2_sata_data);
+	kirkwood_uart0_init();
+	spi_register_board_info(netspace_v2_spi_slave_info,
+				ARRAY_SIZE(netspace_v2_spi_slave_info));
+	kirkwood_spi_init();
+	kirkwood_i2c_init();
+	i2c_register_board_info(0, netspace_v2_i2c_info,
+				ARRAY_SIZE(netspace_v2_i2c_info));
+
+	netspace_v2_gpio_leds_init();
+	platform_device_register(&netspace_v2_gpio_buttons);
+
+	if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+	    gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0)
+		pm_power_off = netspace_v2_power_off;
+	else
+		pr_err("netspace_v2: failed to configure power-off GPIO\n");
+}
+
+MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= netspace_v2_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &netspace_v2_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/orion_spi.h>
@@ -53,6 +54,11 @@ static void __init rd88f6192_init(void)
 	 */
 	kirkwood_init();
 
+	orion_gpio_set_valid(RD88F6192_GPIO_USB_VBUS, 1);
+	if (gpio_request(RD88F6192_GPIO_USB_VBUS, "USB VBUS") != 0 ||
+	    gpio_direction_output(RD88F6192_GPIO_USB_VBUS, 1) != 0)
+		pr_err("RD-88F6192-NAS: failed to setup USB VBUS GPIO\n");
+
 	kirkwood_ehci_init();
 	kirkwood_ge00_init(&rd88f6192_ge00_data);
 	kirkwood_sata_init(&rd88f6192_sata_data);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/ts219-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/ts219-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/ts219-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/ts219-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /*
  *
- * QNAP TS-119/TS-219 Turbo NAS Board Setup
+ * QNAP TS-11x/TS-21x Turbo NAS Board Setup
  *
  * Copyright (C) 2009  Martin Michlmayr <tbm@cyrius.com>
  * Copyright (C) 2008  Byron Bradley <byron.bbradley@gmail.com>
@@ -14,87 +14,17 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
 #include <linux/i2c.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ata_platform.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
-#include <linux/timex.h>
-#include <linux/serial_reg.h>
-#include <linux/pci.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
 #include "common.h"
 #include "mpp.h"
-
-/****************************************************************************
- * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
- *     partitions on the device because we want to keep compatability with
- *     the QNAP firmware.
- * Layout as used by QNAP:
- *  0x00000000-0x00080000 : "U-Boot"
- *  0x00200000-0x00400000 : "Kernel"
- *  0x00400000-0x00d00000 : "RootFS"
- *  0x00d00000-0x01000000 : "RootFS2"
- *  0x00080000-0x000c0000 : "U-Boot Config"
- *  0x000c0000-0x00200000 : "NAS Config"
- *
- * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
- * used by the QNAP TS-109/TS-209.
- *
- ***************************************************************************/
-
-static struct mtd_partition qnap_ts219_partitions[] = {
-	{
-		.name		= "U-Boot",
-		.size		= 0x00080000,
-		.offset		= 0,
-		.mask_flags	= MTD_WRITEABLE,
-	}, {
-		.name		= "Kernel",
-		.size		= 0x00200000,
-		.offset		= 0x00200000,
-	}, {
-		.name		= "RootFS1",
-		.size		= 0x00900000,
-		.offset		= 0x00400000,
-	}, {
-		.name		= "RootFS2",
-		.size		= 0x00300000,
-		.offset		= 0x00d00000,
-	}, {
-		.name		= "U-Boot Config",
-		.size		= 0x00040000,
-		.offset		= 0x00080000,
-	}, {
-		.name		= "NAS Config",
-		.size		= 0x00140000,
-		.offset		= 0x000c0000,
-	},
-};
-
-static const struct flash_platform_data qnap_ts219_flash = {
-	.type		= "m25p128",
-	.name		= "spi_flash",
-	.parts		= qnap_ts219_partitions,
-	.nr_parts	= ARRAY_SIZE(qnap_ts219_partitions),
-};
-
-static struct spi_board_info __initdata qnap_ts219_spi_slave_info[] = {
-	{
-		.modalias	= "m25p80",
-		.platform_data	= &qnap_ts219_flash,
-		.irq		= -1,
-		.max_speed_hz	= 20000000,
-		.bus_num	= 0,
-		.chip_select	= 0,
-	},
-};
+#include "tsx1x-common.h"
 
 static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = {
 	I2C_BOARD_INFO("s35390a", 0x30),
@@ -152,36 +82,10 @@ static unsigned int qnap_ts219_mpp_confi
 	MPP14_UART1_RXD,	/* PIC controller */
 	MPP15_GPIO,		/* USB Copy button */
 	MPP16_GPIO,		/* Reset button */
+	MPP36_GPIO,		/* RAM: 0: 256 MB, 1: 512 MB */
 	0
 };
 
-
-/*****************************************************************************
- * QNAP TS-x19 specific power off method via UART1-attached PIC
- ****************************************************************************/
-
-#define UART1_REG(x)	(UART1_VIRT_BASE + ((UART_##x) << 2))
-
-void qnap_ts219_power_off(void)
-{
-	/* 19200 baud divisor */
-	const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
-
-	pr_info("%s: triggering power-off...\n", __func__);
-
-	/* hijack UART1 and reset into sane state (19200,8n1) */
-	writel(0x83, UART1_REG(LCR));
-	writel(divisor & 0xff, UART1_REG(DLL));
-	writel((divisor >> 8) & 0xff, UART1_REG(DLM));
-	writel(0x03, UART1_REG(LCR));
-	writel(0x00, UART1_REG(IER));
-	writel(0x00, UART1_REG(FCR));
-	writel(0x00, UART1_REG(MCR));
-
-	/* send the power-off command 'A' to PIC */
-	writel('A', UART1_REG(TX));
-}
-
 static void __init qnap_ts219_init(void)
 {
 	/*
@@ -192,9 +96,7 @@ static void __init qnap_ts219_init(void)
 
 	kirkwood_uart0_init();
 	kirkwood_uart1_init(); /* A PIC controller is connected here. */
-	spi_register_board_info(qnap_ts219_spi_slave_info,
-				ARRAY_SIZE(qnap_ts219_spi_slave_info));
-	kirkwood_spi_init();
+	qnap_tsx1x_register_flash();
 	kirkwood_i2c_init();
 	i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
 	kirkwood_ge00_init(&qnap_ts219_ge00_data);
@@ -202,7 +104,7 @@ static void __init qnap_ts219_init(void)
 	kirkwood_ehci_init();
 	platform_device_register(&qnap_ts219_button_device);
 
-	pm_power_off = qnap_ts219_power_off;
+	pm_power_off = qnap_tsx1x_power_off;
 
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/ts41x-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/ts41x-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/ts41x-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/ts41x-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,154 @@
+/*
+ *
+ * QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup
+ *
+ * Copyright (C) 2009  Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2008  Byron Bradley <byron.bbradley@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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx1x-common.h"
+
+static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = {
+	I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv_sata_platform_data qnap_ts41x_sata_data = {
+	.n_ports	= 2,
+};
+
+static struct gpio_keys_button qnap_ts41x_buttons[] = {
+	{
+		.code		= KEY_COPY,
+		.gpio		= 43,
+		.desc		= "USB Copy",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_RESTART,
+		.gpio		= 37,
+		.desc		= "Reset",
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data qnap_ts41x_button_data = {
+	.buttons	= qnap_ts41x_buttons,
+	.nbuttons	= ARRAY_SIZE(qnap_ts41x_buttons),
+};
+
+static struct platform_device qnap_ts41x_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &qnap_ts41x_button_data,
+	}
+};
+
+static unsigned int qnap_ts41x_mpp_config[] __initdata = {
+	MPP0_SPI_SCn,
+	MPP1_SPI_MOSI,
+	MPP2_SPI_SCK,
+	MPP3_SPI_MISO,
+	MPP6_SYSRST_OUTn,
+	MPP7_PEX_RST_OUTn,
+	MPP8_TW_SDA,
+	MPP9_TW_SCK,
+	MPP10_UART0_TXD,
+	MPP11_UART0_RXD,
+	MPP13_UART1_TXD,	/* PIC controller */
+	MPP14_UART1_RXD,	/* PIC controller */
+	MPP15_SATA0_ACTn,
+	MPP16_SATA1_ACTn,
+	MPP20_GE1_0,
+	MPP21_GE1_1,
+	MPP22_GE1_2,
+	MPP23_GE1_3,
+	MPP24_GE1_4,
+	MPP25_GE1_5,
+	MPP26_GE1_6,
+	MPP27_GE1_7,
+	MPP30_GE1_10,
+	MPP31_GE1_11,
+	MPP32_GE1_12,
+	MPP33_GE1_13,
+	MPP36_GPIO,		/* RAM: 0: 256 MB, 1: 512 MB */
+	MPP37_GPIO,		/* Reset button */
+	MPP43_GPIO,		/* USB Copy button */
+	MPP44_GPIO,		/* Board ID: 0: TS-419U, 1: TS-419 */
+	MPP45_GPIO,		/* JP1: 0: console, 1: LCD */
+	MPP46_GPIO,		/* External SATA HDD1 error indicator */
+	MPP47_GPIO,		/* External SATA HDD2 error indicator */
+	MPP48_GPIO,		/* External SATA HDD3 error indicator */
+	MPP49_GPIO,		/* External SATA HDD4 error indicator */
+	0
+};
+
+static void __init qnap_ts41x_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(qnap_ts41x_mpp_config);
+
+	kirkwood_uart0_init();
+	kirkwood_uart1_init(); /* A PIC controller is connected here. */
+	qnap_tsx1x_register_flash();
+	kirkwood_i2c_init();
+	i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1);
+	kirkwood_ge00_init(&qnap_ts41x_ge00_data);
+	kirkwood_ge01_init(&qnap_ts41x_ge01_data);
+	kirkwood_sata_init(&qnap_ts41x_sata_data);
+	kirkwood_ehci_init();
+	platform_device_register(&qnap_ts41x_button_device);
+
+	pm_power_off = qnap_tsx1x_power_off;
+
+}
+
+static int __init ts41x_pci_init(void)
+{
+	if (machine_is_ts41x())
+		kirkwood_pcie_init();
+
+   return 0;
+}
+subsys_initcall(ts41x_pci_init);
+
+MACHINE_START(TS41X, "QNAP TS-41x")
+	/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= qnap_ts41x_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/tsx1x-common.c linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/tsx1x-common.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/tsx1x-common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/tsx1x-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/serial_reg.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+
+/*
+ * QNAP TS-x1x Boards flash
+ */
+
+/****************************************************************************
+ * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
+ *     partitions on the device because we want to keep compatability with
+ *     the QNAP firmware.
+ * Layout as used by QNAP:
+ *  0x00000000-0x00080000 : "U-Boot"
+ *  0x00200000-0x00400000 : "Kernel"
+ *  0x00400000-0x00d00000 : "RootFS"
+ *  0x00d00000-0x01000000 : "RootFS2"
+ *  0x00080000-0x000c0000 : "U-Boot Config"
+ *  0x000c0000-0x00200000 : "NAS Config"
+ *
+ * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
+ * used by the QNAP TS-109/TS-209.
+ *
+ ***************************************************************************/
+
+struct mtd_partition qnap_tsx1x_partitions[] = {
+	{
+		.name		= "U-Boot",
+		.size		= 0x00080000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "Kernel",
+		.size		= 0x00200000,
+		.offset		= 0x00200000,
+	}, {
+		.name		= "RootFS1",
+		.size		= 0x00900000,
+		.offset		= 0x00400000,
+	}, {
+		.name		= "RootFS2",
+		.size		= 0x00300000,
+		.offset		= 0x00d00000,
+	}, {
+		.name		= "U-Boot Config",
+		.size		= 0x00040000,
+		.offset		= 0x00080000,
+	}, {
+		.name		= "NAS Config",
+		.size		= 0x00140000,
+		.offset		= 0x000c0000,
+	},
+};
+
+const struct flash_platform_data qnap_tsx1x_flash = {
+	.type		= "m25p128",
+	.name		= "spi_flash",
+	.parts		= qnap_tsx1x_partitions,
+	.nr_parts	= ARRAY_SIZE(qnap_tsx1x_partitions),
+};
+
+struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
+	{
+		.modalias	= "m25p80",
+		.platform_data	= &qnap_tsx1x_flash,
+		.irq		= -1,
+		.max_speed_hz	= 20000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+	},
+};
+
+void qnap_tsx1x_register_flash(void)
+{
+	spi_register_board_info(qnap_tsx1x_spi_slave_info,
+				ARRAY_SIZE(qnap_tsx1x_spi_slave_info));
+	kirkwood_spi_init();
+}
+
+
+/*****************************************************************************
+ * QNAP TS-x1x specific power off method via UART1-attached PIC
+ ****************************************************************************/
+
+#define UART1_REG(x)	(UART1_VIRT_BASE + ((UART_##x) << 2))
+
+void qnap_tsx1x_power_off(void)
+{
+	/* 19200 baud divisor */
+	const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
+
+	pr_info("%s: triggering power-off...\n", __func__);
+
+	/* hijack UART1 and reset into sane state (19200,8n1) */
+	writel(0x83, UART1_REG(LCR));
+	writel(divisor & 0xff, UART1_REG(DLL));
+	writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+	writel(0x03, UART1_REG(LCR));
+	writel(0x00, UART1_REG(IER));
+	writel(0x00, UART1_REG(FCR));
+	writel(0x00, UART1_REG(MCR));
+
+	/* send the power-off command 'A' to PIC */
+	writel('A', UART1_REG(TX));
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/tsx1x-common.h linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/tsx1x-common.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-kirkwood/tsx1x-common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-kirkwood/tsx1x-common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,7 @@
+#ifndef __ARCH_KIRKWOOD_TSX1X_COMMON_H
+#define __ARCH_KIRKWOOD_TSX1X_COMMON_H
+
+extern void qnap_tsx1x_register_flash(void);
+extern void qnap_tsx1x_power_off(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ks8695/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-ks8695/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ks8695/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ks8695/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,13 @@ extern struct bus_type platform_bus_type
 		__dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
 	   __dma; })
 
+#define __arch_dma_to_page(dev, x)	\
+	({ dma_addr_t __dma = x;				\
+	   if (!is_lbus_device(dev))				\
+		__dma += PHYS_OFFSET - KS8695_PCIMEM_PA;	\
+	   phys_to_page(__dma);					\
+	})
+
 #endif
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-lh7a40x/clocks.c linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/clocks.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-lh7a40x/clocks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/clocks.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,11 +7,11 @@
  *  version 2 as published by the Free Software Foundation.
  *
  */
-
-#include <linux/cpufreq.h>
 #include <mach/hardware.h>
 #include <mach/clocks.h>
 #include <linux/err.h>
+#include <linux/device.h>
+#include <linux/string.h>
 
 struct module;
 
@@ -31,12 +31,6 @@ struct clk {
 #define HCLKDIV(c)	(((c) >>  0) & 0x02)
 #define PCLKDIV(c)	(((c) >> 16) & 0x03)
 
-unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
-{
-	return fclkfreq_get ()/1000;
-}
-EXPORT_SYMBOL(cpufreq_get);
-
 unsigned int fclkfreq_get (void)
 {
 	unsigned int clkset = CSC_CLKSET;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-lh7a40x/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-lh7a40x/include/mach/hardware.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-lh7a40x/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 /*
  * This __REG() version gives the same results as the one above,  except
  * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers.  It's a shame that gcc
+ * assembly code for access to contiguous registers.  It's a shame that gcc
  * doesn't guess this by itself.
  */
 #include <asm/types.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/aspenite.c linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/aspenite.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/aspenite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/aspenite.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,9 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -85,12 +88,48 @@ static struct platform_device smc91x_dev
 	.resource	= smc91x_resources,
 };
 
+static struct mtd_partition aspenite_nand_partitions[] = {
+	{
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_1M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_8M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= (SZ_2M + SZ_1M),
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_48M,
+		.mask_flags	= 0,
+	}
+};
+
+static struct pxa3xx_nand_platform_data aspenite_nand_info = {
+	.enable_arbiter	= 1,
+	.parts		= aspenite_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(aspenite_nand_partitions),
+};
+
 static void __init common_init(void)
 {
 	mfp_config(ARRAY_AND_SIZE(common_pin_config));
 
 	/* on-chip devices */
 	pxa168_add_uart(1);
+	pxa168_add_nand(&aspenite_nand_info);
 
 	/* off-chip devices */
 	platform_device_register(&smc91x_device);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,21 @@ struct clkops apbc_clk_ops = {
 	.disable	= apbc_clk_disable,
 };
 
+static void apmu_clk_enable(struct clk *clk)
+{
+	__raw_writel(clk->enable_val, clk->clk_rst);
+}
+
+static void apmu_clk_disable(struct clk *clk)
+{
+	__raw_writel(0, clk->clk_rst);
+}
+
+struct clkops apmu_clk_ops = {
+	.enable		= apmu_clk_enable,
+	.disable	= apmu_clk_disable,
+};
+
 static DEFINE_SPINLOCK(clocks_lock);
 
 int clk_enable(struct clk *clk)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@ struct clk {
 };
 
 extern struct clkops apbc_clk_ops;
+extern struct clkops apmu_clk_ops;
 
 #define APBC_CLK(_name, _reg, _fnclksel, _rate)			\
 struct clk clk_##_name = {					\
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,9 @@
 #define IRQ_PXA168_DDR_INT		26
 #define IRQ_PXA168_UART1		27
 #define IRQ_PXA168_UART2		28
+#define IRQ_PXA168_UART3		29
 #define IRQ_PXA168_WDT			35
+#define IRQ_PXA168_MAIN_PMU		36
 #define IRQ_PXA168_FRQ_CHANGE		38
 #define IRQ_PXA168_SDH1			39
 #define IRQ_PXA168_SDH2			40
@@ -46,7 +48,7 @@
 #define IRQ_PXA168_USB2			51
 #define IRQ_PXA168_AC97			57
 #define IRQ_PXA168_TWSI1		58
-#define IRQ_PXA168_PMU			60
+#define IRQ_PXA168_AP_PMU		60
 #define IRQ_PXA168_SM_INT		63
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
 #include <linux/i2c.h>
 #include <mach/devices.h>
 #include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -13,6 +14,7 @@ extern struct pxa_device_desc pxa168_dev
 extern struct pxa_device_desc pxa168_device_pwm2;
 extern struct pxa_device_desc pxa168_device_pwm3;
 extern struct pxa_device_desc pxa168_device_pwm4;
+extern struct pxa_device_desc pxa168_device_nand;
 
 static inline int pxa168_add_uart(int id)
 {
@@ -64,4 +66,9 @@ static inline int pxa168_add_pwm(int id)
 
 	return pxa_register_device(d, NULL, 0);
 }
+
+static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+	return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
 #include <linux/i2c.h>
 #include <mach/devices.h>
 #include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
 
 extern struct pxa_device_desc pxa910_device_uart1;
 extern struct pxa_device_desc pxa910_device_uart2;
@@ -13,6 +14,7 @@ extern struct pxa_device_desc pxa910_dev
 extern struct pxa_device_desc pxa910_device_pwm2;
 extern struct pxa_device_desc pxa910_device_pwm3;
 extern struct pxa_device_desc pxa910_device_pwm4;
+extern struct pxa_device_desc pxa910_device_nand;
 
 static inline int pxa910_add_uart(int id)
 {
@@ -64,4 +66,9 @@ static inline int pxa910_add_pwm(int id)
 
 	return pxa_register_device(d, NULL, 0);
 }
+
+static inline int pxa910_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+	return pxa_register_device(&pxa910_device_nand, info, sizeof(*info));
+}
 #endif /* __ASM_MACH_PXA910_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/pxa168.c linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa168.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/pxa168.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa168.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <mach/addr-map.h>
 #include <mach/cputype.h>
 #include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
 #include <mach/irqs.h>
 #include <mach/gpio.h>
 #include <mach/dma.h>
@@ -72,6 +73,8 @@ static APBC_CLK(pwm2, PXA168_PWM2, 1, 13
 static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
 
+static APMU_CLK(nand, NAND, 0x01db, 208000000);
+
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
 	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -82,6 +85,7 @@ static struct clk_lookup pxa168_clkregs[
 	INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
 	INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
 	INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
+	INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
 };
 
 static int __init pxa168_init(void)
@@ -127,3 +131,4 @@ PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NON
 PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10);
 PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
 PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
+PXA168_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/pxa910.c linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa910.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/pxa910.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/pxa910.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,6 +110,8 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13
 static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
 
+static APMU_CLK(nand, NAND, 0x01db, 208000000);
+
 /* device and clock bindings */
 static struct clk_lookup pxa910_clkregs[] = {
 	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -120,6 +122,7 @@ static struct clk_lookup pxa910_clkregs[
 	INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
 	INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
 	INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
+	INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
 };
 
 static int __init pxa910_init(void)
@@ -174,3 +177,4 @@ PXA910_DEVICE(pwm1, "pxa910-pwm", 0, NON
 PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10);
 PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10);
 PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10);
+PXA910_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/ttc_dkb.c linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/ttc_dkb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mmp/ttc_dkb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mmp/ttc_dkb.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,21 +11,103 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
 #include <mach/addr-map.h>
 #include <mach/mfp-pxa910.h>
 #include <mach/pxa910.h>
 
 #include "common.h"
 
-#define ARRAY_AND_SIZE(x)       (x), ARRAY_SIZE(x)
-
 static unsigned long ttc_dkb_pin_config[] __initdata = {
 	/* UART2 */
 	GPIO47_UART2_RXD,
 	GPIO48_UART2_TXD,
+
+	/* DFI */
+	DF_IO0_ND_IO0,
+	DF_IO1_ND_IO1,
+	DF_IO2_ND_IO2,
+	DF_IO3_ND_IO3,
+	DF_IO4_ND_IO4,
+	DF_IO5_ND_IO5,
+	DF_IO6_ND_IO6,
+	DF_IO7_ND_IO7,
+	DF_IO8_ND_IO8,
+	DF_IO9_ND_IO9,
+	DF_IO10_ND_IO10,
+	DF_IO11_ND_IO11,
+	DF_IO12_ND_IO12,
+	DF_IO13_ND_IO13,
+	DF_IO14_ND_IO14,
+	DF_IO15_ND_IO15,
+	DF_nCS0_SM_nCS2_nCS0,
+	DF_ALE_SM_WEn_ND_ALE,
+	DF_CLE_SM_OEn_ND_CLE,
+	DF_WEn_DF_WEn,
+	DF_REn_DF_REn,
+	DF_RDY0_DF_RDY0,
+};
+
+static struct mtd_partition ttc_dkb_onenand_partitions[] = {
+	{
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_1M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_8M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= (SZ_2M + SZ_1M),
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_48M,
+		.mask_flags	= 0,
+	}
+};
+
+static struct onenand_platform_data ttc_dkb_onenand_info = {
+	.parts		= ttc_dkb_onenand_partitions,
+	.nr_parts	= ARRAY_SIZE(ttc_dkb_onenand_partitions),
+};
+
+static struct resource ttc_dkb_resource_onenand[] = {
+	[0] = {
+		.start	= SMC_CS0_PHYS_BASE,
+		.end	= SMC_CS0_PHYS_BASE + SZ_1M,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ttc_dkb_device_onenand = {
+	.name		= "onenand-flash",
+	.id		= -1,
+	.resource	= ttc_dkb_resource_onenand,
+	.num_resources	= ARRAY_SIZE(ttc_dkb_resource_onenand),
+	.dev		= {
+		.platform_data	= &ttc_dkb_onenand_info,
+	},
+};
+
+static struct platform_device *ttc_dkb_devices[] = {
+	&ttc_dkb_device_onenand,
 };
 
 static void __init ttc_dkb_init(void)
@@ -34,6 +116,9 @@ static void __init ttc_dkb_init(void)
 
 	/* on-chip devices */
 	pxa910_add_uart(1);
+
+	/* off-chip devices */
+	platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
 }
 
 MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/board-dream.c linux-libre-2.6.33-gnu1/arch/arm/mach-msm/board-dream.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/board-dream.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/board-dream.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-msm/board-dream.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+
+#include "devices.h"
+#include "board-dream.h"
+
+static struct platform_device *devices[] __initdata = {
+	&msm_device_uart3,
+	&msm_device_smd,
+	&msm_device_nand,
+	&msm_device_hsusb,
+	&msm_device_i2c,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init trout_init_irq(void)
+{
+	msm_init_irq();
+}
+
+static void __init trout_fixup(struct machine_desc *desc, struct tag *tags,
+				char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks = 1;
+	mi->bank[0].start = PHYS_OFFSET;
+	mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+	mi->bank[0].size = (101*1024*1024);
+}
+
+static void __init trout_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc trout_io_desc[] __initdata = {
+	{
+		.virtual = TROUT_CPLD_BASE,
+		.pfn     = __phys_to_pfn(TROUT_CPLD_START),
+		.length  = TROUT_CPLD_SIZE,
+		.type    = MT_DEVICE_NONSHARED
+	}
+};
+
+static void __init trout_map_io(void)
+{
+	msm_map_common_io();
+	iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc));
+
+#ifdef CONFIG_MSM_DEBUG_UART3
+	/* route UART3 to the "H2W" extended usb connector */
+	writeb(0x80, TROUT_CPLD_BASE + 0x00);
+#endif
+
+	msm_clock_init();
+}
+
+MACHINE_START(TROUT, "HTC Dream")
+	.phys_io	= MSM_DEBUG_UART_PHYS,
+	.io_pg_offst	= ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.fixup		= trout_fixup,
+	.map_io		= trout_map_io,
+	.init_irq	= trout_init_irq,
+	.init_machine	= trout_init,
+	.timer		= &msm_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/board-dream.h linux-libre-2.6.33-gnu1/arch/arm/mach-msm/board-dream.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/board-dream.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/board-dream.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+
+#define TROUT_CPLD_BASE   0xE8100000
+#define TROUT_CPLD_START  0x98000000
+#define TROUT_CPLD_SIZE   SZ_4K
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -14,15 +14,18 @@
  *
  */
 
+
+
 #include <mach/hardware.h>
 #include <mach/msm_iomap.h>
 
+#ifdef CONFIG_MSM_DEBUG_UART
 	.macro	addruart,rx
 	@ see if the MMU is enabled and select appropriate base address
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1
-	ldreq	\rx, =MSM_UART1_PHYS
-	movne	\rx, #0
+	ldreq	\rx, =MSM_DEBUG_UART_PHYS
+	ldrne	\rx, =MSM_DEBUG_UART_BASE
 	.endm
 
 	.macro	senduart,rd,rx
@@ -32,13 +35,20 @@
 
 	.macro	waituart,rd,rx
 	@ wait for TX_READY
-	teq	\rx, #0
-	bne	2f
-1:	ldr	\rd, [\rx, #0x08]
+1001:	ldr	\rd, [\rx, #0x08]
 	tst	\rd, #0x04
-	beq	1b
-2:
+	beq	1001b
+	.endm
+#else
+	.macro	addruart,rx
+	.endm
+
+	.macro	senduart,rd,rx
+	.endm
+
+	.macro	waituart,rd,rx
 	.endm
+#endif
 
 	.macro	busyuart,rd,rx
 	.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/mmc.h linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/mmc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/mmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/mmc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ *  arch/arm/include/asm/mach/mmc.h
+ */
+#ifndef ASMARM_MACH_MMC_H
+#define ASMARM_MACH_MMC_H
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+struct embedded_sdio_data {
+	struct sdio_cis cis;
+	struct sdio_cccr cccr;
+	struct sdio_embedded_func *funcs;
+	int num_funcs;
+};
+
+struct mmc_platform_data {
+	unsigned int ocr_mask;			/* available voltages */
+	u32 (*translate_vdd)(struct device *, unsigned int);
+	unsigned int (*status)(struct device *);
+	struct embedded_sdio_data *embedded_sdio;
+	int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/msm_iomap.h linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/msm_iomap.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/msm_iomap.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/msm_iomap.h	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,18 @@
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
 #define MSM_SDC1_PHYS         0xA0400000
 #define MSM_SDC1_SIZE         SZ_4K
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,9 +16,16 @@
 #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H
 
 #include "hardware.h"
+#include "linux/io.h"
+#include "mach/msm_iomap.h"
 
 static void putc(int c)
 {
+#if defined(MSM_DEBUG_UART_PHYS)
+	unsigned base = MSM_DEBUG_UART_PHYS;
+	while (!(readl(base + 0x08) & 0x04)) ;
+	writel(c, base + 0x0c);
+#endif
 }
 
 static inline void flush(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/io.c linux-libre-2.6.33-gnu1/arch/arm/mach-msm/io.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/io.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,9 @@ static struct map_desc msm_io_desc[] __i
 	MSM_DEVICE(GPIO1),
 	MSM_DEVICE(GPIO2),
 	MSM_DEVICE(CLK_CTL),
+#ifdef CONFIG_MSM_DEBUG_UART
+	MSM_DEVICE(DEBUG_UART),
+#endif
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-msm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -3,6 +3,30 @@ if ARCH_MSM
 comment "MSM Board Type"
 	depends on ARCH_MSM
 
+config MSM_DEBUG_UART
+	int
+	default 1 if MSM_DEBUG_UART1
+	default 2 if MSM_DEBUG_UART2
+	default 3 if MSM_DEBUG_UART3
+
+choice
+	prompt "Debug UART"
+
+	default MSM_DEBUG_UART_NONE
+
+	config MSM_DEBUG_UART_NONE
+		bool "None"
+
+	config MSM_DEBUG_UART1
+		bool "UART1"
+
+	config MSM_DEBUG_UART2
+		bool "UART2"
+
+	config MSM_DEBUG_UART3
+		bool "UART3"
+endchoice
+
 config MACH_HALIBUT
 	depends on ARCH_MSM
 	default y
@@ -10,4 +34,10 @@ config MACH_HALIBUT
 	help
 	  Support for the Qualcomm SURF7201A eval board.
 
+config MACH_TROUT
+	default y
+	bool "HTC Dream (aka trout)"
+	help
+	  Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-msm/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-msm/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-msm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-msm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,3 +6,4 @@ obj-y += clock.o clock-7x01a.o
 
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
 
+obj-$(CONFIG_MACH_TROUT) += board-dream.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/clock_imx21.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx21.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/clock_imx21.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx21.c	2010-02-24 13:52:17.000000000 -0500
@@ -1000,7 +1000,7 @@ int __init mx21_clocks_init(unsigned lon
 	clk_enable(&per_clk[0]);
 	clk_enable(&gpio_clk);
 
-#ifdef CONFIG_DEBUG_LL_CONSOLE
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
 	clk_enable(&uart_clk[0]);
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/clock_imx27.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx27.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/clock_imx27.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/clock_imx27.c	2010-02-24 13:52:17.000000000 -0500
@@ -651,8 +651,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
 	_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
 	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
-	_REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
-	_REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
+	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
 	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
 	_REGISTER_CLOCK(NULL, "vpu", vpu_clk)
 	_REGISTER_CLOCK(NULL, "dma", dma_clk)
@@ -751,7 +751,7 @@ int __init mx27_clocks_init(unsigned lon
 	clk_enable(&emi_clk);
 	clk_enable(&iim_clk);
 
-#ifdef CONFIG_DEBUG_LL_CONSOLE
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
 	clk_enable(&uart1_clk);
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -530,6 +530,84 @@ struct platform_device mxc_usbh2 = {
 };
 #endif
 
+static struct resource imx_ssi_resources0[] = {
+	{
+		.start	= SSI1_BASE_ADDR,
+		.end	= SSI1_BASE_ADDR + 0x6F,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MXC_INT_SSI1,
+		.end	= MXC_INT_SSI1,
+		.flags	= IORESOURCE_IRQ,
+	}, {
+		.name	= "tx0",
+		.start	= DMA_REQ_SSI1_TX0,
+		.end	= DMA_REQ_SSI1_TX0,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "rx0",
+		.start	= DMA_REQ_SSI1_RX0,
+		.end	= DMA_REQ_SSI1_RX0,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "tx1",
+		.start	= DMA_REQ_SSI1_TX1,
+		.end	= DMA_REQ_SSI1_TX1,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "rx1",
+		.start	= DMA_REQ_SSI1_RX1,
+		.end	= DMA_REQ_SSI1_RX1,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct resource imx_ssi_resources1[] = {
+	{
+		.start	= SSI2_BASE_ADDR,
+		.end	= SSI2_BASE_ADDR + 0x6F,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MXC_INT_SSI2,
+		.end	= MXC_INT_SSI2,
+		.flags	= IORESOURCE_IRQ,
+	}, {
+		.name	= "tx0",
+		.start	= DMA_REQ_SSI2_TX0,
+		.end	= DMA_REQ_SSI2_TX0,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "rx0",
+		.start	= DMA_REQ_SSI2_RX0,
+		.end	= DMA_REQ_SSI2_RX0,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "tx1",
+		.start	= DMA_REQ_SSI2_TX1,
+		.end	= DMA_REQ_SSI2_TX1,
+		.flags	= IORESOURCE_DMA,
+	}, {
+		.name	= "rx1",
+		.start	= DMA_REQ_SSI2_RX1,
+		.end	= DMA_REQ_SSI2_RX1,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device imx_ssi_device0 = {
+	.name = "imx-ssi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(imx_ssi_resources0),
+	.resource = imx_ssi_resources0,
+};
+
+struct platform_device imx_ssi_device1 = {
+	.name = "imx-ssi",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(imx_ssi_resources1),
+	.resource = imx_ssi_resources1,
+};
+
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
 	{
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/devices.h linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/devices.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/devices.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,4 +26,5 @@ extern struct platform_device mxc_usbh2;
 extern struct platform_device mxc_spi_device0;
 extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
-
+extern struct platform_device imx_ssi_device0;
+extern struct platform_device imx_ssi_device1;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -6,11 +6,13 @@ choice
 
 config MACH_MX21
 	bool "i.MX21 support"
+	select ARCH_MXC_AUDMUX_V1
 	help
 	  This enables support for Freescale's MX2 based i.MX21 processor.
 
 config MACH_MX27
 	bool "i.MX27 support"
+	select ARCH_MXC_AUDMUX_V1
 	help
 	  This enables support for Freescale's MX2 based i.MX27 processor.
 
@@ -102,4 +104,11 @@ config MACH_PCA100
 	  Include support for phyCARD-s (aka pca100) platform. This
 	  includes specific configurations for the module and its peripherals.
 
+config MACH_MXT_TD60
+	bool "Maxtrack i-MXT TD60"
+	depends on MACH_MX27
+	help
+	  Include support for i-MXT (aka td60) platform. This
+	  includes specific configurations for the module and its peripherals.
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -20,4 +20,5 @@ obj-$(CONFIG_MACH_MX27LITE) += mx27lite.
 obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o
 obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
 obj-$(CONFIG_MACH_PCA100) += pca100.o
+obj-$(CONFIG_MACH_MXT_TD60) += mxt_td60.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/mxt_td60.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mxt_td60.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/mxt_td60.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/mxt_td60.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,295 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2006-2007 Freescale Semiconductor, Inc. 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
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/gpio.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux.h>
+#include <mach/mxc_nand.h>
+#include <mach/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <mach/imxfb.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+static unsigned int mxt_td60_pins[] __initdata = {
+	/* UART0 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART1 */
+	PE3_PF_UART2_CTS,
+	PE4_PF_UART2_RTS,
+	PE6_PF_UART2_TXD,
+	PE7_PF_UART2_RXD,
+	/* UART2 */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+	PE10_PF_UART3_CTS,
+	PE11_PF_UART3_RTS,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C1 */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* I2C2 */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* FB */
+	PA5_PF_LSCLK,
+	PA6_PF_LD0,
+	PA7_PF_LD1,
+	PA8_PF_LD2,
+	PA9_PF_LD3,
+	PA10_PF_LD4,
+	PA11_PF_LD5,
+	PA12_PF_LD6,
+	PA13_PF_LD7,
+	PA14_PF_LD8,
+	PA15_PF_LD9,
+	PA16_PF_LD10,
+	PA17_PF_LD11,
+	PA18_PF_LD12,
+	PA19_PF_LD13,
+	PA20_PF_LD14,
+	PA21_PF_LD15,
+	PA22_PF_LD16,
+	PA23_PF_LD17,
+	PA25_PF_CLS,
+	PA27_PF_SPL_SPR,
+	PA28_PF_HSYNC,
+	PA29_PF_VSYNC,
+	PA30_PF_CONTRAST,
+	PA31_PF_OE_ACD,
+	/* OWIRE */
+	PE16_AF_OWIRE,
+	/* SDHC1*/
+	PE18_PF_SD1_D0,
+	PE19_PF_SD1_D1,
+	PE20_PF_SD1_D2,
+	PE21_PF_SD1_D3,
+	PE22_PF_SD1_CMD,
+	PE23_PF_SD1_CLK,
+	PF8_AF_ATA_IORDY,
+	/* SDHC2*/
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+};
+
+static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c_data = {
+	.bitrate = 100000,
+};
+
+/* PCA9557 */
+static int mxt_td60_pca9557_setup(struct i2c_client *client,
+				unsigned gpio_base, unsigned ngpio,
+				void *context)
+{
+	static int mxt_td60_gpio_value[] = {
+		-1, -1, -1, -1, -1, -1, -1, 1
+	};
+	int n;
+
+	for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
+		gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
+		if (mxt_td60_gpio_value[n] < 0)
+			gpio_direction_input(gpio_base + n);
+		else
+			gpio_direction_output(gpio_base + n,
+						mxt_td60_gpio_value[n]);
+		gpio_export(gpio_base + n, 0);
+	}
+
+	return 0;
+}
+
+static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
+	.gpio_base	= 240, /* place PCA9557 after all MX27 gpio pins */
+	.invert		= 0, /* Do not invert */
+	.setup		= mxt_td60_pca9557_setup,
+};
+
+static struct i2c_board_info mxt_td60_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pca9557", 0x18),
+		.platform_data = &mxt_td60_pca9557_pdata,
+	},
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c2_data = {
+	.bitrate = 100000,
+};
+
+static struct i2c_board_info mxt_td60_i2c2_devices[] = {
+};
+
+static struct imx_fb_videomode mxt_td60_modes[] = {
+	{
+		.mode = {
+			.name		= "Chimei LW700AT9003",
+			.refresh	= 60,
+			.xres		= 800,
+			.yres		= 480,
+			.pixclock	= 30303,
+			.hsync_len	= 64,
+			.left_margin	= 0x67,
+			.right_margin	= 0x68,
+			.vsync_len	= 16,
+			.upper_margin	= 0x0f,
+			.lower_margin	= 0x0f,
+		},
+		.bpp		= 16,
+		.pcr		= 0xFA208B83,
+	},
+};
+
+static struct imx_fb_platform_data mxt_td60_fb_data = {
+	.mode = mxt_td60_modes,
+	.num_modes = ARRAY_SIZE(mxt_td60_modes),
+
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+};
+
+static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+				void *data)
+{
+	return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
+				"sdhc1-card-detect", data);
+}
+
+static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOF(8), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+	.init = mxt_td60_sdhc1_init,
+	.exit = mxt_td60_sdhc1_exit,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static void __init mxt_td60_board_init(void)
+{
+	mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
+			"MXT_TD60");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+	mxc_register_device(&mxc_nand_device, &mxt_td60_nand_board_info);
+
+	i2c_register_board_info(0, mxt_td60_i2c_devices,
+				ARRAY_SIZE(mxt_td60_i2c_devices));
+
+	i2c_register_board_info(1, mxt_td60_i2c2_devices,
+				ARRAY_SIZE(mxt_td60_i2c2_devices));
+
+	mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data);
+	mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data);
+	mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
+	mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mxt_td60_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mxt_td60_timer = {
+	.init	= mxt_td60_timer_init,
+};
+
+MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
+	/* maintainer: Maxtrack Industrial */
+	.phys_io	= AIPI_BASE_ADDR,
+	.io_pg_offst	= ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= mx27_map_io,
+	.init_irq	= mx27_init_irq,
+	.init_machine	= mxt_td60_board_init,
+	.timer		= &mxt_td60_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/pca100.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pca100.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx2/pca100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx2/pca100.c	2010-02-24 13:52:17.000000000 -0500
@@ -237,7 +237,7 @@ MACHINE_START(PCA100, "phyCARD-i.MX27")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx27_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx27_init_irq,
 	.init_machine   = pca100_init,
 	.timer          = &pca100_timer,
 MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -119,6 +119,11 @@ static unsigned long get_rate_nfc(struct
 	return get_rate_per(8);
 }
 
+static unsigned long get_rate_gpt(struct clk *clk)
+{
+	return get_rate_per(5);
+}
+
 static unsigned long get_rate_otg(struct clk *clk)
 {
 	return 48000000; /* FIXME */
@@ -144,7 +149,7 @@ static void clk_cgcr_disable(struct clk
 	__raw_writel(reg, clk->enable_reg);
 }
 
-#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, s)	\
 	static struct clk name = {			\
 		.id		= i,			\
 		.enable_reg	= CRM_BASE + er,	\
@@ -153,26 +158,30 @@ static void clk_cgcr_disable(struct clk
 		.set_rate	= sr,			\
 		.enable		= clk_cgcr_enable,	\
 		.disable	= clk_cgcr_disable,	\
+		.secondary	= s,			\
 	}
 
-DEFINE_CLOCK(gpt_clk,    0, CCM_CGCR0,  5, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,  5, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL);
-DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL);
-DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL);
-DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL);
-DEFINE_CLOCK(uart4_clk,  0, CCM_CGCR2, 17, get_rate_uart, NULL);
-DEFINE_CLOCK(uart5_clk,  0, CCM_CGCR2, 18, get_rate_uart, NULL);
-DEFINE_CLOCK(nfc_clk,    0, CCM_CGCR0,  8, get_rate_nfc, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL);
-DEFINE_CLOCK(pwm1_clk,	 0, CCM_CGCR1, 31, get_rate_ipg, NULL);
-DEFINE_CLOCK(pwm2_clk,	 0, CCM_CGCR2,  0, get_rate_ipg, NULL);
-DEFINE_CLOCK(pwm3_clk,	 0, CCM_CGCR2,  1, get_rate_ipg, NULL);
-DEFINE_CLOCK(pwm4_clk,	 0, CCM_CGCR2,  2, get_rate_ipg, NULL);
-DEFINE_CLOCK(kpp_clk,	 0, CCM_CGCR1, 28, get_rate_ipg, NULL);
-DEFINE_CLOCK(tsc_clk,	 0, CCM_CGCR2, 13, get_rate_ipg, NULL);
-DEFINE_CLOCK(i2c_clk,	 0, CCM_CGCR0,  6, get_rate_i2c, NULL);
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGCR0,  5, get_rate_gpt, NULL, NULL);
+DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,  5, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL,	 NULL, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart4_clk,  0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart5_clk,  0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(nfc_clk,    0, CCM_CGCR0,  8, get_rate_nfc, NULL, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
+DEFINE_CLOCK(pwm1_clk,	 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm2_clk,	 0, CCM_CGCR2,  0, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm3_clk,	 0, CCM_CGCR2,  1, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm4_clk,	 0, CCM_CGCR2,  2, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(kpp_clk,	 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(tsc_clk,	 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(i2c_clk,	 0, CCM_CGCR0,  6, get_rate_i2c, NULL, NULL);
+DEFINE_CLOCK(fec_clk,	 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
 
 #define _REGISTER_CLOCK(d, n, c)	\
 	{				\
@@ -204,15 +213,24 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
 	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
 	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
 };
 
-int __init mx25_clocks_init(unsigned long fref)
+int __init mx25_clocks_init(void)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(lookups); i++)
 		clkdev_add(&lookups[i]);
 
+	/* Turn off all clocks except the ones we need to survive, namely:
+	 * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
+	 * SCC
+	 */
+	__raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
+	__raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
+	__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
+
 	mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -419,3 +419,22 @@ int __init mxc_register_gpios(void)
 	return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
 }
 
+static struct resource mx25_fec_resources[] = {
+	{
+		.start	= MX25_FEC_BASE_ADDR,
+		.end	= MX25_FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MX25_INT_FEC,
+		.end	= MX25_INT_FEC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mx25_fec_device = {
+	.name	= "fec",
+	.id	= 0,
+	.num_resources	= ARRAY_SIZE(mx25_fec_resources),
+	.resource	= mx25_fec_resources,
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/devices.h linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/devices.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/devices.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,3 +17,4 @@ extern struct platform_device mxc_keypad
 extern struct platform_device mxc_i2c_device0;
 extern struct platform_device mxc_i2c_device1;
 extern struct platform_device mxc_i2c_device2;
+extern struct platform_device mx25_fec_device;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/mx25pdk.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mx25pdk.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx25/mx25pdk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx25/mx25pdk.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,10 +18,11 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/smsc911x.h>
+#include <linux/fec.h>
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
@@ -35,21 +36,62 @@
 #include <mach/mx25.h>
 #include <mach/mxc_nand.h>
 #include "devices.h"
-#include <mach/iomux-v3.h>
+#include <mach/iomux.h>
 
 static struct imxuart_platform_data uart_pdata = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
+static struct pad_desc mx25pdk_pads[] = {
+	MX25_PAD_FEC_MDC__FEC_MDC,
+	MX25_PAD_FEC_MDIO__FEC_MDIO,
+	MX25_PAD_FEC_TDATA0__FEC_TDATA0,
+	MX25_PAD_FEC_TDATA1__FEC_TDATA1,
+	MX25_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX25_PAD_FEC_RDATA0__FEC_RDATA0,
+	MX25_PAD_FEC_RDATA1__FEC_RDATA1,
+	MX25_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
+	MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
+	MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
+};
+
+static struct fec_platform_data mx25_fec_pdata = {
+        .phy    = PHY_INTERFACE_MODE_RMII,
+};
+
+#define FEC_ENABLE_GPIO		35
+#define FEC_RESET_B_GPIO	104
+
+static void __init mx25pdk_fec_reset(void)
+{
+	gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
+	gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
+
+	gpio_direction_output(FEC_ENABLE_GPIO, 0);  /* drop PHY power */
+	gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
+	udelay(2);
+
+	/* turn on PHY power and lift reset */
+	gpio_set_value(FEC_ENABLE_GPIO, 1);
+	gpio_set_value(FEC_RESET_B_GPIO, 1);
+}
+
 static void __init mx25pdk_init(void)
 {
+	mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
+			ARRAY_SIZE(mx25pdk_pads));
+
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 	mxc_register_device(&mxc_usbh2, NULL);
+
+	mx25pdk_fec_reset();
+	mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
 }
 
 static void __init mx25pdk_timer_init(void)
 {
-	mx25_clocks_init(26000000);
+	mx25_clocks_init();
 }
 
 static struct sys_timer mx25pdk_timer = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/armadillo5x0.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/armadillo5x0.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/armadillo5x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/armadillo5x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,9 @@
 #include <linux/irq.h>
 #include <linux/mtd/physmap.h>
 #include <linux/io.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -97,6 +100,47 @@ static int armadillo5x0_pins[] = {
 	MX31_PIN_FPSHIFT__FPSHIFT,
 	MX31_PIN_DRDY0__DRDY0,
 	IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
+	/* I2C2 */
+	MX31_PIN_CSPI2_MOSI__SCL,
+	MX31_PIN_CSPI2_MISO__SDA,
+};
+
+/* RTC over I2C*/
+#define ARMADILLO5X0_RTC_GPIO	IOMUX_TO_GPIO(MX31_PIN_SRXD4)
+
+static struct i2c_board_info armadillo5x0_i2c_rtc = {
+	I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/* GPIO BUTTONS */
+static struct gpio_keys_button armadillo5x0_buttons[] = {
+	{
+		.code		= KEY_ENTER, /*28*/
+		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SCLK0),
+		.active_low	= 1,
+		.desc		= "menu",
+		.wakeup		= 1,
+	}, {
+		.code		= KEY_BACK, /*158*/
+		.gpio		= IOMUX_TO_GPIO(MX31_PIN_SRST0),
+		.active_low	= 1,
+		.desc		= "back",
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data armadillo5x0_button_data = {
+	.buttons	= armadillo5x0_buttons,
+	.nbuttons	= ARRAY_SIZE(armadillo5x0_buttons),
+};
+
+static struct platform_device armadillo5x0_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &armadillo5x0_button_data,
+	}
 };
 
 /*
@@ -278,7 +322,7 @@ static struct resource armadillo5x0_smc9
 };
 
 static struct smsc911x_platform_config smsc911x_info = {
-	.flags		= SMSC911X_USE_32BIT,
+	.flags		= SMSC911X_USE_16BIT,
 	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 	.irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
 };
@@ -300,6 +344,8 @@ static struct imxuart_platform_data uart
 
 static struct platform_device *devices[] __initdata = {
 	&armadillo5x0_smc911x_device,
+	&mxc_i2c_device1,
+	&armadillo5x0_button_device,
 };
 
 /*
@@ -335,6 +381,18 @@ static void __init armadillo5x0_init(voi
 
 	/* set NAND page size to 2k if not configured via boot mode pins */
 	__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+
+	/* RTC */
+	/* Get RTC IRQ and register the chip */
+	if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
+		if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
+			armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
+		else
+			gpio_free(ARMADILLO5X0_RTC_GPIO);
+	}
+	if (armadillo5x0_i2c_rtc.irq == 0)
+		pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
+	i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
 }
 
 static void __init armadillo5x0_timer_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -558,8 +558,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
 	_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
 	_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
-	_REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
-	_REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
+	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
 	_REGISTER_CLOCK(NULL, "firi", firi_clk)
 	_REGISTER_CLOCK(NULL, "ata", ata_clk)
 	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
@@ -616,6 +616,8 @@ int __init mx31_clocks_init(unsigned lon
 
 	clk_enable(&serial_pll_clk);
 
+	mx31_read_cpu_rev();
+
 	if (mx31_revision() >= CHIP_REV_2_0) {
 		reg = __raw_readl(MXC_CCM_PMCR1);
 		/* No PLL restart on DVFS switch; enable auto EMI handshake */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/clock-imx35.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx35.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/clock-imx35.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/clock-imx35.c	2010-02-24 13:52:17.000000000 -0500
@@ -335,7 +335,7 @@ static void clk_cgr_disable(struct clk *
 
 DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
 DEFINE_CLOCK(ata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
-DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL);
+/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL); */
 DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
 DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
 DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
@@ -381,12 +381,43 @@ DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20
 DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
 DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
 DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
-DEFINE_CLOCK(admux_clk,  0, CCM_CGR2, 30, NULL, NULL);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
 
 DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
 DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
 DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
 
+DEFINE_CLOCK(usbahb_clk, 0, 0,         0, get_rate_ahb, NULL);
+
+static int clk_dummy_enable(struct clk *clk)
+{
+	return 0;
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+	unsigned long div1;
+
+	div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
+
+	return get_rate_ahb(NULL) / div1;
+}
+
+/* NAND Controller: It seems it can't be disabled */
+static struct clk nfc_clk = {
+	.id		= 0,
+	.enable_reg	= 0,
+	.enable_shift	= 0,
+	.get_rate	= get_rate_nfc,
+	.set_rate	= NULL, /* set_rate_nfc, */
+	.enable		= clk_dummy_enable,
+	.disable	= clk_dummy_disable
+};
+
 #define _REGISTER_CLOCK(d, n, c)	\
 	{				\
 		.dev_id = d,		\
@@ -397,7 +428,6 @@ DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4
 static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "asrc", asrc_clk)
 	_REGISTER_CLOCK(NULL, "ata", ata_clk)
-	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
 	_REGISTER_CLOCK(NULL, "can", can1_clk)
 	_REGISTER_CLOCK(NULL, "can", can2_clk)
 	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
@@ -434,8 +464,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "sdma", sdma_clk)
 	_REGISTER_CLOCK(NULL, "spba", spba_clk)
 	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
-	_REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
-	_REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
+	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
 	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
 	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
 	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
@@ -443,12 +473,14 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
 	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
 	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
 	_REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
 	_REGISTER_CLOCK(NULL, "max", max_clk)
-	_REGISTER_CLOCK(NULL, "admux", admux_clk)
+	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
 	_REGISTER_CLOCK(NULL, "csi", csi_clk)
 	_REGISTER_CLOCK(NULL, "iim", iim_clk)
 	_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
 };
 
 int __init mx35_clocks_init()
@@ -456,7 +488,7 @@ int __init mx35_clocks_init()
 	int i;
 	unsigned int ll = 0;
 
-#ifdef CONFIG_DEBUG_LL_CONSOLE
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
 	ll = (3 << 16);
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/cpu.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ * MX3 CPU type detection
+ *
+ * Copyright (c) 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.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/iim.h>
+
+unsigned int mx31_cpu_rev;
+EXPORT_SYMBOL(mx31_cpu_rev);
+
+struct mx3_cpu_type {
+	u8 srev;
+	const char *name;
+	const char *v;
+	unsigned int rev;
+};
+
+static struct mx3_cpu_type mx31_cpu_type[] __initdata = {
+	{ .srev = 0x00, .name = "i.MX31(L)", .v = "1.0",  .rev = CHIP_REV_1_0	},
+	{ .srev = 0x10, .name = "i.MX31",    .v = "1.1",  .rev = CHIP_REV_1_1	},
+	{ .srev = 0x11, .name = "i.MX31L",   .v = "1.1",  .rev = CHIP_REV_1_1	},
+	{ .srev = 0x12, .name = "i.MX31",    .v = "1.15", .rev = CHIP_REV_1_1	},
+	{ .srev = 0x13, .name = "i.MX31L",   .v = "1.15", .rev = CHIP_REV_1_1	},
+	{ .srev = 0x14, .name = "i.MX31",    .v = "1.2",  .rev = CHIP_REV_1_2	},
+	{ .srev = 0x15, .name = "i.MX31L",   .v = "1.2",  .rev = CHIP_REV_1_2	},
+	{ .srev = 0x28, .name = "i.MX31",    .v = "2.0",  .rev = CHIP_REV_2_0	},
+	{ .srev = 0x29, .name = "i.MX31L",   .v = "2.0",  .rev = CHIP_REV_2_0	},
+};
+
+void __init mx31_read_cpu_rev(void)
+{
+	u32 i, srev;
+
+	/* read SREV register from IIM module */
+	srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR) + MXC_IIMSREV);
+
+	for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
+		if (srev == mx31_cpu_type[i].srev) {
+			printk(KERN_INFO
+				"CPU identified as %s, silicon rev %s\n",
+				mx31_cpu_type[i].name, mx31_cpu_type[i].v);
+
+			mx31_cpu_rev = mx31_cpu_type[i].rev;
+			return;
+		}
+
+	printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -537,6 +537,44 @@ struct platform_device mxc_fec_device =
 };
 #endif
 
+static struct resource imx_ssi_resources0[] = {
+	{
+		.start	= SSI1_BASE_ADDR,
+		.end	= SSI1_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MX31_INT_SSI1,
+		.end	= MX31_INT_SSI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource imx_ssi_resources1[] = {
+	{
+		.start	= SSI2_BASE_ADDR,
+		.end	= SSI2_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MX31_INT_SSI2,
+		.end	= MX31_INT_SSI2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device imx_ssi_device0 = {
+	.name = "imx-ssi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(imx_ssi_resources0),
+	.resource = imx_ssi_resources0,
+};
+
+struct platform_device imx_ssi_device1 = {
+	.name = "imx-ssi",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(imx_ssi_resources1),
+	.resource = imx_ssi_resources1,
+};
+
 static int mx3_devices_init(void)
 {
 	if (cpu_is_mx31()) {
@@ -546,7 +584,7 @@ static int mx3_devices_init(void)
 	}
 	if (cpu_is_mx35()) {
 		mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
-		mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
+		mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0x1fff;
 		otg_resources[0].start = MX35_OTG_BASE_ADDR;
 		otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff;
 		otg_resources[1].start = MXC_INT_USBOTG;
@@ -555,6 +593,10 @@ static int mx3_devices_init(void)
 		mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
 		mxc_usbh1_resources[1].start = MXC_INT_USBHS;
 		mxc_usbh1_resources[1].end = MXC_INT_USBHS;
+		imx_ssi_resources0[1].start = MX35_INT_SSI1;
+		imx_ssi_resources0[1].end = MX35_INT_SSI1;
+		imx_ssi_resources1[1].start = MX35_INT_SSI2;
+		imx_ssi_resources1[1].end = MX35_INT_SSI2;
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/devices.h linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/devices.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/devices.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,4 +23,6 @@ extern struct platform_device mxc_rnga_d
 extern struct platform_device mxc_spi_device0;
 extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
+extern struct platform_device imx_ssi_device0;
+extern struct platform_device imx_ssi_device1;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -2,11 +2,13 @@ if ARCH_MX3
 
 config ARCH_MX31
 	select ARCH_HAS_RNGA
+	select ARCH_MXC_AUDMUX_V2
 	bool
 
 config ARCH_MX35
 	bool
 	select ARCH_MXC_IOMUX_V3
+	select ARCH_MXC_AUDMUX_V2
 
 comment "MX3 platforms:"
 
@@ -47,6 +49,7 @@ config MACH_PCM037_EET
 config MACH_MX31LITE
 	bool "Support MX31 LITEKIT (LogicPD)"
 	select ARCH_MX31
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for MX31 LITEKIT platform. This includes specific
 	  configurations for the board and its peripherals.
@@ -61,6 +64,7 @@ config MACH_MX31_3DS
 config MACH_MX31MOBOARD
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
 	select ARCH_MX31
+	select MXC_ULPI if USB_ULPI
 	help
 	  Include support for mx31moboard platform. This includes specific
 	  configurations for the board and its peripherals.
@@ -100,4 +104,12 @@ config MACH_MX35_3DS
 	help
 	  Include support for MX35PDK platform. This includes specific
 	  configurations for the board and its peripherals.
+
+config MACH_KZM_ARM11_01
+	bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
+	select ARCH_MX31
+	help
+	  Include support for KZM-ARM11-01. This includes specific
+	  configurations for the board and its peripherals.
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/kzmarm11.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/kzmarm11.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/kzmarm11.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/kzmarm11.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,268 @@
+/*
+ * KZM-ARM11-01 support
+ *  Copyright (C) 2009  Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * based on code for MX31ADS,
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. 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
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/types.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-kzmarm11.h>
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/memory.h>
+
+#include "devices.h"
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*
+ * KZM-ARM11-01 has an external UART on FPGA
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase	= IO_ADDRESS(KZM_ARM11_16550),
+		.mapbase	= KZM_ARM11_16550,
+		.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.irqflags	= IRQ_TYPE_EDGE_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 0,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_BUGGY_UART,
+	},
+	{},
+};
+
+static struct resource serial8250_resources[] = {
+	{
+		.start	= KZM_ARM11_16550,
+		.end	= KZM_ARM11_16550 + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device serial_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.dev		= {
+				.platform_data = serial_platform_data,
+			  },
+	.num_resources	= ARRAY_SIZE(serial8250_resources),
+	.resource	= serial8250_resources,
+};
+
+static int __init kzm_init_ext_uart(void)
+{
+	u8 tmp;
+
+	/*
+	 * GPIO 1-1: external UART interrupt line
+	 */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+	/*
+	 * Unmask UART interrupt
+	 */
+	tmp = __raw_readb(IO_ADDRESS(KZM_ARM11_CTL1));
+	tmp |= 0x2;
+	__raw_writeb(tmp, IO_ADDRESS(KZM_ARM11_CTL1));
+
+	return platform_device_register(&serial_device);
+}
+#else
+static inline int kzm_init_ext_uart(void)
+{
+	return 0;
+}
+#endif
+
+/*
+ * SMSC LAN9118
+ */
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct smsc911x_platform_config kzm_smsc9118_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct resource kzm_smsc9118_resources[] = {
+	{
+		.start	= CS5_BASE_ADDR,
+		.end	= CS5_BASE_ADDR + SZ_128K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+		.end	= IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+static struct platform_device kzm_smsc9118_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(kzm_smsc9118_resources),
+	.resource	= kzm_smsc9118_resources,
+	.dev		= {
+				.platform_data = &kzm_smsc9118_config,
+			  },
+};
+
+static int __init kzm_init_smsc9118(void)
+{
+	/*
+	 * GPIO 1-2: SMSC9118 interrupt line
+	 */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
+
+	return platform_device_register(&kzm_smsc9118_device);
+}
+#else
+static inline int kzm_init_smsc9118(void)
+{
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init kzm_init_imx_uart(void)
+{
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+}
+#else
+static inline void kzm_init_imx_uart(void)
+{
+}
+#endif
+
+static int kzm_pins[] __initdata = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	MX31_PIN_DCD_DCE1__DCD_DCE1,
+	MX31_PIN_RI_DCE1__RI_DCE1,
+	MX31_PIN_DSR_DCE1__DSR_DCE1,
+	MX31_PIN_DTR_DCE1__DTR_DCE1,
+	MX31_PIN_CTS2__CTS2,
+	MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2,
+	MX31_PIN_RXD2__RXD2,
+	MX31_PIN_DCD_DTE1__DCD_DTE2,
+	MX31_PIN_RI_DTE1__RI_DTE2,
+	MX31_PIN_DSR_DTE1__DSR_DTE2,
+	MX31_PIN_DTR_DTE1__DTR_DTE2,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init kzm_board_init(void)
+{
+	mxc_iomux_setup_multiple_pins(kzm_pins,
+				      ARRAY_SIZE(kzm_pins), "kzm");
+	kzm_init_ext_uart();
+	kzm_init_smsc9118();
+	kzm_init_imx_uart();
+
+	pr_info("Clock input source is 26MHz\n");
+}
+
+/*
+ * This structure defines static mappings for the kzm-arm11-01 board.
+ */
+static struct map_desc kzm_io_desc[] __initdata = {
+	{
+		.virtual	= CS4_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
+		.length		= CS4_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= CS5_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(CS5_BASE_ADDR),
+		.length		= CS5_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init kzm_map_io(void)
+{
+	mx31_map_io();
+	iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
+}
+
+static void __init kzm_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer kzm_timer = {
+	.init   = kzm_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_KZM_ARM11_01 data structure.
+ */
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+	.phys_io        = AIPS1_BASE_ADDR,
+	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = kzm_map_io,
+	.init_irq       = mx31_init_irq,
+	.init_machine   = kzm_board_init,
+	.timer          = &kzm_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,12 +4,12 @@
 
 # Object file lists.
 
-obj-y				:= mm.o devices.o
+obj-y				:= mm.o devices.o cpu.o
 obj-$(CONFIG_ARCH_MX31)		+= clock.o iomux.o
 obj-$(CONFIG_ARCH_MX35)		+= clock-imx35.o
 obj-$(CONFIG_MACH_MX31ADS)	+= mx31ads.o
 obj-$(CONFIG_MACH_MX31LILLY)	+= mx31lilly.o mx31lilly-db.o
-obj-$(CONFIG_MACH_MX31LITE)	+= mx31lite.o
+obj-$(CONFIG_MACH_MX31LITE)	+= mx31lite.o mx31lite-db.o
 obj-$(CONFIG_MACH_PCM037)	+= pcm037.o
 obj-$(CONFIG_MACH_PCM037_EET)	+= pcm037_eet.o
 obj-$(CONFIG_MACH_MX31_3DS)	+= mx31pdk.o
@@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_QONG)		+= qong.o
 obj-$(CONFIG_MACH_PCM043)	+= pcm043.o
 obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o
 obj-$(CONFIG_MACH_MX35_3DS)	+= mx35pdk.o
+obj-$(CONFIG_MACH_KZM_ARM11_01)	+= kzmarm11.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mm.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mm.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,6 +65,11 @@ static struct map_desc mxc_io_desc[] __i
 		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
 		.length		= AIPS2_SIZE,
 		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual = SPBA0_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
+		.length = SPBA0_SIZE,
+		.type = MT_DEVICE_NONSHARED
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31ads.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31ads.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31ads.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31ads.c	2010-02-24 13:52:17.000000000 -0500
@@ -173,6 +173,7 @@ static void expio_unmask_irq(u32 irq)
 }
 
 static struct irq_chip expio_irq_chip = {
+	.name = "EXPIO(CPLD)",
 	.ack = expio_ack_irq,
 	.mask = expio_mask_irq,
 	.unmask = expio_unmask_irq,
@@ -302,6 +303,7 @@ static struct regulator_init_data ldo1_d
 		.min_uV = 2800000,
 		.max_uV = 2800000,
 		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 		.apply_uV = 1,
 	},
 };
@@ -322,6 +324,7 @@ static struct regulator_init_data ldo2_d
 		.min_uV = 3300000,
 		.max_uV = 3300000,
 		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 		.apply_uV = 1,
 	},
 	.num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
@@ -459,6 +462,7 @@ static int mx31_wm8350_init(struct wm835
 
 static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
 	.init = mx31_wm8350_init,
+	.irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
 };
 #endif
 
@@ -494,11 +498,6 @@ static void mxc_init_i2c(void)
  */
 static struct map_desc mx31ads_io_desc[] __initdata = {
 	{
-		.virtual	= SPBA0_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(SPBA0_BASE_ADDR),
-		.length		= SPBA0_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
 		.virtual	= CS4_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
 		.length		= CS4_SIZE / 2,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lilly.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lilly.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,8 @@
 #include <linux/interrupt.h>
 #include <linux/smsc911x.h>
 #include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13783.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -41,6 +43,7 @@
 #include <mach/common.h>
 #include <mach/iomux-mx3.h>
 #include <mach/board-mx31lilly.h>
+#include <mach/spi.h>
 
 #include "devices.h"
 
@@ -108,7 +111,36 @@ static struct platform_device physmap_fl
 static struct platform_device *devices[] __initdata = {
 	&smsc91x_device,
 	&physmap_flash_device,
-	&mxc_i2c_device1,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(1),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi0_pdata = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info mc13783_dev __initdata = {
+	.modalias	= "mc13783",
+	.max_speed_hz	= 1000000,
+	.bus_num	= 1,
+	.chip_select	= 0,
+	.platform_data	= &mc13783_pdata,
 };
 
 static int mx31lilly_baseboard;
@@ -128,8 +160,27 @@ static void __init mx31lilly_board_init(
 	}
 
 	mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__SCL, "I2C SCL");
-	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__SDA, "I2C SDA");
+
+	/* SPI */
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
+
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1");
+	mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2");
+
+	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(&mc13783_dev, 1);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lilly-db.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly-db.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lilly-db.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lilly-db.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,6 +109,9 @@ static int mxc_mmc1_get_ro(struct device
 
 static int gpio_det, gpio_wp;
 
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
 static int mxc_mmc1_init(struct device *dev,
 			 irq_handler_t detect_irq, void *data)
 {
@@ -117,6 +120,13 @@ static int mxc_mmc1_init(struct device *
 	gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1);
 	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0);
 
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
+
 	ret = gpio_request(gpio_det, "MMC detect");
 	if (ret)
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lite.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
  *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
  *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright (C) 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
@@ -25,38 +26,47 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/mtd/physmap.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/common.h>
 #include <asm/page.h>
 #include <asm/setup.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
 #include <mach/board-mx31lite.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 #include <mach/irqs.h>
 #include <mach/mxc_nand.h>
+#include <mach/spi.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
 #include "devices.h"
 
 /*
- * This file contains the board-specific initialization routines.
+ * This file contains the module-specific initialization routines.
  */
 
 static unsigned int mx31lite_pins[] = {
-	/* UART1 */
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
 	/* LAN9117 IRQ pin */
 	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
-};
-
-static struct imxuart_platform_data uart_pdata = {
-	.flags = IMXUART_HAVE_RTSCTS,
+	/* SPI 1 */
+	MX31_PIN_CSPI2_SCLK__SCLK,
+	MX31_PIN_CSPI2_MOSI__MOSI,
+	MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0,
+	MX31_PIN_CSPI2_SS1__SS1,
+	MX31_PIN_CSPI2_SS2__SS2,
 };
 
 static struct mxc_nand_platform_data mx31lite_nand_board_info = {
@@ -93,15 +103,117 @@ static struct platform_device smsc911x_d
 };
 
 /*
+ * SPI
+ *
+ * The MC13783 is the only hard-wired SPI device on the module.
+ */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect	= spi_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.flags  = MC13783_USE_RTC |
+		  MC13783_USE_REGULATOR,
+};
+
+static struct spi_board_info mc13783_spi_dev __initdata = {
+	.modalias       = "mc13783",
+	.max_speed_hz   = 1000000,
+	.bus_num	= 1,
+	.chip_select    = 0,
+	.platform_data  = &mc13783_pdata,
+	.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+/*
+ * USB
+ */
+
+#if defined(CONFIG_USB_ULPI)
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbh2_init(struct platform_device *pdev)
+{
+	int pins[] = {
+		MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+		MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+		MX31_PIN_USBH2_CLK__USBH2_CLK,
+		MX31_PIN_USBH2_DIR__USBH2_DIR,
+		MX31_PIN_USBH2_NXT__USBH2_NXT,
+		MX31_PIN_USBH2_STP__USBH2_STP,
+	};
+
+	mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+	/* chip select */
+	mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+				"USBH2_CS");
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init   = usbh2_init,
+	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags  = MXC_EHCI_POWER_PINS_ENABLED,
+};
+#endif
+
+/*
+ * NOR flash
+ */
+
+static struct physmap_flash_data nor_flash_data = {
+	.width  = 2,
+};
+
+static struct resource nor_flash_resource = {
+	.start  = 0xa0000000,
+	.end    = 0xa1ffffff,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+	.name   = "physmap-flash",
+	.id     = 0,
+	.dev    = {
+		.platform_data  = &nor_flash_data,
+	},
+	.resource = &nor_flash_resource,
+	.num_resources = 1,
+};
+
+
+
+/*
  * This structure defines the MX31 memory map.
  */
 static struct map_desc mx31lite_io_desc[] __initdata = {
 	{
-		.virtual = SPBA0_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
-		.length = SPBA0_SIZE,
-		.type = MT_DEVICE_NONSHARED
-	}, {
 		.virtual = CS4_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
 		.length = CS4_SIZE,
@@ -118,19 +230,42 @@ void __init mx31lite_map_io(void)
 	iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
 }
 
-/*
- * Board specific initialization.
- */
+static int mx31lite_baseboard;
+core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
+
 static void __init mxc_board_init(void)
 {
 	int ret;
 
+	switch (mx31lite_baseboard) {
+	case MX31LITE_NOBOARD:
+		break;
+	case MX31LITE_DB:
+		mx31lite_db_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
+				mx31lite_baseboard);
+	}
+
 	mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
 				      "mx31lite");
 
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	/* NOR and NAND flash */
+	platform_device_register(&physmap_flash_device);
 	mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
 
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(&mc13783_spi_dev, 1);
+
+#if defined(CONFIG_USB_ULPI)
+	/* USB */
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+				USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+
 	/* SMSC9117 IRQ pin */
 	ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
 	if (ret)
@@ -150,12 +285,7 @@ struct sys_timer mx31lite_timer = {
 	.init	= mx31lite_timer_init,
 };
 
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31LITE data structure.
- */
-
-MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT")
+MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
 	/* Maintainer: Freescale Semiconductor, Inc. */
 	.phys_io        = AIPS1_BASE_ADDR,
 	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lite-db.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite-db.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31lite-db.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31lite-db.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,198 @@
+/*
+ *  LogicPD i.MX31 SOM-LV development board support
+ *
+ *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  based on code for other MX31 boards,
+ *
+ *    Copyright 2005-2007 Freescale Semiconductor
+ *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lite.h>
+#include <mach/mmc.h>
+#include <mach/spi.h>
+
+#include "devices.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'.
+ * If you design an own baseboard for the module, use this file as base
+ * for support code.
+ */
+
+static unsigned int litekit_db_board_pins[] __initdata = {
+	/* UART1 */
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	/* SPI 0 */
+	MX31_PIN_CSPI1_SCLK__SCLK,
+	MX31_PIN_CSPI1_MOSI__MOSI,
+	MX31_PIN_CSPI1_MISO__MISO,
+	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI1_SS0__SS0,
+	MX31_PIN_CSPI1_SS1__SS1,
+	MX31_PIN_CSPI1_SS2__SS2,
+};
+
+/* UART */
+static struct imxuart_platform_data uart_pdata __initdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC */
+
+static int gpio_det, gpio_wp;
+
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+}
+
+static int mxc_mmc1_init(struct device *dev,
+			 irq_handler_t detect_irq, void *data)
+{
+	int ret;
+
+	gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
+	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
+
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
+
+	ret = gpio_request(gpio_det, "MMC detect");
+	if (ret)
+		return ret;
+
+	ret = gpio_request(gpio_wp, "MMC w/p");
+	if (ret)
+		goto exit_free_det;
+
+	gpio_direction_input(gpio_det);
+	gpio_direction_input(gpio_wp);
+
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "MMC detect", data);
+	if (ret)
+		goto exit_free_wp;
+
+	return 0;
+
+exit_free_wp:
+	gpio_free(gpio_wp);
+
+exit_free_det:
+	gpio_free(gpio_det);
+
+	return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+	gpio_free(gpio_det);
+	gpio_free(gpio_wp);
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+}
+
+static struct imxmmc_platform_data mmc_pdata = {
+	.get_ro	 = mxc_mmc1_get_ro,
+	.init	   = mxc_mmc1_init,
+	.exit	   = mxc_mmc1_exit,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(1),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi0_pdata = {
+	.chipselect	= spi_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
+};
+
+/* GPIO LEDs */
+
+static struct gpio_led litekit_leds[] = {
+	{
+		.name           = "GPIO0",
+		.gpio           = IOMUX_TO_GPIO(MX31_PIN_COMPARE),
+		.active_low     = 1,
+		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
+	},
+	{
+		.name           = "GPIO1",
+		.gpio           = IOMUX_TO_GPIO(MX31_PIN_CAPTURE),
+		.active_low     = 1,
+		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
+	}
+};
+
+static struct gpio_led_platform_data litekit_led_platform_data = {
+	.leds           = litekit_leds,
+	.num_leds       = ARRAY_SIZE(litekit_leds),
+};
+
+static struct platform_device litekit_led_device = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data = &litekit_led_platform_data,
+	},
+};
+
+void __init mx31lite_db_init(void)
+{
+	mxc_iomux_setup_multiple_pins(litekit_db_board_pins,
+					ARRAY_SIZE(litekit_db_board_pins),
+					"development board pins");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
+	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
+	platform_device_register(&litekit_led_device);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
@@ -26,8 +27,14 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
 #include <linux/types.h>
 
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
@@ -37,16 +44,20 @@
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/ipu.h>
 #include <mach/i2c.h>
 #include <mach/mmc.h>
-#include <mach/mx31.h>
+#include <mach/mxc_ehci.h>
+#include <mach/mx3_camera.h>
+#include <mach/spi.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 
 static unsigned int moboard_pins[] = {
 	/* UART0 */
-	MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
 	MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+	MX31_PIN_CTS1__GPIO2_7,
 	/* UART4 */
 	MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
 	MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
@@ -73,12 +84,31 @@ static unsigned int moboard_pins[] = {
 	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
 	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
 	MX31_PIN_USB_OC__GPIO1_30,
+	/* USB H2 */
+	MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+	MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+	MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
+	MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
+	MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
+	MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
+	MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
+	MX31_PIN_SCK6__GPIO1_25,
 	/* LEDs */
 	MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
 	MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
 	/* SEL */
 	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
 	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+	/* SPI1 */
+	MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
+	/* Atlas IRQ */
+	MX31_PIN_GPIO1_3__GPIO1_3,
+	/* SPI2 */
+	MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
+	MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS1__CSPI3_SS1,
 };
 
 static struct physmap_flash_data mx31moboard_flash_data = {
@@ -101,7 +131,18 @@ static struct platform_device mx31moboar
 	.num_resources = 1,
 };
 
-static struct imxuart_platform_data uart_pdata = {
+static int moboard_uart0_init(struct platform_device *pdev)
+{
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
+	gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+	return 0;
+}
+
+static struct imxuart_platform_data uart0_pdata = {
+	.init = moboard_uart0_init,
+};
+
+static struct imxuart_platform_data uart4_pdata = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
@@ -113,6 +154,103 @@ static struct imxi2c_platform_data moboa
 	.bitrate = 100000,
 };
 
+static int moboard_spi1_cs[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master moboard_spi1_master = {
+	.chipselect	= moboard_spi1_cs,
+	.num_chipselect	= ARRAY_SIZE(moboard_spi1_cs),
+};
+
+static struct regulator_consumer_supply sdhc_consumers[] = {
+	{
+		.dev	= &mxcsdhc_device0.dev,
+		.supply	= "sdhc0_vcc",
+	},
+	{
+		.dev	= &mxcsdhc_device1.dev,
+		.supply	= "sdhc1_vcc",
+	},
+};
+
+static struct regulator_init_data sdhc_vreg_data = {
+	.constraints = {
+		.min_uV = 2700000,
+		.max_uV = 3000000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
+	.consumer_supplies = sdhc_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+	{
+		.dev	= &mx3_camera.dev,
+		.supply	= "cam_vcc",
+	},
+};
+
+static struct regulator_init_data cam_vreg_data = {
+	.constraints = {
+		.min_uV = 2700000,
+		.max_uV = 3000000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+			REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+			REGULATOR_MODE_FAST,
+		.always_on = 0,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+	.consumer_supplies = cam_consumers,
+};
+
+static struct mc13783_regulator_init_data moboard_regulators[] = {
+	{
+		.id = MC13783_REGU_VMMC1,
+		.init_data = &sdhc_vreg_data,
+	},
+	{
+		.id = MC13783_REGU_VCAM,
+		.init_data = &cam_vreg_data,
+	},
+};
+
+static struct mc13783_platform_data moboard_pmic = {
+	.regulators = moboard_regulators,
+	.num_regulators = ARRAY_SIZE(moboard_regulators),
+	.flags = MC13783_USE_REGULATOR | MC13783_USE_RTC |
+		MC13783_USE_ADC,
+};
+
+static struct spi_board_info moboard_spi_board_info[] __initdata = {
+	{
+		.modalias = "mc13783",
+		.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+		.max_speed_hz = 300000,
+		.bus_num = 1,
+		.chip_select = 0,
+		.platform_data = &moboard_pmic,
+		.mode = SPI_CS_HIGH,
+	},
+};
+
+static int moboard_spi2_cs[] = {
+	MXC_SPI_CS(1),
+};
+
+static struct spi_imx_master moboard_spi2_master = {
+	.chipselect	= moboard_spi2_cs,
+	.num_chipselect	= ARRAY_SIZE(moboard_spi2_cs),
+};
+
 #define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
 #define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
 
@@ -208,6 +346,61 @@ static struct fsl_usb2_platform_data usb
 	.phy_mode	= FSL_USB2_PHY_ULPI,
 };
 
+#if defined(CONFIG_USB_ULPI)
+
+#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int moboard_usbh2_hw_init(struct platform_device *pdev)
+{
+	int ret = gpio_request(USBH2_EN_B, "usbh2-en");
+	if (ret)
+		return ret;
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	gpio_direction_output(USBH2_EN_B, 0);
+
+	return 0;
+}
+
+static int moboard_usbh2_hw_exit(struct platform_device *pdev)
+{
+	gpio_free(USBH2_EN_B);
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init	= moboard_usbh2_hw_init,
+	.exit	= moboard_usbh2_hw_exit,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static int __init moboard_usbh2_init(void)
+{
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+}
+#else
+static inline int moboard_usbh2_init(void) { return 0; }
+#endif
+
+
 static struct gpio_led mx31moboard_leds[] = {
 	{
 		.name 	= "coreboard-led-0:red:running",
@@ -266,11 +459,48 @@ static void mx31moboard_init_sel_gpios(v
 	}
 }
 
+static struct ipu_platform_data mx3_ipu_data = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&mx31moboard_flash,
 	&mx31moboard_leds_device,
 };
 
+static struct mx3_camera_pdata camera_pdata = {
+	.dma_dev	= &mx3_ipu.dev,
+	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz	= 4800,
+};
+
+#define CAMERA_BUF_SIZE	(4*1024*1024)
+
+static int __init mx31moboard_cam_alloc_dma(const size_t buf_size)
+{
+	dma_addr_t dma_handle;
+	void *buf;
+	int dma;
+
+	if (buf_size < 2 * 1024 * 1024)
+		return -EINVAL;
+
+	buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	memset(buf, 0, buf_size);
+
+	dma = dma_declare_coherent_memory(&mx3_camera.dev,
+					dma_handle, dma_handle, buf_size,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+	/* The way we call dma_declare_coherent_memory only a malloc can fail */
+	return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
+}
+
 static int mx31moboard_baseboard;
 core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
 
@@ -284,20 +514,34 @@ static void __init mxc_board_init(void)
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-	mxc_register_device(&mxc_uart_device4, &uart_pdata);
+	mxc_register_device(&mxc_uart_device0, &uart0_pdata);
+
+	mxc_register_device(&mxc_uart_device4, &uart4_pdata);
 
 	mx31moboard_init_sel_gpios();
 
 	mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
 	mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
 
+	mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
+	mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
+
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+	spi_register_board_info(moboard_spi_board_info,
+		ARRAY_SIZE(moboard_spi_board_info));
+
 	mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
 
+	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+	if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
+		mxc_register_device(&mx3_camera, &camera_pdata);
+
 	usb_xcvr_reset();
 
 	moboard_usbotg_init();
 	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+	moboard_usbh2_init();
 
 	switch (mx31moboard_baseboard) {
 	case MX31NOBOARD:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,11 +22,15 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 
+#include <linux/usb/otg.h>
+
 #include <mach/common.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 #include <mach/hardware.h>
 #include <mach/mmc.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 
@@ -39,6 +43,12 @@ static unsigned int devboard_pins[] = {
 	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
 	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
 	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
+	/* USB H1 */
+	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -98,6 +108,80 @@ static struct imxmmc_platform_data sdhc2
 	.exit	= devboard_sdhc2_exit,
 };
 
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int devboard_usbh1_hw_init(struct platform_device *pdev)
+{
+	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+	return 0;
+}
+
+#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int devboard_isp1105_init(struct otg_transceiver *otg)
+{
+	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+	if (ret)
+		return ret;
+	/* single ended */
+	gpio_direction_output(USBH1_MODE, 0);
+
+	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+	if (ret) {
+		gpio_free(USBH1_MODE);
+		return ret;
+	}
+	gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+
+static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+	if (on)
+		gpio_set_value(USBH1_VBUSEN_B, 0);
+	else
+		gpio_set_value(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata = {
+	.init	= devboard_usbh1_hw_init,
+	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
+};
+
+static int __init devboard_usbh1_init(void)
+{
+	struct otg_transceiver *otg;
+
+	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+	if (!otg)
+		return -ENOMEM;
+
+	otg->label	= "ISP1105";
+	otg->init	= devboard_isp1105_init;
+	otg->set_vbus	= devboard_isp1105_set_vbus;
+
+	usbh1_pdata.otg = otg;
+
+	return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+}
+
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
@@ -111,4 +195,6 @@ void __init mx31moboard_devboard_init(vo
 	mxc_register_device(&mxc_uart_device1, &uart_pdata);
 
 	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+
+	devboard_usbh1_init();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,17 +16,26 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
 
+#include <linux/usb/otg.h>
+
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 #include <mach/mmc.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include <media/soc_camera.h>
 
 #include "devices.h"
 
@@ -37,7 +46,6 @@ static unsigned int marxbot_pins[] = {
 	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
 	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
 	/* CSI */
-	MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5,
 	MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7,
 	MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9,
 	MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11,
@@ -45,10 +53,19 @@ static unsigned int marxbot_pins[] = {
 	MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15,
 	MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK,
 	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+	MX31_PIN_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5,
 	MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
 	MX31_PIN_TXD2__GPIO1_28,
 	/* dsPIC resets */
 	MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
+	/*battery detection */
+	MX31_PIN_LCS0__GPIO3_23,
+	/* USB H1 */
+	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
 };
 
 #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
@@ -120,6 +137,166 @@ static void dspics_resets_init(void)
 	}
 }
 
+static struct spi_board_info marxbot_spi_board_info[] __initdata = {
+	{
+		.modalias = "spidev",
+		.max_speed_hz = 300000,
+		.bus_num = 1,
+		.chip_select = 1, /* according spi1_cs[] ! */
+	},
+};
+
+#define TURRETCAM_POWER	IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define BASECAM_POWER	IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
+#define TURRETCAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+#define BASECAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_CSI_D4)
+#define CAM_CHOICE	IOMUX_TO_GPIO(MX31_PIN_TXD2)
+
+static int marxbot_basecam_power(struct device *dev, int on)
+{
+	gpio_set_value(BASECAM_POWER, !on);
+	return 0;
+}
+
+static int marxbot_basecam_reset(struct device *dev)
+{
+	gpio_set_value(BASECAM_RST_B, 0);
+	udelay(100);
+	gpio_set_value(BASECAM_RST_B, 1);
+	return 0;
+}
+
+static struct i2c_board_info marxbot_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("mt9t031", 0x5d),
+	},
+};
+
+static struct soc_camera_link base_iclink = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.power		= marxbot_basecam_power,
+	.reset		= marxbot_basecam_reset,
+	.board_info	= &marxbot_i2c_devices[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "mt9t031",
+};
+
+static struct platform_device marxbot_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &base_iclink,
+		},
+	},
+};
+
+static struct platform_device *marxbot_cameras[] __initdata = {
+	&marxbot_camera[0],
+};
+
+static int __init marxbot_cam_init(void)
+{
+	int ret = gpio_request(CAM_CHOICE, "cam-choice");
+	if (ret)
+		return ret;
+	gpio_direction_output(CAM_CHOICE, 1);
+
+	ret = gpio_request(BASECAM_RST_B, "basecam-reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(BASECAM_RST_B, 1);
+	ret = gpio_request(BASECAM_POWER, "basecam-standby");
+	if (ret)
+		return ret;
+	gpio_direction_output(BASECAM_POWER, 0);
+
+	ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(TURRETCAM_RST_B, 1);
+	ret = gpio_request(TURRETCAM_POWER, "turretcam-standby");
+	if (ret)
+		return ret;
+	gpio_direction_output(TURRETCAM_POWER, 0);
+
+	return 0;
+}
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int marxbot_usbh1_hw_init(struct platform_device *pdev)
+{
+	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+	return 0;
+}
+
+#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int marxbot_isp1105_init(struct otg_transceiver *otg)
+{
+	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+	if (ret)
+		return ret;
+	/* single ended */
+	gpio_direction_output(USBH1_MODE, 0);
+
+	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+	if (ret) {
+		gpio_free(USBH1_MODE);
+		return ret;
+	}
+	gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+
+static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+	if (on)
+		gpio_set_value(USBH1_VBUSEN_B, 0);
+	else
+		gpio_set_value(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata = {
+	.init	= marxbot_usbh1_hw_init,
+	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
+};
+
+static int __init marxbot_usbh1_init(void)
+{
+	struct otg_transceiver *otg;
+
+	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+	if (!otg)
+		return -ENOMEM;
+
+	otg->label	= "ISP1105";
+	otg->init	= marxbot_isp1105_init;
+	otg->set_vbus	= marxbot_isp1105_set_vbus;
+
+	usbh1_pdata.otg = otg;
+
+	return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+}
+
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
@@ -133,4 +310,17 @@ void __init mx31moboard_marxbot_init(voi
 	dspics_resets_init();
 
 	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+
+	spi_register_board_info(marxbot_spi_board_info,
+		ARRAY_SIZE(marxbot_spi_board_info));
+
+	marxbot_cam_init();
+	platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras));
+
+	/* battery present pin */
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+	gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
+
+	marxbot_usbh1_init();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31pdk.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31pdk.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx31pdk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx31pdk.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,11 +211,6 @@ static int __init mx31pdk_init_expio(voi
  */
 static struct map_desc mx31pdk_io_desc[] __initdata = {
 	{
-		.virtual = SPBA0_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
-		.length = SPBA0_SIZE,
-		.type = MT_DEVICE_NONSHARED,
-	}, {
 		.virtual = CS5_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(CS5_BASE_ADDR),
 		.length = CS5_SIZE,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx35pdk.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx35pdk.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/mx35pdk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/mx35pdk.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/memory.h>
 #include <linux/gpio.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -69,6 +70,15 @@ static struct pad_desc mx35pdk_pads[] =
 	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
 	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
 	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* USBOTG */
+	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+};
+
+/* OTG config */
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
 };
 
 /*
@@ -81,6 +91,8 @@ static void __init mxc_board_init(void)
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
 }
 
 static void __init mx35pdk_timer_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/pcm037.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/pcm037.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm037.c	2010-02-24 13:52:17.000000000 -0500
@@ -322,16 +322,25 @@ static int pcm037_camera_power(struct de
 	return 0;
 }
 
-static struct i2c_board_info pcm037_i2c_2_devices[] = {
+static struct i2c_board_info pcm037_i2c_camera[] = {
 	{
 		I2C_BOARD_INFO("mt9t031", 0x5d),
+	}, {
+		I2C_BOARD_INFO("mt9v022", 0x48),
 	},
 };
 
-static struct soc_camera_link iclink = {
+static struct soc_camera_link iclink_mt9v022 = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.board_info	= &pcm037_i2c_camera[1],
+	.i2c_adapter_id	= 2,
+	.module_name	= "mt9v022",
+};
+
+static struct soc_camera_link iclink_mt9t031 = {
 	.bus_id		= 0,		/* Must match with the camera ID */
 	.power		= pcm037_camera_power,
-	.board_info	= &pcm037_i2c_2_devices[0],
+	.board_info	= &pcm037_i2c_camera[0],
 	.i2c_adapter_id	= 2,
 	.module_name	= "mt9t031",
 };
@@ -345,11 +354,19 @@ static struct i2c_board_info pcm037_i2c_
 	}
 };
 
-static struct platform_device pcm037_camera = {
+static struct platform_device pcm037_mt9t031 = {
 	.name	= "soc-camera-pdrv",
 	.id	= 0,
 	.dev	= {
-		.platform_data = &iclink,
+		.platform_data = &iclink_mt9t031,
+	},
+};
+
+static struct platform_device pcm037_mt9v022 = {
+	.name	= "soc-camera-pdrv",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &iclink_mt9v022,
 	},
 };
 
@@ -449,7 +466,8 @@ static int __init pcm037_camera_alloc_dm
 static struct platform_device *devices[] __initdata = {
 	&pcm037_flash,
 	&pcm037_sram_device,
-	&pcm037_camera,
+	&pcm037_mt9t031,
+	&pcm037_mt9v022,
 };
 
 static struct ipu_platform_data mx3_ipu_data = {
@@ -599,7 +617,7 @@ static void __init mxc_board_init(void)
 	if (!ret)
 		gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
 	else
-		iclink.power = NULL;
+		iclink_mt9t031.power = NULL;
 
 	if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
 		mxc_register_device(&mx3_camera, &camera_pdata);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/pcm043.c linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm043.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-mx3/pcm043.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-mx3/pcm043.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,7 @@
 #include <mach/iomux-mx35.h>
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
+#include <mach/mxc_nand.h>
 
 #include "devices.h"
 
@@ -206,6 +207,11 @@ static struct pad_desc pcm043_pads[] = {
 	MX35_PAD_ATA_CS0__GPIO2_6,
 };
 
+static struct mxc_nand_platform_data pcm037_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
 /*
  * Board specific initialization.
  */
@@ -216,6 +222,7 @@ static void __init mxc_board_init(void)
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
 
 	mxc_register_device(&mxc_uart_device1, &uart_pdata);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/board-nhk8815.c linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/board-nhk8815.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/board-nhk8815.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/board-nhk8815.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
+#include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <asm/sizes.h>
@@ -25,11 +26,18 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+
+#include <plat/mtu.h>
+
 #include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 #include "clock.h"
 
+/* Initial value for SRC control register: all timers use MXTAL/8 source */
+#define SRC_CR_INIT_MASK	0x00007fff
+#define SRC_CR_INIT_VAL		0x2aaa8000
+
 /* These adresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
 	{
@@ -142,7 +150,7 @@ static struct mtd_partition nhk8815_onen
 	}
 };
 
-static struct flash_platform_data nhk8815_onenand_data = {
+static struct onenand_platform_data nhk8815_onenand_data = {
 	.parts		= nhk8815_onenand_partitions,
 	.nr_parts	= ARRAY_SIZE(nhk8815_onenand_partitions),
 };
@@ -156,7 +164,7 @@ static struct resource nhk8815_onenand_r
 };
 
 static struct platform_device nhk8815_onenand_device = {
-	.name		= "onenand",
+	.name		= "onenand-flash",
 	.id		= -1,
 	.dev		= {
 		.platform_data	= &nhk8815_onenand_data,
@@ -167,10 +175,10 @@ static struct platform_device nhk8815_on
 
 static void __init nhk8815_onenand_init(void)
 {
-#ifdef CONFIG_ONENAND
+#ifdef CONFIG_MTD_ONENAND
        /* Set up SMCS0 for OneNand */
-       writel(0x000030db, FSMC_BCR0);
-       writel(0x02100551, FSMC_BTR0);
+	writel(0x000030db, FSMC_BCR(0));
+	writel(0x02100551, FSMC_BTR(0));
 #endif
 }
 
@@ -239,6 +247,26 @@ static struct platform_device *nhk8815_p
 	/* will add more devices */
 };
 
+static void __init nomadik_timer_init(void)
+{
+	u32 src_cr;
+
+	/* Configure timer sources in "system reset controller" ctrl reg */
+	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
+	src_cr &= SRC_CR_INIT_MASK;
+	src_cr |= SRC_CR_INIT_VAL;
+	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
+
+	/* Save global pointer to mtu, used by platform timer code */
+	mtu_base = io_p2v(NOMADIK_MTU0_BASE);
+
+	nmdk_timer_init();
+}
+
+static struct sys_timer nomadik_timer = {
+	.init	= nomadik_timer_init,
+};
+
 static void __init nhk8815_platform_init(void)
 {
 	int i;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/include/mach/mtu.h linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/mtu.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/include/mach/mtu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/mtu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-#ifndef __ASM_ARCH_MTU_H
-#define __ASM_ARCH_MTU_H
-
-/*
- * The MTU device hosts four different counters, with 4 set of
- * registers. These are register names.
- */
-
-#define MTU_IMSC	0x00	/* Interrupt mask set/clear */
-#define MTU_RIS		0x04	/* Raw interrupt status */
-#define MTU_MIS		0x08	/* Masked interrupt status */
-#define MTU_ICR		0x0C	/* Interrupt clear register */
-
-/* per-timer registers take 0..3 as argument */
-#define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */
-#define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */
-#define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */
-#define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */
-
-/* bits for the control register */
-#define MTU_CRn_ENA		0x80
-#define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */
-#define MTU_CRn_PRESCALE_MASK	0x0c
-#define MTU_CRn_PRESCALE_1		0x00
-#define MTU_CRn_PRESCALE_16		0x04
-#define MTU_CRn_PRESCALE_256		0x08
-#define MTU_CRn_32BITS		0x02
-#define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/
-
-/* Other registers are usual amba/primecell registers, currently not used */
-#define MTU_ITCR	0xff0
-#define MTU_ITOP	0xff4
-
-#define MTU_PERIPH_ID0	0xfe0
-#define MTU_PERIPH_ID1	0xfe4
-#define MTU_PERIPH_ID2	0xfe8
-#define MTU_PERIPH_ID3	0xfeC
-
-#define MTU_PCELL0	0xff0
-#define MTU_PCELL1	0xff4
-#define MTU_PCELL2	0xff8
-#define MTU_PCELL3	0xffC
-
-#endif /* __ASM_ARCH_MTU_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/include/mach/setup.h linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/setup.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/include/mach/setup.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/include/mach/setup.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
 extern void cpu8815_map_io(void);
 extern void cpu8815_platform_init(void);
 extern void cpu8815_init_irq(void);
-extern struct sys_timer nomadik_timer;
+extern void nmdk_timer_init(void);
 
 #endif /* NOMADIK_8815 */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,13 +5,13 @@ menu "Nomadik boards"
 config MACH_NOMADIK_8815NHK
 	bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
 	select NOMADIK_8815
+	select HAS_MTU
 
 endmenu
 
 config NOMADIK_8815
 	bool
 
-
 config I2C_BITBANG_8815NHK
 	tristate "Driver for bit-bang busses found on the 8815 NHK"
 	depends on I2C && MACH_NOMADIK_8815NHK
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@
 
 # Object file lists.
 
-obj-y			+= clock.o timer.o gpio.o
+obj-y			+= clock.o gpio.o
 
 # Cpu revision
 obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/timer.c linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/timer.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-nomadik/timer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-nomadik/timer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,164 +0,0 @@
-/*
- *  linux/arch/arm/mach-nomadik/timer.c
- *
- * Copyright (C) 2008 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
- *
- * This 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/irq.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-#include <linux/jiffies.h>
-#include <asm/mach/time.h>
-#include <mach/mtu.h>
-
-#define TIMER_CTRL	0x80	/* No divisor */
-#define TIMER_PERIODIC	0x40
-#define TIMER_SZ32BIT	0x02
-
-/* Initial value for SRC control register: all timers use MXTAL/8 source */
-#define SRC_CR_INIT_MASK	0x00007fff
-#define SRC_CR_INIT_VAL		0x2aaa8000
-
-static u32	nmdk_count;		/* accumulated count */
-static u32	nmdk_cycle;		/* write-once */
-static __iomem void *mtu_base;
-
-/*
- * clocksource: the MTU device is a decrementing counters, so we negate
- * the value being read.
- */
-static cycle_t nmdk_read_timer(struct clocksource *cs)
-{
-	u32 count = readl(mtu_base + MTU_VAL(0));
-	return nmdk_count + nmdk_cycle - count;
-
-}
-
-static struct clocksource nmdk_clksrc = {
-	.name		= "mtu_0",
-	.rating		= 120,
-	.read		= nmdk_read_timer,
-	.shift		= 20,
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Clockevent device: currently only periodic mode is supported
- */
-static void nmdk_clkevt_mode(enum clock_event_mode mode,
-			     struct clock_event_device *dev)
-{
-	unsigned long flags;
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		/* enable interrupts -- and count current value? */
-		raw_local_irq_save(flags);
-		writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
-		raw_local_irq_restore(flags);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		BUG(); /* Not supported, yet */
-		/* FALLTHROUGH */
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_UNUSED:
-		/* disable irq */
-		raw_local_irq_save(flags);
-		writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
-		raw_local_irq_restore(flags);
-		break;
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
-}
-
-static struct clock_event_device nmdk_clkevt = {
-	.name		= "mtu_0",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
-	.shift		= 32,
-	.rating		= 100,
-	.set_mode	= nmdk_clkevt_mode,
-};
-
-/*
- * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
- * as we are the only users of mtu0 by now.
- */
-static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
-{
-	/* ack: "interrupt clear register" */
-	writel( 1 << 0, mtu_base + MTU_ICR);
-
-	/* we can't count lost ticks, unfortunately */
-	nmdk_count += nmdk_cycle;
-	nmdk_clkevt.event_handler(&nmdk_clkevt);
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static struct irqaction nmdk_timer_irq = {
-	.name		= "Nomadik Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.handler	= nmdk_timer_interrupt,
-};
-
-static void nmdk_timer_reset(void)
-{
-	u32 cr;
-
-	writel(0, mtu_base + MTU_CR(0)); /* off */
-
-	/* configure load and background-load, and fire it up */
-	writel(nmdk_cycle, mtu_base + MTU_LR(0));
-	writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
-	cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
-	writel(cr, mtu_base + MTU_CR(0));
-	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
-}
-
-static void __init nmdk_timer_init(void)
-{
-	u32 src_cr;
-	unsigned long rate;
-	int bits;
-
-	rate = CLOCK_TICK_RATE; /* 2.4MHz */
-	nmdk_cycle = (rate + HZ/2) / HZ;
-
-	/* Configure timer sources in "system reset controller" ctrl reg */
-	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
-	src_cr &= SRC_CR_INIT_MASK;
-	src_cr |= SRC_CR_INIT_VAL;
-	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
-
-	/* Save global pointer to mtu, used by functions above */
-	mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-
-	/* Init the timer and register clocksource */
-	nmdk_timer_reset();
-
-	nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
-	bits =  8*sizeof(nmdk_count);
-	nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
-
-	clocksource_register(&nmdk_clksrc);
-
-	/* Register irq and clockevents */
-	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-	nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
-	nmdk_clkevt.cpumask = cpumask_of(0);
-	clockevents_register_device(&nmdk_clkevt);
-}
-
-struct sys_timer nomadik_timer = {
-	.init		= nmdk_timer_init,
-};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ns9xxx/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ns9xxx/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ns9xxx/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@ static void handle_prio_irq(unsigned int
 	struct irqaction *action;
 	irqreturn_t action_ret;
 
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 
 	BUG_ON(desc->status & IRQ_INPROGRESS);
 
@@ -78,7 +78,7 @@ static void handle_prio_irq(unsigned int
 		goto out_mask;
 
 	desc->status |= IRQ_INPROGRESS;
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 
 	action_ret = handle_IRQ_event(irq, action);
 
@@ -87,7 +87,7 @@ static void handle_prio_irq(unsigned int
 	 * Maybe this function should go to kernel/irq/chip.c? */
 	note_interrupt(irq, desc, action_ret);
 
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	desc->status &= ~IRQ_INPROGRESS;
 
 	if (desc->status & IRQ_DISABLED)
@@ -97,7 +97,7 @@ out_mask:
 	/* ack unconditionally to unmask lower prio irqs */
 	desc->chip->ack(irq);
 
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 }
 #define handle_irq handle_prio_irq
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-ams-delta.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-ams-delta.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-ams-delta.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-ams-delta.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,13 +25,13 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/board-ams-delta.h>
+#include <plat/board-ams-delta.h>
 #include <mach/gpio.h>
-#include <mach/keypad.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/keypad.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
 
 static u8 ams_delta_latch1_reg;
 static u16 ams_delta_latch2_reg;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-fsample.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-fsample.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-fsample.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-fsample.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -26,14 +27,13 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/tc.h>
+#include <plat/tc.h>
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/fpga.h>
-#include <mach/nand.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
-#include <mach/board.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/board.h>
 
 /* fsample is pretty close to p2-sample */
 
@@ -100,6 +100,12 @@ static int fsample_keymap[] = {
 	0
 };
 
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
@@ -107,7 +113,7 @@ static struct resource smc91x_resources[
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= INT_730_MPU_EXT_NIRQ,
+		.start	= INT_7XX_MPU_EXT_NIRQ,
 		.end	= 0,
 		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
@@ -167,8 +173,40 @@ static struct platform_device nor_device
 	.resource	= &nor_resource,
 };
 
-static struct omap_nand_platform_data nand_data = {
-	.options	= NAND_SAMSUNG_LP_OPTIONS,
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd,	unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long mask;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+	if (ctrl & NAND_ALE)
+		mask |= 0x04;
+	writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define FSAMPLE_NAND_RB_GPIO_PIN	62
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data nand_data = {
+	.chip	= {
+		.nr_chips		= 1,
+		.chip_offset		= 0,
+		.options		= NAND_SAMSUNG_LP_OPTIONS,
+		.part_probe_types	= part_probes,
+	},
+	.ctrl	= {
+		.cmd_ctrl	= nand_cmd_ctl,
+		.dev_ready	= nand_dev_ready,
+	},
 };
 
 static struct resource nand_resource = {
@@ -178,7 +216,7 @@ static struct resource nand_resource = {
 };
 
 static struct platform_device nand_device = {
-	.name		= "omapnand",
+	.name		= "gen_nand",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &nand_data,
@@ -190,14 +228,17 @@ static struct platform_device nand_devic
 static struct platform_device smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(smc91x_resources),
 	.resource	= smc91x_resources,
 };
 
 static struct resource kp_resources[] = {
 	[0] = {
-		.start	= INT_730_MPUIO_KEYPAD,
-		.end	= INT_730_MPUIO_KEYPAD,
+		.start	= INT_7XX_MPUIO_KEYPAD,
+		.end	= INT_7XX_MPUIO_KEYPAD,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -233,13 +274,6 @@ static struct platform_device *devices[]
 	&lcd_device,
 };
 
-#define P2_NAND_RB_GPIO_PIN	62
-
-static int nand_dev_ready(struct omap_nand_platform_data *data)
-{
-	return gpio_get_value(P2_NAND_RB_GPIO_PIN);
-}
-
 static struct omap_lcd_config fsample_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
@@ -250,9 +284,9 @@ static struct omap_board_config_kernel f
 
 static void __init omap_fsample_init(void)
 {
-	if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
+	if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0)
 		BUG();
-	nand_data.dev_ready = nand_dev_ready;
+	gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN);
 
 	omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
 	omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
@@ -309,7 +343,7 @@ static void __init omap_fsample_map_io(v
 	/*
 	 * Hold GSM Reset until needed
 	 */
-	omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
+	omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL);
 
 	/*
 	 * UARTs -> done automagically by 8250 driver
@@ -320,21 +354,21 @@ static void __init omap_fsample_map_io(v
 	 */
 
 	/* Flash: CS0 timings setup */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
-	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
+	omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0);
+	omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0);
 
 	/*
 	 * Ethernet support through the debug board
 	 * CS1 timings setup
 	 */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
-	omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
+	omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1);
+	omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1);
 
 	/*
 	 * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
 	 * It is used as the Ethernet controller interrupt
 	 */
-	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
+	omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9);
 }
 
 MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-generic.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-generic.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,10 +23,10 @@
 #include <asm/mach/map.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
 
 static void __init omap_generic_init_irq(void)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h2.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
 #include <linux/i2c/tps65010.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
@@ -37,14 +38,13 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/mux.h>
-#include <mach/dma.h>
-#include <mach/tc.h>
-#include <mach/nand.h>
-#include <mach/irda.h>
-#include <mach/usb.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/irda.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
 
 #include "board-h2.h"
 
@@ -179,11 +179,43 @@ static struct mtd_partition h2_nand_part
 	},
 };
 
-/* dip switches control NAND chip access:  8 bit, 16 bit, or neither */
-static struct omap_nand_platform_data h2_nand_data = {
-	.options	= NAND_SAMSUNG_LP_OPTIONS,
-	.parts		= h2_nand_partitions,
-	.nr_parts	= ARRAY_SIZE(h2_nand_partitions),
+static void h2_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long mask;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+	if (ctrl & NAND_ALE)
+		mask |= 0x04;
+	writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define H2_NAND_RB_GPIO_PIN	62
+
+static int h2_nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(H2_NAND_RB_GPIO_PIN);
+}
+
+static const char *h2_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data h2_nand_platdata = {
+	.chip	= {
+		.nr_chips		= 1,
+		.chip_offset		= 0,
+		.nr_partitions		= ARRAY_SIZE(h2_nand_partitions),
+		.partitions		= h2_nand_partitions,
+		.options		= NAND_SAMSUNG_LP_OPTIONS,
+		.part_probe_types	= h2_part_probes,
+	},
+	.ctrl	= {
+		.cmd_ctrl	= h2_nand_cmd_ctl,
+		.dev_ready	= h2_nand_dev_ready,
+
+	},
 };
 
 static struct resource h2_nand_resource = {
@@ -191,15 +223,21 @@ static struct resource h2_nand_resource
 };
 
 static struct platform_device h2_nand_device = {
-	.name		= "omapnand",
+	.name		= "gen_nand",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &h2_nand_data,
+		.platform_data	= &h2_nand_platdata,
 	},
 	.num_resources	= 1,
 	.resource	= &h2_nand_resource,
 };
 
+static struct smc91x_platdata h2_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource h2_smc91x_resources[] = {
 	[0] = {
 		.start	= OMAP1610_ETHR_START,		/* Physical */
@@ -216,6 +254,9 @@ static struct resource h2_smc91x_resourc
 static struct platform_device h2_smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &h2_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(h2_smc91x_resources),
 	.resource	= h2_smc91x_resources,
 };
@@ -368,8 +409,6 @@ static struct omap_board_config_kernel h
 	{ OMAP_TAG_LCD,		&h2_lcd_config },
 };
 
-#define H2_NAND_RB_GPIO_PIN	62
-
 static void __init h2_init(void)
 {
 	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h2-mmc.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2-mmc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h2-mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h2-mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 
 #include <linux/i2c/tps65010.h>
 
-#include <mach/mmc.h>
+#include <plat/mmc.h>
 #include <mach/gpio.h>
 
 #include "board-h2.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h3.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c/tps65010.h>
+#include <linux/smc91x.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
@@ -40,13 +41,12 @@
 #include <asm/mach/map.h>
 
 #include <mach/irqs.h>
-#include <mach/mux.h>
-#include <mach/tc.h>
-#include <mach/nand.h>
-#include <mach/usb.h>
-#include <mach/keypad.h>
-#include <mach/dma.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/dma.h>
+#include <plat/common.h>
 
 #include "board-h3.h"
 
@@ -181,11 +181,43 @@ static struct mtd_partition nand_partiti
 	},
 };
 
-/* dip switches control NAND chip access:  8 bit, 16 bit, or neither */
-static struct omap_nand_platform_data nand_data = {
-	.options	= NAND_SAMSUNG_LP_OPTIONS,
-	.parts		= nand_partitions,
-	.nr_parts	= ARRAY_SIZE(nand_partitions),
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long mask;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+	if (ctrl & NAND_ALE)
+		mask |= 0x04;
+	writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define H3_NAND_RB_GPIO_PIN	10
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(H3_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data nand_platdata = {
+	.chip	= {
+		.nr_chips		= 1,
+		.chip_offset		= 0,
+		.nr_partitions		= ARRAY_SIZE(nand_partitions),
+		.partitions		= nand_partitions,
+		.options		= NAND_SAMSUNG_LP_OPTIONS,
+		.part_probe_types	= part_probes,
+	},
+	.ctrl	= {
+		.cmd_ctrl	= nand_cmd_ctl,
+		.dev_ready	= nand_dev_ready,
+
+	},
 };
 
 static struct resource nand_resource = {
@@ -193,15 +225,21 @@ static struct resource nand_resource = {
 };
 
 static struct platform_device nand_device = {
-	.name		= "omapnand",
+	.name		= "gen_nand",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &nand_data,
+		.platform_data	= &nand_platdata,
 	},
 	.num_resources	= 1,
 	.resource	= &nand_resource,
 };
 
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= OMAP1710_ETHR_START,		/* Physical */
@@ -218,6 +256,9 @@ static struct resource smc91x_resources[
 static struct platform_device smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(smc91x_resources),
 	.resource	= smc91x_resources,
 };
@@ -332,13 +373,6 @@ static struct i2c_board_info __initdata
 	},
 };
 
-#define H3_NAND_RB_GPIO_PIN	10
-
-static int nand_dev_ready(struct omap_nand_platform_data *data)
-{
-	return gpio_get_value(H3_NAND_RB_GPIO_PIN);
-}
-
 static void __init h3_init(void)
 {
 	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped
@@ -356,7 +390,7 @@ static void __init h3_init(void)
 	nand_resource.end += SZ_4K - 1;
 	if (gpio_request(H3_NAND_RB_GPIO_PIN, "NAND ready") < 0)
 		BUG();
-	nand_data.dev_ready = nand_dev_ready;
+	gpio_direction_input(H3_NAND_RB_GPIO_PIN);
 
 	/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
 	/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h3-mmc.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3-mmc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-h3-mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-h3-mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 
 #include <linux/i2c/tps65010.h>
 
-#include <mach/mmc.h>
+#include <plat/mmc.h>
 #include <mach/gpio.h>
 
 #include "board-h3.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-htcherald.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-htcherald.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-htcherald.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-htcherald.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,311 @@
+/*
+ * HTC Herald board configuration
+ * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
+ * Copyright (C) 2009 Wing Linux
+ *
+ * Based on the board-htcwizard.c file from the linwizard project:
+ * Copyright (C) 2006 Unai Uribarri
+ * Copyright (C) 2008 linwizard.sourceforge.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
+ * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
+ * General Public License for more details.
+ *
+ * You 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 <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/omap7xx.h>
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/keypad.h>
+#include <plat/usb.h>
+
+#include <mach/irqs.h>
+
+#include <linux/delay.h>
+
+/* LCD register definition */
+#define       OMAP_LCDC_CONTROL               (0xfffec000 + 0x00)
+#define       OMAP_LCDC_STATUS                (0xfffec000 + 0x10)
+#define       OMAP_DMA_LCD_CCR                (0xfffee300 + 0xc2)
+#define       OMAP_DMA_LCD_CTRL               (0xfffee300 + 0xc4)
+#define       OMAP_LCDC_CTRL_LCD_EN           (1 << 0)
+#define       OMAP_LCDC_STAT_DONE             (1 << 0)
+
+static struct omap_lcd_config htcherald_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel htcherald_config[] __initdata = {
+	{ OMAP_TAG_LCD, &htcherald_lcd_config },
+};
+
+/* Keyboard definition */
+
+static int htc_herald_keymap[] = {
+	KEY(0, 0, KEY_RECORD), /* Mail button */
+	KEY(0, 1, KEY_CAMERA), /* Camera */
+	KEY(0, 2, KEY_PHONE), /* Send key */
+	KEY(0, 3, KEY_VOLUMEUP), /* Volume up */
+	KEY(0, 4, KEY_F2),  /* Right bar (landscape) */
+	KEY(0, 5, KEY_MAIL), /* Win key (portrait) */
+	KEY(0, 6, KEY_DIRECTORY), /* Right bar (protrait) */
+	KEY(1, 0, KEY_LEFTCTRL), /* Windows key */
+	KEY(1, 1, KEY_COMMA),
+	KEY(1, 2, KEY_M),
+	KEY(1, 3, KEY_K),
+	KEY(1, 4, KEY_SLASH), /* OK key */
+	KEY(1, 5, KEY_I),
+	KEY(1, 6, KEY_U),
+	KEY(2, 0, KEY_LEFTALT),
+	KEY(2, 1, KEY_TAB),
+	KEY(2, 2, KEY_N),
+	KEY(2, 3, KEY_J),
+	KEY(2, 4, KEY_ENTER),
+	KEY(2, 5, KEY_H),
+	KEY(2, 6, KEY_Y),
+	KEY(3, 0, KEY_SPACE),
+	KEY(3, 1, KEY_L),
+	KEY(3, 2, KEY_B),
+	KEY(3, 3, KEY_V),
+	KEY(3, 4, KEY_BACKSPACE),
+	KEY(3, 5, KEY_G),
+	KEY(3, 6, KEY_T),
+	KEY(4, 0, KEY_CAPSLOCK), /* Shift */
+	KEY(4, 1, KEY_C),
+	KEY(4, 2, KEY_F),
+	KEY(4, 3, KEY_R),
+	KEY(4, 4, KEY_O),
+	KEY(4, 5, KEY_E),
+	KEY(4, 6, KEY_D),
+	KEY(5, 0, KEY_X),
+	KEY(5, 1, KEY_Z),
+	KEY(5, 2, KEY_S),
+	KEY(5, 3, KEY_W),
+	KEY(5, 4, KEY_P),
+	KEY(5, 5, KEY_Q),
+	KEY(5, 6, KEY_A),
+	KEY(6, 0, KEY_CONNECT), /* Voice button */
+	KEY(6, 2, KEY_CANCEL), /* End key */
+	KEY(6, 3, KEY_VOLUMEDOWN), /* Volume down */
+	KEY(6, 4, KEY_F1), /* Left bar (landscape) */
+	KEY(6, 5, KEY_WWW), /* OK button (portrait) */
+	KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
+	0
+};
+
+struct omap_kp_platform_data htcherald_kp_data = {
+	.rows	= 7,
+	.cols	= 7,
+	.delay = 20,
+	.rep = 1,
+	.keymap = htc_herald_keymap,
+};
+
+static struct resource kp_resources[] = {
+	[0] = {
+		.start	= INT_7XX_MPUIO_KEYPAD,
+		.end	= INT_7XX_MPUIO_KEYPAD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &htcherald_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(kp_resources),
+	.resource	= kp_resources,
+};
+
+/* USB Device */
+static struct omap_usb_config htcherald_usb_config __initdata = {
+	.otg = 0,
+	.register_host = 0,
+	.register_dev  = 1,
+	.hmc_mode = 4,
+	.pins[0] = 2,
+};
+
+/* LCD Device resources */
+static struct platform_device lcd_device = {
+	.name           = "lcd_htcherald",
+	.id             = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&kp_device,
+	&lcd_device,
+};
+
+/*
+ * Init functions from here on
+ */
+
+static void __init htcherald_lcd_init(void)
+{
+	u32 reg;
+	unsigned int tries = 200;
+
+	/* disable controller if active */
+	reg = omap_readl(OMAP_LCDC_CONTROL);
+	if (reg & OMAP_LCDC_CTRL_LCD_EN) {
+		reg &= ~OMAP_LCDC_CTRL_LCD_EN;
+		omap_writel(reg, OMAP_LCDC_CONTROL);
+
+		/* wait for end of frame */
+		while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
+			tries--;
+			if (!tries)
+				break;
+		}
+		if (!tries)
+			printk(KERN_WARNING "Timeout waiting for end of frame "
+			       "-- LCD may not be available\n");
+
+		/* turn off DMA */
+		reg = omap_readw(OMAP_DMA_LCD_CCR);
+		reg &= ~(1 << 7);
+		omap_writew(reg, OMAP_DMA_LCD_CCR);
+
+		reg = omap_readw(OMAP_DMA_LCD_CTRL);
+		reg &= ~(1 << 8);
+		omap_writew(reg, OMAP_DMA_LCD_CTRL);
+	}
+}
+
+static void __init htcherald_map_io(void)
+{
+	omap1_map_common_io();
+
+	/*
+	 * The LCD panel must be disabled and DMA turned off here, as doing
+	 * it later causes the LCD never to reinitialize.
+	 */
+	htcherald_lcd_init();
+
+	printk(KERN_INFO "htcherald_map_io done.\n");
+}
+
+static void __init htcherald_disable_watchdog(void)
+{
+	/* Disable watchdog if running */
+	if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
+		/*
+		 * disable a potentially running watchdog timer before
+		 * it kills us.
+		 */
+		printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
+		omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
+		omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
+	}
+}
+
+#define HTCHERALD_GPIO_USB_EN1 33
+#define HTCHERALD_GPIO_USB_EN2 73
+#define HTCHERALD_GPIO_USB_DM  35
+#define HTCHERALD_GPIO_USB_DP  36
+
+static void __init htcherald_usb_enable(void)
+{
+	unsigned int tries = 20;
+	unsigned int value = 0;
+
+	/* Request the GPIOs we need to control here */
+	if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
+		goto err1;
+
+	if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
+		goto err2;
+
+	if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
+		goto err3;
+
+	if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
+		goto err4;
+
+	/* force USB_EN GPIO to 0 */
+	do {
+		/* output low */
+		gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
+	} while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
+			--tries);
+
+	if (value == 1)
+		printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
+
+	gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */
+	gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */
+	gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */
+
+	goto done;
+
+err4:
+	gpio_free(HTCHERALD_GPIO_USB_DM);
+err3:
+	gpio_free(HTCHERALD_GPIO_USB_EN2);
+err2:
+	gpio_free(HTCHERALD_GPIO_USB_EN1);
+err1:
+	printk(KERN_ERR "Unabled to request GPIO for USB\n");
+done:
+	printk(KERN_INFO "USB setup complete.\n");
+}
+
+static void __init htcherald_init(void)
+{
+	printk(KERN_INFO "HTC Herald init.\n");
+
+	omap_gpio_init();
+
+	omap_board_config = htcherald_config;
+	omap_board_config_size = ARRAY_SIZE(htcherald_config);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	htcherald_disable_watchdog();
+
+	htcherald_usb_enable();
+	omap_usb_init(&htcherald_usb_config);
+}
+
+static void __init htcherald_init_irq(void)
+{
+	printk(KERN_INFO "htcherald_init_irq.\n");
+	omap1_init_common_hw();
+	omap_init_irq();
+}
+
+MACHINE_START(HERALD, "HTC Herald")
+	/* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
+	/* Maintainer: wing-linux.sourceforge.net */
+	.phys_io        = 0xfff00000,
+	.io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params    = 0x10000100,
+	.map_io         = htcherald_map_io,
+	.init_irq       = htcherald_init_irq,
+	.init_machine   = htcherald_init,
+	.timer          = &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-innovator.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-innovator.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-innovator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-innovator.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -30,14 +31,14 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/mux.h>
-#include <mach/fpga.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
 #include <mach/gpio.h>
-#include <mach/tc.h>
-#include <mach/usb.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
-#include <mach/mmc.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/mmc.h>
 
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define INNOVATOR1610_ETHR_START	0x04000300
@@ -142,6 +143,11 @@ static struct platform_device innovator_
 	.resource	= innovator_kp_resources,
 };
 
+static struct smc91x_platdata innovator_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
 
 #ifdef CONFIG_ARCH_OMAP15XX
 
@@ -175,6 +181,9 @@ static struct resource innovator1510_smc
 static struct platform_device innovator1510_smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &innovator_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(innovator1510_smc91x_resources),
 	.resource	= innovator1510_smc91x_resources,
 };
@@ -241,6 +250,9 @@ static struct resource innovator1610_smc
 static struct platform_device innovator1610_smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &innovator_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(innovator1610_smc91x_resources),
 	.resource	= innovator1610_smc91x_resources,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-nokia770.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-nokia770.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-nokia770.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-nokia770.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/clk.h>
+#include <linux/omapfb.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -26,17 +27,16 @@
 #include <asm/mach/map.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
-#include <mach/dsp_common.h>
-#include <mach/omapfb.h>
-#include <mach/hwa742.h>
-#include <mach/lcd_mipid.h>
-#include <mach/mmc.h>
-#include <mach/clock.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/dsp_common.h>
+#include <plat/hwa742.h>
+#include <plat/lcd_mipid.h>
+#include <plat/mmc.h>
+#include <plat/clock.h>
 
 #define ADS7846_PENDOWN_GPIO	15
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-osk.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-osk.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-osk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-osk.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
+#include <linux/smc91x.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -47,10 +48,10 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
-#include <mach/usb.h>
-#include <mach/mux.h>
-#include <mach/tc.h>
-#include <mach/common.h>
+#include <plat/usb.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/common.h>
 
 /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
 #define OMAP_OSK_ETHR_START		0x04800300
@@ -115,6 +116,12 @@ static struct platform_device osk5912_fl
 	.resource	= &osk_flash_resource,
 };
 
+static struct smc91x_platdata osk5912_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource osk5912_smc91x_resources[] = {
 	[0] = {
 		.start	= OMAP_OSK_ETHR_START,		/* Physical */
@@ -131,6 +138,9 @@ static struct resource osk5912_smc91x_re
 static struct platform_device osk5912_smc91x_device = {
 	.name		= "smc91x",
 	.id		= -1,
+	.dev	= {
+		.platform_data	= &osk5912_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(osk5912_smc91x_resources),
 	.resource	= osk5912_smc91x_resources,
 };
@@ -312,7 +322,7 @@ static struct omap_board_config_kernel o
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
-#include <mach/keypad.h>
+#include <plat/keypad.h>
 
 static struct at24_platform_data at24c04 = {
 	.byte_len	= SZ_4K / 8,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmte.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmte.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmte.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmte.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,14 +34,14 @@
 #include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/tc.h>
-#include <mach/dma.h>
-#include <mach/board.h>
-#include <mach/irda.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/tc.h>
+#include <plat/dma.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
 
 #define PALMTE_USBDETECT_GPIO	0
 #define PALMTE_USB_OR_DC_GPIO	1
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmtt.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmtt.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmtt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmtt.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,16 +29,16 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
-#include <mach/led.h>
+#include <plat/led.h>
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/dma.h>
-#include <mach/tc.h>
-#include <mach/board.h>
-#include <mach/irda.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmz71.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmz71.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-palmz71.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-palmz71.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,15 +33,15 @@
 #include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/dma.h>
-#include <mach/tc.h>
-#include <mach/board.h>
-#include <mach/irda.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
-#include <mach/omap-alsa.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/omap-alsa.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-perseus2.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-perseus2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-perseus2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-perseus2.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -26,14 +27,13 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/tc.h>
+#include <plat/tc.h>
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/fpga.h>
-#include <mach/nand.h>
-#include <mach/keypad.h>
-#include <mach/common.h>
-#include <mach/board.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/board.h>
 
 static int p2_keymap[] = {
 	KEY(0,0,KEY_UP),
@@ -67,6 +67,12 @@ static int p2_keymap[] = {
 	0
 };
 
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
@@ -74,7 +80,7 @@ static struct resource smc91x_resources[
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= INT_730_MPU_EXT_NIRQ,
+		.start	= INT_7XX_MPU_EXT_NIRQ,
 		.end	= 0,
 		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
@@ -134,8 +140,40 @@ static struct platform_device nor_device
 	.resource	= &nor_resource,
 };
 
-static struct omap_nand_platform_data nand_data = {
-	.options	= NAND_SAMSUNG_LP_OPTIONS,
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd,	unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long mask;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+	if (ctrl & NAND_ALE)
+		mask |= 0x04;
+	writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define P2_NAND_RB_GPIO_PIN	62
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(P2_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data nand_data = {
+	.chip	= {
+		.nr_chips		= 1,
+		.chip_offset		= 0,
+		.options		= NAND_SAMSUNG_LP_OPTIONS,
+		.part_probe_types	= part_probes,
+	},
+	.ctrl	= {
+		.cmd_ctrl	= nand_cmd_ctl,
+		.dev_ready	= nand_dev_ready,
+	},
 };
 
 static struct resource nand_resource = {
@@ -145,7 +183,7 @@ static struct resource nand_resource = {
 };
 
 static struct platform_device nand_device = {
-	.name		= "omapnand",
+	.name		= "gen_nand",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &nand_data,
@@ -157,14 +195,17 @@ static struct platform_device nand_devic
 static struct platform_device smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(smc91x_resources),
 	.resource	= smc91x_resources,
 };
 
 static struct resource kp_resources[] = {
 	[0] = {
-		.start	= INT_730_MPUIO_KEYPAD,
-		.end	= INT_730_MPUIO_KEYPAD,
+		.start	= INT_7XX_MPUIO_KEYPAD,
+		.end	= INT_7XX_MPUIO_KEYPAD,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -201,13 +242,6 @@ static struct platform_device *devices[]
 	&lcd_device,
 };
 
-#define P2_NAND_RB_GPIO_PIN	62
-
-static int nand_dev_ready(struct omap_nand_platform_data *data)
-{
-	return gpio_get_value(P2_NAND_RB_GPIO_PIN);
-}
-
 static struct omap_lcd_config perseus2_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
@@ -220,7 +254,7 @@ static void __init omap_perseus2_init(vo
 {
 	if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
 		BUG();
-	nand_data.dev_ready = nand_dev_ready;
+	gpio_direction_input(P2_NAND_RB_GPIO_PIN);
 
 	omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
 	omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
@@ -270,7 +304,7 @@ static void __init omap_perseus2_map_io(
 	/*
 	 * Hold GSM Reset until needed
 	 */
-	omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
+	omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL);
 
 	/*
 	 * UARTs -> done automagically by 8250 driver
@@ -281,21 +315,21 @@ static void __init omap_perseus2_map_io(
 	 */
 
 	/* Flash: CS0 timings setup */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
-	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
+	omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0);
+	omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0);
 
 	/*
 	 * Ethernet support through the debug board
 	 * CS1 timings setup
 	 */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
-	omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
+	omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1);
+	omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1);
 
 	/*
 	 * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
 	 * It is used as the Ethernet controller interrupt
 	 */
-	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
+	omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9);
 }
 
 MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-sx1.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-sx1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,15 +33,15 @@
 #include <asm/mach/map.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/dma.h>
-#include <mach/irda.h>
-#include <mach/usb.h>
-#include <mach/tc.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/keypad.h>
-#include <mach/board-sx1.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/irda.h>
+#include <plat/usb.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/keypad.h>
+#include <plat/board-sx1.h>
 
 /* Write to I2C device */
 int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,9 @@
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
-#include <mach/mmc.h>
+#include <plat/mmc.h>
 #include <mach/gpio.h>
-#include <mach/board-sx1.h>
+#include <plat/board-sx1.h>
 
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-voiceblue.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-voiceblue.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/reboot.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -29,11 +30,11 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/common.h>
+#include <plat/common.h>
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/tc.h>
-#include <mach/usb.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
 
 static struct plat_serial8250_port voiceblue_ports[] = {
 	{
@@ -106,6 +107,12 @@ static struct platform_device voiceblue_
 	.resource	= &voiceblue_flash_resource,
 };
 
+static struct smc91x_platdata voiceblue_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource voiceblue_smc91x_resources[] = {
 	[0] = {
 		.start	= OMAP_CS2_PHYS + 0x300,
@@ -122,6 +129,9 @@ static struct resource voiceblue_smc91x_
 static struct platform_device voiceblue_smc91x_device = {
 	.name		= "smc91x",
 	.id		= 0,
+	.dev	= {
+		.platform_data	= &voiceblue_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(voiceblue_smc91x_resources),
 	.resource	= voiceblue_smc91x_resources,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mach-omap1/clock.c
  *
- *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  *
  *  Modified to use omap shared clock framework by
@@ -22,16 +22,21 @@
 #include <asm/mach-types.h>
 #include <asm/clkdev.h>
 
-#include <mach/cpu.h>
-#include <mach/usb.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
-
-static const struct clkops clkops_generic;
-static const struct clkops clkops_uart;
-static const struct clkops clkops_dspck;
+#include <plat/cpu.h>
+#include <plat/usb.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/clkdev_omap.h>
 
 #include "clock.h"
+#include "opp.h"
+
+__u32 arm_idlect1_mask;
+struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
+
+/*-------------------------------------------------------------------------
+ * Omap1 specific clock functions
+ *-------------------------------------------------------------------------*/
 
 static int clk_omap1_dummy_enable(struct clk *clk)
 {
@@ -42,132 +47,24 @@ static void clk_omap1_dummy_disable(stru
 {
 }
 
-static const struct clkops clkops_dummy = {
-	.enable = clk_omap1_dummy_enable,
-	.disable = clk_omap1_dummy_disable,
-};
-
-static struct clk dummy_ck = {
-	.name	= "dummy",
-	.ops	= &clkops_dummy,
-	.flags	= RATE_FIXED,
-};
-
-struct omap_clk {
-	u32		cpu;
-	struct clk_lookup lk;
-};
-
-#define CLK(dev, con, ck, cp) 		\
-	{				\
-		 .cpu = cp,		\
-		.lk = {			\
-			.dev_id = dev,	\
-			.con_id = con,	\
-			.clk = ck,	\
-		},			\
-	}
-
-#define CK_310	(1 << 0)
-#define CK_730	(1 << 1)
-#define CK_1510	(1 << 2)
-#define CK_16XX	(1 << 3)
-
-static struct omap_clk omap_clks[] = {
-	/* non-ULPD clocks */
-	CLK(NULL,	"ck_ref",	&ck_ref,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"ck_dpll1",	&ck_dpll1,	CK_16XX | CK_1510 | CK_310),
-	/* CK_GEN1 clocks */
-	CLK(NULL,	"ck_dpll1out",	&ck_dpll1out.clk, CK_16XX),
-	CLK(NULL,	"ck_sossi",	&sossi_ck,	CK_16XX),
-	CLK(NULL,	"arm_ck",	&arm_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"armper_ck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"arm_gpio_ck",	&arm_gpio_ck,	CK_1510 | CK_310),
-	CLK(NULL,	"armxor_ck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"armtim_ck",	&armtim_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK("omap_wdt",	"fck",		&armwdt_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK("omap_wdt",	"ick",		&armper_ck.clk,	CK_16XX),
-	CLK("omap_wdt", "ick",		&dummy_ck,	CK_1510 | CK_310),
-	CLK(NULL,	"arminth_ck",	&arminth_ck1510, CK_1510 | CK_310),
-	CLK(NULL,	"arminth_ck",	&arminth_ck16xx, CK_16XX),
-	/* CK_GEN2 clocks */
-	CLK(NULL,	"dsp_ck",	&dsp_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"dspmmu_ck",	&dspmmu_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"dspper_ck",	&dspper_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"dspxor_ck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"dsptim_ck",	&dsptim_ck,	CK_16XX | CK_1510 | CK_310),
-	/* CK_GEN3 clocks */
-	CLK(NULL,	"tc_ck",	&tc_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_730),
-	CLK(NULL,	"tipb_ck",	&tipb_ck,	CK_1510 | CK_310),
-	CLK(NULL,	"l3_ocpi_ck",	&l3_ocpi_ck,	CK_16XX),
-	CLK(NULL,	"tc1_ck",	&tc1_ck,	CK_16XX),
-	CLK(NULL,	"tc2_ck",	&tc2_ck,	CK_16XX),
-	CLK(NULL,	"dma_ck",	&dma_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
-	CLK(NULL,	"api_ck",	&api_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"lb_ck",	&lb_ck.clk,	CK_1510 | CK_310),
-	CLK(NULL,	"rhea1_ck",	&rhea1_ck,	CK_16XX),
-	CLK(NULL,	"rhea2_ck",	&rhea2_ck,	CK_16XX),
-	CLK(NULL,	"lcd_ck",	&lcd_ck_16xx,	CK_16XX | CK_730),
-	CLK(NULL,	"lcd_ck",	&lcd_ck_1510.clk, CK_1510 | CK_310),
-	/* ULPD clocks */
-	CLK(NULL,	"uart1_ck",	&uart1_1510,	CK_1510 | CK_310),
-	CLK(NULL,	"uart1_ck",	&uart1_16xx.clk, CK_16XX),
-	CLK(NULL,	"uart2_ck",	&uart2_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"uart3_ck",	&uart3_1510,	CK_1510 | CK_310),
-	CLK(NULL,	"uart3_ck",	&uart3_16xx.clk, CK_16XX),
-	CLK(NULL,	"usb_clko",	&usb_clko,	CK_16XX | CK_1510 | CK_310),
-	CLK(NULL,	"usb_hhc_ck",	&usb_hhc_ck1510, CK_1510 | CK_310),
-	CLK(NULL,	"usb_hhc_ck",	&usb_hhc_ck16xx, CK_16XX),
-	CLK(NULL,	"usb_dc_ck",	&usb_dc_ck,	CK_16XX),
-	CLK(NULL,	"mclk",		&mclk_1510,	CK_1510 | CK_310),
-	CLK(NULL,	"mclk",		&mclk_16xx,	CK_16XX),
-	CLK(NULL,	"bclk",		&bclk_1510,	CK_1510 | CK_310),
-	CLK(NULL,	"bclk",		&bclk_16xx,	CK_16XX),
-	CLK("mmci-omap.0", "fck",	&mmc1_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK("mmci-omap.0", "ick",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK("mmci-omap.1", "fck",	&mmc2_ck,	CK_16XX),
-	CLK("mmci-omap.1", "ick",	&armper_ck.clk,	CK_16XX),
-	/* Virtual clocks */
-	CLK(NULL,	"mpu",		&virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
-	CLK("i2c_omap.1", "fck",	&i2c_fck,	CK_16XX | CK_1510 | CK_310),
-	CLK("i2c_omap.1", "ick",	&i2c_ick,	CK_16XX),
-	CLK("i2c_omap.1", "ick",	&dummy_ck,	CK_1510 | CK_310),
-	CLK("omap_uwire", "fck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK("omap-mcbsp.1", "ick",	&dspper_ck,	CK_16XX),
-	CLK("omap-mcbsp.1", "ick",	&dummy_ck,	CK_1510 | CK_310),
-	CLK("omap-mcbsp.2", "ick",	&armper_ck.clk,	CK_16XX),
-	CLK("omap-mcbsp.2", "ick",	&dummy_ck,	CK_1510 | CK_310),
-	CLK("omap-mcbsp.3", "ick",	&dspper_ck,	CK_16XX),
-	CLK("omap-mcbsp.3", "ick",	&dummy_ck,	CK_1510 | CK_310),
-	CLK("omap-mcbsp.1", "fck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
-	CLK("omap-mcbsp.2", "fck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
-	CLK("omap-mcbsp.3", "fck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
+const struct clkops clkops_dummy = {
+	.enable		= clk_omap1_dummy_enable,
+	.disable	= clk_omap1_dummy_disable,
 };
 
-static int omap1_clk_enable_generic(struct clk * clk);
-static int omap1_clk_enable(struct clk *clk);
-static void omap1_clk_disable_generic(struct clk * clk);
-static void omap1_clk_disable(struct clk *clk);
-
-__u32 arm_idlect1_mask;
-
-/*-------------------------------------------------------------------------
- * Omap1 specific clock functions
- *-------------------------------------------------------------------------*/
-
-static unsigned long omap1_watchdog_recalc(struct clk *clk)
+/* XXX can be replaced with a fixed_divisor_recalc */
+unsigned long omap1_watchdog_recalc(struct clk *clk)
 {
 	return clk->parent->rate / 14;
 }
 
-static unsigned long omap1_uart_recalc(struct clk *clk)
+unsigned long omap1_uart_recalc(struct clk *clk)
 {
 	unsigned int val = __raw_readl(clk->enable_reg);
 	return val & clk->enable_bit ? 48000000 : 12000000;
 }
 
-static unsigned long omap1_sossi_recalc(struct clk *clk)
+unsigned long omap1_sossi_recalc(struct clk *clk)
 {
 	u32 div = omap_readl(MOD_CONF_CTRL_1);
 
@@ -177,64 +74,6 @@ static unsigned long omap1_sossi_recalc(
 	return clk->parent->rate / div;
 }
 
-static int omap1_clk_enable_dsp_domain(struct clk *clk)
-{
-	int retval;
-
-	retval = omap1_clk_enable(&api_ck.clk);
-	if (!retval) {
-		retval = omap1_clk_enable_generic(clk);
-		omap1_clk_disable(&api_ck.clk);
-	}
-
-	return retval;
-}
-
-static void omap1_clk_disable_dsp_domain(struct clk *clk)
-{
-	if (omap1_clk_enable(&api_ck.clk) == 0) {
-		omap1_clk_disable_generic(clk);
-		omap1_clk_disable(&api_ck.clk);
-	}
-}
-
-static const struct clkops clkops_dspck = {
-	.enable		= &omap1_clk_enable_dsp_domain,
-	.disable	= &omap1_clk_disable_dsp_domain,
-};
-
-static int omap1_clk_enable_uart_functional(struct clk *clk)
-{
-	int ret;
-	struct uart_clk *uclk;
-
-	ret = omap1_clk_enable_generic(clk);
-	if (ret == 0) {
-		/* Set smart idle acknowledgement mode */
-		uclk = (struct uart_clk *)clk;
-		omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
-			    uclk->sysc_addr);
-	}
-
-	return ret;
-}
-
-static void omap1_clk_disable_uart_functional(struct clk *clk)
-{
-	struct uart_clk *uclk;
-
-	/* Set force idle acknowledgement mode */
-	uclk = (struct uart_clk *)clk;
-	omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
-
-	omap1_clk_disable_generic(clk);
-}
-
-static const struct clkops clkops_uart = {
-	.enable		= &omap1_clk_enable_uart_functional,
-	.disable	= &omap1_clk_disable_uart_functional,
-};
-
 static void omap1_clk_allow_idle(struct clk *clk)
 {
 	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
@@ -342,7 +181,7 @@ static int calc_dsor_exp(struct clk *clk
 	return dsor_exp;
 }
 
-static unsigned long omap1_ckctl_recalc(struct clk *clk)
+unsigned long omap1_ckctl_recalc(struct clk *clk)
 {
 	/* Calculate divisor encoded as 2-bit exponent */
 	int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
@@ -350,7 +189,7 @@ static unsigned long omap1_ckctl_recalc(
 	return clk->parent->rate / dsor;
 }
 
-static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
+unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
 {
 	int dsor;
 
@@ -361,28 +200,29 @@ static unsigned long omap1_ckctl_recalc_
 	 * Note that DSP_CKCTL virt addr = phys addr, so
 	 * we must use __raw_readw() instead of omap_readw().
 	 */
-	omap1_clk_enable(&api_ck.clk);
+	omap1_clk_enable(api_ck_p);
 	dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
-	omap1_clk_disable(&api_ck.clk);
+	omap1_clk_disable(api_ck_p);
 
 	return clk->parent->rate / dsor;
 }
 
 /* MPU virtual clock functions */
-static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
+int omap1_select_table_rate(struct clk *clk, unsigned long rate)
 {
 	/* Find the highest supported frequency <= rate and switch to it */
 	struct mpu_rate * ptr;
+	unsigned long dpll1_rate, ref_rate;
 
-	if (clk != &virtual_ck_mpu)
-		return -EINVAL;
+	dpll1_rate = ck_dpll1_p->rate;
+	ref_rate = ck_ref_p->rate;
 
-	for (ptr = rate_table; ptr->rate; ptr++) {
-		if (ptr->xtal != ck_ref.rate)
+	for (ptr = omap1_rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ref_rate)
 			continue;
 
 		/* DPLL1 cannot be reprogrammed without risking system crash */
-		if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
+		if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate)
 			continue;
 
 		/* Can check only after xtal frequency check */
@@ -398,16 +238,18 @@ static int omap1_select_table_rate(struc
 	 * Reprogramming the DPLL is tricky, it must be done from SRAM.
 	 * (on 730, bit 13 must always be 1)
 	 */
-	if (cpu_is_omap730())
+	if (cpu_is_omap7xx())
 		omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000);
 	else
 		omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
 
-	ck_dpll1.rate = ptr->pll_rate;
+	/* XXX Do we need to recalculate the tree below DPLL1 at this point? */
+	ck_dpll1_p->rate = ptr->pll_rate;
+
 	return 0;
 }
 
-static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
+int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
 {
 	int dsor_exp;
 	u16 regval;
@@ -427,7 +269,7 @@ static int omap1_clk_set_rate_dsp_domain
 	return 0;
 }
 
-static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
 {
 	int dsor_exp = calc_dsor_exp(clk, rate);
 	if (dsor_exp < 0)
@@ -437,7 +279,7 @@ static long omap1_clk_round_rate_ckctl_a
 	return clk->parent->rate / (1 << dsor_exp);
 }
 
-static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
 {
 	int dsor_exp;
 	u16 regval;
@@ -457,19 +299,19 @@ static int omap1_clk_set_rate_ckctl_arm(
 	return 0;
 }
 
-static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
+long omap1_round_to_table_rate(struct clk *clk, unsigned long rate)
 {
 	/* Find the highest supported frequency <= rate */
 	struct mpu_rate * ptr;
-	long  highest_rate;
+	long highest_rate;
+	unsigned long ref_rate;
 
-	if (clk != &virtual_ck_mpu)
-		return -EINVAL;
+	ref_rate = ck_ref_p->rate;
 
 	highest_rate = -EINVAL;
 
-	for (ptr = rate_table; ptr->rate; ptr++) {
-		if (ptr->xtal != ck_ref.rate)
+	for (ptr = omap1_rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ref_rate)
 			continue;
 
 		highest_rate = ptr->rate;
@@ -504,8 +346,8 @@ static unsigned calc_ext_dsor(unsigned l
 	return dsor;
 }
 
-/* Only needed on 1510 */
-static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
+/* XXX Only needed on 1510 */
+int omap1_set_uart_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned int val;
 
@@ -523,7 +365,7 @@ static int omap1_set_uart_rate(struct cl
 }
 
 /* External clock (MCLK & BCLK) functions */
-static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
+int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned dsor;
 	__u16 ratio_bits;
@@ -541,7 +383,7 @@ static int omap1_set_ext_clk_rate(struct
 	return 0;
 }
 
-static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
+int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
 {
 	u32 l;
 	int div;
@@ -564,12 +406,12 @@ static int omap1_set_sossi_rate(struct c
 	return 0;
 }
 
-static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
+long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate)
 {
 	return 96000000 / calc_ext_dsor(rate);
 }
 
-static void omap1_init_ext_clk(struct clk * clk)
+void omap1_init_ext_clk(struct clk *clk)
 {
 	unsigned dsor;
 	__u16 ratio_bits;
@@ -587,7 +429,7 @@ static void omap1_init_ext_clk(struct cl
 	clk-> rate = 96000000 / dsor;
 }
 
-static int omap1_clk_enable(struct clk *clk)
+int omap1_clk_enable(struct clk *clk)
 {
 	int ret = 0;
 
@@ -615,7 +457,7 @@ err:
 	return ret;
 }
 
-static void omap1_clk_disable(struct clk *clk)
+void omap1_clk_disable(struct clk *clk)
 {
 	if (clk->usecount > 0 && !(--clk->usecount)) {
 		clk->ops->disable(clk);
@@ -670,12 +512,70 @@ static void omap1_clk_disable_generic(st
 	}
 }
 
-static const struct clkops clkops_generic = {
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+const struct clkops clkops_generic = {
+	.enable		= omap1_clk_enable_generic,
+	.disable	= omap1_clk_disable_generic,
 };
 
-static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
+static int omap1_clk_enable_dsp_domain(struct clk *clk)
+{
+	int retval;
+
+	retval = omap1_clk_enable(api_ck_p);
+	if (!retval) {
+		retval = omap1_clk_enable_generic(clk);
+		omap1_clk_disable(api_ck_p);
+	}
+
+	return retval;
+}
+
+static void omap1_clk_disable_dsp_domain(struct clk *clk)
+{
+	if (omap1_clk_enable(api_ck_p) == 0) {
+		omap1_clk_disable_generic(clk);
+		omap1_clk_disable(api_ck_p);
+	}
+}
+
+const struct clkops clkops_dspck = {
+	.enable		= omap1_clk_enable_dsp_domain,
+	.disable	= omap1_clk_disable_dsp_domain,
+};
+
+static int omap1_clk_enable_uart_functional(struct clk *clk)
+{
+	int ret;
+	struct uart_clk *uclk;
+
+	ret = omap1_clk_enable_generic(clk);
+	if (ret == 0) {
+		/* Set smart idle acknowledgement mode */
+		uclk = (struct uart_clk *)clk;
+		omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
+			    uclk->sysc_addr);
+	}
+
+	return ret;
+}
+
+static void omap1_clk_disable_uart_functional(struct clk *clk)
+{
+	struct uart_clk *uclk;
+
+	/* Set force idle acknowledgement mode */
+	uclk = (struct uart_clk *)clk;
+	omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
+
+	omap1_clk_disable_generic(clk);
+}
+
+const struct clkops clkops_uart = {
+	.enable		= omap1_clk_enable_uart_functional,
+	.disable	= omap1_clk_disable_uart_functional,
+};
+
+long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	if (clk->flags & RATE_FIXED)
 		return clk->rate;
@@ -686,7 +586,7 @@ static long omap1_clk_round_rate(struct
 	return clk->rate;
 }
 
-static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
+int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	int  ret = -EINVAL;
 
@@ -701,7 +601,7 @@ static int omap1_clk_set_rate(struct clk
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 
-static void __init omap1_clk_disable_unused(struct clk *clk)
+void __init omap1_clk_disable_unused(struct clk *clk)
 {
 	__u32 regval32;
 
@@ -722,184 +622,9 @@ static void __init omap1_clk_disable_unu
 	if ((regval32 & (1 << clk->enable_bit)) == 0)
 		return;
 
-	/* FIXME: This clock seems to be necessary but no-one
-	 * has asked for its activation. */
-	if (clk == &tc2_ck		/* FIX: pm.c (SRAM), CCP, Camera */
-	    || clk == &ck_dpll1out.clk	/* FIX: SoSSI, SSR */
-	    || clk == &arm_gpio_ck	/* FIX: GPIO code for 1510 */
-		) {
-		printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
-		       clk->name);
-		return;
-	}
-
 	printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
 	clk->ops->disable(clk);
 	printk(" done\n");
 }
 
-#else
-#define omap1_clk_disable_unused	NULL
-#endif
-
-static struct clk_functions omap1_clk_functions = {
-	.clk_enable		= omap1_clk_enable,
-	.clk_disable		= omap1_clk_disable,
-	.clk_round_rate		= omap1_clk_round_rate,
-	.clk_set_rate		= omap1_clk_set_rate,
-	.clk_disable_unused	= omap1_clk_disable_unused,
-};
-
-int __init omap1_clk_init(void)
-{
-	struct omap_clk *c;
-	const struct omap_clock_config *info;
-	int crystal_type = 0; /* Default 12 MHz */
-	u32 reg, cpu_mask;
-
-#ifdef CONFIG_DEBUG_LL
-	/* Resets some clocks that may be left on from bootloader,
-	 * but leaves serial clocks on.
- 	 */
-	omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
-#endif
-
-	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
-	reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
-	omap_writew(reg, SOFT_REQ_REG);
-	if (!cpu_is_omap15xx())
-		omap_writew(0, SOFT_REQ_REG2);
-
-	clk_init(&omap1_clk_functions);
-
-	/* By default all idlect1 clocks are allowed to idle */
-	arm_idlect1_mask = ~0;
-
-	for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	cpu_mask = 0;
-	if (cpu_is_omap16xx())
-		cpu_mask |= CK_16XX;
-	if (cpu_is_omap1510())
-		cpu_mask |= CK_1510;
-	if (cpu_is_omap730())
-		cpu_mask |= CK_730;
-	if (cpu_is_omap310())
-		cpu_mask |= CK_310;
-
-	for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
-		if (c->cpu & cpu_mask) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-		}
-
-	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
-	if (info != NULL) {
-		if (!cpu_is_omap15xx())
-			crystal_type = info->system_clock_type;
-	}
-
-#if defined(CONFIG_ARCH_OMAP730)
-	ck_ref.rate = 13000000;
-#elif defined(CONFIG_ARCH_OMAP16XX)
-	if (crystal_type == 2)
-		ck_ref.rate = 19200000;
 #endif
-
-	printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
-	       omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
-	       omap_readw(ARM_CKCTL));
-
-	/* We want to be in syncronous scalable mode */
-	omap_writew(0x1000, ARM_SYSST);
-
-#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
-	/* Use values set by bootloader. Determine PLL rate and recalculate
-	 * dependent clocks as if kernel had changed PLL or divisors.
-	 */
-	{
-		unsigned pll_ctl_val = omap_readw(DPLL_CTL);
-
-		ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
-		if (pll_ctl_val & 0x10) {
-			/* PLL enabled, apply multiplier and divisor */
-			if (pll_ctl_val & 0xf80)
-				ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
-			ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
-		} else {
-			/* PLL disabled, apply bypass divisor */
-			switch (pll_ctl_val & 0xc) {
-			case 0:
-				break;
-			case 0x4:
-				ck_dpll1.rate /= 2;
-				break;
-			default:
-				ck_dpll1.rate /= 4;
-				break;
-			}
-		}
-	}
-#else
-	/* Find the highest supported frequency and enable it */
-	if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
-		printk(KERN_ERR "System frequencies not set. Check your config.\n");
-		/* Guess sane values (60MHz) */
-		omap_writew(0x2290, DPLL_CTL);
-		omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
-		ck_dpll1.rate = 60000000;
-	}
-#endif
-	propagate_rate(&ck_dpll1);
-	/* Cache rates for clocks connected to ck_ref (not dpll1) */
-	propagate_rate(&ck_ref);
-	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
-		"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
-	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
-	       ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
-	       arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
-
-#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
-	/* Select slicer output as OMAP input clock */
-	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
-#endif
-
-	/* Amstrad Delta wants BCLK high when inactive */
-	if (machine_is_ams_delta())
-		omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
-				(1 << SDW_MCLK_INV_BIT),
-				ULPD_CLOCK_CTRL);
-
-	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
-	/* (on 730, bit 13 must not be cleared) */
-	if (cpu_is_omap730())
-		omap_writew(omap_readw(ARM_CKCTL) & 0x2fff, ARM_CKCTL);
-	else
-		omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
-
-	/* Put DSP/MPUI into reset until needed */
-	omap_writew(0, ARM_RSTCT1);
-	omap_writew(1, ARM_RSTCT2);
-	omap_writew(0x400, ARM_IDLECT1);
-
-	/*
-	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
-	 * of the ARM_IDLECT2 register must be set to zero. The power-on
-	 * default value of this bit is one.
-	 */
-	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable(&armper_ck.clk);
-	clk_enable(&armxor_ck.clk);
-	clk_enable(&armtim_ck.clk); /* This should be done by timer code */
-
-	if (cpu_is_omap15xx())
-		clk_enable(&arm_gpio_ck);
-
-	return 0;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,847 @@
+/*
+ *  linux/arch/arm/mach-omap1/clock_data.c
+ *
+ *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>  /* for machine_is_* */
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/clkdev_omap.h>
+#include <plat/usb.h>   /* for OTG_BASE */
+
+#include "clock.h"
+
+/*------------------------------------------------------------------------
+ * Omap1 clocks
+ *-------------------------------------------------------------------------*/
+
+/* XXX is this necessary? */
+static struct clk dummy_ck = {
+	.name	= "dummy",
+	.ops	= &clkops_dummy,
+	.flags	= RATE_FIXED,
+};
+
+static struct clk ck_ref = {
+	.name		= "ck_ref",
+	.ops		= &clkops_null,
+	.rate		= 12000000,
+};
+
+static struct clk ck_dpll1 = {
+	.name		= "ck_dpll1",
+	.ops		= &clkops_null,
+	.parent		= &ck_ref,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation.  [ FIX: SoSSI, SSR ]
+ */
+static struct arm_idlect1_clk ck_dpll1out = {
+	.clk = {
+		.name		= "ck_dpll1out",
+		.ops		= &clkops_generic,
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT |
+				  ENABLE_ON_INIT,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_CKOUT_ARM,
+		.recalc		= &followparent_recalc,
+	},
+	.idlect_shift	= 12,
+};
+
+static struct clk sossi_ck = {
+	.name		= "ck_sossi",
+	.ops		= &clkops_generic,
+	.parent		= &ck_dpll1out.clk,
+	.flags		= CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
+	.enable_bit	= 16,
+	.recalc		= &omap1_sossi_recalc,
+	.set_rate	= &omap1_set_sossi_rate,
+};
+
+static struct clk arm_ck = {
+	.name		= "arm_ck",
+	.ops		= &clkops_null,
+	.parent		= &ck_dpll1,
+	.rate_offset	= CKCTL_ARMDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.round_rate	= omap1_clk_round_rate_ckctl_arm,
+	.set_rate	= omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct arm_idlect1_clk armper_ck = {
+	.clk = {
+		.name		= "armper_ck",
+		.ops		= &clkops_generic,
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_PERCK,
+		.rate_offset	= CKCTL_PERDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.round_rate	= omap1_clk_round_rate_ckctl_arm,
+		.set_rate	= omap1_clk_set_rate_ckctl_arm,
+	},
+	.idlect_shift	= 2,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation.  [ GPIO code for 1510 ]
+ */
+static struct clk arm_gpio_ck = {
+	.name		= "arm_gpio_ck",
+	.ops		= &clkops_generic,
+	.parent		= &ck_dpll1,
+	.flags		= ENABLE_ON_INIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+	.enable_bit	= EN_GPIOCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct arm_idlect1_clk armxor_ck = {
+	.clk = {
+		.name		= "armxor_ck",
+		.ops		= &clkops_generic,
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_XORPCK,
+		.recalc		= &followparent_recalc,
+	},
+	.idlect_shift	= 1,
+};
+
+static struct arm_idlect1_clk armtim_ck = {
+	.clk = {
+		.name		= "armtim_ck",
+		.ops		= &clkops_generic,
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_TIMCK,
+		.recalc		= &followparent_recalc,
+	},
+	.idlect_shift	= 9,
+};
+
+static struct arm_idlect1_clk armwdt_ck = {
+	.clk = {
+		.name		= "armwdt_ck",
+		.ops		= &clkops_generic,
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_WDTCK,
+		.recalc		= &omap1_watchdog_recalc,
+	},
+	.idlect_shift	= 0,
+};
+
+static struct clk arminth_ck16xx = {
+	.name		= "arminth_ck",
+	.ops		= &clkops_null,
+	.parent		= &arm_ck,
+	.recalc		= &followparent_recalc,
+	/* Note: On 16xx the frequency can be divided by 2 by programming
+	 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
+	 *
+	 * 1510 version is in TC clocks.
+	 */
+};
+
+static struct clk dsp_ck = {
+	.name		= "dsp_ck",
+	.ops		= &clkops_generic,
+	.parent		= &ck_dpll1,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_CKCTL),
+	.enable_bit	= EN_DSPCK,
+	.rate_offset	= CKCTL_DSPDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.round_rate	= omap1_clk_round_rate_ckctl_arm,
+	.set_rate	= omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct clk dspmmu_ck = {
+	.name		= "dspmmu_ck",
+	.ops		= &clkops_null,
+	.parent		= &ck_dpll1,
+	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.round_rate	= omap1_clk_round_rate_ckctl_arm,
+	.set_rate	= omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct clk dspper_ck = {
+	.name		= "dspper_ck",
+	.ops		= &clkops_dspck,
+	.parent		= &ck_dpll1,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_PERCK,
+	.rate_offset	= CKCTL_PERDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc_dsp_domain,
+	.round_rate	= omap1_clk_round_rate_ckctl_arm,
+	.set_rate	= &omap1_clk_set_rate_dsp_domain,
+};
+
+static struct clk dspxor_ck = {
+	.name		= "dspxor_ck",
+	.ops		= &clkops_dspck,
+	.parent		= &ck_ref,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_XORPCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dsptim_ck = {
+	.name		= "dsptim_ck",
+	.ops		= &clkops_dspck,
+	.parent		= &ck_ref,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_DSPTIMCK,
+	.recalc		= &followparent_recalc,
+};
+
+/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
+static struct arm_idlect1_clk tc_ck = {
+	.clk = {
+		.name		= "tc_ck",
+		.ops		= &clkops_null,
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.rate_offset	= CKCTL_TCDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.round_rate	= omap1_clk_round_rate_ckctl_arm,
+		.set_rate	= omap1_clk_set_rate_ckctl_arm,
+	},
+	.idlect_shift	= 6,
+};
+
+static struct clk arminth_ck1510 = {
+	.name		= "arminth_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+	/* Note: On 1510 the frequency follows TC_CK
+	 *
+	 * 16xx version is in MPU clocks.
+	 */
+};
+
+static struct clk tipb_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "tipb_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk l3_ocpi_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "l3_ocpi_ck",
+	.ops		= &clkops_generic,
+	.parent		= &tc_ck.clk,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
+	.enable_bit	= EN_OCPI_CK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk tc1_ck = {
+	.name		= "tc1_ck",
+	.ops		= &clkops_generic,
+	.parent		= &tc_ck.clk,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
+	.enable_bit	= EN_TC1_CK,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation.  [ pm.c (SRAM), CCP, Camera ]
+ */
+static struct clk tc2_ck = {
+	.name		= "tc2_ck",
+	.ops		= &clkops_generic,
+	.parent		= &tc_ck.clk,
+	.flags		= ENABLE_ON_INIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
+	.enable_bit	= EN_TC2_CK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dma_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "dma_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dma_lcdfree_ck = {
+	.name		= "dma_lcdfree_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct arm_idlect1_clk api_ck = {
+	.clk = {
+		.name		= "api_ck",
+		.ops		= &clkops_generic,
+		.parent		= &tc_ck.clk,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_APICK,
+		.recalc		= &followparent_recalc,
+	},
+	.idlect_shift	= 8,
+};
+
+static struct arm_idlect1_clk lb_ck = {
+	.clk = {
+		.name		= "lb_ck",
+		.ops		= &clkops_generic,
+		.parent		= &tc_ck.clk,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_LBCK,
+		.recalc		= &followparent_recalc,
+	},
+	.idlect_shift	= 4,
+};
+
+static struct clk rhea1_ck = {
+	.name		= "rhea1_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rhea2_ck = {
+	.name		= "rhea2_ck",
+	.ops		= &clkops_null,
+	.parent		= &tc_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk lcd_ck_16xx = {
+	.name		= "lcd_ck",
+	.ops		= &clkops_generic,
+	.parent		= &ck_dpll1,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+	.enable_bit	= EN_LCDCK,
+	.rate_offset	= CKCTL_LCDDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.round_rate	= omap1_clk_round_rate_ckctl_arm,
+	.set_rate	= omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct arm_idlect1_clk lcd_ck_1510 = {
+	.clk = {
+		.name		= "lcd_ck",
+		.ops		= &clkops_generic,
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
+		.enable_bit	= EN_LCDCK,
+		.rate_offset	= CKCTL_LCDDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.round_rate	= omap1_clk_round_rate_ckctl_arm,
+		.set_rate	= omap1_clk_set_rate_ckctl_arm,
+	},
+	.idlect_shift	= 3,
+};
+
+static struct clk uart1_1510 = {
+	.name		= "uart1_ck",
+	.ops		= &clkops_null,
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+};
+
+static struct uart_clk uart1_16xx = {
+	.clk	= {
+		.name		= "uart1_ck",
+		.ops		= &clkops_uart,
+		/* Direct from ULPD, no real parent */
+		.parent		= &armper_ck.clk,
+		.rate		= 48000000,
+		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
+				  CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+		.enable_bit	= 29,
+	},
+	.sysc_addr	= 0xfffb0054,
+};
+
+static struct clk uart2_ck = {
+	.name		= "uart2_ck",
+	.ops		= &clkops_null,
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+};
+
+static struct clk uart3_1510 = {
+	.name		= "uart3_ck",
+	.ops		= &clkops_null,
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+};
+
+static struct uart_clk uart3_16xx = {
+	.clk	= {
+		.name		= "uart3_ck",
+		.ops		= &clkops_uart,
+		/* Direct from ULPD, no real parent */
+		.parent		= &armper_ck.clk,
+		.rate		= 48000000,
+		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
+				  CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+		.enable_bit	= 31,
+	},
+	.sysc_addr	= 0xfffb9854,
+};
+
+static struct clk usb_clko = {	/* 6 MHz output on W4_USB_CLKO */
+	.name		= "usb_clko",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent */
+	.rate		= 6000000,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
+	.enable_bit	= USB_MCLK_EN_BIT,
+};
+
+static struct clk usb_hhc_ck1510 = {
+	.name		= "usb_hhc_ck",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= USB_HOST_HHC_UHOST_EN,
+};
+
+static struct clk usb_hhc_ck16xx = {
+	.name		= "usb_hhc_ck",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
+	.enable_bit	= 8 /* UHOST_EN */,
+};
+
+static struct clk usb_dc_ck = {
+	.name		= "usb_dc_ck",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= RATE_FIXED,
+	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+	.enable_bit	= 4,
+};
+
+static struct clk usb_dc_ck7xx = {
+	.name		= "usb_dc_ck",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= RATE_FIXED,
+	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+	.enable_bit	= 8,
+};
+
+static struct clk mclk_1510 = {
+	.name		= "mclk",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= RATE_FIXED,
+	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+	.enable_bit	= 6,
+};
+
+static struct clk mclk_16xx = {
+	.name		= "mclk",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.enable_reg	= OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
+	.enable_bit	= COM_ULPD_PLL_CLK_REQ,
+	.set_rate	= &omap1_set_ext_clk_rate,
+	.round_rate	= &omap1_round_ext_clk_rate,
+	.init		= &omap1_init_ext_clk,
+};
+
+static struct clk bclk_1510 = {
+	.name		= "bclk",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk bclk_16xx = {
+	.name		= "bclk",
+	.ops		= &clkops_generic,
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.enable_reg	= OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
+	.enable_bit	= SWD_ULPD_PLL_CLK_REQ,
+	.set_rate	= &omap1_set_ext_clk_rate,
+	.round_rate	= &omap1_round_ext_clk_rate,
+	.init		= &omap1_init_ext_clk,
+};
+
+static struct clk mmc1_ck = {
+	.name		= "mmc_ck",
+	.ops		= &clkops_generic,
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck.clk,
+	.rate		= 48000000,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= 23,
+};
+
+static struct clk mmc2_ck = {
+	.name		= "mmc_ck",
+	.id		= 1,
+	.ops		= &clkops_generic,
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck.clk,
+	.rate		= 48000000,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+	.enable_bit	= 20,
+};
+
+static struct clk mmc3_ck = {
+	.name		= "mmc_ck",
+	.id		= 2,
+	.ops		= &clkops_generic,
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck.clk,
+	.rate		= 48000000,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+	.enable_bit	= 12,
+};
+
+static struct clk virtual_ck_mpu = {
+	.name		= "mpu",
+	.ops		= &clkops_null,
+	.parent		= &arm_ck, /* Is smarter alias for */
+	.recalc		= &followparent_recalc,
+	.set_rate	= &omap1_select_table_rate,
+	.round_rate	= &omap1_round_to_table_rate,
+};
+
+/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
+remains active during MPU idle whenever this is enabled */
+static struct clk i2c_fck = {
+	.name		= "i2c_fck",
+	.id		= 1,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_NO_IDLE_PARENT,
+	.parent		= &armxor_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c_ick = {
+	.name		= "i2c_ick",
+	.id		= 1,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_NO_IDLE_PARENT,
+	.parent		= &armper_ck.clk,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap_clks[] = {
+	/* non-ULPD clocks */
+	CLK(NULL,	"ck_ref",	&ck_ref,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK(NULL,	"ck_dpll1",	&ck_dpll1,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	/* CK_GEN1 clocks */
+	CLK(NULL,	"ck_dpll1out",	&ck_dpll1out.clk, CK_16XX),
+	CLK(NULL,	"ck_sossi",	&sossi_ck,	CK_16XX),
+	CLK(NULL,	"arm_ck",	&arm_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"armper_ck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"arm_gpio_ck",	&arm_gpio_ck,	CK_1510 | CK_310),
+	CLK(NULL,	"armxor_ck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK(NULL,	"armtim_ck",	&armtim_ck.clk,	CK_16XX | CK_1510 | CK_310),
+	CLK("omap_wdt",	"fck",		&armwdt_ck.clk,	CK_16XX | CK_1510 | CK_310),
+	CLK("omap_wdt",	"ick",		&armper_ck.clk,	CK_16XX),
+	CLK("omap_wdt", "ick",		&dummy_ck,	CK_1510 | CK_310),
+	CLK(NULL,	"arminth_ck",	&arminth_ck1510, CK_1510 | CK_310),
+	CLK(NULL,	"arminth_ck",	&arminth_ck16xx, CK_16XX),
+	/* CK_GEN2 clocks */
+	CLK(NULL,	"dsp_ck",	&dsp_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"dspmmu_ck",	&dspmmu_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"dspper_ck",	&dspper_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"dspxor_ck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"dsptim_ck",	&dsptim_ck,	CK_16XX | CK_1510 | CK_310),
+	/* CK_GEN3 clocks */
+	CLK(NULL,	"tc_ck",	&tc_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK(NULL,	"tipb_ck",	&tipb_ck,	CK_1510 | CK_310),
+	CLK(NULL,	"l3_ocpi_ck",	&l3_ocpi_ck,	CK_16XX | CK_7XX),
+	CLK(NULL,	"tc1_ck",	&tc1_ck,	CK_16XX),
+	CLK(NULL,	"tc2_ck",	&tc2_ck,	CK_16XX),
+	CLK(NULL,	"dma_ck",	&dma_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
+	CLK(NULL,	"api_ck",	&api_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK(NULL,	"lb_ck",	&lb_ck.clk,	CK_1510 | CK_310),
+	CLK(NULL,	"rhea1_ck",	&rhea1_ck,	CK_16XX),
+	CLK(NULL,	"rhea2_ck",	&rhea2_ck,	CK_16XX),
+	CLK(NULL,	"lcd_ck",	&lcd_ck_16xx,	CK_16XX | CK_7XX),
+	CLK(NULL,	"lcd_ck",	&lcd_ck_1510.clk, CK_1510 | CK_310),
+	/* ULPD clocks */
+	CLK(NULL,	"uart1_ck",	&uart1_1510,	CK_1510 | CK_310),
+	CLK(NULL,	"uart1_ck",	&uart1_16xx.clk, CK_16XX),
+	CLK(NULL,	"uart2_ck",	&uart2_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"uart3_ck",	&uart3_1510,	CK_1510 | CK_310),
+	CLK(NULL,	"uart3_ck",	&uart3_16xx.clk, CK_16XX),
+	CLK(NULL,	"usb_clko",	&usb_clko,	CK_16XX | CK_1510 | CK_310),
+	CLK(NULL,	"usb_hhc_ck",	&usb_hhc_ck1510, CK_1510 | CK_310),
+	CLK(NULL,	"usb_hhc_ck",	&usb_hhc_ck16xx, CK_16XX),
+	CLK(NULL,	"usb_dc_ck",	&usb_dc_ck,	CK_16XX),
+	CLK(NULL,	"usb_dc_ck",	&usb_dc_ck7xx,	CK_7XX),
+	CLK(NULL,	"mclk",		&mclk_1510,	CK_1510 | CK_310),
+	CLK(NULL,	"mclk",		&mclk_16xx,	CK_16XX),
+	CLK(NULL,	"bclk",		&bclk_1510,	CK_1510 | CK_310),
+	CLK(NULL,	"bclk",		&bclk_16xx,	CK_16XX),
+	CLK("mmci-omap.0", "fck",	&mmc1_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK("mmci-omap.0", "fck",	&mmc3_ck,	CK_7XX),
+	CLK("mmci-omap.0", "ick",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK("mmci-omap.1", "fck",	&mmc2_ck,	CK_16XX),
+	CLK("mmci-omap.1", "ick",	&armper_ck.clk,	CK_16XX),
+	/* Virtual clocks */
+	CLK(NULL,	"mpu",		&virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
+	CLK("i2c_omap.1", "fck",	&i2c_fck,	CK_16XX | CK_1510 | CK_310 | CK_7XX),
+	CLK("i2c_omap.1", "ick",	&i2c_ick,	CK_16XX),
+	CLK("i2c_omap.1", "ick",	&dummy_ck,	CK_1510 | CK_310 | CK_7XX),
+	CLK("omap1_spi100k.1", "fck",	&dummy_ck,	CK_7XX),
+	CLK("omap1_spi100k.1", "ick",	&dummy_ck,	CK_7XX),
+	CLK("omap1_spi100k.2", "fck",	&dummy_ck,	CK_7XX),
+	CLK("omap1_spi100k.2", "ick",	&dummy_ck,	CK_7XX),
+	CLK("omap_uwire", "fck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310),
+	CLK("omap-mcbsp.1", "ick",	&dspper_ck,	CK_16XX),
+	CLK("omap-mcbsp.1", "ick",	&dummy_ck,	CK_1510 | CK_310),
+	CLK("omap-mcbsp.2", "ick",	&armper_ck.clk,	CK_16XX),
+	CLK("omap-mcbsp.2", "ick",	&dummy_ck,	CK_1510 | CK_310),
+	CLK("omap-mcbsp.3", "ick",	&dspper_ck,	CK_16XX),
+	CLK("omap-mcbsp.3", "ick",	&dummy_ck,	CK_1510 | CK_310),
+	CLK("omap-mcbsp.1", "fck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
+	CLK("omap-mcbsp.2", "fck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310),
+	CLK("omap-mcbsp.3", "fck",	&dspxor_ck,	CK_16XX | CK_1510 | CK_310),
+};
+
+/*
+ * init
+ */
+
+static struct clk_functions omap1_clk_functions = {
+	.clk_enable		= omap1_clk_enable,
+	.clk_disable		= omap1_clk_disable,
+	.clk_round_rate		= omap1_clk_round_rate,
+	.clk_set_rate		= omap1_clk_set_rate,
+	.clk_disable_unused	= omap1_clk_disable_unused,
+};
+
+int __init omap1_clk_init(void)
+{
+	struct omap_clk *c;
+	const struct omap_clock_config *info;
+	int crystal_type = 0; /* Default 12 MHz */
+	u32 reg, cpu_mask;
+
+#ifdef CONFIG_DEBUG_LL
+	/*
+	 * Resets some clocks that may be left on from bootloader,
+	 * but leaves serial clocks on.
+	 */
+	omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+#endif
+
+	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+	reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
+	omap_writew(reg, SOFT_REQ_REG);
+	if (!cpu_is_omap15xx())
+		omap_writew(0, SOFT_REQ_REG2);
+
+	clk_init(&omap1_clk_functions);
+
+	/* By default all idlect1 clocks are allowed to idle */
+	arm_idlect1_mask = ~0;
+
+	for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+		clk_preinit(c->lk.clk);
+
+	cpu_mask = 0;
+	if (cpu_is_omap16xx())
+		cpu_mask |= CK_16XX;
+	if (cpu_is_omap1510())
+		cpu_mask |= CK_1510;
+	if (cpu_is_omap7xx())
+		cpu_mask |= CK_7XX;
+	if (cpu_is_omap310())
+		cpu_mask |= CK_310;
+
+	for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+		if (c->cpu & cpu_mask) {
+			clkdev_add(&c->lk);
+			clk_register(c->lk.clk);
+		}
+
+	/* Pointers to these clocks are needed by code in clock.c */
+	api_ck_p = clk_get(NULL, "api_ck");
+	ck_dpll1_p = clk_get(NULL, "ck_dpll1");
+	ck_ref_p = clk_get(NULL, "ck_ref");
+
+	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
+	if (info != NULL) {
+		if (!cpu_is_omap15xx())
+			crystal_type = info->system_clock_type;
+	}
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	ck_ref.rate = 13000000;
+#elif defined(CONFIG_ARCH_OMAP16XX)
+	if (crystal_type == 2)
+		ck_ref.rate = 19200000;
+#endif
+
+	pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: "
+		"0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+		omap_readw(ARM_CKCTL));
+
+	/* We want to be in syncronous scalable mode */
+	omap_writew(0x1000, ARM_SYSST);
+
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+	/* Use values set by bootloader. Determine PLL rate and recalculate
+	 * dependent clocks as if kernel had changed PLL or divisors.
+	 */
+	{
+		unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+		ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+		if (pll_ctl_val & 0x10) {
+			/* PLL enabled, apply multiplier and divisor */
+			if (pll_ctl_val & 0xf80)
+				ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+			ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+		} else {
+			/* PLL disabled, apply bypass divisor */
+			switch (pll_ctl_val & 0xc) {
+			case 0:
+				break;
+			case 0x4:
+				ck_dpll1.rate /= 2;
+				break;
+			default:
+				ck_dpll1.rate /= 4;
+				break;
+			}
+		}
+	}
+#else
+	/* Find the highest supported frequency and enable it */
+	if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+		printk(KERN_ERR "System frequencies not set. Check your config.\n");
+		/* Guess sane values (60MHz) */
+		omap_writew(0x2290, DPLL_CTL);
+		omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL);
+		ck_dpll1.rate = 60000000;
+	}
+#endif
+	propagate_rate(&ck_dpll1);
+	/* Cache rates for clocks connected to ck_ref (not dpll1) */
+	propagate_rate(&ck_ref);
+	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
+		"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+	       ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+	       arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+
+#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
+	/* Select slicer output as OMAP input clock */
+	omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, OMAP7XX_PCC_UPLD_CTRL);
+#endif
+
+	/* Amstrad Delta wants BCLK high when inactive */
+	if (machine_is_ams_delta())
+		omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
+				(1 << SDW_MCLK_INV_BIT),
+				ULPD_CLOCK_CTRL);
+
+	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
+	/* (on 730, bit 13 must not be cleared) */
+	if (cpu_is_omap7xx())
+		omap_writew(omap_readw(ARM_CKCTL) & 0x2fff, ARM_CKCTL);
+	else
+		omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
+
+	/* Put DSP/MPUI into reset until needed */
+	omap_writew(0, ARM_RSTCT1);
+	omap_writew(1, ARM_RSTCT2);
+	omap_writew(0x400, ARM_IDLECT1);
+
+	/*
+	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
+	 * of the ARM_IDLECT2 register must be set to zero. The power-on
+	 * default value of this bit is one.
+	 */
+	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable(&armper_ck.clk);
+	clk_enable(&armxor_ck.clk);
+	clk_enable(&armtim_ck.clk); /* This should be done by timer code */
+
+	if (cpu_is_omap15xx())
+		clk_enable(&arm_gpio_ck);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mach-omap1/clock.h
  *
- *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
  *
@@ -13,30 +13,36 @@
 #ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
 #define __ARCH_ARM_MACH_OMAP1_CLOCK_H
 
-static unsigned long omap1_ckctl_recalc(struct clk *clk);
-static unsigned long omap1_watchdog_recalc(struct clk *clk);
-static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
-static unsigned long omap1_sossi_recalc(struct clk *clk);
-static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
-static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
-static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
-static unsigned long omap1_uart_recalc(struct clk *clk);
-static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
-static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
-static void omap1_init_ext_clk(struct clk * clk);
-static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
-static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
+#include <linux/clk.h>
 
-static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
-static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+#include <plat/clock.h>
 
-struct mpu_rate {
-	unsigned long		rate;
-	unsigned long		xtal;
-	unsigned long		pll_rate;
-	__u16			ckctl_val;
-	__u16			dpllctl_val;
-};
+extern int __init omap1_clk_init(void);
+extern int omap1_clk_enable(struct clk *clk);
+extern void omap1_clk_disable(struct clk *clk);
+extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
+extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_ckctl_recalc(struct clk *clk);
+extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_sossi_recalc(struct clk *clk);
+extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
+extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate);
+extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_uart_recalc(struct clk *clk);
+extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate);
+extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate);
+extern void omap1_init_ext_clk(struct clk *clk);
+extern int omap1_select_table_rate(struct clk *clk, unsigned long rate);
+extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate);
+extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_watchdog_recalc(struct clk *clk);
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+extern void __init omap1_clk_disable_unused(struct clk *clk);
+#else
+#define omap1_clk_disable_unused	NULL
+#endif
 
 struct uart_clk {
 	struct clk	clk;
@@ -96,574 +102,12 @@ struct arm_idlect1_clk {
 #define SOFT_REQ_REG		0xfffe0834
 #define SOFT_REQ_REG2		0xfffe0880
 
-/*-------------------------------------------------------------------------
- * Omap1 MPU rate table
- *-------------------------------------------------------------------------*/
-static struct mpu_rate rate_table[] = {
-	/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
-	 * NOTE: Comment order here is different from bits in CKCTL value:
-	 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
-	 */
-#if defined(CONFIG_OMAP_ARM_216MHZ)
-	{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_195MHZ)
-	{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_192MHZ)
-	{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
-	{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
-	{  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
-	{  48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
-	{  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_182MHZ)
-	{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_168MHZ)
-	{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_150MHZ)
-	{ 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
-#endif
-#if defined(CONFIG_OMAP_ARM_120MHZ)
-	{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
-#endif
-#if defined(CONFIG_OMAP_ARM_96MHZ)
-	{  96000000, 12000000,  96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_60MHZ)
-	{  60000000, 12000000,  60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_30MHZ)
-	{  30000000, 12000000,  60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
-#endif
-	{ 0, 0, 0, 0, 0 },
-};
-
-/*-------------------------------------------------------------------------
- * Omap1 clocks
- *-------------------------------------------------------------------------*/
-
-static struct clk ck_ref = {
-	.name		= "ck_ref",
-	.ops		= &clkops_null,
-	.rate		= 12000000,
-};
-
-static struct clk ck_dpll1 = {
-	.name		= "ck_dpll1",
-	.ops		= &clkops_null,
-	.parent		= &ck_ref,
-};
-
-static struct arm_idlect1_clk ck_dpll1out = {
-	.clk = {
-		.name		= "ck_dpll1out",
-		.ops		= &clkops_generic,
-		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_CKOUT_ARM,
-		.recalc		= &followparent_recalc,
-	},
-	.idlect_shift	= 12,
-};
-
-static struct clk sossi_ck = {
-	.name		= "ck_sossi",
-	.ops		= &clkops_generic,
-	.parent		= &ck_dpll1out.clk,
-	.flags		= CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
-	.enable_bit	= 16,
-	.recalc		= &omap1_sossi_recalc,
-	.set_rate	= &omap1_set_sossi_rate,
-};
-
-static struct clk arm_ck = {
-	.name		= "arm_ck",
-	.ops		= &clkops_null,
-	.parent		= &ck_dpll1,
-	.rate_offset	= CKCTL_ARMDIV_OFFSET,
-	.recalc		= &omap1_ckctl_recalc,
-	.round_rate	= omap1_clk_round_rate_ckctl_arm,
-	.set_rate	= omap1_clk_set_rate_ckctl_arm,
-};
-
-static struct arm_idlect1_clk armper_ck = {
-	.clk = {
-		.name		= "armper_ck",
-		.ops		= &clkops_generic,
-		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_PERCK,
-		.rate_offset	= CKCTL_PERDIV_OFFSET,
-		.recalc		= &omap1_ckctl_recalc,
-		.round_rate	= omap1_clk_round_rate_ckctl_arm,
-		.set_rate	= omap1_clk_set_rate_ckctl_arm,
-	},
-	.idlect_shift	= 2,
-};
-
-static struct clk arm_gpio_ck = {
-	.name		= "arm_gpio_ck",
-	.ops		= &clkops_generic,
-	.parent		= &ck_dpll1,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-	.enable_bit	= EN_GPIOCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct arm_idlect1_clk armxor_ck = {
-	.clk = {
-		.name		= "armxor_ck",
-		.ops		= &clkops_generic,
-		.parent		= &ck_ref,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_XORPCK,
-		.recalc		= &followparent_recalc,
-	},
-	.idlect_shift	= 1,
-};
-
-static struct arm_idlect1_clk armtim_ck = {
-	.clk = {
-		.name		= "armtim_ck",
-		.ops		= &clkops_generic,
-		.parent		= &ck_ref,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_TIMCK,
-		.recalc		= &followparent_recalc,
-	},
-	.idlect_shift	= 9,
-};
-
-static struct arm_idlect1_clk armwdt_ck = {
-	.clk = {
-		.name		= "armwdt_ck",
-		.ops		= &clkops_generic,
-		.parent		= &ck_ref,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_WDTCK,
-		.recalc		= &omap1_watchdog_recalc,
-	},
-	.idlect_shift	= 0,
-};
-
-static struct clk arminth_ck16xx = {
-	.name		= "arminth_ck",
-	.ops		= &clkops_null,
-	.parent		= &arm_ck,
-	.recalc		= &followparent_recalc,
-	/* Note: On 16xx the frequency can be divided by 2 by programming
-	 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
-	 *
-	 * 1510 version is in TC clocks.
-	 */
-};
-
-static struct clk dsp_ck = {
-	.name		= "dsp_ck",
-	.ops		= &clkops_generic,
-	.parent		= &ck_dpll1,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_CKCTL),
-	.enable_bit	= EN_DSPCK,
-	.rate_offset	= CKCTL_DSPDIV_OFFSET,
-	.recalc		= &omap1_ckctl_recalc,
-	.round_rate	= omap1_clk_round_rate_ckctl_arm,
-	.set_rate	= omap1_clk_set_rate_ckctl_arm,
-};
-
-static struct clk dspmmu_ck = {
-	.name		= "dspmmu_ck",
-	.ops		= &clkops_null,
-	.parent		= &ck_dpll1,
-	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
-	.recalc		= &omap1_ckctl_recalc,
-	.round_rate	= omap1_clk_round_rate_ckctl_arm,
-	.set_rate	= omap1_clk_set_rate_ckctl_arm,
-};
-
-static struct clk dspper_ck = {
-	.name		= "dspper_ck",
-	.ops		= &clkops_dspck,
-	.parent		= &ck_dpll1,
-	.enable_reg	= DSP_IDLECT2,
-	.enable_bit	= EN_PERCK,
-	.rate_offset	= CKCTL_PERDIV_OFFSET,
-	.recalc		= &omap1_ckctl_recalc_dsp_domain,
-	.round_rate	= omap1_clk_round_rate_ckctl_arm,
-	.set_rate	= &omap1_clk_set_rate_dsp_domain,
-};
-
-static struct clk dspxor_ck = {
-	.name		= "dspxor_ck",
-	.ops		= &clkops_dspck,
-	.parent		= &ck_ref,
-	.enable_reg	= DSP_IDLECT2,
-	.enable_bit	= EN_XORPCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dsptim_ck = {
-	.name		= "dsptim_ck",
-	.ops		= &clkops_dspck,
-	.parent		= &ck_ref,
-	.enable_reg	= DSP_IDLECT2,
-	.enable_bit	= EN_DSPTIMCK,
-	.recalc		= &followparent_recalc,
-};
-
-/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
-static struct arm_idlect1_clk tc_ck = {
-	.clk = {
-		.name		= "tc_ck",
-		.ops		= &clkops_null,
-		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.rate_offset	= CKCTL_TCDIV_OFFSET,
-		.recalc		= &omap1_ckctl_recalc,
-		.round_rate	= omap1_clk_round_rate_ckctl_arm,
-		.set_rate	= omap1_clk_set_rate_ckctl_arm,
-	},
-	.idlect_shift	= 6,
-};
-
-static struct clk arminth_ck1510 = {
-	.name		= "arminth_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-	/* Note: On 1510 the frequency follows TC_CK
-	 *
-	 * 16xx version is in MPU clocks.
-	 */
-};
-
-static struct clk tipb_ck = {
-	/* No-idle controlled by "tc_ck" */
-	.name		= "tipb_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l3_ocpi_ck = {
-	/* No-idle controlled by "tc_ck" */
-	.name		= "l3_ocpi_ck",
-	.ops		= &clkops_generic,
-	.parent		= &tc_ck.clk,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
-	.enable_bit	= EN_OCPI_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk tc1_ck = {
-	.name		= "tc1_ck",
-	.ops		= &clkops_generic,
-	.parent		= &tc_ck.clk,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
-	.enable_bit	= EN_TC1_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk tc2_ck = {
-	.name		= "tc2_ck",
-	.ops		= &clkops_generic,
-	.parent		= &tc_ck.clk,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
-	.enable_bit	= EN_TC2_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dma_ck = {
-	/* No-idle controlled by "tc_ck" */
-	.name		= "dma_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dma_lcdfree_ck = {
-	.name		= "dma_lcdfree_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct arm_idlect1_clk api_ck = {
-	.clk = {
-		.name		= "api_ck",
-		.ops		= &clkops_generic,
-		.parent		= &tc_ck.clk,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_APICK,
-		.recalc		= &followparent_recalc,
-	},
-	.idlect_shift	= 8,
-};
-
-static struct arm_idlect1_clk lb_ck = {
-	.clk = {
-		.name		= "lb_ck",
-		.ops		= &clkops_generic,
-		.parent		= &tc_ck.clk,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_LBCK,
-		.recalc		= &followparent_recalc,
-	},
-	.idlect_shift	= 4,
-};
-
-static struct clk rhea1_ck = {
-	.name		= "rhea1_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rhea2_ck = {
-	.name		= "rhea2_ck",
-	.ops		= &clkops_null,
-	.parent		= &tc_ck.clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk lcd_ck_16xx = {
-	.name		= "lcd_ck",
-	.ops		= &clkops_generic,
-	.parent		= &ck_dpll1,
-	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-	.enable_bit	= EN_LCDCK,
-	.rate_offset	= CKCTL_LCDDIV_OFFSET,
-	.recalc		= &omap1_ckctl_recalc,
-	.round_rate	= omap1_clk_round_rate_ckctl_arm,
-	.set_rate	= omap1_clk_set_rate_ckctl_arm,
-};
-
-static struct arm_idlect1_clk lcd_ck_1510 = {
-	.clk = {
-		.name		= "lcd_ck",
-		.ops		= &clkops_generic,
-		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IDLE_CONTROL,
-		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
-		.enable_bit	= EN_LCDCK,
-		.rate_offset	= CKCTL_LCDDIV_OFFSET,
-		.recalc		= &omap1_ckctl_recalc,
-		.round_rate	= omap1_clk_round_rate_ckctl_arm,
-		.set_rate	= omap1_clk_set_rate_ckctl_arm,
-	},
-	.idlect_shift	= 3,
-};
-
-static struct clk uart1_1510 = {
-	.name		= "uart1_ck",
-	.ops		= &clkops_null,
-	/* Direct from ULPD, no real parent */
-	.parent		= &armper_ck.clk,
-	.rate		= 12000000,
-	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
-	.set_rate	= &omap1_set_uart_rate,
-	.recalc		= &omap1_uart_recalc,
-};
-
-static struct uart_clk uart1_16xx = {
-	.clk	= {
-		.name		= "uart1_ck",
-		.ops		= &clkops_uart,
-		/* Direct from ULPD, no real parent */
-		.parent		= &armper_ck.clk,
-		.rate		= 48000000,
-		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
-				  CLOCK_NO_IDLE_PARENT,
-		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-		.enable_bit	= 29,
-	},
-	.sysc_addr	= 0xfffb0054,
-};
-
-static struct clk uart2_ck = {
-	.name		= "uart2_ck",
-	.ops		= &clkops_null,
-	/* Direct from ULPD, no real parent */
-	.parent		= &armper_ck.clk,
-	.rate		= 12000000,
-	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
-	.set_rate	= &omap1_set_uart_rate,
-	.recalc		= &omap1_uart_recalc,
-};
-
-static struct clk uart3_1510 = {
-	.name		= "uart3_ck",
-	.ops		= &clkops_null,
-	/* Direct from ULPD, no real parent */
-	.parent		= &armper_ck.clk,
-	.rate		= 12000000,
-	.flags		= ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
-	.set_rate	= &omap1_set_uart_rate,
-	.recalc		= &omap1_uart_recalc,
-};
-
-static struct uart_clk uart3_16xx = {
-	.clk	= {
-		.name		= "uart3_ck",
-		.ops		= &clkops_uart,
-		/* Direct from ULPD, no real parent */
-		.parent		= &armper_ck.clk,
-		.rate		= 48000000,
-		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
-				  CLOCK_NO_IDLE_PARENT,
-		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-		.enable_bit	= 31,
-	},
-	.sysc_addr	= 0xfffb9854,
-};
-
-static struct clk usb_clko = {	/* 6 MHz output on W4_USB_CLKO */
-	.name		= "usb_clko",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent */
-	.rate		= 6000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
-	.enable_bit	= USB_MCLK_EN_BIT,
-};
-
-static struct clk usb_hhc_ck1510 = {
-	.name		= "usb_hhc_ck",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= USB_HOST_HHC_UHOST_EN,
-};
-
-static struct clk usb_hhc_ck16xx = {
-	.name		= "usb_hhc_ck",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
-	.enable_bit	= 8 /* UHOST_EN */,
-};
-
-static struct clk usb_dc_ck = {
-	.name		= "usb_dc_ck",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	.flags		= RATE_FIXED,
-	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-	.enable_bit	= 4,
-};
-
-static struct clk mclk_1510 = {
-	.name		= "mclk",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.rate		= 12000000,
-	.flags		= RATE_FIXED,
-	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-	.enable_bit	= 6,
-};
-
-static struct clk mclk_16xx = {
-	.name		= "mclk",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.enable_reg	= OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
-	.enable_bit	= COM_ULPD_PLL_CLK_REQ,
-	.set_rate	= &omap1_set_ext_clk_rate,
-	.round_rate	= &omap1_round_ext_clk_rate,
-	.init		= &omap1_init_ext_clk,
-};
-
-static struct clk bclk_1510 = {
-	.name		= "bclk",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.rate		= 12000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk bclk_16xx = {
-	.name		= "bclk",
-	.ops		= &clkops_generic,
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.enable_reg	= OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
-	.enable_bit	= SWD_ULPD_PLL_CLK_REQ,
-	.set_rate	= &omap1_set_ext_clk_rate,
-	.round_rate	= &omap1_round_ext_clk_rate,
-	.init		= &omap1_init_ext_clk,
-};
-
-static struct clk mmc1_ck = {
-	.name		= "mmc_ck",
-	.ops		= &clkops_generic,
-	/* Functional clock is direct from ULPD, interface clock is ARMPER */
-	.parent		= &armper_ck.clk,
-	.rate		= 48000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= 23,
-};
-
-static struct clk mmc2_ck = {
-	.name		= "mmc_ck",
-	.id		= 1,
-	.ops		= &clkops_generic,
-	/* Functional clock is direct from ULPD, interface clock is ARMPER */
-	.parent		= &armper_ck.clk,
-	.rate		= 48000000,
-	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-	.enable_bit	= 20,
-};
-
-static struct clk virtual_ck_mpu = {
-	.name		= "mpu",
-	.ops		= &clkops_null,
-	.parent		= &arm_ck, /* Is smarter alias for */
-	.recalc		= &followparent_recalc,
-	.set_rate	= &omap1_select_table_rate,
-	.round_rate	= &omap1_round_to_table_rate,
-};
-
-/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
-remains active during MPU idle whenever this is enabled */
-static struct clk i2c_fck = {
-	.name		= "i2c_fck",
-	.id		= 1,
-	.ops		= &clkops_null,
-	.flags		= CLOCK_NO_IDLE_PARENT,
-	.parent		= &armxor_ck.clk,
-	.recalc		= &followparent_recalc,
-};
+extern __u32 arm_idlect1_mask;
+extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
 
-static struct clk i2c_ick = {
-	.name		= "i2c_ick",
-	.id		= 1,
-	.ops		= &clkops_null,
-	.flags		= CLOCK_NO_IDLE_PARENT,
-	.parent		= &armper_ck.clk,
-	.recalc		= &followparent_recalc,
-};
+extern const struct clkops clkops_dspck;
+extern const struct clkops clkops_dummy;
+extern const struct clkops clkops_uart;
+extern const struct clkops clkops_generic;
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,15 +14,17 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 
-#include <mach/tc.h>
-#include <mach/board.h>
-#include <mach/mux.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/mux.h>
 #include <mach/gpio.h>
-#include <mach/mmc.h>
+#include <plat/mmc.h>
+#include <plat/omap7xx.h>
 
 /*-------------------------------------------------------------------------*/
 
@@ -108,15 +110,22 @@ static inline void omap1_mmc_mux(struct
 			int controller_nr)
 {
 	if (controller_nr == 0) {
-		omap_cfg_reg(MMC_CMD);
-		omap_cfg_reg(MMC_CLK);
-		omap_cfg_reg(MMC_DAT0);
+		if (cpu_is_omap7xx()) {
+			omap_cfg_reg(MMC_7XX_CMD);
+			omap_cfg_reg(MMC_7XX_CLK);
+			omap_cfg_reg(MMC_7XX_DAT0);
+		} else {
+			omap_cfg_reg(MMC_CMD);
+			omap_cfg_reg(MMC_CLK);
+			omap_cfg_reg(MMC_DAT0);
+		}
+
 		if (cpu_is_omap1710()) {
 			omap_cfg_reg(M15_1710_MMC_CLKI);
 			omap_cfg_reg(P19_1710_MMC_CMDDIR);
 			omap_cfg_reg(P20_1710_MMC_DATDIR0);
 		}
-		if (mmc_controller->slots[0].wires == 4) {
+		if (mmc_controller->slots[0].wires == 4 && !cpu_is_omap7xx()) {
 			omap_cfg_reg(MMC_DAT1);
 			/* NOTE: DAT2 can be on W10 (here) or M15 */
 			if (!mmc_controller->slots[0].nomux)
@@ -189,6 +198,38 @@ void __init omap1_init_mmc(struct omap_m
 
 /*-------------------------------------------------------------------------*/
 
+/* OMAP7xx SPI support */
+#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE)
+
+struct platform_device omap_spi1 = {
+	.name           = "omap1_spi100k",
+	.id             = 1,
+};
+
+struct platform_device omap_spi2 = {
+	.name           = "omap1_spi100k",
+	.id             = 2,
+};
+
+static void omap_init_spi100k(void)
+{
+	omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff);
+	if (omap_spi1.dev.platform_data)
+		platform_device_register(&omap_spi1);
+
+	omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff);
+	if (omap_spi2.dev.platform_data)
+		platform_device_register(&omap_spi2);
+}
+
+#else
+static inline void omap_init_spi100k(void)
+{
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if defined(CONFIG_OMAP_STI)
 
 #define OMAP1_STI_BASE		0xfffea000
@@ -256,6 +297,7 @@ static int __init omap1_init_devices(voi
 
 	omap_init_mbox();
 	omap_init_rtc();
+	omap_init_spi100k();
 	omap_init_sti();
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/fpga.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/fpga.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/fpga.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/fpga.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
-#include <mach/fpga.h>
+#include <plat/fpga.h>
 #include <mach/gpio.h>
 
 static void fpga_mask_irq(unsigned int irq)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/i2c.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/i2c.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <plat/i2c.h>
+#include <plat/mux.h>
+#include <plat/cpu.h>
+
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+			  struct i2c_board_info const *info,
+			  unsigned len)
+{
+	if (cpu_is_omap7xx()) {
+		omap_cfg_reg(I2C_7XX_SDA);
+		omap_cfg_reg(I2C_7XX_SCL);
+	} else {
+		omap_cfg_reg(I2C_SDA);
+		omap_cfg_reg(I2C_SCL);
+	}
+
+	return omap_plat_register_i2c_bus(bus_id, clkrate, info, len);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/id.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/id.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/id.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/id.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <mach/cpu.h>
+#include <plat/cpu.h>
 
 #define OMAP_DIE_ID_0		0xfffe1800
 #define OMAP_DIE_ID_1		0xfffe1804
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/clkdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/clkdev.h
+ */
+
+#include <plat/clkdev.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,45 @@
+/* arch/arm/mach-omap1/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This 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.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0xff000000	@ physical base address
+		movne	\rx, #0xfe000000	@ virtual base
+		orr	\rx, \rx, #0x00fb0000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+		orr	\rx, \rx, #0x00009000	@ UART 3
+#endif
+#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
+		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		beq	1002f
+		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1001b
+1002:
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/entry-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/entry-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-omap1/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for OMAP-based platforms
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * 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 <mach/hardware.h>
+#include <mach/io.h>
+#include <mach/irqs.h>
+#include <asm/hardware/gic.h>
+
+#if (defined(CONFIG_ARCH_OMAP730)||defined(CONFIG_ARCH_OMAP850)) && \
+	(defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
+#error "FIXME: OMAP7XX doesn't support multiple-OMAP"
+#elif defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+#define INT_IH2_IRQ		INT_7XX_IH2_IRQ
+#elif defined(CONFIG_ARCH_OMAP15XX)
+#define INT_IH2_IRQ		INT_1510_IH2_IRQ
+#elif defined(CONFIG_ARCH_OMAP16XX)
+#define INT_IH2_IRQ		INT_1610_IH2_IRQ
+#else
+#warning "IH2 IRQ defaulted"
+#define INT_IH2_IRQ		INT_1510_IH2_IRQ
+#endif
+
+ 		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
+		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
+		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
+		mov	\irqstat, #0xffffffff
+		bic	\tmp, \irqstat, \tmp
+		tst	\irqnr, \tmp
+		beq	1510f
+
+		ldr	\irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
+		cmp	\irqnr, #0
+		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+		cmpeq	\irqnr, #INT_IH2_IRQ
+		ldreq	\base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
+		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+		addeqs	\irqnr, \irqnr, #32
+1510:
+		.endm
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/gpio.h
+ */
+
+#include <plat/gpio.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/hardware.h
+ */
+
+#include <plat/hardware.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/io.h
+ */
+
+#include <plat/io.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/irqs.h
+ */
+
+#include <plat/irqs.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/lcdc.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/lcdc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/lcdc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/lcdc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-omap1/include/mach/lcdc.h
+ *
+ * Extracted from drivers/video/omap/lcdc.c
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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.
+ */
+#ifndef __MACH_LCDC_H__
+#define __MACH_LCDC_H__
+
+#define OMAP_LCDC_BASE			0xfffec000
+#define OMAP_LCDC_SIZE			256
+#define OMAP_LCDC_IRQ			INT_LCD_CTRL
+
+#define OMAP_LCDC_CONTROL		(OMAP_LCDC_BASE + 0x00)
+#define OMAP_LCDC_TIMING0		(OMAP_LCDC_BASE + 0x04)
+#define OMAP_LCDC_TIMING1		(OMAP_LCDC_BASE + 0x08)
+#define OMAP_LCDC_TIMING2		(OMAP_LCDC_BASE + 0x0c)
+#define OMAP_LCDC_STATUS		(OMAP_LCDC_BASE + 0x10)
+#define OMAP_LCDC_SUBPANEL		(OMAP_LCDC_BASE + 0x14)
+#define OMAP_LCDC_LINE_INT		(OMAP_LCDC_BASE + 0x18)
+#define OMAP_LCDC_DISPLAY_STATUS	(OMAP_LCDC_BASE + 0x1c)
+
+#define OMAP_LCDC_STAT_DONE		(1 << 0)
+#define OMAP_LCDC_STAT_VSYNC		(1 << 1)
+#define OMAP_LCDC_STAT_SYNC_LOST	(1 << 2)
+#define OMAP_LCDC_STAT_ABC		(1 << 3)
+#define OMAP_LCDC_STAT_LINE_INT		(1 << 4)
+#define OMAP_LCDC_STAT_FUF		(1 << 5)
+#define OMAP_LCDC_STAT_LOADED_PALETTE	(1 << 6)
+
+#define OMAP_LCDC_CTRL_LCD_EN		(1 << 0)
+#define OMAP_LCDC_CTRL_LCD_TFT		(1 << 7)
+#define OMAP_LCDC_CTRL_LINE_IRQ_CLR_SEL	(1 << 10)
+
+#define OMAP_LCDC_IRQ_VSYNC		(1 << 2)
+#define OMAP_LCDC_IRQ_DONE		(1 << 3)
+#define OMAP_LCDC_IRQ_LOADED_PALETTE	(1 << 4)
+#define OMAP_LCDC_IRQ_LINE_NIRQ		(1 << 5)
+#define OMAP_LCDC_IRQ_LINE		(1 << 6)
+#define OMAP_LCDC_IRQ_MASK		(((1 << 5) - 1) << 2)
+
+#endif /* __MACH_LCDC_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/lcd_dma.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/lcd_dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/lcd_dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/lcd_dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,78 @@
+/*
+ *  arch/arm/mach-omap1/include/mach/lcd_dma.h
+ *
+ * Extracted from arch/arm/plat-omap/include/plat/dma.h
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.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
+ */
+#ifndef __MACH_OMAP1_LCD_DMA_H__
+#define __MACH_OMAP1_LCD_DMA_H__
+
+/* Hardware registers for LCD DMA */
+#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
+
+/* LCD DMA block numbers */
+enum {
+	OMAP_LCD_DMA_B1_TOP,
+	OMAP_LCD_DMA_B1_BOTTOM,
+	OMAP_LCD_DMA_B2_TOP,
+	OMAP_LCD_DMA_B2_BOTTOM
+};
+
+/* LCD DMA functions */
+extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+				void *data);
+extern void omap_free_lcd_dma(void);
+extern void omap_setup_lcd_dma(void);
+extern void omap_enable_lcd_dma(void);
+extern void omap_stop_lcd_dma(void);
+extern void omap_set_lcd_dma_ext_controller(int external);
+extern void omap_set_lcd_dma_single_transfer(int single);
+extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+				int data_type);
+extern void omap_set_lcd_dma_b1_rotation(int rotate);
+extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
+extern void omap_set_lcd_dma_b1_mirror(int mirror);
+extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
+
+extern int omap_lcd_dma_running(void);
+
+#endif /* __MACH_OMAP1_LCD_DMA_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/memory.h
+ */
+
+#include <plat/memory.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/mtd-xip.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/mtd-xip.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/mtd-xip.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/mtd-xip.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,61 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions.
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
+ *
+ * (c) 2005 MontaVista Software, 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.
+ */
+
+#ifndef __ARCH_OMAP_MTD_XIP_H__
+#define __ARCH_OMAP_MTD_XIP_H__
+
+#include <mach/hardware.h>
+#define OMAP_MPU_TIMER_BASE	(0xfffec500)
+#define OMAP_MPU_TIMER_OFFSET	0x100
+
+typedef struct {
+	u32 cntl;			/* CNTL_TIMER, R/W */
+	u32 load_tim;			/* LOAD_TIM,   W */
+	u32 read_tim;			/* READ_TIM,   R */
+} xip_omap_mpu_timer_regs_t;
+
+#define xip_omap_mpu_timer_base(n)					\
+((volatile xip_omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+	(n)*OMAP_MPU_TIMER_OFFSET))
+
+static inline unsigned long xip_omap_mpu_timer_read(int nr)
+{
+	volatile xip_omap_mpu_timer_regs_t* timer = xip_omap_mpu_timer_base(nr);
+	return timer->read_tim;
+}
+
+#define xip_irqpending()	\
+	(omap_readl(OMAP_IH1_ITR) & ~omap_readl(OMAP_IH1_MIR))
+#define xip_currtime()		(~xip_omap_mpu_timer_read(0))
+
+/*
+ * It's permitted to do approxmation for xip_elapsed_since macro
+ * (see linux/mtd/xip.h)
+ */
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 7)
+#else
+#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 6)
+#endif
+
+/*
+ * xip_cpu_idle() is used when waiting for a delay equal or larger than
+ * the system timer tick period.  This should put the CPU into idle mode
+ * to save power and to be woken up only when some interrupts are pending.
+ * As above, this should not rely upon standard kernel code.
+ */
+
+#define xip_cpu_idle()  asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (1))
+
+#endif /* __ARCH_OMAP_MTD_XIP_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/smp.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/smp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/smp.h
+ */
+
+#include <plat/smp.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/system.h
+ */
+
+#include <plat/system.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/timex.h
+ */
+
+#include <plat/timex.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/uncompress.h
+ */
+
+#include <plat/uncompress.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/vmalloc.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/vmalloc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+/*
+ *  arch/arm/mach-omap1/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * 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 VMALLOC_END	(PAGE_OFFSET + 0x18000000)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/io.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/io.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/io.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,10 +15,11 @@
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
-#include <mach/mux.h>
-#include <mach/tc.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+
+#include "clock.h"
 
-extern int omap1_clk_init(void);
 extern void omap_check_revision(void);
 extern void omap_sram_init(void);
 extern void omapfb_reserve_sdram(void);
@@ -36,33 +37,17 @@ static struct map_desc omap_io_desc[] __
 	}
 };
 
-#ifdef CONFIG_ARCH_OMAP730
-static struct map_desc omap730_io_desc[] __initdata = {
-	{
-		.virtual	= OMAP730_DSP_BASE,
-		.pfn		= __phys_to_pfn(OMAP730_DSP_START),
-		.length		= OMAP730_DSP_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= OMAP730_DSPREG_BASE,
-		.pfn		= __phys_to_pfn(OMAP730_DSPREG_START),
-		.length		= OMAP730_DSPREG_SIZE,
-		.type		= MT_DEVICE
-	}
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP850
-static struct map_desc omap850_io_desc[] __initdata = {
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+static struct map_desc omap7xx_io_desc[] __initdata = {
 	{
-		.virtual	= OMAP850_DSP_BASE,
-		.pfn		= __phys_to_pfn(OMAP850_DSP_START),
-		.length		= OMAP850_DSP_SIZE,
+		.virtual	= OMAP7XX_DSP_BASE,
+		.pfn		= __phys_to_pfn(OMAP7XX_DSP_START),
+		.length		= OMAP7XX_DSP_SIZE,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= OMAP850_DSPREG_BASE,
-		.pfn		= __phys_to_pfn(OMAP850_DSPREG_START),
-		.length		= OMAP850_DSPREG_SIZE,
+		.virtual	= OMAP7XX_DSPREG_BASE,
+		.pfn		= __phys_to_pfn(OMAP7XX_DSPREG_START),
+		.length		= OMAP7XX_DSPREG_SIZE,
 		.type		= MT_DEVICE
 	}
 };
@@ -120,18 +105,11 @@ void __init omap1_map_common_io(void)
 	 */
 	omap_check_revision();
 
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
-	}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP850
-	if (cpu_is_omap850()) {
-		iotable_init(omap850_io_desc, ARRAY_SIZE(omap850_io_desc));
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+	if (cpu_is_omap7xx()) {
+		iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc));
 	}
 #endif
-
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap15xx()) {
 		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,7 @@
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <mach/gpio.h>
-#include <mach/cpu.h>
+#include <plat/cpu.h>
 
 #define IRQ_BANK(irq) ((irq) >> 5)
 #define IRQ_BIT(irq)  ((irq) & 0x1f)
@@ -137,16 +137,8 @@ static void omap_irq_set_cfg(int irq, in
 	irq_bank_writel(val, bank, offset);
 }
 
-#ifdef CONFIG_ARCH_OMAP730
-static struct omap_irq_bank omap730_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3f8e22f },
-	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xfdb9c1f2 },
-	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0x800040f3 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP850
-static struct omap_irq_bank omap850_irq_banks[] = {
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+static struct omap_irq_bank omap7xx_irq_banks[] = {
 	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3f8e22f },
 	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xfdb9c1f2 },
 	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0x800040f3 },
@@ -186,16 +178,10 @@ void __init omap_init_irq(void)
 {
 	int i, j;
 
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		irq_banks = omap730_irq_banks;
-		irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	if (cpu_is_omap850()) {
-		irq_banks = omap850_irq_banks;
-		irq_bank_count = ARRAY_SIZE(omap850_irq_banks);
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	if (cpu_is_omap7xx()) {
+		irq_banks = omap7xx_irq_banks;
+		irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -247,10 +233,8 @@ void __init omap_init_irq(void)
 
 	/* Unmask level 2 handler */
 
-	if (cpu_is_omap730())
-		omap_unmask_irq(INT_730_IH2_IRQ);
-	else if (cpu_is_omap850())
-		omap_unmask_irq(INT_850_IH2_IRQ);
+	if (cpu_is_omap7xx())
+		omap_unmask_irq(INT_7XX_IH2_IRQ);
 	else if (cpu_is_omap15xx())
 		omap_unmask_irq(INT_1510_IH2_IRQ);
 	else if (cpu_is_omap16xx())
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@ config ARCH_OMAP850
 	depends on ARCH_OMAP1
 	bool "OMAP850 Based System"
 	select CPU_ARM926T
+	select ARCH_OMAP_OTG
 
 config ARCH_OMAP15XX
 	depends on ARCH_OMAP1
@@ -56,6 +57,12 @@ config MACH_OMAP_HTCWIZARD
 	help
 	  HTC Wizard smartphone support (AKA QTEK 9100, ...)
 
+config MACH_HERALD
+	bool "HTC Herald"
+	depends on ARCH_OMAP850
+	help
+	  HTC Herald smartphone support (AKA T-Mobile Wing, ...)
+
 config MACH_OMAP_OSK
 	bool "TI OSK Support"
 	depends on ARCH_OMAP1 && ARCH_OMAP16XX
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/lcd_dma.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/lcd_dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/lcd_dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/lcd_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,448 @@
+/*
+ * linux/arch/arm/mach-omap1/lcd_dma.c
+ *
+ * Extracted from arch/arm/plat-omap/dma.c
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Support functions for the OMAP internal DMA channels.
+ *
+ * This 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/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/lcdc.h>
+#include <plat/dma.h>
+
+int omap_lcd_dma_running(void)
+{
+	/*
+	 * On OMAP1510, internal LCD controller will start the transfer
+	 * when it gets enabled, so assume DMA running if LCD enabled.
+	 */
+	if (cpu_is_omap1510())
+		if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN)
+			return 1;
+
+	/* Check if LCD DMA is running */
+	if (cpu_is_omap16xx())
+		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+			return 1;
+
+	return 0;
+}
+
+static struct lcd_dma_info {
+	spinlock_t lock;
+	int reserved;
+	void (*callback)(u16 status, void *data);
+	void *cb_data;
+
+	int active;
+	unsigned long addr, size;
+	int rotate, data_type, xres, yres;
+	int vxres;
+	int mirror;
+	int xscale, yscale;
+	int ext_ctrl;
+	int src_port;
+	int single_transfer;
+} lcd_dma;
+
+void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+			 int data_type)
+{
+	lcd_dma.addr = addr;
+	lcd_dma.data_type = data_type;
+	lcd_dma.xres = fb_xres;
+	lcd_dma.yres = fb_yres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1);
+
+void omap_set_lcd_dma_src_port(int port)
+{
+	lcd_dma.src_port = port;
+}
+
+void omap_set_lcd_dma_ext_controller(int external)
+{
+	lcd_dma.ext_ctrl = external;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
+
+void omap_set_lcd_dma_single_transfer(int single)
+{
+	lcd_dma.single_transfer = single;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
+
+void omap_set_lcd_dma_b1_rotation(int rotate)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
+		BUG();
+		return;
+	}
+	lcd_dma.rotate = rotate;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
+
+void omap_set_lcd_dma_b1_mirror(int mirror)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.mirror = mirror;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
+
+void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA virtual resulotion is not supported "
+				"in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.vxres = vxres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
+
+void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.xscale = xscale;
+	lcd_dma.yscale = yscale;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
+
+static void set_b1_regs(void)
+{
+	unsigned long top, bottom;
+	int es;
+	u16 w;
+	unsigned long en, fn;
+	long ei, fi;
+	unsigned long vxres;
+	unsigned int xscale, yscale;
+
+	switch (lcd_dma.data_type) {
+	case OMAP_DMA_DATA_TYPE_S8:
+		es = 1;
+		break;
+	case OMAP_DMA_DATA_TYPE_S16:
+		es = 2;
+		break;
+	case OMAP_DMA_DATA_TYPE_S32:
+		es = 4;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
+	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
+	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
+	BUG_ON(vxres < lcd_dma.xres);
+
+#define PIXADDR(x, y) (lcd_dma.addr +					\
+		((y) * vxres * yscale + (x) * xscale) * es)
+#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+
+	switch (lcd_dma.rotate) {
+	case 0:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			/* 1510 DMA requires the bottom address to be 2 more
+			 * than the actual last memory access location. */
+			if (cpu_is_omap1510() &&
+				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+					bottom += 2;
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 90:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	case 180:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
+		} else {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 270:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
+		} else {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	default:
+		BUG();
+		return;	/* Suppress warning about uninitialized vars */
+	}
+
+	if (cpu_is_omap1510()) {
+		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
+		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
+		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
+		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
+
+		return;
+	}
+
+	/* 1610 regs */
+	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
+	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
+	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
+	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
+
+	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
+	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
+	w &= ~0x03;
+	w |= lcd_dma.data_type;
+	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	/* Always set the source port as SDRAM for now*/
+	w &= ~(0x03 << 6);
+	if (lcd_dma.callback != NULL)
+		w |= 1 << 1;		/* Block interrupt enable */
+	else
+		w &= ~(1 << 1);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	if (!(lcd_dma.rotate || lcd_dma.mirror ||
+	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	/* Set the double-indexed addressing mode */
+	w |= (0x03 << 12);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
+	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
+	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
+}
+
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
+{
+	u16 w;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	if (unlikely(!(w & (1 << 3)))) {
+		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
+		return IRQ_NONE;
+	}
+	/* Ack the IRQ */
+	w |= (1 << 3);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	lcd_dma.active = 0;
+	if (lcd_dma.callback != NULL)
+		lcd_dma.callback(w, lcd_dma.cb_data);
+
+	return IRQ_HANDLED;
+}
+
+int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+			 void *data)
+{
+	spin_lock_irq(&lcd_dma.lock);
+	if (lcd_dma.reserved) {
+		spin_unlock_irq(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA channel already reserved\n");
+		BUG();
+		return -EBUSY;
+	}
+	lcd_dma.reserved = 1;
+	spin_unlock_irq(&lcd_dma.lock);
+	lcd_dma.callback = callback;
+	lcd_dma.cb_data = data;
+	lcd_dma.active = 0;
+	lcd_dma.single_transfer = 0;
+	lcd_dma.rotate = 0;
+	lcd_dma.vxres = 0;
+	lcd_dma.mirror = 0;
+	lcd_dma.xscale = 0;
+	lcd_dma.yscale = 0;
+	lcd_dma.ext_ctrl = 0;
+	lcd_dma.src_port = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_request_lcd_dma);
+
+void omap_free_lcd_dma(void)
+{
+	spin_lock(&lcd_dma.lock);
+	if (!lcd_dma.reserved) {
+		spin_unlock(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA is not reserved\n");
+		BUG();
+		return;
+	}
+	if (!cpu_is_omap1510())
+		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
+			    OMAP1610_DMA_LCD_CCR);
+	lcd_dma.reserved = 0;
+	spin_unlock(&lcd_dma.lock);
+}
+EXPORT_SYMBOL(omap_free_lcd_dma);
+
+void omap_enable_lcd_dma(void)
+{
+	u16 w;
+
+	/*
+	 * Set the Enable bit only if an external controller is
+	 * connected. Otherwise the OMAP internal controller will
+	 * start the transfer when it gets enabled.
+	 */
+	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w |= 1 << 8;
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	lcd_dma.active = 1;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w |= 1 << 7;
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+}
+EXPORT_SYMBOL(omap_enable_lcd_dma);
+
+void omap_setup_lcd_dma(void)
+{
+	BUG_ON(lcd_dma.active);
+	if (!cpu_is_omap1510()) {
+		/* Set some reasonable defaults */
+		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
+		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
+		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
+	}
+	set_b1_regs();
+	if (!cpu_is_omap1510()) {
+		u16 w;
+
+		w = omap_readw(OMAP1610_DMA_LCD_CCR);
+		/*
+		 * If DMA was already active set the end_prog bit to have
+		 * the programmed register set loaded into the active
+		 * register set.
+		 */
+		w |= 1 << 11;		/* End_prog */
+		if (!lcd_dma.single_transfer)
+			w |= (3 << 8);	/* Auto_init, repeat */
+		omap_writew(w, OMAP1610_DMA_LCD_CCR);
+	}
+}
+EXPORT_SYMBOL(omap_setup_lcd_dma);
+
+void omap_stop_lcd_dma(void)
+{
+	u16 w;
+
+	lcd_dma.active = 0;
+	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w &= ~(1 << 7);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w &= ~(1 << 8);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+}
+EXPORT_SYMBOL(omap_stop_lcd_dma);
+
+static int __init omap_init_lcd_dma(void)
+{
+	int r;
+
+	if (cpu_is_omap16xx()) {
+		u16 w;
+
+		/* this would prevent OMAP sleep */
+		w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+		w &= ~(1 << 8);
+		omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	}
+
+	spin_lock_init(&lcd_dma.lock);
+
+	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
+			"LCD DMA", NULL);
+	if (r != 0)
+		printk(KERN_ERR "unable to request IRQ for LCD DMA "
+			       "(error %d)\n", r);
+
+	return r;
+}
+
+arch_initcall(omap_init_lcd_dma);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/leds.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/leds.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
 #include <asm/mach-types.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
+#include <plat/mux.h>
 
 #include "leds.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/leds-h2p2-debug.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/leds-h2p2-debug.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/leds-h2p2-debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/leds-h2p2-debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
-#include <mach/fpga.h>
+#include <plat/fpga.h>
 #include <mach/gpio.h>
 
 #include "leds.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mailbox.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mailbox.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mailbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mailbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <mach/mailbox.h>
+#include <plat/mailbox.h>
 #include <mach/irqs.h>
 
 #define MAILBOX_ARM2DSP1		0x00
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,8 @@
 #
 
 # Common support
-obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
+obj-y := io.o id.o sram.o irq.o mux.o serial.o devices.o
+obj-y += clock.o clock_data.o opp_data.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
@@ -17,6 +18,9 @@ obj-$(CONFIG_PM) += pm.o sleep.o
 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)
+
 led-y := leds.o
 
 # Specific board support
@@ -34,6 +38,7 @@ obj-$(CONFIG_MACH_OMAP_PALMTT)		+= board
 obj-$(CONFIG_MACH_NOKIA770)		+= board-nokia770.o
 obj-$(CONFIG_MACH_AMS_DELTA)		+= board-ams-delta.o
 obj-$(CONFIG_MACH_SX1)			+= board-sx1.o board-sx1-mmc.o
+obj-$(CONFIG_MACH_HERALD)		+= board-htcherald.o
 
 ifeq ($(CONFIG_ARCH_OMAP15XX),y)
 # Innovator-1510 FPGA
@@ -47,3 +52,7 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR)	+= led
 led-$(CONFIG_MACH_OMAP_PERSEUS2)	+= leds-h2p2-debug.o
 led-$(CONFIG_MACH_OMAP_OSK)		+= leds-osk.o
 obj-$(CONFIG_LEDS)			+= $(led-y)
+
+ifneq ($(CONFIG_FB_OMAP),)
+obj-y += lcd_dma.o
+endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mcbsp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mcbsp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mcbsp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,11 +18,11 @@
 #include <linux/platform_device.h>
 
 #include <mach/irqs.h>
-#include <mach/dma.h>
-#include <mach/mux.h>
-#include <mach/cpu.h>
-#include <mach/mcbsp.h>
-#include <mach/dsp_common.h>
+#include <plat/dma.h>
+#include <plat/mux.h>
+#include <plat/cpu.h>
+#include <plat/mcbsp.h>
+#include <plat/dsp_common.h>
 
 #define DPS_RSTCT2_PER_EN	(1 << 0)
 #define DSP_RSTCT2_WD_PER_EN	(1 << 1)
@@ -79,29 +79,29 @@ static struct omap_mcbsp_ops omap1_mcbsp
 	.free		= omap1_mcbsp_free,
 };
 
-#ifdef CONFIG_ARCH_OMAP730
-static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
 	{
-		.phys_base	= OMAP730_MCBSP1_BASE,
+		.phys_base	= OMAP7XX_MCBSP1_BASE,
 		.dma_rx_sync	= OMAP_DMA_MCBSP1_RX,
 		.dma_tx_sync	= OMAP_DMA_MCBSP1_TX,
-		.rx_irq		= INT_730_McBSP1RX,
-		.tx_irq		= INT_730_McBSP1TX,
+		.rx_irq		= INT_7XX_McBSP1RX,
+		.tx_irq		= INT_7XX_McBSP1TX,
 		.ops		= &omap1_mcbsp_ops,
 	},
 	{
-		.phys_base	= OMAP730_MCBSP2_BASE,
+		.phys_base	= OMAP7XX_MCBSP2_BASE,
 		.dma_rx_sync	= OMAP_DMA_MCBSP3_RX,
 		.dma_tx_sync	= OMAP_DMA_MCBSP3_TX,
-		.rx_irq		= INT_730_McBSP2RX,
-		.tx_irq		= INT_730_McBSP2TX,
+		.rx_irq		= INT_7XX_McBSP2RX,
+		.tx_irq		= INT_7XX_McBSP2TX,
 		.ops		= &omap1_mcbsp_ops,
 	},
 };
-#define OMAP730_MCBSP_PDATA_SZ		ARRAY_SIZE(omap730_mcbsp_pdata)
+#define OMAP7XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap7xx_mcbsp_pdata)
 #else
-#define omap730_mcbsp_pdata		NULL
-#define OMAP730_MCBSP_PDATA_SZ		0
+#define omap7xx_mcbsp_pdata		NULL
+#define OMAP7XX_MCBSP_PDATA_SZ		0
 #endif
 
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -172,8 +172,8 @@ static struct omap_mcbsp_platform_data o
 
 int __init omap1_mcbsp_init(void)
 {
-	if (cpu_is_omap730())
-		omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
+	if (cpu_is_omap7xx())
+		omap_mcbsp_count = OMAP7XX_MCBSP_PDATA_SZ;
 	if (cpu_is_omap15xx())
 		omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
 	if (cpu_is_omap16xx())
@@ -184,9 +184,9 @@ int __init omap1_mcbsp_init(void)
 	if (!mcbsp_ptr)
 		return -ENOMEM;
 
-	if (cpu_is_omap730())
-		omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
-						OMAP730_MCBSP_PDATA_SZ);
+	if (cpu_is_omap7xx())
+		omap_mcbsp_register_board_cfg(omap7xx_mcbsp_pdata,
+						OMAP7XX_MCBSP_PDATA_SZ);
 
 	if (cpu_is_omap15xx())
 		omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mux.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mux.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/mux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/mux.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,53 +29,53 @@
 
 #include <asm/system.h>
 
-#include <mach/mux.h>
+#include <plat/mux.h>
 
 #ifdef CONFIG_OMAP_MUX
 
 static struct omap_mux_cfg arch_mux_cfg;
 
-#ifdef CONFIG_ARCH_OMAP730
-static struct pin_config __initdata_or_module omap730_pins[] = {
-MUX_CFG_730("E2_730_KBR0",        12,   21,    0,   20,   1, 0)
-MUX_CFG_730("J7_730_KBR1",        12,   25,    0,   24,   1, 0)
-MUX_CFG_730("E1_730_KBR2",        12,   29,    0,   28,   1, 0)
-MUX_CFG_730("F3_730_KBR3",        13,    1,    0,    0,   1, 0)
-MUX_CFG_730("D2_730_KBR4",        13,    5,    0,    4,   1, 0)
-MUX_CFG_730("C2_730_KBC0",        13,    9,    0,    8,   1, 0)
-MUX_CFG_730("D3_730_KBC1",        13,   13,    0,   12,   1, 0)
-MUX_CFG_730("E4_730_KBC2",        13,   17,    0,   16,   1, 0)
-MUX_CFG_730("F4_730_KBC3",        13,   21,    0,   20,   1, 0)
-MUX_CFG_730("E3_730_KBC4",        13,   25,    0,   24,   1, 0)
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+static struct pin_config __initdata_or_module omap7xx_pins[] = {
+MUX_CFG_7XX("E2_7XX_KBR0",        12,   21,    0,   20,   1, 0)
+MUX_CFG_7XX("J7_7XX_KBR1",        12,   25,    0,   24,   1, 0)
+MUX_CFG_7XX("E1_7XX_KBR2",        12,   29,    0,   28,   1, 0)
+MUX_CFG_7XX("F3_7XX_KBR3",        13,    1,    0,    0,   1, 0)
+MUX_CFG_7XX("D2_7XX_KBR4",        13,    5,    0,    4,   1, 0)
+MUX_CFG_7XX("C2_7XX_KBC0",        13,    9,    0,    8,   1, 0)
+MUX_CFG_7XX("D3_7XX_KBC1",        13,   13,    0,   12,   1, 0)
+MUX_CFG_7XX("E4_7XX_KBC2",        13,   17,    0,   16,   1, 0)
+MUX_CFG_7XX("F4_7XX_KBC3",        13,   21,    0,   20,   1, 0)
+MUX_CFG_7XX("E3_7XX_KBC4",        13,   25,    0,   24,   1, 0)
 
-MUX_CFG_730("AA17_730_USB_DM",     2,   21,    0,   20,   0, 0)
-MUX_CFG_730("W16_730_USB_PU_EN",   2,   25,    0,   24,   0, 0)
-MUX_CFG_730("W17_730_USB_VBUSI",   2,   29,    0,   28,   0, 0)
-};
-#define OMAP730_PINS_SZ		ARRAY_SIZE(omap730_pins)
-#else
-#define omap730_pins		NULL
-#define OMAP730_PINS_SZ		0
-#endif	/* CONFIG_ARCH_OMAP730 */
+MUX_CFG_7XX("AA17_7XX_USB_DM",     2,   21,    0,   20,   0, 0)
+MUX_CFG_7XX("W16_7XX_USB_PU_EN",   2,   25,    0,   24,   0, 0)
+MUX_CFG_7XX("W17_7XX_USB_VBUSI",   2,   29,    6,   28,   1, 0)
+MUX_CFG_7XX("W18_7XX_USB_DMCK_OUT",3,    3,    1,    2,   0, 0)
+MUX_CFG_7XX("W19_7XX_USB_DCRST",   3,    7,    1,    6,   0, 0)
 
-#ifdef CONFIG_ARCH_OMAP850
-struct pin_config __initdata_or_module omap850_pins[] = {
-MUX_CFG_850("E2_850_KBR0",        12,   21,    0,   20,   1, 0)
-MUX_CFG_850("J7_850_KBR1",        12,   25,    0,   24,   1, 0)
-MUX_CFG_850("E1_850_KBR2",        12,   29,    0,   28,   1, 0)
-MUX_CFG_850("F3_850_KBR3",        13,    1,    0,    0,   1, 0)
-MUX_CFG_850("D2_850_KBR4",        13,    5,    0,    4,   1, 0)
-MUX_CFG_850("C2_850_KBC0",        13,    9,    0,    8,   1, 0)
-MUX_CFG_850("D3_850_KBC1",        13,   13,    0,   12,   1, 0)
-MUX_CFG_850("E4_850_KBC2",        13,   17,    0,   16,   1, 0)
-MUX_CFG_850("F4_850_KBC3",        13,   21,    0,   20,   1, 0)
-MUX_CFG_850("E3_850_KBC4",        13,   25,    0,   24,   1, 0)
+/* MMC Pins */
+MUX_CFG_7XX("MMC_7XX_CMD",         2,    9,    0,    8,   1, 0)
+MUX_CFG_7XX("MMC_7XX_CLK",         2,   13,    0,   12,   1, 0)
+MUX_CFG_7XX("MMC_7XX_DAT0",        2,   17,    0,   16,   1, 0)
 
-MUX_CFG_850("AA17_850_USB_DM",     2,   21,    0,   20,   0, 0)
-MUX_CFG_850("W16_850_USB_PU_EN",   2,   25,    0,   24,   0, 0)
-MUX_CFG_850("W17_850_USB_VBUSI",   2,   29,    0,   28,   0, 0)
+/* I2C interface */
+MUX_CFG_7XX("I2C_7XX_SCL",         5,    1,    0,    0,   1, 0)
+MUX_CFG_7XX("I2C_7XX_SDA",         5,    5,    0,    0,   1, 0)
+
+/* SPI pins */
+MUX_CFG_7XX("SPI_7XX_1",           6,    5,    4,    4,   1, 0)
+MUX_CFG_7XX("SPI_7XX_2",           6,    9,    4,    8,   1, 0)
+MUX_CFG_7XX("SPI_7XX_3",           6,   13,    4,   12,   1, 0)
+MUX_CFG_7XX("SPI_7XX_4",           6,   17,    4,   16,   1, 0)
+MUX_CFG_7XX("SPI_7XX_5",           8,   25,    0,   24,   0, 0)
+MUX_CFG_7XX("SPI_7XX_6",           9,    5,    0,    4,   0, 0)
 };
-#endif
+#define OMAP7XX_PINS_SZ		ARRAY_SIZE(omap7xx_pins)
+#else
+#define omap7xx_pins		NULL
+#define OMAP7XX_PINS_SZ		0
+#endif	/* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
 static struct pin_config __initdata_or_module omap1xxx_pins[] = {
@@ -438,11 +438,6 @@ int __init_or_module omap1_cfg_reg(const
 			printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
 			       cfg->pull_name, cfg->pull_reg, pull_orig, pull);
 	}
-
-#ifdef CONFIG_ARCH_OMAP850
-	omap_mux_register(omap850_pins, ARRAY_SIZE(omap850_pins));
-#endif
-
 #endif
 
 #ifdef CONFIG_OMAP_MUX_ERRORS
@@ -454,9 +449,9 @@ int __init_or_module omap1_cfg_reg(const
 
 int __init omap1_mux_init(void)
 {
-	if (cpu_is_omap730()) {
-		arch_mux_cfg.pins	= omap730_pins;
-		arch_mux_cfg.size	= OMAP730_PINS_SZ;
+	if (cpu_is_omap7xx()) {
+		arch_mux_cfg.pins	= omap7xx_pins;
+		arch_mux_cfg.size	= OMAP7XX_PINS_SZ;
 		arch_mux_cfg.cfg_reg	= omap1_cfg_reg;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/opp_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/opp_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/opp_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/opp_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,59 @@
+/*
+ *  linux/arch/arm/mach-omap1/opp_data.c
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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 "opp.h"
+
+/*-------------------------------------------------------------------------
+ * Omap1 MPU rate table
+ *-------------------------------------------------------------------------*/
+struct mpu_rate omap1_rate_table[] = {
+	/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
+	 * NOTE: Comment order here is different from bits in CKCTL value:
+	 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
+	 */
+#if defined(CONFIG_OMAP_ARM_216MHZ)
+	{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_195MHZ)
+	{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_192MHZ)
+	{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
+	{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
+	{  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
+	{  48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
+	{  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_182MHZ)
+	{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_168MHZ)
+	{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_150MHZ)
+	{ 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_120MHZ)
+	{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_96MHZ)
+	{  96000000, 12000000,  96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_60MHZ)
+	{  60000000, 12000000,  60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_30MHZ)
+	{  30000000, 12000000,  60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
+#endif
+	{ 0, 0, 0, 0, 0 },
+};
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/opp.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/opp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/opp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/opp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ *  linux/arch/arm/mach-omap1/opp.h
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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 __ARCH_ARM_MACH_OMAP1_OPP_H
+#define __ARCH_ARM_MACH_OMAP1_OPP_H
+
+#include <linux/types.h>
+
+struct mpu_rate {
+	unsigned long		rate;
+	unsigned long		xtal;
+	unsigned long		pll_rate;
+	__u16			ckctl_val;
+	__u16			dpllctl_val;
+};
+
+extern struct mpu_rate omap1_rate_table[];
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/pm.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,21 +48,21 @@
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
-#include <mach/cpu.h>
+#include <plat/cpu.h>
 #include <mach/irqs.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
-#include <mach/tc.h>
-#include <mach/mux.h>
-#include <mach/dma.h>
-#include <mach/dmtimer.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/tc.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/dmtimer.h>
 
 #include "pm.h"
 
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
 static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
-static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
+static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 
@@ -183,9 +183,9 @@ static void omap_pm_wakeup_setup(void)
 	 * drivers must still separately call omap_set_gpio_wakeup() to
 	 * wake up to a GPIO interrupt.
 	 */
-	if (cpu_is_omap730())
-		level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
-			OMAP_IRQ_BIT(INT_730_IH2_IRQ);
+	if (cpu_is_omap7xx())
+		level1_wake = OMAP_IRQ_BIT(INT_7XX_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_7XX_IH2_IRQ);
 	else if (cpu_is_omap15xx())
 		level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
 			OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
@@ -195,10 +195,10 @@ static void omap_pm_wakeup_setup(void)
 
 	omap_writel(~level1_wake, OMAP_IH1_MIR);
 
-	if (cpu_is_omap730()) {
+	if (cpu_is_omap7xx()) {
 		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
-		omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
-				OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
+		omap_writel(~(OMAP_IRQ_BIT(INT_7XX_WAKE_UP_REQ) |
+				OMAP_IRQ_BIT(INT_7XX_MPUIO_KEYPAD)),
 				OMAP_IH2_1_MIR);
 	} else if (cpu_is_omap15xx()) {
 		level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
@@ -253,15 +253,15 @@ void omap1_pm_suspend(void)
 	 * Save interrupt, MPUI, ARM and UPLD control registers.
 	 */
 
-	if (cpu_is_omap730()) {
-		MPUI730_SAVE(OMAP_IH1_MIR);
-		MPUI730_SAVE(OMAP_IH2_0_MIR);
-		MPUI730_SAVE(OMAP_IH2_1_MIR);
-		MPUI730_SAVE(MPUI_CTRL);
-		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI730_SAVE(EMIFS_CONFIG);
-		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+	if (cpu_is_omap7xx()) {
+		MPUI7XX_SAVE(OMAP_IH1_MIR);
+		MPUI7XX_SAVE(OMAP_IH2_0_MIR);
+		MPUI7XX_SAVE(OMAP_IH2_1_MIR);
+		MPUI7XX_SAVE(MPUI_CTRL);
+		MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI7XX_SAVE(EMIFS_CONFIG);
+		MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
 
 	} else if (cpu_is_omap15xx()) {
 		MPUI1510_SAVE(OMAP_IH1_MIR);
@@ -306,7 +306,7 @@ void omap1_pm_suspend(void)
 	omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
 
 		/* shut down dsp_ck */
-	if (!cpu_is_omap730())
+	if (!cpu_is_omap7xx())
 		omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
 
 	/* temporarily enabling api_ck to access DSP registers */
@@ -383,12 +383,12 @@ void omap1_pm_suspend(void)
 	ULPD_RESTORE(ULPD_CLOCK_CTRL);
 	ULPD_RESTORE(ULPD_STATUS_REQ);
 
-	if (cpu_is_omap730()) {
-		MPUI730_RESTORE(EMIFS_CONFIG);
-		MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
-		MPUI730_RESTORE(OMAP_IH1_MIR);
-		MPUI730_RESTORE(OMAP_IH2_0_MIR);
-		MPUI730_RESTORE(OMAP_IH2_1_MIR);
+	if (cpu_is_omap7xx()) {
+		MPUI7XX_RESTORE(EMIFS_CONFIG);
+		MPUI7XX_RESTORE(EMIFF_SDRAM_CONFIG);
+		MPUI7XX_RESTORE(OMAP_IH1_MIR);
+		MPUI7XX_RESTORE(OMAP_IH2_0_MIR);
+		MPUI7XX_RESTORE(OMAP_IH2_1_MIR);
 	} else if (cpu_is_omap15xx()) {
 		MPUI1510_RESTORE(MPUI_CTRL);
 		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
@@ -461,13 +461,13 @@ static int omap_pm_read_proc(
 	ULPD_SAVE(ULPD_DPLL_CTRL);
 	ULPD_SAVE(ULPD_POWER_CTRL);
 
-	if (cpu_is_omap730()) {
-		MPUI730_SAVE(MPUI_CTRL);
-		MPUI730_SAVE(MPUI_DSP_STATUS);
-		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
-		MPUI730_SAVE(EMIFS_CONFIG);
+	if (cpu_is_omap7xx()) {
+		MPUI7XX_SAVE(MPUI_CTRL);
+		MPUI7XX_SAVE(MPUI_DSP_STATUS);
+		MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI7XX_SAVE(EMIFS_CONFIG);
 	} else if (cpu_is_omap15xx()) {
 		MPUI1510_SAVE(MPUI_CTRL);
 		MPUI1510_SAVE(MPUI_DSP_STATUS);
@@ -517,20 +517,20 @@ static int omap_pm_read_proc(
 		   ULPD_SHOW(ULPD_STATUS_REQ),
 		   ULPD_SHOW(ULPD_POWER_CTRL));
 
-		if (cpu_is_omap730()) {
+		if (cpu_is_omap7xx()) {
 			my_buffer_offset += sprintf(my_base + my_buffer_offset,
-			   "MPUI730_CTRL_REG	     0x%-8x \n"
-			   "MPUI730_DSP_STATUS_REG:      0x%-8x \n"
-			   "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-			   "MPUI730_DSP_API_CONFIG_REG:  0x%-8x \n"
-			   "MPUI730_SDRAM_CONFIG_REG:    0x%-8x \n"
-			   "MPUI730_EMIFS_CONFIG_REG:    0x%-8x \n",
-			   MPUI730_SHOW(MPUI_CTRL),
-			   MPUI730_SHOW(MPUI_DSP_STATUS),
-			   MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
-			   MPUI730_SHOW(MPUI_DSP_API_CONFIG),
-			   MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
-			   MPUI730_SHOW(EMIFS_CONFIG));
+			   "MPUI7XX_CTRL_REG	     0x%-8x \n"
+			   "MPUI7XX_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI7XX_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+			   "MPUI7XX_DSP_API_CONFIG_REG:  0x%-8x \n"
+			   "MPUI7XX_SDRAM_CONFIG_REG:    0x%-8x \n"
+			   "MPUI7XX_EMIFS_CONFIG_REG:    0x%-8x \n",
+			   MPUI7XX_SHOW(MPUI_CTRL),
+			   MPUI7XX_SHOW(MPUI_DSP_STATUS),
+			   MPUI7XX_SHOW(MPUI_DSP_BOOT_CONFIG),
+			   MPUI7XX_SHOW(MPUI_DSP_API_CONFIG),
+			   MPUI7XX_SHOW(EMIFF_SDRAM_CONFIG),
+			   MPUI7XX_SHOW(EMIFS_CONFIG));
 		} else if (cpu_is_omap15xx()) {
 			my_buffer_offset += sprintf(my_base + my_buffer_offset,
 			   "MPUI1510_CTRL_REG             0x%-8x \n"
@@ -668,9 +668,9 @@ static int __init omap_pm_init(void)
 	 * These routines need to be in SRAM as that's the only
 	 * memory the MPU can see when it wakes up.
 	 */
-	if (cpu_is_omap730()) {
-		omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
-						   omap730_cpu_suspend_sz);
+	if (cpu_is_omap7xx()) {
+		omap_sram_suspend = omap_sram_push(omap7xx_cpu_suspend,
+						   omap7xx_cpu_suspend_sz);
 	} else if (cpu_is_omap15xx()) {
 		omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
 						   omap1510_cpu_suspend_sz);
@@ -686,8 +686,8 @@ static int __init omap_pm_init(void)
 
 	pm_idle = omap1_pm_idle;
 
-	if (cpu_is_omap730())
-		setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
+	if (cpu_is_omap7xx())
+		setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
 	else if (cpu_is_omap16xx())
 		setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
 
@@ -700,8 +700,8 @@ static int __init omap_pm_init(void)
 	omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
 
 	/* Configure IDLECT3 */
-	if (cpu_is_omap730())
-		omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
+	if (cpu_is_omap7xx())
+		omap_writel(OMAP7XX_IDLECT3_VAL, OMAP7XX_IDLECT3);
 	else if (cpu_is_omap16xx())
 		omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/pm.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/pm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/pm.h	2010-02-24 13:52:17.000000000 -0500
@@ -98,13 +98,14 @@
 #define OMAP1610_IDLECT3		0xfffece24
 #define OMAP1610_IDLE_LOOP_REQUEST	0x0400
 
-#define OMAP730_IDLECT1_SLEEP_VAL	0x16c7
-#define OMAP730_IDLECT2_SLEEP_VAL	0x09c7
-#define OMAP730_IDLECT3_VAL		0x3f
-#define OMAP730_IDLECT3		0xfffece24
-#define OMAP730_IDLE_LOOP_REQUEST	0x0C00
+#define OMAP7XX_IDLECT1_SLEEP_VAL	0x16c7
+#define OMAP7XX_IDLECT2_SLEEP_VAL	0x09c7
+#define OMAP7XX_IDLECT3_VAL		0x3f
+#define OMAP7XX_IDLECT3		0xfffece24
+#define OMAP7XX_IDLE_LOOP_REQUEST	0x0C00
 
 #if     !defined(CONFIG_ARCH_OMAP730) && \
+	!defined(CONFIG_ARCH_OMAP850) && \
 	!defined(CONFIG_ARCH_OMAP15XX) && \
 	!defined(CONFIG_ARCH_OMAP16XX)
 #warning "Power management for this processor not implemented yet"
@@ -122,17 +123,17 @@ extern void allow_idle_sleep(void);
 extern void omap1_pm_idle(void);
 extern void omap1_pm_suspend(void);
 
-extern void omap730_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
 extern void omap1510_cpu_suspend(unsigned short, unsigned short);
 extern void omap1610_cpu_suspend(unsigned short, unsigned short);
-extern void omap730_idle_loop_suspend(void);
+extern void omap7xx_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
 
-extern unsigned int omap730_cpu_suspend_sz;
+extern unsigned int omap7xx_cpu_suspend_sz;
 extern unsigned int omap1510_cpu_suspend_sz;
 extern unsigned int omap1610_cpu_suspend_sz;
-extern unsigned int omap730_idle_loop_suspend_sz;
+extern unsigned int omap7xx_idle_loop_suspend_sz;
 extern unsigned int omap1510_idle_loop_suspend_sz;
 extern unsigned int omap1610_idle_loop_suspend_sz;
 
@@ -155,9 +156,9 @@ extern void omap_serial_wake_trigger(int
 #define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
 #define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
 
-#define MPUI730_SAVE(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x] = omap_readl(x)
-#define MPUI730_RESTORE(x) omap_writel((mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]), (x))
-#define MPUI730_SHOW(x) mpui730_sleep_save[MPUI730_SLEEP_SAVE_##x]
+#define MPUI7XX_SAVE(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] = omap_readl(x)
+#define MPUI7XX_RESTORE(x) omap_writel((mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]), (x))
+#define MPUI7XX_SHOW(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]
 
 #define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x)
 #define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x))
@@ -232,24 +233,24 @@ enum mpui1510_save_state {
 #endif
 };
 
-enum mpui730_save_state {
-	MPUI730_SLEEP_SAVE_START = 0,
+enum mpui7xx_save_state {
+	MPUI7XX_SLEEP_SAVE_START = 0,
 	/*
 	 * MPUI registers 32 bits
 	 */
-	MPUI730_SLEEP_SAVE_MPUI_CTRL,
-	MPUI730_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
-	MPUI730_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
-	MPUI730_SLEEP_SAVE_MPUI_DSP_STATUS,
-	MPUI730_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
-	MPUI730_SLEEP_SAVE_EMIFS_CONFIG,
-	MPUI730_SLEEP_SAVE_OMAP_IH1_MIR,
-	MPUI730_SLEEP_SAVE_OMAP_IH2_0_MIR,
-	MPUI730_SLEEP_SAVE_OMAP_IH2_1_MIR,
-#if defined(CONFIG_ARCH_OMAP730)
-	MPUI730_SLEEP_SAVE_SIZE
+	MPUI7XX_SLEEP_SAVE_MPUI_CTRL,
+	MPUI7XX_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
+	MPUI7XX_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
+	MPUI7XX_SLEEP_SAVE_MPUI_DSP_STATUS,
+	MPUI7XX_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
+	MPUI7XX_SLEEP_SAVE_EMIFS_CONFIG,
+	MPUI7XX_SLEEP_SAVE_OMAP_IH1_MIR,
+	MPUI7XX_SLEEP_SAVE_OMAP_IH2_0_MIR,
+	MPUI7XX_SLEEP_SAVE_OMAP_IH2_1_MIR,
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	MPUI7XX_SLEEP_SAVE_SIZE
 #else
-	MPUI730_SLEEP_SAVE_SIZE = 0
+	MPUI7XX_SLEEP_SAVE_SIZE = 0
 #endif
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/serial.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/serial.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/serial.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/serial.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,10 +22,10 @@
 
 #include <asm/mach-types.h>
 
-#include <mach/board.h>
-#include <mach/mux.h>
+#include <plat/board.h>
+#include <plat/mux.h>
 #include <mach/gpio.h>
-#include <mach/fpga.h>
+#include <plat/fpga.h>
 
 static struct clk * uart1_ck;
 static struct clk * uart2_ck;
@@ -64,7 +64,6 @@ static void __init omap_serial_reset(str
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
-		.membase	= OMAP1_IO_ADDRESS(OMAP_UART1_BASE),
 		.mapbase	= OMAP_UART1_BASE,
 		.irq		= INT_UART1,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -73,7 +72,6 @@ static struct plat_serial8250_port seria
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.membase	= OMAP1_IO_ADDRESS(OMAP_UART2_BASE),
 		.mapbase	= OMAP_UART2_BASE,
 		.irq		= INT_UART2,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -82,7 +80,6 @@ static struct plat_serial8250_port seria
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.membase	= OMAP1_IO_ADDRESS(OMAP_UART3_BASE),
 		.mapbase	= OMAP_UART3_BASE,
 		.irq		= INT_UART3,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -110,18 +107,11 @@ void __init omap_serial_init(void)
 {
 	int i;
 
-	if (cpu_is_omap730()) {
-		serial_platform_data[0].regshift = 0;
-		serial_platform_data[1].regshift = 0;
-		serial_platform_data[0].irq = INT_730_UART_MODEM_1;
-		serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
-	}
-
-	if (cpu_is_omap850()) {
+	if (cpu_is_omap7xx()) {
 		serial_platform_data[0].regshift = 0;
 		serial_platform_data[1].regshift = 0;
-		serial_platform_data[0].irq = INT_850_UART_MODEM_1;
-		serial_platform_data[1].irq = INT_850_UART_MODEM_IRDA_2;
+		serial_platform_data[0].irq = INT_7XX_UART_MODEM_1;
+		serial_platform_data[1].irq = INT_7XX_UART_MODEM_IRDA_2;
 	}
 
 	if (cpu_is_omap15xx()) {
@@ -130,7 +120,15 @@ void __init omap_serial_init(void)
 		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
 	}
 
-	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+	for (i = 0; i < ARRAY_SIZE(serial_platform_data) - 1; i++) {
+
+		/* Static mapping, never released */
+		serial_platform_data[i].membase =
+			ioremap(serial_platform_data[i].mapbase, SZ_2K);
+		if (!serial_platform_data[i].membase) {
+			printk(KERN_ERR "Could not ioremap uart%i\n", i);
+			continue;
+		}
 		switch (i) {
 		case 0:
 			uart1_ck = clk_get(NULL, "uart1_ck");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/sleep.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/sleep.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/sleep.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/sleep.S	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-omap1/sleep.S
  *
- * Low-level OMAP730/1510/1610 sleep/wakeUp support
+ * Low-level OMAP7XX/1510/1610 sleep/wakeUp support
  *
  * Initial SA1110 code:
  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
@@ -57,8 +57,8 @@
  *
  */
 
-#if defined(CONFIG_ARCH_OMAP730)
-ENTRY(omap730_cpu_suspend)
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ENTRY(omap7xx_cpu_suspend)
 
 	@ save registers on stack
 	stmfd	sp!, {r0 - r12, lr}
@@ -91,13 +91,13 @@ ENTRY(omap730_cpu_suspend)
 
 	@ turn off clock domains
 	@ do not disable PERCK (0x04)
-	mov	r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
-	orr	r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
+	mov	r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff
+	orr	r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00
 	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 
 	@ request ARM idle
-	mov	r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
-	orr	r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
+	mov	r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff
+	orr	r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
 	@ disable instruction cache
@@ -113,7 +113,7 @@ ENTRY(omap730_cpu_suspend)
 	mov	r2, #0
 	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
 /*
- * omap730_cpu_suspend()'s resume point.
+ * omap7xx_cpu_suspend()'s resume point.
  *
  * It will just start executing here, so we'll restore stuff from the
  * stack.
@@ -132,9 +132,9 @@ ENTRY(omap730_cpu_suspend)
 	@ restore regs and return
 	ldmfd	sp!, {r0 - r12, pc}
 
-ENTRY(omap730_cpu_suspend_sz)
-	.word	. - omap730_cpu_suspend
-#endif /* CONFIG_ARCH_OMAP730 */
+ENTRY(omap7xx_cpu_suspend_sz)
+	.word	. - omap7xx_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #ifdef CONFIG_ARCH_OMAP15XX
 ENTRY(omap1510_cpu_suspend)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/timer32k.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/timer32k.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap1/timer32k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap1/timer32k.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,7 @@
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <mach/dmtimer.h>
+#include <plat/dmtimer.h>
 
 struct sys_timer omap_timer;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-2430sdp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-2430sdp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -31,12 +31,12 @@
 #include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/gpmc.h>
-#include <mach/usb.h>
-#include <mach/gpmc-smc91x.h>
+#include <plat/mux.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc-smc91x.h>
 
 #include "mmc-twl4030.h"
 
@@ -221,7 +221,7 @@ static void __init omap_2430sdp_map_io(v
 MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
 	/* Maintainer: Syed Khasim - Texas Instruments Inc */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_2430sdp_map_io,
 	.init_irq	= omap_2430sdp_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-3430sdp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3430sdp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-3430sdp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3430sdp.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
@@ -30,17 +30,18 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/mcspi.h>
-#include <mach/mux.h>
-#include <mach/board.h>
-#include <mach/usb.h>
-#include <mach/common.h>
-#include <mach/dma.h>
-#include <mach/gpmc.h>
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/usb.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/display.h>
 
-#include <mach/control.h>
-#include <mach/gpmc-smc91x.h>
+#include <plat/control.h>
+#include <plat/gpmc-smc91x.h>
 
+#include "mux.h"
 #include "sdram-qimonda-hyb18m512160af-6.h"
 #include "mmc-twl4030.h"
 
@@ -152,31 +153,152 @@ static struct spi_board_info sdp3430_spi
 	},
 };
 
-static struct platform_device sdp3430_lcd_device = {
-	.name		= "sdp2430_lcd",
-	.id		= -1,
+
+#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO	8
+#define SDP3430_LCD_PANEL_ENABLE_GPIO		5
+
+static unsigned backlight_gpio;
+static unsigned enable_gpio;
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init sdp3430_display_init(void)
+{
+	int r;
+
+	enable_gpio    = SDP3430_LCD_PANEL_ENABLE_GPIO;
+	backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
+
+	r = gpio_request(enable_gpio, "LCD reset");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD reset GPIO\n");
+		goto err0;
+	}
+
+	r = gpio_request(backlight_gpio, "LCD Backlight");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD backlight GPIO\n");
+		goto err1;
+	}
+
+	gpio_direction_output(enable_gpio, 0);
+	gpio_direction_output(backlight_gpio, 0);
+
+	return;
+err1:
+	gpio_free(enable_gpio);
+err0:
+	return;
+}
+
+static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	if (dvi_enabled) {
+		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+		return -EINVAL;
+	}
+
+	gpio_direction_output(enable_gpio, 1);
+	gpio_direction_output(backlight_gpio, 1);
+
+	lcd_enabled = 1;
+
+	return 0;
+}
+
+static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	lcd_enabled = 0;
+
+	gpio_direction_output(enable_gpio, 0);
+	gpio_direction_output(backlight_gpio, 0);
+}
+
+static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+	if (lcd_enabled) {
+		printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+		return -EINVAL;
+	}
+
+	dvi_enabled = 1;
+
+	return 0;
+}
+
+static void sdp3430_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+	dvi_enabled = 0;
+}
+
+static int sdp3430_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void sdp3430_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+
+static struct omap_dss_device sdp3430_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "sharp_ls_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 16,
+	.platform_enable	= sdp3430_panel_enable_lcd,
+	.platform_disable	= sdp3430_panel_disable_lcd,
 };
 
-static struct regulator_consumer_supply sdp3430_vdac_supply = {
-	.supply		= "vdac",
-	.dev		= &sdp3430_lcd_device.dev,
+static struct omap_dss_device sdp3430_dvi_device = {
+	.name			= "dvi",
+	.driver_name		= "generic_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 24,
+	.platform_enable	= sdp3430_panel_enable_dvi,
+	.platform_disable	= sdp3430_panel_disable_dvi,
 };
 
-static struct regulator_consumer_supply sdp3430_vdvi_supply = {
-	.supply		= "vdvi",
-	.dev		= &sdp3430_lcd_device.dev,
+static struct omap_dss_device sdp3430_tv_device = {
+	.name			= "tv",
+	.driver_name		= "venc",
+	.type			= OMAP_DISPLAY_TYPE_VENC,
+	.phy.venc.type		= OMAP_DSS_VENC_TYPE_SVIDEO,
+	.platform_enable	= sdp3430_panel_enable_tv,
+	.platform_disable	= sdp3430_panel_disable_tv,
 };
 
-static struct platform_device *sdp3430_devices[] __initdata = {
+
+static struct omap_dss_device *sdp3430_dss_devices[] = {
 	&sdp3430_lcd_device,
+	&sdp3430_dvi_device,
+	&sdp3430_tv_device,
 };
 
-static struct omap_lcd_config sdp3430_lcd_config __initdata = {
-	.ctrl_name	= "internal",
+static struct omap_dss_board_info sdp3430_dss_data = {
+	.num_devices	= ARRAY_SIZE(sdp3430_dss_devices),
+	.devices	= sdp3430_dss_devices,
+	.default_device	= &sdp3430_lcd_device,
+};
+
+static struct platform_device sdp3430_dss_device = {
+	.name		= "omapdss",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &sdp3430_dss_data,
+	},
+};
+
+static struct regulator_consumer_supply sdp3430_vdda_dac_supply = {
+	.supply		= "vdda_dac",
+	.dev		= &sdp3430_dss_device.dev,
+};
+
+static struct platform_device *sdp3430_devices[] __initdata = {
+	&sdp3430_dss_device,
 };
 
 static struct omap_board_config_kernel sdp3430_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&sdp3430_lcd_config },
 };
 
 static void __init omap_3430sdp_init_irq(void)
@@ -392,22 +514,43 @@ static struct regulator_init_data sdp343
 					| REGULATOR_CHANGE_STATUS,
 	},
 	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &sdp3430_vdac_supply,
+	.consumer_supplies	= &sdp3430_vdda_dac_supply,
 };
 
 /* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
+	{
+		.supply		= "vdvi",
+		.dev		= &sdp3430_lcd_device.dev,
+	},
+	{
+		.supply		= "vdds_dsi",
+		.dev		= &sdp3430_dss_device.dev,
+	}
+};
+
 static struct regulator_init_data sdp3430_vpll2 = {
 	.constraints = {
 		.name			= "VDVI",
 		.min_uV			= 1800000,
 		.max_uV			= 1800000,
+		.apply_uV		= true,
 		.valid_modes_mask	= REGULATOR_MODE_NORMAL
 					| REGULATOR_MODE_STANDBY,
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &sdp3430_vdvi_supply,
+	.num_consumer_supplies	= ARRAY_SIZE(sdp3430_vpll2_supplies),
+	.consumer_supplies	= sdp3430_vpll2_supplies,
+};
+
+static struct twl4030_codec_audio_data sdp3430_audio = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data sdp3430_codec = {
+	.audio_mclk = 26000000,
+	.audio = &sdp3430_audio,
 };
 
 static struct twl4030_platform_data sdp3430_twldata = {
@@ -420,6 +563,7 @@ static struct twl4030_platform_data sdp3
 	.madc		= &sdp3430_madc_data,
 	.keypad		= &sdp3430_kp_data,
 	.usb		= &sdp3430_usb_data,
+	.codec		= &sdp3430_codec,
 
 	.vaux1		= &sdp3430_vaux1,
 	.vaux2		= &sdp3430_vaux2,
@@ -481,11 +625,34 @@ static inline void board_smc91x_init(voi
 
 static void enable_board_wakeup_source(void)
 {
-	omap_cfg_reg(AF26_34XX_SYS_NIRQ); /* T2 interrupt line (keypad) */
+	/* T2 interrupt line (keypad) */
+	omap_mux_init_signal("sys_nirq",
+		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = 57,
+	.reset_gpio_port[1]  = 61,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init omap_3430sdp_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3430_i2c_init();
 	platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
 	if (omap_rev() > OMAP3430_REV_ES1_0)
@@ -499,7 +666,9 @@ static void __init omap_3430sdp_init(voi
 	omap_serial_init();
 	usb_musb_init();
 	board_smc91x_init();
+	sdp3430_display_init();
 	enable_board_wakeup_source();
+	usb_ehci_init(&ehci_pdata);
 }
 
 static void __init omap_3430sdp_map_io(void)
@@ -511,7 +680,7 @@ static void __init omap_3430sdp_map_io(v
 MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
 	/* Maintainer: Syed Khasim - Texas Instruments Inc */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_3430sdp_map_io,
 	.init_irq	= omap_3430sdp_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-3630sdp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3630sdp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-3630sdp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-3630sdp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/gpmc-smc91x.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "mux.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+	.cs             = 3,
+	.flags          = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+	board_smc91x_data.gpio_irq = 158;
+	gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif /* defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) */
+
+static void enable_board_wakeup_source(void)
+{
+	/* T2 interrupt line (keypad) */
+	omap_mux_init_signal("sys_nirq",
+		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = 126,
+	.reset_gpio_port[1]  = 61,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+static void __init omap_sdp_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+static struct omap_board_config_kernel sdp_config[] __initdata = {
+};
+
+static void __init omap_sdp_init_irq(void)
+{
+	omap_board_config = sdp_config;
+	omap_board_config_size = ARRAY_SIZE(sdp_config);
+	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
+			h8mbx00u0mer0em_sdrc_params);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
+static void __init omap_sdp_init(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+	zoom_peripherals_init();
+	board_smc91x_init();
+	enable_board_wakeup_source();
+	usb_ehci_init(&ehci_pdata);
+}
+
+MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_sdp_map_io,
+	.init_irq	= omap_sdp_init_irq,
+	.init_machine	= omap_sdp_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-4430sdp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-4430sdp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-4430sdp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-4430sdp.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,10 +23,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/control.h>
-#include <mach/timer-gp.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/control.h>
+#include <plat/timer-gp.h>
 #include <asm/hardware/gic.h>
 
 static struct platform_device sdp4430_lcd_device = {
@@ -52,8 +52,17 @@ static struct omap_board_config_kernel s
 
 static void __init gic_init_irq(void)
 {
-	gic_dist_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29);
-	gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
+	void __iomem *base;
+
+	/* Static mapping, never released */
+	base = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
+	BUG_ON(!base);
+	gic_dist_init(0, base, 29);
+
+	/* Static mapping, never released */
+	gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
+	BUG_ON(!gic_cpu_base_addr);
+	gic_cpu_init(0, gic_cpu_base_addr);
 }
 
 static void __init omap_4430sdp_init_irq(void)
@@ -84,7 +93,7 @@ static void __init omap_4430sdp_map_io(v
 MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
 	/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_4430sdp_map_io,
 	.init_irq	= omap_4430sdp_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-am3517evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-am3517evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-am3517evm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-am3517evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,97 @@
+/*
+ * linux/arch/arm/mach-omap2/board-am3517evm.c
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ * Author: Ranjith Lohithakshan <ranjithl@ti.com>
+ *
+ * Based on mach-omap2/board-omap3evm.c
+ *
+ * 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 <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+
+/*
+ * Board initialization
+ */
+static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
+};
+
+static struct platform_device *am3517_evm_devices[] __initdata = {
+};
+
+static void __init am3517_evm_init_irq(void)
+{
+	omap_board_config = am3517_evm_config;
+	omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
+
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = 57,
+	.reset_gpio_port[1]  = -EINVAL,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
+static void __init am3517_evm_init(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	platform_add_devices(am3517_evm_devices,
+				ARRAY_SIZE(am3517_evm_devices));
+
+	omap_serial_init();
+	usb_ehci_init(&ehci_pdata);
+}
+
+static void __init am3517_evm_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= am3517_evm_map_io,
+	.init_irq	= am3517_evm_init_irq,
+	.init_machine	= am3517_evm_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-apollon.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-apollon.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-apollon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-apollon.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <linux/leds.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -33,13 +34,13 @@
 #include <asm/mach/flash.h>
 
 #include <mach/gpio.h>
-#include <mach/led.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/gpmc.h>
-#include <mach/control.h>
+#include <plat/led.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/control.h>
 
 /* LED & Switch macros */
 #define LED0_GPIO13		13
@@ -120,6 +121,12 @@ static void __init apollon_flash_init(vo
 	apollon_flash_resource[0].end   = base + SZ_128K - 1;
 }
 
+static struct smc91x_platdata appolon_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource apollon_smc91x_resources[] = {
 	[0] = {
 		.flags  = IORESOURCE_MEM,
@@ -134,6 +141,9 @@ static struct resource apollon_smc91x_re
 static struct platform_device apollon_smc91x_device = {
 	.name		= "smc91x",
 	.id		= -1,
+	.dev	= {
+		.platform_data	= &appolon_smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(apollon_smc91x_resources),
 	.resource	= apollon_smc91x_resources,
 };
@@ -333,7 +343,7 @@ static void __init omap_apollon_map_io(v
 MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
 	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_apollon_map_io,
 	.init_irq	= omap_apollon_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-cm-t35.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-cm-t35.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-cm-t35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-cm-t35.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,599 @@
+/*
+ * board-cm-t35.c (CompuLab CM-T35 module)
+ *
+ * Copyright (C) 2009 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/at24.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+
+#include <mach/hardware.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "mmc-twl4030.h"
+
+#define CM_T35_GPIO_PENDOWN	57
+
+#define CM_T35_SMSC911X_CS	5
+#define CM_T35_SMSC911X_GPIO	163
+#define SB_T35_SMSC911X_CS	4
+#define SB_T35_SMSC911X_GPIO	65
+
+#define NAND_BLOCK_SIZE		SZ_128K
+#define GPMC_CS0_BASE		0x60
+#define GPMC_CS0_BASE_ADDR	(OMAP34XX_GPMC_VIRT + GPMC_CS0_BASE)
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
+static struct smsc911x_platform_config cm_t35_smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource cm_t35_smsc911x_resources[] = {
+	{
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
+		.end	= OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct platform_device cm_t35_smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(cm_t35_smsc911x_resources),
+	.resource	= cm_t35_smsc911x_resources,
+	.dev		= {
+		.platform_data = &cm_t35_smsc911x_config,
+	},
+};
+
+static struct resource sb_t35_smsc911x_resources[] = {
+	{
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
+		.end	= OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct platform_device sb_t35_smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(sb_t35_smsc911x_resources),
+	.resource	= sb_t35_smsc911x_resources,
+	.dev		= {
+		.platform_data = &cm_t35_smsc911x_config,
+	},
+};
+
+static void __init cm_t35_init_smsc911x(struct platform_device *dev,
+					int cs, int irq_gpio)
+{
+	unsigned long cs_mem_base;
+
+	if (gpmc_cs_request(cs, SZ_16M, &cs_mem_base) < 0) {
+		pr_err("CM-T35: Failed request for GPMC mem for smsc911x\n");
+		return;
+	}
+
+	dev->resource[0].start = cs_mem_base + 0x0;
+	dev->resource[0].end   = cs_mem_base + 0xff;
+
+	if ((gpio_request(irq_gpio, "ETH IRQ") == 0) &&
+	    (gpio_direction_input(irq_gpio) == 0)) {
+		gpio_export(irq_gpio, 0);
+	} else {
+		pr_err("CM-T35: could not obtain gpio for SMSC911X IRQ\n");
+		return;
+	}
+
+	platform_device_register(dev);
+}
+
+static void __init cm_t35_init_ethernet(void)
+{
+	cm_t35_init_smsc911x(&cm_t35_smsc911x_device,
+			     CM_T35_SMSC911X_CS, CM_T35_SMSC911X_GPIO);
+	cm_t35_init_smsc911x(&sb_t35_smsc911x_device,
+			     SB_T35_SMSC911X_CS, SB_T35_SMSC911X_GPIO);
+}
+#else
+static inline void __init cm_t35_init_ethernet(void) { return; }
+#endif
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led cm_t35_leds[] = {
+	[0] = {
+		.gpio			= 186,
+		.name			= "cm-t35:green",
+		.default_trigger	= "heartbeat",
+		.active_low		= 0,
+	},
+};
+
+static struct gpio_led_platform_data cm_t35_led_pdata = {
+	.num_leds	= ARRAY_SIZE(cm_t35_leds),
+	.leds		= cm_t35_leds,
+};
+
+static struct platform_device cm_t35_led_device = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &cm_t35_led_pdata,
+	},
+};
+
+static void __init cm_t35_init_led(void)
+{
+	platform_device_register(&cm_t35_led_device);
+}
+#else
+static inline void cm_t35_init_led(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct mtd_partition cm_t35_nand_partitions[] = {
+	{
+		.name           = "xloader",
+		.offset         = 0,			/* Offset = 0x00000 */
+		.size           = 4 * NAND_BLOCK_SIZE,
+		.mask_flags     = MTD_WRITEABLE
+	},
+	{
+		.name           = "uboot",
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x80000 */
+		.size           = 15 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name           = "uboot environment",
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x260000 */
+		.size           = 2 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name           = "linux",
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
+		.size           = 32 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name           = "rootfs",
+		.offset         = MTDPART_OFS_APPEND,	/* Offset = 0x680000 */
+		.size           = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct omap_nand_platform_data cm_t35_nand_data = {
+	.parts			= cm_t35_nand_partitions,
+	.nr_parts		= ARRAY_SIZE(cm_t35_nand_partitions),
+	.dma_channel		= -1,	/* disable DMA in OMAP NAND driver */
+	.cs			= 0,
+	.gpmc_cs_baseaddr	= (void __iomem *)GPMC_CS0_BASE_ADDR,
+	.gpmc_baseaddr		= (void __iomem *)OMAP34XX_GPMC_VIRT,
+
+};
+
+static struct resource cm_t35_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device cm_t35_nand_device = {
+	.name		= "omap2-nand",
+	.id		= -1,
+	.num_resources	= 1,
+	.resource	= &cm_t35_nand_resource,
+	.dev		= {
+		.platform_data	= &cm_t35_nand_data,
+	},
+};
+
+static void __init cm_t35_init_nand(void)
+{
+	if (platform_device_register(&cm_t35_nand_device) < 0)
+		pr_err("CM-T35: Unable to register NAND device\n");
+}
+#else
+static inline void cm_t35_init_nand(void) {}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <plat/mcspi.h>
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static int ads7846_get_pendown_state(void)
+{
+	return !gpio_get_value(CM_T35_GPIO_PENDOWN);
+}
+
+static struct ads7846_platform_data ads7846_config = {
+	.x_max			= 0x0fff,
+	.y_max			= 0x0fff,
+	.x_plate_ohms		= 180,
+	.pressure_max		= 255,
+	.debounce_max		= 10,
+	.debounce_tol		= 3,
+	.debounce_rep		= 1,
+	.get_pendown_state	= ads7846_get_pendown_state,
+	.keep_vref_on		= 1,
+};
+
+static struct spi_board_info cm_t35_spi_board_info[] __initdata = {
+	{
+		.modalias		= "ads7846",
+		.bus_num		= 1,
+		.chip_select		= 0,
+		.max_speed_hz		= 1500000,
+		.controller_data	= &ads7846_mcspi_config,
+		.irq			= OMAP_GPIO_IRQ(CM_T35_GPIO_PENDOWN),
+		.platform_data		= &ads7846_config,
+	},
+};
+
+static void __init cm_t35_init_ads7846(void)
+{
+	if ((gpio_request(CM_T35_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
+	    (gpio_direction_input(CM_T35_GPIO_PENDOWN) == 0)) {
+		gpio_export(CM_T35_GPIO_PENDOWN, 0);
+	} else {
+		pr_err("CM-T35: could not obtain gpio for ADS7846_PENDOWN\n");
+		return;
+	}
+
+	spi_register_board_info(cm_t35_spi_board_info,
+				ARRAY_SIZE(cm_t35_spi_board_info));
+}
+#else
+static inline void cm_t35_init_ads7846(void) {}
+#endif
+
+static struct regulator_consumer_supply cm_t35_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply cm_t35_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data cm_t35_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &cm_t35_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data cm_t35_vsim = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 3000000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &cm_t35_vsim_supply,
+};
+
+static struct twl4030_usb_data cm_t35_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static int cm_t35_keymap[] = {
+	KEY(0, 0, KEY_A),	KEY(0, 1, KEY_B),	KEY(0, 2, KEY_LEFT),
+	KEY(1, 0, KEY_UP),	KEY(1, 1, KEY_ENTER),	KEY(1, 2, KEY_DOWN),
+	KEY(2, 0, KEY_RIGHT),	KEY(2, 1, KEY_C),	KEY(2, 2, KEY_D),
+};
+
+static struct matrix_keymap_data cm_t35_keymap_data = {
+	.keymap			= cm_t35_keymap,
+	.keymap_size		= ARRAY_SIZE(cm_t35_keymap),
+};
+
+static struct twl4030_keypad_data cm_t35_kp_data = {
+	.keymap_data	= &cm_t35_keymap_data,
+	.rows		= 3,
+	.cols		= 3,
+	.rep		= 1,
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+	{
+		.mmc		= 1,
+		.wires		= 4,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+
+	},
+	{
+		.mmc		= 2,
+		.wires		= 4,
+		.transceiver	= 1,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+		.ocr_mask	= 0x00100000,	/* 3.3V */
+	},
+	{}	/* Terminator */
+};
+
+static struct ehci_hcd_omap_platform_data ehci_pdata = {
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = -EINVAL,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
+				 unsigned ngpio)
+{
+	int wlan_rst = gpio + 2;
+
+	if ((gpio_request(wlan_rst, "WLAN RST") == 0) &&
+	    (gpio_direction_output(wlan_rst, 1) == 0)) {
+		gpio_export(wlan_rst, 0);
+
+		udelay(10);
+		gpio_set_value(wlan_rst, 0);
+		udelay(10);
+		gpio_set_value(wlan_rst, 1);
+	} else {
+		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
+	}
+
+	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
+	mmc[0].gpio_cd = gpio + 0;
+	twl4030_mmc_init(mmc);
+
+	/* link regulators to MMC adapters */
+	cm_t35_vmmc1_supply.dev = mmc[0].dev;
+	cm_t35_vsim_supply.dev = mmc[0].dev;
+
+	/* setup USB with proper PHY reset GPIOs */
+	ehci_pdata.reset_gpio_port[0] = gpio + 6;
+	ehci_pdata.reset_gpio_port[1] = gpio + 7;
+
+	usb_ehci_init(&ehci_pdata);
+
+	return 0;
+}
+
+static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.setup          = cm_t35_twl_gpio_setup,
+};
+
+static struct twl4030_platform_data cm_t35_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.keypad		= &cm_t35_kp_data,
+	.usb		= &cm_t35_usb_data,
+	.gpio		= &cm_t35_gpio_data,
+	.vmmc1		= &cm_t35_vmmc1,
+	.vsim		= &cm_t35_vsim,
+};
+
+static struct i2c_board_info __initdata cm_t35_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("tps65930", 0x48),
+		.flags		= I2C_CLIENT_WAKE,
+		.irq		= INT_34XX_SYS_NIRQ,
+		.platform_data	= &cm_t35_twldata,
+	},
+};
+
+static void __init cm_t35_init_i2c(void)
+{
+	omap_register_i2c_bus(1, 2600, cm_t35_i2c_boardinfo,
+			      ARRAY_SIZE(cm_t35_i2c_boardinfo));
+}
+
+static struct omap_board_config_kernel cm_t35_config[] __initdata = {
+};
+
+static void __init cm_t35_init_irq(void)
+{
+	omap_board_config = cm_t35_config;
+	omap_board_config_size = ARRAY_SIZE(cm_t35_config);
+
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static void __init cm_t35_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+static struct omap_board_mux board_mux[] __initdata = {
+	/* nCS and IRQ for CM-T35 ethernet */
+	OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
+	OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+	/* nCS and IRQ for SB-T35 ethernet */
+	OMAP3_MUX(GPMC_NCS4, OMAP_MUX_MODE0),
+	OMAP3_MUX(GPMC_WAIT3, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+	/* PENDOWN GPIO */
+	OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+	/* mUSB */
+	OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+	/* MMC 2 */
+	OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+
+	/* McSPI 1 */
+	OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+
+	/* McSPI 4 */
+	OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
+
+	/* McBSP 2 */
+	OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+	/* serial ports */
+	OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+	OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+	/* DSS */
+	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),
+
+	/* TPS IRQ */
+	OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
+		  OMAP_PIN_INPUT_PULLUP),
+
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static void __init cm_t35_init(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+	omap_serial_init();
+	cm_t35_init_i2c();
+	cm_t35_init_nand();
+	cm_t35_init_ads7846();
+	cm_t35_init_ethernet();
+	cm_t35_init_led();
+
+	usb_musb_init();
+}
+
+MACHINE_START(CM_T35, "Compulab CM-T35")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= cm_t35_map_io,
+	.init_irq	= cm_t35_init_irq,
+	.init_machine	= cm_t35_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-generic.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-generic.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,10 +26,10 @@
 #include <asm/mach/map.h>
 
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
 
 static struct omap_board_config_kernel generic_config[] = {
 };
@@ -56,7 +56,7 @@ static void __init omap_generic_map_io(v
 MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
 	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_generic_map_io,
 	.init_irq	= omap_generic_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-h4.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-h4.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-h4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-h4.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,16 +31,16 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
-#include <mach/control.h>
+#include <plat/control.h>
 #include <mach/gpio.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/keypad.h>
-#include <mach/menelaus.h>
-#include <mach/dma.h>
-#include <mach/gpmc.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/keypad.h>
+#include <plat/menelaus.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
 
 #define H4_FLASH_CS	0
 #define H4_SMC91X_CS	1
@@ -376,7 +376,7 @@ static void __init omap_h4_map_io(void)
 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
 	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_h4_map_io,
 	.init_irq	= omap_h4_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-igep0020.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-igep0020.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-igep0020.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-igep0020.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2009 Integration Software and Electronic Engineering.
+ *
+ * Modified from mach-omap2/board-generic.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/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "mmc-twl4030.h"
+
+#define IGEP2_SMSC911X_CS       5
+#define IGEP2_SMSC911X_GPIO     176
+#define IGEP2_GPIO_USBH_NRESET  24
+#define IGEP2_GPIO_LED0_RED 	26
+#define IGEP2_GPIO_LED0_GREEN 	27
+#define IGEP2_GPIO_LED1_RED   	28
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct smsc911x_platform_config igep2_smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS  ,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource igep2_smsc911x_resources[] = {
+	{
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO),
+		.end	= OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct platform_device igep2_smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(igep2_smsc911x_resources),
+	.resource	= igep2_smsc911x_resources,
+	.dev		= {
+		.platform_data = &igep2_smsc911x_config,
+	},
+};
+
+static inline void __init igep2_init_smsc911x(void)
+{
+	unsigned long cs_mem_base;
+
+	if (gpmc_cs_request(IGEP2_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+		pr_err("IGEP v2: Failed request for GPMC mem for smsc911x\n");
+		gpmc_cs_free(IGEP2_SMSC911X_CS);
+		return;
+	}
+
+	igep2_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	igep2_smsc911x_resources[0].end   = cs_mem_base + 0xff;
+
+	if ((gpio_request(IGEP2_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+	    (gpio_direction_input(IGEP2_SMSC911X_GPIO) == 0)) {
+		gpio_export(IGEP2_SMSC911X_GPIO, 0);
+	} else {
+		pr_err("IGEP v2: Could not obtain gpio for for SMSC911X IRQ\n");
+		return;
+	}
+
+	platform_device_register(&igep2_smsc911x_device);
+}
+
+#else
+static inline void __init igep2_init_smsc911x(void) { }
+#endif
+
+static struct omap_board_config_kernel igep2_config[] __initdata = {
+};
+
+static struct regulator_consumer_supply igep2_vmmc1_supply = {
+	.supply		= "vmmc",
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data igep2_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &igep2_vmmc1_supply,
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+	{
+		.mmc		= 1,
+		.wires		= 4,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+	},
+	{
+		.mmc		= 2,
+		.wires		= 4,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+	},
+	{}      /* Terminator */
+};
+
+static int igep2_twl_gpio_setup(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
+	mmc[0].gpio_cd = gpio + 0;
+	twl4030_mmc_init(mmc);
+
+	/* link regulators to MMC adapters ... we "know" the
+	 * regulators will be set up only *after* we return.
+	*/
+	igep2_vmmc1_supply.dev = mmc[0].dev;
+
+	return 0;
+};
+
+static struct twl4030_gpio_platform_data igep2_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.use_leds	= false,
+	.setup		= igep2_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data igep2_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static void __init igep2_init_irq(void)
+{
+	omap_board_config = igep2_config;
+	omap_board_config_size = ARRAY_SIZE(igep2_config);
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static struct twl4030_platform_data igep2_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.usb		= &igep2_usb_data,
+	.gpio		= &igep2_gpio_data,
+	.vmmc1          = &igep2_vmmc1,
+
+};
+
+static struct i2c_board_info __initdata igep2_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("twl4030", 0x48),
+		.flags		= I2C_CLIENT_WAKE,
+		.irq		= INT_34XX_SYS_NIRQ,
+		.platform_data	= &igep2_twldata,
+	},
+};
+
+static int __init igep2_i2c_init(void)
+{
+	omap_register_i2c_bus(1, 2600, igep2_i2c_boardinfo,
+			ARRAY_SIZE(igep2_i2c_boardinfo));
+	/* 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, NULL, 0);
+	return 0;
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
+static void __init igep2_init(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	igep2_i2c_init();
+	omap_serial_init();
+	usb_musb_init();
+
+	igep2_init_smsc911x();
+
+	/* GPIO userspace leds */
+	if ((gpio_request(IGEP2_GPIO_LED0_RED, "GPIO_LED0_RED") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED0_RED, 0);
+		gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
+
+	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "GPIO_LED0_GREEN") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
+		gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
+
+	if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_LED1_RED") == 0) &&
+	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
+		gpio_export(IGEP2_GPIO_LED1_RED, 0);
+		gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
+	} else
+		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+}
+
+static void __init igep2_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+MACHINE_START(IGEP0020, "IGEP v2 board")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= igep2_map_io,
+	.init_irq	= igep2_init_irq,
+	.init_machine	= igep2_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-ldp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-ldp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-ldp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-ldp.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 
@@ -33,16 +33,17 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/mcspi.h>
+#include <plat/mcspi.h>
 #include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/gpmc.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
 
 #include <asm/delay.h>
-#include <mach/control.h>
-#include <mach/usb.h>
+#include <plat/control.h>
+#include <plat/usb.h>
 
+#include "mux.h"
 #include "mmc-twl4030.h"
 
 #define LDP_SMSC911X_CS		1
@@ -374,8 +375,17 @@ static struct platform_device *ldp_devic
 	&ldp_gpio_keys_device,
 };
 
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init omap_ldp_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_i2c_init();
 	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
 	ts_gpio = 54;
@@ -399,7 +409,7 @@ static void __init omap_ldp_map_io(void)
 
 MACHINE_START(OMAP_LDP, "OMAP LDP board")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_ldp_map_io,
 	.init_irq	= omap_ldp_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-n8x0.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-n8x0.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-n8x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-n8x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,12 +23,12 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/board.h>
+#include <plat/common.h>
 #include <mach/irqs.h>
-#include <mach/mcspi.h>
-#include <mach/onenand.h>
-#include <mach/serial.h>
+#include <plat/mcspi.h>
+#include <plat/onenand.h>
+#include <plat/serial.h>
 
 static struct omap2_mcspi_device_config p54spi_mcspi_config = {
 	.turbo_mode	= 0,
@@ -121,7 +121,7 @@ static void __init n8x0_init_machine(voi
 
 MACHINE_START(NOKIA_N800, "Nokia N800")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
 	.init_irq	= n8x0_init_irq,
@@ -131,7 +131,7 @@ MACHINE_END
 
 MACHINE_START(NOKIA_N810, "Nokia N810")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
 	.init_irq	= n8x0_init_irq,
@@ -141,7 +141,7 @@ MACHINE_END
 
 MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
 	.init_irq	= n8x0_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3beagle.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3beagle.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,7 @@
 #include <linux/mtd/nand.h>
 
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -37,14 +37,14 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/gpmc.h>
-#include <mach/nand.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/timer-gp.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <plat/timer-gp.h>
 
+#include "mux.h"
 #include "mmc-twl4030.h"
 
 #define GPMC_CS0_BASE  0x60
@@ -140,10 +140,10 @@ static int beagle_twl_gpio_setup(struct
 		unsigned gpio, unsigned ngpio)
 {
 	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
-		omap_cfg_reg(AG9_34XX_GPIO23);
+		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
 		mmc[0].gpio_wp = 23;
 	} else {
-		omap_cfg_reg(AH8_34XX_GPIO29);
+		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
 	}
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
@@ -254,6 +254,15 @@ static struct twl4030_usb_data beagle_us
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
 
+static struct twl4030_codec_audio_data beagle_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data beagle_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &beagle_audio_data,
+};
+
 static struct twl4030_platform_data beagle_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -261,6 +270,7 @@ static struct twl4030_platform_data beag
 	/* platform_data for children goes here */
 	.usb		= &beagle_usb_data,
 	.gpio		= &beagle_gpio_data,
+	.codec		= &beagle_codec_data,
 	.vmmc1		= &beagle_vmmc1,
 	.vsim		= &beagle_vsim,
 	.vdac		= &beagle_vdac,
@@ -400,24 +410,46 @@ static void __init omap3beagle_flash_ini
 	}
 }
 
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = 147,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init omap3_beagle_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3_beagle_i2c_init();
 	platform_add_devices(omap3_beagle_devices,
 			ARRAY_SIZE(omap3_beagle_devices));
 	omap_serial_init();
 
-	omap_cfg_reg(J25_34XX_GPIO170);
+	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
 	gpio_request(170, "DVI_nPD");
 	/* REVISIT leave DVI powered down until it's needed ... */
 	gpio_direction_output(170, true);
 
 	usb_musb_init();
+	usb_ehci_init(&ehci_pdata);
 	omap3beagle_flash_init();
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
-	omap_cfg_reg(H16_34XX_SDRC_CKE0);
-	omap_cfg_reg(H17_34XX_SDRC_CKE1);
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 }
 
 static void __init omap3_beagle_map_io(void)
@@ -429,7 +461,7 @@ static void __init omap3_beagle_map_io(v
 MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
 	/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_beagle_map_io,
 	.init_irq	= omap3_beagle_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3evm.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3evm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3evm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,34 +22,74 @@
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/leds.h>
+#include <linux/interrupt.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/usb/otg.h>
+#include <linux/smsc911x.h>
+
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/board.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/common.h>
-#include <mach/mcspi.h>
+#include <plat/board.h>
+#include <plat/usb.h>
+#include <plat/common.h>
+#include <plat/mcspi.h>
 
+#include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
 
 #define OMAP3_EVM_TS_GPIO	175
+#define OMAP3_EVM_EHCI_VBUS	22
+#define OMAP3_EVM_EHCI_SELECT	61
 
 #define OMAP3EVM_ETHR_START	0x2c000000
 #define OMAP3EVM_ETHR_SIZE	1024
+#define OMAP3EVM_ETHR_ID_REV	0x50
 #define OMAP3EVM_ETHR_GPIO_IRQ	176
-#define OMAP3EVM_SMC911X_CS	5
+#define OMAP3EVM_SMSC911X_CS	5
 
-static struct resource omap3evm_smc911x_resources[] = {
+static u8 omap3_evm_version;
+
+u8 get_omap3_evm_rev(void)
+{
+	return omap3_evm_version;
+}
+EXPORT_SYMBOL(get_omap3_evm_rev);
+
+static void __init omap3_evm_get_revision(void)
+{
+	void __iomem *ioaddr;
+	unsigned int smsc_id;
+
+	/* Ethernet PHY ID is stored at ID_REV register */
+	ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K);
+	if (!ioaddr)
+		return;
+	smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000;
+	iounmap(ioaddr);
+
+	switch (smsc_id) {
+	/*SMSC9115 chipset*/
+	case 0x01150000:
+		omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
+		break;
+	/*SMSC 9220 chipset*/
+	case 0x92200000:
+	default:
+		omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
+	}
+}
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource omap3evm_smsc911x_resources[] = {
 	[0] =	{
 		.start	= OMAP3EVM_ETHR_START,
 		.end	= (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
@@ -58,24 +98,34 @@ static struct resource omap3evm_smc911x_
 	[1] =	{
 		.start	= OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
 		.end	= OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
 	},
 };
 
-static struct platform_device omap3evm_smc911x_device = {
-	.name		= "smc911x",
+static struct smsc911x_platform_config smsc911x_config = {
+	.phy_interface  = PHY_INTERFACE_MODE_MII,
+	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type       = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags          = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
+};
+
+static struct platform_device omap3evm_smsc911x_device = {
+	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(omap3evm_smc911x_resources),
-	.resource	= &omap3evm_smc911x_resources[0],
+	.num_resources	= ARRAY_SIZE(omap3evm_smsc911x_resources),
+	.resource	= &omap3evm_smsc911x_resources[0],
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	},
 };
 
-static inline void __init omap3evm_init_smc911x(void)
+static inline void __init omap3evm_init_smsc911x(void)
 {
 	int eth_cs;
 	struct clk *l3ck;
 	unsigned int rate;
 
-	eth_cs = OMAP3EVM_SMC911X_CS;
+	eth_cs = OMAP3EVM_SMSC911X_CS;
 
 	l3ck = clk_get(NULL, "l3_ck");
 	if (IS_ERR(l3ck))
@@ -83,15 +133,58 @@ static inline void __init omap3evm_init_
 	else
 		rate = clk_get_rate(l3ck);
 
-	if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+	if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
 			OMAP3EVM_ETHR_GPIO_IRQ);
 		return;
 	}
 
 	gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
+	platform_device_register(&omap3evm_smsc911x_device);
 }
 
+#else
+static inline void __init omap3evm_init_smsc911x(void) { return; }
+#endif
+
+static struct regulator_consumer_supply omap3evm_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply omap3evm_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3evm_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &omap3evm_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3evm_vsim = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 3000000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &omap3evm_vsim_supply,
+};
+
 static struct twl4030_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
@@ -130,10 +223,14 @@ static int omap3evm_twl_gpio_setup(struc
 		unsigned gpio, unsigned ngpio)
 {
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	omap_cfg_reg(L8_34XX_GPIO63);
+	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	mmc[0].gpio_cd = gpio + 0;
 	twl4030_mmc_init(mmc);
 
+	/* link regulators to MMC adapters */
+	omap3evm_vmmc1_supply.dev = mmc[0].dev;
+	omap3evm_vsim_supply.dev = mmc[0].dev;
+
 	/*
 	 * Most GPIOs are for USB OTG.  Some are mostly sent to
 	 * the P2 connector; notably LEDA for the LCD backlight.
@@ -194,6 +291,15 @@ static struct twl4030_madc_platform_data
 	.irq_line	= 1,
 };
 
+static struct twl4030_codec_audio_data omap3evm_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data omap3evm_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &omap3evm_audio_data,
+};
+
 static struct twl4030_platform_data omap3evm_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -203,6 +309,7 @@ static struct twl4030_platform_data omap
 	.madc		= &omap3evm_madc_data,
 	.usb		= &omap3evm_usb_data,
 	.gpio		= &omap3evm_gpio_data,
+	.codec		= &omap3evm_codec_data,
 };
 
 static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
@@ -216,6 +323,13 @@ static struct i2c_board_info __initdata
 
 static int __init omap3_evm_i2c_init(void)
 {
+	/*
+	 * REVISIT: These entries can be set in omap3evm_twl_data
+	 * after a merge with MFD tree
+	 */
+	omap3evm_twldata.vmmc1 = &omap3evm_vmmc1;
+	omap3evm_twldata.vsim = &omap3evm_vsim;
+
 	omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
 			ARRAY_SIZE(omap3evm_i2c_boardinfo));
 	omap_register_i2c_bus(2, 400, NULL, 0);
@@ -289,16 +403,38 @@ static void __init omap3_evm_init_irq(vo
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
 	omap_init_irq();
 	omap_gpio_init();
-	omap3evm_init_smc911x();
 }
 
 static struct platform_device *omap3_evm_devices[] __initdata = {
 	&omap3_evm_lcd_device,
-	&omap3evm_smc911x_device,
 };
 
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	/* PHY reset GPIO will be runtime programmed based on EVM version */
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = -EINVAL,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init omap3_evm_init(void)
 {
+	omap3_evm_get_revision();
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
 	omap3_evm_i2c_init();
 
 	platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
@@ -311,8 +447,32 @@ static void __init omap3_evm_init(void)
 	/* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
 	usb_nop_xceiv_register();
 #endif
+	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
+		/* enable EHCI VBUS using GPIO22 */
+		omap_mux_init_gpio(22, OMAP_PIN_INPUT_PULLUP);
+		gpio_request(OMAP3_EVM_EHCI_VBUS, "enable EHCI VBUS");
+		gpio_direction_output(OMAP3_EVM_EHCI_VBUS, 0);
+		gpio_set_value(OMAP3_EVM_EHCI_VBUS, 1);
+
+		/* Select EHCI port on main board */
+		omap_mux_init_gpio(61, OMAP_PIN_INPUT_PULLUP);
+		gpio_request(OMAP3_EVM_EHCI_SELECT, "select EHCI port");
+		gpio_direction_output(OMAP3_EVM_EHCI_SELECT, 0);
+		gpio_set_value(OMAP3_EVM_EHCI_SELECT, 0);
+
+		/* setup EHCI phy reset config */
+		omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
+		ehci_pdata.reset_gpio_port[1] = 21;
+
+	} else {
+		/* setup EHCI phy reset on MDC */
+		omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
+		ehci_pdata.reset_gpio_port[1] = 135;
+	}
 	usb_musb_init();
+	usb_ehci_init(&ehci_pdata);
 	ads7846_dev_init();
+	omap3evm_init_smsc911x();
 }
 
 static void __init omap3_evm_map_io(void)
@@ -324,7 +484,7 @@ static void __init omap3_evm_map_io(void
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")
 	/* Maintainer: Syed Mohammed Khasim - Texas Instruments */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_evm_map_io,
 	.init_irq	= omap3_evm_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3pandora.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3pandora.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
@@ -34,14 +34,14 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/board.h>
+#include <plat/common.h>
 #include <mach/gpio.h>
 #include <mach/hardware.h>
-#include <mach/mcspi.h>
-#include <mach/usb.h>
-#include <mach/mux.h>
+#include <plat/mcspi.h>
+#include <plat/usb.h>
 
+#include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
 
@@ -98,10 +98,10 @@ static struct gpio_keys_button pandora_g
 	GPIO_BUTTON_LOW(103,	KEY_DOWN,	"down"),
 	GPIO_BUTTON_LOW(96,	KEY_LEFT,	"left"),
 	GPIO_BUTTON_LOW(98,	KEY_RIGHT,	"right"),
-	GPIO_BUTTON_LOW(111,	BTN_A,		"a"),
-	GPIO_BUTTON_LOW(106,	BTN_B,		"b"),
-	GPIO_BUTTON_LOW(109,	BTN_X,		"x"),
-	GPIO_BUTTON_LOW(101,	BTN_Y,		"y"),
+	GPIO_BUTTON_LOW(109,	KEY_KP1,	"game 1"),
+	GPIO_BUTTON_LOW(111,	KEY_KP2,	"game 2"),
+	GPIO_BUTTON_LOW(106,	KEY_KP3,	"game 3"),
+	GPIO_BUTTON_LOW(101,	KEY_KP4,	"game 4"),
 	GPIO_BUTTON_LOW(102,	BTN_TL,		"l"),
 	GPIO_BUTTON_LOW(97,	BTN_TL2,	"l2"),
 	GPIO_BUTTON_LOW(105,	BTN_TR,		"r"),
@@ -281,11 +281,21 @@ static struct twl4030_usb_data omap3pand
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
 
+static struct twl4030_codec_audio_data omap3pandora_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data omap3pandora_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &omap3pandora_audio_data,
+};
+
 static struct twl4030_platform_data omap3pandora_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
 	.gpio		= &omap3pandora_gpio_data,
 	.usb		= &omap3pandora_usb_data,
+	.codec		= &omap3pandora_codec_data,
 	.vmmc1		= &pandora_vmmc1,
 	.vmmc2		= &pandora_vmmc2,
 	.keypad		= &pandora_kp_data,
@@ -305,7 +315,7 @@ static int __init omap3pandora_i2c_init(
 	omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo,
 			ARRAY_SIZE(omap3pandora_i2c_boardinfo));
 	/* i2c2 pins are not connected */
-	omap_register_i2c_bus(3, 400, NULL, 0);
+	omap_register_i2c_bus(3, 100, NULL, 0);
 	return 0;
 }
 
@@ -358,23 +368,8 @@ static struct spi_board_info omap3pandor
 	}
 };
 
-static struct platform_device omap3pandora_lcd_device = {
-	.name		= "pandora_lcd",
-	.id		= -1,
-};
-
-static struct omap_lcd_config omap3pandora_lcd_config __initdata = {
-	.ctrl_name	= "internal",
-};
-
-static struct omap_board_config_kernel omap3pandora_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&omap3pandora_lcd_config },
-};
-
 static void __init omap3pandora_init_irq(void)
 {
-	omap_board_config = omap3pandora_config;
-	omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
@@ -382,13 +377,33 @@ static void __init omap3pandora_init_irq
 }
 
 static struct platform_device *omap3pandora_devices[] __initdata = {
-	&omap3pandora_lcd_device,
 	&pandora_leds_gpio,
 	&pandora_keys_gpio,
 };
 
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = 16,
+	.reset_gpio_port[1]  = -EINVAL,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init omap3pandora_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3pandora_i2c_init();
 	platform_add_devices(omap3pandora_devices,
 			ARRAY_SIZE(omap3pandora_devices));
@@ -396,12 +411,13 @@ static void __init omap3pandora_init(voi
 	spi_register_board_info(omap3pandora_spi_board_info,
 			ARRAY_SIZE(omap3pandora_spi_board_info));
 	omap3pandora_ads7846_init();
+	usb_ehci_init(&ehci_pdata);
 	pandora_keys_gpio_init();
 	usb_musb_init();
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
-	omap_cfg_reg(H16_34XX_SDRC_CKE0);
-	omap_cfg_reg(H17_34XX_SDRC_CKE1);
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 }
 
 static void __init omap3pandora_map_io(void)
@@ -412,7 +428,7 @@ static void __init omap3pandora_map_io(v
 
 MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3pandora_map_io,
 	.init_irq	= omap3pandora_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-omap3touchbook.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,572 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3touchbook.c
+ *
+ * Copyright (C) 2009 Always Innovating
+ *
+ * Modified from mach-omap2/board-omap3beagleboard.c
+ *
+ * Initial code: Grégoire Gentil, Tim Yamin
+ *
+ * This 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/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#include <linux/spi/ads7846.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <plat/timer-gp.h>
+
+#include "mux.h"
+#include "mmc-twl4030.h"
+
+#include <asm/setup.h>
+
+#define GPMC_CS0_BASE  0x60
+#define GPMC_CS_SIZE   0x30
+
+#define NAND_BLOCK_SIZE		SZ_128K
+
+#define OMAP3_AC_GPIO		136
+#define OMAP3_TS_GPIO		162
+#define TB_BL_PWM_TIMER		9
+#define TB_KILL_POWER_GPIO	168
+
+unsigned long touchbook_revision;
+
+static struct mtd_partition omap3touchbook_nand_partitions[] = {
+	/* All the partition sizes are listed in terms of NAND block size */
+	{
+		.name		= "X-Loader",
+		.offset		= 0,
+		.size		= 4 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "U-Boot",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x80000 */
+		.size		= 15 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "U-Boot Env",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x260000 */
+		.size		= 1 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name		= "Kernel",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
+		.size		= 32 * NAND_BLOCK_SIZE,
+	},
+	{
+		.name		= "File System",
+		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x680000 */
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct omap_nand_platform_data omap3touchbook_nand_data = {
+	.options	= NAND_BUSWIDTH_16,
+	.parts		= omap3touchbook_nand_partitions,
+	.nr_parts	= ARRAY_SIZE(omap3touchbook_nand_partitions),
+	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
+	.nand_setup	= NULL,
+	.dev_ready	= NULL,
+};
+
+static struct resource omap3touchbook_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device omap3touchbook_nand_device = {
+	.name		= "omap2-nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &omap3touchbook_nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &omap3touchbook_nand_resource,
+};
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct twl4030_hsmmc_info mmc[] = {
+	{
+		.mmc		= 1,
+		.wires		= 8,
+		.gpio_wp	= 29,
+	},
+	{}	/* Terminator */
+};
+
+static struct platform_device omap3_touchbook_lcd_device = {
+	.name		= "omap3touchbook_lcd",
+	.id		= -1,
+};
+
+static struct omap_lcd_config omap3_touchbook_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct regulator_consumer_supply touchbook_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply touchbook_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+static struct gpio_led gpio_leds[];
+
+static int touchbook_twl_gpio_setup(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+		mmc[0].gpio_wp = 23;
+	} else {
+		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+	}
+	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
+	mmc[0].gpio_cd = gpio + 0;
+	twl4030_mmc_init(mmc);
+
+	/* link regulators to MMC adapters */
+	touchbook_vmmc1_supply.dev = mmc[0].dev;
+	touchbook_vsim_supply.dev = mmc[0].dev;
+
+	/* REVISIT: need ehci-omap hooks for external VBUS
+	 * power switch and overcurrent detect
+	 */
+
+	gpio_request(gpio + 1, "EHCI_nOC");
+	gpio_direction_input(gpio + 1);
+
+	/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+	gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
+	gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+
+	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+	return 0;
+}
+
+static struct twl4030_gpio_platform_data touchbook_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.use_leds	= true,
+	.pullups	= BIT(1),
+	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+				| BIT(15) | BIT(16) | BIT(17),
+	.setup		= touchbook_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply touchbook_vdac_supply = {
+	.supply		= "vdac",
+	.dev		= &omap3_touchbook_lcd_device.dev,
+};
+
+static struct regulator_consumer_supply touchbook_vdvi_supply = {
+	.supply		= "vdvi",
+	.dev		= &omap3_touchbook_lcd_device.dev,
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data touchbook_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &touchbook_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data touchbook_vsim = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 3000000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &touchbook_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data touchbook_vdac = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &touchbook_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data touchbook_vpll2 = {
+	.constraints = {
+		.name			= "VDVI",
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &touchbook_vdvi_supply,
+};
+
+static struct twl4030_usb_data touchbook_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data touchbook_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data touchbook_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &touchbook_audio_data,
+};
+
+static struct twl4030_platform_data touchbook_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.usb		= &touchbook_usb_data,
+	.gpio		= &touchbook_gpio_data,
+	.codec		= &touchbook_codec_data,
+	.vmmc1		= &touchbook_vmmc1,
+	.vsim		= &touchbook_vsim,
+	.vdac		= &touchbook_vdac,
+	.vpll2		= &touchbook_vpll2,
+};
+
+static struct i2c_board_info __initdata touchbook_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("twl4030", 0x48),
+		.flags = I2C_CLIENT_WAKE,
+		.irq = INT_34XX_SYS_NIRQ,
+		.platform_data = &touchbook_twldata,
+	},
+};
+
+static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("bq27200", 0x55),
+	},
+};
+
+static int __init omap3_touchbook_i2c_init(void)
+{
+	/* Standard TouchBook bus */
+	omap_register_i2c_bus(1, 2600, touchbook_i2c_boardinfo,
+			ARRAY_SIZE(touchbook_i2c_boardinfo));
+
+	/* Additional TouchBook bus */
+	omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
+			ARRAY_SIZE(touchBook_i2c_boardinfo));
+
+	return 0;
+}
+
+static void __init omap3_ads7846_init(void)
+{
+	if (gpio_request(OMAP3_TS_GPIO, "ads7846_pen_down")) {
+		printk(KERN_ERR "Failed to request GPIO %d for "
+				"ads7846 pen down IRQ\n", OMAP3_TS_GPIO);
+		return;
+	}
+
+	gpio_direction_input(OMAP3_TS_GPIO);
+	omap_set_gpio_debounce(OMAP3_TS_GPIO, 1);
+	omap_set_gpio_debounce_time(OMAP3_TS_GPIO, 0xa);
+}
+
+static struct ads7846_platform_data ads7846_config = {
+	.x_min			= 100,
+	.y_min			= 265,
+	.x_max			= 3950,
+	.y_max			= 3750,
+	.x_plate_ohms		= 40,
+	.pressure_max		= 255,
+	.debounce_max		= 10,
+	.debounce_tol		= 5,
+	.debounce_rep		= 1,
+	.gpio_pendown		= OMAP3_TS_GPIO,
+	.keep_vref_on		= 1,
+};
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static struct spi_board_info omap3_ads7846_spi_board_info[] __initdata = {
+	{
+		.modalias		= "ads7846",
+		.bus_num		= 4,
+		.chip_select		= 0,
+		.max_speed_hz		= 1500000,
+		.controller_data	= &ads7846_mcspi_config,
+		.irq			= OMAP_GPIO_IRQ(OMAP3_TS_GPIO),
+		.platform_data		= &ads7846_config,
+	}
+};
+
+static struct gpio_led gpio_leds[] = {
+	{
+		.name			= "touchbook::usr0",
+		.default_trigger	= "heartbeat",
+		.gpio			= 150,
+	},
+	{
+		.name			= "touchbook::usr1",
+		.default_trigger	= "mmc0",
+		.gpio			= 149,
+	},
+	{
+		.name			= "touchbook::pmu_stat",
+		.gpio			= -EINVAL,	/* gets replaced */
+		.active_low		= true,
+	},
+};
+
+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 gpio_keys_button gpio_buttons[] = {
+	{
+		.code			= BTN_EXTRA,
+		.gpio			= 7,
+		.desc			= "user",
+		.wakeup			= 1,
+	},
+	{
+		.code			= KEY_POWER,
+		.gpio			= 183,
+		.desc			= "power",
+		.wakeup			= 1,
+	},
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+	.buttons	= gpio_buttons,
+	.nbuttons	= ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_key_info,
+	},
+};
+
+static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
+	{ OMAP_TAG_LCD,		&omap3_touchbook_lcd_config },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
+static void __init omap3_touchbook_init_irq(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_board_config = omap3_touchbook_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+	omap2_gp_clockevent_set_gptimer(12);
+#endif
+	omap_gpio_init();
+}
+
+static struct platform_device *omap3_touchbook_devices[] __initdata = {
+	&omap3_touchbook_lcd_device,
+	&leds_gpio,
+	&keys_gpio,
+};
+
+static void __init omap3touchbook_flash_init(void)
+{
+	u8 cs = 0;
+	u8 nandcs = GPMC_CS_NUM + 1;
+
+	u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+	/* find out the chip-select on which NAND exists */
+	while (cs < GPMC_CS_NUM) {
+		u32 ret = 0;
+		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+		if ((ret & 0xC00) == 0x800) {
+			printk(KERN_INFO "Found NAND on CS%d\n", cs);
+			if (nandcs > GPMC_CS_NUM)
+				nandcs = cs;
+		}
+		cs++;
+	}
+
+	if (nandcs > GPMC_CS_NUM) {
+		printk(KERN_INFO "NAND: Unable to find configuration "
+				 "in GPMC\n ");
+		return;
+	}
+
+	if (nandcs < GPMC_CS_NUM) {
+		omap3touchbook_nand_data.cs = nandcs;
+		omap3touchbook_nand_data.gpmc_cs_baseaddr = (void *)
+			(gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+		omap3touchbook_nand_data.gpmc_baseaddr =
+						(void *) (gpmc_base_add);
+
+		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+		if (platform_device_register(&omap3touchbook_nand_device) < 0)
+			printk(KERN_ERR "Unable to register NAND device\n");
+	}
+}
+
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = 147,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+static void omap3_touchbook_poweroff(void)
+{
+	int r;
+
+	r = gpio_request(TB_KILL_POWER_GPIO, "DVI reset");
+	if (r < 0) {
+		printk(KERN_ERR "Unable to get kill power GPIO\n");
+		return;
+	}
+
+	gpio_direction_output(TB_KILL_POWER_GPIO, 0);
+}
+
+static void __init early_touchbook_revision(char **p)
+{
+	if (!*p)
+		return;
+
+	strict_strtoul(*p, 10, &touchbook_revision);
+}
+__early_param("tbr=", early_touchbook_revision);
+
+static void __init omap3_touchbook_init(void)
+{
+	pm_power_off = omap3_touchbook_poweroff;
+
+	omap3_touchbook_i2c_init();
+	platform_add_devices(omap3_touchbook_devices,
+			ARRAY_SIZE(omap3_touchbook_devices));
+	omap_serial_init();
+
+	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
+	gpio_request(176, "DVI_nPD");
+	/* REVISIT leave DVI powered down until it's needed ... */
+	gpio_direction_output(176, true);
+
+	/* Touchscreen and accelerometer */
+	spi_register_board_info(omap3_ads7846_spi_board_info,
+				ARRAY_SIZE(omap3_ads7846_spi_board_info));
+	omap3_ads7846_init();
+	usb_musb_init();
+	usb_ehci_init(&ehci_pdata);
+	omap3touchbook_flash_init();
+
+	/* Ensure SDRC pins are mux'd for self-refresh */
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+static void __init omap3_touchbook_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
+	/* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap3_touchbook_map_io,
+	.init_irq	= omap3_touchbook_init_irq,
+	.init_machine	= omap3_touchbook_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-overo.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-overo.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-overo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-overo.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 
 #include <linux/mtd/mtd.h>
@@ -38,15 +38,15 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/board.h>
-#include <mach/common.h>
+#include <plat/board.h>
+#include <plat/common.h>
 #include <mach/gpio.h>
-#include <mach/gpmc.h>
+#include <plat/gpmc.h>
 #include <mach/hardware.h>
-#include <mach/nand.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
 
+#include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
 
@@ -67,7 +67,7 @@
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
 	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 
-#include <mach/mcspi.h>
+#include <plat/mcspi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
@@ -329,6 +329,15 @@ static struct regulator_init_data overo_
 	.consumer_supplies	= &overo_vmmc1_supply,
 };
 
+static struct twl4030_codec_audio_data overo_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data overo_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &overo_audio_data,
+};
+
 /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
 
 static struct twl4030_platform_data overo_twldata = {
@@ -336,6 +345,7 @@ static struct twl4030_platform_data over
 	.irq_end	= TWL4030_IRQ_END,
 	.gpio		= &overo_gpio_data,
 	.usb		= &overo_usb_data,
+	.codec		= &overo_codec_data,
 	.vmmc1		= &overo_vmmc1,
 };
 
@@ -384,19 +394,40 @@ static struct platform_device *overo_dev
 	&overo_lcd_device,
 };
 
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+	.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+	.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+	.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+	.phy_reset  = true,
+	.reset_gpio_port[0]  = -EINVAL,
+	.reset_gpio_port[1]  = OVERO_GPIO_USBH_NRESET,
+	.reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init overo_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	overo_i2c_init();
 	platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
 	omap_serial_init();
 	overo_flash_init();
 	usb_musb_init();
+	usb_ehci_init(&ehci_pdata);
 	overo_ads7846_init();
 	overo_init_smsc911x();
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
-	omap_cfg_reg(H16_34XX_SDRC_CKE0);
-	omap_cfg_reg(H17_34XX_SDRC_CKE1);
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 
 	if ((gpio_request(OVERO_GPIO_W2W_NRESET,
 			  "OVERO_GPIO_W2W_NRESET") == 0) &&
@@ -433,14 +464,6 @@ static void __init overo_init(void)
 	else
 		printk(KERN_ERR "could not obtain gpio for "
 					"OVERO_GPIO_USBH_CPEN\n");
-
-	if ((gpio_request(OVERO_GPIO_USBH_NRESET,
-			  "OVERO_GPIO_USBH_NRESET") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_USBH_NRESET, 1) == 0))
-		gpio_export(OVERO_GPIO_USBH_NRESET, 0);
-	else
-		printk(KERN_ERR "could not obtain gpio for "
-					"OVERO_GPIO_USBH_NRESET\n");
 }
 
 static void __init overo_map_io(void)
@@ -451,7 +474,7 @@ static void __init overo_map_io(void)
 
 MACHINE_START(OVERO, "Gumstix Overo")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= overo_map_io,
 	.init_irq	= overo_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,13 +22,16 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/mcspi.h>
-#include <mach/mux.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/dma.h>
-#include <mach/gpmc.h>
-#include <mach/usb.h>
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+
+struct omap_sdrc_params *rx51_get_sdram_timings(void);
 
 static struct omap_lcd_config rx51_lcd_config = {
 	.ctrl_name	= "internal",
@@ -55,24 +58,36 @@ static struct omap_board_config_kernel r
 
 static void __init rx51_init_irq(void)
 {
+	struct omap_sdrc_params *sdrc_params;
+
 	omap_board_config = rx51_config;
 	omap_board_config_size = ARRAY_SIZE(rx51_config);
-	omap2_init_common_hw(NULL, NULL);
+	sdrc_params = rx51_get_sdram_timings();
+	omap2_init_common_hw(sdrc_params, sdrc_params);
 	omap_init_irq();
 	omap_gpio_init();
 }
 
 extern void __init rx51_peripherals_init(void);
 
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
 static void __init rx51_init(void)
 {
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_serial_init();
 	usb_musb_init();
 	rx51_peripherals_init();
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
-	omap_cfg_reg(H16_34XX_SDRC_CKE0);
-	omap_cfg_reg(H17_34XX_SDRC_CKE1);
+	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 }
 
 static void __init rx51_map_io(void)
@@ -84,7 +99,7 @@ static void __init rx51_map_io(void)
 MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
 	/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
 	.init_irq	= rx51_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,28 +14,138 @@
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/wl12xx.h>
 #include <linux/i2c.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
+#include <linux/gpio_keys.h>
 #include <linux/mmc/host.h>
 
-#include <mach/mcspi.h>
-#include <mach/mux.h>
-#include <mach/board.h>
-#include <mach/common.h>
-#include <mach/dma.h>
-#include <mach/gpmc.h>
-#include <mach/onenand.h>
-#include <mach/gpmc-smc91x.h>
+#include <plat/mcspi.h>
+#include <plat/mux.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/onenand.h>
+#include <plat/gpmc-smc91x.h>
 
+#include "mux.h"
 #include "mmc-twl4030.h"
 
 #define SYSTEM_REV_B_USES_VAUX3	0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
 
+#define RX51_WL1251_POWER_GPIO		87
+#define RX51_WL1251_IRQ_GPIO		42
+
+/* list all spi devices here */
+enum {
+	RX51_SPI_WL1251,
+};
+
+static struct wl12xx_platform_data wl1251_pdata;
+
+static struct omap2_mcspi_device_config wl1251_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,
+};
+
+static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
+	[RX51_SPI_WL1251] = {
+		.modalias		= "wl1251",
+		.bus_num		= 4,
+		.chip_select		= 0,
+		.max_speed_hz   	= 48000000,
+		.mode                   = SPI_MODE_3,
+		.controller_data	= &wl1251_mcspi_config,
+		.platform_data		= &wl1251_pdata,
+	},
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+
+#define RX51_GPIO_CAMERA_LENS_COVER	110
+#define RX51_GPIO_CAMERA_FOCUS		68
+#define RX51_GPIO_CAMERA_CAPTURE	69
+#define RX51_GPIO_KEYPAD_SLIDE		71
+#define RX51_GPIO_LOCK_BUTTON		113
+#define RX51_GPIO_PROXIMITY		89
+
+#define RX51_GPIO_DEBOUNCE_TIMEOUT	10
+
+static struct gpio_keys_button rx51_gpio_keys[] = {
+	{
+		.desc			= "Camera Lens Cover",
+		.type			= EV_SW,
+		.code			= SW_CAMERA_LENS_COVER,
+		.gpio			= RX51_GPIO_CAMERA_LENS_COVER,
+		.active_low		= 1,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}, {
+		.desc			= "Camera Focus",
+		.type			= EV_KEY,
+		.code			= KEY_CAMERA_FOCUS,
+		.gpio			= RX51_GPIO_CAMERA_FOCUS,
+		.active_low		= 1,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}, {
+		.desc			= "Camera Capture",
+		.type			= EV_KEY,
+		.code			= KEY_CAMERA,
+		.gpio			= RX51_GPIO_CAMERA_CAPTURE,
+		.active_low		= 1,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}, {
+		.desc			= "Lock Button",
+		.type			= EV_KEY,
+		.code			= KEY_SCREENLOCK,
+		.gpio			= RX51_GPIO_LOCK_BUTTON,
+		.active_low		= 1,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}, {
+		.desc			= "Keypad Slide",
+		.type			= EV_SW,
+		.code			= SW_KEYPAD_SLIDE,
+		.gpio			= RX51_GPIO_KEYPAD_SLIDE,
+		.active_low		= 1,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}, {
+		.desc			= "Proximity Sensor",
+		.type			= EV_SW,
+		.code			= SW_FRONT_PROXIMITY,
+		.gpio			= RX51_GPIO_PROXIMITY,
+		.active_low		= 0,
+		.debounce_interval	= RX51_GPIO_DEBOUNCE_TIMEOUT,
+	}
+};
+
+static struct gpio_keys_platform_data rx51_gpio_keys_data = {
+	.buttons	= rx51_gpio_keys,
+	.nbuttons	= ARRAY_SIZE(rx51_gpio_keys),
+};
+
+static struct platform_device rx51_gpio_keys_device = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &rx51_gpio_keys_data,
+	},
+};
+
+static void __init rx51_add_gpio_keys(void)
+{
+	platform_device_register(&rx51_gpio_keys_device);
+}
+#else
+static void __init rx51_add_gpio_keys(void)
+{
+}
+#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */
+
 static int board_keymap[] = {
 	KEY(0, 0, KEY_Q),
 	KEY(0, 1, KEY_O),
@@ -292,15 +402,9 @@ static struct twl4030_usb_data rx51_usb_
 
 static struct twl4030_ins sleep_on_seq[] __initdata = {
 /*
- * Turn off VDD1 and VDD2.
- */
-	{MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4},
-	{MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2},
-/*
- * And also turn off the OMAP3 PLLs and the sysclk output.
+ * Turn off everything
  */
-	{MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3},
-	{MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_OFF), 3},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_SLEEP), 2},
 };
 
 static struct twl4030_script sleep_on_script __initdata = {
@@ -311,14 +415,9 @@ static struct twl4030_script sleep_on_sc
 
 static struct twl4030_ins wakeup_seq[] __initdata = {
 /*
- * Reenable the OMAP3 PLLs.
- * Wakeup VDD1 and VDD2.
- * Reenable sysclk output.
+ * Reenable everything
  */
-	{MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30},
-	{MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30},
-	{MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37},
-	{MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
 };
 
 static struct twl4030_script wakeup_script __initdata = {
@@ -329,10 +428,9 @@ static struct twl4030_script wakeup_scri
 
 static struct twl4030_ins wakeup_p3_seq[] __initdata = {
 /*
- * Wakeup VDD1 (dummy to be able to insert a delay)
- * Enable CLKEN
+ * Reenable everything
  */
-	{MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_ACTIVE), 3},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
 };
 
 static struct twl4030_script wakeup_p3_script __initdata = {
@@ -353,12 +451,11 @@ static struct twl4030_ins wrst_seq[] __i
 	{MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
 	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE),
 		0x13},
-	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 2, RES_STATE_WRST), 0x13},
 	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13},
 	{MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13},
 	{MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13},
 	{MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35},
-	{MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
+	{MSG_SINGULAR(DEV_GRP_P3, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
 	{MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
 };
 
@@ -380,22 +477,81 @@ static struct twl4030_script *twl4030_sc
 };
 
 static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
-	{ .resource = RES_VINTANA1, .devgroup = -1, .type = -1, .type2 = 1 },
-	{ .resource = RES_VINTANA2, .devgroup = -1, .type = -1, .type2 = 1 },
-	{ .resource = RES_VINTDIG, .devgroup = -1, .type = -1, .type2 = 1 },
-	{ .resource = RES_VMMC1, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VMMC2, .devgroup = DEV_GRP_NULL, .type = -1,
-	  .type2 = 3},
-	{ .resource = RES_VAUX1, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VAUX2, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VAUX3, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VAUX4, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VPLL2, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VDAC, .devgroup = -1, .type = -1, .type2 = 3},
-	{ .resource = RES_VSIM, .devgroup = DEV_GRP_NULL, .type = -1,
-	  .type2 = 3},
-	{ .resource = RES_CLKEN, .devgroup = DEV_GRP_P3, .type = -1,
-		.type2 = 1 },
+	{ .resource = RES_VDD1, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+	  .remap_sleep = RES_STATE_OFF
+	},
+	{ .resource = RES_VDD2, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+	  .remap_sleep = RES_STATE_OFF
+	},
+	{ .resource = RES_VPLL1, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+	  .remap_sleep = RES_STATE_OFF
+	},
+	{ .resource = RES_VPLL2, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VAUX1, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VAUX2, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VAUX3, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VAUX4, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VMMC1, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VMMC2, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VDAC, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VSIM, .devgroup = -1,
+	  .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VINTANA1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VINTANA2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VINTDIG, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_VIO, .devgroup = DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_CLKEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = 1, .type2 = -1 , .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_REGEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_SYSEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_32KCLKOUT, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_RESET, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
+	{ .resource = RES_Main_Ref, .devgroup = -1,
+	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+	},
 	{ 0, 0},
 };
 
@@ -521,9 +677,9 @@ static struct omap_smc91x_platform_data
 
 static void __init board_smc91x_init(void)
 {
-	omap_cfg_reg(U8_34XX_GPIO54_DOWN);
-	omap_cfg_reg(G25_34XX_GPIO86_OUT);
-	omap_cfg_reg(H19_34XX_GPIO164_OUT);
+	omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN);
+	omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
+	omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
 
 	gpmc_smc91x_init(&board_smc91x_data);
 }
@@ -536,10 +692,64 @@ static inline void board_smc91x_init(voi
 
 #endif
 
+static void rx51_wl1251_set_power(bool enable)
+{
+	gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
+}
+
+static void __init rx51_init_wl1251(void)
+{
+	int irq, ret;
+
+	ret = gpio_request(RX51_WL1251_POWER_GPIO, "wl1251 power");
+	if (ret < 0)
+		goto error;
+
+	ret = gpio_direction_output(RX51_WL1251_POWER_GPIO, 0);
+	if (ret < 0)
+		goto err_power;
+
+	ret = gpio_request(RX51_WL1251_IRQ_GPIO, "wl1251 irq");
+	if (ret < 0)
+		goto err_power;
+
+	ret = gpio_direction_input(RX51_WL1251_IRQ_GPIO);
+	if (ret < 0)
+		goto err_irq;
+
+	irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO);
+	if (irq < 0)
+		goto err_irq;
+
+	wl1251_pdata.set_power = rx51_wl1251_set_power;
+	rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
+
+	return;
+
+err_irq:
+	gpio_free(RX51_WL1251_IRQ_GPIO);
+
+err_power:
+	gpio_free(RX51_WL1251_POWER_GPIO);
+
+error:
+	printk(KERN_ERR "wl1251 board initialisation failed\n");
+	wl1251_pdata.set_power = NULL;
+
+	/*
+	 * Now rx51_peripherals_spi_board_info[1].irq is zero and
+	 * set_power is null, and wl1251_probe() will fail.
+	 */
+}
+
 void __init rx51_peripherals_init(void)
 {
 	rx51_i2c_init();
 	board_onenand_init();
 	board_smc91x_init();
+	rx51_add_gpio_keys();
+	rx51_init_wl1251();
+	spi_register_board_info(rx51_peripherals_spi_board_info,
+				ARRAY_SIZE(rx51_peripherals_spi_board_info));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51-sdram.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-sdram.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-rx51-sdram.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-rx51-sdram.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,221 @@
+/*
+ * SDRC register values for RX51
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * Original code by Juha Yrjola <juha.yrjola@solidboot.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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/io.h>
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sdrc.h>
+
+
+/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */
+struct sdram_timings {
+	u32 casl;
+	u32 tDAL;
+	u32 tDPL;
+	u32 tRRD;
+	u32 tRCD;
+	u32 tRP;
+	u32 tRAS;
+	u32 tRC;
+	u32 tRFC;
+	u32 tXSR;
+
+	u32 tREF; /* in ns */
+
+	u32 tXP;
+	u32 tCKE;
+	u32 tWTR;
+};
+
+struct omap_sdrc_params rx51_sdrc_params[4];
+
+static const struct sdram_timings rx51_timings[] = {
+	{
+		.casl = 3,
+		.tDAL = 33000,
+		.tDPL = 15000,
+		.tRRD = 12000,
+		.tRCD = 22500,
+		.tRP = 18000,
+		.tRAS = 42000,
+		.tRC = 66000,
+		.tRFC = 138000,
+		.tXSR = 200000,
+
+		.tREF = 7800,
+
+		.tXP = 2,
+		.tCKE = 2,
+		.tWTR = 2
+	},
+};
+
+static unsigned long sdrc_get_fclk_period(long rate)
+{
+	/* In picoseconds */
+	return 1000000000 / rate;
+}
+
+static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate)
+{
+	unsigned long tick_ps;
+
+	/* Calculate in picosecs to yield more exact results */
+	tick_ps = sdrc_get_fclk_period(rate);
+
+	return (time_ps + tick_ps - 1) / tick_ps;
+}
+#undef DEBUG
+#ifdef DEBUG
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+				int ticks, long rate, const char *name)
+#else
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+			       int ticks)
+#endif
+{
+	int mask, nr_bits;
+
+	nr_bits = end_bit - st_bit + 1;
+	if (ticks >= 1 << nr_bits)
+		return -1;
+	mask = (1 << nr_bits) - 1;
+	*regval &= ~(mask << st_bit);
+	*regval |= ticks << st_bit;
+#ifdef DEBUG
+	printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks,
+			(unsigned int)sdrc_get_fclk_period(rate) * ticks /
+			1000);
+#endif
+
+	return 0;
+}
+
+#ifdef DEBUG
+#define SDRC_SET_ONE(reg, st, end, field, rate) \
+	if (set_sdrc_timing_regval((reg), (st), (end), \
+			rx51_timings->field, (rate), #field) < 0) \
+		err = -1;
+#else
+#define SDRC_SET_ONE(reg, st, end, field, rate) \
+	if (set_sdrc_timing_regval((reg), (st), (end), \
+			rx51_timings->field) < 0) \
+		err = -1;
+#endif
+
+#ifdef DEBUG
+static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
+				int time, long rate, const char *name)
+#else
+static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
+				int time, long rate)
+#endif
+{
+	int ticks, ret;
+	ret = 0;
+
+	if (time == 0)
+		ticks = 0;
+	else
+		ticks = sdrc_ps_to_ticks(time, rate);
+
+#ifdef DEBUG
+	ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks,
+				     rate, name);
+#else
+	ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks);
+#endif
+
+	return ret;
+}
+
+#ifdef DEBUG
+#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
+	if (set_sdrc_timing_regval_ps((reg), (st), (end), \
+			rx51_timings->field, \
+			(rate), #field) < 0) \
+		err = -1;
+
+#else
+#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
+	if (set_sdrc_timing_regval_ps((reg), (st), (end), \
+			rx51_timings->field, (rate)) < 0) \
+		err = -1;
+#endif
+
+static int sdrc_timings(int id, long rate)
+{
+	u32 ticks_per_ms;
+	u32 rfr, l;
+	u32 actim_ctrla = 0, actim_ctrlb = 0;
+	u32 rfr_ctrl;
+	int err = 0;
+	long l3_rate = rate / 1000;
+
+	SDRC_SET_ONE_PS(&actim_ctrla,  0,  4, tDAL, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla,  6,  8, tDPL, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla,  9, 11, tRRD, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate);
+	SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate);
+
+	SDRC_SET_ONE_PS(&actim_ctrlb,  0,  7, tXSR, l3_rate);
+
+	SDRC_SET_ONE(&actim_ctrlb,  8, 10, tXP, l3_rate);
+	SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate);
+	SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate);
+
+	ticks_per_ms = l3_rate;
+	rfr = rx51_timings[0].tREF * ticks_per_ms / 1000000;
+	if (rfr > 65535 + 50)
+		rfr = 65535;
+	else
+		rfr -= 50;
+
+#ifdef DEBUG
+	printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr);
+#endif
+
+	l = rfr << 8;
+	rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */
+
+	rx51_sdrc_params[id].rate = rate;
+	rx51_sdrc_params[id].actim_ctrla = actim_ctrla;
+	rx51_sdrc_params[id].actim_ctrlb = actim_ctrlb;
+	rx51_sdrc_params[id].rfr_ctrl = rfr_ctrl;
+	rx51_sdrc_params[id].mr = 0x32;
+
+	rx51_sdrc_params[id + 1].rate = 0;
+
+	return err;
+}
+
+struct omap_sdrc_params *rx51_get_sdram_timings(void)
+{
+	int err;
+
+	err = sdrc_timings(0, 41500000);
+	err |= sdrc_timings(1, 83000000);
+	err |= sdrc_timings(2, 166000000);
+
+	return &rx51_sdrc_params[0];
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom2.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom2.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,223 +13,43 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/input/matrix_keypad.h>
 #include <linux/gpio.h>
-#include <linux/i2c/twl4030.h>
-#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/common.h>
-#include <mach/usb.h>
-
-#include "mmc-twl4030.h"
-#include "sdram-micron-mt46h32m32lf-6.h"
-
-/* Zoom2 has Qwerty keyboard*/
-static int board_keymap[] = {
-	KEY(0, 0, KEY_E),
-	KEY(0, 1, KEY_R),
-	KEY(0, 2, KEY_T),
-	KEY(0, 3, KEY_HOME),
-	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, 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, 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, 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, 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, 5, KEY_VOLUMEDOWN),
-	KEY(5, 6, KEY_M),
-	KEY(5, 7, KEY_ENTER),
-	KEY(6, 0, KEY_Q),
-	KEY(6, 1, KEY_A),
-	KEY(6, 2, KEY_N),
-	KEY(6, 3, KEY_BACKSPACE),
-	KEY(6, 6, KEY_P),
-	KEY(6, 7, KEY_SELECT),
-	KEY(7, 0, KEY_PROG1),	/*MACRO 1 <User defined> */
-	KEY(7, 1, KEY_PROG2),	/*MACRO 2 <User defined> */
-	KEY(7, 2, KEY_PROG3),	/*MACRO 3 <User defined> */
-	KEY(7, 3, KEY_PROG4),	/*MACRO 4 <User defined> */
-	KEY(7, 5, KEY_RIGHT),
-	KEY(7, 6, KEY_UP),
-	KEY(7, 7, KEY_DOWN)
-};
-
-static struct matrix_keymap_data board_map_data = {
-	.keymap			= board_keymap,
-	.keymap_size		= ARRAY_SIZE(board_keymap),
-};
-
-static struct twl4030_keypad_data zoom2_kp_twl4030_data = {
-	.keymap_data	= &board_map_data,
-	.rows		= 8,
-	.cols		= 8,
-	.rep		= 1,
-};
-
-static struct omap_board_config_kernel zoom2_config[] __initdata = {
-};
-
-static struct regulator_consumer_supply zoom2_vmmc1_supply = {
-	.supply		= "vmmc",
-};
-
-static struct regulator_consumer_supply zoom2_vsim_supply = {
-	.supply		= "vmmc_aux",
-};
-
-static struct regulator_consumer_supply zoom2_vmmc2_supply = {
-	.supply		= "vmmc",
-};
-
-/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
-static struct regulator_init_data zoom2_vmmc1 = {
-	.constraints = {
-		.min_uV			= 1850000,
-		.max_uV			= 3150000,
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
-					| REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies  = 1,
-	.consumer_supplies      = &zoom2_vmmc1_supply,
-};
-
-/* VMMC2 for MMC2 card */
-static struct regulator_init_data zoom2_vmmc2 = {
-	.constraints = {
-		.min_uV			= 1850000,
-		.max_uV			= 1850000,
-		.apply_uV		= true,
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-		.valid_ops_mask		= REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies  = 1,
-	.consumer_supplies      = &zoom2_vmmc2_supply,
-};
-
-/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
-static struct regulator_init_data zoom2_vsim = {
-	.constraints = {
-		.min_uV			= 1800000,
-		.max_uV			= 3000000,
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
-					| REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies  = 1,
-	.consumer_supplies      = &zoom2_vsim_supply,
-};
-
-static struct twl4030_hsmmc_info mmc[] __initdata = {
-	{
-		.mmc		= 1,
-		.wires		= 4,
-		.gpio_wp	= -EINVAL,
-	},
-	{
-		.mmc		= 2,
-		.wires		= 4,
-		.gpio_wp	= -EINVAL,
-	},
-	{}      /* Terminator */
-};
-
-static int zoom2_twl_gpio_setup(struct device *dev,
-		unsigned gpio, unsigned ngpio)
-{
-	/* gpio + 0 is "mmc0_cd" (input/IRQ),
-	 * gpio + 1 is "mmc1_cd" (input/IRQ)
-	 */
-	mmc[0].gpio_cd = gpio + 0;
-	mmc[1].gpio_cd = gpio + 1;
-	twl4030_mmc_init(mmc);
-
-	/* link regulators to MMC adapters ... we "know" the
-	 * regulators will be set up only *after* we return.
-	*/
-	zoom2_vmmc1_supply.dev = mmc[0].dev;
-	zoom2_vsim_supply.dev = mmc[0].dev;
-	zoom2_vmmc2_supply.dev = mmc[1].dev;
-
-	return 0;
-}
-
-
-static int zoom2_batt_table[] = {
-/* 0 C*/
-30800, 29500, 28300, 27100,
-26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
-17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
-11600, 11200, 10800, 10400, 10000, 9630,  9280,  8950,  8620,  8310,
-8020,  7730,  7460,  7200,  6950,  6710,  6470,  6250,  6040,  5830,
-5640,  5450,  5260,  5090,  4920,  4760,  4600,  4450,  4310,  4170,
-4040,  3910,  3790,  3670,  3550
-};
+#include <plat/common.h>
+#include <plat/board.h>
 
-static struct twl4030_bci_platform_data zoom2_bci_data = {
-	.battery_tmp_tbl	= zoom2_batt_table,
-	.tblsize		= ARRAY_SIZE(zoom2_batt_table),
-};
+#include <mach/board-zoom.h>
 
-static struct twl4030_usb_data zoom2_usb_data = {
-	.usb_mode	= T2_USB_MODE_ULPI,
-};
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
 
 static void __init omap_zoom2_init_irq(void)
 {
-	omap_board_config = zoom2_config;
-	omap_board_config_size = ARRAY_SIZE(zoom2_config);
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 				 mt46h32m32lf6_sdrc_params);
 	omap_init_irq();
 	omap_gpio_init();
 }
 
-static struct twl4030_gpio_platform_data zoom2_gpio_data = {
-	.gpio_base	= OMAP_MAX_GPIO_LINES,
-	.irq_base	= TWL4030_GPIO_IRQ_BASE,
-	.irq_end	= TWL4030_GPIO_IRQ_END,
-	.setup		= zoom2_twl_gpio_setup,
-};
+/* REVISIT: These audio entries can be removed once MFD code is merged */
+#if 0
 
 static struct twl4030_madc_platform_data zoom2_madc_data = {
 	.irq_line	= 1,
 };
 
+static struct twl4030_codec_audio_data zoom2_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data zoom2_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &zoom2_audio_data,
+};
+
 static struct twl4030_platform_data zoom2_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -240,38 +60,28 @@ static struct twl4030_platform_data zoom
 	.usb		= &zoom2_usb_data,
 	.gpio		= &zoom2_gpio_data,
 	.keypad		= &zoom2_kp_twl4030_data,
+	.codec		= &zoom2_codec_data,
 	.vmmc1          = &zoom2_vmmc1,
 	.vmmc2          = &zoom2_vmmc2,
 	.vsim           = &zoom2_vsim,
 
 };
 
-static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &zoom2_twldata,
-	},
-};
-
-static int __init omap_i2c_init(void)
-{
-	omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
-			ARRAY_SIZE(zoom2_i2c_boardinfo));
-	omap_register_i2c_bus(2, 400, NULL, 0);
-	omap_register_i2c_bus(3, 400, NULL, 0);
-	return 0;
-}
+#endif
 
-extern int __init omap_zoom2_debugboard_init(void);
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
 
 static void __init omap_zoom2_init(void)
 {
-	omap_i2c_init();
-	omap_serial_init();
-	omap_zoom2_debugboard_init();
-	usb_musb_init();
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	zoom_peripherals_init();
+	zoom_debugboard_init();
 }
 
 static void __init omap_zoom2_map_io(void)
@@ -282,7 +92,7 @@ static void __init omap_zoom2_map_io(voi
 
 MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
 	.phys_io	= 0x48000000,
-	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom2_map_io,
 	.init_irq	= omap_zoom2_init_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom3.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom3.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom3.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board-zoom.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+
+#include "mux.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+static void __init omap_zoom_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+static struct omap_board_config_kernel zoom_config[] __initdata = {
+};
+
+static void __init omap_zoom_init_irq(void)
+{
+	omap_board_config = zoom_config;
+	omap_board_config_size = ARRAY_SIZE(zoom_config);
+	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,
+			h8mbx00u0mer0em_sdrc_params);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux	NULL
+#endif
+
+static void __init omap_zoom_init(void)
+{
+	omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+	zoom_peripherals_init();
+	zoom_debugboard_init();
+}
+
+MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_zoom_map_io,
+	.init_irq	= omap_zoom_init_irq,
+	.init_machine	= omap_zoom_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-debugboard.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,20 +14,20 @@
 #include <linux/smsc911x.h>
 #include <linux/interrupt.h>
 
-#include <mach/gpmc.h>
+#include <plat/gpmc.h>
 
-#define ZOOM2_SMSC911X_CS	7
-#define ZOOM2_SMSC911X_GPIO	158
-#define ZOOM2_QUADUART_CS	3
-#define ZOOM2_QUADUART_GPIO	102
+#define ZOOM_SMSC911X_CS	7
+#define ZOOM_SMSC911X_GPIO	158
+#define ZOOM_QUADUART_CS	3
+#define ZOOM_QUADUART_GPIO	102
 #define QUART_CLK		1843200
 #define DEBUG_BASE		0x08000000
-#define ZOOM2_ETHR_START	DEBUG_BASE
+#define ZOOM_ETHR_START	DEBUG_BASE
 
-static struct resource zoom2_smsc911x_resources[] = {
+static struct resource zoom_smsc911x_resources[] = {
 	[0] = {
-		.start	= ZOOM2_ETHR_START,
-		.end	= ZOOM2_ETHR_START + SZ_4K,
+		.start	= ZOOM_ETHR_START,
+		.end	= ZOOM_ETHR_START + SZ_4K,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -35,42 +35,42 @@ static struct resource zoom2_smsc911x_re
 	},
 };
 
-static struct smsc911x_platform_config zoom2_smsc911x_config = {
+static struct smsc911x_platform_config zoom_smsc911x_config = {
 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
 	.flags		= SMSC911X_USE_32BIT,
 	.phy_interface	= PHY_INTERFACE_MODE_MII,
 };
 
-static struct platform_device zoom2_smsc911x_device = {
+static struct platform_device zoom_smsc911x_device = {
 	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(zoom2_smsc911x_resources),
-	.resource	= zoom2_smsc911x_resources,
+	.num_resources	= ARRAY_SIZE(zoom_smsc911x_resources),
+	.resource	= zoom_smsc911x_resources,
 	.dev		= {
-		.platform_data = &zoom2_smsc911x_config,
+		.platform_data = &zoom_smsc911x_config,
 	},
 };
 
-static inline void __init zoom2_init_smsc911x(void)
+static inline void __init zoom_init_smsc911x(void)
 {
 	int eth_cs;
 	unsigned long cs_mem_base;
 	int eth_gpio = 0;
 
-	eth_cs = ZOOM2_SMSC911X_CS;
+	eth_cs = ZOOM_SMSC911X_CS;
 
 	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
 		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
 		return;
 	}
 
-	zoom2_smsc911x_resources[0].start = cs_mem_base + 0x0;
-	zoom2_smsc911x_resources[0].end   = cs_mem_base + 0xff;
+	zoom_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	zoom_smsc911x_resources[0].end   = cs_mem_base + 0xff;
 
-	eth_gpio = ZOOM2_SMSC911X_GPIO;
+	eth_gpio = ZOOM_SMSC911X_GPIO;
 
-	zoom2_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
+	zoom_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
 
 	if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
 		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
@@ -94,7 +94,7 @@ static struct plat_serial8250_port seria
 	}
 };
 
-static struct platform_device zoom2_debugboard_serial_device = {
+static struct platform_device zoom_debugboard_serial_device = {
 	.name			= "serial8250",
 	.id			= 3,
 	.dev			= {
@@ -102,13 +102,13 @@ static struct platform_device zoom2_debu
 	},
 };
 
-static inline void __init zoom2_init_quaduart(void)
+static inline void __init zoom_init_quaduart(void)
 {
 	int quart_cs;
 	unsigned long cs_mem_base;
 	int quart_gpio = 0;
 
-	quart_cs = ZOOM2_QUADUART_CS;
+	quart_cs = ZOOM_QUADUART_CS;
 
 	if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
 		printk(KERN_ERR "Failed to request GPMC mem"
@@ -116,7 +116,7 @@ static inline void __init zoom2_init_qua
 		return;
 	}
 
-	quart_gpio = ZOOM2_QUADUART_GPIO;
+	quart_gpio = ZOOM_QUADUART_GPIO;
 
 	if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) {
 		printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
@@ -126,15 +126,15 @@ static inline void __init zoom2_init_qua
 	gpio_direction_input(quart_gpio);
 }
 
-static inline int omap_zoom2_debugboard_detect(void)
+static inline int omap_zoom_debugboard_detect(void)
 {
 	int debug_board_detect = 0;
 	int ret = 1;
 
-	debug_board_detect = ZOOM2_SMSC911X_GPIO;
+	debug_board_detect = ZOOM_SMSC911X_GPIO;
 
-	if (gpio_request(debug_board_detect, "Zoom2 debug board detect") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for Zoom2 debug"
+	if (gpio_request(debug_board_detect, "Zoom debug board detect") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for Zoom debug"
 		"board detect\n", debug_board_detect);
 		return 0;
 	}
@@ -147,17 +147,17 @@ static inline int omap_zoom2_debugboard_
 	return ret;
 }
 
-static struct platform_device *zoom2_devices[] __initdata = {
-	&zoom2_smsc911x_device,
-	&zoom2_debugboard_serial_device,
+static struct platform_device *zoom_devices[] __initdata = {
+	&zoom_smsc911x_device,
+	&zoom_debugboard_serial_device,
 };
 
-int __init omap_zoom2_debugboard_init(void)
+int __init zoom_debugboard_init(void)
 {
-	if (!omap_zoom2_debugboard_detect())
+	if (!omap_zoom_debugboard_detect())
 		return 0;
 
-	zoom2_init_smsc911x();
-	zoom2_init_quaduart();
-	return platform_add_devices(zoom2_devices, ARRAY_SIZE(zoom2_devices));
+	zoom_init_smsc911x();
+	zoom_init_quaduart();
+	return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/board-zoom-peripherals.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ *
+ * Modified from mach-omap2/board-zoom2.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/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/common.h>
+#include <plat/usb.h>
+
+#include "mmc-twl4030.h"
+
+/* Zoom2 has Qwerty keyboard*/
+static int board_keymap[] = {
+	KEY(0, 0, KEY_E),
+	KEY(0, 1, KEY_R),
+	KEY(0, 2, KEY_T),
+	KEY(0, 3, KEY_HOME),
+	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, 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, 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, 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, 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_UNKNOWN),
+	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_BACKSPACE),
+	KEY(6, 6, KEY_P),
+	KEY(6, 7, KEY_UP),
+	KEY(7, 0, KEY_PROG1),	/*MACRO 1 <User defined> */
+	KEY(7, 1, KEY_PROG2),	/*MACRO 2 <User defined> */
+	KEY(7, 2, KEY_PROG3),	/*MACRO 3 <User defined> */
+	KEY(7, 3, KEY_PROG4),	/*MACRO 4 <User defined> */
+	KEY(7, 6, KEY_SELECT),
+	KEY(7, 7, KEY_DOWN)
+};
+
+static struct matrix_keymap_data board_map_data = {
+	.keymap			= board_keymap,
+	.keymap_size		= ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data zoom_kp_twl4030_data = {
+	.keymap_data	= &board_map_data,
+	.rows		= 8,
+	.cols		= 8,
+	.rep		= 1,
+};
+
+static struct regulator_consumer_supply zoom_vmmc1_supply = {
+	.supply		= "vmmc",
+};
+
+static struct regulator_consumer_supply zoom_vsim_supply = {
+	.supply		= "vmmc_aux",
+};
+
+static struct regulator_consumer_supply zoom_vmmc2_supply = {
+	.supply		= "vmmc",
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data zoom_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data zoom_vmmc2 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 1850000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data zoom_vsim = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 3000000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom_vsim_supply,
+};
+
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+	{
+		.name		= "external",
+		.mmc		= 1,
+		.wires		= 4,
+		.gpio_wp	= -EINVAL,
+		.power_saving	= true,
+	},
+	{
+		.name		= "internal",
+		.mmc		= 2,
+		.wires		= 8,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+		.nonremovable	= true,
+		.power_saving	= true,
+	},
+	{}      /* Terminator */
+};
+
+static int zoom_twl_gpio_setup(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
+	mmc[0].gpio_cd = gpio + 0;
+	twl4030_mmc_init(mmc);
+
+	/* link regulators to MMC adapters ... we "know" the
+	 * regulators will be set up only *after* we return.
+	*/
+	zoom_vmmc1_supply.dev = mmc[0].dev;
+	zoom_vsim_supply.dev = mmc[0].dev;
+	zoom_vmmc2_supply.dev = mmc[1].dev;
+
+	return 0;
+}
+
+
+static int zoom_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630,  9280,  8950,  8620,  8310,
+8020,  7730,  7460,  7200,  6950,  6710,  6470,  6250,  6040,  5830,
+5640,  5450,  5260,  5090,  4920,  4760,  4600,  4450,  4310,  4170,
+4040,  3910,  3790,  3670,  3550
+};
+
+static struct twl4030_bci_platform_data zoom_bci_data = {
+	.battery_tmp_tbl	= zoom_batt_table,
+	.tblsize		= ARRAY_SIZE(zoom_batt_table),
+};
+
+static struct twl4030_usb_data zoom_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_gpio_platform_data zoom_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.setup		= zoom_twl_gpio_setup,
+};
+
+static struct twl4030_madc_platform_data zoom_madc_data = {
+	.irq_line	= 1,
+};
+
+static struct twl4030_codec_audio_data zoom_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data zoom_codec_data = {
+	.audio_mclk = 26000000,
+	.audio = &zoom_audio_data,
+};
+
+static struct twl4030_platform_data zoom_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.bci		= &zoom_bci_data,
+	.madc		= &zoom_madc_data,
+	.usb		= &zoom_usb_data,
+	.gpio		= &zoom_gpio_data,
+	.keypad		= &zoom_kp_twl4030_data,
+	.codec		= &zoom_codec_data,
+	.vmmc1          = &zoom_vmmc1,
+	.vmmc2          = &zoom_vmmc2,
+	.vsim           = &zoom_vsim,
+
+};
+
+static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("twl5030", 0x48),
+		.flags		= I2C_CLIENT_WAKE,
+		.irq		= INT_34XX_SYS_NIRQ,
+		.platform_data	= &zoom_twldata,
+	},
+};
+
+static int __init omap_i2c_init(void)
+{
+	omap_register_i2c_bus(1, 2400, zoom_i2c_boardinfo,
+			ARRAY_SIZE(zoom_i2c_boardinfo));
+	omap_register_i2c_bus(2, 400, NULL, 0);
+	omap_register_i2c_bus(3, 400, NULL, 0);
+	return 0;
+}
+
+void __init zoom_peripherals_init(void)
+{
+	omap_i2c_init();
+	omap_serial_init();
+	usb_musb_init();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock24xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock24xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock24xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock24xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,805 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap2/clock.c
- *
- *  Copyright (C) 2005-2008 Texas Instruments, Inc.
- *  Copyright (C) 2004-2008 Nokia Corporation
- *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
- *
- *  Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
- *  Gordon McNutt and RidgeRun, 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.
- */
-#undef DEBUG
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/cpufreq.h>
-#include <linux/bitops.h>
-
-#include <mach/clock.h>
-#include <mach/sram.h>
-#include <mach/prcm.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
-
-#include <mach/sdrc.h>
-#include "clock.h"
-#include "prm.h"
-#include "prm-regbits-24xx.h"
-#include "cm.h"
-#include "cm-regbits-24xx.h"
-
-static const struct clkops clkops_oscck;
-static const struct clkops clkops_fixed;
-
-static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
-					   void __iomem **idlest_reg,
-					   u8 *idlest_bit);
-
-/* 2430 I2CHS has non-standard IDLEST register */
-static const struct clkops clkops_omap2430_i2chs_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap2430_clk_i2chs_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-#include "clock24xx.h"
-
-struct omap_clk {
-	u32		cpu;
-	struct clk_lookup lk;
-};
-
-#define CLK(dev, con, ck, cp) 		\
-	{				\
-		 .cpu = cp,		\
-		.lk = {			\
-			.dev_id = dev,	\
-			.con_id = con,	\
-			.clk = ck,	\
-		},			\
-	}
-
-#define CK_243X			RATE_IN_243X
-#define CK_242X			RATE_IN_242X
-
-static struct omap_clk omap24xx_clks[] = {
-	/* external root sources */
-	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X),
-	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X | CK_242X),
-	/* internal analog sources */
-	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X | CK_242X),
-	/* internal prcm root sources */
-	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X | CK_242X),
-	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_242X),
-	CLK(NULL,	"emul_ck",	&emul_ck,	CK_242X),
-	/* mpu domain clocks */
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X | CK_242X),
-	/* dsp domain clocks */
-	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X),
-	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
-	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
-	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
-	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
-	/* GFX domain clocks */
-	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X | CK_242X),
-	/* Modem domain clocks */
-	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
-	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
-	/* DSS domain clocks */
-	CLK("omapfb",	"ick",		&dss_ick,	CK_243X | CK_242X),
-	CLK("omapfb",	"dss1_fck",	&dss1_fck,	CK_243X | CK_242X),
-	CLK("omapfb",	"dss2_fck",	&dss2_fck,	CK_243X | CK_242X),
-	CLK("omapfb",	"tv_fck",	&dss_54m_fck,	CK_243X | CK_242X),
-	/* L3 domain clocks */
-	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X | CK_242X),
-	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X | CK_242X),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X | CK_242X),
-	/* L4 domain clocks */
-	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X | CK_242X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X | CK_242X),
-	/* virtual meta-group clock */
-	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X),
-	/* general l4 interface ck, multi-parent functional clk */
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_243X | CK_242X),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_243X),
-	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_243X),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_243X),
-	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_243X),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_243X),
-	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_243X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_243X | CK_242X),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_243X),
-	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_243X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X | CK_242X),
-	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X | CK_242X),
-	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
-	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X | CK_242X),
-	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_242X),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_242X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X | CK_242X),
-	CLK("mmci-omap.0", "ick",	&mmc_ick,	CK_242X),
-	CLK("mmci-omap.0", "fck",	&mmc_fck,	CK_242X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"eac_ick",	&eac_ick,	CK_242X),
-	CLK(NULL,	"eac_fck",	&eac_fck,	CK_242X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X | CK_242X),
-	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X | CK_242X),
-	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_243X | CK_242X),
-	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_242X),
-	CLK("i2c_omap.1", "fck",	&i2chs1_fck,	CK_243X),
-	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_243X | CK_242X),
-	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_242X),
-	CLK("i2c_omap.2", "fck",	&i2chs2_fck,	CK_243X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X | CK_242X),
-	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
-	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
-	CLK(NULL,	"des_ick",	&des_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"sha_ick",	&sha_ick,	CK_243X | CK_242X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"aes_ick",	&aes_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X | CK_242X),
-	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X | CK_242X),
-	CLK("musb_hdrc",	"ick",	&usbhs_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "ick",	&mmchs1_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "fck",	&mmchs1_fck,	CK_243X),
-	CLK("mmci-omap-hs.1", "ick",	&mmchs2_ick,	CK_243X),
-	CLK("mmci-omap-hs.1", "fck",	&mmchs2_fck,	CK_243X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
-	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
-	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
-	CLK("mmci-omap-hs.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
-	CLK("mmci-omap-hs.1", "mmchsdb_fck", 	&mmchsdb2_fck,	CK_243X),
-};
-
-/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
-#define EN_APLL_STOPPED			0
-#define EN_APLL_LOCKED			3
-
-/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
-#define APLLS_CLKIN_19_2MHZ		0
-#define APLLS_CLKIN_13MHZ		2
-#define APLLS_CLKIN_12MHZ		3
-
-/* #define DOWN_VARIABLE_DPLL 1 */		/* Experimental */
-
-static struct prcm_config *curr_prcm_set;
-static struct clk *vclk;
-static struct clk *sclk;
-
-static void __iomem *prcm_clksrc_ctrl;
-
-/*-------------------------------------------------------------------------
- * Omap24xx specific clock functions
- *-------------------------------------------------------------------------*/
-
-/**
- * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
- * @clk: struct clk * being enabled
- * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
- * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
- *
- * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
- * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
- * passes back the correct CM_IDLEST register address for I2CHS
- * modules.  No return value.
- */
-static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
-					   void __iomem **idlest_reg,
-					   u8 *idlest_bit)
-{
-	*idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
-	*idlest_bit = clk->enable_bit;
-}
-
-
-/**
- * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
- * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
- *
- * Returns the CORE_CLK rate.  CORE_CLK can have one of three rate
- * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
- * (the latter is unusual).  This currently should be called with
- * struct clk *dpll_ck, which is a composite clock of dpll_ck and
- * core_ck.
- */
-static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
-{
-	long long core_clk;
-	u32 v;
-
-	core_clk = omap2_get_dpll_rate(clk);
-
-	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	v &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if (v == CORE_CLK_SRC_32K)
-		core_clk = 32768;
-	else
-		core_clk *= v;
-
-	return core_clk;
-}
-
-static int omap2_enable_osc_ck(struct clk *clk)
-{
-	u32 pcc;
-
-	pcc = __raw_readl(prcm_clksrc_ctrl);
-
-	__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-
-	return 0;
-}
-
-static void omap2_disable_osc_ck(struct clk *clk)
-{
-	u32 pcc;
-
-	pcc = __raw_readl(prcm_clksrc_ctrl);
-
-	__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-}
-
-static const struct clkops clkops_oscck = {
-	.enable		= &omap2_enable_osc_ck,
-	.disable	= &omap2_disable_osc_ck,
-};
-
-#ifdef OLD_CK
-/* Recalculate SYST_CLK */
-static void omap2_sys_clk_recalc(struct clk * clk)
-{
-	u32 div = PRCM_CLKSRC_CTRL;
-	div &= (1 << 7) | (1 << 6);	/* Test if ext clk divided by 1 or 2 */
-	div >>= clk->rate_offset;
-	clk->rate = (clk->parent->rate / div);
-	propagate_rate(clk);
-}
-#endif	/* OLD_CK */
-
-/* Enable an APLL if off */
-static int omap2_clk_fixed_enable(struct clk *clk)
-{
-	u32 cval, apll_mask;
-
-	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
-	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-
-	if ((cval & apll_mask) == apll_mask)
-		return 0;   /* apll already enabled */
-
-	cval &= ~apll_mask;
-	cval |= apll_mask;
-	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-
-	if (clk == &apll96_ck)
-		cval = OMAP24XX_ST_96M_APLL;
-	else if (clk == &apll54_ck)
-		cval = OMAP24XX_ST_54M_APLL;
-
-	omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval,
-			     clk->name);
-
-	/*
-	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
-	 * fails?
-	 */
-	return 0;
-}
-
-/* Stop APLL */
-static void omap2_clk_fixed_disable(struct clk *clk)
-{
-	u32 cval;
-
-	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-	cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
-	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-}
-
-static const struct clkops clkops_fixed = {
-	.enable		= &omap2_clk_fixed_enable,
-	.disable	= &omap2_clk_fixed_disable,
-};
-
-/*
- * Uses the current prcm set to tell if a rate is valid.
- * You can go slower, but not faster within a given rate set.
- */
-static long omap2_dpllcore_round_rate(unsigned long target_rate)
-{
-	u32 high, low, core_clk_src;
-
-	core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if (core_clk_src == CORE_CLK_SRC_DPLL) {	/* DPLL clockout */
-		high = curr_prcm_set->dpll_speed * 2;
-		low = curr_prcm_set->dpll_speed;
-	} else {				/* DPLL clockout x 2 */
-		high = curr_prcm_set->dpll_speed;
-		low = curr_prcm_set->dpll_speed / 2;
-	}
-
-#ifdef DOWN_VARIABLE_DPLL
-	if (target_rate > high)
-		return high;
-	else
-		return target_rate;
-#else
-	if (target_rate > low)
-		return high;
-	else
-		return low;
-#endif
-
-}
-
-static unsigned long omap2_dpllcore_recalc(struct clk *clk)
-{
-	return omap2xxx_clk_get_core_rate(clk);
-}
-
-static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
-{
-	u32 cur_rate, low, mult, div, valid_rate, done_rate;
-	u32 bypass = 0;
-	struct prcm_config tmpset;
-	const struct dpll_data *dd;
-
-	cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
-	mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	mult &= OMAP24XX_CORE_CLK_SRC_MASK;
-
-	if ((rate == (cur_rate / 2)) && (mult == 2)) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
-	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-	} else if (rate != cur_rate) {
-		valid_rate = omap2_dpllcore_round_rate(rate);
-		if (valid_rate != rate)
-			return -EINVAL;
-
-		if (mult == 1)
-			low = curr_prcm_set->dpll_speed;
-		else
-			low = curr_prcm_set->dpll_speed / 2;
-
-		dd = clk->dpll_data;
-		if (!dd)
-			return -EINVAL;
-
-		tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
-		tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
-					   dd->div1_mask);
-		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
-		tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-		tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
-		if (rate > low) {
-			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
-			mult = ((rate / 2) / 1000000);
-			done_rate = CORE_CLK_SRC_DPLL_X2;
-		} else {
-			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
-			mult = (rate / 1000000);
-			done_rate = CORE_CLK_SRC_DPLL;
-		}
-		tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
-		tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
-
-		/* Worst case */
-		tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
-
-		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
-			bypass = 1;
-
-		/* For omap2xxx_sdrc_init_params() */
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
-		/* Force dll lock mode */
-		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
-			       bypass);
-
-		/* Errata: ret dll entry state */
-		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
-		omap2xxx_sdrc_reprogram(done_rate, 0);
-	}
-
-	return 0;
-}
-
-/**
- * omap2_table_mpu_recalc - just return the MPU speed
- * @clk: virt_prcm_set struct clk
- *
- * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
- */
-static unsigned long omap2_table_mpu_recalc(struct clk *clk)
-{
-	return curr_prcm_set->mpu_speed;
-}
-
-/*
- * Look for a rate equal or less than the target rate given a configuration set.
- *
- * What's not entirely clear is "which" field represents the key field.
- * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
- * just uses the ARM rates.
- */
-static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
-{
-	struct prcm_config *ptr;
-	long highest_rate;
-
-	if (clk != &virt_prcm_set)
-		return -EINVAL;
-
-	highest_rate = -EINVAL;
-
-	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
-		if (!(ptr->flags & cpu_mask))
-			continue;
-		if (ptr->xtal_speed != sys_ck.rate)
-			continue;
-
-		highest_rate = ptr->mpu_speed;
-
-		/* Can check only after xtal frequency check */
-		if (ptr->mpu_speed <= rate)
-			break;
-	}
-	return highest_rate;
-}
-
-/* Sets basic clocks based on the specified rate */
-static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
-{
-	u32 cur_rate, done_rate, bypass = 0, tmp;
-	struct prcm_config *prcm;
-	unsigned long found_speed = 0;
-	unsigned long flags;
-
-	if (clk != &virt_prcm_set)
-		return -EINVAL;
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-
-		if (prcm->mpu_speed <= rate) {
-			found_speed = prcm->mpu_speed;
-			break;
-		}
-	}
-
-	if (!found_speed) {
-		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
-		       rate / 1000000);
-		return -EINVAL;
-	}
-
-	curr_prcm_set = prcm;
-	cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
-
-	if (prcm->dpll_speed == cur_rate / 2) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
-	} else if (prcm->dpll_speed == cur_rate * 2) {
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-	} else if (prcm->dpll_speed != cur_rate) {
-		local_irq_save(flags);
-
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			bypass = 1;
-
-		if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
-		    CORE_CLK_SRC_DPLL_X2)
-			done_rate = CORE_CLK_SRC_DPLL_X2;
-		else
-			done_rate = CORE_CLK_SRC_DPLL;
-
-		/* MPU divider */
-		cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
-
-		/* dsp + iva1 div(2420), iva2.1(2430) */
-		cm_write_mod_reg(prcm->cm_clksel_dsp,
-				 OMAP24XX_DSP_MOD, CM_CLKSEL);
-
-		cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
-
-		/* Major subsystem dividers */
-		tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
-		cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
-				 CM_CLKSEL1);
-
-		if (cpu_is_omap2430())
-			cm_write_mod_reg(prcm->cm_clksel_mdm,
-					 OMAP2430_MDM_MOD, CM_CLKSEL);
-
-		/* x2 to enter omap2xxx_sdrc_init_params() */
-		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
-		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
-			       bypass);
-
-		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
-		omap2xxx_sdrc_reprogram(done_rate, 0);
-
-		local_irq_restore(flags);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_CPU_FREQ
-/*
- * Walk PRCM rate table and fillout cpufreq freq_table
- */
-static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)];
-
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	struct prcm_config *prcm;
-	int i = 0;
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-
-		/* don't put bypass rates in table */
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			continue;
-
-		freq_table[i].index = i;
-		freq_table[i].frequency = prcm->mpu_speed / 1000;
-		i++;
-	}
-
-	if (i == 0) {
-		printk(KERN_WARNING "%s: failed to initialize frequency "
-		       "table\n", __func__);
-		return;
-	}
-
-	freq_table[i].index = i;
-	freq_table[i].frequency = CPUFREQ_TABLE_END;
-
-	*table = &freq_table[0];
-}
-#endif
-
-static struct clk_functions omap2_clk_functions = {
-	.clk_enable		= omap2_clk_enable,
-	.clk_disable		= omap2_clk_disable,
-	.clk_round_rate		= omap2_clk_round_rate,
-	.clk_set_rate		= omap2_clk_set_rate,
-	.clk_set_parent		= omap2_clk_set_parent,
-	.clk_disable_unused	= omap2_clk_disable_unused,
-#ifdef	CONFIG_CPU_FREQ
-	.clk_init_cpufreq_table	= omap2_clk_init_cpufreq_table,
-#endif
-};
-
-static u32 omap2_get_apll_clkin(void)
-{
-	u32 aplls, srate = 0;
-
-	aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
-	aplls &= OMAP24XX_APLLS_CLKIN_MASK;
-	aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
-
-	if (aplls == APLLS_CLKIN_19_2MHZ)
-		srate = 19200000;
-	else if (aplls == APLLS_CLKIN_13MHZ)
-		srate = 13000000;
-	else if (aplls == APLLS_CLKIN_12MHZ)
-		srate = 12000000;
-
-	return srate;
-}
-
-static u32 omap2_get_sysclkdiv(void)
-{
-	u32 div;
-
-	div = __raw_readl(prcm_clksrc_ctrl);
-	div &= OMAP_SYSCLKDIV_MASK;
-	div >>= OMAP_SYSCLKDIV_SHIFT;
-
-	return div;
-}
-
-static unsigned long omap2_osc_clk_recalc(struct clk *clk)
-{
-	return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
-}
-
-static unsigned long omap2_sys_clk_recalc(struct clk *clk)
-{
-	return clk->parent->rate / omap2_get_sysclkdiv();
-}
-
-/*
- * Set clocks for bypass mode for reboot to work.
- */
-void omap2_clk_prepare_for_reboot(void)
-{
-	u32 rate;
-
-	if (vclk == NULL || sclk == NULL)
-		return;
-
-	rate = clk_get_rate(sclk);
-	clk_set_rate(vclk, rate);
-}
-
-/*
- * Switch the MPU rate if specified on cmdline.
- * We cannot do this early until cmdline is parsed.
- */
-static int __init omap2_clk_arch_init(void)
-{
-	if (!mpurate)
-		return -EINVAL;
-
-	if (clk_set_rate(&virt_prcm_set, mpurate))
-		printk(KERN_ERR "Could not find matching MPU rate\n");
-
-	recalculate_root_clocks();
-
-	printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
-	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
-
-	return 0;
-}
-arch_initcall(omap2_clk_arch_init);
-
-int __init omap2_clk_init(void)
-{
-	struct prcm_config *prcm;
-	struct omap_clk *c;
-	u32 clkrate;
-
-	if (cpu_is_omap242x()) {
-		prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
-		cpu_mask = RATE_IN_242X;
-	} else if (cpu_is_omap2430()) {
-		prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
-		cpu_mask = RATE_IN_243X;
-	}
-
-	clk_init(&omap2_clk_functions);
-
-	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
-	propagate_rate(&osc_ck);
-	sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
-	propagate_rate(&sys_ck);
-
-	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
-		if (c->cpu & cpu_mask) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-
-	/* Check the MPU rate set by bootloader */
-	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-		if (prcm->dpll_speed <= clkrate)
-			 break;
-	}
-	curr_prcm_set = prcm;
-
-	recalculate_root_clocks();
-
-	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
-	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	/* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
-	vclk = clk_get(NULL, "virt_prcm_set");
-	sclk = clk_get(NULL, "sys_ck");
-
-	return 0;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock24xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock24xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock24xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock24xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,2657 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap2/clock24xx.h
- *
- *  Copyright (C) 2005-2008 Texas Instruments, Inc.
- *  Copyright (C) 2004-2008 Nokia Corporation
- *
- *  Contacts:
- *  Richard Woodruff <r-woodruff2@ti.com>
- *  Paul Walmsley
- *
- * This 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_CLOCK24XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK24XX_H
-
-#include "clock.h"
-
-#include "prm.h"
-#include "cm.h"
-#include "prm-regbits-24xx.h"
-#include "cm-regbits-24xx.h"
-#include "sdrc.h"
-
-/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
-#ifdef CONFIG_ARCH_OMAP2420
-#define OMAP_CM_REGADDR			OMAP2420_CM_REGADDR
-#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2420_PRCM_CLKOUT_CTRL
-#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2420_PRCM_CLKEMUL_CTRL
-#else
-#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
-#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2430_PRCM_CLKOUT_CTRL
-#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2430_PRCM_CLKEMUL_CTRL
-#endif
-
-static unsigned long omap2_table_mpu_recalc(struct clk *clk);
-static int omap2_select_table_rate(struct clk *clk, unsigned long rate);
-static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
-static unsigned long omap2_sys_clk_recalc(struct clk *clk);
-static unsigned long omap2_osc_clk_recalc(struct clk *clk);
-static unsigned long omap2_sys_clk_recalc(struct clk *clk);
-static unsigned long omap2_dpllcore_recalc(struct clk *clk);
-static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
-
-/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
- * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
- * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
- */
-struct prcm_config {
-	unsigned long xtal_speed;	/* crystal rate */
-	unsigned long dpll_speed;	/* dpll: out*xtal*M/(N-1)table_recalc */
-	unsigned long mpu_speed;	/* speed of MPU */
-	unsigned long cm_clksel_mpu;	/* mpu divider */
-	unsigned long cm_clksel_dsp;	/* dsp+iva1 div(2420), iva2.1(2430) */
-	unsigned long cm_clksel_gfx;	/* gfx dividers */
-	unsigned long cm_clksel1_core;	/* major subsystem dividers */
-	unsigned long cm_clksel1_pll;	/* m,n */
-	unsigned long cm_clksel2_pll;	/* dpllx1 or x2 out */
-	unsigned long cm_clksel_mdm;	/* modem dividers 2430 only */
-	unsigned long base_sdrc_rfr;	/* base refresh timing for a set */
-	unsigned char flags;
-};
-
-/*
- * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
- * These configurations are characterized by voltage and speed for clocks.
- * The device is only validated for certain combinations. One way to express
- * these combinations is via the 'ratio's' which the clocks operate with
- * respect to each other. These ratio sets are for a given voltage/DPLL
- * setting. All configurations can be described by a DPLL setting and a ratio
- * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
- *
- * 2430 differs from 2420 in that there are no more phase synchronizers used.
- * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
- * 2430 (iva2.1, NOdsp, mdm)
- */
-
-/* Core fields for cm_clksel, not ratio governed */
-#define RX_CLKSEL_DSS1			(0x10 << 8)
-#define RX_CLKSEL_DSS2			(0x0 << 13)
-#define RX_CLKSEL_SSI			(0x5 << 20)
-
-/*-------------------------------------------------------------------------
- * Voltage/DPLL ratios
- *-------------------------------------------------------------------------*/
-
-/* 2430 Ratio's, 2430-Ratio Config 1 */
-#define R1_CLKSEL_L3			(4 << 0)
-#define R1_CLKSEL_L4			(2 << 5)
-#define R1_CLKSEL_USB			(4 << 25)
-#define R1_CM_CLKSEL1_CORE_VAL		R1_CLKSEL_USB | RX_CLKSEL_SSI | \
-					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
-					R1_CLKSEL_L4 | R1_CLKSEL_L3
-#define R1_CLKSEL_MPU			(2 << 0)
-#define R1_CM_CLKSEL_MPU_VAL		R1_CLKSEL_MPU
-#define R1_CLKSEL_DSP			(2 << 0)
-#define R1_CLKSEL_DSP_IF		(2 << 5)
-#define R1_CM_CLKSEL_DSP_VAL		R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF
-#define R1_CLKSEL_GFX			(2 << 0)
-#define R1_CM_CLKSEL_GFX_VAL		R1_CLKSEL_GFX
-#define R1_CLKSEL_MDM			(4 << 0)
-#define R1_CM_CLKSEL_MDM_VAL		R1_CLKSEL_MDM
-
-/* 2430-Ratio Config 2 */
-#define R2_CLKSEL_L3			(6 << 0)
-#define R2_CLKSEL_L4			(2 << 5)
-#define R2_CLKSEL_USB			(2 << 25)
-#define R2_CM_CLKSEL1_CORE_VAL		R2_CLKSEL_USB | RX_CLKSEL_SSI | \
-					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
-					R2_CLKSEL_L4 | R2_CLKSEL_L3
-#define R2_CLKSEL_MPU			(2 << 0)
-#define R2_CM_CLKSEL_MPU_VAL		R2_CLKSEL_MPU
-#define R2_CLKSEL_DSP			(2 << 0)
-#define R2_CLKSEL_DSP_IF		(3 << 5)
-#define R2_CM_CLKSEL_DSP_VAL		R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF
-#define R2_CLKSEL_GFX			(2 << 0)
-#define R2_CM_CLKSEL_GFX_VAL		R2_CLKSEL_GFX
-#define R2_CLKSEL_MDM			(6 << 0)
-#define R2_CM_CLKSEL_MDM_VAL		R2_CLKSEL_MDM
-
-/* 2430-Ratio Bootm (BYPASS) */
-#define RB_CLKSEL_L3			(1 << 0)
-#define RB_CLKSEL_L4			(1 << 5)
-#define RB_CLKSEL_USB			(1 << 25)
-#define RB_CM_CLKSEL1_CORE_VAL		RB_CLKSEL_USB | RX_CLKSEL_SSI | \
-					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
-					RB_CLKSEL_L4 | RB_CLKSEL_L3
-#define RB_CLKSEL_MPU			(1 << 0)
-#define RB_CM_CLKSEL_MPU_VAL		RB_CLKSEL_MPU
-#define RB_CLKSEL_DSP			(1 << 0)
-#define RB_CLKSEL_DSP_IF		(1 << 5)
-#define RB_CM_CLKSEL_DSP_VAL		RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF
-#define RB_CLKSEL_GFX			(1 << 0)
-#define RB_CM_CLKSEL_GFX_VAL		RB_CLKSEL_GFX
-#define RB_CLKSEL_MDM			(1 << 0)
-#define RB_CM_CLKSEL_MDM_VAL		RB_CLKSEL_MDM
-
-/* 2420 Ratio Equivalents */
-#define RXX_CLKSEL_VLYNQ		(0x12 << 15)
-#define RXX_CLKSEL_SSI			(0x8 << 20)
-
-/* 2420-PRCM III 532MHz core */
-#define RIII_CLKSEL_L3			(4 << 0)	/* 133MHz */
-#define RIII_CLKSEL_L4			(2 << 5)	/* 66.5MHz */
-#define RIII_CLKSEL_USB			(4 << 25)	/* 33.25MHz */
-#define RIII_CM_CLKSEL1_CORE_VAL	RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
-					RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
-					RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
-					RIII_CLKSEL_L3
-#define RIII_CLKSEL_MPU			(2 << 0)	/* 266MHz */
-#define RIII_CM_CLKSEL_MPU_VAL		RIII_CLKSEL_MPU
-#define RIII_CLKSEL_DSP			(3 << 0)	/* c5x - 177.3MHz */
-#define RIII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 88.67MHz */
-#define RIII_SYNC_DSP			(1 << 7)	/* Enable sync */
-#define RIII_CLKSEL_IVA			(6 << 8)	/* iva1 - 88.67MHz */
-#define RIII_SYNC_IVA			(1 << 13)	/* Enable sync */
-#define RIII_CM_CLKSEL_DSP_VAL		RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
-					RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
-					RIII_CLKSEL_DSP
-#define RIII_CLKSEL_GFX			(2 << 0)	/* 66.5MHz */
-#define RIII_CM_CLKSEL_GFX_VAL		RIII_CLKSEL_GFX
-
-/* 2420-PRCM II 600MHz core */
-#define RII_CLKSEL_L3			(6 << 0)	/* 100MHz */
-#define RII_CLKSEL_L4			(2 << 5)	/* 50MHz */
-#define RII_CLKSEL_USB			(2 << 25)	/* 50MHz */
-#define RII_CM_CLKSEL1_CORE_VAL		RII_CLKSEL_USB | \
-					RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
-					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
-					RII_CLKSEL_L4 | RII_CLKSEL_L3
-#define RII_CLKSEL_MPU			(2 << 0)	/* 300MHz */
-#define RII_CM_CLKSEL_MPU_VAL		RII_CLKSEL_MPU
-#define RII_CLKSEL_DSP			(3 << 0)	/* c5x - 200MHz */
-#define RII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 100MHz */
-#define RII_SYNC_DSP			(0 << 7)	/* Bypass sync */
-#define RII_CLKSEL_IVA			(3 << 8)	/* iva1 - 200MHz */
-#define RII_SYNC_IVA			(0 << 13)	/* Bypass sync */
-#define RII_CM_CLKSEL_DSP_VAL		RII_SYNC_IVA | RII_CLKSEL_IVA | \
-					RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
-					RII_CLKSEL_DSP
-#define RII_CLKSEL_GFX			(2 << 0)	/* 50MHz */
-#define RII_CM_CLKSEL_GFX_VAL		RII_CLKSEL_GFX
-
-/* 2420-PRCM I 660MHz core */
-#define RI_CLKSEL_L3			(4 << 0)	/* 165MHz */
-#define RI_CLKSEL_L4			(2 << 5)	/* 82.5MHz */
-#define RI_CLKSEL_USB			(4 << 25)	/* 41.25MHz */
-#define RI_CM_CLKSEL1_CORE_VAL		RI_CLKSEL_USB | \
-					RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
-					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
-					RI_CLKSEL_L4 | RI_CLKSEL_L3
-#define RI_CLKSEL_MPU			(2 << 0)	/* 330MHz */
-#define RI_CM_CLKSEL_MPU_VAL		RI_CLKSEL_MPU
-#define RI_CLKSEL_DSP			(3 << 0)	/* c5x - 220MHz */
-#define RI_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 110MHz */
-#define RI_SYNC_DSP			(1 << 7)	/* Activate sync */
-#define RI_CLKSEL_IVA			(4 << 8)	/* iva1 - 165MHz */
-#define RI_SYNC_IVA			(0 << 13)	/* Bypass sync */
-#define RI_CM_CLKSEL_DSP_VAL		RI_SYNC_IVA | RI_CLKSEL_IVA | \
-					RI_SYNC_DSP | RI_CLKSEL_DSP_IF | \
-					RI_CLKSEL_DSP
-#define RI_CLKSEL_GFX			(1 << 0)	/* 165MHz */
-#define RI_CM_CLKSEL_GFX_VAL		RI_CLKSEL_GFX
-
-/* 2420-PRCM VII (boot) */
-#define RVII_CLKSEL_L3			(1 << 0)
-#define RVII_CLKSEL_L4			(1 << 5)
-#define RVII_CLKSEL_DSS1		(1 << 8)
-#define RVII_CLKSEL_DSS2		(0 << 13)
-#define RVII_CLKSEL_VLYNQ		(1 << 15)
-#define RVII_CLKSEL_SSI			(1 << 20)
-#define RVII_CLKSEL_USB			(1 << 25)
-
-#define RVII_CM_CLKSEL1_CORE_VAL	RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
-					RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \
-					RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3
-
-#define RVII_CLKSEL_MPU			(1 << 0) /* all divide by 1 */
-#define RVII_CM_CLKSEL_MPU_VAL		RVII_CLKSEL_MPU
-
-#define RVII_CLKSEL_DSP			(1 << 0)
-#define RVII_CLKSEL_DSP_IF		(1 << 5)
-#define RVII_SYNC_DSP			(0 << 7)
-#define RVII_CLKSEL_IVA			(1 << 8)
-#define RVII_SYNC_IVA			(0 << 13)
-#define RVII_CM_CLKSEL_DSP_VAL		RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \
-					RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP
-
-#define RVII_CLKSEL_GFX			(1 << 0)
-#define RVII_CM_CLKSEL_GFX_VAL		RVII_CLKSEL_GFX
-
-/*-------------------------------------------------------------------------
- * 2430 Target modes: Along with each configuration the CPU has several
- * modes which goes along with them. Modes mainly are the addition of
- * describe DPLL combinations to go along with a ratio.
- *-------------------------------------------------------------------------*/
-
-/* Hardware governed */
-#define MX_48M_SRC			(0 << 3)
-#define MX_54M_SRC			(0 << 5)
-#define MX_APLLS_CLIKIN_12		(3 << 23)
-#define MX_APLLS_CLIKIN_13		(2 << 23)
-#define MX_APLLS_CLIKIN_19_2		(0 << 23)
-
-/*
- * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
- * #5a	(ratio1) baseport-target, target DPLL = 266*2 = 532MHz
- */
-#define M5A_DPLL_MULT_12		(133 << 12)
-#define M5A_DPLL_DIV_12			(5 << 8)
-#define M5A_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-#define M5A_DPLL_MULT_13		(61 << 12)
-#define M5A_DPLL_DIV_13			(2 << 8)
-#define M5A_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-#define M5A_DPLL_MULT_19		(55 << 12)
-#define M5A_DPLL_DIV_19			(3 << 8)
-#define M5A_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
-					MX_APLLS_CLIKIN_19_2
-/* #5b	(ratio1) target DPLL = 200*2 = 400MHz */
-#define M5B_DPLL_MULT_12		(50 << 12)
-#define M5B_DPLL_DIV_12			(2 << 8)
-#define M5B_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-#define M5B_DPLL_MULT_13		(200 << 12)
-#define M5B_DPLL_DIV_13			(12 << 8)
-
-#define M5B_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-#define M5B_DPLL_MULT_19		(125 << 12)
-#define M5B_DPLL_DIV_19			(31 << 8)
-#define M5B_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
-					MX_APLLS_CLIKIN_19_2
-/*
- * #4	(ratio2), DPLL = 399*2 = 798MHz, L3=133MHz
- */
-#define M4_DPLL_MULT_12			(133 << 12)
-#define M4_DPLL_DIV_12			(3 << 8)
-#define M4_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M4_DPLL_DIV_12 | M4_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-
-#define M4_DPLL_MULT_13			(399 << 12)
-#define M4_DPLL_DIV_13			(12 << 8)
-#define M4_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M4_DPLL_DIV_13 | M4_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-
-#define M4_DPLL_MULT_19			(145 << 12)
-#define M4_DPLL_DIV_19			(6 << 8)
-#define M4_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M4_DPLL_DIV_19 | M4_DPLL_MULT_19 | \
-					MX_APLLS_CLIKIN_19_2
-
-/*
- * #3	(ratio2) baseport-target, target DPLL = 330*2 = 660MHz
- */
-#define M3_DPLL_MULT_12			(55 << 12)
-#define M3_DPLL_DIV_12			(1 << 8)
-#define M3_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-#define M3_DPLL_MULT_13			(76 << 12)
-#define M3_DPLL_DIV_13			(2 << 8)
-#define M3_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-#define M3_DPLL_MULT_19			(17 << 12)
-#define M3_DPLL_DIV_19			(0 << 8)
-#define M3_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
-					MX_APLLS_CLIKIN_19_2
-
-/*
- * #2   (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz
- */
-#define M2_DPLL_MULT_12		        (55 << 12)
-#define M2_DPLL_DIV_12		        (1 << 8)
-#define M2_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M2_DPLL_DIV_12 | M2_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-
-/* Speed changes - Used 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2,
- * relock time issue */
-/* Core frequency changed from 330/165 to 329/164 MHz*/
-#define M2_DPLL_MULT_13		        (76 << 12)
-#define M2_DPLL_DIV_13		        (2 << 8)
-#define M2_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M2_DPLL_DIV_13 | M2_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-
-#define M2_DPLL_MULT_19		        (17 << 12)
-#define M2_DPLL_DIV_19		        (0 << 8)
-#define M2_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
-					M2_DPLL_DIV_19 | M2_DPLL_MULT_19 | \
-					MX_APLLS_CLIKIN_19_2
-
-/* boot (boot) */
-#define MB_DPLL_MULT			(1 << 12)
-#define MB_DPLL_DIV			(0 << 8)
-#define MB_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
-					MB_DPLL_MULT | MX_APLLS_CLIKIN_12
-
-#define MB_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
-					MB_DPLL_MULT | MX_APLLS_CLIKIN_13
-
-#define MB_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
-					MB_DPLL_MULT | MX_APLLS_CLIKIN_19
-
-/*
- * 2430 - chassis (sedna)
- * 165 (ratio1) same as above #2
- * 150 (ratio1)
- * 133 (ratio2) same as above #4
- * 110 (ratio2) same as above #3
- * 104 (ratio2)
- * boot (boot)
- */
-
-/* PRCM I target DPLL = 2*330MHz = 660MHz */
-#define MI_DPLL_MULT_12			(55 << 12)
-#define MI_DPLL_DIV_12			(1 << 8)
-#define MI_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					MI_DPLL_DIV_12 | MI_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-
-/*
- * 2420 Equivalent - mode registers
- * PRCM II , target DPLL = 2*300MHz = 600MHz
- */
-#define MII_DPLL_MULT_12		(50 << 12)
-#define MII_DPLL_DIV_12			(1 << 8)
-#define MII_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-#define MII_DPLL_MULT_13		(300 << 12)
-#define MII_DPLL_DIV_13			(12 << 8)
-#define MII_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-
-/* PRCM III target DPLL = 2*266 = 532MHz*/
-#define MIII_DPLL_MULT_12		(133 << 12)
-#define MIII_DPLL_DIV_12		(5 << 8)
-#define MIII_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
-					MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \
-					MX_APLLS_CLIKIN_12
-#define MIII_DPLL_MULT_13		(266 << 12)
-#define MIII_DPLL_DIV_13		(12 << 8)
-#define MIII_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
-					MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \
-					MX_APLLS_CLIKIN_13
-
-/* PRCM VII (boot bypass) */
-#define MVII_CM_CLKSEL1_PLL_12_VAL	MB_CM_CLKSEL1_PLL_12_VAL
-#define MVII_CM_CLKSEL1_PLL_13_VAL	MB_CM_CLKSEL1_PLL_13_VAL
-
-/* High and low operation value */
-#define MX_CLKSEL2_PLL_2x_VAL		(2 << 0)
-#define MX_CLKSEL2_PLL_1x_VAL		(1 << 0)
-
-/* MPU speed defines */
-#define S12M	12000000
-#define S13M	13000000
-#define S19M	19200000
-#define S26M	26000000
-#define S100M	100000000
-#define S133M	133000000
-#define S150M	150000000
-#define S164M	164000000
-#define S165M	165000000
-#define S199M	199000000
-#define S200M	200000000
-#define S266M	266000000
-#define S300M	300000000
-#define S329M	329000000
-#define S330M	330000000
-#define S399M	399000000
-#define S400M	400000000
-#define S532M	532000000
-#define S600M	600000000
-#define S658M	658000000
-#define S660M	660000000
-#define S798M	798000000
-
-/*-------------------------------------------------------------------------
- * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
- * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
- * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
- * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
- *
- * Filling in table based on H4 boards and 2430-SDPs variants available.
- * There are quite a few more rates combinations which could be defined.
- *
- * When multiple values are defined the start up will try and choose the
- * fastest one. If a 'fast' value is defined, then automatically, the /2
- * one should be included as it can be used.	Generally having more that
- * one fast set does not make sense, as static timings need to be changed
- * to change the set.	 The exception is the bypass setting which is
- * availble for low power bypass.
- *
- * Note: This table needs to be sorted, fastest to slowest.
- *-------------------------------------------------------------------------*/
-static struct prcm_config rate_table[] = {
-	/* PRCM I - FAST */
-	{S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL,		/* 330MHz ARM */
-		RI_CM_CLKSEL_DSP_VAL, RI_CM_CLKSEL_GFX_VAL,
-		RI_CM_CLKSEL1_CORE_VAL, MI_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_165MHz,
-		RATE_IN_242X},
-
-	/* PRCM II - FAST */
-	{S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
-		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
-		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
-		RATE_IN_242X},
-
-	{S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
-		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
-		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
-		RATE_IN_242X},
-
-	/* PRCM III - FAST */
-	{S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
-		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
-		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
-		RATE_IN_242X},
-
-	{S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
-		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
-		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
-		RATE_IN_242X},
-
-	/* PRCM II - SLOW */
-	{S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
-		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
-		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
-		RATE_IN_242X},
-
-	{S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
-		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
-		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
-		RATE_IN_242X},
-
-	/* PRCM III - SLOW */
-	{S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
-		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
-		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
-		RATE_IN_242X},
-
-	{S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
-		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
-		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
-		RATE_IN_242X},
-
-	/* PRCM-VII (boot-bypass) */
-	{S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL,		/* 12MHz ARM*/
-		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
-		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
-		RATE_IN_242X},
-
-	/* PRCM-VII (boot-bypass) */
-	{S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL,		/* 13MHz ARM */
-		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
-		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
-		RATE_IN_242X},
-
-	/* PRCM #4 - ratio2 (ES2.1) - FAST */
-	{S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL,		/* 399MHz ARM */
-		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
-		R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_133MHz,
-		RATE_IN_243X},
-
-	/* PRCM #2 - ratio1 (ES2) - FAST */
-	{S13M, S658M, S329M, R1_CM_CLKSEL_MPU_VAL,		/* 330MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_165MHz,
-		RATE_IN_243X},
-
-	/* PRCM #5a - ratio1 - FAST */
-	{S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_133MHz,
-		RATE_IN_243X},
-
-	/* PRCM #5b - ratio1 - FAST */
-	{S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL,		/* 200MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_100MHz,
-		RATE_IN_243X},
-
-	/* PRCM #4 - ratio1 (ES2.1) - SLOW */
-	{S13M, S399M, S199M, R2_CM_CLKSEL_MPU_VAL,		/* 200MHz ARM */
-		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
-		R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_133MHz,
-		RATE_IN_243X},
-
-	/* PRCM #2 - ratio1 (ES2) - SLOW */
-	{S13M, S329M, S164M, R1_CM_CLKSEL_MPU_VAL,		/* 165MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_165MHz,
-		RATE_IN_243X},
-
-	/* PRCM #5a - ratio1 - SLOW */
-	{S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_133MHz,
-		RATE_IN_243X},
-
-	/* PRCM #5b - ratio1 - SLOW*/
-	{S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL,		/* 100MHz ARM */
-		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
-		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_100MHz,
-		RATE_IN_243X},
-
-	/* PRCM-boot/bypass */
-	{S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL,		/* 13Mhz */
-		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
-		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_BYPASS,
-		RATE_IN_243X},
-
-	/* PRCM-boot/bypass */
-	{S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL,		/* 12Mhz */
-		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
-		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
-		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
-		SDRC_RFR_CTRL_BYPASS,
-		RATE_IN_243X},
-
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-};
-
-/*-------------------------------------------------------------------------
- * 24xx clock tree.
- *
- * NOTE:In many cases here we are assigning a 'default' parent.	In many
- *	cases the parent is selectable.	The get/set parent calls will also
- *	switch sources.
- *
- *	Many some clocks say always_enabled, but they can be auto idled for
- *	power savings. They will always be available upon clock request.
- *
- *	Several sources are given initial rates which may be wrong, this will
- *	be fixed up in the init func.
- *
- *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most periferals have dependencies on multiple clock
- *	domains. Many get their interface clocks from the L4 domain, but get
- *	functional clocks from fixed sources or other core domain derived
- *	clocks.
- *-------------------------------------------------------------------------*/
-
-/* Base external input clocks */
-static struct clk func_32k_ck = {
-	.name		= "func_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32000,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-static struct clk secure_32k_ck = {
-	.name		= "secure_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
-static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
-	.name		= "osc_ck",
-	.ops		= &clkops_oscck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_osc_clk_recalc,
-};
-
-/* Without modem likely 12MHz, with modem likely 13MHz */
-static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
-	.name		= "sys_ck",		/* ~ ref_clk also */
-	.ops		= &clkops_null,
-	.parent		= &osc_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_sys_clk_recalc,
-};
-
-static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
-	.name		= "alt_ck",
-	.ops		= &clkops_null,
-	.rate		= 54000000,
-	.flags		= RATE_FIXED,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/*
- * Analog domain root source clocks
- */
-
-/* dpll_ck, is broken out in to special cases through clksel */
-/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
- * deal with this
- */
-
-static struct dpll_data dpll_dd = {
-	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
-	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
-	.clk_bypass		= &sys_ck,
-	.clk_ref		= &sys_ck,
-	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
-	.max_multiplier		= 1024,
-	.min_divider		= 1,
-	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-/*
- * XXX Cannot add round_rate here yet, as this is still a composite clock,
- * not just a DPLL
- */
-static struct clk dpll_ck = {
-	.name		= "dpll_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,		/* Can be func_32k also */
-	.dpll_data	= &dpll_dd,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_dpllcore_recalc,
-	.set_rate	= &omap2_reprogram_dpllcore,
-};
-
-static struct clk apll96_ck = {
-	.name		= "apll96_ck",
-	.ops		= &clkops_fixed,
-	.parent		= &sys_ck,
-	.rate		= 96000000,
-	.flags		= RATE_FIXED | ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
-};
-
-static struct clk apll54_ck = {
-	.name		= "apll54_ck",
-	.ops		= &clkops_fixed,
-	.parent		= &sys_ck,
-	.rate		= 54000000,
-	.flags		= RATE_FIXED | ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
-};
-
-/*
- * PRCM digital base sources
- */
-
-/* func_54m_ck */
-
-static const struct clksel_rate func_54m_apll54_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_54m_clksel[] = {
-	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
-	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
-	{ .parent = NULL },
-};
-
-static struct clk func_54m_ck = {
-	.name		= "func_54m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll54_ck,	/* can also be alt_clk */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_54M_SOURCE,
-	.clksel		= func_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll_ck,		/* can also be 32k */
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* func_96m_ck */
-static const struct clksel_rate func_96m_apll96_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_96m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_96m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_96m_apll96_rates },
-	{ .parent = &alt_ck,	.rates = func_96m_alt_rates },
-	{ .parent = NULL }
-};
-
-/* The parent of this clock is not selectable on 2420. */
-static struct clk func_96m_ck = {
-	.name		= "func_96m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2430_96M_SOURCE,
-	.clksel		= func_96m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* func_48m_ck */
-
-static const struct clksel_rate func_48m_apll96_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel func_48m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
-	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk func_48m_ck = {
-	.name		= "func_48m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,	 /* 96M or Alt */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_48M_SOURCE,
-	.clksel		= func_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk func_12m_ck = {
-	.name		= "func_12m_ck",
-	.ops		= &clkops_null,
-	.parent		= &func_48m_ck,
-	.fixed_div	= 4,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/* Secure timer, only available in secure mode */
-static struct clk wdt1_osc_ck = {
-	.name		= "ck_wdt1_osc",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &osc_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The common_clkout* clksel_rate structs are common to
- * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
- * sys_clkout2_* are 2420-only, so the
- * clksel_rate flags fields are inaccurate for those clocks. This is
- * harmless since access to those clocks are gated by the struct clk
- * flags fields, which mark them as 2420-only.
- */
-static const struct clksel_rate common_clkout_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel common_clkout_src_clksel[] = {
-	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
-	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
-	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
-	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout_src = {
-	.name		= "sys_clkout_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate common_clkout_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout_clksel[] = {
-	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout = {
-	.name		= "sys_clkout",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
-	.clksel		= sys_clkout_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2_src = {
-	.name		= "sys_clkout2_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &sys_clkout2_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout2_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk emul_ck = {
-	.name		= "emul_ck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP24XX_PRCM_CLKEMUL_CTRL,
-	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-
-};
-
-/*
- * MPU clock domain
- *	Clocks:
- *		MPU_FCLK, MPU_ICLK
- *		INT_M_FCLK, INT_M_I_CLK
- *
- * - Individual clocks are hardware managed.
- * - Base divider comes from: CM_CLKSEL_MPU
- *
- */
-static const struct clksel_rate mpu_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &core_ck, .rates = mpu_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mpu_ck = {	/* Control cpu */
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "mpu_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
-	.clksel		= mpu_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
- * Clocks:
- *	2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
- *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
- *
- * Won't be too specific here. The core clock comes into this block
- * it is divided then tee'ed. One branch goes directly to xyz enable
- * controls. The other branch gets further divided by 2 then possibly
- * routed into a synchronizer and out of clocks abc.
- */
-static const struct clksel_rate dsp_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dsp_fck = {
-	.name		= "dsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
-	{ .parent = NULL }
-};
-
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
-	.name		= "dsp_irate_ick",
-	.ops		= &clkops_null,
-	.parent		= &dsp_fck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_irate_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	      = &omap2_clksel_set_rate
-};
-
-/* 2420 only */
-static struct clk dsp_ick = {
-	.name		= "dsp_ick",	 /* apparently ipi and isp */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
-};
-
-/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
-static struct clk iva2_1_ick = {
-	.name		= "iva2_1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_irate_ick,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-};
-
-/*
- * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
- * the C54x, but which is contained in the DSP powerdomain.  Does not
- * exist on later OMAPs.
- */
-static struct clk iva1_ifck = {
-	.name		= "iva1_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= CONFIG_PARTICIPANT | DELAYED_APP,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_COP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2420_CLKSEL_IVA_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* IVA1 mpu/int/i/f clocks are /2 of parent */
-static struct clk iva1_mpu_int_ifck = {
-	.name		= "iva1_mpu_int_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &iva1_ifck,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/*
- * L3 clock domain
- * L3 clocks are used for both interface and functional clocks to
- * multiple entities. Some of these clocks are completely managed
- * by hardware, and some others allow software control. Hardware
- * managed ones general are based on directly CLK_REQ signals and
- * various auto idle settings. The functional spec sets many of these
- * as 'tie-high' for their enables.
- *
- * I-CLOCKS:
- *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
- *	CAM, HS-USB.
- * F-CLOCK
- *	SSI.
- *
- * GPMC memories and SDRC have timing and clock sensitive registers which
- * may very well need notification when the clock changes. Currently for low
- * operating points, these are taken care of in sleep.S.
- */
-static const struct clksel_rate core_l3_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel core_l3_clksel[] = {
-	{ .parent = &core_ck, .rates = core_l3_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
-	.name		= "core_l3_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "core_l3_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
-	.clksel		= core_l3_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* usb_l4_ick */
-static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel usb_l4_ick_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
-	{ .parent = NULL },
-};
-
-/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
-static struct clk usb_l4_ick = {	/* FS-USB interface clock */
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
-	.clksel		= usb_l4_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks.	Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ck = {		/* used both as an ick and fck */
-	.name		= "l4_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l4_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
-	.clksel		= l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * SSI is in L3 management domain, its direct parent is core not l3,
- * many core power domain entities are grouped into the L3 clock
- * domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
- *
- * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
- */
-static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_sst_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_sst_fck = {
-	.name		= "ssi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_sst_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/*
- * Presumably this is the same as SSI_ICLK.
- * TRM contradicts itself on what clockdomain SSI_ICLK is in
- */
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-
-/*
- * GFX clock domain
- *	Clocks:
- * GFX_FCLK, GFX_ICLK
- * GFX_CG1(2d), GFX_CG2(3d)
- *
- * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
- * The 2d and 3d clocks run at a hardware determined
- * divided value of fclk.
- *
- */
-/* XXX REVISIT: GFX clock is part of CONFIG_PARTICIPANT, no? doublecheck. */
-
-/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
-static const struct clksel gfx_fck_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_3d_fck = {
-	.name		= "gfx_3d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_2d_fck = {
-	.name		= "gfx_2d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_ick = {
-	.name		= "gfx_ick",		/* From l3 */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * Modem clock domain (2430)
- *	CLOCKS:
- *		MDM_OSC_CLK
- *		MDM_ICLK
- * These clocks are usable in chassis mode only.
- */
-static const struct clksel_rate mdm_ick_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE },
-	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
-	{ .div = 0 }
-};
-
-static const struct clksel mdm_ick_clksel[] = {
-	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mdm_ick = {		/* used both as a ick and fck */
-	.name		= "mdm_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2430_CLKSEL_MDM_MASK,
-	.clksel		= mdm_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk mdm_osc_ck = {
-	.name		= "mdm_osc_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &osc_ck,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * DSS clock domain
- * CLOCKs:
- * DSS_L4_ICLK, DSS_L3_ICLK,
- * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
- *
- * DSS is both initiator and target.
- */
-/* XXX Add RATE_NOT_VALIDATED */
-
-static const struct clksel_rate dss1_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss1_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel dss1_fck_clksel[] = {
-	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
-	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ck,	/* really both l3 and l4 */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_fck = {
-	.name		= "dss1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_ck,		/* Core or sys */
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
-	.clksel		= dss1_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate dss2_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss2_fck_48m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel dss2_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
-	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dss2_fck = {		/* Alt clk used in power management */
-	.name		= "dss2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
-	.clksel		= dss2_fck_clksel,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_54m_fck = {	/* Alt clk used in power management */
-	.name		= "dss_54m_fck",	/* 54m tv clk */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * CORE power domain ICLK & FCLK defines.
- * Many of the these can have more than one possible parent. Entries
- * here will likely have an L4 interface parent, and may have multiple
- * functional clock parents.
- */
-static const struct clksel_rate gpt_alt_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap24xx_gpt_clksel[] = {
-	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
-	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &secure_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_ick = {
-	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_fck = {
-	.name		= "gpios_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_ick = {
-	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_fck = {
-	.name		= "mpu_wdt_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sync_32k_ick = {
-	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
- * split into two separate clocks, since the parent clocks are different
- * and the clockdomains are also different.
- */
-static struct clk cam_fck = {
-	.name		= "cam_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_ick = {
-	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_fck = {
-	.name		= "wdt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_ick = {
-	.name		= "mmc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_fck = {
-	.name		= "mmc_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_fck = {
-	.name		= "fac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_ick = {
-	.name		= "eac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_fck = {
-	.name		= "eac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.id		= 2,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_fck = {
-	.name		= "sdma_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_ick = {
-	.name		= "sdma_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk vlynq_ick = {
-	.name		= "vlynq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate vlynq_fck_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate vlynq_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE },
-	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel vlynq_fck_clksel[] = {
-	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
-	{ .parent = &core_ck,	  .rates = vlynq_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk vlynq_fck = {
-	.name		= "vlynq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.flags		= DELAYED_APP,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2420_CLKSEL_VLYNQ_MASK,
-	.clksel		= vlynq_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des_ick = {
-	.name		= "des_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha_ick = {
-	.name		= "sha_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes_ick = {
-	.name		= "aes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_fck = {
-	.name		= "usb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhs_ick = {
-	.name		= "usbhs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_96m_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_fck = {
-	.name		= "gpio5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mdm_intc_ick = {
-	.name		= "mdm_intc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb1_fck = {
-	.name		= "mmchsdb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb2_fck = {
-	.name		= "mmchsdb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * This clock is a composite clock which does entire set changes then
- * forces a rebalance. It keys on the MPU speed, but it really could
- * be any key speed part of a set in the rate table.
- *
- * to really change a set, you need memory table sets which get changed
- * in sram, pre-notifiers & post notifiers, changing the top set, without
- * having low level display recalc's won't work... this is why dpm notifiers
- * work, isr's off, walk a list of clocks already _off_ and not messing with
- * the bus.
- *
- * This clock should have no parent. It embodies the entire upper level
- * active set. A parent will mess up some of the init also.
- */
-static struct clk virt_prcm_set = {
-	.name		= "virt_prcm_set",
-	.ops		= &clkops_null,
-	.flags		= DELAYED_APP,
-	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
-	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
-	.set_rate	= &omap2_select_table_rate,
-	.round_rate	= &omap2_round_to_table_rate,
-};
-
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,626 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock.c
+ *
+ *  Copyright (C) 2005-2008 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2008 Nokia Corporation
+ *
+ *  Contacts:
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Paul Walmsley
+ *
+ *  Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ *  Gordon McNutt and RidgeRun, 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.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+#include <linux/bitops.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/prcm.h>
+#include <plat/clkdev_omap.h>
+#include <asm/div64.h>
+#include <asm/clkdev.h>
+
+#include <plat/sdrc.h>
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+
+/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
+#define EN_APLL_STOPPED			0
+#define EN_APLL_LOCKED			3
+
+/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
+#define APLLS_CLKIN_19_2MHZ		0
+#define APLLS_CLKIN_13MHZ		2
+#define APLLS_CLKIN_12MHZ		3
+
+/* #define DOWN_VARIABLE_DPLL 1 */		/* Experimental */
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+struct clk *vclk, *sclk, *dclk;
+
+void __iomem *prcm_clksrc_ctrl;
+
+/*-------------------------------------------------------------------------
+ * Omap24xx specific clock functions
+ *-------------------------------------------------------------------------*/
+
+/**
+ * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ *
+ * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
+ * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
+ * passes back the correct CM_IDLEST register address for I2CHS
+ * modules.  No return value.
+ */
+static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+					   void __iomem **idlest_reg,
+					   u8 *idlest_bit)
+{
+	*idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
+	*idlest_bit = clk->enable_bit;
+}
+
+/* 2430 I2CHS has non-standard IDLEST register */
+const struct clkops clkops_omap2430_i2chs_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap2430_clk_i2chs_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+};
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate.  CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual).  This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+{
+	long long core_clk;
+	u32 v;
+
+	core_clk = omap2_get_dpll_rate(clk);
+
+	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if (v == CORE_CLK_SRC_32K)
+		core_clk = 32768;
+	else
+		core_clk *= v;
+
+	return core_clk;
+}
+
+static int omap2_enable_osc_ck(struct clk *clk)
+{
+	u32 pcc;
+
+	pcc = __raw_readl(prcm_clksrc_ctrl);
+
+	__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+
+	return 0;
+}
+
+static void omap2_disable_osc_ck(struct clk *clk)
+{
+	u32 pcc;
+
+	pcc = __raw_readl(prcm_clksrc_ctrl);
+
+	__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+}
+
+const struct clkops clkops_oscck = {
+	.enable		= omap2_enable_osc_ck,
+	.disable	= omap2_disable_osc_ck,
+};
+
+#ifdef OLD_CK
+/* Recalculate SYST_CLK */
+static void omap2_sys_clk_recalc(struct clk *clk)
+{
+	u32 div = PRCM_CLKSRC_CTRL;
+	div &= (1 << 7) | (1 << 6);	/* Test if ext clk divided by 1 or 2 */
+	div >>= clk->rate_offset;
+	clk->rate = (clk->parent->rate / div);
+	propagate_rate(clk);
+}
+#endif	/* OLD_CK */
+
+/* Enable an APLL if off */
+static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
+{
+	u32 cval, apll_mask;
+
+	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+	if ((cval & apll_mask) == apll_mask)
+		return 0;   /* apll already enabled */
+
+	cval &= ~apll_mask;
+	cval |= apll_mask;
+	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+
+	omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
+			     clk->name);
+
+	/*
+	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
+	 * fails?
+	 */
+	return 0;
+}
+
+static int omap2_clk_apll96_enable(struct clk *clk)
+{
+	return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
+}
+
+static int omap2_clk_apll54_enable(struct clk *clk)
+{
+	return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
+}
+
+/* Stop APLL */
+static void omap2_clk_apll_disable(struct clk *clk)
+{
+	u32 cval;
+
+	cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+	cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
+	cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+}
+
+const struct clkops clkops_apll96 = {
+	.enable		= omap2_clk_apll96_enable,
+	.disable	= omap2_clk_apll_disable,
+};
+
+const struct clkops clkops_apll54 = {
+	.enable		= omap2_clk_apll54_enable,
+	.disable	= omap2_clk_apll_disable,
+};
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+long omap2_dpllcore_round_rate(unsigned long target_rate)
+{
+	u32 high, low, core_clk_src;
+
+	core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if (core_clk_src == CORE_CLK_SRC_DPLL) {	/* DPLL clockout */
+		high = curr_prcm_set->dpll_speed * 2;
+		low = curr_prcm_set->dpll_speed;
+	} else {				/* DPLL clockout x 2 */
+		high = curr_prcm_set->dpll_speed;
+		low = curr_prcm_set->dpll_speed / 2;
+	}
+
+#ifdef DOWN_VARIABLE_DPLL
+	if (target_rate > high)
+		return high;
+	else
+		return target_rate;
+#else
+	if (target_rate > low)
+		return high;
+	else
+		return low;
+#endif
+
+}
+
+unsigned long omap2_dpllcore_recalc(struct clk *clk)
+{
+	return omap2xxx_clk_get_core_rate(clk);
+}
+
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+{
+	u32 cur_rate, low, mult, div, valid_rate, done_rate;
+	u32 bypass = 0;
+	struct prcm_config tmpset;
+	const struct dpll_data *dd;
+
+	cur_rate = omap2xxx_clk_get_core_rate(dclk);
+	mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+	if ((rate == (cur_rate / 2)) && (mult == 2)) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+	} else if (rate != cur_rate) {
+		valid_rate = omap2_dpllcore_round_rate(rate);
+		if (valid_rate != rate)
+			return -EINVAL;
+
+		if (mult == 1)
+			low = curr_prcm_set->dpll_speed;
+		else
+			low = curr_prcm_set->dpll_speed / 2;
+
+		dd = clk->dpll_data;
+		if (!dd)
+			return -EINVAL;
+
+		tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+		tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
+					   dd->div1_mask);
+		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+		tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+		tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
+		if (rate > low) {
+			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
+			mult = ((rate / 2) / 1000000);
+			done_rate = CORE_CLK_SRC_DPLL_X2;
+		} else {
+			tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
+			mult = (rate / 1000000);
+			done_rate = CORE_CLK_SRC_DPLL;
+		}
+		tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
+		tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
+
+		/* Worst case */
+		tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
+
+		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
+			bypass = 1;
+
+		/* For omap2xxx_sdrc_init_params() */
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+		/* Force dll lock mode */
+		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+			       bypass);
+
+		/* Errata: ret dll entry state */
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
+	}
+
+	return 0;
+}
+
+/**
+ * omap2_table_mpu_recalc - just return the MPU speed
+ * @clk: virt_prcm_set struct clk
+ *
+ * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
+ */
+unsigned long omap2_table_mpu_recalc(struct clk *clk)
+{
+	return curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+	const struct prcm_config *ptr;
+	long highest_rate;
+	long sys_ck_rate;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	highest_rate = -EINVAL;
+
+	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+		if (!(ptr->flags & cpu_mask))
+			continue;
+		if (ptr->xtal_speed != sys_ck_rate)
+			continue;
+
+		highest_rate = ptr->mpu_speed;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->mpu_speed <= rate)
+			break;
+	}
+	return highest_rate;
+}
+
+/* Sets basic clocks based on the specified rate */
+int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+{
+	u32 cur_rate, done_rate, bypass = 0, tmp;
+	const struct prcm_config *prcm;
+	unsigned long found_speed = 0;
+	unsigned long flags;
+	long sys_ck_rate;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		if (prcm->mpu_speed <= rate) {
+			found_speed = prcm->mpu_speed;
+			break;
+		}
+	}
+
+	if (!found_speed) {
+		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+		       rate / 1000000);
+		return -EINVAL;
+	}
+
+	curr_prcm_set = prcm;
+	cur_rate = omap2xxx_clk_get_core_rate(dclk);
+
+	if (prcm->dpll_speed == cur_rate / 2) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+	} else if (prcm->dpll_speed == cur_rate * 2) {
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+	} else if (prcm->dpll_speed != cur_rate) {
+		local_irq_save(flags);
+
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			bypass = 1;
+
+		if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
+		    CORE_CLK_SRC_DPLL_X2)
+			done_rate = CORE_CLK_SRC_DPLL_X2;
+		else
+			done_rate = CORE_CLK_SRC_DPLL;
+
+		/* MPU divider */
+		cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+
+		/* dsp + iva1 div(2420), iva2.1(2430) */
+		cm_write_mod_reg(prcm->cm_clksel_dsp,
+				 OMAP24XX_DSP_MOD, CM_CLKSEL);
+
+		cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+
+		/* Major subsystem dividers */
+		tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+		cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+				 CM_CLKSEL1);
+
+		if (cpu_is_omap2430())
+			cm_write_mod_reg(prcm->cm_clksel_mdm,
+					 OMAP2430_MDM_MOD, CM_CLKSEL);
+
+		/* x2 to enter omap2xxx_sdrc_init_params() */
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+			       bypass);
+
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
+
+		local_irq_restore(flags);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ * XXX This should be replaced by an OPP layer in the near future
+ */
+static struct cpufreq_frequency_table *freq_table;
+
+void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+	const struct prcm_config *prcm;
+	long sys_ck_rate;
+	int i = 0;
+	int tbl_sz = 0;
+
+	sys_ck_rate = clk_get_rate(sclk);
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		/* don't put bypass rates in table */
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			continue;
+
+		tbl_sz++;
+	}
+
+	/*
+	 * XXX Ensure that we're doing what CPUFreq expects for this error
+	 * case and the following one
+	 */
+	if (tbl_sz == 0) {
+		pr_warning("%s: no matching entries in rate_table\n",
+			   __func__);
+		return;
+	}
+
+	/* Include the CPUFREQ_TABLE_END terminator entry */
+	tbl_sz++;
+
+	freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
+			     GFP_ATOMIC);
+	if (!freq_table) {
+		pr_err("%s: could not kzalloc frequency table\n", __func__);
+		return;
+	}
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck_rate)
+			continue;
+
+		/* don't put bypass rates in table */
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			continue;
+
+		freq_table[i].index = i;
+		freq_table[i].frequency = prcm->mpu_speed / 1000;
+		i++;
+	}
+
+	freq_table[i].index = i;
+	freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+	*table = &freq_table[0];
+}
+
+void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+	kfree(freq_table);
+}
+
+#endif
+
+struct clk_functions omap2_clk_functions = {
+	.clk_enable		= omap2_clk_enable,
+	.clk_disable		= omap2_clk_disable,
+	.clk_round_rate		= omap2_clk_round_rate,
+	.clk_set_rate		= omap2_clk_set_rate,
+	.clk_set_parent		= omap2_clk_set_parent,
+	.clk_disable_unused	= omap2_clk_disable_unused,
+#ifdef	CONFIG_CPU_FREQ
+	.clk_init_cpufreq_table	= omap2_clk_init_cpufreq_table,
+	.clk_exit_cpufreq_table	= omap2_clk_exit_cpufreq_table,
+#endif
+};
+
+static u32 omap2_get_apll_clkin(void)
+{
+	u32 aplls, srate = 0;
+
+	aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+	aplls &= OMAP24XX_APLLS_CLKIN_MASK;
+	aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
+
+	if (aplls == APLLS_CLKIN_19_2MHZ)
+		srate = 19200000;
+	else if (aplls == APLLS_CLKIN_13MHZ)
+		srate = 13000000;
+	else if (aplls == APLLS_CLKIN_12MHZ)
+		srate = 12000000;
+
+	return srate;
+}
+
+static u32 omap2_get_sysclkdiv(void)
+{
+	u32 div;
+
+	div = __raw_readl(prcm_clksrc_ctrl);
+	div &= OMAP_SYSCLKDIV_MASK;
+	div >>= OMAP_SYSCLKDIV_SHIFT;
+
+	return div;
+}
+
+unsigned long omap2_osc_clk_recalc(struct clk *clk)
+{
+	return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
+}
+
+unsigned long omap2_sys_clk_recalc(struct clk *clk)
+{
+	return clk->parent->rate / omap2_get_sysclkdiv();
+}
+
+/*
+ * Set clocks for bypass mode for reboot to work.
+ */
+void omap2_clk_prepare_for_reboot(void)
+{
+	u32 rate;
+
+	if (vclk == NULL || sclk == NULL)
+		return;
+
+	rate = clk_get_rate(sclk);
+	clk_set_rate(vclk, rate);
+}
+
+/*
+ * Switch the MPU rate if specified on cmdline.
+ * We cannot do this early until cmdline is parsed.
+ */
+static int __init omap2_clk_arch_init(void)
+{
+	struct clk *virt_prcm_set, *sys_ck, *dpll_ck, *mpu_ck;
+	unsigned long sys_ck_rate;
+
+	if (!mpurate)
+		return -EINVAL;
+
+	virt_prcm_set = clk_get(NULL, "virt_prcm_set");
+	sys_ck = clk_get(NULL, "sys_ck");
+	dpll_ck = clk_get(NULL, "dpll_ck");
+	mpu_ck = clk_get(NULL, "mpu_ck");
+
+	if (clk_set_rate(virt_prcm_set, mpurate))
+		printk(KERN_ERR "Could not find matching MPU rate\n");
+
+	recalculate_root_clocks();
+
+	sys_ck_rate = clk_get_rate(sys_ck);
+
+	pr_info("Switched to new clocking rate (Crystal/DPLL/MPU): "
+		"%ld.%01ld/%ld/%ld MHz\n",
+		(sys_ck_rate / 1000000), (sys_ck_rate / 100000) % 10,
+		(clk_get_rate(dpll_ck) / 1000000),
+		(clk_get_rate(mpu_ck) / 1000000));
+
+	return 0;
+}
+arch_initcall(omap2_clk_arch_init);
+
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2309 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock2xxx_data.c
+ *
+ *  Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2009 Nokia Corporation
+ *
+ *  Contacts:
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Paul Walmsley
+ *
+ * This 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/kernel.h>
+#include <linux/clk.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "prm.h"
+#include "cm.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+
+/*-------------------------------------------------------------------------
+ * 24xx clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent.	In many
+ *	cases the parent is selectable.	The get/set parent calls will also
+ *	switch sources.
+ *
+ *	Many some clocks say always_enabled, but they can be auto idled for
+ *	power savings. They will always be available upon clock request.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most periferals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ *-------------------------------------------------------------------------*/
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+	.name		= "func_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32000,
+	.flags		= RATE_FIXED,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+	.name		= "secure_32k_ck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.flags		= RATE_FIXED,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
+	.name		= "osc_ck",
+	.ops		= &clkops_oscck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
+	.name		= "sys_ck",		/* ~ ref_clk also */
+	.ops		= &clkops_null,
+	.parent		= &osc_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_sys_clk_recalc,
+};
+
+static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
+	.name		= "alt_ck",
+	.ops		= &clkops_null,
+	.rate		= 54000000,
+	.flags		= RATE_FIXED,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
+	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
+	.clk_bypass		= &sys_ck,
+	.clk_ref		= &sys_ck,
+	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
+	.max_multiplier		= 1024,
+	.min_divider		= 1,
+	.max_divider		= 16,
+	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+	.name		= "dpll_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,		/* Can be func_32k also */
+	.dpll_data	= &dpll_dd,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_dpllcore_recalc,
+	.set_rate	= &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+	.name		= "apll96_ck",
+	.ops		= &clkops_apll96,
+	.parent		= &sys_ck,
+	.rate		= 96000000,
+	.flags		= RATE_FIXED | ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+	.name		= "apll54_ck",
+	.ops		= &clkops_apll54,
+	.parent		= &sys_ck,
+	.rate		= 54000000,
+	.flags		= RATE_FIXED | ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
+	{ .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+	.name		= "func_54m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll54_ck,	/* can also be alt_clk */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_54M_SOURCE,
+	.clksel		= func_54m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll_ck,		/* can also be 32k */
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* func_96m_ck */
+static const struct clksel_rate func_96m_apll96_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_96m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_243X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_96m_clksel[] = {
+	{ .parent = &apll96_ck,	.rates = func_96m_apll96_rates },
+	{ .parent = &alt_ck,	.rates = func_96m_alt_rates },
+	{ .parent = NULL }
+};
+
+/* The parent of this clock is not selectable on 2420. */
+static struct clk func_96m_ck = {
+	.name		= "func_96m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP2430_96M_SOURCE,
+	.clksel		= func_96m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
+	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+	.name		= "func_48m_ck",
+	.ops		= &clkops_null,
+	.parent		= &apll96_ck,	 /* 96M or Alt */
+	.clkdm_name	= "wkup_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_48M_SOURCE,
+	.clksel		= func_48m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+	.name		= "func_12m_ck",
+	.ops		= &clkops_null,
+	.parent		= &func_48m_ck,
+	.fixed_div	= 4,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+	.name		= "ck_wdt1_osc",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &osc_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
+	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
+	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+	.name		= "sys_clkout_src",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
+	.clksel		= common_clkout_src_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
+	{ .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+	.name		= "sys_clkout",
+	.ops		= &clkops_null,
+	.parent		= &sys_clkout_src,
+	.clkdm_name	= "wkup_clkdm",
+	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
+	.clksel		= sys_clkout_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2_src = {
+	.name		= "sys_clkout2_src",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP2420_CLKOUT2_SOURCE_MASK,
+	.clksel		= common_clkout_src_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+	{ .parent = &sys_clkout2_src, .rates = common_clkout_rates },
+	{ .parent = NULL }
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+	.name		= "sys_clkout2",
+	.ops		= &clkops_null,
+	.parent		= &sys_clkout2_src,
+	.clkdm_name	= "wkup_clkdm",
+	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
+	.clksel		= sys_clkout2_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+	.name		= "emul_ck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP24XX_PRCM_CLKEMUL_CTRL,
+	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
+	.recalc		= &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ *	Clocks:
+ *		MPU_FCLK, MPU_ICLK
+ *		INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+	{ .parent = &core_ck, .rates = mpu_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mpu_ck = {	/* Control cpu */
+	.name		= "mpu_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clkdm_name	= "mpu_clkdm",
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
+	.clksel		= mpu_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/*
+ * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
+ * Clocks:
+ *	2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
+ *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+	.name		= "dsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clkdm_name	= "dsp_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
+	.clksel		= dsp_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* DSP interface clock */
+static const struct clksel_rate dsp_irate_ick_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_243X },
+	{ .div = 0 },
+};
+
+static const struct clksel dsp_irate_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+	{ .parent = NULL }
+};
+
+/* This clock does not exist as such in the TRM. */
+static struct clk dsp_irate_ick = {
+	.name		= "dsp_irate_ick",
+	.ops		= &clkops_null,
+	.parent		= &dsp_fck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
+	.clksel		= dsp_irate_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	      = &omap2_clksel_set_rate
+};
+
+/* 2420 only */
+static struct clk dsp_ick = {
+	.name		= "dsp_ick",	 /* apparently ipi and isp */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dsp_irate_ick,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
+};
+
+/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
+static struct clk iva2_1_ick = {
+	.name		= "iva2_1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dsp_irate_ick,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+};
+
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain.  Does not
+ * exist on later OMAPs.
+ */
+static struct clk iva1_ifck = {
+	.name		= "iva1_ifck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.flags		= CONFIG_PARTICIPANT | DELAYED_APP,
+	.clkdm_name	= "iva1_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2420_EN_IVA_COP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP2420_CLKSEL_IVA_MASK,
+	.clksel		= dsp_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+	.name		= "iva1_mpu_int_ifck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &iva1_ifck,
+	.clkdm_name	= "iva1_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
+	.fixed_div	= 2,
+	.recalc		= &omap2_fixed_divisor_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ *	CAM, HS-USB.
+ * F-CLOCK
+ *	SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+	{ .parent = &core_ck, .rates = core_l3_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
+	.name		= "core_l3_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clkdm_name	= "core_l3_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
+	.clksel		= core_l3_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+	{ .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = {	/* FS-USB interface clock */
+	.name		= "usb_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
+	.clksel		= usb_l4_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks.	Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l4_ck = {		/* used both as an ick and fck */
+	.name		= "l4_ck",
+	.ops		= &clkops_null,
+	.parent		= &core_l3_ck,
+	.flags		= DELAYED_APP,
+	.clkdm_name	= "core_l4_clkdm",
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
+	.clksel		= l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+	.name		= "ssi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.flags		= DELAYED_APP,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_sst_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ *	Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+/* XXX REVISIT: GFX clock is part of CONFIG_PARTICIPANT, no? doublecheck. */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+	.name		= "gfx_3d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gfx_2d_fck = {
+	.name		= "gfx_2d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gfx_ick = {
+	.name		= "gfx_ick",		/* From l3 */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "gfx_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * Modem clock domain (2430)
+ *	CLOCKS:
+ *		MDM_OSC_CLK
+ *		MDM_ICLK
+ * These clocks are usable in chassis mode only.
+ */
+static const struct clksel_rate mdm_ick_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_243X | DEFAULT_RATE },
+	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
+	{ .div = 0 }
+};
+
+static const struct clksel mdm_ick_clksel[] = {
+	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mdm_ick = {		/* used both as a ick and fck */
+	.name		= "mdm_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_ck,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
+	.clkdm_name	= "mdm_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP2430_CLKSEL_MDM_MASK,
+	.clksel		= mdm_ick_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk mdm_osc_ck = {
+	.name		= "mdm_osc_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &osc_ck,
+	.clkdm_name	= "mdm_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+/* XXX Add RATE_NOT_VALIDATED */
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
+	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,	/* really both l3 and l4 */
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+	.name		= "dss1_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_ck,		/* Core or sys */
+	.flags		= DELAYED_APP,
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
+	.clksel		= dss1_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel dss2_fck_clksel[] = {
+	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
+	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dss2_fck = {		/* Alt clk used in power management */
+	.name		= "dss2_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
+	.flags		= DELAYED_APP,
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
+	.clksel		= dss2_fck_clksel,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_54m_fck = {	/* Alt clk used in power management */
+	.name		= "dss_54m_fck",	/* 54m tv clk */
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_54m_ck,
+	.clkdm_name	= "dss_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static const struct clksel_rate gpt_alt_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
+	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &secure_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
+	.clksel		= omap24xx_gpt_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 5,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 5,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+	.name		= "gpios_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+	.name		= "gpios_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+	.name		= "mpu_wdt_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+	.name		= "mpu_wdt_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+	.name		= "sync_32k_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk icr_ick = {
+	.name		= "icr_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
+static struct clk cam_fck = {
+	.name		= "cam_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+	.name		= "wdt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+	.name		= "wdt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+	.name		= "wdt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc_ick = {
+	.name		= "mmc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc_fck = {
+	.name		= "mmc_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_fck = {
+	.name		= "fac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk eac_ick = {
+	.name		= "eac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk eac_fck = {
+	.name		= "eac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2chs2_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2430_i2chs_wait,
+	.id		= 2,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &func_12m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2chs1_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2430_i2chs_wait,
+	.id		= 1,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+	.name		= "gpmc_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_fck = {
+	.name		= "sdma_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdma_ick = {
+	.name		= "sdma_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk vlynq_ick = {
+	.name		= "vlynq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel_rate vlynq_fck_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_242X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate vlynq_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
+	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_242X | DEFAULT_RATE },
+	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel vlynq_fck_clksel[] = {
+	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
+	{ .parent = &core_ck,	  .rates = vlynq_fck_core_rates },
+	{ .parent = NULL }
+};
+
+static struct clk vlynq_fck = {
+	.name		= "vlynq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.flags		= DELAYED_APP,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP2420_CLKSEL_VLYNQ_MASK,
+	.clksel		= vlynq_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate
+};
+
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des_ick = {
+	.name		= "des_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha_ick = {
+	.name		= "sha_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes_ick = {
+	.name		= "aes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_fck = {
+	.name		= "usb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_48m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhs_ick = {
+	.name		= "usbhs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_96m_ck,
+	.clkdm_name	= "core_l3_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &func_96m_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_fck = {
+	.name		= "gpio5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mdm_intc_ick = {
+	.name		= "mdm_intc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchsdb1_fck = {
+	.name		= "mmchsdb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchsdb2_fck = {
+	.name		= "mmchsdb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &func_32k_ck,
+	.clkdm_name	= "core_l4_clkdm",
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+	.name		= "virt_prcm_set",
+	.ops		= &clkops_null,
+	.flags		= DELAYED_APP,
+	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
+	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap24xx_clks[] = {
+	/* external root sources */
+	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X),
+	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X | CK_242X),
+	/* internal analog sources */
+	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X | CK_242X),
+	/* internal prcm root sources */
+	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X),
+	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X | CK_242X),
+	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X),
+	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_242X),
+	CLK(NULL,	"emul_ck",	&emul_ck,	CK_242X),
+	/* mpu domain clocks */
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X | CK_242X),
+	/* dsp domain clocks */
+	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X),
+	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
+	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
+	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
+	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
+	/* GFX domain clocks */
+	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X | CK_242X),
+	/* Modem domain clocks */
+	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
+	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
+	/* DSS domain clocks */
+	CLK("omapdss",	"ick",		&dss_ick,	CK_243X | CK_242X),
+	CLK("omapdss",	"dss1_fck",	&dss1_fck,	CK_243X | CK_242X),
+	CLK("omapdss",	"dss2_fck",	&dss2_fck,	CK_243X | CK_242X),
+	CLK("omapdss",	"tv_fck",	&dss_54m_fck,	CK_243X | CK_242X),
+	/* L3 domain clocks */
+	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X | CK_242X),
+	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X | CK_242X),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X | CK_242X),
+	/* L4 domain clocks */
+	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X | CK_242X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X | CK_242X),
+	/* virtual meta-group clock */
+	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X),
+	/* general l4 interface ck, multi-parent functional clk */
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X | CK_242X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X | CK_242X),
+	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_243X | CK_242X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X | CK_242X),
+	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_243X | CK_242X),
+	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_243X),
+	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_243X),
+	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_243X),
+	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_243X),
+	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_243X),
+	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_243X),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_243X | CK_242X),
+	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_243X | CK_242X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X | CK_242X),
+	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_243X | CK_242X),
+	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_243X),
+	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_243X),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X | CK_242X),
+	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X | CK_242X),
+	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
+	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X | CK_242X),
+	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_242X),
+	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_242X),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X | CK_242X),
+	CLK("mmci-omap.0", "ick",	&mmc_ick,	CK_242X),
+	CLK("mmci-omap.0", "fck",	&mmc_fck,	CK_242X),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"eac_ick",	&eac_ick,	CK_242X),
+	CLK(NULL,	"eac_fck",	&eac_fck,	CK_242X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X | CK_242X),
+	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X | CK_242X),
+	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_243X | CK_242X),
+	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_242X),
+	CLK("i2c_omap.1", "fck",	&i2chs1_fck,	CK_243X),
+	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_243X | CK_242X),
+	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_242X),
+	CLK("i2c_omap.2", "fck",	&i2chs2_fck,	CK_243X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X | CK_242X),
+	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
+	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
+	CLK(NULL,	"des_ick",	&des_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"sha_ick",	&sha_ick,	CK_243X | CK_242X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"aes_ick",	&aes_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X | CK_242X),
+	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X | CK_242X),
+	CLK("musb_hdrc",	"ick",	&usbhs_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "ick",	&mmchs1_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "fck",	&mmchs1_fck,	CK_243X),
+	CLK("mmci-omap-hs.1", "ick",	&mmchs2_ick,	CK_243X),
+	CLK("mmci-omap-hs.1", "fck",	&mmchs2_fck,	CK_243X),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
+	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
+	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
+	CLK("mmci-omap-hs.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
+	CLK("mmci-omap-hs.1", "mmchsdb_fck", 	&mmchsdb2_fck,	CK_243X),
+};
+
+/*
+ * init code
+ */
+
+int __init omap2_clk_init(void)
+{
+	const struct prcm_config *prcm;
+	struct omap_clk *c;
+	u32 clkrate;
+	u16 cpu_clkflg;
+
+	if (cpu_is_omap242x()) {
+		prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
+		cpu_mask = RATE_IN_242X;
+		cpu_clkflg = CK_242X;
+		rate_table = omap2420_rate_table;
+	} else if (cpu_is_omap2430()) {
+		prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
+		cpu_mask = RATE_IN_243X;
+		cpu_clkflg = CK_243X;
+		rate_table = omap2430_rate_table;
+	}
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+		clk_preinit(c->lk.clk);
+
+	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+	propagate_rate(&osc_ck);
+	sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
+	propagate_rate(&sys_ck);
+
+	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			clk_register(c->lk.clk);
+			omap2_init_clk_clkdm(c->lk.clk);
+		}
+
+	/* Check the MPU rate set by bootloader */
+	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+		if (prcm->dpll_speed <= clkrate)
+			break;
+	}
+	curr_prcm_set = prcm;
+
+	recalculate_root_clocks();
+
+	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
+	       "%ld.%01ld/%ld/%ld MHz\n",
+	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	/* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+	vclk = clk_get(NULL, "virt_prcm_set");
+	sclk = clk_get(NULL, "sys_ck");
+	dclk = clk_get(NULL, "dpll_ck");
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock2xxx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock2xxx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * OMAP2 clock function prototypes and macros
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_24XX_H
+
+unsigned long omap2_table_mpu_recalc(struct clk *clk);
+int omap2_select_table_rate(struct clk *clk, unsigned long rate);
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
+unsigned long omap2_sys_clk_recalc(struct clk *clk);
+unsigned long omap2_osc_clk_recalc(struct clk *clk);
+unsigned long omap2_sys_clk_recalc(struct clk *clk);
+unsigned long omap2_dpllcore_recalc(struct clk *clk);
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
+
+/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
+#ifdef CONFIG_ARCH_OMAP2420
+#define OMAP_CM_REGADDR			OMAP2420_CM_REGADDR
+#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2420_PRCM_CLKOUT_CTRL
+#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2420_PRCM_CLKEMUL_CTRL
+#else
+#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
+#define OMAP24XX_PRCM_CLKOUT_CTRL	OMAP2430_PRCM_CLKOUT_CTRL
+#define OMAP24XX_PRCM_CLKEMUL_CTRL	OMAP2430_PRCM_CLKEMUL_CTRL
+#endif
+
+extern void __iomem *prcm_clksrc_ctrl;
+
+extern struct clk *dclk;
+
+extern const struct clkops clkops_omap2430_i2chs_wait;
+extern const struct clkops clkops_oscck;
+extern const struct clkops clkops_apll96;
+extern const struct clkops clkops_apll54;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,317 +27,23 @@
 #include <linux/limits.h>
 #include <linux/bitops.h>
 
-#include <mach/cpu.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
 #include <asm/div64.h>
 #include <asm/clkdev.h>
 
-#include <mach/sdrc.h>
 #include "clock.h"
+#include "clock34xx.h"
+#include "sdrc.h"
 #include "prm.h"
 #include "prm-regbits-34xx.h"
 #include "cm.h"
 #include "cm-regbits-34xx.h"
 
-static const struct clkops clkops_noncore_dpll_ops;
-
-static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
-					    void __iomem **idlest_reg,
-					    u8 *idlest_bit);
-static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
-					    void __iomem **idlest_reg,
-					    u8 *idlest_bit);
-static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
-						    void __iomem **idlest_reg,
-						    u8 *idlest_bit);
-
-static const struct clkops clkops_omap3430es2_ssi_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-static const struct clkops clkops_omap3430es2_hsotgusb_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-static const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-#include "clock34xx.h"
-
-struct omap_clk {
-	u32		cpu;
-	struct clk_lookup lk;
-};
-
-#define CLK(dev, con, ck, cp) 		\
-	{				\
-		 .cpu = cp,		\
-		.lk = {			\
-			.dev_id = dev,	\
-			.con_id = con,	\
-			.clk = ck,	\
-		},			\
-	}
-
-#define CK_343X		(1 << 0)
-#define CK_3430ES1	(1 << 1)
-#define CK_3430ES2	(1 << 2)
-
-static struct omap_clk omap34xx_clks[] = {
-	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_343X),
-	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_343X),
-	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_343X),
-	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2),
-	CLK(NULL,	"virt_19_2m_ck", &virt_19_2m_ck, CK_343X),
-	CLK(NULL,	"virt_26m_ck",	&virt_26m_ck,	CK_343X),
-	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_343X),
-	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_343X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_343X),
-	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_343X),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_343X),
-	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_343X),
-	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_343X),
-	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_343X),
-	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_343X),
-	CLK(NULL,	"dpll2_ck",	&dpll2_ck,	CK_343X),
-	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_ck",	&dpll3_ck,	CK_343X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_343X),
-	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
-	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_343X),
-	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
-	CLK(NULL,	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_343X),
-	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_343X),
-	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
-	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_343X),
-	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_343X),
-	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_343X),
-	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_343X),
-	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_343X),
-	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
-	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_343X),
-	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
-	CLK(NULL,	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2),
-	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2),
-	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_343X),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_343X),
-	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_343X),
-	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_343X),
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_343X),
-	CLK(NULL,	"arm_fck",	&arm_fck,	CK_343X),
-	CLK(NULL,	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
-	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_343X),
-	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_343X),
-	CLK(NULL,	"l3_ick",	&l3_ick,	CK_343X),
-	CLK(NULL,	"l4_ick",	&l4_ick,	CK_343X),
-	CLK(NULL,	"rm_ick",	&rm_ick,	CK_343X),
-	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck,	CK_3430ES1),
-	CLK(NULL,	"sgx_fck",	&sgx_fck,	CK_3430ES2),
-	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2),
-	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
-	CLK(NULL,	"modem_fck",	&modem_fck,	CK_343X),
-	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_343X),
-	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_343X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_343X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_343X),
-	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2),
-	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2),
-	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2),
-	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_343X),
-	CLK("mmci-omap-hs.2",	"fck",	&mmchs3_fck,	CK_3430ES2),
-	CLK("mmci-omap-hs.1",	"fck",	&mmchs2_fck,	CK_343X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_343X),
-	CLK("mmci-omap-hs.0",	"fck",	&mmchs1_fck,	CK_343X),
-	CLK("i2c_omap.3", "fck",	&i2c3_fck,	CK_343X),
-	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_343X),
-	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_343X),
-	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_343X),
-	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_343X),
-	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_343X),
-	CLK("omap2_mcspi.4", "fck",	&mcspi4_fck,	CK_343X),
-	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_343X),
-	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_343X),
-	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_343X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_343X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_343X),
-	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
-	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_343X),
-	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_343X),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2),
-	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_343X),
-	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
-	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_343X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_343X),
-	CLK(NULL,	"security_l3_ick", &security_l3_ick, CK_343X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_343X),
-	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_343X),
-	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2),
-	CLK("mmci-omap-hs.2",	"ick",	&mmchs3_ick,	CK_3430ES2),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_343X),
-	CLK(NULL,	"aes2_ick",	&aes2_ick,	CK_343X),
-	CLK(NULL,	"sha12_ick",	&sha12_ick,	CK_343X),
-	CLK(NULL,	"des2_ick",	&des2_ick,	CK_343X),
-	CLK("mmci-omap-hs.1",	"ick",	&mmchs2_ick,	CK_343X),
-	CLK("mmci-omap-hs.0",	"ick",	&mmchs1_ick,	CK_343X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_343X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_343X),
-	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_343X),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_343X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_343X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_343X),
-	CLK("i2c_omap.3", "ick",	&i2c3_ick,	CK_343X),
-	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_343X),
-	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_343X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_343X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_343X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_343X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_343X),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_343X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_343X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_343X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_343X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_343X),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
-	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_343X),
-	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_343X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_343X),
-	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_343X),
-	CLK(NULL,	"des1_ick",	&des1_ick,	CK_343X),
-	CLK("omapfb",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
-	CLK("omapfb",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2),
-	CLK("omapfb",	"tv_fck",	&dss_tv_fck,	CK_343X),
-	CLK("omapfb",	"video_fck",	&dss_96m_fck,	CK_343X),
-	CLK("omapfb",	"dss2_fck",	&dss2_alwon_fck, CK_343X),
-	CLK("omapfb",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
-	CLK("omapfb",	"ick",		&dss_ick_3430es2,	CK_3430ES2),
-	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_343X),
-	CLK(NULL,	"cam_ick",	&cam_ick,	CK_343X),
-	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_343X),
-	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2),
-	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2),
-	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2),
-	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_343X),
-	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_343X),
-	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_343X),
-	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_343X),
-	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_343X),
-	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2),
-	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_343X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_343X),
-	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_343X),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_343X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_343X),
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_343X),
-	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_343X),
-	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_343X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_343X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_343X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_343X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_343X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_343X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_343X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_343X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_343X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_343X),
-	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_343X),
-	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_343X),
-	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_343X),
-	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_343X),
-	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_343X),
-	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_343X),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_343X),
-	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_343X),
-	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_343X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_343X),
-	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_343X),
-	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_343X),
-	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_343X),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_343X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_343X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_343X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_343X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_343X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_343X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_343X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_343X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_343X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_343X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_343X),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_343X),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_343X),
-	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_343X),
-	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_343X),
-	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_343X),
-	CLK(NULL,	"emu_src_ck",	&emu_src_ck,	CK_343X),
-	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_343X),
-	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_343X),
-	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_343X),
-	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_343X),
-	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_343X),
-	CLK(NULL,	"sr1_fck",	&sr1_fck,	CK_343X),
-	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_343X),
-	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_343X),
-	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_343X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_343X),
-	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_343X),
-};
-
-/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
-#define DPLL_AUTOIDLE_DISABLE			0x0
-#define DPLL_AUTOIDLE_LOW_POWER_STOP		0x1
-
-#define MAX_DPLL_WAIT_TRIES		1000000
-
-#define MIN_SDRC_DLL_LOCK_FREQ		83000000
-
 #define CYCLES_PER_MHZ			1000000
 
-/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */
-#define SDRC_MPURATE_SCALE		8
-
-/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */
-#define SDRC_MPURATE_BASE_SHIFT		9
-
-/*
- * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at
- * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize
- */
-#define SDRC_MPURATE_LOOPS		96
-
 /*
  * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
  * that are sourced by DPLL5, and both of these require this clock
@@ -345,6 +51,9 @@ static struct omap_clk omap34xx_clks[] =
  */
 #define DPLL5_FREQ_FOR_USBHOST		120000000
 
+/* needed by omap3_core_dpll_m2_set_rate() */
+struct clk *sdrc_ick_p, *arm_fck_p;
+
 /**
  * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
  * @clk: struct clk * being enabled
@@ -366,6 +75,13 @@ static void omap3430es2_clk_ssi_find_idl
 	*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
 }
 
+const struct clkops clkops_omap3430es2_ssi_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+};
+
 /**
  * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST
  * @clk: struct clk * being enabled
@@ -391,6 +107,13 @@ static void omap3430es2_clk_dss_usbhost_
 	*idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
 }
 
+const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+};
+
 /**
  * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB
  * @clk: struct clk * being enabled
@@ -412,395 +135,19 @@ static void omap3430es2_clk_hsotgusb_fin
 	*idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
 }
 
-/**
- * omap3_dpll_recalc - recalculate DPLL rate
- * @clk: DPLL struct clk
- *
- * Recalculate and propagate the DPLL rate.
- */
-static unsigned long omap3_dpll_recalc(struct clk *clk)
-{
-	return omap2_get_dpll_rate(clk);
-}
-
-/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
-static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->control_reg);
-	v &= ~dd->enable_mask;
-	v |= clken_bits << __ffs(dd->enable_mask);
-	__raw_writel(v, dd->control_reg);
-}
-
-/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
-static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
-{
-	const struct dpll_data *dd;
-	int i = 0;
-	int ret = -EINVAL;
-
-	dd = clk->dpll_data;
-
-	state <<= __ffs(dd->idlest_mask);
-
-	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
-	       i < MAX_DPLL_WAIT_TRIES) {
-		i++;
-		udelay(1);
-	}
-
-	if (i == MAX_DPLL_WAIT_TRIES) {
-		printk(KERN_ERR "clock: %s failed transition to '%s'\n",
-		       clk->name, (state) ? "locked" : "bypassed");
-	} else {
-		pr_debug("clock: %s transition to '%s' in %d loops\n",
-			 clk->name, (state) ? "locked" : "bypassed", i);
-
-		ret = 0;
-	}
-
-	return ret;
-}
-
-/* From 3430 TRM ES2 4.7.6.2 */
-static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
-{
-	unsigned long fint;
-	u16 f = 0;
-
-	fint = clk->dpll_data->clk_ref->rate / n;
-
-	pr_debug("clock: fint is %lu\n", fint);
-
-	if (fint >= 750000 && fint <= 1000000)
-		f = 0x3;
-	else if (fint > 1000000 && fint <= 1250000)
-		f = 0x4;
-	else if (fint > 1250000 && fint <= 1500000)
-		f = 0x5;
-	else if (fint > 1500000 && fint <= 1750000)
-		f = 0x6;
-	else if (fint > 1750000 && fint <= 2100000)
-		f = 0x7;
-	else if (fint > 7500000 && fint <= 10000000)
-		f = 0xB;
-	else if (fint > 10000000 && fint <= 12500000)
-		f = 0xC;
-	else if (fint > 12500000 && fint <= 15000000)
-		f = 0xD;
-	else if (fint > 15000000 && fint <= 17500000)
-		f = 0xE;
-	else if (fint > 17500000 && fint <= 21000000)
-		f = 0xF;
-	else
-		pr_debug("clock: unknown freqsel setting for %d\n", n);
-
-	return f;
-}
-
-/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
-
-/*
- * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to lock.  Waits for the DPLL to report
- * readiness before returning.  Will save and restore the DPLL's
- * autoidle state across the enable, per the CDP code.  If the DPLL
- * locked successfully, return 0; if the DPLL did not lock in the time
- * allotted, or DPLL3 was passed in, return -EINVAL.
- */
-static int _omap3_noncore_dpll_lock(struct clk *clk)
-{
-	u8 ai;
-	int r;
-
-	if (clk == &dpll3_ck)
-		return -EINVAL;
-
-	pr_debug("clock: locking DPLL %s\n", clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	omap3_dpll_deny_idle(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOCKED);
-
-	r = _omap3_wait_dpll_status(clk, 1);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-
-	return r;
-}
-
-/*
- * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
- * bypass mode, the DPLL's rate is set equal to its parent clock's
- * rate.  Waits for the DPLL to report readiness before returning.
- * Will save and restore the DPLL's autoidle state across the enable,
- * per the CDP code.  If the DPLL entered bypass mode successfully,
- * return 0; if the DPLL did not enter bypass in the time allotted, or
- * DPLL3 was passed in, or the DPLL does not support low-power bypass,
- * return -EINVAL.
- */
-static int _omap3_noncore_dpll_bypass(struct clk *clk)
-{
-	int r;
-	u8 ai;
-
-	if (clk == &dpll3_ck)
-		return -EINVAL;
-
-	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
-		return -EINVAL;
-
-	pr_debug("clock: configuring DPLL %s for low-power bypass\n",
-		 clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
-
-	r = _omap3_wait_dpll_status(clk, 0);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-	else
-		omap3_dpll_deny_idle(clk);
-
-	return r;
-}
-
-/*
- * _omap3_noncore_dpll_stop - instruct a DPLL to stop
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enter low-power stop. Will save and
- * restore the DPLL's autoidle state across the stop, per the CDP
- * code.  If DPLL3 was passed in, or the DPLL does not support
- * low-power stop, return -EINVAL; otherwise, return 0.
- */
-static int _omap3_noncore_dpll_stop(struct clk *clk)
-{
-	u8 ai;
-
-	if (clk == &dpll3_ck)
-		return -EINVAL;
-
-	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
-		return -EINVAL;
-
-	pr_debug("clock: stopping DPLL %s\n", clk->name);
-
-	ai = omap3_dpll_autoidle_read(clk);
-
-	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
-
-	if (ai)
-		omap3_dpll_allow_idle(clk);
-	else
-		omap3_dpll_deny_idle(clk);
-
-	return 0;
-}
-
-/**
- * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
- * The choice of modes depends on the DPLL's programmed rate: if it is
- * the same as the DPLL's parent clock, it will enter bypass;
- * otherwise, it will enter lock.  This code will wait for the DPLL to
- * indicate readiness before returning, unless the DPLL takes too long
- * to enter the target state.  Intended to be used as the struct clk's
- * enable function.  If DPLL3 was passed in, or the DPLL does not
- * support low-power stop, or if the DPLL took too long to enter
- * bypass or lock, return -EINVAL; otherwise, return 0.
- */
-static int omap3_noncore_dpll_enable(struct clk *clk)
-{
-	int r;
-	struct dpll_data *dd;
-
-	if (clk == &dpll3_ck)
-		return -EINVAL;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return -EINVAL;
-
-	if (clk->rate == dd->clk_bypass->rate) {
-		WARN_ON(clk->parent != dd->clk_bypass);
-		r = _omap3_noncore_dpll_bypass(clk);
-	} else {
-		WARN_ON(clk->parent != dd->clk_ref);
-		r = _omap3_noncore_dpll_lock(clk);
-	}
-	/* FIXME: this is dubious - if clk->rate has changed, what about propagating? */
-	if (!r)
-		clk->rate = omap2_get_dpll_rate(clk);
-
-	return r;
-}
-
-/**
- * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
- * @clk: pointer to a DPLL struct clk
- *
- * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
- * The choice of modes depends on the DPLL's programmed rate: if it is
- * the same as the DPLL's parent clock, it will enter bypass;
- * otherwise, it will enter lock.  This code will wait for the DPLL to
- * indicate readiness before returning, unless the DPLL takes too long
- * to enter the target state.  Intended to be used as the struct clk's
- * enable function.  If DPLL3 was passed in, or the DPLL does not
- * support low-power stop, or if the DPLL took too long to enter
- * bypass or lock, return -EINVAL; otherwise, return 0.
- */
-static void omap3_noncore_dpll_disable(struct clk *clk)
-{
-	if (clk == &dpll3_ck)
-		return;
-
-	_omap3_noncore_dpll_stop(clk);
-}
-
-
-/* Non-CORE DPLL rate set code */
-
-/*
- * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
- * @clk: struct clk * of DPLL to set
- * @m: DPLL multiplier to set
- * @n: DPLL divider to set
- * @freqsel: FREQSEL value to set
- *
- * Program the DPLL with the supplied M, N values, and wait for the DPLL to
- * lock..  Returns -EINVAL upon error, or 0 upon success.
- */
-static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
-{
-	struct dpll_data *dd = clk->dpll_data;
-	u32 v;
-
-	/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
-	_omap3_noncore_dpll_bypass(clk);
-
-	/* Set jitter correction */
-	v = __raw_readl(dd->control_reg);
-	v &= ~dd->freqsel_mask;
-	v |= freqsel << __ffs(dd->freqsel_mask);
-	__raw_writel(v, dd->control_reg);
-
-	/* Set DPLL multiplier, divider */
-	v = __raw_readl(dd->mult_div1_reg);
-	v &= ~(dd->mult_mask | dd->div1_mask);
-	v |= m << __ffs(dd->mult_mask);
-	v |= (n - 1) << __ffs(dd->div1_mask);
-	__raw_writel(v, dd->mult_div1_reg);
-
-	/* We let the clock framework set the other output dividers later */
-
-	/* REVISIT: Set ramp-up delay? */
-
-	_omap3_noncore_dpll_lock(clk);
-
-	return 0;
-}
-
-/**
- * omap3_noncore_dpll_set_rate - set non-core DPLL rate
- * @clk: struct clk * of DPLL to set
- * @rate: rounded target rate
- *
- * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
- * low-power bypass, and the target rate is the bypass source clock
- * rate, then configure the DPLL for bypass.  Otherwise, round the
- * target rate if it hasn't been done already, then program and lock
- * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
- */
-static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct clk *new_parent = NULL;
-	u16 freqsel;
-	struct dpll_data *dd;
-	int ret;
-
-	if (!clk || !rate)
-		return -EINVAL;
-
-	dd = clk->dpll_data;
-	if (!dd)
-		return -EINVAL;
-
-	if (rate == omap2_get_dpll_rate(clk))
-		return 0;
-
-	/*
-	 * Ensure both the bypass and ref clocks are enabled prior to
-	 * doing anything; we need the bypass clock running to reprogram
-	 * the DPLL.
-	 */
-	omap2_clk_enable(dd->clk_bypass);
-	omap2_clk_enable(dd->clk_ref);
-
-	if (dd->clk_bypass->rate == rate &&
-	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
-		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
-
-		ret = _omap3_noncore_dpll_bypass(clk);
-		if (!ret)
-			new_parent = dd->clk_bypass;
-	} else {
-		if (dd->last_rounded_rate != rate)
-			omap2_dpll_round_rate(clk, rate);
-
-		if (dd->last_rounded_rate == 0)
-			return -EINVAL;
-
-		freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
-		if (!freqsel)
-			WARN_ON(1);
-
-		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
-			 clk->name, rate);
-
-		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
-						 dd->last_rounded_n, freqsel);
-		if (!ret)
-			new_parent = dd->clk_ref;
-	}
-	if (!ret) {
-		/*
-		 * Switch the parent clock in the heirarchy, and make sure
-		 * that the new parent's usecount is correct.  Note: we
-		 * enable the new parent before disabling the old to avoid
-		 * any unnecessary hardware disable->enable transitions.
-		 */
-		if (clk->usecount) {
-			omap2_clk_enable(new_parent);
-			omap2_clk_disable(clk->parent);
-		}
-		clk_reparent(clk, new_parent);
-		clk->rate = rate;
-	}
-	omap2_clk_disable(dd->clk_ref);
-	omap2_clk_disable(dd->clk_bypass);
+const struct clkops clkops_omap3430es2_hsotgusb_wait = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
+};
 
-	return 0;
-}
+const struct clkops clkops_noncore_dpll_ops = {
+	.enable		= omap3_noncore_dpll_enable,
+	.disable	= omap3_noncore_dpll_disable,
+};
 
-static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
 {
 	/*
 	 * According to the 12-5 CDP code from TI, "Limitation 2.5"
@@ -831,12 +178,12 @@ static int omap3_dpll4_set_rate(struct c
  * Program the DPLL M2 divider with the rounded target rate.  Returns
  * -EINVAL upon error, or 0 upon success.
  */
-static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 new_div = 0;
 	u32 unlock_dll = 0;
 	u32 c;
-	unsigned long validrate, sdrcrate, mpurate;
+	unsigned long validrate, sdrcrate, _mpurate;
 	struct omap_sdrc_params *sdrc_cs0;
 	struct omap_sdrc_params *sdrc_cs1;
 	int ret;
@@ -844,14 +191,11 @@ static int omap3_core_dpll_m2_set_rate(s
 	if (!clk || !rate)
 		return -EINVAL;
 
-	if (clk != &dpll3_m2_ck)
-		return -EINVAL;
-
 	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
 	if (validrate != rate)
 		return -EINVAL;
 
-	sdrcrate = sdrc_ick.rate;
+	sdrcrate = sdrc_ick_p->rate;
 	if (rate > clk->rate)
 		sdrcrate <<= ((rate / clk->rate) >> 1);
 	else
@@ -869,8 +213,8 @@ static int omap3_core_dpll_m2_set_rate(s
 	/*
 	 * XXX This only needs to be done when the CPU frequency changes
 	 */
-	mpurate = arm_fck.rate / CYCLES_PER_MHZ;
-	c = (mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+	_mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+	c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
 	c += 1;  /* for safety */
 	c *= SDRC_MPURATE_LOOPS;
 	c >>= SDRC_MPURATE_SCALE;
@@ -906,129 +250,6 @@ static int omap3_core_dpll_m2_set_rate(s
 	return 0;
 }
 
-
-static const struct clkops clkops_noncore_dpll_ops = {
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
-};
-
-/* DPLL autoidle read/set code */
-
-
-/**
- * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
- * @clk: struct clk * of the DPLL to read
- *
- * Return the DPLL's autoidle bits, shifted down to bit 0.  Returns
- * -EINVAL if passed a null pointer or if the struct clk does not
- * appear to refer to a DPLL.
- */
-static u32 omap3_dpll_autoidle_read(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return -EINVAL;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->autoidle_reg);
-	v &= dd->autoidle_mask;
-	v >>= __ffs(dd->autoidle_mask);
-
-	return v;
-}
-
-/**
- * omap3_dpll_allow_idle - enable DPLL autoidle bits
- * @clk: struct clk * of the DPLL to operate on
- *
- * Enable DPLL automatic idle control.  This automatic idle mode
- * switching takes effect only when the DPLL is locked, at least on
- * OMAP3430.  The DPLL will enter low-power stop when its downstream
- * clocks are gated.  No return value.
- */
-static void omap3_dpll_allow_idle(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return;
-
-	dd = clk->dpll_data;
-
-	/*
-	 * REVISIT: CORE DPLL can optionally enter low-power bypass
-	 * by writing 0x5 instead of 0x1.  Add some mechanism to
-	 * optionally enter this mode.
-	 */
-	v = __raw_readl(dd->autoidle_reg);
-	v &= ~dd->autoidle_mask;
-	v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
-	__raw_writel(v, dd->autoidle_reg);
-}
-
-/**
- * omap3_dpll_deny_idle - prevent DPLL from automatically idling
- * @clk: struct clk * of the DPLL to operate on
- *
- * Disable DPLL automatic idle control.  No return value.
- */
-static void omap3_dpll_deny_idle(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	u32 v;
-
-	if (!clk || !clk->dpll_data)
-		return;
-
-	dd = clk->dpll_data;
-
-	v = __raw_readl(dd->autoidle_reg);
-	v &= ~dd->autoidle_mask;
-	v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
-	__raw_writel(v, dd->autoidle_reg);
-}
-
-/* Clock control for DPLL outputs */
-
-/**
- * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
- * @clk: DPLL output struct clk
- *
- * Using parent clock DPLL data, look up DPLL state.  If locked, set our
- * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
- */
-static unsigned long omap3_clkoutx2_recalc(struct clk *clk)
-{
-	const struct dpll_data *dd;
-	unsigned long rate;
-	u32 v;
-	struct clk *pclk;
-
-	/* Walk up the parents of clk, looking for a DPLL */
-	pclk = clk->parent;
-	while (pclk && !pclk->dpll_data)
-		pclk = pclk->parent;
-
-	/* clk does not have a DPLL as a parent? */
-	WARN_ON(!pclk);
-
-	dd = pclk->dpll_data;
-
-	WARN_ON(!dd->enable_mask);
-
-	v = __raw_readl(dd->control_reg) & dd->enable_mask;
-	v >>= __ffs(dd->enable_mask);
-	if (v != OMAP3XXX_EN_DPLL_LOCKED)
-		rate = clk->parent->rate;
-	else
-		rate = clk->parent->rate * 2;
-	return rate;
-}
-
 /* Common clock code */
 
 /*
@@ -1037,7 +258,7 @@ static unsigned long omap3_clkoutx2_reca
  */
 #if defined(CONFIG_ARCH_OMAP3)
 
-static struct clk_functions omap2_clk_functions = {
+struct clk_functions omap2_clk_functions = {
 	.clk_enable		= omap2_clk_enable,
 	.clk_disable		= omap2_clk_disable,
 	.clk_round_rate		= omap2_clk_round_rate,
@@ -1063,7 +284,7 @@ void omap2_clk_prepare_for_reboot(void)
 #endif
 }
 
-static void omap3_clk_lock_dpll5(void)
+void omap3_clk_lock_dpll5(void)
 {
 	struct clk *dpll5_clk;
 	struct clk *dpll5_m2_clk;
@@ -1093,19 +314,32 @@ static void omap3_clk_lock_dpll5(void)
  */
 static int __init omap2_clk_arch_init(void)
 {
+	struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
+	unsigned long osc_sys_rate;
+
 	if (!mpurate)
 		return -EINVAL;
 
+	/* XXX test these for success */
+	dpll1_ck = clk_get(NULL, "dpll1_ck");
+	arm_fck = clk_get(NULL, "arm_fck");
+	core_ck = clk_get(NULL, "core_ck");
+	osc_sys_ck = clk_get(NULL, "osc_sys_ck");
+
 	/* REVISIT: not yet ready for 343x */
-	if (clk_set_rate(&dpll1_ck, mpurate))
+	if (clk_set_rate(dpll1_ck, mpurate))
 		printk(KERN_ERR "*** Unable to set MPU rate\n");
 
 	recalculate_root_clocks();
 
-	printk(KERN_INFO "Switched to new clocking rate (Crystal/Core/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (osc_sys_ck.rate / 1000000), ((osc_sys_ck.rate / 100000) % 10),
-	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000)) ;
+	osc_sys_rate = clk_get_rate(osc_sys_ck);
+
+	pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
+		"%ld.%01ld/%ld/%ld MHz\n",
+		(osc_sys_rate / 1000000),
+		((osc_sys_rate / 100000) % 10),
+		(clk_get_rate(core_ck) / 1000000),
+		(clk_get_rate(arm_fck) / 1000000));
 
 	calibrate_delay();
 
@@ -1113,83 +347,7 @@ static int __init omap2_clk_arch_init(vo
 }
 arch_initcall(omap2_clk_arch_init);
 
-int __init omap2_clk_init(void)
-{
-	/* struct prcm_config *prcm; */
-	struct omap_clk *c;
-	/* u32 clkrate; */
-	u32 cpu_clkflg;
-
-	if (cpu_is_omap34xx()) {
-		cpu_mask = RATE_IN_343X;
-		cpu_clkflg = CK_343X;
-
-		/*
-		 * Update this if there are further clock changes between ES2
-		 * and production parts
-		 */
-		if (omap_rev() == OMAP3430_REV_ES1_0) {
-			/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
-			cpu_clkflg |= CK_3430ES1;
-		} else {
-			cpu_mask |= RATE_IN_3430ES2;
-			cpu_clkflg |= CK_3430ES2;
-		}
-	}
-
-	clk_init(&omap2_clk_functions);
-
-	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
 
-	/* REVISIT: Not yet ready for OMAP3 */
-#if 0
-	/* Check the MPU rate set by bootloader */
-	clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sys_ck.rate)
-			continue;
-		if (prcm->dpll_speed <= clkrate)
-			 break;
-	}
-	curr_prcm_set = prcm;
 #endif
 
-	recalculate_root_clocks();
-
-	printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
-	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
-	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	/*
-	 * Lock DPLL5 and put it in autoidle.
-	 */
-	if (omap_rev() >= OMAP3430_REV_ES2_0)
-		omap3_clk_lock_dpll5();
 
-	/* Avoid sleeping during omap2_clk_prepare_for_reboot() */
-	/* REVISIT: not yet ready for 343x */
-#if 0
-	vclk = clk_get(NULL, "virt_prcm_set");
-	sclk = clk_get(NULL, "sys_ck");
-#endif
-	return 0;
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3289 @@
+/*
+ * OMAP3 clock data
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * With many device clock fixes by Kevin Hilman and Jouni Högander
+ * DPLL bypass clock support added by Roman Tereshonkov
+ *
+ */
+
+/*
+ * Virtual clocks are introduced as convenient tools.
+ * They are sources for other clocks and not supposed
+ * to be requested from drivers directly.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+
+#include <plat/control.h>
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+
+/*
+ * clocks
+ */
+
+#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
+
+/* Maximum DPLL multiplier, divider values for OMAP3 */
+#define OMAP3_MAX_DPLL_MULT		2048
+#define OMAP3_MAX_DPLL_DIV		128
+
+/*
+ * DPLL1 supplies clock to the MPU.
+ * DPLL2 supplies clock to the IVA2.
+ * DPLL3 supplies CORE domain clocks.
+ * DPLL4 supplies peripheral clocks.
+ * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
+ */
+
+/* Forward declarations for DPLL bypass clocks */
+static struct clk dpll1_fck;
+static struct clk dpll2_fck;
+
+/* PRM CLOCKS */
+
+/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
+static struct clk omap_32k_fck = {
+	.name		= "omap_32k_fck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk secure_32k_fck = {
+	.name		= "secure_32k_fck",
+	.ops		= &clkops_null,
+	.rate		= 32768,
+	.flags		= RATE_FIXED,
+};
+
+/* Virtual source clocks for osc_sys_ck */
+static struct clk virt_12m_ck = {
+	.name		= "virt_12m_ck",
+	.ops		= &clkops_null,
+	.rate		= 12000000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk virt_13m_ck = {
+	.name		= "virt_13m_ck",
+	.ops		= &clkops_null,
+	.rate		= 13000000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk virt_16_8m_ck = {
+	.name		= "virt_16_8m_ck",
+	.ops		= &clkops_null,
+	.rate		= 16800000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk virt_19_2m_ck = {
+	.name		= "virt_19_2m_ck",
+	.ops		= &clkops_null,
+	.rate		= 19200000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk virt_26m_ck = {
+	.name		= "virt_26m_ck",
+	.ops		= &clkops_null,
+	.rate		= 26000000,
+	.flags		= RATE_FIXED,
+};
+
+static struct clk virt_38_4m_ck = {
+	.name		= "virt_38_4m_ck",
+	.ops		= &clkops_null,
+	.rate		= 38400000,
+	.flags		= RATE_FIXED,
+};
+
+static const struct clksel_rate osc_sys_12m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_13m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_16_8m_rates[] = {
+	{ .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_19_2m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_26m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_38_4m_rates[] = {
+	{ .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel osc_sys_clksel[] = {
+	{ .parent = &virt_12m_ck,   .rates = osc_sys_12m_rates },
+	{ .parent = &virt_13m_ck,   .rates = osc_sys_13m_rates },
+	{ .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
+	{ .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates },
+	{ .parent = &virt_26m_ck,   .rates = osc_sys_26m_rates },
+	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
+	{ .parent = NULL },
+};
+
+/* Oscillator clock */
+/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
+static struct clk osc_sys_ck = {
+	.name		= "osc_sys_ck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_PRM_CLKSEL,
+	.clksel_mask	= OMAP3430_SYS_CLKIN_SEL_MASK,
+	.clksel		= osc_sys_clksel,
+	/* REVISIT: deal with autoextclkmode? */
+	.flags		= RATE_FIXED,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate div2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel sys_clksel[] = {
+	{ .parent = &osc_sys_ck, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
+/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
+static struct clk sys_ck = {
+	.name		= "sys_ck",
+	.ops		= &clkops_null,
+	.parent		= &osc_sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_PRM_CLKSRC_CTRL,
+	.clksel_mask	= OMAP_SYSCLKDIV_MASK,
+	.clksel		= sys_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk sys_altclk = {
+	.name		= "sys_altclk",
+	.ops		= &clkops_null,
+};
+
+/* Optional external clock input for some McBSPs */
+static struct clk mcbsp_clks = {
+	.name		= "mcbsp_clks",
+	.ops		= &clkops_null,
+};
+
+/* PRM EXTERNAL CLOCK OUTPUT */
+
+static struct clk sys_clkout1 = {
+	.name		= "sys_clkout1",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &osc_sys_ck,
+	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
+	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLLS */
+
+/* CM CLOCKS */
+
+static const struct clksel_rate div16_dpll_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 5, .val = 5, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 7, .val = 7, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_343X },
+	{ .div = 10, .val = 10, .flags = RATE_IN_343X },
+	{ .div = 11, .val = 11, .flags = RATE_IN_343X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_343X },
+	{ .div = 13, .val = 13, .flags = RATE_IN_343X },
+	{ .div = 14, .val = 14, .flags = RATE_IN_343X },
+	{ .div = 15, .val = 15, .flags = RATE_IN_343X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+/* DPLL1 */
+/* MPU clock source */
+/* Type: DPLL */
+static struct dpll_data dpll1_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll1_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll1_ck = {
+	.name		= "dpll1_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll1_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed.
+ */
+static struct clk dpll1_x2_ck = {
+	.name		= "dpll1_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_ck,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
+static const struct clksel div16_dpll1_x2m2_clksel[] = {
+	{ .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * Does not exist in the TRM - needed to separate the M2 divider from
+ * bypass selection in mpu_ck
+ */
+static struct clk dpll1_x2m2_ck = {
+	.name		= "dpll1_x2m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_x2_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
+	.clksel_mask	= OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div16_dpll1_x2m2_clksel,
+	.clkdm_name	= "dpll1_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* DPLL2 */
+/* IVA2 clock source */
+/* Type: DPLL */
+
+static struct dpll_data dpll2_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll2_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
+				(1 << DPLL_LOW_POWER_BYPASS),
+	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll2_ck = {
+	.name		= "dpll2_ck",
+	.ops		= &clkops_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll2_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll2_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll2_m2x2_clksel[] = {
+	{ .parent = &dpll2_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
+ * or CLKOUTX2. CLKOUT seems most plausible.
+ */
+static struct clk dpll2_m2_ck = {
+	.name		= "dpll2_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll2_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
+					  OMAP3430_CM_CLKSEL2_PLL),
+	.clksel_mask	= OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div16_dpll2_m2x2_clksel,
+	.clkdm_name	= "dpll2_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * DPLL3
+ * Source clock for all interfaces and for some device fclks
+ * REVISIT: Also supports fast relock bypass - not included below
+ */
+static struct dpll_data dpll3_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
+	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll3_ck = {
+	.name		= "dpll3_ck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll3_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed
+ */
+static struct clk dpll3_x2_ck = {
+	.name		= "dpll3_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate div31_dpll3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_3430ES2 },
+	{ .div = 4, .val = 4, .flags = RATE_IN_3430ES2 },
+	{ .div = 5, .val = 5, .flags = RATE_IN_3430ES2 },
+	{ .div = 6, .val = 6, .flags = RATE_IN_3430ES2 },
+	{ .div = 7, .val = 7, .flags = RATE_IN_3430ES2 },
+	{ .div = 8, .val = 8, .flags = RATE_IN_3430ES2 },
+	{ .div = 9, .val = 9, .flags = RATE_IN_3430ES2 },
+	{ .div = 10, .val = 10, .flags = RATE_IN_3430ES2 },
+	{ .div = 11, .val = 11, .flags = RATE_IN_3430ES2 },
+	{ .div = 12, .val = 12, .flags = RATE_IN_3430ES2 },
+	{ .div = 13, .val = 13, .flags = RATE_IN_3430ES2 },
+	{ .div = 14, .val = 14, .flags = RATE_IN_3430ES2 },
+	{ .div = 15, .val = 15, .flags = RATE_IN_3430ES2 },
+	{ .div = 16, .val = 16, .flags = RATE_IN_3430ES2 },
+	{ .div = 17, .val = 17, .flags = RATE_IN_3430ES2 },
+	{ .div = 18, .val = 18, .flags = RATE_IN_3430ES2 },
+	{ .div = 19, .val = 19, .flags = RATE_IN_3430ES2 },
+	{ .div = 20, .val = 20, .flags = RATE_IN_3430ES2 },
+	{ .div = 21, .val = 21, .flags = RATE_IN_3430ES2 },
+	{ .div = 22, .val = 22, .flags = RATE_IN_3430ES2 },
+	{ .div = 23, .val = 23, .flags = RATE_IN_3430ES2 },
+	{ .div = 24, .val = 24, .flags = RATE_IN_3430ES2 },
+	{ .div = 25, .val = 25, .flags = RATE_IN_3430ES2 },
+	{ .div = 26, .val = 26, .flags = RATE_IN_3430ES2 },
+	{ .div = 27, .val = 27, .flags = RATE_IN_3430ES2 },
+	{ .div = 28, .val = 28, .flags = RATE_IN_3430ES2 },
+	{ .div = 29, .val = 29, .flags = RATE_IN_3430ES2 },
+	{ .div = 30, .val = 30, .flags = RATE_IN_3430ES2 },
+	{ .div = 31, .val = 31, .flags = RATE_IN_3430ES2 },
+	{ .div = 0 },
+};
+
+static const struct clksel div31_dpll3m2_clksel[] = {
+	{ .parent = &dpll3_ck, .rates = div31_dpll3_rates },
+	{ .parent = NULL }
+};
+
+/* DPLL3 output M2 - primary control point for CORE speed */
+static struct clk dpll3_m2_ck = {
+	.name		= "dpll3_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
+	.clksel		= div31_dpll3m2_clksel,
+	.clkdm_name	= "dpll3_clkdm",
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap3_core_dpll_m2_set_rate,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dpll3_m2x2_ck = {
+	.name		= "dpll3_m2x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static const struct clksel div16_dpll3_clksel[] = {
+	{ .parent = &dpll3_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll3_m3x2_ck */
+static struct clk dpll3_m3_ck = {
+	.name		= "dpll3_m3_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_DIV_DPLL3_MASK,
+	.clksel		= div16_dpll3_clksel,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll3_m3x2_ck = {
+	.name		= "dpll3_m3x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll3_m3_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_core_alwon_ck = {
+	.name		= "emu_core_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m3x2_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL4 */
+/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
+/* Type: DPLL */
+static struct dpll_data dpll4_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll4_ck = {
+	.name		= "dpll4_ck",
+	.ops		= &clkops_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll4_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_dpll4_set_rate,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed --
+ * XXX does this serve any downstream clocks?
+ */
+static struct clk dpll4_x2_ck = {
+	.name		= "dpll4_x2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel div16_dpll4_clksel[] = {
+	{ .parent = &dpll4_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll4_m2x2_ck */
+static struct clk dpll4_m2_ck = {
+	.name		= "dpll4_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
+	.clksel_mask	= OMAP3430_DIV_96M_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m2x2_ck = {
+	.name		= "dpll4_m2x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/*
+ * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
+ * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
+ * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
+ * CM_96K_(F)CLK.
+ */
+static struct clk omap_96m_alwon_fck = {
+	.name		= "omap_96m_alwon_fck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_m2x2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cm_96m_fck = {
+	.name		= "cm_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_alwon_fck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel_rate omap_96m_dpll_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_96m_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_96m_fck_clksel[] = {
+	{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
+	{ .parent = &sys_ck,	 .rates = omap_96m_sys_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_96m_fck = {
+	.name		= "omap_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_96M_MASK,
+	.clksel		= omap_96m_fck_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m3x2_ck */
+static struct clk dpll4_m3_ck = {
+	.name		= "dpll4_m3_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_TV_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m3x2_ck = {
+	.name		= "dpll4_m3x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m3_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_54m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_54m_clksel[] = {
+	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
+	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_54m_fck = {
+	.name		= "omap_54m_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
+	.clksel		= omap_54m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_48m_clksel[] = {
+	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
+	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_48m_fck = {
+	.name		= "omap_48m_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
+	.clksel		= omap_48m_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk omap_12m_fck = {
+	.name		= "omap_12m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.fixed_div	= 4,
+	.recalc		= &omap2_fixed_divisor_recalc,
+};
+
+/* This virstual clock is the source for dpll4_m4x2_ck */
+static struct clk dpll4_m4_ck = {
+	.name		= "dpll4_m4_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_DSS1_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m4x2_ck = {
+	.name		= "dpll4_m4x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m4_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m5x2_ck */
+static struct clk dpll4_m5_ck = {
+	.name		= "dpll4_m5_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_CAM_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m5x2_ck = {
+	.name		= "dpll4_m5x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m5_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m6x2_ck */
+static struct clk dpll4_m6_ck = {
+	.name		= "dpll4_m6_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_DIV_DPLL4_MASK,
+	.clksel		= div16_dpll4_clksel,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m6x2_ck = {
+	.name		= "dpll4_m6x2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll4_m6_ck,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_per_alwon_ck = {
+	.name		= "emu_per_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll4_m6x2_ck,
+	.clkdm_name	= "dpll4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL5 */
+/* Supplies 120MHz clock, USIM source clock */
+/* Type: DPLL */
+/* 3430ES2 only */
+static struct dpll_data dpll5_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
+	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
+	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
+	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
+};
+
+static struct clk dpll5_ck = {
+	.name		= "dpll5_ck",
+	.ops		= &clkops_noncore_dpll_ops,
+	.parent		= &sys_ck,
+	.dpll_data	= &dpll5_dd,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll5_clkdm",
+	.recalc		= &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll5_clksel[] = {
+	{ .parent = &dpll5_ck, .rates = div16_dpll_rates },
+	{ .parent = NULL }
+};
+
+static struct clk dpll5_m2_ck = {
+	.name		= "dpll5_m2_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll5_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
+	.clksel_mask	= OMAP3430ES2_DIV_120M_MASK,
+	.clksel		= div16_dpll5_clksel,
+	.clkdm_name	= "dpll5_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CM EXTERNAL CLOCK OUTPUTS */
+
+static const struct clksel_rate clkout2_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel clkout2_src_clksel[] = {
+	{ .parent = &core_ck,		.rates = clkout2_src_core_rates },
+	{ .parent = &sys_ck,		.rates = clkout2_src_sys_rates },
+	{ .parent = &cm_96m_fck,	.rates = clkout2_src_96m_rates },
+	{ .parent = &omap_54m_fck,	.rates = clkout2_src_54m_rates },
+	{ .parent = NULL }
+};
+
+static struct clk clkout2_src_ck = {
+	.name		= "clkout2_src_ck",
+	.ops		= &clkops_omap2_dflt,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.enable_bit	= OMAP3430_CLKOUT2_EN_SHIFT,
+	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP3430_CLKOUT2SOURCE_MASK,
+	.clksel		= clkout2_src_clksel,
+	.clkdm_name	= "core_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate sys_clkout2_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 16, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+	{ .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk sys_clkout2 = {
+	.name		= "sys_clkout2",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
+	.clksel_mask	= OMAP3430_CLKOUT2_DIV_MASK,
+	.clksel		= sys_clkout2_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CM OUTPUT CLOCKS */
+
+static struct clk corex2_fck = {
+	.name		= "corex2_fck",
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2x2_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL power domain clock controls */
+
+static const struct clksel_rate div4_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel div4_core_clksel[] = {
+	{ .parent = &core_ck, .rates = div4_rates },
+	{ .parent = NULL }
+};
+
+/*
+ * REVISIT: Are these in DPLL power domain or CM power domain? docs
+ * may be inconsistent here?
+ */
+static struct clk dpll1_fck = {
+	.name		= "dpll1_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.clksel_mask	= OMAP3430_MPU_CLK_SRC_MASK,
+	.clksel		= div4_core_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mpu_ck = {
+	.name		= "mpu_ck",
+	.ops		= &clkops_null,
+	.parent		= &dpll1_x2m2_ck,
+	.clkdm_name	= "mpu_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
+static const struct clksel_rate arm_fck_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel arm_fck_clksel[] = {
+	{ .parent = &mpu_ck, .rates = arm_fck_rates },
+	{ .parent = NULL }
+};
+
+static struct clk arm_fck = {
+	.name		= "arm_fck",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
+	.clksel		= arm_fck_clksel,
+	.clkdm_name	= "mpu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* XXX What about neon_clkdm ? */
+
+/*
+ * REVISIT: This clock is never specifically defined in the 3430 TRM,
+ * although it is referenced - so this is a guess
+ */
+static struct clk emu_mpu_alwon_ck = {
+	.name		= "emu_mpu_alwon_ck",
+	.ops		= &clkops_null,
+	.parent		= &mpu_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dpll2_fck = {
+	.name		= "dpll2_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.clksel_mask	= OMAP3430_IVA2_CLK_SRC_MASK,
+	.clksel		= div4_core_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk iva2_ck = {
+	.name		= "iva2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll2_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+	.clkdm_name	= "iva2_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* Common interface clocks */
+
+static const struct clksel div2_core_clksel[] = {
+	{ .parent = &core_ck, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l3_ick = {
+	.name		= "l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &core_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_L3_MASK,
+	.clksel		= div2_core_clksel,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel div2_l3_clksel[] = {
+	{ .parent = &l3_ick, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk l4_ick = {
+	.name		= "l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_L4_MASK,
+	.clksel		= div2_l3_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+
+};
+
+static const struct clksel div2_l4_clksel[] = {
+	{ .parent = &l4_ick, .rates = div2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk rm_ick = {
+	.name		= "rm_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_RM_MASK,
+	.clksel		= div2_l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* GFX power domain */
+
+/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
+
+static const struct clksel gfx_l3_clksel[] = {
+	{ .parent = &l3_ick, .rates = gfx_l3_rates },
+	{ .parent = NULL }
+};
+
+/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
+static struct clk gfx_l3_ck = {
+	.name		= "gfx_l3_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_l3_fck = {
+	.name		= "gfx_l3_fck",
+	.ops		= &clkops_null,
+	.parent		= &gfx_l3_ck,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
+	.clksel		= gfx_l3_clksel,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_l3_ick = {
+	.name		= "gfx_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &gfx_l3_ck,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_cg1_ck = {
+	.name		= "gfx_cg1_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gfx_cg2_ck = {
+	.name		= "gfx_cg2_ck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SGX power domain - 3430ES2 only */
+
+static const struct clksel_rate sgx_core_rates[] = {
+	{ .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 4, .val = 1, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate sgx_96m_rates[] = {
+	{ .div = 1,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel sgx_clksel[] = {
+	{ .parent = &core_ck,	 .rates = sgx_core_rates },
+	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
+	{ .parent = NULL },
+};
+
+static struct clk sgx_fck = {
+	.name		= "sgx_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES2_CLKSEL_SGX_MASK,
+	.clksel		= sgx_clksel,
+	.clkdm_name	= "sgx_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk sgx_ick = {
+	.name		= "sgx_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
+	.clkdm_name	= "sgx_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE power domain */
+
+static struct clk d2d_26m_fck = {
+	.name		= "d2d_26m_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk modem_fck = {
+	.name		= "modem_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sad2d_ick = {
+	.name		= "sad2d_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mad2d_ick = {
+	.name		= "mad2d_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel omap343x_gpt_clksel[] = {
+	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck,	   .rates = gpt_sys_rates },
+	{ .parent = NULL}
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk cpefuse_fck = {
+	.name		= "cpefuse_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ts_fck = {
+	.name		= "ts_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbtll_fck = {
+	.name		= "usbtll_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll5_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE 96M FCLK-derived clocks */
+
+static struct clk core_96m_fck = {
+	.name		= "core_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs3_fck = {
+	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c3_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/*
+ * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
+ * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
+ */
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 }
+};
+
+static const struct clksel mcbsp_15_clksel[] = {
+	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mcbsp5_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 5,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
+	.clksel		= mcbsp_15_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
+	.clksel		= mcbsp_15_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* CORE_48M_FCK-derived clocks */
+
+static struct clk core_48m_fck = {
+	.name		= "core_48m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi4_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fshostusb_fck = {
+	.name		= "fshostusb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE_12M_FCK based clocks */
+
+static struct clk core_12m_fck = {
+	.name		= "core_12m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_12m_fck,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_12m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DPLL3-derived clock */
+
+static const struct clksel_rate ssi_ssr_corex2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_clksel[] = {
+	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
+	{ .parent = NULL }
+};
+
+static struct clk ssi_ssr_fck_3430es1 = {
+	.name		= "ssi_ssr_fck",
+	.ops		= &clkops_omap2_dflt,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk ssi_ssr_fck_3430es2 = {
+	.name		= "ssi_ssr_fck",
+	.ops		= &clkops_omap3430es2_ssi_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
+	.clksel		= ssi_ssr_clksel,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es1 = {
+	.name		= "ssi_sst_fck",
+	.ops		= &clkops_null,
+	.parent		= &ssi_ssr_fck_3430es1,
+	.fixed_div	= 2,
+	.recalc		= &omap2_fixed_divisor_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es2 = {
+	.name		= "ssi_sst_fck",
+	.ops		= &clkops_null,
+	.parent		= &ssi_ssr_fck_3430es2,
+	.fixed_div	= 2,
+	.recalc		= &omap2_fixed_divisor_recalc,
+};
+
+
+
+/* CORE_L3_ICK based clocks */
+
+/*
+ * XXX must add clk_enable/clk_disable for these if standard code won't
+ * handle it
+ */
+static struct clk core_l3_ick = {
+	.name		= "core_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es1 = {
+	.name		= "hsotgusb_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es2 = {
+	.name		= "hsotgusb_ick",
+	.ops		= &clkops_omap3430es2_hsotgusb_wait,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+	.name		= "gpmc_fck",
+	.ops		= &clkops_null,
+	.parent		= &core_l3_ick,
+	.flags		= ENABLE_ON_INIT, /* huh? */
+	.clkdm_name	= "core_l3_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SECURITY_L3_ICK based clocks */
+
+static struct clk security_l3_ick = {
+	.name		= "security_l3_ick",
+	.ops		= &clkops_null,
+	.parent		= &l3_ick,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l3_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* CORE_L4_ICK based clocks */
+
+static struct clk core_l4_ick = {
+	.name		= "core_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbtll_ick = {
+	.name		= "usbtll_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs3_ick = {
+	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* Intersystem Communication Registers - chassis mode only */
+static struct clk icr_ick = {
+	.name		= "icr_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes2_ick = {
+	.name		= "aes2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha12_ick = {
+	.name		= "sha12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des2_ick = {
+	.name		= "des2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi4_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c3_ick = {
+	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 5,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 1,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &core_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.recalc		= &followparent_recalc,
+};
+
+/* SSI_L4_ICK based clocks */
+
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es1 = {
+	.name		= "ssi_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &ssi_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es2 = {
+	.name		= "ssi_ick",
+	.ops		= &clkops_omap3430es2_ssi_wait,
+	.parent		= &ssi_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
+ * but l4_ick makes more sense to me */
+
+static const struct clksel usb_l4_clksel[] = {
+	{ .parent = &l4_ick, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk usb_l4_ick = {
+	.name		= "usb_l4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &l4_ick,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
+	.clksel		= usb_l4_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* SECURITY_L4_ICK2 based clocks */
+
+static struct clk security_l4_ick2 = {
+	.name		= "security_l4_ick2",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes1_ick = {
+	.name		= "aes1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha11_ick = {
+	.name		= "sha11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des1_ick = {
+	.name		= "des1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &security_l4_ick2,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* DSS */
+static struct clk dss1_alwon_fck_3430es1 = {
+	.name		= "dss1_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll4_m4x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss1_alwon_fck_3430es2 = {
+	.name		= "dss1_alwon_fck",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &dpll4_m4x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_tv_fck = {
+	.name		= "dss_tv_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_54m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_96m_fck = {
+	.name		= "dss_96m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &omap_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss2_alwon_fck = {
+	.name		= "dss2_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es1 = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es2 = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "dss_ick",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* CAM */
+
+static struct clk cam_mclk = {
+	.name		= "cam_mclk",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll4_m5x2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk csi2_96m_fck = {
+	.name		= "csi2_96m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &core_96m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* USBHOST - 3430ES2 only */
+
+static struct clk usbhost_120m_fck = {
+	.name		= "usbhost_120m_fck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &dpll5_m2_ck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhost_48m_fck = {
+	.name		= "usbhost_48m_fck",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &omap_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbhost_ick = {
+	/* Handles both L3 and L4 clocks */
+	.name		= "usbhost_ick",
+	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
+	.parent		= &l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* WKUP */
+
+static const struct clksel_rate usim_96m_rates[] = {
+	{ .div = 2,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 4,  .val = 4, .flags = RATE_IN_343X },
+	{ .div = 8,  .val = 5, .flags = RATE_IN_343X },
+	{ .div = 10, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate usim_120m_rates[] = {
+	{ .div = 4,  .val = 7,	.flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 8,  .val = 8,	.flags = RATE_IN_343X },
+	{ .div = 16, .val = 9,	.flags = RATE_IN_343X },
+	{ .div = 20, .val = 10, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel usim_clksel[] = {
+	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
+	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
+	{ .parent = &sys_ck,		.rates = div2_rates },
+	{ .parent = NULL },
+};
+
+/* 3430ES2 only */
+static struct clk usim_fck = {
+	.name		= "usim_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430ES2_CLKSEL_USIMOCP_MASK,
+	.clksel		= usim_clksel,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT1_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk wkup_32k_fck = {
+	.name		= "wkup_32k_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_32k_fck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio1_dbck = {
+	.name		= "gpio1_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &wkup_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt2_fck = {
+	.name		= "wdt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_32k_fck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wkup_l4_ick = {
+	.name		= "wkup_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* 3430ES2 only */
+/* Never specifically named in the TRM, so we have to infer a likely name */
+static struct clk usim_ick = {
+	.name		= "usim_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt2_ick = {
+	.name		= "wdt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio1_ick = {
+	.name		= "gpio1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk omap_32ksync_ick = {
+	.name		= "omap_32ksync_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* XXX This clock no longer exists in 3430 TRM rev F */
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &wkup_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+
+
+/* PER clock domain */
+
+static struct clk per_96m_fck = {
+	.name		= "per_96m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_96m_alwon_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk per_48m_fck = {
+	.name		= "per_48m_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_48m_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_48m_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT2_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT3_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT4_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT5_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT6_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT7_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT8_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3430_CLKSEL_GPT9_MASK,
+	.clksel		= omap343x_gpt_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk per_32k_alwon_fck = {
+	.name		= "per_32k_alwon_fck",
+	.ops		= &clkops_null,
+	.parent		= &omap_32k_fck,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio6_dbck = {
+	.name		= "gpio6_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_dbck = {
+	.name		= "gpio5_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio4_dbck = {
+	.name		= "gpio4_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio3_dbck = {
+	.name		= "gpio3_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio2_dbck = {
+	.name		= "gpio2_dbck",
+	.ops		= &clkops_omap2_dflt,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_32k_alwon_fck,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk per_l4_ick = {
+	.name		= "per_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &l4_ick,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio6_ick = {
+	.name		= "gpio6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio4_ick = {
+	.name		= "gpio4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio3_ick = {
+	.name		= "gpio3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio2_ick = {
+	.name		= "gpio2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+	.name		= "wdt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.parent		= &per_l4_ick,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel mcbsp_234_clksel[] = {
+	{ .parent = &per_96m_fck,  .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL }
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 2,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 3,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.id		= 4,
+	.init		= &omap2_init_clksel_parent,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
+	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
+	.clksel		= mcbsp_234_clksel,
+	.clkdm_name	= "per_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* EMU clocks */
+
+/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
+
+static const struct clksel_rate emu_src_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_per_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_mpu_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 0 },
+};
+
+static const struct clksel emu_src_clksel[] = {
+	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
+	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
+	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
+	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
+	{ .parent = NULL },
+};
+
+/*
+ * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
+ * to switch the source of some of the EMU clocks.
+ * XXX Are there CLKEN bits for these EMU clks?
+ */
+static struct clk emu_src_ck = {
+	.name		= "emu_src_ck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
+	.clksel		= emu_src_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclk_emu_rates[] = {
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel pclk_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = pclk_emu_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pclk_fck = {
+	.name		= "pclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_PCLK_MASK,
+	.clksel		= pclk_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclkx2_emu_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel pclkx2_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pclkx2_fck = {
+	.name		= "pclkx2_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_PCLKX2_MASK,
+	.clksel		= pclkx2_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel atclk_emu_clksel[] = {
+	{ .parent = &emu_src_ck, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk atclk_fck = {
+	.name		= "atclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_ATCLK_MASK,
+	.clksel		= atclk_emu_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk traceclk_src_fck = {
+	.name		= "traceclk_src_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_TRACE_MUX_CTRL_MASK,
+	.clksel		= emu_src_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate traceclk_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
+	{ .div = 0 },
+};
+
+static const struct clksel traceclk_clksel[] = {
+	{ .parent = &traceclk_src_fck, .rates = traceclk_rates },
+	{ .parent = NULL },
+};
+
+static struct clk traceclk_fck = {
+	.name		= "traceclk_fck",
+	.ops		= &clkops_null,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_CLKSEL_TRACECLK_MASK,
+	.clksel		= traceclk_clksel,
+	.clkdm_name	= "emu_clkdm",
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* SR clocks */
+
+/* SmartReflex fclk (VDD1) */
+static struct clk sr1_fck = {
+	.name		= "sr1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+/* SmartReflex fclk (VDD2) */
+static struct clk sr2_fck = {
+	.name		= "sr2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &sys_ck,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sr_l4_ick = {
+	.name		= "sr_l4_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
+	.parent		= &l4_ick,
+	.clkdm_name	= "core_l4_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
+/* SECURE_32K_FCK clocks */
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.ops		= &clkops_null,
+	.parent		= &secure_32k_fck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt1_fck = {
+	.name		= "wdt1_fck",
+	.ops		= &clkops_null,
+	.parent		= &secure_32k_fck,
+	.recalc		= &followparent_recalc,
+};
+
+
+/*
+ * clkdev
+ */
+
+static struct omap_clk omap34xx_clks[] = {
+	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_343X),
+	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_343X),
+	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_343X),
+	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2),
+	CLK(NULL,	"virt_19_2m_ck", &virt_19_2m_ck, CK_343X),
+	CLK(NULL,	"virt_26m_ck",	&virt_26m_ck,	CK_343X),
+	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_343X),
+	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_343X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_343X),
+	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_343X),
+	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_343X),
+	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_343X),
+	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_343X),
+	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_343X),
+	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_343X),
+	CLK(NULL,	"dpll2_ck",	&dpll2_ck,	CK_343X),
+	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck,	CK_343X),
+	CLK(NULL,	"dpll3_ck",	&dpll3_ck,	CK_343X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_343X),
+	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_343X),
+	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_343X),
+	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
+	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_343X),
+	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
+	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
+	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_343X),
+	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_343X),
+	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
+	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_343X),
+	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_343X),
+	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_343X),
+	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_343X),
+	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_343X),
+	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_343X),
+	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_343X),
+	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_343X),
+	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_343X),
+	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_343X),
+	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_343X),
+	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_343X),
+	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
+	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_343X),
+	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
+	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
+	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2),
+	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2),
+	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_343X),
+	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_343X),
+	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_343X),
+	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_343X),
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_343X),
+	CLK(NULL,	"arm_fck",	&arm_fck,	CK_343X),
+	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
+	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_343X),
+	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_343X),
+	CLK(NULL,	"l3_ick",	&l3_ick,	CK_343X),
+	CLK(NULL,	"l4_ick",	&l4_ick,	CK_343X),
+	CLK(NULL,	"rm_ick",	&rm_ick,	CK_343X),
+	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck,	CK_3430ES1),
+	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck,	CK_3430ES1),
+	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick,	CK_3430ES1),
+	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck,	CK_3430ES1),
+	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck,	CK_3430ES1),
+	CLK(NULL,	"sgx_fck",	&sgx_fck,	CK_3430ES2),
+	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2),
+	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
+	CLK(NULL,	"modem_fck",	&modem_fck,	CK_343X),
+	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_343X),
+	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_343X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_343X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_343X),
+	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2),
+	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2),
+	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2),
+	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_343X),
+	CLK("mmci-omap-hs.2",	"fck",	&mmchs3_fck,	CK_3430ES2),
+	CLK("mmci-omap-hs.1",	"fck",	&mmchs2_fck,	CK_343X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_343X),
+	CLK("mmci-omap-hs.0",	"fck",	&mmchs1_fck,	CK_343X),
+	CLK("i2c_omap.3", "fck",	&i2c3_fck,	CK_343X),
+	CLK("i2c_omap.2", "fck",	&i2c2_fck,	CK_343X),
+	CLK("i2c_omap.1", "fck",	&i2c1_fck,	CK_343X),
+	CLK("omap-mcbsp.5", "fck",	&mcbsp5_fck,	CK_343X),
+	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_343X),
+	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_343X),
+	CLK("omap2_mcspi.4", "fck",	&mcspi4_fck,	CK_343X),
+	CLK("omap2_mcspi.3", "fck",	&mcspi3_fck,	CK_343X),
+	CLK("omap2_mcspi.2", "fck",	&mcspi2_fck,	CK_343X),
+	CLK("omap2_mcspi.1", "fck",	&mcspi1_fck,	CK_343X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_343X),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_343X),
+	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
+	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_343X),
+	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_343X),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2),
+	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_343X),
+	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
+	CLK("musb_hdrc",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_343X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_343X),
+	CLK(NULL,	"security_l3_ick", &security_l3_ick, CK_343X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_343X),
+	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_343X),
+	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2),
+	CLK("mmci-omap-hs.2",	"ick",	&mmchs3_ick,	CK_3430ES2),
+	CLK(NULL,	"icr_ick",	&icr_ick,	CK_343X),
+	CLK(NULL,	"aes2_ick",	&aes2_ick,	CK_343X),
+	CLK(NULL,	"sha12_ick",	&sha12_ick,	CK_343X),
+	CLK(NULL,	"des2_ick",	&des2_ick,	CK_343X),
+	CLK("mmci-omap-hs.1",	"ick",	&mmchs2_ick,	CK_343X),
+	CLK("mmci-omap-hs.0",	"ick",	&mmchs1_ick,	CK_343X),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_343X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_343X),
+	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_343X),
+	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_343X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_343X),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_343X),
+	CLK("i2c_omap.3", "ick",	&i2c3_ick,	CK_343X),
+	CLK("i2c_omap.2", "ick",	&i2c2_ick,	CK_343X),
+	CLK("i2c_omap.1", "ick",	&i2c1_ick,	CK_343X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_343X),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_343X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_343X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_343X),
+	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_343X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_343X),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_343X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_343X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_343X),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
+	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_343X),
+	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_343X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_343X),
+	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_343X),
+	CLK(NULL,	"des1_ick",	&des1_ick,	CK_343X),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es1, CK_3430ES1),
+	CLK("omapdss",	"dss1_fck",	&dss1_alwon_fck_3430es2, CK_3430ES2),
+	CLK("omapdss",	"tv_fck",	&dss_tv_fck,	CK_343X),
+	CLK("omapdss",	"video_fck",	&dss_96m_fck,	CK_343X),
+	CLK("omapdss",	"dss2_fck",	&dss2_alwon_fck, CK_343X),
+	CLK("omapdss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
+	CLK("omapdss",	"ick",		&dss_ick_3430es2,	CK_3430ES2),
+	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_343X),
+	CLK(NULL,	"cam_ick",	&cam_ick,	CK_343X),
+	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_343X),
+	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2),
+	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2),
+	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2),
+	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_343X),
+	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_343X),
+	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_343X),
+	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_343X),
+	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_343X),
+	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2),
+	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_343X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_343X),
+	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_343X),
+	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_343X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_343X),
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_343X),
+	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_343X),
+	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_343X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_343X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_343X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_343X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_343X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_343X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_343X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_343X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_343X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_343X),
+	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_343X),
+	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_343X),
+	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_343X),
+	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_343X),
+	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_343X),
+	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_343X),
+	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_343X),
+	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_343X),
+	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_343X),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_343X),
+	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_343X),
+	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_343X),
+	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_343X),
+	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_343X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_343X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_343X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_343X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_343X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_343X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_343X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_343X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_343X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_343X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_343X),
+	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_343X),
+	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_343X),
+	CLK("omap-mcbsp.2", "fck",	&mcbsp2_fck,	CK_343X),
+	CLK("omap-mcbsp.3", "fck",	&mcbsp3_fck,	CK_343X),
+	CLK("omap-mcbsp.4", "fck",	&mcbsp4_fck,	CK_343X),
+	CLK("etb",	"emu_src_ck",	&emu_src_ck,	CK_343X),
+	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_343X),
+	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_343X),
+	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_343X),
+	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_343X),
+	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_343X),
+	CLK(NULL,	"sr1_fck",	&sr1_fck,	CK_343X),
+	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_343X),
+	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_343X),
+	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_343X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_343X),
+	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_343X),
+};
+
+
+int __init omap2_clk_init(void)
+{
+	/* struct prcm_config *prcm; */
+	struct omap_clk *c;
+	/* u32 clkrate; */
+	u32 cpu_clkflg;
+
+	if (cpu_is_omap34xx()) {
+		cpu_mask = RATE_IN_343X;
+		cpu_clkflg = CK_343X;
+
+		/*
+		 * Update this if there are further clock changes between ES2
+		 * and production parts
+		 */
+		if (omap_rev() == OMAP3430_REV_ES1_0) {
+			/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
+			cpu_clkflg |= CK_3430ES1;
+		} else {
+			cpu_mask |= RATE_IN_3430ES2;
+			cpu_clkflg |= CK_3430ES2;
+		}
+	}
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
+		clk_preinit(c->lk.clk);
+
+	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			clk_register(c->lk.clk);
+			omap2_init_clk_clkdm(c->lk.clk);
+		}
+
+	/* REVISIT: Not yet ready for OMAP3 */
+#if 0
+	/* Check the MPU rate set by bootloader */
+	clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+		if (prcm->dpll_speed <= clkrate)
+			break;
+	}
+	curr_prcm_set = prcm;
+#endif
+
+	recalculate_root_clocks();
+
+	printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
+	       "%ld.%01ld/%ld/%ld MHz\n",
+	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
+	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	/*
+	 * Lock DPLL5 and put it in autoidle.
+	 */
+	if (omap_rev() >= OMAP3430_REV_ES2_0)
+		omap3_clk_lock_dpll5();
+
+	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
+	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
+	arm_fck_p = clk_get(NULL, "arm_fck");
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock34xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,2993 +1,24 @@
 /*
- * OMAP3 clock framework
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
- *
- * Written by Paul Walmsley
- * With many device clock fixes by Kevin Hilman and Jouni Högander
- * DPLL bypass clock support added by Roman Tereshonkov
+ * OMAP3 clock function prototypes and macros
  *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
  */
 
-/*
- * Virtual clocks are introduced as convenient tools.
- * They are sources for other clocks and not supposed
- * to be requested from drivers directly.
- */
-
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
-
-#include <mach/control.h>
-
-#include "clock.h"
-#include "cm.h"
-#include "cm-regbits-34xx.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
-
-#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
-
-static unsigned long omap3_dpll_recalc(struct clk *clk);
-static unsigned long omap3_clkoutx2_recalc(struct clk *clk);
-static void omap3_dpll_allow_idle(struct clk *clk);
-static void omap3_dpll_deny_idle(struct clk *clk);
-static u32 omap3_dpll_autoidle_read(struct clk *clk);
-static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
-static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
-static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
-
-/* Maximum DPLL multiplier, divider values for OMAP3 */
-#define OMAP3_MAX_DPLL_MULT		2048
-#define OMAP3_MAX_DPLL_DIV		128
-
-/*
- * DPLL1 supplies clock to the MPU.
- * DPLL2 supplies clock to the IVA2.
- * DPLL3 supplies CORE domain clocks.
- * DPLL4 supplies peripheral clocks.
- * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
- */
-
-/* Forward declarations for DPLL bypass clocks */
-static struct clk dpll1_fck;
-static struct clk dpll2_fck;
-
-/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
-#define DPLL_LOW_POWER_STOP		0x1
-#define DPLL_LOW_POWER_BYPASS		0x5
-#define DPLL_LOCKED			0x7
-
-/* PRM CLOCKS */
-
-/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
-static struct clk omap_32k_fck = {
-	.name		= "omap_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk secure_32k_fck = {
-	.name		= "secure_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.flags		= RATE_FIXED,
-};
-
-/* Virtual source clocks for osc_sys_ck */
-static struct clk virt_12m_ck = {
-	.name		= "virt_12m_ck",
-	.ops		= &clkops_null,
-	.rate		= 12000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_13m_ck = {
-	.name		= "virt_13m_ck",
-	.ops		= &clkops_null,
-	.rate		= 13000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_16_8m_ck = {
-	.name		= "virt_16_8m_ck",
-	.ops		= &clkops_null,
-	.rate		= 16800000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_19_2m_ck = {
-	.name		= "virt_19_2m_ck",
-	.ops		= &clkops_null,
-	.rate		= 19200000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_26m_ck = {
-	.name		= "virt_26m_ck",
-	.ops		= &clkops_null,
-	.rate		= 26000000,
-	.flags		= RATE_FIXED,
-};
-
-static struct clk virt_38_4m_ck = {
-	.name		= "virt_38_4m_ck",
-	.ops		= &clkops_null,
-	.rate		= 38400000,
-	.flags		= RATE_FIXED,
-};
-
-static const struct clksel_rate osc_sys_12m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_13m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_16_8m_rates[] = {
-	{ .div = 1, .val = 5, .flags = RATE_IN_3430ES2 | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_19_2m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_26m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_38_4m_rates[] = {
-	{ .div = 1, .val = 4, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel osc_sys_clksel[] = {
-	{ .parent = &virt_12m_ck,   .rates = osc_sys_12m_rates },
-	{ .parent = &virt_13m_ck,   .rates = osc_sys_13m_rates },
-	{ .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
-	{ .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates },
-	{ .parent = &virt_26m_ck,   .rates = osc_sys_26m_rates },
-	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
-	{ .parent = NULL },
-};
-
-/* Oscillator clock */
-/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
-static struct clk osc_sys_ck = {
-	.name		= "osc_sys_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSEL,
-	.clksel_mask	= OMAP3430_SYS_CLKIN_SEL_MASK,
-	.clksel		= osc_sys_clksel,
-	/* REVISIT: deal with autoextclkmode? */
-	.flags		= RATE_FIXED,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate div2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel sys_clksel[] = {
-	{ .parent = &osc_sys_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
-/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
-static struct clk sys_ck = {
-	.name		= "sys_ck",
-	.ops		= &clkops_null,
-	.parent		= &osc_sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSRC_CTRL,
-	.clksel_mask	= OMAP_SYSCLKDIV_MASK,
-	.clksel		= sys_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk sys_altclk = {
-	.name		= "sys_altclk",
-	.ops		= &clkops_null,
-};
-
-/* Optional external clock input for some McBSPs */
-static struct clk mcbsp_clks = {
-	.name		= "mcbsp_clks",
-	.ops		= &clkops_null,
-};
-
-/* PRM EXTERNAL CLOCK OUTPUT */
-
-static struct clk sys_clkout1 = {
-	.name		= "sys_clkout1",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &osc_sys_ck,
-	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLLS */
-
-/* CM CLOCKS */
-
-static const struct clksel_rate div16_dpll_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 5, .val = 5, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 7, .val = 7, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_343X },
-	{ .div = 10, .val = 10, .flags = RATE_IN_343X },
-	{ .div = 11, .val = 11, .flags = RATE_IN_343X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_343X },
-	{ .div = 13, .val = 13, .flags = RATE_IN_343X },
-	{ .div = 14, .val = 14, .flags = RATE_IN_343X },
-	{ .div = 15, .val = 15, .flags = RATE_IN_343X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-/* DPLL1 */
-/* MPU clock source */
-/* Type: DPLL */
-static struct dpll_data dpll1_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll1_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll1_ck = {
-	.name		= "dpll1_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll1_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed.
- */
-static struct clk dpll1_x2_ck = {
-	.name		= "dpll1_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_ck,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
-static const struct clksel div16_dpll1_x2m2_clksel[] = {
-	{ .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * Does not exist in the TRM - needed to separate the M2 divider from
- * bypass selection in mpu_ck
- */
-static struct clk dpll1_x2m2_ck = {
-	.name		= "dpll1_x2m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll1_x2m2_clksel,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL2 */
-/* IVA2 clock source */
-/* Type: DPLL */
-
-static struct dpll_data dpll2_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll2_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
-				(1 << DPLL_LOW_POWER_BYPASS),
-	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll2_ck = {
-	.name		= "dpll2_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll2_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll2_m2x2_clksel[] = {
-	{ .parent = &dpll2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
- * or CLKOUTX2. CLKOUT seems most plausible.
- */
-static struct clk dpll2_m2_ck = {
-	.name		= "dpll2_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
-					  OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll2_m2x2_clksel,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * DPLL3
- * Source clock for all interfaces and for some device fclks
- * REVISIT: Also supports fast relock bypass - not included below
- */
-static struct dpll_data dpll3_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
-	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll3_ck = {
-	.name		= "dpll3_ck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll3_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed
- */
-static struct clk dpll3_x2_ck = {
-	.name		= "dpll3_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate div31_dpll3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3430ES2 },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3430ES2 },
-	{ .div = 5, .val = 5, .flags = RATE_IN_3430ES2 },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3430ES2 },
-	{ .div = 7, .val = 7, .flags = RATE_IN_3430ES2 },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3430ES2 },
-	{ .div = 9, .val = 9, .flags = RATE_IN_3430ES2 },
-	{ .div = 10, .val = 10, .flags = RATE_IN_3430ES2 },
-	{ .div = 11, .val = 11, .flags = RATE_IN_3430ES2 },
-	{ .div = 12, .val = 12, .flags = RATE_IN_3430ES2 },
-	{ .div = 13, .val = 13, .flags = RATE_IN_3430ES2 },
-	{ .div = 14, .val = 14, .flags = RATE_IN_3430ES2 },
-	{ .div = 15, .val = 15, .flags = RATE_IN_3430ES2 },
-	{ .div = 16, .val = 16, .flags = RATE_IN_3430ES2 },
-	{ .div = 17, .val = 17, .flags = RATE_IN_3430ES2 },
-	{ .div = 18, .val = 18, .flags = RATE_IN_3430ES2 },
-	{ .div = 19, .val = 19, .flags = RATE_IN_3430ES2 },
-	{ .div = 20, .val = 20, .flags = RATE_IN_3430ES2 },
-	{ .div = 21, .val = 21, .flags = RATE_IN_3430ES2 },
-	{ .div = 22, .val = 22, .flags = RATE_IN_3430ES2 },
-	{ .div = 23, .val = 23, .flags = RATE_IN_3430ES2 },
-	{ .div = 24, .val = 24, .flags = RATE_IN_3430ES2 },
-	{ .div = 25, .val = 25, .flags = RATE_IN_3430ES2 },
-	{ .div = 26, .val = 26, .flags = RATE_IN_3430ES2 },
-	{ .div = 27, .val = 27, .flags = RATE_IN_3430ES2 },
-	{ .div = 28, .val = 28, .flags = RATE_IN_3430ES2 },
-	{ .div = 29, .val = 29, .flags = RATE_IN_3430ES2 },
-	{ .div = 30, .val = 30, .flags = RATE_IN_3430ES2 },
-	{ .div = 31, .val = 31, .flags = RATE_IN_3430ES2 },
-	{ .div = 0 },
-};
-
-static const struct clksel div31_dpll3m2_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div31_dpll3_rates },
-	{ .parent = NULL }
-};
-
-/* DPLL3 output M2 - primary control point for CORE speed */
-static struct clk dpll3_m2_ck = {
-	.name		= "dpll3_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div31_dpll3m2_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap3_core_dpll_m2_set_rate,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll3_m2x2_ck = {
-	.name		= "dpll3_m2x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static const struct clksel div16_dpll3_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll3_m3x2_ck */
-static struct clk dpll3_m3_ck = {
-	.name		= "dpll3_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_DIV_DPLL3_MASK,
-	.clksel		= div16_dpll3_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll3_m3x2_ck = {
-	.name		= "dpll3_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll3_m3_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_core_alwon_ck = {
-	.name		= "emu_core_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m3x2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL4 */
-/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
-/* Type: DPLL */
-static struct dpll_data dpll4_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll4_ck = {
-	.name		= "dpll4_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll4_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_dpll4_set_rate,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed --
- * XXX does this serve any downstream clocks?
- */
-static struct clk dpll4_x2_ck = {
-	.name		= "dpll4_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel div16_dpll4_clksel[] = {
-	{ .parent = &dpll4_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll4_m2x2_ck */
-static struct clk dpll4_m2_ck = {
-	.name		= "dpll4_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
-	.clksel_mask	= OMAP3430_DIV_96M_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m2x2_ck = {
-	.name		= "dpll4_m2x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/*
- * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
- * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
- * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
- * CM_96K_(F)CLK.
- */
-static struct clk omap_96m_alwon_fck = {
-	.name		= "omap_96m_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cm_96m_fck = {
-	.name		= "cm_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate omap_96m_dpll_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_96m_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_96m_fck_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
-	{ .parent = &sys_ck,	 .rates = omap_96m_sys_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_96m_fck = {
-	.name		= "omap_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_96M_MASK,
-	.clksel		= omap_96m_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m3x2_ck */
-static struct clk dpll4_m3_ck = {
-	.name		= "dpll4_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_TV_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m3x2_ck = {
-	.name		= "dpll4_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_54m_clksel[] = {
-	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
-	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_54m_fck = {
-	.name		= "omap_54m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
-	.clksel		= omap_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate omap_48m_cm96m_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_48m_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
-	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_48m_fck = {
-	.name		= "omap_48m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
-	.clksel		= omap_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk omap_12m_fck = {
-	.name		= "omap_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.fixed_div	= 4,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-/* This virstual clock is the source for dpll4_m4x2_ck */
-static struct clk dpll4_m4_ck = {
-	.name		= "dpll4_m4_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_DSS1_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m4x2_ck = {
-	.name		= "dpll4_m4x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m4_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m5x2_ck */
-static struct clk dpll4_m5_ck = {
-	.name		= "dpll4_m5_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_CAM_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m5x2_ck = {
-	.name		= "dpll4_m5x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m5_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m6x2_ck */
-static struct clk dpll4_m6_ck = {
-	.name		= "dpll4_m6_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_DIV_DPLL4_MASK,
-	.clksel		= div16_dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m6x2_ck = {
-	.name		= "dpll4_m6x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m6_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_per_alwon_ck = {
-	.name		= "emu_per_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m6x2_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL5 */
-/* Supplies 120MHz clock, USIM source clock */
-/* Type: DPLL */
-/* 3430ES2 only */
-static struct dpll_data dpll5_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
-	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
-	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
-	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
-};
-
-static struct clk dpll5_ck = {
-	.name		= "dpll5_ck",
-	.ops		= &clkops_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll5_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll5_clksel[] = {
-	{ .parent = &dpll5_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dpll5_m2_ck = {
-	.name		= "dpll5_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll5_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
-	.clksel_mask	= OMAP3430ES2_DIV_120M_MASK,
-	.clksel		= div16_dpll5_clksel,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CM EXTERNAL CLOCK OUTPUTS */
-
-static const struct clksel_rate clkout2_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel clkout2_src_clksel[] = {
-	{ .parent = &core_ck,		.rates = clkout2_src_core_rates },
-	{ .parent = &sys_ck,		.rates = clkout2_src_sys_rates },
-	{ .parent = &cm_96m_fck,	.rates = clkout2_src_96m_rates },
-	{ .parent = &omap_54m_fck,	.rates = clkout2_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk clkout2_src_ck = {
-	.name		= "clkout2_src_ck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT2_EN_SHIFT,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2SOURCE_MASK,
-	.clksel		= clkout2_src_clksel,
-	.clkdm_name	= "core_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate sys_clkout2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 16, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CM OUTPUT CLOCKS */
-
-static struct clk corex2_fck = {
-	.name		= "corex2_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL power domain clock controls */
-
-static const struct clksel_rate div4_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel div4_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div4_rates },
-	{ .parent = NULL }
-};
-
-/*
- * REVISIT: Are these in DPLL power domain or CM power domain? docs
- * may be inconsistent here?
- */
-static struct clk dpll1_fck = {
-	.name		= "dpll1_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_MPU_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mpu_ck = {
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2m2_ck,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
-static const struct clksel_rate arm_fck_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel arm_fck_clksel[] = {
-	{ .parent = &mpu_ck, .rates = arm_fck_rates },
-	{ .parent = NULL }
-};
-
-static struct clk arm_fck = {
-	.name		= "arm_fck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.clksel		= arm_fck_clksel,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX What about neon_clkdm ? */
-
-/*
- * REVISIT: This clock is never specifically defined in the 3430 TRM,
- * although it is referenced - so this is a guess
- */
-static struct clk emu_mpu_alwon_ck = {
-	.name		= "emu_mpu_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll2_fck = {
-	.name		= "dpll2_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_IVA2_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk iva2_ck = {
-	.name		= "iva2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll2_m2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
-	.clkdm_name	= "iva2_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Common interface clocks */
-
-static const struct clksel div2_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l3_ick = {
-	.name		= "l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L3_MASK,
-	.clksel		= div2_core_clksel,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel div2_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ick = {
-	.name		= "l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L4_MASK,
-	.clksel		= div2_l3_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-
-};
-
-static const struct clksel div2_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk rm_ick = {
-	.name		= "rm_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_RM_MASK,
-	.clksel		= div2_l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* GFX power domain */
-
-/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
-
-static const struct clksel gfx_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = gfx_l3_rates },
-	{ .parent = NULL }
-};
-
-/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
-static struct clk gfx_l3_ck = {
-	.name		= "gfx_l3_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_l3_fck = {
-	.name		= "gfx_l3_fck",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_l3_clksel,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gfx_l3_ick = {
-	.name		= "gfx_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg1_ck = {
-	.name		= "gfx_cg1_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg2_ck = {
-	.name		= "gfx_cg2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SGX power domain - 3430ES2 only */
-
-static const struct clksel_rate sgx_core_rates[] = {
-	{ .div = 3, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 4, .val = 1, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate sgx_96m_rates[] = {
-	{ .div = 1,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel sgx_clksel[] = {
-	{ .parent = &core_ck,	 .rates = sgx_core_rates },
-	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sgx_fck = {
-	.name		= "sgx_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_SGX_MASK,
-	.clksel		= sgx_clksel,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk sgx_ick = {
-	.name		= "sgx_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE power domain */
-
-static struct clk d2d_26m_fck = {
-	.name		= "d2d_26m_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk modem_fck = {
-	.name		= "modem_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sad2d_ick = {
-	.name		= "sad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mad2d_ick = {
-	.name		= "mad2d_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel omap343x_gpt_clksel[] = {
-	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	   .rates = gpt_sys_rates },
-	{ .parent = NULL}
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk cpefuse_fck = {
-	.name		= "cpefuse_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ts_fck = {
-	.name		= "ts_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_fck = {
-	.name		= "usbtll_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll5_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE 96M FCLK-derived clocks */
-
-static struct clk core_96m_fck = {
-	.name		= "core_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
- * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
- */
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_15_clksel[] = {
-	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CORE_48M_FCK-derived clocks */
-
-static struct clk core_48m_fck = {
-	.name		= "core_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fshostusb_fck = {
-	.name		= "fshostusb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_12M_FCK based clocks */
-
-static struct clk core_12m_fck = {
-	.name		= "core_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_12m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_12m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL3-derived clock */
-
-static const struct clksel_rate ssi_ssr_corex2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_343X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_clksel[] = {
-	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_fck_3430es1 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_ssr_fck_3430es2 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap3430es2_ssi_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es1 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es1,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es2 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es2,
-	.fixed_div	= 2,
-	.recalc		= &omap2_fixed_divisor_recalc,
-};
-
-
-
-/* CORE_L3_ICK based clocks */
-
-/*
- * XXX must add clk_enable/clk_disable for these if standard code won't
- * handle it
- */
-static struct clk core_l3_ick = {
-	.name		= "core_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es1 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es2 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap3430es2_hsotgusb_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ick,
-	.flags		= ENABLE_ON_INIT, /* huh? */
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SECURITY_L3_ICK based clocks */
-
-static struct clk security_l3_ick = {
-	.name		= "security_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_L4_ICK based clocks */
-
-static struct clk core_l4_ick = {
-	.name		= "core_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_ick = {
-	.name		= "usbtll_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Intersystem Communication Registers - chassis mode only */
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes2_ick = {
-	.name		= "aes2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha12_ick = {
-	.name		= "sha12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des2_ick = {
-	.name		= "des2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 5,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 1,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.recalc		= &followparent_recalc,
-};
-
-/* SSI_L4_ICK based clocks */
-
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es1 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es2 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap3430es2_ssi_wait,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
- * but l4_ick makes more sense to me */
-
-static const struct clksel usb_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk usb_l4_ick = {
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
-	.clksel		= usb_l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SECURITY_L4_ICK2 based clocks */
-
-static struct clk security_l4_ick2 = {
-	.name		= "security_l4_ick2",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes1_ick = {
-	.name		= "aes1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha11_ick = {
-	.name		= "sha11_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des1_ick = {
-	.name		= "des1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DSS */
-static struct clk dss1_alwon_fck_3430es1 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_alwon_fck_3430es2 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_tv_fck = {
-	.name		= "dss_tv_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_54m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_96m_fck = {
-	.name		= "dss_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss2_alwon_fck = {
-	.name		= "dss2_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es1 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es2 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CAM */
-
-static struct clk cam_mclk = {
-	.name		= "cam_mclk",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m5x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk csi2_96m_fck = {
-	.name		= "csi2_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* USBHOST - 3430ES2 only */
-
-static struct clk usbhost_120m_fck = {
-	.name		= "usbhost_120m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll5_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_48m_fck = {
-	.name		= "usbhost_48m_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &omap_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "usbhost_ick",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* WKUP */
-
-static const struct clksel_rate usim_96m_rates[] = {
-	{ .div = 2,  .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 4,  .val = 4, .flags = RATE_IN_343X },
-	{ .div = 8,  .val = 5, .flags = RATE_IN_343X },
-	{ .div = 10, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate usim_120m_rates[] = {
-	{ .div = 4,  .val = 7,	.flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 8,  .val = 8,	.flags = RATE_IN_343X },
-	{ .div = 16, .val = 9,	.flags = RATE_IN_343X },
-	{ .div = 20, .val = 10, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel usim_clksel[] = {
-	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
-	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
-	{ .parent = &sys_ck,		.rates = div2_rates },
-	{ .parent = NULL },
-};
-
-/* 3430ES2 only */
-static struct clk usim_fck = {
-	.name		= "usim_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_USIMOCP_MASK,
-	.clksel		= usim_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT1_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk wkup_32k_fck = {
-	.name		= "wkup_32k_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_dbck = {
-	.name		= "gpio1_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_fck = {
-	.name		= "wdt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wkup_l4_ick = {
-	.name		= "wkup_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* 3430ES2 only */
-/* Never specifically named in the TRM, so we have to infer a likely name */
-static struct clk usim_ick = {
-	.name		= "usim_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_ick = {
-	.name		= "wdt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_ick = {
-	.name		= "gpio1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omap_32ksync_ick = {
-	.name		= "omap_32ksync_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* XXX This clock no longer exists in 3430 TRM rev F */
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-
-
-/* PER clock domain */
-
-static struct clk per_96m_fck = {
-	.name		= "per_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_48m_fck = {
-	.name		= "per_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT2_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT3_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT4_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT5_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT6_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT7_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT8_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT9_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk per_32k_alwon_fck = {
-	.name		= "per_32k_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_dbck = {
-	.name		= "gpio6_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_dbck = {
-	.name		= "gpio5_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_dbck = {
-	.name		= "gpio4_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_dbck = {
-	.name		= "gpio3_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_dbck = {
-	.name		= "gpio2_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_l4_ick = {
-	.name		= "per_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_ick = {
-	.name		= "gpio6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_ick = {
-	.name		= "gpio4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_ick = {
-	.name		= "gpio3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_ick = {
-	.name		= "gpio2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel mcbsp_234_clksel[] = {
-	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 2,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 3,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.id		= 4,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* EMU clocks */
-
-/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
-
-static const struct clksel_rate emu_src_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_per_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_mpu_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 },
-};
-
-static const struct clksel emu_src_clksel[] = {
-	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
-	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
-	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
-	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
-	{ .parent = NULL },
-};
-
-/*
- * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
- * to switch the source of some of the EMU clocks.
- * XXX Are there CLKEN bits for these EMU clks?
- */
-static struct clk emu_src_ck = {
-	.name		= "emu_src_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclk_emu_rates[] = {
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel pclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclk_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclk_fck = {
-	.name		= "pclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLK_MASK,
-	.clksel		= pclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclkx2_emu_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel pclkx2_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclkx2_fck = {
-	.name		= "pclkx2_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLKX2_MASK,
-	.clksel		= pclkx2_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel atclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk atclk_fck = {
-	.name		= "atclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_ATCLK_MASK,
-	.clksel		= atclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk traceclk_src_fck = {
-	.name		= "traceclk_src_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_TRACE_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate traceclk_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_343X },
-	{ .div = 0 },
-};
-
-static const struct clksel traceclk_clksel[] = {
-	{ .parent = &traceclk_src_fck, .rates = traceclk_rates },
-	{ .parent = NULL },
-};
-
-static struct clk traceclk_fck = {
-	.name		= "traceclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_TRACECLK_MASK,
-	.clksel		= traceclk_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SR clocks */
-
-/* SmartReflex fclk (VDD1) */
-static struct clk sr1_fck = {
-	.name		= "sr1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* SmartReflex fclk (VDD2) */
-static struct clk sr2_fck = {
-	.name		= "sr2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sr_l4_ick = {
-	.name		= "sr_l4_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
 
-/* SECURE_32K_FCK clocks */
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
+void omap3_clk_lock_dpll5(void);
 
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.recalc		= &followparent_recalc,
-};
+extern struct clk *sdrc_ick_p;
+extern struct clk *arm_fck_p;
 
-static struct clk wdt1_fck = {
-	.name		= "wdt1_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.recalc		= &followparent_recalc,
-};
+/* OMAP34xx-specific clkops */
+extern const struct clkops clkops_omap3430es2_ssi_wait;
+extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
+extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
+extern const struct clkops clkops_noncore_dpll_ops;
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+/*
+ * OMAP4-specific clock framework functions
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Rajendra Nayak (rnayak@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/errno.h>
+#include "clock.h"
+
+struct clk_functions omap2_clk_functions = {
+	.clk_enable		= omap2_clk_enable,
+	.clk_disable		= omap2_clk_disable,
+	.clk_round_rate		= omap2_clk_round_rate,
+	.clk_set_rate		= omap2_clk_set_rate,
+	.clk_set_parent		= omap2_clk_set_parent,
+	.clk_disable_unused	= omap2_clk_disable_unused,
+};
+
+const struct clkops clkops_noncore_dpll_ops = {
+	.enable		= &omap3_noncore_dpll_enable,
+	.disable	= &omap3_noncore_dpll_disable,
+};
+
+void omap2_clk_prepare_for_reboot(void)
+{
+	return;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2766 @@
+/*
+ * OMAP4 Clock data
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <plat/control.h>
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock44xx.h"
+#include "cm.h"
+#include "cm-regbits-44xx.h"
+#include "prm.h"
+#include "prm-regbits-44xx.h"
+
+/* Root clocks */
+
+static struct clk extalt_clkin_ck = {
+	.name		= "extalt_clkin_ck",
+	.rate		= 59000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk pad_clks_ck = {
+	.name		= "pad_clks_ck",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk pad_slimbus_core_clks_ck = {
+	.name		= "pad_slimbus_core_clks_ck",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk secure_32k_clk_src_ck = {
+	.name		= "secure_32k_clk_src_ck",
+	.rate		= 32768,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk slimbus_clk = {
+	.name		= "slimbus_clk",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk sys_32k_ck = {
+	.name		= "sys_32k_ck",
+	.rate		= 32768,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk virt_12000000_ck = {
+	.name		= "virt_12000000_ck",
+	.ops		= &clkops_null,
+	.rate		= 12000000,
+};
+
+static struct clk virt_13000000_ck = {
+	.name		= "virt_13000000_ck",
+	.ops		= &clkops_null,
+	.rate		= 13000000,
+};
+
+static struct clk virt_16800000_ck = {
+	.name		= "virt_16800000_ck",
+	.ops		= &clkops_null,
+	.rate		= 16800000,
+};
+
+static struct clk virt_19200000_ck = {
+	.name		= "virt_19200000_ck",
+	.ops		= &clkops_null,
+	.rate		= 19200000,
+};
+
+static struct clk virt_26000000_ck = {
+	.name		= "virt_26000000_ck",
+	.ops		= &clkops_null,
+	.rate		= 26000000,
+};
+
+static struct clk virt_27000000_ck = {
+	.name		= "virt_27000000_ck",
+	.ops		= &clkops_null,
+	.rate		= 27000000,
+};
+
+static struct clk virt_38400000_ck = {
+	.name		= "virt_38400000_ck",
+	.ops		= &clkops_null,
+	.rate		= 38400000,
+};
+
+static const struct clksel_rate div_1_0_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_1_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_2_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_3_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_4_rates[] = {
+	{ .div = 1, .val = 4, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_5_rates[] = {
+	{ .div = 1, .val = 5, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_6_rates[] = {
+	{ .div = 1, .val = 6, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate div_1_7_rates[] = {
+	{ .div = 1, .val = 7, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel sys_clkin_sel[] = {
+	{ .parent = &virt_12000000_ck, .rates = div_1_1_rates },
+	{ .parent = &virt_13000000_ck, .rates = div_1_2_rates },
+	{ .parent = &virt_16800000_ck, .rates = div_1_3_rates },
+	{ .parent = &virt_19200000_ck, .rates = div_1_4_rates },
+	{ .parent = &virt_26000000_ck, .rates = div_1_5_rates },
+	{ .parent = &virt_27000000_ck, .rates = div_1_6_rates },
+	{ .parent = &virt_38400000_ck, .rates = div_1_7_rates },
+	{ .parent = NULL },
+};
+
+static struct clk sys_clkin_ck = {
+	.name		= "sys_clkin_ck",
+	.rate		= 38400000,
+	.clksel		= sys_clkin_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_SYS_CLKSEL,
+	.clksel_mask	= OMAP4430_SYS_CLKSEL_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk utmi_phy_clkout_ck = {
+	.name		= "utmi_phy_clkout_ck",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk xclk60mhsp1_ck = {
+	.name		= "xclk60mhsp1_ck",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk xclk60mhsp2_ck = {
+	.name		= "xclk60mhsp2_ck",
+	.rate		= 12000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+static struct clk xclk60motg_ck = {
+	.name		= "xclk60motg_ck",
+	.rate		= 60000000,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_IN_OMAP4430 | ALWAYS_ENABLED,
+};
+
+/* Module clocks and DPLL outputs */
+
+static const struct clksel_rate div2_1to2_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel dpll_sys_ref_clk_div[] = {
+	{ .parent = &sys_clkin_ck, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_sys_ref_clk = {
+	.name		= "dpll_sys_ref_clk",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dpll_sys_ref_clk_div,
+	.clksel_reg	= OMAP4430_CM_DPLL_SYS_REF_CLKSEL,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel abe_dpll_refclk_mux_sel[] = {
+	{ .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk abe_dpll_refclk_mux_ck = {
+	.name		= "abe_dpll_refclk_mux_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.clksel		= abe_dpll_refclk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_ABE_PLL_REF_CLKSEL,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_ABE */
+static struct dpll_data dpll_abe_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_ABE,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &abe_dpll_refclk_mux_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_ABE,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_ABE,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_ABE,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_abe_ck = {
+	.name		= "dpll_abe_ck",
+	.parent		= &abe_dpll_refclk_mux_ck,
+	.dpll_data	= &dpll_abe_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_abe_m2x2_ck = {
+	.name		= "dpll_abe_m2x2_ck",
+	.parent		= &dpll_abe_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk abe_24m_fclk = {
+	.name		= "abe_24m_fclk",
+	.parent		= &dpll_abe_m2x2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div3_1to4_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel abe_clk_div[] = {
+	{ .parent = &dpll_abe_m2x2_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk abe_clk = {
+	.name		= "abe_clk",
+	.parent		= &dpll_abe_m2x2_ck,
+	.clksel		= abe_clk_div,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_ABE,
+	.clksel_mask	= OMAP4430_CLKSEL_OPP_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel aess_fclk_div[] = {
+	{ .parent = &abe_clk, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk aess_fclk = {
+	.name		= "aess_fclk",
+	.parent		= &abe_clk,
+	.clksel		= aess_fclk_div,
+	.clksel_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_AESS_FCLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div31_1to31_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 2, .val = 2, .flags = RATE_IN_4430 },
+	{ .div = 3, .val = 3, .flags = RATE_IN_4430 },
+	{ .div = 4, .val = 4, .flags = RATE_IN_4430 },
+	{ .div = 5, .val = 5, .flags = RATE_IN_4430 },
+	{ .div = 6, .val = 6, .flags = RATE_IN_4430 },
+	{ .div = 7, .val = 7, .flags = RATE_IN_4430 },
+	{ .div = 8, .val = 8, .flags = RATE_IN_4430 },
+	{ .div = 9, .val = 9, .flags = RATE_IN_4430 },
+	{ .div = 10, .val = 10, .flags = RATE_IN_4430 },
+	{ .div = 11, .val = 11, .flags = RATE_IN_4430 },
+	{ .div = 12, .val = 12, .flags = RATE_IN_4430 },
+	{ .div = 13, .val = 13, .flags = RATE_IN_4430 },
+	{ .div = 14, .val = 14, .flags = RATE_IN_4430 },
+	{ .div = 15, .val = 15, .flags = RATE_IN_4430 },
+	{ .div = 16, .val = 16, .flags = RATE_IN_4430 },
+	{ .div = 17, .val = 17, .flags = RATE_IN_4430 },
+	{ .div = 18, .val = 18, .flags = RATE_IN_4430 },
+	{ .div = 19, .val = 19, .flags = RATE_IN_4430 },
+	{ .div = 20, .val = 20, .flags = RATE_IN_4430 },
+	{ .div = 21, .val = 21, .flags = RATE_IN_4430 },
+	{ .div = 22, .val = 22, .flags = RATE_IN_4430 },
+	{ .div = 23, .val = 23, .flags = RATE_IN_4430 },
+	{ .div = 24, .val = 24, .flags = RATE_IN_4430 },
+	{ .div = 25, .val = 25, .flags = RATE_IN_4430 },
+	{ .div = 26, .val = 26, .flags = RATE_IN_4430 },
+	{ .div = 27, .val = 27, .flags = RATE_IN_4430 },
+	{ .div = 28, .val = 28, .flags = RATE_IN_4430 },
+	{ .div = 29, .val = 29, .flags = RATE_IN_4430 },
+	{ .div = 30, .val = 30, .flags = RATE_IN_4430 },
+	{ .div = 31, .val = 31, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel dpll_abe_m3_div[] = {
+	{ .parent = &dpll_abe_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_abe_m3_ck = {
+	.name		= "dpll_abe_m3_ck",
+	.parent		= &dpll_abe_ck,
+	.clksel		= dpll_abe_m3_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_ABE,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel core_hsd_byp_clk_mux_sel[] = {
+	{ .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+	{ .parent = &dpll_abe_m3_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk core_hsd_byp_clk_mux_ck = {
+	.name		= "core_hsd_byp_clk_mux_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.clksel		= core_hsd_byp_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_DPLL_CORE,
+	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_CORE */
+static struct dpll_data dpll_core_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_CORE,
+	.clk_bypass	= &core_hsd_byp_clk_mux_ck,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_CORE,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_CORE,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_CORE,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_core_ck = {
+	.name		= "dpll_core_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_core_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_null,
+	.recalc		= &omap3_dpll_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_core_m6_div[] = {
+	{ .parent = &dpll_core_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_core_m6_ck = {
+	.name		= "dpll_core_m6_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_CORE,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dbgclk_mux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_core_m6_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dbgclk_mux_ck = {
+	.name		= "dbgclk_mux_ck",
+	.parent		= &sys_clkin_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_core_m2_ck = {
+	.name		= "dpll_core_m2_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_CORE,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk ddrphy_ck = {
+	.name		= "ddrphy_ck",
+	.parent		= &dpll_core_m2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_core_m5_ck = {
+	.name		= "dpll_core_m5_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_CORE,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel div_core_div[] = {
+	{ .parent = &dpll_core_m5_ck, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk div_core_ck = {
+	.name		= "div_core_ck",
+	.parent		= &dpll_core_m5_ck,
+	.clksel		= div_core_div,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
+	.clksel_mask	= OMAP4430_CLKSEL_CORE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div4_1to8_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
+	{ .div = 8, .val = 3, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel div_iva_hs_clk_div[] = {
+	{ .parent = &dpll_core_m5_ck, .rates = div4_1to8_rates },
+	{ .parent = NULL },
+};
+
+static struct clk div_iva_hs_clk = {
+	.name		= "div_iva_hs_clk",
+	.parent		= &dpll_core_m5_ck,
+	.clksel		= div_iva_hs_clk_div,
+	.clksel_reg	= OMAP4430_CM_BYPCLK_DPLL_IVA,
+	.clksel_mask	= OMAP4430_CLKSEL_0_1_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk div_mpu_hs_clk = {
+	.name		= "div_mpu_hs_clk",
+	.parent		= &dpll_core_m5_ck,
+	.clksel		= div_iva_hs_clk_div,
+	.clksel_reg	= OMAP4430_CM_BYPCLK_DPLL_MPU,
+	.clksel_mask	= OMAP4430_CLKSEL_0_1_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_core_m4_ck = {
+	.name		= "dpll_core_m4_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_CORE,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dll_clk_div_ck = {
+	.name		= "dll_clk_div_ck",
+	.parent		= &dpll_core_m4_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_abe_m2_ck = {
+	.name		= "dpll_abe_m2_ck",
+	.parent		= &dpll_abe_ck,
+	.clksel		= dpll_abe_m3_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_core_m3_ck = {
+	.name		= "dpll_core_m3_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_CORE,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_core_m7_ck = {
+	.name		= "dpll_core_m7_ck",
+	.parent		= &dpll_core_ck,
+	.clksel		= dpll_core_m6_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_CORE,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
+	{ .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+	{ .parent = &div_iva_hs_clk, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk iva_hsd_byp_clk_mux_ck = {
+	.name		= "iva_hsd_byp_clk_mux_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_IVA */
+static struct dpll_data dpll_iva_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_IVA,
+	.clk_bypass	= &iva_hsd_byp_clk_mux_ck,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_IVA,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_IVA,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_IVA,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_iva_ck = {
+	.name		= "dpll_iva_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_iva_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_iva_m4_div[] = {
+	{ .parent = &dpll_iva_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_iva_m4_ck = {
+	.name		= "dpll_iva_m4_ck",
+	.parent		= &dpll_iva_ck,
+	.clksel		= dpll_iva_m4_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_IVA,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_iva_m5_ck = {
+	.name		= "dpll_iva_m5_ck",
+	.parent		= &dpll_iva_ck,
+	.clksel		= dpll_iva_m4_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_IVA,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_MPU */
+static struct dpll_data dpll_mpu_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_MPU,
+	.clk_bypass	= &div_mpu_hs_clk,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_MPU,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_MPU,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_MPU,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_mpu_ck = {
+	.name		= "dpll_mpu_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_mpu_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_mpu_m2_div[] = {
+	{ .parent = &dpll_mpu_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_mpu_m2_ck = {
+	.name		= "dpll_mpu_m2_ck",
+	.parent		= &dpll_mpu_ck,
+	.clksel		= dpll_mpu_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_MPU,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk per_hs_clk_div_ck = {
+	.name		= "per_hs_clk_div_ck",
+	.parent		= &dpll_abe_m3_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel per_hsd_byp_clk_mux_sel[] = {
+	{ .parent = &dpll_sys_ref_clk, .rates = div_1_0_rates },
+	{ .parent = &per_hs_clk_div_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk per_hsd_byp_clk_mux_ck = {
+	.name		= "per_hsd_byp_clk_mux_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.clksel		= per_hsd_byp_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_DPLL_PER,
+	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_PER */
+static struct dpll_data dpll_per_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_PER,
+	.clk_bypass	= &per_hsd_byp_clk_mux_ck,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_PER,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_PER,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_PER,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_per_ck = {
+	.name		= "dpll_per_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_per_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_per_m2_div[] = {
+	{ .parent = &dpll_per_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_per_m2_ck = {
+	.name		= "dpll_per_m2_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m2x2_ck = {
+	.name		= "dpll_per_m2x2_ck",
+	.parent		= &dpll_per_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m3_ck = {
+	.name		= "dpll_per_m3_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_PER,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m4_ck = {
+	.name		= "dpll_per_m4_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_PER,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m5_ck = {
+	.name		= "dpll_per_m5_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_PER,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m6_ck = {
+	.name		= "dpll_per_m6_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_PER,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_per_m7_ck = {
+	.name		= "dpll_per_m7_ck",
+	.parent		= &dpll_per_ck,
+	.clksel		= dpll_per_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_PER,
+	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_UNIPRO */
+static struct dpll_data dpll_unipro_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_UNIPRO,
+	.clk_bypass	= &dpll_sys_ref_clk,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_UNIPRO,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_UNIPRO,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_unipro_ck = {
+	.name		= "dpll_unipro_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_unipro_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_unipro_m2x2_div[] = {
+	{ .parent = &dpll_unipro_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_unipro_m2x2_ck = {
+	.name		= "dpll_unipro_m2x2_ck",
+	.parent		= &dpll_unipro_ck,
+	.clksel		= dpll_unipro_m2x2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_UNIPRO,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk usb_hs_clk_div_ck = {
+	.name		= "usb_hs_clk_div_ck",
+	.parent		= &dpll_abe_m3_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* DPLL_USB */
+static struct dpll_data dpll_usb_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_USB,
+	.clk_bypass	= &usb_hs_clk_div_ck,
+	.clk_ref	= &dpll_sys_ref_clk,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_USB,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_USB,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_USB,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= OMAP4430_MAX_DPLL_MULT,
+	.max_divider	= OMAP4430_MAX_DPLL_DIV,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_usb_ck = {
+	.name		= "dpll_usb_ck",
+	.parent		= &dpll_sys_ref_clk,
+	.dpll_data	= &dpll_usb_dd,
+	.init		= &omap2_init_dpll_parent,
+	.ops		= &clkops_noncore_dpll_ops,
+	.recalc		= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk dpll_usb_clkdcoldo_ck = {
+	.name		= "dpll_usb_clkdcoldo_ck",
+	.parent		= &dpll_usb_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel dpll_usb_m2_div[] = {
+	{ .parent = &dpll_usb_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dpll_usb_m2_ck = {
+	.name		= "dpll_usb_m2_ck",
+	.parent		= &dpll_usb_ck,
+	.clksel		= dpll_usb_m2_div,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_USB,
+	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel ducati_clk_mux_sel[] = {
+	{ .parent = &div_core_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_per_m6_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk ducati_clk_mux_ck = {
+	.name		= "ducati_clk_mux_ck",
+	.parent		= &div_core_ck,
+	.clksel		= ducati_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk func_12m_fclk = {
+	.name		= "func_12m_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk func_24m_clk = {
+	.name		= "func_24m_clk",
+	.parent		= &dpll_per_m2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk func_24mc_fclk = {
+	.name		= "func_24mc_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div2_4to8_rates[] = {
+	{ .div = 4, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 8, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel func_48m_fclk_div[] = {
+	{ .parent = &dpll_per_m2x2_ck, .rates = div2_4to8_rates },
+	{ .parent = NULL },
+};
+
+static struct clk func_48m_fclk = {
+	.name		= "func_48m_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.clksel		= func_48m_fclk_div,
+	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
+	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk func_48mc_fclk = {
+	.name		= "func_48mc_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div2_2to4_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 4, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel func_64m_fclk_div[] = {
+	{ .parent = &dpll_per_m4_ck, .rates = div2_2to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk func_64m_fclk = {
+	.name		= "func_64m_fclk",
+	.parent		= &dpll_per_m4_ck,
+	.clksel		= func_64m_fclk_div,
+	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
+	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_96m_fclk_div[] = {
+	{ .parent = &dpll_per_m2x2_ck, .rates = div2_2to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk func_96m_fclk = {
+	.name		= "func_96m_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.clksel		= func_96m_fclk_div,
+	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
+	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel hsmmc6_fclk_sel[] = {
+	{ .parent = &func_64m_fclk, .rates = div_1_0_rates },
+	{ .parent = &func_96m_fclk, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk hsmmc6_fclk = {
+	.name		= "hsmmc6_fclk",
+	.parent		= &func_64m_fclk,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div2_1to8_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 8, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel init_60m_fclk_div[] = {
+	{ .parent = &dpll_usb_m2_ck, .rates = div2_1to8_rates },
+	{ .parent = NULL },
+};
+
+static struct clk init_60m_fclk = {
+	.name		= "init_60m_fclk",
+	.parent		= &dpll_usb_m2_ck,
+	.clksel		= init_60m_fclk_div,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_USB_60MHZ,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel l3_div_div[] = {
+	{ .parent = &div_core_ck, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk l3_div_ck = {
+	.name		= "l3_div_ck",
+	.parent		= &div_core_ck,
+	.clksel		= l3_div_div,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
+	.clksel_mask	= OMAP4430_CLKSEL_L3_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel l4_div_div[] = {
+	{ .parent = &l3_div_ck, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk l4_div_ck = {
+	.name		= "l4_div_ck",
+	.parent		= &l3_div_ck,
+	.clksel		= l4_div_div,
+	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
+	.clksel_mask	= OMAP4430_CLKSEL_L4_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk lp_clk_div_ck = {
+	.name		= "lp_clk_div_ck",
+	.parent		= &dpll_abe_m2x2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel l4_wkup_clk_mux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &lp_clk_div_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk l4_wkup_clk_mux_ck = {
+	.name		= "l4_wkup_clk_mux_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= l4_wkup_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4_WKUP_CLKSEL,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel per_abe_nc_fclk_div[] = {
+	{ .parent = &dpll_abe_m2_ck, .rates = div2_1to2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk per_abe_nc_fclk = {
+	.name		= "per_abe_nc_fclk",
+	.parent		= &dpll_abe_m2_ck,
+	.clksel		= per_abe_nc_fclk_div,
+	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
+	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel mcasp2_fclk_sel[] = {
+	{ .parent = &func_96m_fclk, .rates = div_1_0_rates },
+	{ .parent = &per_abe_nc_fclk, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk mcasp2_fclk = {
+	.name		= "mcasp2_fclk",
+	.parent		= &func_96m_fclk,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk mcasp3_fclk = {
+	.name		= "mcasp3_fclk",
+	.parent		= &func_96m_fclk,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk ocp_abe_iclk = {
+	.name		= "ocp_abe_iclk",
+	.parent		= &aess_fclk,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk per_abe_24m_fclk = {
+	.name		= "per_abe_24m_fclk",
+	.parent		= &dpll_abe_m2_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel pmd_stm_clock_mux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_core_m6_ck, .rates = div_1_1_rates },
+	{ .parent = &dpll_per_m7_ck, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pmd_stm_clock_mux_ck = {
+	.name		= "pmd_stm_clock_mux_ck",
+	.parent		= &sys_clkin_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk pmd_trace_clk_mux_ck = {
+	.name		= "pmd_trace_clk_mux_ck",
+	.parent		= &sys_clkin_ck,
+	.ops		= &clkops_null,
+	.recalc		= &followparent_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static struct clk syc_clk_div_ck = {
+	.name		= "syc_clk_div_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dpll_sys_ref_clk_div,
+	.clksel_reg	= OMAP4430_CM_ABE_DSS_SYS_CLKSEL,
+	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/* Leaf clocks controlled by modules */
+
+static struct clk aes1_ck = {
+	.name		= "aes1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_AES1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aes2_ck = {
+	.name		= "aes2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_AES2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk aess_ck = {
+	.name		= "aess_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+	.parent		= &aess_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk cust_efuse_ck = {
+	.name		= "cust_efuse_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_cefuse_clkdm",
+	.parent		= &sys_clkin_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk des3des_ck = {
+	.name		= "des3des_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel dmic_sync_mux_sel[] = {
+	{ .parent = &abe_24m_fclk, .rates = div_1_0_rates },
+	{ .parent = &syc_clk_div_ck, .rates = div_1_1_rates },
+	{ .parent = &func_24m_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk dmic_sync_mux_ck = {
+	.name		= "dmic_sync_mux_ck",
+	.parent		= &abe_24m_fclk,
+	.clksel		= dmic_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_dmic_abe_gfclk_sel[] = {
+	{ .parent = &dmic_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+/* Merged func_dmic_abe_gfclk into dmic_ck */
+static struct clk dmic_ck = {
+	.name		= "dmic_ck",
+	.parent		= &dmic_sync_mux_ck,
+	.clksel		= func_dmic_abe_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+static struct clk dss_ck = {
+	.name		= "dss_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_dss_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ducati_ck = {
+	.name		= "ducati_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "ducati_clkdm",
+	.parent		= &ducati_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk emif1_ck = {
+	.name		= "emif1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_emif_clkdm",
+	.parent		= &ddrphy_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk emif2_ck = {
+	.name		= "emif2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_emif_clkdm",
+	.parent		= &ddrphy_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel fdif_fclk_div[] = {
+	{ .parent = &dpll_per_m4_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+/* Merged fdif_fclk into fdif_ck */
+static struct clk fdif_ck = {
+	.name		= "fdif_ck",
+	.parent		= &dpll_per_m4_ck,
+	.clksel		= fdif_fclk_div,
+	.clksel_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_FCLK_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "iss_clkdm",
+};
+
+static const struct clksel per_sgx_fclk_div[] = {
+	{ .parent = &dpll_per_m2x2_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk per_sgx_fclk = {
+	.name		= "per_sgx_fclk",
+	.parent		= &dpll_per_m2x2_ck,
+	.clksel		= per_sgx_fclk_div,
+	.clksel_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_PER_192M_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel sgx_clk_mux_sel[] = {
+	{ .parent = &dpll_core_m7_ck, .rates = div_1_0_rates },
+	{ .parent = &per_sgx_fclk, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+/* Merged sgx_clk_mux into gfx_ck */
+static struct clk gfx_ck = {
+	.name		= "gfx_ck",
+	.parent		= &dpll_core_m7_ck,
+	.clksel		= sgx_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SGX_FCLK_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_gfx_clkdm",
+};
+
+static struct clk gpio1_ck = {
+	.name		= "gpio1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_wkup_clkdm",
+	.parent		= &l4_wkup_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio2_ck = {
+	.name		= "gpio2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio3_ck = {
+	.name		= "gpio3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio4_ck = {
+	.name		= "gpio4_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio5_ck = {
+	.name		= "gpio5_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpio6_ck = {
+	.name		= "gpio6_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk gpmc_ck = {
+	.name		= "gpmc_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3_2_GPMC_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_2_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static const struct clksel dmt1_clk_mux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+/* Merged dmt1_clk_mux into gptimer1_ck */
+static struct clk gptimer1_ck = {
+	.name		= "gptimer1_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_wkup_clkdm",
+};
+
+/* Merged cm2_dm10_mux into gptimer10_ck */
+static struct clk gptimer10_ck = {
+	.name		= "gptimer10_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+/* Merged cm2_dm11_mux into gptimer11_ck */
+static struct clk gptimer11_ck = {
+	.name		= "gptimer11_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+/* Merged cm2_dm2_mux into gptimer2_ck */
+static struct clk gptimer2_ck = {
+	.name		= "gptimer2_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+/* Merged cm2_dm3_mux into gptimer3_ck */
+static struct clk gptimer3_ck = {
+	.name		= "gptimer3_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+/* Merged cm2_dm4_mux into gptimer4_ck */
+static struct clk gptimer4_ck = {
+	.name		= "gptimer4_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+static const struct clksel timer5_sync_mux_sel[] = {
+	{ .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
+	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+/* Merged timer5_sync_mux into gptimer5_ck */
+static struct clk gptimer5_ck = {
+	.name		= "gptimer5_ck",
+	.parent		= &syc_clk_div_ck,
+	.clksel		= timer5_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+/* Merged timer6_sync_mux into gptimer6_ck */
+static struct clk gptimer6_ck = {
+	.name		= "gptimer6_ck",
+	.parent		= &syc_clk_div_ck,
+	.clksel		= timer5_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+/* Merged timer7_sync_mux into gptimer7_ck */
+static struct clk gptimer7_ck = {
+	.name		= "gptimer7_ck",
+	.parent		= &syc_clk_div_ck,
+	.clksel		= timer5_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+/* Merged timer8_sync_mux into gptimer8_ck */
+static struct clk gptimer8_ck = {
+	.name		= "gptimer8_ck",
+	.parent		= &syc_clk_div_ck,
+	.clksel		= timer5_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+/* Merged cm2_dm9_mux into gptimer9_ck */
+static struct clk gptimer9_ck = {
+	.name		= "gptimer9_ck",
+	.parent		= &sys_clkin_ck,
+	.clksel		= dmt1_clk_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+static struct clk hdq1w_ck = {
+	.name		= "hdq1w_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_12m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+/* Merged hsi_fclk into hsi_ck */
+static struct clk hsi_ck = {
+	.name		= "hsi_ck",
+	.parent		= &dpll_per_m2x2_ck,
+	.clksel		= per_sgx_fclk_div,
+	.clksel_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_24_25_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+};
+
+static struct clk i2c1_ck = {
+	.name		= "i2c1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_96m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c2_ck = {
+	.name		= "i2c2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_96m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c3_ck = {
+	.name		= "i2c3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_96m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk i2c4_ck = {
+	.name		= "i2c4_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_96m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk iss_ck = {
+	.name		= "iss_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_CAM_ISS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "iss_clkdm",
+	.parent		= &ducati_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ivahd_ck = {
+	.name		= "ivahd_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "ivahd_clkdm",
+	.parent		= &dpll_iva_m5_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk keyboard_ck = {
+	.name		= "keyboard_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_wkup_clkdm",
+	.parent		= &sys_32k_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk l3_instr_interconnect_ck = {
+	.name		= "l3_instr_interconnect_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_instr_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk l3_interconnect_3_ck = {
+	.name		= "l3_interconnect_3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_instr_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcasp_sync_mux_ck = {
+	.name		= "mcasp_sync_mux_ck",
+	.parent		= &abe_24m_fclk,
+	.clksel		= dmic_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_mcasp_abe_gfclk_sel[] = {
+	{ .parent = &mcasp_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+/* Merged func_mcasp_abe_gfclk into mcasp_ck */
+static struct clk mcasp_ck = {
+	.name		= "mcasp_ck",
+	.parent		= &mcasp_sync_mux_ck,
+	.clksel		= func_mcasp_abe_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+static struct clk mcbsp1_sync_mux_ck = {
+	.name		= "mcbsp1_sync_mux_ck",
+	.parent		= &abe_24m_fclk,
+	.clksel		= dmic_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_mcbsp1_gfclk_sel[] = {
+	{ .parent = &mcbsp1_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+/* Merged func_mcbsp1_gfclk into mcbsp1_ck */
+static struct clk mcbsp1_ck = {
+	.name		= "mcbsp1_ck",
+	.parent		= &mcbsp1_sync_mux_ck,
+	.clksel		= func_mcbsp1_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+static struct clk mcbsp2_sync_mux_ck = {
+	.name		= "mcbsp2_sync_mux_ck",
+	.parent		= &abe_24m_fclk,
+	.clksel		= dmic_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_mcbsp2_gfclk_sel[] = {
+	{ .parent = &mcbsp2_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+/* Merged func_mcbsp2_gfclk into mcbsp2_ck */
+static struct clk mcbsp2_ck = {
+	.name		= "mcbsp2_ck",
+	.parent		= &mcbsp2_sync_mux_ck,
+	.clksel		= func_mcbsp2_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+static struct clk mcbsp3_sync_mux_ck = {
+	.name		= "mcbsp3_sync_mux_ck",
+	.parent		= &abe_24m_fclk,
+	.clksel		= dmic_sync_mux_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel func_mcbsp3_gfclk_sel[] = {
+	{ .parent = &mcbsp3_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+/* Merged func_mcbsp3_gfclk into mcbsp3_ck */
+static struct clk mcbsp3_ck = {
+	.name		= "mcbsp3_ck",
+	.parent		= &mcbsp3_sync_mux_ck,
+	.clksel		= func_mcbsp3_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+};
+
+static struct clk mcbsp4_sync_mux_ck = {
+	.name		= "mcbsp4_sync_mux_ck",
+	.parent		= &func_96m_fclk,
+	.clksel		= mcasp2_fclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel per_mcbsp4_gfclk_sel[] = {
+	{ .parent = &mcbsp4_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+/* Merged per_mcbsp4_gfclk into mcbsp4_ck */
+static struct clk mcbsp4_ck = {
+	.name		= "mcbsp4_ck",
+	.parent		= &mcbsp4_sync_mux_ck,
+	.clksel		= per_mcbsp4_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_24_24_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+};
+
+static struct clk mcspi1_ck = {
+	.name		= "mcspi1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi2_ck = {
+	.name		= "mcspi2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi3_ck = {
+	.name		= "mcspi3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mcspi4_ck = {
+	.name		= "mcspi4_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+/* Merged hsmmc1_fclk into mmc1_ck */
+static struct clk mmc1_ck = {
+	.name		= "mmc1_ck",
+	.parent		= &func_64m_fclk,
+	.clksel		= hsmmc6_fclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+};
+
+/* Merged hsmmc2_fclk into mmc2_ck */
+static struct clk mmc2_ck = {
+	.name		= "mmc2_ck",
+	.parent		= &func_64m_fclk,
+	.clksel		= hsmmc6_fclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_MASK,
+	.ops		= &clkops_omap2_dflt,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+	.enable_reg	= OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+};
+
+static struct clk mmc3_ck = {
+	.name		= "mmc3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc4_ck = {
+	.name		= "mmc4_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk mmc5_ck = {
+	.name		= "mmc5_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk ocp_wp1_ck = {
+	.name		= "ocp_wp1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_instr_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pdm_ck = {
+	.name		= "pdm_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM1_ABE_PDM_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+	.parent		= &pad_clks_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk pkaeip29_ck = {
+	.name		= "pkaeip29_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rng_ck = {
+	.name		= "rng_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_RNG_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sha2md51_ck = {
+	.name		= "sha2md51_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_secure_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sl2_ck = {
+	.name		= "sl2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_IVAHD_SL2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "ivahd_clkdm",
+	.parent		= &dpll_iva_m5_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk slimbus1_ck = {
+	.name		= "slimbus1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+	.parent		= &ocp_abe_iclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk slimbus2_ck = {
+	.name		= "slimbus2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sr_core_ck = {
+	.name		= "sr_core_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_ao_clkdm",
+	.parent		= &l4_wkup_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sr_iva_ck = {
+	.name		= "sr_iva_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_ao_clkdm",
+	.parent		= &l4_wkup_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk sr_mpu_ck = {
+	.name		= "sr_mpu_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_ao_clkdm",
+	.parent		= &l4_wkup_clk_mux_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk tesla_ck = {
+	.name		= "tesla_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "tesla_clkdm",
+	.parent		= &dpll_iva_m4_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart1_ck = {
+	.name		= "uart1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_UART1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart2_ck = {
+	.name		= "uart2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_UART2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart3_ck = {
+	.name		= "uart3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_UART3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk uart4_ck = {
+	.name		= "uart4_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L4PER_UART4_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_per_clkdm",
+	.parent		= &func_48m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk unipro1_ck = {
+	.name		= "unipro1_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &func_96m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_host_ck = {
+	.name		= "usb_host_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &init_60m_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_host_fs_ck = {
+	.name		= "usb_host_fs_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &func_48mc_fclk,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_otg_ck = {
+	.name		= "usb_otg_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &l3_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usb_tll_ck = {
+	.name		= "usb_tll_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usbphyocp2scp_ck = {
+	.name		= "usbphyocp2scp_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
+	.clkdm_name	= "l3_init_clkdm",
+	.parent		= &l4_div_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk usim_ck = {
+	.name		= "usim_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_wkup_clkdm",
+	.parent		= &sys_32k_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt2_ck = {
+	.name		= "wdt2_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "l4_wkup_clkdm",
+	.parent		= &sys_32k_ck,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk wdt3_ck = {
+	.name		= "wdt3_ck",
+	.ops		= &clkops_omap2_dflt,
+	.enable_reg	= OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
+	.clkdm_name	= "abe_clkdm",
+	.parent		= &sys_32k_ck,
+	.recalc		= &followparent_recalc,
+};
+
+/* Remaining optional clocks */
+static const struct clksel otg_60m_gfclk_sel[] = {
+	{ .parent = &utmi_phy_clkout_ck, .rates = div_1_0_rates },
+	{ .parent = &xclk60motg_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk otg_60m_gfclk_ck = {
+	.name		= "otg_60m_gfclk_ck",
+	.parent		= &utmi_phy_clkout_ck,
+	.clksel		= otg_60m_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_60M_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel stm_clk_div_div[] = {
+	{ .parent = &pmd_stm_clock_mux_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk stm_clk_div_ck = {
+	.name		= "stm_clk_div_ck",
+	.parent		= &pmd_stm_clock_mux_ck,
+	.clksel		= stm_clk_div_div,
+	.clksel_reg	= OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_PMD_STM_CLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel trace_clk_div_div[] = {
+	{ .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk trace_clk_div_ck = {
+	.name		= "trace_clk_div_ck",
+	.parent		= &pmd_trace_clk_mux_ck,
+	.clksel		= trace_clk_div_div,
+	.clksel_reg	= OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel_rate div2_14to18_rates[] = {
+	{ .div = 14, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 18, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
+static const struct clksel usim_fclk_div[] = {
+	{ .parent = &dpll_per_m4_ck, .rates = div2_14to18_rates },
+	{ .parent = NULL },
+};
+
+static struct clk usim_fclk = {
+	.name		= "usim_fclk",
+	.parent		= &dpll_per_m4_ck,
+	.clksel		= usim_fclk_div,
+	.clksel_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_DIV_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap2_clksel_set_rate,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel utmi_p1_gfclk_sel[] = {
+	{ .parent = &init_60m_fclk, .rates = div_1_0_rates },
+	{ .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk utmi_p1_gfclk_ck = {
+	.name		= "utmi_p1_gfclk_ck",
+	.parent		= &init_60m_fclk,
+	.clksel		= utmi_p1_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P1_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+static const struct clksel utmi_p2_gfclk_sel[] = {
+	{ .parent = &init_60m_fclk, .rates = div_1_0_rates },
+	{ .parent = &xclk60mhsp2_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk utmi_p2_gfclk_ck = {
+	.name		= "utmi_p2_gfclk_ck",
+	.parent		= &init_60m_fclk,
+	.clksel		= utmi_p2_gfclk_sel,
+	.init		= &omap2_init_clksel_parent,
+	.clksel_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P2_MASK,
+	.ops		= &clkops_null,
+	.recalc		= &omap2_clksel_recalc,
+	.flags		= CLOCK_IN_OMAP4430,
+};
+
+/*
+ * clkdev
+ */
+
+static struct omap_clk omap44xx_clks[] = {
+	CLK(NULL,	"extalt_clkin_ck",		&extalt_clkin_ck,	CK_443X),
+	CLK(NULL,	"pad_clks_ck",			&pad_clks_ck,	CK_443X),
+	CLK(NULL,	"pad_slimbus_core_clks_ck",	&pad_slimbus_core_clks_ck,	CK_443X),
+	CLK(NULL,	"secure_32k_clk_src_ck",	&secure_32k_clk_src_ck,	CK_443X),
+	CLK(NULL,	"slimbus_clk",			&slimbus_clk,	CK_443X),
+	CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_443X),
+	CLK(NULL,	"virt_12000000_ck",		&virt_12000000_ck,	CK_443X),
+	CLK(NULL,	"virt_13000000_ck",		&virt_13000000_ck,	CK_443X),
+	CLK(NULL,	"virt_16800000_ck",		&virt_16800000_ck,	CK_443X),
+	CLK(NULL,	"virt_19200000_ck",		&virt_19200000_ck,	CK_443X),
+	CLK(NULL,	"virt_26000000_ck",		&virt_26000000_ck,	CK_443X),
+	CLK(NULL,	"virt_27000000_ck",		&virt_27000000_ck,	CK_443X),
+	CLK(NULL,	"virt_38400000_ck",		&virt_38400000_ck,	CK_443X),
+	CLK(NULL,	"sys_clkin_ck",			&sys_clkin_ck,	CK_443X),
+	CLK(NULL,	"utmi_phy_clkout_ck",		&utmi_phy_clkout_ck,	CK_443X),
+	CLK(NULL,	"xclk60mhsp1_ck",		&xclk60mhsp1_ck,	CK_443X),
+	CLK(NULL,	"xclk60mhsp2_ck",		&xclk60mhsp2_ck,	CK_443X),
+	CLK(NULL,	"xclk60motg_ck",		&xclk60motg_ck,	CK_443X),
+	CLK(NULL,	"dpll_sys_ref_clk",		&dpll_sys_ref_clk,	CK_443X),
+	CLK(NULL,	"abe_dpll_refclk_mux_ck",	&abe_dpll_refclk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_ck",			&dpll_abe_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_m2x2_ck",		&dpll_abe_m2x2_ck,	CK_443X),
+	CLK(NULL,	"abe_24m_fclk",			&abe_24m_fclk,	CK_443X),
+	CLK(NULL,	"abe_clk",			&abe_clk,	CK_443X),
+	CLK(NULL,	"aess_fclk",			&aess_fclk,	CK_443X),
+	CLK(NULL,	"dpll_abe_m3_ck",		&dpll_abe_m3_ck,	CK_443X),
+	CLK(NULL,	"core_hsd_byp_clk_mux_ck",	&core_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_ck",			&dpll_core_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m6_ck",		&dpll_core_m6_ck,	CK_443X),
+	CLK(NULL,	"dbgclk_mux_ck",		&dbgclk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m2_ck",		&dpll_core_m2_ck,	CK_443X),
+	CLK(NULL,	"ddrphy_ck",			&ddrphy_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m5_ck",		&dpll_core_m5_ck,	CK_443X),
+	CLK(NULL,	"div_core_ck",			&div_core_ck,	CK_443X),
+	CLK(NULL,	"div_iva_hs_clk",		&div_iva_hs_clk,	CK_443X),
+	CLK(NULL,	"div_mpu_hs_clk",		&div_mpu_hs_clk,	CK_443X),
+	CLK(NULL,	"dpll_core_m4_ck",		&dpll_core_m4_ck,	CK_443X),
+	CLK(NULL,	"dll_clk_div_ck",		&dll_clk_div_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_m2_ck",		&dpll_abe_m2_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m3_ck",		&dpll_core_m3_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m7_ck",		&dpll_core_m7_ck,	CK_443X),
+	CLK(NULL,	"iva_hsd_byp_clk_mux_ck",	&iva_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_ck",			&dpll_iva_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_m4_ck",		&dpll_iva_m4_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_m5_ck",		&dpll_iva_m5_ck,	CK_443X),
+	CLK(NULL,	"dpll_mpu_ck",			&dpll_mpu_ck,	CK_443X),
+	CLK(NULL,	"dpll_mpu_m2_ck",		&dpll_mpu_m2_ck,	CK_443X),
+	CLK(NULL,	"per_hs_clk_div_ck",		&per_hs_clk_div_ck,	CK_443X),
+	CLK(NULL,	"per_hsd_byp_clk_mux_ck",	&per_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_ck",			&dpll_per_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m2_ck",		&dpll_per_m2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m2x2_ck",		&dpll_per_m2x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m3_ck",		&dpll_per_m3_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m4_ck",		&dpll_per_m4_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m5_ck",		&dpll_per_m5_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m6_ck",		&dpll_per_m6_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m7_ck",		&dpll_per_m7_ck,	CK_443X),
+	CLK(NULL,	"dpll_unipro_ck",		&dpll_unipro_ck,	CK_443X),
+	CLK(NULL,	"dpll_unipro_m2x2_ck",		&dpll_unipro_m2x2_ck,	CK_443X),
+	CLK(NULL,	"usb_hs_clk_div_ck",		&usb_hs_clk_div_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_ck",			&dpll_usb_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_clkdcoldo_ck",	&dpll_usb_clkdcoldo_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_m2_ck",		&dpll_usb_m2_ck,	CK_443X),
+	CLK(NULL,	"ducati_clk_mux_ck",		&ducati_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"func_12m_fclk",		&func_12m_fclk,	CK_443X),
+	CLK(NULL,	"func_24m_clk",			&func_24m_clk,	CK_443X),
+	CLK(NULL,	"func_24mc_fclk",		&func_24mc_fclk,	CK_443X),
+	CLK(NULL,	"func_48m_fclk",		&func_48m_fclk,	CK_443X),
+	CLK(NULL,	"func_48mc_fclk",		&func_48mc_fclk,	CK_443X),
+	CLK(NULL,	"func_64m_fclk",		&func_64m_fclk,	CK_443X),
+	CLK(NULL,	"func_96m_fclk",		&func_96m_fclk,	CK_443X),
+	CLK(NULL,	"hsmmc6_fclk",			&hsmmc6_fclk,	CK_443X),
+	CLK(NULL,	"init_60m_fclk",		&init_60m_fclk,	CK_443X),
+	CLK(NULL,	"l3_div_ck",			&l3_div_ck,	CK_443X),
+	CLK(NULL,	"l4_div_ck",			&l4_div_ck,	CK_443X),
+	CLK(NULL,	"lp_clk_div_ck",		&lp_clk_div_ck,	CK_443X),
+	CLK(NULL,	"l4_wkup_clk_mux_ck",		&l4_wkup_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"per_abe_nc_fclk",		&per_abe_nc_fclk,	CK_443X),
+	CLK(NULL,	"mcasp2_fclk",			&mcasp2_fclk,	CK_443X),
+	CLK(NULL,	"mcasp3_fclk",			&mcasp3_fclk,	CK_443X),
+	CLK(NULL,	"ocp_abe_iclk",			&ocp_abe_iclk,	CK_443X),
+	CLK(NULL,	"per_abe_24m_fclk",		&per_abe_24m_fclk,	CK_443X),
+	CLK(NULL,	"pmd_stm_clock_mux_ck",		&pmd_stm_clock_mux_ck,	CK_443X),
+	CLK(NULL,	"pmd_trace_clk_mux_ck",		&pmd_trace_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"syc_clk_div_ck",		&syc_clk_div_ck,	CK_443X),
+	CLK(NULL,	"aes1_ck",			&aes1_ck,	CK_443X),
+	CLK(NULL,	"aes2_ck",			&aes2_ck,	CK_443X),
+	CLK(NULL,	"aess_ck",			&aess_ck,	CK_443X),
+	CLK(NULL,	"cust_efuse_ck",		&cust_efuse_ck,	CK_443X),
+	CLK(NULL,	"des3des_ck",			&des3des_ck,	CK_443X),
+	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"dmic_ck",			&dmic_ck,	CK_443X),
+	CLK(NULL,	"dss_ck",			&dss_ck,	CK_443X),
+	CLK(NULL,	"ducati_ck",			&ducati_ck,	CK_443X),
+	CLK(NULL,	"emif1_ck",			&emif1_ck,	CK_443X),
+	CLK(NULL,	"emif2_ck",			&emif2_ck,	CK_443X),
+	CLK(NULL,	"fdif_ck",			&fdif_ck,	CK_443X),
+	CLK(NULL,	"per_sgx_fclk",			&per_sgx_fclk,	CK_443X),
+	CLK(NULL,	"gfx_ck",			&gfx_ck,	CK_443X),
+	CLK(NULL,	"gpio1_ck",			&gpio1_ck,	CK_443X),
+	CLK(NULL,	"gpio2_ck",			&gpio2_ck,	CK_443X),
+	CLK(NULL,	"gpio3_ck",			&gpio3_ck,	CK_443X),
+	CLK(NULL,	"gpio4_ck",			&gpio4_ck,	CK_443X),
+	CLK(NULL,	"gpio5_ck",			&gpio5_ck,	CK_443X),
+	CLK(NULL,	"gpio6_ck",			&gpio6_ck,	CK_443X),
+	CLK(NULL,	"gpmc_ck",			&gpmc_ck,	CK_443X),
+	CLK(NULL,	"gptimer1_ck",			&gptimer1_ck,	CK_443X),
+	CLK(NULL,	"gptimer10_ck",			&gptimer10_ck,	CK_443X),
+	CLK(NULL,	"gptimer11_ck",			&gptimer11_ck,	CK_443X),
+	CLK(NULL,	"gptimer2_ck",			&gptimer2_ck,	CK_443X),
+	CLK(NULL,	"gptimer3_ck",			&gptimer3_ck,	CK_443X),
+	CLK(NULL,	"gptimer4_ck",			&gptimer4_ck,	CK_443X),
+	CLK(NULL,	"gptimer5_ck",			&gptimer5_ck,	CK_443X),
+	CLK(NULL,	"gptimer6_ck",			&gptimer6_ck,	CK_443X),
+	CLK(NULL,	"gptimer7_ck",			&gptimer7_ck,	CK_443X),
+	CLK(NULL,	"gptimer8_ck",			&gptimer8_ck,	CK_443X),
+	CLK(NULL,	"gptimer9_ck",			&gptimer9_ck,	CK_443X),
+	CLK("omap2_hdq.0",	"ick",				&hdq1w_ck,	CK_443X),
+	CLK(NULL,	"hsi_ck",			&hsi_ck,	CK_443X),
+	CLK("i2c_omap.1",	"ick",				&i2c1_ck,	CK_443X),
+	CLK("i2c_omap.2",	"ick",				&i2c2_ck,	CK_443X),
+	CLK("i2c_omap.3",	"ick",				&i2c3_ck,	CK_443X),
+	CLK("i2c_omap.4",	"ick",				&i2c4_ck,	CK_443X),
+	CLK(NULL,	"iss_ck",			&iss_ck,	CK_443X),
+	CLK(NULL,	"ivahd_ck",			&ivahd_ck,	CK_443X),
+	CLK(NULL,	"keyboard_ck",			&keyboard_ck,	CK_443X),
+	CLK(NULL,	"l3_instr_interconnect_ck",	&l3_instr_interconnect_ck,	CK_443X),
+	CLK(NULL,	"l3_interconnect_3_ck",		&l3_interconnect_3_ck,	CK_443X),
+	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcasp_ck",			&mcasp_ck,	CK_443X),
+	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_443X),
+	CLK("omap-mcbsp.1",	"fck",				&mcbsp1_ck,	CK_443X),
+	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_443X),
+	CLK("omap-mcbsp.2",	"fck",				&mcbsp2_ck,	CK_443X),
+	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_443X),
+	CLK("omap-mcbsp.3",	"fck",				&mcbsp3_ck,	CK_443X),
+	CLK(NULL,	"mcbsp4_sync_mux_ck",		&mcbsp4_sync_mux_ck,	CK_443X),
+	CLK("omap-mcbsp.4",	"fck",				&mcbsp4_ck,	CK_443X),
+	CLK("omap2_mcspi.1",	"fck",				&mcspi1_ck,	CK_443X),
+	CLK("omap2_mcspi.2",	"fck",				&mcspi2_ck,	CK_443X),
+	CLK("omap2_mcspi.3",	"fck",				&mcspi3_ck,	CK_443X),
+	CLK("omap2_mcspi.4",	"fck",				&mcspi4_ck,	CK_443X),
+	CLK("mmci-omap-hs.0",	"fck",				&mmc1_ck,	CK_443X),
+	CLK("mmci-omap-hs.1",	"fck",				&mmc2_ck,	CK_443X),
+	CLK("mmci-omap-hs.2",	"fck",				&mmc3_ck,	CK_443X),
+	CLK("mmci-omap-hs.3",	"fck",				&mmc4_ck,	CK_443X),
+	CLK("mmci-omap-hs.4",	"fck",				&mmc5_ck,	CK_443X),
+	CLK(NULL,	"ocp_wp1_ck",			&ocp_wp1_ck,	CK_443X),
+	CLK(NULL,	"pdm_ck",			&pdm_ck,	CK_443X),
+	CLK(NULL,	"pkaeip29_ck",			&pkaeip29_ck,	CK_443X),
+	CLK("omap_rng",	"ick",				&rng_ck,	CK_443X),
+	CLK(NULL,	"sha2md51_ck",			&sha2md51_ck,	CK_443X),
+	CLK(NULL,	"sl2_ck",			&sl2_ck,	CK_443X),
+	CLK(NULL,	"slimbus1_ck",			&slimbus1_ck,	CK_443X),
+	CLK(NULL,	"slimbus2_ck",			&slimbus2_ck,	CK_443X),
+	CLK(NULL,	"sr_core_ck",			&sr_core_ck,	CK_443X),
+	CLK(NULL,	"sr_iva_ck",			&sr_iva_ck,	CK_443X),
+	CLK(NULL,	"sr_mpu_ck",			&sr_mpu_ck,	CK_443X),
+	CLK(NULL,	"tesla_ck",			&tesla_ck,	CK_443X),
+	CLK(NULL,	"uart1_ck",			&uart1_ck,	CK_443X),
+	CLK(NULL,	"uart2_ck",			&uart2_ck,	CK_443X),
+	CLK(NULL,	"uart3_ck",			&uart3_ck,	CK_443X),
+	CLK(NULL,	"uart4_ck",			&uart4_ck,	CK_443X),
+	CLK(NULL,	"unipro1_ck",			&unipro1_ck,	CK_443X),
+	CLK(NULL,	"usb_host_ck",			&usb_host_ck,	CK_443X),
+	CLK(NULL,	"usb_host_fs_ck",		&usb_host_fs_ck,	CK_443X),
+	CLK("musb_hdrc",	"ick",				&usb_otg_ck,	CK_443X),
+	CLK(NULL,	"usb_tll_ck",			&usb_tll_ck,	CK_443X),
+	CLK(NULL,	"usbphyocp2scp_ck",		&usbphyocp2scp_ck,	CK_443X),
+	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
+	CLK("omap_wdt",	"fck",				&wdt2_ck,	CK_443X),
+	CLK(NULL,	"wdt3_ck",			&wdt3_ck,	CK_443X),
+	CLK(NULL,	"otg_60m_gfclk_ck",		&otg_60m_gfclk_ck,	CK_443X),
+	CLK(NULL,	"stm_clk_div_ck",		&stm_clk_div_ck,	CK_443X),
+	CLK(NULL,	"trace_clk_div_ck",		&trace_clk_div_ck,	CK_443X),
+	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
+	CLK(NULL,	"utmi_p1_gfclk_ck",		&utmi_p1_gfclk_ck,	CK_443X),
+	CLK(NULL,	"utmi_p2_gfclk_ck",		&utmi_p2_gfclk_ck,	CK_443X),
+};
+
+int __init omap2_clk_init(void)
+{
+	/* struct prcm_config *prcm; */
+	struct omap_clk *c;
+	/* u32 clkrate; */
+	u32 cpu_clkflg;
+
+	if (cpu_is_omap44xx()) {
+		cpu_mask = RATE_IN_4430;
+		cpu_clkflg = CK_443X;
+	}
+
+	clk_init(&omap2_clk_functions);
+
+	for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
+									  c++)
+		clk_preinit(c->lk.clk);
+
+	for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
+									  c++)
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			clk_register(c->lk.clk);
+			/* TODO
+			omap2_init_clk_clkdm(c->lk.clk);
+			*/
+		}
+
+	recalculate_root_clocks();
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_enable_init_clocks();
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,15 @@
+/*
+ * OMAP4 clock function prototypes and macros
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
+
+#define OMAP4430_MAX_DPLL_MULT	2048
+#define OMAP4430_MAX_DPLL_DIV	128
+
+extern const struct clkops clkops_noncore_dpll_ops;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,13 +24,13 @@
 #include <linux/io.h>
 #include <linux/bitops.h>
 
-#include <mach/clock.h>
-#include <mach/clockdomain.h>
-#include <mach/cpu.h>
-#include <mach/prcm.h>
+#include <plat/clock.h>
+#include <plat/clockdomain.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
 #include <asm/div64.h>
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 #include "sdrc.h"
 #include "clock.h"
 #include "prm.h"
@@ -70,9 +70,41 @@
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
- * OMAP2/3 specific clock functions
+ * OMAP2/3/4 specific clock functions
  *-------------------------------------------------------------------------*/
 
+void omap2_init_dpll_parent(struct clk *clk)
+{
+	u32 v;
+	struct dpll_data *dd;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return;
+
+	/* Return bypass rate if DPLL is bypassed */
+	v = __raw_readl(dd->control_reg);
+	v &= dd->enable_mask;
+	v >>= __ffs(dd->enable_mask);
+
+	/* Reparent in case the dpll is in bypass */
+	if (cpu_is_omap24xx()) {
+		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	} else if (cpu_is_omap34xx()) {
+		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	} else if (cpu_is_omap44xx()) {
+		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
+			clk_reparent(clk, dd->clk_bypass);
+	}
+	return;
+}
+
 /**
  * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
  * @clk: struct clk *
@@ -149,6 +181,7 @@ static int _dpll_test_fint(struct clk *c
  * clockdomain pointer, and save it into the struct clk.  Intended to be
  * called during clk_register().  No return value.
  */
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 void omap2_init_clk_clkdm(struct clk *clk)
 {
 	struct clockdomain *clkdm;
@@ -166,6 +199,7 @@ void omap2_init_clk_clkdm(struct clk *cl
 			 "clkdm %s\n", clk->name, clk->clkdm_name);
 	}
 }
+#endif
 
 /**
  * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
@@ -247,6 +281,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
 		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
 			return dd->clk_bypass->rate;
+	} else if (cpu_is_omap44xx()) {
+		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
+			return dd->clk_bypass->rate;
 	}
 
 	v = __raw_readl(dd->mult_div1_reg);
@@ -437,8 +476,10 @@ void omap2_clk_disable(struct clk *clk)
 		_omap2_clk_disable(clk);
 		if (clk->parent)
 			omap2_clk_disable(clk->parent);
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 		if (clk->clkdm)
 			omap2_clkdm_clk_disable(clk->clkdm, clk);
+#endif
 
 	}
 }
@@ -448,8 +489,10 @@ int omap2_clk_enable(struct clk *clk)
 	int ret = 0;
 
 	if (clk->usecount++ == 0) {
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 		if (clk->clkdm)
 			omap2_clkdm_clk_enable(clk->clkdm, clk);
+#endif
 
 		if (clk->parent) {
 			ret = omap2_clk_enable(clk->parent);
@@ -468,8 +511,10 @@ int omap2_clk_enable(struct clk *clk)
 	return ret;
 
 err:
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 	if (clk->clkdm)
 		omap2_clkdm_clk_disable(clk->clkdm, clk);
+#endif
 	clk->usecount--;
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock_common_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock_common_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock_common_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock_common_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock_common_data.c
+ *
+ *  Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2009 Nokia Corporation
+ *
+ *  Contacts:
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Paul Walmsley
+ *
+ * This 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 file contains clock data that is common to both the OMAP2xxx and
+ * OMAP3xxx clock definition files.
+ */
+
+#include "clock.h"
+
+/* clksel_rate data common to 24xx/343x */
+const struct clksel_rate gpt_32k_rates[] = {
+	 { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
+	 { .div = 0 }
+};
+
+const struct clksel_rate gpt_sys_rates[] = {
+	 { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
+	 { .div = 0 }
+};
+
+const struct clksel_rate gfx_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
+	{ .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_343X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_343X },
+	{ .div = 0 }
+};
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clockdomain.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomain.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clockdomain.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomain.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  * OMAP2/3 clockdomain framework functions
  *
  * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2008-2009 Nokia Corporation
  *
  * Written by Paul Walmsley and Jouni Högander
  *
@@ -10,9 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifdef CONFIG_OMAP_DEBUG_CLOCKDOMAIN
-#  define DEBUG
-#endif
+#undef DEBUG
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -28,14 +26,14 @@
 
 #include <linux/bitops.h>
 
-#include <mach/clock.h>
+#include <plat/clock.h>
 
 #include "prm.h"
 #include "prm-regbits-24xx.h"
 #include "cm.h"
 
-#include <mach/powerdomain.h>
-#include <mach/clockdomain.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
 
 /* clkdm_list contains all registered struct clockdomains */
 static LIST_HEAD(clkdm_list);
@@ -561,7 +559,7 @@ int omap2_clkdm_clk_enable(struct clockd
 	 * downstream clocks for debugging purposes?
 	 */
 
-	if (!clkdm || !clk)
+	if (!clkdm || !clk || !clkdm->clktrctrl_mask)
 		return -EINVAL;
 
 	if (atomic_inc_return(&clkdm->usecount) > 1)
@@ -612,7 +610,7 @@ int omap2_clkdm_clk_disable(struct clock
 	 * downstream clocks for debugging purposes?
 	 */
 
-	if (!clkdm || !clk)
+	if (!clkdm || !clk || !clkdm->clktrctrl_mask)
 		return -EINVAL;
 
 #ifdef DEBUG
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clockdomains.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clockdomains.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clockdomains.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
 
-#include <mach/clockdomain.h>
+#include <plat/clockdomain.h>
 
 /*
  * OMAP2/3-common clockdomains
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,8 @@
 /*
  *  linux/arch/arm/mach-omap2/clock.h
  *
- *  Copyright (C) 2005-2008 Texas Instruments, Inc.
- *  Copyright (C) 2004-2008 Nokia Corporation
+ *  Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *  Copyright (C) 2004-2009 Nokia Corporation
  *
  *  Contacts:
  *  Richard Woodruff <r-woodruff2@ti.com>
@@ -16,7 +16,7 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCK_H
 
-#include <mach/clock.h>
+#include <plat/clock.h>
 
 /* The maximum error between a target DPLL rate and the rounded rate in Hz */
 #define DEFAULT_DPLL_RATE_TOLERANCE	50000
@@ -36,6 +36,17 @@
 #define OMAP3XXX_EN_DPLL_FRBYPASS		0x6
 #define OMAP3XXX_EN_DPLL_LOCKED			0x7
 
+/* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP4XXX_EN_DPLL_MNBYPASS		0x4
+#define OMAP4XXX_EN_DPLL_LPBYPASS		0x5
+#define OMAP4XXX_EN_DPLL_FRBYPASS		0x6
+#define OMAP4XXX_EN_DPLL_LOCKED			0x7
+
+/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
+#define DPLL_LOW_POWER_STOP	0x1
+#define DPLL_LOW_POWER_BYPASS	0x5
+#define DPLL_LOCKED		0x7
+
 int omap2_clk_init(void);
 int omap2_clk_enable(struct clk *clk);
 void omap2_clk_disable(struct clk *clk);
@@ -44,6 +55,14 @@ int omap2_clk_set_rate(struct clk *clk,
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
 int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
+unsigned long omap3_dpll_recalc(struct clk *clk);
+unsigned long omap3_clkoutx2_recalc(struct clk *clk);
+void omap3_dpll_allow_idle(struct clk *clk);
+void omap3_dpll_deny_idle(struct clk *clk);
+u32 omap3_dpll_autoidle_read(struct clk *clk);
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
+int omap3_noncore_dpll_enable(struct clk *clk);
+void omap3_noncore_dpll_disable(struct clk *clk);
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 void omap2_clk_disable_unused(struct clk *clk);
@@ -63,6 +82,7 @@ unsigned long omap2_fixed_divisor_recalc
 long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
 u32 omap2_get_dpll_rate(struct clk *clk);
+void omap2_init_dpll_parent(struct clk *clk);
 int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
 void omap2_clk_prepare_for_reboot(void);
 int omap2_dflt_clk_enable(struct clk *clk);
@@ -72,29 +92,17 @@ void omap2_clk_dflt_find_companion(struc
 void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
 				u8 *idlest_bit);
 
-extern const struct clkops clkops_omap2_dflt_wait;
-extern const struct clkops clkops_omap2_dflt;
-
 extern u8 cpu_mask;
 
-/* clksel_rate data common to 24xx/343x */
-static const struct clksel_rate gpt_32k_rates[] = {
-	 { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
-	 { .div = 0 }
-};
+extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_omap2_dflt;
 
-static const struct clksel_rate gpt_sys_rates[] = {
-	 { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
-	 { .div = 0 }
-};
+extern struct clk_functions omap2_clk_functions;
+extern struct clk *vclk, *sclk;
 
-static const struct clksel_rate gfx_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_343X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_343X },
-	{ .div = 0 }
-};
+extern const struct clksel_rate gpt_32k_rates[];
+extern const struct clksel_rate gpt_sys_rates[];
+extern const struct clksel_rate gfx_l3_rates[];
 
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm44xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,358 @@
+/*
+ * OMAP44xx CM1 & CM2 instance offset macros
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 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_CM44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM44XX_H
+
+
+/* CM1 */
+
+
+/* CM1.OCP_SOCKET_CM1 register offsets */
+#define OMAP4430_REVISION_CM1				OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0000)
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_MOD, 0x0040)
+
+/* CM1.CKGEN_CM1 register offsets */
+#define OMAP4430_CM_CLKSEL_CORE				OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0000)
+#define OMAP4430_CM_CLKSEL_ABE				OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0008)
+#define OMAP4430_CM_DLL_CTRL				OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0010)
+#define OMAP4430_CM_CLKMODE_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0020)
+#define OMAP4430_CM_IDLEST_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0024)
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0028)
+#define OMAP4430_CM_CLKSEL_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x002c)
+#define OMAP4430_CM_DIV_M2_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0030)
+#define OMAP4430_CM_DIV_M3_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0034)
+#define OMAP4430_CM_DIV_M4_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0038)
+#define OMAP4430_CM_DIV_M5_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x003c)
+#define OMAP4430_CM_DIV_M6_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0040)
+#define OMAP4430_CM_DIV_M7_DPLL_CORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0044)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0048)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x004c)
+#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0050)
+#define OMAP4430_CM_CLKMODE_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0060)
+#define OMAP4430_CM_IDLEST_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0064)
+#define OMAP4430_CM_AUTOIDLE_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0068)
+#define OMAP4430_CM_CLKSEL_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x006c)
+#define OMAP4430_CM_DIV_M2_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0070)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0088)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x008c)
+#define OMAP4430_CM_BYPCLK_DPLL_MPU			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x009c)
+#define OMAP4430_CM_CLKMODE_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a0)
+#define OMAP4430_CM_IDLEST_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a4)
+#define OMAP4430_CM_AUTOIDLE_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00a8)
+#define OMAP4430_CM_CLKSEL_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ac)
+#define OMAP4430_CM_DIV_M4_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00b8)
+#define OMAP4430_CM_DIV_M5_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00bc)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00c8)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00cc)
+#define OMAP4430_CM_BYPCLK_DPLL_IVA			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00dc)
+#define OMAP4430_CM_CLKMODE_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e0)
+#define OMAP4430_CM_IDLEST_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e4)
+#define OMAP4430_CM_AUTOIDLE_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00e8)
+#define OMAP4430_CM_CLKSEL_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00ec)
+#define OMAP4430_CM_DIV_M2_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f0)
+#define OMAP4430_CM_DIV_M3_DPLL_ABE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x00f4)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0108)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x010c)
+#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0120)
+#define OMAP4430_CM_IDLEST_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0124)
+#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0128)
+#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x012c)
+#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0130)
+#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0138)
+#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x013c)
+#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0140)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0148)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x014c)
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0160)
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0164)
+#define OMAP4430_CM_DYN_DEP_PRESCAL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0170)
+#define OMAP4430_CM_RESTORE_ST				OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_MOD, 0x0180)
+
+/* CM1.MPU_CM1 register offsets */
+#define OMAP4430_CM_MPU_CLKSTCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0000)
+#define OMAP4430_CM_MPU_STATICDEP			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0004)
+#define OMAP4430_CM_MPU_DYNAMICDEP			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0008)
+#define OMAP4430_CM_MPU_MPU_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_MOD, 0x0020)
+
+/* CM1.TESLA_CM1 register offsets */
+#define OMAP4430_CM_TESLA_CLKSTCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0000)
+#define OMAP4430_CM_TESLA_STATICDEP			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0004)
+#define OMAP4430_CM_TESLA_DYNAMICDEP			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0008)
+#define OMAP4430_CM_TESLA_TESLA_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_MOD, 0x0020)
+
+/* CM1.ABE_CM1 register offsets */
+#define OMAP4430_CM1_ABE_CLKSTCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0000)
+#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0020)
+#define OMAP4430_CM1_ABE_AESS_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0028)
+#define OMAP4430_CM1_ABE_PDM_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0030)
+#define OMAP4430_CM1_ABE_DMIC_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0038)
+#define OMAP4430_CM1_ABE_MCASP_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0040)
+#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0048)
+#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0050)
+#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0058)
+#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0060)
+#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0068)
+#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0070)
+#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0078)
+#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0080)
+#define OMAP4430_CM1_ABE_WDT3_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_MOD, 0x0088)
+
+/* CM1.RESTORE_CM1 register offsets */
+#define OMAP4430_CM_CLKSEL_CORE_RESTORE			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0000)
+#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0004)
+#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0008)
+#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x000c)
+#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0010)
+#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0014)
+#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0018)
+#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x001c)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE	OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0020)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE	OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0024)
+#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0028)
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x002c)
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0030)
+#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE		OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_MOD, 0x0034)
+
+/* CM2 */
+
+
+/* CM2.OCP_SOCKET_CM2 register offsets */
+#define OMAP4430_REVISION_CM2				OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0000)
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_MOD, 0x0040)
+
+/* CM2.CKGEN_CM2 register offsets */
+#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0000)
+#define OMAP4430_CM_CLKSEL_USB_60MHZ			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0004)
+#define OMAP4430_CM_SCALE_FCLK				OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0008)
+#define OMAP4430_CM_CORE_DVFS_PERF1			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0010)
+#define OMAP4430_CM_CORE_DVFS_PERF2			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0014)
+#define OMAP4430_CM_CORE_DVFS_PERF3			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0018)
+#define OMAP4430_CM_CORE_DVFS_PERF4			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x001c)
+#define OMAP4430_CM_CORE_DVFS_CURRENT			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0024)
+#define OMAP4430_CM_IVA_DVFS_PERF_TESLA			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0028)
+#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x002c)
+#define OMAP4430_CM_IVA_DVFS_PERF_ABE			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0030)
+#define OMAP4430_CM_IVA_DVFS_CURRENT			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0038)
+#define OMAP4430_CM_CLKMODE_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0040)
+#define OMAP4430_CM_IDLEST_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0044)
+#define OMAP4430_CM_AUTOIDLE_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0048)
+#define OMAP4430_CM_CLKSEL_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x004c)
+#define OMAP4430_CM_DIV_M2_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0050)
+#define OMAP4430_CM_DIV_M3_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0054)
+#define OMAP4430_CM_DIV_M4_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0058)
+#define OMAP4430_CM_DIV_M5_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x005c)
+#define OMAP4430_CM_DIV_M6_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0060)
+#define OMAP4430_CM_DIV_M7_DPLL_PER			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0064)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0068)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x006c)
+#define OMAP4430_CM_EMU_OVERRIDE_DPLL_PER		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0070)
+#define OMAP4430_CM_CLKMODE_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0080)
+#define OMAP4430_CM_IDLEST_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0084)
+#define OMAP4430_CM_AUTOIDLE_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0088)
+#define OMAP4430_CM_CLKSEL_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x008c)
+#define OMAP4430_CM_DIV_M2_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x0090)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00a8)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ac)
+#define OMAP4430_CM_CLKDCOLDO_DPLL_USB			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00b4)
+#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c0)
+#define OMAP4430_CM_IDLEST_DPLL_UNIPRO			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c4)
+#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00c8)
+#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00cc)
+#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00d0)
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00e8)
+#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_MOD, 0x00ec)
+
+/* CM2.ALWAYS_ON_CM2 register offsets */
+#define OMAP4430_CM_ALWON_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0000)
+#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0020)
+#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0028)
+#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0030)
+#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_MOD, 0x0038)
+
+/* CM2.CORE_CM2 register offsets */
+#define OMAP4430_CM_L3_1_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0000)
+#define OMAP4430_CM_L3_1_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0008)
+#define OMAP4430_CM_L3_1_L3_1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0020)
+#define OMAP4430_CM_L3_2_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0100)
+#define OMAP4430_CM_L3_2_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0108)
+#define OMAP4430_CM_L3_2_L3_2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0120)
+#define OMAP4430_CM_L3_2_GPMC_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0128)
+#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0130)
+#define OMAP4430_CM_DUCATI_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0200)
+#define OMAP4430_CM_DUCATI_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0204)
+#define OMAP4430_CM_DUCATI_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0208)
+#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0220)
+#define OMAP4430_CM_SDMA_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0300)
+#define OMAP4430_CM_SDMA_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0304)
+#define OMAP4430_CM_SDMA_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0308)
+#define OMAP4430_CM_SDMA_SDMA_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0320)
+#define OMAP4430_CM_MEMIF_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0400)
+#define OMAP4430_CM_MEMIF_DMM_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0420)
+#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0428)
+#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0430)
+#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0438)
+#define OMAP4430_CM_MEMIF_DLL_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0440)
+#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0450)
+#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0458)
+#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0460)
+#define OMAP4430_CM_D2D_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0500)
+#define OMAP4430_CM_D2D_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0504)
+#define OMAP4430_CM_D2D_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0508)
+#define OMAP4430_CM_D2D_SAD2D_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0520)
+#define OMAP4430_CM_D2D_MODEM_ICR_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0528)
+#define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0530)
+#define OMAP4430_CM_L4CFG_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0600)
+#define OMAP4430_CM_L4CFG_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0608)
+#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0620)
+#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0628)
+#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0630)
+#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0638)
+#define OMAP4430_CM_L3INSTR_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0700)
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0720)
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0728)
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_MOD, 0x0740)
+
+/* CM2.IVAHD_CM2 register offsets */
+#define OMAP4430_CM_IVAHD_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0000)
+#define OMAP4430_CM_IVAHD_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0004)
+#define OMAP4430_CM_IVAHD_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0008)
+#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0020)
+#define OMAP4430_CM_IVAHD_SL2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_MOD, 0x0028)
+
+/* CM2.CAM_CM2 register offsets */
+#define OMAP4430_CM_CAM_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0000)
+#define OMAP4430_CM_CAM_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0004)
+#define OMAP4430_CM_CAM_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0008)
+#define OMAP4430_CM_CAM_ISS_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0020)
+#define OMAP4430_CM_CAM_FDIF_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_MOD, 0x0028)
+
+/* CM2.DSS_CM2 register offsets */
+#define OMAP4430_CM_DSS_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0000)
+#define OMAP4430_CM_DSS_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0004)
+#define OMAP4430_CM_DSS_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0008)
+#define OMAP4430_CM_DSS_DSS_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0020)
+#define OMAP4430_CM_DSS_DEISS_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_MOD, 0x0028)
+
+/* CM2.GFX_CM2 register offsets */
+#define OMAP4430_CM_GFX_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0000)
+#define OMAP4430_CM_GFX_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0004)
+#define OMAP4430_CM_GFX_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0008)
+#define OMAP4430_CM_GFX_GFX_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_MOD, 0x0020)
+
+/* CM2.L3INIT_CM2 register offsets */
+#define OMAP4430_CM_L3INIT_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0000)
+#define OMAP4430_CM_L3INIT_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0004)
+#define OMAP4430_CM_L3INIT_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0008)
+#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0028)
+#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0030)
+#define OMAP4430_CM_L3INIT_HSI_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0038)
+#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0040)
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0058)
+#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0060)
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0068)
+#define OMAP4430_CM_L3INIT_P1500_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0078)
+#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0080)
+#define OMAP4430_CM_L3INIT_SATA_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0088)
+#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0090)
+#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x0098)
+#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00a8)
+#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c0)
+#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00c8)
+#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00d0)
+#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_MOD, 0x00e0)
+
+/* CM2.L4PER_CM2 register offsets */
+#define OMAP4430_CM_L4PER_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0000)
+#define OMAP4430_CM_L4PER_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0008)
+#define OMAP4430_CM_L4PER_ADC_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0020)
+#define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0028)
+#define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0030)
+#define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0038)
+#define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0040)
+#define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0048)
+#define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0050)
+#define OMAP4430_CM_L4PER_ELM_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0058)
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0060)
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0068)
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0070)
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0078)
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0080)
+#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0088)
+#define OMAP4430_CM_L4PER_HECC1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0090)
+#define OMAP4430_CM_L4PER_HECC2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0098)
+#define OMAP4430_CM_L4PER_I2C1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a0)
+#define OMAP4430_CM_L4PER_I2C2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00a8)
+#define OMAP4430_CM_L4PER_I2C3_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b0)
+#define OMAP4430_CM_L4PER_I2C4_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00b8)
+#define OMAP4430_CM_L4PER_L4PER_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00c0)
+#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d0)
+#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00d8)
+#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e0)
+#define OMAP4430_CM_L4PER_MGATE_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00e8)
+#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f0)
+#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x00f8)
+#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0100)
+#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0108)
+#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0120)
+#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0128)
+#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0130)
+#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0138)
+#define OMAP4430_CM_L4PER_UART1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0140)
+#define OMAP4430_CM_L4PER_UART2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0148)
+#define OMAP4430_CM_L4PER_UART3_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0150)
+#define OMAP4430_CM_L4PER_UART4_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0158)
+#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0160)
+#define OMAP4430_CM_L4PER_I2C5_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0168)
+#define OMAP4430_CM_L4SEC_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0180)
+#define OMAP4430_CM_L4SEC_STATICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0184)
+#define OMAP4430_CM_L4SEC_DYNAMICDEP			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x0188)
+#define OMAP4430_CM_L4SEC_AES1_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a0)
+#define OMAP4430_CM_L4SEC_AES2_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01a8)
+#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b0)
+#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01b8)
+#define OMAP4430_CM_L4SEC_RNG_CLKCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c0)
+#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01c8)
+#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_MOD, 0x01d8)
+
+/* CM2.CEFUSE_CM2 register offsets */
+#define OMAP4430_CM_CEFUSE_CLKSTCTRL			OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0000)
+#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_MOD, 0x0020)
+
+/* CM2.RESTORE_CM2 register offsets */
+#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0000)
+#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0004)
+#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0008)
+#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x000c)
+#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0010)
+#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0014)
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0018)
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x001c)
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0020)
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0024)
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0028)
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x002c)
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0030)
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0034)
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0038)
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE	OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x003c)
+#define OMAP4430_CM_SDMA_STATICDEP_RESTORE		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_MOD, 0x0040)
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,8 @@
 
 #include <asm/atomic.h>
 
+#include <plat/common.h>
+
 #include "cm.h"
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
@@ -61,9 +63,8 @@ int omap2_cm_wait_module_ready(s16 prcm_
 	mask = 1 << idlest_shift;
 
 	/* XXX should be OMAP2 CM */
-	while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) &&
-	       (i++ < MAX_MODULE_READY_TIME))
-		udelay(1);
+	omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
+			  MAX_MODULE_READY_TIME, i);
 
 	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,8 +4,8 @@
 /*
  * OMAP2/3 Clock Management (CM) register definitions
  *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
@@ -17,11 +17,17 @@
 #include "prcm-common.h"
 
 #define OMAP2420_CM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+			OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
 #define OMAP2430_CM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+			OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
 #define OMAP34XX_CM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+			OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+#define OMAP44XX_CM1_REGADDR(module, reg)				\
+			OMAP2_L4_IO_ADDRESS(OMAP4430_CM1_BASE + (module) + (reg))
+#define OMAP44XX_CM2_REGADDR(module, reg)				\
+			OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE + (module) + (reg))
+
+#include "cm44xx.h"
 
 /*
  * Architecture-specific global CM registers
@@ -89,6 +95,11 @@
 #define OMAP3430_CM_CLKSEL2_EMU				0x0050
 #define OMAP3430_CM_CLKSEL3_EMU				0x0054
 
+/* CM2.CEFUSE_CM2 register offsets */
+
+/* OMAP4 modulemode control */
+#define OMAP4430_MODULEMODE_HWCTRL			0
+#define OMAP4430_MODULEMODE_SWCTRL			1
 
 /* Clock management domain register get/set */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cm-regbits-44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1474 @@
+/*
+ * OMAP44xx Clock Management register bits
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 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_REGBITS_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H
+
+#include "cm.h"
+
+
+/* Used by CM_L3_1_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
+#define OMAP4430_ABE_DYNDEP_SHIFT				(1 << 3)
+#define OMAP4430_ABE_DYNDEP_MASK				BITFIELD(3, 3)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
+ * CM_TESLA_STATICDEP
+ */
+#define OMAP4430_ABE_STATDEP_SHIFT				(1 << 3)
+#define OMAP4430_ABE_STATDEP_MASK				BITFIELD(3, 3)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_ALWONCORE_DYNDEP_SHIFT				(1 << 16)
+#define OMAP4430_ALWONCORE_DYNDEP_MASK				BITFIELD(16, 16)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
+#define OMAP4430_ALWONCORE_STATDEP_SHIFT			(1 << 16)
+#define OMAP4430_ALWONCORE_STATDEP_MASK				BITFIELD(16, 16)
+
+/*
+ * Used by CM_AUTOIDLE_DPLL_PER, CM_AUTOIDLE_DPLL_UNIPRO, CM_AUTOIDLE_DPLL_USB,
+ * CM_AUTOIDLE_DPLL_CORE_RESTORE, CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE,
+ * CM_AUTOIDLE_DPLL_DDRPHY, CM_AUTOIDLE_DPLL_IVA, CM_AUTOIDLE_DPLL_MPU
+ */
+#define OMAP4430_AUTO_DPLL_MODE_SHIFT				(1 << 0)
+#define OMAP4430_AUTO_DPLL_MODE_MASK				BITFIELD(0, 2)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_CEFUSE_DYNDEP_SHIFT				(1 << 17)
+#define OMAP4430_CEFUSE_DYNDEP_MASK				BITFIELD(17, 17)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
+#define OMAP4430_CEFUSE_STATDEP_SHIFT				(1 << 17)
+#define OMAP4430_CEFUSE_STATDEP_MASK				BITFIELD(17, 17)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK			BITFIELD(13, 13)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK		BITFIELD(12, 12)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT			(1 << 11)
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK			BITFIELD(11, 11)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK			BITFIELD(11, 11)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK		BITFIELD(12, 12)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK		BITFIELD(13, 13)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK		BITFIELD(9, 9)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK		BITFIELD(9, 9)
+
+/* Used by CM_CEFUSE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK		BITFIELD(9, 9)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT			(1 << 11)
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK			BITFIELD(11, 11)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT			(1 << 12)
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK			BITFIELD(12, 12)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT			(1 << 13)
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK			BITFIELD(13, 13)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT			(1 << 14)
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK			BITFIELD(14, 14)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK		BITFIELD(10, 10)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_DUCATI_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_MASK		BITFIELD(10, 10)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT		(1 << 15)
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK		BITFIELD(15, 15)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK		BITFIELD(10, 10)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK		BITFIELD(11, 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT		(1 << 20)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK		BITFIELD(20, 20)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT		(1 << 26)
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK			BITFIELD(26, 26)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT		(1 << 21)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK		BITFIELD(21, 21)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT		(1 << 27)
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK			BITFIELD(27, 27)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_SHIFT		(1 << 31)
+#define OMAP4430_CLKACTIVITY_INIT_32K_GFCLK_MASK		BITFIELD(31, 31)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT		(1 << 13)
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK		BITFIELD(13, 13)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK		BITFIELD(12, 12)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT		(1 << 28)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK		BITFIELD(28, 28)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT		(1 << 29)
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK		BITFIELD(29, 29)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK		BITFIELD(11, 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT		(1 << 16)
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK		BITFIELD(16, 16)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT		(1 << 17)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK		BITFIELD(17, 17)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT		(1 << 18)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK		BITFIELD(18, 18)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT		(1 << 19)
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK		BITFIELD(19, 19)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_IVAHD_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK		BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_SHIFT	(1 << 14)
+#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_MASK		BITFIELD(14, 14)
+
+/* Used by CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3_2_CLKSTCTRL, CM_L3_2_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_SDMA_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_GFX_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INSTR_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK		BITFIELD(8, 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK		BITFIELD(8, 8)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_CEFUSE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK		BITFIELD(8, 8)
+
+/* Used by CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK		BITFIELD(9, 9)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT		(1 << 12)
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK			BITFIELD(12, 12)
+
+/* Used by CM_MPU_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT		(1 << 16)
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK		BITFIELD(16, 16)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT		(1 << 17)
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK			BITFIELD(17, 17)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT		(1 << 18)
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK			BITFIELD(18, 18)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT		(1 << 19)
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK			BITFIELD(19, 19)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT		(1 << 25)
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK		BITFIELD(25, 25)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_PER_DPLL_EMU_CLK_MASK		BITFIELD(10, 10)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT		(1 << 20)
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK		BITFIELD(20, 20)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_SHIFT		(1 << 21)
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK		BITFIELD(21, 21)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT		(1 << 22)
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK		BITFIELD(22, 22)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT		(1 << 24)
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK			BITFIELD(24, 24)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_GFX_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT			(1 << 9)
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK		BITFIELD(11, 11)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT		(1 << 10)
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT		(1 << 9)
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT			(1 << 8)
+#define OMAP4430_CLKACTIVITY_SYS_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_TESLA_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT		(1 << 8)
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK		BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT		(1 << 22)
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK			BITFIELD(22, 22)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT		(1 << 23)
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK			BITFIELD(23, 23)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT		(1 << 24)
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK			BITFIELD(24, 24)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT		(1 << 15)
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK		BITFIELD(15, 15)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT			(1 << 10)
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT		(1 << 30)
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK			BITFIELD(30, 30)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT		(1 << 25)
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK		BITFIELD(25, 25)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT		(1 << 11)
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK		BITFIELD(11, 11)
+
+/*
+ * Used by CM_WKUP_TIMER1_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
+ * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
+ * CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
+ * CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MMC6_CLKCTRL,
+ * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_SHIFT					(1 << 24)
+#define OMAP4430_CLKSEL_MASK					BITFIELD(24, 24)
+
+/*
+ * Renamed from CLKSEL Used by CM_ABE_DSS_SYS_CLKSEL, CM_ABE_PLL_REF_CLKSEL,
+ * CM_DPLL_SYS_REF_CLKSEL, CM_L4_WKUP_CLKSEL, CM_CLKSEL_DUCATI_ISS_ROOT,
+ * CM_CLKSEL_USB_60MHZ
+ */
+#define OMAP4430_CLKSEL_0_0_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_0_0_MASK				BITFIELD(0, 0)
+
+/* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
+#define OMAP4430_CLKSEL_0_1_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_0_1_MASK				BITFIELD(0, 1)
+
+/* Renamed from CLKSEL Used by CM_L3INIT_HSI_CLKCTRL */
+#define OMAP4430_CLKSEL_24_25_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_24_25_MASK				BITFIELD(24, 25)
+
+/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
+#define OMAP4430_CLKSEL_60M_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_60M_MASK				BITFIELD(24, 24)
+
+/* Used by CM1_ABE_AESS_CLKCTRL */
+#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_AESS_FCLK_MASK				BITFIELD(24, 24)
+
+/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+#define OMAP4430_CLKSEL_CORE_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_CORE_MASK				BITFIELD(0, 0)
+
+/* Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP4430_CLKSEL_CORE_1_1_SHIFT				(1 << 1)
+#define OMAP4430_CLKSEL_CORE_1_1_MASK				BITFIELD(1, 1)
+
+/* Used by CM_WKUP_USIM_CLKCTRL */
+#define OMAP4430_CLKSEL_DIV_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_DIV_MASK				BITFIELD(24, 24)
+
+/* Used by CM_CAM_FDIF_CLKCTRL */
+#define OMAP4430_CLKSEL_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_FCLK_MASK				BITFIELD(24, 25)
+
+/* Used by CM_L4PER_MCBSP4_CLKCTRL */
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT			(1 << 25)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK			BITFIELD(25, 25)
+
+/*
+ * Renamed from CLKSEL_INTERNAL_SOURCE Used by CM1_ABE_DMIC_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT	(1 << 26)
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK	BITFIELD(26, 27)
+
+/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+#define OMAP4430_CLKSEL_L3_SHIFT				(1 << 4)
+#define OMAP4430_CLKSEL_L3_MASK					BITFIELD(4, 4)
+
+/* Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT				(1 << 2)
+#define OMAP4430_CLKSEL_L3_SHADOW_MASK				BITFIELD(2, 2)
+
+/* Used by CM_CLKSEL_CORE_RESTORE, CM_CLKSEL_CORE */
+#define OMAP4430_CLKSEL_L4_SHIFT				(1 << 8)
+#define OMAP4430_CLKSEL_L4_MASK					BITFIELD(8, 8)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_CLKSEL_OPP_SHIFT				(1 << 0)
+#define OMAP4430_CLKSEL_OPP_MASK				BITFIELD(0, 1)
+
+/* Used by CM_GFX_GFX_CLKCTRL */
+#define OMAP4430_CLKSEL_PER_192M_SHIFT				(1 << 25)
+#define OMAP4430_CLKSEL_PER_192M_MASK				BITFIELD(25, 26)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT			(1 << 27)
+#define OMAP4430_CLKSEL_PMD_STM_CLK_MASK			BITFIELD(27, 29)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT			(1 << 24)
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK			BITFIELD(24, 26)
+
+/* Used by CM_GFX_GFX_CLKCTRL */
+#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_SGX_FCLK_MASK				BITFIELD(24, 24)
+
+/*
+ * Used by CM1_ABE_DMIC_CLKCTRL, CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL,
+ * CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_SOURCE_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_SOURCE_MASK				BITFIELD(24, 25)
+
+/* Renamed from CLKSEL_SOURCE Used by CM_L4PER_MCBSP4_CLKCTRL */
+#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT			(1 << 24)
+#define OMAP4430_CLKSEL_SOURCE_24_24_MASK			BITFIELD(24, 24)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_CLKSEL_UTMI_P1_SHIFT				(1 << 24)
+#define OMAP4430_CLKSEL_UTMI_P1_MASK				BITFIELD(24, 24)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_CLKSEL_UTMI_P2_SHIFT				(1 << 25)
+#define OMAP4430_CLKSEL_UTMI_P2_MASK				BITFIELD(25, 25)
+
+/*
+ * Used by CM_WKUP_CLKSTCTRL, CM_EMU_CLKSTCTRL, CM_D2D_CLKSTCTRL,
+ * CM_DUCATI_CLKSTCTRL, CM_L3INSTR_CLKSTCTRL, CM_L3_1_CLKSTCTRL,
+ * CM_L3_2_CLKSTCTRL, CM_L4CFG_CLKSTCTRL, CM_MEMIF_CLKSTCTRL,
+ * CM_SDMA_CLKSTCTRL, CM_GFX_CLKSTCTRL, CM_L4PER_CLKSTCTRL, CM_L4SEC_CLKSTCTRL,
+ * CM_L3INIT_CLKSTCTRL, CM_CAM_CLKSTCTRL, CM_CEFUSE_CLKSTCTRL,
+ * CM_L3INIT_CLKSTCTRL_RESTORE, CM_L3_1_CLKSTCTRL_RESTORE,
+ * CM_L3_2_CLKSTCTRL_RESTORE, CM_L4CFG_CLKSTCTRL_RESTORE,
+ * CM_L4PER_CLKSTCTRL_RESTORE, CM_MEMIF_CLKSTCTRL_RESTORE, CM_ALWON_CLKSTCTRL,
+ * CM_IVAHD_CLKSTCTRL, CM_DSS_CLKSTCTRL, CM_MPU_CLKSTCTRL, CM_TESLA_CLKSTCTRL,
+ * CM1_ABE_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE
+ */
+#define OMAP4430_CLKTRCTRL_SHIFT				(1 << 0)
+#define OMAP4430_CLKTRCTRL_MASK					BITFIELD(0, 1)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT			(1 << 0)
+#define OMAP4430_CORE_DPLL_EMU_DIV_MASK				BITFIELD(0, 6)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT			(1 << 8)
+#define OMAP4430_CORE_DPLL_EMU_MULT_MASK			BITFIELD(8, 18)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_D2D_DYNDEP_SHIFT				(1 << 18)
+#define OMAP4430_D2D_DYNDEP_MASK				BITFIELD(18, 18)
+
+/* Used by CM_MPU_STATICDEP */
+#define OMAP4430_D2D_STATDEP_SHIFT				(1 << 18)
+#define OMAP4430_D2D_STATDEP_MASK				BITFIELD(18, 18)
+
+/*
+ * Used by CM_SSC_DELTAMSTEP_DPLL_PER, CM_SSC_DELTAMSTEP_DPLL_UNIPRO,
+ * CM_SSC_DELTAMSTEP_DPLL_USB, CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE,
+ * CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
+ * CM_SSC_DELTAMSTEP_DPLL_DDRPHY, CM_SSC_DELTAMSTEP_DPLL_IVA,
+ * CM_SSC_DELTAMSTEP_DPLL_MPU
+ */
+#define OMAP4430_DELTAMSTEP_SHIFT				(1 << 0)
+#define OMAP4430_DELTAMSTEP_MASK				BITFIELD(0, 19)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_DLL_OVERRIDE_SHIFT				(1 << 2)
+#define OMAP4430_DLL_OVERRIDE_MASK				BITFIELD(2, 2)
+
+/* Renamed from DLL_OVERRIDE Used by CM_DLL_CTRL */
+#define OMAP4430_DLL_OVERRIDE_0_0_SHIFT				(1 << 0)
+#define OMAP4430_DLL_OVERRIDE_0_0_MASK				BITFIELD(0, 0)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_DLL_RESET_SHIFT				(1 << 3)
+#define OMAP4430_DLL_RESET_MASK					BITFIELD(3, 3)
+
+/*
+ * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO, CM_CLKSEL_DPLL_USB,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ */
+#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT				(1 << 23)
+#define OMAP4430_DPLL_BYP_CLKSEL_MASK				BITFIELD(23, 23)
+
+/* Used by CM_CLKDCOLDO_DPLL_USB */
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK			BITFIELD(8, 8)
+
+/* Used by CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_CORE */
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT			(1 << 20)
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK			BITFIELD(20, 20)
+
+/*
+ * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
+ * CM_DIV_M3_DPLL_CORE
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT			(1 << 0)
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK			BITFIELD(0, 4)
+
+/*
+ * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
+ * CM_DIV_M3_DPLL_CORE
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT			(1 << 5)
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK			BITFIELD(5, 5)
+
+/*
+ * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
+ * CM_DIV_M3_DPLL_CORE
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK			BITFIELD(8, 8)
+
+/* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT			(1 << 10)
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK			BITFIELD(10, 10)
+
+/*
+ * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
+ */
+#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CLKOUT_DIV_MASK				BITFIELD(0, 4)
+
+/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_USB */
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT			(1 << 0)
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK			BITFIELD(0, 6)
+
+/*
+ * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU
+ */
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT			(1 << 5)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK			BITFIELD(5, 5)
+
+/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_USB */
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT		(1 << 7)
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK		BITFIELD(7, 7)
+
+/*
+ * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB, CM_DIV_M2_DPLL_CORE_RESTORE,
+ * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
+ * CM_DIV_M2_DPLL_MPU
+ */
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK			BITFIELD(8, 8)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_CORE_DPLL_EN_MASK				BITFIELD(8, 10)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT				(1 << 11)
+#define OMAP4430_DPLL_CORE_M2_DIV_MASK				BITFIELD(11, 15)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_CORE_M5_DIV_MASK				BITFIELD(3, 7)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_SHIFT			(1 << 1)
+#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_MASK			BITFIELD(1, 1)
+
+/*
+ * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ */
+#define OMAP4430_DPLL_DIV_SHIFT					(1 << 0)
+#define OMAP4430_DPLL_DIV_MASK					BITFIELD(0, 6)
+
+/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_DIV_0_7_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_DIV_0_7_MASK				BITFIELD(0, 7)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_USB,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT			(1 << 8)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK			BITFIELD(8, 8)
+
+/* Renamed from DPLL_DRIFTGUARD_EN Used by CM_CLKMODE_DPLL_UNIPRO */
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT			(1 << 3)
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK			BITFIELD(3, 3)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_EN_SHIFT					(1 << 0)
+#define OMAP4430_DPLL_EN_MASK					BITFIELD(0, 2)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_LPMODE_EN_SHIFT				(1 << 10)
+#define OMAP4430_DPLL_LPMODE_EN_MASK				BITFIELD(10, 10)
+
+/*
+ * Used by CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA, CM_CLKSEL_DPLL_MPU
+ */
+#define OMAP4430_DPLL_MULT_SHIFT				(1 << 8)
+#define OMAP4430_DPLL_MULT_MASK					BITFIELD(8, 18)
+
+/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_MULT_USB_SHIFT				(1 << 8)
+#define OMAP4430_DPLL_MULT_USB_MASK				BITFIELD(8, 19)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_REGM4XEN_SHIFT				(1 << 11)
+#define OMAP4430_DPLL_REGM4XEN_MASK				BITFIELD(11, 11)
+
+/* Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_SD_DIV_SHIFT				(1 << 24)
+#define OMAP4430_DPLL_SD_DIV_MASK				BITFIELD(24, 31)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_SSC_ACK_SHIFT				(1 << 13)
+#define OMAP4430_DPLL_SSC_ACK_MASK				BITFIELD(13, 13)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT			(1 << 14)
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK			BITFIELD(14, 14)
+
+/*
+ * Used by CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU
+ */
+#define OMAP4430_DPLL_SSC_EN_SHIFT				(1 << 12)
+#define OMAP4430_DPLL_SSC_EN_MASK				BITFIELD(12, 12)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP4430_DSS_DYNDEP_SHIFT				(1 << 8)
+#define OMAP4430_DSS_DYNDEP_MASK				BITFIELD(8, 8)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
+ * CM_MPU_STATICDEP
+ */
+#define OMAP4430_DSS_STATDEP_SHIFT				(1 << 8)
+#define OMAP4430_DSS_STATDEP_MASK				BITFIELD(8, 8)
+
+/* Used by CM_L3_2_DYNAMICDEP */
+#define OMAP4430_DUCATI_DYNDEP_SHIFT				(1 << 0)
+#define OMAP4430_DUCATI_DYNDEP_MASK				BITFIELD(0, 0)
+
+/* Used by CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP */
+#define OMAP4430_DUCATI_STATDEP_SHIFT				(1 << 0)
+#define OMAP4430_DUCATI_STATDEP_MASK				BITFIELD(0, 0)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1_RESTORE, CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP4430_FREQ_UPDATE_SHIFT				(1 << 0)
+#define OMAP4430_FREQ_UPDATE_MASK				BITFIELD(0, 0)
+
+/* Used by CM_L3_2_DYNAMICDEP */
+#define OMAP4430_GFX_DYNDEP_SHIFT				(1 << 10)
+#define OMAP4430_GFX_DYNDEP_MASK				BITFIELD(10, 10)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_GFX_STATDEP_SHIFT				(1 << 10)
+#define OMAP4430_GFX_STATDEP_MASK				BITFIELD(10, 10)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT				(1 << 0)
+#define OMAP4430_GPMC_FREQ_UPDATE_MASK				BITFIELD(0, 0)
+
+/*
+ * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK			BITFIELD(0, 4)
+
+/*
+ * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK		BITFIELD(5, 5)
+
+/*
+ * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK		BITFIELD(8, 8)
+
+/*
+ * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK			BITFIELD(12, 12)
+
+/*
+ * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK			BITFIELD(0, 4)
+
+/*
+ * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK		BITFIELD(5, 5)
+
+/*
+ * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK		BITFIELD(8, 8)
+
+/*
+ * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK			BITFIELD(12, 12)
+
+/*
+ * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK			BITFIELD(0, 4)
+
+/*
+ * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK		BITFIELD(5, 5)
+
+/*
+ * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK		BITFIELD(8, 8)
+
+/*
+ * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK			BITFIELD(12, 12)
+
+/*
+ * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_CORE
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT			(1 << 0)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK			BITFIELD(0, 4)
+
+/*
+ * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_CORE
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT		(1 << 5)
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK		BITFIELD(5, 5)
+
+/*
+ * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_CORE
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT		(1 << 8)
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK		BITFIELD(8, 8)
+
+/*
+ * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_CORE
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT			(1 << 12)
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK			BITFIELD(12, 12)
+
+/*
+ * Used by PRM_PRM_PROFILING_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL,
+ * CM_WKUP_KEYBOARD_CLKCTRL, CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL,
+ * CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL,
+ * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL,
+ * CM_WKUP_WDT2_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL,
+ * CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
+ * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
+ * CM_L4PER_ADC_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
+ * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
+ * CM_L4PER_DMTIMER9_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_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL,
+ * CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
+ * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
+ * CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
+ * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL,
+ * CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL,
+ * CM_L4PER_MSPROHG_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
+ * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
+ * CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL,
+ * CM_L4SEC_DES3DES_CLKCTRL, CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
+ * CM_L4SEC_SHA2MD51_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
+ * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_3_CLKCTRL_RESTORE, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_ALWON_MDMINTC_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL,
+ * CM_ALWON_SR_MPU_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL, CM_IVAHD_SL2_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
+ * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL,
+ * CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL, CM1_ABE_MCASP_CLKCTRL,
+ * CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL,
+ * CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL, CM1_ABE_TIMER5_CLKCTRL,
+ * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
+ * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
+ */
+#define OMAP4430_IDLEST_SHIFT					(1 << 16)
+#define OMAP4430_IDLEST_MASK					BITFIELD(16, 17)
+
+/* Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_ISS_DYNDEP_SHIFT				(1 << 9)
+#define OMAP4430_ISS_DYNDEP_MASK				BITFIELD(9, 9)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
+ * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_ISS_STATDEP_SHIFT				(1 << 9)
+#define OMAP4430_ISS_STATDEP_MASK				BITFIELD(9, 9)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
+#define OMAP4430_IVAHD_DYNDEP_SHIFT				(1 << 2)
+#define OMAP4430_IVAHD_DYNDEP_MASK				BITFIELD(2, 2)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_GFX_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_DSS_STATICDEP, CM_MPU_STATICDEP,
+ * CM_TESLA_STATICDEP
+ */
+#define OMAP4430_IVAHD_STATDEP_SHIFT				(1 << 2)
+#define OMAP4430_IVAHD_STATDEP_MASK				BITFIELD(2, 2)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP4430_L3INIT_DYNDEP_SHIFT				(1 << 7)
+#define OMAP4430_L3INIT_DYNDEP_MASK				BITFIELD(7, 7)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3INIT_STATDEP_SHIFT				(1 << 7)
+#define OMAP4430_L3INIT_STATDEP_MASK				BITFIELD(7, 7)
+
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
+ * CM_DSS_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ */
+#define OMAP4430_L3_1_DYNDEP_SHIFT				(1 << 5)
+#define OMAP4430_L3_1_DYNDEP_MASK				BITFIELD(5, 5)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
+ * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3_1_STATDEP_SHIFT				(1 << 5)
+#define OMAP4430_L3_1_STATDEP_MASK				BITFIELD(5, 5)
+
+/*
+ * Used by CM_EMU_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_DUCATI_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_SDMA_DYNAMICDEP,
+ * CM_GFX_DYNAMICDEP, CM_L4SEC_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
+ * CM_CAM_DYNAMICDEP, CM_IVAHD_DYNAMICDEP
+ */
+#define OMAP4430_L3_2_DYNDEP_SHIFT				(1 << 6)
+#define OMAP4430_L3_2_DYNDEP_MASK				BITFIELD(6, 6)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
+ * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3_2_STATDEP_SHIFT				(1 << 6)
+#define OMAP4430_L3_2_STATDEP_MASK				BITFIELD(6, 6)
+
+/* Used by CM_L3_1_DYNAMICDEP */
+#define OMAP4430_L4CFG_DYNDEP_SHIFT				(1 << 12)
+#define OMAP4430_L4CFG_DYNDEP_MASK				BITFIELD(12, 12)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP,
+ * CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4CFG_STATDEP_SHIFT				(1 << 12)
+#define OMAP4430_L4CFG_STATDEP_MASK				BITFIELD(12, 12)
+
+/* Used by CM_L3_2_DYNAMICDEP */
+#define OMAP4430_L4PER_DYNDEP_SHIFT				(1 << 13)
+#define OMAP4430_L4PER_DYNDEP_MASK				BITFIELD(13, 13)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
+ * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4PER_STATDEP_SHIFT				(1 << 13)
+#define OMAP4430_L4PER_STATDEP_MASK				BITFIELD(13, 13)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP4430_L4SEC_DYNDEP_SHIFT				(1 << 14)
+#define OMAP4430_L4SEC_DYNDEP_MASK				BITFIELD(14, 14)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP
+ */
+#define OMAP4430_L4SEC_STATDEP_SHIFT				(1 << 14)
+#define OMAP4430_L4SEC_STATDEP_MASK				BITFIELD(14, 14)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_L4WKUP_DYNDEP_SHIFT				(1 << 15)
+#define OMAP4430_L4WKUP_DYNDEP_MASK				BITFIELD(15, 15)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP, CM_L3INIT_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4WKUP_STATDEP_SHIFT				(1 << 15)
+#define OMAP4430_L4WKUP_STATDEP_MASK				BITFIELD(15, 15)
+
+/*
+ * Used by CM_D2D_DYNAMICDEP, CM_L3_1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
+ * CM_MPU_DYNAMICDEP
+ */
+#define OMAP4430_MEMIF_DYNDEP_SHIFT				(1 << 4)
+#define OMAP4430_MEMIF_DYNDEP_MASK				BITFIELD(4, 4)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_DUCATI_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_GFX_STATICDEP, CM_L4SEC_STATICDEP, CM_L3INIT_STATICDEP, CM_CAM_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_IVAHD_STATICDEP, CM_DSS_STATICDEP,
+ * CM_MPU_STATICDEP, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_MEMIF_STATDEP_SHIFT				(1 << 4)
+#define OMAP4430_MEMIF_STATDEP_MASK				BITFIELD(4, 4)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB, CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE,
+ * CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
+ * CM_SSC_MODFREQDIV_DPLL_MPU
+ */
+#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT			(1 << 8)
+#define OMAP4430_MODFREQDIV_EXPONENT_MASK			BITFIELD(8, 10)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB, CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE,
+ * CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_DDRPHY, CM_SSC_MODFREQDIV_DPLL_IVA,
+ * CM_SSC_MODFREQDIV_DPLL_MPU
+ */
+#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT			(1 << 0)
+#define OMAP4430_MODFREQDIV_MANTISSA_MASK			BITFIELD(0, 6)
+
+/*
+ * Used by PRM_PRM_PROFILING_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL,
+ * CM_WKUP_KEYBOARD_CLKCTRL, CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL,
+ * CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL,
+ * CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL,
+ * CM_WKUP_WDT2_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL,
+ * CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
+ * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
+ * CM_L4PER_ADC_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
+ * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
+ * CM_L4PER_DMTIMER9_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_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL,
+ * CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
+ * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
+ * CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
+ * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL,
+ * CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL,
+ * CM_L4PER_MSPROHG_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
+ * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
+ * CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL,
+ * CM_L4SEC_DES3DES_CLKCTRL, CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
+ * CM_L4SEC_SHA2MD51_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
+ * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_3_CLKCTRL_RESTORE, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_ALWON_MDMINTC_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL,
+ * CM_ALWON_SR_MPU_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL, CM_IVAHD_SL2_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
+ * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL,
+ * CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL, CM1_ABE_MCASP_CLKCTRL,
+ * CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL,
+ * CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL, CM1_ABE_TIMER5_CLKCTRL,
+ * CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL,
+ * CM1_ABE_WDT3_CLKCTRL, CM_CM1_PROFILING_CLKCTRL
+ */
+#define OMAP4430_MODULEMODE_SHIFT				(1 << 0)
+#define OMAP4430_MODULEMODE_MASK				BITFIELD(0, 1)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_WKUP_BANDGAP_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT				(1 << 9)
+#define OMAP4430_OPTFCLKEN_CLK32K_MASK				BITFIELD(9, 9)
+
+/* Used by CM_CAM_ISS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK				BITFIELD(8, 8)
+
+/*
+ * Used by CM_WKUP_GPIO1_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL_RESTORE, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL_RESTORE, CM_L4PER_GPIO6_CLKCTRL_RESTORE
+ */
+#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_DBCLK_MASK				BITFIELD(8, 8)
+
+/* Used by CM_MEMIF_DLL_CLKCTRL, CM_MEMIF_DLL_H_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK				BITFIELD(8, 8)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_DSSCLK_MASK				BITFIELD(8, 8)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_FCLK0_MASK				BITFIELD(8, 8)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT				(1 << 9)
+#define OMAP4430_OPTFCLKEN_FCLK1_MASK				BITFIELD(9, 9)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT				(1 << 10)
+#define OMAP4430_OPTFCLKEN_FCLK2_MASK				BITFIELD(10, 10)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT			(1 << 15)
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK			BITFIELD(15, 15)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT		(1 << 13)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK			BITFIELD(13, 13)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT		(1 << 14)
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK			BITFIELD(14, 14)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT			(1 << 11)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK			BITFIELD(11, 11)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT			(1 << 12)
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK			BITFIELD(12, 12)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT		(1 << 9)
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_PHY_48M_MASK				BITFIELD(8, 8)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK			BITFIELD(10, 10)
+
+/* Renamed from OPTFCLKEN_SLIMBUS_CLK Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT		(1 << 11)
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK		BITFIELD(11, 11)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK				BITFIELD(10, 10)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT				(1 << 11)
+#define OMAP4430_OPTFCLKEN_TV_CLK_MASK				BITFIELD(11, 11)
+
+/* Used by CM_L3INIT_UNIPRO1_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT			(1 << 8)
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK			BITFIELD(8, 8)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT			(1 << 9)
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK			BITFIELD(9, 9)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT			(1 << 10)
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK			BITFIELD(10, 10)
+
+/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_XCLK_SHIFT				(1 << 8)
+#define OMAP4430_OPTFCLKEN_XCLK_MASK				BITFIELD(8, 8)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_PER, CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_OVERRIDE_ENABLE_SHIFT				(1 << 19)
+#define OMAP4430_OVERRIDE_ENABLE_MASK				BITFIELD(19, 19)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_PAD_CLKS_GATE_SHIFT				(1 << 8)
+#define OMAP4430_PAD_CLKS_GATE_MASK				BITFIELD(8, 8)
+
+/* Used by CM_CORE_DVFS_CURRENT, CM_IVA_DVFS_CURRENT */
+#define OMAP4430_PERF_CURRENT_SHIFT				(1 << 0)
+#define OMAP4430_PERF_CURRENT_MASK				BITFIELD(0, 7)
+
+/*
+ * Used by CM_CORE_DVFS_PERF1, CM_CORE_DVFS_PERF2, CM_CORE_DVFS_PERF3,
+ * CM_CORE_DVFS_PERF4, CM_IVA_DVFS_PERF_ABE, CM_IVA_DVFS_PERF_IVAHD,
+ * CM_IVA_DVFS_PERF_TESLA
+ */
+#define OMAP4430_PERF_REQ_SHIFT					(1 << 0)
+#define OMAP4430_PERF_REQ_MASK					BITFIELD(0, 7)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_PER */
+#define OMAP4430_PER_DPLL_EMU_DIV_SHIFT				(1 << 0)
+#define OMAP4430_PER_DPLL_EMU_DIV_MASK				BITFIELD(0, 6)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_PER */
+#define OMAP4430_PER_DPLL_EMU_MULT_SHIFT			(1 << 8)
+#define OMAP4430_PER_DPLL_EMU_MULT_MASK				BITFIELD(8, 18)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE1_COMPLETED_SHIFT				(1 << 0)
+#define OMAP4430_PHASE1_COMPLETED_MASK				BITFIELD(0, 0)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE2A_COMPLETED_SHIFT			(1 << 1)
+#define OMAP4430_PHASE2A_COMPLETED_MASK				BITFIELD(1, 1)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE2B_COMPLETED_SHIFT			(1 << 2)
+#define OMAP4430_PHASE2B_COMPLETED_MASK				BITFIELD(2, 2)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT				(1 << 20)
+#define OMAP4430_PMD_STM_MUX_CTRL_MASK				BITFIELD(20, 21)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT			(1 << 22)
+#define OMAP4430_PMD_TRACE_MUX_CTRL_MASK			BITFIELD(22, 23)
+
+/* Used by CM_DYN_DEP_PRESCAL */
+#define OMAP4430_PRESCAL_SHIFT					(1 << 0)
+#define OMAP4430_PRESCAL_MASK					BITFIELD(0, 5)
+
+/* Used by REVISION_CM2, REVISION_CM1 */
+#define OMAP4430_REV_SHIFT					(1 << 0)
+#define OMAP4430_REV_MASK					BITFIELD(0, 7)
+
+/*
+ * Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE
+ */
+#define OMAP4430_SAR_MODE_SHIFT					(1 << 4)
+#define OMAP4430_SAR_MODE_MASK					BITFIELD(4, 4)
+
+/* Used by CM_SCALE_FCLK */
+#define OMAP4430_SCALE_FCLK_SHIFT				(1 << 0)
+#define OMAP4430_SCALE_FCLK_MASK				BITFIELD(0, 0)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_SDMA_DYNDEP_SHIFT				(1 << 11)
+#define OMAP4430_SDMA_DYNDEP_MASK				BITFIELD(11, 11)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_SDMA_STATDEP_SHIFT				(1 << 11)
+#define OMAP4430_SDMA_STATDEP_MASK				BITFIELD(11, 11)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT				(1 << 10)
+#define OMAP4430_SLIMBUS_CLK_GATE_MASK				BITFIELD(10, 10)
+
+/*
+ * Used by CM_EMU_DEBUGSS_CLKCTRL, CM_D2D_SAD2D_CLKCTRL,
+ * CM_DUCATI_DUCATI_CLKCTRL, CM_SDMA_SDMA_CLKCTRL, CM_GFX_GFX_CLKCTRL,
+ * CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
+ * CM_IVAHD_IVAHD_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
+ * CM_MPU_MPU_CLKCTRL, CM_TESLA_TESLA_CLKCTRL, CM1_ABE_AESS_CLKCTRL
+ */
+#define OMAP4430_STBYST_SHIFT					(1 << 18)
+#define OMAP4430_STBYST_MASK					BITFIELD(18, 18)
+
+/*
+ * Used by CM_IDLEST_DPLL_PER, CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB,
+ * CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
+ * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU
+ */
+#define OMAP4430_ST_DPLL_CLK_SHIFT				(1 << 0)
+#define OMAP4430_ST_DPLL_CLK_MASK				BITFIELD(0, 0)
+
+/* Used by CM_CLKDCOLDO_DPLL_USB */
+#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT			(1 << 9)
+#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK				BITFIELD(9, 9)
+
+/*
+ * Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB, CM_DIV_M2_DPLL_CORE_RESTORE,
+ * CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_DDRPHY,
+ * CM_DIV_M2_DPLL_MPU
+ */
+#define OMAP4430_ST_DPLL_CLKOUT_SHIFT				(1 << 9)
+#define OMAP4430_ST_DPLL_CLKOUT_MASK				BITFIELD(9, 9)
+
+/*
+ * Used by CM_DIV_M3_DPLL_PER, CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_ABE,
+ * CM_DIV_M3_DPLL_CORE
+ */
+#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT			(1 << 9)
+#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK				BITFIELD(9, 9)
+
+/* Used by CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO, CM_DIV_M2_DPLL_ABE */
+#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT				(1 << 11)
+#define OMAP4430_ST_DPLL_CLKOUTX2_MASK				BITFIELD(11, 11)
+
+/*
+ * Used by CM_DIV_M4_DPLL_PER, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK			BITFIELD(9, 9)
+
+/*
+ * Used by CM_DIV_M5_DPLL_PER, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK			BITFIELD(9, 9)
+
+/*
+ * Used by CM_DIV_M6_DPLL_PER, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK			BITFIELD(9, 9)
+
+/*
+ * Used by CM_DIV_M7_DPLL_PER, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_CORE
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT			(1 << 9)
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK			BITFIELD(9, 9)
+
+/* Used by CM_SYS_CLKSEL */
+#define OMAP4430_SYS_CLKSEL_SHIFT				(1 << 0)
+#define OMAP4430_SYS_CLKSEL_MASK				BITFIELD(0, 2)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4430_TESLA_DYNDEP_SHIFT				(1 << 1)
+#define OMAP4430_TESLA_DYNDEP_MASK				BITFIELD(1, 1)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_TESLA_STATDEP_SHIFT				(1 << 1)
+#define OMAP4430_TESLA_STATDEP_MASK				BITFIELD(1, 1)
+
+/*
+ * Used by CM_EMU_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_DUCATI_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
+ * CM_L4PER_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ */
+#define OMAP4430_WINDOWSIZE_SHIFT				(1 << 24)
+#define OMAP4430_WINDOWSIZE_MASK				BITFIELD(24, 27)
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/control.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/control.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/control.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/control.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,11 +15,127 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 
-#include <mach/common.h>
-#include <mach/control.h>
+#include <plat/common.h>
+#include <plat/control.h>
+#include <plat/sdrc.h>
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "prm.h"
+#include "sdrc.h"
 
 static void __iomem *omap2_ctrl_base;
 
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+struct omap3_scratchpad {
+	u32 boot_config_ptr;
+	u32 public_restore_ptr;
+	u32 secure_ram_restore_ptr;
+	u32 sdrc_module_semaphore;
+	u32 prcm_block_offset;
+	u32 sdrc_block_offset;
+};
+
+struct omap3_scratchpad_prcm_block {
+	u32 prm_clksrc_ctrl;
+	u32 prm_clksel;
+	u32 cm_clksel_core;
+	u32 cm_clksel_wkup;
+	u32 cm_clken_pll;
+	u32 cm_autoidle_pll;
+	u32 cm_clksel1_pll;
+	u32 cm_clksel2_pll;
+	u32 cm_clksel3_pll;
+	u32 cm_clken_pll_mpu;
+	u32 cm_autoidle_pll_mpu;
+	u32 cm_clksel1_pll_mpu;
+	u32 cm_clksel2_pll_mpu;
+	u32 prcm_block_size;
+};
+
+struct omap3_scratchpad_sdrc_block {
+	u16 sysconfig;
+	u16 cs_cfg;
+	u16 sharing;
+	u16 err_type;
+	u32 dll_a_ctrl;
+	u32 dll_b_ctrl;
+	u32 power;
+	u32 cs_0;
+	u32 mcfg_0;
+	u16 mr_0;
+	u16 emr_1_0;
+	u16 emr_2_0;
+	u16 emr_3_0;
+	u32 actim_ctrla_0;
+	u32 actim_ctrlb_0;
+	u32 rfr_ctrl_0;
+	u32 cs_1;
+	u32 mcfg_1;
+	u16 mr_1;
+	u16 emr_1_1;
+	u16 emr_2_1;
+	u16 emr_3_1;
+	u32 actim_ctrla_1;
+	u32 actim_ctrlb_1;
+	u32 rfr_ctrl_1;
+	u16 dcdl_1_ctrl;
+	u16 dcdl_2_ctrl;
+	u32 flags;
+	u32 block_size;
+};
+
+void *omap3_secure_ram_storage;
+
+/*
+ * This is used to store ARM registers in SDRAM before attempting
+ * an MPU OFF. The save and restore happens from the SRAM sleep code.
+ * The address is stored in scratchpad, so that it can be used
+ * during the restore path.
+ */
+u32 omap3_arm_context[128];
+
+struct omap3_control_regs {
+	u32 sysconfig;
+	u32 devconf0;
+	u32 mem_dftrw0;
+	u32 mem_dftrw1;
+	u32 msuspendmux_0;
+	u32 msuspendmux_1;
+	u32 msuspendmux_2;
+	u32 msuspendmux_3;
+	u32 msuspendmux_4;
+	u32 msuspendmux_5;
+	u32 sec_ctrl;
+	u32 devconf1;
+	u32 csirxfe;
+	u32 iva2_bootaddr;
+	u32 iva2_bootmod;
+	u32 debobs_0;
+	u32 debobs_1;
+	u32 debobs_2;
+	u32 debobs_3;
+	u32 debobs_4;
+	u32 debobs_5;
+	u32 debobs_6;
+	u32 debobs_7;
+	u32 debobs_8;
+	u32 prog_io0;
+	u32 prog_io1;
+	u32 dss_dpll_spreading;
+	u32 core_dpll_spreading;
+	u32 per_dpll_spreading;
+	u32 usbhost_dpll_spreading;
+	u32 pbias_lite;
+	u32 temp_sensor;
+	u32 sramldo4;
+	u32 sramldo5;
+	u32 csi;
+};
+
+static struct omap3_control_regs control_context;
+#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+
 #define OMAP_CTRL_REGADDR(reg)		(omap2_ctrl_base + (reg))
 
 void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
@@ -62,3 +178,268 @@ void omap_ctrl_writel(u32 val, u16 offse
 	__raw_writel(val, OMAP_CTRL_REGADDR(offset));
 }
 
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+/*
+ * Clears the scratchpad contents in case of cold boot-
+ * called during bootup
+ */
+void omap3_clear_scratchpad_contents(void)
+{
+	u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET;
+	u32 *v_addr;
+	u32 offset = 0;
+	v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
+	if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
+		OMAP3430_GLOBAL_COLD_RST) {
+		for ( ; offset <= max_offset; offset += 0x4)
+			__raw_writel(0x0, (v_addr + offset));
+		prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST, OMAP3430_GR_MOD,
+			OMAP3_PRM_RSTST_OFFSET);
+	}
+}
+
+/* Populate the scratchpad structure with restore structure */
+void omap3_save_scratchpad_contents(void)
+{
+	void * __iomem scratchpad_address;
+	u32 arm_context_addr;
+	struct omap3_scratchpad scratchpad_contents;
+	struct omap3_scratchpad_prcm_block prcm_block_contents;
+	struct omap3_scratchpad_sdrc_block sdrc_block_contents;
+
+	/* Populate the Scratchpad contents */
+	scratchpad_contents.boot_config_ptr = 0x0;
+	if (omap_rev() != OMAP3430_REV_ES3_0 &&
+					omap_rev() != OMAP3430_REV_ES3_1)
+		scratchpad_contents.public_restore_ptr =
+			virt_to_phys(get_restore_pointer());
+	else
+		scratchpad_contents.public_restore_ptr =
+			virt_to_phys(get_es3_restore_pointer());
+	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+		scratchpad_contents.secure_ram_restore_ptr = 0x0;
+	else
+		scratchpad_contents.secure_ram_restore_ptr =
+			(u32) __pa(omap3_secure_ram_storage);
+	scratchpad_contents.sdrc_module_semaphore = 0x0;
+	scratchpad_contents.prcm_block_offset = 0x2C;
+	scratchpad_contents.sdrc_block_offset = 0x64;
+
+	/* Populate the PRCM block contents */
+	prcm_block_contents.prm_clksrc_ctrl = prm_read_mod_reg(OMAP3430_GR_MOD,
+			OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+	prcm_block_contents.prm_clksel = prm_read_mod_reg(OMAP3430_CCR_MOD,
+			OMAP3_PRM_CLKSEL_OFFSET);
+	prcm_block_contents.cm_clksel_core =
+			cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
+	prcm_block_contents.cm_clksel_wkup =
+			cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
+	prcm_block_contents.cm_clken_pll =
+			cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+	prcm_block_contents.cm_autoidle_pll =
+			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+	prcm_block_contents.cm_clksel1_pll =
+			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
+	prcm_block_contents.cm_clksel2_pll =
+			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
+	prcm_block_contents.cm_clksel3_pll =
+			cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
+	prcm_block_contents.cm_clken_pll_mpu =
+			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
+	prcm_block_contents.cm_autoidle_pll_mpu =
+			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+	prcm_block_contents.cm_clksel1_pll_mpu =
+			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
+	prcm_block_contents.cm_clksel2_pll_mpu =
+			cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+	prcm_block_contents.prcm_block_size = 0x0;
+
+	/* Populate the SDRC block contents */
+	sdrc_block_contents.sysconfig =
+			(sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF);
+	sdrc_block_contents.cs_cfg =
+			(sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF);
+	sdrc_block_contents.sharing =
+			(sdrc_read_reg(SDRC_SHARING) & 0xFFFF);
+	sdrc_block_contents.err_type =
+			(sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
+	sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
+	sdrc_block_contents.dll_b_ctrl = 0x0;
+	/*
+	 * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
+	 * be programed to issue automatic self refresh on timeout
+	 * of AUTO_CNT = 1 prior to any transition to OFF mode.
+	 */
+	if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
+			&& (omap_rev() >= OMAP3430_REV_ES3_0))
+		sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
+				~(SDRC_POWER_AUTOCOUNT_MASK|
+				SDRC_POWER_CLKCTRL_MASK)) |
+				(1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
+				SDRC_SELF_REFRESH_ON_AUTOCOUNT;
+	else
+		sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
+
+	sdrc_block_contents.cs_0 = 0x0;
+	sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
+	sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
+	sdrc_block_contents.emr_1_0 = 0x0;
+	sdrc_block_contents.emr_2_0 = 0x0;
+	sdrc_block_contents.emr_3_0 = 0x0;
+	sdrc_block_contents.actim_ctrla_0 =
+			sdrc_read_reg(SDRC_ACTIM_CTRL_A_0);
+	sdrc_block_contents.actim_ctrlb_0 =
+			sdrc_read_reg(SDRC_ACTIM_CTRL_B_0);
+	sdrc_block_contents.rfr_ctrl_0 =
+			sdrc_read_reg(SDRC_RFR_CTRL_0);
+	sdrc_block_contents.cs_1 = 0x0;
+	sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1);
+	sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF;
+	sdrc_block_contents.emr_1_1 = 0x0;
+	sdrc_block_contents.emr_2_1 = 0x0;
+	sdrc_block_contents.emr_3_1 = 0x0;
+	sdrc_block_contents.actim_ctrla_1 =
+			sdrc_read_reg(SDRC_ACTIM_CTRL_A_1);
+	sdrc_block_contents.actim_ctrlb_1 =
+			sdrc_read_reg(SDRC_ACTIM_CTRL_B_1);
+	sdrc_block_contents.rfr_ctrl_1 =
+			sdrc_read_reg(SDRC_RFR_CTRL_1);
+	sdrc_block_contents.dcdl_1_ctrl = 0x0;
+	sdrc_block_contents.dcdl_2_ctrl = 0x0;
+	sdrc_block_contents.flags = 0x0;
+	sdrc_block_contents.block_size = 0x0;
+
+	arm_context_addr = virt_to_phys(omap3_arm_context);
+
+	/* Copy all the contents to the scratchpad location */
+	scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
+	memcpy_toio(scratchpad_address, &scratchpad_contents,
+		 sizeof(scratchpad_contents));
+	/* Scratchpad contents being 32 bits, a divide by 4 done here */
+	memcpy_toio(scratchpad_address +
+		scratchpad_contents.prcm_block_offset,
+		&prcm_block_contents, sizeof(prcm_block_contents));
+	memcpy_toio(scratchpad_address +
+		scratchpad_contents.sdrc_block_offset,
+		&sdrc_block_contents, sizeof(sdrc_block_contents));
+	/*
+	 * Copies the address of the location in SDRAM where ARM
+	 * registers get saved during a MPU OFF transition.
+	 */
+	memcpy_toio(scratchpad_address +
+		scratchpad_contents.sdrc_block_offset +
+		sizeof(sdrc_block_contents), &arm_context_addr, 4);
+}
+
+void omap3_control_save_context(void)
+{
+	control_context.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG);
+	control_context.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+	control_context.mem_dftrw0 =
+			omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0);
+	control_context.mem_dftrw1 =
+			omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1);
+	control_context.msuspendmux_0 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0);
+	control_context.msuspendmux_1 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1);
+	control_context.msuspendmux_2 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2);
+	control_context.msuspendmux_3 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3);
+	control_context.msuspendmux_4 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4);
+	control_context.msuspendmux_5 =
+			omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5);
+	control_context.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL);
+	control_context.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
+	control_context.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE);
+	control_context.iva2_bootaddr =
+			omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR);
+	control_context.iva2_bootmod =
+			omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD);
+	control_context.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(0));
+	control_context.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(1));
+	control_context.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(2));
+	control_context.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(3));
+	control_context.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(4));
+	control_context.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(5));
+	control_context.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(6));
+	control_context.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(7));
+	control_context.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(8));
+	control_context.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0);
+	control_context.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
+	control_context.dss_dpll_spreading =
+			omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING);
+	control_context.core_dpll_spreading =
+			omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING);
+	control_context.per_dpll_spreading =
+			omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING);
+	control_context.usbhost_dpll_spreading =
+		omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
+	control_context.pbias_lite =
+			omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE);
+	control_context.temp_sensor =
+			omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR);
+	control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4);
+	control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5);
+	control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI);
+	return;
+}
+
+void omap3_control_restore_context(void)
+{
+	omap_ctrl_writel(control_context.sysconfig, OMAP2_CONTROL_SYSCONFIG);
+	omap_ctrl_writel(control_context.devconf0, OMAP2_CONTROL_DEVCONF0);
+	omap_ctrl_writel(control_context.mem_dftrw0,
+					OMAP343X_CONTROL_MEM_DFTRW0);
+	omap_ctrl_writel(control_context.mem_dftrw1,
+					OMAP343X_CONTROL_MEM_DFTRW1);
+	omap_ctrl_writel(control_context.msuspendmux_0,
+					OMAP2_CONTROL_MSUSPENDMUX_0);
+	omap_ctrl_writel(control_context.msuspendmux_1,
+					OMAP2_CONTROL_MSUSPENDMUX_1);
+	omap_ctrl_writel(control_context.msuspendmux_2,
+					OMAP2_CONTROL_MSUSPENDMUX_2);
+	omap_ctrl_writel(control_context.msuspendmux_3,
+					OMAP2_CONTROL_MSUSPENDMUX_3);
+	omap_ctrl_writel(control_context.msuspendmux_4,
+					OMAP2_CONTROL_MSUSPENDMUX_4);
+	omap_ctrl_writel(control_context.msuspendmux_5,
+					OMAP2_CONTROL_MSUSPENDMUX_5);
+	omap_ctrl_writel(control_context.sec_ctrl, OMAP2_CONTROL_SEC_CTRL);
+	omap_ctrl_writel(control_context.devconf1, OMAP343X_CONTROL_DEVCONF1);
+	omap_ctrl_writel(control_context.csirxfe, OMAP343X_CONTROL_CSIRXFE);
+	omap_ctrl_writel(control_context.iva2_bootaddr,
+					OMAP343X_CONTROL_IVA2_BOOTADDR);
+	omap_ctrl_writel(control_context.iva2_bootmod,
+					OMAP343X_CONTROL_IVA2_BOOTMOD);
+	omap_ctrl_writel(control_context.debobs_0, OMAP343X_CONTROL_DEBOBS(0));
+	omap_ctrl_writel(control_context.debobs_1, OMAP343X_CONTROL_DEBOBS(1));
+	omap_ctrl_writel(control_context.debobs_2, OMAP343X_CONTROL_DEBOBS(2));
+	omap_ctrl_writel(control_context.debobs_3, OMAP343X_CONTROL_DEBOBS(3));
+	omap_ctrl_writel(control_context.debobs_4, OMAP343X_CONTROL_DEBOBS(4));
+	omap_ctrl_writel(control_context.debobs_5, OMAP343X_CONTROL_DEBOBS(5));
+	omap_ctrl_writel(control_context.debobs_6, OMAP343X_CONTROL_DEBOBS(6));
+	omap_ctrl_writel(control_context.debobs_7, OMAP343X_CONTROL_DEBOBS(7));
+	omap_ctrl_writel(control_context.debobs_8, OMAP343X_CONTROL_DEBOBS(8));
+	omap_ctrl_writel(control_context.prog_io0, OMAP343X_CONTROL_PROG_IO0);
+	omap_ctrl_writel(control_context.prog_io1, OMAP343X_CONTROL_PROG_IO1);
+	omap_ctrl_writel(control_context.dss_dpll_spreading,
+					OMAP343X_CONTROL_DSS_DPLL_SPREADING);
+	omap_ctrl_writel(control_context.core_dpll_spreading,
+					OMAP343X_CONTROL_CORE_DPLL_SPREADING);
+	omap_ctrl_writel(control_context.per_dpll_spreading,
+					OMAP343X_CONTROL_PER_DPLL_SPREADING);
+	omap_ctrl_writel(control_context.usbhost_dpll_spreading,
+				OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
+	omap_ctrl_writel(control_context.pbias_lite,
+					OMAP343X_CONTROL_PBIAS_LITE);
+	omap_ctrl_writel(control_context.temp_sensor,
+					OMAP343X_CONTROL_TEMP_SENSOR);
+	omap_ctrl_writel(control_context.sramldo4, OMAP343X_CONTROL_SRAMLDO4);
+	omap_ctrl_writel(control_context.sramldo5, OMAP343X_CONTROL_SRAMLDO5);
+	omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI);
+	return;
+}
+#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cpuidle34xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cpuidle34xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/cpuidle34xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/cpuidle34xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,318 @@
+/*
+ * linux/arch/arm/mach-omap2/cpuidle34xx.c
+ *
+ * OMAP3 CPU IDLE Routines
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Karthik Dasu <karthik-dp@ti.com>
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Based on pm.c for omap2
+ *
+ * This 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 <linux/cpuidle.h>
+
+#include <plat/prcm.h>
+#include <plat/irqs.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
+#include <plat/control.h>
+#include <plat/serial.h>
+
+#include "pm.h"
+
+#ifdef CONFIG_CPU_IDLE
+
+#define OMAP3_MAX_STATES 7
+#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
+#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */
+#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */
+#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */
+#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */
+#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
+#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
+
+struct omap3_processor_cx {
+	u8 valid;
+	u8 type;
+	u32 sleep_latency;
+	u32 wakeup_latency;
+	u32 mpu_state;
+	u32 core_state;
+	u32 threshold;
+	u32 flags;
+};
+
+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
+struct omap3_processor_cx current_cx_state;
+struct powerdomain *mpu_pd, *core_pd;
+
+static int omap3_idle_bm_check(void)
+{
+	if (!omap3_can_sleep())
+		return 1;
+	return 0;
+}
+
+static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
+				struct clockdomain *clkdm)
+{
+	omap2_clkdm_allow_idle(clkdm);
+	return 0;
+}
+
+static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
+				struct clockdomain *clkdm)
+{
+	omap2_clkdm_deny_idle(clkdm);
+	return 0;
+}
+
+/**
+ * omap3_enter_idle - Programs OMAP3 to enter the specified state
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified target state selected by the governor.
+ */
+static int omap3_enter_idle(struct cpuidle_device *dev,
+			struct cpuidle_state *state)
+{
+	struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
+	struct timespec ts_preidle, ts_postidle, ts_idle;
+	u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
+
+	current_cx_state = *cx;
+
+	/* Used to keep track of the total time in idle */
+	getnstimeofday(&ts_preidle);
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	if (!enable_off_mode) {
+		if (mpu_state < PWRDM_POWER_RET)
+			mpu_state = PWRDM_POWER_RET;
+		if (core_state < PWRDM_POWER_RET)
+			core_state = PWRDM_POWER_RET;
+	}
+
+	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
+	pwrdm_set_next_pwrst(core_pd, core_state);
+
+	if (omap_irq_pending() || need_resched())
+		goto return_sleep_time;
+
+	if (cx->type == OMAP3_STATE_C1) {
+		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
+		pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
+	}
+
+	/* Execute ARM wfi */
+	omap_sram_idle();
+
+	if (cx->type == OMAP3_STATE_C1) {
+		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
+		pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
+	}
+
+return_sleep_time:
+	getnstimeofday(&ts_postidle);
+	ts_idle = timespec_sub(ts_postidle, ts_preidle);
+
+	local_irq_enable();
+	local_fiq_enable();
+
+	return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
+}
+
+/**
+ * omap3_enter_idle_bm - Checks for any bus activity
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * Used for C states with CPUIDLE_FLAG_CHECK_BM flag set. This
+ * function checks for any pending activity and then programs the
+ * device to the specified or a safer state.
+ */
+static int omap3_enter_idle_bm(struct cpuidle_device *dev,
+			       struct cpuidle_state *state)
+{
+	struct cpuidle_state *new_state = state;
+
+	if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
+		BUG_ON(!dev->safe_state);
+		new_state = dev->safe_state;
+	}
+
+	dev->last_state = new_state;
+	return omap3_enter_idle(dev, new_state);
+}
+
+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
+
+/* omap3_init_power_states - Initialises the OMAP3 specific C states.
+ *
+ * Below is the desciption of each C state.
+ * 	C1 . MPU WFI + Core active
+ *	C2 . MPU WFI + Core inactive
+ *	C3 . MPU CSWR + Core inactive
+ *	C4 . MPU OFF + Core inactive
+ *	C5 . MPU CSWR + Core CSWR
+ *	C6 . MPU OFF + Core CSWR
+ *	C7 . MPU OFF + Core OFF
+ */
+void omap_init_power_states(void)
+{
+	/* C1 . MPU WFI + Core active */
+	omap3_power_states[OMAP3_STATE_C1].valid = 1;
+	omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
+	omap3_power_states[OMAP3_STATE_C1].sleep_latency = 2;
+	omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 2;
+	omap3_power_states[OMAP3_STATE_C1].threshold = 5;
+	omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
+
+	/* C2 . MPU WFI + Core inactive */
+	omap3_power_states[OMAP3_STATE_C2].valid = 1;
+	omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2;
+	omap3_power_states[OMAP3_STATE_C2].sleep_latency = 10;
+	omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 10;
+	omap3_power_states[OMAP3_STATE_C2].threshold = 30;
+	omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
+
+	/* C3 . MPU CSWR + Core inactive */
+	omap3_power_states[OMAP3_STATE_C3].valid = 1;
+	omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
+	omap3_power_states[OMAP3_STATE_C3].sleep_latency = 50;
+	omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 50;
+	omap3_power_states[OMAP3_STATE_C3].threshold = 300;
+	omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET;
+	omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
+				CPUIDLE_FLAG_CHECK_BM;
+
+	/* C4 . MPU OFF + Core inactive */
+	omap3_power_states[OMAP3_STATE_C4].valid = 1;
+	omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
+	omap3_power_states[OMAP3_STATE_C4].sleep_latency = 1500;
+	omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 1800;
+	omap3_power_states[OMAP3_STATE_C4].threshold = 4000;
+	omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF;
+	omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON;
+	omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
+				CPUIDLE_FLAG_CHECK_BM;
+
+	/* C5 . MPU CSWR + Core CSWR*/
+	omap3_power_states[OMAP3_STATE_C5].valid = 1;
+	omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
+	omap3_power_states[OMAP3_STATE_C5].sleep_latency = 2500;
+	omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 7500;
+	omap3_power_states[OMAP3_STATE_C5].threshold = 12000;
+	omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET;
+	omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET;
+	omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID |
+				CPUIDLE_FLAG_CHECK_BM;
+
+	/* C6 . MPU OFF + Core CSWR */
+	omap3_power_states[OMAP3_STATE_C6].valid = 1;
+	omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6;
+	omap3_power_states[OMAP3_STATE_C6].sleep_latency = 3000;
+	omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 8500;
+	omap3_power_states[OMAP3_STATE_C6].threshold = 15000;
+	omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF;
+	omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET;
+	omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID |
+				CPUIDLE_FLAG_CHECK_BM;
+
+	/* C7 . MPU OFF + Core OFF */
+	omap3_power_states[OMAP3_STATE_C7].valid = 1;
+	omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
+	omap3_power_states[OMAP3_STATE_C7].sleep_latency = 10000;
+	omap3_power_states[OMAP3_STATE_C7].wakeup_latency = 30000;
+	omap3_power_states[OMAP3_STATE_C7].threshold = 300000;
+	omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF;
+	omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
+	omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
+				CPUIDLE_FLAG_CHECK_BM;
+}
+
+struct cpuidle_driver omap3_idle_driver = {
+	.name = 	"omap3_idle",
+	.owner = 	THIS_MODULE,
+};
+
+/**
+ * omap3_idle_init - Init routine for OMAP3 idle
+ *
+ * Registers the OMAP3 specific cpuidle driver with the cpuidle
+ * framework with the valid set of states.
+ */
+int __init omap3_idle_init(void)
+{
+	int i, count = 0;
+	struct omap3_processor_cx *cx;
+	struct cpuidle_state *state;
+	struct cpuidle_device *dev;
+
+	mpu_pd = pwrdm_lookup("mpu_pwrdm");
+	core_pd = pwrdm_lookup("core_pwrdm");
+
+	omap_init_power_states();
+	cpuidle_register_driver(&omap3_idle_driver);
+
+	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
+
+	for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
+		cx = &omap3_power_states[i];
+		state = &dev->states[count];
+
+		if (!cx->valid)
+			continue;
+		cpuidle_set_statedata(state, cx);
+		state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
+		state->target_residency = cx->threshold;
+		state->flags = cx->flags;
+		state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
+			omap3_enter_idle_bm : omap3_enter_idle;
+		if (cx->type == OMAP3_STATE_C1)
+			dev->safe_state = state;
+		sprintf(state->name, "C%d", count+1);
+		count++;
+	}
+
+	if (!count)
+		return -EINVAL;
+	dev->state_count = count;
+
+	if (cpuidle_register_device(dev)) {
+		printk(KERN_ERR "%s: CPUidle register device failed\n",
+		       __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+#else
+int __init omap3_idle_init(void)
+{
+	return 0;
+}
+#endif /* CONFIG_CPU_IDLE */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,12 +20,14 @@
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <mach/control.h>
-#include <mach/tc.h>
-#include <mach/board.h>
-#include <mach/mux.h>
+#include <plat/control.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/mux.h>
 #include <mach/gpio.h>
-#include <mach/mmc.h>
+#include <plat/mmc.h>
+
+#include "mux.h"
 
 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
@@ -136,9 +138,10 @@ static inline void omap_init_camera(void
 
 #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
 
-#define MBOX_REG_SIZE	0x120
+#define MBOX_REG_SIZE   0x120
 
-static struct resource omap2_mbox_resources[] = {
+#ifdef CONFIG_ARCH_OMAP2
+static struct resource omap_mbox_resources[] = {
 	{
 		.start		= OMAP24XX_MAILBOX_BASE,
 		.end		= OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
@@ -153,8 +156,10 @@ static struct resource omap2_mbox_resour
 		.flags		= IORESOURCE_IRQ,
 	},
 };
+#endif
 
-static struct resource omap3_mbox_resources[] = {
+#ifdef CONFIG_ARCH_OMAP3
+static struct resource omap_mbox_resources[] = {
 	{
 		.start		= OMAP34XX_MAILBOX_BASE,
 		.end		= OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
@@ -165,6 +170,24 @@ static struct resource omap3_mbox_resour
 		.flags		= IORESOURCE_IRQ,
 	},
 };
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+
+#define OMAP4_MBOX_REG_SIZE	0x130
+static struct resource omap_mbox_resources[] = {
+	{
+		.start          = OMAP44XX_MAILBOX_BASE,
+		.end            = OMAP44XX_MAILBOX_BASE +
+					OMAP4_MBOX_REG_SIZE - 1,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		.start          = INT_44XX_MAIL_U0_MPU,
+		.flags          = IORESOURCE_IRQ,
+	},
+};
+#endif
 
 static struct platform_device mbox_device = {
 	.name		= "omap2-mailbox",
@@ -173,12 +196,9 @@ static struct platform_device mbox_devic
 
 static inline void omap_init_mbox(void)
 {
-	if (cpu_is_omap2420()) {
-		mbox_device.num_resources = ARRAY_SIZE(omap2_mbox_resources);
-		mbox_device.resource = omap2_mbox_resources;
-	} else if (cpu_is_omap3430()) {
-		mbox_device.num_resources = ARRAY_SIZE(omap3_mbox_resources);
-		mbox_device.resource = omap3_mbox_resources;
+	if (cpu_is_omap2420() || cpu_is_omap3430() || cpu_is_omap44xx()) {
+		mbox_device.num_resources = ARRAY_SIZE(omap_mbox_resources);
+		mbox_device.resource = omap_mbox_resources;
 	} else {
 		pr_err("%s: platform not supported\n", __func__);
 		return;
@@ -250,7 +270,7 @@ static inline void omap_init_sti(void) {
 
 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
 
-#include <mach/mcspi.h>
+#include <plat/mcspi.h>
 
 #define OMAP2_MCSPI1_BASE		0x48098000
 #define OMAP2_MCSPI2_BASE		0x4809a000
@@ -575,29 +595,42 @@ static inline void omap2_mmc_mux(struct
 		}
 	}
 
-	if (cpu_is_omap3430()) {
+	if (cpu_is_omap34xx()) {
 		if (controller_nr == 0) {
-			omap_cfg_reg(N28_3430_MMC1_CLK);
-			omap_cfg_reg(M27_3430_MMC1_CMD);
-			omap_cfg_reg(N27_3430_MMC1_DAT0);
+			omap_mux_init_signal("sdmmc1_clk",
+				OMAP_PIN_INPUT_PULLUP);
+			omap_mux_init_signal("sdmmc1_cmd",
+				OMAP_PIN_INPUT_PULLUP);
+			omap_mux_init_signal("sdmmc1_dat0",
+				OMAP_PIN_INPUT_PULLUP);
 			if (mmc_controller->slots[0].wires == 4 ||
 				mmc_controller->slots[0].wires == 8) {
-				omap_cfg_reg(N26_3430_MMC1_DAT1);
-				omap_cfg_reg(N25_3430_MMC1_DAT2);
-				omap_cfg_reg(P28_3430_MMC1_DAT3);
+				omap_mux_init_signal("sdmmc1_dat1",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc1_dat2",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc1_dat3",
+					OMAP_PIN_INPUT_PULLUP);
 			}
 			if (mmc_controller->slots[0].wires == 8) {
-				omap_cfg_reg(P27_3430_MMC1_DAT4);
-				omap_cfg_reg(P26_3430_MMC1_DAT5);
-				omap_cfg_reg(R27_3430_MMC1_DAT6);
-				omap_cfg_reg(R25_3430_MMC1_DAT7);
+				omap_mux_init_signal("sdmmc1_dat4",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc1_dat5",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc1_dat6",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc1_dat7",
+					OMAP_PIN_INPUT_PULLUP);
 			}
 		}
 		if (controller_nr == 1) {
 			/* MMC2 */
-			omap_cfg_reg(AE2_3430_MMC2_CLK);
-			omap_cfg_reg(AG5_3430_MMC2_CMD);
-			omap_cfg_reg(AH5_3430_MMC2_DAT0);
+			omap_mux_init_signal("sdmmc2_clk",
+				OMAP_PIN_INPUT_PULLUP);
+			omap_mux_init_signal("sdmmc2_cmd",
+				OMAP_PIN_INPUT_PULLUP);
+			omap_mux_init_signal("sdmmc2_dat0",
+				OMAP_PIN_INPUT_PULLUP);
 
 			/*
 			 * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
@@ -605,9 +638,22 @@ static inline void omap2_mmc_mux(struct
 			 */
 			if (mmc_controller->slots[0].wires == 4 ||
 				mmc_controller->slots[0].wires == 8) {
-				omap_cfg_reg(AH4_3430_MMC2_DAT1);
-				omap_cfg_reg(AG4_3430_MMC2_DAT2);
-				omap_cfg_reg(AF4_3430_MMC2_DAT3);
+				omap_mux_init_signal("sdmmc2_dat1",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc2_dat2",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc2_dat3",
+					OMAP_PIN_INPUT_PULLUP);
+			}
+			if (mmc_controller->slots[0].wires == 8) {
+				omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
+					OMAP_PIN_INPUT_PULLUP);
+				omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
+					OMAP_PIN_INPUT_PULLUP);
 			}
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/dpll.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/dpll.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/dpll.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,538 @@
+/*
+ * OMAP3/4 - specific DPLL control functions
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Testing and integration fixes by Jouni HÃ¶gander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This 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/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/limits.h>
+#include <linux/bitops.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <asm/div64.h>
+#include <asm/clkdev.h>
+
+#include "clock.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
+#define DPLL_AUTOIDLE_DISABLE			0x0
+#define DPLL_AUTOIDLE_LOW_POWER_STOP		0x1
+
+#define MAX_DPLL_WAIT_TRIES		1000000
+
+
+/**
+ * omap3_dpll_recalc - recalculate DPLL rate
+ * @clk: DPLL struct clk
+ *
+ * Recalculate and propagate the DPLL rate.
+ */
+unsigned long omap3_dpll_recalc(struct clk *clk)
+{
+	return omap2_get_dpll_rate(clk);
+}
+
+/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
+static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->control_reg);
+	v &= ~dd->enable_mask;
+	v |= clken_bits << __ffs(dd->enable_mask);
+	__raw_writel(v, dd->control_reg);
+}
+
+/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
+static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
+{
+	const struct dpll_data *dd;
+	int i = 0;
+	int ret = -EINVAL;
+
+	dd = clk->dpll_data;
+
+	state <<= __ffs(dd->idlest_mask);
+
+	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
+	       i < MAX_DPLL_WAIT_TRIES) {
+		i++;
+		udelay(1);
+	}
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		printk(KERN_ERR "clock: %s failed transition to '%s'\n",
+		       clk->name, (state) ? "locked" : "bypassed");
+	} else {
+		pr_debug("clock: %s transition to '%s' in %d loops\n",
+			 clk->name, (state) ? "locked" : "bypassed", i);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* From 3430 TRM ES2 4.7.6.2 */
+static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
+{
+	unsigned long fint;
+	u16 f = 0;
+
+	fint = clk->dpll_data->clk_ref->rate / n;
+
+	pr_debug("clock: fint is %lu\n", fint);
+
+	if (fint >= 750000 && fint <= 1000000)
+		f = 0x3;
+	else if (fint > 1000000 && fint <= 1250000)
+		f = 0x4;
+	else if (fint > 1250000 && fint <= 1500000)
+		f = 0x5;
+	else if (fint > 1500000 && fint <= 1750000)
+		f = 0x6;
+	else if (fint > 1750000 && fint <= 2100000)
+		f = 0x7;
+	else if (fint > 7500000 && fint <= 10000000)
+		f = 0xB;
+	else if (fint > 10000000 && fint <= 12500000)
+		f = 0xC;
+	else if (fint > 12500000 && fint <= 15000000)
+		f = 0xD;
+	else if (fint > 15000000 && fint <= 17500000)
+		f = 0xE;
+	else if (fint > 17500000 && fint <= 21000000)
+		f = 0xF;
+	else
+		pr_debug("clock: unknown freqsel setting for %d\n", n);
+
+	return f;
+}
+
+/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
+
+/*
+ * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to lock.  Waits for the DPLL to report
+ * readiness before returning.  Will save and restore the DPLL's
+ * autoidle state across the enable, per the CDP code.  If the DPLL
+ * locked successfully, return 0; if the DPLL did not lock in the time
+ * allotted, or DPLL3 was passed in, return -EINVAL.
+ */
+static int _omap3_noncore_dpll_lock(struct clk *clk)
+{
+	u8 ai;
+	int r;
+
+	pr_debug("clock: locking DPLL %s\n", clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	omap3_dpll_deny_idle(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOCKED);
+
+	r = _omap3_wait_dpll_status(clk, 1);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+
+	return r;
+}
+
+/*
+ * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
+ * bypass mode, the DPLL's rate is set equal to its parent clock's
+ * rate.  Waits for the DPLL to report readiness before returning.
+ * Will save and restore the DPLL's autoidle state across the enable,
+ * per the CDP code.  If the DPLL entered bypass mode successfully,
+ * return 0; if the DPLL did not enter bypass in the time allotted, or
+ * DPLL3 was passed in, or the DPLL does not support low-power bypass,
+ * return -EINVAL.
+ */
+static int _omap3_noncore_dpll_bypass(struct clk *clk)
+{
+	int r;
+	u8 ai;
+
+	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
+		return -EINVAL;
+
+	pr_debug("clock: configuring DPLL %s for low-power bypass\n",
+		 clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
+
+	r = _omap3_wait_dpll_status(clk, 0);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+	else
+		omap3_dpll_deny_idle(clk);
+
+	return r;
+}
+
+/*
+ * _omap3_noncore_dpll_stop - instruct a DPLL to stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop. Will save and
+ * restore the DPLL's autoidle state across the stop, per the CDP
+ * code.  If DPLL3 was passed in, or the DPLL does not support
+ * low-power stop, return -EINVAL; otherwise, return 0.
+ */
+static int _omap3_noncore_dpll_stop(struct clk *clk)
+{
+	u8 ai;
+
+	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
+		return -EINVAL;
+
+	pr_debug("clock: stopping DPLL %s\n", clk->name);
+
+	ai = omap3_dpll_autoidle_read(clk);
+
+	_omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
+
+	if (ai)
+		omap3_dpll_allow_idle(clk);
+	else
+		omap3_dpll_deny_idle(clk);
+
+	return 0;
+}
+
+/**
+ * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
+ * The choice of modes depends on the DPLL's programmed rate: if it is
+ * the same as the DPLL's parent clock, it will enter bypass;
+ * otherwise, it will enter lock.  This code will wait for the DPLL to
+ * indicate readiness before returning, unless the DPLL takes too long
+ * to enter the target state.  Intended to be used as the struct clk's
+ * enable function.  If DPLL3 was passed in, or the DPLL does not
+ * support low-power stop, or if the DPLL took too long to enter
+ * bypass or lock, return -EINVAL; otherwise, return 0.
+ */
+int omap3_noncore_dpll_enable(struct clk *clk)
+{
+	int r;
+	struct dpll_data *dd;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return -EINVAL;
+
+	if (clk->rate == dd->clk_bypass->rate) {
+		WARN_ON(clk->parent != dd->clk_bypass);
+		r = _omap3_noncore_dpll_bypass(clk);
+	} else {
+		WARN_ON(clk->parent != dd->clk_ref);
+		r = _omap3_noncore_dpll_lock(clk);
+	}
+	/*
+	 *FIXME: this is dubious - if clk->rate has changed, what about
+	 * propagating?
+	 */
+	if (!r)
+		clk->rate = omap2_get_dpll_rate(clk);
+
+	return r;
+}
+
+/**
+ * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop.  This function is
+ * intended for use in struct clkops.  No return value.
+ */
+void omap3_noncore_dpll_disable(struct clk *clk)
+{
+	_omap3_noncore_dpll_stop(clk);
+}
+
+
+/* Non-CORE DPLL rate set code */
+
+/*
+ * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
+ * @clk: struct clk * of DPLL to set
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ * @freqsel: FREQSEL value to set
+ *
+ * Program the DPLL with the supplied M, N values, and wait for the DPLL to
+ * lock..  Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
+{
+	struct dpll_data *dd = clk->dpll_data;
+	u32 v;
+
+	/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
+	_omap3_noncore_dpll_bypass(clk);
+
+	/* Set jitter correction */
+	if (!cpu_is_omap44xx()) {
+		v = __raw_readl(dd->control_reg);
+		v &= ~dd->freqsel_mask;
+		v |= freqsel << __ffs(dd->freqsel_mask);
+		__raw_writel(v, dd->control_reg);
+	}
+
+	/* Set DPLL multiplier, divider */
+	v = __raw_readl(dd->mult_div1_reg);
+	v &= ~(dd->mult_mask | dd->div1_mask);
+	v |= m << __ffs(dd->mult_mask);
+	v |= (n - 1) << __ffs(dd->div1_mask);
+	__raw_writel(v, dd->mult_div1_reg);
+
+	/* We let the clock framework set the other output dividers later */
+
+	/* REVISIT: Set ramp-up delay? */
+
+	_omap3_noncore_dpll_lock(clk);
+
+	return 0;
+}
+
+/**
+ * omap3_noncore_dpll_set_rate - set non-core DPLL rate
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
+ * low-power bypass, and the target rate is the bypass source clock
+ * rate, then configure the DPLL for bypass.  Otherwise, round the
+ * target rate if it hasn't been done already, then program and lock
+ * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct clk *new_parent = NULL;
+	u16 freqsel = 0;
+	struct dpll_data *dd;
+	int ret;
+
+	if (!clk || !rate)
+		return -EINVAL;
+
+	dd = clk->dpll_data;
+	if (!dd)
+		return -EINVAL;
+
+	if (rate == omap2_get_dpll_rate(clk))
+		return 0;
+
+	/*
+	 * Ensure both the bypass and ref clocks are enabled prior to
+	 * doing anything; we need the bypass clock running to reprogram
+	 * the DPLL.
+	 */
+	omap2_clk_enable(dd->clk_bypass);
+	omap2_clk_enable(dd->clk_ref);
+
+	if (dd->clk_bypass->rate == rate &&
+	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
+
+		ret = _omap3_noncore_dpll_bypass(clk);
+		if (!ret)
+			new_parent = dd->clk_bypass;
+	} else {
+		if (dd->last_rounded_rate != rate)
+			omap2_dpll_round_rate(clk, rate);
+
+		if (dd->last_rounded_rate == 0)
+			return -EINVAL;
+
+		/* No freqsel on OMAP4 */
+		if (!cpu_is_omap44xx()) {
+			freqsel = _omap3_dpll_compute_freqsel(clk,
+						dd->last_rounded_n);
+			if (!freqsel)
+				WARN_ON(1);
+		}
+
+		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
+			 clk->name, rate);
+
+		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
+						 dd->last_rounded_n, freqsel);
+		if (!ret)
+			new_parent = dd->clk_ref;
+	}
+	if (!ret) {
+		/*
+		 * Switch the parent clock in the heirarchy, and make sure
+		 * that the new parent's usecount is correct.  Note: we
+		 * enable the new parent before disabling the old to avoid
+		 * any unnecessary hardware disable->enable transitions.
+		 */
+		if (clk->usecount) {
+			omap2_clk_enable(new_parent);
+			omap2_clk_disable(clk->parent);
+		}
+		clk_reparent(clk, new_parent);
+		clk->rate = rate;
+	}
+	omap2_clk_disable(dd->clk_ref);
+	omap2_clk_disable(dd->clk_bypass);
+
+	return 0;
+}
+
+/* DPLL autoidle read/set code */
+
+/**
+ * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
+ * @clk: struct clk * of the DPLL to read
+ *
+ * Return the DPLL's autoidle bits, shifted down to bit 0.  Returns
+ * -EINVAL if passed a null pointer or if the struct clk does not
+ * appear to refer to a DPLL.
+ */
+u32 omap3_dpll_autoidle_read(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return -EINVAL;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->autoidle_reg);
+	v &= dd->autoidle_mask;
+	v >>= __ffs(dd->autoidle_mask);
+
+	return v;
+}
+
+/**
+ * omap3_dpll_allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control.  This automatic idle mode
+ * switching takes effect only when the DPLL is locked, at least on
+ * OMAP3430.  The DPLL will enter low-power stop when its downstream
+ * clocks are gated.  No return value.
+ */
+void omap3_dpll_allow_idle(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return;
+
+	dd = clk->dpll_data;
+
+	/*
+	 * REVISIT: CORE DPLL can optionally enter low-power bypass
+	 * by writing 0x5 instead of 0x1.  Add some mechanism to
+	 * optionally enter this mode.
+	 */
+	v = __raw_readl(dd->autoidle_reg);
+	v &= ~dd->autoidle_mask;
+	v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+	__raw_writel(v, dd->autoidle_reg);
+}
+
+/**
+ * omap3_dpll_deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control.  No return value.
+ */
+void omap3_dpll_deny_idle(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	u32 v;
+
+	if (!clk || !clk->dpll_data)
+		return;
+
+	dd = clk->dpll_data;
+
+	v = __raw_readl(dd->autoidle_reg);
+	v &= ~dd->autoidle_mask;
+	v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+	__raw_writel(v, dd->autoidle_reg);
+
+}
+
+/* Clock control for DPLL outputs */
+
+/**
+ * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
+ * @clk: DPLL output struct clk
+ *
+ * Using parent clock DPLL data, look up DPLL state.  If locked, set our
+ * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
+ */
+unsigned long omap3_clkoutx2_recalc(struct clk *clk)
+{
+	const struct dpll_data *dd;
+	unsigned long rate;
+	u32 v;
+	struct clk *pclk;
+
+	/* Walk up the parents of clk, looking for a DPLL */
+	pclk = clk->parent;
+	while (pclk && !pclk->dpll_data)
+		pclk = pclk->parent;
+
+	/* clk does not have a DPLL as a parent? */
+	WARN_ON(!pclk);
+
+	dd = pclk->dpll_data;
+
+	WARN_ON(!dd->enable_mask);
+
+	v = __raw_readl(dd->control_reg) & dd->enable_mask;
+	v >>= __ffs(dd->enable_mask);
+	if (v != OMAP3XXX_EN_DPLL_LOCKED)
+		rate = clk->parent->rate;
+	else
+		rate = clk->parent->rate * 2;
+	return rate;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/emu.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/emu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/emu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/emu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,66 @@
+/*
+ * emu.c
+ *
+ * ETM and ETB CoreSight components' resources as found in OMAP3xxx.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This 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/types.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+/* Cortex CoreSight components within omap3xxx EMU */
+#define ETM_BASE	(L4_EMU_34XX_PHYS + 0x10000)
+#define DBG_BASE	(L4_EMU_34XX_PHYS + 0x11000)
+#define ETB_BASE	(L4_EMU_34XX_PHYS + 0x1b000)
+#define DAPCTL		(L4_EMU_34XX_PHYS + 0x1d000)
+
+static struct amba_device omap3_etb_device = {
+	.dev		= {
+		.init_name = "etb",
+	},
+	.res		= {
+		.start	= ETB_BASE,
+		.end	= ETB_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	.periphid	= 0x000bb907,
+};
+
+static struct amba_device omap3_etm_device = {
+	.dev		= {
+		.init_name = "etm",
+	},
+	.res		= {
+		.start	= ETM_BASE,
+		.end	= ETM_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	.periphid	= 0x102bb921,
+};
+
+static int __init emu_init(void)
+{
+	amba_device_register(&omap3_etb_device, &iomem_resource);
+	amba_device_register(&omap3_etm_device, &iomem_resource);
+
+	return 0;
+}
+
+subsys_initcall(emu_init);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,9 +24,9 @@
 #include <linux/module.h>
 
 #include <asm/mach-types.h>
-#include <mach/gpmc.h>
+#include <plat/gpmc.h>
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 
 /* GPMC register offsets */
 #define GPMC_REVISION		0x00
@@ -62,6 +62,33 @@
 #define ENABLE_PREFETCH		(0x1 << 7)
 #define DMA_MPU_MODE		2
 
+/* Structure to save gpmc cs context */
+struct gpmc_cs_config {
+	u32 config1;
+	u32 config2;
+	u32 config3;
+	u32 config4;
+	u32 config5;
+	u32 config6;
+	u32 config7;
+	int is_valid;
+};
+
+/*
+ * Structure to save/restore gpmc context
+ * to support core off on OMAP3
+ */
+struct omap3_gpmc_regs {
+	u32 sysconfig;
+	u32 irqenable;
+	u32 timeout_ctrl;
+	u32 config;
+	u32 prefetch_config1;
+	u32 prefetch_config2;
+	u32 prefetch_control;
+	struct gpmc_cs_config cs_context[GPMC_CS_NUM];
+};
+
 static struct resource	gpmc_mem_root;
 static struct resource	gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -261,7 +288,7 @@ static void gpmc_cs_enable_mem(int cs, u
 	l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
 	l &= ~(0x0f << 8);
 	l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
-	l |= 1 << 6;		/* CSVALID */
+	l |= GPMC_CONFIG7_CSVALID;
 	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
 }
 
@@ -270,7 +297,7 @@ static void gpmc_cs_disable_mem(int cs)
 	u32 l;
 
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
-	l &= ~(1 << 6);		/* CSVALID */
+	l &= ~GPMC_CONFIG7_CSVALID;
 	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
 }
 
@@ -290,7 +317,7 @@ static int gpmc_cs_mem_enabled(int cs)
 	u32 l;
 
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
-	return l & (1 << 6);
+	return l & GPMC_CONFIG7_CSVALID;
 }
 
 int gpmc_cs_set_reserved(int cs, int reserved)
@@ -478,7 +505,7 @@ static void __init gpmc_mem_init(void)
 void __init gpmc_init(void)
 {
 	u32 l;
-	char *ck;
+	char *ck = NULL;
 
 	if (cpu_is_omap24xx()) {
 		ck = "core_l3_ck";
@@ -490,10 +517,13 @@ void __init gpmc_init(void)
 		ck = "gpmc_fck";
 		l = OMAP34XX_GPMC_BASE;
 	} else if (cpu_is_omap44xx()) {
-		ck = "gpmc_fck";
+		ck = "gpmc_ck";
 		l = OMAP44XX_GPMC_BASE;
 	}
 
+	if (WARN_ON(!ck))
+		return;
+
 	gpmc_l3_clk = clk_get(NULL, ck);
 	if (IS_ERR(gpmc_l3_clk)) {
 		printk(KERN_ERR "Could not get GPMC clock %s\n", ck);
@@ -507,6 +537,8 @@ void __init gpmc_init(void)
 		BUG();
 	}
 
+	clk_enable(gpmc_l3_clk);
+
 	l = gpmc_read_reg(GPMC_REVISION);
 	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
 	/* Set smart idle mode and automatic L3 clock gating */
@@ -516,3 +548,68 @@ void __init gpmc_init(void)
 	gpmc_write_reg(GPMC_SYSCONFIG, l);
 	gpmc_mem_init();
 }
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap3_gpmc_regs gpmc_context;
+
+void omap3_gpmc_save_context()
+{
+	int i;
+	gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
+	gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
+	gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
+	gpmc_context.config = gpmc_read_reg(GPMC_CONFIG);
+	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++) {
+		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 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG1);
+			gpmc_context.cs_context[i].config2 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG2);
+			gpmc_context.cs_context[i].config3 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG3);
+			gpmc_context.cs_context[i].config4 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG4);
+			gpmc_context.cs_context[i].config5 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG5);
+			gpmc_context.cs_context[i].config6 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG6);
+			gpmc_context.cs_context[i].config7 =
+				gpmc_cs_read_reg(i, GPMC_CS_CONFIG7);
+		}
+	}
+}
+
+void omap3_gpmc_restore_context()
+{
+	int i;
+	gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
+	gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
+	gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
+	gpmc_write_reg(GPMC_CONFIG, gpmc_context.config);
+	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++) {
+		if (gpmc_context.cs_context[i].is_valid) {
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
+				gpmc_context.cs_context[i].config1);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG2,
+				gpmc_context.cs_context[i].config2);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG3,
+				gpmc_context.cs_context[i].config3);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG4,
+				gpmc_context.cs_context[i].config4);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG5,
+				gpmc_context.cs_context[i].config5);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG6,
+				gpmc_context.cs_context[i].config6);
+			gpmc_cs_write_reg(i, GPMC_CS_CONFIG7,
+				gpmc_context.cs_context[i].config7);
+		}
+	}
+}
+#endif /* CONFIG_ARCH_OMAP3 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc-onenand.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-onenand.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc-onenand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-onenand.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,9 @@
 
 #include <asm/mach/flash.h>
 
-#include <mach/onenand.h>
-#include <mach/board.h>
-#include <mach/gpmc.h>
+#include <plat/onenand.h>
+#include <plat/board.h>
+#include <plat/gpmc.h>
 
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc-smc91x.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-smc91x.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/gpmc-smc91x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/gpmc-smc91x.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,9 @@
 #include <linux/io.h>
 #include <linux/smc91x.h>
 
-#include <mach/board.h>
-#include <mach/gpmc.h>
-#include <mach/gpmc-smc91x.h>
+#include <plat/board.h>
+#include <plat/gpmc.h>
+#include <plat/gpmc-smc91x.h>
 
 static struct omap_smc91x_platform_data *gpmc_cfg;
 
@@ -33,17 +33,19 @@ static struct resource gpmc_smc91x_resou
 };
 
 static struct smc91x_platdata gpmc_smc91x_info = {
-	.flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
 };
 
 static struct platform_device gpmc_smc91x_device = {
 	.name		= "smc91x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(gpmc_smc91x_resources),
-	.resource	= gpmc_smc91x_resources,
 	.dev		= {
 		.platform_data = &gpmc_smc91x_info,
 	},
+	.num_resources	= ARRAY_SIZE(gpmc_smc91x_resources),
+	.resource	= gpmc_smc91x_resources,
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/i2c.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/i2c.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,56 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <plat/cpu.h>
+#include <plat/i2c.h>
+#include <plat/mux.h>
+
+#include "mux.h"
+
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+			  struct i2c_board_info const *info,
+			  unsigned len)
+{
+	if (cpu_is_omap24xx()) {
+		const int omap24xx_pins[][2] = {
+			{ M19_24XX_I2C1_SCL, L15_24XX_I2C1_SDA },
+			{ J15_24XX_I2C2_SCL, H19_24XX_I2C2_SDA },
+		};
+		int scl, sda;
+
+		scl = omap24xx_pins[bus_id - 1][0];
+		sda = omap24xx_pins[bus_id - 1][1];
+		omap_cfg_reg(sda);
+		omap_cfg_reg(scl);
+	}
+
+	/* First I2C bus is not muxable */
+	if (cpu_is_omap34xx() && bus_id > 1) {
+		char mux_name[sizeof("i2c2_scl.i2c2_scl")];
+
+		sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
+		omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
+		sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
+		omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
+	}
+
+	return omap_plat_register_i2c_bus(bus_id, clkrate, info, len);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/id.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/id.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/id.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/id.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,13 +21,14 @@
 
 #include <asm/cputype.h>
 
-#include <mach/common.h>
-#include <mach/control.h>
-#include <mach/cpu.h>
+#include <plat/common.h>
+#include <plat/control.h>
+#include <plat/cpu.h>
 
 static struct omap_chip_id omap_chip;
 static unsigned int omap_revision;
 
+u32 omap3_features;
 
 unsigned int omap_rev(void)
 {
@@ -52,11 +53,11 @@ int omap_type(void)
 {
 	u32 val = 0;
 
-	if (cpu_is_omap24xx())
+	if (cpu_is_omap24xx()) {
 		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
-	else if (cpu_is_omap34xx())
+	} else if (cpu_is_omap34xx()) {
 		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
-	else {
+	} else {
 		pr_err("Cannot detect omap type!\n");
 		goto out;
 	}
@@ -155,12 +156,39 @@ void __init omap24xx_check_revision(void
 	pr_info("\n");
 }
 
-void __init omap34xx_check_revision(void)
+#define OMAP3_CHECK_FEATURE(status,feat)				\
+	if (((status & OMAP3_ ##feat## _MASK) 				\
+		>> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { 	\
+		omap3_features |= OMAP3_HAS_ ##feat;			\
+	}
+
+void __init omap3_check_features(void)
+{
+	u32 status;
+
+	omap3_features = 0;
+
+	status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
+
+	OMAP3_CHECK_FEATURE(status, L2CACHE);
+	OMAP3_CHECK_FEATURE(status, IVA);
+	OMAP3_CHECK_FEATURE(status, SGX);
+	OMAP3_CHECK_FEATURE(status, NEON);
+	OMAP3_CHECK_FEATURE(status, ISP);
+
+	/*
+	 * TODO: Get additional info (where applicable)
+	 *       e.g. Size of L2 cache.
+	 */
+}
+
+void __init omap3_check_revision(void)
 {
 	u32 cpuid, idcode;
 	u16 hawkeye;
 	u8 rev;
-	char *rev_name = "ES1.0";
+
+	omap_chip.oc = CHIP_IS_OMAP3430;
 
 	/*
 	 * We cannot access revision registers on ES1.0.
@@ -170,7 +198,8 @@ void __init omap34xx_check_revision(void
 	cpuid = read_cpuid(CPUID_ID);
 	if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
 		omap_revision = OMAP3430_REV_ES1_0;
-		goto out;
+		omap_chip.oc |= CHIP_IS_OMAP3430ES1;
+		return;
 	}
 
 	/*
@@ -183,33 +212,154 @@ void __init omap34xx_check_revision(void
 	hawkeye = (idcode >> 12) & 0xffff;
 	rev = (idcode >> 28) & 0xff;
 
-	if (hawkeye == 0xb7ae) {
+	switch (hawkeye) {
+	case 0xb7ae:
+		/* Handle 34xx/35xx devices */
 		switch (rev) {
-		case 0:
+		case 0: /* Take care of early samples */
+		case 1:
 			omap_revision = OMAP3430_REV_ES2_0;
-			rev_name = "ES2.0";
+			omap_chip.oc |= CHIP_IS_OMAP3430ES2;
 			break;
 		case 2:
 			omap_revision = OMAP3430_REV_ES2_1;
-			rev_name = "ES2.1";
+			omap_chip.oc |= CHIP_IS_OMAP3430ES2;
 			break;
 		case 3:
 			omap_revision = OMAP3430_REV_ES3_0;
-			rev_name = "ES3.0";
+			omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
 			break;
 		case 4:
 			omap_revision = OMAP3430_REV_ES3_1;
-			rev_name = "ES3.1";
+			omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
 			break;
+		case 7:
+		/* FALLTHROUGH */
 		default:
 			/* Use the latest known revision as default */
-			omap_revision = OMAP3430_REV_ES3_1;
-			rev_name = "Unknown revision\n";
+			omap_revision = OMAP3430_REV_ES3_1_2;
+
+			/* REVISIT: Add CHIP_IS_OMAP3430ES3_1_2? */
+			omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
 		}
+		break;
+	case 0xb868:
+		/* Handle OMAP35xx/AM35xx devices
+		 *
+		 * Set the device to be OMAP3505 here. Actual device
+		 * is identified later based on the features.
+		 *
+		 * REVISIT: AM3505/AM3517 should have their own CHIP_IS
+		 */
+		omap_revision = OMAP3505_REV(rev);
+		omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+		break;
+	case 0xb891:
+	/* FALLTHROUGH */
+	default:
+		/* Unknown default to latest silicon rev as default*/
+		omap_revision = OMAP3630_REV_ES1_0;
+		omap_chip.oc |= CHIP_IS_OMAP3630ES1;
 	}
+}
 
-out:
-	pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
+void __init omap4_check_revision(void)
+{
+	u32 idcode;
+	u16 hawkeye;
+	u8 rev;
+	char *rev_name = "ES1.0";
+
+	/*
+	 * The IC rev detection is done with hawkeye and rev.
+	 * Note that rev does not map directly to defined processor
+	 * revision numbers as ES1.0 uses value 0.
+	 */
+	idcode = read_tap_reg(OMAP_TAP_IDCODE);
+	hawkeye = (idcode >> 12) & 0xffff;
+	rev = (idcode >> 28) & 0xff;
+
+	if ((hawkeye == 0xb852) && (rev == 0x0)) {
+		omap_revision = OMAP4430_REV_ES1_0;
+		pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
+		return;
+	}
+
+	pr_err("Unknown OMAP4 CPU id\n");
+}
+
+#define OMAP3_SHOW_FEATURE(feat)		\
+	if (omap3_has_ ##feat())		\
+		printk(#feat" ");
+
+void __init omap3_cpuinfo(void)
+{
+	u8 rev = GET_OMAP_REVISION();
+	char cpu_name[16], cpu_rev[16];
+
+	/* OMAP3430 and OMAP3530 are assumed to be same.
+	 *
+	 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
+	 * on available features. Upon detection, update the CPU id
+	 * and CPU class bits.
+	 */
+	if (cpu_is_omap3630()) {
+		strcpy(cpu_name, "OMAP3630");
+	} else if (cpu_is_omap3505()) {
+		/*
+		 * AM35xx devices
+		 */
+		if (omap3_has_sgx()) {
+			omap_revision = OMAP3517_REV(rev);
+			strcpy(cpu_name, "AM3517");
+		} else {
+			/* Already set in omap3_check_revision() */
+			strcpy(cpu_name, "AM3505");
+		}
+	} else if (omap3_has_iva() && omap3_has_sgx()) {
+		/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
+		strcpy(cpu_name, "OMAP3430/3530");
+	} else if (omap3_has_iva()) {
+		omap_revision = OMAP3525_REV(rev);
+		strcpy(cpu_name, "OMAP3525");
+	} else if (omap3_has_sgx()) {
+		omap_revision = OMAP3515_REV(rev);
+		strcpy(cpu_name, "OMAP3515");
+	} else {
+		omap_revision = OMAP3503_REV(rev);
+		strcpy(cpu_name, "OMAP3503");
+	}
+
+	switch (rev) {
+	case OMAP_REVBITS_00:
+		strcpy(cpu_rev, "1.0");
+		break;
+	case OMAP_REVBITS_10:
+		strcpy(cpu_rev, "2.0");
+		break;
+	case OMAP_REVBITS_20:
+		strcpy(cpu_rev, "2.1");
+		break;
+	case OMAP_REVBITS_30:
+		strcpy(cpu_rev, "3.0");
+		break;
+	case OMAP_REVBITS_40:
+	/* FALLTHROUGH */
+	default:
+		/* Use the latest known revision as default */
+		strcpy(cpu_rev, "3.1");
+	}
+
+	/* Print verbose information */
+	pr_info("%s ES%s (", cpu_name, cpu_rev);
+
+	OMAP3_SHOW_FEATURE(l2cache);
+	OMAP3_SHOW_FEATURE(iva);
+	OMAP3_SHOW_FEATURE(sgx);
+	OMAP3_SHOW_FEATURE(neon);
+	OMAP3_SHOW_FEATURE(isp);
+
+	printk(")\n");
 }
 
 /*
@@ -221,15 +371,19 @@ void __init omap2_check_revision(void)
 	 * At this point we have an idea about the processor revision set
 	 * earlier with omap2_set_globals_tap().
 	 */
-	if (cpu_is_omap24xx())
+	if (cpu_is_omap24xx()) {
 		omap24xx_check_revision();
-	else if (cpu_is_omap34xx())
-		omap34xx_check_revision();
-	else if (cpu_is_omap44xx()) {
-		printk(KERN_INFO "FIXME: CPU revision = OMAP4430\n");
+	} else if (cpu_is_omap34xx()) {
+		omap3_check_revision();
+		omap3_check_features();
+		omap3_cpuinfo();
 		return;
-	} else
+	} else if (cpu_is_omap44xx()) {
+		omap4_check_revision();
+		return;
+	} else {
 		pr_err("OMAP revision unknown, please fix!\n");
+	}
 
 	/*
 	 * OK, now we know the exact revision. Initialize omap_chip bits
@@ -238,23 +392,14 @@ void __init omap2_check_revision(void)
 	if (cpu_is_omap243x()) {
 		/* Currently only supports 2430ES2.1 and 2430-all */
 		omap_chip.oc |= CHIP_IS_OMAP2430;
+		return;
 	} else if (cpu_is_omap242x()) {
 		/* Currently only supports 2420ES2.1.1 and 2420-all */
 		omap_chip.oc |= CHIP_IS_OMAP2420;
-	} else if (cpu_is_omap343x()) {
-		omap_chip.oc = CHIP_IS_OMAP3430;
-		if (omap_rev() == OMAP3430_REV_ES1_0)
-			omap_chip.oc |= CHIP_IS_OMAP3430ES1;
-		else if (omap_rev() >= OMAP3430_REV_ES2_0 &&
-			 omap_rev() <= OMAP3430_REV_ES2_1)
-			omap_chip.oc |= CHIP_IS_OMAP3430ES2;
-		else if (omap_rev() == OMAP3430_REV_ES3_0)
-			omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
-		else if (omap_rev() == OMAP3430_REV_ES3_1)
-			omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
-	} else {
-		pr_err("Uninitialized omap_chip, please fix!\n");
+		return;
 	}
+
+	pr_err("Uninitialized omap_chip, please fix!\n");
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/board-zoom.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/board-zoom.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/board-zoom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/board-zoom.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * Defines for zoom boards
+ */
+extern int __init zoom_debugboard_init(void);
+extern void __init zoom_peripherals_init(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/clkdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/clkdev.h
+ */
+
+#include <plat/clkdev.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,59 @@
+/* arch/arm/mach-omap2/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This 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.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+#ifdef  CONFIG_ARCH_OMAP2
+		moveq	\rx, #0x48000000	@ physical base address
+		movne	\rx, #0xfa000000	@ virtual base
+		orr	\rx, \rx, #0x0006a000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
+		add	\rx, \rx, #0x00002000	@ UART 2
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+		add	\rx, \rx, #0x00004000	@ UART 3
+#endif
+
+#elif defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+		moveq	\rx, #0x48000000	@ physical base address
+		movne	\rx, #0xfa000000	@ virtual base
+		orr	\rx, \rx, #0x0006a000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
+		add	\rx, \rx, #0x00002000	@ UART 2
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+		add	\rx, \rx, #0x00fb0000	@ UART 3
+		add	\rx, \rx, #0x00006000
+#endif
+#endif
+		.endm
+
+		.macro	senduart,rd,rx
+		strb	\rd, [\rx]
+		.endm
+
+		.macro	busyuart,rd,rx
+1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		beq	1002f
+		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
+		and	\rd, \rd, #0x60
+		teq	\rd, #0x60
+		bne	1001b
+1002:
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,124 @@
+/*
+ * arch/arm/plat-omap/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for OMAP-based platforms
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@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 <mach/hardware.h>
+#include <mach/io.h>
+#include <mach/irqs.h>
+#include <asm/hardware/gic.h>
+
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+
+/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
+#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
+#define OMAP2_VA_IC_BASE		OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
+#elif defined(CONFIG_ARCH_OMAP34XX)
+#define OMAP2_VA_IC_BASE		OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+#include <plat/omap44xx.h>
+#endif
+#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
+#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+#ifndef CONFIG_ARCH_OMAP4
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =OMAP2_VA_IC_BASE
+		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
+		cmp	\irqnr, #0x0
+		bne	2222f
+		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
+		cmp	\irqnr, #0x0
+		bne	2222f
+		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
+		cmp	\irqnr, #0x0
+2222:
+		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
+
+		.endm
+#else
+#define OMAP44XX_VA_GIC_CPU_BASE	OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
+
+		/*
+		 * The interrupt numbering scheme is defined in the
+		 * interrupt controller spec.  To wit:
+		 *
+		 * Interrupts 0-15 are IPI
+		 * 16-28 are reserved
+		 * 29-31 are local.  We allow 30 to be used for the watchdog.
+		 * 32-1020 are global
+		 * 1021-1022 are reserved
+		 * 1023 is "spurious" (no interrupt)
+		 *
+		 * For now, we ignore all local interrupts so only return an
+		 * interrupt if it's between 30 and 1020.  The test_for_ipi
+		 * routine below will pick up on IPIs.
+		 * A simple read from the controller will tell us the number
+		 * of the highest priority enabled interrupt.
+		 * We then just need to check whether it is in the
+		 * valid range for an IRQ (30-1020 inclusive).
+		 */
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr     \base, =OMAP44XX_VA_GIC_CPU_BASE
+		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
+
+		ldr     \tmp, =1021
+
+		bic     \irqnr, \irqstat, #0x1c00
+
+		cmp     \irqnr, #29
+		cmpcc   \irqnr, \irqnr
+		cmpne   \irqnr, \tmp
+		cmpcs   \irqnr, \irqnr
+		.endm
+
+		/* We assume that irqstat (the raw value of the IRQ acknowledge
+		 * register) is preserved from the macro above.
+		 * If there is an IPI, we immediately signal end of interrupt
+		 * on the controller, since this requires the original irqstat
+		 * value which we won't easily be able to recreate later.
+		 */
+
+		.macro test_for_ipi, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		cmp	\irqnr, #16
+		it	cc
+		strcc	\irqstat, [\base, #GIC_CPU_EOI]
+		it	cs
+		cmpcs	\irqnr, \irqnr
+		.endm
+
+		/* As above, this assumes that irqstat and base are preserved */
+
+		.macro test_for_ltirq, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		mov 	\tmp, #0
+		cmp	\irqnr, #29
+		itt	eq
+		moveq	\tmp, #1
+		streq	\irqstat, [\base, #GIC_CPU_EOI]
+		cmp	\tmp, #0
+		.endm
+#endif
+
+		.macro	irq_prio_table
+		.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/gpio.h
+ */
+
+#include <plat/gpio.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/hardware.h
+ */
+
+#include <plat/hardware.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/io.h
+ */
+
+#include <plat/io.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/irqs.h
+ */
+
+#include <plat/irqs.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/memory.h
+ */
+
+#include <plat/memory.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/smp.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/smp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/smp.h
+ */
+
+#include <plat/smp.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/system.h
+ */
+
+#include <plat/system.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/timex.h
+ */
+
+#include <plat/timex.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/uncompress.h
+ */
+
+#include <plat/uncompress.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/vmalloc.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/vmalloc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+/*
+ *  arch/arm/plat-omap/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * 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 VMALLOC_END	  (PAGE_OFFSET + 0x38000000)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/io.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/io.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/io.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,29 +22,28 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/omapfb.h>
 
 #include <asm/tlb.h>
 
 #include <asm/mach/map.h>
 
-#include <mach/mux.h>
-#include <mach/omapfb.h>
-#include <mach/sram.h>
-#include <mach/sdrc.h>
-#include <mach/gpmc.h>
-#include <mach/serial.h>
+#include <plat/mux.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+#include <plat/gpmc.h>
+#include <plat/serial.h>
+#include <plat/vram.h>
 
-#ifndef CONFIG_ARCH_OMAP4	/* FIXME: Remove this once clkdev is ready */
 #include "clock.h"
 
-#include <mach/omap-pm.h>
-#include <mach/powerdomain.h>
+#include <plat/omap-pm.h>
+#include <plat/powerdomain.h>
 #include "powerdomains.h"
 
-#include <mach/clockdomain.h>
+#include <plat/clockdomain.h>
 #include "clockdomains.h"
-#endif
-#include <mach/omap_hwmod.h>
+#include <plat/omap_hwmod.h>
 #include "omap_hwmod_2420.h"
 #include "omap_hwmod_2430.h"
 #include "omap_hwmod_34xx.h"
@@ -73,21 +72,21 @@ static struct map_desc omap24xx_io_desc[
 #ifdef CONFIG_ARCH_OMAP2420
 static struct map_desc omap242x_io_desc[] __initdata = {
 	{
-		.virtual	= DSP_MEM_24XX_VIRT,
-		.pfn		= __phys_to_pfn(DSP_MEM_24XX_PHYS),
-		.length		= DSP_MEM_24XX_SIZE,
+		.virtual	= DSP_MEM_2420_VIRT,
+		.pfn		= __phys_to_pfn(DSP_MEM_2420_PHYS),
+		.length		= DSP_MEM_2420_SIZE,
 		.type		= MT_DEVICE
 	},
 	{
-		.virtual	= DSP_IPI_24XX_VIRT,
-		.pfn		= __phys_to_pfn(DSP_IPI_24XX_PHYS),
-		.length		= DSP_IPI_24XX_SIZE,
+		.virtual	= DSP_IPI_2420_VIRT,
+		.pfn		= __phys_to_pfn(DSP_IPI_2420_PHYS),
+		.length		= DSP_IPI_2420_SIZE,
 		.type		= MT_DEVICE
 	},
 	{
-		.virtual	= DSP_MMU_24XX_VIRT,
-		.pfn		= __phys_to_pfn(DSP_MMU_24XX_PHYS),
-		.length		= DSP_MMU_24XX_SIZE,
+		.virtual	= DSP_MMU_2420_VIRT,
+		.pfn		= __phys_to_pfn(DSP_MMU_2420_PHYS),
+		.length		= DSP_MMU_2420_SIZE,
 		.type		= MT_DEVICE
 	},
 };
@@ -203,6 +202,24 @@ static struct map_desc omap44xx_io_desc[
 		.type		= MT_DEVICE,
 	},
 	{
+		.virtual	= OMAP44XX_EMIF1_VIRT,
+		.pfn		= __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
+		.length		= OMAP44XX_EMIF1_SIZE,
+		.type		= MT_DEVICE,
+	},
+	{
+		.virtual	= OMAP44XX_EMIF2_VIRT,
+		.pfn		= __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
+		.length		= OMAP44XX_EMIF2_SIZE,
+		.type		= MT_DEVICE,
+	},
+	{
+		.virtual	= OMAP44XX_DMM_VIRT,
+		.pfn		= __phys_to_pfn(OMAP44XX_DMM_PHYS),
+		.length		= OMAP44XX_DMM_SIZE,
+		.type		= MT_DEVICE,
+	},
+	{
 		.virtual	= L4_PER_44XX_VIRT,
 		.pfn		= __phys_to_pfn(L4_PER_44XX_PHYS),
 		.length		= L4_PER_44XX_SIZE,
@@ -246,6 +263,7 @@ void __init omap2_map_common_io(void)
 	omap2_check_revision();
 	omap_sram_init();
 	omapfb_reserve_sdram();
+	omap_vram_reserve_sdram();
 }
 
 /*
@@ -301,8 +319,8 @@ void __init omap2_init_common_hw(struct
 	omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
 	pwrdm_init(powerdomains_omap);
 	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
-	omap2_clk_init();
 #endif
+	omap2_clk_init();
 	omap_serial_early_init();
 #ifndef CONFIG_ARCH_OMAP4
 	omap_hwmod_late_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/iommu2.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/iommu2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/iommu2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/iommu2.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,7 @@
 #include <linux/module.h>
 #include <linux/stringify.h>
 
-#include <mach/iommu.h>
+#include <plat/iommu.h>
 
 /*
  * omap2 architecture specific register bit definitions
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,10 @@
 #define INTC_SYSSTATUS		0x0014
 #define INTC_SIR		0x0040
 #define INTC_CONTROL		0x0048
+#define INTC_PROTECTION		0x004C
+#define INTC_IDLE		0x0050
+#define INTC_THRESHOLD		0x0068
+#define INTC_MIR0		0x0084
 #define INTC_MIR_CLEAR0		0x0088
 #define INTC_MIR_SET0		0x008c
 #define INTC_PENDING_IRQ0	0x0098
@@ -48,6 +52,18 @@ static struct omap_irq_bank {
 	},
 };
 
+/* Structure to save interrupt controller context */
+struct omap3_intc_regs {
+	u32 sysconfig;
+	u32 protection;
+	u32 idle;
+	u32 threshold;
+	u32 ilr[INTCPS_NR_IRQS];
+	u32 mir[INTCPS_NR_MIR_REGS];
+};
+
+static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
+
 /* INTC bank register get/set */
 
 static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
@@ -178,12 +194,22 @@ void __init omap_init_irq(void)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
+		unsigned long base = 0;
 		struct omap_irq_bank *bank = irq_banks + i;
 
 		if (cpu_is_omap24xx())
-			bank->base_reg = OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE);
+			base = OMAP24XX_IC_BASE;
 		else if (cpu_is_omap34xx())
-			bank->base_reg = OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE);
+			base = OMAP34XX_IC_BASE;
+
+		BUG_ON(!base);
+
+		/* Static mapping, never released */
+		bank->base_reg = ioremap(base, SZ_4K);
+		if (!bank->base_reg) {
+			printk(KERN_ERR "Could not ioremap irq bank%i\n", i);
+			continue;
+		}
 
 		omap_irq_bank_init_one(bank);
 
@@ -201,3 +227,71 @@ void __init omap_init_irq(void)
 	}
 }
 
+#ifdef CONFIG_ARCH_OMAP3
+void omap_intc_save_context(void)
+{
+	int ind = 0, i = 0;
+	for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
+		struct omap_irq_bank *bank = irq_banks + ind;
+		intc_context[ind].sysconfig =
+			intc_bank_read_reg(bank, INTC_SYSCONFIG);
+		intc_context[ind].protection =
+			intc_bank_read_reg(bank, INTC_PROTECTION);
+		intc_context[ind].idle =
+			intc_bank_read_reg(bank, INTC_IDLE);
+		intc_context[ind].threshold =
+			intc_bank_read_reg(bank, INTC_THRESHOLD);
+		for (i = 0; i < INTCPS_NR_IRQS; i++)
+			intc_context[ind].ilr[i] =
+				intc_bank_read_reg(bank, (0x100 + 0x4*i));
+		for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
+			intc_context[ind].mir[i] =
+				intc_bank_read_reg(&irq_banks[0], INTC_MIR0 +
+				(0x20 * i));
+	}
+}
+
+void omap_intc_restore_context(void)
+{
+	int ind = 0, i = 0;
+
+	for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
+		struct omap_irq_bank *bank = irq_banks + ind;
+		intc_bank_write_reg(intc_context[ind].sysconfig,
+					bank, INTC_SYSCONFIG);
+		intc_bank_write_reg(intc_context[ind].sysconfig,
+					bank, INTC_SYSCONFIG);
+		intc_bank_write_reg(intc_context[ind].protection,
+					bank, INTC_PROTECTION);
+		intc_bank_write_reg(intc_context[ind].idle,
+					bank, INTC_IDLE);
+		intc_bank_write_reg(intc_context[ind].threshold,
+					bank, INTC_THRESHOLD);
+		for (i = 0; i < INTCPS_NR_IRQS; i++)
+			intc_bank_write_reg(intc_context[ind].ilr[i],
+				bank, (0x100 + 0x4*i));
+		for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
+			intc_bank_write_reg(intc_context[ind].mir[i],
+				 &irq_banks[0], INTC_MIR0 + (0x20 * i));
+	}
+	/* MIRs are saved and restore with other PRCM registers */
+}
+
+void omap3_intc_suspend(void)
+{
+	/* A pending interrupt would prevent OMAP from entering suspend */
+	omap_ack_irq(0);
+}
+
+void omap3_intc_prepare_idle(void)
+{
+	/* Disable autoidle as it can stall interrupt controller */
+	intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
+}
+
+void omap3_intc_resume_idle(void)
+{
+	/* Re-enable autoidle */
+	intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
+}
+#endif /* CONFIG_ARCH_OMAP3 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -18,12 +18,25 @@ config ARCH_OMAP2430
 config ARCH_OMAP34XX
 	bool "OMAP34xx Based System"
 	depends on ARCH_OMAP3
+	select USB_ARCH_HAS_EHCI
 
 config ARCH_OMAP3430
 	bool "OMAP3430 support"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
 	select ARCH_OMAP_OTG
 
+config OMAP_PACKAGE_CBC
+       bool
+
+config OMAP_PACKAGE_CBB
+       bool
+
+config OMAP_PACKAGE_CUS
+       bool
+
+config OMAP_PACKAGE_CBP
+       bool
+
 comment "OMAP Board Type"
 	depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4
 
@@ -52,26 +65,42 @@ config MACH_OMAP_2430SDP
 config MACH_OMAP3_BEAGLE
 	bool "OMAP3 BEAGLE board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP_LDP
 	bool "OMAP3 LDP board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_OVERO
 	bool "Gumstix Overo board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3EVM
 	bool "OMAP 3530 EVM board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3517EVM
+	bool "OMAP3517/ AM3517 EVM board"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP3_PANDORA
 	bool "OMAP3 Pandora"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3_TOUCHBOOK
+	bool "OMAP3 Touch Book"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select BACKLIGHT_CLASS_DEVICE
 
 config MACH_OMAP_3430SDP
 	bool "OMAP 3430 SDP board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_NOKIA_N800
        bool
@@ -92,11 +121,54 @@ config MACH_NOKIA_N8X0
 config MACH_NOKIA_RX51
 	bool "Nokia RX-51 board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
 
 config MACH_OMAP_ZOOM2
 	bool "OMAP3 Zoom2 board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
+
+config MACH_OMAP_ZOOM3
+	bool "OMAP3630 Zoom3 board"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBP
+
+config MACH_CM_T35
+	bool "CompuLab CM-T35 module"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CUS
+	select OMAP_MUX
+
+config MACH_IGEP0020
+	bool "IGEP0020"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBB
+
+config MACH_OMAP_3630SDP
+	bool "OMAP3630 SDP board"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	select OMAP_PACKAGE_CBP
 
 config MACH_OMAP_4430SDP
 	bool "OMAP 4430 SDP board"
 	depends on ARCH_OMAP4
+
+config OMAP3_EMU
+	bool "OMAP3 debugging peripherals"
+	depends on ARCH_OMAP3
+	select OC_ETM
+	help
+	  Say Y here to enable debugging hardware of omap3
+
+config OMAP3_SDRC_AC_TIMING
+	bool "Enable SDRC AC timing register changes"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+	default n
+	help
+	  If you know that none of your system initiators will attempt to
+	  access SDRAM during CORE DVFS, select Y here.  This should boost
+	  SDRAM performance at lower CORE OPPs.  There are relatively few
+	  users who will wish to say yes at this point - almost everyone will
+	  wish to say no.  Selecting yes without understanding what is
+	  going on could result in system crashes;
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mailbox.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mailbox.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mailbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mailbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,11 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <mach/mailbox.h>
+#include <plat/mailbox.h>
 #include <mach/irqs.h>
 
+#define DRV_NAME "omap2-mailbox"
+
 #define MAILBOX_REVISION		0x000
 #define MAILBOX_SYSCONFIG		0x010
 #define MAILBOX_SYSSTATUS		0x014
@@ -27,8 +29,12 @@
 #define MAILBOX_IRQSTATUS(u)		(0x100 + 8 * (u))
 #define MAILBOX_IRQENABLE(u)		(0x104 + 8 * (u))
 
-#define MAILBOX_IRQ_NEWMSG(u)		(1 << (2 * (u)))
-#define MAILBOX_IRQ_NOTFULL(u)		(1 << (2 * (u) + 1))
+#define OMAP4_MAILBOX_IRQSTATUS(u)	(0x104 + 10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE(u)	(0x108 + 10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE_CLR(u)	(0x10c + 10 * (u))
+
+#define MAILBOX_IRQ_NEWMSG(m)		(1 << (2 * (m)))
+#define MAILBOX_IRQ_NOTFULL(m)		(1 << (2 * (m) + 1))
 
 /* SYSCONFIG: register bit definition */
 #define AUTOIDLE	(1 << 0)
@@ -39,7 +45,11 @@
 #define RESETDONE	(1 << 0)
 
 #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;
 
@@ -56,7 +66,8 @@ struct omap_mbox2_priv {
 	unsigned long irqstatus;
 	u32 newmsg_bit;
 	u32 notfull_bit;
-	u32 ctx[MBOX_NR_REGS];
+	u32 ctx[OMAP4_MBOX_NR_REGS];
+	unsigned long irqdisable;
 };
 
 static struct clk *mbox_ick_handle;
@@ -82,8 +93,9 @@ static int omap2_mbox_startup(struct oma
 
 	mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
 	if (IS_ERR(mbox_ick_handle)) {
-		pr_err("Can't get mailboxes_ick\n");
-		return -ENODEV;
+		printk(KERN_ERR "Could not get mailboxes_ick: %d\n",
+			PTR_ERR(mbox_ick_handle));
+		return PTR_ERR(mbox_ick_handle);
 	}
 	clk_enable(mbox_ick_handle);
 
@@ -115,6 +127,7 @@ static void omap2_mbox_shutdown(struct o
 {
 	clk_disable(mbox_ick_handle);
 	clk_put(mbox_ick_handle);
+	mbox_ick_handle = NULL;
 }
 
 /* Mailbox FIFO handle functions */
@@ -143,7 +156,7 @@ static int omap2_mbox_fifo_full(struct o
 {
 	struct omap_mbox2_fifo *fifo =
 		&((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
-	return (mbox_read_reg(fifo->fifo_stat));
+	return mbox_read_reg(fifo->fifo_stat);
 }
 
 /* Mailbox IRQ handle functions */
@@ -163,10 +176,9 @@ static void omap2_mbox_disable_irq(struc
 {
 	struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
 	u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
-
-	l = mbox_read_reg(p->irqenable);
+	l = mbox_read_reg(p->irqdisable);
 	l &= ~bit;
-	mbox_write_reg(l, p->irqenable);
+	mbox_write_reg(l, p->irqdisable);
 }
 
 static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
@@ -189,15 +201,19 @@ static int omap2_mbox_is_irq(struct omap
 	u32 enable = mbox_read_reg(p->irqenable);
 	u32 status = mbox_read_reg(p->irqstatus);
 
-	return (enable & status & bit);
+	return (int)(enable & status & bit);
 }
 
 static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
 {
 	int i;
 	struct omap_mbox2_priv *p = mbox->priv;
-
-	for (i = 0; i < MBOX_NR_REGS; i++) {
+	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__,
@@ -209,8 +225,12 @@ static void omap2_mbox_restore_ctx(struc
 {
 	int i;
 	struct omap_mbox2_priv *p = mbox->priv;
-
-	for (i = 0; i < MBOX_NR_REGS; i++) {
+	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__,
@@ -242,7 +262,6 @@ static struct omap_mbox_ops omap2_mbox_o
  */
 
 /* FIXME: the following structs should be filled automatically by the user id */
-
 /* DSP */
 static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
 	.tx_fifo = {
@@ -257,8 +276,36 @@ static struct omap_mbox2_priv omap2_mbox
 	.irqstatus	= MAILBOX_IRQSTATUS(0),
 	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
 	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(1),
+	.irqdisable	= MAILBOX_IRQENABLE(0),
+};
+
+
+
+/* OMAP4 specific data structure. Use the cpu_is_omap4xxx()
+to use this*/
+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,
+};
+EXPORT_SYMBOL(mbox_1_info);
+
 struct omap_mbox mbox_dsp_info = {
 	.name	= "dsp",
 	.ops	= &omap2_mbox_ops,
@@ -266,6 +313,30 @@ struct omap_mbox mbox_dsp_info = {
 };
 EXPORT_SYMBOL(mbox_dsp_info);
 
+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,
+};
+EXPORT_SYMBOL(mbox_2_info);
+
+
 #if defined(CONFIG_ARCH_OMAP2420) /* IVA */
 static struct omap_mbox2_priv omap2_mbox_iva_priv = {
 	.tx_fifo = {
@@ -280,6 +351,7 @@ static struct omap_mbox2_priv omap2_mbox
 	.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 = {
@@ -305,17 +377,31 @@ static int __devinit omap2_mbox_probe(st
 		return -ENOMEM;
 
 	/* DSP or IVA2 IRQ */
-	ret = platform_get_irq(pdev, 0);
-	if (ret < 0) {
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+	if (unlikely(!res)) {
 		dev_err(&pdev->dev, "invalid irq resource\n");
+		ret = -ENODEV;
 		goto err_dsp;
 	}
-	mbox_dsp_info.irq = ret;
-
-	ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
+	if (cpu_is_omap44xx()) {
+		mbox_1_info.irq = res->start;
+		ret = omap_mbox_register(&pdev->dev, &mbox_1_info);
+	} else {
+		mbox_dsp_info.irq = res->start;
+		ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
+	}
 	if (ret)
 		goto err_dsp;
 
+	if (cpu_is_omap44xx()) {
+		mbox_2_info.irq = res->start;
+		ret = omap_mbox_register(&pdev->dev, &mbox_2_info);
+		if (ret) {
+			omap_mbox_unregister(&mbox_1_info);
+			goto err_dsp;
+		}
+	}
 #if defined(CONFIG_ARCH_OMAP2420) /* IVA */
 	if (cpu_is_omap2420()) {
 		/* IVA IRQ */
@@ -335,6 +421,7 @@ static int __devinit omap2_mbox_probe(st
 
 err_iva1:
 	omap_mbox_unregister(&mbox_dsp_info);
+
 err_dsp:
 	iounmap(mbox_base);
 	return ret;
@@ -345,7 +432,12 @@ static int __devexit omap2_mbox_remove(s
 #if defined(CONFIG_ARCH_OMAP2420)
 	omap_mbox_unregister(&mbox_iva_info);
 #endif
-	omap_mbox_unregister(&mbox_dsp_info);
+
+	if (cpu_is_omap44xx()) {
+		omap_mbox_unregister(&mbox_2_info);
+		omap_mbox_unregister(&mbox_1_info);
+	} else
+		omap_mbox_unregister(&mbox_dsp_info);
 	iounmap(mbox_base);
 	return 0;
 }
@@ -354,7 +446,7 @@ static struct platform_driver omap2_mbox
 	.probe = omap2_mbox_probe,
 	.remove = __devexit_p(omap2_mbox_remove),
 	.driver = {
-		.name = "omap2-mailbox",
+		.name = DRV_NAME,
 	},
 };
 
@@ -372,6 +464,6 @@ module_init(omap2_mbox_init);
 module_exit(omap2_mbox_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("omap mailbox: omap2/3 architecture specific functions");
+MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
 MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, Paul Mundt");
-MODULE_ALIAS("platform:omap2-mailbox");
+MODULE_ALIAS("platform:"DRV_NAME);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,11 +6,14 @@
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
 
 omap-2-3-common				= irq.o sdrc.o omap_hwmod.o
+omap-3-4-common				= dpll.o
 prcm-common				= prcm.o powerdomain.o
-clock-common				= clock.o clockdomain.o
+clock-common				= clock.o clock_common_data.o clockdomain.o
 
 obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
-obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
+			    $(omap-3-4-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) prcm.o clock.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
@@ -23,6 +26,9 @@ obj-$(CONFIG_ARCH_OMAP2420)		+= sram242x
 obj-$(CONFIG_ARCH_OMAP2430)		+= sram243x.o
 obj-$(CONFIG_ARCH_OMAP3)		+= sram34xx.o
 
+# Pin multiplexing
+obj-$(CONFIG_ARCH_OMAP3)		+= mux34xx.o
+
 # SMS/SDRC
 obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 # obj-$(CONFIG_ARCH_OMAP3)		+= sdrc3xxx.o
@@ -31,7 +37,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP24XX)		+= sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 endif
 
@@ -41,14 +47,26 @@ obj-$(CONFIG_ARCH_OMAP3)		+= cm.o
 obj-$(CONFIG_ARCH_OMAP4)		+= cm4xxx.o
 
 # Clock framework
-obj-$(CONFIG_ARCH_OMAP2)		+= clock24xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o
+obj-$(CONFIG_ARCH_OMAP2)		+= clock2xxx.o clock2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP2420)		+= opp2420_data.o
+obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clock34xx_data.o
+obj-$(CONFIG_ARCH_OMAP2430)		+= opp2430_data.o
+obj-$(CONFIG_ARCH_OMAP4)		+= clock44xx.o clock44xx_data.o
+
+# EMU peripherals
+obj-$(CONFIG_OMAP3_EMU)		+= emu.o
+
+obj-$(CONFIG_OMAP_MBOX_FWK)		+= mailbox_mach.o
+mailbox_mach-objs			:= mailbox.o
 
 iommu-y					+= iommu2.o
 iommu-$(CONFIG_ARCH_OMAP3)		+= omap3-iommu.o
 
 obj-$(CONFIG_OMAP_IOMMU)		+= $(iommu-y)
 
+i2c-omap-$(CONFIG_I2C_OMAP)		:= i2c.o
+obj-y					+= $(i2c-omap-m) $(i2c-omap-y)
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
@@ -69,17 +87,34 @@ obj-$(CONFIG_MACH_OMAP_3430SDP)		+= boar
 					   mmc-twl4030.o
 obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
+					   board-rx51-sdram.o \
 					   board-rx51-peripherals.o \
 					   mmc-twl4030.o
 obj-$(CONFIG_MACH_OMAP_ZOOM2)		+= board-zoom2.o \
+					   board-zoom-peripherals.o \
 					   mmc-twl4030.o \
 					   board-zoom-debugboard.o
-
+obj-$(CONFIG_MACH_OMAP_ZOOM3)		+= board-zoom3.o \
+					   board-zoom-peripherals.o \
+					   mmc-twl4030.o \
+					   board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_3630SDP)		+= board-3630sdp.o \
+					   board-zoom-peripherals.o \
+					   mmc-twl4030.o
+obj-$(CONFIG_MACH_CM_T35)		+= board-cm-t35.o \
+					   mmc-twl4030.o
+obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o \
+					   mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)	+= board-omap3touchbook.o \
+					   mmc-twl4030.o
 obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o
 
+obj-$(CONFIG_MACH_OMAP3517EVM)     += board-am3517evm.o
+
 # Platform specific device init code
 obj-y					+= usb-musb.o
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
+obj-y					+= usb-ehci.o
 
 onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
 obj-y					+= $(onenand-m) $(onenand-y)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mcbsp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mcbsp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mcbsp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,10 +18,10 @@
 #include <linux/platform_device.h>
 
 #include <mach/irqs.h>
-#include <mach/dma.h>
-#include <mach/mux.h>
-#include <mach/cpu.h>
-#include <mach/mcbsp.h>
+#include <plat/dma.h>
+#include <plat/mux.h>
+#include <plat/cpu.h>
+#include <plat/mcbsp.h>
 
 static void omap2_mcbsp2_mux_setup(void)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mmc-twl4030.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,9 +20,9 @@
 #include <linux/regulator/consumer.h>
 
 #include <mach/hardware.h>
-#include <mach/control.h>
-#include <mach/mmc.h>
-#include <mach/board.h>
+#include <plat/control.h>
+#include <plat/mmc.h>
+#include <plat/board.h>
 
 #include "mmc-twl4030.h"
 
@@ -213,7 +213,7 @@ static int twl4030_mmc_get_context_loss(
 static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
 				int vdd)
 {
-	u32 reg;
+	u32 reg, prog_io;
 	int ret = 0;
 	struct twl_mmc_controller *c = &hsmmc[0];
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -245,7 +245,14 @@ static int twl_mmc1_set_power(struct dev
 		}
 
 		reg = omap_ctrl_readl(control_pbias_offset);
-		reg |= OMAP2_PBIASSPEEDCTRL0;
+		if (cpu_is_omap3630()) {
+			/* Set MMC I/O to 52Mhz */
+			prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
+			prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
+			omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
+		} else {
+			reg |= OMAP2_PBIASSPEEDCTRL0;
+		}
 		reg &= ~OMAP2_PBIASLITEPWRDNZ0;
 		omap_ctrl_writel(reg, control_pbias_offset);
 
@@ -401,6 +408,7 @@ void __init twl4030_mmc_init(struct twl4
 {
 	struct twl4030_hsmmc_info *c;
 	int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
+	int i;
 
 	if (cpu_is_omap2430()) {
 		control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
@@ -427,7 +435,7 @@ void __init twl4030_mmc_init(struct twl4
 		mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
 		if (!mmc) {
 			pr_err("Cannot allocate memory for mmc device!\n");
-			return;
+			goto done;
 		}
 
 		if (c->name)
@@ -489,6 +497,12 @@ void __init twl4030_mmc_init(struct twl4
 			/* on-chip level shifting via PBIAS0/PBIAS1 */
 			mmc->slots[0].set_power = twl_mmc1_set_power;
 			mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
+
+			/* Omap3630 HSMMC1 supports only 4-bit */
+			if (cpu_is_omap3630() && c->wires > 4) {
+				c->wires = 4;
+				mmc->slots[0].wires = c->wires;
+			}
 			break;
 		case 2:
 			if (c->ext_clock)
@@ -519,6 +533,10 @@ void __init twl4030_mmc_init(struct twl4
 			continue;
 		c->dev = mmc->dev;
 	}
+
+done:
+	for (i = 0; i < nr_hsmmc; i++)
+		kfree(hsmmc_data[i]);
 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux34xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux34xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux34xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux34xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2146 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 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 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 _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7)		\
+{									\
+	.reg_offset	= (OMAP3_CONTROL_PADCONF_##M0##_OFFSET),	\
+	.gpio		= (g),						\
+	.muxnames	= { m0, m1, m2, m3, m4, m5, m6, m7 },		\
+}
+
+#else
+
+#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7)		\
+{									\
+	.reg_offset	= (OMAP3_CONTROL_PADCONF_##M0##_OFFSET),	\
+	.gpio		= (g),						\
+}
+
+#endif
+
+#define _OMAP3_BALLENTRY(M0, bb, bt)					\
+{									\
+	.reg_offset	= (OMAP3_CONTROL_PADCONF_##M0##_OFFSET),	\
+	.balls		= { bb, bt },					\
+}
+
+/*
+ * Superset of all mux modes for omap3
+ */
+static struct omap_mux __initdata omap3_muxmodes[] = {
+	_OMAP3_MUXENTRY(CAM_D0, 99,
+		"cam_d0", NULL, NULL, NULL,
+		"gpio_99", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D1, 100,
+		"cam_d1", NULL, NULL, NULL,
+		"gpio_100", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D10, 109,
+		"cam_d10", NULL, NULL, NULL,
+		"gpio_109", "hw_dbg8", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D11, 110,
+		"cam_d11", NULL, NULL, NULL,
+		"gpio_110", "hw_dbg9", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D2, 101,
+		"cam_d2", NULL, NULL, NULL,
+		"gpio_101", "hw_dbg4", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D3, 102,
+		"cam_d3", NULL, NULL, NULL,
+		"gpio_102", "hw_dbg5", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D4, 103,
+		"cam_d4", NULL, NULL, NULL,
+		"gpio_103", "hw_dbg6", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D5, 104,
+		"cam_d5", NULL, NULL, NULL,
+		"gpio_104", "hw_dbg7", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D6, 105,
+		"cam_d6", NULL, NULL, NULL,
+		"gpio_105", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D7, 106,
+		"cam_d7", NULL, NULL, NULL,
+		"gpio_106", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D8, 107,
+		"cam_d8", NULL, NULL, NULL,
+		"gpio_107", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D9, 108,
+		"cam_d9", NULL, NULL, NULL,
+		"gpio_108", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_FLD, 98,
+		"cam_fld", NULL, "cam_global_reset", NULL,
+		"gpio_98", "hw_dbg3", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_HS, 94,
+		"cam_hs", NULL, NULL, NULL,
+		"gpio_94", "hw_dbg0", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_PCLK, 97,
+		"cam_pclk", NULL, NULL, NULL,
+		"gpio_97", "hw_dbg2", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_STROBE, 126,
+		"cam_strobe", NULL, NULL, NULL,
+		"gpio_126", "hw_dbg11", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_VS, 95,
+		"cam_vs", NULL, NULL, NULL,
+		"gpio_95", "hw_dbg1", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_WEN, 167,
+		"cam_wen", NULL, "cam_shutter", NULL,
+		"gpio_167", "hw_dbg10", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_XCLKA, 96,
+		"cam_xclka", NULL, NULL, NULL,
+		"gpio_96", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_XCLKB, 111,
+		"cam_xclkb", NULL, NULL, NULL,
+		"gpio_111", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CSI2_DX0, 112,
+		"csi2_dx0", NULL, NULL, NULL,
+		"gpio_112", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CSI2_DX1, 114,
+		"csi2_dx1", NULL, NULL, NULL,
+		"gpio_114", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CSI2_DY0, 113,
+		"csi2_dy0", NULL, NULL, NULL,
+		"gpio_113", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CSI2_DY1, 115,
+		"csi2_dy1", NULL, NULL, NULL,
+		"gpio_115", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_ACBIAS, 69,
+		"dss_acbias", NULL, NULL, NULL,
+		"gpio_69", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA0, 70,
+		"dss_data0", NULL, "uart1_cts", NULL,
+		"gpio_70", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA1, 71,
+		"dss_data1", NULL, "uart1_rts", NULL,
+		"gpio_71", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA10, 80,
+		"dss_data10", NULL, NULL, NULL,
+		"gpio_80", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA11, 81,
+		"dss_data11", NULL, NULL, NULL,
+		"gpio_81", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA12, 82,
+		"dss_data12", NULL, NULL, NULL,
+		"gpio_82", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA13, 83,
+		"dss_data13", NULL, NULL, NULL,
+		"gpio_83", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA14, 84,
+		"dss_data14", NULL, NULL, NULL,
+		"gpio_84", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA15, 85,
+		"dss_data15", NULL, NULL, NULL,
+		"gpio_85", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA16, 86,
+		"dss_data16", NULL, NULL, NULL,
+		"gpio_86", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA17, 87,
+		"dss_data17", NULL, NULL, NULL,
+		"gpio_87", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA18, 88,
+		"dss_data18", NULL, "mcspi3_clk", "dss_data0",
+		"gpio_88", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA19, 89,
+		"dss_data19", NULL, "mcspi3_simo", "dss_data1",
+		"gpio_89", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA20, 90,
+		"dss_data20", NULL, "mcspi3_somi", "dss_data2",
+		"gpio_90", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA21, 91,
+		"dss_data21", NULL, "mcspi3_cs0", "dss_data3",
+		"gpio_91", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA22, 92,
+		"dss_data22", NULL, "mcspi3_cs1", "dss_data4",
+		"gpio_92", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA23, 93,
+		"dss_data23", NULL, NULL, "dss_data5",
+		"gpio_93", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA2, 72,
+		"dss_data2", NULL, NULL, NULL,
+		"gpio_72", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA3, 73,
+		"dss_data3", NULL, NULL, NULL,
+		"gpio_73", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA4, 74,
+		"dss_data4", NULL, "uart3_rx_irrx", NULL,
+		"gpio_74", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA5, 75,
+		"dss_data5", NULL, "uart3_tx_irtx", NULL,
+		"gpio_75", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA6, 76,
+		"dss_data6", NULL, "uart1_tx", NULL,
+		"gpio_76", "hw_dbg14", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA7, 77,
+		"dss_data7", NULL, "uart1_rx", NULL,
+		"gpio_77", "hw_dbg15", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA8, 78,
+		"dss_data8", NULL, NULL, NULL,
+		"gpio_78", "hw_dbg16", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA9, 79,
+		"dss_data9", NULL, NULL, NULL,
+		"gpio_79", "hw_dbg17", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_HSYNC, 67,
+		"dss_hsync", NULL, NULL, NULL,
+		"gpio_67", "hw_dbg13", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_PCLK, 66,
+		"dss_pclk", NULL, NULL, NULL,
+		"gpio_66", "hw_dbg12", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_VSYNC, 68,
+		"dss_vsync", NULL, NULL, NULL,
+		"gpio_68", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(ETK_CLK, 12,
+		"etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+		"gpio_12", "mm1_rxdp", "hsusb1_tll_stp", "hw_dbg0"),
+	_OMAP3_MUXENTRY(ETK_CTL, 13,
+		"etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+		"gpio_13", NULL, "hsusb1_tll_clk", "hw_dbg1"),
+	_OMAP3_MUXENTRY(ETK_D0, 14,
+		"etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+		"gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", "hw_dbg2"),
+	_OMAP3_MUXENTRY(ETK_D1, 15,
+		"etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+		"gpio_15", "mm1_txse0", "hsusb1_tll_data1", "hw_dbg3"),
+	_OMAP3_MUXENTRY(ETK_D10, 24,
+		"etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+		"gpio_24", NULL, "hsusb2_tll_clk", "hw_dbg12"),
+	_OMAP3_MUXENTRY(ETK_D11, 25,
+		"etk_d11", NULL, NULL, "hsusb2_stp",
+		"gpio_25", "mm2_rxdp", "hsusb2_tll_stp", "hw_dbg13"),
+	_OMAP3_MUXENTRY(ETK_D12, 26,
+		"etk_d12", NULL, NULL, "hsusb2_dir",
+		"gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
+	_OMAP3_MUXENTRY(ETK_D13, 27,
+		"etk_d13", NULL, NULL, "hsusb2_nxt",
+		"gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", "hw_dbg15"),
+	_OMAP3_MUXENTRY(ETK_D14, 28,
+		"etk_d14", NULL, NULL, "hsusb2_data0",
+		"gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", "hw_dbg16"),
+	_OMAP3_MUXENTRY(ETK_D15, 29,
+		"etk_d15", NULL, NULL, "hsusb2_data1",
+		"gpio_29", "mm2_txse0", "hsusb2_tll_data1", "hw_dbg17"),
+	_OMAP3_MUXENTRY(ETK_D2, 16,
+		"etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+		"gpio_16", "mm1_txdat", "hsusb1_tll_data2", "hw_dbg4"),
+	_OMAP3_MUXENTRY(ETK_D3, 17,
+		"etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+		"gpio_17", NULL, "hsusb1_tll_data7", "hw_dbg5"),
+	_OMAP3_MUXENTRY(ETK_D4, 18,
+		"etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+		"gpio_18", NULL, "hsusb1_tll_data4", "hw_dbg6"),
+	_OMAP3_MUXENTRY(ETK_D5, 19,
+		"etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+		"gpio_19", NULL, "hsusb1_tll_data5", "hw_dbg7"),
+	_OMAP3_MUXENTRY(ETK_D6, 20,
+		"etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+		"gpio_20", NULL, "hsusb1_tll_data6", "hw_dbg8"),
+	_OMAP3_MUXENTRY(ETK_D7, 21,
+		"etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+		"gpio_21", "mm1_txen_n", "hsusb1_tll_data3", "hw_dbg9"),
+	_OMAP3_MUXENTRY(ETK_D8, 22,
+		"etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+		"gpio_22", NULL, "hsusb1_tll_dir", "hw_dbg10"),
+	_OMAP3_MUXENTRY(ETK_D9, 23,
+		"etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+		"gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", "hw_dbg11"),
+	_OMAP3_MUXENTRY(GPMC_A1, 34,
+		"gpmc_a1", NULL, NULL, NULL,
+		"gpio_34", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A10, 43,
+		"gpmc_a10", "sys_ndmareq3", NULL, NULL,
+		"gpio_43", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A2, 35,
+		"gpmc_a2", NULL, NULL, NULL,
+		"gpio_35", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A3, 36,
+		"gpmc_a3", NULL, NULL, NULL,
+		"gpio_36", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A4, 37,
+		"gpmc_a4", NULL, NULL, NULL,
+		"gpio_37", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A5, 38,
+		"gpmc_a5", NULL, NULL, NULL,
+		"gpio_38", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A6, 39,
+		"gpmc_a6", NULL, NULL, NULL,
+		"gpio_39", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A7, 40,
+		"gpmc_a7", NULL, NULL, NULL,
+		"gpio_40", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A8, 41,
+		"gpmc_a8", NULL, NULL, NULL,
+		"gpio_41", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_A9, 42,
+		"gpmc_a9", "sys_ndmareq2", NULL, NULL,
+		"gpio_42", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_CLK, 59,
+		"gpmc_clk", NULL, NULL, NULL,
+		"gpio_59", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D10, 46,
+		"gpmc_d10", NULL, NULL, NULL,
+		"gpio_46", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D11, 47,
+		"gpmc_d11", NULL, NULL, NULL,
+		"gpio_47", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D12, 48,
+		"gpmc_d12", NULL, NULL, NULL,
+		"gpio_48", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D13, 49,
+		"gpmc_d13", NULL, NULL, NULL,
+		"gpio_49", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D14, 50,
+		"gpmc_d14", NULL, NULL, NULL,
+		"gpio_50", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D15, 51,
+		"gpmc_d15", NULL, NULL, NULL,
+		"gpio_51", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D8, 44,
+		"gpmc_d8", NULL, NULL, NULL,
+		"gpio_44", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_D9, 45,
+		"gpmc_d9", NULL, NULL, NULL,
+		"gpio_45", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NBE0_CLE, 60,
+		"gpmc_nbe0_cle", NULL, NULL, NULL,
+		"gpio_60", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NBE1, 61,
+		"gpmc_nbe1", NULL, NULL, NULL,
+		"gpio_61", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS1, 52,
+		"gpmc_ncs1", NULL, NULL, NULL,
+		"gpio_52", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS2, 53,
+		"gpmc_ncs2", NULL, NULL, NULL,
+		"gpio_53", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS3, 54,
+		"gpmc_ncs3", "sys_ndmareq0", NULL, NULL,
+		"gpio_54", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS4, 55,
+		"gpmc_ncs4", "sys_ndmareq1", "mcbsp4_clkx", "gpt9_pwm_evt",
+		"gpio_55", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS5, 56,
+		"gpmc_ncs5", "sys_ndmareq2", "mcbsp4_dr", "gpt10_pwm_evt",
+		"gpio_56", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS6, 57,
+		"gpmc_ncs6", "sys_ndmareq3", "mcbsp4_dx", "gpt11_pwm_evt",
+		"gpio_57", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NCS7, 58,
+		"gpmc_ncs7", "gpmc_io_dir", "mcbsp4_fsx", "gpt8_pwm_evt",
+		"gpio_58", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_NWP, 62,
+		"gpmc_nwp", NULL, NULL, NULL,
+		"gpio_62", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_WAIT1, 63,
+		"gpmc_wait1", NULL, NULL, NULL,
+		"gpio_63", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_WAIT2, 64,
+		"gpmc_wait2", NULL, NULL, NULL,
+		"gpio_64", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_WAIT3, 65,
+		"gpmc_wait3", "sys_ndmareq1", NULL, NULL,
+		"gpio_65", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HDQ_SIO, 170,
+		"hdq_sio", "sys_altclk", "i2c2_sccbe", "i2c3_sccbe",
+		"gpio_170", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_CLK, 120,
+		"hsusb0_clk", NULL, NULL, NULL,
+		"gpio_120", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
+		"hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
+		"gpio_125", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
+		"hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
+		"gpio_130", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
+		"hsusb0_data2", NULL, "uart3_rts_sd", NULL,
+		"gpio_131", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
+		"hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
+		"gpio_169", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA4, 188,
+		"hsusb0_data4", NULL, NULL, NULL,
+		"gpio_188", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA5, 189,
+		"hsusb0_data5", NULL, NULL, NULL,
+		"gpio_189", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA6, 190,
+		"hsusb0_data6", NULL, NULL, NULL,
+		"gpio_190", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA7, 191,
+		"hsusb0_data7", NULL, NULL, NULL,
+		"gpio_191", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DIR, 122,
+		"hsusb0_dir", NULL, NULL, NULL,
+		"gpio_122", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_NXT, 124,
+		"hsusb0_nxt", NULL, NULL, NULL,
+		"gpio_124", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_STP, 121,
+		"hsusb0_stp", NULL, NULL, NULL,
+		"gpio_121", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C2_SCL, 168,
+		"i2c2_scl", NULL, NULL, NULL,
+		"gpio_168", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C2_SDA, 183,
+		"i2c2_sda", NULL, NULL, NULL,
+		"gpio_183", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C3_SCL, 184,
+		"i2c3_scl", NULL, NULL, NULL,
+		"gpio_184", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C3_SDA, 185,
+		"i2c3_sda", NULL, NULL, NULL,
+		"gpio_185", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C4_SCL, 0,
+		"i2c4_scl", "sys_nvmode1", NULL, NULL,
+		NULL, NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(I2C4_SDA, 0,
+		"i2c4_sda", "sys_nvmode2", NULL, NULL,
+		NULL, NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(JTAG_EMU0, 11,
+		"jtag_emu0", NULL, NULL, NULL,
+		"gpio_11", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(JTAG_EMU1, 31,
+		"jtag_emu1", NULL, NULL, NULL,
+		"gpio_31", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
+		"mcbsp1_clkr", "mcspi4_clk", NULL, NULL,
+		"gpio_156", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_CLKX, 162,
+		"mcbsp1_clkx", NULL, "mcbsp3_clkx", NULL,
+		"gpio_162", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_DR, 159,
+		"mcbsp1_dr", "mcspi4_somi", "mcbsp3_dr", NULL,
+		"gpio_159", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_DX, 158,
+		"mcbsp1_dx", "mcspi4_simo", "mcbsp3_dx", NULL,
+		"gpio_158", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_FSR, 157,
+		"mcbsp1_fsr", NULL, "cam_global_reset", NULL,
+		"gpio_157", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_FSX, 161,
+		"mcbsp1_fsx", "mcspi4_cs0", "mcbsp3_fsx", NULL,
+		"gpio_161", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP2_CLKX, 117,
+		"mcbsp2_clkx", NULL, NULL, NULL,
+		"gpio_117", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP2_DR, 118,
+		"mcbsp2_dr", NULL, NULL, NULL,
+		"gpio_118", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP2_DX, 119,
+		"mcbsp2_dx", NULL, NULL, NULL,
+		"gpio_119", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP2_FSX, 116,
+		"mcbsp2_fsx", NULL, NULL, NULL,
+		"gpio_116", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
+		"mcbsp3_clkx", "uart2_tx", NULL, NULL,
+		"gpio_142", "hsusb3_tll_data6", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_DR, 141,
+		"mcbsp3_dr", "uart2_rts", NULL, NULL,
+		"gpio_141", "hsusb3_tll_data5", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_DX, 140,
+		"mcbsp3_dx", "uart2_cts", NULL, NULL,
+		"gpio_140", "hsusb3_tll_data4", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_FSX, 143,
+		"mcbsp3_fsx", "uart2_rx", NULL, NULL,
+		"gpio_143", "hsusb3_tll_data7", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
+		"mcbsp4_clkx", NULL, NULL, NULL,
+		"gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_DR, 153,
+		"mcbsp4_dr", NULL, NULL, NULL,
+		"gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_DX, 154,
+		"mcbsp4_dx", NULL, NULL, NULL,
+		"gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_FSX, 155,
+		"mcbsp4_fsx", NULL, NULL, NULL,
+		"gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP_CLKS, 160,
+		"mcbsp_clks", NULL, "cam_shutter", NULL,
+		"gpio_160", "uart1_cts", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CLK, 171,
+		"mcspi1_clk", "sdmmc2_dat4", NULL, NULL,
+		"gpio_171", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CS0, 174,
+		"mcspi1_cs0", "sdmmc2_dat7", NULL, NULL,
+		"gpio_174", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CS1, 175,
+		"mcspi1_cs1", NULL, NULL, "sdmmc3_cmd",
+		"gpio_175", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CS2, 176,
+		"mcspi1_cs2", NULL, NULL, "sdmmc3_clk",
+		"gpio_176", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CS3, 177,
+		"mcspi1_cs3", NULL, "hsusb2_tll_data2", "hsusb2_data2",
+		"gpio_177", "mm2_txdat", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_SIMO, 172,
+		"mcspi1_simo", "sdmmc2_dat5", NULL, NULL,
+		"gpio_172", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_SOMI, 173,
+		"mcspi1_somi", "sdmmc2_dat6", NULL, NULL,
+		"gpio_173", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI2_CLK, 178,
+		"mcspi2_clk", NULL, "hsusb2_tll_data7", "hsusb2_data7",
+		"gpio_178", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI2_CS0, 181,
+		"mcspi2_cs0", "gpt11_pwm_evt",
+		"hsusb2_tll_data6", "hsusb2_data6",
+		"gpio_181", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI2_CS1, 182,
+		"mcspi2_cs1", "gpt8_pwm_evt",
+		"hsusb2_tll_data3", "hsusb2_data3",
+		"gpio_182", "mm2_txen_n", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI2_SIMO, 179,
+		"mcspi2_simo", "gpt9_pwm_evt",
+		"hsusb2_tll_data4", "hsusb2_data4",
+		"gpio_179", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI2_SOMI, 180,
+		"mcspi2_somi", "gpt10_pwm_evt",
+		"hsusb2_tll_data5", "hsusb2_data5",
+		"gpio_180", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_CLK, 120,
+		"sdmmc1_clk", NULL, NULL, NULL,
+		"gpio_120", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_CMD, 121,
+		"sdmmc1_cmd", NULL, NULL, NULL,
+		"gpio_121", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
+		"sdmmc1_dat0", NULL, NULL, NULL,
+		"gpio_122", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
+		"sdmmc1_dat1", NULL, NULL, NULL,
+		"gpio_123", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
+		"sdmmc1_dat2", NULL, NULL, NULL,
+		"gpio_124", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
+		"sdmmc1_dat3", NULL, NULL, NULL,
+		"gpio_125", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT4, 126,
+		"sdmmc1_dat4", NULL, "sim_io", NULL,
+		"gpio_126", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT5, 127,
+		"sdmmc1_dat5", NULL, "sim_clk", NULL,
+		"gpio_127", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT6, 128,
+		"sdmmc1_dat6", NULL, "sim_pwrctrl", NULL,
+		"gpio_128", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT7, 129,
+		"sdmmc1_dat7", NULL, "sim_rst", NULL,
+		"gpio_129", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_CLK, 130,
+		"sdmmc2_clk", "mcspi3_clk", NULL, NULL,
+		"gpio_130", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_CMD, 131,
+		"sdmmc2_cmd", "mcspi3_simo", NULL, NULL,
+		"gpio_131", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT0, 132,
+		"sdmmc2_dat0", "mcspi3_somi", NULL, NULL,
+		"gpio_132", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT1, 133,
+		"sdmmc2_dat1", NULL, NULL, NULL,
+		"gpio_133", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT2, 134,
+		"sdmmc2_dat2", "mcspi3_cs1", NULL, NULL,
+		"gpio_134", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT3, 135,
+		"sdmmc2_dat3", "mcspi3_cs0", NULL, NULL,
+		"gpio_135", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT4, 136,
+		"sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, "sdmmc3_dat0",
+		"gpio_136", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
+		"sdmmc2_dat5", "sdmmc2_dir_dat1",
+		"cam_global_reset", "sdmmc3_dat1",
+		"gpio_137", "hsusb3_tll_stp", "mm3_rxdp", "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
+		"sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
+		"gpio_138", "hsusb3_tll_dir", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
+		"sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
+		"gpio_139", "hsusb3_tll_nxt", "mm3_rxdm", "safe_mode"),
+	_OMAP3_MUXENTRY(SDRC_CKE0, 0,
+		"sdrc_cke0", NULL, NULL, NULL,
+		NULL, NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDRC_CKE1, 0,
+		"sdrc_cke1", NULL, NULL, NULL,
+		NULL, NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT0, 2,
+		"sys_boot0", NULL, NULL, NULL,
+		"gpio_2", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT1, 3,
+		"sys_boot1", NULL, NULL, NULL,
+		"gpio_3", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT2, 4,
+		"sys_boot2", NULL, NULL, NULL,
+		"gpio_4", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT3, 5,
+		"sys_boot3", NULL, NULL, NULL,
+		"gpio_5", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT4, 6,
+		"sys_boot4", "sdmmc2_dir_dat2", NULL, NULL,
+		"gpio_6", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT5, 7,
+		"sys_boot5", "sdmmc2_dir_dat3", NULL, NULL,
+		"gpio_7", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT6, 8,
+		"sys_boot6", NULL, NULL, NULL,
+		"gpio_8", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_CLKOUT1, 10,
+		"sys_clkout1", NULL, NULL, NULL,
+		"gpio_10", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_CLKOUT2, 186,
+		"sys_clkout2", NULL, NULL, NULL,
+		"gpio_186", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_CLKREQ, 1,
+		"sys_clkreq", NULL, NULL, NULL,
+		"gpio_1", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_NIRQ, 0,
+		"sys_nirq", NULL, NULL, NULL,
+		"gpio_0", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_NRESWARM, 30,
+		"sys_nreswarm", NULL, NULL, NULL,
+		"gpio_30", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_OFF_MODE, 9,
+		"sys_off_mode", NULL, NULL, NULL,
+		"gpio_9", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_CTS, 150,
+		"uart1_cts", NULL, NULL, NULL,
+		"gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_RTS, 149,
+		"uart1_rts", NULL, NULL, NULL,
+		"gpio_149", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_RX, 151,
+		"uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk",
+		"gpio_151", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_TX, 148,
+		"uart1_tx", NULL, NULL, NULL,
+		"gpio_148", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART2_CTS, 144,
+		"uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL,
+		"gpio_144", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART2_RTS, 145,
+		"uart2_rts", "mcbsp3_dr", "gpt10_pwm_evt", NULL,
+		"gpio_145", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART2_RX, 147,
+		"uart2_rx", "mcbsp3_fsx", "gpt8_pwm_evt", NULL,
+		"gpio_147", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART2_TX, 146,
+		"uart2_tx", "mcbsp3_clkx", "gpt11_pwm_evt", NULL,
+		"gpio_146", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART3_CTS_RCTX, 163,
+		"uart3_cts_rctx", NULL, NULL, NULL,
+		"gpio_163", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART3_RTS_SD, 164,
+		"uart3_rts_sd", NULL, NULL, NULL,
+		"gpio_164", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART3_RX_IRRX, 165,
+		"uart3_rx_irrx", NULL, NULL, NULL,
+		"gpio_165", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART3_TX_IRTX, 166,
+		"uart3_tx_irtx", NULL, NULL, NULL,
+		"gpio_166", NULL, NULL, "safe_mode"),
+
+	/* Only on 3630, see omap36xx_cbp_subset for the signals */
+	_OMAP3_MUXENTRY(GPMC_A11, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MREAD, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SREAD, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(GPMC_A11, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
+		NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Signals different on CBC package compared to the superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC)
+struct omap_mux __initdata omap3_cbc_subset[] = {
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbc_subset	NULL
+#endif
+
+/*
+ * Balls for CBC package
+ * 515-pin s-PBGA Package, 0.65mm Ball Pitch (Top), 0.50mm Ball Pitch (Bottom)
+ *
+ * FIXME: What's up with the outdated TI documentation? See:
+ *
+ * http://wiki.davincidsp.com/index.php/Datasheet_Errata_for_OMAP35x_CBC_Package
+ * http://community.ti.com/forums/t/10982.aspx
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)	\
+		&& defined(CONFIG_OMAP_PACKAGE_CBC)
+struct omap_ball __initdata omap3_cbc_ball[] = {
+	_OMAP3_BALLENTRY(CAM_D0, "ae16", NULL),
+	_OMAP3_BALLENTRY(CAM_D1, "ae15", NULL),
+	_OMAP3_BALLENTRY(CAM_D10, "d25", NULL),
+	_OMAP3_BALLENTRY(CAM_D11, "e26", NULL),
+	_OMAP3_BALLENTRY(CAM_D2, "a24", NULL),
+	_OMAP3_BALLENTRY(CAM_D3, "b24", NULL),
+	_OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+	_OMAP3_BALLENTRY(CAM_D5, "c24", NULL),
+	_OMAP3_BALLENTRY(CAM_D6, "p25", NULL),
+	_OMAP3_BALLENTRY(CAM_D7, "p26", NULL),
+	_OMAP3_BALLENTRY(CAM_D8, "n25", NULL),
+	_OMAP3_BALLENTRY(CAM_D9, "n26", NULL),
+	_OMAP3_BALLENTRY(CAM_FLD, "b23", NULL),
+	_OMAP3_BALLENTRY(CAM_HS, "c23", NULL),
+	_OMAP3_BALLENTRY(CAM_PCLK, "c26", NULL),
+	_OMAP3_BALLENTRY(CAM_STROBE, "d26", NULL),
+	_OMAP3_BALLENTRY(CAM_VS, "d23", NULL),
+	_OMAP3_BALLENTRY(CAM_WEN, "a23", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKB, "e25", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX0, "ad17", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX1, "ae18", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY0, "ad16", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY1, "ae17", NULL),
+	_OMAP3_BALLENTRY(DSS_ACBIAS, "f26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA0, "ae21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA1, "ae22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA10, "ac26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA11, "ad26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA12, "aa25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA13, "y25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA14, "aa26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA15, "ab26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA16, "l25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA17, "l26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA18, "m24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA19, "m26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA2, "ae23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA20, "f25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA21, "n24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA22, "ac25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA23, "ab25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA3, "ae24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA4, "ad23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA5, "ad24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA6, "g26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA7, "h25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA8, "h26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA9, "j26", NULL),
+	_OMAP3_BALLENTRY(DSS_HSYNC, "k24", NULL),
+	_OMAP3_BALLENTRY(DSS_PCLK, "g25", NULL),
+	_OMAP3_BALLENTRY(DSS_VSYNC, "m25", NULL),
+	_OMAP3_BALLENTRY(ETK_CLK, "ab2", NULL),
+	_OMAP3_BALLENTRY(ETK_CTL, "ab3", NULL),
+	_OMAP3_BALLENTRY(ETK_D0, "ac3", NULL),
+	_OMAP3_BALLENTRY(ETK_D1, "ad4", NULL),
+	_OMAP3_BALLENTRY(ETK_D10, "ae4", NULL),
+	_OMAP3_BALLENTRY(ETK_D11, "af6", NULL),
+	_OMAP3_BALLENTRY(ETK_D12, "ae6", NULL),
+	_OMAP3_BALLENTRY(ETK_D13, "af7", NULL),
+	_OMAP3_BALLENTRY(ETK_D14, "af9", NULL),
+	_OMAP3_BALLENTRY(ETK_D15, "ae9", NULL),
+	_OMAP3_BALLENTRY(ETK_D2, "ad3", NULL),
+	_OMAP3_BALLENTRY(ETK_D3, "aa3", NULL),
+	_OMAP3_BALLENTRY(ETK_D4, "y3", NULL),
+	_OMAP3_BALLENTRY(ETK_D5, "ab1", NULL),
+	_OMAP3_BALLENTRY(ETK_D6, "ae3", NULL),
+	_OMAP3_BALLENTRY(ETK_D7, "ad2", NULL),
+	_OMAP3_BALLENTRY(ETK_D8, "aa4", NULL),
+	_OMAP3_BALLENTRY(ETK_D9, "v2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A1, "j2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A10, "d2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A2, "h1", NULL),
+	_OMAP3_BALLENTRY(GPMC_A3, "h2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A4, "g2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A5, "f1", NULL),
+	_OMAP3_BALLENTRY(GPMC_A6, "f2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A7, "e1", NULL),
+	_OMAP3_BALLENTRY(GPMC_A8, "e2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A9, "d1", NULL),
+	_OMAP3_BALLENTRY(GPMC_CLK, "n1", "l1"),
+	_OMAP3_BALLENTRY(GPMC_D10, "t1", "n1"),
+	_OMAP3_BALLENTRY(GPMC_D11, "u2", "p2"),
+	_OMAP3_BALLENTRY(GPMC_D12, "u1", "p1"),
+	_OMAP3_BALLENTRY(GPMC_D13, "p1", "m1"),
+	_OMAP3_BALLENTRY(GPMC_D14, "l2", "j2"),
+	_OMAP3_BALLENTRY(GPMC_D15, "m2", "k2"),
+	_OMAP3_BALLENTRY(GPMC_D8, "v1", "r1"),
+	_OMAP3_BALLENTRY(GPMC_D9, "y1", "t1"),
+	_OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k2", NULL),
+	_OMAP3_BALLENTRY(GPMC_NBE1, "j1", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS1, "ad1", "w1"),
+	_OMAP3_BALLENTRY(GPMC_NCS2, "a3", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS3, "b6", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS4, "b4", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS5, "c4", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS6, "b5", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS7, "c5", NULL),
+	_OMAP3_BALLENTRY(GPMC_NWP, "ac6", "y5"),
+	_OMAP3_BALLENTRY(GPMC_WAIT1, "ac8", "y8"),
+	_OMAP3_BALLENTRY(GPMC_WAIT2, "b3", NULL),
+	_OMAP3_BALLENTRY(GPMC_WAIT3, "c6", NULL),
+	_OMAP3_BALLENTRY(HDQ_SIO, "j23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_CLK, "w19", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA0, "v20", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA1, "y20", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA2, "v18", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA3, "w20", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA4, "w17", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA5, "y18", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA6, "y19", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA7, "y17", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DIR, "v19", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_NXT, "w18", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_STP, "u20", NULL),
+	_OMAP3_BALLENTRY(I2C2_SCL, "c2", NULL),
+	_OMAP3_BALLENTRY(I2C2_SDA, "c1", NULL),
+	_OMAP3_BALLENTRY(I2C3_SCL, "ab4", NULL),
+	_OMAP3_BALLENTRY(I2C3_SDA, "ac4", NULL),
+	_OMAP3_BALLENTRY(I2C4_SCL, "ad15", NULL),
+	_OMAP3_BALLENTRY(I2C4_SDA, "w16", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU0, "y15", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU1, "y14", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKR, "u19", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKX, "t17", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DR, "t20", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DX, "u17", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSR, "v17", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSX, "p20", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_CLKX, "r18", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DR, "t18", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DX, "r19", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_FSX, "u18", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_CLKX, "u3", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DR, "n3", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DX, "p3", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_FSX, "w3", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_CLKX, "v3", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DR, "u4", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DX, "r3", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_FSX, "t3", NULL),
+	_OMAP3_BALLENTRY(MCBSP_CLKS, "t19", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CLK, "p9", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS0, "r7", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS1, "r8", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS2, "r9", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS3, "t8", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SIMO, "p8", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SOMI, "p7", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CLK, "w7", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS0, "v8", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS1, "v9", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SIMO, "w8", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SOMI, "u8", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CLK, "n19", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CMD, "l18", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT0, "m19", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT1, "m18", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT2, "k18", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT3, "n20", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT4, "m20", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT5, "p17", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT6, "p18", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT7, "p19", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CLK, "w10", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CMD, "r10", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT0, "t10", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT1, "t9", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT2, "u10", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT3, "u9", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT4, "v10", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT5, "m3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT6, "l3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT7, "k3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT0, "f3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT1, "d3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT2, "c3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT3, "e3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT4, "e4", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT5, "g3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT6, "d4", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT1, "ae14", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT2, "w11", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKREQ, "w15", NULL),
+	_OMAP3_BALLENTRY(SYS_NIRQ, "v16", NULL),
+	_OMAP3_BALLENTRY(SYS_NRESWARM, "ad7", "aa5"),
+	_OMAP3_BALLENTRY(SYS_OFF_MODE, "v12", NULL),
+	_OMAP3_BALLENTRY(UART1_CTS, "w2", NULL),
+	_OMAP3_BALLENTRY(UART1_RTS, "r2", NULL),
+	_OMAP3_BALLENTRY(UART1_RX, "h3", NULL),
+	_OMAP3_BALLENTRY(UART1_TX, "l4", NULL),
+	_OMAP3_BALLENTRY(UART2_CTS, "y24", NULL),
+	_OMAP3_BALLENTRY(UART2_RTS, "aa24", NULL),
+	_OMAP3_BALLENTRY(UART2_RX, "ad21", NULL),
+	_OMAP3_BALLENTRY(UART2_TX, "ad22", NULL),
+	_OMAP3_BALLENTRY(UART3_CTS_RCTX, "f23", NULL),
+	_OMAP3_BALLENTRY(UART3_RTS_SD, "f24", NULL),
+	_OMAP3_BALLENTRY(UART3_RX_IRRX, "h24", NULL),
+	_OMAP3_BALLENTRY(UART3_TX_IRTX, "g24", NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbc_ball	 NULL
+#endif
+
+/*
+ * Signals different on CUS package compared to superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CUS)
+struct omap_mux __initdata omap3_cus_subset[] = {
+	_OMAP3_MUXENTRY(CAM_D10, 109,
+		"cam_d10", NULL, NULL, NULL,
+		"gpio_109", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D11, 110,
+		"cam_d11", NULL, NULL, NULL,
+		"gpio_110", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D2, 101,
+		"cam_d2", NULL, NULL, NULL,
+		"gpio_101", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D3, 102,
+		"cam_d3", NULL, NULL, NULL,
+		"gpio_102", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D4, 103,
+		"cam_d4", NULL, NULL, NULL,
+		"gpio_103", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D5, 104,
+		"cam_d5", NULL, NULL, NULL,
+		"gpio_104", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_FLD, 98,
+		"cam_fld", NULL, "cam_global_reset", NULL,
+		"gpio_98", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_HS, 94,
+		"cam_hs", NULL, NULL, NULL,
+		"gpio_94", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_PCLK, 97,
+		"cam_pclk", NULL, NULL, NULL,
+		"gpio_97", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_STROBE, 126,
+		"cam_strobe", NULL, NULL, NULL,
+		"gpio_126", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_VS, 95,
+		"cam_vs", NULL, NULL, NULL,
+		"gpio_95", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_WEN, 167,
+		"cam_wen", NULL, "cam_shutter", NULL,
+		"gpio_167", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA6, 76,
+		"dss_data6", NULL, "uart1_tx", NULL,
+		"gpio_76", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA7, 77,
+		"dss_data7", NULL, "uart1_rx", NULL,
+		"gpio_77", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA8, 78,
+		"dss_data8", NULL, NULL, NULL,
+		"gpio_78", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA9, 79,
+		"dss_data9", NULL, NULL, NULL,
+		"gpio_79", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_HSYNC, 67,
+		"dss_hsync", NULL, NULL, NULL,
+		"gpio_67", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_PCLK, 66,
+		"dss_pclk", NULL, NULL, NULL,
+		"gpio_66", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(ETK_CLK, 12,
+		"etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+		"gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
+	_OMAP3_MUXENTRY(ETK_CTL, 13,
+		"etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+		"gpio_13", NULL, "hsusb1_tll_clk", NULL),
+	_OMAP3_MUXENTRY(ETK_D0, 14,
+		"etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+		"gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
+	_OMAP3_MUXENTRY(ETK_D1, 15,
+		"etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+		"gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
+	_OMAP3_MUXENTRY(ETK_D10, 24,
+		"etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+		"gpio_24", NULL, "hsusb2_tll_clk", NULL),
+	_OMAP3_MUXENTRY(ETK_D11, 25,
+		"etk_d11", NULL, NULL, "hsusb2_stp",
+		"gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
+	_OMAP3_MUXENTRY(ETK_D12, 26,
+		"etk_d12", NULL, NULL, "hsusb2_dir",
+		"gpio_26", NULL, "hsusb2_tll_dir", NULL),
+	_OMAP3_MUXENTRY(ETK_D13, 27,
+		"etk_d13", NULL, NULL, "hsusb2_nxt",
+		"gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
+	_OMAP3_MUXENTRY(ETK_D14, 28,
+		"etk_d14", NULL, NULL, "hsusb2_data0",
+		"gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
+	_OMAP3_MUXENTRY(ETK_D15, 29,
+		"etk_d15", NULL, NULL, "hsusb2_data1",
+		"gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
+	_OMAP3_MUXENTRY(ETK_D2, 16,
+		"etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+		"gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
+	_OMAP3_MUXENTRY(ETK_D3, 17,
+		"etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+		"gpio_17", NULL, "hsusb1_tll_data7", NULL),
+	_OMAP3_MUXENTRY(ETK_D4, 18,
+		"etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+		"gpio_18", NULL, "hsusb1_tll_data4", NULL),
+	_OMAP3_MUXENTRY(ETK_D5, 19,
+		"etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+		"gpio_19", NULL, "hsusb1_tll_data5", NULL),
+	_OMAP3_MUXENTRY(ETK_D6, 20,
+		"etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+		"gpio_20", NULL, "hsusb1_tll_data6", NULL),
+	_OMAP3_MUXENTRY(ETK_D7, 21,
+		"etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+		"gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
+	_OMAP3_MUXENTRY(ETK_D8, 22,
+		"etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+		"gpio_22", NULL, "hsusb1_tll_dir", NULL),
+	_OMAP3_MUXENTRY(ETK_D9, 23,
+		"etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+		"gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
+	_OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
+		"mcbsp3_clkx", "uart2_tx", NULL, NULL,
+		"gpio_142", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_DR, 141,
+		"mcbsp3_dr", "uart2_rts", NULL, NULL,
+		"gpio_141", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_DX, 140,
+		"mcbsp3_dx", "uart2_cts", NULL, NULL,
+		"gpio_140", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP3_FSX, 143,
+		"mcbsp3_fsx", "uart2_rx", NULL, NULL,
+		"gpio_143", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
+		"sdmmc2_dat5", "sdmmc2_dir_dat1",
+		"cam_global_reset", "sdmmc3_dat1",
+		"gpio_137", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
+		"sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
+		"gpio_138", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
+		"sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
+		"gpio_139", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_CTS, 150,
+		"uart1_cts", NULL, NULL, NULL,
+		"gpio_150", NULL, NULL, "safe_mode"),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cus_subset	NULL
+#endif
+
+/*
+ * Balls for CUS package
+ * 423-pin s-PBGA Package, 0.65mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
+		&& defined(CONFIG_OMAP_PACKAGE_CUS)
+struct omap_ball __initdata omap3_cus_ball[] = {
+	_OMAP3_BALLENTRY(CAM_D0, "ab18", NULL),
+	_OMAP3_BALLENTRY(CAM_D1, "ac18", NULL),
+	_OMAP3_BALLENTRY(CAM_D10, "f21", NULL),
+	_OMAP3_BALLENTRY(CAM_D11, "g21", NULL),
+	_OMAP3_BALLENTRY(CAM_D2, "g19", NULL),
+	_OMAP3_BALLENTRY(CAM_D3, "f19", NULL),
+	_OMAP3_BALLENTRY(CAM_D4, "g20", NULL),
+	_OMAP3_BALLENTRY(CAM_D5, "b21", NULL),
+	_OMAP3_BALLENTRY(CAM_D6, "l24", NULL),
+	_OMAP3_BALLENTRY(CAM_D7, "k24", NULL),
+	_OMAP3_BALLENTRY(CAM_D8, "j23", NULL),
+	_OMAP3_BALLENTRY(CAM_D9, "k23", NULL),
+	_OMAP3_BALLENTRY(CAM_FLD, "h24", NULL),
+	_OMAP3_BALLENTRY(CAM_HS, "a22", NULL),
+	_OMAP3_BALLENTRY(CAM_PCLK, "j19", NULL),
+	_OMAP3_BALLENTRY(CAM_STROBE, "j20", NULL),
+	_OMAP3_BALLENTRY(CAM_VS, "e18", NULL),
+	_OMAP3_BALLENTRY(CAM_WEN, "f18", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKA, "b22", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKB, "c22", NULL),
+	_OMAP3_BALLENTRY(DSS_ACBIAS, "j21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA0, "ac19", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA1, "ab19", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA10, "ac22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA11, "ac23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA12, "ab22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA13, "y22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA14, "w22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA15, "v22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA16, "j22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA17, "g23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA18, "g24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA19, "h23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA2, "ad20", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA20, "d23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA21, "k22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA22, "v21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA23, "w21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA3, "ac20", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA4, "ad21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA5, "ac21", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA6, "d24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA7, "e23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA8, "e24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA9, "f23", NULL),
+	_OMAP3_BALLENTRY(DSS_HSYNC, "e22", NULL),
+	_OMAP3_BALLENTRY(DSS_PCLK, "g22", NULL),
+	_OMAP3_BALLENTRY(DSS_VSYNC, "f22", NULL),
+	_OMAP3_BALLENTRY(ETK_CLK, "ac1", NULL),
+	_OMAP3_BALLENTRY(ETK_CTL, "ad3", NULL),
+	_OMAP3_BALLENTRY(ETK_D0, "ad6", NULL),
+	_OMAP3_BALLENTRY(ETK_D1, "ac6", NULL),
+	_OMAP3_BALLENTRY(ETK_D10, "ac3", NULL),
+	_OMAP3_BALLENTRY(ETK_D11, "ac9", NULL),
+	_OMAP3_BALLENTRY(ETK_D12, "ac10", NULL),
+	_OMAP3_BALLENTRY(ETK_D13, "ad11", NULL),
+	_OMAP3_BALLENTRY(ETK_D14, "ac11", NULL),
+	_OMAP3_BALLENTRY(ETK_D15, "ad12", NULL),
+	_OMAP3_BALLENTRY(ETK_D2, "ac7", NULL),
+	_OMAP3_BALLENTRY(ETK_D3, "ad8", NULL),
+	_OMAP3_BALLENTRY(ETK_D4, "ac5", NULL),
+	_OMAP3_BALLENTRY(ETK_D5, "ad2", NULL),
+	_OMAP3_BALLENTRY(ETK_D6, "ac8", NULL),
+	_OMAP3_BALLENTRY(ETK_D7, "ad9", NULL),
+	_OMAP3_BALLENTRY(ETK_D8, "ac4", NULL),
+	_OMAP3_BALLENTRY(ETK_D9, "ad5", NULL),
+	_OMAP3_BALLENTRY(GPMC_A1, "k4", NULL),
+	_OMAP3_BALLENTRY(GPMC_A10, "g2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A2, "k3", NULL),
+	_OMAP3_BALLENTRY(GPMC_A3, "k2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A4, "j4", NULL),
+	_OMAP3_BALLENTRY(GPMC_A5, "j3", NULL),
+	_OMAP3_BALLENTRY(GPMC_A6, "j2", NULL),
+	_OMAP3_BALLENTRY(GPMC_A7, "j1", NULL),
+	_OMAP3_BALLENTRY(GPMC_A8, "h1", NULL),
+	_OMAP3_BALLENTRY(GPMC_A9, "h2", NULL),
+	_OMAP3_BALLENTRY(GPMC_CLK, "w2", NULL),
+	_OMAP3_BALLENTRY(GPMC_D10, "u1", NULL),
+	_OMAP3_BALLENTRY(GPMC_D11, "r3", NULL),
+	_OMAP3_BALLENTRY(GPMC_D12, "t3", NULL),
+	_OMAP3_BALLENTRY(GPMC_D13, "u2", NULL),
+	_OMAP3_BALLENTRY(GPMC_D14, "v1", NULL),
+	_OMAP3_BALLENTRY(GPMC_D15, "v2", NULL),
+	_OMAP3_BALLENTRY(GPMC_D8, "r2", NULL),
+	_OMAP3_BALLENTRY(GPMC_D9, "t2", NULL),
+	_OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k5", NULL),
+	_OMAP3_BALLENTRY(GPMC_NBE1, "l1", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS3, "d2", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS4, "f4", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS5, "g5", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS6, "f3", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS7, "g4", NULL),
+	_OMAP3_BALLENTRY(GPMC_NWP, "e1", NULL),
+	_OMAP3_BALLENTRY(GPMC_WAIT3, "c2", NULL),
+	_OMAP3_BALLENTRY(HDQ_SIO, "a24", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_CLK, "r21", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA0, "t24", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA1, "t23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA2, "u24", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA3, "u23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA4, "w24", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA5, "v23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA6, "w23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA7, "t22", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DIR, "p23", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_NXT, "r22", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_STP, "r23", NULL),
+	_OMAP3_BALLENTRY(I2C2_SCL, "ac15", NULL),
+	_OMAP3_BALLENTRY(I2C2_SDA, "ac14", NULL),
+	_OMAP3_BALLENTRY(I2C3_SCL, "ac13", NULL),
+	_OMAP3_BALLENTRY(I2C3_SDA, "ac12", NULL),
+	_OMAP3_BALLENTRY(I2C4_SCL, "y16", NULL),
+	_OMAP3_BALLENTRY(I2C4_SDA, "y15", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU0, "ac24", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU1, "ad24", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKR, "w19", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKX, "v18", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DR, "y18", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DX, "w18", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSR, "ab20", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSX, "aa19", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_CLKX, "t21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DR, "v19", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DX, "r20", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_FSX, "v20", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_CLKX, "w4", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DR, "v5", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DX, "v6", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_FSX, "v4", NULL),
+	_OMAP3_BALLENTRY(MCBSP_CLKS, "aa18", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CLK, "t5", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS0, "t6", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS3, "r5", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SIMO, "r4", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SOMI, "t4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CLK, "n5", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS0, "m5", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS1, "m4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SIMO, "n4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SOMI, "n3", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CLK, "m23", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CMD, "l23", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT0, "m22", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT1, "m21", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT2, "m20", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT3, "n23", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT4, "n22", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT5, "n21", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT6, "n20", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT7, "p24", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CLK, "y1", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CMD, "ab5", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT0, "ab3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT1, "y3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT2, "w3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT3, "v3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT4, "ab2", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT5, "aa2", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT6, "y2", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT7, "aa1", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT0, "ab12", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT1, "ac16", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT2, "ad17", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT3, "ad18", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT4, "ac17", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT5, "ab16", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT6, "aa15", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT1, "y7", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT2, "aa6", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKREQ, "y13", NULL),
+	_OMAP3_BALLENTRY(SYS_NIRQ, "w16", NULL),
+	_OMAP3_BALLENTRY(SYS_NRESWARM, "y10", NULL),
+	_OMAP3_BALLENTRY(SYS_OFF_MODE, "ad23", NULL),
+	_OMAP3_BALLENTRY(UART1_CTS, "ac2", NULL),
+	_OMAP3_BALLENTRY(UART1_RTS, "w6", NULL),
+	_OMAP3_BALLENTRY(UART1_RX, "v7", NULL),
+	_OMAP3_BALLENTRY(UART1_TX, "w7", NULL),
+	_OMAP3_BALLENTRY(UART3_CTS_RCTX, "a23", NULL),
+	_OMAP3_BALLENTRY(UART3_RTS_SD, "b23", NULL),
+	_OMAP3_BALLENTRY(UART3_RX_IRRX, "b24", NULL),
+	_OMAP3_BALLENTRY(UART3_TX_IRTX, "c23", NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cus_ball	 NULL
+#endif
+
+/*
+ * Signals different on CBB package comapared to superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB)
+struct omap_mux __initdata omap3_cbb_subset[] = {
+	_OMAP3_MUXENTRY(CAM_D10, 109,
+		"cam_d10", NULL, NULL, NULL,
+		"gpio_109", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D11, 110,
+		"cam_d11", NULL, NULL, NULL,
+		"gpio_110", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D2, 101,
+		"cam_d2", NULL, NULL, NULL,
+		"gpio_101", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D3, 102,
+		"cam_d3", NULL, NULL, NULL,
+		"gpio_102", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D4, 103,
+		"cam_d4", NULL, NULL, NULL,
+		"gpio_103", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D5, 104,
+		"cam_d5", NULL, NULL, NULL,
+		"gpio_104", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_FLD, 98,
+		"cam_fld", NULL, "cam_global_reset", NULL,
+		"gpio_98", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_HS, 94,
+		"cam_hs", NULL, NULL, NULL,
+		"gpio_94", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_PCLK, 97,
+		"cam_pclk", NULL, NULL, NULL,
+		"gpio_97", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_STROBE, 126,
+		"cam_strobe", NULL, NULL, NULL,
+		"gpio_126", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_VS, 95,
+		"cam_vs", NULL, NULL, NULL,
+		"gpio_95", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_WEN, 167,
+		"cam_wen", NULL, "cam_shutter", NULL,
+		"gpio_167", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA6, 76,
+		"dss_data6", NULL, "uart1_tx", NULL,
+		"gpio_76", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA7, 77,
+		"dss_data7", NULL, "uart1_rx", NULL,
+		"gpio_77", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA8, 78,
+		"dss_data8", NULL, NULL, NULL,
+		"gpio_78", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA9, 79,
+		"dss_data9", NULL, NULL, NULL,
+		"gpio_79", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_HSYNC, 67,
+		"dss_hsync", NULL, NULL, NULL,
+		"gpio_67", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_PCLK, 66,
+		"dss_pclk", NULL, NULL, NULL,
+		"gpio_66", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(ETK_CLK, 12,
+		"etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+		"gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
+	_OMAP3_MUXENTRY(ETK_CTL, 13,
+		"etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+		"gpio_13", NULL, "hsusb1_tll_clk", NULL),
+	_OMAP3_MUXENTRY(ETK_D0, 14,
+		"etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+		"gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
+	_OMAP3_MUXENTRY(ETK_D1, 15,
+		"etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+		"gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
+	_OMAP3_MUXENTRY(ETK_D10, 24,
+		"etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+		"gpio_24", NULL, "hsusb2_tll_clk", NULL),
+	_OMAP3_MUXENTRY(ETK_D11, 25,
+		"etk_d11", NULL, NULL, "hsusb2_stp",
+		"gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
+	_OMAP3_MUXENTRY(ETK_D12, 26,
+		"etk_d12", NULL, NULL, "hsusb2_dir",
+		"gpio_26", NULL, "hsusb2_tll_dir", NULL),
+	_OMAP3_MUXENTRY(ETK_D13, 27,
+		"etk_d13", NULL, NULL, "hsusb2_nxt",
+		"gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
+	_OMAP3_MUXENTRY(ETK_D14, 28,
+		"etk_d14", NULL, NULL, "hsusb2_data0",
+		"gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
+	_OMAP3_MUXENTRY(ETK_D15, 29,
+		"etk_d15", NULL, NULL, "hsusb2_data1",
+		"gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
+	_OMAP3_MUXENTRY(ETK_D2, 16,
+		"etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+		"gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
+	_OMAP3_MUXENTRY(ETK_D3, 17,
+		"etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+		"gpio_17", NULL, "hsusb1_tll_data7", NULL),
+	_OMAP3_MUXENTRY(ETK_D4, 18,
+		"etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+		"gpio_18", NULL, "hsusb1_tll_data4", NULL),
+	_OMAP3_MUXENTRY(ETK_D5, 19,
+		"etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+		"gpio_19", NULL, "hsusb1_tll_data5", NULL),
+	_OMAP3_MUXENTRY(ETK_D6, 20,
+		"etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+		"gpio_20", NULL, "hsusb1_tll_data6", NULL),
+	_OMAP3_MUXENTRY(ETK_D7, 21,
+		"etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+		"gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
+	_OMAP3_MUXENTRY(ETK_D8, 22,
+		"etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+		"gpio_22", NULL, "hsusb1_tll_dir", NULL),
+	_OMAP3_MUXENTRY(ETK_D9, 23,
+		"etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+		"gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbb_subset	NULL
+#endif
+
+/*
+ * Balls for CBB package
+ * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
+		&& defined(CONFIG_OMAP_PACKAGE_CBB)
+struct omap_ball __initdata omap3_cbb_ball[] = {
+	_OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
+	_OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
+	_OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
+	_OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
+	_OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
+	_OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
+	_OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+	_OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
+	_OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
+	_OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
+	_OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
+	_OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
+	_OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
+	_OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
+	_OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
+	_OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
+	_OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
+	_OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
+	_OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
+	_OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
+	_OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
+	_OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
+	_OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
+	_OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
+	_OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
+	_OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
+	_OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
+	_OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
+	_OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
+	_OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
+	_OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
+	_OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
+	_OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
+	_OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
+	_OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
+	_OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
+	_OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
+	_OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
+	_OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
+	_OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
+	_OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
+	_OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
+	_OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
+	_OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
+	_OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
+	_OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
+	_OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
+	_OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
+	_OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
+	_OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
+	_OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
+	_OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
+	_OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
+	_OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
+	_OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
+	_OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
+	_OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
+	_OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"),
+	_OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
+	_OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
+	_OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
+	_OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
+	_OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
+	_OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
+	_OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
+	_OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
+	_OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
+	_OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
+	_OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
+	_OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
+	_OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
+	_OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
+	_OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT4, "p27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT5, "p26", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT6, "r27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT7, "r25", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
+	_OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
+	_OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
+	_OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
+	_OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
+	_OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
+	_OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
+	_OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
+	_OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
+	_OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
+	_OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
+	_OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
+	_OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
+	_OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
+	_OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
+	_OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbb_ball	 NULL
+#endif
+
+/*
+ * Signals different on 36XX CBP package comapared to 34XX CBC package
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP)
+struct omap_mux __initdata omap36xx_cbp_subset[] = {
+	_OMAP3_MUXENTRY(CAM_D0, 99,
+		"cam_d0", NULL, "csi2_dx2", NULL,
+		"gpio_99", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D1, 100,
+		"cam_d1", NULL, "csi2_dy2", NULL,
+		"gpio_100", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D10, 109,
+		"cam_d10", "ssi2_wake", NULL, NULL,
+		"gpio_109", "hw_dbg8", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D2, 101,
+		"cam_d2", "ssi2_rdy_tx", NULL, NULL,
+		"gpio_101", "hw_dbg4", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D3, 102,
+		"cam_d3", "ssi2_dat_rx", NULL, NULL,
+		"gpio_102", "hw_dbg5", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D4, 103,
+		"cam_d4", "ssi2_flag_rx", NULL, NULL,
+		"gpio_103", "hw_dbg6", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_D5, 104,
+		"cam_d5", "ssi2_rdy_rx", NULL, NULL,
+		"gpio_104", "hw_dbg7", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_HS, 94,
+		"cam_hs", "ssi2_dat_tx", NULL, NULL,
+		"gpio_94", "hw_dbg0", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(CAM_VS, 95,
+		"cam_vs", "ssi2_flag_tx", NULL, NULL,
+		"gpio_95", "hw_dbg1", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA0, 70,
+		"dss_data0", "dsi_dx0", "uart1_cts", NULL,
+		"gpio_70", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA1, 71,
+		"dss_data1", "dsi_dy0", "uart1_rts", NULL,
+		"gpio_71", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA2, 72,
+		"dss_data2", "dsi_dx1", NULL, NULL,
+		"gpio_72", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA3, 73,
+		"dss_data3", "dsi_dy1", NULL, NULL,
+		"gpio_73", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA4, 74,
+		"dss_data4", "dsi_dx2", "uart3_rx_irrx", NULL,
+		"gpio_74", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA5, 75,
+		"dss_data5", "dsi_dy2", "uart3_tx_irtx", NULL,
+		"gpio_75", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA6, 76,
+		"dss_data6", NULL, "uart1_tx", "dssvenc656_data6",
+		"gpio_76", "hw_dbg14", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA7, 77,
+		"dss_data7", NULL, "uart1_rx", "dssvenc656_data7",
+		"gpio_77", "hw_dbg15", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA8, 78,
+		"dss_data8", NULL, "uart3_rx_irrx", NULL,
+		"gpio_78", "hw_dbg16", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(DSS_DATA9, 79,
+		"dss_data9", NULL, "uart3_tx_irtx", NULL,
+		"gpio_79", "hw_dbg17", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(ETK_D12, 26,
+		"etk_d12", "sys_drm_msecure", NULL, "hsusb2_dir",
+		"gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
+	_OMAP3_MUXENTRY(GPMC_A11, 0,
+		"gpmc_a11", NULL, NULL, NULL,
+		NULL, NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_WAIT2, 64,
+		"gpmc_wait2", NULL, "uart4_tx", NULL,
+		"gpio_64", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(GPMC_WAIT3, 65,
+		"gpmc_wait3", "sys_ndmareq1", "uart4_rx", NULL,
+		"gpio_65", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
+		"hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
+		"gpio_125", "uart2_tx", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
+		"hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
+		"gpio_130", "uart2_rx", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
+		"hsusb0_data2", NULL, "uart3_rts_sd", NULL,
+		"gpio_131", "uart2_rts", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
+		"hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
+		"gpio_169", "uart2_cts", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
+		"mcbsp1_clkr", "mcspi4_clk", "sim_cd", NULL,
+		"gpio_156", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP1_FSR, 157,
+		"mcbsp1_fsr", "adpllv2d_dithering_en1",
+		"cam_global_reset", NULL,
+		"gpio_157", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
+		"mcbsp4_clkx", "ssi1_dat_rx", NULL, NULL,
+		"gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_DR, 153,
+		"mcbsp4_dr", "ssi1_flag_rx", NULL, NULL,
+		"gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_DX, 154,
+		"mcbsp4_dx", "ssi1_rdy_rx", NULL, NULL,
+		"gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
+	_OMAP3_MUXENTRY(MCBSP4_FSX, 155,
+		"mcbsp4_fsx", "ssi1_wake", NULL, NULL,
+		"gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
+	_OMAP3_MUXENTRY(MCSPI1_CS1, 175,
+		"mcspi1_cs1", "adpllv2d_dithering_en2", NULL, "sdmmc3_cmd",
+		"gpio_175", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
+		"sad2d_mbusflag", "mad2d_sbusflag", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
+		"sad2d_mcad28", "mad2d_mcad28", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
+		"sad2d_mcad29", "mad2d_mcad29", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
+		"sad2d_mcad32", "mad2d_mcad32", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
+		"sad2d_mcad33", "mad2d_mcad33", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
+		"sad2d_mcad34", "mad2d_mcad34", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
+		"sad2d_mcad35", "mad2d_mcad35", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
+		"sad2d_mcad36", "mad2d_mcad36", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MREAD, 0,
+		"sad2d_mread", "mad2d_sread", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
+		"sad2d_mwrite", "mad2d_swrite", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
+		"sad2d_sbusflag", "mad2d_mbusflag", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SREAD, 0,
+		"sad2d_sread", "mad2d_mread", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
+		"sad2d_swrite", "mad2d_mwrite", NULL, NULL,
+		NULL, NULL, NULL, NULL),
+	_OMAP3_MUXENTRY(SDMMC1_CLK, 120,
+		"sdmmc1_clk", "ms_clk", NULL, NULL,
+		"gpio_120", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_CMD, 121,
+		"sdmmc1_cmd", "ms_bs", NULL, NULL,
+		"gpio_121", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
+		"sdmmc1_dat0", "ms_dat0", NULL, NULL,
+		"gpio_122", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
+		"sdmmc1_dat1", "ms_dat1", NULL, NULL,
+		"gpio_123", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
+		"sdmmc1_dat2", "ms_dat2", NULL, NULL,
+		"gpio_124", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
+		"sdmmc1_dat3", "ms_dat3", NULL, NULL,
+		"gpio_125", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SDRC_CKE0, 0,
+		"sdrc_cke0", NULL, NULL, NULL,
+		NULL, NULL, NULL, "safe_mode_out1"),
+	_OMAP3_MUXENTRY(SDRC_CKE1, 0,
+		"sdrc_cke1", NULL, NULL, NULL,
+		NULL, NULL, NULL, "safe_mode_out1"),
+	_OMAP3_MUXENTRY(SIM_IO, 126,
+		"sim_io", "sim_io_low_impedance", NULL, NULL,
+		"gpio_126", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SIM_CLK, 127,
+		"sim_clk", NULL, NULL, NULL,
+		"gpio_127", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SIM_PWRCTRL, 128,
+		"sim_pwrctrl", NULL, NULL, NULL,
+		"gpio_128", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SIM_RST, 129,
+		"sim_rst", NULL, NULL, NULL,
+		"gpio_129", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT0, 2,
+		"sys_boot0", NULL, NULL, "dss_data18",
+		"gpio_2", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT1, 3,
+		"sys_boot1", NULL, NULL, "dss_data19",
+		"gpio_3", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT3, 5,
+		"sys_boot3", NULL, NULL, "dss_data20",
+		"gpio_5", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT4, 6,
+		"sys_boot4", "sdmmc2_dir_dat2", NULL, "dss_data21",
+		"gpio_6", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT5, 7,
+		"sys_boot5", "sdmmc2_dir_dat3", NULL, "dss_data22",
+		"gpio_7", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(SYS_BOOT6, 8,
+		"sys_boot6", NULL, NULL, "dss_data23",
+		"gpio_8", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_CTS, 150,
+		"uart1_cts", "ssi1_rdy_tx", NULL, NULL,
+		"gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_RTS, 149,
+		"uart1_rts", "ssi1_flag_tx", NULL, NULL,
+		"gpio_149", NULL, NULL, "safe_mode"),
+	_OMAP3_MUXENTRY(UART1_TX, 148,
+		"uart1_tx", "ssi1_dat_tx", NULL, NULL,
+		"gpio_148", NULL, NULL, "safe_mode"),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap36xx_cbp_subset	NULL
+#endif
+
+/*
+ * Balls for 36XX CBP package
+ * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
+		&& defined (CONFIG_OMAP_PACKAGE_CBP)
+struct omap_ball __initdata omap36xx_cbp_ball[] = {
+	_OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
+	_OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
+	_OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
+	_OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
+	_OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
+	_OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
+	_OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+	_OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
+	_OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
+	_OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
+	_OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
+	_OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
+	_OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
+	_OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
+	_OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
+	_OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
+	_OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
+	_OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+	_OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
+	_OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
+	_OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
+	_OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
+	_OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
+	_OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
+	_OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
+	_OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
+	_OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
+	_OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
+	_OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
+	_OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
+	_OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
+	_OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
+	_OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
+	_OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
+	_OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
+	_OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
+	_OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
+	_OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
+	_OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
+	_OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
+	_OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
+	_OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
+	_OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
+	_OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
+	_OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
+	_OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
+	_OMAP3_BALLENTRY(GPMC_A11, NULL, "ac20"),
+	_OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
+	_OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
+	_OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
+	_OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
+	_OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
+	_OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
+	_OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
+	_OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
+	_OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
+	_OMAP3_BALLENTRY(GPMC_D0, "k1", "m2"),
+	_OMAP3_BALLENTRY(GPMC_D1, "l1", "m1"),
+	_OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
+	_OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
+	_OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
+	_OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
+	_OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
+	_OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
+	_OMAP3_BALLENTRY(GPMC_D2, "l2", "n2"),
+	_OMAP3_BALLENTRY(GPMC_D3, "p2", "n1"),
+	_OMAP3_BALLENTRY(GPMC_D4, "t1", "r2"),
+	_OMAP3_BALLENTRY(GPMC_D5, "v1", "r1"),
+	_OMAP3_BALLENTRY(GPMC_D6, "v2", "t2"),
+	_OMAP3_BALLENTRY(GPMC_D7, "w2", "t1"),
+	_OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"),
+	_OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
+	_OMAP3_BALLENTRY(GPMC_NADV_ALE, "f3", "w1"),
+	_OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
+	_OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS0, "g4", "y2"),
+	_OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
+	_OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
+	_OMAP3_BALLENTRY(GPMC_NOE, "g2", "v2"),
+	_OMAP3_BALLENTRY(GPMC_NWE, "f4", "v1"),
+	_OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
+	_OMAP3_BALLENTRY(GPMC_WAIT0, "m8", "ab12"),
+	_OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
+	_OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
+	_OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
+	_OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
+	_OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
+	_OMAP3_BALLENTRY(I2C1_SCL, "k21", NULL),
+	_OMAP3_BALLENTRY(I2C1_SDA, "j21", NULL),
+	_OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
+	_OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
+	_OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
+	_OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
+	_OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
+	_OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
+	_OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
+	_OMAP3_BALLENTRY(JTAG_RTCK, "aa12", NULL),
+	_OMAP3_BALLENTRY(JTAG_TCK, "aa13", NULL),
+	_OMAP3_BALLENTRY(JTAG_TDI, "aa20", NULL),
+	_OMAP3_BALLENTRY(JTAG_TDO, "aa19", NULL),
+	_OMAP3_BALLENTRY(JTAG_TMS_TMSC, "aa18", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
+	_OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
+	_OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
+	_OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
+	_OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
+	_OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
+	_OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
+	_OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
+	_OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
+	_OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
+	_OMAP3_BALLENTRY(SDRC_A0, NULL, "n22"),
+	_OMAP3_BALLENTRY(SDRC_A1, NULL, "n23"),
+	_OMAP3_BALLENTRY(SDRC_A10, NULL, "v22"),
+	_OMAP3_BALLENTRY(SDRC_A11, NULL, "v23"),
+	_OMAP3_BALLENTRY(SDRC_A12, NULL, "w22"),
+	_OMAP3_BALLENTRY(SDRC_A13, NULL, "w23"),
+	_OMAP3_BALLENTRY(SDRC_A14, NULL, "y22"),
+	_OMAP3_BALLENTRY(SDRC_A2, NULL, "p22"),
+	_OMAP3_BALLENTRY(SDRC_A3, NULL, "p23"),
+	_OMAP3_BALLENTRY(SDRC_A4, NULL, "r22"),
+	_OMAP3_BALLENTRY(SDRC_A5, NULL, "r23"),
+	_OMAP3_BALLENTRY(SDRC_A6, NULL, "t22"),
+	_OMAP3_BALLENTRY(SDRC_A7, NULL, "t23"),
+	_OMAP3_BALLENTRY(SDRC_A8, NULL, "u22"),
+	_OMAP3_BALLENTRY(SDRC_A9, NULL, "u23"),
+	_OMAP3_BALLENTRY(SDRC_BA0, "h9", "ab21"),
+	_OMAP3_BALLENTRY(SDRC_BA1, "h10", "ac21"),
+	_OMAP3_BALLENTRY(SDRC_CKE0, "h16", "j22"),
+	_OMAP3_BALLENTRY(SDRC_CKE1, "h17", "j23"),
+	_OMAP3_BALLENTRY(SDRC_CLK, "a13", "a11"),
+	_OMAP3_BALLENTRY(SDRC_D0, NULL, "j2"),
+	_OMAP3_BALLENTRY(SDRC_D1, NULL, "j1"),
+	_OMAP3_BALLENTRY(SDRC_D10, "c15", "b14"),
+	_OMAP3_BALLENTRY(SDRC_D11, "b16", "a14"),
+	_OMAP3_BALLENTRY(SDRC_D12, "d17", "b16"),
+	_OMAP3_BALLENTRY(SDRC_D13, "c17", "a16"),
+	_OMAP3_BALLENTRY(SDRC_D14, "b17", "b19"),
+	_OMAP3_BALLENTRY(SDRC_D15, "d18", "a19"),
+	_OMAP3_BALLENTRY(SDRC_D16, NULL, "b3"),
+	_OMAP3_BALLENTRY(SDRC_D17, NULL, "a3"),
+	_OMAP3_BALLENTRY(SDRC_D18, NULL, "b5"),
+	_OMAP3_BALLENTRY(SDRC_D19, NULL, "a5"),
+	_OMAP3_BALLENTRY(SDRC_D2, NULL, "g2"),
+	_OMAP3_BALLENTRY(SDRC_D20, NULL, "b8"),
+	_OMAP3_BALLENTRY(SDRC_D21, NULL, "a8"),
+	_OMAP3_BALLENTRY(SDRC_D22, NULL, "b9"),
+	_OMAP3_BALLENTRY(SDRC_D23, NULL, "a9"),
+	_OMAP3_BALLENTRY(SDRC_D24, NULL, "b21"),
+	_OMAP3_BALLENTRY(SDRC_D25, NULL, "a21"),
+	_OMAP3_BALLENTRY(SDRC_D26, NULL, "d22"),
+	_OMAP3_BALLENTRY(SDRC_D27, NULL, "d23"),
+	_OMAP3_BALLENTRY(SDRC_D28, NULL, "e22"),
+	_OMAP3_BALLENTRY(SDRC_D29, NULL, "e23"),
+	_OMAP3_BALLENTRY(SDRC_D3, NULL, "g1"),
+	_OMAP3_BALLENTRY(SDRC_D30, NULL, "g22"),
+	_OMAP3_BALLENTRY(SDRC_D31, NULL, "g23"),
+	_OMAP3_BALLENTRY(SDRC_D4, NULL, "f2"),
+	_OMAP3_BALLENTRY(SDRC_D5, NULL, "f1"),
+	_OMAP3_BALLENTRY(SDRC_D6, NULL, "d2"),
+	_OMAP3_BALLENTRY(SDRC_D7, NULL, "d1"),
+	_OMAP3_BALLENTRY(SDRC_D8, "c14", "b13"),
+	_OMAP3_BALLENTRY(SDRC_D9, "b14", "a13"),
+	_OMAP3_BALLENTRY(SDRC_DM0, NULL, "c1"),
+	_OMAP3_BALLENTRY(SDRC_DM1, "a16", "a17"),
+	_OMAP3_BALLENTRY(SDRC_DM2, NULL, "a6"),
+	_OMAP3_BALLENTRY(SDRC_DM3, NULL, "a20"),
+	_OMAP3_BALLENTRY(SDRC_DQS0, NULL, "c2"),
+	_OMAP3_BALLENTRY(SDRC_DQS1, "a17", "b17"),
+	_OMAP3_BALLENTRY(SDRC_DQS2, NULL, "b6"),
+	_OMAP3_BALLENTRY(SDRC_DQS3, NULL, "b20"),
+	_OMAP3_BALLENTRY(SDRC_NCAS, "h13", "l22"),
+	_OMAP3_BALLENTRY(SDRC_NCLK, "a14", "b11"),
+	_OMAP3_BALLENTRY(SDRC_NCS0, "h11", "m22"),
+	_OMAP3_BALLENTRY(SDRC_NCS1, "h12", "m23"),
+	_OMAP3_BALLENTRY(SDRC_NRAS, "h14", "l23"),
+	_OMAP3_BALLENTRY(SDRC_NWE, "h15", "k23"),
+	_OMAP3_BALLENTRY(SIM_CLK, "p26", NULL),
+	_OMAP3_BALLENTRY(SIM_IO, "p27", NULL),
+	_OMAP3_BALLENTRY(SIM_PWRCTRL, "r27", NULL),
+	_OMAP3_BALLENTRY(SIM_RST, "r25", NULL),
+	_OMAP3_BALLENTRY(SYS_32K, "ae25", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
+	_OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
+	_OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
+	_OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
+	_OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
+	_OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
+	_OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
+	_OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
+	_OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
+	_OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
+	_OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
+	_OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
+	_OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
+	_OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
+	_OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
+	_OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
+	_OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
+	_OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
+	{ .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap36xx_cbp_ball	 NULL
+#endif
+
+int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+	struct omap_mux *package_subset;
+	struct omap_ball *package_balls;
+
+	switch (flags & OMAP_PACKAGE_MASK) {
+	case (OMAP_PACKAGE_CBC):
+		package_subset = omap3_cbc_subset;
+		package_balls = omap3_cbc_ball;
+		break;
+	case (OMAP_PACKAGE_CBB):
+		package_subset = omap3_cbb_subset;
+		package_balls = omap3_cbb_ball;
+		break;
+	case (OMAP_PACKAGE_CUS):
+		package_subset = omap3_cus_subset;
+		package_balls = omap3_cus_ball;
+		break;
+	case (OMAP_PACKAGE_CBP):
+		package_subset = omap36xx_cbp_subset;
+		package_balls = omap36xx_cbp_ball;
+		break;
+	default:
+		printk(KERN_ERR "mux: Unknown omap package, mux disabled\n");
+		return -EINVAL;
+	}
+
+	return omap_mux_init(OMAP3_CONTROL_PADCONF_MUX_PBASE,
+			     OMAP3_CONTROL_PADCONF_MUX_SIZE,
+				omap3_muxmodes, package_subset, board_subset,
+				package_balls);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux34xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux34xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP3_CONTROL_PADCONF_MUX_PBASE				0x48002030LU
+
+#define OMAP3_MUX(mode0, mux_value)					\
+{									\
+	.reg_offset	= (OMAP3_CONTROL_PADCONF_##mode0##_OFFSET),	\
+	.value		= (mux_value),					\
+}
+
+/*
+ * OMAP3 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM.  Add 0x48002030 to these values to get the
+ * absolute addresses.  The name in the macro is the mode-0 name of
+ * the pin.  NOTE: These registers are 16-bits wide.
+ *
+ * Note that 34XX TRM uses MMC instead of SDMMC and SAD2D instead
+ * of CHASSIS for some registers. For the defines, we follow the
+ * 36XX naming, and use SDMMC and CHASSIS.
+ */
+#define OMAP3_CONTROL_PADCONF_SDRC_D0_OFFSET			0x000
+#define OMAP3_CONTROL_PADCONF_SDRC_D1_OFFSET			0x002
+#define OMAP3_CONTROL_PADCONF_SDRC_D2_OFFSET			0x004
+#define OMAP3_CONTROL_PADCONF_SDRC_D3_OFFSET			0x006
+#define OMAP3_CONTROL_PADCONF_SDRC_D4_OFFSET			0x008
+#define OMAP3_CONTROL_PADCONF_SDRC_D5_OFFSET			0x00a
+#define OMAP3_CONTROL_PADCONF_SDRC_D6_OFFSET			0x00c
+#define OMAP3_CONTROL_PADCONF_SDRC_D7_OFFSET			0x00e
+#define OMAP3_CONTROL_PADCONF_SDRC_D8_OFFSET			0x010
+#define OMAP3_CONTROL_PADCONF_SDRC_D9_OFFSET			0x012
+#define OMAP3_CONTROL_PADCONF_SDRC_D10_OFFSET			0x014
+#define OMAP3_CONTROL_PADCONF_SDRC_D11_OFFSET			0x016
+#define OMAP3_CONTROL_PADCONF_SDRC_D12_OFFSET			0x018
+#define OMAP3_CONTROL_PADCONF_SDRC_D13_OFFSET			0x01a
+#define OMAP3_CONTROL_PADCONF_SDRC_D14_OFFSET			0x01c
+#define OMAP3_CONTROL_PADCONF_SDRC_D15_OFFSET			0x01e
+#define OMAP3_CONTROL_PADCONF_SDRC_D16_OFFSET			0x020
+#define OMAP3_CONTROL_PADCONF_SDRC_D17_OFFSET			0x022
+#define OMAP3_CONTROL_PADCONF_SDRC_D18_OFFSET			0x024
+#define OMAP3_CONTROL_PADCONF_SDRC_D19_OFFSET			0x026
+#define OMAP3_CONTROL_PADCONF_SDRC_D20_OFFSET			0x028
+#define OMAP3_CONTROL_PADCONF_SDRC_D21_OFFSET			0x02a
+#define OMAP3_CONTROL_PADCONF_SDRC_D22_OFFSET			0x02c
+#define OMAP3_CONTROL_PADCONF_SDRC_D23_OFFSET			0x02e
+#define OMAP3_CONTROL_PADCONF_SDRC_D24_OFFSET			0x030
+#define OMAP3_CONTROL_PADCONF_SDRC_D25_OFFSET			0x032
+#define OMAP3_CONTROL_PADCONF_SDRC_D26_OFFSET			0x034
+#define OMAP3_CONTROL_PADCONF_SDRC_D27_OFFSET			0x036
+#define OMAP3_CONTROL_PADCONF_SDRC_D28_OFFSET			0x038
+#define OMAP3_CONTROL_PADCONF_SDRC_D29_OFFSET			0x03a
+#define OMAP3_CONTROL_PADCONF_SDRC_D30_OFFSET			0x03c
+#define OMAP3_CONTROL_PADCONF_SDRC_D31_OFFSET			0x03e
+#define OMAP3_CONTROL_PADCONF_SDRC_CLK_OFFSET			0x040
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS0_OFFSET			0x042
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS1_OFFSET			0x044
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS2_OFFSET			0x046
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS3_OFFSET			0x048
+#define OMAP3_CONTROL_PADCONF_GPMC_A1_OFFSET			0x04a
+#define OMAP3_CONTROL_PADCONF_GPMC_A2_OFFSET			0x04c
+#define OMAP3_CONTROL_PADCONF_GPMC_A3_OFFSET			0x04e
+#define OMAP3_CONTROL_PADCONF_GPMC_A4_OFFSET			0x050
+#define OMAP3_CONTROL_PADCONF_GPMC_A5_OFFSET			0x052
+#define OMAP3_CONTROL_PADCONF_GPMC_A6_OFFSET			0x054
+#define OMAP3_CONTROL_PADCONF_GPMC_A7_OFFSET			0x056
+#define OMAP3_CONTROL_PADCONF_GPMC_A8_OFFSET			0x058
+#define OMAP3_CONTROL_PADCONF_GPMC_A9_OFFSET			0x05a
+#define OMAP3_CONTROL_PADCONF_GPMC_A10_OFFSET			0x05c
+#define OMAP3_CONTROL_PADCONF_GPMC_D0_OFFSET			0x05e
+#define OMAP3_CONTROL_PADCONF_GPMC_D1_OFFSET			0x060
+#define OMAP3_CONTROL_PADCONF_GPMC_D2_OFFSET			0x062
+#define OMAP3_CONTROL_PADCONF_GPMC_D3_OFFSET			0x064
+#define OMAP3_CONTROL_PADCONF_GPMC_D4_OFFSET			0x066
+#define OMAP3_CONTROL_PADCONF_GPMC_D5_OFFSET			0x068
+#define OMAP3_CONTROL_PADCONF_GPMC_D6_OFFSET			0x06a
+#define OMAP3_CONTROL_PADCONF_GPMC_D7_OFFSET			0x06c
+#define OMAP3_CONTROL_PADCONF_GPMC_D8_OFFSET			0x06e
+#define OMAP3_CONTROL_PADCONF_GPMC_D9_OFFSET			0x070
+#define OMAP3_CONTROL_PADCONF_GPMC_D10_OFFSET			0x072
+#define OMAP3_CONTROL_PADCONF_GPMC_D11_OFFSET			0x074
+#define OMAP3_CONTROL_PADCONF_GPMC_D12_OFFSET			0x076
+#define OMAP3_CONTROL_PADCONF_GPMC_D13_OFFSET			0x078
+#define OMAP3_CONTROL_PADCONF_GPMC_D14_OFFSET			0x07a
+#define OMAP3_CONTROL_PADCONF_GPMC_D15_OFFSET			0x07c
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS0_OFFSET			0x07e
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS1_OFFSET			0x080
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS2_OFFSET			0x082
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS3_OFFSET			0x084
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS4_OFFSET			0x086
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS5_OFFSET			0x088
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS6_OFFSET			0x08a
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS7_OFFSET			0x08c
+#define OMAP3_CONTROL_PADCONF_GPMC_CLK_OFFSET			0x08e
+#define OMAP3_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET		0x090
+#define OMAP3_CONTROL_PADCONF_GPMC_NOE_OFFSET			0x092
+#define OMAP3_CONTROL_PADCONF_GPMC_NWE_OFFSET			0x094
+#define OMAP3_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET		0x096
+#define OMAP3_CONTROL_PADCONF_GPMC_NBE1_OFFSET			0x098
+#define OMAP3_CONTROL_PADCONF_GPMC_NWP_OFFSET			0x09a
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT0_OFFSET			0x09c
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT1_OFFSET			0x09e
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT2_OFFSET			0x0a0
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT3_OFFSET			0x0a2
+#define OMAP3_CONTROL_PADCONF_DSS_PCLK_OFFSET			0x0a4
+#define OMAP3_CONTROL_PADCONF_DSS_HSYNC_OFFSET			0x0a6
+#define OMAP3_CONTROL_PADCONF_DSS_VSYNC_OFFSET			0x0a8
+#define OMAP3_CONTROL_PADCONF_DSS_ACBIAS_OFFSET			0x0aa
+#define OMAP3_CONTROL_PADCONF_DSS_DATA0_OFFSET			0x0ac
+#define OMAP3_CONTROL_PADCONF_DSS_DATA1_OFFSET			0x0ae
+#define OMAP3_CONTROL_PADCONF_DSS_DATA2_OFFSET			0x0b0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA3_OFFSET			0x0b2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA4_OFFSET			0x0b4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA5_OFFSET			0x0b6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA6_OFFSET			0x0b8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA7_OFFSET			0x0ba
+#define OMAP3_CONTROL_PADCONF_DSS_DATA8_OFFSET			0x0bc
+#define OMAP3_CONTROL_PADCONF_DSS_DATA9_OFFSET			0x0be
+#define OMAP3_CONTROL_PADCONF_DSS_DATA10_OFFSET			0x0c0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA11_OFFSET			0x0c2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA12_OFFSET			0x0c4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA13_OFFSET			0x0c6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA14_OFFSET			0x0c8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA15_OFFSET			0x0ca
+#define OMAP3_CONTROL_PADCONF_DSS_DATA16_OFFSET			0x0cc
+#define OMAP3_CONTROL_PADCONF_DSS_DATA17_OFFSET			0x0ce
+#define OMAP3_CONTROL_PADCONF_DSS_DATA18_OFFSET			0x0d0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA19_OFFSET			0x0d2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA20_OFFSET			0x0d4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA21_OFFSET			0x0d6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA22_OFFSET			0x0d8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA23_OFFSET			0x0da
+#define OMAP3_CONTROL_PADCONF_CAM_HS_OFFSET			0x0dc
+#define OMAP3_CONTROL_PADCONF_CAM_VS_OFFSET			0x0de
+#define OMAP3_CONTROL_PADCONF_CAM_XCLKA_OFFSET			0x0e0
+#define OMAP3_CONTROL_PADCONF_CAM_PCLK_OFFSET			0x0e2
+#define OMAP3_CONTROL_PADCONF_CAM_FLD_OFFSET			0x0e4
+#define OMAP3_CONTROL_PADCONF_CAM_D0_OFFSET			0x0e6
+#define OMAP3_CONTROL_PADCONF_CAM_D1_OFFSET			0x0e8
+#define OMAP3_CONTROL_PADCONF_CAM_D2_OFFSET			0x0ea
+#define OMAP3_CONTROL_PADCONF_CAM_D3_OFFSET			0x0ec
+#define OMAP3_CONTROL_PADCONF_CAM_D4_OFFSET			0x0ee
+#define OMAP3_CONTROL_PADCONF_CAM_D5_OFFSET			0x0f0
+#define OMAP3_CONTROL_PADCONF_CAM_D6_OFFSET			0x0f2
+#define OMAP3_CONTROL_PADCONF_CAM_D7_OFFSET			0x0f4
+#define OMAP3_CONTROL_PADCONF_CAM_D8_OFFSET			0x0f6
+#define OMAP3_CONTROL_PADCONF_CAM_D9_OFFSET			0x0f8
+#define OMAP3_CONTROL_PADCONF_CAM_D10_OFFSET			0x0fa
+#define OMAP3_CONTROL_PADCONF_CAM_D11_OFFSET			0x0fc
+#define OMAP3_CONTROL_PADCONF_CAM_XCLKB_OFFSET			0x0fe
+#define OMAP3_CONTROL_PADCONF_CAM_WEN_OFFSET			0x100
+#define OMAP3_CONTROL_PADCONF_CAM_STROBE_OFFSET			0x102
+#define OMAP3_CONTROL_PADCONF_CSI2_DX0_OFFSET			0x104
+#define OMAP3_CONTROL_PADCONF_CSI2_DY0_OFFSET			0x106
+#define OMAP3_CONTROL_PADCONF_CSI2_DX1_OFFSET			0x108
+#define OMAP3_CONTROL_PADCONF_CSI2_DY1_OFFSET			0x10a
+#define OMAP3_CONTROL_PADCONF_MCBSP2_FSX_OFFSET			0x10c
+#define OMAP3_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET		0x10e
+#define OMAP3_CONTROL_PADCONF_MCBSP2_DR_OFFSET			0x110
+#define OMAP3_CONTROL_PADCONF_MCBSP2_DX_OFFSET			0x112
+#define OMAP3_CONTROL_PADCONF_SDMMC1_CLK_OFFSET			0x114
+#define OMAP3_CONTROL_PADCONF_SDMMC1_CMD_OFFSET			0x116
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET		0x118
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET		0x11a
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET		0x11c
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET		0x11e
+
+/* SDMMC1_DAT4 - DAT7 are SIM_IO SIM_CLK SIM_PWRCTRL and SIM_RST on 36xx */
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT4_OFFSET		0x120
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT5_OFFSET		0x122
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT6_OFFSET		0x124
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT7_OFFSET		0x126
+
+#define OMAP3_CONTROL_PADCONF_SDMMC2_CLK_OFFSET			0x128
+#define OMAP3_CONTROL_PADCONF_SDMMC2_CMD_OFFSET			0x12a
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET		0x12c
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET		0x12e
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET		0x130
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET		0x132
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT4_OFFSET		0x134
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT5_OFFSET		0x136
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT6_OFFSET		0x138
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT7_OFFSET		0x13a
+#define OMAP3_CONTROL_PADCONF_MCBSP3_DX_OFFSET			0x13c
+#define OMAP3_CONTROL_PADCONF_MCBSP3_DR_OFFSET			0x13e
+#define OMAP3_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET		0x140
+#define OMAP3_CONTROL_PADCONF_MCBSP3_FSX_OFFSET			0x142
+#define OMAP3_CONTROL_PADCONF_UART2_CTS_OFFSET			0x144
+#define OMAP3_CONTROL_PADCONF_UART2_RTS_OFFSET			0x146
+#define OMAP3_CONTROL_PADCONF_UART2_TX_OFFSET			0x148
+#define OMAP3_CONTROL_PADCONF_UART2_RX_OFFSET			0x14a
+#define OMAP3_CONTROL_PADCONF_UART1_TX_OFFSET			0x14c
+#define OMAP3_CONTROL_PADCONF_UART1_RTS_OFFSET			0x14e
+#define OMAP3_CONTROL_PADCONF_UART1_CTS_OFFSET			0x150
+#define OMAP3_CONTROL_PADCONF_UART1_RX_OFFSET			0x152
+#define OMAP3_CONTROL_PADCONF_MCBSP4_CLKX_OFFSET		0x154
+#define OMAP3_CONTROL_PADCONF_MCBSP4_DR_OFFSET			0x156
+#define OMAP3_CONTROL_PADCONF_MCBSP4_DX_OFFSET			0x158
+#define OMAP3_CONTROL_PADCONF_MCBSP4_FSX_OFFSET			0x15a
+#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET		0x15c
+#define OMAP3_CONTROL_PADCONF_MCBSP1_FSR_OFFSET			0x15e
+#define OMAP3_CONTROL_PADCONF_MCBSP1_DX_OFFSET			0x160
+#define OMAP3_CONTROL_PADCONF_MCBSP1_DR_OFFSET			0x162
+#define OMAP3_CONTROL_PADCONF_MCBSP_CLKS_OFFSET			0x164
+#define OMAP3_CONTROL_PADCONF_MCBSP1_FSX_OFFSET			0x166
+#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET		0x168
+#define OMAP3_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET		0x16a
+#define OMAP3_CONTROL_PADCONF_UART3_RTS_SD_OFFSET		0x16c
+#define OMAP3_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET		0x16e
+#define OMAP3_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET		0x170
+#define OMAP3_CONTROL_PADCONF_HSUSB0_CLK_OFFSET			0x172
+#define OMAP3_CONTROL_PADCONF_HSUSB0_STP_OFFSET			0x174
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DIR_OFFSET			0x176
+#define OMAP3_CONTROL_PADCONF_HSUSB0_NXT_OFFSET			0x178
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA0_OFFSET		0x17a
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA1_OFFSET		0x17c
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA2_OFFSET		0x17e
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA3_OFFSET		0x180
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA4_OFFSET		0x182
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA5_OFFSET		0x184
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA6_OFFSET		0x186
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA7_OFFSET		0x188
+#define OMAP3_CONTROL_PADCONF_I2C1_SCL_OFFSET			0x18a
+#define OMAP3_CONTROL_PADCONF_I2C1_SDA_OFFSET			0x18c
+#define OMAP3_CONTROL_PADCONF_I2C2_SCL_OFFSET			0x18e
+#define OMAP3_CONTROL_PADCONF_I2C2_SDA_OFFSET			0x190
+#define OMAP3_CONTROL_PADCONF_I2C3_SCL_OFFSET			0x192
+#define OMAP3_CONTROL_PADCONF_I2C3_SDA_OFFSET			0x194
+#define OMAP3_CONTROL_PADCONF_HDQ_SIO_OFFSET			0x196
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CLK_OFFSET			0x198
+#define OMAP3_CONTROL_PADCONF_MCSPI1_SIMO_OFFSET		0x19a
+#define OMAP3_CONTROL_PADCONF_MCSPI1_SOMI_OFFSET		0x19c
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS0_OFFSET			0x19e
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS1_OFFSET			0x1a0
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS2_OFFSET			0x1a2
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS3_OFFSET			0x1a4
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CLK_OFFSET			0x1a6
+#define OMAP3_CONTROL_PADCONF_MCSPI2_SIMO_OFFSET		0x1a8
+#define OMAP3_CONTROL_PADCONF_MCSPI2_SOMI_OFFSET		0x1aa
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CS0_OFFSET			0x1ac
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CS1_OFFSET			0x1ae
+#define OMAP3_CONTROL_PADCONF_SYS_NIRQ_OFFSET			0x1b0
+#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT2_OFFSET		0x1b2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD0_OFFSET		0x1b4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD1_OFFSET		0x1b6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD2_OFFSET		0x1b8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD3_OFFSET		0x1ba
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD4_OFFSET		0x1bc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD5_OFFSET		0x1be
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD6_OFFSET		0x1c0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD7_OFFSET		0x1c2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD8_OFFSET		0x1c4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD9_OFFSET		0x1c6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD10_OFFSET		0x1c8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD11_OFFSET		0x1ca
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD12_OFFSET		0x1cc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD13_OFFSET		0x1ce
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD14_OFFSET		0x1d0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD15_OFFSET		0x1d2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD16_OFFSET		0x1d4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD17_OFFSET		0x1d6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD18_OFFSET		0x1d8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD19_OFFSET		0x1da
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD20_OFFSET		0x1dc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD21_OFFSET		0x1de
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD22_OFFSET		0x1e0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD23_OFFSET		0x1e2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD24_OFFSET		0x1e4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD25_OFFSET		0x1e6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD26_OFFSET		0x1e8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD27_OFFSET		0x1ea
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD28_OFFSET		0x1ec
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD29_OFFSET		0x1ee
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD30_OFFSET		0x1f0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD31_OFFSET		0x1f2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD32_OFFSET		0x1f4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD33_OFFSET		0x1f6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD34_OFFSET		0x1f8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD35_OFFSET		0x1fa
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD36_OFFSET		0x1fc
+
+/* Note that 34xx TRM has SAD2D instead of CHASSIS for these */
+#define OMAP3_CONTROL_PADCONF_CHASSIS_CLK26MI_OFFSET		0x1fe
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESPWRON_OFFSET		0x200
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESWARW_OFFSET		0x202
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NIRQ_OFFSET		0x204
+#define OMAP3_CONTROL_PADCONF_CHASSIS_FIQ_OFFSET		0x206
+#define OMAP3_CONTROL_PADCONF_CHASSIS_ARMIRQ_OFFSET		0x208
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IVAIRQ_OFFSET		0x20a
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ0_OFFSET		0x20c
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ1_OFFSET		0x20e
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ2_OFFSET		0x210
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ3_OFFSET		0x212
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NTRST_OFFSET		0x214
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TDI_OFFSET		0x216
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TDO_OFFSET		0x218
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TMS_OFFSET		0x21a
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TCK_OFFSET		0x21c
+#define OMAP3_CONTROL_PADCONF_CHASSIS_RTCK_OFFSET		0x21e
+#define OMAP3_CONTROL_PADCONF_CHASSIS_MSTDBY_OFFSET		0x220
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEREQ_OFFSET		0x222
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEACK_OFFSET		0x224
+
+#define OMAP3_CONTROL_PADCONF_SAD2D_MWRITE_OFFSET		0x226
+#define OMAP3_CONTROL_PADCONF_SAD2D_SWRITE_OFFSET		0x228
+#define OMAP3_CONTROL_PADCONF_SAD2D_MREAD_OFFSET		0x22a
+#define OMAP3_CONTROL_PADCONF_SAD2D_SREAD_OFFSET		0x22c
+#define OMAP3_CONTROL_PADCONF_SAD2D_MBUSFLAG_OFFSET		0x22e
+#define OMAP3_CONTROL_PADCONF_SAD2D_SBUSFLAG_OFFSET		0x230
+#define OMAP3_CONTROL_PADCONF_SDRC_CKE0_OFFSET			0x232
+#define OMAP3_CONTROL_PADCONF_SDRC_CKE1_OFFSET			0x234
+
+/* 36xx only */
+#define OMAP3_CONTROL_PADCONF_GPMC_A11_OFFSET			0x236
+#define OMAP3_CONTROL_PADCONF_SDRC_BA0_OFFSET			0x570
+#define OMAP3_CONTROL_PADCONF_SDRC_BA1_OFFSET			0x572
+#define OMAP3_CONTROL_PADCONF_SDRC_A0_OFFSET			0x574
+#define OMAP3_CONTROL_PADCONF_SDRC_A1_OFFSET			0x576
+#define OMAP3_CONTROL_PADCONF_SDRC_A2_OFFSET			0x578
+#define OMAP3_CONTROL_PADCONF_SDRC_A3_OFFSET			0x57a
+#define OMAP3_CONTROL_PADCONF_SDRC_A4_OFFSET			0x57c
+#define OMAP3_CONTROL_PADCONF_SDRC_A5_OFFSET			0x57e
+#define OMAP3_CONTROL_PADCONF_SDRC_A6_OFFSET			0x580
+#define OMAP3_CONTROL_PADCONF_SDRC_A7_OFFSET			0x582
+#define OMAP3_CONTROL_PADCONF_SDRC_A8_OFFSET			0x584
+#define OMAP3_CONTROL_PADCONF_SDRC_A9_OFFSET			0x586
+#define OMAP3_CONTROL_PADCONF_SDRC_A10_OFFSET			0x588
+#define OMAP3_CONTROL_PADCONF_SDRC_A11_OFFSET			0x58a
+#define OMAP3_CONTROL_PADCONF_SDRC_A12_OFFSET			0x58c
+#define OMAP3_CONTROL_PADCONF_SDRC_A13_OFFSET			0x58e
+#define OMAP3_CONTROL_PADCONF_SDRC_A14_OFFSET			0x590
+#define OMAP3_CONTROL_PADCONF_SDRC_NCS0_OFFSET			0x592
+#define OMAP3_CONTROL_PADCONF_SDRC_NCS1_OFFSET			0x594
+#define OMAP3_CONTROL_PADCONF_SDRC_NCLK_OFFSET			0x596
+#define OMAP3_CONTROL_PADCONF_SDRC_NRAS_OFFSET			0x598
+#define OMAP3_CONTROL_PADCONF_SDRC_NCAS_OFFSET			0x59a
+#define OMAP3_CONTROL_PADCONF_SDRC_NWE_OFFSET			0x59c
+#define OMAP3_CONTROL_PADCONF_SDRC_DM0_OFFSET			0x59e
+#define OMAP3_CONTROL_PADCONF_SDRC_DM1_OFFSET			0x5a0
+#define OMAP3_CONTROL_PADCONF_SDRC_DM2_OFFSET			0x5a2
+#define OMAP3_CONTROL_PADCONF_SDRC_DM3_OFFSET			0x5a4
+
+/* 36xx only, these are SDMMC1_DAT4 - DAT7 on 34xx */
+#define OMAP3_CONTROL_PADCONF_SIM_IO_OFFSET			0x120
+#define OMAP3_CONTROL_PADCONF_SIM_CLK_OFFSET			0x122
+#define OMAP3_CONTROL_PADCONF_SIM_PWRCTRL_OFFSET		0x124
+#define OMAP3_CONTROL_PADCONF_SIM_RST_OFFSET			0x126
+
+#define OMAP3_CONTROL_PADCONF_ETK_CLK_OFFSET			0x5a8
+#define OMAP3_CONTROL_PADCONF_ETK_CTL_OFFSET			0x5aa
+#define OMAP3_CONTROL_PADCONF_ETK_D0_OFFSET			0x5ac
+#define OMAP3_CONTROL_PADCONF_ETK_D1_OFFSET			0x5ae
+#define OMAP3_CONTROL_PADCONF_ETK_D2_OFFSET			0x5b0
+#define OMAP3_CONTROL_PADCONF_ETK_D3_OFFSET			0x5b2
+#define OMAP3_CONTROL_PADCONF_ETK_D4_OFFSET			0x5b4
+#define OMAP3_CONTROL_PADCONF_ETK_D5_OFFSET			0x5b6
+#define OMAP3_CONTROL_PADCONF_ETK_D6_OFFSET			0x5b8
+#define OMAP3_CONTROL_PADCONF_ETK_D7_OFFSET			0x5ba
+#define OMAP3_CONTROL_PADCONF_ETK_D8_OFFSET			0x5bc
+#define OMAP3_CONTROL_PADCONF_ETK_D9_OFFSET			0x5be
+#define OMAP3_CONTROL_PADCONF_ETK_D10_OFFSET			0x5c0
+#define OMAP3_CONTROL_PADCONF_ETK_D11_OFFSET			0x5c2
+#define OMAP3_CONTROL_PADCONF_ETK_D12_OFFSET			0x5c4
+#define OMAP3_CONTROL_PADCONF_ETK_D13_OFFSET			0x5c6
+#define OMAP3_CONTROL_PADCONF_ETK_D14_OFFSET			0x5c8
+#define OMAP3_CONTROL_PADCONF_ETK_D15_OFFSET			0x5ca
+#define OMAP3_CONTROL_PADCONF_I2C4_SCL_OFFSET			0x9d0
+#define OMAP3_CONTROL_PADCONF_I2C4_SDA_OFFSET			0x9d2
+#define OMAP3_CONTROL_PADCONF_SYS_32K_OFFSET			0x9d4
+#define OMAP3_CONTROL_PADCONF_SYS_CLKREQ_OFFSET			0x9d6
+#define OMAP3_CONTROL_PADCONF_SYS_NRESWARM_OFFSET		0x9d8
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT0_OFFSET			0x9da
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT1_OFFSET			0x9dc
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT2_OFFSET			0x9de
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT3_OFFSET			0x9e0
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT4_OFFSET			0x9e2
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT5_OFFSET			0x9e4
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT6_OFFSET			0x9e6
+#define OMAP3_CONTROL_PADCONF_SYS_OFF_MODE_OFFSET		0x9e8
+#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT1_OFFSET		0x9ea
+#define OMAP3_CONTROL_PADCONF_JTAG_NTRST_OFFSET			0x9ec
+#define OMAP3_CONTROL_PADCONF_JTAG_TCK_OFFSET			0x9ee
+#define OMAP3_CONTROL_PADCONF_JTAG_TMS_TMSC_OFFSET		0x9f0
+#define OMAP3_CONTROL_PADCONF_JTAG_TDI_OFFSET			0x9f2
+#define OMAP3_CONTROL_PADCONF_JTAG_EMU0_OFFSET			0x9f4
+#define OMAP3_CONTROL_PADCONF_JTAG_EMU1_OFFSET			0x9f6
+#define OMAP3_CONTROL_PADCONF_SAD2D_SWAKEUP_OFFSET		0xa1c
+#define OMAP3_CONTROL_PADCONF_JTAG_RTCK_OFFSET			0xa1e
+#define OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET			0xa20
+
+#define OMAP3_CONTROL_PADCONF_MUX_SIZE				\
+		(OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET + 0x2)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,19 +27,60 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
 
 #include <asm/system.h>
 
-#include <mach/control.h>
-#include <mach/mux.h>
+#include <plat/control.h>
+#include <plat/mux.h>
 
-#ifdef CONFIG_OMAP_MUX
+#include "mux.h"
+
+#define OMAP_MUX_BASE_OFFSET		0x30	/* Offset from CTRL_BASE */
+#define OMAP_MUX_BASE_SZ		0x5ca
+
+struct omap_mux_entry {
+	struct omap_mux		mux;
+	struct list_head	node;
+};
+
+static unsigned long mux_phys;
+static void __iomem *mux_base;
+
+u16 omap_mux_read(u16 reg)
+{
+	if (cpu_is_omap24xx())
+		return __raw_readb(mux_base + reg);
+	else
+		return __raw_readw(mux_base + reg);
+}
+
+void omap_mux_write(u16 val, u16 reg)
+{
+	if (cpu_is_omap24xx())
+		__raw_writeb(val, mux_base + reg);
+	else
+		__raw_writew(val, mux_base + reg);
+}
+
+void omap_mux_write_array(struct omap_board_mux *board_mux)
+{
+	while (board_mux->reg_offset !=  OMAP_MUX_TERMINATOR) {
+		omap_mux_write(board_mux->value, board_mux->reg_offset);
+		board_mux++;
+	}
+}
+
+#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_OMAP_MUX)
 
 static struct omap_mux_cfg arch_mux_cfg;
 
 /* NOTE: See mux.h for the enumeration */
 
-#ifdef CONFIG_ARCH_OMAP24XX
 static struct pin_config __initdata_or_module omap24xx_pins[] = {
 /*
  *	description			mux	mux	pull	pull	debug
@@ -249,327 +290,14 @@ MUX_CFG_24XX("AF19_2430_GPIO_85",	0x0113
 
 #define OMAP24XX_PINS_SZ	ARRAY_SIZE(omap24xx_pins)
 
-#else
-#define omap24xx_pins		NULL
-#define OMAP24XX_PINS_SZ	0
-#endif	/* CONFIG_ARCH_OMAP24XX */
-
-#ifdef CONFIG_ARCH_OMAP34XX
-static struct pin_config __initdata_or_module omap34xx_pins[] = {
-/*
- *		Name, reg-offset,
- *		mux-mode | [active-mode | off-mode]
- */
-
-/* 34xx I2C */
-MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-
-/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
-MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-
-/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
-MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
-
-/* TLL - HSUSB: 12-pin TLL Port 1*/
-MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-
-/* TLL - HSUSB: 12-pin TLL Port 2*/
-MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
-
-/* TLL - HSUSB: 12-pin TLL Port 3*/
-MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-
-/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
-MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
-
-/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
-MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de,
-		OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
-
-/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
-MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a,
-		OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT)
-
-
-/* 34XX GPIO - bidirectional, unless the name has an "_OUT" suffix.
- * (Always specify PIN_INPUT, except for names suffixed by "_OUT".)
- * No internal pullup/pulldown without "_UP" or "_DOWN" suffix.
- */
-MUX_CFG_34XX("AF26_34XX_GPIO0", 0x1e0,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("AF22_34XX_GPIO9", 0xa18,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("AG9_34XX_GPIO23", 0x5ee,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("U8_34XX_GPIO54_OUT", 0x0b4,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("U8_34XX_GPIO54_DOWN", 0x0b4,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLDOWN)
-MUX_CFG_34XX("L8_34XX_GPIO63", 0x0ce,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("G25_34XX_GPIO86_OUT", 0x0fc,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AF4_34XX_GPIO135_OUT", 0x162,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6,
-		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
-
-/* OMAP3 SDRC CKE signals to SDR/DDR ram chips */
-MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
-MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
-
-/* MMC1 */
-MUX_CFG_34XX("N28_3430_MMC1_CLK", 0x144,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("M27_3430_MMC1_CMD", 0x146,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("N27_3430_MMC1_DAT0", 0x148,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("N26_3430_MMC1_DAT1", 0x14a,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("N25_3430_MMC1_DAT2", 0x14c,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("P28_3430_MMC1_DAT3", 0x14e,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("P27_3430_MMC1_DAT4", 0x150,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("P26_3430_MMC1_DAT5", 0x152,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("R27_3430_MMC1_DAT6", 0x154,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("R25_3430_MMC1_DAT7", 0x156,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-
-/* MMC2 */
-MUX_CFG_34XX("AE2_3430_MMC2_CLK", 0x158,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AG5_3430_MMC2_CMD", 0x15A,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AH5_3430_MMC2_DAT0", 0x15c,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AH4_3430_MMC2_DAT1", 0x15e,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AG4_3430_MMC2_DAT2", 0x160,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AF4_3430_MMC2_DAT3", 0x162,
-		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
-
-/* MMC3 */
-MUX_CFG_34XX("AF10_3430_MMC3_CLK", 0x5d8,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AC3_3430_MMC3_CMD", 0x1d0,
-		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AE11_3430_MMC3_DAT0", 0x5e4,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AH9_3430_MMC3_DAT1", 0x5e6,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AF13_3430_MMC3_DAT2", 0x5e8,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
-MUX_CFG_34XX("AF13_3430_MMC3_DAT3", 0x5e2,
-		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
-
-/* SYS_NIRQ T2 INT1 */
-MUX_CFG_34XX("AF26_34XX_SYS_NIRQ", 0x1E0,
-		OMAP3_WAKEUP_EN | OMAP34XX_PIN_INPUT_PULLUP |
-		OMAP34XX_MUX_MODE0)
-};
-
-#define OMAP34XX_PINS_SZ	ARRAY_SIZE(omap34xx_pins)
-
-#else
-#define omap34xx_pins		NULL
-#define OMAP34XX_PINS_SZ	0
-#endif	/* CONFIG_ARCH_OMAP34XX */
-
 #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
+
 static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg)
 {
 	u16 orig;
 	u8 warn = 0, debug = 0;
 
-	if (cpu_is_omap24xx())
-		orig = omap_ctrl_readb(cfg->mux_reg);
-	else
-		orig = omap_ctrl_readw(cfg->mux_reg);
+	orig = omap_mux_read(cfg->mux_reg - OMAP_MUX_BASE_OFFSET);
 
 #ifdef	CONFIG_OMAP_MUX_DEBUG
 	debug = cfg->debug;
@@ -585,7 +313,6 @@ static void __init_or_module omap2_cfg_d
 #define omap2_cfg_debug(x, y)	do {} while (0)
 #endif
 
-#ifdef CONFIG_ARCH_OMAP24XX
 static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
 {
 	static DEFINE_SPINLOCK(mux_spin_lock);
@@ -599,47 +326,695 @@ static int __init_or_module omap24xx_cfg
 	if (cfg->pu_pd_val)
 		reg |= OMAP2_PULL_UP;
 	omap2_cfg_debug(cfg, reg);
-	omap_ctrl_writeb(reg, cfg->mux_reg);
+	omap_mux_write(reg, cfg->mux_reg - OMAP_MUX_BASE_OFFSET);
 	spin_unlock_irqrestore(&mux_spin_lock, flags);
 
 	return 0;
 }
+
+int __init omap2_mux_init(void)
+{
+	u32 mux_pbase;
+
+	if (cpu_is_omap2420())
+		mux_pbase = OMAP2420_CTRL_BASE + OMAP_MUX_BASE_OFFSET;
+	else if (cpu_is_omap2430())
+		mux_pbase = OMAP243X_CTRL_BASE + OMAP_MUX_BASE_OFFSET;
+	else
+		return -ENODEV;
+
+	mux_base = ioremap(mux_pbase, OMAP_MUX_BASE_SZ);
+	if (!mux_base) {
+		printk(KERN_ERR "mux: Could not ioremap\n");
+		return -ENODEV;
+	}
+
+	if (cpu_is_omap24xx()) {
+		arch_mux_cfg.pins	= omap24xx_pins;
+		arch_mux_cfg.size	= OMAP24XX_PINS_SZ;
+		arch_mux_cfg.cfg_reg	= omap24xx_cfg_reg;
+
+		return omap_mux_register(&arch_mux_cfg);
+	}
+
+	return 0;
+}
+
 #else
-#define omap24xx_cfg_reg	NULL
-#endif
+int __init omap2_mux_init(void)
+{
+	return 0;
+}
+#endif	/* CONFIG_OMAP_MUX */
+
+/*----------------------------------------------------------------------------*/
 
 #ifdef CONFIG_ARCH_OMAP34XX
-static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg)
+static LIST_HEAD(muxmodes);
+static DEFINE_MUTEX(muxmode_mutex);
+
+#ifdef CONFIG_OMAP_MUX
+
+static char *omap_mux_options;
+
+int __init omap_mux_init_gpio(int gpio, int val)
 {
-	static DEFINE_SPINLOCK(mux_spin_lock);
-	unsigned long flags;
-	u16 reg = 0;
+	struct omap_mux_entry *e;
+	int found = 0;
 
-	spin_lock_irqsave(&mux_spin_lock, flags);
-	reg |= cfg->mux_val;
-	omap2_cfg_debug(cfg, reg);
-	omap_ctrl_writew(reg, cfg->mux_reg);
-	spin_unlock_irqrestore(&mux_spin_lock, flags);
+	if (!gpio)
+		return -EINVAL;
+
+	list_for_each_entry(e, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+		if (gpio == m->gpio) {
+			u16 old_mode;
+			u16 mux_mode;
+
+			old_mode = omap_mux_read(m->reg_offset);
+			mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
+			mux_mode |= OMAP_MUX_MODE4;
+			printk(KERN_DEBUG "mux: Setting signal "
+				"%s.gpio%i 0x%04x -> 0x%04x\n",
+				m->muxnames[0], gpio, old_mode, mux_mode);
+			omap_mux_write(mux_mode, m->reg_offset);
+			found++;
+		}
+	}
+
+	if (found == 1)
+		return 0;
+
+	if (found > 1) {
+		printk(KERN_ERR "mux: Multiple gpio paths for gpio%i\n", gpio);
+		return -EINVAL;
+	}
+
+	printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
+
+	return -ENODEV;
+}
+
+int __init omap_mux_init_signal(char *muxname, int val)
+{
+	struct omap_mux_entry *e;
+	char *m0_name = NULL, *mode_name = NULL;
+	int found = 0;
+
+	mode_name = strchr(muxname, '.');
+	if (mode_name) {
+		*mode_name = '\0';
+		mode_name++;
+		m0_name = muxname;
+	} else {
+		mode_name = muxname;
+	}
+
+	list_for_each_entry(e, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+		char *m0_entry = m->muxnames[0];
+		int i;
+
+		if (m0_name && strcmp(m0_name, m0_entry))
+			continue;
+
+		for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
+			char *mode_cur = m->muxnames[i];
+
+			if (!mode_cur)
+				continue;
+
+			if (!strcmp(mode_name, mode_cur)) {
+				u16 old_mode;
+				u16 mux_mode;
+
+				old_mode = omap_mux_read(m->reg_offset);
+				mux_mode = val | i;
+				printk(KERN_DEBUG "mux: Setting signal "
+					"%s.%s 0x%04x -> 0x%04x\n",
+					m0_entry, muxname, old_mode, mux_mode);
+				omap_mux_write(mux_mode, m->reg_offset);
+				found++;
+			}
+		}
+	}
+
+	if (found == 1)
+		return 0;
+
+	if (found > 1) {
+		printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n",
+				found, muxname);
+		return -EINVAL;
+	}
+
+	printk(KERN_ERR "mux: Could not set signal %s\n", muxname);
+
+	return -ENODEV;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define OMAP_MUX_MAX_NR_FLAGS	10
+#define OMAP_MUX_TEST_FLAG(val, mask)				\
+	if (((val) & (mask)) == (mask)) {			\
+		i++;						\
+		flags[i] =  #mask;				\
+	}
+
+/* REVISIT: Add checking for non-optimal mux settings */
+static inline void omap_mux_decode(struct seq_file *s, u16 val)
+{
+	char *flags[OMAP_MUX_MAX_NR_FLAGS];
+	char mode[sizeof("OMAP_MUX_MODE") + 1];
+	int i = -1;
+
+	sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
+	i++;
+	flags[i] = mode;
+
+	OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
+	if (val & OMAP_OFF_EN) {
+		if (!(val & OMAP_OFFOUT_EN)) {
+			if (!(val & OMAP_OFF_PULL_UP)) {
+				OMAP_MUX_TEST_FLAG(val,
+					OMAP_PIN_OFF_INPUT_PULLDOWN);
+			} else {
+				OMAP_MUX_TEST_FLAG(val,
+					OMAP_PIN_OFF_INPUT_PULLUP);
+			}
+		} else {
+			if (!(val & OMAP_OFFOUT_VAL)) {
+				OMAP_MUX_TEST_FLAG(val,
+					OMAP_PIN_OFF_OUTPUT_LOW);
+			} else {
+				OMAP_MUX_TEST_FLAG(val,
+					OMAP_PIN_OFF_OUTPUT_HIGH);
+			}
+		}
+	}
+
+	if (val & OMAP_INPUT_EN) {
+		if (val & OMAP_PULL_ENA) {
+			if (!(val & OMAP_PULL_UP)) {
+				OMAP_MUX_TEST_FLAG(val,
+					OMAP_PIN_INPUT_PULLDOWN);
+			} else {
+				OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
+			}
+		} else {
+			OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
+		}
+	} else {
+		i++;
+		flags[i] = "OMAP_PIN_OUTPUT";
+	}
+
+	do {
+		seq_printf(s, "%s", flags[i]);
+		if (i > 0)
+			seq_printf(s, " | ");
+	} while (i-- > 0);
+}
+
+#define OMAP_MUX_DEFNAME_LEN	16
+
+static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
+{
+	struct omap_mux_entry *e;
+
+	list_for_each_entry(e, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+		char m0_def[OMAP_MUX_DEFNAME_LEN];
+		char *m0_name = m->muxnames[0];
+		u16 val;
+		int i, mode;
+
+		if (!m0_name)
+			continue;
+
+		/* REVISIT: Needs to be updated if mode0 names get longer */
+		for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
+			if (m0_name[i] == '\0') {
+				m0_def[i] = m0_name[i];
+				break;
+			}
+			m0_def[i] = toupper(m0_name[i]);
+		}
+		val = omap_mux_read(m->reg_offset);
+		mode = val & OMAP_MUX_MODE7;
+
+		seq_printf(s, "OMAP%i_MUX(%s, ",
+					cpu_is_omap34xx() ? 3 : 0, m0_def);
+		omap_mux_decode(s, val);
+		seq_printf(s, "),\n");
+	}
+
+	return 0;
+}
+
+static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, omap_mux_dbg_board_show, &inode->i_private);
+}
+
+static const struct file_operations omap_mux_dbg_board_fops = {
+	.open		= omap_mux_dbg_board_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
+{
+	struct omap_mux *m = s->private;
+	const char *none = "NA";
+	u16 val;
+	int mode;
+
+	val = omap_mux_read(m->reg_offset);
+	mode = val & OMAP_MUX_MODE7;
+
+	seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n",
+			m->muxnames[0], m->muxnames[mode],
+			mux_phys + m->reg_offset, m->reg_offset, val,
+			m->balls[0] ? m->balls[0] : none,
+			m->balls[1] ? m->balls[1] : none);
+	seq_printf(s, "mode: ");
+	omap_mux_decode(s, val);
+	seq_printf(s, "\n");
+	seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
+			m->muxnames[0] ? m->muxnames[0] : none,
+			m->muxnames[1] ? m->muxnames[1] : none,
+			m->muxnames[2] ? m->muxnames[2] : none,
+			m->muxnames[3] ? m->muxnames[3] : none,
+			m->muxnames[4] ? m->muxnames[4] : none,
+			m->muxnames[5] ? m->muxnames[5] : none,
+			m->muxnames[6] ? m->muxnames[6] : none,
+			m->muxnames[7] ? m->muxnames[7] : none);
 
 	return 0;
 }
+
+#define OMAP_MUX_MAX_ARG_CHAR  7
+
+static ssize_t omap_mux_dbg_signal_write(struct file *file,
+						const char __user *user_buf,
+						size_t count, loff_t *ppos)
+{
+	char buf[OMAP_MUX_MAX_ARG_CHAR];
+	struct seq_file *seqf;
+	struct omap_mux *m;
+	unsigned long val;
+	int buf_size, ret;
+
+	if (count > OMAP_MUX_MAX_ARG_CHAR)
+		return -EINVAL;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) - 1);
+
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	ret = strict_strtoul(buf, 0x10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val > 0xffff)
+		return -EINVAL;
+
+	seqf = file->private_data;
+	m = seqf->private;
+
+	omap_mux_write((u16)val, m->reg_offset);
+	*ppos += count;
+
+	return count;
+}
+
+static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
+}
+
+static const struct file_operations omap_mux_dbg_signal_fops = {
+	.open		= omap_mux_dbg_signal_open,
+	.read		= seq_read,
+	.write		= omap_mux_dbg_signal_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct dentry *mux_dbg_dir;
+
+static void __init omap_mux_dbg_init(void)
+{
+	struct omap_mux_entry *e;
+
+	mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
+	if (!mux_dbg_dir)
+		return;
+
+	(void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir,
+					NULL, &omap_mux_dbg_board_fops);
+
+	list_for_each_entry(e, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+
+		(void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
+					m, &omap_mux_dbg_signal_fops);
+	}
+}
+
 #else
-#define omap34xx_cfg_reg	NULL
+static inline void omap_mux_dbg_init(void)
+{
+}
+#endif	/* CONFIG_DEBUG_FS */
+
+static void __init omap_mux_free_names(struct omap_mux *m)
+{
+	int i;
+
+	for (i = 0; i < OMAP_MUX_NR_MODES; i++)
+		kfree(m->muxnames[i]);
+
+#ifdef CONFIG_DEBUG_FS
+	for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
+		kfree(m->balls[i]);
 #endif
 
-int __init omap2_mux_init(void)
+}
+
+/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
+static int __init omap_mux_late_init(void)
 {
-	if (cpu_is_omap24xx()) {
-		arch_mux_cfg.pins	= omap24xx_pins;
-		arch_mux_cfg.size	= OMAP24XX_PINS_SZ;
-		arch_mux_cfg.cfg_reg	= omap24xx_cfg_reg;
-	} else if (cpu_is_omap34xx()) {
-		arch_mux_cfg.pins	= omap34xx_pins;
-		arch_mux_cfg.size	= OMAP34XX_PINS_SZ;
-		arch_mux_cfg.cfg_reg	= omap34xx_cfg_reg;
+	struct omap_mux_entry *e, *tmp;
+
+	list_for_each_entry_safe(e, tmp, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+		u16 mode = omap_mux_read(m->reg_offset);
+
+		if (OMAP_MODE_GPIO(mode))
+			continue;
+
+#ifndef CONFIG_DEBUG_FS
+		mutex_lock(&muxmode_mutex);
+		list_del(&e->node);
+		mutex_unlock(&muxmode_mutex);
+		omap_mux_free_names(m);
+		kfree(m);
+#endif
+
 	}
 
-	return omap_mux_register(&arch_mux_cfg);
+	omap_mux_dbg_init();
+
+	return 0;
+}
+late_initcall(omap_mux_late_init);
+
+static void __init omap_mux_package_fixup(struct omap_mux *p,
+					struct omap_mux *superset)
+{
+	while (p->reg_offset !=  OMAP_MUX_TERMINATOR) {
+		struct omap_mux *s = superset;
+		int found = 0;
+
+		while (s->reg_offset != OMAP_MUX_TERMINATOR) {
+			if (s->reg_offset == p->reg_offset) {
+				*s = *p;
+				found++;
+				break;
+			}
+			s++;
+		}
+		if (!found)
+			printk(KERN_ERR "mux: Unknown entry offset 0x%x\n",
+					p->reg_offset);
+		p++;
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static void __init omap_mux_package_init_balls(struct omap_ball *b,
+				struct omap_mux *superset)
+{
+	while (b->reg_offset != OMAP_MUX_TERMINATOR) {
+		struct omap_mux *s = superset;
+		int found = 0;
+
+		while (s->reg_offset != OMAP_MUX_TERMINATOR) {
+			if (s->reg_offset == b->reg_offset) {
+				s->balls[0] = b->balls[0];
+				s->balls[1] = b->balls[1];
+				found++;
+				break;
+			}
+			s++;
+		}
+		if (!found)
+			printk(KERN_ERR "mux: Unknown ball offset 0x%x\n",
+					b->reg_offset);
+		b++;
+	}
 }
 
+#else	/* CONFIG_DEBUG_FS */
+
+static inline void omap_mux_package_init_balls(struct omap_ball *b,
+					struct omap_mux *superset)
+{
+}
+
+#endif	/* CONFIG_DEBUG_FS */
+
+static int __init omap_mux_setup(char *options)
+{
+	if (!options)
+		return 0;
+
+	omap_mux_options = options;
+
+	return 1;
+}
+__setup("omap_mux=", omap_mux_setup);
+
+/*
+ * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
+ * cmdline options only override the bootloader values.
+ * During development, please enable CONFIG_DEBUG_FS, and use the
+ * signal specific entries under debugfs.
+ */
+static void __init omap_mux_set_cmdline_signals(void)
+{
+	char *options, *next_opt, *token;
+
+	if (!omap_mux_options)
+		return;
+
+	options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL);
+	if (!options)
+		return;
+
+	strcpy(options, omap_mux_options);
+	next_opt = options;
+
+	while ((token = strsep(&next_opt, ",")) != NULL) {
+		char *keyval, *name;
+		unsigned long val;
+
+		keyval = token;
+		name = strsep(&keyval, "=");
+		if (name) {
+			int res;
+
+			res = strict_strtoul(keyval, 0x10, &val);
+			if (res < 0)
+				continue;
+
+			omap_mux_init_signal(name, (u16)val);
+		}
+	}
+
+	kfree(options);
+}
+
+static int __init omap_mux_copy_names(struct omap_mux *src,
+					struct omap_mux *dst)
+{
+	int i;
+
+	for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
+		if (src->muxnames[i]) {
+			dst->muxnames[i] =
+				kmalloc(strlen(src->muxnames[i]) + 1,
+					GFP_KERNEL);
+			if (!dst->muxnames[i])
+				goto free;
+			strcpy(dst->muxnames[i], src->muxnames[i]);
+		}
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
+		if (src->balls[i]) {
+			dst->balls[i] =
+				kmalloc(strlen(src->balls[i]) + 1,
+					GFP_KERNEL);
+			if (!dst->balls[i])
+				goto free;
+			strcpy(dst->balls[i], src->balls[i]);
+		}
+	}
 #endif
+
+	return 0;
+
+free:
+	omap_mux_free_names(dst);
+	return -ENOMEM;
+
+}
+
+#endif	/* CONFIG_OMAP_MUX */
+
+static u16 omap_mux_get_by_gpio(int gpio)
+{
+	struct omap_mux_entry *e;
+	u16 offset = OMAP_MUX_TERMINATOR;
+
+	list_for_each_entry(e, &muxmodes, node) {
+		struct omap_mux *m = &e->mux;
+		if (m->gpio == gpio) {
+			offset = m->reg_offset;
+			break;
+		}
+	}
+
+	return offset;
+}
+
+/* Needed for dynamic muxing of GPIO pins for off-idle */
+u16 omap_mux_get_gpio(int gpio)
+{
+	u16 offset;
+
+	offset = omap_mux_get_by_gpio(gpio);
+	if (offset == OMAP_MUX_TERMINATOR) {
+		printk(KERN_ERR "mux: Could not get gpio%i\n", gpio);
+		return offset;
+	}
+
+	return omap_mux_read(offset);
+}
+
+/* Needed for dynamic muxing of GPIO pins for off-idle */
+void omap_mux_set_gpio(u16 val, int gpio)
+{
+	u16 offset;
+
+	offset = omap_mux_get_by_gpio(gpio);
+	if (offset == OMAP_MUX_TERMINATOR) {
+		printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
+		return;
+	}
+
+	omap_mux_write(val, offset);
+}
+
+static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
+{
+	struct omap_mux_entry *entry;
+	struct omap_mux *m;
+
+	entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
+	if (!entry)
+		return NULL;
+
+	m = &entry->mux;
+	memcpy(m, src, sizeof(struct omap_mux_entry));
+
+#ifdef CONFIG_OMAP_MUX
+	if (omap_mux_copy_names(src, m)) {
+		kfree(entry);
+		return NULL;
+	}
+#endif
+
+	mutex_lock(&muxmode_mutex);
+	list_add_tail(&entry->node, &muxmodes);
+	mutex_unlock(&muxmode_mutex);
+
+	return m;
+}
+
+/*
+ * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
+ * the GPIO to mux offset mapping that is needed for dynamic muxing
+ * of GPIO pins for off-idle.
+ */
+static void __init omap_mux_init_list(struct omap_mux *superset)
+{
+	while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) {
+		struct omap_mux *entry;
+
+#ifdef CONFIG_OMAP_MUX
+		if (!superset->muxnames || !superset->muxnames[0]) {
+			superset++;
+			continue;
+		}
+#else
+		/* Skip pins that are not muxed as GPIO by bootloader */
+		if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
+			superset++;
+			continue;
+		}
+#endif
+
+		entry = omap_mux_list_add(superset);
+		if (!entry) {
+			printk(KERN_ERR "mux: Could not add entry\n");
+			return;
+		}
+		superset++;
+	}
+}
+
+int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
+				struct omap_mux *superset,
+				struct omap_mux *package_subset,
+				struct omap_board_mux *board_mux,
+				struct omap_ball *package_balls)
+{
+	if (mux_base)
+		return -EBUSY;
+
+	mux_phys = mux_pbase;
+	mux_base = ioremap(mux_pbase, mux_size);
+	if (!mux_base) {
+		printk(KERN_ERR "mux: Could not ioremap\n");
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_OMAP_MUX
+	if (package_subset)
+		omap_mux_package_fixup(package_subset, superset);
+	if (package_balls)
+		omap_mux_package_init_balls(package_balls, superset);
+#endif
+
+	omap_mux_init_list(superset);
+
+#ifdef CONFIG_OMAP_MUX
+	omap_mux_set_cmdline_signals();
+	omap_mux_write_array(board_mux);
+#endif
+
+	return 0;
+}
+
+#endif	/* CONFIG_ARCH_OMAP34XX */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/mux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/mux.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "mux34xx.h"
+
+#define OMAP_MUX_TERMINATOR	0xffff
+
+/* 34xx mux mode options for each pin. See TRM for options */
+#define OMAP_MUX_MODE0      0
+#define OMAP_MUX_MODE1      1
+#define OMAP_MUX_MODE2      2
+#define OMAP_MUX_MODE3      3
+#define OMAP_MUX_MODE4      4
+#define OMAP_MUX_MODE5      5
+#define OMAP_MUX_MODE6      6
+#define OMAP_MUX_MODE7      7
+
+/* 24xx/34xx mux bit defines */
+#define OMAP_PULL_ENA			(1 << 3)
+#define OMAP_PULL_UP			(1 << 4)
+#define OMAP_ALTELECTRICALSEL		(1 << 5)
+
+/* 34xx specific mux bit defines */
+#define OMAP_INPUT_EN			(1 << 8)
+#define OMAP_OFF_EN			(1 << 9)
+#define OMAP_OFFOUT_EN			(1 << 10)
+#define OMAP_OFFOUT_VAL			(1 << 11)
+#define OMAP_OFF_PULL_EN		(1 << 12)
+#define OMAP_OFF_PULL_UP		(1 << 13)
+#define OMAP_WAKEUP_EN			(1 << 14)
+
+/* Active pin states */
+#define OMAP_PIN_OUTPUT			0
+#define OMAP_PIN_INPUT			OMAP_INPUT_EN
+#define OMAP_PIN_INPUT_PULLUP		(OMAP_PULL_ENA | OMAP_INPUT_EN \
+						| OMAP_PULL_UP)
+#define OMAP_PIN_INPUT_PULLDOWN		(OMAP_PULL_ENA | OMAP_INPUT_EN)
+
+/* Off mode states */
+#define OMAP_PIN_OFF_NONE		0
+#define OMAP_PIN_OFF_OUTPUT_HIGH	(OMAP_OFF_EN | OMAP_OFFOUT_EN \
+						| OMAP_OFFOUT_VAL)
+#define OMAP_PIN_OFF_OUTPUT_LOW		(OMAP_OFF_EN | OMAP_OFFOUT_EN)
+#define OMAP_PIN_OFF_INPUT_PULLUP	(OMAP_OFF_EN | OMAP_OFF_PULL_EN \
+						| OMAP_OFF_PULL_UP)
+#define OMAP_PIN_OFF_INPUT_PULLDOWN	(OMAP_OFF_EN | OMAP_OFF_PULL_EN)
+#define OMAP_PIN_OFF_WAKEUPENABLE	OMAP_WAKEUP_EN
+
+#define OMAP_MODE_GPIO(x)	(((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
+
+/* Flags for omap_mux_init */
+#define OMAP_PACKAGE_MASK		0xffff
+#define OMAP_PACKAGE_CBP		4		/* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CUS		3		/* 423-pin 0.65 */
+#define OMAP_PACKAGE_CBB		2		/* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CBC		1		/* 515-pin 0.50 0.65 */
+
+
+#define OMAP_MUX_NR_MODES	8			/* Available modes */
+#define OMAP_MUX_NR_SIDES	2			/* Bottom & top */
+
+/**
+ * struct omap_mux - data for omap mux register offset and it's value
+ * @reg_offset:	mux register offset from the mux base
+ * @gpio:	GPIO number
+ * @muxnames:	available signal modes for a ball
+ */
+struct omap_mux {
+	u16	reg_offset;
+	u16	gpio;
+#ifdef CONFIG_OMAP_MUX
+	char	*muxnames[OMAP_MUX_NR_MODES];
+#ifdef CONFIG_DEBUG_FS
+	char	*balls[OMAP_MUX_NR_SIDES];
+#endif
+#endif
+};
+
+/**
+ * struct omap_ball - data for balls on omap package
+ * @reg_offset:	mux register offset from the mux base
+ * @balls:	available balls on the package
+ */
+struct omap_ball {
+	u16	reg_offset;
+	char	*balls[OMAP_MUX_NR_SIDES];
+};
+
+/**
+ * struct omap_board_mux - data for initializing mux registers
+ * @reg_offset:	mux register offset from the mux base
+ * @mux_value:	desired mux value to set
+ */
+struct omap_board_mux {
+	u16	reg_offset;
+	u16	value;
+};
+
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_ARCH_OMAP34XX)
+
+/**
+ * omap_mux_init_gpio - initialize a signal based on the GPIO number
+ * @gpio:		GPIO number
+ * @val:		Options for the mux register value
+ */
+int omap_mux_init_gpio(int gpio, int val);
+
+/**
+ * omap_mux_init_signal - initialize a signal based on the signal name
+ * @muxname:		Mux name in mode0_name.signal_name format
+ * @val:		Options for the mux register value
+ */
+int omap_mux_init_signal(char *muxname, int val);
+
+#else
+
+static inline int omap_mux_init_gpio(int gpio, int val)
+{
+	return 0;
+}
+static inline int omap_mux_init_signal(char *muxname, int val)
+{
+	return 0;
+}
+
+#endif
+
+/**
+ * omap_mux_get_gpio() - get mux register value based on GPIO number
+ * @gpio:		GPIO number
+ *
+ */
+u16 omap_mux_get_gpio(int gpio);
+
+/**
+ * omap_mux_set_gpio() - set mux register value based on GPIO number
+ * @val:		New mux register value
+ * @gpio:		GPIO number
+ *
+ */
+void omap_mux_set_gpio(u16 val, int gpio);
+
+/**
+ * omap_mux_read() - read mux register
+ * @mux_offset:		Offset of the mux register
+ *
+ */
+u16 omap_mux_read(u16 mux_offset);
+
+/**
+ * omap_mux_write() - write mux register
+ * @val:		New mux register value
+ * @mux_offset:		Offset of the mux register
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write(u16 val, u16 mux_offset);
+
+/**
+ * omap_mux_write_array() - write an array of mux registers
+ * @board_mux:		Array of mux registers terminated by MAP_MUX_TERMINATOR
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write_array(struct omap_board_mux *board_mux);
+
+/**
+ * omap3_mux_init() - initialize mux system with board specific set
+ * @board_mux:		Board specific mux table
+ * @flags:		OMAP package type used for the board
+ */
+int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
+ * omap_mux_init - private mux init function, do not call
+ */
+int omap_mux_init(u32 mux_pbase, u32 mux_size,
+				struct omap_mux *superset,
+				struct omap_mux *package_subset,
+				struct omap_board_mux *board_mux,
+				struct omap_ball *package_balls);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap3-iommu.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap3-iommu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap3-iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap3-iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,49 +12,52 @@
 
 #include <linux/platform_device.h>
 
-#include <mach/iommu.h>
-
-#define OMAP3_MMU1_BASE	0x480bd400
-#define OMAP3_MMU2_BASE	0x5d000000
-#define OMAP3_MMU1_IRQ	24
-#define OMAP3_MMU2_IRQ	28
-
-
-static unsigned long iommu_base[] __initdata = {
-	OMAP3_MMU1_BASE,
-	OMAP3_MMU2_BASE,
-};
+#include <plat/iommu.h>
 
-static int iommu_irq[] __initdata = {
-	OMAP3_MMU1_IRQ,
-	OMAP3_MMU2_IRQ,
+struct iommu_device {
+	resource_size_t base;
+	int irq;
+	struct iommu_platform_data pdata;
+	struct resource res[2];
 };
 
-static const struct iommu_platform_data omap3_iommu_pdata[] __initconst = {
+static struct iommu_device devices[] = {
 	{
-		.name = "isp",
-		.nr_tlb_entries = 8,
-		.clk_name = "cam_ick",
+		.base = 0x480bd400,
+		.irq = 24,
+		.pdata = {
+			.name = "isp",
+			.nr_tlb_entries = 8,
+			.clk_name = "cam_ick",
+		},
 	},
 #if defined(CONFIG_MPU_BRIDGE_IOMMU)
 	{
-		.name = "iva2",
-		.nr_tlb_entries = 32,
-		.clk_name = "iva2_ck",
+		.base = 0x5d000000,
+		.irq = 28,
+		.pdata = {
+			.name = "iva2",
+			.nr_tlb_entries = 32,
+			.clk_name = "iva2_ck",
+		},
 	},
 #endif
 };
-#define NR_IOMMU_DEVICES ARRAY_SIZE(omap3_iommu_pdata)
+#define NR_IOMMU_DEVICES ARRAY_SIZE(devices)
 
 static struct platform_device *omap3_iommu_pdev[NR_IOMMU_DEVICES];
 
 static int __init omap3_iommu_init(void)
 {
 	int i, err;
+	struct resource res[] = {
+		{ .flags = IORESOURCE_MEM },
+		{ .flags = IORESOURCE_IRQ },
+	};
 
 	for (i = 0; i < NR_IOMMU_DEVICES; i++) {
 		struct platform_device *pdev;
-		struct resource res[2];
+		const struct iommu_device *d = &devices[i];
 
 		pdev = platform_device_alloc("omap-iommu", i);
 		if (!pdev) {
@@ -62,19 +65,16 @@ static int __init omap3_iommu_init(void)
 			goto err_out;
 		}
 
-		memset(res, 0,  sizeof(res));
-		res[0].start = iommu_base[i];
-		res[0].end = iommu_base[i] + MMU_REG_SIZE - 1;
-		res[0].flags = IORESOURCE_MEM;
-		res[1].start = res[1].end = iommu_irq[i];
-		res[1].flags = IORESOURCE_IRQ;
+		res[0].start = d->base;
+		res[0].end = d->base + MMU_REG_SIZE - 1;
+		res[1].start = res[1].end = d->irq;
 
 		err = platform_device_add_resources(pdev, res,
 						    ARRAY_SIZE(res));
 		if (err)
 			goto err_out;
-		err = platform_device_add_data(pdev, &omap3_iommu_pdata[i],
-					       sizeof(omap3_iommu_pdata[0]));
+		err = platform_device_add_data(pdev, &d->pdata,
+					       sizeof(d->pdata));
 		if (err)
 			goto err_out;
 		err = platform_device_add(pdev);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap-headsmp.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-headsmp.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap-headsmp.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-headsmp.S	2010-02-24 13:52:17.000000000 -0500
@@ -27,20 +27,39 @@
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
  * secondary core is held until we're ready for it to initialise.
- * The primary core will update the this flag using a hardware
- * register AuxCoreBoot1.
+ * The primary core will update this flag using a hardware
+ * register AuxCoreBoot0.
  */
 ENTRY(omap_secondary_startup)
-	mrc	p15, 0, r0, c0, c0, 5
-	and	r0, r0, #0x0f
-hold:	ldr	r1, =OMAP4_AUX_CORE_BOOT1_PA	@ read from AuxCoreBoot1
-	ldr	r2, [r1]
-	cmp	r2, r0
+hold:	ldr	r12,=0x103
+	dsb
+	smc				@ read from AuxCoreBoot0
+	mov	r0, r0, lsr #9
+	mrc	p15, 0, r4, c0, c0, 5
+	and	r4, r4, #0x0f
+	cmp	r0, r4
 	bne	hold
 
 	/*
-	 * we've been released from the cpu_release,secondary_stack
+	 * we've been released from the wait loop,secondary_stack
 	 * should now contain the SVC stack for this core
 	 */
 	b	secondary_startup
+END(omap_secondary_startup)
+
 
+ENTRY(omap_modify_auxcoreboot0)
+	stmfd   sp!, {r1-r12, lr}
+	ldr	r12, =0x104
+	dsb
+	smc
+	ldmfd   sp!, {r1-r12, pc}
+END(omap_modify_auxcoreboot0)
+
+ENTRY(omap_auxcoreboot_addr)
+	stmfd   sp!, {r2-r12, lr}
+	ldr	r12, =0x105
+	dsb
+	smc
+	ldmfd   sp!, {r2-r12, pc}
+END(omap_auxcoreboot_addr)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2420.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,10 +16,10 @@
 
 #ifdef CONFIG_ARCH_OMAP2420
 
-#include <mach/omap_hwmod.h>
+#include <plat/omap_hwmod.h>
 #include <mach/irqs.h>
-#include <mach/cpu.h>
-#include <mach/dma.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
 
 #include "prm-regbits-24xx.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_2430.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,10 +16,10 @@
 
 #ifdef CONFIG_ARCH_OMAP2430
 
-#include <mach/omap_hwmod.h>
+#include <plat/omap_hwmod.h>
 #include <mach/irqs.h>
-#include <mach/cpu.h>
-#include <mach/dma.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
 
 #include "prm-regbits-24xx.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod_34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,10 +14,10 @@
 
 #ifdef CONFIG_ARCH_OMAP34XX
 
-#include <mach/omap_hwmod.h>
+#include <plat/omap_hwmod.h>
 #include <mach/irqs.h>
-#include <mach/cpu.h>
-#include <mach/dma.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
 
 #include "prm-regbits-34xx.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap_hwmod.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap_hwmod.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,11 +45,12 @@
 #include <linux/mutex.h>
 #include <linux/bootmem.h>
 
-#include <mach/cpu.h>
-#include <mach/clockdomain.h>
-#include <mach/powerdomain.h>
-#include <mach/clock.h>
-#include <mach/omap_hwmod.h>
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/clockdomain.h>
+#include <plat/powerdomain.h>
+#include <plat/clock.h>
+#include <plat/omap_hwmod.h>
 
 #include "cm.h"
 
@@ -93,7 +94,8 @@ static int _update_sysc_cache(struct oma
 
 	oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
 
-	oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
+	if (!(oh->sysconfig->sysc_flags & SYSC_NO_CACHE))
+		oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
 
 	return 0;
 }
@@ -210,6 +212,32 @@ static int _set_softreset(struct omap_hw
 }
 
 /**
+ * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ * @v: pointer to register contents to modify
+ *
+ * Update the module autoidle bit in @v to be @autoidle for the @oh
+ * hwmod.  The autoidle bit controls whether the module can gate
+ * internal clocks automatically when it isn't doing anything; the
+ * exact function of this bit varies on a per-module basis.  This
+ * function does not write to the hardware.  Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
+				u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
+		return -EINVAL;
+
+	*v &= ~SYSC_AUTOIDLE_MASK;
+	*v |= autoidle << SYSC_AUTOIDLE_SHIFT;
+
+	return 0;
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -326,6 +354,9 @@ static int _init_main_clk(struct omap_hw
 		ret = -EINVAL;
 	oh->_clk = c;
 
+	WARN(!c->clkdm, "omap_hwmod: %s: missing clockdomain for %s.\n",
+	     oh->clkdev_con_id, c->name);
+
 	return ret;
 }
 
@@ -496,6 +527,7 @@ static void __iomem *_find_mpu_rt_base(s
 	struct omap_hwmod_addr_space *mem;
 	int i;
 	int found = 0;
+	void __iomem *va_start;
 
 	if (!oh || oh->slaves_cnt == 0)
 		return NULL;
@@ -509,16 +541,20 @@ static void __iomem *_find_mpu_rt_base(s
 		}
 	}
 
-	/* XXX use ioremap() instead? */
-
-	if (found)
+	if (found) {
+		va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
+		if (!va_start) {
+			pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+			return NULL;
+		}
 		pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
-			 oh->name, OMAP2_IO_ADDRESS(mem->pa_start));
-	else
+			 oh->name, va_start);
+	} else {
 		pr_debug("omap_hwmod: %s: no MPU register target found\n",
 			 oh->name);
+	}
 
-	return (found) ? OMAP2_IO_ADDRESS(mem->pa_start) : NULL;
+	return (found) ? va_start : NULL;
 }
 
 /**
@@ -552,8 +588,19 @@ static void _sysc_enable(struct omap_hwm
 		_set_master_standbymode(oh, idlemode, &v);
 	}
 
-	/* XXX OCP AUTOIDLE bit? */
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE) {
+		idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
+			0 : 1;
+		_set_module_autoidle(oh, idlemode, &v);
+	}
+
+	/* XXX OCP ENAWAKEUP bit? */
 
+	/*
+	 * XXX The clock framework should handle this, by
+	 * calling into this code.  But this must wait until the
+	 * clock structures are tagged with omap_hwmod entries
+	 */
 	if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
 	    oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
 		_set_clockactivity(oh, oh->sysconfig->clockact, &v);
@@ -617,7 +664,8 @@ static void _sysc_shutdown(struct omap_h
 	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
 		_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
 
-	/* XXX clear OCP AUTOIDLE bit? */
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)
+		_set_module_autoidle(oh, 1, &v);
 
 	_write_sysconfig(v, oh);
 }
@@ -731,7 +779,7 @@ static int _wait_target_ready(struct oma
 static int _reset(struct omap_hwmod *oh)
 {
 	u32 r, v;
-	int c;
+	int c = 0;
 
 	if (!oh->sysconfig ||
 	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
@@ -753,13 +801,9 @@ static int _reset(struct omap_hwmod *oh)
 		return r;
 	_write_sysconfig(v, oh);
 
-	c = 0;
-	while (c < MAX_MODULE_RESET_WAIT &&
-	       !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
-		 SYSS_RESETDONE_MASK)) {
-		udelay(1);
-		c++;
-	}
+	omap_test_timeout((omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
+			   SYSS_RESETDONE_MASK),
+			  MAX_MODULE_RESET_WAIT, c);
 
 	if (c == MAX_MODULE_RESET_WAIT)
 		WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
@@ -879,33 +923,6 @@ static int _shutdown(struct omap_hwmod *
 }
 
 /**
- * _write_clockact_lock - set the module's clockactivity bits
- * @oh: struct omap_hwmod *
- * @clockact: CLOCKACTIVITY field bits
- *
- * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register.  Returns -EINVAL if the hwmod is in the
- * wrong state or returns 0.
- */
-static int _write_clockact_lock(struct omap_hwmod *oh, u8 clockact)
-{
-	u32 v;
-
-	if (!oh->sysconfig ||
-	    !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
-		return -EINVAL;
-
-	mutex_lock(&omap_hwmod_mutex);
-	v = oh->_sysc_cache;
-	_set_clockactivity(oh, clockact, &v);
-	_write_sysconfig(v, oh);
-	mutex_unlock(&omap_hwmod_mutex);
-
-	return 0;
-}
-
-
-/**
  * _setup - do initial configuration of omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -943,11 +960,19 @@ static int _setup(struct omap_hwmod *oh)
 
 	_enable(oh);
 
-	if (!(oh->flags & HWMOD_INIT_NO_RESET))
-		_reset(oh);
-
-	/* XXX OCP AUTOIDLE bit? */
-	/* XXX OCP ENAWAKEUP bit? */
+	if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
+		/*
+		 * XXX Do the OCP_SYSCONFIG bits need to be
+		 * reprogrammed after a reset?  If not, then this can
+		 * be removed.  If they do, then probably the
+		 * _enable() function should be split to avoid the
+		 * rewrite of the OCP_SYSCONFIG register.
+		 */
+		if (oh->sysconfig) {
+			_update_sysc_cache(oh);
+			_sysc_enable(oh);
+		}
+	}
 
 	if (!(oh->flags & HWMOD_INIT_NO_IDLE))
 		_idle(oh);
@@ -1148,6 +1173,7 @@ int omap_hwmod_unregister(struct omap_hw
 	pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
 
 	mutex_lock(&omap_hwmod_mutex);
+	iounmap(oh->_rt_va);
 	list_del(&oh->node);
 	mutex_unlock(&omap_hwmod_mutex);
 
@@ -1342,8 +1368,9 @@ int omap_hwmod_fill_resources(struct oma
 	/* For each IRQ, DMA, memory area, fill in array.*/
 
 	for (i = 0; i < oh->mpu_irqs_cnt; i++) {
-		(res + r)->start = *(oh->mpu_irqs + i);
-		(res + r)->end = *(oh->mpu_irqs + i);
+		(res + r)->name = (oh->mpu_irqs + i)->name;
+		(res + r)->start = (oh->mpu_irqs + i)->irq;
+		(res + r)->end = (oh->mpu_irqs + i)->irq;
 		(res + r)->flags = IORESOURCE_IRQ;
 		r++;
 	}
@@ -1448,62 +1475,6 @@ int omap_hwmod_del_initiator_dep(struct
 }
 
 /**
- * omap_hwmod_set_clockact_none - set clockactivity test to BOTH
- * @oh: struct omap_hwmod *
- *
- * On some modules, this function can affect the wakeup latency vs.
- * power consumption balance.  Intended to be called by the
- * omap_device layer.  Passes along the return value from
- * _write_clockact_lock().
- */
-int omap_hwmod_set_clockact_both(struct omap_hwmod *oh)
-{
-	return _write_clockact_lock(oh, CLOCKACT_TEST_BOTH);
-}
-
-/**
- * omap_hwmod_set_clockact_none - set clockactivity test to MAIN
- * @oh: struct omap_hwmod *
- *
- * On some modules, this function can affect the wakeup latency vs.
- * power consumption balance.  Intended to be called by the
- * omap_device layer.  Passes along the return value from
- * _write_clockact_lock().
- */
-int omap_hwmod_set_clockact_main(struct omap_hwmod *oh)
-{
-	return _write_clockact_lock(oh, CLOCKACT_TEST_MAIN);
-}
-
-/**
- * omap_hwmod_set_clockact_none - set clockactivity test to ICLK
- * @oh: struct omap_hwmod *
- *
- * On some modules, this function can affect the wakeup latency vs.
- * power consumption balance.  Intended to be called by the
- * omap_device layer.  Passes along the return value from
- * _write_clockact_lock().
- */
-int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh)
-{
-	return _write_clockact_lock(oh, CLOCKACT_TEST_ICLK);
-}
-
-/**
- * omap_hwmod_set_clockact_none - set clockactivity test to NONE
- * @oh: struct omap_hwmod *
- *
- * On some modules, this function can affect the wakeup latency vs.
- * power consumption balance.  Intended to be called by the
- * omap_device layer.  Passes along the return value from
- * _write_clockact_lock().
- */
-int omap_hwmod_set_clockact_none(struct omap_hwmod *oh)
-{
-	return _write_clockact_lock(oh, CLOCKACT_TEST_NONE);
-}
-
-/**
  * omap_hwmod_enable_wakeup - allow device to wake up the system
  * @oh: struct omap_hwmod *
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap-smp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-smp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/omap-smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/omap-smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,20 +17,17 @@
  */
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/io.h>
 
+#include <asm/cacheflush.h>
 #include <asm/localtimer.h>
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
-
-/* Registers used for communicating startup information */
-#define OMAP4_AUXCOREBOOT_REG0		(OMAP44XX_VA_WKUPGEN_BASE + 0x800)
-#define OMAP4_AUXCOREBOOT_REG1		(OMAP44XX_VA_WKUPGEN_BASE + 0x804)
+#include <plat/common.h>
 
 /* SCU base address */
-static void __iomem *scu_base = OMAP44XX_VA_SCU_BASE;
+static void __iomem *scu_base;
 
 /*
  * Use SCU config register to count number of cores
@@ -53,8 +50,7 @@ void __cpuinit platform_secondary_init(u
 	 * core (e.g. timer irq), then they will not have been enabled
 	 * for us: do so
 	 */
-
-	gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
+	gic_cpu_init(0, gic_cpu_base_addr);
 
 	/*
 	 * Synchronise with the boot thread.
@@ -65,8 +61,6 @@ void __cpuinit platform_secondary_init(u
 
 int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-	unsigned long timeout;
-
 	/*
 	 * Set synchronisation state between this boot processor
 	 * and the secondary one
@@ -74,18 +68,15 @@ int __cpuinit boot_secondary(unsigned in
 	spin_lock(&boot_lock);
 
 	/*
-	 * Update the AuxCoreBoot1 with boot state for secondary core.
+	 * Update the AuxCoreBoot0 with boot state for secondary core.
 	 * omap_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
 	 */
-	__raw_writel(cpu, OMAP4_AUXCOREBOOT_REG1);
+	omap_modify_auxcoreboot0(0x200, 0x0);
+	flush_cache_all();
 	smp_wmb();
 
-	timeout = jiffies + (1 * HZ);
-	while (time_before(jiffies, timeout))
-		;
-
 	/*
 	 * Now the secondary core is starting up let it run its
 	 * calibrations, then wait for it to finish
@@ -99,17 +90,18 @@ static void __init wakeup_secondary(void
 {
 	/*
 	 * Write the address of secondary startup routine into the
-	 * AuxCoreBoot0 where ROM code will jump and start executing
+	 * AuxCoreBoot1 where ROM code will jump and start executing
 	 * on secondary core once out of WFE
 	 * A barrier is added to ensure that write buffer is drained
 	 */
-	__raw_writel(virt_to_phys(omap_secondary_startup),	   \
-					OMAP4_AUXCOREBOOT_REG0);
+	omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup));
 	smp_wmb();
 
 	/*
 	 * Send a 'sev' to wake the secondary core from WFE.
+	 * Drain the outstanding writes to memory
 	 */
+	dsb();
 	set_event();
 	mb();
 }
@@ -120,7 +112,13 @@ static void __init wakeup_secondary(void
  */
 void __init smp_init_cpus(void)
 {
-	unsigned int i, ncores = get_core_count();
+	unsigned int i, ncores;
+
+	/* Never released */
+	scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
+	BUG_ON(!scu_base);
+
+	ncores = get_core_count();
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2420_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2420_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2420_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2420_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,128 @@
+/*
+ * opp2420_data.c - old-style "OPP" table for OMAP2420
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratios' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio.
+ *
+ * XXX Missing voltage data.
+ * XXX Missing 19.2MHz sys_clk rate sets (needed for N800/N810)
+ *
+ * THe format described in this file is deprecated.  Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ *
+ * Considerable work is still needed to fully support dynamic frequency
+ * changes on OMAP2xxx-series chips.  Readers interested in such a
+ * project are encouraged to review the Maemo Diablo RX-34 and RX-44
+ * kernel source at:
+ *     http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/
+ */
+
+#include "opp2xxx.h"
+#include "sdrc.h"
+#include "clock.h"
+
+/*
+ * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on H4 boards available.  There are quite a
+ * few more rate combinations which could be defined.
+ *
+ * When multiple values are defined the start up will try and choose
+ * the fastest one. If a 'fast' value is defined, then automatically,
+ * the /2 one should be included as it can be used.  Generally having
+ * more than one fast set does not make sense, as static timings need
+ * to be changed to change the set.  The exception is the bypass
+ * setting which is available for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ **/
+const struct prcm_config omap2420_rate_table[] = {
+	/* PRCM I - FAST */
+	{S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL,		/* 330MHz ARM */
+		RI_CM_CLKSEL_DSP_VAL, RI_CM_CLKSEL_GFX_VAL,
+		RI_CM_CLKSEL1_CORE_VAL, MI_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_165MHz,
+		RATE_IN_242X},
+
+	/* PRCM II - FAST */
+	{S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	{S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	/* PRCM III - FAST */
+	{S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	{S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	/* PRCM II - SLOW */
+	{S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	{S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	/* PRCM III - SLOW */
+	{S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	{S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	/* PRCM-VII (boot-bypass) */
+	{S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL,		/* 12MHz ARM*/
+		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_242X},
+
+	/* PRCM-VII (boot-bypass) */
+	{S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL,		/* 13MHz ARM */
+		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_242X},
+
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2430_data.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2430_data.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2430_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2430_data.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,133 @@
+/*
+ * opp2430_data.c - old-style "OPP" table for OMAP2430
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratios' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ *
+ * XXX Missing voltage data.
+ * XXX Missing 19.2MHz sys_clk rate sets.
+ *
+ * THe format described in this file is deprecated.  Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ */
+
+#include "opp2xxx.h"
+#include "sdrc.h"
+#include "clock.h"
+
+/*
+ * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on 2430-SDPs variants available.  There are
+ * quite a few more rate combinations which could be defined.
+ *
+ * When multiple values are defined the start up will try and choose
+ * the fastest one. If a 'fast' value is defined, then automatically,
+ * the /2 one should be included as it can be used.  Generally having
+ * more than one fast set does not make sense, as static timings need
+ * to be changed to change the set.  The exception is the bypass
+ * setting which is available for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ */
+const struct prcm_config omap2430_rate_table[] = {
+	/* PRCM #4 - ratio2 (ES2.1) - FAST */
+	{S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL,		/* 399MHz ARM */
+		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+		R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #2 - ratio1 (ES2) - FAST */
+	{S13M, S658M, S329M, R1_CM_CLKSEL_MPU_VAL,		/* 330MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_165MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5a - ratio1 - FAST */
+	{S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5b - ratio1 - FAST */
+	{S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL,		/* 200MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_100MHz,
+		RATE_IN_243X},
+
+	/* PRCM #4 - ratio1 (ES2.1) - SLOW */
+	{S13M, S399M, S199M, R2_CM_CLKSEL_MPU_VAL,		/* 200MHz ARM */
+		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+		R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #2 - ratio1 (ES2) - SLOW */
+	{S13M, S329M, S164M, R1_CM_CLKSEL_MPU_VAL,		/* 165MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_165MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5a - ratio1 - SLOW */
+	{S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5b - ratio1 - SLOW*/
+	{S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL,		/* 100MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_100MHz,
+		RATE_IN_243X},
+
+	/* PRCM-boot/bypass */
+	{S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL,		/* 13Mhz */
+		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_243X},
+
+	/* PRCM-boot/bypass */
+	{S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL,		/* 12Mhz */
+		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+		SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_243X},
+
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2xxx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2xxx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/opp2xxx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/opp2xxx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,424 @@
+/*
+ * opp2xxx.h - macros for old-style OMAP2xxx "OPP" definitions
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratio's' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio
+ * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ *
+ * XXX Missing voltage data.
+ *
+ * THe format described in this file is deprecated.  Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OPP2XXX_H
+#define __ARCH_ARM_MACH_OMAP2_OPP2XXX_H
+
+/**
+ * struct prcm_config - define clock rates on a per-OPP basis (24xx)
+ *
+ * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
+ * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * This is deprecated.  As soon as we have a decent OPP API, we should
+ * move all this stuff to it.
+ */
+struct prcm_config {
+	unsigned long xtal_speed;	/* crystal rate */
+	unsigned long dpll_speed;	/* dpll: out*xtal*M/(N-1)table_recalc */
+	unsigned long mpu_speed;	/* speed of MPU */
+	unsigned long cm_clksel_mpu;	/* mpu divider */
+	unsigned long cm_clksel_dsp;	/* dsp+iva1 div(2420), iva2.1(2430) */
+	unsigned long cm_clksel_gfx;	/* gfx dividers */
+	unsigned long cm_clksel1_core;	/* major subsystem dividers */
+	unsigned long cm_clksel1_pll;	/* m,n */
+	unsigned long cm_clksel2_pll;	/* dpllx1 or x2 out */
+	unsigned long cm_clksel_mdm;	/* modem dividers 2430 only */
+	unsigned long base_sdrc_rfr;	/* base refresh timing for a set */
+	unsigned char flags;
+};
+
+
+/* Core fields for cm_clksel, not ratio governed */
+#define RX_CLKSEL_DSS1			(0x10 << 8)
+#define RX_CLKSEL_DSS2			(0x0 << 13)
+#define RX_CLKSEL_SSI			(0x5 << 20)
+
+/*-------------------------------------------------------------------------
+ * Voltage/DPLL ratios
+ *-------------------------------------------------------------------------*/
+
+/* 2430 Ratio's, 2430-Ratio Config 1 */
+#define R1_CLKSEL_L3			(4 << 0)
+#define R1_CLKSEL_L4			(2 << 5)
+#define R1_CLKSEL_USB			(4 << 25)
+#define R1_CM_CLKSEL1_CORE_VAL		(R1_CLKSEL_USB | RX_CLKSEL_SSI | \
+					 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					 R1_CLKSEL_L4 | R1_CLKSEL_L3)
+#define R1_CLKSEL_MPU			(2 << 0)
+#define R1_CM_CLKSEL_MPU_VAL		R1_CLKSEL_MPU
+#define R1_CLKSEL_DSP			(2 << 0)
+#define R1_CLKSEL_DSP_IF		(2 << 5)
+#define R1_CM_CLKSEL_DSP_VAL		(R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF)
+#define R1_CLKSEL_GFX			(2 << 0)
+#define R1_CM_CLKSEL_GFX_VAL		R1_CLKSEL_GFX
+#define R1_CLKSEL_MDM			(4 << 0)
+#define R1_CM_CLKSEL_MDM_VAL		R1_CLKSEL_MDM
+
+/* 2430-Ratio Config 2 */
+#define R2_CLKSEL_L3			(6 << 0)
+#define R2_CLKSEL_L4			(2 << 5)
+#define R2_CLKSEL_USB			(2 << 25)
+#define R2_CM_CLKSEL1_CORE_VAL		(R2_CLKSEL_USB | RX_CLKSEL_SSI | \
+					 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					 R2_CLKSEL_L4 | R2_CLKSEL_L3)
+#define R2_CLKSEL_MPU			(2 << 0)
+#define R2_CM_CLKSEL_MPU_VAL		R2_CLKSEL_MPU
+#define R2_CLKSEL_DSP			(2 << 0)
+#define R2_CLKSEL_DSP_IF		(3 << 5)
+#define R2_CM_CLKSEL_DSP_VAL		(R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF)
+#define R2_CLKSEL_GFX			(2 << 0)
+#define R2_CM_CLKSEL_GFX_VAL		R2_CLKSEL_GFX
+#define R2_CLKSEL_MDM			(6 << 0)
+#define R2_CM_CLKSEL_MDM_VAL		R2_CLKSEL_MDM
+
+/* 2430-Ratio Bootm (BYPASS) */
+#define RB_CLKSEL_L3			(1 << 0)
+#define RB_CLKSEL_L4			(1 << 5)
+#define RB_CLKSEL_USB			(1 << 25)
+#define RB_CM_CLKSEL1_CORE_VAL		(RB_CLKSEL_USB | RX_CLKSEL_SSI | \
+					 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					 RB_CLKSEL_L4 | RB_CLKSEL_L3)
+#define RB_CLKSEL_MPU			(1 << 0)
+#define RB_CM_CLKSEL_MPU_VAL		RB_CLKSEL_MPU
+#define RB_CLKSEL_DSP			(1 << 0)
+#define RB_CLKSEL_DSP_IF		(1 << 5)
+#define RB_CM_CLKSEL_DSP_VAL		(RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF)
+#define RB_CLKSEL_GFX			(1 << 0)
+#define RB_CM_CLKSEL_GFX_VAL		RB_CLKSEL_GFX
+#define RB_CLKSEL_MDM			(1 << 0)
+#define RB_CM_CLKSEL_MDM_VAL		RB_CLKSEL_MDM
+
+/* 2420 Ratio Equivalents */
+#define RXX_CLKSEL_VLYNQ		(0x12 << 15)
+#define RXX_CLKSEL_SSI			(0x8 << 20)
+
+/* 2420-PRCM III 532MHz core */
+#define RIII_CLKSEL_L3			(4 << 0)	/* 133MHz */
+#define RIII_CLKSEL_L4			(2 << 5)	/* 66.5MHz */
+#define RIII_CLKSEL_USB			(4 << 25)	/* 33.25MHz */
+#define RIII_CM_CLKSEL1_CORE_VAL	(RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+					 RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+					 RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
+					 RIII_CLKSEL_L3)
+#define RIII_CLKSEL_MPU			(2 << 0)	/* 266MHz */
+#define RIII_CM_CLKSEL_MPU_VAL		RIII_CLKSEL_MPU
+#define RIII_CLKSEL_DSP			(3 << 0)	/* c5x - 177.3MHz */
+#define RIII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 88.67MHz */
+#define RIII_SYNC_DSP			(1 << 7)	/* Enable sync */
+#define RIII_CLKSEL_IVA			(6 << 8)	/* iva1 - 88.67MHz */
+#define RIII_SYNC_IVA			(1 << 13)	/* Enable sync */
+#define RIII_CM_CLKSEL_DSP_VAL		(RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
+					 RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
+					 RIII_CLKSEL_DSP)
+#define RIII_CLKSEL_GFX			(2 << 0)	/* 66.5MHz */
+#define RIII_CM_CLKSEL_GFX_VAL		RIII_CLKSEL_GFX
+
+/* 2420-PRCM II 600MHz core */
+#define RII_CLKSEL_L3			(6 << 0)	/* 100MHz */
+#define RII_CLKSEL_L4			(2 << 5)	/* 50MHz */
+#define RII_CLKSEL_USB			(2 << 25)	/* 50MHz */
+#define RII_CM_CLKSEL1_CORE_VAL		(RII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+					 RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+					 RX_CLKSEL_DSS1 | RII_CLKSEL_L4 | \
+					 RII_CLKSEL_L3)
+#define RII_CLKSEL_MPU			(2 << 0)	/* 300MHz */
+#define RII_CM_CLKSEL_MPU_VAL		RII_CLKSEL_MPU
+#define RII_CLKSEL_DSP			(3 << 0)	/* c5x - 200MHz */
+#define RII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 100MHz */
+#define RII_SYNC_DSP			(0 << 7)	/* Bypass sync */
+#define RII_CLKSEL_IVA			(3 << 8)	/* iva1 - 200MHz */
+#define RII_SYNC_IVA			(0 << 13)	/* Bypass sync */
+#define RII_CM_CLKSEL_DSP_VAL		(RII_SYNC_IVA | RII_CLKSEL_IVA | \
+					 RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
+					 RII_CLKSEL_DSP)
+#define RII_CLKSEL_GFX			(2 << 0)	/* 50MHz */
+#define RII_CM_CLKSEL_GFX_VAL		RII_CLKSEL_GFX
+
+/* 2420-PRCM I 660MHz core */
+#define RI_CLKSEL_L3			(4 << 0)	/* 165MHz */
+#define RI_CLKSEL_L4			(2 << 5)	/* 82.5MHz */
+#define RI_CLKSEL_USB			(4 << 25)	/* 41.25MHz */
+#define RI_CM_CLKSEL1_CORE_VAL		(RI_CLKSEL_USB |		\
+					 RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
+					 RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					 RI_CLKSEL_L4 | RI_CLKSEL_L3)
+#define RI_CLKSEL_MPU			(2 << 0)	/* 330MHz */
+#define RI_CM_CLKSEL_MPU_VAL		RI_CLKSEL_MPU
+#define RI_CLKSEL_DSP			(3 << 0)	/* c5x - 220MHz */
+#define RI_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 110MHz */
+#define RI_SYNC_DSP			(1 << 7)	/* Activate sync */
+#define RI_CLKSEL_IVA			(4 << 8)	/* iva1 - 165MHz */
+#define RI_SYNC_IVA			(0 << 13)	/* Bypass sync */
+#define RI_CM_CLKSEL_DSP_VAL		(RI_SYNC_IVA | RI_CLKSEL_IVA |	\
+					 RI_SYNC_DSP | RI_CLKSEL_DSP_IF | \
+					 RI_CLKSEL_DSP)
+#define RI_CLKSEL_GFX			(1 << 0)	/* 165MHz */
+#define RI_CM_CLKSEL_GFX_VAL		RI_CLKSEL_GFX
+
+/* 2420-PRCM VII (boot) */
+#define RVII_CLKSEL_L3			(1 << 0)
+#define RVII_CLKSEL_L4			(1 << 5)
+#define RVII_CLKSEL_DSS1		(1 << 8)
+#define RVII_CLKSEL_DSS2		(0 << 13)
+#define RVII_CLKSEL_VLYNQ		(1 << 15)
+#define RVII_CLKSEL_SSI			(1 << 20)
+#define RVII_CLKSEL_USB			(1 << 25)
+
+#define RVII_CM_CLKSEL1_CORE_VAL	(RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
+					 RVII_CLKSEL_VLYNQ | \
+					 RVII_CLKSEL_DSS2 | RVII_CLKSEL_DSS1 | \
+					 RVII_CLKSEL_L4 | RVII_CLKSEL_L3)
+
+#define RVII_CLKSEL_MPU			(1 << 0) /* all divide by 1 */
+#define RVII_CM_CLKSEL_MPU_VAL		RVII_CLKSEL_MPU
+
+#define RVII_CLKSEL_DSP			(1 << 0)
+#define RVII_CLKSEL_DSP_IF		(1 << 5)
+#define RVII_SYNC_DSP			(0 << 7)
+#define RVII_CLKSEL_IVA			(1 << 8)
+#define RVII_SYNC_IVA			(0 << 13)
+#define RVII_CM_CLKSEL_DSP_VAL		(RVII_SYNC_IVA | RVII_CLKSEL_IVA | \
+					 RVII_SYNC_DSP | RVII_CLKSEL_DSP_IF | \
+					 RVII_CLKSEL_DSP)
+
+#define RVII_CLKSEL_GFX			(1 << 0)
+#define RVII_CM_CLKSEL_GFX_VAL		RVII_CLKSEL_GFX
+
+/*-------------------------------------------------------------------------
+ * 2430 Target modes: Along with each configuration the CPU has several
+ * modes which goes along with them. Modes mainly are the addition of
+ * describe DPLL combinations to go along with a ratio.
+ *-------------------------------------------------------------------------*/
+
+/* Hardware governed */
+#define MX_48M_SRC			(0 << 3)
+#define MX_54M_SRC			(0 << 5)
+#define MX_APLLS_CLIKIN_12		(3 << 23)
+#define MX_APLLS_CLIKIN_13		(2 << 23)
+#define MX_APLLS_CLIKIN_19_2		(0 << 23)
+
+/*
+ * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
+ * #5a	(ratio1) baseport-target, target DPLL = 266*2 = 532MHz
+ */
+#define M5A_DPLL_MULT_12		(133 << 12)
+#define M5A_DPLL_DIV_12			(5 << 8)
+#define M5A_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+#define M5A_DPLL_MULT_13		(61 << 12)
+#define M5A_DPLL_DIV_13			(2 << 8)
+#define M5A_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+#define M5A_DPLL_MULT_19		(55 << 12)
+#define M5A_DPLL_DIV_19			(3 << 8)
+#define M5A_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
+					 MX_APLLS_CLIKIN_19_2)
+/* #5b	(ratio1) target DPLL = 200*2 = 400MHz */
+#define M5B_DPLL_MULT_12		(50 << 12)
+#define M5B_DPLL_DIV_12			(2 << 8)
+#define M5B_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+#define M5B_DPLL_MULT_13		(200 << 12)
+#define M5B_DPLL_DIV_13			(12 << 8)
+
+#define M5B_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+#define M5B_DPLL_MULT_19		(125 << 12)
+#define M5B_DPLL_DIV_19			(31 << 8)
+#define M5B_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
+					 MX_APLLS_CLIKIN_19_2)
+/*
+ * #4	(ratio2), DPLL = 399*2 = 798MHz, L3=133MHz
+ */
+#define M4_DPLL_MULT_12			(133 << 12)
+#define M4_DPLL_DIV_12			(3 << 8)
+#define M4_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M4_DPLL_DIV_12 | M4_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+
+#define M4_DPLL_MULT_13			(399 << 12)
+#define M4_DPLL_DIV_13			(12 << 8)
+#define M4_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M4_DPLL_DIV_13 | M4_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+
+#define M4_DPLL_MULT_19			(145 << 12)
+#define M4_DPLL_DIV_19			(6 << 8)
+#define M4_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M4_DPLL_DIV_19 | M4_DPLL_MULT_19 | \
+					 MX_APLLS_CLIKIN_19_2)
+
+/*
+ * #3	(ratio2) baseport-target, target DPLL = 330*2 = 660MHz
+ */
+#define M3_DPLL_MULT_12			(55 << 12)
+#define M3_DPLL_DIV_12			(1 << 8)
+#define M3_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+#define M3_DPLL_MULT_13			(76 << 12)
+#define M3_DPLL_DIV_13			(2 << 8)
+#define M3_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+#define M3_DPLL_MULT_19			(17 << 12)
+#define M3_DPLL_DIV_19			(0 << 8)
+#define M3_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
+					 MX_APLLS_CLIKIN_19_2)
+
+/*
+ * #2   (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz
+ */
+#define M2_DPLL_MULT_12		        (55 << 12)
+#define M2_DPLL_DIV_12		        (1 << 8)
+#define M2_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M2_DPLL_DIV_12 | M2_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+
+/* Speed changes - Used 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2,
+ * relock time issue */
+/* Core frequency changed from 330/165 to 329/164 MHz*/
+#define M2_DPLL_MULT_13		        (76 << 12)
+#define M2_DPLL_DIV_13		        (2 << 8)
+#define M2_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M2_DPLL_DIV_13 | M2_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+
+#define M2_DPLL_MULT_19		        (17 << 12)
+#define M2_DPLL_DIV_19		        (0 << 8)
+#define M2_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 M2_DPLL_DIV_19 | M2_DPLL_MULT_19 | \
+					 MX_APLLS_CLIKIN_19_2)
+
+/* boot (boot) */
+#define MB_DPLL_MULT			(1 << 12)
+#define MB_DPLL_DIV			(0 << 8)
+#define MB_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 MB_DPLL_DIV | MB_DPLL_MULT | \
+					 MX_APLLS_CLIKIN_12)
+
+#define MB_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 MB_DPLL_DIV | MB_DPLL_MULT | \
+					 MX_APLLS_CLIKIN_13)
+
+#define MB_CM_CLKSEL1_PLL_19_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 MB_DPLL_DIV | MB_DPLL_MULT | \
+					 MX_APLLS_CLIKIN_19)
+
+/*
+ * 2430 - chassis (sedna)
+ * 165 (ratio1) same as above #2
+ * 150 (ratio1)
+ * 133 (ratio2) same as above #4
+ * 110 (ratio2) same as above #3
+ * 104 (ratio2)
+ * boot (boot)
+ */
+
+/* PRCM I target DPLL = 2*330MHz = 660MHz */
+#define MI_DPLL_MULT_12			(55 << 12)
+#define MI_DPLL_DIV_12			(1 << 8)
+#define MI_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC | \
+					 MI_DPLL_DIV_12 | MI_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+
+/*
+ * 2420 Equivalent - mode registers
+ * PRCM II , target DPLL = 2*300MHz = 600MHz
+ */
+#define MII_DPLL_MULT_12		(50 << 12)
+#define MII_DPLL_DIV_12			(1 << 8)
+#define MII_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC |	\
+					 MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
+					 MX_APLLS_CLIKIN_12)
+#define MII_DPLL_MULT_13		(300 << 12)
+#define MII_DPLL_DIV_13			(12 << 8)
+#define MII_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC |	\
+					 MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
+					 MX_APLLS_CLIKIN_13)
+
+/* PRCM III target DPLL = 2*266 = 532MHz*/
+#define MIII_DPLL_MULT_12		(133 << 12)
+#define MIII_DPLL_DIV_12		(5 << 8)
+#define MIII_CM_CLKSEL1_PLL_12_VAL	(MX_48M_SRC | MX_54M_SRC |	\
+					 MIII_DPLL_DIV_12 | \
+					 MIII_DPLL_MULT_12 | MX_APLLS_CLIKIN_12)
+#define MIII_DPLL_MULT_13		(266 << 12)
+#define MIII_DPLL_DIV_13		(12 << 8)
+#define MIII_CM_CLKSEL1_PLL_13_VAL	(MX_48M_SRC | MX_54M_SRC |	\
+					 MIII_DPLL_DIV_13 | \
+					 MIII_DPLL_MULT_13 | MX_APLLS_CLIKIN_13)
+
+/* PRCM VII (boot bypass) */
+#define MVII_CM_CLKSEL1_PLL_12_VAL	MB_CM_CLKSEL1_PLL_12_VAL
+#define MVII_CM_CLKSEL1_PLL_13_VAL	MB_CM_CLKSEL1_PLL_13_VAL
+
+/* High and low operation value */
+#define MX_CLKSEL2_PLL_2x_VAL		(2 << 0)
+#define MX_CLKSEL2_PLL_1x_VAL		(1 << 0)
+
+/* MPU speed defines */
+#define S12M	12000000
+#define S13M	13000000
+#define S19M	19200000
+#define S26M	26000000
+#define S100M	100000000
+#define S133M	133000000
+#define S150M	150000000
+#define S164M	164000000
+#define S165M	165000000
+#define S199M	199000000
+#define S200M	200000000
+#define S266M	266000000
+#define S300M	300000000
+#define S329M	329000000
+#define S330M	330000000
+#define S399M	399000000
+#define S400M	400000000
+#define S532M	532000000
+#define S600M	600000000
+#define S658M	658000000
+#define S660M	660000000
+#define S798M	798000000
+
+
+extern const struct prcm_config omap2420_rate_table[];
+extern const struct prcm_config omap2430_rate_table[];
+extern const struct prcm_config *rate_table;
+extern const struct prcm_config *curr_prcm_set;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm24xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm24xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm24xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm24xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,12 +36,12 @@
 #include <asm/mach-types.h>
 
 #include <mach/irqs.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
-#include <mach/control.h>
-#include <mach/mux.h>
-#include <mach/dma.h>
-#include <mach/board.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/control.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/board.h>
 
 #include "prm.h"
 #include "prm-regbits-24xx.h"
@@ -50,8 +50,8 @@
 #include "sdrc.h"
 #include "pm.h"
 
-#include <mach/powerdomain.h>
-#include <mach/clockdomain.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
 
 static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm34xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm34xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm34xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm34xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,9 @@
  * Tony Lindgren <tony@atomide.com>
  * Jouni Hogander
  *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
  * Copyright (C) 2005 Texas Instruments, Inc.
  * Richard Woodruff <r-woodruff2@ti.com>
  *
@@ -22,12 +25,21 @@
 #include <linux/list.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
 
-#include <mach/sram.h>
-#include <mach/clockdomain.h>
-#include <mach/powerdomain.h>
-#include <mach/control.h>
-#include <mach/serial.h>
+#include <plat/sram.h>
+#include <plat/clockdomain.h>
+#include <plat/powerdomain.h>
+#include <plat/control.h>
+#include <plat/serial.h>
+#include <plat/sdrc.h>
+#include <plat/prcm.h>
+#include <plat/gpmc.h>
+#include <plat/dma.h>
+#include <plat/dmtimer.h>
+
+#include <asm/tlbflush.h>
 
 #include "cm.h"
 #include "cm-regbits-34xx.h"
@@ -35,6 +47,16 @@
 
 #include "prm.h"
 #include "pm.h"
+#include "sdrc.h"
+
+/* Scratchpad offsets */
+#define OMAP343X_TABLE_ADDRESS_OFFSET	   0x31
+#define OMAP343X_TABLE_VALUE_OFFSET	   0x30
+#define OMAP343X_CONTROL_REG_VALUE_OFFSET  0x32
+
+u32 enable_off_mode;
+u32 sleep_while_idle;
+u32 wakeup_timer_seconds;
 
 struct power_state {
 	struct powerdomain *pwrdm;
@@ -49,7 +71,120 @@ static LIST_HEAD(pwrst_list);
 
 static void (*_omap_sram_idle)(u32 *addr, int save_state);
 
-static struct powerdomain *mpu_pwrdm;
+static int (*_omap_save_secure_sram)(u32 *addr);
+
+static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
+static struct powerdomain *core_pwrdm, *per_pwrdm;
+static struct powerdomain *cam_pwrdm;
+
+static inline void omap3_per_save_context(void)
+{
+	omap_gpio_save_context();
+}
+
+static inline void omap3_per_restore_context(void)
+{
+	omap_gpio_restore_context();
+}
+
+static void omap3_enable_io_chain(void)
+{
+	int timeout = 0;
+
+	if (omap_rev() >= OMAP3430_REV_ES3_1) {
+		prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN);
+		/* Do a readback to assure write has been done */
+		prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+		while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+			 OMAP3430_ST_IO_CHAIN)) {
+			timeout++;
+			if (timeout > 1000) {
+				printk(KERN_ERR "Wake up daisy chain "
+				       "activation failed.\n");
+				return;
+			}
+			prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN,
+					     WKUP_MOD, PM_WKST);
+		}
+	}
+}
+
+static void omap3_disable_io_chain(void)
+{
+	if (omap_rev() >= OMAP3430_REV_ES3_1)
+		prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN, WKUP_MOD, PM_WKEN);
+}
+
+static void omap3_core_save_context(void)
+{
+	u32 control_padconf_off;
+
+	/* Save the padconf registers */
+	control_padconf_off = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
+	control_padconf_off |= START_PADCONF_SAVE;
+	omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF);
+	/* wait for the save to complete */
+	while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
+			& PADCONF_SAVE_DONE))
+		udelay(1);
+
+	/*
+	 * Force write last pad into memory, as this can fail in some
+	 * cases according to erratas 1.157, 1.185
+	 */
+	omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
+		OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
+
+	/* Save the Interrupt controller context */
+	omap_intc_save_context();
+	/* Save the GPMC context */
+	omap3_gpmc_save_context();
+	/* Save the system control module context, padconf already save above*/
+	omap3_control_save_context();
+	omap_dma_global_context_save();
+}
+
+static void omap3_core_restore_context(void)
+{
+	/* Restore the control module context, padconf restored by h/w */
+	omap3_control_restore_context();
+	/* Restore the GPMC context */
+	omap3_gpmc_restore_context();
+	/* Restore the interrupt controller context */
+	omap_intc_restore_context();
+	omap_dma_global_context_restore();
+}
+
+/*
+ * FIXME: This function should be called before entering off-mode after
+ * OMAP3 secure services have been accessed. Currently it is only called
+ * once during boot sequence, but this works as we are not using secure
+ * services.
+ */
+static void omap3_save_secure_ram_context(u32 target_mpu_state)
+{
+	u32 ret;
+
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+		/*
+		 * MPU next state must be set to POWER_ON temporarily,
+		 * otherwise the WFI executed inside the ROM code
+		 * will hang the system.
+		 */
+		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+		ret = _omap_save_secure_sram((u32 *)
+				__pa(omap3_secure_ram_storage));
+		pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state);
+		/* Following is for error tracking, it should not happen */
+		if (ret) {
+			printk(KERN_ERR "save_secure_sram() returns %08x\n",
+				ret);
+			while (1)
+				;
+		}
+	}
+}
 
 /*
  * PRCM Interrupt Handler Helper Function
@@ -161,7 +296,36 @@ static irqreturn_t prcm_interrupt_handle
 	return IRQ_HANDLED;
 }
 
-static void omap_sram_idle(void)
+static void restore_control_register(u32 val)
+{
+	__asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val));
+}
+
+/* Function to restore the table entry that was modified for enabling MMU */
+static void restore_table_entry(void)
+{
+	u32 *scratchpad_address;
+	u32 previous_value, control_reg_value;
+	u32 *address;
+
+	scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
+
+	/* Get address of entry that was modified */
+	address = (u32 *)__raw_readl(scratchpad_address +
+				     OMAP343X_TABLE_ADDRESS_OFFSET);
+	/* Get the previous value which needs to be restored */
+	previous_value = __raw_readl(scratchpad_address +
+				     OMAP343X_TABLE_VALUE_OFFSET);
+	address = __va(address);
+	*address = previous_value;
+	flush_tlb_all();
+	control_reg_value = __raw_readl(scratchpad_address
+					+ OMAP343X_CONTROL_REG_VALUE_OFFSET);
+	/* This will enable caches and prediction */
+	restore_control_register(control_reg_value);
+}
+
+void omap_sram_idle(void)
 {
 	/* Variable to tell what needs to be saved and restored
 	 * in omap_sram_idle*/
@@ -169,17 +333,32 @@ static void omap_sram_idle(void)
 	/* save_state = 1 => Only L1 and logic lost */
 	/* save_state = 2 => Only L2 lost */
 	/* save_state = 3 => L1, L2 and logic lost */
-	int save_state = 0, mpu_next_state;
+	int save_state = 0;
+	int mpu_next_state = PWRDM_POWER_ON;
+	int per_next_state = PWRDM_POWER_ON;
+	int core_next_state = PWRDM_POWER_ON;
+	int core_prev_state, per_prev_state;
+	u32 sdrc_pwr = 0;
+	int per_state_modified = 0;
 
 	if (!_omap_sram_idle)
 		return;
 
+	pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
+	pwrdm_clear_all_prev_pwrst(neon_pwrdm);
+	pwrdm_clear_all_prev_pwrst(core_pwrdm);
+	pwrdm_clear_all_prev_pwrst(per_pwrdm);
+
 	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
 	switch (mpu_next_state) {
+	case PWRDM_POWER_ON:
 	case PWRDM_POWER_RET:
 		/* No need to save context */
 		save_state = 0;
 		break;
+	case PWRDM_POWER_OFF:
+		save_state = 3;
+		break;
 	default:
 		/* Invalid state */
 		printk(KERN_ERR "Invalid mpu state in sram_idle\n");
@@ -187,68 +366,117 @@ static void omap_sram_idle(void)
 	}
 	pwrdm_pre_transition();
 
-	omap2_gpio_prepare_for_retention();
-	omap_uart_prepare_idle(0);
-	omap_uart_prepare_idle(1);
-	omap_uart_prepare_idle(2);
+	/* NEON control */
+	if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
+		pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
 
-	_omap_sram_idle(NULL, save_state);
+	/* PER */
+	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
+	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+	if (per_next_state < PWRDM_POWER_ON) {
+		omap_uart_prepare_idle(2);
+		omap2_gpio_prepare_for_retention();
+		if (per_next_state == PWRDM_POWER_OFF) {
+			if (core_next_state == PWRDM_POWER_ON) {
+				per_next_state = PWRDM_POWER_RET;
+				pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
+				per_state_modified = 1;
+			} else
+				omap3_per_save_context();
+		}
+	}
+
+	if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
+		omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
+
+	/* CORE */
+	if (core_next_state < PWRDM_POWER_ON) {
+		omap_uart_prepare_idle(0);
+		omap_uart_prepare_idle(1);
+		if (core_next_state == PWRDM_POWER_OFF) {
+			omap3_core_save_context();
+			omap3_prcm_save_context();
+		}
+		/* Enable IO-PAD and IO-CHAIN wakeups */
+		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+		omap3_enable_io_chain();
+	}
+	omap3_intc_prepare_idle();
+
+	/*
+	* On EMU/HS devices ROM code restores a SRDC value
+	* from scratchpad which has automatic self refresh on timeout
+	* of AUTO_CNT = 1 enabled. This takes care of errata 1.142.
+	* Hence store/restore the SDRC_POWER register here.
+	*/
+	if (omap_rev() >= OMAP3430_REV_ES3_0 &&
+	    omap_type() != OMAP2_DEVICE_TYPE_GP &&
+	    core_next_state == PWRDM_POWER_OFF)
+		sdrc_pwr = sdrc_read_reg(SDRC_POWER);
+
+	/*
+	 * omap3_arm_context is the location where ARM registers
+	 * get saved. The restore path then reads from this
+	 * location and restores them back.
+	 */
+	_omap_sram_idle(omap3_arm_context, save_state);
 	cpu_init();
 
-	omap_uart_resume_idle(2);
-	omap_uart_resume_idle(1);
-	omap_uart_resume_idle(0);
-	omap2_gpio_resume_after_retention();
+	/* Restore normal SDRC POWER settings */
+	if (omap_rev() >= OMAP3430_REV_ES3_0 &&
+	    omap_type() != OMAP2_DEVICE_TYPE_GP &&
+	    core_next_state == PWRDM_POWER_OFF)
+		sdrc_write_reg(sdrc_pwr, SDRC_POWER);
 
-	pwrdm_post_transition();
+	/* Restore table entry modified during MMU restoration */
+	if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
+		restore_table_entry();
 
-}
+	/* CORE */
+	if (core_next_state < PWRDM_POWER_ON) {
+		core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
+		if (core_prev_state == PWRDM_POWER_OFF) {
+			omap3_core_restore_context();
+			omap3_prcm_restore_context();
+			omap3_sram_restore_context();
+			omap2_sms_restore_context();
+		}
+		omap_uart_resume_idle(0);
+		omap_uart_resume_idle(1);
+		if (core_next_state == PWRDM_POWER_OFF)
+			prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF,
+					       OMAP3430_GR_MOD,
+					       OMAP3_PRM_VOLTCTRL_OFFSET);
+	}
+	omap3_intc_resume_idle();
 
-/*
- * Check if functional clocks are enabled before entering
- * sleep. This function could be behind CONFIG_PM_DEBUG
- * when all drivers are configuring their sysconfig registers
- * properly and using their clocks properly.
- */
-static int omap3_fclks_active(void)
-{
-	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
-		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
+	/* PER */
+	if (per_next_state < PWRDM_POWER_ON) {
+		per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
+		if (per_prev_state == PWRDM_POWER_OFF)
+			omap3_per_restore_context();
+		omap2_gpio_resume_after_retention();
+		omap_uart_resume_idle(2);
+		if (per_state_modified)
+			pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
+	}
 
-	fck_core1 = cm_read_mod_reg(CORE_MOD,
-				    CM_FCLKEN1);
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		fck_core3 = cm_read_mod_reg(CORE_MOD,
-					    OMAP3430ES2_CM_FCLKEN3);
-		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
-					  CM_FCLKEN);
-		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-					      CM_FCLKEN);
-	} else
-		fck_sgx = cm_read_mod_reg(GFX_MOD,
-					  OMAP3430ES2_CM_FCLKEN3);
-	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
-				  CM_FCLKEN);
-	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
-				  CM_FCLKEN);
-	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
-				  CM_FCLKEN);
+	/* Disable IO-PAD and IO-CHAIN wakeup */
+	if (core_next_state < PWRDM_POWER_ON) {
+		prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
+		omap3_disable_io_chain();
+	}
 
-	/* Ignore UART clocks.  These are handled by UART core (serial.c) */
-	fck_core1 &= ~(OMAP3430_EN_UART1 | OMAP3430_EN_UART2);
-	fck_per &= ~OMAP3430_EN_UART3;
+	pwrdm_post_transition();
 
-	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
-	    fck_cam | fck_per | fck_usbhost)
-		return 1;
-	return 0;
+	omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
-static int omap3_can_sleep(void)
+int omap3_can_sleep(void)
 {
-	if (!omap_uart_can_sleep())
+	if (!sleep_while_idle)
 		return 0;
-	if (omap3_fclks_active())
+	if (!omap_uart_can_sleep())
 		return 0;
 	return 1;
 }
@@ -256,7 +484,7 @@ static int omap3_can_sleep(void)
 /* This sets pwrdm state (other than mpu & core. Currently only ON &
  * RET are supported. Function is assuming that clkdm doesn't have
  * hw_sup mode enabled. */
-static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 {
 	u32 cur_state;
 	int sleep_switch = 0;
@@ -306,7 +534,7 @@ static void omap3_pm_idle(void)
 	if (!omap3_can_sleep())
 		goto out;
 
-	if (omap_irq_pending())
+	if (omap_irq_pending() || need_resched())
 		goto out;
 
 	omap_sram_idle();
@@ -319,6 +547,22 @@ out:
 #ifdef CONFIG_SUSPEND
 static suspend_state_t suspend_state;
 
+static void omap2_pm_wakeup_on_timer(u32 seconds)
+{
+	u32 tick_rate, cycles;
+
+	if (!seconds)
+		return;
+
+	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+	cycles = tick_rate * seconds;
+	omap_dm_timer_stop(gptimer_wakeup);
+	omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+	pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n",
+		seconds, cycles, tick_rate);
+}
+
 static int omap3_pm_prepare(void)
 {
 	disable_hlt();
@@ -330,6 +574,9 @@ static int omap3_pm_suspend(void)
 	struct power_state *pwrst;
 	int state, ret = 0;
 
+	if (wakeup_timer_seconds)
+		omap2_pm_wakeup_on_timer(wakeup_timer_seconds);
+
 	/* Read current next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node)
 		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
@@ -342,6 +589,8 @@ static int omap3_pm_suspend(void)
 	}
 
 	omap_uart_prepare_suspend();
+	omap3_intc_suspend();
+
 	omap_sram_idle();
 
 restore:
@@ -599,6 +848,8 @@ static void __init prcm_setup_regs(void)
 			CM_AUTOIDLE);
 	}
 
+	omap_ctrl_writel(OMAP3430_AUTOIDLE, OMAP2_CONTROL_SYSCONFIG);
+
 	/*
 	 * Set all plls to autoidle. This is needed until autoidle is
 	 * enabled by clockfw
@@ -639,15 +890,23 @@ static void __init prcm_setup_regs(void)
 	prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
 			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
+	/* Enable PM_WKEN to support DSS LPR */
+	prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS,
+				OMAP3430_DSS_MOD, PM_WKEN);
+
 	/* Enable wakeups in PER */
 	prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
 			  OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
-			  OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3,
+			  OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3 |
+			  OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 |
+			  OMAP3430_EN_MCBSP4,
 			  OMAP3430_PER_MOD, PM_WKEN);
 	/* and allow them to wake up MPU */
 	prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
 			  OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
-			  OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3,
+			  OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3 |
+			  OMAP3430_EN_MCBSP2 | OMAP3430_EN_MCBSP3 |
+			  OMAP3430_EN_MCBSP4,
 			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 
 	/* Don't attach IVA interrupts */
@@ -668,26 +927,24 @@ static void __init prcm_setup_regs(void)
 	/* Clear any pending PRCM interrupts */
 	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-	/* Don't attach IVA interrupts */
-	prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
-	prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
-	prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
-	prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+	omap3_iva_idle();
+	omap3_d2d_idle();
+}
 
-	/* Clear any pending 'reset' flags */
-	prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
-	prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
+void omap3_pm_off_mode_enable(int enable)
+{
+	struct power_state *pwrst;
+	u32 state;
 
-	/* Clear any pending PRCM interrupts */
-	prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+	if (enable)
+		state = PWRDM_POWER_OFF;
+	else
+		state = PWRDM_POWER_RET;
 
-	omap3_iva_idle();
-	omap3_d2d_idle();
+	list_for_each_entry(pwrst, &pwrst_list, node) {
+		pwrst->next_state = state;
+		set_pwrdm_state(pwrst->pwrdm, state);
+	}
 }
 
 int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
@@ -749,6 +1006,15 @@ static int __init clkdms_setup(struct cl
 	return 0;
 }
 
+void omap_push_sram_idle(void)
+{
+	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
+					omap34xx_cpu_suspend_sz);
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
+				save_secure_ram_context_sz);
+}
+
 static int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst, *tmp;
@@ -786,15 +1052,47 @@ static int __init omap3_pm_init(void)
 		goto err2;
 	}
 
-	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
-					 omap34xx_cpu_suspend_sz);
+	neon_pwrdm = pwrdm_lookup("neon_pwrdm");
+	per_pwrdm = pwrdm_lookup("per_pwrdm");
+	core_pwrdm = pwrdm_lookup("core_pwrdm");
+	cam_pwrdm = pwrdm_lookup("cam_pwrdm");
 
+	omap_push_sram_idle();
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
 
 	pm_idle = omap3_pm_idle;
+	omap3_idle_init();
 
+	pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm);
+	/*
+	 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
+	 * IO-pad wakeup.  Otherwise it will unnecessarily waste power
+	 * waking up PER with every CORE wakeup - see
+	 * http://marc.info/?l=linux-omap&m=121852150710062&w=2
+	*/
+	pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
+
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+		omap3_secure_ram_storage =
+			kmalloc(0x803F, GFP_KERNEL);
+		if (!omap3_secure_ram_storage)
+			printk(KERN_ERR "Memory allocation failed when"
+					"allocating for secure sram context\n");
+
+		local_irq_disable();
+		local_fiq_disable();
+
+		omap_dma_global_context_save();
+		omap3_save_secure_ram_context(PWRDM_POWER_ON);
+		omap_dma_global_context_restore();
+
+		local_irq_enable();
+		local_fiq_enable();
+	}
+
+	omap3_save_scratchpad_contents();
 err1:
 	return ret;
 err2:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm-debug.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm-debug.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm-debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm-debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,10 +26,10 @@
 #include <linux/io.h>
 #include <linux/module.h>
 
-#include <mach/clock.h>
-#include <mach/board.h>
-#include <mach/powerdomain.h>
-#include <mach/clockdomain.h>
+#include <plat/clock.h>
+#include <plat/board.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
 
 #include "prm.h"
 #include "cm.h"
@@ -51,9 +51,8 @@ int omap2_pm_debug;
 	regs[reg_count++].val = __raw_readl(reg)
 #define DUMP_INTC_REG(reg, off) \
 	regs[reg_count].name = #reg; \
-	regs[reg_count++].val = __raw_readl(OMAP2_IO_ADDRESS(0x480fe000 + (off)))
-
-static int __init pm_dbg_init(void);
+	regs[reg_count++].val = \
+			 __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
 
 void omap2_pm_dump(int mode, int resume, unsigned int us)
 {
@@ -166,6 +165,8 @@ struct dentry *pm_dbg_dir;
 
 static int pm_dbg_init_done;
 
+static int __init pm_dbg_init(void);
+
 enum {
 	DEBUG_FILE_COUNTERS = 0,
 	DEBUG_FILE_TIMERS,
@@ -325,7 +326,7 @@ int pm_dbg_regset_save(int reg_set)
 	return 0;
 }
 
-static const char pwrdm_state_names[][4] = {
+static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
 	"OFF",
 	"RET",
 	"INA",
@@ -380,7 +381,7 @@ static int pwrdm_dbg_show_counter(struct
 
 	seq_printf(s, "%s (%s)", pwrdm->name,
 			pwrdm_state_names[pwrdm->state]);
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
 		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
 			pwrdm->state_counter[i]);
 
@@ -487,9 +488,11 @@ int pm_dbg_regset_init(int reg_set)
 
 static int pwrdm_suspend_get(void *data, u64 *val)
 {
-	*val = omap3_pm_get_suspend_state((struct powerdomain *)data);
+	int ret;
+	ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+	*val = ret;
 
-	if (*val >= 0)
+	if (ret >= 0)
 		return 0;
 	return *val;
 }
@@ -526,6 +529,29 @@ static int __init pwrdms_setup(struct po
 	return 0;
 }
 
+static int option_get(void *data, u64 *val)
+{
+	u32 *option = data;
+
+	*val = *option;
+
+	return 0;
+}
+
+static int option_set(void *data, u64 val)
+{
+	u32 *option = data;
+
+	*option = val;
+
+	if (option == &enable_off_mode)
+		omap3_pm_off_mode_enable(val);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
+
 static int __init pm_dbg_init(void)
 {
 	int i;
@@ -568,12 +594,16 @@ static int __init pm_dbg_init(void)
 
 		}
 
+	(void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUGO, d,
+				   &enable_off_mode, &pm_dbg_option_fops);
+	(void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUGO, d,
+				   &sleep_while_idle, &pm_dbg_option_fops);
+	(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
+				   &wakeup_timer_seconds, &pm_dbg_option_fops);
 	pm_dbg_init_done = 1;
 
 	return 0;
 }
 arch_initcall(pm_dbg_init);
 
-#else
-void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {}
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/pm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/pm.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,20 +11,37 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PM_H
 #define __ARCH_ARM_MACH_OMAP2_PM_H
 
-#include <mach/powerdomain.h>
+#include <plat/powerdomain.h>
+
+extern u32 enable_off_mode;
+extern u32 sleep_while_idle;
+
+extern void *omap3_secure_ram_storage;
+extern void omap3_pm_off_mode_enable(int);
+extern void omap_sram_idle(void);
+extern int omap3_can_sleep(void);
+extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int omap3_idle_init(void);
 
 extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
 extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 
+extern u32 wakeup_timer_seconds;
+extern struct omap_dm_timer *gptimer_wakeup;
+
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
 extern int omap2_pm_debug;
+#else
+#define omap2_pm_dump(mode, resume, us)		do {} while (0);
+#define omap2_pm_debug				0
+#endif
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
 extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
 extern int pm_dbg_regset_save(int reg_set);
 extern int pm_dbg_regset_init(int reg_set);
 #else
-#define omap2_pm_dump(mode, resume, us)		do {} while (0);
-#define omap2_pm_debug				0
 #define pm_dbg_update_time(pwrdm, prev) do {} while (0);
 #define pm_dbg_regset_save(reg_set) do {} while (0);
 #define pm_dbg_regset_init(reg_set) do {} while (0);
@@ -36,6 +53,7 @@ extern void omap24xx_cpu_suspend(u32 dll
 					void __iomem *sdrc_power);
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
 extern void save_secure_ram_context(u32 *addr);
+extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
 extern unsigned int omap34xx_suspend_sz;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomain.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomain.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomain.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomain.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,9 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN
-# define DEBUG
-#endif
+#undef DEBUG
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -31,9 +29,9 @@
 #include "prm.h"
 #include "prm-regbits-34xx.h"
 
-#include <mach/cpu.h>
-#include <mach/powerdomain.h>
-#include <mach/clockdomain.h>
+#include <plat/cpu.h>
+#include <plat/powerdomain.h>
+#include <plat/clockdomain.h>
 
 #include "pm.h"
 
@@ -160,7 +158,7 @@ static __init void _pwrdm_setup(struct p
 {
 	int i;
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
 		pwrdm->state_counter[i] = 0;
 
 	pwrdm_wait_transition(pwrdm);
@@ -480,7 +478,7 @@ int pwrdm_add_wkdep(struct powerdomain *
 	if (IS_ERR(p)) {
 		pr_debug("powerdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
@@ -513,7 +511,7 @@ int pwrdm_del_wkdep(struct powerdomain *
 	if (IS_ERR(p)) {
 		pr_debug("powerdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	pr_debug("powerdomain: hardware will no longer wake up %s after %s "
@@ -550,7 +548,7 @@ int pwrdm_read_wkdep(struct powerdomain
 	if (IS_ERR(p)) {
 		pr_debug("powerdomain: hardware cannot set/clear wake up of "
 			 "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
@@ -573,10 +571,10 @@ int pwrdm_add_sleepdep(struct powerdomai
 {
 	struct powerdomain *p;
 
-	if (!pwrdm1)
+	if (!cpu_is_omap34xx())
 		return -EINVAL;
 
-	if (!cpu_is_omap34xx())
+	if (!pwrdm1)
 		return -EINVAL;
 
 	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
@@ -584,7 +582,7 @@ int pwrdm_add_sleepdep(struct powerdomai
 		pr_debug("powerdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", pwrdm1->name,
 			 pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
@@ -612,10 +610,10 @@ int pwrdm_del_sleepdep(struct powerdomai
 {
 	struct powerdomain *p;
 
-	if (!pwrdm1)
+	if (!cpu_is_omap34xx())
 		return -EINVAL;
 
-	if (!cpu_is_omap34xx())
+	if (!pwrdm1)
 		return -EINVAL;
 
 	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
@@ -623,7 +621,7 @@ int pwrdm_del_sleepdep(struct powerdomai
 		pr_debug("powerdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", pwrdm1->name,
 			 pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	pr_debug("powerdomain: will no longer prevent %s from sleeping if "
@@ -655,10 +653,10 @@ int pwrdm_read_sleepdep(struct powerdoma
 {
 	struct powerdomain *p;
 
-	if (!pwrdm1)
+	if (!cpu_is_omap34xx())
 		return -EINVAL;
 
-	if (!cpu_is_omap34xx())
+	if (!pwrdm1)
 		return -EINVAL;
 
 	p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
@@ -666,7 +664,7 @@ int pwrdm_read_sleepdep(struct powerdoma
 		pr_debug("powerdomain: hardware cannot set/clear sleep "
 			 "dependency affecting %s from %s\n", pwrdm1->name,
 			 pwrdm2->name);
-		return IS_ERR(p);
+		return PTR_ERR(p);
 	}
 
 	return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
@@ -985,6 +983,9 @@ int pwrdm_read_mem_pwrst(struct powerdom
 	if (pwrdm->banks < (bank + 1))
 		return -EEXIST;
 
+	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
+		bank = 1;
+
 	/*
 	 * The register bit names below may not correspond to the
 	 * actual names of the bits in each powerdomain's register,
@@ -1032,6 +1033,9 @@ int pwrdm_read_prev_mem_pwrst(struct pow
 	if (pwrdm->banks < (bank + 1))
 		return -EEXIST;
 
+	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
+		bank = 1;
+
 	/*
 	 * The register bit names below may not correspond to the
 	 * actual names of the bits in each powerdomain's register,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains24xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains24xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains24xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains24xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@
  * the array in mach-omap2/powerdomains.h.
  */
 
-#include <mach/powerdomain.h>
+#include <plat/powerdomain.h>
 
 #include "prcm-common.h"
 #include "prm.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains34xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@
  * the array in mach-omap2/powerdomains.h.
  */
 
-#include <mach/powerdomain.h>
+#include <plat/powerdomain.h>
 
 #include "prcm-common.h"
 #include "prm.h"
@@ -190,6 +190,7 @@ static struct powerdomain mpu_34xx_pwrdm
 	.wkdep_srcs	  = mpu_34xx_wkdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.flags		  = PWRDM_HAS_MPU_QUIRK,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRSTS_OFF_RET,
@@ -338,7 +339,13 @@ static struct powerdomain usbhost_pwrdm
 	.sleepdep_srcs	  = dss_per_usbhost_sleepdeps,
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
-	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBHOST ctrlr only */
+	/*
+	 * REVISIT: Enabling usb host save and restore mechanism seems to
+	 * leave the usb host domain permanently in ACTIVE mode after
+	 * changing the usb host power domain state from OFF to active once.
+	 * Disabling for now.
+	 */
+	/*.flags	  = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/powerdomains.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/powerdomains.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,7 +63,7 @@
  * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
  */
 
-#include <mach/powerdomain.h>
+#include <plat/powerdomain.h>
 
 #include "prcm-common.h"
 #include "prm.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prcm.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prcm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,9 @@
  *
  * Written by Tony Lindgren <tony.lindgren@nokia.com>
  *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
  * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -19,18 +22,102 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 
-#include <mach/common.h>
-#include <mach/prcm.h>
+#include <plat/common.h>
+#include <plat/prcm.h>
+#include <plat/irqs.h>
+#include <plat/control.h>
 
 #include "clock.h"
+#include "cm.h"
 #include "prm.h"
 #include "prm-regbits-24xx.h"
 
 static void __iomem *prm_base;
 static void __iomem *cm_base;
+static void __iomem *cm2_base;
 
 #define MAX_MODULE_ENABLE_WAIT		100000
 
+struct omap3_prcm_regs {
+	u32 control_padconf_sys_nirq;
+	u32 iva2_cm_clksel1;
+	u32 iva2_cm_clksel2;
+	u32 cm_sysconfig;
+	u32 sgx_cm_clksel;
+	u32 dss_cm_clksel;
+	u32 cam_cm_clksel;
+	u32 per_cm_clksel;
+	u32 emu_cm_clksel;
+	u32 emu_cm_clkstctrl;
+	u32 pll_cm_autoidle2;
+	u32 pll_cm_clksel4;
+	u32 pll_cm_clksel5;
+	u32 pll_cm_clken2;
+	u32 cm_polctrl;
+	u32 iva2_cm_fclken;
+	u32 iva2_cm_clken_pll;
+	u32 core_cm_fclken1;
+	u32 core_cm_fclken3;
+	u32 sgx_cm_fclken;
+	u32 wkup_cm_fclken;
+	u32 dss_cm_fclken;
+	u32 cam_cm_fclken;
+	u32 per_cm_fclken;
+	u32 usbhost_cm_fclken;
+	u32 core_cm_iclken1;
+	u32 core_cm_iclken2;
+	u32 core_cm_iclken3;
+	u32 sgx_cm_iclken;
+	u32 wkup_cm_iclken;
+	u32 dss_cm_iclken;
+	u32 cam_cm_iclken;
+	u32 per_cm_iclken;
+	u32 usbhost_cm_iclken;
+	u32 iva2_cm_autiidle2;
+	u32 mpu_cm_autoidle2;
+	u32 iva2_cm_clkstctrl;
+	u32 mpu_cm_clkstctrl;
+	u32 core_cm_clkstctrl;
+	u32 sgx_cm_clkstctrl;
+	u32 dss_cm_clkstctrl;
+	u32 cam_cm_clkstctrl;
+	u32 per_cm_clkstctrl;
+	u32 neon_cm_clkstctrl;
+	u32 usbhost_cm_clkstctrl;
+	u32 core_cm_autoidle1;
+	u32 core_cm_autoidle2;
+	u32 core_cm_autoidle3;
+	u32 wkup_cm_autoidle;
+	u32 dss_cm_autoidle;
+	u32 cam_cm_autoidle;
+	u32 per_cm_autoidle;
+	u32 usbhost_cm_autoidle;
+	u32 sgx_cm_sleepdep;
+	u32 dss_cm_sleepdep;
+	u32 cam_cm_sleepdep;
+	u32 per_cm_sleepdep;
+	u32 usbhost_cm_sleepdep;
+	u32 cm_clkout_ctrl;
+	u32 prm_clkout_ctrl;
+	u32 sgx_pm_wkdep;
+	u32 dss_pm_wkdep;
+	u32 cam_pm_wkdep;
+	u32 per_pm_wkdep;
+	u32 neon_pm_wkdep;
+	u32 usbhost_pm_wkdep;
+	u32 core_pm_mpugrpsel1;
+	u32 iva2_pm_ivagrpsel1;
+	u32 core_pm_mpugrpsel3;
+	u32 core_pm_ivagrpsel3;
+	u32 wkup_pm_mpugrpsel;
+	u32 wkup_pm_ivagrpsel;
+	u32 per_pm_mpugrpsel;
+	u32 per_pm_ivagrpsel;
+	u32 wkup_pm_wken;
+};
+
+struct omap3_prcm_regs prcm_context;
+
 u32 omap_prcm_get_reset_sources(void)
 {
 	/* XXX This presumably needs modification for 34XX */
@@ -46,9 +133,18 @@ void omap_prcm_arch_reset(char mode)
 
 	if (cpu_is_omap24xx())
 		prcm_offs = WKUP_MOD;
-	else if (cpu_is_omap34xx())
+	else if (cpu_is_omap34xx()) {
+		u32 l;
+
 		prcm_offs = OMAP3430_GR_MOD;
-	else
+		l = ('B' << 24) | ('M' << 16) | mode;
+		/* Reserve the first word in scratchpad for communicating
+		 * with the boot ROM. A pointer to a data structure
+		 * describing the boot process can be stored there,
+		 * cf. OMAP34xx TRM, Initialization / Software Booting
+		 * Configuration. */
+		omap_writel(l, OMAP343X_SCRATCHPAD + 4);
+	} else
 		WARN_ON(1);
 
 	prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL);
@@ -72,14 +168,12 @@ u32 prm_read_mod_reg(s16 module, u16 idx
 {
 	return __omap_prcm_read(prm_base, module, idx);
 }
-EXPORT_SYMBOL(prm_read_mod_reg);
 
 /* Write into a register in a PRM module */
 void prm_write_mod_reg(u32 val, s16 module, u16 idx)
 {
 	__omap_prcm_write(val, prm_base, module, idx);
 }
-EXPORT_SYMBOL(prm_write_mod_reg);
 
 /* Read-modify-write a register in a PRM module. Caller must lock */
 u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
@@ -93,21 +187,18 @@ u32 prm_rmw_mod_reg_bits(u32 mask, u32 b
 
 	return v;
 }
-EXPORT_SYMBOL(prm_rmw_mod_reg_bits);
 
 /* Read a register in a CM module */
 u32 cm_read_mod_reg(s16 module, u16 idx)
 {
 	return __omap_prcm_read(cm_base, module, idx);
 }
-EXPORT_SYMBOL(cm_read_mod_reg);
 
 /* Write into a register in a CM module */
 void cm_write_mod_reg(u32 val, s16 module, u16 idx)
 {
 	__omap_prcm_write(val, cm_base, module, idx);
 }
-EXPORT_SYMBOL(cm_write_mod_reg);
 
 /* Read-modify-write a register in a CM module. Caller must lock */
 u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
@@ -121,7 +212,6 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bi
 
 	return v;
 }
-EXPORT_SYMBOL(cm_rmw_mod_reg_bits);
 
 /**
  * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
@@ -149,9 +239,8 @@ int omap2_cm_wait_idlest(void __iomem *r
 		BUG();
 
 	/* Wait for lock */
-	while (((__raw_readl(reg) & mask) != ena) &&
-	       (i++ < MAX_MODULE_ENABLE_WAIT))
-		udelay(1);
+	omap_test_timeout(((__raw_readl(reg) & mask) == ena),
+			  MAX_MODULE_ENABLE_WAIT, i);
 
 	if (i < MAX_MODULE_ENABLE_WAIT)
 		pr_debug("cm: Module associated with clock %s ready after %d "
@@ -167,4 +256,302 @@ void __init omap2_set_globals_prcm(struc
 {
 	prm_base = omap2_globals->prm;
 	cm_base = omap2_globals->cm;
+	cm2_base = omap2_globals->cm2;
 }
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3_prcm_save_context(void)
+{
+	prcm_context.control_padconf_sys_nirq =
+			 omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
+	prcm_context.iva2_cm_clksel1 =
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+	prcm_context.iva2_cm_clksel2 =
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
+	prcm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
+	prcm_context.sgx_cm_clksel =
+			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
+	prcm_context.dss_cm_clksel =
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
+	prcm_context.cam_cm_clksel =
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
+	prcm_context.per_cm_clksel =
+			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
+	prcm_context.emu_cm_clksel =
+			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
+	prcm_context.emu_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL);
+	prcm_context.pll_cm_autoidle2 =
+			 cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
+	prcm_context.pll_cm_clksel4 =
+			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
+	prcm_context.pll_cm_clksel5 =
+			 cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
+	prcm_context.pll_cm_clken2 =
+			cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
+	prcm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
+	prcm_context.iva2_cm_fclken =
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
+	prcm_context.iva2_cm_clken_pll = cm_read_mod_reg(OMAP3430_IVA2_MOD,
+			OMAP3430_CM_CLKEN_PLL);
+	prcm_context.core_cm_fclken1 =
+			 cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+	prcm_context.core_cm_fclken3 =
+			 cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
+	prcm_context.sgx_cm_fclken =
+			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
+	prcm_context.wkup_cm_fclken =
+			 cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
+	prcm_context.dss_cm_fclken =
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
+	prcm_context.cam_cm_fclken =
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
+	prcm_context.per_cm_fclken =
+			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
+	prcm_context.usbhost_cm_fclken =
+			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+	prcm_context.core_cm_iclken1 =
+			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
+	prcm_context.core_cm_iclken2 =
+			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
+	prcm_context.core_cm_iclken3 =
+			 cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
+	prcm_context.sgx_cm_iclken =
+			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
+	prcm_context.wkup_cm_iclken =
+			 cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
+	prcm_context.dss_cm_iclken =
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
+	prcm_context.cam_cm_iclken =
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
+	prcm_context.per_cm_iclken =
+			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
+	prcm_context.usbhost_cm_iclken =
+			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+	prcm_context.iva2_cm_autiidle2 =
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
+	prcm_context.mpu_cm_autoidle2 =
+			 cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
+	prcm_context.iva2_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
+	prcm_context.mpu_cm_clkstctrl =
+			 cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL);
+	prcm_context.core_cm_clkstctrl =
+			 cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
+	prcm_context.sgx_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSTCTRL);
+	prcm_context.dss_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL);
+	prcm_context.cam_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL);
+	prcm_context.per_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL);
+	prcm_context.neon_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL);
+	prcm_context.usbhost_cm_clkstctrl =
+			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
+	prcm_context.core_cm_autoidle1 =
+			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
+	prcm_context.core_cm_autoidle2 =
+			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
+	prcm_context.core_cm_autoidle3 =
+			 cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
+	prcm_context.wkup_cm_autoidle =
+			 cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
+	prcm_context.dss_cm_autoidle =
+			 cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
+	prcm_context.cam_cm_autoidle =
+			 cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
+	prcm_context.per_cm_autoidle =
+			 cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+	prcm_context.usbhost_cm_autoidle =
+			 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+	prcm_context.sgx_cm_sleepdep =
+		 cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP);
+	prcm_context.dss_cm_sleepdep =
+		 cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
+	prcm_context.cam_cm_sleepdep =
+		 cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
+	prcm_context.per_cm_sleepdep =
+		 cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
+	prcm_context.usbhost_cm_sleepdep =
+		 cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+	prcm_context.cm_clkout_ctrl = cm_read_mod_reg(OMAP3430_CCR_MOD,
+		 OMAP3_CM_CLKOUT_CTRL_OFFSET);
+	prcm_context.prm_clkout_ctrl = prm_read_mod_reg(OMAP3430_CCR_MOD,
+		OMAP3_PRM_CLKOUT_CTRL_OFFSET);
+	prcm_context.sgx_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430ES2_SGX_MOD, PM_WKDEP);
+	prcm_context.dss_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430_DSS_MOD, PM_WKDEP);
+	prcm_context.cam_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430_CAM_MOD, PM_WKDEP);
+	prcm_context.per_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKDEP);
+	prcm_context.neon_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430_NEON_MOD, PM_WKDEP);
+	prcm_context.usbhost_pm_wkdep =
+		 prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
+	prcm_context.core_pm_mpugrpsel1 =
+		 prm_read_mod_reg(CORE_MOD, OMAP3430_PM_MPUGRPSEL1);
+	prcm_context.iva2_pm_ivagrpsel1 =
+		 prm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_PM_IVAGRPSEL1);
+	prcm_context.core_pm_mpugrpsel3 =
+		 prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3);
+	prcm_context.core_pm_ivagrpsel3 =
+		 prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+	prcm_context.wkup_pm_mpugrpsel =
+		 prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
+	prcm_context.wkup_pm_ivagrpsel =
+		 prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+	prcm_context.per_pm_mpugrpsel =
+		 prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
+	prcm_context.per_pm_ivagrpsel =
+		 prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+	prcm_context.wkup_pm_wken = prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+	return;
+}
+
+void omap3_prcm_restore_context(void)
+{
+	omap_ctrl_writel(prcm_context.control_padconf_sys_nirq,
+					 OMAP343X_CONTROL_PADCONF_SYSNIRQ);
+	cm_write_mod_reg(prcm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
+					 CM_CLKSEL1);
+	cm_write_mod_reg(prcm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
+					 CM_CLKSEL2);
+	__raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
+	cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
+					 CM_CLKSEL);
+	cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
+					 CM_CLKSEL);
+	cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
+					 CM_CLKSEL);
+	cm_write_mod_reg(prcm_context.per_cm_clksel, OMAP3430_PER_MOD,
+					 CM_CLKSEL);
+	cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
+					 CM_CLKSEL1);
+	cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
+					 CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
+					 CM_AUTOIDLE2);
+	cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
+					OMAP3430ES2_CM_CLKSEL4);
+	cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD,
+					 OMAP3430ES2_CM_CLKSEL5);
+	cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD,
+					OMAP3430ES2_CM_CLKEN2);
+	__raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
+	cm_write_mod_reg(prcm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
+					 CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
+					OMAP3430_CM_CLKEN_PLL);
+	cm_write_mod_reg(prcm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1);
+	cm_write_mod_reg(prcm_context.core_cm_fclken3, CORE_MOD,
+					 OMAP3430ES2_CM_FCLKEN3);
+	cm_write_mod_reg(prcm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
+					 CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
+					 CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
+					 CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.per_cm_fclken, OMAP3430_PER_MOD,
+					 CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.usbhost_cm_fclken,
+					 OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+	cm_write_mod_reg(prcm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1);
+	cm_write_mod_reg(prcm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2);
+	cm_write_mod_reg(prcm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3);
+	cm_write_mod_reg(prcm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
+					CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
+					CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
+					CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.per_cm_iclken, OMAP3430_PER_MOD,
+					CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.usbhost_cm_iclken,
+					OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+	cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD,
+					CM_AUTOIDLE2);
+	cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
+	cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
+					CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
+					OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
+	cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
+					CM_AUTOIDLE1);
+	cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
+					CM_AUTOIDLE2);
+	cm_write_mod_reg(prcm_context.core_cm_autoidle3, CORE_MOD,
+					CM_AUTOIDLE3);
+	cm_write_mod_reg(prcm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE);
+	cm_write_mod_reg(prcm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
+					CM_AUTOIDLE);
+	cm_write_mod_reg(prcm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
+					CM_AUTOIDLE);
+	cm_write_mod_reg(prcm_context.per_cm_autoidle, OMAP3430_PER_MOD,
+					CM_AUTOIDLE);
+	cm_write_mod_reg(prcm_context.usbhost_cm_autoidle,
+					OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+	cm_write_mod_reg(prcm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
+					OMAP3430_CM_SLEEPDEP);
+	cm_write_mod_reg(prcm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
+					OMAP3430_CM_SLEEPDEP);
+	cm_write_mod_reg(prcm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
+					OMAP3430_CM_SLEEPDEP);
+	cm_write_mod_reg(prcm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
+					OMAP3430_CM_SLEEPDEP);
+	cm_write_mod_reg(prcm_context.usbhost_cm_sleepdep,
+				OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+	cm_write_mod_reg(prcm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
+					OMAP3_CM_CLKOUT_CTRL_OFFSET);
+	prm_write_mod_reg(prcm_context.prm_clkout_ctrl, OMAP3430_CCR_MOD,
+					OMAP3_PRM_CLKOUT_CTRL_OFFSET);
+	prm_write_mod_reg(prcm_context.sgx_pm_wkdep, OMAP3430ES2_SGX_MOD,
+					PM_WKDEP);
+	prm_write_mod_reg(prcm_context.dss_pm_wkdep, OMAP3430_DSS_MOD,
+					PM_WKDEP);
+	prm_write_mod_reg(prcm_context.cam_pm_wkdep, OMAP3430_CAM_MOD,
+					PM_WKDEP);
+	prm_write_mod_reg(prcm_context.per_pm_wkdep, OMAP3430_PER_MOD,
+					PM_WKDEP);
+	prm_write_mod_reg(prcm_context.neon_pm_wkdep, OMAP3430_NEON_MOD,
+					PM_WKDEP);
+	prm_write_mod_reg(prcm_context.usbhost_pm_wkdep,
+					OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
+	prm_write_mod_reg(prcm_context.core_pm_mpugrpsel1, CORE_MOD,
+					OMAP3430_PM_MPUGRPSEL1);
+	prm_write_mod_reg(prcm_context.iva2_pm_ivagrpsel1, OMAP3430_IVA2_MOD,
+					OMAP3430_PM_IVAGRPSEL1);
+	prm_write_mod_reg(prcm_context.core_pm_mpugrpsel3, CORE_MOD,
+					OMAP3430ES2_PM_MPUGRPSEL3);
+	prm_write_mod_reg(prcm_context.core_pm_ivagrpsel3, CORE_MOD,
+					OMAP3430ES2_PM_IVAGRPSEL3);
+	prm_write_mod_reg(prcm_context.wkup_pm_mpugrpsel, WKUP_MOD,
+					OMAP3430_PM_MPUGRPSEL);
+	prm_write_mod_reg(prcm_context.wkup_pm_ivagrpsel, WKUP_MOD,
+					OMAP3430_PM_IVAGRPSEL);
+	prm_write_mod_reg(prcm_context.per_pm_mpugrpsel, OMAP3430_PER_MOD,
+					OMAP3430_PM_MPUGRPSEL);
+	prm_write_mod_reg(prcm_context.per_pm_ivagrpsel, OMAP3430_PER_MOD,
+					 OMAP3430_PM_IVAGRPSEL);
+	prm_write_mod_reg(prcm_context.wkup_pm_wken, WKUP_MOD, PM_WKEN);
+	return;
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prcm-common.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm-common.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prcm-common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prcm-common.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,10 +4,12 @@
 /*
  * OMAP2/3 PRCM base and module definitions
  *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
+ * OMAP4 defines in this file are automatically generated from the OMAP hardware
+ * databases.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -49,6 +51,73 @@
 #define OMAP3430_NEON_MOD				0xb00
 #define OMAP3430ES2_USBHOST_MOD				0xc00
 
+#define BITS(n_bit)	\
+	(((1 << n_bit) - 1) | (1 << n_bit))
+
+#define BITFIELD(l_bit, u_bit)	\
+	(BITS(u_bit) & ~((BITS(l_bit)) >> 1))
+
+/* OMAP44XX specific module offsets */
+
+/* CM1 instances */
+
+#define OMAP4430_CM1_OCP_SOCKET_MOD	0x0000
+#define OMAP4430_CM1_CKGEN_MOD		0x0100
+#define OMAP4430_CM1_MPU_MOD		0x0300
+#define OMAP4430_CM1_TESLA_MOD		0x0400
+#define OMAP4430_CM1_ABE_MOD		0x0500
+#define OMAP4430_CM1_RESTORE_MOD	0x0e00
+#define OMAP4430_CM1_INSTR_MOD		0x0f00
+
+/* CM2 instances */
+
+#define OMAP4430_CM2_OCP_SOCKET_MOD	0x0000
+#define OMAP4430_CM2_CKGEN_MOD		0x0100
+#define OMAP4430_CM2_ALWAYS_ON_MOD	0x0600
+#define OMAP4430_CM2_CORE_MOD		0x0700
+#define OMAP4430_CM2_IVAHD_MOD		0x0f00
+#define OMAP4430_CM2_CAM_MOD		0x1000
+#define OMAP4430_CM2_DSS_MOD		0x1100
+#define OMAP4430_CM2_GFX_MOD		0x1200
+#define OMAP4430_CM2_L3INIT_MOD		0x1300
+#define OMAP4430_CM2_L4PER_MOD		0x1400
+#define OMAP4430_CM2_CEFUSE_MOD		0x1600
+#define OMAP4430_CM2_RESTORE_MOD	0x1e00
+#define OMAP4430_CM2_INSTR_MOD		0x1f00
+
+/* PRM instances */
+
+#define OMAP4430_PRM_OCP_SOCKET_MOD	0x0000
+#define OMAP4430_PRM_CKGEN_MOD		0x0100
+#define OMAP4430_PRM_MPU_MOD		0x0300
+#define OMAP4430_PRM_TESLA_MOD		0x0400
+#define OMAP4430_PRM_ABE_MOD		0x0500
+#define OMAP4430_PRM_ALWAYS_ON_MOD	0x0600
+#define OMAP4430_PRM_CORE_MOD		0x0700
+#define OMAP4430_PRM_IVAHD_MOD		0x0f00
+#define OMAP4430_PRM_CAM_MOD		0x1000
+#define OMAP4430_PRM_DSS_MOD		0x1100
+#define OMAP4430_PRM_GFX_MOD		0x1200
+#define OMAP4430_PRM_L3INIT_MOD		0x1300
+#define OMAP4430_PRM_L4PER_MOD		0x1400
+#define OMAP4430_PRM_CEFUSE_MOD		0x1600
+#define OMAP4430_PRM_WKUP_MOD		0x1700
+#define OMAP4430_PRM_WKUP_CM_MOD	0x1800
+#define OMAP4430_PRM_EMU_MOD		0x1900
+#define OMAP4430_PRM_EMU_CM_MOD		0x1a00
+#define OMAP4430_PRM_DEVICE_MOD		0x1b00
+#define OMAP4430_PRM_INSTR_MOD		0x1f00
+
+/* SCRM instances */
+
+#define OMAP4430_SCRM_SCRM_MOD	0x0000
+
+/* CHIRONSS instances */
+
+#define OMAP4430_CHIRONSS_CHIRONSS_OCP_SOCKET_PRCM_MOD	0x0000
+#define OMAP4430_CHIRONSS_CHIRONSS_DEVICE_PRM_MOD	0x0200
+#define OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD		0x0400
+#define OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD		0x0800
 
 /* 24XX register bits shared between CM & PRM registers */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm44xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,411 @@
+/*
+ * OMAP44xx PRM instance offset macros
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 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_H
+#define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
+
+
+/* PRM */
+
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define OMAP4430_REVISION_PRM				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0000)
+#define OMAP4430_PRM_IRQSTATUS_MPU			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0010)
+#define OMAP4430_PRM_IRQSTATUS_MPU_2			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0014)
+#define OMAP4430_PRM_IRQENABLE_MPU			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0018)
+#define OMAP4430_PRM_IRQENABLE_MPU_2			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x001c)
+#define OMAP4430_PRM_IRQSTATUS_DUCATI			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0020)
+#define OMAP4430_PRM_IRQENABLE_DUCATI			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0028)
+#define OMAP4430_PRM_IRQSTATUS_TESLA			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0030)
+#define OMAP4430_PRM_IRQENABLE_TESLA			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0038)
+#define OMAP4430_PRM_PRM_PROFILING_CLKCTRL		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_MOD, 0x0040)
+
+/* PRM.CKGEN_PRM register offsets */
+#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0000)
+#define OMAP4430_CM_DPLL_SYS_REF_CLKSEL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0004)
+#define OMAP4430_CM_L4_WKUP_CLKSEL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0008)
+#define OMAP4430_CM_ABE_PLL_REF_CLKSEL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x000c)
+#define OMAP4430_CM_SYS_CLKSEL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_MOD, 0x0010)
+
+/* PRM.MPU_PRM register offsets */
+#define OMAP4430_PM_MPU_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0000)
+#define OMAP4430_PM_MPU_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0004)
+#define OMAP4430_RM_MPU_RSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0014)
+#define OMAP4430_RM_MPU_MPU_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_MOD, 0x0024)
+
+/* PRM.TESLA_PRM register offsets */
+#define OMAP4430_PM_TESLA_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0000)
+#define OMAP4430_PM_TESLA_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0004)
+#define OMAP4430_RM_TESLA_RSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0010)
+#define OMAP4430_RM_TESLA_RSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0014)
+#define OMAP4430_RM_TESLA_TESLA_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_MOD, 0x0024)
+
+/* PRM.ABE_PRM register offsets */
+#define OMAP4430_PM_ABE_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0000)
+#define OMAP4430_PM_ABE_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0004)
+#define OMAP4430_RM_ABE_AESS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x002c)
+#define OMAP4430_PM_ABE_PDM_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0030)
+#define OMAP4430_RM_ABE_PDM_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0034)
+#define OMAP4430_PM_ABE_DMIC_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0038)
+#define OMAP4430_RM_ABE_DMIC_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x003c)
+#define OMAP4430_PM_ABE_MCASP_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0040)
+#define OMAP4430_RM_ABE_MCASP_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0044)
+#define OMAP4430_PM_ABE_MCBSP1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0048)
+#define OMAP4430_RM_ABE_MCBSP1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x004c)
+#define OMAP4430_PM_ABE_MCBSP2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0050)
+#define OMAP4430_RM_ABE_MCBSP2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0054)
+#define OMAP4430_PM_ABE_MCBSP3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0058)
+#define OMAP4430_RM_ABE_MCBSP3_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x005c)
+#define OMAP4430_PM_ABE_SLIMBUS_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0060)
+#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0064)
+#define OMAP4430_PM_ABE_TIMER5_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0068)
+#define OMAP4430_RM_ABE_TIMER5_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x006c)
+#define OMAP4430_PM_ABE_TIMER6_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0070)
+#define OMAP4430_RM_ABE_TIMER6_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0074)
+#define OMAP4430_PM_ABE_TIMER7_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0078)
+#define OMAP4430_RM_ABE_TIMER7_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x007c)
+#define OMAP4430_PM_ABE_TIMER8_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0080)
+#define OMAP4430_RM_ABE_TIMER8_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0084)
+#define OMAP4430_PM_ABE_WDT3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x0088)
+#define OMAP4430_RM_ABE_WDT3_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_MOD, 0x008c)
+
+/* PRM.ALWAYS_ON_PRM register offsets */
+#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0024)
+#define OMAP4430_PM_ALWON_SR_MPU_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0028)
+#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x002c)
+#define OMAP4430_PM_ALWON_SR_IVA_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0030)
+#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0034)
+#define OMAP4430_PM_ALWON_SR_CORE_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x0038)
+#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_MOD, 0x003c)
+
+/* PRM.CORE_PRM register offsets */
+#define OMAP4430_PM_CORE_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0000)
+#define OMAP4430_PM_CORE_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0004)
+#define OMAP4430_RM_L3_1_L3_1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0024)
+#define OMAP4430_RM_L3_2_L3_2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0124)
+#define OMAP4430_RM_L3_2_GPMC_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x012c)
+#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0134)
+#define OMAP4430_RM_DUCATI_RSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0210)
+#define OMAP4430_RM_DUCATI_RSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0214)
+#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0224)
+#define OMAP4430_RM_SDMA_SDMA_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0324)
+#define OMAP4430_RM_MEMIF_DMM_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0424)
+#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x042c)
+#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0434)
+#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x043c)
+#define OMAP4430_RM_MEMIF_DLL_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0444)
+#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0454)
+#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x045c)
+#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0464)
+#define OMAP4430_RM_D2D_SAD2D_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0524)
+#define OMAP4430_RM_D2D_MODEM_ICR_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x052c)
+#define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0534)
+#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0624)
+#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x062c)
+#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0634)
+#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x063c)
+#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0724)
+#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x072c)
+#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_MOD, 0x0744)
+
+/* PRM.IVAHD_PRM register offsets */
+#define OMAP4430_PM_IVAHD_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0000)
+#define OMAP4430_PM_IVAHD_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0004)
+#define OMAP4430_RM_IVAHD_RSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0010)
+#define OMAP4430_RM_IVAHD_RSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0014)
+#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x0024)
+#define OMAP4430_RM_IVAHD_SL2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_MOD, 0x002c)
+
+/* PRM.CAM_PRM register offsets */
+#define OMAP4430_PM_CAM_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0000)
+#define OMAP4430_PM_CAM_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0004)
+#define OMAP4430_RM_CAM_ISS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x0024)
+#define OMAP4430_RM_CAM_FDIF_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_MOD, 0x002c)
+
+/* PRM.DSS_PRM register offsets */
+#define OMAP4430_PM_DSS_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0000)
+#define OMAP4430_PM_DSS_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0004)
+#define OMAP4430_PM_DSS_DSS_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0020)
+#define OMAP4430_RM_DSS_DSS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x0024)
+#define OMAP4430_RM_DSS_DEISS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_MOD, 0x002c)
+
+/* PRM.GFX_PRM register offsets */
+#define OMAP4430_PM_GFX_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0000)
+#define OMAP4430_PM_GFX_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0004)
+#define OMAP4430_RM_GFX_GFX_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_MOD, 0x0024)
+
+/* PRM.L3INIT_PRM register offsets */
+#define OMAP4430_PM_L3INIT_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0000)
+#define OMAP4430_PM_L3INIT_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0004)
+#define OMAP4430_PM_L3INIT_MMC1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0028)
+#define OMAP4430_RM_L3INIT_MMC1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x002c)
+#define OMAP4430_PM_L3INIT_MMC2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0030)
+#define OMAP4430_RM_L3INIT_MMC2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0034)
+#define OMAP4430_PM_L3INIT_HSI_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0038)
+#define OMAP4430_RM_L3INIT_HSI_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x003c)
+#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0040)
+#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0044)
+#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0058)
+#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x005c)
+#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0060)
+#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0064)
+#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0068)
+#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x006c)
+#define OMAP4430_RM_L3INIT_P1500_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x007c)
+#define OMAP4430_RM_L3INIT_EMAC_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0084)
+#define OMAP4430_PM_L3INIT_SATA_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0088)
+#define OMAP4430_RM_L3INIT_SATA_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x008c)
+#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0094)
+#define OMAP4430_PM_L3INIT_PCIESS_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x0098)
+#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x009c)
+#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00ac)
+#define OMAP4430_PM_L3INIT_XHPI_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c0)
+#define OMAP4430_RM_L3INIT_XHPI_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c4)
+#define OMAP4430_PM_L3INIT_MMC6_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00c8)
+#define OMAP4430_RM_L3INIT_MMC6_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00cc)
+#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d0)
+#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00d4)
+#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT	OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_MOD, 0x00e4)
+
+/* PRM.L4PER_PRM register offsets */
+#define OMAP4430_PM_L4PER_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0000)
+#define OMAP4430_PM_L4PER_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0004)
+#define OMAP4430_RM_L4PER_ADC_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0024)
+#define OMAP4430_PM_L4PER_DMTIMER10_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0028)
+#define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x002c)
+#define OMAP4430_PM_L4PER_DMTIMER11_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0030)
+#define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0034)
+#define OMAP4430_PM_L4PER_DMTIMER2_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0038)
+#define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x003c)
+#define OMAP4430_PM_L4PER_DMTIMER3_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0040)
+#define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0044)
+#define OMAP4430_PM_L4PER_DMTIMER4_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0048)
+#define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x004c)
+#define OMAP4430_PM_L4PER_DMTIMER9_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0050)
+#define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0054)
+#define OMAP4430_RM_L4PER_ELM_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x005c)
+#define OMAP4430_PM_L4PER_GPIO2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0060)
+#define OMAP4430_RM_L4PER_GPIO2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0064)
+#define OMAP4430_PM_L4PER_GPIO3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0068)
+#define OMAP4430_RM_L4PER_GPIO3_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x006c)
+#define OMAP4430_PM_L4PER_GPIO4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0070)
+#define OMAP4430_RM_L4PER_GPIO4_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0074)
+#define OMAP4430_PM_L4PER_GPIO5_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0078)
+#define OMAP4430_RM_L4PER_GPIO5_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x007c)
+#define OMAP4430_PM_L4PER_GPIO6_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0080)
+#define OMAP4430_RM_L4PER_GPIO6_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0084)
+#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x008c)
+#define OMAP4430_PM_L4PER_HECC1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0090)
+#define OMAP4430_RM_L4PER_HECC1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0094)
+#define OMAP4430_PM_L4PER_HECC2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0098)
+#define OMAP4430_RM_L4PER_HECC2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x009c)
+#define OMAP4430_PM_L4PER_I2C1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a0)
+#define OMAP4430_RM_L4PER_I2C1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a4)
+#define OMAP4430_PM_L4PER_I2C2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00a8)
+#define OMAP4430_RM_L4PER_I2C2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ac)
+#define OMAP4430_PM_L4PER_I2C3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b0)
+#define OMAP4430_RM_L4PER_I2C3_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b4)
+#define OMAP4430_PM_L4PER_I2C4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00b8)
+#define OMAP4430_RM_L4PER_I2C4_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00bc)
+#define OMAP4430_RM_L4PER_L4_PER_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00c0)
+#define OMAP4430_PM_L4PER_MCASP2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d0)
+#define OMAP4430_RM_L4PER_MCASP2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d4)
+#define OMAP4430_PM_L4PER_MCASP3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00d8)
+#define OMAP4430_RM_L4PER_MCASP3_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00dc)
+#define OMAP4430_PM_L4PER_MCBSP4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e0)
+#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00e4)
+#define OMAP4430_RM_L4PER_MGATE_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00ec)
+#define OMAP4430_PM_L4PER_MCSPI1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f0)
+#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f4)
+#define OMAP4430_PM_L4PER_MCSPI2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00f8)
+#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x00fc)
+#define OMAP4430_PM_L4PER_MCSPI3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0100)
+#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0104)
+#define OMAP4430_PM_L4PER_MCSPI4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0108)
+#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x010c)
+#define OMAP4430_PM_L4PER_MMCSD3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0120)
+#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0124)
+#define OMAP4430_PM_L4PER_MMCSD4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0128)
+#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x012c)
+#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0134)
+#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0138)
+#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x013c)
+#define OMAP4430_PM_L4PER_UART1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0140)
+#define OMAP4430_RM_L4PER_UART1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0144)
+#define OMAP4430_PM_L4PER_UART2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0148)
+#define OMAP4430_RM_L4PER_UART2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x014c)
+#define OMAP4430_PM_L4PER_UART3_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0150)
+#define OMAP4430_RM_L4PER_UART3_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0154)
+#define OMAP4430_PM_L4PER_UART4_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0158)
+#define OMAP4430_RM_L4PER_UART4_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x015c)
+#define OMAP4430_PM_L4PER_MMCSD5_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0160)
+#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0164)
+#define OMAP4430_PM_L4PER_I2C5_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x0168)
+#define OMAP4430_RM_L4PER_I2C5_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x016c)
+#define OMAP4430_RM_L4SEC_AES1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01a4)
+#define OMAP4430_RM_L4SEC_AES2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01ac)
+#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01b4)
+#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01bc)
+#define OMAP4430_RM_L4SEC_RNG_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01c4)
+#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01cc)
+#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_MOD, 0x01dc)
+
+/* PRM.CEFUSE_PRM register offsets */
+#define OMAP4430_PM_CEFUSE_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0000)
+#define OMAP4430_PM_CEFUSE_PWRSTST			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0004)
+#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_MOD, 0x0024)
+
+/* PRM.WKUP_PRM register offsets */
+#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0024)
+#define OMAP4430_RM_WKUP_WDT1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x002c)
+#define OMAP4430_PM_WKUP_WDT2_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0030)
+#define OMAP4430_RM_WKUP_WDT2_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0034)
+#define OMAP4430_PM_WKUP_GPIO1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0038)
+#define OMAP4430_RM_WKUP_GPIO1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x003c)
+#define OMAP4430_PM_WKUP_TIMER1_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0040)
+#define OMAP4430_RM_WKUP_TIMER1_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0044)
+#define OMAP4430_PM_WKUP_TIMER12_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0048)
+#define OMAP4430_RM_WKUP_TIMER12_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x004c)
+#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0054)
+#define OMAP4430_PM_WKUP_USIM_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0058)
+#define OMAP4430_RM_WKUP_USIM_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x005c)
+#define OMAP4430_RM_WKUP_SARRAM_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0064)
+#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0078)
+#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x007c)
+#define OMAP4430_PM_WKUP_RTC_WKDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0080)
+#define OMAP4430_RM_WKUP_RTC_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_MOD, 0x0084)
+
+/* PRM.WKUP_CM register offsets */
+#define OMAP4430_CM_WKUP_CLKSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0000)
+#define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0020)
+#define OMAP4430_CM_WKUP_WDT1_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0028)
+#define OMAP4430_CM_WKUP_WDT2_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0030)
+#define OMAP4430_CM_WKUP_GPIO1_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0038)
+#define OMAP4430_CM_WKUP_TIMER1_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0040)
+#define OMAP4430_CM_WKUP_TIMER12_CLKCTRL		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0048)
+#define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0050)
+#define OMAP4430_CM_WKUP_USIM_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0058)
+#define OMAP4430_CM_WKUP_SARRAM_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0060)
+#define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0078)
+#define OMAP4430_CM_WKUP_RTC_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0080)
+#define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_MOD, 0x0088)
+
+/* PRM.EMU_PRM register offsets */
+#define OMAP4430_PM_EMU_PWRSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0000)
+#define OMAP4430_PM_EMU_PWRSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0004)
+#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_MOD, 0x0024)
+
+/* PRM.EMU_CM register offsets */
+#define OMAP4430_CM_EMU_CLKSTCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0000)
+#define OMAP4430_CM_EMU_DYNAMICDEP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0008)
+#define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_MOD, 0x0020)
+
+/* PRM.DEVICE_PRM register offsets */
+#define OMAP4430_PRM_RSTCTRL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0000)
+#define OMAP4430_PRM_RSTST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0004)
+#define OMAP4430_PRM_RSTTIME				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0008)
+#define OMAP4430_PRM_CLKREQCTRL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x000c)
+#define OMAP4430_PRM_VOLTCTRL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0010)
+#define OMAP4430_PRM_PWRREQCTRL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0014)
+#define OMAP4430_PRM_PSCON_COUNT			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0018)
+#define OMAP4430_PRM_IO_COUNT				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x001c)
+#define OMAP4430_PRM_IO_PMCTRL				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0020)
+#define OMAP4430_PRM_VOLTSETUP_WARMRESET		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0024)
+#define OMAP4430_PRM_VOLTSETUP_CORE_OFF			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0028)
+#define OMAP4430_PRM_VOLTSETUP_MPU_OFF			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x002c)
+#define OMAP4430_PRM_VOLTSETUP_IVA_OFF			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0030)
+#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0034)
+#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0038)
+#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x003c)
+#define OMAP4430_PRM_VP_CORE_CONFIG			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0040)
+#define OMAP4430_PRM_VP_CORE_STATUS			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0044)
+#define OMAP4430_PRM_VP_CORE_VLIMITTO			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0048)
+#define OMAP4430_PRM_VP_CORE_VOLTAGE			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x004c)
+#define OMAP4430_PRM_VP_CORE_VSTEPMAX			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0050)
+#define OMAP4430_PRM_VP_CORE_VSTEPMIN			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0054)
+#define OMAP4430_PRM_VP_MPU_CONFIG			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0058)
+#define OMAP4430_PRM_VP_MPU_STATUS			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x005c)
+#define OMAP4430_PRM_VP_MPU_VLIMITTO			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0060)
+#define OMAP4430_PRM_VP_MPU_VOLTAGE			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0064)
+#define OMAP4430_PRM_VP_MPU_VSTEPMAX			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0068)
+#define OMAP4430_PRM_VP_MPU_VSTEPMIN			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x006c)
+#define OMAP4430_PRM_VP_IVA_CONFIG			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0070)
+#define OMAP4430_PRM_VP_IVA_STATUS			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0074)
+#define OMAP4430_PRM_VP_IVA_VLIMITTO			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0078)
+#define OMAP4430_PRM_VP_IVA_VOLTAGE			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x007c)
+#define OMAP4430_PRM_VP_IVA_VSTEPMAX			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0080)
+#define OMAP4430_PRM_VP_IVA_VSTEPMIN			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0084)
+#define OMAP4430_PRM_VC_SMPS_SA				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0088)
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x008c)
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0090)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0094)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x0098)
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x009c)
+#define OMAP4430_PRM_VC_VAL_BYPASS			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a0)
+#define OMAP4430_PRM_VC_CFG_CHANNEL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a4)
+#define OMAP4430_PRM_VC_CFG_I2C_MODE			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00a8)
+#define OMAP4430_PRM_VC_CFG_I2C_CLK			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ac)
+#define OMAP4430_PRM_SRAM_COUNT				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b0)
+#define OMAP4430_PRM_SRAM_WKUP_SETUP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b4)
+#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP		OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00b8)
+#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00bc)
+#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c0)
+#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c4)
+#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00c8)
+#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00cc)
+#define OMAP4430_PRM_LDO_ABB_MPU_SETUP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d0)
+#define OMAP4430_PRM_LDO_ABB_MPU_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d4)
+#define OMAP4430_PRM_LDO_ABB_IVA_SETUP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00d8)
+#define OMAP4430_PRM_LDO_ABB_IVA_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00dc)
+#define OMAP4430_PRM_LDO_BANDGAP_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e0)
+#define OMAP4430_PRM_DEVICE_OFF_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e4)
+#define OMAP4430_PRM_PHASE1_CNDP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00e8)
+#define OMAP4430_PRM_PHASE2A_CNDP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00ec)
+#define OMAP4430_PRM_PHASE2B_CNDP			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f0)
+#define OMAP4430_PRM_MODEM_IF_CTRL			OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_MOD, 0x00f4)
+
+/* CHIRON_PRCM */
+
+
+/* CHIRON_PRCM.CHIRONSS_OCP_SOCKET_PRCM register offsets */
+#define OMAP4430_REVISION_PRCM				OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_OCP_SOCKET_PRCM_MOD, 0x0000)
+
+/* CHIRON_PRCM.CHIRONSS_DEVICE_PRM register offsets */
+#define OMAP4430_CHIRON_PRCM_PRM_RSTST			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_DEVICE_PRM_MOD, 0x0000)
+
+/* CHIRON_PRCM.CHIRONSS_CPU0 register offsets */
+#define OMAP4430_PM_PDA_CPU0_PWRSTCTRL			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0000)
+#define OMAP4430_PM_PDA_CPU0_PWRSTST			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0004)
+#define OMAP4430_RM_PDA_CPU0_CPU0_CONTEXT		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0008)
+#define OMAP4430_RM_PDA_CPU0_CPU0_RSTCTRL		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x000c)
+#define OMAP4430_RM_PDA_CPU0_CPU0_RSTST			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0010)
+#define OMAP4430_CM_PDA_CPU0_CPU0_CLKCTRL		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0014)
+#define OMAP4430_CM_PDA_CPU0_CLKSTCTRL			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD, 0x0018)
+
+/* CHIRON_PRCM.CHIRONSS_CPU1 register offsets */
+#define OMAP4430_PM_PDA_CPU1_PWRSTCTRL			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0000)
+#define OMAP4430_PM_PDA_CPU1_PWRSTST			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0004)
+#define OMAP4430_RM_PDA_CPU1_CPU1_CONTEXT		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0008)
+#define OMAP4430_RM_PDA_CPU1_CPU1_RSTCTRL		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x000c)
+#define OMAP4430_RM_PDA_CPU1_CPU1_RSTST			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0010)
+#define OMAP4430_CM_PDA_CPU1_CPU1_CLKCTRL		OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0014)
+#define OMAP4430_CM_PDA_CPU1_CLKSTCTRL			OMAP44XX_CHIRONSS_REGADDR(OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD, 0x0018)
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,8 +4,8 @@
 /*
  * OMAP2/3 Power/Reset Management (PRM) register definitions
  *
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  *
@@ -17,11 +17,17 @@
 #include "prcm-common.h"
 
 #define OMAP2420_PRM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
+		OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
 #define OMAP2430_PRM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
+		OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
 #define OMAP34XX_PRM_REGADDR(module, reg)				\
-			OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+		OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+#define OMAP44XX_PRM_REGADDR(module, reg)				\
+		OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (module) + (reg))
+#define OMAP44XX_CHIRONSS_REGADDR(module, reg)				\
+		OMAP2_L4_IO_ADDRESS(OMAP4430_CHIRONSS_BASE + (module) + (reg))
+
+#include "prm44xx.h"
 
 /*
  * Architecture-specific global PRM registers
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -365,6 +365,7 @@
 /* PM_PREPWSTST_GFX specific bits */
 
 /* PM_WKEN_WKUP specific bits */
+#define OMAP3430_EN_IO_CHAIN				(1 << 16)
 #define OMAP3430_EN_IO					(1 << 8)
 #define OMAP3430_EN_GPIO1				(1 << 3)
 
@@ -373,6 +374,7 @@
 /* PM_IVA2GRPSEL_WKUP specific bits */
 
 /* PM_WKST_WKUP specific bits */
+#define OMAP3430_ST_IO_CHAIN				(1 << 16)
 #define OMAP3430_ST_IO					(1 << 8)
 
 /* PRM_CLKSEL */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/prm-regbits-44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2205 @@
+/*
+ * OMAP44xx Power Management register bits
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 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_PRM_REGBITS_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H
+
+#include "prm.h"
+
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ABBOFF_ACT_EXPORT_SHIFT				(1 << 1)
+#define OMAP4430_ABBOFF_ACT_EXPORT_MASK					BITFIELD(1, 1)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_SHIFT				(1 << 2)
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK				BITFIELD(2, 2)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_ABB_IVA_DONE_EN_SHIFT					(1 << 31)
+#define OMAP4430_ABB_IVA_DONE_EN_MASK					BITFIELD(31, 31)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_ABB_IVA_DONE_ST_SHIFT					(1 << 31)
+#define OMAP4430_ABB_IVA_DONE_ST_MASK					BITFIELD(31, 31)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_ABB_MPU_DONE_EN_SHIFT					(1 << 7)
+#define OMAP4430_ABB_MPU_DONE_EN_MASK					BITFIELD(7, 7)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_ABB_MPU_DONE_ST_SHIFT					(1 << 7)
+#define OMAP4430_ABB_MPU_DONE_ST_MASK					BITFIELD(7, 7)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_ACTIVE_FBB_SEL_SHIFT					(1 << 2)
+#define OMAP4430_ACTIVE_FBB_SEL_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_ACTIVE_RBB_SEL_SHIFT					(1 << 1)
+#define OMAP4430_ACTIVE_RBB_SEL_MASK					BITFIELD(1, 1)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_AESSMEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_AESSMEM_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_AESSMEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_AESSMEM_RETSTATE_MASK					BITFIELD(8, 8)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP4430_AESSMEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_AESSMEM_STATEST_MASK					BITFIELD(4, 5)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_AIPOFF_SHIFT						(1 << 8)
+#define OMAP4430_AIPOFF_MASK						BITFIELD(8, 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT				(1 << 0)
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK				BITFIELD(0, 1)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT				(1 << 4)
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK				BITFIELD(4, 5)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT				(1 << 2)
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK				BITFIELD(2, 3)
+
+/* Used by PM_CAM_PWRSTCTRL */
+#define OMAP4430_CAM_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_CAM_MEM_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_CAM_PWRSTST */
+#define OMAP4430_CAM_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_CAM_MEM_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by PRM_CLKREQCTRL */
+#define OMAP4430_CLKREQ_COND_SHIFT					(1 << 0)
+#define OMAP4430_CLKREQ_COND_MASK					BITFIELD(0, 2)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_CMDRA_VDD_CORE_L_MASK					BITFIELD(0, 7)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_CMDRA_VDD_IVA_L_MASK					BITFIELD(8, 15)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_CMDRA_VDD_MPU_L_MASK					BITFIELD(16, 23)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_CORE_L_SHIFT					(1 << 4)
+#define OMAP4430_CMD_VDD_CORE_L_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_IVA_L_SHIFT					(1 << 12)
+#define OMAP4430_CMD_VDD_IVA_L_MASK					BITFIELD(12, 12)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_MPU_L_SHIFT					(1 << 17)
+#define OMAP4430_CMD_VDD_MPU_L_MASK					BITFIELD(17, 17)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OCMRAM_ONSTATE_SHIFT				(1 << 18)
+#define OMAP4430_CORE_OCMRAM_ONSTATE_MASK				BITFIELD(18, 19)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OCMRAM_RETSTATE_SHIFT				(1 << 9)
+#define OMAP4430_CORE_OCMRAM_RETSTATE_MASK				BITFIELD(9, 9)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_CORE_OCMRAM_STATEST_SHIFT				(1 << 6)
+#define OMAP4430_CORE_OCMRAM_STATEST_MASK				BITFIELD(6, 7)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK				BITFIELD(16, 17)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK				BITFIELD(8, 8)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_CORE_OTHER_BANK_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_CORE_OTHER_BANK_STATEST_MASK				BITFIELD(4, 5)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_DATA_SHIFT						(1 << 16)
+#define OMAP4430_DATA_MASK						BITFIELD(16, 23)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4430_DEVICE_OFF_ENABLE_SHIFT				(1 << 0)
+#define OMAP4430_DEVICE_OFF_ENABLE_MASK					BITFIELD(0, 0)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_DFILTEREN_SHIFT					(1 << 6)
+#define OMAP4430_DFILTEREN_MASK						BITFIELD(6, 6)
+
+/* Used by PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
+#define OMAP4430_DPLL_ABE_RECAL_EN_SHIFT				(1 << 4)
+#define OMAP4430_DPLL_ABE_RECAL_EN_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_DPLL_ABE_RECAL_ST_SHIFT				(1 << 4)
+#define OMAP4430_DPLL_ABE_RECAL_ST_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_CORE_RECAL_EN_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CORE_RECAL_EN_MASK				BITFIELD(0, 0)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_CORE_RECAL_ST_SHIFT				(1 << 0)
+#define OMAP4430_DPLL_CORE_RECAL_ST_MASK				BITFIELD(0, 0)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_SHIFT				(1 << 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK				BITFIELD(6, 6)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_SHIFT				(1 << 6)
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK				BITFIELD(6, 6)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
+#define OMAP4430_DPLL_IVA_RECAL_EN_SHIFT				(1 << 2)
+#define OMAP4430_DPLL_IVA_RECAL_EN_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_DPLL_IVA_RECAL_ST_SHIFT				(1 << 2)
+#define OMAP4430_DPLL_IVA_RECAL_ST_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_MPU_RECAL_EN_SHIFT				(1 << 1)
+#define OMAP4430_DPLL_MPU_RECAL_EN_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_MPU_RECAL_ST_SHIFT				(1 << 1)
+#define OMAP4430_DPLL_MPU_RECAL_ST_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_PER_RECAL_EN_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_PER_RECAL_EN_MASK					BITFIELD(3, 3)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_PER_RECAL_ST_SHIFT				(1 << 3)
+#define OMAP4430_DPLL_PER_RECAL_ST_MASK					BITFIELD(3, 3)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_SHIFT				(1 << 7)
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK				BITFIELD(7, 7)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_SHIFT				(1 << 7)
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK				BITFIELD(7, 7)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_USB_RECAL_EN_SHIFT				(1 << 5)
+#define OMAP4430_DPLL_USB_RECAL_EN_MASK					BITFIELD(5, 5)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_USB_RECAL_ST_SHIFT				(1 << 5)
+#define OMAP4430_DPLL_USB_RECAL_ST_MASK					BITFIELD(5, 5)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP4430_DSS_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_DSS_MEM_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP4430_DSS_MEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_DSS_MEM_RETSTATE_MASK					BITFIELD(8, 8)
+
+/* Used by PM_DSS_PWRSTST */
+#define OMAP4430_DSS_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_DSS_MEM_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK				BITFIELD(20, 21)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK				BITFIELD(10, 10)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_DUCATI_L2RAM_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_DUCATI_L2RAM_STATEST_MASK				BITFIELD(8, 9)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_SHIFT				(1 << 22)
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK				BITFIELD(22, 23)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_SHIFT				(1 << 11)
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK				BITFIELD(11, 11)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT				(1 << 10)
+#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK				BITFIELD(10, 11)
+
+/* Used by RM_MPU_RSTST */
+#define OMAP4430_EMULATION_RST_SHIFT					(1 << 0)
+#define OMAP4430_EMULATION_RST_MASK					BITFIELD(0, 0)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_EMULATION_RST1ST_SHIFT					(1 << 3)
+#define OMAP4430_EMULATION_RST1ST_MASK					BITFIELD(3, 3)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_EMULATION_RST2ST_SHIFT					(1 << 4)
+#define OMAP4430_EMULATION_RST2ST_MASK					BITFIELD(4, 4)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_EMULATION_SEQ1_RST1ST_SHIFT				(1 << 3)
+#define OMAP4430_EMULATION_SEQ1_RST1ST_MASK				BITFIELD(3, 3)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_EMULATION_SEQ2_RST2ST_SHIFT				(1 << 4)
+#define OMAP4430_EMULATION_SEQ2_RST2ST_MASK				BITFIELD(4, 4)
+
+/* Used by PM_EMU_PWRSTCTRL */
+#define OMAP4430_EMU_BANK_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_EMU_BANK_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_EMU_PWRSTST */
+#define OMAP4430_EMU_BANK_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_EMU_BANK_STATEST_MASK					BITFIELD(4, 5)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP, PRM_SRAM_WKUP_SETUP
+ */
+#define OMAP4430_ENABLE_RTA_EXPORT_SHIFT				(1 << 0)
+#define OMAP4430_ENABLE_RTA_EXPORT_MASK					BITFIELD(0, 0)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC1_SHIFT						(1 << 3)
+#define OMAP4430_ENFUNC1_MASK						BITFIELD(3, 3)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC3_SHIFT						(1 << 5)
+#define OMAP4430_ENFUNC3_MASK						BITFIELD(5, 5)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC4_SHIFT						(1 << 6)
+#define OMAP4430_ENFUNC4_MASK						BITFIELD(6, 6)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC5_SHIFT						(1 << 7)
+#define OMAP4430_ENFUNC5_MASK						BITFIELD(7, 7)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_ERRORGAIN_SHIFT					(1 << 16)
+#define OMAP4430_ERRORGAIN_MASK						BITFIELD(16, 23)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_ERROROFFSET_SHIFT					(1 << 24)
+#define OMAP4430_ERROROFFSET_MASK					BITFIELD(24, 31)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_EXTERNAL_WARM_RST_SHIFT				(1 << 5)
+#define OMAP4430_EXTERNAL_WARM_RST_MASK					BITFIELD(5, 5)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_FORCEUPDATE_SHIFT					(1 << 1)
+#define OMAP4430_FORCEUPDATE_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP4430_FORCEUPDATEWAIT_SHIFT					(1 << 8)
+#define OMAP4430_FORCEUPDATEWAIT_MASK					BITFIELD(8, 31)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_TESLA */
+#define OMAP4430_FORCEWKUP_EN_SHIFT					(1 << 10)
+#define OMAP4430_FORCEWKUP_EN_MASK					BITFIELD(10, 10)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_FORCEWKUP_ST_SHIFT					(1 << 10)
+#define OMAP4430_FORCEWKUP_ST_MASK					BITFIELD(10, 10)
+
+/* Used by PM_GFX_PWRSTCTRL */
+#define OMAP4430_GFX_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_GFX_MEM_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_GFX_PWRSTST */
+#define OMAP4430_GFX_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_GFX_MEM_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_GLOBAL_COLD_RST_SHIFT					(1 << 0)
+#define OMAP4430_GLOBAL_COLD_RST_MASK					BITFIELD(0, 0)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT				(1 << 1)
+#define OMAP4430_GLOBAL_WARM_SW_RST_MASK				BITFIELD(1, 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_GLOBAL_WUEN_SHIFT					(1 << 16)
+#define OMAP4430_GLOBAL_WUEN_MASK					BITFIELD(16, 16)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_HSMCODE_SHIFT						(1 << 0)
+#define OMAP4430_HSMCODE_MASK						BITFIELD(0, 2)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_HSMODEEN_SHIFT						(1 << 3)
+#define OMAP4430_HSMODEEN_MASK						BITFIELD(3, 3)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSSCLH_SHIFT						(1 << 16)
+#define OMAP4430_HSSCLH_MASK						BITFIELD(16, 23)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSSCLL_SHIFT						(1 << 24)
+#define OMAP4430_HSSCLL_MASK						BITFIELD(24, 31)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_HWA_MEM_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_HWA_MEM_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_HWA_MEM_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_HWA_MEM_RETSTATE_MASK					BITFIELD(8, 8)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_HWA_MEM_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_HWA_MEM_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by RM_MPU_RSTST */
+#define OMAP4430_ICECRUSHER_MPU_RST_SHIFT				(1 << 1)
+#define OMAP4430_ICECRUSHER_MPU_RST_MASK				BITFIELD(1, 1)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_ICECRUSHER_RST1ST_SHIFT				(1 << 5)
+#define OMAP4430_ICECRUSHER_RST1ST_MASK					BITFIELD(5, 5)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_ICECRUSHER_RST2ST_SHIFT				(1 << 6)
+#define OMAP4430_ICECRUSHER_RST2ST_MASK					BITFIELD(6, 6)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_SHIFT				(1 << 5)
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK				BITFIELD(5, 5)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_SHIFT				(1 << 6)
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK				BITFIELD(6, 6)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_ICEPICK_RST_SHIFT					(1 << 9)
+#define OMAP4430_ICEPICK_RST_MASK					BITFIELD(9, 9)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_INITVDD_SHIFT						(1 << 2)
+#define OMAP4430_INITVDD_MASK						BITFIELD(2, 2)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_INITVOLTAGE_SHIFT					(1 << 8)
+#define OMAP4430_INITVOLTAGE_MASK					BITFIELD(8, 15)
+
+/*
+ * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
+ * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ */
+#define OMAP4430_INTRANSITION_SHIFT					(1 << 20)
+#define OMAP4430_INTRANSITION_MASK					BITFIELD(20, 20)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_IO_EN_SHIFT						(1 << 9)
+#define OMAP4430_IO_EN_MASK						BITFIELD(9, 9)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_IO_ON_STATUS_SHIFT					(1 << 5)
+#define OMAP4430_IO_ON_STATUS_MASK					BITFIELD(5, 5)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_IO_ST_SHIFT						(1 << 9)
+#define OMAP4430_IO_ST_MASK						BITFIELD(9, 9)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOCLK_OVERRIDE_SHIFT					(1 << 0)
+#define OMAP4430_ISOCLK_OVERRIDE_MASK					BITFIELD(0, 0)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOCLK_STATUS_SHIFT					(1 << 1)
+#define OMAP4430_ISOCLK_STATUS_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOOVR_EXTEND_SHIFT					(1 << 4)
+#define OMAP4430_ISOOVR_EXTEND_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_IO_COUNT */
+#define OMAP4430_ISO_2_ON_TIME_SHIFT					(1 << 0)
+#define OMAP4430_ISO_2_ON_TIME_MASK					BITFIELD(0, 7)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP4430_L3INIT_BANK1_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_L3INIT_BANK1_ONSTATE_MASK				BITFIELD(16, 17)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP4430_L3INIT_BANK1_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_L3INIT_BANK1_RETSTATE_MASK				BITFIELD(8, 8)
+
+/* Used by PM_L3INIT_PWRSTST */
+#define OMAP4430_L3INIT_BANK1_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_L3INIT_BANK1_STATEST_MASK				BITFIELD(4, 5)
+
+/*
+ * Used by PM_CORE_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_ABE_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL,
+ * PM_IVAHD_PWRSTCTRL
+ */
+#define OMAP4430_LOGICRETSTATE_SHIFT					(1 << 2)
+#define OMAP4430_LOGICRETSTATE_MASK					BITFIELD(2, 2)
+
+/*
+ * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
+ * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ */
+#define OMAP4430_LOGICSTATEST_SHIFT					(1 << 2)
+#define OMAP4430_LOGICSTATEST_MASK					BITFIELD(2, 2)
+
+/*
+ * Used by RM_WKUP_GPIO1_CONTEXT, RM_WKUP_KEYBOARD_CONTEXT,
+ * RM_WKUP_L4WKUP_CONTEXT, RM_WKUP_RTC_CONTEXT, RM_WKUP_SARRAM_CONTEXT,
+ * RM_WKUP_SYNCTIMER_CONTEXT, RM_WKUP_TIMER12_CONTEXT, RM_WKUP_TIMER1_CONTEXT,
+ * RM_WKUP_USIM_CONTEXT, RM_WKUP_WDT1_CONTEXT, RM_WKUP_WDT2_CONTEXT,
+ * RM_EMU_DEBUGSS_CONTEXT, RM_D2D_SAD2D_CONTEXT, RM_D2D_SAD2D_FW_CONTEXT,
+ * RM_DUCATI_DUCATI_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
+ * RM_L3INSTR_L3_INSTR_CONTEXT, RM_L3INSTR_OCP_WP1_CONTEXT,
+ * RM_L3_1_L3_1_CONTEXT, RM_L3_2_L3_2_CONTEXT, RM_L3_2_OCMC_RAM_CONTEXT,
+ * RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_SAR_ROM_CONTEXT, RM_MEMIF_DLL_CONTEXT,
+ * RM_MEMIF_DLL_H_CONTEXT, RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_FW_CONTEXT,
+ * RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT, RM_L3INIT_CCPTX_CONTEXT,
+ * RM_L3INIT_EMAC_CONTEXT, RM_L3INIT_P1500_CONTEXT, RM_L3INIT_PCIESS_CONTEXT,
+ * RM_L3INIT_SATA_CONTEXT, RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
+ * RM_L3INIT_USBPHYOCP2SCP_CONTEXT, RM_L3INIT_XHPI_CONTEXT,
+ * 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_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT, RM_ABE_TIMER5_CONTEXT,
+ * RM_ABE_TIMER6_CONTEXT, RM_ABE_TIMER7_CONTEXT, RM_ABE_TIMER8_CONTEXT,
+ * RM_ABE_WDT3_CONTEXT, RM_GFX_GFX_CONTEXT, RM_MPU_MPU_CONTEXT,
+ * RM_CEFUSE_CEFUSE_CONTEXT, RM_ALWON_MDMINTC_CONTEXT,
+ * RM_ALWON_SR_CORE_CONTEXT, RM_ALWON_SR_IVA_CONTEXT, RM_ALWON_SR_MPU_CONTEXT,
+ * RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT, RM_L4PER_ADC_CONTEXT,
+ * RM_L4PER_DMTIMER10_CONTEXT, RM_L4PER_DMTIMER11_CONTEXT,
+ * RM_L4PER_DMTIMER2_CONTEXT, RM_L4PER_DMTIMER3_CONTEXT,
+ * RM_L4PER_DMTIMER4_CONTEXT, RM_L4PER_DMTIMER9_CONTEXT, RM_L4PER_ELM_CONTEXT,
+ * RM_L4PER_HDQ1W_CONTEXT, RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT,
+ * RM_L4PER_I2C2_CONTEXT, RM_L4PER_I2C3_CONTEXT, RM_L4PER_I2C4_CONTEXT,
+ * RM_L4PER_I2C5_CONTEXT, RM_L4PER_L4_PER_CONTEXT, RM_L4PER_MCASP2_CONTEXT,
+ * RM_L4PER_MCASP3_CONTEXT, RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MCSPI1_CONTEXT,
+ * RM_L4PER_MCSPI2_CONTEXT, RM_L4PER_MCSPI3_CONTEXT, RM_L4PER_MCSPI4_CONTEXT,
+ * RM_L4PER_MGATE_CONTEXT, RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT,
+ * RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_MSPROHG_CONTEXT,
+ * RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT,
+ * RM_TESLA_TESLA_CONTEXT, RM_IVAHD_IVAHD_CONTEXT, RM_IVAHD_SL2_CONTEXT
+ */
+#define OMAP4430_LOSTCONTEXT_DFF_SHIFT					(1 << 0)
+#define OMAP4430_LOSTCONTEXT_DFF_MASK					BITFIELD(0, 0)
+
+/*
+ * Used by RM_D2D_MODEM_ICR_CONTEXT, RM_D2D_SAD2D_CONTEXT,
+ * RM_D2D_SAD2D_FW_CONTEXT, RM_DUCATI_DUCATI_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
+ * RM_L3INSTR_OCP_WP1_CONTEXT, RM_L3_1_L3_1_CONTEXT, RM_L3_2_GPMC_CONTEXT,
+ * RM_L3_2_L3_2_CONTEXT, RM_L4CFG_HW_SEM_CONTEXT, RM_L4CFG_L4_CFG_CONTEXT,
+ * RM_L4CFG_MAILBOX_CONTEXT, RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT,
+ * RM_MEMIF_EMIF_2_CONTEXT, RM_MEMIF_EMIF_FW_CONTEXT, RM_MEMIF_EMIF_H1_CONTEXT,
+ * RM_MEMIF_EMIF_H2_CONTEXT, RM_SDMA_SDMA_CONTEXT, RM_L3INIT_HSI_CONTEXT,
+ * RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT, RM_L3INIT_MMC6_CONTEXT,
+ * RM_L3INIT_USB_HOST_CONTEXT, RM_L3INIT_USB_HOST_FS_CONTEXT,
+ * RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_USB_TLL_CONTEXT, RM_DSS_DSS_CONTEXT,
+ * RM_L4PER_GPIO2_CONTEXT, RM_L4PER_GPIO3_CONTEXT, RM_L4PER_GPIO4_CONTEXT,
+ * RM_L4PER_GPIO5_CONTEXT, RM_L4PER_GPIO6_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_L4SEC_AES1_CONTEXT,
+ * RM_L4SEC_AES2_CONTEXT, RM_L4SEC_CRYPTODMA_CONTEXT, RM_L4SEC_DES3DES_CONTEXT,
+ * RM_L4SEC_RNG_CONTEXT, RM_L4SEC_SHA2MD51_CONTEXT, RM_TESLA_TESLA_CONTEXT
+ */
+#define OMAP4430_LOSTCONTEXT_RFF_SHIFT					(1 << 1)
+#define OMAP4430_LOSTCONTEXT_RFF_MASK					BITFIELD(1, 1)
+
+/* Used by RM_ABE_AESS_CONTEXT */
+#define OMAP4430_LOSTMEM_AESSMEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_AESSMEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT */
+#define OMAP4430_LOSTMEM_CAM_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_CAM_MEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_L3INSTR_OCP_WP1_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK				BITFIELD(8, 8)
+
+/* Renamed from LOSTMEM_CORE_NRET_BANK Used by RM_MEMIF_DMM_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_SHIFT			(1 << 9)
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_MASK			BITFIELD(9, 9)
+
+/* Used by RM_L3_2_OCMC_RAM_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK				BITFIELD(8, 8)
+
+/*
+ * Used by RM_D2D_MODEM_ICR_CONTEXT, RM_MEMIF_DMM_CONTEXT,
+ * RM_SDMA_SDMA_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK				BITFIELD(8, 8)
+
+/* Used by RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT */
+#define OMAP4430_LOSTMEM_DSS_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_DSS_MEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_DUCATI_DUCATI_CONTEXT */
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_SHIFT				(1 << 9)
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK				BITFIELD(9, 9)
+
+/* Used by RM_DUCATI_DUCATI_CONTEXT */
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK				BITFIELD(8, 8)
+
+/* Used by RM_EMU_DEBUGSS_CONTEXT */
+#define OMAP4430_LOSTMEM_EMU_BANK_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_EMU_BANK_MASK					BITFIELD(8, 8)
+
+/* Used by RM_GFX_GFX_CONTEXT */
+#define OMAP4430_LOSTMEM_GFX_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_GFX_MEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_HWA_MEM_SHIFT					(1 << 10)
+#define OMAP4430_LOSTMEM_HWA_MEM_MASK					BITFIELD(10, 10)
+
+/*
+ * Used by RM_L3INIT_CCPTX_CONTEXT, RM_L3INIT_EMAC_CONTEXT,
+ * RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT,
+ * RM_L3INIT_MMC6_CONTEXT, RM_L3INIT_PCIESS_CONTEXT, RM_L3INIT_SATA_CONTEXT,
+ * RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
+ * RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_XHPI_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK				BITFIELD(8, 8)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_L1_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_MPU_L1_MASK					BITFIELD(8, 8)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_L2_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_MPU_L2_MASK					BITFIELD(9, 9)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_RAM_SHIFT					(1 << 10)
+#define OMAP4430_LOSTMEM_MPU_RAM_MASK					BITFIELD(10, 10)
+
+/*
+ * Used by RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT,
+ * RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT,
+ * RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK				BITFIELD(8, 8)
+
+/*
+ * Used by RM_ABE_DMIC_CONTEXT, RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT,
+ * RM_ABE_MCBSP3_CONTEXT, RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_PERIHPMEM_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_PERIHPMEM_MASK					BITFIELD(8, 8)
+
+/*
+ * Used by RM_L4PER_MSPROHG_CONTEXT, RM_L4PER_UART1_CONTEXT,
+ * RM_L4PER_UART2_CONTEXT, RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT,
+ * RM_L4SEC_CRYPTODMA_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_RETAINED_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK				BITFIELD(8, 8)
+
+/* Used by RM_IVAHD_SL2_CONTEXT */
+#define OMAP4430_LOSTMEM_SL2_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_SL2_MEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_TCM1_MEM_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_TCM1_MEM_MASK					BITFIELD(8, 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_TCM2_MEM_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_TCM2_MEM_MASK					BITFIELD(9, 9)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_EDMA_SHIFT				(1 << 10)
+#define OMAP4430_LOSTMEM_TESLA_EDMA_MASK				BITFIELD(10, 10)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_L1_SHIFT					(1 << 8)
+#define OMAP4430_LOSTMEM_TESLA_L1_MASK					BITFIELD(8, 8)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_L2_SHIFT					(1 << 9)
+#define OMAP4430_LOSTMEM_TESLA_L2_MASK					BITFIELD(9, 9)
+
+/* Used by RM_WKUP_SARRAM_CONTEXT */
+#define OMAP4430_LOSTMEM_WKUP_BANK_SHIFT				(1 << 8)
+#define OMAP4430_LOSTMEM_WKUP_BANK_MASK					BITFIELD(8, 8)
+
+/*
+ * Used by PM_CORE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_L3INIT_PWRSTCTRL,
+ * PM_ABE_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
+ * PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
+ */
+#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT				(1 << 4)
+#define OMAP4430_LOWPOWERSTATECHANGE_MASK				BITFIELD(4, 4)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_MEMORYCHANGE_SHIFT					(1 << 3)
+#define OMAP4430_MEMORYCHANGE_MASK					BITFIELD(3, 3)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_READY_SHIFT					(1 << 1)
+#define OMAP4430_MODEM_READY_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_SHIFT				(1 << 9)
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK				BITFIELD(9, 9)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_SLEEP_ST_SHIFT					(1 << 16)
+#define OMAP4430_MODEM_SLEEP_ST_MASK					BITFIELD(16, 16)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_WAKE_IRQ_SHIFT					(1 << 8)
+#define OMAP4430_MODEM_WAKE_IRQ_MASK					BITFIELD(8, 8)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L1_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_MPU_L1_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L1_RETSTATE_SHIFT					(1 << 8)
+#define OMAP4430_MPU_L1_RETSTATE_MASK					BITFIELD(8, 8)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_L1_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_MPU_L1_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L2_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_MPU_L2_ONSTATE_MASK					BITFIELD(18, 19)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L2_RETSTATE_SHIFT					(1 << 9)
+#define OMAP4430_MPU_L2_RETSTATE_MASK					BITFIELD(9, 9)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_L2_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_MPU_L2_STATEST_MASK					BITFIELD(6, 7)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_RAM_ONSTATE_SHIFT					(1 << 20)
+#define OMAP4430_MPU_RAM_ONSTATE_MASK					BITFIELD(20, 21)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_RAM_RETSTATE_SHIFT					(1 << 10)
+#define OMAP4430_MPU_RAM_RETSTATE_MASK					BITFIELD(10, 10)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_RAM_STATEST_SHIFT					(1 << 8)
+#define OMAP4430_MPU_RAM_STATEST_MASK					BITFIELD(8, 9)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT				(1 << 2)
+#define OMAP4430_MPU_SECURITY_VIOL_RST_MASK				BITFIELD(2, 2)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_MPU_WDT_RST_SHIFT					(1 << 3)
+#define OMAP4430_MPU_WDT_RST_MASK					BITFIELD(3, 3)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_SHIFT				(1 << 18)
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK				BITFIELD(18, 19)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_SHIFT			(1 << 9)
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK				BITFIELD(9, 9)
+
+/* Used by PM_L4PER_PWRSTST */
+#define OMAP4430_NONRETAINED_BANK_STATEST_SHIFT				(1 << 6)
+#define OMAP4430_NONRETAINED_BANK_STATEST_MASK				BITFIELD(6, 7)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_SHIFT				(1 << 24)
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK				BITFIELD(24, 25)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_SHIFT				(1 << 12)
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK				BITFIELD(12, 12)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_OCP_NRET_BANK_STATEST_SHIFT				(1 << 12)
+#define OMAP4430_OCP_NRET_BANK_STATEST_MASK				BITFIELD(12, 13)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_OFF_SHIFT						(1 << 0)
+#define OMAP4430_OFF_MASK						BITFIELD(0, 7)
+
+/* Used by PRM_LDO_BANDGAP_CTRL */
+#define OMAP4430_OFF_ENABLE_SHIFT					(1 << 0)
+#define OMAP4430_OFF_ENABLE_MASK					BITFIELD(0, 0)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_ON_SHIFT						(1 << 24)
+#define OMAP4430_ON_MASK						BITFIELD(24, 31)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_ONLP_SHIFT						(1 << 16)
+#define OMAP4430_ONLP_MASK						BITFIELD(16, 23)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_OPP_CHANGE_SHIFT					(1 << 2)
+#define OMAP4430_OPP_CHANGE_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_OPP_SEL_SHIFT						(1 << 0)
+#define OMAP4430_OPP_SEL_MASK						BITFIELD(0, 1)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_PCHARGECNT_VALUE_SHIFT					(1 << 0)
+#define OMAP4430_PCHARGECNT_VALUE_MASK					BITFIELD(0, 5)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP4430_PCHARGE_TIME_SHIFT					(1 << 0)
+#define OMAP4430_PCHARGE_TIME_MASK					BITFIELD(0, 7)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_PERIPHMEM_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_PERIPHMEM_ONSTATE_MASK					BITFIELD(20, 21)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_PERIPHMEM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_PERIPHMEM_RETSTATE_MASK				BITFIELD(10, 10)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP4430_PERIPHMEM_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_PERIPHMEM_STATEST_MASK					BITFIELD(8, 9)
+
+/* Used by PRM_PHASE1_CNDP */
+#define OMAP4430_PHASE1_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE1_CNDP_MASK					BITFIELD(0, 31)
+
+/* Used by PRM_PHASE2A_CNDP */
+#define OMAP4430_PHASE2A_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE2A_CNDP_MASK					BITFIELD(0, 31)
+
+/* Used by PRM_PHASE2B_CNDP */
+#define OMAP4430_PHASE2B_CNDP_SHIFT					(1 << 0)
+#define OMAP4430_PHASE2B_CNDP_MASK					BITFIELD(0, 31)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_SHIFT				(1 << 8)
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK				BITFIELD(8, 15)
+
+/*
+ * Used by PM_EMU_PWRSTCTRL, PM_CORE_PWRSTCTRL, PM_CAM_PWRSTCTRL,
+ * PM_L3INIT_PWRSTCTRL, PM_ABE_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_MPU_PWRSTCTRL,
+ * PM_CEFUSE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
+ * PM_TESLA_PWRSTCTRL, PM_IVAHD_PWRSTCTRL
+ */
+#define OMAP4430_POWERSTATE_SHIFT					(1 << 0)
+#define OMAP4430_POWERSTATE_MASK					BITFIELD(0, 1)
+
+/*
+ * Used by PM_EMU_PWRSTST, PM_CORE_PWRSTST, PM_CAM_PWRSTST, PM_L3INIT_PWRSTST,
+ * PM_ABE_PWRSTST, PM_GFX_PWRSTST, PM_MPU_PWRSTST, PM_CEFUSE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_L4PER_PWRSTST, PM_TESLA_PWRSTST, PM_IVAHD_PWRSTST
+ */
+#define OMAP4430_POWERSTATEST_SHIFT					(1 << 0)
+#define OMAP4430_POWERSTATEST_MASK					BITFIELD(0, 1)
+
+/* Used by PRM_PWRREQCTRL */
+#define OMAP4430_PWRREQ_COND_SHIFT					(1 << 0)
+#define OMAP4430_PWRREQ_COND_MASK					BITFIELD(0, 1)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_CORE_L_SHIFT					(1 << 3)
+#define OMAP4430_RACEN_VDD_CORE_L_MASK					BITFIELD(3, 3)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_IVA_L_SHIFT					(1 << 11)
+#define OMAP4430_RACEN_VDD_IVA_L_MASK					BITFIELD(11, 11)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_MPU_L_SHIFT					(1 << 20)
+#define OMAP4430_RACEN_VDD_MPU_L_MASK					BITFIELD(20, 20)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_CORE_L_SHIFT					(1 << 2)
+#define OMAP4430_RAC_VDD_CORE_L_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_IVA_L_SHIFT					(1 << 10)
+#define OMAP4430_RAC_VDD_IVA_L_MASK					BITFIELD(10, 10)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_MPU_L_SHIFT					(1 << 19)
+#define OMAP4430_RAC_VDD_MPU_L_MASK					BITFIELD(19, 19)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_DOWN_COUNT_SHIFT					(1 << 16)
+#define OMAP4430_RAMP_DOWN_COUNT_MASK					BITFIELD(16, 21)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_DOWN_PRESCAL_SHIFT				(1 << 24)
+#define OMAP4430_RAMP_DOWN_PRESCAL_MASK					BITFIELD(24, 25)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_UP_COUNT_SHIFT					(1 << 0)
+#define OMAP4430_RAMP_UP_COUNT_MASK					BITFIELD(0, 5)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_UP_PRESCAL_SHIFT					(1 << 8)
+#define OMAP4430_RAMP_UP_PRESCAL_MASK					BITFIELD(8, 9)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_CORE_L_SHIFT					(1 << 1)
+#define OMAP4430_RAV_VDD_CORE_L_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_IVA_L_SHIFT					(1 << 9)
+#define OMAP4430_RAV_VDD_IVA_L_MASK					BITFIELD(9, 9)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_MPU_L_SHIFT					(1 << 18)
+#define OMAP4430_RAV_VDD_MPU_L_MASK					BITFIELD(18, 18)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_REGADDR_SHIFT						(1 << 8)
+#define OMAP4430_REGADDR_MASK						BITFIELD(8, 15)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_RET_SHIFT						(1 << 8)
+#define OMAP4430_RET_MASK						BITFIELD(8, 15)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_RETAINED_BANK_ONSTATE_SHIFT				(1 << 16)
+#define OMAP4430_RETAINED_BANK_ONSTATE_MASK				BITFIELD(16, 17)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_RETAINED_BANK_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_RETAINED_BANK_RETSTATE_MASK				BITFIELD(8, 8)
+
+/* Used by PM_L4PER_PWRSTST */
+#define OMAP4430_RETAINED_BANK_STATEST_SHIFT				(1 << 4)
+#define OMAP4430_RETAINED_BANK_STATEST_MASK				BITFIELD(4, 5)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_RETMODE_ENABLE_SHIFT					(1 << 0)
+#define OMAP4430_RETMODE_ENABLE_MASK					BITFIELD(0, 0)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_REV_SHIFT						(1 << 0)
+#define OMAP4430_REV_MASK						BITFIELD(0, 7)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
+#define OMAP4430_RST1_SHIFT						(1 << 0)
+#define OMAP4430_RST1_MASK						BITFIELD(0, 0)
+
+/* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
+#define OMAP4430_RST1ST_SHIFT						(1 << 0)
+#define OMAP4430_RST1ST_MASK						BITFIELD(0, 0)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_TESLA_RSTCTRL, RM_IVAHD_RSTCTRL */
+#define OMAP4430_RST2_SHIFT						(1 << 1)
+#define OMAP4430_RST2_MASK						BITFIELD(1, 1)
+
+/* Used by RM_DUCATI_RSTST, RM_TESLA_RSTST, RM_IVAHD_RSTST */
+#define OMAP4430_RST2ST_SHIFT						(1 << 1)
+#define OMAP4430_RST2ST_MASK						BITFIELD(1, 1)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL */
+#define OMAP4430_RST3_SHIFT						(1 << 2)
+#define OMAP4430_RST3_MASK						BITFIELD(2, 2)
+
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST */
+#define OMAP4430_RST3ST_SHIFT						(1 << 2)
+#define OMAP4430_RST3ST_MASK						BITFIELD(2, 2)
+
+/* Used by PRM_RSTTIME */
+#define OMAP4430_RSTTIME1_SHIFT						(1 << 0)
+#define OMAP4430_RSTTIME1_MASK						BITFIELD(0, 9)
+
+/* Used by PRM_RSTTIME */
+#define OMAP4430_RSTTIME2_SHIFT						(1 << 10)
+#define OMAP4430_RSTTIME2_MASK						BITFIELD(10, 14)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP4430_RST_GLOBAL_COLD_SW_SHIFT				(1 << 1)
+#define OMAP4430_RST_GLOBAL_COLD_SW_MASK				BITFIELD(1, 1)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP4430_RST_GLOBAL_WARM_SW_SHIFT				(1 << 0)
+#define OMAP4430_RST_GLOBAL_WARM_SW_MASK				BITFIELD(0, 0)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_SA_VDD_CORE_L_MASK					BITFIELD(0, 0)
+
+/* Renamed from SA_VDD_CORE_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_CORE_L_0_6_SHIFT				(1 << 0)
+#define OMAP4430_SA_VDD_CORE_L_0_6_MASK					BITFIELD(0, 6)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_SA_VDD_IVA_L_MASK					BITFIELD(8, 8)
+
+/* Renamed from SA_VDD_IVA_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT			(1 << 8)
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK			BITFIELD(8, 14)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_SA_VDD_MPU_L_MASK					BITFIELD(16, 16)
+
+/* Renamed from SA_VDD_MPU_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT			(1 << 16)
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK			BITFIELD(16, 22)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_SCLH_SHIFT						(1 << 0)
+#define OMAP4430_SCLH_MASK						BITFIELD(0, 7)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_SCLL_SHIFT						(1 << 8)
+#define OMAP4430_SCLL_MASK						BITFIELD(8, 15)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_SECURE_WDT_RST_SHIFT					(1 << 4)
+#define OMAP4430_SECURE_WDT_RST_MASK					BITFIELD(4, 4)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_SL2_MEM_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_SL2_MEM_ONSTATE_MASK					BITFIELD(18, 19)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_SL2_MEM_RETSTATE_SHIFT					(1 << 9)
+#define OMAP4430_SL2_MEM_RETSTATE_MASK					BITFIELD(9, 9)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_SL2_MEM_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_SL2_MEM_STATEST_MASK					BITFIELD(6, 7)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_SLAVEADDR_SHIFT					(1 << 0)
+#define OMAP4430_SLAVEADDR_MASK						BITFIELD(0, 6)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SLEEP_RBB_SEL_SHIFT					(1 << 3)
+#define OMAP4430_SLEEP_RBB_SEL_MASK					BITFIELD(3, 3)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_SLPCNT_VALUE_SHIFT					(1 << 16)
+#define OMAP4430_SLPCNT_VALUE_MASK					BITFIELD(16, 23)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP4430_SMPSWAITTIMEMAX_SHIFT					(1 << 8)
+#define OMAP4430_SMPSWAITTIMEMAX_MASK					BITFIELD(8, 23)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP4430_SMPSWAITTIMEMIN_SHIFT					(1 << 8)
+#define OMAP4430_SMPSWAITTIMEMIN_MASK					BITFIELD(8, 23)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SR2EN_SHIFT						(1 << 0)
+#define OMAP4430_SR2EN_MASK						BITFIELD(0, 0)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_SR2_IN_TRANSITION_SHIFT				(1 << 6)
+#define OMAP4430_SR2_IN_TRANSITION_MASK					BITFIELD(6, 6)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_SR2_STATUS_SHIFT					(1 << 3)
+#define OMAP4430_SR2_STATUS_MASK					BITFIELD(3, 4)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SR2_WTCNT_VALUE_SHIFT					(1 << 8)
+#define OMAP4430_SR2_WTCNT_VALUE_MASK					BITFIELD(8, 15)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_SRAMLDO_STATUS_SHIFT					(1 << 8)
+#define OMAP4430_SRAMLDO_STATUS_MASK					BITFIELD(8, 8)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_SRAM_IN_TRANSITION_SHIFT				(1 << 9)
+#define OMAP4430_SRAM_IN_TRANSITION_MASK				BITFIELD(9, 9)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_SRMODEEN_SHIFT						(1 << 4)
+#define OMAP4430_SRMODEEN_MASK						BITFIELD(4, 4)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP4430_STABLE_COUNT_SHIFT					(1 << 0)
+#define OMAP4430_STABLE_COUNT_MASK					BITFIELD(0, 5)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP4430_STABLE_PRESCAL_SHIFT					(1 << 8)
+#define OMAP4430_STABLE_PRESCAL_MASK					BITFIELD(8, 9)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM1_MEM_ONSTATE_SHIFT					(1 << 20)
+#define OMAP4430_TCM1_MEM_ONSTATE_MASK					BITFIELD(20, 21)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM1_MEM_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_TCM1_MEM_RETSTATE_MASK					BITFIELD(10, 10)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_TCM1_MEM_STATEST_SHIFT					(1 << 8)
+#define OMAP4430_TCM1_MEM_STATEST_MASK					BITFIELD(8, 9)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM2_MEM_ONSTATE_SHIFT					(1 << 22)
+#define OMAP4430_TCM2_MEM_ONSTATE_MASK					BITFIELD(22, 23)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM2_MEM_RETSTATE_SHIFT				(1 << 11)
+#define OMAP4430_TCM2_MEM_RETSTATE_MASK					BITFIELD(11, 11)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_TCM2_MEM_STATEST_SHIFT					(1 << 10)
+#define OMAP4430_TCM2_MEM_STATEST_MASK					BITFIELD(10, 11)
+
+/* Used by RM_TESLA_RSTST */
+#define OMAP4430_TESLASS_EMU_RSTST_SHIFT				(1 << 2)
+#define OMAP4430_TESLASS_EMU_RSTST_MASK					BITFIELD(2, 2)
+
+/* Used by RM_TESLA_RSTST */
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_SHIFT				(1 << 3)
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK				BITFIELD(3, 3)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_EDMA_ONSTATE_SHIFT				(1 << 20)
+#define OMAP4430_TESLA_EDMA_ONSTATE_MASK				BITFIELD(20, 21)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_EDMA_RETSTATE_SHIFT				(1 << 10)
+#define OMAP4430_TESLA_EDMA_RETSTATE_MASK				BITFIELD(10, 10)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_EDMA_STATEST_SHIFT				(1 << 8)
+#define OMAP4430_TESLA_EDMA_STATEST_MASK				BITFIELD(8, 9)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L1_ONSTATE_SHIFT					(1 << 16)
+#define OMAP4430_TESLA_L1_ONSTATE_MASK					BITFIELD(16, 17)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L1_RETSTATE_SHIFT				(1 << 8)
+#define OMAP4430_TESLA_L1_RETSTATE_MASK					BITFIELD(8, 8)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_L1_STATEST_SHIFT					(1 << 4)
+#define OMAP4430_TESLA_L1_STATEST_MASK					BITFIELD(4, 5)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L2_ONSTATE_SHIFT					(1 << 18)
+#define OMAP4430_TESLA_L2_ONSTATE_MASK					BITFIELD(18, 19)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L2_RETSTATE_SHIFT				(1 << 9)
+#define OMAP4430_TESLA_L2_RETSTATE_MASK					BITFIELD(9, 9)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_L2_STATEST_SHIFT					(1 << 6)
+#define OMAP4430_TESLA_L2_STATEST_MASK					BITFIELD(6, 7)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_TIMEOUT_SHIFT						(1 << 0)
+#define OMAP4430_TIMEOUT_MASK						BITFIELD(0, 15)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_TIMEOUTEN_SHIFT					(1 << 3)
+#define OMAP4430_TIMEOUTEN_MASK						BITFIELD(3, 3)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_TRANSITION_EN_SHIFT					(1 << 8)
+#define OMAP4430_TRANSITION_EN_MASK					BITFIELD(8, 8)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_TRANSITION_ST_SHIFT					(1 << 8)
+#define OMAP4430_TRANSITION_ST_MASK					BITFIELD(8, 8)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_VALID_SHIFT						(1 << 24)
+#define OMAP4430_VALID_MASK						BITFIELD(24, 24)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_BYPASSACK_EN_SHIFT					(1 << 14)
+#define OMAP4430_VC_BYPASSACK_EN_MASK					BITFIELD(14, 14)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_BYPASSACK_ST_SHIFT					(1 << 14)
+#define OMAP4430_VC_BYPASSACK_ST_MASK					BITFIELD(14, 14)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_IVA_VPACK_EN_SHIFT					(1 << 30)
+#define OMAP4430_VC_IVA_VPACK_EN_MASK					BITFIELD(30, 30)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_IVA_VPACK_ST_SHIFT					(1 << 30)
+#define OMAP4430_VC_IVA_VPACK_ST_MASK					BITFIELD(30, 30)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VC_MPU_VPACK_EN_SHIFT					(1 << 6)
+#define OMAP4430_VC_MPU_VPACK_EN_MASK					BITFIELD(6, 6)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VC_MPU_VPACK_ST_SHIFT					(1 << 6)
+#define OMAP4430_VC_MPU_VPACK_ST_MASK					BITFIELD(6, 6)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_RAERR_EN_SHIFT					(1 << 12)
+#define OMAP4430_VC_RAERR_EN_MASK					BITFIELD(12, 12)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_RAERR_ST_SHIFT					(1 << 12)
+#define OMAP4430_VC_RAERR_ST_MASK					BITFIELD(12, 12)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_SAERR_EN_SHIFT					(1 << 11)
+#define OMAP4430_VC_SAERR_EN_MASK					BITFIELD(11, 11)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_SAERR_ST_SHIFT					(1 << 11)
+#define OMAP4430_VC_SAERR_ST_MASK					BITFIELD(11, 11)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_TOERR_EN_SHIFT					(1 << 13)
+#define OMAP4430_VC_TOERR_EN_MASK					BITFIELD(13, 13)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_TOERR_ST_SHIFT					(1 << 13)
+#define OMAP4430_VC_TOERR_ST_MASK					BITFIELD(13, 13)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_VDDMAX_SHIFT						(1 << 24)
+#define OMAP4430_VDDMAX_MASK						BITFIELD(24, 31)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_VDDMIN_SHIFT						(1 << 16)
+#define OMAP4430_VDDMIN_MASK						BITFIELD(16, 23)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_CORE_I2C_DISABLE_SHIFT				(1 << 12)
+#define OMAP4430_VDD_CORE_I2C_DISABLE_MASK				BITFIELD(12, 12)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT				(1 << 8)
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK				BITFIELD(8, 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_IVA_I2C_DISABLE_SHIFT				(1 << 14)
+#define OMAP4430_VDD_IVA_I2C_DISABLE_MASK				BITFIELD(14, 14)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_IVA_PRESENCE_SHIFT					(1 << 9)
+#define OMAP4430_VDD_IVA_PRESENCE_MASK					BITFIELD(9, 9)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT				(1 << 7)
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK				BITFIELD(7, 7)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_MPU_I2C_DISABLE_SHIFT				(1 << 13)
+#define OMAP4430_VDD_MPU_I2C_DISABLE_MASK				BITFIELD(13, 13)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_MPU_PRESENCE_SHIFT					(1 << 8)
+#define OMAP4430_VDD_MPU_PRESENCE_MASK					BITFIELD(8, 8)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT				(1 << 6)
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK				BITFIELD(6, 6)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_CORE_L_SHIFT					(1 << 0)
+#define OMAP4430_VOLRA_VDD_CORE_L_MASK					BITFIELD(0, 7)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_IVA_L_SHIFT					(1 << 8)
+#define OMAP4430_VOLRA_VDD_IVA_L_MASK					BITFIELD(8, 15)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_MPU_L_SHIFT					(1 << 16)
+#define OMAP4430_VOLRA_VDD_MPU_L_MASK					BITFIELD(16, 23)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_VPENABLE_SHIFT						(1 << 0)
+#define OMAP4430_VPENABLE_MASK						BITFIELD(0, 0)
+
+/* Used by PRM_VP_CORE_STATUS, PRM_VP_IVA_STATUS, PRM_VP_MPU_STATUS */
+#define OMAP4430_VPINIDLE_SHIFT						(1 << 0)
+#define OMAP4430_VPINIDLE_MASK						BITFIELD(0, 0)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP4430_VPVOLTAGE_SHIFT					(1 << 0)
+#define OMAP4430_VPVOLTAGE_MASK						BITFIELD(0, 7)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_EQVALUE_EN_SHIFT				(1 << 20)
+#define OMAP4430_VP_CORE_EQVALUE_EN_MASK				BITFIELD(20, 20)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_EQVALUE_ST_SHIFT				(1 << 20)
+#define OMAP4430_VP_CORE_EQVALUE_ST_MASK				BITFIELD(20, 20)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_MAXVDD_EN_SHIFT				(1 << 18)
+#define OMAP4430_VP_CORE_MAXVDD_EN_MASK					BITFIELD(18, 18)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_MAXVDD_ST_SHIFT				(1 << 18)
+#define OMAP4430_VP_CORE_MAXVDD_ST_MASK					BITFIELD(18, 18)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_MINVDD_EN_SHIFT				(1 << 17)
+#define OMAP4430_VP_CORE_MINVDD_EN_MASK					BITFIELD(17, 17)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_MINVDD_ST_SHIFT				(1 << 17)
+#define OMAP4430_VP_CORE_MINVDD_ST_MASK					BITFIELD(17, 17)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_SHIFT				(1 << 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK				BITFIELD(19, 19)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_SHIFT				(1 << 19)
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK				BITFIELD(19, 19)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_SHIFT				(1 << 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK				BITFIELD(16, 16)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_SHIFT				(1 << 16)
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK				BITFIELD(16, 16)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_TRANXDONE_EN_SHIFT				(1 << 21)
+#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK				BITFIELD(21, 21)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_TRANXDONE_ST_SHIFT				(1 << 21)
+#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK				BITFIELD(21, 21)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_EQVALUE_EN_SHIFT				(1 << 28)
+#define OMAP4430_VP_IVA_EQVALUE_EN_MASK					BITFIELD(28, 28)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_EQVALUE_ST_SHIFT				(1 << 28)
+#define OMAP4430_VP_IVA_EQVALUE_ST_MASK					BITFIELD(28, 28)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_MAXVDD_EN_SHIFT					(1 << 26)
+#define OMAP4430_VP_IVA_MAXVDD_EN_MASK					BITFIELD(26, 26)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_MAXVDD_ST_SHIFT					(1 << 26)
+#define OMAP4430_VP_IVA_MAXVDD_ST_MASK					BITFIELD(26, 26)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_MINVDD_EN_SHIFT					(1 << 25)
+#define OMAP4430_VP_IVA_MINVDD_EN_MASK					BITFIELD(25, 25)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_MINVDD_ST_SHIFT					(1 << 25)
+#define OMAP4430_VP_IVA_MINVDD_ST_MASK					BITFIELD(25, 25)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_SHIFT				(1 << 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK				BITFIELD(27, 27)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_SHIFT				(1 << 27)
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK				BITFIELD(27, 27)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_SHIFT				(1 << 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK				BITFIELD(24, 24)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_SHIFT				(1 << 24)
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK				BITFIELD(24, 24)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_TRANXDONE_EN_SHIFT				(1 << 29)
+#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK				BITFIELD(29, 29)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_TRANXDONE_ST_SHIFT				(1 << 29)
+#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK				BITFIELD(29, 29)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_EQVALUE_EN_SHIFT				(1 << 4)
+#define OMAP4430_VP_MPU_EQVALUE_EN_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_EQVALUE_ST_SHIFT				(1 << 4)
+#define OMAP4430_VP_MPU_EQVALUE_ST_MASK					BITFIELD(4, 4)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_MAXVDD_EN_SHIFT					(1 << 2)
+#define OMAP4430_VP_MPU_MAXVDD_EN_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_MAXVDD_ST_SHIFT					(1 << 2)
+#define OMAP4430_VP_MPU_MAXVDD_ST_MASK					BITFIELD(2, 2)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_MINVDD_EN_SHIFT					(1 << 1)
+#define OMAP4430_VP_MPU_MINVDD_EN_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_MINVDD_ST_SHIFT					(1 << 1)
+#define OMAP4430_VP_MPU_MINVDD_ST_MASK					BITFIELD(1, 1)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_SHIFT				(1 << 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK				BITFIELD(3, 3)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_SHIFT				(1 << 3)
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK				BITFIELD(3, 3)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_SHIFT				(1 << 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK				BITFIELD(0, 0)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_SHIFT				(1 << 0)
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK				BITFIELD(0, 0)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_TRANXDONE_EN_SHIFT				(1 << 5)
+#define OMAP4430_VP_MPU_TRANXDONE_EN_MASK				BITFIELD(5, 5)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_TRANXDONE_ST_SHIFT				(1 << 5)
+#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK				BITFIELD(5, 5)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_VSETUPCNT_VALUE_SHIFT					(1 << 8)
+#define OMAP4430_VSETUPCNT_VALUE_MASK					BITFIELD(8, 15)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP4430_VSTEPMAX_SHIFT						(1 << 0)
+#define OMAP4430_VSTEPMAX_MASK						BITFIELD(0, 7)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP4430_VSTEPMIN_SHIFT						(1 << 0)
+#define OMAP4430_VSTEPMIN_MASK						BITFIELD(0, 7)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_WAKE_MODEM_SHIFT					(1 << 0)
+#define OMAP4430_WAKE_MODEM_MASK					BITFIELD(0, 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DISPC_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_DISPC_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_DISPC_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_DMTIMER10_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_DMTIMER11_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_DMTIMER11_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_DMTIMER2_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_DMTIMER3_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_DMTIMER3_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_DMTIMER4_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_DMTIMER4_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_DMTIMER9_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_DMTIMER9_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_SHIFT				(1 << 5)
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK				BITFIELD(5, 5)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_MPU_SHIFT					(1 << 4)
+#define OMAP4430_WKUPDEP_DSI1_MPU_MASK					BITFIELD(4, 4)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_DSI1_SDMA_MASK					BITFIELD(7, 7)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_DSI1_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_SHIFT				(1 << 9)
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK				BITFIELD(9, 9)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_MPU_SHIFT					(1 << 8)
+#define OMAP4430_WKUPDEP_DSI2_MPU_MASK					BITFIELD(8, 8)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_SDMA_SHIFT				(1 << 11)
+#define OMAP4430_WKUPDEP_DSI2_SDMA_MASK					BITFIELD(11, 11)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_TESLA_SHIFT				(1 << 10)
+#define OMAP4430_WKUPDEP_DSI2_TESLA_MASK				BITFIELD(10, 10)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_SHIFT				(1 << 19)
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK				BITFIELD(19, 19)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_SHIFT				(1 << 13)
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK				BITFIELD(13, 13)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_SHIFT				(1 << 12)
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK				BITFIELD(12, 12)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_SHIFT				(1 << 14)
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK				BITFIELD(14, 14)
+
+/* Used by PM_L4PER_HECC1_WKDEP */
+#define OMAP4430_WKUPDEP_HECC1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HECC1_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L4PER_HECC2_WKDEP */
+#define OMAP4430_WKUPDEP_HECC2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HECC2_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_I2C5_WKDEP */
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_I2C5_WKDEP */
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_WKUP_KEYBOARD_WKDEP */
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC1_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMC1_SDMA_MASK					BITFIELD(3, 3)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC1_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC2_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMC2_SDMA_MASK					BITFIELD(3, 3)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC2_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_MMC6_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_MMC6_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L3INIT_PCIESS_WKDEP */
+#define OMAP4430_WKUPDEP_PCIESS_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_PCIESS_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_PCIESS_WKDEP */
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_SHIFT				(1 << 7)
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_SHIFT				(1 << 6)
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK				BITFIELD(6, 6)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_WKUP_RTC_WKDEP */
+#define OMAP4430_WKUPDEP_RTC_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_RTC_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_SATA_WKDEP */
+#define OMAP4430_WKUPDEP_SATA_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_SATA_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_SATA_WKDEP */
+#define OMAP4430_WKUPDEP_SATA_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_SATA_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT			(1 << 7)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_SHIFT			(1 << 6)
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK			BITFIELD(6, 6)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_SHIFT			(1 << 2)
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK			BITFIELD(2, 2)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_SHIFT			(1 << 7)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK				BITFIELD(7, 7)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_SHIFT			(1 << 6)
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK			BITFIELD(6, 6)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_SHIFT			(1 << 2)
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK			BITFIELD(2, 2)
+
+/* Used by PM_ALWON_SR_CORE_WKDEP */
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_ALWON_SR_CORE_WKDEP */
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ALWON_SR_IVA_WKDEP */
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_ALWON_SR_IVA_WKDEP */
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ALWON_SR_MPU_WKDEP */
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_WKUP_TIMER12_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER12_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER12_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_WKUP_TIMER1_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER5_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER5_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER6_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER6_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER7_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER7_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER8_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_TIMER8_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP4430_WKUPDEP_UART1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART1_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP4430_WKUPDEP_UART1_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART1_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP4430_WKUPDEP_UART2_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART2_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP4430_WKUPDEP_UART2_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART2_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_UART3_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART3_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART3_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_TESLA_SHIFT				(1 << 2)
+#define OMAP4430_WKUPDEP_UART3_TESLA_MASK				BITFIELD(2, 2)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP4430_WKUPDEP_UART4_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UART4_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP4430_WKUPDEP_UART4_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_UART4_SDMA_MASK				BITFIELD(3, 3)
+
+/* Used by PM_L3INIT_UNIPRO1_WKDEP */
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_UNIPRO1_WKDEP */
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_USB_HOST_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_SHIFT			(1 << 1)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK			BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_USB_HOST_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_USB_OTG_WKDEP */
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_USB_OTG_WKDEP */
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_USB_TLL_WKDEP */
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_L3INIT_USB_TLL_WKDEP */
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_SHIFT				(1 << 0)
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK				BITFIELD(0, 0)
+
+/* Used by PM_WKUP_USIM_WKDEP */
+#define OMAP4430_WKUPDEP_USIM_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_USIM_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_WKUP_USIM_WKDEP */
+#define OMAP4430_WKUPDEP_USIM_SDMA_SHIFT				(1 << 3)
+#define OMAP4430_WKUPDEP_USIM_SDMA_MASK					BITFIELD(3, 3)
+
+/* Used by PM_WKUP_WDT2_WKDEP */
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PM_WKUP_WDT2_WKDEP */
+#define OMAP4430_WKUPDEP_WDT2_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_WDT2_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_ABE_WDT3_WKDEP */
+#define OMAP4430_WKUPDEP_WDT3_MPU_SHIFT					(1 << 0)
+#define OMAP4430_WKUPDEP_WDT3_MPU_MASK					BITFIELD(0, 0)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_SHIFT				(1 << 8)
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK				BITFIELD(8, 8)
+
+/* Used by PM_L3INIT_XHPI_WKDEP */
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_SHIFT				(1 << 1)
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK				BITFIELD(1, 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_WUCLK_CTRL_SHIFT					(1 << 8)
+#define OMAP4430_WUCLK_CTRL_MASK					BITFIELD(8, 8)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_WUCLK_STATUS_SHIFT					(1 << 9)
+#define OMAP4430_WUCLK_STATUS_MASK					BITFIELD(9, 9)
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,51 @@
+/*
+ * SDRC register values for the Hynix H8MBX00U0MER-0EM
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
+#define __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
+
+#include <plat/sdrc.h>
+
+/* Hynix H8MBX00U0MER-0EM */
+static struct omap_sdrc_params h8mbx00u0mer0em_sdrc_params[] = {
+	[0] = {
+		.rate        = 200000000,
+		.actim_ctrla = 0xa2e1b4c6,
+		.actim_ctrlb = 0x0002131c,
+		.rfr_ctrl    = 0x0005e601,
+		.mr          = 0x00000032,
+	},
+	[1] = {
+		.rate        = 166000000,
+		.actim_ctrla = 0x629db4c6,
+		.actim_ctrlb = 0x00012214,
+		.rfr_ctrl    = 0x0004dc01,
+		.mr          = 0x00000032,
+	},
+	[2] = {
+		.rate        = 100000000,
+		.actim_ctrla = 0x51912284,
+		.actim_ctrlb = 0x0002120e,
+		.rfr_ctrl    = 0x0002d101,
+		.mr          = 0x00000022,
+	},
+	[3] = {
+		.rate        = 83000000,
+		.actim_ctrla = 0x31512283,
+		.actim_ctrlb = 0x0001220a,
+		.rfr_ctrl    = 0x00025501,
+		.mr          = 0x00000022,
+	},
+	[4] = {
+		.rate        = 0
+	},
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
 #ifndef ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
 #define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 
 /* Micron MT46H32M32LF-6 */
 /* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
 #ifndef ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
 #define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 
 /* Qimonda HYB18M512160AF-6 */
 static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc2xxx.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc2xxx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc2xxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc2xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,13 +24,13 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <mach/common.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
 
 #include "prm.h"
 #include "clock.h"
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 #include "sdrc.h"
 
 /* Memory timing, DLL mode flags */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,13 +23,13 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <mach/common.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
 
 #include "prm.h"
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 #include "sdrc.h"
 
 static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
@@ -37,12 +37,38 @@ static struct omap_sdrc_params *sdrc_ini
 void __iomem *omap2_sdrc_base;
 void __iomem *omap2_sms_base;
 
+struct omap2_sms_regs {
+	u32	sms_sysconfig;
+};
+
+static struct omap2_sms_regs sms_context;
+
 /* SDRC_POWER register bits */
 #define SDRC_POWER_EXTCLKDIS_SHIFT		3
 #define SDRC_POWER_PWDENA_SHIFT			2
 #define SDRC_POWER_PAGEPOLICY_SHIFT		0
 
 /**
+ * omap2_sms_save_context - Save SMS registers
+ *
+ * Save SMS registers that need to be restored after off mode.
+ */
+void omap2_sms_save_context(void)
+{
+	sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG);
+}
+
+/**
+ * omap2_sms_restore_context - Restore SMS registers
+ *
+ * Restore SMS registers that need to be Restored after off mode.
+ */
+void omap2_sms_restore_context(void)
+{
+	sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG);
+}
+
+/**
  * omap2_sdrc_get_params - return SDRC register values for a given clock rate
  * @r: SDRC clock rate (in Hz)
  * @sdrc_cs0: chip select 0 ram timings **
@@ -132,4 +158,21 @@ void __init omap2_sdrc_init(struct omap_
 	l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
 		(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
 	sdrc_write_reg(l, SDRC_POWER);
+	omap2_sms_save_context();
 }
+
+void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_CONTROL(ctx));
+}
+
+void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_SIZE(ctx));
+}
+
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+	sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx));
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc.h linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sdrc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sdrc.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,12 @@
  */
 #undef DEBUG
 
-#include <mach/sdrc.h>
+#include <plat/sdrc.h>
 
 #ifndef __ASSEMBLER__
+
+#include <linux/io.h>
+
 extern void __iomem *omap2_sdrc_base;
 extern void __iomem *omap2_sms_base;
 
@@ -48,9 +51,28 @@ static inline u32 sms_read_reg(u16 reg)
 	return __raw_readl(OMAP_SMS_REGADDR(reg));
 }
 #else
-#define OMAP242X_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg))
-#define OMAP243X_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg))
-#define OMAP34XX_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg))
+#define OMAP242X_SDRC_REGADDR(reg)					\
+			OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg))
+#define OMAP243X_SDRC_REGADDR(reg)					\
+			OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg))
+#define OMAP34XX_SDRC_REGADDR(reg)					\
+			OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg))
 #endif	/* __ASSEMBLER__ */
 
+/* Minimum frequency that the SDRC DLL can lock at */
+#define MIN_SDRC_DLL_LOCK_FREQ		83000000
+
+/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */
+#define SDRC_MPURATE_SCALE		8
+
+/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */
+#define SDRC_MPURATE_BASE_SHIFT		9
+
+/*
+ * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at
+ * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize
+ */
+#define SDRC_MPURATE_LOOPS		96
+
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/serial.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/serial.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/serial.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/serial.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,18 +24,25 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <mach/common.h>
-#include <mach/board.h>
-#include <mach/clock.h>
-#include <mach/control.h>
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/clock.h>
+#include <plat/control.h>
 
 #include "prm.h"
 #include "pm.h"
 #include "prm-regbits-34xx.h"
 
+#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV	0x52
 #define UART_OMAP_WER		0x17	/* Wake-up enable register */
 
-#define DEFAULT_TIMEOUT (5 * HZ)
+/*
+ * NOTE: By default the serial timeout is disabled as it causes lost characters
+ * over the serial ports. This means that the UART clocks will stay on until
+ * disabled via sysfs. This also causes that any deeper omap sleep states are
+ * blocked. 
+ */
+#define DEFAULT_TIMEOUT 0
 
 struct omap_uart_state {
 	int num;
@@ -73,7 +80,6 @@ static LIST_HEAD(uart_list);
 
 static struct plat_serial8250_port serial_platform_data0[] = {
 	{
-		.membase	= OMAP2_IO_ADDRESS(OMAP_UART1_BASE),
 		.mapbase	= OMAP_UART1_BASE,
 		.irq		= 72,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -87,7 +93,6 @@ static struct plat_serial8250_port seria
 
 static struct plat_serial8250_port serial_platform_data1[] = {
 	{
-		.membase	= OMAP2_IO_ADDRESS(OMAP_UART2_BASE),
 		.mapbase	= OMAP_UART2_BASE,
 		.irq		= 73,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -101,7 +106,6 @@ static struct plat_serial8250_port seria
 
 static struct plat_serial8250_port serial_platform_data2[] = {
 	{
-		.membase	= OMAP2_IO_ADDRESS(OMAP_UART3_BASE),
 		.mapbase	= OMAP_UART3_BASE,
 		.irq		= 74,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -116,7 +120,6 @@ static struct plat_serial8250_port seria
 #ifdef CONFIG_ARCH_OMAP4
 static struct plat_serial8250_port serial_platform_data3[] = {
 	{
-		.membase	= OMAP2_IO_ADDRESS(OMAP_UART4_BASE),
 		.mapbase	= OMAP_UART4_BASE,
 		.irq		= 70,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -128,6 +131,13 @@ static struct plat_serial8250_port seria
 	}
 };
 #endif
+static inline unsigned int __serial_read_reg(struct uart_port *up,
+					   int offset)
+{
+	offset <<= up->regshift;
+	return (unsigned int)__raw_readb(up->membase + offset);
+}
+
 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
 					   int offset)
 {
@@ -159,8 +169,6 @@ static inline void __init omap_uart_rese
 
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
 
-static int enable_off_mode; /* to be removed by full off-mode patches */
-
 static void omap_uart_save_context(struct omap_uart_state *uart)
 {
 	u16 lcr = 0;
@@ -420,7 +428,8 @@ static void omap_uart_idle_init(struct o
 	uart->timeout = DEFAULT_TIMEOUT;
 	setup_timer(&uart->timer, omap_uart_idle_timer,
 		    (unsigned long) uart);
-	mod_timer(&uart->timer, jiffies + uart->timeout);
+	if (uart->timeout)
+		mod_timer(&uart->timer, jiffies + uart->timeout);
 	omap_uart_smart_idle_enable(uart, 0);
 
 	if (cpu_is_omap34xx()) {
@@ -539,7 +548,7 @@ static inline void omap_uart_idle_init(s
 #define DEV_CREATE_FILE(dev, attr)
 #endif /* CONFIG_PM */
 
-static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
+static struct omap_uart_state omap_uart[] = {
 	{
 		.pdev = {
 			.name			= "serial8250",
@@ -578,6 +587,24 @@ static struct omap_uart_state omap_uart[
 #endif
 };
 
+/*
+ * Override the default 8250 read handler: mem_serial_in()
+ * Empty RX fifo read causes an abort on omap3630 and omap4
+ * This function makes sure that an empty rx fifo is not read on these silicons
+ * (OMAP1/2/3430 are not affected)
+ */
+static unsigned int serial_in_override(struct uart_port *up, int offset)
+{
+	if (UART_RX == offset) {
+		unsigned int lsr;
+		lsr = __serial_read_reg(up, UART_LSR);
+		if (!(lsr & UART_LSR_DR))
+			return -EPERM;
+	}
+
+	return __serial_read_reg(up, offset);
+}
+
 void __init omap_serial_early_init(void)
 {
 	int i;
@@ -589,12 +616,22 @@ void __init omap_serial_early_init(void)
 	 * if not needed.
 	 */
 
-	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+	for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
 		struct omap_uart_state *uart = &omap_uart[i];
 		struct platform_device *pdev = &uart->pdev;
 		struct device *dev = &pdev->dev;
 		struct plat_serial8250_port *p = dev->platform_data;
 
+		/*
+		 * Module 4KB + L4 interconnect 4KB
+		 * Static mapping, never released
+		 */
+		p->membase = ioremap(p->mapbase, SZ_8K);
+		if (!p->membase) {
+			printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
+			continue;
+		}
+
 		sprintf(name, "uart%d_ick", i+1);
 		uart->ick = clk_get(NULL, name);
 		if (IS_ERR(uart->ick)) {
@@ -618,33 +655,74 @@ void __init omap_serial_early_init(void)
 		uart->num = i;
 		p->private_data = uart;
 		uart->p = p;
-		list_add_tail(&uart->node, &uart_list);
 
 		if (cpu_is_omap44xx())
 			p->irq += 32;
-
-		omap_uart_enable_clocks(uart);
 	}
 }
 
-void __init omap_serial_init(void)
+/**
+ * omap_serial_init_port() - initialize single serial port
+ * @port: serial port number (0-3)
+ *
+ * This function initialies serial driver for given @port only.
+ * Platforms can call this function instead of omap_serial_init()
+ * if they don't plan to use all available UARTs as serial ports.
+ *
+ * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
+ * use only one of the two.
+ */
+void __init omap_serial_init_port(int port)
 {
-	int i;
+	struct omap_uart_state *uart;
+	struct platform_device *pdev;
+	struct device *dev;
 
-	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
-		struct omap_uart_state *uart = &omap_uart[i];
-		struct platform_device *pdev = &uart->pdev;
-		struct device *dev = &pdev->dev;
+	BUG_ON(port < 0);
+	BUG_ON(port >= ARRAY_SIZE(omap_uart));
 
-		omap_uart_reset(uart);
-		omap_uart_idle_init(uart);
+	uart = &omap_uart[port];
+	pdev = &uart->pdev;
+	dev = &pdev->dev;
 
-		if (WARN_ON(platform_device_register(pdev)))
-			continue;
-		if ((cpu_is_omap34xx() && uart->padconf) ||
-		    (uart->wk_en && uart->wk_mask)) {
-			device_init_wakeup(dev, true);
-			DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
-		}
+	omap_uart_enable_clocks(uart);
+
+	omap_uart_reset(uart);
+	omap_uart_idle_init(uart);
+
+	list_add_tail(&uart->node, &uart_list);
+
+	if (WARN_ON(platform_device_register(pdev)))
+		return;
+
+	if ((cpu_is_omap34xx() && uart->padconf) ||
+	    (uart->wk_en && uart->wk_mask)) {
+		device_init_wakeup(dev, true);
+		DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
 	}
+
+		/* omap44xx: Never read empty UART fifo
+		 * omap3xxx: Never read empty UART fifo on UARTs
+		 * with IP rev >=0x52
+		 */
+		if (cpu_is_omap44xx())
+			uart->p->serial_in = serial_in_override;
+		else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
+				>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
+			uart->p->serial_in = serial_in_override;
+}
+
+/**
+ * omap_serial_init() - intialize all supported serial ports
+ *
+ * Initializes all available UARTs as serial ports. Platforms
+ * can call this function when they want to have default behaviour
+ * for serial ports (e.g initialize them all as serial ports).
+ */
+void __init omap_serial_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(omap_uart); i++)
+		omap_serial_init_port(i);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sleep24xx.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep24xx.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sleep24xx.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep24xx.S	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,7 @@
 #include <asm/assembler.h>
 #include <mach/io.h>
 
-#include <mach/omap24xx.h>
+#include <plat/omap24xx.h>
 
 #include "sdrc.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sleep34xx.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep34xx.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sleep34xx.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sleep34xx.S	2010-02-24 13:52:17.000000000 -0500
@@ -27,22 +27,35 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <mach/io.h>
-#include <mach/control.h>
+#include <plat/control.h>
 
+#include "cm.h"
 #include "prm.h"
 #include "sdrc.h"
 
 #define PM_PREPWSTST_CORE_V	OMAP34XX_PRM_REGADDR(CORE_MOD, \
 				OMAP3430_PM_PREPWSTST)
+#define PM_PREPWSTST_CORE_P	0x48306AE8
 #define PM_PREPWSTST_MPU_V	OMAP34XX_PRM_REGADDR(MPU_MOD, \
 				OMAP3430_PM_PREPWSTST)
-#define PM_PWSTCTRL_MPU_P	OMAP34XX_PRM_REGADDR(MPU_MOD, PM_PWSTCTRL)
+#define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
+#define CM_IDLEST1_CORE_V	OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
+#define SRAM_BASE_P		0x40200000
+#define CONTROL_STAT		0x480022F0
 #define SCRATCHPAD_MEM_OFFS	0x310 /* Move this as correct place is
 				       * available */
-#define SCRATCHPAD_BASE_P	OMAP343X_CTRL_REGADDR(\
-				OMAP343X_CONTROL_MEM_WKUP +\
-				SCRATCHPAD_MEM_OFFS)
+#define SCRATCHPAD_BASE_P	(OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
+						+ SCRATCHPAD_MEM_OFFS)
 #define SDRC_POWER_V		OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+#define SDRC_SYSCONFIG_P	(OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
+#define SDRC_MR_0_P		(OMAP343X_SDRC_BASE + SDRC_MR_0)
+#define SDRC_EMR2_0_P		(OMAP343X_SDRC_BASE + SDRC_EMR2_0)
+#define SDRC_MANUAL_0_P		(OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
+#define SDRC_MR_1_P		(OMAP343X_SDRC_BASE + SDRC_MR_1)
+#define SDRC_EMR2_1_P		(OMAP343X_SDRC_BASE + SDRC_EMR2_1)
+#define SDRC_MANUAL_1_P		(OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
+#define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
+#define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
 
 	.text
 /* Function call to get the restore pointer for resume from OFF */
@@ -51,7 +64,93 @@ ENTRY(get_restore_pointer)
 	adr	r0, restore
         ldmfd   sp!, {pc}     @ restore regs and return
 ENTRY(get_restore_pointer_sz)
-        .word   . - get_restore_pointer_sz
+        .word   . - get_restore_pointer
+
+	.text
+/* Function call to get the restore pointer for for ES3 to resume from OFF */
+ENTRY(get_es3_restore_pointer)
+	stmfd	sp!, {lr}	@ save registers on stack
+	adr	r0, restore_es3
+	ldmfd	sp!, {pc}	@ restore regs and return
+ENTRY(get_es3_restore_pointer_sz)
+	.word	. - get_es3_restore_pointer
+
+ENTRY(es3_sdrc_fix)
+	ldr	r4, sdrc_syscfg		@ get config addr
+	ldr	r5, [r4]		@ get value
+	tst	r5, #0x100		@ is part access blocked
+	it	eq
+	biceq	r5, r5, #0x100		@ clear bit if set
+	str	r5, [r4]		@ write back change
+	ldr	r4, sdrc_mr_0		@ get config addr
+	ldr	r5, [r4]		@ get value
+	str	r5, [r4]		@ write back change
+	ldr	r4, sdrc_emr2_0		@ get config addr
+	ldr	r5, [r4]		@ get value
+	str	r5, [r4]		@ write back change
+	ldr	r4, sdrc_manual_0	@ get config addr
+	mov	r5, #0x2		@ autorefresh command
+	str	r5, [r4]		@ kick off refreshes
+	ldr	r4, sdrc_mr_1		@ get config addr
+	ldr	r5, [r4]		@ get value
+	str	r5, [r4]		@ write back change
+	ldr	r4, sdrc_emr2_1		@ get config addr
+	ldr	r5, [r4]		@ get value
+	str	r5, [r4]		@ write back change
+	ldr	r4, sdrc_manual_1	@ get config addr
+	mov	r5, #0x2		@ autorefresh command
+	str	r5, [r4]		@ kick off refreshes
+	bx	lr
+sdrc_syscfg:
+	.word	SDRC_SYSCONFIG_P
+sdrc_mr_0:
+	.word	SDRC_MR_0_P
+sdrc_emr2_0:
+	.word	SDRC_EMR2_0_P
+sdrc_manual_0:
+	.word	SDRC_MANUAL_0_P
+sdrc_mr_1:
+	.word	SDRC_MR_1_P
+sdrc_emr2_1:
+	.word	SDRC_EMR2_1_P
+sdrc_manual_1:
+	.word	SDRC_MANUAL_1_P
+ENTRY(es3_sdrc_fix_sz)
+	.word	. - es3_sdrc_fix
+
+/* Function to call rom code to save secure ram context */
+ENTRY(save_secure_ram_context)
+	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
+save_secure_ram_debug:
+	/* b save_secure_ram_debug */	@ enable to debug save code
+	adr	r3, api_params		@ r3 points to parameters
+	str	r0, [r3,#0x4]		@ r0 has sdram address
+	ldr	r12, high_mask
+	and	r3, r3, r12
+	ldr	r12, sram_phy_addr_mask
+	orr	r3, r3, r12
+	mov	r0, #25			@ set service ID for PPA
+	mov	r12, r0			@ copy secure service ID in r12
+	mov	r1, #0			@ set task id for ROM code in r1
+	mov	r2, #4			@ set some flags in r2, r6
+	mov	r6, #0xff
+	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
+	.word	0xE1600071		@ call SMI monitor (smi #1)
+	nop
+	nop
+	nop
+	nop
+	ldmfd	sp!, {r1-r12, pc}
+sram_phy_addr_mask:
+	.word	SRAM_BASE_P
+high_mask:
+	.word	0xffff
+api_params:
+	.word	0x4, 0x0, 0x0, 0x1, 0x1
+ENTRY(save_secure_ram_context_sz)
+	.word	. - save_secure_ram_context
+
 /*
  * Forces OMAP into idle state
  *
@@ -92,11 +191,29 @@ loop:
 	nop
 	nop
 	nop
-	bl i_dll_wait
+	bl wait_sdrc_ok
 
 	ldmfd	sp!, {r0-r12, pc}		@ restore regs and return
+restore_es3:
+	/*b restore_es3*/		@ Enable to debug restore code
+	ldr	r5, pm_prepwstst_core_p
+	ldr	r4, [r5]
+	and	r4, r4, #0x3
+	cmp	r4, #0x0	@ Check if previous power state of CORE is OFF
+	bne	restore
+	adr	r0, es3_sdrc_fix
+	ldr	r1, sram_base
+	ldr	r2, es3_sdrc_fix_sz
+	mov	r2, r2, ror #2
+copy_to_sram:
+	ldmia	r0!, {r3}	@ val = *src
+	stmia	r1!, {r3}	@ *dst = val
+	subs	r2, r2, #0x1	@ num_words--
+	bne	copy_to_sram
+	ldr	r1, sram_base
+	blx	r1
 restore:
-	/* b restore*/ 	@ Enable to debug restore code
+	/* b restore*/  @ Enable to debug restore code
         /* Check what was the reason for mpu reset and store the reason in r9*/
         /* 1 - Only L1 and logic lost */
         /* 2 - Only L2 lost - In this case, we wont be here */
@@ -108,9 +225,45 @@ restore:
         moveq   r9, #0x3        @ MPU OFF => L1 and L2 lost
 	movne	r9, #0x1	@ Only L1 and L2 lost => avoid L2 invalidation
 	bne	logic_l1_restore
+	ldr	r0, control_stat
+	ldr	r1, [r0]
+	and	r1, #0x700
+	cmp	r1, #0x300
+	beq	l2_inv_gp
+	mov	r0, #40		@ set service ID for PPA
+	mov	r12, r0		@ copy secure Service ID in r12
+	mov	r1, #0		@ set task id for ROM code in r1
+	mov	r2, #4		@ set some flags in r2, r6
+	mov	r6, #0xff
+	adr	r3, l2_inv_api_params	@ r3 points to dummy parameters
+	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
+	.word	0xE1600071		@ call SMI monitor (smi #1)
+	/* Write to Aux control register to set some bits */
+	mov	r0, #42		@ set service ID for PPA
+	mov	r12, r0		@ copy secure Service ID in r12
+	mov	r1, #0		@ set task id for ROM code in r1
+	mov	r2, #4		@ set some flags in r2, r6
+	mov	r6, #0xff
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4, #0xBC]	@ r3 points to parameters
+	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
+	.word	0xE1600071		@ call SMI monitor (smi #1)
+
+	b	logic_l1_restore
+l2_inv_api_params:
+	.word   0x1, 0x00
+l2_inv_gp:
 	/* Execute smi to invalidate L2 cache */
 	mov r12, #0x1                         @ set up to invalide L2
-smi:    .word 0xE1600070                @ Call SMI monitor (smieq)
+smi:    .word 0xE1600070		@ Call SMI monitor (smieq)
+	/* Write to Aux control register to set some bits */
+	ldr	r4, scratchpad_base
+	ldr	r3, [r4,#0xBC]
+	ldr	r0, [r3,#4]
+	mov	r12, #0x3
+	.word 0xE1600070	@ Call SMI monitor (smieq)
 logic_l1_restore:
 	mov	r1, #0
 	/* Invalidate all instruction caches to PoU
@@ -119,6 +272,7 @@ logic_l1_restore:
 
 	ldr	r4, scratchpad_base
 	ldr	r3, [r4,#0xBC]
+	adds	r3, r3, #8
 	ldmia	r3!, {r4-r6}
 	mov	sp, r4
 	msr	spsr_cxsf, r5
@@ -235,6 +389,9 @@ usettbr0:
 save_context_wfi:
 	/*b	save_context_wfi*/	@ enable to debug save code
 	mov	r8, r0 /* Store SDRAM address in r8 */
+	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
+	mov	r4, #0x1		@ Number of parameters for restore call
+	stmia	r8!, {r4-r5}
         /* Check what that target sleep state is:stored in r1*/
         /* 1 - Only L1 and logic lost */
         /* 2 - Only L2 lost */
@@ -391,33 +548,55 @@ skip_l2_inval:
 	nop
 	nop
 	nop
-	bl i_dll_wait
+	bl wait_sdrc_ok
 	/* restore regs and return */
 	ldmfd   sp!, {r0-r12, pc}
 
-i_dll_wait:
-	ldr     r4, clk_stabilize_delay
+/* Make sure SDRC accesses are ok */
+wait_sdrc_ok:
+        ldr     r4, cm_idlest1_core
+        ldr     r5, [r4]
+        and     r5, r5, #0x2
+        cmp     r5, #0
+        bne     wait_sdrc_ok
+        ldr     r4, sdrc_power
+        ldr     r5, [r4]
+        bic     r5, r5, #0x40
+        str     r5, [r4]
+wait_dll_lock:
+        /* Is dll in lock mode? */
+        ldr     r4, sdrc_dlla_ctrl
+        ldr     r5, [r4]
+        tst     r5, #0x4
+        bxne    lr
+        /* wait till dll locks */
+        ldr     r4, sdrc_dlla_status
+        ldr     r5, [r4]
+        and     r5, r5, #0x4
+        cmp     r5, #0x4
+        bne     wait_dll_lock
+        bx      lr
 
-i_dll_delay:
-	subs    r4, r4, #0x1
-	bne     i_dll_delay
-	ldr     r4, sdrc_power
-	ldr     r5, [r4]
-	bic     r5, r5, #0x40
-	str     r5, [r4]
-	bx	lr
+cm_idlest1_core:
+	.word	CM_IDLEST1_CORE_V
+sdrc_dlla_status:
+	.word	SDRC_DLLA_STATUS_V
+sdrc_dlla_ctrl:
+	.word	SDRC_DLLA_CTRL_V
 pm_prepwstst_core:
 	.word	PM_PREPWSTST_CORE_V
+pm_prepwstst_core_p:
+	.word	PM_PREPWSTST_CORE_P
 pm_prepwstst_mpu:
 	.word	PM_PREPWSTST_MPU_V
 pm_pwstctrl_mpu:
 	.word	PM_PWSTCTRL_MPU_P
 scratchpad_base:
 	.word	SCRATCHPAD_BASE_P
+sram_base:
+	.word	SRAM_BASE_P + 0x8000
 sdrc_power:
 	.word SDRC_POWER_V
-context_mem:
-	.word	0x803E3E14
 clk_stabilize_delay:
 	.word 0x000001FF
 assoc_mask:
@@ -432,5 +611,7 @@ table_entry:
 	.word	0x00000C02
 cache_pred_disable_mask:
 	.word	0xFFFFE7FB
+control_stat:
+	.word	CONTROL_STAT
 ENTRY(omap34xx_cpu_suspend_sz)
 	.word	. - omap34xx_cpu_suspend
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram242x.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram242x.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram242x.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram242x.S	2010-02-24 13:52:17.000000000 -0500
@@ -128,7 +128,7 @@ omap242x_sdi_prcm_voltctrl:
 prcm_mask_val:
 	.word 0xFFFF3FFC
 omap242x_sdi_timer_32ksynct_cr:
-	.word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+	.word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
 ENTRY(omap242x_sram_ddr_init_sz)
 	.word	. - omap242x_sram_ddr_init
 
@@ -224,7 +224,7 @@ omap242x_srs_prcm_voltctrl:
 ddr_prcm_mask_val:
 	.word 0xFFFF3FFC
 omap242x_srs_timer_32ksynct:
-	.word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+	.word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
 
 ENTRY(omap242x_sram_reprogram_sdrc_sz)
 	.word	. - omap242x_sram_reprogram_sdrc
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram243x.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram243x.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram243x.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram243x.S	2010-02-24 13:52:17.000000000 -0500
@@ -128,7 +128,7 @@ omap243x_sdi_prcm_voltctrl:
 prcm_mask_val:
 	.word 0xFFFF3FFC
 omap243x_sdi_timer_32ksynct_cr:
-	.word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+	.word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
 ENTRY(omap243x_sram_ddr_init_sz)
 	.word	. - omap243x_sram_ddr_init
 
@@ -224,7 +224,7 @@ omap243x_srs_prcm_voltctrl:
 ddr_prcm_mask_val:
 	.word 0xFFFF3FFC
 omap243x_srs_timer_32ksynct:
-	.word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+	.word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
 
 ENTRY(omap243x_sram_reprogram_sdrc_sz)
 	.word	. - omap243x_sram_reprogram_sdrc
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram34xx.S linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram34xx.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/sram34xx.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/sram34xx.S	2010-02-24 13:52:17.000000000 -0500
@@ -91,8 +91,19 @@
  *  new SDRC_ACTIM_CTRL_B_1 register contents
  *  new SDRC_MR_1 register value
  *
- * If the param SDRC_RFR_CTRL_1 is 0, the parameters
- *  are not programmed into the SDRC CS1 registers
+ * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into
+ * the SDRC CS1 registers
+ *
+ * NOTE: This code no longer attempts to program the SDRC AC timing and MR
+ * registers.  This is because the code currently cannot ensure that all
+ * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the
+ * SDRAM when the registers are written.  If the registers are changed while
+ * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC
+ * may enter an unpredictable state.  In the future, the intent is to
+ * re-enable this code in cases where we can ensure that no initiators are
+ * touching the SDRAM.  Until that time, users who know that their use case
+ * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING
+ * option.
  */
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
@@ -219,6 +230,7 @@ configure_sdrc:
 	ldr	r12, omap_sdrc_rfr_ctrl_0_val	@ fetch value from SRAM
 	ldr	r11, omap3_sdrc_rfr_ctrl_0	@ fetch addr from SRAM
 	str	r12, [r11]			@ store
+#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
 	ldr	r12, omap_sdrc_actim_ctrl_a_0_val
 	ldr	r11, omap3_sdrc_actim_ctrl_a_0
 	str	r12, [r11]
@@ -228,11 +240,13 @@ configure_sdrc:
 	ldr	r12, omap_sdrc_mr_0_val
 	ldr	r11, omap3_sdrc_mr_0
 	str	r12, [r11]
+#endif
 	ldr	r12, omap_sdrc_rfr_ctrl_1_val
 	cmp	r12, #0			@ if SDRC_RFR_CTRL_1 is 0,
 	beq	skip_cs1_prog		@  do not program cs1 params
 	ldr	r11, omap3_sdrc_rfr_ctrl_1
 	str	r12, [r11]
+#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
 	ldr	r12, omap_sdrc_actim_ctrl_a_1_val
 	ldr	r11, omap3_sdrc_actim_ctrl_a_1
 	str	r12, [r11]
@@ -242,6 +256,7 @@ configure_sdrc:
 	ldr	r12, omap_sdrc_mr_1_val
 	ldr	r11, omap3_sdrc_mr_1
 	str	r12, [r11]
+#endif
 skip_cs1_prog:
 	ldr	r12, [r11]		@ posted-write barrier for SDRC
 	bx	lr
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/timer-gp.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-gp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/timer-gp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/timer-gp.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,7 +37,7 @@
 #include <linux/clockchips.h>
 
 #include <asm/mach/time.h>
-#include <mach/dmtimer.h>
+#include <plat/dmtimer.h>
 #include <asm/localtimer.h>
 
 /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
@@ -47,6 +47,7 @@ static struct omap_dm_timer *gptimer;
 static struct clock_event_device clockevent_gpt;
 static u8 __initdata gptimer_id = 1;
 static u8 __initdata inited;
+struct omap_dm_timer *gptimer_wakeup;
 
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
@@ -134,6 +135,7 @@ static void __init omap2_gp_clockevent_i
 
 	gptimer = omap_dm_timer_request_specific(gptimer_id);
 	BUG_ON(gptimer == NULL);
+	gptimer_wakeup = gptimer;
 
 #if defined(CONFIG_OMAP_32K_TIMER)
 	src = OMAP_TIMER_SRC_32_KHZ;
@@ -231,7 +233,8 @@ static void __init omap2_gp_clocksource_
 static void __init omap2_gp_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
-	twd_base = OMAP2_IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE);
+	twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
+	BUG_ON(!twd_base);
 #endif
 	omap_dm_timer_init();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-ehci.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-ehci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-ehci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-ehci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,238 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-ehci.c
+ *
+ * This file will contain the board specific details for the
+ * Synopsys EHCI host controller on OMAP3430
+ *
+ * Copyright (C) 2007 Texas Instruments
+ * Author: Vikram Pandita <vikram.pandita@ti.com>
+ *
+ * Generalization by:
+ * Felipe Balbi <felipe.balbi@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.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <plat/mux.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+
+static struct resource ehci_resources[] = {
+	{
+		.start	= OMAP34XX_EHCI_BASE,
+		.end	= OMAP34XX_EHCI_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP34XX_UHH_CONFIG_BASE,
+		.end	= OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP34XX_USBTLL_BASE,
+		.end	= OMAP34XX_USBTLL_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{         /* general IRQ */
+		.start   = INT_34XX_EHCI_IRQ,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+static struct platform_device ehci_device = {
+	.name           = "ehci-omap",
+	.id             = 0,
+	.dev = {
+		.dma_mask               = &ehci_dmamask,
+		.coherent_dma_mask      = 0xffffffff,
+		.platform_data          = NULL,
+	},
+	.num_resources  = ARRAY_SIZE(ehci_resources),
+	.resource       = ehci_resources,
+};
+
+/* MUX settings for EHCI pins */
+/*
+ * setup_ehci_io_mux - initialize IO pad mux for USBHOST
+ */
+static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
+{
+	switch (port_mode[0]) {
+	case EHCI_HCD_OMAP_MODE_PHY:
+		omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
+		omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
+		omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
+		break;
+	case EHCI_HCD_OMAP_MODE_TLL:
+		omap_mux_init_signal("hsusb1_tll_stp",
+			OMAP_PIN_INPUT_PULLUP);
+		omap_mux_init_signal("hsusb1_tll_clk",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_dir",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_nxt",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data0",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data1",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data2",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data3",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data4",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data5",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data6",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb1_tll_data7",
+			OMAP_PIN_INPUT_PULLDOWN);
+		break;
+	case EHCI_HCD_OMAP_MODE_UNKNOWN:
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+
+	switch (port_mode[1]) {
+	case EHCI_HCD_OMAP_MODE_PHY:
+		omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
+		omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
+		omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data0",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data1",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data2",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data3",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data4",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data5",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data6",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_data7",
+			OMAP_PIN_INPUT_PULLDOWN);
+		break;
+	case EHCI_HCD_OMAP_MODE_TLL:
+		omap_mux_init_signal("hsusb2_tll_stp",
+			OMAP_PIN_INPUT_PULLUP);
+		omap_mux_init_signal("hsusb2_tll_clk",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_dir",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_nxt",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data0",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data1",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data2",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data3",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data4",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data5",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data6",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb2_tll_data7",
+			OMAP_PIN_INPUT_PULLDOWN);
+		break;
+	case EHCI_HCD_OMAP_MODE_UNKNOWN:
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+
+	switch (port_mode[2]) {
+	case EHCI_HCD_OMAP_MODE_PHY:
+		printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
+		break;
+	case EHCI_HCD_OMAP_MODE_TLL:
+		omap_mux_init_signal("hsusb3_tll_stp",
+			OMAP_PIN_INPUT_PULLUP);
+		omap_mux_init_signal("hsusb3_tll_clk",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_dir",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_nxt",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data0",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data1",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data2",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data3",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data4",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data5",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data6",
+			OMAP_PIN_INPUT_PULLDOWN);
+		omap_mux_init_signal("hsusb3_tll_data7",
+			OMAP_PIN_INPUT_PULLDOWN);
+		break;
+	case EHCI_HCD_OMAP_MODE_UNKNOWN:
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+
+	return;
+}
+
+void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+{
+	platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
+
+	/* Setup Pin IO MUX for EHCI */
+	if (cpu_is_omap34xx())
+		setup_ehci_io_mux(pdata->port_mode);
+
+	if (platform_device_register(&ehci_device) < 0) {
+		printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
+		return;
+	}
+}
+
+#else
+
+void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+
+{
+}
+
+#endif /* CONFIG_USB_EHCI_HCD */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-musb.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-musb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-musb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-musb.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,8 +28,8 @@
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
 
 #ifdef CONFIG_USB_MUSB_SOC
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-tusb6010.c linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-tusb6010.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-omap2/usb-tusb6010.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-omap2/usb-tusb6010.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,8 +16,8 @@
 
 #include <linux/usb/musb.h>
 
-#include <mach/gpmc.h>
-#include <mach/mux.h>
+#include <plat/gpmc.h>
+#include <plat/mux.h>
 
 
 static u8		async_cs, sync_cs;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/dns323-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/dns323-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
@@ -32,6 +33,7 @@
 
 #define DNS323_GPIO_LED_RIGHT_AMBER	1
 #define DNS323_GPIO_LED_LEFT_AMBER	2
+#define DNS323_GPIO_SYSTEM_UP		3
 #define DNS323_GPIO_LED_POWER		5
 #define DNS323_GPIO_OVERTEMP		6
 #define DNS323_GPIO_RTC			7
@@ -239,7 +241,7 @@ static struct gpio_led dns323_leds[] = {
 	{
 		.name = "power:blue",
 		.gpio = DNS323_GPIO_LED_POWER,
-		.active_low = 1,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
 	}, {
 		.name = "right:amber",
 		.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
@@ -334,7 +336,7 @@ static struct orion5x_mpp_mode dns323_mv
 	{  0, MPP_UNUSED },
 	{  1, MPP_GPIO },		/* right amber LED (sata ch0) */
 	{  2, MPP_GPIO },		/* left amber LED (sata ch1) */
-	{  3, MPP_UNUSED },
+	{  3, MPP_GPIO },		/* system up flag */
 	{  4, MPP_GPIO },		/* power button LED */
 	{  5, MPP_GPIO },		/* power button LED */
 	{  6, MPP_GPIO },		/* GMT G751-2f overtemp */
@@ -372,13 +374,23 @@ static struct i2c_board_info __initdata
 	},
 };
 
-/* DNS-323 specific power off method */
-static void dns323_power_off(void)
+/* DNS-323 rev. A specific power off method */
+static void dns323a_power_off(void)
 {
 	pr_info("%s: triggering power-off...\n", __func__);
 	gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
 }
 
+/* DNS-323 rev B specific power off method */
+static void dns323b_power_off(void)
+{
+	pr_info("%s: triggering power-off...\n", __func__);
+	/* Pin has to be changed to 1 and back to 0 to do actual power off. */
+	gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+	mdelay(100);
+	gpio_set_value(DNS323_GPIO_POWER_OFF, 0);
+}
+
 static void __init dns323_init(void)
 {
 	/* Setup basic Orion functions. Need to be called early. */
@@ -424,11 +436,20 @@ static void __init dns323_init(void)
 	if (dns323_dev_id() == MV88F5182_DEV_ID)
 		orion5x_sata_init(&dns323_sata_data);
 
-	/* register dns323 specific power-off method */
+	/* The 5182 has flag to indicate the system is up. Without this flag
+	 * set, power LED will flash and cannot be controlled via leds-gpio.
+	 */
+	if (dns323_dev_id() == MV88F5182_DEV_ID)
+		gpio_set_value(DNS323_GPIO_SYSTEM_UP, 1);
+
+	/* Register dns323 specific power-off method */
 	if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
 	    gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
 		pr_err("DNS323: failed to setup power-off GPIO\n");
-	pm_power_off = dns323_power_off;
+	if (dns323_dev_id() == MV88F5182_DEV_ID)
+		pm_power_off = dns323b_power_off;
+	else
+		pm_power_off = dns323a_power_off;
 }
 
 /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/pci.c linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/pci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -463,7 +463,7 @@ static void __init orion5x_setup_pci_win
 	writel(win_enable, PCI_BAR_ENABLE);
 
 	/*
-	 * Disable automatic update of address remaping when writing to BARs.
+	 * Disable automatic update of address remapping when writing to BARs.
 	 */
 	orion5x_setbits(PCI_ADDR_DECODE_CTRL, 1);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,9 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
@@ -24,6 +27,80 @@
 #include "common.h"
 #include "mpp.h"
 
+/*
+ * LEDs attached to GPIO
+ */
+static struct gpio_led wrt350n_v2_led_pins[] = {
+	{
+		.name		= "wrt350nv2:green:power",
+		.gpio		= 0,
+		.active_low	= 1,
+	}, {
+		.name		= "wrt350nv2:green:security",
+		.gpio		= 1,
+		.active_low	= 1,
+	}, {
+		.name		= "wrt350nv2:orange:power",
+		.gpio		= 5,
+		.active_low	= 1,
+	}, {
+		.name		= "wrt350nv2:green:usb",
+		.gpio		= 6,
+		.active_low	= 1,
+	}, {
+		.name		= "wrt350nv2:green:wireless",
+		.gpio		= 7,
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_led_platform_data wrt350n_v2_led_data = {
+	.leds		= wrt350n_v2_led_pins,
+	.num_leds	= ARRAY_SIZE(wrt350n_v2_led_pins),
+};
+
+static struct platform_device wrt350n_v2_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &wrt350n_v2_led_data,
+	},
+};
+
+/*
+ * Buttons attached to GPIO
+ */
+static struct gpio_keys_button wrt350n_v2_buttons[] = {
+	{
+		.code		= KEY_RESTART,
+		.gpio		= 3,
+		.desc		= "Reset Button",
+		.active_low	= 1,
+	}, {
+		.code		= KEY_WLAN,
+		.gpio		= 2,
+		.desc		= "WPS Button",
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data wrt350n_v2_button_data = {
+	.buttons	= wrt350n_v2_buttons,
+	.nbuttons	= ARRAY_SIZE(wrt350n_v2_buttons),
+};
+
+static struct platform_device wrt350n_v2_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &wrt350n_v2_button_data,
+	},
+};
+
+/*
+ * General setup
+ */
 static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = {
 	{  0, MPP_GPIO },		/* Power LED green (0=on) */
 	{  1, MPP_GPIO },		/* Security LED (0=on) */
@@ -140,6 +217,8 @@ static void __init wrt350n_v2_init(void)
 	orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
 				   WRT350N_V2_NOR_BOOT_SIZE);
 	platform_device_register(&wrt350n_v2_nor_flash);
+	platform_device_register(&wrt350n_v2_leds);
+	platform_device_register(&wrt350n_v2_button_device);
 }
 
 static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/balloon3.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/balloon3.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/balloon3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/balloon3.c	2010-02-24 13:52:17.000000000 -0500
@@ -306,6 +306,10 @@ static void __init balloon3_init(void)
 	 */
 	ARB_CNTRL = ARB_CORE_PARK | 0x234;
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 	if (balloon3_has(BALLOON3_FEATURE_AUDIO))
 		pxa_set_ac97_info(NULL);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/cm-x2xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x2xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/cm-x2xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x2xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -453,6 +453,10 @@ static inline void cmx2xx_init_ac97(void
 
 static void __init cmx2xx_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	cmx2xx_pm_init();
 
 	if (cpu_is_pxa25x())
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/cm-x300.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x300.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/cm-x300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/cm-x300.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,9 +3,10 @@
  *
  * Support for the CompuLab CM-X300 modules
  *
- * Copyright (C) 2008 CompuLab Ltd.
+ * Copyright (C) 2008,2009 CompuLab Ltd.
  *
  * Mike Rapoport <mike@compulab.co.il>
+ * Igor Grinberg <grinberg@compulab.co.il>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -16,30 +17,41 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 
 #include <linux/gpio.h>
 #include <linux/dm9000.h>
 #include <linux/leds.h>
 #include <linux/rtc-v3020.h>
+#include <linux/pwm_backlight.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 
+#include <linux/mfd/da903x.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/spi/tdo24m.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/setup.h>
 
 #include <mach/pxa300.h>
+#include <mach/pxa27x-udc.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
 #include <plat/i2c.h>
-#include <mach/pxa3xx_nand.h>
+#include <plat/pxa3xx_nand.h>
+#include <mach/audio.h>
 
 #include <asm/mach/map.h>
 
 #include "generic.h"
+#include "devices.h"
 
 #define CM_X300_ETH_PHYS	0x08000010
 
@@ -53,7 +65,7 @@
 #define GPIO97_RTC_RD		(97)
 #define GPIO98_RTC_IO		(98)
 
-static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = {
+static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
 	/* LCD */
 	GPIO54_LCD_LDD_0,
 	GPIO55_LCD_LDD_1,
@@ -137,7 +149,6 @@ static mfp_cfg_t cm_x300_mfp_cfg[] __ini
 	GPIO36_UART1_DTR,
 
 	/* GPIOs */
-	GPIO79_GPIO,			/* LED */
 	GPIO82_GPIO | MFP_PULL_HIGH,	/* MMC CD */
 	GPIO85_GPIO,			/* MMC WP */
 	GPIO99_GPIO,			/* Ethernet IRQ */
@@ -151,6 +162,50 @@ static mfp_cfg_t cm_x300_mfp_cfg[] __ini
 	/* Standard I2C */
 	GPIO21_I2C_SCL,
 	GPIO22_I2C_SDA,
+
+	/* PWM Backlight */
+	GPIO19_PWM2_OUT,
+};
+
+static mfp_cfg_t cm_x3xx_rev_lt130_mfp_cfg[] __initdata = {
+	/* GPIOs */
+	GPIO79_GPIO,			/* LED */
+	GPIO77_GPIO,			/* WiFi reset */
+	GPIO78_GPIO,			/* BT reset */
+};
+
+static mfp_cfg_t cm_x3xx_rev_ge130_mfp_cfg[] __initdata = {
+	/* GPIOs */
+	GPIO76_GPIO,			/* LED */
+	GPIO71_GPIO,			/* WiFi reset */
+	GPIO70_GPIO,			/* BT reset */
+};
+
+static mfp_cfg_t cm_x310_mfp_cfg[] __initdata = {
+	/* USB PORT 2 */
+	ULPI_STP,
+	ULPI_NXT,
+	ULPI_DIR,
+	GPIO30_ULPI_DATA_OUT_0,
+	GPIO31_ULPI_DATA_OUT_1,
+	GPIO32_ULPI_DATA_OUT_2,
+	GPIO33_ULPI_DATA_OUT_3,
+	GPIO34_ULPI_DATA_OUT_4,
+	GPIO35_ULPI_DATA_OUT_5,
+	GPIO36_ULPI_DATA_OUT_6,
+	GPIO37_ULPI_DATA_OUT_7,
+	GPIO38_ULPI_CLK,
+	/* external PHY reset pin */
+	GPIO127_GPIO,
+
+	/* USB PORT 3 */
+	GPIO77_USB_P3_1,
+	GPIO78_USB_P3_2,
+	GPIO79_USB_P3_3,
+	GPIO80_USB_P3_4,
+	GPIO81_USB_P3_5,
+	GPIO82_USB_P3_6,
+	GPIO0_2_USBH_PEN,
 };
 
 #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
@@ -195,17 +250,18 @@ static void __init cm_x300_init_dm9000(v
 static inline void cm_x300_init_dm9000(void) {}
 #endif
 
+/* LCD */
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 static struct pxafb_mode_info cm_x300_lcd_modes[] = {
 	[0] = {
-		.pixclock	= 38000,
+		.pixclock	= 38250,
 		.bpp		= 16,
 		.xres		= 480,
 		.yres		= 640,
 		.hsync_len	= 8,
 		.vsync_len	= 2,
 		.left_margin	= 8,
-		.upper_margin	= 0,
+		.upper_margin	= 2,
 		.right_margin	= 24,
 		.lower_margin	= 4,
 		.cmap_greyscale	= 0,
@@ -227,7 +283,7 @@ static struct pxafb_mode_info cm_x300_lc
 
 static struct pxafb_mach_info cm_x300_lcd = {
 	.modes			= cm_x300_lcd_modes,
-	.num_modes		= 2,
+	.num_modes		= ARRAY_SIZE(cm_x300_lcd_modes),
 	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 };
 
@@ -239,6 +295,87 @@ static void __init cm_x300_init_lcd(void
 static inline void cm_x300_init_lcd(void) {}
 #endif
 
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct platform_pwm_backlight_data cm_x300_backlight_data = {
+	.pwm_id		= 2,
+	.max_brightness	= 100,
+	.dft_brightness	= 100,
+	.pwm_period_ns	= 10000,
+};
+
+static struct platform_device cm_x300_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent = &pxa27x_device_pwm0.dev,
+		.platform_data	= &cm_x300_backlight_data,
+	},
+};
+
+static void cm_x300_init_bl(void)
+{
+	platform_device_register(&cm_x300_backlight_device);
+}
+#else
+static inline void cm_x300_init_bl(void) {}
+#endif
+
+#if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE)
+#define GPIO_LCD_BASE	(144)
+#define GPIO_LCD_DIN	(GPIO_LCD_BASE + 8)	/* aux_gpio3_0 */
+#define GPIO_LCD_DOUT	(GPIO_LCD_BASE + 9)	/* aux_gpio3_1 */
+#define GPIO_LCD_SCL	(GPIO_LCD_BASE + 10)	/* aux_gpio3_2 */
+#define GPIO_LCD_CS	(GPIO_LCD_BASE + 11)	/* aux_gpio3_3 */
+#define LCD_SPI_BUS_NUM	(1)
+
+static struct spi_gpio_platform_data cm_x300_spi_gpio_pdata = {
+	.sck		= GPIO_LCD_SCL,
+	.mosi		= GPIO_LCD_DIN,
+	.miso		= GPIO_LCD_DOUT,
+	.num_chipselect	= 1,
+};
+
+static struct platform_device cm_x300_spi_gpio = {
+	.name		= "spi_gpio",
+	.id		= LCD_SPI_BUS_NUM,
+	.dev		= {
+		.platform_data	= &cm_x300_spi_gpio_pdata,
+	},
+};
+
+static struct tdo24m_platform_data cm_x300_tdo24m_pdata = {
+	.model = TDO35S,
+};
+
+static struct spi_board_info cm_x300_spi_devices[] __initdata = {
+	{
+		.modalias		= "tdo24m",
+		.max_speed_hz		= 1000000,
+		.bus_num		= LCD_SPI_BUS_NUM,
+		.chip_select		= 0,
+		.controller_data	= (void *) GPIO_LCD_CS,
+		.platform_data		= &cm_x300_tdo24m_pdata,
+	},
+};
+
+static void __init cm_x300_init_spi(void)
+{
+	spi_register_board_info(cm_x300_spi_devices,
+				ARRAY_SIZE(cm_x300_spi_devices));
+	platform_device_register(&cm_x300_spi_gpio);
+}
+#else
+static inline void cm_x300_init_spi(void) {}
+#endif
+
+#if defined(CONFIG_SND_PXA2XX_LIB_AC97)
+static void __init cm_x300_init_ac97(void)
+{
+	pxa_set_ac97_info(NULL);
+}
+#else
+static inline void cm_x300_init_ac97(void) {}
+#endif
+
 #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
 static struct mtd_partition cm_x300_nand_partitions[] = {
 	[0] = {
@@ -333,9 +470,19 @@ static inline void cm_x300_init_mmc(void
 #endif
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int cm_x300_ohci_init(struct device *dev)
+{
+	if (cpu_is_pxa300())
+		UP2OCR = UP2OCR_HXS
+			| UP2OCR_HXOE | UP2OCR_DMPDE | UP2OCR_DPPDE;
+
+	return 0;
+}
+
 static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
+	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW,
+	.init		= cm_x300_ohci_init,
 };
 
 static void __init cm_x300_init_ohci(void)
@@ -351,7 +498,6 @@ static struct gpio_led cm_x300_leds[] =
 	[0] = {
 		.name = "cm-x300:green",
 		.default_trigger = "heartbeat",
-		.gpio = 79,
 		.active_low = 1,
 	},
 };
@@ -371,6 +517,11 @@ static struct platform_device cm_x300_le
 
 static void __init cm_x300_init_leds(void)
 {
+	if (system_rev < 130)
+		cm_x300_leds[0].gpio = 79;
+	else
+		cm_x300_leds[0].gpio = 76;
+
 	platform_device_register(&cm_x300_led_device);
 }
 #else
@@ -433,11 +584,94 @@ static void __init cm_x300_init_rtc(void
 static inline void cm_x300_init_rtc(void) {}
 #endif
 
-static void __init cm_x300_init(void)
+/* DA9030 */
+struct da903x_subdev_info cm_x300_da9030_subdevs[] = {
+	{
+		.name = "da903x-backlight",
+		.id = DA9030_ID_WLED,
+	}
+};
+
+static struct da903x_platform_data cm_x300_da9030_info = {
+	.num_subdevs = ARRAY_SIZE(cm_x300_da9030_subdevs),
+	.subdevs = cm_x300_da9030_subdevs,
+};
+
+static struct i2c_board_info cm_x300_pmic_info = {
+	I2C_BOARD_INFO("da9030", 0x49),
+	.irq = IRQ_GPIO(0),
+	.platform_data = &cm_x300_da9030_info,
+};
+
+static struct i2c_pxa_platform_data cm_x300_pwr_i2c_info = {
+	.use_pio = 1,
+};
+
+static void __init cm_x300_init_da9030(void)
+{
+	pxa3xx_set_i2c_power_info(&cm_x300_pwr_i2c_info);
+	i2c_register_board_info(1, &cm_x300_pmic_info, 1);
+}
+
+static void __init cm_x300_init_wi2wi(void)
+{
+	int bt_reset, wlan_en;
+	int err;
+
+	if (system_rev < 130) {
+		wlan_en = 77;
+		bt_reset = 78;
+	} else {
+		wlan_en = 71;
+		bt_reset = 70;
+	}
+
+	/* Libertas and CSR reset */
+	err = gpio_request(wlan_en, "wlan en");
+	if (err) {
+		pr_err("CM-X300: failed to request wlan en gpio: %d\n", err);
+	} else {
+		gpio_direction_output(wlan_en, 1);
+		gpio_free(wlan_en);
+	}
+
+	err = gpio_request(bt_reset, "bt reset");
+	if (err) {
+		pr_err("CM-X300: failed to request bt reset gpio: %d\n", err);
+	} else {
+		gpio_direction_output(bt_reset, 1);
+		udelay(10);
+		gpio_set_value(bt_reset, 0);
+		udelay(10);
+		gpio_set_value(bt_reset, 1);
+		gpio_free(bt_reset);
+	}
+}
+
+/* MFP */
+static void __init cm_x300_init_mfp(void)
 {
 	/* board-processor specific GPIO initialization */
-	pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x300_mfp_cfg));
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_mfp_cfg));
+
+	if (system_rev < 130)
+		pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_lt130_mfp_cfg));
+	else
+		pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_ge130_mfp_cfg));
+
+	if (cpu_is_pxa310())
+		pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x310_mfp_cfg));
+}
+
+static void __init cm_x300_init(void)
+{
+	cm_x300_init_mfp();
+
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 
+	cm_x300_init_da9030();
 	cm_x300_init_dm9000();
 	cm_x300_init_lcd();
 	cm_x300_init_ohci();
@@ -445,7 +679,11 @@ static void __init cm_x300_init(void)
 	cm_x300_init_nand();
 	cm_x300_init_leds();
 	cm_x300_init_i2c();
+	cm_x300_init_spi();
 	cm_x300_init_rtc();
+	cm_x300_init_ac97();
+	cm_x300_init_wi2wi();
+	cm_x300_init_bl();
 }
 
 static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa270.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa270.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa270.c	2010-02-24 13:52:17.000000000 -0500
@@ -130,6 +130,9 @@ static struct platform_device *colibri_p
 static void __init colibri_pxa270_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	platform_add_devices(ARRAY_AND_SIZE(colibri_pxa270_devices));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa300.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa300.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa300.c	2010-02-24 13:52:17.000000000 -0500
@@ -170,6 +170,10 @@ static inline void colibri_pxa310_init_a
 
 void __init colibri_pxa300_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	colibri_pxa300_init_eth();
 	colibri_pxa300_init_ohci();
 	colibri_pxa3xx_init_nand();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa320.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa320.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa320.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa320.c	2010-02-24 13:52:17.000000000 -0500
@@ -199,6 +199,10 @@ static void __init colibri_pxa320_init_u
 
 void __init colibri_pxa320_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	colibri_pxa320_init_eth();
 	colibri_pxa320_init_ohci();
 	colibri_pxa3xx_init_nand();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,7 +25,7 @@
 #include <mach/colibri.h>
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
-#include <mach/pxa3xx_nand.h>
+#include <plat/pxa3xx_nand.h>
 
 #include "generic.h"
 #include "devices.h"
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/corgi.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/corgi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi.c	2010-02-24 13:52:17.000000000 -0500
@@ -457,6 +457,7 @@ static struct pxaficp_platform_data corg
  * USB Device Controller
  */
 static struct pxa2xx_udc_mach_info udc_info __initdata = {
+	.gpio_vbus		= -1,
 	/* no connect GPIO; corgi can't tell connection status */
 	.gpio_pullup		= CORGI_GPIO_USB_PULLUP,
 };
@@ -671,6 +672,10 @@ static void __init corgi_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	corgi_init_spi();
 
  	pxa_set_udc_info(&udc_info);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/corgi_pm.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi_pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/corgi_pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/corgi_pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,8 +214,8 @@ static struct sharpsl_charger_machinfo c
 	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
 	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
 	.bat_levels       = 40,
-	.bat_levels_noac  = spitz_battery_levels_noac,
-	.bat_levels_acin  = spitz_battery_levels_acin,
+	.bat_levels_noac  = sharpsl_battery_levels_noac,
+	.bat_levels_acin  = sharpsl_battery_levels_acin,
 	.status_high_acin = 188,
 	.status_low_acin  = 178,
 	.status_high_noac = 185,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/csb726.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/csb726.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/csb726.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/csb726.c	2010-02-24 13:52:17.000000000 -0500
@@ -268,6 +268,9 @@ static void __init csb726_init(void)
 /*	MSC2 = 0x06697ff4; *//* none/SM501 */
 	MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	pxa_set_i2c_info(NULL);
 	pxa27x_set_i2c_power_info(NULL);
 	pxa_set_mci_info(&csb726_mci);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/devices.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,13 +8,14 @@
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
-#include <plat/i2c.h>
 #include <mach/ohci.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/camera.h>
 #include <mach/audio.h>
-#include <mach/pxa3xx_nand.h>
+#include <mach/hardware.h>
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -167,13 +168,18 @@ static struct resource pxa_resource_ffua
 	}
 };
 
-struct platform_device pxa_device_ffuart= {
+struct platform_device pxa_device_ffuart = {
 	.name		= "pxa2xx-uart",
 	.id		= 0,
 	.resource	= pxa_resource_ffuart,
 	.num_resources	= ARRAY_SIZE(pxa_resource_ffuart),
 };
 
+void __init pxa_set_ffuart_info(void *info)
+{
+	pxa_register_device(&pxa_device_ffuart, info);
+}
+
 static struct resource pxa_resource_btuart[] = {
 	{
 		.start	= 0x40200000,
@@ -193,6 +199,11 @@ struct platform_device pxa_device_btuart
 	.num_resources	= ARRAY_SIZE(pxa_resource_btuart),
 };
 
+void __init pxa_set_btuart_info(void *info)
+{
+	pxa_register_device(&pxa_device_btuart, info);
+}
+
 static struct resource pxa_resource_stuart[] = {
 	{
 		.start	= 0x40700000,
@@ -212,6 +223,11 @@ struct platform_device pxa_device_stuart
 	.num_resources	= ARRAY_SIZE(pxa_resource_stuart),
 };
 
+void __init pxa_set_stuart_info(void *info)
+{
+	pxa_register_device(&pxa_device_stuart, info);
+}
+
 static struct resource pxa_resource_hwuart[] = {
 	{
 		.start	= 0x41600000,
@@ -231,6 +247,14 @@ struct platform_device pxa_device_hwuart
 	.num_resources	= ARRAY_SIZE(pxa_resource_hwuart),
 };
 
+void __init pxa_set_hwuart_info(void *info)
+{
+	if (cpu_is_pxa255())
+		pxa_register_device(&pxa_device_hwuart, info);
+	else
+		pr_info("UART: Ignoring attempt to register HWUART on non-PXA255 hardware");
+}
+
 static struct resource pxai2c_resources[] = {
 	{
 		.start	= 0x40301680,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e330.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e330.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e330.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e330.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,6 +55,9 @@ static struct platform_device *devices[]
 
 static void __init e330_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e350.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e350.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e350.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e350.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,9 @@ static struct platform_device *devices[]
 
 static void __init e350_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e400.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e400.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e400.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e400.c	2010-02-24 13:52:17.000000000 -0500
@@ -130,6 +130,9 @@ static struct platform_device *devices[]
 static void __init e400_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	/* Fixme - e400 may have a switched clock */
 	eseries_register_clks();
 	eseries_get_tmio_gpios();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e740.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e740.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e740.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e740.c	2010-02-24 13:52:17.000000000 -0500
@@ -192,6 +192,9 @@ static struct platform_device *devices[]
 static void __init e740_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	eseries_register_clks();
 	clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
 			"UDCCLK", &pxa25x_device_udc.dev),
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e750.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e750.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e750.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e750.c	2010-02-24 13:52:17.000000000 -0500
@@ -194,6 +194,9 @@ static struct platform_device *devices[]
 static void __init e750_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e800.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e800.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/e800.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/e800.c	2010-02-24 13:52:17.000000000 -0500
@@ -195,6 +195,9 @@ static struct platform_device *devices[]
 
 static void __init e800_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/em-x270.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/em-x270.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/em-x270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/em-x270.c	2010-02-24 13:52:17.000000000 -0500
@@ -497,16 +497,15 @@ static int em_x270_usb_hub_init(void)
 		goto err_free_vbus_gpio;
 
 	/* USB Hub power-on and reset */
-	gpio_direction_output(usb_hub_reset, 0);
+	gpio_direction_output(usb_hub_reset, 1);
+	gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
 	regulator_enable(em_x270_usb_ldo);
-	gpio_set_value(usb_hub_reset, 1);
 	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);
-	gpio_set_value(usb_hub_reset, 1);
-
-	/* enable VBUS */
-	gpio_direction_output(GPIO9_USB_VBUS_EN, 1);
+	gpio_set_value(usb_hub_reset, 0);
+	gpio_set_value(GPIO9_USB_VBUS_EN, 1);
 
 	return 0;
 
@@ -967,7 +966,7 @@ static inline void em_x270_init_gpio_key
 #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
 static struct regulator *em_x270_camera_ldo;
 
-static int em_x270_sensor_init(struct device *dev)
+static int em_x270_sensor_init(void)
 {
 	int ret;
 
@@ -996,7 +995,6 @@ static int em_x270_sensor_init(struct de
 }
 
 struct pxacamera_platform_data em_x270_camera_platform_data = {
-	.init	= em_x270_sensor_init,
 	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
 		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
 	.mclk_10khz = 2600,
@@ -1049,8 +1047,10 @@ static struct platform_device em_x270_ca
 
 static void  __init em_x270_init_camera(void)
 {
-	pxa_set_camera_info(&em_x270_camera_platform_data);
-	platform_device_register(&em_x270_camera);
+	if (em_x270_sensor_init() == 0) {
+		pxa_set_camera_info(&em_x270_camera_platform_data);
+		platform_device_register(&em_x270_camera);
+	}
 }
 #else
 static inline void em_x270_init_camera(void) {}
@@ -1286,6 +1286,10 @@ static void __init em_x270_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 #ifdef CONFIG_PM
 	pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/ezx.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ezx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/ezx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ezx.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,11 @@
 #include <linux/delay.h>
 #include <linux/pwm_backlight.h>
 #include <linux/input.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
+#include <linux/leds-lp3944.h>
+
+#include <media/soc_camera.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -29,6 +33,7 @@
 #include <plat/i2c.h>
 #include <mach/hardware.h>
 #include <mach/pxa27x_keypad.h>
+#include <mach/camera.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -38,6 +43,9 @@
 #define GPIO15_A910_FLIP_LID 		15
 #define GPIO12_E680_LOCK_SWITCH 	12
 #define GPIO15_E6_LOCK_SWITCH 		15
+#define GPIO50_nCAM_EN			50
+#define GPIO19_GEN1_CAM_RST		19
+#define GPIO28_GEN2_CAM_RST		28
 
 static struct platform_pwm_backlight_data ezx_backlight_data = {
 	.pwm_id		= 0,
@@ -191,8 +199,8 @@ static unsigned long gen1_pin_config[] _
 	GPIO94_CIF_DD_5,
 	GPIO17_CIF_DD_6,
 	GPIO108_CIF_DD_7,
-	GPIO50_GPIO,				/* CAM_EN */
-	GPIO19_GPIO,				/* CAM_RST */
+	GPIO50_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_EN */
+	GPIO19_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_RST */
 
 	/* EMU */
 	GPIO120_GPIO,				/* EMU_MUX1 */
@@ -248,8 +256,8 @@ static unsigned long gen2_pin_config[] _
 	GPIO48_CIF_DD_5,
 	GPIO93_CIF_DD_6,
 	GPIO12_CIF_DD_7,
-	GPIO50_GPIO,				/* CAM_EN */
-	GPIO28_GPIO,				/* CAM_RST */
+	GPIO50_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_EN */
+	GPIO28_GPIO | MFP_LPM_DRIVE_HIGH,	/* CAM_RST */
 	GPIO17_GPIO,				/* CAM_FLASH */
 };
 #endif
@@ -683,6 +691,81 @@ static struct platform_device a780_gpio_
 	},
 };
 
+/* camera */
+static int a780_camera_init(void)
+{
+	int err;
+
+	/*
+	 * GPIO50_nCAM_EN is active low
+	 * GPIO19_GEN1_CAM_RST is active on rising edge
+	 */
+	err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
+	if (err) {
+		pr_err("%s: Failed to request nCAM_EN\n", __func__);
+		goto fail;
+	}
+
+	err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST");
+	if (err) {
+		pr_err("%s: Failed to request CAM_RST\n", __func__);
+		goto fail_gpio_cam_rst;
+	}
+
+	gpio_direction_output(GPIO50_nCAM_EN, 1);
+	gpio_direction_output(GPIO19_GEN1_CAM_RST, 0);
+
+	return 0;
+
+fail_gpio_cam_rst:
+	gpio_free(GPIO50_nCAM_EN);
+fail:
+	return err;
+}
+
+static int a780_camera_power(struct device *dev, int on)
+{
+	gpio_set_value(GPIO50_nCAM_EN, !on);
+	return 0;
+}
+
+static int a780_camera_reset(struct device *dev)
+{
+	gpio_set_value(GPIO19_GEN1_CAM_RST, 0);
+	msleep(10);
+	gpio_set_value(GPIO19_GEN1_CAM_RST, 1);
+
+	return 0;
+}
+
+struct pxacamera_platform_data a780_pxacamera_platform_data = {
+	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz = 5000,
+};
+
+static struct i2c_board_info a780_camera_i2c_board_info = {
+	I2C_BOARD_INFO("mt9m111", 0x5d),
+};
+
+static struct soc_camera_link a780_iclink = {
+	.bus_id         = 0,
+	.flags          = SOCAM_SENSOR_INVERT_PCLK,
+	.i2c_adapter_id = 0,
+	.board_info     = &a780_camera_i2c_board_info,
+	.module_name    = "mt9m111",
+	.power          = a780_camera_power,
+	.reset          = a780_camera_reset,
+};
+
+static struct platform_device a780_camera = {
+	.name   = "soc-camera-pdrv",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &a780_iclink,
+	},
+};
+
 static struct platform_device *a780_devices[] __initdata = {
 	&a780_gpio_keys,
 };
@@ -693,12 +776,21 @@ static void __init a780_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(a780_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 
 	set_pxa_fb_info(&ezx_fb_info_1);
 
 	pxa_set_keypad_info(&a780_keypad_platform_data);
 
+	if (a780_camera_init() == 0) {
+		pxa_set_camera_info(&a780_pxacamera_platform_data);
+		platform_device_register(&a780_camera);
+	}
+
 	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
 	platform_add_devices(ARRAY_AND_SIZE(a780_devices));
 }
@@ -754,6 +846,10 @@ static void __init e680_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e680_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
 
@@ -816,6 +912,10 @@ static void __init a1200_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(a1200_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
 
@@ -864,6 +964,131 @@ static struct platform_device a910_gpio_
 	},
 };
 
+/* camera */
+static int a910_camera_init(void)
+{
+	int err;
+
+	/*
+	 * GPIO50_nCAM_EN is active low
+	 * GPIO28_GEN2_CAM_RST is active on rising edge
+	 */
+	err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
+	if (err) {
+		pr_err("%s: Failed to request nCAM_EN\n", __func__);
+		goto fail;
+	}
+
+	err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST");
+	if (err) {
+		pr_err("%s: Failed to request CAM_RST\n", __func__);
+		goto fail_gpio_cam_rst;
+	}
+
+	gpio_direction_output(GPIO50_nCAM_EN, 1);
+	gpio_direction_output(GPIO28_GEN2_CAM_RST, 0);
+
+	return 0;
+
+fail_gpio_cam_rst:
+	gpio_free(GPIO50_nCAM_EN);
+fail:
+	return err;
+}
+
+static int a910_camera_power(struct device *dev, int on)
+{
+	gpio_set_value(GPIO50_nCAM_EN, !on);
+	return 0;
+}
+
+static int a910_camera_reset(struct device *dev)
+{
+	gpio_set_value(GPIO28_GEN2_CAM_RST, 0);
+	msleep(10);
+	gpio_set_value(GPIO28_GEN2_CAM_RST, 1);
+
+	return 0;
+}
+
+struct pxacamera_platform_data a910_pxacamera_platform_data = {
+	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz = 5000,
+};
+
+static struct i2c_board_info a910_camera_i2c_board_info = {
+	I2C_BOARD_INFO("mt9m111", 0x5d),
+};
+
+static struct soc_camera_link a910_iclink = {
+	.bus_id         = 0,
+	.i2c_adapter_id = 0,
+	.board_info     = &a910_camera_i2c_board_info,
+	.module_name    = "mt9m111",
+	.power          = a910_camera_power,
+	.reset          = a910_camera_reset,
+};
+
+static struct platform_device a910_camera = {
+	.name   = "soc-camera-pdrv",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &a910_iclink,
+	},
+};
+
+/* leds-lp3944 */
+static struct lp3944_platform_data a910_lp3944_leds = {
+	.leds_size = LP3944_LEDS_MAX,
+	.leds = {
+		[0] = {
+			.name = "a910:red:",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED,
+		},
+		[1] = {
+			.name = "a910:green:",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED,
+		},
+		[2] {
+			.name = "a910:blue:",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED,
+		},
+		/* Leds 3 and 4 are used as display power switches */
+		[3] = {
+			.name = "a910::cli_display",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED_INVERTED
+		},
+		[4] = {
+			.name = "a910::main_display",
+			.status = LP3944_LED_STATUS_ON,
+			.type = LP3944_LED_TYPE_LED_INVERTED
+		},
+		[5] = { .type = LP3944_LED_TYPE_NONE },
+		[6] = {
+			.name = "a910::torch",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED,
+		},
+		[7] = {
+			.name = "a910::flash",
+			.status = LP3944_LED_STATUS_OFF,
+			.type = LP3944_LED_TYPE_LED_INVERTED,
+		},
+	},
+};
+
+static struct i2c_board_info __initdata a910_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("lp3944", 0x60),
+		.platform_data = &a910_lp3944_leds,
+	},
+};
+
 static struct platform_device *a910_devices[] __initdata = {
 	&a910_gpio_keys,
 };
@@ -874,12 +1099,22 @@ static void __init a910_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(a910_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
 
 	set_pxa_fb_info(&ezx_fb_info_2);
 
 	pxa_set_keypad_info(&a910_keypad_platform_data);
 
+	if (a910_camera_init() == 0) {
+		pxa_set_camera_info(&a910_pxacamera_platform_data);
+		platform_device_register(&a910_camera);
+	}
+
 	platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
 	platform_add_devices(ARRAY_AND_SIZE(a910_devices));
 }
@@ -935,6 +1170,10 @@ static void __init e6_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e6_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
 
@@ -971,6 +1210,10 @@ static void __init e2_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e2_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/generic.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/generic.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/generic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/generic.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,3 +67,8 @@ extern struct sysdev_class pxa_irq_syscl
 extern struct sysdev_class pxa_gpio_sysclass;
 extern struct sysdev_class pxa2xx_mfp_sysclass;
 extern struct sysdev_class pxa3xx_mfp_sysclass;
+
+void __init pxa_set_ffuart_info(void *info);
+void __init pxa_set_btuart_info(void *info);
+void __init pxa_set_stuart_info(void *info);
+void __init pxa_set_hwuart_info(void *info);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/gumstix.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/gumstix.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/gumstix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/gumstix.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,6 +211,11 @@ static void __init gumstix_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+	pxa_set_hwuart_info(NULL);
+
 	gumstix_bluetooth_init();
 	gumstix_udc_init();
 	gumstix_mmc_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/h5000.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/h5000.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/h5000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/h5000.c	2010-02-24 13:52:17.000000000 -0500
@@ -193,6 +193,9 @@ static void __init h5000_init(void)
 	fix_msc();
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(h5000_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	pxa_set_udc_info(&h5000_udc_mach_info);
 	platform_add_devices(ARRAY_AND_SIZE(devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/himalaya.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/himalaya.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/himalaya.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/himalaya.c	2010-02-24 13:52:17.000000000 -0500
@@ -150,6 +150,9 @@ static void __init himalaya_lcd_init(voi
 
 static void __init himalaya_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	himalaya_lcd_init();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/hx4700.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/hx4700.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/hx4700.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/hx4700.c	2010-02-24 13:52:17.000000000 -0500
@@ -820,6 +820,7 @@ static struct platform_device *devices[]
 	&gpio_keys,
 	&backlight,
 	&w3220,
+	&hx4700_lcd,
 	&egpio,
 	&bq24022,
 	&gpio_vbus,
@@ -849,6 +850,10 @@ static void __init hx4700_init(void)
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config));
 	hx4700_gpio_request(ARRAY_AND_SIZE(global_gpios));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	pxa_set_ficp_info(&ficp_info);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/idp.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/idp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/idp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/idp.c	2010-02-24 13:52:17.000000000 -0500
@@ -179,6 +179,9 @@ static void __init idp_init(void)
 	printk("idp_init()\n");
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 
 	platform_device_register(&smc91x_device);
 	//platform_device_register(&mst_audio_device);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/imote2.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/imote2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/imote2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/imote2.c	2010-02-24 13:52:17.000000000 -0500
@@ -554,8 +554,12 @@ static struct i2c_pxa_platform_data i2c_
 
 static void __init imote2_init(void)
 {
-
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config));
+
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	/* SPI chip select directions - all other directions should
 	 * be handled by drivers.*/
 	gpio_direction_output(37, 0);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,11 @@
+#ifndef __ARCOM_PCMCIA_H
+#define __ARCOM_PCMCIA_H
+
+struct arcom_pcmcia_pdata {
+	int	cd_gpio;
+	int	rdy_gpio;
+	int	pwr_gpio;
+	void	(*reset)(int state);
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/hardware.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -105,6 +105,7 @@
  *
  *  PXA935	A0	0x56056931	0x1E653013
  *  PXA935	B0	0x56056936	0x6E653013
+ *  PXA935	B1	0x56056938	0x8E653013
  */
 #ifdef CONFIG_PXA25x
 #define __cpu_is_pxa210(id)				\
@@ -249,20 +250,17 @@
 
 #define cpu_is_pxa930()					\
 	({						\
-		unsigned int id = read_cpuid(CPUID_ID);	\
-		__cpu_is_pxa930(id);			\
+		__cpu_is_pxa930(read_cpuid_id());	\
 	 })
 
 #define cpu_is_pxa935()					\
 	({						\
-		unsigned int id = read_cpuid(CPUID_ID);	\
-		__cpu_is_pxa935(id);			\
+		__cpu_is_pxa935(read_cpuid_id());	\
 	 })
 
 #define cpu_is_pxa950()					\
 	({						\
-		unsigned int id = read_cpuid(CPUID_ID);	\
-		__cpu_is_pxa950(id);			\
+		__cpu_is_pxa950(read_cpuid_id());	\
 	 })
 
 
@@ -283,7 +281,7 @@
 		_id == 0x3;				\
 	 })
 
-#define __cpu_is_pxa9xx(id)				\
+#define __cpu_is_pxa93x(id)				\
 	({						\
 		unsigned int _id = (id) >> 4 & 0xfff;	\
 		_id == 0x683 || _id == 0x693;		\
@@ -299,9 +297,9 @@
 		__cpu_is_pxa3xx(read_cpuid_id());	\
 	 })
 
-#define cpu_is_pxa9xx()					\
+#define cpu_is_pxa93x()					\
 	({						\
-		__cpu_is_pxa9xx(read_cpuid_id());	\
+		__cpu_is_pxa93x(read_cpuid_id());	\
 	 })
 /*
  * return current memory and LCD clock frequency in units of 10kHz
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2010-02-24 13:52:17.000000000 -0500
@@ -169,7 +169,6 @@
 #define GPIO86_nSDCS2		MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
 #define GPIO87_nSDCS3		MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
 #define GPIO88_RDnWR		MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
-#define GPIO89_nACRESET		MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
 
 /* USB */
 #define GPIO9_USB_RCV		MFP_CFG_IN(GPIO9, AF1)
@@ -186,6 +185,9 @@
 #define GPIO30_ASSP_TXD		MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
 #define GPIO31_ASSP_SFRM_IN	MFP_CFG_IN(GPIO31, AF1)
 #define GPIO31_ASSP_SFRM_OUT	MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
-#endif
+
+/* AC97 */
+#define GPIO89_AC97_nRESET	MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
+#endif	/* CONFIG_CPU_PXA26x */
 
 #endif /* __ASM_ARCH_MFP_PXA25X_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmld.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmld.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmld.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmld.h	2010-02-24 13:52:17.000000000 -0500
@@ -91,7 +91,7 @@
 /* BATTERY */
 #define PALMLD_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
 #define PALMLD_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
-#define PALMLD_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMLD_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMLD_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMLD_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMLD_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@
 /* BATTERY */
 #define PALMT5_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMT5_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMT5_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMT5_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMT5_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMT5_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMT5_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtc.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtc.h	2010-02-24 13:52:17.000000000 -0500
@@ -68,7 +68,7 @@
 /* BATTERY */
 #define PALMTC_BAT_MAX_VOLTAGE		4000	/* 4.00V maximum voltage */
 #define PALMTC_BAT_MIN_VOLTAGE		3550	/* 3.55V critical voltage */
-#define PALMTC_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTC_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTC_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTC_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTC_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@
 /* BATTERY */
 #define PALMTE2_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMTE2_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMTE2_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTE2_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTE2_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTE2_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTE2_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtreo.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtreo.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtreo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtreo.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,67 @@
+/*
+ * GPIOs and interrupts for Palm Treo smartphones
+ *
+ * currently supported:
+ *     Palm Treo 680 (GSM)
+ *     Palm Centro 685 (GSM)
+ *
+ * Author:     Tomas Cech <sleep_walker@suse.cz>
+ *
+ * This 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.
+ *
+ * find more info at www.hackndev.com
+ *
+ */
+
+#ifndef _INCLUDE_TREO_H_
+#define _INCLUDE_TREO_H_
+
+/* GPIOs */
+#define GPIO_NR_TREO_POWER_DETECT	0
+#define GPIO_NR_TREO_AMP_EN		27
+#define GPIO_NR_TREO_GREEN_LED	20
+#define GPIO_NR_TREO_RED_LED		79
+#define GPIO_NR_TREO_SD_DETECT_N	113
+#define GPIO_NR_TREO_EP_DETECT_N	116
+#define GPIO_NR_TREO_USB_DETECT	1
+#define GPIO_NR_TREO_USB_PULLUP	114
+#define GPIO_NR_TREO_GSM_POWER	40
+#define GPIO_NR_TREO_GSM_RESET	87
+#define GPIO_NR_TREO_GSM_WAKE	57
+#define GPIO_NR_TREO_GSM_HOST_WAKE	14
+#define GPIO_NR_TREO_GSM_TRIGGER	10
+#define GPIO_NR_TREO_IR_EN		115
+#define GPIO_NR_TREO_IR_TXD		47
+#define GPIO_NR_TREO_BL_POWER	38
+#define GPIO_NR_TREO_LCD_POWER	25
+
+/* Treo680 specific GPIOs */
+#ifdef CONFIG_MACH_TREO680
+#define GPIO_NR_TREO680_SD_READONLY	33
+#define GPIO_NR_TREO680_SD_POWER	42
+#define GPIO_NR_TREO680_VIBRATE_EN	44
+#define GPIO_NR_TREO680_KEYB_BL		24
+#define GPIO_NR_TREO680_BT_EN		43
+#endif /* CONFIG_MACH_TREO680 */
+
+/* Centro685 specific GPIOs */
+#define GPIO_NR_CENTRO_SD_POWER		21
+#define GPIO_NR_CENTRO_VIBRATE_EN	22
+#define GPIO_NR_CENTRO_KEYB_BL		33
+#define GPIO_NR_CENTRO_BT_EN		80
+
+/* Various addresses  */
+#define TREO_PHYS_RAM_START	0xa0000000
+#define TREO_PHYS_IO_START	0x40000000
+#define TREO_STR_BASE	0xa2000000
+
+/* BACKLIGHT */
+#define TREO_MAX_INTENSITY		254
+#define TREO_DEFAULT_INTENSITY	160
+#define TREO_LIMIT_MASK		0x7F
+#define TREO_PRESCALER		63
+#define TREO_PERIOD_NS		3500
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h	2010-02-24 13:52:17.000000000 -0500
@@ -94,7 +94,7 @@
 /* BATTERY */
 #define PALMTX_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMTX_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMTX_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMTX_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMTX_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMTX_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMTX_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmz72.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmz72.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/palmz72.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/palmz72.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,7 @@
 /* Battery */
 #define PALMZ72_BAT_MAX_VOLTAGE		4000	/* 4.00v current voltage */
 #define PALMZ72_BAT_MIN_VOLTAGE		3550	/* 3.55v critical voltage */
-#define PALMZ72_BAT_MAX_CURRENT		0	/* unknokn */
+#define PALMZ72_BAT_MAX_CURRENT		0	/* unknown */
 #define PALMZ72_BAT_MIN_CURRENT		0	/* unknown */
 #define PALMZ72_BAT_MAX_CHARGE		1	/* unknown */
 #define PALMZ72_BAT_MIN_CHARGE		1	/* unknown */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-#ifndef __ASM_ARCH_PXA3XX_NAND_H
-#define __ASM_ARCH_PXA3XX_NAND_H
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-struct pxa3xx_nand_timing {
-	unsigned int	tCH;  /* Enable signal hold time */
-	unsigned int	tCS;  /* Enable signal setup time */
-	unsigned int	tWH;  /* ND_nWE high duration */
-	unsigned int	tWP;  /* ND_nWE pulse time */
-	unsigned int	tRH;  /* ND_nRE high duration */
-	unsigned int	tRP;  /* ND_nRE pulse width */
-	unsigned int	tR;   /* ND_nWE high to ND_nRE low for read */
-	unsigned int	tWHR; /* ND_nWE high to ND_nRE low for status read */
-	unsigned int	tAR;  /* ND_ALE low to ND_nRE low delay */
-};
-
-struct pxa3xx_nand_cmdset {
-	uint16_t	read1;
-	uint16_t	read2;
-	uint16_t	program;
-	uint16_t	read_status;
-	uint16_t	read_id;
-	uint16_t	erase;
-	uint16_t	reset;
-	uint16_t	lock;
-	uint16_t	unlock;
-	uint16_t	lock_status;
-};
-
-struct pxa3xx_nand_flash {
-	const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
-	const struct pxa3xx_nand_cmdset *cmdset;
-
-	uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
-	uint32_t page_size;	/* Page size in bytes (PAGE_SZ) */
-	uint32_t flash_width;	/* Width of Flash memory (DWIDTH_M) */
-	uint32_t dfc_width;	/* Width of flash controller(DWIDTH_C) */
-	uint32_t num_blocks;	/* Number of physical blocks in Flash */
-	uint32_t chip_id;
-};
-
-struct pxa3xx_nand_platform_data {
-
-	/* the data flash bus is shared between the Static Memory
-	 * Controller and the Data Flash Controller,  the arbiter
-	 * controls the ownership of the bus
-	 */
-	int	enable_arbiter;
-
-	/* allow platform code to keep OBM/bootloader defined NFC config */
-	int	keep_config;
-
-	const struct mtd_partition		*parts;
-	unsigned int				nr_parts;
-
-	const struct pxa3xx_nand_flash * 	flash;
-	size_t					num_flash;
-};
-
-extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
-#endif /* __ASM_ARCH_PXA3XX_NAND_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/pxafb.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pxafb.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/pxafb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/pxafb.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,7 +76,8 @@ struct pxafb_mode_info {
 	u_char		bpp;
 	u_int		cmap_greyscale:1,
 			depth:8,
-			unused:23;
+			transparency:1,
+			unused:22;
 
 	/* Parallel Mode Timing */
 	u_char		hsync_len;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/regs-u2d.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,199 @@
+#ifndef __ASM_ARCH_PXA3xx_U2D_H
+#define __ASM_ARCH_PXA3xx_U2D_H
+
+#include <mach/bitfield.h>
+
+/*
+ * USB2 device controller registers and bits definitions
+ */
+#define U2DCR		(0x0000)	/* U2D Control Register */
+#define U2DCR_NDC	(1   << 31)	/* NAK During Config */
+#define U2DCR_HSTC	(0x7 << 28)	/* High Speed Timeout Calibration */
+#define U2DCR_SPEOREN	(1   << 27)	/* Short Packet EOR INTR generation Enable */
+#define U2DCR_FSTC	(0x7 << 24)	/* Full Speed Timeout Calibration */
+#define U2DCR_UCLKOVR	(1   << 22)	/* UTM Clock Override */
+#define U2DCR_ABP	(1   << 21)	/* Application Bus Power */
+#define U2DCR_ADD	(1   << 20)	/* Application Device Disconnect */
+#define U2DCR_CC	(1   << 19)	/* Configuration Change */
+#define U2DCR_HS	(1   << 18)	/* High Speed USB Detection */
+#define U2DCR_SMAC	(1   << 17)	/* Switch Endpoint Memory to Active Configuration */
+#define U2DCR_DWRE	(1   << 16)	/* Device Remote Wake-up Feature */
+#define U2DCR_ACN	(0xf << 12)	/* Active U2D Configuration Number */
+#define U2DCR_AIN	(0xf << 8)	/* Active U2D Interface Number */
+#define U2DCR_AAISN	(0xf << 4)	/* Active U2D Alternate Interface Setting Number */
+#define U2DCR_EMCE	(1   << 3)	/* Endpoint Memory Configuration Error */
+#define U2DCR_UDR	(1   << 2)	/* U2D Resume */
+#define U2DCR_UDA	(1   << 1)	/* U2D Active */
+#define U2DCR_UDE	(1   << 0)	/* U2D Enable */
+
+#define U2DICR			(0x0004)	/* U2D Interrupt Control Register */
+#define U2DISR			(0x000C)	/* U2D Interrupt Status Register */
+#define U2DINT_CC		(1 << 31)	/* Interrupt - Configuration Change */
+#define U2DINT_SOF		(1 << 30)	/* Interrupt - SOF */
+#define U2DINT_USOF		(1 << 29)	/* Interrupt - micro SOF */
+#define U2DINT_RU		(1 << 28)	/* Interrupt - Resume */
+#define U2DINT_SU		(1 << 27)	/* Interrupt - Suspend */
+#define U2DINT_RS		(1 << 26)	/* Interrupt - Reset */
+#define U2DINT_DPE		(1 << 25)	/* Interrupt - Data Packet Error */
+#define U2DINT_FIFOERR		(0x4)		/* Interrupt - endpoint FIFO error */
+#define U2DINT_PACKETCMP	(0x2)		/* Interrupt - endpoint packet complete */
+#define U2DINT_SPACKETCMP	(0x1)		/* Interrupt - endpoint short packet complete */
+
+#define U2DFNR			(0x0014)	/* U2D Frame Number Register */
+
+#define U2DINT(n, intr)		(((intr) & 0x07) << (((n) & 0x07) * 3))
+#define U2DICR2			(0x0008)	/* U2D Interrupt Control Register 2 */
+#define U2DISR2			(0x0010)	/* U2D Interrupt Status Register 2 */
+
+#define U2DOTGCR		(0x0020)	/* U2D OTG Control Register */
+#define U2DOTGCR_OTGEN		(1 << 31)	/* On-The-Go Enable */
+#define U2DOTGCR_AALTHNP	(1 << 30)	/* A-device Alternate Host Negotiation Protocal Port Support */
+#define U2DOTGCR_AHNP		(1 << 29)	/* A-device Host Negotiation Protocal Support */
+#define U2DOTGCR_BHNP		(1 << 28)	/* B-device Host Negotiation Protocal Enable */
+
+#ifdef CONFIG_CPU_PXA930
+#define U2DOTGCR_LPA		(1 << 15)	/* ULPI low power mode active */
+#define U2DOTGCR_IESI		(1 << 13)	/* OTG interrupt Enable */
+#define U2DOTGCR_ISSI		(1 << 12)	/* OTG interrupt status */
+#endif
+
+#define U2DOTGCR_CKAF	(1 << 5)	/* Carkit Mode Alternate Function Select */
+#define U2DOTGCR_UTMID	(1 << 4)	/* UTMI Interface Disable */
+#define U2DOTGCR_ULAF	(1 << 3)	/* ULPI Mode Alternate Function Select */
+#define U2DOTGCR_SMAF	(1 << 2)	/* Serial Mode Alternate Function Select */
+#define U2DOTGCR_RTSM	(1 << 1)	/* Return to Synchronous Mode (ULPI Mode) */
+#define U2DOTGCR_ULE	(1 << 0)	/* ULPI Wrapper Enable */
+
+#define U2DOTGICR	(0x0024)	/* U2D OTG Interrupt Control Register */
+#define U2DOTGISR	(0x0028)	/* U2D OTG Interrupt Status Register */
+
+#define U2DOTGINT_SF	(1 << 17)	/* OTG Set Feature Command Received */
+#define U2DOTGINT_SI	(1 << 16)	/* OTG Interrupt */
+#define U2DOTGINT_RLS1	(1 << 14)	/* RXCMD Linestate[1] Change Interrupt Rise */
+#define U2DOTGINT_RLS0	(1 << 13)	/* RXCMD Linestate[0] Change Interrupt Rise */
+#define U2DOTGINT_RID	(1 << 12)	/* RXCMD OTG ID Change Interrupt Rise */
+#define U2DOTGINT_RSE	(1 << 11)	/* RXCMD OTG Session End Interrupt Rise */
+#define U2DOTGINT_RSV	(1 << 10)	/* RXCMD OTG Session Valid Interrupt Rise */
+#define U2DOTGINT_RVV	(1 << 9)	/* RXCMD OTG Vbus Valid Interrupt Rise */
+#define U2DOTGINT_RCK	(1 << 8)	/* RXCMD Carkit Interrupt Rise */
+#define U2DOTGINT_FLS1	(1 << 6)	/* RXCMD Linestate[1] Change Interrupt Fall */
+#define U2DOTGINT_FLS0	(1 << 5)	/* RXCMD Linestate[0] Change Interrupt Fall */
+#define U2DOTGINT_FID	(1 << 4)	/* RXCMD OTG ID Change Interrupt Fall */
+#define U2DOTGINT_FSE	(1 << 3)	/* RXCMD OTG Session End Interrupt Fall */
+#define U2DOTGINT_FSV	(1 << 2)	/* RXCMD OTG Session Valid Interrupt Fall */
+#define U2DOTGINT_FVV	(1 << 1)	/* RXCMD OTG Vbus Valid Interrupt Fall */
+#define U2DOTGINT_FCK	(1 << 0)	/* RXCMD Carkit Interrupt Fall */
+
+#define U2DOTGUSR	(0x002C)	/* U2D OTG ULPI Status Register */
+#define U2DOTGUSR_LPA	(1 << 31)	/* ULPI Low Power Mode Active */
+#define U2DOTGUSR_S6A	(1 << 30)	/* ULPI Serial Mode (6-pin) Active */
+#define U2DOTGUSR_S3A	(1 << 29)	/* ULPI Serial Mode (3-pin) Active */
+#define U2DOTGUSR_CKA	(1 << 28)	/* ULPI Car Kit Mode Active */
+#define U2DOTGUSR_LS1	(1 << 6)	/* RXCMD Linestate 1 Status */
+#define U2DOTGUSR_LS0	(1 << 5)	/* RXCMD Linestate 0 Status */
+#define U2DOTGUSR_ID	(1 << 4)	/* OTG IDGnd Status */
+#define U2DOTGUSR_SE	(1 << 3)	/* OTG Session End Status */
+#define U2DOTGUSR_SV	(1 << 2)	/* OTG Session Valid Status */
+#define U2DOTGUSR_VV	(1 << 1)	/* OTG Vbus Valid Status */
+#define U2DOTGUSR_CK	(1 << 0)	/* Carkit Interrupt Status */
+
+#define U2DOTGUCR	(0x0030)	/* U2D OTG ULPI Control Register */
+#define U2DOTGUCR_RUN	(1    << 25)	/* RUN */
+#define U2DOTGUCR_RNW	(1    << 24)	/* Read or Write operation */
+#define U2DOTGUCR_ADDR	(0x3f << 16)	/* Address of the ULPI PHY register */
+#define U2DOTGUCR_WDATA	(0xff << 8)	/* The data for a WRITE command */
+#define U2DOTGUCR_RDATA	(0xff << 0)	/* The data for a READ command */
+
+#define U2DP3CR		(0x0034)	/* U2D Port 3 Control Register */
+#define U2DP3CR_P2SS	(0x3 << 8)	/* Host Port 2 Serial Mode Select */
+#define U2DP3CR_P3SS	(0x7 << 4)	/* Host Port 3 Serial Mode Select */
+#define U2DP3CR_VPVMBEN	(0x1 << 2)	/* Host Port 3 Vp/Vm Block Enable */
+#define U2DP3CR_CFG	(0x3 << 0)	/* Host Port 3 Configuration */
+
+#define U2DCSR0		(0x0100)	/* U2D Control/Status Register - Endpoint 0 */
+#define U2DCSR0_IPA	(1 << 8)	/* IN Packet Adjusted */
+#define U2DCSR0_SA	(1 << 7)	/* SETUP Active */
+#define U2DCSR0_RNE	(1 << 6)	/* Receive FIFO Not Empty */
+#define U2DCSR0_FST	(1 << 5)	/* Force Stall */
+#define U2DCSR0_SST	(1 << 4)	/* Send Stall */
+#define U2DCSR0_DME	(1 << 3)	/* DMA Enable */
+#define U2DCSR0_FTF	(1 << 2)	/* Flush Transmit FIFO */
+#define U2DCSR0_IPR	(1 << 1)	/* IN Packet Ready */
+#define U2DCSR0_OPC	(1 << 0)	/* OUT Packet Complete */
+
+#define U2DCSR(x)	(0x0100 + ((x) << 2))	/* U2D Control/Status Register - Endpoint x */
+#define U2DCSR_BF	(1 << 10)	/* Buffer Full, for OUT eps */
+#define U2DCSR_BE	(1 << 10)	/* Buffer Empty, for IN eps */
+#define U2DCSR_DPE	(1 << 9)	/* Data Packet Error, for ISO eps only */
+#define U2DCSR_FEF	(1 << 8)	/* Flush Endpoint FIFO */
+#define U2DCSR_SP	(1 << 7)	/* Short Packet Control/Status, for OUT eps only, readonly */
+#define U2DCSR_BNE	(1 << 6)	/* Buffer Not Empty, for OUT eps */
+#define U2DCSR_BNF	(1 << 6)	/* Buffer Not Full, for IN eps */
+#define U2DCSR_FST	(1 << 5)	/* Force STALL, write 1 set */
+#define U2DCSR_SST	(1 << 4)	/* Sent STALL, write 1 clear */
+#define U2DCSR_DME	(1 << 3)	/* DMA Enable */
+#define U2DCSR_TRN	(1 << 2)	/* Tx/Rx NAK, write 1 clear */
+#define U2DCSR_PC	(1 << 1)	/* Packet Complete, write 1 clear */
+#define U2DCSR_FS	(1 << 0)	/* FIFO needs Service */
+
+#define U2DBCR0		(0x0200)		/* U2D Byte Count Register - Endpoint 0 */
+#define U2DBCR(x)	(0x0200 + ((x) << 2))	/* U2D Byte Count Register - Endpoint x */
+
+#define U2DDR0		(0x0300)		/* U2D Data Register - Endpoint 0 */
+
+#define U2DEPCR(x)	(0x0400 + ((x) << 2))	/* U2D Configuration Register - Endpoint x */
+#define U2DEPCR_EE	(1 << 0)		/* Endpoint Enable */
+#define U2DEPCR_BS_MASK	(0x3FE)			/* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */
+
+#define U2DSCA		(0x0500)		/* U2D Setup Command Address */
+#define U2DSCA_VALUE	(0x0120)
+
+#define U2DEN0		(0x0504)		/* U2D Endpoint Information Register - Endpoint 0 */
+#define U2DEN(x)	(0x0504 + ((x) << 2))	/* U2D Endpoint Information Register - Endpoint x */
+
+/* U2DMA registers */
+#define U2DMACSR0		(0x1000)	/* U2DMA Control/Status Register - Channel 0 */
+#define U2DMACSR(x)		(0x1000 + ((x) << 2))	/* U2DMA Control/Status Register - Channel x */
+#define U2DMACSR_RUN		(1 << 31)	/* Run Bit (read / write) */
+#define U2DMACSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
+#define U2DMACSR_EORIRQEN	(1 << 28)	/* End of Receive Interrupt Enable (R/W) */
+#define U2DMACSR_EORJMPEN	(1 << 27)	/* Jump to next descriptor on EOR */
+#define U2DMACSR_EORSTOPEN	(1 << 26)	/* STOP on an EOR */
+#define U2DMACSR_RASIRQEN	(1 << 23)	/* Request After Cnannel Stopped Interrupt Enable */
+#define U2DMACSR_MASKRUN	(1 << 22)	/* Mask Run */
+#define U2DMACSR_SCEMC		(3 << 18)	/* System Bus Split Completion Error Message Class */
+#define U2DMACSR_SCEMI		(0x1f << 13)	/* System Bus Split Completion Error Message Index */
+#define U2DMACSR_BUSERRTYPE	(7 << 10)	/* PX Bus Error Type */
+#define U2DMACSR_EORINTR	(1 << 9)	/* End Of Receive */
+#define U2DMACSR_REQPEND	(1 << 8)	/* Request Pending */
+#define U2DMACSR_RASINTR	(1 << 4)	/* Request After Channel Stopped (read / write 1 clear) */#define U2DMACSR_STOPINTR	(1 << 3)	/* Stop Interrupt (read only) */
+#define U2DMACSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write 1 clear) */
+#define U2DMACSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write 1 clear) */
+#define U2DMACSR_BUSERRINTR	(1 << 0)	/* Bus Error Interrupt (read / write 1 clear) */
+
+#define U2DMACR		(0x1080)		/* U2DMA Control Register */
+#define U2DMAINT	(0x10F0)		/* U2DMA Interrupt Register */
+
+#define U2DMABR0	(0x1100)		/* U2DMA Branch Register - Channel 0 */
+#define U2DMABR(x)      (0x1100 + (x) << 2)	/* U2DMA Branch Register - Channel x */
+
+#define U2DMADADR0      (0x1200)		/* U2DMA Descriptor Address Register - Channel 0 */
+#define U2DMADADR(x)    (0x1200 + (x) * 0x10)	/* U2DMA Descriptor Address Register - Channel x */
+
+#define U2DMADADR_STOP	(1U << 0)
+
+#define U2DMASADR0	(0x1204)		/* U2DMA Source Address Register - Channel 0 */
+#define U2DMASADR(x)	(0x1204 + (x) * 0x10)	/* U2DMA Source Address Register - Channel x */
+#define U2DMATADR0	(0x1208)		/* U2DMA Target Address Register - Channel 0 */
+#define U2DMATADR(x)	(0x1208 + (x) * 0x10)	/* U2DMA Target Address Register - Channel x */
+
+#define U2DMACMDR0	(0x120C)		/* U2DMA Command Address Register - Channel 0 */
+#define U2DMACMDR(x)	(0x120C + (x) * 0x10)	/* U2DMA Command Address Register - Channel x */
+
+#define U2DMACMDR_XFRDIS	(1 << 31)	/* Transfer Direction */
+#define U2DMACMDR_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
+#define U2DMACMDR_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
+#define U2DMACMDR_PACKCOMP	(1 << 13)	/* Packet Complete */
+#define U2DMACMDR_LEN		(0x07ff)	/* length mask (max = 2K - 1) */
+
+#endif /* __ASM_ARCH_PXA3xx_U2D_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/treo680.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/treo680.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/treo680.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/treo680.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * GPIOs and interrupts for Palm Treo 680 smartphone
- *
- * This 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 _INCLUDE_TREO680_H_
-#define _INCLUDE_TREO680_H_
-
-/* GPIOs */
-#define GPIO_NR_TREO680_POWER_DETECT	0
-#define GPIO_NR_TREO680_AMP_EN		27
-#define GPIO_NR_TREO680_KEYB_BL		24
-#define GPIO_NR_TREO680_VIBRATE_EN	44
-#define GPIO_NR_TREO680_GREEN_LED	20
-#define GPIO_NR_TREO680_RED_LED		79
-#define GPIO_NR_TREO680_SD_DETECT_N	113
-#define GPIO_NR_TREO680_SD_READONLY	33
-#define GPIO_NR_TREO680_EP_DETECT_N	116
-#define GPIO_NR_TREO680_SD_POWER	42
-#define GPIO_NR_TREO680_USB_DETECT	1
-#define GPIO_NR_TREO680_USB_PULLUP	114
-#define GPIO_NR_TREO680_GSM_POWER	40
-#define GPIO_NR_TREO680_GSM_RESET	87
-#define GPIO_NR_TREO680_GSM_WAKE	57
-#define GPIO_NR_TREO680_GSM_HOST_WAKE	14
-#define GPIO_NR_TREO680_GSM_TRIGGER	10
-#define GPIO_NR_TREO680_BT_EN		43
-#define GPIO_NR_TREO680_IR_EN		115
-#define GPIO_NR_TREO680_IR_TXD		47
-#define GPIO_NR_TREO680_BL_POWER	38
-#define GPIO_NR_TREO680_LCD_POWER	25
-
-/* Various addresses  */
-#define TREO680_PHYS_RAM_START	0xa0000000
-#define TREO680_PHYS_IO_START	0x40000000
-#define TREO680_STR_BASE	0xa2000000
-
-/* BACKLIGHT */
-#define TREO680_MAX_INTENSITY		254
-#define TREO680_DEFAULT_INTENSITY	160
-#define TREO680_LIMIT_MASK		0x7F
-#define TREO680_PRESCALER		63
-#define TREO680_PERIOD_NS		3500
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/viper.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/viper.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/viper.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/viper.h	2010-02-24 13:52:17.000000000 -0500
@@ -85,8 +85,6 @@
 /* Interrupt and Configuration Register (VIPER_ICR) */
 /* This is a write only register. Only CF_RST is used under Linux */
 
-extern void viper_cf_rst(int state);
-
 #define VIPER_ICR_RETRIG	(1 << 0)
 #define VIPER_ICR_AUTO_CLR	(1 << 1)
 #define VIPER_ICR_R_DIS		(1 << 2)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/zeus.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zeus.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/zeus.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zeus.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,82 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/zeus.h
+ *
+ *  Author:	David Vrabel
+ *  Created:	Sept 28, 2005
+ *  Copyright:	Arcom Control Systems Ltd.
+ *
+ *  Maintained by: Marc Zyngier <maz@misterjones.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.
+ */
+
+#ifndef _MACH_ZEUS_H
+#define _MACH_ZEUS_H
+
+/* Physical addresses */
+#define ZEUS_FLASH_PHYS		PXA_CS0_PHYS
+#define ZEUS_ETH0_PHYS		PXA_CS1_PHYS
+#define ZEUS_ETH1_PHYS		PXA_CS2_PHYS
+#define ZEUS_CPLD_PHYS		(PXA_CS4_PHYS+0x2000000)
+#define ZEUS_SRAM_PHYS		PXA_CS5_PHYS
+#define ZEUS_PC104IO_PHYS	(0x30000000)
+
+#define ZEUS_CPLD_VERSION_PHYS	(ZEUS_CPLD_PHYS + 0x00000000)
+#define ZEUS_CPLD_ISA_IRQ_PHYS	(ZEUS_CPLD_PHYS + 0x00800000)
+#define ZEUS_CPLD_CONTROL_PHYS	(ZEUS_CPLD_PHYS + 0x01000000)
+#define ZEUS_CPLD_EXTWDOG_PHYS	(ZEUS_CPLD_PHYS + 0x01800000)
+
+/* GPIOs */
+#define ZEUS_AC97_GPIO		0
+#define ZEUS_WAKEUP_GPIO	1
+#define ZEUS_UARTA_GPIO		9
+#define ZEUS_UARTB_GPIO		10
+#define ZEUS_UARTC_GPIO		12
+#define ZEUS_UARTD_GPIO		11
+#define ZEUS_ETH0_GPIO		14
+#define ZEUS_ISA_GPIO		17
+#define ZEUS_BKLEN_GPIO		19
+#define ZEUS_USB2_PWREN_GPIO	22
+#define ZEUS_PTT_GPIO		27
+#define ZEUS_CF_CD_GPIO         35
+#define ZEUS_MMC_WP_GPIO        52
+#define ZEUS_MMC_CD_GPIO        53
+#define ZEUS_EXTGPIO_GPIO	91
+#define ZEUS_CF_PWEN_GPIO       97
+#define ZEUS_CF_RDY_GPIO        99
+#define ZEUS_LCD_EN_GPIO	101
+#define ZEUS_ETH1_GPIO		113
+#define ZEUS_CAN_GPIO		116
+
+#define ZEUS_EXT0_GPIO_BASE	128
+#define ZEUS_EXT1_GPIO_BASE	160
+#define ZEUS_USER_GPIO_BASE	192
+
+#define ZEUS_EXT0_GPIO(x)	(ZEUS_EXT0_GPIO_BASE + (x))
+#define ZEUS_EXT1_GPIO(x)	(ZEUS_EXT1_GPIO_BASE + (x))
+#define ZEUS_USER_GPIO(x)	(ZEUS_USER_GPIO_BASE + (x))
+
+/*
+ * CPLD registers:
+ * Only 4 registers, but spreaded over a 32MB address space.
+ * Be gentle, and remap that over 32kB...
+ */
+
+#define ZEUS_CPLD		(0xf0000000)
+#define ZEUS_CPLD_VERSION	(ZEUS_CPLD + 0x0000)
+#define ZEUS_CPLD_ISA_IRQ	(ZEUS_CPLD + 0x1000)
+#define ZEUS_CPLD_CONTROL	(ZEUS_CPLD + 0x2000)
+#define ZEUS_CPLD_EXTWDOG	(ZEUS_CPLD + 0x3000)
+
+/* CPLD register bits */
+#define ZEUS_CPLD_CONTROL_CF_RST        0x01
+
+#define ZEUS_PC104IO		(0xf1000000)
+
+#define ZEUS_SRAM_SIZE		(256 * 1024)
+
+#endif
+
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/zylonite.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zylonite.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/include/mach/zylonite.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/include/mach/zylonite.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,13 +8,6 @@
 /* the following variables are processor specific and initialized
  * by the corresponding zylonite_pxa3xx_init()
  */
-struct platform_mmc_slot {
-	int gpio_cd;
-	int gpio_wp;
-};
-
-extern struct platform_mmc_slot zylonite_mmc_slot[];
-
 extern int gpio_eth_irq;
 extern int gpio_debug_led1;
 extern int gpio_debug_led2;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,8 +164,11 @@ static int pxa_irq_suspend(struct sys_de
 		saved_icmr[i] = _ICMR(irq);
 		_ICMR(irq) = 0;
 	}
-	for (i = 0; i < pxa_internal_irq_nr; i++)
-		saved_ipr[i] = IPR(i);
+
+	if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+		for (i = 0; i < pxa_internal_irq_nr; i++)
+			saved_ipr[i] = IPR(i);
+	}
 
 	return 0;
 }
@@ -174,12 +177,15 @@ static int pxa_irq_resume(struct sys_dev
 {
 	int i, irq = PXA_IRQ(0);
 
+	if (cpu_is_pxa27x() || cpu_is_pxa3xx()) {
+		for (i = 0; i < pxa_internal_irq_nr; i++)
+			IPR(i) = saved_ipr[i];
+	}
+
 	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
 		_ICMR(irq) = saved_icmr[i];
 		_ICLR(irq) = 0;
 	}
-	for (i = 0; i < pxa_internal_irq_nr; i++)
-		IPR(i) = saved_ipr[i];
 
 	ICCR = 1;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -2,87 +2,78 @@ if ARCH_PXA
 
 menu "Intel PXA2xx/PXA3xx Implementations"
 
-if PXA3xx
+comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
 
-menu "Supported PXA3xx Processor Variants"
+config ARCH_LUBBOCK
+	bool "Intel DBPXA250 Development Platform (aka Lubbock)"
+	select PXA25x
+	select SA1111
+	select PXA_HAVE_BOARD_IRQS
 
-config CPU_PXA300
-	bool "PXA300 (codename Monahans-L)"
+config MACH_MAINSTONE
+	bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
+	select PXA27x
+	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
 
-config CPU_PXA310
-	bool "PXA310 (codename Monahans-LV)"
+config MACH_ZYLONITE
+	bool
+	select PXA3xx
+	select PXA_SSP
+	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_ZYLONITE300
+	bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
 	select CPU_PXA300
+	select CPU_PXA310
+	select MACH_ZYLONITE
 
-config CPU_PXA320
-	bool "PXA320 (codename Monahans-P)"
+config MACH_ZYLONITE320
+	bool "PXA3xx Development Platform (aka Zylonite) PXA320"
+	select CPU_PXA320
+	select MACH_ZYLONITE
 
-config CPU_PXA930
-	bool "PXA930 (codename Tavor-P)"
+config MACH_LITTLETON
+	bool "PXA3xx Form Factor Platform (aka Littleton)"
+	select PXA3xx
+	select CPU_PXA300
+	select CPU_PXA310
+	select PXA_SSP
 
-config CPU_PXA935
-	bool "PXA935 (codename Tavor-P65)"
+config MACH_TAVOREVB
+	bool "PXA930 Evaluation Board (aka TavorEVB)"
+	select PXA3xx
 	select CPU_PXA930
 
-config CPU_PXA950
-	bool "PXA950 (codename Tavor-PV2)"
+config MACH_SAAR
+	bool "PXA930 Handheld Platform (aka SAAR)"
+	select PXA3xx
 	select CPU_PXA930
 
-endmenu
-
-endif
+comment "Third Party Dev Platforms (sorted by vendor name)"
 
-config ARCH_GUMSTIX
-	bool "Gumstix XScale 255 boards"
+config ARCH_PXA_IDP
+	bool "Accelent Xscale IDP"
 	select PXA25x
-	help
-	  Say Y here if you intend to run this kernel on
-	  Basix, Connex, ws-200ax, ws-400ax systems
-
-choice
-	prompt "Gumstix Carrier/Expansion Board"
-	depends on ARCH_GUMSTIX
-
-config GUMSTIX_AM200EPD
-	bool "Enable AM200EPD board support"
-
-config GUMSTIX_AM300EPD
-	bool "Enable AM300EPD board support"
-
-endchoice
-
-config MACH_INTELMOTE2
-	bool "Intel Mote 2 Platform"
-	select PXA27x
-	select IWMMXT
-	select PXA_HAVE_BOARD_IRQS
-
-config MACH_STARGATE2
-	bool "Intel Stargate 2 Platform"
-	select PXA27x
-	select IWMMXT
-	select PXA_HAVE_BOARD_IRQS
 
-config ARCH_LUBBOCK
-	bool "Intel DBPXA250 Development Platform"
+config ARCH_VIPER
+	bool "Arcom/Eurotech VIPER SBC"
 	select PXA25x
-	select SA1111
-	select PXA_HAVE_BOARD_IRQS
-
-config MACH_LOGICPD_PXA270
-	bool "LogicPD PXA270 Card Engine Development Platform"
-	select PXA27x
+	select ISA
+	select I2C_GPIO
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
+	select PXA_HAVE_ISA_IRQS
+	select ARCOM_PCMCIA
 
-config MACH_MAINSTONE
-	bool "Intel HCDDBBVA0 Development Platform"
+config MACH_ARCOM_ZEUS
+	bool "Arcom/Eurotech ZEUS SBC"
 	select PXA27x
-	select HAVE_PWM
+	select ISA
 	select PXA_HAVE_BOARD_IRQS
-
-config MACH_MP900C
-	bool "Nec Mobilepro 900/c"
-	select PXA25x
+	select PXA_HAVE_ISA_IRQS
+	select ARCOM_PCMCIA
 
 config MACH_BALLOON3
 	bool "Balloon 3 board"
@@ -90,157 +81,89 @@ config MACH_BALLOON3
 	select IWMMXT
 	select PXA_HAVE_BOARD_IRQS
 
-config ARCH_PXA_IDP
-	bool "Accelent Xscale IDP"
-	select PXA25x
-
-config PXA_SHARPSL
-	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
-	select SHARP_SCOOP
-	select SHARP_PARAM
+config MACH_CSB726
+	bool "Enable Cogent CSB726 System On a Module"
+	select PXA27x
+	select IWMMXT
 	help
-	  Say Y here if you intend to run this kernel on a
-	  Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
-	  SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
-	  SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
-	  handheld computer.
-
-config SHARPSL_PM
-	bool
-	select APM_EMULATION
+	  Say Y here if you intend to run this kernel on a Cogent
+	  CSB726 System On Module.
 
-config CORGI_SSP_DEPRECATED
-	bool
-	select PXA_SSP
-	help
-	  This option will include corgi_ssp.c and corgi_lcd.c
-	  that corgi_ts.c and other legacy drivers (corgi_bl.c
-	  and sharpsl_pm.c) may depend on.
+config CSB726_CSB701
+	bool "Enable support for CSB701 baseboard"
+	depends on MACH_CSB726
 
-config MACH_POODLE
-	bool "Enable Sharp SL-5600 (Poodle) Support"
-	depends on PXA_SHARPSL
+config MACH_ARMCORE
+	bool "CompuLab CM-X255/CM-X270 modules"
+	select PXA27x
+	select IWMMXT
 	select PXA25x
-	select SHARP_LOCOMO
 	select PXA_SSP
 
-config MACH_CORGI
-	bool "Enable Sharp SL-C700 (Corgi) Support"
-	depends on PXA_SHARPSL
-	select PXA25x
-	select PXA_SHARP_C7xx
-
-config MACH_SHEPHERD
-	bool "Enable Sharp SL-C750 (Shepherd) Support"
-	depends on PXA_SHARPSL
-	select PXA25x
-	select PXA_SHARP_C7xx
-
-config MACH_HUSKY
-	bool "Enable Sharp SL-C760 (Husky) Support"
-	depends on PXA_SHARPSL
-	select PXA25x
-	select PXA_SHARP_C7xx
-
-config MACH_AKITA
-	bool "Enable Sharp SL-1000 (Akita) Support"
-	depends on PXA_SHARPSL
-	select PXA27x
-	select PXA_SHARP_Cxx00
-	select MACH_SPITZ
-	select I2C
-	select I2C_PXA
-
-config MACH_SPITZ
-	bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
-	depends on PXA_SHARPSL
+config MACH_EM_X270
+	bool "CompuLab EM-x270 platform"
 	select PXA27x
-	select PXA_SHARP_Cxx00
 
-config MACH_BORZOI
-	bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
-	depends on PXA_SHARPSL
+config MACH_EXEDA
+	bool "CompuLab eXeda platform"
 	select PXA27x
-	select PXA_SHARP_Cxx00
-
-config MACH_TOSA
-	bool "Enable Sharp SL-6000x (Tosa) Support"
-	depends on PXA_SHARPSL
-	select PXA25x
-	select PXA_HAVE_BOARD_IRQS
 
-config ARCH_VIPER
-	bool "Arcom/Eurotech VIPER SBC"
-	select PXA25x
-	select ISA
-	select I2C_GPIO
+config MACH_CM_X300
+	bool "CompuLab CM-X300 modules"
+	select PXA3xx
+	select CPU_PXA300
+	select CPU_PXA310
 	select HAVE_PWM
-	select PXA_HAVE_BOARD_IRQS
-	select PXA_HAVE_ISA_IRQS
 
-config ARCH_PXA_ESERIES
-	bool "PXA based Toshiba e-series PDAs"
+config ARCH_GUMSTIX
+	bool "Gumstix XScale 255 boards"
 	select PXA25x
-	select PXA_HAVE_BOARD_IRQS
-
-config MACH_E330
-	bool "Toshiba e330"
-	default y
-	depends on ARCH_PXA_ESERIES
 	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e330 family PDA.
+	  Say Y here if you intend to run this kernel on
+	  Basix, Connex, ws-200ax, ws-400ax systems
 
-config MACH_E350
-	bool "Toshiba e350"
-	default y
-	depends on ARCH_PXA_ESERIES
-	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e350 family PDA.
+choice
+	prompt "Gumstix Carrier/Expansion Board"
+	depends on ARCH_GUMSTIX
 
-config MACH_E740
-	bool "Toshiba e740"
-	default y
-	depends on ARCH_PXA_ESERIES
-	select FB_W100
-	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e740 family PDA.
+config GUMSTIX_AM200EPD
+	bool "Enable AM200EPD board support"
 
-config MACH_E750
-	bool "Toshiba e750"
-	default y
-	depends on ARCH_PXA_ESERIES
-	select FB_W100
-	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e750 family PDA.
+config GUMSTIX_AM300EPD
+	bool "Enable AM300EPD board support"
 
-config MACH_E400
-	bool "Toshiba e400"
-	default y
-	depends on ARCH_PXA_ESERIES
-	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e400 family PDA.
+endchoice
 
-config MACH_E800
-	bool "Toshiba e800"
-	default y
-	depends on ARCH_PXA_ESERIES
-	select FB_W100
+config MACH_INTELMOTE2
+	bool "Intel Mote 2 Platform"
+	select PXA27x
+	select IWMMXT
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_STARGATE2
+	bool "Intel Stargate 2 Platform"
+	select PXA27x
+	select IWMMXT
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_XCEP
+	bool "Iskratel Electronics XCEP"
+	select PXA25x
+	select MTD
+	select MTD_PARTITIONS
+	select MTD_PHYSMAP
+	select MTD_CFI_INTELEXT
+	select MTD_CFI
+	select MTD_CHAR
+	select SMC91X
+	select PXA_SSP
 	help
-	  Say Y here if you intend to run this kernel on a Toshiba
-	  e800 family PDA.
+	  PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
+	  Tuned for usage in Libera instruments for particle accelerators.
 
 config TRIZEPS_PXA
 	bool "PXA based Keith und Koep Trizeps DIMM-Modules"
 
-config MACH_H5000
-	bool "HP iPAQ h5000"
-	select PXA25x
-
 config MACH_TRIZEPS4
 	bool "Keith und Koep Trizeps4 DIMM-Module"
 	depends on TRIZEPS_PXA
@@ -269,18 +192,48 @@ config MACH_TRIZEPS_ANY
 
 endchoice
 
+config ARCOM_PCMCIA
+	bool
+	help
+	  Generic option for Arcom Viper/Zeus PCMCIA
+
 config TRIZEPS_PCMCIA
 	bool
 	help
 	  Enable PCMCIA support for Trizeps modules
 
-config MACH_EM_X270
-	bool "CompuLab EM-x270 platform"
+config MACH_LOGICPD_PXA270
+	bool "LogicPD PXA270 Card Engine Development Platform"
 	select PXA27x
+	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
 
-config MACH_EXEDA
-	bool "CompuLab eXeda platform"
+config MACH_PCM027
+	bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
 	select PXA27x
+	select IWMMXT
+	select PXA_SSP
+	select PXA_HAVE_BOARD_IRQS
+
+config MACH_PCM990_BASEBOARD
+	bool "PHYTEC PCM-990 development board"
+	select HAVE_PWM
+	depends on MACH_PCM027
+
+choice
+	prompt "display on pcm990"
+	depends on MACH_PCM990_BASEBOARD
+
+config PCM990_DISPLAY_SHARP
+	bool "sharp lq084v1dg21 stn display"
+
+config PCM990_DISPLAY_NEC
+	bool "nec nl6448bc20_18d tft display"
+
+config PCM990_DISPLAY_NONE
+	bool "no display"
+
+endchoice
 
 config MACH_COLIBRI
 	bool "Toradex Colibri PXA270"
@@ -290,45 +243,14 @@ config MACH_COLIBRI300
 	bool "Toradex Colibri PXA300/310"
 	select PXA3xx
 	select CPU_PXA300
+	select CPU_PXA310
 
 config MACH_COLIBRI320
 	bool "Toradex Colibri PXA320"
 	select PXA3xx
 	select CPU_PXA320
 
-config MACH_ZYLONITE
-	bool "PXA3xx Development Platform (aka Zylonite)"
-	select PXA3xx
-	select PXA_SSP
-	select HAVE_PWM
-	select PXA_HAVE_BOARD_IRQS
-
-config MACH_LITTLETON
-	bool "PXA3xx Form Factor Platform (aka Littleton)"
-	select PXA3xx
-	select PXA_SSP
-
-config MACH_TAVOREVB
-	bool "PXA930 Evaluation Board (aka TavorEVB)"
-	select PXA3xx
-	select CPU_PXA930
-
-config MACH_SAAR
-	bool "PXA930 Handheld Platform (aka SAAR)"
-	select PXA3xx
-	select CPU_PXA930
-
-config MACH_ARMCORE
-	bool "CompuLab CM-X255/CM-X270 modules"
-	select PXA27x
-	select IWMMXT
-	select PXA25x
-	select PXA_SSP
-
-config MACH_CM_X300
-	bool "CompuLab CM-X300 modules"
-	select PXA3xx
-	select CPU_PXA300
+comment "End-user Products (sorted by vendor name)"
 
 config MACH_H4700
 	bool "HP iPAQ hx4700"
@@ -338,6 +260,15 @@ config MACH_H4700
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
+config MACH_H5000
+	bool "HP iPAQ h5000"
+	select PXA25x
+
+config MACH_HIMALAYA
+	bool "HTC Himalaya Support"
+	select CPU_PXA26x
+	select FB_W100
+
 config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
 	select PXA27x
@@ -346,11 +277,6 @@ config MACH_MAGICIAN
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
-config MACH_HIMALAYA
-	bool "HTC Himalaya Support"
-	select CPU_PXA26x
-	select FB_W100
-
 config MACH_MIOA701
 	bool "Mitac Mio A701 Support"
 	select PXA27x
@@ -362,13 +288,47 @@ config MACH_MIOA701
 	  MIO A701. Currently there is only basic support
 	  for this PDA.
 
-config MACH_PCM027
-	bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
+config PXA_EZX
+	bool "Motorola EZX Platform"
 	select PXA27x
 	select IWMMXT
-	select PXA_SSP
+	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
+config MACH_EZX_A780
+	bool "Motorola EZX A780"
+	default y
+	depends on PXA_EZX
+
+config MACH_EZX_E680
+	bool "Motorola EZX E680"
+	default y
+	depends on PXA_EZX
+
+config MACH_EZX_A1200
+	bool "Motorola EZX A1200"
+	default y
+	depends on PXA_EZX
+
+config MACH_EZX_A910
+	bool "Motorola EZX A910"
+	default y
+	depends on PXA_EZX
+
+config MACH_EZX_E6
+	bool "Motorola EZX E6"
+	default y
+	depends on PXA_EZX
+
+config MACH_EZX_E2
+	bool "Motorola EZX E2"
+	default y
+	depends on PXA_EZX
+
+config MACH_MP900C
+	bool "Nec Mobilepro 900/c"
+	select PXA25x
+
 config ARCH_PXA_PALM
 	bool "PXA based Palm PDAs"
 	select HAVE_PWM
@@ -421,109 +381,172 @@ config MACH_PALMZ72
 	  Say Y here if you intend to run this kernel on Palm Zire 72
 	  handheld computer.
 
-config MACH_TREO680
-	bool "Palm Treo 680"
+config MACH_PALMLD
+	bool "Palm LifeDrive"
 	default y
 	depends on ARCH_PXA_PALM
 	select PXA27x
 	select IWMMXT
 	help
-	  Say Y here if you intend to run this kernel on Palm Treo 680
+	  Say Y here if you intend to run this kernel on a Palm LifeDrive
+	  handheld computer.
+
+config PALM_TREO
+	bool
+	depends on ARCH_PXA_PALM
+
+config MACH_CENTRO
+	bool "Palm Centro 685 (GSM)"
+	default y
+	depends on ARCH_PXA_PALM
+	select PXA27x
+	select IWMMXT
+	select PALM_TREO
+	help
+	  Say Y here if you intend to run this kernel on Palm Centro 685 (GSM)
 	  smartphone.
 
-config MACH_PALMLD
-	bool "Palm LifeDrive"
+config MACH_TREO680
+	bool "Palm Treo 680"
 	default y
 	depends on ARCH_PXA_PALM
 	select PXA27x
 	select IWMMXT
+	select PALM_TREO
 	help
-	  Say Y here if you intend to run this kernel on a Palm LifeDrive
+	  Say Y here if you intend to run this kernel on Palm Treo 680
+	  smartphone.
+
+config PXA_SHARPSL
+	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
+	select SHARP_SCOOP
+	select SHARP_PARAM
+	help
+	  Say Y here if you intend to run this kernel on a
+	  Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
+	  SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
+	  SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
 	  handheld computer.
 
-config MACH_PCM990_BASEBOARD
-	bool "PHYTEC PCM-990 development board"
-	select HAVE_PWM
-	depends on MACH_PCM027
+config SHARPSL_PM
+	bool
+	select APM_EMULATION
 
-choice
-	prompt "display on pcm990"
-	depends on MACH_PCM990_BASEBOARD
+config CORGI_SSP_DEPRECATED
+	bool
+	select PXA_SSP
+	help
+	  This option will include corgi_ssp.c and corgi_lcd.c
+	  that corgi_ts.c and other legacy drivers (corgi_bl.c
+	  and sharpsl_pm.c) may depend on.
 
-config PCM990_DISPLAY_SHARP
-	bool "sharp lq084v1dg21 stn display"
+config MACH_POODLE
+	bool "Enable Sharp SL-5600 (Poodle) Support"
+	depends on PXA_SHARPSL
+	select PXA25x
+	select SHARP_LOCOMO
+	select PXA_SSP
 
-config PCM990_DISPLAY_NEC
-	bool "nec nl6448bc20_18d tft display"
+config MACH_CORGI
+	bool "Enable Sharp SL-C700 (Corgi) Support"
+	depends on PXA_SHARPSL
+	select PXA25x
+	select PXA_SHARP_C7xx
 
-config PCM990_DISPLAY_NONE
-	bool "no display"
+config MACH_SHEPHERD
+	bool "Enable Sharp SL-C750 (Shepherd) Support"
+	depends on PXA_SHARPSL
+	select PXA25x
+	select PXA_SHARP_C7xx
 
-endchoice
+config MACH_HUSKY
+	bool "Enable Sharp SL-C760 (Husky) Support"
+	depends on PXA_SHARPSL
+	select PXA25x
+	select PXA_SHARP_C7xx
 
-config MACH_CSB726
-	bool "Enable Cogent CSB726 System On a Module"
+config MACH_AKITA
+	bool "Enable Sharp SL-1000 (Akita) Support"
+	depends on PXA_SHARPSL
 	select PXA27x
-	select IWMMXT
-	help
-	  Say Y here if you intend to run this kernel on a Cogent
-	  CSB726 System On Module.
+	select PXA_SHARP_Cxx00
+	select MACH_SPITZ
+	select I2C
+	select I2C_PXA
 
-config CSB726_CSB701
-	bool "Enable supprot for CSB701 baseboard"
-	depends on MACH_CSB726
+config MACH_SPITZ
+	bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
+	depends on PXA_SHARPSL
+	select PXA27x
+	select PXA_SHARP_Cxx00
 
-config PXA_EZX
-	bool "Motorola EZX Platform"
+config MACH_BORZOI
+	bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
+	depends on PXA_SHARPSL
 	select PXA27x
-	select IWMMXT
-	select HAVE_PWM
+	select PXA_SHARP_Cxx00
+
+config MACH_TOSA
+	bool "Enable Sharp SL-6000x (Tosa) Support"
+	depends on PXA_SHARPSL
+	select PXA25x
 	select PXA_HAVE_BOARD_IRQS
 
-config MACH_EZX_A780
-	bool "Motorola EZX A780"
-	default y
-	depends on PXA_EZX
+config ARCH_PXA_ESERIES
+	bool "PXA based Toshiba e-series PDAs"
+	select PXA25x
+	select PXA_HAVE_BOARD_IRQS
 
-config MACH_EZX_E680
-	bool "Motorola EZX E680"
+config MACH_E330
+	bool "Toshiba e330"
 	default y
-	depends on PXA_EZX
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e330 family PDA.
 
-config MACH_EZX_A1200
-	bool "Motorola EZX A1200"
+config MACH_E350
+	bool "Toshiba e350"
 	default y
-	depends on PXA_EZX
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e350 family PDA.
 
-config MACH_EZX_A910
-	bool "Motorola EZX A910"
+config MACH_E740
+	bool "Toshiba e740"
 	default y
-	depends on PXA_EZX
+	depends on ARCH_PXA_ESERIES
+	select FB_W100
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e740 family PDA.
 
-config MACH_EZX_E6
-	bool "Motorola EZX E6"
+config MACH_E750
+	bool "Toshiba e750"
 	default y
-	depends on PXA_EZX
+	depends on ARCH_PXA_ESERIES
+	select FB_W100
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e750 family PDA.
 
-config MACH_EZX_E2
-	bool "Motorola EZX E2"
+config MACH_E400
+	bool "Toshiba e400"
 	default y
-	depends on PXA_EZX
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e400 family PDA.
 
-config MACH_XCEP
-	bool "Iskratel Electronics XCEP"
-	select PXA25x
-	select MTD
-	select MTD_PARTITIONS
-	select MTD_PHYSMAP
-	select MTD_CFI_INTELEXT
-	select MTD_CFI
-	select MTD_CHAR
-	select SMC91X
-	select PXA_SSP
+config MACH_E800
+	bool "Toshiba e800"
+	default y
+	depends on ARCH_PXA_ESERIES
+	select FB_W100
 	help
-	  PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
-	  Tuned for usage in Libera instruments for particle accelerators.
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e800 family PDA.
 
 endmenu
 
@@ -551,6 +574,42 @@ config PXA3xx
 	help
 	  Select code specific to PXA3xx variants
 
+config CPU_PXA300
+	bool
+	select PXA3xx
+	help
+	  PXA300 (codename Monahans-L)
+
+config CPU_PXA310
+	bool
+	select CPU_PXA300
+	help
+	  PXA310 (codename Monahans-LV)
+
+config CPU_PXA320
+	bool
+	select PXA3xx
+	help
+	  PXA320 (codename Monahans-P)
+
+config CPU_PXA930
+	bool
+	select PXA3xx
+	help
+	  PXA930 (codename Tavor-P)
+
+config CPU_PXA935
+	bool
+	select CPU_PXA930
+	help
+	  PXA935 (codename Tavor-P65)
+
+config CPU_PXA950
+	bool
+	select CPU_PXA930
+	help
+	  PXA950 (codename Tavor-PV2)
+
 config PXA_SHARP_C7xx
 	bool
 	select PXA_SSP
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/littleton.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/littleton.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/littleton.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/littleton.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,10 +44,10 @@
 #include <mach/ssp.h>
 #include <mach/mmc.h>
 #include <mach/pxa2xx_spi.h>
-#include <plat/i2c.h>
 #include <mach/pxa27x_keypad.h>
-#include <mach/pxa3xx_nand.h>
 #include <mach/littleton.h>
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
 
 #include "generic.h"
 
@@ -110,6 +110,12 @@ static mfp_cfg_t littleton_mfp_cfg[] __i
 	GPIO7_MMC1_CLK,
 	GPIO8_MMC1_CMD,
 	GPIO15_GPIO, /* card detect */
+
+	/* UART3 */
+	GPIO107_UART3_CTS,
+	GPIO108_UART3_RTS,
+	GPIO109_UART3_TXD,
+	GPIO110_UART3_RXD,
 };
 
 static struct resource smc91x_resources[] = {
@@ -413,6 +419,10 @@ static void __init littleton_init(void)
 	/* initialize MFP configurations */
 	pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	/*
 	 * Note: we depend bootloader set the correct
 	 * value to MSC register for SMC91x.
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/lpd270.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lpd270.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/lpd270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lpd270.c	2010-02-24 13:52:17.000000000 -0500
@@ -455,6 +455,10 @@ static void __init lpd270_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(lpd270_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
 	lpd270_flash_data[1].width = 4;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/lubbock.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lubbock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/lubbock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/lubbock.c	2010-02-24 13:52:17.000000000 -0500
@@ -518,6 +518,10 @@ static void __init lubbock_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	pxa_set_udc_info(&udc_info);
 	set_pxa_fb_info(&sharp_lm8v31);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/magician.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/magician.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/magician.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/magician.c	2010-02-24 13:52:17.000000000 -0500
@@ -381,7 +381,7 @@ err:
 	return ret;
 }
 
-static int magician_backlight_notify(int brightness)
+static int magician_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
 	if (brightness >= 200) {
@@ -742,6 +742,10 @@ static void __init magician_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_add_devices(ARRAY_AND_SIZE(devices));
 
 	err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mainstone.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mainstone.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mainstone.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mainstone.c	2010-02-24 13:52:17.000000000 -0500
@@ -576,6 +576,10 @@ static void __init mainstone_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
 	mst_flash_data[1].width = 4;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -24,33 +24,64 @@ obj-$(CONFIG_CPU_PXA300)	+= pxa300.o
 obj-$(CONFIG_CPU_PXA320)	+= pxa320.o
 obj-$(CONFIG_CPU_PXA930)	+= pxa930.o
 
-# Specific board support
-obj-$(CONFIG_ARCH_GUMSTIX)	+= gumstix.o
-obj-$(CONFIG_GUMSTIX_AM200EPD)	+= am200epd.o
-obj-$(CONFIG_GUMSTIX_AM300EPD)	+= am300epd.o
+# NOTE: keep the order of boards in accordance to their order in Kconfig
+
+# Intel/Marvell Dev Platforms
 obj-$(CONFIG_ARCH_LUBBOCK)	+= lubbock.o
-obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
 obj-$(CONFIG_MACH_MAINSTONE)	+= mainstone.o
-obj-$(CONFIG_MACH_BALLOON3)	+= balloon3.o
-obj-$(CONFIG_MACH_MP900C)	+= mp900.o
+obj-$(CONFIG_MACH_ZYLONITE300)	+= zylonite.o zylonite_pxa300.o
+obj-$(CONFIG_MACH_ZYLONITE320)	+= zylonite.o zylonite_pxa320.o
+obj-$(CONFIG_MACH_LITTLETON)	+= littleton.o
+obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
+obj-$(CONFIG_MACH_SAAR)		+= saar.o
+
+# 3rd Party Dev Platforms
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
+obj-$(CONFIG_ARCH_VIPER)	+= viper.o
+obj-$(CONFIG_MACH_ARCOM_ZEUS)	+= zeus.o
+obj-$(CONFIG_MACH_BALLOON3)	+= balloon3.o
+obj-$(CONFIG_MACH_CSB726)	+= csb726.o
+obj-$(CONFIG_CSB726_CSB701)	+= csb701.o
+obj-$(CONFIG_MACH_ARMCORE)      += cm-x2xx.o cm-x255.o cm-x270.o
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MACH_ARMCORE)	+= cm-x2xx-pci.o
+endif
+obj-$(CONFIG_MACH_EM_X270)	+= em-x270.o
+obj-$(CONFIG_MACH_CM_X300)      += cm-x300.o
+obj-$(CONFIG_ARCH_GUMSTIX)	+= gumstix.o
+obj-$(CONFIG_GUMSTIX_AM200EPD)	+= am200epd.o
+obj-$(CONFIG_GUMSTIX_AM300EPD)	+= am300epd.o
+obj-$(CONFIG_MACH_INTELMOTE2)   += imote2.o
+obj-$(CONFIG_MACH_STARGATE2)	+= stargate2.o
+obj-$(CONFIG_MACH_XCEP)         += xcep.o
 obj-$(CONFIG_MACH_TRIZEPS4)	+= trizeps4.o
+obj-$(CONFIG_MACH_LOGICPD_PXA270)	+= lpd270.o
+obj-$(CONFIG_MACH_PCM027)		+= pcm027.o
+obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= pcm990-baseboard.o
 obj-$(CONFIG_MACH_COLIBRI)	+= colibri-pxa270.o
 obj-$(CONFIG_MACH_COLIBRI300)	+= colibri-pxa3xx.o colibri-pxa300.o
 obj-$(CONFIG_MACH_COLIBRI320)	+= colibri-pxa3xx.o colibri-pxa320.o
+
+# End-user Products
+obj-$(CONFIG_MACH_H4700)	+= hx4700.o
 obj-$(CONFIG_MACH_H5000)	+= h5000.o
+obj-$(CONFIG_MACH_HIMALAYA)	+= himalaya.o
+obj-$(CONFIG_MACH_MAGICIAN)	+= magician.o
+obj-$(CONFIG_MACH_MIOA701)	+= mioa701.o mioa701_bootresume.o
+obj-$(CONFIG_PXA_EZX)           += ezx.o
+obj-$(CONFIG_MACH_MP900C)	+= mp900.o
+obj-$(CONFIG_MACH_PALMTE2)	+= palmte2.o
+obj-$(CONFIG_MACH_PALMTC)	+= palmtc.o
+obj-$(CONFIG_MACH_PALMT5)	+= palmt5.o
+obj-$(CONFIG_MACH_PALMTX)	+= palmtx.o
+obj-$(CONFIG_MACH_PALMZ72)	+= palmz72.o
+obj-$(CONFIG_MACH_PALMLD)	+= palmld.o
+obj-$(CONFIG_PALM_TREO)		+= palmtreo.o
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o sharpsl_pm.o spitz_pm.o
 obj-$(CONFIG_CORGI_SSP_DEPRECATED)	+= corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
-obj-$(CONFIG_MACH_PCM027)	+= pcm027.o
-obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= pcm990-baseboard.o
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
-obj-$(CONFIG_MACH_EM_X270)	+= em-x270.o
-obj-$(CONFIG_MACH_H4700)	+= hx4700.o
-obj-$(CONFIG_MACH_MAGICIAN)	+= magician.o
-obj-$(CONFIG_MACH_HIMALAYA)	+= himalaya.o
-obj-$(CONFIG_MACH_MIOA701)	+= mioa701.o mioa701_bootresume.o
 obj-$(CONFIG_ARCH_PXA_ESERIES)	+= eseries.o
 obj-$(CONFIG_MACH_E330)		+= e330.o
 obj-$(CONFIG_MACH_E350)		+= e350.o
@@ -58,34 +89,6 @@ obj-$(CONFIG_MACH_E740)		+= e740.o
 obj-$(CONFIG_MACH_E750)		+= e750.o
 obj-$(CONFIG_MACH_E400)		+= e400.o
 obj-$(CONFIG_MACH_E800)		+= e800.o
-obj-$(CONFIG_MACH_PALMTE2)	+= palmte2.o
-obj-$(CONFIG_MACH_PALMTC)	+= palmtc.o
-obj-$(CONFIG_MACH_PALMT5)	+= palmt5.o
-obj-$(CONFIG_MACH_PALMTX)	+= palmtx.o
-obj-$(CONFIG_MACH_PALMLD)	+= palmld.o
-obj-$(CONFIG_MACH_PALMZ72)	+= palmz72.o
-obj-$(CONFIG_MACH_TREO680)	+= treo680.o
-obj-$(CONFIG_ARCH_VIPER)	+= viper.o
-
-ifeq ($(CONFIG_MACH_ZYLONITE),y)
-  obj-y				+= zylonite.o
-  obj-$(CONFIG_CPU_PXA300)	+= zylonite_pxa300.o
-  obj-$(CONFIG_CPU_PXA320)	+= zylonite_pxa320.o
-endif
-obj-$(CONFIG_MACH_LITTLETON)	+= littleton.o
-obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
-obj-$(CONFIG_MACH_SAAR)		+= saar.o
-
-obj-$(CONFIG_MACH_ARMCORE)      += cm-x2xx.o cm-x255.o cm-x270.o
-obj-$(CONFIG_MACH_CM_X300)      += cm-x300.o
-obj-$(CONFIG_PXA_EZX)           += ezx.o
-
-obj-$(CONFIG_MACH_XCEP)         += xcep.o
-
-obj-$(CONFIG_MACH_INTELMOTE2)   += imote2.o
-obj-$(CONFIG_MACH_STARGATE2)	+= stargate2.o
-obj-$(CONFIG_MACH_CSB726)	+= csb726.o
-obj-$(CONFIG_CSB726_CSB701)	+= csb701.o
 
 # Support for blinky lights
 led-y := leds.o
@@ -95,8 +98,4 @@ led-$(CONFIG_ARCH_PXA_IDP)	+= leds-idp.o
 
 obj-$(CONFIG_LEDS)		+= $(led-y)
 
-ifeq ($(CONFIG_PCI),y)
-obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o
-endif
-
 obj-$(CONFIG_TOSA_BT)		+= tosa-bt.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mioa701.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mioa701.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mioa701.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mioa701.c	2010-02-24 13:52:17.000000000 -0500
@@ -798,6 +798,9 @@ static void __init mioa701_machine_init(
 	UP2OCR = UP2OCR_HXOE;
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 	bootstrap_init();
 	set_pxa_fb_info(&mioa701_pxafb_info);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mp900.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mp900.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/mp900.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/mp900.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,9 @@ static struct platform_device *devices[]
 static void __init mp900c_init(void)
 {
 	printk(KERN_INFO "MobilePro 900/C machine init\n");
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmld.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmld.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmld.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmld.c	2010-02-24 13:52:17.000000000 -0500
@@ -270,7 +270,7 @@ err:
 	return ret;
 }
 
-static int palmld_backlight_notify(int brightness)
+static int palmld_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness);
 	gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness);
@@ -530,6 +530,10 @@ static void __init palmld_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	palmld_pm_init();
 	set_pxa_fb_info(&palmld_lcd_screen);
 	pxa_set_mci_info(&palmld_mci_platform_data);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmt5.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmt5.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmt5.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmt5.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,7 +209,7 @@ err:
 	return ret;
 }
 
-static int palmt5_backlight_notify(int brightness)
+static int palmt5_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness);
 	gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness);
@@ -419,6 +419,10 @@ static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	palmt5_pm_init();
 	set_pxa_fb_info(&palmt5_lcd_screen);
 	pxa_set_mci_info(&palmt5_mci_platform_data);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtc.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,7 +185,7 @@ err:
 	return ret;
 }
 
-static int palmtc_backlight_notify(int brightness)
+static int palmtc_backlight_notify(struct device *dev, int brightness)
 {
 	/* backlight is on when GPIO16 AF0 is high */
 	gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness);
@@ -416,6 +416,11 @@ static void __init palmtc_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+	pxa_set_hwuart_info(NULL);
+
 	set_pxa_fb_info(&palmtc_lcd_screen);
 	pxa_set_mci_info(&palmtc_mci_platform_data);
 	pxa_set_udc_info(&palmtc_udc_info);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmte2.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmte2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmte2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmte2.c	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,7 @@ err:
 	return ret;
 }
 
-static int palmte2_backlight_notify(int brightness)
+static int palmte2_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness);
 	gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness);
@@ -373,6 +373,10 @@ static void __init palmte2_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	set_pxa_fb_info(&palmte2_lcd_screen);
 	pxa_set_mci_info(&palmte2_mci_platform_data);
 	palmte2_udc_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtreo.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtreo.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtreo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtreo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,716 @@
+/*
+ * Hardware definitions for Palm Treo smartphones
+ *
+ * currently supported:
+ *     Palm Treo 680 (GSM)
+ *     Palm Centro 685 (GSM)
+ *
+ * Author:     Tomas Cech <sleep_walker@suse.cz>
+ *
+ * This 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.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+#include <linux/power_supply.h>
+#include <linux/sysdev.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/audio.h>
+#include <mach/palmtreo.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/ohci.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/palmasoc.h>
+#include <mach/camera.h>
+
+#include <sound/pxa2xx-lib.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long treo_pin_config[] __initdata = {
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	GPIO113_GPIO,				/* SD detect */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO89_AC97_SYSCLK,
+	GPIO95_AC97_nRESET,
+
+	/* IrDA */
+	GPIO46_FICP_RXD,
+	GPIO47_FICP_TXD,
+
+	/* PWM */
+	GPIO16_PWM0_OUT,
+
+	/* USB */
+	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,	/* usb detect */
+
+	/* MATRIX KEYPAD */
+	GPIO101_KP_MKIN_1,
+	GPIO102_KP_MKIN_2,
+	GPIO97_KP_MKIN_3,
+	GPIO98_KP_MKIN_4,
+	GPIO91_KP_MKIN_6,
+	GPIO13_KP_MKIN_7,
+	GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+	GPIO106_KP_MKOUT_3,
+	GPIO107_KP_MKOUT_4,
+	GPIO108_KP_MKOUT_5,
+	GPIO96_KP_MKOUT_6,
+	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,	/* Hotsync button */
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+
+	/* Quick Capture Interface */
+	GPIO84_CIF_FV,
+	GPIO85_CIF_LV,
+	GPIO53_CIF_MCLK,
+	GPIO54_CIF_PCLK,
+	GPIO81_CIF_DD_0,
+	GPIO55_CIF_DD_1,
+	GPIO51_CIF_DD_2,
+	GPIO50_CIF_DD_3,
+	GPIO52_CIF_DD_4,
+	GPIO48_CIF_DD_5,
+	GPIO17_CIF_DD_6,
+	GPIO12_CIF_DD_7,
+
+	/* I2C */
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+
+	/* GSM */
+	GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,	/* GSM host wake up */
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+	GPIO39_FFUART_TXD,
+	GPIO41_FFUART_RTS,
+
+	/* MISC. */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* external power detect */
+	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,	/* silent switch */
+	GPIO116_GPIO,				/* headphone detect */
+	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* bluetooth host wake up */
+};
+
+#ifdef CONFIG_MACH_TREO680
+static unsigned long treo680_pin_config[] __initdata = {
+	GPIO33_GPIO,    /* SD read only */
+
+	/* MATRIX KEYPAD - different wake up source */
+	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO99_KP_MKIN_5,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static unsigned long centro685_pin_config[] __initdata = {
+	/* Bluetooth attached to BT UART*/
+	MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW),    /* power: LOW = off */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	/* MATRIX KEYPAD - different wake up source */
+	GPIO100_KP_MKIN_0,
+	GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#ifdef CONFIG_MACH_TREO680
+static struct pxamci_platform_data treo680_mci_platform_data = {
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_TREO_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_TREO680_SD_READONLY,
+	.gpio_power		= GPIO_NR_TREO680_SD_POWER,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static struct pxamci_platform_data centro_mci_platform_data = {
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_TREO_SD_DETECT_N,
+	.gpio_card_ro		= -1,
+	.gpio_power		= GPIO_NR_CENTRO_SD_POWER,
+	.gpio_power_invert	= 1,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#ifdef CONFIG_MACH_TREO680
+static unsigned int treo680_matrix_keys[] = {
+	KEY(0, 0, KEY_F8),		/* Red/Off/Power */
+	KEY(0, 1, KEY_LEFT),
+	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
+	KEY(0, 3, KEY_L),
+	KEY(0, 4, KEY_A),
+	KEY(0, 5, KEY_Q),
+	KEY(0, 6, KEY_P),
+
+	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
+	KEY(1, 1, KEY_RIGHT),
+	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
+	KEY(1, 3, KEY_Z),
+	KEY(1, 4, KEY_S),
+	KEY(1, 5, KEY_W),
+
+	KEY(2, 0, KEY_F1),		/* Phone */
+	KEY(2, 1, KEY_UP),
+	KEY(2, 2, KEY_0),
+	KEY(2, 3, KEY_X),
+	KEY(2, 4, KEY_D),
+	KEY(2, 5, KEY_E),
+
+	KEY(3, 0, KEY_F10),		/* Calendar */
+	KEY(3, 1, KEY_DOWN),
+	KEY(3, 2, KEY_SPACE),
+	KEY(3, 3, KEY_C),
+	KEY(3, 4, KEY_F),
+	KEY(3, 5, KEY_R),
+
+	KEY(4, 0, KEY_F12),		/* Mail */
+	KEY(4, 1, KEY_KPENTER),
+	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
+	KEY(4, 3, KEY_V),
+	KEY(4, 4, KEY_G),
+	KEY(4, 5, KEY_T),
+
+	KEY(5, 0, KEY_F9),		/* Home */
+	KEY(5, 1, KEY_PAGEUP),		/* Side up */
+	KEY(5, 2, KEY_DOT),
+	KEY(5, 3, KEY_B),
+	KEY(5, 4, KEY_H),
+	KEY(5, 5, KEY_Y),
+
+	KEY(6, 0, KEY_TAB),		/* Side Activate */
+	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
+	KEY(6, 2, KEY_ENTER),
+	KEY(6, 3, KEY_N),
+	KEY(6, 4, KEY_J),
+	KEY(6, 5, KEY_U),
+
+	KEY(7, 0, KEY_F6),		/* Green/Call */
+	KEY(7, 1, KEY_O),
+	KEY(7, 2, KEY_BACKSPACE),
+	KEY(7, 3, KEY_M),
+	KEY(7, 4, KEY_K),
+	KEY(7, 5, KEY_I),
+};
+
+static struct pxa27x_keypad_platform_data treo680_keypad_platform_data = {
+	.matrix_key_rows	= 8,
+	.matrix_key_cols	= 7,
+	.matrix_key_map		= treo680_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(treo680_matrix_keys),
+	.direct_key_map		= { KEY_CONNECT },
+	.direct_key_num		= 1,
+
+	.debounce_interval	= 30,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static unsigned int centro_matrix_keys[] = {
+	KEY(0, 0, KEY_F9),		/* Home */
+	KEY(0, 1, KEY_LEFT),
+	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
+	KEY(0, 3, KEY_L),
+	KEY(0, 4, KEY_A),
+	KEY(0, 5, KEY_Q),
+	KEY(0, 6, KEY_P),
+
+	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
+	KEY(1, 1, KEY_RIGHT),
+	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
+	KEY(1, 3, KEY_Z),
+	KEY(1, 4, KEY_S),
+	KEY(1, 5, KEY_W),
+
+	KEY(2, 0, KEY_F1),		/* Phone */
+	KEY(2, 1, KEY_UP),
+	KEY(2, 2, KEY_0),
+	KEY(2, 3, KEY_X),
+	KEY(2, 4, KEY_D),
+	KEY(2, 5, KEY_E),
+
+	KEY(3, 0, KEY_F10),		/* Calendar */
+	KEY(3, 1, KEY_DOWN),
+	KEY(3, 2, KEY_SPACE),
+	KEY(3, 3, KEY_C),
+	KEY(3, 4, KEY_F),
+	KEY(3, 5, KEY_R),
+
+	KEY(4, 0, KEY_F12),		/* Mail */
+	KEY(4, 1, KEY_KPENTER),
+	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
+	KEY(4, 3, KEY_V),
+	KEY(4, 4, KEY_G),
+	KEY(4, 5, KEY_T),
+
+	KEY(5, 0, KEY_F8),		/* Red/Off/Power */
+	KEY(5, 1, KEY_PAGEUP),		/* Side up */
+	KEY(5, 2, KEY_DOT),
+	KEY(5, 3, KEY_B),
+	KEY(5, 4, KEY_H),
+	KEY(5, 5, KEY_Y),
+
+	KEY(6, 0, KEY_TAB),		/* Side Activate */
+	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
+	KEY(6, 2, KEY_ENTER),
+	KEY(6, 3, KEY_N),
+	KEY(6, 4, KEY_J),
+	KEY(6, 5, KEY_U),
+
+	KEY(7, 0, KEY_F6),		/* Green/Call */
+	KEY(7, 1, KEY_O),
+	KEY(7, 2, KEY_BACKSPACE),
+	KEY(7, 3, KEY_M),
+	KEY(7, 4, KEY_K),
+	KEY(7, 5, KEY_I),
+};
+
+static struct pxa27x_keypad_platform_data centro_keypad_platform_data = {
+	.matrix_key_rows	= 8,
+	.matrix_key_cols	= 7,
+	.matrix_key_map		= centro_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(centro_matrix_keys),
+	.direct_key_map		= { KEY_CONNECT },
+	.direct_key_num		= 1,
+
+	.debounce_interval	= 30,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+
+static pxa2xx_audio_ops_t treo_ac97_pdata = {
+	.reset_gpio	= 95,
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int treo_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_TREO_BL_POWER, "BL POWER");
+	if (ret)
+		goto err;
+	ret = gpio_direction_output(GPIO_NR_TREO_BL_POWER, 0);
+	if (ret)
+		goto err2;
+
+	return 0;
+
+err2:
+	gpio_free(GPIO_NR_TREO_BL_POWER);
+err:
+	return ret;
+}
+
+static int treo_backlight_notify(struct device *dev, int brightness)
+{
+	gpio_set_value(GPIO_NR_TREO_BL_POWER, brightness);
+	return TREO_MAX_INTENSITY - brightness;
+};
+
+static void treo_backlight_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_TREO_BL_POWER);
+}
+
+static struct platform_pwm_backlight_data treo_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= TREO_MAX_INTENSITY,
+	.dft_brightness	= TREO_DEFAULT_INTENSITY,
+	.pwm_period_ns	= TREO_PERIOD_NS,
+	.init		= treo_backlight_init,
+	.notify		= treo_backlight_notify,
+	.exit		= treo_backlight_exit,
+};
+
+static struct platform_device treo_backlight = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &treo_backlight_data,
+	},
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static struct pxaficp_platform_data treo_ficp_info = {
+	.gpio_pwdown		= GPIO_NR_TREO_IR_EN,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct pxa2xx_udc_mach_info treo_udc_info __initdata = {
+	.gpio_vbus		= GPIO_NR_TREO_USB_DETECT,
+	.gpio_vbus_inverted	= 1,
+	.gpio_pullup		= GPIO_NR_TREO_USB_PULLUP,
+};
+
+
+/******************************************************************************
+ * USB host
+ ******************************************************************************/
+#ifdef CONFIG_MACH_TREO680
+static struct pxaohci_platform_data treo680_ohci_info = {
+	.port_mode    = PMM_PERPORT_MODE,
+	.flags        = ENABLE_PORT1 | ENABLE_PORT3,
+	.power_budget = 0,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_TREO_POWER_DETECT, "CABLE_STATE_AC");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_input(GPIO_NR_TREO_POWER_DETECT);
+	if (ret)
+		goto err2;
+
+	return 0;
+
+err2:
+	gpio_free(GPIO_NR_TREO_POWER_DETECT);
+err1:
+	return ret;
+}
+
+static int treo_is_ac_online(void)
+{
+	return gpio_get_value(GPIO_NR_TREO_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_TREO_POWER_DETECT);
+}
+
+static char *treo_supplicants[] = {
+	"main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+	.init		 = power_supply_init,
+	.is_ac_online    = treo_is_ac_online,
+	.exit		 = power_supply_exit,
+	.supplied_to     = treo_supplicants,
+	.num_supplicants = ARRAY_SIZE(treo_supplicants),
+};
+
+static struct platform_device power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+};
+
+/******************************************************************************
+ * Vibra and LEDs
+ ******************************************************************************/
+#ifdef CONFIG_MACH_TREO680
+static struct gpio_led treo680_gpio_leds[] = {
+	{
+		.name			= "treo680:vibra:vibra",
+		.default_trigger	= "none",
+		.gpio			= GPIO_NR_TREO680_VIBRATE_EN,
+	},
+	{
+		.name			= "treo680:green:led",
+		.default_trigger	= "mmc0",
+		.gpio			= GPIO_NR_TREO_GREEN_LED,
+	},
+	{
+		.name			= "treo680:white:keybbl",
+		.default_trigger	= "none",
+		.gpio			= GPIO_NR_TREO680_KEYB_BL,
+	},
+};
+
+static struct gpio_led_platform_data treo680_gpio_led_info = {
+	.leds		= treo680_gpio_leds,
+	.num_leds	= ARRAY_SIZE(treo680_gpio_leds),
+};
+
+static struct platform_device treo680_leds = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data  = &treo680_gpio_led_info,
+	}
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static struct gpio_led centro_gpio_leds[] = {
+	{
+		.name			= "centro:vibra:vibra",
+		.default_trigger	= "none",
+		.gpio			= GPIO_NR_CENTRO_VIBRATE_EN,
+	},
+	{
+		.name			= "centro:green:led",
+		.default_trigger	= "mmc0",
+		.gpio			= GPIO_NR_TREO_GREEN_LED,
+	},
+	{
+		.name			= "centro:white:keybbl",
+		.default_trigger	= "none",
+		.active_low		= 1,
+		.gpio			= GPIO_NR_CENTRO_KEYB_BL,
+	},
+};
+
+static struct gpio_led_platform_data centro_gpio_led_info = {
+	.leds		= centro_gpio_leds,
+	.num_leds	= ARRAY_SIZE(centro_gpio_leds),
+};
+
+static struct platform_device centro_leds = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data  = &centro_gpio_led_info,
+	}
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+/* TODO: add support for 324x324 */
+static struct pxafb_mode_info treo_lcd_modes[] = {
+{
+	.pixclock		= 86538,
+	.xres			= 320,
+	.yres			= 320,
+	.bpp			= 16,
+
+	.left_margin		= 20,
+	.right_margin		= 8,
+	.upper_margin		= 8,
+	.lower_margin		= 5,
+
+	.hsync_len		= 4,
+	.vsync_len		= 1,
+},
+};
+
+static void treo_lcd_power(int on, struct fb_var_screeninfo *info)
+{
+	gpio_set_value(GPIO_NR_TREO_BL_POWER, on);
+}
+
+static struct pxafb_mach_info treo_lcd_screen = {
+	.modes		= treo_lcd_modes,
+	.num_modes	= ARRAY_SIZE(treo_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+static void __init treo_pm_init(void)
+{
+	static u32 resume[] = {
+		0xe3a00101,	/* mov	r0,	#0x40000000 */
+		0xe380060f,	/* orr	r0, r0, #0x00f00000 */
+		0xe590f008,	/* ldr	pc, [r0, #0x08] */
+	};
+
+	/* this is where the bootloader jumps */
+	memcpy(phys_to_virt(TREO_STR_BASE), resume, sizeof(resume));
+}
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *treo_devices[] __initdata = {
+	&treo_backlight,
+	&power_supply,
+};
+
+#ifdef CONFIG_MACH_TREO680
+static struct platform_device *treo680_devices[] __initdata = {
+	&treo680_leds,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static struct platform_device *centro_devices[] __initdata = {
+	&centro_leds,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/* setup udc GPIOs initial state */
+static void __init treo_udc_init(void)
+{
+	if (!gpio_request(GPIO_NR_TREO_USB_PULLUP, "UDC Vbus")) {
+		gpio_direction_output(GPIO_NR_TREO_USB_PULLUP, 1);
+		gpio_free(GPIO_NR_TREO_USB_PULLUP);
+	}
+}
+
+static void __init treo_lcd_power_init(void)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_TREO_LCD_POWER, "LCD POWER");
+	if (ret) {
+		pr_err("Treo680: LCD power GPIO request failed!\n");
+		return;
+	}
+
+	ret = gpio_direction_output(GPIO_NR_TREO_LCD_POWER, 0);
+	if (ret) {
+		pr_err("Treo680: setting LCD power GPIO direction failed!\n");
+		gpio_free(GPIO_NR_TREO_LCD_POWER);
+		return;
+	}
+
+	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
+}
+
+static void __init treo_init(void)
+{
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
+	treo_pm_init();
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config));
+	treo_lcd_power_init();
+	set_pxa_fb_info(&treo_lcd_screen);
+	treo_udc_init();
+	pxa_set_udc_info(&treo_udc_info);
+	pxa_set_ac97_info(&treo_ac97_pdata);
+	pxa_set_ficp_info(&treo_ficp_info);
+
+	platform_add_devices(ARRAY_AND_SIZE(treo_devices));
+}
+
+#ifdef CONFIG_MACH_TREO680
+static void __init treo680_init(void)
+{
+	treo_init();
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
+	pxa_set_mci_info(&treo680_mci_platform_data);
+	pxa_set_keypad_info(&treo680_keypad_platform_data);
+	pxa_set_ohci_info(&treo680_ohci_info);
+
+	platform_add_devices(ARRAY_AND_SIZE(treo680_devices));
+}
+
+MACHINE_START(TREO680, "Palm Treo 680")
+	.phys_io        = TREO_PHYS_IO_START,
+	.io_pg_offst    = io_p2v(0x40000000),
+	.boot_params    = 0xa0000100,
+	.map_io         = pxa_map_io,
+	.init_irq       = pxa27x_init_irq,
+	.timer          = &pxa_timer,
+	.init_machine   = treo680_init,
+MACHINE_END
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static void __init centro_init(void)
+{
+	treo_init();
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config));
+	pxa_set_mci_info(&centro_mci_platform_data);
+
+	pxa_set_keypad_info(&centro_keypad_platform_data);
+
+	platform_add_devices(ARRAY_AND_SIZE(centro_devices));
+}
+
+MACHINE_START(CENTRO, "Palm Centro 685")
+	.phys_io        = TREO_PHYS_IO_START,
+	.io_pg_offst    = io_p2v(0x40000000),
+	.boot_params    = 0xa0000100,
+	.map_io         = pxa_map_io,
+	.init_irq       = pxa27x_init_irq,
+	.timer          = &pxa_timer,
+       .init_machine   = centro_init,
+MACHINE_END
+#endif /* CONFIG_MACH_CENTRO */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtx.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmtx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmtx.c	2010-02-24 13:52:17.000000000 -0500
@@ -269,7 +269,7 @@ err:
 	return ret;
 }
 
-static int palmtx_backlight_notify(int brightness)
+static int palmtx_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness);
 	gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness);
@@ -570,6 +570,10 @@ static void __init palmtx_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	palmtx_pm_init();
 	set_pxa_fb_info(&palmtx_lcd_screen);
 	pxa_set_mci_info(&palmtx_mci_platform_data);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmz72.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmz72.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/palmz72.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/palmz72.c	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,7 @@ err:
 	return ret;
 }
 
-static int palmz72_backlight_notify(int brightness)
+static int palmz72_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness);
 	gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness);
@@ -491,6 +491,10 @@ static void __init palmz72_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	set_pxa_fb_info(&palmz72_lcd_screen);
 	pxa_set_mci_info(&palmz72_mci_platform_data);
 	palmz72_udc_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pcm027.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm027.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pcm027.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm027.c	2010-02-24 13:52:17.000000000 -0500
@@ -227,6 +227,10 @@ static void __init pcm027_init(void)
 
 	pxa2xx_mfp_config(pcm027_pin_config, ARRAY_SIZE(pcm027_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	/* at last call the baseboard to initialize itself */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2010-02-24 13:52:17.000000000 -0500
@@ -359,19 +359,12 @@ static unsigned long pcm990_camera_pin_c
 	GPIO44_CIF_LV,
 };
 
-static int pcm990_pxacamera_init(struct device *dev)
-{
-	pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
-	return 0;
-}
-
 /*
  * CICR4: PCLK_EN:	Pixel clock is supplied by the sensor
  *	MCLK_EN:	Master clock is generated by PXA
  *	PCP:		Data sampled on the falling edge of pixel clock
  */
 struct pxacamera_platform_data pcm990_pxacamera_platform_data = {
-	.init	= pcm990_pxacamera_init,
 	.flags  = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 |
 		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN/* | PXA_CAMERA_PCP*/,
 	.mclk_10khz = 1000,
@@ -532,6 +525,7 @@ void __init pcm990_baseboard_init(void)
 	pxa_set_ac97_info(NULL);
 
 #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
 	pxa_set_camera_info(&pcm990_pxacamera_platform_data);
 
 	i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/poodle.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/poodle.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/poodle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/poodle.c	2010-02-24 13:52:17.000000000 -0500
@@ -293,7 +293,7 @@ static struct pxamci_platform_data poodl
 	.init 			= poodle_mci_init,
 	.setpower 		= poodle_mci_setpower,
 	.exit			= poodle_mci_exit,
-	.gpio_card_detect	= POODLE_IRQ_GPIO_nSD_DETECT,
+	.gpio_card_detect	= POODLE_GPIO_nSD_DETECT,
 	.gpio_card_ro		= POODLE_GPIO_nSD_WP,
 	.gpio_power		= -1,
 };
@@ -449,6 +449,10 @@ static void __init poodle_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_scoop_config = &poodle_pcmcia_config;
 
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa25x.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa25x.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa25x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa25x.c	2010-02-24 13:52:17.000000000 -0500
@@ -322,9 +322,6 @@ void __init pxa26x_init_irq(void)
 
 static struct platform_device *pxa25x_devices[] __initdata = {
 	&pxa25x_device_udc,
-	&pxa_device_ffuart,
-	&pxa_device_btuart,
-	&pxa_device_stuart,
 	&pxa_device_i2s,
 	&sa1100_device_rtc,
 	&pxa25x_device_ssp,
@@ -372,10 +369,8 @@ static int __init pxa25x_init(void)
 	}
 
 	/* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
-	if (cpu_is_pxa255()) {
+	if (cpu_is_pxa255())
 		clks_register(&pxa25x_hwuart_clkreg, 1);
-		ret = platform_device_register(&pxa_device_hwuart);
-	}
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa27x.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa27x.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa27x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa27x.c	2010-02-24 13:52:17.000000000 -0500
@@ -364,9 +364,6 @@ void __init pxa27x_set_i2c_power_info(st
 
 static struct platform_device *devices[] __initdata = {
 	&pxa27x_device_udc,
-	&pxa_device_ffuart,
-	&pxa_device_btuart,
-	&pxa_device_stuart,
 	&pxa_device_i2s,
 	&sa1100_device_rtc,
 	&pxa_device_rtc,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa3xx.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa3xx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/pxa3xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/pxa3xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <mach/pm.h>
 #include <mach/dma.h>
 #include <mach/ssp.h>
+#include <mach/regs-intc.h>
 #include <plat/i2c.h>
 
 #include "generic.h"
@@ -45,6 +46,9 @@
 #define ACCR_D0CS	(1 << 26)
 #define ACCR_PCCE	(1 << 11)
 
+#define PECR_IE(n)	((1 << ((n) * 2)) << 28)
+#define PECR_IS(n)	((1 << ((n) * 2)) << 29)
+
 /* crystal frequency to static memory controller multiplier (SMCFS) */
 static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
 
@@ -237,6 +241,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_stuart, S
 static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0);
 static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5);
 static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_u2d, USB2, 48000000, 0);
 static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0);
 static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0);
 static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0);
@@ -261,6 +266,7 @@ static struct clk_lookup pxa3xx_clkregs[
 	INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
 	INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
 	INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
+	INIT_CLKREG(&clk_pxa3xx_u2d, NULL, "U2DCLK"),
 	INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
 	INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
 	INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
@@ -530,6 +536,43 @@ static inline void pxa3xx_init_pm(void)
 #define pxa3xx_set_wake	NULL
 #endif
 
+static void pxa_ack_ext_wakeup(unsigned int irq)
+{
+	PECR |= PECR_IS(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_mask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 &= ~(1 << ((irq - PXA_IRQ(0)) & 0x1f));
+	PECR &= ~PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static void pxa_unmask_ext_wakeup(unsigned int irq)
+{
+	ICMR2 |= 1 << ((irq - PXA_IRQ(0)) & 0x1f);
+	PECR |= PECR_IE(irq - IRQ_WAKEUP0);
+}
+
+static struct irq_chip pxa_ext_wakeup_chip = {
+	.name		= "WAKEUP",
+	.ack		= pxa_ack_ext_wakeup,
+	.mask		= pxa_mask_ext_wakeup,
+	.unmask		= pxa_unmask_ext_wakeup,
+};
+
+static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
+{
+	int irq;
+
+	for (irq = IRQ_WAKEUP0; irq <= IRQ_WAKEUP1; irq++) {
+		set_irq_chip(irq, &pxa_ext_wakeup_chip);
+		set_irq_handler(irq, handle_edge_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	pxa_ext_wakeup_chip.set_wake = fn;
+}
+
 void __init pxa3xx_init_irq(void)
 {
 	/* enable CP6 access */
@@ -539,6 +582,7 @@ void __init pxa3xx_init_irq(void)
 	__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
 
 	pxa_init_irq(56, pxa3xx_set_wake);
+	pxa_init_ext_wakeup_irq(pxa3xx_set_wake);
 	pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
 }
 
@@ -553,9 +597,6 @@ void __init pxa3xx_set_i2c_power_info(st
 
 static struct platform_device *devices[] __initdata = {
 	&pxa27x_device_udc,
-	&pxa_device_ffuart,
-	&pxa_device_btuart,
-	&pxa_device_stuart,
 	&pxa_device_i2s,
 	&sa1100_device_rtc,
 	&pxa_device_rtc,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/saar.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/saar.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/saar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/saar.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,9 +22,13 @@
 #include <linux/i2c.h>
 #include <linux/smc91x.h>
 #include <linux/mfd/da903x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
 
 #include <mach/pxa930.h>
 #include <plat/i2c.h>
@@ -33,7 +37,7 @@
 #include "devices.h"
 #include "generic.h"
 
-#define GPIO_LCD_RESET	(16)
+#define GPIO_LCD_RESET		(16)
 
 /* SAAR MFP configurations */
 static mfp_cfg_t saar_mfp_cfg[] __initdata = {
@@ -56,6 +60,31 @@ static mfp_cfg_t saar_mfp_cfg[] __initda
 	/* Ethernet */
 	DF_nCS1_nCS3,
 	GPIO97_GPIO,
+
+	/* DFI */
+	DF_INT_RnB_ND_INT_RnB,
+	DF_nRE_nOE_ND_nRE,
+	DF_nWE_ND_nWE,
+	DF_CLE_nOE_ND_CLE,
+	DF_nADV1_ALE_ND_ALE,
+	DF_nADV2_ALE_nCS3,
+	DF_nCS0_ND_nCS0,
+	DF_IO0_ND_IO0,
+	DF_IO1_ND_IO1,
+	DF_IO2_ND_IO2,
+	DF_IO3_ND_IO3,
+	DF_IO4_ND_IO4,
+	DF_IO5_ND_IO5,
+	DF_IO6_ND_IO6,
+	DF_IO7_ND_IO7,
+	DF_IO8_ND_IO8,
+	DF_IO9_ND_IO9,
+	DF_IO10_ND_IO10,
+	DF_IO11_ND_IO11,
+	DF_IO12_ND_IO12,
+	DF_IO13_ND_IO13,
+	DF_IO14_ND_IO14,
+	DF_IO15_ND_IO15,
 };
 
 #define SAAR_ETH_PHYS	(0x14000000)
@@ -451,10 +480,15 @@ static inline void saar_init_lcd(void) {
 #endif
 
 #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct da9034_backlight_pdata saar_da9034_backlight = {
+	.output_current	= 4,	/* 4mA */
+};
+
 static struct da903x_subdev_info saar_da9034_subdevs[] = {
 	[0] = {
 		.name		= "da903x-backlight",
 		.id		= DA9034_ID_WLED,
+		.platform_data	= &saar_da9034_backlight,
 	},
 };
 
@@ -480,12 +514,81 @@ static void __init saar_init_i2c(void)
 #else
 static inline void saar_init_i2c(void) {}
 #endif
+
+#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
+static struct mtd_partition saar_onenand_partitions[] = {
+	{
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_1M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "reserved",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_8M,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= (SZ_2M + SZ_1M),
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_48M,
+		.mask_flags	= 0,
+	}
+};
+
+static struct onenand_platform_data saar_onenand_info = {
+	.parts		= saar_onenand_partitions,
+	.nr_parts	= ARRAY_SIZE(saar_onenand_partitions),
+};
+
+#define SMC_CS0_PHYS_BASE	(0x10000000)
+
+static struct resource saar_resource_onenand[] = {
+	[0] = {
+		.start	= SMC_CS0_PHYS_BASE,
+		.end	= SMC_CS0_PHYS_BASE + SZ_1M,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device saar_device_onenand = {
+	.name		= "onenand-flash",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &saar_onenand_info,
+	},
+	.resource	= saar_resource_onenand,
+	.num_resources	= ARRAY_SIZE(saar_resource_onenand),
+};
+
+static void __init saar_init_onenand(void)
+{
+	platform_device_register(&saar_device_onenand);
+}
+#else
+static void __init saar_init_onenand(void) {}
+#endif
+
 static void __init saar_init(void)
 {
 	/* initialize MFP configurations */
 	pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_device_register(&smc91x_device);
+	saar_init_onenand();
 
 	saar_init_i2c();
 	saar_init_lcd();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/sharpsl.h linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/sharpsl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,8 +42,8 @@ void corgi_lcdtg_hw_init(int mode);
 #define MAX1111_BATT_TEMP   2u
 #define MAX1111_ACIN_VOLT   6u
 
-extern struct battery_thresh spitz_battery_levels_acin[];
-extern struct battery_thresh spitz_battery_levels_noac[];
+extern struct battery_thresh sharpsl_battery_levels_acin[];
+extern struct battery_thresh sharpsl_battery_levels_noac[];
 int sharpsl_pm_pxa_read_max1111(int channel);
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/sharpsl_pm.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl_pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,7 +78,7 @@ DEFINE_LED_TRIGGER(sharpsl_charge_led_tr
 
 
 
-struct battery_thresh spitz_battery_levels_acin[] = {
+struct battery_thresh sharpsl_battery_levels_acin[] = {
 	{ 213, 100},
 	{ 212,  98},
 	{ 211,  95},
@@ -121,7 +121,7 @@ struct battery_thresh spitz_battery_leve
 	{   0,   0},
 };
 
-struct battery_thresh  spitz_battery_levels_noac[] = {
+struct battery_thresh sharpsl_battery_levels_noac[] = {
 	{ 213, 100},
 	{ 212,  98},
 	{ 211,  95},
@@ -165,19 +165,20 @@ struct battery_thresh  spitz_battery_lev
 };
 
 /* MAX1111 Commands */
-#define MAXCTRL_PD0      1u << 0
-#define MAXCTRL_PD1      1u << 1
-#define MAXCTRL_SGL      1u << 2
-#define MAXCTRL_UNI      1u << 3
+#define MAXCTRL_PD0      (1u << 0)
+#define MAXCTRL_PD1      (1u << 1)
+#define MAXCTRL_SGL      (1u << 2)
+#define MAXCTRL_UNI      (1u << 3)
 #define MAXCTRL_SEL_SH   4
-#define MAXCTRL_STR      1u << 7
+#define MAXCTRL_STR      (1u << 7)
 
 /*
  * Read MAX1111 ADC
  */
 int sharpsl_pm_pxa_read_max1111(int channel)
 {
-	if (machine_is_tosa()) // Ugly, better move this function into another module
+	/* Ugly, better move this function into another module */
+	if (machine_is_tosa())
 	    return 0;
 
 #ifdef CONFIG_CORGI_SSP_DEPRECATED
@@ -238,7 +239,7 @@ EXPORT_SYMBOL(sharpsl_battery_kick);
 
 static void sharpsl_battery_thread(struct work_struct *private_)
 {
-	int voltage, percent, apm_status, i = 0;
+	int voltage, percent, apm_status, i;
 
 	if (!sharpsl_pm.machinfo)
 		return;
@@ -250,15 +251,14 @@ static void sharpsl_battery_thread(struc
 			&& time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
 		schedule_delayed_work(&toggle_charger, 0);
 
-	while(1) {
+	for (i = 0; i < 5; i++) {
 		voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
-
-		if (voltage > 0) break;
-		if (i++ > 5) {
-			voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
-			dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+		if (voltage > 0)
 			break;
-		}
+	}
+	if (voltage <= 0) {
+		voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+		dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
 	}
 
 	voltage = sharpsl_average_value(voltage);
@@ -266,8 +266,10 @@ static void sharpsl_battery_thread(struc
 	percent = get_percentage(voltage);
 
 	/* At low battery voltages, the voltage has a tendency to start
-           creeping back up so we try to avoid this here */
-	if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) ||  percent <= sharpsl_pm.battstat.mainbat_percent) {
+	   creeping back up so we try to avoid this here */
+	if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE)
+	    || (apm_status == APM_BATTERY_STATUS_HIGH)
+	    || percent <= sharpsl_pm.battstat.mainbat_percent) {
 		sharpsl_pm.battstat.mainbat_voltage = voltage;
 		sharpsl_pm.battstat.mainbat_status = apm_status;
 		sharpsl_pm.battstat.mainbat_percent = percent;
@@ -279,8 +281,8 @@ static void sharpsl_battery_thread(struc
 #ifdef CONFIG_BACKLIGHT_CORGI
 	/* If battery is low. limit backlight intensity to save power. */
 	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-			&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
-			(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
+	    && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW)
+	    || (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
 		if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
 			sharpsl_pm.machinfo->backlight_limit(1);
 			sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
@@ -293,8 +295,8 @@ static void sharpsl_battery_thread(struc
 
 	/* Suspend if critical battery level */
 	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-			&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
-			&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+	     && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+	     && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
 		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
 		dev_err(sharpsl_pm.dev, "Fatal Off\n");
 		apm_queue_event(APM_CRITICAL_SUSPEND);
@@ -346,7 +348,7 @@ static void sharpsl_charge_error(void)
 
 static void sharpsl_charge_toggle(struct work_struct *private_)
 {
-	dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
+	dev_dbg(sharpsl_pm.dev, "Toggling Charger at time: %lx\n", jiffies);
 
 	if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
 		sharpsl_charge_off();
@@ -368,7 +370,7 @@ static void sharpsl_ac_timer(unsigned lo
 {
 	int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
-	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
+	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n", acin);
 
 	sharpsl_average_clear();
 	if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
@@ -472,14 +474,14 @@ static int sharpsl_average_value(int ad)
 	sharpsl_ad[sharpsl_ad_index] = ad;
 	sharpsl_ad_index++;
 	if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
-		for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+		for (i = 0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
 			sharpsl_ad[i] = sharpsl_ad[i+1];
 		sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
 	}
-	for (i=0; i < sharpsl_ad_index; i++)
+	for (i = 0; i < sharpsl_ad_index; i++)
 		ad_val += sharpsl_ad[i];
 
-	return (ad_val / sharpsl_ad_index);
+	return ad_val / sharpsl_ad_index;
 }
 
 /*
@@ -492,8 +494,8 @@ static int get_select_val(int *val)
 
 	/* Find MAX val */
 	temp = val[0];
-	j=0;
-	for (i=1; i<5; i++) {
+	j = 0;
+	for (i = 1; i < 5; i++) {
 		if (temp < val[i]) {
 			temp = val[i];
 			j = i;
@@ -502,21 +504,21 @@ static int get_select_val(int *val)
 
 	/* Find MIN val */
 	temp = val[4];
-	k=4;
-	for (i=3; i>=0; i--) {
+	k = 4;
+	for (i = 3; i >= 0; i--) {
 		if (temp > val[i]) {
 			temp = val[i];
 			k = i;
 		}
 	}
 
-	for (i=0; i<5; i++)
-		if (i != j && i != k )
+	for (i = 0; i < 5; i++)
+		if (i != j && i != k)
 			sum += val[i];
 
 	dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
 
-	return (sum/3);
+	return sum/3;
 }
 
 static int sharpsl_check_battery_temp(void)
@@ -524,7 +526,7 @@ static int sharpsl_check_battery_temp(vo
 	int val, i, buff[5];
 
 	/* Check battery temperature */
-	for (i=0; i<5; i++) {
+	for (i = 0; i < 5; i++) {
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
 		sharpsl_pm.machinfo->measure_temp(1);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
@@ -557,7 +559,7 @@ static int sharpsl_check_battery_voltage
 		sharpsl_pm.machinfo->discharge1(1);
 
 	/* Check battery voltage */
-	for (i=0; i<5; i++) {
+	for (i = 0; i < 5; i++) {
 		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
 	}
@@ -581,16 +583,16 @@ static int sharpsl_ac_check(void)
 {
 	int temp, i, buff[5];
 
-	for (i=0; i<5; i++) {
+	for (i = 0; i < 5; i++) {
 		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
 	}
 
 	temp = get_select_val(buff);
-	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
+	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n", temp);
 
 	if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
-		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
+		dev_err(sharpsl_pm.dev, "Error: AC check failed: voltage %d.\n", temp);
 		return -1;
 	}
 
@@ -624,9 +626,9 @@ static int sharpsl_pm_resume(struct plat
 
 static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
 {
-	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
+	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR);
 
-	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
 	/* not charging and AC-IN! */
 
 	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
@@ -644,12 +646,12 @@ static void corgi_goto_sleep(unsigned lo
 	if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
 		RTSR &= RTSR_ALE;
 		RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
-		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
+		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR);
 		sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
 	} else if (alarm_enable) {
 		RTSR &= RTSR_ALE;
 		RTAR = alarm_time;
-		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
+		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR);
 	} else {
 		dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
 	}
@@ -658,19 +660,18 @@ static void corgi_goto_sleep(unsigned lo
 
 	sharpsl_pm.machinfo->postsuspend();
 
-	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
+	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR);
 }
 
 static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
 {
-	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
-	{
+	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) {
 		if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
 			dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
 			corgi_goto_sleep(alarm_time, alarm_enable, state);
 			return 1;
 		}
-		if(sharpsl_off_charge_battery()) {
+		if (sharpsl_off_charge_battery()) {
 			dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
 			corgi_goto_sleep(alarm_time, alarm_enable, state);
 			return 1;
@@ -697,7 +698,7 @@ static int corgi_pxa_pm_enter(suspend_st
 
 	corgi_goto_sleep(alarm_time, alarm_status, state);
 
-	while (corgi_enter_suspend(alarm_time,alarm_status,state))
+	while (corgi_enter_suspend(alarm_time, alarm_status, state))
 		{}
 
 	if (sharpsl_pm.machinfo->earlyresume)
@@ -732,7 +733,7 @@ static int sharpsl_fatal_check(void)
 		sharpsl_pm.machinfo->discharge1(1);
 
 	/* Check battery : check inserting battery ? */
-	for (i=0; i<5; i++) {
+	for (i = 0; i < 5; i++) {
 		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
 	}
@@ -812,7 +813,7 @@ static int sharpsl_off_charge_battery(vo
 		mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
 
 		time = RCNR;
-		while(1) {
+		while (1) {
 			/* Check if any wakeup event had occurred */
 			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
 				return 0;
@@ -835,9 +836,9 @@ static int sharpsl_off_charge_battery(vo
 	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
 
 	time = RCNR;
-	while(1) {
+	while (1) {
 		/* Check if any wakeup event had occurred */
-		if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+		if (sharpsl_pm.machinfo->charger_wakeup())
 			return 0;
 		/* Check for timeout */
 		if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
@@ -864,12 +865,12 @@ static int sharpsl_off_charge_battery(vo
 
 static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
+	return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent);
 }
 
 static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
+	return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage);
 }
 
 static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
@@ -943,8 +944,7 @@ static int __init sharpsl_pm_probe(struc
 		}
 	}
 
-	if (sharpsl_pm.machinfo->batfull_irq)
-	{
+	if (sharpsl_pm.machinfo->batfull_irq) {
 		/* Register interrupt handler. */
 		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
 			dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/spitz.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/spitz.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz.c	2010-02-24 13:52:17.000000000 -0500
@@ -389,13 +389,13 @@ static struct gpio_keys_button spitz_gpi
 		.type	= EV_SW,
 		.code	= 0,
 		.gpio	= SPITZ_GPIO_SWA,
-		.desc	= "﻿Display Down",
+		.desc	= "Display Down",
 	},
 	{
 		.type	= EV_SW,
 		.code	= 1,
 		.gpio	= SPITZ_GPIO_SWB,
-		.desc	= "﻿Lid Closed",
+		.desc	= "Lid Closed",
 	},
 };
 
@@ -768,6 +768,10 @@ static void __init common_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	spitz_init_spi();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/spitz_pm.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz_pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/spitz_pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/spitz_pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,7 @@ static void spitz_presuspend(void)
 	PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
 	PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
 	PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
-	PKSR = 0xffffffff; // clear
+	PKSR = 0xffffffff; /* clear */
 
 	/* nRESET_OUT Disable */
 	PSLR |= PSLR_SL_ROD;
@@ -149,7 +149,7 @@ static int spitz_should_wakeup(unsigned
 	if (resume_on_alarm && (PEDR & PWER_RTC))
 		is_resume |= PWER_RTC;
 
-	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n", is_resume);
 	return is_resume;
 }
 
@@ -160,7 +160,7 @@ static unsigned long spitz_charger_wakeu
 
 unsigned long spitzpm_read_devdata(int type)
 {
-	switch(type) {
+	switch (type) {
 	case SHARPSL_STATUS_ACIN:
 		return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
 	case SHARPSL_STATUS_LOCK:
@@ -199,7 +199,7 @@ struct sharpsl_charger_machinfo spitz_pm
 #if defined(CONFIG_LCD_CORGI)
 	.backlight_limit = corgi_lcd_limit_intensity,
 #elif defined(CONFIG_BACKLIGHT_CORGI)
-        .backlight_limit  = corgibl_limit_intensity,
+	.backlight_limit  = corgibl_limit_intensity,
 #endif
 	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
 	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
@@ -208,8 +208,8 @@ struct sharpsl_charger_machinfo spitz_pm
 	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
 	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
 	.bat_levels       = 40,
-	.bat_levels_noac  = spitz_battery_levels_noac,
-	.bat_levels_acin  = spitz_battery_levels_acin,
+	.bat_levels_noac  = sharpsl_battery_levels_noac,
+	.bat_levels_acin  = sharpsl_battery_levels_acin,
 	.status_high_acin = 188,
 	.status_low_acin  = 178,
 	.status_high_noac = 185,
@@ -241,7 +241,7 @@ static int __devinit spitzpm_init(void)
 
 static void spitzpm_exit(void)
 {
- 	platform_device_unregister(spitzpm_device);
+	platform_device_unregister(spitzpm_device);
 }
 
 module_init(spitzpm_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/ssp.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ssp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/ssp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/ssp.c	2010-02-24 13:52:17.000000000 -0500
@@ -342,8 +342,9 @@ void ssp_free(struct ssp_device *ssp)
 }
 EXPORT_SYMBOL(ssp_free);
 
-static int __devinit ssp_probe(struct platform_device *pdev, int type)
+static int __devinit ssp_probe(struct platform_device *pdev)
 {
+	const struct platform_device_id *id = platform_get_device_id(pdev);
 	struct resource *res;
 	struct ssp_device *ssp;
 	int ret = 0;
@@ -413,7 +414,7 @@ static int __devinit ssp_probe(struct pl
 	 */
 	ssp->port_id = pdev->id + 1;
 	ssp->use_count = 0;
-	ssp->type = type;
+	ssp->type = (int)id->driver_data;
 
 	mutex_lock(&ssp_lock);
 	list_add(&ssp->node, &ssp_list);
@@ -457,75 +458,31 @@ static int __devexit ssp_remove(struct p
 	return 0;
 }
 
-static int __devinit pxa25x_ssp_probe(struct platform_device *pdev)
-{
-	return ssp_probe(pdev, PXA25x_SSP);
-}
-
-static int __devinit pxa25x_nssp_probe(struct platform_device *pdev)
-{
-	return ssp_probe(pdev, PXA25x_NSSP);
-}
-
-static int __devinit pxa27x_ssp_probe(struct platform_device *pdev)
-{
-	return ssp_probe(pdev, PXA27x_SSP);
-}
-
-static struct platform_driver pxa25x_ssp_driver = {
-	.driver		= {
-		.name	= "pxa25x-ssp",
-	},
-	.probe		= pxa25x_ssp_probe,
-	.remove		= __devexit_p(ssp_remove),
+static const struct platform_device_id ssp_id_table[] = {
+	{ "pxa25x-ssp",		PXA25x_SSP },
+	{ "pxa25x-nssp",	PXA25x_NSSP },
+	{ "pxa27x-ssp",		PXA27x_SSP },
+	{ },
 };
 
-static struct platform_driver pxa25x_nssp_driver = {
-	.driver		= {
-		.name	= "pxa25x-nssp",
-	},
-	.probe		= pxa25x_nssp_probe,
+static struct platform_driver ssp_driver = {
+	.probe		= ssp_probe,
 	.remove		= __devexit_p(ssp_remove),
-};
-
-static struct platform_driver pxa27x_ssp_driver = {
 	.driver		= {
-		.name	= "pxa27x-ssp",
+		.owner	= THIS_MODULE,
+		.name	= "pxa2xx-ssp",
 	},
-	.probe		= pxa27x_ssp_probe,
-	.remove		= __devexit_p(ssp_remove),
+	.id_table	= ssp_id_table,
 };
 
 static int __init pxa_ssp_init(void)
 {
-	int ret = 0;
-
-	ret = platform_driver_register(&pxa25x_ssp_driver);
-	if (ret) {
-		printk(KERN_ERR "failed to register pxa25x_ssp_driver");
-		return ret;
-	}
-
-	ret = platform_driver_register(&pxa25x_nssp_driver);
-	if (ret) {
-		printk(KERN_ERR "failed to register pxa25x_nssp_driver");
-		return ret;
-	}
-
-	ret = platform_driver_register(&pxa27x_ssp_driver);
-	if (ret) {
-		printk(KERN_ERR "failed to register pxa27x_ssp_driver");
-		return ret;
-	}
-
-	return ret;
+	return platform_driver_register(&ssp_driver);
 }
 
 static void __exit pxa_ssp_exit(void)
 {
-	platform_driver_unregister(&pxa25x_ssp_driver);
-	platform_driver_unregister(&pxa25x_nssp_driver);
-	platform_driver_unregister(&pxa27x_ssp_driver);
+	platform_driver_unregister(&ssp_driver);
 }
 
 arch_initcall(pxa_ssp_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/stargate2.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/stargate2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/stargate2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/stargate2.c	2010-02-24 13:52:17.000000000 -0500
@@ -760,6 +760,10 @@ static void __init stargate2_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	/* spi chip selects */
 	gpio_direction_output(37, 0);
 	gpio_direction_output(24, 0);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/tavorevb.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tavorevb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/tavorevb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tavorevb.c	2010-02-24 13:52:17.000000000 -0500
@@ -477,6 +477,10 @@ static void __init tavorevb_init(void)
 	/* initialize MFP configurations */
 	pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	platform_device_register(&smc91x_device);
 
 	tavorevb_init_lcd();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/tosa.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tosa.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/tosa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/tosa.c	2010-02-24 13:52:17.000000000 -0500
@@ -825,6 +825,11 @@ static void __init tosa_init(void)
 	int dummy;
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
+
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	gpio_set_wake(MFP_PIN_GPIO1, 1);
 	/* We can't pass to gpio-keys since it will drop the Reset altfunc */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/treo680.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/treo680.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/treo680.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/treo680.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,519 +0,0 @@
-/*
- * Hardware definitions for Palm Treo 680
- *
- * Author:     Tomas Cech <sleep_walker@suse.cz>
- *
- * This 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.
- *
- * (find more info at www.hackndev.com)
- *
- */
-
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <linux/pda_power.h>
-#include <linux/pwm_backlight.h>
-#include <linux/gpio.h>
-#include <linux/wm97xx_batt.h>
-#include <linux/power_supply.h>
-#include <linux/sysdev.h>
-#include <linux/w1-gpio.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/pxa27x.h>
-#include <mach/pxa27x-udc.h>
-#include <mach/audio.h>
-#include <mach/treo680.h>
-#include <mach/mmc.h>
-#include <mach/pxafb.h>
-#include <mach/irda.h>
-#include <mach/pxa27x_keypad.h>
-#include <mach/udc.h>
-#include <mach/ohci.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/palmasoc.h>
-#include <mach/camera.h>
-
-#include <sound/pxa2xx-lib.h>
-
-#include "generic.h"
-#include "devices.h"
-
-/******************************************************************************
- * Pin configuration
- ******************************************************************************/
-static unsigned long treo680_pin_config[] __initdata = {
-	/* MMC */
-	GPIO32_MMC_CLK,
-	GPIO92_MMC_DAT_0,
-	GPIO109_MMC_DAT_1,
-	GPIO110_MMC_DAT_2,
-	GPIO111_MMC_DAT_3,
-	GPIO112_MMC_CMD,
-	GPIO33_GPIO,				/* SD read only */
-	GPIO113_GPIO,				/* SD detect */
-
-	/* AC97 */
-	GPIO28_AC97_BITCLK,
-	GPIO29_AC97_SDATA_IN_0,
-	GPIO30_AC97_SDATA_OUT,
-	GPIO31_AC97_SYNC,
-	GPIO89_AC97_SYSCLK,
-	GPIO95_AC97_nRESET,
-
-	/* IrDA */
-	GPIO46_FICP_RXD,
-	GPIO47_FICP_TXD,
-
-	/* PWM */
-	GPIO16_PWM0_OUT,
-
-	/* USB */
-	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,	/* usb detect */
-
-	/* MATRIX KEYPAD */
-	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
-	GPIO101_KP_MKIN_1,
-	GPIO102_KP_MKIN_2,
-	GPIO97_KP_MKIN_3,
-	GPIO98_KP_MKIN_4,
-	GPIO99_KP_MKIN_5,
-	GPIO91_KP_MKIN_6,
-	GPIO13_KP_MKIN_7,
-	GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
-	GPIO104_KP_MKOUT_1,
-	GPIO105_KP_MKOUT_2,
-	GPIO106_KP_MKOUT_3,
-	GPIO107_KP_MKOUT_4,
-	GPIO108_KP_MKOUT_5,
-	GPIO96_KP_MKOUT_6,
-	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,	/* Hotsync button */
-
-	/* LCD */
-	GPIO58_LCD_LDD_0,
-	GPIO59_LCD_LDD_1,
-	GPIO60_LCD_LDD_2,
-	GPIO61_LCD_LDD_3,
-	GPIO62_LCD_LDD_4,
-	GPIO63_LCD_LDD_5,
-	GPIO64_LCD_LDD_6,
-	GPIO65_LCD_LDD_7,
-	GPIO66_LCD_LDD_8,
-	GPIO67_LCD_LDD_9,
-	GPIO68_LCD_LDD_10,
-	GPIO69_LCD_LDD_11,
-	GPIO70_LCD_LDD_12,
-	GPIO71_LCD_LDD_13,
-	GPIO72_LCD_LDD_14,
-	GPIO73_LCD_LDD_15,
-	GPIO74_LCD_FCLK,
-	GPIO75_LCD_LCLK,
-	GPIO76_LCD_PCLK,
-
-	/* Quick Capture Interface */
-	GPIO84_CIF_FV,
-	GPIO85_CIF_LV,
-	GPIO53_CIF_MCLK,
-	GPIO54_CIF_PCLK,
-	GPIO81_CIF_DD_0,
-	GPIO55_CIF_DD_1,
-	GPIO51_CIF_DD_2,
-	GPIO50_CIF_DD_3,
-	GPIO52_CIF_DD_4,
-	GPIO48_CIF_DD_5,
-	GPIO17_CIF_DD_6,
-	GPIO12_CIF_DD_7,
-
-	/* I2C */
-	GPIO117_I2C_SCL,
-	GPIO118_I2C_SDA,
-
-	/* GSM */
-	GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,	/* GSM host wake up */
-	GPIO34_FFUART_RXD,
-	GPIO35_FFUART_CTS,
-	GPIO39_FFUART_TXD,
-	GPIO41_FFUART_RTS,
-
-	/* MISC. */
-	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* external power detect */
-	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,	/* silent switch */
-	GPIO116_GPIO,				/* headphone detect */
-	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* bluetooth host wake up */
-};
-
-/******************************************************************************
- * SD/MMC card controller
- ******************************************************************************/
-static struct pxamci_platform_data treo680_mci_platform_data = {
-	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.gpio_card_detect	= GPIO_NR_TREO680_SD_DETECT_N,
-	.gpio_card_ro		= GPIO_NR_TREO680_SD_READONLY,
-	.gpio_power		= GPIO_NR_TREO680_SD_POWER,
-};
-
-/******************************************************************************
- * GPIO keyboard
- ******************************************************************************/
-static unsigned int treo680_matrix_keys[] = {
-	KEY(0, 0, KEY_F8),		/* Red/Off/Power */
-	KEY(0, 1, KEY_LEFT),
-	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
-	KEY(0, 3, KEY_L),
-	KEY(0, 4, KEY_A),
-	KEY(0, 5, KEY_Q),
-	KEY(0, 6, KEY_P),
-
-	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
-	KEY(1, 1, KEY_RIGHT),
-	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
-	KEY(1, 3, KEY_Z),
-	KEY(1, 4, KEY_S),
-	KEY(1, 5, KEY_W),
-
-	KEY(2, 0, KEY_F1),		/* Phone */
-	KEY(2, 1, KEY_UP),
-	KEY(2, 2, KEY_0),
-	KEY(2, 3, KEY_X),
-	KEY(2, 4, KEY_D),
-	KEY(2, 5, KEY_E),
-
-	KEY(3, 0, KEY_F10),		/* Calendar */
-	KEY(3, 1, KEY_DOWN),
-	KEY(3, 2, KEY_SPACE),
-	KEY(3, 3, KEY_C),
-	KEY(3, 4, KEY_F),
-	KEY(3, 5, KEY_R),
-
-	KEY(4, 0, KEY_F12),		/* Mail */
-	KEY(4, 1, KEY_KPENTER),
-	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
-	KEY(4, 3, KEY_V),
-	KEY(4, 4, KEY_G),
-	KEY(4, 5, KEY_T),
-
-	KEY(5, 0, KEY_F9),		/* Home */
-	KEY(5, 1, KEY_PAGEUP),		/* Side up */
-	KEY(5, 2, KEY_DOT),
-	KEY(5, 3, KEY_B),
-	KEY(5, 4, KEY_H),
-	KEY(5, 5, KEY_Y),
-
-	KEY(6, 0, KEY_TAB),		/* Side Activate */
-	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
-	KEY(6, 2, KEY_ENTER),
-	KEY(6, 3, KEY_N),
-	KEY(6, 4, KEY_J),
-	KEY(6, 5, KEY_U),
-
-	KEY(7, 0, KEY_F6),		/* Green/Call */
-	KEY(7, 1, KEY_O),
-	KEY(7, 2, KEY_BACKSPACE),
-	KEY(7, 3, KEY_M),
-	KEY(7, 4, KEY_K),
-	KEY(7, 5, KEY_I),
-};
-
-static struct pxa27x_keypad_platform_data treo680_keypad_platform_data = {
-	.matrix_key_rows	= 8,
-	.matrix_key_cols	= 7,
-	.matrix_key_map		= treo680_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(treo680_matrix_keys),
-	.direct_key_map		= { KEY_CONNECT },
-	.direct_key_num		= 1,
-
-	.debounce_interval	= 30,
-};
-
-/******************************************************************************
- * aSoC audio
- ******************************************************************************/
-
-static pxa2xx_audio_ops_t treo680_ac97_pdata = {
-	.reset_gpio	= 95,
-};
-
-/******************************************************************************
- * Backlight
- ******************************************************************************/
-static int treo680_backlight_init(struct device *dev)
-{
-	int ret;
-
-	ret = gpio_request(GPIO_NR_TREO680_BL_POWER, "BL POWER");
-	if (ret)
-		goto err;
-	ret = gpio_direction_output(GPIO_NR_TREO680_BL_POWER, 0);
-	if (ret)
-		goto err2;
-
-	return 0;
-
-err2:
-	gpio_free(GPIO_NR_TREO680_BL_POWER);
-err:
-	return ret;
-}
-
-static int treo680_backlight_notify(int brightness)
-{
-	gpio_set_value(GPIO_NR_TREO680_BL_POWER, brightness);
-	return TREO680_MAX_INTENSITY - brightness;
-};
-
-static void treo680_backlight_exit(struct device *dev)
-{
-	gpio_free(GPIO_NR_TREO680_BL_POWER);
-}
-
-static struct platform_pwm_backlight_data treo680_backlight_data = {
-	.pwm_id		= 0,
-	.max_brightness	= TREO680_MAX_INTENSITY,
-	.dft_brightness	= TREO680_DEFAULT_INTENSITY,
-	.pwm_period_ns	= TREO680_PERIOD_NS,
-	.init		= treo680_backlight_init,
-	.notify		= treo680_backlight_notify,
-	.exit		= treo680_backlight_exit,
-};
-
-static struct platform_device treo680_backlight = {
-	.name	= "pwm-backlight",
-	.dev	= {
-		.parent		= &pxa27x_device_pwm0.dev,
-		.platform_data	= &treo680_backlight_data,
-	},
-};
-
-/******************************************************************************
- * IrDA
- ******************************************************************************/
-static struct pxaficp_platform_data treo680_ficp_info = {
-	.gpio_pwdown		= GPIO_NR_TREO680_IR_EN,
-	.transceiver_cap	= IR_SIRMODE | IR_OFF,
-};
-
-/******************************************************************************
- * UDC
- ******************************************************************************/
-static struct pxa2xx_udc_mach_info treo680_udc_info __initdata = {
-	.gpio_vbus		= GPIO_NR_TREO680_USB_DETECT,
-	.gpio_vbus_inverted	= 1,
-	.gpio_pullup		= GPIO_NR_TREO680_USB_PULLUP,
-};
-
-
-/******************************************************************************
- * USB host
- ******************************************************************************/
-static struct pxaohci_platform_data treo680_ohci_info = {
-	.port_mode    = PMM_PERPORT_MODE,
-	.flags        = ENABLE_PORT1 | ENABLE_PORT3,
-	.power_budget = 0,
-};
-
-/******************************************************************************
- * Power supply
- ******************************************************************************/
-static int power_supply_init(struct device *dev)
-{
-	int ret;
-
-	ret = gpio_request(GPIO_NR_TREO680_POWER_DETECT, "CABLE_STATE_AC");
-	if (ret)
-		goto err1;
-	ret = gpio_direction_input(GPIO_NR_TREO680_POWER_DETECT);
-	if (ret)
-		goto err2;
-
-	return 0;
-
-err2:
-	gpio_free(GPIO_NR_TREO680_POWER_DETECT);
-err1:
-	return ret;
-}
-
-static int treo680_is_ac_online(void)
-{
-	return gpio_get_value(GPIO_NR_TREO680_POWER_DETECT);
-}
-
-static void power_supply_exit(struct device *dev)
-{
-	gpio_free(GPIO_NR_TREO680_POWER_DETECT);
-}
-
-static char *treo680_supplicants[] = {
-	"main-battery",
-};
-
-static struct pda_power_pdata power_supply_info = {
-	.init		 = power_supply_init,
-	.is_ac_online    = treo680_is_ac_online,
-	.exit		 = power_supply_exit,
-	.supplied_to     = treo680_supplicants,
-	.num_supplicants = ARRAY_SIZE(treo680_supplicants),
-};
-
-static struct platform_device power_supply = {
-	.name = "pda-power",
-	.id   = -1,
-	.dev  = {
-		.platform_data = &power_supply_info,
-	},
-};
-
-/******************************************************************************
- * Vibra and LEDs
- ******************************************************************************/
-static struct gpio_led gpio_leds[] = {
-	{
-		.name			= "treo680:vibra:vibra",
-		.default_trigger	= "none",
-		.gpio			= GPIO_NR_TREO680_VIBRATE_EN,
-	},
-	{
-		.name			= "treo680:green:led",
-		.default_trigger	= "mmc0",
-		.gpio			= GPIO_NR_TREO680_GREEN_LED,
-	},
-	{
-		.name			= "treo680:keybbl:keybbl",
-		.default_trigger	= "none",
-		.gpio			= GPIO_NR_TREO680_KEYB_BL,
-	},
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
-	.leds		= gpio_leds,
-	.num_leds	= ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device treo680_leds = {
-	.name   = "leds-gpio",
-	.id     = -1,
-	.dev    = {
-		.platform_data  = &gpio_led_info,
-	}
-};
-
-
-/******************************************************************************
- * Framebuffer
- ******************************************************************************/
-/* TODO: add support for 324x324 */
-static struct pxafb_mode_info treo680_lcd_modes[] = {
-{
-	.pixclock		= 86538,
-	.xres			= 320,
-	.yres			= 320,
-	.bpp			= 16,
-
-	.left_margin		= 20,
-	.right_margin		= 8,
-	.upper_margin		= 8,
-	.lower_margin		= 5,
-
-	.hsync_len		= 4,
-	.vsync_len		= 1,
-},
-};
-
-static void treo680_lcd_power(int on, struct fb_var_screeninfo *info)
-{
-	gpio_set_value(GPIO_NR_TREO680_BL_POWER, on);
-}
-
-static struct pxafb_mach_info treo680_lcd_screen = {
-	.modes		= treo680_lcd_modes,
-	.num_modes	= ARRAY_SIZE(treo680_lcd_modes),
-	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
-};
-
-/******************************************************************************
- * Power management - standby
- ******************************************************************************/
-static void __init treo680_pm_init(void)
-{
-	static u32 resume[] = {
-		0xe3a00101,	/* mov	r0,	#0x40000000 */
-		0xe380060f,	/* orr	r0, r0, #0x00f00000 */
-		0xe590f008,	/* ldr	pc, [r0, #0x08] */
-	};
-
-	/* this is where the bootloader jumps */
-	memcpy(phys_to_virt(TREO680_STR_BASE), resume, sizeof(resume));
-}
-
-/******************************************************************************
- * Machine init
- ******************************************************************************/
-static struct platform_device *devices[] __initdata = {
-	&treo680_backlight,
-	&treo680_leds,
-	&power_supply,
-};
-
-/* setup udc GPIOs initial state */
-static void __init treo680_udc_init(void)
-{
-	if (!gpio_request(GPIO_NR_TREO680_USB_PULLUP, "UDC Vbus")) {
-		gpio_direction_output(GPIO_NR_TREO680_USB_PULLUP, 1);
-		gpio_free(GPIO_NR_TREO680_USB_PULLUP);
-	}
-}
-
-static void __init treo680_lcd_power_init(void)
-{
-	int ret;
-
-	ret = gpio_request(GPIO_NR_TREO680_LCD_POWER, "LCD POWER");
-	if (ret) {
-		pr_err("Treo680: LCD power GPIO request failed!\n");
-		return;
-	}
-
-	ret = gpio_direction_output(GPIO_NR_TREO680_LCD_POWER, 0);
-	if (ret) {
-		pr_err("Treo680: setting LCD power GPIO direction failed!\n");
-		gpio_free(GPIO_NR_TREO680_LCD_POWER);
-		return;
-	}
-
-	treo680_lcd_screen.pxafb_lcd_power = treo680_lcd_power;
-}
-
-static void __init treo680_init(void)
-{
-	treo680_pm_init();
-	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
-	pxa_set_keypad_info(&treo680_keypad_platform_data);
-	treo680_lcd_power_init();
-	set_pxa_fb_info(&treo680_lcd_screen);
-	pxa_set_mci_info(&treo680_mci_platform_data);
-	treo680_udc_init();
-	pxa_set_udc_info(&treo680_udc_info);
-	pxa_set_ac97_info(&treo680_ac97_pdata);
-	pxa_set_ficp_info(&treo680_ficp_info);
-	pxa_set_ohci_info(&treo680_ohci_info);
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-MACHINE_START(TREO680, "Palm Treo 680")
-	.phys_io	= TREO680_PHYS_IO_START,
-	.io_pg_offst	= io_p2v(0x40000000),
-	.boot_params	= 0xa0000100,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa27x_init_irq,
-	.timer		= &pxa_timer,
-	.init_machine	= treo680_init,
-MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/trizeps4.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/trizeps4.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/trizeps4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/trizeps4.c	2010-02-24 13:52:17.000000000 -0500
@@ -524,6 +524,10 @@ static void __init trizeps4_init(void)
 					ARRAY_SIZE(trizeps4_devices));
 	}
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	if (0)	/* dont know how to determine LCD */
 		set_pxa_fb_info(&sharp_lcd);
 	else
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/viper.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/viper.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/viper.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/viper.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,7 @@
 #include <mach/pxafb.h>
 #include <plat/i2c.h>
 #include <mach/regs-uart.h>
+#include <mach/arcom-pcmcia.h>
 #include <mach/viper.h>
 
 #include <asm/setup.h>
@@ -76,14 +77,28 @@ static void viper_icr_clear_bit(unsigned
 }
 
 /* This function is used from the pcmcia module to reset the CF */
-void viper_cf_rst(int state)
+static void viper_cf_reset(int state)
 {
 	if (state)
 		viper_icr_set_bit(VIPER_ICR_CF_RST);
 	else
 		viper_icr_clear_bit(VIPER_ICR_CF_RST);
 }
-EXPORT_SYMBOL(viper_cf_rst);
+
+static struct arcom_pcmcia_pdata viper_pcmcia_info = {
+	.cd_gpio	= VIPER_CF_CD_GPIO,
+	.rdy_gpio	= VIPER_CF_RDY_GPIO,
+	.pwr_gpio	= VIPER_CF_POWER_GPIO,
+	.reset		= viper_cf_reset,
+};
+
+static struct platform_device viper_pcmcia_device = {
+	.name		= "viper-pcmcia",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &viper_pcmcia_info,
+	},
+};
 
 /*
  * The CPLD version register was not present on VIPER boards prior to
@@ -301,15 +316,6 @@ static void __init viper_init_irq(void)
 	set_irq_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO),
 				viper_irq_handler);
 	set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH);
-
-#ifndef CONFIG_SERIAL_PXA
-	/*
-	 * 8250 doesn't support IRQ_TYPE being passed as part
-	 * of the plat_serial8250_port structure...
-	 */
-	set_irq_type(gpio_to_irq(VIPER_UARTA_GPIO), IRQ_TYPE_EDGE_RISING);
-	set_irq_type(gpio_to_irq(VIPER_UARTB_GPIO), IRQ_TYPE_EDGE_RISING);
-#endif
 }
 
 /* Flat Panel */
@@ -373,7 +379,7 @@ err_request_bckl:
 	return ret;
 }
 
-static int viper_backlight_notify(int brightness)
+static int viper_backlight_notify(struct device *dev, int brightness)
 {
 	gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness);
 	gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness);
@@ -539,6 +545,7 @@ static struct plat_serial8250_port seria
 	{
 		.mapbase	= VIPER_UARTA_PHYS,
 		.irq		= gpio_to_irq(VIPER_UARTA_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
 		.uartclk	= 1843200,
 		.regshift	= 1,
 		.iotype		= UPIO_MEM,
@@ -548,6 +555,7 @@ static struct plat_serial8250_port seria
 	{
 		.mapbase	= VIPER_UARTB_PHYS,
 		.irq		= gpio_to_irq(VIPER_UARTB_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
 		.uartclk	= 1843200,
 		.regshift	= 1,
 		.iotype		= UPIO_MEM,
@@ -692,6 +700,7 @@ static struct platform_device *viper_dev
 	&viper_mtd_devices[0],
 	&viper_mtd_devices[1],
 	&viper_backlight_device,
+	&viper_pcmcia_device,
 };
 
 static mfp_cfg_t viper_pin_config[] __initdata = {
@@ -908,6 +917,10 @@ static void __init viper_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	/* Wake-up serial console */
 	viper_init_serial_gpio();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/xcep.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/xcep.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/xcep.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/xcep.c	2010-02-24 13:52:17.000000000 -0500
@@ -165,6 +165,11 @@ static void __init xcep_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(xcep_pin_config));
 
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+	pxa_set_hwuart_info(NULL);
+
 	/* See Intel XScale Developer's Guide for details */
 	/* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */
 	MSC1 = (MSC1 & 0xffff) | 0xD5540000;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zeus.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zeus.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zeus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zeus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,850 @@
+/*
+ *  Support for the Arcom ZEUS.
+ *
+ *  Copyright (C) 2006 Arcom Control Systems Ltd.
+ *
+ *  Loosely based on Arcom's 2.6.16.28.
+ *  Maintained by Marc Zyngier <maz@misterjones.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/cpufreq.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/gpio.h>
+#include <linux/serial_8250.h>
+#include <linux/dm9000.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/apm-emulation.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/i2c.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/regs-uart.h>
+#include <mach/ohci.h>
+#include <mach/mmc.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+#include <mach/pxafb.h>
+#include <mach/pxa2xx_spi.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pm.h>
+#include <mach/audio.h>
+#include <mach/arcom-pcmcia.h>
+#include <mach/zeus.h>
+
+#include "generic.h"
+
+/*
+ * Interrupt handling
+ */
+
+static unsigned long zeus_irq_enabled_mask;
+static const int zeus_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, };
+static const int zeus_isa_irq_map[] = {
+	0,		/* ISA irq #0, invalid */
+	0,		/* ISA irq #1, invalid */
+	0,		/* ISA irq #2, invalid */
+	1 << 0,		/* ISA irq #3 */
+	1 << 1,		/* ISA irq #4 */
+	1 << 2,		/* ISA irq #5 */
+	1 << 3,		/* ISA irq #6 */
+	1 << 4,		/* ISA irq #7 */
+	0,		/* ISA irq #8, invalid */
+	0,		/* ISA irq #9, invalid */
+	1 << 5,		/* ISA irq #10 */
+	1 << 6,		/* ISA irq #11 */
+	1 << 7,		/* ISA irq #12 */
+};
+
+static inline int zeus_irq_to_bitmask(unsigned int irq)
+{
+	return zeus_isa_irq_map[irq - PXA_ISA_IRQ(0)];
+}
+
+static inline int zeus_bit_to_irq(int bit)
+{
+	return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0);
+}
+
+static void zeus_ack_irq(unsigned int irq)
+{
+	__raw_writew(zeus_irq_to_bitmask(irq), ZEUS_CPLD_ISA_IRQ);
+}
+
+static void zeus_mask_irq(unsigned int irq)
+{
+	zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(irq));
+}
+
+static void zeus_unmask_irq(unsigned int irq)
+{
+	zeus_irq_enabled_mask |= zeus_irq_to_bitmask(irq);
+}
+
+static inline unsigned long zeus_irq_pending(void)
+{
+	return __raw_readw(ZEUS_CPLD_ISA_IRQ) & zeus_irq_enabled_mask;
+}
+
+static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long pending;
+
+	pending = zeus_irq_pending();
+	do {
+		/* we're in a chained irq handler,
+		 * so ack the interrupt by hand */
+		desc->chip->ack(gpio_to_irq(ZEUS_ISA_GPIO));
+
+		if (likely(pending)) {
+			irq = zeus_bit_to_irq(__ffs(pending));
+			generic_handle_irq(irq);
+		}
+		pending = zeus_irq_pending();
+	} while (pending);
+}
+
+static struct irq_chip zeus_irq_chip = {
+	.name	= "ISA",
+	.ack	= zeus_ack_irq,
+	.mask	= zeus_mask_irq,
+	.unmask	= zeus_unmask_irq,
+};
+
+static void __init zeus_init_irq(void)
+{
+	int level;
+	int isa_irq;
+
+	pxa27x_init_irq();
+
+	/* Peripheral IRQs. It would be nice to move those inside driver
+	   configuration, but it is not supported at the moment. */
+	set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO),	IRQ_TYPE_EDGE_RISING);
+	set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO),	IRQ_TYPE_EDGE_RISING);
+	set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO),	IRQ_TYPE_EDGE_RISING);
+	set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO),	IRQ_TYPE_EDGE_FALLING);
+	set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO),	IRQ_TYPE_EDGE_FALLING);
+
+	/* Setup ISA IRQs */
+	for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) {
+		isa_irq = zeus_bit_to_irq(level);
+		set_irq_chip(isa_irq, &zeus_irq_chip);
+		set_irq_handler(isa_irq, handle_edge_irq);
+		set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING);
+	set_irq_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler);
+}
+
+
+/*
+ * Platform devices
+ */
+
+/* Flash */
+static struct resource zeus_mtd_resources[] = {
+	[0] = { /* NOR Flash (up to 64MB) */
+		.start	= ZEUS_FLASH_PHYS,
+		.end	= ZEUS_FLASH_PHYS + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = { /* SRAM */
+		.start	= ZEUS_SRAM_PHYS,
+		.end	= ZEUS_SRAM_PHYS + SZ_512K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct physmap_flash_data zeus_flash_data[] = {
+	[0] = {
+		.width		= 2,
+		.parts		= NULL,
+		.nr_parts	= 0,
+	},
+};
+
+static struct platform_device zeus_mtd_devices[] = {
+	[0] = {
+		.name		= "physmap-flash",
+		.id		= 0,
+		.dev		= {
+			.platform_data = &zeus_flash_data[0],
+		},
+		.resource	= &zeus_mtd_resources[0],
+		.num_resources	= 1,
+	},
+};
+
+/* Serial */
+static struct resource zeus_serial_resources[] = {
+	{
+		.start	= 0x10000000,
+		.end	= 0x1000000f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x10800000,
+		.end	= 0x1080000f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x11000000,
+		.end	= 0x1100000f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x40100000,
+		.end	= 0x4010001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x40200000,
+		.end	= 0x4020001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x40700000,
+		.end	= 0x4070001f,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	/* External UARTs */
+	/* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */
+	{ /* COM1 */
+		.mapbase	= 0x10000000,
+		.irq		= gpio_to_irq(ZEUS_UARTA_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 1,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ /* COM2 */
+		.mapbase	= 0x10800000,
+		.irq		= gpio_to_irq(ZEUS_UARTB_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 1,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ /* COM3 */
+		.mapbase	= 0x11000000,
+		.irq		= gpio_to_irq(ZEUS_UARTC_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 1,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ /* COM4 */
+		.mapbase	= 0x11800000,
+		.irq		= gpio_to_irq(ZEUS_UARTD_GPIO),
+		.irqflags	= IRQF_TRIGGER_RISING,
+		.uartclk	= 14745600,
+		.regshift	= 1,
+		.flags		= UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	/* Internal UARTs */
+	{ /* FFUART */
+		.membase	= (void *)&FFUART,
+		.mapbase	= __PREG(FFUART),
+		.irq		= IRQ_FFUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ /* BTUART */
+		.membase	= (void *)&BTUART,
+		.mapbase	= __PREG(BTUART),
+		.irq		= IRQ_BTUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ /* STUART */
+		.membase	= (void *)&STUART,
+		.mapbase	= __PREG(STUART),
+		.irq		= IRQ_STUART,
+		.uartclk	= 921600 * 16,
+		.regshift	= 2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+	},
+	{ },
+};
+
+static struct platform_device zeus_serial_device = {
+	.name = "serial8250",
+	.id   = PLAT8250_DEV_PLATFORM,
+	.dev  = {
+		.platform_data = serial_platform_data,
+	},
+	.num_resources	= ARRAY_SIZE(zeus_serial_resources),
+	.resource	= zeus_serial_resources,
+};
+
+/* Ethernet */
+static struct resource zeus_dm9k0_resource[] = {
+	[0] = {
+		.start = ZEUS_ETH0_PHYS,
+		.end   = ZEUS_ETH0_PHYS + 1,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = ZEUS_ETH0_PHYS + 2,
+		.end   = ZEUS_ETH0_PHYS + 3,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = gpio_to_irq(ZEUS_ETH0_GPIO),
+		.end   = gpio_to_irq(ZEUS_ETH0_GPIO),
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+static struct resource zeus_dm9k1_resource[] = {
+	[0] = {
+		.start = ZEUS_ETH1_PHYS,
+		.end   = ZEUS_ETH1_PHYS + 1,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = ZEUS_ETH1_PHYS + 2,
+		.end   = ZEUS_ETH1_PHYS + 3,
+		.flags = IORESOURCE_MEM,
+	},
+	[2] = {
+		.start = gpio_to_irq(ZEUS_ETH1_GPIO),
+		.end   = gpio_to_irq(ZEUS_ETH1_GPIO),
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+static struct dm9000_plat_data zeus_dm9k_platdata = {
+	.flags		= DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device zeus_dm9k0_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(zeus_dm9k0_resource),
+	.resource	= zeus_dm9k0_resource,
+	.dev		= {
+		.platform_data = &zeus_dm9k_platdata,
+	}
+};
+
+static struct platform_device zeus_dm9k1_device = {
+	.name		= "dm9000",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(zeus_dm9k1_resource),
+	.resource	= zeus_dm9k1_resource,
+	.dev		= {
+		.platform_data = &zeus_dm9k_platdata,
+	}
+};
+
+/* External SRAM */
+static struct resource zeus_sram_resource = {
+	.start		= ZEUS_SRAM_PHYS,
+	.end		= ZEUS_SRAM_PHYS + ZEUS_SRAM_SIZE * 2 - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device zeus_sram_device = {
+	.name		= "pxa2xx-8bit-sram",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &zeus_sram_resource,
+};
+
+/* SPI interface on SSP3 */
+static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
+	.num_chipselect = 1,
+	.enable_dma     = 1,
+};
+
+static struct platform_device pxa2xx_spi_ssp3_device = {
+	.name = "pxa2xx-spi",
+	.id = 3,
+	.dev = {
+		.platform_data = &pxa2xx_spi_ssp3_master_info,
+	},
+};
+
+/* Leds */
+static struct gpio_led zeus_leds[] = {
+	[0] = {
+		.name		 = "zeus:yellow:1",
+		.default_trigger = "heartbeat",
+		.gpio		 = ZEUS_EXT0_GPIO(3),
+		.active_low	 = 1,
+	},
+	[1] = {
+		.name		 = "zeus:yellow:2",
+		.default_trigger = "default-on",
+		.gpio		 = ZEUS_EXT0_GPIO(4),
+		.active_low	 = 1,
+	},
+	[2] = {
+		.name		 = "zeus:yellow:3",
+		.default_trigger = "default-on",
+		.gpio		 = ZEUS_EXT0_GPIO(5),
+		.active_low	 = 1,
+	},
+};
+
+static struct gpio_led_platform_data zeus_leds_info = {
+	.leds		= zeus_leds,
+	.num_leds	= ARRAY_SIZE(zeus_leds),
+};
+
+static struct platform_device zeus_leds_device = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &zeus_leds_info,
+	},
+};
+
+static void zeus_cf_reset(int state)
+{
+	u16 cpld_state = __raw_readw(ZEUS_CPLD_CONTROL);
+
+	if (state)
+		cpld_state |= ZEUS_CPLD_CONTROL_CF_RST;
+	else
+		cpld_state &= ~ZEUS_CPLD_CONTROL_CF_RST;
+
+	__raw_writew(cpld_state, ZEUS_CPLD_CONTROL);
+}
+
+static struct arcom_pcmcia_pdata zeus_pcmcia_info = {
+	.cd_gpio	= ZEUS_CF_CD_GPIO,
+	.rdy_gpio	= ZEUS_CF_RDY_GPIO,
+	.pwr_gpio	= ZEUS_CF_PWEN_GPIO,
+	.reset		= zeus_cf_reset,
+};
+
+static struct platform_device zeus_pcmcia_device = {
+	.name		= "zeus-pcmcia",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &zeus_pcmcia_info,
+	},
+};
+
+static struct platform_device *zeus_devices[] __initdata = {
+	&zeus_serial_device,
+	&zeus_mtd_devices[0],
+	&zeus_dm9k0_device,
+	&zeus_dm9k1_device,
+	&zeus_sram_device,
+	&pxa2xx_spi_ssp3_device,
+	&zeus_leds_device,
+	&zeus_pcmcia_device,
+};
+
+/* AC'97 */
+static pxa2xx_audio_ops_t zeus_ac97_info = {
+	.reset_gpio = 95,
+};
+
+
+/*
+ * USB host
+ */
+
+static int zeus_ohci_init(struct device *dev)
+{
+	int err;
+
+	/* Switch on port 2. */
+	if ((err = gpio_request(ZEUS_USB2_PWREN_GPIO, "USB2_PWREN"))) {
+		dev_err(dev, "Can't request USB2_PWREN\n");
+		return err;
+	}
+
+	if ((err = gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 1))) {
+		gpio_free(ZEUS_USB2_PWREN_GPIO);
+		dev_err(dev, "Can't enable USB2_PWREN\n");
+		return err;
+	}
+
+	/* Port 2 is shared between host and client interface. */
+	UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+
+	return 0;
+}
+
+static void zeus_ohci_exit(struct device *dev)
+{
+	/* Power-off port 2 */
+	gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 0);
+	gpio_free(ZEUS_USB2_PWREN_GPIO);
+}
+
+static struct pxaohci_platform_data zeus_ohci_platform_data = {
+	.port_mode	= PMM_NPS_MODE,
+	.flags		= ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+	.init		= zeus_ohci_init,
+	.exit		= zeus_ohci_exit,
+};
+
+/*
+ * Flat Panel
+ */
+
+static void zeus_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+	gpio_set_value(ZEUS_LCD_EN_GPIO, on);
+}
+
+static void zeus_backlight_power(int on)
+{
+	gpio_set_value(ZEUS_BKLEN_GPIO, on);
+}
+
+static int zeus_setup_fb_gpios(void)
+{
+	int err;
+
+	if ((err = gpio_request(ZEUS_LCD_EN_GPIO, "LCD_EN")))
+		goto out_err;
+
+	if ((err = gpio_direction_output(ZEUS_LCD_EN_GPIO, 0)))
+		goto out_err_lcd;
+
+	if ((err = gpio_request(ZEUS_BKLEN_GPIO, "BKLEN")))
+		goto out_err_lcd;
+
+	if ((err = gpio_direction_output(ZEUS_BKLEN_GPIO, 0)))
+		goto out_err_bkl;
+
+	return 0;
+
+out_err_bkl:
+	gpio_free(ZEUS_BKLEN_GPIO);
+out_err_lcd:
+	gpio_free(ZEUS_LCD_EN_GPIO);
+out_err:
+	return err;
+}
+
+static struct pxafb_mode_info zeus_fb_mode_info[] = {
+	{
+		.pixclock       = 39722,
+
+		.xres           = 640,
+		.yres           = 480,
+
+		.bpp            = 16,
+
+		.hsync_len      = 63,
+		.left_margin    = 16,
+		.right_margin   = 81,
+
+		.vsync_len      = 2,
+		.upper_margin   = 12,
+		.lower_margin   = 31,
+
+		.sync		= 0,
+	},
+};
+
+static struct pxafb_mach_info zeus_fb_info = {
+	.modes			= zeus_fb_mode_info,
+	.num_modes		= 1,
+	.lcd_conn		= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+	.pxafb_lcd_power	= zeus_lcd_power,
+	.pxafb_backlight_power	= zeus_backlight_power,
+};
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+
+static struct pxamci_platform_data zeus_mci_platform_data = {
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.detect_delay		= HZ/4,
+	.gpio_card_detect       = ZEUS_MMC_CD_GPIO,
+	.gpio_card_ro           = ZEUS_MMC_WP_GPIO,
+	.gpio_card_ro_invert	= 1,
+	.gpio_power             = -1
+};
+
+/*
+ * USB Device Controller
+ */
+static void zeus_udc_command(int cmd)
+{
+	switch (cmd) {
+	case PXA2XX_UDC_CMD_DISCONNECT:
+		pr_info("zeus: disconnecting USB client\n");
+		UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+		break;
+
+	case PXA2XX_UDC_CMD_CONNECT:
+		pr_info("zeus: connecting USB client\n");
+		UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+		break;
+	}
+}
+
+static struct pxa2xx_udc_mach_info zeus_udc_info = {
+	.udc_command = zeus_udc_command,
+};
+
+static void zeus_power_off(void)
+{
+	local_irq_disable();
+	pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
+}
+
+#ifdef CONFIG_APM_EMULATION
+static void zeus_get_power_status(struct apm_power_info *info)
+{
+	/* Power supply is always present */
+	info->ac_line_status	= APM_AC_ONLINE;
+	info->battery_status	= APM_BATTERY_STATUS_NOT_PRESENT;
+	info->battery_flag	= APM_BATTERY_FLAG_NOT_PRESENT;
+}
+
+static inline void zeus_setup_apm(void)
+{
+	apm_get_power_status = zeus_get_power_status;
+}
+#else
+static inline void zeus_setup_apm(void)
+{
+}
+#endif
+
+static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio,
+			     unsigned ngpio, void *context)
+{
+	int i;
+	u8 pcb_info = 0;
+
+	for (i = 0; i < 8; i++) {
+		int pcb_bit = gpio + i + 8;
+
+		if (gpio_request(pcb_bit, "pcb info")) {
+			dev_err(&client->dev, "Can't request pcb info %d\n", i);
+			continue;
+		}
+
+		if (gpio_direction_input(pcb_bit)) {
+			dev_err(&client->dev, "Can't read pcb info %d\n", i);
+			gpio_free(pcb_bit);
+			continue;
+		}
+
+		pcb_info |= !!gpio_get_value(pcb_bit) << i;
+
+		gpio_free(pcb_bit);
+	}
+
+	dev_info(&client->dev, "Zeus PCB version %d issue %d\n",
+		 pcb_info >> 4, pcb_info & 0xf);
+
+	return 0;
+}
+
+static struct pca953x_platform_data zeus_pca953x_pdata[] = {
+	[0] = { .gpio_base	= ZEUS_EXT0_GPIO_BASE, },
+	[1] = {
+		.gpio_base	= ZEUS_EXT1_GPIO_BASE,
+		.setup		= zeus_get_pcb_info,
+	},
+	[2] = { .gpio_base = ZEUS_USER_GPIO_BASE, },
+};
+
+static struct i2c_board_info __initdata zeus_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pca9535",	0x21),
+		.platform_data	= &zeus_pca953x_pdata[0],
+	},
+	{
+		I2C_BOARD_INFO("pca9535",	0x22),
+		.platform_data	= &zeus_pca953x_pdata[1],
+	},
+	{
+		I2C_BOARD_INFO("pca9535",	0x20),
+		.platform_data	= &zeus_pca953x_pdata[2],
+		.irq		= gpio_to_irq(ZEUS_EXTGPIO_GPIO),
+	},
+	{ I2C_BOARD_INFO("lm75a",	0x48) },
+	{ I2C_BOARD_INFO("24c01",	0x50) },
+	{ I2C_BOARD_INFO("isl1208",	0x6f) },
+};
+
+static mfp_cfg_t zeus_pin_config[] __initdata = {
+	GPIO15_nCS_1,
+	GPIO78_nCS_2,
+	GPIO80_nCS_4,
+	GPIO33_nCS_5,
+
+	GPIO22_GPIO,
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+
+	GPIO88_USBH1_PWR,
+	GPIO89_USBH1_PEN,
+	GPIO119_USBH2_PWR,
+	GPIO120_USBH2_PEN,
+
+	GPIO86_LCD_LDD_16,
+	GPIO87_LCD_LDD_17,
+
+	GPIO102_GPIO,
+	GPIO104_CIF_DD_2,
+	GPIO105_CIF_DD_1,
+
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO85_nPCE_1,
+	GPIO54_nPCE_2,
+	GPIO79_PSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+	GPIO36_GPIO,		/* CF CD */
+	GPIO97_GPIO,		/* CF PWREN */
+	GPIO99_GPIO,		/* CF RDY */
+};
+
+/*
+ * DM9k MSCx settings:	SRAM, 16 bits
+ *			17 cycles delay first access
+ *			 5 cycles delay next access
+ *			13 cycles recovery time
+ *			faster device
+ */
+#define DM9K_MSC_VALUE		0xe4c9
+
+static void __init zeus_init(void)
+{
+	u16 dm9000_msc = DM9K_MSC_VALUE;
+
+	system_rev = __raw_readw(ZEUS_CPLD_VERSION);
+	pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f));
+
+	/* Fix timings for dm9000s (CS1/CS2)*/
+	MSC0 = (MSC0 & 0xffff) | (dm9000_msc << 16);
+	MSC1 = (MSC1 & 0xffff0000) | dm9000_msc;
+
+	pm_power_off = zeus_power_off;
+	zeus_setup_apm();
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config));
+
+	platform_add_devices(zeus_devices, ARRAY_SIZE(zeus_devices));
+
+	pxa_set_ohci_info(&zeus_ohci_platform_data);
+
+	if (zeus_setup_fb_gpios())
+		pr_err("Failed to setup fb gpios\n");
+	else
+		set_pxa_fb_info(&zeus_fb_info);
+
+	pxa_set_mci_info(&zeus_mci_platform_data);
+	pxa_set_udc_info(&zeus_udc_info);
+	pxa_set_ac97_info(&zeus_ac97_info);
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices));
+}
+
+static struct map_desc zeus_io_desc[] __initdata = {
+	{
+		.virtual = ZEUS_CPLD_VERSION,
+		.pfn     = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS),
+		.length  = 0x1000,
+		.type    = MT_DEVICE,
+	},
+	{
+		.virtual = ZEUS_CPLD_ISA_IRQ,
+		.pfn     = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS),
+		.length  = 0x1000,
+		.type    = MT_DEVICE,
+	},
+	{
+		.virtual = ZEUS_CPLD_CONTROL,
+		.pfn     = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS),
+		.length  = 0x1000,
+		.type    = MT_DEVICE,
+	},
+	{
+		.virtual = ZEUS_CPLD_EXTWDOG,
+		.pfn     = __phys_to_pfn(ZEUS_CPLD_EXTWDOG_PHYS),
+		.length  = 0x1000,
+		.type    = MT_DEVICE,
+	},
+	{
+		.virtual = ZEUS_PC104IO,
+		.pfn     = __phys_to_pfn(ZEUS_PC104IO_PHYS),
+		.length  = 0x00800000,
+		.type    = MT_DEVICE,
+	},
+};
+
+static void __init zeus_map_io(void)
+{
+	pxa_map_io();
+
+	iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc));
+
+	/* Clear PSPR to ensure a full restart on wake-up. */
+	PMCR = PSPR = 0;
+
+	/* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */
+	OSCC |= OSCC_OON;
+
+	/* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...).
+	 * float chip selects and PCMCIA */
+	PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP;
+}
+
+MACHINE_START(ARCOM_ZEUS, "Arcom ZEUS")
+	/* Maintainer: Marc Zyngier <maz@misterjones.org> */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= ((io_p2v(0x40000000) >> 18) & 0xfffc),
+	.boot_params	= 0xa0000100,
+	.map_io		= zeus_map_io,
+	.init_irq	= zeus_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= zeus_init,
+MACHINE_END
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,14 +31,11 @@
 #include <mach/mmc.h>
 #include <mach/ohci.h>
 #include <mach/pxa27x_keypad.h>
-#include <mach/pxa3xx_nand.h>
+#include <plat/pxa3xx_nand.h>
 
 #include "devices.h"
 #include "generic.h"
 
-#define MAX_SLOTS	3
-struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
-
 int gpio_eth_irq;
 int gpio_debug_led1;
 int gpio_debug_led2;
@@ -220,84 +217,28 @@ static inline void zylonite_init_lcd(voi
 #endif
 
 #if defined(CONFIG_MMC)
-static int zylonite_mci_ro(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-
-	return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
-}
-
-static int zylonite_mci_init(struct device *dev,
-			     irq_handler_t zylonite_detect_int,
-			     void *data)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int err, cd_irq, gpio_cd, gpio_wp;
-
-	cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
-	gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
-	gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
-
-	/*
-	 * setup GPIO for Zylonite MMC controller
-	 */
-	err = gpio_request(gpio_cd, "mmc card detect");
-	if (err)
-		goto err_request_cd;
-	gpio_direction_input(gpio_cd);
-
-	err = gpio_request(gpio_wp, "mmc write protect");
-	if (err)
-		goto err_request_wp;
-	gpio_direction_input(gpio_wp);
-
-	err = request_irq(cd_irq, zylonite_detect_int,
-			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: MMC/SD/SDIO: "
-				"can't request card detect IRQ\n", __func__);
-		goto err_request_irq;
-	}
-
-	return 0;
-
-err_request_irq:
-	gpio_free(gpio_wp);
-err_request_wp:
-	gpio_free(gpio_cd);
-err_request_cd:
-	return err;
-}
-
-static void zylonite_mci_exit(struct device *dev, void *data)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int cd_irq, gpio_cd, gpio_wp;
-
-	cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
-	gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
-	gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
-
-	free_irq(cd_irq, data);
-	gpio_free(gpio_cd);
-	gpio_free(gpio_wp);
-}
-
 static struct pxamci_platform_data zylonite_mci_platform_data = {
 	.detect_delay	= 20,
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= zylonite_mci_init,
-	.exit		= zylonite_mci_exit,
-	.get_ro		= zylonite_mci_ro,
-	.gpio_card_detect = -1,
-	.gpio_card_ro	= -1,
+	.gpio_card_detect = EXT_GPIO(0),
+	.gpio_card_ro	= EXT_GPIO(2),
 	.gpio_power	= -1,
 };
 
 static struct pxamci_platform_data zylonite_mci2_platform_data = {
 	.detect_delay	= 20,
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect = EXT_GPIO(1),
+	.gpio_card_ro	= EXT_GPIO(3),
+	.gpio_power	= -1,
+};
+
+static struct pxamci_platform_data zylonite_mci3_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect = EXT_GPIO(30),
+	.gpio_card_ro	= EXT_GPIO(31),
+	.gpio_power	= -1,
 };
 
 static void __init zylonite_init_mmc(void)
@@ -305,7 +246,7 @@ static void __init zylonite_init_mmc(voi
 	pxa_set_mci_info(&zylonite_mci_platform_data);
 	pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
 	if (cpu_is_pxa310())
-		pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
+		pxa3xx_set_mci3_info(&zylonite_mci3_platform_data);
 }
 #else
 static inline void zylonite_init_mmc(void) {}
@@ -444,6 +385,10 @@ static inline void zylonite_init_ohci(vo
 
 static void __init zylonite_init(void)
 {
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
 	/* board-processor specific initialization */
 	zylonite_pxa300_init();
 	zylonite_pxa320_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c	2010-02-24 13:52:17.000000000 -0500
@@ -129,8 +129,8 @@ static mfp_cfg_t common_mfp_cfg[] __init
 	GPIO22_I2C_SDA,
 
 	/* GPIO */
-	GPIO18_GPIO,	/* GPIO Expander #0 INT_N */
-	GPIO19_GPIO,	/* GPIO Expander #1 INT_N */
+	GPIO18_GPIO | MFP_PULL_HIGH,	/* GPIO Expander #0 INT_N */
+	GPIO19_GPIO | MFP_PULL_HIGH,	/* GPIO Expander #1 INT_N */
 };
 
 static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
@@ -258,10 +258,6 @@ void __init zylonite_pxa300_init(void)
 		/* detect LCD panel */
 		zylonite_detect_lcd_panel();
 
-		/* MMC card detect & write protect for controller 0 */
-		zylonite_mmc_slot[0].gpio_cd  = EXT_GPIO(0);
-		zylonite_mmc_slot[0].gpio_wp  = EXT_GPIO(2);
-
 		/* WM9713 IRQ */
 		wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26);
 
@@ -276,10 +272,6 @@ void __init zylonite_pxa300_init(void)
 	if (cpu_is_pxa310()) {
 		pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
 		gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
-
-		/* MMC card detect & write protect for controller 2 */
-		zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30);
-		zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31);
 	}
 
 	/* GPIOs for Debug LEDs */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,10 +209,6 @@ void __init zylonite_pxa320_init(void)
 		gpio_debug_led1	= mfp_to_gpio(MFP_PIN_GPIO1_2);
 		gpio_debug_led2	= mfp_to_gpio(MFP_PIN_GPIO4_2);
 
-		/* MMC card detect & write protect for controller 0 */
-		zylonite_mmc_slot[0].gpio_cd  = mfp_to_gpio(MFP_PIN_GPIO1);
-		zylonite_mmc_slot[0].gpio_wp  = mfp_to_gpio(MFP_PIN_GPIO5);
-
 		/* WM9713 IRQ */
 		wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15);
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/include/mach/board-pb1176.h linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/board-pb1176.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/include/mach/board-pb1176.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/board-pb1176.h	2010-02-24 13:52:17.000000000 -0500
@@ -74,8 +74,8 @@
 #define REALVIEW_PB1176_L220_BASE		0x10110000 /* L220 registers */
 
 /*
- * Control register SYS_RESETCTL is set to 1 to force a soft reset
+ * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset
  */
-#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL    0x0100
+#define REALVIEW_PB1176_SYS_SOFT_RESET    0x0100
 
 #endif	/* __ASM_ARCH_BOARD_PB1176_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/include/mach/platform.h linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/platform.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/include/mach/platform.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/include/mach/platform.h	2010-02-24 13:52:17.000000000 -0500
@@ -140,7 +140,7 @@
  *     SYS_CLD, SYS_BOOTCS
  */
 #define REALVIEW_SYS_LOCK_LOCKED    (1 << 16)
-#define REALVIEW_SYS_LOCKVAL_MASK	0xA05F	       /* Enable write access */
+#define REALVIEW_SYS_LOCK_VAL	0xA05F	       /* Enable write access */
 
 /*
  * REALVIEW_SYS_FLASH
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-realview/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ config MACH_REALVIEW_PBX
 	bool "Support RealView/PBX platform"
 	select ARM_GIC
 	select HAVE_PATA_PLATFORM
-	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !HIGH_PHYS_OFFSET
+	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
 	select ZONE_DMA if SPARSEMEM
 	help
 	  Include support for the ARM(R) RealView PBX platform.
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_eb.c linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_eb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_eb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_eb.c	2010-02-24 13:52:17.000000000 -0500
@@ -381,6 +381,20 @@ static struct sys_timer realview_eb_time
 	.init		= realview_eb_timer_init,
 };
 
+static void realview_eb_reset(char mode)
+{
+	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+	/*
+	 * To reset, we hit the on-board reset register
+	 * in the system FPGA
+	 */
+	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+	if (core_tile_eb11mp())
+		__raw_writel(0x0008, reset_ctrl);
+}
+
 static void __init realview_eb_init(void)
 {
 	int i;
@@ -408,6 +422,7 @@ static void __init realview_eb_init(void
 #ifdef CONFIG_LEDS
 	leds_event = realview_leds_event;
 #endif
+	realview_reset = realview_eb_reset;
 }
 
 MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pb1176.c linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pb1176.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pb1176.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pb1176.c	2010-02-24 13:52:17.000000000 -0500
@@ -292,12 +292,10 @@ static struct sys_timer realview_pb1176_
 
 static void realview_pb1176_reset(char mode)
 {
-	void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
-		REALVIEW_SYS_RESETCTL_OFFSET;
-	void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
-		REALVIEW_SYS_LOCK_OFFSET;
-	__raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl);
-	__raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl);
+	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+	__raw_writel(REALVIEW_PB1176_SYS_SOFT_RESET, reset_ctrl);
 }
 
 static void realview_pb1176_fixup(struct machine_desc *mdesc,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pb11mp.c linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pb11mp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pb11mp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pb11mp.c	2010-02-24 13:52:17.000000000 -0500
@@ -301,17 +301,16 @@ static struct sys_timer realview_pb11mp_
 
 static void realview_pb11mp_reset(char mode)
 {
-	void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
-		REALVIEW_SYS_RESETCTL_OFFSET;
-	unsigned int val;
+	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
 
 	/*
 	 * To reset, we hit the on-board reset register
 	 * in the system FPGA
 	 */
-	val = __raw_readl(hdr_ctrl);
-	val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR;
-	__raw_writel(val, hdr_ctrl);
+	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+	__raw_writel(0x0000, reset_ctrl);
+	__raw_writel(0x0004, reset_ctrl);
 }
 
 static void __init realview_pb11mp_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pba8.c linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pba8.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pba8.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pba8.c	2010-02-24 13:52:17.000000000 -0500
@@ -272,6 +272,20 @@ static struct sys_timer realview_pba8_ti
 	.init		= realview_pba8_timer_init,
 };
 
+static void realview_pba8_reset(char mode)
+{
+	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+	/*
+	 * To reset, we hit the on-board reset register
+	 * in the system FPGA
+	 */
+	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+	__raw_writel(0x0000, reset_ctrl);
+	__raw_writel(0x0004, reset_ctrl);
+}
+
 static void __init realview_pba8_init(void)
 {
 	int i;
@@ -291,6 +305,7 @@ static void __init realview_pba8_init(vo
 #ifdef CONFIG_LEDS
 	leds_event = realview_leds_event;
 #endif
+	realview_reset = realview_pba8_reset;
 }
 
 MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pbx.c linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pbx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-realview/realview_pbx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-realview/realview_pbx.c	2010-02-24 13:52:17.000000000 -0500
@@ -324,6 +324,20 @@ static void realview_pbx_fixup(struct ma
 #endif
 }
 
+static void realview_pbx_reset(char mode)
+{
+	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+	/*
+	 * To reset, we hit the on-board reset register
+	 * in the system FPGA
+	 */
+	__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+	__raw_writel(0x00F0, reset_ctrl);
+	__raw_writel(0x00F4, reset_ctrl);
+}
+
 static void __init realview_pbx_init(void)
 {
 	int i;
@@ -358,6 +372,7 @@ static void __init realview_pbx_init(voi
 #ifdef CONFIG_LEDS
 	leds_event = realview_leds_event;
 #endif
+	realview_reset = realview_pbx_reset;
 }
 
 MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2400/include/mach/map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2400/include/mach/map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2400/include/mach/map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2400/include/mach/map.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2400/include/mach/map.h
  *
- * Copyright 2003,2007  Simtec Electronics
+ * Copyright 2003-2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2400/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2400/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2400/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2400/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,13 +1,7 @@
-# arch/arm/mach-s3c2400/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
 
-
-
 menu "S3C2400 Machines"
 
-
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/bast-irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/bast-irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/bast-irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/bast-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/bast-irq.c
  *
- * Copyright (c) 2003,2005 Simtec Electronics
+ * Copyright 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -141,7 +141,7 @@ static __init int bast_irq_init(void)
 	unsigned int i;
 
 	if (machine_is_bast()) {
-		printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n");
+		printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
 
 		/* zap all the IRQs */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/cpu-freq.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/cpu-freq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/cpu-freq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/cpu-freq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/cpu-freq.c
  *
- * Copyright (c) 2006,2008 Simtec Electronics
+ * Copyright (c) 2006-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/h1940-bluetooth.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 #include <linux/ctype.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
+#include <linux/rfkill.h>
 
 #include <mach/regs-gpio.h>
 #include <mach/hardware.h>
@@ -24,21 +25,10 @@
 
 #define DRV_NAME              "h1940-bt"
 
-#ifdef CONFIG_LEDS_H1940
-DEFINE_LED_TRIGGER(bt_led_trigger);
-#endif
-
-static int state;
-
 /* Bluetooth control */
 static void h1940bt_enable(int on)
 {
 	if (on) {
-#ifdef CONFIG_LEDS_H1940
-		/* flashing Blue */
-		led_trigger_event(bt_led_trigger, LED_HALF);
-#endif
-
 		/* Power on the chip */
 		h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
 		/* Reset the chip */
@@ -46,48 +36,31 @@ static void h1940bt_enable(int on)
 		s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
 		mdelay(10);
 		s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
-
-		state = 1;
 	}
 	else {
-#ifdef CONFIG_LEDS_H1940
-		led_trigger_event(bt_led_trigger, 0);
-#endif
-
 		s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
 		mdelay(10);
 		s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
 		mdelay(10);
 		h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
-
-		state = 0;
 	}
 }
 
-static ssize_t h1940bt_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int h1940bt_set_block(void *data, bool blocked)
 {
-	return snprintf(buf, PAGE_SIZE, "%d\n", state);
+	h1940bt_enable(!blocked);
+	return 0;
 }
 
-static ssize_t h1940bt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int new_state;
-	char *endp;
-
-	new_state = simple_strtoul(buf, &endp, 0);
-	if (*endp && !isspace(*endp))
-		return -EINVAL;
-
-	h1940bt_enable(new_state);
-
-	return count;
-}
-static DEVICE_ATTR(enable, 0644,
-		h1940bt_show,
-		h1940bt_store);
+static const struct rfkill_ops h1940bt_rfkill_ops = {
+	.set_block = h1940bt_set_block,
+};
 
 static int __init h1940bt_probe(struct platform_device *pdev)
 {
+	struct rfkill *rfk;
+	int ret = 0;
+
 	/* Configures BT serial port GPIOs */
 	s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
 	s3c2410_gpio_pullup(S3C2410_GPH(0), 1);
@@ -98,21 +71,44 @@ static int __init h1940bt_probe(struct p
 	s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
 	s3c2410_gpio_pullup(S3C2410_GPH(3), 1);
 
-#ifdef CONFIG_LEDS_H1940
-	led_trigger_register_simple("h1940-bluetooth", &bt_led_trigger);
-#endif
 
-	/* disable BT by default */
-	h1940bt_enable(0);
+	rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
+			&h1940bt_rfkill_ops, NULL);
+	if (!rfk) {
+		ret = -ENOMEM;
+		goto err_rfk_alloc;
+	}
 
-	return device_create_file(&pdev->dev, &dev_attr_enable);
+	rfkill_set_led_trigger_name(rfk, "h1940-bluetooth");
+
+	ret = rfkill_register(rfk);
+	if (ret)
+		goto err_rfkill;
+
+	platform_set_drvdata(pdev, rfk);
+
+	return 0;
+
+err_rfkill:
+	rfkill_destroy(rfk);
+err_rfk_alloc:
+	return ret;
 }
 
 static int h1940bt_remove(struct platform_device *pdev)
 {
-#ifdef CONFIG_LEDS_H1940
-	led_trigger_unregister_simple(bt_led_trigger);
-#endif
+	struct rfkill *rfk = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (rfk) {
+		rfkill_unregister(rfk);
+		rfkill_destroy(rfk);
+	}
+	rfk = NULL;
+
+	h1940bt_enable(0);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-cpld.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-cpld.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-cpld.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-cpld.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/bast-cpld.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * BAST - CPLD control constants
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-irq.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-irq.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/bast-irq.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine BAST - IRQ Number definitions
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-map.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/bast-map.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine BAST - Memory map definitions
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-pmu.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-pmu.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/bast-pmu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/bast-pmu.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/bast-pmu.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	Vincent Sanders <vince@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/dma.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/dma.h
  *
- * Copyright (C) 2003,2004,2006 Simtec Electronics
+ * Copyright (C) 2003-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C24XX DMA support
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-fns.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-fns.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-fns.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/gpio-fns.h
  *
- * Copyright (c) 2003,2009 Simtec Electronics
+ * Copyright (c) 2003-2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - hardware
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/osiris-map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/osiris-map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/osiris-map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/osiris-map.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/osiris-map.h
  *
- * (c) 2005 Simtec Electronics
+ * Copyright 2005 Simtec Electronics
  *	http://www.simtec.co.uk/products/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/include/mach/regs-clock.h
  *
- * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
- *		      http://armlinux.simtec.co.uk/
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@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
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/include/mach/regs-gpio.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics <linux@simtec.co.uk>
- *		           http://www.simtec.co.uk/products/SWLINUX/
+ * Copyright (c) 2003-2004 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
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-power.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-power.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/regs-power.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/regs-power.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/include/mach/regs-power.h
  *
- * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
- *		      http://armlinux.simtec.co.uk/
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@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
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/spi.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/spi.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/spi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/spi.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,8 @@ struct s3c2410_spi_info {
 	unsigned int		 num_cs;	/* total chipselects */
 	int			 bus_num;       /* bus number to use. */
 
+	unsigned int		 use_fiq:1;	/* use fiq */
+
 	void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
 	void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/ts.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/ts.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/ts.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/ts.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,21 @@
+/* linux/include/asm/arch-s3c2410/ts.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.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.
+*/
+
+#ifndef __ASM_ARM_TS_H
+#define __ASM_ARM_TS_H
+
+struct s3c2410_ts_mach_info {
+       int             delay;
+       int             presc;
+       int             oversampling_shift;
+};
+
+extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+
+#endif /* __ASM_ARM_TS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,6 @@
-
 /* arch/arm/mach-s3c2410/include/mach/uncompress.h
  *
- * Copyright (c) 2003, 2007 Simtec Electronics
+ * Copyright (c) 2003-2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Machine VR1000 - IRQ Number definitions
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2410/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -81,6 +79,14 @@ config ARCH_H1940
 	help
 	  Say Y here if you are using the HP IPAQ H1940
 
+config H1940BT
+        tristate "Control the state of H1940 bluetooth chip"
+        depends on ARCH_H1940
+        select RFKILL
+        help
+          This is a simple driver that is able to control
+          the state of built in bluetooth chip on h1940.
+
 config PM_H1940
 	bool
 	help
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-bast.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-bast.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-bast.c
  *
- * Copyright (c) 2003-2005,2008 Simtec Electronics
+ * Copyright 2003-2008 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -61,11 +61,12 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
+#include <plat/audio-simtec.h>
 
 #include "usb-simtec.h"
 #include "nor-simtec.h"
 
-#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
+#define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics"
 
 /* macros for virtual address mods for the io space entries */
 #define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
@@ -247,7 +248,7 @@ static int chip0_map[] = { 1 };
 static int chip1_map[] = { 2 };
 static int chip2_map[] = { 3 };
 
-static struct mtd_partition bast_default_nand_part[] = {
+static struct mtd_partition __initdata bast_default_nand_part[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_16K,
@@ -273,11 +274,12 @@ static struct mtd_partition bast_default
  * socket.
 */
 
-static struct s3c2410_nand_set bast_nand_sets[] = {
+static struct s3c2410_nand_set __initdata bast_nand_sets[] = {
 	[0] = {
 		.name		= "SmartMedia",
 		.nr_chips	= 1,
 		.nr_map		= smartmedia_map,
+		.options        = NAND_SCAN_SILENT_NODEV,
 		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
 		.partitions	= bast_default_nand_part,
 	},
@@ -292,6 +294,7 @@ static struct s3c2410_nand_set bast_nand
 		.name		= "chip1",
 		.nr_chips	= 1,
 		.nr_map		= chip1_map,
+		.options        = NAND_SCAN_SILENT_NODEV,
 		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
 		.partitions	= bast_default_nand_part,
 	},
@@ -299,6 +302,7 @@ static struct s3c2410_nand_set bast_nand
 		.name		= "chip2",
 		.nr_chips	= 1,
 		.nr_map		= chip2_map,
+		.options        = NAND_SCAN_SILENT_NODEV,
 		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
 		.partitions	= bast_default_nand_part,
 	}
@@ -323,7 +327,7 @@ static void bast_nand_select(struct s3c2
 	__raw_writeb(tmp, BAST_VA_CTRL2);
 }
 
-static struct s3c2410_platform_nand bast_nand_info = {
+static struct s3c2410_platform_nand __initdata bast_nand_info = {
 	.tacls		= 30,
 	.twrph0		= 60,
 	.twrph1		= 60,
@@ -608,6 +612,11 @@ static struct s3c_cpufreq_board __initda
 	.need_io	= 1,
 };
 
+static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
+	.have_mic	= 1,
+	.have_lout	= 1,
+};
+
 static void __init bast_map_io(void)
 {
 	/* initialise the clocks */
@@ -625,7 +634,6 @@ static void __init bast_map_io(void)
 
 	s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
 
-	s3c_device_nand.dev.platform_data = &bast_nand_info;
 	s3c_device_hwmon.dev.platform_data = &bast_hwmon_info;
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
@@ -639,6 +647,7 @@ static void __init bast_init(void)
 	sysdev_register(&bast_pm_sysdev);
 
 	s3c_i2c0_set_platdata(&bast_i2c_info);
+	s3c_nand_set_platdata(&bast_nand_info);
 	s3c24xx_fb_set_platdata(&bast_fb_info);
 	platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
 
@@ -647,6 +656,7 @@ static void __init bast_init(void)
 
 	usb_simtec_init();
 	nor_simtec_init();
+	simtec_audio_add(NULL, true, &bast_audio);
 
 	s3c_cpufreq_setboard(&bast_cpufreq);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-h1940.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-h1940.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,11 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
+#include <video/platform_lcd.h>
+
+#include <linux/mmc/host.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,12 +37,16 @@
 
 #include <plat/regs-serial.h>
 #include <mach/regs-lcd.h>
-#include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 
+#include <mach/regs-gpio.h>
+#include <mach/gpio-fns.h>
+#include <mach/gpio-nrs.h>
+
 #include <mach/h1940.h>
 #include <mach/h1940-latch.h>
 #include <mach/fb.h>
+#include <mach/ts.h>
 #include <plat/udc.h>
 #include <plat/iic.h>
 
@@ -46,6 +55,7 @@
 #include <plat/cpu.h>
 #include <plat/pll.h>
 #include <plat/pm.h>
+#include <plat/mci.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
 	[0] = {
@@ -131,6 +141,11 @@ static struct s3c2410_udc_mach_info h194
 	.vbus_pin_inverted	= 1,
 };
 
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+		.delay = 10000,
+		.presc = 49,
+		.oversampling_shift = 2,
+};
 
 /**
  * Set lcd on or off
@@ -171,25 +186,105 @@ static struct s3c2410fb_mach_info h1940_
 	.gpdup_mask=	0xffffffff,
 };
 
-static struct platform_device s3c_device_leds = {
+static struct platform_device h1940_device_leds = {
 	.name             = "h1940-leds",
 	.id               = -1,
 };
 
-static struct platform_device s3c_device_bluetooth = {
+static struct platform_device h1940_device_bluetooth = {
 	.name             = "h1940-bt",
 	.id               = -1,
 };
 
+static struct s3c24xx_mci_pdata h1940_mmc_cfg = {
+	.gpio_detect   = S3C2410_GPF(5),
+	.gpio_wprotect = S3C2410_GPH(8),
+	.set_power     = NULL,
+	.ocr_avail     = MMC_VDD_32_33,
+};
+
+static int h1940_backlight_init(struct device *dev)
+{
+	gpio_request(S3C2410_GPB(0), "Backlight");
+
+	s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
+	s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
+	s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+
+	return 0;
+}
+
+static void h1940_backlight_exit(struct device *dev)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/);
+}
+
+static struct platform_pwm_backlight_data backlight_data = {
+	.pwm_id         = 0,
+	.max_brightness = 100,
+	.dft_brightness = 50,
+	/* tcnt = 0x31 */
+	.pwm_period_ns  = 36296,
+	.init           = h1940_backlight_init,
+	.exit           = h1940_backlight_exit,
+};
+
+static struct platform_device h1940_backlight = {
+	.name = "pwm-backlight",
+	.dev  = {
+		.parent = &s3c_device_timer[0].dev,
+		.platform_data = &backlight_data,
+	},
+	.id   = -1,
+};
+
+static void h1940_lcd_power_set(struct plat_lcd_data *pd,
+					unsigned int power)
+{
+	int value;
+
+	if (!power) {
+		/* set to 3ec */
+		s3c2410_gpio_setpin(S3C2410_GPC(0), 0);
+		/* wait for 3ac */
+		do {
+			value = s3c2410_gpio_getpin(S3C2410_GPC(6));
+		} while (value);
+		/* set to 38c */
+		s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+	} else {
+		/* Set to 3ac */
+		s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+		/* Set to 3ad */
+		s3c2410_gpio_setpin(S3C2410_GPC(0), 1);
+	}
+}
+
+static struct plat_lcd_data h1940_lcd_power_data = {
+	.set_power      = h1940_lcd_power_set,
+};
+
+static struct platform_device h1940_lcd_powerdev = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s3c_device_lcd.dev,
+	.dev.platform_data      = &h1940_lcd_power_data,
+};
+
 static struct platform_device *h1940_devices[] __initdata = {
+	&s3c_device_ts,
 	&s3c_device_usb,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
 	&s3c_device_usbgadget,
-	&s3c_device_leds,
-	&s3c_device_bluetooth,
+	&h1940_device_leds,
+	&h1940_device_bluetooth,
+	&s3c_device_sdi,
+	&s3c_device_rtc,
+	&s3c_device_timer[0],
+	&h1940_backlight,
+	&h1940_lcd_powerdev,
 };
 
 static void __init h1940_map_io(void)
@@ -217,8 +312,11 @@ static void __init h1940_init(void)
 
 	s3c24xx_fb_set_platdata(&h1940_fb_info);
  	s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+	s3c24xx_ts_set_platdata(&h1940_ts_cfg);
 	s3c_i2c0_set_platdata(NULL);
 
+	s3c_device_sdi.dev.platform_data = &h1940_mmc_cfg;
+
 	/* Turn off suspend on both USB ports, and switch the
 	 * selectable USB port to USB device mode. */
 
@@ -231,6 +329,11 @@ static void __init h1940_init(void)
 	      | (0x03 << S3C24XX_PLLCON_SDIVSHIFT);
 	writel(tmp, S3C2410_UPLLCON);
 
+	gpio_request(S3C2410_GPC(0), "LCD power");
+	gpio_request(S3C2410_GPC(5), "LCD power");
+	gpio_request(S3C2410_GPC(6), "LCD power");
+
+
 	platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-n30.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-n30.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2010-02-24 13:52:17.000000000 -0500
@@ -338,7 +338,7 @@ static struct platform_device *n35_devic
 	&n35_button_device,
 };
 
-static struct s3c2410_platform_i2c n30_i2ccfg = {
+static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
 	.flags		= 0,
 	.slave_addr	= 0x10,
 	.frequency	= 10*1000,
@@ -500,8 +500,8 @@ static void __init n30_init_irq(void)
 static void __init n30_init(void)
 {
 	s3c24xx_fb_set_platdata(&n30_fb_info);
-	s3c_device_i2c0.dev.platform_data = &n30_i2ccfg;
 	s3c24xx_udc_set_platdata(&n30_udc_cfg);
+	s3c_i2c0_set_platdata(&n30_i2ccfg);
 
 	/* Turn off suspend on both USB ports, and switch the
 	 * selectable USB port to USB device mode. */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2010-02-24 13:52:17.000000000 -0500
@@ -258,7 +258,7 @@ static struct platform_device *qt2410_de
 	&qt2410_led,
 };
 
-static struct mtd_partition qt2410_nand_part[] = {
+static struct mtd_partition __initdata qt2410_nand_part[] = {
 	[0] = {
 		.name	= "U-Boot",
 		.size	= 0x30000,
@@ -286,7 +286,7 @@ static struct mtd_partition qt2410_nand_
 	},
 };
 
-static struct s3c2410_nand_set qt2410_nand_sets[] = {
+static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
 	[0] = {
 		.name		= "NAND",
 		.nr_chips	= 1,
@@ -299,7 +299,7 @@ static struct s3c2410_nand_set qt2410_na
  * chips and beyond.
  */
 
-static struct s3c2410_platform_nand qt2410_nand_info = {
+static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
 	.tacls		= 20,
 	.twrph0		= 60,
 	.twrph1		= 20,
@@ -331,7 +331,7 @@ static void __init qt2410_map_io(void)
 
 static void __init qt2410_machine_init(void)
 {
-	s3c_device_nand.dev.platform_data = &qt2410_nand_info;
+	s3c_nand_set_platdata(&qt2410_nand_info);
 
 	switch (tft_type) {
 	case 'p': /* production */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/mach-vr1000.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-vr1000.c
  *
- * Copyright (c) 2003-2005,2008 Simtec Electronics
+ * Copyright (c) 2003-2008 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Machine support for Thorcom VR1000 board. Designed for Thorcom by
@@ -49,6 +49,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/iic.h>
+#include <plat/audio-simtec.h>
 
 #include "usb-simtec.h"
 #include "nor-simtec.h"
@@ -393,6 +394,7 @@ static void __init vr1000_init(void)
 				ARRAY_SIZE(vr1000_i2c_devs));
 
 	nor_simtec_init();
+	simtec_audio_add(NULL, true, NULL);
 }
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,8 @@ obj-$(CONFIG_S3C2410_PLLTABLE)	+= pll.o
 # Machine support
 
 obj-$(CONFIG_ARCH_SMDK2410)	+= mach-smdk2410.o
-obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o h1940-bluetooth.o
+obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o
+obj-$(CONFIG_H1940BT)		+= h1940-bluetooth.o
 obj-$(CONFIG_PM_H1940)		+= pm-h1940.o
 obj-$(CONFIG_MACH_N30)		+= mach-n30.o
 obj-$(CONFIG_ARCH_BAST)		+= mach-bast.o usb-simtec.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/pll.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/pll.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/pll.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/pll.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/pll.c
  *
- * Copyright (c) 2006,2007 Simtec Electronics
+ * Copyright (c) 2006-2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *	Vincent Sanders <vince@arm.linux.org.uk>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/usb-simtec.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/usb-simtec.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/usb-simtec.c
  *
- * Copyright (c) 2004,2005 Simtec Electronics
+ * Copyright 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -108,7 +108,7 @@ int usb_simtec_init(void)
 {
 	int ret;
 
-	printk("USB Power Control, (c) 2004 Simtec Electronics\n");
+	printk("USB Power Control, Copyright 2004 Simtec Electronics\n");
 
 	ret = gpio_request(S3C2410_GPB(4), "USB power control");
 	if (ret < 0) {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2412/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -90,6 +88,4 @@ config MACH_VSTMS
 	help
 	  Say Y here if you are using an VSTMS board
 
-
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/mach-jive.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-jive.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ static struct s3c2410_uartcfg jive_uartc
  * 0x017d0000-0x02bd0000 : cramfs B
  * 0x02bd0000-0x03fd0000 : yaffs
  */
-static struct mtd_partition jive_imageA_nand_part[] = {
+static struct mtd_partition __initdata jive_imageA_nand_part[] = {
 
 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
 	/* Don't allow access to the bootloader from linux */
@@ -154,7 +154,7 @@ static struct mtd_partition jive_imageA_
         },
 };
 
-static struct mtd_partition jive_imageB_nand_part[] = {
+static struct mtd_partition __initdata jive_imageB_nand_part[] = {
 
 #ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
 	/* Don't allow access to the bootloader from linux */
@@ -213,7 +213,7 @@ static struct mtd_partition jive_imageB_
         },
 };
 
-static struct s3c2410_nand_set jive_nand_sets[] = {
+static struct s3c2410_nand_set __initdata jive_nand_sets[] = {
 	[0] = {
 		.name           = "flash",
 		.nr_chips       = 1,
@@ -222,7 +222,7 @@ static struct s3c2410_nand_set jive_nand
 	},
 };
 
-static struct s3c2410_platform_nand jive_nand_info = {
+static struct s3c2410_platform_nand __initdata jive_nand_info = {
 	/* set taken from osiris nand timings, possibly still conservative */
 	.tacls		= 30,
 	.twrph0		= 55,
@@ -631,7 +631,8 @@ static void __init jive_machine_init(voi
 
 	s3c_pm_init();
 
-	s3c_device_nand.dev.platform_data = &jive_nand_info;
+	/** TODO - check that this is after the cmdline option! */
+	s3c_nand_set_platdata(&jive_nand_info);
 
 	/* initialise the spi */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/mach-vstms.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-vstms.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2412/mach-vstms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2412/mach-vstms.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,7 +76,7 @@ static struct s3c2410_uartcfg vstms_uart
 	}
 };
 
-static struct mtd_partition vstms_nand_part[] = {
+static struct mtd_partition __initdata vstms_nand_part[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= 0x7C000,
@@ -99,7 +99,7 @@ static struct mtd_partition vstms_nand_p
 	},
 };
 
-static struct s3c2410_nand_set vstms_nand_sets[] = {
+static struct s3c2410_nand_set __initdata vstms_nand_sets[] = {
 	[0] = {
 		.name		= "NAND",
 		.nr_chips	= 1,
@@ -112,7 +112,7 @@ static struct s3c2410_nand_set vstms_nan
  * chips and beyond.
 */
 
-static struct s3c2410_platform_nand vstms_nand_info = {
+static struct s3c2410_platform_nand __initdata vstms_nand_info = {
 	.tacls		= 20,
 	.twrph0		= 60,
 	.twrph1		= 20,
@@ -143,8 +143,6 @@ static void __init vstms_fixup(struct ma
 
 static void __init vstms_map_io(void)
 {
-	s3c_device_nand.dev.platform_data = &vstms_nand_info;
-
 	s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
@@ -153,6 +151,8 @@ static void __init vstms_map_io(void)
 static void __init vstms_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
+	s3c_nand_set_platdata(&vstms_nand_info);
+
 	platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/irq.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2440/irq.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2440/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -53,6 +51,19 @@ config MACH_OSIRIS
 	  Say Y here if you are using the Simtec IM2440D20 module, also
 	  known as the Osiris.
 
+config MACH_OSIRIS_DVS
+	tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
+	depends on MACH_OSIRIS
+	select TPS65010
+	help
+	  Say Y/M here if you want to have dynamic voltage scaling support
+	  on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.
+
+	  The DVS driver alters the voltage supplied to the ARM core
+	  depending on the frequency it is running at. The driver itself
+	  does not do any of the frequency alteration, which is left up
+	  to the cpufreq driver.
+
 config MACH_RX3715
 	bool "HP iPAQ rx3715"
 	select CPU_S3C2440
@@ -109,4 +120,3 @@ config MACH_MINI2440
 	  available via various sources. It can come with a 3.5" or 7" touch LCD.
 
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-anubis.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-anubis.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2440/mach-anubis.c
  *
- * Copyright (c) 2003-2005,2008 Simtec Electronics
+ * Copyright 2003-2009 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
@@ -53,8 +53,9 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/audio-simtec.h>
 
-#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics"
 
 static struct map_desc anubis_iodesc[] __initdata = {
   /* ISA IO areas */
@@ -138,7 +139,7 @@ static int external_map[]   = { 2 };
 static int chip0_map[]      = { 0 };
 static int chip1_map[]      = { 1 };
 
-static struct mtd_partition anubis_default_nand_part[] = {
+static struct mtd_partition __initdata anubis_default_nand_part[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_16K,
@@ -161,7 +162,7 @@ static struct mtd_partition anubis_defau
 	}
 };
 
-static struct mtd_partition anubis_default_nand_part_large[] = {
+static struct mtd_partition __initdata anubis_default_nand_part_large[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_128K,
@@ -191,7 +192,7 @@ static struct mtd_partition anubis_defau
  * socket.
 */
 
-static struct s3c2410_nand_set anubis_nand_sets[] = {
+static struct s3c2410_nand_set __initdata anubis_nand_sets[] = {
 	[1] = {
 		.name		= "External",
 		.nr_chips	= 1,
@@ -233,7 +234,7 @@ static void anubis_nand_select(struct s3
 	__raw_writeb(tmp, ANUBIS_VA_CTRL1);
 }
 
-static struct s3c2410_platform_nand anubis_nand_info = {
+static struct s3c2410_platform_nand __initdata anubis_nand_info = {
 	.tacls		= 25,
 	.twrph0		= 55,
 	.twrph1		= 40,
@@ -437,6 +438,17 @@ static struct i2c_board_info anubis_i2c_
 	}
 };
 
+/* Audio setup */
+static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
+	.have_mic	= 1,
+	.have_lout	= 1,
+	.output_cdclk	= 1,
+	.use_mpllin	= 1,
+	.amp_gpio	= S3C2410_GPB(2),
+	.amp_gain[0]	= S3C2410_GPD(10),
+	.amp_gain[1]	= S3C2410_GPD(11),
+};
+
 static void __init anubis_map_io(void)
 {
 	/* initialise the clocks */
@@ -454,8 +466,6 @@ static void __init anubis_map_io(void)
 
 	s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
 
-	s3c_device_nand.dev.platform_data = &anubis_nand_info;
-
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
@@ -476,6 +486,9 @@ static void __init anubis_map_io(void)
 static void __init anubis_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
+	s3c_nand_set_platdata(&anubis_nand_info);
+	simtec_audio_add(NULL, false, &anubis_audio);
+
 	platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
 
 	i2c_register_board_info(0, anubis_i2c_devs,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-at2440evb.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ static struct s3c2410_uartcfg at2440evb_
 
 /* NAND Flash on AT2440EVB board */
 
-static struct mtd_partition at2440evb_default_nand_part[] = {
+static struct mtd_partition __initdata at2440evb_default_nand_part[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_256K,
@@ -114,7 +114,7 @@ static struct mtd_partition at2440evb_de
 	},
 };
 
-static struct s3c2410_nand_set at2440evb_nand_sets[] = {
+static struct s3c2410_nand_set __initdata at2440evb_nand_sets[] = {
 	[0] = {
 		.name		= "nand",
 		.nr_chips	= 1,
@@ -123,7 +123,7 @@ static struct s3c2410_nand_set at2440evb
 	},
 };
 
-static struct s3c2410_platform_nand at2440evb_nand_info = {
+static struct s3c2410_platform_nand __initdata at2440evb_nand_info = {
 	.tacls		= 25,
 	.twrph0		= 55,
 	.twrph1		= 40,
@@ -216,8 +216,6 @@ static struct platform_device *at2440evb
 
 static void __init at2440evb_map_io(void)
 {
-	s3c_device_nand.dev.platform_data = &at2440evb_nand_info;
-	s3c_device_sdi.name = "s3c2440-sdi";
 	s3c_device_sdi.dev.platform_data = &at2440evb_mci_pdata;
 
 	s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
@@ -228,6 +226,7 @@ static void __init at2440evb_map_io(void
 static void __init at2440evb_init(void)
 {
 	s3c24xx_fb_set_platdata(&at2440evb_fb_info);
+	s3c_nand_set_platdata(&at2440evb_nand_info);
 	s3c_i2c0_set_platdata(NULL);
 
 	platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-mini2440.c	2010-02-24 13:52:17.000000000 -0500
@@ -288,7 +288,7 @@ static struct s3c2410_platform_nand mini
 
 /* DM9000AEP 10/100 ethernet controller */
 
-static struct resource mini2440_dm9k_resource[] __initdata = {
+static struct resource mini2440_dm9k_resource[] = {
 	[0] = {
 		.start = MACH_MINI2440_DM9K_BASE,
 		.end   = MACH_MINI2440_DM9K_BASE + 3,
@@ -310,11 +310,11 @@ static struct resource mini2440_dm9k_res
  * The DM9000 has no eeprom, and it's MAC address is set by
  * the bootloader before starting the kernel.
  */
-static struct dm9000_plat_data mini2440_dm9k_pdata __initdata = {
+static struct dm9000_plat_data mini2440_dm9k_pdata = {
 	.flags		= (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
 };
 
-static struct platform_device mini2440_device_eth __initdata = {
+static struct platform_device mini2440_device_eth = {
 	.name		= "dm9000",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(mini2440_dm9k_resource),
@@ -341,7 +341,7 @@ static struct platform_device mini2440_d
  *	|  |  +----+  +----+
  *	  .....
  */
-static struct gpio_keys_button mini2440_buttons[] __initdata = {
+static struct gpio_keys_button mini2440_buttons[] = {
 	{
 		.gpio		= S3C2410_GPG(0),		/* K1 */
 		.code		= KEY_F1,
@@ -384,12 +384,12 @@ static struct gpio_keys_button mini2440_
 #endif
 };
 
-static struct gpio_keys_platform_data mini2440_button_data __initdata = {
+static struct gpio_keys_platform_data mini2440_button_data = {
 	.buttons	= mini2440_buttons,
 	.nbuttons	= ARRAY_SIZE(mini2440_buttons),
 };
 
-static struct platform_device mini2440_button_device __initdata = {
+static struct platform_device mini2440_button_device = {
 	.name		= "gpio-keys",
 	.id		= -1,
 	.dev		= {
@@ -399,41 +399,41 @@ static struct platform_device mini2440_b
 
 /* LEDS */
 
-static struct s3c24xx_led_platdata mini2440_led1_pdata __initdata = {
+static struct s3c24xx_led_platdata mini2440_led1_pdata = {
 	.name		= "led1",
 	.gpio		= S3C2410_GPB(5),
 	.flags		= S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
 	.def_trigger	= "heartbeat",
 };
 
-static struct s3c24xx_led_platdata mini2440_led2_pdata __initdata = {
+static struct s3c24xx_led_platdata mini2440_led2_pdata = {
 	.name		= "led2",
 	.gpio		= S3C2410_GPB(6),
 	.flags		= S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
 	.def_trigger	= "nand-disk",
 };
 
-static struct s3c24xx_led_platdata mini2440_led3_pdata __initdata = {
+static struct s3c24xx_led_platdata mini2440_led3_pdata = {
 	.name		= "led3",
 	.gpio		= S3C2410_GPB(7),
 	.flags		= S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
 	.def_trigger	= "mmc0",
 };
 
-static struct s3c24xx_led_platdata mini2440_led4_pdata __initdata = {
+static struct s3c24xx_led_platdata mini2440_led4_pdata = {
 	.name		= "led4",
 	.gpio		= S3C2410_GPB(8),
 	.flags		= S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
 	.def_trigger	= "",
 };
 
-static struct s3c24xx_led_platdata mini2440_led_backlight_pdata __initdata = {
+static struct s3c24xx_led_platdata mini2440_led_backlight_pdata = {
 	.name		= "backlight",
 	.gpio		= S3C2410_GPG(4),
 	.def_trigger	= "backlight",
 };
 
-static struct platform_device mini2440_led1 __initdata = {
+static struct platform_device mini2440_led1 = {
 	.name		= "s3c24xx_led",
 	.id		= 1,
 	.dev		= {
@@ -441,7 +441,7 @@ static struct platform_device mini2440_l
 	},
 };
 
-static struct platform_device mini2440_led2 __initdata = {
+static struct platform_device mini2440_led2 = {
 	.name		= "s3c24xx_led",
 	.id		= 2,
 	.dev		= {
@@ -449,7 +449,7 @@ static struct platform_device mini2440_l
 	},
 };
 
-static struct platform_device mini2440_led3 __initdata = {
+static struct platform_device mini2440_led3 = {
 	.name		= "s3c24xx_led",
 	.id		= 3,
 	.dev		= {
@@ -457,7 +457,7 @@ static struct platform_device mini2440_l
 	},
 };
 
-static struct platform_device mini2440_led4 __initdata = {
+static struct platform_device mini2440_led4 = {
 	.name		= "s3c24xx_led",
 	.id		= 4,
 	.dev		= {
@@ -465,7 +465,7 @@ static struct platform_device mini2440_l
 	},
 };
 
-static struct platform_device mini2440_led_backlight __initdata = {
+static struct platform_device mini2440_led_backlight = {
 	.name		= "s3c24xx_led",
 	.id		= 5,
 	.dev		= {
@@ -475,14 +475,14 @@ static struct platform_device mini2440_l
 
 /* AUDIO */
 
-static struct s3c24xx_uda134x_platform_data mini2440_audio_pins __initdata = {
+static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = {
 	.l3_clk = S3C2410_GPB(4),
 	.l3_mode = S3C2410_GPB(2),
 	.l3_data = S3C2410_GPB(3),
 	.model = UDA134X_UDA1341
 };
 
-static struct platform_device mini2440_audio __initdata = {
+static struct platform_device mini2440_audio = {
 	.name		= "s3c24xx_uda134x",
 	.id		= 0,
 	.dev		= {
@@ -532,7 +532,6 @@ static void __init mini2440_map_io(void)
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
 
-	s3c_device_nand.dev.platform_data = &mini2440_nand_info;
 	s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
 }
 
@@ -677,8 +676,11 @@ static void __init mini2440_init(void)
 		printk("\n");
 		s3c24xx_fb_set_platdata(&mini2440_fb_info);
 	}
+
 	s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
+	s3c_nand_set_platdata(&mini2440_nand_info);
 	s3c_i2c0_set_platdata(NULL);
+
 	i2c_register_board_info(0, mini2440_i2c_devs,
 				ARRAY_SIZE(mini2440_i2c_devs));
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-osiris.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-osiris.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-osiris.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-osiris.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2440/mach-osiris.c
  *
- * Copyright (c) 2005,2008 Simtec Electronics
+ * Copyright (c) 2005-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
@@ -23,6 +23,8 @@
 #include <linux/i2c.h>
 #include <linux/io.h>
 
+#include <linux/i2c/tps65010.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -148,7 +150,7 @@ static int external_map[]   = { 2 };
 static int chip0_map[]      = { 0 };
 static int chip1_map[]      = { 1 };
 
-static struct mtd_partition osiris_default_nand_part[] = {
+static struct mtd_partition __initdata osiris_default_nand_part[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_16K,
@@ -171,7 +173,7 @@ static struct mtd_partition osiris_defau
 	}
 };
 
-static struct mtd_partition osiris_default_nand_part_large[] = {
+static struct mtd_partition __initdata osiris_default_nand_part_large[] = {
 	[0] = {
 		.name	= "Boot Agent",
 		.size	= SZ_128K,
@@ -201,11 +203,12 @@ static struct mtd_partition osiris_defau
  * socket.
 */
 
-static struct s3c2410_nand_set osiris_nand_sets[] = {
+static struct s3c2410_nand_set __initdata osiris_nand_sets[] = {
 	[1] = {
 		.name		= "External",
 		.nr_chips	= 1,
 		.nr_map		= external_map,
+		.options	= NAND_SCAN_SILENT_NODEV,
 		.nr_partitions	= ARRAY_SIZE(osiris_default_nand_part),
 		.partitions	= osiris_default_nand_part,
 	},
@@ -220,6 +223,7 @@ static struct s3c2410_nand_set osiris_na
 		.name		= "chip1",
 		.nr_chips	= 1,
 		.nr_map		= chip1_map,
+		.options	= NAND_SCAN_SILENT_NODEV,
 		.nr_partitions	= ARRAY_SIZE(osiris_default_nand_part),
 		.partitions	= osiris_default_nand_part,
 	},
@@ -243,7 +247,7 @@ static void osiris_nand_select(struct s3
 	__raw_writeb(tmp, OSIRIS_VA_CTRL0);
 }
 
-static struct s3c2410_platform_nand osiris_nand_info = {
+static struct s3c2410_platform_nand __initdata osiris_nand_info = {
 	.tacls		= 25,
 	.twrph0		= 60,
 	.twrph1		= 60,
@@ -326,12 +330,44 @@ static struct sys_device osiris_pm_sysde
 	.cls		= &osiris_pm_sysclass,
 };
 
+/* Link for DVS driver to TPS65011 */
+
+static void osiris_tps_release(struct device *dev)
+{
+	/* static device, do not need to release anything */
+}
+
+static struct platform_device osiris_tps_device = {
+	.name	= "osiris-dvs",
+	.id	= -1,
+	.dev.release = osiris_tps_release,
+};
+
+static int osiris_tps_setup(struct i2c_client *client, void *context)
+{
+	osiris_tps_device.dev.parent = &client->dev;
+	return platform_device_register(&osiris_tps_device);
+}
+
+static int osiris_tps_remove(struct i2c_client *client, void *context)
+{
+	platform_device_unregister(&osiris_tps_device);
+	return 0;
+}
+
+static struct tps65010_board osiris_tps_board = {
+	.base		= -1,	/* GPIO can go anywhere at the moment */
+	.setup		= osiris_tps_setup,
+	.teardown	= osiris_tps_remove,
+};
+
 /* I2C devices fitted. */
 
 static struct i2c_board_info osiris_i2c_devs[] __initdata = {
 	{
 		I2C_BOARD_INFO("tps65011", 0x48),
 		.irq	= IRQ_EINT20,
+		.platform_data = &osiris_tps_board,
 	},
 };
 
@@ -377,8 +413,6 @@ static void __init osiris_map_io(void)
 
 	s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
 
-	s3c_device_nand.dev.platform_data = &osiris_nand_info;
-
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
@@ -408,6 +442,7 @@ static void __init osiris_init(void)
 	sysdev_register(&osiris_pm_sysdev);
 
 	s3c_i2c0_set_platdata(NULL);
+	s3c_nand_set_platdata(&osiris_nand_info);
 
 	s3c_cpufreq_setboard(&osiris_cpufreq);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-osiris-dvs.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-osiris-dvs.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-osiris-dvs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-osiris-dvs.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,194 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris-dvs.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec Osiris Dynamic Voltage Scaling 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <plat/cpu-freq.h>
+
+#define OSIRIS_GPIO_DVS	S3C2410_GPB(5)
+
+static bool dvs_en;
+
+static void osiris_dvs_tps_setdvs(bool on)
+{
+	unsigned vregs1 = 0, vdcdc2 = 0;
+
+	if (!on) {
+		vdcdc2 = TPS_VCORE_DISCH | TPS_LP_COREOFF;
+		vregs1 = TPS_LDO1_OFF;	/* turn off in low-power mode */
+	}
+
+	dvs_en = on;
+	vdcdc2 |= TPS_VCORE_1_3V | TPS_VCORE_LP_1_0V;
+	vregs1 |= TPS_LDO2_ENABLE | TPS_LDO1_ENABLE;
+
+	tps65010_config_vregs1(vregs1);
+	tps65010_config_vdcdc2(vdcdc2);
+}
+
+static bool is_dvs(struct s3c_freq *f)
+{
+	/* at the moment, we assume ARMCLK = HCLK => DVS */
+	return f->armclk == f->hclk;
+}
+
+/* keep track of current state */
+static bool cur_dvs = false;
+
+static int osiris_dvs_notify(struct notifier_block *nb,
+			      unsigned long val, void *data)
+{
+	struct cpufreq_freqs *cf = data;
+	struct s3c_cpufreq_freqs *freqs = to_s3c_cpufreq(cf);
+	bool old_dvs = is_dvs(&freqs->old);
+	bool new_dvs = is_dvs(&freqs->new);
+	int ret = 0;
+
+	if (!dvs_en)
+		return 0;
+
+	printk(KERN_DEBUG "%s: old %ld,%ld new %ld,%ld\n", __func__,
+	       freqs->old.armclk, freqs->old.hclk,
+	       freqs->new.armclk, freqs->new.hclk);
+
+	switch (val) {
+	case CPUFREQ_PRECHANGE:
+		if (old_dvs & !new_dvs ||
+		    cur_dvs & !new_dvs) {
+			pr_debug("%s: exiting dvs\n", __func__);
+			cur_dvs = false;
+			gpio_set_value(OSIRIS_GPIO_DVS, 1);
+		}
+		break;
+	case CPUFREQ_POSTCHANGE:
+		if (!old_dvs & new_dvs ||
+		    !cur_dvs & new_dvs) {
+			pr_debug("entering dvs\n");
+			cur_dvs = true;
+			gpio_set_value(OSIRIS_GPIO_DVS, 0);
+		}
+		break;
+	}
+
+	return ret;
+}
+
+static struct notifier_block osiris_dvs_nb = {
+	.notifier_call	= osiris_dvs_notify,
+};
+
+static int __devinit osiris_dvs_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	dev_info(&pdev->dev, "initialising\n");
+
+	ret = gpio_request(OSIRIS_GPIO_DVS, "osiris-dvs");
+	if (ret) {
+		dev_err(&pdev->dev, "cannot claim gpio\n");
+		goto err_nogpio;
+	}
+
+	/* start with dvs disabled */
+	gpio_direction_output(OSIRIS_GPIO_DVS, 1);
+
+	ret = cpufreq_register_notifier(&osiris_dvs_nb,
+					CPUFREQ_TRANSITION_NOTIFIER);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register with cpufreq\n");
+		goto err_nofreq;
+	}
+
+	osiris_dvs_tps_setdvs(true);
+
+	return 0;
+
+err_nofreq:
+	gpio_free(OSIRIS_GPIO_DVS);
+
+err_nogpio:
+	return ret;
+}
+
+static int __devexit osiris_dvs_remove(struct platform_device *pdev)
+{
+	dev_info(&pdev->dev, "exiting\n");
+
+	/* disable any current dvs */
+	gpio_set_value(OSIRIS_GPIO_DVS, 1);
+	osiris_dvs_tps_setdvs(false);
+
+	cpufreq_unregister_notifier(&osiris_dvs_nb,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+
+	gpio_free(OSIRIS_GPIO_DVS);
+
+	return 0;
+}
+
+/* the CONFIG_PM block is so small, it isn't worth actaully compiling it
+ * out if the configuration isn't set. */
+
+static int osiris_dvs_suspend(struct device *dev)
+{
+	gpio_set_value(OSIRIS_GPIO_DVS, 1);
+	osiris_dvs_tps_setdvs(false);
+	cur_dvs = false;
+
+	return 0;
+}
+
+static int osiris_dvs_resume(struct device *dev)
+{
+	osiris_dvs_tps_setdvs(true);
+	return 0;
+}
+
+static const struct dev_pm_ops osiris_dvs_pm = {
+	.suspend	= osiris_dvs_suspend,
+	.resume		= osiris_dvs_resume,
+};
+
+static struct platform_driver osiris_dvs_driver = {
+	.probe		= osiris_dvs_probe,
+	.remove		= __devexit_p(osiris_dvs_remove),
+	.driver		= {
+		.name	= "osiris-dvs",
+		.owner	= THIS_MODULE,
+		.pm	= &osiris_dvs_pm,
+	},
+};
+
+static int __init osiris_dvs_init(void)
+{
+	return platform_driver_register(&osiris_dvs_driver);
+}
+
+static void __exit osiris_dvs_exit(void)
+{
+	platform_driver_unregister(&osiris_dvs_driver);
+}
+
+module_init(osiris_dvs_init);
+module_exit(osiris_dvs_exit);
+
+MODULE_DESCRIPTION("Simtec OSIRIS DVS support");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:osiris-dvs");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2440/mach-rx3715.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.handhelds.org/projects/rx3715.html
@@ -149,7 +149,7 @@ static struct s3c2410fb_mach_info rx3715
 	.gpdup_mask =	0xffffffff,
 };
 
-static struct mtd_partition rx3715_nand_part[] = {
+static struct mtd_partition __initdata rx3715_nand_part[] = {
 	[0] = {
 		.name		= "Whole Flash",
 		.offset		= 0,
@@ -158,7 +158,7 @@ static struct mtd_partition rx3715_nand_
 	}
 };
 
-static struct s3c2410_nand_set rx3715_nand_sets[] = {
+static struct s3c2410_nand_set __initdata rx3715_nand_sets[] = {
 	[0] = {
 		.name		= "Internal",
 		.nr_chips	= 1,
@@ -167,7 +167,7 @@ static struct s3c2410_nand_set rx3715_na
 	},
 };
 
-static struct s3c2410_platform_nand rx3715_nand_info = {
+static struct s3c2410_platform_nand __initdata rx3715_nand_info = {
 	.tacls		= 25,
 	.twrph0		= 50,
 	.twrph1		= 15,
@@ -186,8 +186,6 @@ static struct platform_device *rx3715_de
 
 static void __init rx3715_map_io(void)
 {
-	s3c_device_nand.dev.platform_data = &rx3715_nand_info;
-
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
@@ -205,6 +203,7 @@ static void __init rx3715_init_machine(v
 #endif
 	s3c_pm_init();
 
+	s3c_nand_set_platdata(&rx3715_nand_info);
 	s3c24xx_fb_set_platdata(&rx3715_fb_info);
 	platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/mach-smdk2440.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
  *
- * Copyright (c) 2004,2005 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.fluff.org/ben/smdk2440/
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2440/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2440/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -23,3 +23,7 @@ obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
+
+# extra machine support
+
+obj-$(CONFIG_MACH_OSIRIS_DVS)	+= mach-osiris-dvs.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2442/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2442/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2442/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -36,6 +34,4 @@ config MACH_NEO1973_GTA02
 	help
 	   Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
 
-
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2442/mach-gta02.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/mach-gta02.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2442/mach-gta02.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2442/mach-gta02.c	2010-02-24 13:52:17.000000000 -0500
@@ -268,6 +268,9 @@ struct pcf50633_platform_data gta02_pcf_
 
 	.batteries = gta02_batteries,
 	.num_batteries = ARRAY_SIZE(gta02_batteries),
+
+	.charger_reference_current_ma = 1000,
+
 	.reg_init_data = {
 		[PCF50633_REGULATOR_AUTO] = {
 			.constraints = {
@@ -423,7 +426,7 @@ static struct i2c_board_info gta02_i2c_d
 	},
 };
 
-static struct s3c2410_nand_set gta02_nand_sets[] = {
+static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
 	[0] = {
 		/*
 		 * This name is also hard-coded in the boot loaders, so
@@ -442,7 +445,7 @@ static struct s3c2410_nand_set gta02_nan
  * data sheet (K5D2G13ACM-D075 MCP Memory).
  */
 
-static struct s3c2410_platform_nand gta02_nand_info = {
+static struct s3c2410_platform_nand __initdata gta02_nand_info = {
 	.tacls		= 0,
 	.twrph0		= 25,
 	.twrph1		= 15,
@@ -621,9 +624,9 @@ static void __init gta02_machine_init(vo
 #endif
 
 	s3c_device_usb.dev.platform_data = &gta02_usb_info;
-	s3c_device_nand.dev.platform_data = &gta02_nand_info;
 
 	s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+	s3c_nand_set_platdata(&gta02_nand_info);
 	s3c_i2c0_set_platdata(NULL);
 
 	i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2443/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c2443/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c2443/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c2443/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/map.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c24a0/include/mach/map.h
  *
- * Copyright 2003,2007  Simtec Electronics
+ * Copyright 2003-2007  Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,5 +15,7 @@
 
 #define __virt_to_bus(x) __virt_to_phys(x)
 #define __bus_to_virt(x) __phys_to_virt(x)
+#define __pfn_to_bus(x) __pfn_to_phys(x)
+#define __bus_to_pfn(x)	__phys_to_pfn(x)
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/regs-clock.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c24a0/include/mach/regs-clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c24a0/include/mach/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
  *
- * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
- *		      http://armlinux.simtec.co.uk/
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@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
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/include/mach/map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,8 @@
 #define S3C64XX_PA_IIS1		(0x7F003000)
 #define S3C64XX_PA_TIMER	(0x7F006000)
 #define S3C64XX_PA_IIC0		(0x7F004000)
+#define S3C64XX_PA_PCM0		(0x7F009000)
+#define S3C64XX_PA_PCM1		(0x7F00A000)
 #define S3C64XX_PA_IISV4	(0x7F00D000)
 #define S3C64XX_PA_IIC1		(0x7F00F000)
 
@@ -64,6 +66,9 @@
 
 #define S3C64XX_PA_USBHOST	(0x74300000)
 
+#define S3C64XX_PA_USB_HSPHY	(0x7C100000)
+#define S3C64XX_VA_USB_HSPHY	S3C_ADDR_CPU(0x00200000)
+
 /* place VICs close together */
 #define S3C_VA_VIC0		(S3C_VA_IRQ + 0x00)
 #define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
@@ -79,5 +84,6 @@
 #define S3C_PA_FB		S3C64XX_PA_FB
 #define S3C_PA_USBHOST		S3C64XX_PA_USBHOST
 #define S3C_PA_USB_HSOTG	S3C64XX_PA_USB_HSOTG
+#define S3C_VA_USB_HSPHY	S3C64XX_VA_USB_HSPHY
 
 #endif /* __ASM_ARCH_6400_MAP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/include/mach/regs-fb.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,195 +1,30 @@
-/* arch/arm/mach-s3c6400/include/mach/regs-fb.h
- *
+/*
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - new-style framebuffer register definitions
+ * Copyright 2009 Samsung Electronics Co.
  *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards and specifically the S3C64XX series
- * S3C6400 and S3C6410.
+ * Pawel Osciak <p.osciak@samsung.com>
+ * Based on plat-s3c/include/plat/regs-fb.h by Ben Dooks <ben@simtec.co.uk>
  *
- * The file contains the cpu specific items which change between whichever
- * architecture is selected. See <plat/regs-fb.h> for the core definitions
- * that are the same.
+ * Framebuffer register definitions for Samsung S3C64xx.
  *
  * This 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 the core definitions here, in case we really do need to
- * override them at a later date.
-*/
-
-#include <plat/regs-fb.h>
-
-#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
-#define VIDCON1_FSTATUS_EVEN	(1 << 15)
-
-/* Video timing controls */
-#define VIDTCON0				(0x10)
-#define VIDTCON1				(0x14)
-#define VIDTCON2				(0x18)
-
-/* Window position controls */
-
-#define WINCON(_win)				(0x20 + ((_win) * 4))
-
-/* OSD1 and OSD4 do not have register D */
-
-#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
-#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
-#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
-#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
-
-/* Video buffer addresses */
-
-#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
-#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
-#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
-#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
-#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
-
-#define VIDINTCON0				(0x130)
-
-#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
-
-/* WINCONx */
-
-#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
-#define WINCONx_CSCWIDTH_SHIFT			(26)
-#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
-#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
-
-#define WINCONx_ENLOCAL				(1 << 22)
-#define WINCONx_BUFSTATUS			(1 << 21)
-#define WINCONx_BUFSEL				(1 << 20)
-#define WINCONx_BUFAUTOEN			(1 << 19)
-#define WINCONx_YCbCr				(1 << 13)
-
-#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
-
-#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
-#define WINCON2_BLD_PIX				(1 << 6)
-
-#define WINCON2_ALPHA_SEL			(1 << 1)
-#define WINCON2_BPPMODE_MASK			(0xf << 2)
-#define WINCON2_BPPMODE_SHIFT			(2)
-#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
-#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define WINCON3_BLD_PIX				(1 << 6)
-
-#define WINCON3_ALPHA_SEL			(1 << 1)
-#define WINCON3_BPPMODE_MASK			(0xf << 2)
-#define WINCON3_BPPMODE_SHIFT			(2)
-#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
-
-#define DITHMODE				(0x170)
-#define WINxMAP(_win)				(0x180 + ((_win) * 4))
-
-
-#define DITHMODE_R_POS_MASK			(0x3 << 5)
-#define DITHMODE_R_POS_SHIFT			(5)
-#define DITHMODE_R_POS_8BIT			(0x0 << 5)
-#define DITHMODE_R_POS_6BIT			(0x1 << 5)
-#define DITHMODE_R_POS_5BIT			(0x2 << 5)
-
-#define DITHMODE_G_POS_MASK			(0x3 << 3)
-#define DITHMODE_G_POS_SHIFT			(3)
-#define DITHMODE_G_POS_8BIT			(0x0 << 3)
-#define DITHMODE_G_POS_6BIT			(0x1 << 3)
-#define DITHMODE_G_POS_5BIT			(0x2 << 3)
-
-#define DITHMODE_B_POS_MASK			(0x3 << 1)
-#define DITHMODE_B_POS_SHIFT			(1)
-#define DITHMODE_B_POS_8BIT			(0x0 << 1)
-#define DITHMODE_B_POS_6BIT			(0x1 << 1)
-#define DITHMODE_B_POS_5BIT			(0x2 << 1)
-
-#define DITHMODE_DITH_EN			(1 << 0)
-
-#define WPALCON					(0x1A0)
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
 
-#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
-#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
-#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+#include <plat/regs-fb-v4.h>
 
 /* Palette registers */
-
 #define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
 #define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
 #define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
 #define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
 #define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
 
-/* system specific implementation code for palette sizes, and other
- * information that changes depending on which architecture is being
- * compiled.
-*/
-
-/* return true if window _win has OSD register D */
-#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
-
-static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
-{
-	if (win < 2)
-		return 256;
-	if (win < 4)
-		return 16;
-	if (win == 4)
-		return 4;
-
-	BUG();	/* shouldn't get here */
-}
-
-static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
-{
-	/* all windows can do 1/2 bpp */
-
-	if ((bpp == 25 || bpp == 19) && win == 0)
-		return 0;	/* win 0 does not have 19 or 25bpp modes */
-
-	if (bpp == 4 && win == 4)
-		return 0;
-
-	if (bpp == 8 && (win >= 3))
-		return 0;	/* win 3/4 cannot do 8bpp in any mode */
-
-	return 1;
-}
-
 static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
 {
 	switch (window) {
@@ -203,57 +38,4 @@ static inline unsigned int s3c_fb_pal_re
 	BUG();
 }
 
-static inline int s3c_fb_pal_is16(unsigned int window)
-{
-	return window > 1;
-}
-
-struct s3c_fb_palette {
-	struct fb_bitfield	r;
-	struct fb_bitfield	g;
-	struct fb_bitfield	b;
-	struct fb_bitfield	a;
-};
-
-static inline void s3c_fb_init_palette(unsigned int window,
-				       struct s3c_fb_palette *palette)
-{
-	if (window < 2) {
-		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
-		palette->r.offset = 16;
-		palette->r.length = 8;
-		palette->g.offset = 8;
-		palette->g.length = 8;
-		palette->b.offset = 0;
-		palette->b.length = 8;
-	} else {
-		/* currently we assume RGB 5/6/5 */
-		palette->r.offset = 11;
-		palette->r.length = 5;
-		palette->g.offset = 5;
-		palette->g.length = 6;
-		palette->b.offset = 0;
-		palette->b.length = 5;
-	}
-}
-
-/* Notes on per-window bpp settings
- *
- * Value	Win0	 Win1	  Win2	   Win3	    Win 4
- * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
- * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
- * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
- * 0011		8(P)	 8(P)     -none-   -none-   -none-
- * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
- * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
- * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
- * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
- * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
- * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
- * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
- * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
- * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
- * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
- * 1110		-none-	 -none-	  -none-   -none-    -none-
- * 1111		-none-	 -none-   -none-   -none-    -none-
-*/
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c6400/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 #	Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/s3c6400.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/s3c6400.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/s3c6400.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/s3c6400.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,6 +45,7 @@ void __init s3c6400_map_io(void)
 
 	s3c6400_default_sdhci0();
 	s3c6400_default_sdhci1();
+	s3c6400_default_sdhci2();
 
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6400/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,7 @@ char *s3c6400_hsmmc_clksrcs[4] = {
 	[0] = "hsmmc",
 	[1] = "hsmmc",
 	[2] = "mmc_bus",
-	/* [3] = "48m", - note not succesfully used yet */
+	/* [3] = "48m", - note not successfully used yet */
 };
 
 void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/cpu.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,6 +58,7 @@ void __init s3c6410_map_io(void)
 	/* initialise device information early */
 	s3c6410_default_sdhci0();
 	s3c6410_default_sdhci1();
+	s3c6410_default_sdhci2();
 
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s3c6410/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 # Copyright 2008 Simtec Electronics
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/mach-hmt.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-hmt.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/mach-hmt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-hmt.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,7 @@ static int hmt_bl_init(struct device *de
 	return ret;
 }
 
-static int hmt_bl_notify(int brightness)
+static int hmt_bl_notify(struct device *dev, int brightness)
 {
 	/*
 	 * translate from CIELUV/CIELAB L*->brightness, E.G. from
@@ -250,7 +250,7 @@ static void __init hmt_machine_init(void
 {
 	s3c_i2c0_set_platdata(NULL);
 	s3c_fb_set_platdata(&hmt_lcd_pdata);
-	s3c_device_nand.dev.platform_data = &hmt_nand_info;
+	s3c_nand_set_platdata(&hmt_nand_info);
 
 	gpio_request(S3C64XX_GPC(7), "usb power");
 	gpio_direction_output(S3C64XX_GPC(7), 0);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
 
 #ifdef CONFIG_SMDK6410_WM1190_EV1
 #include <linux/mfd/wm8350/core.h>
@@ -184,6 +185,44 @@ static struct platform_device smdk6410_s
 	},
 };
 
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
+	{
+		/* WM8580 */
+		.supply = "PVDD",
+		.dev_name = "0-001b",
+	},
+	{
+		/* WM8580 */
+		.supply = "AVDD",
+		.dev_name = "0-001b",
+	},
+};
+
+static struct regulator_init_data smdk6410_b_pwr_5v_data = {
+	.constraints = {
+		.always_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
+	.consumer_supplies = smdk6410_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
+	.supply_name = "B_PWR_5V",
+	.microvolts = 5000000,
+	.init_data = &smdk6410_b_pwr_5v_data,
+	.gpio = -EINVAL,
+};
+
+static struct platform_device smdk6410_b_pwr_5v = {
+	.name          = "reg-fixed-voltage",
+	.id            = -1,
+	.dev = {
+		.platform_data = &smdk6410_b_pwr_5v_pdata,
+	},
+};
+#endif
+
 static struct map_desc smdk6410_iodesc[] = {};
 
 static struct platform_device *smdk6410_devices[] __initdata = {
@@ -198,6 +237,10 @@ static struct platform_device *smdk6410_
 	&s3c_device_fb,
 	&s3c_device_usb,
 	&s3c_device_usb_hsotg,
+
+#ifdef CONFIG_REGULATOR
+	&smdk6410_b_pwr_5v,
+#endif
 	&smdk6410_lcd_powerdev,
 
 	&smdk6410_smsc911x,
@@ -232,6 +275,14 @@ static struct regulator_init_data wm8350
 };
 
 /* USB, EXT, PCM, ADC/DAC, USB, MMC */
+static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
+	{
+		/* WM8580 */
+		.supply = "DVDD",
+		.dev_name = "0-001b",
+	},
+};
+
 static struct regulator_init_data wm8350_dcdc4_data = {
 	.constraints = {
 		.name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
@@ -239,6 +290,8 @@ static struct regulator_init_data wm8350
 		.max_uV = 3000000,
 		.always_on = 1,
 	},
+	.num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
+	.consumer_supplies = wm8350_dcdc4_consumers,
 };
 
 /* ARM core */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s3c6410/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,7 @@ char *s3c6410_hsmmc_clksrcs[4] = {
 	[0] = "hsmmc",
 	[1] = "hsmmc",
 	[2] = "mmc_bus",
-	/* [3] = "48m", - note not succesfully used yet */
+	/* [3] = "48m", - note not successfully used yet */
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/cpu.c linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,8 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -32,6 +34,7 @@
 
 #include <plat/cpu-freq.h>
 #include <plat/regs-serial.h>
+#include <plat/regs-power.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
@@ -45,6 +48,23 @@
 static struct map_desc s5pc100_iodesc[] __initdata = {
 };
 
+static void s5pc100_idle(void)
+{
+	unsigned long tmp;
+
+	tmp = __raw_readl(S5PC100_PWR_CFG);
+	tmp &= ~S5PC100_PWRCFG_CFG_DEEP_IDLE;
+	tmp &= ~S5PC100_PWRCFG_CFG_WFI_MASK;
+	tmp |= S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE;
+	__raw_writel(tmp, S5PC100_PWR_CFG);
+
+	tmp = __raw_readl(S5PC100_OTHERS);
+	tmp |= S5PC100_PMU_INT_DISABLE;
+	__raw_writel(tmp, S5PC100_OTHERS);
+
+	cpu_do_idle();
+}
+
 /* s5pc100_map_io
  *
  * register the standard cpu IO areas
@@ -55,6 +75,13 @@ void __init s5pc100_map_io(void)
 	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
 
 	/* initialise device information early */
+	s5pc100_default_sdhci0();
+	s5pc100_default_sdhci1();
+	s5pc100_default_sdhci2();
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
 }
 
 void __init s5pc100_init_clocks(int xtal)
@@ -93,5 +120,7 @@ int __init s5pc100_init(void)
 {
 	printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
 
+	s5pc1xx_idle = s5pc100_idle;
+
 	return sysdev_register(&s5pc100_sysdev);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,40 +18,45 @@
 #define gpio_to_irq	__gpio_to_irq
 
 /* GPIO bank sizes */
-#define S5PC1XX_GPIO_A0_NR	(8)
-#define S5PC1XX_GPIO_A1_NR	(5)
-#define S5PC1XX_GPIO_B_NR	(8)
-#define S5PC1XX_GPIO_C_NR	(5)
-#define S5PC1XX_GPIO_D_NR	(7)
-#define S5PC1XX_GPIO_E0_NR	(8)
-#define S5PC1XX_GPIO_E1_NR	(6)
-#define S5PC1XX_GPIO_F0_NR	(8)
-#define S5PC1XX_GPIO_F1_NR	(8)
-#define S5PC1XX_GPIO_F2_NR	(8)
-#define S5PC1XX_GPIO_F3_NR	(4)
-#define S5PC1XX_GPIO_G0_NR	(8)
-#define S5PC1XX_GPIO_G1_NR	(3)
-#define S5PC1XX_GPIO_G2_NR	(7)
-#define S5PC1XX_GPIO_G3_NR	(7)
-#define S5PC1XX_GPIO_H0_NR	(8)
-#define S5PC1XX_GPIO_H1_NR	(8)
-#define S5PC1XX_GPIO_H2_NR	(8)
-#define S5PC1XX_GPIO_H3_NR	(8)
-#define S5PC1XX_GPIO_I_NR	(8)
-#define S5PC1XX_GPIO_J0_NR	(8)
-#define S5PC1XX_GPIO_J1_NR	(5)
-#define S5PC1XX_GPIO_J2_NR	(8)
-#define S5PC1XX_GPIO_J3_NR	(8)
-#define S5PC1XX_GPIO_J4_NR	(4)
-#define S5PC1XX_GPIO_K0_NR	(8)
-#define S5PC1XX_GPIO_K1_NR	(6)
-#define S5PC1XX_GPIO_K2_NR	(8)
-#define S5PC1XX_GPIO_K3_NR	(8)
-#define S5PC1XX_GPIO_MP00_NR	(8)
-#define S5PC1XX_GPIO_MP01_NR	(8)
-#define S5PC1XX_GPIO_MP02_NR	(8)
-#define S5PC1XX_GPIO_MP03_NR	(8)
-#define S5PC1XX_GPIO_MP04_NR	(5)
+#define S5PC100_GPIO_A0_NR	(8)
+#define S5PC100_GPIO_A1_NR	(5)
+#define S5PC100_GPIO_B_NR	(8)
+#define S5PC100_GPIO_C_NR	(5)
+#define S5PC100_GPIO_D_NR	(7)
+#define S5PC100_GPIO_E0_NR	(8)
+#define S5PC100_GPIO_E1_NR	(6)
+#define S5PC100_GPIO_F0_NR	(8)
+#define S5PC100_GPIO_F1_NR	(8)
+#define S5PC100_GPIO_F2_NR	(8)
+#define S5PC100_GPIO_F3_NR	(4)
+#define S5PC100_GPIO_G0_NR	(8)
+#define S5PC100_GPIO_G1_NR	(3)
+#define S5PC100_GPIO_G2_NR	(7)
+#define S5PC100_GPIO_G3_NR	(7)
+#define S5PC100_GPIO_H0_NR	(8)
+#define S5PC100_GPIO_H1_NR	(8)
+#define S5PC100_GPIO_H2_NR	(8)
+#define S5PC100_GPIO_H3_NR	(8)
+#define S5PC100_GPIO_I_NR	(8)
+#define S5PC100_GPIO_J0_NR	(8)
+#define S5PC100_GPIO_J1_NR	(5)
+#define S5PC100_GPIO_J2_NR	(8)
+#define S5PC100_GPIO_J3_NR	(8)
+#define S5PC100_GPIO_J4_NR	(4)
+#define S5PC100_GPIO_K0_NR	(8)
+#define S5PC100_GPIO_K1_NR	(6)
+#define S5PC100_GPIO_K2_NR	(8)
+#define S5PC100_GPIO_K3_NR	(8)
+#define S5PC100_GPIO_L0_NR	(8)
+#define S5PC100_GPIO_L1_NR	(8)
+#define S5PC100_GPIO_L2_NR	(8)
+#define S5PC100_GPIO_L3_NR	(8)
+#define S5PC100_GPIO_L4_NR	(8)
+#define S5PC100_GPIO_MP00_NR	(8)
+#define S5PC100_GPIO_MP01_NR	(8)
+#define S5PC100_GPIO_MP02_NR	(8)
+#define S5PC100_GPIO_MP03_NR	(8)
+#define S5PC100_GPIO_MP04_NR	(5)
 
 /* GPIO bank numbes */
 
@@ -64,83 +69,94 @@
 	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
 enum s3c_gpio_number {
-	S5PC1XX_GPIO_A0_START 	= 0,
-	S5PC1XX_GPIO_A1_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
-	S5PC1XX_GPIO_B_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
-	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
-	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
-	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
-	S5PC1XX_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0),
-	S5PC1XX_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1),
-	S5PC1XX_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0),
-	S5PC1XX_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1),
-	S5PC1XX_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2),
-	S5PC1XX_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3),
-	S5PC1XX_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0),
-	S5PC1XX_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1),
-	S5PC1XX_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2),
-	S5PC1XX_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3),
-	S5PC1XX_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0),
-	S5PC1XX_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1),
-	S5PC1XX_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2),
-	S5PC1XX_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3),
-	S5PC1XX_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I),
-	S5PC1XX_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0),
-	S5PC1XX_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1),
-	S5PC1XX_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2),
-	S5PC1XX_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3),
-	S5PC1XX_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4),
-	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
-	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
-	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
-	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
-	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
-	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
-	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
-	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
+	S5PC100_GPIO_A0_START	= 0,
+	S5PC100_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A0),
+	S5PC100_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A1),
+	S5PC100_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_B),
+	S5PC100_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_C),
+	S5PC100_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_D),
+	S5PC100_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E0),
+	S5PC100_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E1),
+	S5PC100_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F0),
+	S5PC100_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F1),
+	S5PC100_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F2),
+	S5PC100_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F3),
+	S5PC100_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G0),
+	S5PC100_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G1),
+	S5PC100_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G2),
+	S5PC100_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G3),
+	S5PC100_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H0),
+	S5PC100_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H1),
+	S5PC100_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H2),
+	S5PC100_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H3),
+	S5PC100_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_I),
+	S5PC100_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J0),
+	S5PC100_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J1),
+	S5PC100_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J2),
+	S5PC100_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J3),
+	S5PC100_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J4),
+	S5PC100_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K0),
+	S5PC100_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K1),
+	S5PC100_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K2),
+	S5PC100_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K3),
+	S5PC100_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L0),
+	S5PC100_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L1),
+	S5PC100_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L2),
+	S5PC100_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L3),
+	S5PC100_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L4),
+	S5PC100_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP00),
+	S5PC100_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP01),
+	S5PC100_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP02),
+	S5PC100_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP03),
+	S5PC100_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP04),
 };
 
-/* S5PC1XX GPIO number definitions. */
-#define S5PC1XX_GPA0(_nr)	(S5PC1XX_GPIO_A0_START + (_nr))
-#define S5PC1XX_GPA1(_nr)	(S5PC1XX_GPIO_A1_START + (_nr))
-#define S5PC1XX_GPB(_nr)	(S5PC1XX_GPIO_B_START + (_nr))
-#define S5PC1XX_GPC(_nr)	(S5PC1XX_GPIO_C_START + (_nr))
-#define S5PC1XX_GPD(_nr)	(S5PC1XX_GPIO_D_START + (_nr))
-#define S5PC1XX_GPE0(_nr)	(S5PC1XX_GPIO_E0_START + (_nr))
-#define S5PC1XX_GPE1(_nr)	(S5PC1XX_GPIO_E1_START + (_nr))
-#define S5PC1XX_GPF0(_nr)	(S5PC1XX_GPIO_F0_START + (_nr))
-#define S5PC1XX_GPF1(_nr)	(S5PC1XX_GPIO_F1_START + (_nr))
-#define S5PC1XX_GPF2(_nr)	(S5PC1XX_GPIO_F2_START + (_nr))
-#define S5PC1XX_GPF3(_nr)	(S5PC1XX_GPIO_F3_START + (_nr))
-#define S5PC1XX_GPG0(_nr)	(S5PC1XX_GPIO_G0_START + (_nr))
-#define S5PC1XX_GPG1(_nr)	(S5PC1XX_GPIO_G1_START + (_nr))
-#define S5PC1XX_GPG2(_nr)	(S5PC1XX_GPIO_G2_START + (_nr))
-#define S5PC1XX_GPG3(_nr)	(S5PC1XX_GPIO_G3_START + (_nr))
-#define S5PC1XX_GPH0(_nr)	(S5PC1XX_GPIO_H0_START + (_nr))
-#define S5PC1XX_GPH1(_nr)	(S5PC1XX_GPIO_H1_START + (_nr))
-#define S5PC1XX_GPH2(_nr)	(S5PC1XX_GPIO_H2_START + (_nr))
-#define S5PC1XX_GPH3(_nr)	(S5PC1XX_GPIO_H3_START + (_nr))
-#define S5PC1XX_GPI(_nr)	(S5PC1XX_GPIO_I_START + (_nr))
-#define S5PC1XX_GPJ0(_nr)	(S5PC1XX_GPIO_J0_START + (_nr))
-#define S5PC1XX_GPJ1(_nr)	(S5PC1XX_GPIO_J1_START + (_nr))
-#define S5PC1XX_GPJ2(_nr)	(S5PC1XX_GPIO_J2_START + (_nr))
-#define S5PC1XX_GPJ3(_nr)	(S5PC1XX_GPIO_J3_START + (_nr))
-#define S5PC1XX_GPJ4(_nr)	(S5PC1XX_GPIO_J4_START + (_nr))
-#define S5PC1XX_GPK0(_nr)	(S5PC1XX_GPIO_K0_START + (_nr))
-#define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
-#define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
-#define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
-#define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
-#define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
-#define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
-#define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
-#define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
+/* S5PC100 GPIO number definitions. */
+#define S5PC100_GPA0(_nr)	(S5PC100_GPIO_A0_START + (_nr))
+#define S5PC100_GPA1(_nr)	(S5PC100_GPIO_A1_START + (_nr))
+#define S5PC100_GPB(_nr)	(S5PC100_GPIO_B_START + (_nr))
+#define S5PC100_GPC(_nr)	(S5PC100_GPIO_C_START + (_nr))
+#define S5PC100_GPD(_nr)	(S5PC100_GPIO_D_START + (_nr))
+#define S5PC100_GPE0(_nr)	(S5PC100_GPIO_E0_START + (_nr))
+#define S5PC100_GPE1(_nr)	(S5PC100_GPIO_E1_START + (_nr))
+#define S5PC100_GPF0(_nr)	(S5PC100_GPIO_F0_START + (_nr))
+#define S5PC100_GPF1(_nr)	(S5PC100_GPIO_F1_START + (_nr))
+#define S5PC100_GPF2(_nr)	(S5PC100_GPIO_F2_START + (_nr))
+#define S5PC100_GPF3(_nr)	(S5PC100_GPIO_F3_START + (_nr))
+#define S5PC100_GPG0(_nr)	(S5PC100_GPIO_G0_START + (_nr))
+#define S5PC100_GPG1(_nr)	(S5PC100_GPIO_G1_START + (_nr))
+#define S5PC100_GPG2(_nr)	(S5PC100_GPIO_G2_START + (_nr))
+#define S5PC100_GPG3(_nr)	(S5PC100_GPIO_G3_START + (_nr))
+#define S5PC100_GPH0(_nr)	(S5PC100_GPIO_H0_START + (_nr))
+#define S5PC100_GPH1(_nr)	(S5PC100_GPIO_H1_START + (_nr))
+#define S5PC100_GPH2(_nr)	(S5PC100_GPIO_H2_START + (_nr))
+#define S5PC100_GPH3(_nr)	(S5PC100_GPIO_H3_START + (_nr))
+#define S5PC100_GPI(_nr)	(S5PC100_GPIO_I_START + (_nr))
+#define S5PC100_GPJ0(_nr)	(S5PC100_GPIO_J0_START + (_nr))
+#define S5PC100_GPJ1(_nr)	(S5PC100_GPIO_J1_START + (_nr))
+#define S5PC100_GPJ2(_nr)	(S5PC100_GPIO_J2_START + (_nr))
+#define S5PC100_GPJ3(_nr)	(S5PC100_GPIO_J3_START + (_nr))
+#define S5PC100_GPJ4(_nr)	(S5PC100_GPIO_J4_START + (_nr))
+#define S5PC100_GPK0(_nr)	(S5PC100_GPIO_K0_START + (_nr))
+#define S5PC100_GPK1(_nr)	(S5PC100_GPIO_K1_START + (_nr))
+#define S5PC100_GPK2(_nr)	(S5PC100_GPIO_K2_START + (_nr))
+#define S5PC100_GPK3(_nr)	(S5PC100_GPIO_K3_START + (_nr))
+#define S5PC100_GPL0(_nr)	(S5PC100_GPIO_L0_START + (_nr))
+#define S5PC100_GPL1(_nr)	(S5PC100_GPIO_L1_START + (_nr))
+#define S5PC100_GPL2(_nr)	(S5PC100_GPIO_L2_START + (_nr))
+#define S5PC100_GPL3(_nr)	(S5PC100_GPIO_L3_START + (_nr))
+#define S5PC100_GPL4(_nr)	(S5PC100_GPIO_L4_START + (_nr))
+#define S5PC100_MP00(_nr)	(S5PC100_GPIO_MP00_START + (_nr))
+#define S5PC100_MP01(_nr)	(S5PC100_GPIO_MP01_START + (_nr))
+#define S5PC100_MP02(_nr)	(S5PC100_GPIO_MP02_START + (_nr))
+#define S5PC100_MP03(_nr)	(S5PC100_GPIO_MP03_START + (_nr))
+#define S5PC100_MP04(_nr)	(S5PC100_GPIO_MP04_START + (_nr))
+#define S5PC100_MP05(_nr)	(S5PC100_GPIO_MP05_START + (_nr))
 
-/* the end of the S5PC1XX specific gpios */
-#define S5PC1XX_GPIO_END	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
-#define S3C_GPIO_END		S5PC1XX_GPIO_END
+/* It used the end of the S5PC1XX gpios */
+#define S3C_GPIO_END		S5PC100_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
-#define ARCH_NR_GPIOS	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+#define ARCH_NR_GPIOS		(S5PC100_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,4 +11,9 @@
 
 #include <plat/irqs.h>
 
+/* LCD */
+#define IRQ_LCD_FIFO		IRQ_LCD0
+#define IRQ_LCD_VSYNC		IRQ_LCD1
+#define IRQ_LCD_SYSTEM		IRQ_LCD2
+
 #endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/map.h linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/map.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/map.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,19 @@
 
 #include <plat/map-base.h>
 
+/*
+ * map-base.h has already defined virtual memory address
+ * S3C_VA_IRQ		S3C_ADDR(0x00000000)	irq controller(s)
+ * S3C_VA_SYS		S3C_ADDR(0x00100000)	system control
+ * S3C_VA_MEM		S3C_ADDR(0x00200000)	system control (not used)
+ * S3C_VA_TIMER		S3C_ADDR(0x00300000)	timer block
+ * S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	watchdog
+ * S3C_VA_UART		S3C_ADDR(0x01000000)	UART
+ *
+ * S5PC100 specific virtual memory address can be defined here
+ * S5PC1XX_VA_GPIO	S3C_ADDR(0x00500000)	GPIO
+ *
+ */
 
 /* Chip ID */
 #define S5PC100_PA_CHIPID	(0xE0000000)
@@ -24,13 +37,20 @@
 #define S5PC1XX_VA_CHIPID	S3C_VA_SYS
 
 /* System */
-#define S5PC100_PA_SYS		(0xE0100000)
-#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
-#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
+#define S5PC100_PA_CLK		(0xE0100000)
+#define S5PC100_PA_CLK_OTHER	(0xE0200000)
+#define S5PC100_PA_PWR		(0xE0108000)
 #define S5PC1XX_PA_CLK		S5PC100_PA_CLK
 #define S5PC1XX_PA_PWR		S5PC100_PA_PWR
+#define S5PC1XX_PA_CLK_OTHER	S5PC100_PA_CLK_OTHER
 #define S5PC1XX_VA_CLK		(S3C_VA_SYS + 0x10000)
 #define S5PC1XX_VA_PWR		(S3C_VA_SYS + 0x20000)
+#define S5PC1XX_VA_CLK_OTHER	(S3C_VA_SYS + 0x30000)
+
+/* GPIO */
+#define S5PC100_PA_GPIO		(0xE0300000)
+#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
+#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
 
 /* Interrupt */
 #define S5PC100_PA_VIC		(0xE4000000)
@@ -40,23 +60,64 @@
 #define S5PC1XX_PA_VIC(x)	(S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
 #define S5PC1XX_VA_VIC(x)	(S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
 
+/* DMA */
+#define S5PC100_PA_MDMA		(0xE8100000)
+#define S5PC100_PA_PDMA0	(0xE9000000)
+#define S5PC100_PA_PDMA1	(0xE9200000)
+
 /* Timer */
 #define S5PC100_PA_TIMER	(0xEA000000)
 #define S5PC1XX_PA_TIMER	S5PC100_PA_TIMER
 #define S5PC1XX_VA_TIMER	S3C_VA_TIMER
 
+/* RTC */
+#define S5PC100_PA_RTC		(0xEA300000)
+
 /* UART */
 #define S5PC100_PA_UART		(0xEC000000)
 #define S5PC1XX_PA_UART		S5PC100_PA_UART
 #define S5PC1XX_VA_UART		S3C_VA_UART
 
-/* IIC */
-#define S5PC100_PA_IIC		(0xEC100000)
+/* I2C */
+#define S5PC100_PA_I2C		(0xEC100000)
+#define S5PC100_PA_I2C1		(0xEC200000)
+
+/* USB HS OTG */
+#define S5PC100_PA_USB_HSOTG	(0xED200000)
+#define S5PC100_PA_USB_HSPHY	(0xED300000)
+
+/* SD/MMC */
+#define S5PC100_PA_HSMMC(x)	(0xED800000 + ((x) * 0x100000))
+#define S5PC100_PA_HSMMC0	S5PC100_PA_HSMMC(0)
+#define S5PC100_PA_HSMMC1	S5PC100_PA_HSMMC(1)
+#define S5PC100_PA_HSMMC2	S5PC100_PA_HSMMC(2)
+
+/* LCD */
+#define S5PC100_PA_FB		(0xEE000000)
+
+/* Multimedia */
+#define S5PC100_PA_G2D		(0xEE800000)
+#define S5PC100_PA_JPEG		(0xEE500000)
+#define S5PC100_PA_ROTATOR	(0xEE100000)
+#define S5PC100_PA_G3D		(0xEF000000)
+
+/* I2S */
+#define S5PC100_PA_I2S0		(0xF2000000)
+#define S5PC100_PA_I2S1		(0xF2100000)
+#define S5PC100_PA_I2S2		(0xF2200000)
+
+/* KEYPAD */
+#define S5PC100_PA_KEYPAD	(0xF3100000)
+
+/* ADC & TouchScreen */
+#define S5PC100_PA_TSADC	(0xF3000000)
 
 /* ETC */
 #define S5PC100_PA_SDRAM	(0x20000000)
+#define S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM
 
 /* compatibility defines. */
+#define S3C_PA_RTC		S5PC100_PA_RTC
 #define S3C_PA_UART		S5PC100_PA_UART
 #define S3C_PA_UART0		(S5PC100_PA_UART + 0x0)
 #define S3C_PA_UART1		(S5PC100_PA_UART + 0x400)
@@ -67,9 +128,23 @@
 #define S3C_VA_UART2		(S3C_VA_UART + 0x800)
 #define S3C_VA_UART3		(S3C_VA_UART + 0xC00)
 #define S3C_UART_OFFSET		0x400
+#define S3C_VA_UARTx(x)		(S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define S3C_PA_FB		S5PC100_PA_FB
+#define S3C_PA_G2D		S5PC100_PA_G2D
+#define S3C_PA_G3D		S5PC100_PA_G3D
+#define S3C_PA_JPEG		S5PC100_PA_JPEG
+#define S3C_PA_ROTATOR		S5PC100_PA_ROTATOR
 #define S3C_VA_VIC0		(S3C_VA_IRQ + 0x0)
 #define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
 #define S3C_VA_VIC2		(S3C_VA_IRQ + 0x20000)
-#define S3C_PA_IIC		S5PC100_PA_IIC
+#define S3C_PA_IIC		S5PC100_PA_I2C
+#define S3C_PA_IIC1		S5PC100_PA_I2C1
+#define S3C_PA_USB_HSOTG	S5PC100_PA_USB_HSOTG
+#define S3C_PA_USB_HSPHY	S5PC100_PA_USB_HSPHY
+#define S3C_PA_HSMMC0		S5PC100_PA_HSMMC0
+#define S3C_PA_HSMMC1		S5PC100_PA_HSMMC1
+#define S3C_PA_HSMMC2		S5PC100_PA_HSMMC2
+#define S3C_PA_KEYPAD		S5PC100_PA_KEYPAD
+#define S3C_PA_TSADC		S5PC100_PA_TSADC
 
 #endif /* __ASM_ARCH_C100_MAP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/regs-fb.h linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/regs-fb.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/regs-fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/regs-fb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,139 @@
+/* arch/arm/mach-s5pc100/include/mach/regs-fb.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *   Pawel Osciak <p.osciak@samsung.com>
+ *
+ * Framebuffer register definitions for Samsung S5PC100.
+ *
+ * This 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_FB_H
+#define __ASM_ARCH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+/* VP1 interface timing control */
+#define VP1CON0						(0x118)
+#define VP1_RATECON_EN					(1 << 31)
+#define VP1_CLKRATE_MASK				(0xff)
+
+#define VP1CON1						(0x11c)
+#define VP1_VTREGCON_EN					(1 << 31)
+#define VP1_VBPD_MASK					(0xfff)
+#define VP1_VBPD_SHIFT					(16)
+
+
+#define WPALCON_H					(0x19c)
+#define WPALCON_L					(0x1a0)
+
+/* Pallete contro for WPAL0 and WPAL1 is the same as in S3C64xx, but
+ * different for WPAL2-4
+ */
+/* In WPALCON_L (aka WPALCON) */
+#define WPALCON_W1PAL_32BPP_A888			(0x7 << 3)
+#define WPALCON_W0PAL_32BPP_A888			(0x7 << 0)
+
+/* To set W2PAL-W4PAL consist of one bit from WPALCON_L and two from WPALCON_H,
+ * e.g. W2PAL[2..0] is made of (WPALCON_H[10..9], WPALCON_L[6]).
+ */
+#define WPALCON_L_WxPAL_L_MASK				(0x1)
+#define WPALCON_L_W2PAL_L_SHIFT				(6)
+#define WPALCON_L_W3PAL_L_SHIFT				(7)
+#define WPALCON_L_W4PAL_L_SHIFT				(8)
+
+#define WPALCON_L_WxPAL_H_MASK				(0x3)
+#define WPALCON_H_W2PAL_H_SHIFT				(9)
+#define WPALCON_H_W3PAL_H_SHIFT				(13)
+#define WPALCON_H_W4PAL_H_SHIFT				(17)
+
+/* Per-window alpha value registers */
+/* For window 0 8-bit alpha values are in VIDW0ALPHAx,
+ * for windows 1-4 alpha values consist of two parts, the 4 low bits are
+ * taken from VIDWxALPHAx and 4 high bits are from VIDOSDxC,
+ * e.g. WIN1_ALPHA0_B[7..0] = (VIDOSD1C[3..0], VIDW1ALPHA0[3..0])
+ */
+#define VIDWxALPHA0(_win)				(0x200 + (_win * 8))
+#define VIDWxALPHA1(_win)				(0x204 + (_win * 8))
+
+/* Only for window 0 in VIDW0ALPHAx. */
+#define VIDW0ALPHAx_R(_x)				((_x) << 16)
+#define VIDW0ALPHAx_R_MASK				(0xff << 16)
+#define VIDW0ALPHAx_R_SHIFT				(16)
+#define VIDW0ALPHAx_G(_x)				((_x) << 8)
+#define VIDW0ALPHAx_G_MASK				(0xff << 8)
+#define VIDW0ALPHAx_G_SHIFT				(8)
+#define VIDW0ALPHAx_B(_x)				((_x) << 0)
+#define VIDW0ALPHAx_B_MASK				(0xff << 0)
+#define VIDW0ALPHAx_B_SHIFT				(0)
+
+/* Low 4 bits of alpha0-1 for windows 1-4 */
+#define VIDW14ALPHAx_R_L(_x)				((_x) << 16)
+#define VIDW14ALPHAx_R_L_MASK				(0xf << 16)
+#define VIDW14ALPHAx_R_L_SHIFT				(16)
+#define VIDW14ALPHAx_G_L(_x)				((_x) << 8)
+#define VIDW14ALPHAx_G_L_MASK				(0xf << 8)
+#define VIDW14ALPHAx_G_L_SHIFT				(8)
+#define VIDW14ALPHAx_B_L(_x)				((_x) << 0)
+#define VIDW14ALPHAx_B_L_MASK				(0xf << 0)
+#define VIDW14ALPHAx_B_L_SHIFT				(0)
+
+
+/* Per-window blending equation control registers */
+#define BLENDEQx(_win)					(0x244 + ((_win) * 4))
+#define BLENDEQ1					(0x244)
+#define BLENDEQ2					(0x248)
+#define BLENDEQ3					(0x24c)
+#define BLENDEQ4					(0x250)
+
+#define BLENDEQx_Q_FUNC(_x)				((_x) << 18)
+#define BLENDEQx_Q_FUNC_MASK				(0xf << 18)
+#define BLENDEQx_P_FUNC(_x)				((_x) << 12)
+#define BLENDEQx_P_FUNC_MASK				(0xf << 12)
+#define BLENDEQx_B_FUNC(_x)				((_x) << 6)
+#define BLENDEQx_B_FUNC_MASK				(0xf << 6)
+#define BLENDEQx_A_FUNC(_x)				((_x) << 0)
+#define BLENDEQx_A_FUNC_MASK				(0xf << 0)
+
+#define BLENDCON					(0x260)
+#define BLENDCON_8BIT_ALPHA				(1 << 0)
+
+/* Per-window palette base addresses (start of palette memory).
+ * Each window palette area consists of 256 32-bit entries.
+ * START is the first address (entry 0th), END is the address of 255th entry.
+ */
+#define WIN0_PAL_BASE					(0x2400)
+#define WIN0_PAL_END					(0x27fc)
+#define WIN1_PAL_BASE					(0x2800)
+#define WIN1_PAL_END					(0x2bfc)
+#define WIN2_PAL_BASE					(0x2c00)
+#define WIN2_PAL_END					(0x2ffc)
+#define WIN3_PAL_BASE					(0x3000)
+#define WIN3_PAL_END					(0x33fc)
+#define WIN4_PAL_BASE					(0x3400)
+#define WIN4_PAL_END					(0x37fc)
+
+#define WIN0_PAL(_entry)			(WIN0_PAL_BASE + ((_entry) * 4))
+#define WIN1_PAL(_entry)			(WIN1_PAL_BASE + ((_entry) * 4))
+#define WIN2_PAL(_entry)			(WIN2_PAL_BASE + ((_entry) * 4))
+#define WIN3_PAL(_entry)			(WIN3_PAL_BASE + ((_entry) * 4))
+#define WIN4_PAL(_entry)			(WIN4_PAL_BASE + ((_entry) * 4))
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	switch (window) {
+	case 0: return WIN0_PAL(reg);
+	case 1: return WIN1_PAL(reg);
+	case 2: return WIN2_PAL(reg);
+	case 3: return WIN3_PAL(reg);
+	case 4: return WIN4_PAL(reg);
+	}
+
+	BUG();
+}
+
+
+#endif /* __ASM_ARCH_REGS_FB_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/include/mach/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,14 +11,21 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H __FILE__
 
+#include <linux/io.h>
+#include <mach/map.h>
+#include <plat/regs-clock.h>
+
+void (*s5pc1xx_idle)(void);
+
 static void arch_idle(void)
 {
-	/* nothing here yet */
+	if (s5pc1xx_idle)
+		s5pc1xx_idle();
 }
 
 static void arch_reset(char mode, const char *cmd)
 {
-	/* nothing here yet */
+	__raw_writel(S5PC100_SWRESET_RESETVAL, S5PC100_SWRESET);
+	return;
 }
-
 #endif /* __ASM_ARCH_IRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/mach-s5pc100/Kconfig
-#
 # Copyright 2009 Samsung Electronics Co.
 #	Byungho Min <bhmin@samsung.com>
 #
@@ -14,9 +12,23 @@ config CPU_S5PC100
 	help
 	  Enable S5PC100 CPU support
 
+config S5PC100_SETUP_SDHCI
+        bool
+        select S5PC1XX_SETUP_SDHCI_GPIO
+        help
+          Internal helper functions for S5PC100 based SDHCI systems
+
 config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
+	select S3C_DEV_FB
+	select S3C_DEV_I2C1
+	select S3C_DEV_HSMMC
+	select S3C_DEV_HSMMC1
+	select S3C_DEV_HSMMC2
+	select S5PC1XX_SETUP_I2C0
 	select S5PC1XX_SETUP_I2C1
+	select S5PC1XX_SETUP_FB_24BPP
+	select S5PC100_SETUP_SDHCI
 	help
 	  Machine support for the Samsung SMDKC100
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/mach-smdkc100.c linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/mach-smdkc100.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/mach-smdkc100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/mach-smdkc100.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,16 +27,22 @@
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <video/platform_lcd.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
 #include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-gpio.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/s5pc100.h>
+#include <plat/fb.h>
+#include <plat/iic.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -73,9 +79,78 @@ static struct s3c2410_uartcfg smdkc100_u
 	},
 };
 
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
+/* LCD power controller */
+static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	/* backlight */
+	gpio_direction_output(S5PC100_GPD(0), power);
+
+	if (power) {
+		/* module reset */
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(100);
+		gpio_direction_output(S5PC100_GPH0(6), 0);
+		mdelay(10);
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(10);
+	}
+}
+
+static struct plat_lcd_data smdkc100_lcd_power_data = {
+	.set_power	= smdkc100_lcd_power_set,
+};
+
+static struct platform_device smdkc100_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.parent		= &s3c_device_fb.dev,
+	.dev.platform_data	= &smdkc100_lcd_power_data,
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdkc100_fb_win0 = {
+	/* this is to ensure we use win0 */
+	.win_mode	= {
+		.refresh	= 70,
+		.pixclock	= (8+13+3+800)*(7+5+1+480),
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
+	.win[0]		= &smdkc100_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= s5pc100_fb_gpio_setup_24bpp,
+};
+
 static struct map_desc smdkc100_iodesc[] = {};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
+	&s3c_device_i2c0,
+	&s3c_device_i2c1,
+	&s3c_device_fb,
+	&s3c_device_hsmmc0,
+	&s3c_device_hsmmc1,
+	&s3c_device_hsmmc2,
+	&smdkc100_lcd_powerdev,
 };
 
 static void __init smdkc100_map_io(void)
@@ -87,12 +162,24 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
+	/* I2C */
+	s3c_i2c0_set_platdata(NULL);
+	s3c_i2c1_set_platdata(NULL);
+	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+	s3c_fb_set_platdata(&smdkc100_lcd_pdata);
+
+	/* LCD init */
+	gpio_request(S5PC100_GPD(0), "GPD");
+	gpio_request(S5PC100_GPH0(6), "GPH0");
+	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
 }
 
 MACHINE_START(SMDKC100, "SMDKC100")
 	/* Maintainer: Byungho Min <bhmin@samsung.com> */
-	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
+	.phys_io	= S5PC100_PA_UART & 0xfff00000,
 	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S5PC100_PA_SDRAM + 0x100,
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -13,5 +13,9 @@ obj-				:=
 
 obj-$(CONFIG_CPU_S5PC100)	+= cpu.o
 
+# Helper and device support
+
+obj-$(CONFIG_S5PC100_SETUP_SDHCI)       += setup-sdhci.o
+
 # machine support
 obj-$(CONFIG_MACH_SMDKC100)	+= mach-smdkc100.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-s5pc100/setup-sdhci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
+ *
+ * Copyright 2008 Samsung Electronics
+ *
+ * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * Based on mach-s3c6410/setup-sdhci.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/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pc100_hsmmc_clksrcs[4] = {
+	[0] = "hsmmc",
+	[1] = "hsmmc",
+	/* [2] = "mmc_bus", not yet succesfuuly used yet */
+	/* [3] = "48m", - note not succesfully used yet */
+};
+
+
+void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+				    void __iomem *r,
+				    struct mmc_ios *ios,
+				    struct mmc_card *card)
+{
+	u32 ctrl2, ctrl3;
+
+	/* don't need to alter anything acording to card-type */
+
+	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+		  S3C_SDHCI_CTRL2_ENFBCLKRX |
+		  S3C_SDHCI_CTRL2_DFCNT_NONE |
+		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+	if (ios->clock < 25 * 1000000)
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+			 S3C_SDHCI_CTRL3_FCSEL2 |
+			 S3C_SDHCI_CTRL3_FCSEL1 |
+			 S3C_SDHCI_CTRL3_FCSEL0);
+	else
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/assabet.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/assabet.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/assabet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/assabet.c	2010-02-24 13:52:17.000000000 -0500
@@ -249,10 +249,10 @@ static void __init assabet_init(void)
 #endif
 	}
 
-	sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources,
-			      ARRAY_SIZE(assabet_flash_resources));
-	sa11x0_set_irda_data(&assabet_irda_data);
-	sa11x0_set_mcp_data(&assabet_mcp_data);
+	sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
+			    ARRAY_SIZE(assabet_flash_resources));
+	sa11x0_register_irda(&assabet_irda_data);
+	sa11x0_register_mcp(&assabet_mcp_data);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/badge4.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/badge4.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/badge4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/badge4.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,7 @@ static int __init badge4_init(void)
 	/* maybe turn on 5v0 from the start */
 	badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on);
 
-	sa11x0_set_flash_data(&badge4_flash_data, &badge4_flash_resource, 1);
+	sa11x0_register_mtd(&badge4_flash_data, &badge4_flash_resource, 1);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/cerf.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/cerf.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/cerf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/cerf.c	2010-02-24 13:52:17.000000000 -0500
@@ -129,8 +129,8 @@ static struct mcp_plat_data cerf_mcp_dat
 static void __init cerf_init(void)
 {
 	platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
-	sa11x0_set_flash_data(&cerf_flash_data, &cerf_flash_resource, 1);
-	sa11x0_set_mcp_data(&cerf_mcp_data);
+	sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
+	sa11x0_register_mcp(&cerf_mcp_data);
 }
 
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/collie.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/collie.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/collie.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/collie.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio.h>
+#include <linux/pda_power.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -56,6 +57,7 @@ static struct resource collie_scoop_reso
 static struct scoop_config collie_scoop_setup = {
 	.io_dir 	= COLLIE_SCOOP_IO_DIR,
 	.io_out		= COLLIE_SCOOP_IO_OUT,
+	.gpio_base	= COLLIE_SCOOP_GPIO_BASE,
 };
 
 struct platform_device colliescoop_device = {
@@ -85,6 +87,70 @@ static struct scoop_pcmcia_config collie
 static struct mcp_plat_data collie_mcp_data = {
 	.mccr0		= MCCR0_ADM | MCCR0_ExtClk,
 	.sclk_rate	= 9216000,
+	.gpio_base	= COLLIE_TC35143_GPIO_BASE,
+};
+
+/*
+ * Collie AC IN
+ */
+static int collie_power_init(struct device *dev)
+{
+	int ret = gpio_request(COLLIE_GPIO_AC_IN, "ac in");
+	if (ret)
+		goto err_gpio_req;
+
+	ret = gpio_direction_input(COLLIE_GPIO_AC_IN);
+	if (ret)
+		goto err_gpio_in;
+
+	return 0;
+
+err_gpio_in:
+	gpio_free(COLLIE_GPIO_AC_IN);
+err_gpio_req:
+	return ret;
+}
+
+static void collie_power_exit(struct device *dev)
+{
+	gpio_free(COLLIE_GPIO_AC_IN);
+}
+
+static int collie_power_ac_online(void)
+{
+	return gpio_get_value(COLLIE_GPIO_AC_IN) == 2;
+}
+
+static char *collie_ac_supplied_to[] = {
+	"main-battery",
+	"backup-battery",
+};
+
+static struct pda_power_pdata collie_power_data = {
+	.init			= collie_power_init,
+	.is_ac_online		= collie_power_ac_online,
+	.exit			= collie_power_exit,
+	.supplied_to		= collie_ac_supplied_to,
+	.num_supplicants	= ARRAY_SIZE(collie_ac_supplied_to),
+};
+
+static struct resource collie_power_resource[] = {
+	{
+		.name		= "ac",
+		.start		= gpio_to_irq(COLLIE_GPIO_AC_IN),
+		.end		= gpio_to_irq(COLLIE_GPIO_AC_IN),
+		.flags		= IORESOURCE_IRQ |
+				  IORESOURCE_IRQ_HIGHEDGE |
+				  IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+static struct platform_device collie_power_device = {
+	.name			= "pda-power",
+	.id			= -1,
+	.dev.platform_data	= &collie_power_data,
+	.resource		= collie_power_resource,
+	.num_resources		= ARRAY_SIZE(collie_power_resource),
 };
 
 #ifdef CONFIG_SHARP_LOCOMO
@@ -178,6 +244,7 @@ struct platform_device collie_locomo_dev
 static struct platform_device *devices[] __initdata = {
 	&collie_locomo_device,
 	&colliescoop_device,
+	&collie_power_device,
 };
 
 static struct mtd_partition collie_partitions[] = {
@@ -248,22 +315,24 @@ static void __init collie_init(void)
 	GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
 		GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
 		GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
-		COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON |
-		COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
+		_COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
+		_COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
 
 	PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
 		PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
 		PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
 
-	PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY |
-		COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
+	PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY |
+		_COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
 
-	PGSR = COLLIE_GPIO_nREMOCON_ON;
+	PGSR = _COLLIE_GPIO_nREMOCON_ON;
 
 	PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
 
 	PCFR = PCFR_OPDE;
 
+	GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
+
 
 	platform_scoop_config = &collie_pcmcia_config;
 
@@ -272,9 +341,9 @@ static void __init collie_init(void)
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
 	}
 
-	sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources,
-			      ARRAY_SIZE(collie_flash_resources));
-	sa11x0_set_mcp_data(&collie_mcp_data);
+	sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
+			    ARRAY_SIZE(collie_flash_resources));
+	sa11x0_register_mcp(&collie_mcp_data);
 
 	sharpsl_save_param();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/dma.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,7 @@ static irqreturn_t dma_irq_handler(int i
 
 
 /**
- *	sa1100_request_dma - allocate one of the SA11x0's DMA chanels
+ *	sa1100_request_dma - allocate one of the SA11x0's DMA channels
  *	@device: The SA11x0 peripheral targeted by this request
  *	@device_id: An ascii name for the claiming device
  *	@callback: Function to be called when the DMA completes
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/generic.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/generic.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,6 @@ static const unsigned short cclk_frequen
 	2802	/* 280.2 MHz */
 };
 
-#if defined(CONFIG_CPU_FREQ_SA1100) || defined(CONFIG_CPU_FREQ_SA1110)
 /* rounds up(!)  */
 unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
 {
@@ -110,17 +109,6 @@ unsigned int sa11x0_getspeed(unsigned in
 	return cclk_frequency_100khz[PPCR & 0xf] * 100;
 }
 
-#else
-/*
- * We still need to provide this so building without cpufreq works.
- */
-unsigned int cpufreq_get(unsigned int cpu)
-{
-	return cclk_frequency_100khz[PPCR & 0xf] * 100;
-}
-EXPORT_SYMBOL(cpufreq_get);
-#endif
-
 /*
  * This is the SA11x0 sched_clock implementation.  This has
  * a resolution of 271ns, and a maximum value of 32025597s (370 days).
@@ -162,6 +150,17 @@ static void sa1100_power_off(void)
 	PMCR = PMCR_SF;
 }
 
+static void sa11x0_register_device(struct platform_device *dev, void *data)
+{
+	int err;
+	dev->dev.platform_data = data;
+	err = platform_device_register(dev);
+	if (err)
+		printk(KERN_ERR "Unable to register device %s: %d\n",
+			dev->name, err);
+}
+
+
 static struct resource sa11x0udc_resources[] = {
 	[0] = {
 		.start	= 0x80000000,
@@ -234,9 +233,9 @@ static struct platform_device sa11x0mcp_
 	.resource	= sa11x0mcp_resources,
 };
 
-void sa11x0_set_mcp_data(struct mcp_plat_data *data)
+void sa11x0_register_mcp(struct mcp_plat_data *data)
 {
-	sa11x0mcp_device.dev.platform_data = data;
+	sa11x0_register_device(&sa11x0mcp_device, data);
 }
 
 static struct resource sa11x0ssp_resources[] = {
@@ -293,13 +292,13 @@ static struct platform_device sa11x0mtd_
 	.id		= -1,
 };
 
-void sa11x0_set_flash_data(struct flash_platform_data *flash,
-			   struct resource *res, int nr)
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+			 struct resource *res, int nr)
 {
 	flash->name = "sa1100";
-	sa11x0mtd_device.dev.platform_data = flash;
 	sa11x0mtd_device.resource = res;
 	sa11x0mtd_device.num_resources = nr;
+	sa11x0_register_device(&sa11x0mtd_device, flash);
 }
 
 static struct resource sa11x0ir_resources[] = {
@@ -329,9 +328,9 @@ static struct platform_device sa11x0ir_d
 	.resource	= sa11x0ir_resources,
 };
 
-void sa11x0_set_irda_data(struct irda_platform_data *irda)
+void sa11x0_register_irda(struct irda_platform_data *irda)
 {
-	sa11x0ir_device.dev.platform_data = irda;
+	sa11x0_register_device(&sa11x0ir_device, irda);
 }
 
 static struct platform_device sa11x0rtc_device = {
@@ -343,21 +342,15 @@ static struct platform_device *sa11x0_de
 	&sa11x0udc_device,
 	&sa11x0uart1_device,
 	&sa11x0uart3_device,
-	&sa11x0mcp_device,
 	&sa11x0ssp_device,
 	&sa11x0pcmcia_device,
 	&sa11x0fb_device,
-	&sa11x0mtd_device,
 	&sa11x0rtc_device,
 };
 
 static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
-
-	if (sa11x0ir_device.dev.platform_data)
-		platform_device_register(&sa11x0ir_device);
-
 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/generic.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/generic.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/generic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/generic.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,14 +32,11 @@ extern unsigned int sa11x0_ppcr_to_freq(
 struct flash_platform_data;
 struct resource;
 
-extern void sa11x0_set_flash_data(struct flash_platform_data *flash,
-				  struct resource *res, int nr);
-
-struct sa11x0_ssp_plat_ops;
-extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+			 struct resource *res, int nr);
 
 struct irda_platform_data;
-void sa11x0_set_irda_data(struct irda_platform_data *irda);
+void sa11x0_register_irda(struct irda_platform_data *irda);
 
 struct mcp_plat_data;
-void sa11x0_set_mcp_data(struct mcp_plat_data *data);
+void sa11x0_register_mcp(struct mcp_plat_data *data);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3100.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3100.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3100.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3100.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,95 @@
+/*
+ * Support for Compaq iPAQ H3100 handheld computer
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This 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/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irda.h>
+
+#include <mach/h3xxx.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static void h3100_lcd_power(int enable)
+{
+	if (!gpio_request(H3XXX_EGPIO_LCD_ON, "LCD ON")) {
+		gpio_set_value(H3100_GPIO_LCD_3V_ON, enable);
+		gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
+		gpio_free(H3XXX_EGPIO_LCD_ON);
+	} else {
+		pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
+	}
+}
+
+
+static void __init h3100_map_io(void)
+{
+	h3xxx_map_io();
+
+	sa1100fb_lcd_power = h3100_lcd_power;
+
+	/* Older bootldrs put GPIO2-9 in alternate mode on the
+	   assumption that they are used for video */
+	GAFR &= ~0x000001fb;
+}
+
+/*
+ * This turns the IRDA power on or off on the Compaq H3100
+ */
+static int h3100_irda_set_power(struct device *dev, unsigned int state)
+{
+	gpio_set_value(H3100_GPIO_IR_ON, state);
+	return 0;
+}
+
+static void h3100_irda_set_speed(struct device *dev, unsigned int speed)
+{
+	gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000));
+}
+
+static struct irda_platform_data h3100_irda_data = {
+	.set_power	= h3100_irda_set_power,
+	.set_speed	= h3100_irda_set_speed,
+};
+
+static struct gpio_default_state h3100_default_gpio[] = {
+	{ H3100_GPIO_IR_ON,	GPIO_MODE_OUT0, "IrDA power" },
+	{ H3100_GPIO_IR_FSEL,	GPIO_MODE_OUT0, "IrDA fsel" },
+	{ H3XXX_GPIO_COM_DCD,	GPIO_MODE_IN,	"COM DCD" },
+	{ H3XXX_GPIO_COM_CTS,	GPIO_MODE_IN,	"COM CTS" },
+	{ H3XXX_GPIO_COM_RTS,	GPIO_MODE_OUT0,	"COM RTS" },
+	{ H3100_GPIO_LCD_3V_ON,	GPIO_MODE_OUT0,	"LCD 3v" },
+};
+
+static void __init h3100_mach_init(void)
+{
+	h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
+	h3xxx_mach_init();
+	sa11x0_register_irda(&h3100_irda_data);
+}
+
+MACHINE_START(H3100, "Compaq iPAQ H3100")
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3100_map_io,
+	.init_irq	= sa1100_init_irq,
+	.timer		= &sa1100_timer,
+	.init_machine	= h3100_mach_init,
+MACHINE_END
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3600.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3600.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3600.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3600.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,421 +1,127 @@
 /*
- * Hardware definitions for Compaq iPAQ H3xxx Handheld Computers
- *
- * Copyright 2000,1 Compaq Computer Corporation.
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Author: Jamey Hicks.
+ * Support for Compaq iPAQ H3600 handheld computer
  *
- * History:
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
  *
- * 2001-10-??	Andrew Christian   Added support for iPAQ H3800
- *				   and abstracted EGPIO interface.
+ * This 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/kernel.h>
-#include <linux/tty.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/serial_core.h>
+#include <linux/gpio.h>
 
-#include <asm/irq.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/setup.h>
-
-#include <asm/mach/irq.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/irda.h>
-#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
 
-#include <mach/h3600.h>
-#include <mach/h3600_gpio.h>
+#include <mach/h3xxx.h>
 
 #include "generic.h"
 
-void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
-EXPORT_SYMBOL(assign_h3600_egpio);
-
-static struct mtd_partition h3xxx_partitions[] = {
-	{
-		.name		= "H3XXX boot firmware",
-		.size		= 0x00040000,
-		.offset		= 0,
-		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
-	}, {
-		.name		= "H3XXX rootfs",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= 0x00040000,
-	}
-};
-
-static void h3xxx_set_vpp(int vpp)
-{
-	assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
-}
-
-static struct flash_platform_data h3xxx_flash_data = {
-	.map_name	= "cfi_probe",
-	.set_vpp	= h3xxx_set_vpp,
-	.parts		= h3xxx_partitions,
-	.nr_parts	= ARRAY_SIZE(h3xxx_partitions),
-};
-
-static struct resource h3xxx_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
 /*
- * This turns the IRDA power on or off on the Compaq H3600
- */
-static int h3600_irda_set_power(struct device *dev, unsigned int state)
-{
-	assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state );
-
-	return 0;
-}
-
-static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL, !(speed < 4000000));
-}
-
-static struct irda_platform_data h3600_irda_data = {
-	.set_power	= h3600_irda_set_power,
-	.set_speed	= h3600_irda_set_speed,
-};
-
-static void h3xxx_mach_init(void)
-{
-	sa11x0_set_flash_data(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
-	sa11x0_set_irda_data(&h3600_irda_data);
-}
-
-/*
- * low-level UART features
+ * helper for sa1100fb
  */
-
-static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+static void h3600_lcd_power(int enable)
 {
-	if (port->mapbase == _Ser3UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_H3600_COM_RTS;
-		else
-			GPSR = GPIO_H3600_COM_RTS;
+	if (gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power")) {
+		pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
+		goto err1;
 	}
-}
-
-static u_int h3600_uart_get_mctrl(struct uart_port *port)
-{
-	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	if (port->mapbase == _Ser3UTCR0) {
-		int gplr = GPLR;
-		/* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
-		if (gplr & GPIO_H3600_COM_DCD)
-			ret &= ~TIOCM_CD;
-		if (gplr & GPIO_H3600_COM_CTS)
-			ret &= ~TIOCM_CTS;
+	if (gpio_request(H3600_EGPIO_LCD_PCI, "LCD control")) {
+		pr_err("%s: can't request H3XXX_EGPIO_LCD_PCI\n", __func__);
+		goto err2;
+	}
+	if (gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v")) {
+		pr_err("%s: can't request H3XXX_EGPIO_LCD_5V_ON\n", __func__);
+		goto err3;
+	}
+	if (gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v")) {
+		pr_err("%s: can't request H3600_EGPIO_LVDD_ON\n", __func__);
+		goto err4;
 	}
 
-	return ret;
-}
+	gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
+	gpio_direction_output(H3600_EGPIO_LCD_PCI, enable);
+	gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable);
+	gpio_direction_output(H3600_EGPIO_LVDD_ON, enable);
 
-static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
-{
-	if (port->mapbase == _Ser2UTCR0) { /* TODO: REMOVE THIS */
-		assign_h3600_egpio(IPAQ_EGPIO_IR_ON, !state);
-	} else if (port->mapbase == _Ser3UTCR0) {
-		assign_h3600_egpio(IPAQ_EGPIO_RS232_ON, !state);
-	}
+	gpio_free(H3600_EGPIO_LVDD_ON);
+err4:	gpio_free(H3600_EGPIO_LCD_5V_ON);
+err3:	gpio_free(H3600_EGPIO_LCD_PCI);
+err2:	gpio_free(H3XXX_EGPIO_LCD_ON);
+err1:	return;
 }
 
-/*
- * Enable/Disable wake up events for this serial port.
- * Obviously, we only support this on the normal COM port.
- */
-static int h3600_uart_set_wake(struct uart_port *port, u_int enable)
+static void __init h3600_map_io(void)
 {
-	int err = -EINVAL;
+	h3xxx_map_io();
 
-	if (port->mapbase == _Ser3UTCR0) {
-		if (enable)
-			PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
-		else
-			PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
-		err = 0;
-	}
-	return err;
+	sa1100fb_lcd_power = h3600_lcd_power;
 }
 
-static struct sa1100_port_fns h3600_port_fns __initdata = {
-	.set_mctrl	= h3600_uart_set_mctrl,
-	.get_mctrl	= h3600_uart_get_mctrl,
-	.pm		= h3600_uart_pm,
-	.set_wake	= h3600_uart_set_wake,
-};
-
 /*
- * helper for sa1100fb
+ * This turns the IRDA power on or off on the Compaq H3600
  */
-static void h3xxx_lcd_power(int enable)
+static int h3600_irda_set_power(struct device *dev, unsigned int state)
 {
-	assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER, enable);
+	gpio_set_value(H3600_EGPIO_IR_ON, state);
+	return 0;
 }
 
-static struct map_desc h3600_io_desc[] __initdata = {
-  	{	/* static memory bank 2  CS#2 */
-		.virtual	=  H3600_BANK_2_VIRT,
-		.pfn		= __phys_to_pfn(SA1100_CS2_PHYS),
-		.length		= 0x02800000,
-		.type		= MT_DEVICE
-	}, {	/* static memory bank 4  CS#4 */
-		.virtual	=  H3600_BANK_4_VIRT,
-		.pfn		= __phys_to_pfn(SA1100_CS4_PHYS),
-		.length		= 0x00800000,
-		.type		= MT_DEVICE
-	}, {	/* EGPIO 0		CS#5 */
-		.virtual	=  H3600_EGPIO_VIRT,
-		.pfn		= __phys_to_pfn(H3600_EGPIO_PHYS),
-		.length		= 0x01000000,
-		.type		= MT_DEVICE
-	}
-};
-
-/*
- * Common map_io initialization
- */
-
-static void __init h3xxx_map_io(void)
+static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
 {
-	sa1100_map_io();
-	iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
-
-	sa1100_register_uart_fns(&h3600_port_fns);
-	sa1100_register_uart(0, 3); /* Common serial port */
-//	sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
-
-	/* Ensure those pins are outputs and driving low  */
-	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
-	/* Configure suspend conditions */
-	PGSR = 0;
-	PWER = PWER_GPIO0 | PWER_RTC;
-	PCFR = PCFR_OPDE;
-	PSDR = 0;
-
-	sa1100fb_lcd_power = h3xxx_lcd_power;
+	gpio_set_value(H3600_EGPIO_IR_FSEL, !(speed < 4000000));
 }
 
-/************************* H3100 *************************/
-
-#ifdef CONFIG_SA1100_H3100
-
-#define H3100_EGPIO	(*(volatile unsigned int *)H3600_EGPIO_VIRT)
-static unsigned int h3100_egpio = 0;
-
-static void h3100_control_egpio(enum ipaq_egpio_type x, int setp)
+static int h3600_irda_startup(struct device *dev)
 {
-	unsigned int egpio = 0;
-	long	     gpio = 0;
-	unsigned long flags;
-
-	switch (x) {
-	case IPAQ_EGPIO_LCD_POWER:
-		egpio |= EGPIO_H3600_LCD_ON;
-		gpio  |= GPIO_H3100_LCD_3V_ON;
-		break;
-	case IPAQ_EGPIO_LCD_ENABLE:
-		break;
-	case IPAQ_EGPIO_CODEC_NRESET:
-		egpio |= EGPIO_H3600_CODEC_NRESET;
-		break;
-	case IPAQ_EGPIO_AUDIO_ON:
-		gpio |= GPIO_H3100_AUD_PWR_ON
-			| GPIO_H3100_AUD_ON;
-		break;
-	case IPAQ_EGPIO_QMUTE:
-		gpio |= GPIO_H3100_QMUTE;
-		break;
-	case IPAQ_EGPIO_OPT_NVRAM_ON:
-		egpio |= EGPIO_H3600_OPT_NVRAM_ON;
-		break;
-	case IPAQ_EGPIO_OPT_ON:
-		egpio |= EGPIO_H3600_OPT_ON;
-		break;
-	case IPAQ_EGPIO_CARD_RESET:
-		egpio |= EGPIO_H3600_CARD_RESET;
-		break;
-	case IPAQ_EGPIO_OPT_RESET:
-		egpio |= EGPIO_H3600_OPT_RESET;
-		break;
-	case IPAQ_EGPIO_IR_ON:
-		gpio |= GPIO_H3100_IR_ON;
-		break;
-	case IPAQ_EGPIO_IR_FSEL:
-		gpio |= GPIO_H3100_IR_FSEL;
-		break;
-	case IPAQ_EGPIO_RS232_ON:
-		egpio |= EGPIO_H3600_RS232_ON;
-		break;
-	case IPAQ_EGPIO_VPP_ON:
-		egpio |= EGPIO_H3600_VPP_ON;
-		break;
-	}
+	int err = gpio_request(H3600_EGPIO_IR_ON, "IrDA power");
+	if (err)
+		goto err1;
+	err = gpio_direction_output(H3600_EGPIO_IR_ON, 0);
+	if (err)
+		goto err2;
+	err = gpio_request(H3600_EGPIO_IR_FSEL, "IrDA fsel");
+	if (err)
+		goto err2;
+	err = gpio_direction_output(H3600_EGPIO_IR_FSEL, 0);
+	if (err)
+		goto err3;
+	return 0;
 
-	if (egpio || gpio) {
-		local_irq_save(flags);
-		if (setp) {
-			h3100_egpio |= egpio;
-			GPSR = gpio;
-		} else {
-			h3100_egpio &= ~egpio;
-			GPCR = gpio;
-		}
-		H3100_EGPIO = h3100_egpio;
-		local_irq_restore(flags);
-	}
+err3:	gpio_free(H3600_EGPIO_IR_FSEL);
+err2:	gpio_free(H3600_EGPIO_IR_ON);
+err1:	return err;
 }
 
-#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON	  \
-			  | GPIO_H3100_GPIO3	  \
-			  | GPIO_H3100_QMUTE	  \
-			  | GPIO_H3100_LCD_3V_ON  \
-			  | GPIO_H3100_AUD_ON	  \
-			  | GPIO_H3100_AUD_PWR_ON \
-			  | GPIO_H3100_IR_ON	  \
-			  | GPIO_H3100_IR_FSEL)
-
-static void __init h3100_map_io(void)
+static void h3600_irda_shutdown(struct device *dev)
 {
-	h3xxx_map_io();
-
-	/* Initialize h3100-specific values here */
-	GPCR = 0x0fffffff;	 /* All outputs are set low by default */
-	GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
-	       GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
-	       GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
-	       H3100_DIRECT_EGPIO;
-
-	/* Older bootldrs put GPIO2-9 in alternate mode on the
-	   assumption that they are used for video */
-	GAFR &= ~H3100_DIRECT_EGPIO;
-
-	H3100_EGPIO = h3100_egpio;
-	assign_h3600_egpio = h3100_control_egpio;
+	gpio_free(H3600_EGPIO_IR_ON);
+	gpio_free(H3600_EGPIO_IR_FSEL);
 }
 
-MACHINE_START(H3100, "Compaq iPAQ H3100")
-	.phys_io	= 0x80000000,
-	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
-	.boot_params	= 0xc0000100,
-	.map_io		= h3100_map_io,
-	.init_irq	= sa1100_init_irq,
-	.timer		= &sa1100_timer,
-	.init_machine	= h3xxx_mach_init,
-MACHINE_END
-
-#endif /* CONFIG_SA1100_H3100 */
-
-/************************* H3600 *************************/
-
-#ifdef CONFIG_SA1100_H3600
-
-#define H3600_EGPIO	(*(volatile unsigned int *)H3600_EGPIO_VIRT)
-static unsigned int h3600_egpio = EGPIO_H3600_RS232_ON;
-
-static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
-{
-	unsigned int egpio = 0;
-	unsigned long flags;
-
-	switch (x) {
-	case IPAQ_EGPIO_LCD_POWER:
-		egpio |= EGPIO_H3600_LCD_ON |
-			 EGPIO_H3600_LCD_PCI |
-			 EGPIO_H3600_LCD_5V_ON |
-			 EGPIO_H3600_LVDD_ON;
-		break;
-	case IPAQ_EGPIO_LCD_ENABLE:
-		break;
-	case IPAQ_EGPIO_CODEC_NRESET:
-		egpio |= EGPIO_H3600_CODEC_NRESET;
-		break;
-	case IPAQ_EGPIO_AUDIO_ON:
-		egpio |= EGPIO_H3600_AUD_AMP_ON |
-			 EGPIO_H3600_AUD_PWR_ON;
-		break;
-	case IPAQ_EGPIO_QMUTE:
-		egpio |= EGPIO_H3600_QMUTE;
-		break;
-	case IPAQ_EGPIO_OPT_NVRAM_ON:
-		egpio |= EGPIO_H3600_OPT_NVRAM_ON;
-		break;
-	case IPAQ_EGPIO_OPT_ON:
-		egpio |= EGPIO_H3600_OPT_ON;
-		break;
-	case IPAQ_EGPIO_CARD_RESET:
-		egpio |= EGPIO_H3600_CARD_RESET;
-		break;
-	case IPAQ_EGPIO_OPT_RESET:
-		egpio |= EGPIO_H3600_OPT_RESET;
-		break;
-	case IPAQ_EGPIO_IR_ON:
-		egpio |= EGPIO_H3600_IR_ON;
-		break;
-	case IPAQ_EGPIO_IR_FSEL:
-		egpio |= EGPIO_H3600_IR_FSEL;
-		break;
-	case IPAQ_EGPIO_RS232_ON:
-		egpio |= EGPIO_H3600_RS232_ON;
-		break;
-	case IPAQ_EGPIO_VPP_ON:
-		egpio |= EGPIO_H3600_VPP_ON;
-		break;
-	}
+static struct irda_platform_data h3600_irda_data = {
+	.set_power	= h3600_irda_set_power,
+	.set_speed	= h3600_irda_set_speed,
+	.startup	= h3600_irda_startup,
+	.shutdown	= h3600_irda_shutdown,
+};
 
-	if (egpio) {
-		local_irq_save(flags);
-		if (setp)
-			h3600_egpio |= egpio;
-		else
-			h3600_egpio &= ~egpio;
-		H3600_EGPIO = h3600_egpio;
-		local_irq_restore(flags);
-	}
-}
+static struct gpio_default_state h3600_default_gpio[] = {
+	{ H3XXX_GPIO_COM_DCD,	GPIO_MODE_IN,	"COM DCD" },
+	{ H3XXX_GPIO_COM_CTS,	GPIO_MODE_IN,	"COM CTS" },
+	{ H3XXX_GPIO_COM_RTS,	GPIO_MODE_OUT0,	"COM RTS" },
+};
 
-static void __init h3600_map_io(void)
+static void __init h3600_mach_init(void)
 {
-	h3xxx_map_io();
-
-	/* Initialize h3600-specific values here */
-
-	GPCR = 0x0fffffff;	 /* All outputs are set low by default */
-	GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
-	       GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
-	       GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
-	       GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
-	       GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
-
-	H3600_EGPIO = h3600_egpio;	   /* Maintains across sleep? */
-	assign_h3600_egpio = h3600_control_egpio;
+	h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
+	h3xxx_mach_init();
+	sa11x0_register_irda(&h3600_irda_data);
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
@@ -425,8 +131,6 @@ MACHINE_START(H3600, "Compaq iPAQ H3600"
 	.map_io		= h3600_map_io,
 	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
-	.init_machine	= h3xxx_mach_init,
+	.init_machine	= h3600_mach_init,
 MACHINE_END
 
-#endif /* CONFIG_SA1100_H3600 */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3xxx.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3xxx.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/h3xxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/h3xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,313 @@
+/*
+ * Support for Compaq iPAQ H3100 and H3600 handheld computers (common code)
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This 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/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mfd/htc-egpio.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/h3xxx.h>
+
+#include "generic.h"
+
+void h3xxx_init_gpio(struct gpio_default_state *s, size_t n)
+{
+	while (n--) {
+		const char *name = s->name;
+		int err;
+
+		if (!name)
+			name = "[init]";
+		err = gpio_request(s->gpio, name);
+		if (err) {
+			printk(KERN_ERR "gpio%u: unable to request: %d\n",
+				s->gpio, err);
+			continue;
+		}
+		if (s->mode >= 0) {
+			err = gpio_direction_output(s->gpio, s->mode);
+		} else {
+			err = gpio_direction_input(s->gpio);
+		}
+		if (err) {
+			printk(KERN_ERR "gpio%u: unable to set direction: %d\n",
+				s->gpio, err);
+			continue;
+		}
+		if (!s->name)
+			gpio_free(s->gpio);
+		s++;
+	}
+}
+
+
+/*
+ * H3xxx flash support
+ */
+static struct mtd_partition h3xxx_partitions[] = {
+	{
+		.name		= "H3XXX boot firmware",
+		.size		= 0x00040000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
+	}, {
+		.name		= "H3XXX rootfs",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= 0x00040000,
+	}
+};
+
+static void h3xxx_set_vpp(int vpp)
+{
+	gpio_set_value(H3XXX_EGPIO_VPP_ON, vpp);
+}
+
+static int h3xxx_flash_init(void)
+{
+	int err = gpio_request(H3XXX_EGPIO_VPP_ON, "Flash Vpp");
+	if (err) {
+		pr_err("%s: can't request H3XXX_EGPIO_VPP_ON\n", __func__);
+		return err;
+	}
+
+	err = gpio_direction_output(H3XXX_EGPIO_VPP_ON, 0);
+	if (err)
+		gpio_free(H3XXX_EGPIO_VPP_ON);
+
+	return err;
+}
+
+static void h3xxx_flash_exit(void)
+{
+	gpio_free(H3XXX_EGPIO_VPP_ON);
+}
+
+static struct flash_platform_data h3xxx_flash_data = {
+	.map_name	= "cfi_probe",
+	.set_vpp	= h3xxx_set_vpp,
+	.init		= h3xxx_flash_init,
+	.exit		= h3xxx_flash_exit,
+	.parts		= h3xxx_partitions,
+	.nr_parts	= ARRAY_SIZE(h3xxx_partitions),
+};
+
+static struct resource h3xxx_flash_resource = {
+	.start		= SA1100_CS0_PHYS,
+	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+
+/*
+ * H3xxx uart support
+ */
+static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser3UTCR0) {
+		gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
+	}
+}
+
+static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
+{
+	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	if (port->mapbase == _Ser3UTCR0) {
+		/*
+		 * DCD and CTS bits are inverted in GPLR by RS232 transceiver
+		 */
+		if (gpio_get_value(H3XXX_GPIO_COM_DCD))
+			ret &= ~TIOCM_CD;
+		if (gpio_get_value(H3XXX_GPIO_COM_CTS))
+			ret &= ~TIOCM_CTS;
+	}
+
+	return ret;
+}
+
+static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	if (port->mapbase == _Ser3UTCR0) {
+		if (!gpio_request(H3XXX_EGPIO_RS232_ON, "RS232 transceiver")) {
+			gpio_direction_output(H3XXX_EGPIO_RS232_ON, !state);
+			gpio_free(H3XXX_EGPIO_RS232_ON);
+		} else {
+			pr_err("%s: can't request H3XXX_EGPIO_RS232_ON\n",
+				__func__);
+		}
+	}
+}
+
+/*
+ * Enable/Disable wake up events for this serial port.
+ * Obviously, we only support this on the normal COM port.
+ */
+static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
+{
+	int err = -EINVAL;
+
+	if (port->mapbase == _Ser3UTCR0) {
+		if (enable)
+			PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
+		else
+			PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
+		err = 0;
+	}
+	return err;
+}
+
+static struct sa1100_port_fns h3xxx_port_fns __initdata = {
+	.set_mctrl	= h3xxx_uart_set_mctrl,
+	.get_mctrl	= h3xxx_uart_get_mctrl,
+	.pm		= h3xxx_uart_pm,
+	.set_wake	= h3xxx_uart_set_wake,
+};
+
+/*
+ * EGPIO
+ */
+
+static struct resource egpio_resources[] = {
+	[0] = {
+		.start	= H3600_EGPIO_PHYS,
+		.end	= H3600_EGPIO_PHYS + 0x4 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct htc_egpio_chip egpio_chips[] = {
+	[0] = {
+		.reg_start	= 0,
+		.gpio_base	= H3XXX_EGPIO_BASE,
+		.num_gpios	= 16,
+		.direction	= HTC_EGPIO_OUTPUT,
+		.initial_values	= 0x0080, /* H3XXX_EGPIO_RS232_ON */
+	},
+};
+
+static struct htc_egpio_platform_data egpio_info = {
+	.reg_width	= 16,
+	.bus_width	= 16,
+	.chip		= egpio_chips,
+	.num_chips	= ARRAY_SIZE(egpio_chips),
+};
+
+static struct platform_device h3xxx_egpio = {
+	.name		= "htc-egpio",
+	.id		= -1,
+	.resource	= egpio_resources,
+	.num_resources	= ARRAY_SIZE(egpio_resources),
+	.dev		= {
+		.platform_data = &egpio_info,
+	},
+};
+
+/*
+ * GPIO keys
+ */
+
+static struct gpio_keys_button h3xxx_button_table[] = {
+	{
+		.code		= KEY_POWER,
+		.gpio		= H3XXX_GPIO_PWR_BUTTON,
+		.desc		= "Power Button",
+		.active_low	= 1,
+		.type		= EV_KEY,
+		.wakeup		= 1,
+	}, {
+		.code		= KEY_ENTER,
+		.gpio		= H3XXX_GPIO_ACTION_BUTTON,
+		.active_low	= 1,
+		.desc		= "Action button",
+		.type		= EV_KEY,
+		.wakeup		= 0,
+	},
+};
+
+static struct gpio_keys_platform_data h3xxx_keys_data = {
+	.buttons  = h3xxx_button_table,
+	.nbuttons = ARRAY_SIZE(h3xxx_button_table),
+};
+
+static struct platform_device h3xxx_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &h3xxx_keys_data,
+	},
+};
+
+static struct platform_device *h3xxx_devices[] = {
+	&h3xxx_egpio,
+	&h3xxx_keys,
+};
+
+void __init h3xxx_mach_init(void)
+{
+	sa1100_register_uart_fns(&h3xxx_port_fns);
+	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
+	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
+}
+
+static struct map_desc h3600_io_desc[] __initdata = {
+	{	/* static memory bank 2  CS#2 */
+		.virtual	=  H3600_BANK_2_VIRT,
+		.pfn		= __phys_to_pfn(SA1100_CS2_PHYS),
+		.length		= 0x02800000,
+		.type		= MT_DEVICE
+	}, {	/* static memory bank 4  CS#4 */
+		.virtual	=  H3600_BANK_4_VIRT,
+		.pfn		= __phys_to_pfn(SA1100_CS4_PHYS),
+		.length		= 0x00800000,
+		.type		= MT_DEVICE
+	}, {	/* EGPIO 0		CS#5 */
+		.virtual	=  H3600_EGPIO_VIRT,
+		.pfn		= __phys_to_pfn(H3600_EGPIO_PHYS),
+		.length		= 0x01000000,
+		.type		= MT_DEVICE
+	}
+};
+
+/*
+ * Common map_io initialization
+ */
+
+void __init h3xxx_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
+
+	sa1100_register_uart(0, 3); /* Common serial port */
+//	sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
+
+	/* Ensure those pins are outputs and driving low  */
+	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
+	/* Configure suspend conditions */
+	PGSR = 0;
+	PCFR = PCFR_OPDE;
+	PSDR = 0;
+
+	GPCR = 0x0fffffff;	/* All outputs are set low by default */
+	GPDR = 0;		/* Configure all GPIOs as input */
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/hackkit.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/hackkit.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/hackkit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/hackkit.c	2010-02-24 13:52:17.000000000 -0500
@@ -187,7 +187,7 @@ static struct resource hackkit_flash_res
 
 static void __init hackkit_init(void)
 {
-	sa11x0_set_flash_data(&hackkit_flash_data, &hackkit_flash_resource, 1);
+	sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
 }
 
 /**********************************************************************
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/collie.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/collie.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,29 +25,39 @@
 #define COLLIE_GPIO_VPEN	(COLLIE_SCOOP_GPIO_BASE + 7)
 #define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19
 
-#define COLLIE_SCOOP_IO_DIR	( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
+#define COLLIE_SCOOP_IO_DIR	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
 				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
-				COLLIE_SCP_LB_VOL_CHG )
-#define COLLIE_SCOOP_IO_OUT	( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R )
+				COLLIE_SCP_LB_VOL_CHG)
+#define COLLIE_SCOOP_IO_OUT	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
 
-/* GPIOs for which the generic definition doesn't say much */
+/* GPIOs for gpiolib  */
 
-#define COLLIE_GPIO_ON_KEY		GPIO_GPIO (0)
-#define COLLIE_GPIO_AC_IN		GPIO_GPIO (1)
-#define COLLIE_GPIO_SDIO_INT		GPIO_GPIO (11)
-#define COLLIE_GPIO_CF_IRQ		GPIO_GPIO (14)
-#define COLLIE_GPIO_nREMOCON_INT	GPIO_GPIO (15)
-#define COLLIE_GPIO_UCB1x00_RESET	GPIO_GPIO (16)
-#define COLLIE_GPIO_nMIC_ON		GPIO_GPIO (17)
-#define COLLIE_GPIO_nREMOCON_ON		GPIO_GPIO (18)
-#define COLLIE_GPIO_CO			GPIO_GPIO (20)
-#define COLLIE_GPIO_MCP_CLK		GPIO_GPIO (21)
-#define COLLIE_GPIO_CF_CD		GPIO_GPIO (22)
-#define COLLIE_GPIO_UCB1x00_IRQ		GPIO_GPIO (23)
-#define COLLIE_GPIO_WAKEUP		GPIO_GPIO (24)
-#define COLLIE_GPIO_GA_INT		GPIO_GPIO (25)
-#define COLLIE_GPIO_MAIN_BAT_LOW	GPIO_GPIO (26)
+#define COLLIE_GPIO_ON_KEY		(0)
+#define COLLIE_GPIO_AC_IN		(1)
+#define COLLIE_GPIO_SDIO_INT		(11)
+#define COLLIE_GPIO_CF_IRQ		(14)
+#define COLLIE_GPIO_nREMOCON_INT	(15)
+#define COLLIE_GPIO_UCB1x00_RESET	(16)
+#define COLLIE_GPIO_nMIC_ON		(17)
+#define COLLIE_GPIO_nREMOCON_ON		(18)
+#define COLLIE_GPIO_CO			(20)
+#define COLLIE_GPIO_MCP_CLK		(21)
+#define COLLIE_GPIO_CF_CD		(22)
+#define COLLIE_GPIO_UCB1x00_IRQ		(23)
+#define COLLIE_GPIO_WAKEUP		(24)
+#define COLLIE_GPIO_GA_INT		(25)
+#define COLLIE_GPIO_MAIN_BAT_LOW	(26)
 
+/* GPIO definitions for direct register access */
+
+#define _COLLIE_GPIO_ON_KEY		GPIO_GPIO(0)
+#define _COLLIE_GPIO_AC_IN		GPIO_GPIO(1)
+#define _COLLIE_GPIO_nREMOCON_INT	GPIO_GPIO(15)
+#define _COLLIE_GPIO_UCB1x00_RESET	GPIO_GPIO(16)
+#define _COLLIE_GPIO_nMIC_ON		GPIO_GPIO(17)
+#define _COLLIE_GPIO_nREMOCON_ON	GPIO_GPIO(18)
+#define _COLLIE_GPIO_CO			GPIO_GPIO(20)
+#define _COLLIE_GPIO_WAKEUP		GPIO_GPIO(24)
 /* Interrupts */
 
 #define COLLIE_IRQ_GPIO_ON_KEY		IRQ_GPIO0
@@ -70,19 +80,20 @@
 #define COLLIE_LCM_IRQ_GPIO_nSD_WP	IRQ_LOCOMO_GPIO14
 
 /* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
-#define COLLIE_TC35143_GPIO_VERSION0    UCB_IO_0	/* GPIO0=Version                 */
-#define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1	/* GPIO1=TBL_CHK                 */
-#define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2	/* GPIO2=VPNE_ON                 */
-#define COLLIE_TC35143_GPIO_IR_ON       UCB_IO_3	/* GPIO3=IR_ON                   */
-#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4	/* GPIO4=AMP_ON                  */
-#define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5	/* GPIO5=Version                 */
-#define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5	/* GPIO5=fs 8k LPF               */
-#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6	/* GPIO6=BUZZER BIAS             */
-#define COLLIE_TC35143_GPIO_MBAT_ON     UCB_IO_7	/* GPIO7=MBAT_ON                 */
-#define COLLIE_TC35143_GPIO_BBAT_ON     UCB_IO_8	/* GPIO8=BBAT_ON                 */
-#define COLLIE_TC35143_GPIO_TMP_ON      UCB_IO_9	/* GPIO9=TMP_ON                  */
-#define COLLIE_TC35143_GPIO_IN		( UCB_IO_0 | UCB_IO_2 | UCB_IO_5 )
-#define COLLIE_TC35143_GPIO_OUT		( UCB_IO_1 | UCB_IO_3 | UCB_IO_4 | UCB_IO_6 | \
-					UCB_IO_7 | UCB_IO_8 | UCB_IO_9 )
+#define COLLIE_TC35143_GPIO_BASE	(GPIO_MAX + 13)
+#define COLLIE_TC35143_GPIO_VERSION0    UCB_IO_0
+#define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
+#define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
+#define COLLIE_TC35143_GPIO_IR_ON       UCB_IO_3
+#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
+#define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
+#define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
+#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
+#define COLLIE_GPIO_MBAT_ON     	(COLLIE_TC35143_GPIO_BASE + 7)
+#define COLLIE_GPIO_BBAT_ON     	(COLLIE_TC35143_GPIO_BASE + 8)
+#define COLLIE_GPIO_TMP_ON      	(COLLIE_TC35143_GPIO_BASE + 9)
+#define COLLIE_TC35143_GPIO_IN		(UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
+#define COLLIE_TC35143_GPIO_OUT		(UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
+						| UCB_IO_6)
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,20 +49,9 @@ static inline void gpio_set_value(unsign
 
 #define gpio_cansleep	__gpio_cansleep
 
-static inline unsigned gpio_to_irq(unsigned gpio)
-{
-	if (gpio < 11)
-		return IRQ_GPIO0 + gpio;
-	else
-		return IRQ_GPIO11 - 11 + gpio;
-}
-
-static inline unsigned irq_to_gpio(unsigned irq)
-{
-	if (irq < IRQ_GPIO11_27)
-		return irq - IRQ_GPIO0;
-	else
-		return irq - IRQ_GPIO11 + 11;
-}
+#define gpio_to_irq(gpio)	((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
+					(IRQ_GPIO11 - 11 + gpio))
+#define irq_to_gpio(irq)	((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
+					(irq - IRQ_GPIO11 + 11))
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,77 +0,0 @@
-/*
- *
- * Definitions for H3600 Handheld Computer
- *
- * Copyright 2000 Compaq Computer Corporation.
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Author: Jamey Hicks.
- *
- * History:
- *
- * 2001-10-??   Andrew Christian   Added support for iPAQ H3800
- *
- */
-
-#ifndef _INCLUDE_H3600_GPIO_H_
-#define _INCLUDE_H3600_GPIO_H_
-
-/*
- * GPIO lines that are common across ALL iPAQ models are in "h3600.h"
- * This file contains machine-specific definitions
- */
-
-#define GPIO_H3600_SUSPEND              GPIO_GPIO (0)
-/* GPIO[2:9] used by LCD on H3600/3800, used as GPIO on H3100 */
-#define GPIO_H3100_BT_ON		GPIO_GPIO (2)
-#define GPIO_H3100_GPIO3		GPIO_GPIO (3)
-#define GPIO_H3100_QMUTE		GPIO_GPIO (4)
-#define GPIO_H3100_LCD_3V_ON		GPIO_GPIO (5)
-#define GPIO_H3100_AUD_ON		GPIO_GPIO (6)
-#define GPIO_H3100_AUD_PWR_ON		GPIO_GPIO (7)
-#define GPIO_H3100_IR_ON		GPIO_GPIO (8)
-#define GPIO_H3100_IR_FSEL		GPIO_GPIO (9)
-
-/* for H3600, audio sample rate clock generator */
-#define GPIO_H3600_CLK_SET0		GPIO_GPIO (12)
-#define GPIO_H3600_CLK_SET1		GPIO_GPIO (13)
-
-#define GPIO_H3600_ACTION_BUTTON	GPIO_GPIO (18)
-#define GPIO_H3600_SOFT_RESET           GPIO_GPIO (20)   /* Also known as BATT_FAULT */
-#define GPIO_H3600_OPT_LOCK		GPIO_GPIO (22)
-#define GPIO_H3600_OPT_DET		GPIO_GPIO (27)
-
-/****************************************************/
-
-#define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
-#define IRQ_GPIO_H3600_OPT_DET		IRQ_GPIO27
-
-/* H3100 / 3600 EGPIO pins */
-#define EGPIO_H3600_VPP_ON		(1 << 0)
-#define EGPIO_H3600_CARD_RESET		(1 << 1)   /* reset the attached pcmcia/compactflash card.  active high. */
-#define EGPIO_H3600_OPT_RESET		(1 << 2)   /* reset the attached option pack.  active high. */
-#define EGPIO_H3600_CODEC_NRESET	(1 << 3)   /* reset the onboard UDA1341.  active low. */
-#define EGPIO_H3600_OPT_NVRAM_ON	(1 << 4)   /* apply power to optionpack nvram, active high. */
-#define EGPIO_H3600_OPT_ON		(1 << 5)   /* full power to option pack.  active high. */
-#define EGPIO_H3600_LCD_ON		(1 << 6)   /* enable 3.3V to LCD.  active high. */
-#define EGPIO_H3600_RS232_ON		(1 << 7)   /* UART3 transceiver force on.  Active high. */
-
-/* H3600 only EGPIO pins */
-#define EGPIO_H3600_LCD_PCI		(1 << 8)   /* LCD control IC enable.  active high. */
-#define EGPIO_H3600_IR_ON		(1 << 9)   /* apply power to IR module.  active high. */
-#define EGPIO_H3600_AUD_AMP_ON		(1 << 10)  /* apply power to audio power amp.  active high. */
-#define EGPIO_H3600_AUD_PWR_ON		(1 << 11)  /* apply power to reset of audio circuit.  active high. */
-#define EGPIO_H3600_QMUTE		(1 << 12)  /* mute control for onboard UDA1341.  active high. */
-#define EGPIO_H3600_IR_FSEL		(1 << 13)  /* IR speed select: 1->fast, 0->slow */
-#define EGPIO_H3600_LCD_5V_ON		(1 << 14)  /* enable 5V to LCD. active high. */
-#define EGPIO_H3600_LVDD_ON		(1 << 15)  /* enable 9V and -6.5V to LCD. */
-
-
-#endif /* _INCLUDE_H3600_GPIO_H_ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*
- *
- * Definitions for H3600 Handheld Computer
- *
- * Copyright 2000 Compaq Computer Corporation.
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Author: Jamey Hicks.
- *
- * History:
- *
- * 2001-10-??	Andrew Christian   Added support for iPAQ H3800
- *
- */
-
-#ifndef _INCLUDE_H3600_H_
-#define _INCLUDE_H3600_H_
-
-typedef int __bitwise pm_request_t;
-
-#define PM_SUSPEND	((__force pm_request_t) 1)	/* enter D1-D3 */
-#define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */
-
-/* generalized support for H3xxx series Compaq Pocket PC's */
-#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600())
-
-/* Physical memory regions corresponding to chip selects */
-#define H3600_EGPIO_PHYS	(SA1100_CS5_PHYS + 0x01000000)
-#define H3600_BANK_2_PHYS	SA1100_CS2_PHYS
-#define H3600_BANK_4_PHYS	SA1100_CS4_PHYS
-
-/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
-#define H3600_EGPIO_VIRT	0xf0000000
-#define H3600_BANK_2_VIRT	0xf1000000
-#define H3600_BANK_4_VIRT	0xf3800000
-
-/*
-   Machine-independent GPIO definitions
-   --- these are common across all current iPAQ platforms
-*/
-
-#define GPIO_H3600_NPOWER_BUTTON	GPIO_GPIO (0)	/* Also known as the "off button"  */
-
-#define GPIO_H3600_PCMCIA_CD1		GPIO_GPIO (10)
-#define GPIO_H3600_PCMCIA_IRQ1		GPIO_GPIO (11)
-
-/* UDA1341 L3 Interface */
-#define GPIO_H3600_L3_DATA		GPIO_GPIO (14)
-#define GPIO_H3600_L3_MODE		GPIO_GPIO (15)
-#define GPIO_H3600_L3_CLOCK		GPIO_GPIO (16)
-
-#define GPIO_H3600_PCMCIA_CD0		GPIO_GPIO (17)
-#define GPIO_H3600_SYS_CLK		GPIO_GPIO (19)
-#define GPIO_H3600_PCMCIA_IRQ0		GPIO_GPIO (21)
-
-#define GPIO_H3600_COM_DCD		GPIO_GPIO (23)
-#define GPIO_H3600_OPT_IRQ		GPIO_GPIO (24)
-#define GPIO_H3600_COM_CTS		GPIO_GPIO (25)
-#define GPIO_H3600_COM_RTS		GPIO_GPIO (26)
-
-#define IRQ_GPIO_H3600_NPOWER_BUTTON	IRQ_GPIO0
-#define IRQ_GPIO_H3600_PCMCIA_CD1	IRQ_GPIO10
-#define IRQ_GPIO_H3600_PCMCIA_IRQ1	IRQ_GPIO11
-#define IRQ_GPIO_H3600_PCMCIA_CD0	IRQ_GPIO17
-#define IRQ_GPIO_H3600_PCMCIA_IRQ0	IRQ_GPIO21
-#define IRQ_GPIO_H3600_COM_DCD		IRQ_GPIO23
-#define IRQ_GPIO_H3600_OPT_IRQ		IRQ_GPIO24
-#define IRQ_GPIO_H3600_COM_CTS		IRQ_GPIO25
-
-
-#ifndef __ASSEMBLY__
-
-enum ipaq_egpio_type {
-	IPAQ_EGPIO_LCD_POWER,	  /* Power to the LCD panel */
-	IPAQ_EGPIO_CODEC_NRESET,  /* Clear to reset the audio codec (remember to return high) */
-	IPAQ_EGPIO_AUDIO_ON,	  /* Audio power */
-	IPAQ_EGPIO_QMUTE,	  /* Audio muting */
-	IPAQ_EGPIO_OPT_NVRAM_ON,  /* Non-volatile RAM on extension sleeves (SPI interface) */
-	IPAQ_EGPIO_OPT_ON,	  /* Power to extension sleeves */
-	IPAQ_EGPIO_CARD_RESET,	  /* Reset PCMCIA cards on extension sleeve (???) */
-	IPAQ_EGPIO_OPT_RESET,	  /* Reset option pack (???) */
-	IPAQ_EGPIO_IR_ON,	  /* IR sensor/emitter power */
-	IPAQ_EGPIO_IR_FSEL,	  /* IR speed selection 1->fast, 0->slow */
-	IPAQ_EGPIO_RS232_ON,	  /* Maxim RS232 chip power */
-	IPAQ_EGPIO_VPP_ON,	  /* Turn on power to flash programming */
-	IPAQ_EGPIO_LCD_ENABLE,	  /* Enable/disable LCD controller */
-};
-
-extern void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
-
-#endif /* ASSEMBLY */
-
-#endif /* _INCLUDE_H3600_H_ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3xxx.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3xxx.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/h3xxx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/h3xxx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,94 @@
+/*
+ * Definitions for Compaq iPAQ H3100 and H3600 handheld computers
+ *
+ * (c) 2000 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This 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 _INCLUDE_H3XXX_H_
+#define _INCLUDE_H3XXX_H_
+
+/* Physical memory regions corresponding to chip selects */
+#define H3600_EGPIO_PHYS	(SA1100_CS5_PHYS + 0x01000000)
+#define H3600_BANK_2_PHYS	SA1100_CS2_PHYS
+#define H3600_BANK_4_PHYS	SA1100_CS4_PHYS
+
+/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
+#define H3600_EGPIO_VIRT	0xf0000000
+#define H3600_BANK_2_VIRT	0xf1000000
+#define H3600_BANK_4_VIRT	0xf3800000
+
+/*
+ * gpiolib numbers for all iPAQs
+ */
+#define H3XXX_GPIO_PWR_BUTTON		0
+#define H3XXX_GPIO_PCMCIA_CD1		10
+#define H3XXX_GPIO_PCMCIA_IRQ1		11
+#define H3XXX_GPIO_PCMCIA_CD0		17
+#define H3XXX_GPIO_ACTION_BUTTON	18
+#define H3XXX_GPIO_SYS_CLK		19
+#define H3XXX_GPIO_PCMCIA_IRQ0		21
+#define H3XXX_GPIO_COM_DCD		23
+#define H3XXX_GPIO_OPTION		24
+#define H3XXX_GPIO_COM_CTS		25
+#define H3XXX_GPIO_COM_RTS		26
+
+/* machine-specific gpios */
+
+#define H3100_GPIO_BT_ON		2
+#define H3100_GPIO_QMUTE		4
+#define H3100_GPIO_LCD_3V_ON		5
+#define H3100_GPIO_AUD_ON		6
+#define H3100_GPIO_AUD_PWR_ON		7
+#define H3100_GPIO_IR_ON		8
+#define H3100_GPIO_IR_FSEL		9
+
+#define H3600_GPIO_CLK_SET0		12	/* audio sample rate clock generator */
+#define H3600_GPIO_CLK_SET1		13
+#define H3600_GPIO_SOFT_RESET		20	/* also known as BATT_FAULT */
+#define H3600_GPIO_OPT_LOCK		22
+#define H3600_GPIO_OPT_DET		27
+
+
+/* H3100 / 3600 EGPIO pins */
+#define H3XXX_EGPIO_BASE		(GPIO_MAX + 1)
+
+#define H3XXX_EGPIO_VPP_ON		(H3XXX_EGPIO_BASE + 0)
+#define H3XXX_EGPIO_CARD_RESET		(H3XXX_EGPIO_BASE + 1) /* reset the attached pcmcia/compactflash card.  active high. */
+#define H3XXX_EGPIO_OPT_RESET		(H3XXX_EGPIO_BASE + 2) /* reset the attached option pack.  active high. */
+#define H3XXX_EGPIO_CODEC_NRESET	(H3XXX_EGPIO_BASE + 3) /* reset the onboard UDA1341.  active low. */
+#define H3XXX_EGPIO_OPT_NVRAM_ON	(H3XXX_EGPIO_BASE + 4) /* apply power to optionpack nvram, active high. */
+#define H3XXX_EGPIO_OPT_ON		(H3XXX_EGPIO_BASE + 5) /* full power to option pack.  active high. */
+#define H3XXX_EGPIO_LCD_ON		(H3XXX_EGPIO_BASE + 6) /* enable 3.3V to LCD.  active high. */
+#define H3XXX_EGPIO_RS232_ON		(H3XXX_EGPIO_BASE + 7) /* UART3 transceiver force on.  Active high. */
+
+/* H3600 only EGPIO pins */
+#define H3600_EGPIO_LCD_PCI		(H3XXX_EGPIO_BASE + 8) /* LCD control IC enable.  active high. */
+#define H3600_EGPIO_IR_ON		(H3XXX_EGPIO_BASE + 9) /* apply power to IR module.  active high. */
+#define H3600_EGPIO_AUD_AMP_ON		(H3XXX_EGPIO_BASE + 10) /* apply power to audio power amp.  active high. */
+#define H3600_EGPIO_AUD_PWR_ON		(H3XXX_EGPIO_BASE + 11) /* apply power to reset of audio circuit.  active high. */
+#define H3600_EGPIO_QMUTE		(H3XXX_EGPIO_BASE + 12) /* mute control for onboard UDA1341.  active high. */
+#define H3600_EGPIO_IR_FSEL		(H3XXX_EGPIO_BASE + 13) /* IR speed select: 1->fast, 0->slow */
+#define H3600_EGPIO_LCD_5V_ON		(H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
+#define H3600_EGPIO_LVDD_ON		(H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
+
+struct gpio_default_state {
+	int gpio;
+	int mode;
+	const char *name;
+};
+
+#define GPIO_MODE_IN	-1
+#define GPIO_MODE_OUT0	0
+#define GPIO_MODE_OUT1	1
+
+void h3xxx_init_gpio(struct gpio_default_state *s, size_t n);
+void __init h3xxx_map_io(void);
+void __init h3xxx_mach_init(void);
+
+#endif /* _INCLUDE_H3XXX_H_ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/mcp.h linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/mcp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/include/mach/mcp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/include/mach/mcp.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@ struct mcp_plat_data {
 	u32 mccr0;
 	u32 mccr1;
 	unsigned int sclk_rate;
+	int gpio_base;
 };
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/jornada720.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/jornada720.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/jornada720.c	2010-02-24 13:52:17.000000000 -0500
@@ -354,7 +354,7 @@ static struct resource jornada720_flash_
 
 static void __init jornada720_mach_init(void)
 {
-	sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1);
+	sa11x0_register_mtd(&jornada720_flash_data, &jornada720_flash_resource, 1);
 }
 
 MACHINE_START(JORNADA720, "HP Jornada 720")
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@ menu "SA11x0 Implementations"
 
 config SA1100_ASSABET
 	bool "Assabet"
+	select CPU_FREQ_SA1110
 	help
 	  Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
 	  Microprocessor Development Board (also known as the Assabet).
@@ -19,6 +20,7 @@ config ASSABET_NEPONSET
 
 config SA1100_CERF
 	bool "CerfBoard"
+	select CPU_FREQ_SA1110
 	help
 	  The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
 	  More information is available at:
@@ -45,6 +47,7 @@ endchoice
 
 config SA1100_COLLIE
 	bool "Sharp Zaurus SL5500"
+	# FIXME: select CPU_FREQ_SA11x0
 	select SHARP_LOCOMO
 	select SHARP_SCOOP
 	select SHARP_PARAM
@@ -53,27 +56,30 @@ config SA1100_COLLIE
 
 config SA1100_H3100
 	bool "Compaq iPAQ H3100"
+	select HTC_EGPIO
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here if you intend to run this kernel on the Compaq iPAQ
 	  H3100 handheld computer.  Information about this machine and the
 	  Linux port to this machine can be found at:
 
 	  <http://www.handhelds.org/Compaq/index.html#iPAQ_H3100>
-	  <http://www.compaq.com/products/handhelds/pocketpc/>
 
 config SA1100_H3600
 	bool "Compaq iPAQ H3600/H3700"
+	select HTC_EGPIO
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here if you intend to run this kernel on the Compaq iPAQ
 	  H3600 handheld computer.  Information about this machine and the
 	  Linux port to this machine can be found at:
 
 	  <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
-	  <http://www.compaq.com/products/handhelds/pocketpc/>
 
 config SA1100_BADGE4
 	bool "HP Labs BadgePAD 4"
 	select SA1111
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here if you want to build a kernel for the HP Laboratories
 	  BadgePAD 4.
@@ -81,6 +87,7 @@ config SA1100_BADGE4
 config SA1100_JORNADA720
 	bool "HP Jornada 720"
 	select SA1111
+	# FIXME: select CPU_FREQ_SA11x0
 	help
 	  Say Y here if you want to build a kernel for the HP Jornada 720
 	  handheld computer.  See <http://www.hp.com/jornada/products/720>
@@ -98,12 +105,14 @@ config SA1100_JORNADA720_SSP
 
 config SA1100_HACKKIT
 	bool "HackKit Core CPU Board"
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here to support the HackKit Core CPU Board
 	  <http://hackkit.eletztrick.de>;
 
 config SA1100_LART
 	bool "LART"
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here if you are using the Linux Advanced Radio Terminal
 	  (also known as the LART).  See <http://www.lartmaker.nl/> for
@@ -111,6 +120,7 @@ config SA1100_LART
 
 config SA1100_PLEB
 	bool "PLEB"
+	select CPU_FREQ_SA1100
 	help
 	  Say Y here if you are using version 1 of the Portable Linux
 	  Embedded Board (also known as PLEB).
@@ -119,6 +129,7 @@ config SA1100_PLEB
 
 config SA1100_SHANNON
 	bool "Shannon"
+	select CPU_FREQ_SA1100
 	help
 	  The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
 	  limited edition webphone produced by Philips. The Shannon is a SA1100
@@ -127,6 +138,7 @@ config SA1100_SHANNON
 
 config SA1100_SIMPAD
 	bool "Simpad"
+	select CPU_FREQ_SA1110
 	help
 	  The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
 	  are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
@@ -145,3 +157,4 @@ config SA1100_SSP
 endmenu
 
 endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/lart.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/lart.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/lart.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/lart.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ static struct mcp_plat_data lart_mcp_dat
 
 static void __init lart_init(void)
 {
-	sa11x0_set_mcp_data(&lart_mcp_data);
+	sa11x0_register_mcp(&lart_mcp_data);
 }
 
 static struct map_desc lart_io_desc[] __initdata = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -25,8 +25,8 @@ led-$(CONFIG_SA1100_CERF)		+= leds-cerf.
 
 obj-$(CONFIG_SA1100_COLLIE)		+= collie.o
 
-obj-$(CONFIG_SA1100_H3100)		+= h3600.o
-obj-$(CONFIG_SA1100_H3600)		+= h3600.o
+obj-$(CONFIG_SA1100_H3100)		+= h3100.o h3xxx.o
+obj-$(CONFIG_SA1100_H3600)		+= h3600.o h3xxx.o
 
 obj-$(CONFIG_SA1100_HACKKIT)		+= hackkit.o
 led-$(CONFIG_SA1100_HACKKIT)		+= leds-hackkit.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/pleb.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/pleb.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/pleb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/pleb.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,7 +109,7 @@ static struct flash_platform_data pleb_f
 
 static void __init pleb_init(void)
 {
-	sa11x0_set_flash_data(&pleb_flash_data, pleb_flash_resources,
+	sa11x0_register_mtd(&pleb_flash_data, pleb_flash_resources,
 			      ARRAY_SIZE(pleb_flash_resources));
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/shannon.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/shannon.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/shannon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/shannon.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,8 +59,8 @@ static struct mcp_plat_data shannon_mcp_
 
 static void __init shannon_init(void)
 {
-	sa11x0_set_flash_data(&shannon_flash_data, &shannon_flash_resource, 1);
-	sa11x0_set_mcp_data(&shannon_mcp_data);
+	sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
+	sa11x0_register_mcp(&shannon_mcp_data);
 }
 
 static void __init shannon_map_io(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/simpad.c linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/simpad.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-sa1100/simpad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-sa1100/simpad.c	2010-02-24 13:52:17.000000000 -0500
@@ -166,9 +166,9 @@ static void __init simpad_map_io(void)
 	PCFR = 0;
 	PSDR = 0;
 
-	sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources,
+	sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
 			      ARRAY_SIZE(simpad_flash_resources));
-	sa11x0_set_mcp_data(&simpad_mcp_data);
+	sa11x0_register_mcp(&simpad_mcp_data);
 }
 
 static void simpad_power_off(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-u300/i2c.c linux-libre-2.6.33-gnu1/arch/arm/mach-u300/i2c.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,13 +9,257 @@
  */
 #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
+
+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[] = {
+	{
+		.dev = NULL,
+		.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[] = {
+	{
+		.dev = NULL,
+		.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,
+				.valid_ops_mask =
+				REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS,
+				.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,
+				.valid_ops_mask =
+				REGULATOR_CHANGE_VOLTAGE |
+				REGULATOR_CHANGE_STATUS,
+				.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 |
+				REGULATOR_CHANGE_STATUS,
+				.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,
+	},
+};
+
 static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
 	{
 		.type = "ab3100",
 		.addr = 0x48,
 		.irq = IRQ_U300_IRQ0_EXT,
+		.platform_data = &ab3100_plf_data,
 	},
 };
 
@@ -38,6 +282,11 @@ void __init u300_i2c_register_board_devi
 {
 	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 linux-libre-2.6.32-gnu1/arch/arm/mach-u300/include/mach/coh901318.h linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/coh901318.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/include/mach/coh901318.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/coh901318.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,281 @@
+/*
+ *
+ * include/linux/coh901318.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * DMA driver for COH 901 318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef COH901318_H
+#define COH901318_H
+
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+
+#define MAX_DMA_PACKET_SIZE_SHIFT 11
+#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT)
+
+/**
+ * struct coh901318_lli - linked list item for DMAC
+ * @control: control settings for DMAC
+ * @src_addr: transfer source address
+ * @dst_addr: transfer destination address
+ * @link_addr:  physical address to next lli
+ * @virt_link_addr: virtual addres of next lli (only used by pool_free)
+ * @phy_this: physical address of current lli (only used by pool_free)
+ */
+struct coh901318_lli {
+	u32 control;
+	dma_addr_t src_addr;
+	dma_addr_t dst_addr;
+	dma_addr_t link_addr;
+
+	void *virt_link_addr;
+	dma_addr_t phy_this;
+};
+/**
+ * struct coh901318_params - parameters for DMAC configuration
+ * @config: DMA config register
+ * @ctrl_lli_last: DMA control register for the last lli in the list
+ * @ctrl_lli: DMA control register for an lli
+ * @ctrl_lli_chained: DMA control register for a chained lli
+ */
+struct coh901318_params {
+	u32 config;
+	u32 ctrl_lli_last;
+	u32 ctrl_lli;
+	u32 ctrl_lli_chained;
+};
+/**
+ * struct coh_dma_channel - dma channel base
+ * @name: ascii name of dma channel
+ * @number: channel id number
+ * @desc_nbr_max: number of preallocated descriptortors
+ * @priority_high: prio of channel, 0 low otherwise high.
+ * @param: configuration parameters
+ * @dev_addr: physical address of periphal connected to channel
+ */
+struct coh_dma_channel {
+	const char name[32];
+	const int number;
+	const int desc_nbr_max;
+	const int priority_high;
+	const struct coh901318_params param;
+	const dma_addr_t dev_addr;
+};
+
+/**
+ * dma_access_memory_state_t - register dma for memory access
+ *
+ * @dev: The dma device
+ * @active:  1 means dma intends to access memory
+ *           0 means dma wont access memory
+ */
+typedef void (*dma_access_memory_state_t)(struct device *dev,
+					  bool active);
+
+/**
+ * struct powersave - DMA power save structure
+ * @lock: lock protecting data in this struct
+ * @started_channels: bit mask indicating active dma channels
+ */
+struct powersave {
+	spinlock_t lock;
+	u64 started_channels;
+};
+/**
+ * struct coh901318_platform - platform arch structure
+ * @chans_slave: specifying dma slave channels
+ * @chans_memcpy: specifying dma memcpy channels
+ * @access_memory_state: requesting DMA memeory access (on / off)
+ * @chan_conf: dma channel configurations
+ * @max_channels: max number of dma chanenls
+ */
+struct coh901318_platform {
+	const int *chans_slave;
+	const int *chans_memcpy;
+	const dma_access_memory_state_t access_memory_state;
+	const struct coh_dma_channel *chan_conf;
+	const int max_channels;
+};
+
+/**
+ * coh901318_get_bytes_left() - Get number of bytes left on a current transfer
+ * @chan: dma channel handle
+ * return number of bytes left, or negative on error
+ */
+u32 coh901318_get_bytes_left(struct dma_chan *chan);
+
+/**
+ * coh901318_stop() - Stops dma transfer
+ * @chan: dma channel handle
+ * return 0 on success otherwise negative value
+ */
+void coh901318_stop(struct dma_chan *chan);
+
+/**
+ * coh901318_continue() - Resumes a stopped dma transfer
+ * @chan: dma channel handle
+ * return 0 on success otherwise negative value
+ */
+void coh901318_continue(struct dma_chan *chan);
+
+/**
+ * coh901318_filter_id() - DMA channel filter function
+ * @chan: dma channel handle
+ * @chan_id: id of dma channel to be filter out
+ *
+ * In dma_request_channel() it specifies what channel id to be requested
+ */
+bool coh901318_filter_id(struct dma_chan *chan, void *chan_id);
+
+/*
+ * DMA Controller - this access the static mappings of the coh901318 dma.
+ *
+ */
+
+#define COH901318_MOD32_MASK					(0x1F)
+#define COH901318_WORD_MASK					(0xFFFFFFFF)
+/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */
+#define COH901318_INT_STATUS1					(0x0000)
+#define COH901318_INT_STATUS2					(0x0004)
+/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_TC_INT_STATUS1				(0x0008)
+#define COH901318_TC_INT_STATUS2				(0x000C)
+/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_TC_INT_CLEAR1					(0x0010)
+#define COH901318_TC_INT_CLEAR2					(0x0014)
+/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_TC_INT_STATUS1				(0x0018)
+#define COH901318_RAW_TC_INT_STATUS2				(0x001C)
+/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */
+#define COH901318_BE_INT_STATUS1				(0x0020)
+#define COH901318_BE_INT_STATUS2				(0x0024)
+/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_BE_INT_CLEAR1					(0x0028)
+#define COH901318_BE_INT_CLEAR2					(0x002C)
+/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_BE_INT_STATUS1				(0x0030)
+#define COH901318_RAW_BE_INT_STATUS2				(0x0034)
+
+/*
+ * CX_CFG - Channel Configuration Registers 32bit (R/W)
+ */
+#define COH901318_CX_CFG					(0x0100)
+#define COH901318_CX_CFG_SPACING				(0x04)
+/* Channel enable activates tha dma job */
+#define COH901318_CX_CFG_CH_ENABLE				(0x00000001)
+#define COH901318_CX_CFG_CH_DISABLE				(0x00000000)
+/* Request Mode */
+#define COH901318_CX_CFG_RM_MASK				(0x00000006)
+#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY			(0x0 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY			(0x1 << 1)
+#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY			(0x1 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY		(0x3 << 1)
+#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY		(0x3 << 1)
+/* Linked channel request field. RM must == 11 */
+#define COH901318_CX_CFG_LCRF_SHIFT				3
+#define COH901318_CX_CFG_LCRF_MASK				(0x000001F8)
+#define COH901318_CX_CFG_LCR_DISABLE				(0x00000000)
+/* Terminal Counter Interrupt Request Mask */
+#define COH901318_CX_CFG_TC_IRQ_ENABLE				(0x00000200)
+#define COH901318_CX_CFG_TC_IRQ_DISABLE				(0x00000000)
+/* Bus Error interrupt Mask */
+#define COH901318_CX_CFG_BE_IRQ_ENABLE				(0x00000400)
+#define COH901318_CX_CFG_BE_IRQ_DISABLE				(0x00000000)
+
+/*
+ * CX_STAT - Channel Status Registers 32bit (R/-)
+ */
+#define COH901318_CX_STAT					(0x0200)
+#define COH901318_CX_STAT_SPACING				(0x04)
+#define COH901318_CX_STAT_RBE_IRQ_IND				(0x00000008)
+#define COH901318_CX_STAT_RTC_IRQ_IND				(0x00000004)
+#define COH901318_CX_STAT_ACTIVE				(0x00000002)
+#define COH901318_CX_STAT_ENABLED				(0x00000001)
+
+/*
+ * CX_CTRL - Channel Control Registers 32bit (R/W)
+ */
+#define COH901318_CX_CTRL					(0x0400)
+#define COH901318_CX_CTRL_SPACING				(0x10)
+/* Transfer Count Enable */
+#define COH901318_CX_CTRL_TC_ENABLE				(0x00001000)
+#define COH901318_CX_CTRL_TC_DISABLE				(0x00000000)
+/* Transfer Count Value 0 - 4095 */
+#define COH901318_CX_CTRL_TC_VALUE_MASK				(0x00000FFF)
+/* Burst count */
+#define COH901318_CX_CTRL_BURST_COUNT_MASK			(0x0000E000)
+#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES			(0x7 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES			(0x6 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES			(0x5 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES			(0x4 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES			(0x3 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES			(0x2 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES			(0x1 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE			(0x0 << 13)
+/* Source bus size  */
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK			(0x00030000)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS			(0x2 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS			(0x1 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS			(0x0 << 16)
+/* Source address increment */
+#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE			(0x00040000)
+#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE			(0x00000000)
+/* Destination Bus Size */
+#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK			(0x00180000)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS			(0x2 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS			(0x1 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS			(0x0 << 19)
+/* Destination address increment */
+#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE			(0x00200000)
+#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE			(0x00000000)
+/* Master Mode (Master2 is only connected to MSL) */
+#define COH901318_CX_CTRL_MASTER_MODE_MASK			(0x00C00000)
+#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W			(0x3 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W			(0x2 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M2RW			(0x1 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1RW			(0x0 << 22)
+/* Terminal Count flag to PER enable */
+#define COH901318_CX_CTRL_TCP_ENABLE				(0x01000000)
+#define COH901318_CX_CTRL_TCP_DISABLE				(0x00000000)
+/* Terminal Count flags to CPU enable */
+#define COH901318_CX_CTRL_TC_IRQ_ENABLE				(0x02000000)
+#define COH901318_CX_CTRL_TC_IRQ_DISABLE			(0x00000000)
+/* Hand shake to peripheral */
+#define COH901318_CX_CTRL_HSP_ENABLE				(0x04000000)
+#define COH901318_CX_CTRL_HSP_DISABLE				(0x00000000)
+#define COH901318_CX_CTRL_HSS_ENABLE				(0x08000000)
+#define COH901318_CX_CTRL_HSS_DISABLE				(0x00000000)
+/* DMA mode */
+#define COH901318_CX_CTRL_DDMA_MASK				(0x30000000)
+#define COH901318_CX_CTRL_DDMA_LEGACY				(0x0 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1			(0x1 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2			(0x2 << 28)
+/* Primary Request Data Destination */
+#define COH901318_CX_CTRL_PRDD_MASK				(0x40000000)
+#define COH901318_CX_CTRL_PRDD_DEST				(0x1 << 30)
+#define COH901318_CX_CTRL_PRDD_SOURCE				(0x0 << 30)
+
+/*
+ * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_SRC_ADDR					(0x0404)
+#define COH901318_CX_SRC_ADDR_SPACING				(0x10)
+
+/*
+ * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W
+ */
+#define COH901318_CX_DST_ADDR					(0x0408)
+#define COH901318_CX_DST_ADDR_SPACING				(0x10)
+
+/*
+ * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_LNK_ADDR					(0x040C)
+#define COH901318_CX_LNK_ADDR_SPACING				(0x10)
+#define COH901318_CX_LNK_LINK_IMMEDIATE				(0x00000001)
+#endif /* COH901318_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-u300/include/mach/u300-regs.h linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/u300-regs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/include/mach/u300-regs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/include/mach/u300-regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  * 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 defintions for core devices like the timer.
+ * some block definitions for core devices like the timer.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-u300/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-u300/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -12,3 +12,4 @@ obj-$(CONFIG_MMC)                 += mmc
 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 linux-libre-2.6.32-gnu1/arch/arm/mach-u300/mmc.c linux-libre-2.6.33-gnu1/arch/arm/mach-u300/mmc.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,64 +40,6 @@ static unsigned int mmc_status(struct de
 	return mmci_card->mmc_inserted;
 }
 
-/*
- * Here follows a large chunk of code which will only be enabled if you
- * have both the AB3100 chip mounted and the MMC subsystem activated.
- */
-
-static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage)
-{
-	int v;
-
-	/*
-	 * MMC Spec:
-	 * bit 7:	1.70 - 1.95V
-	 * bit 8 - 14:	2.0 - 2.6V
-	 * bit 15 - 23:	2.7 - 3.6V
-	 *
-	 * ab3100 voltages:
-	 * 000 - 2.85V
-	 * 001 - 2.75V
-	 * 010 - 1.8V
-	 * 011 - 1.5V
-	 */
-	switch (voltage) {
-	case 8:
-		v = 3;
-		break;
-	case 9:
-	case 10:
-	case 11:
-	case 12:
-	case 13:
-	case 14:
-	case 15:
-		v = 1;
-		break;
-	case 16:
-		v = 1;
-		break;
-	case 17:
-	case 18:
-	case 19:
-	case 20:
-	case 21:
-	case 22:
-	case 23:
-	case 24:
-		v = 0;
-		break;
-	default:
-		v = 0;
-		break;
-	}
-
-	/* PL180 voltage register bits */
-	return v << 2;
-}
-
-
-
 static int mmci_callback(void *data)
 {
 	struct mmci_card_event *mmci_card = data;
@@ -154,9 +96,11 @@ int __devinit mmc_init(struct amba_devic
 	if (!mmci_card)
 		return -ENOMEM;
 
+	/*
+	 * Do not set ocr_mask or voltage translation function,
+	 * we have a regulator we can control instead.
+	 */
 	/* Nominally 2.85V on our platform */
-	mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29;
-	mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd;
 	mmci_card->mmc0_plat_data.status = mmc_status;
 	mmci_card->mmc0_plat_data.gpio_wp = -1;
 	mmci_card->mmc0_plat_data.gpio_cd = -1;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-u300/regulator.c linux-libre-2.6.33-gnu1/arch/arm/mach-u300/regulator.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-u300/regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-u300/regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-u300/regulator.c
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Handle board-bound regulators and board power not related
+ * to any devices.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/err.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>
+
+/*
+ * Regulators that power the board and chip and which are
+ * not copuled to specific drivers are hogged in these
+ * instances.
+ */
+static struct regulator *main_power_15;
+
+/*
+ * This function is used from pm.h to shut down the system by
+ * resetting all regulators in turn and then disable regulator
+ * LDO D (main power).
+ */
+void u300_pm_poweroff(void)
+{
+	sigset_t old, all;
+
+	sigfillset(&all);
+	if (!sigprocmask(SIG_BLOCK, &all, &old)) {
+		/* Disable LDO D to shut down the system */
+		if (main_power_15)
+			regulator_disable(main_power_15);
+		else
+			pr_err("regulator not available to shut down system\n");
+		(void) sigprocmask(SIG_SETMASK, &old, NULL);
+	}
+	return;
+}
+
+/*
+ * Hog the regulators needed to power up the board.
+ */
+static int __init u300_init_boardpower(void)
+{
+	int err;
+	u32 val;
+
+	pr_info("U300: setting up board power\n");
+	main_power_15 = regulator_get(NULL, "vana15");
+	if (IS_ERR(main_power_15)) {
+		pr_err("could not get vana15");
+		return PTR_ERR(main_power_15);
+	}
+	err = regulator_enable(main_power_15);
+	if (err) {
+		pr_err("could not enable vana15\n");
+		return err;
+	}
+
+	/*
+	 * On U300 a special system controller register pulls up the DC
+	 * until the vana15 (LDO D) regulator comes up. At this point, all
+	 * regulators are set and we do not need power control via
+	 * DC ON anymore. This function will likely be moved whenever
+	 * 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);
+
+	/* Register globally exported PM poweroff hook */
+	pm_power_off = u300_pm_poweroff;
+
+	return 0;
+}
+
+/*
+ * So at module init time we hog the regulator!
+ */
+module_init(u300_init_boardpower);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/board-mop500.c linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/board-mop500.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/board-mop500.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/board-mop500.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@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/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl022.h>
+#include <linux/spi/spi.h>
+
+#include <asm/localtimer.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/mtu.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+#define __MEM_4K_RESOURCE(x) \
+	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+/* These are active devices on this board */
+static struct amba_device uart0_device = {
+	.dev = { .init_name = "uart0" },
+	__MEM_4K_RESOURCE(U8500_UART0_BASE),
+	.irq = {IRQ_UART0, NO_IRQ},
+};
+
+static struct amba_device uart1_device = {
+	.dev = { .init_name = "uart1" },
+	__MEM_4K_RESOURCE(U8500_UART1_BASE),
+	.irq = {IRQ_UART1, NO_IRQ},
+};
+
+static struct amba_device uart2_device = {
+	.dev = { .init_name = "uart2" },
+	__MEM_4K_RESOURCE(U8500_UART2_BASE),
+	.irq = {IRQ_UART2, NO_IRQ},
+};
+
+static void ab4500_spi_cs_control(u32 command)
+{
+	/* set the FRM signal, which is CS  - TODO */
+}
+
+struct pl022_config_chip ab4500_chip_info = {
+	.lbm = LOOPBACK_DISABLED,
+	.com_mode = INTERRUPT_TRANSFER,
+	.iface = SSP_INTERFACE_MOTOROLA_SPI,
+	/* we can act as master only */
+	.hierarchy = SSP_MASTER,
+	.slave_tx_disable = 0,
+	.endian_rx = SSP_RX_MSB,
+	.endian_tx = SSP_TX_MSB,
+	.data_size = SSP_DATA_BITS_24,
+	.rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
+	.tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
+	.clk_phase = SSP_CLK_SECOND_EDGE,
+	.clk_pol = SSP_CLK_POL_IDLE_HIGH,
+	.cs_control = ab4500_spi_cs_control,
+};
+
+static struct spi_board_info u8500_spi_devices[] = {
+	{
+		.modalias = "ab4500",
+		.controller_data = &ab4500_chip_info,
+		.max_speed_hz = 12000000,
+		.bus_num = 0,
+		.chip_select = 0,
+		.mode = SPI_MODE_0,
+		.irq = IRQ_AB4500,
+	},
+};
+
+static struct pl022_ssp_controller ssp0_platform_data = {
+	.bus_id = 0,
+	/* pl022 not yet supports dma */
+	.enable_dma = 0,
+	/* on this platform, gpio 31,142,144,214 &
+	 * 224 are connected as chip selects
+	 */
+	.num_chipselect = 5,
+};
+
+static struct amba_device pl022_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "pl022",
+		.platform_data = &ssp0_platform_data,
+	},
+	.res = {
+		.start = U8500_SSP0_BASE,
+		.end   = U8500_SSP0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_SSP0, NO_IRQ },
+	/* ST-Ericsson modified id */
+	.periphid = SSP_PER_ID,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	&uart0_device,
+	&uart1_device,
+	&uart2_device,
+	&pl022_device,
+};
+
+static void __init u8500_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+	/* Setup the local timer base */
+	twd_base = __io_address(U8500_TWD_BASE);
+#endif
+	/* Setup the MTU base */
+	mtu_base = __io_address(U8500_MTU0_BASE);
+
+	nmdk_timer_init();
+}
+
+static struct sys_timer u8500_timer = {
+	.init	= u8500_timer_init,
+};
+
+static void __init u8500_init_machine(void)
+{
+	int i;
+
+	/* Register the active AMBA devices on this board */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+
+	spi_register_board_info(u8500_spi_devices,
+			ARRAY_SIZE(u8500_spi_devices));
+
+	u8500_init_devices();
+}
+
+MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
+	/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
+	.phys_io	= U8500_UART2_BASE,
+	.io_pg_offst	= (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x100,
+	.map_io		= u8500_map_io,
+	.init_irq	= u8500_init_irq,
+	/* we re-use nomadik timer here */
+	.timer		= &u8500_timer,
+	.init_machine	= u8500_init_machine,
+MACHINE_END
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/clock.c linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ * 	heavily based on realview platform
+ *
+ * This 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/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/clkdev.h>
+
+/* currently the clk structure
+ * just supports rate. This would
+ * be extended as and when new devices are
+ * added - TODO
+ */
+struct clk {
+	unsigned long		rate;
+};
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	/*TODO*/
+	return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* ssp clock */
+static struct clk ssp_clk = {
+	.rate = 48000000,
+};
+
+/* fixed clock */
+static struct clk f38_clk = {
+	.rate = 38400000,
+};
+
+static struct clk_lookup lookups[] = {
+	{
+		/* UART0 */
+		.dev_id		= "uart0",
+		.clk		= &f38_clk,
+	}, {	/* UART1 */
+		.dev_id		= "uart1",
+		.clk		= &f38_clk,
+	}, {	/* UART2 */
+		.dev_id		= "uart2",
+		.clk		= &f38_clk,
+	}, {	/* SSP */
+		.dev_id		= "pl022",
+		.clk		= &ssp_clk,
+	}
+};
+
+static int __init clk_init(void)
+{
+	int i;
+
+	/* register the clock lookups */
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+	return 0;
+}
+arch_initcall(clk_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/cpu-u8500.c linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/cpu-u8500.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/cpu-u8500.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/cpu-u8500.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@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/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
+	/* yet to be added, add i2c0, gpio.. */
+};
+
+#define __IO_DEV_DESC(x, sz)	{		\
+	.virtual	= IO_ADDRESS(x),	\
+	.pfn		= __phys_to_pfn(x),	\
+	.length		= sz,			\
+	.type		= MT_DEVICE,		\
+}
+
+/* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
+};
+
+void __init u8500_map_io(void)
+{
+	iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+}
+
+void __init u8500_init_irq(void)
+{
+	gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29);
+	gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+}
+
+/*
+ * This function is called from the board init
+ */
+void __init u8500_init_devices(void)
+{
+	/* Register the platform devices */
+	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+	return ;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/headsmp.S linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/headsmp.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/headsmp.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/headsmp.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2009 ST-Ericsson
+ *	This file is based  ARM Realview platform
+ *  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>
+
+	__INIT
+
+/*
+ * U8500 specific entry point for secondary CPUs.
+ */
+ENTRY(u8500_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
+	dsb
+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 linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/clkdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/debug-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,19 @@
+/*
+ * Debugging macro include header
+ *
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * This 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.
+ *
+ */
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1			@MMU enabled?
+	moveq	\rx, #0x80000000	@MMU off, Physical address
+	movne	\rx, #0xF0000000	@MMU on, Virtual address
+	orr	\rx, \rx, #0x7000
+	.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/entry-macro.S linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/entry-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/entry-macro.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,89 @@
+/*
+ * Low-level IRQ helper macros for U8500 platforms
+ *
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This file is a copy of ARM Realview platform.
+ *	-just satisfied checkpatch script.
+ *
+ * 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 <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr     \base, =IO_ADDRESS(U8500_GIC_CPU_BASE)
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		/*
+		 * The interrupt numbering scheme is defined in the
+		 * interrupt controller spec.  To wit:
+		 *
+		 * Interrupts 0-15 are IPI
+		 * 16-28 are reserved
+		 * 29-31 are local.  We allow 30 to be used for the watchdog.
+		 * 32-1020 are global
+		 * 1021-1022 are reserved
+		 * 1023 is "spurious" (no interrupt)
+		 *
+		 * For now, we ignore all local interrupts so only return an
+		 * interrupt if it's between 30 and 1020. The test_for_ipi
+		 * routine below will pick up on IPIs.
+		 *
+		 * A simple read from the controller will tell us the number
+		 * of the highest priority enabled interrupt. We then just
+		 * need to check whether it is in the valid range for an
+		 * IRQ (30-1020 inclusive).
+		 */
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		/* bits 12-10 = src CPU, 9-0 = int # */
+		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
+
+		ldr	\tmp, =1021
+
+		bic     \irqnr, \irqstat, #0x1c00
+
+		cmp     \irqnr, #29
+		cmpcc	\irqnr, \irqnr
+		cmpne	\irqnr, \tmp
+		cmpcs	\irqnr, \irqnr
+
+		.endm
+
+		/* We assume that irqstat (the raw value of the IRQ
+		 * acknowledge register) is preserved from the macro above.
+		 * If there is an IPI, we immediately signal end of
+		 * interrupt on the controller, since this requires the
+		 * original irqstat value which we won't easily be able
+		 * to recreate later.
+		 */
+
+		.macro test_for_ipi, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		cmp	\irqnr, #16
+		strcc	\irqstat, [\base, #GIC_CPU_EOI]
+		cmpcs	\irqnr, \irqnr
+		.endm
+
+		/* As above, this assumes that irqstat and base
+		 * are preserved..
+		 */
+
+		.macro test_for_ltirq, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		mov 	\tmp, #0
+		cmp	\irqnr, #29
+		moveq	\tmp, #1
+		streq	\irqstat, [\base, #GIC_CPU_EOI]
+		cmp	\tmp, #0
+		.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * U8500 hardware definitions
+ *
+ * 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_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* macros to get at IO space when running virtually
+ * We dont map all the peripherals, let ioremap do
+ * this for us. We map only very basic peripherals here.
+ */
+#define U8500_IO_VIRTUAL	0xf0000000
+#define U8500_IO_PHYSICAL	0xa0000000
+
+/* this macro is used in assembly, so no cast */
+#define IO_ADDRESS(x)           \
+	(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)
+
+/* typesafe io address */
+#define __io_address(n)		__io(IO_ADDRESS(n))
+
+/*
+ * Base address definitions for U8500 Onchip IPs. All the
+ * peripherals are contained in a single 1 Mbyte region, with
+ * AHB peripherals at the bottom and APB peripherals at the
+ * top of the region. PER stands for PERIPHERAL region which
+ * itself divided into sub regions.
+ */
+#define U8500_PER3_BASE		0x80000000
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_PER4_BASE		0x80150000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER5_BASE		0xa03e0000
+#define U8500_PER7_BASE		0xa03d0000
+
+#define U8500_SVA_BASE		0xa0100000
+#define U8500_SIA_BASE		0xa0200000
+
+#define U8500_SGA_BASE		0xa0300000
+#define U8500_MCDE_BASE		0xa0350000
+#define U8500_DMA_BASE		0xa0362000
+
+#define U8500_SCU_BASE		0xa0410000
+#define U8500_GIC_CPU_BASE	0xa0410100
+#define U8500_TWD_BASE		0xa0410600
+#define U8500_GIC_DIST_BASE	0xa0411000
+#define U8500_L2CC_BASE		0xa0412000
+
+#define U8500_TWD_SIZE		0x100
+
+/* per7 base addressess */
+#define U8500_CR_BASE		(U8500_PER7_BASE + 0x8000)
+#define U8500_MTU0_BASE		(U8500_PER7_BASE + 0xa000)
+#define U8500_MTU1_BASE		(U8500_PER7_BASE + 0xb000)
+#define U8500_TZPC0_BASE	(U8500_PER7_BASE + 0xc000)
+#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* per6 base addressess */
+#define U8500_RNG_BASE		(U8500_PER6_BASE + 0x0000)
+#define U8500_PKA_BASE		(U8500_PER6_BASE + 0x1000)
+#define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x2000)
+#define U8500_CRYPTO0_BASE	(U8500_PER6_BASE + 0xa000)
+#define U8500_CRYPTO1_BASE	(U8500_PER6_BASE + 0xb000)
+#define U8500_CLKRST6_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* per5 base addressess */
+#define U8500_USBOTG_BASE	(U8500_PER5_BASE + 0x00000)
+#define U8500_GPIO5_BASE	(U8500_PER5_BASE + 0x1e000)
+#define U8500_CLKRST5_BASE	(U8500_PER7_BASE + 0x1f000)
+
+/* per4 base addressess */
+#define U8500_BACKUPRAM0_BASE	(U8500_PER4_BASE + 0x0000)
+#define U8500_BACKUPRAM1_BASE	(U8500_PER4_BASE + 0x1000)
+#define U8500_RTT0_BASE		(U8500_PER4_BASE + 0x2000)
+#define U8500_RTT1_BASE		(U8500_PER4_BASE + 0x3000)
+#define U8500_RTC_BASE		(U8500_PER4_BASE + 0x4000)
+#define U8500_SCR_BASE		(U8500_PER4_BASE + 0x5000)
+#define U8500_DMC_BASE		(U8500_PER4_BASE + 0x6000)
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x7000)
+
+/* per3 base addressess */
+#define U8500_FSMC_BASE		(U8500_PER3_BASE + 0x0000)
+#define U8500_SSP0_BASE		(U8500_PER3_BASE + 0x2000)
+#define U8500_SSP1_BASE		(U8500_PER3_BASE + 0x3000)
+#define U8500_I2C0_BASE		(U8500_PER3_BASE + 0x4000)
+#define U8500_SDI2_BASE		(U8500_PER3_BASE + 0x5000)
+#define U8500_SKE_BASE		(U8500_PER3_BASE + 0x6000)
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_SDI5_BASE		(U8500_PER3_BASE + 0x8000)
+#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xe000)
+#define U8500_CLKRST3_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* per2 base addressess */
+#define U8500_I2C3_BASE		(U8500_PER2_BASE + 0x0000)
+#define U8500_SPI2_BASE		(U8500_PER2_BASE + 0x1000)
+#define U8500_SPI1_BASE		(U8500_PER2_BASE + 0x2000)
+#define U8500_PWL_BASE		(U8500_PER2_BASE + 0x3000)
+#define U8500_SDI4_BASE		(U8500_PER2_BASE + 0x4000)
+#define U8500_MSP2_BASE		(U8500_PER2_BASE + 0x7000)
+#define U8500_SDI1_BASE		(U8500_PER2_BASE + 0x8000)
+#define U8500_SDI3_BASE		(U8500_PER2_BASE + 0x9000)
+#define U8500_SPI0_BASE		(U8500_PER2_BASE + 0xa000)
+#define U8500_HSIR_BASE		(U8500_PER2_BASE + 0xb000)
+#define U8500_HSIT_BASE		(U8500_PER2_BASE + 0xc000)
+#define U8500_GPIO2_BASE	(U8500_PER2_BASE + 0xe000)
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* per1 base addresses */
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+#define U8500_I2C1_BASE		(U8500_PER1_BASE + 0x2000)
+#define U8500_MSP0_BASE		(U8500_PER1_BASE + 0x3000)
+#define U8500_MSP1_BASE		(U8500_PER1_BASE + 0x4000)
+#define U8500_SDI0_BASE		(U8500_PER1_BASE + 0x6000)
+#define U8500_I2C2_BASE		(U8500_PER1_BASE + 0x8000)
+#define U8500_SPI3_BASE		(U8500_PER1_BASE + 0x9000)
+#define U8500_SLIM0_BASE	(U8500_PER1_BASE + 0xa000)
+#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xe000)
+#define U8500_CLKRST1_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* ST-Ericsson modified pl022 id */
+#define SSP_PER_ID		0x01080022
+
+#endif				/* __MACH_HARDWARE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-u8500/include/mach/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (C) 2008 STMicroelectronics
+ *  Copyright (C) 2009 ST-Ericsson.
+ *
+ * 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 ASM_ARCH_IRQS_H
+#define ASM_ARCH_IRQS_H
+
+#include <mach/hardware.h>
+
+#define IRQ_LOCALTIMER                  29
+#define IRQ_LOCALWDOG                   30
+
+/* Shared Peripheral Interrupt (SHPI) */
+#define IRQ_SHPI_START			32
+
+/* Interrupt numbers generic for shared peripheral */
+#define IRQ_MTU0		(IRQ_SHPI_START + 4)
+#define IRQ_SPI2		(IRQ_SHPI_START + 6)
+#define IRQ_SPI0		(IRQ_SHPI_START + 8)
+#define IRQ_UART0		(IRQ_SHPI_START + 11)
+#define IRQ_I2C3		(IRQ_SHPI_START + 12)
+#define IRQ_SSP0		(IRQ_SHPI_START + 14)
+#define IRQ_MTU1		(IRQ_SHPI_START + 17)
+#define IRQ_RTC_RTT		(IRQ_SHPI_START + 18)
+#define IRQ_UART1		(IRQ_SHPI_START + 19)
+#define IRQ_I2C0		(IRQ_SHPI_START + 21)
+#define IRQ_I2C1		(IRQ_SHPI_START + 22)
+#define IRQ_USBOTG		(IRQ_SHPI_START + 23)
+#define IRQ_DMA			(IRQ_SHPI_START + 25)
+#define IRQ_UART2		(IRQ_SHPI_START + 26)
+#define IRQ_HSIR_EXCEP		(IRQ_SHPI_START + 29)
+#define IRQ_MSP0		(IRQ_SHPI_START + 31)
+#define IRQ_HSIR_CH0_OVRRUN	(IRQ_SHPI_START + 32)
+#define IRQ_HSIR_CH1_OVRRUN	(IRQ_SHPI_START + 33)
+#define IRQ_HSIR_CH2_OVRRUN	(IRQ_SHPI_START + 34)
+#define IRQ_HSIR_CH3_OVRRUN	(IRQ_SHPI_START + 35)
+#define IRQ_AB4500		(IRQ_SHPI_START + 40)
+#define IRQ_DISP		(IRQ_SHPI_START + 48)
+#define IRQ_SiPI3		(IRQ_SHPI_START + 49)
+#define IRQ_SSP1		(IRQ_SHPI_START + 52)
+#define IRQ_I2C2		(IRQ_SHPI_START + 55)
+#define IRQ_SDMMC0		(IRQ_SHPI_START + 60)
+#define IRQ_MSP1		(IRQ_SHPI_START + 62)
+#define IRQ_SPI1		(IRQ_SHPI_START + 96)
+#define IRQ_MSP2		(IRQ_SHPI_START + 98)
+#define IRQ_SDMMC4		(IRQ_SHPI_START + 99)
+#define IRQ_HSIRD0		(IRQ_SHPI_START + 104)
+#define IRQ_HSIRD1		(IRQ_SHPI_START + 105)
+#define IRQ_HSITD0		(IRQ_SHPI_START + 106)
+#define IRQ_HSITD1		(IRQ_SHPI_START + 107)
+#define IRQ_GPIO0		(IRQ_SHPI_START + 119)
+#define IRQ_GPIO1		(IRQ_SHPI_START + 120)
+#define IRQ_GPIO2		(IRQ_SHPI_START + 121)
+#define IRQ_GPIO3		(IRQ_SHPI_START + 122)
+#define IRQ_GPIO4		(IRQ_SHPI_START + 123)
+#define IRQ_GPIO5		(IRQ_SHPI_START + 124)
+#define IRQ_GPIO6		(IRQ_SHPI_START + 125)
+#define IRQ_GPIO7		(IRQ_SHPI_START + 126)
+#define IRQ_GPIO8		(IRQ_SHPI_START + 127)
+
+/* There are 128 shared peripheral interrupts assigned to
+ * INTID[160:32]. The first 32 interrupts are reserved.
+ */
+#define NR_IRQS			161
+
+#endif /*ASM_ARCH_IRQS_H*/
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	UL(0x00000000)
+#define BUS_OFFSET	UL(0x00000000)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/setup.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/setup.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/setup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/setup.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This 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.
+ *
+ * These symbols are needed for board-specific files to call their
+ * own cpu-specific files
+ */
+#ifndef __ASM_ARCH_SETUP_H
+#define __ASM_ARCH_SETUP_H
+
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+extern void u8500_map_io(void);
+extern void u8500_init_devices(void);
+extern void u8500_init_irq(void);
+/* We re-use nomadik_timer for this platform */
+extern void nmdk_timer_init(void);
+
+#endif /*  __ASM_ARCH_SETUP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/smp.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/smp.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/*
+ * This file is based ARM realview platform.
+ * Copyright (C) ARM Limited.
+ *
+ * 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 ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+/* This is required to wakeup the secondary core */
+extern void u8500_secondary_startup(void);
+
+#define hard_smp_processor_id()				\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+	gic_raise_softirq(mask, 1);
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	/* yet to be implemented - TODO */
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE		110000000
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * 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_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define U8500_UART_DR		0x80007000
+#define U8500_UART_LCRH		0x8000702c
+#define U8500_UART_CR		0x80007030
+#define U8500_UART_FR		0x80007018
+
+static void putc(const char c)
+{
+	/* Do nothing if the UART is not enabled. */
+	if (!(readb(U8500_UART_CR) & 0x1))
+		return;
+
+	if (c == '\n')
+		putc('\r');
+
+	while (readb(U8500_UART_FR) & (1 << 5))
+		barrier();
+	writeb(c, U8500_UART_DR);
+}
+
+static void flush(void)
+{
+	if (!(readb(U8500_UART_CR) & 0x1))
+		return;
+	while (readb(U8500_UART_FR) & (1 << 3))
+		barrier();
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog() /* nothing to do here */
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/include/mach/vmalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * 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 VMALLOC_END	0xf0000000
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,15 @@
+menu "ST-Ericsson platform type"
+	depends on ARCH_U8500
+
+comment "ST-Ericsson Multicore Mobile Platforms"
+
+config MACH_U8500_MOP
+	bool "U8500 Early Development platform"
+	default y
+	select ARM_GIC
+	select HAS_MTU
+	help
+	  Include support for mop500 development platform
+	  based on U8500 architecture. The platform is based
+	  on early drop silicon version of 8500.
+endmenu
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/localtimer.c linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/localtimer.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/localtimer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/localtimer.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is heavily based on relaview platform, almost a copy.
+ *
+ * Copyright (C) 2002 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.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/irq.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = IRQ_LOCALTIMER;
+	twd_timer_setup(evt);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Makefile linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel, U8500 machine.
+#
+
+obj-y				:= clock.o
+obj-$(CONFIG_ARCH_U8500)	+= cpu-u8500.o
+obj-$(CONFIG_MACH_U8500_MOP)	+= board-mop500.o
+obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o localtimer.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Makefile.boot linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Makefile.boot
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/Makefile.boot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,4 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/platsmp.c linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/platsmp.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-ux500/platsmp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-ux500/platsmp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * Copyright (C) 2008 STMicroelctronics.
+ * Copyright (C) 2009 ST-Ericsson.
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is based on arm realview platform
+ *
+ * This 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/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+#include <mach/hardware.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static unsigned int __init get_core_count(void)
+{
+	return scu_get_core_count(__io_address(U8500_SCU_BASE));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	pen_release = -1;
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit 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.
+	 */
+	pen_release = cpu;
+	flush_cache_all();
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		if (pen_release == -1)
+			break;
+	}
+
+	/*
+	 * 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;
+}
+
+static void __init wakeup_secondary(void)
+{
+	/* nobody is to be released from the pen yet */
+	pen_release = -1;
+
+	/*
+	 * write the address of secondary startup into the backup ram register
+	 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
+	 * backup ram register at offset 0x1FF0, which is what boot rom code
+	 * is waiting for. This would wake up the secondary core from WFE
+	 */
+#define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
+	__raw_writel(virt_to_phys(u8500_secondary_startup),
+		(void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+		U8500_CPU1_JUMPADDR_OFFSET);
+
+#define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
+	__raw_writel(0xA1FEED01,
+		(void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+		U8500_CPU1_WAKEMAGIC_OFFSET);
+
+	/* make sure write buffer is drained */
+	mb();
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	unsigned int i, ncores = get_core_count();
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	unsigned int ncores = get_core_count();
+	unsigned int cpu = smp_processor_id();
+	int i;
+
+	/* sanity check */
+	if (ncores == 0) {
+		printk(KERN_ERR
+		       "U8500: strange CM count of 0? Default to 1\n");
+		ncores = 1;
+	}
+
+	if (ncores > num_possible_cpus())	{
+		printk(KERN_WARNING
+		       "U8500: no. of cores (%d) greater than configured "
+		       "maximum of %d - clipping\n",
+		       ncores, num_possible_cpus());
+		ncores = num_possible_cpus();
+	}
+
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * are we trying to boot more cores than exist?
+	 */
+	if (max_cpus > ncores)
+		max_cpus = ncores;
+
+	/*
+	 * Initialise the present map, which describes the set of CPUs
+	 * actually populated at the present time.
+	 */
+	for (i = 0; i < max_cpus; i++)
+		set_cpu_present(i, true);
+
+	if (max_cpus > 1) {
+		/*
+		 * Enable the local timer or broadcast device for the
+		 * boot CPU, but only if we have more than one CPU.
+		 */
+		percpu_timer_setup();
+		scu_enable(__io_address(U8500_SCU_BASE));
+		wakeup_secondary();
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/cpu.c linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,6 +96,7 @@ static struct clk_lookup nuc900_clkregs[
 
 struct plat_serial8250_port nuc900_uart_data[] = {
 	NUC900_8250PORT(UART0),
+	{},
 };
 
 struct platform_device nuc900_serial_device = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/dev.c linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/dev.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <asm/mach-types.h>
 
 #include <mach/regs-serial.h>
+#include <mach/nuc900_spi.h>
 #include <mach/map.h>
 
 #include "cpu.h"
@@ -196,6 +197,18 @@ static struct platform_device nuc900_dev
 
 /* SPI device */
 
+static struct nuc900_spi_info nuc900_spiflash_data = {
+	.num_cs		= 1,
+	.lsb		= 0,
+	.txneg		= 1,
+	.rxneg		= 0,
+	.divider	= 24,
+	.sleep		= 0,
+	.txnum		= 0,
+	.txbitlen	= 1,
+	.bus_num	= 0,
+};
+
 static struct resource nuc900_spi_resource[] = {
 	[0] = {
 		.start = W90X900_PA_I2C + SPIOFFSET,
@@ -214,6 +227,9 @@ static struct platform_device nuc900_dev
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(nuc900_spi_resource),
 	.resource	= nuc900_spi_resource,
+	.dev		= {
+				.platform_data = &nuc900_spiflash_data,
+			}
 };
 
 /* spi device, spi flash info */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/nuc900_spi.h linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/nuc900_spi.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/nuc900_spi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/nuc900_spi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/nuc900_spi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_SPI_H
+#define __ASM_ARCH_SPI_H
+
+extern void mfp_set_groupg(struct device *dev);
+
+struct nuc900_spi_info {
+	unsigned int num_cs;
+	unsigned int lsb;
+	unsigned int txneg;
+	unsigned int rxneg;
+	unsigned int divider;
+	unsigned int sleep;
+	unsigned int txnum;
+	unsigned int txbitlen;
+	int bus_num;
+};
+
+struct nuc900_spi_chip {
+	unsigned char bits_per_word;
+};
+
+#endif /* __ASM_ARCH_SPI_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,15 @@
  *
  */
 
+#include <linux/io.h>
 #include <asm/proc-fns.h>
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define	WTCR	(TMR_BA + 0x1C)
+#define	WTCLK	(1 << 10)
+#define	WTE	(1 << 7)
+#define	WTRE	(1 << 1)
 
 static void arch_idle(void)
 {
@@ -23,6 +31,11 @@ static void arch_idle(void)
 
 static void arch_reset(char mode, const char *cmd)
 {
-	cpu_reset(0);
+	if (mode == 's') {
+		/* Jump into ROM at address 0 */
+		cpu_reset(0);
+	} else {
+		__raw_writel(WTE | WTRE | WTCLK, WTCR);
+	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,11 +22,21 @@
 
 #include <mach/regs-serial.h>
 #include <mach/map.h>
+#include <linux/serial_reg.h>
 
 #define arch_decomp_wdog()
 
+#define TX_DONE	(UART_LSR_TEMT | UART_LSR_THRE)
+static volatile u32 * uart_base = (u32 *)UART0_PA;
+
 static void putc(int ch)
 {
+	/* Check THRE and TEMT bits before we transmit the character.
+	 */
+	while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+		barrier();
+
+	*uart_base = ch;
 }
 
 static inline void flush(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/time.c linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/time.c
--- linux-libre-2.6.32-gnu1/arch/arm/mach-w90x900/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mach-w90x900/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,10 @@
 #define TICKS_PER_SEC	100
 #define PRESCALE	0x63 /* Divider = prescale + 1 */
 
-unsigned int timer0_load;
+#define	TDR_SHIFT	24
+#define	TDR_MASK	((1 << TDR_SHIFT) - 1)
+
+static unsigned int timer0_load;
 
 static void nuc900_clockevent_setmode(enum clock_event_mode mode,
 		struct clock_event_device *clk)
@@ -88,7 +91,7 @@ static int nuc900_clockevent_setnexteven
 static struct clock_event_device nuc900_clockevent_device = {
 	.name		= "nuc900-timer0",
 	.shift		= 32,
-	.features	= CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.set_mode	= nuc900_clockevent_setmode,
 	.set_next_event	= nuc900_clockevent_setnextevent,
 	.rating		= 300,
@@ -112,8 +115,23 @@ static struct irqaction nuc900_timer0_ir
 	.handler	= nuc900_timer0_interrupt,
 };
 
-static void __init nuc900_clockevents_init(unsigned int rate)
+static void __init nuc900_clockevents_init(void)
 {
+	unsigned int rate;
+	struct clk *clk = clk_get(NULL, "timer0");
+
+	BUG_ON(IS_ERR(clk));
+
+	__raw_writel(0x00, REG_TCSR0);
+
+	clk_enable(clk);
+	rate = clk_get_rate(clk) / (PRESCALE + 1);
+
+	timer0_load = (rate / TICKS_PER_SEC);
+
+	__raw_writel(RESETINT, REG_TISR);
+	setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
+
 	nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC,
 					nuc900_clockevent_device.shift);
 	nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff,
@@ -127,26 +145,35 @@ static void __init nuc900_clockevents_in
 
 static cycle_t nuc900_get_cycles(struct clocksource *cs)
 {
-	return ~__raw_readl(REG_TDR1);
+	return (~__raw_readl(REG_TDR1)) & TDR_MASK;
 }
 
 static struct clocksource clocksource_nuc900 = {
 	.name	= "nuc900-timer1",
 	.rating	= 200,
 	.read	= nuc900_get_cycles,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.shift	= 20,
+	.mask	= CLOCKSOURCE_MASK(TDR_SHIFT),
+	.shift	= 10,
 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static void __init nuc900_clocksource_init(unsigned int rate)
+static void __init nuc900_clocksource_init(void)
 {
 	unsigned int val;
+	unsigned int rate;
+	struct clk *clk = clk_get(NULL, "timer1");
+
+	BUG_ON(IS_ERR(clk));
+
+	__raw_writel(0x00, REG_TCSR1);
+
+	clk_enable(clk);
+	rate = clk_get_rate(clk) / (PRESCALE + 1);
 
 	__raw_writel(0xffffffff, REG_TICR1);
 
 	val = __raw_readl(REG_TCSR1);
-	val |= (COUNTEN | PERIOD);
+	val |= (COUNTEN | PERIOD | PRESCALE);
 	__raw_writel(val, REG_TCSR1);
 
 	clocksource_nuc900.mult =
@@ -156,25 +183,8 @@ static void __init nuc900_clocksource_in
 
 static void __init nuc900_timer_init(void)
 {
-	struct clk *ck_ext = clk_get(NULL, "ext");
-	unsigned int	rate;
-
-	BUG_ON(IS_ERR(ck_ext));
-
-	rate = clk_get_rate(ck_ext);
-	clk_put(ck_ext);
-	rate = rate / (PRESCALE + 0x01);
-
-	 /* set a known state */
-	__raw_writel(0x00, REG_TCSR0);
-	__raw_writel(0x00, REG_TCSR1);
-	__raw_writel(RESETINT, REG_TISR);
-	timer0_load = (rate / TICKS_PER_SEC);
-
-	setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
-
-	nuc900_clocksource_init(rate);
-	nuc900_clockevents_init(rate);
+	nuc900_clocksource_init();
+	nuc900_clockevents_init();
 }
 
 struct sys_timer nuc900_timer = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/Makefile linux-libre-2.6.33-gnu1/arch/arm/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -94,7 +94,7 @@ CFLAGS_ABI	+=-funwind-tables
 endif
 
 ifeq ($(CONFIG_THUMB2_KERNEL),y)
-AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it)
+AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
 AFLAGS_NOWARN	:=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
 CFLAGS_THUMB2	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
 AFLAGS_THUMB2	:=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
@@ -122,6 +122,7 @@ machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_BCMRING)		:= bcmring
 machine-$(CONFIG_ARCH_CLPS711X)		:= clps711x
 machine-$(CONFIG_ARCH_DAVINCI)		:= davinci
+machine-$(CONFIG_ARCH_DOVE)		:= dove
 machine-$(CONFIG_ARCH_EBSA110)		:= ebsa110
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_GEMINI)		:= gemini
@@ -145,6 +146,7 @@ machine-$(CONFIG_ARCH_MX1)		:= mx1
 machine-$(CONFIG_ARCH_MX2)		:= mx2
 machine-$(CONFIG_ARCH_MX25)		:= mx25
 machine-$(CONFIG_ARCH_MX3)		:= mx3
+machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
@@ -166,22 +168,23 @@ machine-$(CONFIG_ARCH_SHARK)		:= shark
 machine-$(CONFIG_ARCH_STMP378X)		:= stmp378x
 machine-$(CONFIG_ARCH_STMP37XX)		:= stmp37xx
 machine-$(CONFIG_ARCH_U300)		:= u300
+machine-$(CONFIG_ARCH_U8500)		:= ux500
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_W90X900)		:= w90x900
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
-machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 plat-$(CONFIG_ARCH_MXC)		:= mxc
 plat-$(CONFIG_ARCH_OMAP)	:= omap
+plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
 plat-$(CONFIG_PLAT_IOP)		:= iop
+plat-$(CONFIG_PLAT_NOMADIK)	:= nomadik
 plat-$(CONFIG_PLAT_ORION)	:= orion
 plat-$(CONFIG_PLAT_PXA)		:= pxa
-plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx s3c
-plat-$(CONFIG_PLAT_S3C64XX)	:= s3c64xx s3c
-plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx s3c
-plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
+plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx s3c samsung
+plat-$(CONFIG_PLAT_S3C64XX)	:= s3c64xx s3c samsung
+plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx s3c samsung
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
@@ -239,15 +242,8 @@ all:	$(KBUILD_IMAGE)
 
 boot := arch/arm/boot
 
-#	Update machine arch and proc symlinks if something which affects
-#	them changed.  We use .arch to indicate when they were updated
-#	last, otherwise make uses the target directory mtime.
-
-archprepare: maketools
-
-PHONY += maketools FORCE
-maketools: include/linux/version.h FORCE
-	$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
+archprepare:
+	$(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
 
 # Convert bzImage to zImage
 bzImage: zImage
@@ -258,9 +254,6 @@ zImage Image xipImage bootpImage uImage:
 zinstall install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
 
-CLEAN_FILES += include/asm-arm/mach-types.h \
-	       include/asm-arm/arch include/asm-arm/.arch
-
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/alignment.c linux-libre-2.6.33-gnu1/arch/arm/mm/alignment.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/alignment.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/alignment.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/moduleparam.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -77,6 +78,8 @@ static unsigned long ai_dword;
 static unsigned long ai_multi;
 static int ai_usermode;
 
+core_param(alignment, ai_usermode, int, 0600);
+
 #define UM_WARN		(1 << 0)
 #define UM_FIXUP	(1 << 1)
 #define UM_SIGNAL	(1 << 2)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-fa.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-fa.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-fa.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-fa.S	2010-02-24 13:52:17.000000000 -0500
@@ -127,15 +127,16 @@ ENTRY(fa_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(kaddr)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure that the data held in the page kaddr is written back
  *	to the page in question.
  *
- *	- kaddr   - kernel address (guaranteed to be page aligned)
+ *	- addr	- kernel address
+ *	- size	- size of region
  */
-ENTRY(fa_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(fa_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -213,7 +214,7 @@ ENTRY(fa_cache_fns)
 	.long	fa_flush_user_cache_range
 	.long	fa_coherent_kern_range
 	.long	fa_coherent_user_range
-	.long	fa_flush_kern_dcache_page
+	.long	fa_flush_kern_dcache_area
 	.long	fa_dma_inv_range
 	.long	fa_dma_clean_range
 	.long	fa_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-l2x0.c linux-libre-2.6.33-gnu1/arch/arm/mm/cache-l2x0.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-l2x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-l2x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,69 +28,120 @@
 static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
 
-static inline void sync_writel(unsigned long val, unsigned long reg,
-			       unsigned long complete_mask)
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&l2x0_lock, flags);
-	writel(val, l2x0_base + reg);
 	/* wait for the operation to complete */
-	while (readl(l2x0_base + reg) & complete_mask)
+	while (readl(reg) & mask)
 		;
-	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static inline void cache_sync(void)
 {
-	sync_writel(0, L2X0_CACHE_SYNC, 1);
+	void __iomem *base = l2x0_base;
+	writel(0, base + L2X0_CACHE_SYNC);
+	cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
 static inline void l2x0_inv_all(void)
 {
+	unsigned long flags;
+
 	/* invalidate all ways */
-	sync_writel(0xff, L2X0_INV_WAY, 0xff);
+	spin_lock_irqsave(&l2x0_lock, flags);
+	writel(0xff, l2x0_base + L2X0_INV_WAY);
+	cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
 	cache_sync();
+	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_inv_range(unsigned long start, unsigned long end)
 {
-	unsigned long addr;
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
 
+	spin_lock_irqsave(&l2x0_lock, flags);
 	if (start & (CACHE_LINE_SIZE - 1)) {
 		start &= ~(CACHE_LINE_SIZE - 1);
-		sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1);
+		cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+		writel(start, base + L2X0_CLEAN_INV_LINE_PA);
 		start += CACHE_LINE_SIZE;
 	}
 
 	if (end & (CACHE_LINE_SIZE - 1)) {
 		end &= ~(CACHE_LINE_SIZE - 1);
-		sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1);
+		cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+		writel(end, base + L2X0_CLEAN_INV_LINE_PA);
 	}
 
-	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
-		sync_writel(addr, L2X0_INV_LINE_PA, 1);
+	while (start < end) {
+		unsigned long blk_end = start + min(end - start, 4096UL);
+
+		while (start < blk_end) {
+			cache_wait(base + L2X0_INV_LINE_PA, 1);
+			writel(start, base + L2X0_INV_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (blk_end < end) {
+			spin_unlock_irqrestore(&l2x0_lock, flags);
+			spin_lock_irqsave(&l2x0_lock, flags);
+		}
+	}
+	cache_wait(base + L2X0_INV_LINE_PA, 1);
 	cache_sync();
+	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_clean_range(unsigned long start, unsigned long end)
 {
-	unsigned long addr;
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
 
+	spin_lock_irqsave(&l2x0_lock, flags);
 	start &= ~(CACHE_LINE_SIZE - 1);
-	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
-		sync_writel(addr, L2X0_CLEAN_LINE_PA, 1);
+	while (start < end) {
+		unsigned long blk_end = start + min(end - start, 4096UL);
+
+		while (start < blk_end) {
+			cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+			writel(start, base + L2X0_CLEAN_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (blk_end < end) {
+			spin_unlock_irqrestore(&l2x0_lock, flags);
+			spin_lock_irqsave(&l2x0_lock, flags);
+		}
+	}
+	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
 	cache_sync();
+	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_flush_range(unsigned long start, unsigned long end)
 {
-	unsigned long addr;
+	void __iomem *base = l2x0_base;
+	unsigned long flags;
 
+	spin_lock_irqsave(&l2x0_lock, flags);
 	start &= ~(CACHE_LINE_SIZE - 1);
-	for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
-		sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1);
+	while (start < end) {
+		unsigned long blk_end = start + min(end - start, 4096UL);
+
+		while (start < blk_end) {
+			cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+			writel(start, base + L2X0_CLEAN_INV_LINE_PA);
+			start += CACHE_LINE_SIZE;
+		}
+
+		if (blk_end < end) {
+			spin_unlock_irqrestore(&l2x0_lock, flags);
+			spin_lock_irqsave(&l2x0_lock, flags);
+		}
+	}
+	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
 	cache_sync();
+	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
@@ -99,18 +150,25 @@ void __init l2x0_init(void __iomem *base
 
 	l2x0_base = base;
 
-	/* disable L2X0 */
-	writel(0, l2x0_base + L2X0_CTRL);
+	/*
+	 * Check if l2x0 controller is already enabled.
+	 * If you are booting from non-secure mode
+	 * accessing the below registers will fault.
+	 */
+	if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
 
-	aux = readl(l2x0_base + L2X0_AUX_CTRL);
-	aux &= aux_mask;
-	aux |= aux_val;
-	writel(aux, l2x0_base + L2X0_AUX_CTRL);
+		/* l2x0 controller is disabled */
 
-	l2x0_inv_all();
+		aux = readl(l2x0_base + L2X0_AUX_CTRL);
+		aux &= aux_mask;
+		aux |= aux_val;
+		writel(aux, l2x0_base + L2X0_AUX_CTRL);
 
-	/* enable L2X0 */
-	writel(1, l2x0_base + L2X0_CTRL);
+		l2x0_inv_all();
+
+		/* enable L2X0 */
+		writel(1, l2x0_base + L2X0_CTRL);
+	}
 
 	outer_cache.inv_range = l2x0_inv_range;
 	outer_cache.clean_range = l2x0_clean_range;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-tauros2.c linux-libre-2.6.33-gnu1/arch/arm/mm/cache-tauros2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-tauros2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-tauros2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,263 @@
+/*
+ * arch/arm/mm/cache-tauros2.c - Tauros2 L2 cache controller support
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * 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.
+ *
+ * References:
+ * - PJ1 CPU Core Datasheet,
+ *   Document ID MV-S104837-01, Rev 0.7, January 24 2008.
+ * - PJ4 CPU Core Datasheet,
+ *   Document ID MV-S105190-00, Rev 0.7, March 14 2008.
+ */
+
+#include <linux/init.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-tauros2.h>
+
+
+/*
+ * When Tauros2 is used on a CPU that supports the v7 hierarchical
+ * cache operations, the cache handling code in proc-v7.S takes care
+ * of everything, including handling DMA coherency.
+ *
+ * So, we only need to register outer cache operations here if we're
+ * being used on a pre-v7 CPU, and we only need to build support for
+ * outer cache operations into the kernel image if the kernel has been
+ * configured to support a pre-v7 CPU.
+ */
+#if __LINUX_ARM_ARCH__ < 7
+/*
+ * Low-level cache maintenance operations.
+ */
+static inline void tauros2_clean_pa(unsigned long addr)
+{
+	__asm__("mcr p15, 1, %0, c7, c11, 3" : : "r" (addr));
+}
+
+static inline void tauros2_clean_inv_pa(unsigned long addr)
+{
+	__asm__("mcr p15, 1, %0, c7, c15, 3" : : "r" (addr));
+}
+
+static inline void tauros2_inv_pa(unsigned long addr)
+{
+	__asm__("mcr p15, 1, %0, c7, c7, 3" : : "r" (addr));
+}
+
+
+/*
+ * Linux primitives.
+ *
+ * Note that the end addresses passed to Linux primitives are
+ * noninclusive.
+ */
+#define CACHE_LINE_SIZE		32
+
+static void tauros2_inv_range(unsigned long start, unsigned long end)
+{
+	/*
+	 * Clean and invalidate partial first cache line.
+	 */
+	if (start & (CACHE_LINE_SIZE - 1)) {
+		tauros2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
+		start = (start | (CACHE_LINE_SIZE - 1)) + 1;
+	}
+
+	/*
+	 * Clean and invalidate partial last cache line.
+	 */
+	if (end & (CACHE_LINE_SIZE - 1)) {
+		tauros2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+		end &= ~(CACHE_LINE_SIZE - 1);
+	}
+
+	/*
+	 * Invalidate all full cache lines between 'start' and 'end'.
+	 */
+	while (start < end) {
+		tauros2_inv_pa(start);
+		start += CACHE_LINE_SIZE;
+	}
+
+	dsb();
+}
+
+static void tauros2_clean_range(unsigned long start, unsigned long end)
+{
+	start &= ~(CACHE_LINE_SIZE - 1);
+	while (start < end) {
+		tauros2_clean_pa(start);
+		start += CACHE_LINE_SIZE;
+	}
+
+	dsb();
+}
+
+static void tauros2_flush_range(unsigned long start, unsigned long end)
+{
+	start &= ~(CACHE_LINE_SIZE - 1);
+	while (start < end) {
+		tauros2_clean_inv_pa(start);
+		start += CACHE_LINE_SIZE;
+	}
+
+	dsb();
+}
+#endif
+
+static inline u32 __init read_extra_features(void)
+{
+	u32 u;
+
+	__asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u));
+
+	return u;
+}
+
+static inline void __init write_extra_features(u32 u)
+{
+	__asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
+}
+
+static void __init disable_l2_prefetch(void)
+{
+	u32 u;
+
+	/*
+	 * Read the CPU Extra Features register and verify that the
+	 * Disable L2 Prefetch bit is set.
+	 */
+	u = read_extra_features();
+	if (!(u & 0x01000000)) {
+		printk(KERN_INFO "Tauros2: Disabling L2 prefetch.\n");
+		write_extra_features(u | 0x01000000);
+	}
+}
+
+static inline int __init cpuid_scheme(void)
+{
+	extern int processor_id;
+
+	return !!((processor_id & 0x000f0000) == 0x000f0000);
+}
+
+static inline u32 __init read_mmfr3(void)
+{
+	u32 mmfr3;
+
+	__asm__("mrc p15, 0, %0, c0, c1, 7\n" : "=r" (mmfr3));
+
+	return mmfr3;
+}
+
+static inline u32 __init read_actlr(void)
+{
+	u32 actlr;
+
+	__asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
+
+	return actlr;
+}
+
+static inline void __init write_actlr(u32 actlr)
+{
+	__asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
+}
+
+void __init tauros2_init(void)
+{
+	extern int processor_id;
+	char *mode;
+
+	disable_l2_prefetch();
+
+#ifdef CONFIG_CPU_32v5
+	if ((processor_id & 0xff0f0000) == 0x56050000) {
+		u32 feat;
+
+		/*
+		 * v5 CPUs with Tauros2 have the L2 cache enable bit
+		 * located in the CPU Extra Features register.
+		 */
+		feat = read_extra_features();
+		if (!(feat & 0x00400000)) {
+			printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+			write_extra_features(feat | 0x00400000);
+		}
+
+		mode = "ARMv5";
+		outer_cache.inv_range = tauros2_inv_range;
+		outer_cache.clean_range = tauros2_clean_range;
+		outer_cache.flush_range = tauros2_flush_range;
+	}
+#endif
+
+#ifdef CONFIG_CPU_32v6
+	/*
+	 * Check whether this CPU lacks support for the v7 hierarchical
+	 * cache ops.  (PJ4 is in its v6 personality mode if the MMFR3
+	 * register indicates no support for the v7 hierarchical cache
+	 * ops.)
+	 */
+	if (cpuid_scheme() && (read_mmfr3() & 0xf) == 0) {
+		/*
+		 * When Tauros2 is used in an ARMv6 system, the L2
+		 * enable bit is in the ARMv6 ARM-mandated position
+		 * (bit [26] of the System Control Register).
+		 */
+		if (!(get_cr() & 0x04000000)) {
+			printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+			adjust_cr(0x04000000, 0x04000000);
+		}
+
+		mode = "ARMv6";
+		outer_cache.inv_range = tauros2_inv_range;
+		outer_cache.clean_range = tauros2_clean_range;
+		outer_cache.flush_range = tauros2_flush_range;
+	}
+#endif
+
+#ifdef CONFIG_CPU_32v7
+	/*
+	 * Check whether this CPU has support for the v7 hierarchical
+	 * cache ops.  (PJ4 is in its v7 personality mode if the MMFR3
+	 * register indicates support for the v7 hierarchical cache
+	 * ops.)
+	 *
+	 * (Although strictly speaking there may exist CPUs that
+	 * implement the v7 cache ops but are only ARMv6 CPUs (due to
+	 * not complying with all of the other ARMv7 requirements),
+	 * there are no real-life examples of Tauros2 being used on
+	 * such CPUs as of yet.)
+	 */
+	if (cpuid_scheme() && (read_mmfr3() & 0xf) == 1) {
+		u32 actlr;
+
+		/*
+		 * When Tauros2 is used in an ARMv7 system, the L2
+		 * enable bit is located in the Auxiliary System Control
+		 * Register (which is the only register allowed by the
+		 * ARMv7 spec to contain fine-grained cache control bits).
+		 */
+		actlr = read_actlr();
+		if (!(actlr & 0x00000002)) {
+			printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+			write_actlr(actlr | 0x00000002);
+		}
+
+		mode = "ARMv7";
+	}
+#endif
+
+	if (mode == NULL) {
+		printk(KERN_CRIT "Tauros2: Unable to detect CPU mode.\n");
+		return;
+	}
+
+	printk(KERN_INFO "Tauros2: L2 cache support initialised "
+			 "in %s mode.\n", mode);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v3.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v3.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v3.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v3.S	2010-02-24 13:52:17.000000000 -0500
@@ -72,14 +72,15 @@ ENTRY(v3_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *page, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v3_flush_kern_dcache_page)
+ENTRY(v3_flush_kern_dcache_area)
 	/* FALLTHROUGH */
 
 /*
@@ -129,7 +130,7 @@ ENTRY(v3_cache_fns)
 	.long	v3_flush_user_cache_range
 	.long	v3_coherent_kern_range
 	.long	v3_coherent_user_range
-	.long	v3_flush_kern_dcache_page
+	.long	v3_flush_kern_dcache_area
 	.long	v3_dma_inv_range
 	.long	v3_dma_clean_range
 	.long	v3_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4.S	2010-02-24 13:52:17.000000000 -0500
@@ -82,14 +82,15 @@ ENTRY(v4_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v4_flush_kern_dcache_page)
+ENTRY(v4_flush_kern_dcache_area)
 	/* FALLTHROUGH */
 
 /*
@@ -141,7 +142,7 @@ ENTRY(v4_cache_fns)
 	.long	v4_flush_user_cache_range
 	.long	v4_coherent_kern_range
 	.long	v4_coherent_user_range
-	.long	v4_flush_kern_dcache_page
+	.long	v4_flush_kern_dcache_area
 	.long	v4_dma_inv_range
 	.long	v4_dma_clean_range
 	.long	v4_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4wb.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wb.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4wb.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wb.S	2010-02-24 13:52:17.000000000 -0500
@@ -114,15 +114,16 @@ ENTRY(v4wb_flush_user_cache_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v4wb_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(v4wb_flush_kern_dcache_area)
+	add	r1, r0, r1
 	/* fall through */
 
 /*
@@ -224,7 +225,7 @@ ENTRY(v4wb_cache_fns)
 	.long	v4wb_flush_user_cache_range
 	.long	v4wb_coherent_kern_range
 	.long	v4wb_coherent_user_range
-	.long	v4wb_flush_kern_dcache_page
+	.long	v4wb_flush_kern_dcache_area
 	.long	v4wb_dma_inv_range
 	.long	v4wb_dma_clean_range
 	.long	v4wb_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4wt.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wt.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v4wt.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v4wt.S	2010-02-24 13:52:17.000000000 -0500
@@ -117,17 +117,18 @@ ENTRY(v4wt_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v4wt_flush_kern_dcache_page)
+ENTRY(v4wt_flush_kern_dcache_area)
 	mov	r2, #0
 	mcr	p15, 0, r2, c7, c5, 0		@ invalidate I cache
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 	/* fallthrough */
 
 /*
@@ -180,7 +181,7 @@ ENTRY(v4wt_cache_fns)
 	.long	v4wt_flush_user_cache_range
 	.long	v4wt_coherent_kern_range
 	.long	v4wt_coherent_user_range
-	.long	v4wt_flush_kern_dcache_page
+	.long	v4wt_flush_kern_dcache_area
 	.long	v4wt_dma_inv_range
 	.long	v4wt_dma_clean_range
 	.long	v4wt_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v6.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v6.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v6.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v6.S	2010-02-24 13:52:17.000000000 -0500
@@ -159,15 +159,16 @@ ENDPROC(v6_coherent_user_range)
 ENDPROC(v6_coherent_kern_range)
 
 /*
- *	v6_flush_kern_dcache_page(kaddr)
+ *	v6_flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure that the data held in the page kaddr is written back
  *	to the page in question.
  *
- *	- kaddr   - kernel address (guaranteed to be page aligned)
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v6_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(v6_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
@@ -271,7 +272,7 @@ ENTRY(v6_cache_fns)
 	.long	v6_flush_user_cache_range
 	.long	v6_coherent_kern_range
 	.long	v6_coherent_user_range
-	.long	v6_flush_kern_dcache_page
+	.long	v6_flush_kern_dcache_area
 	.long	v6_dma_inv_range
 	.long	v6_dma_clean_range
 	.long	v6_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v7.S linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v7.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-v7.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-v7.S	2010-02-24 13:52:17.000000000 -0500
@@ -186,16 +186,17 @@ ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
 
 /*
- *	v7_flush_kern_dcache_page(kaddr)
+ *	v7_flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure that the data held in the page kaddr is written back
  *	to the page in question.
  *
- *	- kaddr   - kernel address (guaranteed to be page aligned)
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(v7_flush_kern_dcache_page)
+ENTRY(v7_flush_kern_dcache_area)
 	dcache_line_size r2, r3
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 1:
 	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line / unified line
 	add	r0, r0, r2
@@ -203,7 +204,7 @@ ENTRY(v7_flush_kern_dcache_page)
 	blo	1b
 	dsb
 	mov	pc, lr
-ENDPROC(v7_flush_kern_dcache_page)
+ENDPROC(v7_flush_kern_dcache_area)
 
 /*
  *	v7_dma_inv_range(start,end)
@@ -279,7 +280,7 @@ ENTRY(v7_cache_fns)
 	.long	v7_flush_user_cache_range
 	.long	v7_coherent_kern_range
 	.long	v7_coherent_user_range
-	.long	v7_flush_kern_dcache_page
+	.long	v7_flush_kern_dcache_area
 	.long	v7_dma_inv_range
 	.long	v7_dma_clean_range
 	.long	v7_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/cache-xsc3l2.c linux-libre-2.6.33-gnu1/arch/arm/mm/cache-xsc3l2.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/cache-xsc3l2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/cache-xsc3l2.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,15 +221,14 @@ static int __init xsc3_l2_init(void)
 	if (!cpu_is_xsc3() || !xsc3_l2_present())
 		return 0;
 
-	if (!(get_cr() & CR_L2)) {
+	if (get_cr() & CR_L2) {
 		pr_info("XScale3 L2 cache enabled.\n");
-		adjust_cr(CR_L2, CR_L2);
 		xsc3_l2_inv_all();
-	}
 
-	outer_cache.inv_range = xsc3_l2_inv_range;
-	outer_cache.clean_range = xsc3_l2_clean_range;
-	outer_cache.flush_range = xsc3_l2_flush_range;
+		outer_cache.inv_range = xsc3_l2_inv_range;
+		outer_cache.clean_range = xsc3_l2_clean_range;
+		outer_cache.flush_range = xsc3_l2_flush_range;
+	}
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/copypage-v6.c linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v6.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/copypage-v6.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/copypage-v6.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,14 @@ static void v6_copy_user_highpage_nonali
 	kfrom = kmap_atomic(from, KM_USER0);
 	kto = kmap_atomic(to, KM_USER1);
 	copy_page(kto, kfrom);
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * kmap_atomic() doesn't set the page virtual address, and
+	 * kunmap_atomic() takes care of cache flushing already.
+	 */
+	if (page_address(to) != NULL)
+#endif
+		__cpuc_flush_dcache_area(kto, PAGE_SIZE);
 	kunmap_atomic(kto, KM_USER1);
 	kunmap_atomic(kfrom, KM_USER0);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/dma-mapping.c linux-libre-2.6.33-gnu1/arch/arm/mm/dma-mapping.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/dma-mapping.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/dma-mapping.c	2010-02-24 13:52:17.000000000 -0500
@@ -63,194 +63,152 @@ static u64 get_coherent_dma_mask(struct
 	return mask;
 }
 
-#ifdef CONFIG_MMU
-/*
- * These are the page tables (2MB each) covering uncached, DMA consistent allocations
- */
-static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
-static DEFINE_SPINLOCK(consistent_lock);
-
 /*
- * VM region handling support.
- *
- * This should become something generic, handling VM region allocations for
- * vmalloc and similar (ioremap, module space, etc).
- *
- * I envisage vmalloc()'s supporting vm_struct becoming:
- *
- *  struct vm_struct {
- *    struct vm_region	region;
- *    unsigned long	flags;
- *    struct page	**pages;
- *    unsigned int	nr_pages;
- *    unsigned long	phys_addr;
- *  };
- *
- * get_vm_area() would then call vm_region_alloc with an appropriate
- * struct vm_region head (eg):
- *
- *  struct vm_region vmalloc_head = {
- *	.vm_list	= LIST_HEAD_INIT(vmalloc_head.vm_list),
- *	.vm_start	= VMALLOC_START,
- *	.vm_end		= VMALLOC_END,
- *  };
- *
- * However, vmalloc_head.vm_start is variable (typically, it is dependent on
- * the amount of RAM found at boot time.)  I would imagine that get_vm_area()
- * would have to initialise this each time prior to calling vm_region_alloc().
+ * Allocate a DMA buffer for 'dev' of size 'size' using the
+ * specified gfp mask.  Note that 'size' must be page aligned.
  */
-struct arm_vm_region {
-	struct list_head	vm_list;
-	unsigned long		vm_start;
-	unsigned long		vm_end;
-	struct page		*vm_pages;
-	int			vm_active;
-};
-
-static struct arm_vm_region consistent_head = {
-	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
-	.vm_start	= CONSISTENT_BASE,
-	.vm_end		= CONSISTENT_END,
-};
-
-static struct arm_vm_region *
-arm_vm_region_alloc(struct arm_vm_region *head, size_t size, gfp_t gfp)
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
 {
-	unsigned long addr = head->vm_start, end = head->vm_end - size;
-	unsigned long flags;
-	struct arm_vm_region *c, *new;
+	unsigned long order = get_order(size);
+	struct page *page, *p, *e;
+	void *ptr;
+	u64 mask = get_coherent_dma_mask(dev);
 
-	new = kmalloc(sizeof(struct arm_vm_region), gfp);
-	if (!new)
-		goto out;
+#ifdef CONFIG_DMA_API_DEBUG
+	u64 limit = (mask + 1) & ~mask;
+	if (limit && size >= limit) {
+		dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
+			size, mask);
+		return NULL;
+	}
+#endif
 
-	spin_lock_irqsave(&consistent_lock, flags);
+	if (!mask)
+		return NULL;
 
-	list_for_each_entry(c, &head->vm_list, vm_list) {
-		if ((addr + size) < addr)
-			goto nospc;
-		if ((addr + size) <= c->vm_start)
-			goto found;
-		addr = c->vm_end;
-		if (addr > end)
-			goto nospc;
-	}
+	if (mask < 0xffffffffULL)
+		gfp |= GFP_DMA;
+
+	page = alloc_pages(gfp, order);
+	if (!page)
+		return NULL;
 
- found:
 	/*
-	 * Insert this entry _before_ the one we found.
+	 * Now split the huge page and free the excess pages
 	 */
-	list_add_tail(&new->vm_list, &c->vm_list);
-	new->vm_start = addr;
-	new->vm_end = addr + size;
-	new->vm_active = 1;
+	split_page(page, order);
+	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
+		__free_page(p);
 
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	return new;
+	/*
+	 * Ensure that the allocated pages are zeroed, and that any data
+	 * lurking in the kernel direct-mapped region is invalidated.
+	 */
+	ptr = page_address(page);
+	memset(ptr, 0, size);
+	dmac_flush_range(ptr, ptr + size);
+	outer_flush_range(__pa(ptr), __pa(ptr) + size);
 
- nospc:
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	kfree(new);
- out:
-	return NULL;
+	return page;
 }
 
-static struct arm_vm_region *arm_vm_region_find(struct arm_vm_region *head, unsigned long addr)
+/*
+ * Free a DMA buffer.  'size' must be page aligned.
+ */
+static void __dma_free_buffer(struct page *page, size_t size)
 {
-	struct arm_vm_region *c;
-	
-	list_for_each_entry(c, &head->vm_list, vm_list) {
-		if (c->vm_active && c->vm_start == addr)
-			goto out;
+	struct page *e = page + (size >> PAGE_SHIFT);
+
+	while (page < e) {
+		__free_page(page);
+		page++;
 	}
-	c = NULL;
- out:
-	return c;
 }
 
+#ifdef CONFIG_MMU
+/*
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+ */
+static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
+
+#include "vmregion.h"
+
+static struct arm_vmregion_head consistent_head = {
+	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
+	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
+	.vm_start	= CONSISTENT_BASE,
+	.vm_end		= CONSISTENT_END,
+};
+
 #ifdef CONFIG_HUGETLB_PAGE
 #error ARM Coherent DMA allocator does not (yet) support huge TLB
 #endif
 
-static void *
-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
-	    pgprot_t prot)
+/*
+ * Initialise the consistent memory allocation.
+ */
+static int __init consistent_init(void)
 {
-	struct page *page;
-	struct arm_vm_region *c;
-	unsigned long order;
-	u64 mask = get_coherent_dma_mask(dev);
-	u64 limit;
+	int ret = 0;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i = 0;
+	u32 base = CONSISTENT_BASE;
 
-	if (!consistent_pte[0]) {
-		printk(KERN_ERR "%s: not initialised\n", __func__);
-		dump_stack();
-		return NULL;
-	}
+	do {
+		pgd = pgd_offset(&init_mm, base);
+		pmd = pmd_alloc(&init_mm, pgd, base);
+		if (!pmd) {
+			printk(KERN_ERR "%s: no pmd tables\n", __func__);
+			ret = -ENOMEM;
+			break;
+		}
+		WARN_ON(!pmd_none(*pmd));
 
-	if (!mask)
-		goto no_page;
+		pte = pte_alloc_kernel(pmd, base);
+		if (!pte) {
+			printk(KERN_ERR "%s: no pte tables\n", __func__);
+			ret = -ENOMEM;
+			break;
+		}
 
-	/*
-	 * Sanity check the allocation size.
-	 */
-	size = PAGE_ALIGN(size);
-	limit = (mask + 1) & ~mask;
-	if ((limit && size >= limit) ||
-	    size >= (CONSISTENT_END - CONSISTENT_BASE)) {
-		printk(KERN_WARNING "coherent allocation too big "
-		       "(requested %#x mask %#llx)\n", size, mask);
-		goto no_page;
-	}
+		consistent_pte[i++] = pte;
+		base += (1 << PGDIR_SHIFT);
+	} while (base < CONSISTENT_END);
 
-	order = get_order(size);
+	return ret;
+}
 
-	if (mask < 0xffffffffULL)
-		gfp |= GFP_DMA;
+core_initcall(consistent_init);
 
-	page = alloc_pages(gfp, order);
-	if (!page)
-		goto no_page;
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
+{
+	struct arm_vmregion *c;
 
-	/*
-	 * Invalidate any data that might be lurking in the
-	 * kernel direct-mapped region for device DMA.
-	 */
-	{
-		void *ptr = page_address(page);
-		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+	if (!consistent_pte[0]) {
+		printk(KERN_ERR "%s: not initialised\n", __func__);
+		dump_stack();
+		return NULL;
 	}
 
 	/*
 	 * Allocate a virtual address in the consistent mapping region.
 	 */
-	c = arm_vm_region_alloc(&consistent_head, size,
+	c = arm_vmregion_alloc(&consistent_head, size,
 			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
 	if (c) {
 		pte_t *pte;
-		struct page *end = page + (1 << order);
 		int idx = CONSISTENT_PTE_INDEX(c->vm_start);
 		u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
 
 		pte = consistent_pte[idx] + off;
 		c->vm_pages = page;
 
-		split_page(page, order);
-
-		/*
-		 * Set the "dma handle"
-		 */
-		*handle = page_to_dma(dev, page);
-
 		do {
 			BUG_ON(!pte_none(*pte));
 
-			/*
-			 * x86 does not mark the pages reserved...
-			 */
-			SetPageReserved(page);
 			set_pte_ext(pte, mk_pte(page, prot), 0);
 			page++;
 			pte++;
@@ -261,48 +219,90 @@ __dma_alloc(struct device *dev, size_t s
 			}
 		} while (size -= PAGE_SIZE);
 
-		/*
-		 * Free the otherwise unused pages.
-		 */
-		while (page < end) {
-			__free_page(page);
-			page++;
-		}
-
 		return (void *)c->vm_start;
 	}
-
-	if (page)
-		__free_pages(page, order);
- no_page:
-	*handle = ~0;
 	return NULL;
 }
+
+static void __dma_free_remap(void *cpu_addr, size_t size)
+{
+	struct arm_vmregion *c;
+	unsigned long addr;
+	pte_t *ptep;
+	int idx;
+	u32 off;
+
+	c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
+	if (!c) {
+		printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+		       __func__, cpu_addr);
+		dump_stack();
+		return;
+	}
+
+	if ((c->vm_end - c->vm_start) != size) {
+		printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+		       __func__, c->vm_end - c->vm_start, size);
+		dump_stack();
+		size = c->vm_end - c->vm_start;
+	}
+
+	idx = CONSISTENT_PTE_INDEX(c->vm_start);
+	off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+	ptep = consistent_pte[idx] + off;
+	addr = c->vm_start;
+	do {
+		pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
+
+		ptep++;
+		addr += PAGE_SIZE;
+		off++;
+		if (off >= PTRS_PER_PTE) {
+			off = 0;
+			ptep = consistent_pte[++idx];
+		}
+
+		if (pte_none(pte) || !pte_present(pte))
+			printk(KERN_CRIT "%s: bad page in kernel page table\n",
+			       __func__);
+	} while (size -= PAGE_SIZE);
+
+	flush_tlb_kernel_range(c->vm_start, c->vm_end);
+
+	arm_vmregion_free(&consistent_head, c);
+}
+
 #else	/* !CONFIG_MMU */
+
+#define __dma_alloc_remap(page, size, gfp, prot)	page_address(page)
+#define __dma_free_remap(addr, size)			do { } while (0)
+
+#endif	/* CONFIG_MMU */
+
 static void *
 __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 	    pgprot_t prot)
 {
-	void *virt;
-	u64 mask = get_coherent_dma_mask(dev);
+	struct page *page;
+	void *addr;
 
-	if (!mask)
-		goto error;
+	*handle = ~0;
+	size = PAGE_ALIGN(size);
 
-	if (mask < 0xffffffffULL)
-		gfp |= GFP_DMA;
-	virt = kmalloc(size, gfp);
-	if (!virt)
-		goto error;
+	page = __dma_alloc_buffer(dev, size, gfp);
+	if (!page)
+		return NULL;
 
-	*handle =  virt_to_dma(dev, virt);
-	return virt;
+	if (!arch_is_coherent())
+		addr = __dma_alloc_remap(page, size, gfp, prot);
+	else
+		addr = page_address(page);
 
-error:
-	*handle = ~0;
-	return NULL;
+	if (addr)
+		*handle = page_to_dma(dev, page);
+
+	return addr;
 }
-#endif	/* CONFIG_MMU */
 
 /*
  * Allocate DMA-coherent memory space and return both the kernel remapped
@@ -316,19 +316,8 @@ dma_alloc_coherent(struct device *dev, s
 	if (dma_alloc_from_coherent(dev, size, handle, &memory))
 		return memory;
 
-	if (arch_is_coherent()) {
-		void *virt;
-
-		virt = kmalloc(size, gfp);
-		if (!virt)
-			return NULL;
-		*handle =  virt_to_dma(dev, virt);
-
-		return virt;
-	}
-
 	return __dma_alloc(dev, size, handle, gfp,
-			   pgprot_noncached(pgprot_kernel));
+			   pgprot_dmacoherent(pgprot_kernel));
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
 
@@ -349,15 +338,12 @@ static int dma_mmap(struct device *dev,
 {
 	int ret = -ENXIO;
 #ifdef CONFIG_MMU
-	unsigned long flags, user_size, kern_size;
-	struct arm_vm_region *c;
+	unsigned long user_size, kern_size;
+	struct arm_vmregion *c;
 
 	user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
-	spin_lock_irqsave(&consistent_lock, flags);
-	c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr);
-	spin_unlock_irqrestore(&consistent_lock, flags);
-
+	c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
 	if (c) {
 		unsigned long off = vma->vm_pgoff;
 
@@ -379,7 +365,7 @@ static int dma_mmap(struct device *dev,
 int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 		      void *cpu_addr, dma_addr_t dma_addr, size_t size)
 {
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
 	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 EXPORT_SYMBOL(dma_mmap_coherent);
@@ -396,144 +382,23 @@ EXPORT_SYMBOL(dma_mmap_writecombine);
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
-#ifdef CONFIG_MMU
 void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
 {
-	struct arm_vm_region *c;
-	unsigned long flags, addr;
-	pte_t *ptep;
-	int idx;
-	u32 off;
-
 	WARN_ON(irqs_disabled());
 
 	if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
 		return;
 
-	if (arch_is_coherent()) {
-		kfree(cpu_addr);
-		return;
-	}
-
 	size = PAGE_ALIGN(size);
 
-	spin_lock_irqsave(&consistent_lock, flags);
-	c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr);
-	if (!c)
-		goto no_area;
-
-	c->vm_active = 0;
-	spin_unlock_irqrestore(&consistent_lock, flags);
-
-	if ((c->vm_end - c->vm_start) != size) {
-		printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
-		       __func__, c->vm_end - c->vm_start, size);
-		dump_stack();
-		size = c->vm_end - c->vm_start;
-	}
-
-	idx = CONSISTENT_PTE_INDEX(c->vm_start);
-	off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-	ptep = consistent_pte[idx] + off;
-	addr = c->vm_start;
-	do {
-		pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
-		unsigned long pfn;
-
-		ptep++;
-		addr += PAGE_SIZE;
-		off++;
-		if (off >= PTRS_PER_PTE) {
-			off = 0;
-			ptep = consistent_pte[++idx];
-		}
-
-		if (!pte_none(pte) && pte_present(pte)) {
-			pfn = pte_pfn(pte);
-
-			if (pfn_valid(pfn)) {
-				struct page *page = pfn_to_page(pfn);
-
-				/*
-				 * x86 does not mark the pages reserved...
-				 */
-				ClearPageReserved(page);
-
-				__free_page(page);
-				continue;
-			}
-		}
-
-		printk(KERN_CRIT "%s: bad page in kernel page table\n",
-		       __func__);
-	} while (size -= PAGE_SIZE);
-
-	flush_tlb_kernel_range(c->vm_start, c->vm_end);
-
-	spin_lock_irqsave(&consistent_lock, flags);
-	list_del(&c->vm_list);
-	spin_unlock_irqrestore(&consistent_lock, flags);
-
-	kfree(c);
-	return;
+	if (!arch_is_coherent())
+		__dma_free_remap(cpu_addr, size);
 
- no_area:
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
-	       __func__, cpu_addr);
-	dump_stack();
-}
-#else	/* !CONFIG_MMU */
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
-{
-	if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
-		return;
-	kfree(cpu_addr);
+	__dma_free_buffer(dma_to_page(dev, handle), size);
 }
-#endif	/* CONFIG_MMU */
 EXPORT_SYMBOL(dma_free_coherent);
 
 /*
- * Initialise the consistent memory allocation.
- */
-static int __init consistent_init(void)
-{
-	int ret = 0;
-#ifdef CONFIG_MMU
-	pgd_t *pgd;
-	pmd_t *pmd;
-	pte_t *pte;
-	int i = 0;
-	u32 base = CONSISTENT_BASE;
-
-	do {
-		pgd = pgd_offset(&init_mm, base);
-		pmd = pmd_alloc(&init_mm, pgd, base);
-		if (!pmd) {
-			printk(KERN_ERR "%s: no pmd tables\n", __func__);
-			ret = -ENOMEM;
-			break;
-		}
-		WARN_ON(!pmd_none(*pmd));
-
-		pte = pte_alloc_kernel(pmd, base);
-		if (!pte) {
-			printk(KERN_ERR "%s: no pte tables\n", __func__);
-			ret = -ENOMEM;
-			break;
-		}
-
-		consistent_pte[i++] = pte;
-		base += (1 << PGDIR_SHIFT);
-	} while (base < CONSISTENT_END);
-#endif	/* !CONFIG_MMU */
-
-	return ret;
-}
-
-core_initcall(consistent_init);
-
-/*
  * Make an area consistent for devices.
  * Note: Drivers should NOT use this function directly, as it will break
  * platforms with CONFIG_DMABOUNCE.
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/fault-armv.c linux-libre-2.6.33-gnu1/arch/arm/mm/fault-armv.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/fault-armv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/fault-armv.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,8 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
+#include "mm.h"
+
 static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
 
 /*
@@ -151,7 +153,14 @@ void update_mmu_cache(struct vm_area_str
 	if (!pfn_valid(pfn))
 		return;
 
+	/*
+	 * The zero page is never written to, so never has any dirty
+	 * cache lines, and therefore never needs to be flushed.
+	 */
 	page = pfn_to_page(pfn);
+	if (page == ZERO_PAGE(0))
+		return;
+
 	mapping = page_mapping(page);
 #ifndef CONFIG_SMP
 	if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
@@ -198,9 +207,8 @@ void __init check_writebuffer_bugs(void)
 	page = alloc_page(GFP_KERNEL);
 	if (page) {
 		unsigned long *p1, *p2;
-		pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG|
-					 L_PTE_DIRTY|L_PTE_WRITE|
-					 L_PTE_MT_BUFFERABLE);
+		pgprot_t prot = __pgprot_modify(PAGE_KERNEL,
+					L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE);
 
 		p1 = vmap(&page, 1, VM_IOREMAP, prot);
 		p2 = vmap(&page, 1, VM_IOREMAP, prot);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/flush.c linux-libre-2.6.33-gnu1/arch/arm/mm/flush.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/flush.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/flush.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,14 +35,12 @@ static void flush_pfn_alias(unsigned lon
 	    :
 	    : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
 	    : "cc");
-	__flush_icache_all();
 }
 
 void flush_cache_mm(struct mm_struct *mm)
 {
 	if (cache_is_vivt()) {
-		if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
-			__cpuc_flush_user_all();
+		vivt_flush_cache_mm(mm);
 		return;
 	}
 
@@ -52,16 +50,13 @@ void flush_cache_mm(struct mm_struct *mm
 		    :
 		    : "r" (0)
 		    : "cc");
-		__flush_icache_all();
 	}
 }
 
 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
 	if (cache_is_vivt()) {
-		if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
-			__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
-						vma->vm_flags);
+		vivt_flush_cache_range(vma, start, end);
 		return;
 	}
 
@@ -71,22 +66,26 @@ void flush_cache_range(struct vm_area_st
 		    :
 		    : "r" (0)
 		    : "cc");
-		__flush_icache_all();
 	}
+
+	if (vma->vm_flags & VM_EXEC)
+		__flush_icache_all();
 }
 
 void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
 {
 	if (cache_is_vivt()) {
-		if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-			unsigned long addr = user_addr & PAGE_MASK;
-			__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
-		}
+		vivt_flush_cache_page(vma, user_addr, pfn);
 		return;
 	}
 
-	if (cache_is_vipt_aliasing())
+	if (cache_is_vipt_aliasing()) {
 		flush_pfn_alias(pfn, user_addr);
+		__flush_icache_all();
+	}
+
+	if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
+		__flush_icache_all();
 }
 
 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
@@ -94,15 +93,13 @@ void flush_ptrace_access(struct vm_area_
 			 unsigned long len, int write)
 {
 	if (cache_is_vivt()) {
-		if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-			unsigned long addr = (unsigned long)kaddr;
-			__cpuc_coherent_kern_range(addr, addr + len);
-		}
+		vivt_flush_ptrace_access(vma, page, uaddr, kaddr, len, write);
 		return;
 	}
 
 	if (cache_is_vipt_aliasing()) {
 		flush_pfn_alias(page_to_pfn(page), uaddr);
+		__flush_icache_all();
 		return;
 	}
 
@@ -120,6 +117,8 @@ void flush_ptrace_access(struct vm_area_
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
+	void *addr = page_address(page);
+
 	/*
 	 * Writeback any data associated with the kernel mapping of this
 	 * page.  This ensures that data in the physical page is mutually
@@ -130,9 +129,9 @@ void __flush_dcache_page(struct address_
 	 * kmap_atomic() doesn't set the page virtual address, and
 	 * kunmap_atomic() takes care of cache flushing already.
 	 */
-	if (page_address(page))
+	if (addr)
 #endif
-		__cpuc_flush_dcache_page(page_address(page));
+		__cpuc_flush_dcache_area(addr, PAGE_SIZE);
 
 	/*
 	 * If this is a page cache page, and we have an aliasing VIPT cache,
@@ -196,7 +195,16 @@ static void __flush_dcache_aliases(struc
  */
 void flush_dcache_page(struct page *page)
 {
-	struct address_space *mapping = page_mapping(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);
 
 #ifndef CONFIG_SMP
 	if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
@@ -242,6 +250,7 @@ void __flush_anon_page(struct vm_area_st
 		 * userspace address only.
 		 */
 		flush_pfn_alias(pfn, vmaddr);
+		__flush_icache_all();
 	}
 
 	/*
@@ -249,5 +258,5 @@ void __flush_anon_page(struct vm_area_st
 	 * in this mapping of the page.  FIXME: this is overkill
 	 * since we actually ask for a write-back and invalidate.
 	 */
-	__cpuc_flush_dcache_page(page_address(page));
+	__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/highmem.c linux-libre-2.6.33-gnu1/arch/arm/mm/highmem.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/highmem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/highmem.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ void kunmap_atomic(void *kvaddr, enum km
 	unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
 	if (kvaddr >= (void *)FIXADDR_START) {
-		__cpuc_flush_dcache_page((void *)vaddr);
+		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
 		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/init.c linux-libre-2.6.33-gnu1/arch/arm/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -616,7 +616,7 @@ void __init mem_init(void)
 		"%dK data, %dK init, %luK highmem)\n",
 		nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10,
 		datasize >> 10, initsize >> 10,
-		(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+		totalhigh_pages << (PAGE_SHIFT-10));
 
 	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
 		extern int sysctl_overcommit_memory;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/Kconfig linux-libre-2.6.33-gnu1/arch/arm/mm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/mm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,5 @@
 comment "Processor Type"
 
-config CPU_32
-	bool
-	default y
-
 # Select CPU types depending on the architecture selected.  This selects
 # which CPUs we support in the kernel image, and the compiler instruction
 # optimiser behaviour.
@@ -388,7 +384,7 @@ config CPU_FEROCEON_OLD_ID
 
 # ARMv6
 config CPU_V6
-	bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+	bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_PABRT_V6
@@ -764,6 +760,15 @@ config CACHE_L2X0
 	help
 	  This option enables the L2x0 PrimeCell.
 
+config CACHE_TAUROS2
+	bool "Enable the Tauros2 L2 cache controller"
+	depends on ARCH_DOVE
+	default y
+	select OUTER_CACHE
+	help
+	  This option enables the Tauros2 L2 cache controller (as
+	  found on PJ1/PJ4).
+
 config CACHE_XSC3L2
 	bool "Enable the L2 cache on XScale3"
 	depends on CPU_XSC3
@@ -774,5 +779,5 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
 	int
-	default 6 if ARCH_OMAP3
+	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
 	default 5
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/Makefile linux-libre-2.6.33-gnu1/arch/arm/mm/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/mm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@ obj-y				:= dma-mapping.o extable.o faul
 				   iomap.o
 
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o ioremap.o mmap.o \
-				   pgd.o mmu.o
+				   pgd.o mmu.o vmregion.o
 
 ifneq ($(CONFIG_MMU),y)
 obj-y				+= nommu.o
@@ -27,6 +27,9 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ)	+= abort-ev
 obj-$(CONFIG_CPU_ABRT_EV6)	+= abort-ev6.o
 obj-$(CONFIG_CPU_ABRT_EV7)	+= abort-ev7.o
 
+AFLAGS_abort-ev6.o	:=-Wa,-march=armv6k
+AFLAGS_abort-ev7.o	:=-Wa,-march=armv7-a
+
 obj-$(CONFIG_CPU_PABRT_LEGACY)	+= pabort-legacy.o
 obj-$(CONFIG_CPU_PABRT_V6)	+= pabort-v6.o
 obj-$(CONFIG_CPU_PABRT_V7)	+= pabort-v7.o
@@ -39,6 +42,9 @@ obj-$(CONFIG_CPU_CACHE_V6)	+= cache-v6.o
 obj-$(CONFIG_CPU_CACHE_V7)	+= cache-v7.o
 obj-$(CONFIG_CPU_CACHE_FA)	+= cache-fa.o
 
+AFLAGS_cache-v6.o	:=-Wa,-march=armv6
+AFLAGS_cache-v7.o	:=-Wa,-march=armv7-a
+
 obj-$(CONFIG_CPU_COPY_V3)	+= copypage-v3.o
 obj-$(CONFIG_CPU_COPY_V4WT)	+= copypage-v4wt.o
 obj-$(CONFIG_CPU_COPY_V4WB)	+= copypage-v4wb.o
@@ -58,6 +64,9 @@ obj-$(CONFIG_CPU_TLB_V6)	+= tlb-v6.o
 obj-$(CONFIG_CPU_TLB_V7)	+= tlb-v7.o
 obj-$(CONFIG_CPU_TLB_FA)	+= tlb-fa.o
 
+AFLAGS_tlb-v6.o		:=-Wa,-march=armv6
+AFLAGS_tlb-v7.o		:=-Wa,-march=armv7-a
+
 obj-$(CONFIG_CPU_ARM610)	+= proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM710)	+= proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM7TDMI)	+= proc-arm7tdmi.o
@@ -84,7 +93,10 @@ obj-$(CONFIG_CPU_FEROCEON)	+= proc-feroc
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
 obj-$(CONFIG_CPU_V7)		+= proc-v7.o
 
+AFLAGS_proc-v6.o	:=-Wa,-march=armv6
+AFLAGS_proc-v7.o	:=-Wa,-march=armv7-a
+
 obj-$(CONFIG_CACHE_FEROCEON_L2)	+= cache-feroceon-l2.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_CACHE_XSC3L2)	+= cache-xsc3l2.o
-
+obj-$(CONFIG_CACHE_TAUROS2)	+= cache-tauros2.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/mmap.c linux-libre-2.6.33-gnu1/arch/arm/mm/mmap.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/mmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/mmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,8 @@ arch_get_unmapped_area(struct file *filp
 	 * We enforce the MAP_FIXED case.
 	 */
 	if (flags & MAP_FIXED) {
-		if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
+		if (aliasing && flags & MAP_SHARED &&
+		    (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
 			return -EINVAL;
 		return addr;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/mm.h linux-libre-2.6.33-gnu1/arch/arm/mm/mm.h
--- linux-libre-2.6.32-gnu1/arch/arm/mm/mm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/mm.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,8 @@ struct mem_type {
 
 const struct mem_type *get_mem_type(unsigned int type);
 
+extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
 #endif
 
 struct map_desc;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/mmu.c linux-libre-2.6.33-gnu1/arch/arm/mm/mmu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -453,8 +453,7 @@ static void __init build_mem_type_table(
 
 	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
 	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
-				 L_PTE_DIRTY | L_PTE_WRITE |
-				 L_PTE_EXEC | kern_pgprot);
+				 L_PTE_DIRTY | L_PTE_WRITE | kern_pgprot);
 
 	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
 	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
@@ -881,7 +880,7 @@ void __init reserve_node_zero(pg_data_t
 				BOOTMEM_EXCLUSIVE);
 	}
 
-	if (machine_is_treo680()) {
+	if (machine_is_treo680() || machine_is_centro()) {
 		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
 				BOOTMEM_EXCLUSIVE);
 		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
@@ -1036,7 +1035,7 @@ void __init paging_init(struct machine_d
 	 */
 	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
 	empty_zero_page = virt_to_page(zero_page);
-	flush_dcache_page(empty_zero_page);
+	__flush_dcache_page(NULL, empty_zero_page);
 }
 
 /*
@@ -1068,4 +1067,6 @@ void setup_mm_for_reboot(char mode)
 		pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
 		flush_pmd_entry(pmd);
 	}
+
+	local_flush_tlb_all();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/nommu.c linux-libre-2.6.33-gnu1/arch/arm/mm/nommu.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/nommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/nommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ void setup_mm_for_reboot(char mode)
 
 void flush_dcache_page(struct page *page)
 {
-	__cpuc_flush_dcache_page(page_address(page));
+	__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1020e.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020e.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1020e.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020e.S	2010-02-24 13:52:17.000000000 -0500
@@ -225,17 +225,18 @@ ENTRY(arm1020e_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- page	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm1020e_flush_kern_dcache_page)
+ENTRY(arm1020e_flush_kern_dcache_area)
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -321,7 +322,7 @@ ENTRY(arm1020e_cache_fns)
 	.long	arm1020e_flush_user_cache_range
 	.long	arm1020e_coherent_kern_range
 	.long	arm1020e_coherent_user_range
-	.long	arm1020e_flush_kern_dcache_page
+	.long	arm1020e_flush_kern_dcache_area
 	.long	arm1020e_dma_inv_range
 	.long	arm1020e_dma_clean_range
 	.long	arm1020e_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1020.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1020.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1020.S	2010-02-24 13:52:17.000000000 -0500
@@ -231,17 +231,18 @@ ENTRY(arm1020_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- page	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm1020_flush_kern_dcache_page)
+ENTRY(arm1020_flush_kern_dcache_area)
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
 	add	r0, r0, #CACHE_DLINESIZE
@@ -335,7 +336,7 @@ ENTRY(arm1020_cache_fns)
 	.long	arm1020_flush_user_cache_range
 	.long	arm1020_coherent_kern_range
 	.long	arm1020_coherent_user_range
-	.long	arm1020_flush_kern_dcache_page
+	.long	arm1020_flush_kern_dcache_area
 	.long	arm1020_dma_inv_range
 	.long	arm1020_dma_clean_range
 	.long	arm1020_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1022.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1022.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1022.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1022.S	2010-02-24 13:52:17.000000000 -0500
@@ -214,17 +214,18 @@ ENTRY(arm1022_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- page	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm1022_flush_kern_dcache_page)
+ENTRY(arm1022_flush_kern_dcache_area)
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -310,7 +311,7 @@ ENTRY(arm1022_cache_fns)
 	.long	arm1022_flush_user_cache_range
 	.long	arm1022_coherent_kern_range
 	.long	arm1022_coherent_user_range
-	.long	arm1022_flush_kern_dcache_page
+	.long	arm1022_flush_kern_dcache_area
 	.long	arm1022_dma_inv_range
 	.long	arm1022_dma_clean_range
 	.long	arm1022_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1026.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1026.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm1026.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm1026.S	2010-02-24 13:52:17.000000000 -0500
@@ -208,17 +208,18 @@ ENTRY(arm1026_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- page	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm1026_flush_kern_dcache_page)
+ENTRY(arm1026_flush_kern_dcache_area)
 	mov	ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
-	add	r1, r0, #PAGE_SZ
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -304,7 +305,7 @@ ENTRY(arm1026_cache_fns)
 	.long	arm1026_flush_user_cache_range
 	.long	arm1026_coherent_kern_range
 	.long	arm1026_coherent_user_range
-	.long	arm1026_flush_kern_dcache_page
+	.long	arm1026_flush_kern_dcache_area
 	.long	arm1026_dma_inv_range
 	.long	arm1026_dma_clean_range
 	.long	arm1026_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm6_7.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm6_7.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm6_7.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm6_7.S	2010-02-24 13:52:17.000000000 -0500
@@ -41,7 +41,7 @@ ENTRY(cpu_arm7_dcache_clean_area)
 ENTRY(cpu_arm7_data_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-	ldr	r8, [r0]			@ read arm instruction
+	ldr	r8, [r2]			@ read arm instruction
 	tst	r8, #1 << 20			@ L = 0 -> write?
 	orreq	r1, r1, #1 << 11		@ yes.
 	and	r7, r8, #15 << 24
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm920.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm920.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm920.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm920.S	2010-02-24 13:52:17.000000000 -0500
@@ -207,15 +207,16 @@ ENTRY(arm920_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm920_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(arm920_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -293,7 +294,7 @@ ENTRY(arm920_cache_fns)
 	.long	arm920_flush_user_cache_range
 	.long	arm920_coherent_kern_range
 	.long	arm920_coherent_user_range
-	.long	arm920_flush_kern_dcache_page
+	.long	arm920_flush_kern_dcache_area
 	.long	arm920_dma_inv_range
 	.long	arm920_dma_clean_range
 	.long	arm920_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm922.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm922.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm922.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm922.S	2010-02-24 13:52:17.000000000 -0500
@@ -209,15 +209,16 @@ ENTRY(arm922_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm922_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(arm922_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -295,7 +296,7 @@ ENTRY(arm922_cache_fns)
 	.long	arm922_flush_user_cache_range
 	.long	arm922_coherent_kern_range
 	.long	arm922_coherent_user_range
-	.long	arm922_flush_kern_dcache_page
+	.long	arm922_flush_kern_dcache_area
 	.long	arm922_dma_inv_range
 	.long	arm922_dma_clean_range
 	.long	arm922_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm925.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm925.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm925.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm925.S	2010-02-24 13:52:17.000000000 -0500
@@ -251,15 +251,16 @@ ENTRY(arm925_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm925_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(arm925_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -346,7 +347,7 @@ ENTRY(arm925_cache_fns)
 	.long	arm925_flush_user_cache_range
 	.long	arm925_coherent_kern_range
 	.long	arm925_coherent_user_range
-	.long	arm925_flush_kern_dcache_page
+	.long	arm925_flush_kern_dcache_area
 	.long	arm925_dma_inv_range
 	.long	arm925_dma_clean_range
 	.long	arm925_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm926.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm926.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm926.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm926.S	2010-02-24 13:52:17.000000000 -0500
@@ -214,15 +214,16 @@ ENTRY(arm926_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm926_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(arm926_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -309,7 +310,7 @@ ENTRY(arm926_cache_fns)
 	.long	arm926_flush_user_cache_range
 	.long	arm926_coherent_kern_range
 	.long	arm926_coherent_user_range
-	.long	arm926_flush_kern_dcache_page
+	.long	arm926_flush_kern_dcache_area
 	.long	arm926_dma_inv_range
 	.long	arm926_dma_clean_range
 	.long	arm926_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm940.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm940.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm940.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm940.S	2010-02-24 13:52:17.000000000 -0500
@@ -141,14 +141,15 @@ ENTRY(arm940_coherent_user_range)
 	/* FALLTHROUGH */
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(arm940_flush_kern_dcache_page)
+ENTRY(arm940_flush_kern_dcache_area)
 	mov	ip, #0
 	mov	r1, #(CACHE_DSEGMENTS - 1) << 4	@ 4 segments
 1:	orr	r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
@@ -238,7 +239,7 @@ ENTRY(arm940_cache_fns)
 	.long	arm940_flush_user_cache_range
 	.long	arm940_coherent_kern_range
 	.long	arm940_coherent_user_range
-	.long	arm940_flush_kern_dcache_page
+	.long	arm940_flush_kern_dcache_area
 	.long	arm940_dma_inv_range
 	.long	arm940_dma_clean_range
 	.long	arm940_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm946.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm946.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-arm946.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-arm946.S	2010-02-24 13:52:17.000000000 -0500
@@ -183,16 +183,17 @@ ENTRY(arm946_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  * (same as arm926)
  */
-ENTRY(arm946_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(arm946_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -280,7 +281,7 @@ ENTRY(arm946_cache_fns)
 	.long	arm946_flush_user_cache_range
 	.long	arm946_coherent_kern_range
 	.long	arm946_coherent_user_range
-	.long	arm946_flush_kern_dcache_page
+	.long	arm946_flush_kern_dcache_area
 	.long	arm946_dma_inv_range
 	.long	arm946_dma_clean_range
 	.long	arm946_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-feroceon.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-feroceon.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-feroceon.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-feroceon.S	2010-02-24 13:52:17.000000000 -0500
@@ -226,16 +226,17 @@ ENTRY(feroceon_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
 	.align	5
-ENTRY(feroceon_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(feroceon_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -246,7 +247,7 @@ ENTRY(feroceon_flush_kern_dcache_page)
 	mov	pc, lr
 
 	.align	5
-ENTRY(feroceon_range_flush_kern_dcache_page)
+ENTRY(feroceon_range_flush_kern_dcache_area)
 	mrs	r2, cpsr
 	add	r1, r0, #PAGE_SZ - CACHE_DLINESIZE	@ top addr is inclusive
 	orr	r3, r2, #PSR_I_BIT
@@ -372,7 +373,7 @@ ENTRY(feroceon_cache_fns)
 	.long	feroceon_flush_user_cache_range
 	.long	feroceon_coherent_kern_range
 	.long	feroceon_coherent_user_range
-	.long	feroceon_flush_kern_dcache_page
+	.long	feroceon_flush_kern_dcache_area
 	.long	feroceon_dma_inv_range
 	.long	feroceon_dma_clean_range
 	.long	feroceon_dma_flush_range
@@ -383,7 +384,7 @@ ENTRY(feroceon_range_cache_fns)
 	.long	feroceon_flush_user_cache_range
 	.long	feroceon_coherent_kern_range
 	.long	feroceon_coherent_user_range
-	.long	feroceon_range_flush_kern_dcache_page
+	.long	feroceon_range_flush_kern_dcache_area
 	.long	feroceon_range_dma_inv_range
 	.long	feroceon_range_dma_clean_range
 	.long	feroceon_range_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-mohawk.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-mohawk.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-mohawk.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-mohawk.S	2010-02-24 13:52:17.000000000 -0500
@@ -186,15 +186,16 @@ ENTRY(mohawk_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(mohawk_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(mohawk_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
@@ -273,7 +274,7 @@ ENTRY(mohawk_cache_fns)
 	.long	mohawk_flush_user_cache_range
 	.long	mohawk_coherent_kern_range
 	.long	mohawk_coherent_user_range
-	.long	mohawk_flush_kern_dcache_page
+	.long	mohawk_flush_kern_dcache_area
 	.long	mohawk_dma_inv_range
 	.long	mohawk_dma_clean_range
 	.long	mohawk_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-syms.c linux-libre-2.6.33-gnu1/arch/arm/mm/proc-syms.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-syms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-syms.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,8 +27,7 @@ EXPORT_SYMBOL(__cpuc_flush_kern_all);
 EXPORT_SYMBOL(__cpuc_flush_user_all);
 EXPORT_SYMBOL(__cpuc_flush_user_range);
 EXPORT_SYMBOL(__cpuc_coherent_kern_range);
-EXPORT_SYMBOL(__cpuc_flush_dcache_page);
-EXPORT_SYMBOL(dmac_inv_range);  /* because of flush_ioremap_region() */
+EXPORT_SYMBOL(__cpuc_flush_dcache_area);
 #else
 EXPORT_SYMBOL(cpu_cache);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-v6.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-v6.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-v6.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-v6.S	2010-02-24 13:52:17.000000000 -0500
@@ -59,8 +59,6 @@ ENTRY(cpu_v6_proc_fin)
  *	to what would be the reset vector.
  *
  *	- loc   - location to jump to for soft reset
- *
- *	It is assumed that:
  */
 	.align	5
 ENTRY(cpu_v6_reset)
@@ -130,9 +128,16 @@ ENTRY(cpu_v6_set_pte_ext)
 
 
 
-
+	.type	cpu_v6_name, #object
 cpu_v6_name:
 	.asciz	"ARMv6-compatible processor"
+	.size	cpu_v6_name, . - cpu_v6_name
+
+	.type	cpu_pj4_name, #object
+cpu_pj4_name:
+	.asciz	"Marvell PJ4 processor"
+	.size	cpu_pj4_name, . - cpu_pj4_name
+
 	.align
 
 	__INIT
@@ -241,3 +246,26 @@ __v6_proc_info:
 	.long	v6_user_fns
 	.long	v6_cache_fns
 	.size	__v6_proc_info, . - __v6_proc_info
+
+	.type	__pj4_v6_proc_info, #object
+__pj4_v6_proc_info:
+	.long	0x560f5810
+	.long	0xff0ffff0
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ | \
+		PMD_FLAGS
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_XN | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__v6_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_pj4_name
+	.long	v6_processor_functions
+	.long	v6wbi_tlb_fns
+	.long	v6_user_fns
+	.long	v6_cache_fns
+	.size	__pj4_v6_proc_info, . - __pj4_v6_proc_info
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-v7.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-v7.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-v7.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-v7.S	2010-02-24 13:52:17.000000000 -0500
@@ -45,7 +45,14 @@ ENTRY(cpu_v7_proc_init)
 ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
-	mov	pc, lr
+	stmfd	sp!, {lr}
+	cpsid	if				@ disable interrupts
+	bl	v7_flush_kern_cache_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x0006			@ .............ca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
 ENDPROC(cpu_v7_proc_fin)
 
 /*
@@ -56,8 +63,6 @@ ENDPROC(cpu_v7_proc_fin)
  *	to what would be the reset vector.
  *
  *	- loc   - location to jump to for soft reset
- *
- *	It is assumed that:
  */
 	.align	5
 ENTRY(cpu_v7_reset)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-xsc3.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xsc3.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-xsc3.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xsc3.S	2010-02-24 13:52:17.000000000 -0500
@@ -226,15 +226,16 @@ ENTRY(xsc3_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache.
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(xsc3_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(xsc3_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean/invalidate L1 D line
 	add	r0, r0, #CACHELINESIZE
 	cmp	r0, r1
@@ -309,7 +310,7 @@ ENTRY(xsc3_cache_fns)
 	.long	xsc3_flush_user_cache_range
 	.long	xsc3_coherent_kern_range
 	.long	xsc3_coherent_user_range
-	.long	xsc3_flush_kern_dcache_page
+	.long	xsc3_flush_kern_dcache_area
 	.long	xsc3_dma_inv_range
 	.long	xsc3_dma_clean_range
 	.long	xsc3_dma_flush_range
@@ -396,7 +397,7 @@ __xsc3_setup:
 	orr	r4, r4, #0x18			@ cache the page table in L2
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 
-	mov	r0, #0				@ don't allow CP access
+	mov	r0, #1 << 6			@ cp6 access for early sched_clock
 	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
 
 	mrc	p15, 0, r0, c1, c0, 1		@ get auxiliary control reg
@@ -406,6 +407,13 @@ __xsc3_setup:
 
 	adr	r5, xsc3_crval
 	ldmia	r5, {r5, r6}
+
+#ifdef CONFIG_CACHE_XSC3L2
+	mrc	p15, 1, r0, c0, c0, 1		@ get L2 present information
+	ands	r0, r0, #0xf8
+	orrne	r6, r6, #(1 << 26)		@ enable L2 if present
+#endif
+
 	mrc	p15, 0, r0, c1, c0, 0		@ get control register
 	bic	r0, r0, r5			@ ..V. ..R. .... ..A.
 	orr	r0, r0, r6			@ ..VI Z..S .... .C.M (mmu)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/proc-xscale.S linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xscale.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/proc-xscale.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/proc-xscale.S	2010-02-24 13:52:17.000000000 -0500
@@ -284,15 +284,16 @@ ENTRY(xscale_coherent_user_range)
 	mov	pc, lr
 
 /*
- *	flush_kern_dcache_page(void *page)
+ *	flush_kern_dcache_area(void *addr, size_t size)
  *
  *	Ensure no D cache aliasing occurs, either with itself or
  *	the I cache
  *
- *	- addr	- page aligned address
+ *	- addr	- kernel address
+ *	- size	- region size
  */
-ENTRY(xscale_flush_kern_dcache_page)
-	add	r1, r0, #PAGE_SZ
+ENTRY(xscale_flush_kern_dcache_area)
+	add	r1, r0, r1
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #CACHELINESIZE
@@ -368,7 +369,7 @@ ENTRY(xscale_cache_fns)
 	.long	xscale_flush_user_cache_range
 	.long	xscale_coherent_kern_range
 	.long	xscale_coherent_user_range
-	.long	xscale_flush_kern_dcache_page
+	.long	xscale_flush_kern_dcache_area
 	.long	xscale_dma_inv_range
 	.long	xscale_dma_clean_range
 	.long	xscale_dma_flush_range
@@ -392,7 +393,7 @@ ENTRY(xscale_80200_A0_A1_cache_fns)
 	.long	xscale_flush_user_cache_range
 	.long	xscale_coherent_kern_range
 	.long	xscale_coherent_user_range
-	.long	xscale_flush_kern_dcache_page
+	.long	xscale_flush_kern_dcache_area
 	.long	xscale_dma_flush_range
 	.long	xscale_dma_clean_range
 	.long	xscale_dma_flush_range
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/tlb-v7.S linux-libre-2.6.33-gnu1/arch/arm/mm/tlb-v7.S
--- linux-libre-2.6.32-gnu1/arch/arm/mm/tlb-v7.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/tlb-v7.S	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,6 @@ ENTRY(v7wbi_flush_user_tlb_range)
 	asid	r3, r3				@ mask ASID
 	orr	r0, r3, r0, lsl #PAGE_SHIFT	@ Create initial MVA
 	mov	r1, r1, lsl #PAGE_SHIFT
-	vma_vm_flags r2, r2			@ get vma->vm_flags
 1:
 #ifdef CONFIG_SMP
 	mcr	p15, 0, r0, c8, c3, 1		@ TLB invalidate U MVA (shareable) 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/vmregion.c linux-libre-2.6.33-gnu1/arch/arm/mm/vmregion.c
--- linux-libre-2.6.32-gnu1/arch/arm/mm/vmregion.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/vmregion.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,131 @@
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "vmregion.h"
+
+/*
+ * VM region handling support.
+ *
+ * This should become something generic, handling VM region allocations for
+ * vmalloc and similar (ioremap, module space, etc).
+ *
+ * I envisage vmalloc()'s supporting vm_struct becoming:
+ *
+ *  struct vm_struct {
+ *    struct vmregion	region;
+ *    unsigned long	flags;
+ *    struct page	**pages;
+ *    unsigned int	nr_pages;
+ *    unsigned long	phys_addr;
+ *  };
+ *
+ * get_vm_area() would then call vmregion_alloc with an appropriate
+ * struct vmregion head (eg):
+ *
+ *  struct vmregion vmalloc_head = {
+ *	.vm_list	= LIST_HEAD_INIT(vmalloc_head.vm_list),
+ *	.vm_start	= VMALLOC_START,
+ *	.vm_end		= VMALLOC_END,
+ *  };
+ *
+ * However, vmalloc_head.vm_start is variable (typically, it is dependent on
+ * the amount of RAM found at boot time.)  I would imagine that get_vm_area()
+ * would have to initialise this each time prior to calling vmregion_alloc().
+ */
+
+struct arm_vmregion *
+arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp)
+{
+	unsigned long addr = head->vm_start, end = head->vm_end - size;
+	unsigned long flags;
+	struct arm_vmregion *c, *new;
+
+	if (head->vm_end - head->vm_start < size) {
+		printk(KERN_WARNING "%s: allocation too big (requested %#x)\n",
+			__func__, size);
+		goto out;
+	}
+
+	new = kmalloc(sizeof(struct arm_vmregion), gfp);
+	if (!new)
+		goto out;
+
+	spin_lock_irqsave(&head->vm_lock, flags);
+
+	list_for_each_entry(c, &head->vm_list, vm_list) {
+		if ((addr + size) < addr)
+			goto nospc;
+		if ((addr + size) <= c->vm_start)
+			goto found;
+		addr = c->vm_end;
+		if (addr > end)
+			goto nospc;
+	}
+
+ found:
+	/*
+	 * Insert this entry _before_ the one we found.
+	 */
+	list_add_tail(&new->vm_list, &c->vm_list);
+	new->vm_start = addr;
+	new->vm_end = addr + size;
+	new->vm_active = 1;
+
+	spin_unlock_irqrestore(&head->vm_lock, flags);
+	return new;
+
+ nospc:
+	spin_unlock_irqrestore(&head->vm_lock, flags);
+	kfree(new);
+ out:
+	return NULL;
+}
+
+static struct arm_vmregion *__arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+	struct arm_vmregion *c;
+
+	list_for_each_entry(c, &head->vm_list, vm_list) {
+		if (c->vm_active && c->vm_start == addr)
+			goto out;
+	}
+	c = NULL;
+ out:
+	return c;
+}
+
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+	struct arm_vmregion *c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&head->vm_lock, flags);
+	c = __arm_vmregion_find(head, addr);
+	spin_unlock_irqrestore(&head->vm_lock, flags);
+	return c;
+}
+
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *head, unsigned long addr)
+{
+	struct arm_vmregion *c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&head->vm_lock, flags);
+	c = __arm_vmregion_find(head, addr);
+	if (c)
+		c->vm_active = 0;
+	spin_unlock_irqrestore(&head->vm_lock, flags);
+	return c;
+}
+
+void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&head->vm_lock, flags);
+	list_del(&c->vm_list);
+	spin_unlock_irqrestore(&head->vm_lock, flags);
+
+	kfree(c);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/mm/vmregion.h linux-libre-2.6.33-gnu1/arch/arm/mm/vmregion.h
--- linux-libre-2.6.32-gnu1/arch/arm/mm/vmregion.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/mm/vmregion.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+#ifndef VMREGION_H
+#define VMREGION_H
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+struct page;
+
+struct arm_vmregion_head {
+	spinlock_t		vm_lock;
+	struct list_head	vm_list;
+	unsigned long		vm_start;
+	unsigned long		vm_end;
+};
+
+struct arm_vmregion {
+	struct list_head	vm_list;
+	unsigned long		vm_start;
+	unsigned long		vm_end;
+	struct page		*vm_pages;
+	int			vm_active;
+};
+
+struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, gfp_t);
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
+void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/nwfpe/Makefile linux-libre-2.6.33-gnu1/arch/arm/nwfpe/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/nwfpe/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/nwfpe/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@ obj-$(CONFIG_FPE_NWFPE)		+= nwfpe.o
 
 nwfpe-y				+= fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
 				   fpa11_cprt.o fpmodule.o fpopcode.o \
-				   softfloat.o single_cpdo.o double_cpdo.o
+				   softfloat.o single_cpdo.o double_cpdo.o \
+				   entry.o
 
 nwfpe-$(CONFIG_FPE_NWFPE_XP)	+= extended_cpdo.o
-nwfpe-$(CONFIG_CPU_32)		+= entry.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/oprofile/op_model_v7.c linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.c
--- linux-libre-2.6.32-gnu1/arch/arm/oprofile/op_model_v7.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/oprofile/op_model_v7.c	2010-02-24 13:52:17.000000000 -0500
@@ -191,12 +191,8 @@ int armv7_setup_pmnc(void)
 		return -EBUSY;
 	}
 
-	/*
-	 * Initialize & Reset PMNC: C bit, D bit and P bit.
-	 *  Note: Using a slower count for CCNT (D bit: divide by 64) results
-	 *   in a more stable system
-	 */
-	armv7_pmnc_write(PMNC_P | PMNC_C | PMNC_D);
+	/* Initialize & Reset PMNC: C bit and P bit */
+	armv7_pmnc_write(PMNC_P | PMNC_C);
 
 
 	for (cnt = CCNT; cnt < CNTMAX; cnt++) {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-iop/time.c linux-libre-2.6.33-gnu1/arch/arm/plat-iop/time.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-iop/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-iop/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,8 @@
 #include <linux/init.h>
 #include <linux/timex.h>
 #include <linux/io.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -26,45 +28,136 @@
 #include <asm/mach/time.h>
 #include <mach/time.h>
 
+/*
+ * IOP clocksource (free-running timer 1).
+ */
+static cycle_t iop_clocksource_read(struct clocksource *unused)
+{
+	return 0xffffffffu - read_tcr1();
+}
+
+static struct clocksource iop_clocksource = {
+	.name 		= "iop_timer1",
+	.rating		= 300,
+	.read		= iop_clocksource_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init iop_clocksource_set_hz(struct clocksource *cs, unsigned int hz)
+{
+	u64 temp;
+	u32 shift;
+
+	/* Find shift and mult values for hz. */
+	shift = 32;
+	do {
+		temp = (u64) NSEC_PER_SEC << shift;
+		do_div(temp, hz);
+		if ((temp >> 32) == 0)
+			break;
+	} while (--shift != 0);
+
+	cs->shift = shift;
+	cs->mult = (u32) temp;
+
+	printk(KERN_INFO "clocksource: %s uses shift %u mult %#x\n",
+	       cs->name, cs->shift, cs->mult);
+}
+
+/*
+ * IOP sched_clock() implementation via its clocksource.
+ */
+unsigned long long sched_clock(void)
+{
+	cycle_t cyc = iop_clocksource_read(NULL);
+	struct clocksource *cs = &iop_clocksource;
+
+	return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+}
+
+/*
+ * IOP clockevents (interrupting timer 0).
+ */
+static int iop_set_next_event(unsigned long delta,
+			      struct clock_event_device *unused)
+{
+	u32 tmr = IOP_TMR_PRIVILEGED | IOP_TMR_RATIO_1_1;
+
+	BUG_ON(delta == 0);
+	write_tmr0(tmr & ~(IOP_TMR_EN | IOP_TMR_RELOAD));
+	write_tcr0(delta);
+	write_tmr0((tmr & ~IOP_TMR_RELOAD) | IOP_TMR_EN);
+
+	return 0;
+}
+
 static unsigned long ticks_per_jiffy;
-static unsigned long ticks_per_usec;
-static unsigned long next_jiffy_time;
 
-unsigned long iop_gettimeoffset(void)
+static void iop_set_mode(enum clock_event_mode mode,
+			 struct clock_event_device *unused)
 {
-	unsigned long offset, temp;
+	u32 tmr = read_tmr0();
 
-	/* enable cp6, if necessary, to avoid taking the overhead of an
-	 * undefined instruction trap
-	 */
-	asm volatile (
-	"mrc	p15, 0, %0, c15, c1, 0\n\t"
-	"tst	%0, #(1 << 6)\n\t"
-	"orreq	%0, %0, #(1 << 6)\n\t"
-	"mcreq	p15, 0, %0, c15, c1, 0\n\t"
-#ifdef CONFIG_CPU_XSCALE
-	"mrceq	p15, 0, %0, c15, c1, 0\n\t"
-	"moveq	%0, %0\n\t"
-	"subeq	pc, pc, #4\n\t"
-#endif
-	: "=r"(temp) : : "cc");
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		write_tmr0(tmr & ~IOP_TMR_EN);
+		write_tcr0(ticks_per_jiffy - 1);
+		tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* ->set_next_event sets period and enables timer */
+		tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		tmr |= IOP_TMR_EN;
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	default:
+		tmr &= ~IOP_TMR_EN;
+		break;
+	}
 
-	offset = next_jiffy_time - read_tcr1();
+	write_tmr0(tmr);
+}
 
-	return offset / ticks_per_usec;
+static struct clock_event_device iop_clockevent = {
+	.name		= "iop_timer0",
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating         = 300,
+	.set_next_event	= iop_set_next_event,
+	.set_mode	= iop_set_mode,
+};
+
+static void __init iop_clockevent_set_hz(struct clock_event_device *ce, unsigned int hz)
+{
+	u64 temp;
+	u32 shift;
+
+	/* Find shift and mult values for hz. */
+	shift = 32;
+	do {
+		temp = (u64) hz << shift;
+		do_div(temp, NSEC_PER_SEC);
+		if ((temp >> 32) == 0)
+			break;
+	} while (--shift != 0);
+
+	ce->shift = shift;
+	ce->mult = (u32) temp;
+
+	printk(KERN_INFO "clockevent: %s uses shift %u mult %#lx\n",
+	       ce->name, ce->shift, ce->mult);
 }
 
 static irqreturn_t
 iop_timer_interrupt(int irq, void *dev_id)
 {
-	write_tisr(1);
-
-	while ((signed long)(next_jiffy_time - read_tcr1())
-		>= ticks_per_jiffy) {
-		timer_tick();
-		next_jiffy_time -= ticks_per_jiffy;
-	}
+	struct clock_event_device *evt = dev_id;
 
+	write_tisr(1);
+	evt->event_handler(evt);
 	return IRQ_HANDLED;
 }
 
@@ -72,6 +165,7 @@ static struct irqaction iop_timer_irq =
 	.name		= "IOP Timer Tick",
 	.handler	= iop_timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.dev_id		= &iop_clockevent,
 };
 
 static unsigned long iop_tick_rate;
@@ -86,21 +180,33 @@ void __init iop_init_time(unsigned long
 	u32 timer_ctl;
 
 	ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
-	ticks_per_usec = tick_rate / 1000000;
-	next_jiffy_time = 0xffffffff;
 	iop_tick_rate = tick_rate;
 
 	timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
 			IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
 
 	/*
-	 * We use timer 0 for our timer interrupt, and timer 1 as
-	 * monotonic counter for tracking missed jiffies.
+	 * Set up interrupting clockevent timer 0.
 	 */
+	write_tmr0(timer_ctl & ~IOP_TMR_EN);
+	setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
+	iop_clockevent_set_hz(&iop_clockevent, tick_rate);
+	iop_clockevent.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &iop_clockevent);
+	iop_clockevent.min_delta_ns =
+		clockevent_delta2ns(0xf, &iop_clockevent);
+	iop_clockevent.cpumask = cpumask_of(0);
+	clockevents_register_device(&iop_clockevent);
 	write_trr0(ticks_per_jiffy - 1);
+	write_tcr0(ticks_per_jiffy - 1);
 	write_tmr0(timer_ctl);
+
+	/*
+	 * Set up free-running clocksource timer 1.
+	 */
 	write_trr1(0xffffffff);
+	write_tcr1(0xffffffff);
 	write_tmr1(timer_ctl);
-
-	setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
+	iop_clocksource_set_hz(&iop_clocksource, tick_rate);
+	clocksource_register(&iop_clocksource);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/audmux-v1.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v1.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/audmux-v1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v1.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <mach/audmux.h>
+#include <mach/hardware.h>
+
+static void __iomem *audmux_base;
+
+static unsigned char port_mapping[] = {
+	0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
+};
+
+int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
+{
+	if (!audmux_base) {
+		printk("%s: not configured\n", __func__);
+		return -ENOSYS;
+	}
+
+	if (port >= ARRAY_SIZE(port_mapping))
+		return -EINVAL;
+
+	writel(pcr, audmux_base + port_mapping[port]);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
+
+static int mxc_audmux_v1_init(void)
+{
+	if (cpu_is_mx27() || cpu_is_mx21())
+		audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
+	return 0;
+}
+
+postcore_initcall(mxc_audmux_v1_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/audmux-v2.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v2.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/audmux-v2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/audmux-v2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <mach/audmux.h>
+#include <mach/hardware.h>
+
+static struct clk *audmux_clk;
+static void __iomem *audmux_base;
+
+#define MXC_AUDMUX_V2_PTCR(x)		((x) * 8)
+#define MXC_AUDMUX_V2_PDCR(x)		((x) * 8 + 4)
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *audmux_debugfs_root;
+
+static int audmux_open_file(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+/* There is an annoying discontinuity in the SSI numbering with regard
+ * to the Linux number of the devices */
+static const char *audmux_port_string(int port)
+{
+	switch (port) {
+	case MX31_AUDMUX_PORT1_SSI0:
+		return "imx-ssi.0";
+	case MX31_AUDMUX_PORT2_SSI1:
+		return "imx-ssi.1";
+	case MX31_AUDMUX_PORT3_SSI_PINS_3:
+		return "SSI3";
+	case MX31_AUDMUX_PORT4_SSI_PINS_4:
+		return "SSI4";
+	case MX31_AUDMUX_PORT5_SSI_PINS_5:
+		return "SSI5";
+	case MX31_AUDMUX_PORT6_SSI_PINS_6:
+		return "SSI6";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	ssize_t ret;
+	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	int port = (int)file->private_data;
+	u32 pdcr, ptcr;
+
+	if (!buf)
+		return -ENOMEM;
+
+	if (audmux_clk)
+		clk_enable(audmux_clk);
+
+	ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
+	pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
+
+	if (audmux_clk)
+		clk_disable(audmux_clk);
+
+	ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
+		       pdcr, ptcr);
+
+	if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR)
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"TxFS output from %s, ",
+				audmux_port_string((ptcr >> 27) & 0x7));
+	else
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"TxFS input, ");
+
+	if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR)
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"TxClk output from %s",
+				audmux_port_string((ptcr >> 22) & 0x7));
+	else
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"TxClk input");
+
+	ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+
+	if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) {
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"Port is symmetric");
+	} else {
+		if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR)
+			ret += snprintf(buf + ret, PAGE_SIZE - ret,
+					"RxFS output from %s, ",
+					audmux_port_string((ptcr >> 17) & 0x7));
+		else
+			ret += snprintf(buf + ret, PAGE_SIZE - ret,
+					"RxFS input, ");
+
+		if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR)
+			ret += snprintf(buf + ret, PAGE_SIZE - ret,
+					"RxClk output from %s",
+					audmux_port_string((ptcr >> 12) & 0x7));
+		else
+			ret += snprintf(buf + ret, PAGE_SIZE - ret,
+					"RxClk input");
+	}
+
+	ret += snprintf(buf + ret, PAGE_SIZE - ret,
+			"\nData received from %s\n",
+			audmux_port_string((pdcr >> 13) & 0x7));
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+	kfree(buf);
+
+	return ret;
+}
+
+static const struct file_operations audmux_debugfs_fops = {
+	.open = audmux_open_file,
+	.read = audmux_read_file,
+};
+
+static void audmux_debugfs_init(void)
+{
+	int i;
+	char buf[20];
+
+	audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
+	if (!audmux_debugfs_root) {
+		pr_warning("Failed to create AUDMUX debugfs root\n");
+		return;
+	}
+
+	for (i = 1; i < 8; i++) {
+		snprintf(buf, sizeof(buf), "ssi%d", i);
+		if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
+					 (void *)i, &audmux_debugfs_fops))
+			pr_warning("Failed to create AUDMUX port %d debugfs file\n",
+				   i);
+	}
+}
+#else
+static inline void audmux_debugfs_init(void)
+{
+}
+#endif
+
+int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+		unsigned int pdcr)
+{
+	if (!audmux_base)
+		return -ENOSYS;
+
+	if (audmux_clk)
+		clk_enable(audmux_clk);
+
+	writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
+	writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
+
+	if (audmux_clk)
+		clk_disable(audmux_clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
+
+static int mxc_audmux_v2_init(void)
+{
+	int ret;
+
+	if (cpu_is_mx35()) {
+		audmux_clk = clk_get(NULL, "audmux");
+		if (IS_ERR(audmux_clk)) {
+			ret = PTR_ERR(audmux_clk);
+			printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
+					ret);
+			return ret;
+		}
+	}
+
+	if (cpu_is_mx31() || cpu_is_mx35())
+		audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
+
+	audmux_debugfs_init();
+
+	return 0;
+}
+
+postcore_initcall(mxc_audmux_v2_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2010-02-24 13:52:17.000000000 -0500
@@ -156,7 +156,8 @@ static inline int imx_dma_sg_next(int ch
 	}
 
 	now = min(imxdma->resbytes, sg->length);
-	imxdma->resbytes -= now;
+	if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP)
+		imxdma->resbytes -= now;
 
 	if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
 		__raw_writel(sg->dma_address, DMA_BASE + DMA_DAR(channel));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/ehci.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ehci.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/ehci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ehci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET	0x600
+
+#define MX31_OTG_SIC_SHIFT	29
+#define MX31_OTG_SIC_MASK	(0xf << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_PM_BIT		(1 << 24)
+
+#define MX31_H2_SIC_SHIFT	21
+#define MX31_H2_SIC_MASK	(0xf << MX31_H2_SIC_SHIFT)
+#define MX31_H2_PM_BIT		(1 << 16)
+#define MX31_H2_DT_BIT		(1 << 5)
+
+#define MX31_H1_SIC_SHIFT	13
+#define MX31_H1_SIC_MASK	(0xf << MX31_H1_SIC_SHIFT)
+#define MX31_H1_PM_BIT		(1 << 8)
+#define MX31_H1_DT_BIT		(1 << 4)
+
+int mxc_set_usbcontrol(int port, unsigned int flags)
+{
+	unsigned int v;
+
+	if (cpu_is_mx31()) {
+		v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+
+		switch (port) {
+		case 0:	/* OTG port */
+			v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+					<< MX31_OTG_SIC_SHIFT;
+			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+				v |= MX31_OTG_PM_BIT;
+
+			break;
+		case 1: /* H1 port */
+			v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H1_SIC_SHIFT;
+			if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+				v |= MX31_H1_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H1_DT_BIT;
+
+			break;
+		case 2:	/* H2 port */
+			v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT);
+			v |= (flags & MXC_EHCI_INTERFACE_MASK)
+						<< MX31_H2_SIC_SHIFT;
+			if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+				v |= MX31_H2_PM_BIT;
+
+			if (!(flags & MXC_EHCI_TTL_ENABLED))
+				v |= MX31_H2_DT_BIT;
+
+			break;
+		}
+
+		writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR +
+				     USBCTRL_OTGBASE_OFFSET));
+		return 0;
+	}
+
+	printk(KERN_WARNING
+		"%s() unable to setup USBCONTROL for this CPU\n", __func__);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mxc_set_usbcontrol);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/gpio.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -282,7 +282,7 @@ int __init mxc_gpio_init(struct mxc_gpio
 		for (j = port[i].virtual_irq_start;
 			j < port[i].virtual_irq_start + 32; j++) {
 			set_irq_chip(j, &gpio_irq_chip);
-			set_irq_handler(j, handle_edge_irq);
+			set_irq_handler(j, handle_level_irq);
 			set_irq_flags(j, IRQF_VALID);
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/audmux.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/audmux.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/audmux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/audmux.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+#ifndef __MACH_AUDMUX_H
+#define __MACH_AUDMUX_H
+
+#define MX27_AUDMUX_HPCR1_SSI0		0
+#define MX27_AUDMUX_HPCR2_SSI1		1
+#define MX27_AUDMUX_HPCR3_SSI_PINS_4	2
+#define MX27_AUDMUX_PPCR1_SSI_PINS_1	3
+#define MX27_AUDMUX_PPCR2_SSI_PINS_2	4
+#define MX27_AUDMUX_PPCR3_SSI_PINS_3	5
+
+#define MX31_AUDMUX_PORT1_SSI0		0
+#define MX31_AUDMUX_PORT2_SSI1		1
+#define MX31_AUDMUX_PORT3_SSI_PINS_3	2
+#define MX31_AUDMUX_PORT4_SSI_PINS_4	3
+#define MX31_AUDMUX_PORT5_SSI_PINS_5	4
+#define MX31_AUDMUX_PORT6_SSI_PINS_6	5
+
+/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
+#define MXC_AUDMUX_V1_PCR_INMMASK(x)	((x) & 0xff)
+#define MXC_AUDMUX_V1_PCR_INMEN		(1 << 8)
+#define MXC_AUDMUX_V1_PCR_TXRXEN	(1 << 10)
+#define MXC_AUDMUX_V1_PCR_SYN		(1 << 12)
+#define MXC_AUDMUX_V1_PCR_RXDSEL(x)	(((x) & 0x7) << 13)
+#define MXC_AUDMUX_V1_PCR_RFCSEL(x)	(((x) & 0xf) << 20)
+#define MXC_AUDMUX_V1_PCR_RCLKDIR	(1 << 24)
+#define MXC_AUDMUX_V1_PCR_RFSDIR	(1 << 25)
+#define MXC_AUDMUX_V1_PCR_TFCSEL(x)	(((x) & 0xf) << 26)
+#define MXC_AUDMUX_V1_PCR_TCLKDIR	(1 << 30)
+#define MXC_AUDMUX_V1_PCR_TFSDIR	(1 << 31)
+
+/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */
+#define MXC_AUDMUX_V2_PTCR_TFSDIR	(1 << 31)
+#define MXC_AUDMUX_V2_PTCR_TFSEL(x)	(((x) & 0xf) << 27)
+#define MXC_AUDMUX_V2_PTCR_TCLKDIR	(1 << 26)
+#define MXC_AUDMUX_V2_PTCR_TCSEL(x)	(((x) & 0xf) << 22)
+#define MXC_AUDMUX_V2_PTCR_RFSDIR	(1 << 21)
+#define MXC_AUDMUX_V2_PTCR_RFSEL(x)	(((x) & 0xf) << 17)
+#define MXC_AUDMUX_V2_PTCR_RCLKDIR	(1 << 16)
+#define MXC_AUDMUX_V2_PTCR_RCSEL(x)	(((x) & 0xf) << 12)
+#define MXC_AUDMUX_V2_PTCR_SYN		(1 << 11)
+
+#define MXC_AUDMUX_V2_PDCR_RXDSEL(x)	(((x) & 0x7) << 13)
+#define MXC_AUDMUX_V2_PDCR_TXRXEN	(1 << 12)
+#define MXC_AUDMUX_V2_PDCR_MODE(x)	(((x) & 0x3) << 8)
+#define MXC_AUDMUX_V2_PDCR_INMMASK(x)	((x) & 0xff)
+
+int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
+
+int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+		unsigned int pdcr);
+
+#endif /* __MACH_AUDMUX_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-kzmarm11.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2009  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
+ */
+#ifndef __ARM_ARCH_BOARD_KZM_ARM11_H
+#define __ARM_ARCH_BOARD_KZM_ARM11_H
+
+/*
+ *  KZM-ARM11-01 Board Control Registers on FPGA
+ */
+#define KZM_ARM11_CTL1		(CS4_BASE_ADDR + 0x1000)
+#define KZM_ARM11_CTL2		(CS4_BASE_ADDR + 0x1001)
+#define KZM_ARM11_RSW1		(CS4_BASE_ADDR + 0x1002)
+#define KZM_ARM11_BACK_LIGHT	(CS4_BASE_ADDR + 0x1004)
+#define KZM_ARM11_FPGA_REV	(CS4_BASE_ADDR + 0x1008)
+#define KZM_ARM11_7SEG_LED	(CS4_BASE_ADDR + 0x1010)
+#define KZM_ARM11_LEDS		(CS4_BASE_ADDR + 0x1020)
+#define KZM_ARM11_DIPSW2	(CS4_BASE_ADDR + 0x1003)
+
+/*
+ * External UART for touch panel on FPGA
+ */
+#define KZM_ARM11_16550		(CS4_BASE_ADDR + 0x1050)
+
+#endif /* __ARM_ARCH_BOARD_KZM_ARM11_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/board-mx31lite.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31lite.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/board-mx31lite.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/board-mx31lite.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,15 +1,42 @@
 /*
  * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code for mobots boards,
+ *   Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
  */
 
+#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__
+#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__
+
+#ifndef __ASSEMBLY__
+
+enum mx31lite_boards {
+	MX31LITE_NOBOARD	= 0,
+	MX31LITE_DB		= 1,
+};
+
 /*
- * This 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 CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
  */
 
-#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__
-#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__
+extern void mx31lite_db_init(void);
 
-#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */
+#endif
 
+#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/common.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/common.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@ extern void mxc91231_init_irq(void);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
 extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
-extern int mx25_clocks_init(unsigned long fref);
+extern int mx25_clocks_init(void);
 extern int mx27_clocks_init(unsigned long fref);
 extern int mx31_clocks_init(unsigned long fref);
 extern int mx35_clocks_init(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,6 +58,14 @@ imx_dma_setup_single(int channel, dma_ad
 		unsigned int dma_length, unsigned int dev_addr,
 		unsigned int dmamode);
 
+
+/*
+ * Use this flag as the dma_length argument to imx_dma_setup_sg()
+ * to create an endless running dma loop. The end of the scatterlist
+ * must be linked to the beginning for this to work.
+ */
+#define IMX_DMA_LENGTH_LOOP	((unsigned int)-1)
+
 int
 imx_dma_setup_sg(int channel, struct scatterlist *sg,
 		unsigned int sgcount, unsigned int dma_length,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	2010-02-24 13:52:17.000000000 -0500
@@ -123,6 +123,7 @@
 #define IRQ_GPIOC(x)  (IRQ_GPIOB(32) + x)
 #define IRQ_GPIOD(x)  (IRQ_GPIOC(32) + x)
 #define IRQ_GPIOE(x)  (IRQ_GPIOD(32) + x)
+#define IRQ_GPIOF(x)  (IRQ_GPIOE(32) + x)
 
 
 extern void mxc_gpio_mode(int gpio_mode);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,19 +58,19 @@
 
 #define MX25_PAD_A18__A18		IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A18__GPIO_2_4		IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A18__FEC_COL		IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL)
+#define MX25_PAD_A18__FEC_COL		IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_A19__A19		IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A19__FEC_RX_ER		IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL)
+#define MX25_PAD_A19__FEC_RX_ER		IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL)
 #define MX25_PAD_A19__GPIO_2_5		IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_A20__A20		IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A20__GPIO_2_6		IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A20__FEC_RDATA2	IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL)
+#define MX25_PAD_A20__FEC_RDATA2	IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_A21__A21		IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A21__GPIO_2_7		IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A21__FEC_RDATA3	IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL)
+#define MX25_PAD_A21__FEC_RDATA3	IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_A22__A22		IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A22__GPIO_2_8		IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL)
@@ -80,11 +80,11 @@
 
 #define MX25_PAD_A24__A24		IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A24__GPIO_2_10		IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A24__FEC_RX_CLK	IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL)
+#define MX25_PAD_A24__FEC_RX_CLK	IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_A25__A25		IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_A25__GPIO_2_11		IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_A25__FEC_CRS		IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL)
+#define MX25_PAD_A25__FEC_CRS		IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_EB0__EB0		IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_EB0__AUD4_TXD		IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL)
@@ -112,7 +112,7 @@
 #define MX25_PAD_CS5__UART5_RTS		IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS5__GPIO_3_21		IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_NF_CE0__NF_CE0		IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_NF_CE0__NF_CE0		IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_NF_CE0__GPIO_3_22	IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_ECB__ECB		IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL)
@@ -229,28 +229,28 @@
 #define MX25_PAD_LD7__GPIO_1_21		IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_LD8__LD8		IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD8__FEC_TX_ERR	IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_LD8__FEC_TX_ERR	IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_LD9__LD9		IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD9__FEC_COL		IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL)
+#define MX25_PAD_LD9__FEC_COL		IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_LD10__LD10		IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD10__FEC_RX_ER	IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL)
+#define MX25_PAD_LD10__FEC_RX_ER	IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_LD11__LD11		IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD11__FEC_RDATA2	IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL)
+#define MX25_PAD_LD11__FEC_RDATA2	IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_LD12__LD12		IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD12__FEC_RDATA3	IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL)
+#define MX25_PAD_LD12__FEC_RDATA3	IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_LD13__LD13		IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD13__FEC_TDATA2	IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_LD13__FEC_TDATA2	IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_LD14__LD14		IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD14__FEC_TDATA3	IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_LD14__FEC_TDATA3	IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_LD15__LD15		IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_LD15__FEC_RX_CLK	IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL)
+#define MX25_PAD_LD15__FEC_RX_CLK	IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_HSYNC__HSYNC		IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_HSYNC__GPIO_1_22	IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL)
@@ -265,7 +265,7 @@
 #define MX25_PAD_OE_ACD__GPIO_1_25	IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_CONTRAST__CONTRAST	IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_CONTRAST__FEC_CRS	IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL)
+#define MX25_PAD_CONTRAST__FEC_CRS	IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_PWM__PWM		IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_PWM__GPIO_1_26		IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL)
@@ -354,19 +354,19 @@
 #define MX25_PAD_UART2_TXD__GPIO_4_27	IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_UART2_RTS__UART2_RTS	IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_UART2_RTS__FEC_COL	IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL)
+#define MX25_PAD_UART2_RTS__FEC_COL	IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL)
 #define MX25_PAD_UART2_RTS__GPIO_4_28	IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_UART2_CTS__FEC_RX_ER	IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL)
+#define MX25_PAD_UART2_CTS__FEC_RX_ER	IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL)
 #define MX25_PAD_UART2_CTS__UART2_CTS	IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_UART2_CTS__GPIO_4_29	IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_SD1_CMD__SD1_CMD	IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
-#define MX25_PAD_SD1_CMD__FEC_RDATA2	IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_CMD__FEC_RDATA2	IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CMD__GPIO_2_23	IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_SD1_CLK__SD1_CLK	IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
-#define MX25_PAD_SD1_CLK__FEC_RDATA3	IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_CLK__FEC_RDATA3	IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_CLK__GPIO_2_24	IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_SD1_DATA0__SD1_DATA0	IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
@@ -377,11 +377,11 @@
 #define MX25_PAD_SD1_DATA1__GPIO_2_26	IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_SD1_DATA2__SD1_DATA2	IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
-#define MX25_PAD_SD1_DATA2__FEC_RX_CLK	IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK	IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA2__GPIO_2_27	IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_SD1_DATA3__SD1_DATA3	IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
-#define MX25_PAD_SD1_DATA3__FEC_CRS	IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_DATA3__FEC_CRS	IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL)
 #define MX25_PAD_SD1_DATA3__GPIO_2_28	IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_KPP_ROW0__KPP_ROW0	IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE)
@@ -410,7 +410,7 @@
 #define MX25_PAD_KPP_COL3__KPP_COL3	IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
 #define MX25_PAD_KPP_COL3__GPIO_3_4	IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_MDC__FEC_MDC	IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_MDC__FEC_MDC	IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_FEC_MDC__AUD4_TXD	IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
 #define MX25_PAD_FEC_MDC__GPIO_3_5	IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL)
 
@@ -418,23 +418,23 @@
 #define MX25_PAD_FEC_MDIO__AUD4_RXD	IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL)
 #define MX25_PAD_FEC_MDIO__GPIO_3_6	IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_TDATA0__FEC_TDATA0	IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0	IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_FEC_TDATA0__GPIO_3_7	IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_TDATA1__FEC_TDATA1	IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1	IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_FEC_TDATA1__AUD4_TXFS	IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL)
 #define MX25_PAD_FEC_TDATA1__GPIO_3_8	IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_TX_EN__FEC_TX_EN	IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN	IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_FEC_TX_EN__GPIO_3_9   	IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_RDATA0__FEC_RDATA0	IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0	IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
 #define MX25_PAD_FEC_RDATA0__GPIO_3_10	IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_RDATA1__FEC_RDATA1	IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1	IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
 #define MX25_PAD_FEC_RDATA1__GPIO_3_11	IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_FEC_RX_DV__FEC_RX_DV	IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV	IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
 #define MX25_PAD_FEC_RX_DV__CAN2_RX	IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP)
 #define MX25_PAD_FEC_RX_DV__GPIO_3_12	IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx35.h	2010-02-24 13:52:17.000000000 -0500
@@ -671,7 +671,7 @@
 #define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8			IOMUX_PAD(0x634, 0x1d0, 6, 0x0,   0, NO_PAD_CTRL)
 
 #define MX35_PAD_LD9__IPU_DISPB_DAT_9				IOMUX_PAD(0x638, 0x1d4, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX35_PAD_LD9__GPIO2_9					IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4  0, NO_PAD_CTRL)
+#define MX35_PAD_LD9__GPIO2_9					IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4, 0, NO_PAD_CTRL)
 #define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9			IOMUX_PAD(0x638, 0x1d4, 6, 0x0,   0, NO_PAD_CTRL)
 
 #define MX35_PAD_LD10__IPU_DISPB_DAT_10				IOMUX_PAD(0x63c, 0x1d8, 0, 0x0,   0, NO_PAD_CTRL)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2010-02-24 13:52:17.000000000 -0500
@@ -112,7 +112,7 @@ enum iomux_gp_func {
  * setups a single pin:
  * 	- reserves the pin so that it is not claimed by another driver
  * 	- setups the iomux according to the configuration
- * 	- if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
  */
 int mxc_iomux_alloc_pin(const unsigned int pin, const char *label);
 /*
@@ -524,10 +524,18 @@ enum iomux_pins {
 #define MX31_PIN_RTS1__RTS1		IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_TXD1__TXD1		IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_RXD1__RXD1		IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DCE1__DCD_DCE1	IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RI_DCE1__RI_DCE1	IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DSR_DCE1__DSR_DCE1	IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DTR_DCE1__DTR_DCE1	IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_CTS2__CTS2		IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_RTS2__RTS2		IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_TXD2__TXD2		IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_RXD2__RXD2		IOMUX_MODE(MX31_PIN_RXD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DTE1__DCD_DTE2	IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_RI_DTE1__RI_DTE2	IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_DSR_DTE1__DSR_DTE2	IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_DTR_DTE1__DTR_DTE2	IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_OCONFIG_ALT3 | IOMUX_ICONFIG_NONE)
 #define MX31_PIN_PC_RST__CTS5		IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT2)
 #define MX31_PIN_PC_VS2__RTS5		IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT2)
 #define MX31_PIN_PC_BVD2__TXD5		IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT2)
@@ -623,6 +631,8 @@ enum iomux_pins {
 #define MX31_PIN_GPIO3_0__GPIO3_0	IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_GPIO3_1__GPIO3_1	IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_TXD2__GPIO1_28		IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSI_D4__GPIO3_4	IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSI_D5__GPIO3_5	IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0    IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1    IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2    IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
@@ -642,12 +652,22 @@ enum iomux_pins {
 #define MX31_PIN_CSPI1_SS2__USBH1_RCV          IOMUX_MODE(MX31_PIN_CSPI1_SS2,  IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CSPI1_SCLK__USBH1_OEB         IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS       IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_SFS6__USBH1_SUSPEND	IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_NFRE_B__GPIO1_11	IOMUX_MODE(MX31_PIN_NFRE_B, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_NFALE__GPIO1_12	IOMUX_MODE(MX31_PIN_NFALE, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_USBH2_DATA0__USBH2_DATA0      IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBH2_DATA1__USBH2_DATA1      IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD3__USBH2_DATA2	IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD3__USBH2_DATA3	IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK3__USBH2_DATA4	IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS3__USBH2_DATA5	IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD6__USBH2_DATA6	IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD6__USBH2_DATA7	IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBH2_CLK__USBH2_CLK          IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBH2_DIR__USBH2_DIR          IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBH2_NXT__USBH2_NXT          IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBH2_STP__USBH2_STP          IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK6__GPIO1_25		IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_USB_OC__GPIO1_30	IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_I2C_DAT__I2C1_SDA	IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_I2C_CLK__I2C1_SCL	IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
@@ -693,7 +713,19 @@ enum iomux_pins {
 #define MX31_PIN_DCD_DCE1__GPIO2_11	IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_STXD5__GPIO1_21       IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_SRXD5__GPIO1_22       IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
-
+#define MX31_PIN_GPIO1_3__GPIO1_3	IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSPI2_SS1__CSPI3_SS1	IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_RTS1__GPIO2_6		IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CTS1__GPIO2_7		IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_LCS0__GPIO3_23		IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD4__STXD4		IOMUX_MODE(MX31_PIN_STXD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD4__SRXD4		IOMUX_MODE(MX31_PIN_SRXD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK4__SCK4		IOMUX_MODE(MX31_PIN_SCK4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS4__SFS4		IOMUX_MODE(MX31_PIN_SFS4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD5__STXD5		IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD5__SRXD5		IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK5__SCK5		IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS5__SFS5		IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC)
 
 /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
  * cspi1_ss1*/
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,7 @@
  * setups a single pin:
  * 	- reserves the pin so that it is not claimed by another driver
  * 	- setups the iomux according to the configuration
- * 	- if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
  */
 int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label);
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2010-02-24 13:52:17.000000000 -0500
@@ -88,9 +88,7 @@ struct pad_desc {
 #define PAD_CTL_SRE_FAST		(1 << 0)
 
 /*
- * setups a single pad:
- * 	- reserves the pad so that it is not claimed by another driver
- * 	- setups the iomux according to the configuration
+ * setups a single pad in the iomuxer
  */
 int mxc_iomux_v3_setup_pad(struct pad_desc *pad);
 
@@ -101,19 +99,6 @@ int mxc_iomux_v3_setup_pad(struct pad_de
 int mxc_iomux_v3_setup_multiple_pads(struct pad_desc *pad_list, unsigned count);
 
 /*
- * releases a single pad:
- * 	- make it available for a future use by another driver
- * 	- DOES NOT reconfigure the IOMUX in its reset state
- */
-void mxc_iomux_v3_release_pad(struct pad_desc *pad);
-
-/*
- * releases multiple pads
- * convenvient way to call the above function with tables
- */
-void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count);
-
-/*
  * Initialise the iomux controller
  */
 void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,7 +37,12 @@
  * within sensible limits.
  */
 #define MXC_BOARD_IRQ_START	(MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#define MXC_BOARD_IRQS  80
+#else
 #define MXC_BOARD_IRQS	16
+#endif
 
 #define MXC_IPU_IRQ_START	(MXC_BOARD_IRQ_START + MXC_BOARD_IRQS)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx21.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,46 +25,191 @@
 #ifndef __ASM_ARCH_MXC_MX21_H__
 #define __ASM_ARCH_MXC_MX21_H__
 
+#define MX21_AIPI_BASE_ADDR		0x10000000
+#define MX21_AIPI_BASE_ADDR_VIRT	0xf4000000
+#define MX21_AIPI_SIZE			SZ_1M
+#define MX21_DMA_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x01000)
+#define MX21_WDOG_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x02000)
+#define MX21_GPT1_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x03000)
+#define MX21_GPT2_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x04000)
+#define MX21_GPT3_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x05000)
+#define MX21_PWM_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x06000)
+#define MX21_RTC_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x07000)
+#define MX21_KPP_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x08000)
+#define MX21_OWIRE_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x09000)
+#define MX21_UART1_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0a000)
+#define MX21_UART2_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0b000)
+#define MX21_UART3_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0c000)
+#define MX21_UART4_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0d000)
+#define MX21_CSPI1_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0e000)
+#define MX21_CSPI2_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x0f000)
+#define MX21_SSI1_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x10000)
+#define MX21_SSI2_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x11000)
+#define MX21_I2C_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x12000)
+#define MX21_SDHC1_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x13000)
+#define MX21_SDHC2_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x14000)
+#define MX21_GPIO_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x15000)
+#define MX21_AUDMUX_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x16000)
+#define MX21_CSPI3_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x17000)
+#define MX21_LCDC_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x21000)
+#define MX21_SLCDC_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x22000)
+#define MX21_USBOTG_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x24000)
+#define MX21_EMMA_PP_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x26000)
+#define MX21_EMMA_PRP_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x26400)
+#define MX21_CCM_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x27000)
+#define MX21_SYSCTRL_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x27800)
+#define MX21_JAM_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x3e000)
+#define MX21_MAX_BASE_ADDR			(MX21_AIPI_BASE_ADDR + 0x3f000)
+
+#define MX21_AVIC_BASE_ADDR		0x10040000
+
+#define MX21_SAHB1_BASE_ADDR		0x80000000
+#define MX21_SAHB1_BASE_ADDR_VIRT	0xf4100000
+#define MX21_SAHB1_SIZE			SZ_1M
+#define MX21_CSI_BASE_ADDR			(MX2x_SAHB1_BASE_ADDR + 0x0000)
+
 /* Memory regions and CS */
-#define SDRAM_BASE_ADDR         0xC0000000
-#define CSD1_BASE_ADDR          0xC4000000
+#define MX21_SDRAM_BASE_ADDR		0xc0000000
+#define MX21_CSD1_BASE_ADDR		0xc4000000
 
-#define CS0_BASE_ADDR           0xC8000000
-#define CS1_BASE_ADDR           0xCC000000
-#define CS2_BASE_ADDR           0xD0000000
-#define CS3_BASE_ADDR           0xD1000000
-#define CS4_BASE_ADDR           0xD2000000
-#define CS5_BASE_ADDR           0xDD000000
-#define PCMCIA_MEM_BASE_ADDR    0xD4000000
+#define MX21_CS0_BASE_ADDR		0xc8000000
+#define MX21_CS1_BASE_ADDR		0xcc000000
+#define MX21_CS2_BASE_ADDR		0xd0000000
+#define MX21_CS3_BASE_ADDR		0xd1000000
+#define MX21_CS4_BASE_ADDR		0xd2000000
+#define MX21_PCMCIA_MEM_BASE_ADDR	0xd4000000
+#define MX21_CS5_BASE_ADDR		0xdd000000
 
 /* NAND, SDRAM, WEIM etc controllers */
-#define X_MEMC_BASE_ADDR        0xDF000000
-#define X_MEMC_BASE_ADDR_VIRT   0xF4200000
-#define X_MEMC_SIZE             SZ_256K
+#define MX21_X_MEMC_BASE_ADDR		0xdf000000
+#define MX21_X_MEMC_BASE_ADDR_VIRT	0xf4200000
+#define MX21_X_MEMC_SIZE		SZ_256K
 
-#define SDRAMC_BASE_ADDR        (X_MEMC_BASE_ADDR + 0x0000)
-#define EIM_BASE_ADDR           (X_MEMC_BASE_ADDR + 0x1000)
-#define PCMCIA_CTL_BASE_ADDR    (X_MEMC_BASE_ADDR + 0x2000)
-#define NFC_BASE_ADDR           (X_MEMC_BASE_ADDR + 0x3000)
+#define MX21_SDRAMC_BASE_ADDR		(MX21_X_MEMC_BASE_ADDR + 0x0000)
+#define MX21_EIM_BASE_ADDR		(MX21_X_MEMC_BASE_ADDR + 0x1000)
+#define MX21_PCMCIA_CTL_BASE_ADDR	(MX21_X_MEMC_BASE_ADDR + 0x2000)
+#define MX21_NFC_BASE_ADDR		(MX21_X_MEMC_BASE_ADDR + 0x3000)
 
-#define IRAM_BASE_ADDR          0xFFFFE800	/* internal ram */
+#define MX21_IRAM_BASE_ADDR		0xffffe800	/* internal ram */
 
 /* fixed interrupt numbers */
-#define MXC_INT_USBCTRL         58
-#define MXC_INT_USBCTRL         58
-#define MXC_INT_USBMNP          57
-#define MXC_INT_USBFUNC         56
-#define MXC_INT_USBHOST         55
-#define MXC_INT_USBDMA          54
-#define MXC_INT_USBWKUP         53
-#define MXC_INT_EMMADEC         50
-#define MXC_INT_EMMAENC         49
-#define MXC_INT_BMI             30
-#define MXC_INT_FIRI            9
+#define MX21_INT_CSPI3		6
+#define MX21_INT_GPIO		8
+#define MX21_INT_FIRI		9
+#define MX21_INT_SDHC2		10
+#define MX21_INT_SDHC1		11
+#define MX21_INT_I2C		12
+#define MX21_INT_SSI2		13
+#define MX21_INT_SSI1		14
+#define MX21_INT_CSPI2		15
+#define MX21_INT_CSPI1		16
+#define MX21_INT_UART4		17
+#define MX21_INT_UART3		18
+#define MX21_INT_UART2		19
+#define MX21_INT_UART1		20
+#define MX21_INT_KPP		21
+#define MX21_INT_RTC		22
+#define MX21_INT_PWM		23
+#define MX21_INT_GPT3		24
+#define MX21_INT_GPT2		25
+#define MX21_INT_GPT1		26
+#define MX21_INT_WDOG		27
+#define MX21_INT_PCMCIA		28
+#define MX21_INT_NANDFC		29
+#define MX21_INT_BMI		30
+#define MX21_INT_CSI		31
+#define MX21_INT_DMACH0		32
+#define MX21_INT_DMACH1		33
+#define MX21_INT_DMACH2		34
+#define MX21_INT_DMACH3		35
+#define MX21_INT_DMACH4		36
+#define MX21_INT_DMACH5		37
+#define MX21_INT_DMACH6		38
+#define MX21_INT_DMACH7		39
+#define MX21_INT_DMACH8		40
+#define MX21_INT_DMACH9		41
+#define MX21_INT_DMACH10	42
+#define MX21_INT_DMACH11	43
+#define MX21_INT_DMACH12	44
+#define MX21_INT_DMACH13	45
+#define MX21_INT_DMACH14	46
+#define MX21_INT_DMACH15	47
+#define MX21_INT_EMMAENC	49
+#define MX21_INT_EMMADEC	50
+#define MX21_INT_EMMAPRP	51
+#define MX21_INT_EMMAPP		52
+#define MX21_INT_USBWKUP	53
+#define MX21_INT_USBDMA		54
+#define MX21_INT_USBHOST	55
+#define MX21_INT_USBFUNC	56
+#define MX21_INT_USBMNP		57
+#define MX21_INT_USBCTRL	58
+#define MX21_INT_SLCDC		60
+#define MX21_INT_LCDC		61
 
 /* fixed DMA request numbers */
-#define DMA_REQ_BMI_RX          29
-#define DMA_REQ_BMI_TX          28
-#define DMA_REQ_FIRI_RX         4
+#define MX21_DMA_REQ_CSPI3_RX	1
+#define MX21_DMA_REQ_CSPI3_TX	2
+#define MX21_DMA_REQ_EXT	3
+#define MX21_DMA_REQ_FIRI_RX	4
+#define MX21_DMA_REQ_SDHC2	6
+#define MX21_DMA_REQ_SDHC1	7
+#define MX21_DMA_REQ_SSI2_RX0	8
+#define MX21_DMA_REQ_SSI2_TX0	9
+#define MX21_DMA_REQ_SSI2_RX1	10
+#define MX21_DMA_REQ_SSI2_TX1	11
+#define MX21_DMA_REQ_SSI1_RX0	12
+#define MX21_DMA_REQ_SSI1_TX0	13
+#define MX21_DMA_REQ_SSI1_RX1	14
+#define MX21_DMA_REQ_SSI1_TX1	15
+#define MX21_DMA_REQ_CSPI2_RX	16
+#define MX21_DMA_REQ_CSPI2_TX	17
+#define MX21_DMA_REQ_CSPI1_RX	18
+#define MX21_DMA_REQ_CSPI1_TX	19
+#define MX21_DMA_REQ_UART4_RX	20
+#define MX21_DMA_REQ_UART4_TX	21
+#define MX21_DMA_REQ_UART3_RX	22
+#define MX21_DMA_REQ_UART3_TX	23
+#define MX21_DMA_REQ_UART2_RX	24
+#define MX21_DMA_REQ_UART2_TX	25
+#define MX21_DMA_REQ_UART1_RX	26
+#define MX21_DMA_REQ_UART1_TX	27
+#define MX21_DMA_REQ_BMI_TX	28
+#define MX21_DMA_REQ_BMI_RX	29
+#define MX21_DMA_REQ_CSI_STAT	30
+#define MX21_DMA_REQ_CSI_RX	31
+
+/* these should go away */
+#define SDRAM_BASE_ADDR MX21_SDRAM_BASE_ADDR
+#define CSD1_BASE_ADDR MX21_CSD1_BASE_ADDR
+#define CS0_BASE_ADDR MX21_CS0_BASE_ADDR
+#define CS1_BASE_ADDR MX21_CS1_BASE_ADDR
+#define CS2_BASE_ADDR MX21_CS2_BASE_ADDR
+#define CS3_BASE_ADDR MX21_CS3_BASE_ADDR
+#define CS4_BASE_ADDR MX21_CS4_BASE_ADDR
+#define PCMCIA_MEM_BASE_ADDR MX21_PCMCIA_MEM_BASE_ADDR
+#define CS5_BASE_ADDR MX21_CS5_BASE_ADDR
+#define X_MEMC_BASE_ADDR MX21_X_MEMC_BASE_ADDR
+#define X_MEMC_BASE_ADDR_VIRT MX21_X_MEMC_BASE_ADDR_VIRT
+#define X_MEMC_SIZE MX21_X_MEMC_SIZE
+#define SDRAMC_BASE_ADDR MX21_SDRAMC_BASE_ADDR
+#define EIM_BASE_ADDR MX21_EIM_BASE_ADDR
+#define PCMCIA_CTL_BASE_ADDR MX21_PCMCIA_CTL_BASE_ADDR
+#define NFC_BASE_ADDR MX21_NFC_BASE_ADDR
+#define IRAM_BASE_ADDR MX21_IRAM_BASE_ADDR
+#define MXC_INT_FIRI MX21_INT_FIRI
+#define MXC_INT_BMI MX21_INT_BMI
+#define MXC_INT_EMMAENC MX21_INT_EMMAENC
+#define MXC_INT_EMMADEC MX21_INT_EMMADEC
+#define MXC_INT_USBWKUP MX21_INT_USBWKUP
+#define MXC_INT_USBDMA MX21_INT_USBDMA
+#define MXC_INT_USBHOST MX21_INT_USBHOST
+#define MXC_INT_USBFUNC MX21_INT_USBFUNC
+#define MXC_INT_USBMNP MX21_INT_USBMNP
+#define MXC_INT_USBCTRL MX21_INT_USBCTRL
+#define MXC_INT_USBCTRL MX21_INT_USBCTRL
+#define DMA_REQ_FIRI_RX MX21_DMA_REQ_FIRI_RX
+#define DMA_REQ_BMI_TX MX21_DMA_REQ_BMI_TX
+#define DMA_REQ_BMI_RX MX21_DMA_REQ_BMI_RX
 
 #endif /* __ASM_ARCH_MXC_MX21_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx25.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx25.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx25.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx25.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #ifndef __MACH_MX25_H__
 #define __MACH_MX25_H__
 
-#define MX25_AIPS1_BASE_ADDR		0x43F00000
-#define MX25_AIPS1_BASE_ADDR_VIRT	0xFC000000
+#define MX25_AIPS1_BASE_ADDR		0x43f00000
+#define MX25_AIPS1_BASE_ADDR_VIRT	0xfc000000
 #define MX25_AIPS1_SIZE			SZ_1M
-#define MX25_AIPS2_BASE_ADDR		0x53F00000
-#define MX25_AIPS2_BASE_ADDR_VIRT	0xFC200000
+#define MX25_AIPS2_BASE_ADDR		0x53f00000
+#define MX25_AIPS2_BASE_ADDR_VIRT	0xfc200000
 #define MX25_AIPS2_SIZE			SZ_1M
 #define MX25_AVIC_BASE_ADDR		0x68000000
-#define MX25_AVIC_BASE_ADDR_VIRT	0xFC400000
+#define MX25_AVIC_BASE_ADDR_VIRT	0xfc400000
 #define MX25_AVIC_SIZE			SZ_1M
 
 #define MX25_IOMUXC_BASE_ADDR		(MX25_AIPS1_BASE_ADDR + 0xac000)
@@ -41,4 +41,8 @@
 #define UART1_BASE_ADDR			0x43f90000
 #define UART2_BASE_ADDR			0x43f94000
 
+#define MX25_FEC_BASE_ADDR		0x50038000
+
+#define MX25_INT_FEC	57
+
 #endif /* __MACH_MX25_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx27.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx27.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,87 +24,198 @@
 #ifndef __ASM_ARCH_MXC_MX27_H__
 #define __ASM_ARCH_MXC_MX27_H__
 
-/* IRAM */
-#define IRAM_BASE_ADDR          0xFFFF4C00	/* internal ram */
+#define MX27_AIPI_BASE_ADDR		0x10000000
+#define MX27_AIPI_BASE_ADDR_VIRT	0xf4000000
+#define MX27_AIPI_SIZE			SZ_1M
+#define MX27_DMA_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x01000)
+#define MX27_WDOG_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x02000)
+#define MX27_GPT1_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x03000)
+#define MX27_GPT2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x04000)
+#define MX27_GPT3_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x05000)
+#define MX27_PWM_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x06000)
+#define MX27_RTC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x07000)
+#define MX27_KPP_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x08000)
+#define MX27_OWIRE_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x09000)
+#define MX27_UART1_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0a000)
+#define MX27_UART2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0b000)
+#define MX27_UART3_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0c000)
+#define MX27_UART4_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0d000)
+#define MX27_CSPI1_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0e000)
+#define MX27_CSPI2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x0f000)
+#define MX27_SSI1_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x10000)
+#define MX27_SSI2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x11000)
+#define MX27_I2C_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x12000)
+#define MX27_SDHC1_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x13000)
+#define MX27_SDHC2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x14000)
+#define MX27_GPIO_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x15000)
+#define MX27_AUDMUX_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x16000)
+#define MX27_CSPI3_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x17000)
+#define MX27_MSHC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x18000)
+#define MX27_GPT5_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x19000)
+#define MX27_GPT4_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1a000)
+#define MX27_UART5_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1b000)
+#define MX27_UART6_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1c000)
+#define MX27_I2C2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1d000)
+#define MX27_SDHC3_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1e000)
+#define MX27_GPT6_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1f000)
+#define MX27_LCDC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x21000)
+#define MX27_SLCDC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x22000)
+#define MX27_VPU_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x23000)
+#define MX27_USBOTG_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x24000)
+#define MX27_OTG_BASE_ADDR			MX27_USBOTG_BASE_ADDR
+#define MX27_SAHARA_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x25000)
+#define MX27_EMMA_PP_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x26000)
+#define MX27_EMMA_PRP_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x26400)
+#define MX27_CCM_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x27000)
+#define MX27_SYSCTRL_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x27800)
+#define MX27_IIM_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x28000)
+#define MX27_RTIC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x2a000)
+#define MX27_FEC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x2b000)
+#define MX27_SCC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x2c000)
+#define MX27_ETB_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x3b000)
+#define MX27_ETB_RAM_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x3c000)
+#define MX27_JAM_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x3e000)
+#define MX27_MAX_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x3f000)
 
-#define MSHC_BASE_ADDR          (AIPI_BASE_ADDR + 0x18000)
-#define GPT5_BASE_ADDR          (AIPI_BASE_ADDR + 0x19000)
-#define GPT4_BASE_ADDR          (AIPI_BASE_ADDR + 0x1A000)
-#define UART5_BASE_ADDR         (AIPI_BASE_ADDR + 0x1B000)
-#define UART6_BASE_ADDR         (AIPI_BASE_ADDR + 0x1C000)
-#define I2C2_BASE_ADDR          (AIPI_BASE_ADDR + 0x1D000)
-#define SDHC3_BASE_ADDR         (AIPI_BASE_ADDR + 0x1E000)
-#define GPT6_BASE_ADDR          (AIPI_BASE_ADDR + 0x1F000)
-#define VPU_BASE_ADDR           (AIPI_BASE_ADDR + 0x23000)
-#define OTG_BASE_ADDR           USBOTG_BASE_ADDR
-#define SAHARA_BASE_ADDR        (AIPI_BASE_ADDR + 0x25000)
-#define IIM_BASE_ADDR           (AIPI_BASE_ADDR + 0x28000)
-#define RTIC_BASE_ADDR          (AIPI_BASE_ADDR + 0x2A000)
-#define FEC_BASE_ADDR           (AIPI_BASE_ADDR + 0x2B000)
-#define SCC_BASE_ADDR           (AIPI_BASE_ADDR + 0x2C000)
-#define ETB_BASE_ADDR           (AIPI_BASE_ADDR + 0x3B000)
-#define ETB_RAM_BASE_ADDR       (AIPI_BASE_ADDR + 0x3C000)
+#define MX27_AVIC_BASE_ADDR		0x10040000
 
 /* ROM patch */
-#define ROMP_BASE_ADDR          0x10041000
+#define MX27_ROMP_BASE_ADDR		0x10041000
 
-#define ATA_BASE_ADDR           (SAHB1_BASE_ADDR + 0x1000)
+#define MX27_SAHB1_BASE_ADDR		0x80000000
+#define MX27_SAHB1_BASE_ADDR_VIRT	0xf4100000
+#define MX27_SAHB1_SIZE			SZ_1M
+#define MX27_CSI_BASE_ADDR			(MX27_SAHB1_BASE_ADDR + 0x0000)
+#define MX27_ATA_BASE_ADDR			(MX27_SAHB1_BASE_ADDR + 0x1000)
 
 /* Memory regions and CS */
-#define SDRAM_BASE_ADDR         0xA0000000
-#define CSD1_BASE_ADDR          0xB0000000
+#define MX27_SDRAM_BASE_ADDR		0xa0000000
+#define MX27_CSD1_BASE_ADDR		0xb0000000
 
-#define CS0_BASE_ADDR           0xC0000000
-#define CS1_BASE_ADDR           0xC8000000
-#define CS2_BASE_ADDR           0xD0000000
-#define CS3_BASE_ADDR           0xD2000000
-#define CS4_BASE_ADDR           0xD4000000
-#define CS5_BASE_ADDR           0xD6000000
-#define PCMCIA_MEM_BASE_ADDR    0xDC000000
+#define MX27_CS0_BASE_ADDR		0xc0000000
+#define MX27_CS1_BASE_ADDR		0xc8000000
+#define MX27_CS2_BASE_ADDR		0xd0000000
+#define MX27_CS3_BASE_ADDR		0xd2000000
+#define MX27_CS4_BASE_ADDR		0xd4000000
+#define MX27_CS5_BASE_ADDR		0xd6000000
 
 /* NAND, SDRAM, WEIM, M3IF, EMI controllers */
-#define X_MEMC_BASE_ADDR        0xD8000000
-#define X_MEMC_BASE_ADDR_VIRT   0xF4200000
-#define X_MEMC_SIZE             SZ_1M
+#define MX27_X_MEMC_BASE_ADDR		0xd8000000
+#define MX27_X_MEMC_BASE_ADDR_VIRT	0xf4200000
+#define MX27_X_MEMC_SIZE		SZ_1M
+#define MX27_NFC_BASE_ADDR			(MX27_X_MEMC_BASE_ADDR)
+#define MX27_SDRAMC_BASE_ADDR			(MX27_X_MEMC_BASE_ADDR + 0x1000)
+#define MX27_WEIM_BASE_ADDR			(MX27_X_MEMC_BASE_ADDR + 0x2000)
+#define MX27_M3IF_BASE_ADDR			(MX27_X_MEMC_BASE_ADDR + 0x3000)
+#define MX27_PCMCIA_CTL_BASE_ADDR		(MX27_X_MEMC_BASE_ADDR + 0x4000)
 
-#define NFC_BASE_ADDR           (X_MEMC_BASE_ADDR)
-#define SDRAMC_BASE_ADDR        (X_MEMC_BASE_ADDR + 0x1000)
-#define WEIM_BASE_ADDR          (X_MEMC_BASE_ADDR + 0x2000)
-#define M3IF_BASE_ADDR          (X_MEMC_BASE_ADDR + 0x3000)
-#define PCMCIA_CTL_BASE_ADDR    (X_MEMC_BASE_ADDR + 0x4000)
+#define MX27_PCMCIA_MEM_BASE_ADDR	0xdc000000
+
+/* IRAM */
+#define MX27_IRAM_BASE_ADDR		0xffff4c00	/* internal ram */
 
 /* fixed interrupt numbers */
-#define MXC_INT_CCM		63
-#define MXC_INT_IIM		62
-#define MXC_INT_SAHARA		59
-#define MXC_INT_SCC_SCM		58
-#define MXC_INT_SCC_SMN		57
-#define MXC_INT_USB3		56
-#define MXC_INT_USB2		55
-#define MXC_INT_USB1		54
-#define MXC_INT_VPU		53
-#define MXC_INT_FEC		50
-#define MXC_INT_UART5		49
-#define MXC_INT_UART6		48
-#define MXC_INT_ATA		30
-#define MXC_INT_SDHC3		9
-#define MXC_INT_SDHC		7
-#define MXC_INT_RTIC		5
-#define MXC_INT_GPT4		4
-#define MXC_INT_GPT5		3
-#define MXC_INT_GPT6		2
-#define MXC_INT_I2C2		1
+#define MX27_INT_I2C2		1
+#define MX27_INT_GPT6		2
+#define MX27_INT_GPT5		3
+#define MX27_INT_GPT4		4
+#define MX27_INT_RTIC		5
+#define MX27_INT_CSPI3		6
+#define MX27_INT_SDHC		7
+#define MX27_INT_GPIO		8
+#define MX27_INT_SDHC3		9
+#define MX27_INT_SDHC2		10
+#define MX27_INT_SDHC1		11
+#define MX27_INT_I2C		12
+#define MX27_INT_SSI2		13
+#define MX27_INT_SSI1		14
+#define MX27_INT_CSPI2		15
+#define MX27_INT_CSPI1		16
+#define MX27_INT_UART4		17
+#define MX27_INT_UART3		18
+#define MX27_INT_UART2		19
+#define MX27_INT_UART1		20
+#define MX27_INT_KPP		21
+#define MX27_INT_RTC		22
+#define MX27_INT_PWM		23
+#define MX27_INT_GPT3		24
+#define MX27_INT_GPT2		25
+#define MX27_INT_GPT1		26
+#define MX27_INT_WDOG		27
+#define MX27_INT_PCMCIA		28
+#define MX27_INT_NANDFC		29
+#define MX27_INT_ATA		30
+#define MX27_INT_CSI		31
+#define MX27_INT_DMACH0		32
+#define MX27_INT_DMACH1		33
+#define MX27_INT_DMACH2		34
+#define MX27_INT_DMACH3		35
+#define MX27_INT_DMACH4		36
+#define MX27_INT_DMACH5		37
+#define MX27_INT_DMACH6		38
+#define MX27_INT_DMACH7		39
+#define MX27_INT_DMACH8		40
+#define MX27_INT_DMACH9		41
+#define MX27_INT_DMACH10	42
+#define MX27_INT_DMACH11	43
+#define MX27_INT_DMACH12	44
+#define MX27_INT_DMACH13	45
+#define MX27_INT_DMACH14	46
+#define MX27_INT_DMACH15	47
+#define MX27_INT_UART6		48
+#define MX27_INT_UART5		49
+#define MX27_INT_FEC		50
+#define MX27_INT_EMMAPRP	51
+#define MX27_INT_EMMAPP		52
+#define MX27_INT_VPU		53
+#define MX27_INT_USB1		54
+#define MX27_INT_USB2		55
+#define MX27_INT_USB3		56
+#define MX27_INT_SCC_SMN	57
+#define MX27_INT_SCC_SCM	58
+#define MX27_INT_SAHARA		59
+#define MX27_INT_SLCDC		60
+#define MX27_INT_LCDC		61
+#define MX27_INT_IIM		62
+#define MX27_INT_CCM		63
 
 /* fixed DMA request numbers */
-#define DMA_REQ_NFC             37
-#define DMA_REQ_SDHC3           36
-#define DMA_REQ_UART6_RX        35
-#define DMA_REQ_UART6_TX        34
-#define DMA_REQ_UART5_RX        33
-#define DMA_REQ_UART5_TX        32
-#define DMA_REQ_ATA_RCV         29
-#define DMA_REQ_ATA_TX          28
-#define DMA_REQ_MSHC            4
+#define MX27_DMA_REQ_CSPI3_RX	1
+#define MX27_DMA_REQ_CSPI3_TX	2
+#define MX27_DMA_REQ_EXT	3
+#define MX27_DMA_REQ_MSHC	4
+#define MX27_DMA_REQ_SDHC2	6
+#define MX27_DMA_REQ_SDHC1	7
+#define MX27_DMA_REQ_SSI2_RX0	8
+#define MX27_DMA_REQ_SSI2_TX0	9
+#define MX27_DMA_REQ_SSI2_RX1	10
+#define MX27_DMA_REQ_SSI2_TX1	11
+#define MX27_DMA_REQ_SSI1_RX0	12
+#define MX27_DMA_REQ_SSI1_TX0	13
+#define MX27_DMA_REQ_SSI1_RX1	14
+#define MX27_DMA_REQ_SSI1_TX1	15
+#define MX27_DMA_REQ_CSPI2_RX	16
+#define MX27_DMA_REQ_CSPI2_TX	17
+#define MX27_DMA_REQ_CSPI1_RX	18
+#define MX27_DMA_REQ_CSPI1_TX	19
+#define MX27_DMA_REQ_UART4_RX	20
+#define MX27_DMA_REQ_UART4_TX	21
+#define MX27_DMA_REQ_UART3_RX	22
+#define MX27_DMA_REQ_UART3_TX	23
+#define MX27_DMA_REQ_UART2_RX	24
+#define MX27_DMA_REQ_UART2_TX	25
+#define MX27_DMA_REQ_UART1_RX	26
+#define MX27_DMA_REQ_UART1_TX	27
+#define MX27_DMA_REQ_ATA_TX	28
+#define MX27_DMA_REQ_ATA_RCV	29
+#define MX27_DMA_REQ_CSI_STAT	30
+#define MX27_DMA_REQ_CSI_RX	31
+#define MX27_DMA_REQ_UART5_TX	32
+#define MX27_DMA_REQ_UART5_RX	33
+#define MX27_DMA_REQ_UART6_TX	34
+#define MX27_DMA_REQ_UART6_RX	35
+#define MX27_DMA_REQ_SDHC3	36
+#define MX27_DMA_REQ_NFC	37
 
 /* silicon revisions specific to i.MX27 */
 #define CHIP_REV_1_0		0x00
@@ -114,6 +225,72 @@
 extern int mx27_revision(void);
 #endif
 
-/* Mandatory defines used globally */
+/* these should go away */
+#define MSHC_BASE_ADDR MX27_MSHC_BASE_ADDR
+#define GPT5_BASE_ADDR MX27_GPT5_BASE_ADDR
+#define GPT4_BASE_ADDR MX27_GPT4_BASE_ADDR
+#define UART5_BASE_ADDR MX27_UART5_BASE_ADDR
+#define UART6_BASE_ADDR MX27_UART6_BASE_ADDR
+#define I2C2_BASE_ADDR MX27_I2C2_BASE_ADDR
+#define SDHC3_BASE_ADDR MX27_SDHC3_BASE_ADDR
+#define GPT6_BASE_ADDR MX27_GPT6_BASE_ADDR
+#define VPU_BASE_ADDR MX27_VPU_BASE_ADDR
+#define OTG_BASE_ADDR MX27_OTG_BASE_ADDR
+#define SAHARA_BASE_ADDR MX27_SAHARA_BASE_ADDR
+#define IIM_BASE_ADDR MX27_IIM_BASE_ADDR
+#define RTIC_BASE_ADDR MX27_RTIC_BASE_ADDR
+#define FEC_BASE_ADDR MX27_FEC_BASE_ADDR
+#define SCC_BASE_ADDR MX27_SCC_BASE_ADDR
+#define ETB_BASE_ADDR MX27_ETB_BASE_ADDR
+#define ETB_RAM_BASE_ADDR MX27_ETB_RAM_BASE_ADDR
+#define ROMP_BASE_ADDR MX27_ROMP_BASE_ADDR
+#define ATA_BASE_ADDR MX27_ATA_BASE_ADDR
+#define SDRAM_BASE_ADDR MX27_SDRAM_BASE_ADDR
+#define CSD1_BASE_ADDR MX27_CSD1_BASE_ADDR
+#define CS0_BASE_ADDR MX27_CS0_BASE_ADDR
+#define CS1_BASE_ADDR MX27_CS1_BASE_ADDR
+#define CS2_BASE_ADDR MX27_CS2_BASE_ADDR
+#define CS3_BASE_ADDR MX27_CS3_BASE_ADDR
+#define CS4_BASE_ADDR MX27_CS4_BASE_ADDR
+#define CS5_BASE_ADDR MX27_CS5_BASE_ADDR
+#define X_MEMC_BASE_ADDR MX27_X_MEMC_BASE_ADDR
+#define X_MEMC_BASE_ADDR_VIRT MX27_X_MEMC_BASE_ADDR_VIRT
+#define X_MEMC_SIZE MX27_X_MEMC_SIZE
+#define NFC_BASE_ADDR MX27_NFC_BASE_ADDR
+#define SDRAMC_BASE_ADDR MX27_SDRAMC_BASE_ADDR
+#define WEIM_BASE_ADDR MX27_WEIM_BASE_ADDR
+#define M3IF_BASE_ADDR MX27_M3IF_BASE_ADDR
+#define PCMCIA_CTL_BASE_ADDR MX27_PCMCIA_CTL_BASE_ADDR
+#define PCMCIA_MEM_BASE_ADDR MX27_PCMCIA_MEM_BASE_ADDR
+#define IRAM_BASE_ADDR MX27_IRAM_BASE_ADDR
+#define MXC_INT_I2C2 MX27_INT_I2C2
+#define MXC_INT_GPT6 MX27_INT_GPT6
+#define MXC_INT_GPT5 MX27_INT_GPT5
+#define MXC_INT_GPT4 MX27_INT_GPT4
+#define MXC_INT_RTIC MX27_INT_RTIC
+#define MXC_INT_SDHC MX27_INT_SDHC
+#define MXC_INT_SDHC3 MX27_INT_SDHC3
+#define MXC_INT_ATA MX27_INT_ATA
+#define MXC_INT_UART6 MX27_INT_UART6
+#define MXC_INT_UART5 MX27_INT_UART5
+#define MXC_INT_FEC MX27_INT_FEC
+#define MXC_INT_VPU MX27_INT_VPU
+#define MXC_INT_USB1 MX27_INT_USB1
+#define MXC_INT_USB2 MX27_INT_USB2
+#define MXC_INT_USB3 MX27_INT_USB3
+#define MXC_INT_SCC_SMN MX27_INT_SCC_SMN
+#define MXC_INT_SCC_SCM MX27_INT_SCC_SCM
+#define MXC_INT_SAHARA MX27_INT_SAHARA
+#define MXC_INT_IIM MX27_INT_IIM
+#define MXC_INT_CCM MX27_INT_CCM
+#define DMA_REQ_MSHC MX27_DMA_REQ_MSHC
+#define DMA_REQ_ATA_TX MX27_DMA_REQ_ATA_TX
+#define DMA_REQ_ATA_RCV MX27_DMA_REQ_ATA_RCV
+#define DMA_REQ_UART5_TX MX27_DMA_REQ_UART5_TX
+#define DMA_REQ_UART5_RX MX27_DMA_REQ_UART5_RX
+#define DMA_REQ_UART6_TX MX27_DMA_REQ_UART6_TX
+#define DMA_REQ_UART6_RX MX27_DMA_REQ_UART6_RX
+#define DMA_REQ_SDHC3 MX27_DMA_REQ_SDHC3
+#define DMA_REQ_NFC MX27_DMA_REQ_NFC
 
 #endif /* __ASM_ARCH_MXC_MX27_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,51 +25,49 @@
 
 /* The following addresses are common between i.MX21 and i.MX27 */
 
-/* Register offests */
-#define AIPI_BASE_ADDR          0x10000000
-#define AIPI_BASE_ADDR_VIRT     0xF4000000
-#define AIPI_SIZE               SZ_1M
-
-#define DMA_BASE_ADDR           (AIPI_BASE_ADDR + 0x01000)
-#define WDOG_BASE_ADDR          (AIPI_BASE_ADDR + 0x02000)
-#define GPT1_BASE_ADDR          (AIPI_BASE_ADDR + 0x03000)
-#define GPT2_BASE_ADDR          (AIPI_BASE_ADDR + 0x04000)
-#define GPT3_BASE_ADDR          (AIPI_BASE_ADDR + 0x05000)
-#define PWM_BASE_ADDR           (AIPI_BASE_ADDR + 0x06000)
-#define RTC_BASE_ADDR           (AIPI_BASE_ADDR + 0x07000)
-#define KPP_BASE_ADDR           (AIPI_BASE_ADDR + 0x08000)
-#define OWIRE_BASE_ADDR         (AIPI_BASE_ADDR + 0x09000)
-#define UART1_BASE_ADDR         (AIPI_BASE_ADDR + 0x0A000)
-#define UART2_BASE_ADDR         (AIPI_BASE_ADDR + 0x0B000)
-#define UART3_BASE_ADDR         (AIPI_BASE_ADDR + 0x0C000)
-#define UART4_BASE_ADDR         (AIPI_BASE_ADDR + 0x0D000)
-#define CSPI1_BASE_ADDR         (AIPI_BASE_ADDR + 0x0E000)
-#define CSPI2_BASE_ADDR         (AIPI_BASE_ADDR + 0x0F000)
-#define SSI1_BASE_ADDR          (AIPI_BASE_ADDR + 0x10000)
-#define SSI2_BASE_ADDR          (AIPI_BASE_ADDR + 0x11000)
-#define I2C_BASE_ADDR           (AIPI_BASE_ADDR + 0x12000)
-#define SDHC1_BASE_ADDR         (AIPI_BASE_ADDR + 0x13000)
-#define SDHC2_BASE_ADDR         (AIPI_BASE_ADDR + 0x14000)
-#define GPIO_BASE_ADDR          (AIPI_BASE_ADDR + 0x15000)
-#define AUDMUX_BASE_ADDR        (AIPI_BASE_ADDR + 0x16000)
-#define CSPI3_BASE_ADDR         (AIPI_BASE_ADDR + 0x17000)
-#define LCDC_BASE_ADDR          (AIPI_BASE_ADDR + 0x21000)
-#define SLCDC_BASE_ADDR         (AIPI_BASE_ADDR + 0x22000)
-#define USBOTG_BASE_ADDR        (AIPI_BASE_ADDR + 0x24000)
-#define EMMA_PP_BASE_ADDR       (AIPI_BASE_ADDR + 0x26000)
-#define EMMA_PRP_BASE_ADDR      (AIPI_BASE_ADDR + 0x26400)
-#define CCM_BASE_ADDR           (AIPI_BASE_ADDR + 0x27000)
-#define SYSCTRL_BASE_ADDR       (AIPI_BASE_ADDR + 0x27800)
-#define JAM_BASE_ADDR           (AIPI_BASE_ADDR + 0x3E000)
-#define MAX_BASE_ADDR           (AIPI_BASE_ADDR + 0x3F000)
-
-#define AVIC_BASE_ADDR          0x10040000
+/* Register offsets */
+#define MX2x_AIPI_BASE_ADDR		0x10000000
+#define MX2x_AIPI_BASE_ADDR_VIRT	0xf4000000
+#define MX2x_AIPI_SIZE			SZ_1M
+#define MX2x_DMA_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x01000)
+#define MX2x_WDOG_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x02000)
+#define MX2x_GPT1_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x03000)
+#define MX2x_GPT2_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x04000)
+#define MX2x_GPT3_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x05000)
+#define MX2x_PWM_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x06000)
+#define MX2x_RTC_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x07000)
+#define MX2x_KPP_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x08000)
+#define MX2x_OWIRE_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x09000)
+#define MX2x_UART1_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0a000)
+#define MX2x_UART2_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0b000)
+#define MX2x_UART3_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0c000)
+#define MX2x_UART4_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0d000)
+#define MX2x_CSPI1_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0e000)
+#define MX2x_CSPI2_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x0f000)
+#define MX2x_SSI1_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x10000)
+#define MX2x_SSI2_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x11000)
+#define MX2x_I2C_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x12000)
+#define MX2x_SDHC1_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x13000)
+#define MX2x_SDHC2_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x14000)
+#define MX2x_GPIO_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x15000)
+#define MX2x_AUDMUX_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x16000)
+#define MX2x_CSPI3_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x17000)
+#define MX2x_LCDC_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x21000)
+#define MX2x_SLCDC_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x22000)
+#define MX2x_USBOTG_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x24000)
+#define MX2x_EMMA_PP_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x26000)
+#define MX2x_EMMA_PRP_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x26400)
+#define MX2x_CCM_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x27000)
+#define MX2x_SYSCTRL_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x27800)
+#define MX2x_JAM_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x3e000)
+#define MX2x_MAX_BASE_ADDR			(MX2x_AIPI_BASE_ADDR + 0x3f000)
 
-#define SAHB1_BASE_ADDR         0x80000000
-#define SAHB1_BASE_ADDR_VIRT    0xF4100000
-#define SAHB1_SIZE              SZ_1M
+#define MX2x_AVIC_BASE_ADDR		0x10040000
 
-#define CSI_BASE_ADDR           (SAHB1_BASE_ADDR + 0x0000)
+#define MX2x_SAHB1_BASE_ADDR		0x80000000
+#define MX2x_SAHB1_BASE_ADDR_VIRT	0xf4100000
+#define MX2x_SAHB1_SIZE			SZ_1M
+#define MX2x_CSI_BASE_ADDR			(MX2x_SAHB1_BASE_ADDR + 0x0000)
 
 /*
  * This macro defines the physical to virtual address mapping for all the
@@ -105,78 +103,189 @@
 	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
 
 /* fixed interrupt numbers */
-#define MXC_INT_LCDC		61
-#define MXC_INT_SLCDC		60
-#define MXC_INT_EMMAPP		52
-#define MXC_INT_EMMAPRP		51
-#define MXC_INT_DMACH15		47
-#define MXC_INT_DMACH14		46
-#define MXC_INT_DMACH13		45
-#define MXC_INT_DMACH12		44
-#define MXC_INT_DMACH11		43
-#define MXC_INT_DMACH10		42
-#define MXC_INT_DMACH9		41
-#define MXC_INT_DMACH8		40
-#define MXC_INT_DMACH7		39
-#define MXC_INT_DMACH6		38
-#define MXC_INT_DMACH5		37
-#define MXC_INT_DMACH4		36
-#define MXC_INT_DMACH3		35
-#define MXC_INT_DMACH2		34
-#define MXC_INT_DMACH1		33
-#define MXC_INT_DMACH0		32
-#define MXC_INT_CSI		31
-#define MXC_INT_NANDFC		29
-#define MXC_INT_PCMCIA		28
-#define MXC_INT_WDOG		27
-#define MXC_INT_GPT1		26
-#define MXC_INT_GPT2		25
-#define MXC_INT_GPT3		24
-#define MXC_INT_GPT		INT_GPT1
-#define MXC_INT_PWM		23
-#define MXC_INT_RTC		22
-#define MXC_INT_KPP		21
-#define MXC_INT_UART1		20
-#define MXC_INT_UART2		19
-#define MXC_INT_UART3		18
-#define MXC_INT_UART4		17
-#define MXC_INT_CSPI1		16
-#define MXC_INT_CSPI2		15
-#define MXC_INT_SSI1		14
-#define MXC_INT_SSI2		13
-#define MXC_INT_I2C		12
-#define MXC_INT_SDHC1		11
-#define MXC_INT_SDHC2		10
-#define MXC_INT_GPIO		8
-#define MXC_INT_CSPI3		6
+#define MX2x_INT_CSPI3		6
+#define MX2x_INT_GPIO		8
+#define MX2x_INT_SDHC2		10
+#define MX2x_INT_SDHC1		11
+#define MX2x_INT_I2C		12
+#define MX2x_INT_SSI2		13
+#define MX2x_INT_SSI1		14
+#define MX2x_INT_CSPI2		15
+#define MX2x_INT_CSPI1		16
+#define MX2x_INT_UART4		17
+#define MX2x_INT_UART3		18
+#define MX2x_INT_UART2		19
+#define MX2x_INT_UART1		20
+#define MX2x_INT_KPP		21
+#define MX2x_INT_RTC		22
+#define MX2x_INT_PWM		23
+#define MX2x_INT_GPT3		24
+#define MX2x_INT_GPT2		25
+#define MX2x_INT_GPT1		26
+#define MX2x_INT_WDOG		27
+#define MX2x_INT_PCMCIA		28
+#define MX2x_INT_NANDFC		29
+#define MX2x_INT_CSI		31
+#define MX2x_INT_DMACH0		32
+#define MX2x_INT_DMACH1		33
+#define MX2x_INT_DMACH2		34
+#define MX2x_INT_DMACH3		35
+#define MX2x_INT_DMACH4		36
+#define MX2x_INT_DMACH5		37
+#define MX2x_INT_DMACH6		38
+#define MX2x_INT_DMACH7		39
+#define MX2x_INT_DMACH8		40
+#define MX2x_INT_DMACH9		41
+#define MX2x_INT_DMACH10	42
+#define MX2x_INT_DMACH11	43
+#define MX2x_INT_DMACH12	44
+#define MX2x_INT_DMACH13	45
+#define MX2x_INT_DMACH14	46
+#define MX2x_INT_DMACH15	47
+#define MX2x_INT_EMMAPRP	51
+#define MX2x_INT_EMMAPP		52
+#define MX2x_INT_SLCDC		60
+#define MX2x_INT_LCDC		61
 
 /* fixed DMA request numbers */
-#define DMA_REQ_CSI_RX          31
-#define DMA_REQ_CSI_STAT        30
-#define DMA_REQ_UART1_TX        27
-#define DMA_REQ_UART1_RX        26
-#define DMA_REQ_UART2_TX        25
-#define DMA_REQ_UART2_RX        24
-#define DMA_REQ_UART3_TX        23
-#define DMA_REQ_UART3_RX        22
-#define DMA_REQ_UART4_TX        21
-#define DMA_REQ_UART4_RX        20
-#define DMA_REQ_CSPI1_TX        19
-#define DMA_REQ_CSPI1_RX        18
-#define DMA_REQ_CSPI2_TX        17
-#define DMA_REQ_CSPI2_RX        16
-#define DMA_REQ_SSI1_TX1        15
-#define DMA_REQ_SSI1_RX1        14
-#define DMA_REQ_SSI1_TX0        13
-#define DMA_REQ_SSI1_RX0        12
-#define DMA_REQ_SSI2_TX1        11
-#define DMA_REQ_SSI2_RX1        10
-#define DMA_REQ_SSI2_TX0        9
-#define DMA_REQ_SSI2_RX0        8
-#define DMA_REQ_SDHC1           7
-#define DMA_REQ_SDHC2           6
-#define DMA_REQ_EXT             3
-#define DMA_REQ_CSPI3_TX        2
-#define DMA_REQ_CSPI3_RX        1
+#define MX2x_DMA_REQ_CSPI3_RX	1
+#define MX2x_DMA_REQ_CSPI3_TX	2
+#define MX2x_DMA_REQ_EXT	3
+#define MX2x_DMA_REQ_SDHC2	6
+#define MX2x_DMA_REQ_SDHC1	7
+#define MX2x_DMA_REQ_SSI2_RX0	8
+#define MX2x_DMA_REQ_SSI2_TX0	9
+#define MX2x_DMA_REQ_SSI2_RX1	10
+#define MX2x_DMA_REQ_SSI2_TX1	11
+#define MX2x_DMA_REQ_SSI1_RX0	12
+#define MX2x_DMA_REQ_SSI1_TX0	13
+#define MX2x_DMA_REQ_SSI1_RX1	14
+#define MX2x_DMA_REQ_SSI1_TX1	15
+#define MX2x_DMA_REQ_CSPI2_RX	16
+#define MX2x_DMA_REQ_CSPI2_TX	17
+#define MX2x_DMA_REQ_CSPI1_RX	18
+#define MX2x_DMA_REQ_CSPI1_TX	19
+#define MX2x_DMA_REQ_UART4_RX	20
+#define MX2x_DMA_REQ_UART4_TX	21
+#define MX2x_DMA_REQ_UART3_RX	22
+#define MX2x_DMA_REQ_UART3_TX	23
+#define MX2x_DMA_REQ_UART2_RX	24
+#define MX2x_DMA_REQ_UART2_TX	25
+#define MX2x_DMA_REQ_UART1_RX	26
+#define MX2x_DMA_REQ_UART1_TX	27
+#define MX2x_DMA_REQ_CSI_STAT	30
+#define MX2x_DMA_REQ_CSI_RX	31
+
+/* these should go away */
+#define AIPI_BASE_ADDR MX2x_AIPI_BASE_ADDR
+#define AIPI_BASE_ADDR_VIRT MX2x_AIPI_BASE_ADDR_VIRT
+#define AIPI_SIZE MX2x_AIPI_SIZE
+#define DMA_BASE_ADDR MX2x_DMA_BASE_ADDR
+#define WDOG_BASE_ADDR MX2x_WDOG_BASE_ADDR
+#define GPT1_BASE_ADDR MX2x_GPT1_BASE_ADDR
+#define GPT2_BASE_ADDR MX2x_GPT2_BASE_ADDR
+#define GPT3_BASE_ADDR MX2x_GPT3_BASE_ADDR
+#define PWM_BASE_ADDR MX2x_PWM_BASE_ADDR
+#define RTC_BASE_ADDR MX2x_RTC_BASE_ADDR
+#define KPP_BASE_ADDR MX2x_KPP_BASE_ADDR
+#define OWIRE_BASE_ADDR MX2x_OWIRE_BASE_ADDR
+#define UART1_BASE_ADDR MX2x_UART1_BASE_ADDR
+#define UART2_BASE_ADDR MX2x_UART2_BASE_ADDR
+#define UART3_BASE_ADDR MX2x_UART3_BASE_ADDR
+#define UART4_BASE_ADDR MX2x_UART4_BASE_ADDR
+#define CSPI1_BASE_ADDR MX2x_CSPI1_BASE_ADDR
+#define CSPI2_BASE_ADDR MX2x_CSPI2_BASE_ADDR
+#define SSI1_BASE_ADDR MX2x_SSI1_BASE_ADDR
+#define SSI2_BASE_ADDR MX2x_SSI2_BASE_ADDR
+#define I2C_BASE_ADDR MX2x_I2C_BASE_ADDR
+#define SDHC1_BASE_ADDR MX2x_SDHC1_BASE_ADDR
+#define SDHC2_BASE_ADDR MX2x_SDHC2_BASE_ADDR
+#define GPIO_BASE_ADDR MX2x_GPIO_BASE_ADDR
+#define AUDMUX_BASE_ADDR MX2x_AUDMUX_BASE_ADDR
+#define CSPI3_BASE_ADDR MX2x_CSPI3_BASE_ADDR
+#define LCDC_BASE_ADDR MX2x_LCDC_BASE_ADDR
+#define SLCDC_BASE_ADDR MX2x_SLCDC_BASE_ADDR
+#define USBOTG_BASE_ADDR MX2x_USBOTG_BASE_ADDR
+#define EMMA_PP_BASE_ADDR MX2x_EMMA_PP_BASE_ADDR
+#define EMMA_PRP_BASE_ADDR MX2x_EMMA_PRP_BASE_ADDR
+#define CCM_BASE_ADDR MX2x_CCM_BASE_ADDR
+#define SYSCTRL_BASE_ADDR MX2x_SYSCTRL_BASE_ADDR
+#define JAM_BASE_ADDR MX2x_JAM_BASE_ADDR
+#define MAX_BASE_ADDR MX2x_MAX_BASE_ADDR
+#define AVIC_BASE_ADDR MX2x_AVIC_BASE_ADDR
+#define SAHB1_BASE_ADDR MX2x_SAHB1_BASE_ADDR
+#define SAHB1_BASE_ADDR_VIRT MX2x_SAHB1_BASE_ADDR_VIRT
+#define SAHB1_SIZE MX2x_SAHB1_SIZE
+#define CSI_BASE_ADDR MX2x_CSI_BASE_ADDR
+#define MXC_INT_CSPI3 MX2x_INT_CSPI3
+#define MXC_INT_GPIO MX2x_INT_GPIO
+#define MXC_INT_SDHC2 MX2x_INT_SDHC2
+#define MXC_INT_SDHC1 MX2x_INT_SDHC1
+#define MXC_INT_I2C MX2x_INT_I2C
+#define MXC_INT_SSI2 MX2x_INT_SSI2
+#define MXC_INT_SSI1 MX2x_INT_SSI1
+#define MXC_INT_CSPI2 MX2x_INT_CSPI2
+#define MXC_INT_CSPI1 MX2x_INT_CSPI1
+#define MXC_INT_UART4 MX2x_INT_UART4
+#define MXC_INT_UART3 MX2x_INT_UART3
+#define MXC_INT_UART2 MX2x_INT_UART2
+#define MXC_INT_UART1 MX2x_INT_UART1
+#define MXC_INT_KPP MX2x_INT_KPP
+#define MXC_INT_RTC MX2x_INT_RTC
+#define MXC_INT_PWM MX2x_INT_PWM
+#define MXC_INT_GPT3 MX2x_INT_GPT3
+#define MXC_INT_GPT2 MX2x_INT_GPT2
+#define MXC_INT_GPT1 MX2x_INT_GPT1
+#define MXC_INT_WDOG MX2x_INT_WDOG
+#define MXC_INT_PCMCIA MX2x_INT_PCMCIA
+#define MXC_INT_NANDFC MX2x_INT_NANDFC
+#define MXC_INT_CSI MX2x_INT_CSI
+#define MXC_INT_DMACH0 MX2x_INT_DMACH0
+#define MXC_INT_DMACH1 MX2x_INT_DMACH1
+#define MXC_INT_DMACH2 MX2x_INT_DMACH2
+#define MXC_INT_DMACH3 MX2x_INT_DMACH3
+#define MXC_INT_DMACH4 MX2x_INT_DMACH4
+#define MXC_INT_DMACH5 MX2x_INT_DMACH5
+#define MXC_INT_DMACH6 MX2x_INT_DMACH6
+#define MXC_INT_DMACH7 MX2x_INT_DMACH7
+#define MXC_INT_DMACH8 MX2x_INT_DMACH8
+#define MXC_INT_DMACH9 MX2x_INT_DMACH9
+#define MXC_INT_DMACH10 MX2x_INT_DMACH10
+#define MXC_INT_DMACH11 MX2x_INT_DMACH11
+#define MXC_INT_DMACH12 MX2x_INT_DMACH12
+#define MXC_INT_DMACH13 MX2x_INT_DMACH13
+#define MXC_INT_DMACH14 MX2x_INT_DMACH14
+#define MXC_INT_DMACH15 MX2x_INT_DMACH15
+#define MXC_INT_EMMAPRP MX2x_INT_EMMAPRP
+#define MXC_INT_EMMAPP MX2x_INT_EMMAPP
+#define MXC_INT_SLCDC MX2x_INT_SLCDC
+#define MXC_INT_LCDC MX2x_INT_LCDC
+#define DMA_REQ_CSPI3_RX MX2x_DMA_REQ_CSPI3_RX
+#define DMA_REQ_CSPI3_TX MX2x_DMA_REQ_CSPI3_TX
+#define DMA_REQ_EXT MX2x_DMA_REQ_EXT
+#define DMA_REQ_SDHC2 MX2x_DMA_REQ_SDHC2
+#define DMA_REQ_SDHC1 MX2x_DMA_REQ_SDHC1
+#define DMA_REQ_SSI2_RX0 MX2x_DMA_REQ_SSI2_RX0
+#define DMA_REQ_SSI2_TX0 MX2x_DMA_REQ_SSI2_TX0
+#define DMA_REQ_SSI2_RX1 MX2x_DMA_REQ_SSI2_RX1
+#define DMA_REQ_SSI2_TX1 MX2x_DMA_REQ_SSI2_TX1
+#define DMA_REQ_SSI1_RX0 MX2x_DMA_REQ_SSI1_RX0
+#define DMA_REQ_SSI1_TX0 MX2x_DMA_REQ_SSI1_TX0
+#define DMA_REQ_SSI1_RX1 MX2x_DMA_REQ_SSI1_RX1
+#define DMA_REQ_SSI1_TX1 MX2x_DMA_REQ_SSI1_TX1
+#define DMA_REQ_CSPI2_RX MX2x_DMA_REQ_CSPI2_RX
+#define DMA_REQ_CSPI2_TX MX2x_DMA_REQ_CSPI2_TX
+#define DMA_REQ_CSPI1_RX MX2x_DMA_REQ_CSPI1_RX
+#define DMA_REQ_CSPI1_TX MX2x_DMA_REQ_CSPI1_TX
+#define DMA_REQ_UART4_RX MX2x_DMA_REQ_UART4_RX
+#define DMA_REQ_UART4_TX MX2x_DMA_REQ_UART4_TX
+#define DMA_REQ_UART3_RX MX2x_DMA_REQ_UART3_RX
+#define DMA_REQ_UART3_TX MX2x_DMA_REQ_UART3_TX
+#define DMA_REQ_UART2_RX MX2x_DMA_REQ_UART2_RX
+#define DMA_REQ_UART2_TX MX2x_DMA_REQ_UART2_TX
+#define DMA_REQ_UART1_RX MX2x_DMA_REQ_UART1_RX
+#define DMA_REQ_UART1_TX MX2x_DMA_REQ_UART1_TX
+#define DMA_REQ_CSI_STAT MX2x_DMA_REQ_CSI_STAT
+#define DMA_REQ_CSI_RX MX2x_DMA_REQ_CSI_RX
 
 #endif /* __ASM_ARCH_MXC_MX2x_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx31.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx31.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,45 +1,218 @@
 /*
  * IRAM
  */
-#define MX31_IRAM_BASE_ADDR		0x1FFC0000	/* internal ram */
+#define MX31_IRAM_BASE_ADDR		0x1ffc0000	/* internal ram */
 #define MX31_IRAM_SIZE			SZ_16K
 
-#define MX31_OTG_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00088000)
-#define ATA_BASE_ADDR		(AIPS1_BASE_ADDR + 0x0008C000)
-#define UART4_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B0000)
-#define UART5_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B4000)
+#define MX31_L2CC_BASE_ADDR		0x30000000
+#define MX31_L2CC_SIZE			SZ_1M
 
-#define MMC_SDHC1_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00004000)
-#define MMC_SDHC2_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00008000)
-#define SIM1_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00018000)
-#define IIM_BASE_ADDR		(SPBA0_BASE_ADDR + 0x0001C000)
+#define MX31_AIPS1_BASE_ADDR		0x43f00000
+#define MX31_AIPS1_BASE_ADDR_VIRT	0xfc000000
+#define MX31_AIPS1_SIZE			SZ_1M
+#define MX31_MAX_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x04000)
+#define MX31_EVTMON_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x08000)
+#define MX31_CLKCTL_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x0c000)
+#define MX31_ETB_SLOT4_BASE_ADDR		(MX31_AIPS1_BASE_ADDR + 0x10000)
+#define MX31_ETB_SLOT5_BASE_ADDR		(MX31_AIPS1_BASE_ADDR + 0x14000)
+#define MX31_ECT_CTIO_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x18000)
+#define MX31_I2C_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x80000)
+#define MX31_I2C3_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x84000)
+#define MX31_OTG_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x88000)
+#define MX31_ATA_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x8c000)
+#define MX31_UART1_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x90000)
+#define MX31_UART2_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x94000)
+#define MX31_I2C2_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x98000)
+#define MX31_OWIRE_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0x9c000)
+#define MX31_SSI1_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xa0000)
+#define MX31_CSPI1_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xa4000)
+#define MX31_KPP_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xa8000)
+#define MX31_IOMUXC_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xac000)
+#define MX31_UART4_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xb0000)
+#define MX31_UART5_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xb4000)
+#define MX31_ECT_IP1_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xb8000)
+#define MX31_ECT_IP2_BASE_ADDR			(MX31_AIPS1_BASE_ADDR + 0xbc000)
 
-#define CSPI3_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00084000)
-#define FIRI_BASE_ADDR		(AIPS2_BASE_ADDR + 0x0008C000)
-#define SCM_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000AE000)
-#define SMN_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000AF000)
-#define MPEG4_ENC_BASE_ADDR	(AIPS2_BASE_ADDR + 0x000C8000)
+#define MX31_SPBA0_BASE_ADDR		0x50000000
+#define MX31_SPBA0_BASE_ADDR_VIRT	0xfc100000
+#define MX31_SPBA0_SIZE			SZ_1M
+#define MX31_MMC_SDHC1_BASE_ADDR		(MX31_SPBA0_BASE_ADDR + 0x04000)
+#define MX31_MMC_SDHC2_BASE_ADDR		(MX31_SPBA0_BASE_ADDR + 0x08000)
+#define MX31_UART3_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x0c000)
+#define MX31_CSPI2_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x10000)
+#define MX31_SSI2_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x14000)
+#define MX31_SIM1_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x18000)
+#define MX31_IIM_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x1c000)
+#define MX31_ATA_DMA_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x20000)
+#define MX31_MSHC1_BASE_ADDR			(MX31_SPBA0_BASE_ADDR + 0x24000)
+#define MX31_SPBA_CTRL_BASE_ADDR		(MX31_SPBA0_BASE_ADDR + 0x3c000)
 
-#define MX31_NFC_BASE_ADDR	(X_MEMC_BASE_ADDR + 0x0000)
+#define MX31_AIPS2_BASE_ADDR		0x53f00000
+#define MX31_AIPS2_BASE_ADDR_VIRT	0xfc200000
+#define MX31_AIPS2_SIZE			SZ_1M
+#define MX31_CCM_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x80000)
+#define MX31_CSPI3_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x84000)
+#define MX31_FIRI_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x8c000)
+#define MX31_GPT1_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x90000)
+#define MX31_EPIT1_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x94000)
+#define MX31_EPIT2_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0x98000)
+#define MX31_GPIO3_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xa4000)
+#define MX31_SCC_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xac000)
+#define MX31_SCM_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xae000)
+#define MX31_SMN_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xaf000)
+#define MX31_RNGA_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xb0000)
+#define MX31_IPU_CTRL_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xc0000)
+#define MX31_AUDMUX_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xc4000)
+#define MX31_MPEG4_ENC_BASE_ADDR		(MX31_AIPS2_BASE_ADDR + 0xc8000)
+#define MX31_GPIO1_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xcc000)
+#define MX31_GPIO2_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xd0000)
+#define MX31_SDMA_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xd4000)
+#define MX31_RTC_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xd8000)
+#define MX31_WDOG_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xdc000)
+#define MX31_PWM_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xe0000)
+#define MX31_RTIC_BASE_ADDR			(MX31_AIPS2_BASE_ADDR + 0xec000)
 
-#define MXC_INT_MPEG4_ENCODER	5
-#define MXC_INT_FIRI		7
+#define MX31_ROMP_BASE_ADDR		0x60000000
+#define MX31_ROMP_BASE_ADDR_VIRT	0xfc500000
+#define MX31_ROMP_SIZE			SZ_1M
+
+#define MX31_AVIC_BASE_ADDR		0x68000000
+#define MX31_AVIC_BASE_ADDR_VIRT	0xfc400000
+#define MX31_AVIC_SIZE			SZ_1M
+
+#define MX31_IPU_MEM_BASE_ADDR		0x70000000
+#define MX31_CSD0_BASE_ADDR		0x80000000
+#define MX31_CSD1_BASE_ADDR		0x90000000
+
+#define MX31_CS0_BASE_ADDR		0xa0000000
+#define MX31_CS1_BASE_ADDR		0xa8000000
+#define MX31_CS2_BASE_ADDR		0xb0000000
+#define MX31_CS3_BASE_ADDR		0xb2000000
+
+#define MX31_CS4_BASE_ADDR		0xb4000000
+#define MX31_CS4_BASE_ADDR_VIRT		0xf4000000
+#define MX31_CS4_SIZE			SZ_32M
+
+#define MX31_CS5_BASE_ADDR		0xb6000000
+#define MX31_CS5_BASE_ADDR_VIRT		0xf6000000
+#define MX31_CS5_SIZE			SZ_32M
+
+#define MX31_X_MEMC_BASE_ADDR		0xb8000000
+#define MX31_X_MEMC_BASE_ADDR_VIRT	0xfc320000
+#define MX31_X_MEMC_SIZE		SZ_64K
+#define MX31_NFC_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x0000)
+#define MX31_ESDCTL_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x1000)
+#define MX31_WEIM_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x2000)
+#define MX31_M3IF_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x3000)
+#define MX31_EMI_CTL_BASE_ADDR			(MX31_X_MEMC_BASE_ADDR + 0x4000)
+#define MX31_PCMCIA_CTL_BASE_ADDR		MX31_EMI_CTL_BASE_ADDR
+
+#define MX31_PCMCIA_MEM_BASE_ADDR	0xbc000000
+
+#define MX31_INT_I2C3		3
+#define MX31_INT_I2C2		4
+#define MX31_INT_MPEG4_ENCODER	5
+#define MX31_INT_RTIC		6
+#define MX31_INT_FIRI		7
 #define MX31_INT_MMC_SDHC2	8
-#define MXC_INT_MMC_SDHC1	9
+#define MX31_INT_MMC_SDHC1	9
+#define MX31_INT_I2C		10
 #define MX31_INT_SSI2		11
 #define MX31_INT_SSI1		12
-#define MXC_INT_MBX		16
-#define MXC_INT_CSPI3		17
-#define MXC_INT_SIM2		20
-#define MXC_INT_SIM1		21
-#define MXC_INT_CCM_DVFS	31
-#define MXC_INT_USB1		35
-#define MXC_INT_USB2		36
-#define MXC_INT_USB3		37
-#define MXC_INT_USB4		38
-#define MXC_INT_MSHC2		40
-#define MXC_INT_UART4		46
-#define MXC_INT_UART5		47
-#define MXC_INT_CCM		53
-#define MXC_INT_PCMCIA		54
+#define MX31_INT_CSPI2		13
+#define MX31_INT_CSPI1		14
+#define MX31_INT_ATA		15
+#define MX31_INT_MBX		16
+#define MX31_INT_CSPI3		17
+#define MX31_INT_UART3		18
+#define MX31_INT_IIM		19
+#define MX31_INT_SIM2		20
+#define MX31_INT_SIM1		21
+#define MX31_INT_RNGA		22
+#define MX31_INT_EVTMON		23
+#define MX31_INT_KPP		24
+#define MX31_INT_RTC		25
+#define MX31_INT_PWM		26
+#define MX31_INT_EPIT2		27
+#define MX31_INT_EPIT1		28
+#define MX31_INT_GPT		29
+#define MX31_INT_POWER_FAIL	30
+#define MX31_INT_CCM_DVFS	31
+#define MX31_INT_UART2		32
+#define MX31_INT_NANDFC		33
+#define MX31_INT_SDMA		34
+#define MX31_INT_USB1		35
+#define MX31_INT_USB2		36
+#define MX31_INT_USB3		37
+#define MX31_INT_USB4		38
+#define MX31_INT_MSHC1		39
+#define MX31_INT_MSHC2		40
+#define MX31_INT_IPU_ERR	41
+#define MX31_INT_IPU_SYN	42
+#define MX31_INT_UART1		45
+#define MX31_INT_UART4		46
+#define MX31_INT_UART5		47
+#define MX31_INT_ECT		48
+#define MX31_INT_SCC_SCM	49
+#define MX31_INT_SCC_SMN	50
+#define MX31_INT_GPIO2		51
+#define MX31_INT_GPIO1		52
+#define MX31_INT_CCM		53
+#define MX31_INT_PCMCIA		54
+#define MX31_INT_WDOG		55
+#define MX31_INT_GPIO3		56
+#define MX31_INT_EXT_POWER	58
+#define MX31_INT_EXT_TEMPER	59
+#define MX31_INT_EXT_SENSOR60	60
+#define MX31_INT_EXT_SENSOR61	61
+#define MX31_INT_EXT_WDOG	62
+#define MX31_INT_EXT_TV		63
+
+#define MX31_PROD_SIGNATURE		0x1	/* For MX31 */
+
+/* silicon revisions specific to i.MX31 */
+#define MX31_CHIP_REV_1_0		0x10
+#define MX31_CHIP_REV_1_1		0x11
+#define MX31_CHIP_REV_1_2		0x12
+#define MX31_CHIP_REV_1_3		0x13
+#define MX31_CHIP_REV_2_0		0x20
+#define MX31_CHIP_REV_2_1		0x21
+#define MX31_CHIP_REV_2_2		0x22
+#define MX31_CHIP_REV_2_3		0x23
+#define MX31_CHIP_REV_3_0		0x30
+#define MX31_CHIP_REV_3_1		0x31
+#define MX31_CHIP_REV_3_2		0x32
 
+#define MX31_SYSTEM_REV_MIN		MX31_CHIP_REV_1_0
+#define MX31_SYSTEM_REV_NUM		3
+
+/* these should go away */
+#define ATA_BASE_ADDR MX31_ATA_BASE_ADDR
+#define UART4_BASE_ADDR MX31_UART4_BASE_ADDR
+#define UART5_BASE_ADDR MX31_UART5_BASE_ADDR
+#define MMC_SDHC1_BASE_ADDR MX31_MMC_SDHC1_BASE_ADDR
+#define MMC_SDHC2_BASE_ADDR MX31_MMC_SDHC2_BASE_ADDR
+#define SIM1_BASE_ADDR MX31_SIM1_BASE_ADDR
+#define IIM_BASE_ADDR MX31_IIM_BASE_ADDR
+#define CSPI3_BASE_ADDR MX31_CSPI3_BASE_ADDR
+#define FIRI_BASE_ADDR MX31_FIRI_BASE_ADDR
+#define SCM_BASE_ADDR MX31_SCM_BASE_ADDR
+#define SMN_BASE_ADDR MX31_SMN_BASE_ADDR
+#define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR
+#define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER
+#define MXC_INT_FIRI MX31_INT_FIRI
+#define MXC_INT_MMC_SDHC1 MX31_INT_MMC_SDHC1
+#define MXC_INT_MBX MX31_INT_MBX
+#define MXC_INT_CSPI3 MX31_INT_CSPI3
+#define MXC_INT_SIM2 MX31_INT_SIM2
+#define MXC_INT_SIM1 MX31_INT_SIM1
+#define MXC_INT_CCM_DVFS MX31_INT_CCM_DVFS
+#define MXC_INT_USB1 MX31_INT_USB1
+#define MXC_INT_USB2 MX31_INT_USB2
+#define MXC_INT_USB3 MX31_INT_USB3
+#define MXC_INT_USB4 MX31_INT_USB4
+#define MXC_INT_MSHC2 MX31_INT_MSHC2
+#define MXC_INT_UART4 MX31_INT_UART4
+#define MXC_INT_UART5 MX31_INT_UART5
+#define MXC_INT_CCM MX31_INT_CCM
+#define MXC_INT_PCMCIA MX31_INT_PCMCIA
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx35.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx35.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,29 +2,196 @@
  * IRAM
  */
 #define MX35_IRAM_BASE_ADDR		0x10000000	/* internal ram */
-#define MX35_IRAM_SIZE		SZ_128K
+#define MX35_IRAM_SIZE			SZ_128K
 
-#define MXC_FEC_BASE_ADDR	0x50038000
-#define MX35_OTG_BASE_ADDR	0x53ff4000
-#define MX35_NFC_BASE_ADDR	0xBB000000
+#define MX35_L2CC_BASE_ADDR		0x30000000
+#define MX35_L2CC_SIZE			SZ_1M
+
+#define MX35_AIPS1_BASE_ADDR		0x43f00000
+#define MX35_AIPS1_BASE_ADDR_VIRT	0xfc000000
+#define MX35_AIPS1_SIZE			SZ_1M
+#define MX35_MAX_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x04000)
+#define MX35_EVTMON_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x08000)
+#define MX35_CLKCTL_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x0c000)
+#define MX35_ETB_SLOT4_BASE_ADDR		(MX35_AIPS1_BASE_ADDR + 0x10000)
+#define MX35_ETB_SLOT5_BASE_ADDR		(MX35_AIPS1_BASE_ADDR + 0x14000)
+#define MX35_ECT_CTIO_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x18000)
+#define MX35_I2C_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x80000)
+#define MX35_I2C3_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x84000)
+#define MX35_UART1_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x90000)
+#define MX35_UART2_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x94000)
+#define MX35_I2C2_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x98000)
+#define MX35_OWIRE_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0x9c000)
+#define MX35_SSI1_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xa0000)
+#define MX35_CSPI1_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xa4000)
+#define MX35_KPP_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xa8000)
+#define MX35_IOMUXC_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xac000)
+#define MX35_ECT_IP1_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xb8000)
+#define MX35_ECT_IP2_BASE_ADDR			(MX35_AIPS1_BASE_ADDR + 0xbc000)
+
+#define MX35_SPBA0_BASE_ADDR		0x50000000
+#define MX35_SPBA0_BASE_ADDR_VIRT	0xfc100000
+#define MX35_SPBA0_SIZE			SZ_1M
+#define MX35_UART3_BASE_ADDR			(MX35_SPBA0_BASE_ADDR + 0x0c000)
+#define MX35_CSPI2_BASE_ADDR			(MX35_SPBA0_BASE_ADDR + 0x10000)
+#define MX35_SSI2_BASE_ADDR			(MX35_SPBA0_BASE_ADDR + 0x14000)
+#define MX35_ATA_DMA_BASE_ADDR			(MX35_SPBA0_BASE_ADDR + 0x20000)
+#define MX35_MSHC1_BASE_ADDR			(MX35_SPBA0_BASE_ADDR + 0x24000)
+#define MX35_FEC_BASE_ADDR		0x50038000
+#define MX35_SPBA_CTRL_BASE_ADDR		(MX35_SPBA0_BASE_ADDR + 0x3c000)
+
+#define MX35_AIPS2_BASE_ADDR		0x53f00000
+#define MX35_AIPS2_BASE_ADDR_VIRT	0xfc200000
+#define MX35_AIPS2_SIZE			SZ_1M
+#define MX35_CCM_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0x80000)
+#define MX35_GPT1_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0x90000)
+#define MX35_EPIT1_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0x94000)
+#define MX35_EPIT2_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0x98000)
+#define MX35_GPIO3_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xa4000)
+#define MX35_SCC_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xac000)
+#define MX35_RNGA_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xb0000)
+#define MX35_IPU_CTRL_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xc0000)
+#define MX35_AUDMUX_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xc4000)
+#define MX35_GPIO1_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xcc000)
+#define MX35_GPIO2_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xd0000)
+#define MX35_SDMA_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xd4000)
+#define MX35_RTC_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xd8000)
+#define MX35_WDOG_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xdc000)
+#define MX35_PWM_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xe0000)
+#define MX35_RTIC_BASE_ADDR			(MX35_AIPS2_BASE_ADDR + 0xec000)
+#define MX35_OTG_BASE_ADDR		0x53ff4000
+
+#define MX35_ROMP_BASE_ADDR		0x60000000
+#define MX35_ROMP_BASE_ADDR_VIRT	0xfc500000
+#define MX35_ROMP_SIZE			SZ_1M
+
+#define MX35_AVIC_BASE_ADDR		0x68000000
+#define MX35_AVIC_BASE_ADDR_VIRT	0xfc400000
+#define MX35_AVIC_SIZE			SZ_1M
+
+/*
+ * Memory regions and CS
+ */
+#define MX35_IPU_MEM_BASE_ADDR		0x70000000
+#define MX35_CSD0_BASE_ADDR		0x80000000
+#define MX35_CSD1_BASE_ADDR		0x90000000
+
+#define MX35_CS0_BASE_ADDR		0xa0000000
+#define MX35_CS1_BASE_ADDR		0xa8000000
+#define MX35_CS2_BASE_ADDR		0xb0000000
+#define MX35_CS3_BASE_ADDR		0xb2000000
+
+#define MX35_CS4_BASE_ADDR		0xb4000000
+#define MX35_CS4_BASE_ADDR_VIRT		0xf4000000
+#define MX35_CS4_SIZE			SZ_32M
+
+#define MX35_CS5_BASE_ADDR		0xb6000000
+#define MX35_CS5_BASE_ADDR_VIRT		0xf6000000
+#define MX35_CS5_SIZE			SZ_32M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define MX35_X_MEMC_BASE_ADDR		0xb8000000
+#define MX35_X_MEMC_BASE_ADDR_VIRT	0xfc320000
+#define MX35_X_MEMC_SIZE		SZ_64K
+#define MX35_ESDCTL_BASE_ADDR			(MX35_X_MEMC_BASE_ADDR + 0x1000)
+#define MX35_WEIM_BASE_ADDR			(MX35_X_MEMC_BASE_ADDR + 0x2000)
+#define MX35_M3IF_BASE_ADDR			(MX35_X_MEMC_BASE_ADDR + 0x3000)
+#define MX35_EMI_CTL_BASE_ADDR			(MX35_X_MEMC_BASE_ADDR + 0x4000)
+#define MX35_PCMCIA_CTL_BASE_ADDR		MX35_EMI_CTL_BASE_ADDR
+
+#define MX35_NFC_BASE_ADDR		0xbb000000
+#define MX35_PCMCIA_MEM_BASE_ADDR	0xbc000000
 
 /*
  * Interrupt numbers
  */
-#define MXC_INT_OWIRE		2
+#define MX35_INT_OWIRE		2
+#define MX35_INT_I2C3		3
+#define MX35_INT_I2C2		4
+#define MX35_INT_RTIC		6
 #define MX35_INT_MMC_SDHC1	7
-#define MXC_INT_MMC_SDHC2	8
-#define MXC_INT_MMC_SDHC3	9
+#define MX35_INT_MMC_SDHC2	8
+#define MX35_INT_MMC_SDHC3	9
+#define MX35_INT_I2C		10
 #define MX35_INT_SSI1		11
 #define MX35_INT_SSI2		12
-#define MXC_INT_GPU2D		16
-#define MXC_INT_ASRC		17
-#define MXC_INT_USBHS		35
-#define MXC_INT_USBOTG		37
-#define MXC_INT_ESAI		40
-#define MXC_INT_CAN1		43
-#define MXC_INT_CAN2		44
-#define MXC_INT_MLB		46
-#define MXC_INT_SPDIF		47
-#define MXC_INT_FEC		57
+#define MX35_INT_CSPI2		13
+#define MX35_INT_CSPI1		14
+#define MX35_INT_ATA		15
+#define MX35_INT_GPU2D		16
+#define MX35_INT_ASRC		17
+#define MX35_INT_UART3		18
+#define MX35_INT_IIM		19
+#define MX35_INT_RNGA		22
+#define MX35_INT_EVTMON		23
+#define MX35_INT_KPP		24
+#define MX35_INT_RTC		25
+#define MX35_INT_PWM		26
+#define MX35_INT_EPIT2		27
+#define MX35_INT_EPIT1		28
+#define MX35_INT_GPT		29
+#define MX35_INT_POWER_FAIL	30
+#define MX35_INT_UART2		32
+#define MX35_INT_NANDFC		33
+#define MX35_INT_SDMA		34
+#define MX35_INT_USBHS		35
+#define MX35_INT_USBOTG		37
+#define MX35_INT_MSHC1		39
+#define MX35_INT_ESAI		40
+#define MX35_INT_IPU_ERR	41
+#define MX35_INT_IPU_SYN	42
+#define MX35_INT_CAN1		43
+#define MX35_INT_CAN2		44
+#define MX35_INT_UART1		45
+#define MX35_INT_MLB		46
+#define MX35_INT_SPDIF		47
+#define MX35_INT_ECT		48
+#define MX35_INT_SCC_SCM	49
+#define MX35_INT_SCC_SMN	50
+#define MX35_INT_GPIO2		51
+#define MX35_INT_GPIO1		52
+#define MX35_INT_WDOG		55
+#define MX35_INT_GPIO3		56
+#define MX35_INT_FEC		57
+#define MX35_INT_EXT_POWER	58
+#define MX35_INT_EXT_TEMPER	59
+#define MX35_INT_EXT_SENSOR60	60
+#define MX35_INT_EXT_SENSOR61	61
+#define MX35_INT_EXT_WDOG	62
+#define MX35_INT_EXT_TV		63
+
+#define MX35_PROD_SIGNATURE		0x1	/* For MX31 */
+
+/* silicon revisions specific to i.MX31 */
+#define MX35_CHIP_REV_1_0		0x10
+#define MX35_CHIP_REV_1_1		0x11
+#define MX35_CHIP_REV_1_2		0x12
+#define MX35_CHIP_REV_1_3		0x13
+#define MX35_CHIP_REV_2_0		0x20
+#define MX35_CHIP_REV_2_1		0x21
+#define MX35_CHIP_REV_2_2		0x22
+#define MX35_CHIP_REV_2_3		0x23
+#define MX35_CHIP_REV_3_0		0x30
+#define MX35_CHIP_REV_3_1		0x31
+#define MX35_CHIP_REV_3_2		0x32
 
+#define MX35_SYSTEM_REV_MIN		MX35_CHIP_REV_1_0
+#define MX35_SYSTEM_REV_NUM		3
+
+/* these should go away */
+#define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
+#define MXC_INT_OWIRE MX35_INT_OWIRE
+#define MXC_INT_MMC_SDHC2 MX35_INT_MMC_SDHC2
+#define MXC_INT_MMC_SDHC3 MX35_INT_MMC_SDHC3
+#define MXC_INT_GPU2D MX35_INT_GPU2D
+#define MXC_INT_ASRC MX35_INT_ASRC
+#define MXC_INT_USBHS MX35_INT_USBHS
+#define MXC_INT_USBOTG MX35_INT_USBOTG
+#define MXC_INT_ESAI MX35_INT_ESAI
+#define MXC_INT_CAN1 MX35_INT_CAN1
+#define MXC_INT_CAN2 MX35_INT_CAN2
+#define MXC_INT_MLB MX35_INT_MLB
+#define MXC_INT_SPDIF MX35_INT_SPDIF
+#define MXC_INT_FEC MX35_INT_FEC
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,120 +34,117 @@
  *         	C0000000	64M	PCMCIA/CF
  */
 
-#define CS0_BASE_ADDR		0xA0000000
-#define CS1_BASE_ADDR		0xA8000000
-#define CS2_BASE_ADDR		0xB0000000
-#define CS3_BASE_ADDR		0xB2000000
-
-#define CS4_BASE_ADDR		0xB4000000
-#define CS4_BASE_ADDR_VIRT	0xF4000000
-#define CS4_SIZE		SZ_32M
-
-#define CS5_BASE_ADDR		0xB6000000
-#define CS5_BASE_ADDR_VIRT	0xF6000000
-#define CS5_SIZE		SZ_32M
-
-#define PCMCIA_MEM_BASE_ADDR	0xBC000000
-
 /*
  * L2CC
  */
-#define L2CC_BASE_ADDR		0x30000000
-#define L2CC_SIZE		SZ_1M
+#define MX3x_L2CC_BASE_ADDR		0x30000000
+#define MX3x_L2CC_SIZE			SZ_1M
 
 /*
  * AIPS 1
  */
-#define AIPS1_BASE_ADDR		0x43F00000
-#define AIPS1_BASE_ADDR_VIRT	0xFC000000
-#define AIPS1_SIZE		SZ_1M
-
-#define MAX_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00004000)
-#define EVTMON_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00008000)
-#define CLKCTL_BASE_ADDR	(AIPS1_BASE_ADDR + 0x0000C000)
-#define ETB_SLOT4_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00010000)
-#define ETB_SLOT5_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00014000)
-#define ECT_CTIO_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00018000)
-#define I2C_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00080000)
-#define I2C3_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00084000)
-#define UART1_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x00090000)
-#define UART2_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x00094000)
-#define I2C2_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00098000)
-#define OWIRE_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x0009C000)
-#define SSI1_BASE_ADDR		(AIPS1_BASE_ADDR + 0x000A0000)
-#define CSPI1_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000A4000)
-#define KPP_BASE_ADDR		(AIPS1_BASE_ADDR + 0x000A8000)
-#define IOMUXC_BASE_ADDR	(AIPS1_BASE_ADDR + 0x000AC000)
-#define ECT_IP1_BASE_ADDR	(AIPS1_BASE_ADDR + 0x000B8000)
-#define ECT_IP2_BASE_ADDR	(AIPS1_BASE_ADDR + 0x000BC000)
+#define MX3x_AIPS1_BASE_ADDR		0x43f00000
+#define MX3x_AIPS1_BASE_ADDR_VIRT	0xfc000000
+#define MX3x_AIPS1_SIZE			SZ_1M
+#define MX3x_MAX_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x04000)
+#define MX3x_EVTMON_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x08000)
+#define MX3x_CLKCTL_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x0c000)
+#define MX3x_ETB_SLOT4_BASE_ADDR		(MX3x_AIPS1_BASE_ADDR + 0x10000)
+#define MX3x_ETB_SLOT5_BASE_ADDR		(MX3x_AIPS1_BASE_ADDR + 0x14000)
+#define MX3x_ECT_CTIO_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x18000)
+#define MX3x_I2C_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x80000)
+#define MX3x_I2C3_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x84000)
+#define MX3x_UART1_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x90000)
+#define MX3x_UART2_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x94000)
+#define MX3x_I2C2_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x98000)
+#define MX3x_OWIRE_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0x9c000)
+#define MX3x_SSI1_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xa0000)
+#define MX3x_CSPI1_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xa4000)
+#define MX3x_KPP_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xa8000)
+#define MX3x_IOMUXC_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xac000)
+#define MX3x_ECT_IP1_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xb8000)
+#define MX3x_ECT_IP2_BASE_ADDR			(MX3x_AIPS1_BASE_ADDR + 0xbc000)
 
 /*
  * SPBA global module enabled #0
  */
-#define SPBA0_BASE_ADDR 	0x50000000
-#define SPBA0_BASE_ADDR_VIRT	0xFC100000
-#define SPBA0_SIZE		SZ_1M
-
-#define UART3_BASE_ADDR 	(SPBA0_BASE_ADDR + 0x0000C000)
-#define CSPI2_BASE_ADDR 	(SPBA0_BASE_ADDR + 0x00010000)
-#define SSI2_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00014000)
-#define ATA_DMA_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00020000)
-#define MSHC1_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00024000)
-#define SPBA_CTRL_BASE_ADDR	(SPBA0_BASE_ADDR + 0x0003C000)
+#define MX3x_SPBA0_BASE_ADDR		0x50000000
+#define MX3x_SPBA0_BASE_ADDR_VIRT	0xfc100000
+#define MX3x_SPBA0_SIZE			SZ_1M
+#define MX3x_UART3_BASE_ADDR			(MX3x_SPBA0_BASE_ADDR + 0x0c000)
+#define MX3x_CSPI2_BASE_ADDR			(MX3x_SPBA0_BASE_ADDR + 0x10000)
+#define MX3x_SSI2_BASE_ADDR			(MX3x_SPBA0_BASE_ADDR + 0x14000)
+#define MX3x_ATA_DMA_BASE_ADDR			(MX3x_SPBA0_BASE_ADDR + 0x20000)
+#define MX3x_MSHC1_BASE_ADDR			(MX3x_SPBA0_BASE_ADDR + 0x24000)
+#define MX3x_SPBA_CTRL_BASE_ADDR		(MX3x_SPBA0_BASE_ADDR + 0x3c000)
 
 /*
  * AIPS 2
  */
-#define AIPS2_BASE_ADDR		0x53F00000
-#define AIPS2_BASE_ADDR_VIRT	0xFC200000
-#define AIPS2_SIZE		SZ_1M
-#define CCM_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00080000)
-#define GPT1_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00090000)
-#define EPIT1_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00094000)
-#define EPIT2_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00098000)
-#define GPIO3_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000A4000)
-#define SCC_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000AC000)
-#define RNGA_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000B0000)
-#define IPU_CTRL_BASE_ADDR	(AIPS2_BASE_ADDR + 0x000C0000)
-#define AUDMUX_BASE_ADDR	(AIPS2_BASE_ADDR + 0x000C4000)
-#define GPIO1_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000CC000)
-#define GPIO2_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000D0000)
-#define SDMA_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000D4000)
-#define RTC_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000D8000)
-#define WDOG_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000DC000)
-#define PWM_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000E0000)
-#define RTIC_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000EC000)
+#define MX3x_AIPS2_BASE_ADDR		0x53f00000
+#define MX3x_AIPS2_BASE_ADDR_VIRT	0xfc200000
+#define MX3x_AIPS2_SIZE			SZ_1M
+#define MX3x_CCM_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0x80000)
+#define MX3x_GPT1_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0x90000)
+#define MX3x_EPIT1_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0x94000)
+#define MX3x_EPIT2_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0x98000)
+#define MX3x_GPIO3_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xa4000)
+#define MX3x_SCC_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xac000)
+#define MX3x_RNGA_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xb0000)
+#define MX3x_IPU_CTRL_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xc0000)
+#define MX3x_AUDMUX_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xc4000)
+#define MX3x_GPIO1_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xcc000)
+#define MX3x_GPIO2_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xd0000)
+#define MX3x_SDMA_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xd4000)
+#define MX3x_RTC_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xd8000)
+#define MX3x_WDOG_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xdc000)
+#define MX3x_PWM_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xe0000)
+#define MX3x_RTIC_BASE_ADDR			(MX3x_AIPS2_BASE_ADDR + 0xec000)
 
 /*
  * ROMP and AVIC
  */
-#define ROMP_BASE_ADDR		0x60000000
-#define ROMP_BASE_ADDR_VIRT	0xFC500000
-#define ROMP_SIZE		SZ_1M
+#define MX3x_ROMP_BASE_ADDR		0x60000000
+#define MX3x_ROMP_BASE_ADDR_VIRT	0xfc500000
+#define MX3x_ROMP_SIZE			SZ_1M
 
-#define AVIC_BASE_ADDR		0x68000000
-#define AVIC_BASE_ADDR_VIRT	0xFC400000
-#define AVIC_SIZE		SZ_1M
+#define MX3x_AVIC_BASE_ADDR		0x68000000
+#define MX3x_AVIC_BASE_ADDR_VIRT	0xfc400000
+#define MX3x_AVIC_SIZE			SZ_1M
 
 /*
- * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ * Memory regions and CS
  */
-#define X_MEMC_BASE_ADDR	0xB8000000
-#define X_MEMC_BASE_ADDR_VIRT	0xFC320000
-#define X_MEMC_SIZE		SZ_64K
+#define MX3x_IPU_MEM_BASE_ADDR		0x70000000
+#define MX3x_CSD0_BASE_ADDR		0x80000000
+#define MX3x_CSD1_BASE_ADDR		0x90000000
 
-#define ESDCTL_BASE_ADDR	(X_MEMC_BASE_ADDR + 0x1000)
-#define WEIM_BASE_ADDR		(X_MEMC_BASE_ADDR + 0x2000)
-#define M3IF_BASE_ADDR		(X_MEMC_BASE_ADDR + 0x3000)
-#define EMI_CTL_BASE_ADDR	(X_MEMC_BASE_ADDR + 0x4000)
-#define PCMCIA_CTL_BASE_ADDR	EMI_CTL_BASE_ADDR
+#define MX3x_CS0_BASE_ADDR		0xa0000000
+#define MX3x_CS1_BASE_ADDR		0xa8000000
+#define MX3x_CS2_BASE_ADDR		0xb0000000
+#define MX3x_CS3_BASE_ADDR		0xb2000000
+
+#define MX3x_CS4_BASE_ADDR		0xb4000000
+#define MX3x_CS4_BASE_ADDR_VIRT		0xf4000000
+#define MX3x_CS4_SIZE			SZ_32M
+
+#define MX3x_CS5_BASE_ADDR		0xb6000000
+#define MX3x_CS5_BASE_ADDR_VIRT		0xf6000000
+#define MX3x_CS5_SIZE			SZ_32M
 
 /*
- * Memory regions and CS
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
  */
-#define IPU_MEM_BASE_ADDR	0x70000000
-#define CSD0_BASE_ADDR		0x80000000
-#define CSD1_BASE_ADDR		0x90000000
+#define MX3x_X_MEMC_BASE_ADDR		0xb8000000
+#define MX3x_X_MEMC_BASE_ADDR_VIRT	0xfc320000
+#define MX3x_X_MEMC_SIZE		SZ_64K
+#define MX3x_ESDCTL_BASE_ADDR			(MX3x_X_MEMC_BASE_ADDR + 0x1000)
+#define MX3x_WEIM_BASE_ADDR			(MX3x_X_MEMC_BASE_ADDR + 0x2000)
+#define MX3x_M3IF_BASE_ADDR			(MX3x_X_MEMC_BASE_ADDR + 0x3000)
+#define MX3x_EMI_CTL_BASE_ADDR			(MX3x_X_MEMC_BASE_ADDR + 0x4000)
+#define MX3x_PCMCIA_CTL_BASE_ADDR		MX3x_EMI_CTL_BASE_ADDR
+
+#define MX3x_PCMCIA_MEM_BASE_ADDR	0xbc000000
 
 /*!
  * This macro defines the physical to virtual address mapping for all the
@@ -202,74 +199,207 @@
 /*
  * Interrupt numbers
  */
-#define MXC_INT_I2C3		3
-#define MXC_INT_I2C2		4
-#define MXC_INT_RTIC		6
-#define MXC_INT_I2C		10
-#define MXC_INT_CSPI2		13
-#define MXC_INT_CSPI1		14
-#define MXC_INT_ATA		15
-#define MXC_INT_UART3		18
-#define MXC_INT_IIM		19
-#define MXC_INT_RNGA		22
-#define MXC_INT_EVTMON		23
-#define MXC_INT_KPP		24
-#define MXC_INT_RTC		25
-#define MXC_INT_PWM		26
-#define MXC_INT_EPIT2		27
-#define MXC_INT_EPIT1		28
-#define MXC_INT_GPT		29
-#define MXC_INT_POWER_FAIL	30
-#define MXC_INT_UART2		32
-#define MXC_INT_NANDFC		33
-#define MXC_INT_SDMA		34
-#define MXC_INT_MSHC1		39
-#define MXC_INT_IPU_ERR		41
-#define MXC_INT_IPU_SYN		42
-#define MXC_INT_UART1		45
-#define MXC_INT_ECT		48
-#define MXC_INT_SCC_SCM		49
-#define MXC_INT_SCC_SMN		50
-#define MXC_INT_GPIO2		51
-#define MXC_INT_GPIO1		52
-#define MXC_INT_WDOG		55
-#define MXC_INT_GPIO3		56
-#define MXC_INT_EXT_POWER	58
-#define MXC_INT_EXT_TEMPER	59
-#define MXC_INT_EXT_SENSOR60	60
-#define MXC_INT_EXT_SENSOR61	61
-#define MXC_INT_EXT_WDOG	62
-#define MXC_INT_EXT_TV		63
+#define MX3x_INT_I2C3		3
+#define MX3x_INT_I2C2		4
+#define MX3x_INT_RTIC		6
+#define MX3x_INT_I2C		10
+#define MX3x_INT_CSPI2		13
+#define MX3x_INT_CSPI1		14
+#define MX3x_INT_ATA		15
+#define MX3x_INT_UART3		18
+#define MX3x_INT_IIM		19
+#define MX3x_INT_RNGA		22
+#define MX3x_INT_EVTMON		23
+#define MX3x_INT_KPP		24
+#define MX3x_INT_RTC		25
+#define MX3x_INT_PWM		26
+#define MX3x_INT_EPIT2		27
+#define MX3x_INT_EPIT1		28
+#define MX3x_INT_GPT		29
+#define MX3x_INT_POWER_FAIL	30
+#define MX3x_INT_UART2		32
+#define MX3x_INT_NANDFC		33
+#define MX3x_INT_SDMA		34
+#define MX3x_INT_MSHC1		39
+#define MX3x_INT_IPU_ERR	41
+#define MX3x_INT_IPU_SYN	42
+#define MX3x_INT_UART1		45
+#define MX3x_INT_ECT		48
+#define MX3x_INT_SCC_SCM	49
+#define MX3x_INT_SCC_SMN	50
+#define MX3x_INT_GPIO2		51
+#define MX3x_INT_GPIO1		52
+#define MX3x_INT_WDOG		55
+#define MX3x_INT_GPIO3		56
+#define MX3x_INT_EXT_POWER	58
+#define MX3x_INT_EXT_TEMPER	59
+#define MX3x_INT_EXT_SENSOR60	60
+#define MX3x_INT_EXT_SENSOR61	61
+#define MX3x_INT_EXT_WDOG	62
+#define MX3x_INT_EXT_TV		63
 
-#define PROD_SIGNATURE		0x1	/* For MX31 */
+#define MX3x_PROD_SIGNATURE		0x1	/* For MX31 */
 
 /* silicon revisions specific to i.MX31 */
-#define CHIP_REV_1_0		0x10
-#define CHIP_REV_1_1		0x11
-#define CHIP_REV_1_2		0x12
-#define CHIP_REV_1_3		0x13
-#define CHIP_REV_2_0		0x20
-#define CHIP_REV_2_1		0x21
-#define CHIP_REV_2_2		0x22
-#define CHIP_REV_2_3		0x23
-#define CHIP_REV_3_0		0x30
-#define CHIP_REV_3_1		0x31
-#define CHIP_REV_3_2		0x32
+#define MX3x_CHIP_REV_1_0		0x10
+#define MX3x_CHIP_REV_1_1		0x11
+#define MX3x_CHIP_REV_1_2		0x12
+#define MX3x_CHIP_REV_1_3		0x13
+#define MX3x_CHIP_REV_2_0		0x20
+#define MX3x_CHIP_REV_2_1		0x21
+#define MX3x_CHIP_REV_2_2		0x22
+#define MX3x_CHIP_REV_2_3		0x23
+#define MX3x_CHIP_REV_3_0		0x30
+#define MX3x_CHIP_REV_3_1		0x31
+#define MX3x_CHIP_REV_3_2		0x32
 
-#define SYSTEM_REV_MIN		CHIP_REV_1_0
-#define SYSTEM_REV_NUM		3
+#define MX3x_SYSTEM_REV_MIN		MX3x_CHIP_REV_1_0
+#define MX3x_SYSTEM_REV_NUM		3
 
 /* Mandatory defines used globally */
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
-extern unsigned int system_rev;
+extern unsigned int mx31_cpu_rev;
+extern void mx31_read_cpu_rev(void);
 
 static inline int mx31_revision(void)
 {
-	return system_rev;
+	return mx31_cpu_rev;
 }
 #endif
 
-#endif /*  __ASM_ARCH_MXC_MX31_H__ */
+/* these should go away */
+#define L2CC_BASE_ADDR MX3x_L2CC_BASE_ADDR
+#define L2CC_SIZE MX3x_L2CC_SIZE
+#define AIPS1_BASE_ADDR MX3x_AIPS1_BASE_ADDR
+#define AIPS1_BASE_ADDR_VIRT MX3x_AIPS1_BASE_ADDR_VIRT
+#define AIPS1_SIZE MX3x_AIPS1_SIZE
+#define MAX_BASE_ADDR MX3x_MAX_BASE_ADDR
+#define EVTMON_BASE_ADDR MX3x_EVTMON_BASE_ADDR
+#define CLKCTL_BASE_ADDR MX3x_CLKCTL_BASE_ADDR
+#define ETB_SLOT4_BASE_ADDR MX3x_ETB_SLOT4_BASE_ADDR
+#define ETB_SLOT5_BASE_ADDR MX3x_ETB_SLOT5_BASE_ADDR
+#define ECT_CTIO_BASE_ADDR MX3x_ECT_CTIO_BASE_ADDR
+#define I2C_BASE_ADDR MX3x_I2C_BASE_ADDR
+#define I2C3_BASE_ADDR MX3x_I2C3_BASE_ADDR
+#define UART1_BASE_ADDR MX3x_UART1_BASE_ADDR
+#define UART2_BASE_ADDR MX3x_UART2_BASE_ADDR
+#define I2C2_BASE_ADDR MX3x_I2C2_BASE_ADDR
+#define OWIRE_BASE_ADDR MX3x_OWIRE_BASE_ADDR
+#define SSI1_BASE_ADDR MX3x_SSI1_BASE_ADDR
+#define CSPI1_BASE_ADDR MX3x_CSPI1_BASE_ADDR
+#define KPP_BASE_ADDR MX3x_KPP_BASE_ADDR
+#define IOMUXC_BASE_ADDR MX3x_IOMUXC_BASE_ADDR
+#define ECT_IP1_BASE_ADDR MX3x_ECT_IP1_BASE_ADDR
+#define ECT_IP2_BASE_ADDR MX3x_ECT_IP2_BASE_ADDR
+#define SPBA0_BASE_ADDR MX3x_SPBA0_BASE_ADDR
+#define SPBA0_BASE_ADDR_VIRT MX3x_SPBA0_BASE_ADDR_VIRT
+#define SPBA0_SIZE MX3x_SPBA0_SIZE
+#define UART3_BASE_ADDR MX3x_UART3_BASE_ADDR
+#define CSPI2_BASE_ADDR MX3x_CSPI2_BASE_ADDR
+#define SSI2_BASE_ADDR MX3x_SSI2_BASE_ADDR
+#define ATA_DMA_BASE_ADDR MX3x_ATA_DMA_BASE_ADDR
+#define MSHC1_BASE_ADDR MX3x_MSHC1_BASE_ADDR
+#define SPBA_CTRL_BASE_ADDR MX3x_SPBA_CTRL_BASE_ADDR
+#define AIPS2_BASE_ADDR MX3x_AIPS2_BASE_ADDR
+#define AIPS2_BASE_ADDR_VIRT MX3x_AIPS2_BASE_ADDR_VIRT
+#define AIPS2_SIZE MX3x_AIPS2_SIZE
+#define CCM_BASE_ADDR MX3x_CCM_BASE_ADDR
+#define GPT1_BASE_ADDR MX3x_GPT1_BASE_ADDR
+#define EPIT1_BASE_ADDR MX3x_EPIT1_BASE_ADDR
+#define EPIT2_BASE_ADDR MX3x_EPIT2_BASE_ADDR
+#define GPIO3_BASE_ADDR MX3x_GPIO3_BASE_ADDR
+#define SCC_BASE_ADDR MX3x_SCC_BASE_ADDR
+#define RNGA_BASE_ADDR MX3x_RNGA_BASE_ADDR
+#define IPU_CTRL_BASE_ADDR MX3x_IPU_CTRL_BASE_ADDR
+#define AUDMUX_BASE_ADDR MX3x_AUDMUX_BASE_ADDR
+#define GPIO1_BASE_ADDR MX3x_GPIO1_BASE_ADDR
+#define GPIO2_BASE_ADDR MX3x_GPIO2_BASE_ADDR
+#define SDMA_BASE_ADDR MX3x_SDMA_BASE_ADDR
+#define RTC_BASE_ADDR MX3x_RTC_BASE_ADDR
+#define WDOG_BASE_ADDR MX3x_WDOG_BASE_ADDR
+#define PWM_BASE_ADDR MX3x_PWM_BASE_ADDR
+#define RTIC_BASE_ADDR MX3x_RTIC_BASE_ADDR
+#define ROMP_BASE_ADDR MX3x_ROMP_BASE_ADDR
+#define ROMP_BASE_ADDR_VIRT MX3x_ROMP_BASE_ADDR_VIRT
+#define ROMP_SIZE MX3x_ROMP_SIZE
+#define AVIC_BASE_ADDR MX3x_AVIC_BASE_ADDR
+#define AVIC_BASE_ADDR_VIRT MX3x_AVIC_BASE_ADDR_VIRT
+#define AVIC_SIZE MX3x_AVIC_SIZE
+#define IPU_MEM_BASE_ADDR MX3x_IPU_MEM_BASE_ADDR
+#define CSD0_BASE_ADDR MX3x_CSD0_BASE_ADDR
+#define CSD1_BASE_ADDR MX3x_CSD1_BASE_ADDR
+#define CS0_BASE_ADDR MX3x_CS0_BASE_ADDR
+#define CS1_BASE_ADDR MX3x_CS1_BASE_ADDR
+#define CS2_BASE_ADDR MX3x_CS2_BASE_ADDR
+#define CS3_BASE_ADDR MX3x_CS3_BASE_ADDR
+#define CS4_BASE_ADDR MX3x_CS4_BASE_ADDR
+#define CS4_BASE_ADDR_VIRT MX3x_CS4_BASE_ADDR_VIRT
+#define CS4_SIZE MX3x_CS4_SIZE
+#define CS5_BASE_ADDR MX3x_CS5_BASE_ADDR
+#define CS5_BASE_ADDR_VIRT MX3x_CS5_BASE_ADDR_VIRT
+#define CS5_SIZE MX3x_CS5_SIZE
+#define X_MEMC_BASE_ADDR MX3x_X_MEMC_BASE_ADDR
+#define X_MEMC_BASE_ADDR_VIRT MX3x_X_MEMC_BASE_ADDR_VIRT
+#define X_MEMC_SIZE MX3x_X_MEMC_SIZE
+#define ESDCTL_BASE_ADDR MX3x_ESDCTL_BASE_ADDR
+#define WEIM_BASE_ADDR MX3x_WEIM_BASE_ADDR
+#define M3IF_BASE_ADDR MX3x_M3IF_BASE_ADDR
+#define EMI_CTL_BASE_ADDR MX3x_EMI_CTL_BASE_ADDR
+#define PCMCIA_CTL_BASE_ADDR MX3x_PCMCIA_CTL_BASE_ADDR
+#define PCMCIA_MEM_BASE_ADDR MX3x_PCMCIA_MEM_BASE_ADDR
+#define MXC_INT_I2C3 MX3x_INT_I2C3
+#define MXC_INT_I2C2 MX3x_INT_I2C2
+#define MXC_INT_RTIC MX3x_INT_RTIC
+#define MXC_INT_I2C MX3x_INT_I2C
+#define MXC_INT_CSPI2 MX3x_INT_CSPI2
+#define MXC_INT_CSPI1 MX3x_INT_CSPI1
+#define MXC_INT_ATA MX3x_INT_ATA
+#define MXC_INT_UART3 MX3x_INT_UART3
+#define MXC_INT_IIM MX3x_INT_IIM
+#define MXC_INT_RNGA MX3x_INT_RNGA
+#define MXC_INT_EVTMON MX3x_INT_EVTMON
+#define MXC_INT_KPP MX3x_INT_KPP
+#define MXC_INT_RTC MX3x_INT_RTC
+#define MXC_INT_PWM MX3x_INT_PWM
+#define MXC_INT_EPIT2 MX3x_INT_EPIT2
+#define MXC_INT_EPIT1 MX3x_INT_EPIT1
+#define MXC_INT_GPT MX3x_INT_GPT
+#define MXC_INT_POWER_FAIL MX3x_INT_POWER_FAIL
+#define MXC_INT_UART2 MX3x_INT_UART2
+#define MXC_INT_NANDFC MX3x_INT_NANDFC
+#define MXC_INT_SDMA MX3x_INT_SDMA
+#define MXC_INT_MSHC1 MX3x_INT_MSHC1
+#define MXC_INT_IPU_ERR MX3x_INT_IPU_ERR
+#define MXC_INT_IPU_SYN MX3x_INT_IPU_SYN
+#define MXC_INT_UART1 MX3x_INT_UART1
+#define MXC_INT_ECT MX3x_INT_ECT
+#define MXC_INT_SCC_SCM MX3x_INT_SCC_SCM
+#define MXC_INT_SCC_SMN MX3x_INT_SCC_SMN
+#define MXC_INT_GPIO2 MX3x_INT_GPIO2
+#define MXC_INT_GPIO1 MX3x_INT_GPIO1
+#define MXC_INT_WDOG MX3x_INT_WDOG
+#define MXC_INT_GPIO3 MX3x_INT_GPIO3
+#define MXC_INT_EXT_POWER MX3x_INT_EXT_POWER
+#define MXC_INT_EXT_TEMPER MX3x_INT_EXT_TEMPER
+#define MXC_INT_EXT_SENSOR60 MX3x_INT_EXT_SENSOR60
+#define MXC_INT_EXT_SENSOR61 MX3x_INT_EXT_SENSOR61
+#define MXC_INT_EXT_WDOG MX3x_INT_EXT_WDOG
+#define MXC_INT_EXT_TV MX3x_INT_EXT_TV
+#define PROD_SIGNATURE MX3x_PROD_SIGNATURE
+#define CHIP_REV_1_0 MX3x_CHIP_REV_1_0
+#define CHIP_REV_1_1 MX3x_CHIP_REV_1_1
+#define CHIP_REV_1_2 MX3x_CHIP_REV_1_2
+#define CHIP_REV_1_3 MX3x_CHIP_REV_1_3
+#define CHIP_REV_2_0 MX3x_CHIP_REV_2_0
+#define CHIP_REV_2_1 MX3x_CHIP_REV_2_1
+#define CHIP_REV_2_2 MX3x_CHIP_REV_2_2
+#define CHIP_REV_2_3 MX3x_CHIP_REV_2_3
+#define CHIP_REV_3_0 MX3x_CHIP_REV_3_0
+#define CHIP_REV_3_1 MX3x_CHIP_REV_3_1
+#define CHIP_REV_3_2 MX3x_CHIP_REV_3_2
+#define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN
+#define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM
 
+#endif /*  __ASM_ARCH_MXC_MX31_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_ehci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,37 @@
+#ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H
+#define __INCLUDE_ASM_ARCH_MXC_EHCI_H
+
+/* values for portsc field */
+#define MXC_EHCI_PHY_LOW_POWER_SUSPEND	(1 << 23)
+#define MXC_EHCI_FORCE_FS		(1 << 24)
+#define MXC_EHCI_UTMI_8BIT		(0 << 28)
+#define MXC_EHCI_UTMI_16BIT		(1 << 28)
+#define MXC_EHCI_SERIAL			(1 << 29)
+#define MXC_EHCI_MODE_UTMI		(0 << 30)
+#define MXC_EHCI_MODE_PHILIPS		(1 << 30)
+#define MXC_EHCI_MODE_ULPI		(2 << 30)
+#define MXC_EHCI_MODE_SERIAL		(3 << 30)
+
+/* values for flags field */
+#define MXC_EHCI_INTERFACE_DIFF_UNI	(0 << 0)
+#define MXC_EHCI_INTERFACE_DIFF_BI	(1 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI	(2 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_BI	(3 << 0)
+#define MXC_EHCI_INTERFACE_MASK		(0xf)
+
+#define MXC_EHCI_POWER_PINS_ENABLED	(1 << 5)
+#define MXC_EHCI_TTL_ENABLED		(1 << 6)
+
+struct mxc_usbh_platform_data {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+
+	unsigned int		 portsc;
+	unsigned int		 flags;
+	struct otg_transceiver	*otg;
+};
+
+int mxc_set_usbcontrol(int port, unsigned int flags);
+
+#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mxc_nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/mxc_nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/mxc_nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 
 struct mxc_nand_platform_data {
 	int width;	/* data bus width in bytes */
-	int hw_ecc;	/* 0 if supress hardware ECC */
+	int hw_ecc:1;	/* 0 if supress hardware ECC */
+	int flash_bbt:1; /* set to 1 to use a flash based bbt */
 };
 #endif /* __ASM_ARCH_NAND_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/ulpi.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/ulpi.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/ulpi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/ulpi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,7 @@
+#ifndef __MACH_ULPI_H
+#define __MACH_ULPI_H
+
+extern struct otg_io_access_ops mxc_ulpi_access_ops;
+
+#endif /* __MACH_ULPI_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/include/mach/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,7 +60,9 @@ static void putc(int ch)
 	UART(TXR) = ch;
 }
 
-#define flush() do { } while (0)
+static inline void flush(void)
+{
+}
 
 #define MX1_UART1_BASE_ADDR	0x00206000
 #define MX25_UART1_BASE_ADDR	0x43f90000
@@ -83,6 +85,8 @@ static __inline__ void __arch_decomp_set
 	case MACH_TYPE_MX27ADS:
 	case MACH_TYPE_PCM038:
 	case MACH_TYPE_MX21ADS:
+	case MACH_TYPE_PCA100:
+	case MACH_TYPE_MXT_TD60:
 		uart_base = MX2X_UART1_BASE_ADDR;
 		break;
 	case MACH_TYPE_MX31LITE:
@@ -94,6 +98,7 @@ static __inline__ void __arch_decomp_set
 	case MACH_TYPE_MX31ADS:
 	case MACH_TYPE_MX35_3DS:
 	case MACH_TYPE_PCM043:
+	case MACH_TYPE_LILLY1131:
 		uart_base = MX3X_UART1_BASE_ADDR;
 		break;
 	case MACH_TYPE_MAGX_ZN5:
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/iomux-v3.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-v3.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/iomux-v3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/iomux-v3.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,19 +31,11 @@
 
 static void __iomem *base;
 
-static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG];
-
 /*
- * setups a single pin:
- * 	- reserves the pin so that it is not claimed by another driver
- * 	- setups the iomux according to the configuration
+ * setups a single pad in the iomuxer
  */
 int mxc_iomux_v3_setup_pad(struct pad_desc *pad)
 {
-	unsigned int pad_ofs = pad->pad_ctrl_ofs;
-
-	if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map))
-		return -EBUSY;
 	if (pad->mux_ctrl_ofs)
 		__raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs);
 
@@ -66,37 +58,13 @@ int mxc_iomux_v3_setup_multiple_pads(str
 	for (i = 0; i < count; i++) {
 		ret = mxc_iomux_v3_setup_pad(p);
 		if (ret)
-			goto setup_error;
+			return ret;
 		p++;
 	}
 	return 0;
-
-setup_error:
-	mxc_iomux_v3_release_multiple_pads(pad_list, i);
-	return ret;
 }
 EXPORT_SYMBOL(mxc_iomux_v3_setup_multiple_pads);
 
-void mxc_iomux_v3_release_pad(struct pad_desc *pad)
-{
-	unsigned int pad_ofs = pad->pad_ctrl_ofs;
-
-	clear_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map);
-}
-EXPORT_SYMBOL(mxc_iomux_v3_release_pad);
-
-void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count)
-{
-	struct pad_desc *p = pad_list;
-	int i;
-
-	for (i = 0; i < count; i++) {
-		mxc_iomux_v3_release_pad(p);
-		p++;
-	}
-}
-EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads);
-
 void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
 {
 	base = iomux_v3_base;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -69,10 +69,20 @@ config MXC_PWM
 	help
 	  Enable support for the i.MX PWM controller(s).
 
+config MXC_ULPI
+	bool
+
 config ARCH_HAS_RNGA
 	bool
 	depends on ARCH_MXC
 
 config ARCH_MXC_IOMUX_V3
 	bool
+
+config ARCH_MXC_AUDMUX_V1
+	bool
+
+config ARCH_MXC_AUDMUX_V2
+	bool
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,3 +9,7 @@ obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
+obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
+obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
+obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/pwm.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/pwm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/pwm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/pwm.c	2010-02-24 13:52:17.000000000 -0500
@@ -94,7 +94,7 @@ int pwm_config(struct pwm_device *pwm, i
 		 * register to follow the ratio of duty_ns vs. period_ns
 		 * accordingly.
 		 *
-		 * This is good enought for programming the brightness of
+		 * This is good enough for programming the brightness of
 		 * the LCD backlight.
 		 *
 		 * The real implementation would divide PERCLK[0] first by
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/ulpi.c linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ulpi.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-mxc/ulpi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-mxc/ulpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+/*
+ * 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 <mach/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 otg_transceiver *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 otg_transceiver *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 otg_io_access_ops mxc_ulpi_access_ops = {
+	.read	= ulpi_read,
+	.write	= ulpi_write,
+};
+EXPORT_SYMBOL_GPL(mxc_ulpi_access_ops);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/include/plat/mtu.h linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/include/plat/mtu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/include/plat/mtu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/include/plat/mtu.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,48 @@
+#ifndef __PLAT_MTU_H
+#define __PLAT_MTU_H
+
+/* should be set by the platform code */
+extern void __iomem *mtu_base;
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC	0x00	/* Interrupt mask set/clear */
+#define MTU_RIS		0x04	/* Raw interrupt status */
+#define MTU_MIS		0x08	/* Masked interrupt status */
+#define MTU_ICR		0x0C	/* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */
+#define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */
+#define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */
+#define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA		0x80
+#define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK	0x0c
+#define MTU_CRn_PRESCALE_1		0x00
+#define MTU_CRn_PRESCALE_16		0x04
+#define MTU_CRn_PRESCALE_256		0x08
+#define MTU_CRn_32BITS		0x02
+#define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR	0xff0
+#define MTU_ITOP	0xff4
+
+#define MTU_PERIPH_ID0	0xfe0
+#define MTU_PERIPH_ID1	0xfe4
+#define MTU_PERIPH_ID2	0xfe8
+#define MTU_PERIPH_ID3	0xfeC
+
+#define MTU_PCELL0	0xff0
+#define MTU_PCELL1	0xff4
+#define MTU_PCELL2	0xff8
+#define MTU_PCELL3	0xffC
+
+#endif /* __PLAT_MTU_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,22 @@
+# We keep common IP's here for Nomadik and other similar
+# familiy of processors from ST-Ericsson. At the moment we have
+# just MTU, others to follow soon.
+
+config PLAT_NOMADIK
+	bool
+	depends on ARCH_NOMADIK || ARCH_U8500
+	default y
+	help
+	  Common platform code for Nomadik and other ST-Ericsson
+	  platforms.
+
+if PLAT_NOMADIK
+
+config HAS_MTU
+	bool
+	help
+	  Support for Multi Timer Unit. MTU provides access
+	  to multiple interrupt generating programmable
+	  32-bit free running decrementing counters.
+
+endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+# arch/arm/plat-nomadik/Makefile
+# Copyright 2009 ST-Ericsson
+# Licensed under GPLv2
+
+obj-$(CONFIG_HAS_MTU)	+= timer.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/timer.c linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/timer.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-nomadik/timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-nomadik/timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,147 @@
+/*
+ *  linux/arch/arm/mach-nomadik/timer.c
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ *
+ * This 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/irq.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/jiffies.h>
+#include <asm/mach/time.h>
+
+#include <plat/mtu.h>
+
+static u32	nmdk_count;		/* accumulated count */
+static u32	nmdk_cycle;		/* write-once */
+
+/* setup by the platform code */
+void __iomem *mtu_base;
+
+/*
+ * clocksource: the MTU device is a decrementing counters, so we negate
+ * the value being read.
+ */
+static cycle_t nmdk_read_timer(struct clocksource *cs)
+{
+	u32 count = readl(mtu_base + MTU_VAL(0));
+	return nmdk_count + nmdk_cycle - count;
+
+}
+
+static struct clocksource nmdk_clksrc = {
+	.name		= "mtu_0",
+	.rating		= 120,
+	.read		= nmdk_read_timer,
+	.shift		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Clockevent device: currently only periodic mode is supported
+ */
+static void nmdk_clkevt_mode(enum clock_event_mode mode,
+			     struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* enable interrupts -- and count current value? */
+		raw_local_irq_save(flags);
+		writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+		raw_local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		BUG(); /* Not supported, yet */
+		/* FALLTHROUGH */
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		/* disable irq */
+		raw_local_irq_save(flags);
+		writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+		raw_local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device nmdk_clkevt = {
+	.name		= "mtu_0",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 32,
+	.rating		= 100,
+	.set_mode	= nmdk_clkevt_mode,
+};
+
+/*
+ * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
+ * as we are the only users of mtu0 by now.
+ */
+static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
+{
+	/* ack: "interrupt clear register" */
+	writel(1 << 0, mtu_base + MTU_ICR);
+
+	/* we can't count lost ticks, unfortunately */
+	nmdk_count += nmdk_cycle;
+	nmdk_clkevt.event_handler(&nmdk_clkevt);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static struct irqaction nmdk_timer_irq = {
+	.name		= "Nomadik Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER,
+	.handler	= nmdk_timer_interrupt,
+};
+
+static void nmdk_timer_reset(void)
+{
+	u32 cr;
+
+	writel(0, mtu_base + MTU_CR(0)); /* off */
+
+	/* configure load and background-load, and fire it up */
+	writel(nmdk_cycle, mtu_base + MTU_LR(0));
+	writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
+	cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
+	writel(cr, mtu_base + MTU_CR(0));
+	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+}
+
+void __init nmdk_timer_init(void)
+{
+	unsigned long rate;
+	int bits;
+
+	rate = CLOCK_TICK_RATE; /* 2.4MHz */
+	nmdk_cycle = (rate + HZ/2) / HZ;
+
+	/* Init the timer and register clocksource */
+	nmdk_timer_reset();
+
+	nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
+	bits =  8*sizeof(nmdk_count);
+	nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+
+	if (clocksource_register(&nmdk_clksrc))
+		printk(KERN_ERR "timer: failed to initialize clock "
+			"source %s\n", nmdk_clksrc.name);
+
+	/* Register irq and clockevents */
+	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+	nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+	nmdk_clkevt.cpumask = cpumask_of(0);
+	clockevents_register_device(&nmdk_clkevt);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #include <linux/debugfs.h>
 #include <linux/io.h>
 
-#include <mach/clock.h>
+#include <plat/clock.h>
 
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
@@ -36,40 +36,10 @@ static struct clk_functions *arch_clock;
  * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
-/* This functions is moved to arch/arm/common/clkdev.c. For OMAP4 since
- * clock framework is not up , it is defined here to avoid rework in
- * every driver. Also dummy prcm reset function is added */
-
-/* Dummy hooks only for OMAP4.For rest OMAPs, common clkdev is used */
-#if defined(CONFIG_ARCH_OMAP4)
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	return NULL;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
-void omap2_clk_prepare_for_reboot(void)
-{
-}
-EXPORT_SYMBOL(omap2_clk_prepare_for_reboot);
-
-void omap_prcm_arch_reset(char mode)
-{
-}
-EXPORT_SYMBOL(omap_prcm_arch_reset);
-#endif
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
 	int ret = 0;
-	if (cpu_is_omap44xx())
-		/* OMAP4 clk framework not supported yet */
-		return 0;
 
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
@@ -331,7 +301,6 @@ void clk_enable_init_clocks(void)
 			clk_enable(clkp);
 	}
 }
-EXPORT_SYMBOL(clk_enable_init_clocks);
 
 /*
  * Low level helpers
@@ -360,7 +329,16 @@ void clk_init_cpufreq_table(struct cpufr
 		arch_clock->clk_init_cpufreq_table(table);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
-EXPORT_SYMBOL(clk_init_cpufreq_table);
+
+void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	if (arch_clock->clk_exit_cpufreq_table)
+		arch_clock->clk_exit_cpufreq_table(table);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+}
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -413,7 +391,7 @@ static struct dentry *clk_debugfs_root;
 static int clk_debugfs_register_one(struct clk *c)
 {
 	int err;
-	struct dentry *d, *child;
+	struct dentry *d, *child, *child_tmp;
 	struct clk *pa = c->parent;
 	char s[255];
 	char *p = s;
@@ -445,7 +423,7 @@ static int clk_debugfs_register_one(stru
 
 err_out:
 	d = c->dent;
-	list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
+	list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
 		debugfs_remove(child);
 	debugfs_remove(c->dent);
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/common.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/common.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,13 +29,13 @@
 #include <asm/mach/map.h>
 #include <asm/setup.h>
 
-#include <mach/common.h>
-#include <mach/board.h>
-#include <mach/control.h>
-#include <mach/mux.h>
-#include <mach/fpga.h>
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/control.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
 
-#include <mach/clock.h>
+#include <plat/clock.h>
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 # include "../mach-omap2/sdrc.h"
@@ -49,6 +49,9 @@ int omap_bootloader_tag_len;
 struct omap_board_config_kernel *omap_board_config;
 int omap_board_config_size;
 
+/* used by omap-smp.c and board-4430sdp.c */
+void __iomem *gic_cpu_base_addr;
+
 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
 {
 	struct omap_board_config_kernel *kinfo = NULL;
@@ -169,6 +172,32 @@ unsigned long long sched_clock(void)
 				  clocksource_32k.mult, clocksource_32k.shift);
 }
 
+/**
+ * read_persistent_clock -  Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer.  Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+static struct timespec persistent_ts;
+static cycles_t cycles, last_cycles;
+void read_persistent_clock(struct timespec *ts)
+{
+	unsigned long long nsecs;
+	cycles_t delta;
+	struct timespec *tsp = &persistent_ts;
+
+	last_cycles = cycles;
+	cycles = clocksource_32k.read(&clocksource_32k);
+	delta = cycles - last_cycles;
+
+	nsecs = clocksource_cyc2ns(delta,
+				   clocksource_32k.mult, clocksource_32k.shift);
+
+	timespec_add_ns(tsp, nsecs);
+	*ts = *tsp;
+}
+
 static int __init omap_init_clocksource_32k(void)
 {
 	static char err[] __initdata = KERN_ERR
@@ -224,12 +253,12 @@ static void __init __omap2_set_globals(s
 
 static struct omap_globals omap242x_globals = {
 	.class	= OMAP242X_CLASS,
-	.tap	= OMAP2_IO_ADDRESS(0x48014000),
-	.sdrc	= OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
-	.sms	= OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
-	.ctrl	= OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
-	.prm	= OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
-	.cm	= OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
+	.tap	= OMAP2_L4_IO_ADDRESS(0x48014000),
+	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
+	.sms	= OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE),
+	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP2420_CTRL_BASE),
+	.prm	= OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE),
+	.cm	= OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE),
 };
 
 void __init omap2_set_globals_242x(void)
@@ -242,12 +271,12 @@ void __init omap2_set_globals_242x(void)
 
 static struct omap_globals omap243x_globals = {
 	.class	= OMAP243X_CLASS,
-	.tap	= OMAP2_IO_ADDRESS(0x4900a000),
-	.sdrc	= OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
-	.sms	= OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
-	.ctrl	= OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
-	.prm	= OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
-	.cm	= OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
+	.tap	= OMAP2_L4_IO_ADDRESS(0x4900a000),
+	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
+	.sms	= OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE),
+	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
+	.prm	= OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE),
+	.cm	= OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE),
 };
 
 void __init omap2_set_globals_243x(void)
@@ -260,12 +289,12 @@ void __init omap2_set_globals_243x(void)
 
 static struct omap_globals omap343x_globals = {
 	.class	= OMAP343X_CLASS,
-	.tap	= OMAP2_IO_ADDRESS(0x4830A000),
-	.sdrc	= OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
-	.sms	= OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
-	.ctrl	= OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
-	.prm	= OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
-	.cm	= OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
+	.tap	= OMAP2_L4_IO_ADDRESS(0x4830A000),
+	.sdrc	= OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
+	.sms	= OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE),
+	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
+	.prm	= OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE),
+	.cm	= OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
 };
 
 void __init omap2_set_globals_343x(void)
@@ -277,16 +306,18 @@ void __init omap2_set_globals_343x(void)
 #if defined(CONFIG_ARCH_OMAP4)
 static struct omap_globals omap4_globals = {
 	.class	= OMAP443X_CLASS,
-	.tap	= OMAP2_IO_ADDRESS(0x4830a000),
-	.ctrl	= OMAP2_IO_ADDRESS(OMAP443X_CTRL_BASE),
-	.prm	= OMAP2_IO_ADDRESS(OMAP4430_PRM_BASE),
-	.cm	= OMAP2_IO_ADDRESS(OMAP4430_CM_BASE),
+	.tap	= OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
+	.ctrl	= OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE),
+	.prm	= OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE),
+	.cm	= OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
+	.cm2	= OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE),
 };
 
 void __init omap2_set_globals_443x(void)
 {
 	omap2_set_globals_tap(&omap4_globals);
 	omap2_set_globals_control(&omap4_globals);
+	omap2_set_globals_prcm(&omap4_globals);
 }
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/cpu-omap.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/cpu-omap.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/cpu-omap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/cpu-omap.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <mach/clock.h>
+#include <plat/clock.h>
 #include <asm/system.h>
 
 #define VERY_HI_RATE	900000000
@@ -134,6 +134,7 @@ static int __init omap_cpu_init(struct c
 
 static int omap_cpu_exit(struct cpufreq_policy *policy)
 {
+	clk_exit_cpufreq_table(&freq_table);
 	clk_put(mpu_clk);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/debug-devices.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/debug-devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/debug-devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/debug-devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,10 +13,11 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/smc91x.h>
 
 #include <mach/hardware.h>
 
-#include <mach/board.h>
+#include <plat/board.h>
 #include <mach/gpio.h>
 
 
@@ -24,6 +25,12 @@
  * platforms include H2, H3, H4, and Perseus2.
  */
 
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.flags  = IORESOURCE_MEM,
@@ -36,6 +43,9 @@ static struct resource smc91x_resources[
 static struct platform_device smc91x_device = {
 	.name		= "smc91x",
 	.id		= -1,
+	.dev		= {
+		.platform_data = &smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(smc91x_resources),
 	.resource	= smc91x_resources,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/debug-leds.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/debug-leds.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/debug-leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/debug-leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
-#include <mach/fpga.h>
+#include <plat/fpga.h>
 #include <mach/gpio.h>
 
 
@@ -293,7 +293,7 @@ static int fpga_resume_noirq(struct devi
 	return 0;
 }
 
-static struct dev_pm_ops fpga_dev_pm_ops = {
+static const struct dev_pm_ops fpga_dev_pm_ops = {
 	.suspend_noirq = fpga_suspend_noirq,
 	.resume_noirq = fpga_resume_noirq,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/devices.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/devices.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/devices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,15 +19,15 @@
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <mach/tc.h>
-#include <mach/control.h>
-#include <mach/board.h>
-#include <mach/mmc.h>
-#include <mach/mux.h>
+#include <plat/tc.h>
+#include <plat/control.h>
+#include <plat/board.h>
+#include <plat/mmc.h>
+#include <plat/mux.h>
 #include <mach/gpio.h>
-#include <mach/menelaus.h>
-#include <mach/mcbsp.h>
-#include <mach/dsp_common.h>
+#include <plat/menelaus.h>
+#include <plat/mcbsp.h>
+#include <plat/dsp_common.h>
 
 #if	defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
 
@@ -113,17 +113,17 @@ static void omap_init_kp(void)
 		omap_cfg_reg(E19_1610_KBR4);
 		omap_cfg_reg(N19_1610_KBR5);
 	} else if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
-		omap_cfg_reg(E2_730_KBR0);
-		omap_cfg_reg(J7_730_KBR1);
-		omap_cfg_reg(E1_730_KBR2);
-		omap_cfg_reg(F3_730_KBR3);
-		omap_cfg_reg(D2_730_KBR4);
+		omap_cfg_reg(E2_7XX_KBR0);
+		omap_cfg_reg(J7_7XX_KBR1);
+		omap_cfg_reg(E1_7XX_KBR2);
+		omap_cfg_reg(F3_7XX_KBR3);
+		omap_cfg_reg(D2_7XX_KBR4);
 
-		omap_cfg_reg(C2_730_KBC0);
-		omap_cfg_reg(D3_730_KBC1);
-		omap_cfg_reg(E4_730_KBC2);
-		omap_cfg_reg(F4_730_KBC3);
-		omap_cfg_reg(E3_730_KBC4);
+		omap_cfg_reg(C2_7XX_KBC0);
+		omap_cfg_reg(D3_7XX_KBC1);
+		omap_cfg_reg(E4_7XX_KBC2);
+		omap_cfg_reg(F4_7XX_KBC3);
+		omap_cfg_reg(E3_7XX_KBC4);
 	} else if (machine_is_omap_h4()) {
 		omap_cfg_reg(T19_24XX_KBR0);
 		omap_cfg_reg(R19_24XX_KBR1);
@@ -242,6 +242,39 @@ fail:
 
 /*-------------------------------------------------------------------------*/
 
+#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define	OMAP_RNG_BASE		0x480A0000
+#else
+#define	OMAP_RNG_BASE		0xfffe5000
+#endif
+
+static struct resource rng_resources[] = {
+	{
+		.start		= OMAP_RNG_BASE,
+		.end		= OMAP_RNG_BASE + 0x4f,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_rng_device = {
+	.name		= "omap_rng",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(rng_resources),
+	.resource	= rng_resources,
+};
+
+static void omap_init_rng(void)
+{
+	(void) platform_device_register(&omap_rng_device);
+}
+#else
+static inline void omap_init_rng(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 /* Numbering for the SPI-capable controllers when used for SPI:
  * spi		= 1
  * uwire	= 2
@@ -324,39 +357,6 @@ static void omap_init_wdt(void)
 static inline void omap_init_wdt(void) {}
 #endif
 
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
-
-#ifdef CONFIG_ARCH_OMAP24XX
-#define	OMAP_RNG_BASE		0x480A0000
-#else
-#define	OMAP_RNG_BASE		0xfffe5000
-#endif
-
-static struct resource rng_resources[] = {
-	{
-		.start		= OMAP_RNG_BASE,
-		.end		= OMAP_RNG_BASE + 0x4f,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device omap_rng_device = {
-	.name	   = "omap_rng",
-	.id	     = -1,
-	.num_resources	= ARRAY_SIZE(rng_resources),
-	.resource	= rng_resources,
-};
-
-static void omap_init_rng(void)
-{
-	(void) platform_device_register(&omap_rng_device);
-}
-#else
-static inline void omap_init_rng(void) {}
-#endif
-
 /*
  * This gets called after board-specific INIT_MACHINE, and initializes most
  * on-chip peripherals accessible on this board (except for few like USB):
@@ -384,9 +384,9 @@ static int __init omap_init_devices(void
 	 */
 	omap_init_dsp();
 	omap_init_kp();
+	omap_init_rng();
 	omap_init_uwire();
 	omap_init_wdt();
-	omap_init_rng();
 	return 0;
 }
 arch_initcall(omap_init_devices);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/dma.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,9 +32,9 @@
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <mach/dma.h>
+#include <plat/dma.h>
 
-#include <mach/tc.h>
+#include <plat/tc.h>
 
 #undef DEBUG
 
@@ -47,13 +47,18 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTS
 #endif
 
 #define OMAP_DMA_ACTIVE			0x01
-#define OMAP_DMA_CCR_EN			(1 << 7)
 #define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
 
 #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
 
 static int enable_1510_mode;
 
+static struct omap_dma_global_context_registers {
+	u32 dma_irqenable_l0;
+	u32 dma_ocp_sysconfig;
+	u32 dma_gcr;
+} omap_dma_global_context;
+
 struct omap_dma_lch {
 	int next_lch;
 	int dev_id;
@@ -1114,17 +1119,8 @@ int omap_dma_running(void)
 {
 	int lch;
 
-	/*
-	 * On OMAP1510, internal LCD controller will start the transfer
-	 * when it gets enabled, so assume DMA running if LCD enabled.
-	 */
-	if (cpu_is_omap1510())
-		if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
-			return 1;
-
-	/* Check if LCD DMA is running */
-	if (cpu_is_omap16xx())
-		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+	if (cpu_class_is_omap1())
+		if (omap_lcd_dma_running())
 			return 1;
 
 	for (lch = 0; lch < dma_chan_count; lch++)
@@ -1187,7 +1183,7 @@ void omap_dma_unlink_lch(int lch_head, i
 	}
 
 	if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
-	    (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
+	    (dma_chan[lch_queue].flags & OMAP_DMA_ACTIVE)) {
 		printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
 		       "before unlinking\n");
 		dump_stack();
@@ -1246,7 +1242,7 @@ static void create_dma_lch_chain(int lch
  * 					      OMAP_DMA_DYNAMIC_CHAIN
  * @params - Channel parameters
  *
- * @return - Succes : 0
+ * @return - Success : 0
  * 	     Failure: -EINVAL/-ENOMEM
  */
 int omap_request_dma_chain(int dev_id, const char *dev_name,
@@ -1984,415 +1980,83 @@ static struct irqaction omap24xx_dma_irq
 
 /*----------------------------------------------------------------------------*/
 
-static struct lcd_dma_info {
-	spinlock_t lock;
-	int reserved;
-	void (*callback)(u16 status, void *data);
-	void *cb_data;
-
-	int active;
-	unsigned long addr, size;
-	int rotate, data_type, xres, yres;
-	int vxres;
-	int mirror;
-	int xscale, yscale;
-	int ext_ctrl;
-	int src_port;
-	int single_transfer;
-} lcd_dma;
-
-void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
-			 int data_type)
-{
-	lcd_dma.addr = addr;
-	lcd_dma.data_type = data_type;
-	lcd_dma.xres = fb_xres;
-	lcd_dma.yres = fb_yres;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1);
-
-void omap_set_lcd_dma_src_port(int port)
-{
-	lcd_dma.src_port = port;
-}
-
-void omap_set_lcd_dma_ext_controller(int external)
-{
-	lcd_dma.ext_ctrl = external;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
-
-void omap_set_lcd_dma_single_transfer(int single)
-{
-	lcd_dma.single_transfer = single;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
-
-void omap_set_lcd_dma_b1_rotation(int rotate)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
-		BUG();
-		return;
-	}
-	lcd_dma.rotate = rotate;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
-
-void omap_set_lcd_dma_b1_mirror(int mirror)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.mirror = mirror;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
-
-void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA virtual resulotion is not supported "
-				"in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.vxres = vxres;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
-
-void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.xscale = xscale;
-	lcd_dma.yscale = yscale;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
-
-static void set_b1_regs(void)
-{
-	unsigned long top, bottom;
-	int es;
-	u16 w;
-	unsigned long en, fn;
-	long ei, fi;
-	unsigned long vxres;
-	unsigned int xscale, yscale;
-
-	switch (lcd_dma.data_type) {
-	case OMAP_DMA_DATA_TYPE_S8:
-		es = 1;
-		break;
-	case OMAP_DMA_DATA_TYPE_S16:
-		es = 2;
-		break;
-	case OMAP_DMA_DATA_TYPE_S32:
-		es = 4;
-		break;
-	default:
-		BUG();
-		return;
-	}
-
-	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
-	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
-	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
-	BUG_ON(vxres < lcd_dma.xres);
-
-#define PIXADDR(x, y) (lcd_dma.addr +					\
-		((y) * vxres * yscale + (x) * xscale) * es)
-#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
-
-	switch (lcd_dma.rotate) {
-	case 0:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			/* 1510 DMA requires the bottom address to be 2 more
-			 * than the actual last memory access location. */
-			if (omap_dma_in_1510_mode() &&
-				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
-					bottom += 2;
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 90:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	case 180:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
-		} else {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 270:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
-		} else {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	default:
-		BUG();
-		return;	/* Suppress warning about uninitialized vars */
-	}
-
-	if (omap_dma_in_1510_mode()) {
-		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
-		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
-		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
-		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
-
-		return;
-	}
-
-	/* 1610 regs */
-	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
-	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
-	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
-	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
-
-	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
-	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
-	w &= ~0x03;
-	w |= lcd_dma.data_type;
-	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	/* Always set the source port as SDRAM for now*/
-	w &= ~(0x03 << 6);
-	if (lcd_dma.callback != NULL)
-		w |= 1 << 1;		/* Block interrupt enable */
-	else
-		w &= ~(1 << 1);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-
-	if (!(lcd_dma.rotate || lcd_dma.mirror ||
-	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	/* Set the double-indexed addressing mode */
-	w |= (0x03 << 12);
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-
-	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
-	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
-	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
-}
-
-static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
-{
-	u16 w;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	if (unlikely(!(w & (1 << 3)))) {
-		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
-		return IRQ_NONE;
-	}
-	/* Ack the IRQ */
-	w |= (1 << 3);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-	lcd_dma.active = 0;
-	if (lcd_dma.callback != NULL)
-		lcd_dma.callback(w, lcd_dma.cb_data);
-
-	return IRQ_HANDLED;
-}
-
-int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
-			 void *data)
+void omap_dma_global_context_save(void)
 {
-	spin_lock_irq(&lcd_dma.lock);
-	if (lcd_dma.reserved) {
-		spin_unlock_irq(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA channel already reserved\n");
-		BUG();
-		return -EBUSY;
-	}
-	lcd_dma.reserved = 1;
-	spin_unlock_irq(&lcd_dma.lock);
-	lcd_dma.callback = callback;
-	lcd_dma.cb_data = data;
-	lcd_dma.active = 0;
-	lcd_dma.single_transfer = 0;
-	lcd_dma.rotate = 0;
-	lcd_dma.vxres = 0;
-	lcd_dma.mirror = 0;
-	lcd_dma.xscale = 0;
-	lcd_dma.yscale = 0;
-	lcd_dma.ext_ctrl = 0;
-	lcd_dma.src_port = 0;
-
-	return 0;
+	omap_dma_global_context.dma_irqenable_l0 =
+		dma_read(IRQENABLE_L0);
+	omap_dma_global_context.dma_ocp_sysconfig =
+		dma_read(OCP_SYSCONFIG);
+	omap_dma_global_context.dma_gcr = dma_read(GCR);
 }
-EXPORT_SYMBOL(omap_request_lcd_dma);
 
-void omap_free_lcd_dma(void)
+void omap_dma_global_context_restore(void)
 {
-	spin_lock(&lcd_dma.lock);
-	if (!lcd_dma.reserved) {
-		spin_unlock(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA is not reserved\n");
-		BUG();
-		return;
-	}
-	if (!enable_1510_mode)
-		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
-			    OMAP1610_DMA_LCD_CCR);
-	lcd_dma.reserved = 0;
-	spin_unlock(&lcd_dma.lock);
-}
-EXPORT_SYMBOL(omap_free_lcd_dma);
+	int ch;
 
-void omap_enable_lcd_dma(void)
-{
-	u16 w;
+	dma_write(omap_dma_global_context.dma_gcr, GCR);
+	dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+		OCP_SYSCONFIG);
+	dma_write(omap_dma_global_context.dma_irqenable_l0,
+		IRQENABLE_L0);
 
 	/*
-	 * Set the Enable bit only if an external controller is
-	 * connected. Otherwise the OMAP internal controller will
-	 * start the transfer when it gets enabled.
+	 * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
+	 * after secure sram context save and restore. Hence we need to
+	 * manually clear those IRQs to avoid spurious interrupts. This
+	 * affects only secure devices.
 	 */
-	if (enable_1510_mode || !lcd_dma.ext_ctrl)
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	w |= 1 << 8;
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-
-	lcd_dma.active = 1;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	w |= 1 << 7;
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-}
-EXPORT_SYMBOL(omap_enable_lcd_dma);
-
-void omap_setup_lcd_dma(void)
-{
-	BUG_ON(lcd_dma.active);
-	if (!enable_1510_mode) {
-		/* Set some reasonable defaults */
-		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
-		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
-		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
-	}
-	set_b1_regs();
-	if (!enable_1510_mode) {
-		u16 w;
-
-		w = omap_readw(OMAP1610_DMA_LCD_CCR);
-		/*
-		 * If DMA was already active set the end_prog bit to have
-		 * the programmed register set loaded into the active
-		 * register set.
-		 */
-		w |= 1 << 11;		/* End_prog */
-		if (!lcd_dma.single_transfer)
-			w |= (3 << 8);	/* Auto_init, repeat */
-		omap_writew(w, OMAP1610_DMA_LCD_CCR);
-	}
-}
-EXPORT_SYMBOL(omap_setup_lcd_dma);
-
-void omap_stop_lcd_dma(void)
-{
-	u16 w;
-
-	lcd_dma.active = 0;
-	if (enable_1510_mode || !lcd_dma.ext_ctrl)
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	w &= ~(1 << 7);
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+	if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+		dma_write(0x3 , IRQSTATUS_L0);
 
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	w &= ~(1 << 8);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	for (ch = 0; ch < dma_chan_count; ch++)
+		if (dma_chan[ch].dev_id != -1)
+			omap_clear_dma(ch);
 }
-EXPORT_SYMBOL(omap_stop_lcd_dma);
 
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
 {
+	unsigned long base;
 	int ch, r;
 
 	if (cpu_class_is_omap1()) {
-		omap_dma_base = OMAP1_IO_ADDRESS(OMAP1_DMA_BASE);
+		base = OMAP1_DMA_BASE;
 		dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap24xx()) {
-		omap_dma_base = OMAP2_IO_ADDRESS(OMAP24XX_DMA4_BASE);
+		base = OMAP24XX_DMA4_BASE;
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap34xx()) {
-		omap_dma_base = OMAP2_IO_ADDRESS(OMAP34XX_DMA4_BASE);
+		base = OMAP34XX_DMA4_BASE;
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap44xx()) {
-		omap_dma_base = OMAP2_IO_ADDRESS(OMAP44XX_DMA4_BASE);
+		base = OMAP44XX_DMA4_BASE;
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else {
 		pr_err("DMA init failed for unsupported omap\n");
 		return -ENODEV;
 	}
 
+	omap_dma_base = ioremap(base, SZ_4K);
+	BUG_ON(!omap_dma_base);
+
 	if (cpu_class_is_omap2() && omap_dma_reserve_channels
 			&& (omap_dma_reserve_channels <= dma_lch_count))
 		dma_lch_count = omap_dma_reserve_channels;
 
 	dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
 				GFP_KERNEL);
-	if (!dma_chan)
-		return -ENOMEM;
+	if (!dma_chan) {
+		r = -ENOMEM;
+		goto out_unmap;
+	}
 
 	if (cpu_class_is_omap2()) {
 		dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
 						dma_lch_count, GFP_KERNEL);
 		if (!dma_linked_lch) {
-			kfree(dma_chan);
-			return -ENOMEM;
+			r = -ENOMEM;
+			goto out_free;
 		}
 	}
 
@@ -2420,14 +2084,6 @@ static int __init omap_init_dma(void)
 			dma_chan_count = 16;
 		} else
 			dma_chan_count = 9;
-		if (cpu_is_omap16xx()) {
-			u16 w;
-
-			/* this would prevent OMAP sleep */
-			w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-			w &= ~(1 << 8);
-			omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-		}
 	} else if (cpu_class_is_omap2()) {
 		u8 revision = dma_read(REVISION) & 0xff;
 		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
@@ -2438,7 +2094,6 @@ static int __init omap_init_dma(void)
 		return 0;
 	}
 
-	spin_lock_init(&lcd_dma.lock);
 	spin_lock_init(&dma_chan_lock);
 
 	for (ch = 0; ch < dma_chan_count; ch++) {
@@ -2466,7 +2121,7 @@ static int __init omap_init_dma(void)
 				for (i = 0; i < ch; i++)
 					free_irq(omap1_dma_irq[i],
 						 (void *) (i + 1));
-				return r;
+				goto out_free;
 			}
 		}
 	}
@@ -2484,8 +2139,8 @@ static int __init omap_init_dma(void)
 		setup_irq(irq, &omap24xx_dma_irq);
 	}
 
-	/* Enable smartidle idlemodes and autoidle */
 	if (cpu_is_omap34xx()) {
+		/* Enable smartidle idlemodes and autoidle */
 		u32 v = dma_read(OCP_SYSCONFIG);
 		v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
 				DMA_SYSCONFIG_SIDLEMODE_MASK |
@@ -2494,25 +2149,24 @@ static int __init omap_init_dma(void)
 			DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
 			DMA_SYSCONFIG_AUTOIDLE);
 		dma_write(v , OCP_SYSCONFIG);
+		/* reserve dma channels 0 and 1 in high security devices */
+		if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+			printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+					"HS ROM code\n");
+			dma_chan[0].dev_id = 0;
+			dma_chan[1].dev_id = 1;
+		}
 	}
 
+	return 0;
 
-	/* FIXME: Update LCD DMA to work on 24xx */
-	if (cpu_class_is_omap1()) {
-		r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
-				"LCD DMA", NULL);
-		if (r != 0) {
-			int i;
+out_free:
+	kfree(dma_chan);
 
-			printk(KERN_ERR "unable to request IRQ for LCD DMA "
-			       "(error %d)\n", r);
-			for (i = 0; i < dma_chan_count; i++)
-				free_irq(omap1_dma_irq[i], (void *) (i + 1));
-			return r;
-		}
-	}
+out_unmap:
+	iounmap(omap_dma_base);
 
-	return 0;
+	return r;
 }
 
 arch_initcall(omap_init_dma);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/dmtimer.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dmtimer.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/dmtimer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/dmtimer.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <mach/hardware.h>
-#include <mach/dmtimer.h>
+#include <plat/dmtimer.h>
 #include <mach/irqs.h>
 
 /* register offsets */
@@ -551,6 +551,19 @@ void omap_dm_timer_stop(struct omap_dm_t
 	if (l & OMAP_TIMER_CTRL_ST) {
 		l &= ~0x1;
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
+			defined(CONFIG_ARCH_OMAP4)
+		/* Readback to make sure write has completed */
+		omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+		 /*
+		  * Wait for functional clock period x 3.5 to make sure that
+		  * timer is stopped
+		  */
+		udelay(3500000 / clk_get_rate(timer->fclk) + 1);
+		/* Ack possibly pending interrupt */
+		omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
+				OMAP_TIMER_INT_OVERFLOW);
+#endif
 	}
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
@@ -742,16 +755,17 @@ EXPORT_SYMBOL_GPL(omap_dm_timers_active)
 int __init omap_dm_timer_init(void)
 {
 	struct omap_dm_timer *timer;
-	int i;
+	int i, map_size = SZ_8K;	/* Module 4KB + L4 4KB except on omap1 */
 
 	if (!(cpu_is_omap16xx() || cpu_class_is_omap2()))
 		return -ENODEV;
 
 	spin_lock_init(&dm_timer_lock);
 
-	if (cpu_class_is_omap1())
+	if (cpu_class_is_omap1()) {
 		dm_timers = omap1_dm_timers;
-	else if (cpu_is_omap24xx()) {
+		map_size = SZ_2K;
+	} else if (cpu_is_omap24xx()) {
 		dm_timers = omap2_dm_timers;
 		dm_source_names = omap2_dm_source_names;
 		dm_source_clocks = omap2_dm_source_clocks;
@@ -774,10 +788,11 @@ int __init omap_dm_timer_init(void)
 
 	for (i = 0; i < dm_timer_count; i++) {
 		timer = &dm_timers[i];
-		if (cpu_class_is_omap1())
-			timer->io_base = OMAP1_IO_ADDRESS(timer->phys_base);
-		else
-			timer->io_base = OMAP2_IO_ADDRESS(timer->phys_base);
+
+		/* Static mapping, never released */
+		timer->io_base = ioremap(timer->phys_base, map_size);
+		BUG_ON(!timer->io_base);
+
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
 					defined(CONFIG_ARCH_OMAP4)
 		if (cpu_class_is_omap2()) {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/fb.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/fb.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/fb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,13 +28,13 @@
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/omapfb.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 
-#include <mach/board.h>
-#include <mach/sram.h>
-#include <mach/omapfb.h>
+#include <plat/board.h>
+#include <plat/sram.h>
 
 #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
 
@@ -55,6 +55,10 @@ static struct platform_device omap_fb_de
 	.num_resources = 0,
 };
 
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
 static inline int ranges_overlap(unsigned long start1, unsigned long size1,
 				 unsigned long start2, unsigned long size2)
 {
@@ -327,7 +331,33 @@ static inline int omap_init_fb(void)
 
 arch_initcall(omap_init_fb);
 
-#else
+#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+static struct omapfb_platform_data omapfb_config;
+
+static struct platform_device omap_fb_device = {
+	.name		= "omapfb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &omap_fb_dma_mask,
+		.coherent_dma_mask	= ~(u32)0,
+		.platform_data		= &omapfb_config,
+	},
+	.num_resources = 0,
+};
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+	omapfb_config = *data;
+}
+
+static inline int omap_init_fb(void)
+{
+	return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
 
 void omapfb_reserve_sdram(void) {}
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
@@ -339,5 +369,20 @@ unsigned long omapfb_reserve_sram(unsign
 	return 0;
 }
 
+#else
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
+void omapfb_reserve_sdram(void) {}
+unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+				  unsigned long sram_vstart,
+				  unsigned long sram_size,
+				  unsigned long start_avail,
+				  unsigned long size_avail)
+{
+	return 0;
+}
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/gpio.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 /*
  * OMAP1510 GPIO registers
  */
-#define OMAP1510_GPIO_BASE		OMAP1_IO_ADDRESS(0xfffce000)
+#define OMAP1510_GPIO_BASE		0xfffce000
 #define OMAP1510_GPIO_DATA_INPUT	0x00
 #define OMAP1510_GPIO_DATA_OUTPUT	0x04
 #define OMAP1510_GPIO_DIR_CONTROL	0x08
@@ -45,10 +45,10 @@
 /*
  * OMAP1610 specific GPIO registers
  */
-#define OMAP1610_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbe400)
-#define OMAP1610_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbec00)
-#define OMAP1610_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbb400)
-#define OMAP1610_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbbc00)
+#define OMAP1610_GPIO1_BASE		0xfffbe400
+#define OMAP1610_GPIO2_BASE		0xfffbec00
+#define OMAP1610_GPIO3_BASE		0xfffbb400
+#define OMAP1610_GPIO4_BASE		0xfffbbc00
 #define OMAP1610_GPIO_REVISION		0x0000
 #define OMAP1610_GPIO_SYSCONFIG		0x0010
 #define OMAP1610_GPIO_SYSSTATUS		0x0014
@@ -68,52 +68,36 @@
 #define OMAP1610_GPIO_SET_DATAOUT	0x00f0
 
 /*
- * OMAP730 specific GPIO registers
- */
-#define OMAP730_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbc000)
-#define OMAP730_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbc800)
-#define OMAP730_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbd000)
-#define OMAP730_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbd800)
-#define OMAP730_GPIO5_BASE		OMAP1_IO_ADDRESS(0xfffbe000)
-#define OMAP730_GPIO6_BASE		OMAP1_IO_ADDRESS(0xfffbe800)
-#define OMAP730_GPIO_DATA_INPUT		0x00
-#define OMAP730_GPIO_DATA_OUTPUT	0x04
-#define OMAP730_GPIO_DIR_CONTROL	0x08
-#define OMAP730_GPIO_INT_CONTROL	0x0c
-#define OMAP730_GPIO_INT_MASK		0x10
-#define OMAP730_GPIO_INT_STATUS		0x14
-
-/*
- * OMAP850 specific GPIO registers
+ * OMAP7XX specific GPIO registers
  */
-#define OMAP850_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbc000)
-#define OMAP850_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbc800)
-#define OMAP850_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbd000)
-#define OMAP850_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbd800)
-#define OMAP850_GPIO5_BASE		OMAP1_IO_ADDRESS(0xfffbe000)
-#define OMAP850_GPIO6_BASE		OMAP1_IO_ADDRESS(0xfffbe800)
-#define OMAP850_GPIO_DATA_INPUT		0x00
-#define OMAP850_GPIO_DATA_OUTPUT	0x04
-#define OMAP850_GPIO_DIR_CONTROL	0x08
-#define OMAP850_GPIO_INT_CONTROL	0x0c
-#define OMAP850_GPIO_INT_MASK		0x10
-#define OMAP850_GPIO_INT_STATUS		0x14
+#define OMAP7XX_GPIO1_BASE		0xfffbc000
+#define OMAP7XX_GPIO2_BASE		0xfffbc800
+#define OMAP7XX_GPIO3_BASE		0xfffbd000
+#define OMAP7XX_GPIO4_BASE		0xfffbd800
+#define OMAP7XX_GPIO5_BASE		0xfffbe000
+#define OMAP7XX_GPIO6_BASE		0xfffbe800
+#define OMAP7XX_GPIO_DATA_INPUT		0x00
+#define OMAP7XX_GPIO_DATA_OUTPUT	0x04
+#define OMAP7XX_GPIO_DIR_CONTROL	0x08
+#define OMAP7XX_GPIO_INT_CONTROL	0x0c
+#define OMAP7XX_GPIO_INT_MASK		0x10
+#define OMAP7XX_GPIO_INT_STATUS		0x14
 
-#define OMAP1_MPUIO_VBASE		OMAP1_IO_ADDRESS(OMAP1_MPUIO_BASE)
+#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE
 
 /*
  * omap24xx specific GPIO registers
  */
-#define OMAP242X_GPIO1_BASE		OMAP2_IO_ADDRESS(0x48018000)
-#define OMAP242X_GPIO2_BASE		OMAP2_IO_ADDRESS(0x4801a000)
-#define OMAP242X_GPIO3_BASE		OMAP2_IO_ADDRESS(0x4801c000)
-#define OMAP242X_GPIO4_BASE		OMAP2_IO_ADDRESS(0x4801e000)
+#define OMAP242X_GPIO1_BASE		0x48018000
+#define OMAP242X_GPIO2_BASE		0x4801a000
+#define OMAP242X_GPIO3_BASE		0x4801c000
+#define OMAP242X_GPIO4_BASE		0x4801e000
 
-#define OMAP243X_GPIO1_BASE		OMAP2_IO_ADDRESS(0x4900C000)
-#define OMAP243X_GPIO2_BASE		OMAP2_IO_ADDRESS(0x4900E000)
-#define OMAP243X_GPIO3_BASE		OMAP2_IO_ADDRESS(0x49010000)
-#define OMAP243X_GPIO4_BASE		OMAP2_IO_ADDRESS(0x49012000)
-#define OMAP243X_GPIO5_BASE		OMAP2_IO_ADDRESS(0x480B6000)
+#define OMAP243X_GPIO1_BASE		0x4900C000
+#define OMAP243X_GPIO2_BASE		0x4900E000
+#define OMAP243X_GPIO3_BASE		0x49010000
+#define OMAP243X_GPIO4_BASE		0x49012000
+#define OMAP243X_GPIO5_BASE		0x480B6000
 
 #define OMAP24XX_GPIO_REVISION		0x0000
 #define OMAP24XX_GPIO_SYSCONFIG		0x0010
@@ -170,24 +154,25 @@
  * omap34xx specific GPIO registers
  */
 
-#define OMAP34XX_GPIO1_BASE		OMAP2_IO_ADDRESS(0x48310000)
-#define OMAP34XX_GPIO2_BASE		OMAP2_IO_ADDRESS(0x49050000)
-#define OMAP34XX_GPIO3_BASE		OMAP2_IO_ADDRESS(0x49052000)
-#define OMAP34XX_GPIO4_BASE		OMAP2_IO_ADDRESS(0x49054000)
-#define OMAP34XX_GPIO5_BASE		OMAP2_IO_ADDRESS(0x49056000)
-#define OMAP34XX_GPIO6_BASE		OMAP2_IO_ADDRESS(0x49058000)
+#define OMAP34XX_GPIO1_BASE		0x48310000
+#define OMAP34XX_GPIO2_BASE		0x49050000
+#define OMAP34XX_GPIO3_BASE		0x49052000
+#define OMAP34XX_GPIO4_BASE		0x49054000
+#define OMAP34XX_GPIO5_BASE		0x49056000
+#define OMAP34XX_GPIO6_BASE		0x49058000
 
 /*
  * OMAP44XX  specific GPIO registers
  */
-#define OMAP44XX_GPIO1_BASE             OMAP2_IO_ADDRESS(0x4a310000)
-#define OMAP44XX_GPIO2_BASE             OMAP2_IO_ADDRESS(0x48055000)
-#define OMAP44XX_GPIO3_BASE             OMAP2_IO_ADDRESS(0x48057000)
-#define OMAP44XX_GPIO4_BASE             OMAP2_IO_ADDRESS(0x48059000)
-#define OMAP44XX_GPIO5_BASE             OMAP2_IO_ADDRESS(0x4805B000)
-#define OMAP44XX_GPIO6_BASE             OMAP2_IO_ADDRESS(0x4805D000)
+#define OMAP44XX_GPIO1_BASE             0x4a310000
+#define OMAP44XX_GPIO2_BASE             0x48055000
+#define OMAP44XX_GPIO3_BASE             0x48057000
+#define OMAP44XX_GPIO4_BASE             0x48059000
+#define OMAP44XX_GPIO5_BASE             0x4805B000
+#define OMAP44XX_GPIO6_BASE             0x4805D000
 
 struct gpio_bank {
+	unsigned long pbase;
 	void __iomem *base;
 	u16 irq;
 	u16 virtual_irq_start;
@@ -207,104 +192,138 @@ struct gpio_bank {
 	u32 saved_risingdetect;
 #endif
 	u32 level_mask;
+	u32 toggle_mask;
 	spinlock_t lock;
 	struct gpio_chip chip;
 	struct clk *dbck;
+	u32 mod_usage;
 };
 
 #define METHOD_MPUIO		0
 #define METHOD_GPIO_1510	1
 #define METHOD_GPIO_1610	2
-#define METHOD_GPIO_730		3
-#define METHOD_GPIO_850		4
+#define METHOD_GPIO_7XX		3
 #define METHOD_GPIO_24XX	5
 
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
-	{ OMAP1_MPUIO_VBASE,    INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
-	{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,	    IH_GPIO_BASE,      METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO4_BASE, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, METHOD_GPIO_1610 },
+	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
+		METHOD_MPUIO },
+	{ OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16,
+		METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32,
+		METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48,
+		METHOD_GPIO_1610 },
 };
 #endif
 
 #ifdef CONFIG_ARCH_OMAP15XX
 static struct gpio_bank gpio_bank_1510[2] = {
-	{ OMAP1_MPUIO_VBASE,   INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
-	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP730
-static struct gpio_bank gpio_bank_730[7] = {
-	{ OMAP1_MPUIO_VBASE,    INT_730_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
-	{ OMAP730_GPIO1_BASE,  INT_730_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO2_BASE,  INT_730_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO3_BASE,  INT_730_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO4_BASE,  INT_730_GPIO_BANK4,  IH_GPIO_BASE + 96,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO5_BASE,  INT_730_GPIO_BANK5,  IH_GPIO_BASE + 128, METHOD_GPIO_730 },
-	{ OMAP730_GPIO6_BASE,  INT_730_GPIO_BANK6,  IH_GPIO_BASE + 160, METHOD_GPIO_730 },
+	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE,
+		METHOD_MPUIO },
+	{ OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_1510 }
 };
 #endif
 
-#ifdef CONFIG_ARCH_OMAP850
-static struct gpio_bank gpio_bank_850[7] = {
-	{ OMAP1_MPUIO_VBASE,     INT_850_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
-	{ OMAP850_GPIO1_BASE,  INT_850_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_850 },
-	{ OMAP850_GPIO2_BASE,  INT_850_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_850 },
-	{ OMAP850_GPIO3_BASE,  INT_850_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_850 },
-	{ OMAP850_GPIO4_BASE,  INT_850_GPIO_BANK4,  IH_GPIO_BASE + 96,	METHOD_GPIO_850 },
-	{ OMAP850_GPIO5_BASE,  INT_850_GPIO_BANK5,  IH_GPIO_BASE + 128, METHOD_GPIO_850 },
-	{ OMAP850_GPIO6_BASE,  INT_850_GPIO_BANK6,  IH_GPIO_BASE + 160, METHOD_GPIO_850 },
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+static struct gpio_bank gpio_bank_7xx[7] = {
+	{ OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE,
+		METHOD_MPUIO },
+	{ OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_7XX },
+	{ OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32,
+		METHOD_GPIO_7XX },
+	{ OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64,
+		METHOD_GPIO_7XX },
+	{ OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4,  IH_GPIO_BASE + 96,
+		METHOD_GPIO_7XX },
+	{ OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5,  IH_GPIO_BASE + 128,
+		METHOD_GPIO_7XX },
+	{ OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6,  IH_GPIO_BASE + 160,
+		METHOD_GPIO_7XX },
 };
 #endif
 
-
 #ifdef CONFIG_ARCH_OMAP24XX
 
 static struct gpio_bank gpio_bank_242x[4] = {
-	{ OMAP242X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
-	{ OMAP242X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
+		METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
+		METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
+		METHOD_GPIO_24XX },
 };
 
 static struct gpio_bank gpio_bank_243x[5] = {
-	{ OMAP243X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
-	{ OMAP243X_GPIO5_BASE, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,
+		METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,
+		METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,
+		METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128,
+		METHOD_GPIO_24XX },
 };
 
 #endif
 
 #ifdef CONFIG_ARCH_OMAP34XX
 static struct gpio_bank gpio_bank_34xx[6] = {
-	{ OMAP34XX_GPIO1_BASE, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO2_BASE, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO3_BASE, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO4_BASE, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO5_BASE, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX },
-	{ OMAP34XX_GPIO6_BASE, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE,
+		METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO2_BASE, NULL, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32,
+		METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO3_BASE, NULL, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64,
+		METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO4_BASE, NULL, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96,
+		METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO5_BASE, NULL, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128,
+		METHOD_GPIO_24XX },
+	{ OMAP34XX_GPIO6_BASE, NULL, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160,
+		METHOD_GPIO_24XX },
+};
+
+struct omap3_gpio_regs {
+	u32 sysconfig;
+	u32 irqenable1;
+	u32 irqenable2;
+	u32 wake_en;
+	u32 ctrl;
+	u32 oe;
+	u32 leveldetect0;
+	u32 leveldetect1;
+	u32 risingdetect;
+	u32 fallingdetect;
+	u32 dataout;
+	u32 setwkuena;
+	u32 setdataout;
 };
 
+static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
 static struct gpio_bank gpio_bank_44xx[6] = {
-	{ OMAP44XX_GPIO1_BASE, INT_44XX_GPIO_BANK1, IH_GPIO_BASE,	\
+	{ OMAP44XX_GPIO1_BASE, NULL, INT_44XX_GPIO_BANK1, IH_GPIO_BASE,
 		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO2_BASE, INT_44XX_GPIO_BANK2, IH_GPIO_BASE + 32,	\
+	{ OMAP44XX_GPIO2_BASE, NULL, INT_44XX_GPIO_BANK2, IH_GPIO_BASE + 32,
 		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO3_BASE, INT_44XX_GPIO_BANK3, IH_GPIO_BASE + 64,	\
+	{ OMAP44XX_GPIO3_BASE, NULL, INT_44XX_GPIO_BANK3, IH_GPIO_BASE + 64,
 		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO4_BASE, INT_44XX_GPIO_BANK4, IH_GPIO_BASE + 96,	\
+	{ OMAP44XX_GPIO4_BASE, NULL, INT_44XX_GPIO_BANK4, IH_GPIO_BASE + 96,
 		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO5_BASE, INT_44XX_GPIO_BANK5, IH_GPIO_BASE + 128, \
+	{ OMAP44XX_GPIO5_BASE, NULL, INT_44XX_GPIO_BANK5, IH_GPIO_BASE + 128,
 		METHOD_GPIO_24XX },
-	{ OMAP44XX_GPIO6_BASE, INT_44XX_GPIO_BANK6, IH_GPIO_BASE + 160, \
+	{ OMAP44XX_GPIO6_BASE, NULL, INT_44XX_GPIO_BANK6, IH_GPIO_BASE + 160,
 		METHOD_GPIO_24XX },
 };
 
@@ -402,14 +421,9 @@ static void _set_gpio_direction(struct g
 		reg += OMAP1610_GPIO_DIRECTION;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DIR_CONTROL;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_DIR_CONTROL;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DIR_CONTROL;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
@@ -469,19 +483,9 @@ static void _set_gpio_dataout(struct gpi
 		l = 1 << gpio;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_DATA_OUTPUT;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_OUTPUT;
 		l = __raw_readl(reg);
 		if (enable)
 			l |= 1 << gpio;
@@ -537,14 +541,9 @@ static int _get_gpio_datain(struct gpio_
 		reg += OMAP1610_GPIO_DATAIN;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DATA_INPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_DATA_INPUT;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_INPUT;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
@@ -588,14 +587,9 @@ static int _get_gpio_dataout(struct gpio
 		reg += OMAP1610_GPIO_DATAOUT;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DATA_OUTPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_DATA_OUTPUT;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_OUTPUT;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
@@ -636,6 +630,10 @@ void omap_set_gpio_debounce(int gpio, in
 #else
 	reg += OMAP24XX_GPIO_DEBOUNCE_EN;
 #endif
+	if (!(bank->mod_usage & l)) {
+		printk(KERN_ERR "GPIO %d not requested\n", gpio);
+		return;
+	}
 
 	spin_lock_irqsave(&bank->lock, flags);
 	val = __raw_readl(reg);
@@ -671,6 +669,11 @@ void omap_set_gpio_debounce_time(int gpi
 	bank = get_gpio_bank(gpio);
 	reg = bank->base;
 
+	if (!bank->mod_usage) {
+		printk(KERN_ERR "GPIO not requested\n");
+		return;
+	}
+
 	enc_time &= 0xff;
 #ifdef CONFIG_ARCH_OMAP4
 	reg += OMAP4_GPIO_DEBOUNCINGTIME;
@@ -747,6 +750,44 @@ static inline void set_24xx_gpio_trigger
 }
 #endif
 
+#ifdef CONFIG_ARCH_OMAP1
+/*
+ * This only applies to chips that can't do both rising and falling edge
+ * detection at once.  For all other chips, this function is a noop.
+ */
+static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
+{
+	void __iomem *reg = bank->base;
+	u32 l = 0;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_INT_EDGE;
+		break;
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_CONTROL;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_CONTROL;
+		break;
+#endif
+	default:
+		return;
+	}
+
+	l = __raw_readl(reg);
+	if ((l >> gpio) & 1)
+		l &= ~(1 << gpio);
+	else
+		l |= 1 << gpio;
+
+	__raw_writel(l, reg);
+}
+#endif
+
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
 	void __iomem *reg = bank->base;
@@ -757,6 +798,8 @@ static int _set_gpio_triggering(struct g
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		l = __raw_readl(reg);
+		if (trigger & IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
@@ -769,6 +812,8 @@ static int _set_gpio_triggering(struct g
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
+		if (trigger & IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
@@ -797,22 +842,12 @@ static int _set_gpio_triggering(struct g
 			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_INT_CONTROL;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
+		if (trigger & IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
 		if (trigger & IRQ_TYPE_EDGE_RISING)
 			l |= 1 << gpio;
 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
@@ -897,14 +932,9 @@ static void _clear_gpio_irqbank(struct g
 		reg += OMAP1610_GPIO_IRQSTATUS1;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_STATUS;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_INT_STATUS;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_STATUS;
 		break;
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
@@ -971,16 +1001,9 @@ static u32 _get_gpio_irqbank_mask(struct
 		mask = 0xffff;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_MASK;
-		mask = 0xffffffff;
-		inv = 1;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_INT_MASK;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_MASK;
 		mask = 0xffffffff;
 		inv = 1;
 		break;
@@ -1044,19 +1067,9 @@ static void _enable_gpio_irqbank(struct
 		l = gpio_mask;
 		break;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_INT_MASK;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_MASK;
 		l = __raw_readl(reg);
 		if (enable)
 			l &= ~(gpio_mask);
@@ -1104,7 +1117,7 @@ static inline void _set_gpio_irqenable(s
  */
 static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 {
-	unsigned long flags;
+	unsigned long uninitialized_var(flags);
 
 	switch (bank->method) {
 #ifdef CONFIG_ARCH_OMAP16XX
@@ -1186,6 +1199,16 @@ static int omap_gpio_request(struct gpio
 		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
 	}
 #endif
+	if (!cpu_class_is_omap1()) {
+		if (!bank->mod_usage) {
+			u32 ctrl;
+			ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+			ctrl &= 0xFFFFFFFE;
+			/* Module is enabled, clocks are not gated */
+			__raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+		}
+		bank->mod_usage |= 1 << offset;
+	}
 	spin_unlock_irqrestore(&bank->lock, flags);
 
 	return 0;
@@ -1212,6 +1235,16 @@ static void omap_gpio_free(struct gpio_c
 		__raw_writel(1 << offset, reg);
 	}
 #endif
+	if (!cpu_class_is_omap1()) {
+		bank->mod_usage &= ~(1 << offset);
+		if (!bank->mod_usage) {
+			u32 ctrl;
+			ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+			/* Module is disabled, clocks are gated */
+			ctrl |= 1;
+			__raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL);
+		}
+	}
 	_reset_gpio(bank, bank->chip.base + offset);
 	spin_unlock_irqrestore(&bank->lock, flags);
 }
@@ -1229,7 +1262,7 @@ static void gpio_irq_handler(unsigned in
 {
 	void __iomem *isr_reg = NULL;
 	u32 isr;
-	unsigned int gpio_irq;
+	unsigned int gpio_irq, gpio_index;
 	struct gpio_bank *bank;
 	u32 retrigger = 0;
 	int unmasked = 0;
@@ -1249,13 +1282,9 @@ static void gpio_irq_handler(unsigned in
 	if (bank->method == METHOD_GPIO_1610)
 		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
 #endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (bank->method == METHOD_GPIO_730)
-		isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-	if (bank->method == METHOD_GPIO_850)
-		isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	if (bank->method == METHOD_GPIO_7XX)
+		isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	if (bank->method == METHOD_GPIO_24XX)
@@ -1300,9 +1329,23 @@ static void gpio_irq_handler(unsigned in
 
 		gpio_irq = bank->virtual_irq_start;
 		for (; isr != 0; isr >>= 1, gpio_irq++) {
+			gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
+
 			if (!(isr & 1))
 				continue;
 
+#ifdef CONFIG_ARCH_OMAP1
+			/*
+			 * Some chips can't respond to both rising and falling
+			 * at the same time.  If this irq was requested with
+			 * both flags, we need to flip the ICR data for the IRQ
+			 * to respond to the IRQ for the opposite direction.
+			 * This will be indicated in the bank toggle_mask.
+			 */
+			if (bank->toggle_mask & (1 << gpio_index))
+				_toggle_gpio_edge_triggering(bank, gpio_index);
+#endif
+
 			generic_handle_irq(gpio_irq);
 		}
 	}
@@ -1447,7 +1490,7 @@ static int omap_mpuio_resume_noirq(struc
 	return 0;
 }
 
-static struct dev_pm_ops omap_mpuio_dev_pm_ops = {
+static const struct dev_pm_ops omap_mpuio_dev_pm_ops = {
 	.suspend_noirq = omap_mpuio_suspend_noirq,
 	.resume_noirq = omap_mpuio_resume_noirq,
 };
@@ -1524,11 +1567,8 @@ static int gpio_is_input(struct gpio_ban
 	case METHOD_GPIO_1610:
 		reg += OMAP1610_GPIO_DIRECTION;
 		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_850:
-		reg += OMAP850_GPIO_DIR_CONTROL;
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DIR_CONTROL;
 		break;
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
@@ -1607,6 +1647,23 @@ static struct clk * gpio5_fck;
 static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS];
 #endif
 
+static void __init omap_gpio_show_rev(void)
+{
+	u32 rev;
+
+	if (cpu_is_omap16xx())
+		rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+	else if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+	else if (cpu_is_omap44xx())
+		rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
+	else
+		return;
+
+	printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
+		(rev >> 4) & 0x0f, rev & 0x0f);
+}
+
 /* This lock class tells lockdep that GPIO irqs are in a different
  * category than their parents, so it won't report false recursion.
  */
@@ -1617,6 +1674,7 @@ static int __init _omap_gpio_init(void)
 	int i;
 	int gpio = 0;
 	struct gpio_bank *bank;
+	int bank_size = SZ_8K;	/* Module 4KB + L4 4KB except on omap1 */
 	char clk_name[11];
 
 	initialized = 1;
@@ -1679,77 +1737,45 @@ static int __init _omap_gpio_init(void)
 
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap15xx()) {
-		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
 		gpio_bank_count = 2;
 		gpio_bank = gpio_bank_1510;
+		bank_size = SZ_2K;
 	}
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
 	if (cpu_is_omap16xx()) {
-		u32 rev;
-
 		gpio_bank_count = 5;
 		gpio_bank = gpio_bank_1610;
-		rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
-		printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
-		       (rev >> 4) & 0x0f, rev & 0x0f);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		printk(KERN_INFO "OMAP730 GPIO hardware\n");
-		gpio_bank_count = 7;
-		gpio_bank = gpio_bank_730;
+		bank_size = SZ_2K;
 	}
 #endif
-#ifdef CONFIG_ARCH_OMAP850
-	if (cpu_is_omap850()) {
-		printk(KERN_INFO "OMAP850 GPIO hardware\n");
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	if (cpu_is_omap7xx()) {
 		gpio_bank_count = 7;
-		gpio_bank = gpio_bank_850;
+		gpio_bank = gpio_bank_7xx;
+		bank_size = SZ_2K;
 	}
 #endif
-
 #ifdef CONFIG_ARCH_OMAP24XX
 	if (cpu_is_omap242x()) {
-		int rev;
-
 		gpio_bank_count = 4;
 		gpio_bank = gpio_bank_242x;
-		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
-		printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n",
-			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
 	if (cpu_is_omap243x()) {
-		int rev;
-
 		gpio_bank_count = 5;
 		gpio_bank = gpio_bank_243x;
-		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
-		printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
-			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP34XX
 	if (cpu_is_omap34xx()) {
-		int rev;
-
 		gpio_bank_count = OMAP34XX_NR_GPIOS;
 		gpio_bank = gpio_bank_34xx;
-		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
-		printk(KERN_INFO "OMAP34xx GPIO hardware version %d.%d\n",
-			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP4
 	if (cpu_is_omap44xx()) {
-		int rev;
-
 		gpio_bank_count = OMAP34XX_NR_GPIOS;
 		gpio_bank = gpio_bank_44xx;
-		rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
-		printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n",
-			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
 #endif
 	for (i = 0; i < gpio_bank_count; i++) {
@@ -1757,6 +1783,14 @@ static int __init _omap_gpio_init(void)
 
 		bank = &gpio_bank[i];
 		spin_lock_init(&bank->lock);
+
+		/* Static mapping, never released */
+		bank->base = ioremap(bank->pbase, bank_size);
+		if (!bank->base) {
+			printk(KERN_ERR "Could not ioremap gpio bank%i\n", i);
+			continue;
+		}
+
 		if (bank_is_mpuio(bank))
 			__raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
 		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
@@ -1768,11 +1802,11 @@ static int __init _omap_gpio_init(void)
 			__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
 			__raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
 		}
-		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_730) {
-			__raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
-			__raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
+		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
+			__raw_writel(0xffffffff, bank->base + OMAP7XX_GPIO_INT_MASK);
+			__raw_writel(0x00000000, bank->base + OMAP7XX_GPIO_INT_STATUS);
 
-			gpio_count = 32; /* 730 has 32-bit GPIOs */
+			gpio_count = 32; /* 7xx has 32-bit GPIOs */
 		}
 
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
@@ -1804,6 +1838,8 @@ static int __init _omap_gpio_init(void)
 			gpio_count = 32;
 		}
 #endif
+
+		bank->mod_usage = 0;
 		/* REVISIT eventually switch from OMAP-specific gpio structs
 		 * over to the generic ones
 		 */
@@ -1862,6 +1898,8 @@ static int __init _omap_gpio_init(void)
 	if (cpu_is_omap34xx())
 		omap_writel(1 << 0, 0x48306814);
 
+	omap_gpio_show_rev();
+
 	return 0;
 }
 
@@ -2106,6 +2144,81 @@ void omap2_gpio_resume_after_retention(v
 
 #endif
 
+#ifdef CONFIG_ARCH_OMAP34XX
+/* save the registers of bank 2-6 */
+void omap_gpio_save_context(void)
+{
+	int i;
+
+	/* saving banks from 2-6 only since GPIO1 is in WKUP */
+	for (i = 1; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		gpio_context[i].sysconfig =
+			__raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);
+		gpio_context[i].irqenable1 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
+		gpio_context[i].irqenable2 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
+		gpio_context[i].wake_en =
+			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
+		gpio_context[i].ctrl =
+			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+		gpio_context[i].oe =
+			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
+		gpio_context[i].leveldetect0 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+		gpio_context[i].leveldetect1 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+		gpio_context[i].risingdetect =
+			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		gpio_context[i].fallingdetect =
+			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		gpio_context[i].dataout =
+			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
+		gpio_context[i].setwkuena =
+			__raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA);
+		gpio_context[i].setdataout =
+			__raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT);
+	}
+}
+
+/* restore the required registers of bank 2-6 */
+void omap_gpio_restore_context(void)
+{
+	int i;
+
+	for (i = 1; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		__raw_writel(gpio_context[i].sysconfig,
+				bank->base + OMAP24XX_GPIO_SYSCONFIG);
+		__raw_writel(gpio_context[i].irqenable1,
+				bank->base + OMAP24XX_GPIO_IRQENABLE1);
+		__raw_writel(gpio_context[i].irqenable2,
+				bank->base + OMAP24XX_GPIO_IRQENABLE2);
+		__raw_writel(gpio_context[i].wake_en,
+				bank->base + OMAP24XX_GPIO_WAKE_EN);
+		__raw_writel(gpio_context[i].ctrl,
+				bank->base + OMAP24XX_GPIO_CTRL);
+		__raw_writel(gpio_context[i].oe,
+				bank->base + OMAP24XX_GPIO_OE);
+		__raw_writel(gpio_context[i].leveldetect0,
+				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+		__raw_writel(gpio_context[i].leveldetect1,
+				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+		__raw_writel(gpio_context[i].risingdetect,
+				bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		__raw_writel(gpio_context[i].fallingdetect,
+				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		__raw_writel(gpio_context[i].dataout,
+				bank->base + OMAP24XX_GPIO_DATAOUT);
+		__raw_writel(gpio_context[i].setwkuena,
+				bank->base + OMAP24XX_GPIO_SETWKUENA);
+		__raw_writel(gpio_context[i].setdataout,
+				bank->base + OMAP24XX_GPIO_SETDATAOUT);
+	}
+}
+#endif
+
 /*
  * This may get called early from board specific init
  * for boards that have interrupts routed via FPGA.
@@ -2160,8 +2273,7 @@ static int dbg_gpio_show(struct seq_file
 
 		if (bank_is_mpuio(bank))
 			gpio = OMAP_MPUIO(0);
-		else if (cpu_class_is_omap2() || cpu_is_omap730() ||
-				cpu_is_omap850())
+		else if (cpu_class_is_omap2() || cpu_is_omap7xx())
 			bankwidth = 32;
 
 		for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/i2c.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/i2c.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <mach/irqs.h>
-#include <mach/mux.h>
+#include <plat/mux.h>
 
 #define OMAP_I2C_SIZE		0x3f
 #define OMAP1_I2C_BASE		0xfffb3800
@@ -80,47 +80,8 @@ static struct platform_device omap_i2c_d
 #endif
 };
 
-#if defined(CONFIG_ARCH_OMAP24XX)
-static const int omap24xx_pins[][2] = {
-	{ M19_24XX_I2C1_SCL, L15_24XX_I2C1_SDA },
-	{ J15_24XX_I2C2_SCL, H19_24XX_I2C2_SDA },
-};
-#else
-static const int omap24xx_pins[][2] = {};
-#endif
-#if defined(CONFIG_ARCH_OMAP34XX)
-static const int omap34xx_pins[][2] = {
-	{ K21_34XX_I2C1_SCL, J21_34XX_I2C1_SDA},
-	{ AF15_34XX_I2C2_SCL, AE15_34XX_I2C2_SDA},
-	{ AF14_34XX_I2C3_SCL, AG14_34XX_I2C3_SDA},
-};
-#else
-static const int omap34xx_pins[][2] = {};
-#endif
-
 #define OMAP_I2C_CMDLINE_SETUP	(BIT(31))
 
-static void __init omap_i2c_mux_pins(int bus)
-{
-	int scl, sda;
-
-	if (cpu_class_is_omap1()) {
-		scl = I2C_SCL;
-		sda = I2C_SDA;
-	} else if (cpu_is_omap24xx()) {
-		scl = omap24xx_pins[bus][0];
-		sda = omap24xx_pins[bus][1];
-	} else if (cpu_is_omap34xx()) {
-		scl = omap34xx_pins[bus][0];
-		sda = omap34xx_pins[bus][1];
-	} else {
-		return;
-	}
-
-	omap_cfg_reg(sda);
-	omap_cfg_reg(scl);
-}
-
 static int __init omap_i2c_nr_ports(void)
 {
 	int ports = 0;
@@ -156,7 +117,6 @@ static int __init omap_i2c_add_bus(int b
 		res[1].start = irq;
 	}
 
-	omap_i2c_mux_pins(bus_id - 1);
 	return platform_device_register(pdev);
 }
 
@@ -209,7 +169,7 @@ out:
 subsys_initcall(omap_register_i2c_bus_cmdline);
 
 /**
- * omap_register_i2c_bus - register I2C bus with device descriptors
+ * omap_plat_register_i2c_bus - register I2C bus with device descriptors
  * @bus_id: bus id counting from number 1
  * @clkrate: clock rate of the bus in kHz
  * @info: pointer into I2C device descriptor table or NULL
@@ -217,7 +177,7 @@ subsys_initcall(omap_register_i2c_bus_cm
  *
  * Returns 0 on success or an error code.
  */
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+int __init omap_plat_register_i2c_bus(int bus_id, u32 clkrate,
 			  struct i2c_board_info const *info,
 			  unsigned len)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/blizzard.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/blizzard.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/blizzard.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/blizzard.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _BLIZZARD_H
-#define _BLIZZARD_H
-
-struct blizzard_platform_data {
-	void		(*power_up)(struct device *dev);
-	void		(*power_down)(struct device *dev);
-	unsigned long	(*get_clock_rate)(struct device *dev);
-
-	unsigned	te_connected : 1;
-};
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-ams-delta.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-ams-delta.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-ams-delta.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-ams-delta.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-ams-delta.h
- *
- * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
- *
- * 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.
- */
-#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
-#define __ASM_ARCH_OMAP_AMS_DELTA_H
-
-#if defined (CONFIG_MACH_AMS_DELTA)
-
-#define AMS_DELTA_LATCH1_PHYS		0x01000000
-#define AMS_DELTA_LATCH1_VIRT		0xEA000000
-#define AMS_DELTA_MODEM_PHYS		0x04000000
-#define AMS_DELTA_MODEM_VIRT		0xEB000000
-#define AMS_DELTA_LATCH2_PHYS		0x08000000
-#define AMS_DELTA_LATCH2_VIRT		0xEC000000
-
-#define AMS_DELTA_LATCH1_LED_CAMERA	0x01
-#define AMS_DELTA_LATCH1_LED_ADVERT	0x02
-#define AMS_DELTA_LATCH1_LED_EMAIL	0x04
-#define AMS_DELTA_LATCH1_LED_HANDSFREE	0x08
-#define AMS_DELTA_LATCH1_LED_VOICEMAIL	0x10
-#define AMS_DELTA_LATCH1_LED_VOICE	0x20
-
-#define AMS_DELTA_LATCH2_LCD_VBLEN	0x0001
-#define AMS_DELTA_LATCH2_LCD_NDISP	0x0002
-#define AMS_DELTA_LATCH2_NAND_NCE	0x0004
-#define AMS_DELTA_LATCH2_NAND_NRE	0x0008
-#define AMS_DELTA_LATCH2_NAND_NWP	0x0010
-#define AMS_DELTA_LATCH2_NAND_NWE	0x0020
-#define AMS_DELTA_LATCH2_NAND_ALE	0x0040
-#define AMS_DELTA_LATCH2_NAND_CLE	0x0080
-#define AMD_DELTA_LATCH2_KEYBRD_PWR	0x0100
-#define AMD_DELTA_LATCH2_KEYBRD_DATA	0x0200
-#define AMD_DELTA_LATCH2_SCARD_RSTIN	0x0400
-#define AMD_DELTA_LATCH2_SCARD_CMDVCC	0x0800
-#define AMS_DELTA_LATCH2_MODEM_NRESET	0x1000
-#define AMS_DELTA_LATCH2_MODEM_CODEC	0x2000
-
-#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA	0
-#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK	1
-#define AMS_DELTA_GPIO_PIN_MODEM_IRQ	2
-#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH	4
-#define AMS_DELTA_GPIO_PIN_SCARD_NOFF	6
-#define AMS_DELTA_GPIO_PIN_SCARD_IO	7
-#define AMS_DELTA_GPIO_PIN_CONFIG	11
-#define AMS_DELTA_GPIO_PIN_NAND_RB	12
-
-#ifndef __ASSEMBLY__
-void ams_delta_latch1_write(u8 mask, u8 value);
-void ams_delta_latch2_write(u16 mask, u16 value);
-#endif
-
-#endif /* CONFIG_MACH_AMS_DELTA */
-
-#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,160 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/board.h
- *
- *  Information structures for board-specific data
- *
- *  Copyright (C) 2004	Nokia Corporation
- *  Written by Juha Yrjölä <juha.yrjola@nokia.com>
- */
-
-#ifndef _OMAP_BOARD_H
-#define _OMAP_BOARD_H
-
-#include <linux/types.h>
-
-#include <mach/gpio-switch.h>
-
-/* Different peripheral ids */
-#define OMAP_TAG_CLOCK		0x4f01
-#define OMAP_TAG_LCD		0x4f05
-#define OMAP_TAG_GPIO_SWITCH	0x4f06
-#define OMAP_TAG_FBMEM		0x4f08
-#define OMAP_TAG_STI_CONSOLE	0x4f09
-#define OMAP_TAG_CAMERA_SENSOR	0x4f0a
-
-#define OMAP_TAG_BOOT_REASON    0x4f80
-#define OMAP_TAG_FLASH_PART	0x4f81
-#define OMAP_TAG_VERSION_STR	0x4f82
-
-struct omap_clock_config {
-	/* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
-	u8 system_clock_type;
-};
-
-struct omap_serial_console_config {
-	u8 console_uart;
-	u32 console_speed;
-};
-
-struct omap_sti_console_config {
-	unsigned enable:1;
-	u8 channel;
-};
-
-struct omap_camera_sensor_config {
-	u16 reset_gpio;
-	int (*power_on)(void * data);
-	int (*power_off)(void * data);
-};
-
-struct omap_usb_config {
-	/* Configure drivers according to the connectors on your board:
-	 *  - "A" connector (rectagular)
-	 *	... for host/OHCI use, set "register_host".
-	 *  - "B" connector (squarish) or "Mini-B"
-	 *	... for device/gadget use, set "register_dev".
-	 *  - "Mini-AB" connector (very similar to Mini-B)
-	 *	... for OTG use as device OR host, initialize "otg"
-	 */
-	unsigned	register_host:1;
-	unsigned	register_dev:1;
-	u8		otg;	/* port number, 1-based:  usb1 == 2 */
-
-	u8		hmc_mode;
-
-	/* implicitly true if otg:  host supports remote wakeup? */
-	u8		rwc;
-
-	/* signaling pins used to talk to transceiver on usbN:
-	 *  0 == usbN unused
-	 *  2 == usb0-only, using internal transceiver
-	 *  3 == 3 wire bidirectional
-	 *  4 == 4 wire bidirectional
-	 *  6 == 6 wire unidirectional (or TLL)
-	 */
-	u8		pins[3];
-};
-
-struct omap_lcd_config {
-	char panel_name[16];
-	char ctrl_name[16];
-	s16  nreset_gpio;
-	u8   data_lines;
-};
-
-struct device;
-struct fb_info;
-struct omap_backlight_config {
-	int default_intensity;
-	int (*set_power)(struct device *dev, int state);
-	int (*check_fb)(struct fb_info *fb);
-};
-
-struct omap_fbmem_config {
-	u32 start;
-	u32 size;
-};
-
-struct omap_pwm_led_platform_data {
-	const char *name;
-	int intensity_timer;
-	int blink_timer;
-	void (*set_power)(struct omap_pwm_led_platform_data *self, int on_off);
-};
-
-/* See arch/arm/plat-omap/include/mach/gpio-switch.h for definitions */
-struct omap_gpio_switch_config {
-	char name[12];
-	u16 gpio;
-	int flags:4;
-	int type:4;
-	int key_code:24; /* Linux key code */
-};
-
-struct omap_uart_config {
-	/* Bit field of UARTs present; bit 0 --> UART1 */
-	unsigned int enabled_uarts;
-};
-
-
-struct omap_flash_part_config {
-	char part_table[0];
-};
-
-struct omap_boot_reason_config {
-	char reason_str[12];
-};
-
-struct omap_version_config {
-	char component[12];
-	char version[12];
-};
-
-struct omap_board_config_entry {
-	u16 tag;
-	u16 len;
-	u8  data[0];
-};
-
-struct omap_board_config_kernel {
-	u16 tag;
-	const void *data;
-};
-
-extern const void *__omap_get_config(u16 tag, size_t len, int nr);
-
-#define omap_get_config(tag, type) \
-	((const type *) __omap_get_config((tag), sizeof(type), 0))
-#define omap_get_nr_config(tag, type, nr) \
-	((const type *) __omap_get_config((tag), sizeof(type), (nr)))
-
-extern const void *omap_get_var_config(u16 tag, size_t *len);
-
-extern struct omap_board_config_kernel *omap_board_config;
-extern int omap_board_config_size;
-
-
-/* for TI reference platforms sharing the same debug card */
-extern int debug_card_init(u32 addr, unsigned gpio);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-sx1.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-sx1.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-sx1.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-sx1.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * Siemens SX1 board definitions
- *
- * Copyright: Vovan888 at gmail com
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
-#define __ASM_ARCH_SX1_I2C_CHIPS_H
-
-#define SOFIA_MAX_LIGHT_VAL	0x2B
-
-#define SOFIA_I2C_ADDR		0x32
-/* Sofia reg 3 bits masks */
-#define SOFIA_POWER1_REG	0x03
-
-#define	SOFIA_USB_POWER		0x01
-#define	SOFIA_MMC_POWER		0x04
-#define	SOFIA_BLUETOOTH_POWER	0x08
-#define	SOFIA_MMILIGHT_POWER	0x20
-
-#define SOFIA_POWER2_REG	0x04
-#define SOFIA_BACKLIGHT_REG	0x06
-#define SOFIA_KEYLIGHT_REG	0x07
-#define SOFIA_DIMMING_REG	0x09
-
-
-/* Function Prototypes for SX1 devices control on I2C bus */
-
-int sx1_setbacklight(u8 backlight);
-int sx1_getbacklight(u8 *backlight);
-int sx1_setkeylight(u8 keylight);
-int sx1_getkeylight(u8 *keylight);
-
-int sx1_setmmipower(u8 onoff);
-int sx1_setusbpower(u8 onoff);
-int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
-int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
-
-/* MMC prototypes */
-
-extern void sx1_mmc_init(void);
-extern void sx1_mmc_slot_cover_handler(void *arg, int state);
-
-#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Hardware definitions for OMAP5910 based VoiceBlue board.
- *
- * This 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_VOICEBLUE_H
-#define __ASM_ARCH_VOICEBLUE_H
-
-extern void voiceblue_wdt_enable(void);
-extern void voiceblue_wdt_disable(void);
-extern void voiceblue_wdt_ping(void);
-
-#endif /*  __ASM_ARCH_VOICEBLUE_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clkdev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef __MACH_CLKDEV_H
-#define __MACH_CLKDEV_H
-
-static inline int __clk_get(struct clk *clk)
-{
-	return 1;
-}
-
-static inline void __clk_put(struct clk *clk)
-{
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,111 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
- * OMAP2/3 clockdomain framework functions
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- * Copyright (C) 2008 Nokia Corporation
- *
- * Written by Paul Walmsley
- *
- * This 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_ARM_ARCH_OMAP_CLOCKDOMAIN_H
-#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
-
-#include <mach/powerdomain.h>
-#include <mach/clock.h>
-#include <mach/cpu.h>
-
-/* Clockdomain capability flags */
-#define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
-#define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
-#define CLKDM_CAN_ENABLE_AUTO			(1 << 2)
-#define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
-
-#define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
-#define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
-#define CLKDM_CAN_HWSUP_SWSUP	(CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
-
-/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
-#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO		0x0
-#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO		0x1
-
-/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
-#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO		0x0
-#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP		0x1
-#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP		0x2
-#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO		0x3
-
-/*
- * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
- * and sleepdeps added when a powerdomain should stay active in hwsup mode;
- * and conversely, removed when the powerdomain should be allowed to go
- * inactive in hwsup mode.
- */
-struct clkdm_pwrdm_autodep {
-
-	union {
-		/* Name of the powerdomain to add a wkdep/sleepdep on */
-		const char *name;
-
-		/* Powerdomain pointer (looked up at clkdm_init() time) */
-		struct powerdomain *ptr;
-	} pwrdm;
-
-	/* OMAP chip types that this clockdomain dep is valid on */
-	const struct omap_chip_id omap_chip;
-
-};
-
-struct clockdomain {
-
-	/* Clockdomain name */
-	const char *name;
-
-	union {
-		/* Powerdomain enclosing this clockdomain */
-		const char *name;
-
-		/* Powerdomain pointer assigned at clkdm_register() */
-		struct powerdomain *ptr;
-	} pwrdm;
-
-	/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
-	const u16 clktrctrl_mask;
-
-	/* Clockdomain capability flags */
-	const u8 flags;
-
-	/* OMAP chip types that this clockdomain is valid on */
-	const struct omap_chip_id omap_chip;
-
-	/* Usecount tracking */
-	atomic_t usecount;
-
-	struct list_head node;
-
-};
-
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
-int clkdm_register(struct clockdomain *clkdm);
-int clkdm_unregister(struct clockdomain *clkdm);
-struct clockdomain *clkdm_lookup(const char *name);
-
-int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
-			void *user);
-struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
-
-void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
-void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
-
-int omap2_clkdm_wakeup(struct clockdomain *clkdm);
-int omap2_clkdm_sleep(struct clockdomain *clkdm);
-
-int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
-int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clock.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,163 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/clock.h
- *
- *  Copyright (C) 2004 - 2005 Nokia corporation
- *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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 __ARCH_ARM_OMAP_CLOCK_H
-#define __ARCH_ARM_OMAP_CLOCK_H
-
-struct module;
-struct clk;
-struct clockdomain;
-
-struct clkops {
-	int			(*enable)(struct clk *);
-	void			(*disable)(struct clk *);
-	void			(*find_idlest)(struct clk *, void __iomem **, u8 *);
-	void			(*find_companion)(struct clk *, void __iomem **, u8 *);
-};
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
-
-struct clksel_rate {
-	u32			val;
-	u8			div;
-	u8			flags;
-};
-
-struct clksel {
-	struct clk		 *parent;
-	const struct clksel_rate *rates;
-};
-
-struct dpll_data {
-	void __iomem		*mult_div1_reg;
-	u32			mult_mask;
-	u32			div1_mask;
-	struct clk		*clk_bypass;
-	struct clk		*clk_ref;
-	void __iomem		*control_reg;
-	u32			enable_mask;
-	unsigned int		rate_tolerance;
-	unsigned long		last_rounded_rate;
-	u16			last_rounded_m;
-	u8			last_rounded_n;
-	u8			min_divider;
-	u8			max_divider;
-	u32			max_tolerance;
-	u16			max_multiplier;
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-	u8			modes;
-	void __iomem		*autoidle_reg;
-	void __iomem		*idlest_reg;
-	u32			autoidle_mask;
-	u32			freqsel_mask;
-	u32			idlest_mask;
-	u8			auto_recal_bit;
-	u8			recal_en_bit;
-	u8			recal_st_bit;
-#  endif
-};
-
-#endif
-
-struct clk {
-	struct list_head	node;
-	const struct clkops	*ops;
-	const char		*name;
-	int			id;
-	struct clk		*parent;
-	struct list_head	children;
-	struct list_head	sibling;	/* node for children */
-	unsigned long		rate;
-	__u32			flags;
-	void __iomem		*enable_reg;
-	unsigned long		(*recalc)(struct clk *);
-	int			(*set_rate)(struct clk *, unsigned long);
-	long			(*round_rate)(struct clk *, unsigned long);
-	void			(*init)(struct clk *);
-	__u8			enable_bit;
-	__s8			usecount;
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
-	u8			fixed_div;
-	void __iomem		*clksel_reg;
-	u32			clksel_mask;
-	const struct clksel	*clksel;
-	struct dpll_data	*dpll_data;
-	const char		*clkdm_name;
-	struct clockdomain	*clkdm;
-#else
-	__u8			rate_offset;
-	__u8			src_offset;
-#endif
-#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
-	struct dentry		*dent;	/* For visible tree hierarchy */
-#endif
-};
-
-struct cpufreq_frequency_table;
-
-struct clk_functions {
-	int		(*clk_enable)(struct clk *clk);
-	void		(*clk_disable)(struct clk *clk);
-	long		(*clk_round_rate)(struct clk *clk, unsigned long rate);
-	int		(*clk_set_rate)(struct clk *clk, unsigned long rate);
-	int		(*clk_set_parent)(struct clk *clk, struct clk *parent);
-	void		(*clk_allow_idle)(struct clk *clk);
-	void		(*clk_deny_idle)(struct clk *clk);
-	void		(*clk_disable_unused)(struct clk *clk);
-#ifdef CONFIG_CPU_FREQ
-	void		(*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
-#endif
-};
-
-extern unsigned int mpurate;
-
-extern int clk_init(struct clk_functions *custom_clocks);
-extern void clk_preinit(struct clk *clk);
-extern int clk_register(struct clk *clk);
-extern void clk_reparent(struct clk *child, struct clk *parent);
-extern void clk_unregister(struct clk *clk);
-extern void propagate_rate(struct clk *clk);
-extern void recalculate_root_clocks(void);
-extern unsigned long followparent_recalc(struct clk *clk);
-extern void clk_enable_init_clocks(void);
-#ifdef CONFIG_CPU_FREQ
-extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
-#endif
-
-extern const struct clkops clkops_null;
-
-/* Clock flags */
-/* bit 0 is free */
-#define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
-/* bits 2-4 are free */
-#define ENABLE_REG_32BIT	(1 << 5)	/* Use 32-bit access */
-#define CLOCK_IDLE_CONTROL	(1 << 7)
-#define CLOCK_NO_IDLE_PARENT	(1 << 8)
-#define DELAYED_APP		(1 << 9)	/* Delay application of clock */
-#define CONFIG_PARTICIPANT	(1 << 10)	/* Fundamental clock */
-#define ENABLE_ON_INIT		(1 << 11)	/* Enable upon framework init */
-#define INVERT_ENABLE           (1 << 12)       /* 0 enables, 1 disables */
-/* bits 13-31 are currently free */
-
-/* Clksel_rate flags */
-#define DEFAULT_RATE		(1 << 0)
-#define RATE_IN_242X		(1 << 1)
-#define RATE_IN_243X		(1 << 2)
-#define RATE_IN_343X		(1 << 3)	/* rates common to all 343X */
-#define RATE_IN_3430ES2		(1 << 4)	/* 3430ES2 rates only */
-
-#define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
-
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/common.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/common.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/common.h
- *
- * Header for code common to all OMAP machines.
- *
- * 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.
- */
-
-#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
-#define __ARCH_ARM_MACH_OMAP_COMMON_H
-
-#include <linux/i2c.h>
-
-struct sys_timer;
-
-extern void omap_map_common_io(void);
-extern struct sys_timer omap_timer;
-#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
-extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
-				 struct i2c_board_info const *info,
-				 unsigned len);
-#else
-static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
-				 struct i2c_board_info const *info,
-				 unsigned len)
-{
-	return 0;
-}
-#endif
-
-/* IO bases for various OMAP processors */
-struct omap_globals {
-	u32		class;		/* OMAP class to detect */
-	void __iomem	*tap;		/* Control module ID code */
-	void __iomem	*sdrc;		/* SDRAM Controller */
-	void __iomem	*sms;		/* SDRAM Memory Scheduler */
-	void __iomem	*ctrl;		/* System Control Module */
-	void __iomem	*prm;		/* Power and Reset Management */
-	void __iomem	*cm;		/* Clock Management */
-};
-
-void omap2_set_globals_242x(void);
-void omap2_set_globals_243x(void);
-void omap2_set_globals_343x(void);
-void omap2_set_globals_443x(void);
-
-/* These get called from omap2_set_globals_xxxx(), do not call these */
-void omap2_set_globals_tap(struct omap_globals *);
-void omap2_set_globals_sdrc(struct omap_globals *);
-void omap2_set_globals_control(struct omap_globals *);
-void omap2_set_globals_prcm(struct omap_globals *);
-
-#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/control.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/control.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/control.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/control.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,227 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/control.h
- *
- * OMAP2/3/4 System Control Module definitions
- *
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
- *
- * Written by Paul Walmsley
- *
- * 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.
- */
-
-#ifndef __ASM_ARCH_CONTROL_H
-#define __ASM_ARCH_CONTROL_H
-
-#include <mach/io.h>
-
-#ifndef __ASSEMBLY__
-#define OMAP242X_CTRL_REGADDR(reg)					\
-	OMAP2_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
-#define OMAP243X_CTRL_REGADDR(reg)					\
-	OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
-#define OMAP343X_CTRL_REGADDR(reg)					\
-	OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
-#else
-#define OMAP242X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
-#define OMAP243X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
-#define OMAP343X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
-#endif /* __ASSEMBLY__ */
-
-/*
- * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
- * OMAP24XX and OMAP34XX.
- */
-
-/* Control submodule offsets */
-
-#define OMAP2_CONTROL_INTERFACE		0x000
-#define OMAP2_CONTROL_PADCONFS		0x030
-#define OMAP2_CONTROL_GENERAL		0x270
-#define OMAP343X_CONTROL_MEM_WKUP	0x600
-#define OMAP343X_CONTROL_PADCONFS_WKUP	0xa00
-#define OMAP343X_CONTROL_GENERAL_WKUP	0xa60
-
-/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
-
-#define OMAP2_CONTROL_SYSCONFIG		(OMAP2_CONTROL_INTERFACE + 0x10)
-
-/* CONTROL_GENERAL register offsets common to OMAP2 & 3 */
-#define OMAP2_CONTROL_DEVCONF0		(OMAP2_CONTROL_GENERAL + 0x0004)
-#define OMAP2_CONTROL_MSUSPENDMUX_0	(OMAP2_CONTROL_GENERAL + 0x0020)
-#define OMAP2_CONTROL_MSUSPENDMUX_1	(OMAP2_CONTROL_GENERAL + 0x0024)
-#define OMAP2_CONTROL_MSUSPENDMUX_2	(OMAP2_CONTROL_GENERAL + 0x0028)
-#define OMAP2_CONTROL_MSUSPENDMUX_3	(OMAP2_CONTROL_GENERAL + 0x002c)
-#define OMAP2_CONTROL_MSUSPENDMUX_4	(OMAP2_CONTROL_GENERAL + 0x0030)
-#define OMAP2_CONTROL_MSUSPENDMUX_5	(OMAP2_CONTROL_GENERAL + 0x0034)
-#define OMAP2_CONTROL_SEC_CTRL		(OMAP2_CONTROL_GENERAL + 0x0040)
-#define OMAP2_CONTROL_RPUB_KEY_H_0	(OMAP2_CONTROL_GENERAL + 0x0090)
-#define OMAP2_CONTROL_RPUB_KEY_H_1	(OMAP2_CONTROL_GENERAL + 0x0094)
-#define OMAP2_CONTROL_RPUB_KEY_H_2	(OMAP2_CONTROL_GENERAL + 0x0098)
-#define OMAP2_CONTROL_RPUB_KEY_H_3	(OMAP2_CONTROL_GENERAL + 0x009c)
-
-/* 242x-only CONTROL_GENERAL register offsets */
-#define OMAP242X_CONTROL_DEVCONF	OMAP2_CONTROL_DEVCONF0 /* match TRM */
-#define OMAP242X_CONTROL_OCM_RAM_PERM	(OMAP2_CONTROL_GENERAL + 0x0068)
-
-/* 243x-only CONTROL_GENERAL register offsets */
-/* CONTROL_IVA2_BOOT{ADDR,MOD} are at the same place on 343x - noted below */
-#define OMAP243X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0078)
-#define OMAP243X_CONTROL_CSIRXFE	(OMAP2_CONTROL_GENERAL + 0x007c)
-#define OMAP243X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
-#define OMAP243X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
-#define OMAP243X_CONTROL_IVA2_GEMCFG	(OMAP2_CONTROL_GENERAL + 0x0198)
-#define OMAP243X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x0230)
-
-/* 24xx-only CONTROL_GENERAL register offsets */
-#define OMAP24XX_CONTROL_DEBOBS		(OMAP2_CONTROL_GENERAL + 0x0000)
-#define OMAP24XX_CONTROL_EMU_SUPPORT	(OMAP2_CONTROL_GENERAL + 0x0008)
-#define OMAP24XX_CONTROL_SEC_TEST	(OMAP2_CONTROL_GENERAL + 0x0044)
-#define OMAP24XX_CONTROL_PSA_CTRL	(OMAP2_CONTROL_GENERAL + 0x0048)
-#define OMAP24XX_CONTROL_PSA_CMD	(OMAP2_CONTROL_GENERAL + 0x004c)
-#define OMAP24XX_CONTROL_PSA_VALUE	(OMAP2_CONTROL_GENERAL + 0x0050)
-#define OMAP24XX_CONTROL_SEC_EMU	(OMAP2_CONTROL_GENERAL + 0x0060)
-#define OMAP24XX_CONTROL_SEC_TAP	(OMAP2_CONTROL_GENERAL + 0x0064)
-#define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD	(OMAP2_CONTROL_GENERAL + 0x006c)
-#define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD	(OMAP2_CONTROL_GENERAL + 0x0070)
-#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD	(OMAP2_CONTROL_GENERAL + 0x0074)
-#define OMAP24XX_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0080)
-#define OMAP24XX_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0084)
-#define OMAP24XX_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0088)
-#define OMAP24XX_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x008c)
-#define OMAP24XX_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a0)
-#define OMAP24XX_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00a4)
-#define OMAP24XX_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00a8)
-#define OMAP24XX_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00ac)
-#define OMAP24XX_CONTROL_CUST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00b0)
-#define OMAP24XX_CONTROL_CUST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00b4)
-#define OMAP24XX_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c0)
-#define OMAP24XX_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00c4)
-#define OMAP24XX_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00c8)
-#define OMAP24XX_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00cc)
-#define OMAP24XX_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d0)
-#define OMAP24XX_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00d4)
-#define OMAP24XX_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00d8)
-#define OMAP24XX_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00dc)
-#define OMAP24XX_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e0)
-#define OMAP24XX_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00e4)
-
-/* 34xx-only CONTROL_GENERAL register offsets */
-#define OMAP343X_CONTROL_PADCONF_OFF	(OMAP2_CONTROL_GENERAL + 0x0000)
-#define OMAP343X_CONTROL_MEM_DFTRW0	(OMAP2_CONTROL_GENERAL + 0x0008)
-#define OMAP343X_CONTROL_MEM_DFTRW1	(OMAP2_CONTROL_GENERAL + 0x000c)
-#define OMAP343X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0068)
-#define OMAP343X_CONTROL_CSIRXFE		(OMAP2_CONTROL_GENERAL + 0x006c)
-#define OMAP343X_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0070)
-#define OMAP343X_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0074)
-#define OMAP343X_CONTROL_SEC_ERR_STATUS_DEBUG	(OMAP2_CONTROL_GENERAL + 0x0078)
-#define OMAP343X_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0080)
-#define OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x0084)
-#define OMAP343X_CONTROL_RPUB_KEY_H_4	(OMAP2_CONTROL_GENERAL + 0x00a0)
-#define OMAP343X_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a8)
-#define OMAP343X_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00ac)
-#define OMAP343X_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00b0)
-#define OMAP343X_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00b4)
-#define OMAP343X_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c8)
-#define OMAP343X_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00cc)
-#define OMAP343X_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00d0)
-#define OMAP343X_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00d4)
-#define OMAP343X_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d8)
-#define OMAP343X_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00dc)
-#define OMAP343X_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00e0)
-#define OMAP343X_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00e4)
-#define OMAP343X_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e8)
-#define OMAP343X_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00ec)
-#define OMAP343X_CONTROL_TEST_KEY_10	(OMAP2_CONTROL_GENERAL + 0x00f0)
-#define OMAP343X_CONTROL_TEST_KEY_11	(OMAP2_CONTROL_GENERAL + 0x00f4)
-#define OMAP343X_CONTROL_TEST_KEY_12	(OMAP2_CONTROL_GENERAL + 0x00f8)
-#define OMAP343X_CONTROL_TEST_KEY_13	(OMAP2_CONTROL_GENERAL + 0x00fc)
-#define OMAP343X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
-#define OMAP343X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
-#define OMAP343X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x02b0)
-#define OMAP343X_CONTROL_TEMP_SENSOR	(OMAP2_CONTROL_GENERAL + 0x02b4)
-
-/* 34xx D2D idle-related pins, handled by PM core */
-#define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
-#define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
-
-/*
- * REVISIT: This list of registers is not comprehensive - there are more
- * that should be added.
- */
-
-/*
- * Control module register bit defines - these should eventually go into
- * their own regbits file.  Some of these will be complicated, depending
- * on the device type (general-purpose, emulator, test, secure, bad, other)
- * and the security mode (secure, non-secure, don't care)
- */
-/* CONTROL_DEVCONF0 bits */
-#define OMAP2_MMCSDIO1ADPCLKISEL	(1 << 24) /* MMC1 loop back clock */
-#define OMAP24XX_USBSTANDBYCTRL		(1 << 15)
-#define OMAP2_MCBSP2_CLKS_MASK		(1 << 6)
-#define OMAP2_MCBSP1_CLKS_MASK		(1 << 2)
-
-/* CONTROL_DEVCONF1 bits */
-#define OMAP243X_MMC1_ACTIVE_OVERWRITE	(1 << 31)
-#define OMAP2_MMCSDIO2ADPCLKISEL	(1 << 6) /* MMC2 loop back clock */
-#define OMAP2_MCBSP5_CLKS_MASK		(1 << 4) /* > 242x */
-#define OMAP2_MCBSP4_CLKS_MASK		(1 << 2) /* > 242x */
-#define OMAP2_MCBSP3_CLKS_MASK		(1 << 0) /* > 242x */
-
-/* CONTROL_STATUS bits */
-#define OMAP2_DEVICETYPE_MASK		(0x7 << 8)
-#define OMAP2_SYSBOOT_5_MASK		(1 << 5)
-#define OMAP2_SYSBOOT_4_MASK		(1 << 4)
-#define OMAP2_SYSBOOT_3_MASK		(1 << 3)
-#define OMAP2_SYSBOOT_2_MASK		(1 << 2)
-#define OMAP2_SYSBOOT_1_MASK		(1 << 1)
-#define OMAP2_SYSBOOT_0_MASK		(1 << 0)
-
-/* CONTROL_PBIAS_LITE bits */
-#define OMAP343X_PBIASLITESUPPLY_HIGH1	(1 << 15)
-#define OMAP343X_PBIASLITEVMODEERROR1	(1 << 11)
-#define OMAP343X_PBIASSPEEDCTRL1	(1 << 10)
-#define OMAP343X_PBIASLITEPWRDNZ1	(1 << 9)
-#define OMAP343X_PBIASLITEVMODE1	(1 << 8)
-#define OMAP343X_PBIASLITESUPPLY_HIGH0	(1 << 7)
-#define OMAP343X_PBIASLITEVMODEERROR0	(1 << 3)
-#define OMAP2_PBIASSPEEDCTRL0		(1 << 2)
-#define OMAP2_PBIASLITEPWRDNZ0		(1 << 1)
-#define OMAP2_PBIASLITEVMODE0		(1 << 0)
-
-/* CONTROL_IVA2_BOOTMOD bits */
-#define OMAP3_IVA2_BOOTMOD_SHIFT	0
-#define OMAP3_IVA2_BOOTMOD_MASK		(0xf << 0)
-#define OMAP3_IVA2_BOOTMOD_IDLE		(0x1 << 0)
-
-/* CONTROL_PADCONF_X bits */
-#define OMAP3_PADCONF_WAKEUPEVENT0	(1 << 15)
-#define OMAP3_PADCONF_WAKEUPENABLE0	(1 << 14)
-
-#ifndef __ASSEMBLY__
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-		defined(CONFIG_ARCH_OMAP4)
-extern void __iomem *omap_ctrl_base_get(void);
-extern u8 omap_ctrl_readb(u16 offset);
-extern u16 omap_ctrl_readw(u16 offset);
-extern u32 omap_ctrl_readl(u16 offset);
-extern void omap_ctrl_writeb(u8 val, u16 offset);
-extern void omap_ctrl_writew(u16 val, u16 offset);
-extern void omap_ctrl_writel(u32 val, u16 offset);
-#else
-#define omap_ctrl_base_get()		0
-#define omap_ctrl_readb(x)		0
-#define omap_ctrl_readw(x)		0
-#define omap_ctrl_readl(x)		0
-#define omap_ctrl_writeb(x, y)		WARN_ON(1)
-#define omap_ctrl_writew(x, y)		WARN_ON(1)
-#define omap_ctrl_writel(x, y)		WARN_ON(1)
-#endif
-#endif	/* __ASSEMBLY__ */
-
-#endif /* __ASM_ARCH_CONTROL_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/cpu.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/cpu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/cpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/cpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,426 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/cpu.h
- *
- * OMAP cpu type detection
- *
- * Copyright (C) 2004, 2008 Nokia Corporation
- *
- * Copyright (C) 2009 Texas Instruments.
- *
- * Written by Tony Lindgren <tony.lindgren@nokia.com>
- *
- * Added OMAP4 specific defines - 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 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_OMAP_CPU_H
-#define __ASM_ARCH_OMAP_CPU_H
-
-/*
- * Omap device type i.e. EMU/HS/TST/GP/BAD
- */
-#define OMAP2_DEVICE_TYPE_TEST		0
-#define OMAP2_DEVICE_TYPE_EMU		1
-#define OMAP2_DEVICE_TYPE_SEC		2
-#define OMAP2_DEVICE_TYPE_GP		3
-#define OMAP2_DEVICE_TYPE_BAD		4
-
-int omap_type(void);
-
-struct omap_chip_id {
-	u8 oc;
-	u8 type;
-};
-
-#define OMAP_CHIP_INIT(x)	{ .oc = x }
-
-/*
- * omap_rev bits:
- * CPU id bits	(0730, 1510, 1710, 2422...)	[31:16]
- * CPU revision	(See _REV_ defined in cpu.h)	[15:08]
- * CPU class bits (15xx, 16xx, 24xx, 34xx...)	[07:00]
- */
-unsigned int omap_rev(void);
-
-/*
- * Test if multicore OMAP support is needed
- */
-#undef MULTI_OMAP1
-#undef MULTI_OMAP2
-#undef OMAP_NAME
-
-#ifdef CONFIG_ARCH_OMAP730
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap730
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP850
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap850
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap1510
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP1
-#  define MULTI_OMAP1
-# else
-#  define OMAP_NAME omap16xx
-# endif
-#endif
-#if (defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX))
-# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
-#  error "OMAP1 and OMAP2 can't be selected at the same time"
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP2420
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap2420
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP2430
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap2430
-# endif
-#endif
-#ifdef CONFIG_ARCH_OMAP3430
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP2
-#  define MULTI_OMAP2
-# else
-#  define OMAP_NAME omap3430
-# endif
-#endif
-
-/*
- * Macros to group OMAP into cpu classes.
- * These can be used in most places.
- * cpu_is_omap7xx():	True for OMAP730, OMAP850
- * cpu_is_omap15xx():	True for OMAP1510, OMAP5910 and OMAP310
- * cpu_is_omap16xx():	True for OMAP1610, OMAP5912 and OMAP1710
- * cpu_is_omap24xx():	True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
- * cpu_is_omap242x():	True for OMAP2420, OMAP2422, OMAP2423
- * cpu_is_omap243x():	True for OMAP2430
- * cpu_is_omap343x():	True for OMAP3430
- */
-#define GET_OMAP_CLASS	(omap_rev() & 0xff)
-
-#define IS_OMAP_CLASS(class, id)			\
-static inline int is_omap ##class (void)		\
-{							\
-	return (GET_OMAP_CLASS == (id)) ? 1 : 0;	\
-}
-
-#define GET_OMAP_SUBCLASS	((omap_rev() >> 20) & 0x0fff)
-
-#define IS_OMAP_SUBCLASS(subclass, id)			\
-static inline int is_omap ##subclass (void)		\
-{							\
-	return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;	\
-}
-
-IS_OMAP_CLASS(7xx, 0x07)
-IS_OMAP_CLASS(15xx, 0x15)
-IS_OMAP_CLASS(16xx, 0x16)
-IS_OMAP_CLASS(24xx, 0x24)
-IS_OMAP_CLASS(34xx, 0x34)
-
-IS_OMAP_SUBCLASS(242x, 0x242)
-IS_OMAP_SUBCLASS(243x, 0x243)
-IS_OMAP_SUBCLASS(343x, 0x343)
-
-#define cpu_is_omap7xx()		0
-#define cpu_is_omap15xx()		0
-#define cpu_is_omap16xx()		0
-#define cpu_is_omap24xx()		0
-#define cpu_is_omap242x()		0
-#define cpu_is_omap243x()		0
-#define cpu_is_omap34xx()		0
-#define cpu_is_omap343x()		0
-#define cpu_is_omap44xx()		0
-#define cpu_is_omap443x()		0
-
-#if defined(MULTI_OMAP1)
-# if defined(CONFIG_ARCH_OMAP730)
-#  undef  cpu_is_omap7xx
-#  define cpu_is_omap7xx()		is_omap7xx()
-# endif
-# if defined(CONFIG_ARCH_OMAP850)
-#  undef  cpu_is_omap7xx
-#  define cpu_is_omap7xx()		is_omap7xx()
-# endif
-# if defined(CONFIG_ARCH_OMAP15XX)
-#  undef  cpu_is_omap15xx
-#  define cpu_is_omap15xx()		is_omap15xx()
-# endif
-# if defined(CONFIG_ARCH_OMAP16XX)
-#  undef  cpu_is_omap16xx
-#  define cpu_is_omap16xx()		is_omap16xx()
-# endif
-#else
-# if defined(CONFIG_ARCH_OMAP730)
-#  undef  cpu_is_omap7xx
-#  define cpu_is_omap7xx()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP850)
-#  undef  cpu_is_omap7xx
-#  define cpu_is_omap7xx()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP15XX)
-#  undef  cpu_is_omap15xx
-#  define cpu_is_omap15xx()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP16XX)
-#  undef  cpu_is_omap16xx
-#  define cpu_is_omap16xx()		1
-# endif
-#endif
-
-#if defined(MULTI_OMAP2)
-# if defined(CONFIG_ARCH_OMAP24XX)
-#  undef  cpu_is_omap24xx
-#  undef  cpu_is_omap242x
-#  undef  cpu_is_omap243x
-#  define cpu_is_omap24xx()		is_omap24xx()
-#  define cpu_is_omap242x()		is_omap242x()
-#  define cpu_is_omap243x()		is_omap243x()
-# endif
-# if defined(CONFIG_ARCH_OMAP34XX)
-#  undef  cpu_is_omap34xx
-#  undef  cpu_is_omap343x
-#  define cpu_is_omap34xx()		is_omap34xx()
-#  define cpu_is_omap343x()		is_omap343x()
-# endif
-#else
-# if defined(CONFIG_ARCH_OMAP24XX)
-#  undef  cpu_is_omap24xx
-#  define cpu_is_omap24xx()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP2420)
-#  undef  cpu_is_omap242x
-#  define cpu_is_omap242x()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP2430)
-#  undef  cpu_is_omap243x
-#  define cpu_is_omap243x()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP34XX)
-#  undef  cpu_is_omap34xx
-#  define cpu_is_omap34xx()		1
-# endif
-# if defined(CONFIG_ARCH_OMAP3430)
-#  undef  cpu_is_omap343x
-#  define cpu_is_omap343x()		1
-# endif
-#endif
-
-/*
- * Macros to detect individual cpu types.
- * These are only rarely needed.
- * cpu_is_omap330():	True for OMAP330
- * cpu_is_omap730():	True for OMAP730
- * cpu_is_omap850():	True for OMAP850
- * cpu_is_omap1510():	True for OMAP1510
- * cpu_is_omap1610():	True for OMAP1610
- * cpu_is_omap1611():	True for OMAP1611
- * cpu_is_omap5912():	True for OMAP5912
- * cpu_is_omap1621():	True for OMAP1621
- * cpu_is_omap1710():	True for OMAP1710
- * cpu_is_omap2420():	True for OMAP2420
- * cpu_is_omap2422():	True for OMAP2422
- * cpu_is_omap2423():	True for OMAP2423
- * cpu_is_omap2430():	True for OMAP2430
- * cpu_is_omap3430():	True for OMAP3430
- */
-#define GET_OMAP_TYPE	((omap_rev() >> 16) & 0xffff)
-
-#define IS_OMAP_TYPE(type, id)				\
-static inline int is_omap ##type (void)			\
-{							\
-	return (GET_OMAP_TYPE == (id)) ? 1 : 0;		\
-}
-
-IS_OMAP_TYPE(310, 0x0310)
-IS_OMAP_TYPE(730, 0x0730)
-IS_OMAP_TYPE(850, 0x0850)
-IS_OMAP_TYPE(1510, 0x1510)
-IS_OMAP_TYPE(1610, 0x1610)
-IS_OMAP_TYPE(1611, 0x1611)
-IS_OMAP_TYPE(5912, 0x1611)
-IS_OMAP_TYPE(1621, 0x1621)
-IS_OMAP_TYPE(1710, 0x1710)
-IS_OMAP_TYPE(2420, 0x2420)
-IS_OMAP_TYPE(2422, 0x2422)
-IS_OMAP_TYPE(2423, 0x2423)
-IS_OMAP_TYPE(2430, 0x2430)
-IS_OMAP_TYPE(3430, 0x3430)
-
-#define cpu_is_omap310()		0
-#define cpu_is_omap730()		0
-#define cpu_is_omap850()		0
-#define cpu_is_omap1510()		0
-#define cpu_is_omap1610()		0
-#define cpu_is_omap5912()		0
-#define cpu_is_omap1611()		0
-#define cpu_is_omap1621()		0
-#define cpu_is_omap1710()		0
-#define cpu_is_omap2420()		0
-#define cpu_is_omap2422()		0
-#define cpu_is_omap2423()		0
-#define cpu_is_omap2430()		0
-#define cpu_is_omap3430()		0
-
-/*
- * Whether we have MULTI_OMAP1 or not, we still need to distinguish
- * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
- */
-
-#if defined(CONFIG_ARCH_OMAP730)
-# undef  cpu_is_omap730
-# define cpu_is_omap730()		is_omap730()
-#endif
-
-#if defined(CONFIG_ARCH_OMAP850)
-# undef  cpu_is_omap850
-# define cpu_is_omap850()		is_omap850()
-#endif
-
-#if defined(CONFIG_ARCH_OMAP15XX)
-# undef  cpu_is_omap310
-# undef  cpu_is_omap1510
-# define cpu_is_omap310()		is_omap310()
-# define cpu_is_omap1510()		is_omap1510()
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-# undef  cpu_is_omap1610
-# undef  cpu_is_omap1611
-# undef  cpu_is_omap5912
-# undef  cpu_is_omap1621
-# undef  cpu_is_omap1710
-# define cpu_is_omap1610()		is_omap1610()
-# define cpu_is_omap1611()		is_omap1611()
-# define cpu_is_omap5912()		is_omap5912()
-# define cpu_is_omap1621()		is_omap1621()
-# define cpu_is_omap1710()		is_omap1710()
-#endif
-
-#if defined(CONFIG_ARCH_OMAP24XX)
-# undef  cpu_is_omap2420
-# undef  cpu_is_omap2422
-# undef  cpu_is_omap2423
-# undef  cpu_is_omap2430
-# define cpu_is_omap2420()		is_omap2420()
-# define cpu_is_omap2422()		is_omap2422()
-# define cpu_is_omap2423()		is_omap2423()
-# define cpu_is_omap2430()		is_omap2430()
-#endif
-
-#if defined(CONFIG_ARCH_OMAP34XX)
-# undef cpu_is_omap3430
-# define cpu_is_omap3430()		is_omap3430()
-#endif
-
-# if defined(CONFIG_ARCH_OMAP4)
-# undef cpu_is_omap44xx
-# undef cpu_is_omap443x
-# define cpu_is_omap44xx()		1
-# define cpu_is_omap443x()		1
-# endif
-
-/* Macros to detect if we have OMAP1 or OMAP2 */
-#define cpu_class_is_omap1()	(cpu_is_omap7xx() || cpu_is_omap15xx() || \
-				cpu_is_omap16xx())
-#define cpu_class_is_omap2()	(cpu_is_omap24xx() || cpu_is_omap34xx() || \
-				cpu_is_omap44xx())
-
-/* Various silicon revisions for omap2 */
-#define OMAP242X_CLASS		0x24200024
-#define OMAP2420_REV_ES1_0	0x24200024
-#define OMAP2420_REV_ES2_0	0x24201024
-
-#define OMAP243X_CLASS		0x24300024
-#define OMAP2430_REV_ES1_0	0x24300024
-
-#define OMAP343X_CLASS		0x34300034
-#define OMAP3430_REV_ES1_0	0x34300034
-#define OMAP3430_REV_ES2_0	0x34301034
-#define OMAP3430_REV_ES2_1	0x34302034
-#define OMAP3430_REV_ES3_0	0x34303034
-#define OMAP3430_REV_ES3_1	0x34304034
-
-#define OMAP443X_CLASS		0x44300034
-
-/*
- * omap_chip bits
- *
- * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
- * valid on all chips of that type.  CHIP_IS_OMAP3430ES{1,2} indicates
- * something that is only valid on that particular ES revision.
- *
- * These bits may be ORed together to indicate structures that are
- * available on multiple chip types.
- *
- * To test whether a particular structure matches the current OMAP chip type,
- * use omap_chip_is().
- *
- */
-#define CHIP_IS_OMAP2420		(1 << 0)
-#define CHIP_IS_OMAP2430		(1 << 1)
-#define CHIP_IS_OMAP3430		(1 << 2)
-#define CHIP_IS_OMAP3430ES1		(1 << 3)
-#define CHIP_IS_OMAP3430ES2		(1 << 4)
-#define CHIP_IS_OMAP3430ES3_0		(1 << 5)
-#define CHIP_IS_OMAP3430ES3_1		(1 << 6)
-
-#define CHIP_IS_OMAP24XX		(CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
-
-/*
- * "GE" here represents "greater than or equal to" in terms of ES
- * levels.  So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
- * chips at ES2 and beyond, but not, for example, any OMAP lines after
- * OMAP3.
- */
-#define CHIP_GE_OMAP3430ES2		(CHIP_IS_OMAP3430ES2 | \
-					 CHIP_IS_OMAP3430ES3_0 | \
-					 CHIP_IS_OMAP3430ES3_1)
-#define CHIP_GE_OMAP3430ES3_1		(CHIP_IS_OMAP3430ES3_1)
-
-
-int omap_chip_is(struct omap_chip_id oci);
-void omap2_check_revision(void);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/debug-macro.S linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/debug-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/debug-macro.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* arch/arm/plat-omap/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This 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.
- *
-*/
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-#ifdef CONFIG_ARCH_OMAP1
-		moveq	\rx, #0xff000000	@ physical base address
-		movne	\rx, #0xfe000000	@ virtual base
-		orr	\rx, \rx, #0x00fb0000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		orr	\rx, \rx, #0x00009000	@ UART 3
-#endif
-#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
-		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
-#endif
-
-#elif  CONFIG_ARCH_OMAP2
-		moveq	\rx, #0x48000000	@ physical base address
-		movne	\rx, #0xd8000000	@ virtual base
-		orr	\rx, \rx, #0x0006a000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART2
-		add	\rx, \rx, #0x00002000	@ UART 2
-#endif
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		add	\rx, \rx, #0x00004000	@ UART 3
-#endif
-
-#elif defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
-		moveq	\rx, #0x48000000	@ physical base address
-		movne	\rx, #0xd8000000	@ virtual base
-		orr	\rx, \rx, #0x0006a000
-#ifdef CONFIG_OMAP_LL_DEBUG_UART2
-		add	\rx, \rx, #0x00002000	@ UART 2
-#endif
-#ifdef CONFIG_OMAP_LL_DEBUG_UART3
-		add	\rx, \rx, #0x00fb0000	@ UART 3
-		add	\rx, \rx, #0x00006000
-#endif
-#endif
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx]
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldrb	\rd, [\rx, #(0x5 << 2)]	@ OMAP-1510 and friends
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		beq	1002f
-		ldrb	\rd, [\rx, #(0x5 << 0)]	@ OMAP-730 only
-		and	\rd, \rd, #0x60
-		teq	\rd, #0x60
-		bne	1001b
-1002:
-		.endm
-
-		.macro	waituart,rd,rx
-		.endm
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dma.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,675 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/dma.h
- *
- *  Copyright (C) 2003 Nokia Corporation
- *  Author: Juha Yrjölä <juha.yrjola@nokia.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
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-/* Hardware registers for omap1 */
-#define OMAP1_DMA_BASE			(0xfffed800)
-
-#define OMAP1_DMA_GCR			0x400
-#define OMAP1_DMA_GSCR			0x404
-#define OMAP1_DMA_GRST			0x408
-#define OMAP1_DMA_HW_ID			0x442
-#define OMAP1_DMA_PCH2_ID		0x444
-#define OMAP1_DMA_PCH0_ID		0x446
-#define OMAP1_DMA_PCH1_ID		0x448
-#define OMAP1_DMA_PCHG_ID		0x44a
-#define OMAP1_DMA_PCHD_ID		0x44c
-#define OMAP1_DMA_CAPS_0_U		0x44e
-#define OMAP1_DMA_CAPS_0_L		0x450
-#define OMAP1_DMA_CAPS_1_U		0x452
-#define OMAP1_DMA_CAPS_1_L		0x454
-#define OMAP1_DMA_CAPS_2		0x456
-#define OMAP1_DMA_CAPS_3		0x458
-#define OMAP1_DMA_CAPS_4		0x45a
-#define OMAP1_DMA_PCH2_SR		0x460
-#define OMAP1_DMA_PCH0_SR		0x480
-#define OMAP1_DMA_PCH1_SR		0x482
-#define OMAP1_DMA_PCHD_SR		0x4c0
-
-/* Hardware registers for omap2 and omap3 */
-#define OMAP24XX_DMA4_BASE		(L4_24XX_BASE + 0x56000)
-#define OMAP34XX_DMA4_BASE		(L4_34XX_BASE + 0x56000)
-#define OMAP44XX_DMA4_BASE		(L4_44XX_BASE + 0x56000)
-
-#define OMAP_DMA4_REVISION		0x00
-#define OMAP_DMA4_GCR			0x78
-#define OMAP_DMA4_IRQSTATUS_L0		0x08
-#define OMAP_DMA4_IRQSTATUS_L1		0x0c
-#define OMAP_DMA4_IRQSTATUS_L2		0x10
-#define OMAP_DMA4_IRQSTATUS_L3		0x14
-#define OMAP_DMA4_IRQENABLE_L0		0x18
-#define OMAP_DMA4_IRQENABLE_L1		0x1c
-#define OMAP_DMA4_IRQENABLE_L2		0x20
-#define OMAP_DMA4_IRQENABLE_L3		0x24
-#define OMAP_DMA4_SYSSTATUS		0x28
-#define OMAP_DMA4_OCP_SYSCONFIG		0x2c
-#define OMAP_DMA4_CAPS_0		0x64
-#define OMAP_DMA4_CAPS_2		0x6c
-#define OMAP_DMA4_CAPS_3		0x70
-#define OMAP_DMA4_CAPS_4		0x74
-
-#define OMAP1_LOGICAL_DMA_CH_COUNT	17
-#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
-
-/* Common channel specific registers for omap1 */
-#define OMAP1_DMA_CH_BASE(n)		(0x40 * (n) + 0x00)
-#define OMAP1_DMA_CSDP(n)		(0x40 * (n) + 0x00)
-#define OMAP1_DMA_CCR(n)		(0x40 * (n) + 0x02)
-#define OMAP1_DMA_CICR(n)		(0x40 * (n) + 0x04)
-#define OMAP1_DMA_CSR(n)		(0x40 * (n) + 0x06)
-#define OMAP1_DMA_CEN(n)		(0x40 * (n) + 0x10)
-#define OMAP1_DMA_CFN(n)		(0x40 * (n) + 0x12)
-#define OMAP1_DMA_CSFI(n)		(0x40 * (n) + 0x14)
-#define OMAP1_DMA_CSEI(n)		(0x40 * (n) + 0x16)
-#define OMAP1_DMA_CPC(n)		(0x40 * (n) + 0x18)	/* 15xx only */
-#define OMAP1_DMA_CSAC(n)		(0x40 * (n) + 0x18)
-#define OMAP1_DMA_CDAC(n)		(0x40 * (n) + 0x1a)
-#define OMAP1_DMA_CDEI(n)		(0x40 * (n) + 0x1c)
-#define OMAP1_DMA_CDFI(n)		(0x40 * (n) + 0x1e)
-#define OMAP1_DMA_CLNK_CTRL(n)		(0x40 * (n) + 0x28)
-
-/* Common channel specific registers for omap2 */
-#define OMAP_DMA4_CH_BASE(n)		(0x60 * (n) + 0x80)
-#define OMAP_DMA4_CCR(n)		(0x60 * (n) + 0x80)
-#define OMAP_DMA4_CLNK_CTRL(n)		(0x60 * (n) + 0x84)
-#define OMAP_DMA4_CICR(n)		(0x60 * (n) + 0x88)
-#define OMAP_DMA4_CSR(n)		(0x60 * (n) + 0x8c)
-#define OMAP_DMA4_CSDP(n)		(0x60 * (n) + 0x90)
-#define OMAP_DMA4_CEN(n)		(0x60 * (n) + 0x94)
-#define OMAP_DMA4_CFN(n)		(0x60 * (n) + 0x98)
-#define OMAP_DMA4_CSEI(n)		(0x60 * (n) + 0xa4)
-#define OMAP_DMA4_CSFI(n)		(0x60 * (n) + 0xa8)
-#define OMAP_DMA4_CDEI(n)		(0x60 * (n) + 0xac)
-#define OMAP_DMA4_CDFI(n)		(0x60 * (n) + 0xb0)
-#define OMAP_DMA4_CSAC(n)		(0x60 * (n) + 0xb4)
-#define OMAP_DMA4_CDAC(n)		(0x60 * (n) + 0xb8)
-
-/* Channel specific registers only on omap1 */
-#define OMAP1_DMA_CSSA_L(n)		(0x40 * (n) + 0x08)
-#define OMAP1_DMA_CSSA_U(n)		(0x40 * (n) + 0x0a)
-#define OMAP1_DMA_CDSA_L(n)		(0x40 * (n) + 0x0c)
-#define OMAP1_DMA_CDSA_U(n)		(0x40 * (n) + 0x0e)
-#define OMAP1_DMA_COLOR_L(n)		(0x40 * (n) + 0x20)
-#define OMAP1_DMA_COLOR_U(n)		(0x40 * (n) + 0x22)
-#define OMAP1_DMA_CCR2(n)		(0x40 * (n) + 0x24)
-#define OMAP1_DMA_LCH_CTRL(n)		(0x40 * (n) + 0x2a)	/* not on 15xx */
-#define OMAP1_DMA_CCEN(n)		0
-#define OMAP1_DMA_CCFN(n)		0
-
-/* Channel specific registers only on omap2 */
-#define OMAP_DMA4_CSSA(n)		(0x60 * (n) + 0x9c)
-#define OMAP_DMA4_CDSA(n)		(0x60 * (n) + 0xa0)
-#define OMAP_DMA4_CCEN(n)		(0x60 * (n) + 0xbc)
-#define OMAP_DMA4_CCFN(n)		(0x60 * (n) + 0xc0)
-#define OMAP_DMA4_COLOR(n)		(0x60 * (n) + 0xc4)
-
-/* Additional registers available on OMAP4 */
-#define OMAP_DMA4_CDP(n)		(0x60 * (n) + 0xd0)
-#define OMAP_DMA4_CNDP(n)		(0x60 * (n) + 0xd4)
-#define OMAP_DMA4_CCDN(n)		(0x60 * (n) + 0xd8)
-
-/* Dummy defines to keep multi-omap compiles happy */
-#define OMAP1_DMA_REVISION		0
-#define OMAP1_DMA_IRQSTATUS_L0		0
-#define OMAP1_DMA_IRQENABLE_L0		0
-#define OMAP1_DMA_OCP_SYSCONFIG		0
-#define OMAP_DMA4_HW_ID			0
-#define OMAP_DMA4_CAPS_0_L		0
-#define OMAP_DMA4_CAPS_0_U		0
-#define OMAP_DMA4_CAPS_1_L		0
-#define OMAP_DMA4_CAPS_1_U		0
-#define OMAP_DMA4_GSCR			0
-#define OMAP_DMA4_CPC(n)		0
-
-#define OMAP_DMA4_LCH_CTRL(n)		0
-#define OMAP_DMA4_COLOR_L(n)		0
-#define OMAP_DMA4_COLOR_U(n)		0
-#define OMAP_DMA4_CCR2(n)		0
-#define OMAP1_DMA_CSSA(n)		0
-#define OMAP1_DMA_CDSA(n)		0
-#define OMAP_DMA4_CSSA_L(n)		0
-#define OMAP_DMA4_CSSA_U(n)		0
-#define OMAP_DMA4_CDSA_L(n)		0
-#define OMAP_DMA4_CDSA_U(n)		0
-#define OMAP1_DMA_COLOR(n)		0
-
-/*----------------------------------------------------------------------------*/
-
-/* DMA channels for omap1 */
-#define OMAP_DMA_NO_DEVICE		0
-#define OMAP_DMA_MCSI1_TX		1
-#define OMAP_DMA_MCSI1_RX		2
-#define OMAP_DMA_I2C_RX			3
-#define OMAP_DMA_I2C_TX			4
-#define OMAP_DMA_EXT_NDMA_REQ		5
-#define OMAP_DMA_EXT_NDMA_REQ2		6
-#define OMAP_DMA_UWIRE_TX		7
-#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_UART1_TX		12
-#define OMAP_DMA_UART1_RX		13
-#define OMAP_DMA_UART2_TX		14
-#define OMAP_DMA_UART2_RX		15
-#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_NAND			23
-#define OMAP_DMA_IRQ_LCD_LINE		24
-#define OMAP_DMA_MEMORY_STICK		25
-#define OMAP_DMA_USB_W2FC_RX0		26
-#define OMAP_DMA_USB_W2FC_RX1		27
-#define OMAP_DMA_USB_W2FC_RX2		28
-#define OMAP_DMA_USB_W2FC_TX0		29
-#define OMAP_DMA_USB_W2FC_TX1		30
-#define OMAP_DMA_USB_W2FC_TX2		31
-
-/* These are only for 1610 */
-#define OMAP_DMA_CRYPTO_DES_IN		32
-#define OMAP_DMA_SPI_TX			33
-#define OMAP_DMA_SPI_RX			34
-#define OMAP_DMA_CRYPTO_HASH		35
-#define OMAP_DMA_CCP_ATTN		36
-#define OMAP_DMA_CCP_FIFO_NOT_EMPTY	37
-#define OMAP_DMA_CMT_APE_TX_CHAN_0	38
-#define OMAP_DMA_CMT_APE_RV_CHAN_0	39
-#define OMAP_DMA_CMT_APE_TX_CHAN_1	40
-#define OMAP_DMA_CMT_APE_RV_CHAN_1	41
-#define OMAP_DMA_CMT_APE_TX_CHAN_2	42
-#define OMAP_DMA_CMT_APE_RV_CHAN_2	43
-#define OMAP_DMA_CMT_APE_TX_CHAN_3	44
-#define OMAP_DMA_CMT_APE_RV_CHAN_3	45
-#define OMAP_DMA_CMT_APE_TX_CHAN_4	46
-#define OMAP_DMA_CMT_APE_RV_CHAN_4	47
-#define OMAP_DMA_CMT_APE_TX_CHAN_5	48
-#define OMAP_DMA_CMT_APE_RV_CHAN_5	49
-#define OMAP_DMA_CMT_APE_TX_CHAN_6	50
-#define OMAP_DMA_CMT_APE_RV_CHAN_6	51
-#define OMAP_DMA_CMT_APE_TX_CHAN_7	52
-#define OMAP_DMA_CMT_APE_RV_CHAN_7	53
-#define OMAP_DMA_MMC2_TX		54
-#define OMAP_DMA_MMC2_RX		55
-#define OMAP_DMA_CRYPTO_DES_OUT		56
-
-/* DMA channels for 24xx */
-#define OMAP24XX_DMA_NO_DEVICE		0
-#define OMAP24XX_DMA_XTI_DMA		1	/* S_DMA_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_GFX		5	/* S_DMA_4 */
-#define OMAP24XX_DMA_DSS		6	/* S_DMA_5 */
-#define OMAP242X_DMA_VLYNQ_TX		7	/* S_DMA_6 */
-#define OMAP24XX_DMA_EXT_DMAREQ2	7	/* S_DMA_6 */
-#define OMAP24XX_DMA_CWT		8	/* S_DMA_7 */
-#define OMAP24XX_DMA_AES_TX		9	/* S_DMA_8 */
-#define OMAP24XX_DMA_AES_RX		10	/* S_DMA_9 */
-#define OMAP24XX_DMA_DES_TX		11	/* S_DMA_10 */
-#define OMAP24XX_DMA_DES_RX		12	/* S_DMA_11 */
-#define OMAP24XX_DMA_SHA1MD5_RX		13	/* S_DMA_12 */
-#define OMAP34XX_DMA_SHA2MD5_RX		13	/* S_DMA_12 */
-#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 OMAP242X_DMA_EAC_AC_RD		17	/* S_DMA_16 */
-#define OMAP242X_DMA_EAC_AC_WR		18	/* S_DMA_17 */
-#define OMAP242X_DMA_EAC_MD_UL_RD	19	/* S_DMA_18 */
-#define OMAP242X_DMA_EAC_MD_UL_WR	20	/* S_DMA_19 */
-#define OMAP242X_DMA_EAC_MD_DL_RD	21	/* S_DMA_20 */
-#define OMAP242X_DMA_EAC_MD_DL_WR	22	/* S_DMA_21 */
-#define OMAP242X_DMA_EAC_BT_UL_RD	23	/* S_DMA_22 */
-#define OMAP242X_DMA_EAC_BT_UL_WR	24	/* S_DMA_23 */
-#define OMAP242X_DMA_EAC_BT_DL_RD	25	/* S_DMA_24 */
-#define OMAP242X_DMA_EAC_BT_DL_WR	26	/* S_DMA_25 */
-#define OMAP243X_DMA_EXT_DMAREQ3	14	/* S_DMA_13 */
-#define OMAP24XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
-#define OMAP24XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
-#define OMAP24XX_DMA_MCBSP3_TX		17	/* S_DMA_16 */
-#define OMAP24XX_DMA_MCBSP3_RX		18	/* S_DMA_17 */
-#define OMAP24XX_DMA_MCBSP4_TX		19	/* S_DMA_18 */
-#define OMAP24XX_DMA_MCBSP4_RX		20	/* S_DMA_19 */
-#define OMAP24XX_DMA_MCBSP5_TX		21	/* S_DMA_20 */
-#define OMAP24XX_DMA_MCBSP5_RX		22	/* S_DMA_21 */
-#define OMAP24XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
-#define OMAP24XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
-#define OMAP243X_DMA_EXT_DMAREQ4	25	/* S_DMA_24 */
-#define OMAP243X_DMA_EXT_DMAREQ5	26	/* S_DMA_25 */
-#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_MCBSP1_TX		31	/* S_DMA_30 */
-#define OMAP24XX_DMA_MCBSP1_RX		32	/* S_DMA_31 */
-#define OMAP24XX_DMA_MCBSP2_TX		33	/* S_DMA_32 */
-#define OMAP24XX_DMA_MCBSP2_RX		34	/* S_DMA_33 */
-#define OMAP24XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
-#define OMAP24XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
-#define OMAP24XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
-#define OMAP24XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
-#define OMAP24XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
-#define OMAP24XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
-#define OMAP24XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
-#define OMAP24XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
-#define OMAP24XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
-#define OMAP24XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
-#define OMAP24XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
-#define OMAP24XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
-#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_USB_W2FC_TX0	55	/* S_DMA_54 */
-#define OMAP24XX_DMA_USB_W2FC_RX0	56	/* S_DMA_55 */
-#define OMAP24XX_DMA_USB_W2FC_TX1	57	/* S_DMA_56 */
-#define OMAP24XX_DMA_USB_W2FC_RX1	58	/* S_DMA_57 */
-#define OMAP24XX_DMA_USB_W2FC_TX2	59	/* S_DMA_58 */
-#define OMAP24XX_DMA_USB_W2FC_RX2	60	/* S_DMA_59 */
-#define OMAP24XX_DMA_MMC1_TX		61	/* S_DMA_60 */
-#define OMAP24XX_DMA_MMC1_RX		62	/* S_DMA_61 */
-#define OMAP24XX_DMA_MS			63	/* S_DMA_62 */
-#define OMAP242X_DMA_EXT_DMAREQ5	64	/* S_DMA_63 */
-#define OMAP243X_DMA_EXT_DMAREQ6	64	/* S_DMA_63 */
-#define OMAP34XX_DMA_EXT_DMAREQ3	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_DES2_TX		67	/* S_DMA_66 */
-#define OMAP34XX_DMA_DES2_RX		68	/* S_DMA_67 */
-#define OMAP34XX_DMA_SHA1MD5_RX		69	/* S_DMA_68 */
-#define OMAP34XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
-#define OMAP34XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
-#define OMAP34XX_DSS_DMA0		72	/* S_DMA_71 */
-#define OMAP34XX_DSS_DMA1		73	/* S_DMA_72 */
-#define OMAP34XX_DSS_DMA2		74	/* S_DMA_73 */
-#define OMAP34XX_DSS_DMA3		75	/* S_DMA_74 */
-#define OMAP34XX_DMA_MMC3_TX		77	/* S_DMA_76 */
-#define OMAP34XX_DMA_MMC3_RX		78	/* S_DMA_77 */
-#define OMAP34XX_DMA_USIM_TX		79	/* S_DMA_78 */
-#define OMAP34XX_DMA_USIM_RX		80	/* S_DMA_79 */
-
-/* DMA request lines for 44xx */
-#define OMAP44XX_DMA_DSS_DISPC_REQ	6	/* S_DMA_5 */
-#define OMAP44XX_DMA_SYS_REQ2		7	/* S_DMA_6 */
-#define OMAP44XX_DMA_ISS_REQ1		9	/* S_DMA_8 */
-#define OMAP44XX_DMA_ISS_REQ2		10	/* S_DMA_9 */
-#define OMAP44XX_DMA_ISS_REQ3		12	/* S_DMA_11 */
-#define OMAP44XX_DMA_ISS_REQ4		13	/* S_DMA_12 */
-#define OMAP44XX_DMA_DSS_RFBI_REQ	14	/* S_DMA_13 */
-#define OMAP44XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
-#define OMAP44XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
-#define OMAP44XX_DMA_MCBSP2_TX		17	/* S_DMA_16 */
-#define OMAP44XX_DMA_MCBSP2_RX		18	/* S_DMA_17 */
-#define OMAP44XX_DMA_MCBSP3_TX		19	/* S_DMA_18 */
-#define OMAP44XX_DMA_MCBSP3_RX		20	/* S_DMA_19 */
-#define OMAP44XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
-#define OMAP44XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
-#define OMAP44XX_DMA_I2C3_TX		25	/* S_DMA_24 */
-#define OMAP44XX_DMA_I2C3_RX		26	/* S_DMA_25 */
-#define OMAP44XX_DMA_I2C1_TX		27	/* S_DMA_26 */
-#define OMAP44XX_DMA_I2C1_RX		28	/* S_DMA_27 */
-#define OMAP44XX_DMA_I2C2_TX		29	/* S_DMA_28 */
-#define OMAP44XX_DMA_I2C2_RX		30	/* S_DMA_29 */
-#define OMAP44XX_DMA_MCBSP4_TX		31	/* S_DMA_30 */
-#define OMAP44XX_DMA_MCBSP4_RX		32	/* S_DMA_31 */
-#define OMAP44XX_DMA_MCBSP1_TX		33	/* S_DMA_32 */
-#define OMAP44XX_DMA_MCBSP1_RX		34	/* S_DMA_33 */
-#define OMAP44XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
-#define OMAP44XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
-#define OMAP44XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
-#define OMAP44XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
-#define OMAP44XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
-#define OMAP44XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
-#define OMAP44XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
-#define OMAP44XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
-#define OMAP44XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
-#define OMAP44XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
-#define OMAP44XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
-#define OMAP44XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
-#define OMAP44XX_DMA_MMC2_TX		47	/* S_DMA_46 */
-#define OMAP44XX_DMA_MMC2_RX		48	/* S_DMA_47 */
-#define OMAP44XX_DMA_UART1_TX		49	/* S_DMA_48 */
-#define OMAP44XX_DMA_UART1_RX		50	/* S_DMA_49 */
-#define OMAP44XX_DMA_UART2_TX		51	/* S_DMA_50 */
-#define OMAP44XX_DMA_UART2_RX		52	/* S_DMA_51 */
-#define OMAP44XX_DMA_UART3_TX		53	/* S_DMA_52 */
-#define OMAP44XX_DMA_UART3_RX		54	/* S_DMA_53 */
-#define OMAP44XX_DMA_UART4_TX		55	/* S_DMA_54 */
-#define OMAP44XX_DMA_UART4_RX		56	/* S_DMA_55 */
-#define OMAP44XX_DMA_MMC4_TX		57	/* S_DMA_56 */
-#define OMAP44XX_DMA_MMC4_RX		58	/* S_DMA_57 */
-#define OMAP44XX_DMA_MMC5_TX		59	/* S_DMA_58 */
-#define OMAP44XX_DMA_MMC5_RX		60	/* S_DMA_59 */
-#define OMAP44XX_DMA_MMC1_TX		61	/* S_DMA_60 */
-#define OMAP44XX_DMA_MMC1_RX		62	/* S_DMA_61 */
-#define OMAP44XX_DMA_SYS_REQ3		64	/* S_DMA_63 */
-#define OMAP44XX_DMA_MCPDM_UP		65	/* S_DMA_64 */
-#define OMAP44XX_DMA_MCPDM_DL		66	/* S_DMA_65 */
-#define OMAP44XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
-#define OMAP44XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ0	72	/* S_DMA_71 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ1	73	/* S_DMA_72 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ2	74	/* S_DMA_73 */
-#define OMAP44XX_DMA_DSS_DSI1_REQ3	75	/* S_DMA_74 */
-#define OMAP44XX_DMA_DSS_HDMI_REQ	76	/* S_DMA_75 */
-#define OMAP44XX_DMA_MMC3_TX		77	/* S_DMA_76 */
-#define OMAP44XX_DMA_MMC3_RX		78	/* S_DMA_77 */
-#define OMAP44XX_DMA_USIM_TX		79	/* S_DMA_78 */
-#define OMAP44XX_DMA_USIM_RX		80	/* S_DMA_79 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ0	81	/* S_DMA_80 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ1	82	/* S_DMA_81 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ2	83	/* S_DMA_82 */
-#define OMAP44XX_DMA_DSS_DSI2_REQ3	84	/* S_DMA_83 */
-#define OMAP44XX_DMA_ABE_REQ0		101	/* S_DMA_100 */
-#define OMAP44XX_DMA_ABE_REQ1		102	/* S_DMA_101 */
-#define OMAP44XX_DMA_ABE_REQ2		103	/* S_DMA_102 */
-#define OMAP44XX_DMA_ABE_REQ3		104	/* S_DMA_103 */
-#define OMAP44XX_DMA_ABE_REQ4		105	/* S_DMA_104 */
-#define OMAP44XX_DMA_ABE_REQ5		106	/* S_DMA_105 */
-#define OMAP44XX_DMA_ABE_REQ6		107	/* S_DMA_106 */
-#define OMAP44XX_DMA_ABE_REQ7		108	/* S_DMA_107 */
-#define OMAP44XX_DMA_I2C4_TX		124	/* S_DMA_123 */
-#define OMAP44XX_DMA_I2C4_RX		125	/* S_DMA_124 */
-
-/*----------------------------------------------------------------------------*/
-
-/* Hardware registers for LCD DMA */
-#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
-#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
-#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
-#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
-#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
-#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
-
-#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
-#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
-#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
-#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
-#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
-#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
-#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
-#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
-#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
-#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
-#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
-#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
-#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
-#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
-#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
-#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
-#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
-#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
-
-#define OMAP1_DMA_TOUT_IRQ		(1 << 0)
-#define OMAP_DMA_DROP_IRQ		(1 << 1)
-#define OMAP_DMA_HALF_IRQ		(1 << 2)
-#define OMAP_DMA_FRAME_IRQ		(1 << 3)
-#define OMAP_DMA_LAST_IRQ		(1 << 4)
-#define OMAP_DMA_BLOCK_IRQ		(1 << 5)
-#define OMAP1_DMA_SYNC_IRQ		(1 << 6)
-#define OMAP2_DMA_PKT_IRQ		(1 << 7)
-#define OMAP2_DMA_TRANS_ERR_IRQ		(1 << 8)
-#define OMAP2_DMA_SECURE_ERR_IRQ	(1 << 9)
-#define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
-#define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
-
-#define OMAP_DMA_DATA_TYPE_S8		0x00
-#define OMAP_DMA_DATA_TYPE_S16		0x01
-#define OMAP_DMA_DATA_TYPE_S32		0x02
-
-#define OMAP_DMA_SYNC_ELEMENT		0x00
-#define OMAP_DMA_SYNC_FRAME		0x01
-#define OMAP_DMA_SYNC_BLOCK		0x02
-#define OMAP_DMA_SYNC_PACKET		0x03
-
-#define OMAP_DMA_SRC_SYNC		0x01
-#define OMAP_DMA_DST_SYNC		0x00
-
-#define OMAP_DMA_PORT_EMIFF		0x00
-#define OMAP_DMA_PORT_EMIFS		0x01
-#define OMAP_DMA_PORT_OCP_T1		0x02
-#define OMAP_DMA_PORT_TIPB		0x03
-#define OMAP_DMA_PORT_OCP_T2		0x04
-#define OMAP_DMA_PORT_MPUI		0x05
-
-#define OMAP_DMA_AMODE_CONSTANT		0x00
-#define OMAP_DMA_AMODE_POST_INC		0x01
-#define OMAP_DMA_AMODE_SINGLE_IDX	0x02
-#define OMAP_DMA_AMODE_DOUBLE_IDX	0x03
-
-#define DMA_DEFAULT_FIFO_DEPTH		0x10
-#define DMA_DEFAULT_ARB_RATE		0x01
-/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
-#define DMA_THREAD_RESERVE_NORM		(0x00 << 12) /* Def */
-#define DMA_THREAD_RESERVE_ONET		(0x01 << 12)
-#define DMA_THREAD_RESERVE_TWOT		(0x02 << 12)
-#define DMA_THREAD_RESERVE_THREET	(0x03 << 12)
-#define DMA_THREAD_FIFO_NONE		(0x00 << 14) /* Def */
-#define DMA_THREAD_FIFO_75		(0x01 << 14)
-#define DMA_THREAD_FIFO_25		(0x02 << 14)
-#define DMA_THREAD_FIFO_50		(0x03 << 14)
-
-/* DMA4_OCP_SYSCONFIG bits */
-#define DMA_SYSCONFIG_MIDLEMODE_MASK		(3 << 12)
-#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
-#define DMA_SYSCONFIG_EMUFREE			(1 << 5)
-#define DMA_SYSCONFIG_SIDLEMODE_MASK		(3 << 3)
-#define DMA_SYSCONFIG_SOFTRESET			(1 << 2)
-#define DMA_SYSCONFIG_AUTOIDLE			(1 << 0)
-
-#define DMA_SYSCONFIG_MIDLEMODE(n)		((n) << 12)
-#define DMA_SYSCONFIG_SIDLEMODE(n)		((n) << 3)
-
-#define DMA_IDLEMODE_SMARTIDLE			0x2
-#define DMA_IDLEMODE_NO_IDLE			0x1
-#define DMA_IDLEMODE_FORCE_IDLE			0x0
-
-/* Chaining modes*/
-#ifndef CONFIG_ARCH_OMAP1
-#define OMAP_DMA_STATIC_CHAIN		0x1
-#define OMAP_DMA_DYNAMIC_CHAIN		0x2
-#define OMAP_DMA_CHAIN_ACTIVE		0x1
-#define OMAP_DMA_CHAIN_INACTIVE		0x0
-#endif
-
-#define DMA_CH_PRIO_HIGH		0x1
-#define DMA_CH_PRIO_LOW			0x0 /* Def */
-
-/* LCD DMA block numbers */
-enum {
-	OMAP_LCD_DMA_B1_TOP,
-	OMAP_LCD_DMA_B1_BOTTOM,
-	OMAP_LCD_DMA_B2_TOP,
-	OMAP_LCD_DMA_B2_BOTTOM
-};
-
-enum omap_dma_burst_mode {
-	OMAP_DMA_DATA_BURST_DIS = 0,
-	OMAP_DMA_DATA_BURST_4,
-	OMAP_DMA_DATA_BURST_8,
-	OMAP_DMA_DATA_BURST_16,
-};
-
-enum end_type {
-	OMAP_DMA_LITTLE_ENDIAN = 0,
-	OMAP_DMA_BIG_ENDIAN
-};
-
-enum omap_dma_color_mode {
-	OMAP_DMA_COLOR_DIS = 0,
-	OMAP_DMA_CONSTANT_FILL,
-	OMAP_DMA_TRANSPARENT_COPY
-};
-
-enum omap_dma_write_mode {
-	OMAP_DMA_WRITE_NON_POSTED = 0,
-	OMAP_DMA_WRITE_POSTED,
-	OMAP_DMA_WRITE_LAST_NON_POSTED
-};
-
-enum omap_dma_channel_mode {
-	OMAP_DMA_LCH_2D = 0,
-	OMAP_DMA_LCH_G,
-	OMAP_DMA_LCH_P,
-	OMAP_DMA_LCH_PD
-};
-
-struct omap_dma_channel_params {
-	int data_type;		/* data type 8,16,32 */
-	int elem_count;		/* number of elements in a frame */
-	int frame_count;	/* number of frames in a element */
-
-	int src_port;		/* Only on OMAP1 REVISIT: Is this needed? */
-	int src_amode;		/* constant, post increment, indexed,
-					double indexed */
-	unsigned long src_start;	/* source address : physical */
-	int src_ei;		/* source element index */
-	int src_fi;		/* source frame index */
-
-	int dst_port;		/* Only on OMAP1 REVISIT: Is this needed? */
-	int dst_amode;		/* constant, post increment, indexed,
-					double indexed */
-	unsigned long dst_start;	/* source address : physical */
-	int dst_ei;		/* source element index */
-	int dst_fi;		/* source frame index */
-
-	int trigger;		/* trigger attached if the channel is
-					synchronized */
-	int sync_mode;		/* sycn on element, frame , block or packet */
-	int src_or_dst_synch;	/* source synch(1) or destination synch(0) */
-
-	int ie;			/* interrupt enabled */
-
-	unsigned char read_prio;/* read priority */
-	unsigned char write_prio;/* write priority */
-
-#ifndef CONFIG_ARCH_OMAP1
-	enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
-#endif
-};
-
-
-extern void omap_set_dma_priority(int lch, int dst_port, int priority);
-extern int omap_request_dma(int dev_id, const char *dev_name,
-			void (*callback)(int lch, u16 ch_status, void *data),
-			void *data, int *dma_ch);
-extern void omap_enable_dma_irq(int ch, u16 irq_bits);
-extern void omap_disable_dma_irq(int ch, u16 irq_bits);
-extern void omap_free_dma(int ch);
-extern void omap_start_dma(int lch);
-extern void omap_stop_dma(int lch);
-extern void omap_set_dma_transfer_params(int lch, int data_type,
-					 int elem_count, int frame_count,
-					 int sync_mode,
-					 int dma_trigger, int src_or_dst_synch);
-extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
-				    u32 color);
-extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
-extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
-
-extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
-				    unsigned long src_start,
-				    int src_ei, int src_fi);
-extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
-extern void omap_set_dma_src_data_pack(int lch, int enable);
-extern void omap_set_dma_src_burst_mode(int lch,
-					enum omap_dma_burst_mode burst_mode);
-
-extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
-				     unsigned long dest_start,
-				     int dst_ei, int dst_fi);
-extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
-extern void omap_set_dma_dest_data_pack(int lch, int enable);
-extern void omap_set_dma_dest_burst_mode(int lch,
-					 enum omap_dma_burst_mode burst_mode);
-
-extern void omap_set_dma_params(int lch,
-				struct omap_dma_channel_params *params);
-
-extern void omap_dma_link_lch(int lch_head, int lch_queue);
-extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
-
-extern int omap_set_dma_callback(int lch,
-			void (*callback)(int lch, u16 ch_status, void *data),
-			void *data);
-extern dma_addr_t omap_get_dma_src_pos(int lch);
-extern dma_addr_t omap_get_dma_dst_pos(int lch);
-extern void omap_clear_dma(int lch);
-extern int omap_get_dma_active_status(int lch);
-extern int omap_dma_running(void);
-extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
-				       int tparams);
-extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
-				 unsigned char write_prio);
-extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
-extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
-extern int omap_get_dma_index(int lch, int *ei, int *fi);
-
-/* Chaining APIs */
-#ifndef CONFIG_ARCH_OMAP1
-extern int omap_request_dma_chain(int dev_id, const char *dev_name,
-				  void (*callback) (int lch, u16 ch_status,
-						    void *data),
-				  int *chain_id, int no_of_chans,
-				  int chain_mode,
-				  struct omap_dma_channel_params params);
-extern int omap_free_dma_chain(int chain_id);
-extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
-				     int dest_start, int elem_count,
-				     int frame_count, void *callbk_data);
-extern int omap_start_dma_chain_transfers(int chain_id);
-extern int omap_stop_dma_chain_transfers(int chain_id);
-extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
-extern int omap_get_dma_chain_dst_pos(int chain_id);
-extern int omap_get_dma_chain_src_pos(int chain_id);
-
-extern int omap_modify_dma_chain_params(int chain_id,
-					struct omap_dma_channel_params params);
-extern int omap_dma_chain_status(int chain_id);
-#endif
-
-/* LCD DMA functions */
-extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
-				void *data);
-extern void omap_free_lcd_dma(void);
-extern void omap_setup_lcd_dma(void);
-extern void omap_enable_lcd_dma(void);
-extern void omap_stop_lcd_dma(void);
-extern void omap_set_lcd_dma_ext_controller(int external);
-extern void omap_set_lcd_dma_single_transfer(int single);
-extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
-				int data_type);
-extern void omap_set_lcd_dma_b1_rotation(int rotate);
-extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
-extern void omap_set_lcd_dma_b1_mirror(int mirror);
-extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
-
-#endif /* __ASM_ARCH_DMA_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,84 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/dmtimer.h
- *
- * OMAP Dual-Mode Timers
- *
- * Copyright (C) 2005 Nokia Corporation
- * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
- * PWM and clock framwork support by Timo Teras.
- *
- * 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
- * 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.
- */
-
-#ifndef __ASM_ARCH_DMTIMER_H
-#define __ASM_ARCH_DMTIMER_H
-
-/* clock sources */
-#define OMAP_TIMER_SRC_SYS_CLK			0x00
-#define OMAP_TIMER_SRC_32_KHZ			0x01
-#define OMAP_TIMER_SRC_EXT_CLK			0x02
-
-/* timer interrupt enable bits */
-#define OMAP_TIMER_INT_CAPTURE			(1 << 2)
-#define OMAP_TIMER_INT_OVERFLOW			(1 << 1)
-#define OMAP_TIMER_INT_MATCH			(1 << 0)
-
-/* trigger types */
-#define OMAP_TIMER_TRIGGER_NONE			0x00
-#define OMAP_TIMER_TRIGGER_OVERFLOW		0x01
-#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
-
-struct omap_dm_timer;
-struct clk;
-
-int omap_dm_timer_init(void);
-
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
-void omap_dm_timer_free(struct omap_dm_timer *timer);
-void omap_dm_timer_enable(struct omap_dm_timer *timer);
-void omap_dm_timer_disable(struct omap_dm_timer *timer);
-
-int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
-
-u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-
-void omap_dm_timer_trigger(struct omap_dm_timer *timer);
-void omap_dm_timer_start(struct omap_dm_timer *timer);
-void omap_dm_timer_stop(struct omap_dm_timer *timer);
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
-
-int omap_dm_timers_active(void);
-
-
-#endif /* __ASM_ARCH_DMTIMER_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dsp_common.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dsp_common.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/dsp_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/dsp_common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
- *
- * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
- *
- * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@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
- *
- */
-
-#ifndef ASM_ARCH_DSP_COMMON_H
-#define ASM_ARCH_DSP_COMMON_H
-
-#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_OMAP_MMU_FWK)
-extern void omap_dsp_request_mpui(void);
-extern void omap_dsp_release_mpui(void);
-extern int omap_dsp_request_mem(void);
-extern int omap_dsp_release_mem(void);
-#else
-static inline int omap_dsp_request_mem(void)
-{
-	return 0;
-}
-#define omap_dsp_release_mem()	do {} while (0)
-#endif
-
-#endif /* ASM_ARCH_DSP_COMMON_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/entry-macro.S linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/entry-macro.S
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/entry-macro.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,172 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for OMAP-based platforms
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@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 <mach/hardware.h>
-#include <mach/io.h>
-#include <mach/irqs.h>
-#include <asm/hardware/gic.h>
-
-#if defined(CONFIG_ARCH_OMAP1)
-
-#if defined(CONFIG_ARCH_OMAP730) && \
-	(defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
-#error "FIXME: OMAP730 doesn't support multiple-OMAP"
-#elif defined(CONFIG_ARCH_OMAP730)
-#define INT_IH2_IRQ		INT_730_IH2_IRQ
-#elif defined(CONFIG_ARCH_OMAP15XX)
-#define INT_IH2_IRQ		INT_1510_IH2_IRQ
-#elif defined(CONFIG_ARCH_OMAP16XX)
-#define INT_IH2_IRQ		INT_1610_IH2_IRQ
-#else
-#warning "IH2 IRQ defaulted"
-#define INT_IH2_IRQ		INT_1510_IH2_IRQ
-#endif
-
- 		.macro	disable_fiq
-		.endm
-
-		.macro  get_irqnr_preamble, base, tmp
-		.endm
-
-		.macro  arch_ret_to_user, tmp1, tmp2
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
-		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
-		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
-		mov	\irqstat, #0xffffffff
-		bic	\tmp, \irqstat, \tmp
-		tst	\irqnr, \tmp
-		beq	1510f
-
-		ldr	\irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
-		cmp	\irqnr, #0
-		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-		cmpeq	\irqnr, #INT_IH2_IRQ
-		ldreq	\base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
-		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-		addeqs	\irqnr, \irqnr, #32
-1510:
-		.endm
-
-#endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
-
-#include <mach/omap24xx.h>
-#include <mach/omap34xx.h>
-
-/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
-#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
-#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE)
-#elif defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE)
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-#include <mach/omap44xx.h>
-#endif
-#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
-#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
-
-		.macro	disable_fiq
-		.endm
-
-		.macro  get_irqnr_preamble, base, tmp
-		.endm
-
-		.macro  arch_ret_to_user, tmp1, tmp2
-		.endm
-
-#ifndef CONFIG_ARCH_OMAP4
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =OMAP2_VA_IC_BASE
-		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
-		cmp	\irqnr, #0x0
-		bne	2222f
-		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
-		cmp	\irqnr, #0x0
-2222:
-		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
-		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
-
-		.endm
-#else
-		/*
-		 * The interrupt numbering scheme is defined in the
-		 * interrupt controller spec.  To wit:
-		 *
-		 * Interrupts 0-15 are IPI
-		 * 16-28 are reserved
-		 * 29-31 are local.  We allow 30 to be used for the watchdog.
-		 * 32-1020 are global
-		 * 1021-1022 are reserved
-		 * 1023 is "spurious" (no interrupt)
-		 *
-		 * For now, we ignore all local interrupts so only return an
-		 * interrupt if it's between 30 and 1020.  The test_for_ipi
-		 * routine below will pick up on IPIs.
-		 * A simple read from the controller will tell us the number
-		 * of the highest priority enabled interrupt.
-		 * We then just need to check whether it is in the
-		 * valid range for an IRQ (30-1020 inclusive).
-		 */
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr     \base, =OMAP44XX_VA_GIC_CPU_BASE
-		ldr     \irqstat, [\base, #GIC_CPU_INTACK]
-
-		ldr     \tmp, =1021
-
-		bic     \irqnr, \irqstat, #0x1c00
-
-		cmp     \irqnr, #29
-		cmpcc   \irqnr, \irqnr
-		cmpne   \irqnr, \tmp
-		cmpcs   \irqnr, \irqnr
-		.endm
-
-		/* We assume that irqstat (the raw value of the IRQ acknowledge
-		 * register) is preserved from the macro above.
-		 * If there is an IPI, we immediately signal end of interrupt
-		 * on the controller, since this requires the original irqstat
-		 * value which we won't easily be able to recreate later.
-		 */
-
-		.macro test_for_ipi, irqnr, irqstat, base, tmp
-		bic	\irqnr, \irqstat, #0x1c00
-		cmp	\irqnr, #16
-		it	cc
-		strcc	\irqstat, [\base, #GIC_CPU_EOI]
-		it	cs
-		cmpcs	\irqnr, \irqnr
-		.endm
-
-		/* As above, this assumes that irqstat and base are preserved */
-
-		.macro test_for_ltirq, irqnr, irqstat, base, tmp
-		bic	\irqnr, \irqstat, #0x1c00
-		mov 	\tmp, #0
-		cmp	\irqnr, #29
-		itt	eq
-		moveq	\tmp, #1
-		streq	\irqstat, [\base, #GIC_CPU_EOI]
-		cmp	\tmp, #0
-		.endm
-#endif
-
-		.macro	irq_prio_table
-		.endm
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/fpga.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/fpga.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/fpga.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/fpga.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,197 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/fpga.h
- *
- * Interrupt handler for OMAP-1510 FPGA
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Copyright (C) 2002 MontaVista Software, Inc.
- *
- * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
- * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.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 __ASM_ARCH_OMAP_FPGA_H
-#define __ASM_ARCH_OMAP_FPGA_H
-
-#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
-extern void omap1510_fpga_init_irq(void);
-#else
-#define omap1510_fpga_init_irq()	(0)
-#endif
-
-#define fpga_read(reg)			__raw_readb(reg)
-#define fpga_write(val, reg)		__raw_writeb(val, reg)
-
-/*
- * ---------------------------------------------------------------------------
- *  H2/P2 Debug board FPGA
- * ---------------------------------------------------------------------------
- */
-/* maps in the FPGA registers and the ETHR registers */
-#define H2P2_DBG_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
-#define H2P2_DBG_FPGA_SIZE		SZ_4K			/* SIZE */
-#define H2P2_DBG_FPGA_START		0x04000000		/* PA */
-
-#define H2P2_DBG_FPGA_ETHR_START	(H2P2_DBG_FPGA_START + 0x300)
-#define H2P2_DBG_FPGA_FPGA_REV		(H2P2_DBG_FPGA_BASE + 0x10)	/* FPGA Revision */
-#define H2P2_DBG_FPGA_BOARD_REV		(H2P2_DBG_FPGA_BASE + 0x12)	/* Board Revision */
-#define H2P2_DBG_FPGA_GPIO		(H2P2_DBG_FPGA_BASE + 0x14)	/* GPIO outputs */
-#define H2P2_DBG_FPGA_LEDS		(H2P2_DBG_FPGA_BASE + 0x16)	/* LEDs outputs */
-#define H2P2_DBG_FPGA_MISC_INPUTS	(H2P2_DBG_FPGA_BASE + 0x18)	/* Misc inputs */
-#define H2P2_DBG_FPGA_LAN_STATUS	(H2P2_DBG_FPGA_BASE + 0x1A)	/* LAN Status line */
-#define H2P2_DBG_FPGA_LAN_RESET		(H2P2_DBG_FPGA_BASE + 0x1C)	/* LAN Reset line */
-
-/* NOTE:  most boards don't have a static mapping for the FPGA ... */
-struct h2p2_dbg_fpga {
-	/* offset 0x00 */
-	u16		smc91x[8];
-	/* offset 0x10 */
-	u16		fpga_rev;
-	u16		board_rev;
-	u16		gpio_outputs;
-	u16		leds;
-	/* offset 0x18 */
-	u16		misc_inputs;
-	u16		lan_status;
-	u16		lan_reset;
-	u16		reserved0;
-	/* offset 0x20 */
-	u16		ps2_data;
-	u16		ps2_ctrl;
-	/* plus also 4 rs232 ports ... */
-};
-
-/* LEDs definition on debug board (16 LEDs, all physically green) */
-#define H2P2_DBG_FPGA_LED_GREEN		(1 << 15)
-#define H2P2_DBG_FPGA_LED_AMBER		(1 << 14)
-#define H2P2_DBG_FPGA_LED_RED		(1 << 13)
-#define H2P2_DBG_FPGA_LED_BLUE		(1 << 12)
-/*  cpu0 load-meter LEDs */
-#define H2P2_DBG_FPGA_LOAD_METER	(1 << 0)	// A bit of fun on our board ...
-#define H2P2_DBG_FPGA_LOAD_METER_SIZE	11
-#define H2P2_DBG_FPGA_LOAD_METER_MASK	((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
-
-#define H2P2_DBG_FPGA_P2_LED_TIMER		(1 << 0)
-#define H2P2_DBG_FPGA_P2_LED_IDLE		(1 << 1)
-
-/*
- * ---------------------------------------------------------------------------
- *  OMAP-1510 FPGA
- * ---------------------------------------------------------------------------
- */
-#define OMAP1510_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
-#define OMAP1510_FPGA_SIZE		SZ_4K
-#define OMAP1510_FPGA_START		0x08000000		/* PA */
-
-/* Revision */
-#define OMAP1510_FPGA_REV_LOW			(OMAP1510_FPGA_BASE + 0x0)
-#define OMAP1510_FPGA_REV_HIGH			(OMAP1510_FPGA_BASE + 0x1)
-
-#define OMAP1510_FPGA_LCD_PANEL_CONTROL		(OMAP1510_FPGA_BASE + 0x2)
-#define OMAP1510_FPGA_LED_DIGIT			(OMAP1510_FPGA_BASE + 0x3)
-#define INNOVATOR_FPGA_HID_SPI			(OMAP1510_FPGA_BASE + 0x4)
-#define OMAP1510_FPGA_POWER			(OMAP1510_FPGA_BASE + 0x5)
-
-/* Interrupt status */
-#define OMAP1510_FPGA_ISR_LO			(OMAP1510_FPGA_BASE + 0x6)
-#define OMAP1510_FPGA_ISR_HI			(OMAP1510_FPGA_BASE + 0x7)
-
-/* Interrupt mask */
-#define OMAP1510_FPGA_IMR_LO			(OMAP1510_FPGA_BASE + 0x8)
-#define OMAP1510_FPGA_IMR_HI			(OMAP1510_FPGA_BASE + 0x9)
-
-/* Reset registers */
-#define OMAP1510_FPGA_HOST_RESET		(OMAP1510_FPGA_BASE + 0xa)
-#define OMAP1510_FPGA_RST			(OMAP1510_FPGA_BASE + 0xb)
-
-#define OMAP1510_FPGA_AUDIO			(OMAP1510_FPGA_BASE + 0xc)
-#define OMAP1510_FPGA_DIP			(OMAP1510_FPGA_BASE + 0xe)
-#define OMAP1510_FPGA_FPGA_IO			(OMAP1510_FPGA_BASE + 0xf)
-#define OMAP1510_FPGA_UART1			(OMAP1510_FPGA_BASE + 0x14)
-#define OMAP1510_FPGA_UART2			(OMAP1510_FPGA_BASE + 0x15)
-#define OMAP1510_FPGA_OMAP1510_STATUS		(OMAP1510_FPGA_BASE + 0x16)
-#define OMAP1510_FPGA_BOARD_REV			(OMAP1510_FPGA_BASE + 0x18)
-#define OMAP1510P1_PPT_DATA			(OMAP1510_FPGA_BASE + 0x100)
-#define OMAP1510P1_PPT_STATUS			(OMAP1510_FPGA_BASE + 0x101)
-#define OMAP1510P1_PPT_CONTROL			(OMAP1510_FPGA_BASE + 0x102)
-
-#define OMAP1510_FPGA_TOUCHSCREEN		(OMAP1510_FPGA_BASE + 0x204)
-
-#define INNOVATOR_FPGA_INFO			(OMAP1510_FPGA_BASE + 0x205)
-#define INNOVATOR_FPGA_LCD_BRIGHT_LO		(OMAP1510_FPGA_BASE + 0x206)
-#define INNOVATOR_FPGA_LCD_BRIGHT_HI		(OMAP1510_FPGA_BASE + 0x207)
-#define INNOVATOR_FPGA_LED_GRN_LO		(OMAP1510_FPGA_BASE + 0x208)
-#define INNOVATOR_FPGA_LED_GRN_HI		(OMAP1510_FPGA_BASE + 0x209)
-#define INNOVATOR_FPGA_LED_RED_LO		(OMAP1510_FPGA_BASE + 0x20a)
-#define INNOVATOR_FPGA_LED_RED_HI		(OMAP1510_FPGA_BASE + 0x20b)
-#define INNOVATOR_FPGA_CAM_USB_CONTROL		(OMAP1510_FPGA_BASE + 0x20c)
-#define INNOVATOR_FPGA_EXP_CONTROL		(OMAP1510_FPGA_BASE + 0x20d)
-#define INNOVATOR_FPGA_ISR2			(OMAP1510_FPGA_BASE + 0x20e)
-#define INNOVATOR_FPGA_IMR2			(OMAP1510_FPGA_BASE + 0x210)
-
-#define OMAP1510_FPGA_ETHR_START		(OMAP1510_FPGA_START + 0x300)
-
-/*
- * Power up Giga UART driver, turn on HID clock.
- * Turn off BT power, since we're not using it and it
- * draws power.
- */
-#define OMAP1510_FPGA_RESET_VALUE		0x42
-
-#define OMAP1510_FPGA_PCR_IF_PD0		(1 << 7)
-#define OMAP1510_FPGA_PCR_COM2_EN		(1 << 6)
-#define OMAP1510_FPGA_PCR_COM1_EN		(1 << 5)
-#define OMAP1510_FPGA_PCR_EXP_PD0		(1 << 4)
-#define OMAP1510_FPGA_PCR_EXP_PD1		(1 << 3)
-#define OMAP1510_FPGA_PCR_48MHZ_CLK		(1 << 2)
-#define OMAP1510_FPGA_PCR_4MHZ_CLK		(1 << 1)
-#define OMAP1510_FPGA_PCR_RSRVD_BIT0		(1 << 0)
-
-/*
- * Innovator/OMAP1510 FPGA HID register bit definitions
- */
-#define OMAP1510_FPGA_HID_SCLK	(1<<0)	/* output */
-#define OMAP1510_FPGA_HID_MOSI	(1<<1)	/* output */
-#define OMAP1510_FPGA_HID_nSS	(1<<2)	/* output 0/1 chip idle/select */
-#define OMAP1510_FPGA_HID_nHSUS	(1<<3)	/* output 0/1 host active/suspended */
-#define OMAP1510_FPGA_HID_MISO	(1<<4)	/* input */
-#define OMAP1510_FPGA_HID_ATN	(1<<5)	/* input  0/1 chip idle/ATN */
-#define OMAP1510_FPGA_HID_rsrvd	(1<<6)
-#define OMAP1510_FPGA_HID_RESETn (1<<7)	/* output - 0/1 USAR reset/run */
-
-/* The FPGA IRQ is cascaded through GPIO_13 */
-#define OMAP1510_INT_FPGA		(IH_GPIO_BASE + 13)
-
-/* IRQ Numbers for interrupts muxed through the FPGA */
-#define OMAP1510_INT_FPGA_ATN		(OMAP_FPGA_IRQ_BASE + 0)
-#define OMAP1510_INT_FPGA_ACK		(OMAP_FPGA_IRQ_BASE + 1)
-#define OMAP1510_INT_FPGA2		(OMAP_FPGA_IRQ_BASE + 2)
-#define OMAP1510_INT_FPGA3		(OMAP_FPGA_IRQ_BASE + 3)
-#define OMAP1510_INT_FPGA4		(OMAP_FPGA_IRQ_BASE + 4)
-#define OMAP1510_INT_FPGA5		(OMAP_FPGA_IRQ_BASE + 5)
-#define OMAP1510_INT_FPGA6		(OMAP_FPGA_IRQ_BASE + 6)
-#define OMAP1510_INT_FPGA7		(OMAP_FPGA_IRQ_BASE + 7)
-#define OMAP1510_INT_FPGA8		(OMAP_FPGA_IRQ_BASE + 8)
-#define OMAP1510_INT_FPGA9		(OMAP_FPGA_IRQ_BASE + 9)
-#define OMAP1510_INT_FPGA10		(OMAP_FPGA_IRQ_BASE + 10)
-#define OMAP1510_INT_FPGA11		(OMAP_FPGA_IRQ_BASE + 11)
-#define OMAP1510_INT_FPGA12		(OMAP_FPGA_IRQ_BASE + 12)
-#define OMAP1510_INT_ETHER		(OMAP_FPGA_IRQ_BASE + 13)
-#define OMAP1510_INT_FPGAUART1		(OMAP_FPGA_IRQ_BASE + 14)
-#define OMAP1510_INT_FPGAUART2		(OMAP_FPGA_IRQ_BASE + 15)
-#define OMAP1510_INT_FPGA_TS		(OMAP_FPGA_IRQ_BASE + 16)
-#define OMAP1510_INT_FPGA17		(OMAP_FPGA_IRQ_BASE + 17)
-#define OMAP1510_INT_FPGA_CAM		(OMAP_FPGA_IRQ_BASE + 18)
-#define OMAP1510_INT_FPGA_RTC_A		(OMAP_FPGA_IRQ_BASE + 19)
-#define OMAP1510_INT_FPGA_RTC_B		(OMAP_FPGA_IRQ_BASE + 20)
-#define OMAP1510_INT_FPGA_CD		(OMAP_FPGA_IRQ_BASE + 21)
-#define OMAP1510_INT_FPGA22		(OMAP_FPGA_IRQ_BASE + 22)
-#define OMAP1510_INT_FPGA23		(OMAP_FPGA_IRQ_BASE + 23)
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/gpio.h
- *
- * OMAP GPIO handling defines and functions
- *
- * Copyright (C) 2003-2005 Nokia Corporation
- *
- * Written by Juha Yrjölä <juha.yrjola@nokia.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
- *
- */
-
-#ifndef __ASM_ARCH_OMAP_GPIO_H
-#define __ASM_ARCH_OMAP_GPIO_H
-
-#include <linux/io.h>
-#include <mach/irqs.h>
-
-#define OMAP1_MPUIO_BASE			0xfffb5000
-
-#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
-
-#define OMAP_MPUIO_INPUT_LATCH		0x00
-#define OMAP_MPUIO_OUTPUT		0x02
-#define OMAP_MPUIO_IO_CNTL		0x04
-#define OMAP_MPUIO_KBR_LATCH		0x08
-#define OMAP_MPUIO_KBC			0x0a
-#define OMAP_MPUIO_GPIO_EVENT_MODE	0x0c
-#define OMAP_MPUIO_GPIO_INT_EDGE	0x0e
-#define OMAP_MPUIO_KBD_INT		0x10
-#define OMAP_MPUIO_GPIO_INT		0x12
-#define OMAP_MPUIO_KBD_MASKIT		0x14
-#define OMAP_MPUIO_GPIO_MASKIT		0x16
-#define OMAP_MPUIO_GPIO_DEBOUNCING	0x18
-#define OMAP_MPUIO_LATCH		0x1a
-#else
-#define OMAP_MPUIO_INPUT_LATCH		0x00
-#define OMAP_MPUIO_OUTPUT		0x04
-#define OMAP_MPUIO_IO_CNTL		0x08
-#define OMAP_MPUIO_KBR_LATCH		0x10
-#define OMAP_MPUIO_KBC			0x14
-#define OMAP_MPUIO_GPIO_EVENT_MODE	0x18
-#define OMAP_MPUIO_GPIO_INT_EDGE	0x1c
-#define OMAP_MPUIO_KBD_INT		0x20
-#define OMAP_MPUIO_GPIO_INT		0x24
-#define OMAP_MPUIO_KBD_MASKIT		0x28
-#define OMAP_MPUIO_GPIO_MASKIT		0x2c
-#define OMAP_MPUIO_GPIO_DEBOUNCING	0x30
-#define OMAP_MPUIO_LATCH		0x34
-#endif
-
-#define OMAP34XX_NR_GPIOS		6
-
-#define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
-#define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
-
-#define OMAP_GPIO_IRQ(nr)	(OMAP_GPIO_IS_MPUIO(nr) ? \
-				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
-				 IH_GPIO_BASE + (nr))
-
-extern int omap_gpio_init(void);	/* Call from board init only */
-extern void omap2_gpio_prepare_for_retention(void);
-extern void omap2_gpio_resume_after_retention(void);
-extern void omap_set_gpio_debounce(int gpio, int enable);
-extern void omap_set_gpio_debounce_time(int gpio, int enable);
-
-/*-------------------------------------------------------------------------*/
-
-/* Wrappers for "new style" GPIO calls, using the new infrastructure
- * which lets us plug in FPGA, I2C, and other implementations.
- * *
- * The original OMAP-specfic calls should eventually be removed.
- */
-
-#include <linux/errno.h>
-#include <asm-generic/gpio.h>
-
-static inline int gpio_get_value(unsigned gpio)
-{
-	return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	__gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-	return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return __gpio_to_irq(gpio);
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-	int tmp;
-
-	/* omap1 SOC mpuio */
-	if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
-		return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;
-
-	/* SOC gpio */
-	tmp = irq - IH_GPIO_BASE;
-	if (tmp < OMAP_MAX_GPIO_LINES)
-		return tmp;
-
-	/* we don't supply reverse mappings for non-SOC gpios */
-	return -EIO;
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpio-switch.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpio-switch.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpio-switch.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpio-switch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- * GPIO switch definitions
- *
- * Copyright (C) 2006 Nokia 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 __ASM_ARCH_OMAP_GPIO_SWITCH_H
-#define __ASM_ARCH_OMAP_GPIO_SWITCH_H
-
-#include <linux/types.h>
-
-/* Cover:
- *	high -> closed
- *	low  -> open
- * Connection:
- *	high -> connected
- *	low  -> disconnected
- * Activity:
- *	high -> active
- *	low  -> inactive
- *
- */
-#define OMAP_GPIO_SWITCH_TYPE_COVER		0x0000
-#define OMAP_GPIO_SWITCH_TYPE_CONNECTION	0x0001
-#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY		0x0002
-#define OMAP_GPIO_SWITCH_FLAG_INVERTED		0x0001
-#define OMAP_GPIO_SWITCH_FLAG_OUTPUT		0x0002
-
-struct omap_gpio_switch {
-	const char *name;
-	s16 gpio;
-	unsigned flags:4;
-	unsigned type:4;
-
-	/* Time in ms to debounce when transitioning from
-	 * inactive state to active state. */
-	u16 debounce_rising;
-	/* Same for transition from active to inactive state. */
-	u16 debounce_falling;
-
-	/* notify board-specific code about state changes */
-	void (* notify)(void *data, int state);
-	void *notify_data;
-};
-
-/* Call at init time only */
-extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
-					int count);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpmc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpmc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpmc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpmc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,112 +0,0 @@
-/*
- * General-Purpose Memory Controller for OMAP2
- *
- * Copyright (C) 2005-2006 Nokia 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 __OMAP2_GPMC_H
-#define __OMAP2_GPMC_H
-
-/* Maximum Number of Chip Selects */
-#define GPMC_CS_NUM		8
-
-#define GPMC_CS_CONFIG1		0x00
-#define GPMC_CS_CONFIG2		0x04
-#define GPMC_CS_CONFIG3		0x08
-#define GPMC_CS_CONFIG4		0x0c
-#define GPMC_CS_CONFIG5		0x10
-#define GPMC_CS_CONFIG6		0x14
-#define GPMC_CS_CONFIG7		0x18
-#define GPMC_CS_NAND_COMMAND	0x1c
-#define GPMC_CS_NAND_ADDRESS	0x20
-#define GPMC_CS_NAND_DATA	0x24
-
-#define GPMC_CONFIG		0x50
-#define GPMC_STATUS		0x54
-
-#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
-#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
-#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
-#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
-#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
-#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
-#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
-#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
-#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
-#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
-#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
-#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
-#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
-#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
-#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
-#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
-#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
-#define GPMC_CONFIG1_DEVICETYPE_NAND    GPMC_CONFIG1_DEVICETYPE(1)
-#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
-#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
-#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
-#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
-#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
-#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
-
-/*
- * Note that all values in this struct are in nanoseconds, while
- * the register values are in gpmc_fck cycles.
- */
-struct gpmc_timings {
-	/* Minimum clock period for synchronous mode */
-	u16 sync_clk;
-
-	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
-
-	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
-
-	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
-
-	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
-
-	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
-
-	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
-};
-
-extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
-extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
-extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
-extern unsigned long gpmc_get_fclk_period(void);
-
-extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
-extern u32 gpmc_cs_read_reg(int cs, int idx);
-extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
-extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
-extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
-extern void gpmc_cs_free(int cs);
-extern int gpmc_cs_set_reserved(int cs, int reserved);
-extern int gpmc_cs_reserved(int cs);
-extern int gpmc_prefetch_enable(int cs, int dma_mode,
-					unsigned int u32_count, int is_write);
-extern void gpmc_prefetch_reset(void);
-extern int gpmc_prefetch_status(void);
-extern void __init gpmc_init(void);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpmc-smc91x.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpmc-smc91x.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/gpmc-smc91x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/gpmc-smc91x.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/gpmc-smc91x.h
- *
- * Copyright (C) 2009 Nokia 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 __ASM_ARCH_OMAP_GPMC_SMC91X_H__
-
-#define GPMC_TIMINGS_SMC91C96	(1 << 4)
-#define GPMC_MUX_ADD_DATA	(1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
-#define GPMC_READ_MON		(1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
-#define GPMC_WRITE_MON		(1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
-
-struct omap_smc91x_platform_data {
-	int	cs;
-	int	gpio_irq;
-	int	gpio_pwrdwn;
-	int	gpio_reset;
-	int	wait_pin;	/* Optional GPMC_CONFIG1_WAITPINSELECT */
-	u32	flags;
-	int	(*retime)(void);
-};
-
-#if defined(CONFIG_SMC91X) || \
-	defined(CONFIG_SMC91X_MODULE)
-
-extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
-
-#else
-
-#define board_smc91x_data	NULL
-
-static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
-{
-}
-
-#endif
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/hardware.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/hardware.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,290 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/hardware.h
- *
- * Hardware definitions for TI OMAP processors and boards
- *
- * NOTE: Please put device driver specific defines into a separate header
- *	 file for each driver.
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
- *
- * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
- *                          and Dirk Behme <dirk.behme@de.bosch.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 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.
- */
-
-#ifndef __ASM_ARCH_OMAP_HARDWARE_H
-#define __ASM_ARCH_OMAP_HARDWARE_H
-
-#include <asm/sizes.h>
-#ifndef __ASSEMBLER__
-#include <asm/types.h>
-#include <mach/cpu.h>
-#endif
-#include <mach/serial.h>
-
-/*
- * ---------------------------------------------------------------------------
- * Common definitions for all OMAP processors
- * NOTE: Put all processor or board specific parts to the special header
- *	 files.
- * ---------------------------------------------------------------------------
- */
-
-/*
- * ----------------------------------------------------------------------------
- * Timers
- * ----------------------------------------------------------------------------
- */
-#define OMAP_MPU_TIMER1_BASE	(0xfffec500)
-#define OMAP_MPU_TIMER2_BASE	(0xfffec600)
-#define OMAP_MPU_TIMER3_BASE	(0xfffec700)
-#define MPU_TIMER_FREE		(1 << 6)
-#define MPU_TIMER_CLOCK_ENABLE	(1 << 5)
-#define MPU_TIMER_AR		(1 << 1)
-#define MPU_TIMER_ST		(1 << 0)
-
-/*
- * ----------------------------------------------------------------------------
- * Clocks
- * ----------------------------------------------------------------------------
- */
-#define CLKGEN_REG_BASE		(0xfffece00)
-#define ARM_CKCTL		(CLKGEN_REG_BASE + 0x0)
-#define ARM_IDLECT1		(CLKGEN_REG_BASE + 0x4)
-#define ARM_IDLECT2		(CLKGEN_REG_BASE + 0x8)
-#define ARM_EWUPCT		(CLKGEN_REG_BASE + 0xC)
-#define ARM_RSTCT1		(CLKGEN_REG_BASE + 0x10)
-#define ARM_RSTCT2		(CLKGEN_REG_BASE + 0x14)
-#define ARM_SYSST		(CLKGEN_REG_BASE + 0x18)
-#define ARM_IDLECT3		(CLKGEN_REG_BASE + 0x24)
-
-#define CK_RATEF		1
-#define CK_IDLEF		2
-#define CK_ENABLEF		4
-#define CK_SELECTF		8
-#define SETARM_IDLE_SHIFT
-
-/* DPLL control registers */
-#define DPLL_CTL		(0xfffecf00)
-
-/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
-#define DSP_CONFIG_REG_BASE     IOMEM(0xe1008000)
-#define DSP_CKCTL		(DSP_CONFIG_REG_BASE + 0x0)
-#define DSP_IDLECT1		(DSP_CONFIG_REG_BASE + 0x4)
-#define DSP_IDLECT2		(DSP_CONFIG_REG_BASE + 0x8)
-#define DSP_RSTCT2		(DSP_CONFIG_REG_BASE + 0x14)
-
-/*
- * ---------------------------------------------------------------------------
- * UPLD
- * ---------------------------------------------------------------------------
- */
-#define ULPD_REG_BASE		(0xfffe0800)
-#define ULPD_IT_STATUS		(ULPD_REG_BASE + 0x14)
-#define ULPD_SETUP_ANALOG_CELL_3	(ULPD_REG_BASE + 0x24)
-#define ULPD_CLOCK_CTRL		(ULPD_REG_BASE + 0x30)
-#	define DIS_USB_PVCI_CLK		(1 << 5)	/* no USB/FAC synch */
-#	define USB_MCLK_EN		(1 << 4)	/* enable W4_USB_CLKO */
-#define ULPD_SOFT_REQ		(ULPD_REG_BASE + 0x34)
-#	define SOFT_UDC_REQ		(1 << 4)
-#	define SOFT_USB_CLK_REQ		(1 << 3)
-#	define SOFT_DPLL_REQ		(1 << 0)
-#define ULPD_DPLL_CTRL		(ULPD_REG_BASE + 0x3c)
-#define ULPD_STATUS_REQ		(ULPD_REG_BASE + 0x40)
-#define ULPD_APLL_CTRL		(ULPD_REG_BASE + 0x4c)
-#define ULPD_POWER_CTRL		(ULPD_REG_BASE + 0x50)
-#define ULPD_SOFT_DISABLE_REQ_REG	(ULPD_REG_BASE + 0x68)
-#	define DIS_MMC2_DPLL_REQ	(1 << 11)
-#	define DIS_MMC1_DPLL_REQ	(1 << 10)
-#	define DIS_UART3_DPLL_REQ	(1 << 9)
-#	define DIS_UART2_DPLL_REQ	(1 << 8)
-#	define DIS_UART1_DPLL_REQ	(1 << 7)
-#	define DIS_USB_HOST_DPLL_REQ	(1 << 6)
-#define ULPD_SDW_CLK_DIV_CTRL_SEL	(ULPD_REG_BASE + 0x74)
-#define ULPD_CAM_CLK_CTRL	(ULPD_REG_BASE + 0x7c)
-
-/*
- * ---------------------------------------------------------------------------
- * Watchdog timer
- * ---------------------------------------------------------------------------
- */
-
-/* Watchdog timer within the OMAP3.2 gigacell */
-#define OMAP_MPU_WATCHDOG_BASE	(0xfffec800)
-#define OMAP_WDT_TIMER		(OMAP_MPU_WATCHDOG_BASE + 0x0)
-#define OMAP_WDT_LOAD_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
-#define OMAP_WDT_READ_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
-#define OMAP_WDT_TIMER_MODE	(OMAP_MPU_WATCHDOG_BASE + 0x8)
-
-/*
- * ---------------------------------------------------------------------------
- * Interrupts
- * ---------------------------------------------------------------------------
- */
-#ifdef CONFIG_ARCH_OMAP1
-
-/*
- * XXX: These probably want to be moved to arch/arm/mach-omap/omap1/irq.c
- * or something similar.. -- PFM.
- */
-
-#define OMAP_IH1_BASE		0xfffecb00
-#define OMAP_IH2_BASE		0xfffe0000
-
-#define OMAP_IH1_ITR		(OMAP_IH1_BASE + 0x00)
-#define OMAP_IH1_MIR		(OMAP_IH1_BASE + 0x04)
-#define OMAP_IH1_SIR_IRQ	(OMAP_IH1_BASE + 0x10)
-#define OMAP_IH1_SIR_FIQ	(OMAP_IH1_BASE + 0x14)
-#define OMAP_IH1_CONTROL	(OMAP_IH1_BASE + 0x18)
-#define OMAP_IH1_ILR0		(OMAP_IH1_BASE + 0x1c)
-#define OMAP_IH1_ISR		(OMAP_IH1_BASE + 0x9c)
-
-#define OMAP_IH2_ITR		(OMAP_IH2_BASE + 0x00)
-#define OMAP_IH2_MIR		(OMAP_IH2_BASE + 0x04)
-#define OMAP_IH2_SIR_IRQ	(OMAP_IH2_BASE + 0x10)
-#define OMAP_IH2_SIR_FIQ	(OMAP_IH2_BASE + 0x14)
-#define OMAP_IH2_CONTROL	(OMAP_IH2_BASE + 0x18)
-#define OMAP_IH2_ILR0		(OMAP_IH2_BASE + 0x1c)
-#define OMAP_IH2_ISR		(OMAP_IH2_BASE + 0x9c)
-
-#define IRQ_ITR_REG_OFFSET	0x00
-#define IRQ_MIR_REG_OFFSET	0x04
-#define IRQ_SIR_IRQ_REG_OFFSET	0x10
-#define IRQ_SIR_FIQ_REG_OFFSET	0x14
-#define IRQ_CONTROL_REG_OFFSET	0x18
-#define IRQ_ISR_REG_OFFSET	0x9c
-#define IRQ_ILR0_REG_OFFSET	0x1c
-#define IRQ_GMR_REG_OFFSET	0xa0
-
-#endif
-
-/*
- * ----------------------------------------------------------------------------
- * System control registers
- * ----------------------------------------------------------------------------
- */
-#define MOD_CONF_CTRL_0		0xfffe1080
-#define MOD_CONF_CTRL_1		0xfffe1110
-
-/*
- * ----------------------------------------------------------------------------
- * Pin multiplexing registers
- * ----------------------------------------------------------------------------
- */
-#define FUNC_MUX_CTRL_0		0xfffe1000
-#define FUNC_MUX_CTRL_1		0xfffe1004
-#define FUNC_MUX_CTRL_2		0xfffe1008
-#define COMP_MODE_CTRL_0	0xfffe100c
-#define FUNC_MUX_CTRL_3		0xfffe1010
-#define FUNC_MUX_CTRL_4		0xfffe1014
-#define FUNC_MUX_CTRL_5		0xfffe1018
-#define FUNC_MUX_CTRL_6		0xfffe101C
-#define FUNC_MUX_CTRL_7		0xfffe1020
-#define FUNC_MUX_CTRL_8		0xfffe1024
-#define FUNC_MUX_CTRL_9		0xfffe1028
-#define FUNC_MUX_CTRL_A		0xfffe102C
-#define FUNC_MUX_CTRL_B		0xfffe1030
-#define FUNC_MUX_CTRL_C		0xfffe1034
-#define FUNC_MUX_CTRL_D		0xfffe1038
-#define PULL_DWN_CTRL_0		0xfffe1040
-#define PULL_DWN_CTRL_1		0xfffe1044
-#define PULL_DWN_CTRL_2		0xfffe1048
-#define PULL_DWN_CTRL_3		0xfffe104c
-#define PULL_DWN_CTRL_4		0xfffe10ac
-
-/* OMAP-1610 specific multiplexing registers */
-#define FUNC_MUX_CTRL_E		0xfffe1090
-#define FUNC_MUX_CTRL_F		0xfffe1094
-#define FUNC_MUX_CTRL_10	0xfffe1098
-#define FUNC_MUX_CTRL_11	0xfffe109c
-#define FUNC_MUX_CTRL_12	0xfffe10a0
-#define PU_PD_SEL_0		0xfffe10b4
-#define PU_PD_SEL_1		0xfffe10b8
-#define PU_PD_SEL_2		0xfffe10bc
-#define PU_PD_SEL_3		0xfffe10c0
-#define PU_PD_SEL_4		0xfffe10c4
-
-/* Timer32K for 1610 and 1710*/
-#define OMAP_TIMER32K_BASE	0xFFFBC400
-
-/*
- * ---------------------------------------------------------------------------
- * TIPB bus interface
- * ---------------------------------------------------------------------------
- */
-#define TIPB_PUBLIC_CNTL_BASE		0xfffed300
-#define MPU_PUBLIC_TIPB_CNTL		(TIPB_PUBLIC_CNTL_BASE + 0x8)
-#define TIPB_PRIVATE_CNTL_BASE		0xfffeca00
-#define MPU_PRIVATE_TIPB_CNTL		(TIPB_PRIVATE_CNTL_BASE + 0x8)
-
-/*
- * ----------------------------------------------------------------------------
- * MPUI interface
- * ----------------------------------------------------------------------------
- */
-#define MPUI_BASE			(0xfffec900)
-#define MPUI_CTRL			(MPUI_BASE + 0x0)
-#define MPUI_DEBUG_ADDR			(MPUI_BASE + 0x4)
-#define MPUI_DEBUG_DATA			(MPUI_BASE + 0x8)
-#define MPUI_DEBUG_FLAG			(MPUI_BASE + 0xc)
-#define MPUI_STATUS_REG			(MPUI_BASE + 0x10)
-#define MPUI_DSP_STATUS			(MPUI_BASE + 0x14)
-#define MPUI_DSP_BOOT_CONFIG		(MPUI_BASE + 0x18)
-#define MPUI_DSP_API_CONFIG		(MPUI_BASE + 0x1c)
-
-/*
- * ----------------------------------------------------------------------------
- * LED Pulse Generator
- * ----------------------------------------------------------------------------
- */
-#define OMAP_LPG1_BASE			0xfffbd000
-#define OMAP_LPG2_BASE			0xfffbd800
-#define OMAP_LPG1_LCR			(OMAP_LPG1_BASE + 0x00)
-#define OMAP_LPG1_PMR			(OMAP_LPG1_BASE + 0x04)
-#define OMAP_LPG2_LCR			(OMAP_LPG2_BASE + 0x00)
-#define OMAP_LPG2_PMR			(OMAP_LPG2_BASE + 0x04)
-
-/*
- * ----------------------------------------------------------------------------
- * Pulse-Width Light
- * ----------------------------------------------------------------------------
- */
-#define OMAP_PWL_BASE			0xfffb5800
-#define OMAP_PWL_ENABLE			(OMAP_PWL_BASE + 0x00)
-#define OMAP_PWL_CLK_ENABLE		(OMAP_PWL_BASE + 0x04)
-
-/*
- * ---------------------------------------------------------------------------
- * Processor specific defines
- * ---------------------------------------------------------------------------
- */
-
-#include "omap730.h"
-#include "omap1510.h"
-#include "omap16xx.h"
-#include "omap24xx.h"
-#include "omap34xx.h"
-#include "omap44xx.h"
-
-#endif	/* __ASM_ARCH_OMAP_HARDWARE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/hwa742.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/hwa742.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/hwa742.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/hwa742.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#ifndef _HWA742_H
-#define _HWA742_H
-
-struct hwa742_platform_data {
-	unsigned	te_connected:1;
-};
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/io.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,241 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/io.h
- *
- * IO definitions for TI OMAP processors and boards
- *
- * Copied from arch/arm/mach-sa1100/include/mach/io.h
- * Copyright (C) 1997-1999 Russell King
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - 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 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.
- *
- * Modifications:
- *  06-12-1997	RMK	Created.
- *  07-04-1999	RMK	Major cleanup
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <mach/hardware.h>
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * We don't actually have real ISA nor PCI buses, but there is so many
- * drivers out there that might just work if we fake them...
- */
-#define __io(a)		__typesafe_io(a)
-#define __mem_pci(a)	(a)
-
-/*
- * ----------------------------------------------------------------------------
- * I/O mapping
- * ----------------------------------------------------------------------------
- */
-
-#ifdef __ASSEMBLER__
-#define IOMEM(x)		(x)
-#else
-#define IOMEM(x)		((void __force __iomem *)(x))
-#endif
-
-#define OMAP1_IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
-#define OMAP1_IO_ADDRESS(pa)	IOMEM((pa) - OMAP1_IO_OFFSET)
-
-#define OMAP2_IO_OFFSET		0x90000000
-#define OMAP2_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_IO_OFFSET) /* L3 and L4 */
-
-/*
- * ----------------------------------------------------------------------------
- * Omap1 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-#define OMAP1_IO_PHYS		0xFFFB0000
-#define OMAP1_IO_SIZE		0x40000
-#define OMAP1_IO_VIRT		(OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
-
-/*
- * ----------------------------------------------------------------------------
- * Omap2 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP2 */
-#define L3_24XX_PHYS	L3_24XX_BASE	/* 0x68000000 */
-#define L3_24XX_VIRT	0xf8000000
-#define L3_24XX_SIZE	SZ_1M		/* 44kB of 128MB used, want 1MB sect */
-#define L4_24XX_PHYS	L4_24XX_BASE	/* 0x48000000 */
-#define L4_24XX_VIRT	0xd8000000
-#define L4_24XX_SIZE	SZ_1M		/* 1MB of 128MB used, want 1MB sect */
-
-#define L4_WK_243X_PHYS		L4_WK_243X_BASE		/* 0x49000000 */
-#define L4_WK_243X_VIRT		0xd9000000
-#define L4_WK_243X_SIZE		SZ_1M
-#define OMAP243X_GPMC_PHYS	OMAP243X_GPMC_BASE	/* 0x49000000 */
-#define OMAP243X_GPMC_VIRT	0xFE000000
-#define OMAP243X_GPMC_SIZE	SZ_1M
-#define OMAP243X_SDRC_PHYS	OMAP243X_SDRC_BASE
-#define OMAP243X_SDRC_VIRT	0xFD000000
-#define OMAP243X_SDRC_SIZE	SZ_1M
-#define OMAP243X_SMS_PHYS	OMAP243X_SMS_BASE
-#define OMAP243X_SMS_VIRT	0xFC000000
-#define OMAP243X_SMS_SIZE	SZ_1M
-
-/* DSP */
-#define DSP_MEM_24XX_PHYS	OMAP2420_DSP_MEM_BASE	/* 0x58000000 */
-#define DSP_MEM_24XX_VIRT	0xe0000000
-#define DSP_MEM_24XX_SIZE	0x28000
-#define DSP_IPI_24XX_PHYS	OMAP2420_DSP_IPI_BASE	/* 0x59000000 */
-#define DSP_IPI_24XX_VIRT	0xe1000000
-#define DSP_IPI_24XX_SIZE	SZ_4K
-#define DSP_MMU_24XX_PHYS	OMAP2420_DSP_MMU_BASE	/* 0x5a000000 */
-#define DSP_MMU_24XX_VIRT	0xe2000000
-#define DSP_MMU_24XX_SIZE	SZ_4K
-
-/*
- * ----------------------------------------------------------------------------
- * Omap3 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP3 */
-#define L3_34XX_PHYS		L3_34XX_BASE	/* 0x68000000 */
-#define L3_34XX_VIRT		0xf8000000
-#define L3_34XX_SIZE		SZ_1M   /* 44kB of 128MB used, want 1MB sect */
-
-#define L4_34XX_PHYS		L4_34XX_BASE	/* 0x48000000 */
-#define L4_34XX_VIRT		0xd8000000
-#define L4_34XX_SIZE		SZ_4M   /* 1MB of 128MB used, want 1MB sect */
-
-/*
- * Need to look at the Size 4M for L4.
- * VPOM3430 was not working for Int controller
- */
-
-#define L4_WK_34XX_PHYS		L4_WK_34XX_BASE /* 0x48300000 */
-#define L4_WK_34XX_VIRT		0xd8300000
-#define L4_WK_34XX_SIZE		SZ_1M
-
-#define L4_PER_34XX_PHYS	L4_PER_34XX_BASE /* 0x49000000 */
-#define L4_PER_34XX_VIRT	0xd9000000
-#define L4_PER_34XX_SIZE	SZ_1M
-
-#define L4_EMU_34XX_PHYS	L4_EMU_34XX_BASE /* 0x54000000 */
-#define L4_EMU_34XX_VIRT	0xe4000000
-#define L4_EMU_34XX_SIZE	SZ_64M
-
-#define OMAP34XX_GPMC_PHYS	OMAP34XX_GPMC_BASE /* 0x6E000000 */
-#define OMAP34XX_GPMC_VIRT	0xFE000000
-#define OMAP34XX_GPMC_SIZE	SZ_1M
-
-#define OMAP343X_SMS_PHYS	OMAP343X_SMS_BASE /* 0x6C000000 */
-#define OMAP343X_SMS_VIRT	0xFC000000
-#define OMAP343X_SMS_SIZE	SZ_1M
-
-#define OMAP343X_SDRC_PHYS	OMAP343X_SDRC_BASE /* 0x6D000000 */
-#define OMAP343X_SDRC_VIRT	0xFD000000
-#define OMAP343X_SDRC_SIZE	SZ_1M
-
-/* DSP */
-#define DSP_MEM_34XX_PHYS	OMAP34XX_DSP_MEM_BASE	/* 0x58000000 */
-#define DSP_MEM_34XX_VIRT	0xe0000000
-#define DSP_MEM_34XX_SIZE	0x28000
-#define DSP_IPI_34XX_PHYS	OMAP34XX_DSP_IPI_BASE	/* 0x59000000 */
-#define DSP_IPI_34XX_VIRT	0xe1000000
-#define DSP_IPI_34XX_SIZE	SZ_4K
-#define DSP_MMU_34XX_PHYS	OMAP34XX_DSP_MMU_BASE	/* 0x5a000000 */
-#define DSP_MMU_34XX_VIRT	0xe2000000
-#define DSP_MMU_34XX_SIZE	SZ_4K
-
-/*
- * ----------------------------------------------------------------------------
- * Omap4 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP4 */
-#define L3_44XX_PHYS		L3_44XX_BASE
-#define L3_44XX_VIRT		0xd4000000
-#define L3_44XX_SIZE		SZ_1M
-
-#define L4_44XX_PHYS		L4_44XX_BASE
-#define L4_44XX_VIRT		0xda000000
-#define L4_44XX_SIZE		SZ_4M
-
-
-#define L4_WK_44XX_PHYS		L4_WK_44XX_BASE
-#define L4_WK_44XX_VIRT		0xda300000
-#define L4_WK_44XX_SIZE		SZ_1M
-
-#define L4_PER_44XX_PHYS	L4_PER_44XX_BASE
-#define L4_PER_44XX_VIRT	0xd8000000
-#define L4_PER_44XX_SIZE	SZ_4M
-
-#define L4_EMU_44XX_PHYS	L4_EMU_44XX_BASE
-#define L4_EMU_44XX_VIRT	0xe4000000
-#define L4_EMU_44XX_SIZE	SZ_64M
-
-#define OMAP44XX_GPMC_PHYS	OMAP44XX_GPMC_BASE
-#define OMAP44XX_GPMC_VIRT	0xe0000000
-#define OMAP44XX_GPMC_SIZE	SZ_1M
-
-
-/*
- * ----------------------------------------------------------------------------
- * Omap specific register access
- * ----------------------------------------------------------------------------
- */
-
-#ifndef __ASSEMBLER__
-
-/*
- * NOTE: Please use ioremap + __raw_read/write where possible instead of these
- */
-
-extern u8 omap_readb(u32 pa);
-extern u16 omap_readw(u32 pa);
-extern u32 omap_readl(u32 pa);
-extern void omap_writeb(u8 v, u32 pa);
-extern void omap_writew(u16 v, u32 pa);
-extern void omap_writel(u32 v, u32 pa);
-
-struct omap_sdrc_params;
-
-extern void omap1_map_common_io(void);
-extern void omap1_init_common_hw(void);
-
-extern void omap2_map_common_io(void);
-extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
-				 struct omap_sdrc_params *sdrc_cs1);
-
-#define __arch_ioremap(p,s,t)	omap_ioremap(p,s,t)
-#define __arch_iounmap(v)	omap_iounmap(v)
-
-void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
-void omap_iounmap(volatile void __iomem *addr);
-
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iommu2.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iommu2.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iommu2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iommu2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/*
- * omap iommu: omap2 architecture specific definitions
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by 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.
- */
-
-#ifndef __MACH_IOMMU2_H
-#define __MACH_IOMMU2_H
-
-#include <linux/io.h>
-
-/*
- * MMU Register offsets
- */
-#define MMU_REVISION		0x00
-#define MMU_SYSCONFIG		0x10
-#define MMU_SYSSTATUS		0x14
-#define MMU_IRQSTATUS		0x18
-#define MMU_IRQENABLE		0x1c
-#define MMU_WALKING_ST		0x40
-#define MMU_CNTL		0x44
-#define MMU_FAULT_AD		0x48
-#define MMU_TTB			0x4c
-#define MMU_LOCK		0x50
-#define MMU_LD_TLB		0x54
-#define MMU_CAM			0x58
-#define MMU_RAM			0x5c
-#define MMU_GFLUSH		0x60
-#define MMU_FLUSH_ENTRY		0x64
-#define MMU_READ_CAM		0x68
-#define MMU_READ_RAM		0x6c
-#define MMU_EMU_FAULT_AD	0x70
-
-#define MMU_REG_SIZE		256
-
-/*
- * MMU Register bit definitions
- */
-#define MMU_LOCK_BASE_SHIFT	10
-#define MMU_LOCK_BASE_MASK	(0x1f << MMU_LOCK_BASE_SHIFT)
-#define MMU_LOCK_BASE(x)	\
-	((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
-
-#define MMU_LOCK_VICT_SHIFT	4
-#define MMU_LOCK_VICT_MASK	(0x1f << MMU_LOCK_VICT_SHIFT)
-#define MMU_LOCK_VICT(x)	\
-	((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
-
-#define MMU_CAM_VATAG_SHIFT	12
-#define MMU_CAM_VATAG_MASK \
-	((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
-#define MMU_CAM_P		(1 << 3)
-#define MMU_CAM_V		(1 << 2)
-#define MMU_CAM_PGSZ_MASK	3
-#define MMU_CAM_PGSZ_1M		(0 << 0)
-#define MMU_CAM_PGSZ_64K	(1 << 0)
-#define MMU_CAM_PGSZ_4K		(2 << 0)
-#define MMU_CAM_PGSZ_16M	(3 << 0)
-
-#define MMU_RAM_PADDR_SHIFT	12
-#define MMU_RAM_PADDR_MASK \
-	((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
-#define MMU_RAM_ENDIAN_SHIFT	9
-#define MMU_RAM_ENDIAN_MASK	(1 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ENDIAN_BIG	(1 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ENDIAN_LITTLE	(0 << MMU_RAM_ENDIAN_SHIFT)
-#define MMU_RAM_ELSZ_SHIFT	7
-#define MMU_RAM_ELSZ_MASK	(3 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_8		(0 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_16		(1 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_32		(2 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_ELSZ_NONE	(3 << MMU_RAM_ELSZ_SHIFT)
-#define MMU_RAM_MIXED_SHIFT	6
-#define MMU_RAM_MIXED_MASK	(1 << MMU_RAM_MIXED_SHIFT)
-#define MMU_RAM_MIXED		MMU_RAM_MIXED_MASK
-
-/*
- * register accessors
- */
-static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
-{
-	return __raw_readl(obj->regbase + offs);
-}
-
-static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
-{
-	__raw_writel(val, obj->regbase + offs);
-}
-
-#endif /* __MACH_IOMMU2_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iommu.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iommu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iommu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iommu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,168 +0,0 @@
-/*
- * omap iommu: main structures
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by 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.
- */
-
-#ifndef __MACH_IOMMU_H
-#define __MACH_IOMMU_H
-
-struct iotlb_entry {
-	u32 da;
-	u32 pa;
-	u32 pgsz, prsvd, valid;
-	union {
-		u16 ap;
-		struct {
-			u32 endian, elsz, mixed;
-		};
-	};
-};
-
-struct iommu {
-	const char	*name;
-	struct module	*owner;
-	struct clk	*clk;
-	void __iomem	*regbase;
-	struct device	*dev;
-
-	unsigned int	refcount;
-	struct mutex	iommu_lock;	/* global for this whole object */
-
-	/*
-	 * We don't change iopgd for a situation like pgd for a task,
-	 * but share it globally for each iommu.
-	 */
-	u32		*iopgd;
-	spinlock_t	page_table_lock; /* protect iopgd */
-
-	int		nr_tlb_entries;
-
-	struct list_head	mmap;
-	struct mutex		mmap_lock; /* protect mmap */
-
-	int (*isr)(struct iommu *obj);
-
-	void *ctx; /* iommu context: registres saved area */
-};
-
-struct cr_regs {
-	union {
-		struct {
-			u16 cam_l;
-			u16 cam_h;
-		};
-		u32 cam;
-	};
-	union {
-		struct {
-			u16 ram_l;
-			u16 ram_h;
-		};
-		u32 ram;
-	};
-};
-
-struct iotlb_lock {
-	short base;
-	short vict;
-};
-
-/* architecture specific functions */
-struct iommu_functions {
-	unsigned long	version;
-
-	int (*enable)(struct iommu *obj);
-	void (*disable)(struct iommu *obj);
-	u32 (*fault_isr)(struct iommu *obj, u32 *ra);
-
-	void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
-	void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
-
-	struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e);
-	int (*cr_valid)(struct cr_regs *cr);
-	u32 (*cr_to_virt)(struct cr_regs *cr);
-	void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e);
-	ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf);
-
-	u32 (*get_pte_attr)(struct iotlb_entry *e);
-
-	void (*save_ctx)(struct iommu *obj);
-	void (*restore_ctx)(struct iommu *obj);
-	ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len);
-};
-
-struct iommu_platform_data {
-	const char *name;
-	const char *clk_name;
-	const int nr_tlb_entries;
-};
-
-#if defined(CONFIG_ARCH_OMAP1)
-#error "iommu for this processor not implemented yet"
-#else
-#include <mach/iommu2.h>
-#endif
-
-/*
- * utilities for super page(16MB, 1MB, 64KB and 4KB)
- */
-
-#define iopgsz_max(bytes)			\
-	(((bytes) >= SZ_16M) ? SZ_16M :		\
-	 ((bytes) >= SZ_1M)  ? SZ_1M  :		\
-	 ((bytes) >= SZ_64K) ? SZ_64K :		\
-	 ((bytes) >= SZ_4K)  ? SZ_4K  :	0)
-
-#define bytes_to_iopgsz(bytes)				\
-	(((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M :	\
-	 ((bytes) == SZ_1M)  ? MMU_CAM_PGSZ_1M  :	\
-	 ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K :	\
-	 ((bytes) == SZ_4K)  ? MMU_CAM_PGSZ_4K  : -1)
-
-#define iopgsz_to_bytes(iopgsz)				\
-	(((iopgsz) == MMU_CAM_PGSZ_16M)	? SZ_16M :	\
-	 ((iopgsz) == MMU_CAM_PGSZ_1M)	? SZ_1M  :	\
-	 ((iopgsz) == MMU_CAM_PGSZ_64K)	? SZ_64K :	\
-	 ((iopgsz) == MMU_CAM_PGSZ_4K)	? SZ_4K  : 0)
-
-#define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
-
-/*
- * global functions
- */
-extern u32 iommu_arch_version(void);
-
-extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
-extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
-
-extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
-extern void flush_iotlb_page(struct iommu *obj, u32 da);
-extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
-extern void flush_iotlb_all(struct iommu *obj);
-
-extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
-extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
-
-extern struct iommu *iommu_get(const char *name);
-extern void iommu_put(struct iommu *obj);
-
-extern void iommu_save_ctx(struct iommu *obj);
-extern void iommu_restore_ctx(struct iommu *obj);
-
-extern int install_iommu_arch(const struct iommu_functions *ops);
-extern void uninstall_iommu_arch(const struct iommu_functions *ops);
-
-extern int foreach_iommu_device(void *data,
-				int (*fn)(struct device *, void *));
-
-extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len);
-extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len);
-
-#endif /* __MACH_IOMMU_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iovmm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iovmm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/iovmm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/iovmm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-/*
- * omap iommu: simple virtual address space management
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by 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.
- */
-
-#ifndef __IOMMU_MMAP_H
-#define __IOMMU_MMAP_H
-
-struct iovm_struct {
-	struct iommu		*iommu;	/* iommu object which this belongs to */
-	u32			da_start; /* area definition */
-	u32			da_end;
-	u32			flags; /* IOVMF_: see below */
-	struct list_head	list; /* linked in ascending order */
-	const struct sg_table	*sgt; /* keep 'page' <-> 'da' mapping */
-	void			*va; /* mpu side mapped address */
-};
-
-/*
- * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
- *
- * lower 16 bit is used for h/w and upper 16 bit is for s/w.
- */
-#define IOVMF_SW_SHIFT		16
-#define IOVMF_HW_SIZE		(1 << IOVMF_SW_SHIFT)
-#define IOVMF_HW_MASK		(IOVMF_HW_SIZE - 1)
-#define IOVMF_SW_MASK		(~IOVMF_HW_MASK)UL
-
-/*
- * iovma: h/w flags derived from cam and ram attribute
- */
-#define IOVMF_CAM_MASK		(~((1 << 10) - 1))
-#define IOVMF_RAM_MASK		(~IOVMF_CAM_MASK)
-
-#define IOVMF_PGSZ_MASK		(3 << 0)
-#define IOVMF_PGSZ_1M		MMU_CAM_PGSZ_1M
-#define IOVMF_PGSZ_64K		MMU_CAM_PGSZ_64K
-#define IOVMF_PGSZ_4K		MMU_CAM_PGSZ_4K
-#define IOVMF_PGSZ_16M		MMU_CAM_PGSZ_16M
-
-#define IOVMF_ENDIAN_MASK	(1 << 9)
-#define IOVMF_ENDIAN_BIG	MMU_RAM_ENDIAN_BIG
-#define IOVMF_ENDIAN_LITTLE	MMU_RAM_ENDIAN_LITTLE
-
-#define IOVMF_ELSZ_MASK		(3 << 7)
-#define IOVMF_ELSZ_8		MMU_RAM_ELSZ_8
-#define IOVMF_ELSZ_16		MMU_RAM_ELSZ_16
-#define IOVMF_ELSZ_32		MMU_RAM_ELSZ_32
-#define IOVMF_ELSZ_NONE		MMU_RAM_ELSZ_NONE
-
-#define IOVMF_MIXED_MASK	(1 << 6)
-#define IOVMF_MIXED		MMU_RAM_MIXED
-
-/*
- * iovma: s/w flags, used for mapping and umapping internally.
- */
-#define IOVMF_MMIO		(1 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC		(2 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC_MASK	(3 << IOVMF_SW_SHIFT)
-
-/* "superpages" is supported just with physically linear pages */
-#define IOVMF_DISCONT		(1 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR		(2 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR_MASK	(3 << (2 + IOVMF_SW_SHIFT))
-
-#define IOVMF_DA_FIXED		(1 << (4 + IOVMF_SW_SHIFT))
-#define IOVMF_DA_ANON		(2 << (4 + IOVMF_SW_SHIFT))
-#define IOVMF_DA_MASK		(3 << (4 + IOVMF_SW_SHIFT))
-
-
-extern struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da);
-extern u32 iommu_vmap(struct iommu *obj, u32 da,
-			const struct sg_table *sgt, u32 flags);
-extern struct sg_table *iommu_vunmap(struct iommu *obj, u32 da);
-extern u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes,
-			   u32 flags);
-extern void iommu_vfree(struct iommu *obj, const u32 da);
-extern u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
-			u32 flags);
-extern void iommu_kunmap(struct iommu *obj, u32 da);
-extern u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes,
-			   u32 flags);
-extern void iommu_kfree(struct iommu *obj, u32 da);
-
-extern void *da_to_va(struct iommu *obj, u32 da);
-
-#endif /* __IOMMU_MMAP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/irda.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/irda.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/irda.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/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 linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/irqs.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,568 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/irqs.h
- *
- *  Copyright (C) Greg Lonnon 2001
- *  Updated for OMAP-1610 by Tony Lindgren <tony@atomide.com>
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - 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 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
- *
- * NOTE: The interrupt vectors for the OMAP-1509, OMAP-1510, and OMAP-1610
- *	 are different.
- */
-
-#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
-#define __ASM_ARCH_OMAP15XX_IRQS_H
-
-/*
- * IRQ numbers for interrupt handler 1
- *
- * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
- *
- */
-#define INT_CAMERA		1
-#define INT_FIQ			3
-#define INT_RTDX		6
-#define INT_DSP_MMU_ABORT	7
-#define INT_HOST		8
-#define INT_ABORT		9
-#define INT_BRIDGE_PRIV		13
-#define INT_GPIO_BANK1		14
-#define INT_UART3		15
-#define INT_TIMER3		16
-#define INT_DMA_CH0_6		19
-#define INT_DMA_CH1_7		20
-#define INT_DMA_CH2_8		21
-#define INT_DMA_CH3		22
-#define INT_DMA_CH4		23
-#define INT_DMA_CH5		24
-#define INT_DMA_LCD		25
-#define INT_TIMER1		26
-#define INT_WD_TIMER		27
-#define INT_BRIDGE_PUB		28
-#define INT_TIMER2		30
-#define INT_LCD_CTRL		31
-
-/*
- * OMAP-1510 specific IRQ numbers for interrupt handler 1
- */
-#define INT_1510_IH2_IRQ	0
-#define INT_1510_RES2		2
-#define INT_1510_SPI_TX		4
-#define INT_1510_SPI_RX		5
-#define INT_1510_DSP_MAILBOX1	10
-#define INT_1510_DSP_MAILBOX2	11
-#define INT_1510_RES12		12
-#define INT_1510_LB_MMU		17
-#define INT_1510_RES18		18
-#define INT_1510_LOCAL_BUS	29
-
-/*
- * OMAP-1610 specific IRQ numbers for interrupt handler 1
- */
-#define INT_1610_IH2_IRQ	0
-#define INT_1610_IH2_FIQ	2
-#define INT_1610_McBSP2_TX	4
-#define INT_1610_McBSP2_RX	5
-#define INT_1610_DSP_MAILBOX1	10
-#define INT_1610_DSP_MAILBOX2	11
-#define INT_1610_LCD_LINE	12
-#define INT_1610_GPTIMER1	17
-#define INT_1610_GPTIMER2	18
-#define INT_1610_SSR_FIFO_0	29
-
-/*
- * OMAP-730 specific IRQ numbers for interrupt handler 1
- */
-#define INT_730_IH2_FIQ		0
-#define INT_730_IH2_IRQ		1
-#define INT_730_USB_NON_ISO	2
-#define INT_730_USB_ISO		3
-#define INT_730_ICR		4
-#define INT_730_EAC		5
-#define INT_730_GPIO_BANK1	6
-#define INT_730_GPIO_BANK2	7
-#define INT_730_GPIO_BANK3	8
-#define INT_730_McBSP2TX	10
-#define INT_730_McBSP2RX	11
-#define INT_730_McBSP2RX_OVF	12
-#define INT_730_LCD_LINE	14
-#define INT_730_GSM_PROTECT	15
-#define INT_730_TIMER3		16
-#define INT_730_GPIO_BANK5	17
-#define INT_730_GPIO_BANK6	18
-#define INT_730_SPGIO_WR	29
-
-/*
- * OMAP-850 specific IRQ numbers for interrupt handler 1
- */
-#define INT_850_IH2_FIQ		0
-#define INT_850_IH2_IRQ		1
-#define INT_850_USB_NON_ISO	2
-#define INT_850_USB_ISO		3
-#define INT_850_ICR		4
-#define INT_850_EAC		5
-#define INT_850_GPIO_BANK1	6
-#define INT_850_GPIO_BANK2	7
-#define INT_850_GPIO_BANK3	8
-#define INT_850_McBSP2TX	10
-#define INT_850_McBSP2RX	11
-#define INT_850_McBSP2RX_OVF	12
-#define INT_850_LCD_LINE	14
-#define INT_850_GSM_PROTECT	15
-#define INT_850_TIMER3		16
-#define INT_850_GPIO_BANK5	17
-#define INT_850_GPIO_BANK6	18
-#define INT_850_SPGIO_WR	29
-
-
-/*
- * IRQ numbers for interrupt handler 2
- *
- * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
- */
-#define IH2_BASE		32
-
-#define INT_KEYBOARD		(1 + IH2_BASE)
-#define INT_uWireTX		(2 + IH2_BASE)
-#define INT_uWireRX		(3 + IH2_BASE)
-#define INT_I2C			(4 + IH2_BASE)
-#define INT_MPUIO		(5 + IH2_BASE)
-#define INT_USB_HHC_1		(6 + IH2_BASE)
-#define INT_McBSP3TX		(10 + IH2_BASE)
-#define INT_McBSP3RX		(11 + IH2_BASE)
-#define INT_McBSP1TX		(12 + IH2_BASE)
-#define INT_McBSP1RX		(13 + IH2_BASE)
-#define INT_UART1		(14 + IH2_BASE)
-#define INT_UART2		(15 + IH2_BASE)
-#define INT_BT_MCSI1TX		(16 + IH2_BASE)
-#define INT_BT_MCSI1RX		(17 + IH2_BASE)
-#define INT_SOSSI_MATCH		(19 + IH2_BASE)
-#define INT_USB_W2FC		(20 + IH2_BASE)
-#define INT_1WIRE		(21 + IH2_BASE)
-#define INT_OS_TIMER		(22 + IH2_BASE)
-#define INT_MMC			(23 + IH2_BASE)
-#define INT_GAUGE_32K		(24 + IH2_BASE)
-#define INT_RTC_TIMER		(25 + IH2_BASE)
-#define INT_RTC_ALARM		(26 + IH2_BASE)
-#define INT_MEM_STICK		(27 + IH2_BASE)
-
-/*
- * OMAP-1510 specific IRQ numbers for interrupt handler 2
- */
-#define INT_1510_DSP_MMU	(28 + IH2_BASE)
-#define INT_1510_COM_SPI_RO	(31 + IH2_BASE)
-
-/*
- * OMAP-1610 specific IRQ numbers for interrupt handler 2
- */
-#define INT_1610_FAC		(0 + IH2_BASE)
-#define INT_1610_USB_HHC_2	(7 + IH2_BASE)
-#define INT_1610_USB_OTG	(8 + IH2_BASE)
-#define INT_1610_SoSSI		(9 + IH2_BASE)
-#define INT_1610_SoSSI_MATCH	(19 + IH2_BASE)
-#define INT_1610_DSP_MMU	(28 + IH2_BASE)
-#define INT_1610_McBSP2RX_OF	(31 + IH2_BASE)
-#define INT_1610_STI		(32 + IH2_BASE)
-#define INT_1610_STI_WAKEUP	(33 + IH2_BASE)
-#define INT_1610_GPTIMER3	(34 + IH2_BASE)
-#define INT_1610_GPTIMER4	(35 + IH2_BASE)
-#define INT_1610_GPTIMER5	(36 + IH2_BASE)
-#define INT_1610_GPTIMER6	(37 + IH2_BASE)
-#define INT_1610_GPTIMER7	(38 + IH2_BASE)
-#define INT_1610_GPTIMER8	(39 + IH2_BASE)
-#define INT_1610_GPIO_BANK2	(40 + IH2_BASE)
-#define INT_1610_GPIO_BANK3	(41 + IH2_BASE)
-#define INT_1610_MMC2		(42 + IH2_BASE)
-#define INT_1610_CF		(43 + IH2_BASE)
-#define INT_1610_WAKE_UP_REQ	(46 + IH2_BASE)
-#define INT_1610_GPIO_BANK4	(48 + IH2_BASE)
-#define INT_1610_SPI		(49 + IH2_BASE)
-#define INT_1610_DMA_CH6	(53 + IH2_BASE)
-#define INT_1610_DMA_CH7	(54 + IH2_BASE)
-#define INT_1610_DMA_CH8	(55 + IH2_BASE)
-#define INT_1610_DMA_CH9	(56 + IH2_BASE)
-#define INT_1610_DMA_CH10	(57 + IH2_BASE)
-#define INT_1610_DMA_CH11	(58 + IH2_BASE)
-#define INT_1610_DMA_CH12	(59 + IH2_BASE)
-#define INT_1610_DMA_CH13	(60 + IH2_BASE)
-#define INT_1610_DMA_CH14	(61 + IH2_BASE)
-#define INT_1610_DMA_CH15	(62 + IH2_BASE)
-#define INT_1610_NAND		(63 + IH2_BASE)
-#define INT_1610_SHA1MD5	(91 + IH2_BASE)
-
-/*
- * OMAP-730 specific IRQ numbers for interrupt handler 2
- */
-#define INT_730_HW_ERRORS	(0 + IH2_BASE)
-#define INT_730_NFIQ_PWR_FAIL	(1 + IH2_BASE)
-#define INT_730_CFCD		(2 + IH2_BASE)
-#define INT_730_CFIREQ		(3 + IH2_BASE)
-#define INT_730_I2C		(4 + IH2_BASE)
-#define INT_730_PCC		(5 + IH2_BASE)
-#define INT_730_MPU_EXT_NIRQ	(6 + IH2_BASE)
-#define INT_730_SPI_100K_1	(7 + IH2_BASE)
-#define INT_730_SYREN_SPI	(8 + IH2_BASE)
-#define INT_730_VLYNQ		(9 + IH2_BASE)
-#define INT_730_GPIO_BANK4	(10 + IH2_BASE)
-#define INT_730_McBSP1TX	(11 + IH2_BASE)
-#define INT_730_McBSP1RX	(12 + IH2_BASE)
-#define INT_730_McBSP1RX_OF	(13 + IH2_BASE)
-#define INT_730_UART_MODEM_IRDA_2 (14 + IH2_BASE)
-#define INT_730_UART_MODEM_1	(15 + IH2_BASE)
-#define INT_730_MCSI		(16 + IH2_BASE)
-#define INT_730_uWireTX		(17 + IH2_BASE)
-#define INT_730_uWireRX		(18 + IH2_BASE)
-#define INT_730_SMC_CD		(19 + IH2_BASE)
-#define INT_730_SMC_IREQ	(20 + IH2_BASE)
-#define INT_730_HDQ_1WIRE	(21 + IH2_BASE)
-#define INT_730_TIMER32K	(22 + IH2_BASE)
-#define INT_730_MMC_SDIO	(23 + IH2_BASE)
-#define INT_730_UPLD		(24 + IH2_BASE)
-#define INT_730_USB_HHC_1	(27 + IH2_BASE)
-#define INT_730_USB_HHC_2	(28 + IH2_BASE)
-#define INT_730_USB_GENI	(29 + IH2_BASE)
-#define INT_730_USB_OTG		(30 + IH2_BASE)
-#define INT_730_CAMERA_IF	(31 + IH2_BASE)
-#define INT_730_RNG		(32 + IH2_BASE)
-#define INT_730_DUAL_MODE_TIMER (33 + IH2_BASE)
-#define INT_730_DBB_RF_EN	(34 + IH2_BASE)
-#define INT_730_MPUIO_KEYPAD	(35 + IH2_BASE)
-#define INT_730_SHA1_MD5	(36 + IH2_BASE)
-#define INT_730_SPI_100K_2	(37 + IH2_BASE)
-#define INT_730_RNG_IDLE	(38 + IH2_BASE)
-#define INT_730_MPUIO		(39 + IH2_BASE)
-#define INT_730_LLPC_LCD_CTRL_CAN_BE_OFF	(40 + IH2_BASE)
-#define INT_730_LLPC_OE_FALLING (41 + IH2_BASE)
-#define INT_730_LLPC_OE_RISING	(42 + IH2_BASE)
-#define INT_730_LLPC_VSYNC	(43 + IH2_BASE)
-#define INT_730_WAKE_UP_REQ	(46 + IH2_BASE)
-#define INT_730_DMA_CH6		(53 + IH2_BASE)
-#define INT_730_DMA_CH7		(54 + IH2_BASE)
-#define INT_730_DMA_CH8		(55 + IH2_BASE)
-#define INT_730_DMA_CH9		(56 + IH2_BASE)
-#define INT_730_DMA_CH10	(57 + IH2_BASE)
-#define INT_730_DMA_CH11	(58 + IH2_BASE)
-#define INT_730_DMA_CH12	(59 + IH2_BASE)
-#define INT_730_DMA_CH13	(60 + IH2_BASE)
-#define INT_730_DMA_CH14	(61 + IH2_BASE)
-#define INT_730_DMA_CH15	(62 + IH2_BASE)
-#define INT_730_NAND		(63 + IH2_BASE)
-
-/*
- * OMAP-850 specific IRQ numbers for interrupt handler 2
- */
-#define INT_850_HW_ERRORS	(0 + IH2_BASE)
-#define INT_850_NFIQ_PWR_FAIL	(1 + IH2_BASE)
-#define INT_850_CFCD		(2 + IH2_BASE)
-#define INT_850_CFIREQ		(3 + IH2_BASE)
-#define INT_850_I2C		(4 + IH2_BASE)
-#define INT_850_PCC		(5 + IH2_BASE)
-#define INT_850_MPU_EXT_NIRQ	(6 + IH2_BASE)
-#define INT_850_SPI_100K_1	(7 + IH2_BASE)
-#define INT_850_SYREN_SPI	(8 + IH2_BASE)
-#define INT_850_VLYNQ		(9 + IH2_BASE)
-#define INT_850_GPIO_BANK4	(10 + IH2_BASE)
-#define INT_850_McBSP1TX	(11 + IH2_BASE)
-#define INT_850_McBSP1RX	(12 + IH2_BASE)
-#define INT_850_McBSP1RX_OF	(13 + IH2_BASE)
-#define INT_850_UART_MODEM_IRDA_2 (14 + IH2_BASE)
-#define INT_850_UART_MODEM_1	(15 + IH2_BASE)
-#define INT_850_MCSI		(16 + IH2_BASE)
-#define INT_850_uWireTX		(17 + IH2_BASE)
-#define INT_850_uWireRX		(18 + IH2_BASE)
-#define INT_850_SMC_CD		(19 + IH2_BASE)
-#define INT_850_SMC_IREQ	(20 + IH2_BASE)
-#define INT_850_HDQ_1WIRE	(21 + IH2_BASE)
-#define INT_850_TIMER32K	(22 + IH2_BASE)
-#define INT_850_MMC_SDIO	(23 + IH2_BASE)
-#define INT_850_UPLD		(24 + IH2_BASE)
-#define INT_850_USB_HHC_1	(27 + IH2_BASE)
-#define INT_850_USB_HHC_2	(28 + IH2_BASE)
-#define INT_850_USB_GENI	(29 + IH2_BASE)
-#define INT_850_USB_OTG		(30 + IH2_BASE)
-#define INT_850_CAMERA_IF	(31 + IH2_BASE)
-#define INT_850_RNG		(32 + IH2_BASE)
-#define INT_850_DUAL_MODE_TIMER (33 + IH2_BASE)
-#define INT_850_DBB_RF_EN	(34 + IH2_BASE)
-#define INT_850_MPUIO_KEYPAD	(35 + IH2_BASE)
-#define INT_850_SHA1_MD5	(36 + IH2_BASE)
-#define INT_850_SPI_100K_2	(37 + IH2_BASE)
-#define INT_850_RNG_IDLE	(38 + IH2_BASE)
-#define INT_850_MPUIO		(39 + IH2_BASE)
-#define INT_850_LLPC_LCD_CTRL_CAN_BE_OFF	(40 + IH2_BASE)
-#define INT_850_LLPC_OE_FALLING (41 + IH2_BASE)
-#define INT_850_LLPC_OE_RISING	(42 + IH2_BASE)
-#define INT_850_LLPC_VSYNC	(43 + IH2_BASE)
-#define INT_850_WAKE_UP_REQ	(46 + IH2_BASE)
-#define INT_850_DMA_CH6		(53 + IH2_BASE)
-#define INT_850_DMA_CH7		(54 + IH2_BASE)
-#define INT_850_DMA_CH8		(55 + IH2_BASE)
-#define INT_850_DMA_CH9		(56 + IH2_BASE)
-#define INT_850_DMA_CH10	(57 + IH2_BASE)
-#define INT_850_DMA_CH11	(58 + IH2_BASE)
-#define INT_850_DMA_CH12	(59 + IH2_BASE)
-#define INT_850_DMA_CH13	(60 + IH2_BASE)
-#define INT_850_DMA_CH14	(61 + IH2_BASE)
-#define INT_850_DMA_CH15	(62 + IH2_BASE)
-#define INT_850_NAND		(63 + IH2_BASE)
-
-#define INT_24XX_SYS_NIRQ	7
-#define INT_24XX_SDMA_IRQ0	12
-#define INT_24XX_SDMA_IRQ1	13
-#define INT_24XX_SDMA_IRQ2	14
-#define INT_24XX_SDMA_IRQ3	15
-#define INT_24XX_CAM_IRQ	24
-#define INT_24XX_DSS_IRQ	25
-#define INT_24XX_MAIL_U0_MPU	26
-#define INT_24XX_DSP_UMA	27
-#define INT_24XX_DSP_MMU	28
-#define INT_24XX_GPIO_BANK1	29
-#define INT_24XX_GPIO_BANK2	30
-#define INT_24XX_GPIO_BANK3	31
-#define INT_24XX_GPIO_BANK4	32
-#define INT_24XX_GPIO_BANK5	33
-#define INT_24XX_MAIL_U3_MPU	34
-#define INT_24XX_GPTIMER1	37
-#define INT_24XX_GPTIMER2	38
-#define INT_24XX_GPTIMER3	39
-#define INT_24XX_GPTIMER4	40
-#define INT_24XX_GPTIMER5	41
-#define INT_24XX_GPTIMER6	42
-#define INT_24XX_GPTIMER7	43
-#define INT_24XX_GPTIMER8	44
-#define INT_24XX_GPTIMER9	45
-#define INT_24XX_GPTIMER10	46
-#define INT_24XX_GPTIMER11	47
-#define INT_24XX_GPTIMER12	48
-#define INT_24XX_SHA1MD5	51
-#define INT_24XX_MCBSP4_IRQ_TX	54
-#define INT_24XX_MCBSP4_IRQ_RX	55
-#define INT_24XX_I2C1_IRQ	56
-#define INT_24XX_I2C2_IRQ	57
-#define INT_24XX_HDQ_IRQ	58
-#define INT_24XX_MCBSP1_IRQ_TX	59
-#define INT_24XX_MCBSP1_IRQ_RX	60
-#define INT_24XX_MCBSP2_IRQ_TX	62
-#define INT_24XX_MCBSP2_IRQ_RX	63
-#define INT_24XX_SPI1_IRQ	65
-#define INT_24XX_SPI2_IRQ	66
-#define INT_24XX_UART1_IRQ	72
-#define INT_24XX_UART2_IRQ	73
-#define INT_24XX_UART3_IRQ	74
-#define INT_24XX_USB_IRQ_GEN	75
-#define INT_24XX_USB_IRQ_NISO	76
-#define INT_24XX_USB_IRQ_ISO	77
-#define INT_24XX_USB_IRQ_HGEN	78
-#define INT_24XX_USB_IRQ_HSOF	79
-#define INT_24XX_USB_IRQ_OTG	80
-#define INT_24XX_MCBSP5_IRQ_TX	81
-#define INT_24XX_MCBSP5_IRQ_RX	82
-#define INT_24XX_MMC_IRQ	83
-#define INT_24XX_MMC2_IRQ	86
-#define INT_24XX_MCBSP3_IRQ_TX	89
-#define INT_24XX_MCBSP3_IRQ_RX	90
-#define INT_24XX_SPI3_IRQ	91
-
-#define INT_243X_MCBSP2_IRQ	16
-#define INT_243X_MCBSP3_IRQ	17
-#define INT_243X_MCBSP4_IRQ	18
-#define INT_243X_MCBSP5_IRQ	19
-#define INT_243X_MCBSP1_IRQ	64
-#define INT_243X_HS_USB_MC	92
-#define INT_243X_HS_USB_DMA	93
-#define INT_243X_CARKIT_IRQ	94
-
-#define INT_34XX_BENCH_MPU_EMUL	3
-#define INT_34XX_ST_MCBSP2_IRQ	4
-#define INT_34XX_ST_MCBSP3_IRQ	5
-#define INT_34XX_SSM_ABORT_IRQ	6
-#define INT_34XX_SYS_NIRQ	7
-#define INT_34XX_D2D_FW_IRQ	8
-#define INT_34XX_PRCM_MPU_IRQ	11
-#define INT_34XX_MCBSP1_IRQ	16
-#define INT_34XX_MCBSP2_IRQ	17
-#define INT_34XX_MCBSP3_IRQ	22
-#define INT_34XX_MCBSP4_IRQ	23
-#define INT_34XX_CAM_IRQ	24
-#define INT_34XX_MCBSP5_IRQ	27
-#define INT_34XX_GPIO_BANK1	29
-#define INT_34XX_GPIO_BANK2	30
-#define INT_34XX_GPIO_BANK3	31
-#define INT_34XX_GPIO_BANK4	32
-#define INT_34XX_GPIO_BANK5	33
-#define INT_34XX_GPIO_BANK6	34
-#define INT_34XX_USIM_IRQ	35
-#define INT_34XX_WDT3_IRQ	36
-#define INT_34XX_SPI4_IRQ	48
-#define INT_34XX_SHA1MD52_IRQ	49
-#define INT_34XX_FPKA_READY_IRQ	50
-#define INT_34XX_SHA1MD51_IRQ	51
-#define INT_34XX_RNG_IRQ	52
-#define INT_34XX_I2C3_IRQ	61
-#define INT_34XX_FPKA_ERROR_IRQ	64
-#define INT_34XX_PBIAS_IRQ	75
-#define INT_34XX_OHCI_IRQ	76
-#define INT_34XX_EHCI_IRQ	77
-#define INT_34XX_TLL_IRQ	78
-#define INT_34XX_PARTHASH_IRQ	79
-#define INT_34XX_MMC3_IRQ	94
-#define INT_34XX_GPT12_IRQ	95
-
-#define	INT_34XX_BENCH_MPU_EMUL	3
-
-
-#define IRQ_GIC_START		32
-#define INT_44XX_LOCALTIMER_IRQ	29
-#define INT_44XX_LOCALWDT_IRQ	30
-
-#define INT_44XX_BENCH_MPU_EMUL	(3 + IRQ_GIC_START)
-#define INT_44XX_SSM_ABORT_IRQ	(6 + IRQ_GIC_START)
-#define INT_44XX_SYS_NIRQ	(7 + IRQ_GIC_START)
-#define INT_44XX_D2D_FW_IRQ	(8 + IRQ_GIC_START)
-#define INT_44XX_PRCM_MPU_IRQ	(11 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ0	(12 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ1	(13 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ2	(14 + IRQ_GIC_START)
-#define INT_44XX_SDMA_IRQ3	(15 + IRQ_GIC_START)
-#define INT_44XX_ISS_IRQ	(24 + IRQ_GIC_START)
-#define INT_44XX_DSS_IRQ	(25 + IRQ_GIC_START)
-#define INT_44XX_MAIL_U0_MPU	(26 + IRQ_GIC_START)
-#define INT_44XX_DSP_MMU	(28 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER1	(37 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER2	(38 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER3	(39 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER4	(40 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER5	(41 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER6	(42 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER7	(43 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER8	(44 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER9	(45 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER10	(46 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER11	(47 + IRQ_GIC_START)
-#define INT_44XX_GPTIMER12	(95 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD5	(51 + IRQ_GIC_START)
-#define INT_44XX_I2C1_IRQ	(56 + IRQ_GIC_START)
-#define INT_44XX_I2C2_IRQ	(57 + IRQ_GIC_START)
-#define INT_44XX_HDQ_IRQ	(58 + IRQ_GIC_START)
-#define INT_44XX_SPI1_IRQ	(65 + IRQ_GIC_START)
-#define INT_44XX_SPI2_IRQ	(66 + IRQ_GIC_START)
-#define INT_44XX_HSI_1_IRQ0	(67 + IRQ_GIC_START)
-#define INT_44XX_HSI_2_IRQ1	(68 + IRQ_GIC_START)
-#define INT_44XX_HSI_1_DMAIRQ	(71 + IRQ_GIC_START)
-#define INT_44XX_UART1_IRQ	(72 + IRQ_GIC_START)
-#define INT_44XX_UART2_IRQ	(73 + IRQ_GIC_START)
-#define INT_44XX_UART3_IRQ	(74 + IRQ_GIC_START)
-#define INT_44XX_UART4_IRQ	(70 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_NISO	(76 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_ISO	(77 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_HGEN	(78 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_HSOF	(79 + IRQ_GIC_START)
-#define INT_44XX_USB_IRQ_OTG	(80 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ_TX	(81 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ_RX	(82 + IRQ_GIC_START)
-#define INT_44XX_MMC_IRQ	(83 + IRQ_GIC_START)
-#define INT_44XX_MMC2_IRQ	(86 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ_TX	(89 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ_RX	(90 + IRQ_GIC_START)
-#define INT_44XX_SPI3_IRQ	(91 + IRQ_GIC_START)
-#define INT_44XX_SPI5_IRQ	(69 + IRQ_GIC_START)
-
-#define INT_44XX_MCBSP5_IRQ	(16 + IRQ_GIC_START)
-#define INT_44xX_MCBSP1_IRQ	(17 + IRQ_GIC_START)
-#define INT_44XX_MCBSP2_IRQ	(22 + IRQ_GIC_START)
-#define INT_44XX_MCBSP3_IRQ	(23 + IRQ_GIC_START)
-#define INT_44XX_MCBSP4_IRQ	(27 + IRQ_GIC_START)
-#define INT_44XX_HS_USB_MC	(92 + IRQ_GIC_START)
-#define INT_44XX_HS_USB_DMA	(93 + IRQ_GIC_START)
-
-#define INT_44XX_GPIO_BANK1	(29 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK2	(30 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK3	(31 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK4	(32 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK5	(33 + IRQ_GIC_START)
-#define INT_44XX_GPIO_BANK6	(34 + IRQ_GIC_START)
-#define INT_44XX_USIM_IRQ	(35 + IRQ_GIC_START)
-#define INT_44XX_WDT3_IRQ	(36 + IRQ_GIC_START)
-#define INT_44XX_SPI4_IRQ	(48 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD52_IRQ	(49 + IRQ_GIC_START)
-#define INT_44XX_FPKA_READY_IRQ	(50 + IRQ_GIC_START)
-#define INT_44XX_SHA1MD51_IRQ	(51 + IRQ_GIC_START)
-#define INT_44XX_RNG_IRQ	(52 + IRQ_GIC_START)
-#define INT_44XX_MMC5_IRQ	(59 + IRQ_GIC_START)
-#define INT_44XX_I2C3_IRQ	(61 + IRQ_GIC_START)
-#define INT_44XX_FPKA_ERROR_IRQ	(64 + IRQ_GIC_START)
-#define INT_44XX_PBIAS_IRQ	(75 + IRQ_GIC_START)
-#define INT_44XX_OHCI_IRQ	(76 + IRQ_GIC_START)
-#define INT_44XX_EHCI_IRQ	(77 + IRQ_GIC_START)
-#define INT_44XX_TLL_IRQ	(78 + IRQ_GIC_START)
-#define INT_44XX_PARTHASH_IRQ	(79 + IRQ_GIC_START)
-#define INT_44XX_MMC3_IRQ	(94 + IRQ_GIC_START)
-#define INT_44XX_MMC4_IRQ	(96 + IRQ_GIC_START)
-
-
-/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
- * 16 MPUIO lines */
-#define OMAP_MAX_GPIO_LINES	192
-#define IH_GPIO_BASE		(128 + IH2_BASE)
-#define IH_MPUIO_BASE		(OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
-#define OMAP_IRQ_END		(IH_MPUIO_BASE + 16)
-
-/* External FPGA handles interrupts on Innovator boards */
-#define	OMAP_FPGA_IRQ_BASE	(OMAP_IRQ_END)
-#ifdef	CONFIG_MACH_OMAP_INNOVATOR
-#define OMAP_FPGA_NR_IRQS	24
-#else
-#define OMAP_FPGA_NR_IRQS	0
-#endif
-#define OMAP_FPGA_IRQ_END	(OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
-
-/* External TWL4030 can handle interrupts on 2430 and 34xx boards */
-#define	TWL4030_IRQ_BASE	(OMAP_FPGA_IRQ_END)
-#ifdef	CONFIG_TWL4030_CORE
-#define	TWL4030_BASE_NR_IRQS	8
-#define	TWL4030_PWR_NR_IRQS	8
-#else
-#define	TWL4030_BASE_NR_IRQS	0
-#define	TWL4030_PWR_NR_IRQS	0
-#endif
-#define TWL4030_IRQ_END		(TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS)
-#define TWL4030_PWR_IRQ_BASE	TWL4030_IRQ_END
-#define	TWL4030_PWR_IRQ_END	(TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS)
-
-/* External TWL4030 gpio interrupts are optional */
-#define TWL4030_GPIO_IRQ_BASE	TWL4030_PWR_IRQ_END
-#ifdef	CONFIG_GPIO_TWL4030
-#define TWL4030_GPIO_NR_IRQS	18
-#else
-#define	TWL4030_GPIO_NR_IRQS	0
-#endif
-#define TWL4030_GPIO_IRQ_END	(TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
-
-/* Total number of interrupts depends on the enabled blocks above */
-#define NR_IRQS			TWL4030_GPIO_IRQ_END
-
-#define OMAP_IRQ_BIT(irq)	(1 << ((irq) % 32))
-
-#ifndef __ASSEMBLY__
-extern void omap_init_irq(void);
-extern int omap_irq_pending(void);
-#endif
-
-#include <mach/hardware.h>
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/keypad.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/keypad.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/keypad.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/keypad.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/keypad.h
- *
- *  Copyright (C) 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_KEYPAD_H
-#define ASMARM_ARCH_KEYPAD_H
-
-#warning: Please update the board to use matrix_keypad.h instead
-
-struct omap_kp_platform_data {
-	int rows;
-	int cols;
-	int *keymap;
-	unsigned int keymapsize;
-	unsigned int rep:1;
-	unsigned long delay;
-	unsigned int dbounce:1;
-	/* specific to OMAP242x*/
-	unsigned int *row_gpios;
-	unsigned int *col_gpios;
-};
-
-/* Group (0..3) -- when multiple keys are pressed, only the
- * keys pressed in the same group are considered as pressed. This is
- * in order to workaround certain crappy HW designs that produce ghost
- * keypresses. */
-#define GROUP_0		(0 << 16)
-#define GROUP_1		(1 << 16)
-#define GROUP_2		(2 << 16)
-#define GROUP_3		(3 << 16)
-#define GROUP_MASK	GROUP_3
-
-#define KEY_PERSISTENT		0x00800000
-#define KEYNUM_MASK		0x00EFFFFF
-#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
-#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
-						KEY_PERSISTENT)
-
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/lcd_mipid.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/lcd_mipid.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/lcd_mipid.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/lcd_mipid.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-#ifndef __LCD_MIPID_H
-#define __LCD_MIPID_H
-
-enum mipid_test_num {
-	MIPID_TEST_RGB_LINES,
-};
-
-enum mipid_test_result {
-	MIPID_TEST_SUCCESS,
-	MIPID_TEST_INVALID,
-	MIPID_TEST_FAILED,
-};
-
-#ifdef __KERNEL__
-
-struct mipid_platform_data {
-	int	nreset_gpio;
-	int	data_lines;
-
-	void	(*shutdown)(struct mipid_platform_data *pdata);
-	void	(*set_bklight_level)(struct mipid_platform_data *pdata,
-				     int level);
-	int	(*get_bklight_level)(struct mipid_platform_data *pdata);
-	int	(*get_bklight_max)(struct mipid_platform_data *pdata);
-};
-
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/led.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/led.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/led.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/led.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/led.h
- *
- *  Copyright (C) 2006 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@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.
- */
-#ifndef ASMARM_ARCH_LED_H
-#define ASMARM_ARCH_LED_H
-
-struct omap_led_config {
-	struct led_classdev	cdev;
-	s16			gpio;
-};
-
-struct omap_led_platform_data {
-	s16			nr_leds;
-	struct omap_led_config	*leds;
-};
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mailbox.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mailbox.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mailbox.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mailbox.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/* mailbox.h */
-
-#ifndef MAILBOX_H
-#define MAILBOX_H
-
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/blkdev.h>
-
-typedef u32 mbox_msg_t;
-typedef void (mbox_receiver_t)(mbox_msg_t msg);
-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 request_queue	*queue;
-	struct work_struct	work;
-	int	(*callback)(void *);
-	struct omap_mbox	*mbox;
-};
-
-struct omap_mbox {
-	char			*name;
-	unsigned int		irq;
-
-	struct omap_mbox_queue	*txq, *rxq;
-
-	struct omap_mbox_ops	*ops;
-
-	mbox_msg_t		seq_snd, seq_rcv;
-
-	struct device		*dev;
-
-	struct omap_mbox	*next;
-	void			*priv;
-
-	void			(*err_notify)(void);
-};
-
-int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg, void *);
-void omap_mbox_init_seq(struct omap_mbox *);
-
-struct omap_mbox *omap_mbox_get(const char *);
-void omap_mbox_put(struct omap_mbox *);
-
-int omap_mbox_register(struct device *parent, struct omap_mbox *);
-int omap_mbox_unregister(struct omap_mbox *);
-
-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);
-}
-
-#endif /* MAILBOX_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,462 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/mcbsp.h
- *
- * Defines for Multi-Channel Buffered Serial Port
- *
- * Copyright (C) 2002 RidgeRun, Inc.
- * Author: Steve Johnson
- *
- * 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_OMAP_MCBSP_H
-#define __ASM_ARCH_OMAP_MCBSP_H
-
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-
-#include <mach/hardware.h>
-#include <mach/clock.h>
-
-#define OMAP730_MCBSP1_BASE	0xfffb1000
-#define OMAP730_MCBSP2_BASE	0xfffb1800
-
-#define OMAP1510_MCBSP1_BASE	0xe1011800
-#define OMAP1510_MCBSP2_BASE	0xfffb1000
-#define OMAP1510_MCBSP3_BASE	0xe1017000
-
-#define OMAP1610_MCBSP1_BASE	0xe1011800
-#define OMAP1610_MCBSP2_BASE	0xfffb1000
-#define OMAP1610_MCBSP3_BASE	0xe1017000
-
-#define OMAP24XX_MCBSP1_BASE	0x48074000
-#define OMAP24XX_MCBSP2_BASE	0x48076000
-#define OMAP2430_MCBSP3_BASE	0x4808c000
-#define OMAP2430_MCBSP4_BASE	0x4808e000
-#define OMAP2430_MCBSP5_BASE	0x48096000
-
-#define OMAP34XX_MCBSP1_BASE	0x48074000
-#define OMAP34XX_MCBSP2_BASE	0x49022000
-#define OMAP34XX_MCBSP3_BASE	0x49024000
-#define OMAP34XX_MCBSP4_BASE	0x49026000
-#define OMAP34XX_MCBSP5_BASE	0x48096000
-
-#define OMAP44XX_MCBSP1_BASE	0x49022000
-#define OMAP44XX_MCBSP2_BASE	0x49024000
-#define OMAP44XX_MCBSP3_BASE	0x49026000
-#define OMAP44XX_MCBSP4_BASE	0x48074000
-
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
-
-#define OMAP_MCBSP_REG_DRR2	0x00
-#define OMAP_MCBSP_REG_DRR1	0x02
-#define OMAP_MCBSP_REG_DXR2	0x04
-#define OMAP_MCBSP_REG_DXR1	0x06
-#define OMAP_MCBSP_REG_SPCR2	0x08
-#define OMAP_MCBSP_REG_SPCR1	0x0a
-#define OMAP_MCBSP_REG_RCR2	0x0c
-#define OMAP_MCBSP_REG_RCR1	0x0e
-#define OMAP_MCBSP_REG_XCR2	0x10
-#define OMAP_MCBSP_REG_XCR1	0x12
-#define OMAP_MCBSP_REG_SRGR2	0x14
-#define OMAP_MCBSP_REG_SRGR1	0x16
-#define OMAP_MCBSP_REG_MCR2	0x18
-#define OMAP_MCBSP_REG_MCR1	0x1a
-#define OMAP_MCBSP_REG_RCERA	0x1c
-#define OMAP_MCBSP_REG_RCERB	0x1e
-#define OMAP_MCBSP_REG_XCERA	0x20
-#define OMAP_MCBSP_REG_XCERB	0x22
-#define OMAP_MCBSP_REG_PCR0	0x24
-#define OMAP_MCBSP_REG_RCERC	0x26
-#define OMAP_MCBSP_REG_RCERD	0x28
-#define OMAP_MCBSP_REG_XCERC	0x2A
-#define OMAP_MCBSP_REG_XCERD	0x2C
-#define OMAP_MCBSP_REG_RCERE	0x2E
-#define OMAP_MCBSP_REG_RCERF	0x30
-#define OMAP_MCBSP_REG_XCERE	0x32
-#define OMAP_MCBSP_REG_XCERF	0x34
-#define OMAP_MCBSP_REG_RCERG	0x36
-#define OMAP_MCBSP_REG_RCERH	0x38
-#define OMAP_MCBSP_REG_XCERG	0x3A
-#define OMAP_MCBSP_REG_XCERH	0x3C
-
-/* Dummy defines, these are not available on omap1 */
-#define OMAP_MCBSP_REG_XCCR	0x00
-#define OMAP_MCBSP_REG_RCCR	0x00
-
-#define AUDIO_MCBSP_DATAWRITE	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
-#define AUDIO_MCBSP_DATAREAD	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
-
-#define AUDIO_MCBSP		OMAP_MCBSP1
-#define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
-#define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
-
-#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-	defined(CONFIG_ARCH_OMAP4)
-
-#define OMAP_MCBSP_REG_DRR2	0x00
-#define OMAP_MCBSP_REG_DRR1	0x04
-#define OMAP_MCBSP_REG_DXR2	0x08
-#define OMAP_MCBSP_REG_DXR1	0x0C
-#define OMAP_MCBSP_REG_DRR	0x00
-#define OMAP_MCBSP_REG_DXR	0x08
-#define OMAP_MCBSP_REG_SPCR2	0x10
-#define OMAP_MCBSP_REG_SPCR1	0x14
-#define OMAP_MCBSP_REG_RCR2	0x18
-#define OMAP_MCBSP_REG_RCR1	0x1C
-#define OMAP_MCBSP_REG_XCR2	0x20
-#define OMAP_MCBSP_REG_XCR1	0x24
-#define OMAP_MCBSP_REG_SRGR2	0x28
-#define OMAP_MCBSP_REG_SRGR1	0x2C
-#define OMAP_MCBSP_REG_MCR2	0x30
-#define OMAP_MCBSP_REG_MCR1	0x34
-#define OMAP_MCBSP_REG_RCERA	0x38
-#define OMAP_MCBSP_REG_RCERB	0x3C
-#define OMAP_MCBSP_REG_XCERA	0x40
-#define OMAP_MCBSP_REG_XCERB	0x44
-#define OMAP_MCBSP_REG_PCR0	0x48
-#define OMAP_MCBSP_REG_RCERC	0x4C
-#define OMAP_MCBSP_REG_RCERD	0x50
-#define OMAP_MCBSP_REG_XCERC	0x54
-#define OMAP_MCBSP_REG_XCERD	0x58
-#define OMAP_MCBSP_REG_RCERE	0x5C
-#define OMAP_MCBSP_REG_RCERF	0x60
-#define OMAP_MCBSP_REG_XCERE	0x64
-#define OMAP_MCBSP_REG_XCERF	0x68
-#define OMAP_MCBSP_REG_RCERG	0x6C
-#define OMAP_MCBSP_REG_RCERH	0x70
-#define OMAP_MCBSP_REG_XCERG	0x74
-#define OMAP_MCBSP_REG_XCERH	0x78
-#define OMAP_MCBSP_REG_SYSCON	0x8C
-#define OMAP_MCBSP_REG_THRSH2	0x90
-#define OMAP_MCBSP_REG_THRSH1	0x94
-#define OMAP_MCBSP_REG_IRQST	0xA0
-#define OMAP_MCBSP_REG_IRQEN	0xA4
-#define OMAP_MCBSP_REG_WAKEUPEN	0xA8
-#define OMAP_MCBSP_REG_XCCR	0xAC
-#define OMAP_MCBSP_REG_RCCR	0xB0
-
-#define AUDIO_MCBSP_DATAWRITE	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
-#define AUDIO_MCBSP_DATAREAD	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
-
-#define AUDIO_MCBSP		OMAP_MCBSP2
-#define AUDIO_DMA_TX		OMAP24XX_DMA_MCBSP2_TX
-#define AUDIO_DMA_RX		OMAP24XX_DMA_MCBSP2_RX
-
-#endif
-
-/************************** McBSP SPCR1 bit definitions ***********************/
-#define RRST			0x0001
-#define RRDY			0x0002
-#define RFULL			0x0004
-#define RSYNC_ERR		0x0008
-#define RINTM(value)		((value)<<4)	/* bits 4:5 */
-#define ABIS			0x0040
-#define DXENA			0x0080
-#define CLKSTP(value)		((value)<<11)	/* bits 11:12 */
-#define RJUST(value)		((value)<<13)	/* bits 13:14 */
-#define ALB			0x8000
-#define DLB			0x8000
-
-/************************** McBSP SPCR2 bit definitions ***********************/
-#define XRST		0x0001
-#define XRDY		0x0002
-#define XEMPTY		0x0004
-#define XSYNC_ERR	0x0008
-#define XINTM(value)	((value)<<4)		/* bits 4:5 */
-#define GRST		0x0040
-#define FRST		0x0080
-#define SOFT		0x0100
-#define FREE		0x0200
-
-/************************** McBSP PCR bit definitions *************************/
-#define CLKRP		0x0001
-#define CLKXP		0x0002
-#define FSRP		0x0004
-#define FSXP		0x0008
-#define DR_STAT		0x0010
-#define DX_STAT		0x0020
-#define CLKS_STAT	0x0040
-#define SCLKME		0x0080
-#define CLKRM		0x0100
-#define CLKXM		0x0200
-#define FSRM		0x0400
-#define FSXM		0x0800
-#define RIOEN		0x1000
-#define XIOEN		0x2000
-#define IDLE_EN		0x4000
-
-/************************** McBSP RCR1 bit definitions ************************/
-#define RWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
-#define RFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
-
-/************************** McBSP XCR1 bit definitions ************************/
-#define XWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
-#define XFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
-
-/*************************** McBSP RCR2 bit definitions ***********************/
-#define RDATDLY(value)		(value)		/* Bits 0:1 */
-#define RFIG			0x0004
-#define RCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
-#define RWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
-#define RFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
-#define RPHASE			0x8000
-
-/*************************** McBSP XCR2 bit definitions ***********************/
-#define XDATDLY(value)		(value)		/* Bits 0:1 */
-#define XFIG			0x0004
-#define XCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
-#define XWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
-#define XFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
-#define XPHASE			0x8000
-
-/************************* McBSP SRGR1 bit definitions ************************/
-#define CLKGDV(value)		(value)		/* Bits 0:7 */
-#define FWID(value)		((value)<<8)	/* Bits 8:15 */
-
-/************************* McBSP SRGR2 bit definitions ************************/
-#define FPER(value)		(value)		/* Bits 0:11 */
-#define FSGM			0x1000
-#define CLKSM			0x2000
-#define CLKSP			0x4000
-#define GSYNC			0x8000
-
-/************************* McBSP MCR1 bit definitions *************************/
-#define RMCM			0x0001
-#define RCBLK(value)		((value)<<2)	/* Bits 2:4 */
-#define RPABLK(value)		((value)<<5)	/* Bits 5:6 */
-#define RPBBLK(value)		((value)<<7)	/* Bits 7:8 */
-
-/************************* McBSP MCR2 bit definitions *************************/
-#define XMCM(value)		(value)		/* Bits 0:1 */
-#define XCBLK(value)		((value)<<2)	/* Bits 2:4 */
-#define XPABLK(value)		((value)<<5)	/* Bits 5:6 */
-#define XPBBLK(value)		((value)<<7)	/* Bits 7:8 */
-
-/*********************** McBSP XCCR bit definitions *************************/
-#define EXTCLKGATE		0x8000
-#define PPCONNECT		0x4000
-#define DXENDLY(value)		((value)<<12)	/* Bits 12:13 */
-#define XFULL_CYCLE		0x0800
-#define DILB			0x0020
-#define XDMAEN			0x0008
-#define XDISABLE		0x0001
-
-/********************** McBSP RCCR bit definitions *************************/
-#define RFULL_CYCLE		0x0800
-#define RDMAEN			0x0008
-#define RDISABLE		0x0001
-
-/********************** McBSP SYSCONFIG bit definitions ********************/
-#define CLOCKACTIVITY(value)	((value)<<8)
-#define SIDLEMODE(value)	((value)<<3)
-#define ENAWAKEUP		0x0004
-#define SOFTRST			0x0002
-
-/********************** McBSP DMA operating modes **************************/
-#define MCBSP_DMA_MODE_ELEMENT		0
-#define MCBSP_DMA_MODE_THRESHOLD	1
-#define MCBSP_DMA_MODE_FRAME		2
-
-/********************** McBSP WAKEUPEN bit definitions *********************/
-#define XEMPTYEOFEN		0x4000
-#define XRDYEN			0x0400
-#define XEOFEN			0x0200
-#define XFSXEN			0x0100
-#define XSYNCERREN		0x0080
-#define RRDYEN			0x0008
-#define REOFEN			0x0004
-#define RFSREN			0x0002
-#define RSYNCERREN		0x0001
-
-/* we don't do multichannel for now */
-struct omap_mcbsp_reg_cfg {
-	u16 spcr2;
-	u16 spcr1;
-	u16 rcr2;
-	u16 rcr1;
-	u16 xcr2;
-	u16 xcr1;
-	u16 srgr2;
-	u16 srgr1;
-	u16 mcr2;
-	u16 mcr1;
-	u16 pcr0;
-	u16 rcerc;
-	u16 rcerd;
-	u16 xcerc;
-	u16 xcerd;
-	u16 rcere;
-	u16 rcerf;
-	u16 xcere;
-	u16 xcerf;
-	u16 rcerg;
-	u16 rcerh;
-	u16 xcerg;
-	u16 xcerh;
-	u16 xccr;
-	u16 rccr;
-};
-
-typedef enum {
-	OMAP_MCBSP1 = 0,
-	OMAP_MCBSP2,
-	OMAP_MCBSP3,
-	OMAP_MCBSP4,
-	OMAP_MCBSP5
-} omap_mcbsp_id;
-
-typedef int __bitwise omap_mcbsp_io_type_t;
-#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
-#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
-
-typedef enum {
-	OMAP_MCBSP_WORD_8 = 0,
-	OMAP_MCBSP_WORD_12,
-	OMAP_MCBSP_WORD_16,
-	OMAP_MCBSP_WORD_20,
-	OMAP_MCBSP_WORD_24,
-	OMAP_MCBSP_WORD_32,
-} omap_mcbsp_word_length;
-
-typedef enum {
-	OMAP_MCBSP_CLK_RISING = 0,
-	OMAP_MCBSP_CLK_FALLING,
-} omap_mcbsp_clk_polarity;
-
-typedef enum {
-	OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
-	OMAP_MCBSP_FS_ACTIVE_LOW,
-} omap_mcbsp_fs_polarity;
-
-typedef enum {
-	OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
-	OMAP_MCBSP_CLK_STP_MODE_DELAY,
-} omap_mcbsp_clk_stp_mode;
-
-
-/******* SPI specific mode **********/
-typedef enum {
-	OMAP_MCBSP_SPI_MASTER = 0,
-	OMAP_MCBSP_SPI_SLAVE,
-} omap_mcbsp_spi_mode;
-
-struct omap_mcbsp_spi_cfg {
-	omap_mcbsp_spi_mode		spi_mode;
-	omap_mcbsp_clk_polarity		rx_clock_polarity;
-	omap_mcbsp_clk_polarity		tx_clock_polarity;
-	omap_mcbsp_fs_polarity		fsx_polarity;
-	u8				clk_div;
-	omap_mcbsp_clk_stp_mode		clk_stp_mode;
-	omap_mcbsp_word_length		word_length;
-};
-
-/* Platform specific configuration */
-struct omap_mcbsp_ops {
-	void (*request)(unsigned int);
-	void (*free)(unsigned int);
-};
-
-struct omap_mcbsp_platform_data {
-	unsigned long phys_base;
-	u8 dma_rx_sync, dma_tx_sync;
-	u16 rx_irq, tx_irq;
-	struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP34XX
-	u16 buffer_size;
-#endif
-};
-
-struct omap_mcbsp {
-	struct device *dev;
-	unsigned long phys_base;
-	void __iomem *io_base;
-	u8 id;
-	u8 free;
-	omap_mcbsp_word_length rx_word_length;
-	omap_mcbsp_word_length tx_word_length;
-
-	omap_mcbsp_io_type_t io_type; /* IRQ or poll */
-	/* IRQ based TX/RX */
-	int rx_irq;
-	int tx_irq;
-
-	/* DMA stuff */
-	u8 dma_rx_sync;
-	short dma_rx_lch;
-	u8 dma_tx_sync;
-	short dma_tx_lch;
-
-	/* Completion queues */
-	struct completion tx_irq_completion;
-	struct completion rx_irq_completion;
-	struct completion tx_dma_completion;
-	struct completion rx_dma_completion;
-
-	/* Protect the field .free, while checking if the mcbsp is in use */
-	spinlock_t lock;
-	struct omap_mcbsp_platform_data *pdata;
-	struct clk *iclk;
-	struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP34XX
-	int dma_op_mode;
-	u16 max_tx_thres;
-	u16 max_rx_thres;
-#endif
-};
-extern struct omap_mcbsp **mcbsp_ptr;
-extern int omap_mcbsp_count;
-
-int omap_mcbsp_init(void);
-void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
-					int size);
-void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
-#ifdef CONFIG_ARCH_OMAP34XX
-void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
-void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
-u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
-u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
-int omap_mcbsp_get_dma_op_mode(unsigned int id);
-#else
-static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
-{ }
-static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
-{ }
-static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
-static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
-static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
-#endif
-int omap_mcbsp_request(unsigned int id);
-void omap_mcbsp_free(unsigned int id);
-void omap_mcbsp_start(unsigned int id, int tx, int rx);
-void omap_mcbsp_stop(unsigned int id, int tx, int rx);
-void omap_mcbsp_xmit_word(unsigned int id, u32 word);
-u32 omap_mcbsp_recv_word(unsigned int id);
-
-int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
-int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
-int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
-int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
-
-
-/* SPI specific API */
-void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
-
-/* Polled read/write functions */
-int omap_mcbsp_pollread(unsigned int id, u16 * buf);
-int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
-int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mcspi.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mcspi.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mcspi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mcspi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,15 +0,0 @@
-#ifndef _OMAP2_MCSPI_H
-#define _OMAP2_MCSPI_H
-
-struct omap2_mcspi_platform_config {
-	unsigned short	num_cs;
-};
-
-struct omap2_mcspi_device_config {
-	unsigned turbo_mode:1;
-
-	/* Do we want one channel enabled at the same time? */
-	unsigned single_channel:1;
-};
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/memory.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/memory.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/memory.h
- *
- * Memory map for OMAP-1510 and 1610
- *
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * This file was derived from arch/arm/mach-intergrator/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 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.
- */
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset.
- */
-#if defined(CONFIG_ARCH_OMAP1)
-#define PHYS_OFFSET		UL(0x10000000)
-#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-			defined(CONFIG_ARCH_OMAP4)
-#define PHYS_OFFSET		UL(0x80000000)
-#endif
-
-/*
- * Bus address is physical address, except for OMAP-1510 Local Bus.
- * OMAP-1510 bus address is translated into a Local Bus address if the
- * OMAP bus type is lbus. We do the address translation based on the
- * device overriding the defaults used in the dma-mapping API.
- * Note that the is_lbus_device() test is not very efficient on 1510
- * because of the strncmp().
- */
-#ifdef CONFIG_ARCH_OMAP15XX
-
-/*
- * OMAP-1510 Local Bus address offset
- */
-#define OMAP1510_LB_OFFSET	UL(0x30000000)
-
-#define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
-#define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
-#define is_lbus_device(dev)	(cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
-
-#define __arch_page_to_dma(dev, page)	\
-	({ dma_addr_t __dma = page_to_phys(page); \
-	   if (is_lbus_device(dev)) \
-		__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
-	   __dma; })
-
-#define __arch_dma_to_virt(dev, addr)	({ (void *) (is_lbus_device(dev) ? \
-						lbus_to_virt(addr) : \
-						__phys_to_virt(addr)); })
-
-#define __arch_virt_to_dma(dev, addr)	({ unsigned long __addr = (unsigned long)(addr); \
-					   (dma_addr_t) (is_lbus_device(dev) ? \
-						virt_to_lbus(__addr) : \
-						__virt_to_phys(__addr)); })
-
-#endif	/* CONFIG_ARCH_OMAP15XX */
-
-/* Override the ARM default */
-#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
-
-#if (CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE == 0)
-#undef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
-#define CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE 2
-#endif
-
-#define CONSISTENT_DMA_SIZE \
-	(((CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE + 1) & ~1) * 1024 * 1024)
-
-#endif
-
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/menelaus.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/menelaus.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/menelaus.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/menelaus.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/menelaus.h
- *
- * Functions to access Menelaus power management chip
- */
-
-#ifndef __ASM_ARCH_MENELAUS_H
-#define __ASM_ARCH_MENELAUS_H
-
-struct device;
-
-struct menelaus_platform_data {
-	int (* late_init)(struct device *dev);
-};
-
-extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
-					  void *data);
-extern void menelaus_unregister_mmc_callback(void);
-extern int menelaus_set_mmc_opendrain(int slot, int enable);
-extern int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_on);
-
-extern int menelaus_set_vmem(unsigned int mV);
-extern int menelaus_set_vio(unsigned int mV);
-extern int menelaus_set_vmmc(unsigned int mV);
-extern int menelaus_set_vaux(unsigned int mV);
-extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
-extern int menelaus_set_slot_sel(int enable);
-extern int menelaus_get_slot_pin_states(void);
-extern int menelaus_set_vcore_sw(unsigned int mV);
-extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
-
-#define EN_VPLL_SLEEP	(1 << 7)
-#define EN_VMMC_SLEEP	(1 << 6)
-#define EN_VAUX_SLEEP	(1 << 5)
-#define EN_VIO_SLEEP	(1 << 4)
-#define EN_VMEM_SLEEP	(1 << 3)
-#define EN_DC3_SLEEP	(1 << 2)
-#define EN_DC2_SLEEP	(1 << 1)
-#define EN_VC_SLEEP	(1 << 0)
-
-extern int menelaus_set_regulator_sleep(int enable, u32 val);
-
-#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
-#define omap_has_menelaus()	1
-#else
-#define omap_has_menelaus()	0
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mmc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mmc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mmc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mmc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,157 +0,0 @@
-/*
- * MMC definitions for OMAP2
- *
- * Copyright (C) 2006 Nokia 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 __OMAP2_MMC_H
-#define __OMAP2_MMC_H
-
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/board.h>
-
-#define OMAP15XX_NR_MMC		1
-#define OMAP16XX_NR_MMC		2
-#define OMAP1_MMC_SIZE		0x080
-#define OMAP1_MMC1_BASE		0xfffb7800
-#define OMAP1_MMC2_BASE		0xfffb7c00	/* omap16xx only */
-
-#define OMAP24XX_NR_MMC		2
-#define OMAP34XX_NR_MMC		3
-#define OMAP44XX_NR_MMC		5
-#define OMAP2420_MMC_SIZE	OMAP1_MMC_SIZE
-#define OMAP3_HSMMC_SIZE	0x200
-#define OMAP4_HSMMC_SIZE	0x1000
-#define OMAP2_MMC1_BASE		0x4809c000
-#define OMAP2_MMC2_BASE		0x480b4000
-#define OMAP3_MMC3_BASE		0x480ad000
-#define OMAP4_MMC4_BASE		0x480d1000
-#define OMAP4_MMC5_BASE		0x480d5000
-#define OMAP4_MMC_REG_OFFSET	0x100
-#define HSMMC5			(1 << 4)
-#define HSMMC4			(1 << 3)
-#define HSMMC3			(1 << 2)
-#define HSMMC2			(1 << 1)
-#define HSMMC1			(1 << 0)
-
-#define OMAP_MMC_MAX_SLOTS	2
-
-struct omap_mmc_platform_data {
-	/* back-link to device */
-	struct device *dev;
-
-	/* number of slots per controller */
-	unsigned nr_slots:2;
-
-	/* set if your board has components or wiring that limits the
-	 * maximum frequency on the MMC bus */
-	unsigned int max_freq;
-
-	/* switch the bus to a new slot */
-	int (* switch_slot)(struct device *dev, int slot);
-	/* initialize board-specific MMC functionality, can be NULL if
-	 * not supported */
-	int (* init)(struct device *dev);
-	void (* cleanup)(struct device *dev);
-	void (* shutdown)(struct device *dev);
-
-	/* To handle board related suspend/resume functionality for MMC */
-	int (*suspend)(struct device *dev, int slot);
-	int (*resume)(struct device *dev, int slot);
-
-	/* Return context loss count due to PM states changing */
-	int (*get_context_loss_count)(struct device *dev);
-
-	u64 dma_mask;
-
-	struct omap_mmc_slot_data {
-
-		/* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
-		 * 8 wire signaling is also optional, and is used with HSMMC
-		 */
-		u8 wires;
-
-		/*
-		 * nomux means "standard" muxing is wrong on this board, and
-		 * that board-specific code handled it before common init logic.
-		 */
-		unsigned nomux:1;
-
-		/* switch pin can be for card detect (default) or card cover */
-		unsigned cover:1;
-
-		/* use the internal clock */
-		unsigned internal_clock:1;
-
-		/* nonremovable e.g. eMMC */
-		unsigned nonremovable:1;
-
-		/* Try to sleep or power off when possible */
-		unsigned power_saving:1;
-
-		int switch_pin;			/* gpio (card detect) */
-		int gpio_wp;			/* gpio (write protect) */
-
-		int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
-		int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
-		int (* get_ro)(struct device *dev, int slot);
-		int (*set_sleep)(struct device *dev, int slot, int sleep,
-				 int vdd, int cardsleep);
-
-		/* return MMC cover switch state, can be NULL if not supported.
-		 *
-		 * possible return values:
-		 *   0 - closed
-		 *   1 - open
-		 */
-		int (* get_cover_state)(struct device *dev, int slot);
-
-		const char *name;
-		u32 ocr_mask;
-
-		/* Card detection IRQs */
-		int card_detect_irq;
-		int (* card_detect)(int irq);
-
-		unsigned int ban_openended:1;
-
-	} slots[OMAP_MMC_MAX_SLOTS];
-};
-
-/* called from board-specific card detection service routine */
-extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
-
-#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
-	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
-				int nr_controllers);
-void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
-				int nr_controllers);
-int omap_mmc_add(const char *name, int id, unsigned long base,
-				unsigned long size, unsigned int irq,
-				struct omap_mmc_platform_data *data);
-#else
-static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
-				int nr_controllers)
-{
-}
-static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
-				int nr_controllers)
-{
-}
-static inline int omap_mmc_add(const char *name, int id, unsigned long base,
-				unsigned long size, unsigned int irq,
-				struct omap_mmc_platform_data *data)
-{
-	return 0;
-}
-
-#endif
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mtd-xip.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mtd-xip.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mtd-xip.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mtd-xip.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/*
- * MTD primitives for XIP support. Architecture specific functions.
- *
- * Do not include this file directly. It's included from linux/mtd/xip.h
- *
- * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
- *
- * (c) 2005 MontaVista Software, 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.
- */
-
-#ifndef __ARCH_OMAP_MTD_XIP_H__
-#define __ARCH_OMAP_MTD_XIP_H__
-
-#include <mach/hardware.h>
-#define OMAP_MPU_TIMER_BASE	(0xfffec500)
-#define OMAP_MPU_TIMER_OFFSET	0x100
-
-typedef struct {
-	u32 cntl;			/* CNTL_TIMER, R/W */
-	u32 load_tim;			/* LOAD_TIM,   W */
-	u32 read_tim;			/* READ_TIM,   R */
-} xip_omap_mpu_timer_regs_t;
-
-#define xip_omap_mpu_timer_base(n)					\
-((volatile xip_omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
-	(n)*OMAP_MPU_TIMER_OFFSET))
-
-static inline unsigned long xip_omap_mpu_timer_read(int nr)
-{
-	volatile xip_omap_mpu_timer_regs_t* timer = xip_omap_mpu_timer_base(nr);
-	return timer->read_tim;
-}
-
-#define xip_irqpending()	\
-	(omap_readl(OMAP_IH1_ITR) & ~omap_readl(OMAP_IH1_MIR))
-#define xip_currtime()		(~xip_omap_mpu_timer_read(0))
-
-/*
- * It's permitted to do approxmation for xip_elapsed_since macro
- * (see linux/mtd/xip.h)
- */
-
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
-#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 7)
-#else
-#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 6)
-#endif
-
-/*
- * xip_cpu_idle() is used when waiting for a delay equal or larger than
- * the system timer tick period.  This should put the CPU into idle mode
- * to save power and to be woken up only when some interrupts are pending.
- * As above, this should not rely upon standard kernel code.
- */
-
-#define xip_cpu_idle()  asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (1))
-
-#endif /* __ARCH_OMAP_MTD_XIP_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mux.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mux.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/mux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/mux.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,914 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/mux.h
- *
- * Table of the Omap register configurations for the FUNC_MUX and
- * PULL_DWN combinations.
- *
- * Copyright (C) 2004 - 2008 Texas Instruments Inc.
- * Copyright (C) 2003 - 2008 Nokia Corporation
- *
- * Written by Tony Lindgren
- *
- * 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
- *
- * NOTE: Please use the following naming style for new pin entries.
- *	 For example, W8_1610_MMC2_DAT0, where:
- *	 - W8	     = ball
- *	 - 1610	     = 1510 or 1610, none if common for both 1510 and 1610
- *	 - MMC2_DAT0 = function
- */
-
-#ifndef __ASM_ARCH_MUX_H
-#define __ASM_ARCH_MUX_H
-
-#define PU_PD_SEL_NA		0	/* No pu_pd reg available */
-#define PULL_DWN_CTRL_NA	0	/* No pull-down control needed */
-
-#ifdef	CONFIG_OMAP_MUX_DEBUG
-#define MUX_REG(reg, mode_offset, mode) .mux_reg_name = "FUNC_MUX_CTRL_"#reg, \
-					.mux_reg = FUNC_MUX_CTRL_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG(reg, bit, status)	.pull_name = "PULL_DWN_CTRL_"#reg, \
-					.pull_reg = PULL_DWN_CTRL_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#define PU_PD_REG(reg, status)		.pu_pd_name = "PU_PD_SEL_"#reg, \
-					.pu_pd_reg = PU_PD_SEL_##reg, \
-					.pu_pd_val = status,
-
-#define MUX_REG_730(reg, mode_offset, mode) .mux_reg_name = "OMAP730_IO_CONF_"#reg, \
-					.mux_reg = OMAP730_IO_CONF_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG_730(reg, bit, status)	.pull_name = "OMAP730_IO_CONF_"#reg, \
-					.pull_reg = OMAP730_IO_CONF_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#define MUX_REG_850(reg, mode_offset, mode) .mux_reg_name = "OMAP850_IO_CONF_"#reg, \
-					.mux_reg = OMAP850_IO_CONF_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG_850(reg, bit, status)	.pull_name = "OMAP850_IO_CONF_"#reg, \
-					.pull_reg = OMAP850_IO_CONF_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#else
-
-#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG(reg, bit, status)	.pull_reg = PULL_DWN_CTRL_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#define PU_PD_REG(reg, status)		.pu_pd_reg = PU_PD_SEL_##reg, \
-					.pu_pd_val = status,
-
-#define MUX_REG_730(reg, mode_offset, mode) \
-					.mux_reg = OMAP730_IO_CONF_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG_730(reg, bit, status)	.pull_reg = OMAP730_IO_CONF_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#define MUX_REG_850(reg, mode_offset, mode) \
-					.mux_reg = OMAP850_IO_CONF_##reg, \
-					.mask_offset = mode_offset, \
-					.mask = mode,
-
-#define PULL_REG_850(reg, bit, status)	.pull_reg = OMAP850_IO_CONF_##reg, \
-					.pull_bit = bit, \
-					.pull_val = status,
-
-#endif /* CONFIG_OMAP_MUX_DEBUG */
-
-#define MUX_CFG(desc, mux_reg, mode_offset, mode,	\
-		pull_reg, pull_bit, pull_status,	\
-		pu_pd_reg, pu_pd_status, debug_status)	\
-{							\
-	.name =	 desc,					\
-	.debug = debug_status,				\
-	MUX_REG(mux_reg, mode_offset, mode)		\
-	PULL_REG(pull_reg, pull_bit, pull_status)	\
-	PU_PD_REG(pu_pd_reg, pu_pd_status)		\
-},
-
-
-/*
- * OMAP730/850 has a slightly different config for the pin mux.
- * - config regs are the OMAP730_IO_CONF_x regs (see omap730.h) regs and
- *   not the FUNC_MUX_CTRL_x regs from hardware.h
- * - for pull-up/down, only has one enable bit which is is in the same register
- *   as mux config
- */
-#define MUX_CFG_730(desc, mux_reg, mode_offset, mode,	\
-		   pull_bit, pull_status, debug_status)\
-{							\
-	.name =	 desc,					\
-	.debug = debug_status,				\
-	MUX_REG_730(mux_reg, mode_offset, mode)		\
-	PULL_REG_730(mux_reg, pull_bit, pull_status)	\
-	PU_PD_REG(NA, 0)		\
-},
-
-#define MUX_CFG_850(desc, mux_reg, mode_offset, mode,	\
-		   pull_bit, pull_status, debug_status)\
-{							\
-	.name =	 desc,					\
-	.debug = debug_status,				\
-	MUX_REG_850(mux_reg, mode_offset, mode)		\
-	PULL_REG_850(mux_reg, pull_bit, pull_status)	\
-	PU_PD_REG(NA, 0)		\
-},
-
-
-#define MUX_CFG_24XX(desc, reg_offset, mode,			\
-				pull_en, pull_mode, dbg)	\
-{								\
-	.name		= desc,					\
-	.debug		= dbg,					\
-	.mux_reg	= reg_offset,				\
-	.mask		= mode,					\
-	.pull_val	= pull_en,				\
-	.pu_pd_val	= pull_mode,				\
-},
-
-/* 24xx/34xx mux bit defines */
-#define OMAP2_PULL_ENA		(1 << 3)
-#define OMAP2_PULL_UP		(1 << 4)
-#define OMAP2_ALTELECTRICALSEL	(1 << 5)
-
-/* 34xx specific mux bit defines */
-#define OMAP3_INPUT_EN		(1 << 8)
-#define OMAP3_OFF_EN		(1 << 9)
-#define OMAP3_OFFOUT_EN		(1 << 10)
-#define OMAP3_OFFOUT_VAL	(1 << 11)
-#define OMAP3_OFF_PULL_EN	(1 << 12)
-#define OMAP3_OFF_PULL_UP	(1 << 13)
-#define OMAP3_WAKEUP_EN		(1 << 14)
-
-/* 34xx mux mode options for each pin. See TRM for options */
-#define	OMAP34XX_MUX_MODE0	0
-#define	OMAP34XX_MUX_MODE1	1
-#define	OMAP34XX_MUX_MODE2	2
-#define	OMAP34XX_MUX_MODE3	3
-#define	OMAP34XX_MUX_MODE4	4
-#define	OMAP34XX_MUX_MODE5	5
-#define	OMAP34XX_MUX_MODE6	6
-#define	OMAP34XX_MUX_MODE7	7
-
-/* 34xx active pin states */
-#define OMAP34XX_PIN_OUTPUT		0
-#define OMAP34XX_PIN_INPUT		OMAP3_INPUT_EN
-#define OMAP34XX_PIN_INPUT_PULLUP	(OMAP2_PULL_ENA | OMAP3_INPUT_EN \
-						| OMAP2_PULL_UP)
-#define OMAP34XX_PIN_INPUT_PULLDOWN	(OMAP2_PULL_ENA | OMAP3_INPUT_EN)
-
-/* 34xx off mode states */
-#define OMAP34XX_PIN_OFF_NONE           0
-#define OMAP34XX_PIN_OFF_OUTPUT_HIGH	(OMAP3_OFF_EN | OMAP3_OFFOUT_EN \
-						| OMAP3_OFFOUT_VAL)
-#define OMAP34XX_PIN_OFF_OUTPUT_LOW	(OMAP3_OFF_EN | OMAP3_OFFOUT_EN)
-#define OMAP34XX_PIN_OFF_INPUT_PULLUP	(OMAP3_OFF_EN | OMAP3_OFF_PULL_EN \
-						| OMAP3_OFF_PULL_UP)
-#define OMAP34XX_PIN_OFF_INPUT_PULLDOWN	(OMAP3_OFF_EN | OMAP3_OFF_PULL_EN)
-#define OMAP34XX_PIN_OFF_WAKEUPENABLE	OMAP3_WAKEUP_EN
-
-#define MUX_CFG_34XX(desc, reg_offset, mux_value) {		\
-	.name		= desc,					\
-	.debug		= 0,					\
-	.mux_reg	= reg_offset,				\
-	.mux_val	= mux_value				\
-},
-
-struct pin_config {
-	char 			*name;
-	const unsigned int 	mux_reg;
-	unsigned char		debug;
-
-#if	defined(CONFIG_ARCH_OMAP34XX)
-	u16			mux_val; /* Wake-up, off mode, pull, mux mode */
-#endif
-
-#if	defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
-	const unsigned char mask_offset;
-	const unsigned char mask;
-
-	const char *pull_name;
-	const unsigned int pull_reg;
-	const unsigned char pull_val;
-	const unsigned char pull_bit;
-
-	const char *pu_pd_name;
-	const unsigned int pu_pd_reg;
-	const unsigned char pu_pd_val;
-#endif
-
-#if	defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
-	const char *mux_reg_name;
-#endif
-
-};
-
-enum omap730_index {
-	/* OMAP 730 keyboard */
-	E2_730_KBR0,
-	J7_730_KBR1,
-	E1_730_KBR2,
-	F3_730_KBR3,
-	D2_730_KBR4,
-	C2_730_KBC0,
-	D3_730_KBC1,
-	E4_730_KBC2,
-	F4_730_KBC3,
-	E3_730_KBC4,
-
-	/* USB */
-	AA17_730_USB_DM,
-	W16_730_USB_PU_EN,
-	W17_730_USB_VBUSI,
-};
-
-enum omap850_index {
-	/* OMAP 850 keyboard */
-	E2_850_KBR0,
-	J7_850_KBR1,
-	E1_850_KBR2,
-	F3_850_KBR3,
-	D2_850_KBR4,
-	C2_850_KBC0,
-	D3_850_KBC1,
-	E4_850_KBC2,
-	F4_850_KBC3,
-	E3_850_KBC4,
-
-	/* USB */
-	AA17_850_USB_DM,
-	W16_850_USB_PU_EN,
-	W17_850_USB_VBUSI,
-};
-
-
-enum omap1xxx_index {
-	/* UART1 (BT_UART_GATING)*/
-	UART1_TX = 0,
-	UART1_RTS,
-
-	/* UART2 (COM_UART_GATING)*/
-	UART2_TX,
-	UART2_RX,
-	UART2_CTS,
-	UART2_RTS,
-
-	/* UART3 (GIGA_UART_GATING) */
-	UART3_TX,
-	UART3_RX,
-	UART3_CTS,
-	UART3_RTS,
-	UART3_CLKREQ,
-	UART3_BCLK,	/* 12MHz clock out */
-	Y15_1610_UART3_RTS,
-
-	/* PWT & PWL */
-	PWT,
-	PWL,
-
-	/* USB master generic */
-	R18_USB_VBUS,
-	R18_1510_USB_GPIO0,
-	W4_USB_PUEN,
-	W4_USB_CLKO,
-	W4_USB_HIGHZ,
-	W4_GPIO58,
-
-	/* USB1 master */
-	USB1_SUSP,
-	USB1_SEO,
-	W13_1610_USB1_SE0,
-	USB1_TXEN,
-	USB1_TXD,
-	USB1_VP,
-	USB1_VM,
-	USB1_RCV,
-	USB1_SPEED,
-	R13_1610_USB1_SPEED,
-	R13_1710_USB1_SE0,
-
-	/* USB2 master */
-	USB2_SUSP,
-	USB2_VP,
-	USB2_TXEN,
-	USB2_VM,
-	USB2_RCV,
-	USB2_SEO,
-	USB2_TXD,
-
-	/* OMAP-1510 GPIO */
-	R18_1510_GPIO0,
-	R19_1510_GPIO1,
-	M14_1510_GPIO2,
-
-	/* OMAP1610 GPIO */
-	P18_1610_GPIO3,
-	Y15_1610_GPIO17,
-
-	/* OMAP-1710 GPIO */
-	R18_1710_GPIO0,
-	V2_1710_GPIO10,
-	N21_1710_GPIO14,
-	W15_1710_GPIO40,
-
-	/* MPUIO */
-	MPUIO2,
-	N15_1610_MPUIO2,
-	MPUIO4,
-	MPUIO5,
-	T20_1610_MPUIO5,
-	W11_1610_MPUIO6,
-	V10_1610_MPUIO7,
-	W11_1610_MPUIO9,
-	V10_1610_MPUIO10,
-	W10_1610_MPUIO11,
-	E20_1610_MPUIO13,
-	U20_1610_MPUIO14,
-	E19_1610_MPUIO15,
-
-	/* MCBSP2 */
-	MCBSP2_CLKR,
-	MCBSP2_CLKX,
-	MCBSP2_DR,
-	MCBSP2_DX,
-	MCBSP2_FSR,
-	MCBSP2_FSX,
-
-	/* MCBSP3 */
-	MCBSP3_CLKX,
-
-	/* Misc ballouts */
-	BALLOUT_V8_ARMIO3,
-	N20_HDQ,
-
-	/* OMAP-1610 MMC2 */
-	W8_1610_MMC2_DAT0,
-	V8_1610_MMC2_DAT1,
-	W15_1610_MMC2_DAT2,
-	R10_1610_MMC2_DAT3,
-	Y10_1610_MMC2_CLK,
-	Y8_1610_MMC2_CMD,
-	V9_1610_MMC2_CMDDIR,
-	V5_1610_MMC2_DATDIR0,
-	W19_1610_MMC2_DATDIR1,
-	R18_1610_MMC2_CLKIN,
-
-	/* OMAP-1610 External Trace Interface */
-	M19_1610_ETM_PSTAT0,
-	L15_1610_ETM_PSTAT1,
-	L18_1610_ETM_PSTAT2,
-	L19_1610_ETM_D0,
-	J19_1610_ETM_D6,
-	J18_1610_ETM_D7,
-
-	/* OMAP16XX GPIO */
-	P20_1610_GPIO4,
-	V9_1610_GPIO7,
-	W8_1610_GPIO9,
-	N20_1610_GPIO11,
-	N19_1610_GPIO13,
-	P10_1610_GPIO22,
-	V5_1610_GPIO24,
-	AA20_1610_GPIO_41,
-	W19_1610_GPIO48,
-	M7_1610_GPIO62,
-	V14_16XX_GPIO37,
-	R9_16XX_GPIO18,
-	L14_16XX_GPIO49,
-
-	/* OMAP-1610 uWire */
-	V19_1610_UWIRE_SCLK,
-	U18_1610_UWIRE_SDI,
-	W21_1610_UWIRE_SDO,
-	N14_1610_UWIRE_CS0,
-	P15_1610_UWIRE_CS3,
-	N15_1610_UWIRE_CS1,
-
-	/* OMAP-1610 SPI */
-	U19_1610_SPIF_SCK,
-	U18_1610_SPIF_DIN,
-	P20_1610_SPIF_DIN,
-	W21_1610_SPIF_DOUT,
-	R18_1610_SPIF_DOUT,
-	N14_1610_SPIF_CS0,
-	N15_1610_SPIF_CS1,
-	T19_1610_SPIF_CS2,
-	P15_1610_SPIF_CS3,
-
-	/* OMAP-1610 Flash */
-	L3_1610_FLASH_CS2B_OE,
-	M8_1610_FLASH_CS2B_WE,
-
-	/* First MMC */
-	MMC_CMD,
-	MMC_DAT1,
-	MMC_DAT2,
-	MMC_DAT0,
-	MMC_CLK,
-	MMC_DAT3,
-
-	/* OMAP-1710 MMC CMDDIR and DATDIR0 */
-	M15_1710_MMC_CLKI,
-	P19_1710_MMC_CMDDIR,
-	P20_1710_MMC_DATDIR0,
-
-	/* OMAP-1610 USB0 alternate pin configuration */
-	W9_USB0_TXEN,
-	AA9_USB0_VP,
-	Y5_USB0_RCV,
-	R9_USB0_VM,
-	V6_USB0_TXD,
-	W5_USB0_SE0,
-	V9_USB0_SPEED,
-	V9_USB0_SUSP,
-
-	/* USB2 */
-	W9_USB2_TXEN,
-	AA9_USB2_VP,
-	Y5_USB2_RCV,
-	R9_USB2_VM,
-	V6_USB2_TXD,
-	W5_USB2_SE0,
-
-	/* 16XX UART */
-	R13_1610_UART1_TX,
-	V14_16XX_UART1_RX,
-	R14_1610_UART1_CTS,
-	AA15_1610_UART1_RTS,
-	R9_16XX_UART2_RX,
-	L14_16XX_UART3_RX,
-
-	/* I2C OMAP-1610 */
-	I2C_SCL,
-	I2C_SDA,
-
-	/* Keypad */
-	F18_1610_KBC0,
-	D20_1610_KBC1,
-	D19_1610_KBC2,
-	E18_1610_KBC3,
-	C21_1610_KBC4,
-	G18_1610_KBR0,
-	F19_1610_KBR1,
-	H14_1610_KBR2,
-	E20_1610_KBR3,
-	E19_1610_KBR4,
-	N19_1610_KBR5,
-
-	/* Power management */
-	T20_1610_LOW_PWR,
-
-	/* MCLK Settings */
-	V5_1710_MCLK_ON,
-	V5_1710_MCLK_OFF,
-	R10_1610_MCLK_ON,
-	R10_1610_MCLK_OFF,
-
-	/* CompactFlash controller */
-	P11_1610_CF_CD2,
-	R11_1610_CF_IOIS16,
-	V10_1610_CF_IREQ,
-	W10_1610_CF_RESET,
-	W11_1610_CF_CD1,
-
-	/* parallel camera */
-	J15_1610_CAM_LCLK,
-	J18_1610_CAM_D7,
-	J19_1610_CAM_D6,
-	J14_1610_CAM_D5,
-	K18_1610_CAM_D4,
-	K19_1610_CAM_D3,
-	K15_1610_CAM_D2,
-	K14_1610_CAM_D1,
-	L19_1610_CAM_D0,
-	L18_1610_CAM_VS,
-	L15_1610_CAM_HS,
-	M19_1610_CAM_RSTZ,
-	Y15_1610_CAM_OUTCLK,
-
-	/* serial camera */
-	H19_1610_CAM_EXCLK,
-	Y12_1610_CCP_CLKP,
-	W13_1610_CCP_CLKM,
-	W14_1610_CCP_DATAP,
-	Y14_1610_CCP_DATAM,
-
-};
-
-enum omap24xx_index {
-	/* 24xx I2C */
-	M19_24XX_I2C1_SCL,
-	L15_24XX_I2C1_SDA,
-	J15_24XX_I2C2_SCL,
-	H19_24XX_I2C2_SDA,
-
-	/* 24xx Menelaus interrupt */
-	W19_24XX_SYS_NIRQ,
-
-	/* 24xx clock */
-	W14_24XX_SYS_CLKOUT,
-
-	/* 24xx GPMC chipselects, wait pin monitoring */
-	E2_GPMC_NCS2,
-	L2_GPMC_NCS7,
-	L3_GPMC_WAIT0,
-	N7_GPMC_WAIT1,
-	M1_GPMC_WAIT2,
-	P1_GPMC_WAIT3,
-
-	/* 242X McBSP */
-	Y15_24XX_MCBSP2_CLKX,
-	R14_24XX_MCBSP2_FSX,
-	W15_24XX_MCBSP2_DR,
-	V15_24XX_MCBSP2_DX,
-
-	/* 24xx GPIO */
-	M21_242X_GPIO11,
-	P21_242X_GPIO12,
-	AA10_242X_GPIO13,
-	AA6_242X_GPIO14,
-	AA4_242X_GPIO15,
-	Y11_242X_GPIO16,
-	AA12_242X_GPIO17,
-	AA8_242X_GPIO58,
-	Y20_24XX_GPIO60,
-	W4__24XX_GPIO74,
-	N15_24XX_GPIO85,
-	M15_24XX_GPIO92,
-	P20_24XX_GPIO93,
-	P18_24XX_GPIO95,
-	M18_24XX_GPIO96,
-	L14_24XX_GPIO97,
-	J15_24XX_GPIO99,
-	V14_24XX_GPIO117,
-	P14_24XX_GPIO125,
-
-	/* 242x DBG GPIO */
-	V4_242X_GPIO49,
-	W2_242X_GPIO50,
-	U4_242X_GPIO51,
-	V3_242X_GPIO52,
-	V2_242X_GPIO53,
-	V6_242X_GPIO53,
-	T4_242X_GPIO54,
-	Y4_242X_GPIO54,
-	T3_242X_GPIO55,
-	U2_242X_GPIO56,
-
-	/* 24xx external DMA requests */
-	AA10_242X_DMAREQ0,
-	AA6_242X_DMAREQ1,
-	E4_242X_DMAREQ2,
-	G4_242X_DMAREQ3,
-	D3_242X_DMAREQ4,
-	E3_242X_DMAREQ5,
-
-	/* UART3 */
-	K15_24XX_UART3_TX,
-	K14_24XX_UART3_RX,
-
-	/* MMC/SDIO */
-	G19_24XX_MMC_CLKO,
-	H18_24XX_MMC_CMD,
-	F20_24XX_MMC_DAT0,
-	H14_24XX_MMC_DAT1,
-	E19_24XX_MMC_DAT2,
-	D19_24XX_MMC_DAT3,
-	F19_24XX_MMC_DAT_DIR0,
-	E20_24XX_MMC_DAT_DIR1,
-	F18_24XX_MMC_DAT_DIR2,
-	E18_24XX_MMC_DAT_DIR3,
-	G18_24XX_MMC_CMD_DIR,
-	H15_24XX_MMC_CLKI,
-
-	/* Full speed USB */
-	J20_24XX_USB0_PUEN,
-	J19_24XX_USB0_VP,
-	K20_24XX_USB0_VM,
-	J18_24XX_USB0_RCV,
-	K19_24XX_USB0_TXEN,
-	J14_24XX_USB0_SE0,
-	K18_24XX_USB0_DAT,
-
-	N14_24XX_USB1_SE0,
-	W12_24XX_USB1_SE0,
-	P15_24XX_USB1_DAT,
-	R13_24XX_USB1_DAT,
-	W20_24XX_USB1_TXEN,
-	P13_24XX_USB1_TXEN,
-	V19_24XX_USB1_RCV,
-	V12_24XX_USB1_RCV,
-
-	AA10_24XX_USB2_SE0,
-	Y11_24XX_USB2_DAT,
-	AA12_24XX_USB2_TXEN,
-	AA6_24XX_USB2_RCV,
-	AA4_24XX_USB2_TLLSE0,
-
-	/* Keypad GPIO*/
-	T19_24XX_KBR0,
-	R19_24XX_KBR1,
-	V18_24XX_KBR2,
-	M21_24XX_KBR3,
-	E5__24XX_KBR4,
-	M18_24XX_KBR5,
-	R20_24XX_KBC0,
-	M14_24XX_KBC1,
-	H19_24XX_KBC2,
-	V17_24XX_KBC3,
-	P21_24XX_KBC4,
-	L14_24XX_KBC5,
-	N19_24XX_KBC6,
-
-	/* 24xx Menelaus Keypad GPIO */
-	B3__24XX_KBR5,
-	AA4_24XX_KBC2,
-	B13_24XX_KBC6,
-
-	/* 2430 USB */
-	AD9_2430_USB0_PUEN,
-	Y11_2430_USB0_VP,
-	AD7_2430_USB0_VM,
-	AE7_2430_USB0_RCV,
-	AD4_2430_USB0_TXEN,
-	AF9_2430_USB0_SE0,
-	AE6_2430_USB0_DAT,
-	AD24_2430_USB1_SE0,
-	AB24_2430_USB1_RCV,
-	Y25_2430_USB1_TXEN,
-	AA26_2430_USB1_DAT,
-
-	/* 2430 HS-USB */
-	AD9_2430_USB0HS_DATA3,
-	Y11_2430_USB0HS_DATA4,
-	AD7_2430_USB0HS_DATA5,
-	AE7_2430_USB0HS_DATA6,
-	AD4_2430_USB0HS_DATA2,
-	AF9_2430_USB0HS_DATA0,
-	AE6_2430_USB0HS_DATA1,
-	AE8_2430_USB0HS_CLK,
-	AD8_2430_USB0HS_DIR,
-	AE5_2430_USB0HS_STP,
-	AE9_2430_USB0HS_NXT,
-	AC7_2430_USB0HS_DATA7,
-
-	/* 2430 McBSP */
-	AD6_2430_MCBSP_CLKS,
-
-	AB2_2430_MCBSP1_CLKR,
-	AD5_2430_MCBSP1_FSR,
-	AA1_2430_MCBSP1_DX,
-	AF3_2430_MCBSP1_DR,
-	AB3_2430_MCBSP1_FSX,
-	Y9_2430_MCBSP1_CLKX,
-
-	AC10_2430_MCBSP2_FSX,
-	AD16_2430_MCBSP2_CLX,
-	AE13_2430_MCBSP2_DX,
-	AD13_2430_MCBSP2_DR,
-	AC10_2430_MCBSP2_FSX_OFF,
-	AD16_2430_MCBSP2_CLX_OFF,
-	AE13_2430_MCBSP2_DX_OFF,
-	AD13_2430_MCBSP2_DR_OFF,
-
-	AC9_2430_MCBSP3_CLKX,
-	AE4_2430_MCBSP3_FSX,
-	AE2_2430_MCBSP3_DR,
-	AF4_2430_MCBSP3_DX,
-
-	N3_2430_MCBSP4_CLKX,
-	AD23_2430_MCBSP4_DR,
-	AB25_2430_MCBSP4_DX,
-	AC25_2430_MCBSP4_FSX,
-
-	AE16_2430_MCBSP5_CLKX,
-	AF12_2430_MCBSP5_FSX,
-	K7_2430_MCBSP5_DX,
-	M1_2430_MCBSP5_DR,
-
-	/* 2430 McSPI*/
-	Y18_2430_MCSPI1_CLK,
-	AD15_2430_MCSPI1_SIMO,
-	AE17_2430_MCSPI1_SOMI,
-	U1_2430_MCSPI1_CS0,
-
-	/* Touchscreen GPIO */
-	AF19_2430_GPIO_85,
-
-};
-
-enum omap34xx_index {
-	/* 34xx I2C */
-	K21_34XX_I2C1_SCL,
-	J21_34XX_I2C1_SDA,
-	AF15_34XX_I2C2_SCL,
-	AE15_34XX_I2C2_SDA,
-	AF14_34XX_I2C3_SCL,
-	AG14_34XX_I2C3_SDA,
-	AD26_34XX_I2C4_SCL,
-	AE26_34XX_I2C4_SDA,
-
-	/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
-	Y8_3430_USB1HS_PHY_CLK,
-	Y9_3430_USB1HS_PHY_STP,
-	AA14_3430_USB1HS_PHY_DIR,
-	AA11_3430_USB1HS_PHY_NXT,
-	W13_3430_USB1HS_PHY_DATA0,
-	W12_3430_USB1HS_PHY_DATA1,
-	W11_3430_USB1HS_PHY_DATA2,
-	Y11_3430_USB1HS_PHY_DATA3,
-	W9_3430_USB1HS_PHY_DATA4,
-	Y12_3430_USB1HS_PHY_DATA5,
-	W8_3430_USB1HS_PHY_DATA6,
-	Y13_3430_USB1HS_PHY_DATA7,
-
-	/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
-	AA8_3430_USB2HS_PHY_CLK,
-	AA10_3430_USB2HS_PHY_STP,
-	AA9_3430_USB2HS_PHY_DIR,
-	AB11_3430_USB2HS_PHY_NXT,
-	AB10_3430_USB2HS_PHY_DATA0,
-	AB9_3430_USB2HS_PHY_DATA1,
-	W3_3430_USB2HS_PHY_DATA2,
-	T4_3430_USB2HS_PHY_DATA3,
-	T3_3430_USB2HS_PHY_DATA4,
-	R3_3430_USB2HS_PHY_DATA5,
-	R4_3430_USB2HS_PHY_DATA6,
-	T2_3430_USB2HS_PHY_DATA7,
-
-
-	/* TLL - HSUSB: 12-pin TLL Port 1*/
-	Y8_3430_USB1HS_TLL_CLK,
-	Y9_3430_USB1HS_TLL_STP,
-	AA14_3430_USB1HS_TLL_DIR,
-	AA11_3430_USB1HS_TLL_NXT,
-	W13_3430_USB1HS_TLL_DATA0,
-	W12_3430_USB1HS_TLL_DATA1,
-	W11_3430_USB1HS_TLL_DATA2,
-	Y11_3430_USB1HS_TLL_DATA3,
-	W9_3430_USB1HS_TLL_DATA4,
-	Y12_3430_USB1HS_TLL_DATA5,
-	W8_3430_USB1HS_TLL_DATA6,
-	Y13_3430_USB1HS_TLL_DATA7,
-
-	/* TLL - HSUSB: 12-pin TLL Port 2*/
-	AA8_3430_USB2HS_TLL_CLK,
-	AA10_3430_USB2HS_TLL_STP,
-	AA9_3430_USB2HS_TLL_DIR,
-	AB11_3430_USB2HS_TLL_NXT,
-	AB10_3430_USB2HS_TLL_DATA0,
-	AB9_3430_USB2HS_TLL_DATA1,
-	W3_3430_USB2HS_TLL_DATA2,
-	T4_3430_USB2HS_TLL_DATA3,
-	T3_3430_USB2HS_TLL_DATA4,
-	R3_3430_USB2HS_TLL_DATA5,
-	R4_3430_USB2HS_TLL_DATA6,
-	T2_3430_USB2HS_TLL_DATA7,
-
-	/* TLL - HSUSB: 12-pin TLL Port 3*/
-	AA6_3430_USB3HS_TLL_CLK,
-	AB3_3430_USB3HS_TLL_STP,
-	AA3_3430_USB3HS_TLL_DIR,
-	Y3_3430_USB3HS_TLL_NXT,
-	AA5_3430_USB3HS_TLL_DATA0,
-	Y4_3430_USB3HS_TLL_DATA1,
-	Y5_3430_USB3HS_TLL_DATA2,
-	W5_3430_USB3HS_TLL_DATA3,
-	AB12_3430_USB3HS_TLL_DATA4,
-	AB13_3430_USB3HS_TLL_DATA5,
-	AA13_3430_USB3HS_TLL_DATA6,
-	AA12_3430_USB3HS_TLL_DATA7,
-
-	/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
-	AF10_3430_USB1FS_PHY_MM1_RXDP,
-	AG9_3430_USB1FS_PHY_MM1_RXDM,
-	W13_3430_USB1FS_PHY_MM1_RXRCV,
-	W12_3430_USB1FS_PHY_MM1_TXSE0,
-	W11_3430_USB1FS_PHY_MM1_TXDAT,
-	Y11_3430_USB1FS_PHY_MM1_TXEN_N,
-
-	/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
-	AF7_3430_USB2FS_PHY_MM2_RXDP,
-	AH7_3430_USB2FS_PHY_MM2_RXDM,
-	AB10_3430_USB2FS_PHY_MM2_RXRCV,
-	AB9_3430_USB2FS_PHY_MM2_TXSE0,
-	W3_3430_USB2FS_PHY_MM2_TXDAT,
-	T4_3430_USB2FS_PHY_MM2_TXEN_N,
-
-	/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
-	AH3_3430_USB3FS_PHY_MM3_RXDP,
-	AE3_3430_USB3FS_PHY_MM3_RXDM,
-	AD1_3430_USB3FS_PHY_MM3_RXRCV,
-	AE1_3430_USB3FS_PHY_MM3_TXSE0,
-	AD2_3430_USB3FS_PHY_MM3_TXDAT,
-	AC1_3430_USB3FS_PHY_MM3_TXEN_N,
-
-	/* 34xx GPIO
-	 *  - normally these are bidirectional, no internal pullup/pulldown
-	 *  - "_UP" suffix (GPIO3_UP) if internal pullup is configured
-	 *  - "_DOWN" suffix (GPIO3_DOWN) with internal pulldown
-	 *  - "_OUT" suffix (GPIO3_OUT) for output-only pins (unlike 24xx)
-	 */
-	AF26_34XX_GPIO0,
-	AF22_34XX_GPIO9,
-	AG9_34XX_GPIO23,
-	AH8_34XX_GPIO29,
-	U8_34XX_GPIO54_OUT,
-	U8_34XX_GPIO54_DOWN,
-	L8_34XX_GPIO63,
-	G25_34XX_GPIO86_OUT,
-	AG4_34XX_GPIO134_OUT,
-	AF4_34XX_GPIO135_OUT,
-	AE4_34XX_GPIO136_OUT,
-	AF6_34XX_GPIO140_UP,
-	AE6_34XX_GPIO141,
-	AF5_34XX_GPIO142,
-	AE5_34XX_GPIO143,
-	H19_34XX_GPIO164_OUT,
-	J25_34XX_GPIO170,
-
-	/* OMAP3 SDRC CKE signals to SDR/DDR ram chips */
-	H16_34XX_SDRC_CKE0,
-	H17_34XX_SDRC_CKE1,
-
-	/* MMC1 */
-	N28_3430_MMC1_CLK,
-	M27_3430_MMC1_CMD,
-	N27_3430_MMC1_DAT0,
-	N26_3430_MMC1_DAT1,
-	N25_3430_MMC1_DAT2,
-	P28_3430_MMC1_DAT3,
-	P27_3430_MMC1_DAT4,
-	P26_3430_MMC1_DAT5,
-	R27_3430_MMC1_DAT6,
-	R25_3430_MMC1_DAT7,
-
-	/* MMC2 */
-	AE2_3430_MMC2_CLK,
-	AG5_3430_MMC2_CMD,
-	AH5_3430_MMC2_DAT0,
-	AH4_3430_MMC2_DAT1,
-	AG4_3430_MMC2_DAT2,
-	AF4_3430_MMC2_DAT3,
-
-	/* MMC3 */
-	AF10_3430_MMC3_CLK,
-	AC3_3430_MMC3_CMD,
-	AE11_3430_MMC3_DAT0,
-	AH9_3430_MMC3_DAT1,
-	AF13_3430_MMC3_DAT2,
-	AF13_3430_MMC3_DAT3,
-
-	/* SYS_NIRQ T2 INT1 */
-	AF26_34XX_SYS_NIRQ,
-};
-
-struct omap_mux_cfg {
-	struct pin_config	*pins;
-	unsigned long		size;
-	int			(*cfg_reg)(const struct pin_config *cfg);
-};
-
-#ifdef	CONFIG_OMAP_MUX
-/* setup pin muxing in Linux */
-extern int omap1_mux_init(void);
-extern int omap2_mux_init(void);
-extern int omap_mux_register(struct omap_mux_cfg *);
-extern int omap_cfg_reg(unsigned long reg_cfg);
-#else
-/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
-static inline int omap1_mux_init(void) { return 0; }
-static inline int omap2_mux_init(void) { return 0; }
-static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/nand.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/nand.h
- *
- * Copyright (C) 2006 Micron Technology 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/mtd/partitions.h>
-
-struct omap_nand_platform_data {
-	unsigned int		options;
-	int			cs;
-	int			gpio_irq;
-	struct mtd_partition	*parts;
-	int			nr_parts;
-	int			(*nand_setup)(void __iomem *);
-	int			(*dev_ready)(struct omap_nand_platform_data *);
-	int			dma_channel;
-	void __iomem		*gpmc_cs_baseaddr;
-	void __iomem		*gpmc_baseaddr;
-};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap1510.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap1510.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap1510.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap1510.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/* arch/arm/plat-omap/include/mach/omap1510.h
- *
- * Hardware definitions for TI OMAP1510 processor.
- *
- * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
- */
-
-#ifndef __ASM_ARCH_OMAP15XX_H
-#define __ASM_ARCH_OMAP15XX_H
-
-/*
- * ----------------------------------------------------------------------------
- * Base addresses
- * ----------------------------------------------------------------------------
- */
-
-/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
-
-#define OMAP1510_DSP_BASE	0xE0000000
-#define OMAP1510_DSP_SIZE	0x28000
-#define OMAP1510_DSP_START	0xE0000000
-
-#define OMAP1510_DSPREG_BASE	0xE1000000
-#define OMAP1510_DSPREG_SIZE	SZ_128K
-#define OMAP1510_DSPREG_START	0xE1000000
-
-#define OMAP1510_DSP_MMU_BASE	(0xfffed200)
-
-#endif /*  __ASM_ARCH_OMAP15XX_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap16xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap16xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap16xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap16xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-/* arch/arm/plat-omap/include/mach/omap16xx.h
- *
- * Hardware definitions for TI OMAP1610/5912/1710 processors.
- *
- * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
- */
-
-#ifndef __ASM_ARCH_OMAP16XX_H
-#define __ASM_ARCH_OMAP16XX_H
-
-/*
- * ----------------------------------------------------------------------------
- * Base addresses
- * ----------------------------------------------------------------------------
- */
-
-/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
-
-#define OMAP16XX_DSP_BASE	0xE0000000
-#define OMAP16XX_DSP_SIZE	0x28000
-#define OMAP16XX_DSP_START	0xE0000000
-
-#define OMAP16XX_DSPREG_BASE	0xE1000000
-#define OMAP16XX_DSPREG_SIZE	SZ_128K
-#define OMAP16XX_DSPREG_START	0xE1000000
-
-#define OMAP16XX_SEC_BASE	0xFFFE4000
-#define OMAP16XX_SEC_DES	(OMAP16XX_SEC_BASE + 0x0000)
-#define OMAP16XX_SEC_SHA1MD5	(OMAP16XX_SEC_BASE + 0x0800)
-#define OMAP16XX_SEC_RNG	(OMAP16XX_SEC_BASE + 0x1000)
-
-/*
- * ---------------------------------------------------------------------------
- * Interrupts
- * ---------------------------------------------------------------------------
- */
-#define OMAP_IH2_0_BASE		(0xfffe0000)
-#define OMAP_IH2_1_BASE		(0xfffe0100)
-#define OMAP_IH2_2_BASE		(0xfffe0200)
-#define OMAP_IH2_3_BASE		(0xfffe0300)
-
-#define OMAP_IH2_0_ITR		(OMAP_IH2_0_BASE + 0x00)
-#define OMAP_IH2_0_MIR		(OMAP_IH2_0_BASE + 0x04)
-#define OMAP_IH2_0_SIR_IRQ	(OMAP_IH2_0_BASE + 0x10)
-#define OMAP_IH2_0_SIR_FIQ	(OMAP_IH2_0_BASE + 0x14)
-#define OMAP_IH2_0_CONTROL	(OMAP_IH2_0_BASE + 0x18)
-#define OMAP_IH2_0_ILR0		(OMAP_IH2_0_BASE + 0x1c)
-#define OMAP_IH2_0_ISR		(OMAP_IH2_0_BASE + 0x9c)
-
-#define OMAP_IH2_1_ITR		(OMAP_IH2_1_BASE + 0x00)
-#define OMAP_IH2_1_MIR		(OMAP_IH2_1_BASE + 0x04)
-#define OMAP_IH2_1_SIR_IRQ	(OMAP_IH2_1_BASE + 0x10)
-#define OMAP_IH2_1_SIR_FIQ	(OMAP_IH2_1_BASE + 0x14)
-#define OMAP_IH2_1_CONTROL	(OMAP_IH2_1_BASE + 0x18)
-#define OMAP_IH2_1_ILR1		(OMAP_IH2_1_BASE + 0x1c)
-#define OMAP_IH2_1_ISR		(OMAP_IH2_1_BASE + 0x9c)
-
-#define OMAP_IH2_2_ITR		(OMAP_IH2_2_BASE + 0x00)
-#define OMAP_IH2_2_MIR		(OMAP_IH2_2_BASE + 0x04)
-#define OMAP_IH2_2_SIR_IRQ	(OMAP_IH2_2_BASE + 0x10)
-#define OMAP_IH2_2_SIR_FIQ	(OMAP_IH2_2_BASE + 0x14)
-#define OMAP_IH2_2_CONTROL	(OMAP_IH2_2_BASE + 0x18)
-#define OMAP_IH2_2_ILR2		(OMAP_IH2_2_BASE + 0x1c)
-#define OMAP_IH2_2_ISR		(OMAP_IH2_2_BASE + 0x9c)
-
-#define OMAP_IH2_3_ITR		(OMAP_IH2_3_BASE + 0x00)
-#define OMAP_IH2_3_MIR		(OMAP_IH2_3_BASE + 0x04)
-#define OMAP_IH2_3_SIR_IRQ	(OMAP_IH2_3_BASE + 0x10)
-#define OMAP_IH2_3_SIR_FIQ	(OMAP_IH2_3_BASE + 0x14)
-#define OMAP_IH2_3_CONTROL	(OMAP_IH2_3_BASE + 0x18)
-#define OMAP_IH2_3_ILR3		(OMAP_IH2_3_BASE + 0x1c)
-#define OMAP_IH2_3_ISR		(OMAP_IH2_3_BASE + 0x9c)
-
-/*
- * ----------------------------------------------------------------------------
- * Clocks
- * ----------------------------------------------------------------------------
- */
-#define OMAP16XX_ARM_IDLECT3	(CLKGEN_REG_BASE + 0x24)
-
-/*
- * ----------------------------------------------------------------------------
- * Pin configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP16XX_CONF_VOLTAGE_VDDSHV6	(1 << 8)
-#define OMAP16XX_CONF_VOLTAGE_VDDSHV7	(1 << 9)
-#define OMAP16XX_CONF_VOLTAGE_VDDSHV8	(1 << 10)
-#define OMAP16XX_CONF_VOLTAGE_VDDSHV9	(1 << 11)
-#define OMAP16XX_SUBLVDS_CONF_VALID	(1 << 13)
-
-/*
- * ----------------------------------------------------------------------------
- * System control registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP1610_RESET_CONTROL  0xfffe1140
-
-/*
- * ---------------------------------------------------------------------------
- * TIPB bus interface
- * ---------------------------------------------------------------------------
- */
-#define TIPB_SWITCH_BASE		 (0xfffbc800)
-#define OMAP16XX_MMCSD2_SSW_MPU_CONF	(TIPB_SWITCH_BASE + 0x160)
-
-/* UART3 Registers Maping through MPU bus */
-#define UART3_RHR               (OMAP_UART3_BASE + 0)
-#define UART3_THR               (OMAP_UART3_BASE + 0)
-#define UART3_DLL               (OMAP_UART3_BASE + 0)
-#define UART3_IER               (OMAP_UART3_BASE + 4)
-#define UART3_DLH               (OMAP_UART3_BASE + 4)
-#define UART3_IIR               (OMAP_UART3_BASE + 8)
-#define UART3_FCR               (OMAP_UART3_BASE + 8)
-#define UART3_EFR               (OMAP_UART3_BASE + 8)
-#define UART3_LCR               (OMAP_UART3_BASE + 0x0C)
-#define UART3_MCR               (OMAP_UART3_BASE + 0x10)
-#define UART3_XON1_ADDR1        (OMAP_UART3_BASE + 0x10)
-#define UART3_XON2_ADDR2        (OMAP_UART3_BASE + 0x14)
-#define UART3_LSR               (OMAP_UART3_BASE + 0x14)
-#define UART3_TCR               (OMAP_UART3_BASE + 0x18)
-#define UART3_MSR               (OMAP_UART3_BASE + 0x18)
-#define UART3_XOFF1             (OMAP_UART3_BASE + 0x18)
-#define UART3_XOFF2             (OMAP_UART3_BASE + 0x1C)
-#define UART3_SPR               (OMAP_UART3_BASE + 0x1C)
-#define UART3_TLR               (OMAP_UART3_BASE + 0x1C)
-#define UART3_MDR1              (OMAP_UART3_BASE + 0x20)
-#define UART3_MDR2              (OMAP_UART3_BASE + 0x24)
-#define UART3_SFLSR             (OMAP_UART3_BASE + 0x28)
-#define UART3_TXFLL             (OMAP_UART3_BASE + 0x28)
-#define UART3_RESUME            (OMAP_UART3_BASE + 0x2C)
-#define UART3_TXFLH             (OMAP_UART3_BASE + 0x2C)
-#define UART3_SFREGL            (OMAP_UART3_BASE + 0x30)
-#define UART3_RXFLL             (OMAP_UART3_BASE + 0x30)
-#define UART3_SFREGH            (OMAP_UART3_BASE + 0x34)
-#define UART3_RXFLH             (OMAP_UART3_BASE + 0x34)
-#define UART3_BLR               (OMAP_UART3_BASE + 0x38)
-#define UART3_ACREG             (OMAP_UART3_BASE + 0x3C)
-#define UART3_DIV16             (OMAP_UART3_BASE + 0x3C)
-#define UART3_SCR               (OMAP_UART3_BASE + 0x40)
-#define UART3_SSR               (OMAP_UART3_BASE + 0x44)
-#define UART3_EBLR              (OMAP_UART3_BASE + 0x48)
-#define UART3_OSC_12M_SEL       (OMAP_UART3_BASE + 0x4C)
-#define UART3_MVR               (OMAP_UART3_BASE + 0x50)
-
-/*
- * ---------------------------------------------------------------------------
- * Watchdog timer
- * ---------------------------------------------------------------------------
- */
-
-/* 32-bit Watchdog timer in OMAP 16XX */
-#define OMAP_16XX_WATCHDOG_BASE        (0xfffeb000)
-#define OMAP_16XX_WIDR         (OMAP_16XX_WATCHDOG_BASE + 0x00)
-#define OMAP_16XX_WD_SYSCONFIG (OMAP_16XX_WATCHDOG_BASE + 0x10)
-#define OMAP_16XX_WD_SYSSTATUS (OMAP_16XX_WATCHDOG_BASE + 0x14)
-#define OMAP_16XX_WCLR         (OMAP_16XX_WATCHDOG_BASE + 0x24)
-#define OMAP_16XX_WCRR         (OMAP_16XX_WATCHDOG_BASE + 0x28)
-#define OMAP_16XX_WLDR         (OMAP_16XX_WATCHDOG_BASE + 0x2c)
-#define OMAP_16XX_WTGR         (OMAP_16XX_WATCHDOG_BASE + 0x30)
-#define OMAP_16XX_WWPS         (OMAP_16XX_WATCHDOG_BASE + 0x34)
-#define OMAP_16XX_WSPR         (OMAP_16XX_WATCHDOG_BASE + 0x48)
-
-#define WCLR_PRE_SHIFT         5
-#define WCLR_PTV_SHIFT         2
-
-#define WWPS_W_PEND_WSPR       (1 << 4)
-#define WWPS_W_PEND_WTGR       (1 << 3)
-#define WWPS_W_PEND_WLDR       (1 << 2)
-#define WWPS_W_PEND_WCRR       (1 << 1)
-#define WWPS_W_PEND_WCLR       (1 << 0)
-
-#define WSPR_ENABLE_0          (0x0000bbbb)
-#define WSPR_ENABLE_1          (0x00004444)
-#define WSPR_DISABLE_0         (0x0000aaaa)
-#define WSPR_DISABLE_1         (0x00005555)
-
-#define OMAP16XX_DSP_MMU_BASE	(0xfffed200)
-#define OMAP16XX_MAILBOX_BASE	(0xfffcf000)
-
-#endif /*  __ASM_ARCH_OMAP16XX_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap24xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap24xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap24xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap24xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/omap24xx.h
- *
- * This file contains the processor specific definitions
- * of the TI OMAP24XX.
- *
- * Copyright (C) 2007 Texas Instruments.
- * Copyright (C) 2007 Nokia 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
- *
- */
-
-#ifndef __ASM_ARCH_OMAP24XX_H
-#define __ASM_ARCH_OMAP24XX_H
-
-/*
- * Please place only base defines here and put the rest in device
- * specific headers. Note also that some of these defines are needed
- * for omap1 to compile without adding ifdefs.
- */
-
-#define L4_24XX_BASE		0x48000000
-#define L4_WK_243X_BASE		0x49000000
-#define L3_24XX_BASE		0x68000000
-
-/* interrupt controller */
-#define OMAP24XX_IC_BASE	(L4_24XX_BASE + 0xfe000)
-#define OMAP24XX_IVA_INTC_BASE	0x40000000
-
-#define OMAP2420_CTRL_BASE	L4_24XX_BASE
-#define OMAP2420_32KSYNCT_BASE	(L4_24XX_BASE + 0x4000)
-#define OMAP2420_PRCM_BASE	(L4_24XX_BASE + 0x8000)
-#define OMAP2420_CM_BASE	(L4_24XX_BASE + 0x8000)
-#define OMAP2420_PRM_BASE	OMAP2420_CM_BASE
-#define OMAP2420_SDRC_BASE	(L3_24XX_BASE + 0x9000)
-#define OMAP2420_SMS_BASE	0x68008000
-#define OMAP2420_GPMC_BASE	0x6800a000
-
-#define OMAP2430_32KSYNCT_BASE	(L4_WK_243X_BASE + 0x20000)
-#define OMAP2430_PRCM_BASE	(L4_WK_243X_BASE + 0x6000)
-#define OMAP2430_CM_BASE	(L4_WK_243X_BASE + 0x6000)
-#define OMAP2430_PRM_BASE	OMAP2430_CM_BASE
-
-#define OMAP243X_SMS_BASE	0x6C000000
-#define OMAP243X_SDRC_BASE	0x6D000000
-#define OMAP243X_GPMC_BASE	0x6E000000
-#define OMAP243X_SCM_BASE	(L4_WK_243X_BASE + 0x2000)
-#define OMAP243X_CTRL_BASE	OMAP243X_SCM_BASE
-#define OMAP243X_HS_BASE	(L4_24XX_BASE + 0x000ac000)
-
-/* DSP SS */
-#define OMAP2420_DSP_BASE	0x58000000
-#define OMAP2420_DSP_MEM_BASE	(OMAP2420_DSP_BASE + 0x0)
-#define OMAP2420_DSP_IPI_BASE	(OMAP2420_DSP_BASE + 0x1000000)
-#define OMAP2420_DSP_MMU_BASE	(OMAP2420_DSP_BASE + 0x2000000)
-
-#define OMAP243X_DSP_BASE	0x5C000000
-#define OMAP243X_DSP_MEM_BASE	(OMAP243X_DSP_BASE + 0x0)
-#define OMAP243X_DSP_MMU_BASE	(OMAP243X_DSP_BASE + 0x1000000)
-
-/* Mailbox */
-#define OMAP24XX_MAILBOX_BASE	(L4_24XX_BASE + 0x94000)
-
-/* Camera */
-#define OMAP24XX_CAMERA_BASE	(L4_24XX_BASE + 0x52000)
-
-/* Security */
-#define OMAP24XX_SEC_BASE	(L4_24XX_BASE + 0xA0000)
-#define OMAP24XX_SEC_RNG_BASE	(OMAP24XX_SEC_BASE + 0x0000)
-#define OMAP24XX_SEC_DES_BASE	(OMAP24XX_SEC_BASE + 0x2000)
-#define OMAP24XX_SEC_SHA1MD5_BASE (OMAP24XX_SEC_BASE + 0x4000)
-#define OMAP24XX_SEC_AES_BASE	(OMAP24XX_SEC_BASE + 0x6000)
-#define OMAP24XX_SEC_PKA_BASE	(OMAP24XX_SEC_BASE + 0x8000)
-
-#endif /* __ASM_ARCH_OMAP24XX_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/omap34xx.h
- *
- * This file contains the processor specific definitions of the TI OMAP34XX.
- *
- * Copyright (C) 2007 Texas Instruments.
- * Copyright (C) 2007 Nokia 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
- */
-
-#ifndef __ASM_ARCH_OMAP34XX_H
-#define __ASM_ARCH_OMAP34XX_H
-
-/*
- * Please place only base defines here and put the rest in device
- * specific headers.
- */
-
-#define L4_34XX_BASE		0x48000000
-#define L4_WK_34XX_BASE		0x48300000
-#define L4_PER_34XX_BASE	0x49000000
-#define L4_EMU_34XX_BASE	0x54000000
-#define L3_34XX_BASE		0x68000000
-
-#define OMAP3430_32KSYNCT_BASE	0x48320000
-#define OMAP3430_CM_BASE	0x48004800
-#define OMAP3430_PRM_BASE	0x48306800
-#define OMAP343X_SMS_BASE	0x6C000000
-#define OMAP343X_SDRC_BASE	0x6D000000
-#define OMAP34XX_GPMC_BASE	0x6E000000
-#define OMAP343X_SCM_BASE	0x48002000
-#define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
-
-#define OMAP34XX_IC_BASE	0x48200000
-
-#define OMAP3430_ISP_BASE		(L4_34XX_BASE + 0xBC000)
-#define OMAP3430_ISP_CBUFF_BASE		(OMAP3430_ISP_BASE + 0x0100)
-#define OMAP3430_ISP_CCP2_BASE		(OMAP3430_ISP_BASE + 0x0400)
-#define OMAP3430_ISP_CCDC_BASE		(OMAP3430_ISP_BASE + 0x0600)
-#define OMAP3430_ISP_HIST_BASE		(OMAP3430_ISP_BASE + 0x0A00)
-#define OMAP3430_ISP_H3A_BASE		(OMAP3430_ISP_BASE + 0x0C00)
-#define OMAP3430_ISP_PREV_BASE		(OMAP3430_ISP_BASE + 0x0E00)
-#define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
-#define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
-#define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
-#define OMAP3430_ISP_CSI2A_BASE		(OMAP3430_ISP_BASE + 0x1800)
-#define OMAP3430_ISP_CSI2PHY_BASE	(OMAP3430_ISP_BASE + 0x1970)
-
-#define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
-#define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
-#define OMAP3430_ISP_CCP2_END		(OMAP3430_ISP_CCP2_BASE    + 0x1EF)
-#define OMAP3430_ISP_CCDC_END		(OMAP3430_ISP_CCDC_BASE    + 0x0A7)
-#define OMAP3430_ISP_HIST_END		(OMAP3430_ISP_HIST_BASE    + 0x047)
-#define OMAP3430_ISP_H3A_END		(OMAP3430_ISP_H3A_BASE     + 0x05F)
-#define OMAP3430_ISP_PREV_END		(OMAP3430_ISP_PREV_BASE    + 0x09F)
-#define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
-#define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
-#define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
-#define OMAP3430_ISP_CSI2A_END		(OMAP3430_ISP_CSI2A_BASE   + 0x16F)
-#define OMAP3430_ISP_CSI2PHY_END	(OMAP3430_ISP_CSI2PHY_BASE + 0x007)
-
-#define OMAP34XX_IVA_INTC_BASE	0x40000000
-#define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
-#define OMAP34XX_HSUSB_HOST_BASE	(L4_34XX_BASE + 0x64000)
-#define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)
-
-#define OMAP34XX_MAILBOX_BASE		(L4_34XX_BASE + 0x94000)
-
-#define OMAP34XX_DSP_BASE	0x58000000
-#define OMAP34XX_DSP_MEM_BASE	(OMAP34XX_DSP_BASE + 0x0)
-#define OMAP34XX_DSP_IPI_BASE	(OMAP34XX_DSP_BASE + 0x1000000)
-#define OMAP34XX_DSP_MMU_BASE	(OMAP34XX_DSP_BASE + 0x2000000)
-#endif /* __ASM_ARCH_OMAP34XX_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap44xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap44xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap44xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/*:
- * Address mappings and base address for OMAP4 interconnects
- * and peripherals.
- *
- * Copyright (C) 2009 Texas Instruments
- *
- * Author: 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.
- */
-#ifndef __ASM_ARCH_OMAP44XX_H
-#define __ASM_ARCH_OMAP44XX_H
-
-/*
- * Please place only base defines here and put the rest in device
- * specific headers.
- */
-#define L4_44XX_BASE			0x4a000000
-#define L4_WK_44XX_BASE			0x4a300000
-#define L4_PER_44XX_BASE		0x48000000
-#define L4_EMU_44XX_BASE		0x54000000
-#define L3_44XX_BASE			0x44000000
-#define OMAP4430_32KSYNCT_BASE		0x4a304000
-#define OMAP4430_CM_BASE		0x4a004000
-#define OMAP4430_PRM_BASE		0x48306000
-#define OMAP44XX_GPMC_BASE		0x50000000
-#define OMAP443X_SCM_BASE		0x4a002000
-#define OMAP443X_CTRL_BASE		OMAP443X_SCM_BASE
-#define OMAP44XX_IC_BASE		0x48200000
-#define OMAP44XX_IVA_INTC_BASE		0x40000000
-#define IRQ_SIR_IRQ			0x0040
-#define OMAP44XX_GIC_DIST_BASE		0x48241000
-#define OMAP44XX_GIC_CPU_BASE		0x48240100
-#define OMAP44XX_VA_GIC_CPU_BASE	OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
-#define OMAP44XX_SCU_BASE		0x48240000
-#define OMAP44XX_VA_SCU_BASE		OMAP2_IO_ADDRESS(OMAP44XX_SCU_BASE)
-#define OMAP44XX_LOCAL_TWD_BASE		0x48240600
-#define OMAP44XX_VA_LOCAL_TWD_BASE	OMAP2_IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE)
-#define OMAP44XX_LOCAL_TWD_SIZE		0x00000100
-#define OMAP44XX_WKUPGEN_BASE		0x48281000
-#define OMAP44XX_VA_WKUPGEN_BASE	OMAP2_IO_ADDRESS(OMAP44XX_WKUPGEN_BASE)
-
-#endif /* __ASM_ARCH_OMAP44XX_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap730.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap730.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap730.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap730.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/* arch/arm/plat-omap/include/mach/omap730.h
- *
- * Hardware definitions for TI OMAP730 processor.
- *
- * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
- */
-
-#ifndef __ASM_ARCH_OMAP730_H
-#define __ASM_ARCH_OMAP730_H
-
-/*
- * ----------------------------------------------------------------------------
- * Base addresses
- * ----------------------------------------------------------------------------
- */
-
-/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
-
-#define OMAP730_DSP_BASE	0xE0000000
-#define OMAP730_DSP_SIZE	0x50000
-#define OMAP730_DSP_START	0xE0000000
-
-#define OMAP730_DSPREG_BASE	0xE1000000
-#define OMAP730_DSPREG_SIZE	SZ_128K
-#define OMAP730_DSPREG_START	0xE1000000
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP730 specific configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP730_CONFIG_BASE	0xfffe1000
-#define OMAP730_IO_CONF_0	0xfffe1070
-#define OMAP730_IO_CONF_1	0xfffe1074
-#define OMAP730_IO_CONF_2	0xfffe1078
-#define OMAP730_IO_CONF_3	0xfffe107c
-#define OMAP730_IO_CONF_4	0xfffe1080
-#define OMAP730_IO_CONF_5	0xfffe1084
-#define OMAP730_IO_CONF_6	0xfffe1088
-#define OMAP730_IO_CONF_7	0xfffe108c
-#define OMAP730_IO_CONF_8	0xfffe1090
-#define OMAP730_IO_CONF_9	0xfffe1094
-#define OMAP730_IO_CONF_10	0xfffe1098
-#define OMAP730_IO_CONF_11	0xfffe109c
-#define OMAP730_IO_CONF_12	0xfffe10a0
-#define OMAP730_IO_CONF_13	0xfffe10a4
-
-#define OMAP730_MODE_1		0xfffe1010
-#define OMAP730_MODE_2		0xfffe1014
-
-/* CSMI specials: in terms of base + offset */
-#define OMAP730_MODE2_OFFSET	0x14
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP730 traffic controller configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP730_FLASH_CFG_0	0xfffecc10
-#define OMAP730_FLASH_ACFG_0	0xfffecc50
-#define OMAP730_FLASH_CFG_1	0xfffecc14
-#define OMAP730_FLASH_ACFG_1	0xfffecc54
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP730 DSP control registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP730_ICR_BASE	0xfffbb800
-#define OMAP730_DSP_M_CTL	0xfffbb804
-#define OMAP730_DSP_MMU_BASE	0xfffed200
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP730 PCC_UPLD configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP730_PCC_UPLD_CTRL_BASE	(0xfffe0900)
-#define OMAP730_PCC_UPLD_CTRL		(OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
-
-#endif /*  __ASM_ARCH_OMAP730_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap850.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap850.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap850.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap850.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/* arch/arm/plat-omap/include/mach/omap850.h
- *
- * Hardware definitions for TI OMAP850 processor.
- *
- * Derived from omap730.h by Zebediah C. McClure <zmc@lurian.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.
- *
- * 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.
- */
-
-#ifndef __ASM_ARCH_OMAP850_H
-#define __ASM_ARCH_OMAP850_H
-
-/*
- * ----------------------------------------------------------------------------
- * Base addresses
- * ----------------------------------------------------------------------------
- */
-
-/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
-
-#define OMAP850_DSP_BASE	0xE0000000
-#define OMAP850_DSP_SIZE	0x50000
-#define OMAP850_DSP_START	0xE0000000
-
-#define OMAP850_DSPREG_BASE	0xE1000000
-#define OMAP850_DSPREG_SIZE	SZ_128K
-#define OMAP850_DSPREG_START	0xE1000000
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP850 specific configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP850_CONFIG_BASE	0xfffe1000
-#define OMAP850_IO_CONF_0	0xfffe1070
-#define OMAP850_IO_CONF_1	0xfffe1074
-#define OMAP850_IO_CONF_2	0xfffe1078
-#define OMAP850_IO_CONF_3	0xfffe107c
-#define OMAP850_IO_CONF_4	0xfffe1080
-#define OMAP850_IO_CONF_5	0xfffe1084
-#define OMAP850_IO_CONF_6	0xfffe1088
-#define OMAP850_IO_CONF_7	0xfffe108c
-#define OMAP850_IO_CONF_8	0xfffe1090
-#define OMAP850_IO_CONF_9	0xfffe1094
-#define OMAP850_IO_CONF_10	0xfffe1098
-#define OMAP850_IO_CONF_11	0xfffe109c
-#define OMAP850_IO_CONF_12	0xfffe10a0
-#define OMAP850_IO_CONF_13	0xfffe10a4
-
-#define OMAP850_MODE_1		0xfffe1010
-#define OMAP850_MODE_2		0xfffe1014
-
-/* CSMI specials: in terms of base + offset */
-#define OMAP850_MODE2_OFFSET	0x14
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP850 traffic controller configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP850_FLASH_CFG_0	0xfffecc10
-#define OMAP850_FLASH_ACFG_0	0xfffecc50
-#define OMAP850_FLASH_CFG_1	0xfffecc14
-#define OMAP850_FLASH_ACFG_1	0xfffecc54
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP850 DSP control registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP850_ICR_BASE	0xfffbb800
-#define OMAP850_DSP_M_CTL	0xfffbb804
-#define OMAP850_DSP_MMU_BASE	0xfffed200
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP850 PCC_UPLD configuration registers
- * ----------------------------------------------------------------------------
- */
-#define OMAP850_PCC_UPLD_CTRL_BASE	(0xfffe0900)
-#define OMAP850_PCC_UPLD_CTRL		(OMAP850_PCC_UPLD_CTRL_BASE + 0x00)
-
-#endif /*  __ASM_ARCH_OMAP850_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap-alsa.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap-alsa.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap-alsa.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap-alsa.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,123 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/omap-alsa.h
- *
- * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
- *
- * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
- *
- * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
- * Written by Daniel Petrini, David Cohen, Anderson Briglia
- *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
- *
- * 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.
- *
- *  History
- *  -------
- *
- *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
- *  					original version based in sa1100 driver
- *  					and omap oss driver.
- */
-
-#ifndef __OMAP_ALSA_H
-#define __OMAP_ALSA_H
-
-#include <mach/dma.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <mach/mcbsp.h>
-#include <linux/platform_device.h>
-
-#define DMA_BUF_SIZE	(1024 * 8)
-
-/*
- * Buffer management for alsa and dma
- */
-struct audio_stream {
-	char *id;		/* identification string */
-	int stream_id;		/* numeric identification */
-	int dma_dev;		/* dma number of that device */
-	int *lch;		/* Chain of channels this stream is linked to */
-	char started;		/* to store if the chain was started or not */
-	int dma_q_head;		/* DMA Channel Q Head */
-	int dma_q_tail;		/* DMA Channel Q Tail */
-	char dma_q_count;	/* DMA Channel Q Count */
-	int active:1;		/* we are using this stream for transfer now */
-	int period;		/* current transfer period */
-	int periods;		/* current count of periods registerd in the DMA engine */
-	spinlock_t dma_lock;	/* for locking in DMA operations */
-	struct snd_pcm_substream *stream;	/* the pcm stream */
-	unsigned linked:1;	/* dma channels linked */
-	int offset;		/* store start position of the last period in the alsa buffer */
-	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
-	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
-};
-
-/*
- * Alsa card structure for aic23
- */
-struct snd_card_omap_codec {
-	struct snd_card *card;
-	struct snd_pcm *pcm;
-	long samplerate;
-	struct audio_stream s[2];	/* playback & capture */
-};
-
-/* Codec specific information and function pointers.
- * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
- * are responsible for defining the function pointers.
- */
-struct omap_alsa_codec_config {
-	char 	*name;
-	struct	omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
-	struct	snd_pcm_hw_constraint_list *hw_constraints_rates;
-	struct	snd_pcm_hardware *snd_omap_alsa_playback;
-	struct	snd_pcm_hardware *snd_omap_alsa_capture;
-	void	(*codec_configure_dev)(void);
-	void	(*codec_set_samplerate)(long);
-	void	(*codec_clock_setup)(void);
-	int	(*codec_clock_on)(void);
-	int 	(*codec_clock_off)(void);
-	int	(*get_default_samplerate)(void);
-};
-
-/*********** Mixer function prototypes *************************/
-int snd_omap_mixer(struct snd_card_omap_codec *);
-void snd_omap_init_mixer(void);
-
-#ifdef CONFIG_PM
-void snd_omap_suspend_mixer(void);
-void snd_omap_resume_mixer(void);
-#endif
-
-int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
-int snd_omap_alsa_remove(struct platform_device *pdev);
-#ifdef CONFIG_PM
-int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
-int snd_omap_alsa_resume(struct platform_device *pdev);
-#else
-#define snd_omap_alsa_suspend	NULL
-#define snd_omap_alsa_resume	NULL
-#endif
-
-void callback_omap_alsa_sound_dma(void *);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap_device.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap_device.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap_device.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap_device.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,141 +0,0 @@
-/*
- * omap_device headers
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * Developed in collaboration with (alphabetical order): Benoit
- * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
- * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
- * Woodruff
- *
- * This 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.
- *
- * Eventually this type of functionality should either be
- * a) implemented via arch-specific pointers in platform_device
- * or
- * b) implemented as a proper omap_bus/omap_device in Linux, no more
- *    platform_device
- *
- * omap_device differs from omap_hwmod in that it includes external
- * (e.g., board- and system-level) integration details.  omap_hwmod
- * stores hardware data that is invariant for a given OMAP chip.
- *
- * To do:
- * - GPIO integration
- * - regulator integration
- *
- */
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/omap_hwmod.h>
-
-/* omap_device._state values */
-#define OMAP_DEVICE_STATE_UNKNOWN	0
-#define OMAP_DEVICE_STATE_ENABLED	1
-#define OMAP_DEVICE_STATE_IDLE		2
-#define OMAP_DEVICE_STATE_SHUTDOWN	3
-
-/**
- * struct omap_device - omap_device wrapper for platform_devices
- * @pdev: platform_device
- * @hwmods: (one .. many per omap_device)
- * @hwmods_cnt: ARRAY_SIZE() of @hwmods
- * @pm_lats: ptr to an omap_device_pm_latency table
- * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
- * @pm_lat_level: array index of the last odpl entry executed - -1 if never
- * @dev_wakeup_lat: dev wakeup latency in microseconds
- * @_dev_wakeup_lat_limit: dev wakeup latency limit in usec - set by OMAP PM
- * @_state: one of OMAP_DEVICE_STATE_* (see above)
- * @flags: device flags
- *
- * Integrates omap_hwmod data into Linux platform_device.
- *
- * Field names beginning with underscores are for the internal use of
- * the omap_device code.
- *
- */
-struct omap_device {
-	struct platform_device		pdev;
-	struct omap_hwmod		**hwmods;
-	struct omap_device_pm_latency	*pm_lats;
-	u32				dev_wakeup_lat;
-	u32				_dev_wakeup_lat_limit;
-	u8				pm_lats_cnt;
-	s8				pm_lat_level;
-	u8				hwmods_cnt;
-	u8				_state;
-};
-
-/* Device driver interface (call via platform_data fn ptrs) */
-
-int omap_device_enable(struct platform_device *pdev);
-int omap_device_idle(struct platform_device *pdev);
-int omap_device_shutdown(struct platform_device *pdev);
-
-/* Core code interface */
-
-int omap_device_count_resources(struct omap_device *od);
-int omap_device_fill_resources(struct omap_device *od, struct resource *res);
-
-struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
-				      struct omap_hwmod *oh, void *pdata,
-				      int pdata_len,
-				      struct omap_device_pm_latency *pm_lats,
-				      int pm_lats_cnt);
-
-struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
-					 struct omap_hwmod **oh, int oh_cnt,
-					 void *pdata, int pdata_len,
-					 struct omap_device_pm_latency *pm_lats,
-					 int pm_lats_cnt);
-
-int omap_device_register(struct omap_device *od);
-
-/* OMAP PM interface */
-int omap_device_align_pm_lat(struct platform_device *pdev,
-			     u32 new_wakeup_lat_limit);
-struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
-
-/* Other */
-
-int omap_device_idle_hwmods(struct omap_device *od);
-int omap_device_enable_hwmods(struct omap_device *od);
-
-int omap_device_disable_clocks(struct omap_device *od);
-int omap_device_enable_clocks(struct omap_device *od);
-
-
-/*
- * Entries should be kept in latency order ascending
- *
- * deact_lat is the maximum number of microseconds required to complete
- * deactivate_func() at the device's slowest OPP.
- *
- * act_lat is the maximum number of microseconds required to complete
- * activate_func() at the device's slowest OPP.
- *
- * This will result in some suboptimal power management decisions at fast
- * OPPs, but avoids having to recompute all device power management decisions
- * if the system shifts from a fast OPP to a slow OPP (in order to meet
- * latency requirements).
- *
- * XXX should deactivate_func/activate_func() take platform_device pointers
- * rather than omap_device pointers?
- */
-struct omap_device_pm_latency {
-	u32 deactivate_lat;
-	int (*deactivate_func)(struct omap_device *od);
-	u32 activate_lat;
-	int (*activate_func)(struct omap_device *od);
-};
-
-
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omapfb.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omapfb.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omapfb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omapfb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,398 +0,0 @@
-/*
- * File: arch/arm/plat-omap/include/mach/omapfb.h
- *
- * Framebuffer driver for TI OMAP boards
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.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.
- */
-
-#ifndef __OMAPFB_H
-#define __OMAPFB_H
-
-#include <asm/ioctl.h>
-#include <asm/types.h>
-
-/* IOCTL commands. */
-
-#define OMAP_IOW(num, dtype)	_IOW('O', num, dtype)
-#define OMAP_IOR(num, dtype)	_IOR('O', num, dtype)
-#define OMAP_IOWR(num, dtype)	_IOWR('O', num, dtype)
-#define OMAP_IO(num)		_IO('O', num)
-
-#define OMAPFB_MIRROR		OMAP_IOW(31, int)
-#define OMAPFB_SYNC_GFX		OMAP_IO(37)
-#define OMAPFB_VSYNC		OMAP_IO(38)
-#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, int)
-#define OMAPFB_GET_CAPS		OMAP_IOR(42, struct omapfb_caps)
-#define OMAPFB_GET_UPDATE_MODE	OMAP_IOW(43, int)
-#define OMAPFB_LCD_TEST		OMAP_IOW(45, int)
-#define OMAPFB_CTRL_TEST	OMAP_IOW(46, int)
-#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
-#define OMAPFB_SET_COLOR_KEY	OMAP_IOW(50, struct omapfb_color_key)
-#define OMAPFB_GET_COLOR_KEY	OMAP_IOW(51, struct omapfb_color_key)
-#define OMAPFB_SETUP_PLANE	OMAP_IOW(52, struct omapfb_plane_info)
-#define OMAPFB_QUERY_PLANE	OMAP_IOW(53, struct omapfb_plane_info)
-#define OMAPFB_UPDATE_WINDOW	OMAP_IOW(54, struct omapfb_update_window)
-#define OMAPFB_SETUP_MEM	OMAP_IOW(55, struct omapfb_mem_info)
-#define OMAPFB_QUERY_MEM	OMAP_IOW(56, struct omapfb_mem_info)
-
-#define OMAPFB_CAPS_GENERIC_MASK	0x00000fff
-#define OMAPFB_CAPS_LCDC_MASK		0x00fff000
-#define OMAPFB_CAPS_PANEL_MASK		0xff000000
-
-#define OMAPFB_CAPS_MANUAL_UPDATE	0x00001000
-#define OMAPFB_CAPS_TEARSYNC		0x00002000
-#define OMAPFB_CAPS_PLANE_RELOCATE_MEM	0x00004000
-#define OMAPFB_CAPS_PLANE_SCALE		0x00008000
-#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE	0x00010000
-#define OMAPFB_CAPS_WINDOW_SCALE	0x00020000
-#define OMAPFB_CAPS_WINDOW_OVERLAY	0x00040000
-#define OMAPFB_CAPS_WINDOW_ROTATE	0x00080000
-#define OMAPFB_CAPS_SET_BACKLIGHT	0x01000000
-
-/* Values from DSP must map to lower 16-bits */
-#define OMAPFB_FORMAT_MASK		0x00ff
-#define OMAPFB_FORMAT_FLAG_DOUBLE	0x0100
-#define OMAPFB_FORMAT_FLAG_TEARSYNC	0x0200
-#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC	0x0400
-#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY	0x0800
-#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY	0x1000
-
-#define OMAPFB_EVENT_READY	1
-#define OMAPFB_EVENT_DISABLED	2
-
-#define OMAPFB_MEMTYPE_SDRAM		0
-#define OMAPFB_MEMTYPE_SRAM		1
-#define OMAPFB_MEMTYPE_MAX		1
-
-enum omapfb_color_format {
-	OMAPFB_COLOR_RGB565 = 0,
-	OMAPFB_COLOR_YUV422,
-	OMAPFB_COLOR_YUV420,
-	OMAPFB_COLOR_CLUT_8BPP,
-	OMAPFB_COLOR_CLUT_4BPP,
-	OMAPFB_COLOR_CLUT_2BPP,
-	OMAPFB_COLOR_CLUT_1BPP,
-	OMAPFB_COLOR_RGB444,
-	OMAPFB_COLOR_YUY422,
-};
-
-struct omapfb_update_window {
-	__u32 x, y;
-	__u32 width, height;
-	__u32 format;
-	__u32 out_x, out_y;
-	__u32 out_width, out_height;
-	__u32 reserved[8];
-};
-
-struct omapfb_update_window_old {
-	__u32 x, y;
-	__u32 width, height;
-	__u32 format;
-};
-
-enum omapfb_plane {
-	OMAPFB_PLANE_GFX = 0,
-	OMAPFB_PLANE_VID1,
-	OMAPFB_PLANE_VID2,
-};
-
-enum omapfb_channel_out {
-	OMAPFB_CHANNEL_OUT_LCD = 0,
-	OMAPFB_CHANNEL_OUT_DIGIT,
-};
-
-struct omapfb_plane_info {
-	__u32 pos_x;
-	__u32 pos_y;
-	__u8  enabled;
-	__u8  channel_out;
-	__u8  mirror;
-	__u8  reserved1;
-	__u32 out_width;
-	__u32 out_height;
-	__u32 reserved2[12];
-};
-
-struct omapfb_mem_info {
-	__u32 size;
-	__u8  type;
-	__u8  reserved[3];
-};
-
-struct omapfb_caps {
-	__u32 ctrl;
-	__u32 plane_color;
-	__u32 wnd_color;
-};
-
-enum omapfb_color_key_type {
-	OMAPFB_COLOR_KEY_DISABLED = 0,
-	OMAPFB_COLOR_KEY_GFX_DST,
-	OMAPFB_COLOR_KEY_VID_SRC,
-};
-
-struct omapfb_color_key {
-	__u8  channel_out;
-	__u32 background;
-	__u32 trans_key;
-	__u8  key_type;
-};
-
-enum omapfb_update_mode {
-	OMAPFB_UPDATE_DISABLED = 0,
-	OMAPFB_AUTO_UPDATE,
-	OMAPFB_MANUAL_UPDATE
-};
-
-#ifdef __KERNEL__
-
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/mutex.h>
-
-#include <mach/board.h>
-
-#define OMAP_LCDC_INV_VSYNC             0x0001
-#define OMAP_LCDC_INV_HSYNC             0x0002
-#define OMAP_LCDC_INV_PIX_CLOCK         0x0004
-#define OMAP_LCDC_INV_OUTPUT_EN         0x0008
-#define OMAP_LCDC_HSVS_RISING_EDGE      0x0010
-#define OMAP_LCDC_HSVS_OPPOSITE         0x0020
-
-#define OMAP_LCDC_SIGNAL_MASK		0x003f
-
-#define OMAP_LCDC_PANEL_TFT		0x0100
-
-#define OMAPFB_PLANE_XRES_MIN		8
-#define OMAPFB_PLANE_YRES_MIN		8
-
-#ifdef CONFIG_ARCH_OMAP1
-#define OMAPFB_PLANE_NUM		1
-#else
-#define OMAPFB_PLANE_NUM		3
-#endif
-
-struct omapfb_device;
-
-struct lcd_panel {
-	const char	*name;
-	int		config;		/* TFT/STN, signal inversion */
-	int		bpp;		/* Pixel format in fb mem */
-	int		data_lines;	/* Lines on LCD HW interface */
-
-	int		x_res, y_res;
-	int		pixel_clock;	/* In kHz */
-	int		hsw;		/* Horizontal synchronization
-					   pulse width */
-	int		hfp;		/* Horizontal front porch */
-	int		hbp;		/* Horizontal back porch */
-	int		vsw;		/* Vertical synchronization
-					   pulse width */
-	int		vfp;		/* Vertical front porch */
-	int		vbp;		/* Vertical back porch */
-	int		acb;		/* ac-bias pin frequency */
-	int		pcd;		/* pixel clock divider.
-					   Obsolete use pixel_clock instead */
-
-	int		(*init)		(struct lcd_panel *panel,
-					 struct omapfb_device *fbdev);
-	void		(*cleanup)	(struct lcd_panel *panel);
-	int		(*enable)	(struct lcd_panel *panel);
-	void		(*disable)	(struct lcd_panel *panel);
-	unsigned long	(*get_caps)	(struct lcd_panel *panel);
-	int		(*set_bklight_level)(struct lcd_panel *panel,
-					     unsigned int level);
-	unsigned int	(*get_bklight_level)(struct lcd_panel *panel);
-	unsigned int	(*get_bklight_max)  (struct lcd_panel *panel);
-	int		(*run_test)	(struct lcd_panel *panel, int test_num);
-};
-
-struct extif_timings {
-	int cs_on_time;
-	int cs_off_time;
-	int we_on_time;
-	int we_off_time;
-	int re_on_time;
-	int re_off_time;
-	int we_cycle_time;
-	int re_cycle_time;
-	int cs_pulse_width;
-	int access_time;
-
-	int clk_div;
-
-	u32 tim[5];		/* set by extif->convert_timings */
-
-	int converted;
-};
-
-struct lcd_ctrl_extif {
-	int  (*init)		(struct omapfb_device *fbdev);
-	void (*cleanup)		(void);
-	void (*get_clk_info)	(u32 *clk_period, u32 *max_clk_div);
-	unsigned long (*get_max_tx_rate)(void);
-	int  (*convert_timings)	(struct extif_timings *timings);
-	void (*set_timings)	(const struct extif_timings *timings);
-	void (*set_bits_per_cycle)(int bpc);
-	void (*write_command)	(const void *buf, unsigned int len);
-	void (*read_data)	(void *buf, unsigned int len);
-	void (*write_data)	(const void *buf, unsigned int len);
-	void (*transfer_area)	(int width, int height,
-				 void (callback)(void * data), void *data);
-	int  (*setup_tearsync)	(unsigned pin_cnt,
-				 unsigned hs_pulse_time, unsigned vs_pulse_time,
-				 int hs_pol_inv, int vs_pol_inv, int div);
-	int  (*enable_tearsync) (int enable, unsigned line);
-
-	unsigned long		max_transmit_size;
-};
-
-struct omapfb_notifier_block {
-	struct notifier_block	nb;
-	void			*data;
-	int			plane_idx;
-};
-
-typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
-					  unsigned long event,
-					  void *fbi);
-
-struct omapfb_mem_region {
-	u32		paddr;
-	void __iomem	*vaddr;
-	unsigned long	size;
-	u8		type;		/* OMAPFB_PLANE_MEM_* */
-	unsigned	alloc:1;	/* allocated by the driver */
-	unsigned	map:1;		/* kernel mapped by the driver */
-};
-
-struct omapfb_mem_desc {
-	int				region_cnt;
-	struct omapfb_mem_region	region[OMAPFB_PLANE_NUM];
-};
-
-struct lcd_ctrl {
-	const char	*name;
-	void		*data;
-
-	int		(*init)		  (struct omapfb_device *fbdev,
-					   int ext_mode,
-					   struct omapfb_mem_desc *req_md);
-	void		(*cleanup)	  (void);
-	void		(*bind_client)	  (struct omapfb_notifier_block *nb);
-	void		(*get_caps)	  (int plane, struct omapfb_caps *caps);
-	int		(*set_update_mode)(enum omapfb_update_mode mode);
-	enum omapfb_update_mode (*get_update_mode)(void);
-	int		(*setup_plane)	  (int plane, int channel_out,
-					   unsigned long offset,
-					   int screen_width,
-					   int pos_x, int pos_y, int width,
-					   int height, int color_mode);
-	int		(*set_rotate)	  (int angle);
-	int		(*setup_mem)	  (int plane, size_t size,
-					   int mem_type, unsigned long *paddr);
-	int		(*mmap)		  (struct fb_info *info,
-					   struct vm_area_struct *vma);
-	int		(*set_scale)	  (int plane,
-					   int orig_width, int orig_height,
-					   int out_width, int out_height);
-	int		(*enable_plane)	  (int plane, int enable);
-	int		(*update_window)  (struct fb_info *fbi,
-					   struct omapfb_update_window *win,
-					   void (*callback)(void *),
-					   void *callback_data);
-	void		(*sync)		  (void);
-	void		(*suspend)	  (void);
-	void		(*resume)	  (void);
-	int		(*run_test)	  (int test_num);
-	int		(*setcolreg)	  (u_int regno, u16 red, u16 green,
-					   u16 blue, u16 transp,
-					   int update_hw_mem);
-	int		(*set_color_key)  (struct omapfb_color_key *ck);
-	int		(*get_color_key)  (struct omapfb_color_key *ck);
-};
-
-enum omapfb_state {
-	OMAPFB_DISABLED	= 0,
-	OMAPFB_SUSPENDED= 99,
-	OMAPFB_ACTIVE	= 100
-};
-
-struct omapfb_plane_struct {
-	int				idx;
-	struct omapfb_plane_info	info;
-	enum omapfb_color_format	color_mode;
-	struct omapfb_device		*fbdev;
-};
-
-struct omapfb_device {
-	int			state;
-	int                     ext_lcdc;               /* Using external
-                                                           LCD controller */
-	struct mutex		rqueue_mutex;
-
-	int			palette_size;
-	u32			pseudo_palette[17];
-
-	struct lcd_panel	*panel;			/* LCD panel */
-	const struct lcd_ctrl	*ctrl;			/* LCD controller */
-	const struct lcd_ctrl	*int_ctrl;		/* internal LCD ctrl */
-	struct lcd_ctrl_extif	*ext_if;		/* LCD ctrl external
-							   interface */
-	struct device		*dev;
-	struct fb_var_screeninfo	new_var;	/* for mode changes */
-
-	struct omapfb_mem_desc		mem_desc;
-	struct fb_info			*fb_info[OMAPFB_PLANE_NUM];
-};
-
-struct omapfb_platform_data {
-	struct omap_lcd_config		lcd;
-	struct omapfb_mem_desc		mem_desc;
-	void				*ctrl_platform_data;
-};
-
-#ifdef CONFIG_ARCH_OMAP1
-extern struct lcd_ctrl omap1_lcd_ctrl;
-#else
-extern struct lcd_ctrl omap2_disp_ctrl;
-#endif
-
-extern void omapfb_reserve_sdram(void);
-extern void omapfb_register_panel(struct lcd_panel *panel);
-extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
-extern void omapfb_notify_clients(struct omapfb_device *fbdev,
-				  unsigned long event);
-extern int  omapfb_register_client(struct omapfb_notifier_block *nb,
-				   omapfb_notifier_callback_t callback,
-				   void *callback_data);
-extern int  omapfb_unregister_client(struct omapfb_notifier_block *nb);
-extern int  omapfb_update_window_async(struct fb_info *fbi,
-				       struct omapfb_update_window *win,
-				       void (*callback)(void *),
-				       void *callback_data);
-
-/* in arch/arm/plat-omap/fb.c */
-extern void omapfb_set_ctrl_platform_data(void *pdata);
-
-#endif /* __KERNEL__ */
-
-#endif /* __OMAPFB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap_hwmod.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap_hwmod.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap_hwmod.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap_hwmod.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,447 +0,0 @@
-/*
- * omap_hwmod macros, structures
- *
- * Copyright (C) 2009 Nokia Corporation
- * Paul Walmsley
- *
- * Created in collaboration with (alphabetical order): Benoit Cousson,
- * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
- * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
- *
- * This 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.
- *
- * These headers and macros are used to define OMAP on-chip module
- * data and their integration with other OMAP modules and Linux.
- *
- * References:
- * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
- * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
- * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
- * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
- * - Open Core Protocol Specification 2.2
- *
- * To do:
- * - add interconnect error log structures
- * - add pinmuxing
- * - init_conn_id_bit (CONNID_BIT_VECTOR)
- * - implement default hwmod SMS/SDRC flags?
- *
- */
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-
-#include <mach/cpu.h>
-
-struct omap_device;
-
-/* OCP SYSCONFIG bit shifts/masks */
-#define SYSC_MIDLEMODE_SHIFT		12
-#define SYSC_MIDLEMODE_MASK		(0x3 << SYSC_MIDLEMODE_SHIFT)
-#define SYSC_CLOCKACTIVITY_SHIFT	8
-#define SYSC_CLOCKACTIVITY_MASK		(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
-#define SYSC_SIDLEMODE_SHIFT		3
-#define SYSC_SIDLEMODE_MASK		(0x3 << SYSC_SIDLEMODE_SHIFT)
-#define SYSC_ENAWAKEUP_SHIFT		2
-#define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
-#define SYSC_SOFTRESET_SHIFT		1
-#define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
-
-/* OCP SYSSTATUS bit shifts/masks */
-#define SYSS_RESETDONE_SHIFT		0
-#define SYSS_RESETDONE_MASK		(1 << SYSS_RESETDONE_SHIFT)
-
-/* Master standby/slave idle mode flags */
-#define HWMOD_IDLEMODE_FORCE		(1 << 0)
-#define HWMOD_IDLEMODE_NO		(1 << 1)
-#define HWMOD_IDLEMODE_SMART		(1 << 2)
-
-
-/**
- * struct omap_hwmod_dma_info - MPU address space handled by the hwmod
- * @name: name of the DMA channel (module local name)
- * @dma_ch: DMA channel ID
- *
- * @name should be something short, e.g., "tx" or "rx".  It is for use
- * by platform_get_resource_byname().  It is defined locally to the
- * hwmod.
- */
-struct omap_hwmod_dma_info {
-	const char	*name;
-	u16		dma_ch;
-};
-
-/**
- * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
- * @role: "sys", "32k", "tv", etc -- for use in clk_get()
- * @clkdev_dev_id: opt clock: clkdev dev_id string
- * @clkdev_con_id: opt clock: clkdev con_id string
- * @_clk: pointer to the struct clk (filled in at runtime)
- *
- * The module's interface clock and main functional clock should not
- * be added as optional clocks.
- */
-struct omap_hwmod_opt_clk {
-	const char	*role;
-	const char	*clkdev_dev_id;
-	const char	*clkdev_con_id;
-	struct clk	*_clk;
-};
-
-
-/* omap_hwmod_omap2_firewall.flags bits */
-#define OMAP_FIREWALL_L3		(1 << 0)
-#define OMAP_FIREWALL_L4		(1 << 1)
-
-/**
- * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
- * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
- * @l4_fw_region: L4 firewall region ID
- * @l4_prot_group: L4 protection group ID
- * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
- */
-struct omap_hwmod_omap2_firewall {
-	u8 l3_perm_bit;
-	u8 l4_fw_region;
-	u8 l4_prot_group;
-	u8 flags;
-};
-
-
-/*
- * omap_hwmod_addr_space.flags bits
- *
- * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
- * ADDR_TYPE_RT: Address space contains module register target data.
- */
-#define ADDR_MAP_ON_INIT	(1 << 0)
-#define ADDR_TYPE_RT		(1 << 1)
-
-/**
- * struct omap_hwmod_addr_space - MPU address space handled by the hwmod
- * @pa_start: starting physical address
- * @pa_end: ending physical address
- * @flags: (see omap_hwmod_addr_space.flags macros above)
- *
- * Address space doesn't necessarily follow physical interconnect
- * structure.  GPMC is one example.
- */
-struct omap_hwmod_addr_space {
-	u32 pa_start;
-	u32 pa_end;
-	u8 flags;
-};
-
-
-/*
- * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
- * interface to interact with the hwmod.  Used to add sleep dependencies
- * when the module is enabled or disabled.
- */
-#define OCP_USER_MPU			(1 << 0)
-#define OCP_USER_SDMA			(1 << 1)
-
-/* omap_hwmod_ocp_if.flags bits */
-#define OCPIF_HAS_IDLEST		(1 << 0)
-#define OCPIF_SWSUP_IDLE		(1 << 1)
-#define OCPIF_CAN_BURST			(1 << 2)
-
-/**
- * struct omap_hwmod_ocp_if - OCP interface data
- * @master: struct omap_hwmod that initiates OCP transactions on this link
- * @slave: struct omap_hwmod that responds to OCP transactions on this link
- * @addr: address space associated with this link
- * @clkdev_dev_id: interface clock: clkdev dev_id string
- * @clkdev_con_id: interface clock: clkdev con_id string
- * @_clk: pointer to the interface struct clk (filled in at runtime)
- * @fw: interface firewall data
- * @addr_cnt: ARRAY_SIZE(@addr)
- * @width: OCP data width
- * @thread_cnt: number of threads
- * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
- * @user: initiators using this interface (see OCP_USER_* macros above)
- * @flags: OCP interface flags (see OCPIF_* macros above)
- *
- * It may also be useful to add a tag_cnt field for OCP2.x devices.
- *
- * Parameter names beginning with an underscore are managed internally by
- * the omap_hwmod code and should not be set during initialization.
- */
-struct omap_hwmod_ocp_if {
-	struct omap_hwmod		*master;
-	struct omap_hwmod		*slave;
-	struct omap_hwmod_addr_space	*addr;
-	const char			*clkdev_dev_id;
-	const char			*clkdev_con_id;
-	struct clk			*_clk;
-	union {
-		struct omap_hwmod_omap2_firewall omap2;
-	}				fw;
-	u8				addr_cnt;
-	u8				width;
-	u8				thread_cnt;
-	u8				max_burst_len;
-	u8				user;
-	u8				flags;
-};
-
-
-/* Macros for use in struct omap_hwmod_sysconfig */
-
-/* Flags for use in omap_hwmod_sysconfig.idlemodes */
-#define MASTER_STANDBY_SHIFT	2
-#define SLAVE_IDLE_SHIFT	0
-#define SIDLE_FORCE		(HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
-#define SIDLE_NO		(HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
-#define SIDLE_SMART		(HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
-#define MSTANDBY_FORCE		(HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
-#define MSTANDBY_NO		(HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
-#define MSTANDBY_SMART		(HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
-
-/* omap_hwmod_sysconfig.sysc_flags capability flags */
-#define SYSC_HAS_AUTOIDLE	(1 << 0)
-#define SYSC_HAS_SOFTRESET	(1 << 1)
-#define SYSC_HAS_ENAWAKEUP	(1 << 2)
-#define SYSC_HAS_EMUFREE	(1 << 3)
-#define SYSC_HAS_CLOCKACTIVITY	(1 << 4)
-#define SYSC_HAS_SIDLEMODE	(1 << 5)
-#define SYSC_HAS_MIDLEMODE	(1 << 6)
-#define SYSS_MISSING		(1 << 7)
-
-/* omap_hwmod_sysconfig.clockact flags */
-#define CLOCKACT_TEST_BOTH	0x0
-#define CLOCKACT_TEST_MAIN	0x1
-#define CLOCKACT_TEST_ICLK	0x2
-#define CLOCKACT_TEST_NONE	0x3
-
-/**
- * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
- * @rev_offs: IP block revision register offset (from module base addr)
- * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
- * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
- * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
- * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
- * @clockact: the default value of the module CLOCKACTIVITY bits
- *
- * @clockact describes to the module which clocks are likely to be
- * disabled when the PRCM issues its idle request to the module.  Some
- * modules have separate clockdomains for the interface clock and main
- * functional clock, and can check whether they should acknowledge the
- * idle request based on the internal module functionality that has
- * been associated with the clocks marked in @clockact.  This field is
- * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
- *
- */
-struct omap_hwmod_sysconfig {
-	u16 rev_offs;
-	u16 sysc_offs;
-	u16 syss_offs;
-	u8 idlemodes;
-	u8 sysc_flags;
-	u8 clockact;
-};
-
-/**
- * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
- * @module_offs: PRCM submodule offset from the start of the PRM/CM
- * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
- * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
- * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
- * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
- * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
- *
- * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
- * WKEN, GRPSEL registers.  In an ideal world, no extra information
- * would be needed for IDLEST information, but alas, there are some
- * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
- * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
- */
-struct omap_hwmod_omap2_prcm {
-	s16 module_offs;
-	u8 prcm_reg_id;
-	u8 module_bit;
-	u8 idlest_reg_id;
-	u8 idlest_idle_bit;
-	u8 idlest_stdby_bit;
-};
-
-
-/**
- * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
- * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2
- * @device_offs: device register offset from @module_offs
- * @submodule_wkdep_bit: bit shift of the WKDEP range
- */
-struct omap_hwmod_omap4_prcm {
-	u32 module_offs;
-	u16 device_offs;
-	u8 submodule_wkdep_bit;
-};
-
-
-/*
- * omap_hwmod.flags definitions
- *
- * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
- *     of idle, rather than relying on module smart-idle
- * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
- *     of standby, rather than relying on module smart-standby
- * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
- *     SDRAM controller, etc.
- * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
- *     controller, etc.
- * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
- */
-#define HWMOD_SWSUP_SIDLE			(1 << 0)
-#define HWMOD_SWSUP_MSTANDBY			(1 << 1)
-#define HWMOD_INIT_NO_RESET			(1 << 2)
-#define HWMOD_INIT_NO_IDLE			(1 << 3)
-#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 4)
-
-/*
- * omap_hwmod._int_flags definitions
- * These are for internal use only and are managed by the omap_hwmod code.
- *
- * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
- * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
- * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
- */
-#define _HWMOD_NO_MPU_PORT			(1 << 0)
-#define _HWMOD_WAKEUP_ENABLED			(1 << 1)
-#define _HWMOD_SYSCONFIG_LOADED			(1 << 2)
-
-/*
- * omap_hwmod._state definitions
- *
- * INITIALIZED: reset (optionally), initialized, enabled, disabled
- *              (optionally)
- *
- *
- */
-#define _HWMOD_STATE_UNKNOWN			0
-#define _HWMOD_STATE_REGISTERED			1
-#define _HWMOD_STATE_CLKS_INITED		2
-#define _HWMOD_STATE_INITIALIZED		3
-#define _HWMOD_STATE_ENABLED			4
-#define _HWMOD_STATE_IDLE			5
-#define _HWMOD_STATE_DISABLED			6
-
-/**
- * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
- * @name: name of the hwmod
- * @od: struct omap_device currently associated with this hwmod (internal use)
- * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
- * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
- * @prcm: PRCM data pertaining to this hwmod
- * @clkdev_dev_id: main clock: clkdev dev_id string
- * @clkdev_con_id: main clock: clkdev con_id string
- * @_clk: pointer to the main struct clk (filled in at runtime)
- * @opt_clks: other device clocks that drivers can request (0..*)
- * @masters: ptr to array of OCP ifs that this hwmod can initiate on
- * @slaves: ptr to array of OCP ifs that this hwmod can respond on
- * @sysconfig: device SYSCONFIG/SYSSTATUS register data
- * @dev_attr: arbitrary device attributes that can be passed to the driver
- * @_sysc_cache: internal-use hwmod flags
- * @_rt_va: cached register target start address (internal use)
- * @_mpu_port_index: cached MPU register target slave ID (internal use)
- * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
- * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
- * @mpu_irqs_cnt: number of @mpu_irqs
- * @sdma_chs_cnt: number of @sdma_chs
- * @opt_clks_cnt: number of @opt_clks
- * @master_cnt: number of @master entries
- * @slaves_cnt: number of @slave entries
- * @response_lat: device OCP response latency (in interface clock cycles)
- * @_int_flags: internal-use hwmod flags
- * @_state: internal-use hwmod state
- * @flags: hwmod flags (documented below)
- * @omap_chip: OMAP chips this hwmod is present on
- * @node: list node for hwmod list (internal use)
- *
- * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
- * clock," which for our purposes is defined as "the functional clock needed
- * for register accesses to complete."  Modules may not have a main clock if
- * the interface clock also serves as a main clock.
- *
- * Parameter names beginning with an underscore are managed internally by
- * the omap_hwmod code and should not be set during initialization.
- */
-struct omap_hwmod {
-	const char			*name;
-	struct omap_device		*od;
-	u8				*mpu_irqs;
-	struct omap_hwmod_dma_info	*sdma_chs;
-	union {
-		struct omap_hwmod_omap2_prcm omap2;
-		struct omap_hwmod_omap4_prcm omap4;
-	}				prcm;
-	const char			*clkdev_dev_id;
-	const char			*clkdev_con_id;
-	struct clk			*_clk;
-	struct omap_hwmod_opt_clk	*opt_clks;
-	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
-	struct omap_hwmod_ocp_if	**slaves;  /* connect to *_TA */
-	struct omap_hwmod_sysconfig	*sysconfig;
-	void				*dev_attr;
-	u32				_sysc_cache;
-	void __iomem			*_rt_va;
-	struct list_head		node;
-	u16				flags;
-	u8				_mpu_port_index;
-	u8				msuspendmux_reg_id;
-	u8				msuspendmux_shift;
-	u8				response_lat;
-	u8				mpu_irqs_cnt;
-	u8				sdma_chs_cnt;
-	u8				opt_clks_cnt;
-	u8				masters_cnt;
-	u8				slaves_cnt;
-	u8				hwmods_cnt;
-	u8				_int_flags;
-	u8				_state;
-	const struct omap_chip_id	omap_chip;
-};
-
-int omap_hwmod_init(struct omap_hwmod **ohs);
-int omap_hwmod_register(struct omap_hwmod *oh);
-int omap_hwmod_unregister(struct omap_hwmod *oh);
-struct omap_hwmod *omap_hwmod_lookup(const char *name);
-int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
-int omap_hwmod_late_init(void);
-
-int omap_hwmod_enable(struct omap_hwmod *oh);
-int omap_hwmod_idle(struct omap_hwmod *oh);
-int omap_hwmod_shutdown(struct omap_hwmod *oh);
-
-int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
-int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
-
-int omap_hwmod_reset(struct omap_hwmod *oh);
-void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
-
-void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
-u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
-
-int omap_hwmod_count_resources(struct omap_hwmod *oh);
-int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
-
-struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
-
-int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
-				 struct omap_hwmod *init_oh);
-int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
-				 struct omap_hwmod *init_oh);
-
-int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
-
-int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
-int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap-pm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap-pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/omap-pm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/omap-pm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,301 +0,0 @@
-/*
- * omap-pm.h - OMAP power management interface
- *
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- * Paul Walmsley
- *
- * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
- * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
- * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
- * Richard Woodruff
- */
-
-#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
-#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
-
-#include <linux/device.h>
-#include <linux/cpufreq.h>
-
-#include "powerdomain.h"
-
-/**
- * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
- * @rate: target clock rate
- * @opp_id: OPP ID
- * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
- *
- * Operating performance point data.  Can vary by OMAP chip and board.
- */
-struct omap_opp {
-	unsigned long rate;
-	u8 opp_id;
-	u16 min_vdd;
-};
-
-extern struct omap_opp *mpu_opps;
-extern struct omap_opp *dsp_opps;
-extern struct omap_opp *l3_opps;
-
-/*
- * agent_id values for use with omap_pm_set_min_bus_tput():
- *
- * OCP_INITIATOR_AGENT is only valid for devices that can act as
- * initiators -- it represents the device's L3 interconnect
- * connection.  OCP_TARGET_AGENT represents the device's L4
- * interconnect connection.
- */
-#define OCP_TARGET_AGENT		1
-#define OCP_INITIATOR_AGENT		2
-
-/**
- * omap_pm_if_early_init - OMAP PM init code called before clock fw init
- * @mpu_opp_table: array ptr to struct omap_opp for MPU
- * @dsp_opp_table: array ptr to struct omap_opp for DSP
- * @l3_opp_table : array ptr to struct omap_opp for CORE
- *
- * Initialize anything that must be configured before the clock
- * framework starts.  The "_if_" is to avoid name collisions with the
- * PM idle-loop code.
- */
-int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
-				 struct omap_opp *dsp_opp_table,
-				 struct omap_opp *l3_opp_table);
-
-/**
- * omap_pm_if_init - OMAP PM init code called after clock fw init
- *
- * The main initialization code.  OPP tables are passed in here.  The
- * "_if_" is to avoid name collisions with the PM idle-loop code.
- */
-int __init omap_pm_if_init(void);
-
-/**
- * omap_pm_if_exit - OMAP PM exit code
- *
- * Exit code; currently unused.  The "_if_" is to avoid name
- * collisions with the PM idle-loop code.
- */
-void omap_pm_if_exit(void);
-
-/*
- * Device-driver-originated constraints (via board-*.c files, platform_data)
- */
-
-
-/**
- * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
- * @t: maximum MPU wakeup latency in microseconds
- *
- * Request that the maximum interrupt latency for the MPU to be no
- * greater than 't' microseconds. "Interrupt latency" in this case is
- * defined as the elapsed time from the occurrence of a hardware or
- * timer interrupt to the time when the device driver's interrupt
- * service routine has been entered by the MPU.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the MPU powerdomain into, and
- * possibly the CORE powerdomain as well, since interrupt handling
- * code currently runs from SDRAM.  Advanced PM or board*.c code may
- * also configure interrupt controller priorities, OCP bus priorities,
- * CPU speed(s), etc.
- *
- * This function will not affect device wakeup latency, e.g., time
- * elapsed from when a device driver enables a hardware device with
- * clk_enable(), to when the device is ready for register access or
- * other use.  To control this device wakeup latency, use
- * set_max_dev_wakeup_lat()
- *
- * Multiple calls to set_max_mpu_wakeup_lat() will replace the
- * previous t value.  To remove the latency target for the MPU, call
- * with t = -1.
- *
- * No return value.
- */
-void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
- * @dev: struct device * requesting the constraint
- * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
- * @r: minimum throughput (in KiB/s)
- *
- * Request that the minimum data throughput on the OCP interconnect
- * attached to device 'dev' interconnect agent 'tbus_id' be no less
- * than 'r' KiB/s.
- *
- * It is expected that the OMAP PM or bus code will use this
- * information to set the interconnect clock to run at the lowest
- * possible speed that satisfies all current system users.  The PM or
- * bus code will adjust the estimate based on its model of the bus, so
- * device driver authors should attempt to specify an accurate
- * quantity for their device use case, and let the PM or bus code
- * overestimate the numbers as necessary to handle request/response
- * latency, other competing users on the system, etc.  On OMAP2/3, if
- * a driver requests a minimum L4 interconnect speed constraint, the
- * code will also need to add an minimum L3 interconnect speed
- * constraint,
- *
- * Multiple calls to set_min_bus_tput() will replace the previous rate
- * value for this device.  To remove the interconnect throughput
- * restriction for this device, call with r = 0.
- *
- * No return value.
- */
-void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
-
-
-/**
- * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @dev: struct device *
- * @t: maximum device wakeup latency in microseconds
- *
- * Request that the maximum amount of time necessary for a device to
- * become accessible after its clocks are enabled should be no greater
- * than 't' microseconds.  Specifically, this represents the time from
- * when a device driver enables device clocks with clk_enable(), to
- * when the register reads and writes on the device will succeed.
- * This function should be called before clk_disable() is called,
- * since the power state transition decision may be made during
- * clk_disable().
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the powerdomain enclosing this
- * device into.
- *
- * Multiple calls to set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device.  To remove the wakeup
- * latency restriction for this device, call with t = -1.
- *
- * No return value.
- */
-void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
- * @t: maximum DMA transfer start latency in microseconds
- *
- * Request that the maximum system DMA transfer start latency for this
- * device 'dev' should be no greater than 't' microseconds.  "DMA
- * transfer start latency" here is defined as the elapsed time from
- * when a device (e.g., McBSP) requests that a system DMA transfer
- * start or continue, to the time at which data starts to flow into
- * that device from the system DMA controller.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the CORE powerdomain into.
- *
- * Since system DMA transfers may not involve the MPU, this function
- * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
- * so.  Similarly, this function will not affect device wakeup latency
- * -- use set_max_dev_wakeup_lat() to affect that.
- *
- * Multiple calls to set_max_sdma_lat() will replace the previous t
- * value for this device.  To remove the maximum DMA latency for this
- * device, call with t = -1.
- *
- * No return value.
- */
-void omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
-
-/*
- * DSP Bridge-specific constraints
- */
-
-/**
- * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
- *
- * Intended for use by DSPBridge.  Returns an array of OPP->DSP clock
- * frequency entries.  The final item in the array should have .rate =
- * .opp_id = 0.
- */
-const struct omap_opp *omap_pm_dsp_get_opp_table(void);
-
-/**
- * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
- * @opp_id: target DSP OPP ID
- *
- * Set a minimum OPP ID for the DSP.  This is intended to be called
- * only from the DSP Bridge MPU-side driver.  Unfortunately, the only
- * information that code receives from the DSP/BIOS load estimator is the
- * target OPP ID; hence, this interface.  No return value.
- */
-void omap_pm_dsp_set_min_opp(u8 opp_id);
-
-/**
- * omap_pm_dsp_get_opp - report the current DSP OPP ID
- *
- * Report the current OPP for the DSP.  Since on OMAP3, the DSP and
- * MPU share a single voltage domain, the OPP ID returned back may
- * represent a higher DSP speed than the OPP requested via
- * omap_pm_dsp_set_min_opp().
- *
- * Returns the current VDD1 OPP ID, or 0 upon error.
- */
-u8 omap_pm_dsp_get_opp(void);
-
-
-/*
- * CPUFreq-originated constraint
- *
- * In the future, this should be handled by custom OPP clocktype
- * functions.
- */
-
-/**
- * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
- *
- * Provide a frequency table usable by CPUFreq for the current chip/board.
- * Returns a pointer to a struct cpufreq_frequency_table array or NULL
- * upon error.
- */
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
-
-/**
- * omap_pm_cpu_set_freq - set the current minimum MPU frequency
- * @f: MPU frequency in Hz
- *
- * Set the current minimum CPU frequency.  The actual CPU frequency
- * used could end up higher if the DSP requested a higher OPP.
- * Intended to be called by plat-omap/cpu_omap.c:omap_target().  No
- * return value.
- */
-void omap_pm_cpu_set_freq(unsigned long f);
-
-/**
- * omap_pm_cpu_get_freq - report the current CPU frequency
- *
- * Returns the current MPU frequency, or 0 upon error.
- */
-unsigned long omap_pm_cpu_get_freq(void);
-
-
-/*
- * Device context loss tracking
- */
-
-/**
- * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
- * @dev: struct device *
- *
- * This function returns the number of times that the device @dev has
- * lost its internal context.  This generally occurs on a powerdomain
- * transition to OFF.  Drivers use this as an optimization to avoid restoring
- * context if the device hasn't lost it.  To use, drivers should initially
- * call this in their context save functions and store the result.  Early in
- * the driver's context restore function, the driver should call this function
- * again, and compare the result to the stored counter.  If they differ, the
- * driver must restore device context.   If the number of context losses
- * exceeds the maximum positive integer, the function will wrap to 0 and
- * continue counting.  Returns the number of context losses for this device,
- * or -EINVAL upon error.
- */
-int omap_pm_get_dev_context_loss_count(struct device *dev);
-
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/onenand.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/onenand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/onenand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/onenand.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/onenand.h
- *
- * Copyright (C) 2006 Nokia Corporation
- * Author: Juha Yrjola
- *
- * This 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/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define ONENAND_SYNC_READ	(1 << 0)
-#define ONENAND_SYNC_READWRITE	(1 << 1)
-
-struct omap_onenand_platform_data {
-	int			cs;
-	int			gpio_irq;
-	struct mtd_partition	*parts;
-	int			nr_parts;
-	int                     (*onenand_setup)(void __iomem *, int freq);
-	int			dma_channel;
-	u8			flags;
-};
-
-#define ONENAND_MAX_PARTITIONS 8
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
-
-extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
-
-#else
-
-#define board_onenand_data	NULL
-
-static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
-{
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/param.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/param.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/param.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/param.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/param.h
- *
- */
-
-#ifdef CONFIG_OMAP_32K_TIMER_HZ
-#define HZ	CONFIG_OMAP_32K_TIMER_HZ
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,182 +0,0 @@
-/*
- * OMAP2/3 powerdomain control
- *
- * Copyright (C) 2007-8 Texas Instruments, Inc.
- * Copyright (C) 2007-8 Nokia Corporation
- *
- * Written by Paul Walmsley
- *
- * This 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_ARM_ARCH_OMAP_POWERDOMAIN
-#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
-
-#include <linux/types.h>
-#include <linux/list.h>
-
-#include <asm/atomic.h>
-
-#include <mach/cpu.h>
-
-
-/* Powerdomain basic power states */
-#define PWRDM_POWER_OFF		0x0
-#define PWRDM_POWER_RET		0x1
-#define PWRDM_POWER_INACTIVE	0x2
-#define PWRDM_POWER_ON		0x3
-
-/* Powerdomain allowable state bitfields */
-#define PWRSTS_OFF_ON		((1 << PWRDM_POWER_OFF) | \
-				 (1 << PWRDM_POWER_ON))
-
-#define PWRSTS_OFF_RET		((1 << PWRDM_POWER_OFF) | \
-				 (1 << PWRDM_POWER_RET))
-
-#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
-
-
-/* Powerdomain flags */
-#define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */
-
-
-/*
- * Number of memory banks that are power-controllable.	On OMAP3430, the
- * maximum is 4.
- */
-#define PWRDM_MAX_MEM_BANKS	4
-
-/*
- * Maximum number of clockdomains that can be associated with a powerdomain.
- * CORE powerdomain on OMAP3 is the worst case
- */
-#define PWRDM_MAX_CLKDMS	4
-
-/* XXX A completely arbitrary number. What is reasonable here? */
-#define PWRDM_TRANSITION_BAILOUT 100000
-
-struct clockdomain;
-struct powerdomain;
-
-/* Encodes dependencies between powerdomains - statically defined */
-struct pwrdm_dep {
-
-	/* Powerdomain name */
-	const char *pwrdm_name;
-
-	/* Powerdomain pointer - resolved by the powerdomain code */
-	struct powerdomain *pwrdm;
-
-	/* Flags to mark OMAP chip restrictions, etc. */
-	const struct omap_chip_id omap_chip;
-
-};
-
-struct powerdomain {
-
-	/* Powerdomain name */
-	const char *name;
-
-	/* the address offset from CM_BASE/PRM_BASE */
-	const s16 prcm_offs;
-
-	/* Used to represent the OMAP chip types containing this pwrdm */
-	const struct omap_chip_id omap_chip;
-
-	/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
-	const u8 dep_bit;
-
-	/* Powerdomains that can be told to wake this powerdomain up */
-	struct pwrdm_dep *wkdep_srcs;
-
-	/* Powerdomains that can be told to keep this pwrdm from inactivity */
-	struct pwrdm_dep *sleepdep_srcs;
-
-	/* Possible powerdomain power states */
-	const u8 pwrsts;
-
-	/* Possible logic power states when pwrdm in RETENTION */
-	const u8 pwrsts_logic_ret;
-
-	/* Powerdomain flags */
-	const u8 flags;
-
-	/* Number of software-controllable memory banks in this powerdomain */
-	const u8 banks;
-
-	/* Possible memory bank pwrstates when pwrdm in RETENTION */
-	const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
-
-	/* Possible memory bank pwrstates when pwrdm is ON */
-	const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
-
-	/* Clockdomains in this powerdomain */
-	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
-
-	struct list_head node;
-
-	int state;
-	unsigned state_counter[4];
-
-#ifdef CONFIG_PM_DEBUG
-	s64 timer;
-	s64 state_timer[4];
-#endif
-};
-
-
-void pwrdm_init(struct powerdomain **pwrdm_list);
-
-int pwrdm_register(struct powerdomain *pwrdm);
-int pwrdm_unregister(struct powerdomain *pwrdm);
-struct powerdomain *pwrdm_lookup(const char *name);
-
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
-			void *user);
-
-int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
-			 int (*fn)(struct powerdomain *pwrdm,
-				   struct clockdomain *clkdm));
-
-int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
-
-int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
-
-int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
-int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
-
-int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
-int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
-
-int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
-int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
-
-int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
-int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
-bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
-
-int pwrdm_wait_transition(struct powerdomain *pwrdm);
-
-int pwrdm_state_switch(struct powerdomain *pwrdm);
-int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
-int pwrdm_pre_transition(void);
-int pwrdm_post_transition(void);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/prcm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/prcm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/prcm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/prcm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/prcm.h
- *
- * Access definations for use in OMAP24XX clock and power management
- *
- * Copyright (C) 2005 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 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_ARCH_OMAP_PRCM_H
-#define __ASM_ARM_ARCH_OMAP_PRCM_H
-
-u32 omap_prcm_get_reset_sources(void);
-void omap_prcm_arch_reset(char mode);
-int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
-
-#endif
-
-
-
-
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/sdrc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/sdrc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/sdrc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/sdrc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,143 +0,0 @@
-#ifndef ____ASM_ARCH_SDRC_H
-#define ____ASM_ARCH_SDRC_H
-
-/*
- * OMAP2/3 SDRC/SMS register definitions
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
- *
- * Tony Lindgren
- * Paul Walmsley
- * Richard Woodruff
- *
- * This 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 <mach/io.h>
-
-/* SDRC register offsets - read/write with sdrc_{read,write}_reg() */
-
-#define SDRC_SYSCONFIG		0x010
-#define SDRC_CS_CFG		0x040
-#define SDRC_SHARING		0x044
-#define SDRC_ERR_TYPE		0x04C
-#define SDRC_DLLA_CTRL		0x060
-#define SDRC_DLLA_STATUS	0x064
-#define SDRC_DLLB_CTRL		0x068
-#define SDRC_DLLB_STATUS	0x06C
-#define SDRC_POWER		0x070
-#define SDRC_MCFG_0		0x080
-#define SDRC_MR_0		0x084
-#define SDRC_EMR2_0		0x08c
-#define SDRC_ACTIM_CTRL_A_0	0x09c
-#define SDRC_ACTIM_CTRL_B_0	0x0a0
-#define SDRC_RFR_CTRL_0		0x0a4
-#define SDRC_MANUAL_0		0x0a8
-#define SDRC_MCFG_1		0x0B0
-#define SDRC_MR_1		0x0B4
-#define SDRC_EMR2_1		0x0BC
-#define SDRC_ACTIM_CTRL_A_1	0x0C4
-#define SDRC_ACTIM_CTRL_B_1	0x0C8
-#define SDRC_RFR_CTRL_1		0x0D4
-#define SDRC_MANUAL_1		0x0D8
-
-/*
- * These values represent the number of memory clock cycles between
- * autorefresh initiation.  They assume 1 refresh per 64 ms (JEDEC), 8192
- * rows per device, and include a subtraction of a 50 cycle window in the
- * event that the autorefresh command is delayed due to other SDRC activity.
- * The '| 1' sets the ARE field to send one autorefresh when the autorefresh
- * counter reaches 0.
- *
- * These represent optimal values for common parts, it won't work for all.
- * As long as you scale down, most parameters are still work, they just
- * become sub-optimal. The RFR value goes in the opposite direction. If you
- * don't adjust it down as your clock period increases the refresh interval
- * will not be met. Setting all parameters for complete worst case may work,
- * but may cut memory performance by 2x. Due to errata the DLLs need to be
- * unlocked and their value needs run time calibration.	A dynamic call is
- * need for that as no single right value exists acorss production samples.
- *
- * Only the FULL speed values are given. Current code is such that rate
- * changes must be made at DPLLoutx2. The actual value adjustment for low
- * frequency operation will be handled by omap_set_performance()
- *
- * By having the boot loader boot up in the fastest L4 speed available likely
- * will result in something which you can switch between.
- */
-#define SDRC_RFR_CTRL_165MHz	(0x00044c00 | 1)
-#define SDRC_RFR_CTRL_133MHz	(0x0003de00 | 1)
-#define SDRC_RFR_CTRL_100MHz	(0x0002da01 | 1)
-#define SDRC_RFR_CTRL_110MHz	(0x0002da01 | 1) /* Need to calc */
-#define SDRC_RFR_CTRL_BYPASS	(0x00005000 | 1) /* Need to calc */
-
-
-/*
- * SMS register access
- */
-
-#define OMAP242X_SMS_REGADDR(reg)					\
-			(void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE + reg)
-#define OMAP243X_SMS_REGADDR(reg)					\
-			(void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE + reg)
-#define OMAP343X_SMS_REGADDR(reg)					\
-			(void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE + reg)
-
-/* SMS register offsets - read/write with sms_{read,write}_reg() */
-
-#define SMS_SYSCONFIG		0x010
-/* REVISIT: fill in other SMS registers here */
-
-
-#ifndef __ASSEMBLER__
-
-/**
- * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
- * @rate: SDRC clock rate (in Hz)
- * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
- * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
- * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
- * @mr: Value to program to SDRC_MR for this rate
- *
- * This structure holds a pre-computed set of register values for the
- * SDRC for a given SDRC clock rate and SDRAM chip.  These are
- * intended to be pre-computed and specified in an array in the board-*.c
- * files.  The structure is keyed off the 'rate' field.
- */
-struct omap_sdrc_params {
-	unsigned long rate;
-	u32 actim_ctrla;
-	u32 actim_ctrlb;
-	u32 rfr_ctrl;
-	u32 mr;
-};
-
-void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
-			    struct omap_sdrc_params *sdrc_cs1);
-int omap2_sdrc_get_params(unsigned long r,
-			  struct omap_sdrc_params **sdrc_cs0,
-			  struct omap_sdrc_params **sdrc_cs1);
-
-#ifdef CONFIG_ARCH_OMAP2
-
-struct memory_timings {
-	u32 m_type;		/* ddr = 1, sdr = 0 */
-	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
-	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
-	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
-	u32 base_cs;		/* base chip select to use for calculations */
-};
-
-extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
-
-u32 omap2xxx_sdrc_dll_is_unlocked(void);
-u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
-
-#endif  /* CONFIG_ARCH_OMAP2 */
-
-#endif  /* __ASSEMBLER__ */
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/serial.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/serial.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/serial.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/serial.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/serial.h
- *
- * Copyright (C) 2009 Texas Instruments
- * Addded OMAP4 support- Santosh Shilimkar <santosh.shilimkar@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.
- */
-
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-#include <linux/init.h>
-
-#if defined(CONFIG_ARCH_OMAP1)
-/* OMAP1 serial ports */
-#define OMAP_UART1_BASE		0xfffb0000
-#define OMAP_UART2_BASE		0xfffb0800
-#define OMAP_UART3_BASE		0xfffb9800
-#define OMAP_MAX_NR_PORTS	3
-#elif defined(CONFIG_ARCH_OMAP2)
-/* OMAP2 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x4806e000
-#define OMAP_MAX_NR_PORTS	3
-#elif defined(CONFIG_ARCH_OMAP3)
-/* OMAP3 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x49020000
-#define OMAP_MAX_NR_PORTS	3
-#elif defined(CONFIG_ARCH_OMAP4)
-/* OMAP4 serial ports */
-#define OMAP_UART1_BASE		0x4806a000
-#define OMAP_UART2_BASE		0x4806c000
-#define OMAP_UART3_BASE		0x48020000
-#define OMAP_UART4_BASE		0x4806e000
-#define OMAP_MAX_NR_PORTS	4
-#endif
-
-#define OMAP1510_BASE_BAUD	(12000000/16)
-#define OMAP16XX_BASE_BAUD	(48000000/16)
-#define OMAP24XX_BASE_BAUD	(48000000/16)
-
-#define is_omap_port(pt)	({int __ret = 0;			\
-			if ((pt)->port.mapbase == OMAP_UART1_BASE ||	\
-			    (pt)->port.mapbase == OMAP_UART2_BASE ||	\
-			    (pt)->port.mapbase == OMAP_UART3_BASE)	\
-				__ret = 1;				\
-			__ret;						\
-			})
-
-#ifndef __ASSEMBLER__
-extern void __init omap_serial_early_init(void);
-extern void omap_serial_init(void);
-extern int omap_uart_can_sleep(void);
-extern void omap_uart_check_wakeup(void);
-extern void omap_uart_prepare_suspend(void);
-extern void omap_uart_prepare_idle(int num);
-extern void omap_uart_resume_idle(int num);
-extern void omap_uart_enable_irqs(int enable);
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/smp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/smp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/smp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- * OMAP4 machine specific smp.h
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Author:
- *	Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Interface functions needed for the SMP. This file is based on arm
- * realview smp platform.
- * 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 version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef OMAP_ARCH_SMP_H
-#define OMAP_ARCH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/*
- * set_event() is used to wake up secondary core from wfe using sev. ROM
- * code puts the second core into wfe(standby).
- *
- */
-#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
-
-/* Needed for secondary core boot */
-extern void omap_secondary_startup(void);
-
-/*
- * We use Soft IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask)
-{
-	gic_raise_softirq(mask, 1);
-}
-
-/*
- * Read MPIDR: Multiprocessor affinity register
- */
-#define hard_smp_processor_id()			\
-	({						\
-		unsigned int cpunum;			\
-		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
-			: "=r" (cpunum));		\
-		cpunum &= 0x0F;				\
-	})
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/sram.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/sram.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/sram.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/sram.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/sram.h
- *
- * Interface for functions that need to be run in internal SRAM
- *
- * This 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_OMAP_SRAM_H
-#define __ARCH_ARM_OMAP_SRAM_H
-
-extern int __init omap_sram_init(void);
-extern void * omap_sram_push(void * start, unsigned long size);
-extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
-
-extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
-				u32 base_cs, u32 force_unlock);
-extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
-				      u32 mem_type);
-extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
-
-extern u32 omap3_configure_core_dpll(
-			u32 m2, u32 unlock_dll, u32 f, u32 inc,
-			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
-
-/* Do not use these */
-extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
-extern unsigned long omap1_sram_reprogram_clock_sz;
-
-extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
-extern unsigned long omap24xx_sram_reprogram_clock_sz;
-
-extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
-						u32 base_cs, u32 force_unlock);
-extern unsigned long omap242x_sram_ddr_init_sz;
-
-extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
-						int bypass);
-extern unsigned long omap242x_sram_set_prcm_sz;
-
-extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
-						u32 mem_type);
-extern unsigned long omap242x_sram_reprogram_sdrc_sz;
-
-
-extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
-						u32 base_cs, u32 force_unlock);
-extern unsigned long omap243x_sram_ddr_init_sz;
-
-extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
-						int bypass);
-extern unsigned long omap243x_sram_set_prcm_sz;
-
-extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
-						u32 mem_type);
-extern unsigned long omap243x_sram_reprogram_sdrc_sz;
-
-extern u32 omap3_sram_configure_core_dpll(
-			u32 m2, u32 unlock_dll, u32 f, u32 inc,
-			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
-extern unsigned long omap3_sram_configure_core_dpll_sz;
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/system.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- * Copied from arch/arm/mach-sa1100/include/mach/system.h
- * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-#include <linux/clk.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include <mach/prcm.h>
-
-#ifndef CONFIG_MACH_VOICEBLUE
-#define voiceblue_reset()		do {} while (0)
-#else
-extern void voiceblue_reset(void);
-#endif
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-static inline void omap1_arch_reset(char mode)
-{
-	/*
-	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
-	 * "Global Software Reset Affects Traffic Controller Frequency".
-	 */
-	if (cpu_is_omap5912()) {
-		omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4),
-				 DPLL_CTL);
-		omap_writew(0x8, ARM_RSTCT1);
-	}
-
-	if (machine_is_voiceblue())
-		voiceblue_reset();
-	else
-		omap_writew(1, ARM_RSTCT1);
-}
-
-static inline void arch_reset(char mode, const char *cmd)
-{
-	if (!cpu_class_is_omap2())
-		omap1_arch_reset(mode);
-	else
-		omap_prcm_arch_reset(mode);
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/tc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/tc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/tc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/tc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,106 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/tc.h
- *
- * OMAP Traffic Controller
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.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.
- */
-
-#ifndef __ASM_ARCH_TC_H
-#define __ASM_ARCH_TC_H
-
-#define TCMIF_BASE		0xfffecc00
-#define OMAP_TC_OCPT1_PRIOR	(TCMIF_BASE + 0x00)
-#define OMAP_TC_EMIFS_PRIOR	(TCMIF_BASE + 0x04)
-#define OMAP_TC_EMIFF_PRIOR	(TCMIF_BASE + 0x08)
-#define EMIFS_CONFIG		(TCMIF_BASE + 0x0c)
-#define EMIFS_CS0_CONFIG	(TCMIF_BASE + 0x10)
-#define EMIFS_CS1_CONFIG	(TCMIF_BASE + 0x14)
-#define EMIFS_CS2_CONFIG	(TCMIF_BASE + 0x18)
-#define EMIFS_CS3_CONFIG	(TCMIF_BASE + 0x1c)
-#define EMIFF_SDRAM_CONFIG	(TCMIF_BASE + 0x20)
-#define EMIFF_MRS		(TCMIF_BASE + 0x24)
-#define TC_TIMEOUT1		(TCMIF_BASE + 0x28)
-#define TC_TIMEOUT2		(TCMIF_BASE + 0x2c)
-#define TC_TIMEOUT3		(TCMIF_BASE + 0x30)
-#define TC_ENDIANISM		(TCMIF_BASE + 0x34)
-#define EMIFF_SDRAM_CONFIG_2	(TCMIF_BASE + 0x3c)
-#define EMIF_CFG_DYNAMIC_WS	(TCMIF_BASE + 0x40)
-#define EMIFS_ACS0		(TCMIF_BASE + 0x50)
-#define EMIFS_ACS1		(TCMIF_BASE + 0x54)
-#define EMIFS_ACS2		(TCMIF_BASE + 0x58)
-#define EMIFS_ACS3		(TCMIF_BASE + 0x5c)
-#define OMAP_TC_OCPT2_PRIOR	(TCMIF_BASE + 0xd0)
-
-/* external EMIFS chipselect regions */
-#define	OMAP_CS0_PHYS		0x00000000
-#define	OMAP_CS0_SIZE		SZ_64M
-
-#define	OMAP_CS1_PHYS		0x04000000
-#define	OMAP_CS1_SIZE		SZ_64M
-
-#define	OMAP_CS1A_PHYS		OMAP_CS1_PHYS
-#define	OMAP_CS1A_SIZE		SZ_32M
-
-#define	OMAP_CS1B_PHYS		(OMAP_CS1A_PHYS + OMAP_CS1A_SIZE)
-#define	OMAP_CS1B_SIZE		SZ_32M
-
-#define	OMAP_CS2_PHYS		0x08000000
-#define	OMAP_CS2_SIZE		SZ_64M
-
-#define	OMAP_CS2A_PHYS		OMAP_CS2_PHYS
-#define	OMAP_CS2A_SIZE		SZ_32M
-
-#define	OMAP_CS2B_PHYS		(OMAP_CS2A_PHYS + OMAP_CS2A_SIZE)
-#define	OMAP_CS2B_SIZE		SZ_32M
-
-#define	OMAP_CS3_PHYS		0x0c000000
-#define	OMAP_CS3_SIZE		SZ_64M
-
-#ifndef	__ASSEMBLER__
-
-/* EMIF Slow Interface Configuration Register */
-#define OMAP_EMIFS_CONFIG_FR		(1 << 4)
-#define OMAP_EMIFS_CONFIG_PDE		(1 << 3)
-#define OMAP_EMIFS_CONFIG_PWD_EN	(1 << 2)
-#define OMAP_EMIFS_CONFIG_BM		(1 << 1)
-#define OMAP_EMIFS_CONFIG_WP		(1 << 0)
-
-#define EMIFS_CCS(n)		(EMIFS_CS0_CONFIG + (4 * (n)))
-#define EMIFS_ACS(n)		(EMIFS_ACS0 + (4 * (n)))
-
-/* Almost all documentation for chip and board memory maps assumes
- * BM is clear.  Most devel boards have a switch to control booting
- * from NOR flash (using external chipselect 3) rather than mask ROM,
- * which uses BM to interchange the physical CS0 and CS3 addresses.
- */
-static inline u32 omap_cs0_phys(void)
-{
-	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
-			?  OMAP_CS3_PHYS : 0;
-}
-
-static inline u32 omap_cs3_phys(void)
-{
-	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
-			? 0 : OMAP_CS3_PHYS;
-}
-
-#endif	/* __ASSEMBLER__ */
-
-#endif	/* __ASM_ARCH_TC_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/*
- * OMAP2/3 GPTIMER support.headers
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * 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.
- */
-
-#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
-#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
-
-int __init omap2_gp_clockevent_set_gptimer(u8 id);
-
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/timex.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/timex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/timex.h
- *
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author:  Greg Lonnon <glonnon@ridgerun.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 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.
- */
-
-#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
-#define __ASM_ARCH_OMAP_TIMEX_H
-
-/*
- * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
- * and that's why the CLOCK_TICK_RATE is not 32768.
- */
-#ifdef CONFIG_OMAP_32K_TIMER
-#define CLOCK_TICK_RATE		(CONFIG_OMAP_32K_TIMER_HZ)
-#else
-#define CLOCK_TICK_RATE		(HZ * 100000UL)
-#endif
-
-#endif /* __ASM_ARCH_OMAP_TIMEX_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/uncompress.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,83 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/uncompress.h
- *
- * Serial port stubs for kernel decompress status messages
- *
- * Initially based on:
- * linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Rewritten by:
- * Author: <source@mvista.com>
- * 2004 (c) MontaVista Software, 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/types.h>
-#include <linux/serial_reg.h>
-#include <mach/serial.h>
-
-unsigned int system_rev;
-
-#define UART_OMAP_MDR1		0x08	/* mode definition register */
-#define OMAP_ID_730		0x355F
-#define ID_MASK			0x7fff
-#define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
-#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
-
-static void putc(int c)
-{
-	volatile u8 * uart = 0;
-	int shift = 2;
-
-#ifdef CONFIG_MACH_OMAP_PALMTE
-	return;
-#endif
-
-#ifdef CONFIG_ARCH_OMAP
-#ifdef	CONFIG_OMAP_LL_DEBUG_UART3
-	uart = (volatile u8 *)(OMAP_UART3_BASE);
-#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
-	uart = (volatile u8 *)(OMAP_UART2_BASE);
-#else
-	uart = (volatile u8 *)(OMAP_UART1_BASE);
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1
-	/* Determine which serial port to use */
-	do {
-		/* MMU is not on, so cpu_is_omapXXXX() won't work here */
-		unsigned int omap_id = omap_get_id();
-
-		if (omap_id == OMAP_ID_730)
-			shift = 0;
-
-		if (check_port(uart, shift))
-			break;
-		/* Silent boot if no serial ports are enabled. */
-		return;
-	} while (0);
-#endif /* CONFIG_ARCH_OMAP1 */
-#endif
-
-	/*
-	 * Now, xmit each character
-	 */
-	while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
-		barrier();
-	uart[UART_TX << shift] = c;
-}
-
-static inline void flush(void)
-{
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-#define arch_decomp_wdog()
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/usb.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/usb.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/usb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-// include/asm-arm/mach-omap/usb.h
-
-#ifndef	__ASM_ARCH_OMAP_USB_H
-#define	__ASM_ARCH_OMAP_USB_H
-
-#include <mach/board.h>
-
-/*-------------------------------------------------------------------------*/
-
-#define OMAP1_OTG_BASE			0xfffb0400
-#define OMAP1_UDC_BASE			0xfffb4000
-#define OMAP1_OHCI_BASE			0xfffba000
-
-#define OMAP2_OHCI_BASE			0x4805e000
-#define OMAP2_UDC_BASE			0x4805e200
-#define OMAP2_OTG_BASE			0x4805e300
-
-#ifdef CONFIG_ARCH_OMAP1
-
-#define OTG_BASE			OMAP1_OTG_BASE
-#define UDC_BASE			OMAP1_UDC_BASE
-#define OMAP_OHCI_BASE			OMAP1_OHCI_BASE
-
-#else
-
-#define OTG_BASE			OMAP2_OTG_BASE
-#define UDC_BASE			OMAP2_UDC_BASE
-#define OMAP_OHCI_BASE			OMAP2_OHCI_BASE
-
-extern void usb_musb_init(void);
-
-#endif
-
-void omap_usb_init(struct omap_usb_config *pdata);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * OTG and transceiver registers, for OMAPs starting with ARM926
- */
-#define OTG_REV				(OTG_BASE + 0x00)
-#define OTG_SYSCON_1			(OTG_BASE + 0x04)
-#	define	 USB2_TRX_MODE(w)	(((w)>>24)&0x07)
-#	define	 USB1_TRX_MODE(w)	(((w)>>20)&0x07)
-#	define	 USB0_TRX_MODE(w)	(((w)>>16)&0x07)
-#	define	 OTG_IDLE_EN		(1 << 15)
-#	define	 HST_IDLE_EN		(1 << 14)
-#	define	 DEV_IDLE_EN		(1 << 13)
-#	define	 OTG_RESET_DONE		(1 << 2)
-#	define	 OTG_SOFT_RESET		(1 << 1)
-#define OTG_SYSCON_2			(OTG_BASE + 0x08)
-#	define	 OTG_EN			(1 << 31)
-#	define	 USBX_SYNCHRO		(1 << 30)
-#	define	 OTG_MST16		(1 << 29)
-#	define	 SRP_GPDATA		(1 << 28)
-#	define	 SRP_GPDVBUS		(1 << 27)
-#	define	 SRP_GPUVBUS(w)		(((w)>>24)&0x07)
-#	define	 A_WAIT_VRISE(w)	(((w)>>20)&0x07)
-#	define	 B_ASE_BRST(w)		(((w)>>16)&0x07)
-#	define	 SRP_DPW		(1 << 14)
-#	define	 SRP_DATA		(1 << 13)
-#	define	 SRP_VBUS		(1 << 12)
-#	define	 OTG_PADEN		(1 << 10)
-#	define	 HMC_PADEN		(1 << 9)
-#	define	 UHOST_EN		(1 << 8)
-#	define	 HMC_TLLSPEED		(1 << 7)
-#	define	 HMC_TLLATTACH		(1 << 6)
-#	define	 OTG_HMC(w)		(((w)>>0)&0x3f)
-#define OTG_CTRL			(OTG_BASE + 0x0c)
-#	define	 OTG_USB2_EN		(1 << 29)
-#	define	 OTG_USB2_DP		(1 << 28)
-#	define	 OTG_USB2_DM		(1 << 27)
-#	define	 OTG_USB1_EN		(1 << 26)
-#	define	 OTG_USB1_DP		(1 << 25)
-#	define	 OTG_USB1_DM		(1 << 24)
-#	define	 OTG_USB0_EN		(1 << 23)
-#	define	 OTG_USB0_DP		(1 << 22)
-#	define	 OTG_USB0_DM		(1 << 21)
-#	define	 OTG_ASESSVLD		(1 << 20)
-#	define	 OTG_BSESSEND		(1 << 19)
-#	define	 OTG_BSESSVLD		(1 << 18)
-#	define	 OTG_VBUSVLD		(1 << 17)
-#	define	 OTG_ID			(1 << 16)
-#	define	 OTG_DRIVER_SEL		(1 << 15)
-#	define	 OTG_A_SETB_HNPEN	(1 << 12)
-#	define	 OTG_A_BUSREQ		(1 << 11)
-#	define	 OTG_B_HNPEN		(1 << 9)
-#	define	 OTG_B_BUSREQ		(1 << 8)
-#	define	 OTG_BUSDROP		(1 << 7)
-#	define	 OTG_PULLDOWN		(1 << 5)
-#	define	 OTG_PULLUP		(1 << 4)
-#	define	 OTG_DRV_VBUS		(1 << 3)
-#	define	 OTG_PD_VBUS		(1 << 2)
-#	define	 OTG_PU_VBUS		(1 << 1)
-#	define	 OTG_PU_ID		(1 << 0)
-#define OTG_IRQ_EN			(OTG_BASE + 0x10)	/* 16-bit */
-#	define	 DRIVER_SWITCH		(1 << 15)
-#	define	 A_VBUS_ERR		(1 << 13)
-#	define	 A_REQ_TMROUT		(1 << 12)
-#	define	 A_SRP_DETECT		(1 << 11)
-#	define	 B_HNP_FAIL		(1 << 10)
-#	define	 B_SRP_TMROUT		(1 << 9)
-#	define	 B_SRP_DONE		(1 << 8)
-#	define	 B_SRP_STARTED		(1 << 7)
-#	define	 OPRT_CHG		(1 << 0)
-#define OTG_IRQ_SRC			(OTG_BASE + 0x14)	/* 16-bit */
-	// same bits as in IRQ_EN
-#define OTG_OUTCTRL			(OTG_BASE + 0x18)	/* 16-bit */
-#	define	 OTGVPD			(1 << 14)
-#	define	 OTGVPU			(1 << 13)
-#	define	 OTGPUID		(1 << 12)
-#	define	 USB2VDR		(1 << 10)
-#	define	 USB2PDEN		(1 << 9)
-#	define	 USB2PUEN		(1 << 8)
-#	define	 USB1VDR		(1 << 6)
-#	define	 USB1PDEN		(1 << 5)
-#	define	 USB1PUEN		(1 << 4)
-#	define	 USB0VDR		(1 << 2)
-#	define	 USB0PDEN		(1 << 1)
-#	define	 USB0PUEN		(1 << 0)
-#define OTG_TEST			(OTG_BASE + 0x20)	/* 16-bit */
-#define OTG_VENDOR_CODE			(OTG_BASE + 0xfc)	/* 16-bit */
-
-/*-------------------------------------------------------------------------*/
-
-/* OMAP1 */
-#define	USB_TRANSCEIVER_CTRL		(0xfffe1000 + 0x0064)
-#	define	CONF_USB2_UNI_R		(1 << 8)
-#	define	CONF_USB1_UNI_R		(1 << 7)
-#	define	CONF_USB_PORT0_R(x)	(((x)>>4)&0x7)
-#	define	CONF_USB0_ISOLATE_R	(1 << 3)
-#	define	CONF_USB_PWRDN_DM_R	(1 << 2)
-#	define	CONF_USB_PWRDN_DP_R	(1 << 1)
-
-/* OMAP2 */
-#	define	USB_UNIDIR			0x0
-#	define	USB_UNIDIR_TLL			0x1
-#	define	USB_BIDIR			0x2
-#	define	USB_BIDIR_TLL			0x3
-#	define	USBTXWRMODEI(port, x)	((x) << (22 - (port * 2)))
-#	define	USBT2TLL5PI		(1 << 17)
-#	define	USB0PUENACTLOI		(1 << 16)
-#	define	USBSTANDBYCTRL		(1 << 15)
-
-#endif	/* __ASM_ARCH_OMAP_USB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/vmalloc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/vmalloc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/mach/vmalloc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/vmalloc.h
- *
- *  Copyright (C) 2000 Russell King.
- *
- * 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 VMALLOC_END	  (PAGE_OFFSET + 0x18000000)
-
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/blizzard.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/blizzard.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/blizzard.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/blizzard.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,12 @@
+#ifndef _BLIZZARD_H
+#define _BLIZZARD_H
+
+struct blizzard_platform_data {
+	void		(*power_up)(struct device *dev);
+	void		(*power_down)(struct device *dev);
+	unsigned long	(*get_clock_rate)(struct device *dev);
+
+	unsigned	te_connected : 1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-ams-delta.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-ams-delta.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-ams-delta.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-ams-delta.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-ams-delta.h
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
+#define __ASM_ARCH_OMAP_AMS_DELTA_H
+
+#if defined (CONFIG_MACH_AMS_DELTA)
+
+#define AMS_DELTA_LATCH1_PHYS		0x01000000
+#define AMS_DELTA_LATCH1_VIRT		0xEA000000
+#define AMS_DELTA_MODEM_PHYS		0x04000000
+#define AMS_DELTA_MODEM_VIRT		0xEB000000
+#define AMS_DELTA_LATCH2_PHYS		0x08000000
+#define AMS_DELTA_LATCH2_VIRT		0xEC000000
+
+#define AMS_DELTA_LATCH1_LED_CAMERA	0x01
+#define AMS_DELTA_LATCH1_LED_ADVERT	0x02
+#define AMS_DELTA_LATCH1_LED_EMAIL	0x04
+#define AMS_DELTA_LATCH1_LED_HANDSFREE	0x08
+#define AMS_DELTA_LATCH1_LED_VOICEMAIL	0x10
+#define AMS_DELTA_LATCH1_LED_VOICE	0x20
+
+#define AMS_DELTA_LATCH2_LCD_VBLEN	0x0001
+#define AMS_DELTA_LATCH2_LCD_NDISP	0x0002
+#define AMS_DELTA_LATCH2_NAND_NCE	0x0004
+#define AMS_DELTA_LATCH2_NAND_NRE	0x0008
+#define AMS_DELTA_LATCH2_NAND_NWP	0x0010
+#define AMS_DELTA_LATCH2_NAND_NWE	0x0020
+#define AMS_DELTA_LATCH2_NAND_ALE	0x0040
+#define AMS_DELTA_LATCH2_NAND_CLE	0x0080
+#define AMD_DELTA_LATCH2_KEYBRD_PWR	0x0100
+#define AMD_DELTA_LATCH2_KEYBRD_DATA	0x0200
+#define AMD_DELTA_LATCH2_SCARD_RSTIN	0x0400
+#define AMD_DELTA_LATCH2_SCARD_CMDVCC	0x0800
+#define AMS_DELTA_LATCH2_MODEM_NRESET	0x1000
+#define AMS_DELTA_LATCH2_MODEM_CODEC	0x2000
+
+#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA	0
+#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK	1
+#define AMS_DELTA_GPIO_PIN_MODEM_IRQ	2
+#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH	4
+#define AMS_DELTA_GPIO_PIN_SCARD_NOFF	6
+#define AMS_DELTA_GPIO_PIN_SCARD_IO	7
+#define AMS_DELTA_GPIO_PIN_CONFIG	11
+#define AMS_DELTA_GPIO_PIN_NAND_RB	12
+
+#ifndef __ASSEMBLY__
+void ams_delta_latch1_write(u8 mask, u8 value);
+void ams_delta_latch2_write(u16 mask, u16 value);
+#endif
+
+#endif /* CONFIG_MACH_AMS_DELTA */
+
+#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,168 @@
+/*
+ *  arch/arm/plat-omap/include/mach/board.h
+ *
+ *  Information structures for board-specific data
+ *
+ *  Copyright (C) 2004	Nokia Corporation
+ *  Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ */
+
+#ifndef _OMAP_BOARD_H
+#define _OMAP_BOARD_H
+
+#include <linux/types.h>
+
+#include <plat/gpio-switch.h>
+
+/*
+ * OMAP35x EVM revision
+ * Run time detection of EVM revision is done by reading Ethernet
+ * PHY ID -
+ *	GEN_1	= 0x01150000
+ *	GEN_2	= 0x92200000
+ */
+enum {
+	OMAP3EVM_BOARD_GEN_1 = 0,	/* EVM Rev between  A - D */
+	OMAP3EVM_BOARD_GEN_2,		/* EVM Rev >= Rev E */
+};
+
+/* Different peripheral ids */
+#define OMAP_TAG_CLOCK		0x4f01
+#define OMAP_TAG_LCD		0x4f05
+#define OMAP_TAG_GPIO_SWITCH	0x4f06
+#define OMAP_TAG_FBMEM		0x4f08
+#define OMAP_TAG_STI_CONSOLE	0x4f09
+#define OMAP_TAG_CAMERA_SENSOR	0x4f0a
+
+#define OMAP_TAG_BOOT_REASON    0x4f80
+#define OMAP_TAG_FLASH_PART	0x4f81
+#define OMAP_TAG_VERSION_STR	0x4f82
+
+struct omap_clock_config {
+	/* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
+	u8 system_clock_type;
+};
+
+struct omap_serial_console_config {
+	u8 console_uart;
+	u32 console_speed;
+};
+
+struct omap_sti_console_config {
+	unsigned enable:1;
+	u8 channel;
+};
+
+struct omap_camera_sensor_config {
+	u16 reset_gpio;
+	int (*power_on)(void * data);
+	int (*power_off)(void * data);
+};
+
+struct omap_usb_config {
+	/* Configure drivers according to the connectors on your board:
+	 *  - "A" connector (rectagular)
+	 *	... for host/OHCI use, set "register_host".
+	 *  - "B" connector (squarish) or "Mini-B"
+	 *	... for device/gadget use, set "register_dev".
+	 *  - "Mini-AB" connector (very similar to Mini-B)
+	 *	... for OTG use as device OR host, initialize "otg"
+	 */
+	unsigned	register_host:1;
+	unsigned	register_dev:1;
+	u8		otg;	/* port number, 1-based:  usb1 == 2 */
+
+	u8		hmc_mode;
+
+	/* implicitly true if otg:  host supports remote wakeup? */
+	u8		rwc;
+
+	/* signaling pins used to talk to transceiver on usbN:
+	 *  0 == usbN unused
+	 *  2 == usb0-only, using internal transceiver
+	 *  3 == 3 wire bidirectional
+	 *  4 == 4 wire bidirectional
+	 *  6 == 6 wire unidirectional (or TLL)
+	 */
+	u8		pins[3];
+};
+
+struct omap_lcd_config {
+	char panel_name[16];
+	char ctrl_name[16];
+	s16  nreset_gpio;
+	u8   data_lines;
+};
+
+struct device;
+struct fb_info;
+struct omap_backlight_config {
+	int default_intensity;
+	int (*set_power)(struct device *dev, int state);
+};
+
+struct omap_fbmem_config {
+	u32 start;
+	u32 size;
+};
+
+struct omap_pwm_led_platform_data {
+	const char *name;
+	int intensity_timer;
+	int blink_timer;
+	void (*set_power)(struct omap_pwm_led_platform_data *self, int on_off);
+};
+
+struct omap_uart_config {
+	/* Bit field of UARTs present; bit 0 --> UART1 */
+	unsigned int enabled_uarts;
+};
+
+
+struct omap_flash_part_config {
+	char part_table[0];
+};
+
+struct omap_boot_reason_config {
+	char reason_str[12];
+};
+
+struct omap_version_config {
+	char component[12];
+	char version[12];
+};
+
+struct omap_board_config_entry {
+	u16 tag;
+	u16 len;
+	u8  data[0];
+};
+
+struct omap_board_config_kernel {
+	u16 tag;
+	const void *data;
+};
+
+extern const void *__omap_get_config(u16 tag, size_t len, int nr);
+
+#define omap_get_config(tag, type) \
+	((const type *) __omap_get_config((tag), sizeof(type), 0))
+#define omap_get_nr_config(tag, type, nr) \
+	((const type *) __omap_get_config((tag), sizeof(type), (nr)))
+
+extern const void *omap_get_var_config(u16 tag, size_t *len);
+
+extern struct omap_board_config_kernel *omap_board_config;
+extern int omap_board_config_size;
+
+
+/* for TI reference platforms sharing the same debug card */
+extern int debug_card_init(u32 addr, unsigned gpio);
+
+/* OMAP3EVM revision */
+#if defined(CONFIG_MACH_OMAP3EVM)
+u8 get_omap3_evm_rev(void);
+#else
+#define get_omap3_evm_rev() (-EINVAL)
+#endif
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-sx1.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-sx1.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-sx1.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-sx1.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * Siemens SX1 board definitions
+ *
+ * Copyright: Vovan888 at gmail com
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
+#define __ASM_ARCH_SX1_I2C_CHIPS_H
+
+#define SOFIA_MAX_LIGHT_VAL	0x2B
+
+#define SOFIA_I2C_ADDR		0x32
+/* Sofia reg 3 bits masks */
+#define SOFIA_POWER1_REG	0x03
+
+#define	SOFIA_USB_POWER		0x01
+#define	SOFIA_MMC_POWER		0x04
+#define	SOFIA_BLUETOOTH_POWER	0x08
+#define	SOFIA_MMILIGHT_POWER	0x20
+
+#define SOFIA_POWER2_REG	0x04
+#define SOFIA_BACKLIGHT_REG	0x06
+#define SOFIA_KEYLIGHT_REG	0x07
+#define SOFIA_DIMMING_REG	0x09
+
+
+/* Function Prototypes for SX1 devices control on I2C bus */
+
+int sx1_setbacklight(u8 backlight);
+int sx1_getbacklight(u8 *backlight);
+int sx1_setkeylight(u8 keylight);
+int sx1_getkeylight(u8 *keylight);
+
+int sx1_setmmipower(u8 onoff);
+int sx1_setusbpower(u8 onoff);
+int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
+int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
+
+/* MMC prototypes */
+
+extern void sx1_mmc_init(void);
+extern void sx1_mmc_slot_cover_handler(void *arg, int state);
+
+#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-voiceblue.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-voiceblue.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/board-voiceblue.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/board-voiceblue.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
+ *
+ * Hardware definitions for OMAP5910 based VoiceBlue board.
+ *
+ * This 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_VOICEBLUE_H
+#define __ASM_ARCH_VOICEBLUE_H
+
+extern void voiceblue_wdt_enable(void);
+extern void voiceblue_wdt_disable(void);
+extern void voiceblue_wdt_ping(void);
+
+#endif /*  __ASM_ARCH_VOICEBLUE_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clkdev.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,13 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+static inline int __clk_get(struct clk *clk)
+{
+	return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clkdev_omap.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * clkdev <-> OMAP integration
+ *
+ * Russell King <linux@arm.linux.org.uk>
+ *
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
+
+#include <asm/clkdev.h>
+
+struct omap_clk {
+	u16				cpu;
+	struct clk_lookup		lk;
+};
+
+#define CLK(dev, con, ck, cp) 		\
+	{				\
+		 .cpu = cp,		\
+		.lk = {			\
+			.dev_id = dev,	\
+			.con_id = con,	\
+			.clk = ck,	\
+		},			\
+	}
+
+
+#define CK_310		(1 << 0)
+#define CK_7XX		(1 << 1)
+#define CK_1510		(1 << 2)
+#define CK_16XX		(1 << 3)
+#define CK_243X		(1 << 4)
+#define CK_242X		(1 << 5)
+#define CK_343X		(1 << 6)
+#define CK_3430ES1	(1 << 7)
+#define CK_3430ES2	(1 << 8)
+#define CK_443X		(1 << 9)
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clockdomain.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,111 @@
+/*
+ * arch/arm/plat-omap/include/mach/clockdomain.h
+ *
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This 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_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+
+#include <plat/powerdomain.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* Clockdomain capability flags */
+#define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
+#define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
+#define CLKDM_CAN_ENABLE_AUTO			(1 << 2)
+#define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
+
+#define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
+#define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
+#define CLKDM_CAN_HWSUP_SWSUP	(CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
+
+/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO		0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO		0x1
+
+/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
+#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO		0x0
+#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP		0x1
+#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP		0x2
+#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO		0x3
+
+/*
+ * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
+ * and sleepdeps added when a powerdomain should stay active in hwsup mode;
+ * and conversely, removed when the powerdomain should be allowed to go
+ * inactive in hwsup mode.
+ */
+struct clkdm_pwrdm_autodep {
+
+	union {
+		/* Name of the powerdomain to add a wkdep/sleepdep on */
+		const char *name;
+
+		/* Powerdomain pointer (looked up at clkdm_init() time) */
+		struct powerdomain *ptr;
+	} pwrdm;
+
+	/* OMAP chip types that this clockdomain dep is valid on */
+	const struct omap_chip_id omap_chip;
+
+};
+
+struct clockdomain {
+
+	/* Clockdomain name */
+	const char *name;
+
+	union {
+		/* Powerdomain enclosing this clockdomain */
+		const char *name;
+
+		/* Powerdomain pointer assigned at clkdm_register() */
+		struct powerdomain *ptr;
+	} pwrdm;
+
+	/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
+	const u16 clktrctrl_mask;
+
+	/* Clockdomain capability flags */
+	const u8 flags;
+
+	/* OMAP chip types that this clockdomain is valid on */
+	const struct omap_chip_id omap_chip;
+
+	/* Usecount tracking */
+	atomic_t usecount;
+
+	struct list_head node;
+
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
+int clkdm_register(struct clockdomain *clkdm);
+int clkdm_unregister(struct clockdomain *clkdm);
+struct clockdomain *clkdm_lookup(const char *name);
+
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+			void *user);
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
+
+void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
+void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
+
+int omap2_clkdm_wakeup(struct clockdomain *clkdm);
+int omap2_clkdm_sleep(struct clockdomain *clkdm);
+
+int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clock.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,170 @@
+/*
+ *  arch/arm/plat-omap/include/mach/clock.h
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, 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 __ARCH_ARM_OMAP_CLOCK_H
+#define __ARCH_ARM_OMAP_CLOCK_H
+
+#include <linux/list.h>
+
+struct module;
+struct clk;
+struct clockdomain;
+
+struct clkops {
+	int			(*enable)(struct clk *);
+	void			(*disable)(struct clk *);
+	void			(*find_idlest)(struct clk *, void __iomem **, u8 *);
+	void			(*find_companion)(struct clk *, void __iomem **, u8 *);
+};
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
+		defined(CONFIG_ARCH_OMAP4)
+
+struct clksel_rate {
+	u32			val;
+	u8			div;
+	u8			flags;
+};
+
+struct clksel {
+	struct clk		 *parent;
+	const struct clksel_rate *rates;
+};
+
+struct dpll_data {
+	void __iomem		*mult_div1_reg;
+	u32			mult_mask;
+	u32			div1_mask;
+	struct clk		*clk_bypass;
+	struct clk		*clk_ref;
+	void __iomem		*control_reg;
+	u32			enable_mask;
+	unsigned int		rate_tolerance;
+	unsigned long		last_rounded_rate;
+	u16			last_rounded_m;
+	u8			last_rounded_n;
+	u8			min_divider;
+	u8			max_divider;
+	u32			max_tolerance;
+	u16			max_multiplier;
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+	u8			modes;
+	void __iomem		*autoidle_reg;
+	void __iomem		*idlest_reg;
+	u32			autoidle_mask;
+	u32			freqsel_mask;
+	u32			idlest_mask;
+	u8			auto_recal_bit;
+	u8			recal_en_bit;
+	u8			recal_st_bit;
+#  endif
+};
+
+#endif
+
+struct clk {
+	struct list_head	node;
+	const struct clkops	*ops;
+	const char		*name;
+	int			id;
+	struct clk		*parent;
+	struct list_head	children;
+	struct list_head	sibling;	/* node for children */
+	unsigned long		rate;
+	__u32			flags;
+	void __iomem		*enable_reg;
+	unsigned long		(*recalc)(struct clk *);
+	int			(*set_rate)(struct clk *, unsigned long);
+	long			(*round_rate)(struct clk *, unsigned long);
+	void			(*init)(struct clk *);
+	__u8			enable_bit;
+	__s8			usecount;
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
+		defined(CONFIG_ARCH_OMAP4)
+	u8			fixed_div;
+	void __iomem		*clksel_reg;
+	u32			clksel_mask;
+	const struct clksel	*clksel;
+	struct dpll_data	*dpll_data;
+	const char		*clkdm_name;
+	struct clockdomain	*clkdm;
+#else
+	__u8			rate_offset;
+	__u8			src_offset;
+#endif
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+	struct dentry		*dent;	/* For visible tree hierarchy */
+#endif
+};
+
+struct cpufreq_frequency_table;
+
+struct clk_functions {
+	int		(*clk_enable)(struct clk *clk);
+	void		(*clk_disable)(struct clk *clk);
+	long		(*clk_round_rate)(struct clk *clk, unsigned long rate);
+	int		(*clk_set_rate)(struct clk *clk, unsigned long rate);
+	int		(*clk_set_parent)(struct clk *clk, struct clk *parent);
+	void		(*clk_allow_idle)(struct clk *clk);
+	void		(*clk_deny_idle)(struct clk *clk);
+	void		(*clk_disable_unused)(struct clk *clk);
+#ifdef CONFIG_CPU_FREQ
+	void		(*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
+	void		(*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **);
+#endif
+};
+
+extern unsigned int mpurate;
+
+extern int clk_init(struct clk_functions *custom_clocks);
+extern void clk_preinit(struct clk *clk);
+extern int clk_register(struct clk *clk);
+extern void clk_reparent(struct clk *child, struct clk *parent);
+extern void clk_unregister(struct clk *clk);
+extern void propagate_rate(struct clk *clk);
+extern void recalculate_root_clocks(void);
+extern unsigned long followparent_recalc(struct clk *clk);
+extern void clk_enable_init_clocks(void);
+#ifdef CONFIG_CPU_FREQ
+extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#endif
+
+extern const struct clkops clkops_null;
+
+/* Clock flags */
+/* bit 0 is free */
+#define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
+/* bits 2-4 are free */
+#define ENABLE_REG_32BIT	(1 << 5)	/* Use 32-bit access */
+#define CLOCK_IDLE_CONTROL	(1 << 7)
+#define CLOCK_NO_IDLE_PARENT	(1 << 8)
+#define DELAYED_APP		(1 << 9)	/* Delay application of clock */
+#define CONFIG_PARTICIPANT	(1 << 10)	/* Fundamental clock */
+#define ENABLE_ON_INIT		(1 << 11)	/* Enable upon framework init */
+#define INVERT_ENABLE           (1 << 12)       /* 0 enables, 1 disables */
+#define CLOCK_IN_OMAP4430	(1 << 13)
+#define ALWAYS_ENABLED		(1 << 14)
+/* bits 13-31 are currently free */
+
+/* Clksel_rate flags */
+#define DEFAULT_RATE		(1 << 0)
+#define RATE_IN_242X		(1 << 1)
+#define RATE_IN_243X		(1 << 2)
+#define RATE_IN_343X		(1 << 3)	/* rates common to all 343X */
+#define RATE_IN_3430ES2		(1 << 4)	/* 3430ES2 rates only */
+#define RATE_IN_4430            (1 << 5)
+
+#define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
+
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/common.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/common.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/plat-omap/include/mach/common.h
+ *
+ * Header for code common to all OMAP machines.
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
+#define __ARCH_ARM_MACH_OMAP_COMMON_H
+
+#include <plat/i2c.h>
+
+struct sys_timer;
+
+/* used by omap-smp.c and board-4430sdp.c */
+extern void __iomem *gic_cpu_base_addr;
+
+extern void omap_map_common_io(void);
+extern struct sys_timer omap_timer;
+
+/* IO bases for various OMAP processors */
+struct omap_globals {
+	u32		class;		/* OMAP class to detect */
+	void __iomem	*tap;		/* Control module ID code */
+	void __iomem	*sdrc;		/* SDRAM Controller */
+	void __iomem	*sms;		/* SDRAM Memory Scheduler */
+	void __iomem	*ctrl;		/* System Control Module */
+	void __iomem	*prm;		/* Power and Reset Management */
+	void __iomem	*cm;		/* Clock Management */
+	void __iomem	*cm2;
+};
+
+void omap2_set_globals_242x(void);
+void omap2_set_globals_243x(void);
+void omap2_set_globals_343x(void);
+void omap2_set_globals_443x(void);
+
+/* These get called from omap2_set_globals_xxxx(), do not call these */
+void omap2_set_globals_tap(struct omap_globals *);
+void omap2_set_globals_sdrc(struct omap_globals *);
+void omap2_set_globals_control(struct omap_globals *);
+void omap2_set_globals_prcm(struct omap_globals *);
+
+/**
+ * omap_test_timeout - busy-loop, testing a condition
+ * @cond: condition to test until it evaluates to true
+ * @timeout: maximum number of microseconds in the timeout
+ * @index: loop index (integer)
+ *
+ * Loop waiting for @cond to become true or until at least @timeout
+ * microseconds have passed.  To use, define some integer @index in the
+ * calling code.  After running, if @index == @timeout, then the loop has
+ * timed out.
+ */
+#define omap_test_timeout(cond, timeout, index)			\
+({								\
+	for (index = 0; index < timeout; index++) {		\
+		if (cond)					\
+			break;					\
+		udelay(1);					\
+	}							\
+})
+
+#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/control.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/control.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/control.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/control.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,325 @@
+/*
+ * arch/arm/plat-omap/include/mach/control.h
+ *
+ * OMAP2/3/4 System Control Module definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_CONTROL_H
+#define __ASM_ARCH_CONTROL_H
+
+#include <mach/io.h>
+
+#ifndef __ASSEMBLY__
+#define OMAP242X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#else
+#define OMAP242X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg)					\
+		OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#endif /* __ASSEMBLY__ */
+
+/*
+ * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
+ * OMAP24XX and OMAP34XX.
+ */
+
+/* Control submodule offsets */
+
+#define OMAP2_CONTROL_INTERFACE		0x000
+#define OMAP2_CONTROL_PADCONFS		0x030
+#define OMAP2_CONTROL_GENERAL		0x270
+#define OMAP343X_CONTROL_MEM_WKUP	0x600
+#define OMAP343X_CONTROL_PADCONFS_WKUP	0xa00
+#define OMAP343X_CONTROL_GENERAL_WKUP	0xa60
+
+/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
+
+#define OMAP2_CONTROL_SYSCONFIG		(OMAP2_CONTROL_INTERFACE + 0x10)
+
+/* CONTROL_GENERAL register offsets common to OMAP2 & 3 */
+#define OMAP2_CONTROL_DEVCONF0		(OMAP2_CONTROL_GENERAL + 0x0004)
+#define OMAP2_CONTROL_MSUSPENDMUX_0	(OMAP2_CONTROL_GENERAL + 0x0020)
+#define OMAP2_CONTROL_MSUSPENDMUX_1	(OMAP2_CONTROL_GENERAL + 0x0024)
+#define OMAP2_CONTROL_MSUSPENDMUX_2	(OMAP2_CONTROL_GENERAL + 0x0028)
+#define OMAP2_CONTROL_MSUSPENDMUX_3	(OMAP2_CONTROL_GENERAL + 0x002c)
+#define OMAP2_CONTROL_MSUSPENDMUX_4	(OMAP2_CONTROL_GENERAL + 0x0030)
+#define OMAP2_CONTROL_MSUSPENDMUX_5	(OMAP2_CONTROL_GENERAL + 0x0034)
+#define OMAP2_CONTROL_SEC_CTRL		(OMAP2_CONTROL_GENERAL + 0x0040)
+#define OMAP2_CONTROL_RPUB_KEY_H_0	(OMAP2_CONTROL_GENERAL + 0x0090)
+#define OMAP2_CONTROL_RPUB_KEY_H_1	(OMAP2_CONTROL_GENERAL + 0x0094)
+#define OMAP2_CONTROL_RPUB_KEY_H_2	(OMAP2_CONTROL_GENERAL + 0x0098)
+#define OMAP2_CONTROL_RPUB_KEY_H_3	(OMAP2_CONTROL_GENERAL + 0x009c)
+
+/* 242x-only CONTROL_GENERAL register offsets */
+#define OMAP242X_CONTROL_DEVCONF	OMAP2_CONTROL_DEVCONF0 /* match TRM */
+#define OMAP242X_CONTROL_OCM_RAM_PERM	(OMAP2_CONTROL_GENERAL + 0x0068)
+
+/* 243x-only CONTROL_GENERAL register offsets */
+/* CONTROL_IVA2_BOOT{ADDR,MOD} are at the same place on 343x - noted below */
+#define OMAP243X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0078)
+#define OMAP243X_CONTROL_CSIRXFE	(OMAP2_CONTROL_GENERAL + 0x007c)
+#define OMAP243X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
+#define OMAP243X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP243X_CONTROL_IVA2_GEMCFG	(OMAP2_CONTROL_GENERAL + 0x0198)
+#define OMAP243X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x0230)
+
+/* 24xx-only CONTROL_GENERAL register offsets */
+#define OMAP24XX_CONTROL_DEBOBS		(OMAP2_CONTROL_GENERAL + 0x0000)
+#define OMAP24XX_CONTROL_EMU_SUPPORT	(OMAP2_CONTROL_GENERAL + 0x0008)
+#define OMAP24XX_CONTROL_SEC_TEST	(OMAP2_CONTROL_GENERAL + 0x0044)
+#define OMAP24XX_CONTROL_PSA_CTRL	(OMAP2_CONTROL_GENERAL + 0x0048)
+#define OMAP24XX_CONTROL_PSA_CMD	(OMAP2_CONTROL_GENERAL + 0x004c)
+#define OMAP24XX_CONTROL_PSA_VALUE	(OMAP2_CONTROL_GENERAL + 0x0050)
+#define OMAP24XX_CONTROL_SEC_EMU	(OMAP2_CONTROL_GENERAL + 0x0060)
+#define OMAP24XX_CONTROL_SEC_TAP	(OMAP2_CONTROL_GENERAL + 0x0064)
+#define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD	(OMAP2_CONTROL_GENERAL + 0x006c)
+#define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD	(OMAP2_CONTROL_GENERAL + 0x0070)
+#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD	(OMAP2_CONTROL_GENERAL + 0x0074)
+#define OMAP24XX_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0080)
+#define OMAP24XX_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0084)
+#define OMAP24XX_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0088)
+#define OMAP24XX_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x008c)
+#define OMAP24XX_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a0)
+#define OMAP24XX_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00a4)
+#define OMAP24XX_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00a8)
+#define OMAP24XX_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00ac)
+#define OMAP24XX_CONTROL_CUST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00b0)
+#define OMAP24XX_CONTROL_CUST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00b4)
+#define OMAP24XX_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c0)
+#define OMAP24XX_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00c4)
+#define OMAP24XX_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00c8)
+#define OMAP24XX_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00cc)
+#define OMAP24XX_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d0)
+#define OMAP24XX_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00d4)
+#define OMAP24XX_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00d8)
+#define OMAP24XX_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00dc)
+#define OMAP24XX_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e0)
+#define OMAP24XX_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00e4)
+
+#define OMAP343X_CONTROL_PADCONF_SYSNIRQ (OMAP2_CONTROL_INTERFACE + 0x01b0)
+
+/* 34xx-only CONTROL_GENERAL register offsets */
+#define OMAP343X_CONTROL_PADCONF_OFF	(OMAP2_CONTROL_GENERAL + 0x0000)
+#define OMAP343X_CONTROL_MEM_DFTRW0	(OMAP2_CONTROL_GENERAL + 0x0008)
+#define OMAP343X_CONTROL_MEM_DFTRW1	(OMAP2_CONTROL_GENERAL + 0x000c)
+#define OMAP343X_CONTROL_DEVCONF1	(OMAP2_CONTROL_GENERAL + 0x0068)
+#define OMAP343X_CONTROL_CSIRXFE		(OMAP2_CONTROL_GENERAL + 0x006c)
+#define OMAP343X_CONTROL_SEC_STATUS		(OMAP2_CONTROL_GENERAL + 0x0070)
+#define OMAP343X_CONTROL_SEC_ERR_STATUS		(OMAP2_CONTROL_GENERAL + 0x0074)
+#define OMAP343X_CONTROL_SEC_ERR_STATUS_DEBUG	(OMAP2_CONTROL_GENERAL + 0x0078)
+#define OMAP343X_CONTROL_STATUS			(OMAP2_CONTROL_GENERAL + 0x0080)
+#define OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS	(OMAP2_CONTROL_GENERAL + 0x0084)
+#define OMAP343X_CONTROL_RPUB_KEY_H_4	(OMAP2_CONTROL_GENERAL + 0x00a0)
+#define OMAP343X_CONTROL_RAND_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00a8)
+#define OMAP343X_CONTROL_RAND_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00ac)
+#define OMAP343X_CONTROL_RAND_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00b0)
+#define OMAP343X_CONTROL_RAND_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00b4)
+#define OMAP343X_CONTROL_TEST_KEY_0	(OMAP2_CONTROL_GENERAL + 0x00c8)
+#define OMAP343X_CONTROL_TEST_KEY_1	(OMAP2_CONTROL_GENERAL + 0x00cc)
+#define OMAP343X_CONTROL_TEST_KEY_2	(OMAP2_CONTROL_GENERAL + 0x00d0)
+#define OMAP343X_CONTROL_TEST_KEY_3	(OMAP2_CONTROL_GENERAL + 0x00d4)
+#define OMAP343X_CONTROL_TEST_KEY_4	(OMAP2_CONTROL_GENERAL + 0x00d8)
+#define OMAP343X_CONTROL_TEST_KEY_5	(OMAP2_CONTROL_GENERAL + 0x00dc)
+#define OMAP343X_CONTROL_TEST_KEY_6	(OMAP2_CONTROL_GENERAL + 0x00e0)
+#define OMAP343X_CONTROL_TEST_KEY_7	(OMAP2_CONTROL_GENERAL + 0x00e4)
+#define OMAP343X_CONTROL_TEST_KEY_8	(OMAP2_CONTROL_GENERAL + 0x00e8)
+#define OMAP343X_CONTROL_TEST_KEY_9	(OMAP2_CONTROL_GENERAL + 0x00ec)
+#define OMAP343X_CONTROL_TEST_KEY_10	(OMAP2_CONTROL_GENERAL + 0x00f0)
+#define OMAP343X_CONTROL_TEST_KEY_11	(OMAP2_CONTROL_GENERAL + 0x00f4)
+#define OMAP343X_CONTROL_TEST_KEY_12	(OMAP2_CONTROL_GENERAL + 0x00f8)
+#define OMAP343X_CONTROL_TEST_KEY_13	(OMAP2_CONTROL_GENERAL + 0x00fc)
+#define OMAP343X_CONTROL_IVA2_BOOTADDR	(OMAP2_CONTROL_GENERAL + 0x0190)
+#define OMAP343X_CONTROL_IVA2_BOOTMOD	(OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_DEBOBS(i)	(OMAP2_CONTROL_GENERAL + 0x01B0 \
+					+ ((i) >> 1) * 4 + (!((i) & 1)) * 2)
+#define OMAP343X_CONTROL_PROG_IO0	(OMAP2_CONTROL_GENERAL + 0x01D4)
+#define OMAP343X_CONTROL_PROG_IO1	(OMAP2_CONTROL_GENERAL + 0x01D8)
+#define OMAP343X_CONTROL_DSS_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E0)
+#define OMAP343X_CONTROL_CORE_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E4)
+#define OMAP343X_CONTROL_PER_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01E8)
+#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING	(OMAP2_CONTROL_GENERAL + 0x01EC)
+#define OMAP343X_CONTROL_PBIAS_LITE	(OMAP2_CONTROL_GENERAL + 0x02B0)
+#define OMAP343X_CONTROL_TEMP_SENSOR	(OMAP2_CONTROL_GENERAL + 0x02B4)
+#define OMAP343X_CONTROL_SRAMLDO4	(OMAP2_CONTROL_GENERAL + 0x02B8)
+#define OMAP343X_CONTROL_SRAMLDO5	(OMAP2_CONTROL_GENERAL + 0x02C0)
+#define OMAP343X_CONTROL_CSI		(OMAP2_CONTROL_GENERAL + 0x02C4)
+
+
+/* 34xx PADCONF register offsets */
+#define OMAP343X_PADCONF_ETK(i)		(OMAP2_CONTROL_PADCONFS + 0x5a8 + \
+						(i)*2)
+#define OMAP343X_PADCONF_ETK_CLK	OMAP343X_PADCONF_ETK(0)
+#define OMAP343X_PADCONF_ETK_CTL	OMAP343X_PADCONF_ETK(1)
+#define OMAP343X_PADCONF_ETK_D0		OMAP343X_PADCONF_ETK(2)
+#define OMAP343X_PADCONF_ETK_D1		OMAP343X_PADCONF_ETK(3)
+#define OMAP343X_PADCONF_ETK_D2		OMAP343X_PADCONF_ETK(4)
+#define OMAP343X_PADCONF_ETK_D3		OMAP343X_PADCONF_ETK(5)
+#define OMAP343X_PADCONF_ETK_D4		OMAP343X_PADCONF_ETK(6)
+#define OMAP343X_PADCONF_ETK_D5		OMAP343X_PADCONF_ETK(7)
+#define OMAP343X_PADCONF_ETK_D6		OMAP343X_PADCONF_ETK(8)
+#define OMAP343X_PADCONF_ETK_D7		OMAP343X_PADCONF_ETK(9)
+#define OMAP343X_PADCONF_ETK_D8		OMAP343X_PADCONF_ETK(10)
+#define OMAP343X_PADCONF_ETK_D9		OMAP343X_PADCONF_ETK(11)
+#define OMAP343X_PADCONF_ETK_D10	OMAP343X_PADCONF_ETK(12)
+#define OMAP343X_PADCONF_ETK_D11	OMAP343X_PADCONF_ETK(13)
+#define OMAP343X_PADCONF_ETK_D12	OMAP343X_PADCONF_ETK(14)
+#define OMAP343X_PADCONF_ETK_D13	OMAP343X_PADCONF_ETK(15)
+#define OMAP343X_PADCONF_ETK_D14	OMAP343X_PADCONF_ETK(16)
+#define OMAP343X_PADCONF_ETK_D15	OMAP343X_PADCONF_ETK(17)
+
+/* 34xx GENERAL_WKUP regist offsets */
+#define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \
+						0x008 + (i))
+#define OMAP343X_CONTROL_WKUP_DEBOBS0 (OMAP343X_CONTROL_GENERAL_WKUP + 0x008)
+#define OMAP343X_CONTROL_WKUP_DEBOBS1 (OMAP343X_CONTROL_GENERAL_WKUP + 0x00C)
+#define OMAP343X_CONTROL_WKUP_DEBOBS2 (OMAP343X_CONTROL_GENERAL_WKUP + 0x010)
+#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
+#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
+
+/* 34xx D2D idle-related pins, handled by PM core */
+#define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
+#define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
+
+/*
+ * REVISIT: This list of registers is not comprehensive - there are more
+ * that should be added.
+ */
+
+/*
+ * Control module register bit defines - these should eventually go into
+ * their own regbits file.  Some of these will be complicated, depending
+ * on the device type (general-purpose, emulator, test, secure, bad, other)
+ * and the security mode (secure, non-secure, don't care)
+ */
+/* CONTROL_DEVCONF0 bits */
+#define OMAP2_MMCSDIO1ADPCLKISEL	(1 << 24) /* MMC1 loop back clock */
+#define OMAP24XX_USBSTANDBYCTRL		(1 << 15)
+#define OMAP2_MCBSP2_CLKS_MASK		(1 << 6)
+#define OMAP2_MCBSP1_CLKS_MASK		(1 << 2)
+
+/* CONTROL_DEVCONF1 bits */
+#define OMAP243X_MMC1_ACTIVE_OVERWRITE	(1 << 31)
+#define OMAP2_MMCSDIO2ADPCLKISEL	(1 << 6) /* MMC2 loop back clock */
+#define OMAP2_MCBSP5_CLKS_MASK		(1 << 4) /* > 242x */
+#define OMAP2_MCBSP4_CLKS_MASK		(1 << 2) /* > 242x */
+#define OMAP2_MCBSP3_CLKS_MASK		(1 << 0) /* > 242x */
+
+/* CONTROL_STATUS bits */
+#define OMAP2_DEVICETYPE_MASK		(0x7 << 8)
+#define OMAP2_SYSBOOT_5_MASK		(1 << 5)
+#define OMAP2_SYSBOOT_4_MASK		(1 << 4)
+#define OMAP2_SYSBOOT_3_MASK		(1 << 3)
+#define OMAP2_SYSBOOT_2_MASK		(1 << 2)
+#define OMAP2_SYSBOOT_1_MASK		(1 << 1)
+#define OMAP2_SYSBOOT_0_MASK		(1 << 0)
+
+/* CONTROL_PBIAS_LITE bits */
+#define OMAP343X_PBIASLITESUPPLY_HIGH1	(1 << 15)
+#define OMAP343X_PBIASLITEVMODEERROR1	(1 << 11)
+#define OMAP343X_PBIASSPEEDCTRL1	(1 << 10)
+#define OMAP343X_PBIASLITEPWRDNZ1	(1 << 9)
+#define OMAP343X_PBIASLITEVMODE1	(1 << 8)
+#define OMAP343X_PBIASLITESUPPLY_HIGH0	(1 << 7)
+#define OMAP343X_PBIASLITEVMODEERROR0	(1 << 3)
+#define OMAP2_PBIASSPEEDCTRL0		(1 << 2)
+#define OMAP2_PBIASLITEPWRDNZ0		(1 << 1)
+#define OMAP2_PBIASLITEVMODE0		(1 << 0)
+
+/* CONTROL_PROG_IO1 bits */
+#define OMAP3630_PRG_SDMMC1_SPEEDCTRL	(1 << 20)
+
+/* CONTROL_IVA2_BOOTMOD bits */
+#define OMAP3_IVA2_BOOTMOD_SHIFT	0
+#define OMAP3_IVA2_BOOTMOD_MASK		(0xf << 0)
+#define OMAP3_IVA2_BOOTMOD_IDLE		(0x1 << 0)
+
+/* CONTROL_PADCONF_X bits */
+#define OMAP3_PADCONF_WAKEUPEVENT0	(1 << 15)
+#define OMAP3_PADCONF_WAKEUPENABLE0	(1 << 14)
+
+#define OMAP343X_SCRATCHPAD_ROM		(OMAP343X_CTRL_BASE + 0x860)
+#define OMAP343X_SCRATCHPAD		(OMAP343X_CTRL_BASE + 0x910)
+#define OMAP343X_SCRATCHPAD_ROM_OFFSET	0x19C
+
+/*
+ * CONTROL OMAP STATUS register to identify OMAP3 features
+ */
+#define OMAP3_CONTROL_OMAP_STATUS	0x044c
+
+#define OMAP3_SGX_SHIFT			13
+#define OMAP3_SGX_MASK			(3 << OMAP3_SGX_SHIFT)
+#define		FEAT_SGX_FULL		0
+#define		FEAT_SGX_HALF		1
+#define		FEAT_SGX_NONE		2
+
+#define OMAP3_IVA_SHIFT			12
+#define OMAP3_IVA_MASK			(1 << OMAP3_SGX_SHIFT)
+#define		FEAT_IVA		0
+#define		FEAT_IVA_NONE		1
+
+#define OMAP3_L2CACHE_SHIFT		10
+#define OMAP3_L2CACHE_MASK		(3 << OMAP3_L2CACHE_SHIFT)
+#define		FEAT_L2CACHE_NONE	0
+#define		FEAT_L2CACHE_64KB	1
+#define		FEAT_L2CACHE_128KB	2
+#define		FEAT_L2CACHE_256KB	3
+
+#define OMAP3_ISP_SHIFT			5
+#define OMAP3_ISP_MASK			(1<< OMAP3_ISP_SHIFT)
+#define		FEAT_ISP		0
+#define		FEAT_ISP_NONE		1
+
+#define OMAP3_NEON_SHIFT		4
+#define OMAP3_NEON_MASK			(1<< OMAP3_NEON_SHIFT)
+#define		FEAT_NEON		0
+#define		FEAT_NEON_NONE		1
+
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
+		defined(CONFIG_ARCH_OMAP4)
+extern void __iomem *omap_ctrl_base_get(void);
+extern u8 omap_ctrl_readb(u16 offset);
+extern u16 omap_ctrl_readw(u16 offset);
+extern u32 omap_ctrl_readl(u16 offset);
+extern void omap_ctrl_writeb(u8 val, u16 offset);
+extern void omap_ctrl_writew(u16 val, u16 offset);
+extern void omap_ctrl_writel(u32 val, u16 offset);
+
+extern void omap3_save_scratchpad_contents(void);
+extern void omap3_clear_scratchpad_contents(void);
+extern u32 *get_restore_pointer(void);
+extern u32 *get_es3_restore_pointer(void);
+extern u32 omap3_arm_context[128];
+extern void omap3_control_save_context(void);
+extern void omap3_control_restore_context(void);
+
+#else
+#define omap_ctrl_base_get()		0
+#define omap_ctrl_readb(x)		0
+#define omap_ctrl_readw(x)		0
+#define omap_ctrl_readl(x)		0
+#define omap_ctrl_writeb(x, y)		WARN_ON(1)
+#define omap_ctrl_writew(x, y)		WARN_ON(1)
+#define omap_ctrl_writel(x, y)		WARN_ON(1)
+#endif
+#endif	/* __ASSEMBLY__ */
+
+#endif /* __ASM_ARCH_CONTROL_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/cpu.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/cpu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/cpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/cpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,517 @@
+/*
+ * arch/arm/plat-omap/include/mach/cpu.h
+ *
+ * OMAP cpu type detection
+ *
+ * Copyright (C) 2004, 2008 Nokia Corporation
+ *
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * Added OMAP4 specific defines - 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 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_OMAP_CPU_H
+#define __ASM_ARCH_OMAP_CPU_H
+
+#include <linux/bitops.h>
+
+/*
+ * Omap device type i.e. EMU/HS/TST/GP/BAD
+ */
+#define OMAP2_DEVICE_TYPE_TEST		0
+#define OMAP2_DEVICE_TYPE_EMU		1
+#define OMAP2_DEVICE_TYPE_SEC		2
+#define OMAP2_DEVICE_TYPE_GP		3
+#define OMAP2_DEVICE_TYPE_BAD		4
+
+int omap_type(void);
+
+struct omap_chip_id {
+	u8 oc;
+	u8 type;
+};
+
+#define OMAP_CHIP_INIT(x)	{ .oc = x }
+
+/*
+ * omap_rev bits:
+ * CPU id bits	(0730, 1510, 1710, 2422...)	[31:16]
+ * CPU revision	(See _REV_ defined in cpu.h)	[15:08]
+ * CPU class bits (15xx, 16xx, 24xx, 34xx...)	[07:00]
+ */
+unsigned int omap_rev(void);
+
+/*
+ * Define CPU revision bits
+ *
+ * Verbose meaning of the revision bits may be different for a silicon
+ * family. This difference can be handled separately.
+ */
+#define OMAP_REVBITS_00		0x00
+#define OMAP_REVBITS_10		0x10
+#define OMAP_REVBITS_20		0x20
+#define OMAP_REVBITS_30		0x30
+#define OMAP_REVBITS_40		0x40
+
+/*
+ * Get the CPU revision for OMAP devices
+ */
+#define GET_OMAP_REVISION()	((omap_rev() >> 8) & 0xff)
+
+/*
+ * Test if multicore OMAP support is needed
+ */
+#undef MULTI_OMAP1
+#undef MULTI_OMAP2
+#undef OMAP_NAME
+
+#ifdef CONFIG_ARCH_OMAP730
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap730
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP850
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap850
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap1510
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
+# else
+#  define OMAP_NAME omap16xx
+# endif
+#endif
+#if (defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX))
+# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
+#  error "OMAP1 and OMAP2 can't be selected at the same time"
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP2420
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap2420
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP2430
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap2430
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP3430
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME omap3430
+# endif
+#endif
+
+/*
+ * Macros to group OMAP into cpu classes.
+ * These can be used in most places.
+ * cpu_is_omap7xx():	True for OMAP730, OMAP850
+ * cpu_is_omap15xx():	True for OMAP1510, OMAP5910 and OMAP310
+ * cpu_is_omap16xx():	True for OMAP1610, OMAP5912 and OMAP1710
+ * cpu_is_omap24xx():	True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
+ * cpu_is_omap242x():	True for OMAP2420, OMAP2422, OMAP2423
+ * cpu_is_omap243x():	True for OMAP2430
+ * cpu_is_omap343x():	True for OMAP3430
+ */
+#define GET_OMAP_CLASS	(omap_rev() & 0xff)
+
+#define IS_OMAP_CLASS(class, id)			\
+static inline int is_omap ##class (void)		\
+{							\
+	return (GET_OMAP_CLASS == (id)) ? 1 : 0;	\
+}
+
+#define GET_OMAP_SUBCLASS	((omap_rev() >> 20) & 0x0fff)
+
+#define IS_OMAP_SUBCLASS(subclass, id)			\
+static inline int is_omap ##subclass (void)		\
+{							\
+	return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;	\
+}
+
+IS_OMAP_CLASS(7xx, 0x07)
+IS_OMAP_CLASS(15xx, 0x15)
+IS_OMAP_CLASS(16xx, 0x16)
+IS_OMAP_CLASS(24xx, 0x24)
+IS_OMAP_CLASS(34xx, 0x34)
+IS_OMAP_CLASS(44xx, 0x44)
+
+IS_OMAP_SUBCLASS(242x, 0x242)
+IS_OMAP_SUBCLASS(243x, 0x243)
+IS_OMAP_SUBCLASS(343x, 0x343)
+IS_OMAP_SUBCLASS(363x, 0x363)
+IS_OMAP_SUBCLASS(443x, 0x443)
+
+#define cpu_is_omap7xx()		0
+#define cpu_is_omap15xx()		0
+#define cpu_is_omap16xx()		0
+#define cpu_is_omap24xx()		0
+#define cpu_is_omap242x()		0
+#define cpu_is_omap243x()		0
+#define cpu_is_omap34xx()		0
+#define cpu_is_omap343x()		0
+#define cpu_is_omap44xx()		0
+#define cpu_is_omap443x()		0
+
+#if defined(MULTI_OMAP1)
+# if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap7xx
+#  define cpu_is_omap7xx()		is_omap7xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP850)
+#  undef  cpu_is_omap7xx
+#  define cpu_is_omap7xx()		is_omap7xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP15XX)
+#  undef  cpu_is_omap15xx
+#  define cpu_is_omap15xx()		is_omap15xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP16XX)
+#  undef  cpu_is_omap16xx
+#  define cpu_is_omap16xx()		is_omap16xx()
+# endif
+#else
+# if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap7xx
+#  define cpu_is_omap7xx()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP850)
+#  undef  cpu_is_omap7xx
+#  define cpu_is_omap7xx()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP15XX)
+#  undef  cpu_is_omap15xx
+#  define cpu_is_omap15xx()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP16XX)
+#  undef  cpu_is_omap16xx
+#  define cpu_is_omap16xx()		1
+# endif
+#endif
+
+#if defined(MULTI_OMAP2)
+# if defined(CONFIG_ARCH_OMAP24XX)
+#  undef  cpu_is_omap24xx
+#  undef  cpu_is_omap242x
+#  undef  cpu_is_omap243x
+#  define cpu_is_omap24xx()		is_omap24xx()
+#  define cpu_is_omap242x()		is_omap242x()
+#  define cpu_is_omap243x()		is_omap243x()
+# endif
+# if defined(CONFIG_ARCH_OMAP34XX)
+#  undef  cpu_is_omap34xx
+#  undef  cpu_is_omap343x
+#  define cpu_is_omap34xx()		is_omap34xx()
+#  define cpu_is_omap343x()		is_omap343x()
+# endif
+#else
+# if defined(CONFIG_ARCH_OMAP24XX)
+#  undef  cpu_is_omap24xx
+#  define cpu_is_omap24xx()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP2420)
+#  undef  cpu_is_omap242x
+#  define cpu_is_omap242x()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP2430)
+#  undef  cpu_is_omap243x
+#  define cpu_is_omap243x()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP34XX)
+#  undef  cpu_is_omap34xx
+#  define cpu_is_omap34xx()		1
+# endif
+# if defined(CONFIG_ARCH_OMAP3430)
+#  undef  cpu_is_omap343x
+#  define cpu_is_omap343x()		1
+# endif
+#endif
+
+/*
+ * Macros to detect individual cpu types.
+ * These are only rarely needed.
+ * cpu_is_omap330():	True for OMAP330
+ * cpu_is_omap730():	True for OMAP730
+ * cpu_is_omap850():	True for OMAP850
+ * cpu_is_omap1510():	True for OMAP1510
+ * cpu_is_omap1610():	True for OMAP1610
+ * cpu_is_omap1611():	True for OMAP1611
+ * cpu_is_omap5912():	True for OMAP5912
+ * cpu_is_omap1621():	True for OMAP1621
+ * cpu_is_omap1710():	True for OMAP1710
+ * cpu_is_omap2420():	True for OMAP2420
+ * cpu_is_omap2422():	True for OMAP2422
+ * cpu_is_omap2423():	True for OMAP2423
+ * cpu_is_omap2430():	True for OMAP2430
+ * cpu_is_omap3430():	True for OMAP3430
+ * cpu_is_omap3505():	True for OMAP3505
+ * cpu_is_omap3517():	True for OMAP3517
+ */
+#define GET_OMAP_TYPE	((omap_rev() >> 16) & 0xffff)
+
+#define IS_OMAP_TYPE(type, id)				\
+static inline int is_omap ##type (void)			\
+{							\
+	return (GET_OMAP_TYPE == (id)) ? 1 : 0;		\
+}
+
+IS_OMAP_TYPE(310, 0x0310)
+IS_OMAP_TYPE(730, 0x0730)
+IS_OMAP_TYPE(850, 0x0850)
+IS_OMAP_TYPE(1510, 0x1510)
+IS_OMAP_TYPE(1610, 0x1610)
+IS_OMAP_TYPE(1611, 0x1611)
+IS_OMAP_TYPE(5912, 0x1611)
+IS_OMAP_TYPE(1621, 0x1621)
+IS_OMAP_TYPE(1710, 0x1710)
+IS_OMAP_TYPE(2420, 0x2420)
+IS_OMAP_TYPE(2422, 0x2422)
+IS_OMAP_TYPE(2423, 0x2423)
+IS_OMAP_TYPE(2430, 0x2430)
+IS_OMAP_TYPE(3430, 0x3430)
+IS_OMAP_TYPE(3505, 0x3505)
+IS_OMAP_TYPE(3517, 0x3517)
+
+#define cpu_is_omap310()		0
+#define cpu_is_omap730()		0
+#define cpu_is_omap850()		0
+#define cpu_is_omap1510()		0
+#define cpu_is_omap1610()		0
+#define cpu_is_omap5912()		0
+#define cpu_is_omap1611()		0
+#define cpu_is_omap1621()		0
+#define cpu_is_omap1710()		0
+#define cpu_is_omap2420()		0
+#define cpu_is_omap2422()		0
+#define cpu_is_omap2423()		0
+#define cpu_is_omap2430()		0
+#define cpu_is_omap3503()		0
+#define cpu_is_omap3515()		0
+#define cpu_is_omap3525()		0
+#define cpu_is_omap3530()		0
+#define cpu_is_omap3505()		0
+#define cpu_is_omap3517()		0
+#define cpu_is_omap3430()		0
+#define cpu_is_omap3630()		0
+
+/*
+ * Whether we have MULTI_OMAP1 or not, we still need to distinguish
+ * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
+ */
+
+#if defined(CONFIG_ARCH_OMAP730)
+# undef  cpu_is_omap730
+# define cpu_is_omap730()		is_omap730()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP850)
+# undef  cpu_is_omap850
+# define cpu_is_omap850()		is_omap850()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX)
+# undef  cpu_is_omap310
+# undef  cpu_is_omap1510
+# define cpu_is_omap310()		is_omap310()
+# define cpu_is_omap1510()		is_omap1510()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+# undef  cpu_is_omap1610
+# undef  cpu_is_omap1611
+# undef  cpu_is_omap5912
+# undef  cpu_is_omap1621
+# undef  cpu_is_omap1710
+# define cpu_is_omap1610()		is_omap1610()
+# define cpu_is_omap1611()		is_omap1611()
+# define cpu_is_omap5912()		is_omap5912()
+# define cpu_is_omap1621()		is_omap1621()
+# define cpu_is_omap1710()		is_omap1710()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP24XX)
+# undef  cpu_is_omap2420
+# undef  cpu_is_omap2422
+# undef  cpu_is_omap2423
+# undef  cpu_is_omap2430
+# define cpu_is_omap2420()		is_omap2420()
+# define cpu_is_omap2422()		is_omap2422()
+# define cpu_is_omap2423()		is_omap2423()
+# define cpu_is_omap2430()		is_omap2430()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+# undef cpu_is_omap3430
+# undef cpu_is_omap3503
+# undef cpu_is_omap3515
+# undef cpu_is_omap3525
+# undef cpu_is_omap3530
+# undef cpu_is_omap3505
+# undef cpu_is_omap3517
+# define cpu_is_omap3430()		is_omap3430()
+# define cpu_is_omap3503()		(cpu_is_omap3430() &&		\
+						(!omap3_has_iva()) &&	\
+						(!omap3_has_sgx()))
+# define cpu_is_omap3515()		(cpu_is_omap3430() &&		\
+						(!omap3_has_iva()) &&	\
+						(omap3_has_sgx()))
+# define cpu_is_omap3525()		(cpu_is_omap3430() &&		\
+						(!omap3_has_sgx()) &&	\
+						(omap3_has_iva()))
+# define cpu_is_omap3530()		(cpu_is_omap3430())
+# define cpu_is_omap3505()		is_omap3505()
+# define cpu_is_omap3517()		is_omap3517()
+# undef cpu_is_omap3630
+# define cpu_is_omap3630()		is_omap363x()
+#endif
+
+# if defined(CONFIG_ARCH_OMAP4)
+# undef cpu_is_omap44xx
+# undef cpu_is_omap443x
+# define cpu_is_omap44xx()		is_omap44xx()
+# define cpu_is_omap443x()		is_omap443x()
+# endif
+
+/* Macros to detect if we have OMAP1 or OMAP2 */
+#define cpu_class_is_omap1()	(cpu_is_omap7xx() || cpu_is_omap15xx() || \
+				cpu_is_omap16xx())
+#define cpu_class_is_omap2()	(cpu_is_omap24xx() || cpu_is_omap34xx() || \
+				cpu_is_omap44xx())
+
+/* Various silicon revisions for omap2 */
+#define OMAP242X_CLASS		0x24200024
+#define OMAP2420_REV_ES1_0	0x24200024
+#define OMAP2420_REV_ES2_0	0x24201024
+
+#define OMAP243X_CLASS		0x24300024
+#define OMAP2430_REV_ES1_0	0x24300024
+
+#define OMAP343X_CLASS		0x34300034
+#define OMAP3430_REV_ES1_0	0x34300034
+#define OMAP3430_REV_ES2_0	0x34301034
+#define OMAP3430_REV_ES2_1	0x34302034
+#define OMAP3430_REV_ES3_0	0x34303034
+#define OMAP3430_REV_ES3_1	0x34304034
+#define OMAP3430_REV_ES3_1_2	0x34305034
+
+#define OMAP3630_REV_ES1_0	0x36300034
+
+#define OMAP35XX_CLASS		0x35000034
+#define OMAP3503_REV(v)		(OMAP35XX_CLASS | (0x3503 << 16) | (v << 8))
+#define OMAP3515_REV(v)		(OMAP35XX_CLASS | (0x3515 << 16) | (v << 8))
+#define OMAP3525_REV(v)		(OMAP35XX_CLASS | (0x3525 << 16) | (v << 8))
+#define OMAP3530_REV(v)		(OMAP35XX_CLASS | (0x3530 << 16) | (v << 8))
+#define OMAP3505_REV(v)		(OMAP35XX_CLASS | (0x3505 << 16) | (v << 8))
+#define OMAP3517_REV(v)		(OMAP35XX_CLASS | (0x3517 << 16) | (v << 8))
+
+#define OMAP443X_CLASS		0x44300044
+#define OMAP4430_REV_ES1_0	0x44300044
+
+/*
+ * omap_chip bits
+ *
+ * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
+ * valid on all chips of that type.  CHIP_IS_OMAP3430ES{1,2} indicates
+ * something that is only valid on that particular ES revision.
+ *
+ * These bits may be ORed together to indicate structures that are
+ * available on multiple chip types.
+ *
+ * To test whether a particular structure matches the current OMAP chip type,
+ * use omap_chip_is().
+ *
+ */
+#define CHIP_IS_OMAP2420		(1 << 0)
+#define CHIP_IS_OMAP2430		(1 << 1)
+#define CHIP_IS_OMAP3430		(1 << 2)
+#define CHIP_IS_OMAP3430ES1		(1 << 3)
+#define CHIP_IS_OMAP3430ES2		(1 << 4)
+#define CHIP_IS_OMAP3430ES3_0		(1 << 5)
+#define CHIP_IS_OMAP3430ES3_1		(1 << 6)
+#define CHIP_IS_OMAP3630ES1		(1 << 7)
+
+#define CHIP_IS_OMAP24XX		(CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
+
+/*
+ * "GE" here represents "greater than or equal to" in terms of ES
+ * levels.  So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
+ * chips at ES2 and beyond, but not, for example, any OMAP lines after
+ * OMAP3.
+ */
+#define CHIP_GE_OMAP3430ES2		(CHIP_IS_OMAP3430ES2 | \
+					 CHIP_IS_OMAP3430ES3_0 | \
+					 CHIP_IS_OMAP3430ES3_1 | \
+					 CHIP_IS_OMAP3630ES1)
+#define CHIP_GE_OMAP3430ES3_1		(CHIP_IS_OMAP3430ES3_1 | \
+					 CHIP_IS_OMAP3630ES1)
+
+
+int omap_chip_is(struct omap_chip_id oci);
+void omap2_check_revision(void);
+
+/*
+ * Runtime detection of OMAP3 features
+ */
+extern u32 omap3_features;
+
+#define OMAP3_HAS_L2CACHE		BIT(0)
+#define OMAP3_HAS_IVA			BIT(1)
+#define OMAP3_HAS_SGX			BIT(2)
+#define OMAP3_HAS_NEON			BIT(3)
+#define OMAP3_HAS_ISP			BIT(4)
+
+#define OMAP3_HAS_FEATURE(feat,flag)			\
+static inline unsigned int omap3_has_ ##feat(void)	\
+{							\
+	return (omap3_features & OMAP3_HAS_ ##flag);	\
+}							\
+
+OMAP3_HAS_FEATURE(l2cache, L2CACHE)
+OMAP3_HAS_FEATURE(sgx, SGX)
+OMAP3_HAS_FEATURE(iva, IVA)
+OMAP3_HAS_FEATURE(neon, NEON)
+OMAP3_HAS_FEATURE(isp, ISP)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/display.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/display.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/display.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/display.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,575 @@
+/*
+ * linux/include/asm-arm/arch-omap/display.h
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_ARCH_OMAP_DISPLAY_H
+#define __ASM_ARCH_OMAP_DISPLAY_H
+
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/device.h>
+#include <asm/atomic.h>
+
+#define DISPC_IRQ_FRAMEDONE		(1 << 0)
+#define DISPC_IRQ_VSYNC			(1 << 1)
+#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
+#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
+#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
+#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
+#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
+#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
+#define DISPC_IRQ_OCP_ERR		(1 << 9)
+#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
+#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
+#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
+#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
+#define DISPC_IRQ_SYNC_LOST		(1 << 14)
+#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
+#define DISPC_IRQ_WAKEUP		(1 << 16)
+
+struct omap_dss_device;
+struct omap_overlay_manager;
+
+enum omap_display_type {
+	OMAP_DISPLAY_TYPE_NONE		= 0,
+	OMAP_DISPLAY_TYPE_DPI		= 1 << 0,
+	OMAP_DISPLAY_TYPE_DBI		= 1 << 1,
+	OMAP_DISPLAY_TYPE_SDI		= 1 << 2,
+	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
+	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
+};
+
+enum omap_plane {
+	OMAP_DSS_GFX	= 0,
+	OMAP_DSS_VIDEO1	= 1,
+	OMAP_DSS_VIDEO2	= 2
+};
+
+enum omap_channel {
+	OMAP_DSS_CHANNEL_LCD	= 0,
+	OMAP_DSS_CHANNEL_DIGIT	= 1,
+};
+
+enum omap_color_mode {
+	OMAP_DSS_COLOR_CLUT1	= 1 << 0,  /* BITMAP 1 */
+	OMAP_DSS_COLOR_CLUT2	= 1 << 1,  /* BITMAP 2 */
+	OMAP_DSS_COLOR_CLUT4	= 1 << 2,  /* BITMAP 4 */
+	OMAP_DSS_COLOR_CLUT8	= 1 << 3,  /* BITMAP 8 */
+	OMAP_DSS_COLOR_RGB12U	= 1 << 4,  /* RGB12, 16-bit container */
+	OMAP_DSS_COLOR_ARGB16	= 1 << 5,  /* ARGB16 */
+	OMAP_DSS_COLOR_RGB16	= 1 << 6,  /* RGB16 */
+	OMAP_DSS_COLOR_RGB24U	= 1 << 7,  /* RGB24, 32-bit container */
+	OMAP_DSS_COLOR_RGB24P	= 1 << 8,  /* RGB24, 24-bit container */
+	OMAP_DSS_COLOR_YUV2	= 1 << 9,  /* YUV2 4:2:2 co-sited */
+	OMAP_DSS_COLOR_UYVY	= 1 << 10, /* UYVY 4:2:2 co-sited */
+	OMAP_DSS_COLOR_ARGB32	= 1 << 11, /* ARGB32 */
+	OMAP_DSS_COLOR_RGBA32	= 1 << 12, /* RGBA32 */
+	OMAP_DSS_COLOR_RGBX32	= 1 << 13, /* RGBx32 */
+
+	OMAP_DSS_COLOR_GFX_OMAP2 =
+		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
+		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
+		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P,
+
+	OMAP_DSS_COLOR_VID_OMAP2 =
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
+		OMAP_DSS_COLOR_UYVY,
+
+	OMAP_DSS_COLOR_GFX_OMAP3 =
+		OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
+		OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
+		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
+
+	OMAP_DSS_COLOR_VID1_OMAP3 =
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
+		OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P |
+		OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
+
+	OMAP_DSS_COLOR_VID2_OMAP3 =
+		OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
+		OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
+		OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
+		OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 |
+		OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
+};
+
+enum omap_lcd_display_type {
+	OMAP_DSS_LCD_DISPLAY_STN,
+	OMAP_DSS_LCD_DISPLAY_TFT,
+};
+
+enum omap_dss_load_mode {
+	OMAP_DSS_LOAD_CLUT_AND_FRAME	= 0,
+	OMAP_DSS_LOAD_CLUT_ONLY		= 1,
+	OMAP_DSS_LOAD_FRAME_ONLY	= 2,
+	OMAP_DSS_LOAD_CLUT_ONCE_FRAME	= 3,
+};
+
+enum omap_dss_trans_key_type {
+	OMAP_DSS_COLOR_KEY_GFX_DST = 0,
+	OMAP_DSS_COLOR_KEY_VID_SRC = 1,
+};
+
+enum omap_rfbi_te_mode {
+	OMAP_DSS_RFBI_TE_MODE_1 = 1,
+	OMAP_DSS_RFBI_TE_MODE_2 = 2,
+};
+
+enum omap_panel_config {
+	OMAP_DSS_LCD_IVS		= 1<<0,
+	OMAP_DSS_LCD_IHS		= 1<<1,
+	OMAP_DSS_LCD_IPC		= 1<<2,
+	OMAP_DSS_LCD_IEO		= 1<<3,
+	OMAP_DSS_LCD_RF			= 1<<4,
+	OMAP_DSS_LCD_ONOFF		= 1<<5,
+
+	OMAP_DSS_LCD_TFT		= 1<<20,
+};
+
+enum omap_dss_venc_type {
+	OMAP_DSS_VENC_TYPE_COMPOSITE,
+	OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+enum omap_display_caps {
+	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
+	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
+};
+
+enum omap_dss_update_mode {
+	OMAP_DSS_UPDATE_DISABLED = 0,
+	OMAP_DSS_UPDATE_AUTO,
+	OMAP_DSS_UPDATE_MANUAL,
+};
+
+enum omap_dss_display_state {
+	OMAP_DSS_DISPLAY_DISABLED = 0,
+	OMAP_DSS_DISPLAY_ACTIVE,
+	OMAP_DSS_DISPLAY_SUSPENDED,
+};
+
+/* XXX perhaps this should be removed */
+enum omap_dss_overlay_managers {
+	OMAP_DSS_OVL_MGR_LCD,
+	OMAP_DSS_OVL_MGR_TV,
+};
+
+enum omap_dss_rotation_type {
+	OMAP_DSS_ROT_DMA = 0,
+	OMAP_DSS_ROT_VRFB = 1,
+};
+
+/* clockwise rotation angle */
+enum omap_dss_rotation_angle {
+	OMAP_DSS_ROT_0   = 0,
+	OMAP_DSS_ROT_90  = 1,
+	OMAP_DSS_ROT_180 = 2,
+	OMAP_DSS_ROT_270 = 3,
+};
+
+enum omap_overlay_caps {
+	OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
+	OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
+};
+
+enum omap_overlay_manager_caps {
+	OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
+};
+
+/* RFBI */
+
+struct rfbi_timings {
+	int cs_on_time;
+	int cs_off_time;
+	int we_on_time;
+	int we_off_time;
+	int re_on_time;
+	int re_off_time;
+	int we_cycle_time;
+	int re_cycle_time;
+	int cs_pulse_width;
+	int access_time;
+
+	int clk_div;
+
+	u32 tim[5];             /* set by rfbi_convert_timings() */
+
+	int converted;
+};
+
+void omap_rfbi_write_command(const void *buf, u32 len);
+void omap_rfbi_read_data(void *buf, u32 len);
+void omap_rfbi_write_data(const void *buf, u32 len);
+void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
+		u16 x, u16 y,
+		u16 w, u16 h);
+int omap_rfbi_enable_te(bool enable, unsigned line);
+int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
+			     unsigned hs_pulse_time, unsigned vs_pulse_time,
+			     int hs_pol_inv, int vs_pol_inv, int extif_div);
+
+/* DSI */
+void dsi_bus_lock(void);
+void dsi_bus_unlock(void);
+int dsi_vc_dcs_write(int channel, u8 *data, int len);
+int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
+int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
+int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
+int dsi_vc_send_null(int channel);
+int dsi_vc_send_bta_sync(int channel);
+
+/* Board specific data */
+struct omap_dss_board_info {
+	int (*get_last_off_on_transaction_id)(struct device *dev);
+	int num_devices;
+	struct omap_dss_device **devices;
+	struct omap_dss_device *default_device;
+};
+
+struct omap_video_timings {
+	/* Unit: pixels */
+	u16 x_res;
+	/* Unit: pixels */
+	u16 y_res;
+	/* Unit: KHz */
+	u32 pixel_clock;
+	/* Unit: pixel clocks */
+	u16 hsw;	/* Horizontal synchronization pulse width */
+	/* Unit: pixel clocks */
+	u16 hfp;	/* Horizontal front porch */
+	/* Unit: pixel clocks */
+	u16 hbp;	/* Horizontal back porch */
+	/* Unit: line clocks */
+	u16 vsw;	/* Vertical synchronization pulse width */
+	/* Unit: line clocks */
+	u16 vfp;	/* Vertical front porch */
+	/* Unit: line clocks */
+	u16 vbp;	/* Vertical back porch */
+};
+
+#ifdef CONFIG_OMAP2_DSS_VENC
+/* Hardcoded timings for tv modes. Venc only uses these to
+ * identify the mode, and does not actually use the configs
+ * itself. However, the configs should be something that
+ * a normal monitor can also show */
+const extern struct omap_video_timings omap_dss_pal_timings;
+const extern struct omap_video_timings omap_dss_ntsc_timings;
+#endif
+
+struct omap_overlay_info {
+	bool enabled;
+
+	u32 paddr;
+	void __iomem *vaddr;
+	u16 screen_width;
+	u16 width;
+	u16 height;
+	enum omap_color_mode color_mode;
+	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
+	bool mirror;
+
+	u16 pos_x;
+	u16 pos_y;
+	u16 out_width;	/* if 0, out_width == width */
+	u16 out_height;	/* if 0, out_height == height */
+	u8 global_alpha;
+};
+
+struct omap_overlay {
+	struct kobject kobj;
+	struct list_head list;
+
+	/* static fields */
+	const char *name;
+	int id;
+	enum omap_color_mode supported_modes;
+	enum omap_overlay_caps caps;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+	struct omap_overlay_info info;
+
+	/* if true, info has been changed, but not applied() yet */
+	bool info_dirty;
+
+	int (*set_manager)(struct omap_overlay *ovl,
+		struct omap_overlay_manager *mgr);
+	int (*unset_manager)(struct omap_overlay *ovl);
+
+	int (*set_overlay_info)(struct omap_overlay *ovl,
+			struct omap_overlay_info *info);
+	void (*get_overlay_info)(struct omap_overlay *ovl,
+			struct omap_overlay_info *info);
+
+	int (*wait_for_go)(struct omap_overlay *ovl);
+};
+
+struct omap_overlay_manager_info {
+	u32 default_color;
+
+	enum omap_dss_trans_key_type trans_key_type;
+	u32 trans_key;
+	bool trans_enabled;
+
+	bool alpha_enabled;
+};
+
+struct omap_overlay_manager {
+	struct kobject kobj;
+	struct list_head list;
+
+	/* static fields */
+	const char *name;
+	int id;
+	enum omap_overlay_manager_caps caps;
+	int num_overlays;
+	struct omap_overlay **overlays;
+	enum omap_display_type supported_displays;
+
+	/* dynamic fields */
+	struct omap_dss_device *device;
+	struct omap_overlay_manager_info info;
+
+	bool device_changed;
+	/* if true, info has been changed but not applied() yet */
+	bool info_dirty;
+
+	int (*set_device)(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev);
+	int (*unset_device)(struct omap_overlay_manager *mgr);
+
+	int (*set_manager_info)(struct omap_overlay_manager *mgr,
+			struct omap_overlay_manager_info *info);
+	void (*get_manager_info)(struct omap_overlay_manager *mgr,
+			struct omap_overlay_manager_info *info);
+
+	int (*apply)(struct omap_overlay_manager *mgr);
+	int (*wait_for_go)(struct omap_overlay_manager *mgr);
+};
+
+struct omap_dss_device {
+	struct device dev;
+
+	enum omap_display_type type;
+
+	union {
+		struct {
+			u8 data_lines;
+		} dpi;
+
+		struct {
+			u8 channel;
+			u8 data_lines;
+		} rfbi;
+
+		struct {
+			u8 datapairs;
+		} sdi;
+
+		struct {
+			u8 clk_lane;
+			u8 clk_pol;
+			u8 data1_lane;
+			u8 data1_pol;
+			u8 data2_lane;
+			u8 data2_pol;
+
+			struct {
+				u16 regn;
+				u16 regm;
+				u16 regm3;
+				u16 regm4;
+
+				u16 lp_clk_div;
+
+				u16 lck_div;
+				u16 pck_div;
+			} div;
+
+			bool ext_te;
+			u8 ext_te_gpio;
+		} dsi;
+
+		struct {
+			enum omap_dss_venc_type type;
+			bool invert_polarity;
+		} venc;
+	} phy;
+
+	struct {
+		struct omap_video_timings timings;
+
+		int acbi;	/* ac-bias pin transitions per interrupt */
+		/* Unit: line clocks */
+		int acb;	/* ac-bias pin frequency */
+
+		enum omap_panel_config config;
+
+		u8 recommended_bpp;
+
+		struct omap_dss_device *ctrl;
+	} panel;
+
+	struct {
+		u8 pixel_size;
+		struct rfbi_timings rfbi_timings;
+		struct omap_dss_device *panel;
+	} ctrl;
+
+	int reset_gpio;
+
+	int max_backlight_level;
+
+	const char *name;
+
+	/* used to match device to driver */
+	const char *driver_name;
+
+	void *data;
+
+	struct omap_dss_driver *driver;
+
+	/* helper variable for driver suspend/resume */
+	bool activate_after_resume;
+
+	enum omap_display_caps caps;
+
+	struct omap_overlay_manager *manager;
+
+	enum omap_dss_display_state state;
+
+	int (*enable)(struct omap_dss_device *dssdev);
+	void (*disable)(struct omap_dss_device *dssdev);
+
+	int (*suspend)(struct omap_dss_device *dssdev);
+	int (*resume)(struct omap_dss_device *dssdev);
+
+	void (*get_resolution)(struct omap_dss_device *dssdev,
+			u16 *xres, u16 *yres);
+	int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
+
+	int (*check_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*set_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	void (*get_timings)(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings);
+	int (*update)(struct omap_dss_device *dssdev,
+			       u16 x, u16 y, u16 w, u16 h);
+	int (*sync)(struct omap_dss_device *dssdev);
+	int (*wait_vsync)(struct omap_dss_device *dssdev);
+
+	int (*set_update_mode)(struct omap_dss_device *dssdev,
+			enum omap_dss_update_mode);
+	enum omap_dss_update_mode (*get_update_mode)
+		(struct omap_dss_device *dssdev);
+
+	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
+	int (*get_te)(struct omap_dss_device *dssdev);
+
+	u8 (*get_rotate)(struct omap_dss_device *dssdev);
+	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
+
+	bool (*get_mirror)(struct omap_dss_device *dssdev);
+	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
+
+	int (*run_test)(struct omap_dss_device *dssdev, int test);
+	int (*memory_read)(struct omap_dss_device *dssdev,
+			void *buf, size_t size,
+			u16 x, u16 y, u16 w, u16 h);
+
+	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
+	u32 (*get_wss)(struct omap_dss_device *dssdev);
+
+	/* platform specific  */
+	int (*platform_enable)(struct omap_dss_device *dssdev);
+	void (*platform_disable)(struct omap_dss_device *dssdev);
+	int (*set_backlight)(struct omap_dss_device *dssdev, int level);
+	int (*get_backlight)(struct omap_dss_device *dssdev);
+};
+
+struct omap_dss_driver {
+	struct device_driver driver;
+
+	int (*probe)(struct omap_dss_device *);
+	void (*remove)(struct omap_dss_device *);
+
+	int (*enable)(struct omap_dss_device *display);
+	void (*disable)(struct omap_dss_device *display);
+	int (*suspend)(struct omap_dss_device *display);
+	int (*resume)(struct omap_dss_device *display);
+	int (*run_test)(struct omap_dss_device *display, int test);
+
+	void (*setup_update)(struct omap_dss_device *dssdev,
+			u16 x, u16 y, u16 w, u16 h);
+
+	int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
+	int (*wait_for_te)(struct omap_dss_device *dssdev);
+
+	u8 (*get_rotate)(struct omap_dss_device *dssdev);
+	int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
+
+	bool (*get_mirror)(struct omap_dss_device *dssdev);
+	int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
+
+	int (*memory_read)(struct omap_dss_device *dssdev,
+			void *buf, size_t size,
+			u16 x, u16 y, u16 w, u16 h);
+};
+
+int omap_dss_register_driver(struct omap_dss_driver *);
+void omap_dss_unregister_driver(struct omap_dss_driver *);
+
+int omap_dss_register_device(struct omap_dss_device *);
+void omap_dss_unregister_device(struct omap_dss_device *);
+
+void omap_dss_get_device(struct omap_dss_device *dssdev);
+void omap_dss_put_device(struct omap_dss_device *dssdev);
+#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
+struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
+struct omap_dss_device *omap_dss_find_device(void *data,
+		int (*match)(struct omap_dss_device *dssdev, void *data));
+
+int omap_dss_start_device(struct omap_dss_device *dssdev);
+void omap_dss_stop_device(struct omap_dss_device *dssdev);
+
+int omap_dss_get_num_overlay_managers(void);
+struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
+
+int omap_dss_get_num_overlays(void);
+struct omap_overlay *omap_dss_get_overlay(int num);
+
+typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
+int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+
+int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+		unsigned long timeout);
+
+#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
+#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dma.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,640 @@
+/*
+ *  arch/arm/plat-omap/include/mach/dma.h
+ *
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.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
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/* Hardware registers for omap1 */
+#define OMAP1_DMA_BASE			(0xfffed800)
+
+#define OMAP1_DMA_GCR			0x400
+#define OMAP1_DMA_GSCR			0x404
+#define OMAP1_DMA_GRST			0x408
+#define OMAP1_DMA_HW_ID			0x442
+#define OMAP1_DMA_PCH2_ID		0x444
+#define OMAP1_DMA_PCH0_ID		0x446
+#define OMAP1_DMA_PCH1_ID		0x448
+#define OMAP1_DMA_PCHG_ID		0x44a
+#define OMAP1_DMA_PCHD_ID		0x44c
+#define OMAP1_DMA_CAPS_0_U		0x44e
+#define OMAP1_DMA_CAPS_0_L		0x450
+#define OMAP1_DMA_CAPS_1_U		0x452
+#define OMAP1_DMA_CAPS_1_L		0x454
+#define OMAP1_DMA_CAPS_2		0x456
+#define OMAP1_DMA_CAPS_3		0x458
+#define OMAP1_DMA_CAPS_4		0x45a
+#define OMAP1_DMA_PCH2_SR		0x460
+#define OMAP1_DMA_PCH0_SR		0x480
+#define OMAP1_DMA_PCH1_SR		0x482
+#define OMAP1_DMA_PCHD_SR		0x4c0
+
+/* Hardware registers for omap2 and omap3 */
+#define OMAP24XX_DMA4_BASE		(L4_24XX_BASE + 0x56000)
+#define OMAP34XX_DMA4_BASE		(L4_34XX_BASE + 0x56000)
+#define OMAP44XX_DMA4_BASE		(L4_44XX_BASE + 0x56000)
+
+#define OMAP_DMA4_REVISION		0x00
+#define OMAP_DMA4_GCR			0x78
+#define OMAP_DMA4_IRQSTATUS_L0		0x08
+#define OMAP_DMA4_IRQSTATUS_L1		0x0c
+#define OMAP_DMA4_IRQSTATUS_L2		0x10
+#define OMAP_DMA4_IRQSTATUS_L3		0x14
+#define OMAP_DMA4_IRQENABLE_L0		0x18
+#define OMAP_DMA4_IRQENABLE_L1		0x1c
+#define OMAP_DMA4_IRQENABLE_L2		0x20
+#define OMAP_DMA4_IRQENABLE_L3		0x24
+#define OMAP_DMA4_SYSSTATUS		0x28
+#define OMAP_DMA4_OCP_SYSCONFIG		0x2c
+#define OMAP_DMA4_CAPS_0		0x64
+#define OMAP_DMA4_CAPS_2		0x6c
+#define OMAP_DMA4_CAPS_3		0x70
+#define OMAP_DMA4_CAPS_4		0x74
+
+#define OMAP1_LOGICAL_DMA_CH_COUNT	17
+#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT	32	/* REVISIT: Is this 32 + 2? */
+
+/* Common channel specific registers for omap1 */
+#define OMAP1_DMA_CH_BASE(n)		(0x40 * (n) + 0x00)
+#define OMAP1_DMA_CSDP(n)		(0x40 * (n) + 0x00)
+#define OMAP1_DMA_CCR(n)		(0x40 * (n) + 0x02)
+#define OMAP1_DMA_CICR(n)		(0x40 * (n) + 0x04)
+#define OMAP1_DMA_CSR(n)		(0x40 * (n) + 0x06)
+#define OMAP1_DMA_CEN(n)		(0x40 * (n) + 0x10)
+#define OMAP1_DMA_CFN(n)		(0x40 * (n) + 0x12)
+#define OMAP1_DMA_CSFI(n)		(0x40 * (n) + 0x14)
+#define OMAP1_DMA_CSEI(n)		(0x40 * (n) + 0x16)
+#define OMAP1_DMA_CPC(n)		(0x40 * (n) + 0x18)	/* 15xx only */
+#define OMAP1_DMA_CSAC(n)		(0x40 * (n) + 0x18)
+#define OMAP1_DMA_CDAC(n)		(0x40 * (n) + 0x1a)
+#define OMAP1_DMA_CDEI(n)		(0x40 * (n) + 0x1c)
+#define OMAP1_DMA_CDFI(n)		(0x40 * (n) + 0x1e)
+#define OMAP1_DMA_CLNK_CTRL(n)		(0x40 * (n) + 0x28)
+
+/* Common channel specific registers for omap2 */
+#define OMAP_DMA4_CH_BASE(n)		(0x60 * (n) + 0x80)
+#define OMAP_DMA4_CCR(n)		(0x60 * (n) + 0x80)
+#define OMAP_DMA4_CLNK_CTRL(n)		(0x60 * (n) + 0x84)
+#define OMAP_DMA4_CICR(n)		(0x60 * (n) + 0x88)
+#define OMAP_DMA4_CSR(n)		(0x60 * (n) + 0x8c)
+#define OMAP_DMA4_CSDP(n)		(0x60 * (n) + 0x90)
+#define OMAP_DMA4_CEN(n)		(0x60 * (n) + 0x94)
+#define OMAP_DMA4_CFN(n)		(0x60 * (n) + 0x98)
+#define OMAP_DMA4_CSEI(n)		(0x60 * (n) + 0xa4)
+#define OMAP_DMA4_CSFI(n)		(0x60 * (n) + 0xa8)
+#define OMAP_DMA4_CDEI(n)		(0x60 * (n) + 0xac)
+#define OMAP_DMA4_CDFI(n)		(0x60 * (n) + 0xb0)
+#define OMAP_DMA4_CSAC(n)		(0x60 * (n) + 0xb4)
+#define OMAP_DMA4_CDAC(n)		(0x60 * (n) + 0xb8)
+
+/* Channel specific registers only on omap1 */
+#define OMAP1_DMA_CSSA_L(n)		(0x40 * (n) + 0x08)
+#define OMAP1_DMA_CSSA_U(n)		(0x40 * (n) + 0x0a)
+#define OMAP1_DMA_CDSA_L(n)		(0x40 * (n) + 0x0c)
+#define OMAP1_DMA_CDSA_U(n)		(0x40 * (n) + 0x0e)
+#define OMAP1_DMA_COLOR_L(n)		(0x40 * (n) + 0x20)
+#define OMAP1_DMA_COLOR_U(n)		(0x40 * (n) + 0x22)
+#define OMAP1_DMA_CCR2(n)		(0x40 * (n) + 0x24)
+#define OMAP1_DMA_LCH_CTRL(n)		(0x40 * (n) + 0x2a)	/* not on 15xx */
+#define OMAP1_DMA_CCEN(n)		0
+#define OMAP1_DMA_CCFN(n)		0
+
+/* Channel specific registers only on omap2 */
+#define OMAP_DMA4_CSSA(n)		(0x60 * (n) + 0x9c)
+#define OMAP_DMA4_CDSA(n)		(0x60 * (n) + 0xa0)
+#define OMAP_DMA4_CCEN(n)		(0x60 * (n) + 0xbc)
+#define OMAP_DMA4_CCFN(n)		(0x60 * (n) + 0xc0)
+#define OMAP_DMA4_COLOR(n)		(0x60 * (n) + 0xc4)
+
+/* Additional registers available on OMAP4 */
+#define OMAP_DMA4_CDP(n)		(0x60 * (n) + 0xd0)
+#define OMAP_DMA4_CNDP(n)		(0x60 * (n) + 0xd4)
+#define OMAP_DMA4_CCDN(n)		(0x60 * (n) + 0xd8)
+
+/* Dummy defines to keep multi-omap compiles happy */
+#define OMAP1_DMA_REVISION		0
+#define OMAP1_DMA_IRQSTATUS_L0		0
+#define OMAP1_DMA_IRQENABLE_L0		0
+#define OMAP1_DMA_OCP_SYSCONFIG		0
+#define OMAP_DMA4_HW_ID			0
+#define OMAP_DMA4_CAPS_0_L		0
+#define OMAP_DMA4_CAPS_0_U		0
+#define OMAP_DMA4_CAPS_1_L		0
+#define OMAP_DMA4_CAPS_1_U		0
+#define OMAP_DMA4_GSCR			0
+#define OMAP_DMA4_CPC(n)		0
+
+#define OMAP_DMA4_LCH_CTRL(n)		0
+#define OMAP_DMA4_COLOR_L(n)		0
+#define OMAP_DMA4_COLOR_U(n)		0
+#define OMAP_DMA4_CCR2(n)		0
+#define OMAP1_DMA_CSSA(n)		0
+#define OMAP1_DMA_CDSA(n)		0
+#define OMAP_DMA4_CSSA_L(n)		0
+#define OMAP_DMA4_CSSA_U(n)		0
+#define OMAP_DMA4_CDSA_L(n)		0
+#define OMAP_DMA4_CDSA_U(n)		0
+#define OMAP1_DMA_COLOR(n)		0
+
+/*----------------------------------------------------------------------------*/
+
+/* DMA channels for omap1 */
+#define OMAP_DMA_NO_DEVICE		0
+#define OMAP_DMA_MCSI1_TX		1
+#define OMAP_DMA_MCSI1_RX		2
+#define OMAP_DMA_I2C_RX			3
+#define OMAP_DMA_I2C_TX			4
+#define OMAP_DMA_EXT_NDMA_REQ		5
+#define OMAP_DMA_EXT_NDMA_REQ2		6
+#define OMAP_DMA_UWIRE_TX		7
+#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_UART1_TX		12
+#define OMAP_DMA_UART1_RX		13
+#define OMAP_DMA_UART2_TX		14
+#define OMAP_DMA_UART2_RX		15
+#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_NAND			23
+#define OMAP_DMA_IRQ_LCD_LINE		24
+#define OMAP_DMA_MEMORY_STICK		25
+#define OMAP_DMA_USB_W2FC_RX0		26
+#define OMAP_DMA_USB_W2FC_RX1		27
+#define OMAP_DMA_USB_W2FC_RX2		28
+#define OMAP_DMA_USB_W2FC_TX0		29
+#define OMAP_DMA_USB_W2FC_TX1		30
+#define OMAP_DMA_USB_W2FC_TX2		31
+
+/* These are only for 1610 */
+#define OMAP_DMA_CRYPTO_DES_IN		32
+#define OMAP_DMA_SPI_TX			33
+#define OMAP_DMA_SPI_RX			34
+#define OMAP_DMA_CRYPTO_HASH		35
+#define OMAP_DMA_CCP_ATTN		36
+#define OMAP_DMA_CCP_FIFO_NOT_EMPTY	37
+#define OMAP_DMA_CMT_APE_TX_CHAN_0	38
+#define OMAP_DMA_CMT_APE_RV_CHAN_0	39
+#define OMAP_DMA_CMT_APE_TX_CHAN_1	40
+#define OMAP_DMA_CMT_APE_RV_CHAN_1	41
+#define OMAP_DMA_CMT_APE_TX_CHAN_2	42
+#define OMAP_DMA_CMT_APE_RV_CHAN_2	43
+#define OMAP_DMA_CMT_APE_TX_CHAN_3	44
+#define OMAP_DMA_CMT_APE_RV_CHAN_3	45
+#define OMAP_DMA_CMT_APE_TX_CHAN_4	46
+#define OMAP_DMA_CMT_APE_RV_CHAN_4	47
+#define OMAP_DMA_CMT_APE_TX_CHAN_5	48
+#define OMAP_DMA_CMT_APE_RV_CHAN_5	49
+#define OMAP_DMA_CMT_APE_TX_CHAN_6	50
+#define OMAP_DMA_CMT_APE_RV_CHAN_6	51
+#define OMAP_DMA_CMT_APE_TX_CHAN_7	52
+#define OMAP_DMA_CMT_APE_RV_CHAN_7	53
+#define OMAP_DMA_MMC2_TX		54
+#define OMAP_DMA_MMC2_RX		55
+#define OMAP_DMA_CRYPTO_DES_OUT		56
+
+/* DMA channels for 24xx */
+#define OMAP24XX_DMA_NO_DEVICE		0
+#define OMAP24XX_DMA_XTI_DMA		1	/* S_DMA_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_GFX		5	/* S_DMA_4 */
+#define OMAP24XX_DMA_DSS		6	/* S_DMA_5 */
+#define OMAP242X_DMA_VLYNQ_TX		7	/* S_DMA_6 */
+#define OMAP24XX_DMA_EXT_DMAREQ2	7	/* S_DMA_6 */
+#define OMAP24XX_DMA_CWT		8	/* S_DMA_7 */
+#define OMAP24XX_DMA_AES_TX		9	/* S_DMA_8 */
+#define OMAP24XX_DMA_AES_RX		10	/* S_DMA_9 */
+#define OMAP24XX_DMA_DES_TX		11	/* S_DMA_10 */
+#define OMAP24XX_DMA_DES_RX		12	/* S_DMA_11 */
+#define OMAP24XX_DMA_SHA1MD5_RX		13	/* S_DMA_12 */
+#define OMAP34XX_DMA_SHA2MD5_RX		13	/* S_DMA_12 */
+#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 OMAP242X_DMA_EAC_AC_RD		17	/* S_DMA_16 */
+#define OMAP242X_DMA_EAC_AC_WR		18	/* S_DMA_17 */
+#define OMAP242X_DMA_EAC_MD_UL_RD	19	/* S_DMA_18 */
+#define OMAP242X_DMA_EAC_MD_UL_WR	20	/* S_DMA_19 */
+#define OMAP242X_DMA_EAC_MD_DL_RD	21	/* S_DMA_20 */
+#define OMAP242X_DMA_EAC_MD_DL_WR	22	/* S_DMA_21 */
+#define OMAP242X_DMA_EAC_BT_UL_RD	23	/* S_DMA_22 */
+#define OMAP242X_DMA_EAC_BT_UL_WR	24	/* S_DMA_23 */
+#define OMAP242X_DMA_EAC_BT_DL_RD	25	/* S_DMA_24 */
+#define OMAP242X_DMA_EAC_BT_DL_WR	26	/* S_DMA_25 */
+#define OMAP243X_DMA_EXT_DMAREQ3	14	/* S_DMA_13 */
+#define OMAP24XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
+#define OMAP24XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
+#define OMAP24XX_DMA_MCBSP3_TX		17	/* S_DMA_16 */
+#define OMAP24XX_DMA_MCBSP3_RX		18	/* S_DMA_17 */
+#define OMAP24XX_DMA_MCBSP4_TX		19	/* S_DMA_18 */
+#define OMAP24XX_DMA_MCBSP4_RX		20	/* S_DMA_19 */
+#define OMAP24XX_DMA_MCBSP5_TX		21	/* S_DMA_20 */
+#define OMAP24XX_DMA_MCBSP5_RX		22	/* S_DMA_21 */
+#define OMAP24XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
+#define OMAP24XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
+#define OMAP243X_DMA_EXT_DMAREQ4	25	/* S_DMA_24 */
+#define OMAP243X_DMA_EXT_DMAREQ5	26	/* S_DMA_25 */
+#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_MCBSP1_TX		31	/* S_DMA_30 */
+#define OMAP24XX_DMA_MCBSP1_RX		32	/* S_DMA_31 */
+#define OMAP24XX_DMA_MCBSP2_TX		33	/* S_DMA_32 */
+#define OMAP24XX_DMA_MCBSP2_RX		34	/* S_DMA_33 */
+#define OMAP24XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
+#define OMAP24XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
+#define OMAP24XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
+#define OMAP24XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
+#define OMAP24XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
+#define OMAP24XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
+#define OMAP24XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
+#define OMAP24XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
+#define OMAP24XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
+#define OMAP24XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
+#define OMAP24XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
+#define OMAP24XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
+#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_USB_W2FC_TX0	55	/* S_DMA_54 */
+#define OMAP24XX_DMA_USB_W2FC_RX0	56	/* S_DMA_55 */
+#define OMAP24XX_DMA_USB_W2FC_TX1	57	/* S_DMA_56 */
+#define OMAP24XX_DMA_USB_W2FC_RX1	58	/* S_DMA_57 */
+#define OMAP24XX_DMA_USB_W2FC_TX2	59	/* S_DMA_58 */
+#define OMAP24XX_DMA_USB_W2FC_RX2	60	/* S_DMA_59 */
+#define OMAP24XX_DMA_MMC1_TX		61	/* S_DMA_60 */
+#define OMAP24XX_DMA_MMC1_RX		62	/* S_DMA_61 */
+#define OMAP24XX_DMA_MS			63	/* S_DMA_62 */
+#define OMAP242X_DMA_EXT_DMAREQ5	64	/* S_DMA_63 */
+#define OMAP243X_DMA_EXT_DMAREQ6	64	/* S_DMA_63 */
+#define OMAP34XX_DMA_EXT_DMAREQ3	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_DES2_TX		67	/* S_DMA_66 */
+#define OMAP34XX_DMA_DES2_RX		68	/* S_DMA_67 */
+#define OMAP34XX_DMA_SHA1MD5_RX		69	/* S_DMA_68 */
+#define OMAP34XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
+#define OMAP34XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
+#define OMAP34XX_DSS_DMA0		72	/* S_DMA_71 */
+#define OMAP34XX_DSS_DMA1		73	/* S_DMA_72 */
+#define OMAP34XX_DSS_DMA2		74	/* S_DMA_73 */
+#define OMAP34XX_DSS_DMA3		75	/* S_DMA_74 */
+#define OMAP34XX_DMA_MMC3_TX		77	/* S_DMA_76 */
+#define OMAP34XX_DMA_MMC3_RX		78	/* S_DMA_77 */
+#define OMAP34XX_DMA_USIM_TX		79	/* S_DMA_78 */
+#define OMAP34XX_DMA_USIM_RX		80	/* S_DMA_79 */
+
+/* DMA request lines for 44xx */
+#define OMAP44XX_DMA_DSS_DISPC_REQ	6	/* S_DMA_5 */
+#define OMAP44XX_DMA_SYS_REQ2		7	/* S_DMA_6 */
+#define OMAP44XX_DMA_ISS_REQ1		9	/* S_DMA_8 */
+#define OMAP44XX_DMA_ISS_REQ2		10	/* S_DMA_9 */
+#define OMAP44XX_DMA_ISS_REQ3		12	/* S_DMA_11 */
+#define OMAP44XX_DMA_ISS_REQ4		13	/* S_DMA_12 */
+#define OMAP44XX_DMA_DSS_RFBI_REQ	14	/* S_DMA_13 */
+#define OMAP44XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
+#define OMAP44XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
+#define OMAP44XX_DMA_MCBSP2_TX		17	/* S_DMA_16 */
+#define OMAP44XX_DMA_MCBSP2_RX		18	/* S_DMA_17 */
+#define OMAP44XX_DMA_MCBSP3_TX		19	/* S_DMA_18 */
+#define OMAP44XX_DMA_MCBSP3_RX		20	/* S_DMA_19 */
+#define OMAP44XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
+#define OMAP44XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
+#define OMAP44XX_DMA_I2C3_TX		25	/* S_DMA_24 */
+#define OMAP44XX_DMA_I2C3_RX		26	/* S_DMA_25 */
+#define OMAP44XX_DMA_I2C1_TX		27	/* S_DMA_26 */
+#define OMAP44XX_DMA_I2C1_RX		28	/* S_DMA_27 */
+#define OMAP44XX_DMA_I2C2_TX		29	/* S_DMA_28 */
+#define OMAP44XX_DMA_I2C2_RX		30	/* S_DMA_29 */
+#define OMAP44XX_DMA_MCBSP4_TX		31	/* S_DMA_30 */
+#define OMAP44XX_DMA_MCBSP4_RX		32	/* S_DMA_31 */
+#define OMAP44XX_DMA_MCBSP1_TX		33	/* S_DMA_32 */
+#define OMAP44XX_DMA_MCBSP1_RX		34	/* S_DMA_33 */
+#define OMAP44XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
+#define OMAP44XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
+#define OMAP44XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
+#define OMAP44XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
+#define OMAP44XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
+#define OMAP44XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
+#define OMAP44XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
+#define OMAP44XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
+#define OMAP44XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
+#define OMAP44XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
+#define OMAP44XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
+#define OMAP44XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
+#define OMAP44XX_DMA_MMC2_TX		47	/* S_DMA_46 */
+#define OMAP44XX_DMA_MMC2_RX		48	/* S_DMA_47 */
+#define OMAP44XX_DMA_UART1_TX		49	/* S_DMA_48 */
+#define OMAP44XX_DMA_UART1_RX		50	/* S_DMA_49 */
+#define OMAP44XX_DMA_UART2_TX		51	/* S_DMA_50 */
+#define OMAP44XX_DMA_UART2_RX		52	/* S_DMA_51 */
+#define OMAP44XX_DMA_UART3_TX		53	/* S_DMA_52 */
+#define OMAP44XX_DMA_UART3_RX		54	/* S_DMA_53 */
+#define OMAP44XX_DMA_UART4_TX		55	/* S_DMA_54 */
+#define OMAP44XX_DMA_UART4_RX		56	/* S_DMA_55 */
+#define OMAP44XX_DMA_MMC4_TX		57	/* S_DMA_56 */
+#define OMAP44XX_DMA_MMC4_RX		58	/* S_DMA_57 */
+#define OMAP44XX_DMA_MMC5_TX		59	/* S_DMA_58 */
+#define OMAP44XX_DMA_MMC5_RX		60	/* S_DMA_59 */
+#define OMAP44XX_DMA_MMC1_TX		61	/* S_DMA_60 */
+#define OMAP44XX_DMA_MMC1_RX		62	/* S_DMA_61 */
+#define OMAP44XX_DMA_SYS_REQ3		64	/* S_DMA_63 */
+#define OMAP44XX_DMA_MCPDM_UP		65	/* S_DMA_64 */
+#define OMAP44XX_DMA_MCPDM_DL		66	/* S_DMA_65 */
+#define OMAP44XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
+#define OMAP44XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ0	72	/* S_DMA_71 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ1	73	/* S_DMA_72 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ2	74	/* S_DMA_73 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ3	75	/* S_DMA_74 */
+#define OMAP44XX_DMA_DSS_HDMI_REQ	76	/* S_DMA_75 */
+#define OMAP44XX_DMA_MMC3_TX		77	/* S_DMA_76 */
+#define OMAP44XX_DMA_MMC3_RX		78	/* S_DMA_77 */
+#define OMAP44XX_DMA_USIM_TX		79	/* S_DMA_78 */
+#define OMAP44XX_DMA_USIM_RX		80	/* S_DMA_79 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ0	81	/* S_DMA_80 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ1	82	/* S_DMA_81 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ2	83	/* S_DMA_82 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ3	84	/* S_DMA_83 */
+#define OMAP44XX_DMA_ABE_REQ0		101	/* S_DMA_100 */
+#define OMAP44XX_DMA_ABE_REQ1		102	/* S_DMA_101 */
+#define OMAP44XX_DMA_ABE_REQ2		103	/* S_DMA_102 */
+#define OMAP44XX_DMA_ABE_REQ3		104	/* S_DMA_103 */
+#define OMAP44XX_DMA_ABE_REQ4		105	/* S_DMA_104 */
+#define OMAP44XX_DMA_ABE_REQ5		106	/* S_DMA_105 */
+#define OMAP44XX_DMA_ABE_REQ6		107	/* S_DMA_106 */
+#define OMAP44XX_DMA_ABE_REQ7		108	/* S_DMA_107 */
+#define OMAP44XX_DMA_I2C4_TX		124	/* S_DMA_123 */
+#define OMAP44XX_DMA_I2C4_RX		125	/* S_DMA_124 */
+
+/*----------------------------------------------------------------------------*/
+
+#define OMAP1_DMA_TOUT_IRQ		(1 << 0)
+#define OMAP_DMA_DROP_IRQ		(1 << 1)
+#define OMAP_DMA_HALF_IRQ		(1 << 2)
+#define OMAP_DMA_FRAME_IRQ		(1 << 3)
+#define OMAP_DMA_LAST_IRQ		(1 << 4)
+#define OMAP_DMA_BLOCK_IRQ		(1 << 5)
+#define OMAP1_DMA_SYNC_IRQ		(1 << 6)
+#define OMAP2_DMA_PKT_IRQ		(1 << 7)
+#define OMAP2_DMA_TRANS_ERR_IRQ		(1 << 8)
+#define OMAP2_DMA_SECURE_ERR_IRQ	(1 << 9)
+#define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
+#define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
+
+#define OMAP_DMA_CCR_EN			(1 << 7)
+
+#define OMAP_DMA_DATA_TYPE_S8		0x00
+#define OMAP_DMA_DATA_TYPE_S16		0x01
+#define OMAP_DMA_DATA_TYPE_S32		0x02
+
+#define OMAP_DMA_SYNC_ELEMENT		0x00
+#define OMAP_DMA_SYNC_FRAME		0x01
+#define OMAP_DMA_SYNC_BLOCK		0x02
+#define OMAP_DMA_SYNC_PACKET		0x03
+
+#define OMAP_DMA_SRC_SYNC		0x01
+#define OMAP_DMA_DST_SYNC		0x00
+
+#define OMAP_DMA_PORT_EMIFF		0x00
+#define OMAP_DMA_PORT_EMIFS		0x01
+#define OMAP_DMA_PORT_OCP_T1		0x02
+#define OMAP_DMA_PORT_TIPB		0x03
+#define OMAP_DMA_PORT_OCP_T2		0x04
+#define OMAP_DMA_PORT_MPUI		0x05
+
+#define OMAP_DMA_AMODE_CONSTANT		0x00
+#define OMAP_DMA_AMODE_POST_INC		0x01
+#define OMAP_DMA_AMODE_SINGLE_IDX	0x02
+#define OMAP_DMA_AMODE_DOUBLE_IDX	0x03
+
+#define DMA_DEFAULT_FIFO_DEPTH		0x10
+#define DMA_DEFAULT_ARB_RATE		0x01
+/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
+#define DMA_THREAD_RESERVE_NORM		(0x00 << 12) /* Def */
+#define DMA_THREAD_RESERVE_ONET		(0x01 << 12)
+#define DMA_THREAD_RESERVE_TWOT		(0x02 << 12)
+#define DMA_THREAD_RESERVE_THREET	(0x03 << 12)
+#define DMA_THREAD_FIFO_NONE		(0x00 << 14) /* Def */
+#define DMA_THREAD_FIFO_75		(0x01 << 14)
+#define DMA_THREAD_FIFO_25		(0x02 << 14)
+#define DMA_THREAD_FIFO_50		(0x03 << 14)
+
+/* DMA4_OCP_SYSCONFIG bits */
+#define DMA_SYSCONFIG_MIDLEMODE_MASK		(3 << 12)
+#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
+#define DMA_SYSCONFIG_EMUFREE			(1 << 5)
+#define DMA_SYSCONFIG_SIDLEMODE_MASK		(3 << 3)
+#define DMA_SYSCONFIG_SOFTRESET			(1 << 2)
+#define DMA_SYSCONFIG_AUTOIDLE			(1 << 0)
+
+#define DMA_SYSCONFIG_MIDLEMODE(n)		((n) << 12)
+#define DMA_SYSCONFIG_SIDLEMODE(n)		((n) << 3)
+
+#define DMA_IDLEMODE_SMARTIDLE			0x2
+#define DMA_IDLEMODE_NO_IDLE			0x1
+#define DMA_IDLEMODE_FORCE_IDLE			0x0
+
+/* Chaining modes*/
+#ifndef CONFIG_ARCH_OMAP1
+#define OMAP_DMA_STATIC_CHAIN		0x1
+#define OMAP_DMA_DYNAMIC_CHAIN		0x2
+#define OMAP_DMA_CHAIN_ACTIVE		0x1
+#define OMAP_DMA_CHAIN_INACTIVE		0x0
+#endif
+
+#define DMA_CH_PRIO_HIGH		0x1
+#define DMA_CH_PRIO_LOW			0x0 /* Def */
+
+enum omap_dma_burst_mode {
+	OMAP_DMA_DATA_BURST_DIS = 0,
+	OMAP_DMA_DATA_BURST_4,
+	OMAP_DMA_DATA_BURST_8,
+	OMAP_DMA_DATA_BURST_16,
+};
+
+enum end_type {
+	OMAP_DMA_LITTLE_ENDIAN = 0,
+	OMAP_DMA_BIG_ENDIAN
+};
+
+enum omap_dma_color_mode {
+	OMAP_DMA_COLOR_DIS = 0,
+	OMAP_DMA_CONSTANT_FILL,
+	OMAP_DMA_TRANSPARENT_COPY
+};
+
+enum omap_dma_write_mode {
+	OMAP_DMA_WRITE_NON_POSTED = 0,
+	OMAP_DMA_WRITE_POSTED,
+	OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
+enum omap_dma_channel_mode {
+	OMAP_DMA_LCH_2D = 0,
+	OMAP_DMA_LCH_G,
+	OMAP_DMA_LCH_P,
+	OMAP_DMA_LCH_PD
+};
+
+struct omap_dma_channel_params {
+	int data_type;		/* data type 8,16,32 */
+	int elem_count;		/* number of elements in a frame */
+	int frame_count;	/* number of frames in a element */
+
+	int src_port;		/* Only on OMAP1 REVISIT: Is this needed? */
+	int src_amode;		/* constant, post increment, indexed,
+					double indexed */
+	unsigned long src_start;	/* source address : physical */
+	int src_ei;		/* source element index */
+	int src_fi;		/* source frame index */
+
+	int dst_port;		/* Only on OMAP1 REVISIT: Is this needed? */
+	int dst_amode;		/* constant, post increment, indexed,
+					double indexed */
+	unsigned long dst_start;	/* source address : physical */
+	int dst_ei;		/* source element index */
+	int dst_fi;		/* source frame index */
+
+	int trigger;		/* trigger attached if the channel is
+					synchronized */
+	int sync_mode;		/* sycn on element, frame , block or packet */
+	int src_or_dst_synch;	/* source synch(1) or destination synch(0) */
+
+	int ie;			/* interrupt enabled */
+
+	unsigned char read_prio;/* read priority */
+	unsigned char write_prio;/* write priority */
+
+#ifndef CONFIG_ARCH_OMAP1
+	enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
+#endif
+};
+
+
+extern void omap_set_dma_priority(int lch, int dst_port, int priority);
+extern int omap_request_dma(int dev_id, const char *dev_name,
+			void (*callback)(int lch, u16 ch_status, void *data),
+			void *data, int *dma_ch);
+extern void omap_enable_dma_irq(int ch, u16 irq_bits);
+extern void omap_disable_dma_irq(int ch, u16 irq_bits);
+extern void omap_free_dma(int ch);
+extern void omap_start_dma(int lch);
+extern void omap_stop_dma(int lch);
+extern void omap_set_dma_transfer_params(int lch, int data_type,
+					 int elem_count, int frame_count,
+					 int sync_mode,
+					 int dma_trigger, int src_or_dst_synch);
+extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
+				    u32 color);
+extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
+extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
+
+extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
+				    unsigned long src_start,
+				    int src_ei, int src_fi);
+extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_src_data_pack(int lch, int enable);
+extern void omap_set_dma_src_burst_mode(int lch,
+					enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
+				     unsigned long dest_start,
+				     int dst_ei, int dst_fi);
+extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_dest_data_pack(int lch, int enable);
+extern void omap_set_dma_dest_burst_mode(int lch,
+					 enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_params(int lch,
+				struct omap_dma_channel_params *params);
+
+extern void omap_dma_link_lch(int lch_head, int lch_queue);
+extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
+
+extern int omap_set_dma_callback(int lch,
+			void (*callback)(int lch, u16 ch_status, void *data),
+			void *data);
+extern dma_addr_t omap_get_dma_src_pos(int lch);
+extern dma_addr_t omap_get_dma_dst_pos(int lch);
+extern void omap_clear_dma(int lch);
+extern int omap_get_dma_active_status(int lch);
+extern int omap_dma_running(void);
+extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
+				       int tparams);
+extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
+				 unsigned char write_prio);
+extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
+extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
+extern int omap_get_dma_index(int lch, int *ei, int *fi);
+
+void omap_dma_global_context_save(void);
+void omap_dma_global_context_restore(void);
+
+extern void omap_dma_disable_irq(int lch);
+
+/* Chaining APIs */
+#ifndef CONFIG_ARCH_OMAP1
+extern int omap_request_dma_chain(int dev_id, const char *dev_name,
+				  void (*callback) (int lch, u16 ch_status,
+						    void *data),
+				  int *chain_id, int no_of_chans,
+				  int chain_mode,
+				  struct omap_dma_channel_params params);
+extern int omap_free_dma_chain(int chain_id);
+extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
+				     int dest_start, int elem_count,
+				     int frame_count, void *callbk_data);
+extern int omap_start_dma_chain_transfers(int chain_id);
+extern int omap_stop_dma_chain_transfers(int chain_id);
+extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
+extern int omap_get_dma_chain_dst_pos(int chain_id);
+extern int omap_get_dma_chain_src_pos(int chain_id);
+
+extern int omap_modify_dma_chain_params(int chain_id,
+					struct omap_dma_channel_params params);
+extern int omap_dma_chain_status(int chain_id);
+#endif
+
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
+#include <mach/lcd_dma.h>
+#else
+static inline int omap_lcd_dma_running(void)
+{
+	return 0;
+}
+#endif
+
+#endif /* __ASM_ARCH_DMA_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dmtimer.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dmtimer.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dmtimer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dmtimer.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/plat-omap/include/mach/dmtimer.h
+ *
+ * OMAP Dual-Mode Timers
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * PWM and clock framwork support by Timo Teras.
+ *
+ * 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
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_DMTIMER_H
+#define __ASM_ARCH_DMTIMER_H
+
+/* clock sources */
+#define OMAP_TIMER_SRC_SYS_CLK			0x00
+#define OMAP_TIMER_SRC_32_KHZ			0x01
+#define OMAP_TIMER_SRC_EXT_CLK			0x02
+
+/* timer interrupt enable bits */
+#define OMAP_TIMER_INT_CAPTURE			(1 << 2)
+#define OMAP_TIMER_INT_OVERFLOW			(1 << 1)
+#define OMAP_TIMER_INT_MATCH			(1 << 0)
+
+/* trigger types */
+#define OMAP_TIMER_TRIGGER_NONE			0x00
+#define OMAP_TIMER_TRIGGER_OVERFLOW		0x01
+#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
+
+struct omap_dm_timer;
+struct clk;
+
+int omap_dm_timer_init(void);
+
+struct omap_dm_timer *omap_dm_timer_request(void);
+struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
+void omap_dm_timer_free(struct omap_dm_timer *timer);
+void omap_dm_timer_enable(struct omap_dm_timer *timer);
+void omap_dm_timer_disable(struct omap_dm_timer *timer);
+
+int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
+
+u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
+
+void omap_dm_timer_trigger(struct omap_dm_timer *timer);
+void omap_dm_timer_start(struct omap_dm_timer *timer);
+void omap_dm_timer_stop(struct omap_dm_timer *timer);
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
+void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
+void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+
+void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
+void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
+
+int omap_dm_timers_active(void);
+
+
+#endif /* __ASM_ARCH_DMTIMER_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dsp_common.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dsp_common.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/dsp_common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/dsp_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,40 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@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
+ *
+ */
+
+#ifndef ASM_ARCH_DSP_COMMON_H
+#define ASM_ARCH_DSP_COMMON_H
+
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_OMAP_MMU_FWK)
+extern void omap_dsp_request_mpui(void);
+extern void omap_dsp_release_mpui(void);
+extern int omap_dsp_request_mem(void);
+extern int omap_dsp_release_mem(void);
+#else
+static inline int omap_dsp_request_mem(void)
+{
+	return 0;
+}
+#define omap_dsp_release_mem()	do {} while (0)
+#endif
+
+#endif /* ASM_ARCH_DSP_COMMON_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/fpga.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/fpga.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/fpga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/fpga.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,197 @@
+/*
+ * arch/arm/plat-omap/include/mach/fpga.h
+ *
+ * Interrupt handler for OMAP-1510 FPGA
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.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 __ASM_ARCH_OMAP_FPGA_H
+#define __ASM_ARCH_OMAP_FPGA_H
+
+#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
+extern void omap1510_fpga_init_irq(void);
+#else
+#define omap1510_fpga_init_irq()	(0)
+#endif
+
+#define fpga_read(reg)			__raw_readb(reg)
+#define fpga_write(val, reg)		__raw_writeb(val, reg)
+
+/*
+ * ---------------------------------------------------------------------------
+ *  H2/P2 Debug board FPGA
+ * ---------------------------------------------------------------------------
+ */
+/* maps in the FPGA registers and the ETHR registers */
+#define H2P2_DBG_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
+#define H2P2_DBG_FPGA_SIZE		SZ_4K			/* SIZE */
+#define H2P2_DBG_FPGA_START		0x04000000		/* PA */
+
+#define H2P2_DBG_FPGA_ETHR_START	(H2P2_DBG_FPGA_START + 0x300)
+#define H2P2_DBG_FPGA_FPGA_REV		(H2P2_DBG_FPGA_BASE + 0x10)	/* FPGA Revision */
+#define H2P2_DBG_FPGA_BOARD_REV		(H2P2_DBG_FPGA_BASE + 0x12)	/* Board Revision */
+#define H2P2_DBG_FPGA_GPIO		(H2P2_DBG_FPGA_BASE + 0x14)	/* GPIO outputs */
+#define H2P2_DBG_FPGA_LEDS		(H2P2_DBG_FPGA_BASE + 0x16)	/* LEDs outputs */
+#define H2P2_DBG_FPGA_MISC_INPUTS	(H2P2_DBG_FPGA_BASE + 0x18)	/* Misc inputs */
+#define H2P2_DBG_FPGA_LAN_STATUS	(H2P2_DBG_FPGA_BASE + 0x1A)	/* LAN Status line */
+#define H2P2_DBG_FPGA_LAN_RESET		(H2P2_DBG_FPGA_BASE + 0x1C)	/* LAN Reset line */
+
+/* NOTE:  most boards don't have a static mapping for the FPGA ... */
+struct h2p2_dbg_fpga {
+	/* offset 0x00 */
+	u16		smc91x[8];
+	/* offset 0x10 */
+	u16		fpga_rev;
+	u16		board_rev;
+	u16		gpio_outputs;
+	u16		leds;
+	/* offset 0x18 */
+	u16		misc_inputs;
+	u16		lan_status;
+	u16		lan_reset;
+	u16		reserved0;
+	/* offset 0x20 */
+	u16		ps2_data;
+	u16		ps2_ctrl;
+	/* plus also 4 rs232 ports ... */
+};
+
+/* LEDs definition on debug board (16 LEDs, all physically green) */
+#define H2P2_DBG_FPGA_LED_GREEN		(1 << 15)
+#define H2P2_DBG_FPGA_LED_AMBER		(1 << 14)
+#define H2P2_DBG_FPGA_LED_RED		(1 << 13)
+#define H2P2_DBG_FPGA_LED_BLUE		(1 << 12)
+/*  cpu0 load-meter LEDs */
+#define H2P2_DBG_FPGA_LOAD_METER	(1 << 0)	// A bit of fun on our board ...
+#define H2P2_DBG_FPGA_LOAD_METER_SIZE	11
+#define H2P2_DBG_FPGA_LOAD_METER_MASK	((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
+
+#define H2P2_DBG_FPGA_P2_LED_TIMER		(1 << 0)
+#define H2P2_DBG_FPGA_P2_LED_IDLE		(1 << 1)
+
+/*
+ * ---------------------------------------------------------------------------
+ *  OMAP-1510 FPGA
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP1510_FPGA_BASE		IOMEM(0xE8000000)	/* VA */
+#define OMAP1510_FPGA_SIZE		SZ_4K
+#define OMAP1510_FPGA_START		0x08000000		/* PA */
+
+/* Revision */
+#define OMAP1510_FPGA_REV_LOW			(OMAP1510_FPGA_BASE + 0x0)
+#define OMAP1510_FPGA_REV_HIGH			(OMAP1510_FPGA_BASE + 0x1)
+
+#define OMAP1510_FPGA_LCD_PANEL_CONTROL		(OMAP1510_FPGA_BASE + 0x2)
+#define OMAP1510_FPGA_LED_DIGIT			(OMAP1510_FPGA_BASE + 0x3)
+#define INNOVATOR_FPGA_HID_SPI			(OMAP1510_FPGA_BASE + 0x4)
+#define OMAP1510_FPGA_POWER			(OMAP1510_FPGA_BASE + 0x5)
+
+/* Interrupt status */
+#define OMAP1510_FPGA_ISR_LO			(OMAP1510_FPGA_BASE + 0x6)
+#define OMAP1510_FPGA_ISR_HI			(OMAP1510_FPGA_BASE + 0x7)
+
+/* Interrupt mask */
+#define OMAP1510_FPGA_IMR_LO			(OMAP1510_FPGA_BASE + 0x8)
+#define OMAP1510_FPGA_IMR_HI			(OMAP1510_FPGA_BASE + 0x9)
+
+/* Reset registers */
+#define OMAP1510_FPGA_HOST_RESET		(OMAP1510_FPGA_BASE + 0xa)
+#define OMAP1510_FPGA_RST			(OMAP1510_FPGA_BASE + 0xb)
+
+#define OMAP1510_FPGA_AUDIO			(OMAP1510_FPGA_BASE + 0xc)
+#define OMAP1510_FPGA_DIP			(OMAP1510_FPGA_BASE + 0xe)
+#define OMAP1510_FPGA_FPGA_IO			(OMAP1510_FPGA_BASE + 0xf)
+#define OMAP1510_FPGA_UART1			(OMAP1510_FPGA_BASE + 0x14)
+#define OMAP1510_FPGA_UART2			(OMAP1510_FPGA_BASE + 0x15)
+#define OMAP1510_FPGA_OMAP1510_STATUS		(OMAP1510_FPGA_BASE + 0x16)
+#define OMAP1510_FPGA_BOARD_REV			(OMAP1510_FPGA_BASE + 0x18)
+#define OMAP1510P1_PPT_DATA			(OMAP1510_FPGA_BASE + 0x100)
+#define OMAP1510P1_PPT_STATUS			(OMAP1510_FPGA_BASE + 0x101)
+#define OMAP1510P1_PPT_CONTROL			(OMAP1510_FPGA_BASE + 0x102)
+
+#define OMAP1510_FPGA_TOUCHSCREEN		(OMAP1510_FPGA_BASE + 0x204)
+
+#define INNOVATOR_FPGA_INFO			(OMAP1510_FPGA_BASE + 0x205)
+#define INNOVATOR_FPGA_LCD_BRIGHT_LO		(OMAP1510_FPGA_BASE + 0x206)
+#define INNOVATOR_FPGA_LCD_BRIGHT_HI		(OMAP1510_FPGA_BASE + 0x207)
+#define INNOVATOR_FPGA_LED_GRN_LO		(OMAP1510_FPGA_BASE + 0x208)
+#define INNOVATOR_FPGA_LED_GRN_HI		(OMAP1510_FPGA_BASE + 0x209)
+#define INNOVATOR_FPGA_LED_RED_LO		(OMAP1510_FPGA_BASE + 0x20a)
+#define INNOVATOR_FPGA_LED_RED_HI		(OMAP1510_FPGA_BASE + 0x20b)
+#define INNOVATOR_FPGA_CAM_USB_CONTROL		(OMAP1510_FPGA_BASE + 0x20c)
+#define INNOVATOR_FPGA_EXP_CONTROL		(OMAP1510_FPGA_BASE + 0x20d)
+#define INNOVATOR_FPGA_ISR2			(OMAP1510_FPGA_BASE + 0x20e)
+#define INNOVATOR_FPGA_IMR2			(OMAP1510_FPGA_BASE + 0x210)
+
+#define OMAP1510_FPGA_ETHR_START		(OMAP1510_FPGA_START + 0x300)
+
+/*
+ * Power up Giga UART driver, turn on HID clock.
+ * Turn off BT power, since we're not using it and it
+ * draws power.
+ */
+#define OMAP1510_FPGA_RESET_VALUE		0x42
+
+#define OMAP1510_FPGA_PCR_IF_PD0		(1 << 7)
+#define OMAP1510_FPGA_PCR_COM2_EN		(1 << 6)
+#define OMAP1510_FPGA_PCR_COM1_EN		(1 << 5)
+#define OMAP1510_FPGA_PCR_EXP_PD0		(1 << 4)
+#define OMAP1510_FPGA_PCR_EXP_PD1		(1 << 3)
+#define OMAP1510_FPGA_PCR_48MHZ_CLK		(1 << 2)
+#define OMAP1510_FPGA_PCR_4MHZ_CLK		(1 << 1)
+#define OMAP1510_FPGA_PCR_RSRVD_BIT0		(1 << 0)
+
+/*
+ * Innovator/OMAP1510 FPGA HID register bit definitions
+ */
+#define OMAP1510_FPGA_HID_SCLK	(1<<0)	/* output */
+#define OMAP1510_FPGA_HID_MOSI	(1<<1)	/* output */
+#define OMAP1510_FPGA_HID_nSS	(1<<2)	/* output 0/1 chip idle/select */
+#define OMAP1510_FPGA_HID_nHSUS	(1<<3)	/* output 0/1 host active/suspended */
+#define OMAP1510_FPGA_HID_MISO	(1<<4)	/* input */
+#define OMAP1510_FPGA_HID_ATN	(1<<5)	/* input  0/1 chip idle/ATN */
+#define OMAP1510_FPGA_HID_rsrvd	(1<<6)
+#define OMAP1510_FPGA_HID_RESETn (1<<7)	/* output - 0/1 USAR reset/run */
+
+/* The FPGA IRQ is cascaded through GPIO_13 */
+#define OMAP1510_INT_FPGA		(IH_GPIO_BASE + 13)
+
+/* IRQ Numbers for interrupts muxed through the FPGA */
+#define OMAP1510_INT_FPGA_ATN		(OMAP_FPGA_IRQ_BASE + 0)
+#define OMAP1510_INT_FPGA_ACK		(OMAP_FPGA_IRQ_BASE + 1)
+#define OMAP1510_INT_FPGA2		(OMAP_FPGA_IRQ_BASE + 2)
+#define OMAP1510_INT_FPGA3		(OMAP_FPGA_IRQ_BASE + 3)
+#define OMAP1510_INT_FPGA4		(OMAP_FPGA_IRQ_BASE + 4)
+#define OMAP1510_INT_FPGA5		(OMAP_FPGA_IRQ_BASE + 5)
+#define OMAP1510_INT_FPGA6		(OMAP_FPGA_IRQ_BASE + 6)
+#define OMAP1510_INT_FPGA7		(OMAP_FPGA_IRQ_BASE + 7)
+#define OMAP1510_INT_FPGA8		(OMAP_FPGA_IRQ_BASE + 8)
+#define OMAP1510_INT_FPGA9		(OMAP_FPGA_IRQ_BASE + 9)
+#define OMAP1510_INT_FPGA10		(OMAP_FPGA_IRQ_BASE + 10)
+#define OMAP1510_INT_FPGA11		(OMAP_FPGA_IRQ_BASE + 11)
+#define OMAP1510_INT_FPGA12		(OMAP_FPGA_IRQ_BASE + 12)
+#define OMAP1510_INT_ETHER		(OMAP_FPGA_IRQ_BASE + 13)
+#define OMAP1510_INT_FPGAUART1		(OMAP_FPGA_IRQ_BASE + 14)
+#define OMAP1510_INT_FPGAUART2		(OMAP_FPGA_IRQ_BASE + 15)
+#define OMAP1510_INT_FPGA_TS		(OMAP_FPGA_IRQ_BASE + 16)
+#define OMAP1510_INT_FPGA17		(OMAP_FPGA_IRQ_BASE + 17)
+#define OMAP1510_INT_FPGA_CAM		(OMAP_FPGA_IRQ_BASE + 18)
+#define OMAP1510_INT_FPGA_RTC_A		(OMAP_FPGA_IRQ_BASE + 19)
+#define OMAP1510_INT_FPGA_RTC_B		(OMAP_FPGA_IRQ_BASE + 20)
+#define OMAP1510_INT_FPGA_CD		(OMAP_FPGA_IRQ_BASE + 21)
+#define OMAP1510_INT_FPGA22		(OMAP_FPGA_IRQ_BASE + 22)
+#define OMAP1510_INT_FPGA23		(OMAP_FPGA_IRQ_BASE + 23)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpio.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/plat-omap/include/mach/gpio.h
+ *
+ * OMAP GPIO handling defines and functions
+ *
+ * Copyright (C) 2003-2005 Nokia Corporation
+ *
+ * Written by Juha Yrjölä <juha.yrjola@nokia.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
+ *
+ */
+
+#ifndef __ASM_ARCH_OMAP_GPIO_H
+#define __ASM_ARCH_OMAP_GPIO_H
+
+#include <linux/io.h>
+#include <mach/irqs.h>
+
+#define OMAP1_MPUIO_BASE			0xfffb5000
+
+#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
+
+#define OMAP_MPUIO_INPUT_LATCH		0x00
+#define OMAP_MPUIO_OUTPUT		0x02
+#define OMAP_MPUIO_IO_CNTL		0x04
+#define OMAP_MPUIO_KBR_LATCH		0x08
+#define OMAP_MPUIO_KBC			0x0a
+#define OMAP_MPUIO_GPIO_EVENT_MODE	0x0c
+#define OMAP_MPUIO_GPIO_INT_EDGE	0x0e
+#define OMAP_MPUIO_KBD_INT		0x10
+#define OMAP_MPUIO_GPIO_INT		0x12
+#define OMAP_MPUIO_KBD_MASKIT		0x14
+#define OMAP_MPUIO_GPIO_MASKIT		0x16
+#define OMAP_MPUIO_GPIO_DEBOUNCING	0x18
+#define OMAP_MPUIO_LATCH		0x1a
+#else
+#define OMAP_MPUIO_INPUT_LATCH		0x00
+#define OMAP_MPUIO_OUTPUT		0x04
+#define OMAP_MPUIO_IO_CNTL		0x08
+#define OMAP_MPUIO_KBR_LATCH		0x10
+#define OMAP_MPUIO_KBC			0x14
+#define OMAP_MPUIO_GPIO_EVENT_MODE	0x18
+#define OMAP_MPUIO_GPIO_INT_EDGE	0x1c
+#define OMAP_MPUIO_KBD_INT		0x20
+#define OMAP_MPUIO_GPIO_INT		0x24
+#define OMAP_MPUIO_KBD_MASKIT		0x28
+#define OMAP_MPUIO_GPIO_MASKIT		0x2c
+#define OMAP_MPUIO_GPIO_DEBOUNCING	0x30
+#define OMAP_MPUIO_LATCH		0x34
+#endif
+
+#define OMAP34XX_NR_GPIOS		6
+
+#define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
+#define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
+
+#define OMAP_GPIO_IRQ(nr)	(OMAP_GPIO_IS_MPUIO(nr) ? \
+				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
+				 IH_GPIO_BASE + (nr))
+
+extern int omap_gpio_init(void);	/* Call from board init only */
+extern void omap2_gpio_prepare_for_retention(void);
+extern void omap2_gpio_resume_after_retention(void);
+extern void omap_set_gpio_debounce(int gpio, int enable);
+extern void omap_set_gpio_debounce_time(int gpio, int enable);
+extern void omap_gpio_save_context(void);
+extern void omap_gpio_restore_context(void);
+/*-------------------------------------------------------------------------*/
+
+/* Wrappers for "new style" GPIO calls, using the new infrastructure
+ * which lets us plug in FPGA, I2C, and other implementations.
+ * *
+ * The original OMAP-specfic calls should eventually be removed.
+ */
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	int tmp;
+
+	/* omap1 SOC mpuio */
+	if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
+		return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;
+
+	/* SOC gpio */
+	tmp = irq - IH_GPIO_BASE;
+	if (tmp < OMAP_MAX_GPIO_LINES)
+		return tmp;
+
+	/* we don't supply reverse mappings for non-SOC gpios */
+	return -EIO;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpio-switch.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpio-switch.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpio-switch.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpio-switch.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,54 @@
+/*
+ * GPIO switch definitions
+ *
+ * Copyright (C) 2006 Nokia 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 __ASM_ARCH_OMAP_GPIO_SWITCH_H
+#define __ASM_ARCH_OMAP_GPIO_SWITCH_H
+
+#include <linux/types.h>
+
+/* Cover:
+ *	high -> closed
+ *	low  -> open
+ * Connection:
+ *	high -> connected
+ *	low  -> disconnected
+ * Activity:
+ *	high -> active
+ *	low  -> inactive
+ *
+ */
+#define OMAP_GPIO_SWITCH_TYPE_COVER		0x0000
+#define OMAP_GPIO_SWITCH_TYPE_CONNECTION	0x0001
+#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY		0x0002
+#define OMAP_GPIO_SWITCH_FLAG_INVERTED		0x0001
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT		0x0002
+
+struct omap_gpio_switch {
+	const char *name;
+	s16 gpio;
+	unsigned flags:4;
+	unsigned type:4;
+
+	/* Time in ms to debounce when transitioning from
+	 * inactive state to active state. */
+	u16 debounce_rising;
+	/* Same for transition from active to inactive state. */
+	u16 debounce_falling;
+
+	/* notify board-specific code about state changes */
+	void (* notify)(void *data, int state);
+	void *notify_data;
+};
+
+/* Call at init time only */
+extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
+					int count);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpmc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,115 @@
+/*
+ * General-Purpose Memory Controller for OMAP2
+ *
+ * Copyright (C) 2005-2006 Nokia 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 __OMAP2_GPMC_H
+#define __OMAP2_GPMC_H
+
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM		8
+
+#define GPMC_CS_CONFIG1		0x00
+#define GPMC_CS_CONFIG2		0x04
+#define GPMC_CS_CONFIG3		0x08
+#define GPMC_CS_CONFIG4		0x0c
+#define GPMC_CS_CONFIG5		0x10
+#define GPMC_CS_CONFIG6		0x14
+#define GPMC_CS_CONFIG7		0x18
+#define GPMC_CS_NAND_COMMAND	0x1c
+#define GPMC_CS_NAND_ADDRESS	0x20
+#define GPMC_CS_NAND_DATA	0x24
+
+#define GPMC_CONFIG		0x50
+#define GPMC_STATUS		0x54
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
+#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
+#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
+#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
+#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
+#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
+#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_DEVICETYPE_NAND    GPMC_CONFIG1_DEVICETYPE(2)
+#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
+#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
+#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
+#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
+#define GPMC_CONFIG7_CSVALID		(1 << 6)
+
+/*
+ * Note that all values in this struct are in nanoseconds, while
+ * the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+	/* Minimum clock period for synchronous mode */
+	u16 sync_clk;
+
+	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
+	u16 cs_on;		/* Assertion time */
+	u16 cs_rd_off;		/* Read deassertion time */
+	u16 cs_wr_off;		/* Write deassertion time */
+
+	/* ADV signal timings corresponding to GPMC_CONFIG3 */
+	u16 adv_on;		/* Assertion time */
+	u16 adv_rd_off;		/* Read deassertion time */
+	u16 adv_wr_off;		/* Write deassertion time */
+
+	/* WE signals timings corresponding to GPMC_CONFIG4 */
+	u16 we_on;		/* WE assertion time */
+	u16 we_off;		/* WE deassertion time */
+
+	/* OE signals timings corresponding to GPMC_CONFIG4 */
+	u16 oe_on;		/* OE assertion time */
+	u16 oe_off;		/* OE deassertion time */
+
+	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+	u16 page_burst_access;	/* Multiple access word delay */
+	u16 access;		/* Start-cycle to first data valid delay */
+	u16 rd_cycle;		/* Total read cycle time */
+	u16 wr_cycle;		/* Total write cycle time */
+
+	/* The following are only on OMAP3430 */
+	u16 wr_access;		/* WRACCESSTIME */
+	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+};
+
+extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
+extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
+extern unsigned long gpmc_get_fclk_period(void);
+
+extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+extern u32 gpmc_cs_read_reg(int cs, int idx);
+extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
+extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+extern void gpmc_cs_free(int cs);
+extern int gpmc_cs_set_reserved(int cs, int reserved);
+extern int gpmc_cs_reserved(int cs);
+extern int gpmc_prefetch_enable(int cs, int dma_mode,
+					unsigned int u32_count, int is_write);
+extern void gpmc_prefetch_reset(void);
+extern int gpmc_prefetch_status(void);
+extern void omap3_gpmc_save_context(void);
+extern void omap3_gpmc_restore_context(void);
+extern void __init gpmc_init(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpmc-smc91x.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc-smc91x.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/gpmc-smc91x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/gpmc-smc91x.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/plat-omap/include/mach/gpmc-smc91x.h
+ *
+ * Copyright (C) 2009 Nokia 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 __ASM_ARCH_OMAP_GPMC_SMC91X_H__
+
+#define GPMC_TIMINGS_SMC91C96	(1 << 4)
+#define GPMC_MUX_ADD_DATA	(1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
+#define GPMC_READ_MON		(1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
+#define GPMC_WRITE_MON		(1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
+
+struct omap_smc91x_platform_data {
+	int	cs;
+	int	gpio_irq;
+	int	gpio_pwrdwn;
+	int	gpio_reset;
+	int	wait_pin;	/* Optional GPMC_CONFIG1_WAITPINSELECT */
+	u32	flags;
+	int	(*retime)(void);
+};
+
+#if defined(CONFIG_SMC91X) || \
+	defined(CONFIG_SMC91X_MODULE)
+
+extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
+
+#else
+
+#define board_smc91x_data	NULL
+
+static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
+{
+}
+
+#endif
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/hardware.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/hardware.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/hardware.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,290 @@
+/*
+ * arch/arm/plat-omap/include/mach/hardware.h
+ *
+ * Hardware definitions for TI OMAP processors and boards
+ *
+ * NOTE: Please put device driver specific defines into a separate header
+ *	 file for each driver.
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ *                          and Dirk Behme <dirk.behme@de.bosch.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 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP_HARDWARE_H
+#define __ASM_ARCH_OMAP_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#include <plat/cpu.h>
+#endif
+#include <plat/serial.h>
+
+/*
+ * ---------------------------------------------------------------------------
+ * Common definitions for all OMAP processors
+ * NOTE: Put all processor or board specific parts to the special header
+ *	 files.
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Timers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_MPU_TIMER1_BASE	(0xfffec500)
+#define OMAP_MPU_TIMER2_BASE	(0xfffec600)
+#define OMAP_MPU_TIMER3_BASE	(0xfffec700)
+#define MPU_TIMER_FREE		(1 << 6)
+#define MPU_TIMER_CLOCK_ENABLE	(1 << 5)
+#define MPU_TIMER_AR		(1 << 1)
+#define MPU_TIMER_ST		(1 << 0)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE		(0xfffece00)
+#define ARM_CKCTL		(CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1		(CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2		(CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT		(CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1		(CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2		(CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST		(CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3		(CLKGEN_REG_BASE + 0x24)
+
+#define CK_RATEF		1
+#define CK_IDLEF		2
+#define CK_ENABLEF		4
+#define CK_SELECTF		8
+#define SETARM_IDLE_SHIFT
+
+/* DPLL control registers */
+#define DPLL_CTL		(0xfffecf00)
+
+/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
+#define DSP_CONFIG_REG_BASE     IOMEM(0xe1008000)
+#define DSP_CKCTL		(DSP_CONFIG_REG_BASE + 0x0)
+#define DSP_IDLECT1		(DSP_CONFIG_REG_BASE + 0x4)
+#define DSP_IDLECT2		(DSP_CONFIG_REG_BASE + 0x8)
+#define DSP_RSTCT2		(DSP_CONFIG_REG_BASE + 0x14)
+
+/*
+ * ---------------------------------------------------------------------------
+ * UPLD
+ * ---------------------------------------------------------------------------
+ */
+#define ULPD_REG_BASE		(0xfffe0800)
+#define ULPD_IT_STATUS		(ULPD_REG_BASE + 0x14)
+#define ULPD_SETUP_ANALOG_CELL_3	(ULPD_REG_BASE + 0x24)
+#define ULPD_CLOCK_CTRL		(ULPD_REG_BASE + 0x30)
+#	define DIS_USB_PVCI_CLK		(1 << 5)	/* no USB/FAC synch */
+#	define USB_MCLK_EN		(1 << 4)	/* enable W4_USB_CLKO */
+#define ULPD_SOFT_REQ		(ULPD_REG_BASE + 0x34)
+#	define SOFT_UDC_REQ		(1 << 4)
+#	define SOFT_USB_CLK_REQ		(1 << 3)
+#	define SOFT_DPLL_REQ		(1 << 0)
+#define ULPD_DPLL_CTRL		(ULPD_REG_BASE + 0x3c)
+#define ULPD_STATUS_REQ		(ULPD_REG_BASE + 0x40)
+#define ULPD_APLL_CTRL		(ULPD_REG_BASE + 0x4c)
+#define ULPD_POWER_CTRL		(ULPD_REG_BASE + 0x50)
+#define ULPD_SOFT_DISABLE_REQ_REG	(ULPD_REG_BASE + 0x68)
+#	define DIS_MMC2_DPLL_REQ	(1 << 11)
+#	define DIS_MMC1_DPLL_REQ	(1 << 10)
+#	define DIS_UART3_DPLL_REQ	(1 << 9)
+#	define DIS_UART2_DPLL_REQ	(1 << 8)
+#	define DIS_UART1_DPLL_REQ	(1 << 7)
+#	define DIS_USB_HOST_DPLL_REQ	(1 << 6)
+#define ULPD_SDW_CLK_DIV_CTRL_SEL	(ULPD_REG_BASE + 0x74)
+#define ULPD_CAM_CLK_CTRL	(ULPD_REG_BASE + 0x7c)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Watchdog timer
+ * ---------------------------------------------------------------------------
+ */
+
+/* Watchdog timer within the OMAP3.2 gigacell */
+#define OMAP_MPU_WATCHDOG_BASE	(0xfffec800)
+#define OMAP_WDT_TIMER		(OMAP_MPU_WATCHDOG_BASE + 0x0)
+#define OMAP_WDT_LOAD_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_READ_TIM	(OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_TIMER_MODE	(OMAP_MPU_WATCHDOG_BASE + 0x8)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#ifdef CONFIG_ARCH_OMAP1
+
+/*
+ * XXX: These probably want to be moved to arch/arm/mach-omap/omap1/irq.c
+ * or something similar.. -- PFM.
+ */
+
+#define OMAP_IH1_BASE		0xfffecb00
+#define OMAP_IH2_BASE		0xfffe0000
+
+#define OMAP_IH1_ITR		(OMAP_IH1_BASE + 0x00)
+#define OMAP_IH1_MIR		(OMAP_IH1_BASE + 0x04)
+#define OMAP_IH1_SIR_IRQ	(OMAP_IH1_BASE + 0x10)
+#define OMAP_IH1_SIR_FIQ	(OMAP_IH1_BASE + 0x14)
+#define OMAP_IH1_CONTROL	(OMAP_IH1_BASE + 0x18)
+#define OMAP_IH1_ILR0		(OMAP_IH1_BASE + 0x1c)
+#define OMAP_IH1_ISR		(OMAP_IH1_BASE + 0x9c)
+
+#define OMAP_IH2_ITR		(OMAP_IH2_BASE + 0x00)
+#define OMAP_IH2_MIR		(OMAP_IH2_BASE + 0x04)
+#define OMAP_IH2_SIR_IRQ	(OMAP_IH2_BASE + 0x10)
+#define OMAP_IH2_SIR_FIQ	(OMAP_IH2_BASE + 0x14)
+#define OMAP_IH2_CONTROL	(OMAP_IH2_BASE + 0x18)
+#define OMAP_IH2_ILR0		(OMAP_IH2_BASE + 0x1c)
+#define OMAP_IH2_ISR		(OMAP_IH2_BASE + 0x9c)
+
+#define IRQ_ITR_REG_OFFSET	0x00
+#define IRQ_MIR_REG_OFFSET	0x04
+#define IRQ_SIR_IRQ_REG_OFFSET	0x10
+#define IRQ_SIR_FIQ_REG_OFFSET	0x14
+#define IRQ_CONTROL_REG_OFFSET	0x18
+#define IRQ_ISR_REG_OFFSET	0x9c
+#define IRQ_ILR0_REG_OFFSET	0x1c
+#define IRQ_GMR_REG_OFFSET	0xa0
+
+#endif
+
+/*
+ * ----------------------------------------------------------------------------
+ * System control registers
+ * ----------------------------------------------------------------------------
+ */
+#define MOD_CONF_CTRL_0		0xfffe1080
+#define MOD_CONF_CTRL_1		0xfffe1110
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pin multiplexing registers
+ * ----------------------------------------------------------------------------
+ */
+#define FUNC_MUX_CTRL_0		0xfffe1000
+#define FUNC_MUX_CTRL_1		0xfffe1004
+#define FUNC_MUX_CTRL_2		0xfffe1008
+#define COMP_MODE_CTRL_0	0xfffe100c
+#define FUNC_MUX_CTRL_3		0xfffe1010
+#define FUNC_MUX_CTRL_4		0xfffe1014
+#define FUNC_MUX_CTRL_5		0xfffe1018
+#define FUNC_MUX_CTRL_6		0xfffe101C
+#define FUNC_MUX_CTRL_7		0xfffe1020
+#define FUNC_MUX_CTRL_8		0xfffe1024
+#define FUNC_MUX_CTRL_9		0xfffe1028
+#define FUNC_MUX_CTRL_A		0xfffe102C
+#define FUNC_MUX_CTRL_B		0xfffe1030
+#define FUNC_MUX_CTRL_C		0xfffe1034
+#define FUNC_MUX_CTRL_D		0xfffe1038
+#define PULL_DWN_CTRL_0		0xfffe1040
+#define PULL_DWN_CTRL_1		0xfffe1044
+#define PULL_DWN_CTRL_2		0xfffe1048
+#define PULL_DWN_CTRL_3		0xfffe104c
+#define PULL_DWN_CTRL_4		0xfffe10ac
+
+/* OMAP-1610 specific multiplexing registers */
+#define FUNC_MUX_CTRL_E		0xfffe1090
+#define FUNC_MUX_CTRL_F		0xfffe1094
+#define FUNC_MUX_CTRL_10	0xfffe1098
+#define FUNC_MUX_CTRL_11	0xfffe109c
+#define FUNC_MUX_CTRL_12	0xfffe10a0
+#define PU_PD_SEL_0		0xfffe10b4
+#define PU_PD_SEL_1		0xfffe10b8
+#define PU_PD_SEL_2		0xfffe10bc
+#define PU_PD_SEL_3		0xfffe10c0
+#define PU_PD_SEL_4		0xfffe10c4
+
+/* Timer32K for 1610 and 1710*/
+#define OMAP_TIMER32K_BASE	0xFFFBC400
+
+/*
+ * ---------------------------------------------------------------------------
+ * TIPB bus interface
+ * ---------------------------------------------------------------------------
+ */
+#define TIPB_PUBLIC_CNTL_BASE		0xfffed300
+#define MPU_PUBLIC_TIPB_CNTL		(TIPB_PUBLIC_CNTL_BASE + 0x8)
+#define TIPB_PRIVATE_CNTL_BASE		0xfffeca00
+#define MPU_PRIVATE_TIPB_CNTL		(TIPB_PRIVATE_CNTL_BASE + 0x8)
+
+/*
+ * ----------------------------------------------------------------------------
+ * MPUI interface
+ * ----------------------------------------------------------------------------
+ */
+#define MPUI_BASE			(0xfffec900)
+#define MPUI_CTRL			(MPUI_BASE + 0x0)
+#define MPUI_DEBUG_ADDR			(MPUI_BASE + 0x4)
+#define MPUI_DEBUG_DATA			(MPUI_BASE + 0x8)
+#define MPUI_DEBUG_FLAG			(MPUI_BASE + 0xc)
+#define MPUI_STATUS_REG			(MPUI_BASE + 0x10)
+#define MPUI_DSP_STATUS			(MPUI_BASE + 0x14)
+#define MPUI_DSP_BOOT_CONFIG		(MPUI_BASE + 0x18)
+#define MPUI_DSP_API_CONFIG		(MPUI_BASE + 0x1c)
+
+/*
+ * ----------------------------------------------------------------------------
+ * LED Pulse Generator
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_LPG1_BASE			0xfffbd000
+#define OMAP_LPG2_BASE			0xfffbd800
+#define OMAP_LPG1_LCR			(OMAP_LPG1_BASE + 0x00)
+#define OMAP_LPG1_PMR			(OMAP_LPG1_BASE + 0x04)
+#define OMAP_LPG2_LCR			(OMAP_LPG2_BASE + 0x00)
+#define OMAP_LPG2_PMR			(OMAP_LPG2_BASE + 0x04)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pulse-Width Light
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_PWL_BASE			0xfffb5800
+#define OMAP_PWL_ENABLE			(OMAP_PWL_BASE + 0x00)
+#define OMAP_PWL_CLK_ENABLE		(OMAP_PWL_BASE + 0x04)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Processor specific defines
+ * ---------------------------------------------------------------------------
+ */
+
+#include <plat/omap7xx.h>
+#include <plat/omap1510.h>
+#include <plat/omap16xx.h>
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+#include <plat/omap44xx.h>
+
+#endif	/* __ASM_ARCH_OMAP_HARDWARE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/hwa742.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/hwa742.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/hwa742.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/hwa742.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,8 @@
+#ifndef _HWA742_H
+#define _HWA742_H
+
+struct hwa742_platform_data {
+	unsigned	te_connected:1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/i2c.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/i2c.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/i2c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/i2c.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/i2c.h>
+
+#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
+				 struct i2c_board_info const *info,
+				 unsigned len);
+#else
+static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
+				 struct i2c_board_info const *info,
+				 unsigned len)
+{
+	return 0;
+}
+#endif
+
+int omap_plat_register_i2c_bus(int bus_id, u32 clkrate,
+				 struct i2c_board_info const *info,
+				 unsigned len);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/io.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/io.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,283 @@
+/*
+ * arch/arm/plat-omap/include/mach/io.h
+ *
+ * IO definitions for TI OMAP processors and boards
+ *
+ * Copied from arch/arm/mach-sa1100/include/mach/io.h
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - 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 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.
+ *
+ * Modifications:
+ *  06-12-1997	RMK	Created.
+ *  07-04-1999	RMK	Major cleanup
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+/*
+ * ----------------------------------------------------------------------------
+ * I/O mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)		(x)
+#else
+#define IOMEM(x)		((void __force __iomem *)(x))
+#endif
+
+#define OMAP1_IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
+#define OMAP1_IO_ADDRESS(pa)	IOMEM((pa) - OMAP1_IO_OFFSET)
+
+#define OMAP2_L3_IO_OFFSET	0x90000000
+#define OMAP2_L3_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */
+
+
+#define OMAP2_L4_IO_OFFSET	0xb2000000
+#define OMAP2_L4_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */
+
+#define OMAP4_L3_IO_OFFSET	0xb4000000
+#define OMAP4_L3_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
+
+#define OMAP4_L3_PER_IO_OFFSET	0xb1100000
+#define OMAP4_L3_PER_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
+
+#define OMAP4_GPMC_IO_OFFSET		0xa9000000
+#define OMAP4_GPMC_IO_ADDRESS(pa)	IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
+
+#define OMAP2_EMU_IO_OFFSET		0xaa800000	/* Emulation */
+#define OMAP2_EMU_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap1 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#define OMAP1_IO_PHYS		0xFFFB0000
+#define OMAP1_IO_SIZE		0x40000
+#define OMAP1_IO_VIRT		(OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap2 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP2 */
+#define L3_24XX_PHYS	L3_24XX_BASE	/* 0x68000000 --> 0xf8000000*/
+#define L3_24XX_VIRT	(L3_24XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_24XX_SIZE	SZ_1M		/* 44kB of 128MB used, want 1MB sect */
+#define L4_24XX_PHYS	L4_24XX_BASE	/* 0x48000000 --> 0xfa000000 */
+#define L4_24XX_VIRT	(L4_24XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_24XX_SIZE	SZ_1M		/* 1MB of 128MB used, want 1MB sect */
+
+#define L4_WK_243X_PHYS		L4_WK_243X_BASE	/* 0x49000000 --> 0xfb000000 */
+#define L4_WK_243X_VIRT		(L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_243X_SIZE		SZ_1M
+#define OMAP243X_GPMC_PHYS	OMAP243X_GPMC_BASE
+#define OMAP243X_GPMC_VIRT	(OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+						/* 0x6e000000 --> 0xfe000000 */
+#define OMAP243X_GPMC_SIZE	SZ_1M
+#define OMAP243X_SDRC_PHYS	OMAP243X_SDRC_BASE
+						/* 0x6D000000 --> 0xfd000000 */
+#define OMAP243X_SDRC_VIRT	(OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SDRC_SIZE	SZ_1M
+#define OMAP243X_SMS_PHYS	OMAP243X_SMS_BASE
+						/* 0x6c000000 --> 0xfc000000 */
+#define OMAP243X_SMS_VIRT	(OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SMS_SIZE	SZ_1M
+
+/* 2420 IVA */
+#define DSP_MEM_2420_PHYS	OMAP2420_DSP_MEM_BASE
+						/* 0x58000000 --> 0xfc100000 */
+#define DSP_MEM_2420_VIRT	0xfc100000
+#define DSP_MEM_2420_SIZE	0x28000
+#define DSP_IPI_2420_PHYS	OMAP2420_DSP_IPI_BASE
+						/* 0x59000000 --> 0xfc128000 */
+#define DSP_IPI_2420_VIRT	0xfc128000
+#define DSP_IPI_2420_SIZE	SZ_4K
+#define DSP_MMU_2420_PHYS	OMAP2420_DSP_MMU_BASE
+						/* 0x5a000000 --> 0xfc129000 */
+#define DSP_MMU_2420_VIRT	0xfc129000
+#define DSP_MMU_2420_SIZE	SZ_4K
+
+/* 2430 IVA2.1 - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap3 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP3 */
+#define L3_34XX_PHYS		L3_34XX_BASE	/* 0x68000000 --> 0xf8000000 */
+#define L3_34XX_VIRT		(L3_34XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_34XX_SIZE		SZ_1M   /* 44kB of 128MB used, want 1MB sect */
+
+#define L4_34XX_PHYS		L4_34XX_BASE	/* 0x48000000 --> 0xfa000000 */
+#define L4_34XX_VIRT		(L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_34XX_SIZE		SZ_4M   /* 1MB of 128MB used, want 1MB sect */
+
+/*
+ * Need to look at the Size 4M for L4.
+ * VPOM3430 was not working for Int controller
+ */
+
+#define L4_WK_34XX_PHYS		L4_WK_34XX_BASE	/* 0x48300000 --> 0xfa300000 */
+#define L4_WK_34XX_VIRT		(L4_WK_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_34XX_SIZE		SZ_1M
+
+#define L4_PER_34XX_PHYS	L4_PER_34XX_BASE
+						/* 0x49000000 --> 0xfb000000 */
+#define L4_PER_34XX_VIRT	(L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_34XX_SIZE	SZ_1M
+
+#define L4_EMU_34XX_PHYS	L4_EMU_34XX_BASE
+						/* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_34XX_VIRT	(L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_34XX_SIZE	SZ_8M
+
+#define OMAP34XX_GPMC_PHYS	OMAP34XX_GPMC_BASE
+						/* 0x6e000000 --> 0xfe000000 */
+#define OMAP34XX_GPMC_VIRT	(OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP34XX_GPMC_SIZE	SZ_1M
+
+#define OMAP343X_SMS_PHYS	OMAP343X_SMS_BASE
+						/* 0x6c000000 --> 0xfc000000 */
+#define OMAP343X_SMS_VIRT	(OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SMS_SIZE	SZ_1M
+
+#define OMAP343X_SDRC_PHYS	OMAP343X_SDRC_BASE
+						/* 0x6D000000 --> 0xfd000000 */
+#define OMAP343X_SDRC_VIRT	(OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SDRC_SIZE	SZ_1M
+
+/* 3430 IVA - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap4 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP4 */
+#define L3_44XX_PHYS		L3_44XX_BASE	/* 0x44000000 --> 0xf8000000 */
+#define L3_44XX_VIRT		(L3_44XX_PHYS + OMAP4_L3_IO_OFFSET)
+#define L3_44XX_SIZE		SZ_1M
+
+#define L4_44XX_PHYS		L4_44XX_BASE	/* 0x4a000000 --> 0xfc000000 */
+#define L4_44XX_VIRT		(L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_44XX_SIZE		SZ_4M
+
+
+#define L4_WK_44XX_PHYS		L4_WK_44XX_BASE	/* 0x4a300000 --> 0xfc300000 */
+#define L4_WK_44XX_VIRT		(L4_WK_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_44XX_SIZE		SZ_1M
+
+#define L4_PER_44XX_PHYS	L4_PER_44XX_BASE
+						/* 0x48000000 --> 0xfa000000 */
+#define L4_PER_44XX_VIRT	(L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_44XX_SIZE	SZ_4M
+
+#define L4_ABE_44XX_PHYS	L4_ABE_44XX_BASE
+						/* 0x49000000 --> 0xfb000000 */
+#define L4_ABE_44XX_VIRT	(L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_ABE_44XX_SIZE	SZ_1M
+
+#define L4_EMU_44XX_PHYS	L4_EMU_44XX_BASE
+						/* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_44XX_VIRT	(L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_44XX_SIZE	SZ_8M
+
+#define OMAP44XX_GPMC_PHYS	OMAP44XX_GPMC_BASE
+						/* 0x50000000 --> 0xf9000000 */
+#define OMAP44XX_GPMC_VIRT	(OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
+#define OMAP44XX_GPMC_SIZE	SZ_1M
+
+
+#define OMAP44XX_EMIF1_PHYS	OMAP44XX_EMIF1_BASE
+						/* 0x4c000000 --> 0xfd100000 */
+#define OMAP44XX_EMIF1_VIRT	(OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_EMIF1_SIZE	SZ_1M
+
+#define OMAP44XX_EMIF2_PHYS	OMAP44XX_EMIF2_BASE
+						/* 0x4d000000 --> 0xfd200000 */
+#define OMAP44XX_EMIF2_VIRT	(OMAP44XX_EMIF2_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_EMIF2_SIZE	SZ_1M
+
+#define OMAP44XX_DMM_PHYS	OMAP44XX_DMM_BASE
+						/* 0x4e000000 --> 0xfd300000 */
+#define OMAP44XX_DMM_VIRT	(OMAP44XX_DMM_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_DMM_SIZE	SZ_1M
+/*
+ * ----------------------------------------------------------------------------
+ * Omap specific register access
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef __ASSEMBLER__
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+extern u8 omap_readb(u32 pa);
+extern u16 omap_readw(u32 pa);
+extern u32 omap_readl(u32 pa);
+extern void omap_writeb(u8 v, u32 pa);
+extern void omap_writew(u16 v, u32 pa);
+extern void omap_writel(u32 v, u32 pa);
+
+struct omap_sdrc_params;
+
+extern void omap1_map_common_io(void);
+extern void omap1_init_common_hw(void);
+
+extern void omap2_map_common_io(void);
+extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
+				 struct omap_sdrc_params *sdrc_cs1);
+
+#define __arch_ioremap(p,s,t)	omap_ioremap(p,s,t)
+#define __arch_iounmap(v)	omap_iounmap(v)
+
+void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
+void omap_iounmap(volatile void __iomem *addr);
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iommu2.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iommu2.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iommu2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iommu2.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,96 @@
+/*
+ * omap iommu: omap2 architecture specific definitions
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by 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.
+ */
+
+#ifndef __MACH_IOMMU2_H
+#define __MACH_IOMMU2_H
+
+#include <linux/io.h>
+
+/*
+ * MMU Register offsets
+ */
+#define MMU_REVISION		0x00
+#define MMU_SYSCONFIG		0x10
+#define MMU_SYSSTATUS		0x14
+#define MMU_IRQSTATUS		0x18
+#define MMU_IRQENABLE		0x1c
+#define MMU_WALKING_ST		0x40
+#define MMU_CNTL		0x44
+#define MMU_FAULT_AD		0x48
+#define MMU_TTB			0x4c
+#define MMU_LOCK		0x50
+#define MMU_LD_TLB		0x54
+#define MMU_CAM			0x58
+#define MMU_RAM			0x5c
+#define MMU_GFLUSH		0x60
+#define MMU_FLUSH_ENTRY		0x64
+#define MMU_READ_CAM		0x68
+#define MMU_READ_RAM		0x6c
+#define MMU_EMU_FAULT_AD	0x70
+
+#define MMU_REG_SIZE		256
+
+/*
+ * MMU Register bit definitions
+ */
+#define MMU_LOCK_BASE_SHIFT	10
+#define MMU_LOCK_BASE_MASK	(0x1f << MMU_LOCK_BASE_SHIFT)
+#define MMU_LOCK_BASE(x)	\
+	((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
+
+#define MMU_LOCK_VICT_SHIFT	4
+#define MMU_LOCK_VICT_MASK	(0x1f << MMU_LOCK_VICT_SHIFT)
+#define MMU_LOCK_VICT(x)	\
+	((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
+
+#define MMU_CAM_VATAG_SHIFT	12
+#define MMU_CAM_VATAG_MASK \
+	((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
+#define MMU_CAM_P		(1 << 3)
+#define MMU_CAM_V		(1 << 2)
+#define MMU_CAM_PGSZ_MASK	3
+#define MMU_CAM_PGSZ_1M		(0 << 0)
+#define MMU_CAM_PGSZ_64K	(1 << 0)
+#define MMU_CAM_PGSZ_4K		(2 << 0)
+#define MMU_CAM_PGSZ_16M	(3 << 0)
+
+#define MMU_RAM_PADDR_SHIFT	12
+#define MMU_RAM_PADDR_MASK \
+	((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
+#define MMU_RAM_ENDIAN_SHIFT	9
+#define MMU_RAM_ENDIAN_MASK	(1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_BIG	(1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_LITTLE	(0 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ELSZ_SHIFT	7
+#define MMU_RAM_ELSZ_MASK	(3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_8		(0 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_16		(1 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_32		(2 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_NONE	(3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_MIXED_SHIFT	6
+#define MMU_RAM_MIXED_MASK	(1 << MMU_RAM_MIXED_SHIFT)
+#define MMU_RAM_MIXED		MMU_RAM_MIXED_MASK
+
+/*
+ * register accessors
+ */
+static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
+{
+	return __raw_readl(obj->regbase + offs);
+}
+
+static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
+{
+	__raw_writel(val, obj->regbase + offs);
+}
+
+#endif /* __MACH_IOMMU2_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iommu.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iommu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iommu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iommu.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,168 @@
+/*
+ * omap iommu: main structures
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by 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.
+ */
+
+#ifndef __MACH_IOMMU_H
+#define __MACH_IOMMU_H
+
+struct iotlb_entry {
+	u32 da;
+	u32 pa;
+	u32 pgsz, prsvd, valid;
+	union {
+		u16 ap;
+		struct {
+			u32 endian, elsz, mixed;
+		};
+	};
+};
+
+struct iommu {
+	const char	*name;
+	struct module	*owner;
+	struct clk	*clk;
+	void __iomem	*regbase;
+	struct device	*dev;
+
+	unsigned int	refcount;
+	struct mutex	iommu_lock;	/* global for this whole object */
+
+	/*
+	 * We don't change iopgd for a situation like pgd for a task,
+	 * but share it globally for each iommu.
+	 */
+	u32		*iopgd;
+	spinlock_t	page_table_lock; /* protect iopgd */
+
+	int		nr_tlb_entries;
+
+	struct list_head	mmap;
+	struct mutex		mmap_lock; /* protect mmap */
+
+	int (*isr)(struct iommu *obj);
+
+	void *ctx; /* iommu context: registres saved area */
+};
+
+struct cr_regs {
+	union {
+		struct {
+			u16 cam_l;
+			u16 cam_h;
+		};
+		u32 cam;
+	};
+	union {
+		struct {
+			u16 ram_l;
+			u16 ram_h;
+		};
+		u32 ram;
+	};
+};
+
+struct iotlb_lock {
+	short base;
+	short vict;
+};
+
+/* architecture specific functions */
+struct iommu_functions {
+	unsigned long	version;
+
+	int (*enable)(struct iommu *obj);
+	void (*disable)(struct iommu *obj);
+	u32 (*fault_isr)(struct iommu *obj, u32 *ra);
+
+	void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
+	void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
+
+	struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e);
+	int (*cr_valid)(struct cr_regs *cr);
+	u32 (*cr_to_virt)(struct cr_regs *cr);
+	void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e);
+	ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf);
+
+	u32 (*get_pte_attr)(struct iotlb_entry *e);
+
+	void (*save_ctx)(struct iommu *obj);
+	void (*restore_ctx)(struct iommu *obj);
+	ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len);
+};
+
+struct iommu_platform_data {
+	const char *name;
+	const char *clk_name;
+	const int nr_tlb_entries;
+};
+
+#if defined(CONFIG_ARCH_OMAP1)
+#error "iommu for this processor not implemented yet"
+#else
+#include <plat/iommu2.h>
+#endif
+
+/*
+ * utilities for super page(16MB, 1MB, 64KB and 4KB)
+ */
+
+#define iopgsz_max(bytes)			\
+	(((bytes) >= SZ_16M) ? SZ_16M :		\
+	 ((bytes) >= SZ_1M)  ? SZ_1M  :		\
+	 ((bytes) >= SZ_64K) ? SZ_64K :		\
+	 ((bytes) >= SZ_4K)  ? SZ_4K  :	0)
+
+#define bytes_to_iopgsz(bytes)				\
+	(((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M :	\
+	 ((bytes) == SZ_1M)  ? MMU_CAM_PGSZ_1M  :	\
+	 ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K :	\
+	 ((bytes) == SZ_4K)  ? MMU_CAM_PGSZ_4K  : -1)
+
+#define iopgsz_to_bytes(iopgsz)				\
+	(((iopgsz) == MMU_CAM_PGSZ_16M)	? SZ_16M :	\
+	 ((iopgsz) == MMU_CAM_PGSZ_1M)	? SZ_1M  :	\
+	 ((iopgsz) == MMU_CAM_PGSZ_64K)	? SZ_64K :	\
+	 ((iopgsz) == MMU_CAM_PGSZ_4K)	? SZ_4K  : 0)
+
+#define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
+
+/*
+ * global functions
+ */
+extern u32 iommu_arch_version(void);
+
+extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
+extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
+
+extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
+extern void flush_iotlb_page(struct iommu *obj, u32 da);
+extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
+extern void flush_iotlb_all(struct iommu *obj);
+
+extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
+extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
+
+extern struct iommu *iommu_get(const char *name);
+extern void iommu_put(struct iommu *obj);
+
+extern void iommu_save_ctx(struct iommu *obj);
+extern void iommu_restore_ctx(struct iommu *obj);
+
+extern int install_iommu_arch(const struct iommu_functions *ops);
+extern void uninstall_iommu_arch(const struct iommu_functions *ops);
+
+extern int foreach_iommu_device(void *data,
+				int (*fn)(struct device *, void *));
+
+extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len);
+extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len);
+
+#endif /* __MACH_IOMMU_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iovmm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iovmm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/iovmm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/iovmm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,94 @@
+/*
+ * omap iommu: simple virtual address space management
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by 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.
+ */
+
+#ifndef __IOMMU_MMAP_H
+#define __IOMMU_MMAP_H
+
+struct iovm_struct {
+	struct iommu		*iommu;	/* iommu object which this belongs to */
+	u32			da_start; /* area definition */
+	u32			da_end;
+	u32			flags; /* IOVMF_: see below */
+	struct list_head	list; /* linked in ascending order */
+	const struct sg_table	*sgt; /* keep 'page' <-> 'da' mapping */
+	void			*va; /* mpu side mapped address */
+};
+
+/*
+ * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
+ *
+ * lower 16 bit is used for h/w and upper 16 bit is for s/w.
+ */
+#define IOVMF_SW_SHIFT		16
+#define IOVMF_HW_SIZE		(1 << IOVMF_SW_SHIFT)
+#define IOVMF_HW_MASK		(IOVMF_HW_SIZE - 1)
+#define IOVMF_SW_MASK		(~IOVMF_HW_MASK)UL
+
+/*
+ * iovma: h/w flags derived from cam and ram attribute
+ */
+#define IOVMF_CAM_MASK		(~((1 << 10) - 1))
+#define IOVMF_RAM_MASK		(~IOVMF_CAM_MASK)
+
+#define IOVMF_PGSZ_MASK		(3 << 0)
+#define IOVMF_PGSZ_1M		MMU_CAM_PGSZ_1M
+#define IOVMF_PGSZ_64K		MMU_CAM_PGSZ_64K
+#define IOVMF_PGSZ_4K		MMU_CAM_PGSZ_4K
+#define IOVMF_PGSZ_16M		MMU_CAM_PGSZ_16M
+
+#define IOVMF_ENDIAN_MASK	(1 << 9)
+#define IOVMF_ENDIAN_BIG	MMU_RAM_ENDIAN_BIG
+#define IOVMF_ENDIAN_LITTLE	MMU_RAM_ENDIAN_LITTLE
+
+#define IOVMF_ELSZ_MASK		(3 << 7)
+#define IOVMF_ELSZ_8		MMU_RAM_ELSZ_8
+#define IOVMF_ELSZ_16		MMU_RAM_ELSZ_16
+#define IOVMF_ELSZ_32		MMU_RAM_ELSZ_32
+#define IOVMF_ELSZ_NONE		MMU_RAM_ELSZ_NONE
+
+#define IOVMF_MIXED_MASK	(1 << 6)
+#define IOVMF_MIXED		MMU_RAM_MIXED
+
+/*
+ * iovma: s/w flags, used for mapping and umapping internally.
+ */
+#define IOVMF_MMIO		(1 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC		(2 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC_MASK	(3 << IOVMF_SW_SHIFT)
+
+/* "superpages" is supported just with physically linear pages */
+#define IOVMF_DISCONT		(1 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR		(2 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR_MASK	(3 << (2 + IOVMF_SW_SHIFT))
+
+#define IOVMF_DA_FIXED		(1 << (4 + IOVMF_SW_SHIFT))
+#define IOVMF_DA_ANON		(2 << (4 + IOVMF_SW_SHIFT))
+#define IOVMF_DA_MASK		(3 << (4 + IOVMF_SW_SHIFT))
+
+
+extern struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da);
+extern u32 iommu_vmap(struct iommu *obj, u32 da,
+			const struct sg_table *sgt, u32 flags);
+extern struct sg_table *iommu_vunmap(struct iommu *obj, u32 da);
+extern u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes,
+			   u32 flags);
+extern void iommu_vfree(struct iommu *obj, const u32 da);
+extern u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
+			u32 flags);
+extern void iommu_kunmap(struct iommu *obj, u32 da);
+extern u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes,
+			   u32 flags);
+extern void iommu_kfree(struct iommu *obj, u32 da);
+
+extern void *da_to_va(struct iommu *obj, u32 da);
+
+#endif /* __IOMMU_MMAP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/irda.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irda.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/irda.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irda.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+/*
+ *  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 linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/irqs.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,509 @@
+/*
+ *  arch/arm/plat-omap/include/mach/irqs.h
+ *
+ *  Copyright (C) Greg Lonnon 2001
+ *  Updated for OMAP-1610 by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - 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 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
+ *
+ * NOTE: The interrupt vectors for the OMAP-1509, OMAP-1510, and OMAP-1610
+ *	 are different.
+ */
+
+#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
+#define __ASM_ARCH_OMAP15XX_IRQS_H
+
+/*
+ * IRQ numbers for interrupt handler 1
+ *
+ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
+ *
+ */
+#define INT_CAMERA		1
+#define INT_FIQ			3
+#define INT_RTDX		6
+#define INT_DSP_MMU_ABORT	7
+#define INT_HOST		8
+#define INT_ABORT		9
+#define INT_BRIDGE_PRIV		13
+#define INT_GPIO_BANK1		14
+#define INT_UART3		15
+#define INT_TIMER3		16
+#define INT_DMA_CH0_6		19
+#define INT_DMA_CH1_7		20
+#define INT_DMA_CH2_8		21
+#define INT_DMA_CH3		22
+#define INT_DMA_CH4		23
+#define INT_DMA_CH5		24
+#define INT_DMA_LCD		25
+#define INT_TIMER1		26
+#define INT_WD_TIMER		27
+#define INT_BRIDGE_PUB		28
+#define INT_TIMER2		30
+#define INT_LCD_CTRL		31
+
+/*
+ * OMAP-1510 specific IRQ numbers for interrupt handler 1
+ */
+#define INT_1510_IH2_IRQ	0
+#define INT_1510_RES2		2
+#define INT_1510_SPI_TX		4
+#define INT_1510_SPI_RX		5
+#define INT_1510_DSP_MAILBOX1	10
+#define INT_1510_DSP_MAILBOX2	11
+#define INT_1510_RES12		12
+#define INT_1510_LB_MMU		17
+#define INT_1510_RES18		18
+#define INT_1510_LOCAL_BUS	29
+
+/*
+ * OMAP-1610 specific IRQ numbers for interrupt handler 1
+ */
+#define INT_1610_IH2_IRQ	0
+#define INT_1610_IH2_FIQ	2
+#define INT_1610_McBSP2_TX	4
+#define INT_1610_McBSP2_RX	5
+#define INT_1610_DSP_MAILBOX1	10
+#define INT_1610_DSP_MAILBOX2	11
+#define INT_1610_LCD_LINE	12
+#define INT_1610_GPTIMER1	17
+#define INT_1610_GPTIMER2	18
+#define INT_1610_SSR_FIFO_0	29
+
+/*
+ * OMAP-7xx specific IRQ numbers for interrupt handler 1
+ */
+#define INT_7XX_IH2_FIQ		0
+#define INT_7XX_IH2_IRQ		1
+#define INT_7XX_USB_NON_ISO	2
+#define INT_7XX_USB_ISO		3
+#define INT_7XX_ICR		4
+#define INT_7XX_EAC		5
+#define INT_7XX_GPIO_BANK1	6
+#define INT_7XX_GPIO_BANK2	7
+#define INT_7XX_GPIO_BANK3	8
+#define INT_7XX_McBSP2TX	10
+#define INT_7XX_McBSP2RX	11
+#define INT_7XX_McBSP2RX_OVF	12
+#define INT_7XX_LCD_LINE	14
+#define INT_7XX_GSM_PROTECT	15
+#define INT_7XX_TIMER3		16
+#define INT_7XX_GPIO_BANK5	17
+#define INT_7XX_GPIO_BANK6	18
+#define INT_7XX_SPGIO_WR	29
+
+/*
+ * IRQ numbers for interrupt handler 2
+ *
+ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
+ */
+#define IH2_BASE		32
+
+#define INT_KEYBOARD		(1 + IH2_BASE)
+#define INT_uWireTX		(2 + IH2_BASE)
+#define INT_uWireRX		(3 + IH2_BASE)
+#define INT_I2C			(4 + IH2_BASE)
+#define INT_MPUIO		(5 + IH2_BASE)
+#define INT_USB_HHC_1		(6 + IH2_BASE)
+#define INT_McBSP3TX		(10 + IH2_BASE)
+#define INT_McBSP3RX		(11 + IH2_BASE)
+#define INT_McBSP1TX		(12 + IH2_BASE)
+#define INT_McBSP1RX		(13 + IH2_BASE)
+#define INT_UART1		(14 + IH2_BASE)
+#define INT_UART2		(15 + IH2_BASE)
+#define INT_BT_MCSI1TX		(16 + IH2_BASE)
+#define INT_BT_MCSI1RX		(17 + IH2_BASE)
+#define INT_SOSSI_MATCH		(19 + IH2_BASE)
+#define INT_USB_W2FC		(20 + IH2_BASE)
+#define INT_1WIRE		(21 + IH2_BASE)
+#define INT_OS_TIMER		(22 + IH2_BASE)
+#define INT_MMC			(23 + IH2_BASE)
+#define INT_GAUGE_32K		(24 + IH2_BASE)
+#define INT_RTC_TIMER		(25 + IH2_BASE)
+#define INT_RTC_ALARM		(26 + IH2_BASE)
+#define INT_MEM_STICK		(27 + IH2_BASE)
+
+/*
+ * OMAP-1510 specific IRQ numbers for interrupt handler 2
+ */
+#define INT_1510_DSP_MMU	(28 + IH2_BASE)
+#define INT_1510_COM_SPI_RO	(31 + IH2_BASE)
+
+/*
+ * OMAP-1610 specific IRQ numbers for interrupt handler 2
+ */
+#define INT_1610_FAC		(0 + IH2_BASE)
+#define INT_1610_USB_HHC_2	(7 + IH2_BASE)
+#define INT_1610_USB_OTG	(8 + IH2_BASE)
+#define INT_1610_SoSSI		(9 + IH2_BASE)
+#define INT_1610_SoSSI_MATCH	(19 + IH2_BASE)
+#define INT_1610_DSP_MMU	(28 + IH2_BASE)
+#define INT_1610_McBSP2RX_OF	(31 + IH2_BASE)
+#define INT_1610_STI		(32 + IH2_BASE)
+#define INT_1610_STI_WAKEUP	(33 + IH2_BASE)
+#define INT_1610_GPTIMER3	(34 + IH2_BASE)
+#define INT_1610_GPTIMER4	(35 + IH2_BASE)
+#define INT_1610_GPTIMER5	(36 + IH2_BASE)
+#define INT_1610_GPTIMER6	(37 + IH2_BASE)
+#define INT_1610_GPTIMER7	(38 + IH2_BASE)
+#define INT_1610_GPTIMER8	(39 + IH2_BASE)
+#define INT_1610_GPIO_BANK2	(40 + IH2_BASE)
+#define INT_1610_GPIO_BANK3	(41 + IH2_BASE)
+#define INT_1610_MMC2		(42 + IH2_BASE)
+#define INT_1610_CF		(43 + IH2_BASE)
+#define INT_1610_WAKE_UP_REQ	(46 + IH2_BASE)
+#define INT_1610_GPIO_BANK4	(48 + IH2_BASE)
+#define INT_1610_SPI		(49 + IH2_BASE)
+#define INT_1610_DMA_CH6	(53 + IH2_BASE)
+#define INT_1610_DMA_CH7	(54 + IH2_BASE)
+#define INT_1610_DMA_CH8	(55 + IH2_BASE)
+#define INT_1610_DMA_CH9	(56 + IH2_BASE)
+#define INT_1610_DMA_CH10	(57 + IH2_BASE)
+#define INT_1610_DMA_CH11	(58 + IH2_BASE)
+#define INT_1610_DMA_CH12	(59 + IH2_BASE)
+#define INT_1610_DMA_CH13	(60 + IH2_BASE)
+#define INT_1610_DMA_CH14	(61 + IH2_BASE)
+#define INT_1610_DMA_CH15	(62 + IH2_BASE)
+#define INT_1610_NAND		(63 + IH2_BASE)
+#define INT_1610_SHA1MD5	(91 + IH2_BASE)
+
+/*
+ * OMAP-7xx specific IRQ numbers for interrupt handler 2
+ */
+#define INT_7XX_HW_ERRORS	(0 + IH2_BASE)
+#define INT_7XX_NFIQ_PWR_FAIL	(1 + IH2_BASE)
+#define INT_7XX_CFCD		(2 + IH2_BASE)
+#define INT_7XX_CFIREQ		(3 + IH2_BASE)
+#define INT_7XX_I2C		(4 + IH2_BASE)
+#define INT_7XX_PCC		(5 + IH2_BASE)
+#define INT_7XX_MPU_EXT_NIRQ	(6 + IH2_BASE)
+#define INT_7XX_SPI_100K_1	(7 + IH2_BASE)
+#define INT_7XX_SYREN_SPI	(8 + IH2_BASE)
+#define INT_7XX_VLYNQ		(9 + IH2_BASE)
+#define INT_7XX_GPIO_BANK4	(10 + IH2_BASE)
+#define INT_7XX_McBSP1TX	(11 + IH2_BASE)
+#define INT_7XX_McBSP1RX	(12 + IH2_BASE)
+#define INT_7XX_McBSP1RX_OF	(13 + IH2_BASE)
+#define INT_7XX_UART_MODEM_IRDA_2 (14 + IH2_BASE)
+#define INT_7XX_UART_MODEM_1	(15 + IH2_BASE)
+#define INT_7XX_MCSI		(16 + IH2_BASE)
+#define INT_7XX_uWireTX		(17 + IH2_BASE)
+#define INT_7XX_uWireRX		(18 + IH2_BASE)
+#define INT_7XX_SMC_CD		(19 + IH2_BASE)
+#define INT_7XX_SMC_IREQ	(20 + IH2_BASE)
+#define INT_7XX_HDQ_1WIRE	(21 + IH2_BASE)
+#define INT_7XX_TIMER32K	(22 + IH2_BASE)
+#define INT_7XX_MMC_SDIO	(23 + IH2_BASE)
+#define INT_7XX_UPLD		(24 + IH2_BASE)
+#define INT_7XX_USB_HHC_1	(27 + IH2_BASE)
+#define INT_7XX_USB_HHC_2	(28 + IH2_BASE)
+#define INT_7XX_USB_GENI	(29 + IH2_BASE)
+#define INT_7XX_USB_OTG		(30 + IH2_BASE)
+#define INT_7XX_CAMERA_IF	(31 + IH2_BASE)
+#define INT_7XX_RNG		(32 + IH2_BASE)
+#define INT_7XX_DUAL_MODE_TIMER (33 + IH2_BASE)
+#define INT_7XX_DBB_RF_EN	(34 + IH2_BASE)
+#define INT_7XX_MPUIO_KEYPAD	(35 + IH2_BASE)
+#define INT_7XX_SHA1_MD5	(36 + IH2_BASE)
+#define INT_7XX_SPI_100K_2	(37 + IH2_BASE)
+#define INT_7XX_RNG_IDLE	(38 + IH2_BASE)
+#define INT_7XX_MPUIO		(39 + IH2_BASE)
+#define INT_7XX_LLPC_LCD_CTRL_CAN_BE_OFF	(40 + IH2_BASE)
+#define INT_7XX_LLPC_OE_FALLING (41 + IH2_BASE)
+#define INT_7XX_LLPC_OE_RISING	(42 + IH2_BASE)
+#define INT_7XX_LLPC_VSYNC	(43 + IH2_BASE)
+#define INT_7XX_WAKE_UP_REQ	(46 + IH2_BASE)
+#define INT_7XX_DMA_CH6		(53 + IH2_BASE)
+#define INT_7XX_DMA_CH7		(54 + IH2_BASE)
+#define INT_7XX_DMA_CH8		(55 + IH2_BASE)
+#define INT_7XX_DMA_CH9		(56 + IH2_BASE)
+#define INT_7XX_DMA_CH10	(57 + IH2_BASE)
+#define INT_7XX_DMA_CH11	(58 + IH2_BASE)
+#define INT_7XX_DMA_CH12	(59 + IH2_BASE)
+#define INT_7XX_DMA_CH13	(60 + IH2_BASE)
+#define INT_7XX_DMA_CH14	(61 + IH2_BASE)
+#define INT_7XX_DMA_CH15	(62 + IH2_BASE)
+#define INT_7XX_NAND		(63 + IH2_BASE)
+
+#define INT_24XX_SYS_NIRQ	7
+#define INT_24XX_SDMA_IRQ0	12
+#define INT_24XX_SDMA_IRQ1	13
+#define INT_24XX_SDMA_IRQ2	14
+#define INT_24XX_SDMA_IRQ3	15
+#define INT_24XX_CAM_IRQ	24
+#define INT_24XX_DSS_IRQ	25
+#define INT_24XX_MAIL_U0_MPU	26
+#define INT_24XX_DSP_UMA	27
+#define INT_24XX_DSP_MMU	28
+#define INT_24XX_GPIO_BANK1	29
+#define INT_24XX_GPIO_BANK2	30
+#define INT_24XX_GPIO_BANK3	31
+#define INT_24XX_GPIO_BANK4	32
+#define INT_24XX_GPIO_BANK5	33
+#define INT_24XX_MAIL_U3_MPU	34
+#define INT_24XX_GPTIMER1	37
+#define INT_24XX_GPTIMER2	38
+#define INT_24XX_GPTIMER3	39
+#define INT_24XX_GPTIMER4	40
+#define INT_24XX_GPTIMER5	41
+#define INT_24XX_GPTIMER6	42
+#define INT_24XX_GPTIMER7	43
+#define INT_24XX_GPTIMER8	44
+#define INT_24XX_GPTIMER9	45
+#define INT_24XX_GPTIMER10	46
+#define INT_24XX_GPTIMER11	47
+#define INT_24XX_GPTIMER12	48
+#define INT_24XX_SHA1MD5	51
+#define INT_24XX_MCBSP4_IRQ_TX	54
+#define INT_24XX_MCBSP4_IRQ_RX	55
+#define INT_24XX_I2C1_IRQ	56
+#define INT_24XX_I2C2_IRQ	57
+#define INT_24XX_HDQ_IRQ	58
+#define INT_24XX_MCBSP1_IRQ_TX	59
+#define INT_24XX_MCBSP1_IRQ_RX	60
+#define INT_24XX_MCBSP2_IRQ_TX	62
+#define INT_24XX_MCBSP2_IRQ_RX	63
+#define INT_24XX_SPI1_IRQ	65
+#define INT_24XX_SPI2_IRQ	66
+#define INT_24XX_UART1_IRQ	72
+#define INT_24XX_UART2_IRQ	73
+#define INT_24XX_UART3_IRQ	74
+#define INT_24XX_USB_IRQ_GEN	75
+#define INT_24XX_USB_IRQ_NISO	76
+#define INT_24XX_USB_IRQ_ISO	77
+#define INT_24XX_USB_IRQ_HGEN	78
+#define INT_24XX_USB_IRQ_HSOF	79
+#define INT_24XX_USB_IRQ_OTG	80
+#define INT_24XX_MCBSP5_IRQ_TX	81
+#define INT_24XX_MCBSP5_IRQ_RX	82
+#define INT_24XX_MMC_IRQ	83
+#define INT_24XX_MMC2_IRQ	86
+#define INT_24XX_MCBSP3_IRQ_TX	89
+#define INT_24XX_MCBSP3_IRQ_RX	90
+#define INT_24XX_SPI3_IRQ	91
+
+#define INT_243X_MCBSP2_IRQ	16
+#define INT_243X_MCBSP3_IRQ	17
+#define INT_243X_MCBSP4_IRQ	18
+#define INT_243X_MCBSP5_IRQ	19
+#define INT_243X_MCBSP1_IRQ	64
+#define INT_243X_HS_USB_MC	92
+#define INT_243X_HS_USB_DMA	93
+#define INT_243X_CARKIT_IRQ	94
+
+#define INT_34XX_BENCH_MPU_EMUL	3
+#define INT_34XX_ST_MCBSP2_IRQ	4
+#define INT_34XX_ST_MCBSP3_IRQ	5
+#define INT_34XX_SSM_ABORT_IRQ	6
+#define INT_34XX_SYS_NIRQ	7
+#define INT_34XX_D2D_FW_IRQ	8
+#define INT_34XX_PRCM_MPU_IRQ	11
+#define INT_34XX_MCBSP1_IRQ	16
+#define INT_34XX_MCBSP2_IRQ	17
+#define INT_34XX_MCBSP3_IRQ	22
+#define INT_34XX_MCBSP4_IRQ	23
+#define INT_34XX_CAM_IRQ	24
+#define INT_34XX_MCBSP5_IRQ	27
+#define INT_34XX_GPIO_BANK1	29
+#define INT_34XX_GPIO_BANK2	30
+#define INT_34XX_GPIO_BANK3	31
+#define INT_34XX_GPIO_BANK4	32
+#define INT_34XX_GPIO_BANK5	33
+#define INT_34XX_GPIO_BANK6	34
+#define INT_34XX_USIM_IRQ	35
+#define INT_34XX_WDT3_IRQ	36
+#define INT_34XX_SPI4_IRQ	48
+#define INT_34XX_SHA1MD52_IRQ	49
+#define INT_34XX_FPKA_READY_IRQ	50
+#define INT_34XX_SHA1MD51_IRQ	51
+#define INT_34XX_RNG_IRQ	52
+#define INT_34XX_I2C3_IRQ	61
+#define INT_34XX_FPKA_ERROR_IRQ	64
+#define INT_34XX_PBIAS_IRQ	75
+#define INT_34XX_OHCI_IRQ	76
+#define INT_34XX_EHCI_IRQ	77
+#define INT_34XX_TLL_IRQ	78
+#define INT_34XX_PARTHASH_IRQ	79
+#define INT_34XX_MMC3_IRQ	94
+#define INT_34XX_GPT12_IRQ	95
+
+#define	INT_34XX_BENCH_MPU_EMUL	3
+
+
+#define IRQ_GIC_START		32
+#define INT_44XX_LOCALTIMER_IRQ	29
+#define INT_44XX_LOCALWDT_IRQ	30
+
+#define INT_44XX_BENCH_MPU_EMUL	(3 + IRQ_GIC_START)
+#define INT_44XX_SSM_ABORT_IRQ	(6 + IRQ_GIC_START)
+#define INT_44XX_SYS_NIRQ	(7 + IRQ_GIC_START)
+#define INT_44XX_D2D_FW_IRQ	(8 + IRQ_GIC_START)
+#define INT_44XX_PRCM_MPU_IRQ	(11 + IRQ_GIC_START)
+#define INT_44XX_SDMA_IRQ0	(12 + IRQ_GIC_START)
+#define INT_44XX_SDMA_IRQ1	(13 + IRQ_GIC_START)
+#define INT_44XX_SDMA_IRQ2	(14 + IRQ_GIC_START)
+#define INT_44XX_SDMA_IRQ3	(15 + IRQ_GIC_START)
+#define INT_44XX_ISS_IRQ	(24 + IRQ_GIC_START)
+#define INT_44XX_DSS_IRQ	(25 + IRQ_GIC_START)
+#define INT_44XX_MAIL_U0_MPU	(26 + IRQ_GIC_START)
+#define INT_44XX_DSP_MMU	(28 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER1	(37 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER2	(38 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER3	(39 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER4	(40 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER5	(41 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER6	(42 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER7	(43 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER8	(44 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER9	(45 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER10	(46 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER11	(47 + IRQ_GIC_START)
+#define INT_44XX_GPTIMER12	(95 + IRQ_GIC_START)
+#define INT_44XX_SHA1MD5	(51 + IRQ_GIC_START)
+#define INT_44XX_I2C1_IRQ	(56 + IRQ_GIC_START)
+#define INT_44XX_I2C2_IRQ	(57 + IRQ_GIC_START)
+#define INT_44XX_HDQ_IRQ	(58 + IRQ_GIC_START)
+#define INT_44XX_SPI1_IRQ	(65 + IRQ_GIC_START)
+#define INT_44XX_SPI2_IRQ	(66 + IRQ_GIC_START)
+#define INT_44XX_HSI_1_IRQ0	(67 + IRQ_GIC_START)
+#define INT_44XX_HSI_2_IRQ1	(68 + IRQ_GIC_START)
+#define INT_44XX_HSI_1_DMAIRQ	(71 + IRQ_GIC_START)
+#define INT_44XX_UART1_IRQ	(72 + IRQ_GIC_START)
+#define INT_44XX_UART2_IRQ	(73 + IRQ_GIC_START)
+#define INT_44XX_UART3_IRQ	(74 + IRQ_GIC_START)
+#define INT_44XX_UART4_IRQ	(70 + IRQ_GIC_START)
+#define INT_44XX_USB_IRQ_NISO	(76 + IRQ_GIC_START)
+#define INT_44XX_USB_IRQ_ISO	(77 + IRQ_GIC_START)
+#define INT_44XX_USB_IRQ_HGEN	(78 + IRQ_GIC_START)
+#define INT_44XX_USB_IRQ_HSOF	(79 + IRQ_GIC_START)
+#define INT_44XX_USB_IRQ_OTG	(80 + IRQ_GIC_START)
+#define INT_44XX_MCBSP4_IRQ_TX	(81 + IRQ_GIC_START)
+#define INT_44XX_MCBSP4_IRQ_RX	(82 + IRQ_GIC_START)
+#define INT_44XX_MMC_IRQ	(83 + IRQ_GIC_START)
+#define INT_44XX_MMC2_IRQ	(86 + IRQ_GIC_START)
+#define INT_44XX_MCBSP2_IRQ_TX	(89 + IRQ_GIC_START)
+#define INT_44XX_MCBSP2_IRQ_RX	(90 + IRQ_GIC_START)
+#define INT_44XX_SPI3_IRQ	(91 + IRQ_GIC_START)
+#define INT_44XX_SPI5_IRQ	(69 + IRQ_GIC_START)
+
+#define INT_44XX_MCBSP5_IRQ	(16 + IRQ_GIC_START)
+#define INT_44xX_MCBSP1_IRQ	(17 + IRQ_GIC_START)
+#define INT_44XX_MCBSP2_IRQ	(22 + IRQ_GIC_START)
+#define INT_44XX_MCBSP3_IRQ	(23 + IRQ_GIC_START)
+#define INT_44XX_MCBSP4_IRQ	(27 + IRQ_GIC_START)
+#define INT_44XX_HS_USB_MC	(92 + IRQ_GIC_START)
+#define INT_44XX_HS_USB_DMA	(93 + IRQ_GIC_START)
+
+#define INT_44XX_GPIO_BANK1	(29 + IRQ_GIC_START)
+#define INT_44XX_GPIO_BANK2	(30 + IRQ_GIC_START)
+#define INT_44XX_GPIO_BANK3	(31 + IRQ_GIC_START)
+#define INT_44XX_GPIO_BANK4	(32 + IRQ_GIC_START)
+#define INT_44XX_GPIO_BANK5	(33 + IRQ_GIC_START)
+#define INT_44XX_GPIO_BANK6	(34 + IRQ_GIC_START)
+#define INT_44XX_USIM_IRQ	(35 + IRQ_GIC_START)
+#define INT_44XX_WDT3_IRQ	(36 + IRQ_GIC_START)
+#define INT_44XX_SPI4_IRQ	(48 + IRQ_GIC_START)
+#define INT_44XX_SHA1MD52_IRQ	(49 + IRQ_GIC_START)
+#define INT_44XX_FPKA_READY_IRQ	(50 + IRQ_GIC_START)
+#define INT_44XX_SHA1MD51_IRQ	(51 + IRQ_GIC_START)
+#define INT_44XX_RNG_IRQ	(52 + IRQ_GIC_START)
+#define INT_44XX_MMC5_IRQ	(59 + IRQ_GIC_START)
+#define INT_44XX_I2C3_IRQ	(61 + IRQ_GIC_START)
+#define INT_44XX_FPKA_ERROR_IRQ	(64 + IRQ_GIC_START)
+#define INT_44XX_PBIAS_IRQ	(75 + IRQ_GIC_START)
+#define INT_44XX_OHCI_IRQ	(76 + IRQ_GIC_START)
+#define INT_44XX_EHCI_IRQ	(77 + IRQ_GIC_START)
+#define INT_44XX_TLL_IRQ	(78 + IRQ_GIC_START)
+#define INT_44XX_PARTHASH_IRQ	(79 + IRQ_GIC_START)
+#define INT_44XX_MMC3_IRQ	(94 + IRQ_GIC_START)
+#define INT_44XX_MMC4_IRQ	(96 + IRQ_GIC_START)
+
+
+/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
+ * 16 MPUIO lines */
+#define OMAP_MAX_GPIO_LINES	192
+#define IH_GPIO_BASE		(128 + IH2_BASE)
+#define IH_MPUIO_BASE		(OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
+#define OMAP_IRQ_END		(IH_MPUIO_BASE + 16)
+
+/* External FPGA handles interrupts on Innovator boards */
+#define	OMAP_FPGA_IRQ_BASE	(OMAP_IRQ_END)
+#ifdef	CONFIG_MACH_OMAP_INNOVATOR
+#define OMAP_FPGA_NR_IRQS	24
+#else
+#define OMAP_FPGA_NR_IRQS	0
+#endif
+#define OMAP_FPGA_IRQ_END	(OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
+
+/* External TWL4030 can handle interrupts on 2430 and 34xx boards */
+#define	TWL4030_IRQ_BASE	(OMAP_FPGA_IRQ_END)
+#ifdef	CONFIG_TWL4030_CORE
+#define	TWL4030_BASE_NR_IRQS	8
+#define	TWL4030_PWR_NR_IRQS	8
+#else
+#define	TWL4030_BASE_NR_IRQS	0
+#define	TWL4030_PWR_NR_IRQS	0
+#endif
+#define TWL4030_IRQ_END		(TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS)
+#define TWL4030_PWR_IRQ_BASE	TWL4030_IRQ_END
+#define	TWL4030_PWR_IRQ_END	(TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS)
+
+/* External TWL4030 gpio interrupts are optional */
+#define TWL4030_GPIO_IRQ_BASE	TWL4030_PWR_IRQ_END
+#ifdef	CONFIG_GPIO_TWL4030
+#define TWL4030_GPIO_NR_IRQS	18
+#else
+#define	TWL4030_GPIO_NR_IRQS	0
+#endif
+#define TWL4030_GPIO_IRQ_END	(TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
+
+#define	TWL6030_IRQ_BASE	(OMAP_FPGA_IRQ_END)
+#ifdef CONFIG_TWL4030_CORE
+#define	TWL6030_BASE_NR_IRQS	20
+#else
+#define	TWL6030_BASE_NR_IRQS	0
+#endif
+#define TWL6030_IRQ_END		(TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
+
+/* Total number of interrupts depends on the enabled blocks above */
+#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#define TWL_IRQ_END 		TWL4030_GPIO_IRQ_END
+#else
+#define TWL_IRQ_END		TWL6030_IRQ_END
+#endif
+
+#define NR_IRQS			TWL_IRQ_END
+
+#define OMAP_IRQ_BIT(irq)	(1 << ((irq) % 32))
+
+#define INTCPS_NR_MIR_REGS	3
+#define INTCPS_NR_IRQS		96
+
+#ifndef __ASSEMBLY__
+extern void omap_init_irq(void);
+extern int omap_irq_pending(void);
+void omap_intc_save_context(void);
+void omap_intc_restore_context(void);
+void omap3_intc_suspend(void);
+void omap3_intc_prepare_idle(void);
+void omap3_intc_resume_idle(void);
+#endif
+
+#include <mach/hardware.h>
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/keypad.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/keypad.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/keypad.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/keypad.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+ *  arch/arm/plat-omap/include/mach/keypad.h
+ *
+ *  Copyright (C) 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_KEYPAD_H
+#define ASMARM_ARCH_KEYPAD_H
+
+#warning: Please update the board to use matrix_keypad.h instead
+
+struct omap_kp_platform_data {
+	int rows;
+	int cols;
+	int *keymap;
+	unsigned int keymapsize;
+	unsigned int rep:1;
+	unsigned long delay;
+	unsigned int dbounce:1;
+	/* specific to OMAP242x*/
+	unsigned int *row_gpios;
+	unsigned int *col_gpios;
+};
+
+/* Group (0..3) -- when multiple keys are pressed, only the
+ * keys pressed in the same group are considered as pressed. This is
+ * in order to workaround certain crappy HW designs that produce ghost
+ * keypresses. */
+#define GROUP_0		(0 << 16)
+#define GROUP_1		(1 << 16)
+#define GROUP_2		(2 << 16)
+#define GROUP_3		(3 << 16)
+#define GROUP_MASK	GROUP_3
+
+#define KEY_PERSISTENT		0x00800000
+#define KEYNUM_MASK		0x00EFFFFF
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
+						KEY_PERSISTENT)
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/lcd_mipid.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/lcd_mipid.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/lcd_mipid.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/lcd_mipid.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+#ifndef __LCD_MIPID_H
+#define __LCD_MIPID_H
+
+enum mipid_test_num {
+	MIPID_TEST_RGB_LINES,
+};
+
+enum mipid_test_result {
+	MIPID_TEST_SUCCESS,
+	MIPID_TEST_INVALID,
+	MIPID_TEST_FAILED,
+};
+
+#ifdef __KERNEL__
+
+struct mipid_platform_data {
+	int	nreset_gpio;
+	int	data_lines;
+
+	void	(*shutdown)(struct mipid_platform_data *pdata);
+	void	(*set_bklight_level)(struct mipid_platform_data *pdata,
+				     int level);
+	int	(*get_bklight_level)(struct mipid_platform_data *pdata);
+	int	(*get_bklight_max)(struct mipid_platform_data *pdata);
+};
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/led.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/led.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/led.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/led.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+/*
+ *  arch/arm/plat-omap/include/mach/led.h
+ *
+ *  Copyright (C) 2006 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@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.
+ */
+#ifndef ASMARM_ARCH_LED_H
+#define ASMARM_ARCH_LED_H
+
+struct omap_led_config {
+	struct led_classdev	cdev;
+	s16			gpio;
+};
+
+struct omap_led_platform_data {
+	s16			nr_leds;
+	struct omap_led_config	*leds;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mailbox.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mailbox.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mailbox.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mailbox.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,111 @@
+/* mailbox.h */
+
+#ifndef MAILBOX_H
+#define MAILBOX_H
+
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/blkdev.h>
+#include <linux/interrupt.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 request_queue	*queue;
+	struct work_struct	work;
+	struct tasklet_struct	tasklet;
+	int	(*callback)(void *);
+	struct omap_mbox	*mbox;
+};
+
+struct omap_mbox {
+	char			*name;
+	unsigned int		irq;
+
+	struct omap_mbox_queue	*txq, *rxq;
+
+	struct omap_mbox_ops	*ops;
+
+	mbox_msg_t		seq_snd, seq_rcv;
+
+	struct device		*dev;
+
+	struct omap_mbox	*next;
+	void			*priv;
+
+	void			(*err_notify)(void);
+};
+
+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 *);
+void omap_mbox_put(struct omap_mbox *);
+
+int omap_mbox_register(struct device *parent, struct omap_mbox *);
+int omap_mbox_unregister(struct omap_mbox *);
+
+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 linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcbsp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,462 @@
+/*
+ * arch/arm/plat-omap/include/mach/mcbsp.h
+ *
+ * Defines for Multi-Channel Buffered Serial Port
+ *
+ * Copyright (C) 2002 RidgeRun, Inc.
+ * Author: Steve Johnson
+ *
+ * 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_OMAP_MCBSP_H
+#define __ASM_ARCH_OMAP_MCBSP_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+#include <plat/clock.h>
+
+#define OMAP7XX_MCBSP1_BASE	0xfffb1000
+#define OMAP7XX_MCBSP2_BASE	0xfffb1800
+
+#define OMAP1510_MCBSP1_BASE	0xe1011800
+#define OMAP1510_MCBSP2_BASE	0xfffb1000
+#define OMAP1510_MCBSP3_BASE	0xe1017000
+
+#define OMAP1610_MCBSP1_BASE	0xe1011800
+#define OMAP1610_MCBSP2_BASE	0xfffb1000
+#define OMAP1610_MCBSP3_BASE	0xe1017000
+
+#define OMAP24XX_MCBSP1_BASE	0x48074000
+#define OMAP24XX_MCBSP2_BASE	0x48076000
+#define OMAP2430_MCBSP3_BASE	0x4808c000
+#define OMAP2430_MCBSP4_BASE	0x4808e000
+#define OMAP2430_MCBSP5_BASE	0x48096000
+
+#define OMAP34XX_MCBSP1_BASE	0x48074000
+#define OMAP34XX_MCBSP2_BASE	0x49022000
+#define OMAP34XX_MCBSP3_BASE	0x49024000
+#define OMAP34XX_MCBSP4_BASE	0x49026000
+#define OMAP34XX_MCBSP5_BASE	0x48096000
+
+#define OMAP44XX_MCBSP1_BASE	0x49022000
+#define OMAP44XX_MCBSP2_BASE	0x49024000
+#define OMAP44XX_MCBSP3_BASE	0x49026000
+#define OMAP44XX_MCBSP4_BASE	0x48074000
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+
+#define OMAP_MCBSP_REG_DRR2	0x00
+#define OMAP_MCBSP_REG_DRR1	0x02
+#define OMAP_MCBSP_REG_DXR2	0x04
+#define OMAP_MCBSP_REG_DXR1	0x06
+#define OMAP_MCBSP_REG_SPCR2	0x08
+#define OMAP_MCBSP_REG_SPCR1	0x0a
+#define OMAP_MCBSP_REG_RCR2	0x0c
+#define OMAP_MCBSP_REG_RCR1	0x0e
+#define OMAP_MCBSP_REG_XCR2	0x10
+#define OMAP_MCBSP_REG_XCR1	0x12
+#define OMAP_MCBSP_REG_SRGR2	0x14
+#define OMAP_MCBSP_REG_SRGR1	0x16
+#define OMAP_MCBSP_REG_MCR2	0x18
+#define OMAP_MCBSP_REG_MCR1	0x1a
+#define OMAP_MCBSP_REG_RCERA	0x1c
+#define OMAP_MCBSP_REG_RCERB	0x1e
+#define OMAP_MCBSP_REG_XCERA	0x20
+#define OMAP_MCBSP_REG_XCERB	0x22
+#define OMAP_MCBSP_REG_PCR0	0x24
+#define OMAP_MCBSP_REG_RCERC	0x26
+#define OMAP_MCBSP_REG_RCERD	0x28
+#define OMAP_MCBSP_REG_XCERC	0x2A
+#define OMAP_MCBSP_REG_XCERD	0x2C
+#define OMAP_MCBSP_REG_RCERE	0x2E
+#define OMAP_MCBSP_REG_RCERF	0x30
+#define OMAP_MCBSP_REG_XCERE	0x32
+#define OMAP_MCBSP_REG_XCERF	0x34
+#define OMAP_MCBSP_REG_RCERG	0x36
+#define OMAP_MCBSP_REG_RCERH	0x38
+#define OMAP_MCBSP_REG_XCERG	0x3A
+#define OMAP_MCBSP_REG_XCERH	0x3C
+
+/* Dummy defines, these are not available on omap1 */
+#define OMAP_MCBSP_REG_XCCR	0x00
+#define OMAP_MCBSP_REG_RCCR	0x00
+
+#define AUDIO_MCBSP_DATAWRITE	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
+#define AUDIO_MCBSP_DATAREAD	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
+
+#define AUDIO_MCBSP		OMAP_MCBSP1
+#define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
+#define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
+
+#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
+	defined(CONFIG_ARCH_OMAP4)
+
+#define OMAP_MCBSP_REG_DRR2	0x00
+#define OMAP_MCBSP_REG_DRR1	0x04
+#define OMAP_MCBSP_REG_DXR2	0x08
+#define OMAP_MCBSP_REG_DXR1	0x0C
+#define OMAP_MCBSP_REG_DRR	0x00
+#define OMAP_MCBSP_REG_DXR	0x08
+#define OMAP_MCBSP_REG_SPCR2	0x10
+#define OMAP_MCBSP_REG_SPCR1	0x14
+#define OMAP_MCBSP_REG_RCR2	0x18
+#define OMAP_MCBSP_REG_RCR1	0x1C
+#define OMAP_MCBSP_REG_XCR2	0x20
+#define OMAP_MCBSP_REG_XCR1	0x24
+#define OMAP_MCBSP_REG_SRGR2	0x28
+#define OMAP_MCBSP_REG_SRGR1	0x2C
+#define OMAP_MCBSP_REG_MCR2	0x30
+#define OMAP_MCBSP_REG_MCR1	0x34
+#define OMAP_MCBSP_REG_RCERA	0x38
+#define OMAP_MCBSP_REG_RCERB	0x3C
+#define OMAP_MCBSP_REG_XCERA	0x40
+#define OMAP_MCBSP_REG_XCERB	0x44
+#define OMAP_MCBSP_REG_PCR0	0x48
+#define OMAP_MCBSP_REG_RCERC	0x4C
+#define OMAP_MCBSP_REG_RCERD	0x50
+#define OMAP_MCBSP_REG_XCERC	0x54
+#define OMAP_MCBSP_REG_XCERD	0x58
+#define OMAP_MCBSP_REG_RCERE	0x5C
+#define OMAP_MCBSP_REG_RCERF	0x60
+#define OMAP_MCBSP_REG_XCERE	0x64
+#define OMAP_MCBSP_REG_XCERF	0x68
+#define OMAP_MCBSP_REG_RCERG	0x6C
+#define OMAP_MCBSP_REG_RCERH	0x70
+#define OMAP_MCBSP_REG_XCERG	0x74
+#define OMAP_MCBSP_REG_XCERH	0x78
+#define OMAP_MCBSP_REG_SYSCON	0x8C
+#define OMAP_MCBSP_REG_THRSH2	0x90
+#define OMAP_MCBSP_REG_THRSH1	0x94
+#define OMAP_MCBSP_REG_IRQST	0xA0
+#define OMAP_MCBSP_REG_IRQEN	0xA4
+#define OMAP_MCBSP_REG_WAKEUPEN	0xA8
+#define OMAP_MCBSP_REG_XCCR	0xAC
+#define OMAP_MCBSP_REG_RCCR	0xB0
+
+#define AUDIO_MCBSP_DATAWRITE	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
+#define AUDIO_MCBSP_DATAREAD	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
+
+#define AUDIO_MCBSP		OMAP_MCBSP2
+#define AUDIO_DMA_TX		OMAP24XX_DMA_MCBSP2_TX
+#define AUDIO_DMA_RX		OMAP24XX_DMA_MCBSP2_RX
+
+#endif
+
+/************************** McBSP SPCR1 bit definitions ***********************/
+#define RRST			0x0001
+#define RRDY			0x0002
+#define RFULL			0x0004
+#define RSYNC_ERR		0x0008
+#define RINTM(value)		((value)<<4)	/* bits 4:5 */
+#define ABIS			0x0040
+#define DXENA			0x0080
+#define CLKSTP(value)		((value)<<11)	/* bits 11:12 */
+#define RJUST(value)		((value)<<13)	/* bits 13:14 */
+#define ALB			0x8000
+#define DLB			0x8000
+
+/************************** McBSP SPCR2 bit definitions ***********************/
+#define XRST		0x0001
+#define XRDY		0x0002
+#define XEMPTY		0x0004
+#define XSYNC_ERR	0x0008
+#define XINTM(value)	((value)<<4)		/* bits 4:5 */
+#define GRST		0x0040
+#define FRST		0x0080
+#define SOFT		0x0100
+#define FREE		0x0200
+
+/************************** McBSP PCR bit definitions *************************/
+#define CLKRP		0x0001
+#define CLKXP		0x0002
+#define FSRP		0x0004
+#define FSXP		0x0008
+#define DR_STAT		0x0010
+#define DX_STAT		0x0020
+#define CLKS_STAT	0x0040
+#define SCLKME		0x0080
+#define CLKRM		0x0100
+#define CLKXM		0x0200
+#define FSRM		0x0400
+#define FSXM		0x0800
+#define RIOEN		0x1000
+#define XIOEN		0x2000
+#define IDLE_EN		0x4000
+
+/************************** McBSP RCR1 bit definitions ************************/
+#define RWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
+#define RFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
+
+/************************** McBSP XCR1 bit definitions ************************/
+#define XWDLEN1(value)		((value)<<5)	/* Bits 5:7 */
+#define XFRLEN1(value)		((value)<<8)	/* Bits 8:14 */
+
+/*************************** McBSP RCR2 bit definitions ***********************/
+#define RDATDLY(value)		(value)		/* Bits 0:1 */
+#define RFIG			0x0004
+#define RCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
+#define RWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
+#define RFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
+#define RPHASE			0x8000
+
+/*************************** McBSP XCR2 bit definitions ***********************/
+#define XDATDLY(value)		(value)		/* Bits 0:1 */
+#define XFIG			0x0004
+#define XCOMPAND(value)		((value)<<3)	/* Bits 3:4 */
+#define XWDLEN2(value)		((value)<<5)	/* Bits 5:7 */
+#define XFRLEN2(value)		((value)<<8)	/* Bits 8:14 */
+#define XPHASE			0x8000
+
+/************************* McBSP SRGR1 bit definitions ************************/
+#define CLKGDV(value)		(value)		/* Bits 0:7 */
+#define FWID(value)		((value)<<8)	/* Bits 8:15 */
+
+/************************* McBSP SRGR2 bit definitions ************************/
+#define FPER(value)		(value)		/* Bits 0:11 */
+#define FSGM			0x1000
+#define CLKSM			0x2000
+#define CLKSP			0x4000
+#define GSYNC			0x8000
+
+/************************* McBSP MCR1 bit definitions *************************/
+#define RMCM			0x0001
+#define RCBLK(value)		((value)<<2)	/* Bits 2:4 */
+#define RPABLK(value)		((value)<<5)	/* Bits 5:6 */
+#define RPBBLK(value)		((value)<<7)	/* Bits 7:8 */
+
+/************************* McBSP MCR2 bit definitions *************************/
+#define XMCM(value)		(value)		/* Bits 0:1 */
+#define XCBLK(value)		((value)<<2)	/* Bits 2:4 */
+#define XPABLK(value)		((value)<<5)	/* Bits 5:6 */
+#define XPBBLK(value)		((value)<<7)	/* Bits 7:8 */
+
+/*********************** McBSP XCCR bit definitions *************************/
+#define EXTCLKGATE		0x8000
+#define PPCONNECT		0x4000
+#define DXENDLY(value)		((value)<<12)	/* Bits 12:13 */
+#define XFULL_CYCLE		0x0800
+#define DILB			0x0020
+#define XDMAEN			0x0008
+#define XDISABLE		0x0001
+
+/********************** McBSP RCCR bit definitions *************************/
+#define RFULL_CYCLE		0x0800
+#define RDMAEN			0x0008
+#define RDISABLE		0x0001
+
+/********************** McBSP SYSCONFIG bit definitions ********************/
+#define CLOCKACTIVITY(value)	((value)<<8)
+#define SIDLEMODE(value)	((value)<<3)
+#define ENAWAKEUP		0x0004
+#define SOFTRST			0x0002
+
+/********************** McBSP DMA operating modes **************************/
+#define MCBSP_DMA_MODE_ELEMENT		0
+#define MCBSP_DMA_MODE_THRESHOLD	1
+#define MCBSP_DMA_MODE_FRAME		2
+
+/********************** McBSP WAKEUPEN bit definitions *********************/
+#define XEMPTYEOFEN		0x4000
+#define XRDYEN			0x0400
+#define XEOFEN			0x0200
+#define XFSXEN			0x0100
+#define XSYNCERREN		0x0080
+#define RRDYEN			0x0008
+#define REOFEN			0x0004
+#define RFSREN			0x0002
+#define RSYNCERREN		0x0001
+
+/* we don't do multichannel for now */
+struct omap_mcbsp_reg_cfg {
+	u16 spcr2;
+	u16 spcr1;
+	u16 rcr2;
+	u16 rcr1;
+	u16 xcr2;
+	u16 xcr1;
+	u16 srgr2;
+	u16 srgr1;
+	u16 mcr2;
+	u16 mcr1;
+	u16 pcr0;
+	u16 rcerc;
+	u16 rcerd;
+	u16 xcerc;
+	u16 xcerd;
+	u16 rcere;
+	u16 rcerf;
+	u16 xcere;
+	u16 xcerf;
+	u16 rcerg;
+	u16 rcerh;
+	u16 xcerg;
+	u16 xcerh;
+	u16 xccr;
+	u16 rccr;
+};
+
+typedef enum {
+	OMAP_MCBSP1 = 0,
+	OMAP_MCBSP2,
+	OMAP_MCBSP3,
+	OMAP_MCBSP4,
+	OMAP_MCBSP5
+} omap_mcbsp_id;
+
+typedef int __bitwise omap_mcbsp_io_type_t;
+#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
+#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
+
+typedef enum {
+	OMAP_MCBSP_WORD_8 = 0,
+	OMAP_MCBSP_WORD_12,
+	OMAP_MCBSP_WORD_16,
+	OMAP_MCBSP_WORD_20,
+	OMAP_MCBSP_WORD_24,
+	OMAP_MCBSP_WORD_32,
+} omap_mcbsp_word_length;
+
+typedef enum {
+	OMAP_MCBSP_CLK_RISING = 0,
+	OMAP_MCBSP_CLK_FALLING,
+} omap_mcbsp_clk_polarity;
+
+typedef enum {
+	OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
+	OMAP_MCBSP_FS_ACTIVE_LOW,
+} omap_mcbsp_fs_polarity;
+
+typedef enum {
+	OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
+	OMAP_MCBSP_CLK_STP_MODE_DELAY,
+} omap_mcbsp_clk_stp_mode;
+
+
+/******* SPI specific mode **********/
+typedef enum {
+	OMAP_MCBSP_SPI_MASTER = 0,
+	OMAP_MCBSP_SPI_SLAVE,
+} omap_mcbsp_spi_mode;
+
+struct omap_mcbsp_spi_cfg {
+	omap_mcbsp_spi_mode		spi_mode;
+	omap_mcbsp_clk_polarity		rx_clock_polarity;
+	omap_mcbsp_clk_polarity		tx_clock_polarity;
+	omap_mcbsp_fs_polarity		fsx_polarity;
+	u8				clk_div;
+	omap_mcbsp_clk_stp_mode		clk_stp_mode;
+	omap_mcbsp_word_length		word_length;
+};
+
+/* Platform specific configuration */
+struct omap_mcbsp_ops {
+	void (*request)(unsigned int);
+	void (*free)(unsigned int);
+};
+
+struct omap_mcbsp_platform_data {
+	unsigned long phys_base;
+	u8 dma_rx_sync, dma_tx_sync;
+	u16 rx_irq, tx_irq;
+	struct omap_mcbsp_ops *ops;
+#ifdef CONFIG_ARCH_OMAP34XX
+	u16 buffer_size;
+#endif
+};
+
+struct omap_mcbsp {
+	struct device *dev;
+	unsigned long phys_base;
+	void __iomem *io_base;
+	u8 id;
+	u8 free;
+	omap_mcbsp_word_length rx_word_length;
+	omap_mcbsp_word_length tx_word_length;
+
+	omap_mcbsp_io_type_t io_type; /* IRQ or poll */
+	/* IRQ based TX/RX */
+	int rx_irq;
+	int tx_irq;
+
+	/* DMA stuff */
+	u8 dma_rx_sync;
+	short dma_rx_lch;
+	u8 dma_tx_sync;
+	short dma_tx_lch;
+
+	/* Completion queues */
+	struct completion tx_irq_completion;
+	struct completion rx_irq_completion;
+	struct completion tx_dma_completion;
+	struct completion rx_dma_completion;
+
+	/* Protect the field .free, while checking if the mcbsp is in use */
+	spinlock_t lock;
+	struct omap_mcbsp_platform_data *pdata;
+	struct clk *iclk;
+	struct clk *fclk;
+#ifdef CONFIG_ARCH_OMAP34XX
+	int dma_op_mode;
+	u16 max_tx_thres;
+	u16 max_rx_thres;
+#endif
+};
+extern struct omap_mcbsp **mcbsp_ptr;
+extern int omap_mcbsp_count;
+
+int omap_mcbsp_init(void);
+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
+					int size);
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
+#ifdef CONFIG_ARCH_OMAP34XX
+void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
+void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
+u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
+u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
+int omap_mcbsp_get_dma_op_mode(unsigned int id);
+#else
+static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
+{ }
+static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
+{ }
+static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
+static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
+static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
+#endif
+int omap_mcbsp_request(unsigned int id);
+void omap_mcbsp_free(unsigned int id);
+void omap_mcbsp_start(unsigned int id, int tx, int rx);
+void omap_mcbsp_stop(unsigned int id, int tx, int rx);
+void omap_mcbsp_xmit_word(unsigned int id, u32 word);
+u32 omap_mcbsp_recv_word(unsigned int id);
+
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
+int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
+
+
+/* SPI specific API */
+void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
+
+/* Polled read/write functions */
+int omap_mcbsp_pollread(unsigned int id, u16 * buf);
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mcspi.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcspi.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mcspi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mcspi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,15 @@
+#ifndef _OMAP2_MCSPI_H
+#define _OMAP2_MCSPI_H
+
+struct omap2_mcspi_platform_config {
+	unsigned short	num_cs;
+};
+
+struct omap2_mcspi_device_config {
+	unsigned turbo_mode:1;
+
+	/* Do we want one channel enabled at the same time? */
+	unsigned single_channel:1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/memory.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/memory.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/memory.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * arch/arm/plat-omap/include/mach/memory.h
+ *
+ * Memory map for OMAP-1510 and 1610
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * This file was derived from arch/arm/mach-intergrator/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 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.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#if defined(CONFIG_ARCH_OMAP1)
+#define PHYS_OFFSET		UL(0x10000000)
+#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
+			defined(CONFIG_ARCH_OMAP4)
+#define PHYS_OFFSET		UL(0x80000000)
+#endif
+
+/*
+ * Bus address is physical address, except for OMAP-1510 Local Bus.
+ * OMAP-1510 bus address is translated into a Local Bus address if the
+ * OMAP bus type is lbus. We do the address translation based on the
+ * device overriding the defaults used in the dma-mapping API.
+ * Note that the is_lbus_device() test is not very efficient on 1510
+ * because of the strncmp().
+ */
+#ifdef CONFIG_ARCH_OMAP15XX
+
+/*
+ * OMAP-1510 Local Bus address offset
+ */
+#define OMAP1510_LB_OFFSET	UL(0x30000000)
+
+#define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
+#define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
+#define is_lbus_device(dev)	(cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
+
+#define __arch_page_to_dma(dev, page)	\
+	({ dma_addr_t __dma = page_to_phys(page); \
+	   if (is_lbus_device(dev)) \
+		__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
+	   __dma; })
+
+#define __arch_dma_to_page(dev, addr)	\
+	({ dma_addr_t __dma = addr;				\
+	   if (is_lbus_device(dev))				\
+		__dma += PHYS_OFFSET - OMAP1510_LB_OFFSET;	\
+	   phys_to_page(__dma);					\
+	})
+
+#define __arch_dma_to_virt(dev, addr)	({ (void *) (is_lbus_device(dev) ? \
+						lbus_to_virt(addr) : \
+						__phys_to_virt(addr)); })
+
+#define __arch_virt_to_dma(dev, addr)	({ unsigned long __addr = (unsigned long)(addr); \
+					   (dma_addr_t) (is_lbus_device(dev) ? \
+						virt_to_lbus(__addr) : \
+						__virt_to_phys(__addr)); })
+
+#endif	/* CONFIG_ARCH_OMAP15XX */
+
+/* Override the ARM default */
+#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
+
+#if (CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE == 0)
+#undef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
+#define CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE 2
+#endif
+
+#define CONSISTENT_DMA_SIZE \
+	(((CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE + 1) & ~1) * 1024 * 1024)
+
+#endif
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/menelaus.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/menelaus.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/menelaus.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/menelaus.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/plat-omap/include/mach/menelaus.h
+ *
+ * Functions to access Menelaus power management chip
+ */
+
+#ifndef __ASM_ARCH_MENELAUS_H
+#define __ASM_ARCH_MENELAUS_H
+
+struct device;
+
+struct menelaus_platform_data {
+	int (* late_init)(struct device *dev);
+};
+
+extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
+					  void *data);
+extern void menelaus_unregister_mmc_callback(void);
+extern int menelaus_set_mmc_opendrain(int slot, int enable);
+extern int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_on);
+
+extern int menelaus_set_vmem(unsigned int mV);
+extern int menelaus_set_vio(unsigned int mV);
+extern int menelaus_set_vmmc(unsigned int mV);
+extern int menelaus_set_vaux(unsigned int mV);
+extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
+extern int menelaus_set_slot_sel(int enable);
+extern int menelaus_get_slot_pin_states(void);
+extern int menelaus_set_vcore_sw(unsigned int mV);
+extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
+
+#define EN_VPLL_SLEEP	(1 << 7)
+#define EN_VMMC_SLEEP	(1 << 6)
+#define EN_VAUX_SLEEP	(1 << 5)
+#define EN_VIO_SLEEP	(1 << 4)
+#define EN_VMEM_SLEEP	(1 << 3)
+#define EN_DC3_SLEEP	(1 << 2)
+#define EN_DC2_SLEEP	(1 << 1)
+#define EN_VC_SLEEP	(1 << 0)
+
+extern int menelaus_set_regulator_sleep(int enable, u32 val);
+
+#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
+#define omap_has_menelaus()	1
+#else
+#define omap_has_menelaus()	0
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mmc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mmc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mmc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,157 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * Copyright (C) 2006 Nokia 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 __OMAP2_MMC_H
+#define __OMAP2_MMC_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mmc/host.h>
+
+#include <plat/board.h>
+
+#define OMAP15XX_NR_MMC		1
+#define OMAP16XX_NR_MMC		2
+#define OMAP1_MMC_SIZE		0x080
+#define OMAP1_MMC1_BASE		0xfffb7800
+#define OMAP1_MMC2_BASE		0xfffb7c00	/* omap16xx only */
+
+#define OMAP24XX_NR_MMC		2
+#define OMAP34XX_NR_MMC		3
+#define OMAP44XX_NR_MMC		5
+#define OMAP2420_MMC_SIZE	OMAP1_MMC_SIZE
+#define OMAP3_HSMMC_SIZE	0x200
+#define OMAP4_HSMMC_SIZE	0x1000
+#define OMAP2_MMC1_BASE		0x4809c000
+#define OMAP2_MMC2_BASE		0x480b4000
+#define OMAP3_MMC3_BASE		0x480ad000
+#define OMAP4_MMC4_BASE		0x480d1000
+#define OMAP4_MMC5_BASE		0x480d5000
+#define OMAP4_MMC_REG_OFFSET	0x100
+#define HSMMC5			(1 << 4)
+#define HSMMC4			(1 << 3)
+#define HSMMC3			(1 << 2)
+#define HSMMC2			(1 << 1)
+#define HSMMC1			(1 << 0)
+
+#define OMAP_MMC_MAX_SLOTS	2
+
+struct omap_mmc_platform_data {
+	/* back-link to device */
+	struct device *dev;
+
+	/* number of slots per controller */
+	unsigned nr_slots:2;
+
+	/* set if your board has components or wiring that limits the
+	 * maximum frequency on the MMC bus */
+	unsigned int max_freq;
+
+	/* switch the bus to a new slot */
+	int (* switch_slot)(struct device *dev, int slot);
+	/* initialize board-specific MMC functionality, can be NULL if
+	 * not supported */
+	int (* init)(struct device *dev);
+	void (* cleanup)(struct device *dev);
+	void (* shutdown)(struct device *dev);
+
+	/* To handle board related suspend/resume functionality for MMC */
+	int (*suspend)(struct device *dev, int slot);
+	int (*resume)(struct device *dev, int slot);
+
+	/* Return context loss count due to PM states changing */
+	int (*get_context_loss_count)(struct device *dev);
+
+	u64 dma_mask;
+
+	struct omap_mmc_slot_data {
+
+		/* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
+		 * 8 wire signaling is also optional, and is used with HSMMC
+		 */
+		u8 wires;
+
+		/*
+		 * nomux means "standard" muxing is wrong on this board, and
+		 * that board-specific code handled it before common init logic.
+		 */
+		unsigned nomux:1;
+
+		/* switch pin can be for card detect (default) or card cover */
+		unsigned cover:1;
+
+		/* use the internal clock */
+		unsigned internal_clock:1;
+
+		/* nonremovable e.g. eMMC */
+		unsigned nonremovable:1;
+
+		/* Try to sleep or power off when possible */
+		unsigned power_saving:1;
+
+		int switch_pin;			/* gpio (card detect) */
+		int gpio_wp;			/* gpio (write protect) */
+
+		int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
+		int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
+		int (* get_ro)(struct device *dev, int slot);
+		int (*set_sleep)(struct device *dev, int slot, int sleep,
+				 int vdd, int cardsleep);
+
+		/* return MMC cover switch state, can be NULL if not supported.
+		 *
+		 * possible return values:
+		 *   0 - closed
+		 *   1 - open
+		 */
+		int (* get_cover_state)(struct device *dev, int slot);
+
+		const char *name;
+		u32 ocr_mask;
+
+		/* Card detection IRQs */
+		int card_detect_irq;
+		int (* card_detect)(int irq);
+
+		unsigned int ban_openended:1;
+
+	} slots[OMAP_MMC_MAX_SLOTS];
+};
+
+/* called from board-specific card detection service routine */
+extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+
+#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+	defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+				int nr_controllers);
+void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+				int nr_controllers);
+int omap_mmc_add(const char *name, int id, unsigned long base,
+				unsigned long size, unsigned int irq,
+				struct omap_mmc_platform_data *data);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+				int nr_controllers)
+{
+}
+static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+				int nr_controllers)
+{
+}
+static inline int omap_mmc_add(const char *name, int id, unsigned long base,
+				unsigned long size, unsigned int irq,
+				struct omap_mmc_platform_data *data)
+{
+	return 0;
+}
+
+#endif
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mux.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mux.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/mux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/mux.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,670 @@
+/*
+ * arch/arm/plat-omap/include/mach/mux.h
+ *
+ * Table of the Omap register configurations for the FUNC_MUX and
+ * PULL_DWN combinations.
+ *
+ * Copyright (C) 2004 - 2008 Texas Instruments Inc.
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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
+ *
+ * NOTE: Please use the following naming style for new pin entries.
+ *	 For example, W8_1610_MMC2_DAT0, where:
+ *	 - W8	     = ball
+ *	 - 1610	     = 1510 or 1610, none if common for both 1510 and 1610
+ *	 - MMC2_DAT0 = function
+ */
+
+#ifndef __ASM_ARCH_MUX_H
+#define __ASM_ARCH_MUX_H
+
+#define PU_PD_SEL_NA		0	/* No pu_pd reg available */
+#define PULL_DWN_CTRL_NA	0	/* No pull-down control needed */
+
+#ifdef	CONFIG_OMAP_MUX_DEBUG
+#define MUX_REG(reg, mode_offset, mode) .mux_reg_name = "FUNC_MUX_CTRL_"#reg, \
+					.mux_reg = FUNC_MUX_CTRL_##reg, \
+					.mask_offset = mode_offset, \
+					.mask = mode,
+
+#define PULL_REG(reg, bit, status)	.pull_name = "PULL_DWN_CTRL_"#reg, \
+					.pull_reg = PULL_DWN_CTRL_##reg, \
+					.pull_bit = bit, \
+					.pull_val = status,
+
+#define PU_PD_REG(reg, status)		.pu_pd_name = "PU_PD_SEL_"#reg, \
+					.pu_pd_reg = PU_PD_SEL_##reg, \
+					.pu_pd_val = status,
+
+#define MUX_REG_7XX(reg, mode_offset, mode) .mux_reg_name = "OMAP7XX_IO_CONF_"#reg, \
+					.mux_reg = OMAP7XX_IO_CONF_##reg, \
+					.mask_offset = mode_offset, \
+					.mask = mode,
+
+#define PULL_REG_7XX(reg, bit, status)	.pull_name = "OMAP7XX_IO_CONF_"#reg, \
+					.pull_reg = OMAP7XX_IO_CONF_##reg, \
+					.pull_bit = bit, \
+					.pull_val = status,
+
+#else
+
+#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
+					.mask_offset = mode_offset, \
+					.mask = mode,
+
+#define PULL_REG(reg, bit, status)	.pull_reg = PULL_DWN_CTRL_##reg, \
+					.pull_bit = bit, \
+					.pull_val = status,
+
+#define PU_PD_REG(reg, status)		.pu_pd_reg = PU_PD_SEL_##reg, \
+					.pu_pd_val = status,
+
+#define MUX_REG_7XX(reg, mode_offset, mode) \
+					.mux_reg = OMAP7XX_IO_CONF_##reg, \
+					.mask_offset = mode_offset, \
+					.mask = mode,
+
+#define PULL_REG_7XX(reg, bit, status)	.pull_reg = OMAP7XX_IO_CONF_##reg, \
+					.pull_bit = bit, \
+					.pull_val = status,
+
+#endif /* CONFIG_OMAP_MUX_DEBUG */
+
+#define MUX_CFG(desc, mux_reg, mode_offset, mode,	\
+		pull_reg, pull_bit, pull_status,	\
+		pu_pd_reg, pu_pd_status, debug_status)	\
+{							\
+	.name =	 desc,					\
+	.debug = debug_status,				\
+	MUX_REG(mux_reg, mode_offset, mode)		\
+	PULL_REG(pull_reg, pull_bit, pull_status)	\
+	PU_PD_REG(pu_pd_reg, pu_pd_status)		\
+},
+
+
+/*
+ * OMAP730/850 has a slightly different config for the pin mux.
+ * - config regs are the OMAP7XX_IO_CONF_x regs (see omap730.h) regs and
+ *   not the FUNC_MUX_CTRL_x regs from hardware.h
+ * - for pull-up/down, only has one enable bit which is is in the same register
+ *   as mux config
+ */
+#define MUX_CFG_7XX(desc, mux_reg, mode_offset, mode,	\
+		   pull_bit, pull_status, debug_status)\
+{							\
+	.name =	 desc,					\
+	.debug = debug_status,				\
+	MUX_REG_7XX(mux_reg, mode_offset, mode)		\
+	PULL_REG_7XX(mux_reg, pull_bit, pull_status)	\
+	PU_PD_REG(NA, 0)		\
+},
+
+#define MUX_CFG_24XX(desc, reg_offset, mode,			\
+				pull_en, pull_mode, dbg)	\
+{								\
+	.name		= desc,					\
+	.debug		= dbg,					\
+	.mux_reg	= reg_offset,				\
+	.mask		= mode,					\
+	.pull_val	= pull_en,				\
+	.pu_pd_val	= pull_mode,				\
+},
+
+/* 24xx/34xx mux bit defines */
+#define OMAP2_PULL_ENA		(1 << 3)
+#define OMAP2_PULL_UP		(1 << 4)
+#define OMAP2_ALTELECTRICALSEL	(1 << 5)
+
+struct pin_config {
+	char 			*name;
+	const unsigned int 	mux_reg;
+	unsigned char		debug;
+
+#if	defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
+	const unsigned char mask_offset;
+	const unsigned char mask;
+
+	const char *pull_name;
+	const unsigned int pull_reg;
+	const unsigned char pull_val;
+	const unsigned char pull_bit;
+
+	const char *pu_pd_name;
+	const unsigned int pu_pd_reg;
+	const unsigned char pu_pd_val;
+#endif
+
+#if	defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
+	const char *mux_reg_name;
+#endif
+
+};
+
+enum omap7xx_index {
+	/* OMAP 730 keyboard */
+	E2_7XX_KBR0,
+	J7_7XX_KBR1,
+	E1_7XX_KBR2,
+	F3_7XX_KBR3,
+	D2_7XX_KBR4,
+	C2_7XX_KBC0,
+	D3_7XX_KBC1,
+	E4_7XX_KBC2,
+	F4_7XX_KBC3,
+	E3_7XX_KBC4,
+
+	/* USB */
+	AA17_7XX_USB_DM,
+	W16_7XX_USB_PU_EN,
+	W17_7XX_USB_VBUSI,
+	W18_7XX_USB_DMCK_OUT,
+	W19_7XX_USB_DCRST,
+
+	/* MMC */
+	MMC_7XX_CMD,
+	MMC_7XX_CLK,
+	MMC_7XX_DAT0,
+
+	/* I2C */
+	I2C_7XX_SCL,
+	I2C_7XX_SDA,
+
+	/* SPI */
+	SPI_7XX_1,
+	SPI_7XX_2,
+	SPI_7XX_3,
+	SPI_7XX_4,
+	SPI_7XX_5,
+	SPI_7XX_6,
+};
+
+enum omap1xxx_index {
+	/* UART1 (BT_UART_GATING)*/
+	UART1_TX = 0,
+	UART1_RTS,
+
+	/* UART2 (COM_UART_GATING)*/
+	UART2_TX,
+	UART2_RX,
+	UART2_CTS,
+	UART2_RTS,
+
+	/* UART3 (GIGA_UART_GATING) */
+	UART3_TX,
+	UART3_RX,
+	UART3_CTS,
+	UART3_RTS,
+	UART3_CLKREQ,
+	UART3_BCLK,	/* 12MHz clock out */
+	Y15_1610_UART3_RTS,
+
+	/* PWT & PWL */
+	PWT,
+	PWL,
+
+	/* USB master generic */
+	R18_USB_VBUS,
+	R18_1510_USB_GPIO0,
+	W4_USB_PUEN,
+	W4_USB_CLKO,
+	W4_USB_HIGHZ,
+	W4_GPIO58,
+
+	/* USB1 master */
+	USB1_SUSP,
+	USB1_SEO,
+	W13_1610_USB1_SE0,
+	USB1_TXEN,
+	USB1_TXD,
+	USB1_VP,
+	USB1_VM,
+	USB1_RCV,
+	USB1_SPEED,
+	R13_1610_USB1_SPEED,
+	R13_1710_USB1_SE0,
+
+	/* USB2 master */
+	USB2_SUSP,
+	USB2_VP,
+	USB2_TXEN,
+	USB2_VM,
+	USB2_RCV,
+	USB2_SEO,
+	USB2_TXD,
+
+	/* OMAP-1510 GPIO */
+	R18_1510_GPIO0,
+	R19_1510_GPIO1,
+	M14_1510_GPIO2,
+
+	/* OMAP1610 GPIO */
+	P18_1610_GPIO3,
+	Y15_1610_GPIO17,
+
+	/* OMAP-1710 GPIO */
+	R18_1710_GPIO0,
+	V2_1710_GPIO10,
+	N21_1710_GPIO14,
+	W15_1710_GPIO40,
+
+	/* MPUIO */
+	MPUIO2,
+	N15_1610_MPUIO2,
+	MPUIO4,
+	MPUIO5,
+	T20_1610_MPUIO5,
+	W11_1610_MPUIO6,
+	V10_1610_MPUIO7,
+	W11_1610_MPUIO9,
+	V10_1610_MPUIO10,
+	W10_1610_MPUIO11,
+	E20_1610_MPUIO13,
+	U20_1610_MPUIO14,
+	E19_1610_MPUIO15,
+
+	/* MCBSP2 */
+	MCBSP2_CLKR,
+	MCBSP2_CLKX,
+	MCBSP2_DR,
+	MCBSP2_DX,
+	MCBSP2_FSR,
+	MCBSP2_FSX,
+
+	/* MCBSP3 */
+	MCBSP3_CLKX,
+
+	/* Misc ballouts */
+	BALLOUT_V8_ARMIO3,
+	N20_HDQ,
+
+	/* OMAP-1610 MMC2 */
+	W8_1610_MMC2_DAT0,
+	V8_1610_MMC2_DAT1,
+	W15_1610_MMC2_DAT2,
+	R10_1610_MMC2_DAT3,
+	Y10_1610_MMC2_CLK,
+	Y8_1610_MMC2_CMD,
+	V9_1610_MMC2_CMDDIR,
+	V5_1610_MMC2_DATDIR0,
+	W19_1610_MMC2_DATDIR1,
+	R18_1610_MMC2_CLKIN,
+
+	/* OMAP-1610 External Trace Interface */
+	M19_1610_ETM_PSTAT0,
+	L15_1610_ETM_PSTAT1,
+	L18_1610_ETM_PSTAT2,
+	L19_1610_ETM_D0,
+	J19_1610_ETM_D6,
+	J18_1610_ETM_D7,
+
+	/* OMAP16XX GPIO */
+	P20_1610_GPIO4,
+	V9_1610_GPIO7,
+	W8_1610_GPIO9,
+	N20_1610_GPIO11,
+	N19_1610_GPIO13,
+	P10_1610_GPIO22,
+	V5_1610_GPIO24,
+	AA20_1610_GPIO_41,
+	W19_1610_GPIO48,
+	M7_1610_GPIO62,
+	V14_16XX_GPIO37,
+	R9_16XX_GPIO18,
+	L14_16XX_GPIO49,
+
+	/* OMAP-1610 uWire */
+	V19_1610_UWIRE_SCLK,
+	U18_1610_UWIRE_SDI,
+	W21_1610_UWIRE_SDO,
+	N14_1610_UWIRE_CS0,
+	P15_1610_UWIRE_CS3,
+	N15_1610_UWIRE_CS1,
+
+	/* OMAP-1610 SPI */
+	U19_1610_SPIF_SCK,
+	U18_1610_SPIF_DIN,
+	P20_1610_SPIF_DIN,
+	W21_1610_SPIF_DOUT,
+	R18_1610_SPIF_DOUT,
+	N14_1610_SPIF_CS0,
+	N15_1610_SPIF_CS1,
+	T19_1610_SPIF_CS2,
+	P15_1610_SPIF_CS3,
+
+	/* OMAP-1610 Flash */
+	L3_1610_FLASH_CS2B_OE,
+	M8_1610_FLASH_CS2B_WE,
+
+	/* First MMC */
+	MMC_CMD,
+	MMC_DAT1,
+	MMC_DAT2,
+	MMC_DAT0,
+	MMC_CLK,
+	MMC_DAT3,
+
+	/* OMAP-1710 MMC CMDDIR and DATDIR0 */
+	M15_1710_MMC_CLKI,
+	P19_1710_MMC_CMDDIR,
+	P20_1710_MMC_DATDIR0,
+
+	/* OMAP-1610 USB0 alternate pin configuration */
+	W9_USB0_TXEN,
+	AA9_USB0_VP,
+	Y5_USB0_RCV,
+	R9_USB0_VM,
+	V6_USB0_TXD,
+	W5_USB0_SE0,
+	V9_USB0_SPEED,
+	V9_USB0_SUSP,
+
+	/* USB2 */
+	W9_USB2_TXEN,
+	AA9_USB2_VP,
+	Y5_USB2_RCV,
+	R9_USB2_VM,
+	V6_USB2_TXD,
+	W5_USB2_SE0,
+
+	/* 16XX UART */
+	R13_1610_UART1_TX,
+	V14_16XX_UART1_RX,
+	R14_1610_UART1_CTS,
+	AA15_1610_UART1_RTS,
+	R9_16XX_UART2_RX,
+	L14_16XX_UART3_RX,
+
+	/* I2C OMAP-1610 */
+	I2C_SCL,
+	I2C_SDA,
+
+	/* Keypad */
+	F18_1610_KBC0,
+	D20_1610_KBC1,
+	D19_1610_KBC2,
+	E18_1610_KBC3,
+	C21_1610_KBC4,
+	G18_1610_KBR0,
+	F19_1610_KBR1,
+	H14_1610_KBR2,
+	E20_1610_KBR3,
+	E19_1610_KBR4,
+	N19_1610_KBR5,
+
+	/* Power management */
+	T20_1610_LOW_PWR,
+
+	/* MCLK Settings */
+	V5_1710_MCLK_ON,
+	V5_1710_MCLK_OFF,
+	R10_1610_MCLK_ON,
+	R10_1610_MCLK_OFF,
+
+	/* CompactFlash controller */
+	P11_1610_CF_CD2,
+	R11_1610_CF_IOIS16,
+	V10_1610_CF_IREQ,
+	W10_1610_CF_RESET,
+	W11_1610_CF_CD1,
+
+	/* parallel camera */
+	J15_1610_CAM_LCLK,
+	J18_1610_CAM_D7,
+	J19_1610_CAM_D6,
+	J14_1610_CAM_D5,
+	K18_1610_CAM_D4,
+	K19_1610_CAM_D3,
+	K15_1610_CAM_D2,
+	K14_1610_CAM_D1,
+	L19_1610_CAM_D0,
+	L18_1610_CAM_VS,
+	L15_1610_CAM_HS,
+	M19_1610_CAM_RSTZ,
+	Y15_1610_CAM_OUTCLK,
+
+	/* serial camera */
+	H19_1610_CAM_EXCLK,
+	Y12_1610_CCP_CLKP,
+	W13_1610_CCP_CLKM,
+	W14_1610_CCP_DATAP,
+	Y14_1610_CCP_DATAM,
+
+};
+
+enum omap24xx_index {
+	/* 24xx I2C */
+	M19_24XX_I2C1_SCL,
+	L15_24XX_I2C1_SDA,
+	J15_24XX_I2C2_SCL,
+	H19_24XX_I2C2_SDA,
+
+	/* 24xx Menelaus interrupt */
+	W19_24XX_SYS_NIRQ,
+
+	/* 24xx clock */
+	W14_24XX_SYS_CLKOUT,
+
+	/* 24xx GPMC chipselects, wait pin monitoring */
+	E2_GPMC_NCS2,
+	L2_GPMC_NCS7,
+	L3_GPMC_WAIT0,
+	N7_GPMC_WAIT1,
+	M1_GPMC_WAIT2,
+	P1_GPMC_WAIT3,
+
+	/* 242X McBSP */
+	Y15_24XX_MCBSP2_CLKX,
+	R14_24XX_MCBSP2_FSX,
+	W15_24XX_MCBSP2_DR,
+	V15_24XX_MCBSP2_DX,
+
+	/* 24xx GPIO */
+	M21_242X_GPIO11,
+	P21_242X_GPIO12,
+	AA10_242X_GPIO13,
+	AA6_242X_GPIO14,
+	AA4_242X_GPIO15,
+	Y11_242X_GPIO16,
+	AA12_242X_GPIO17,
+	AA8_242X_GPIO58,
+	Y20_24XX_GPIO60,
+	W4__24XX_GPIO74,
+	N15_24XX_GPIO85,
+	M15_24XX_GPIO92,
+	P20_24XX_GPIO93,
+	P18_24XX_GPIO95,
+	M18_24XX_GPIO96,
+	L14_24XX_GPIO97,
+	J15_24XX_GPIO99,
+	V14_24XX_GPIO117,
+	P14_24XX_GPIO125,
+
+	/* 242x DBG GPIO */
+	V4_242X_GPIO49,
+	W2_242X_GPIO50,
+	U4_242X_GPIO51,
+	V3_242X_GPIO52,
+	V2_242X_GPIO53,
+	V6_242X_GPIO53,
+	T4_242X_GPIO54,
+	Y4_242X_GPIO54,
+	T3_242X_GPIO55,
+	U2_242X_GPIO56,
+
+	/* 24xx external DMA requests */
+	AA10_242X_DMAREQ0,
+	AA6_242X_DMAREQ1,
+	E4_242X_DMAREQ2,
+	G4_242X_DMAREQ3,
+	D3_242X_DMAREQ4,
+	E3_242X_DMAREQ5,
+
+	/* UART3 */
+	K15_24XX_UART3_TX,
+	K14_24XX_UART3_RX,
+
+	/* MMC/SDIO */
+	G19_24XX_MMC_CLKO,
+	H18_24XX_MMC_CMD,
+	F20_24XX_MMC_DAT0,
+	H14_24XX_MMC_DAT1,
+	E19_24XX_MMC_DAT2,
+	D19_24XX_MMC_DAT3,
+	F19_24XX_MMC_DAT_DIR0,
+	E20_24XX_MMC_DAT_DIR1,
+	F18_24XX_MMC_DAT_DIR2,
+	E18_24XX_MMC_DAT_DIR3,
+	G18_24XX_MMC_CMD_DIR,
+	H15_24XX_MMC_CLKI,
+
+	/* Full speed USB */
+	J20_24XX_USB0_PUEN,
+	J19_24XX_USB0_VP,
+	K20_24XX_USB0_VM,
+	J18_24XX_USB0_RCV,
+	K19_24XX_USB0_TXEN,
+	J14_24XX_USB0_SE0,
+	K18_24XX_USB0_DAT,
+
+	N14_24XX_USB1_SE0,
+	W12_24XX_USB1_SE0,
+	P15_24XX_USB1_DAT,
+	R13_24XX_USB1_DAT,
+	W20_24XX_USB1_TXEN,
+	P13_24XX_USB1_TXEN,
+	V19_24XX_USB1_RCV,
+	V12_24XX_USB1_RCV,
+
+	AA10_24XX_USB2_SE0,
+	Y11_24XX_USB2_DAT,
+	AA12_24XX_USB2_TXEN,
+	AA6_24XX_USB2_RCV,
+	AA4_24XX_USB2_TLLSE0,
+
+	/* Keypad GPIO*/
+	T19_24XX_KBR0,
+	R19_24XX_KBR1,
+	V18_24XX_KBR2,
+	M21_24XX_KBR3,
+	E5__24XX_KBR4,
+	M18_24XX_KBR5,
+	R20_24XX_KBC0,
+	M14_24XX_KBC1,
+	H19_24XX_KBC2,
+	V17_24XX_KBC3,
+	P21_24XX_KBC4,
+	L14_24XX_KBC5,
+	N19_24XX_KBC6,
+
+	/* 24xx Menelaus Keypad GPIO */
+	B3__24XX_KBR5,
+	AA4_24XX_KBC2,
+	B13_24XX_KBC6,
+
+	/* 2430 USB */
+	AD9_2430_USB0_PUEN,
+	Y11_2430_USB0_VP,
+	AD7_2430_USB0_VM,
+	AE7_2430_USB0_RCV,
+	AD4_2430_USB0_TXEN,
+	AF9_2430_USB0_SE0,
+	AE6_2430_USB0_DAT,
+	AD24_2430_USB1_SE0,
+	AB24_2430_USB1_RCV,
+	Y25_2430_USB1_TXEN,
+	AA26_2430_USB1_DAT,
+
+	/* 2430 HS-USB */
+	AD9_2430_USB0HS_DATA3,
+	Y11_2430_USB0HS_DATA4,
+	AD7_2430_USB0HS_DATA5,
+	AE7_2430_USB0HS_DATA6,
+	AD4_2430_USB0HS_DATA2,
+	AF9_2430_USB0HS_DATA0,
+	AE6_2430_USB0HS_DATA1,
+	AE8_2430_USB0HS_CLK,
+	AD8_2430_USB0HS_DIR,
+	AE5_2430_USB0HS_STP,
+	AE9_2430_USB0HS_NXT,
+	AC7_2430_USB0HS_DATA7,
+
+	/* 2430 McBSP */
+	AD6_2430_MCBSP_CLKS,
+
+	AB2_2430_MCBSP1_CLKR,
+	AD5_2430_MCBSP1_FSR,
+	AA1_2430_MCBSP1_DX,
+	AF3_2430_MCBSP1_DR,
+	AB3_2430_MCBSP1_FSX,
+	Y9_2430_MCBSP1_CLKX,
+
+	AC10_2430_MCBSP2_FSX,
+	AD16_2430_MCBSP2_CLX,
+	AE13_2430_MCBSP2_DX,
+	AD13_2430_MCBSP2_DR,
+	AC10_2430_MCBSP2_FSX_OFF,
+	AD16_2430_MCBSP2_CLX_OFF,
+	AE13_2430_MCBSP2_DX_OFF,
+	AD13_2430_MCBSP2_DR_OFF,
+
+	AC9_2430_MCBSP3_CLKX,
+	AE4_2430_MCBSP3_FSX,
+	AE2_2430_MCBSP3_DR,
+	AF4_2430_MCBSP3_DX,
+
+	N3_2430_MCBSP4_CLKX,
+	AD23_2430_MCBSP4_DR,
+	AB25_2430_MCBSP4_DX,
+	AC25_2430_MCBSP4_FSX,
+
+	AE16_2430_MCBSP5_CLKX,
+	AF12_2430_MCBSP5_FSX,
+	K7_2430_MCBSP5_DX,
+	M1_2430_MCBSP5_DR,
+
+	/* 2430 McSPI*/
+	Y18_2430_MCSPI1_CLK,
+	AD15_2430_MCSPI1_SIMO,
+	AE17_2430_MCSPI1_SOMI,
+	U1_2430_MCSPI1_CS0,
+
+	/* Touchscreen GPIO */
+	AF19_2430_GPIO_85,
+
+};
+
+struct omap_mux_cfg {
+	struct pin_config	*pins;
+	unsigned long		size;
+	int			(*cfg_reg)(const struct pin_config *cfg);
+};
+
+#ifdef	CONFIG_OMAP_MUX
+/* setup pin muxing in Linux */
+extern int omap1_mux_init(void);
+extern int omap_mux_register(struct omap_mux_cfg *);
+extern int omap_cfg_reg(unsigned long reg_cfg);
+#else
+/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
+static inline int omap1_mux_init(void) { return 0; }
+static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
+#endif
+
+extern int omap2_mux_init(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-omap/include/mach/nand.h
+ *
+ * Copyright (C) 2006 Micron Technology 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/mtd/partitions.h>
+
+struct omap_nand_platform_data {
+	unsigned int		options;
+	int			cs;
+	int			gpio_irq;
+	struct mtd_partition	*parts;
+	int			nr_parts;
+	int			(*nand_setup)(void __iomem *);
+	int			(*dev_ready)(struct omap_nand_platform_data *);
+	int			dma_channel;
+	void __iomem		*gpmc_cs_baseaddr;
+	void __iomem		*gpmc_baseaddr;
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap1510.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap1510.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap1510.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap1510.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,50 @@
+/* arch/arm/plat-omap/include/mach/omap1510.h
+ *
+ * Hardware definitions for TI OMAP1510 processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP15XX_H
+#define __ASM_ARCH_OMAP15XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP1510_DSP_BASE	0xE0000000
+#define OMAP1510_DSP_SIZE	0x28000
+#define OMAP1510_DSP_START	0xE0000000
+
+#define OMAP1510_DSPREG_BASE	0xE1000000
+#define OMAP1510_DSPREG_SIZE	SZ_128K
+#define OMAP1510_DSPREG_START	0xE1000000
+
+#define OMAP1510_DSP_MMU_BASE	(0xfffed200)
+
+#endif /*  __ASM_ARCH_OMAP15XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap16xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,202 @@
+/* arch/arm/plat-omap/include/mach/omap16xx.h
+ *
+ * Hardware definitions for TI OMAP1610/5912/1710 processors.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP16XX_H
+#define __ASM_ARCH_OMAP16XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP16XX_DSP_BASE	0xE0000000
+#define OMAP16XX_DSP_SIZE	0x28000
+#define OMAP16XX_DSP_START	0xE0000000
+
+#define OMAP16XX_DSPREG_BASE	0xE1000000
+#define OMAP16XX_DSPREG_SIZE	SZ_128K
+#define OMAP16XX_DSPREG_START	0xE1000000
+
+#define OMAP16XX_SEC_BASE	0xFFFE4000
+#define OMAP16XX_SEC_DES	(OMAP16XX_SEC_BASE + 0x0000)
+#define OMAP16XX_SEC_SHA1MD5	(OMAP16XX_SEC_BASE + 0x0800)
+#define OMAP16XX_SEC_RNG	(OMAP16XX_SEC_BASE + 0x1000)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE		(0xfffe0000)
+#define OMAP_IH2_1_BASE		(0xfffe0100)
+#define OMAP_IH2_2_BASE		(0xfffe0200)
+#define OMAP_IH2_3_BASE		(0xfffe0300)
+
+#define OMAP_IH2_0_ITR		(OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR		(OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ	(OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ	(OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL	(OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0		(OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR		(OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR		(OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR		(OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ	(OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ	(OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL	(OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1		(OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR		(OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR		(OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR		(OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ	(OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ	(OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL	(OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2		(OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR		(OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR		(OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR		(OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ	(OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ	(OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL	(OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3		(OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR		(OMAP_IH2_3_BASE + 0x9c)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP16XX_ARM_IDLECT3	(CLKGEN_REG_BASE + 0x24)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pin configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV6	(1 << 8)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV7	(1 << 9)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV8	(1 << 10)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV9	(1 << 11)
+#define OMAP16XX_SUBLVDS_CONF_VALID	(1 << 13)
+
+/*
+ * ----------------------------------------------------------------------------
+ * System control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP1610_RESET_CONTROL  0xfffe1140
+
+/*
+ * ---------------------------------------------------------------------------
+ * TIPB bus interface
+ * ---------------------------------------------------------------------------
+ */
+#define TIPB_SWITCH_BASE		 (0xfffbc800)
+#define OMAP16XX_MMCSD2_SSW_MPU_CONF	(TIPB_SWITCH_BASE + 0x160)
+
+/* UART3 Registers Mapping through MPU bus */
+#define UART3_RHR               (OMAP_UART3_BASE + 0)
+#define UART3_THR               (OMAP_UART3_BASE + 0)
+#define UART3_DLL               (OMAP_UART3_BASE + 0)
+#define UART3_IER               (OMAP_UART3_BASE + 4)
+#define UART3_DLH               (OMAP_UART3_BASE + 4)
+#define UART3_IIR               (OMAP_UART3_BASE + 8)
+#define UART3_FCR               (OMAP_UART3_BASE + 8)
+#define UART3_EFR               (OMAP_UART3_BASE + 8)
+#define UART3_LCR               (OMAP_UART3_BASE + 0x0C)
+#define UART3_MCR               (OMAP_UART3_BASE + 0x10)
+#define UART3_XON1_ADDR1        (OMAP_UART3_BASE + 0x10)
+#define UART3_XON2_ADDR2        (OMAP_UART3_BASE + 0x14)
+#define UART3_LSR               (OMAP_UART3_BASE + 0x14)
+#define UART3_TCR               (OMAP_UART3_BASE + 0x18)
+#define UART3_MSR               (OMAP_UART3_BASE + 0x18)
+#define UART3_XOFF1             (OMAP_UART3_BASE + 0x18)
+#define UART3_XOFF2             (OMAP_UART3_BASE + 0x1C)
+#define UART3_SPR               (OMAP_UART3_BASE + 0x1C)
+#define UART3_TLR               (OMAP_UART3_BASE + 0x1C)
+#define UART3_MDR1              (OMAP_UART3_BASE + 0x20)
+#define UART3_MDR2              (OMAP_UART3_BASE + 0x24)
+#define UART3_SFLSR             (OMAP_UART3_BASE + 0x28)
+#define UART3_TXFLL             (OMAP_UART3_BASE + 0x28)
+#define UART3_RESUME            (OMAP_UART3_BASE + 0x2C)
+#define UART3_TXFLH             (OMAP_UART3_BASE + 0x2C)
+#define UART3_SFREGL            (OMAP_UART3_BASE + 0x30)
+#define UART3_RXFLL             (OMAP_UART3_BASE + 0x30)
+#define UART3_SFREGH            (OMAP_UART3_BASE + 0x34)
+#define UART3_RXFLH             (OMAP_UART3_BASE + 0x34)
+#define UART3_BLR               (OMAP_UART3_BASE + 0x38)
+#define UART3_ACREG             (OMAP_UART3_BASE + 0x3C)
+#define UART3_DIV16             (OMAP_UART3_BASE + 0x3C)
+#define UART3_SCR               (OMAP_UART3_BASE + 0x40)
+#define UART3_SSR               (OMAP_UART3_BASE + 0x44)
+#define UART3_EBLR              (OMAP_UART3_BASE + 0x48)
+#define UART3_OSC_12M_SEL       (OMAP_UART3_BASE + 0x4C)
+#define UART3_MVR               (OMAP_UART3_BASE + 0x50)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Watchdog timer
+ * ---------------------------------------------------------------------------
+ */
+
+/* 32-bit Watchdog timer in OMAP 16XX */
+#define OMAP_16XX_WATCHDOG_BASE        (0xfffeb000)
+#define OMAP_16XX_WIDR         (OMAP_16XX_WATCHDOG_BASE + 0x00)
+#define OMAP_16XX_WD_SYSCONFIG (OMAP_16XX_WATCHDOG_BASE + 0x10)
+#define OMAP_16XX_WD_SYSSTATUS (OMAP_16XX_WATCHDOG_BASE + 0x14)
+#define OMAP_16XX_WCLR         (OMAP_16XX_WATCHDOG_BASE + 0x24)
+#define OMAP_16XX_WCRR         (OMAP_16XX_WATCHDOG_BASE + 0x28)
+#define OMAP_16XX_WLDR         (OMAP_16XX_WATCHDOG_BASE + 0x2c)
+#define OMAP_16XX_WTGR         (OMAP_16XX_WATCHDOG_BASE + 0x30)
+#define OMAP_16XX_WWPS         (OMAP_16XX_WATCHDOG_BASE + 0x34)
+#define OMAP_16XX_WSPR         (OMAP_16XX_WATCHDOG_BASE + 0x48)
+
+#define WCLR_PRE_SHIFT         5
+#define WCLR_PTV_SHIFT         2
+
+#define WWPS_W_PEND_WSPR       (1 << 4)
+#define WWPS_W_PEND_WTGR       (1 << 3)
+#define WWPS_W_PEND_WLDR       (1 << 2)
+#define WWPS_W_PEND_WCRR       (1 << 1)
+#define WWPS_W_PEND_WCLR       (1 << 0)
+
+#define WSPR_ENABLE_0          (0x0000bbbb)
+#define WSPR_ENABLE_1          (0x00004444)
+#define WSPR_DISABLE_0         (0x0000aaaa)
+#define WSPR_DISABLE_1         (0x00005555)
+
+#define OMAP16XX_DSP_MMU_BASE	(0xfffed200)
+#define OMAP16XX_MAILBOX_BASE	(0xfffcf000)
+
+#endif /*  __ASM_ARCH_OMAP16XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap24xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap24xx.h
+ *
+ * This file contains the processor specific definitions
+ * of the TI OMAP24XX.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ * Copyright (C) 2007 Nokia 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
+ *
+ */
+
+#ifndef __ASM_ARCH_OMAP24XX_H
+#define __ASM_ARCH_OMAP24XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers. Note also that some of these defines are needed
+ * for omap1 to compile without adding ifdefs.
+ */
+
+#define L4_24XX_BASE		0x48000000
+#define L4_WK_243X_BASE		0x49000000
+#define L3_24XX_BASE		0x68000000
+
+/* interrupt controller */
+#define OMAP24XX_IC_BASE	(L4_24XX_BASE + 0xfe000)
+#define OMAP24XX_IVA_INTC_BASE	0x40000000
+
+#define OMAP2420_CTRL_BASE	L4_24XX_BASE
+#define OMAP2420_32KSYNCT_BASE	(L4_24XX_BASE + 0x4000)
+#define OMAP2420_PRCM_BASE	(L4_24XX_BASE + 0x8000)
+#define OMAP2420_CM_BASE	(L4_24XX_BASE + 0x8000)
+#define OMAP2420_PRM_BASE	OMAP2420_CM_BASE
+#define OMAP2420_SDRC_BASE	(L3_24XX_BASE + 0x9000)
+#define OMAP2420_SMS_BASE	0x68008000
+#define OMAP2420_GPMC_BASE	0x6800a000
+
+#define OMAP2430_32KSYNCT_BASE	(L4_WK_243X_BASE + 0x20000)
+#define OMAP2430_PRCM_BASE	(L4_WK_243X_BASE + 0x6000)
+#define OMAP2430_CM_BASE	(L4_WK_243X_BASE + 0x6000)
+#define OMAP2430_PRM_BASE	OMAP2430_CM_BASE
+
+#define OMAP243X_SMS_BASE	0x6C000000
+#define OMAP243X_SDRC_BASE	0x6D000000
+#define OMAP243X_GPMC_BASE	0x6E000000
+#define OMAP243X_SCM_BASE	(L4_WK_243X_BASE + 0x2000)
+#define OMAP243X_CTRL_BASE	OMAP243X_SCM_BASE
+#define OMAP243X_HS_BASE	(L4_24XX_BASE + 0x000ac000)
+
+/* DSP SS */
+#define OMAP2420_DSP_BASE	0x58000000
+#define OMAP2420_DSP_MEM_BASE	(OMAP2420_DSP_BASE + 0x0)
+#define OMAP2420_DSP_IPI_BASE	(OMAP2420_DSP_BASE + 0x1000000)
+#define OMAP2420_DSP_MMU_BASE	(OMAP2420_DSP_BASE + 0x2000000)
+
+#define OMAP243X_DSP_BASE	0x5C000000
+#define OMAP243X_DSP_MEM_BASE	(OMAP243X_DSP_BASE + 0x0)
+#define OMAP243X_DSP_MMU_BASE	(OMAP243X_DSP_BASE + 0x1000000)
+
+/* Mailbox */
+#define OMAP24XX_MAILBOX_BASE	(L4_24XX_BASE + 0x94000)
+
+/* Camera */
+#define OMAP24XX_CAMERA_BASE	(L4_24XX_BASE + 0x52000)
+
+/* Security */
+#define OMAP24XX_SEC_BASE	(L4_24XX_BASE + 0xA0000)
+#define OMAP24XX_SEC_RNG_BASE	(OMAP24XX_SEC_BASE + 0x0000)
+#define OMAP24XX_SEC_DES_BASE	(OMAP24XX_SEC_BASE + 0x2000)
+#define OMAP24XX_SEC_SHA1MD5_BASE (OMAP24XX_SEC_BASE + 0x4000)
+#define OMAP24XX_SEC_AES_BASE	(OMAP24XX_SEC_BASE + 0x6000)
+#define OMAP24XX_SEC_PKA_BASE	(OMAP24XX_SEC_BASE + 0x8000)
+
+#endif /* __ASM_ARCH_OMAP24XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap34xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap34xx.h
+ *
+ * This file contains the processor specific definitions of the TI OMAP34XX.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ * Copyright (C) 2007 Nokia 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
+ */
+
+#ifndef __ASM_ARCH_OMAP34XX_H
+#define __ASM_ARCH_OMAP34XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+
+#define L4_34XX_BASE		0x48000000
+#define L4_WK_34XX_BASE		0x48300000
+#define L4_PER_34XX_BASE	0x49000000
+#define L4_EMU_34XX_BASE	0x54000000
+#define L3_34XX_BASE		0x68000000
+
+#define OMAP3430_32KSYNCT_BASE	0x48320000
+#define OMAP3430_CM_BASE	0x48004800
+#define OMAP3430_PRM_BASE	0x48306800
+#define OMAP343X_SMS_BASE	0x6C000000
+#define OMAP343X_SDRC_BASE	0x6D000000
+#define OMAP34XX_GPMC_BASE	0x6E000000
+#define OMAP343X_SCM_BASE	0x48002000
+#define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
+
+#define OMAP34XX_IC_BASE	0x48200000
+
+#define OMAP3430_ISP_BASE		(L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_CBUFF_BASE		(OMAP3430_ISP_BASE + 0x0100)
+#define OMAP3430_ISP_CCP2_BASE		(OMAP3430_ISP_BASE + 0x0400)
+#define OMAP3430_ISP_CCDC_BASE		(OMAP3430_ISP_BASE + 0x0600)
+#define OMAP3430_ISP_HIST_BASE		(OMAP3430_ISP_BASE + 0x0A00)
+#define OMAP3430_ISP_H3A_BASE		(OMAP3430_ISP_BASE + 0x0C00)
+#define OMAP3430_ISP_PREV_BASE		(OMAP3430_ISP_BASE + 0x0E00)
+#define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
+#define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
+#define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_CSI2A_BASE		(OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSI2PHY_BASE	(OMAP3430_ISP_BASE + 0x1970)
+
+#define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
+#define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
+#define OMAP3430_ISP_CCP2_END		(OMAP3430_ISP_CCP2_BASE    + 0x1EF)
+#define OMAP3430_ISP_CCDC_END		(OMAP3430_ISP_CCDC_BASE    + 0x0A7)
+#define OMAP3430_ISP_HIST_END		(OMAP3430_ISP_HIST_BASE    + 0x047)
+#define OMAP3430_ISP_H3A_END		(OMAP3430_ISP_H3A_BASE     + 0x05F)
+#define OMAP3430_ISP_PREV_END		(OMAP3430_ISP_PREV_BASE    + 0x09F)
+#define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
+#define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
+#define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
+#define OMAP3430_ISP_CSI2A_END		(OMAP3430_ISP_CSI2A_BASE   + 0x16F)
+#define OMAP3430_ISP_CSI2PHY_END	(OMAP3430_ISP_CSI2PHY_BASE + 0x007)
+
+#define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
+#define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)
+#define OMAP34XX_UHH_CONFIG_BASE	(L4_34XX_BASE + 0x64000)
+#define OMAP34XX_OHCI_BASE	(L4_34XX_BASE + 0x64400)
+#define OMAP34XX_EHCI_BASE	(L4_34XX_BASE + 0x64800)
+#define OMAP34XX_SR1_BASE	0x480C9000
+#define OMAP34XX_SR2_BASE	0x480CB000
+
+#define OMAP34XX_MAILBOX_BASE		(L4_34XX_BASE + 0x94000)
+
+#endif /* __ASM_ARCH_OMAP34XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap44xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,48 @@
+/*:
+ * Address mappings and base address for OMAP4 interconnects
+ * and peripherals.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: 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.
+ */
+#ifndef __ASM_ARCH_OMAP44XX_H
+#define __ASM_ARCH_OMAP44XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+#define L4_44XX_BASE			0x4a000000
+#define L4_WK_44XX_BASE			0x4a300000
+#define L4_PER_44XX_BASE		0x48000000
+#define L4_EMU_44XX_BASE		0x54000000
+#define L3_44XX_BASE			0x44000000
+#define OMAP44XX_EMIF1_BASE		0x4c000000
+#define OMAP44XX_EMIF2_BASE		0x4d000000
+#define OMAP44XX_DMM_BASE		0x4e000000
+#define OMAP4430_32KSYNCT_BASE		0x4a304000
+#define OMAP4430_CM1_BASE		0x4a004000
+#define OMAP4430_CM_BASE		OMAP4430_CM1_BASE
+#define OMAP4430_CM2_BASE		0x4a008000
+#define OMAP4430_PRM_BASE		0x4a306000
+#define OMAP44XX_GPMC_BASE		0x50000000
+#define OMAP443X_SCM_BASE		0x4a002000
+#define OMAP443X_CTRL_BASE		OMAP443X_SCM_BASE
+#define OMAP44XX_IC_BASE		0x48200000
+#define OMAP44XX_IVA_INTC_BASE		0x40000000
+#define IRQ_SIR_IRQ			0x0040
+#define OMAP44XX_GIC_DIST_BASE		0x48241000
+#define OMAP44XX_GIC_CPU_BASE		0x48240100
+#define OMAP44XX_SCU_BASE		0x48240000
+#define OMAP44XX_LOCAL_TWD_BASE		0x48240600
+#define OMAP44XX_WKUPGEN_BASE		0x48281000
+
+#define OMAP44XX_MAILBOX_BASE		(L4_44XX_BASE + 0xF4000)
+
+#endif /* __ASM_ARCH_OMAP44XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap730.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap730.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap730.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap730.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+/* arch/arm/plat-omap/include/mach/omap730.h
+ *
+ * Hardware definitions for TI OMAP730 processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP730_H
+#define __ASM_ARCH_OMAP730_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP730_DSP_BASE	0xE0000000
+#define OMAP730_DSP_SIZE	0x50000
+#define OMAP730_DSP_START	0xE0000000
+
+#define OMAP730_DSPREG_BASE	0xE1000000
+#define OMAP730_DSPREG_SIZE	SZ_128K
+#define OMAP730_DSPREG_START	0xE1000000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_CONFIG_BASE	0xfffe1000
+#define OMAP730_IO_CONF_0	0xfffe1070
+#define OMAP730_IO_CONF_1	0xfffe1074
+#define OMAP730_IO_CONF_2	0xfffe1078
+#define OMAP730_IO_CONF_3	0xfffe107c
+#define OMAP730_IO_CONF_4	0xfffe1080
+#define OMAP730_IO_CONF_5	0xfffe1084
+#define OMAP730_IO_CONF_6	0xfffe1088
+#define OMAP730_IO_CONF_7	0xfffe108c
+#define OMAP730_IO_CONF_8	0xfffe1090
+#define OMAP730_IO_CONF_9	0xfffe1094
+#define OMAP730_IO_CONF_10	0xfffe1098
+#define OMAP730_IO_CONF_11	0xfffe109c
+#define OMAP730_IO_CONF_12	0xfffe10a0
+#define OMAP730_IO_CONF_13	0xfffe10a4
+
+#define OMAP730_MODE_1		0xfffe1010
+#define OMAP730_MODE_2		0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP730_MODE2_OFFSET	0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_FLASH_CFG_0	0xfffecc10
+#define OMAP730_FLASH_ACFG_0	0xfffecc50
+#define OMAP730_FLASH_CFG_1	0xfffecc14
+#define OMAP730_FLASH_ACFG_1	0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_ICR_BASE	0xfffbb800
+#define OMAP730_DSP_M_CTL	0xfffbb804
+#define OMAP730_DSP_MMU_BASE	0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_PCC_UPLD_CTRL_BASE	(0xfffe0900)
+#define OMAP730_PCC_UPLD_CTRL		(OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /*  __ASM_ARCH_OMAP730_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap7xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap7xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap7xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap7xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,107 @@
+/* arch/arm/plat-omap/include/mach/omap7xx.h
+ *
+ * Hardware definitions for TI OMAP7XX processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.com>
+ * Adapted for omap850 by Zebediah C. McClure <zmc@lurian.net>
+ * Adapted for omap7xx by Alistair Buxton <a.j.buxton@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.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP7XX_H
+#define __ASM_ARCH_OMAP7XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP7XX_DSP_BASE	0xE0000000
+#define OMAP7XX_DSP_SIZE	0x50000
+#define OMAP7XX_DSP_START	0xE0000000
+
+#define OMAP7XX_DSPREG_BASE	0xE1000000
+#define OMAP7XX_DSPREG_SIZE	SZ_128K
+#define OMAP7XX_DSPREG_START	0xE1000000
+
+#define OMAP7XX_SPI1_BASE	0xfffc0800
+#define OMAP7XX_SPI2_BASE	0xfffc1000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_CONFIG_BASE	0xfffe1000
+#define OMAP7XX_IO_CONF_0	0xfffe1070
+#define OMAP7XX_IO_CONF_1	0xfffe1074
+#define OMAP7XX_IO_CONF_2	0xfffe1078
+#define OMAP7XX_IO_CONF_3	0xfffe107c
+#define OMAP7XX_IO_CONF_4	0xfffe1080
+#define OMAP7XX_IO_CONF_5	0xfffe1084
+#define OMAP7XX_IO_CONF_6	0xfffe1088
+#define OMAP7XX_IO_CONF_7	0xfffe108c
+#define OMAP7XX_IO_CONF_8	0xfffe1090
+#define OMAP7XX_IO_CONF_9	0xfffe1094
+#define OMAP7XX_IO_CONF_10	0xfffe1098
+#define OMAP7XX_IO_CONF_11	0xfffe109c
+#define OMAP7XX_IO_CONF_12	0xfffe10a0
+#define OMAP7XX_IO_CONF_13	0xfffe10a4
+
+#define OMAP7XX_MODE_1		0xfffe1010
+#define OMAP7XX_MODE_2		0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP7XX_MODE2_OFFSET	0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_FLASH_CFG_0	0xfffecc10
+#define OMAP7XX_FLASH_ACFG_0	0xfffecc50
+#define OMAP7XX_FLASH_CFG_1	0xfffecc14
+#define OMAP7XX_FLASH_ACFG_1	0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_ICR_BASE	0xfffbb800
+#define OMAP7XX_DSP_M_CTL	0xfffbb804
+#define OMAP7XX_DSP_MMU_BASE	0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_PCC_UPLD_CTRL_BASE	(0xfffe0900)
+#define OMAP7XX_PCC_UPLD_CTRL		(OMAP7XX_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /*  __ASM_ARCH_OMAP7XX_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap850.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap850.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap850.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap850.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+/* arch/arm/plat-omap/include/mach/omap850.h
+ *
+ * Hardware definitions for TI OMAP850 processor.
+ *
+ * Derived from omap730.h by Zebediah C. McClure <zmc@lurian.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.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP850_H
+#define __ASM_ARCH_OMAP850_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP850_DSP_BASE	0xE0000000
+#define OMAP850_DSP_SIZE	0x50000
+#define OMAP850_DSP_START	0xE0000000
+
+#define OMAP850_DSPREG_BASE	0xE1000000
+#define OMAP850_DSPREG_SIZE	SZ_128K
+#define OMAP850_DSPREG_START	0xE1000000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_CONFIG_BASE	0xfffe1000
+#define OMAP850_IO_CONF_0	0xfffe1070
+#define OMAP850_IO_CONF_1	0xfffe1074
+#define OMAP850_IO_CONF_2	0xfffe1078
+#define OMAP850_IO_CONF_3	0xfffe107c
+#define OMAP850_IO_CONF_4	0xfffe1080
+#define OMAP850_IO_CONF_5	0xfffe1084
+#define OMAP850_IO_CONF_6	0xfffe1088
+#define OMAP850_IO_CONF_7	0xfffe108c
+#define OMAP850_IO_CONF_8	0xfffe1090
+#define OMAP850_IO_CONF_9	0xfffe1094
+#define OMAP850_IO_CONF_10	0xfffe1098
+#define OMAP850_IO_CONF_11	0xfffe109c
+#define OMAP850_IO_CONF_12	0xfffe10a0
+#define OMAP850_IO_CONF_13	0xfffe10a4
+
+#define OMAP850_MODE_1		0xfffe1010
+#define OMAP850_MODE_2		0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP850_MODE2_OFFSET	0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_FLASH_CFG_0	0xfffecc10
+#define OMAP850_FLASH_ACFG_0	0xfffecc50
+#define OMAP850_FLASH_CFG_1	0xfffecc14
+#define OMAP850_FLASH_ACFG_1	0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_ICR_BASE	0xfffbb800
+#define OMAP850_DSP_M_CTL	0xfffbb804
+#define OMAP850_DSP_MMU_BASE	0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_PCC_UPLD_CTRL_BASE	(0xfffe0900)
+#define OMAP850_PCC_UPLD_CTRL		(OMAP850_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /*  __ASM_ARCH_OMAP850_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap-alsa.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap-alsa.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap-alsa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap-alsa.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,123 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap-alsa.h
+ *
+ * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
+ *
+ * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Written by Daniel Petrini, David Cohen, Anderson Briglia
+ *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
+ *
+ * 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.
+ *
+ *  History
+ *  -------
+ *
+ *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
+ *  					original version based in sa1100 driver
+ *  					and omap oss driver.
+ */
+
+#ifndef __OMAP_ALSA_H
+#define __OMAP_ALSA_H
+
+#include <plat/dma.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <plat/mcbsp.h>
+#include <linux/platform_device.h>
+
+#define DMA_BUF_SIZE	(1024 * 8)
+
+/*
+ * Buffer management for alsa and dma
+ */
+struct audio_stream {
+	char *id;		/* identification string */
+	int stream_id;		/* numeric identification */
+	int dma_dev;		/* dma number of that device */
+	int *lch;		/* Chain of channels this stream is linked to */
+	char started;		/* to store if the chain was started or not */
+	int dma_q_head;		/* DMA Channel Q Head */
+	int dma_q_tail;		/* DMA Channel Q Tail */
+	char dma_q_count;	/* DMA Channel Q Count */
+	int active:1;		/* we are using this stream for transfer now */
+	int period;		/* current transfer period */
+	int periods;		/* current count of periods registerd in the DMA engine */
+	spinlock_t dma_lock;	/* for locking in DMA operations */
+	struct snd_pcm_substream *stream;	/* the pcm stream */
+	unsigned linked:1;	/* dma channels linked */
+	int offset;		/* store start position of the last period in the alsa buffer */
+	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
+	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
+};
+
+/*
+ * Alsa card structure for aic23
+ */
+struct snd_card_omap_codec {
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	long samplerate;
+	struct audio_stream s[2];	/* playback & capture */
+};
+
+/* Codec specific information and function pointers.
+ * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
+ * are responsible for defining the function pointers.
+ */
+struct omap_alsa_codec_config {
+	char 	*name;
+	struct	omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
+	struct	snd_pcm_hw_constraint_list *hw_constraints_rates;
+	struct	snd_pcm_hardware *snd_omap_alsa_playback;
+	struct	snd_pcm_hardware *snd_omap_alsa_capture;
+	void	(*codec_configure_dev)(void);
+	void	(*codec_set_samplerate)(long);
+	void	(*codec_clock_setup)(void);
+	int	(*codec_clock_on)(void);
+	int 	(*codec_clock_off)(void);
+	int	(*get_default_samplerate)(void);
+};
+
+/*********** Mixer function prototypes *************************/
+int snd_omap_mixer(struct snd_card_omap_codec *);
+void snd_omap_init_mixer(void);
+
+#ifdef CONFIG_PM
+void snd_omap_suspend_mixer(void);
+void snd_omap_resume_mixer(void);
+#endif
+
+int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
+int snd_omap_alsa_remove(struct platform_device *pdev);
+#ifdef CONFIG_PM
+int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
+int snd_omap_alsa_resume(struct platform_device *pdev);
+#else
+#define snd_omap_alsa_suspend	NULL
+#define snd_omap_alsa_resume	NULL
+#endif
+
+void callback_omap_alsa_sound_dma(void *);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap_device.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_device.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap_device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_device.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,143 @@
+/*
+ * omap_device headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Developed in collaboration with (alphabetical order): Benoit
+ * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
+ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
+ * Woodruff
+ *
+ * This 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.
+ *
+ * Eventually this type of functionality should either be
+ * a) implemented via arch-specific pointers in platform_device
+ * or
+ * b) implemented as a proper omap_bus/omap_device in Linux, no more
+ *    platform_device
+ *
+ * omap_device differs from omap_hwmod in that it includes external
+ * (e.g., board- and system-level) integration details.  omap_hwmod
+ * stores hardware data that is invariant for a given OMAP chip.
+ *
+ * To do:
+ * - GPIO integration
+ * - regulator integration
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <plat/omap_hwmod.h>
+
+/* omap_device._state values */
+#define OMAP_DEVICE_STATE_UNKNOWN	0
+#define OMAP_DEVICE_STATE_ENABLED	1
+#define OMAP_DEVICE_STATE_IDLE		2
+#define OMAP_DEVICE_STATE_SHUTDOWN	3
+
+/**
+ * struct omap_device - omap_device wrapper for platform_devices
+ * @pdev: platform_device
+ * @hwmods: (one .. many per omap_device)
+ * @hwmods_cnt: ARRAY_SIZE() of @hwmods
+ * @pm_lats: ptr to an omap_device_pm_latency table
+ * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
+ * @pm_lat_level: array index of the last odpl entry executed - -1 if never
+ * @dev_wakeup_lat: dev wakeup latency in nanoseconds
+ * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM
+ * @_state: one of OMAP_DEVICE_STATE_* (see above)
+ * @flags: device flags
+ *
+ * Integrates omap_hwmod data into Linux platform_device.
+ *
+ * Field names beginning with underscores are for the internal use of
+ * the omap_device code.
+ *
+ */
+struct omap_device {
+	struct platform_device		pdev;
+	struct omap_hwmod		**hwmods;
+	struct omap_device_pm_latency	*pm_lats;
+	u32				dev_wakeup_lat;
+	u32				_dev_wakeup_lat_limit;
+	u8				pm_lats_cnt;
+	s8				pm_lat_level;
+	u8				hwmods_cnt;
+	u8				_state;
+};
+
+/* Device driver interface (call via platform_data fn ptrs) */
+
+int omap_device_enable(struct platform_device *pdev);
+int omap_device_idle(struct platform_device *pdev);
+int omap_device_shutdown(struct platform_device *pdev);
+
+/* Core code interface */
+
+int omap_device_count_resources(struct omap_device *od);
+int omap_device_fill_resources(struct omap_device *od, struct resource *res);
+
+struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+				      struct omap_hwmod *oh, void *pdata,
+				      int pdata_len,
+				      struct omap_device_pm_latency *pm_lats,
+				      int pm_lats_cnt);
+
+struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+					 struct omap_hwmod **oh, int oh_cnt,
+					 void *pdata, int pdata_len,
+					 struct omap_device_pm_latency *pm_lats,
+					 int pm_lats_cnt);
+
+int omap_device_register(struct omap_device *od);
+
+/* OMAP PM interface */
+int omap_device_align_pm_lat(struct platform_device *pdev,
+			     u32 new_wakeup_lat_limit);
+struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+
+/* Other */
+
+int omap_device_idle_hwmods(struct omap_device *od);
+int omap_device_enable_hwmods(struct omap_device *od);
+
+int omap_device_disable_clocks(struct omap_device *od);
+int omap_device_enable_clocks(struct omap_device *od);
+
+
+/*
+ * Entries should be kept in latency order ascending
+ *
+ * deact_lat is the maximum number of microseconds required to complete
+ * deactivate_func() at the device's slowest OPP.
+ *
+ * act_lat is the maximum number of microseconds required to complete
+ * activate_func() at the device's slowest OPP.
+ *
+ * This will result in some suboptimal power management decisions at fast
+ * OPPs, but avoids having to recompute all device power management decisions
+ * if the system shifts from a fast OPP to a slow OPP (in order to meet
+ * latency requirements).
+ *
+ * XXX should deactivate_func/activate_func() take platform_device pointers
+ * rather than omap_device pointers?
+ */
+struct omap_device_pm_latency {
+	u32 deactivate_lat;
+	int (*deactivate_func)(struct omap_device *od);
+	u32 activate_lat;
+	int (*activate_func)(struct omap_device *od);
+};
+
+
+/* Get omap_device pointer from platform_device pointer */
+#define to_omap_device(x) container_of((x), struct omap_device, pdev)
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap_hwmod.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,468 @@
+/*
+ * omap_hwmod macros, structures
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Created in collaboration with (alphabetical order): Benoit Cousson,
+ * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
+ * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
+ *
+ * This 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.
+ *
+ * These headers and macros are used to define OMAP on-chip module
+ * data and their integration with other OMAP modules and Linux.
+ *
+ * References:
+ * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
+ * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
+ * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
+ * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
+ * - Open Core Protocol Specification 2.2
+ *
+ * To do:
+ * - add interconnect error log structures
+ * - add pinmuxing
+ * - init_conn_id_bit (CONNID_BIT_VECTOR)
+ * - implement default hwmod SMS/SDRC flags?
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+
+#include <plat/cpu.h>
+
+struct omap_device;
+
+/* OCP SYSCONFIG bit shifts/masks */
+#define SYSC_MIDLEMODE_SHIFT		12
+#define SYSC_MIDLEMODE_MASK		(0x3 << SYSC_MIDLEMODE_SHIFT)
+#define SYSC_CLOCKACTIVITY_SHIFT	8
+#define SYSC_CLOCKACTIVITY_MASK		(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
+#define SYSC_SIDLEMODE_SHIFT		3
+#define SYSC_SIDLEMODE_MASK		(0x3 << SYSC_SIDLEMODE_SHIFT)
+#define SYSC_ENAWAKEUP_SHIFT		2
+#define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
+#define SYSC_SOFTRESET_SHIFT		1
+#define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
+#define SYSC_AUTOIDLE_SHIFT		0
+#define SYSC_AUTOIDLE_MASK		(1 << SYSC_AUTOIDLE_SHIFT)
+
+/* OCP SYSSTATUS bit shifts/masks */
+#define SYSS_RESETDONE_SHIFT		0
+#define SYSS_RESETDONE_MASK		(1 << SYSS_RESETDONE_SHIFT)
+
+/* Master standby/slave idle mode flags */
+#define HWMOD_IDLEMODE_FORCE		(1 << 0)
+#define HWMOD_IDLEMODE_NO		(1 << 1)
+#define HWMOD_IDLEMODE_SMART		(1 << 2)
+
+
+/**
+ * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
+ * @name: name of the IRQ channel (module local name)
+ * @irq_ch: IRQ channel ID
+ *
+ * @name should be something short, e.g., "tx" or "rx".  It is for use
+ * by platform_get_resource_byname().  It is defined locally to the
+ * hwmod.
+ */
+struct omap_hwmod_irq_info {
+	const char	*name;
+	u16		irq;
+};
+
+/**
+ * struct omap_hwmod_dma_info - DMA channels used by the hwmod
+ * @name: name of the DMA channel (module local name)
+ * @dma_ch: DMA channel ID
+ *
+ * @name should be something short, e.g., "tx" or "rx".  It is for use
+ * by platform_get_resource_byname().  It is defined locally to the
+ * hwmod.
+ */
+struct omap_hwmod_dma_info {
+	const char	*name;
+	u16		dma_ch;
+};
+
+/**
+ * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
+ * @role: "sys", "32k", "tv", etc -- for use in clk_get()
+ * @clkdev_dev_id: opt clock: clkdev dev_id string
+ * @clkdev_con_id: opt clock: clkdev con_id string
+ * @_clk: pointer to the struct clk (filled in at runtime)
+ *
+ * The module's interface clock and main functional clock should not
+ * be added as optional clocks.
+ */
+struct omap_hwmod_opt_clk {
+	const char	*role;
+	const char	*clkdev_dev_id;
+	const char	*clkdev_con_id;
+	struct clk	*_clk;
+};
+
+
+/* omap_hwmod_omap2_firewall.flags bits */
+#define OMAP_FIREWALL_L3		(1 << 0)
+#define OMAP_FIREWALL_L4		(1 << 1)
+
+/**
+ * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
+ * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
+ * @l4_fw_region: L4 firewall region ID
+ * @l4_prot_group: L4 protection group ID
+ * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
+ */
+struct omap_hwmod_omap2_firewall {
+	u8 l3_perm_bit;
+	u8 l4_fw_region;
+	u8 l4_prot_group;
+	u8 flags;
+};
+
+
+/*
+ * omap_hwmod_addr_space.flags bits
+ *
+ * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
+ * ADDR_TYPE_RT: Address space contains module register target data.
+ */
+#define ADDR_MAP_ON_INIT	(1 << 0)
+#define ADDR_TYPE_RT		(1 << 1)
+
+/**
+ * struct omap_hwmod_addr_space - MPU address space handled by the hwmod
+ * @pa_start: starting physical address
+ * @pa_end: ending physical address
+ * @flags: (see omap_hwmod_addr_space.flags macros above)
+ *
+ * Address space doesn't necessarily follow physical interconnect
+ * structure.  GPMC is one example.
+ */
+struct omap_hwmod_addr_space {
+	u32 pa_start;
+	u32 pa_end;
+	u8 flags;
+};
+
+
+/*
+ * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
+ * interface to interact with the hwmod.  Used to add sleep dependencies
+ * when the module is enabled or disabled.
+ */
+#define OCP_USER_MPU			(1 << 0)
+#define OCP_USER_SDMA			(1 << 1)
+
+/* omap_hwmod_ocp_if.flags bits */
+#define OCPIF_HAS_IDLEST		(1 << 0)
+#define OCPIF_SWSUP_IDLE		(1 << 1)
+#define OCPIF_CAN_BURST			(1 << 2)
+
+/**
+ * struct omap_hwmod_ocp_if - OCP interface data
+ * @master: struct omap_hwmod that initiates OCP transactions on this link
+ * @slave: struct omap_hwmod that responds to OCP transactions on this link
+ * @addr: address space associated with this link
+ * @clkdev_dev_id: interface clock: clkdev dev_id string
+ * @clkdev_con_id: interface clock: clkdev con_id string
+ * @_clk: pointer to the interface struct clk (filled in at runtime)
+ * @fw: interface firewall data
+ * @addr_cnt: ARRAY_SIZE(@addr)
+ * @width: OCP data width
+ * @thread_cnt: number of threads
+ * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
+ * @user: initiators using this interface (see OCP_USER_* macros above)
+ * @flags: OCP interface flags (see OCPIF_* macros above)
+ *
+ * It may also be useful to add a tag_cnt field for OCP2.x devices.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod_ocp_if {
+	struct omap_hwmod		*master;
+	struct omap_hwmod		*slave;
+	struct omap_hwmod_addr_space	*addr;
+	const char			*clkdev_dev_id;
+	const char			*clkdev_con_id;
+	struct clk			*_clk;
+	union {
+		struct omap_hwmod_omap2_firewall omap2;
+	}				fw;
+	u8				addr_cnt;
+	u8				width;
+	u8				thread_cnt;
+	u8				max_burst_len;
+	u8				user;
+	u8				flags;
+};
+
+
+/* Macros for use in struct omap_hwmod_sysconfig */
+
+/* Flags for use in omap_hwmod_sysconfig.idlemodes */
+#define MASTER_STANDBY_SHIFT	2
+#define SLAVE_IDLE_SHIFT	0
+#define SIDLE_FORCE		(HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
+#define SIDLE_NO		(HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART		(HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
+#define MSTANDBY_FORCE		(HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_NO		(HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_SMART		(HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
+
+/* omap_hwmod_sysconfig.sysc_flags capability flags */
+#define SYSC_HAS_AUTOIDLE	(1 << 0)
+#define SYSC_HAS_SOFTRESET	(1 << 1)
+#define SYSC_HAS_ENAWAKEUP	(1 << 2)
+#define SYSC_HAS_EMUFREE	(1 << 3)
+#define SYSC_HAS_CLOCKACTIVITY	(1 << 4)
+#define SYSC_HAS_SIDLEMODE	(1 << 5)
+#define SYSC_HAS_MIDLEMODE	(1 << 6)
+#define SYSS_MISSING		(1 << 7)
+#define SYSC_NO_CACHE		(1 << 8)  /* XXX SW flag, belongs elsewhere */
+
+/* omap_hwmod_sysconfig.clockact flags */
+#define CLOCKACT_TEST_BOTH	0x0
+#define CLOCKACT_TEST_MAIN	0x1
+#define CLOCKACT_TEST_ICLK	0x2
+#define CLOCKACT_TEST_NONE	0x3
+
+/**
+ * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
+ * @rev_offs: IP block revision register offset (from module base addr)
+ * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
+ * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
+ * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
+ * @clockact: the default value of the module CLOCKACTIVITY bits
+ *
+ * @clockact describes to the module which clocks are likely to be
+ * disabled when the PRCM issues its idle request to the module.  Some
+ * modules have separate clockdomains for the interface clock and main
+ * functional clock, and can check whether they should acknowledge the
+ * idle request based on the internal module functionality that has
+ * been associated with the clocks marked in @clockact.  This field is
+ * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
+ *
+ */
+struct omap_hwmod_sysconfig {
+	u16 rev_offs;
+	u16 sysc_offs;
+	u16 syss_offs;
+	u8 idlemodes;
+	u8 sysc_flags;
+	u8 clockact;
+};
+
+/**
+ * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
+ * @module_offs: PRCM submodule offset from the start of the PRM/CM
+ * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
+ * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
+ * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
+ * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
+ * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
+ *
+ * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
+ * WKEN, GRPSEL registers.  In an ideal world, no extra information
+ * would be needed for IDLEST information, but alas, there are some
+ * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
+ * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
+ */
+struct omap_hwmod_omap2_prcm {
+	s16 module_offs;
+	u8 prcm_reg_id;
+	u8 module_bit;
+	u8 idlest_reg_id;
+	u8 idlest_idle_bit;
+	u8 idlest_stdby_bit;
+};
+
+
+/**
+ * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
+ * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2
+ * @device_offs: device register offset from @module_offs
+ * @submodule_wkdep_bit: bit shift of the WKDEP range
+ */
+struct omap_hwmod_omap4_prcm {
+	u32 module_offs;
+	u16 device_offs;
+	u8 submodule_wkdep_bit;
+};
+
+
+/*
+ * omap_hwmod.flags definitions
+ *
+ * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
+ *     of idle, rather than relying on module smart-idle
+ * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
+ *     of standby, rather than relying on module smart-standby
+ * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
+ *     SDRAM controller, etc.
+ * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
+ *     controller, etc.
+ * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
+ *     when module is enabled, rather than the default, which is to
+ *     enable autoidle
+ * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
+ */
+#define HWMOD_SWSUP_SIDLE			(1 << 0)
+#define HWMOD_SWSUP_MSTANDBY			(1 << 1)
+#define HWMOD_INIT_NO_RESET			(1 << 2)
+#define HWMOD_INIT_NO_IDLE			(1 << 3)
+#define HWMOD_NO_OCP_AUTOIDLE			(1 << 4)
+#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 5)
+
+/*
+ * omap_hwmod._int_flags definitions
+ * These are for internal use only and are managed by the omap_hwmod code.
+ *
+ * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
+ * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
+ * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
+ */
+#define _HWMOD_NO_MPU_PORT			(1 << 0)
+#define _HWMOD_WAKEUP_ENABLED			(1 << 1)
+#define _HWMOD_SYSCONFIG_LOADED			(1 << 2)
+
+/*
+ * omap_hwmod._state definitions
+ *
+ * INITIALIZED: reset (optionally), initialized, enabled, disabled
+ *              (optionally)
+ *
+ *
+ */
+#define _HWMOD_STATE_UNKNOWN			0
+#define _HWMOD_STATE_REGISTERED			1
+#define _HWMOD_STATE_CLKS_INITED		2
+#define _HWMOD_STATE_INITIALIZED		3
+#define _HWMOD_STATE_ENABLED			4
+#define _HWMOD_STATE_IDLE			5
+#define _HWMOD_STATE_DISABLED			6
+
+/**
+ * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
+ * @name: name of the hwmod
+ * @od: struct omap_device currently associated with this hwmod (internal use)
+ * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
+ * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
+ * @prcm: PRCM data pertaining to this hwmod
+ * @clkdev_dev_id: main clock: clkdev dev_id string
+ * @clkdev_con_id: main clock: clkdev con_id string
+ * @_clk: pointer to the main struct clk (filled in at runtime)
+ * @opt_clks: other device clocks that drivers can request (0..*)
+ * @masters: ptr to array of OCP ifs that this hwmod can initiate on
+ * @slaves: ptr to array of OCP ifs that this hwmod can respond on
+ * @sysconfig: device SYSCONFIG/SYSSTATUS register data
+ * @dev_attr: arbitrary device attributes that can be passed to the driver
+ * @_sysc_cache: internal-use hwmod flags
+ * @_rt_va: cached register target start address (internal use)
+ * @_mpu_port_index: cached MPU register target slave ID (internal use)
+ * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
+ * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
+ * @mpu_irqs_cnt: number of @mpu_irqs
+ * @sdma_chs_cnt: number of @sdma_chs
+ * @opt_clks_cnt: number of @opt_clks
+ * @master_cnt: number of @master entries
+ * @slaves_cnt: number of @slave entries
+ * @response_lat: device OCP response latency (in interface clock cycles)
+ * @_int_flags: internal-use hwmod flags
+ * @_state: internal-use hwmod state
+ * @flags: hwmod flags (documented below)
+ * @omap_chip: OMAP chips this hwmod is present on
+ * @node: list node for hwmod list (internal use)
+ *
+ * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
+ * clock," which for our purposes is defined as "the functional clock needed
+ * for register accesses to complete."  Modules may not have a main clock if
+ * the interface clock also serves as a main clock.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod {
+	const char			*name;
+	struct omap_device		*od;
+	struct omap_hwmod_irq_info	*mpu_irqs;
+	struct omap_hwmod_dma_info	*sdma_chs;
+	union {
+		struct omap_hwmod_omap2_prcm omap2;
+		struct omap_hwmod_omap4_prcm omap4;
+	}				prcm;
+	const char			*clkdev_dev_id;
+	const char			*clkdev_con_id;
+	struct clk			*_clk;
+	struct omap_hwmod_opt_clk	*opt_clks;
+	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
+	struct omap_hwmod_ocp_if	**slaves;  /* connect to *_TA */
+	struct omap_hwmod_sysconfig	*sysconfig;
+	void				*dev_attr;
+	u32				_sysc_cache;
+	void __iomem			*_rt_va;
+	struct list_head		node;
+	u16				flags;
+	u8				_mpu_port_index;
+	u8				msuspendmux_reg_id;
+	u8				msuspendmux_shift;
+	u8				response_lat;
+	u8				mpu_irqs_cnt;
+	u8				sdma_chs_cnt;
+	u8				opt_clks_cnt;
+	u8				masters_cnt;
+	u8				slaves_cnt;
+	u8				hwmods_cnt;
+	u8				_int_flags;
+	u8				_state;
+	const struct omap_chip_id	omap_chip;
+};
+
+int omap_hwmod_init(struct omap_hwmod **ohs);
+int omap_hwmod_register(struct omap_hwmod *oh);
+int omap_hwmod_unregister(struct omap_hwmod *oh);
+struct omap_hwmod *omap_hwmod_lookup(const char *name);
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
+int omap_hwmod_late_init(void);
+
+int omap_hwmod_enable(struct omap_hwmod *oh);
+int omap_hwmod_idle(struct omap_hwmod *oh);
+int omap_hwmod_shutdown(struct omap_hwmod *oh);
+
+int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
+int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
+
+int omap_hwmod_reset(struct omap_hwmod *oh);
+void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
+
+void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
+u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
+
+int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
+
+struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
+
+int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh);
+int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh);
+
+int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
+
+int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
+int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap-pm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap-pm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/omap-pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/omap-pm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,301 @@
+/*
+ * omap-pm.h - OMAP power management interface
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
+ * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
+#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
+
+#include <linux/device.h>
+#include <linux/cpufreq.h>
+
+#include "powerdomain.h"
+
+/**
+ * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
+ * @rate: target clock rate
+ * @opp_id: OPP ID
+ * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
+ *
+ * Operating performance point data.  Can vary by OMAP chip and board.
+ */
+struct omap_opp {
+	unsigned long rate;
+	u8 opp_id;
+	u16 min_vdd;
+};
+
+extern struct omap_opp *mpu_opps;
+extern struct omap_opp *dsp_opps;
+extern struct omap_opp *l3_opps;
+
+/*
+ * agent_id values for use with omap_pm_set_min_bus_tput():
+ *
+ * OCP_INITIATOR_AGENT is only valid for devices that can act as
+ * initiators -- it represents the device's L3 interconnect
+ * connection.  OCP_TARGET_AGENT represents the device's L4
+ * interconnect connection.
+ */
+#define OCP_TARGET_AGENT		1
+#define OCP_INITIATOR_AGENT		2
+
+/**
+ * omap_pm_if_early_init - OMAP PM init code called before clock fw init
+ * @mpu_opp_table: array ptr to struct omap_opp for MPU
+ * @dsp_opp_table: array ptr to struct omap_opp for DSP
+ * @l3_opp_table : array ptr to struct omap_opp for CORE
+ *
+ * Initialize anything that must be configured before the clock
+ * framework starts.  The "_if_" is to avoid name collisions with the
+ * PM idle-loop code.
+ */
+int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
+				 struct omap_opp *dsp_opp_table,
+				 struct omap_opp *l3_opp_table);
+
+/**
+ * omap_pm_if_init - OMAP PM init code called after clock fw init
+ *
+ * The main initialization code.  OPP tables are passed in here.  The
+ * "_if_" is to avoid name collisions with the PM idle-loop code.
+ */
+int __init omap_pm_if_init(void);
+
+/**
+ * omap_pm_if_exit - OMAP PM exit code
+ *
+ * Exit code; currently unused.  The "_if_" is to avoid name
+ * collisions with the PM idle-loop code.
+ */
+void omap_pm_if_exit(void);
+
+/*
+ * Device-driver-originated constraints (via board-*.c files, platform_data)
+ */
+
+
+/**
+ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
+ * @dev: struct device * requesting the constraint
+ * @t: maximum MPU wakeup latency in microseconds
+ *
+ * Request that the maximum interrupt latency for the MPU to be no
+ * greater than 't' microseconds. "Interrupt latency" in this case is
+ * defined as the elapsed time from the occurrence of a hardware or
+ * timer interrupt to the time when the device driver's interrupt
+ * service routine has been entered by the MPU.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the MPU powerdomain into, and
+ * possibly the CORE powerdomain as well, since interrupt handling
+ * code currently runs from SDRAM.  Advanced PM or board*.c code may
+ * also configure interrupt controller priorities, OCP bus priorities,
+ * CPU speed(s), etc.
+ *
+ * This function will not affect device wakeup latency, e.g., time
+ * elapsed from when a device driver enables a hardware device with
+ * clk_enable(), to when the device is ready for register access or
+ * other use.  To control this device wakeup latency, use
+ * set_max_dev_wakeup_lat()
+ *
+ * Multiple calls to set_max_mpu_wakeup_lat() will replace the
+ * previous t value.  To remove the latency target for the MPU, call
+ * with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
+ * @dev: struct device * requesting the constraint
+ * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
+ * @r: minimum throughput (in KiB/s)
+ *
+ * Request that the minimum data throughput on the OCP interconnect
+ * attached to device 'dev' interconnect agent 'tbus_id' be no less
+ * than 'r' KiB/s.
+ *
+ * It is expected that the OMAP PM or bus code will use this
+ * information to set the interconnect clock to run at the lowest
+ * possible speed that satisfies all current system users.  The PM or
+ * bus code will adjust the estimate based on its model of the bus, so
+ * device driver authors should attempt to specify an accurate
+ * quantity for their device use case, and let the PM or bus code
+ * overestimate the numbers as necessary to handle request/response
+ * latency, other competing users on the system, etc.  On OMAP2/3, if
+ * a driver requests a minimum L4 interconnect speed constraint, the
+ * code will also need to add an minimum L3 interconnect speed
+ * constraint,
+ *
+ * Multiple calls to set_min_bus_tput() will replace the previous rate
+ * value for this device.  To remove the interconnect throughput
+ * restriction for this device, call with r = 0.
+ *
+ * No return value.
+ */
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+
+
+/**
+ * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
+ * @dev: struct device *
+ * @t: maximum device wakeup latency in microseconds
+ *
+ * Request that the maximum amount of time necessary for a device to
+ * become accessible after its clocks are enabled should be no greater
+ * than 't' microseconds.  Specifically, this represents the time from
+ * when a device driver enables device clocks with clk_enable(), to
+ * when the register reads and writes on the device will succeed.
+ * This function should be called before clk_disable() is called,
+ * since the power state transition decision may be made during
+ * clk_disable().
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the powerdomain enclosing this
+ * device into.
+ *
+ * Multiple calls to set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device.  To remove the wakeup
+ * latency restriction for this device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
+ * @dev: struct device *
+ * @t: maximum DMA transfer start latency in microseconds
+ *
+ * Request that the maximum system DMA transfer start latency for this
+ * device 'dev' should be no greater than 't' microseconds.  "DMA
+ * transfer start latency" here is defined as the elapsed time from
+ * when a device (e.g., McBSP) requests that a system DMA transfer
+ * start or continue, to the time at which data starts to flow into
+ * that device from the system DMA controller.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the CORE powerdomain into.
+ *
+ * Since system DMA transfers may not involve the MPU, this function
+ * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
+ * so.  Similarly, this function will not affect device wakeup latency
+ * -- use set_max_dev_wakeup_lat() to affect that.
+ *
+ * Multiple calls to set_max_sdma_lat() will replace the previous t
+ * value for this device.  To remove the maximum DMA latency for this
+ * device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+/**
+ * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
+ *
+ * Intended for use by DSPBridge.  Returns an array of OPP->DSP clock
+ * frequency entries.  The final item in the array should have .rate =
+ * .opp_id = 0.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void);
+
+/**
+ * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
+ * @opp_id: target DSP OPP ID
+ *
+ * Set a minimum OPP ID for the DSP.  This is intended to be called
+ * only from the DSP Bridge MPU-side driver.  Unfortunately, the only
+ * information that code receives from the DSP/BIOS load estimator is the
+ * target OPP ID; hence, this interface.  No return value.
+ */
+void omap_pm_dsp_set_min_opp(u8 opp_id);
+
+/**
+ * omap_pm_dsp_get_opp - report the current DSP OPP ID
+ *
+ * Report the current OPP for the DSP.  Since on OMAP3, the DSP and
+ * MPU share a single voltage domain, the OPP ID returned back may
+ * represent a higher DSP speed than the OPP requested via
+ * omap_pm_dsp_set_min_opp().
+ *
+ * Returns the current VDD1 OPP ID, or 0 upon error.
+ */
+u8 omap_pm_dsp_get_opp(void);
+
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+/**
+ * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
+ *
+ * Provide a frequency table usable by CPUFreq for the current chip/board.
+ * Returns a pointer to a struct cpufreq_frequency_table array or NULL
+ * upon error.
+ */
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
+
+/**
+ * omap_pm_cpu_set_freq - set the current minimum MPU frequency
+ * @f: MPU frequency in Hz
+ *
+ * Set the current minimum CPU frequency.  The actual CPU frequency
+ * used could end up higher if the DSP requested a higher OPP.
+ * Intended to be called by plat-omap/cpu_omap.c:omap_target().  No
+ * return value.
+ */
+void omap_pm_cpu_set_freq(unsigned long f);
+
+/**
+ * omap_pm_cpu_get_freq - report the current CPU frequency
+ *
+ * Returns the current MPU frequency, or 0 upon error.
+ */
+unsigned long omap_pm_cpu_get_freq(void);
+
+
+/*
+ * Device context loss tracking
+ */
+
+/**
+ * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
+ * @dev: struct device *
+ *
+ * This function returns the number of times that the device @dev has
+ * lost its internal context.  This generally occurs on a powerdomain
+ * transition to OFF.  Drivers use this as an optimization to avoid restoring
+ * context if the device hasn't lost it.  To use, drivers should initially
+ * call this in their context save functions and store the result.  Early in
+ * the driver's context restore function, the driver should call this function
+ * again, and compare the result to the stored counter.  If they differ, the
+ * driver must restore device context.   If the number of context losses
+ * exceeds the maximum positive integer, the function will wrap to 0 and
+ * continue counting.  Returns the number of context losses for this device,
+ * or -EINVAL upon error.
+ */
+int omap_pm_get_dev_context_loss_count(struct device *dev);
+
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/onenand.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/onenand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/onenand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/onenand.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/plat-omap/include/mach/onenand.h
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * This 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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#define ONENAND_SYNC_READ	(1 << 0)
+#define ONENAND_SYNC_READWRITE	(1 << 1)
+
+struct omap_onenand_platform_data {
+	int			cs;
+	int			gpio_irq;
+	struct mtd_partition	*parts;
+	int			nr_parts;
+	int                     (*onenand_setup)(void __iomem *, int freq);
+	int			dma_channel;
+	u8			flags;
+};
+
+#define ONENAND_MAX_PARTITIONS 8
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+
+#else
+
+#define board_onenand_data	NULL
+
+static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+{
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/param.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/param.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/param.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,8 @@
+/*
+ *  arch/arm/plat-omap/include/mach/param.h
+ *
+ */
+
+#ifdef CONFIG_OMAP_32K_TIMER_HZ
+#define HZ	CONFIG_OMAP_32K_TIMER_HZ
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/powerdomain.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,187 @@
+/*
+ * OMAP2/3 powerdomain control
+ *
+ * Copyright (C) 2007-8 Texas Instruments, Inc.
+ * Copyright (C) 2007-8 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This 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_ARM_ARCH_OMAP_POWERDOMAIN
+#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <asm/atomic.h>
+
+#include <plat/cpu.h>
+
+
+/* Powerdomain basic power states */
+#define PWRDM_POWER_OFF		0x0
+#define PWRDM_POWER_RET		0x1
+#define PWRDM_POWER_INACTIVE	0x2
+#define PWRDM_POWER_ON		0x3
+
+#define PWRDM_MAX_PWRSTS	4
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF_ON		((1 << PWRDM_POWER_OFF) | \
+				 (1 << PWRDM_POWER_ON))
+
+#define PWRSTS_OFF_RET		((1 << PWRDM_POWER_OFF) | \
+				 (1 << PWRDM_POWER_RET))
+
+#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
+
+
+/* Powerdomain flags */
+#define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */
+#define PWRDM_HAS_MPU_QUIRK	(1 << 1) /* MPU pwr domain has MEM bank 0 bits
+					  * in MEM bank 1 position. This is
+					  * true for OMAP3430
+					  */
+
+/*
+ * Number of memory banks that are power-controllable.	On OMAP3430, the
+ * maximum is 4.
+ */
+#define PWRDM_MAX_MEM_BANKS	4
+
+/*
+ * Maximum number of clockdomains that can be associated with a powerdomain.
+ * CORE powerdomain on OMAP3 is the worst case
+ */
+#define PWRDM_MAX_CLKDMS	4
+
+/* XXX A completely arbitrary number. What is reasonable here? */
+#define PWRDM_TRANSITION_BAILOUT 100000
+
+struct clockdomain;
+struct powerdomain;
+
+/* Encodes dependencies between powerdomains - statically defined */
+struct pwrdm_dep {
+
+	/* Powerdomain name */
+	const char *pwrdm_name;
+
+	/* Powerdomain pointer - resolved by the powerdomain code */
+	struct powerdomain *pwrdm;
+
+	/* Flags to mark OMAP chip restrictions, etc. */
+	const struct omap_chip_id omap_chip;
+
+};
+
+struct powerdomain {
+
+	/* Powerdomain name */
+	const char *name;
+
+	/* the address offset from CM_BASE/PRM_BASE */
+	const s16 prcm_offs;
+
+	/* Used to represent the OMAP chip types containing this pwrdm */
+	const struct omap_chip_id omap_chip;
+
+	/* Powerdomains that can be told to wake this powerdomain up */
+	struct pwrdm_dep *wkdep_srcs;
+
+	/* Powerdomains that can be told to keep this pwrdm from inactivity */
+	struct pwrdm_dep *sleepdep_srcs;
+
+	/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
+	const u8 dep_bit;
+
+	/* Possible powerdomain power states */
+	const u8 pwrsts;
+
+	/* Possible logic power states when pwrdm in RETENTION */
+	const u8 pwrsts_logic_ret;
+
+	/* Powerdomain flags */
+	const u8 flags;
+
+	/* Number of software-controllable memory banks in this powerdomain */
+	const u8 banks;
+
+	/* Possible memory bank pwrstates when pwrdm in RETENTION */
+	const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
+
+	/* Possible memory bank pwrstates when pwrdm is ON */
+	const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+
+	/* Clockdomains in this powerdomain */
+	struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
+
+	struct list_head node;
+
+	int state;
+	unsigned state_counter[PWRDM_MAX_PWRSTS];
+
+#ifdef CONFIG_PM_DEBUG
+	s64 timer;
+	s64 state_timer[PWRDM_MAX_PWRSTS];
+#endif
+};
+
+
+void pwrdm_init(struct powerdomain **pwrdm_list);
+
+int pwrdm_register(struct powerdomain *pwrdm);
+int pwrdm_unregister(struct powerdomain *pwrdm);
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+			 int (*fn)(struct powerdomain *pwrdm,
+				   struct clockdomain *clkdm));
+
+int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
+int pwrdm_pre_transition(void);
+int pwrdm_post_transition(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/prcm.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/prcm.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/prcm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/prcm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/plat-omap/include/mach/prcm.h
+ *
+ * Access definations for use in OMAP24XX clock and power management
+ *
+ * Copyright (C) 2005 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 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_ARCH_OMAP_PRCM_H
+#define __ASM_ARM_ARCH_OMAP_PRCM_H
+
+u32 omap_prcm_get_reset_sources(void);
+void omap_prcm_arch_reset(char mode);
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
+
+#define START_PADCONF_SAVE 0x2
+#define PADCONF_SAVE_DONE  0x1
+
+void omap3_prcm_save_context(void);
+void omap3_prcm_restore_context(void);
+
+#endif
+
+
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/sdrc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/sdrc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/sdrc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/sdrc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+#ifndef ____ASM_ARCH_SDRC_H
+#define ____ASM_ARCH_SDRC_H
+
+/*
+ * OMAP2/3 SDRC/SMS register definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Tony Lindgren
+ * Paul Walmsley
+ * Richard Woodruff
+ *
+ * This 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 <mach/io.h>
+
+/* SDRC register offsets - read/write with sdrc_{read,write}_reg() */
+
+#define SDRC_SYSCONFIG		0x010
+#define SDRC_CS_CFG		0x040
+#define SDRC_SHARING		0x044
+#define SDRC_ERR_TYPE		0x04C
+#define SDRC_DLLA_CTRL		0x060
+#define SDRC_DLLA_STATUS	0x064
+#define SDRC_DLLB_CTRL		0x068
+#define SDRC_DLLB_STATUS	0x06C
+#define SDRC_POWER		0x070
+#define SDRC_MCFG_0		0x080
+#define SDRC_MR_0		0x084
+#define SDRC_EMR2_0		0x08c
+#define SDRC_ACTIM_CTRL_A_0	0x09c
+#define SDRC_ACTIM_CTRL_B_0	0x0a0
+#define SDRC_RFR_CTRL_0		0x0a4
+#define SDRC_MANUAL_0		0x0a8
+#define SDRC_MCFG_1		0x0B0
+#define SDRC_MR_1		0x0B4
+#define SDRC_EMR2_1		0x0BC
+#define SDRC_ACTIM_CTRL_A_1	0x0C4
+#define SDRC_ACTIM_CTRL_B_1	0x0C8
+#define SDRC_RFR_CTRL_1		0x0D4
+#define SDRC_MANUAL_1		0x0D8
+
+#define SDRC_POWER_AUTOCOUNT_SHIFT	8
+#define SDRC_POWER_AUTOCOUNT_MASK	(0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
+#define SDRC_POWER_CLKCTRL_SHIFT	4
+#define SDRC_POWER_CLKCTRL_MASK		(0x3 << SDRC_POWER_CLKCTRL_SHIFT)
+#define SDRC_SELF_REFRESH_ON_AUTOCOUNT	(0x2 << SDRC_POWER_CLKCTRL_SHIFT)
+
+/*
+ * These values represent the number of memory clock cycles between
+ * autorefresh initiation.  They assume 1 refresh per 64 ms (JEDEC), 8192
+ * rows per device, and include a subtraction of a 50 cycle window in the
+ * event that the autorefresh command is delayed due to other SDRC activity.
+ * The '| 1' sets the ARE field to send one autorefresh when the autorefresh
+ * counter reaches 0.
+ *
+ * These represent optimal values for common parts, it won't work for all.
+ * As long as you scale down, most parameters are still work, they just
+ * become sub-optimal. The RFR value goes in the opposite direction. If you
+ * don't adjust it down as your clock period increases the refresh interval
+ * will not be met. Setting all parameters for complete worst case may work,
+ * but may cut memory performance by 2x. Due to errata the DLLs need to be
+ * unlocked and their value needs run time calibration.	A dynamic call is
+ * need for that as no single right value exists acorss production samples.
+ *
+ * Only the FULL speed values are given. Current code is such that rate
+ * changes must be made at DPLLoutx2. The actual value adjustment for low
+ * frequency operation will be handled by omap_set_performance()
+ *
+ * By having the boot loader boot up in the fastest L4 speed available likely
+ * will result in something which you can switch between.
+ */
+#define SDRC_RFR_CTRL_165MHz	(0x00044c00 | 1)
+#define SDRC_RFR_CTRL_133MHz	(0x0003de00 | 1)
+#define SDRC_RFR_CTRL_100MHz	(0x0002da01 | 1)
+#define SDRC_RFR_CTRL_110MHz	(0x0002da01 | 1) /* Need to calc */
+#define SDRC_RFR_CTRL_BYPASS	(0x00005000 | 1) /* Need to calc */
+
+
+/*
+ * SMS register access
+ */
+
+#define OMAP242X_SMS_REGADDR(reg)					\
+		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg)					\
+		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg)					\
+		(void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+
+/* SMS register offsets - read/write with sms_{read,write}_reg() */
+
+#define SMS_SYSCONFIG			0x010
+#define SMS_ROT_CONTROL(context)	(0x180 + 0x10 * context)
+#define SMS_ROT_SIZE(context)		(0x184 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context)	(0x188 + 0x10 * context)
+/* REVISIT: fill in other SMS registers here */
+
+
+#ifndef __ASSEMBLER__
+
+/**
+ * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
+ * @rate: SDRC clock rate (in Hz)
+ * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
+ * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
+ * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
+ * @mr: Value to program to SDRC_MR for this rate
+ *
+ * This structure holds a pre-computed set of register values for the
+ * SDRC for a given SDRC clock rate and SDRAM chip.  These are
+ * intended to be pre-computed and specified in an array in the board-*.c
+ * files.  The structure is keyed off the 'rate' field.
+ */
+struct omap_sdrc_params {
+	unsigned long rate;
+	u32 actim_ctrla;
+	u32 actim_ctrlb;
+	u32 rfr_ctrl;
+	u32 mr;
+};
+
+void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+			    struct omap_sdrc_params *sdrc_cs1);
+int omap2_sdrc_get_params(unsigned long r,
+			  struct omap_sdrc_params **sdrc_cs0,
+			  struct omap_sdrc_params **sdrc_cs1);
+void omap2_sms_save_context(void);
+void omap2_sms_restore_context(void);
+
+void omap2_sms_write_rot_control(u32 val, unsigned ctx);
+void omap2_sms_write_rot_size(u32 val, unsigned ctx);
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
+
+#ifdef CONFIG_ARCH_OMAP2
+
+struct memory_timings {
+	u32 m_type;		/* ddr = 1, sdr = 0 */
+	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
+	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
+	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
+	u32 base_cs;		/* base chip select to use for calculations */
+};
+
+extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
+
+u32 omap2xxx_sdrc_dll_is_unlocked(void);
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
+
+#endif  /* CONFIG_ARCH_OMAP2 */
+
+#endif  /* __ASSEMBLER__ */
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/serial.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/serial.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/serial.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/plat-omap/include/mach/serial.h
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Addded OMAP4 support- Santosh Shilimkar <santosh.shilimkar@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.
+ */
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/init.h>
+
+#if defined(CONFIG_ARCH_OMAP1)
+/* OMAP1 serial ports */
+#define OMAP_UART1_BASE		0xfffb0000
+#define OMAP_UART2_BASE		0xfffb0800
+#define OMAP_UART3_BASE		0xfffb9800
+#elif defined(CONFIG_ARCH_OMAP2)
+/* OMAP2 serial ports */
+#define OMAP_UART1_BASE		0x4806a000
+#define OMAP_UART2_BASE		0x4806c000
+#define OMAP_UART3_BASE		0x4806e000
+#elif defined(CONFIG_ARCH_OMAP3)
+/* OMAP3 serial ports */
+#define OMAP_UART1_BASE		0x4806a000
+#define OMAP_UART2_BASE		0x4806c000
+#define OMAP_UART3_BASE		0x49020000
+#elif defined(CONFIG_ARCH_OMAP4)
+/* OMAP4 serial ports */
+#define OMAP_UART1_BASE		0x4806a000
+#define OMAP_UART2_BASE		0x4806c000
+#define OMAP_UART3_BASE		0x48020000
+#define OMAP_UART4_BASE		0x4806e000
+#endif
+
+#define OMAP1510_BASE_BAUD	(12000000/16)
+#define OMAP16XX_BASE_BAUD	(48000000/16)
+#define OMAP24XX_BASE_BAUD	(48000000/16)
+
+#define is_omap_port(pt)	({int __ret = 0;			\
+			if ((pt)->port.mapbase == OMAP_UART1_BASE ||	\
+			    (pt)->port.mapbase == OMAP_UART2_BASE ||	\
+			    (pt)->port.mapbase == OMAP_UART3_BASE)	\
+				__ret = 1;				\
+			__ret;						\
+			})
+
+#ifndef __ASSEMBLER__
+extern void __init omap_serial_early_init(void);
+extern void omap_serial_init(void);
+extern void omap_serial_init_port(int port);
+extern int omap_uart_can_sleep(void);
+extern void omap_uart_check_wakeup(void);
+extern void omap_uart_prepare_suspend(void);
+extern void omap_uart_prepare_idle(int num);
+extern void omap_uart_resume_idle(int num);
+extern void omap_uart_enable_irqs(int enable);
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/smp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/smp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,53 @@
+/*
+ * OMAP4 machine specific smp.h
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Author:
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Interface functions needed for the SMP. This file is based on arm
+ * realview smp platform.
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OMAP_ARCH_SMP_H
+#define OMAP_ARCH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+/*
+ * set_event() is used to wake up secondary core from wfe using sev. ROM
+ * code puts the second core into wfe(standby).
+ *
+ */
+#define set_event()	__asm__ __volatile__ ("sev" : : : "memory")
+
+/* Needed for secondary core boot */
+extern void omap_secondary_startup(void);
+extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
+extern void omap_auxcoreboot_addr(u32 cpu_addr);
+
+/*
+ * We use Soft IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+	gic_raise_softirq(mask, 1);
+}
+
+/*
+ * Read MPIDR: Multiprocessor affinity register
+ */
+#define hard_smp_processor_id()			\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/sram.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/sram.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/sram.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/sram.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/plat-omap/include/mach/sram.h
+ *
+ * Interface for functions that need to be run in internal SRAM
+ *
+ * This 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_OMAP_SRAM_H
+#define __ARCH_ARM_OMAP_SRAM_H
+
+extern int __init omap_sram_init(void);
+extern void * omap_sram_push(void * start, unsigned long size);
+extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
+
+extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+				u32 base_cs, u32 force_unlock);
+extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+				      u32 mem_type);
+extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+extern u32 omap3_configure_core_dpll(
+			u32 m2, u32 unlock_dll, u32 f, u32 inc,
+			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+extern void omap3_sram_restore_context(void);
+
+/* Do not use these */
+extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap1_sram_reprogram_clock_sz;
+
+extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap24xx_sram_reprogram_clock_sz;
+
+extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+						u32 base_cs, u32 force_unlock);
+extern unsigned long omap242x_sram_ddr_init_sz;
+
+extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+						int bypass);
+extern unsigned long omap242x_sram_set_prcm_sz;
+
+extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+						u32 mem_type);
+extern unsigned long omap242x_sram_reprogram_sdrc_sz;
+
+
+extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+						u32 base_cs, u32 force_unlock);
+extern unsigned long omap243x_sram_ddr_init_sz;
+
+extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+						int bypass);
+extern unsigned long omap243x_sram_set_prcm_sz;
+
+extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+						u32 mem_type);
+extern unsigned long omap243x_sram_reprogram_sdrc_sz;
+
+extern u32 omap3_sram_configure_core_dpll(
+			u32 m2, u32 unlock_dll, u32 f, u32 inc,
+			u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+			u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+			u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+			u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+extern unsigned long omap3_sram_configure_core_dpll_sz;
+
+#ifdef CONFIG_PM
+extern void omap_push_sram_idle(void);
+#else
+static inline void omap_push_sram_idle(void) {}
+#endif /* CONFIG_PM */
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/system.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/system.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,51 @@
+/*
+ * Copied from arch/arm/mach-sa1100/include/mach/system.h
+ * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <plat/prcm.h>
+
+#ifndef CONFIG_MACH_VOICEBLUE
+#define voiceblue_reset()		do {} while (0)
+#else
+extern void voiceblue_reset(void);
+#endif
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void omap1_arch_reset(char mode)
+{
+	/*
+	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
+	 * "Global Software Reset Affects Traffic Controller Frequency".
+	 */
+	if (cpu_is_omap5912()) {
+		omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4),
+				 DPLL_CTL);
+		omap_writew(0x8, ARM_RSTCT1);
+	}
+
+	if (machine_is_voiceblue())
+		voiceblue_reset();
+	else
+		omap_writew(1, ARM_RSTCT1);
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	if (!cpu_class_is_omap2())
+		omap1_arch_reset(mode);
+	else
+		omap_prcm_arch_reset(mode);
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/tc.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/tc.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/tc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/tc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/plat-omap/include/mach/tc.h
+ *
+ * OMAP Traffic Controller
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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.
+ */
+
+#ifndef __ASM_ARCH_TC_H
+#define __ASM_ARCH_TC_H
+
+#define TCMIF_BASE		0xfffecc00
+#define OMAP_TC_OCPT1_PRIOR	(TCMIF_BASE + 0x00)
+#define OMAP_TC_EMIFS_PRIOR	(TCMIF_BASE + 0x04)
+#define OMAP_TC_EMIFF_PRIOR	(TCMIF_BASE + 0x08)
+#define EMIFS_CONFIG		(TCMIF_BASE + 0x0c)
+#define EMIFS_CS0_CONFIG	(TCMIF_BASE + 0x10)
+#define EMIFS_CS1_CONFIG	(TCMIF_BASE + 0x14)
+#define EMIFS_CS2_CONFIG	(TCMIF_BASE + 0x18)
+#define EMIFS_CS3_CONFIG	(TCMIF_BASE + 0x1c)
+#define EMIFF_SDRAM_CONFIG	(TCMIF_BASE + 0x20)
+#define EMIFF_MRS		(TCMIF_BASE + 0x24)
+#define TC_TIMEOUT1		(TCMIF_BASE + 0x28)
+#define TC_TIMEOUT2		(TCMIF_BASE + 0x2c)
+#define TC_TIMEOUT3		(TCMIF_BASE + 0x30)
+#define TC_ENDIANISM		(TCMIF_BASE + 0x34)
+#define EMIFF_SDRAM_CONFIG_2	(TCMIF_BASE + 0x3c)
+#define EMIF_CFG_DYNAMIC_WS	(TCMIF_BASE + 0x40)
+#define EMIFS_ACS0		(TCMIF_BASE + 0x50)
+#define EMIFS_ACS1		(TCMIF_BASE + 0x54)
+#define EMIFS_ACS2		(TCMIF_BASE + 0x58)
+#define EMIFS_ACS3		(TCMIF_BASE + 0x5c)
+#define OMAP_TC_OCPT2_PRIOR	(TCMIF_BASE + 0xd0)
+
+/* external EMIFS chipselect regions */
+#define	OMAP_CS0_PHYS		0x00000000
+#define	OMAP_CS0_SIZE		SZ_64M
+
+#define	OMAP_CS1_PHYS		0x04000000
+#define	OMAP_CS1_SIZE		SZ_64M
+
+#define	OMAP_CS1A_PHYS		OMAP_CS1_PHYS
+#define	OMAP_CS1A_SIZE		SZ_32M
+
+#define	OMAP_CS1B_PHYS		(OMAP_CS1A_PHYS + OMAP_CS1A_SIZE)
+#define	OMAP_CS1B_SIZE		SZ_32M
+
+#define	OMAP_CS2_PHYS		0x08000000
+#define	OMAP_CS2_SIZE		SZ_64M
+
+#define	OMAP_CS2A_PHYS		OMAP_CS2_PHYS
+#define	OMAP_CS2A_SIZE		SZ_32M
+
+#define	OMAP_CS2B_PHYS		(OMAP_CS2A_PHYS + OMAP_CS2A_SIZE)
+#define	OMAP_CS2B_SIZE		SZ_32M
+
+#define	OMAP_CS3_PHYS		0x0c000000
+#define	OMAP_CS3_SIZE		SZ_64M
+
+#ifndef	__ASSEMBLER__
+
+/* EMIF Slow Interface Configuration Register */
+#define OMAP_EMIFS_CONFIG_FR		(1 << 4)
+#define OMAP_EMIFS_CONFIG_PDE		(1 << 3)
+#define OMAP_EMIFS_CONFIG_PWD_EN	(1 << 2)
+#define OMAP_EMIFS_CONFIG_BM		(1 << 1)
+#define OMAP_EMIFS_CONFIG_WP		(1 << 0)
+
+#define EMIFS_CCS(n)		(EMIFS_CS0_CONFIG + (4 * (n)))
+#define EMIFS_ACS(n)		(EMIFS_ACS0 + (4 * (n)))
+
+/* Almost all documentation for chip and board memory maps assumes
+ * BM is clear.  Most devel boards have a switch to control booting
+ * from NOR flash (using external chipselect 3) rather than mask ROM,
+ * which uses BM to interchange the physical CS0 and CS3 addresses.
+ */
+static inline u32 omap_cs0_phys(void)
+{
+	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+			?  OMAP_CS3_PHYS : 0;
+}
+
+static inline u32 omap_cs3_phys(void)
+{
+	return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+			? 0 : OMAP_CS3_PHYS;
+}
+
+#endif	/* __ASSEMBLER__ */
+
+#endif	/* __ASM_ARCH_TC_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/timer-gp.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/timer-gp.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/timer-gp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/timer-gp.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,17 @@
+/*
+ * OMAP2/3 GPTIMER support.headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+
+int __init omap2_gp_clockevent_set_gptimer(u8 id);
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/timex.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/timex.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/plat-omap/include/mach/timex.h
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author:  Greg Lonnon <glonnon@ridgerun.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 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.
+ */
+
+#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
+#define __ASM_ARCH_OMAP_TIMEX_H
+
+/*
+ * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
+ * and that's why the CLOCK_TICK_RATE is not 32768.
+ */
+#ifdef CONFIG_OMAP_32K_TIMER
+#define CLOCK_TICK_RATE		(CONFIG_OMAP_32K_TIMER_HZ)
+#else
+#define CLOCK_TICK_RATE		(HZ * 100000UL)
+#endif
+
+#endif /* __ASM_ARCH_OMAP_TIMEX_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/uncompress.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/uncompress.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/uncompress.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/plat-omap/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Initially based on:
+ * linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Rewritten by:
+ * Author: <source@mvista.com>
+ * 2004 (c) MontaVista Software, 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/types.h>
+#include <linux/serial_reg.h>
+#include <plat/serial.h>
+
+unsigned int system_rev;
+
+#define UART_OMAP_MDR1		0x08	/* mode definition register */
+#define OMAP_ID_730		0x355F
+#define OMAP_ID_850		0x362C
+#define ID_MASK			0x7fff
+#define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
+#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
+
+static void putc(int c)
+{
+	volatile u8 * uart = 0;
+	int shift = 2;
+
+#ifdef CONFIG_MACH_OMAP_PALMTE
+	return;
+#endif
+
+#ifdef CONFIG_ARCH_OMAP
+#ifdef	CONFIG_OMAP_LL_DEBUG_UART3
+	uart = (volatile u8 *)(OMAP_UART3_BASE);
+#elif defined(CONFIG_OMAP_LL_DEBUG_UART2)
+	uart = (volatile u8 *)(OMAP_UART2_BASE);
+#elif defined(CONFIG_OMAP_LL_DEBUG_UART1)
+	uart = (volatile u8 *)(OMAP_UART1_BASE);
+#elif defined(CONFIG_OMAP_LL_DEBUG_NONE)
+	return;
+#else
+	return;
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1
+	/* Determine which serial port to use */
+	do {
+		/* MMU is not on, so cpu_is_omapXXXX() won't work here */
+		unsigned int omap_id = omap_get_id();
+
+		if (omap_id == OMAP_ID_730 || omap_id == OMAP_ID_850)
+			shift = 0;
+
+		if (check_port(uart, shift))
+			break;
+		/* Silent boot if no serial ports are enabled. */
+		return;
+	} while (0);
+#endif /* CONFIG_ARCH_OMAP1 */
+#endif
+
+	/*
+	 * Now, xmit each character
+	 */
+	while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+		barrier();
+	uart[UART_TX << shift] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/usb.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/usb.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/usb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,162 @@
+// include/asm-arm/mach-omap/usb.h
+
+#ifndef	__ASM_ARCH_OMAP_USB_H
+#define	__ASM_ARCH_OMAP_USB_H
+
+#include <plat/board.h>
+
+#define OMAP3_HS_USB_PORTS	3
+enum ehci_hcd_omap_mode {
+	EHCI_HCD_OMAP_MODE_UNKNOWN,
+	EHCI_HCD_OMAP_MODE_PHY,
+	EHCI_HCD_OMAP_MODE_TLL,
+};
+
+struct ehci_hcd_omap_platform_data {
+	enum ehci_hcd_omap_mode		port_mode[OMAP3_HS_USB_PORTS];
+	unsigned			phy_reset:1;
+
+	/* have to be valid if phy_reset is true and portx is in phy mode */
+	int	reset_gpio_port[OMAP3_HS_USB_PORTS];
+};
+
+/*-------------------------------------------------------------------------*/
+
+#define OMAP1_OTG_BASE			0xfffb0400
+#define OMAP1_UDC_BASE			0xfffb4000
+#define OMAP1_OHCI_BASE			0xfffba000
+
+#define OMAP2_OHCI_BASE			0x4805e000
+#define OMAP2_UDC_BASE			0x4805e200
+#define OMAP2_OTG_BASE			0x4805e300
+
+#ifdef CONFIG_ARCH_OMAP1
+
+#define OTG_BASE			OMAP1_OTG_BASE
+#define UDC_BASE			OMAP1_UDC_BASE
+#define OMAP_OHCI_BASE			OMAP1_OHCI_BASE
+
+#else
+
+#define OTG_BASE			OMAP2_OTG_BASE
+#define UDC_BASE			OMAP2_UDC_BASE
+#define OMAP_OHCI_BASE			OMAP2_OHCI_BASE
+
+extern void usb_musb_init(void);
+
+extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata);
+
+#endif
+
+void omap_usb_init(struct omap_usb_config *pdata);
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * OTG and transceiver registers, for OMAPs starting with ARM926
+ */
+#define OTG_REV				(OTG_BASE + 0x00)
+#define OTG_SYSCON_1			(OTG_BASE + 0x04)
+#	define	 USB2_TRX_MODE(w)	(((w)>>24)&0x07)
+#	define	 USB1_TRX_MODE(w)	(((w)>>20)&0x07)
+#	define	 USB0_TRX_MODE(w)	(((w)>>16)&0x07)
+#	define	 OTG_IDLE_EN		(1 << 15)
+#	define	 HST_IDLE_EN		(1 << 14)
+#	define	 DEV_IDLE_EN		(1 << 13)
+#	define	 OTG_RESET_DONE		(1 << 2)
+#	define	 OTG_SOFT_RESET		(1 << 1)
+#define OTG_SYSCON_2			(OTG_BASE + 0x08)
+#	define	 OTG_EN			(1 << 31)
+#	define	 USBX_SYNCHRO		(1 << 30)
+#	define	 OTG_MST16		(1 << 29)
+#	define	 SRP_GPDATA		(1 << 28)
+#	define	 SRP_GPDVBUS		(1 << 27)
+#	define	 SRP_GPUVBUS(w)		(((w)>>24)&0x07)
+#	define	 A_WAIT_VRISE(w)	(((w)>>20)&0x07)
+#	define	 B_ASE_BRST(w)		(((w)>>16)&0x07)
+#	define	 SRP_DPW		(1 << 14)
+#	define	 SRP_DATA		(1 << 13)
+#	define	 SRP_VBUS		(1 << 12)
+#	define	 OTG_PADEN		(1 << 10)
+#	define	 HMC_PADEN		(1 << 9)
+#	define	 UHOST_EN		(1 << 8)
+#	define	 HMC_TLLSPEED		(1 << 7)
+#	define	 HMC_TLLATTACH		(1 << 6)
+#	define	 OTG_HMC(w)		(((w)>>0)&0x3f)
+#define OTG_CTRL			(OTG_BASE + 0x0c)
+#	define	 OTG_USB2_EN		(1 << 29)
+#	define	 OTG_USB2_DP		(1 << 28)
+#	define	 OTG_USB2_DM		(1 << 27)
+#	define	 OTG_USB1_EN		(1 << 26)
+#	define	 OTG_USB1_DP		(1 << 25)
+#	define	 OTG_USB1_DM		(1 << 24)
+#	define	 OTG_USB0_EN		(1 << 23)
+#	define	 OTG_USB0_DP		(1 << 22)
+#	define	 OTG_USB0_DM		(1 << 21)
+#	define	 OTG_ASESSVLD		(1 << 20)
+#	define	 OTG_BSESSEND		(1 << 19)
+#	define	 OTG_BSESSVLD		(1 << 18)
+#	define	 OTG_VBUSVLD		(1 << 17)
+#	define	 OTG_ID			(1 << 16)
+#	define	 OTG_DRIVER_SEL		(1 << 15)
+#	define	 OTG_A_SETB_HNPEN	(1 << 12)
+#	define	 OTG_A_BUSREQ		(1 << 11)
+#	define	 OTG_B_HNPEN		(1 << 9)
+#	define	 OTG_B_BUSREQ		(1 << 8)
+#	define	 OTG_BUSDROP		(1 << 7)
+#	define	 OTG_PULLDOWN		(1 << 5)
+#	define	 OTG_PULLUP		(1 << 4)
+#	define	 OTG_DRV_VBUS		(1 << 3)
+#	define	 OTG_PD_VBUS		(1 << 2)
+#	define	 OTG_PU_VBUS		(1 << 1)
+#	define	 OTG_PU_ID		(1 << 0)
+#define OTG_IRQ_EN			(OTG_BASE + 0x10)	/* 16-bit */
+#	define	 DRIVER_SWITCH		(1 << 15)
+#	define	 A_VBUS_ERR		(1 << 13)
+#	define	 A_REQ_TMROUT		(1 << 12)
+#	define	 A_SRP_DETECT		(1 << 11)
+#	define	 B_HNP_FAIL		(1 << 10)
+#	define	 B_SRP_TMROUT		(1 << 9)
+#	define	 B_SRP_DONE		(1 << 8)
+#	define	 B_SRP_STARTED		(1 << 7)
+#	define	 OPRT_CHG		(1 << 0)
+#define OTG_IRQ_SRC			(OTG_BASE + 0x14)	/* 16-bit */
+	// same bits as in IRQ_EN
+#define OTG_OUTCTRL			(OTG_BASE + 0x18)	/* 16-bit */
+#	define	 OTGVPD			(1 << 14)
+#	define	 OTGVPU			(1 << 13)
+#	define	 OTGPUID		(1 << 12)
+#	define	 USB2VDR		(1 << 10)
+#	define	 USB2PDEN		(1 << 9)
+#	define	 USB2PUEN		(1 << 8)
+#	define	 USB1VDR		(1 << 6)
+#	define	 USB1PDEN		(1 << 5)
+#	define	 USB1PUEN		(1 << 4)
+#	define	 USB0VDR		(1 << 2)
+#	define	 USB0PDEN		(1 << 1)
+#	define	 USB0PUEN		(1 << 0)
+#define OTG_TEST			(OTG_BASE + 0x20)	/* 16-bit */
+#define OTG_VENDOR_CODE			(OTG_BASE + 0xfc)	/* 16-bit */
+
+/*-------------------------------------------------------------------------*/
+
+/* OMAP1 */
+#define	USB_TRANSCEIVER_CTRL		(0xfffe1000 + 0x0064)
+#	define	CONF_USB2_UNI_R		(1 << 8)
+#	define	CONF_USB1_UNI_R		(1 << 7)
+#	define	CONF_USB_PORT0_R(x)	(((x)>>4)&0x7)
+#	define	CONF_USB0_ISOLATE_R	(1 << 3)
+#	define	CONF_USB_PWRDN_DM_R	(1 << 2)
+#	define	CONF_USB_PWRDN_DP_R	(1 << 1)
+
+/* OMAP2 */
+#	define	USB_UNIDIR			0x0
+#	define	USB_UNIDIR_TLL			0x1
+#	define	USB_BIDIR			0x2
+#	define	USB_BIDIR_TLL			0x3
+#	define	USBTXWRMODEI(port, x)	((x) << (22 - (port * 2)))
+#	define	USBT2TLL5PI		(1 << 17)
+#	define	USB0PUENACTLOI		(1 << 16)
+#	define	USBSTANDBYCTRL		(1 << 15)
+
+#endif	/* __ASM_ARCH_OMAP_USB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/vram.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/vram.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/vram.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/vram.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,62 @@
+/*
+ * VRAM manager for OMAP
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@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.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __OMAP_VRAM_H__
+#define __OMAP_VRAM_H__
+
+#include <linux/types.h>
+
+#define OMAP_VRAM_MEMTYPE_SDRAM		0
+#define OMAP_VRAM_MEMTYPE_SRAM		1
+#define OMAP_VRAM_MEMTYPE_MAX		1
+
+extern int omap_vram_add_region(unsigned long paddr, size_t size);
+extern int omap_vram_free(unsigned long paddr, size_t size);
+extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
+extern int omap_vram_reserve(unsigned long paddr, size_t size);
+extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
+		unsigned long *largest_free_block);
+
+#ifdef CONFIG_OMAP2_VRAM
+extern void omap_vram_set_sdram_vram(u32 size, u32 start);
+extern void omap_vram_set_sram_vram(u32 size, u32 start);
+
+extern void omap_vram_reserve_sdram(void);
+extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+					    unsigned long sram_vstart,
+					    unsigned long sram_size,
+					    unsigned long pstart_avail,
+					    unsigned long size_avail);
+#else
+static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
+static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
+
+static inline void omap_vram_reserve_sdram(void) { }
+static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+					    unsigned long sram_vstart,
+					    unsigned long sram_size,
+					    unsigned long pstart_avail,
+					    unsigned long size_avail)
+{
+	return 0;
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/vrfb.h linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/vrfb.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/include/plat/vrfb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/include/plat/vrfb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,50 @@
+/*
+ * VRFB Rotation Engine
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@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.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __OMAP_VRFB_H__
+#define __OMAP_VRFB_H__
+
+#define OMAP_VRFB_LINE_LEN 2048
+
+struct vrfb {
+	u8 context;
+	void __iomem *vaddr[4];
+	unsigned long paddr[4];
+	u16 xres;
+	u16 yres;
+	u16 xoffset;
+	u16 yoffset;
+	u8 bytespp;
+	bool yuv_mode;
+};
+
+extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
+		u8 bytespp);
+extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
+extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
+extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+		u16 width, u16 height,
+		unsigned bytespp, bool yuv_mode);
+extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
+extern void omap_vrfb_restore_context(void);
+
+#endif /* __VRFB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/io.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/io.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/io.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,12 +13,12 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 
-#include <mach/omap730.h>
-#include <mach/omap1510.h>
-#include <mach/omap16xx.h>
-#include <mach/omap24xx.h>
-#include <mach/omap34xx.h>
-#include <mach/omap44xx.h>
+#include <plat/omap7xx.h>
+#include <plat/omap1510.h>
+#include <plat/omap16xx.h>
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+#include <plat/omap44xx.h>
 
 #define BETWEEN(p,st,sz)	((p) >= (st) && (p) < ((st) + (sz)))
 #define XLATE(p,pst,vst)	((void __iomem *)((p) - (pst) + (vst)))
@@ -33,13 +33,13 @@ void __iomem *omap_ioremap(unsigned long
 		if (BETWEEN(p, OMAP1_IO_PHYS, OMAP1_IO_SIZE))
 			return XLATE(p, OMAP1_IO_PHYS, OMAP1_IO_VIRT);
 	}
-	if (cpu_is_omap730()) {
-		if (BETWEEN(p, OMAP730_DSP_BASE, OMAP730_DSP_SIZE))
-			return XLATE(p, OMAP730_DSP_BASE, OMAP730_DSP_START);
+	if (cpu_is_omap7xx()) {
+		if (BETWEEN(p, OMAP7XX_DSP_BASE, OMAP7XX_DSP_SIZE))
+			return XLATE(p, OMAP7XX_DSP_BASE, OMAP7XX_DSP_START);
 
-		if (BETWEEN(p, OMAP730_DSPREG_BASE, OMAP730_DSPREG_SIZE))
-			return XLATE(p, OMAP730_DSPREG_BASE,
-					OMAP730_DSPREG_START);
+		if (BETWEEN(p, OMAP7XX_DSPREG_BASE, OMAP7XX_DSPREG_SIZE))
+			return XLATE(p, OMAP7XX_DSPREG_BASE,
+					OMAP7XX_DSPREG_START);
 	}
 	if (cpu_is_omap15xx()) {
 		if (BETWEEN(p, OMAP1510_DSP_BASE, OMAP1510_DSP_SIZE))
@@ -66,12 +66,12 @@ void __iomem *omap_ioremap(unsigned long
 			return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT);
 	}
 	if (cpu_is_omap2420()) {
-		if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE))
-			return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT);
-		if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE))
-			return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE);
-		if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE))
-			return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT);
+		if (BETWEEN(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_SIZE))
+			return XLATE(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_VIRT);
+		if (BETWEEN(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE))
+			return XLATE(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE);
+		if (BETWEEN(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_SIZE))
+			return XLATE(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_VIRT);
 	}
 	if (cpu_is_omap2430()) {
 		if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE))
@@ -114,6 +114,14 @@ void __iomem *omap_ioremap(unsigned long
 			return XLATE(p, L4_WK_44XX_PHYS, L4_WK_44XX_VIRT);
 		if (BETWEEN(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_SIZE))
 			return XLATE(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_VIRT);
+		if (BETWEEN(p, OMAP44XX_EMIF1_PHYS, OMAP44XX_EMIF1_SIZE))
+			return XLATE(p, OMAP44XX_EMIF1_PHYS,		\
+							OMAP44XX_EMIF1_VIRT);
+		if (BETWEEN(p, OMAP44XX_EMIF2_PHYS, OMAP44XX_EMIF2_SIZE))
+			return XLATE(p, OMAP44XX_EMIF2_PHYS,		\
+							OMAP44XX_EMIF2_VIRT);
+		if (BETWEEN(p, OMAP44XX_DMM_PHYS, OMAP44XX_DMM_SIZE))
+			return XLATE(p, OMAP44XX_DMM_PHYS, OMAP44XX_DMM_VIRT);
 		if (BETWEEN(p, L4_PER_44XX_PHYS, L4_PER_44XX_SIZE))
 			return XLATE(p, L4_PER_44XX_PHYS, L4_PER_44XX_VIRT);
 		if (BETWEEN(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_SIZE))
@@ -142,7 +150,7 @@ u8 omap_readb(u32 pa)
 	if (cpu_class_is_omap1())
 		return __raw_readb(OMAP1_IO_ADDRESS(pa));
 	else
-		return __raw_readb(OMAP2_IO_ADDRESS(pa));
+		return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_readb);
 
@@ -151,7 +159,7 @@ u16 omap_readw(u32 pa)
 	if (cpu_class_is_omap1())
 		return __raw_readw(OMAP1_IO_ADDRESS(pa));
 	else
-		return __raw_readw(OMAP2_IO_ADDRESS(pa));
+		return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_readw);
 
@@ -160,7 +168,7 @@ u32 omap_readl(u32 pa)
 	if (cpu_class_is_omap1())
 		return __raw_readl(OMAP1_IO_ADDRESS(pa));
 	else
-		return __raw_readl(OMAP2_IO_ADDRESS(pa));
+		return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_readl);
 
@@ -169,7 +177,7 @@ void omap_writeb(u8 v, u32 pa)
 	if (cpu_class_is_omap1())
 		__raw_writeb(v, OMAP1_IO_ADDRESS(pa));
 	else
-		__raw_writeb(v, OMAP2_IO_ADDRESS(pa));
+		__raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_writeb);
 
@@ -178,7 +186,7 @@ void omap_writew(u16 v, u32 pa)
 	if (cpu_class_is_omap1())
 		__raw_writew(v, OMAP1_IO_ADDRESS(pa));
 	else
-		__raw_writew(v, OMAP2_IO_ADDRESS(pa));
+		__raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_writew);
 
@@ -187,6 +195,6 @@ void omap_writel(u32 v, u32 pa)
 	if (cpu_class_is_omap1())
 		__raw_writel(v, OMAP1_IO_ADDRESS(pa));
 	else
-		__raw_writel(v, OMAP2_IO_ADDRESS(pa));
+		__raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
 }
 EXPORT_SYMBOL(omap_writel);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iommu.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@
 
 #include <asm/cacheflush.h>
 
-#include <mach/iommu.h>
+#include <plat/iommu.h>
 
 #include "iopgtable.h"
 
@@ -827,7 +827,7 @@ EXPORT_SYMBOL_GPL(iommu_get);
  **/
 void iommu_put(struct iommu *obj)
 {
-	if (!obj && IS_ERR(obj))
+	if (!obj || IS_ERR(obj))
 		return;
 
 	mutex_lock(&obj->iommu_lock);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iommu-debug.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu-debug.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iommu-debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iommu-debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,8 @@
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
 
-#include <mach/iommu.h>
-#include <mach/iovmm.h>
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
 
 #include "iopgtable.h"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iovmm.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iovmm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/iovmm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/iovmm.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,8 +18,8 @@
 #include <asm/cacheflush.h>
 #include <asm/mach/map.h>
 
-#include <mach/iommu.h>
-#include <mach/iovmm.h>
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
 
 #include "iopgtable.h"
 
@@ -392,7 +392,6 @@ static void sgtable_fill_vmalloc(struct
 	}
 
 	va_end = _va + PAGE_SIZE * i;
-	flush_cache_vmap((unsigned long)_va, (unsigned long)va_end);
 }
 
 static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
@@ -427,8 +426,6 @@ static void sgtable_fill_kmalloc(struct
 		len -= bytes;
 	}
 	BUG_ON(len);
-
-	clean_dcache_area(va, len);
 }
 
 static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
@@ -449,7 +446,7 @@ static int map_iovm_area(struct iommu *o
 	struct scatterlist *sg;
 	u32 da = new->da_start;
 
-	if (!obj || !new || !sgt)
+	if (!obj || !sgt)
 		return -EINVAL;
 
 	BUG_ON(!sgtable_ok(sgt));
@@ -617,7 +614,7 @@ u32 iommu_vmap(struct iommu *obj, u32 da
 		 u32 flags)
 {
 	size_t bytes;
-	void *va;
+	void *va = NULL;
 
 	if (!obj || !obj->dev || !sgt)
 		return -EINVAL;
@@ -627,9 +624,11 @@ u32 iommu_vmap(struct iommu *obj, u32 da
 		return -EINVAL;
 	bytes = PAGE_ALIGN(bytes);
 
-	va = vmap_sg(sgt);
-	if (IS_ERR(va))
-		return PTR_ERR(va);
+	if (flags & IOVMF_MMIO) {
+		va = vmap_sg(sgt);
+		if (IS_ERR(va))
+			return PTR_ERR(va);
+	}
 
 	flags &= IOVMF_HW_MASK;
 	flags |= IOVMF_DISCONT;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-omap/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@ config ARCH_OMAP4
 	bool "TI OMAP4"
 	select CPU_V7
 	select ARM_GIC
+	select COMMON_CLKDEV
 
 endchoice
 
@@ -42,28 +43,6 @@ config OMAP_DEBUG_LEDS
 	depends on OMAP_DEBUG_DEVICES
 	default y if LEDS || LEDS_OMAP_DEBUG
 
-config OMAP_DEBUG_POWERDOMAIN
-	bool "Emit debug messages from powerdomain layer"
-	depends on ARCH_OMAP2 || ARCH_OMAP3
-	help
-	  Say Y here if you want to compile in powerdomain layer
-	  debugging messages for OMAP2/3.   These messages can
-	  provide more detail as to why some powerdomain calls
-	  may be failing, and will also emit a descriptive message
-	  for every powerdomain register write.  However, the
-	  extra detail costs some memory.
-
-config OMAP_DEBUG_CLOCKDOMAIN
-	bool "Emit debug messages from clockdomain layer"
-	depends on ARCH_OMAP2 || ARCH_OMAP3
-	help
-	  Say Y here if you want to compile in clockdomain layer
-	  debugging messages for OMAP2/3.   These messages can
-	  provide more detail as to why some clockdomain calls
-	  may be failing, and will also emit a descriptive message
-	  for every clockdomain register write.  However, the
-	  extra detail costs some memory.
-
 config OMAP_RESET_CLOCKS
 	bool "Reset unused clocks during boot"
 	depends on ARCH_OMAP
@@ -78,28 +57,28 @@ config OMAP_RESET_CLOCKS
 
 config OMAP_MUX
 	bool "OMAP multiplexing support"
-        depends on ARCH_OMAP
+	depends on ARCH_OMAP
 	default y
-        help
-          Pin multiplexing support for OMAP boards. If your bootloader
-          sets the multiplexing correctly, say N. Otherwise, or if unsure,
-          say Y.
+	help
+	  Pin multiplexing support for OMAP boards. If your bootloader
+	  sets the multiplexing correctly, say N. Otherwise, or if unsure,
+	  say Y.
 
 config OMAP_MUX_DEBUG
 	bool "Multiplexing debug output"
-        depends on OMAP_MUX
-        help
-          Makes the multiplexing functions print out a lot of debug info.
-          This is useful if you want to find out the correct values of the
-          multiplexing registers.
+	depends on OMAP_MUX
+	help
+	  Makes the multiplexing functions print out a lot of debug info.
+	  This is useful if you want to find out the correct values of the
+	  multiplexing registers.
 
 config OMAP_MUX_WARNINGS
 	bool "Warn about pins the bootloader didn't set up"
-        depends on OMAP_MUX
-        default y
-        help
+	depends on OMAP_MUX
+	default y
+	help
 	  Choose Y here to warn whenever driver initialization logic needs
-	  to change the pin multiplexing setup.  When there are no 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_MCBSP
@@ -125,7 +104,7 @@ config OMAP_IOMMU_DEBUG
 	tristate
 
 choice
-        prompt "System timer"
+	prompt "System timer"
 	default OMAP_MPU_TIMER
 
 config OMAP_MPU_TIMER
@@ -148,11 +127,11 @@ config OMAP_32K_TIMER
 endchoice
 
 config OMAP_32K_TIMER_HZ
-       int "Kernel internal timer frequency for 32KHz timer"
-       range 32 1024
-       depends on OMAP_32K_TIMER
-       default "128"
-       help
+	int "Kernel internal timer frequency for 32KHz timer"
+	range 32 1024
+	depends on OMAP_32K_TIMER
+	default "128"
+	help
 	  Kernel internal timer frequency should be a divisor of 32768,
 	  such as 64 or 128.
 
@@ -165,7 +144,7 @@ config OMAP_DM_TIMER
 choice
 	prompt "Low-level debug console UART"
 	depends on ARCH_OMAP
-	default OMAP_LL_DEBUG_UART1
+	default OMAP_LL_DEBUG_NONE
 
 config OMAP_LL_DEBUG_UART1
 	bool "UART1"
@@ -176,6 +155,9 @@ config OMAP_LL_DEBUG_UART2
 config OMAP_LL_DEBUG_UART3
 	bool "UART3"
 
+config OMAP_LL_DEBUG_NONE
+	bool "None"
+
 endchoice
 
 config OMAP_SERIAL_WAKE
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mailbox.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mailbox.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mailbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mailbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,55 +26,12 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 
-#include <mach/mailbox.h>
-
-static int enable_seq_bit;
-module_param(enable_seq_bit, bool, 0);
-MODULE_PARM_DESC(enable_seq_bit, "Enable sequence bit checking.");
+#include <plat/mailbox.h>
 
 static struct omap_mbox *mboxes;
 static DEFINE_RWLOCK(mboxes_lock);
 
-/*
- * Mailbox sequence bit API
- */
-
-/* seq_rcv should be initialized with any value other than
- * 0 and 1 << 31, to allow either value for the first
- * message.  */
-static inline void mbox_seq_init(struct omap_mbox *mbox)
-{
-	if (!enable_seq_bit)
-		return;
-
-	/* any value other than 0 and 1 << 31 */
-	mbox->seq_rcv = 0xffffffff;
-}
-
-static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
-{
-	if (!enable_seq_bit)
-		return;
-
-	/* add seq_snd to msg */
-	*msg = (*msg & 0x7fffffff) | mbox->seq_snd;
-	/* flip seq_snd */
-	mbox->seq_snd ^= 1 << 31;
-}
-
-static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	mbox_msg_t seq;
-
-	if (!enable_seq_bit)
-		return 0;
-
-	seq = msg & (1 << 31);
-	if (seq == mbox->seq_rcv)
-		return -1;
-	mbox->seq_rcv = seq;
-	return 0;
-}
+static int mbox_configured;
 
 /* Mailbox FIFO handle functions */
 static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
@@ -95,14 +52,6 @@ static inline int mbox_fifo_full(struct
 }
 
 /* Mailbox IRQ handle functions */
-static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	mbox->ops->enable_irq(mbox, irq);
-}
-static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	mbox->ops->disable_irq(mbox, irq);
-}
 static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
 {
 	if (mbox->ops->ack_irq)
@@ -113,17 +62,10 @@ static inline int is_mbox_irq(struct oma
 	return mbox->ops->is_irq(mbox, irq);
 }
 
-/* Mailbox Sequence Bit function */
-void omap_mbox_init_seq(struct omap_mbox *mbox)
-{
-	mbox_seq_init(mbox);
-}
-EXPORT_SYMBOL(omap_mbox_init_seq);
-
 /*
  * message sender
  */
-static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg)
+static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
 {
 	int ret = 0, i = 1000;
 
@@ -134,89 +76,49 @@ static int __mbox_msg_send(struct omap_m
 			return -1;
 		udelay(1);
 	}
-
-	if (arg && mbox->txq->callback) {
-		ret = mbox->txq->callback(arg);
-		if (ret)
-			goto out;
-	}
-
-	mbox_seq_toggle(mbox, &msg);
 	mbox_fifo_write(mbox, msg);
- out:
 	return ret;
 }
 
-struct omap_msg_tx_data {
-	mbox_msg_t	msg;
-	void		*arg;
-};
 
-static void omap_msg_tx_end_io(struct request *rq, int error)
+int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
 {
-	kfree(rq->special);
-	__blk_put_request(rq->q, rq);
-}
 
-int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
-{
-	struct omap_msg_tx_data *tx_data;
 	struct request *rq;
 	struct request_queue *q = mbox->txq->queue;
 
-	tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC);
-	if (unlikely(!tx_data))
-		return -ENOMEM;
-
 	rq = blk_get_request(q, WRITE, GFP_ATOMIC);
-	if (unlikely(!rq)) {
-		kfree(tx_data);
+	if (unlikely(!rq))
 		return -ENOMEM;
-	}
 
-	tx_data->msg = msg;
-	tx_data->arg = arg;
-	rq->end_io = omap_msg_tx_end_io;
-	blk_insert_request(q, rq, 0, tx_data);
+	blk_insert_request(q, rq, 0, (void *) msg);
+	tasklet_schedule(&mbox->txq->tasklet);
 
-	schedule_work(&mbox->txq->work);
 	return 0;
 }
 EXPORT_SYMBOL(omap_mbox_msg_send);
 
-static void mbox_tx_work(struct work_struct *work)
+static void mbox_tx_tasklet(unsigned long tx_data)
 {
 	int ret;
 	struct request *rq;
-	struct omap_mbox_queue *mq = container_of(work,
-				struct omap_mbox_queue, work);
-	struct omap_mbox *mbox = mq->queue->queuedata;
+	struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
 	struct request_queue *q = mbox->txq->queue;
 
 	while (1) {
-		struct omap_msg_tx_data *tx_data;
 
-		spin_lock(q->queue_lock);
 		rq = blk_fetch_request(q);
-		spin_unlock(q->queue_lock);
 
 		if (!rq)
 			break;
 
-		tx_data = rq->special;
-
-		ret = __mbox_msg_send(mbox, tx_data->msg, tx_data->arg);
+		ret = __mbox_msg_send(mbox, (mbox_msg_t)rq->special);
 		if (ret) {
-			enable_mbox_irq(mbox, IRQ_TX);
-			spin_lock(q->queue_lock);
+			omap_mbox_enable_irq(mbox, IRQ_TX);
 			blk_requeue_request(q, rq);
-			spin_unlock(q->queue_lock);
 			return;
 		}
-
-		spin_lock(q->queue_lock);
-		__blk_end_request_all(rq, 0);
-		spin_unlock(q->queue_lock);
+		blk_end_request_all(rq, 0);
 	}
 }
 
@@ -233,11 +135,6 @@ static void mbox_rx_work(struct work_str
 	mbox_msg_t msg;
 	unsigned long flags;
 
-	if (mbox->rxq->callback == NULL) {
-		sysfs_notify(&mbox->dev->kobj, NULL, "mbox");
-		return;
-	}
-
 	while (1) {
 		spin_lock_irqsave(q->queue_lock, flags);
 		rq = blk_fetch_request(q);
@@ -254,19 +151,19 @@ static void mbox_rx_work(struct work_str
 /*
  * Mailbox interrupt handler
  */
-static void mbox_txq_fn(struct request_queue * q)
+static void mbox_txq_fn(struct request_queue *q)
 {
 }
 
-static void mbox_rxq_fn(struct request_queue * q)
+static void mbox_rxq_fn(struct request_queue *q)
 {
 }
 
 static void __mbox_tx_interrupt(struct omap_mbox *mbox)
 {
-	disable_mbox_irq(mbox, IRQ_TX);
+	omap_mbox_disable_irq(mbox, IRQ_TX);
 	ack_mbox_irq(mbox, IRQ_TX);
-	schedule_work(&mbox->txq->work);
+	tasklet_schedule(&mbox->txq->tasklet);
 }
 
 static void __mbox_rx_interrupt(struct omap_mbox *mbox)
@@ -275,8 +172,6 @@ static void __mbox_rx_interrupt(struct o
 	mbox_msg_t msg;
 	struct request_queue *q = mbox->rxq->queue;
 
-	disable_mbox_irq(mbox, IRQ_RX);
-
 	while (!mbox_fifo_empty(mbox)) {
 		rq = blk_get_request(q, WRITE, GFP_ATOMIC);
 		if (unlikely(!rq))
@@ -284,11 +179,6 @@ static void __mbox_rx_interrupt(struct o
 
 		msg = mbox_fifo_read(mbox);
 
-		if (unlikely(mbox_seq_test(mbox, msg))) {
-			pr_info("mbox: Illegal seq bit!(%08x)\n", msg);
-			if (mbox->err_notify)
-				mbox->err_notify();
-		}
 
 		blk_insert_request(q, rq, 0, (void *)msg);
 		if (mbox->ops->type == OMAP_MBOX_TYPE1)
@@ -297,7 +187,6 @@ static void __mbox_rx_interrupt(struct o
 
 	/* no more messages in the fifo. clear IRQ source. */
 	ack_mbox_irq(mbox, IRQ_RX);
-	enable_mbox_irq(mbox, IRQ_RX);
 nomem:
 	schedule_work(&mbox->rxq->work);
 }
@@ -315,76 +204,10 @@ static irqreturn_t mbox_interrupt(int ir
 	return IRQ_HANDLED;
 }
 
-/*
- * sysfs files
- */
-static ssize_t
-omap_mbox_write(struct device *dev, struct device_attribute *attr,
-		const char * buf, size_t count)
-{
-	int ret;
-	mbox_msg_t *p = (mbox_msg_t *)buf;
-	struct omap_mbox *mbox = dev_get_drvdata(dev);
-
-	for (; count >= sizeof(mbox_msg_t); count -= sizeof(mbox_msg_t)) {
-		ret = omap_mbox_msg_send(mbox, be32_to_cpu(*p), NULL);
-		if (ret)
-			return -EAGAIN;
-		p++;
-	}
-
-	return (size_t)((char *)p - buf);
-}
-
-static ssize_t
-omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	unsigned long flags;
-	struct request *rq;
-	mbox_msg_t *p = (mbox_msg_t *) buf;
-	struct omap_mbox *mbox = dev_get_drvdata(dev);
-	struct request_queue *q = mbox->rxq->queue;
-
-	while (1) {
-		spin_lock_irqsave(q->queue_lock, flags);
-		rq = blk_fetch_request(q);
-		spin_unlock_irqrestore(q->queue_lock, flags);
-
-		if (!rq)
-			break;
-
-		*p = (mbox_msg_t)rq->special;
-
-		blk_end_request_all(rq, 0);
-
-		if (unlikely(mbox_seq_test(mbox, *p))) {
-			pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
-			continue;
-		}
-		p++;
-	}
-
-	pr_debug("%02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
-
-	return (size_t) ((char *)p - buf);
-}
-
-static DEVICE_ATTR(mbox, S_IRUGO | S_IWUSR, omap_mbox_read, omap_mbox_write);
-
-static ssize_t mbox_show(struct class *class, char *buf)
-{
-	return sprintf(buf, "mbox");
-}
-
-static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
-
-static struct class omap_mbox_class = {
-	.name = "omap-mailbox",
-};
-
 static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
-					request_fn_proc * proc,
-					void (*work) (struct work_struct *))
+					request_fn_proc *proc,
+					void (*work) (struct work_struct *),
+					void (*tasklet)(unsigned long))
 {
 	struct request_queue *q;
 	struct omap_mbox_queue *mq;
@@ -401,8 +224,11 @@ static struct omap_mbox_queue *mbox_queu
 	q->queuedata = mbox;
 	mq->queue = q;
 
-	INIT_WORK(&mq->work, work);
+	if (work)
+		INIT_WORK(&mq->work, work);
 
+	if (tasklet)
+		tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
 	return mq;
 error:
 	kfree(mq);
@@ -415,18 +241,25 @@ static void mbox_queue_free(struct omap_
 	kfree(q);
 }
 
-static int omap_mbox_init(struct omap_mbox *mbox)
+static int omap_mbox_startup(struct omap_mbox *mbox)
 {
-	int ret;
+	int ret = 0;
 	struct omap_mbox_queue *mq;
 
 	if (likely(mbox->ops->startup)) {
-		ret = mbox->ops->startup(mbox);
-		if (unlikely(ret))
+		write_lock(&mboxes_lock);
+		if (!mbox_configured)
+			ret = mbox->ops->startup(mbox);
+
+		if (unlikely(ret)) {
+			write_unlock(&mboxes_lock);
 			return ret;
+		}
+		mbox_configured++;
+		write_unlock(&mboxes_lock);
 	}
 
-	ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
+	ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
 				mbox->name, mbox);
 	if (unlikely(ret)) {
 		printk(KERN_ERR
@@ -434,14 +267,14 @@ static int omap_mbox_init(struct omap_mb
 		goto fail_request_irq;
 	}
 
-	mq = mbox_queue_alloc(mbox, mbox_txq_fn, mbox_tx_work);
+	mq = mbox_queue_alloc(mbox, mbox_txq_fn, NULL, mbox_tx_tasklet);
 	if (!mq) {
 		ret = -ENOMEM;
 		goto fail_alloc_txq;
 	}
 	mbox->txq = mq;
 
-	mq = mbox_queue_alloc(mbox, mbox_rxq_fn, mbox_rx_work);
+	mq = mbox_queue_alloc(mbox, mbox_rxq_fn, mbox_rx_work, NULL);
 	if (!mq) {
 		ret = -ENOMEM;
 		goto fail_alloc_rxq;
@@ -468,8 +301,14 @@ static void omap_mbox_fini(struct omap_m
 
 	free_irq(mbox->irq, mbox);
 
-	if (unlikely(mbox->ops->shutdown))
-		mbox->ops->shutdown(mbox);
+	if (unlikely(mbox->ops->shutdown)) {
+		write_lock(&mboxes_lock);
+		if (mbox_configured > 0)
+			mbox_configured--;
+		if (!mbox_configured)
+			mbox->ops->shutdown(mbox);
+		write_unlock(&mboxes_lock);
+	}
 }
 
 static struct omap_mbox **find_mboxes(const char *name)
@@ -498,7 +337,7 @@ struct omap_mbox *omap_mbox_get(const ch
 
 	read_unlock(&mboxes_lock);
 
-	ret = omap_mbox_init(mbox);
+	ret = omap_mbox_startup(mbox);
 	if (ret)
 		return ERR_PTR(-ENODEV);
 
@@ -522,15 +361,6 @@ int omap_mbox_register(struct device *pa
 	if (mbox->next)
 		return -EBUSY;
 
-	mbox->dev = device_create(&omap_mbox_class,
-				  parent, 0, mbox, "%s", mbox->name);
-	if (IS_ERR(mbox->dev))
-		return PTR_ERR(mbox->dev);
-
-	ret = device_create_file(mbox->dev, &dev_attr_mbox);
-	if (ret)
-		goto err_sysfs;
-
 	write_lock(&mboxes_lock);
 	tmp = find_mboxes(mbox->name);
 	if (*tmp) {
@@ -544,9 +374,6 @@ int omap_mbox_register(struct device *pa
 	return 0;
 
 err_find:
-	device_remove_file(mbox->dev, &dev_attr_mbox);
-err_sysfs:
-	device_unregister(mbox->dev);
 	return ret;
 }
 EXPORT_SYMBOL(omap_mbox_register);
@@ -562,8 +389,6 @@ int omap_mbox_unregister(struct omap_mbo
 			*tmp = mbox->next;
 			mbox->next = NULL;
 			write_unlock(&mboxes_lock);
-			device_remove_file(mbox->dev, &dev_attr_mbox);
-			device_unregister(mbox->dev);
 			return 0;
 		}
 		tmp = &(*tmp)->next;
@@ -574,23 +399,16 @@ int omap_mbox_unregister(struct omap_mbo
 }
 EXPORT_SYMBOL(omap_mbox_unregister);
 
-static int __init omap_mbox_class_init(void)
+static int __init omap_mbox_init(void)
 {
-	int ret = class_register(&omap_mbox_class);
-	if (!ret)
-		ret = class_create_file(&omap_mbox_class, &class_attr_mbox);
-
-	return ret;
+	return 0;
 }
+module_init(omap_mbox_init);
 
-static void __exit omap_mbox_class_exit(void)
+static void __exit omap_mbox_exit(void)
 {
-	class_remove_file(&omap_mbox_class, &class_attr_mbox);
-	class_unregister(&omap_mbox_class);
 }
-
-subsys_initcall(omap_mbox_class_init);
-module_exit(omap_mbox_class_exit);
+module_exit(omap_mbox_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mcbsp.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mcbsp.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mcbsp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mcbsp.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,8 +24,8 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include <mach/dma.h>
-#include <mach/mcbsp.h>
+#include <plat/dma.h>
+#include <plat/mcbsp.h>
 
 struct omap_mcbsp **mcbsp_ptr;
 int omap_mcbsp_count;
@@ -298,9 +298,7 @@ int omap_mcbsp_get_dma_op_mode(unsigned
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
-	spin_lock_irq(&mcbsp->lock);
 	dma_op_mode = mcbsp->dma_op_mode;
-	spin_unlock_irq(&mcbsp->lock);
 
 	return dma_op_mode;
 }
@@ -318,7 +316,6 @@ static inline void omap34xx_mcbsp_reques
 		syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 
-		spin_lock_irq(&mcbsp->lock);
 		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
 					CLOCKACTIVITY(0x02));
@@ -327,7 +324,6 @@ static inline void omap34xx_mcbsp_reques
 		} else {
 			syscon |= SIDLEMODE(0x01);
 		}
-		spin_unlock_irq(&mcbsp->lock);
 
 		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 	}
@@ -440,7 +436,7 @@ int omap_mcbsp_request(unsigned int id)
 			dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
 					"for McBSP%d\n", mcbsp->tx_irq,
 					mcbsp->id);
-			return err;
+			goto error;
 		}
 
 		init_completion(&mcbsp->rx_irq_completion);
@@ -450,12 +446,26 @@ int omap_mcbsp_request(unsigned int id)
 			dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
 					"for McBSP%d\n", mcbsp->rx_irq,
 					mcbsp->id);
-			free_irq(mcbsp->tx_irq, (void *)mcbsp);
-			return err;
+			goto tx_irq;
 		}
 	}
 
 	return 0;
+tx_irq:
+	free_irq(mcbsp->tx_irq, (void *)mcbsp);
+error:
+	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
+			mcbsp->pdata->ops->free(id);
+
+	/* Do procedure specific to omap34xx arch, if applicable */
+	omap34xx_mcbsp_free(mcbsp);
+
+	clk_disable(mcbsp->fclk);
+	clk_disable(mcbsp->iclk);
+
+	mcbsp->free = 1;
+
+	return err;
 }
 EXPORT_SYMBOL(omap_mcbsp_request);
 
@@ -1145,9 +1155,7 @@ static ssize_t dma_op_mode_show(struct d
 	ssize_t len = 0;
 	const char * const *s;
 
-	spin_lock_irq(&mcbsp->lock);
 	dma_op_mode = mcbsp->dma_op_mode;
-	spin_unlock_irq(&mcbsp->lock);
 
 	for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
 		if (dma_op_mode == i)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mux.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mux.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/mux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/mux.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@
 #include <linux/io.h>
 #include <asm/system.h>
 #include <linux/spinlock.h>
-#include <mach/mux.h>
+#include <plat/mux.h>
 
 #ifdef CONFIG_OMAP_MUX
 
@@ -54,8 +54,12 @@ int __init_or_module omap_cfg_reg(const
 {
 	struct pin_config *reg;
 
-	if (cpu_is_omap44xx())
-		return 0;
+	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+		printk(KERN_ERR "mux: Broken omap_cfg_reg(%lu) entry\n",
+				index);
+		WARN_ON(1);
+		return -EINVAL;
+	}
 
 	if (mux_cfg == NULL) {
 		printk(KERN_ERR "Pin mux table not initialized\n");
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/omap_device.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap_device.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/omap_device.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap_device.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,42 +82,17 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
-#include <mach/omap_device.h>
-#include <mach/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/omap_hwmod.h>
 
 /* These parameters are passed to _omap_device_{de,}activate() */
 #define USE_WAKEUP_LAT			0
 #define IGNORE_WAKEUP_LAT		1
 
-/* XXX this should be moved into a separate file */
-#if defined(CONFIG_ARCH_OMAP2420)
-# define OMAP_32KSYNCT_BASE		0x48004000
-#elif defined(CONFIG_ARCH_OMAP2430)
-# define OMAP_32KSYNCT_BASE		0x49020000
-#elif defined(CONFIG_ARCH_OMAP3430)
-# define OMAP_32KSYNCT_BASE		0x48320000
-#else
-# error Unknown OMAP device
-#endif
 
 /* Private functions */
 
 /**
- * _read_32ksynct - read the OMAP 32K sync timer
- *
- * Returns the current value of the 32KiHz synchronization counter.
- * XXX this should be generalized to simply read the system clocksource.
- * XXX this should be moved to a separate synctimer32k.c file
- */
-static u32 _read_32ksynct(void)
-{
-	if (!cpu_class_is_omap2())
-		BUG();
-
-	return __raw_readl(OMAP2_IO_ADDRESS(OMAP_32KSYNCT_BASE + 0x010));
-}
-
-/**
  * _omap_device_activate - increase device readiness
  * @od: struct omap_device *
  * @ignore_lat: increase to latency target (0) or full readiness (1)?
@@ -133,13 +108,13 @@ static u32 _read_32ksynct(void)
  */
 static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
 {
-	u32 a, b;
+	struct timespec a, b, c;
 
 	pr_debug("omap_device: %s: activating\n", od->pdev.name);
 
 	while (od->pm_lat_level > 0) {
 		struct omap_device_pm_latency *odpl;
-		int act_lat = 0;
+		unsigned long long act_lat = 0;
 
 		od->pm_lat_level--;
 
@@ -149,20 +124,22 @@ static int _omap_device_activate(struct
 		    (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
 			break;
 
-		a = _read_32ksynct();
+		read_persistent_clock(&a);
 
 		/* XXX check return code */
 		odpl->activate_func(od);
 
-		b = _read_32ksynct();
+		read_persistent_clock(&b);
 
-		act_lat = (b - a) >> 15; /* 32KiHz cycles to microseconds */
+		c = timespec_sub(b, a);
+		act_lat = timespec_to_ns(&c);
 
 		pr_debug("omap_device: %s: pm_lat %d: activate: elapsed time "
-			 "%d usec\n", od->pdev.name, od->pm_lat_level, act_lat);
+			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
+			 act_lat);
 
 		WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: "
-		     "activate step %d took longer than expected (%d > %d)\n",
+		     "activate step %d took longer than expected (%llu > %d)\n",
 		     od->pdev.name, od->pdev.id, od->pm_lat_level,
 		     act_lat, odpl->activate_lat);
 
@@ -188,13 +165,13 @@ static int _omap_device_activate(struct
  */
 static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
 {
-	u32 a, b;
+	struct timespec a, b, c;
 
 	pr_debug("omap_device: %s: deactivating\n", od->pdev.name);
 
 	while (od->pm_lat_level < od->pm_lats_cnt) {
 		struct omap_device_pm_latency *odpl;
-		int deact_lat = 0;
+		unsigned long long deact_lat = 0;
 
 		odpl = od->pm_lats + od->pm_lat_level;
 
@@ -203,23 +180,24 @@ static int _omap_device_deactivate(struc
 		     od->_dev_wakeup_lat_limit))
 			break;
 
-		a = _read_32ksynct();
+		read_persistent_clock(&a);
 
 		/* XXX check return code */
 		odpl->deactivate_func(od);
 
-		b = _read_32ksynct();
+		read_persistent_clock(&b);
 
-		deact_lat = (b - a) >> 15; /* 32KiHz cycles to microseconds */
+		c = timespec_sub(b, a);
+		deact_lat = timespec_to_ns(&c);
 
 		pr_debug("omap_device: %s: pm_lat %d: deactivate: elapsed time "
-			 "%d usec\n", od->pdev.name, od->pm_lat_level,
+			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
 			 deact_lat);
 
 		WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: "
-		     "deactivate step %d took longer than expected (%d > %d)\n",
-		     od->pdev.name, od->pdev.id, od->pm_lat_level,
-		     deact_lat, odpl->deactivate_lat);
+		     "deactivate step %d took longer than expected "
+		     "(%llu > %d)\n", od->pdev.name, od->pdev.id,
+		     od->pm_lat_level, deact_lat, odpl->deactivate_lat);
 
 		od->dev_wakeup_lat += odpl->activate_lat;
 
@@ -471,7 +449,7 @@ int omap_device_enable(struct platform_d
 	ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT);
 
 	od->dev_wakeup_lat = 0;
-	od->_dev_wakeup_lat_limit = INT_MAX;
+	od->_dev_wakeup_lat_limit = UINT_MAX;
 	od->_state = OMAP_DEVICE_STATE_ENABLED;
 
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/omap-pm-noop.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap-pm-noop.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/omap-pm-noop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/omap-pm-noop.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,9 +22,9 @@
 #include <linux/device.h>
 
 /* Interface documentation is in mach/omap-pm.h */
-#include <mach/omap-pm.h>
+#include <plat/omap-pm.h>
 
-#include <mach/powerdomain.h>
+#include <plat/powerdomain.h>
 
 struct omap_opp *dsp_opps;
 struct omap_opp *mpu_opps;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/sram.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/sram.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/sram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/sram.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,11 +25,12 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/sram.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
+#include <plat/sram.h>
+#include <plat/board.h>
+#include <plat/cpu.h>
+#include <plat/vram.h>
 
-#include <mach/control.h>
+#include <plat/control.h>
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 # include "../mach-omap2/prm.h"
@@ -41,14 +42,16 @@
 #define OMAP1_SRAM_VA		VMALLOC_END
 #define OMAP2_SRAM_PA		0x40200000
 #define OMAP2_SRAM_PUB_PA	0x4020f800
-#define OMAP2_SRAM_VA		0xe3000000
+#define OMAP2_SRAM_VA		0xfe400000
 #define OMAP2_SRAM_PUB_VA	(OMAP2_SRAM_VA + 0x800)
 #define OMAP3_SRAM_PA           0x40200000
-#define OMAP3_SRAM_VA           0xe3000000
+#define OMAP3_SRAM_VA           0xfe400000
 #define OMAP3_SRAM_PUB_PA       0x40208000
 #define OMAP3_SRAM_PUB_VA       (OMAP3_SRAM_VA + 0x8000)
-#define OMAP4_SRAM_PA		0x40200000		/*0x402f0000*/
-#define OMAP4_SRAM_VA		0xd7000000		/*0xd70f0000*/
+#define OMAP4_SRAM_PA		0x40300000
+#define OMAP4_SRAM_VA		0xfe400000
+#define OMAP4_SRAM_PUB_PA	(OMAP4_SRAM_PA + 0x4000)
+#define OMAP4_SRAM_PUB_VA	(OMAP4_SRAM_VA + 0x4000)
 
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 #define SRAM_BOOTLOADER_SZ	0x00
@@ -56,16 +59,16 @@
 #define SRAM_BOOTLOADER_SZ	0x80
 #endif
 
-#define OMAP24XX_VA_REQINFOPERM0	OMAP2_IO_ADDRESS(0x68005048)
-#define OMAP24XX_VA_READPERM0		OMAP2_IO_ADDRESS(0x68005050)
-#define OMAP24XX_VA_WRITEPERM0		OMAP2_IO_ADDRESS(0x68005058)
+#define OMAP24XX_VA_REQINFOPERM0	OMAP2_L3_IO_ADDRESS(0x68005048)
+#define OMAP24XX_VA_READPERM0		OMAP2_L3_IO_ADDRESS(0x68005050)
+#define OMAP24XX_VA_WRITEPERM0		OMAP2_L3_IO_ADDRESS(0x68005058)
 
-#define OMAP34XX_VA_REQINFOPERM0	OMAP2_IO_ADDRESS(0x68012848)
-#define OMAP34XX_VA_READPERM0		OMAP2_IO_ADDRESS(0x68012850)
-#define OMAP34XX_VA_WRITEPERM0		OMAP2_IO_ADDRESS(0x68012858)
-#define OMAP34XX_VA_ADDR_MATCH2		OMAP2_IO_ADDRESS(0x68012880)
-#define OMAP34XX_VA_SMS_RG_ATT0		OMAP2_IO_ADDRESS(0x6C000048)
-#define OMAP34XX_VA_CONTROL_STAT	OMAP2_IO_ADDRESS(0x480022F0)
+#define OMAP34XX_VA_REQINFOPERM0	OMAP2_L3_IO_ADDRESS(0x68012848)
+#define OMAP34XX_VA_READPERM0		OMAP2_L3_IO_ADDRESS(0x68012850)
+#define OMAP34XX_VA_WRITEPERM0		OMAP2_L3_IO_ADDRESS(0x68012858)
+#define OMAP34XX_VA_ADDR_MATCH2		OMAP2_L3_IO_ADDRESS(0x68012880)
+#define OMAP34XX_VA_SMS_RG_ATT0		OMAP2_L3_IO_ADDRESS(0x6C000048)
+#define OMAP34XX_VA_CONTROL_STAT	OMAP2_L4_IO_ADDRESS(0x480022F0)
 
 #define GP_DEVICE		0x300
 
@@ -139,6 +142,10 @@ void __init omap_detect_sram(void)
 				} else {
 					omap_sram_size = 0x8000; /* 32K */
 				}
+			} else if (cpu_is_omap44xx()) {
+				omap_sram_base = OMAP4_SRAM_PUB_VA;
+				omap_sram_start = OMAP4_SRAM_PUB_PA;
+				omap_sram_size = 0xa000; /* 40K */
 			} else {
 				omap_sram_base = OMAP2_SRAM_PUB_VA;
 				omap_sram_start = OMAP2_SRAM_PUB_PA;
@@ -152,7 +159,7 @@ void __init omap_detect_sram(void)
 			} else if (cpu_is_omap44xx()) {
 				omap_sram_base = OMAP4_SRAM_VA;
 				omap_sram_start = OMAP4_SRAM_PA;
-				omap_sram_size = 0x8000; /* 32K */
+				omap_sram_size = 0xe000; /* 56K */
 			} else {
 				omap_sram_base = OMAP2_SRAM_VA;
 				omap_sram_start = OMAP2_SRAM_PA;
@@ -185,6 +192,13 @@ void __init omap_detect_sram(void)
 				       omap_sram_start + SRAM_BOOTLOADER_SZ,
 				       omap_sram_size - SRAM_BOOTLOADER_SZ);
 	omap_sram_size -= reserved;
+
+	reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base,
+			omap_sram_size,
+			omap_sram_start + SRAM_BOOTLOADER_SZ,
+			omap_sram_size - SRAM_BOOTLOADER_SZ);
+	omap_sram_size -= reserved;
+
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 }
 
@@ -396,22 +410,24 @@ u32 omap3_configure_core_dpll(u32 m2, u3
 			sdrc_actim_ctrl_b_1, sdrc_mr_1);
 }
 
-/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
-void restore_sram_functions(void)
+#ifdef CONFIG_PM
+void omap3_sram_restore_context(void)
 {
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 
 	_omap3_sram_configure_core_dpll =
 		omap_sram_push(omap3_sram_configure_core_dpll,
 			       omap3_sram_configure_core_dpll_sz);
+	omap_push_sram_idle();
 }
+#endif /* CONFIG_PM */
 
 int __init omap34xx_sram_init(void)
 {
 	_omap3_sram_configure_core_dpll =
 		omap_sram_push(omap3_sram_configure_core_dpll,
 			       omap3_sram_configure_core_dpll_sz);
-
+	omap_push_sram_idle();
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-omap/usb.c linux-libre-2.6.33-gnu1/arch/arm/plat-omap/usb.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-omap/usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-omap/usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,10 +33,10 @@
 #include <asm/system.h>
 #include <mach/hardware.h>
 
-#include <mach/control.h>
-#include <mach/mux.h>
-#include <mach/usb.h>
-#include <mach/board.h>
+#include <plat/control.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
 
 #ifdef CONFIG_ARCH_OMAP1
 
@@ -137,7 +137,13 @@ static u32 __init omap_usb0_init(unsigne
 	if (is_device) {
 		if (cpu_is_omap24xx())
 			omap_cfg_reg(J20_24XX_USB0_PUEN);
-		else
+		else if (cpu_is_omap7xx()) {
+			omap_cfg_reg(AA17_7XX_USB_DM);
+			omap_cfg_reg(W16_7XX_USB_PU_EN);
+			omap_cfg_reg(W17_7XX_USB_VBUSI);
+			omap_cfg_reg(W18_7XX_USB_DMCK_OUT);
+			omap_cfg_reg(W19_7XX_USB_DCRST);
+		} else
 			omap_cfg_reg(W4_USB_PUEN);
 	}
 
@@ -159,11 +165,14 @@ static u32 __init omap_usb0_init(unsigne
 		 *  - OTG support on this port not yet written
 		 */
 
-		l = omap_readl(USB_TRANSCEIVER_CTRL);
-		l &= ~(7 << 4);
-		if (!is_device)
-			l |= (3 << 1);
-		omap_writel(l, USB_TRANSCEIVER_CTRL);
+		/* Don't do this for omap7xx -- it causes USB to not work correctly */
+		if (!cpu_is_omap7xx()) {
+			l = omap_readl(USB_TRANSCEIVER_CTRL);
+			l &= ~(7 << 4);
+			if (!is_device)
+				l |= (3 << 1);
+			omap_writel(l, USB_TRANSCEIVER_CTRL);
+		}
 
 		return 3 << 16;
 	}
@@ -603,7 +612,12 @@ omap_otg_init(struct omap_usb_config *co
 	if (config->otg || config->register_dev) {
 		syscon &= ~DEV_IDLE_EN;
 		udc_device.dev.platform_data = config;
-		/* FIXME patch IRQ numbers for omap730 */
+		/* IRQ numbers for omap7xx */
+		if(cpu_is_omap7xx()) {
+			udc_resources[1].start = INT_7XX_USB_GENI;
+			udc_resources[2].start = INT_7XX_USB_NON_ISO;
+			udc_resources[3].start = INT_7XX_USB_ISO;
+		}
 		status = platform_device_register(&udc_device);
 		if (status)
 			pr_debug("can't register UDC device, %d\n", status);
@@ -614,8 +628,8 @@ omap_otg_init(struct omap_usb_config *co
 	if (config->otg || config->register_host) {
 		syscon &= ~HST_IDLE_EN;
 		ohci_device.dev.platform_data = config;
-		if (cpu_is_omap730())
-			ohci_resources[1].start = INT_730_USB_HHC_1;
+		if (cpu_is_omap7xx())
+			ohci_resources[1].start = INT_7XX_USB_HHC_1;
 		status = platform_device_register(&ohci_device);
 		if (status)
 			pr_debug("can't register OHCI device, %d\n", status);
@@ -626,8 +640,8 @@ omap_otg_init(struct omap_usb_config *co
 	if (config->otg) {
 		syscon &= ~OTG_IDLE_EN;
 		otg_device.dev.platform_data = config;
-		if (cpu_is_omap730())
-			otg_resources[1].start = INT_730_USB_OTG;
+		if (cpu_is_omap7xx())
+			otg_resources[1].start = INT_7XX_USB_OTG;
 		status = platform_device_register(&otg_device);
 		if (status)
 			pr_debug("can't register OTG device, %d\n", status);
@@ -731,7 +745,7 @@ static inline void omap_1510_usb_init(st
 
 void __init omap_usb_init(struct omap_usb_config *pdata)
 {
-	if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
+	if (cpu_is_omap7xx() || cpu_is_omap16xx() || cpu_is_omap24xx())
 		omap_otg_init(pdata);
 	else if (cpu_is_omap15xx())
 		omap_1510_usb_init(pdata);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-orion/pcie.c linux-libre-2.6.33-gnu1/arch/arm/plat-orion/pcie.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-orion/pcie.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-orion/pcie.c	2010-02-24 13:52:17.000000000 -0500
@@ -133,6 +133,12 @@ static void __init orion_pcie_setup_wins
 	}
 
 	/*
+	 * 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, base + PCIE_BAR_LO_OFF(1));
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,63 @@
+#ifndef __ASM_ARCH_PXA3XX_NAND_H
+#define __ASM_ARCH_PXA3XX_NAND_H
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+struct pxa3xx_nand_timing {
+	unsigned int	tCH;  /* Enable signal hold time */
+	unsigned int	tCS;  /* Enable signal setup time */
+	unsigned int	tWH;  /* ND_nWE high duration */
+	unsigned int	tWP;  /* ND_nWE pulse time */
+	unsigned int	tRH;  /* ND_nRE high duration */
+	unsigned int	tRP;  /* ND_nRE pulse width */
+	unsigned int	tR;   /* ND_nWE high to ND_nRE low for read */
+	unsigned int	tWHR; /* ND_nWE high to ND_nRE low for status read */
+	unsigned int	tAR;  /* ND_ALE low to ND_nRE low delay */
+};
+
+struct pxa3xx_nand_cmdset {
+	uint16_t	read1;
+	uint16_t	read2;
+	uint16_t	program;
+	uint16_t	read_status;
+	uint16_t	read_id;
+	uint16_t	erase;
+	uint16_t	reset;
+	uint16_t	lock;
+	uint16_t	unlock;
+	uint16_t	lock_status;
+};
+
+struct pxa3xx_nand_flash {
+	const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
+	const struct pxa3xx_nand_cmdset *cmdset;
+
+	uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
+	uint32_t page_size;	/* Page size in bytes (PAGE_SZ) */
+	uint32_t flash_width;	/* Width of Flash memory (DWIDTH_M) */
+	uint32_t dfc_width;	/* Width of flash controller(DWIDTH_C) */
+	uint32_t num_blocks;	/* Number of physical blocks in Flash */
+	uint32_t chip_id;
+};
+
+struct pxa3xx_nand_platform_data {
+
+	/* the data flash bus is shared between the Static Memory
+	 * Controller and the Data Flash Controller,  the arbiter
+	 * controls the ownership of the bus
+	 */
+	int	enable_arbiter;
+
+	/* allow platform code to keep OBM/bootloader defined NFC config */
+	int	keep_config;
+
+	const struct mtd_partition		*parts;
+	unsigned int				nr_parts;
+
+	const struct pxa3xx_nand_flash * 	flash;
+	size_t					num_flash;
+};
+
+extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
+#endif /* __ASM_ARCH_PXA3XX_NAND_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-pxa/pwm.c linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/pwm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-pxa/pwm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-pxa/pwm.c	2010-02-24 13:52:17.000000000 -0500
@@ -204,14 +204,14 @@ static int __devinit pwm_probe(struct pl
 		goto err_free_clk;
 	}
 
-	r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+	r = request_mem_region(r->start, resource_size(r), pdev->name);
 	if (r == NULL) {
 		dev_err(&pdev->dev, "failed to request memory resource\n");
 		ret = -EBUSY;
 		goto err_free_clk;
 	}
 
-	pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
+	pwm->mmio_base = ioremap(r->start, resource_size(r));
 	if (pwm->mmio_base == NULL) {
 		dev_err(&pdev->dev, "failed to ioremap() registers\n");
 		ret = -ENODEV;
@@ -241,7 +241,7 @@ static int __devinit pwm_probe(struct pl
 	return 0;
 
 err_free_mem:
-	release_mem_region(r->start, r->end - r->start + 1);
+	release_mem_region(r->start, resource_size(r));
 err_free_clk:
 	clk_put(pwm->clk);
 err_free:
@@ -271,7 +271,7 @@ static int __devexit pwm_remove(struct p
 	iounmap(pwm->mmio_base);
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(r->start, r->end - r->start + 1);
+	release_mem_region(r->start, resource_size(r));
 
 	clk_put(pwm->clk);
 	kfree(pwm);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/clock.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C24XX Core clock control support
@@ -337,7 +337,7 @@ int s3c24xx_register_clocks(struct clk *
 
 int __init s3c24xx_register_baseclocks(unsigned long xtal)
 {
-	printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
+	printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
 
 	clk_xtal.rate = xtal;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-hsmmc2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,69 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * Copyright (c) 2009 Maurus Cuelenaere
+ *
+ * Based on arch/arm/plat-s3c/dev-hsmmc1.c
+ * original file Copyright (c) 2008 Simtec Electronics
+ *
+ * S3C series device definition for hsmmc device 2
+ *
+ * This 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/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc2_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC2,
+		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC2,
+		.end   = IRQ_HSMMC2,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+	.name		= "s3c-sdhci",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
+	.resource	= s3c_hsmmc2_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc2_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc2_def_platdata,
+	},
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-i2c0.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c0.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-i2c0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c0.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c/dev-i2c0.c
  *
- * Copyright 2008,2009 Simtec Electronics
+ * Copyright 2008-2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-i2c1.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c1.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-i2c1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-i2c1.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c/dev-i2c1.c
  *
- * Copyright 2008,2009 Simtec Electronics
+ * Copyright 2008-2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-nand.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-nand.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dev-nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dev-nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,8 +9,12 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
 #include <mach/map.h>
 #include <plat/devs.h>
+#include <plat/nand.h>
 
 static struct resource s3c_nand_resource[] = {
 	[0] = {
@@ -28,3 +32,98 @@ struct platform_device s3c_device_nand =
 };
 
 EXPORT_SYMBOL(s3c_device_nand);
+
+/**
+ * s3c_nand_copy_set() - copy nand set data
+ * @set: The new structure, directly copied from the old.
+ *
+ * Copy all the fields from the NAND set field from what is probably __initdata
+ * to new kernel memory. The code returns 0 if the copy happened correctly or
+ * an error code for the calling function to display.
+ *
+ * Note, we currently do not try and look to see if we've already copied the
+ * data in a previous set.
+ */
+static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
+{
+	void *ptr;
+	int size;
+
+	size = sizeof(struct mtd_partition) * set->nr_partitions;
+	if (size) {
+		ptr = kmemdup(set->partitions, size, GFP_KERNEL);
+		set->partitions = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+	
+	if (set->nr_map && set->nr_chips) {
+		size = sizeof(int) * set->nr_chips;
+		ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
+		set->nr_map = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+
+	if (set->ecc_layout) {
+		ptr = kmemdup(set->ecc_layout,
+			      sizeof(struct nand_ecclayout), GFP_KERNEL);
+		set->ecc_layout = ptr;
+
+		if (!ptr)
+			return -ENOMEM;
+	}
+	
+	return 0;
+}
+
+void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
+{
+	struct s3c2410_platform_nand *npd;
+	int size;
+	int ret;
+
+	/* note, if we get a failure in allocation, we simply drop out of the
+	 * function. If there is so little memory available at initialisation
+	 * time then there is little chance the system is going to run.
+	 */ 
+
+	npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
+	if (!npd) {
+		printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+		return;
+	}
+
+	/* now see if we need to copy any of the nand set data */
+
+	size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
+	if (size) {
+		struct s3c2410_nand_set *from = npd->sets;
+		struct s3c2410_nand_set *to;
+		int i;
+
+		to = kmemdup(from, size, GFP_KERNEL);
+		npd->sets = to;	/* set, even if we failed */
+
+		if (!to) {
+			printk(KERN_ERR "%s: no memory for sets\n", __func__);
+			return;
+		}
+		
+		for (i = 0; i < npd->nr_sets; i++) {
+			ret = s3c_nand_copy_set(to);
+			if (ret) {
+				printk(KERN_ERR "%s: failed to copy set %d\n",
+				__func__, i);
+				return;
+			}
+			to++;
+		}
+	}
+
+	s3c_device_nand.dev.platform_data = npd;
+}
+
+EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dma.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c/dma.c
  *
- * Copyright (c) 2003-2005,2006,2009 Simtec Electronics
+ * Copyright (c) 2003-2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/audio.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/audio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,45 +1,17 @@
-/* arch/arm/mach-s3c2410/include/mach/audio.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://www.simtec.co.uk/products/SWLINUX/
- *	Ben Dooks <ben@simtec.co.uk>
+/* arch/arm/plat-s3c/include/plat/audio.h
  *
- * S3C24XX - Audio platfrom_device info
+ * Copyright (c) 2009 Samsung Electronics Co. Ltd
+ * Author: 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.
-*/
-
-#ifndef __ASM_ARCH_AUDIO_H
-#define __ASM_ARCH_AUDIO_H __FILE__
-
-/* struct s3c24xx_iis_ops
- *
- * called from the s3c24xx audio core to deal with the architecture
- * or the codec's setup and control.
- *
- * the pointer to itself is passed through in case the caller wants to
- * embed this in an larger structure for easy reference to it's context.
-*/
-
-struct s3c24xx_iis_ops {
-	struct module *owner;
-
-	int	(*startup)(struct s3c24xx_iis_ops *me);
-	void	(*shutdown)(struct s3c24xx_iis_ops *me);
-	int	(*suspend)(struct s3c24xx_iis_ops *me);
-	int	(*resume)(struct s3c24xx_iis_ops *me);
-
-	int	(*open)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm);
-	int	(*close)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm);
-	int	(*prepare)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm, struct snd_pcm_runtime *rt);
-};
+ */
 
-struct s3c24xx_platdata_iis {
-	const char		*codec_clk;
-	struct s3c24xx_iis_ops	*ops;
-	int			(*match_dev)(struct device *dev);
+/**
+ * struct s3c_audio_pdata - common platform data for audio device drivers
+ * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
+ */
+struct s3c_audio_pdata {
+	int (*cfg_gpio)(struct platform_device *);
 };
-
-#endif /* __ASM_ARCH_AUDIO_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/audio-simtec.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,5 +33,5 @@ struct s3c24xx_audio_simtec_pdata {
 	void	(*startup)(void);
 };
 
-extern int simtec_audio_add(const char *codec_name,
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
 			    struct s3c24xx_audio_simtec_pdata *pdata);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu-freq.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/plat-s3c/include/plat/cpu-freq.h
  *
- * Copyright (c) 2006,2007 Simtec Electronics
+ * Copyright (c) 2006-2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/cpu.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/cpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/cpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,9 @@
 
 /* todo - fix when rmk changes iodescs to use `void __iomem *` */
 
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
@@ -73,3 +76,6 @@ extern struct sysdev_class s3c2443_syscl
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
 
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/devs.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/devs.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/devs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/devs.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,10 @@ extern struct platform_device s3c64xx_de
 extern struct platform_device s3c64xx_device_iis1;
 extern struct platform_device s3c64xx_device_iisv4;
 
+extern struct platform_device s3c64xx_device_pcm0;
+extern struct platform_device s3c64xx_device_pcm1;
+
+extern struct platform_device s3c_device_ts;
 extern struct platform_device s3c_device_fb;
 extern struct platform_device s3c_device_usb;
 extern struct platform_device s3c_device_lcd;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/dma.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/plat-s3c/include/plat/dma.h
  *
- * Copyright (C) 2003,2004,2006 Simtec Electronics
+ * Copyright (C) 2003-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C DMA support
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/fb.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/fb.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/fb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/fb.h	2010-02-24 13:52:17.000000000 -0500
@@ -70,4 +70,11 @@ extern void s3c_fb_set_platdata(struct s
  */
 extern void s3c64xx_fb_gpio_setup_24bpp(void);
 
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/iic.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/iic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/iic.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/plat-s3c/include/plat/iic.h
  *
- * Copyright 2004,2009 Simtec Electronics
+ * Copyright 2004-2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C - I2C Controller platform_device info
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
  *			Setting this flag will allow the kernel to
  *			look for it at boot time and also skip the NAND
  *			scan.
+ * @options:		Default value to set into 'struct nand_chip' options.
  * @nr_chips:		Number of chips in this set
  * @nr_partitions:	Number of partitions pointed to by @partitions
  * @name:		Name of set (optional)
@@ -31,6 +32,7 @@ struct s3c2410_nand_set {
 	unsigned int		disable_ecc:1;
 	unsigned int		flash_bbt:1;
 
+	unsigned int		options;
 	int			nr_chips;
 	int			nr_partitions;
 	char			*name;
@@ -55,3 +57,11 @@ struct s3c2410_platform_nand {
 					       int chip);
 };
 
+/**
+ * s3c_nand_set_platdata() - register NAND platform data.
+ * @nand: The NAND platform data to register with s3c_device_nand.
+ *
+ * This function copies the given NAND platform data, @nand and registers
+ * it with the s3c_device_nand. This allows @nand to be __initdata.
+*/
+extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-fb-v4.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,235 @@
+/* arch/arm/plat-s3c/include/plat/regs-fb-v4.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This 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 the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN	(1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0				(0x10)
+#define VIDTCON1				(0x14)
+#define VIDTCON2				(0x18)
+
+/* Window position controls */
+
+#define WINCON(_win)				(0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
+#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
+#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
+#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
+
+
+#define VIDINTCON0				(0x130)
+
+#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT			(26)
+#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
+
+#define WINCONx_ENLOCAL				(1 << 22)
+#define WINCONx_BUFSTATUS			(1 << 21)
+#define WINCONx_BUFSEL				(1 << 20)
+#define WINCONx_BUFAUTOEN			(1 << 19)
+#define WINCONx_YCbCr				(1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
+#define WINCON2_BLD_PIX				(1 << 6)
+
+#define WINCON2_ALPHA_SEL			(1 << 1)
+#define WINCON2_BPPMODE_MASK			(0xf << 2)
+#define WINCON2_BPPMODE_SHIFT			(2)
+#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define WINCON3_BLD_PIX				(1 << 6)
+
+#define WINCON3_ALPHA_SEL			(1 << 1)
+#define WINCON3_BPPMODE_MASK			(0xf << 2)
+#define WINCON3_BPPMODE_SHIFT			(2)
+#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
+
+#define DITHMODE				(0x170)
+#define WINxMAP(_win)				(0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK			(0x3 << 5)
+#define DITHMODE_R_POS_SHIFT			(5)
+#define DITHMODE_R_POS_8BIT			(0x0 << 5)
+#define DITHMODE_R_POS_6BIT			(0x1 << 5)
+#define DITHMODE_R_POS_5BIT			(0x2 << 5)
+
+#define DITHMODE_G_POS_MASK			(0x3 << 3)
+#define DITHMODE_G_POS_SHIFT			(3)
+#define DITHMODE_G_POS_8BIT			(0x0 << 3)
+#define DITHMODE_G_POS_6BIT			(0x1 << 3)
+#define DITHMODE_G_POS_5BIT			(0x2 << 3)
+
+#define DITHMODE_B_POS_MASK			(0x3 << 1)
+#define DITHMODE_B_POS_SHIFT			(1)
+#define DITHMODE_B_POS_8BIT			(0x0 << 1)
+#define DITHMODE_B_POS_6BIT			(0x1 << 1)
+#define DITHMODE_B_POS_5BIT			(0x2 << 1)
+
+#define DITHMODE_DITH_EN			(1 << 0)
+
+#define WPALCON					(0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
+#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
+#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+
+
+/* system specific implementation code for palette sizes, and other
+ * information that changes depending on which architecture is being
+ * compiled.
+*/
+
+/* return true if window _win has OSD register D */
+#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
+
+static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
+{
+	if (win < 2)
+		return 256;
+	if (win < 4)
+		return 16;
+	if (win == 4)
+		return 4;
+
+	BUG();	/* shouldn't get here */
+}
+
+static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
+{
+	/* all windows can do 1/2 bpp */
+
+	if ((bpp == 25 || bpp == 19) && win == 0)
+		return 0;	/* win 0 does not have 19 or 25bpp modes */
+
+	if (bpp == 4 && win == 4)
+		return 0;
+
+	if (bpp == 8 && (win >= 3))
+		return 0;	/* win 3/4 cannot do 8bpp in any mode */
+
+	return 1;
+}
+
+static inline int s3c_fb_pal_is16(unsigned int window)
+{
+	return window > 1;
+}
+
+struct s3c_fb_palette {
+	struct fb_bitfield	r;
+	struct fb_bitfield	g;
+	struct fb_bitfield	b;
+	struct fb_bitfield	a;
+};
+
+static inline void s3c_fb_init_palette(unsigned int window,
+				       struct s3c_fb_palette *palette)
+{
+	if (window < 2) {
+		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
+		palette->r.offset = 16;
+		palette->r.length = 8;
+		palette->g.offset = 8;
+		palette->g.length = 8;
+		palette->b.offset = 0;
+		palette->b.length = 8;
+	} else {
+		/* currently we assume RGB 5/6/5 */
+		palette->r.offset = 11;
+		palette->r.length = 5;
+		palette->g.offset = 5;
+		palette->g.length = 6;
+		palette->b.offset = 0;
+		palette->b.length = 5;
+	}
+}
+
+/* Notes on per-window bpp settings
+ *
+ * Value	Win0	 Win1	  Win2	   Win3	    Win 4
+ * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
+ * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
+ * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
+ * 0011		8(P)	 8(P)     -none-   -none-   -none-
+ * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
+ * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
+ * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
+ * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
+ * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110		-none-	 -none-	  -none-   -none-    -none-
+ * 1111		-none-	 -none-   -none-   -none-    -none-
+*/
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-nand.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/include/mach/regs-nand.h
  *
- * Copyright (c) 2004,2005 Simtec Electronics <linux@simtec.co.uk>
- *		      http://www.simtec.co.uk/products/SWLINUX/
+ * Copyright (c) 2004-2005 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
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,8 @@
 #define S3C2412_IISMOD_BCLK_MASK	(3 << 1)
 #define S3C2412_IISMOD_8BIT		(1 << 0)
 
+#define S3C64XX_IISMOD_CDCLKCON		(1 << 12)
+
 #define S3C2412_IISPSR_PSREN		(1 << 15)
 
 #define S3C2412_IISFIC_TXFLUSH		(1 << 15)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/regs-serial.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  *
  *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
  *
- *  Additional defines, (c) 2003 Simtec Electronics (linux@simtec.co.uk)
+ *  Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
  *
  *  Adapted from:
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/include/plat/sdhci.h	2010-02-24 13:52:17.000000000 -0500
@@ -57,6 +57,7 @@ struct s3c_sdhci_platdata {
  */
 extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
 extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
 
 /* Default platform data, exported so that per-cpu initialisation can
  * set the correct one when there are more than one cpu type selected.
@@ -64,11 +65,16 @@ extern void s3c_sdhci1_set_platdata(stru
 
 extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
 extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
 
 /* Helper function availablity */
 
 extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 
 /* S3C6400 SDHCI setup */
 
@@ -103,6 +109,17 @@ static inline void s3c6400_default_sdhci
 static inline void s3c6400_default_sdhci1(void) { }
 #endif /* CONFIG_S3C_DEV_HSMMC1 */
 
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6400_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6400_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
 #else
 static inline void s3c6400_default_sdhci0(void) { }
 static inline void s3c6400_default_sdhci1(void) { }
@@ -140,9 +157,70 @@ static inline void s3c6410_default_sdhci
 static inline void s3c6410_default_sdhci1(void) { }
 #endif /* CONFIG_S3C_DEV_HSMMC1 */
 
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6410_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
 #else
 static inline void s3c6410_default_sdhci0(void) { }
 static inline void s3c6410_default_sdhci1(void) { }
 #endif /* CONFIG_S3C6410_SETUP_SDHCI */
 
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+					   void __iomem *r,
+					   struct mmc_ios *ios,
+					   struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s5pc100_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s5pc100_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s5pc100_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
 #endif /* __PLAT_S3C_SDHCI_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -159,6 +157,12 @@ config S3C_GPIO_CFG_S3C64XX
 	  Internal configuration to enable S3C64XX style GPIO configuration
 	  functions.
 
+config S5P_GPIO_CFG_S5PC1XX
+	bool
+	help
+	  Internal configuration to enable S5PC1XX style GPIO configuration
+	  functions.
+
 # DMA
 
 config S3C_DMA
@@ -178,6 +182,11 @@ config S3C_DEV_HSMMC1
 	help
 	  Compile in platform device definitions for HSMMC channel 1
 
+config S3C_DEV_HSMMC2
+	bool
+	help
+	  Compile in platform device definitions for HSMMC channel 2
+
 config S3C_DEV_I2C1
 	bool
 	help
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,7 @@ obj-$(CONFIG_HAVE_PWM)		+= pwm.o
 
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
+obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pm.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s3c/pm.c
  *
  * Copyright 2008 Openmoko, Inc.
- * Copyright 2004,2006,2008 Simtec Electronics
+ * Copyright 2004-2008 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pm-check.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm-check.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pm-check.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pm-check.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s3c/pm-check.c
  *  originally in linux/arch/arm/plat-s3c24xx/pm.c
  *
- * Copyright (c) 2004,2006,2008 Simtec Electronics
+ * Copyright (c) 2004-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pwm.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c/pwm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c/pwm.c	2010-02-24 13:52:17.000000000 -0500
@@ -368,7 +368,7 @@ static int s3c_pwm_probe(struct platform
 	return ret;
 }
 
-static int s3c_pwm_remove(struct platform_device *pdev)
+static int __devexit s3c_pwm_remove(struct platform_device *pdev)
 {
 	struct pwm_device *pwm = platform_get_drvdata(pdev);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/adc.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/adc.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/adc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/adc.c	2010-02-24 13:52:17.000000000 -0500
@@ -365,7 +365,7 @@ static int s3c_adc_probe(struct platform
 	return ret;
 }
 
-static int s3c_adc_remove(struct platform_device *pdev)
+static int __devexit s3c_adc_remove(struct platform_device *pdev)
 {
 	struct adc_device *adc = platform_get_drvdata(pdev);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/clock-dclk.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/clock-dclk.c
  *
- * Copyright (c) 2004,2008 Simtec Electronics
+ * Copyright (c) 2004-2008 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/common-smdk.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/common-smdk.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/common-smdk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/common-smdk.c	2010-02-24 13:52:17.000000000 -0500
@@ -198,7 +198,7 @@ void __init smdk_machine_init(void)
 	if (machine_is_smdk2443())
 		smdk_nand_info.twrph0 = 50;
 
-	s3c_device_nand.dev.platform_data = &smdk_nand_info;
+	s3c_nand_set_platdata(&smdk_nand_info);
 
 	platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/cpu-freq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/cpu-freq.c
  *
- * Copyright (c) 2006,2007,2008 Simtec Electronics
+ * Copyright (c) 2006-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/devs.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/devs.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/devs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/devs.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,8 @@
 #include <plat/cpu.h>
 #include <plat/regs-spi.h>
 
+#include <mach/ts.h>
+
 /* Serial port registrations */
 
 static struct resource s3c2410_uart0_resource[] = {
@@ -182,6 +184,22 @@ void __init s3c24xx_fb_set_platdata(stru
 	}
 }
 
+/* Touchscreen */
+struct platform_device s3c_device_ts = {
+	.name		  = "s3c2410-ts",
+	.id		  = -1,
+};
+EXPORT_SYMBOL(s3c_device_ts);
+
+static struct s3c2410_ts_mach_info s3c2410ts_info;
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
+{
+	memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info));
+	s3c_device_ts.dev.platform_data = &s3c2410ts_info;
+}
+EXPORT_SYMBOL(s3c24xx_ts_set_platdata);
+
 /* USB Device (Gadget)*/
 
 static struct resource s3c_usbgadget_resource[] = {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/dma.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/dma.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/dma.c
  *
- * Copyright (c) 2003-2005,2006 Simtec Electronics
+ * Copyright 2003-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 DMA core
@@ -1310,7 +1310,7 @@ int __init s3c24xx_dma_init(unsigned int
 	int channel;
 	int ret;
 
-	printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
+	printk("S3C24XX DMA Driver, Copyright 2003-2006 Simtec Electronics\n");
 
 	dma_channels = channels;
 
@@ -1403,11 +1403,13 @@ static struct s3c2410_dma_chan *s3c2410_
 		ord = &dma_order->channels[channel];
 
 		for (ch = 0; ch < dma_channels; ch++) {
+			int tmp;
 			if (!is_channel_valid(ord->list[ch]))
 				continue;
 
-			if (s3c2410_chans[ord->list[ch]].in_use == 0) {
-				ch = ord->list[ch] & ~DMA_CH_VALID;
+			tmp = ord->list[ch] & ~DMA_CH_VALID;
+			if (s3c2410_chans[tmp].in_use == 0) {
+				ch = tmp;
 				goto found;
 			}
 		}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/plat-s3c/include/plat/cpu-freq.h
  *
- * Copyright (c) 2006,2007,2009 Simtec Electronics
+ * Copyright (c) 2006-2009 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,7 +64,7 @@
 /* the calculation for the VA of this must ensure that
  * it is the same distance apart from the UART in the
  * phsyical address space, as the initial mapping for the IO
- * is done as a 1:1 maping. This puts it (currently) at
+ * is done as a 1:1 mapping. This puts it (currently) at
  * 0xFA800000, which is not in the way of any current mapping
  * by the base system.
 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/mci.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,31 @@
 #ifndef _ARCH_MCI_H
 #define _ARCH_MCI_H
 
+/**
+ * struct s3c24xx_mci_pdata - sd/mmc controller platform data
+ * @no_wprotect: Set this to indicate there is no write-protect switch.
+ * @no_detect: Set this if there is no detect switch.
+ * @wprotect_invert: Invert the default sense of the write protect switch.
+ * @detect_invert: Invert the default sense of the write protect switch.
+ * @use_dma: Set to allow the use of DMA.
+ * @gpio_detect: GPIO number for the card detect line.
+ * @gpio_wprotect: GPIO number for the write protect line.
+ * @ocr_avail: The mask of the available power states, non-zero to use.
+ * @set_power: Callback to control the power mode.
+ *
+ * The @gpio_detect is used for card detection when @no_wprotect is unset,
+ * and the default sense is that 0 returned from gpio_get_value() means
+ * that a card is inserted. If @detect_invert is set, then the value from
+ * gpio_get_value() is inverted, which makes 1 mean card inserted.
+ *
+ * The driver will use @gpio_wprotect to signal whether the card is write
+ * protected if @no_wprotect is not set. A 0 returned from gpio_get_value()
+ * means the card is read/write, and 1 means read-only. The @wprotect_invert
+ * will invert the value returned from gpio_get_value().
+ *
+ * Card power is set by @ocr_availa, using MCC_VDD_ constants if it is set
+ * to a non-zero value, otherwise the default of 3.2-3.4V is used.
+ */
 struct s3c24xx_mci_pdata {
 	unsigned int	no_wprotect : 1;
 	unsigned int	no_detect : 1;
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-dma.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/mach-s3c2410/include/mach/dma.h
  *
- * Copyright (C) 2003,2004,2006 Simtec Electronics
+ * Copyright (C) 2003-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C24XX DMA support
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/irq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/irq.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics 
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -522,6 +522,8 @@ int s3c24xx_set_fiq(unsigned int irq, bo
 	__raw_writel(intmod, S3C2410_INTMOD);
 	return 0;
 }
+
+EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
 #endif
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/irq-pm.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/irq-pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/irq-pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/irq-pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/irq-om.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c24xx/Kconfig
-#
 # Copyright 2007 Simtec Electronics
 #
 # Licensed under GPLv2
@@ -178,4 +176,11 @@ config MACH_SMDK
 	help
 	  Common machine code for SMDK2410 and SMDK2440
 
+config S3C24XX_SIMTEC_AUDIO
+	bool
+	depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS)
+	default y
+	help
+	  Add audio devices for common Simtec S3C24XX boards
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -55,3 +55,4 @@ obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_
 # machine common support
 
 obj-$(CONFIG_MACH_SMDK)		+= common-smdk.o
+obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO)	+= simtec-audio.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/pm.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/pm.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/pm.c
  *
- * Copyright (c) 2004,2006 Simtec Electronics
+ * Copyright (c) 2004-2006 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C24XX Power Manager (Suspend-To-RAM) support
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/pm-simtec.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright 2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * http://armlinux.simtec.co.uk/
@@ -35,7 +35,7 @@
 
 #include <plat/pm.h>
 
-#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+#define COPYRIGHT ", Copyright 2005 Simtec Electronics"
 
 /* pm_simtec_init
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2410-iotiming.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
  *
- * Copyright (c) 2006,2008,2009 Simtec Electronics
+ * Copyright (c) 2006-2009 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2412-iotiming.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
  *
- * Copyright (c) 2006,2008 Simtec Electronics
+ * Copyright (c) 2006-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
  *
- * Copyright (c) 2006,2008,2009 Simtec Electronics
+ * Copyright (c) 2006-2009 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *	Vincent Sanders <vince@simtec.co.uk>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
  *
- * Copyright (c) 2006,2007 Simtec Electronics
+ * Copyright (c) 2006-2007 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *	Vincent Sanders <vince@arm.linux.org.uk>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,7 @@ void __init s3c244x_map_io(void)
 	s3c_device_sdi.name  = "s3c2440-sdi";
 	s3c_device_i2c0.name  = "s3c2440-i2c";
 	s3c_device_nand.name = "s3c2440-nand";
+	s3c_device_ts.name = "s3c2440-ts";
 	s3c_device_usbgadget.name = "s3c2440-usbgadget";
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
  *
- * Copyright (c) 2004-2005,2008 Simtec Electronics
+ * Copyright (c) 2004-2008 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/s3c244x-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2004 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/simtec-audio.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/simtec-audio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c24xx/simtec-audio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c24xx/simtec-audio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,77 @@
+/* linux/arch/arm/plat-s3c24xx/simtec-audio.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Audio setup for various Simtec S3C24XX 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+#include <mach/bast-cpld.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/audio-simtec.h>
+#include <plat/devs.h>
+
+/* platform ops for audio */
+
+static void simtec_audio_startup_lrroute(void)
+{
+	unsigned int tmp;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	tmp = __raw_readb(BAST_VA_CTRL1);
+	tmp &= ~BAST_CPLD_CTRL1_LRMASK;
+	tmp |= BAST_CPLD_CTRL1_LRCDAC;
+	__raw_writeb(tmp, BAST_VA_CTRL1);
+
+	local_irq_restore(flags);
+}
+
+static struct s3c24xx_audio_simtec_pdata simtec_audio_platdata;
+static char our_name[32];
+
+static struct platform_device simtec_audio_dev = {
+	.name	= our_name,
+	.id	= -1,
+	.dev	= {
+		.parent		= &s3c_device_iis.dev,
+		.platform_data	= &simtec_audio_platdata,
+	},
+};
+
+int __init simtec_audio_add(const char *name, bool has_lr_routing,
+			    struct s3c24xx_audio_simtec_pdata *spd)
+{
+	if (!name)
+		name = "tlv320aic23";
+
+	snprintf(our_name, sizeof(our_name)-1, "s3c24xx-simtec-%s", name);
+
+	/* copy platform data so the source can be __initdata */
+	if (spd)
+		simtec_audio_platdata = *spd;
+
+	if (has_lr_routing)
+		simtec_audio_platdata.startup = simtec_audio_startup_lrroute;
+
+	platform_device_register(&s3c_device_iis);
+	platform_device_register(&simtec_audio_dev);
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/cpu.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -107,6 +107,11 @@ static struct map_desc s3c_iodesc[] __in
 		.pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
+		.length		= SZ_1K,
+		.type		= MT_DEVICE,
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/cpufreq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/cpufreq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 
 static struct clk *armclk;
 static struct regulator *vddarm;
+static unsigned long regulator_latency;
 
 #ifdef CONFIG_CPU_S3C6410
 struct s3c64xx_dvfs {
@@ -27,11 +28,10 @@ struct s3c64xx_dvfs {
 };
 
 static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
-	[0] = { 1000000, 1000000 },
-	[1] = { 1000000, 1050000 },
-	[2] = { 1050000, 1100000 },
-	[3] = { 1050000, 1150000 },
-	[4] = { 1250000, 1350000 },
+	[0] = { 1000000, 1150000 },
+	[1] = { 1050000, 1150000 },
+	[2] = { 1100000, 1150000 },
+	[3] = { 1200000, 1350000 },
 };
 
 static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
@@ -41,9 +41,9 @@ static struct cpufreq_frequency_table s3
 	{ 1, 266000 },
 	{ 2, 333000 },
 	{ 2, 400000 },
-	{ 3, 532000 },
-	{ 3, 533000 },
-	{ 4, 667000 },
+	{ 2, 532000 },
+	{ 2, 533000 },
+	{ 3, 667000 },
 	{ 0, CPUFREQ_TABLE_END },
 };
 #endif
@@ -141,7 +141,7 @@ err:
 }
 
 #ifdef CONFIG_REGULATOR
-static void __init s3c64xx_cpufreq_constrain_voltages(void)
+static void __init s3c64xx_cpufreq_config_regulator(void)
 {
 	int count, v, i, found;
 	struct cpufreq_frequency_table *freq;
@@ -150,11 +150,10 @@ static void __init s3c64xx_cpufreq_const
 	count = regulator_count_voltages(vddarm);
 	if (count < 0) {
 		pr_err("cpufreq: Unable to check supported voltages\n");
-		return;
 	}
 
 	freq = s3c64xx_freq_table;
-	while (freq->frequency != CPUFREQ_TABLE_END) {
+	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
 		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
 			continue;
 
@@ -175,6 +174,10 @@ static void __init s3c64xx_cpufreq_const
 
 		freq++;
 	}
+
+	/* Guess based on having to do an I2C/SPI write; in future we
+	 * will be able to query the regulator performance here. */
+	regulator_latency = 1 * 1000 * 1000;
 }
 #endif
 
@@ -206,7 +209,7 @@ static int __init s3c64xx_cpufreq_driver
 		pr_err("cpufreq: Only frequency scaling available\n");
 		vddarm = NULL;
 	} else {
-		s3c64xx_cpufreq_constrain_voltages();
+		s3c64xx_cpufreq_config_regulator();
 	}
 #endif
 
@@ -217,8 +220,11 @@ static int __init s3c64xx_cpufreq_driver
 		/* Check for frequencies we can generate */
 		r = clk_round_rate(armclk, freq->frequency * 1000);
 		r /= 1000;
-		if (r != freq->frequency)
+		if (r != freq->frequency) {
+			pr_debug("cpufreq: %dkHz unsupported by clock\n",
+				 freq->frequency);
 			freq->frequency = CPUFREQ_ENTRY_INVALID;
+		}
 
 		/* If we have no regulator then assume startup
 		 * frequency is the maximum we can support. */
@@ -230,9 +236,11 @@ static int __init s3c64xx_cpufreq_driver
 
 	policy->cur = clk_get_rate(armclk) / 1000;
 
-	/* Pick a conservative guess in ns: we'll need ~1 I2C/SPI
-	 * write plus clock reprogramming. */
-	policy->cpuinfo.transition_latency = 2 * 1000 * 1000;
+	/* Datasheet says PLL stabalisation time (if we were to use
+	 * the PLLs, which we don't currently) is ~300us worst case,
+	 * but add some fudge.
+	 */
+	policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency;
 
 	ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
 	if (ret != 0) {
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/dev-audio.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-audio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/dev-audio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/dev-audio.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,14 @@
 
 #include <mach/irqs.h>
 #include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/gpio.h>
 
 #include <plat/devs.h>
-
+#include <plat/audio.h>
+#include <plat/gpio-bank-d.h>
+#include <plat/gpio-bank-e.h>
+#include <plat/gpio-cfg.h>
 
 static struct resource s3c64xx_iis0_resource[] = {
 	[0] = {
@@ -66,3 +71,97 @@ struct platform_device s3c64xx_device_ii
 	.resource	  = s3c64xx_iisv4_resource,
 };
 EXPORT_SYMBOL(s3c64xx_device_iisv4);
+
+
+/* PCM Controller platform_devices */
+
+static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
+{
+	switch (pdev->id) {
+	case 0:
+		s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
+		s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
+		s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
+		break;
+	case 1:
+		s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
+		s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
+		s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
+		s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
+		break;
+	default:
+		printk(KERN_DEBUG "Invalid PCM Controller number!");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct resource s3c64xx_pcm0_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_PCM0,
+		.end   = S3C64XX_PA_PCM0 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_PCM0_TX,
+		.end   = DMACH_PCM0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_PCM0_RX,
+		.end   = DMACH_PCM0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_pcm0_pdata = {
+	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm0 = {
+	.name		  = "samsung-pcm",
+	.id		  = 0,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm0_resource),
+	.resource	  = s3c64xx_pcm0_resource,
+	.dev = {
+		.platform_data = &s3c_pcm0_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm0);
+
+static struct resource s3c64xx_pcm1_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_PCM1,
+		.end   = S3C64XX_PA_PCM1 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = DMACH_PCM1_TX,
+		.end   = DMACH_PCM1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = DMACH_PCM1_RX,
+		.end   = DMACH_PCM1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct s3c_audio_pdata s3c_pcm1_pdata = {
+	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm1 = {
+	.name		  = "samsung-pcm",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm1_resource),
+	.resource	  = s3c64xx_pcm1_resource,
+	.dev = {
+		.platform_data = &s3c_pcm1_pdata,
+	},
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm1);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/gpiolib.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/gpiolib.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,6 +213,11 @@ static struct s3c_gpio_cfg gpio_4bit_cfg
 	.get_pull	= s3c_gpio_getpull_updown,
 };
 
+int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
+{
+	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
 static struct s3c_gpio_chip gpio_4bit[] = {
 	{
 		.base	= S3C64XX_GPA_BASE,
@@ -269,10 +274,16 @@ static struct s3c_gpio_chip gpio_4bit[]
 			.base	= S3C64XX_GPM(0),
 			.ngpio	= S3C64XX_GPIO_M_NR,
 			.label	= "GPM",
+			.to_irq = s3c64xx_gpio2int_gpm,
 		},
 	},
 };
 
+int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
+{
+	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+
 static struct s3c_gpio_chip gpio_4bit2[] = {
 	{
 		.base	= S3C64XX_GPH_BASE + 0x4,
@@ -297,6 +308,7 @@ static struct s3c_gpio_chip gpio_4bit2[]
 			.base	= S3C64XX_GPL(0),
 			.ngpio	= S3C64XX_GPIO_L_NR,
 			.label	= "GPL",
+			.to_irq = s3c64xx_gpio2int_gpl,
 		},
 	},
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,18 +36,18 @@
 
 #define S3C64XX_GPC4_SPI_MISO1		(0x02 << 16)
 #define S3C64XX_GPC4_MMC2_CMD		(0x03 << 16)
-#define S3C64XX_GPC4_I2S0_V40_DO	(0x05 << 16)
+#define S3C64XX_GPC4_I2S_V40_DO0	(0x05 << 16)
 #define S3C64XX_GPC4_EINT_G2_4		(0x07 << 16)
 
 #define S3C64XX_GPC5_SPI_CLK1		(0x02 << 20)
 #define S3C64XX_GPC5_MMC2_CLK		(0x03 << 20)
-#define S3C64XX_GPC5_I2S1_V40_DO	(0x05 << 20)
+#define S3C64XX_GPC5_I2S_V40_DO1	(0x05 << 20)
 #define S3C64XX_GPC5_EINT_G2_5		(0x07 << 20)
 
 #define S3C64XX_GPC6_SPI_MOSI1		(0x02 << 24)
 #define S3C64XX_GPC6_EINT_G2_6		(0x07 << 24)
 
 #define S3C64XX_GPC7_SPI_nCS1		(0x02 << 28)
-#define S3C64XX_GPC7_I2S2_V40_DO	(0x05 << 28)
+#define S3C64XX_GPC7_I2S_V40_DO2	(0x05 << 28)
 #define S3C64XX_GPC7_EINT_G2_7		(0x07 << 28)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/irq-eint.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-eint.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,7 @@ static void s3c_irq_eint_maskack(unsigne
 static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
 {
 	int offs = eint_offset(irq);
-	int pin;
+	int pin, pin_val;
 	int shift;
 	u32 ctrl, mask;
 	u32 newvalue = 0;
@@ -109,7 +109,10 @@ static int s3c_irq_eint_set_type(unsigne
 		return -1;
 	}
 
-	shift = (offs / 2) * 4;
+	if (offs <= 15)
+		shift = (offs / 2) * 4;
+	else
+		shift = ((offs - 16) / 2) * 4;
 	mask = 0x7 << shift;
 
 	ctrl = __raw_readl(reg);
@@ -119,12 +122,18 @@ static int s3c_irq_eint_set_type(unsigne
 
 	/* set the GPIO pin appropriately */
 
-	if (offs < 23)
+	if (offs < 16) {
 		pin = S3C64XX_GPN(offs);
-	else
+		pin_val = S3C_GPIO_SFN(2);
+	} else if (offs < 23) {
+		pin = S3C64XX_GPL(offs + 8 - 16);
+		pin_val = S3C_GPIO_SFN(3);
+	} else {
 		pin = S3C64XX_GPM(offs - 23);
+		pin_val = S3C_GPIO_SFN(3);
+	}
 
-	s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgpin(pin, pin_val);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/plat-s3c64xx/Kconfig
-#
 # Copyright 2008 Openmoko, Inc.
 # Copyright 2008 Simtec Electronics
 #	Ben Dooks <ben@simtec.co.uk>
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/s3c6400-clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@ static struct clk clk_ext_xtal_mux = {
 #define clk_fin_epll clk_ext_xtal_mux
 
 #define clk_fout_mpll	clk_mpll
+#define clk_fout_epll	clk_epll
 
 struct clk_sources {
 	unsigned int	nr_sources;
@@ -88,11 +89,6 @@ static struct clksrc_clk clk_mout_apll =
 	.sources	= &clk_src_apll,
 };
 
-static struct clk clk_fout_epll = {
-	.name		= "fout_epll",
-	.id		= -1,
-};
-
 static struct clk *clk_src_epll_list[] = {
 	[0] = &clk_fin_epll,
 	[1] = &clk_fout_epll,
@@ -715,7 +711,6 @@ static struct clk *clks[] __initdata = {
 	&clk_iis_cd1,
 	&clk_pcm_cd,
 	&clk_mout_epll.clk,
-	&clk_fout_epll,
 	&clk_mout_mpll.clk,
 	&clk_dout_mpll,
 	&clk_mmc0.clk,
@@ -760,7 +755,4 @@ void __init s3c6400_register_clocks(unsi
 			       clkp->name, ret);
 		}
 	}
-
-	clk_mpll.parent = &clk_mout_mpll.clk;
-	clk_epll.parent = &clk_mout_epll.clk;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,3 +53,23 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struc
 	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
 	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
 }
+
+void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S3C64XX_GPH(6 + width);
+
+	/* Set all the necessary GPH pins to special-function 1 */
+	for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Set all the necessary GPC pins to special-function 1 */
+	for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,728 @@
+/* linux/arch/arm/plat-s5pc1xx/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * S5PC1XX Base clock support
+ *
+ * Based on plat-s3c64xx/clock.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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-clock.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+struct clk clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S5PC100_CLKSRC1);
+	if (enable)
+		val |= S5PC100_CLKSRC1_CLK48M_MASK;
+	else
+		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+
+	__raw_writel(val, S5PC100_CLKSRC1);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+	.enable		= clk_48m_ctrl,
+};
+
+struct clk clk_54m = {
+	.name		= "clk_54m",
+	.id		= -1,
+	.rate		= 54000000,
+};
+
+static int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+
+static int clk_dummy_enable(struct clk *clk, int enable)
+{
+	return 0;
+}
+
+struct clk clk_hd0 = {
+	.name		= "hclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+struct clk clk_pd0 = {
+	.name		= "pclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
+static int s5pc100_clk_d00_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_clk_d01_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_clk_d02_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_clk_d10_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_clk_d11_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_clk_d12_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_clk_d13_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_clk_d14_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_clk_d15_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_clk_d20_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
+}
+
+int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+}
+
+int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+}
+
+static struct clk s5pc100_init_clocks_disable[] = {
+	{
+		.name		= "dsi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
+	}, {
+		.name		= "csi",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
+	}, {
+		.name		= "ccan",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
+	}, {
+		.name		= "ccan",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
+	}, {
+		.name		= "keypad",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
+	}, {
+		.name		= "hclkd2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
+	}, {
+		.name		= "iis-d2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
+	},
+};
+
+static struct clk s5pc100_init_clocks[] = {
+	/* System1 (D0_0) devices */
+	{
+		.name		= "intc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
+	}, {
+		.name		= "tzic",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
+	}, {
+		.name		= "cf-ata",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
+	}, {
+		.name		= "mdma",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
+	}, {
+		.name		= "g2d",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
+	}, {
+		.name		= "secss",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
+	}, {
+		.name		= "cssys",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
+	},
+
+	/* Memory (D0_1) devices */
+	{
+		.name		= "dmc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
+	}, {
+		.name		= "sromc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
+	}, {
+		.name		= "onenand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
+	}, {
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
+	}, {
+		.name		= "intmem",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
+	}, {
+		.name		= "ebi",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
+	},
+
+	/* System2 (D0_2) devices */
+	{
+		.name		= "seckey",
+		.id		= -1,
+		.parent		= &clk_pd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
+	}, {
+		.name		= "sdm",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
+	},
+
+	/* File (D1_0) devices */
+	{
+		.name		= "pdma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
+	}, {
+		.name		= "pdma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
+	}, {
+		.name		= "otg",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
+	}, {
+		.name		= "modem",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
+	},
+
+	/* Multimedia1 (D1_1) devices */
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
+	}, {
+		.name		= "rotator",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
+	}, {
+		.name		= "jpeg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
+	}, {
+		.name		= "g3d",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
+	},
+
+	/* Multimedia2 (D1_2) devices */
+	{
+		.name		= "tv",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
+	}, {
+		.name		= "vp",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
+	}, {
+		.name		= "mixer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
+	}, {
+		.name		= "hdmi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
+	}, {
+		.name		= "mfc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
+	},
+
+	/* System (D1_3) devices */
+	{
+		.name		= "chipid",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
+	}, {
+		.name		= "apc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
+	}, {
+		.name		= "iec",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
+	}, {
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
+	},
+
+	/* Connectivity (D1_4) devices */
+	{
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
+	}, {
+		.name		= "hdmi-i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
+	}, {
+		.name		= "spi",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
+	}, {
+		.name		= "irda",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
+	}, {
+		.name		= "hsitx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
+	}, {
+		.name		= "hsirx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
+	},
+
+	/* Audio (D1_5) devices */
+	{
+		.name		= "iis",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
+	}, {
+		.name		= "iis",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
+	}, {
+		.name		= "iis",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
+	}, {
+		.name		= "pcm",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
+	}, {
+		.name		= "pcm",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
+	}, {
+		.name		= "spdif",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
+	}, {
+		.name		= "cg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
+	},
+
+	/* Audio (D2_0) devices: all disabled */
+
+	/* Special Clocks 0 */
+	{
+		.name		= "sclk_hpm",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
+	}, {
+		.name		= "sclk_onenand",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
+	}, {
+		.name		= "spi_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
+	},
+	/* Special Clocks 1 */
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_27m,
+	&clk_48m,
+	&clk_54m,
+};
+
+void __init s5pc1xx_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+	int size;
+
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	clkp = s5pc100_init_clocks;
+	size = ARRAY_SIZE(s5pc100_init_clocks);
+
+	for (ptr = 0; ptr < size; ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clkp = s5pc100_init_clocks_disable;
+	size = ARRAY_SIZE(s5pc100_init_clocks_disable);
+
+	for (ptr = 0; ptr < size; ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+
+		(clkp->enable)(clkp, 0);
+	}
+
+	s3c_pwmclk_init();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/cpu.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/cpu.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,6 +55,16 @@ static struct cpu_table cpu_ids[] __init
 
 static struct map_desc s5pc1xx_iodesc[] __initdata = {
 	{
+		.virtual	= (unsigned long)S5PC1XX_VA_CLK_OTHER,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_CLK_OTHER),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_GPIO,
+		.pfn		= __phys_to_pfn(S5PC100_PA_GPIO),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
 		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
 		.length		= SZ_16,
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpio-config.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,62 @@
+/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * S5PC1XX GPIO Configuration.
+ *
+ * Based on plat-s3c64xx/gpio-config.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/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/gpio-core.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 drvstr;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	drvstr = __raw_readl(reg);
+	drvstr = 0xffff & (0x3 << shift);
+	drvstr = drvstr >> shift;
+
+	return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 tmp;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	tmp = __raw_readl(reg);
+	tmp |= drvstr << shift;
+
+	__raw_writel(tmp, reg);
+
+	return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,503 @@
+/*
+ * arch/arm/plat-s5pc1xx/gpiolib.c
+ *
+ *  Copyright 2009 Samsung Electronics Co
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC1XX - GPIOlib 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/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <mach/gpio-core.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/regs-gpio.h>
+
+/* S5PC100 GPIO bank summary:
+ *
+ * Bank	GPIOs	Style	INT Type
+ * A0	8	4Bit	GPIO_INT0
+ * A1	5	4Bit	GPIO_INT1
+ * B	8	4Bit	GPIO_INT2
+ * C	5	4Bit	GPIO_INT3
+ * D	7	4Bit	GPIO_INT4
+ * E0	8	4Bit	GPIO_INT5
+ * E1	6	4Bit	GPIO_INT6
+ * F0	8	4Bit	GPIO_INT7
+ * F1	8	4Bit	GPIO_INT8
+ * F2	8	4Bit	GPIO_INT9
+ * F3	4	4Bit	GPIO_INT10
+ * G0	8	4Bit	GPIO_INT11
+ * G1	3	4Bit	GPIO_INT12
+ * G2	7	4Bit	GPIO_INT13
+ * G3	7	4Bit	GPIO_INT14
+ * H0	8	4Bit	WKUP_INT
+ * H1	8	4Bit	WKUP_INT
+ * H2	8	4Bit	WKUP_INT
+ * H3	8	4Bit	WKUP_INT
+ * I	8	4Bit	GPIO_INT15
+ * J0	8	4Bit	GPIO_INT16
+ * J1	5	4Bit	GPIO_INT17
+ * J2	8	4Bit	GPIO_INT18
+ * J3	8	4Bit	GPIO_INT19
+ * J4	4	4Bit	GPIO_INT20
+ * K0	8	4Bit	None
+ * K1	6	4Bit	None
+ * K2	8	4Bit	None
+ * K3	8	4Bit	None
+ * L0	8	4Bit	None
+ * L1	8	4Bit	None
+ * L2	8	4Bit	None
+ * L3	8	4Bit	None
+ */
+
+#define OFF_GPCON	(0x00)
+#define OFF_GPDAT	(0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+#if 1
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+/* The s5pc1xx_gpiolib routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *	        gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *		bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
+ * the output.
+ */
+
+static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, base + OFF_GPCON);
+
+	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+	unsigned long dat;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	con |= 0x1 << con_4bit_shift(offset);
+
+	dat = __raw_readl(base + OFF_GPDAT);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + OFF_GPDAT);
+	__raw_writel(con, base + OFF_GPCON);
+	__raw_writel(dat, base + OFF_GPDAT);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	return S3C_IRQ_GPIO(chip->base + offset);
+}
+
+static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
+{
+	int base;
+
+	base = chip->base - S5PC100_GPH0(0);
+	if (base == 0)
+		return IRQ_EINT(offset);
+	base = chip->base - S5PC100_GPH1(0);
+	if (base == 0)
+		return IRQ_EINT(8 + offset);
+	base = chip->base - S5PC100_GPH2(0);
+	if (base == 0)
+		return IRQ_EINT(16 + offset);
+	base = chip->base - S5PC100_GPH3(0);
+	if (base == 0)
+		return IRQ_EINT(24 + offset);
+	return -EINVAL;
+}
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_eint = {
+	.cfg_eint	= 0xf,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
+	{
+		.base	= S5PC100_GPA0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA0(0),
+			.ngpio	= S5PC100_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.base	= S5PC100_GPA1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA1(0),
+			.ngpio	= S5PC100_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.base	= S5PC100_GPB_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPB(0),
+			.ngpio	= S5PC100_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.base	= S5PC100_GPC_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPC(0),
+			.ngpio	= S5PC100_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.base	= S5PC100_GPD_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPD(0),
+			.ngpio	= S5PC100_GPIO_D_NR,
+			.label	= "GPD",
+		},
+	}, {
+		.base	= S5PC100_GPE0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE0(0),
+			.ngpio	= S5PC100_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.base	= S5PC100_GPE1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE1(0),
+			.ngpio	= S5PC100_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.base	= S5PC100_GPF0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF0(0),
+			.ngpio	= S5PC100_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.base	= S5PC100_GPF1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF1(0),
+			.ngpio	= S5PC100_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.base	= S5PC100_GPF2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF2(0),
+			.ngpio	= S5PC100_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.base	= S5PC100_GPF3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF3(0),
+			.ngpio	= S5PC100_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	}, {
+		.base	= S5PC100_GPG0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG0(0),
+			.ngpio	= S5PC100_GPIO_G0_NR,
+			.label	= "GPG0",
+		},
+	}, {
+		.base	= S5PC100_GPG1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG1(0),
+			.ngpio	= S5PC100_GPIO_G1_NR,
+			.label	= "GPG1",
+		},
+	}, {
+		.base	= S5PC100_GPG2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG2(0),
+			.ngpio	= S5PC100_GPIO_G2_NR,
+			.label	= "GPG2",
+		},
+	}, {
+		.base	= S5PC100_GPG3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG3(0),
+			.ngpio	= S5PC100_GPIO_G3_NR,
+			.label	= "GPG3",
+		},
+	}, {
+		.base	= S5PC100_GPH0_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH0(0),
+			.ngpio	= S5PC100_GPIO_H0_NR,
+			.label	= "GPH0",
+		},
+	}, {
+		.base	= S5PC100_GPH1_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH1(0),
+			.ngpio	= S5PC100_GPIO_H1_NR,
+			.label	= "GPH1",
+		},
+	}, {
+		.base	= S5PC100_GPH2_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH2(0),
+			.ngpio	= S5PC100_GPIO_H2_NR,
+			.label	= "GPH2",
+		},
+	}, {
+		.base	= S5PC100_GPH3_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH3(0),
+			.ngpio	= S5PC100_GPIO_H3_NR,
+			.label	= "GPH3",
+		},
+	}, {
+		.base	= S5PC100_GPI_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPI(0),
+			.ngpio	= S5PC100_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.base	= S5PC100_GPJ0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ0(0),
+			.ngpio	= S5PC100_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.base	= S5PC100_GPJ1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ1(0),
+			.ngpio	= S5PC100_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.base	= S5PC100_GPJ2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ2(0),
+			.ngpio	= S5PC100_GPIO_J2_NR,
+			.label	= "GPJ2",
+		},
+	}, {
+		.base	= S5PC100_GPJ3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ3(0),
+			.ngpio	= S5PC100_GPIO_J3_NR,
+			.label	= "GPJ3",
+		},
+	}, {
+		.base	= S5PC100_GPJ4_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ4(0),
+			.ngpio	= S5PC100_GPIO_J4_NR,
+			.label	= "GPJ4",
+		},
+	}, {
+		.base	= S5PC100_GPK0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK0(0),
+			.ngpio	= S5PC100_GPIO_K0_NR,
+			.label	= "GPK0",
+		},
+	}, {
+		.base	= S5PC100_GPK1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK1(0),
+			.ngpio	= S5PC100_GPIO_K1_NR,
+			.label	= "GPK1",
+		},
+	}, {
+		.base	= S5PC100_GPK2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK2(0),
+			.ngpio	= S5PC100_GPIO_K2_NR,
+			.label	= "GPK2",
+		},
+	}, {
+		.base	= S5PC100_GPK3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK3(0),
+			.ngpio	= S5PC100_GPIO_K3_NR,
+			.label	= "GPK3",
+		},
+	}, {
+		.base	= S5PC100_GPL0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL0(0),
+			.ngpio	= S5PC100_GPIO_L0_NR,
+			.label	= "GPL0",
+		},
+	}, {
+		.base	= S5PC100_GPL1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL1(0),
+			.ngpio	= S5PC100_GPIO_L1_NR,
+			.label	= "GPL1",
+		},
+	}, {
+		.base	= S5PC100_GPL2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL2(0),
+			.ngpio	= S5PC100_GPIO_L2_NR,
+			.label	= "GPL2",
+		},
+	}, {
+		.base	= S5PC100_GPL3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL3(0),
+			.ngpio	= S5PC100_GPIO_L3_NR,
+			.label	= "GPL3",
+		},
+	}, {
+		.base	= S5PC100_GPL4_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL4(0),
+			.ngpio	= S5PC100_GPIO_L4_NR,
+			.label	= "GPL4",
+		},
+	},
+};
+
+/* FIXME move from irq-gpio.c */
+extern struct irq_chip s5pc1xx_gpioint;
+extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
+
+static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = s5pc1xx_gpiolib_input;
+	chip->chip.direction_output = s5pc1xx_gpiolib_output;
+	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+
+	/* Interrupt */
+	if (chip->config == &gpio_cfg) {
+		int i, irq;
+
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
+
+		for (i = 0;  i < chip->chip.ngpio; i++) {
+			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
+			set_irq_chip(irq, &s5pc1xx_gpioint);
+			set_irq_data(irq, &chip->chip);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID);
+		}
+	} else if (chip->config == &gpio_cfg_eint)
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
+}
+
+static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
+				       int nr_chips,
+				       void (*fn)(struct s3c_gpio_chip *))
+{
+	for (; nr_chips > 0; nr_chips--, chips++) {
+		if (fn)
+			(fn)(chips);
+		s3c_gpiolib_add(chips);
+	}
+}
+
+static __init int s5pc1xx_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chips;
+	int nr_chips;
+
+		chips = s5pc100_gpio_chips;
+		nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+
+	s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
+	/* Interrupt */
+	set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
+
+	return 0;
+}
+core_initcall(s5pc1xx_gpiolib_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
+ *
+ * Copyright 2009 Samsung Electronic
+ *
+ * S5PC1XX Platform - GPIO pin 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.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+#ifndef __GPIO_CFG_S5PC1XX_H
+#define __GPIO_CFG_S5PC1XX_H __FILE__
+
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+
+#define S5P_GPIO_DRVSTR_LV1	0x00
+#define S5P_GPIO_DRVSTR_LV2	0x01
+#define S5P_GPIO_DRVSTR_LV3	0x10
+#define S5P_GPIO_DRVSTR_LV4	0x11
+
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
+
+extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr);
+
+#endif /* __GPIO_CFG_S5PC1XX_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-eint.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * External Interrupt (GPH0 ~ GPH3) control 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.
+*/
+
+#define S5PC1XX_WKUP_INT_CON0_7		(S5PC1XX_EINT_BASE + 0x0)
+#define S5PC1XX_WKUP_INT_CON8_15	(S5PC1XX_EINT_BASE + 0x4)
+#define S5PC1XX_WKUP_INT_CON16_23	(S5PC1XX_EINT_BASE + 0x8)
+#define S5PC1XX_WKUP_INT_CON24_31	(S5PC1XX_EINT_BASE + 0xC)
+#define S5PC1XX_WKUP_INT_CON(x)		(S5PC1XX_WKUP_INT_CON0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_FLTCON0_3	(S5PC1XX_EINT_BASE + 0x80)
+#define S5PC1XX_WKUP_INT_FLTCON4_7	(S5PC1XX_EINT_BASE + 0x84)
+#define S5PC1XX_WKUP_INT_FLTCON8_11	(S5PC1XX_EINT_BASE + 0x88)
+#define S5PC1XX_WKUP_INT_FLTCON12_15	(S5PC1XX_EINT_BASE + 0x8C)
+#define S5PC1XX_WKUP_INT_FLTCON16_19	(S5PC1XX_EINT_BASE + 0x90)
+#define S5PC1XX_WKUP_INT_FLTCON20_23	(S5PC1XX_EINT_BASE + 0x94)
+#define S5PC1XX_WKUP_INT_FLTCON24_27	(S5PC1XX_EINT_BASE + 0x98)
+#define S5PC1XX_WKUP_INT_FLTCON28_31	(S5PC1XX_EINT_BASE + 0x9C)
+#define S5PC1XX_WKUP_INT_FLTCON(x)	(S5PC1XX_WKUP_INT_FLTCON0_3 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_MASK0_7	(S5PC1XX_EINT_BASE + 0x100)
+#define S5PC1XX_WKUP_INT_MASK8_15	(S5PC1XX_EINT_BASE + 0x104)
+#define S5PC1XX_WKUP_INT_MASK16_23	(S5PC1XX_EINT_BASE + 0x108)
+#define S5PC1XX_WKUP_INT_MASK24_31	(S5PC1XX_EINT_BASE + 0x10C)
+#define S5PC1XX_WKUP_INT_MASK(x)	(S5PC1XX_WKUP_INT_MASK0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_PEND0_7	(S5PC1XX_EINT_BASE + 0x140)
+#define S5PC1XX_WKUP_INT_PEND8_15	(S5PC1XX_EINT_BASE + 0x144)
+#define S5PC1XX_WKUP_INT_PEND16_23	(S5PC1XX_EINT_BASE + 0x148)
+#define S5PC1XX_WKUP_INT_PEND24_31	(S5PC1XX_EINT_BASE + 0x14C)
+#define S5PC1XX_WKUP_INT_PEND(x)	(S5PC1XX_WKUP_INT_PEND0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_LOWLEV		(0x00)
+#define S5PC1XX_WKUP_INT_HILEV		(0x01)
+#define S5PC1XX_WKUP_INT_FALLEDGE	(0x02)
+#define S5PC1XX_WKUP_INT_RISEEDGE	(0x03)
+#define S5PC1XX_WKUP_INT_BOTHEDGE	(0x04)
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/irqs.h	2010-02-24 13:52:17.000000000 -0500
@@ -171,12 +171,21 @@
 #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
 #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
 
+/* External interrupt */
 #define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
 
-#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
-#define IRQ_EINT(x)		S3C_EINT(x)
+#define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
+#define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
+#define IRQ_EINT_BIT(x)		(x < IRQ_EINT16_31 ? x - IRQ_EINT0 : x - S3C_EINT(0))
 
-#define NR_IRQS 		(IRQ_EINT(31)+1)
+/* GPIO interrupt */
+#define S3C_IRQ_GPIO_BASE	(IRQ_EINT(31) + 1)
+#define S3C_IRQ_GPIO(x)		(S3C_IRQ_GPIO_BASE + (x))
+
+/*
+ * Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs
+ */
+#define NR_IRQS			(S3C_IRQ_GPIO(320) + 1)
 
 #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,68 +13,69 @@
 #ifndef __PLAT_REGS_CLOCK_H
 #define __PLAT_REGS_CLOCK_H __FILE__
 
-#define S5PC1XX_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
-
-#define S5PC1XX_APLL_LOCK		S5PC1XX_CLKREG(0x00)
-#define S5PC1XX_MPLL_LOCK		S5PC1XX_CLKREG(0x04)
-#define S5PC1XX_EPLL_LOCK		S5PC1XX_CLKREG(0x08)
-#define S5PC100_HPLL_LOCK		S5PC1XX_CLKREG(0x0C)
+#define S5PC100_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
+#define S5PC100_CLKREG_OTHER(x)		(S5PC1XX_VA_CLK_OTHER + (x))
 
-#define S5PC1XX_APLL_CON		S5PC1XX_CLKREG(0x100)
-#define S5PC1XX_MPLL_CON		S5PC1XX_CLKREG(0x104)
-#define S5PC1XX_EPLL_CON		S5PC1XX_CLKREG(0x108)
-#define S5PC100_HPLL_CON		S5PC1XX_CLKREG(0x10C)
+/* s5pc100 register for clock */
+#define S5PC100_APLL_LOCK		S5PC100_CLKREG(0x00)
+#define S5PC100_MPLL_LOCK		S5PC100_CLKREG(0x04)
+#define S5PC100_EPLL_LOCK		S5PC100_CLKREG(0x08)
+#define S5PC100_HPLL_LOCK		S5PC100_CLKREG(0x0C)
 
-#define S5PC1XX_CLK_SRC0		S5PC1XX_CLKREG(0x200)
-#define S5PC1XX_CLK_SRC1		S5PC1XX_CLKREG(0x204)
-#define S5PC1XX_CLK_SRC2		S5PC1XX_CLKREG(0x208)
-#define S5PC1XX_CLK_SRC3		S5PC1XX_CLKREG(0x20C)
+#define S5PC100_APLL_CON		S5PC100_CLKREG(0x100)
+#define S5PC100_MPLL_CON		S5PC100_CLKREG(0x104)
+#define S5PC100_EPLL_CON		S5PC100_CLKREG(0x108)
+#define S5PC100_HPLL_CON		S5PC100_CLKREG(0x10C)
 
-#define S5PC1XX_CLK_DIV0		S5PC1XX_CLKREG(0x300)
-#define S5PC1XX_CLK_DIV1		S5PC1XX_CLKREG(0x304)
-#define S5PC1XX_CLK_DIV2		S5PC1XX_CLKREG(0x308)
-#define S5PC1XX_CLK_DIV3		S5PC1XX_CLKREG(0x30C)
-#define S5PC1XX_CLK_DIV4		S5PC1XX_CLKREG(0x310)
+#define S5PC100_CLKSRC0			S5PC100_CLKREG(0x200)
+#define S5PC100_CLKSRC1			S5PC100_CLKREG(0x204)
+#define S5PC100_CLKSRC2			S5PC100_CLKREG(0x208)
+#define S5PC100_CLKSRC3			S5PC100_CLKREG(0x20C)
 
-#define S5PC100_CLK_OUT			S5PC1XX_CLKREG(0x400)
+#define S5PC100_CLKDIV0			S5PC100_CLKREG(0x300)
+#define S5PC100_CLKDIV1			S5PC100_CLKREG(0x304)
+#define S5PC100_CLKDIV2			S5PC100_CLKREG(0x308)
+#define S5PC100_CLKDIV3			S5PC100_CLKREG(0x30C)
+#define S5PC100_CLKDIV4			S5PC100_CLKREG(0x310)
 
-#define S5PC100_CLKGATE_D00		S5PC1XX_CLKREG(0x500)
-#define S5PC100_CLKGATE_D01		S5PC1XX_CLKREG(0x504)
-#define S5PC100_CLKGATE_D02		S5PC1XX_CLKREG(0x508)
+#define S5PC100_CLK_OUT			S5PC100_CLKREG(0x400)
 
-#define S5PC100_CLKGATE_D10		S5PC1XX_CLKREG(0x520)
-#define S5PC100_CLKGATE_D11		S5PC1XX_CLKREG(0x524)
-#define S5PC100_CLKGATE_D12		S5PC1XX_CLKREG(0x528)
-#define S5PC100_CLKGATE_D13		S5PC1XX_CLKREG(0x52C)
-#define S5PC100_CLKGATE_D14		S5PC1XX_CLKREG(0x530)
-#define S5PC100_CLKGATE_D15		S5PC1XX_CLKREG(0x534)
+#define S5PC100_CLKGATE_D00		S5PC100_CLKREG(0x500)
+#define S5PC100_CLKGATE_D01		S5PC100_CLKREG(0x504)
+#define S5PC100_CLKGATE_D02		S5PC100_CLKREG(0x508)
 
-#define S5PC100_CLKGATE_D20		S5PC1XX_CLKREG(0x540)
+#define S5PC100_CLKGATE_D10		S5PC100_CLKREG(0x520)
+#define S5PC100_CLKGATE_D11		S5PC100_CLKREG(0x524)
+#define S5PC100_CLKGATE_D12		S5PC100_CLKREG(0x528)
+#define S5PC100_CLKGATE_D13		S5PC100_CLKREG(0x52C)
+#define S5PC100_CLKGATE_D14		S5PC100_CLKREG(0x530)
+#define S5PC100_CLKGATE_D15		S5PC100_CLKREG(0x534)
 
-#define S5PC100_SCLKGATE0		S5PC1XX_CLKREG(0x560)
-#define S5PC100_SCLKGATE1		S5PC1XX_CLKREG(0x564)
+#define S5PC100_CLKGATE_D20		S5PC100_CLKREG(0x540)
 
-#define S5PC100_OTHERS          S5PC1XX_CLKREG(0x8200)
+#define S5PC100_SCLKGATE0		S5PC100_CLKREG(0x560)
+#define S5PC100_SCLKGATE1		S5PC100_CLKREG(0x564)
 
-#define S5PC1XX_EPLL_EN     (1<<31)
-#define S5PC1XX_EPLL_MASK   0xffffffff
-#define S5PC1XX_EPLLVAL(_m, _p, _s)   ((_m) << 16 | ((_p) << 8) | ((_s)))
+/* EPLL_CON */
+#define S5PC100_EPLL_EN			(1<<31)
+#define S5PC100_EPLL_MASK		0xffffffff
+#define S5PC100_EPLLVAL(_m, _p, _s)	((_m) << 16 | ((_p) << 8) | ((_s)))
 
 /* CLKSRC0 */
-#define S5PC1XX_CLKSRC0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKSRC0_APLL_SHIFT		(0)
-#define S5PC1XX_CLKSRC0_MPLL_MASK		(0x1<<4)
-#define S5PC1XX_CLKSRC0_MPLL_SHIFT		(4)
-#define S5PC1XX_CLKSRC0_EPLL_MASK		(0x1<<8)
-#define S5PC1XX_CLKSRC0_EPLL_SHIFT		(8)
+#define S5PC100_CLKSRC0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKSRC0_APLL_SHIFT		(0)
+#define S5PC100_CLKSRC0_MPLL_MASK		(0x1<<4)
+#define S5PC100_CLKSRC0_MPLL_SHIFT		(4)
+#define S5PC100_CLKSRC0_EPLL_MASK		(0x1<<8)
+#define S5PC100_CLKSRC0_EPLL_SHIFT		(8)
 #define S5PC100_CLKSRC0_HPLL_MASK		(0x1<<12)
 #define S5PC100_CLKSRC0_HPLL_SHIFT		(12)
 #define S5PC100_CLKSRC0_AMMUX_MASK		(0x1<<16)
 #define S5PC100_CLKSRC0_AMMUX_SHIFT		(16)
 #define S5PC100_CLKSRC0_HREF_MASK		(0x1<<20)
 #define S5PC100_CLKSRC0_HREF_SHIFT		(20)
-#define S5PC1XX_CLKSRC0_ONENAND_MASK	(0x1<<24)
-#define S5PC1XX_CLKSRC0_ONENAND_SHIFT	(24)
+#define S5PC100_CLKSRC0_ONENAND_MASK	(0x1<<24)
+#define S5PC100_CLKSRC0_ONENAND_SHIFT	(24)
 
 
 /* CLKSRC1 */
@@ -127,10 +128,9 @@
 #define S5PC100_CLKSRC3_SPDIF_MASK		(0x3<<24)
 #define S5PC100_CLKSRC3_SPDIF_SHIFT		(24)
 
-
 /* CLKDIV0 */
-#define S5PC1XX_CLKDIV0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKDIV0_APLL_SHIFT		(0)
+#define S5PC100_CLKDIV0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKDIV0_APLL_SHIFT		(0)
 #define S5PC100_CLKDIV0_ARM_MASK		(0x7<<4)
 #define S5PC100_CLKDIV0_ARM_SHIFT		(4)
 #define S5PC100_CLKDIV0_D0_MASK		(0x7<<8)
@@ -141,8 +141,8 @@
 #define S5PC100_CLKDIV0_SECSS_SHIFT		(16)
 
 /* CLKDIV1 */
-#define S5PC100_CLKDIV1_AM_MASK		(0x7<<0)
-#define S5PC100_CLKDIV1_AM_SHIFT		(0)
+#define S5PC100_CLKDIV1_APLL2_MASK		(0x7<<0)
+#define S5PC100_CLKDIV1_APLL2_SHIFT		(0)
 #define S5PC100_CLKDIV1_MPLL_MASK		(0x3<<4)
 #define S5PC100_CLKDIV1_MPLL_SHIFT		(4)
 #define S5PC100_CLKDIV1_MPLL2_MASK		(0x1<<8)
@@ -202,7 +202,6 @@
 #define S5PC100_CLKDIV4_AUDIO2_MASK		(0xf<<20)
 #define S5PC100_CLKDIV4_AUDIO2_SHIFT	(20)
 
-
 /* HCLKD0/PCLKD0 Clock Gate 0 Registers */
 #define S5PC100_CLKGATE_D00_INTC		(1<<0)
 #define S5PC100_CLKGATE_D00_TZIC		(1<<1)
@@ -295,8 +294,8 @@
 #define S5PC100_CLKGATE_D20_I2SD2		(1<<1)
 
 /* Special Clock Gate 0 Registers */
-#define	S5PC1XX_CLKGATE_SCLK0_HPM		(1<<0)
-#define	S5PC1XX_CLKGATE_SCLK0_PWI		(1<<1)
+#define	S5PC100_CLKGATE_SCLK0_HPM		(1<<0)
+#define	S5PC100_CLKGATE_SCLK0_PWI		(1<<1)
 #define	S5PC100_CLKGATE_SCLK0_ONENAND	(1<<2)
 #define	S5PC100_CLKGATE_SCLK0_UART		(1<<3)
 #define	S5PC100_CLKGATE_SCLK0_SPI0		(1<<4)
@@ -329,89 +328,28 @@
 #define	S5PC100_CLKGATE_SCLK1_SPDIF		(1<<11)
 #define	S5PC100_CLKGATE_SCLK1_CAM		(1<<12)
 
-/* register for power management */
-#define S5PC100_PWR_CFG 		S5PC1XX_CLKREG(0x8000)
-#define S5PC100_EINT_WAKEUP_MASK 	S5PC1XX_CLKREG(0x8004)
-#define S5PC100_NORMAL_CFG 		S5PC1XX_CLKREG(0x8010)
-#define S5PC100_STOP_CFG 		S5PC1XX_CLKREG(0x8014)
-#define S5PC100_SLEEP_CFG 		S5PC1XX_CLKREG(0x8018)
-#define S5PC100_STOP_MEM_CFG 	S5PC1XX_CLKREG(0x801C)
-#define S5PC100_OSC_FREQ 		S5PC1XX_CLKREG(0x8100)
-#define S5PC100_OSC_STABLE 		S5PC1XX_CLKREG(0x8104)
-#define S5PC100_PWR_STABLE 		S5PC1XX_CLKREG(0x8108)
-#define S5PC100_MTC_STABLE 		S5PC1XX_CLKREG(0x8110)
-#define S5PC100_CLAMP_STABLE 	S5PC1XX_CLKREG(0x8114)
-#define S5PC100_OTHERS 		S5PC1XX_CLKREG(0x8200)
-#define S5PC100_RST_STAT 		S5PC1XX_CLKREG(0x8300)
-#define S5PC100_WAKEUP_STAT 	S5PC1XX_CLKREG(0x8304)
-#define S5PC100_BLK_PWR_STAT 	S5PC1XX_CLKREG(0x8308)
-#define S5PC100_INFORM0 		S5PC1XX_CLKREG(0x8400)
-#define S5PC100_INFORM1 		S5PC1XX_CLKREG(0x8404)
-#define S5PC100_INFORM2 		S5PC1XX_CLKREG(0x8408)
-#define S5PC100_INFORM3 		S5PC1XX_CLKREG(0x840C)
-#define S5PC100_INFORM4 		S5PC1XX_CLKREG(0x8410)
-#define S5PC100_INFORM5 		S5PC1XX_CLKREG(0x8414)
-#define S5PC100_INFORM6 		S5PC1XX_CLKREG(0x8418)
-#define S5PC100_INFORM7 		S5PC1XX_CLKREG(0x841C)
-#define S5PC100_DCGIDX_MAP0 	S5PC1XX_CLKREG(0x8500)
-#define S5PC100_DCGIDX_MAP1 	S5PC1XX_CLKREG(0x8504)
-#define S5PC100_DCGIDX_MAP2 	S5PC1XX_CLKREG(0x8508)
-#define S5PC100_DCGPERF_MAP0 	S5PC1XX_CLKREG(0x850C)
-#define S5PC100_DCGPERF_MAP1 	S5PC1XX_CLKREG(0x8510)
-#define S5PC100_DVCIDX_MAP 		S5PC1XX_CLKREG(0x8514)
-#define S5PC100_FREQ_CPU 		S5PC1XX_CLKREG(0x8518)
-#define S5PC100_FREQ_DPM 		S5PC1XX_CLKREG(0x851C)
-#define S5PC100_DVSEMCLK_EN 	S5PC1XX_CLKREG(0x8520)
-#define S5PC100_APLL_CON_L8 	S5PC1XX_CLKREG(0x8600)
-#define S5PC100_APLL_CON_L7 	S5PC1XX_CLKREG(0x8604)
-#define S5PC100_APLL_CON_L6 	S5PC1XX_CLKREG(0x8608)
-#define S5PC100_APLL_CON_L5 	S5PC1XX_CLKREG(0x860C)
-#define S5PC100_APLL_CON_L4 	S5PC1XX_CLKREG(0x8610)
-#define S5PC100_APLL_CON_L3 	S5PC1XX_CLKREG(0x8614)
-#define S5PC100_APLL_CON_L2 	S5PC1XX_CLKREG(0x8618)
-#define S5PC100_APLL_CON_L1 	S5PC1XX_CLKREG(0x861C)
-#define S5PC100_IEM_CONTROL 	S5PC1XX_CLKREG(0x8620)
-#define S5PC100_CLKDIV_IEM_L8 	S5PC1XX_CLKREG(0x8700)
-#define S5PC100_CLKDIV_IEM_L7 	S5PC1XX_CLKREG(0x8704)
-#define S5PC100_CLKDIV_IEM_L6 	S5PC1XX_CLKREG(0x8708)
-#define S5PC100_CLKDIV_IEM_L5 	S5PC1XX_CLKREG(0x870C)
-#define S5PC100_CLKDIV_IEM_L4 	S5PC1XX_CLKREG(0x8710)
-#define S5PC100_CLKDIV_IEM_L3 	S5PC1XX_CLKREG(0x8714)
-#define S5PC100_CLKDIV_IEM_L2 	S5PC1XX_CLKREG(0x8718)
-#define S5PC100_CLKDIV_IEM_L1 	S5PC1XX_CLKREG(0x871C)
-#define S5PC100_IEM_HPMCLK_DIV 	S5PC1XX_CLKREG(0x8724)
-
-#define S5PC100_SWRESET		S5PC1XX_CLKREG(0x100000)
-#define S5PC100_OND_SWRESET		S5PC1XX_CLKREG(0x100008)
-#define S5PC100_GEN_CTRL		S5PC1XX_CLKREG(0x100100)
-#define S5PC100_GEN_STATUS		S5PC1XX_CLKREG(0x100104)
-#define S5PC100_MEM_SYS_CFG		S5PC1XX_CLKREG(0x100200)
-#define S5PC100_CAM_MUX_SEL		S5PC1XX_CLKREG(0x100300)
-#define S5PC100_MIXER_OUT_SEL	S5PC1XX_CLKREG(0x100304)
-#define S5PC100_LPMP_MODE_SEL	S5PC1XX_CLKREG(0x100308)
-#define S5PC100_MIPI_PHY_CON0	S5PC1XX_CLKREG(0x100400)
-#define S5PC100_MIPI_PHY_CON1	S5PC1XX_CLKREG(0x100414)
-#define S5PC100_HDMI_PHY_CON0	S5PC1XX_CLKREG(0x100420)
-
-#define S5PC100_CFG_WFI_CLEAN	(~(3<<5))
-#define S5PC100_CFG_WFI_IDLE	(1<<5)
-#define S5PC100_CFG_WFI_STOP	(2<<5)
-#define S5PC100_CFG_WFI_SLEEP	(3<<5)
+#define S5PC100_SWRESET		S5PC100_CLKREG_OTHER(0x000)
+#define S5PC100_OND_SWRESET	S5PC100_CLKREG_OTHER(0x008)
+#define S5PC100_GEN_CTRL	S5PC100_CLKREG_OTHER(0x100)
+#define S5PC100_GEN_STATUS	S5PC100_CLKREG_OTHER(0x104)
+#define S5PC100_MEM_SYS_CFG	S5PC100_CLKREG_OTHER(0x200)
+#define S5PC100_CAM_MUX_SEL	S5PC100_CLKREG_OTHER(0x300)
+#define S5PC100_MIXER_OUT_SEL	S5PC100_CLKREG_OTHER(0x304)
+#define S5PC100_LPMP_MODE_SEL	S5PC100_CLKREG_OTHER(0x308)
+#define S5PC100_MIPI_PHY_CON0	S5PC100_CLKREG_OTHER(0x400)
+#define S5PC100_MIPI_PHY_CON1	S5PC100_CLKREG_OTHER(0x414)
+#define S5PC100_HDMI_PHY_CON0	S5PC100_CLKREG_OTHER(0x420)
 
+#define S5PC100_SWRESET_RESETVAL	0xc100
 #define S5PC100_OTHER_SYS_INT	24
 #define S5PC100_OTHER_STA_TYPE	23
 #define STA_TYPE_EXPON		0
 #define STA_TYPE_SFR		1
 
-#define S5PC100_PWR_STA_EXP_SCALE	0
-#define S5PC100_PWR_STA_CNT		4
-
-#define S5PC100_PWR_STABLE_COUNT	85500
-
 #define S5PC100_SLEEP_CFG_OSC_EN	0
 
 /* OTHERS Resgister */
-#define S5PC100_OTHERS_USB_SIG_MASK 	(1 << 16)
+#define S5PC100_OTHERS_USB_SIG_MASK	(1 << 16)
 #define S5PC100_OTHERS_MIPI_DPHY_EN		(1 << 28)
 
 /* MIPI D-PHY Control Register 0 */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
+#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* S5PC100 */
+#define S5PC100_GPIO_BASE	S5PC1XX_VA_GPIO
+#define S5PC100_GPA0_BASE	(S5PC100_GPIO_BASE + 0x0000)
+#define S5PC100_GPA1_BASE	(S5PC100_GPIO_BASE + 0x0020)
+#define S5PC100_GPB_BASE	(S5PC100_GPIO_BASE + 0x0040)
+#define S5PC100_GPC_BASE	(S5PC100_GPIO_BASE + 0x0060)
+#define S5PC100_GPD_BASE	(S5PC100_GPIO_BASE + 0x0080)
+#define S5PC100_GPE0_BASE	(S5PC100_GPIO_BASE + 0x00A0)
+#define S5PC100_GPE1_BASE	(S5PC100_GPIO_BASE + 0x00C0)
+#define S5PC100_GPF0_BASE	(S5PC100_GPIO_BASE + 0x00E0)
+#define S5PC100_GPF1_BASE	(S5PC100_GPIO_BASE + 0x0100)
+#define S5PC100_GPF2_BASE	(S5PC100_GPIO_BASE + 0x0120)
+#define S5PC100_GPF3_BASE	(S5PC100_GPIO_BASE + 0x0140)
+#define S5PC100_GPG0_BASE	(S5PC100_GPIO_BASE + 0x0160)
+#define S5PC100_GPG1_BASE	(S5PC100_GPIO_BASE + 0x0180)
+#define S5PC100_GPG2_BASE	(S5PC100_GPIO_BASE + 0x01A0)
+#define S5PC100_GPG3_BASE	(S5PC100_GPIO_BASE + 0x01C0)
+#define S5PC100_GPH0_BASE	(S5PC100_GPIO_BASE + 0x0C00)
+#define S5PC100_GPH1_BASE	(S5PC100_GPIO_BASE + 0x0C20)
+#define S5PC100_GPH2_BASE	(S5PC100_GPIO_BASE + 0x0C40)
+#define S5PC100_GPH3_BASE	(S5PC100_GPIO_BASE + 0x0C60)
+#define S5PC100_GPI_BASE	(S5PC100_GPIO_BASE + 0x01E0)
+#define S5PC100_GPJ0_BASE	(S5PC100_GPIO_BASE + 0x0200)
+#define S5PC100_GPJ1_BASE	(S5PC100_GPIO_BASE + 0x0220)
+#define S5PC100_GPJ2_BASE	(S5PC100_GPIO_BASE + 0x0240)
+#define S5PC100_GPJ3_BASE	(S5PC100_GPIO_BASE + 0x0260)
+#define S5PC100_GPJ4_BASE	(S5PC100_GPIO_BASE + 0x0280)
+#define S5PC100_GPK0_BASE	(S5PC100_GPIO_BASE + 0x02A0)
+#define S5PC100_GPK1_BASE	(S5PC100_GPIO_BASE + 0x02C0)
+#define S5PC100_GPK2_BASE	(S5PC100_GPIO_BASE + 0x02E0)
+#define S5PC100_GPK3_BASE	(S5PC100_GPIO_BASE + 0x0300)
+#define S5PC100_GPL0_BASE	(S5PC100_GPIO_BASE + 0x0320)
+#define S5PC100_GPL1_BASE	(S5PC100_GPIO_BASE + 0x0340)
+#define S5PC100_GPL2_BASE	(S5PC100_GPIO_BASE + 0x0360)
+#define S5PC100_GPL3_BASE	(S5PC100_GPIO_BASE + 0x0380)
+#define S5PC100_GPL4_BASE	(S5PC100_GPIO_BASE + 0x03A0)
+#define S5PC100_EINT_BASE	(S5PC100_GPIO_BASE + 0x0E00)
+
+#define S5PC100_UHOST		(S5PC100_GPIO_BASE + 0x0B68)
+#define S5PC100_PDNEN		(S5PC100_GPIO_BASE + 0x0F80)
+
+/* PDNEN */
+#define S5PC100_PDNEN_CFG_PDNEN	(1 << 1)
+#define S5PC100_PDNEN_CFG_AUTO	(0 << 1)
+#define S5PC100_PDNEN_POWERDOWN	(1 << 0)
+#define S5PC100_PDNEN_NORMAL	(0 << 0)
+
+/* Common part */
+/* External interrupt base is same at both s5pc100 and s5pc110 */
+#define S5PC1XX_EINT_BASE	(S5PC100_EINT_BASE)
+
+#define S5PC100_GPx_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S5PC100_GPx_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+#define S5PC100_GPx_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+
+#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-power.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-power.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/regs-power.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,84 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Jongse Won <jongse.won@samsung.com>
+ *
+ * S5PC1XX clock 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_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S5PC1XX_PWRREG(x)			(S5PC1XX_VA_PWR + (x))
+
+/* s5pc100 (0xE0108000) register for power management */
+#define S5PC100_PWR_CFG				S5PC1XX_PWRREG(0x0)
+#define S5PC100_EINT_WAKEUP_MASK		S5PC1XX_PWRREG(0x4)
+#define S5PC100_NORMAL_CFG			S5PC1XX_PWRREG(0x10)
+#define S5PC100_STOP_CFG			S5PC1XX_PWRREG(0x14)
+#define S5PC100_SLEEP_CFG			S5PC1XX_PWRREG(0x18)
+#define S5PC100_STOP_MEM_CFG			S5PC1XX_PWRREG(0x1C)
+#define S5PC100_OSC_FREQ			S5PC1XX_PWRREG(0x100)
+#define S5PC100_OSC_STABLE			S5PC1XX_PWRREG(0x104)
+#define S5PC100_PWR_STABLE			S5PC1XX_PWRREG(0x108)
+#define S5PC100_MTC_STABLE			S5PC1XX_PWRREG(0x110)
+#define S5PC100_CLAMP_STABLE			S5PC1XX_PWRREG(0x114)
+#define S5PC100_OTHERS				S5PC1XX_PWRREG(0x200)
+#define S5PC100_RST_STAT			S5PC1XX_PWRREG(0x300)
+#define S5PC100_WAKEUP_STAT			S5PC1XX_PWRREG(0x304)
+#define S5PC100_BLK_PWR_STAT			S5PC1XX_PWRREG(0x308)
+#define S5PC100_INFORM0				S5PC1XX_PWRREG(0x400)
+#define S5PC100_INFORM1				S5PC1XX_PWRREG(0x404)
+#define S5PC100_INFORM2				S5PC1XX_PWRREG(0x408)
+#define S5PC100_INFORM3				S5PC1XX_PWRREG(0x40C)
+#define S5PC100_INFORM4				S5PC1XX_PWRREG(0x410)
+#define S5PC100_INFORM5				S5PC1XX_PWRREG(0x414)
+#define S5PC100_INFORM6				S5PC1XX_PWRREG(0x418)
+#define S5PC100_INFORM7				S5PC1XX_PWRREG(0x41C)
+#define S5PC100_DCGIDX_MAP0			S5PC1XX_PWRREG(0x500)
+#define S5PC100_DCGIDX_MAP1			S5PC1XX_PWRREG(0x504)
+#define S5PC100_DCGIDX_MAP2			S5PC1XX_PWRREG(0x508)
+#define S5PC100_DCGPERF_MAP0			S5PC1XX_PWRREG(0x50C)
+#define S5PC100_DCGPERF_MAP1			S5PC1XX_PWRREG(0x510)
+#define S5PC100_DVCIDX_MAP			S5PC1XX_PWRREG(0x514)
+#define S5PC100_FREQ_CPU			S5PC1XX_PWRREG(0x518)
+#define S5PC100_FREQ_DPM			S5PC1XX_PWRREG(0x51C)
+#define S5PC100_DVSEMCLK_EN			S5PC1XX_PWRREG(0x520)
+#define S5PC100_APLL_CON_L8			S5PC1XX_PWRREG(0x600)
+#define S5PC100_APLL_CON_L7			S5PC1XX_PWRREG(0x604)
+#define S5PC100_APLL_CON_L6			S5PC1XX_PWRREG(0x608)
+#define S5PC100_APLL_CON_L5			S5PC1XX_PWRREG(0x60C)
+#define S5PC100_APLL_CON_L4			S5PC1XX_PWRREG(0x610)
+#define S5PC100_APLL_CON_L3			S5PC1XX_PWRREG(0x614)
+#define S5PC100_APLL_CON_L2			S5PC1XX_PWRREG(0x618)
+#define S5PC100_APLL_CON_L1			S5PC1XX_PWRREG(0x61C)
+#define S5PC100_IEM_CONTROL			S5PC1XX_PWRREG(0x620)
+#define S5PC100_CLKDIV_IEM_L8			S5PC1XX_PWRREG(0x700)
+#define S5PC100_CLKDIV_IEM_L7			S5PC1XX_PWRREG(0x704)
+#define S5PC100_CLKDIV_IEM_L6			S5PC1XX_PWRREG(0x708)
+#define S5PC100_CLKDIV_IEM_L5			S5PC1XX_PWRREG(0x70C)
+#define S5PC100_CLKDIV_IEM_L4			S5PC1XX_PWRREG(0x710)
+#define S5PC100_CLKDIV_IEM_L3			S5PC1XX_PWRREG(0x714)
+#define S5PC100_CLKDIV_IEM_L2			S5PC1XX_PWRREG(0x718)
+#define S5PC100_CLKDIV_IEM_L1			S5PC1XX_PWRREG(0x71C)
+#define S5PC100_IEM_HPMCLK_DIV			S5PC1XX_PWRREG(0x724)
+
+/* PWR_CFG */
+#define S5PC100_PWRCFG_CFG_DEEP_IDLE		(1 << 31)
+#define S5PC100_PWRCFG_CFG_WFI_MASK		(3 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_IDLE		(0 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE	(1 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_STOP		(2 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_SLEEP		(3 << 5)
+
+/* SLEEP_CFG */
+#define S5PC100_SLEEP_OSC_EN_SLEEP		(1 << 0)
+
+/* OTHERS */
+#define S5PC100_PMU_INT_DISABLE			(1 << 24)
+
+#endif /* __ASM_ARM_REGS_PWR */
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,10 +35,9 @@ extern struct clk clk_hpll;
 extern struct clk clk_hd0;
 extern struct clk clk_pd0;
 extern struct clk clk_54m;
-extern struct clk clk_dout_mpll2;
 extern void s5pc1xx_register_clocks(void);
-extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
-extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk0_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk1_ctrl(struct clk *clk, int enable);
 
 /* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
 extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ static void s3c_irq_timer_ack(unsigned i
 {
 	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
 
-	reg &= 0x1f;
+	reg &= 0x1f;  /* mask out pending interrupts */
 	reg |= (1 << 5) << (irq - IRQ_TIMER0);
 	__raw_writel(reg, S3C64XX_TINT_CSTAT);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq-eint.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq-eint.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq-eint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq-eint.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,281 @@
+/*
+ * linux/arch/arm/plat-s5pc1xx/irq-eint.c
+ *
+ *  Copyright 2009 Samsung Electronics Co.
+ *  Byungho Min <bhmin@samsung.com>
+ *  Kyungin Park <kyungmin.park@samsung.com>
+ *
+ * Based on plat-s3c64xx/irq-eint.c
+ *
+ * S5PC1XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+#include <linux/gpio.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-ext.h>
+#include <plat/pm.h>
+#include <plat/regs-gpio.h>
+#include <plat/regs-irqtype.h>
+
+/*
+ * bank is a group of external interrupt
+ * bank0 means EINT0 ... EINT7
+ * bank1 means EINT8 ... EINT15
+ * bank2 means EINT16 ... EINT23
+ * bank3 means EINT24 ... EINT31
+ */
+
+static inline int s3c_get_eint(unsigned int irq)
+{
+	int real;
+
+	if (irq < IRQ_EINT16_31)
+		real = (irq - IRQ_EINT0);
+	else
+		real = (irq - S3C_IRQ_EINT_BASE) + IRQ_EINT16_31 - IRQ_EINT0;
+
+	return real;
+}
+
+static inline int s3c_get_bank(unsigned int irq)
+{
+	return s3c_get_eint(irq) >> 3;
+}
+
+static inline int s3c_eint_to_bit(unsigned int irq)
+{
+	int real, bit;
+
+	real = s3c_get_eint(irq);
+	bit = 1 << (real & (8 - 1));
+
+	return bit;
+}
+
+static inline void s3c_irq_eint_mask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask |= s3c_eint_to_bit(irq);
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static void s3c_irq_eint_unmask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask &= ~(s3c_eint_to_bit(irq));
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static inline void s3c_irq_eint_ack(unsigned int irq)
+{
+	u32 bank = s3c_get_bank(irq);
+
+	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_ack(irq);
+}
+
+static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+	u32 bank = s3c_get_bank(irq);
+	int real = s3c_get_eint(irq);
+	int gpio, shift, sfn;
+	u32 ctrl, con = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No edge setting!\n");
+		break;
+
+	case IRQ_TYPE_EDGE_RISING:
+		con = S5PC1XX_WKUP_INT_RISEEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		con = S5PC1XX_WKUP_INT_FALLEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_BOTH:
+		con = S5PC1XX_WKUP_INT_BOTHEDGE;
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		con = S5PC1XX_WKUP_INT_LOWLEV;
+		break;
+
+	case IRQ_TYPE_LEVEL_HIGH:
+		con = S5PC1XX_WKUP_INT_HILEV;
+		break;
+
+	default:
+		printk(KERN_ERR "No such irq type %d", type);
+		return -EINVAL;
+	}
+
+	gpio = real & (8 - 1);
+	shift = gpio << 2;
+
+	ctrl = __raw_readl(S5PC1XX_WKUP_INT_CON(bank));
+	ctrl &= ~(0x7 << shift);
+	ctrl |= con << shift;
+	__raw_writel(ctrl, S5PC1XX_WKUP_INT_CON(bank));
+
+	switch (real) {
+	case 0 ... 7:
+			gpio = S5PC100_GPH0(gpio);
+		break;
+	case 8 ... 15:
+			gpio = S5PC100_GPH1(gpio);
+		break;
+	case 16 ... 23:
+			gpio = S5PC100_GPH2(gpio);
+		break;
+	case 24 ... 31:
+			gpio = S5PC100_GPH3(gpio);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sfn = S3C_GPIO_SFN(0x2);
+	s3c_gpio_cfgpin(gpio, sfn);
+
+	return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_eint_mask,
+	.unmask		= s3c_irq_eint_unmask,
+	.mask_ack	= s3c_irq_eint_maskack,
+	.ack		= s3c_irq_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from external interrupts,
+ * from IRQ_EINT(16) to IRQ_EINT(31). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+	u32 status = __raw_readl(S5PC1XX_WKUP_INT_PEND((start >> 3)));
+	u32 mask = __raw_readl(S5PC1XX_WKUP_INT_MASK((start >> 3)));
+	unsigned int irq;
+
+	status &= ~mask;
+	status &= (1 << (end - start + 1)) - 1;
+
+	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+		if (status & 1)
+			generic_handle_irq(irq);
+
+		status >>= 1;
+	}
+}
+
+static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(16, 23);
+	s3c_irq_demux_eint(24, 31);
+}
+
+/*
+ * Handle EINT0 ... EINT15 at VIC directly
+ */
+static void s3c_irq_vic_eint_mask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_mask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void s3c_irq_vic_eint_unmask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_unmask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE);
+}
+
+static inline void s3c_irq_vic_eint_ack(unsigned int irq)
+{
+	u32 bit;
+	u32 bank = s3c_get_bank(irq);
+
+	bit = s3c_eint_to_bit(irq);
+	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_vic_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_vic_eint_mask(irq);
+	s3c_irq_vic_eint_ack(irq);
+}
+
+static struct irq_chip s3c_irq_vic_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_vic_eint_mask,
+	.unmask		= s3c_irq_vic_eint_unmask,
+	.mask_ack	= s3c_irq_vic_eint_maskack,
+	.ack		= s3c_irq_vic_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+static int __init s5pc1xx_init_irq_eint(void)
+{
+	int irq;
+
+	for (irq = IRQ_EINT0; irq <= IRQ_EINT15; irq++) {
+		set_irq_chip(irq, &s3c_irq_vic_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
+		set_irq_chip(irq, &s3c_irq_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_EINT16_31, s3c_irq_demux_eint16_31);
+
+	return 0;
+}
+
+arch_initcall(s5pc1xx_init_irq_eint);
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq-gpio.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq-gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/irq-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/irq-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,266 @@
+/*
+ * arch/arm/plat-s5pc1xx/irq-gpio.c
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ *
+ * S5PC1XX - Interrupt handling for IRQ_GPIO${group}(x)
+ *
+ * This 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <plat/gpio-cfg.h>
+
+#define S5PC1XX_GPIOREG(x)		(S5PC1XX_VA_GPIO + (x))
+
+#define CON_OFFSET			0x700
+#define MASK_OFFSET			0x900
+#define PEND_OFFSET			0xA00
+#define CON_OFFSET_2			0xE00
+#define MASK_OFFSET_2			0xF00
+#define PEND_OFFSET_2			0xF40
+
+#define GPIOINT_LEVEL_LOW		0x0
+#define GPIOINT_LEVEL_HIGH		0x1
+#define GPIOINT_EDGE_FALLING		0x2
+#define GPIOINT_EDGE_RISING		0x3
+#define GPIOINT_EDGE_BOTH		0x4
+
+static int group_to_con_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_mask_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_pend_offset(int group)
+{
+	return group << 2;
+}
+
+static int s5pc1xx_get_start(unsigned int group)
+{
+	switch (group) {
+	case 0: return S5PC100_GPIO_A0_START;
+	case 1: return S5PC100_GPIO_A1_START;
+	case 2: return S5PC100_GPIO_B_START;
+	case 3: return S5PC100_GPIO_C_START;
+	case 4: return S5PC100_GPIO_D_START;
+	case 5: return S5PC100_GPIO_E0_START;
+	case 6: return S5PC100_GPIO_E1_START;
+	case 7: return S5PC100_GPIO_F0_START;
+	case 8: return S5PC100_GPIO_F1_START;
+	case 9: return S5PC100_GPIO_F2_START;
+	case 10: return S5PC100_GPIO_F3_START;
+	case 11: return S5PC100_GPIO_G0_START;
+	case 12: return S5PC100_GPIO_G1_START;
+	case 13: return S5PC100_GPIO_G2_START;
+	case 14: return S5PC100_GPIO_G3_START;
+	case 15: return S5PC100_GPIO_I_START;
+	case 16: return S5PC100_GPIO_J0_START;
+	case 17: return S5PC100_GPIO_J1_START;
+	case 18: return S5PC100_GPIO_J2_START;
+	case 19: return S5PC100_GPIO_J3_START;
+	case 20: return S5PC100_GPIO_J4_START;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_group(unsigned int irq)
+{
+	irq -= S3C_IRQ_GPIO(0);
+
+	switch (irq) {
+	case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
+		return 0;
+	case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
+		return 1;
+	case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
+		return 2;
+	case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
+		return 3;
+	case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
+		return 4;
+	case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
+		return 5;
+	case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
+		return 6;
+	case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
+		return 7;
+	case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
+		return 8;
+	case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
+		return 9;
+	case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
+		return 10;
+	case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
+		return 11;
+	case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
+		return 12;
+	case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
+		return 13;
+	case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
+		return 14;
+	case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
+		return 15;
+	case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
+		return 16;
+	case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
+		return 17;
+	case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
+		return 18;
+	case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
+		return 19;
+	case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
+		return 20;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_offset(unsigned int irq)
+{
+	struct gpio_chip *chip = get_irq_data(irq);
+	return irq - S3C_IRQ_GPIO(chip->base);
+}
+
+static void s5pc1xx_gpioint_ack(unsigned int irq)
+{
+	int group, offset, pend_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	pend_offset = group_to_pend_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+}
+
+static void s5pc1xx_gpioint_mask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_unmask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value &= ~(1 << offset);
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
+{
+	s5pc1xx_gpioint_mask(irq);
+	s5pc1xx_gpioint_ack(irq);
+}
+
+static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
+{
+	int group, offset, con_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	con_offset = group_to_con_offset(group);
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No irq type\n");
+		return -EINVAL;
+	case IRQ_TYPE_EDGE_RISING:
+		type = GPIOINT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		type = GPIOINT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		type = GPIOINT_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		type = GPIOINT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		type = GPIOINT_LEVEL_LOW;
+		break;
+	default:
+		BUG();
+	}
+
+
+	value = __raw_readl(S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+	value &= ~(0xf << (offset * 0x4));
+	value |= (type << (offset * 0x4));
+	__raw_writel(value, S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+
+	return 0;
+}
+
+struct irq_chip s5pc1xx_gpioint = {
+	.name		= "GPIO",
+	.ack		= s5pc1xx_gpioint_ack,
+	.mask		= s5pc1xx_gpioint_mask,
+	.mask_ack	= s5pc1xx_gpioint_mask_ack,
+	.unmask		= s5pc1xx_gpioint_unmask,
+	.set_type	= s5pc1xx_gpioint_set_type,
+};
+
+void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int group, offset, pend_offset, mask_offset;
+	int real_irq, group_end;
+	unsigned int pend, mask;
+
+	group_end = 21;
+
+	for (group = 0; group < group_end; group++) {
+		pend_offset = group_to_pend_offset(group);
+		pend = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+		if (!pend)
+			continue;
+
+		mask_offset = group_to_mask_offset(group);
+		mask = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+		pend &= ~mask;
+
+		for (offset = 0; offset < 8; offset++) {
+			if (pend & (1 << offset)) {
+				real_irq = s5pc1xx_get_start(group) + offset;
+				generic_handle_irq(S3C_IRQ_GPIO(real_irq));
+			}
+		}
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# arch/arm/plat-s5pc1xx/Kconfig
-#
 # Copyright 2009 Samsung Electronics Co.
 #	Byungho Min <bhmin@samsung.com>
 #
@@ -15,6 +13,9 @@ config PLAT_S5PC1XX
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
+	select S3C_GPIO_CFG_S3C24XX
+	select S3C_GPIO_CFG_S3C64XX
+	select S5P_GPIO_CFG_S5PC1XX
 	help
 	  Base platform code for any Samsung S5PC1XX device
 
@@ -34,7 +35,12 @@ config CPU_S5PC100_CLOCK
 
 # platform specific device setup
 
-config S5PC100_SETUP_I2C0
+config S5PC1XX_SETUP_FB_24BPP
+	bool
+	help
+          Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
+config S5PC1XX_SETUP_I2C0
 	bool
 	default y
 	help
@@ -43,8 +49,14 @@ config S5PC100_SETUP_I2C0
 	  Note, currently since i2c0 is always compiled, this setup helper
 	  is always compiled with it.
 
-config S5PC100_SETUP_I2C1
+config S5PC1XX_SETUP_I2C1
 	bool
 	help
 	  Common setup code for i2c bus 1.
+
+config S5PC1XX_SETUP_SDHCI_GPIO
+	bool
+	help
+	  Common setup code for SDHCI gpio.
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,9 @@ obj-				:=
 
 obj-y				+= dev-uart.o
 obj-y				+= cpu.o
-obj-y				+= irq.o
+obj-y				+= irq.o irq-gpio.o irq-eint.o
+obj-y				+= clock.o
+obj-y				+= gpiolib.o
 
 # CPU support
 
@@ -22,5 +24,8 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc1
 
 # Device setup
 
-obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5P_GPIO_CFG_S5PC1XX) += gpio-config.o
+obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/s5pc100-clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,7 @@ static struct clk clk_ext_xtal_mux = {
 #define clk_fin_hpll clk_ext_xtal_mux
 
 #define clk_fout_mpll	clk_mpll
+#define clk_vclk_54m	clk_54m
 
 struct clk_sources {
 	unsigned int	nr_sources;
@@ -67,746 +68,327 @@ struct clksrc_clk {
 	void __iomem		*reg_source;
 };
 
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
-	clk->rate = rate;
-	return 1;
-}
-
-struct clk clk_27m = {
-	.name		= "clk_27m",
+/* APLL */
+static struct clk clk_fout_apll = {
+	.name		= "fout_apll",
 	.id		= -1,
 	.rate		= 27000000,
 };
 
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
-	unsigned long flags;
-	u32 val;
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
 
-	/* can't rely on clock lock, this register has other usages */
-	local_irq_save(flags);
+static struct clk_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
 
-	val = __raw_readl(S5PC1XX_CLK_SRC1);
-	if (enable)
-		val |= S5PC100_CLKSRC1_CLK48M_MASK;
-	else
-		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_APLL_MASK,
+	.sources	= &clk_src_apll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	__raw_writel(val, S5PC1XX_CLK_SRC1);
-	local_irq_restore(flags);
+static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	return 0;
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_APLL_MASK;
+	ratio >>= S5PC100_CLKDIV0_APLL_SHIFT;
 
-struct clk clk_48m = {
-	.name		= "clk_48m",
-	.id		= -1,
-	.rate		= 48000000,
-	.enable		= clk_48m_ctrl,
-};
+	return rate / (ratio + 1);
+}
 
-struct clk clk_54m = {
-	.name		= "clk_54m",
+static struct clk clk_dout_apll = {
+	.name		= "dout_apll",
 	.id		= -1,
-	.rate		= 54000000,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll_get_rate,
 };
 
-struct clk clk_hpll = {
-	.name		= "hpll",
-	.id		= -1,
-};
+static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-struct clk clk_hd0 = {
-	.name		= "hclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_ARM_MASK;
+	ratio >>= S5PC100_CLKDIV0_ARM_SHIFT;
 
-struct clk clk_pd0 = {
-	.name		= "pclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	return rate / (ratio + 1);
+}
 
-static int s5pc1xx_clk_gate(void __iomem *reg,
-				struct clk *clk,
-				int enable)
+static unsigned long s5pc100_clk_arm_round_rate(struct clk *clk,
+						unsigned long rate)
 {
-	unsigned int ctrlbit = clk->ctrlbit;
-	u32 con;
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
 
-	con = __raw_readl(reg);
+	if (parent < rate)
+		return rate;
 
-	if (enable)
-		con |= ctrlbit;
-	else
-		con &= ~ctrlbit;
+	div = (parent / rate) - 1;
+	if (div > S5PC100_CLKDIV0_ARM_MASK)
+		div = S5PC100_CLKDIV0_ARM_MASK;
 
-	__raw_writel(con, reg);
-	return 0;
+	return parent / (div + 1);
 }
 
-static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
+static int s5pc100_clk_arm_set_rate(struct clk *clk, unsigned long rate)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
-}
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
+	u32 val;
 
-static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
-}
+	if (rate < parent / (S5PC100_CLKDIV0_ARM_MASK + 1))
+		return -EINVAL;
 
-static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
-}
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
 
-static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
-}
+	val = __raw_readl(S5PC100_CLKDIV0);
+	val &= S5PC100_CLKDIV0_ARM_MASK;
+	val |= (div - 1);
+	__raw_writel(val, S5PC100_CLKDIV0);
 
-static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+	return 0;
 }
 
-static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
-}
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.parent		= &clk_dout_apll,
+	.get_rate	= s5pc100_clk_arm_get_rate,
+	.set_rate	= s5pc100_clk_arm_set_rate,
+	.round_rate	= s5pc100_clk_arm_round_rate,
+};
 
-static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
-}
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_D0_MASK;
+	ratio >>= S5PC100_CLKDIV0_D0_SHIFT;
 
-static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+	return rate / (ratio + 1);
 }
 
-static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
-}
+static struct clk clk_dout_d0_bus = {
+	.name		= "dout_d0_bus",
+	.id		= -1,
+	.parent		= &clk_arm,
+	.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+};
 
-int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_PCLKD0_MASK;
+	ratio >>= S5PC100_CLKDIV0_PCLKD0_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
+static struct clk clk_dout_pclkd0 = {
+	.name		= "dout_pclkd0",
+	.id		= -1,
+	.parent		= &clk_dout_d0_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+};
+
+static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_APLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_APLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-static struct clk init_clocks_disable[] = {
-	{
-		.name		= "dsi",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
-	}, {
-		.name		= "csi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
-	}, {
-		.name		= "ccan0",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
-	}, {
-		.name		= "ccan1",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
-	}, {
-		.name		= "keypad",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "hclkd2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
-	}, {
-		.name		= "iis-d2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
-	}, {
-		.name		= "otg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
-	},
+static struct clk clk_dout_apll2 = {
+	.name		= "dout_apll2",
+	.id		= -1,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll2_get_rate,
 };
 
-static struct clk init_clocks[] = {
-	/* System1 (D0_0) devices */
-	{
-		.name		= "intc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
-	}, {
-		.name		= "tzic",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
-	}, {
-		.name		= "cf-ata",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
-	}, {
-		.name		= "mdma",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
-	}, {
-		.name		= "g2d",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
-	}, {
-		.name		= "secss",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
-	}, {
-		.name		= "cssys",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
-	},
+/* MPLL */
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
 
-	/* Memory (D0_1) devices */
-	{
-		.name		= "dmc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
-	}, {
-		.name		= "sromc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
-	}, {
-		.name		= "onenand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
-	}, {
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
-	}, {
-		.name		= "intmem",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
-	}, {
-		.name		= "ebi",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
-	},
+static struct clk_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
 
-	/* System2 (D0_2) devices */
-	{
-		.name		= "seckey",
-		.id		= -1,
-		.parent		= &clk_pd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
-	}, {
-		.name		= "sdm",
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
 		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
 	},
+	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
+	.sources	= &clk_src_mpll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* File (D1_0) devices */
-	{
-		.name		= "pdma0",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
-	}, {
-		.name		= "pdma1",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
-	}, {
-		.name		= "modem",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
-	}, {
-		.name		= "hsmmc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
-	}, {
-		.name		= "hsmmc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
-	}, {
-		.name		= "hsmmc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
-	},
+static struct clk *clkset_am_list[] = {
+	[0] = &clk_mout_mpll.clk,
+	[1] = &clk_dout_apll2,
+};
 
-	/* Multimedia1 (D1_1) devices */
-	{
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
-	}, {
-		.name		= "rotator",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
-	}, {
-		.name		= "fimc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
-	}, {
-		.name		= "fimc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
-	}, {
-		.name		= "fimc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
-	}, {
-		.name		= "jpeg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
-	}, {
-		.name		= "g3d",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
-	},
+static struct clk_sources clk_src_am = {
+	.sources	= clkset_am_list,
+	.nr_sources	= ARRAY_SIZE(clkset_am_list),
+};
 
-	/* Multimedia2 (D1_2) devices */
-	{
-		.name		= "tv",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
-	}, {
-		.name		= "vp",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
-	}, {
-		.name		= "mixer",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
-	}, {
-		.name		= "hdmi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
-	}, {
-		.name		= "mfc",
+static struct clksrc_clk clk_mout_am = {
+	.clk = {
+		.name		= "mout_am",
 		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
 	},
+	.shift		= S5PC100_CLKSRC0_AMMUX_SHIFT,
+	.mask		= S5PC100_CLKSRC0_AMMUX_MASK,
+	.sources	= &clk_src_am,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* System (D1_3) devices */
-	{
-		.name		= "chipid",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
-	}, {
-		.name		= "apc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
-	}, {
-		.name		= "iec",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
-	}, {
-		.name		= "systimer",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
-	},
+static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	/* Connectivity (D1_4) devices */
-	{
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
-	}, {
-		.name		= "hdmi-i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
-	}, {
-		.name		= "spi",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
-	}, {
-		.name		= "spi",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
-	}, {
-		.name		= "spi",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
-	}, {
-		.name		= "irda",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
-	}, {
-		.name		= "hsitx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
-	}, {
-		.name		= "hsirx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
-	},
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	/* Audio (D1_5) devices */
-	{
-		.name		= "iis",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
-	}, {
-		.name		= "iis",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
-	}, {
-		.name		= "iis",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
-	}, {
-		.name		= "ac97",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
-	}, {
-		.name		= "pcm",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
-	}, {
-		.name		= "pcm",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
-	}, {
-		.name		= "spdif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
-	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
-	}, {
-		.name		= "keyif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "cg",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
-	},
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_D1_MASK;
+	ratio >>= S5PC100_CLKDIV1_D1_SHIFT;
 
-	/* Audio (D2_0) devices: all disabled */
+	return rate / (ratio + 1);
+}
 
-	/* Special Clocks 1 */
-	{
-		.name		= "sclk_hpm",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC1XX_CLKGATE_SCLK0_HPM,
-	}, {
-		.name		= "sclk_onenand",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
-	},
+static struct clk clk_dout_d1_bus = {
+	.name		= "dout_d1_bus",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+};
 
-	/* Special Clocks 2 */
-	{
-		.name		= "sclk_tv_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_TV54,
-	}, {
-		.name		= "sclk_vdac_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_VDAC54,
-	}, {
-		.name		= "sclk_spdif",
+static struct clk *clkset_onenand_list[] = {
+	[0] = &clk_dout_d0_bus,
+	[1] = &clk_dout_d1_bus,
+};
+
+static struct clk_sources clk_src_onenand = {
+	.sources	= clkset_onenand_list,
+	.nr_sources	= ARRAY_SIZE(clkset_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+	.clk = {
+		.name		= "mout_onenand",
 		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_SPDIF,
 	},
+	.shift		= S5PC100_CLKSRC0_ONENAND_SHIFT,
+	.mask		= S5PC100_CLKSRC0_ONENAND_MASK,
+	.sources	= &clk_src_onenand,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
-void __init s5pc1xx_register_clocks(void)
+static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
 {
-	struct clk *clkp;
-	int ret;
-	int ptr;
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_PCLKD1_MASK;
+	ratio >>= S5PC100_CLKDIV1_PCLKD1_SHIFT;
 
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
+	return rate / (ratio + 1);
+}
 
-		(clkp->enable)(clkp, 0);
-	}
+static struct clk clk_dout_pclkd1 = {
+	.name		= "dout_pclkd1",
+	.id		= -1,
+	.parent		= &clk_dout_d1_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+};
 
-	s3c_pwmclk_init();
+static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
-static struct clk clk_fout_apll = {
-	.name		= "fout_apll",
+
+static struct clk clk_dout_mpll2 = {
+	.name		= "dout_mpll2",
 	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
 };
 
-static struct clk *clk_src_apll_list[] = {
-	[0] = &clk_fin_apll,
-	[1] = &clk_fout_apll,
-};
+static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static struct clk_sources clk_src_apll = {
-	.sources	= clk_src_apll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_CAM_MASK;
+	ratio >>= S5PC100_CLKDIV1_CAM_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_cam = {
+	.name		= "dout_cam",
+	.id		= -1,
+	.parent		= &clk_dout_mpll2,
+	.get_rate	= s5pc100_clk_dout_cam_get_rate,
 };
 
-static struct clksrc_clk clk_mout_apll = {
-	.clk	= {
-		.name		= "mout_apll",
-		.id		= -1,
-	},
-	.shift		= S5PC1XX_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_APLL_MASK,
-	.sources	= &clk_src_apll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll_get_rate,
 };
 
+/* EPLL */
 static struct clk clk_fout_epll = {
 	.name		= "fout_epll",
 	.id		= -1,
@@ -827,91 +409,57 @@ static struct clksrc_clk clk_mout_epll =
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_EPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_EPLL_MASK,
+	.shift		= S5PC100_CLKSRC0_EPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_EPLL_MASK,
 	.sources	= &clk_src_epll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
-};
-
-static struct clk *clk_src_mpll_list[] = {
-	[0] = &clk_fin_mpll,
-	[1] = &clk_fout_mpll,
-};
-
-static struct clk_sources clk_src_mpll = {
-	.sources	= clk_src_mpll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
-};
-
-static struct clksrc_clk clk_mout_mpll = {
-	.clk = {
-		.name		= "mout_mpll",
-		.id		= -1,
-	},
-	.shift		= S5PC1XX_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_MPLL_MASK,
-	.sources	= &clk_src_mpll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
-static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
-
-	return rate;
-}
-
-static struct clk clk_dout_mpll = {
-	.name		= "dout_mpll",
+/* HPLL */
+static struct clk clk_fout_hpll = {
+	.name		= "fout_hpll",
 	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll_get_rate,
 };
 
-static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
-
-	return rate;
-}
-
-struct clk clk_dout_mpll2 = {
-	.name		= "dout_mpll2",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll2_get_rate,
+static struct clk *clk_src_hpll_list[] = {
+	[0] = &clk_27m,
+	[1] = &clk_fout_hpll,
 };
 
-static struct clk *clkset_uart_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	NULL,
-	NULL
+static struct clk_sources clk_src_hpll = {
+	.sources	= clk_src_hpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_hpll_list),
 };
 
-static struct clk_sources clkset_uart = {
-	.sources	= clkset_uart_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+static struct clksrc_clk clk_mout_hpll = {
+	.clk	= {
+		.name		= "mout_hpll",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC0_HPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_HPLL_MASK,
+	.sources	= &clk_src_hpll,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
+/* Peripherals */
+/*
+ * The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S5PC100 version, and also
+ * have a common parent divisor so are not included here.
+ */
+
 static inline struct clksrc_clk *to_clksrc(struct clk *clk)
 {
 	return container_of(clk, struct clksrc_clk, clk);
 }
 
-static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
+static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	unsigned long rate = clk_get_rate(clk->parent);
@@ -925,7 +473,7 @@ static unsigned long s5pc1xx_getrate_clk
 	return rate;
 }
 
-static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
+static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	void __iomem *reg = sclk->reg_divider;
@@ -938,14 +486,14 @@ static int s5pc1xx_setrate_clksrc(struct
 		return -EINVAL;
 
 	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->shift);
-	val |= (div - 1) << sclk->shift;
+	val &= ~(0xf << sclk->divider_shift);
+	val |= (div - 1) << sclk->divider_shift;
 	__raw_writel(val, reg);
 
 	return 0;
 }
 
-static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
+static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	struct clk_sources *srcs = sclk->sources;
@@ -970,7 +518,7 @@ static int s5pc1xx_setparent_clksrc(stru
 	return -EINVAL;
 }
 
-static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
+static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
 					      unsigned long rate)
 {
 	unsigned long parent_rate = clk_get_rate(clk->parent);
@@ -992,35 +540,466 @@ static unsigned long s5pc1xx_roundrate_c
 	return rate;
 }
 
+static struct clk *clkset_spi_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll2,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_spi = {
+	.sources	= clkset_spi_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_list),
+};
+
+static struct clksrc_clk clk_spi0 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI0_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI0_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi1 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI1_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI1_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi2 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI2_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI2_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+};
+
+static struct clk_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
 static struct clksrc_clk clk_uart_uclk1 = {
 	.clk	= {
 		.name		= "uclk1",
 		.id		= -1,
 		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.set_parent	= s5pc1xx_setparent_clksrc,
-		.get_rate	= s5pc1xx_getrate_clksrc,
-		.set_rate	= s5pc1xx_setrate_clksrc,
-		.round_rate	= s5pc1xx_roundrate_clksrc,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
 	},
 	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
 	.sources	= &clkset_uart,
 	.divider_shift	= S5PC100_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S5PC1XX_CLK_DIV2,
-	.reg_source	= S5PC1XX_CLK_SRC1,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clk clk_iis_cd0 = {
+	.name		= "iis_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd1 = {
+	.name		= "iis_cdclk1",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd2 = {
+	.name		= "iis_cdclk2",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd0 = {
+	.name		= "pcm_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd1 = {
+	.name		= "pcm_cdclk1",
+	.id		= -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd0,
+	&clk_pcm_cd0,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio0 = {
+	.sources	= clkset_audio0_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clksrc_clk clk_audio0 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO0_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO0_MASK,
+	.sources	= &clkset_audio0,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio1_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd1,
+	&clk_pcm_cd1,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio1 = {
+	.sources	= clkset_audio1_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clksrc_clk clk_audio1 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO1_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO1_MASK,
+	.sources	= &clkset_audio1,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio2_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd2,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio2 = {
+	.sources	= clkset_audio2_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio2_list),
+};
+
+static struct clksrc_clk clk_audio2 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO2_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO2_MASK,
+	.sources	= &clkset_audio2,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_spdif_list[] = {
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+};
+
+static struct clk_sources clkset_spdif = {
+	.sources	= clkset_spdif_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spdif_list),
+};
+
+static struct clksrc_clk clk_spdif = {
+	.clk	= {
+		.name		= "spdif",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC3_SPDIF_SHIFT,
+	.mask		= S5PC100_CLKSRC3_SPDIF_MASK,
+	.sources	= &clkset_spdif,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_lcd_fimc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_vclk_54m,
+};
+
+static struct clk_sources clkset_lcd_fimc = {
+	.sources	= clkset_lcd_fimc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_lcd_fimc_list),
+};
+
+static struct clksrc_clk clk_lcd = {
+	.clk	= {
+		.name		= "lcd",
+		.id		= -1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_LCD_SHIFT,
+	.mask		= S5PC100_CLKSRC2_LCD_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_LCD_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc0 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC0_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc1 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC1_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc2 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC2_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clk *clkset_mmc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk ,
+};
+
+static struct clk_sources clkset_mmc = {
+	.sources	= clkset_mmc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_mmc_list),
+};
+
+static struct clksrc_clk clk_mmc0 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC0_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc1 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC1_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc2 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC2_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+
+static struct clk *clkset_usbhost_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_48m,
+};
+
+static struct clk_sources clkset_usbhost = {
+	.sources	= clkset_usbhost_list,
+	.nr_sources	= ARRAY_SIZE(clkset_usbhost_list),
+};
+
+static struct clksrc_clk clk_usbhost = {
+	.clk	= {
+		.name		= "usbhost",
+		.id		= -1,
+		.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_UHOST_SHIFT,
+	.mask		= S5PC100_CLKSRC1_UHOST_MASK,
+	.sources	= &clkset_usbhost,
+	.divider_shift	= S5PC100_CLKDIV2_UHOST_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
 };
 
 /* Clock initialisation code */
 
 static struct clksrc_clk *init_parents[] = {
 	&clk_mout_apll,
-	&clk_mout_epll,
 	&clk_mout_mpll,
+	&clk_mout_am,
+	&clk_mout_onenand,
+	&clk_mout_epll,
+	&clk_mout_hpll,
+	&clk_spi0,
+	&clk_spi1,
+	&clk_spi2,
 	&clk_uart_uclk1,
+	&clk_audio0,
+	&clk_audio1,
+	&clk_audio2,
+	&clk_spdif,
+	&clk_lcd,
+	&clk_fimc0,
+	&clk_fimc1,
+	&clk_fimc2,
+	&clk_mmc0,
+	&clk_mmc1,
+	&clk_mmc2,
+	&clk_usbhost,
 };
 
-static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
+static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
 {
 	struct clk_sources *srcs = clk->sources;
 	u32 clksrc = __raw_readl(clk->reg_source);
@@ -1036,9 +1015,9 @@ static void __init_or_cpufreq s5pc1xx_se
 
 	clk->clk.parent = srcs->sources[clksrc];
 
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-	       clk->clk.name, clk->clk.parent->name, clksrc,
-	       clk_get_rate(&clk->clk));
+	printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
+		clk->clk.name, clk->clk.parent->name, clksrc,
+		print_mhz(clk_get_rate(&clk->clk)));
 }
 
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
@@ -1052,20 +1031,16 @@ void __init_or_cpufreq s5pc100_setup_clo
 	unsigned long hclk;
 	unsigned long pclkd0;
 	unsigned long pclk;
-	unsigned long apll;
-	unsigned long mpll;
-	unsigned long hpll;
-	unsigned long epll;
+	unsigned long apll, mpll, epll, hpll;
 	unsigned int ptr;
 	u32 clkdiv0, clkdiv1;
 
 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
 
-	clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
-	clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
+	clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
+	clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
 
-	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
-			__func__, clkdiv0, clkdiv1);
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", __func__, clkdiv0, clkdiv1);
 
 	xtal_clk = clk_get(NULL, "xtal");
 	BUG_ON(IS_ERR(xtal_clk));
@@ -1075,48 +1050,81 @@ void __init_or_cpufreq s5pc100_setup_clo
 
 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
 
-	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
-	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
-	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
+	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON));
+	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON));
+	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
 	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
 
-	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
-	       apll, mpll, epll, hpll);
+	printk(KERN_INFO "S5PC100: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
+		", Epll=%ld.%03ld Mhz, Hpll=%ld.%03ld Mhz\n",
+		print_mhz(apll), print_mhz(mpll),
+		print_mhz(epll), print_mhz(hpll));
 
-	armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
+	armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
 	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
 	hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
 	pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
 	hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
 	pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
 
-	printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
-	       armclk, hclkd0, pclkd0, hclk, pclk);
+	printk(KERN_INFO "S5PC100: ARMCLK=%ld.%03ld MHz, HCLKD0=%ld.%03ld MHz,"
+		" PCLKD0=%ld.%03ld MHz\n, HCLK=%ld.%03ld MHz,"
+		" PCLK=%ld.%03ld MHz\n",
+		print_mhz(armclk), print_mhz(hclkd0),
+		print_mhz(pclkd0), print_mhz(hclk), print_mhz(pclk));
 
 	clk_fout_apll.rate = apll;
 	clk_fout_mpll.rate = mpll;
 	clk_fout_epll.rate = epll;
-	clk_fout_apll.rate = apll;
+	clk_fout_hpll.rate = hpll;
 
 	clk_h.rate = hclk;
 	clk_p.rate = pclk;
+	clk_f.rate = armclk;
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s5pc1xx_set_clksrc(init_parents[ptr]);
+		s5pc100_set_clksrc(init_parents[ptr]);
 }
 
 static struct clk *clks[] __initdata = {
 	&clk_ext_xtal_mux,
-	&clk_mout_epll.clk,
-	&clk_fout_epll,
+	&clk_mout_apll.clk,
+	&clk_dout_apll,
+	&clk_dout_d0_bus,
+	&clk_dout_pclkd0,
+	&clk_dout_apll2,
 	&clk_mout_mpll.clk,
+	&clk_mout_am.clk,
+	&clk_dout_d1_bus,
+	&clk_mout_onenand.clk,
+	&clk_dout_pclkd1,
+	&clk_dout_mpll2,
+	&clk_dout_cam,
 	&clk_dout_mpll,
+	&clk_mout_epll.clk,
+	&clk_fout_epll,
+	&clk_iis_cd0,
+	&clk_iis_cd1,
+	&clk_iis_cd2,
+	&clk_pcm_cd0,
+	&clk_pcm_cd1,
+	&clk_spi0.clk,
+	&clk_spi1.clk,
+	&clk_spi2.clk,
 	&clk_uart_uclk1.clk,
-	&clk_ext,
-	&clk_epll,
-	&clk_27m,
-	&clk_48m,
-	&clk_54m,
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+	&clk_spdif.clk,
+	&clk_lcd.clk,
+	&clk_fimc0.clk,
+	&clk_fimc1.clk,
+	&clk_fimc2.clk,
+	&clk_mmc0.clk,
+	&clk_mmc1.clk,
+	&clk_mmc2.clk,
+	&clk_usbhost.clk,
+	&clk_arm,
 };
 
 void __init s5pc100_register_clocks(void)
@@ -1133,7 +1141,4 @@ void __init s5pc100_register_clocks(void
 			       clkp->name, ret);
 		}
 	}
-
-	clk_mpll.parent = &clk_mout_mpll.clk;
-	clk_epll.parent = &clk_mout_epll.clk;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * Base S5PC1XX setup information for 24bpp LCD framebuffer
+ *
+ * This 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/fb.h>
+#include <linux/gpio.h>
+
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+#define DISR_OFFSET	0x7008
+
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+	unsigned int gpio = 0;
+
+	for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-i2c0.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-i2c0.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-i2c0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-i2c0.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <linux/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-i2c1.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-i2c1.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-i2c1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-i2c1.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <linux/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
--- linux-libre-2.6.32-gnu1/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,86 @@
+/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2009 Samsung Eletronics
+ *
+ * S5PC1XX - 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 <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+
+void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+	unsigned int num;
+
+	num = width;
+	/* In case of 8 width, we should decrease the 2 */
+	if (width == 8)
+		num = width - 2;
+
+	end = S5PC100_GPG0(2 + num);
+
+	/* Set all the necessary GPG0/GPG1 pins to special-function 0 */
+	for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	if (width == 8) {
+		for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG2(2 + width);
+
+	/* Set all the necessary GPG2 pins to special-function 2 */
+	for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG3(2 + width);
+
+	/* Set all the necessary GPG3 pins to special-function 2 */
+	for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-samsung/Kconfig linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Kconfig
--- linux-libre-2.6.32-gnu1/arch/arm/plat-samsung/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,17 @@
+# arch/arm/plat-samsung/Kconfig
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_SAMSUNG
+	bool
+	depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX || ARCH_S5PC1XX
+	default y
+	help
+	  Base platform code for all Samsung SoC based systems
+
+if PLAT_SAMSUNG
+
+
+endif
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/plat-samsung/Makefile linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/plat-samsung/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/plat-samsung/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,11 @@
+# arch/arm/plat-s3c64xx/Makefile
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:= dummy.o
+obj-				:=
+
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/tools/gen-mach-types linux-libre-2.6.33-gnu1/arch/arm/tools/gen-mach-types
--- linux-libre-2.6.32-gnu1/arch/arm/tools/gen-mach-types	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/tools/gen-mach-types	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 #!/bin/awk
 #
-# Awk script to generate include/asm-arm/mach-types.h
+# Awk script to generate include/generated/mach-types.h
 #
 BEGIN	{ nr = 0 }
 /^#/	{ next }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/tools/mach-types linux-libre-2.6.33-gnu1/arch/arm/tools/mach-types
--- linux-libre-2.6.32-gnu1/arch/arm/tools/mach-types	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/tools/mach-types	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Wed Nov 25 22:14:58 2009
+# Last update: Sat Feb 20 14:16:15 2010
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -1776,6 +1776,7 @@ cybook3			MACH_CYBOOK3		CYBOOK3			1784
 wdg002			MACH_WDG002		WDG002			1785
 sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
 nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
+dove_db			MACH_DOVE_DB		DOVE_DB			1788
 marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789
 vandihud		MACH_VANDIHUD		VANDIHUD		1790
 magx_e8			MACH_MAGX_E8		MAGX_E8			1791
@@ -2256,7 +2257,7 @@ oratisalog		MACH_ORATISALOG		ORATISALOG
 oratismadi		MACH_ORATISMADI		ORATISMADI		2269
 oratisot16		MACH_ORATISOT16		ORATISOT16		2270
 oratisdesk		MACH_ORATISDESK		ORATISDESK		2271
-v2_ca9			MACH_V2P_CA9		V2P_CA9			2272
+vexpress		MACH_VEXPRESS		VEXPRESS		2272
 sintexo			MACH_SINTEXO		SINTEXO			2273
 cm3389			MACH_CM3389		CM3389			2274
 omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275
@@ -2535,4 +2536,145 @@ davinci_dm6467tevm	MACH_DAVINCI_DM6467TE
 c3ax03			MACH_C3AX03		C3AX03			2549
 mxt_td60		MACH_MXT_TD60		MXT_TD60		2550
 esyx			MACH_ESYX		ESYX			2551
+dove_db2		MACH_DOVE_DB2		DOVE_DB2		2552
 bulldog			MACH_BULLDOG		BULLDOG			2553
+derell_me2000		MACH_DERELL_ME2000	DERELL_ME2000		2554
+bcmring_base		MACH_BCMRING_BASE	BCMRING_BASE		2555
+bcmring_evm		MACH_BCMRING_EVM	BCMRING_EVM		2556
+bcmring_evm_jazz	MACH_BCMRING_EVM_JAZZ	BCMRING_EVM_JAZZ	2557
+bcmring_sp		MACH_BCMRING_SP		BCMRING_SP		2558
+bcmring_sv		MACH_BCMRING_SV		BCMRING_SV		2559
+bcmring_sv_jazz		MACH_BCMRING_SV_JAZZ	BCMRING_SV_JAZZ		2560
+bcmring_tablet		MACH_BCMRING_TABLET	BCMRING_TABLET		2561
+bcmring_vp		MACH_BCMRING_VP		BCMRING_VP		2562
+bcmring_evm_seikor	MACH_BCMRING_EVM_SEIKOR	BCMRING_EVM_SEIKOR	2563
+bcmring_sp_wqvga	MACH_BCMRING_SP_WQVGA	BCMRING_SP_WQVGA	2564
+bcmring_custom		MACH_BCMRING_CUSTOM	BCMRING_CUSTOM		2565
+acer_s200		MACH_ACER_S200		ACER_S200		2566
+bt270			MACH_BT270		BT270			2567
+iseo			MACH_ISEO		ISEO			2568
+cezanne			MACH_CEZANNE		CEZANNE			2569
+lucca			MACH_LUCCA		LUCCA			2570
+supersmart		MACH_SUPERSMART		SUPERSMART		2571
+arm11_board		MACH_CS_MISANO		CS_MISANO		2572
+magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
+emxx			MACH_EMXX		EMXX			2574
+outlaw			MACH_OUTLAW		OUTLAW			2575
+riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
+riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
+riot_x37		MACH_RIOT_X37		RIOT_X37		2578
+mega25mx		MACH_MEGA25MX		MEGA25MX		2579
+benzina2		MACH_BENZINA2		BENZINA2		2580
+ignite			MACH_IGNITE		IGNITE			2581
+foggia			MACH_FOGGIA		FOGGIA			2582
+arezzo			MACH_AREZZO		AREZZO			2583
+leica_skywalker		MACH_LEICA_SKYWALKER	LEICA_SKYWALKER		2584
+jacinto2_jamr		MACH_JACINTO2_JAMR	JACINTO2_JAMR		2585
+gts_nova		MACH_GTS_NOVA		GTS_NOVA		2586
+p3600			MACH_P3600		P3600			2587
+dlt2			MACH_DLT2		DLT2			2588
+df3120			MACH_DF3120		DF3120			2589
+ecucore_9g20		MACH_ECUCORE_9G20	ECUCORE_9G20		2590
+nautel_lpc3240		MACH_NAUTEL_LPC3240	NAUTEL_LPC3240		2591
+glacier			MACH_GLACIER		GLACIER			2592
+phrazer_bulldog		MACH_PHRAZER_BULLDOG	PHRAZER_BULLDOG		2593
+omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594
+pca101			MACH_PCA101		PCA101			2595
+buzzc			MACH_BUZZC		BUZZC			2596
+sasie2			MACH_SASIE2		SASIE2			2597
+davinci_cio		MACH_DAVINCI_CIO	DAVINCI_CIO		2598
+smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
+wzl6410			MACH_WZL6410		WZL6410			2600
+wzl6410m		MACH_WZL6410M		WZL6410M		2601
+wzl6410f		MACH_WZL6410F		WZL6410F		2602
+wzl6410i		MACH_WZL6410I		WZL6410I		2603
+spacecom1		MACH_SPACECOM1		SPACECOM1		2604
+pingu920		MACH_PINGU920		PINGU920		2605
+bravoc			MACH_BRAVOC		BRAVOC			2606
+cybo2440		MACH_CYBO2440		CYBO2440		2607
+vdssw			MACH_VDSSW		VDSSW			2608
+romulus			MACH_ROMULUS		ROMULUS			2609
+omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
+eltd100			MACH_ELTD100		ELTD100			2611
+capc7117		MACH_CAPC7117		CAPC7117		2612
+swan			MACH_SWAN		SWAN			2613
+veu			MACH_VEU		VEU			2614
+rm2			MACH_RM2		RM2			2615
+tt2100			MACH_TT2100		TT2100			2616
+venice			MACH_VENICE		VENICE			2617
+pc7323			MACH_PC7323		PC7323			2618
+masp			MACH_MASP		MASP			2619
+fujitsu_tvstbsoc0	MACH_FUJITSU_TVSTBSOC	FUJITSU_TVSTBSOC	2620
+fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621
+lexikon			MACH_LEXIKON		LEXIKON			2622
+mini2440v2		MACH_MINI2440V2		MINI2440V2		2623
+icontrol		MACH_ICONTROL		ICONTROL		2624
+sheevad			MACH_SHEEVAD		SHEEVAD			2625
+qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626
+qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
+bee			MACH_BEE		BEE			2628
+mx23evk			MACH_MX23EVK		MX23EVK			2629
+ap4evb			MACH_AP4EVB		AP4EVB			2630
+stockholm		MACH_STOCKHOLM		STOCKHOLM		2631
+lpc_h3131		MACH_LPC_H3131		LPC_H3131		2632
+stingray		MACH_STINGRAY		STINGRAY		2633
+kraken			MACH_KRAKEN		KRAKEN			2634
+gw2388			MACH_GW2388		GW2388			2635
+jadecpu			MACH_JADECPU		JADECPU			2636
+carlisle		MACH_CARLISLE		CARLISLE		2637
+lux_sf9			MACH_LUX_SFT9		LUX_SFT9		2638
+nemid_tb		MACH_NEMID_TB		NEMID_TB		2639
+terrier			MACH_TERRIER		TERRIER			2640
+turbot			MACH_TURBOT		TURBOT			2641
+sanddab			MACH_SANDDAB		SANDDAB			2642
+mx35_cicada		MACH_MX35_CICADA	MX35_CICADA		2643
+ghi2703d		MACH_GHI2703D		GHI2703D		2644
+lux_sfx9		MACH_LUX_SFX9		LUX_SFX9		2645
+lux_sf9g		MACH_LUX_SF9G		LUX_SF9G		2646
+lux_edk9		MACH_LUX_EDK9		LUX_EDK9		2647
+hw90240			MACH_HW90240		HW90240			2648
+dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649
+mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650
+scat110			MACH_SCAT110		SCAT110			2651
+acer_a1			MACH_ACER_A1		ACER_A1			2652
+cmcontrol		MACH_CMCONTROL		CMCONTROL		2653
+pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654
+rfp43			MACH_RFP43		RFP43			2655
+sk86r0301		MACH_SK86R0301		SK86R0301		2656
+ctpxa			MACH_CTPXA		CTPXA			2657
+epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658
+guruplug		MACH_GURUPLUG		GURUPLUG		2659
+spear310		MACH_SPEAR310		SPEAR310		2660
+spear320		MACH_SPEAR320		SPEAR320		2661
+robotx			MACH_ROBOTX		ROBOTX			2662
+lsxhl			MACH_LSXHL		LSXHL			2663
+smartlite		MACH_SMARTLITE		SMARTLITE		2664
+cws2			MACH_CWS2		CWS2			2665
+m619			MACH_M619		M619			2666
+smartview		MACH_SMARTVIEW		SMARTVIEW		2667
+lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668
+kizbox			MACH_KIZBOX		KIZBOX			2669
+htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670
+guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671
+pm9g45			MACH_PM9G45		PM9G45			2672
+htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673
+htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674
+reb01			MACH_REB01		REB01			2675
+aquila			MACH_AQUILA		AQUILA			2676
+spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677
+sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
+surf7x30		MACH_SURF7X30		SURF7X30		2679
+micro2440		MACH_MICRO2440		MICRO2440		2680
+am2440			MACH_AM2440		AM2440			2681
+tq2440			MACH_TQ2440		TQ2440			2682
+lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683
+ak880x			MACH_AK880X		AK880X			2684
+cobra3530		MACH_COBRA3530		COBRA3530		2685
+pmppb			MACH_PMPPB		PMPPB			2686
+u6715			MACH_U6715		U6715			2687
+axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688
+g30_dvb			MACH_G30_DVB		G30_DVB			2689
+vc088x			MACH_VC088X		VC088X			2690
+mioa702			MACH_MIOA702		MIOA702			2691
+hpmin			MACH_HPMIN		HPMIN			2692
+ak880xak		MACH_AK880XAK		AK880XAK		2693
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/tools/Makefile linux-libre-2.6.33-gnu1/arch/arm/tools/Makefile
--- linux-libre-2.6.32-gnu1/arch/arm/tools/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/tools/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@
 # Copyright (C) 2001 Russell King
 #
 
-include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
+include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
 	@echo '  Generating $@'
 	@mkdir -p $(dir $@)
 	$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff -druNp linux-libre-2.6.32-gnu1/arch/arm/vfp/vfpmodule.c linux-libre-2.6.33-gnu1/arch/arm/vfp/vfpmodule.c
--- linux-libre-2.6.32-gnu1/arch/arm/vfp/vfpmodule.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/arm/vfp/vfpmodule.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,16 +38,75 @@ union vfp_state *last_VFP_context[NR_CPU
  */
 unsigned int VFP_arch;
 
+/*
+ * Per-thread VFP initialization.
+ */
+static void vfp_thread_flush(struct thread_info *thread)
+{
+	union vfp_state *vfp = &thread->vfpstate;
+	unsigned int cpu;
+
+	memset(vfp, 0, sizeof(union vfp_state));
+
+	vfp->hard.fpexc = FPEXC_EN;
+	vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
+
+	/*
+	 * Disable VFP to ensure we initialize it first.  We must ensure
+	 * that the modification of last_VFP_context[] and hardware disable
+	 * are done for the same CPU and without preemption.
+	 */
+	cpu = get_cpu();
+	if (last_VFP_context[cpu] == vfp)
+		last_VFP_context[cpu] = NULL;
+	fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+	put_cpu();
+}
+
+static void vfp_thread_exit(struct thread_info *thread)
+{
+	/* release case: Per-thread VFP cleanup. */
+	union vfp_state *vfp = &thread->vfpstate;
+	unsigned int cpu = get_cpu();
+
+	if (last_VFP_context[cpu] == vfp)
+		last_VFP_context[cpu] = NULL;
+	put_cpu();
+}
+
+/*
+ * When this function is called with the following 'cmd's, the following
+ * is true while this function is being run:
+ *  THREAD_NOFTIFY_SWTICH:
+ *   - the previously running thread will not be scheduled onto another CPU.
+ *   - the next thread to be run (v) will not be running on another CPU.
+ *   - thread->cpu is the local CPU number
+ *   - not preemptible as we're called in the middle of a thread switch
+ *  THREAD_NOTIFY_FLUSH:
+ *   - the thread (v) will be running on the local CPU, so
+ *	v === current_thread_info()
+ *   - thread->cpu is the local CPU number at the time it is accessed,
+ *	but may change at any time.
+ *   - we could be preempted if tree preempt rcu is enabled, so
+ *	it is unsafe to use thread->cpu.
+ *  THREAD_NOTIFY_EXIT
+ *   - the thread (v) will be running on the local CPU, so
+ *	v === current_thread_info()
+ *   - thread->cpu is the local CPU number at the time it is accessed,
+ *	but may change at any time.
+ *   - we could be preempted if tree preempt rcu is enabled, so
+ *	it is unsafe to use thread->cpu.
+ */
 static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
 {
 	struct thread_info *thread = v;
-	union vfp_state *vfp;
-	__u32 cpu = thread->cpu;
 
 	if (likely(cmd == THREAD_NOTIFY_SWITCH)) {
 		u32 fpexc = fmrx(FPEXC);
 
 #ifdef CONFIG_SMP
+		unsigned int cpu = thread->cpu;
+
 		/*
 		 * On SMP, if VFP is enabled, save the old state in
 		 * case the thread migrates to a different CPU. The
@@ -74,25 +133,10 @@ static int vfp_notifier(struct notifier_
 		return NOTIFY_DONE;
 	}
 
-	vfp = &thread->vfpstate;
-	if (cmd == THREAD_NOTIFY_FLUSH) {
-		/*
-		 * Per-thread VFP initialisation.
-		 */
-		memset(vfp, 0, sizeof(union vfp_state));
-
-		vfp->hard.fpexc = FPEXC_EN;
-		vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
-
-		/*
-		 * Disable VFP to ensure we initialise it first.
-		 */
-		fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
-	}
-
-	/* flush and release case: Per-thread VFP cleanup. */
-	if (last_VFP_context[cpu] == vfp)
-		last_VFP_context[cpu] = NULL;
+	if (cmd == THREAD_NOTIFY_FLUSH)
+		vfp_thread_flush(thread);
+	else
+		vfp_thread_exit(thread);
 
 	return NOTIFY_DONE;
 }
@@ -153,10 +197,13 @@ static void vfp_raise_exceptions(u32 exc
 	}
 
 	/*
-	 * Update the FPSCR with the additional exception flags.
+	 * If any of the status flags are set, update the FPSCR.
 	 * Comparison instructions always return at least one of
 	 * these flags set.
 	 */
+	if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
+		fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
+
 	fpscr |= exceptions;
 
 	fmxr(FPSCR, fpscr);
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/evklcd10x.c linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/evklcd10x.c
--- linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/evklcd10x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/evklcd10x.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,12 @@ static int __init atevklcd10x_init(void)
 
 	at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
 			fbmem_start, fbmem_size,
-			ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL);
+#ifdef CONFIG_BOARD_ATNGW100_MKII
+			ATMEL_LCDC_PRI_18BIT | ATMEL_LCDC_PC_DVAL
+#else
+			ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL
+#endif
+			);
 
 	at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/Kconfig linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/Kconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,17 @@
 # NGW100 customization
 
-if BOARD_ATNGW100
+if BOARD_ATNGW100_COMMON
+
+config BOARD_ATNGW100_MKII_LCD
+	bool "Enable ATNGW100 mkII LCD interface"
+	depends on BOARD_ATNGW100_MKII
+	help
+	  This enables the LCD controller (LCDC) in the AT32AP7000. Since the
+	  LCDC is multiplexed with MACB1 (LAN) Ethernet port, only one can be
+	  enabled at a time.
+
+	  This choice enables the LCDC and disables the MACB1 interface marked
+	  LAN on the PCB.
 
 choice
 	prompt "Select an NGW100 add-on board to support"
@@ -11,15 +22,11 @@ config BOARD_ATNGW100_ADDON_NONE
 
 config BOARD_ATNGW100_EVKLCD10X
 	bool "EVKLCD10X addon board"
+	depends on BOARD_ATNGW100_MKI || BOARD_ATNGW100_MKII_LCD
 	help
 	  This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA)
-	  addon board for the NGW100. By enabling this the LCD controller and
-	  AC97 controller is added as platform devices.
-
-	  This choice disables the detect pin and the write-protect pin for the
-	  MCI platform device, since it conflicts with the LCD platform device.
-	  The MCI pins can be reenabled by editing the "add device function" but
-	  this may break the setup for other displays that use these pins.
+	  addon board for the NGW100 and NGW100 mkII. By enabling this the LCD
+	  controller and AC97 controller is added as platform devices.
 
 config BOARD_ATNGW100_MRMT
 	bool "Mediama RMT1/2 add-on board"
@@ -55,4 +62,4 @@ if BOARD_ATNGW100_MRMT
 source	"arch/avr32/boards/atngw100/Kconfig_mrmt"
 endif
 
-endif	# BOARD_ATNGW100
+endif	# BOARD_ATNGW100_COMMON
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/mrmt.c linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/mrmt.c
--- linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/mrmt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/mrmt.c	2010-02-24 13:52:17.000000000 -0500
@@ -302,6 +302,7 @@ static int __init mrmt1_init(void)
 	at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ),
 			GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
 	set_irq_type( AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING );
+	at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info));
 	spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info));
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/setup.c linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/setup.c
--- linux-libre-2.6.32-gnu1/arch/avr32/boards/atngw100/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/boards/atngw100/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #include <linux/leds.h>
 #include <linux/spi/spi.h>
 #include <linux/atmel-mci.h>
+#include <linux/usb/atmel_usba_udc.h>
 
 #include <asm/io.h>
 #include <asm/setup.h>
@@ -36,6 +37,75 @@ unsigned long at32_board_osc_rates[3] =
 	[2] = 12000000,	/* 12 MHz on osc1 */
 };
 
+/*
+ * The ATNGW100 mkII is very similar to the ATNGW100. Both have the AT32AP7000
+ * chip on board; the difference is that the ATNGW100 mkII has 128 MB 32-bit
+ * SDRAM (the ATNGW100 has 32 MB 16-bit SDRAM) and 256 MB 16-bit NAND flash
+ * (the ATNGW100 has none.)
+ *
+ * The RAM difference is handled by the boot loader, so the only difference we
+ * end up handling here is the NAND flash, EBI pin reservation and if LCDC or
+ * MACB1 should be enabled.
+ */
+#ifdef CONFIG_BOARD_ATNGW100_MKII
+#include <linux/mtd/partitions.h>
+#include <mach/smc.h>
+
+static struct smc_timing nand_timing __initdata = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 10,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 10,
+
+	.ncs_read_pulse		= 30,
+	.nrd_pulse		= 15,
+	.ncs_write_pulse	= 30,
+	.nwe_pulse		= 15,
+
+	.read_cycle		= 30,
+	.write_cycle		= 30,
+
+	.ncs_read_recover	= 0,
+	.nrd_recover		= 15,
+	.ncs_write_recover	= 0,
+	/* WE# high -> RE# low min 60 ns */
+	.nwe_recover		= 50,
+};
+
+static struct smc_config nand_config __initdata = {
+	.bus_width		= 2,
+	.nrd_controlled		= 1,
+	.nwe_controlled		= 1,
+	.nwait_mode		= 0,
+	.byte_write		= 0,
+	.tdf_cycles		= 2,
+	.tdf_mode		= 0,
+};
+
+static struct mtd_partition nand_partitions[] = {
+	{
+		.name		= "main",
+		.offset		= 0x00000000,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition *nand_part_info(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(nand_partitions);
+	return nand_partitions;
+}
+
+static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
+	.cle		= 21,
+	.ale		= 22,
+	.rdy_pin	= GPIO_PIN_PB(28),
+	.enable_pin	= GPIO_PIN_PE(23),
+	.bus_width_16	= true,
+	.partition_info	= nand_part_info,
+};
+#endif
+
 /* Initialized by bootloader-specific startup code. */
 struct tag *bootloader_tags __initdata;
 
@@ -56,9 +126,9 @@ static struct spi_board_info spi0_board_
 static struct mci_platform_data __initdata mci0_data = {
 	.slot[0] = {
 		.bus_width	= 4,
-#if defined(CONFIG_BOARD_ATNGW100_EVKLCD10X) || defined(CONFIG_BOARD_ATNGW100_MRMT1)
-		.detect_pin     = GPIO_PIN_NONE,
-		.wp_pin         = GPIO_PIN_NONE,
+#if defined(CONFIG_BOARD_ATNGW100_MKII)
+		.detect_pin	= GPIO_PIN_PC(25),
+		.wp_pin		= GPIO_PIN_PE(22),
 #else
 		.detect_pin	= GPIO_PIN_PC(25),
 		.wp_pin		= GPIO_PIN_PE(0),
@@ -66,6 +136,14 @@ static struct mci_platform_data __initda
 	},
 };
 
+static struct usba_platform_data atngw100_usba_data __initdata = {
+#if defined(CONFIG_BOARD_ATNGW100_MKII)
+	.vbus_pin	= GPIO_PIN_PE(26),
+#else
+	.vbus_pin	= -ENODEV,
+#endif
+};
+
 /*
  * The next two functions should go away as the boot loader is
  * supposed to initialize the macb address registers with a valid
@@ -173,18 +251,27 @@ static int __init atngw100_init(void)
 	unsigned	i;
 
 	/*
-	 * ATNGW100 uses 16-bit SDRAM interface, so we don't need to
-	 * reserve any pins for it.
+	 * ATNGW100 mkII uses 32-bit SDRAM interface. Reserve the
+	 * SDRAM-specific pins so that nobody messes with them.
 	 */
+#ifdef CONFIG_BOARD_ATNGW100_MKII
+	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL);
+
+	smc_set_timing(&nand_config, &nand_timing);
+	smc_set_configuration(3, &nand_config);
+	at32_add_device_nand(0, &atngw100mkii_nand_data);
+#endif
 
 	at32_add_device_usart(0);
 
 	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+#ifndef CONFIG_BOARD_ATNGW100_MKII_LCD
 	set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
+#endif
 
 	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
 	at32_add_device_mci(0, &mci0_data);
-	at32_add_device_usba(0, NULL);
+	at32_add_device_usba(0, &atngw100_usba_data);
 
 	for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
 		at32_select_gpio(ngw_leds[i].gpio,
@@ -194,10 +281,14 @@ static int __init atngw100_init(void)
 
 	/* all these i2c/smbus pins should have external pullups for
 	 * open-drain sharing among all I2C devices.  SDA and SCL do;
-	 * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus),
-	 * but it's not available off-board.
+	 * PB28/EXTINT3 (ATNGW100) and PE21 (ATNGW100 mkII) doesn't; it should
+	 * be SMBALERT# (for PMBus), but it's not available off-board.
 	 */
+#ifdef CONFIG_BOARD_ATNGW100_MKII
+	at32_select_periph(GPIO_PIOE_BASE, 1 << 21, 0, AT32_GPIOF_PULLUP);
+#else
 	at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP);
+#endif
 	at32_select_gpio(i2c_gpio_data.sda_pin,
 		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
 	at32_select_gpio(i2c_gpio_data.scl_pin,
@@ -211,14 +302,22 @@ postcore_initcall(atngw100_init);
 
 static int __init atngw100_arch_init(void)
 {
-	/* PB30 is the otherwise unused jumper on the mainboard, with an
-	 * external pullup; the jumper grounds it.  Use it however you
-	 * like, including letting U-Boot or Linux tweak boot sequences.
+	/* PB30 (ATNGW100) and PE30 (ATNGW100 mkII) is the otherwise unused
+	 * jumper on the mainboard, with an external pullup; the jumper grounds
+	 * it. Use it however you like, including letting U-Boot or Linux tweak
+	 * boot sequences.
 	 */
+#ifdef CONFIG_BOARD_ATNGW100_MKII
+	at32_select_gpio(GPIO_PIN_PE(30), 0);
+	gpio_request(GPIO_PIN_PE(30), "j15");
+	gpio_direction_input(GPIO_PIN_PE(30));
+	gpio_export(GPIO_PIN_PE(30), false);
+#else
 	at32_select_gpio(GPIO_PIN_PB(30), 0);
 	gpio_request(GPIO_PIN_PB(30), "j15");
 	gpio_direction_input(GPIO_PIN_PB(30));
 	gpio_export(GPIO_PIN_PB(30), false);
+#endif
 
 	/* set_irq_type() after the arch_initcall for EIC has run, and
 	 * before the I2C subsystem could try using this IRQ.
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/boards/hammerhead/Kconfig linux-libre-2.6.33-gnu1/arch/avr32/boards/hammerhead/Kconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/boards/hammerhead/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/boards/hammerhead/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@ config BOARD_HAMMERHEAD_SND
 	bool "Atmel AC97 Sound support"
 	help
 	  This enables Sound support for the Hammerhead board. You may
-	  also go trough the ALSA settings to get it working.
+	  also go through the ALSA settings to get it working.
 
 	  Choose 'Y' here if you have ordered a Corona daugther board and
 	  want to make your board funky.
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Tue Aug  5 16:00:47 2008
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 29 09:39:22 2009
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,22 +35,37 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -59,38 +75,40 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -98,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -118,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type and features
@@ -133,8 +148,23 @@ CONFIG_PERFORMANCE_COUNTERS=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
 # CONFIG_BOARD_ATSTK1000 is not set
-CONFIG_BOARD_ATNGW100=y
+CONFIG_BOARD_ATNGW100_MKI=y
+# CONFIG_BOARD_ATNGW100_MKII is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATSTK1002 is not set
+# CONFIG_BOARD_ATSTK1003 is not set
+# CONFIG_BOARD_ATSTK1004 is not set
+# CONFIG_BOARD_ATSTK1006 is not set
+# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
+# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
+CONFIG_BOARD_ATNGW100_ADDON_NONE=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X is not set
+# CONFIG_BOARD_ATNGW100_MRMT is not set
 CONFIG_LOADER_U_BOOT=y
 
 #
@@ -150,7 +180,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_QUICKLIST=y
-# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
 # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
 # CONFIG_NEED_NODE_MEMMAP_SIZE is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -162,14 +192,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_OWNERSHIP_TRACE is not set
 CONFIG_NMI_DEBUGGING=y
 # CONFIG_HZ_100 is not set
@@ -177,7 +209,7 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
@@ -188,6 +220,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
@@ -219,6 +252,8 @@ CONFIG_CPU_FREQ_AT32AP=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 
@@ -271,7 +306,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -314,10 +348,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -343,16 +379,18 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
 # CONFIG_DECNET is not set
@@ -364,26 +402,33 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -395,6 +440,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -404,6 +450,7 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -453,16 +500,17 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x80000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
 CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -478,9 +526,22 @@ CONFIG_MTD_DATAFLASH=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -498,10 +559,20 @@ CONFIG_MISC_DEVICES=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_TCB_CLKSRC=y
 CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ATMEL_SSC is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=m
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 
 #
 # SCSI device support
@@ -534,26 +605,37 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MACB=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -603,9 +685,11 @@ CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -614,7 +698,9 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
 
 #
@@ -624,6 +710,7 @@ CONFIG_I2C_ALGOBIT=m
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -644,14 +731,6 @@ CONFIG_I2C_GPIO=m
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-CONFIG_EEPROM_AT24=m
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -666,19 +745,28 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
 
 #
+# Memory mapped GPIO expanders:
+#
+
+#
 # I2C GPIO expanders:
 #
 # CONFIG_GPIO_MAX732X is not set
@@ -694,11 +782,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -707,11 +799,11 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -720,22 +812,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -756,32 +843,43 @@ CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_USB_ATMEL_USBA=y
 # CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
@@ -789,12 +887,18 @@ CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
@@ -802,10 +906,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 CONFIG_MMC_TEST=m
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -815,7 +921,11 @@ CONFIG_LEDS_CLASS=y
 # LED drivers
 #
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -823,7 +933,13 @@ CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -855,25 +971,33 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
 # CONFIG_RTC_DRV_M41T94 is not set
 # CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -892,24 +1016,38 @@ CONFIG_DMA_ENGINE=y
 # DMA Clients
 #
 # CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
 # CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=m
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -917,6 +1055,12 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -940,15 +1084,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -967,7 +1109,9 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_UBIFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -975,7 +1119,9 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=y
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1060,14 +1206,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1083,6 +1233,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -1091,13 +1242,39 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1105,19 +1282,30 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1145,11 +1333,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1166,7 +1356,7 @@ CONFIG_CRYPTO_SHA1=y
 #
 # Ciphers
 #
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_ANUBIS is not set
 CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_BLOWFISH is not set
@@ -1186,15 +1376,21 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1204,8 +1400,9 @@ CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_evklcd100_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_evklcd100_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_evklcd100_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_evklcd100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25.6
-# Wed Jun 18 16:06:32 2008
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 29 09:36:39 2009
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,22 +35,37 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -59,43 +75,51 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_KPROBES=y
-# CONFIG_HAVE_KRETPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -109,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type and features
@@ -124,13 +148,26 @@ CONFIG_PERFORMANCE_COUNTERS=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
 # CONFIG_BOARD_ATSTK1000 is not set
-CONFIG_BOARD_ATNGW100=y
+CONFIG_BOARD_ATNGW100_MKI=y
+# CONFIG_BOARD_ATNGW100_MKII is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATSTK1002 is not set
+# CONFIG_BOARD_ATSTK1003 is not set
+# CONFIG_BOARD_ATSTK1004 is not set
+# CONFIG_BOARD_ATSTK1006 is not set
+# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
+# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
+# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set
 CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+# CONFIG_BOARD_ATNGW100_MRMT is not set
 CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y
 # CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA is not set
 # CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
-CONFIG_BOARD_ATNGW100_I2C_GPIO=y
 CONFIG_LOADER_U_BOOT=y
 
 #
@@ -139,14 +176,14 @@ CONFIG_LOADER_U_BOOT=y
 # CONFIG_AP700X_32_BIT_SMC is not set
 CONFIG_AP700X_16_BIT_SMC=y
 # CONFIG_AP700X_8_BIT_SMC is not set
-CONFIG_GPIO_DEV=y
 CONFIG_LOAD_ADDRESS=0x10000000
 CONFIG_ENTRY_ADDRESS=0x90000000
 CONFIG_PHYS_OFFSET=0x10000000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
 # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
 # CONFIG_NEED_NODE_MEMMAP_SIZE is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -158,33 +195,36 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_OWNERSHIP_TRACE is not set
 CONFIG_NMI_DEBUGGING=y
-CONFIG_DW_DMAC=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
 # Power management options
 #
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
@@ -194,6 +234,7 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 # CONFIG_CPU_FREQ_STAT is not set
 # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
 # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
@@ -214,11 +255,9 @@ CONFIG_CPU_FREQ_AT32AP=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -232,6 +271,7 @@ CONFIG_XFRM_USER=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
@@ -269,7 +309,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -285,8 +324,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -310,10 +351,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -339,16 +382,20 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
 # CONFIG_LLC2 is not set
@@ -358,26 +405,33 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -389,6 +443,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -398,10 +453,12 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -446,16 +503,17 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x80000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
 CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -471,6 +529,11 @@ CONFIG_MTD_DATAFLASH=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 CONFIG_MTD_UBI=y
@@ -499,10 +562,20 @@ CONFIG_MISC_DEVICES=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_TCB_CLKSRC=y
 CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ATMEL_SSC is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 
 #
 # SCSI device support
@@ -514,7 +587,6 @@ CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -536,25 +608,37 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MACB=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -598,15 +682,30 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -619,9 +718,11 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -636,9 +737,11 @@ CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -647,45 +750,44 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-CONFIG_I2C_ATMELTWI=m
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -695,30 +797,48 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
-CONFIG_HAVE_GPIO_LIB=y
 
 #
-# GPIO Support
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+
+#
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -731,24 +851,31 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -758,6 +885,7 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -765,8 +893,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
 # CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -779,6 +907,9 @@ CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -792,119 +923,124 @@ CONFIG_FB_ATMEL=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
-
-#
-# Sound
-#
 CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=y
-CONFIG_SND_TIMER=m
+CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=m
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_HRTIMER=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 # CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_AC97_CODEC=m
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# AVR32 devices
-#
-CONFIG_SND_ATMEL_AC97=m
-
-#
-# SPI devices
-#
+# CONFIG_SND_DRIVERS is not set
 
 #
-# System on Chip audio support
+# Atmel devices (AVR32 and AT91)
 #
+# CONFIG_SND_ATMEL_ABDAC is not set
+CONFIG_SND_ATMEL_AC97C=m
+# CONFIG_SND_SPI is not set
 # CONFIG_SND_SOC is not set
-
-#
-# SoC Audio support for SuperH
-#
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=350
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_USB_ATMEL_USBA=y
 # CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
 CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -913,7 +1049,13 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -921,6 +1063,14 @@ CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -950,51 +1100,84 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
 
 #
-# Userspace I/O
+# DMA Devices
 #
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1002,6 +1185,12 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1025,15 +1214,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=y
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1059,8 +1246,10 @@ CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1071,19 +1260,16 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1151,16 +1337,24 @@ CONFIG_NLS_UTF8=m
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1172,19 +1366,48 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1192,63 +1415,118 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
-# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -1257,8 +1535,9 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_evklcd101_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_evklcd101_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100_evklcd101_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100_evklcd101_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25.6
-# Wed Jun 18 16:09:32 2008
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 29 09:37:19 2009
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,22 +35,37 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -59,43 +75,51 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_KPROBES=y
-# CONFIG_HAVE_KRETPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -109,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type and features
@@ -124,13 +148,20 @@ CONFIG_PERFORMANCE_COUNTERS=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
 # CONFIG_BOARD_ATSTK1000 is not set
-CONFIG_BOARD_ATNGW100=y
+CONFIG_BOARD_ATNGW100_MKI=y
+# CONFIG_BOARD_ATNGW100_MKII is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set
 CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+# CONFIG_BOARD_ATNGW100_MRMT is not set
 # CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA is not set
 CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA=y
 # CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
-CONFIG_BOARD_ATNGW100_I2C_GPIO=y
 CONFIG_LOADER_U_BOOT=y
 
 #
@@ -139,14 +170,14 @@ CONFIG_LOADER_U_BOOT=y
 # CONFIG_AP700X_32_BIT_SMC is not set
 CONFIG_AP700X_16_BIT_SMC=y
 # CONFIG_AP700X_8_BIT_SMC is not set
-CONFIG_GPIO_DEV=y
 CONFIG_LOAD_ADDRESS=0x10000000
 CONFIG_ENTRY_ADDRESS=0x90000000
 CONFIG_PHYS_OFFSET=0x10000000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
 # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
 # CONFIG_NEED_NODE_MEMMAP_SIZE is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -158,33 +189,36 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_OWNERSHIP_TRACE is not set
 CONFIG_NMI_DEBUGGING=y
-CONFIG_DW_DMAC=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
 # Power management options
 #
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
@@ -194,6 +228,7 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 # CONFIG_CPU_FREQ_STAT is not set
 # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
 # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
@@ -214,11 +249,9 @@ CONFIG_CPU_FREQ_AT32AP=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -232,6 +265,7 @@ CONFIG_XFRM_USER=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
@@ -269,7 +303,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -285,8 +318,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -310,10 +345,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -339,16 +376,20 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
 # CONFIG_LLC2 is not set
@@ -358,26 +399,33 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -389,6 +437,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -398,10 +447,12 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -446,16 +497,17 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x80000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
 CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -471,6 +523,11 @@ CONFIG_MTD_DATAFLASH=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 CONFIG_MTD_UBI=y
@@ -499,10 +556,20 @@ CONFIG_MISC_DEVICES=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_TCB_CLKSRC=y
 CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ATMEL_SSC is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 
 #
 # SCSI device support
@@ -514,7 +581,6 @@ CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -536,25 +602,37 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MACB=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -598,15 +676,30 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -619,9 +712,11 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -636,9 +731,11 @@ CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -647,45 +744,44 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-CONFIG_I2C_ATMELTWI=m
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -695,30 +791,48 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
-CONFIG_HAVE_GPIO_LIB=y
 
 #
-# GPIO Support
+# PPS support
 #
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
 
 #
+# PCI GPIO expanders:
+#
+
+#
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -731,24 +845,31 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -758,6 +879,7 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -765,8 +887,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
 # CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -779,6 +901,9 @@ CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -792,119 +917,124 @@ CONFIG_FB_ATMEL=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
-
-#
-# Sound
-#
 CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=y
-CONFIG_SND_TIMER=m
+CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=m
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_HRTIMER=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 # CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_AC97_CODEC=m
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# AVR32 devices
-#
-CONFIG_SND_ATMEL_AC97=m
-
-#
-# SPI devices
-#
+# CONFIG_SND_DRIVERS is not set
 
 #
-# System on Chip audio support
+# Atmel devices (AVR32 and AT91)
 #
+# CONFIG_SND_ATMEL_ABDAC is not set
+CONFIG_SND_ATMEL_AC97C=m
+# CONFIG_SND_SPI is not set
 # CONFIG_SND_SOC is not set
-
-#
-# SoC Audio support for SuperH
-#
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=350
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_USB_ATMEL_USBA=y
 # CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
 CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -913,7 +1043,13 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -921,6 +1057,14 @@ CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -950,51 +1094,84 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
 
 #
-# Userspace I/O
+# DMA Devices
 #
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1002,6 +1179,12 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1025,15 +1208,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=y
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1059,8 +1240,10 @@ CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1071,19 +1254,16 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1151,16 +1331,24 @@ CONFIG_NLS_UTF8=m
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1172,19 +1360,48 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1192,63 +1409,118 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
-# CONFIG_CRYPTO_SEQIV is not set
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -1257,8 +1529,9 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1414 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov  5 15:32:26 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100_MKI is not set
+CONFIG_BOARD_ATNGW100_MKII=y
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATNGW100_MKII_LCD is not set
+CONFIG_BOARD_ATNGW100_ADDON_NONE=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X is not set
+# CONFIG_BOARD_ATNGW100_MRMT is not set
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_HW=y
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_UBIFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+CONFIG_UFS_FS=y
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_evklcd100_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_evklcd100_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_evklcd100_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_evklcd100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1549 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov  5 15:33:09 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100_MKI is not set
+CONFIG_BOARD_ATNGW100_MKII=y
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_ATNGW100_MKII_LCD=y
+# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set
+CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+# CONFIG_BOARD_ATNGW100_MRMT is not set
+CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA is not set
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_HW=y
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_HRTIMER=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+
+#
+# Atmel devices (AVR32 and AT91)
+#
+# CONFIG_SND_ATMEL_ABDAC is not set
+CONFIG_SND_ATMEL_AC97C=m
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=350
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_evklcd101_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_evklcd101_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atngw100mkii_evklcd101_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atngw100mkii_evklcd101_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1549 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Thu Nov  5 15:33:32 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATNGW100_COMMON=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100_MKI is not set
+CONFIG_BOARD_ATNGW100_MKII=y
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_ATNGW100_MKII_LCD=y
+# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set
+CONFIG_BOARD_ATNGW100_EVKLCD10X=y
+# CONFIG_BOARD_ATNGW100_MRMT is not set
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA is not set
+CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA=y
+# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+# CONFIG_AP700X_32_BIT_SMC is not set
+CONFIG_AP700X_16_BIT_SMC=y
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_HW=y
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ATMEL_PWM is not set
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_HRTIMER=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+
+#
+# Atmel devices (AVR32 and AT91)
+#
+# CONFIG_SND_ATMEL_ABDAC is not set
+CONFIG_SND_ATMEL_AC97C=m
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=350
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT32AP700X=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atstk1002_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atstk1002_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atstk1002_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atstk1002_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Mon Aug  4 16:02:27 2008
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 29 13:00:55 2009
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,21 +35,36 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -58,38 +74,40 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -97,11 +115,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -117,7 +132,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type and features
@@ -133,7 +148,12 @@ CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
 CONFIG_BOARD_ATSTK1000=y
-# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_ATNGW100_MKI is not set
+# CONFIG_BOARD_ATNGW100_MKII is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
+# CONFIG_BOARD_MIMC200 is not set
 CONFIG_BOARD_ATSTK1002=y
 # CONFIG_BOARD_ATSTK1003 is not set
 # CONFIG_BOARD_ATSTK1004 is not set
@@ -159,7 +179,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_QUICKLIST=y
-# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
 # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
 # CONFIG_NEED_NODE_MEMMAP_SIZE is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -171,14 +191,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_OWNERSHIP_TRACE is not set
 CONFIG_NMI_DEBUGGING=y
 # CONFIG_HZ_100 is not set
@@ -186,7 +208,7 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
@@ -197,6 +219,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
@@ -228,6 +251,8 @@ CONFIG_CPU_FREQ_AT32AP=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 
@@ -295,10 +320,12 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 CONFIG_LLC=m
@@ -309,26 +336,33 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -340,6 +374,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -349,6 +384,7 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -398,17 +434,18 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
 CONFIG_MTD_DATAFLASH=m
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
 CONFIG_MTD_M25P80=m
 CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -424,9 +461,22 @@ CONFIG_M25PXX_USE_FAST_READ=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -444,10 +494,20 @@ CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_TCB_CLKSRC=y
 CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
 CONFIG_ATMEL_SSC=m
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=m
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 
 #
 # SCSI device support
@@ -469,10 +529,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -489,8 +545,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 # CONFIG_SATA_PMP is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
@@ -519,26 +577,37 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MACB=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -580,18 +649,25 @@ CONFIG_INPUT_EVDEV=m
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_GPIO=m
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -622,9 +698,11 @@ CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -633,7 +711,9 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
 
 #
@@ -643,6 +723,7 @@ CONFIG_I2C_ALGOBIT=m
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -663,14 +744,6 @@ CONFIG_I2C_GPIO=m
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-CONFIG_EEPROM_AT24=m
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -685,19 +758,28 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
 
 #
+# Memory mapped GPIO expanders:
+#
+
+#
 # I2C GPIO expanders:
 #
 # CONFIG_GPIO_MAX732X is not set
@@ -713,11 +795,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -726,11 +812,11 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_AT32AP700X_WDT=y
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -739,22 +825,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -764,6 +845,7 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -785,10 +867,15 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
 CONFIG_LCD_LTV350QV=y
 # CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 # CONFIG_BACKLIGHT_CLASS_DEVICE is not set
@@ -799,6 +886,8 @@ CONFIG_LCD_LTV350QV=y
 # CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -807,12 +896,24 @@ CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 # CONFIG_SND_SUPPORT_OLD_API is not set
 # CONFIG_SND_VERBOSE_PROCFS is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 # CONFIG_SND_DRIVERS is not set
+
+#
+# Atmel devices (AVR32 and AT91)
+#
+# CONFIG_SND_ATMEL_ABDAC is not set
+# CONFIG_SND_ATMEL_AC97C is not set
 CONFIG_SND_SPI=y
 CONFIG_SND_AT73C213=m
 CONFIG_SND_AT73C213_TARGET_BITRATE=48000
@@ -825,33 +926,43 @@ CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
 # CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
 CONFIG_USB_ATMEL_USBA=y
 # CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA25X is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
@@ -859,12 +970,18 @@ CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
@@ -872,10 +989,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -887,7 +1006,11 @@ CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_ATMEL_PWM=m
 # CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -895,7 +1018,13 @@ CONFIG_LEDS_GPIO=m
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -927,25 +1056,33 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
 #
 # CONFIG_RTC_DRV_M41T94 is not set
 # CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -964,25 +1101,45 @@ CONFIG_DMA_ENGINE=y
 # DMA Clients
 #
 # CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
 # CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -990,6 +1147,12 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1013,15 +1176,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1039,7 +1200,14 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_OMFS_FS is not set
@@ -1122,6 +1290,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1130,6 +1299,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1145,6 +1317,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -1153,13 +1326,39 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1167,19 +1366,30 @@ CONFIG_FRAME_POINTER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-CONFIG_CRYPTO_ALGAPI=m
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1207,11 +1417,13 @@ CONFIG_CRYPTO_CBC=m
 #
 CONFIG_CRYPTO_HMAC=m
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1228,7 +1440,7 @@ CONFIG_CRYPTO_SHA1=m
 #
 # Ciphers
 #
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_ANUBIS is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
@@ -1247,18 +1459,24 @@ CONFIG_CRYPTO_DES=m
 #
 # Compression
 #
-CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
@@ -1266,8 +1484,11 @@ CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/configs/atstk1006_defconfig linux-libre-2.6.33-gnu1/arch/avr32/configs/atstk1006_defconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/configs/atstk1006_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/configs/atstk1006_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc8
-# Thu Dec 18 11:22:23 2008
+# Linux kernel version: 2.6.32-rc5
+# Thu Oct 29 13:00:25 2009
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -34,21 +35,36 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -58,32 +74,40 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -91,11 +115,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -111,7 +132,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
 CONFIG_FREEZER=y
 
 #
@@ -128,8 +148,11 @@ CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
 CONFIG_BOARD_ATSTK1000=y
-# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_ATNGW100_MKI is not set
+# CONFIG_BOARD_ATNGW100_MKII is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
 # CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MERISC is not set
 # CONFIG_BOARD_MIMC200 is not set
 # CONFIG_BOARD_ATSTK1002 is not set
 # CONFIG_BOARD_ATSTK1003 is not set
@@ -156,7 +179,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_QUICKLIST=y
-# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_HAVE_ARCH_BOOTMEM is not set
 # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
 # CONFIG_NEED_NODE_MEMMAP_SIZE is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -170,12 +193,14 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_OWNERSHIP_TRACE is not set
 CONFIG_NMI_DEBUGGING=y
 # CONFIG_HZ_100 is not set
@@ -194,6 +219,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
@@ -294,6 +320,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_STP=m
@@ -309,20 +336,24 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -334,6 +365,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
@@ -343,6 +375,7 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -393,9 +426,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -406,6 +437,7 @@ CONFIG_MTD_DATAFLASH=m
 CONFIG_MTD_DATAFLASH_OTP=y
 CONFIG_MTD_M25P80=m
 CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -432,6 +464,11 @@ CONFIG_MTD_NAND_ATMEL_ECC_HW=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 CONFIG_MTD_UBI=y
@@ -460,13 +497,22 @@ CONFIG_ATMEL_PWM=m
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_TCB_CLKSRC=y
 CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 CONFIG_ATMEL_SSC=m
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
@@ -486,10 +532,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -506,8 +548,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 # CONFIG_SATA_PMP is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
@@ -536,12 +580,17 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MACB=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -550,15 +599,18 @@ CONFIG_MACB=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
@@ -600,18 +652,25 @@ CONFIG_INPUT_EVDEV=m
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_GPIO=m
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -642,9 +701,11 @@ CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -653,6 +714,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
@@ -664,6 +726,7 @@ CONFIG_I2C_ALGOBIT=m
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -684,14 +747,6 @@ CONFIG_I2C_GPIO=m
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -706,13 +761,18 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -738,11 +798,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -764,26 +828,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -817,8 +872,10 @@ CONFIG_FB_ATMEL=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
 CONFIG_LCD_LTV350QV=y
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
@@ -833,6 +890,7 @@ CONFIG_LCD_LTV350QV=y
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -841,16 +899,28 @@ CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 # CONFIG_SND_SUPPORT_OLD_API is not set
 # CONFIG_SND_VERBOSE_PROCFS is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+
+#
+# Atmel devices (AVR32 and AT91)
+#
+# CONFIG_SND_ATMEL_ABDAC is not set
+# CONFIG_SND_ATMEL_AC97C is not set
 CONFIG_SND_SPI=y
 CONFIG_SND_AT73C213=m
 CONFIG_SND_AT73C213_TARGET_BITRATE=48000
@@ -863,11 +933,10 @@ CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MUSB_HDRC is not set
 # CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
@@ -882,18 +951,25 @@ CONFIG_USB_ATMEL_USBA=y
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
 # CONFIG_USB_GADGET_M66592 is not set
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 # CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
@@ -901,6 +977,12 @@ CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -917,6 +999,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
 CONFIG_MMC_ATMELMCI=y
 # CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
@@ -930,7 +1013,11 @@ CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_ATMEL_PWM=m
 # CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -939,7 +1026,12 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -972,6 +1064,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -983,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1014,32 +1108,42 @@ CONFIG_DMA_ENGINE=y
 # DMA Clients
 #
 # CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
 # CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=m
-CONFIG_EXT4DEV_COMPAT=y
+CONFIG_EXT4_FS=y
 # CONFIG_EXT4_FS_XATTR is not set
-CONFIG_JBD=m
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-CONFIG_JBD2=m
+CONFIG_JBD2=y
 # CONFIG_JBD2_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1047,6 +1151,12 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1076,10 +1186,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1099,12 +1206,13 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_XATTR=y
+# CONFIG_UBIFS_FS_XATTR is not set
 # CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
 CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_OMFS_FS is not set
@@ -1124,7 +1232,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1188,6 +1295,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1196,6 +1304,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1211,6 +1322,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -1219,6 +1331,8 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
@@ -1226,17 +1340,30 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1262,10 +1389,12 @@ CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG=m
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1293,11 +1422,13 @@ CONFIG_CRYPTO_CBC=m
 #
 CONFIG_CRYPTO_HMAC=m
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1334,6 +1465,7 @@ CONFIG_CRYPTO_DES=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=y
 
 #
@@ -1341,11 +1473,13 @@ CONFIG_CRYPTO_LZO=y
 #
 CONFIG_CRYPTO_ANSI_CPRNG=m
 # CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=m
@@ -1357,8 +1491,9 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,7 @@
 #define BUG()								\
 	do {								\
 		_BUG_OR_WARN(0);					\
-		for (;;);						\
+		unreachable();						\
 	} while (0)
 
 #define WARN_ON(condition)							\
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -107,6 +107,7 @@ extern void flush_icache_page(struct vm_
  * do something here, but only for certain configurations.  No such
  * configurations exist at this time.
  */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(page)		do { } while (0)
 #define flush_dcache_mmap_unlock(page)		do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,6 @@ typedef struct user_fpu_struct elf_fpreg
 #endif
 #define ELF_ARCH	EM_AVR32
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/hardirq.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/hardirq.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/hardirq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/hardirq.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,23 +1,6 @@
 #ifndef __ASM_AVR32_HARDIRQ_H
 #define __ASM_AVR32_HARDIRQ_H
-
-#include <linux/threads.h>
-#include <asm/irq.h>
-
 #ifndef __ASSEMBLY__
-
-#include <linux/cache.h>
-
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
-	unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-void ack_bad_irq(unsigned int irq);
-
-/* Standard mappings for irq_cpustat_t above */
-#include <linux/irq_cpustat.h>
-
+#include <asm-generic/hardirq.h>
 #endif /* __ASSEMBLY__ */
-
 #endif /* __ASM_AVR32_HARDIRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* __ASM_AVR32_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/include/asm/syscalls.h linux-libre-2.6.33-gnu1/arch/avr32/include/asm/syscalls.h
--- linux-libre-2.6.32-gnu1/arch/avr32/include/asm/syscalls.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/include/asm/syscalls.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,10 +29,6 @@ asmlinkage int sys_sigaltstack(const sta
 			       struct pt_regs *);
 asmlinkage int sys_rt_sigreturn(struct pt_regs *);
 
-/* kernel/sys_avr32.c */
-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
-			  unsigned long, unsigned long, off_t);
-
 /* mm/cache.c */
 asmlinkage int sys_cacheflush(int, void __user *, size_t);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/Kconfig linux-libre-2.6.33-gnu1/arch/avr32/Kconfig
--- linux-libre-2.6.32-gnu1/arch/avr32/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -92,6 +92,7 @@ config PLATFORM_AT32AP
 	select PERFORMANCE_COUNTERS
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_ALLOCATOR
+	select HAVE_FB_ATMEL
 
 #
 # CPU types
@@ -111,6 +112,11 @@ config CPU_AT32AP7002
 	bool
 	select CPU_AT32AP700X
 
+# AP700X boards
+config BOARD_ATNGW100_COMMON
+	bool
+	select CPU_AT32AP7000
+
 choice
 	prompt "AVR32 board type"
 	default BOARD_ATSTK1000
@@ -118,9 +124,13 @@ choice
 config BOARD_ATSTK1000
 	bool "ATSTK1000 evaluation board"
 
-config BOARD_ATNGW100
+config BOARD_ATNGW100_MKI
 	bool "ATNGW100 Network Gateway"
-	select CPU_AT32AP7000
+	select BOARD_ATNGW100_COMMON
+
+config BOARD_ATNGW100_MKII
+	bool "ATNGW100 mkII Network Gateway"
+	select BOARD_ATNGW100_COMMON
 
 config BOARD_HAMMERHEAD
 	bool "Hammerhead board"
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/kernel/irq.c linux-libre-2.6.33-gnu1/arch/avr32/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/avr32/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,15 +16,6 @@
 #include <linux/seq_file.h>
 #include <linux/sysdev.h>
 
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
-	printk("unexpected IRQ %u\n", irq);
-}
-
 /* May be overridden by platform code */
 int __weak nmi_enable(void)
 {
@@ -51,7 +42,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto unlock;
@@ -66,7 +57,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 	unlock:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/kernel/sys_avr32.c linux-libre-2.6.33-gnu1/arch/avr32/kernel/sys_avr32.c
--- linux-libre-2.6.32-gnu1/arch/avr32/kernel/sys_avr32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/kernel/sys_avr32.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,39 +5,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
 #include <linux/unistd.h>
 
-#include <asm/mman.h>
-#include <asm/uaccess.h>
-#include <asm/syscalls.h>
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, off_t offset)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return error;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-	return error;
-}
-
 int kernel_execve(const char *file, char **argv, char **envp)
 {
 	register long scno asm("r8") = __NR_execve;
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/kernel/syscall-stubs.S linux-libre-2.6.33-gnu1/arch/avr32/kernel/syscall-stubs.S
--- linux-libre-2.6.32-gnu1/arch/avr32/kernel/syscall-stubs.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/kernel/syscall-stubs.S	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ __sys_execve:
 __sys_mmap2:
 	pushm	lr
 	st.w	--sp, ARG6
-	call	sys_mmap2
+	call	sys_mmap_pgoff
 	sub	sp, -4
 	popm	pc
 
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/kernel/syscall_table.S linux-libre-2.6.33-gnu1/arch/avr32/kernel/syscall_table.S
--- linux-libre-2.6.32-gnu1/arch/avr32/kernel/syscall_table.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/kernel/syscall_table.S	2010-02-24 13:52:17.000000000 -0500
@@ -295,4 +295,5 @@ sys_call_table:
 	.long	sys_signalfd
 	.long	sys_ni_syscall		/* 280, was sys_timerfd */
 	.long	sys_eventfd
+	.long	sys_recvmmsg
 	.long	sys_ni_syscall		/* r8 is saturated at nr_syscalls */
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/avr32/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/avr32/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -39,30 +39,10 @@ SECTIONS
 		__tagtable_begin = .;
 			*(.taglist.init)
 		__tagtable_end = .;
-			INIT_DATA
-		. = ALIGN(16);
-		__setup_start = .;
-			*(.init.setup)
-		__setup_end = .;
-		. = ALIGN(4);
-		__initcall_start = .;
-			INITCALLS
-		__initcall_end = .;
-		__con_initcall_start = .;
-			*(.con_initcall.init)
-		__con_initcall_end = .;
-		__security_initcall_start = .;
-			*(.security_initcall.init)
-		__security_initcall_end = .;
-#ifdef CONFIG_BLK_DEV_INITRD
-		. = ALIGN(32);
-		__initramfs_start = .;
-			*(.init.ramfs)
-		__initramfs_end = .;
-#endif
-		. = ALIGN(PAGE_SIZE);
-		__init_end = .;
 	}
+	INIT_DATA_SECTION(16)
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
 
 	.text		: AT(ADDR(.text) - LOAD_OFFSET) {
 		_evba = .;
@@ -78,34 +58,16 @@ SECTIONS
 		_etext = .;
 	} = 0xd703d703
 
-	. = ALIGN(4);
-	__ex_table	: AT(ADDR(__ex_table) - LOAD_OFFSET) {
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-	}
-
+	EXCEPTION_TABLE(4)
 	RODATA
 
-	. = ALIGN(THREAD_SIZE);
-
 	.data		: AT(ADDR(.data) - LOAD_OFFSET) {
 		_data = .;
 		_sdata = .;
-		/*
-		 * First, the init task union, aligned to an 8K boundary.
-		 */
-		*(.data.init_task)
-
-		/* Then, the page-aligned data */
-		. = ALIGN(PAGE_SIZE);
-		*(.data.page_aligned)
-
-		/* Then, the cacheline aligned data */
-		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.cacheline_aligned)
 
-		/* And the rest... */
+		INIT_TASK_DATA(THREAD_SIZE)
+		PAGE_ALIGNED_DATA(PAGE_SIZE);
+		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 		*(.data.rel*)
 		DATA_DATA
 		CONSTRUCTORS
@@ -113,16 +75,8 @@ SECTIONS
 		_edata = .;
 	}
 
-
-	. = ALIGN(8);
-	.bss    	: AT(ADDR(.bss) - LOAD_OFFSET) {
-		__bss_start = .;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(8);
-		__bss_stop = .;
-		_end = .;
-	}
+	BSS_SECTION(0, 8, 8)
+	_end = .;
 
 	DWARF_DEBUG
 
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/at32ap700x.c linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,8 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/atmel_usba_udc.h>
+
+#include <mach/atmel-mci.h>
 #include <linux/atmel-mci.h>
 
 #include <asm/io.h>
@@ -1181,19 +1183,32 @@ static struct resource atmel_spi1_resour
 DEFINE_DEV(atmel_spi, 1);
 DEV_CLK(spi_clk, atmel_spi1, pba, 1);
 
-static void __init
-at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
-		      unsigned int n, const u8 *pins)
+void __init
+at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n)
 {
+	/*
+	 * Manage the chipselects as GPIOs, normally using the same pins
+	 * the SPI controller expects; but boards can use other pins.
+	 */
+	static u8 __initdata spi_pins[][4] = {
+		{ GPIO_PIN_PA(3), GPIO_PIN_PA(4),
+		  GPIO_PIN_PA(5), GPIO_PIN_PA(20) },
+		{ GPIO_PIN_PB(2), GPIO_PIN_PB(3),
+		  GPIO_PIN_PB(4), GPIO_PIN_PA(27) },
+	};
 	unsigned int pin, mode;
 
+	/* There are only 2 SPI controllers */
+	if (bus_num > 1)
+		return;
+
 	for (; n; n--, b++) {
 		b->bus_num = bus_num;
 		if (b->chip_select >= 4)
 			continue;
 		pin = (unsigned)b->controller_data;
 		if (!pin) {
-			pin = pins[b->chip_select];
+			pin = spi_pins[bus_num][b->chip_select];
 			b->controller_data = (void *)pin;
 		}
 		mode = AT32_GPIOF_OUTPUT;
@@ -1206,16 +1221,6 @@ at32_spi_setup_slaves(unsigned int bus_n
 struct platform_device *__init
 at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
 {
-	/*
-	 * Manage the chipselects as GPIOs, normally using the same pins
-	 * the SPI controller expects; but boards can use other pins.
-	 */
-	static u8 __initdata spi0_pins[] =
-		{ GPIO_PIN_PA(3), GPIO_PIN_PA(4),
-		  GPIO_PIN_PA(5), GPIO_PIN_PA(20), };
-	static u8 __initdata spi1_pins[] =
-		{ GPIO_PIN_PB(2), GPIO_PIN_PB(3),
-		  GPIO_PIN_PB(4), GPIO_PIN_PA(27), };
 	struct platform_device *pdev;
 	u32 pin_mask;
 
@@ -1228,7 +1233,7 @@ at32_add_device_spi(unsigned int id, str
 		select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP);
 		select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
 
-		at32_spi_setup_slaves(0, b, n, spi0_pins);
+		at32_spi_setup_slaves(0, b, n);
 		break;
 
 	case 1:
@@ -1239,7 +1244,7 @@ at32_add_device_spi(unsigned int id, str
 		select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP);
 		select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 
-		at32_spi_setup_slaves(1, b, n, spi1_pins);
+		at32_spi_setup_slaves(1, b, n);
 		break;
 
 	default:
@@ -1320,7 +1325,7 @@ struct platform_device *__init
 at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
 {
 	struct platform_device		*pdev;
-	struct dw_dma_slave		*dws = &data->dma_slave;
+	struct mci_dma_data	        *slave;
 	u32				pioa_mask;
 	u32				piob_mask;
 
@@ -1339,16 +1344,22 @@ at32_add_device_mci(unsigned int id, str
 				ARRAY_SIZE(atmel_mci0_resource)))
 		goto fail;
 
-	dws->dma_dev = &dw_dmac0_device.dev;
-	dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
-	dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
+	slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
+	if (!slave)
+		goto fail;
+
+	slave->sdata.dma_dev = &dw_dmac0_device.dev;
+	slave->sdata.reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+	slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0)
 				| DWC_CFGH_DST_PER(1));
-	dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
+	slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL
 				| DWC_CFGL_HS_SRC_POL);
 
+	data->dma_slave = slave;
+
 	if (platform_device_add_data(pdev, data,
 				sizeof(struct mci_platform_data)))
-		goto fail;
+		goto fail_free;
 
 	/* CLK line is common to both slots */
 	pioa_mask = 1 << 10;
@@ -1372,7 +1383,7 @@ at32_add_device_mci(unsigned int id, str
 		/* Slot is unused */
 		break;
 	default:
-		goto fail;
+		goto fail_free;
 	}
 
 	select_peripheral(PIOA, pioa_mask, PERIPH_A, 0);
@@ -1399,7 +1410,7 @@ at32_add_device_mci(unsigned int id, str
 		break;
 	default:
 		if (!data->slot[0].bus_width)
-			goto fail;
+			goto fail_free;
 
 		data->slot[1].bus_width = 0;
 		break;
@@ -1410,7 +1421,10 @@ at32_add_device_mci(unsigned int id, str
 	platform_device_add(pdev);
 	return pdev;
 
+fail_free:
+	kfree(slave);
 fail:
+	data->dma_slave = NULL;
 	platform_device_put(pdev);
 	return NULL;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/include/mach/atmel-mci.h linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/include/mach/atmel-mci.h
--- linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/include/mach/atmel-mci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/include/mach/atmel-mci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+#ifndef __MACH_ATMEL_MCI_H
+#define __MACH_ATMEL_MCI_H
+
+#include <linux/dw_dmac.h>
+
+/**
+ * struct mci_dma_data - DMA data for MCI interface
+ */
+struct mci_dma_data {
+	struct dw_dma_slave	sdata;
+};
+
+/* accessor macros */
+#define	slave_data_ptr(s)	(&(s)->sdata)
+#define find_slave_dev(s)	((s)->sdata.dma_dev)
+
+#define	setup_dma_addr(s, t, r)	do {		\
+	if (s) {				\
+		(s)->sdata.tx_reg = (t);	\
+		(s)->sdata.rx_reg = (r);	\
+	}					\
+} while (0)
+
+#endif /* __MACH_ATMEL_MCI_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/include/mach/board.h linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/include/mach/board.h
--- linux-libre-2.6.32-gnu1/arch/avr32/mach-at32ap/include/mach/board.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/mach-at32ap/include/mach/board.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,7 @@ at32_add_device_eth(unsigned int id, str
 struct spi_board_info;
 struct platform_device *
 at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n);
+void at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n);
 
 struct atmel_lcdfb_info;
 struct platform_device *
diff -druNp linux-libre-2.6.32-gnu1/arch/avr32/Makefile linux-libre-2.6.33-gnu1/arch/avr32/Makefile
--- linux-libre-2.6.32-gnu1/arch/avr32/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/avr32/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@ head-$(CONFIG_LOADER_U_BOOT)		+= arch/av
 head-y					+= arch/avr32/kernel/head.o
 core-y					+= $(machdirs)
 core-$(CONFIG_BOARD_ATSTK1000)		+= arch/avr32/boards/atstk1000/
-core-$(CONFIG_BOARD_ATNGW100)		+= arch/avr32/boards/atngw100/
+core-$(CONFIG_BOARD_ATNGW100_COMMON)	+= arch/avr32/boards/atngw100/
 core-$(CONFIG_BOARD_HAMMERHEAD)		+= arch/avr32/boards/hammerhead/
 core-$(CONFIG_BOARD_FAVR_32)		+= arch/avr32/boards/favr-32/
 core-$(CONFIG_BOARD_MERISC)		+= arch/avr32/boards/merisc/
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/boot/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/boot/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/boot/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
 
 MKIMAGE := $(srctree)/scripts/mkuboot.sh
 
-targets := vmImage vmImage.bz2 vmImage.gz vmImage.lzma
+targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
 extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
 
 quiet_cmd_uimage = UIMAGE  $@
@@ -29,6 +29,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.b
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)
 
+$(obj)/vmImage.bin: $(obj)/vmlinux.bin
+	$(call if_changed,uimage,none)
+
 $(obj)/vmImage.bz2: $(obj)/vmlinux.bin.bz2
 	$(call if_changed,uimage,bzip2)
 
@@ -38,6 +41,7 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma
 	$(call if_changed,uimage,lzma)
 
+suffix-y                      := bin
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -316,6 +317,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -438,17 +440,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
-CONFIG_NET_DSA=y
-# CONFIG_NET_DSA_TAG_DSA is not set
-# CONFIG_NET_DSA_TAG_EDSA is not set
-# CONFIG_NET_DSA_TAG_TRAILER is not set
-CONFIG_NET_DSA_TAG_STPID=y
-# CONFIG_NET_DSA_MV88E6XXX is not set
-# CONFIG_NET_DSA_MV88E6060 is not set
-# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
-# CONFIG_NET_DSA_MV88E6131 is not set
-# CONFIG_NET_DSA_MV88E6123_61_65 is not set
-CONFIG_NET_DSA_KSZ8893M=y
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -321,6 +322,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -321,6 +322,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -283,6 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -283,6 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -290,6 +291,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -704,10 +706,7 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -301,6 +302,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,22 +1,29 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.31.5
+# Mon Nov  2 22:02:56 2009
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +33,40 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,17 +87,28 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -80,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -94,13 +127,12 @@ CONFIG_BLOCK=y
 CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_CFQ is not set
 CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -137,7 +169,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
 # CONFIG_BF547M is not set
-CONFIG_BF548=y
+CONFIG_BF548_std=y
 # CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
 # CONFIG_BF549M is not set
@@ -195,7 +227,7 @@ CONFIG_BFIN548_EZKIT=y
 #
 # BF548 Specific Configuration
 #
-# CONFIG_DEB_DMA_URGENT is not set
+CONFIG_DEB_DMA_URGENT=y
 # CONFIG_BF548_ATAPI_ALTERNATIVE_PORT is not set
 
 #
@@ -352,10 +384,11 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 CONFIG_DMA_UNCACHED_2M=y
@@ -366,14 +399,13 @@ CONFIG_DMA_UNCACHED_2M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+# CONFIG_BFIN_L2_ICACHEABLE is not set
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_ICACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK is not set
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
 # CONFIG_BFIN_L2_DCACHEABLE is not set
 
 #
@@ -382,7 +414,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -441,11 +473,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -469,13 +496,11 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -493,7 +518,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -548,14 +576,10 @@ CONFIG_SIR_BFIN_DMA=y
 # CONFIG_MCS_FIR is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS is not set
 CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_LIB80211=m
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -578,6 +602,7 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -653,7 +678,6 @@ CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
 # CONFIG_MTD_NAND_ECC_SMC is not set
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_BFIN is not set
 CONFIG_MTD_NAND_IDS=y
 CONFIG_MTD_NAND_BF5XX=y
 CONFIG_MTD_NAND_BF5XX_HWECC=y
@@ -665,6 +689,11 @@ CONFIG_MTD_NAND_BF5XX_HWECC=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -682,10 +711,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -709,10 +748,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -729,6 +764,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -744,13 +780,34 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_SMC91X is not set
-CONFIG_SMSC911X=y
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -759,6 +816,8 @@ CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -771,13 +830,16 @@ CONFIG_LIBERTAS=m
 # CONFIG_LIBERTAS_USB is not set
 CONFIG_LIBERTAS_SDIO=m
 CONFIG_POWEROF2_BLOCKSIZE_ONLY=y
+# CONFIG_LIBERTAS_SPI is not set
 # CONFIG_LIBERTAS_DEBUG is not set
 # CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_HOSTAP is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -813,28 +875,31 @@ CONFIG_INPUT_EVBUG=m
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_BFIN=y
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_GPIO is not set
-CONFIG_KEYBOARD_BFIN=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
 CONFIG_TOUCHSCREEN_AD7877=m
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
 # CONFIG_TOUCHSCREEN_MTOUCH is not set
 # CONFIG_TOUCHSCREEN_INEXIO is not set
 # CONFIG_TOUCHSCREEN_MK712 is not set
@@ -844,6 +909,8 @@ CONFIG_TOUCHSCREEN_AD7877=m
 # CONFIG_TOUCHSCREEN_WM97XX is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -852,7 +919,11 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -863,16 +934,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -890,6 +958,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -903,6 +972,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
@@ -951,14 +1021,9 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -975,13 +1040,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -997,6 +1067,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1038,28 +1109,19 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1096,6 +1158,7 @@ CONFIG_FB_BF54X_LQ043=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1132,6 +1195,7 @@ CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
@@ -1142,6 +1206,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -1152,7 +1221,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-# CONFIG_SND_BLACKFIN_AD1836 is not set
 # CONFIG_SND_BFIN_AD73322 is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
@@ -1160,15 +1228,17 @@ CONFIG_SND_USB=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_AC97_BUS=y
 # CONFIG_SND_BF5XX_I2S is not set
+# CONFIG_SND_BF5XX_TDM is not set
 CONFIG_SND_BF5XX_AC97=y
 CONFIG_SND_BF5XX_MMAP_SUPPORT=y
 # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+CONFIG_SND_BF5XX_HAVE_COLD_RESET=y
+CONFIG_SND_BF5XX_RESET_GPIO_NUM=19
+CONFIG_SND_BF5XX_SOC_AD1980=y
 CONFIG_SND_BF5XX_SOC_SPORT=y
 CONFIG_SND_BF5XX_SOC_AC97=y
-CONFIG_SND_BF5XX_SOC_AD1980=y
 CONFIG_SND_BF5XX_SPORT_NUM=0
-CONFIG_SND_BF5XX_HAVE_COLD_RESET=y
-CONFIG_SND_BF5XX_RESET_GPIO_NUM=19
+CONFIG_SND_SOC_I2C_AND_SPI=y
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=y
 # CONFIG_SOUND_PRIME is not set
@@ -1188,30 +1258,34 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=y
+# CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -1237,6 +1311,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_ISP1362_HCD is not set
@@ -1267,18 +1342,17 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1314,7 +1388,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1326,6 +1399,13 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -1380,6 +1460,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1411,10 +1492,21 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1427,9 +1519,11 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1439,6 +1533,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=m
@@ -1467,10 +1566,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1489,17 +1585,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1508,6 +1595,7 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
@@ -1522,7 +1610,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1596,11 +1683,15 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1608,16 +1699,21 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
@@ -1625,17 +1721,16 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1657,17 +1752,15 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
-CONFIG_SECURITY=y
+# CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_NETWORK is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
 CONFIG_CRYPTO=y
 
 #
@@ -1746,6 +1839,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1753,11 +1847,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1767,6 +1863,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-ACVILON_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1643 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31.4
+# Sat Oct 24 12:15:32 2009
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+# CONFIG_BF527 is not set
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
+CONFIG_BF561=y
+# CONFIG_SMP is not set
+CONFIG_BF_REV_MIN=3
+CONFIG_BF_REV_MAX=5
+# CONFIG_BF_REV_0_0 is not set
+# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+CONFIG_BF_REV_0_5=y
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_TIMER0=10
+CONFIG_IRQ_TIMER1=10
+CONFIG_IRQ_TIMER2=10
+CONFIG_IRQ_TIMER3=10
+CONFIG_IRQ_TIMER4=10
+CONFIG_IRQ_TIMER5=10
+CONFIG_IRQ_TIMER6=10
+CONFIG_IRQ_TIMER7=10
+CONFIG_IRQ_SPI_ERROR=7
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_BFIN561_TEPLA is not set
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+CONFIG_BFIN561_ACVILON=y
+
+#
+# BF561 Specific Configuration
+#
+
+#
+# Core B Support
+#
+# CONFIG_BF561_COREB is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_DMA1_ERROR=7
+CONFIG_IRQ_DMA2_ERROR=7
+CONFIG_IRQ_IMDMA_ERROR=7
+CONFIG_IRQ_PPI0_ERROR=7
+CONFIG_IRQ_PPI1_ERROR=7
+CONFIG_IRQ_UART_ERROR=7
+CONFIG_IRQ_RESERVED_ERROR=7
+CONFIG_IRQ_DMA1_0=8
+CONFIG_IRQ_DMA1_1=8
+CONFIG_IRQ_DMA1_2=8
+CONFIG_IRQ_DMA1_3=8
+CONFIG_IRQ_DMA1_4=8
+CONFIG_IRQ_DMA1_5=8
+CONFIG_IRQ_DMA1_6=8
+CONFIG_IRQ_DMA1_7=8
+CONFIG_IRQ_DMA1_8=8
+CONFIG_IRQ_DMA1_9=8
+CONFIG_IRQ_DMA1_10=8
+CONFIG_IRQ_DMA1_11=8
+CONFIG_IRQ_DMA2_0=9
+CONFIG_IRQ_DMA2_1=9
+CONFIG_IRQ_DMA2_2=9
+CONFIG_IRQ_DMA2_3=9
+CONFIG_IRQ_DMA2_4=9
+CONFIG_IRQ_DMA2_5=9
+CONFIG_IRQ_DMA2_6=9
+CONFIG_IRQ_DMA2_7=9
+CONFIG_IRQ_DMA2_8=9
+CONFIG_IRQ_DMA2_9=9
+CONFIG_IRQ_DMA2_10=9
+CONFIG_IRQ_DMA2_11=9
+CONFIG_IRQ_TIMER8=10
+CONFIG_IRQ_TIMER9=10
+CONFIG_IRQ_TIMER10=10
+CONFIG_IRQ_TIMER11=10
+CONFIG_IRQ_PROG0_INTA=11
+CONFIG_IRQ_PROG0_INTB=11
+CONFIG_IRQ_PROG1_INTA=11
+CONFIG_IRQ_PROG1_INTB=11
+CONFIG_IRQ_PROG2_INTA=11
+CONFIG_IRQ_PROG2_INTB=11
+CONFIG_IRQ_DMA1_WRRD0=8
+CONFIG_IRQ_DMA1_WRRD1=8
+CONFIG_IRQ_DMA2_WRRD0=9
+CONFIG_IRQ_DMA2_WRRD1=9
+CONFIG_IRQ_IMDMA_WRRD0=12
+CONFIG_IRQ_IMDMA_WRRD1=12
+CONFIG_IRQ_WDTIMER=13
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=12000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+CONFIG_CYCLES_CLOCKSOURCE=y
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+CONFIG_SCHEDULE_L1=y
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+CONFIG_MEMSET_L1=y
+CONFIG_MEMCPY_L1=y
+CONFIG_SYS_BFIN_SPINLOCK_L1=y
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=y
+CONFIG_DMA_UNCACHED_4M=y
+# CONFIG_DMA_UNCACHED_2M is not set
+# CONFIG_DMA_UNCACHED_1M is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+# CONFIG_BFIN_L2_ICACHEABLE is not set
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+# CONFIG_BFIN_L2_DCACHEABLE is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+CONFIG_C_B0PEN=y
+CONFIG_C_B1PEN=y
+CONFIG_C_B2PEN=y
+# CONFIG_C_B3PEN is not set
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x99b2
+CONFIG_BANK_1=0x3350
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0xAAC2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_UCLINUX is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_PHRAM=y
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=y
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_BFIN_DMA_INTERFACE is not set
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+CONFIG_BFIN_SIMPLE_TIMER=y
+# CONFIG_BFIN_SPI_ADC is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TWI_LCD is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_BFIN_JTAG_COMM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+# CONFIG_CAN4LINUX is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOPCA=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=y
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+CONFIG_GPIO_PCF857X=y
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+CONFIG_SENSORS_LM75=y
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_SPI=y
+
+#
+# ALSA Blackfin devices
+#
+# CONFIG_SND_BFIN_AD73322 is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_BF5XX_I2S=y
+# CONFIG_SND_BF5XX_SOC_SSM2602 is not set
+# CONFIG_SND_BF5XX_SOC_AD73311 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM is not set
+# CONFIG_SND_BF5XX_AC97 is not set
+CONFIG_SND_BF5XX_SOC_SPORT=y
+CONFIG_SND_BF5XX_SPORT_NUM=1
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=y
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=866
+CONFIG_FAT_DEFAULT_IOCHARSET="cp1251"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+# CONFIG_JFFS2_ZLIB is not set
+CONFIG_JFFS2_LZO=y
+# CONFIG_JFFS2_RTIME is not set
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+# CONFIG_JFFS2_CMODE_PRIORITY is not set
+# CONFIG_JFFS2_CMODE_SIZE is not set
+CONFIG_JFFS2_CMODE_FAVOURLZO=y
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp1251"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+CONFIG_NLS_CODEPAGE_866=y
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+CONFIG_NLS_CODEPAGE_1251=y
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_KOI8_R=y
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+# CONFIG_DEBUG_HWERR is not set
+# CONFIG_DEBUG_DOUBLEFAULT is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,22 +1,29 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.31.5
+# Mon Nov  2 21:59:31 2009
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +33,40 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,17 +87,28 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -80,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -94,13 +127,12 @@ CONFIG_BLOCK=y
 CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_CFQ is not set
 CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -170,6 +202,7 @@ CONFIG_IRQ_SPI_ERROR=7
 CONFIG_BFIN561_EZKIT=y
 # CONFIG_BFIN561_TEPLA is not set
 # CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_ACVILON is not set
 
 #
 # BF561 Specific Configuration
@@ -317,10 +350,11 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -331,14 +365,13 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+# CONFIG_BFIN_L2_ICACHEABLE is not set
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_ICACHEABLE is not set
 # CONFIG_BFIN_L2_DCACHEABLE is not set
 
 #
@@ -347,7 +380,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -407,11 +440,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -435,13 +463,11 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -459,7 +485,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -503,13 +532,8 @@ CONFIG_IRTTY_SIR=m
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -530,6 +554,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
@@ -603,6 +628,11 @@ CONFIG_MTD_PHYSMAP=m
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -619,9 +649,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -645,9 +680,11 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -656,6 +693,8 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -664,7 +703,10 @@ CONFIG_SMC91X=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -708,15 +750,12 @@ CONFIG_INPUT_EVDEV=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -730,6 +769,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -740,6 +780,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
@@ -763,13 +804,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -782,9 +828,6 @@ CONFIG_GPIO_SYSFS=y
 #
 # I2C GPIO expanders:
 #
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
 
 #
 # PCI GPIO expanders:
@@ -822,23 +865,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -862,7 +891,6 @@ CONFIG_HID=m
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -870,10 +898,20 @@ CONFIG_HID_COMPAT=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
@@ -882,9 +920,11 @@ CONFIG_HID_COMPAT=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -894,6 +934,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -915,10 +960,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -937,17 +979,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -956,6 +989,7 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
@@ -966,7 +1000,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1034,11 +1067,15 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1046,16 +1083,21 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
@@ -1063,17 +1105,19 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1095,16 +1139,15 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
-CONFIG_SECURITY=y
+# CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_NETWORK is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
 CONFIG_CRYPTO=y
 
 #
@@ -1183,6 +1226,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1190,11 +1234,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1204,6 +1250,8 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/BlackStamp_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/BlackStamp_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/BlackStamp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/BlackStamp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -66,6 +66,7 @@ CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -275,6 +276,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF527_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF527_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF527_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF527_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
@@ -15,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -25,55 +29,72 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -265,7 +282,10 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
 # CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -315,10 +335,12 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -329,10 +351,9 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -343,7 +364,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -361,7 +382,7 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
 CONFIG_BANK_3=0xFFC0
 
@@ -386,7 +407,6 @@ CONFIG_BINFMT_ZFLAT=y
 #
 # CONFIG_PM is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
 
 #
 # CPU Frequency scaling
@@ -400,11 +420,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -428,7 +443,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -452,7 +466,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -463,13 +479,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -484,22 +495,21 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
 #
-CONFIG_MTD_CHAR=m
+CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -512,9 +522,9 @@ CONFIG_MTD_BLOCK=y
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
@@ -526,9 +536,11 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
@@ -538,7 +550,7 @@ CONFIG_MTD_ROM=m
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_GPIO_ADDR is not set
+CONFIG_MTD_GPIO_ADDR=y
 # CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -562,6 +574,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -586,12 +603,46 @@ CONFIG_HAVE_IDE=y
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -613,6 +664,9 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -623,9 +677,11 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -633,6 +689,7 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -641,7 +698,10 @@ CONFIG_BFIN_MAC_RMII=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -674,17 +734,13 @@ CONFIG_BFIN_MAC_RMII=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PPIFCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-# CONFIG_BF5xx_EPPI is not set
+# CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
-# CONFIG_TWI_LCD is not set
-CONFIG_BFIN_DMA_INTERFACE=m
-CONFIG_SIMPLE_GPIO=m
+# CONFIG_BFIN_TWI_LCD is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_BFIN_JTAG_COMM is not set
@@ -698,6 +754,7 @@ CONFIG_SIMPLE_GPIO=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -710,6 +767,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
@@ -758,13 +816,9 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -772,7 +826,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
 
 #
@@ -780,17 +833,17 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
 
 #
@@ -803,6 +856,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -829,11 +883,13 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -849,11 +905,16 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -885,6 +946,12 @@ CONFIG_BFIN_WDT=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -892,10 +959,14 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -931,20 +1002,20 @@ CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-CONFIG_USB=y
+CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
 # Miscellaneous USB options
 #
-# CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_DEVICE_CLASS=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
-CONFIG_USB_MON=y
+CONFIG_USB_MON=m
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 
@@ -952,24 +1023,24 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
-CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC=m
 CONFIG_USB_MUSB_SOC=y
 
 #
 # Blackfin high speed USB Support
 #
-CONFIG_USB_MUSB_HOST=y
-# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
 # CONFIG_USB_MUSB_OTG is not set
-CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
 CONFIG_MUSB_PIO_ONLY=y
-CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
@@ -981,18 +1052,31 @@ CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
 
 #
 # USB port drivers
@@ -1013,7 +1097,6 @@ CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1021,9 +1104,50 @@ CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2272 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1090,6 +1214,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1102,9 +1227,10 @@ CONFIG_RTC_DRV_BFIN=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1114,6 +1240,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1122,8 +1253,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -1135,10 +1269,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1146,9 +1277,19 @@ CONFIG_SYSFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1157,6 +1298,7 @@ CONFIG_SYSFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
@@ -1167,7 +1309,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1182,9 +1323,9 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
 # CONFIG_NLS_CODEPAGE_850 is not set
@@ -1208,7 +1349,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -1235,55 +1376,34 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB_TESTCASE is not set
 CONFIG_DEBUG_VERBOSE=y
-CONFIG_DEBUG_MMRS=y
-# CONFIG_DEBUG_HWERR is not set
+# CONFIG_DEBUG_MMRS is not set
 # CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
@@ -1293,9 +1413,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CPLB_INFO is not set
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1304,9 +1425,9 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
@@ -1385,6 +1506,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1392,20 +1514,24 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF533_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF533_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF533_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF533_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,94 +1,110 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22.16
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
-CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-# CONFIG_NP2 is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODULE_FORCE_LOAD is not set
+# CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -96,7 +112,7 @@ CONFIG_BLOCK=y
 CONFIG_IOSCHED_NOOP=y
 # CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_IOSCHED_CFQ=y
+# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
@@ -105,6 +121,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
 
 #
 # Blackfin Processor Options
@@ -113,6 +130,10 @@ CONFIG_PREEMPT_NONE=y
 #
 # Processor and Board Settings
 #
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
 # CONFIG_BF522 is not set
 # CONFIG_BF523 is not set
 # CONFIG_BF524 is not set
@@ -125,28 +146,38 @@ CONFIG_BF533=y
 # CONFIG_BF534 is not set
 # CONFIG_BF536 is not set
 # CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
 # CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=3
+CONFIG_BF_REV_MAX=6
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
 # CONFIG_BF_REV_0_2 is not set
 CONFIG_BF_REV_0_3=y
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
 CONFIG_BF53x=y
-CONFIG_BFIN_SINGLE_CORE=y
 CONFIG_MEM_MT48LC16M16A2TG_75=y
 # CONFIG_BFIN533_EZKIT is not set
 # CONFIG_BFIN533_STAMP is not set
+# CONFIG_BLACKSTAMP is not set
 CONFIG_BFIN533_BLUETECHNIX_CM=y
 # CONFIG_H8606_HVSISTEMAS is not set
-# CONFIG_GENERIC_BF533_BOARD is not set
+# CONFIG_BFIN532_IP0X is not set
 
 #
 # BF533/2/1 Specific Configuration
@@ -188,6 +219,7 @@ CONFIG_WDTIMER=13
 # Board customizations
 #
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
 
 #
 # Clock/PLL Setup
@@ -207,13 +239,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
-# Memory Setup
+# Misc
 #
-CONFIG_MAX_MEM_SIZE=32
-CONFIG_MEM_ADD_WIDTH=9
-CONFIG_BOOT_LOAD=0x1000
 CONFIG_BFIN_SCRATCH_REG_RETN=y
 # CONFIG_BFIN_SCRATCH_REG_RETE is not set
 # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
@@ -240,6 +279,12 @@ CONFIG_IP_CHECKSUM_L1=y
 CONFIG_CACHELINE_ALIGNED_L1=y
 CONFIG_SYSCALL_TAB_L1=y
 CONFIG_CPLB_SWITCH_TAB_L1=y
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -248,12 +293,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
-CONFIG_LARGE_ALLOCS=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
+# CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
 # CONFIG_DMA_UNCACHED_NONE is not set
@@ -262,10 +311,9 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -276,7 +324,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -301,12 +349,8 @@ CONFIG_BANK_3=0xFFC2
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-# CONFIG_PCI is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCCARD is not set
 
 #
 # Executable file formats
@@ -315,22 +359,19 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
 #
 # CONFIG_CPU_FREQ is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -339,45 +380,13 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-# 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_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETLABEL is not set
+# CONFIG_INET is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -385,31 +394,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -418,20 +419,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -444,12 +447,15 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -460,6 +466,11 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -468,12 +479,16 @@ CONFIG_MTD_RAM=y
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -489,36 +504,25 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_ONENAND is not set
 
 #
-# UBI - Unsorted block images
+# LPDDR flash memory drivers
 #
-# CONFIG_MTD_UBI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -526,34 +530,19 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
-# CONFIG_DM9000 is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
 # CONFIG_NETDEV_1000 is not set
-# CONFIG_AX88180 is not set
 # CONFIG_NETDEV_10000 is not set
 
 #
@@ -561,22 +550,17 @@ CONFIG_SMC91X=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -593,16 +577,15 @@ CONFIG_SMC91X=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
-# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BFIN_DMA_INTERFACE is not set
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_BFIN_SPI_ADC is not set
+# CONFIG_BFIN_SPORT is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
+# CONFIG_BFIN_JTAG_COMM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -613,6 +596,7 @@ CONFIG_BFIN_SPORT=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -623,176 +607,141 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
 # CAN, the car bus and industrial fieldbus
 #
 # CONFIG_CAN4LINUX is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
 
 #
-# SPI support
+# SPI Master Controller Drivers
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
-# Dallas's 1-wire bus
+# SPI Protocol Masters
 #
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Graphics support
+# Multimedia drivers
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DAB is not set
 
 #
-# Display device support
+# Graphics support
 #
-# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
-
-#
-# Enable Host or Gadget support to see Inventra options
-#
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
+# MMC/SD/SDIO Card Drivers
 #
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# LED devices
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# PBX support
-#
-# CONFIG_PBX is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_FS_MBCACHE=y
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -801,8 +750,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
+CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -813,12 +765,8 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -826,60 +774,106 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_DEBUG_VERBOSE=y
 CONFIG_DEBUG_MMRS=y
+# CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
@@ -888,34 +882,39 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
 # CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=m
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF537E_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF537E_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF537E_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF537E_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,13 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Wed Jun  3 06:27:41 2009
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
@@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -26,21 +29,40 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -49,7 +71,8 @@ CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
@@ -65,12 +88,13 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -78,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -98,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -181,7 +201,8 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_STAMP is not set
-CONFIG_BFIN537_BLUETECHNIX_CM=y
+CONFIG_BFIN537_BLUETECHNIX_CM_E=y
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 # CONFIG_PNAV10 is not set
 # CONFIG_CAMSIG_MINOTAUR is not set
@@ -283,10 +304,12 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -297,10 +320,9 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -311,7 +333,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -337,6 +359,7 @@ CONFIG_BANK_3=0xFFC2
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
 
 #
 # Executable file formats
@@ -366,11 +389,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -394,7 +412,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -418,7 +435,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -429,8 +448,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -441,16 +460,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
@@ -486,22 +510,26 @@ CONFIG_MTD_CFI_I2=y
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
 CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_GPIO_ADDR=y
-CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -517,6 +545,11 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -533,9 +566,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -549,6 +587,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -570,6 +609,9 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -580,8 +622,11 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -598,7 +643,10 @@ CONFIG_BFIN_RX_DESC_NUM=20
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -622,15 +670,12 @@ CONFIG_BFIN_RX_DESC_NUM=20
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
-# CONFIG_SIMPLE_GPIO is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_BFIN_JTAG_COMM is not set
@@ -644,6 +689,7 @@ CONFIG_BFIN_SPORT=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -656,6 +702,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
@@ -668,7 +715,23 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-# CONFIG_SPI is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
@@ -688,15 +751,21 @@ CONFIG_GPIO_SYSFS=y
 #
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
@@ -758,21 +827,74 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# Enable Host or Gadget support to see Inventra options
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+CONFIG_USB_GADGET_NET2272=y
+CONFIG_USB_NET2272=m
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
 #
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# MMC/SD/SDIO Card Drivers
 #
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -789,9 +911,10 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -801,6 +924,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -809,8 +937,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -822,10 +953,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -833,9 +961,19 @@ CONFIG_SYSFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_YAFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -844,14 +982,70 @@ CONFIG_SYSFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
@@ -867,14 +1061,28 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEBUG_VERBOSE=y
@@ -888,9 +1096,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -899,8 +1108,9 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 CONFIG_CRYPTO=y
 
 #
@@ -979,6 +1189,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -986,19 +1197,24 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF537U_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF537U_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF537U_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF537U_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,94 +1,111 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22.16
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
-CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-# CONFIG_NP2 is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -105,6 +122,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
 
 #
 # Blackfin Processor Options
@@ -113,6 +131,10 @@ CONFIG_PREEMPT_NONE=y
 #
 # Processor and Board Settings
 #
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
 # CONFIG_BF522 is not set
 # CONFIG_BF523 is not set
 # CONFIG_BF524 is not set
@@ -125,22 +147,31 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_BF534 is not set
 # CONFIG_BF536 is not set
 CONFIG_BF537=y
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
 # CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=2
+CONFIG_BF_REV_MAX=3
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
 CONFIG_BF_REV_0_2=y
 # CONFIG_BF_REV_0_3 is not set
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
 CONFIG_BF53x=y
-CONFIG_BFIN_SINGLE_CORE=y
 CONFIG_MEM_MT48LC16M16A2TG_75=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_RTC=8
@@ -150,7 +181,6 @@ CONFIG_IRQ_SPORT0_TX=9
 CONFIG_IRQ_SPORT1_RX=9
 CONFIG_IRQ_SPORT1_TX=9
 CONFIG_IRQ_TWI=10
-CONFIG_IRQ_SPI=10
 CONFIG_IRQ_UART0_RX=10
 CONFIG_IRQ_UART0_TX=10
 CONFIG_IRQ_UART1_RX=10
@@ -169,11 +199,13 @@ CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_STAMP is not set
-CONFIG_BFIN537_BLUETECHNIX_CM=y
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+CONFIG_BFIN537_BLUETECHNIX_CM_U=y
+# CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 # CONFIG_PNAV10 is not set
 # CONFIG_CAMSIG_MINOTAUR is not set
-# CONFIG_GENERIC_BF537_BOARD is not set
 
 #
 # BF537 Specific Configuration
@@ -196,6 +228,7 @@ CONFIG_IRQ_PROG_INTA=12
 # Board customizations
 #
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
 
 #
 # Clock/PLL Setup
@@ -215,13 +248,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
-# Memory Setup
+# Misc
 #
-CONFIG_MAX_MEM_SIZE=32
-CONFIG_MEM_ADD_WIDTH=9
-CONFIG_BOOT_LOAD=0x1000
 CONFIG_BFIN_SCRATCH_REG_RETN=y
 # CONFIG_BFIN_SCRATCH_REG_RETE is not set
 # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
@@ -248,6 +288,12 @@ CONFIG_IP_CHECKSUM_L1=y
 CONFIG_CACHELINE_ALIGNED_L1=y
 CONFIG_SYSCALL_TAB_L1=y
 CONFIG_CPLB_SWITCH_TAB_L1=y
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -256,12 +302,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
-CONFIG_LARGE_ALLOCS=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
+# CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
 # CONFIG_DMA_UNCACHED_NONE is not set
@@ -270,10 +320,9 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -284,7 +333,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -309,12 +358,8 @@ CONFIG_BANK_3=0xFFC2
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-# CONFIG_PCI is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCCARD is not set
 
 #
 # Executable file formats
@@ -323,22 +368,19 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
 #
 # CONFIG_CPU_FREQ is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -347,10 +389,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -369,15 +407,13 @@ CONFIG_IP_FIB_HASH=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=y
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -386,6 +422,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -395,29 +432,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -426,20 +457,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -452,12 +485,15 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -468,20 +504,29 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
 
 #
 # Mapping drivers for chip access
 #
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_GPIO_ADDR=y
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -497,36 +542,36 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_ONENAND is not set
 
 #
-# UBI - Unsorted block images
+# LPDDR flash memory drivers
 #
-# CONFIG_MTD_UBI is not set
+# CONFIG_MTD_LPDDR is not set
 
 #
-# Parallel port support
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
 
 #
-# Misc devices
+# EEPROM support
 #
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -534,35 +579,20 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 # CONFIG_MD is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_SMC91X=y
-# CONFIG_BFIN_MAC is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_DM9000 is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
 # CONFIG_NETDEV_1000 is not set
-# CONFIG_AX88180 is not set
 # CONFIG_NETDEV_10000 is not set
 
 #
@@ -570,22 +600,17 @@ CONFIG_SMC91X=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -602,16 +627,15 @@ CONFIG_SMC91X=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
-# CONFIG_BF5xx_PPIFCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
+# CONFIG_BFIN_JTAG_COMM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -622,6 +646,7 @@ CONFIG_BFIN_SPORT=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -634,165 +659,201 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
 # CAN, the car bus and industrial fieldbus
 #
 # CONFIG_CAN4LINUX is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
 
 #
-# TPM devices
+# SPI Master Controller Drivers
 #
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 
 #
-# SPI support
+# Memory mapped GPIO expanders:
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 
 #
-# Dallas's 1-wire bus
+# I2C GPIO expanders:
+#
+
 #
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Graphics support
+# Multimedia drivers
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DAB is not set
 
 #
-# Display device support
+# Graphics support
 #
-# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
-# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 # CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
 CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
 # CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
 CONFIG_USB_GADGET_NET2272=y
 CONFIG_USB_NET2272=y
 # CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
 # CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_AT91 is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
-# CONFIG_USB_ETH is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
 
 #
-# InfiniBand support
+# OTG and related infrastructure
 #
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# MMC/SD/SDIO Card Drivers
 #
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# Real Time Clock
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# PBX support
-#
-# CONFIG_PBX is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -802,25 +863,29 @@ CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -829,8 +894,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -841,12 +909,8 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -854,18 +918,29 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -873,41 +948,94 @@ CONFIG_RAMFS=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_DEBUG_VERBOSE=y
 CONFIG_DEBUG_MMRS=y
+# CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
@@ -916,34 +1044,40 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
 # CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF548_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF548_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF548_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF548_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24.4
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
-CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -26,79 +29,100 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-# CONFIG_NP2 is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
 
 #
 # Blackfin Processor Options
@@ -107,6 +131,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
 #
 # Processor and Board Settings
 #
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
 # CONFIG_BF522 is not set
 # CONFIG_BF523 is not set
 # CONFIG_BF524 is not set
@@ -119,19 +147,29 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF534 is not set
 # CONFIG_BF536 is not set
 # CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
-CONFIG_BF548=y
+# CONFIG_BF547M is not set
+CONFIG_BF548_std=y
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
-CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_2 is not set
 # CONFIG_BF_REV_0_3 is not set
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
-# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_0_6 is not set
+CONFIG_BF_REV_ANY=y
 # CONFIG_BF_REV_NONE is not set
 CONFIG_BF54x=y
 CONFIG_IRQ_PLL_WAKEUP=7
@@ -140,15 +178,12 @@ CONFIG_IRQ_SPORT0_RX=9
 CONFIG_IRQ_SPORT0_TX=9
 CONFIG_IRQ_SPORT1_RX=9
 CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_SPI0=10
 CONFIG_IRQ_UART0_RX=10
 CONFIG_IRQ_UART0_TX=10
 CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_CNT=8
-CONFIG_IRQ_USB_INT0=11
-CONFIG_IRQ_USB_INT1=11
-CONFIG_IRQ_USB_INT2=11
-CONFIG_IRQ_USB_DMA=11
 CONFIG_IRQ_TIMER0=11
 CONFIG_IRQ_TIMER1=11
 CONFIG_IRQ_TIMER2=11
@@ -157,9 +192,21 @@ CONFIG_IRQ_TIMER4=11
 CONFIG_IRQ_TIMER5=11
 CONFIG_IRQ_TIMER6=11
 CONFIG_IRQ_TIMER7=11
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
 CONFIG_IRQ_TIMER8=11
 CONFIG_IRQ_TIMER9=11
 CONFIG_IRQ_TIMER10=11
+CONFIG_IRQ_SPORT2_RX=9
+CONFIG_IRQ_SPORT2_TX=9
+CONFIG_IRQ_SPORT3_RX=9
+CONFIG_IRQ_SPORT3_TX=9
+CONFIG_IRQ_SPI1=10
+CONFIG_IRQ_SPI2=10
+CONFIG_IRQ_TWI0=11
+CONFIG_IRQ_TWI1=11
 # CONFIG_BFIN548_EZKIT is not set
 CONFIG_BFIN548_BLUETECHNIX_CM=y
 
@@ -167,6 +214,7 @@ CONFIG_BFIN548_BLUETECHNIX_CM=y
 # BF548 Specific Configuration
 #
 # CONFIG_DEB_DMA_URGENT is not set
+# CONFIG_BF548_ATAPI_ALTERNATIVE_PORT is not set
 
 #
 # Interrupt Priority Assignment
@@ -182,7 +230,6 @@ CONFIG_IRQ_SPORT1_ERR=7
 CONFIG_IRQ_SPI0_ERR=7
 CONFIG_IRQ_UART0_ERR=7
 CONFIG_IRQ_EPPI0=8
-CONFIG_IRQ_SPI0=10
 CONFIG_IRQ_PINT0=12
 CONFIG_IRQ_PINT1=12
 CONFIG_IRQ_MDMAS0=13
@@ -197,18 +244,10 @@ CONFIG_IRQ_SPI2_ERR=7
 CONFIG_IRQ_UART1_ERR=7
 CONFIG_IRQ_UART2_ERR=7
 CONFIG_IRQ_CAN0_ERR=7
-CONFIG_IRQ_SPORT2_RX=9
-CONFIG_IRQ_SPORT2_TX=9
-CONFIG_IRQ_SPORT3_RX=9
-CONFIG_IRQ_SPORT3_TX=9
 CONFIG_IRQ_EPPI1=9
 CONFIG_IRQ_EPPI2=9
-CONFIG_IRQ_SPI1=10
-CONFIG_IRQ_SPI2=10
 CONFIG_IRQ_ATAPI_RX=10
 CONFIG_IRQ_ATAPI_TX=10
-CONFIG_IRQ_TWI0=11
-CONFIG_IRQ_TWI1=11
 CONFIG_IRQ_CAN0_RX=11
 CONFIG_IRQ_CAN0_TX=11
 CONFIG_IRQ_MDMAS2=13
@@ -255,6 +294,7 @@ CONFIG_PINT3_ASSIGN=0x02020303
 # Board customizations
 #
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
 
 #
 # Clock/PLL Setup
@@ -274,16 +314,12 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 # CONFIG_GENERIC_TIME is not set
-# CONFIG_TICK_ONESHOT is not set
 
 #
-# Memory Setup
+# Misc
 #
-CONFIG_MAX_MEM_SIZE=64
-# CONFIG_MEM_MT46V32M16_6T is not set
-CONFIG_MEM_MT46V32M16_5B=y
-CONFIG_BOOT_LOAD=0x1000
 CONFIG_BFIN_SCRATCH_REG_RETN=y
 # CONFIG_BFIN_SCRATCH_REG_RETE is not set
 # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
@@ -310,6 +346,12 @@ CONFIG_ACCESS_OK_L1=y
 CONFIG_CACHELINE_ALIGNED_L1=y
 # CONFIG_SYSCALL_TAB_L1 is not set
 # CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -318,13 +360,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
+# CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
 # CONFIG_DMA_UNCACHED_NONE is not set
@@ -333,14 +378,13 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+# CONFIG_BFIN_L2_ICACHEABLE is not set
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_ICACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
 # CONFIG_BFIN_L2_DCACHEABLE is not set
 
 #
@@ -349,7 +393,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -369,7 +413,7 @@ CONFIG_C_AMBEN_ALL=y
 CONFIG_BANK_0=0x7BB0
 CONFIG_BANK_1=0x5554
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0x99B2
+CONFIG_BANK_3=0x99B3
 CONFIG_EBIU_MBSCTLVAL=0x0
 CONFIG_EBIU_MODEVAL=0x1
 CONFIG_EBIU_FCTLVAL=0x6
@@ -377,7 +421,6 @@ CONFIG_EBIU_FCTLVAL=0x6
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-# CONFIG_PCI is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCCARD is not set
 
@@ -388,23 +431,19 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 # CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
 #
 # CONFIG_CPU_FREQ is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -417,6 +456,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -435,19 +475,16 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-# 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_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -456,6 +493,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -465,24 +503,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -501,10 +536,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -539,6 +576,7 @@ CONFIG_MTD_CFI_I2=y
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
 CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
@@ -549,9 +587,8 @@ CONFIG_MTD_RAM=y
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -575,6 +612,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -587,31 +629,31 @@ CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
+CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_PROC_FS is not set
+CONFIG_SCSI_PROC_FS=y
 
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SD=m
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
 
@@ -632,29 +674,54 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_SMC91X is not set
-CONFIG_SMSC911X=y
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -666,6 +733,10 @@ CONFIG_SMSC911X=y
 # CONFIG_WLAN_80211 is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -676,7 +747,6 @@ CONFIG_SMSC911X=y
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -711,6 +781,7 @@ CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_GPIO is not set
 # CONFIG_KEYBOARD_BFIN is not set
 # CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -726,19 +797,16 @@ CONFIG_INPUT_KEYBOARD=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PPIFCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_OTP=y
-# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
+# CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
-# CONFIG_TWI_LCD is not set
-# CONFIG_SIMPLE_GPIO is not set
+# CONFIG_BFIN_TWI_LCD is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
+# CONFIG_BFIN_JTAG_COMM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -749,10 +817,11 @@ CONFIG_BFIN_OTP=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
-CONFIG_SERIAL_BFIN_DMA=y
-# CONFIG_SERIAL_BFIN_PIO is not set
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
 # CONFIG_SERIAL_BFIN_UART0 is not set
 CONFIG_SERIAL_BFIN_UART1=y
 # CONFIG_BFIN_UART1_CTSRTS is not set
@@ -762,7 +831,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
 
 #
 # CAN, the car bus and industrial fieldbus
@@ -770,61 +842,53 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
 CONFIG_I2C_BLACKFIN_TWI=y
-CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_TINY_USB is not set
 
 #
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8575 is not set
-# CONFIG_SENSORS_PCA9543 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# SPI support
-#
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -832,64 +896,23 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -903,25 +926,43 @@ CONFIG_BFIN_WDT=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
-# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -935,80 +976,75 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
+# CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-CONFIG_USB=y
+CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
 #
-# CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_DEVICE_CLASS=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
-CONFIG_USB_MUSB_HDRC=y
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=m
 CONFIG_USB_MUSB_SOC=y
 
 #
-# Blackfin BF54x, BF525 and BF527 high speed USB support
+# Blackfin high speed USB Support
 #
-CONFIG_USB_MUSB_HOST=y
-# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
 # CONFIG_USB_MUSB_OTG is not set
-CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
 # CONFIG_MUSB_PIO_ONLY is not set
-# CONFIG_USB_INVENTRA_DMA is not set
+CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TI_CPPI_DMA is not set
-CONFIG_USB_MUSB_LOGLEVEL=0
+# CONFIG_USB_MUSB_DEBUG is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1016,6 +1052,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1023,15 +1060,10 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 # CONFIG_USB_SERIAL is not set
 
 #
@@ -1040,7 +1072,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -1048,7 +1080,6 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1056,38 +1087,75 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2272 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
 
 #
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
+# OTG and related infrastructure
 #
-# CONFIG_USB_GADGET is not set
-CONFIG_MMC=y
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=m
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
-CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK=m
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
-CONFIG_SDH_BFIN=y
+# CONFIG_MMC_SDHCI is not set
+CONFIG_SDH_BFIN=m
+# CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set
+# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
 # CONFIG_MMC_SPI is not set
-# CONFIG_SPI_MMC is not set
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
 
 #
 # RTC interfaces
@@ -1111,66 +1179,74 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
 #
-# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
-CONFIG_RTC_DRV_BFIN=y
-
-#
-# Userspace I/O
-#
+CONFIG_RTC_DRV_BFIN=m
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
-
-#
-# PBX support
-#
-# CONFIG_PBX is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
+# CONFIG_ISO9660_FS is not set
 # CONFIG_UDF_FS is not set
 
 #
@@ -1194,10 +1270,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1205,17 +1278,7 @@ CONFIG_SYSFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
-CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_FS_WBUF_VERIFY is not set
@@ -1227,34 +1290,30 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp437"
-CONFIG_CIFS=y
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
@@ -1267,24 +1326,8 @@ CONFIG_CIFS=y
 #
 # Partition Types
 #
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
+# CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
@@ -1326,9 +1369,6 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1336,14 +1376,39 @@ CONFIG_INSTRUMENTATION=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
-CONFIG_DEBUG_MMRS=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_DEBUG_VERBOSE=y
+# CONFIG_DEBUG_MMRS is not set
+# CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
@@ -1352,33 +1417,125 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
-# CONFIG_CRYPTO is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF561_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF561_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/CM-BF561_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/CM-BF561_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,15 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24.4
-# Tue Apr  1 10:50:11 2008
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
-CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -17,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -27,62 +29,83 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_EVENTFD=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-# CONFIG_NP2 is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -99,6 +122,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
 
 #
 # Blackfin Processor Options
@@ -107,6 +131,10 @@ CONFIG_PREEMPT_NONE=y
 #
 # Processor and Board Settings
 #
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
 # CONFIG_BF522 is not set
 # CONFIG_BF523 is not set
 # CONFIG_BF524 is not set
@@ -119,30 +147,47 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_BF534 is not set
 # CONFIG_BF536 is not set
 # CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
 # CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 CONFIG_BF561=y
+# CONFIG_SMP is not set
+CONFIG_BF_REV_MIN=3
+CONFIG_BF_REV_MAX=5
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
 # CONFIG_BF_REV_0_2 is not set
 CONFIG_BF_REV_0_3=y
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BFIN_DUAL_CORE=y
 CONFIG_MEM_MT48LC8M32B2B5_7=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_SPORT0_ERROR=7
 CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_TIMER0=10
+CONFIG_IRQ_TIMER1=10
+CONFIG_IRQ_TIMER2=10
+CONFIG_IRQ_TIMER3=10
+CONFIG_IRQ_TIMER4=10
+CONFIG_IRQ_TIMER5=10
+CONFIG_IRQ_TIMER6=10
+CONFIG_IRQ_TIMER7=10
 CONFIG_IRQ_SPI_ERROR=7
 # CONFIG_BFIN561_EZKIT is not set
 # CONFIG_BFIN561_TEPLA is not set
 CONFIG_BFIN561_BLUETECHNIX_CM=y
-# CONFIG_GENERIC_BF561_BOARD is not set
 
 #
 # BF561 Specific Configuration
@@ -151,12 +196,7 @@ CONFIG_BFIN561_BLUETECHNIX_CM=y
 #
 # Core B Support
 #
-
-#
-# Core B Support
-#
 CONFIG_BF561_COREB=y
-# CONFIG_BF561_COREB_RESET is not set
 
 #
 # Interrupt Priority Assignment
@@ -196,14 +236,6 @@ CONFIG_IRQ_DMA2_8=9
 CONFIG_IRQ_DMA2_9=9
 CONFIG_IRQ_DMA2_10=9
 CONFIG_IRQ_DMA2_11=9
-CONFIG_IRQ_TIMER0=10
-CONFIG_IRQ_TIMER1=10
-CONFIG_IRQ_TIMER2=10
-CONFIG_IRQ_TIMER3=10
-CONFIG_IRQ_TIMER4=10
-CONFIG_IRQ_TIMER5=10
-CONFIG_IRQ_TIMER6=10
-CONFIG_IRQ_TIMER7=10
 CONFIG_IRQ_TIMER8=10
 CONFIG_IRQ_TIMER9=10
 CONFIG_IRQ_TIMER10=10
@@ -226,6 +258,7 @@ CONFIG_IRQ_WDTIMER=13
 # Board customizations
 #
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
 
 #
 # Clock/PLL Setup
@@ -245,19 +278,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
 # CONFIG_CYCLES_CLOCKSOURCE is not set
-# CONFIG_TICK_ONESHOT is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 
 #
-# Memory Setup
+# Misc
 #
-CONFIG_MAX_MEM_SIZE=32
-CONFIG_BOOT_LOAD=0x1000
 CONFIG_BFIN_SCRATCH_REG_RETN=y
 # CONFIG_BFIN_SCRATCH_REG_RETE is not set
 # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
@@ -284,6 +318,12 @@ CONFIG_IP_CHECKSUM_L1=y
 CONFIG_CACHELINE_ALIGNED_L1=y
 CONFIG_SYSCALL_TAB_L1=y
 CONFIG_CPLB_SWITCH_TAB_L1=y
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -292,14 +332,16 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_LARGE_ALLOCS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
+# CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
 # CONFIG_DMA_UNCACHED_NONE is not set
@@ -308,15 +350,16 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+# CONFIG_BFIN_L2_ICACHEABLE is not set
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_ICACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK is not set
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
 # CONFIG_BFIN_L2_DCACHEABLE is not set
+# CONFIG_BFIN_L2_WRITEBACK is not set
+# CONFIG_BFIN_L2_WRITETHROUGH is not set
 
 #
 # Memory Protection Unit
@@ -324,7 +367,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -353,8 +396,8 @@ CONFIG_BANK_3=0xFFC2
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-# CONFIG_PCI is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
 
 #
 # Executable file formats
@@ -363,18 +406,19 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
-# Networking
+# CPU Frequency scaling
 #
+# CONFIG_CPU_FREQ is not set
 CONFIG_NET=y
 
 #
@@ -383,10 +427,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -407,14 +447,11 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -423,6 +460,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -432,24 +470,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -460,16 +495,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -487,8 +528,10 @@ CONFIG_MTD_BLOCK=y
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -499,20 +542,29 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -528,6 +580,11 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -539,14 +596,21 @@ CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
-# CONFIG_BFIN_IDE_ADDRESS_MAPPING_MODE0 is not set
-# CONFIG_BFIN_IDE_ADDRESS_MAPPING_MODE1 is not set
 
 #
 # SCSI device support
@@ -558,26 +622,50 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
+# CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+CONFIG_SMSC911X=m
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
-# CONFIG_AX88180 is not set
 # CONFIG_NETDEV_10000 is not set
 
 #
@@ -585,10 +673,13 @@ CONFIG_SMC91X=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -609,16 +700,15 @@ CONFIG_SMC91X=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PPIFCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
-# CONFIG_SIMPLE_GPIO is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
+# CONFIG_BFIN_JTAG_COMM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -629,6 +719,7 @@ CONFIG_SMC91X=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -639,6 +730,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
@@ -647,54 +739,100 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
 
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 
 #
-# SPI support
+# Memory mapped GPIO expanders:
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -709,42 +847,85 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# Enable Host or Gadget support to see Inventra options
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+CONFIG_USB_GADGET_NET2272=y
+CONFIG_USB_NET2272=m
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_CDC_COMPOSITE is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# OTG and related infrastructure
 #
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# USB Gadget Support
+# MMC/SD/SDIO Card Drivers
 #
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
 
 #
-# Userspace I/O
+# MMC/SD/SDIO Host Controller Drivers
 #
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
-
-#
-# PBX support
-#
-# CONFIG_PBX is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -754,25 +935,29 @@ CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -781,8 +966,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -794,10 +982,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -805,14 +990,28 @@ CONFIG_SYSFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
@@ -827,11 +1026,47 @@ CONFIG_NETWORK_FILESYSTEMS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -839,14 +1074,40 @@ CONFIG_INSTRUMENTATION=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_DEBUG_VERBOSE=y
 CONFIG_DEBUG_MMRS=y
+# CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
@@ -855,33 +1116,40 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_DUAL_CORE_TEST_MODULE is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
 # CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/H8606_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/H8606_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/H8606_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/H8606_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -249,6 +250,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_LARGE_ALLOCS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/IP0X_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/IP0X_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/IP0X_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/IP0X_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -68,6 +68,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -261,6 +262,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_LARGE_ALLOCS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/PNAV-10_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/PNAV-10_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -63,6 +63,7 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
@@ -285,6 +286,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/SRV1_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/SRV1_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/SRV1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/SRV1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -72,6 +72,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
@@ -271,6 +272,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_LARGE_ALLOCS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_DMA_UNCACHED_2M=y
 # CONFIG_DMA_UNCACHED_1M is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
@@ -700,7 +702,7 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 CONFIG_INPUT_UINPUT=y
 # CONFIG_BF53X_PFBUTTONS is not set
-# CONFIG_TWI_KEYPAD is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/configs/TCM-BF537_defconfig linux-libre-2.6.33-gnu1/arch/blackfin/configs/TCM-BF537_defconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/configs/TCM-BF537_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/configs/TCM-BF537_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,13 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
-# Tue Jan  6 09:22:17 2009
+# Linux kernel version: 2.6.30.5
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
@@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -26,49 +29,72 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -76,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -96,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -128,10 +150,15 @@ CONFIG_BF537=y
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
 # CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=2
 CONFIG_BF_REV_MAX=3
@@ -173,11 +200,11 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_STAMP is not set
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 CONFIG_BFIN537_BLUETECHNIX_TCM=y
 # CONFIG_PNAV10 is not set
 # CONFIG_CAMSIG_MINOTAUR is not set
-# CONFIG_GENERIC_BF537_BOARD is not set
 
 #
 # BF537 Specific Configuration
@@ -223,7 +250,10 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
 # CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -273,10 +303,12 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 # CONFIG_BFIN_GPTIMERS is not set
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
@@ -287,10 +319,9 @@ CONFIG_DMA_UNCACHED_1M=y
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -301,7 +332,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -327,6 +358,7 @@ CONFIG_BANK_3=0xFFC2
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
 
 #
 # Executable file formats
@@ -343,13 +375,83 @@ CONFIG_BINFMT_SHARED_FLAT=y
 #
 # CONFIG_PM is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
 
 #
 # CPU Frequency scaling
 #
 # CONFIG_CPU_FREQ is not set
-# CONFIG_NET is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -358,15 +460,21 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
@@ -402,9 +510,10 @@ CONFIG_MTD_CFI_I2=y
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_PSD4256G is not set
 CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
 
 #
@@ -413,7 +522,7 @@ CONFIG_MTD_RAM=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_GPIO_ADDR=y
-CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -436,6 +545,11 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -443,15 +557,23 @@ CONFIG_MTD_UCLINUX=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -464,6 +586,74 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
 #
@@ -480,15 +670,12 @@ CONFIG_HAVE_IDE=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
-# CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PPIFCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_BFIN_DMA_INTERFACE=m
-# CONFIG_SIMPLE_GPIO is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_BFIN_JTAG_COMM is not set
@@ -502,6 +689,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -514,6 +702,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 
 #
@@ -534,39 +723,17 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_DEBUG_GPIO is not set
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -580,6 +747,12 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -588,7 +761,7 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -598,6 +771,7 @@ CONFIG_BFIN_WDT=y
 # Multimedia core support
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
 # CONFIG_VIDEO_MEDIA is not set
 
 #
@@ -618,13 +792,81 @@ CONFIG_BFIN_WDT=y
 #
 # CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+CONFIG_USB_GADGET_NET2272=y
+CONFIG_USB_NET2272=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -641,8 +883,10 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -652,6 +896,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -660,8 +909,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -673,10 +925,7 @@ CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -684,9 +933,19 @@ CONFIG_SYSFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -695,13 +954,62 @@ CONFIG_SYSFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
@@ -714,12 +1022,30 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEBUG_VERBOSE=y
@@ -733,9 +1059,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OF
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -744,20 +1071,110 @@ CONFIG_ACCESS_CHECK=y
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC32 is not set
-# CONFIG_CRC7 is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bfin-global.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-global.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bfin-global.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-global.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,9 +11,6 @@
 
 #ifndef __ASSEMBLY__
 
-#include <asm/sections.h>
-#include <asm/ptrace.h>
-#include <asm/user.h>
 #include <linux/linkage.h>
 #include <linux/types.h>
 
@@ -23,6 +20,12 @@
 # define DMA_UNCACHED_REGION (2 * 1024 * 1024)
 #elif defined(CONFIG_DMA_UNCACHED_1M)
 # define DMA_UNCACHED_REGION (1024 * 1024)
+#elif defined(CONFIG_DMA_UNCACHED_512K)
+# define DMA_UNCACHED_REGION (512 * 1024)
+#elif defined(CONFIG_DMA_UNCACHED_256K)
+# define DMA_UNCACHED_REGION (256 * 1024)
+#elif defined(CONFIG_DMA_UNCACHED_128K)
+# define DMA_UNCACHED_REGION (128 * 1024)
 #else
 # define DMA_UNCACHED_REGION (0)
 #endif
@@ -35,6 +38,7 @@ extern unsigned long get_sclk(void);
 extern unsigned long sclk_to_usecs(unsigned long sclk);
 extern unsigned long usecs_to_sclk(unsigned long usecs);
 
+struct pt_regs;
 extern void dump_bfin_process(struct pt_regs *regs);
 extern void dump_bfin_mem(struct pt_regs *regs);
 extern void dump_bfin_trace_buffer(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bfin-lq035q1.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ * Blackfin LCD Framebuffer driver SHARP LQ035Q1DH02
+ *
+ * Copyright 2008-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef BFIN_LQ035Q1_H
+#define BFIN_LQ035Q1_H
+
+#define LQ035_RL	(0 << 8)	/* Right -> Left Scan */
+#define LQ035_LR	(1 << 8)	/* Left -> Right Scan */
+#define LQ035_TB	(1 << 9)	/* Top -> Botton Scan */
+#define LQ035_BT	(0 << 9)	/* Botton -> Top Scan */
+#define LQ035_BGR	(1 << 11)	/* Use BGR format */
+#define LQ035_RGB	(0 << 11)	/* Use RGB format */
+#define LQ035_NORM	(1 << 13)	/* Reversal */
+#define LQ035_REV	(0 << 13)	/* Reversal */
+
+struct bfin_lq035q1fb_disp_info {
+
+	unsigned	mode;
+	/* GPIOs */
+	int		use_bl;
+	unsigned 	gpio_bl;
+};
+
+#endif /* BFIN_LQ035Q1_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@
 #define BUG()								\
 	do {								\
 		_BUG_OR_WARN(0);					\
-		for (;;);						\
+		unreachable();						\
 	} while (0)
 
 #define WARN_ON(condition)							\
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@
 #define _BLACKFIN_CACHEFLUSH_H
 
 #include <asm/blackfin.h>	/* for SSYNC() */
+#include <asm/sections.h>	/* for _ramend */
 
 extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address);
 extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address);
@@ -68,9 +69,11 @@ do { memcpy(dst, src, len);						\
 #endif
 #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
 # define flush_dcache_range(start,end)		blackfin_dcache_flush_range((start), (end))
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 # define flush_dcache_page(page)		blackfin_dflush_page(page_address(page))
 #else
 # define flush_dcache_range(start,end)		do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 # define flush_dcache_page(page)		do { } while (0)
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/checksum.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/checksum.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/checksum.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/checksum.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,63 +9,12 @@
 #define _BFIN_CHECKSUM_H
 
 /*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-__wsum csum_partial_copy(const void *src, void *dst,
-			       int len, __wsum sum);
-
-/*
- * the same as csum_partial_copy, but copies from user space.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
-					  int len, __wsum sum, int *csum_err);
-
-#define csum_partial_copy_nocheck(src, dst, len, sum)	\
-	csum_partial_copy((src), (dst), (len), (sum))
-
-__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl);
-
-/*
- *	Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-	while (sum >> 16)
-		sum = (sum & 0xffff) + (sum >> 16);
-	return ((~(sum << 16)) >> 16);
-}
-
-/*
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 16-bit checksum, already complemented
  */
 
 static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
 		   unsigned short proto, __wsum sum)
 {
 	unsigned int carry;
@@ -88,19 +37,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32
 
 	return (sum);
 }
+#define csum_tcpudp_nofold __csum_tcpudp_nofold
 
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
-		  unsigned short proto, __wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-extern __sum16 ip_compute_csum(const void *buff, int len);
+#include <asm-generic/checksum.h>
 
-#endif				/* _BFIN_CHECKSUM_H */
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/clocks.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/clocks.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/clocks.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/clocks.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,8 @@
 #ifndef _BFIN_CLOCKS_H
 #define _BFIN_CLOCKS_H
 
+#include <asm/dpmc.h>
+
 #ifdef CONFIG_CCLK_DIV_1
 # define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
 # define CONFIG_CCLK_DIV 1
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dma.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,46 +10,70 @@
 
 #include <linux/interrupt.h>
 #include <mach/dma.h>
+#include <asm/atomic.h>
 #include <asm/blackfin.h>
 #include <asm/page.h>
+#include <asm-generic/dma.h>
 
-#define MAX_DMA_ADDRESS PAGE_OFFSET
+/* DMA_CONFIG Masks */
+#define DMAEN			0x0001	/* DMA Channel Enable */
+#define WNR				0x0002	/* Channel Direction (W/R*) */
+#define WDSIZE_8		0x0000	/* Transfer Word Size = 8 */
+#define WDSIZE_16		0x0004	/* Transfer Word Size = 16 */
+#define WDSIZE_32		0x0008	/* Transfer Word Size = 32 */
+#define DMA2D			0x0010	/* DMA Mode (2D/1D*) */
+#define RESTART			0x0020	/* DMA Buffer Clear */
+#define DI_SEL			0x0040	/* Data Interrupt Timing Select */
+#define DI_EN			0x0080	/* Data Interrupt Enable */
+#define NDSIZE_0		0x0000	/* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1		0x0100	/* Next Descriptor Size = 1 */
+#define NDSIZE_2		0x0200	/* Next Descriptor Size = 2 */
+#define NDSIZE_3		0x0300	/* Next Descriptor Size = 3 */
+#define NDSIZE_4		0x0400	/* Next Descriptor Size = 4 */
+#define NDSIZE_5		0x0500	/* Next Descriptor Size = 5 */
+#define NDSIZE_6		0x0600	/* Next Descriptor Size = 6 */
+#define NDSIZE_7		0x0700	/* Next Descriptor Size = 7 */
+#define NDSIZE_8		0x0800	/* Next Descriptor Size = 8 */
+#define NDSIZE_9		0x0900	/* Next Descriptor Size = 9 */
+#define NDSIZE			0x0f00	/* Next Descriptor Size */
+#define DMAFLOW			0x7000	/* Flow Control */
+#define DMAFLOW_STOP	0x0000	/* Stop Mode */
+#define DMAFLOW_AUTO	0x1000	/* Autobuffer Mode */
+#define DMAFLOW_ARRAY	0x4000	/* Descriptor Array Mode */
+#define DMAFLOW_SMALL	0x6000	/* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE	0x7000	/* Large Model Descriptor List Mode */
 
-/*****************************************************************************
-*        Generic DMA  Declarations
-*
-****************************************************************************/
-enum dma_chan_status {
-	DMA_CHANNEL_FREE,
-	DMA_CHANNEL_REQUESTED,
-	DMA_CHANNEL_ENABLED,
-};
+/* DMA_IRQ_STATUS Masks */
+#define DMA_DONE		0x0001	/* DMA Completion Interrupt Status */
+#define DMA_ERR			0x0002	/* DMA Error Interrupt Status */
+#define DFETCH			0x0004	/* DMA Descriptor Fetch Indicator */
+#define DMA_RUN			0x0008	/* DMA Channel Running Indicator */
 
 /*-------------------------
  * config reg bits value
  *-------------------------*/
-#define DATA_SIZE_8 		0
-#define DATA_SIZE_16 		1
-#define DATA_SIZE_32 		2
+#define DATA_SIZE_8			0
+#define DATA_SIZE_16		1
+#define DATA_SIZE_32		2
 
-#define DMA_FLOW_STOP 		0
-#define DMA_FLOW_AUTO 		1
-#define DMA_FLOW_ARRAY 		4
-#define DMA_FLOW_SMALL 		6
-#define DMA_FLOW_LARGE 		7
+#define DMA_FLOW_STOP		0
+#define DMA_FLOW_AUTO		1
+#define DMA_FLOW_ARRAY		4
+#define DMA_FLOW_SMALL		6
+#define DMA_FLOW_LARGE		7
 
-#define DIMENSION_LINEAR    0
-#define DIMENSION_2D           1
+#define DIMENSION_LINEAR	0
+#define DIMENSION_2D		1
 
-#define DIR_READ     0
-#define DIR_WRITE    1
+#define DIR_READ			0
+#define DIR_WRITE			1
 
-#define INTR_DISABLE   0
-#define INTR_ON_BUF    2
-#define INTR_ON_ROW    3
+#define INTR_DISABLE		0
+#define INTR_ON_BUF			2
+#define INTR_ON_ROW			3
 
 #define DMA_NOSYNC_KEEP_DMA_BUF	0
-#define DMA_SYNC_RESTART	1
+#define DMA_SYNC_RESTART		1
 
 struct dmasg {
 	void *next_desc_addr;
@@ -104,11 +128,9 @@ struct dma_register {
 
 };
 
-struct mutex;
 struct dma_channel {
-	struct mutex dmalock;
 	const char *device_id;
-	enum dma_chan_status chan_status;
+	atomic_t chan_status;
 	volatile struct dma_register *regs;
 	struct dmasg *sg;		/* large mode descriptor */
 	unsigned int irq;
@@ -220,27 +242,20 @@ static inline void set_dma_sg(unsigned i
 
 static inline int dma_channel_active(unsigned int channel)
 {
-	if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE)
-		return 0;
-	else
-		return 1;
+	return atomic_read(&dma_ch[channel].chan_status);
 }
 
 static inline void disable_dma(unsigned int channel)
 {
 	dma_ch[channel].regs->cfg &= ~DMAEN;
 	SSYNC();
-	dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
 }
 static inline void enable_dma(unsigned int channel)
 {
 	dma_ch[channel].regs->curr_x_count = 0;
 	dma_ch[channel].regs->curr_y_count = 0;
 	dma_ch[channel].regs->cfg |= DMAEN;
-	dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED;
 }
-void free_dma(unsigned int channel);
-int request_dma(unsigned int channel, const char *device_id);
 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data);
 
 static inline void dma_disable_irq(unsigned int channel)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,9 +7,9 @@
 #ifndef _BLACKFIN_DMA_MAPPING_H
 #define _BLACKFIN_DMA_MAPPING_H
 
-#include <asm/scatterlist.h>
+#include <asm/cacheflush.h>
+struct scatterlist;
 
-void dma_alloc_init(unsigned long start, unsigned long end);
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t gfp);
 void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
@@ -20,13 +20,51 @@ void dma_free_coherent(struct device *de
  */
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_supported(d, m)         (1)
+#define dma_get_cache_alignment()   (32)
+#define dma_is_consistent(d, h)     (1)
 
-static inline
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
 {
+	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+		return -EIO;
+
+	*dev->dma_mask = dma_mask;
+
 	return 0;
 }
 
+static inline int
+dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+extern void
+__dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
+static inline void
+_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+	if (!__builtin_constant_p(dir)) {
+		__dma_sync(addr, size, dir);
+		return;
+	}
+
+	switch (dir) {
+	case DMA_NONE:
+		BUG();
+	case DMA_TO_DEVICE:		/* writeback only */
+		flush_dcache_range(addr, addr + size);
+		break;
+	case DMA_FROM_DEVICE: /* invalidate only */
+	case DMA_BIDIRECTIONAL: /* flush and invalidate */
+		/* Blackfin has no dedicated invalidate (it includes a flush) */
+		invalidate_dcache_range(addr, addr + size);
+		break;
+	}
+}
+
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
@@ -34,8 +72,13 @@ int dma_mapping_error(struct device *dev
  * Once the device is given the dma address, the device owns this memory
  * until either pci_unmap_single or pci_dma_sync_single is performed.
  */
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-				 enum dma_data_direction direction);
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	       enum dma_data_direction dir)
+{
+	_dma_sync((dma_addr_t)ptr, size, dir);
+	return (dma_addr_t) ptr;
+}
 
 static inline dma_addr_t
 dma_map_page(struct device *dev, struct page *page,
@@ -53,8 +96,12 @@ dma_map_page(struct device *dev, struct
  * After this call, reads by the cpu to the buffer are guarenteed to see
  * whatever the device wrote there.
  */
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-			  enum dma_data_direction direction);
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+}
 
 static inline void
 dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
@@ -80,38 +127,66 @@ dma_unmap_page(struct device *dev, dma_a
  * the same here.
  */
 extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		      enum dma_data_direction direction);
+		      enum dma_data_direction dir);
 
 /*
  * Unmap a set of streaming mode DMA translations.
  * Again, cpu read rules concerning calls here are the same as for
  * pci_unmap_single() above.
  */
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-		      int nhwentries, enum dma_data_direction direction);
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+	     int nhwentries, enum dma_data_direction dir)
+{
+	BUG_ON(!valid_dma_direction(dir));
+}
 
-static inline void dma_sync_single_for_cpu(struct device *dev,
-					dma_addr_t handle, size_t size,
-					enum dma_data_direction dir)
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle,
+			      unsigned long offset, size_t size,
+			      enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
 }
 
-static inline void dma_sync_single_for_device(struct device *dev,
-					dma_addr_t handle, size_t size,
-					enum dma_data_direction dir)
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction dir)
 {
+	_dma_sync(handle + offset, size, dir);
 }
 
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-					struct scatterlist *sg,
-					int nents, enum dma_data_direction dir)
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
+			enum dma_data_direction dir)
 {
+	dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
 }
 
-static inline void dma_sync_sg_for_device(struct device *dev,
-					struct scatterlist *sg,
-					int nents, enum dma_data_direction dir)
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
+			   enum dma_data_direction dir)
+{
+	dma_sync_single_range_for_device(dev, handle, 0, size, dir);
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
+		    enum dma_data_direction dir)
 {
+	BUG_ON(!valid_dma_direction(dir));
+}
+
+extern void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+		       int nents, enum dma_data_direction dir);
+
+static inline void
+dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+	       enum dma_data_direction dir)
+{
+	_dma_sync((dma_addr_t)vaddr, size, dir);
 }
 
 #endif				/* _BLACKFIN_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dpmc.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dpmc.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/dpmc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/dpmc.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Miscellaneous IOCTL commands for Dynamic Power Management Controller Driver
  *
- * Copyright (C) 2004-2008 Analog Device Inc.
+ * Copyright (C) 2004-2009 Analog Device Inc.
  *
  * Licensed under the GPL-2
  */
@@ -9,7 +9,109 @@
 #ifndef _BLACKFIN_DPMC_H_
 #define _BLACKFIN_DPMC_H_
 
-#ifdef __KERNEL__
+/* PLL_CTL Masks */
+#define DF			0x0001	/* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */
+#define PLL_OFF			0x0002	/* PLL Not Powered */
+#define STOPCK			0x0008	/* Core Clock Off */
+#define PDWN			0x0020	/* Enter Deep Sleep Mode */
+#ifdef __ADSPBF539__
+# define IN_DELAY		0x0014	/* Add 200ps Delay To EBIU Input Latches */
+# define OUT_DELAY		0x00C0	/* Add 200ps Delay To EBIU Output Signals */
+#else
+# define IN_DELAY		0x0040	/* Add 200ps Delay To EBIU Input Latches */
+# define OUT_DELAY		0x0080	/* Add 200ps Delay To EBIU Output Signals */
+#endif
+#define BYPASS			0x0100	/* Bypass the PLL */
+#define MSEL			0x7E00	/* Multiplier Select For CCLK/VCO Factors */
+#define SPORT_HYST		0x8000	/* Enable Additional Hysteresis on SPORT Input Pins */
+#define SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */
+
+/* PLL_DIV Masks */
+#define SSEL			0x000F	/* System Select */
+#define CSEL			0x0030	/* Core Select */
+#define CSEL_DIV1		0x0000	/* CCLK = VCO / 1 */
+#define CSEL_DIV2		0x0010	/* CCLK = VCO / 2 */
+#define CSEL_DIV4		0x0020	/* CCLK = VCO / 4 */
+#define CSEL_DIV8		0x0030	/* CCLK = VCO / 8 */
+
+#define CCLK_DIV1 CSEL_DIV1
+#define CCLK_DIV2 CSEL_DIV2
+#define CCLK_DIV4 CSEL_DIV4
+#define CCLK_DIV8 CSEL_DIV8
+
+#define SET_SSEL(x)	((x) & 0xF)	/* Set SSEL = 0-15 --> SCLK = VCO/SSEL */
+#define SCLK_DIV(x)	(x)		/* SCLK = VCO / x */
+
+/* PLL_STAT Masks */
+#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled */
+#define FULL_ON			0x0002	/* Processor In Full On Mode */
+#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled */
+#define PLL_LOCKED		0x0020	/* PLL_LOCKCNT Has Been Reached */
+
+#define RTCWS			0x0400	/* RTC/Reset Wake-Up Status */
+#define CANWS			0x0800	/* CAN Wake-Up Status */
+#define USBWS			0x2000	/* USB Wake-Up Status */
+#define KPADWS			0x4000	/* Keypad Wake-Up Status */
+#define ROTWS			0x8000	/* Rotary Wake-Up Status */
+#define GPWS			0x1000	/* General-Purpose Wake-Up Status */
+
+/* VR_CTL Masks */
+#if defined(__ADSPBF52x__) || defined(__ADSPBF51x__)
+#define FREQ			0x3000	/* Switching Oscillator Frequency For Regulator */
+#define FREQ_1000		0x3000	/* Switching Frequency Is 1 MHz */
+#else
+#define FREQ			0x0003	/* Switching Oscillator Frequency For Regulator */
+#define FREQ_333		0x0001	/* Switching Frequency Is 333 kHz */
+#define FREQ_667		0x0002	/* Switching Frequency Is 667 kHz */
+#define FREQ_1000		0x0003	/* Switching Frequency Is 1 MHz */
+#endif
+#define HIBERNATE		0x0000	/* Powerdown/Bypass On-Board Regulation */
+
+#define GAIN			0x000C	/* Voltage Level Gain */
+#define GAIN_5			0x0000	/* GAIN = 5 */
+#define GAIN_10			0x0004	/* GAIN = 1 */
+#define GAIN_20			0x0008	/* GAIN = 2 */
+#define GAIN_50			0x000C	/* GAIN = 5 */
+
+#define VLEV			0x00F0	/* Internal Voltage Level */
+#ifdef __ADSPBF52x__
+#define VLEV_085 		0x0040	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_090		0x0050	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define VLEV_095		0x0060	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define VLEV_100		0x0070	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define VLEV_105		0x0080	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define VLEV_110		0x0090	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define VLEV_115		0x00A0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define VLEV_120		0x00B0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#else
+#define VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define VLEV_105		0x00A0	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define VLEV_110		0x00B0	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define VLEV_115		0x00C0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define VLEV_120		0x00D0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define VLEV_125		0x00E0	/* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define VLEV_130		0x00F0	/* VLEV = 1.30 V (-5% - +10% Accuracy) */
+#endif
+
+#define WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate */
+#define CANWE			0x0200	/* Enable CAN Wakeup From Hibernate */
+#define PHYWE			0x0400	/* Enable PHY Wakeup From Hibernate */
+#define GPWE			0x0400	/* General-Purpose Wake-Up Enable */
+#define MXVRWE			0x0400	/* Enable MXVR Wakeup From Hibernate */
+#define KPADWE			0x1000	/* Keypad Wake-Up Enable */
+#define ROTWE			0x2000	/* Rotary Wake-Up Enable */
+#define CLKBUFOE		0x4000	/* CLKIN Buffer Output Enable */
+#define SCKELOW			0x8000	/* Do Not Drive SCKE High During Reset After Hibernate */
+
+#if defined(__ADSPBF52x__) || defined(__ADSPBF51x__)
+#define USBWE			0x0200	/* Enable USB Wakeup From Hibernate */
+#else
+#define USBWE			0x0800	/* Enable USB Wakeup From Hibernate */
+#endif
+
 #ifndef __ASSEMBLY__
 
 void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
@@ -54,6 +156,5 @@ struct bfin_dpmc_platform_data {
 	w[P0 + (x - PLL_CTL)] = R0;\
 
 #endif
-#endif	/* __KERNEL__ */
 
 #endif	/*_BLACKFIN_DPMC_H_*/
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,6 @@ do {											\
 	_regs->p2	= _dynamic_addr;				\
 } while(0)
 
-#define USE_ELF_CORE_DUMP
 #define ELF_FDPIC_CORE_EFLAGS	EF_BFIN_FDPIC
 #define ELF_EXEC_PAGESIZE	4096
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/fcntl.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/fcntl.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/fcntl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/fcntl.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,8 +7,6 @@
 #ifndef _BFIN_FCNTL_H
 #define _BFIN_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_DIRECTORY	 040000	/* must be a directory */
 #define O_NOFOLLOW	0100000	/* don't follow links */
 #define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/gpio.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gpio.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -159,6 +159,11 @@ struct gpio_port_t {
 };
 #endif
 
+#ifdef BFIN_SPECIAL_GPIO_BANKS
+void bfin_special_gpio_free(unsigned gpio);
+int bfin_special_gpio_request(unsigned gpio, const char *label);
+#endif
+
 #ifdef CONFIG_PM
 
 unsigned int bfin_pm_standby_setup(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/gptimers.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gptimers.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/gptimers.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/gptimers.h	2010-02-24 13:52:17.000000000 -0500
@@ -172,25 +172,25 @@
 
 /* The actual gptimer API */
 
-void     set_gptimer_pwidth(int timer_id, uint32_t width);
-uint32_t get_gptimer_pwidth(int timer_id);
-void     set_gptimer_period(int timer_id, uint32_t period);
-uint32_t get_gptimer_period(int timer_id);
-uint32_t get_gptimer_count(int timer_id);
-int      get_gptimer_intr(int timer_id);
-void     clear_gptimer_intr(int timer_id);
-int      get_gptimer_over(int timer_id);
-void     clear_gptimer_over(int timer_id);
-void     set_gptimer_config(int timer_id, uint16_t config);
-uint16_t get_gptimer_config(int timer_id);
-int      get_gptimer_run(int timer_id);
-void     set_gptimer_pulse_hi(int timer_id);
-void     clear_gptimer_pulse_hi(int timer_id);
+void     set_gptimer_pwidth(unsigned int timer_id, uint32_t width);
+uint32_t get_gptimer_pwidth(unsigned int timer_id);
+void     set_gptimer_period(unsigned int timer_id, uint32_t period);
+uint32_t get_gptimer_period(unsigned int timer_id);
+uint32_t get_gptimer_count(unsigned int timer_id);
+int      get_gptimer_intr(unsigned int timer_id);
+void     clear_gptimer_intr(unsigned int timer_id);
+int      get_gptimer_over(unsigned int timer_id);
+void     clear_gptimer_over(unsigned int timer_id);
+void     set_gptimer_config(unsigned int timer_id, uint16_t config);
+uint16_t get_gptimer_config(unsigned int timer_id);
+int      get_gptimer_run(unsigned int timer_id);
+void     set_gptimer_pulse_hi(unsigned int timer_id);
+void     clear_gptimer_pulse_hi(unsigned int timer_id);
 void     enable_gptimers(uint16_t mask);
 void     disable_gptimers(uint16_t mask);
 void     disable_gptimers_sync(uint16_t mask);
 uint16_t get_enabled_gptimers(void);
-uint32_t get_gptimer_status(int group);
-void     set_gptimer_status(int group, uint32_t value);
+uint32_t get_gptimer_status(unsigned int group);
+void     set_gptimer_status(unsigned int group, uint32_t value);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/io.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/io.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,12 +31,14 @@ static inline unsigned char readb(const
 	unsigned int val;
 	int tmp;
 
-	__asm__ __volatile__ ("cli %1;\n\t"
-			"NOP; NOP; SSYNC;\n\t"
-			"%0 = b [%2] (z);\n\t"
-			"sti %1;\n\t"
-			: "=d"(val), "=d"(tmp): "a"(addr)
-			);
+	__asm__ __volatile__ (
+		"cli %1;"
+		"NOP; NOP; SSYNC;"
+		"%0 = b [%2] (z);"
+		"sti %1;"
+		: "=d"(val), "=d"(tmp)
+		: "a"(addr)
+	);
 
 	return (unsigned char) val;
 }
@@ -46,12 +48,14 @@ static inline unsigned short readw(const
 	unsigned int val;
 	int tmp;
 
-	__asm__ __volatile__ ("cli %1;\n\t"
-			"NOP; NOP; SSYNC;\n\t"
-			"%0 = w [%2] (z);\n\t"
-			"sti %1;\n\t"
-		      	: "=d"(val), "=d"(tmp): "a"(addr)
-			);
+	__asm__ __volatile__ (
+		"cli %1;"
+		"NOP; NOP; SSYNC;"
+		"%0 = w [%2] (z);"
+		"sti %1;"
+		: "=d"(val), "=d"(tmp)
+		: "a"(addr)
+	);
 
 	return (unsigned short) val;
 }
@@ -61,20 +65,23 @@ static inline unsigned int readl(const v
 	unsigned int val;
 	int tmp;
 
-	__asm__ __volatile__ ("cli %1;\n\t"
-			"NOP; NOP; SSYNC;\n\t"
-			"%0 = [%2];\n\t"
-			"sti %1;\n\t"
-		      	: "=d"(val), "=d"(tmp): "a"(addr)
-			);
+	__asm__ __volatile__ (
+		"cli %1;"
+		"NOP; NOP; SSYNC;"
+		"%0 = [%2];"
+		"sti %1;"
+		: "=d"(val), "=d"(tmp)
+		: "a"(addr)
+	);
+
 	return val;
 }
 
 #endif /*  __ASSEMBLY__ */
 
-#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
 
 #define __raw_readb readb
 #define __raw_readw readw
@@ -82,9 +89,9 @@ static inline unsigned int readl(const v
 #define __raw_writeb writeb
 #define __raw_writew writew
 #define __raw_writel writel
-#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+#define memset_io(a, b, c)	memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c)	memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c)	memcpy((void *)(a), (b), (c))
 
 /* Convert "I/O port addresses" to actual addresses.  i.e. ugly casts. */
 #define __io(port) ((void *)(unsigned long)(port))
@@ -92,30 +99,30 @@ static inline unsigned int readl(const v
 #define inb(port)    readb(__io(port))
 #define inw(port)    readw(__io(port))
 #define inl(port)    readl(__io(port))
-#define outb(x,port) writeb(x,__io(port))
-#define outw(x,port) writew(x,__io(port))
-#define outl(x,port) writel(x,__io(port))
+#define outb(x, port) writeb(x, __io(port))
+#define outw(x, port) writew(x, __io(port))
+#define outl(x, port) writel(x, __io(port))
 
 #define inb_p(port)    inb(__io(port))
 #define inw_p(port)    inw(__io(port))
 #define inl_p(port)    inl(__io(port))
-#define outb_p(x,port) outb(x,__io(port))
-#define outw_p(x,port) outw(x,__io(port))
-#define outl_p(x,port) outl(x,__io(port))
+#define outb_p(x, port) outb(x, __io(port))
+#define outw_p(x, port) outw(x, __io(port))
+#define outl_p(x, port) outl(x, __io(port))
 
-#define ioread8_rep(a,d,c)	readsb(a,d,c)
-#define ioread16_rep(a,d,c)	readsw(a,d,c)
-#define ioread32_rep(a,d,c)	readsl(a,d,c)
-#define iowrite8_rep(a,s,c)	writesb(a,s,c)
-#define iowrite16_rep(a,s,c)	writesw(a,s,c)
-#define iowrite32_rep(a,s,c)	writesl(a,s,c)
+#define ioread8_rep(a, d, c)	readsb(a, d, c)
+#define ioread16_rep(a, d, c)	readsw(a, d, c)
+#define ioread32_rep(a, d, c)	readsl(a, d, c)
+#define iowrite8_rep(a, s, c)	writesb(a, s, c)
+#define iowrite16_rep(a, s, c)	writesw(a, s, c)
+#define iowrite32_rep(a, s, c)	writesl(a, s, c)
 
-#define ioread8(X)			readb(X)
-#define ioread16(X)			readw(X)
-#define ioread32(X)			readl(X)
-#define iowrite8(val,X)			writeb(val,X)
-#define iowrite16(val,X)		writew(val,X)
-#define iowrite32(val,X)		writel(val,X)
+#define ioread8(x)			readb(x)
+#define ioread16(x)			readw(x)
+#define ioread32(x)			readl(x)
+#define iowrite8(val, x)		writeb(val, x)
+#define iowrite16(val, x)		writew(val, x)
+#define iowrite32(val, x)		writel(val, x)
 
 #define mmiowb() wmb()
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ipipe_base.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ipipe_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ipipe_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ipipe_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,23 +51,15 @@
 
 extern unsigned long __ipipe_root_status; /* Alias to ipipe_root_cpudom_var(status) */
 
-#define __ipipe_stall_root()						\
-	do {								\
-		volatile unsigned long *p = &__ipipe_root_status;	\
-		set_bit(0, p);						\
-	} while (0)
+void __ipipe_stall_root(void);
 
-#define __ipipe_test_and_stall_root()					\
-	({								\
-		volatile unsigned long *p = &__ipipe_root_status;	\
-		test_and_set_bit(0, p);					\
-	})
+unsigned long __ipipe_test_and_stall_root(void);
 
-#define __ipipe_test_root()					\
-	({							\
-		const unsigned long *p = &__ipipe_root_status;	\
-		test_bit(0, p);					\
-	})
+unsigned long __ipipe_test_root(void);
+
+void __ipipe_lock_root(void);
+
+void __ipipe_unlock_root(void);
 
 #endif /* !__ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ipipe.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ipipe.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ipipe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ipipe.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,9 +35,9 @@
 #include <asm/atomic.h>
 #include <asm/traps.h>
 
-#define IPIPE_ARCH_STRING     "1.11-00"
+#define IPIPE_ARCH_STRING     "1.12-00"
 #define IPIPE_MAJOR_NUMBER    1
-#define IPIPE_MINOR_NUMBER    11
+#define IPIPE_MINOR_NUMBER    12
 #define IPIPE_PATCH_NUMBER    0
 
 #ifdef CONFIG_SMP
@@ -124,16 +124,6 @@ static inline int __ipipe_check_tickdev(
 	return 1;
 }
 
-static inline void __ipipe_lock_root(void)
-{
-	set_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status));
-}
-
-static inline void __ipipe_unlock_root(void)
-{
-	clear_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status));
-}
-
 void __ipipe_enable_pipeline(void);
 
 #define __ipipe_hook_critical_ipi(ipd) do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/irqflags.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/irqflags.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/irqflags.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/irqflags.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@ static inline unsigned long bfin_cli(voi
 
 #ifdef CONFIG_IPIPE
 
+#include <linux/compiler.h>
 #include <linux/ipipe_base.h>
 #include <linux/ipipe_trace.h>
 
@@ -49,12 +50,12 @@ static inline unsigned long bfin_cli(voi
 		barrier();				\
 	} while (0)
 
-static inline void raw_local_irq_enable(void)
-{
-	barrier();
-	ipipe_check_context(ipipe_root_domain);
-	__ipipe_unstall_root();
-}
+#define raw_local_irq_enable()				\
+	do {						\
+		barrier();				\
+		ipipe_check_context(ipipe_root_domain);	\
+		__ipipe_unstall_root();			\
+	} while (0)
 
 #define raw_local_save_flags_ptr(x)					\
 	do {								\
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/kgdb.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/kgdb.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/kgdb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/kgdb.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,9 +10,6 @@
 
 #include <linux/ptrace.h>
 
-/* gdb locks */
-#define KGDB_MAX_NO_CPUS 8
-
 /*
  * BUFMAX defines the maximum number of characters in inbound/outbound buffers.
  * At least NUMREGBYTES*2 are needed for register packets.
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/mem_init.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mem_init.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/mem_init.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mem_init.h	2010-02-24 13:52:17.000000000 -0500
@@ -295,156 +295,3 @@
 #else
 #define PLL_BYPASS       0
 #endif
-
-/***************************************Currently Not Being Used *********************************/
-
-#if defined(CONFIG_FLASH_SPEED_BWAT) && \
-defined(CONFIG_FLASH_SPEED_BRAT) && \
-defined(CONFIG_FLASH_SPEED_BHT) && \
-defined(CONFIG_FLASH_SPEED_BST) && \
-defined(CONFIG_FLASH_SPEED_BTT)
-
-#define flash_EBIU_AMBCTL_WAT  ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
-#define flash_EBIU_AMBCTL_RAT  ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
-#define flash_EBIU_AMBCTL_HT   ((CONFIG_FLASH_SPEED_BHT  * 4) / (4000000000 / CONFIG_SCLK_HZ))
-#define flash_EBIU_AMBCTL_ST   ((CONFIG_FLASH_SPEED_BST  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
-#define flash_EBIU_AMBCTL_TT   ((CONFIG_FLASH_SPEED_BTT  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
-
-#if (flash_EBIU_AMBCTL_TT > 3)
-#define flash_EBIU_AMBCTL0_TT   B0TT_4
-#endif
-#if (flash_EBIU_AMBCTL_TT == 3)
-#define flash_EBIU_AMBCTL0_TT   B0TT_3
-#endif
-#if (flash_EBIU_AMBCTL_TT == 2)
-#define flash_EBIU_AMBCTL0_TT   B0TT_2
-#endif
-#if (flash_EBIU_AMBCTL_TT < 2)
-#define flash_EBIU_AMBCTL0_TT   B0TT_1
-#endif
-
-#if (flash_EBIU_AMBCTL_ST > 3)
-#define flash_EBIU_AMBCTL0_ST   B0ST_4
-#endif
-#if (flash_EBIU_AMBCTL_ST == 3)
-#define flash_EBIU_AMBCTL0_ST   B0ST_3
-#endif
-#if (flash_EBIU_AMBCTL_ST == 2)
-#define flash_EBIU_AMBCTL0_ST   B0ST_2
-#endif
-#if (flash_EBIU_AMBCTL_ST < 2)
-#define flash_EBIU_AMBCTL0_ST   B0ST_1
-#endif
-
-#if (flash_EBIU_AMBCTL_HT > 2)
-#define flash_EBIU_AMBCTL0_HT   B0HT_3
-#endif
-#if (flash_EBIU_AMBCTL_HT == 2)
-#define flash_EBIU_AMBCTL0_HT   B0HT_2
-#endif
-#if (flash_EBIU_AMBCTL_HT == 1)
-#define flash_EBIU_AMBCTL0_HT   B0HT_1
-#endif
-#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
-#define flash_EBIU_AMBCTL0_HT   B0HT_0
-#endif
-#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
-#define flash_EBIU_AMBCTL0_HT   B0HT_1
-#endif
-
-#if (flash_EBIU_AMBCTL_WAT > 14)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_15
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 14)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_14
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 13)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_13
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 12)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_12
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 11)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_11
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 10)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_10
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 9)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_9
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 8)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_8
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 7)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_7
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 6)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_6
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 5)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_5
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 4)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_4
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 3)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_3
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 2)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_2
-#endif
-#if (flash_EBIU_AMBCTL_WAT == 1)
-#define flash_EBIU_AMBCTL0_WAT  B0WAT_1
-#endif
-
-#if (flash_EBIU_AMBCTL_RAT > 14)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_15
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 14)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_14
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 13)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_13
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 12)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_12
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 11)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_11
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 10)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_10
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 9)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_9
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 8)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_8
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 7)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_7
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 6)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_6
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 5)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_5
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 4)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_4
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 3)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_3
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 2)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_2
-#endif
-#if (flash_EBIU_AMBCTL_RAT == 1)
-#define flash_EBIU_AMBCTL0_RAT  B0RAT_1
-#endif
-
-#define flash_EBIU_AMBCTL0  \
-	(flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
-	 flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/mmu_context.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mmu_context.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/mmu_context.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
@@ -66,8 +66,8 @@ activate_l1stack(struct mm_struct *mm, u
 
 #define activate_mm(prev, next) switch_mm(prev, next, NULL)
 
-static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
-			     struct task_struct *tsk)
+static inline void __switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
+			       struct task_struct *tsk)
 {
 #ifdef CONFIG_MPU
 	unsigned int cpu = smp_processor_id();
@@ -95,7 +95,24 @@ static inline void switch_mm(struct mm_s
 #endif
 }
 
+#ifdef CONFIG_IPIPE
+#define lock_mm_switch(flags)	local_irq_save_hw_cond(flags)
+#define unlock_mm_switch(flags)	local_irq_restore_hw_cond(flags)
+#else
+#define lock_mm_switch(flags)	do { (void)(flags); } while (0)
+#define unlock_mm_switch(flags)	do { (void)(flags); } while (0)
+#endif /* CONFIG_IPIPE */
+
 #ifdef CONFIG_MPU
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			     struct task_struct *tsk)
+{
+	unsigned long flags;
+	lock_mm_switch(flags);
+	__switch_mm(prev, next, tsk);
+	unlock_mm_switch(flags);
+}
+
 static inline void protect_page(struct mm_struct *mm, unsigned long addr,
 				unsigned long flags)
 {
@@ -128,6 +145,12 @@ static inline void update_protections(st
 		set_mask_dcplbs(mm->context.page_rwx_mask, cpu);
 	}
 }
+#else /* !CONFIG_MPU */
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			     struct task_struct *tsk)
+{
+	__switch_mm(prev, next, tsk);
+}
 #endif
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
@@ -173,4 +196,10 @@ static inline void destroy_context(struc
 #endif
 }
 
+#define ipipe_mm_switch_protect(flags)		\
+	local_irq_save_hw_cond(flags)
+
+#define ipipe_mm_switch_unprotect(flags)	\
+	local_irq_restore_hw_cond(flags)
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/module.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/module.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/module.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/module.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,8 +7,6 @@
 #ifndef _ASM_BFIN_MODULE_H
 #define _ASM_BFIN_MODULE_H
 
-#define MODULE_SYMBOL_PREFIX "_"
-
 #define Elf_Shdr        Elf32_Shdr
 #define Elf_Sym         Elf32_Sym
 #define Elf_Ehdr        Elf32_Ehdr
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/page.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/page.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/page.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,4 +10,9 @@
 #include <asm-generic/page.h>
 #define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
 
+#define VM_DATA_DEFAULT_FLAGS \
+	(VM_READ | VM_WRITE | \
+	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/pci.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/pci.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,145 +4,19 @@
 #define _ASM_BFIN_PCI_H
 
 #include <asm/scatterlist.h>
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci.h>
 
-/*
- *
- * Written by Wout Klaren.
- */
-
-/* Added by Chang Junxiao */
 #define PCIBIOS_MIN_IO 0x00001000
 #define PCIBIOS_MIN_MEM 0x10000000
 
-#define PCI_DMA_BUS_IS_PHYS       (1)
-struct pci_ops;
-
-/*
- * Structure with hardware dependent information and functions of the
- * PCI bus.
- */
-struct pci_bus_info {
-
-	/*
-	 * Resources of the PCI bus.
-	 */
-	struct resource mem_space;
-	struct resource io_space;
-
-	/*
-	 * System dependent functions.
-	 */
-	struct pci_ops *bfin_pci_ops;
-	void (*fixup) (int pci_modify);
-	void (*conf_device) (unsigned char bus, unsigned char device_fn);
-};
-
-#define pcibios_assign_all_busses()	0
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
-
 	/* No special bus mastering setup handling */
 }
 static inline void pcibios_penalize_isa_irq(int irq)
 {
-
 	/* We don't do dynamic PCI IRQ allocation */
 }
-static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-					size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	 /* return virt_to_bus(ptr); */
-	return (dma_addr_t) ptr;
-}
-
-/* Unmap a single streaming mode DMA translation.  The dma_addr and size
- * must match what was provided for in a previous pci_map_single call.  All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
-static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-				    size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/* Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scather-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-			     int nents, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-	return nents;
-}
-
-/* Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-				int nents, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/* Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, the
- * device again owns the buffer.
- */
-static inline void pci_dma_sync_single(struct pci_dev *hwdev,
-				       dma_addr_t dma_handle, size_t size,
-				       int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/* Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list,
- * same rules and usage.
- */
-static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
-				   struct scatterlist *sg, int nelems,
-				   int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
 
 #endif				/* _ASM_BFIN_PCI_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -89,9 +89,9 @@ struct pt_regs {
 #define PTRACE_GETREGS            12
 #define PTRACE_SETREGS            13	/* ptrace signal  */
 
-#define PTRACE_GETFDPIC           31
-#define PTRACE_GETFDPIC_EXEC      0
-#define PTRACE_GETFDPIC_INTERP    1
+#define PTRACE_GETFDPIC           31	/* get the ELF fdpic loadmap address */
+#define PTRACE_GETFDPIC_EXEC       0	/* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP     1	/* [addr] request the interpreter loadmap */
 
 #define PS_S  (0x0002)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/sections.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/sections.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/sections.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/sections.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,10 +13,18 @@ extern unsigned long memory_mtd_start, m
 extern unsigned long _ramstart, _ramend, _rambase;
 extern unsigned long memory_start, memory_end, physical_mem_end;
 
-extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[],
-	_ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
-	_stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[],
-	_ebss_l2[], _l2_lma_start[];
+/*
+ * The weak markings on the lengths might seem weird, but this is required
+ * in order to make gcc accept the fact that these may actually have a value
+ * of 0 (since they aren't actually addresses, but sizes of sections).
+ */
+extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[];
+extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[],
+	_data_l1_lma[], __weak _data_l1_len[];
+extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
+	_data_b_l1_lma[], __weak _data_b_l1_len[];
+extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[],
+	_sbss_l2[], _ebss_l2[], _l2_lma[], __weak _l2_len[];
 
 #include <asm/mem_map.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,84 +17,84 @@ asmlinkage int __raw_spin_is_locked_asm(
 asmlinkage void __raw_spin_lock_asm(volatile int *ptr);
 asmlinkage int __raw_spin_trylock_asm(volatile int *ptr);
 asmlinkage void __raw_spin_unlock_asm(volatile int *ptr);
-asmlinkage void __raw_read_lock_asm(volatile int *ptr);
-asmlinkage int __raw_read_trylock_asm(volatile int *ptr);
-asmlinkage void __raw_read_unlock_asm(volatile int *ptr);
-asmlinkage void __raw_write_lock_asm(volatile int *ptr);
-asmlinkage int __raw_write_trylock_asm(volatile int *ptr);
-asmlinkage void __raw_write_unlock_asm(volatile int *ptr);
+asmlinkage void arch_read_lock_asm(volatile int *ptr);
+asmlinkage int arch_read_trylock_asm(volatile int *ptr);
+asmlinkage void arch_read_unlock_asm(volatile int *ptr);
+asmlinkage void arch_write_lock_asm(volatile int *ptr);
+asmlinkage int arch_write_trylock_asm(volatile int *ptr);
+asmlinkage void arch_write_unlock_asm(volatile int *ptr);
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
 {
 	return __raw_spin_is_locked_asm(&lock->lock);
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	__raw_spin_lock_asm(&lock->lock);
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	return __raw_spin_trylock_asm(&lock->lock);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__raw_spin_unlock_asm(&lock->lock);
 }
 
-static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
-	while (__raw_spin_is_locked(lock))
+	while (arch_spin_is_locked(lock))
 		cpu_relax();
 }
 
-static inline int __raw_read_can_lock(raw_rwlock_t *rw)
+static inline int arch_read_can_lock(arch_rwlock_t *rw)
 {
 	return __raw_uncached_fetch_asm(&rw->lock) > 0;
 }
 
-static inline int __raw_write_can_lock(raw_rwlock_t *rw)
+static inline int arch_write_can_lock(arch_rwlock_t *rw)
 {
 	return __raw_uncached_fetch_asm(&rw->lock) == RW_LOCK_BIAS;
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
-	__raw_read_lock_asm(&rw->lock);
+	arch_read_lock_asm(&rw->lock);
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
-	return __raw_read_trylock_asm(&rw->lock);
+	return arch_read_trylock_asm(&rw->lock);
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
-	__raw_read_unlock_asm(&rw->lock);
+	arch_read_unlock_asm(&rw->lock);
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
-	__raw_write_lock_asm(&rw->lock);
+	arch_write_lock_asm(&rw->lock);
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
-	return __raw_write_trylock_asm(&rw->lock);
+	return arch_write_trylock_asm(&rw->lock);
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
-	__raw_write_unlock_asm(&rw->lock);
+	arch_write_unlock_asm(&rw->lock);
 }
 
-#define _raw_spin_relax(lock)  	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)  	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,14 +15,14 @@
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
+#define __ARCH_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/thread_info.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/thread_info.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/thread_info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
@@ -103,11 +103,13 @@ static inline struct thread_info *curren
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
 #define TIF_FREEZE              6       /* is freezing for suspend */
 #define TIF_IRQ_SYNC            7       /* sync pipeline stage */
+#define TIF_NOTIFY_RESUME       8       /* callback before returning to user */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_FREEZE             (1<<TIF_FREEZE)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/trace.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/trace.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/trace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/trace.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,8 @@ extern unsigned long software_trace_buff
 
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
 
+#define trace_buffer_init() bfin_write_TBUFCTL(BFIN_TRACE_INIT)
+
 #define trace_buffer_save(x) \
 	do { \
 		(x) = bfin_read_TBUFCTL(); \
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/uaccess.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/uaccess.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/uaccess.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,7 @@
 #include <linux/string.h>
 
 #include <asm/segment.h>
-#ifdef CONFIG_ACCESS_CHECK
-# include <asm/bfin-global.h>
-#endif
+#include <asm/sections.h>
 
 #define get_ds()        (KERNEL_DS)
 #define get_fs()        (current_thread_info()->addr_limit)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -388,8 +388,9 @@
 #define __NR_pwritev		367
 #define __NR_rt_tgsigqueueinfo	368
 #define __NR_perf_event_open	369
+#define __NR_recvmmsg		370
 
-#define __NR_syscall		370
+#define __NR_syscall		371
 #define NR_syscalls		__NR_syscall
 
 /* Old optional stuff no one actually uses */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/Kconfig linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,10 @@
 
 mainmenu "Blackfin Kernel Configuration"
 
+config SYMBOL_PREFIX
+	string
+	default "_"
+
 config MMU
 	def_bool n
 
@@ -28,6 +32,9 @@ config BLACKFIN
 	select HAVE_OPROFILE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 
+config GENERIC_CSUM
+	def_bool y
+
 config GENERIC_BUG
 	def_bool y
 	depends on BUG
@@ -173,7 +180,7 @@ config BF539
 	help
 	  BF539 Processor Support.
 
-config BF542
+config BF542_std
 	bool "BF542"
 	help
 	  BF542 Processor Support.
@@ -183,7 +190,7 @@ config BF542M
 	help
 	  BF542 Processor Support.
 
-config BF544
+config BF544_std
 	bool "BF544"
 	help
 	  BF544 Processor Support.
@@ -193,7 +200,7 @@ config BF544M
 	help
 	  BF544 Processor Support.
 
-config BF547
+config BF547_std
 	bool "BF547"
 	help
 	  BF547 Processor Support.
@@ -203,7 +210,7 @@ config BF547M
 	help
 	  BF547 Processor Support.
 
-config BF548
+config BF548_std
 	bool "BF548"
 	help
 	  BF548 Processor Support.
@@ -213,7 +220,7 @@ config BF548M
 	help
 	  BF548 Processor Support.
 
-config BF549
+config BF549_std
 	bool "BF549"
 	help
 	  BF549 Processor Support.
@@ -307,31 +314,11 @@ config BF_REV_NONE
 
 endchoice
 
-config BF51x
-	bool
-	depends on (BF512 || BF514 || BF516 || BF518)
-	default y
-
-config BF52x
-	bool
-	depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527)
-	default y
-
 config BF53x
 	bool
 	depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
 	default y
 
-config BF54xM
-	bool
-	depends on (BF542M || BF544M || BF547M || BF548M || BF549M)
-	default y
-
-config BF54x
-	bool
-	depends on (BF542 || BF544 || BF547 || BF548 || BF549 || BF54xM)
-	default y
-
 config MEM_GENERIC_BOARD
 	bool
 	depends on GENERIC_BOARD
@@ -913,6 +900,12 @@ config DMA_UNCACHED_2M
 	bool "Enable 2M DMA region"
 config DMA_UNCACHED_1M
 	bool "Enable 1M DMA region"
+config DMA_UNCACHED_512K
+	bool "Enable 512K DMA region"
+config DMA_UNCACHED_256K
+	bool "Enable 256K DMA region"
+config DMA_UNCACHED_128K
+	bool "Enable 128K DMA region"
 config DMA_UNCACHED_NONE
 	bool "Disable DMA region"
 endchoice
@@ -1274,6 +1267,8 @@ source "net/Kconfig"
 
 source "drivers/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "fs/Kconfig"
 
 source "arch/blackfin/Kconfig.debug"
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_dma_5xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,9 +37,8 @@ static int __init blackfin_dma_init(void
 	printk(KERN_INFO "Blackfin DMA Controller\n");
 
 	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
-		dma_ch[i].chan_status = DMA_CHANNEL_FREE;
+		atomic_set(&dma_ch[i].chan_status, 0);
 		dma_ch[i].regs = dma_io_base_addr[i];
-		mutex_init(&(dma_ch[i].dmalock));
 	}
 	/* Mark MEMDMA Channel 0 as requested since we're using it internally */
 	request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy");
@@ -60,7 +59,7 @@ static int proc_dma_show(struct seq_file
 	int i;
 
 	for (i = 0; i < MAX_DMA_CHANNELS; ++i)
-		if (dma_ch[i].chan_status != DMA_CHANNEL_FREE)
+		if (dma_channel_active(i))
 			seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id);
 
 	return 0;
@@ -107,20 +106,11 @@ int request_dma(unsigned int channel, co
 	}
 #endif
 
-	mutex_lock(&(dma_ch[channel].dmalock));
-
-	if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED)
-	    || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) {
-		mutex_unlock(&(dma_ch[channel].dmalock));
+	if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
 		pr_debug("DMA CHANNEL IN USE  \n");
 		return -EBUSY;
-	} else {
-		dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
-		pr_debug("DMA CHANNEL IS ALLOCATED  \n");
 	}
 
-	mutex_unlock(&(dma_ch[channel].dmalock));
-
 #ifdef CONFIG_BF54x
 	if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
 		unsigned int per_map;
@@ -148,21 +138,20 @@ EXPORT_SYMBOL(request_dma);
 
 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data)
 {
-	BUG_ON(channel >= MAX_DMA_CHANNELS ||
-			dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
+	int ret;
+	unsigned int irq;
 
-	if (callback != NULL) {
-		int ret;
-		unsigned int irq = channel2irq(channel);
+	BUG_ON(channel >= MAX_DMA_CHANNELS || !callback ||
+			!atomic_read(&dma_ch[channel].chan_status));
 
-		ret = request_irq(irq, callback, IRQF_DISABLED,
-			dma_ch[channel].device_id, data);
-		if (ret)
-			return ret;
+	irq = channel2irq(channel);
+	ret = request_irq(irq, callback, 0, dma_ch[channel].device_id, data);
+	if (ret)
+		return ret;
+
+	dma_ch[channel].irq = irq;
+	dma_ch[channel].data = data;
 
-		dma_ch[channel].irq = irq;
-		dma_ch[channel].data = data;
-	}
 	return 0;
 }
 EXPORT_SYMBOL(set_dma_callback);
@@ -184,7 +173,7 @@ void free_dma(unsigned int channel)
 {
 	pr_debug("freedma() : BEGIN \n");
 	BUG_ON(channel >= MAX_DMA_CHANNELS ||
-			dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
+			!atomic_read(&dma_ch[channel].chan_status));
 
 	/* Halt the DMA */
 	disable_dma(channel);
@@ -194,9 +183,7 @@ void free_dma(unsigned int channel)
 		free_irq(dma_ch[channel].irq, dma_ch[channel].data);
 
 	/* Clear the DMA Variable in the Channel */
-	mutex_lock(&(dma_ch[channel].dmalock));
-	dma_ch[channel].chan_status = DMA_CHANNEL_FREE;
-	mutex_unlock(&(dma_ch[channel].dmalock));
+	atomic_set(&dma_ch[channel].chan_status, 0);
 
 	pr_debug("freedma() : END \n");
 }
@@ -210,13 +197,14 @@ int blackfin_dma_suspend(void)
 {
 	int i;
 
-	for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i) {
-		if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) {
+	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
+		if (dma_ch[i].regs->cfg & DMAEN) {
 			printk(KERN_ERR "DMA Channel %d failed to suspend\n", i);
 			return -EBUSY;
 		}
 
-		dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;
+		if (i < MAX_DMA_SUSPEND_CHANNELS)
+			dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/bfin_gpio.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_gpio.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/bfin_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/bfin_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,6 +100,12 @@ u8 pmux_offset[][16] = {
 };
 # endif
 
+#elif defined(BF538_FAMILY)
+static unsigned short * const port_fer[] = {
+	(unsigned short *) PORTCIO_FER,
+	(unsigned short *) PORTDIO_FER,
+	(unsigned short *) PORTEIO_FER,
+};
 #endif
 
 static unsigned short reserved_gpio_map[GPIO_BANK_NUM];
@@ -163,6 +169,27 @@ static int cmp_label(unsigned short iden
 
 static void port_setup(unsigned gpio, unsigned short usage)
 {
+#if defined(BF538_FAMILY)
+	/*
+	 * BF538/9 Port C,D and E are special.
+	 * Inverted PORT_FER polarity on CDE and no PORF_FER on F
+	 * Regular PORT F GPIOs are handled here, CDE are exclusively
+	 * managed by GPIOLIB
+	 */
+
+	if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
+		return;
+
+	gpio -= MAX_BLACKFIN_GPIOS;
+
+	if (usage == GPIO_USAGE)
+		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
+	else
+		*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+	SSYNC();
+	return;
+#endif
+
 	if (check_gpio(gpio))
 		return;
 
@@ -762,6 +789,8 @@ int peripheral_request(unsigned short pe
 	if (!(per & P_DEFINED))
 		return -ENODEV;
 
+	BUG_ON(ident >= MAX_RESOURCES);
+
 	local_irq_save_hw(flags);
 
 	/* If a pin can be muxed as either GPIO or peripheral, make
@@ -979,6 +1008,76 @@ void bfin_gpio_free(unsigned gpio)
 }
 EXPORT_SYMBOL(bfin_gpio_free);
 
+#ifdef BFIN_SPECIAL_GPIO_BANKS
+static unsigned short reserved_special_gpio_map[gpio_bank(MAX_RESOURCES)];
+
+int bfin_special_gpio_request(unsigned gpio, const char *label)
+{
+	unsigned long flags;
+
+	local_irq_save_hw(flags);
+
+	/*
+	 * Allow that the identical GPIO can
+	 * be requested from the same driver twice
+	 * Do nothing and return -
+	 */
+
+	if (cmp_label(gpio, label) == 0) {
+		local_irq_restore_hw(flags);
+		return 0;
+	}
+
+	if (unlikely(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+		local_irq_restore_hw(flags);
+		printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
+		       gpio, get_label(gpio));
+
+		return -EBUSY;
+	}
+	if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+		local_irq_restore_hw(flags);
+		printk(KERN_ERR
+		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
+		       gpio, get_label(gpio));
+
+		return -EBUSY;
+	}
+
+	reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+	reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+	set_label(gpio, label);
+	local_irq_restore_hw(flags);
+	port_setup(gpio, GPIO_USAGE);
+
+	return 0;
+}
+EXPORT_SYMBOL(bfin_special_gpio_request);
+
+void bfin_special_gpio_free(unsigned gpio)
+{
+	unsigned long flags;
+
+	might_sleep();
+
+	local_irq_save_hw(flags);
+
+	if (unlikely(!(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+		gpio_error(gpio);
+		local_irq_restore_hw(flags);
+		return;
+	}
+
+	reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+	reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+	set_label(gpio, "free");
+	local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(bfin_special_gpio_free);
+#endif
+
+
 int bfin_gpio_irq_request(unsigned gpio, const char *label)
 {
 	unsigned long flags;
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbinit.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,6 +92,6 @@ void __init generate_cplb_tables_cpu(uns
 		icplb_tbl[cpu][i_i++].data = 0;
 }
 
-void generate_cplb_tables_all(void)
+void __init generate_cplb_tables_all(void)
 {
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-mpu/cplbmgr.c	2010-02-24 13:52:17.000000000 -0500
@@ -113,11 +113,11 @@ static noinline int dcplb_miss(unsigned
 		addr = L2_START;
 		d_data = L2_DMEMORY;
 	} else if (addr >= physical_mem_end) {
-		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE
-		    && (status & FAULT_USERSUPV)) {
-			addr &= ~0x3fffff;
+		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
+			addr &= ~(4 * 1024 * 1024 - 1);
 			d_data &= ~PAGE_SIZE_4KB;
 			d_data |= PAGE_SIZE_4MB;
+			d_data |= CPLB_USER_RD | CPLB_USER_WR;
 		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
 		    && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
 			addr &= ~(1 * 1024 * 1024 - 1);
@@ -203,7 +203,12 @@ static noinline int icplb_miss(unsigned
 		addr = L2_START;
 		i_data = L2_IMEMORY;
 	} else if (addr >= physical_mem_end) {
-		if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
+		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
+			addr &= ~(4 * 1024 * 1024 - 1);
+			i_data &= ~PAGE_SIZE_4KB;
+			i_data |= PAGE_SIZE_4MB;
+			i_data |= CPLB_USER_RD;
+		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
 		    && (status & FAULT_USERSUPV)) {
 			addr &= ~(1 * 1024 * 1024 - 1);
 			i_data &= ~PAGE_SIZE_4KB;
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/cplb-nompu/cplbinit.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,15 +89,25 @@ void __init generate_cplb_tables_cpu(uns
 
 void __init generate_cplb_tables_all(void)
 {
+	unsigned long uncached_end;
 	int i_d, i_i;
 
 	i_d = 0;
 	/* Normal RAM, including MTD FS.  */
 #ifdef CONFIG_MTD_UCLINUX
-	dcplb_bounds[i_d].eaddr = memory_mtd_start + mtd_size;
+	uncached_end = memory_mtd_start + mtd_size;
 #else
-	dcplb_bounds[i_d].eaddr = memory_end;
+	uncached_end = memory_end;
 #endif
+	/*
+	 * if DMA uncached is less than 1MB, mark the 1MB chunk as uncached
+	 * so that we don't have to use 4kB pages and cause CPLB thrashing
+	 */
+	if ((DMA_UNCACHED_REGION >= 1 * 1024 * 1024) || !DMA_UNCACHED_REGION ||
+	    ((_ramend - uncached_end) >= 1 * 1024 * 1024))
+		dcplb_bounds[i_d].eaddr = uncached_end;
+	else
+		dcplb_bounds[i_d].eaddr = uncached_end & ~(1 * 1024 * 1024);
 	dcplb_bounds[i_d++].data = SDRAM_DGENERIC;
 	/* DMA uncached region.  */
 	if (DMA_UNCACHED_REGION) {
@@ -135,18 +145,15 @@ void __init generate_cplb_tables_all(voi
 
 	i_i = 0;
 	/* Normal RAM, including MTD FS.  */
-#ifdef CONFIG_MTD_UCLINUX
-	icplb_bounds[i_i].eaddr = memory_mtd_start + mtd_size;
-#else
-	icplb_bounds[i_i].eaddr = memory_end;
-#endif
+	icplb_bounds[i_i].eaddr = uncached_end;
 	icplb_bounds[i_i++].data = SDRAM_IGENERIC;
-	/* DMA uncached region.  */
-	if (DMA_UNCACHED_REGION) {
-		icplb_bounds[i_i].eaddr = _ramend;
-		icplb_bounds[i_i++].data = 0;
-	}
 	if (_ramend != physical_mem_end) {
+		/* DMA uncached region.  */
+		if (DMA_UNCACHED_REGION) {
+			/* Normally this hole is caught by the async below.  */
+			icplb_bounds[i_i].eaddr = _ramend;
+			icplb_bounds[i_i++].data = 0;
+		}
 		/* Reserved memory.  */
 		icplb_bounds[i_i].eaddr = physical_mem_end;
 		icplb_bounds[i_i++].data = (reserved_mem_icache_on ?
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/dma-mapping.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/dma-mapping.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/dma-mapping.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/dma-mapping.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,30 +7,25 @@
  */
 
 #include <linux/types.h>
-#include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/spinlock.h>
-#include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/io.h>
 #include <linux/scatterlist.h>
-#include <asm/cacheflush.h>
-#include <asm/bfin-global.h>
 
 static spinlock_t dma_page_lock;
-static unsigned int *dma_page;
+static unsigned long *dma_page;
 static unsigned int dma_pages;
 static unsigned long dma_base;
 static unsigned long dma_size;
 static unsigned int dma_initialized;
 
-void dma_alloc_init(unsigned long start, unsigned long end)
+static void dma_alloc_init(unsigned long start, unsigned long end)
 {
 	spin_lock_init(&dma_page_lock);
 	dma_initialized = 0;
 
-	dma_page = (unsigned int *)__get_free_page(GFP_KERNEL);
+	dma_page = (unsigned long *)__get_free_page(GFP_KERNEL);
 	memset(dma_page, 0, PAGE_SIZE);
 	dma_base = PAGE_ALIGN(start);
 	dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start);
@@ -58,10 +53,11 @@ static unsigned long __alloc_dma_pages(u
 	spin_lock_irqsave(&dma_page_lock, flags);
 
 	for (i = 0; i < dma_pages;) {
-		if (dma_page[i++] == 0) {
+		if (test_bit(i++, dma_page) == 0) {
 			if (++count == pages) {
 				while (count--)
-					dma_page[--i] = 1;
+					__set_bit(--i, dma_page);
+
 				ret = dma_base + (i << PAGE_SHIFT);
 				break;
 			}
@@ -84,14 +80,14 @@ static void __free_dma_pages(unsigned lo
 	}
 
 	spin_lock_irqsave(&dma_page_lock, flags);
-	for (i = page; i < page + pages; i++) {
-		dma_page[i] = 0;
-	}
+	for (i = page; i < page + pages; i++)
+		__clear_bit(i, dma_page);
+
 	spin_unlock_irqrestore(&dma_page_lock, flags);
 }
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-			 dma_addr_t * dma_handle, gfp_t gfp)
+			 dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
 
@@ -115,21 +111,14 @@ dma_free_coherent(struct device *dev, si
 EXPORT_SYMBOL(dma_free_coherent);
 
 /*
- * Dummy functions defined for some existing drivers
+ * Streaming DMA mappings
  */
-
-dma_addr_t
-dma_map_single(struct device *dev, void *ptr, size_t size,
-	       enum dma_data_direction direction)
+void __dma_sync(dma_addr_t addr, size_t size,
+		enum dma_data_direction dir)
 {
-	BUG_ON(direction == DMA_NONE);
-
-	invalidate_dcache_range((unsigned long)ptr,
-			(unsigned long)ptr + size);
-
-	return (dma_addr_t) ptr;
+	_dma_sync(addr, size, dir);
 }
-EXPORT_SYMBOL(dma_map_single);
+EXPORT_SYMBOL(__dma_sync);
 
 int
 dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
@@ -137,30 +126,23 @@ dma_map_sg(struct device *dev, struct sc
 {
 	int i;
 
-	BUG_ON(direction == DMA_NONE);
-
 	for (i = 0; i < nents; i++, sg++) {
 		sg->dma_address = (dma_addr_t) sg_virt(sg);
-
-		invalidate_dcache_range(sg_dma_address(sg),
-					sg_dma_address(sg) +
-					sg_dma_len(sg));
+		__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
 	}
 
 	return nents;
 }
 EXPORT_SYMBOL(dma_map_sg);
 
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		enum dma_data_direction direction)
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			    int nelems, enum dma_data_direction direction)
 {
-	BUG_ON(direction == DMA_NONE);
-}
-EXPORT_SYMBOL(dma_unmap_single);
+	int i;
 
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-		int nhwentries, enum dma_data_direction direction)
-{
-	BUG_ON(direction == DMA_NONE);
+	for (i = 0; i < nelems; i++, sg++) {
+		sg->dma_address = (dma_addr_t) sg_virt(sg);
+		__dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
+	}
 }
-EXPORT_SYMBOL(dma_unmap_sg);
+EXPORT_SYMBOL(dma_sync_sg_for_device);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/gptimers.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/gptimers.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/gptimers.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/gptimers.c	2010-02-24 13:52:17.000000000 -0500
@@ -137,7 +137,7 @@ static uint32_t const timil_mask[MAX_BLA
 #endif
 };
 
-void set_gptimer_pwidth(int timer_id, uint32_t value)
+void set_gptimer_pwidth(unsigned int timer_id, uint32_t value)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	timer_regs[timer_id]->width = value;
@@ -145,14 +145,14 @@ void set_gptimer_pwidth(int timer_id, ui
 }
 EXPORT_SYMBOL(set_gptimer_pwidth);
 
-uint32_t get_gptimer_pwidth(int timer_id)
+uint32_t get_gptimer_pwidth(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return timer_regs[timer_id]->width;
 }
 EXPORT_SYMBOL(get_gptimer_pwidth);
 
-void set_gptimer_period(int timer_id, uint32_t period)
+void set_gptimer_period(unsigned int timer_id, uint32_t period)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	timer_regs[timer_id]->period = period;
@@ -160,28 +160,28 @@ void set_gptimer_period(int timer_id, ui
 }
 EXPORT_SYMBOL(set_gptimer_period);
 
-uint32_t get_gptimer_period(int timer_id)
+uint32_t get_gptimer_period(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return timer_regs[timer_id]->period;
 }
 EXPORT_SYMBOL(get_gptimer_period);
 
-uint32_t get_gptimer_count(int timer_id)
+uint32_t get_gptimer_count(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return timer_regs[timer_id]->counter;
 }
 EXPORT_SYMBOL(get_gptimer_count);
 
-uint32_t get_gptimer_status(int group)
+uint32_t get_gptimer_status(unsigned int group)
 {
 	tassert(group < BFIN_TIMER_NUM_GROUP);
 	return group_regs[group]->status;
 }
 EXPORT_SYMBOL(get_gptimer_status);
 
-void set_gptimer_status(int group, uint32_t value)
+void set_gptimer_status(unsigned int group, uint32_t value)
 {
 	tassert(group < BFIN_TIMER_NUM_GROUP);
 	group_regs[group]->status = value;
@@ -189,42 +189,42 @@ void set_gptimer_status(int group, uint3
 }
 EXPORT_SYMBOL(set_gptimer_status);
 
-int get_gptimer_intr(int timer_id)
+int get_gptimer_intr(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]);
 }
 EXPORT_SYMBOL(get_gptimer_intr);
 
-void clear_gptimer_intr(int timer_id)
+void clear_gptimer_intr(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	group_regs[BFIN_TIMER_OCTET(timer_id)]->status = timil_mask[timer_id];
 }
 EXPORT_SYMBOL(clear_gptimer_intr);
 
-int get_gptimer_over(int timer_id)
+int get_gptimer_over(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]);
 }
 EXPORT_SYMBOL(get_gptimer_over);
 
-void clear_gptimer_over(int timer_id)
+void clear_gptimer_over(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	group_regs[BFIN_TIMER_OCTET(timer_id)]->status = tovf_mask[timer_id];
 }
 EXPORT_SYMBOL(clear_gptimer_over);
 
-int get_gptimer_run(int timer_id)
+int get_gptimer_run(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & trun_mask[timer_id]);
 }
 EXPORT_SYMBOL(get_gptimer_run);
 
-void set_gptimer_config(int timer_id, uint16_t config)
+void set_gptimer_config(unsigned int timer_id, uint16_t config)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	timer_regs[timer_id]->config = config;
@@ -232,7 +232,7 @@ void set_gptimer_config(int timer_id, ui
 }
 EXPORT_SYMBOL(set_gptimer_config);
 
-uint16_t get_gptimer_config(int timer_id)
+uint16_t get_gptimer_config(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	return timer_regs[timer_id]->config;
@@ -280,7 +280,7 @@ void disable_gptimers_sync(uint16_t mask
 }
 EXPORT_SYMBOL(disable_gptimers_sync);
 
-void set_gptimer_pulse_hi(int timer_id)
+void set_gptimer_pulse_hi(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	timer_regs[timer_id]->config |= TIMER_PULSE_HI;
@@ -288,7 +288,7 @@ void set_gptimer_pulse_hi(int timer_id)
 }
 EXPORT_SYMBOL(set_gptimer_pulse_hi);
 
-void clear_gptimer_pulse_hi(int timer_id)
+void clear_gptimer_pulse_hi(unsigned int timer_id)
 {
 	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
 	timer_regs[timer_id]->config &= ~TIMER_PULSE_HI;
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/ipipe.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ipipe.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/ipipe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ipipe.c	2010-02-24 13:52:17.000000000 -0500
@@ -335,3 +335,70 @@ void __ipipe_enable_root_irqs_hw(void)
 	__clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
 	bfin_sti(bfin_irq_flags);
 }
+
+/*
+ * We could use standard atomic bitops in the following root status
+ * manipulation routines, but let's prepare for SMP support in the
+ * same move, preventing CPU migration as required.
+ */
+void __ipipe_stall_root(void)
+{
+	unsigned long *p, flags;
+
+	local_irq_save_hw(flags);
+	p = &__ipipe_root_status;
+	__set_bit(IPIPE_STALL_FLAG, p);
+	local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(__ipipe_stall_root);
+
+unsigned long __ipipe_test_and_stall_root(void)
+{
+	unsigned long *p, flags;
+	int x;
+
+	local_irq_save_hw(flags);
+	p = &__ipipe_root_status;
+	x = __test_and_set_bit(IPIPE_STALL_FLAG, p);
+	local_irq_restore_hw(flags);
+
+	return x;
+}
+EXPORT_SYMBOL(__ipipe_test_and_stall_root);
+
+unsigned long __ipipe_test_root(void)
+{
+	const unsigned long *p;
+	unsigned long flags;
+	int x;
+
+	local_irq_save_hw_smp(flags);
+	p = &__ipipe_root_status;
+	x = test_bit(IPIPE_STALL_FLAG, p);
+	local_irq_restore_hw_smp(flags);
+
+	return x;
+}
+EXPORT_SYMBOL(__ipipe_test_root);
+
+void __ipipe_lock_root(void)
+{
+	unsigned long *p, flags;
+
+	local_irq_save_hw(flags);
+	p = &__ipipe_root_status;
+	__set_bit(IPIPE_SYNCDEFER_FLAG, p);
+	local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(__ipipe_lock_root);
+
+void __ipipe_unlock_root(void)
+{
+	unsigned long *p, flags;
+
+	local_irq_save_hw(flags);
+	p = &__ipipe_root_status;
+	__clear_bit(IPIPE_SYNCDEFER_FLAG, p);
+	local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(__ipipe_unlock_root);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/irqchip.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/irqchip.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/irqchip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/irqchip.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@ void ack_bad_irq(unsigned int irq)
 
 static struct irq_desc bad_irq_desc = {
 	.handle_irq = handle_bad_irq,
-	.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
+	.lock = __RAW_SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
 };
 
 #ifdef CONFIG_CPUMASK_OFFSTACK
@@ -39,7 +39,7 @@ int show_interrupts(struct seq_file *p,
 	unsigned long flags;
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -53,7 +53,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
  skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "NMI: ");
 		for_each_online_cpu(j)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/kgdb.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/kgdb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,33 +6,9 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
 #include <linux/ptrace.h>		/* for linux pt_regs struct */
 #include <linux/kgdb.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
 #include <linux/uaccess.h>
-#include <asm/system.h>
-#include <asm/traps.h>
-#include <asm/blackfin.h>
-#include <asm/dma.h>
-
-/* Put the error code here just in case the user cares.  */
-int gdb_bfin_errcode;
-/* Likewise, the vector number here (since GDB only gets the signal
-   number through the usual means, and that's not very specific).  */
-int gdb_bfin_vector = -1;
-
-#if KGDB_MAX_NO_CPUS != 8
-#error change the definition of slavecpulocks
-#endif
 
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
@@ -157,7 +133,7 @@ void gdb_regs_to_pt_regs(unsigned long *
 	regs->lb1 = gdb_regs[BFIN_LB1];
 	regs->usp = gdb_regs[BFIN_USP];
 	regs->syscfg = gdb_regs[BFIN_SYSCFG];
-	regs->retx = gdb_regs[BFIN_PC];
+	regs->retx = gdb_regs[BFIN_RETX];
 	regs->retn = gdb_regs[BFIN_RETN];
 	regs->rete = gdb_regs[BFIN_RETE];
 	regs->pc = gdb_regs[BFIN_PC];
@@ -369,13 +345,6 @@ void kgdb_roundup_cpu(int cpu, unsigned
 }
 #endif
 
-void kgdb_post_primary_code(struct pt_regs *regs, int eVector, int err_code)
-{
-	/* Master processor is completely in the debugger */
-	gdb_bfin_vector = eVector;
-	gdb_bfin_errcode = err_code;
-}
-
 int kgdb_arch_handle_exception(int vector, int signo,
 			       int err_code, char *remcom_in_buffer,
 			       char *remcom_out_buffer,
@@ -441,182 +410,6 @@ struct kgdb_arch arch_kgdb_ops = {
 	.correct_hw_break = bfin_correct_hw_break,
 };
 
-static int hex(char ch)
-{
-	if ((ch >= 'a') && (ch <= 'f'))
-		return ch - 'a' + 10;
-	if ((ch >= '0') && (ch <= '9'))
-		return ch - '0';
-	if ((ch >= 'A') && (ch <= 'F'))
-		return ch - 'A' + 10;
-	return -1;
-}
-
-static int validate_memory_access_address(unsigned long addr, int size)
-{
-	if (size < 0 || addr == 0)
-		return -EFAULT;
-	return bfin_mem_access_type(addr, size);
-}
-
-static int bfin_probe_kernel_read(char *dst, char *src, int size)
-{
-	unsigned long lsrc = (unsigned long)src;
-	int mem_type;
-
-	mem_type = validate_memory_access_address(lsrc, size);
-	if (mem_type < 0)
-		return mem_type;
-
-	if (lsrc >= SYSMMR_BASE) {
-		if (size == 2 && lsrc % 2 == 0) {
-			u16 mmr = bfin_read16(src);
-			memcpy(dst, &mmr, sizeof(mmr));
-			return 0;
-		} else if (size == 4 && lsrc % 4 == 0) {
-			u32 mmr = bfin_read32(src);
-			memcpy(dst, &mmr, sizeof(mmr));
-			return 0;
-		}
-	} else {
-		switch (mem_type) {
-			case BFIN_MEM_ACCESS_CORE:
-			case BFIN_MEM_ACCESS_CORE_ONLY:
-				return probe_kernel_read(dst, src, size);
-			/* XXX: should support IDMA here with SMP */
-			case BFIN_MEM_ACCESS_DMA:
-				if (dma_memcpy(dst, src, size))
-					return 0;
-				break;
-			case BFIN_MEM_ACCESS_ITEST:
-				if (isram_memcpy(dst, src, size))
-					return 0;
-				break;
-		}
-	}
-
-	return -EFAULT;
-}
-
-static int bfin_probe_kernel_write(char *dst, char *src, int size)
-{
-	unsigned long ldst = (unsigned long)dst;
-	int mem_type;
-
-	mem_type = validate_memory_access_address(ldst, size);
-	if (mem_type < 0)
-		return mem_type;
-
-	if (ldst >= SYSMMR_BASE) {
-		if (size == 2 && ldst % 2 == 0) {
-			u16 mmr;
-			memcpy(&mmr, src, sizeof(mmr));
-			bfin_write16(dst, mmr);
-			return 0;
-		} else if (size == 4 && ldst % 4 == 0) {
-			u32 mmr;
-			memcpy(&mmr, src, sizeof(mmr));
-			bfin_write32(dst, mmr);
-			return 0;
-		}
-	} else {
-		switch (mem_type) {
-			case BFIN_MEM_ACCESS_CORE:
-			case BFIN_MEM_ACCESS_CORE_ONLY:
-				return probe_kernel_write(dst, src, size);
-			/* XXX: should support IDMA here with SMP */
-			case BFIN_MEM_ACCESS_DMA:
-				if (dma_memcpy(dst, src, size))
-					return 0;
-				break;
-			case BFIN_MEM_ACCESS_ITEST:
-				if (isram_memcpy(dst, src, size))
-					return 0;
-				break;
-		}
-	}
-
-	return -EFAULT;
-}
-
-/*
- * Convert the memory pointed to by mem into hex, placing result in buf.
- * Return a pointer to the last char put in buf (null). May return an error.
- */
-int kgdb_mem2hex(char *mem, char *buf, int count)
-{
-	char *tmp;
-	int err;
-
-	/*
-	 * We use the upper half of buf as an intermediate buffer for the
-	 * raw memory copy.  Hex conversion will work against this one.
-	 */
-	tmp = buf + count;
-
-	err = bfin_probe_kernel_read(tmp, mem, count);
-	if (!err) {
-		while (count > 0) {
-			buf = pack_hex_byte(buf, *tmp);
-			tmp++;
-			count--;
-		}
-
-		*buf = 0;
-	}
-
-	return err;
-}
-
-/*
- * Copy the binary array pointed to by buf into mem.  Fix $, #, and
- * 0x7d escaped with 0x7d.  Return a pointer to the character after
- * the last byte written.
- */
-int kgdb_ebin2mem(char *buf, char *mem, int count)
-{
-	char *tmp_old, *tmp_new;
-	int size;
-
-	tmp_old = tmp_new = buf;
-
-	for (size = 0; size < count; ++size) {
-		if (*tmp_old == 0x7d)
-			*tmp_new = *(++tmp_old) ^ 0x20;
-		else
-			*tmp_new = *tmp_old;
-		tmp_new++;
-		tmp_old++;
-	}
-
-	return bfin_probe_kernel_write(mem, buf, count);
-}
-
-/*
- * Convert the hex array pointed to by buf into binary to be placed in mem.
- * Return a pointer to the character AFTER the last byte written.
- * May return an error.
- */
-int kgdb_hex2mem(char *buf, char *mem, int count)
-{
-	char *tmp_raw, *tmp_hex;
-
-	/*
-	 * We use the upper half of buf as an intermediate buffer for the
-	 * raw memory that is converted from hex.
-	 */
-	tmp_raw = buf + count * 2;
-
-	tmp_hex = tmp_raw - 1;
-	while (tmp_hex >= buf) {
-		tmp_raw--;
-		*tmp_raw = hex(*tmp_hex--);
-		*tmp_raw |= hex(*tmp_hex--) << 4;
-	}
-
-	return bfin_probe_kernel_write(mem, tmp_raw, count);
-}
-
 #define IN_MEM(addr, size, l1_addr, l1_size) \
 ({ \
 	unsigned long __addr = (unsigned long)(addr); \
@@ -646,21 +439,6 @@ int kgdb_validate_break_address(unsigned
 	return -EFAULT;
 }
 
-int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
-{
-	int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
-	                                 BREAK_INSTR_SIZE);
-	if (err)
-		return err;
-	return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
-	                               BREAK_INSTR_SIZE);
-}
-
-int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
-{
-	return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
-}
-
 int kgdb_arch_init(void)
 {
 	kgdb_single_step = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/kgdb_test.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb_test.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/kgdb_test.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/kgdb_test.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,9 @@
 
 #include <asm/blackfin.h>
 
+/* Symbols are here for kgdb test to poke directly */
 static char cmdline[256];
-static unsigned long len;
+static size_t len;
 
 #ifndef CONFIG_SMP
 static int num1 __attribute__((l1_data));
@@ -27,11 +28,10 @@ void kgdb_l1_test(void) __attribute__((l
 
 void kgdb_l1_test(void)
 {
-	printk(KERN_ALERT "L1(before change) : data variable addr = 0x%p, data value is %d\n", &num1, num1);
-	printk(KERN_ALERT "L1 : code function addr = 0x%p\n", kgdb_l1_test);
-	num1 = num1 + 10 ;
-	printk(KERN_ALERT "L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1);
-	return ;
+	pr_alert("L1(before change) : data variable addr = 0x%p, data value is %d\n", &num1, num1);
+	pr_alert("L1 : code function addr = 0x%p\n", kgdb_l1_test);
+	num1 = num1 + 10;
+	pr_alert("L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1);
 }
 #endif
 
@@ -42,11 +42,10 @@ void kgdb_l2_test(void) __attribute__((l
 
 void kgdb_l2_test(void)
 {
-	printk(KERN_ALERT "L2(before change) : data variable addr = 0x%p, data value is %d\n", &num2, num2);
-	printk(KERN_ALERT "L2 : code function addr = 0x%p\n", kgdb_l2_test);
-	num2 = num2 + 20 ;
-	printk(KERN_ALERT "L2(after change) : data variable addr = 0x%p, data value is %d\n", &num2, num2);
-	return ;
+	pr_alert("L2(before change) : data variable addr = 0x%p, data value is %d\n", &num2, num2);
+	pr_alert("L2 : code function addr = 0x%p\n", kgdb_l2_test);
+	num2 = num2 + 20;
+	pr_alert("L2(after change) : data variable addr = 0x%p, data value is %d\n", &num2, num2);
 }
 
 #endif
@@ -54,12 +53,14 @@ void kgdb_l2_test(void)
 
 int kgdb_test(char *name, int len, int count, int z)
 {
-	printk(KERN_ALERT "kgdb name(%d): %s, %d, %d\n", len, name, count, z);
+	pr_alert("kgdb name(%d): %s, %d, %d\n", len, name, count, z);
 	count = z;
 	return count;
 }
 
-static int test_proc_output(char *buf)
+static ssize_t
+kgdb_test_proc_read(struct file *file, char __user *buf,
+                    size_t count, loff_t *ppos)
 {
 	kgdb_test("hello world!", 12, 0x55, 0x10);
 #ifndef CONFIG_SMP
@@ -72,49 +73,31 @@ static int test_proc_output(char *buf)
 	return 0;
 }
 
-static int test_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len;
-
-	len = test_proc_output(page);
-	if (len <= off+count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
-}
-
-static int test_write_proc(struct file *file, const char *buffer,
-				 unsigned long count, void *data)
+static ssize_t
+kgdb_test_proc_write(struct file *file, const char __user *buffer,
+                     size_t count, loff_t *pos)
 {
-	if (count >= 256)
-		len = 255;
-	else
-		len = count;
-
+	len = min_t(size_t, 255, count);
 	memcpy(cmdline, buffer, count);
 	cmdline[len] = 0;
 
 	return len;
 }
 
+static const struct file_operations kgdb_test_proc_fops = {
+	.owner = THIS_MODULE,
+	.read  = kgdb_test_proc_read,
+	.write = kgdb_test_proc_write,
+};
+
 static int __init kgdbtest_init(void)
 {
 	struct proc_dir_entry *entry;
 
-	entry = create_proc_entry("kgdbtest", 0, NULL);
+	entry = proc_create("kgdbtest", 0, NULL, &kgdb_test_proc_fops);
 	if (entry == NULL)
 		return -ENOMEM;
 
-	entry->read_proc = test_read_proc;
-	entry->write_proc = test_write_proc;
-	entry->data = NULL;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/process.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -215,22 +215,18 @@ copy_thread(unsigned long clone_flags,
 /*
  * sys_execve() executes a new program.
  */
-
 asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp)
 {
 	int error;
 	char *filename;
 	struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
- out:
-	unlock_kernel();
 	return error;
 }
 
@@ -262,9 +258,12 @@ void finish_atomic_sections (struct pt_r
 	int __user *up0 = (int __user *)regs->p0;
 
 	switch (regs->pc) {
+	default:
+		/* not in middle of an atomic step, so resume like normal */
+		return;
+
 	case ATOMIC_XCHG32 + 2:
 		put_user(regs->r1, up0);
-		regs->pc = ATOMIC_XCHG32 + 4;
 		break;
 
 	case ATOMIC_CAS32 + 2:
@@ -272,7 +271,6 @@ void finish_atomic_sections (struct pt_r
 		if (regs->r0 == regs->r1)
 	case ATOMIC_CAS32 + 6:
 			put_user(regs->r2, up0);
-		regs->pc = ATOMIC_CAS32 + 8;
 		break;
 
 	case ATOMIC_ADD32 + 2:
@@ -280,7 +278,6 @@ void finish_atomic_sections (struct pt_r
 		/* fall through */
 	case ATOMIC_ADD32 + 4:
 		put_user(regs->r0, up0);
-		regs->pc = ATOMIC_ADD32 + 6;
 		break;
 
 	case ATOMIC_SUB32 + 2:
@@ -288,7 +285,6 @@ void finish_atomic_sections (struct pt_r
 		/* fall through */
 	case ATOMIC_SUB32 + 4:
 		put_user(regs->r0, up0);
-		regs->pc = ATOMIC_SUB32 + 6;
 		break;
 
 	case ATOMIC_IOR32 + 2:
@@ -296,7 +292,6 @@ void finish_atomic_sections (struct pt_r
 		/* fall through */
 	case ATOMIC_IOR32 + 4:
 		put_user(regs->r0, up0);
-		regs->pc = ATOMIC_IOR32 + 6;
 		break;
 
 	case ATOMIC_AND32 + 2:
@@ -304,7 +299,6 @@ void finish_atomic_sections (struct pt_r
 		/* fall through */
 	case ATOMIC_AND32 + 4:
 		put_user(regs->r0, up0);
-		regs->pc = ATOMIC_AND32 + 6;
 		break;
 
 	case ATOMIC_XOR32 + 2:
@@ -312,9 +306,15 @@ void finish_atomic_sections (struct pt_r
 		/* fall through */
 	case ATOMIC_XOR32 + 4:
 		put_user(regs->r0, up0);
-		regs->pc = ATOMIC_XOR32 + 6;
 		break;
 	}
+
+	/*
+	 * We've finished the atomic section, and the only thing left for
+	 * userspace is to do a RTS, so we might as well handle that too
+	 * since we need to update the PC anyways.
+	 */
+	regs->pc = regs->rets;
 }
 
 static inline
@@ -336,12 +336,58 @@ int in_mem_const(unsigned long addr, uns
 {
 	return in_mem_const_off(addr, size, 0, const_addr, const_size);
 }
-#define IN_ASYNC(bnum, bctlnum) \
+#define ASYNC_ENABLED(bnum, bctlnum) \
 ({ \
-	(bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? -EFAULT : \
-	bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? -EFAULT : \
-	BFIN_MEM_ACCESS_CORE; \
+	(bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \
+	bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \
+	1; \
 })
+/*
+ * We can't read EBIU banks that aren't enabled or we end up hanging
+ * on the access to the async space.  Make sure we validate accesses
+ * that cross async banks too.
+ *	0 - found, but unusable
+ *	1 - found & usable
+ *	2 - not found
+ */
+static
+int in_async(unsigned long addr, unsigned long size)
+{
+	if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) {
+		if (!ASYNC_ENABLED(0, 0))
+			return 0;
+		if (addr + size <= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)
+			return 1;
+		size -= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE - addr;
+		addr = ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE;
+	}
+	if (addr >= ASYNC_BANK1_BASE && addr < ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) {
+		if (!ASYNC_ENABLED(1, 0))
+			return 0;
+		if (addr + size <= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)
+			return 1;
+		size -= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE - addr;
+		addr = ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE;
+	}
+	if (addr >= ASYNC_BANK2_BASE && addr < ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) {
+		if (!ASYNC_ENABLED(2, 1))
+			return 0;
+		if (addr + size <= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE)
+			return 1;
+		size -= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE - addr;
+		addr = ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE;
+	}
+	if (addr >= ASYNC_BANK3_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
+		if (ASYNC_ENABLED(3, 1))
+			return 0;
+		if (addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)
+			return 1;
+		return 0;
+	}
+
+	/* not within async bounds */
+	return 2;
+}
 
 int bfin_mem_access_type(unsigned long addr, unsigned long size)
 {
@@ -378,17 +424,11 @@ int bfin_mem_access_type(unsigned long a
 	if (addr >= SYSMMR_BASE)
 		return BFIN_MEM_ACCESS_CORE_ONLY;
 
-	/* We can't read EBIU banks that aren't enabled or we end up hanging
-	 * on the access to the async space.
-	 */
-	if (in_mem_const(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK0_SIZE))
-		return IN_ASYNC(0, 0);
-	if (in_mem_const(addr, size, ASYNC_BANK1_BASE, ASYNC_BANK1_SIZE))
-		return IN_ASYNC(1, 0);
-	if (in_mem_const(addr, size, ASYNC_BANK2_BASE, ASYNC_BANK2_SIZE))
-		return IN_ASYNC(2, 1);
-	if (in_mem_const(addr, size, ASYNC_BANK3_BASE, ASYNC_BANK3_SIZE))
-		return IN_ASYNC(3, 1);
+	switch (in_async(addr, size)) {
+	case 0: return -EFAULT;
+	case 1: return BFIN_MEM_ACCESS_CORE;
+	case 2: /* fall through */;
+	}
 
 	if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH))
 		return BFIN_MEM_ACCESS_CORE;
@@ -405,6 +445,8 @@ __attribute__((l1_text))
 /* Return 1 if access to memory range is OK, 0 otherwise */
 int _access_ok(unsigned long addr, unsigned long size)
 {
+	int aret;
+
 	if (size == 0)
 		return 1;
 	/* Check that things do not wrap around */
@@ -454,6 +496,11 @@ int _access_ok(unsigned long addr, unsig
 	if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH))
 		return 1;
 #endif
+
+	aret = in_async(addr, size);
+	if (aret < 2)
+		return aret;
+
 	if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH))
 		return 1;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/ptrace.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ptrace.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/ptrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -316,19 +316,6 @@ long arch_ptrace(struct task_struct *chi
 			case BFIN_MEM_ACCESS_CORE_ONLY:
 				copied = access_process_vm(child, addr, &data,
 				                           to_copy, 1);
-				if (copied)
-					break;
-
-				/* hrm, why didn't that work ... maybe no mapping */
-				if (addr >= FIXED_CODE_START &&
-				    addr + to_copy <= FIXED_CODE_END) {
-					copy_to_user_page(0, 0, 0, paddr, &data, to_copy);
-					copied = to_copy;
-				} else if (addr >= BOOT_ROM_START) {
-					memcpy(paddr, &data, to_copy);
-					copied = to_copy;
-				}
-
 				break;
 			case BFIN_MEM_ACCESS_DMA:
 				if (safe_dma_memcpy(paddr, &data, to_copy))
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/setup.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -178,10 +178,10 @@ void __init bfin_cache_init(void)
 
 void __init bfin_relocate_l1_mem(void)
 {
-	unsigned long l1_code_length;
-	unsigned long l1_data_a_length;
-	unsigned long l1_data_b_length;
-	unsigned long l2_length;
+	unsigned long text_l1_len = (unsigned long)_text_l1_len;
+	unsigned long data_l1_len = (unsigned long)_data_l1_len;
+	unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len;
+	unsigned long l2_len = (unsigned long)_l2_len;
 
 	early_shadow_stamp();
 
@@ -201,30 +201,23 @@ void __init bfin_relocate_l1_mem(void)
 
 	blackfin_dma_early_init();
 
-	/* if necessary, copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
-	l1_code_length = _etext_l1 - _stext_l1;
-	if (l1_code_length)
-		early_dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
+	/* if necessary, copy L1 text to L1 instruction SRAM */
+	if (L1_CODE_LENGTH && text_l1_len)
+		early_dma_memcpy(_stext_l1, _text_l1_lma, text_l1_len);
 
-	/* if necessary, copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */
-	l1_data_a_length = _sbss_l1 - _sdata_l1;
-	if (l1_data_a_length)
-		early_dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
+	/* if necessary, copy L1 data to L1 data bank A SRAM */
+	if (L1_DATA_A_LENGTH && data_l1_len)
+		early_dma_memcpy(_sdata_l1, _data_l1_lma, data_l1_len);
 
-	/* if necessary, copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */
-	l1_data_b_length = _sbss_b_l1 - _sdata_b_l1;
-	if (l1_data_b_length)
-		early_dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
-			l1_data_a_length, l1_data_b_length);
+	/* if necessary, copy L1 data B to L1 data bank B SRAM */
+	if (L1_DATA_B_LENGTH && data_b_l1_len)
+		early_dma_memcpy(_sdata_b_l1, _data_b_l1_lma, data_b_l1_len);
 
 	early_dma_memcpy_done();
 
-	/* if necessary, copy _stext_l2 to _edata_l2 to L2 SRAM */
-	if (L2_LENGTH != 0) {
-		l2_length = _sbss_l2 - _stext_l2;
-		if (l2_length)
-			memcpy(_stext_l2, _l2_lma_start, l2_length);
-	}
+	/* if necessary, copy L2 text/data to L2 SRAM */
+	if (L2_LENGTH && l2_len)
+		memcpy(_stext_l2, _l2_lma, l2_len);
 }
 
 /* add_memory_region to memmap */
@@ -608,11 +601,6 @@ static __init void memory_setup(void)
 	page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
 #endif
 
-#if !defined(CONFIG_MTD_UCLINUX)
-	/*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
-	memory_end -= SIZE_4K;
-#endif
-
 	init_mm.start_code = (unsigned long)_stext;
 	init_mm.end_code = (unsigned long)_etext;
 	init_mm.end_data = (unsigned long)_edata;
@@ -917,7 +905,7 @@ void __init setup_arch(char **cmdline_p)
 
 	printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n");
 	if (bfin_compiled_revid() == 0xffff)
-		printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU);
+		printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid());
 	else if (bfin_compiled_revid() == -1)
 		printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU);
 	else
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/signal.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #include <linux/binfmts.h>
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
+#include <linux/tracehook.h>
 
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
@@ -332,3 +333,20 @@ asmlinkage void do_signal(struct pt_regs
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 }
+
+/*
+ * notification of userspace execution resumption
+ */
+asmlinkage void do_notify_resume(struct pt_regs *regs)
+{
+	if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK))
+		do_signal(regs);
+
+	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+		if (current->replacement_session_keyring)
+			key_replace_session_keyring();
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/sys_bfin.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/sys_bfin.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/sys_bfin.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/sys_bfin.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,39 +22,6 @@
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 
-/* common code for old and new mmaps */
-static inline long
-do_mmap2(unsigned long addr, unsigned long len,
-	 unsigned long prot, unsigned long flags,
-	 unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
- out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
 {
 	return sram_alloc_with_lsl(size, flags);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/time.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -184,11 +184,3 @@ void __init time_init(void)
 
 	time_sched_init(timer_interrupt);
 }
-
-/*
- * Scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
-	return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ);
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/time-ts.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time-ts.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/time-ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/time-ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,8 +22,6 @@
 #include <asm/time.h>
 #include <asm/gptimers.h>
 
-#if defined(CONFIG_CYCLES_CLOCKSOURCE)
-
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
@@ -46,20 +44,11 @@
  *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
  */
 
-static unsigned long cyc2ns_scale;
 #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
 
-static inline void set_cyc2ns_scale(unsigned long cpu_khz)
-{
-	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz;
-}
-
-static inline unsigned long long cycles_2_ns(cycle_t cyc)
-{
-	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
-}
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
 
-static cycle_t bfin_read_cycles(struct clocksource *cs)
+static notrace cycle_t bfin_read_cycles(struct clocksource *cs)
 {
 	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 }
@@ -69,19 +58,18 @@ static struct clocksource bfin_cs_cycles
 	.rating		= 400,
 	.read		= bfin_read_cycles,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.shift		= 22,
+	.shift		= CYC2NS_SCALE_FACTOR,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-unsigned long long sched_clock(void)
+static inline unsigned long long bfin_cs_cycles_sched_clock(void)
 {
-	return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles));
+	return clocksource_cyc2ns(bfin_read_cycles(&bfin_cs_cycles),
+		bfin_cs_cycles.mult, bfin_cs_cycles.shift);
 }
 
 static int __init bfin_cs_cycles_init(void)
 {
-	set_cyc2ns_scale(get_cclk() / 1000);
-
 	bfin_cs_cycles.mult = \
 		clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
 
@@ -108,7 +96,7 @@ void __init setup_gptimer0(void)
 	enable_gptimers(TIMER0bit);
 }
 
-static cycle_t bfin_read_gptimer0(void)
+static cycle_t bfin_read_gptimer0(struct clocksource *cs)
 {
 	return bfin_read_TIMER0_COUNTER();
 }
@@ -118,10 +106,16 @@ static struct clocksource bfin_cs_gptime
 	.rating		= 350,
 	.read		= bfin_read_gptimer0,
 	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= 22,
+	.shift		= CYC2NS_SCALE_FACTOR,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static inline unsigned long long bfin_cs_gptimer0_sched_clock(void)
+{
+	return clocksource_cyc2ns(bfin_read_TIMER0_COUNTER(),
+		bfin_cs_gptimer0.mult, bfin_cs_gptimer0.shift);
+}
+
 static int __init bfin_cs_gptimer0_init(void)
 {
 	setup_gptimer0();
@@ -138,6 +132,19 @@ static int __init bfin_cs_gptimer0_init(
 # define bfin_cs_gptimer0_init()
 #endif
 
+
+#if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
+/* prefer to use cycles since it has higher rating */
+notrace unsigned long long sched_clock(void)
+{
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
+	return bfin_cs_cycles_sched_clock();
+#else
+	return bfin_cs_gptimer0_sched_clock();
+#endif
+}
+#endif
+
 #ifdef CONFIG_CORE_TIMER_IRQ_L1
 __attribute__((l1_text))
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/traps.c linux-libre-2.6.33-gnu1/arch/blackfin/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -119,6 +119,15 @@ static void decode_address(char *buf, un
 		return;
 	}
 
+	/*
+	 * Don't walk any of the vmas if we are oopsing, it has been known
+	 * to cause problems - corrupt vmas (kernel crashes) cause double faults
+	 */
+	if (oops_in_progress) {
+		strcat(buf, "/* kernel dynamic memory (maybe user-space) */");
+		return;
+	}
+
 	/* looks like we're off in user-land, so let's walk all the
 	 * mappings of all our processes and see if we can't be a whee
 	 * bit more specific
@@ -515,6 +524,36 @@ asmlinkage notrace void trap_c(struct pt
 			break;
 		/* External Memory Addressing Error */
 		case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
+			if (ANOMALY_05000310) {
+				static unsigned long anomaly_rets;
+
+				if ((fp->pc >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
+				    (fp->pc < (L1_CODE_START + L1_CODE_LENGTH))) {
+					/*
+					 * A false hardware error will happen while fetching at
+					 * the L1 instruction SRAM boundary.  Ignore it.
+					 */
+					anomaly_rets = fp->rets;
+					goto traps_done;
+				} else if (fp->rets == anomaly_rets) {
+					/*
+					 * While boundary code returns to a function, at the ret
+					 * point, a new false hardware error might occur too based
+					 * on tests.  Ignore it too.
+					 */
+					goto traps_done;
+				} else if ((fp->rets >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
+				           (fp->rets < (L1_CODE_START + L1_CODE_LENGTH))) {
+					/*
+					 * If boundary code calls a function, at the entry point,
+					 * a new false hardware error maybe happen based on tests.
+					 * Ignore it too.
+					 */
+					goto traps_done;
+				} else
+					anomaly_rets = 0;
+			}
+
 			info.si_code = BUS_ADRERR;
 			sig = SIGBUS;
 			strerror = KERN_NOTICE HWC_x3(KERN_NOTICE);
@@ -619,7 +658,7 @@ asmlinkage notrace void trap_c(struct pt
 
 /*
  * Similar to get_user, do some address checking, then dereference
- * Return true on sucess, false on bad address
+ * Return true on success, false on bad address
  */
 static bool get_instruction(unsigned short *val, unsigned short *address)
 {
@@ -976,12 +1015,12 @@ void dump_bfin_process(struct pt_regs *f
 	    !((unsigned long)current & 0x3) && current->pid) {
 		verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n");
 		if (current->comm >= (char *)FIXED_CODE_START)
-			verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n",
+			verbose_printk(KERN_NOTICE "COMM=%s PID=%d",
 				current->comm, current->pid);
 		else
-			verbose_printk(KERN_NOTICE "COMM= invalid\n");
+			verbose_printk(KERN_NOTICE "COMM= invalid");
 
-		printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu);
+		printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu);
 		if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START)
 			verbose_printk(KERN_NOTICE
 				"TEXT = 0x%p-0x%p        DATA = 0x%p-0x%p\n"
@@ -1140,7 +1179,7 @@ void show_regs(struct pt_regs *fp)
 	if (fp->ipend & ~0x3F) {
 		for (i = 0; i < (NR_IRQS - 1); i++) {
 			if (!in_atomic)
-				spin_lock_irqsave(&irq_desc[i].lock, flags);
+				raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 
 			action = irq_desc[i].action;
 			if (!action)
@@ -1155,7 +1194,7 @@ void show_regs(struct pt_regs *fp)
 			verbose_printk("\n");
 unlock:
 			if (!in_atomic)
-				spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+				raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 		}
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/blackfin/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -4,8 +4,6 @@
  * Licensed under the GPL-2 or later
  */
 
-#define VMLINUX_SYMBOL(_sym_) _##_sym_
-
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/mem_map.h>
 #include <asm/page.h>
@@ -123,8 +121,6 @@ SECTIONS
 		EXIT_DATA
 	}
 
-	__l1_lma_start = .;
-
 	.text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))
 	{
 		. = ALIGN(4);
@@ -136,9 +132,11 @@ SECTIONS
 		. = ALIGN(4);
 		__etext_l1 = .;
 	}
-	ASSERT (SIZEOF(.text_l1) <= L1_CODE_LENGTH, "L1 text overflow!")
+	__text_l1_lma = LOADADDR(.text_l1);
+	__text_l1_len = SIZEOF(.text_l1);
+	ASSERT (__text_l1_len <= L1_CODE_LENGTH, "L1 text overflow!")
 
-	.data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))
+	.data_l1 L1_DATA_A_START : AT(__text_l1_lma + __text_l1_len)
 	{
 		. = ALIGN(4);
 		__sdata_l1 = .;
@@ -154,9 +152,11 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l1 = .;
 	}
-	ASSERT (SIZEOF(.data_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
+	__data_l1_lma = LOADADDR(.data_l1);
+	__data_l1_len = SIZEOF(.data_l1);
+	ASSERT (__data_l1_len <= L1_DATA_A_LENGTH, "L1 data A overflow!")
 
-	.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
+	.data_b_l1 L1_DATA_B_START : AT(__data_l1_lma + __data_l1_len)
 	{
 		. = ALIGN(4);
 		__sdata_b_l1 = .;
@@ -169,11 +169,11 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_b_l1 = .;
 	}
-	ASSERT (SIZEOF(.data_b_l1) <= L1_DATA_B_LENGTH, "L1 data B overflow!")
-
-	__l2_lma_start = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
+	__data_b_l1_lma = LOADADDR(.data_b_l1);
+	__data_b_l1_len = SIZEOF(.data_b_l1);
+	ASSERT (__data_b_l1_len <= L1_DATA_B_LENGTH, "L1 data B overflow!")
 
-	.text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1))
+	.text_data_l2 L2_START : AT(__data_b_l1_lma + __data_b_l1_len)
 	{
 		. = ALIGN(4);
 		__stext_l2 = .;
@@ -195,12 +195,14 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l2 = .;
 	}
-	ASSERT (SIZEOF(.text_data_l2) <= L2_LENGTH, "L2 overflow!")
+	__l2_lma = LOADADDR(.text_data_l2);
+	__l2_len = SIZEOF(.text_data_l2);
+	ASSERT (__l2_len <= L2_LENGTH, "L2 overflow!")
 
 	/* Force trailing alignment of our init section so that when we
 	 * free our init memory, we don't leave behind a partial page.
 	 */
-	. = LOADADDR(.text_data_l2) + SIZEOF(.text_data_l2);
+	. = __l2_lma + __l2_len;
 	. = ALIGN(PAGE_SIZE);
 	___init_end = .;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/lib/checksum.c linux-libre-2.6.33-gnu1/arch/blackfin/lib/checksum.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/lib/checksum.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/lib/checksum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,125 +0,0 @@
-/*
- * Copyright 2004-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- *
- * An implementation of the TCP/IP protocol suite for the LINUX operating
- * system. INET is implemented using the BSD Socket interface as the
- * means of communication with the user level.
- *
- */
-
-#include <linux/module.h>
-#include <net/checksum.h>
-#include <asm/checksum.h>
-
-#ifdef CONFIG_IP_CHECKSUM_L1
-static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text));
-#endif
-
-static unsigned short do_csum(const unsigned char *buff, int len)
-{
-	register unsigned long sum = 0;
-	int swappem = 0;
-
-	if (1 & (unsigned long)buff) {
-		sum = *buff << 8;
-		buff++;
-		len--;
-		++swappem;
-	}
-
-	while (len > 1) {
-		sum += *(unsigned short *)buff;
-		buff += 2;
-		len -= 2;
-	}
-
-	if (len > 0)
-		sum += *buff;
-
-	/*  Fold 32-bit sum to 16 bits */
-	while (sum >> 16)
-		sum = (sum & 0xffff) + (sum >> 16);
-
-	if (swappem)
-		sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8);
-
-	return sum;
-
-}
-
-/*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- */
-__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl)
-{
-	return (__force __sum16)~do_csum(iph, ihl * 4);
-}
-EXPORT_SYMBOL(ip_fast_csum);
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum)
-{
-	/*
-	 * Just in case we get nasty checksum data...
-	 * Like 0xffff6ec3 in the case of our IPv6 multicast header.
-	 * We fold to begin with, as well as at the end.
-	 */
-	sum = (sum & 0xffff) + (sum >> 16);
-
-	sum += do_csum(buff, len);
-
-	sum = (sum & 0xffff) + (sum >> 16);
-
-	return sum;
-}
-EXPORT_SYMBOL(csum_partial);
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum(const void *buff, int len)
-{
-	return (__force __sum16)~do_csum(buff, len);
-}
-EXPORT_SYMBOL(ip_compute_csum);
-
-/*
- * copy from fs while checksumming, otherwise like csum_partial
- */
-
-__wsum
-csum_partial_copy_from_user(const void __user *src, void *dst,
-			    int len, __wsum sum, int *csum_err)
-{
-	if (csum_err)
-		*csum_err = 0;
-	memcpy(dst, (__force void *)src, len);
-	return csum_partial(dst, len, sum);
-}
-EXPORT_SYMBOL(csum_partial_copy_from_user);
-
-/*
- * copy from ds while checksumming, otherwise like csum_partial
- */
-
-__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
-{
-	memcpy(dst, src, len);
-	return csum_partial(dst, len, sum);
-}
-EXPORT_SYMBOL(csum_partial_copy);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/lib/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/lib/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/lib/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,7 @@
 lib-y := \
 	ashldi3.o ashrdi3.o lshrdi3.o \
 	muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
-	checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
+	memcpy.o memset.o memcmp.o memchr.o memmove.o \
 	strcmp.o strcpy.o strncmp.o strncpy.o \
 	umulsi3_highpart.o smulsi3_highpart.o \
 	ins.o outs.o
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,10 +58,4 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* PLL_DIV Masks													*/
-#define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
-#define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
-#define CCLK_DIV4 CSEL_DIV4	/*          CCLK = VCO / 4                                  */
-#define CCLK_DIV8 CSEL_DIV8	/*          CCLK = VCO / 8                                  */
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
  */
 
 #ifndef _CDEF_BF514_H
@@ -10,15 +10,8 @@
 /* include all Core registers and bit definitions */
 #include "defBF514.h"
 
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF514 */
-
-/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "cdefBF51x_base.h"
-
-/* The following are the #defines needed by ADSP-BF514 that are not in the common header */
+/* BF514 is BF512 + RSI */
+#include "cdefBF512.h"
 
 /* Removable Storage Interface Registers */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
  */
 
 #ifndef _CDEF_BF516_H
@@ -10,15 +10,8 @@
 /* include all Core registers and bit definitions */
 #include "defBF516.h"
 
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF516 */
-
-/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "cdefBF51x_base.h"
-
-/* The following are the #defines needed by ADSP-BF516 that are not in the common header */
+/* BF516 is BF514 + EMAC */
+#include "cdefBF514.h"
 
 /* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
 
@@ -185,71 +178,4 @@
 #define bfin_read_EMAC_TXC_ABORT()		bfin_read32(EMAC_TXC_ABORT)
 #define bfin_write_EMAC_TXC_ABORT(val)		bfin_write32(EMAC_TXC_ABORT, val)
 
-/* Removable Storage Interface Registers */
-
-#define bfin_read_RSI_PWR_CTL()        bfin_read16(RSI_PWR_CONTROL)
-#define bfin_write_RSI_PWR_CTL(val)    bfin_write16(RSI_PWR_CONTROL, val)
-#define bfin_read_RSI_CLK_CTL()	       bfin_read16(RSI_CLK_CONTROL)
-#define bfin_write_RSI_CLK_CTL(val)    bfin_write16(RSI_CLK_CONTROL, val)
-#define bfin_read_RSI_ARGUMENT()       bfin_read32(RSI_ARGUMENT)
-#define bfin_write_RSI_ARGUMENT(val)   bfin_write32(RSI_ARGUMENT, val)
-#define bfin_read_RSI_COMMAND()        bfin_read16(RSI_COMMAND)
-#define bfin_write_RSI_COMMAND(val)    bfin_write16(RSI_COMMAND, val)
-#define bfin_read_RSI_RESP_CMD()       bfin_read16(RSI_RESP_CMD)
-#define bfin_write_RSI_RESP_CMD(val)   bfin_write16(RSI_RESP_CMD, val)
-#define bfin_read_RSI_RESPONSE0()      bfin_read32(RSI_RESPONSE0)
-#define bfin_write_RSI_RESPONSE0(val)  bfin_write32(RSI_RESPONSE0, val)
-#define bfin_read_RSI_RESPONSE1()      bfin_read32(RSI_RESPONSE1)
-#define bfin_write_RSI_RESPONSE1(val)  bfin_write32(RSI_RESPONSE1, val)
-#define bfin_read_RSI_RESPONSE2()      bfin_read32(RSI_RESPONSE2)
-#define bfin_write_RSI_RESPONSE2(val)  bfin_write32(RSI_RESPONSE2, val)
-#define bfin_read_RSI_RESPONSE3()      bfin_read32(RSI_RESPONSE3)
-#define bfin_write_RSI_RESPONSE3(val)  bfin_write32(RSI_RESPONSE3, val)
-#define bfin_read_RSI_DATA_TIMER()     bfin_read32(RSI_DATA_TIMER)
-#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val)
-#define bfin_read_RSI_DATA_LGTH()      bfin_read16(RSI_DATA_LGTH)
-#define bfin_write_RSI_DATA_LGTH(val)  bfin_write16(RSI_DATA_LGTH, val)
-#define bfin_read_RSI_DATA_CTL()       bfin_read16(RSI_DATA_CONTROL)
-#define bfin_write_RSI_DATA_CTL(val)   bfin_write16(RSI_DATA_CONTROL, val)
-#define bfin_read_RSI_DATA_CNT()       bfin_read16(RSI_DATA_CNT)
-#define bfin_write_RSI_DATA_CNT(val)   bfin_write16(RSI_DATA_CNT, val)
-#define bfin_read_RSI_STATUS()         bfin_read32(RSI_STATUS)
-#define bfin_write_RSI_STATUS(val)     bfin_write32(RSI_STATUS, val)
-#define bfin_read_RSI_STATUS_CLR()     bfin_read16(RSI_STATUSCL)
-#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val)
-#define bfin_read_RSI_MASK0()          bfin_read32(RSI_MASK0)
-#define bfin_write_RSI_MASK0(val)      bfin_write32(RSI_MASK0, val)
-#define bfin_read_RSI_MASK1()          bfin_read32(RSI_MASK1)
-#define bfin_write_RSI_MASK1(val)      bfin_write32(RSI_MASK1, val)
-#define bfin_read_RSI_FIFO_CNT()       bfin_read16(RSI_FIFO_CNT)
-#define bfin_write_RSI_FIFO_CNT(val)   bfin_write16(RSI_FIFO_CNT, val)
-#define bfin_read_RSI_CEATA_CTL()      bfin_read16(RSI_CEATA_CONTROL)
-#define bfin_write_RSI_CEATA_CTL(val)  bfin_write16(RSI_CEATA_CONTROL, val)
-#define bfin_read_RSI_FIFO()           bfin_read32(RSI_FIFO)
-#define bfin_write_RSI_FIFO(val)       bfin_write32(RSI_FIFO, val)
-#define bfin_read_RSI_E_STATUS()       bfin_read16(RSI_ESTAT)
-#define bfin_write_RSI_E_STATUS(val)   bfin_write16(RSI_ESTAT, val)
-#define bfin_read_RSI_E_MASK()         bfin_read16(RSI_EMASK)
-#define bfin_write_RSI_E_MASK(val)     bfin_write16(RSI_EMASK, val)
-#define bfin_read_RSI_CFG()            bfin_read16(RSI_CONFIG)
-#define bfin_write_RSI_CFG(val)        bfin_write16(RSI_CONFIG, val)
-#define bfin_read_RSI_RD_WAIT_EN()     bfin_read16(RSI_RD_WAIT_EN)
-#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val)
-#define bfin_read_RSI_PID0()           bfin_read16(RSI_PID0)
-#define bfin_write_RSI_PID0(val)       bfin_write16(RSI_PID0, val)
-#define bfin_read_RSI_PID1()           bfin_read16(RSI_PID1)
-#define bfin_write_RSI_PID1(val)       bfin_write16(RSI_PID1, val)
-#define bfin_read_RSI_PID2()           bfin_read16(RSI_PID2)
-#define bfin_write_RSI_PID2(val)       bfin_write16(RSI_PID2, val)
-#define bfin_read_RSI_PID3()           bfin_read16(RSI_PID3)
-#define bfin_write_RSI_PID3(val)       bfin_write16(RSI_PID3, val)
-#define bfin_read_RSI_PID4()           bfin_read16(RSI_PID4)
-#define bfin_write_RSI_PID4(val)       bfin_write16(RSI_PID4, val)
-#define bfin_read_RSI_PID5()           bfin_read16(RSI_PID5)
-#define bfin_write_RSI_PID5(val)       bfin_write16(RSI_PID5, val)
-#define bfin_read_RSI_PID6()           bfin_read16(RSI_PID6)
-#define bfin_write_RSI_PID6(val)       bfin_write16(RSI_PID6, val)
-#define bfin_read_RSI_PID7()           bfin_read16(RSI_PID7)
-#define bfin_write_RSI_PID7(val)       bfin_write16(RSI_PID7, val)
-
 #endif /* _CDEF_BF516_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF518.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF518.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF518.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
  */
 
 #ifndef _CDEF_BF518_H
@@ -10,181 +10,10 @@
 /* include all Core registers and bit definitions */
 #include "defBF518.h"
 
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF518 */
-
-/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "cdefBF51x_base.h"
-
-/* The following are the #defines needed by ADSP-BF518 that are not in the common header */
-
-
-/* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
-
-#define bfin_read_EMAC_OPMODE()			bfin_read32(EMAC_OPMODE)
-#define bfin_write_EMAC_OPMODE(val)		bfin_write32(EMAC_OPMODE, val)
-#define bfin_read_EMAC_ADDRLO()			bfin_read32(EMAC_ADDRLO)
-#define bfin_write_EMAC_ADDRLO(val)		bfin_write32(EMAC_ADDRLO, val)
-#define bfin_read_EMAC_ADDRHI()			bfin_read32(EMAC_ADDRHI)
-#define bfin_write_EMAC_ADDRHI(val)		bfin_write32(EMAC_ADDRHI, val)
-#define bfin_read_EMAC_HASHLO()			bfin_read32(EMAC_HASHLO)
-#define bfin_write_EMAC_HASHLO(val)		bfin_write32(EMAC_HASHLO, val)
-#define bfin_read_EMAC_HASHHI()			bfin_read32(EMAC_HASHHI)
-#define bfin_write_EMAC_HASHHI(val)		bfin_write32(EMAC_HASHHI, val)
-#define bfin_read_EMAC_STAADD()			bfin_read32(EMAC_STAADD)
-#define bfin_write_EMAC_STAADD(val)		bfin_write32(EMAC_STAADD, val)
-#define bfin_read_EMAC_STADAT()			bfin_read32(EMAC_STADAT)
-#define bfin_write_EMAC_STADAT(val)		bfin_write32(EMAC_STADAT, val)
-#define bfin_read_EMAC_FLC()			bfin_read32(EMAC_FLC)
-#define bfin_write_EMAC_FLC(val)		bfin_write32(EMAC_FLC, val)
-#define bfin_read_EMAC_VLAN1()			bfin_read32(EMAC_VLAN1)
-#define bfin_write_EMAC_VLAN1(val)		bfin_write32(EMAC_VLAN1, val)
-#define bfin_read_EMAC_VLAN2()			bfin_read32(EMAC_VLAN2)
-#define bfin_write_EMAC_VLAN2(val)		bfin_write32(EMAC_VLAN2, val)
-#define bfin_read_EMAC_WKUP_CTL()		bfin_read32(EMAC_WKUP_CTL)
-#define bfin_write_EMAC_WKUP_CTL(val)		bfin_write32(EMAC_WKUP_CTL, val)
-#define bfin_read_EMAC_WKUP_FFMSK0()		bfin_read32(EMAC_WKUP_FFMSK0)
-#define bfin_write_EMAC_WKUP_FFMSK0(val)	bfin_write32(EMAC_WKUP_FFMSK0, val)
-#define bfin_read_EMAC_WKUP_FFMSK1()		bfin_read32(EMAC_WKUP_FFMSK1)
-#define bfin_write_EMAC_WKUP_FFMSK1(val)	bfin_write32(EMAC_WKUP_FFMSK1, val)
-#define bfin_read_EMAC_WKUP_FFMSK2()		bfin_read32(EMAC_WKUP_FFMSK2)
-#define bfin_write_EMAC_WKUP_FFMSK2(val)	bfin_write32(EMAC_WKUP_FFMSK2, val)
-#define bfin_read_EMAC_WKUP_FFMSK3()		bfin_read32(EMAC_WKUP_FFMSK3)
-#define bfin_write_EMAC_WKUP_FFMSK3(val)	bfin_write32(EMAC_WKUP_FFMSK3, val)
-#define bfin_read_EMAC_WKUP_FFCMD()		bfin_read32(EMAC_WKUP_FFCMD)
-#define bfin_write_EMAC_WKUP_FFCMD(val)		bfin_write32(EMAC_WKUP_FFCMD, val)
-#define bfin_read_EMAC_WKUP_FFOFF()		bfin_read32(EMAC_WKUP_FFOFF)
-#define bfin_write_EMAC_WKUP_FFOFF(val)		bfin_write32(EMAC_WKUP_FFOFF, val)
-#define bfin_read_EMAC_WKUP_FFCRC0()		bfin_read32(EMAC_WKUP_FFCRC0)
-#define bfin_write_EMAC_WKUP_FFCRC0(val)	bfin_write32(EMAC_WKUP_FFCRC0, val)
-#define bfin_read_EMAC_WKUP_FFCRC1()		bfin_read32(EMAC_WKUP_FFCRC1)
-#define bfin_write_EMAC_WKUP_FFCRC1(val)	bfin_write32(EMAC_WKUP_FFCRC1, val)
-
-#define bfin_read_EMAC_SYSCTL()			bfin_read32(EMAC_SYSCTL)
-#define bfin_write_EMAC_SYSCTL(val)		bfin_write32(EMAC_SYSCTL, val)
-#define bfin_read_EMAC_SYSTAT()			bfin_read32(EMAC_SYSTAT)
-#define bfin_write_EMAC_SYSTAT(val)		bfin_write32(EMAC_SYSTAT, val)
-#define bfin_read_EMAC_RX_STAT()		bfin_read32(EMAC_RX_STAT)
-#define bfin_write_EMAC_RX_STAT(val)		bfin_write32(EMAC_RX_STAT, val)
-#define bfin_read_EMAC_RX_STKY()		bfin_read32(EMAC_RX_STKY)
-#define bfin_write_EMAC_RX_STKY(val)		bfin_write32(EMAC_RX_STKY, val)
-#define bfin_read_EMAC_RX_IRQE()		bfin_read32(EMAC_RX_IRQE)
-#define bfin_write_EMAC_RX_IRQE(val)		bfin_write32(EMAC_RX_IRQE, val)
-#define bfin_read_EMAC_TX_STAT()		bfin_read32(EMAC_TX_STAT)
-#define bfin_write_EMAC_TX_STAT(val)		bfin_write32(EMAC_TX_STAT, val)
-#define bfin_read_EMAC_TX_STKY()		bfin_read32(EMAC_TX_STKY)
-#define bfin_write_EMAC_TX_STKY(val)		bfin_write32(EMAC_TX_STKY, val)
-#define bfin_read_EMAC_TX_IRQE()		bfin_read32(EMAC_TX_IRQE)
-#define bfin_write_EMAC_TX_IRQE(val)		bfin_write32(EMAC_TX_IRQE, val)
-
-#define bfin_read_EMAC_MMC_CTL()		bfin_read32(EMAC_MMC_CTL)
-#define bfin_write_EMAC_MMC_CTL(val)		bfin_write32(EMAC_MMC_CTL, val)
-#define bfin_read_EMAC_MMC_RIRQS()		bfin_read32(EMAC_MMC_RIRQS)
-#define bfin_write_EMAC_MMC_RIRQS(val)		bfin_write32(EMAC_MMC_RIRQS, val)
-#define bfin_read_EMAC_MMC_RIRQE()		bfin_read32(EMAC_MMC_RIRQE)
-#define bfin_write_EMAC_MMC_RIRQE(val)		bfin_write32(EMAC_MMC_RIRQE, val)
-#define bfin_read_EMAC_MMC_TIRQS()		bfin_read32(EMAC_MMC_TIRQS)
-#define bfin_write_EMAC_MMC_TIRQS(val)		bfin_write32(EMAC_MMC_TIRQS, val)
-#define bfin_read_EMAC_MMC_TIRQE()		bfin_read32(EMAC_MMC_TIRQE)
-#define bfin_write_EMAC_MMC_TIRQE(val)		bfin_write32(EMAC_MMC_TIRQE, val)
-
-#define bfin_read_EMAC_RXC_OK()			bfin_read32(EMAC_RXC_OK)
-#define bfin_write_EMAC_RXC_OK(val)		bfin_write32(EMAC_RXC_OK, val)
-#define bfin_read_EMAC_RXC_FCS()		bfin_read32(EMAC_RXC_FCS)
-#define bfin_write_EMAC_RXC_FCS(val)		bfin_write32(EMAC_RXC_FCS, val)
-#define bfin_read_EMAC_RXC_ALIGN()		bfin_read32(EMAC_RXC_ALIGN)
-#define bfin_write_EMAC_RXC_ALIGN(val)		bfin_write32(EMAC_RXC_ALIGN, val)
-#define bfin_read_EMAC_RXC_OCTET()		bfin_read32(EMAC_RXC_OCTET)
-#define bfin_write_EMAC_RXC_OCTET(val)		bfin_write32(EMAC_RXC_OCTET, val)
-#define bfin_read_EMAC_RXC_DMAOVF()		bfin_read32(EMAC_RXC_DMAOVF)
-#define bfin_write_EMAC_RXC_DMAOVF(val)		bfin_write32(EMAC_RXC_DMAOVF, val)
-#define bfin_read_EMAC_RXC_UNICST()		bfin_read32(EMAC_RXC_UNICST)
-#define bfin_write_EMAC_RXC_UNICST(val)		bfin_write32(EMAC_RXC_UNICST, val)
-#define bfin_read_EMAC_RXC_MULTI()		bfin_read32(EMAC_RXC_MULTI)
-#define bfin_write_EMAC_RXC_MULTI(val)		bfin_write32(EMAC_RXC_MULTI, val)
-#define bfin_read_EMAC_RXC_BROAD()		bfin_read32(EMAC_RXC_BROAD)
-#define bfin_write_EMAC_RXC_BROAD(val)		bfin_write32(EMAC_RXC_BROAD, val)
-#define bfin_read_EMAC_RXC_LNERRI()		bfin_read32(EMAC_RXC_LNERRI)
-#define bfin_write_EMAC_RXC_LNERRI(val)		bfin_write32(EMAC_RXC_LNERRI, val)
-#define bfin_read_EMAC_RXC_LNERRO()		bfin_read32(EMAC_RXC_LNERRO)
-#define bfin_write_EMAC_RXC_LNERRO(val)		bfin_write32(EMAC_RXC_LNERRO, val)
-#define bfin_read_EMAC_RXC_LONG()		bfin_read32(EMAC_RXC_LONG)
-#define bfin_write_EMAC_RXC_LONG(val)		bfin_write32(EMAC_RXC_LONG, val)
-#define bfin_read_EMAC_RXC_MACCTL()		bfin_read32(EMAC_RXC_MACCTL)
-#define bfin_write_EMAC_RXC_MACCTL(val)		bfin_write32(EMAC_RXC_MACCTL, val)
-#define bfin_read_EMAC_RXC_OPCODE()		bfin_read32(EMAC_RXC_OPCODE)
-#define bfin_write_EMAC_RXC_OPCODE(val)		bfin_write32(EMAC_RXC_OPCODE, val)
-#define bfin_read_EMAC_RXC_PAUSE()		bfin_read32(EMAC_RXC_PAUSE)
-#define bfin_write_EMAC_RXC_PAUSE(val)		bfin_write32(EMAC_RXC_PAUSE, val)
-#define bfin_read_EMAC_RXC_ALLFRM()		bfin_read32(EMAC_RXC_ALLFRM)
-#define bfin_write_EMAC_RXC_ALLFRM(val)		bfin_write32(EMAC_RXC_ALLFRM, val)
-#define bfin_read_EMAC_RXC_ALLOCT()		bfin_read32(EMAC_RXC_ALLOCT)
-#define bfin_write_EMAC_RXC_ALLOCT(val)		bfin_write32(EMAC_RXC_ALLOCT, val)
-#define bfin_read_EMAC_RXC_TYPED()		bfin_read32(EMAC_RXC_TYPED)
-#define bfin_write_EMAC_RXC_TYPED(val)		bfin_write32(EMAC_RXC_TYPED, val)
-#define bfin_read_EMAC_RXC_SHORT()		bfin_read32(EMAC_RXC_SHORT)
-#define bfin_write_EMAC_RXC_SHORT(val)		bfin_write32(EMAC_RXC_SHORT, val)
-#define bfin_read_EMAC_RXC_EQ64()		bfin_read32(EMAC_RXC_EQ64)
-#define bfin_write_EMAC_RXC_EQ64(val)		bfin_write32(EMAC_RXC_EQ64, val)
-#define bfin_read_EMAC_RXC_LT128()		bfin_read32(EMAC_RXC_LT128)
-#define bfin_write_EMAC_RXC_LT128(val)		bfin_write32(EMAC_RXC_LT128, val)
-#define bfin_read_EMAC_RXC_LT256()		bfin_read32(EMAC_RXC_LT256)
-#define bfin_write_EMAC_RXC_LT256(val)		bfin_write32(EMAC_RXC_LT256, val)
-#define bfin_read_EMAC_RXC_LT512()		bfin_read32(EMAC_RXC_LT512)
-#define bfin_write_EMAC_RXC_LT512(val)		bfin_write32(EMAC_RXC_LT512, val)
-#define bfin_read_EMAC_RXC_LT1024()		bfin_read32(EMAC_RXC_LT1024)
-#define bfin_write_EMAC_RXC_LT1024(val)		bfin_write32(EMAC_RXC_LT1024, val)
-#define bfin_read_EMAC_RXC_GE1024()		bfin_read32(EMAC_RXC_GE1024)
-#define bfin_write_EMAC_RXC_GE1024(val)		bfin_write32(EMAC_RXC_GE1024, val)
+/* BF518 is BF516 + IEEE-1588 */
+#include "cdefBF516.h"
 
-#define bfin_read_EMAC_TXC_OK()			bfin_read32(EMAC_TXC_OK)
-#define bfin_write_EMAC_TXC_OK(val)		bfin_write32(EMAC_TXC_OK, val)
-#define bfin_read_EMAC_TXC_1COL()		bfin_read32(EMAC_TXC_1COL)
-#define bfin_write_EMAC_TXC_1COL(val)		bfin_write32(EMAC_TXC_1COL, val)
-#define bfin_read_EMAC_TXC_GT1COL()		bfin_read32(EMAC_TXC_GT1COL)
-#define bfin_write_EMAC_TXC_GT1COL(val)		bfin_write32(EMAC_TXC_GT1COL, val)
-#define bfin_read_EMAC_TXC_OCTET()		bfin_read32(EMAC_TXC_OCTET)
-#define bfin_write_EMAC_TXC_OCTET(val)		bfin_write32(EMAC_TXC_OCTET, val)
-#define bfin_read_EMAC_TXC_DEFER()		bfin_read32(EMAC_TXC_DEFER)
-#define bfin_write_EMAC_TXC_DEFER(val)		bfin_write32(EMAC_TXC_DEFER, val)
-#define bfin_read_EMAC_TXC_LATECL()		bfin_read32(EMAC_TXC_LATECL)
-#define bfin_write_EMAC_TXC_LATECL(val)		bfin_write32(EMAC_TXC_LATECL, val)
-#define bfin_read_EMAC_TXC_XS_COL()		bfin_read32(EMAC_TXC_XS_COL)
-#define bfin_write_EMAC_TXC_XS_COL(val)		bfin_write32(EMAC_TXC_XS_COL, val)
-#define bfin_read_EMAC_TXC_DMAUND()		bfin_read32(EMAC_TXC_DMAUND)
-#define bfin_write_EMAC_TXC_DMAUND(val)		bfin_write32(EMAC_TXC_DMAUND, val)
-#define bfin_read_EMAC_TXC_CRSERR()		bfin_read32(EMAC_TXC_CRSERR)
-#define bfin_write_EMAC_TXC_CRSERR(val)		bfin_write32(EMAC_TXC_CRSERR, val)
-#define bfin_read_EMAC_TXC_UNICST()		bfin_read32(EMAC_TXC_UNICST)
-#define bfin_write_EMAC_TXC_UNICST(val)		bfin_write32(EMAC_TXC_UNICST, val)
-#define bfin_read_EMAC_TXC_MULTI()		bfin_read32(EMAC_TXC_MULTI)
-#define bfin_write_EMAC_TXC_MULTI(val)		bfin_write32(EMAC_TXC_MULTI, val)
-#define bfin_read_EMAC_TXC_BROAD()		bfin_read32(EMAC_TXC_BROAD)
-#define bfin_write_EMAC_TXC_BROAD(val)		bfin_write32(EMAC_TXC_BROAD, val)
-#define bfin_read_EMAC_TXC_XS_DFR()		bfin_read32(EMAC_TXC_XS_DFR)
-#define bfin_write_EMAC_TXC_XS_DFR(val)		bfin_write32(EMAC_TXC_XS_DFR, val)
-#define bfin_read_EMAC_TXC_MACCTL()		bfin_read32(EMAC_TXC_MACCTL)
-#define bfin_write_EMAC_TXC_MACCTL(val)		bfin_write32(EMAC_TXC_MACCTL, val)
-#define bfin_read_EMAC_TXC_ALLFRM()		bfin_read32(EMAC_TXC_ALLFRM)
-#define bfin_write_EMAC_TXC_ALLFRM(val)		bfin_write32(EMAC_TXC_ALLFRM, val)
-#define bfin_read_EMAC_TXC_ALLOCT()		bfin_read32(EMAC_TXC_ALLOCT)
-#define bfin_write_EMAC_TXC_ALLOCT(val)		bfin_write32(EMAC_TXC_ALLOCT, val)
-#define bfin_read_EMAC_TXC_EQ64()		bfin_read32(EMAC_TXC_EQ64)
-#define bfin_write_EMAC_TXC_EQ64(val)		bfin_write32(EMAC_TXC_EQ64, val)
-#define bfin_read_EMAC_TXC_LT128()		bfin_read32(EMAC_TXC_LT128)
-#define bfin_write_EMAC_TXC_LT128(val)		bfin_write32(EMAC_TXC_LT128, val)
-#define bfin_read_EMAC_TXC_LT256()		bfin_read32(EMAC_TXC_LT256)
-#define bfin_write_EMAC_TXC_LT256(val)		bfin_write32(EMAC_TXC_LT256, val)
-#define bfin_read_EMAC_TXC_LT512()		bfin_read32(EMAC_TXC_LT512)
-#define bfin_write_EMAC_TXC_LT512(val)		bfin_write32(EMAC_TXC_LT512, val)
-#define bfin_read_EMAC_TXC_LT1024()		bfin_read32(EMAC_TXC_LT1024)
-#define bfin_write_EMAC_TXC_LT1024(val)		bfin_write32(EMAC_TXC_LT1024, val)
-#define bfin_read_EMAC_TXC_GE1024()		bfin_read32(EMAC_TXC_GE1024)
-#define bfin_write_EMAC_TXC_GE1024(val)		bfin_write32(EMAC_TXC_GE1024, val)
-#define bfin_read_EMAC_TXC_ABORT()		bfin_read32(EMAC_TXC_ABORT)
-#define bfin_write_EMAC_TXC_ABORT(val)		bfin_write32(EMAC_TXC_ABORT, val)
+/* PTP TSYNC Registers */
 
 #define bfin_read_EMAC_PTP_CTL()                bfin_read16(EMAC_PTP_CTL)
 #define bfin_write_EMAC_PTP_CTL(val)            bfin_write16(EMAC_PTP_CTL, val)
@@ -227,72 +56,4 @@
 #define bfin_read_EMAC_PTP_PPS_PERIOD()         bfin_read32(EMAC_PTP_PPS_PERIOD)
 #define bfin_write_EMAC_PTP_PPS_PERIOD(val)     bfin_write32(EMAC_PTP_PPS_PERIOD, val)
 
-/* Removable Storage Interface Registers */
-
-#define bfin_read_RSI_PWR_CTL()        bfin_read16(RSI_PWR_CONTROL)
-#define bfin_write_RSI_PWR_CTL(val)    bfin_write16(RSI_PWR_CONTROL, val)
-#define bfin_read_RSI_CLK_CTL()	       bfin_read16(RSI_CLK_CONTROL)
-#define bfin_write_RSI_CLK_CTL(val)    bfin_write16(RSI_CLK_CONTROL, val)
-#define bfin_read_RSI_ARGUMENT()       bfin_read32(RSI_ARGUMENT)
-#define bfin_write_RSI_ARGUMENT(val)   bfin_write32(RSI_ARGUMENT, val)
-#define bfin_read_RSI_COMMAND()        bfin_read16(RSI_COMMAND)
-#define bfin_write_RSI_COMMAND(val)    bfin_write16(RSI_COMMAND, val)
-#define bfin_read_RSI_RESP_CMD()       bfin_read16(RSI_RESP_CMD)
-#define bfin_write_RSI_RESP_CMD(val)   bfin_write16(RSI_RESP_CMD, val)
-#define bfin_read_RSI_RESPONSE0()      bfin_read32(RSI_RESPONSE0)
-#define bfin_write_RSI_RESPONSE0(val)  bfin_write32(RSI_RESPONSE0, val)
-#define bfin_read_RSI_RESPONSE1()      bfin_read32(RSI_RESPONSE1)
-#define bfin_write_RSI_RESPONSE1(val)  bfin_write32(RSI_RESPONSE1, val)
-#define bfin_read_RSI_RESPONSE2()      bfin_read32(RSI_RESPONSE2)
-#define bfin_write_RSI_RESPONSE2(val)  bfin_write32(RSI_RESPONSE2, val)
-#define bfin_read_RSI_RESPONSE3()      bfin_read32(RSI_RESPONSE3)
-#define bfin_write_RSI_RESPONSE3(val)  bfin_write32(RSI_RESPONSE3, val)
-#define bfin_read_RSI_DATA_TIMER()     bfin_read32(RSI_DATA_TIMER)
-#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val)
-#define bfin_read_RSI_DATA_LGTH()      bfin_read16(RSI_DATA_LGTH)
-#define bfin_write_RSI_DATA_LGTH(val)  bfin_write16(RSI_DATA_LGTH, val)
-#define bfin_read_RSI_DATA_CTL()       bfin_read16(RSI_DATA_CONTROL)
-#define bfin_write_RSI_DATA_CTL(val)   bfin_write16(RSI_DATA_CONTROL, val)
-#define bfin_read_RSI_DATA_CNT()       bfin_read16(RSI_DATA_CNT)
-#define bfin_write_RSI_DATA_CNT(val)   bfin_write16(RSI_DATA_CNT, val)
-#define bfin_read_RSI_STATUS()         bfin_read32(RSI_STATUS)
-#define bfin_write_RSI_STATUS(val)     bfin_write32(RSI_STATUS, val)
-#define bfin_read_RSI_STATUS_CLR()     bfin_read16(RSI_STATUSCL)
-#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val)
-#define bfin_read_RSI_MASK0()          bfin_read32(RSI_MASK0)
-#define bfin_write_RSI_MASK0(val)      bfin_write32(RSI_MASK0, val)
-#define bfin_read_RSI_MASK1()          bfin_read32(RSI_MASK1)
-#define bfin_write_RSI_MASK1(val)      bfin_write32(RSI_MASK1, val)
-#define bfin_read_RSI_FIFO_CNT()       bfin_read16(RSI_FIFO_CNT)
-#define bfin_write_RSI_FIFO_CNT(val)   bfin_write16(RSI_FIFO_CNT, val)
-#define bfin_read_RSI_CEATA_CTL()      bfin_read16(RSI_CEATA_CONTROL)
-#define bfin_write_RSI_CEATA_CTL(val)  bfin_write16(RSI_CEATA_CONTROL, val)
-#define bfin_read_RSI_FIFO()           bfin_read32(RSI_FIFO)
-#define bfin_write_RSI_FIFO(val)       bfin_write32(RSI_FIFO, val)
-#define bfin_read_RSI_E_STATUS()       bfin_read16(RSI_ESTAT)
-#define bfin_write_RSI_E_STATUS(val)   bfin_write16(RSI_ESTAT, val)
-#define bfin_read_RSI_E_MASK()         bfin_read16(RSI_EMASK)
-#define bfin_write_RSI_E_MASK(val)     bfin_write16(RSI_EMASK, val)
-#define bfin_read_RSI_CFG()            bfin_read16(RSI_CONFIG)
-#define bfin_write_RSI_CFG(val)        bfin_write16(RSI_CONFIG, val)
-#define bfin_read_RSI_RD_WAIT_EN()     bfin_read16(RSI_RD_WAIT_EN)
-#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val)
-#define bfin_read_RSI_PID0()           bfin_read16(RSI_PID0)
-#define bfin_write_RSI_PID0(val)       bfin_write16(RSI_PID0, val)
-#define bfin_read_RSI_PID1()           bfin_read16(RSI_PID1)
-#define bfin_write_RSI_PID1(val)       bfin_write16(RSI_PID1, val)
-#define bfin_read_RSI_PID2()           bfin_read16(RSI_PID2)
-#define bfin_write_RSI_PID2(val)       bfin_write16(RSI_PID2, val)
-#define bfin_read_RSI_PID3()           bfin_read16(RSI_PID3)
-#define bfin_write_RSI_PID3(val)       bfin_write16(RSI_PID3, val)
-#define bfin_read_RSI_PID4()           bfin_read16(RSI_PID4)
-#define bfin_write_RSI_PID4(val)       bfin_write16(RSI_PID4, val)
-#define bfin_read_RSI_PID5()           bfin_read16(RSI_PID5)
-#define bfin_write_RSI_PID5(val)       bfin_write16(RSI_PID5, val)
-#define bfin_read_RSI_PID6()           bfin_read16(RSI_PID6)
-#define bfin_write_RSI_PID6(val)       bfin_write16(RSI_PID6, val)
-#define bfin_read_RSI_PID7()           bfin_read16(RSI_PID7)
-#define bfin_write_RSI_PID7(val)       bfin_write16(RSI_PID7, val)
-
-
 #endif /* _CDEF_BF518_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -131,23 +131,6 @@
 #define bfin_write_UART0_GCTL(val)		bfin_write16(UART0_GCTL, val)
 
 
-/* SPI Controller		(0xFFC00500 - 0xFFC005FF)									*/
-#define bfin_read_SPI_CTL()			bfin_read16(SPI_CTL)
-#define bfin_write_SPI_CTL(val)			bfin_write16(SPI_CTL, val)
-#define bfin_read_SPI_FLG()			bfin_read16(SPI_FLG)
-#define bfin_write_SPI_FLG(val)			bfin_write16(SPI_FLG, val)
-#define bfin_read_SPI_STAT()			bfin_read16(SPI_STAT)
-#define bfin_write_SPI_STAT(val)		bfin_write16(SPI_STAT, val)
-#define bfin_read_SPI_TDBR()			bfin_read16(SPI_TDBR)
-#define bfin_write_SPI_TDBR(val)		bfin_write16(SPI_TDBR, val)
-#define bfin_read_SPI_RDBR()			bfin_read16(SPI_RDBR)
-#define bfin_write_SPI_RDBR(val)		bfin_write16(SPI_RDBR, val)
-#define bfin_read_SPI_BAUD()			bfin_read16(SPI_BAUD)
-#define bfin_write_SPI_BAUD(val)		bfin_write16(SPI_BAUD, val)
-#define bfin_read_SPI_SHADOW()			bfin_read16(SPI_SHADOW)
-#define bfin_write_SPI_SHADOW(val)		bfin_write16(SPI_SHADOW, val)
-
-
 /* TIMER0-7 Registers		(0xFFC00600 - 0xFFC006FF)								*/
 #define bfin_read_TIMER0_CONFIG()		bfin_read16(TIMER0_CONFIG)
 #define bfin_write_TIMER0_CONFIG(val)		bfin_write16(TIMER0_CONFIG, val)
@@ -844,6 +827,7 @@
 #define bfin_write_PPI_CONTROL(val)		bfin_write16(PPI_CONTROL, val)
 #define bfin_read_PPI_STATUS()			bfin_read16(PPI_STATUS)
 #define bfin_write_PPI_STATUS(val)		bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS()			bfin_write_PPI_STATUS(0xFFFF)
 #define bfin_read_PPI_DELAY()			bfin_read16(PPI_DELAY)
 #define bfin_write_PPI_DELAY(val)		bfin_write16(PPI_DELAY, val)
 #define bfin_read_PPI_COUNT()			bfin_read16(PPI_COUNT)
@@ -1062,17 +1046,6 @@
 #define bfin_read_CNT_MIN()			bfin_read32(CNT_MIN)
 #define bfin_write_CNT_MIN(val)			bfin_write32(CNT_MIN, val)
 
-/* OTP/FUSE Registers */
-
-#define bfin_read_OTP_CONTROL()			bfin_read16(OTP_CONTROL)
-#define bfin_write_OTP_CONTROL(val)		bfin_write16(OTP_CONTROL, val)
-#define bfin_read_OTP_BEN()			bfin_read16(OTP_BEN)
-#define bfin_write_OTP_BEN(val)			bfin_write16(OTP_BEN, val)
-#define bfin_read_OTP_STATUS()			bfin_read16(OTP_STATUS)
-#define bfin_write_OTP_STATUS(val)		bfin_write16(OTP_STATUS, val)
-#define bfin_read_OTP_TIMING()			bfin_read32(OTP_TIMING)
-#define bfin_write_OTP_TIMING(val)		bfin_write32(OTP_TIMING, val)
-
 /* Security Registers */
 
 #define bfin_read_SECURE_SYSSWT()		bfin_read32(SECURE_SYSSWT)
@@ -1082,52 +1055,6 @@
 #define bfin_read_SECURE_STATUS()		bfin_read16(SECURE_STATUS)
 #define bfin_write_SECURE_STATUS(val)		bfin_write16(SECURE_STATUS, val)
 
-/* OTP Read/Write Data Buffer Registers */
-
-#define bfin_read_OTP_DATA0()			bfin_read32(OTP_DATA0)
-#define bfin_write_OTP_DATA0(val)		bfin_write32(OTP_DATA0, val)
-#define bfin_read_OTP_DATA1()			bfin_read32(OTP_DATA1)
-#define bfin_write_OTP_DATA1(val)		bfin_write32(OTP_DATA1, val)
-#define bfin_read_OTP_DATA2()			bfin_read32(OTP_DATA2)
-#define bfin_write_OTP_DATA2(val)		bfin_write32(OTP_DATA2, val)
-#define bfin_read_OTP_DATA3()			bfin_read32(OTP_DATA3)
-#define bfin_write_OTP_DATA3(val)		bfin_write32(OTP_DATA3, val)
-
-/* NFC Registers */
-
-#define bfin_read_NFC_CTL()			bfin_read16(NFC_CTL)
-#define bfin_write_NFC_CTL(val)			bfin_write16(NFC_CTL, val)
-#define bfin_read_NFC_STAT()			bfin_read16(NFC_STAT)
-#define bfin_write_NFC_STAT(val)		bfin_write16(NFC_STAT, val)
-#define bfin_read_NFC_IRQSTAT()			bfin_read16(NFC_IRQSTAT)
-#define bfin_write_NFC_IRQSTAT(val)		bfin_write16(NFC_IRQSTAT, val)
-#define bfin_read_NFC_IRQMASK()			bfin_read16(NFC_IRQMASK)
-#define bfin_write_NFC_IRQMASK(val)		bfin_write16(NFC_IRQMASK, val)
-#define bfin_read_NFC_ECC0()			bfin_read16(NFC_ECC0)
-#define bfin_write_NFC_ECC0(val)		bfin_write16(NFC_ECC0, val)
-#define bfin_read_NFC_ECC1()			bfin_read16(NFC_ECC1)
-#define bfin_write_NFC_ECC1(val)		bfin_write16(NFC_ECC1, val)
-#define bfin_read_NFC_ECC2()			bfin_read16(NFC_ECC2)
-#define bfin_write_NFC_ECC2(val)		bfin_write16(NFC_ECC2, val)
-#define bfin_read_NFC_ECC3()			bfin_read16(NFC_ECC3)
-#define bfin_write_NFC_ECC3(val)		bfin_write16(NFC_ECC3, val)
-#define bfin_read_NFC_COUNT()			bfin_read16(NFC_COUNT)
-#define bfin_write_NFC_COUNT(val)		bfin_write16(NFC_COUNT, val)
-#define bfin_read_NFC_RST()			bfin_read16(NFC_RST)
-#define bfin_write_NFC_RST(val)			bfin_write16(NFC_RST, val)
-#define bfin_read_NFC_PGCTL()			bfin_read16(NFC_PGCTL)
-#define bfin_write_NFC_PGCTL(val)		bfin_write16(NFC_PGCTL, val)
-#define bfin_read_NFC_READ()			bfin_read16(NFC_READ)
-#define bfin_write_NFC_READ(val)		bfin_write16(NFC_READ, val)
-#define bfin_read_NFC_ADDR()			bfin_read16(NFC_ADDR)
-#define bfin_write_NFC_ADDR(val)		bfin_write16(NFC_ADDR, val)
-#define bfin_read_NFC_CMD()			bfin_read16(NFC_CMD)
-#define bfin_write_NFC_CMD(val)			bfin_write16(NFC_CMD, val)
-#define bfin_read_NFC_DATA_WR()			bfin_read16(NFC_DATA_WR)
-#define bfin_write_NFC_DATA_WR(val)		bfin_write16(NFC_DATA_WR, val)
-#define bfin_read_NFC_DATA_RD()			bfin_read16(NFC_DATA_RD)
-#define bfin_write_NFC_DATA_RD(val)		bfin_write16(NFC_DATA_RD, val)
-
 /* These need to be last due to the cdef/linux inter-dependencies */
 #include <asm/irq.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,49 +7,8 @@
 #ifndef _DEF_BF514_H
 #define _DEF_BF514_H
 
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF514 */
-
-/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "defBF51x_base.h"
-
-/* The following are the #defines needed by ADSP-BF514 that are not in the common header */
-
-/* SDH Registers */
-
-#define SDH_PWR_CTL                    0xFFC03900 /* SDH Power Control */
-#define SDH_CLK_CTL                    0xFFC03904 /* SDH Clock Control */
-#define SDH_ARGUMENT                   0xFFC03908 /* SDH Argument */
-#define SDH_COMMAND                    0xFFC0390C /* SDH Command */
-#define SDH_RESP_CMD                   0xFFC03910 /* SDH Response Command */
-#define SDH_RESPONSE0                  0xFFC03914 /* SDH Response0 */
-#define SDH_RESPONSE1                  0xFFC03918 /* SDH Response1 */
-#define SDH_RESPONSE2                  0xFFC0391C /* SDH Response2 */
-#define SDH_RESPONSE3                  0xFFC03920 /* SDH Response3 */
-#define SDH_DATA_TIMER                 0xFFC03924 /* SDH Data Timer */
-#define SDH_DATA_LGTH                  0xFFC03928 /* SDH Data Length */
-#define SDH_DATA_CTL                   0xFFC0392C /* SDH Data Control */
-#define SDH_DATA_CNT                   0xFFC03930 /* SDH Data Counter */
-#define SDH_STATUS                     0xFFC03934 /* SDH Status */
-#define SDH_STATUS_CLR                 0xFFC03938 /* SDH Status Clear */
-#define SDH_MASK0                      0xFFC0393C /* SDH Interrupt0 Mask */
-#define SDH_MASK1                      0xFFC03940 /* SDH Interrupt1 Mask */
-#define SDH_FIFO_CNT                   0xFFC03948 /* SDH FIFO Counter */
-#define SDH_FIFO                       0xFFC03980 /* SDH Data FIFO */
-#define SDH_E_STATUS                   0xFFC039C0 /* SDH Exception Status */
-#define SDH_E_MASK                     0xFFC039C4 /* SDH Exception Mask */
-#define SDH_CFG                        0xFFC039C8 /* SDH Configuration */
-#define SDH_RD_WAIT_EN                 0xFFC039CC /* SDH Read Wait Enable */
-#define SDH_PID0                       0xFFC039D0 /* SDH Peripheral Identification0 */
-#define SDH_PID1                       0xFFC039D4 /* SDH Peripheral Identification1 */
-#define SDH_PID2                       0xFFC039D8 /* SDH Peripheral Identification2 */
-#define SDH_PID3                       0xFFC039DC /* SDH Peripheral Identification3 */
-#define SDH_PID4                       0xFFC039E0 /* SDH Peripheral Identification4 */
-#define SDH_PID5                       0xFFC039E4 /* SDH Peripheral Identification5 */
-#define SDH_PID6                       0xFFC039E8 /* SDH Peripheral Identification6 */
-#define SDH_PID7                       0xFFC039EC /* SDH Peripheral Identification7 */
+/* BF514 is BF512 + RSI */
+#include "defBF512.h"
 
 /* Removable Storage Interface Registers */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,13 +7,8 @@
 #ifndef _DEF_BF516_H
 #define _DEF_BF516_H
 
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF516 */
-
-/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "defBF51x_base.h"
+/* BF516 is BF514 + EMAC */
+#include "defBF514.h"
 
 /* The following are the #defines needed by ADSP-BF516 that are not in the common header */
 /* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
@@ -394,208 +389,4 @@
 #define	TX_GE1024_CNT     0x00200000    /* 1024-Max-Byte TX Frames Sent                           */
 #define	TX_ABORT_CNT      0x00400000    /* TX Frames Aborted                                      */
 
-/* SDH Registers */
-
-#define SDH_PWR_CTL                    0xFFC03900 /* SDH Power Control */
-#define SDH_CLK_CTL                    0xFFC03904 /* SDH Clock Control */
-#define SDH_ARGUMENT                   0xFFC03908 /* SDH Argument */
-#define SDH_COMMAND                    0xFFC0390C /* SDH Command */
-#define SDH_RESP_CMD                   0xFFC03910 /* SDH Response Command */
-#define SDH_RESPONSE0                  0xFFC03914 /* SDH Response0 */
-#define SDH_RESPONSE1                  0xFFC03918 /* SDH Response1 */
-#define SDH_RESPONSE2                  0xFFC0391C /* SDH Response2 */
-#define SDH_RESPONSE3                  0xFFC03920 /* SDH Response3 */
-#define SDH_DATA_TIMER                 0xFFC03924 /* SDH Data Timer */
-#define SDH_DATA_LGTH                  0xFFC03928 /* SDH Data Length */
-#define SDH_DATA_CTL                   0xFFC0392C /* SDH Data Control */
-#define SDH_DATA_CNT                   0xFFC03930 /* SDH Data Counter */
-#define SDH_STATUS                     0xFFC03934 /* SDH Status */
-#define SDH_STATUS_CLR                 0xFFC03938 /* SDH Status Clear */
-#define SDH_MASK0                      0xFFC0393C /* SDH Interrupt0 Mask */
-#define SDH_MASK1                      0xFFC03940 /* SDH Interrupt1 Mask */
-#define SDH_FIFO_CNT                   0xFFC03948 /* SDH FIFO Counter */
-#define SDH_FIFO                       0xFFC03980 /* SDH Data FIFO */
-#define SDH_E_STATUS                   0xFFC039C0 /* SDH Exception Status */
-#define SDH_E_MASK                     0xFFC039C4 /* SDH Exception Mask */
-#define SDH_CFG                        0xFFC039C8 /* SDH Configuration */
-#define SDH_RD_WAIT_EN                 0xFFC039CC /* SDH Read Wait Enable */
-#define SDH_PID0                       0xFFC039D0 /* SDH Peripheral Identification0 */
-#define SDH_PID1                       0xFFC039D4 /* SDH Peripheral Identification1 */
-#define SDH_PID2                       0xFFC039D8 /* SDH Peripheral Identification2 */
-#define SDH_PID3                       0xFFC039DC /* SDH Peripheral Identification3 */
-#define SDH_PID4                       0xFFC039E0 /* SDH Peripheral Identification4 */
-#define SDH_PID5                       0xFFC039E4 /* SDH Peripheral Identification5 */
-#define SDH_PID6                       0xFFC039E8 /* SDH Peripheral Identification6 */
-#define SDH_PID7                       0xFFC039EC /* SDH Peripheral Identification7 */
-
-/* Removable Storage Interface Registers */
-
-#define RSI_PWR_CONTROL                0xFFC03800 /* RSI Power Control Register */
-#define RSI_CLK_CONTROL                0xFFC03804 /* RSI Clock Control Register */
-#define RSI_ARGUMENT                   0xFFC03808 /* RSI Argument Register */
-#define RSI_COMMAND                    0xFFC0380C /* RSI Command Register */
-#define RSI_RESP_CMD                   0xFFC03810 /* RSI Response Command Register */
-#define RSI_RESPONSE0                  0xFFC03814 /* RSI Response Register */
-#define RSI_RESPONSE1                  0xFFC03818 /* RSI Response Register */
-#define RSI_RESPONSE2                  0xFFC0381C /* RSI Response Register */
-#define RSI_RESPONSE3                  0xFFC03820 /* RSI Response Register */
-#define RSI_DATA_TIMER                 0xFFC03824 /* RSI Data Timer Register */
-#define RSI_DATA_LGTH                  0xFFC03828 /* RSI Data Length Register */
-#define RSI_DATA_CONTROL               0xFFC0382C /* RSI Data Control Register */
-#define RSI_DATA_CNT                   0xFFC03830 /* RSI Data Counter Register */
-#define RSI_STATUS                     0xFFC03834 /* RSI Status Register */
-#define RSI_STATUSCL                   0xFFC03838 /* RSI Status Clear Register */
-#define RSI_MASK0                      0xFFC0383C /* RSI Interrupt 0 Mask Register */
-#define RSI_MASK1                      0xFFC03840 /* RSI Interrupt 1 Mask Register */
-#define RSI_FIFO_CNT                   0xFFC03848 /* RSI FIFO Counter Register */
-#define RSI_CEATA_CONTROL              0xFFC0384C /* RSI CEATA Register */
-#define RSI_FIFO                       0xFFC03880 /* RSI Data FIFO Register */
-#define RSI_ESTAT                      0xFFC038C0 /* RSI Exception Status Register */
-#define RSI_EMASK                      0xFFC038C4 /* RSI Exception Mask Register */
-#define RSI_CONFIG                     0xFFC038C8 /* RSI Configuration Register */
-#define RSI_RD_WAIT_EN                 0xFFC038CC /* RSI Read Wait Enable Register */
-#define RSI_PID0                       0xFFC03FE0 /* RSI Peripheral ID Register 0 */
-#define RSI_PID1                       0xFFC03FE4 /* RSI Peripheral ID Register 1 */
-#define RSI_PID2                       0xFFC03FE8 /* RSI Peripheral ID Register 2 */
-#define RSI_PID3                       0xFFC03FEC /* RSI Peripheral ID Register 3 */
-#define RSI_PID4                       0xFFC03FF0 /* RSI Peripheral ID Register 4 */
-#define RSI_PID5                       0xFFC03FF4 /* RSI Peripheral ID Register 5 */
-#define RSI_PID6                       0xFFC03FF8 /* RSI Peripheral ID Register 6 */
-#define RSI_PID7                       0xFFC03FFC /* RSI Peripheral ID Register 7 */
-
-/* ********************************************************** */
-/*     SINGLE BIT MACRO PAIRS (bit mask and negated one)      */
-/*     and MULTI BIT READ MACROS                              */
-/* ********************************************************** */
-
-/* Bit masks for SDH_COMMAND */
-
-#define                   CMD_IDX  0x3f       /* Command Index */
-#define                   CMD_RSP  0x40       /* Response */
-#define                 CMD_L_RSP  0x80       /* Long Response */
-#define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                CMD_PEND_E  0x200      /* Command Pending */
-#define                     CMD_E  0x400      /* Command Enable */
-
-/* Bit masks for SDH_PWR_CTL */
-
-#define                    PWR_ON  0x3        /* Power On */
-#if 0
-#define                       TBD  0x3c       /* TBD */
-#endif
-#define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                   ROD_CTL  0x80       /* Rod Control */
-
-/* Bit masks for SDH_CLK_CTL */
-
-#define                    CLKDIV  0xff       /* MC_CLK Divisor */
-#define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-
-/* Bit masks for SDH_RESP_CMD */
-
-#define                  RESP_CMD  0x3f       /* Response Command */
-
-/* Bit masks for SDH_DATA_CTL */
-
-#define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
-
-/* Bit masks for SDH_STATUS */
-
-#define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
-#define               DAT_TIME_OUT  0x8        /* Data Time Out */
-#define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define              CMD_RESP_END  0x40       /* CMD Response End */
-#define                  CMD_SENT  0x80       /* CMD Sent */
-#define                   DAT_END  0x100      /* Data End */
-#define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define               DAT_BLK_END  0x400      /* Data Block End */
-#define                   CMD_ACT  0x800      /* CMD Active */
-#define                    TX_ACT  0x1000     /* Transmit Active */
-#define                    RX_ACT  0x2000     /* Receive Active */
-#define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-
-/* Bit masks for SDH_STATUS_CLR */
-
-#define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define              DAT_END_STAT  0x100      /* Data End Status */
-#define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-
-/* Bit masks for SDH_MASK0 */
-
-#define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define              DAT_END_MASK  0x100      /* Data End Mask */
-#define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-
-/* Bit masks for SDH_FIFO_CNT */
-
-#define                FIFO_COUNT  0x7fff     /* FIFO Count */
-
-/* Bit masks for SDH_E_STATUS */
-
-#define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define               SD_CARD_DET  0x10       /* SD Card Detect */
-
-/* Bit masks for SDH_E_MASK */
-
-#define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                   SCD_MSK  0x40       /* Mask Card Detect */
-
-/* Bit masks for SDH_CFG */
-
-#define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                       MWE  0x8        /* Moving Window Enable */
-#define                    SD_RST  0x10       /* SDMMC Reset */
-#define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-
-/* Bit masks for SDH_RD_WAIT_EN */
-
-#define                       RWR  0x1        /* Read Wait Request */
-
 #endif /* _DEF_BF516_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF518.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF518.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF518.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF518.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,461 +7,8 @@
 #ifndef _DEF_BF518_H
 #define _DEF_BF518_H
 
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF518 */
-
-/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */
-#include "defBF51x_base.h"
-
-/* The following are the #defines needed by ADSP-BF518 that are not in the common header */
-/* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
-
-#define EMAC_OPMODE             0xFFC03000       /* Operating Mode Register                              */
-#define EMAC_ADDRLO             0xFFC03004       /* Address Low (32 LSBs) Register                       */
-#define EMAC_ADDRHI             0xFFC03008       /* Address High (16 MSBs) Register                      */
-#define EMAC_HASHLO             0xFFC0300C       /* Multicast Hash Table Low (Bins 31-0) Register        */
-#define EMAC_HASHHI             0xFFC03010       /* Multicast Hash Table High (Bins 63-32) Register      */
-#define EMAC_STAADD             0xFFC03014       /* Station Management Address Register                  */
-#define EMAC_STADAT             0xFFC03018       /* Station Management Data Register                     */
-#define EMAC_FLC                0xFFC0301C       /* Flow Control Register                                */
-#define EMAC_VLAN1              0xFFC03020       /* VLAN1 Tag Register                                   */
-#define EMAC_VLAN2              0xFFC03024       /* VLAN2 Tag Register                                   */
-#define EMAC_WKUP_CTL           0xFFC0302C       /* Wake-Up Control/Status Register                      */
-#define EMAC_WKUP_FFMSK0        0xFFC03030       /* Wake-Up Frame Filter 0 Byte Mask Register            */
-#define EMAC_WKUP_FFMSK1        0xFFC03034       /* Wake-Up Frame Filter 1 Byte Mask Register            */
-#define EMAC_WKUP_FFMSK2        0xFFC03038       /* Wake-Up Frame Filter 2 Byte Mask Register            */
-#define EMAC_WKUP_FFMSK3        0xFFC0303C       /* Wake-Up Frame Filter 3 Byte Mask Register            */
-#define EMAC_WKUP_FFCMD         0xFFC03040       /* Wake-Up Frame Filter Commands Register               */
-#define EMAC_WKUP_FFOFF         0xFFC03044       /* Wake-Up Frame Filter Offsets Register                */
-#define EMAC_WKUP_FFCRC0        0xFFC03048       /* Wake-Up Frame Filter 0,1 CRC-16 Register             */
-#define EMAC_WKUP_FFCRC1        0xFFC0304C       /* Wake-Up Frame Filter 2,3 CRC-16 Register             */
-
-#define EMAC_SYSCTL             0xFFC03060       /* EMAC System Control Register                         */
-#define EMAC_SYSTAT             0xFFC03064       /* EMAC System Status Register                          */
-#define EMAC_RX_STAT            0xFFC03068       /* RX Current Frame Status Register                     */
-#define EMAC_RX_STKY            0xFFC0306C       /* RX Sticky Frame Status Register                      */
-#define EMAC_RX_IRQE            0xFFC03070       /* RX Frame Status Interrupt Enables Register           */
-#define EMAC_TX_STAT            0xFFC03074       /* TX Current Frame Status Register                     */
-#define EMAC_TX_STKY            0xFFC03078       /* TX Sticky Frame Status Register                      */
-#define EMAC_TX_IRQE            0xFFC0307C       /* TX Frame Status Interrupt Enables Register           */
-
-#define EMAC_MMC_CTL            0xFFC03080       /* MMC Counter Control Register                         */
-#define EMAC_MMC_RIRQS          0xFFC03084       /* MMC RX Interrupt Status Register                     */
-#define EMAC_MMC_RIRQE          0xFFC03088       /* MMC RX Interrupt Enables Register                    */
-#define EMAC_MMC_TIRQS          0xFFC0308C       /* MMC TX Interrupt Status Register                     */
-#define EMAC_MMC_TIRQE          0xFFC03090       /* MMC TX Interrupt Enables Register                    */
-
-#define EMAC_RXC_OK             0xFFC03100       /* RX Frame Successful Count                            */
-#define EMAC_RXC_FCS            0xFFC03104       /* RX Frame FCS Failure Count                           */
-#define EMAC_RXC_ALIGN          0xFFC03108       /* RX Alignment Error Count                             */
-#define EMAC_RXC_OCTET          0xFFC0310C       /* RX Octets Successfully Received Count                */
-#define EMAC_RXC_DMAOVF         0xFFC03110       /* Internal MAC Sublayer Error RX Frame Count           */
-#define EMAC_RXC_UNICST         0xFFC03114       /* Unicast RX Frame Count                               */
-#define EMAC_RXC_MULTI          0xFFC03118       /* Multicast RX Frame Count                             */
-#define EMAC_RXC_BROAD          0xFFC0311C       /* Broadcast RX Frame Count                             */
-#define EMAC_RXC_LNERRI         0xFFC03120       /* RX Frame In Range Error Count                        */
-#define EMAC_RXC_LNERRO         0xFFC03124       /* RX Frame Out Of Range Error Count                    */
-#define EMAC_RXC_LONG           0xFFC03128       /* RX Frame Too Long Count                              */
-#define EMAC_RXC_MACCTL         0xFFC0312C       /* MAC Control RX Frame Count                           */
-#define EMAC_RXC_OPCODE         0xFFC03130       /* Unsupported Op-Code RX Frame Count                   */
-#define EMAC_RXC_PAUSE          0xFFC03134       /* MAC Control Pause RX Frame Count                     */
-#define EMAC_RXC_ALLFRM         0xFFC03138       /* Overall RX Frame Count                               */
-#define EMAC_RXC_ALLOCT         0xFFC0313C       /* Overall RX Octet Count                               */
-#define EMAC_RXC_TYPED          0xFFC03140       /* Type/Length Consistent RX Frame Count                */
-#define EMAC_RXC_SHORT          0xFFC03144       /* RX Frame Fragment Count - Byte Count x < 64          */
-#define EMAC_RXC_EQ64           0xFFC03148       /* Good RX Frame Count - Byte Count x = 64              */
-#define EMAC_RXC_LT128          0xFFC0314C       /* Good RX Frame Count - Byte Count  64 < x < 128       */
-#define EMAC_RXC_LT256          0xFFC03150       /* Good RX Frame Count - Byte Count 128 <= x < 256      */
-#define EMAC_RXC_LT512          0xFFC03154       /* Good RX Frame Count - Byte Count 256 <= x < 512      */
-#define EMAC_RXC_LT1024         0xFFC03158       /* Good RX Frame Count - Byte Count 512 <= x < 1024     */
-#define EMAC_RXC_GE1024         0xFFC0315C       /* Good RX Frame Count - Byte Count x >= 1024           */
-
-#define EMAC_TXC_OK             0xFFC03180       /* TX Frame Successful Count                             */
-#define EMAC_TXC_1COL           0xFFC03184       /* TX Frames Successful After Single Collision Count     */
-#define EMAC_TXC_GT1COL         0xFFC03188       /* TX Frames Successful After Multiple Collisions Count  */
-#define EMAC_TXC_OCTET          0xFFC0318C       /* TX Octets Successfully Received Count                 */
-#define EMAC_TXC_DEFER          0xFFC03190       /* TX Frame Delayed Due To Busy Count                    */
-#define EMAC_TXC_LATECL         0xFFC03194       /* Late TX Collisions Count                              */
-#define EMAC_TXC_XS_COL         0xFFC03198       /* TX Frame Failed Due To Excessive Collisions Count     */
-#define EMAC_TXC_DMAUND         0xFFC0319C       /* Internal MAC Sublayer Error TX Frame Count            */
-#define EMAC_TXC_CRSERR         0xFFC031A0       /* Carrier Sense Deasserted During TX Frame Count        */
-#define EMAC_TXC_UNICST         0xFFC031A4       /* Unicast TX Frame Count                                */
-#define EMAC_TXC_MULTI          0xFFC031A8       /* Multicast TX Frame Count                              */
-#define EMAC_TXC_BROAD          0xFFC031AC       /* Broadcast TX Frame Count                              */
-#define EMAC_TXC_XS_DFR         0xFFC031B0       /* TX Frames With Excessive Deferral Count               */
-#define EMAC_TXC_MACCTL         0xFFC031B4       /* MAC Control TX Frame Count                            */
-#define EMAC_TXC_ALLFRM         0xFFC031B8       /* Overall TX Frame Count                                */
-#define EMAC_TXC_ALLOCT         0xFFC031BC       /* Overall TX Octet Count                                */
-#define EMAC_TXC_EQ64           0xFFC031C0       /* Good TX Frame Count - Byte Count x = 64               */
-#define EMAC_TXC_LT128          0xFFC031C4       /* Good TX Frame Count - Byte Count  64 < x < 128        */
-#define EMAC_TXC_LT256          0xFFC031C8       /* Good TX Frame Count - Byte Count 128 <= x < 256       */
-#define EMAC_TXC_LT512          0xFFC031CC       /* Good TX Frame Count - Byte Count 256 <= x < 512       */
-#define EMAC_TXC_LT1024         0xFFC031D0       /* Good TX Frame Count - Byte Count 512 <= x < 1024      */
-#define EMAC_TXC_GE1024         0xFFC031D4       /* Good TX Frame Count - Byte Count x >= 1024            */
-#define EMAC_TXC_ABORT          0xFFC031D8       /* Total TX Frames Aborted Count                         */
-
-/* Listing for IEEE-Supported Count Registers */
-
-#define FramesReceivedOK                EMAC_RXC_OK        /* RX Frame Successful Count                            */
-#define FrameCheckSequenceErrors        EMAC_RXC_FCS       /* RX Frame FCS Failure Count                           */
-#define AlignmentErrors                 EMAC_RXC_ALIGN     /* RX Alignment Error Count                             */
-#define OctetsReceivedOK                EMAC_RXC_OCTET     /* RX Octets Successfully Received Count                */
-#define FramesLostDueToIntMACRcvError   EMAC_RXC_DMAOVF    /* Internal MAC Sublayer Error RX Frame Count           */
-#define UnicastFramesReceivedOK         EMAC_RXC_UNICST    /* Unicast RX Frame Count                               */
-#define MulticastFramesReceivedOK       EMAC_RXC_MULTI     /* Multicast RX Frame Count                             */
-#define BroadcastFramesReceivedOK       EMAC_RXC_BROAD     /* Broadcast RX Frame Count                             */
-#define InRangeLengthErrors             EMAC_RXC_LNERRI    /* RX Frame In Range Error Count                        */
-#define OutOfRangeLengthField           EMAC_RXC_LNERRO    /* RX Frame Out Of Range Error Count                    */
-#define FrameTooLongErrors              EMAC_RXC_LONG      /* RX Frame Too Long Count                              */
-#define MACControlFramesReceived        EMAC_RXC_MACCTL    /* MAC Control RX Frame Count                           */
-#define UnsupportedOpcodesReceived      EMAC_RXC_OPCODE    /* Unsupported Op-Code RX Frame Count                   */
-#define PAUSEMACCtrlFramesReceived      EMAC_RXC_PAUSE     /* MAC Control Pause RX Frame Count                     */
-#define FramesReceivedAll               EMAC_RXC_ALLFRM    /* Overall RX Frame Count                               */
-#define OctetsReceivedAll               EMAC_RXC_ALLOCT    /* Overall RX Octet Count                               */
-#define TypedFramesReceived             EMAC_RXC_TYPED     /* Type/Length Consistent RX Frame Count                */
-#define FramesLenLt64Received           EMAC_RXC_SHORT     /* RX Frame Fragment Count - Byte Count x < 64          */
-#define FramesLenEq64Received           EMAC_RXC_EQ64      /* Good RX Frame Count - Byte Count x = 64              */
-#define FramesLen65_127Received         EMAC_RXC_LT128     /* Good RX Frame Count - Byte Count  64 < x < 128       */
-#define FramesLen128_255Received        EMAC_RXC_LT256     /* Good RX Frame Count - Byte Count 128 <= x < 256      */
-#define FramesLen256_511Received        EMAC_RXC_LT512     /* Good RX Frame Count - Byte Count 256 <= x < 512      */
-#define FramesLen512_1023Received       EMAC_RXC_LT1024    /* Good RX Frame Count - Byte Count 512 <= x < 1024     */
-#define FramesLen1024_MaxReceived       EMAC_RXC_GE1024    /* Good RX Frame Count - Byte Count x >= 1024           */
-
-#define FramesTransmittedOK             EMAC_TXC_OK        /* TX Frame Successful Count                            */
-#define SingleCollisionFrames           EMAC_TXC_1COL      /* TX Frames Successful After Single Collision Count    */
-#define MultipleCollisionFrames         EMAC_TXC_GT1COL    /* TX Frames Successful After Multiple Collisions Count */
-#define OctetsTransmittedOK             EMAC_TXC_OCTET     /* TX Octets Successfully Received Count                */
-#define FramesWithDeferredXmissions     EMAC_TXC_DEFER     /* TX Frame Delayed Due To Busy Count                   */
-#define LateCollisions                  EMAC_TXC_LATECL    /* Late TX Collisions Count                             */
-#define FramesAbortedDueToXSColls       EMAC_TXC_XS_COL    /* TX Frame Failed Due To Excessive Collisions Count    */
-#define FramesLostDueToIntMacXmitError  EMAC_TXC_DMAUND    /* Internal MAC Sublayer Error TX Frame Count           */
-#define CarrierSenseErrors              EMAC_TXC_CRSERR    /* Carrier Sense Deasserted During TX Frame Count       */
-#define UnicastFramesXmittedOK          EMAC_TXC_UNICST    /* Unicast TX Frame Count                               */
-#define MulticastFramesXmittedOK        EMAC_TXC_MULTI     /* Multicast TX Frame Count                             */
-#define BroadcastFramesXmittedOK        EMAC_TXC_BROAD     /* Broadcast TX Frame Count                             */
-#define FramesWithExcessiveDeferral     EMAC_TXC_XS_DFR    /* TX Frames With Excessive Deferral Count              */
-#define MACControlFramesTransmitted     EMAC_TXC_MACCTL    /* MAC Control TX Frame Count                           */
-#define FramesTransmittedAll            EMAC_TXC_ALLFRM    /* Overall TX Frame Count                               */
-#define OctetsTransmittedAll            EMAC_TXC_ALLOCT    /* Overall TX Octet Count                               */
-#define FramesLenEq64Transmitted        EMAC_TXC_EQ64      /* Good TX Frame Count - Byte Count x = 64              */
-#define FramesLen65_127Transmitted      EMAC_TXC_LT128     /* Good TX Frame Count - Byte Count  64 < x < 128       */
-#define FramesLen128_255Transmitted     EMAC_TXC_LT256     /* Good TX Frame Count - Byte Count 128 <= x < 256      */
-#define FramesLen256_511Transmitted     EMAC_TXC_LT512     /* Good TX Frame Count - Byte Count 256 <= x < 512      */
-#define FramesLen512_1023Transmitted    EMAC_TXC_LT1024    /* Good TX Frame Count - Byte Count 512 <= x < 1024     */
-#define FramesLen1024_MaxTransmitted    EMAC_TXC_GE1024    /* Good TX Frame Count - Byte Count x >= 1024           */
-#define TxAbortedFrames                 EMAC_TXC_ABORT     /* Total TX Frames Aborted Count                        */
-
-/***********************************************************************************
-** System MMR Register Bits And Macros
-**
-** Disclaimer:	All macros are intended to make C and Assembly code more readable.
-**				Use these macros carefully, as any that do left shifts for field
-**				depositing will result in the lower order bits being destroyed.  Any
-**				macro that shifts left to properly position the bit-field should be
-**				used as part of an OR to initialize a register and NOT as a dynamic
-**				modifier UNLESS the lower order bits are saved and ORed back in when
-**				the macro is used.
-*************************************************************************************/
-
-/************************  ETHERNET 10/100 CONTROLLER MASKS  ************************/
-
-/* EMAC_OPMODE Masks */
-
-#define	RE                 0x00000001     /* Receiver Enable                                    */
-#define	ASTP               0x00000002     /* Enable Automatic Pad Stripping On RX Frames        */
-#define	HU                 0x00000010     /* Hash Filter Unicast Address                        */
-#define	HM                 0x00000020     /* Hash Filter Multicast Address                      */
-#define	PAM                0x00000040     /* Pass-All-Multicast Mode Enable                     */
-#define	PR                 0x00000080     /* Promiscuous Mode Enable                            */
-#define	IFE                0x00000100     /* Inverse Filtering Enable                           */
-#define	DBF                0x00000200     /* Disable Broadcast Frame Reception                  */
-#define	PBF                0x00000400     /* Pass Bad Frames Enable                             */
-#define	PSF                0x00000800     /* Pass Short Frames Enable                           */
-#define	RAF                0x00001000     /* Receive-All Mode                                   */
-#define	TE                 0x00010000     /* Transmitter Enable                                 */
-#define	DTXPAD             0x00020000     /* Disable Automatic TX Padding                       */
-#define	DTXCRC             0x00040000     /* Disable Automatic TX CRC Generation                */
-#define	DC                 0x00080000     /* Deferral Check                                     */
-#define	BOLMT              0x00300000     /* Back-Off Limit                                     */
-#define	BOLMT_10           0x00000000     /*		10-bit range                            */
-#define	BOLMT_8            0x00100000     /*		8-bit range                             */
-#define	BOLMT_4            0x00200000     /*		4-bit range                             */
-#define	BOLMT_1            0x00300000     /*		1-bit range                             */
-#define	DRTY               0x00400000     /* Disable TX Retry On Collision                      */
-#define	LCTRE              0x00800000     /* Enable TX Retry On Late Collision                  */
-#define	RMII               0x01000000     /* RMII/MII* Mode                                     */
-#define	RMII_10            0x02000000     /* Speed Select for RMII Port (10MBit/100MBit*)       */
-#define	FDMODE             0x04000000     /* Duplex Mode Enable (Full/Half*)                    */
-#define	LB                 0x08000000     /* Internal Loopback Enable                           */
-#define	DRO                0x10000000     /* Disable Receive Own Frames (Half-Duplex Mode)      */
-
-/* EMAC_STAADD Masks */
-
-#define	STABUSY            0x00000001     /* Initiate Station Mgt Reg Access / STA Busy Stat    */
-#define	STAOP              0x00000002     /* Station Management Operation Code (Write/Read*)    */
-#define	STADISPRE          0x00000004     /* Disable Preamble Generation                        */
-#define	STAIE              0x00000008     /* Station Mgt. Transfer Done Interrupt Enable        */
-#define	REGAD              0x000007C0     /* STA Register Address                               */
-#define	PHYAD              0x0000F800     /* PHY Device Address                                 */
-
-#define	SET_REGAD(x) (((x)&0x1F)<<  6 )   /* Set STA Register Address                           */
-#define	SET_PHYAD(x) (((x)&0x1F)<< 11 )   /* Set PHY Device Address                             */
-
-/* EMAC_STADAT Mask */
-
-#define	STADATA            0x0000FFFF     /* Station Management Data                            */
-
-/* EMAC_FLC Masks */
-
-#define	FLCBUSY            0x00000001     /* Send Flow Ctrl Frame / Flow Ctrl Busy Status       */
-#define	FLCE               0x00000002     /* Flow Control Enable                                */
-#define	PCF                0x00000004     /* Pass Control Frames                                */
-#define	BKPRSEN            0x00000008     /* Enable Backpressure                                */
-#define	FLCPAUSE           0xFFFF0000     /* Pause Time                                         */
-
-#define	SET_FLCPAUSE(x) (((x)&0xFFFF)<< 16) /* Set Pause Time                                   */
-
-/* EMAC_WKUP_CTL Masks */
-
-#define	CAPWKFRM           0x00000001    /* Capture Wake-Up Frames                              */
-#define	MPKE               0x00000002    /* Magic Packet Enable                                 */
-#define	RWKE               0x00000004    /* Remote Wake-Up Frame Enable                         */
-#define	GUWKE              0x00000008    /* Global Unicast Wake Enable                          */
-#define	MPKS               0x00000020    /* Magic Packet Received Status                        */
-#define	RWKS               0x00000F00    /* Wake-Up Frame Received Status, Filters 3:0          */
-
-/* EMAC_WKUP_FFCMD Masks */
-
-#define	WF0_E              0x00000001    /* Enable Wake-Up Filter 0                              */
-#define	WF0_T              0x00000008    /* Wake-Up Filter 0 Addr Type (Multicast/Unicast*)      */
-#define	WF1_E              0x00000100    /* Enable Wake-Up Filter 1                              */
-#define	WF1_T              0x00000800    /* Wake-Up Filter 1 Addr Type (Multicast/Unicast*)      */
-#define	WF2_E              0x00010000    /* Enable Wake-Up Filter 2                              */
-#define	WF2_T              0x00080000    /* Wake-Up Filter 2 Addr Type (Multicast/Unicast*)      */
-#define	WF3_E              0x01000000    /* Enable Wake-Up Filter 3                              */
-#define	WF3_T              0x08000000    /* Wake-Up Filter 3 Addr Type (Multicast/Unicast*)      */
-
-/* EMAC_WKUP_FFOFF Masks */
-
-#define	WF0_OFF            0x000000FF    /* Wake-Up Filter 0 Pattern Offset                      */
-#define	WF1_OFF            0x0000FF00    /* Wake-Up Filter 1 Pattern Offset                      */
-#define	WF2_OFF            0x00FF0000    /* Wake-Up Filter 2 Pattern Offset                      */
-#define	WF3_OFF            0xFF000000    /* Wake-Up Filter 3 Pattern Offset                      */
-
-#define	SET_WF0_OFF(x) (((x)&0xFF)<<  0 ) /* Set Wake-Up Filter 0 Byte Offset                    */
-#define	SET_WF1_OFF(x) (((x)&0xFF)<<  8 ) /* Set Wake-Up Filter 1 Byte Offset                    */
-#define	SET_WF2_OFF(x) (((x)&0xFF)<< 16 ) /* Set Wake-Up Filter 2 Byte Offset                    */
-#define	SET_WF3_OFF(x) (((x)&0xFF)<< 24 ) /* Set Wake-Up Filter 3 Byte Offset                    */
-/* Set ALL Offsets */
-#define	SET_WF_OFFS(x0,x1,x2,x3) (SET_WF0_OFF((x0))|SET_WF1_OFF((x1))|SET_WF2_OFF((x2))|SET_WF3_OFF((x3)))
-
-/* EMAC_WKUP_FFCRC0 Masks */
-
-#define	WF0_CRC           0x0000FFFF    /* Wake-Up Filter 0 Pattern CRC                           */
-#define	WF1_CRC           0xFFFF0000    /* Wake-Up Filter 1 Pattern CRC                           */
-
-#define	SET_WF0_CRC(x) (((x)&0xFFFF)<<   0 ) /* Set Wake-Up Filter 0 Target CRC                   */
-#define	SET_WF1_CRC(x) (((x)&0xFFFF)<<  16 ) /* Set Wake-Up Filter 1 Target CRC                   */
-
-/* EMAC_WKUP_FFCRC1 Masks */
-
-#define	WF2_CRC           0x0000FFFF    /* Wake-Up Filter 2 Pattern CRC                           */
-#define	WF3_CRC           0xFFFF0000    /* Wake-Up Filter 3 Pattern CRC                           */
-
-#define	SET_WF2_CRC(x) (((x)&0xFFFF)<<   0 ) /* Set Wake-Up Filter 2 Target CRC                   */
-#define	SET_WF3_CRC(x) (((x)&0xFFFF)<<  16 ) /* Set Wake-Up Filter 3 Target CRC                   */
-
-/* EMAC_SYSCTL Masks */
-
-#define	PHYIE             0x00000001    /* PHY_INT Interrupt Enable                               */
-#define	RXDWA             0x00000002    /* Receive Frame DMA Word Alignment (Odd/Even*)           */
-#define	RXCKS             0x00000004    /* Enable RX Frame TCP/UDP Checksum Computation           */
-#define	TXDWA             0x00000010    /* Transmit Frame DMA Word Alignment (Odd/Even*)          */
-#define	MDCDIV            0x00003F00    /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))]            */
-
-#define	SET_MDCDIV(x) (((x)&0x3F)<< 8)   /* Set MDC Clock Divisor                                 */
-
-/* EMAC_SYSTAT Masks */
-
-#define	PHYINT            0x00000001    /* PHY_INT Interrupt Status                               */
-#define	MMCINT            0x00000002    /* MMC Counter Interrupt Status                           */
-#define	RXFSINT           0x00000004    /* RX Frame-Status Interrupt Status                       */
-#define	TXFSINT           0x00000008    /* TX Frame-Status Interrupt Status                       */
-#define	WAKEDET           0x00000010    /* Wake-Up Detected Status                                */
-#define	RXDMAERR          0x00000020    /* RX DMA Direction Error Status                          */
-#define	TXDMAERR          0x00000040    /* TX DMA Direction Error Status                          */
-#define	STMDONE           0x00000080    /* Station Mgt. Transfer Done Interrupt Status            */
-
-/* EMAC_RX_STAT, EMAC_RX_STKY, and EMAC_RX_IRQE Masks */
-
-#define	RX_FRLEN          0x000007FF    /* Frame Length In Bytes                                  */
-#define	RX_COMP           0x00001000    /* RX Frame Complete                                      */
-#define	RX_OK             0x00002000    /* RX Frame Received With No Errors                       */
-#define	RX_LONG           0x00004000    /* RX Frame Too Long Error                                */
-#define	RX_ALIGN          0x00008000    /* RX Frame Alignment Error                               */
-#define	RX_CRC            0x00010000    /* RX Frame CRC Error                                     */
-#define	RX_LEN            0x00020000    /* RX Frame Length Error                                  */
-#define	RX_FRAG           0x00040000    /* RX Frame Fragment Error                                */
-#define	RX_ADDR           0x00080000    /* RX Frame Address Filter Failed Error                   */
-#define	RX_DMAO           0x00100000    /* RX Frame DMA Overrun Error                             */
-#define	RX_PHY            0x00200000    /* RX Frame PHY Error                                     */
-#define	RX_LATE           0x00400000    /* RX Frame Late Collision Error                          */
-#define	RX_RANGE          0x00800000    /* RX Frame Length Field Out of Range Error               */
-#define	RX_MULTI          0x01000000    /* RX Multicast Frame Indicator                           */
-#define	RX_BROAD          0x02000000    /* RX Broadcast Frame Indicator                           */
-#define	RX_CTL            0x04000000    /* RX Control Frame Indicator                             */
-#define	RX_UCTL           0x08000000    /* Unsupported RX Control Frame Indicator                 */
-#define	RX_TYPE           0x10000000    /* RX Typed Frame Indicator                               */
-#define	RX_VLAN1          0x20000000    /* RX VLAN1 Frame Indicator                               */
-#define	RX_VLAN2          0x40000000    /* RX VLAN2 Frame Indicator                               */
-#define	RX_ACCEPT         0x80000000    /* RX Frame Accepted Indicator                            */
-
-/*  EMAC_TX_STAT, EMAC_TX_STKY, and EMAC_TX_IRQE Masks  */
-
-#define	TX_COMP           0x00000001    /* TX Frame Complete                                      */
-#define	TX_OK             0x00000002    /* TX Frame Sent With No Errors                           */
-#define	TX_ECOLL          0x00000004    /* TX Frame Excessive Collision Error                     */
-#define	TX_LATE           0x00000008    /* TX Frame Late Collision Error                          */
-#define	TX_DMAU           0x00000010    /* TX Frame DMA Underrun Error (STAT)                     */
-#define	TX_MACE           0x00000010    /* Internal MAC Error Detected (STKY and IRQE)            */
-#define	TX_EDEFER         0x00000020    /* TX Frame Excessive Deferral Error                      */
-#define	TX_BROAD          0x00000040    /* TX Broadcast Frame Indicator                           */
-#define	TX_MULTI          0x00000080    /* TX Multicast Frame Indicator                           */
-#define	TX_CCNT           0x00000F00    /* TX Frame Collision Count                               */
-#define	TX_DEFER          0x00001000    /* TX Frame Deferred Indicator                            */
-#define	TX_CRS            0x00002000    /* TX Frame Carrier Sense Not Asserted Error              */
-#define	TX_LOSS           0x00004000    /* TX Frame Carrier Lost During TX Error                  */
-#define	TX_RETRY          0x00008000    /* TX Frame Successful After Retry                        */
-#define	TX_FRLEN          0x07FF0000    /* TX Frame Length (Bytes)                                */
-
-/* EMAC_MMC_CTL Masks */
-#define	RSTC              0x00000001    /* Reset All Counters                                     */
-#define	CROLL             0x00000002    /* Counter Roll-Over Enable                               */
-#define	CCOR              0x00000004    /* Counter Clear-On-Read Mode Enable                      */
-#define	MMCE              0x00000008    /* Enable MMC Counter Operation                           */
-
-/* EMAC_MMC_RIRQS and EMAC_MMC_RIRQE Masks */
-#define	RX_OK_CNT         0x00000001    /* RX Frames Received With No Errors                      */
-#define	RX_FCS_CNT        0x00000002    /* RX Frames W/Frame Check Sequence Errors                */
-#define	RX_ALIGN_CNT      0x00000004    /* RX Frames With Alignment Errors                        */
-#define	RX_OCTET_CNT      0x00000008    /* RX Octets Received OK                                  */
-#define	RX_LOST_CNT       0x00000010    /* RX Frames Lost Due To Internal MAC RX Error            */
-#define	RX_UNI_CNT        0x00000020    /* Unicast RX Frames Received OK                          */
-#define	RX_MULTI_CNT      0x00000040    /* Multicast RX Frames Received OK                        */
-#define	RX_BROAD_CNT      0x00000080    /* Broadcast RX Frames Received OK                        */
-#define	RX_IRL_CNT        0x00000100    /* RX Frames With In-Range Length Errors                  */
-#define	RX_ORL_CNT        0x00000200    /* RX Frames With Out-Of-Range Length Errors              */
-#define	RX_LONG_CNT       0x00000400    /* RX Frames With Frame Too Long Errors                   */
-#define	RX_MACCTL_CNT     0x00000800    /* MAC Control RX Frames Received                         */
-#define	RX_OPCODE_CTL     0x00001000    /* Unsupported Op-Code RX Frames Received                 */
-#define	RX_PAUSE_CNT      0x00002000    /* PAUSEMAC Control RX Frames Received                    */
-#define	RX_ALLF_CNT       0x00004000    /* All RX Frames Received                                 */
-#define	RX_ALLO_CNT       0x00008000    /* All RX Octets Received                                 */
-#define	RX_TYPED_CNT      0x00010000    /* Typed RX Frames Received                               */
-#define	RX_SHORT_CNT      0x00020000    /* RX Frame Fragments (< 64 Bytes) Received               */
-#define	RX_EQ64_CNT       0x00040000    /* 64-Byte RX Frames Received                             */
-#define	RX_LT128_CNT      0x00080000    /* 65-127-Byte RX Frames Received                         */
-#define	RX_LT256_CNT      0x00100000    /* 128-255-Byte RX Frames Received                        */
-#define	RX_LT512_CNT      0x00200000    /* 256-511-Byte RX Frames Received                        */
-#define	RX_LT1024_CNT     0x00400000    /* 512-1023-Byte RX Frames Received                       */
-#define	RX_GE1024_CNT     0x00800000    /* 1024-Max-Byte RX Frames Received                       */
-
-/* EMAC_MMC_TIRQS and EMAC_MMC_TIRQE Masks  */
-
-#define	TX_OK_CNT         0x00000001    /* TX Frames Sent OK                                      */
-#define	TX_SCOLL_CNT      0x00000002    /* TX Frames With Single Collisions                       */
-#define	TX_MCOLL_CNT      0x00000004    /* TX Frames With Multiple Collisions                     */
-#define	TX_OCTET_CNT      0x00000008    /* TX Octets Sent OK                                      */
-#define	TX_DEFER_CNT      0x00000010    /* TX Frames With Deferred Transmission                   */
-#define	TX_LATE_CNT       0x00000020    /* TX Frames With Late Collisions                         */
-#define	TX_ABORTC_CNT     0x00000040    /* TX Frames Aborted Due To Excess Collisions             */
-#define	TX_LOST_CNT       0x00000080    /* TX Frames Lost Due To Internal MAC TX Error            */
-#define	TX_CRS_CNT        0x00000100    /* TX Frames With Carrier Sense Errors                    */
-#define	TX_UNI_CNT        0x00000200    /* Unicast TX Frames Sent                                 */
-#define	TX_MULTI_CNT      0x00000400    /* Multicast TX Frames Sent                               */
-#define	TX_BROAD_CNT      0x00000800    /* Broadcast TX Frames Sent                               */
-#define	TX_EXDEF_CTL      0x00001000    /* TX Frames With Excessive Deferral                      */
-#define	TX_MACCTL_CNT     0x00002000    /* MAC Control TX Frames Sent                             */
-#define	TX_ALLF_CNT       0x00004000    /* All TX Frames Sent                                     */
-#define	TX_ALLO_CNT       0x00008000    /* All TX Octets Sent                                     */
-#define	TX_EQ64_CNT       0x00010000    /* 64-Byte TX Frames Sent                                 */
-#define	TX_LT128_CNT      0x00020000    /* 65-127-Byte TX Frames Sent                             */
-#define	TX_LT256_CNT      0x00040000    /* 128-255-Byte TX Frames Sent                            */
-#define	TX_LT512_CNT      0x00080000    /* 256-511-Byte TX Frames Sent                            */
-#define	TX_LT1024_CNT     0x00100000    /* 512-1023-Byte TX Frames Sent                           */
-#define	TX_GE1024_CNT     0x00200000    /* 1024-Max-Byte TX Frames Sent                           */
-#define	TX_ABORT_CNT      0x00400000    /* TX Frames Aborted                                      */
-
-/* SDH Registers */
-
-#define SDH_PWR_CTL                    0xFFC03900 /* SDH Power Control */
-#define SDH_CLK_CTL                    0xFFC03904 /* SDH Clock Control */
-#define SDH_ARGUMENT                   0xFFC03908 /* SDH Argument */
-#define SDH_COMMAND                    0xFFC0390C /* SDH Command */
-#define SDH_RESP_CMD                   0xFFC03910 /* SDH Response Command */
-#define SDH_RESPONSE0                  0xFFC03914 /* SDH Response0 */
-#define SDH_RESPONSE1                  0xFFC03918 /* SDH Response1 */
-#define SDH_RESPONSE2                  0xFFC0391C /* SDH Response2 */
-#define SDH_RESPONSE3                  0xFFC03920 /* SDH Response3 */
-#define SDH_DATA_TIMER                 0xFFC03924 /* SDH Data Timer */
-#define SDH_DATA_LGTH                  0xFFC03928 /* SDH Data Length */
-#define SDH_DATA_CTL                   0xFFC0392C /* SDH Data Control */
-#define SDH_DATA_CNT                   0xFFC03930 /* SDH Data Counter */
-#define SDH_STATUS                     0xFFC03934 /* SDH Status */
-#define SDH_STATUS_CLR                 0xFFC03938 /* SDH Status Clear */
-#define SDH_MASK0                      0xFFC0393C /* SDH Interrupt0 Mask */
-#define SDH_MASK1                      0xFFC03940 /* SDH Interrupt1 Mask */
-#define SDH_FIFO_CNT                   0xFFC03948 /* SDH FIFO Counter */
-#define SDH_FIFO                       0xFFC03980 /* SDH Data FIFO */
-#define SDH_E_STATUS                   0xFFC039C0 /* SDH Exception Status */
-#define SDH_E_MASK                     0xFFC039C4 /* SDH Exception Mask */
-#define SDH_CFG                        0xFFC039C8 /* SDH Configuration */
-#define SDH_RD_WAIT_EN                 0xFFC039CC /* SDH Read Wait Enable */
-#define SDH_PID0                       0xFFC039D0 /* SDH Peripheral Identification0 */
-#define SDH_PID1                       0xFFC039D4 /* SDH Peripheral Identification1 */
-#define SDH_PID2                       0xFFC039D8 /* SDH Peripheral Identification2 */
-#define SDH_PID3                       0xFFC039DC /* SDH Peripheral Identification3 */
-#define SDH_PID4                       0xFFC039E0 /* SDH Peripheral Identification4 */
-#define SDH_PID5                       0xFFC039E4 /* SDH Peripheral Identification5 */
-#define SDH_PID6                       0xFFC039E8 /* SDH Peripheral Identification6 */
-#define SDH_PID7                       0xFFC039EC /* SDH Peripheral Identification7 */
-
-/* Removable Storage Interface Registers */
-
-#define RSI_PWR_CONTROL                0xFFC03800 /* RSI Power Control Register */
-#define RSI_CLK_CONTROL                0xFFC03804 /* RSI Clock Control Register */
-#define RSI_ARGUMENT                   0xFFC03808 /* RSI Argument Register */
-#define RSI_COMMAND                    0xFFC0380C /* RSI Command Register */
-#define RSI_RESP_CMD                   0xFFC03810 /* RSI Response Command Register */
-#define RSI_RESPONSE0                  0xFFC03814 /* RSI Response Register */
-#define RSI_RESPONSE1                  0xFFC03818 /* RSI Response Register */
-#define RSI_RESPONSE2                  0xFFC0381C /* RSI Response Register */
-#define RSI_RESPONSE3                  0xFFC03820 /* RSI Response Register */
-#define RSI_DATA_TIMER                 0xFFC03824 /* RSI Data Timer Register */
-#define RSI_DATA_LGTH                  0xFFC03828 /* RSI Data Length Register */
-#define RSI_DATA_CONTROL               0xFFC0382C /* RSI Data Control Register */
-#define RSI_DATA_CNT                   0xFFC03830 /* RSI Data Counter Register */
-#define RSI_STATUS                     0xFFC03834 /* RSI Status Register */
-#define RSI_STATUSCL                   0xFFC03838 /* RSI Status Clear Register */
-#define RSI_MASK0                      0xFFC0383C /* RSI Interrupt 0 Mask Register */
-#define RSI_MASK1                      0xFFC03840 /* RSI Interrupt 1 Mask Register */
-#define RSI_FIFO_CNT                   0xFFC03848 /* RSI FIFO Counter Register */
-#define RSI_CEATA_CONTROL              0xFFC0384C /* RSI CEATA Register */
-#define RSI_FIFO                       0xFFC03880 /* RSI Data FIFO Register */
-#define RSI_ESTAT                      0xFFC038C0 /* RSI Exception Status Register */
-#define RSI_EMASK                      0xFFC038C4 /* RSI Exception Mask Register */
-#define RSI_CONFIG                     0xFFC038C8 /* RSI Configuration Register */
-#define RSI_RD_WAIT_EN                 0xFFC038CC /* RSI Read Wait Enable Register */
-#define RSI_PID0                       0xFFC03FE0 /* RSI Peripheral ID Register 0 */
-#define RSI_PID1                       0xFFC03FE4 /* RSI Peripheral ID Register 1 */
-#define RSI_PID2                       0xFFC03FE8 /* RSI Peripheral ID Register 2 */
-#define RSI_PID3                       0xFFC03FEC /* RSI Peripheral ID Register 3 */
-#define RSI_PID4                       0xFFC03FF0 /* RSI Peripheral ID Register 4 */
-#define RSI_PID5                       0xFFC03FF4 /* RSI Peripheral ID Register 5 */
-#define RSI_PID6                       0xFFC03FF8 /* RSI Peripheral ID Register 6 */
-#define RSI_PID7                       0xFFC03FFC /* RSI Peripheral ID Register 7 */
+/* BF518 is BF516 + IEEE-1588 */
+#include "defBF516.h"
 
 /* PTP TSYNC Registers */
 
@@ -489,141 +36,6 @@
 #define EMAC_PTP_PPS_STARTHI           0xFFC030F4 /* PPS Start Time High */
 #define EMAC_PTP_PPS_PERIOD            0xFFC030F8 /* PPS Count Register */
 
-/* ********************************************************** */
-/*     SINGLE BIT MACRO PAIRS (bit mask and negated one)      */
-/*     and MULTI BIT READ MACROS                              */
-/* ********************************************************** */
-
-/* Bit masks for SDH_COMMAND */
-
-#define                   CMD_IDX  0x3f       /* Command Index */
-#define                   CMD_RSP  0x40       /* Response */
-#define                 CMD_L_RSP  0x80       /* Long Response */
-#define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                CMD_PEND_E  0x200      /* Command Pending */
-#define                     CMD_E  0x400      /* Command Enable */
-
-/* Bit masks for SDH_PWR_CTL */
-
-#define                    PWR_ON  0x3        /* Power On */
-#if 0
-#define                       TBD  0x3c       /* TBD */
-#endif
-#define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                   ROD_CTL  0x80       /* Rod Control */
-
-/* Bit masks for SDH_CLK_CTL */
-
-#define                    CLKDIV  0xff       /* MC_CLK Divisor */
-#define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-
-/* Bit masks for SDH_RESP_CMD */
-
-#define                  RESP_CMD  0x3f       /* Response Command */
-
-/* Bit masks for SDH_DATA_CTL */
-
-#define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
-
-/* Bit masks for SDH_STATUS */
-
-#define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
-#define               DAT_TIME_OUT  0x8        /* Data Time Out */
-#define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define              CMD_RESP_END  0x40       /* CMD Response End */
-#define                  CMD_SENT  0x80       /* CMD Sent */
-#define                   DAT_END  0x100      /* Data End */
-#define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define               DAT_BLK_END  0x400      /* Data Block End */
-#define                   CMD_ACT  0x800      /* CMD Active */
-#define                    TX_ACT  0x1000     /* Transmit Active */
-#define                    RX_ACT  0x2000     /* Receive Active */
-#define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-
-/* Bit masks for SDH_STATUS_CLR */
-
-#define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define              DAT_END_STAT  0x100      /* Data End Status */
-#define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-
-/* Bit masks for SDH_MASK0 */
-
-#define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define              DAT_END_MASK  0x100      /* Data End Mask */
-#define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-
-/* Bit masks for SDH_FIFO_CNT */
-
-#define                FIFO_COUNT  0x7fff     /* FIFO Count */
-
-/* Bit masks for SDH_E_STATUS */
-
-#define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define               SD_CARD_DET  0x10       /* SD Card Detect */
-
-/* Bit masks for SDH_E_MASK */
-
-#define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                   SCD_MSK  0x40       /* Mask Card Detect */
-
-/* Bit masks for SDH_CFG */
-
-#define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                       MWE  0x8        /* Moving Window Enable */
-#define                    SD_RST  0x10       /* SDMMC Reset */
-#define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-
-/* Bit masks for SDH_RD_WAIT_EN */
-
-#define                       RWR  0x1        /* Read Wait Request */
-
 /* Bit masks for EMAC_PTP_CTL */
 
 #define                    PTP_EN  0x1        /* Enable the PTP_TSYNC module */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -542,7 +542,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register					*/
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register				*/
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register				*/
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register		*/
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register		*/
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register	*/
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register				*/
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register				*/
@@ -550,7 +550,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register					*/
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register				*/
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register				*/
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register		*/
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register		*/
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register	*/
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register				*/
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register				*/
@@ -585,58 +585,6 @@
 **				modifier UNLESS the lower order bits are saved and ORed back in when
 **				the macro is used.
 *************************************************************************************/
-/*
-** ********************* PLL AND RESET MASKS ****************************************/
-/* PLL_CTL Masks																	*/
-#define DF				0x0001	/* 0: PLL = CLKIN, 1: PLL = CLKIN/2					*/
-#define PLL_OFF			0x0002	/* PLL Not Powered									*/
-#define STOPCK			0x0008	/* Core Clock Off									*/
-#define PDWN			0x0020	/* Enter Deep Sleep Mode							*/
-#define	IN_DELAY		0x0040	/* Add 200ps Delay To EBIU Input Latches			*/
-#define	OUT_DELAY		0x0080	/* Add 200ps Delay To EBIU Output Signals			*/
-#define BYPASS			0x0100	/* Bypass the PLL									*/
-#define	MSEL			0x7E00	/* Multiplier Select For CCLK/VCO Factors			*/
-/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits)			*/
-#define	SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL		*/
-
-/* PLL_DIV Masks														*/
-#define SSEL			0x000F	/* System Select						*/
-#define	CSEL			0x0030	/* Core Select							*/
-#define CSEL_DIV1		0x0000	/* 		CCLK = VCO / 1					*/
-#define CSEL_DIV2		0x0010	/* 		CCLK = VCO / 2					*/
-#define	CSEL_DIV4		0x0020	/* 		CCLK = VCO / 4					*/
-#define	CSEL_DIV8		0x0030	/* 		CCLK = VCO / 8					*/
-/* PLL_DIV Macros														*/
-#define SET_SSEL(x)		((x)&0xF)		/* Set SSEL = 0-15 --> SCLK = VCO/SSEL	*/
-
-/* VR_CTL Masks	*/
-#define	FREQ			0x3000	/* Switching Oscillator Frequency For Regulator	*/
-#define	HIBERNATE		0x0000	/* 		Powerdown/Bypass On-Board Regulation	*/
-
-#define	VLEV			0x00F0	/* Internal Voltage Level					*/
-#define	VLEV_085 		0x0060	/* 		VLEV = 0.85 V (-5% - +10% Accuracy)	*/
-#define	VLEV_090		0x0070	/* 		VLEV = 0.90 V (-5% - +10% Accuracy)	*/
-#define	VLEV_095		0x0080	/* 		VLEV = 0.95 V (-5% - +10% Accuracy)	*/
-#define	VLEV_100		0x0090	/* 		VLEV = 1.00 V (-5% - +10% Accuracy)	*/
-#define	VLEV_105		0x00A0	/* 		VLEV = 1.05 V (-5% - +10% Accuracy)	*/
-#define	VLEV_110		0x00B0	/* 		VLEV = 1.10 V (-5% - +10% Accuracy)	*/
-#define	VLEV_115		0x00C0	/* 		VLEV = 1.15 V (-5% - +10% Accuracy)	*/
-#define	VLEV_120		0x00D0	/* 		VLEV = 1.20 V (-5% - +10% Accuracy)	*/
-#define	VLEV_125		0x00E0	/* 		VLEV = 1.25 V (-5% - +10% Accuracy)	*/
-#define	VLEV_130		0x00F0	/* 		VLEV = 1.30 V (-5% - +10% Accuracy)	*/
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate	*/
-#define	USBWE			0x0200	/* Enable USB Wakeup From Hibernate			*/
-#define	PHYWE			0x0400	/* Enable PHY Wakeup From Hibernate			*/
-#define	CLKBUFOE		0x4000	/* CLKIN Buffer Output Enable */
-#define	PHYCLKOE		CLKBUFOE	/* Alternative legacy name for the above */
-#define	SCKELOW		0x8000	/* Enable Drive CKE Low During Reset		*/
-
-/* PLL_STAT Masks																	*/
-#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled	*/
-#define	FULL_ON				0x0002	/* Processor In Full On Mode					*/
-#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled	*/
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been Reached					*/
 
 /* CHIPID Masks */
 #define CHIPID_VERSION         0xF0000000
@@ -756,66 +704,6 @@
 #define IWR_DISABLE(x)	(0xFFFFFFFF ^ (1 << ((x)&0x1F))) 	/* Wakeup Disable Peripheral #x		*/
 
 
-/* ********* WATCHDOG TIMER MASKS ******************** */
-
-/* Watchdog Timer WDOG_CTL Register Masks */
-
-#define WDEV(x) (((x)<<1) & 0x0006) /* event generated on roll over */
-#define WDEV_RESET 0x0000 /* generate reset event on roll over */
-#define WDEV_NMI 0x0002 /* generate NMI event on roll over */
-#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */
-#define WDEV_NONE 0x0006 /* no event on roll over */
-#define WDEN 0x0FF0 /* enable watchdog */
-#define WDDIS 0x0AD0 /* disable watchdog */
-#define WDRO 0x8000 /* watchdog rolled over latch */
-
-/* depreciated WDOG_CTL Register Masks for legacy code */
-
-
-#define ICTL WDEV
-#define ENABLE_RESET WDEV_RESET
-#define WDOG_RESET WDEV_RESET
-#define ENABLE_NMI WDEV_NMI
-#define WDOG_NMI WDEV_NMI
-#define ENABLE_GPI WDEV_GPI
-#define WDOG_GPI WDEV_GPI
-#define DISABLE_EVT WDEV_NONE
-#define WDOG_NONE WDEV_NONE
-
-#define TMR_EN WDEN
-#define TMR_DIS WDDIS
-#define TRO WDRO
-#define ICTL_P0 0x01
- #define ICTL_P1 0x02
-#define TRO_P 0x0F
-
-
-
-/* ***************  REAL TIME CLOCK MASKS  **************************/
-/* RTC_STAT and RTC_ALARM Masks										*/
-#define	RTC_SEC				0x0000003F	/* Real-Time Clock Seconds	*/
-#define	RTC_MIN				0x00000FC0	/* Real-Time Clock Minutes	*/
-#define	RTC_HR				0x0001F000	/* Real-Time Clock Hours	*/
-#define	RTC_DAY				0xFFFE0000	/* Real-Time Clock Days		*/
-
-/* RTC_ALARM Macro			z=day		y=hr	x=min	w=sec		*/
-#define SET_ALARM(z,y,x,w)	((((z)&0x7FFF)<<0x11)|(((y)&0x1F)<<0xC)|(((x)&0x3F)<<0x6)|((w)&0x3F))
-
-/* RTC_ICTL and RTC_ISTAT Masks																		*/
-#define	STOPWATCH			0x0001		/* Stopwatch Interrupt Enable								*/
-#define	ALARM				0x0002		/* Alarm Interrupt Enable									*/
-#define	SECOND				0x0004		/* Seconds (1 Hz) Interrupt Enable							*/
-#define	MINUTE				0x0008		/* Minutes Interrupt Enable									*/
-#define	HOUR				0x0010		/* Hours Interrupt Enable									*/
-#define	DAY					0x0020		/* 24 Hours (Days) Interrupt Enable							*/
-#define	DAY_ALARM			0x0040		/* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable	*/
-#define	WRITE_PENDING		0x4000		/* Write Pending Status										*/
-#define	WRITE_COMPLETE		0x8000		/* Write Complete Interrupt Enable							*/
-
-/* RTC_FAST / RTC_PREN Mask												*/
-#define PREN				0x0001	/* Enable Prescaler, RTC Runs @1 Hz	*/
-
-
 /* ************** UART CONTROLLER MASKS *************************/
 /* UARTx_LCR Masks												*/
 #define WLS(x)		(((x)-5) & 0x03)	/* Word Length Select */
@@ -1372,33 +1260,6 @@
 
 
 /* **************************  DMA CONTROLLER MASKS  ********************************/
-/* DMAx_CONFIG, MDMA_yy_CONFIG Masks												*/
-#define DMAEN			0x0001		/* DMA Channel Enable							*/
-#define WNR				0x0002		/* Channel Direction (W/R*)						*/
-#define WDSIZE_8		0x0000		/* Transfer Word Size = 8						*/
-#define WDSIZE_16		0x0004		/* Transfer Word Size = 16						*/
-#define WDSIZE_32		0x0008		/* Transfer Word Size = 32						*/
-#define DMA2D			0x0010		/* DMA Mode (2D/1D*)							*/
-#define RESTART			0x0020		/* DMA Buffer Clear								*/
-#define DI_SEL			0x0040		/* Data Interrupt Timing Select					*/
-#define DI_EN			0x0080		/* Data Interrupt Enable						*/
-#define NDSIZE_0		0x0000		/* Next Descriptor Size = 0 (Stop/Autobuffer)	*/
-#define NDSIZE_1		0x0100		/* Next Descriptor Size = 1						*/
-#define NDSIZE_2		0x0200		/* Next Descriptor Size = 2						*/
-#define NDSIZE_3		0x0300		/* Next Descriptor Size = 3						*/
-#define NDSIZE_4		0x0400		/* Next Descriptor Size = 4						*/
-#define NDSIZE_5		0x0500		/* Next Descriptor Size = 5						*/
-#define NDSIZE_6		0x0600		/* Next Descriptor Size = 6						*/
-#define NDSIZE_7		0x0700		/* Next Descriptor Size = 7						*/
-#define NDSIZE_8		0x0800		/* Next Descriptor Size = 8						*/
-#define NDSIZE_9		0x0900		/* Next Descriptor Size = 9						*/
-#define NDSIZE	        	0x0900	/* Next Descriptor Size */
-#define DMAFLOW	        	0x7000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000		/* Stop Mode									*/
-#define DMAFLOW_AUTO		0x1000		/* Autobuffer Mode								*/
-#define DMAFLOW_ARRAY		0x4000		/* Descriptor Array Mode						*/
-#define DMAFLOW_SMALL		0x6000		/* Small Model Descriptor List Mode				*/
-#define DMAFLOW_LARGE		0x7000		/* Large Model Descriptor List Mode				*/
 
 /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks								*/
 #define CTYPE			0x0040	/* DMA Channel Type Indicator (Memory/Peripheral*)	*/
@@ -1416,13 +1277,6 @@
 #define	PMAP_UART1RX	0xA000	/* 		UART1 Port Receive DMA						*/
 #define	PMAP_UART1TX	0xB000	/* 		UART1 Port Transmit DMA						*/
 
-/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks						*/
-#define DMA_DONE		0x0001	/* DMA Completion Interrupt Status	*/
-#define DMA_ERR			0x0002	/* DMA Error Interrupt Status		*/
-#define DFETCH			0x0004	/* DMA Descriptor Fetch Indicator	*/
-#define DMA_RUN			0x0008	/* DMA Channel Running Indicator	*/
-
-
 /*  ************  PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
 /*  PPI_CONTROL Masks													*/
 #define PORT_EN			0x0001		/* PPI Port Enable					*/
@@ -1830,46 +1684,6 @@
 #define BNDMODE_CAPT     0x2000  /* boundary capture mode */
 #define BNDMODE_AEXT     0x3000  /* boundary auto-extend mode */
 
-/* Bit masks for OTP_CONTROL */
-
-#define                FUSE_FADDR  0x1ff      /* OTP/Fuse Address */
-#define                      FIEN  0x800      /* OTP/Fuse Interrupt Enable */
-#define                     nFIEN  0x0
-#define                  FTESTDEC  0x1000     /* OTP/Fuse Test Decoder */
-#define                 nFTESTDEC  0x0
-#define                   FWRTEST  0x2000     /* OTP/Fuse Write Test */
-#define                  nFWRTEST  0x0
-#define                     FRDEN  0x4000     /* OTP/Fuse Read Enable */
-#define                    nFRDEN  0x0
-#define                     FWREN  0x8000     /* OTP/Fuse Write Enable */
-#define                    nFWREN  0x0
-
-/* Bit masks for OTP_BEN */
-
-#define                      FBEN  0xffff     /* OTP/Fuse Byte Enable */
-
-/* Bit masks for OTP_STATUS */
-
-#define                     FCOMP  0x1        /* OTP/Fuse Access Complete */
-#define                    nFCOMP  0x0
-#define                    FERROR  0x2        /* OTP/Fuse Access Error */
-#define                   nFERROR  0x0
-#define                  MMRGLOAD  0x10       /* Memory Mapped Register Gasket Load */
-#define                 nMMRGLOAD  0x0
-#define                  MMRGLOCK  0x20       /* Memory Mapped Register Gasket Lock */
-#define                 nMMRGLOCK  0x0
-#define                    FPGMEN  0x40       /* OTP/Fuse Program Enable */
-#define                   nFPGMEN  0x0
-
-/* Bit masks for OTP_TIMING */
-
-#define                   USECDIV  0xff       /* Micro Second Divider */
-#define                   READACC  0x7f00     /* Read Access Time */
-#define                   CPUMPRL  0x38000    /* Charge Pump Release Time */
-#define                   CPUMPSU  0xc0000    /* Charge Pump Setup Time */
-#define                   CPUMPHD  0xf00000   /* Charge Pump Hold Time */
-#define                   PGMTIME  0xff000000 /* Program Time */
-
 /* Bit masks for SECURE_SYSSWT */
 
 #define                   EMUDABL  0x1        /* Emulation Disable. */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/Kconfig linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/Kconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf518/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf518/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,7 @@
+config BF51x
+	def_bool y
+	depends on (BF512 || BF514 || BF516 || BF518)
+
 if (BF51x)
 
 source "arch/blackfin/mach-bf518/boards/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/cm_bf527.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,6 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/etherdevice.h>
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-#include <linux/usb/isp1362.h>
-#endif
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -65,7 +62,7 @@ static struct isp1760_platform_data isp1
 };
 
 static struct platform_device bfin_isp1760_device = {
-	.name           = "isp1760-hcd",
+	.name           = "isp1760",
 	.id             = 0,
 	.dev = {
 		.platform_data = &isp1760_priv,
@@ -317,45 +314,6 @@ static struct platform_device sl811_hcd_
 };
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-static struct resource isp1362_hcd_resources[] = {
-	{
-		.start = 0x20360000,
-		.end = 0x20360000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20360004,
-		.end = 0x20360004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-static struct isp1362_platform_data isp1362_priv = {
-	.sel15Kres = 1,
-	.clknotstop = 0,
-	.oc_enable = 0,
-	.int_act_high = 0,
-	.int_edge_triggered = 0,
-	.remote_wakeup_connected = 0,
-	.no_power_switching = 1,
-	.power_switching_mode = 0,
-};
-
-static struct platform_device isp1362_hcd_device = {
-	.name = "isp1362-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &isp1362_priv,
-	},
-	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
-	.resource = isp1362_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -841,10 +799,6 @@ static struct platform_device *cmbf527_d
 	&sl811_hcd_device,
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-	&isp1362_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 	&bfin_isp1760_device,
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,9 +13,6 @@
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-#include <linux/usb/isp1362.h>
-#endif
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -63,7 +60,7 @@ static struct isp1760_platform_data isp1
 };
 
 static struct platform_device bfin_isp1760_device = {
-	.name           = "isp1760-hcd",
+	.name           = "isp1760",
 	.id             = 0,
 	.dev = {
 		.platform_data = &isp1760_priv,
@@ -373,45 +370,6 @@ static struct platform_device sl811_hcd_
 };
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-static struct resource isp1362_hcd_resources[] = {
-	{
-		.start = 0x20360000,
-		.end = 0x20360000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20360004,
-		.end = 0x20360004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-static struct isp1362_platform_data isp1362_priv = {
-	.sel15Kres = 1,
-	.clknotstop = 0,
-	.oc_enable = 0,
-	.int_act_high = 0,
-	.int_edge_triggered = 0,
-	.remote_wakeup_connected = 0,
-	.no_power_switching = 1,
-	.power_switching_mode = 0,
-};
-
-static struct platform_device isp1362_hcd_device = {
-	.name = "isp1362-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &isp1362_priv,
-	},
-	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
-	.resource = isp1362_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -688,12 +646,6 @@ static struct platform_device bfin_spi0_
 };
 #endif  /* spi master and devices */
 
-#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
-static struct platform_device bfin_fb_device = {
-	.name = "bf537-lq035",
-};
-#endif
-
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
@@ -850,7 +802,7 @@ static struct platform_device bfin_devic
 };
 #endif
 
-#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE)
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
 #include <linux/input.h>
 #include <asm/bfin_rotary.h>
 
@@ -924,10 +876,6 @@ static struct platform_device *stamp_dev
 	&sl811_hcd_device,
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-	&isp1362_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 	&bfin_isp1760_device,
 #endif
@@ -957,10 +905,6 @@ static struct platform_device *stamp_dev
 	&bfin_spi0_device,
 #endif
 
-#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
-	&bfin_fb_device,
-#endif
-
 #if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE)
 	&bf52x_t350mcqb_device,
 #endif
@@ -991,7 +935,7 @@ static struct platform_device *stamp_dev
 	&bfin_device_gpiokeys,
 #endif
 
-#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE)
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
 	&bfin_rotary_device,
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h	2010-02-24 13:52:17.000000000 -0500
@@ -46,10 +46,4 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* PLL_DIV Masks													*/
-#define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
-#define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
-#define CCLK_DIV4 CSEL_DIV4	/*          CCLK = VCO / 4                                  */
-#define CCLK_DIV8 CSEL_DIV8	/*          CCLK = VCO / 8                                  */
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF525.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF525.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF525.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,15 +10,8 @@
 /* include all Core registers and bit definitions */
 #include "defBF525.h"
 
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF525 */
-
-/* include cdefBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "cdefBF52x_base.h"
-
-/* The following are the #defines needed by ADSP-BF525 that are not in the common header */
+/* BF525 is BF522 + USB */
+#include "cdefBF522.h"
 
 /* USB Control Registers */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF527.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF527.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF527.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,15 +10,8 @@
 /* include all Core registers and bit definitions */
 #include "defBF527.h"
 
-/* include core specific register pointer definitions */
-#include <asm/cdef_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */
-
-/* include cdefBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "cdefBF52x_base.h"
-
-/* The following are the #defines needed by ADSP-BF527 that are not in the common header */
+/* BF527 is BF525 + EMAC */
+#include "cdefBF525.h"
 
 /* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
 
@@ -185,417 +178,4 @@
 #define bfin_read_EMAC_TXC_ABORT()		bfin_read32(EMAC_TXC_ABORT)
 #define bfin_write_EMAC_TXC_ABORT(val)		bfin_write32(EMAC_TXC_ABORT, val)
 
-/* USB Control Registers */
-
-#define bfin_read_USB_FADDR()			bfin_read16(USB_FADDR)
-#define bfin_write_USB_FADDR(val)		bfin_write16(USB_FADDR, val)
-#define bfin_read_USB_POWER()			bfin_read16(USB_POWER)
-#define bfin_write_USB_POWER(val)		bfin_write16(USB_POWER, val)
-#define bfin_read_USB_INTRTX()			bfin_read16(USB_INTRTX)
-#define bfin_write_USB_INTRTX(val)		bfin_write16(USB_INTRTX, val)
-#define bfin_read_USB_INTRRX()			bfin_read16(USB_INTRRX)
-#define bfin_write_USB_INTRRX(val)		bfin_write16(USB_INTRRX, val)
-#define bfin_read_USB_INTRTXE()			bfin_read16(USB_INTRTXE)
-#define bfin_write_USB_INTRTXE(val)		bfin_write16(USB_INTRTXE, val)
-#define bfin_read_USB_INTRRXE()			bfin_read16(USB_INTRRXE)
-#define bfin_write_USB_INTRRXE(val)		bfin_write16(USB_INTRRXE, val)
-#define bfin_read_USB_INTRUSB()			bfin_read16(USB_INTRUSB)
-#define bfin_write_USB_INTRUSB(val)		bfin_write16(USB_INTRUSB, val)
-#define bfin_read_USB_INTRUSBE()		bfin_read16(USB_INTRUSBE)
-#define bfin_write_USB_INTRUSBE(val)		bfin_write16(USB_INTRUSBE, val)
-#define bfin_read_USB_FRAME()			bfin_read16(USB_FRAME)
-#define bfin_write_USB_FRAME(val)		bfin_write16(USB_FRAME, val)
-#define bfin_read_USB_INDEX()			bfin_read16(USB_INDEX)
-#define bfin_write_USB_INDEX(val)		bfin_write16(USB_INDEX, val)
-#define bfin_read_USB_TESTMODE()		bfin_read16(USB_TESTMODE)
-#define bfin_write_USB_TESTMODE(val)		bfin_write16(USB_TESTMODE, val)
-#define bfin_read_USB_GLOBINTR()		bfin_read16(USB_GLOBINTR)
-#define bfin_write_USB_GLOBINTR(val)		bfin_write16(USB_GLOBINTR, val)
-#define bfin_read_USB_GLOBAL_CTL()		bfin_read16(USB_GLOBAL_CTL)
-#define bfin_write_USB_GLOBAL_CTL(val)		bfin_write16(USB_GLOBAL_CTL, val)
-
-/* USB Packet Control Registers */
-
-#define bfin_read_USB_TX_MAX_PACKET()		bfin_read16(USB_TX_MAX_PACKET)
-#define bfin_write_USB_TX_MAX_PACKET(val)	bfin_write16(USB_TX_MAX_PACKET, val)
-#define bfin_read_USB_CSR0()			bfin_read16(USB_CSR0)
-#define bfin_write_USB_CSR0(val)		bfin_write16(USB_CSR0, val)
-#define bfin_read_USB_TXCSR()			bfin_read16(USB_TXCSR)
-#define bfin_write_USB_TXCSR(val)		bfin_write16(USB_TXCSR, val)
-#define bfin_read_USB_RX_MAX_PACKET()		bfin_read16(USB_RX_MAX_PACKET)
-#define bfin_write_USB_RX_MAX_PACKET(val)	bfin_write16(USB_RX_MAX_PACKET, val)
-#define bfin_read_USB_RXCSR()			bfin_read16(USB_RXCSR)
-#define bfin_write_USB_RXCSR(val)		bfin_write16(USB_RXCSR, val)
-#define bfin_read_USB_COUNT0()			bfin_read16(USB_COUNT0)
-#define bfin_write_USB_COUNT0(val)		bfin_write16(USB_COUNT0, val)
-#define bfin_read_USB_RXCOUNT()			bfin_read16(USB_RXCOUNT)
-#define bfin_write_USB_RXCOUNT(val)		bfin_write16(USB_RXCOUNT, val)
-#define bfin_read_USB_TXTYPE()			bfin_read16(USB_TXTYPE)
-#define bfin_write_USB_TXTYPE(val)		bfin_write16(USB_TXTYPE, val)
-#define bfin_read_USB_NAKLIMIT0()		bfin_read16(USB_NAKLIMIT0)
-#define bfin_write_USB_NAKLIMIT0(val)		bfin_write16(USB_NAKLIMIT0, val)
-#define bfin_read_USB_TXINTERVAL()		bfin_read16(USB_TXINTERVAL)
-#define bfin_write_USB_TXINTERVAL(val)		bfin_write16(USB_TXINTERVAL, val)
-#define bfin_read_USB_RXTYPE()			bfin_read16(USB_RXTYPE)
-#define bfin_write_USB_RXTYPE(val)		bfin_write16(USB_RXTYPE, val)
-#define bfin_read_USB_RXINTERVAL()		bfin_read16(USB_RXINTERVAL)
-#define bfin_write_USB_RXINTERVAL(val)		bfin_write16(USB_RXINTERVAL, val)
-#define bfin_read_USB_TXCOUNT()			bfin_read16(USB_TXCOUNT)
-#define bfin_write_USB_TXCOUNT(val)		bfin_write16(USB_TXCOUNT, val)
-
-/* USB Endpoint FIFO Registers */
-
-#define bfin_read_USB_EP0_FIFO()		bfin_read16(USB_EP0_FIFO)
-#define bfin_write_USB_EP0_FIFO(val)		bfin_write16(USB_EP0_FIFO, val)
-#define bfin_read_USB_EP1_FIFO()		bfin_read16(USB_EP1_FIFO)
-#define bfin_write_USB_EP1_FIFO(val)		bfin_write16(USB_EP1_FIFO, val)
-#define bfin_read_USB_EP2_FIFO()		bfin_read16(USB_EP2_FIFO)
-#define bfin_write_USB_EP2_FIFO(val)		bfin_write16(USB_EP2_FIFO, val)
-#define bfin_read_USB_EP3_FIFO()		bfin_read16(USB_EP3_FIFO)
-#define bfin_write_USB_EP3_FIFO(val)		bfin_write16(USB_EP3_FIFO, val)
-#define bfin_read_USB_EP4_FIFO()		bfin_read16(USB_EP4_FIFO)
-#define bfin_write_USB_EP4_FIFO(val)		bfin_write16(USB_EP4_FIFO, val)
-#define bfin_read_USB_EP5_FIFO()		bfin_read16(USB_EP5_FIFO)
-#define bfin_write_USB_EP5_FIFO(val)		bfin_write16(USB_EP5_FIFO, val)
-#define bfin_read_USB_EP6_FIFO()		bfin_read16(USB_EP6_FIFO)
-#define bfin_write_USB_EP6_FIFO(val)		bfin_write16(USB_EP6_FIFO, val)
-#define bfin_read_USB_EP7_FIFO()		bfin_read16(USB_EP7_FIFO)
-#define bfin_write_USB_EP7_FIFO(val)		bfin_write16(USB_EP7_FIFO, val)
-
-/* USB OTG Control Registers */
-
-#define bfin_read_USB_OTG_DEV_CTL()		bfin_read16(USB_OTG_DEV_CTL)
-#define bfin_write_USB_OTG_DEV_CTL(val)		bfin_write16(USB_OTG_DEV_CTL, val)
-#define bfin_read_USB_OTG_VBUS_IRQ()		bfin_read16(USB_OTG_VBUS_IRQ)
-#define bfin_write_USB_OTG_VBUS_IRQ(val)	bfin_write16(USB_OTG_VBUS_IRQ, val)
-#define bfin_read_USB_OTG_VBUS_MASK()		bfin_read16(USB_OTG_VBUS_MASK)
-#define bfin_write_USB_OTG_VBUS_MASK(val)	bfin_write16(USB_OTG_VBUS_MASK, val)
-
-/* USB Phy Control Registers */
-
-#define bfin_read_USB_LINKINFO()		bfin_read16(USB_LINKINFO)
-#define bfin_write_USB_LINKINFO(val)		bfin_write16(USB_LINKINFO, val)
-#define bfin_read_USB_VPLEN()			bfin_read16(USB_VPLEN)
-#define bfin_write_USB_VPLEN(val)		bfin_write16(USB_VPLEN, val)
-#define bfin_read_USB_HS_EOF1()			bfin_read16(USB_HS_EOF1)
-#define bfin_write_USB_HS_EOF1(val)		bfin_write16(USB_HS_EOF1, val)
-#define bfin_read_USB_FS_EOF1()			bfin_read16(USB_FS_EOF1)
-#define bfin_write_USB_FS_EOF1(val)		bfin_write16(USB_FS_EOF1, val)
-#define bfin_read_USB_LS_EOF1()			bfin_read16(USB_LS_EOF1)
-#define bfin_write_USB_LS_EOF1(val)		bfin_write16(USB_LS_EOF1, val)
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CNTRL()		bfin_read16(USB_APHY_CNTRL)
-#define bfin_write_USB_APHY_CNTRL(val)		bfin_write16(USB_APHY_CNTRL, val)
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CALIB()		bfin_read16(USB_APHY_CALIB)
-#define bfin_write_USB_APHY_CALIB(val)		bfin_write16(USB_APHY_CALIB, val)
-
-#define bfin_read_USB_APHY_CNTRL2()		bfin_read16(USB_APHY_CNTRL2)
-#define bfin_write_USB_APHY_CNTRL2(val)		bfin_write16(USB_APHY_CNTRL2, val)
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define bfin_read_USB_PHY_TEST()		bfin_read16(USB_PHY_TEST)
-#define bfin_write_USB_PHY_TEST(val)		bfin_write16(USB_PHY_TEST, val)
-
-#define bfin_read_USB_PLLOSC_CTRL()		bfin_read16(USB_PLLOSC_CTRL)
-#define bfin_write_USB_PLLOSC_CTRL(val)		bfin_write16(USB_PLLOSC_CTRL, val)
-#define bfin_read_USB_SRP_CLKDIV()		bfin_read16(USB_SRP_CLKDIV)
-#define bfin_write_USB_SRP_CLKDIV(val)		bfin_write16(USB_SRP_CLKDIV, val)
-
-/* USB Endpoint 0 Control Registers */
-
-#define bfin_read_USB_EP_NI0_TXMAXP()		bfin_read16(USB_EP_NI0_TXMAXP)
-#define bfin_write_USB_EP_NI0_TXMAXP(val)	bfin_write16(USB_EP_NI0_TXMAXP, val)
-#define bfin_read_USB_EP_NI0_TXCSR()		bfin_read16(USB_EP_NI0_TXCSR)
-#define bfin_write_USB_EP_NI0_TXCSR(val)	bfin_write16(USB_EP_NI0_TXCSR, val)
-#define bfin_read_USB_EP_NI0_RXMAXP()		bfin_read16(USB_EP_NI0_RXMAXP)
-#define bfin_write_USB_EP_NI0_RXMAXP(val)	bfin_write16(USB_EP_NI0_RXMAXP, val)
-#define bfin_read_USB_EP_NI0_RXCSR()		bfin_read16(USB_EP_NI0_RXCSR)
-#define bfin_write_USB_EP_NI0_RXCSR(val)	bfin_write16(USB_EP_NI0_RXCSR, val)
-#define bfin_read_USB_EP_NI0_RXCOUNT()		bfin_read16(USB_EP_NI0_RXCOUNT)
-#define bfin_write_USB_EP_NI0_RXCOUNT(val)	bfin_write16(USB_EP_NI0_RXCOUNT, val)
-#define bfin_read_USB_EP_NI0_TXTYPE()		bfin_read16(USB_EP_NI0_TXTYPE)
-#define bfin_write_USB_EP_NI0_TXTYPE(val)	bfin_write16(USB_EP_NI0_TXTYPE, val)
-#define bfin_read_USB_EP_NI0_TXINTERVAL()	bfin_read16(USB_EP_NI0_TXINTERVAL)
-#define bfin_write_USB_EP_NI0_TXINTERVAL(val)	bfin_write16(USB_EP_NI0_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI0_RXTYPE()		bfin_read16(USB_EP_NI0_RXTYPE)
-#define bfin_write_USB_EP_NI0_RXTYPE(val)	bfin_write16(USB_EP_NI0_RXTYPE, val)
-#define bfin_read_USB_EP_NI0_RXINTERVAL()	bfin_read16(USB_EP_NI0_RXINTERVAL)
-#define bfin_write_USB_EP_NI0_RXINTERVAL(val)	bfin_write16(USB_EP_NI0_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI0_TXCOUNT()		bfin_read16(USB_EP_NI0_TXCOUNT)
-#define bfin_write_USB_EP_NI0_TXCOUNT(val)	bfin_write16(USB_EP_NI0_TXCOUNT, val)
-
-/* USB Endpoint 1 Control Registers */
-
-#define bfin_read_USB_EP_NI1_TXMAXP()		bfin_read16(USB_EP_NI1_TXMAXP)
-#define bfin_write_USB_EP_NI1_TXMAXP(val)	bfin_write16(USB_EP_NI1_TXMAXP, val)
-#define bfin_read_USB_EP_NI1_TXCSR()		bfin_read16(USB_EP_NI1_TXCSR)
-#define bfin_write_USB_EP_NI1_TXCSR(val)	bfin_write16(USB_EP_NI1_TXCSR, val)
-#define bfin_read_USB_EP_NI1_RXMAXP()		bfin_read16(USB_EP_NI1_RXMAXP)
-#define bfin_write_USB_EP_NI1_RXMAXP(val)	bfin_write16(USB_EP_NI1_RXMAXP, val)
-#define bfin_read_USB_EP_NI1_RXCSR()		bfin_read16(USB_EP_NI1_RXCSR)
-#define bfin_write_USB_EP_NI1_RXCSR(val)	bfin_write16(USB_EP_NI1_RXCSR, val)
-#define bfin_read_USB_EP_NI1_RXCOUNT()		bfin_read16(USB_EP_NI1_RXCOUNT)
-#define bfin_write_USB_EP_NI1_RXCOUNT(val)	bfin_write16(USB_EP_NI1_RXCOUNT, val)
-#define bfin_read_USB_EP_NI1_TXTYPE()		bfin_read16(USB_EP_NI1_TXTYPE)
-#define bfin_write_USB_EP_NI1_TXTYPE(val)	bfin_write16(USB_EP_NI1_TXTYPE, val)
-#define bfin_read_USB_EP_NI1_TXINTERVAL()	bfin_read16(USB_EP_NI1_TXINTERVAL)
-#define bfin_write_USB_EP_NI1_TXINTERVAL(val)	bfin_write16(USB_EP_NI1_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI1_RXTYPE()		bfin_read16(USB_EP_NI1_RXTYPE)
-#define bfin_write_USB_EP_NI1_RXTYPE(val)	bfin_write16(USB_EP_NI1_RXTYPE, val)
-#define bfin_read_USB_EP_NI1_RXINTERVAL()	bfin_read16(USB_EP_NI1_RXINTERVAL)
-#define bfin_write_USB_EP_NI1_RXINTERVAL(val)	bfin_write16(USB_EP_NI1_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI1_TXCOUNT()		bfin_read16(USB_EP_NI1_TXCOUNT)
-#define bfin_write_USB_EP_NI1_TXCOUNT(val)	bfin_write16(USB_EP_NI1_TXCOUNT, val)
-
-/* USB Endpoint 2 Control Registers */
-
-#define bfin_read_USB_EP_NI2_TXMAXP()		bfin_read16(USB_EP_NI2_TXMAXP)
-#define bfin_write_USB_EP_NI2_TXMAXP(val)	bfin_write16(USB_EP_NI2_TXMAXP, val)
-#define bfin_read_USB_EP_NI2_TXCSR()		bfin_read16(USB_EP_NI2_TXCSR)
-#define bfin_write_USB_EP_NI2_TXCSR(val)	bfin_write16(USB_EP_NI2_TXCSR, val)
-#define bfin_read_USB_EP_NI2_RXMAXP()		bfin_read16(USB_EP_NI2_RXMAXP)
-#define bfin_write_USB_EP_NI2_RXMAXP(val)	bfin_write16(USB_EP_NI2_RXMAXP, val)
-#define bfin_read_USB_EP_NI2_RXCSR()		bfin_read16(USB_EP_NI2_RXCSR)
-#define bfin_write_USB_EP_NI2_RXCSR(val)	bfin_write16(USB_EP_NI2_RXCSR, val)
-#define bfin_read_USB_EP_NI2_RXCOUNT()		bfin_read16(USB_EP_NI2_RXCOUNT)
-#define bfin_write_USB_EP_NI2_RXCOUNT(val)	bfin_write16(USB_EP_NI2_RXCOUNT, val)
-#define bfin_read_USB_EP_NI2_TXTYPE()		bfin_read16(USB_EP_NI2_TXTYPE)
-#define bfin_write_USB_EP_NI2_TXTYPE(val)	bfin_write16(USB_EP_NI2_TXTYPE, val)
-#define bfin_read_USB_EP_NI2_TXINTERVAL()	bfin_read16(USB_EP_NI2_TXINTERVAL)
-#define bfin_write_USB_EP_NI2_TXINTERVAL(val)	bfin_write16(USB_EP_NI2_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI2_RXTYPE()		bfin_read16(USB_EP_NI2_RXTYPE)
-#define bfin_write_USB_EP_NI2_RXTYPE(val)	bfin_write16(USB_EP_NI2_RXTYPE, val)
-#define bfin_read_USB_EP_NI2_RXINTERVAL()	bfin_read16(USB_EP_NI2_RXINTERVAL)
-#define bfin_write_USB_EP_NI2_RXINTERVAL(val)	bfin_write16(USB_EP_NI2_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI2_TXCOUNT()		bfin_read16(USB_EP_NI2_TXCOUNT)
-#define bfin_write_USB_EP_NI2_TXCOUNT(val)	bfin_write16(USB_EP_NI2_TXCOUNT, val)
-
-/* USB Endpoint 3 Control Registers */
-
-#define bfin_read_USB_EP_NI3_TXMAXP()		bfin_read16(USB_EP_NI3_TXMAXP)
-#define bfin_write_USB_EP_NI3_TXMAXP(val)	bfin_write16(USB_EP_NI3_TXMAXP, val)
-#define bfin_read_USB_EP_NI3_TXCSR()		bfin_read16(USB_EP_NI3_TXCSR)
-#define bfin_write_USB_EP_NI3_TXCSR(val)	bfin_write16(USB_EP_NI3_TXCSR, val)
-#define bfin_read_USB_EP_NI3_RXMAXP()		bfin_read16(USB_EP_NI3_RXMAXP)
-#define bfin_write_USB_EP_NI3_RXMAXP(val)	bfin_write16(USB_EP_NI3_RXMAXP, val)
-#define bfin_read_USB_EP_NI3_RXCSR()		bfin_read16(USB_EP_NI3_RXCSR)
-#define bfin_write_USB_EP_NI3_RXCSR(val)	bfin_write16(USB_EP_NI3_RXCSR, val)
-#define bfin_read_USB_EP_NI3_RXCOUNT()		bfin_read16(USB_EP_NI3_RXCOUNT)
-#define bfin_write_USB_EP_NI3_RXCOUNT(val)	bfin_write16(USB_EP_NI3_RXCOUNT, val)
-#define bfin_read_USB_EP_NI3_TXTYPE()		bfin_read16(USB_EP_NI3_TXTYPE)
-#define bfin_write_USB_EP_NI3_TXTYPE(val)	bfin_write16(USB_EP_NI3_TXTYPE, val)
-#define bfin_read_USB_EP_NI3_TXINTERVAL()	bfin_read16(USB_EP_NI3_TXINTERVAL)
-#define bfin_write_USB_EP_NI3_TXINTERVAL(val)	bfin_write16(USB_EP_NI3_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI3_RXTYPE()		bfin_read16(USB_EP_NI3_RXTYPE)
-#define bfin_write_USB_EP_NI3_RXTYPE(val)	bfin_write16(USB_EP_NI3_RXTYPE, val)
-#define bfin_read_USB_EP_NI3_RXINTERVAL()	bfin_read16(USB_EP_NI3_RXINTERVAL)
-#define bfin_write_USB_EP_NI3_RXINTERVAL(val)	bfin_write16(USB_EP_NI3_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI3_TXCOUNT()		bfin_read16(USB_EP_NI3_TXCOUNT)
-#define bfin_write_USB_EP_NI3_TXCOUNT(val)	bfin_write16(USB_EP_NI3_TXCOUNT, val)
-
-/* USB Endpoint 4 Control Registers */
-
-#define bfin_read_USB_EP_NI4_TXMAXP()		bfin_read16(USB_EP_NI4_TXMAXP)
-#define bfin_write_USB_EP_NI4_TXMAXP(val)	bfin_write16(USB_EP_NI4_TXMAXP, val)
-#define bfin_read_USB_EP_NI4_TXCSR()		bfin_read16(USB_EP_NI4_TXCSR)
-#define bfin_write_USB_EP_NI4_TXCSR(val)	bfin_write16(USB_EP_NI4_TXCSR, val)
-#define bfin_read_USB_EP_NI4_RXMAXP()		bfin_read16(USB_EP_NI4_RXMAXP)
-#define bfin_write_USB_EP_NI4_RXMAXP(val)	bfin_write16(USB_EP_NI4_RXMAXP, val)
-#define bfin_read_USB_EP_NI4_RXCSR()		bfin_read16(USB_EP_NI4_RXCSR)
-#define bfin_write_USB_EP_NI4_RXCSR(val)	bfin_write16(USB_EP_NI4_RXCSR, val)
-#define bfin_read_USB_EP_NI4_RXCOUNT()		bfin_read16(USB_EP_NI4_RXCOUNT)
-#define bfin_write_USB_EP_NI4_RXCOUNT(val)	bfin_write16(USB_EP_NI4_RXCOUNT, val)
-#define bfin_read_USB_EP_NI4_TXTYPE()		bfin_read16(USB_EP_NI4_TXTYPE)
-#define bfin_write_USB_EP_NI4_TXTYPE(val)	bfin_write16(USB_EP_NI4_TXTYPE, val)
-#define bfin_read_USB_EP_NI4_TXINTERVAL()	bfin_read16(USB_EP_NI4_TXINTERVAL)
-#define bfin_write_USB_EP_NI4_TXINTERVAL(val)	bfin_write16(USB_EP_NI4_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI4_RXTYPE()		bfin_read16(USB_EP_NI4_RXTYPE)
-#define bfin_write_USB_EP_NI4_RXTYPE(val)	bfin_write16(USB_EP_NI4_RXTYPE, val)
-#define bfin_read_USB_EP_NI4_RXINTERVAL()	bfin_read16(USB_EP_NI4_RXINTERVAL)
-#define bfin_write_USB_EP_NI4_RXINTERVAL(val)	bfin_write16(USB_EP_NI4_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI4_TXCOUNT()		bfin_read16(USB_EP_NI4_TXCOUNT)
-#define bfin_write_USB_EP_NI4_TXCOUNT(val)	bfin_write16(USB_EP_NI4_TXCOUNT, val)
-
-/* USB Endpoint 5 Control Registers */
-
-#define bfin_read_USB_EP_NI5_TXMAXP()		bfin_read16(USB_EP_NI5_TXMAXP)
-#define bfin_write_USB_EP_NI5_TXMAXP(val)	bfin_write16(USB_EP_NI5_TXMAXP, val)
-#define bfin_read_USB_EP_NI5_TXCSR()		bfin_read16(USB_EP_NI5_TXCSR)
-#define bfin_write_USB_EP_NI5_TXCSR(val)	bfin_write16(USB_EP_NI5_TXCSR, val)
-#define bfin_read_USB_EP_NI5_RXMAXP()		bfin_read16(USB_EP_NI5_RXMAXP)
-#define bfin_write_USB_EP_NI5_RXMAXP(val)	bfin_write16(USB_EP_NI5_RXMAXP, val)
-#define bfin_read_USB_EP_NI5_RXCSR()		bfin_read16(USB_EP_NI5_RXCSR)
-#define bfin_write_USB_EP_NI5_RXCSR(val)	bfin_write16(USB_EP_NI5_RXCSR, val)
-#define bfin_read_USB_EP_NI5_RXCOUNT()		bfin_read16(USB_EP_NI5_RXCOUNT)
-#define bfin_write_USB_EP_NI5_RXCOUNT(val)	bfin_write16(USB_EP_NI5_RXCOUNT, val)
-#define bfin_read_USB_EP_NI5_TXTYPE()		bfin_read16(USB_EP_NI5_TXTYPE)
-#define bfin_write_USB_EP_NI5_TXTYPE(val)	bfin_write16(USB_EP_NI5_TXTYPE, val)
-#define bfin_read_USB_EP_NI5_TXINTERVAL()	bfin_read16(USB_EP_NI5_TXINTERVAL)
-#define bfin_write_USB_EP_NI5_TXINTERVAL(val)	bfin_write16(USB_EP_NI5_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI5_RXTYPE()		bfin_read16(USB_EP_NI5_RXTYPE)
-#define bfin_write_USB_EP_NI5_RXTYPE(val)	bfin_write16(USB_EP_NI5_RXTYPE, val)
-#define bfin_read_USB_EP_NI5_RXINTERVAL()	bfin_read16(USB_EP_NI5_RXINTERVAL)
-#define bfin_write_USB_EP_NI5_RXINTERVAL(val)	bfin_write16(USB_EP_NI5_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI5_TXCOUNT()		bfin_read16(USB_EP_NI5_TXCOUNT)
-#define bfin_write_USB_EP_NI5_TXCOUNT(val)	bfin_write16(USB_EP_NI5_TXCOUNT, val)
-
-/* USB Endpoint 6 Control Registers */
-
-#define bfin_read_USB_EP_NI6_TXMAXP()		bfin_read16(USB_EP_NI6_TXMAXP)
-#define bfin_write_USB_EP_NI6_TXMAXP(val)	bfin_write16(USB_EP_NI6_TXMAXP, val)
-#define bfin_read_USB_EP_NI6_TXCSR()		bfin_read16(USB_EP_NI6_TXCSR)
-#define bfin_write_USB_EP_NI6_TXCSR(val)	bfin_write16(USB_EP_NI6_TXCSR, val)
-#define bfin_read_USB_EP_NI6_RXMAXP()		bfin_read16(USB_EP_NI6_RXMAXP)
-#define bfin_write_USB_EP_NI6_RXMAXP(val)	bfin_write16(USB_EP_NI6_RXMAXP, val)
-#define bfin_read_USB_EP_NI6_RXCSR()		bfin_read16(USB_EP_NI6_RXCSR)
-#define bfin_write_USB_EP_NI6_RXCSR(val)	bfin_write16(USB_EP_NI6_RXCSR, val)
-#define bfin_read_USB_EP_NI6_RXCOUNT()		bfin_read16(USB_EP_NI6_RXCOUNT)
-#define bfin_write_USB_EP_NI6_RXCOUNT(val)	bfin_write16(USB_EP_NI6_RXCOUNT, val)
-#define bfin_read_USB_EP_NI6_TXTYPE()		bfin_read16(USB_EP_NI6_TXTYPE)
-#define bfin_write_USB_EP_NI6_TXTYPE(val)	bfin_write16(USB_EP_NI6_TXTYPE, val)
-#define bfin_read_USB_EP_NI6_TXINTERVAL()	bfin_read16(USB_EP_NI6_TXINTERVAL)
-#define bfin_write_USB_EP_NI6_TXINTERVAL(val)	bfin_write16(USB_EP_NI6_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI6_RXTYPE()		bfin_read16(USB_EP_NI6_RXTYPE)
-#define bfin_write_USB_EP_NI6_RXTYPE(val)	bfin_write16(USB_EP_NI6_RXTYPE, val)
-#define bfin_read_USB_EP_NI6_RXINTERVAL()	bfin_read16(USB_EP_NI6_RXINTERVAL)
-#define bfin_write_USB_EP_NI6_RXINTERVAL(val)	bfin_write16(USB_EP_NI6_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI6_TXCOUNT()		bfin_read16(USB_EP_NI6_TXCOUNT)
-#define bfin_write_USB_EP_NI6_TXCOUNT(val)	bfin_write16(USB_EP_NI6_TXCOUNT, val)
-
-/* USB Endpoint 7 Control Registers */
-
-#define bfin_read_USB_EP_NI7_TXMAXP()		bfin_read16(USB_EP_NI7_TXMAXP)
-#define bfin_write_USB_EP_NI7_TXMAXP(val)	bfin_write16(USB_EP_NI7_TXMAXP, val)
-#define bfin_read_USB_EP_NI7_TXCSR()		bfin_read16(USB_EP_NI7_TXCSR)
-#define bfin_write_USB_EP_NI7_TXCSR(val)	bfin_write16(USB_EP_NI7_TXCSR, val)
-#define bfin_read_USB_EP_NI7_RXMAXP()		bfin_read16(USB_EP_NI7_RXMAXP)
-#define bfin_write_USB_EP_NI7_RXMAXP(val)	bfin_write16(USB_EP_NI7_RXMAXP, val)
-#define bfin_read_USB_EP_NI7_RXCSR()		bfin_read16(USB_EP_NI7_RXCSR)
-#define bfin_write_USB_EP_NI7_RXCSR(val)	bfin_write16(USB_EP_NI7_RXCSR, val)
-#define bfin_read_USB_EP_NI7_RXCOUNT()		bfin_read16(USB_EP_NI7_RXCOUNT)
-#define bfin_write_USB_EP_NI7_RXCOUNT(val)	bfin_write16(USB_EP_NI7_RXCOUNT, val)
-#define bfin_read_USB_EP_NI7_TXTYPE()		bfin_read16(USB_EP_NI7_TXTYPE)
-#define bfin_write_USB_EP_NI7_TXTYPE(val)	bfin_write16(USB_EP_NI7_TXTYPE, val)
-#define bfin_read_USB_EP_NI7_TXINTERVAL()	bfin_read16(USB_EP_NI7_TXINTERVAL)
-#define bfin_write_USB_EP_NI7_TXINTERVAL(val)	bfin_write16(USB_EP_NI7_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_RXTYPE()		bfin_read16(USB_EP_NI7_RXTYPE)
-#define bfin_write_USB_EP_NI7_RXTYPE(val)	bfin_write16(USB_EP_NI7_RXTYPE, val)
-#define bfin_read_USB_EP_NI7_RXINTERVAL()	bfin_read16(USB_EP_NI7_RXINTERVAL)
-#define bfin_write_USB_EP_NI7_RXINTERVAL(val)	bfin_write16(USB_EP_NI7_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_TXCOUNT()		bfin_read16(USB_EP_NI7_TXCOUNT)
-#define bfin_write_USB_EP_NI7_TXCOUNT(val)	bfin_write16(USB_EP_NI7_TXCOUNT, val)
-
-#define bfin_read_USB_DMA_INTERRUPT()		bfin_read16(USB_DMA_INTERRUPT)
-#define bfin_write_USB_DMA_INTERRUPT(val)	bfin_write16(USB_DMA_INTERRUPT, val)
-
-/* USB Channel 0 Config Registers */
-
-#define bfin_read_USB_DMA0CONTROL()		bfin_read16(USB_DMA0CONTROL)
-#define bfin_write_USB_DMA0CONTROL(val)		bfin_write16(USB_DMA0CONTROL, val)
-#define bfin_read_USB_DMA0ADDRLOW()		bfin_read16(USB_DMA0ADDRLOW)
-#define bfin_write_USB_DMA0ADDRLOW(val)		bfin_write16(USB_DMA0ADDRLOW, val)
-#define bfin_read_USB_DMA0ADDRHIGH()		bfin_read16(USB_DMA0ADDRHIGH)
-#define bfin_write_USB_DMA0ADDRHIGH(val)	bfin_write16(USB_DMA0ADDRHIGH, val)
-#define bfin_read_USB_DMA0COUNTLOW()		bfin_read16(USB_DMA0COUNTLOW)
-#define bfin_write_USB_DMA0COUNTLOW(val)	bfin_write16(USB_DMA0COUNTLOW, val)
-#define bfin_read_USB_DMA0COUNTHIGH()		bfin_read16(USB_DMA0COUNTHIGH)
-#define bfin_write_USB_DMA0COUNTHIGH(val)	bfin_write16(USB_DMA0COUNTHIGH, val)
-
-/* USB Channel 1 Config Registers */
-
-#define bfin_read_USB_DMA1CONTROL()		bfin_read16(USB_DMA1CONTROL)
-#define bfin_write_USB_DMA1CONTROL(val)		bfin_write16(USB_DMA1CONTROL, val)
-#define bfin_read_USB_DMA1ADDRLOW()		bfin_read16(USB_DMA1ADDRLOW)
-#define bfin_write_USB_DMA1ADDRLOW(val)		bfin_write16(USB_DMA1ADDRLOW, val)
-#define bfin_read_USB_DMA1ADDRHIGH()		bfin_read16(USB_DMA1ADDRHIGH)
-#define bfin_write_USB_DMA1ADDRHIGH(val)	bfin_write16(USB_DMA1ADDRHIGH, val)
-#define bfin_read_USB_DMA1COUNTLOW()		bfin_read16(USB_DMA1COUNTLOW)
-#define bfin_write_USB_DMA1COUNTLOW(val)	bfin_write16(USB_DMA1COUNTLOW, val)
-#define bfin_read_USB_DMA1COUNTHIGH()		bfin_read16(USB_DMA1COUNTHIGH)
-#define bfin_write_USB_DMA1COUNTHIGH(val)	bfin_write16(USB_DMA1COUNTHIGH, val)
-
-/* USB Channel 2 Config Registers */
-
-#define bfin_read_USB_DMA2CONTROL()		bfin_read16(USB_DMA2CONTROL)
-#define bfin_write_USB_DMA2CONTROL(val)		bfin_write16(USB_DMA2CONTROL, val)
-#define bfin_read_USB_DMA2ADDRLOW()		bfin_read16(USB_DMA2ADDRLOW)
-#define bfin_write_USB_DMA2ADDRLOW(val)		bfin_write16(USB_DMA2ADDRLOW, val)
-#define bfin_read_USB_DMA2ADDRHIGH()		bfin_read16(USB_DMA2ADDRHIGH)
-#define bfin_write_USB_DMA2ADDRHIGH(val)	bfin_write16(USB_DMA2ADDRHIGH, val)
-#define bfin_read_USB_DMA2COUNTLOW()		bfin_read16(USB_DMA2COUNTLOW)
-#define bfin_write_USB_DMA2COUNTLOW(val)	bfin_write16(USB_DMA2COUNTLOW, val)
-#define bfin_read_USB_DMA2COUNTHIGH()		bfin_read16(USB_DMA2COUNTHIGH)
-#define bfin_write_USB_DMA2COUNTHIGH(val)	bfin_write16(USB_DMA2COUNTHIGH, val)
-
-/* USB Channel 3 Config Registers */
-
-#define bfin_read_USB_DMA3CONTROL()		bfin_read16(USB_DMA3CONTROL)
-#define bfin_write_USB_DMA3CONTROL(val)		bfin_write16(USB_DMA3CONTROL, val)
-#define bfin_read_USB_DMA3ADDRLOW()		bfin_read16(USB_DMA3ADDRLOW)
-#define bfin_write_USB_DMA3ADDRLOW(val)		bfin_write16(USB_DMA3ADDRLOW, val)
-#define bfin_read_USB_DMA3ADDRHIGH()		bfin_read16(USB_DMA3ADDRHIGH)
-#define bfin_write_USB_DMA3ADDRHIGH(val)	bfin_write16(USB_DMA3ADDRHIGH, val)
-#define bfin_read_USB_DMA3COUNTLOW()		bfin_read16(USB_DMA3COUNTLOW)
-#define bfin_write_USB_DMA3COUNTLOW(val)	bfin_write16(USB_DMA3COUNTLOW, val)
-#define bfin_read_USB_DMA3COUNTHIGH()		bfin_read16(USB_DMA3COUNTHIGH)
-#define bfin_write_USB_DMA3COUNTHIGH(val)	bfin_write16(USB_DMA3COUNTHIGH, val)
-
-/* USB Channel 4 Config Registers */
-
-#define bfin_read_USB_DMA4CONTROL()		bfin_read16(USB_DMA4CONTROL)
-#define bfin_write_USB_DMA4CONTROL(val)		bfin_write16(USB_DMA4CONTROL, val)
-#define bfin_read_USB_DMA4ADDRLOW()		bfin_read16(USB_DMA4ADDRLOW)
-#define bfin_write_USB_DMA4ADDRLOW(val)		bfin_write16(USB_DMA4ADDRLOW, val)
-#define bfin_read_USB_DMA4ADDRHIGH()		bfin_read16(USB_DMA4ADDRHIGH)
-#define bfin_write_USB_DMA4ADDRHIGH(val)	bfin_write16(USB_DMA4ADDRHIGH, val)
-#define bfin_read_USB_DMA4COUNTLOW()		bfin_read16(USB_DMA4COUNTLOW)
-#define bfin_write_USB_DMA4COUNTLOW(val)	bfin_write16(USB_DMA4COUNTLOW, val)
-#define bfin_read_USB_DMA4COUNTHIGH()		bfin_read16(USB_DMA4COUNTHIGH)
-#define bfin_write_USB_DMA4COUNTHIGH(val)	bfin_write16(USB_DMA4COUNTHIGH, val)
-
-/* USB Channel 5 Config Registers */
-
-#define bfin_read_USB_DMA5CONTROL()		bfin_read16(USB_DMA5CONTROL)
-#define bfin_write_USB_DMA5CONTROL(val)		bfin_write16(USB_DMA5CONTROL, val)
-#define bfin_read_USB_DMA5ADDRLOW()		bfin_read16(USB_DMA5ADDRLOW)
-#define bfin_write_USB_DMA5ADDRLOW(val)		bfin_write16(USB_DMA5ADDRLOW, val)
-#define bfin_read_USB_DMA5ADDRHIGH()		bfin_read16(USB_DMA5ADDRHIGH)
-#define bfin_write_USB_DMA5ADDRHIGH(val)	bfin_write16(USB_DMA5ADDRHIGH, val)
-#define bfin_read_USB_DMA5COUNTLOW()		bfin_read16(USB_DMA5COUNTLOW)
-#define bfin_write_USB_DMA5COUNTLOW(val)	bfin_write16(USB_DMA5COUNTLOW, val)
-#define bfin_read_USB_DMA5COUNTHIGH()		bfin_read16(USB_DMA5COUNTHIGH)
-#define bfin_write_USB_DMA5COUNTHIGH(val)	bfin_write16(USB_DMA5COUNTHIGH, val)
-
-/* USB Channel 6 Config Registers */
-
-#define bfin_read_USB_DMA6CONTROL()		bfin_read16(USB_DMA6CONTROL)
-#define bfin_write_USB_DMA6CONTROL(val)		bfin_write16(USB_DMA6CONTROL, val)
-#define bfin_read_USB_DMA6ADDRLOW()		bfin_read16(USB_DMA6ADDRLOW)
-#define bfin_write_USB_DMA6ADDRLOW(val)		bfin_write16(USB_DMA6ADDRLOW, val)
-#define bfin_read_USB_DMA6ADDRHIGH()		bfin_read16(USB_DMA6ADDRHIGH)
-#define bfin_write_USB_DMA6ADDRHIGH(val)	bfin_write16(USB_DMA6ADDRHIGH, val)
-#define bfin_read_USB_DMA6COUNTLOW()		bfin_read16(USB_DMA6COUNTLOW)
-#define bfin_write_USB_DMA6COUNTLOW(val)	bfin_write16(USB_DMA6COUNTLOW, val)
-#define bfin_read_USB_DMA6COUNTHIGH()		bfin_read16(USB_DMA6COUNTHIGH)
-#define bfin_write_USB_DMA6COUNTHIGH(val)	bfin_write16(USB_DMA6COUNTHIGH, val)
-
-/* USB Channel 7 Config Registers */
-
-#define bfin_read_USB_DMA7CONTROL()		bfin_read16(USB_DMA7CONTROL)
-#define bfin_write_USB_DMA7CONTROL(val)		bfin_write16(USB_DMA7CONTROL, val)
-#define bfin_read_USB_DMA7ADDRLOW()		bfin_read16(USB_DMA7ADDRLOW)
-#define bfin_write_USB_DMA7ADDRLOW(val)		bfin_write16(USB_DMA7ADDRLOW, val)
-#define bfin_read_USB_DMA7ADDRHIGH()		bfin_read16(USB_DMA7ADDRHIGH)
-#define bfin_write_USB_DMA7ADDRHIGH(val)	bfin_write16(USB_DMA7ADDRHIGH, val)
-#define bfin_read_USB_DMA7COUNTLOW()		bfin_read16(USB_DMA7COUNTLOW)
-#define bfin_write_USB_DMA7COUNTLOW(val)	bfin_write16(USB_DMA7COUNTLOW, val)
-#define bfin_read_USB_DMA7COUNTHIGH()		bfin_read16(USB_DMA7COUNTHIGH)
-#define bfin_write_USB_DMA7COUNTHIGH(val)	bfin_write16(USB_DMA7COUNTHIGH, val)
-
 #endif /* _CDEF_BF527_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -844,6 +844,7 @@
 #define bfin_write_PPI_CONTROL(val)		bfin_write16(PPI_CONTROL, val)
 #define bfin_read_PPI_STATUS()			bfin_read16(PPI_STATUS)
 #define bfin_write_PPI_STATUS(val)		bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS()			bfin_write_PPI_STATUS(0xFFFF)
 #define bfin_read_PPI_DELAY()			bfin_read16(PPI_DELAY)
 #define bfin_write_PPI_DELAY(val)		bfin_write16(PPI_DELAY, val)
 #define bfin_read_PPI_COUNT()			bfin_read16(PPI_COUNT)
@@ -1062,17 +1063,6 @@
 #define bfin_read_CNT_MIN()			bfin_read32(CNT_MIN)
 #define bfin_write_CNT_MIN(val)			bfin_write32(CNT_MIN, val)
 
-/* OTP/FUSE Registers */
-
-#define bfin_read_OTP_CONTROL()			bfin_read16(OTP_CONTROL)
-#define bfin_write_OTP_CONTROL(val)		bfin_write16(OTP_CONTROL, val)
-#define bfin_read_OTP_BEN()			bfin_read16(OTP_BEN)
-#define bfin_write_OTP_BEN(val)			bfin_write16(OTP_BEN, val)
-#define bfin_read_OTP_STATUS()			bfin_read16(OTP_STATUS)
-#define bfin_write_OTP_STATUS(val)		bfin_write16(OTP_STATUS, val)
-#define bfin_read_OTP_TIMING()			bfin_read32(OTP_TIMING)
-#define bfin_write_OTP_TIMING(val)		bfin_write32(OTP_TIMING, val)
-
 /* Security Registers */
 
 #define bfin_read_SECURE_SYSSWT()		bfin_read32(SECURE_SYSSWT)
@@ -1082,17 +1072,6 @@
 #define bfin_read_SECURE_STATUS()		bfin_read16(SECURE_STATUS)
 #define bfin_write_SECURE_STATUS(val)		bfin_write16(SECURE_STATUS, val)
 
-/* OTP Read/Write Data Buffer Registers */
-
-#define bfin_read_OTP_DATA0()			bfin_read32(OTP_DATA0)
-#define bfin_write_OTP_DATA0(val)		bfin_write32(OTP_DATA0, val)
-#define bfin_read_OTP_DATA1()			bfin_read32(OTP_DATA1)
-#define bfin_write_OTP_DATA1(val)		bfin_write32(OTP_DATA1, val)
-#define bfin_read_OTP_DATA2()			bfin_read32(OTP_DATA2)
-#define bfin_write_OTP_DATA2(val)		bfin_write32(OTP_DATA2, val)
-#define bfin_read_OTP_DATA3()			bfin_read32(OTP_DATA3)
-#define bfin_write_OTP_DATA3(val)		bfin_write32(OTP_DATA3, val)
-
 /* NFC Registers */
 
 #define bfin_read_NFC_CTL()			bfin_read16(NFC_CTL)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF525.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF525.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF525.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF525.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,15 +7,8 @@
 #ifndef _DEF_BF525_H
 #define _DEF_BF525_H
 
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF525 */
-
-/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "defBF52x_base.h"
-
-/* The following are the #defines needed by ADSP-BF525 that are not in the common header */
+/* BF525 is BF522 + USB */
+#include "defBF522.h"
 
 /* USB Control Registers */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF527.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF527.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF527.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF527.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,15 +7,9 @@
 #ifndef _DEF_BF527_H
 #define _DEF_BF527_H
 
-/* Include all Core registers and bit definitions */
-#include <asm/def_LPBlackfin.h>
-
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */
-
-/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include "defBF52x_base.h"
+/* BF527 is BF525 + EMAC */
+#include "defBF525.h"
 
-/* The following are the #defines needed by ADSP-BF527 that are not in the common header */
 /* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
 
 #define EMAC_OPMODE             0xFFC03000       /* Operating Mode Register                              */
@@ -394,673 +388,4 @@
 #define	TX_GE1024_CNT     0x00200000    /* 1024-Max-Byte TX Frames Sent                           */
 #define	TX_ABORT_CNT      0x00400000    /* TX Frames Aborted                                      */
 
-/* USB Control Registers */
-
-#define                        USB_FADDR  0xffc03800   /* Function address register */
-#define                        USB_POWER  0xffc03804   /* Power management register */
-#define                       USB_INTRTX  0xffc03808   /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */
-#define                       USB_INTRRX  0xffc0380c   /* Interrupt register for Rx endpoints 1 to 7 */
-#define                      USB_INTRTXE  0xffc03810   /* Interrupt enable register for IntrTx */
-#define                      USB_INTRRXE  0xffc03814   /* Interrupt enable register for IntrRx */
-#define                      USB_INTRUSB  0xffc03818   /* Interrupt register for common USB interrupts */
-#define                     USB_INTRUSBE  0xffc0381c   /* Interrupt enable register for IntrUSB */
-#define                        USB_FRAME  0xffc03820   /* USB frame number */
-#define                        USB_INDEX  0xffc03824   /* Index register for selecting the indexed endpoint registers */
-#define                     USB_TESTMODE  0xffc03828   /* Enabled USB 20 test modes */
-#define                     USB_GLOBINTR  0xffc0382c   /* Global Interrupt Mask register and Wakeup Exception Interrupt */
-#define                   USB_GLOBAL_CTL  0xffc03830   /* Global Clock Control for the core */
-
-/* USB Packet Control Registers */
-
-#define                USB_TX_MAX_PACKET  0xffc03840   /* Maximum packet size for Host Tx endpoint */
-#define                         USB_CSR0  0xffc03844   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                        USB_TXCSR  0xffc03844   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                USB_RX_MAX_PACKET  0xffc03848   /* Maximum packet size for Host Rx endpoint */
-#define                        USB_RXCSR  0xffc0384c   /* Control Status register for Host Rx endpoint */
-#define                       USB_COUNT0  0xffc03850   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                      USB_RXCOUNT  0xffc03850   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                       USB_TXTYPE  0xffc03854   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */
-#define                    USB_NAKLIMIT0  0xffc03858   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                   USB_TXINTERVAL  0xffc03858   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                       USB_RXTYPE  0xffc0385c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */
-#define                   USB_RXINTERVAL  0xffc03860   /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */
-#define                      USB_TXCOUNT  0xffc03868   /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* USB Endpoint FIFO Registers */
-
-#define                     USB_EP0_FIFO  0xffc03880   /* Endpoint 0 FIFO */
-#define                     USB_EP1_FIFO  0xffc03888   /* Endpoint 1 FIFO */
-#define                     USB_EP2_FIFO  0xffc03890   /* Endpoint 2 FIFO */
-#define                     USB_EP3_FIFO  0xffc03898   /* Endpoint 3 FIFO */
-#define                     USB_EP4_FIFO  0xffc038a0   /* Endpoint 4 FIFO */
-#define                     USB_EP5_FIFO  0xffc038a8   /* Endpoint 5 FIFO */
-#define                     USB_EP6_FIFO  0xffc038b0   /* Endpoint 6 FIFO */
-#define                     USB_EP7_FIFO  0xffc038b8   /* Endpoint 7 FIFO */
-
-/* USB OTG Control Registers */
-
-#define                  USB_OTG_DEV_CTL  0xffc03900   /* OTG Device Control Register */
-#define                 USB_OTG_VBUS_IRQ  0xffc03904   /* OTG VBUS Control Interrupts */
-#define                USB_OTG_VBUS_MASK  0xffc03908   /* VBUS Control Interrupt Enable */
-
-/* USB Phy Control Registers */
-
-#define                     USB_LINKINFO  0xffc03948   /* Enables programming of some PHY-side delays */
-#define                        USB_VPLEN  0xffc0394c   /* Determines duration of VBUS pulse for VBUS charging */
-#define                      USB_HS_EOF1  0xffc03950   /* Time buffer for High-Speed transactions */
-#define                      USB_FS_EOF1  0xffc03954   /* Time buffer for Full-Speed transactions */
-#define                      USB_LS_EOF1  0xffc03958   /* Time buffer for Low-Speed transactions */
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define                   USB_APHY_CNTRL  0xffc039e0   /* Register that increases visibility of Analog PHY */
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define                   USB_APHY_CALIB  0xffc039e4   /* Register used to set some calibration values */
-
-#define                  USB_APHY_CNTRL2  0xffc039e8   /* Register used to prevent re-enumeration once Moab goes into hibernate mode */
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define                     USB_PHY_TEST  0xffc039ec   /* Used for reducing simulation time and simplifies FIFO testability */
-
-#define                  USB_PLLOSC_CTRL  0xffc039f0   /* Used to program different parameters for USB PLL and Oscillator */
-#define                   USB_SRP_CLKDIV  0xffc039f4   /* Used to program clock divide value for the clock fed to the SRP detection logic */
-
-/* USB Endpoint 0 Control Registers */
-
-#define                USB_EP_NI0_TXMAXP  0xffc03a00   /* Maximum packet size for Host Tx endpoint0 */
-#define                 USB_EP_NI0_TXCSR  0xffc03a04   /* Control Status register for endpoint 0 */
-#define                USB_EP_NI0_RXMAXP  0xffc03a08   /* Maximum packet size for Host Rx endpoint0 */
-#define                 USB_EP_NI0_RXCSR  0xffc03a0c   /* Control Status register for Host Rx endpoint0 */
-#define               USB_EP_NI0_RXCOUNT  0xffc03a10   /* Number of bytes received in endpoint 0 FIFO */
-#define                USB_EP_NI0_TXTYPE  0xffc03a14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */
-#define            USB_EP_NI0_TXINTERVAL  0xffc03a18   /* Sets the NAK response timeout on Endpoint 0 */
-#define                USB_EP_NI0_RXTYPE  0xffc03a1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */
-#define            USB_EP_NI0_RXINTERVAL  0xffc03a20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */
-#define               USB_EP_NI0_TXCOUNT  0xffc03a28   /* Number of bytes to be written to the endpoint0 Tx FIFO */
-
-/* USB Endpoint 1 Control Registers */
-
-#define                USB_EP_NI1_TXMAXP  0xffc03a40   /* Maximum packet size for Host Tx endpoint1 */
-#define                 USB_EP_NI1_TXCSR  0xffc03a44   /* Control Status register for endpoint1 */
-#define                USB_EP_NI1_RXMAXP  0xffc03a48   /* Maximum packet size for Host Rx endpoint1 */
-#define                 USB_EP_NI1_RXCSR  0xffc03a4c   /* Control Status register for Host Rx endpoint1 */
-#define               USB_EP_NI1_RXCOUNT  0xffc03a50   /* Number of bytes received in endpoint1 FIFO */
-#define                USB_EP_NI1_TXTYPE  0xffc03a54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */
-#define            USB_EP_NI1_TXINTERVAL  0xffc03a58   /* Sets the NAK response timeout on Endpoint1 */
-#define                USB_EP_NI1_RXTYPE  0xffc03a5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */
-#define            USB_EP_NI1_RXINTERVAL  0xffc03a60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */
-#define               USB_EP_NI1_TXCOUNT  0xffc03a68   /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */
-
-/* USB Endpoint 2 Control Registers */
-
-#define                USB_EP_NI2_TXMAXP  0xffc03a80   /* Maximum packet size for Host Tx endpoint2 */
-#define                 USB_EP_NI2_TXCSR  0xffc03a84   /* Control Status register for endpoint2 */
-#define                USB_EP_NI2_RXMAXP  0xffc03a88   /* Maximum packet size for Host Rx endpoint2 */
-#define                 USB_EP_NI2_RXCSR  0xffc03a8c   /* Control Status register for Host Rx endpoint2 */
-#define               USB_EP_NI2_RXCOUNT  0xffc03a90   /* Number of bytes received in endpoint2 FIFO */
-#define                USB_EP_NI2_TXTYPE  0xffc03a94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */
-#define            USB_EP_NI2_TXINTERVAL  0xffc03a98   /* Sets the NAK response timeout on Endpoint2 */
-#define                USB_EP_NI2_RXTYPE  0xffc03a9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */
-#define            USB_EP_NI2_RXINTERVAL  0xffc03aa0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */
-#define               USB_EP_NI2_TXCOUNT  0xffc03aa8   /* Number of bytes to be written to the endpoint2 Tx FIFO */
-
-/* USB Endpoint 3 Control Registers */
-
-#define                USB_EP_NI3_TXMAXP  0xffc03ac0   /* Maximum packet size for Host Tx endpoint3 */
-#define                 USB_EP_NI3_TXCSR  0xffc03ac4   /* Control Status register for endpoint3 */
-#define                USB_EP_NI3_RXMAXP  0xffc03ac8   /* Maximum packet size for Host Rx endpoint3 */
-#define                 USB_EP_NI3_RXCSR  0xffc03acc   /* Control Status register for Host Rx endpoint3 */
-#define               USB_EP_NI3_RXCOUNT  0xffc03ad0   /* Number of bytes received in endpoint3 FIFO */
-#define                USB_EP_NI3_TXTYPE  0xffc03ad4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */
-#define            USB_EP_NI3_TXINTERVAL  0xffc03ad8   /* Sets the NAK response timeout on Endpoint3 */
-#define                USB_EP_NI3_RXTYPE  0xffc03adc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */
-#define            USB_EP_NI3_RXINTERVAL  0xffc03ae0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */
-#define               USB_EP_NI3_TXCOUNT  0xffc03ae8   /* Number of bytes to be written to the H124endpoint3 Tx FIFO */
-
-/* USB Endpoint 4 Control Registers */
-
-#define                USB_EP_NI4_TXMAXP  0xffc03b00   /* Maximum packet size for Host Tx endpoint4 */
-#define                 USB_EP_NI4_TXCSR  0xffc03b04   /* Control Status register for endpoint4 */
-#define                USB_EP_NI4_RXMAXP  0xffc03b08   /* Maximum packet size for Host Rx endpoint4 */
-#define                 USB_EP_NI4_RXCSR  0xffc03b0c   /* Control Status register for Host Rx endpoint4 */
-#define               USB_EP_NI4_RXCOUNT  0xffc03b10   /* Number of bytes received in endpoint4 FIFO */
-#define                USB_EP_NI4_TXTYPE  0xffc03b14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */
-#define            USB_EP_NI4_TXINTERVAL  0xffc03b18   /* Sets the NAK response timeout on Endpoint4 */
-#define                USB_EP_NI4_RXTYPE  0xffc03b1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */
-#define            USB_EP_NI4_RXINTERVAL  0xffc03b20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */
-#define               USB_EP_NI4_TXCOUNT  0xffc03b28   /* Number of bytes to be written to the endpoint4 Tx FIFO */
-
-/* USB Endpoint 5 Control Registers */
-
-#define                USB_EP_NI5_TXMAXP  0xffc03b40   /* Maximum packet size for Host Tx endpoint5 */
-#define                 USB_EP_NI5_TXCSR  0xffc03b44   /* Control Status register for endpoint5 */
-#define                USB_EP_NI5_RXMAXP  0xffc03b48   /* Maximum packet size for Host Rx endpoint5 */
-#define                 USB_EP_NI5_RXCSR  0xffc03b4c   /* Control Status register for Host Rx endpoint5 */
-#define               USB_EP_NI5_RXCOUNT  0xffc03b50   /* Number of bytes received in endpoint5 FIFO */
-#define                USB_EP_NI5_TXTYPE  0xffc03b54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */
-#define            USB_EP_NI5_TXINTERVAL  0xffc03b58   /* Sets the NAK response timeout on Endpoint5 */
-#define                USB_EP_NI5_RXTYPE  0xffc03b5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */
-#define            USB_EP_NI5_RXINTERVAL  0xffc03b60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */
-#define               USB_EP_NI5_TXCOUNT  0xffc03b68   /* Number of bytes to be written to the endpoint5 Tx FIFO */
-
-/* USB Endpoint 6 Control Registers */
-
-#define                USB_EP_NI6_TXMAXP  0xffc03b80   /* Maximum packet size for Host Tx endpoint6 */
-#define                 USB_EP_NI6_TXCSR  0xffc03b84   /* Control Status register for endpoint6 */
-#define                USB_EP_NI6_RXMAXP  0xffc03b88   /* Maximum packet size for Host Rx endpoint6 */
-#define                 USB_EP_NI6_RXCSR  0xffc03b8c   /* Control Status register for Host Rx endpoint6 */
-#define               USB_EP_NI6_RXCOUNT  0xffc03b90   /* Number of bytes received in endpoint6 FIFO */
-#define                USB_EP_NI6_TXTYPE  0xffc03b94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */
-#define            USB_EP_NI6_TXINTERVAL  0xffc03b98   /* Sets the NAK response timeout on Endpoint6 */
-#define                USB_EP_NI6_RXTYPE  0xffc03b9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */
-#define            USB_EP_NI6_RXINTERVAL  0xffc03ba0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */
-#define               USB_EP_NI6_TXCOUNT  0xffc03ba8   /* Number of bytes to be written to the endpoint6 Tx FIFO */
-
-/* USB Endpoint 7 Control Registers */
-
-#define                USB_EP_NI7_TXMAXP  0xffc03bc0   /* Maximum packet size for Host Tx endpoint7 */
-#define                 USB_EP_NI7_TXCSR  0xffc03bc4   /* Control Status register for endpoint7 */
-#define                USB_EP_NI7_RXMAXP  0xffc03bc8   /* Maximum packet size for Host Rx endpoint7 */
-#define                 USB_EP_NI7_RXCSR  0xffc03bcc   /* Control Status register for Host Rx endpoint7 */
-#define               USB_EP_NI7_RXCOUNT  0xffc03bd0   /* Number of bytes received in endpoint7 FIFO */
-#define                USB_EP_NI7_TXTYPE  0xffc03bd4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */
-#define            USB_EP_NI7_TXINTERVAL  0xffc03bd8   /* Sets the NAK response timeout on Endpoint7 */
-#define                USB_EP_NI7_RXTYPE  0xffc03bdc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */
-#define            USB_EP_NI7_RXINTERVAL  0xffc03bf0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
-#define               USB_EP_NI7_TXCOUNT  0xffc03bf8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
-
-#define                USB_DMA_INTERRUPT  0xffc03c00   /* Indicates pending interrupts for the DMA channels */
-
-/* USB Channel 0 Config Registers */
-
-#define                  USB_DMA0CONTROL  0xffc03c04   /* DMA master channel 0 configuration */
-#define                  USB_DMA0ADDRLOW  0xffc03c08   /* Lower 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0ADDRHIGH  0xffc03c0c   /* Upper 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0COUNTLOW  0xffc03c10   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */
-#define                USB_DMA0COUNTHIGH  0xffc03c14   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */
-
-/* USB Channel 1 Config Registers */
-
-#define                  USB_DMA1CONTROL  0xffc03c24   /* DMA master channel 1 configuration */
-#define                  USB_DMA1ADDRLOW  0xffc03c28   /* Lower 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1ADDRHIGH  0xffc03c2c   /* Upper 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1COUNTLOW  0xffc03c30   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */
-#define                USB_DMA1COUNTHIGH  0xffc03c34   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */
-
-/* USB Channel 2 Config Registers */
-
-#define                  USB_DMA2CONTROL  0xffc03c44   /* DMA master channel 2 configuration */
-#define                  USB_DMA2ADDRLOW  0xffc03c48   /* Lower 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2ADDRHIGH  0xffc03c4c   /* Upper 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2COUNTLOW  0xffc03c50   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */
-#define                USB_DMA2COUNTHIGH  0xffc03c54   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */
-
-/* USB Channel 3 Config Registers */
-
-#define                  USB_DMA3CONTROL  0xffc03c64   /* DMA master channel 3 configuration */
-#define                  USB_DMA3ADDRLOW  0xffc03c68   /* Lower 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3ADDRHIGH  0xffc03c6c   /* Upper 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3COUNTLOW  0xffc03c70   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */
-#define                USB_DMA3COUNTHIGH  0xffc03c74   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */
-
-/* USB Channel 4 Config Registers */
-
-#define                  USB_DMA4CONTROL  0xffc03c84   /* DMA master channel 4 configuration */
-#define                  USB_DMA4ADDRLOW  0xffc03c88   /* Lower 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4ADDRHIGH  0xffc03c8c   /* Upper 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4COUNTLOW  0xffc03c90   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */
-#define                USB_DMA4COUNTHIGH  0xffc03c94   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */
-
-/* USB Channel 5 Config Registers */
-
-#define                  USB_DMA5CONTROL  0xffc03ca4   /* DMA master channel 5 configuration */
-#define                  USB_DMA5ADDRLOW  0xffc03ca8   /* Lower 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5ADDRHIGH  0xffc03cac   /* Upper 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5COUNTLOW  0xffc03cb0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */
-#define                USB_DMA5COUNTHIGH  0xffc03cb4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */
-
-/* USB Channel 6 Config Registers */
-
-#define                  USB_DMA6CONTROL  0xffc03cc4   /* DMA master channel 6 configuration */
-#define                  USB_DMA6ADDRLOW  0xffc03cc8   /* Lower 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6ADDRHIGH  0xffc03ccc   /* Upper 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6COUNTLOW  0xffc03cd0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */
-#define                USB_DMA6COUNTHIGH  0xffc03cd4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */
-
-/* USB Channel 7 Config Registers */
-
-#define                  USB_DMA7CONTROL  0xffc03ce4   /* DMA master channel 7 configuration */
-#define                  USB_DMA7ADDRLOW  0xffc03ce8   /* Lower 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7ADDRHIGH  0xffc03cec   /* Upper 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7COUNTLOW  0xffc03cf0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */
-#define                USB_DMA7COUNTHIGH  0xffc03cf4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */
-
-/* Bit masks for USB_FADDR */
-
-#define          FUNCTION_ADDRESS  0x7f       /* Function address */
-
-/* Bit masks for USB_POWER */
-
-#define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
-#define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
-#define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
-#define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
-#define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
-#define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
-#define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
-#define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
-
-/* Bit masks for USB_INTRTX */
-
-#define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
-#define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
-#define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
-#define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
-#define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
-#define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
-#define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
-#define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
-
-/* Bit masks for USB_INTRRX */
-
-#define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
-#define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
-#define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
-#define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
-#define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
-#define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
-#define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
-
-/* Bit masks for USB_INTRTXE */
-
-#define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
-#define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
-#define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
-#define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
-#define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
-#define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
-#define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
-#define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
-
-/* Bit masks for USB_INTRRXE */
-
-#define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
-#define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
-#define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
-#define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
-#define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
-#define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
-#define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
-
-/* Bit masks for USB_INTRUSB */
-
-#define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
-#define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
-#define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
-#define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
-#define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
-#define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
-#define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
-#define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
-
-/* Bit masks for USB_INTRUSBE */
-
-#define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
-#define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
-#define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
-#define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
-#define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
-#define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
-#define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
-#define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
-
-/* Bit masks for USB_FRAME */
-
-#define              FRAME_NUMBER  0x7ff      /* Frame number */
-
-/* Bit masks for USB_INDEX */
-
-#define         SELECTED_ENDPOINT  0xf        /* selected endpoint */
-
-/* Bit masks for USB_GLOBAL_CTL */
-
-#define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
-#define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
-#define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
-#define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
-#define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
-#define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
-#define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
-#define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
-#define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
-#define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
-#define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
-#define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
-#define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
-#define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
-#define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
-
-/* Bit masks for USB_OTG_DEV_CTL */
-
-#define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
-#define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
-#define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
-#define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
-#define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
-#define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
-#define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
-#define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
-
-/* Bit masks for USB_OTG_VBUS_IRQ */
-
-#define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
-#define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
-#define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
-#define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
-#define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
-#define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
-
-/* Bit masks for USB_OTG_VBUS_MASK */
-
-#define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
-#define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
-#define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
-#define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
-#define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
-#define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
-
-/* Bit masks for USB_CSR0 */
-
-#define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
-#define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
-#define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
-#define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
-#define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
-#define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
-#define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
-#define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
-#define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
-#define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
-#define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
-#define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
-#define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
-#define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
-#define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
-
-/* Bit masks for USB_COUNT0 */
-
-#define              EP0_RX_COUNT  0x7f       /* number of received bytes in EP0 FIFO */
-
-/* Bit masks for USB_NAKLIMIT0 */
-
-#define             EP0_NAK_LIMIT  0x1f       /* number of frames/micro frames after which EP0 timeouts */
-
-/* Bit masks for USB_TX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_T  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_RX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_R  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_TXCSR */
-
-#define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
-#define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
-#define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
-#define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
-#define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
-#define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
-#define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
-#define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
-#define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
-#define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
-#define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
-#define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
-#define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
-#define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
-#define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
-#define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
-
-/* Bit masks for USB_TXCOUNT */
-
-#define                  TX_COUNT  0x1fff     /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* Bit masks for USB_RXCSR */
-
-#define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
-#define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
-#define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
-#define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
-#define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
-#define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
-#define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
-#define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
-#define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
-#define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
-#define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
-#define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
-#define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
-#define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
-#define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
-#define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
-#define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
-#define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
-#define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
-#define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
-
-/* Bit masks for USB_RXCOUNT */
-
-#define                  RX_COUNT  0x1fff     /* Number of received bytes in the packet in the Rx FIFO */
-
-/* Bit masks for USB_TXTYPE */
-
-#define            TARGET_EP_NO_T  0xf        /* EP number */
-#define                PROTOCOL_T  0xc        /* transfer type */
-
-/* Bit masks for USB_TXINTERVAL */
-
-#define          TX_POLL_INTERVAL  0xff       /* polling interval for selected Tx EP */
-
-/* Bit masks for USB_RXTYPE */
-
-#define            TARGET_EP_NO_R  0xf        /* EP number */
-#define                PROTOCOL_R  0xc        /* transfer type */
-
-/* Bit masks for USB_RXINTERVAL */
-
-#define          RX_POLL_INTERVAL  0xff       /* polling interval for selected Rx EP */
-
-/* Bit masks for USB_DMA_INTERRUPT */
-
-#define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
-#define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
-#define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
-#define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
-#define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
-#define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
-#define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
-#define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
-
-/* Bit masks for USB_DMAxCONTROL */
-
-#define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
-#define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
-#define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
-#define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
-#define                     EPNUM  0xf0       /* EP number */
-#define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
-
-/* Bit masks for USB_DMAxADDRHIGH */
-
-#define             DMA_ADDR_HIGH  0xffff     /* Upper 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxADDRLOW */
-
-#define              DMA_ADDR_LOW  0xffff     /* Lower 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTHIGH */
-
-#define            DMA_COUNT_HIGH  0xffff     /* Upper 16-bits of byte count of DMA transfer for DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTLOW */
-
-#define             DMA_COUNT_LOW  0xffff     /* Lower 16-bits of byte count of DMA transfer for DMA master channel */
-
 #endif /* _DEF_BF527_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -544,7 +544,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register					*/
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register				*/
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register				*/
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register		*/
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register		*/
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register	*/
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register				*/
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register				*/
@@ -552,7 +552,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register					*/
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register				*/
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register				*/
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register		*/
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register		*/
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register	*/
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register				*/
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register				*/
@@ -586,58 +586,6 @@
 **				modifier UNLESS the lower order bits are saved and ORed back in when
 **				the macro is used.
 *************************************************************************************/
-/*
-** ********************* PLL AND RESET MASKS ****************************************/
-/* PLL_CTL Masks																	*/
-#define DF				0x0001	/* 0: PLL = CLKIN, 1: PLL = CLKIN/2					*/
-#define PLL_OFF			0x0002	/* PLL Not Powered									*/
-#define STOPCK			0x0008	/* Core Clock Off									*/
-#define PDWN			0x0020	/* Enter Deep Sleep Mode							*/
-#define	IN_DELAY		0x0040	/* Add 200ps Delay To EBIU Input Latches			*/
-#define	OUT_DELAY		0x0080	/* Add 200ps Delay To EBIU Output Signals			*/
-#define BYPASS			0x0100	/* Bypass the PLL									*/
-#define	MSEL			0x7E00	/* Multiplier Select For CCLK/VCO Factors			*/
-/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits)			*/
-#define	SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL		*/
-
-/* PLL_DIV Masks														*/
-#define SSEL			0x000F	/* System Select						*/
-#define	CSEL			0x0030	/* Core Select							*/
-#define CSEL_DIV1		0x0000	/* 		CCLK = VCO / 1					*/
-#define CSEL_DIV2		0x0010	/* 		CCLK = VCO / 2					*/
-#define	CSEL_DIV4		0x0020	/* 		CCLK = VCO / 4					*/
-#define	CSEL_DIV8		0x0030	/* 		CCLK = VCO / 8					*/
-/* PLL_DIV Macros														*/
-#define SET_SSEL(x)		((x)&0xF)		/* Set SSEL = 0-15 --> SCLK = VCO/SSEL	*/
-
-/* VR_CTL Masks	*/
-#define	FREQ			0x3000	/* Switching Oscillator Frequency For Regulator	*/
-#define	HIBERNATE		0x0000	/* 		Powerdown/Bypass On-Board Regulation	*/
-
-#define	VLEV			0x00F0	/* Internal Voltage Level					*/
-#define	VLEV_085 		0x0060	/* 		VLEV = 0.85 V (-5% - +10% Accuracy)	*/
-#define	VLEV_090		0x0070	/* 		VLEV = 0.90 V (-5% - +10% Accuracy)	*/
-#define	VLEV_095		0x0080	/* 		VLEV = 0.95 V (-5% - +10% Accuracy)	*/
-#define	VLEV_100		0x0090	/* 		VLEV = 1.00 V (-5% - +10% Accuracy)	*/
-#define	VLEV_105		0x00A0	/* 		VLEV = 1.05 V (-5% - +10% Accuracy)	*/
-#define	VLEV_110		0x00B0	/* 		VLEV = 1.10 V (-5% - +10% Accuracy)	*/
-#define	VLEV_115		0x00C0	/* 		VLEV = 1.15 V (-5% - +10% Accuracy)	*/
-#define	VLEV_120		0x00D0	/* 		VLEV = 1.20 V (-5% - +10% Accuracy)	*/
-#define	VLEV_125		0x00E0	/* 		VLEV = 1.25 V (-5% - +10% Accuracy)	*/
-#define	VLEV_130		0x00F0	/* 		VLEV = 1.30 V (-5% - +10% Accuracy)	*/
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate	*/
-#define	USBWE			0x0200	/* Enable USB Wakeup From Hibernate			*/
-#define	PHYWE			0x0400	/* Enable PHY Wakeup From Hibernate			*/
-#define	CLKBUFOE		0x4000	/* CLKIN Buffer Output Enable */
-#define	PHYCLKOE		CLKBUFOE	/* Alternative legacy name for the above */
-#define	SCKELOW		0x8000	/* Enable Drive CKE Low During Reset		*/
-
-/* PLL_STAT Masks																	*/
-#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled	*/
-#define	FULL_ON				0x0002	/* Processor In Full On Mode					*/
-#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled	*/
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been Reached					*/
 
 /* CHIPID Masks */
 #define CHIPID_VERSION         0xF0000000
@@ -757,66 +705,6 @@
 #define IWR_DISABLE(x)	(0xFFFFFFFF ^ (1 << ((x)&0x1F))) 	/* Wakeup Disable Peripheral #x		*/
 
 
-/* ********* WATCHDOG TIMER MASKS ******************** */
-
-/* Watchdog Timer WDOG_CTL Register Masks */
-
-#define WDEV(x) (((x)<<1) & 0x0006) /* event generated on roll over */
-#define WDEV_RESET 0x0000 /* generate reset event on roll over */
-#define WDEV_NMI 0x0002 /* generate NMI event on roll over */
-#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */
-#define WDEV_NONE 0x0006 /* no event on roll over */
-#define WDEN 0x0FF0 /* enable watchdog */
-#define WDDIS 0x0AD0 /* disable watchdog */
-#define WDRO 0x8000 /* watchdog rolled over latch */
-
-/* depreciated WDOG_CTL Register Masks for legacy code */
-
-
-#define ICTL WDEV
-#define ENABLE_RESET WDEV_RESET
-#define WDOG_RESET WDEV_RESET
-#define ENABLE_NMI WDEV_NMI
-#define WDOG_NMI WDEV_NMI
-#define ENABLE_GPI WDEV_GPI
-#define WDOG_GPI WDEV_GPI
-#define DISABLE_EVT WDEV_NONE
-#define WDOG_NONE WDEV_NONE
-
-#define TMR_EN WDEN
-#define TMR_DIS WDDIS
-#define TRO WDRO
-#define ICTL_P0 0x01
- #define ICTL_P1 0x02
-#define TRO_P 0x0F
-
-
-
-/* ***************  REAL TIME CLOCK MASKS  **************************/
-/* RTC_STAT and RTC_ALARM Masks										*/
-#define	RTC_SEC				0x0000003F	/* Real-Time Clock Seconds	*/
-#define	RTC_MIN				0x00000FC0	/* Real-Time Clock Minutes	*/
-#define	RTC_HR				0x0001F000	/* Real-Time Clock Hours	*/
-#define	RTC_DAY				0xFFFE0000	/* Real-Time Clock Days		*/
-
-/* RTC_ALARM Macro			z=day		y=hr	x=min	w=sec		*/
-#define SET_ALARM(z,y,x,w)	((((z)&0x7FFF)<<0x11)|(((y)&0x1F)<<0xC)|(((x)&0x3F)<<0x6)|((w)&0x3F))
-
-/* RTC_ICTL and RTC_ISTAT Masks																		*/
-#define	STOPWATCH			0x0001		/* Stopwatch Interrupt Enable								*/
-#define	ALARM				0x0002		/* Alarm Interrupt Enable									*/
-#define	SECOND				0x0004		/* Seconds (1 Hz) Interrupt Enable							*/
-#define	MINUTE				0x0008		/* Minutes Interrupt Enable									*/
-#define	HOUR				0x0010		/* Hours Interrupt Enable									*/
-#define	DAY					0x0020		/* 24 Hours (Days) Interrupt Enable							*/
-#define	DAY_ALARM			0x0040		/* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable	*/
-#define	WRITE_PENDING		0x4000		/* Write Pending Status										*/
-#define	WRITE_COMPLETE		0x8000		/* Write Complete Interrupt Enable							*/
-
-/* RTC_FAST / RTC_PREN Mask												*/
-#define PREN				0x0001	/* Enable Prescaler, RTC Runs @1 Hz	*/
-
-
 /* ************** UART CONTROLLER MASKS *************************/
 /* UARTx_LCR Masks												*/
 #define WLS(x)		(((x)-5) & 0x03)	/* Word Length Select */
@@ -1381,33 +1269,6 @@
 
 
 /* **************************  DMA CONTROLLER MASKS  ********************************/
-/* DMAx_CONFIG, MDMA_yy_CONFIG Masks												*/
-#define DMAEN			0x0001		/* DMA Channel Enable							*/
-#define WNR				0x0002		/* Channel Direction (W/R*)						*/
-#define WDSIZE_8		0x0000		/* Transfer Word Size = 8						*/
-#define WDSIZE_16		0x0004		/* Transfer Word Size = 16						*/
-#define WDSIZE_32		0x0008		/* Transfer Word Size = 32						*/
-#define DMA2D			0x0010		/* DMA Mode (2D/1D*)							*/
-#define RESTART			0x0020		/* DMA Buffer Clear								*/
-#define DI_SEL			0x0040		/* Data Interrupt Timing Select					*/
-#define DI_EN			0x0080		/* Data Interrupt Enable						*/
-#define NDSIZE_0		0x0000		/* Next Descriptor Size = 0 (Stop/Autobuffer)	*/
-#define NDSIZE_1		0x0100		/* Next Descriptor Size = 1						*/
-#define NDSIZE_2		0x0200		/* Next Descriptor Size = 2						*/
-#define NDSIZE_3		0x0300		/* Next Descriptor Size = 3						*/
-#define NDSIZE_4		0x0400		/* Next Descriptor Size = 4						*/
-#define NDSIZE_5		0x0500		/* Next Descriptor Size = 5						*/
-#define NDSIZE_6		0x0600		/* Next Descriptor Size = 6						*/
-#define NDSIZE_7		0x0700		/* Next Descriptor Size = 7						*/
-#define NDSIZE_8		0x0800		/* Next Descriptor Size = 8						*/
-#define NDSIZE_9		0x0900		/* Next Descriptor Size = 9						*/
-#define NDSIZE	        	0x0900	/* Next Descriptor Size */
-#define DMAFLOW	        	0x7000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000		/* Stop Mode									*/
-#define DMAFLOW_AUTO		0x1000		/* Autobuffer Mode								*/
-#define DMAFLOW_ARRAY		0x4000		/* Descriptor Array Mode						*/
-#define DMAFLOW_SMALL		0x6000		/* Small Model Descriptor List Mode				*/
-#define DMAFLOW_LARGE		0x7000		/* Large Model Descriptor List Mode				*/
 
 /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks								*/
 #define CTYPE			0x0040	/* DMA Channel Type Indicator (Memory/Peripheral*)	*/
@@ -1425,13 +1286,6 @@
 #define	PMAP_UART1RX	0xA000	/* 		UART1 Port Receive DMA						*/
 #define	PMAP_UART1TX	0xB000	/* 		UART1 Port Transmit DMA						*/
 
-/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks						*/
-#define DMA_DONE		0x0001	/* DMA Completion Interrupt Status	*/
-#define DMA_ERR			0x0002	/* DMA Error Interrupt Status		*/
-#define DFETCH			0x0004	/* DMA Descriptor Fetch Indicator	*/
-#define DMA_RUN			0x0008	/* DMA Channel Running Indicator	*/
-
-
 /*  ************  PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
 /*  PPI_CONTROL Masks													*/
 #define PORT_EN			0x0001		/* PPI Port Enable					*/
@@ -1843,46 +1697,6 @@
 #define BNDMODE_CAPT     0x2000  /* boundary capture mode */
 #define BNDMODE_AEXT     0x3000  /* boundary auto-extend mode */
 
-/* Bit masks for OTP_CONTROL */
-
-#define                FUSE_FADDR  0x1ff      /* OTP/Fuse Address */
-#define                      FIEN  0x800      /* OTP/Fuse Interrupt Enable */
-#define                     nFIEN  0x0
-#define                  FTESTDEC  0x1000     /* OTP/Fuse Test Decoder */
-#define                 nFTESTDEC  0x0
-#define                   FWRTEST  0x2000     /* OTP/Fuse Write Test */
-#define                  nFWRTEST  0x0
-#define                     FRDEN  0x4000     /* OTP/Fuse Read Enable */
-#define                    nFRDEN  0x0
-#define                     FWREN  0x8000     /* OTP/Fuse Write Enable */
-#define                    nFWREN  0x0
-
-/* Bit masks for OTP_BEN */
-
-#define                      FBEN  0xffff     /* OTP/Fuse Byte Enable */
-
-/* Bit masks for OTP_STATUS */
-
-#define                     FCOMP  0x1        /* OTP/Fuse Access Complete */
-#define                    nFCOMP  0x0
-#define                    FERROR  0x2        /* OTP/Fuse Access Error */
-#define                   nFERROR  0x0
-#define                  MMRGLOAD  0x10       /* Memory Mapped Register Gasket Load */
-#define                 nMMRGLOAD  0x0
-#define                  MMRGLOCK  0x20       /* Memory Mapped Register Gasket Lock */
-#define                 nMMRGLOCK  0x0
-#define                    FPGMEN  0x40       /* OTP/Fuse Program Enable */
-#define                   nFPGMEN  0x0
-
-/* Bit masks for OTP_TIMING */
-
-#define                   USECDIV  0xff       /* Micro Second Divider */
-#define                   READACC  0x7f00     /* Read Access Time */
-#define                   CPUMPRL  0x38000    /* Charge Pump Release Time */
-#define                   CPUMPSU  0xc0000    /* Charge Pump Setup Time */
-#define                   CPUMPHD  0xf00000   /* Charge Pump Hold Time */
-#define                   PGMTIME  0xff000000 /* Program Time */
-
 /* Bit masks for SECURE_SYSSWT */
 
 #define                   EMUDABL  0x1        /* Emulation Disable. */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/Kconfig linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/Kconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf527/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf527/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,7 @@
+config BF52x
+	def_bool y
+	depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527)
+
 if (BF52x)
 
 source "arch/blackfin/mach-bf527/boards/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/H8606.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/H8606.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/H8606.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/H8606.c	2010-02-24 13:52:17.000000000 -0500
@@ -166,7 +166,6 @@ static struct bfin5xx_spi_chip spi_flash
 #if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
 /* SPI ADC chip */
 static struct bfin5xx_spi_chip spi_adc_chip_info = {
-	.ctl_reg = 0x1000,
 	.enable_dma = 1,         /* use dma transfer with this chip*/
 	.bits_per_word = 16,
 };
@@ -174,7 +173,6 @@ static struct bfin5xx_spi_chip spi_adc_c
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
-	.ctl_reg = 0x1000,
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
@@ -258,12 +256,6 @@ static struct platform_device bfin_spi0_
 };
 #endif  /* spi master and devices */
 
-#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
-static struct platform_device bfin_fb_device = {
-	.name = "bf537-fb",
-};
-#endif
-
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 	{
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/ip0x.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #endif
 #include <asm/irq.h>
 #include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -107,20 +108,6 @@ static struct platform_device dm9000_dev
 
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
-/*
- * CPOL (Clock Polarity)
- *  0 - Active high SCK
- *  1 - Active low SCK
- *  CPHA (Clock Phase) Selects transfer format and operation mode
- *  0 - SCLK toggles from middle of the first data bit, slave select
- *      pins controlled by hardware.
- *  1 - SCLK toggles from beginning of first data bit, slave select
- *      pins controller by user software.
- * 	.ctl_reg = 0x1c00,		 *  CPOL=1,CPHA=1,Sandisk 1G work
- * NO NO	.ctl_reg = 0x1800,		 *  CPOL=1,CPHA=0
- * NO NO	.ctl_reg = 0x1400,		 *  CPOL=0,CPHA=1
- */
-	.ctl_reg = 0x1000,		/* CPOL=0,CPHA=0,Sandisk 1G work */
 	.enable_dma = 0,		/* if 1 - block!!! */
 	.bits_per_word = 8,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/stamp.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/stamp.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/boards/stamp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/boards/stamp.c	2010-02-24 13:52:17.000000000 -0500
@@ -321,12 +321,6 @@ static struct platform_device bfin_spi0_
 };
 #endif  /* spi master and devices */
 
-#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
-static struct platform_device bfin_fb_device = {
-	.name = "bf537-fb",
-};
-#endif
-
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 	{
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/include/mach/defBF532.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/include/mach/defBF532.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf533/include/mach/defBF532.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf533/include/mach/defBF532.h	2010-02-24 13:52:17.000000000 -0500
@@ -370,72 +370,6 @@
 /* System MMR Register Bits */
 /******************************************************************************* */
 
-/* ********************* PLL AND RESET MASKS ************************ */
-
-/* PLL_CTL Masks */
-#define PLL_CLKIN			0x0000  /* Pass CLKIN to PLL */
-#define PLL_CLKIN_DIV2			0x0001  /* Pass CLKIN/2 to PLL */
-#define DF				0x0001	/* 0: PLL = CLKIN, 1: PLL = CLKIN/2					*/
-#define PLL_OFF				0x0002  /* Shut off PLL clocks */
-#define STOPCK_OFF			0x0008  /* Core clock off */
-#define STOPCK				0x0008	/* Core Clock Off									*/
-#define PDWN				0x0020  /* Put the PLL in a Deep Sleep state */
-#if !defined(__ADSPBF538__)
-/* this file is included in defBF538.h but IN_DELAY/OUT_DELAY are different */
-# define IN_DELAY        0x0040  /* Add 200ps Delay To EBIU Input Latches */
-# define OUT_DELAY       0x0080  /* Add 200ps Delay To EBIU Output Signals */
-#endif
-#define BYPASS				0x0100  /* Bypass the PLL */
-/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits)			*/
-#define	SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL		*/
-
-/* PLL_DIV Masks */
-#define SSEL				0x000F	/* System Select						*/
-#define	CSEL				0x0030	/* Core Select							*/
-
-#define SCLK_DIV(x)  (x)	/* SCLK = VCO / x */
-
-#define CCLK_DIV1              0x00000000	/* CCLK = VCO / 1 */
-#define CCLK_DIV2              0x00000010	/* CCLK = VCO / 2 */
-#define CCLK_DIV4              0x00000020	/* CCLK = VCO / 4 */
-#define CCLK_DIV8              0x00000030	/* CCLK = VCO / 8 */
-/* PLL_DIV Macros														*/
-#define SET_SSEL(x)			((x)&0xF)	/* Set SSEL = 0-15 --> SCLK = VCO/SSEL	*/
-
-/* PLL_STAT Masks																	*/
-#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled    */
-#define	FULL_ON				0x0002	/* Processor In Full On Mode                                    */
-#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled   */
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been Reached                                 */
-
-/* VR_CTL Masks																	*/
-#define	FREQ			0x0003	/* Switching Oscillator Frequency For Regulator	*/
-#define	HIBERNATE		0x0000	/* 		Powerdown/Bypass On-Board Regulation	*/
-#define	FREQ_333		0x0001	/* 		Switching Frequency Is 333 kHz			*/
-#define	FREQ_667		0x0002	/* 		Switching Frequency Is 667 kHz			*/
-#define	FREQ_1000		0x0003	/* 		Switching Frequency Is 1 MHz			*/
-
-#define GAIN			0x000C	/* Voltage Level Gain	*/
-#define	GAIN_5			0x0000	/* 		GAIN = 5		*/
-#define	GAIN_10			0x0004	/* 		GAIN = 10		*/
-#define	GAIN_20			0x0008	/* 		GAIN = 20		*/
-#define	GAIN_50			0x000C	/* 		GAIN = 50		*/
-
-#define	VLEV			0x00F0	/* Internal Voltage Level					*/
-#define	VLEV_085 		0x0060	/* 		VLEV = 0.85 V (-5% - +10% Accuracy)	*/
-#define	VLEV_090		0x0070	/* 		VLEV = 0.90 V (-5% - +10% Accuracy)	*/
-#define	VLEV_095		0x0080	/* 		VLEV = 0.95 V (-5% - +10% Accuracy)	*/
-#define	VLEV_100		0x0090	/* 		VLEV = 1.00 V (-5% - +10% Accuracy)	*/
-#define	VLEV_105		0x00A0	/* 		VLEV = 1.05 V (-5% - +10% Accuracy)	*/
-#define	VLEV_110		0x00B0	/* 		VLEV = 1.10 V (-5% - +10% Accuracy)	*/
-#define	VLEV_115		0x00C0	/* 		VLEV = 1.15 V (-5% - +10% Accuracy)	*/
-#define	VLEV_120		0x00D0	/* 		VLEV = 1.20 V (-5% - +10% Accuracy)	*/
-#define	VLEV_125		0x00E0	/*              VLEV = 1.25 V (-5% - +10% Accuracy)     */
-#define	VLEV_130		0x00F0	/*              VLEV = 1.30 V (-5% - +10% Accuracy)     */
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate	*/
-#define	SCKELOW			0x8000	/* Do Not Drive SCKE High During Reset After Hibernate */
-
 /* CHIPID Masks */
 #define CHIPID_VERSION         0xF0000000
 #define CHIPID_FAMILY          0x0FFFF000
@@ -703,54 +637,7 @@
 
 /* **********  DMA CONTROLLER MASKS  *********************8 */
 
-/*DMAx_CONFIG, MDMA_yy_CONFIG Masks */
-#define DMAEN	        0x00000001	/* Channel Enable */
-#define WNR	   	0x00000002	/* Channel Direction (W/R*) */
-#define WDSIZE_8	0x00000000	/* Word Size 8 bits */
-#define WDSIZE_16	0x00000004	/* Word Size 16 bits */
-#define WDSIZE_32	0x00000008	/* Word Size 32 bits */
-#define DMA2D	        0x00000010	/* 2D/1D* Mode */
-#define RESTART         0x00000020	/* Restart */
-#define DI_SEL	        0x00000040	/* Data Interrupt Select */
-#define DI_EN	        0x00000080	/* Data Interrupt Enable */
-#define NDSIZE_0		0x0000	/* Next Descriptor Size = 0 (Stop/Autobuffer)   */
-#define NDSIZE_1		0x0100	/* Next Descriptor Size = 1                                             */
-#define NDSIZE_2		0x0200	/* Next Descriptor Size = 2                                             */
-#define NDSIZE_3		0x0300	/* Next Descriptor Size = 3                                             */
-#define NDSIZE_4		0x0400	/* Next Descriptor Size = 4                                             */
-#define NDSIZE_5		0x0500	/* Next Descriptor Size = 5                                             */
-#define NDSIZE_6		0x0600	/* Next Descriptor Size = 6                                             */
-#define NDSIZE_7		0x0700	/* Next Descriptor Size = 7                                             */
-#define NDSIZE_8		0x0800	/* Next Descriptor Size = 8                                             */
-#define NDSIZE_9		0x0900	/* Next Descriptor Size = 9                                             */
-#define NDSIZE	        0x00000900	/* Next Descriptor Size */
-#define DMAFLOW	        0x00007000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000	/* Stop Mode */
-#define DMAFLOW_AUTO		0x1000	/* Autobuffer Mode */
-#define DMAFLOW_ARRAY		0x4000	/* Descriptor Array Mode */
-#define DMAFLOW_SMALL		0x6000	/* Small Model Descriptor List Mode */
-#define DMAFLOW_LARGE		0x7000	/* Large Model Descriptor List Mode */
-
-#define DMAEN_P	            	0	/* Channel Enable */
-#define WNR_P	            	1	/* Channel Direction (W/R*) */
-#define DMA2D_P	        	4	/* 2D/1D* Mode */
-#define RESTART_P	      	5	/* Restart */
-#define DI_SEL_P	     	6	/* Data Interrupt Select */
-#define DI_EN_P	            	7	/* Data Interrupt Enable */
-
-/*DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */
-
-#define DMA_DONE		0x00000001	/* DMA Done Indicator */
-#define DMA_ERR	        	0x00000002	/* DMA Error Indicator */
-#define DFETCH	            	0x00000004	/* Descriptor Fetch Indicator */
-#define DMA_RUN	            	0x00000008	/* DMA Running Indicator */
-
-#define DMA_DONE_P	    	0	/* DMA Done Indicator */
-#define DMA_ERR_P     		1	/* DMA Error Indicator */
-#define DFETCH_P     		2	/* Descriptor Fetch Indicator */
-#define DMA_RUN_P     		3	/* DMA Running Indicator */
-
-/*DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
 
 #define CTYPE	            0x00000040	/* DMA Channel Type Indicator */
 #define CTYPE_P             6	/* DMA Channel Type Indicator BIT POSITION */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/pnav10.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,9 +13,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-#include <linux/usb/isp1362.h>
-#endif
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
@@ -147,45 +144,6 @@ static struct platform_device sl811_hcd_
 };
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-static struct resource isp1362_hcd_resources[] = {
-	{
-		.start = 0x20360000,
-		.end = 0x20360000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20360004,
-		.end = 0x20360004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-static struct isp1362_platform_data isp1362_priv = {
-	.sel15Kres = 1,
-	.clknotstop = 0,
-	.oc_enable = 0,
-	.int_act_high = 0,
-	.int_edge_triggered = 0,
-	.remote_wakeup_connected = 0,
-	.no_power_switching = 1,
-	.power_switching_mode = 0,
-};
-
-static struct platform_device isp1362_hcd_device = {
-	.name = "isp1362-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &isp1362_priv,
-	},
-	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
-	.resource = isp1362_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -492,10 +450,6 @@ static struct platform_device *stamp_dev
 	&sl811_hcd_device,
 #endif
 
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-	&isp1362_hcd_device,
-#endif
-
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 	&smc91x_device,
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/boards/stamp.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
@@ -25,6 +26,8 @@
 #include <linux/i2c.h>
 #include <linux/usb/sl811.h>
 #include <linux/spi/mmc_spi.h>
+#include <linux/leds.h>
+#include <linux/input.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
@@ -65,7 +68,7 @@ static struct isp1760_platform_data isp1
 };
 
 static struct platform_device bfin_isp1760_device = {
-	.name           = "isp1760-hcd",
+	.name           = "isp1760",
 	.id             = 0,
 	.dev = {
 		.platform_data = &isp1760_priv,
@@ -76,7 +79,6 @@ static struct platform_device bfin_isp17
 #endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-#include <linux/input.h>
 #include <linux/gpio_keys.h>
 
 static struct gpio_keys_button bfin_gpio_keys_table[] = {
@@ -195,28 +197,6 @@ static struct platform_device dm9000_dev
 };
 #endif
 
-#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE)
-static struct resource ax88180_resources[] = {
-	[0] = {
-		.start	= 0x20300000,
-		.end	= 0x20300000 + 0x8000,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PF7,
-		.end	= IRQ_PF7,
-		.flags	= (IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL),
-	},
-};
-
-static struct platform_device ax88180_device = {
-	.name		= "ax88180",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ax88180_resources),
-	.resource	= ax88180_resources,
-};
-#endif
-
 #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
 static struct resource sl811_hcd_resources[] = {
 	{
@@ -272,8 +252,8 @@ static struct resource isp1362_hcd_resou
 		.end = 0x20360004,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
-		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+		.start = IRQ_PF3,
+		.end = IRQ_PF3,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
 	},
 };
@@ -300,6 +280,44 @@ static struct platform_device isp1362_hc
 };
 #endif
 
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+unsigned short bfin_can_peripherals[] = {
+	P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static struct resource bfin_can_resources[] = {
+	{
+		.start = 0xFFC02A00,
+		.end = 0xFFC02FFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_CAN_RX,
+		.end = IRQ_CAN_RX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN_TX,
+		.end = IRQ_CAN_TX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN_ERROR,
+		.end = IRQ_CAN_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_can_device = {
+	.name = "bfin_can",
+	.num_resources = ARRAY_SIZE(bfin_can_resources),
+	.resource = bfin_can_resources,
+	.dev = {
+		.platform_data = &bfin_can_peripherals, /* Passed to driver */
+	},
+};
+#endif
+
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
 	.name = "bfin_mii_bus",
@@ -514,15 +532,14 @@ static struct bfin5xx_spi_chip ad1938_sp
 };
 #endif
 
-#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
-#include <linux/input.h>
+#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE)
 #include <linux/input/ad714x.h>
 static struct bfin5xx_spi_chip ad7147_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
 
-static struct ad714x_slider_plat slider_plat[] = {
+static struct ad714x_slider_plat ad7147_spi_slider_plat[] = {
 	{
 		.start_stage = 0,
 		.end_stage = 7,
@@ -530,7 +547,7 @@ static struct ad714x_slider_plat slider_
 	},
 };
 
-static struct ad714x_button_plat button_plat[] = {
+static struct ad714x_button_plat ad7147_spi_button_plat[] = {
 	{
 		.keycode = BTN_FORWARD,
 		.l_mask = 0,
@@ -557,11 +574,11 @@ static struct ad714x_button_plat button_
 		.h_mask = 0x400,
 	},
 };
-static struct ad714x_platform_data ad7147_platfrom_data = {
+static struct ad714x_platform_data ad7147_spi_platform_data = {
 	.slider_num = 1,
 	.button_num = 5,
-	.slider = slider_plat,
-	.button = button_plat,
+	.slider = ad7147_spi_slider_plat,
+	.button = ad7147_spi_button_plat,
 	.stage_cfg_reg =  {
 		{0xFBFF, 0x1FFF, 0, 0x2626, 1600, 1600, 1600, 1600},
 		{0xEFFF, 0x1FFF, 0, 0x2626, 1650, 1650, 1650, 1650},
@@ -580,10 +597,9 @@ static struct ad714x_platform_data ad714
 };
 #endif
 
-#if defined(CONFIG_INPUT_EVAL_AD7142EB)
-#include <linux/input.h>
+#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
 #include <linux/input/ad714x.h>
-static struct ad714x_button_plat button_plat[] = {
+static struct ad714x_button_plat ad7142_i2c_button_plat[] = {
 	{
 		.keycode = BTN_1,
 		.l_mask = 0,
@@ -605,9 +621,9 @@ static struct ad714x_button_plat button_
 		.h_mask = 0x8,
 	},
 };
-static struct ad714x_platform_data ad7142_platfrom_data = {
+static struct ad714x_platform_data ad7142_i2c_platform_data = {
 	.button_num = 4,
-	.button = button_plat,
+	.button = ad7142_i2c_button_plat,
 	.stage_cfg_reg =  {
 		/* fixme: figure out right setting for all comoponent according
 		 * to hardware feature of EVAL-AD7142EB board */
@@ -696,8 +712,7 @@ static const struct ad7879_platform_data
 #endif
 
 #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE)
-#include <linux/input.h>
-#include <linux/spi/adxl34x.h>
+#include <linux/input/adxl34x.h>
 static const struct adxl34x_platform_data adxl34x_info = {
 	.x_axis_offset = 0,
 	.y_axis_offset = 0,
@@ -721,9 +736,7 @@ static const struct adxl34x_platform_dat
 	.ev_code_y = ABS_Y,		/* EV_REL */
 	.ev_code_z = ABS_Z,		/* EV_REL */
 
-	.ev_code_tap_x = BTN_TOUCH,		/* EV_KEY */
-	.ev_code_tap_y = BTN_TOUCH,		/* EV_KEY */
-	.ev_code_tap_z = BTN_TOUCH,		/* EV_KEY */
+	.ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */
 
 /*	.ev_code_ff = KEY_F,*/		/* EV_KEY */
 /*	.ev_code_act_inactivity = KEY_A,*/	/* EV_KEY */
@@ -761,6 +774,47 @@ static struct bfin5xx_spi_chip enc28j60_
 };
 #endif
 
+#if defined(CONFIG_ADF702X) || defined(CONFIG_ADF702X_MODULE)
+static struct bfin5xx_spi_chip adf7021_spi_chip_info = {
+	.bits_per_word = 16,
+	.cs_gpio = GPIO_PF10,
+};
+
+#include <linux/spi/adf702x.h>
+#define TXREG 0x0160A470
+static const u32 adf7021_regs[] = {
+	0x09608FA0,
+	0x00575011,
+	0x00A7F092,
+	0x2B141563,
+	0x81F29E94,
+	0x00003155,
+	0x050A4F66,
+	0x00000007,
+	0x00000008,
+	0x000231E9,
+	0x3296354A,
+	0x891A2B3B,
+	0x00000D9C,
+	0x0000000D,
+	0x0000000E,
+	0x0000000F,
+};
+
+static struct adf702x_platform_data adf7021_platform_data = {
+	.regs_base = (void *)SPORT1_TCR1,
+	.dma_ch_rx = CH_SPORT1_RX,
+	.dma_ch_tx = CH_SPORT1_TX,
+	.irq_sport_err = IRQ_SPORT1_ERROR,
+	.gpio_int_rfs = GPIO_PF8,
+	.pin_req = {P_SPORT1_DTPRI, P_SPORT1_RFS, P_SPORT1_DRPRI,
+			P_SPORT1_RSCLK, P_SPORT1_TSCLK, 0},
+	.adf702x_model = MODEL_ADF7021,
+	.adf702x_regs = adf7021_regs,
+	.tx_reg = TXREG,
+};
+#endif
+
 #if defined(CONFIG_MTD_DATAFLASH) \
 	|| defined(CONFIG_MTD_DATAFLASH_MODULE)
 
@@ -794,6 +848,13 @@ static struct bfin5xx_spi_chip data_flas
 };
 #endif
 
+#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE)
+static struct bfin5xx_spi_chip spi_adxl34x_chip_info = {
+	.enable_dma = 0,         /* use dma transfer with this chip*/
+	.bits_per_word = 8,
+};
+#endif
+
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
 	|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -855,7 +916,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 
-#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
+#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE)
 	{
 		.modalias = "ad714x_captouch",
 		.max_speed_hz = 1000000,     /* max spi clock (SCK) speed in HZ */
@@ -863,7 +924,7 @@ static struct spi_board_info bfin_spi_bo
 		.bus_num = 0,
 		.chip_select = 5,
 		.mode = SPI_MODE_3,
-		.platform_data = &ad7147_platfrom_data,
+		.platform_data = &ad7147_spi_platform_data,
 		.controller_data = &ad7147_spi_chip_info,
 	},
 #endif
@@ -932,6 +993,30 @@ static struct spi_board_info bfin_spi_bo
 		.mode = SPI_MODE_0,
 	},
 #endif
+#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE)
+	{
+		.modalias	= "adxl34x",
+		.platform_data	= &adxl34x_info,
+		.irq		= IRQ_PF6,
+		.max_speed_hz	= 5000000,    /* max spi clock (SCK) speed in HZ */
+		.bus_num	= 0,
+		.chip_select	= 2,
+		.controller_data = &spi_adxl34x_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+#if defined(CONFIG_ADF702X) || defined(CONFIG_ADF702X_MODULE)
+	{
+		.modalias = "adf702x",
+		.max_speed_hz = 16000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 0,	/* GPIO controlled SSEL */
+		.controller_data = &adf7021_spi_chip_info,
+		.platform_data = &adf7021_platform_data,
+		.mode = SPI_MODE_0,
+	},
+#endif
+
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -1175,7 +1260,6 @@ static struct platform_device i2c_bfin_t
 #endif
 
 #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
-#include <linux/input.h>
 #include <linux/i2c/adp5588.h>
 static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
 	[0]	 = KEY_GRAVE,
@@ -1268,35 +1352,33 @@ static struct adp5588_kpad_platform_data
 	 *  ADP5520/5501 Backlight Data
 	 */
 
-static struct adp5520_backlight_platfrom_data adp5520_backlight_data = {
-	.fade_in 		= FADE_T_1200ms,
-	.fade_out 		= FADE_T_1200ms,
-	.fade_led_law 		= BL_LAW_LINEAR,
-	.en_ambl_sens 		= 1,
-	.abml_filt 		= BL_AMBL_FILT_640ms,
-	.l1_daylight_max 	= BL_CUR_mA(15),
-	.l1_daylight_dim 	= BL_CUR_mA(0),
-	.l2_office_max 		= BL_CUR_mA(7),
-	.l2_office_dim 		= BL_CUR_mA(0),
-	.l3_dark_max 		= BL_CUR_mA(3),
-	.l3_dark_dim 		= BL_CUR_mA(0),
-	.l2_trip 		= L2_COMP_CURR_uA(700),
-	.l2_hyst 		= L2_COMP_CURR_uA(50),
-	.l3_trip 		= L3_COMP_CURR_uA(80),
-	.l3_hyst 		= L3_COMP_CURR_uA(20),
+static struct adp5520_backlight_platform_data adp5520_backlight_data = {
+	.fade_in		= ADP5520_FADE_T_1200ms,
+	.fade_out		= ADP5520_FADE_T_1200ms,
+	.fade_led_law		= ADP5520_BL_LAW_LINEAR,
+	.en_ambl_sens		= 1,
+	.abml_filt		= ADP5520_BL_AMBL_FILT_640ms,
+	.l1_daylight_max	= ADP5520_BL_CUR_mA(15),
+	.l1_daylight_dim	= ADP5520_BL_CUR_mA(0),
+	.l2_office_max		= ADP5520_BL_CUR_mA(7),
+	.l2_office_dim		= ADP5520_BL_CUR_mA(0),
+	.l3_dark_max		= ADP5520_BL_CUR_mA(3),
+	.l3_dark_dim		= ADP5520_BL_CUR_mA(0),
+	.l2_trip		= ADP5520_L2_COMP_CURR_uA(700),
+	.l2_hyst		= ADP5520_L2_COMP_CURR_uA(50),
+	.l3_trip		= ADP5520_L3_COMP_CURR_uA(80),
+	.l3_hyst		= ADP5520_L3_COMP_CURR_uA(20),
 };
 
 	/*
 	 *  ADP5520/5501 LEDs Data
 	 */
 
-#include <linux/leds.h>
-
 static struct led_info adp5520_leds[] = {
 	{
 		.name = "adp5520-led1",
 		.default_trigger = "none",
-		.flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | LED_OFFT_600ms,
+		.flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms,
 	},
 #ifdef ADP5520_EN_ALL_LEDS
 	{
@@ -1312,51 +1394,50 @@ static struct led_info adp5520_leds[] =
 #endif
 };
 
-static struct adp5520_leds_platfrom_data adp5520_leds_data = {
+static struct adp5520_leds_platform_data adp5520_leds_data = {
 	.num_leds = ARRAY_SIZE(adp5520_leds),
 	.leds = adp5520_leds,
-	.fade_in = FADE_T_600ms,
-	.fade_out = FADE_T_600ms,
-	.led_on_time = LED_ONT_600ms,
+	.fade_in = ADP5520_FADE_T_600ms,
+	.fade_out = ADP5520_FADE_T_600ms,
+	.led_on_time = ADP5520_LED_ONT_600ms,
 };
 
 	/*
 	 *  ADP5520 GPIO Data
 	 */
 
-static struct adp5520_gpio_platfrom_data adp5520_gpio_data = {
+static struct adp5520_gpio_platform_data adp5520_gpio_data = {
 	.gpio_start = 50,
-	.gpio_en_mask = GPIO_C1 | GPIO_C2 | GPIO_R2,
-	.gpio_pullup_mask = GPIO_C1 | GPIO_C2 | GPIO_R2,
+	.gpio_en_mask = ADP5520_GPIO_C1 | ADP5520_GPIO_C2 | ADP5520_GPIO_R2,
+	.gpio_pullup_mask = ADP5520_GPIO_C1 | ADP5520_GPIO_C2 | ADP5520_GPIO_R2,
 };
 
 	/*
 	 *  ADP5520 Keypad Data
 	 */
 
-#include <linux/input.h>
 static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = {
-	[KEY(0, 0)]	= KEY_GRAVE,
-	[KEY(0, 1)]	= KEY_1,
-	[KEY(0, 2)]	= KEY_2,
-	[KEY(0, 3)]	= KEY_3,
-	[KEY(1, 0)]	= KEY_4,
-	[KEY(1, 1)]	= KEY_5,
-	[KEY(1, 2)]	= KEY_6,
-	[KEY(1, 3)]	= KEY_7,
-	[KEY(2, 0)]	= KEY_8,
-	[KEY(2, 1)]	= KEY_9,
-	[KEY(2, 2)]	= KEY_0,
-	[KEY(2, 3)]	= KEY_MINUS,
-	[KEY(3, 0)]	= KEY_EQUAL,
-	[KEY(3, 1)]	= KEY_BACKSLASH,
-	[KEY(3, 2)]	= KEY_BACKSPACE,
-	[KEY(3, 3)]	= KEY_ENTER,
+	[ADP5520_KEY(0, 0)]	= KEY_GRAVE,
+	[ADP5520_KEY(0, 1)]	= KEY_1,
+	[ADP5520_KEY(0, 2)]	= KEY_2,
+	[ADP5520_KEY(0, 3)]	= KEY_3,
+	[ADP5520_KEY(1, 0)]	= KEY_4,
+	[ADP5520_KEY(1, 1)]	= KEY_5,
+	[ADP5520_KEY(1, 2)]	= KEY_6,
+	[ADP5520_KEY(1, 3)]	= KEY_7,
+	[ADP5520_KEY(2, 0)]	= KEY_8,
+	[ADP5520_KEY(2, 1)]	= KEY_9,
+	[ADP5520_KEY(2, 2)]	= KEY_0,
+	[ADP5520_KEY(2, 3)]	= KEY_MINUS,
+	[ADP5520_KEY(3, 0)]	= KEY_EQUAL,
+	[ADP5520_KEY(3, 1)]	= KEY_BACKSLASH,
+	[ADP5520_KEY(3, 2)]	= KEY_BACKSPACE,
+	[ADP5520_KEY(3, 3)]	= KEY_ENTER,
 };
 
-static struct adp5520_keys_platfrom_data adp5520_keys_data = {
-	.rows_en_mask	= ROW_R3 | ROW_R2 | ROW_R1 | ROW_R0,
-	.cols_en_mask	= COL_C3 | COL_C2 | COL_C1 | COL_C0,
+static struct adp5520_keys_platform_data adp5520_keys_data = {
+	.rows_en_mask	= ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0,
+	.cols_en_mask	= ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0,
 	.keymap		= adp5520_keymap,
 	.keymapsize	= ARRAY_SIZE(adp5520_keymap),
 	.repeat		= 0,
@@ -1366,50 +1447,81 @@ static struct adp5520_keys_platfrom_data
 	 *  ADP5520/5501 Multifuction Device Init Data
 	 */
 
-static struct adp5520_subdev_info adp5520_subdevs[] = {
-	{
-		.name = "adp5520-backlight",
-		.id = ID_ADP5520,
-		.platform_data = &adp5520_backlight_data,
-	},
-	{
-		.name = "adp5520-led",
-		.id = ID_ADP5520,
-		.platform_data = &adp5520_leds_data,
-	},
-	{
-		.name = "adp5520-gpio",
-		.id = ID_ADP5520,
-		.platform_data = &adp5520_gpio_data,
-	},
-	{
-		.name = "adp5520-keys",
-		.id = ID_ADP5520,
-		.platform_data = &adp5520_keys_data,
-	},
-};
-
 static struct adp5520_platform_data adp5520_pdev_data = {
-	.num_subdevs = ARRAY_SIZE(adp5520_subdevs),
-	.subdevs = adp5520_subdevs,
+	.backlight = &adp5520_backlight_data,
+	.leds = &adp5520_leds_data,
+	.gpio = &adp5520_gpio_data,
+	.keys = &adp5520_keys_data,
 };
 
 #endif
 
 #if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
 #include <linux/i2c/adp5588.h>
-static struct adp5588_gpio_platfrom_data adp5588_gpio_data = {
+static struct adp5588_gpio_platform_data adp5588_gpio_data = {
 	.gpio_start = 50,
 	.pullup_dis_mask = 0,
 };
 #endif
 
+#if defined(CONFIG_BACKLIGHT_ADP8870) || defined(CONFIG_BACKLIGHT_ADP8870_MODULE)
+#include <linux/i2c/adp8870.h>
+static struct led_info adp8870_leds[] = {
+	{
+		.name = "adp8870-led7",
+		.default_trigger = "none",
+		.flags = ADP8870_LED_D7 | ADP8870_LED_OFFT_600ms,
+	},
+};
+
+
+static struct adp8870_backlight_platform_data adp8870_pdata = {
+	.bl_led_assign = ADP8870_BL_D1 | ADP8870_BL_D2 | ADP8870_BL_D3 |
+			 ADP8870_BL_D4 | ADP8870_BL_D5 | ADP8870_BL_D6,	/* 1 = Backlight 0 = Individual LED */
+	.pwm_assign = 0,				/* 1 = Enables PWM mode */
+
+	.bl_fade_in = ADP8870_FADE_T_1200ms,		/* Backlight Fade-In Timer */
+	.bl_fade_out = ADP8870_FADE_T_1200ms,		/* Backlight Fade-Out Timer */
+	.bl_fade_law = ADP8870_FADE_LAW_CUBIC1,		/* fade-on/fade-off transfer characteristic */
+
+	.en_ambl_sens = 1,				/* 1 = enable ambient light sensor */
+	.abml_filt = ADP8870_BL_AMBL_FILT_320ms,	/* Light sensor filter time */
+
+	.l1_daylight_max = ADP8870_BL_CUR_mA(20),	/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l1_daylight_dim = ADP8870_BL_CUR_mA(0),	/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l2_bright_max = ADP8870_BL_CUR_mA(14),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l2_bright_dim = ADP8870_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l3_office_max = ADP8870_BL_CUR_mA(6),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l3_office_dim = ADP8870_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l4_indoor_max = ADP8870_BL_CUR_mA(3),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l4_indor_dim = ADP8870_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l5_dark_max = ADP8870_BL_CUR_mA(2),		/* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+	.l5_dark_dim = ADP8870_BL_CUR_mA(0),		/* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+
+	.l2_trip = ADP8870_L2_COMP_CURR_uA(710),	/* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+	.l2_hyst = ADP8870_L2_COMP_CURR_uA(73),		/* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+	.l3_trip = ADP8870_L3_COMP_CURR_uA(389),	/* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */
+	.l3_hyst = ADP8870_L3_COMP_CURR_uA(54),		/* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */
+	.l4_trip = ADP8870_L4_COMP_CURR_uA(167),	/* use L4_COMP_CURR_uA(I) 0 <= I <= 275 uA */
+	.l4_hyst = ADP8870_L4_COMP_CURR_uA(16),		/* use L4_COMP_CURR_uA(I) 0 <= I <= 275 uA */
+	.l5_trip = ADP8870_L5_COMP_CURR_uA(43),		/* use L5_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+	.l5_hyst = ADP8870_L5_COMP_CURR_uA(11),		/* use L6_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+
+	.leds = adp8870_leds,
+	.num_leds = ARRAY_SIZE(adp8870_leds),
+	.led_fade_law = ADP8870_FADE_LAW_SQUARE,	/* fade-on/fade-off transfer characteristic */
+	.led_fade_in = ADP8870_FADE_T_600ms,
+	.led_fade_out = ADP8870_FADE_T_600ms,
+	.led_on_time = ADP8870_LED_ONT_200ms,
+};
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
-#if defined(CONFIG_INPUT_EVAL_AD7142EB)
+#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
 	{
 		I2C_BOARD_INFO("ad7142_captouch", 0x2C),
 		.irq = IRQ_PG5,
-		.platform_data = (void *)&ad7142_platfrom_data,
+		.platform_data = (void *)&ad7142_i2c_platform_data,
 	},
 #endif
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
@@ -1462,6 +1574,32 @@ static struct i2c_board_info __initdata
 		I2C_BOARD_INFO("bfin-adv7393", 0x2B),
 	},
 #endif
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+	{
+		I2C_BOARD_INFO("bf537-lq035-ad5280", 0x2C),
+	},
+#endif
+#if defined(CONFIG_BACKLIGHT_ADP8870) || defined(CONFIG_BACKLIGHT_ADP8870_MODULE)
+	{
+		I2C_BOARD_INFO("adp8870", 0x2B),
+		.platform_data = (void *)&adp8870_pdata,
+	},
+#endif
+#if defined(CONFIG_SND_SOC_ADAU1371) || defined(CONFIG_SND_SOC_ADAU1371_MODULE)
+	{
+		I2C_BOARD_INFO("adau1371", 0x1A),
+	},
+#endif
+#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE)
+	{
+		I2C_BOARD_INFO("adau1761", 0x38),
+	},
+#endif
+#if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE)
+	{
+		I2C_BOARD_INFO("ad5258", 0x18),
+	},
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1602,8 +1740,8 @@ static struct platform_device *stamp_dev
 	&dm9000_device,
 #endif
 
-#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE)
-	&ax88180_device,
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+	&bfin_can_device,
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/bf537.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/bf537.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/bf537.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/bf537.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,16 +9,6 @@
 #ifndef __MACH_BF537_H__
 #define __MACH_BF537_H__
 
-/* Masks for generic ERROR IRQ demultiplexing used in int-priority-sc.c */
-
-#define SPI_ERR_MASK (TXCOL | RBSY | MODF | TXE)	/* SPI_STAT */
-#define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF)	/* SPORTx_STAT */
-#define PPI_ERR_MASK (0xFFFF & ~FLD)	/* PPI_STATUS */
-#define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE)	/* EMAC_SYSTAT */
-#define UART_ERR_MASK_STAT1 (0x4)	/* UARTx_IIR */
-#define UART_ERR_MASK_STAT0 (0x2)	/* UARTx_IIR */
-#define CAN_ERR_MASK  (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF)	/* CAN_GIF */
-
 #define OFFSET_(x) ((x) & 0x0000FFFF)
 
 /*some misc defines*/
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/blackfin.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/blackfin.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/blackfin.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/blackfin.h	2010-02-24 13:52:17.000000000 -0500
@@ -40,10 +40,4 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* PLL_DIV Masks													*/
-#define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
-#define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
-#define CCLK_DIV4 CSEL_DIV4	/*          CCLK = VCO / 4                                  */
-#define CCLK_DIV8 CSEL_DIV8	/*          CCLK = VCO / 8                                  */
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/defBF534.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/defBF534.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf537/include/mach/defBF534.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf537/include/mach/defBF534.h	2010-02-24 13:52:17.000000000 -0500
@@ -934,7 +934,7 @@
 #define HMDMA0_CONTROL		0xFFC03300	/* Handshake MDMA0 Control Register                                     */
 #define HMDMA0_ECINIT		0xFFC03304	/* HMDMA0 Initial Edge Count Register                           */
 #define HMDMA0_BCINIT		0xFFC03308	/* HMDMA0 Initial Block Count Register                          */
-#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshhold Register         */
+#define HMDMA0_ECURGENT		0xFFC0330C	/* HMDMA0 Urgent Edge Count Threshold Register         */
 #define HMDMA0_ECOVERFLOW	0xFFC03310	/* HMDMA0 Edge Count Overflow Interrupt Register        */
 #define HMDMA0_ECOUNT		0xFFC03314	/* HMDMA0 Current Edge Count Register                           */
 #define HMDMA0_BCOUNT		0xFFC03318	/* HMDMA0 Current Block Count Register                          */
@@ -942,7 +942,7 @@
 #define HMDMA1_CONTROL		0xFFC03340	/* Handshake MDMA1 Control Register                                     */
 #define HMDMA1_ECINIT		0xFFC03344	/* HMDMA1 Initial Edge Count Register                           */
 #define HMDMA1_BCINIT		0xFFC03348	/* HMDMA1 Initial Block Count Register                          */
-#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshhold Register         */
+#define HMDMA1_ECURGENT		0xFFC0334C	/* HMDMA1 Urgent Edge Count Threshold Register         */
 #define HMDMA1_ECOVERFLOW	0xFFC03350	/* HMDMA1 Edge Count Overflow Interrupt Register        */
 #define HMDMA1_ECOUNT		0xFFC03354	/* HMDMA1 Current Edge Count Register                           */
 #define HMDMA1_BCOUNT		0xFFC03358	/* HMDMA1 Current Block Count Register                          */
@@ -958,67 +958,6 @@
 **				modifier UNLESS the lower order bits are saved and ORed back in when
 **				the macro is used.
 *************************************************************************************/
-/*
-** ********************* PLL AND RESET MASKS ****************************************/
-/* PLL_CTL Masks																	*/
-#define DF				0x0001	/* 0: PLL = CLKIN, 1: PLL = CLKIN/2                                     */
-#define PLL_OFF			0x0002	/* PLL Not Powered                                                                      */
-#define STOPCK			0x0008	/* Core Clock Off                                                                       */
-#define PDWN			0x0020	/* Enter Deep Sleep Mode                                                        */
-#define	IN_DELAY		0x0040	/* Add 200ps Delay To EBIU Input Latches                        */
-#define	OUT_DELAY		0x0080	/* Add 200ps Delay To EBIU Output Signals                       */
-#define BYPASS			0x0100	/* Bypass the PLL                                                                       */
-#define	MSEL			0x7E00	/* Multiplier Select For CCLK/VCO Factors                       */
-/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits)			*/
-#define	SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL         */
-
-/* PLL_DIV Masks														*/
-#define SSEL			0x000F	/* System Select                                                */
-#define	CSEL			0x0030	/* Core Select                                                  */
-#define CSEL_DIV1		0x0000	/*              CCLK = VCO / 1                                  */
-#define CSEL_DIV2		0x0010	/*              CCLK = VCO / 2                                  */
-#define	CSEL_DIV4		0x0020	/*              CCLK = VCO / 4                                  */
-#define	CSEL_DIV8		0x0030	/*              CCLK = VCO / 8                                  */
-/* PLL_DIV Macros														*/
-#define SET_SSEL(x)		((x)&0xF)	/* Set SSEL = 0-15 --> SCLK = VCO/SSEL  */
-
-/* VR_CTL Masks																	*/
-#define	FREQ			0x0003	/* Switching Oscillator Frequency For Regulator */
-#define	HIBERNATE		0x0000	/*              Powerdown/Bypass On-Board Regulation    */
-#define	FREQ_333		0x0001	/*              Switching Frequency Is 333 kHz                  */
-#define	FREQ_667		0x0002	/*              Switching Frequency Is 667 kHz                  */
-#define	FREQ_1000		0x0003	/*              Switching Frequency Is 1 MHz                    */
-
-#define GAIN			0x000C	/* Voltage Level Gain   */
-#define	GAIN_5			0x0000	/*              GAIN = 5                */
-#define	GAIN_10			0x0004	/*              GAIN = 10               */
-#define	GAIN_20			0x0008	/*              GAIN = 20               */
-#define	GAIN_50			0x000C	/*              GAIN = 50               */
-
-#define	VLEV			0x00F0	/* Internal Voltage Level                                       */
-#define	VLEV_085 		0x0060	/*              VLEV = 0.85 V (-5% - +10% Accuracy)     */
-#define	VLEV_090		0x0070	/*              VLEV = 0.90 V (-5% - +10% Accuracy)     */
-#define	VLEV_095		0x0080	/*              VLEV = 0.95 V (-5% - +10% Accuracy)     */
-#define	VLEV_100		0x0090	/*              VLEV = 1.00 V (-5% - +10% Accuracy)     */
-#define	VLEV_105		0x00A0	/*              VLEV = 1.05 V (-5% - +10% Accuracy)     */
-#define	VLEV_110		0x00B0	/*              VLEV = 1.10 V (-5% - +10% Accuracy)     */
-#define	VLEV_115		0x00C0	/*              VLEV = 1.15 V (-5% - +10% Accuracy)     */
-#define	VLEV_120		0x00D0	/*              VLEV = 1.20 V (-5% - +10% Accuracy)     */
-#define	VLEV_125		0x00E0	/*              VLEV = 1.25 V (-5% - +10% Accuracy)     */
-#define	VLEV_130		0x00F0	/*              VLEV = 1.30 V (-5% - +10% Accuracy)     */
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate       */
-#define	CANWE			0x0200	/* Enable CAN Wakeup From Hibernate			*/
-#define	PHYWE			0x0400	/* Enable PHY Wakeup From Hibernate			*/
-#define	CLKBUFOE		0x4000	/* CLKIN Buffer Output Enable */
-#define	PHYCLKOE		CLKBUFOE	/* Alternative legacy name for the above */
-#define	SCKELOW		0x8000	/* Enable Drive CKE Low During Reset		*/
-
-/* PLL_STAT Masks																	*/
-#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled    */
-#define	FULL_ON				0x0002	/* Processor In Full On Mode                                    */
-#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled   */
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been Reached                                 */
 
 /* CHIPID Masks */
 #define CHIPID_VERSION         0xF0000000
@@ -1645,34 +1584,6 @@
 #define BGSTAT			0x0020	/* Bus Grant Status                                             */
 
 /* **************************  DMA CONTROLLER MASKS  ********************************/
-/* DMAx_CONFIG, MDMA_yy_CONFIG Masks												*/
-#define DMAEN			0x0001	/* DMA Channel Enable                                                   */
-#define WNR				0x0002	/* Channel Direction (W/R*)                                             */
-#define WDSIZE_8		0x0000	/* Transfer Word Size = 8                                               */
-#define WDSIZE_16		0x0004	/* Transfer Word Size = 16                                              */
-#define WDSIZE_32		0x0008	/* Transfer Word Size = 32                                              */
-#define DMA2D			0x0010	/* DMA Mode (2D/1D*)                                                    */
-#define RESTART			0x0020	/* DMA Buffer Clear                                                             */
-#define DI_SEL			0x0040	/* Data Interrupt Timing Select                                 */
-#define DI_EN			0x0080	/* Data Interrupt Enable                                                */
-#define NDSIZE_0		0x0000	/* Next Descriptor Size = 0 (Stop/Autobuffer)   */
-#define NDSIZE_1		0x0100	/* Next Descriptor Size = 1                                             */
-#define NDSIZE_2		0x0200	/* Next Descriptor Size = 2                                             */
-#define NDSIZE_3		0x0300	/* Next Descriptor Size = 3                                             */
-#define NDSIZE_4		0x0400	/* Next Descriptor Size = 4                                             */
-#define NDSIZE_5		0x0500	/* Next Descriptor Size = 5                                             */
-#define NDSIZE_6		0x0600	/* Next Descriptor Size = 6                                             */
-#define NDSIZE_7		0x0700	/* Next Descriptor Size = 7                                             */
-#define NDSIZE_8		0x0800	/* Next Descriptor Size = 8                                             */
-#define NDSIZE_9		0x0900	/* Next Descriptor Size = 9                                             */
-#define NDSIZE	        	0x0900	/* Next Descriptor Size */
-
-#define DMAFLOW	        	0x7000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000	/* Stop Mode */
-#define DMAFLOW_AUTO		0x1000	/* Autobuffer Mode */
-#define DMAFLOW_ARRAY		0x4000	/* Descriptor Array Mode */
-#define DMAFLOW_SMALL		0x6000	/* Small Model Descriptor List Mode */
-#define DMAFLOW_LARGE		0x7000	/* Large Model Descriptor List Mode */
 
 /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks								*/
 #define CTYPE			0x0040	/* DMA Channel Type Indicator (Memory/Peripheral*)      */
@@ -1690,12 +1601,6 @@
 #define	PMAP_UART1RX	0xA000	/*              UART1 Port Receive DMA                                          */
 #define	PMAP_UART1TX	0xB000	/*              UART1 Port Transmit DMA                                         */
 
-/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks						*/
-#define DMA_DONE		0x0001	/* DMA Completion Interrupt Status      */
-#define DMA_ERR			0x0002	/* DMA Error Interrupt Status           */
-#define DFETCH			0x0004	/* DMA Descriptor Fetch Indicator       */
-#define DMA_RUN			0x0008	/* DMA Channel Running Indicator        */
-
 /*  ************  PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
 /*  PPI_CONTROL Masks													*/
 #define PORT_EN			0x0001	/* PPI Port Enable                                      */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
@@ -151,6 +151,44 @@ static struct platform_device bfin_sir2_
 #endif
 #endif
 
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+unsigned short bfin_can_peripherals[] = {
+	P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static struct resource bfin_can_resources[] = {
+	{
+		.start = 0xFFC02A00,
+		.end = 0xFFC02FFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_CAN_RX,
+		.end = IRQ_CAN_RX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN_TX,
+		.end = IRQ_CAN_TX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN_ERROR,
+		.end = IRQ_CAN_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_can_device = {
+	.name = "bfin_can",
+	.num_resources = ARRAY_SIZE(bfin_can_resources),
+	.resource = bfin_can_resources,
+	.dev = {
+		.platform_data = &bfin_can_peripherals, /* Passed to driver */
+	},
+};
+#endif
+
 /*
  *  USB-LAN EzExtender board
  *  Driver needs to know address, irq and flag pin.
@@ -610,6 +648,10 @@ static struct platform_device *cm_bf538_
 #endif
 #endif
 
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+	&bfin_can_device,
+#endif
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 	&smc91x_device,
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/ext-gpio.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/ext-gpio.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/ext-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/ext-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,123 @@
+/*
+ * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/portmux.h>
+
+#define DEFINE_REG(reg, off) \
+static inline u16 read_##reg(void __iomem *port) \
+	{ return bfin_read16(port + off); } \
+static inline void write_##reg(void __iomem *port, u16 v) \
+	{ bfin_write16(port + off, v); }
+
+DEFINE_REG(PORTIO, 0x00)
+DEFINE_REG(PORTIO_CLEAR, 0x10)
+DEFINE_REG(PORTIO_SET, 0x20)
+DEFINE_REG(PORTIO_DIR, 0x40)
+DEFINE_REG(PORTIO_INEN, 0x50)
+
+static void __iomem *gpio_chip_to_mmr(struct gpio_chip *chip)
+{
+	switch (chip->base) {
+	default: /* not really needed, but keeps gcc happy */
+	case GPIO_PC0: return (void __iomem *)PORTCIO;
+	case GPIO_PD0: return (void __iomem *)PORTDIO;
+	case GPIO_PE0: return (void __iomem *)PORTEIO;
+	}
+}
+
+static int bf538_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	void __iomem *port = gpio_chip_to_mmr(chip);
+	return !!(read_PORTIO(port) & (1u << gpio));
+}
+
+static void bf538_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	void __iomem *port = gpio_chip_to_mmr(chip);
+	if (value)
+		write_PORTIO_SET(port, (1u << gpio));
+	else
+		write_PORTIO_CLEAR(port, (1u << gpio));
+}
+
+static int bf538_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	void __iomem *port = gpio_chip_to_mmr(chip);
+	write_PORTIO_DIR(port, read_PORTIO_DIR(port) & ~(1u << gpio));
+	write_PORTIO_INEN(port, read_PORTIO_INEN(port) | (1u << gpio));
+	return 0;
+}
+
+static int bf538_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	void __iomem *port = gpio_chip_to_mmr(chip);
+	write_PORTIO_INEN(port, read_PORTIO_INEN(port) & ~(1u << gpio));
+	bf538_gpio_set_value(port, gpio, value);
+	write_PORTIO_DIR(port, read_PORTIO_DIR(port) | (1u << gpio));
+	return 0;
+}
+
+static int bf538_gpio_request(struct gpio_chip *chip, unsigned gpio)
+{
+	return bfin_special_gpio_request(chip->base + gpio, chip->label);
+}
+
+static void bf538_gpio_free(struct gpio_chip *chip, unsigned gpio)
+{
+	return bfin_special_gpio_free(chip->base + gpio);
+}
+
+/* We don't set the irq fields as these banks cannot generate interrupts */
+
+static struct gpio_chip bf538_portc_chip = {
+	.label = "GPIO-PC",
+	.direction_input = bf538_gpio_direction_input,
+	.get = bf538_gpio_get_value,
+	.direction_output = bf538_gpio_direction_output,
+	.set = bf538_gpio_set_value,
+	.request = bf538_gpio_request,
+	.free = bf538_gpio_free,
+	.base = GPIO_PC0,
+	.ngpio = GPIO_PC9 - GPIO_PC0 + 1,
+};
+
+static struct gpio_chip bf538_portd_chip = {
+	.label = "GPIO-PD",
+	.direction_input = bf538_gpio_direction_input,
+	.get = bf538_gpio_get_value,
+	.direction_output = bf538_gpio_direction_output,
+	.set = bf538_gpio_set_value,
+	.request = bf538_gpio_request,
+	.free = bf538_gpio_free,
+	.base = GPIO_PD0,
+	.ngpio = GPIO_PD13 - GPIO_PD0 + 1,
+};
+
+static struct gpio_chip bf538_porte_chip = {
+	.label = "GPIO-PE",
+	.direction_input = bf538_gpio_direction_input,
+	.get = bf538_gpio_get_value,
+	.direction_output = bf538_gpio_direction_output,
+	.set = bf538_gpio_set_value,
+	.request = bf538_gpio_request,
+	.free = bf538_gpio_free,
+	.base = GPIO_PE0,
+	.ngpio = GPIO_PE15 - GPIO_PE0 + 1,
+};
+
+static int __init bf538_extgpio_setup(void)
+{
+	return gpiochip_add(&bf538_portc_chip) |
+		gpiochip_add(&bf538_portd_chip) |
+		gpiochip_add(&bf538_porte_chip);
+}
+arch_initcall(bf538_extgpio_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/blackfin.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/blackfin.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/blackfin.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/blackfin.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,10 +37,4 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* PLL_DIV Masks													*/
-#define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
-#define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
-#define CCLK_DIV4 CSEL_DIV4	/*          CCLK = VCO / 4                                  */
-#define CCLK_DIV8 CSEL_DIV8	/*          CCLK = VCO / 8                                  */
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/defBF539.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/defBF539.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/defBF539.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/defBF539.h	2010-02-24 13:52:17.000000000 -0500
@@ -468,31 +468,31 @@
 /* General-Purpose Ports  (0xFFC01500 -	0xFFC015FF)	 */
 
 /* GPIO	Port C Register	Names */
-#define	GPIO_C_CNFG			0xFFC01500	/* GPIO	Pin Port C Configuration Register */
-#define	GPIO_C_D			0xFFC01510	/* GPIO	Pin Port C Data	Register */
-#define	GPIO_C_C			0xFFC01520	/* Clear GPIO Pin Port C Register */
-#define	GPIO_C_S			0xFFC01530	/* Set GPIO Pin	Port C Register */
-#define	GPIO_C_T			0xFFC01540	/* Toggle GPIO Pin Port	C Register */
-#define	GPIO_C_DIR			0xFFC01550	/* GPIO	Pin Port C Direction Register */
-#define	GPIO_C_INEN			0xFFC01560	/* GPIO	Pin Port C Input Enable	Register */
+#define PORTCIO_FER			0xFFC01500	/* GPIO	Pin Port C Configuration Register */
+#define PORTCIO				0xFFC01510	/* GPIO	Pin Port C Data	Register */
+#define PORTCIO_CLEAR			0xFFC01520	/* Clear GPIO Pin Port C Register */
+#define PORTCIO_SET			0xFFC01530	/* Set GPIO Pin	Port C Register */
+#define PORTCIO_TOGGLE			0xFFC01540	/* Toggle GPIO Pin Port	C Register */
+#define PORTCIO_DIR			0xFFC01550	/* GPIO	Pin Port C Direction Register */
+#define PORTCIO_INEN			0xFFC01560	/* GPIO	Pin Port C Input Enable	Register */
 
 /* GPIO	Port D Register	Names */
-#define	GPIO_D_CNFG			0xFFC01504	/* GPIO	Pin Port D Configuration Register */
-#define	GPIO_D_D			0xFFC01514	/* GPIO	Pin Port D Data	Register */
-#define	GPIO_D_C			0xFFC01524	/* Clear GPIO Pin Port D Register */
-#define	GPIO_D_S			0xFFC01534	/* Set GPIO Pin	Port D Register */
-#define	GPIO_D_T			0xFFC01544	/* Toggle GPIO Pin Port	D Register */
-#define	GPIO_D_DIR			0xFFC01554	/* GPIO	Pin Port D Direction Register */
-#define	GPIO_D_INEN			0xFFC01564	/* GPIO	Pin Port D Input Enable	Register */
+#define PORTDIO_FER			0xFFC01504	/* GPIO	Pin Port D Configuration Register */
+#define PORTDIO				0xFFC01514	/* GPIO	Pin Port D Data	Register */
+#define PORTDIO_CLEAR			0xFFC01524	/* Clear GPIO Pin Port D Register */
+#define PORTDIO_SET			0xFFC01534	/* Set GPIO Pin	Port D Register */
+#define PORTDIO_TOGGLE			0xFFC01544	/* Toggle GPIO Pin Port	D Register */
+#define PORTDIO_DIR			0xFFC01554	/* GPIO	Pin Port D Direction Register */
+#define PORTDIO_INEN			0xFFC01564	/* GPIO	Pin Port D Input Enable	Register */
 
 /* GPIO	Port E Register	Names */
-#define	GPIO_E_CNFG			0xFFC01508	/* GPIO	Pin Port E Configuration Register */
-#define	GPIO_E_D			0xFFC01518	/* GPIO	Pin Port E Data	Register */
-#define	GPIO_E_C			0xFFC01528	/* Clear GPIO Pin Port E Register */
-#define	GPIO_E_S			0xFFC01538	/* Set GPIO Pin	Port E Register */
-#define	GPIO_E_T			0xFFC01548	/* Toggle GPIO Pin Port	E Register */
-#define	GPIO_E_DIR			0xFFC01558	/* GPIO	Pin Port E Direction Register */
-#define	GPIO_E_INEN			0xFFC01568	/* GPIO	Pin Port E Input Enable	Register */
+#define PORTEIO_FER			0xFFC01508	/* GPIO	Pin Port E Configuration Register */
+#define PORTEIO				0xFFC01518	/* GPIO	Pin Port E Data	Register */
+#define PORTEIO_CLEAR			0xFFC01528	/* Clear GPIO Pin Port E Register */
+#define PORTEIO_SET			0xFFC01538	/* Set GPIO Pin	Port E Register */
+#define PORTEIO_TOGGLE			0xFFC01548	/* Toggle GPIO Pin Port	E Register */
+#define PORTEIO_DIR			0xFFC01558	/* GPIO	Pin Port E Direction Register */
+#define PORTEIO_INEN			0xFFC01568	/* GPIO	Pin Port E Input Enable	Register */
 
 /* DMA Controller 1 Traffic Control Registers (0xFFC01B00 - 0xFFC01BFF) */
 
@@ -1422,81 +1422,6 @@
 /* System MMR Register Bits and	Macros */
 /******************************************************************************* */
 
-/* ********************* PLL AND RESET MASKS ************************ */
-/* PLL_CTL Masks */
-#define	PLL_CLKIN			0x0000	/* Pass	CLKIN to PLL */
-#define	PLL_CLKIN_DIV2		0x0001	/* Pass	CLKIN/2	to PLL */
-#define	DF					0x0001	 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */
-#define	PLL_OFF				0x0002	/* Shut	off PLL	clocks */
-
-#define	STOPCK				0x0008	/* Core	Clock Off		 */
-#define	PDWN				0x0020	/* Put the PLL in a Deep Sleep state */
-#define	IN_DELAY			0x0014	/* EBIU	Input Delay Select */
-#define	OUT_DELAY			0x00C0	/* EBIU	Output Delay Select */
-#define	BYPASS				0x0100	/* Bypass the PLL */
-#define	MSEL			0x7E00	/* Multiplier Select For CCLK/VCO Factors */
-
-/* PLL_CTL Macros				 */
-#ifdef _MISRA_RULES
-#define	SET_MSEL(x)		(((x)&0x3Fu) <<	0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */
-#define	SET_OUT_DELAY(x)	(((x)&0x03u) <<	0x6)
-#define	SET_IN_DELAY(x)		((((x)&0x02u) << 0x3) |	(((x)&0x01u) <<	0x2))
-#else
-#define	SET_MSEL(x)		(((x)&0x3F) << 0x9)	/* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */
-#define	SET_OUT_DELAY(x)	(((x)&0x03) << 0x6)
-#define	SET_IN_DELAY(x)		((((x)&0x02) <<	0x3) | (((x)&0x01) << 0x2))
-#endif /* _MISRA_RULES */
-
-/* PLL_DIV Masks */
-#define	SSEL				0x000F	/* System Select */
-#define	CSEL				0x0030	/* Core	Select */
-#define	CSEL_DIV1		0x0000	/*		CCLK = VCO / 1 */
-#define	CSEL_DIV2		0x0010	/*		CCLK = VCO / 2 */
-#define	CSEL_DIV4		0x0020	/*		CCLK = VCO / 4 */
-#define	CSEL_DIV8		0x0030	/*		CCLK = VCO / 8 */
-
-#define	SCLK_DIV(x)			(x)		/* SCLK	= VCO /	x */
-
-/* PLL_DIV Macros							 */
-#ifdef _MISRA_RULES
-#define	SET_SSEL(x)			((x)&0xFu)	/* Set SSEL = 0-15 --> SCLK = VCO/SSEL */
-#else
-#define	SET_SSEL(x)			((x)&0xF)	/* Set SSEL = 0-15 --> SCLK = VCO/SSEL */
-#endif /* _MISRA_RULES */
-
-/* PLL_STAT Masks										 */
-#define	ACTIVE_PLLENABLED	0x0001	/* Processor In	Active Mode With PLL Enabled */
-#define	FULL_ON				0x0002	/* Processor In	Full On	Mode */
-#define	ACTIVE_PLLDISABLED	0x0004	/* Processor In	Active Mode With PLL Disabled */
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been	Reached */
-
-/* VR_CTL Masks										 */
-#define	FREQ			0x0003	/* Switching Oscillator	Frequency For Regulator */
-#define	HIBERNATE		0x0000	/*		Powerdown/Bypass On-Board Regulation */
-#define	FREQ_333		0x0001	/*		Switching Frequency Is 333 kHz */
-#define	FREQ_667		0x0002	/*		Switching Frequency Is 667 kHz */
-#define	FREQ_1000		0x0003	/*		Switching Frequency Is 1 MHz */
-
-#define	GAIN			0x000C	/* Voltage Level Gain */
-#define	GAIN_5			0x0000	/*		GAIN = 5 */
-#define	GAIN_10			0x0004	/*		GAIN = 10 */
-#define	GAIN_20			0x0008	/*		GAIN = 20 */
-#define	GAIN_50			0x000C	/*		GAIN = 50 */
-
-#define	VLEV			0x00F0	/* Internal Voltage Level - Only Program Values	Within Specifications */
-#define	VLEV_100		0x0090	/*	VLEV = 1.00 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_105		0x00A0	/*	VLEV = 1.05 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_110		0x00B0	/*	VLEV = 1.10 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_115		0x00C0	/*	VLEV = 1.15 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_120		0x00D0	/*	VLEV = 1.20 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_125		0x00E0	/*	VLEV = 1.25 V (See Datasheet for Regulator Tolerance) */
-#define	VLEV_130		0x00F0	/*	VLEV = 1.30 V (See Datasheet for Regulator Tolerance) */
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From	Hibernate */
-#define	CANWE			0x0200	/* Enable CAN Wakeup From Hibernate */
-#define	MXVRWE			0x0400	/* Enable MXVR Wakeup From Hibernate */
-#define	SCKELOW			0x8000	/* Do Not Drive	SCKE High During Reset After Hibernate */
-
 /* SWRST Mask */
 #define	SYSTEM_RESET	0x0007	/* Initiates A System Software Reset */
 #define	DOUBLE_FAULT	0x0008	/* Core	Double Fault Causes Reset */
@@ -1609,91 +1534,6 @@
 #endif /* _MISRA_RULES */
 
 
-/* ********* WATCHDOG TIMER MASKS ******************** */
-/* Watchdog Timer WDOG_CTL Register Masks */
-#ifdef _MISRA_RULES
-#define	WDEV(x)			(((x)<<1) & 0x0006u)	/* event generated on roll over */
-#else
-#define	WDEV(x)			(((x)<<1) & 0x0006)	/* event generated on roll over */
-#endif /* _MISRA_RULES */
-#define	WDEV_RESET		0x0000				/* generate reset event	on roll	over */
-#define	WDEV_NMI		0x0002				/* generate NMI	event on roll over */
-#define	WDEV_GPI		0x0004				/* generate GP IRQ on roll over */
-#define	WDEV_NONE		0x0006				/* no event on roll over */
-#define	WDEN			0x0FF0				/* enable watchdog */
-#define	WDDIS			0x0AD0				/* disable watchdog */
-#define	WDRO			0x8000				/* watchdog rolled over	latch */
-
-/* deprecated WDOG_CTL Register	Masks for legacy code */
-#define	ICTL WDEV
-#define	ENABLE_RESET	WDEV_RESET
-#define	WDOG_RESET		WDEV_RESET
-#define	ENABLE_NMI		WDEV_NMI
-#define	WDOG_NMI		WDEV_NMI
-#define	ENABLE_GPI		WDEV_GPI
-#define	WDOG_GPI		WDEV_GPI
-#define	DISABLE_EVT	WDEV_NONE
-#define	WDOG_NONE		WDEV_NONE
-
-#define	TMR_EN			WDEN
-#define	WDOG_DISABLE		WDDIS
-#define	TRO			WDRO
-
-#define	ICTL_P0			0x01
-#define	ICTL_P1			0x02
-#define	TRO_P			0x0F
-
-
-/* ***************  REAL TIME CLOCK MASKS  **************************/
-/* RTC_STAT and	RTC_ALARM register */
-#define	RTSEC		0x0000003F	/* Real-Time Clock Seconds */
-#define	RTMIN		0x00000FC0	/* Real-Time Clock Minutes */
-#define	RTHR		0x0001F000	/* Real-Time Clock Hours */
-#define	RTDAY		0xFFFE0000	/* Real-Time Clock Days */
-
-/* RTC_ICTL register */
-#define	SWIE		0x0001		/* Stopwatch Interrupt Enable */
-#define	AIE			0x0002		/* Alarm Interrupt Enable */
-#define	SIE			0x0004		/* Seconds (1 Hz) Interrupt Enable */
-#define	MIE			0x0008		/* Minutes Interrupt Enable */
-#define	HIE			0x0010		/* Hours Interrupt Enable */
-#define	DIE			0x0020		/* 24 Hours (Days) Interrupt Enable */
-#define	DAIE		0x0040		/* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */
-#define	WCIE		0x8000		/* Write Complete Interrupt Enable */
-
-/* RTC_ISTAT register */
-#define	SWEF		0x0001		/* Stopwatch Event Flag */
-#define	AEF			0x0002		/* Alarm Event Flag */
-#define	SEF			0x0004		/* Seconds (1 Hz) Event	Flag */
-#define	MEF			0x0008		/* Minutes Event Flag */
-#define	HEF			0x0010		/* Hours Event Flag */
-#define	DEF			0x0020		/* 24 Hours (Days) Event Flag */
-#define	DAEF		0x0040		/* Day Alarm (Day, Hour, Minute, Second) Event Flag */
-#define	WPS			0x4000		/* Write Pending Status	(RO) */
-#define	WCOM		0x8000		/* Write Complete */
-
-/* RTC_FAST Mask (RTC_PREN Mask) */
-#define	ENABLE_PRESCALE	     0x00000001	 /* Enable prescaler so	RTC runs at 1 Hz */
-#define	PREN		     0x00000001
-		/* ** Must be set after	power-up for proper operation of RTC */
-
-/* Deprecated RTC_STAT and RTC_ALARM Masks			 */
-#define	RTC_SEC			RTSEC	/* Real-Time Clock Seconds */
-#define	RTC_MIN			RTMIN	/* Real-Time Clock Minutes */
-#define	RTC_HR			RTHR	/* Real-Time Clock Hours */
-#define	RTC_DAY			RTDAY	/* Real-Time Clock Days */
-
-/* Deprecated RTC_ICTL/RTC_ISTAT Masks											 */
-#define	STOPWATCH		SWIE		/* Stopwatch Interrupt Enable	 */
-#define	ALARM			AIE		/* Alarm Interrupt Enable		 */
-#define	SECOND			SIE		/* Seconds (1 Hz) Interrupt Enable */
-#define	MINUTE			MIE		/* Minutes Interrupt Enable		 */
-#define	HOUR			HIE		/* Hours Interrupt Enable		 */
-#define	DAY				DIE		/* 24 Hours (Days) Interrupt Enable */
-#define	DAY_ALARM		DAIE		/* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */
-#define	WRITE_COMPLETE	WCIE		/* Write Complete Interrupt Enable */
-
-
 /* ***************************** UART CONTROLLER MASKS ********************** */
 /* UARTx_LCR Register */
 #ifdef _MISRA_RULES
@@ -1917,52 +1757,6 @@
 
 
 /* **********  DMA CONTROLLER MASKS  ***********************/
-/* DMAx_CONFIG,	MDMA_yy_CONFIG Masks */
-#define	DMAEN		0x0001	/* Channel Enable */
-#define	WNR			0x0002	/* Channel Direction (W/R*) */
-#define	WDSIZE_8	0x0000	/* Word	Size 8 bits */
-#define	WDSIZE_16	0x0004	/* Word	Size 16	bits */
-#define	WDSIZE_32	0x0008	/* Word	Size 32	bits */
-#define	DMA2D		0x0010	/* 2D/1D* Mode */
-#define	RESTART		0x0020	/* Restart */
-#define	DI_SEL		0x0040	/* Data	Interrupt Select */
-#define	DI_EN		0x0080	/* Data	Interrupt Enable */
-#define	NDSIZE		0x0900	/* Next	Descriptor Size */
-#define	NDSIZE_0	0x0000	/* Next	Descriptor Size	= 0 (Stop/Autobuffer) */
-#define	NDSIZE_1	0x0100	/* Next	Descriptor Size	= 1 */
-#define	NDSIZE_2	0x0200	/* Next	Descriptor Size	= 2 */
-#define	NDSIZE_3	0x0300	/* Next	Descriptor Size	= 3 */
-#define	NDSIZE_4	0x0400	/* Next	Descriptor Size	= 4 */
-#define	NDSIZE_5	0x0500	/* Next	Descriptor Size	= 5 */
-#define	NDSIZE_6	0x0600	/* Next	Descriptor Size	= 6 */
-#define	NDSIZE_7	0x0700	/* Next	Descriptor Size	= 7 */
-#define	NDSIZE_8	0x0800	/* Next	Descriptor Size	= 8 */
-#define	NDSIZE_9	0x0900	/* Next	Descriptor Size	= 9 */
-
-#define DMAFLOW			0x7000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000	/* Stop Mode */
-#define DMAFLOW_AUTO		0x1000	/* Autobuffer Mode */
-#define DMAFLOW_ARRAY		0x4000	/* Descriptor Array Mode */
-#define DMAFLOW_SMALL		0x6000	/* Small Model Descriptor List Mode */
-#define DMAFLOW_LARGE		0x7000	/* Large Model Descriptor List Mode */
-
-#define	DMAEN_P		0x0		/* Channel Enable */
-#define	WNR_P		0x1		/* Channel Direction (W/R*) */
-#define	DMA2D_P		0x4		/* 2D/1D* Mode */
-#define	RESTART_P	0x5		/* Restart */
-#define	DI_SEL_P	0x6		/* Data	Interrupt Select */
-#define	DI_EN_P		0x7		/* Data	Interrupt Enable */
-
-/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */
-#define	DMA_DONE	0x0001	/* DMA Done Indicator */
-#define	DMA_ERR		0x0002	/* DMA Error Indicator */
-#define	DFETCH		0x0004	/* Descriptor Fetch Indicator */
-#define	DMA_RUN		0x0008	/* DMA Running Indicator */
-
-#define	DMA_DONE_P	0x0		/* DMA Done Indicator */
-#define	DMA_ERR_P	0x1		/* DMA Error Indicator */
-#define	DFETCH_P	0x2		/* Descriptor Fetch Indicator */
-#define	DMA_RUN_P	0x3		/* DMA Running Indicator */
 
 /* DMAx_PERIPHERAL_MAP,	MDMA_yy_PERIPHERAL_MAP Masks */
 
@@ -2625,1019 +2419,6 @@
 #define	RCV_FULL	0x000C		/*		Receive	FIFO Full (2 Bytes To Read) */
 
 
-/********************************* MXVR	MASKS ****************************************/
-
-/* MXVR_CONFIG Masks */
-
-#define	MXVREN	  0x00000001lu
-#define	MMSM	  0x00000002lu
-#define	ACTIVE	  0x00000004lu
-#define	SDELAY	  0x00000008lu
-#define	NCMRXEN	  0x00000010lu
-#define	RWRRXEN	  0x00000020lu
-#define	MTXEN	  0x00000040lu
-#define	MTXON	  0x00000080lu /*legacy*/
-#define	MTXONB	  0x00000080lu
-#define	EPARITY	  0x00000100lu
-#define	MSB	  0x00001E00lu
-#define	APRXEN	  0x00002000lu
-#define	WAKEUP	  0x00004000lu
-#define	LMECH	  0x00008000lu
-
-#ifdef _MISRA_RULES
-#define	SET_MSB(x)     (((x)&0xFu) << 0x9)
-#else
-#define	SET_MSB(x)     (((x)&0xF) << 0x9)
-#endif /* _MISRA_RULES */
-
-
-/* MXVR_PLL_CTL_0 Masks */
-
-#define	MXTALCEN  0x00000001lu
-#define	MXTALFEN  0x00000002lu
-#define	MPLLMS	  0x00000008lu
-#define	MXTALMUL  0x00000030lu
-#define	MPLLEN	  0x00000040lu
-#define	MPLLEN0	  0x00000040lu /* legacy */
-#define	MPLLEN1	  0x00000080lu /* legacy */
-#define	MMCLKEN	  0x00000100lu
-#define	MMCLKMUL  0x00001E00lu
-#define	MPLLRSTB  0x00002000lu
-#define	MPLLRSTB0 0x00002000lu /* legacy */
-#define	MPLLRSTB1 0x00004000lu /* legacy */
-#define	MBCLKEN	  0x00010000lu
-#define	MBCLKDIV  0x001E0000lu
-#define	MPLLCDR	  0x00200000lu
-#define	MPLLCDR0  0x00200000lu /* legacy */
-#define	MPLLCDR1  0x00400000lu /* legacy */
-#define	INVRX	  0x00800000lu
-#define	MFSEN	  0x01000000lu
-#define	MFSDIV	  0x1E000000lu
-#define	MFSSEL	  0x60000000lu
-#define	MFSSYNC	  0x80000000lu
-
-#define	MXTALMUL_256FS	 0x00000000lu /* legacy */
-#define	MXTALMUL_384FS	 0x00000010lu /* legacy */
-#define	MXTALMUL_512FS	 0x00000020lu /* legacy */
-#define	MXTALMUL_1024FS	 0x00000030lu
-
-#define	MMCLKMUL_1024FS	 0x00000000lu
-#define	MMCLKMUL_512FS	 0x00000200lu
-#define	MMCLKMUL_256FS	 0x00000400lu
-#define	MMCLKMUL_128FS	 0x00000600lu
-#define	MMCLKMUL_64FS	 0x00000800lu
-#define	MMCLKMUL_32FS	 0x00000A00lu
-#define	MMCLKMUL_16FS	 0x00000C00lu
-#define	MMCLKMUL_8FS	 0x00000E00lu
-#define	MMCLKMUL_4FS	 0x00001000lu
-#define	MMCLKMUL_2FS	 0x00001200lu
-#define	MMCLKMUL_1FS	 0x00001400lu
-#define	MMCLKMUL_1536FS	 0x00001A00lu
-#define	MMCLKMUL_768FS	 0x00001C00lu
-#define	MMCLKMUL_384FS	 0x00001E00lu
-
-#define	MBCLKDIV_DIV2	 0x00020000lu
-#define	MBCLKDIV_DIV4	 0x00040000lu
-#define	MBCLKDIV_DIV8	 0x00060000lu
-#define	MBCLKDIV_DIV16	 0x00080000lu
-#define	MBCLKDIV_DIV32	 0x000A0000lu
-#define	MBCLKDIV_DIV64	 0x000C0000lu
-#define	MBCLKDIV_DIV128	 0x000E0000lu
-#define	MBCLKDIV_DIV256	 0x00100000lu
-#define	MBCLKDIV_DIV512	 0x00120000lu
-#define	MBCLKDIV_DIV1024 0x00140000lu
-
-#define	MFSDIV_DIV2	 0x02000000lu
-#define	MFSDIV_DIV4	 0x04000000lu
-#define	MFSDIV_DIV8	 0x06000000lu
-#define	MFSDIV_DIV16	 0x08000000lu
-#define	MFSDIV_DIV32	 0x0A000000lu
-#define	MFSDIV_DIV64	 0x0C000000lu
-#define	MFSDIV_DIV128	 0x0E000000lu
-#define	MFSDIV_DIV256	 0x10000000lu
-#define	MFSDIV_DIV512	 0x12000000lu
-#define	MFSDIV_DIV1024	 0x14000000lu
-
-#define	MFSSEL_CLOCK	 0x00000000lu
-#define	MFSSEL_PULSE_HI	 0x20000000lu
-#define	MFSSEL_PULSE_LO	 0x40000000lu
-
-
-/* MXVR_PLL_CTL_1 Masks */
-
-#define	MSTO	   0x00000001lu
-#define	MSTO0	   0x00000001lu	/* legacy */
-#define	MHOGGD	   0x00000004lu
-#define	MHOGGD0	   0x00000004lu	/* legacy */
-#define	MHOGGD1	   0x00000008lu	/* legacy */
-#define	MSHAPEREN  0x00000010lu
-#define	MSHAPEREN0 0x00000010lu	/* legacy */
-#define	MSHAPEREN1 0x00000020lu	/* legacy */
-#define	MPLLCNTEN  0x00008000lu
-#define	MPLLCNT	   0xFFFF0000lu
-
-#ifdef _MISRA_RULES
-#define	SET_MPLLCNT(x)	   (((x)&0xFFFFu) << 0x10)
-#else
-#define	SET_MPLLCNT(x)	   (((x)&0xFFFF) << 0x10)
-#endif /* _MISRA_RULES */
-
-
-/* MXVR_PLL_CTL_2 Masks */
-
-#define	MSHAPERSEL 0x00000007lu
-#define	MCPSEL	   0x000000E0lu
-
-/* MXVR_INT_STAT_0 Masks */
-
-#define	NI2A  0x00000001lu
-#define	NA2I  0x00000002lu
-#define	SBU2L 0x00000004lu
-#define	SBL2U 0x00000008lu
-#define	PRU   0x00000010lu
-#define	MPRU  0x00000020lu
-#define	DRU   0x00000040lu
-#define	MDRU  0x00000080lu
-#define	SBU   0x00000100lu
-#define	ATU   0x00000200lu
-#define	FCZ0  0x00000400lu
-#define	FCZ1  0x00000800lu
-#define	PERR  0x00001000lu
-#define	MH2L  0x00002000lu
-#define	ML2H  0x00004000lu
-#define	WUP   0x00008000lu
-#define	FU2L  0x00010000lu
-#define	FL2U  0x00020000lu
-#define	BU2L  0x00040000lu
-#define	BL2U  0x00080000lu
-#define	PCZ   0x00400000lu
-#define	FERR  0x00800000lu
-#define	CMR   0x01000000lu
-#define	CMROF 0x02000000lu
-#define	CMTS  0x04000000lu
-#define	CMTC  0x08000000lu
-#define	RWRC  0x10000000lu
-#define	BCZ   0x20000000lu
-#define	BMERR 0x40000000lu
-#define	DERR  0x80000000lu
-
-
-/* MXVR_INT_EN_0 Masks */
-
-#define	NI2AEN	NI2A
-#define	NA2IEN	NA2I
-#define	SBU2LEN	SBU2L
-#define	SBL2UEN	SBL2U
-#define	PRUEN	PRU
-#define	MPRUEN	MPRU
-#define	DRUEN	DRU
-#define	MDRUEN	MDRU
-#define	SBUEN	SBU
-#define	ATUEN	ATU
-#define	FCZ0EN	FCZ0
-#define	FCZ1EN	FCZ1
-#define	PERREN	PERR
-#define	MH2LEN	MH2L
-#define	ML2HEN	ML2H
-#define	WUPEN	WUP
-#define	FU2LEN	FU2L
-#define	FL2UEN	FL2U
-#define	BU2LEN	BU2L
-#define	BL2UEN	BL2U
-#define	PCZEN	PCZ
-#define	FERREN	FERR
-#define	CMREN	CMR
-#define	CMROFEN	CMROF
-#define	CMTSEN	CMTS
-#define	CMTCEN	CMTC
-#define	RWRCEN	RWRC
-#define	BCZEN	BCZ
-#define	BMERREN	BMERR
-#define	DERREN	DERR
-
-
-/* MXVR_INT_STAT_1 Masks */
-
-#define	APR   0x00000004lu
-#define	APROF 0x00000008lu
-#define	APTS  0x00000040lu
-#define	APTC  0x00000080lu
-#define	APRCE 0x00000400lu
-#define	APRPE 0x00000800lu
-
-#define	HDONE0 0x00000001lu
-#define	DONE0  0x00000002lu
-#define	HDONE1 0x00000010lu
-#define	DONE1  0x00000020lu
-#define	HDONE2 0x00000100lu
-#define	DONE2  0x00000200lu
-#define	HDONE3 0x00001000lu
-#define	DONE3  0x00002000lu
-#define	HDONE4 0x00010000lu
-#define	DONE4  0x00020000lu
-#define	HDONE5 0x00100000lu
-#define	DONE5  0x00200000lu
-#define	HDONE6 0x01000000lu
-#define	DONE6  0x02000000lu
-#define	HDONE7 0x10000000lu
-#define	DONE7  0x20000000lu
-
-#define	DONEX(x) (0x00000002 <<	(4 * (x)))
-#define	HDONEX(x) (0x00000001 << (4 * (x)))
-
-
-/* MXVR_INT_EN_1 Masks */
-
-#define	APREN	APR
-#define	APROFEN	APROF
-#define	APTSEN	APTS
-#define	APTCEN	APTC
-#define	APRCEEN	APRCE
-#define	APRPEEN	APRPE
-
-#define	HDONEEN0 HDONE0
-#define	DONEEN0	 DONE0
-#define	HDONEEN1 HDONE1
-#define	DONEEN1	 DONE1
-#define	HDONEEN2 HDONE2
-#define	DONEEN2	 DONE2
-#define	HDONEEN3 HDONE3
-#define	DONEEN3	 DONE3
-#define	HDONEEN4 HDONE4
-#define	DONEEN4	 DONE4
-#define	HDONEEN5 HDONE5
-#define	DONEEN5	 DONE5
-#define	HDONEEN6 HDONE6
-#define	DONEEN6	 DONE6
-#define	HDONEEN7 HDONE7
-#define	DONEEN7	 DONE7
-
-#define	DONEENX(x) (0x00000002 << (4 * (x)))
-#define	HDONEENX(x) (0x00000001	<< (4 *	(x)))
-
-
-/* MXVR_STATE_0	Masks */
-
-#define	NACT	 0x00000001lu
-#define	SBLOCK	 0x00000002lu
-#define	PFDLOCK	 0x00000004lu
-#define	PFDLOCK0 0x00000004lu /* legacy */
-#define	PDD	 0x00000008lu
-#define	PDD0	 0x00000008lu /* legacy */
-#define	PVCO	 0x00000010lu
-#define	PVCO0	 0x00000010lu /* legacy */
-#define	PFDLOCK1 0x00000020lu /* legacy */
-#define	PDD1	 0x00000040lu /* legacy */
-#define	PVCO1	 0x00000080lu /* legacy */
-#define	APBSY	 0x00000100lu
-#define	APARB	 0x00000200lu
-#define	APTX	 0x00000400lu
-#define	APRX	 0x00000800lu
-#define	CMBSY	 0x00001000lu
-#define	CMARB	 0x00002000lu
-#define	CMTX	 0x00004000lu
-#define	CMRX	 0x00008000lu
-#define	MRXONB	 0x00010000lu
-#define	RGSIP	 0x00020000lu
-#define	DALIP	 0x00040000lu
-#define	ALIP	 0x00080000lu
-#define	RRDIP	 0x00100000lu
-#define	RWRIP	 0x00200000lu
-#define	FLOCK	 0x00400000lu
-#define	BLOCK	 0x00800000lu
-#define	RSB	 0x0F000000lu
-#define	DERRNUM	 0xF0000000lu
-
-
-/* MXVR_STATE_1	Masks */
-
-#define	STXNUMB	    0x0000000Flu
-#define	SRXNUMB	    0x000000F0lu
-#define	APCONT	    0x00000100lu
-#define	DMAACTIVEX  0x00FF0000lu
-#define	DMAACTIVE0  0x00010000lu
-#define	DMAACTIVE1  0x00020000lu
-#define	DMAACTIVE2  0x00040000lu
-#define	DMAACTIVE3  0x00080000lu
-#define	DMAACTIVE4  0x00100000lu
-#define	DMAACTIVE5  0x00200000lu
-#define	DMAACTIVE6  0x00400000lu
-#define	DMAACTIVE7  0x00800000lu
-#define	DMAPMENX    0xFF000000lu
-#define	DMAPMEN0    0x01000000lu
-#define	DMAPMEN1    0x02000000lu
-#define	DMAPMEN2    0x04000000lu
-#define	DMAPMEN3    0x08000000lu
-#define	DMAPMEN4    0x10000000lu
-#define	DMAPMEN5    0x20000000lu
-#define	DMAPMEN6    0x40000000lu
-#define	DMAPMEN7    0x80000000lu
-
-
-/* MXVR_POSITION Masks */
-
-#define	PVALID	     0x8000
-#define	POSITION     0x003F
-
-
-/* MXVR_MAX_POSITION Masks */
-
-#define	MPVALID	     0x8000
-#define	MPOSITION    0x003F
-
-
-/* MXVR_DELAY Masks */
-
-#define	DVALID	     0x8000
-#define	DELAY	     0x003F
-
-
-/* MXVR_MAX_DELAY Masks */
-
-#define	MDVALID	     0x8000
-#define	MDELAY	     0x003F
-
-
-/* MXVR_LADDR Masks */
-
-#define	LVALID	     0x80000000lu
-#define	LADDR	     0x0000FFFFlu
-
-
-/* MXVR_GADDR Masks */
-
-#define	GVALID	     0x8000
-#define	GADDRL	     0x00FF
-
-
-/* MXVR_AADDR Masks */
-
-#define	AVALID	     0x80000000lu
-#define	AADDR	     0x0000FFFFlu
-
-
-/* MXVR_ALLOC_0	Masks */
-
-#define	CIU0	     0x00000080lu
-#define	CIU1	     0x00008000lu
-#define	CIU2	     0x00800000lu
-#define	CIU3	     0x80000000lu
-
-#define	CL0	     0x0000007Flu
-#define	CL1	     0x00007F00lu
-#define	CL2	     0x007F0000lu
-#define	CL3	     0x7F000000lu
-
-
-/* MXVR_ALLOC_1	Masks */
-
-#define	CIU4	     0x00000080lu
-#define	CIU5	     0x00008000lu
-#define	CIU6	     0x00800000lu
-#define	CIU7	     0x80000000lu
-
-#define	CL4	     0x0000007Flu
-#define	CL5	     0x00007F00lu
-#define	CL6	     0x007F0000lu
-#define	CL7	     0x7F000000lu
-
-
-/* MXVR_ALLOC_2	Masks */
-
-#define	CIU8	     0x00000080lu
-#define	CIU9	     0x00008000lu
-#define	CIU10	     0x00800000lu
-#define	CIU11	     0x80000000lu
-
-#define	CL8	     0x0000007Flu
-#define	CL9	     0x00007F00lu
-#define	CL10	     0x007F0000lu
-#define	CL11	     0x7F000000lu
-
-
-/* MXVR_ALLOC_3	Masks */
-
-#define	CIU12	     0x00000080lu
-#define	CIU13	     0x00008000lu
-#define	CIU14	     0x00800000lu
-#define	CIU15	     0x80000000lu
-
-#define	CL12	     0x0000007Flu
-#define	CL13	     0x00007F00lu
-#define	CL14	     0x007F0000lu
-#define	CL15	     0x7F000000lu
-
-
-/* MXVR_ALLOC_4	Masks */
-
-#define	CIU16	     0x00000080lu
-#define	CIU17	     0x00008000lu
-#define	CIU18	     0x00800000lu
-#define	CIU19	     0x80000000lu
-
-#define	CL16	     0x0000007Flu
-#define	CL17	     0x00007F00lu
-#define	CL18	     0x007F0000lu
-#define	CL19	     0x7F000000lu
-
-
-/* MXVR_ALLOC_5	Masks */
-
-#define	CIU20	     0x00000080lu
-#define	CIU21	     0x00008000lu
-#define	CIU22	     0x00800000lu
-#define	CIU23	     0x80000000lu
-
-#define	CL20	     0x0000007Flu
-#define	CL21	     0x00007F00lu
-#define	CL22	     0x007F0000lu
-#define	CL23	     0x7F000000lu
-
-
-/* MXVR_ALLOC_6	Masks */
-
-#define	CIU24	     0x00000080lu
-#define	CIU25	     0x00008000lu
-#define	CIU26	     0x00800000lu
-#define	CIU27	     0x80000000lu
-
-#define	CL24	     0x0000007Flu
-#define	CL25	     0x00007F00lu
-#define	CL26	     0x007F0000lu
-#define	CL27	     0x7F000000lu
-
-
-/* MXVR_ALLOC_7	Masks */
-
-#define	CIU28	     0x00000080lu
-#define	CIU29	     0x00008000lu
-#define	CIU30	     0x00800000lu
-#define	CIU31	     0x80000000lu
-
-#define	CL28	     0x0000007Flu
-#define	CL29	     0x00007F00lu
-#define	CL30	     0x007F0000lu
-#define	CL31	     0x7F000000lu
-
-
-/* MXVR_ALLOC_8	Masks */
-
-#define	CIU32	     0x00000080lu
-#define	CIU33	     0x00008000lu
-#define	CIU34	     0x00800000lu
-#define	CIU35	     0x80000000lu
-
-#define	CL32	     0x0000007Flu
-#define	CL33	     0x00007F00lu
-#define	CL34	     0x007F0000lu
-#define	CL35	     0x7F000000lu
-
-
-/* MXVR_ALLOC_9	Masks */
-
-#define	CIU36	     0x00000080lu
-#define	CIU37	     0x00008000lu
-#define	CIU38	     0x00800000lu
-#define	CIU39	     0x80000000lu
-
-#define	CL36	     0x0000007Flu
-#define	CL37	     0x00007F00lu
-#define	CL38	     0x007F0000lu
-#define	CL39	     0x7F000000lu
-
-
-/* MXVR_ALLOC_10 Masks */
-
-#define	CIU40	     0x00000080lu
-#define	CIU41	     0x00008000lu
-#define	CIU42	     0x00800000lu
-#define	CIU43	     0x80000000lu
-
-#define	CL40	     0x0000007Flu
-#define	CL41	     0x00007F00lu
-#define	CL42	     0x007F0000lu
-#define	CL43	     0x7F000000lu
-
-
-/* MXVR_ALLOC_11 Masks */
-
-#define	CIU44	     0x00000080lu
-#define	CIU45	     0x00008000lu
-#define	CIU46	     0x00800000lu
-#define	CIU47	     0x80000000lu
-
-#define	CL44	     0x0000007Flu
-#define	CL45	     0x00007F00lu
-#define	CL46	     0x007F0000lu
-#define	CL47	     0x7F000000lu
-
-
-/* MXVR_ALLOC_12 Masks */
-
-#define	CIU48	     0x00000080lu
-#define	CIU49	     0x00008000lu
-#define	CIU50	     0x00800000lu
-#define	CIU51	     0x80000000lu
-
-#define	CL48	     0x0000007Flu
-#define	CL49	     0x00007F00lu
-#define	CL50	     0x007F0000lu
-#define	CL51	     0x7F000000lu
-
-
-/* MXVR_ALLOC_13 Masks */
-
-#define	CIU52	     0x00000080lu
-#define	CIU53	     0x00008000lu
-#define	CIU54	     0x00800000lu
-#define	CIU55	     0x80000000lu
-
-#define	CL52	     0x0000007Flu
-#define	CL53	     0x00007F00lu
-#define	CL54	     0x007F0000lu
-#define	CL55	     0x7F000000lu
-
-
-/* MXVR_ALLOC_14 Masks */
-
-#define	CIU56	     0x00000080lu
-#define	CIU57	     0x00008000lu
-#define	CIU58	     0x00800000lu
-#define	CIU59	     0x80000000lu
-
-#define	CL56	     0x0000007Flu
-#define	CL57	     0x00007F00lu
-#define	CL58	     0x007F0000lu
-#define	CL59	     0x7F000000lu
-
-
-/* MXVR_SYNC_LCHAN_0 Masks */
-
-#define	LCHANPC0     0x0000000Flu
-#define	LCHANPC1     0x000000F0lu
-#define	LCHANPC2     0x00000F00lu
-#define	LCHANPC3     0x0000F000lu
-#define	LCHANPC4     0x000F0000lu
-#define	LCHANPC5     0x00F00000lu
-#define	LCHANPC6     0x0F000000lu
-#define	LCHANPC7     0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_1 Masks */
-
-#define	LCHANPC8     0x0000000Flu
-#define	LCHANPC9     0x000000F0lu
-#define	LCHANPC10    0x00000F00lu
-#define	LCHANPC11    0x0000F000lu
-#define	LCHANPC12    0x000F0000lu
-#define	LCHANPC13    0x00F00000lu
-#define	LCHANPC14    0x0F000000lu
-#define	LCHANPC15    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_2 Masks */
-
-#define	LCHANPC16    0x0000000Flu
-#define	LCHANPC17    0x000000F0lu
-#define	LCHANPC18    0x00000F00lu
-#define	LCHANPC19    0x0000F000lu
-#define	LCHANPC20    0x000F0000lu
-#define	LCHANPC21    0x00F00000lu
-#define	LCHANPC22    0x0F000000lu
-#define	LCHANPC23    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_3 Masks */
-
-#define	LCHANPC24    0x0000000Flu
-#define	LCHANPC25    0x000000F0lu
-#define	LCHANPC26    0x00000F00lu
-#define	LCHANPC27    0x0000F000lu
-#define	LCHANPC28    0x000F0000lu
-#define	LCHANPC29    0x00F00000lu
-#define	LCHANPC30    0x0F000000lu
-#define	LCHANPC31    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_4 Masks */
-
-#define	LCHANPC32    0x0000000Flu
-#define	LCHANPC33    0x000000F0lu
-#define	LCHANPC34    0x00000F00lu
-#define	LCHANPC35    0x0000F000lu
-#define	LCHANPC36    0x000F0000lu
-#define	LCHANPC37    0x00F00000lu
-#define	LCHANPC38    0x0F000000lu
-#define	LCHANPC39    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_5 Masks */
-
-#define	LCHANPC40    0x0000000Flu
-#define	LCHANPC41    0x000000F0lu
-#define	LCHANPC42    0x00000F00lu
-#define	LCHANPC43    0x0000F000lu
-#define	LCHANPC44    0x000F0000lu
-#define	LCHANPC45    0x00F00000lu
-#define	LCHANPC46    0x0F000000lu
-#define	LCHANPC47    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_6 Masks */
-
-#define	LCHANPC48    0x0000000Flu
-#define	LCHANPC49    0x000000F0lu
-#define	LCHANPC50    0x00000F00lu
-#define	LCHANPC51    0x0000F000lu
-#define	LCHANPC52    0x000F0000lu
-#define	LCHANPC53    0x00F00000lu
-#define	LCHANPC54    0x0F000000lu
-#define	LCHANPC55    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_7 Masks */
-
-#define	LCHANPC56    0x0000000Flu
-#define	LCHANPC57    0x000000F0lu
-#define	LCHANPC58    0x00000F00lu
-#define	LCHANPC59    0x0000F000lu
-
-
-/* MXVR_DMAx_CONFIG Masks */
-
-#define	MDMAEN	    0x00000001lu
-#define	DD	    0x00000002lu
-#define	LCHAN	    0x000003C0lu
-#define	BITSWAPEN   0x00000400lu
-#define	BYSWAPEN    0x00000800lu
-#define	MFLOW	    0x00007000lu
-#define	FIXEDPM	    0x00080000lu
-#define	STARTPAT    0x00300000lu
-#define	STOPPAT	    0x00C00000lu
-#define	COUNTPOS    0x1C000000lu
-
-#define	DD_TX	    0x00000000lu
-#define	DD_RX	    0x00000002lu
-
-#define	LCHAN_0	    0x00000000lu
-#define	LCHAN_1	    0x00000040lu
-#define	LCHAN_2	    0x00000080lu
-#define	LCHAN_3	    0x000000C0lu
-#define	LCHAN_4	    0x00000100lu
-#define	LCHAN_5	    0x00000140lu
-#define	LCHAN_6	    0x00000180lu
-#define	LCHAN_7	    0x000001C0lu
-
-#define	MFLOW_STOP  0x00000000lu
-#define	MFLOW_AUTO  0x00001000lu
-#define	MFLOW_PVC   0x00002000lu
-#define	MFLOW_PSS   0x00003000lu
-#define	MFLOW_PFC   0x00004000lu
-
-#define	STARTPAT_0  0x00000000lu
-#define	STARTPAT_1  0x00100000lu
-
-#define	STOPPAT_0   0x00000000lu
-#define	STOPPAT_1   0x00400000lu
-
-#define	COUNTPOS_0  0x00000000lu
-#define	COUNTPOS_1  0x04000000lu
-#define	COUNTPOS_2  0x08000000lu
-#define	COUNTPOS_3  0x0C000000lu
-#define	COUNTPOS_4  0x10000000lu
-#define	COUNTPOS_5  0x14000000lu
-#define	COUNTPOS_6  0x18000000lu
-#define	COUNTPOS_7  0x1C000000lu
-
-
-/* MXVR_AP_CTL Masks */
-
-#define	STARTAP	   0x00000001lu
-#define	CANCELAP   0x00000002lu
-#define	RESETAP	   0x00000004lu
-#define	APRBE0	   0x00004000lu
-#define	APRBE1	   0x00008000lu
-#define	APRBEX	   0x0000C000lu
-
-
-/* MXVR_CM_CTL Masks */
-
-#define	STARTCM	   0x00000001lu
-#define	CANCELCM   0x00000002lu
-#define	CMRBEX	   0xFFFF0000lu
-#define	CMRBE0	   0x00010000lu
-#define	CMRBE1	   0x00020000lu
-#define	CMRBE2	   0x00040000lu
-#define	CMRBE3	   0x00080000lu
-#define	CMRBE4	   0x00100000lu
-#define	CMRBE5	   0x00200000lu
-#define	CMRBE6	   0x00400000lu
-#define	CMRBE7	   0x00800000lu
-#define	CMRBE8	   0x01000000lu
-#define	CMRBE9	   0x02000000lu
-#define	CMRBE10	   0x04000000lu
-#define	CMRBE11	   0x08000000lu
-#define	CMRBE12	   0x10000000lu
-#define	CMRBE13	   0x20000000lu
-#define	CMRBE14	   0x40000000lu
-#define	CMRBE15	   0x80000000lu
-
-
-/* MXVR_PAT_DATA_x Masks */
-
-#define	MATCH_DATA_0 0x000000FFlu
-#define	MATCH_DATA_1 0x0000FF00lu
-#define	MATCH_DATA_2 0x00FF0000lu
-#define	MATCH_DATA_3 0xFF000000lu
-
-
-
-/* MXVR_PAT_EN_x Masks */
-
-#define	MATCH_EN_0_0 0x00000001lu
-#define	MATCH_EN_0_1 0x00000002lu
-#define	MATCH_EN_0_2 0x00000004lu
-#define	MATCH_EN_0_3 0x00000008lu
-#define	MATCH_EN_0_4 0x00000010lu
-#define	MATCH_EN_0_5 0x00000020lu
-#define	MATCH_EN_0_6 0x00000040lu
-#define	MATCH_EN_0_7 0x00000080lu
-
-#define	MATCH_EN_1_0 0x00000100lu
-#define	MATCH_EN_1_1 0x00000200lu
-#define	MATCH_EN_1_2 0x00000400lu
-#define	MATCH_EN_1_3 0x00000800lu
-#define	MATCH_EN_1_4 0x00001000lu
-#define	MATCH_EN_1_5 0x00002000lu
-#define	MATCH_EN_1_6 0x00004000lu
-#define	MATCH_EN_1_7 0x00008000lu
-
-#define	MATCH_EN_2_0 0x00010000lu
-#define	MATCH_EN_2_1 0x00020000lu
-#define	MATCH_EN_2_2 0x00040000lu
-#define	MATCH_EN_2_3 0x00080000lu
-#define	MATCH_EN_2_4 0x00100000lu
-#define	MATCH_EN_2_5 0x00200000lu
-#define	MATCH_EN_2_6 0x00400000lu
-#define	MATCH_EN_2_7 0x00800000lu
-
-#define	MATCH_EN_3_0 0x01000000lu
-#define	MATCH_EN_3_1 0x02000000lu
-#define	MATCH_EN_3_2 0x04000000lu
-#define	MATCH_EN_3_3 0x08000000lu
-#define	MATCH_EN_3_4 0x10000000lu
-#define	MATCH_EN_3_5 0x20000000lu
-#define	MATCH_EN_3_6 0x40000000lu
-#define	MATCH_EN_3_7 0x80000000lu
-
-
-/* MXVR_ROUTING_0 Masks */
-
-#define	MUTE_CH0	0x00000080lu
-#define	MUTE_CH1	0x00008000lu
-#define	MUTE_CH2	0x00800000lu
-#define	MUTE_CH3	0x80000000lu
-
-#define	TX_CH0		0x0000007Flu
-#define	TX_CH1		0x00007F00lu
-#define	TX_CH2		0x007F0000lu
-#define	TX_CH3		0x7F000000lu
-
-
-/* MXVR_ROUTING_1 Masks */
-
-#define	MUTE_CH4	0x00000080lu
-#define	MUTE_CH5	0x00008000lu
-#define	MUTE_CH6	0x00800000lu
-#define	MUTE_CH7	0x80000000lu
-
-#define	TX_CH4		0x0000007Flu
-#define	TX_CH5		0x00007F00lu
-#define	TX_CH6		0x007F0000lu
-#define	TX_CH7		0x7F000000lu
-
-
-/* MXVR_ROUTING_2 Masks */
-
-#define	MUTE_CH8	0x00000080lu
-#define	MUTE_CH9	0x00008000lu
-#define	MUTE_CH10	0x00800000lu
-#define	MUTE_CH11	0x80000000lu
-
-#define	TX_CH8		0x0000007Flu
-#define	TX_CH9		0x00007F00lu
-#define	TX_CH10		0x007F0000lu
-#define	TX_CH11		0x7F000000lu
-
-/* MXVR_ROUTING_3 Masks */
-
-#define	MUTE_CH12	0x00000080lu
-#define	MUTE_CH13	0x00008000lu
-#define	MUTE_CH14	0x00800000lu
-#define	MUTE_CH15	0x80000000lu
-
-#define	TX_CH12		0x0000007Flu
-#define	TX_CH13		0x00007F00lu
-#define	TX_CH14		0x007F0000lu
-#define	TX_CH15		0x7F000000lu
-
-
-/* MXVR_ROUTING_4 Masks */
-
-#define	MUTE_CH16	0x00000080lu
-#define	MUTE_CH17	0x00008000lu
-#define	MUTE_CH18	0x00800000lu
-#define	MUTE_CH19	0x80000000lu
-
-#define	TX_CH16		0x0000007Flu
-#define	TX_CH17		0x00007F00lu
-#define	TX_CH18		0x007F0000lu
-#define	TX_CH19		0x7F000000lu
-
-
-/* MXVR_ROUTING_5 Masks */
-
-#define	MUTE_CH20	0x00000080lu
-#define	MUTE_CH21	0x00008000lu
-#define	MUTE_CH22	0x00800000lu
-#define	MUTE_CH23	0x80000000lu
-
-#define	TX_CH20		0x0000007Flu
-#define	TX_CH21		0x00007F00lu
-#define	TX_CH22		0x007F0000lu
-#define	TX_CH23		0x7F000000lu
-
-
-/* MXVR_ROUTING_6 Masks */
-
-#define	MUTE_CH24	0x00000080lu
-#define	MUTE_CH25	0x00008000lu
-#define	MUTE_CH26	0x00800000lu
-#define	MUTE_CH27	0x80000000lu
-
-#define	TX_CH24		0x0000007Flu
-#define	TX_CH25		0x00007F00lu
-#define	TX_CH26		0x007F0000lu
-#define	TX_CH27		0x7F000000lu
-
-
-/* MXVR_ROUTING_7 Masks */
-
-#define	MUTE_CH28	0x00000080lu
-#define	MUTE_CH29	0x00008000lu
-#define	MUTE_CH30	0x00800000lu
-#define	MUTE_CH31	0x80000000lu
-
-#define	TX_CH28		0x0000007Flu
-#define	TX_CH29		0x00007F00lu
-#define	TX_CH30		0x007F0000lu
-#define	TX_CH31		0x7F000000lu
-
-
-/* MXVR_ROUTING_8 Masks */
-
-#define	MUTE_CH32	0x00000080lu
-#define	MUTE_CH33	0x00008000lu
-#define	MUTE_CH34	0x00800000lu
-#define	MUTE_CH35	0x80000000lu
-
-#define	TX_CH32		0x0000007Flu
-#define	TX_CH33		0x00007F00lu
-#define	TX_CH34		0x007F0000lu
-#define	TX_CH35		0x7F000000lu
-
-
-/* MXVR_ROUTING_9 Masks */
-
-#define	MUTE_CH36	0x00000080lu
-#define	MUTE_CH37	0x00008000lu
-#define	MUTE_CH38	0x00800000lu
-#define	MUTE_CH39	0x80000000lu
-
-#define	TX_CH36		0x0000007Flu
-#define	TX_CH37		0x00007F00lu
-#define	TX_CH38		0x007F0000lu
-#define	TX_CH39		0x7F000000lu
-
-
-/* MXVR_ROUTING_10 Masks */
-
-#define	MUTE_CH40	0x00000080lu
-#define	MUTE_CH41	0x00008000lu
-#define	MUTE_CH42	0x00800000lu
-#define	MUTE_CH43	0x80000000lu
-
-#define	TX_CH40		0x0000007Flu
-#define	TX_CH41		0x00007F00lu
-#define	TX_CH42		0x007F0000lu
-#define	TX_CH43		0x7F000000lu
-
-
-/* MXVR_ROUTING_11 Masks */
-
-#define	MUTE_CH44	0x00000080lu
-#define	MUTE_CH45	0x00008000lu
-#define	MUTE_CH46	0x00800000lu
-#define	MUTE_CH47	0x80000000lu
-
-#define	TX_CH44		0x0000007Flu
-#define	TX_CH45		0x00007F00lu
-#define	TX_CH46		0x007F0000lu
-#define	TX_CH47		0x7F000000lu
-
-
-/* MXVR_ROUTING_12 Masks */
-
-#define	MUTE_CH48	0x00000080lu
-#define	MUTE_CH49	0x00008000lu
-#define	MUTE_CH50	0x00800000lu
-#define	MUTE_CH51	0x80000000lu
-
-#define	TX_CH48		0x0000007Flu
-#define	TX_CH49		0x00007F00lu
-#define	TX_CH50		0x007F0000lu
-#define	TX_CH51		0x7F000000lu
-
-
-/* MXVR_ROUTING_13 Masks */
-
-#define	MUTE_CH52	0x00000080lu
-#define	MUTE_CH53	0x00008000lu
-#define	MUTE_CH54	0x00800000lu
-#define	MUTE_CH55	0x80000000lu
-
-#define	TX_CH52		0x0000007Flu
-#define	TX_CH53		0x00007F00lu
-#define	TX_CH54		0x007F0000lu
-#define	TX_CH55		0x7F000000lu
-
-
-/* MXVR_ROUTING_14 Masks */
-
-#define	MUTE_CH56	0x00000080lu
-#define	MUTE_CH57	0x00008000lu
-#define	MUTE_CH58	0x00800000lu
-#define	MUTE_CH59	0x80000000lu
-
-#define	TX_CH56		0x0000007Flu
-#define	TX_CH57		0x00007F00lu
-#define	TX_CH58		0x007F0000lu
-#define	TX_CH59		0x7F000000lu
-
-
-/* Control Message Receive Buffer (CMRB) Address Offsets */
-
-#define	CMRB_STRIDE	  0x00000016lu
-
-#define	CMRB_DST_OFFSET	  0x00000000lu
-#define	CMRB_SRC_OFFSET	  0x00000002lu
-#define	CMRB_DATA_OFFSET  0x00000005lu
-
-
-/* Control Message Transmit Buffer (CMTB) Address Offsets */
-
-#define	CMTB_PRIO_OFFSET    0x00000000lu
-#define	CMTB_DST_OFFSET	    0x00000002lu
-#define	CMTB_SRC_OFFSET	    0x00000004lu
-#define	CMTB_TYPE_OFFSET    0x00000006lu
-#define	CMTB_DATA_OFFSET    0x00000007lu
-
-#define	CMTB_ANSWER_OFFSET  0x0000000Alu
-
-#define	CMTB_STAT_N_OFFSET  0x00000018lu
-#define	CMTB_STAT_A_OFFSET  0x00000016lu
-#define	CMTB_STAT_D_OFFSET  0x0000000Elu
-#define	CMTB_STAT_R_OFFSET  0x00000014lu
-#define	CMTB_STAT_W_OFFSET  0x00000014lu
-#define	CMTB_STAT_G_OFFSET  0x00000014lu
-
-
-/* Asynchronous	Packet Receive Buffer (APRB) Address Offsets */
-
-#define	APRB_STRIDE	  0x00000400lu
-
-#define	APRB_DST_OFFSET	  0x00000000lu
-#define	APRB_LEN_OFFSET	  0x00000002lu
-#define	APRB_SRC_OFFSET	  0x00000004lu
-#define	APRB_DATA_OFFSET  0x00000006lu
-
-
-/* Asynchronous	Packet Transmit	Buffer (APTB) Address Offsets */
-
-#define	APTB_PRIO_OFFSET  0x00000000lu
-#define	APTB_DST_OFFSET	  0x00000002lu
-#define	APTB_LEN_OFFSET	  0x00000004lu
-#define	APTB_SRC_OFFSET	  0x00000006lu
-#define	APTB_DATA_OFFSET  0x00000008lu
-
-
-/* Remote Read Buffer (RRDB) Address Offsets */
-
-#define	RRDB_WADDR_OFFSET 0x00000100lu
-#define	RRDB_WLEN_OFFSET  0x00000101lu
-
-
-
 /* ************	 CONTROLLER AREA NETWORK (CAN) MASKS  ***************/
 /* CAN_CONTROL Masks					 */
 #define	SRS			0x0001	/* Software Reset */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/gpio.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/gpio.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Analog Devices Inc.
+ * Copyright (C) 2008-2009 Analog Devices Inc.
  * Licensed under the GPL-2 or later.
  */
 
@@ -7,11 +7,8 @@
 #ifndef _MACH_GPIO_H_
 #define _MACH_GPIO_H_
 
-	/* FIXME:
-	 * For now only support PORTF GPIOs.
-	 * PORT C,D and E are for peripheral usage only
-	 */
 #define MAX_BLACKFIN_GPIOS 16
+#define BFIN_SPECIAL_GPIO_BANKS 3
 
 #define	GPIO_PF0	0	/* PF */
 #define	GPIO_PF1	1
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/portmux.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/portmux.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/include/mach/portmux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/include/mach/portmux.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@
 #ifndef _MACH_PORTMUX_H_
 #define _MACH_PORTMUX_H_
 
-#define MAX_RESOURCES	MAX_BLACKFIN_GPIOS
+#define MAX_RESOURCES	64
 
 #define P_TMR2		(P_DONTCARE)
 #define P_TMR1		(P_DONTCARE)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf538/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf538/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,3 +3,4 @@
 #
 
 obj-y := ints-priority.o dma.o
+obj-$(CONFIG_GPIOLIB)	+= ext-gpio.o
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,7 +62,7 @@ static struct isp1760_platform_data isp1
 };
 
 static struct platform_device bfin_isp1760_device = {
-	.name           = "isp1760-hcd",
+	.name           = "isp1760",
 	.id             = 0,
 	.dev = {
 		.platform_data = &isp1760_priv,
@@ -154,7 +154,7 @@ static struct platform_device bf54x_kpad
 };
 #endif
 
-#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE)
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
 #include <asm/bfin_rotary.h>
 
 static struct bfin_rotary_platform_data bfin_rotary_data = {
@@ -186,7 +186,7 @@ static struct platform_device bfin_rotar
 #endif
 
 #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE)
-#include <linux/spi/adxl34x.h>
+#include <linux/input/adxl34x.h>
 static const struct adxl34x_platform_data adxl34x_info = {
 	.x_axis_offset = 0,
 	.y_axis_offset = 0,
@@ -210,14 +210,17 @@ static const struct adxl34x_platform_dat
 	.ev_code_y = ABS_Y,		/* EV_REL */
 	.ev_code_z = ABS_Z,		/* EV_REL */
 
-	.ev_code_tap_x = BTN_TOUCH,		/* EV_KEY */
-	.ev_code_tap_y = BTN_TOUCH,		/* EV_KEY */
-	.ev_code_tap_z = BTN_TOUCH,		/* EV_KEY */
+	.ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */
 
 /*	.ev_code_ff = KEY_F,*/		/* EV_KEY */
 /*	.ev_code_act_inactivity = KEY_A,*/	/* EV_KEY */
 	.power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
 	.fifo_mode = ADXL_FIFO_STREAM,
+	.orientation_enable = ADXL_EN_ORIENTATION_3D,
+	.deadzone_angle = ADXL_DEADZONE_ANGLE_10p8,
+	.divisor_length = ADXL_LP_FILTER_DIVISOR_16,
+	/* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */
+	.ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C},
 };
 #endif
 
@@ -461,6 +464,44 @@ static struct platform_device musb_devic
 };
 #endif
 
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+unsigned short bfin_can_peripherals[] = {
+	P_CAN0_RX, P_CAN0_TX, 0
+};
+
+static struct resource bfin_can_resources[] = {
+	{
+		.start = 0xFFC02A00,
+		.end = 0xFFC02FFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_CAN0_RX,
+		.end = IRQ_CAN0_RX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN0_TX,
+		.end = IRQ_CAN0_TX,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_CAN0_ERROR,
+		.end = IRQ_CAN0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_can_device = {
+	.name = "bfin_can",
+	.num_resources = ARRAY_SIZE(bfin_can_resources),
+	.resource = bfin_can_resources,
+	.dev = {
+		.platform_data = &bfin_can_peripherals, /* Passed to driver */
+	},
+};
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
 static struct resource bfin_atapi_resources[] = {
 	{
@@ -953,6 +994,10 @@ static struct platform_device *ezkit_dev
 	&bfin_isp1760_device,
 #endif
 
+#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
+	&bfin_can_device,
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
 	&bfin_atapi_device,
 #endif
@@ -974,7 +1019,7 @@ static struct platform_device *ezkit_dev
 	&bf54x_kpad_device,
 #endif
 
-#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE)
+#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
 	&bfin_rotary_device,
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/bf548.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/bf548.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/bf548.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/bf548.h	2010-02-24 13:52:17.000000000 -0500
@@ -81,18 +81,6 @@
 
 #define AMGCTLVAL	(V_AMBEN | V_AMCKEN)
 
-#if defined(CONFIG_BF542M)
-# define CONFIG_BF542
-#elif defined(CONFIG_BF544M)
-# define CONFIG_BF544
-#elif defined(CONFIG_BF547M)
-# define CONFIG_BF547
-#elif defined(CONFIG_BF548M)
-# define CONFIG_BF548
-#elif defined(CONFIG_BF549M)
-# define CONFIG_BF549
-#endif
-
 #if defined(CONFIG_BF542)
 # define CPU   "BF542"
 # define CPUID 0x27de
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,10 +64,4 @@
 #define OFFSET_THR              0x28	/* Transmit Holding register            */
 #define OFFSET_RBR              0x2C	/* Receive Buffer register              */
 
-/* PLL_DIV Masks */
-#define CCLK_DIV1 CSEL_DIV1	/* CCLK = VCO / 1 */
-#define CCLK_DIV2 CSEL_DIV2	/* CCLK = VCO / 2 */
-#define CCLK_DIV4 CSEL_DIV4	/* CCLK = VCO / 4 */
-#define CCLK_DIV8 CSEL_DIV8	/* CCLK = VCO / 8 */
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF547.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF547.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF547.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,21 +4,21 @@
  * Licensed under the GPL-2 or later.
  */
 
-#ifndef _CDEF_BF548_H
-#define _CDEF_BF548_H
+#ifndef _CDEF_BF547_H
+#define _CDEF_BF547_H
 
 /* include all Core registers and bit definitions */
-#include "defBF548.h"
+#include "defBF547.h"
 
 /* include core sbfin_read_()ecific register pointer definitions */
 #include <asm/cdef_LPBlackfin.h>
 
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */
+/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */
 
 /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
 #include "cdefBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF548 that are not in the common header */
+/* The following are the #defines needed by ADSP-BF547 that are not in the common header */
 
 /* Timer Registers */
 
@@ -805,4 +805,4 @@
 #define bfin_read_HMDMA1_BCOUNT()		bfin_read16(HMDMA1_BCOUNT)
 #define bfin_write_HMDMA1_BCOUNT(val)		bfin_write16(HMDMA1_BCOUNT, val)
 
-#endif /* _CDEF_BF548_H */
+#endif /* _CDEF_BF547_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF548.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF548.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF548.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,165 +18,8 @@
 /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
 #include "cdefBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF548 that are not in the common header */
-
-/* Timer Registers */
-
-#define bfin_read_TIMER8_CONFIG()	bfin_read16(TIMER8_CONFIG)
-#define bfin_write_TIMER8_CONFIG(val)	bfin_write16(TIMER8_CONFIG, val)
-#define bfin_read_TIMER8_COUNTER()	bfin_read32(TIMER8_COUNTER)
-#define bfin_write_TIMER8_COUNTER(val)	bfin_write32(TIMER8_COUNTER, val)
-#define bfin_read_TIMER8_PERIOD()	bfin_read32(TIMER8_PERIOD)
-#define bfin_write_TIMER8_PERIOD(val)	bfin_write32(TIMER8_PERIOD, val)
-#define bfin_read_TIMER8_WIDTH()	bfin_read32(TIMER8_WIDTH)
-#define bfin_write_TIMER8_WIDTH(val)	bfin_write32(TIMER8_WIDTH, val)
-#define bfin_read_TIMER9_CONFIG()	bfin_read16(TIMER9_CONFIG)
-#define bfin_write_TIMER9_CONFIG(val)	bfin_write16(TIMER9_CONFIG, val)
-#define bfin_read_TIMER9_COUNTER()	bfin_read32(TIMER9_COUNTER)
-#define bfin_write_TIMER9_COUNTER(val)	bfin_write32(TIMER9_COUNTER, val)
-#define bfin_read_TIMER9_PERIOD()	bfin_read32(TIMER9_PERIOD)
-#define bfin_write_TIMER9_PERIOD(val)	bfin_write32(TIMER9_PERIOD, val)
-#define bfin_read_TIMER9_WIDTH()	bfin_read32(TIMER9_WIDTH)
-#define bfin_write_TIMER9_WIDTH(val)	bfin_write32(TIMER9_WIDTH, val)
-#define bfin_read_TIMER10_CONFIG()	bfin_read16(TIMER10_CONFIG)
-#define bfin_write_TIMER10_CONFIG(val)	bfin_write16(TIMER10_CONFIG, val)
-#define bfin_read_TIMER10_COUNTER()	bfin_read32(TIMER10_COUNTER)
-#define bfin_write_TIMER10_COUNTER(val)	bfin_write32(TIMER10_COUNTER, val)
-#define bfin_read_TIMER10_PERIOD()	bfin_read32(TIMER10_PERIOD)
-#define bfin_write_TIMER10_PERIOD(val)	bfin_write32(TIMER10_PERIOD, val)
-#define bfin_read_TIMER10_WIDTH()	bfin_read32(TIMER10_WIDTH)
-#define bfin_write_TIMER10_WIDTH(val)	bfin_write32(TIMER10_WIDTH, val)
-
-/* Timer Groubfin_read_() of 3 */
-
-#define bfin_read_TIMER_ENABLE1()	bfin_read16(TIMER_ENABLE1)
-#define bfin_write_TIMER_ENABLE1(val)	bfin_write16(TIMER_ENABLE1, val)
-#define bfin_read_TIMER_DISABLE1()	bfin_read16(TIMER_DISABLE1)
-#define bfin_write_TIMER_DISABLE1(val)	bfin_write16(TIMER_DISABLE1, val)
-#define bfin_read_TIMER_STATUS1()	bfin_read32(TIMER_STATUS1)
-#define bfin_write_TIMER_STATUS1(val)	bfin_write32(TIMER_STATUS1, val)
-
-/* SPORT0 Registers */
-
-#define bfin_read_SPORT0_TCR1()		bfin_read16(SPORT0_TCR1)
-#define bfin_write_SPORT0_TCR1(val)	bfin_write16(SPORT0_TCR1, val)
-#define bfin_read_SPORT0_TCR2()		bfin_read16(SPORT0_TCR2)
-#define bfin_write_SPORT0_TCR2(val)	bfin_write16(SPORT0_TCR2, val)
-#define bfin_read_SPORT0_TCLKDIV()	bfin_read16(SPORT0_TCLKDIV)
-#define bfin_write_SPORT0_TCLKDIV(val)	bfin_write16(SPORT0_TCLKDIV, val)
-#define bfin_read_SPORT0_TFSDIV()	bfin_read16(SPORT0_TFSDIV)
-#define bfin_write_SPORT0_TFSDIV(val)	bfin_write16(SPORT0_TFSDIV, val)
-#define bfin_read_SPORT0_TX()		bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX(val)	bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX()		bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX(val)	bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_RCR1()		bfin_read16(SPORT0_RCR1)
-#define bfin_write_SPORT0_RCR1(val)	bfin_write16(SPORT0_RCR1, val)
-#define bfin_read_SPORT0_RCR2()		bfin_read16(SPORT0_RCR2)
-#define bfin_write_SPORT0_RCR2(val)	bfin_write16(SPORT0_RCR2, val)
-#define bfin_read_SPORT0_RCLKDIV()	bfin_read16(SPORT0_RCLKDIV)
-#define bfin_write_SPORT0_RCLKDIV(val)	bfin_write16(SPORT0_RCLKDIV, val)
-#define bfin_read_SPORT0_RFSDIV()	bfin_read16(SPORT0_RFSDIV)
-#define bfin_write_SPORT0_RFSDIV(val)	bfin_write16(SPORT0_RFSDIV, val)
-#define bfin_read_SPORT0_STAT()		bfin_read16(SPORT0_STAT)
-#define bfin_write_SPORT0_STAT(val)	bfin_write16(SPORT0_STAT, val)
-#define bfin_read_SPORT0_CHNL()		bfin_read16(SPORT0_CHNL)
-#define bfin_write_SPORT0_CHNL(val)	bfin_write16(SPORT0_CHNL, val)
-#define bfin_read_SPORT0_MCMC1()	bfin_read16(SPORT0_MCMC1)
-#define bfin_write_SPORT0_MCMC1(val)	bfin_write16(SPORT0_MCMC1, val)
-#define bfin_read_SPORT0_MCMC2()	bfin_read16(SPORT0_MCMC2)
-#define bfin_write_SPORT0_MCMC2(val)	bfin_write16(SPORT0_MCMC2, val)
-#define bfin_read_SPORT0_MTCS0()	bfin_read32(SPORT0_MTCS0)
-#define bfin_write_SPORT0_MTCS0(val)	bfin_write32(SPORT0_MTCS0, val)
-#define bfin_read_SPORT0_MTCS1()	bfin_read32(SPORT0_MTCS1)
-#define bfin_write_SPORT0_MTCS1(val)	bfin_write32(SPORT0_MTCS1, val)
-#define bfin_read_SPORT0_MTCS2()	bfin_read32(SPORT0_MTCS2)
-#define bfin_write_SPORT0_MTCS2(val)	bfin_write32(SPORT0_MTCS2, val)
-#define bfin_read_SPORT0_MTCS3()	bfin_read32(SPORT0_MTCS3)
-#define bfin_write_SPORT0_MTCS3(val)	bfin_write32(SPORT0_MTCS3, val)
-#define bfin_read_SPORT0_MRCS0()	bfin_read32(SPORT0_MRCS0)
-#define bfin_write_SPORT0_MRCS0(val)	bfin_write32(SPORT0_MRCS0, val)
-#define bfin_read_SPORT0_MRCS1()	bfin_read32(SPORT0_MRCS1)
-#define bfin_write_SPORT0_MRCS1(val)	bfin_write32(SPORT0_MRCS1, val)
-#define bfin_read_SPORT0_MRCS2()	bfin_read32(SPORT0_MRCS2)
-#define bfin_write_SPORT0_MRCS2(val)	bfin_write32(SPORT0_MRCS2, val)
-#define bfin_read_SPORT0_MRCS3()	bfin_read32(SPORT0_MRCS3)
-#define bfin_write_SPORT0_MRCS3(val)	bfin_write32(SPORT0_MRCS3, val)
-
-/* EPPI0 Registers */
-
-#define bfin_read_EPPI0_STATUS()	bfin_read16(EPPI0_STATUS)
-#define bfin_write_EPPI0_STATUS(val)	bfin_write16(EPPI0_STATUS, val)
-#define bfin_read_EPPI0_HCOUNT()	bfin_read16(EPPI0_HCOUNT)
-#define bfin_write_EPPI0_HCOUNT(val)	bfin_write16(EPPI0_HCOUNT, val)
-#define bfin_read_EPPI0_HDELAY()	bfin_read16(EPPI0_HDELAY)
-#define bfin_write_EPPI0_HDELAY(val)	bfin_write16(EPPI0_HDELAY, val)
-#define bfin_read_EPPI0_VCOUNT()	bfin_read16(EPPI0_VCOUNT)
-#define bfin_write_EPPI0_VCOUNT(val)	bfin_write16(EPPI0_VCOUNT, val)
-#define bfin_read_EPPI0_VDELAY()	bfin_read16(EPPI0_VDELAY)
-#define bfin_write_EPPI0_VDELAY(val)	bfin_write16(EPPI0_VDELAY, val)
-#define bfin_read_EPPI0_FRAME()		bfin_read16(EPPI0_FRAME)
-#define bfin_write_EPPI0_FRAME(val)	bfin_write16(EPPI0_FRAME, val)
-#define bfin_read_EPPI0_LINE()		bfin_read16(EPPI0_LINE)
-#define bfin_write_EPPI0_LINE(val)	bfin_write16(EPPI0_LINE, val)
-#define bfin_read_EPPI0_CLKDIV()	bfin_read16(EPPI0_CLKDIV)
-#define bfin_write_EPPI0_CLKDIV(val)	bfin_write16(EPPI0_CLKDIV, val)
-#define bfin_read_EPPI0_CONTROL()	bfin_read32(EPPI0_CONTROL)
-#define bfin_write_EPPI0_CONTROL(val)	bfin_write32(EPPI0_CONTROL, val)
-#define bfin_read_EPPI0_FS1W_HBL()	bfin_read32(EPPI0_FS1W_HBL)
-#define bfin_write_EPPI0_FS1W_HBL(val)	bfin_write32(EPPI0_FS1W_HBL, val)
-#define bfin_read_EPPI0_FS1P_AVPL()	bfin_read32(EPPI0_FS1P_AVPL)
-#define bfin_write_EPPI0_FS1P_AVPL(val)	bfin_write32(EPPI0_FS1P_AVPL, val)
-#define bfin_read_EPPI0_FS2W_LVB()	bfin_read32(EPPI0_FS2W_LVB)
-#define bfin_write_EPPI0_FS2W_LVB(val)	bfin_write32(EPPI0_FS2W_LVB, val)
-#define bfin_read_EPPI0_FS2P_LAVF()	bfin_read32(EPPI0_FS2P_LAVF)
-#define bfin_write_EPPI0_FS2P_LAVF(val)	bfin_write32(EPPI0_FS2P_LAVF, val)
-#define bfin_read_EPPI0_CLIP()		bfin_read32(EPPI0_CLIP)
-#define bfin_write_EPPI0_CLIP(val)	bfin_write32(EPPI0_CLIP, val)
-
-/* UART2 Registers */
-
-#define bfin_read_UART2_DLL()		bfin_read16(UART2_DLL)
-#define bfin_write_UART2_DLL(val)	bfin_write16(UART2_DLL, val)
-#define bfin_read_UART2_DLH()		bfin_read16(UART2_DLH)
-#define bfin_write_UART2_DLH(val)	bfin_write16(UART2_DLH, val)
-#define bfin_read_UART2_GCTL()		bfin_read16(UART2_GCTL)
-#define bfin_write_UART2_GCTL(val)	bfin_write16(UART2_GCTL, val)
-#define bfin_read_UART2_LCR()		bfin_read16(UART2_LCR)
-#define bfin_write_UART2_LCR(val)	bfin_write16(UART2_LCR, val)
-#define bfin_read_UART2_MCR()		bfin_read16(UART2_MCR)
-#define bfin_write_UART2_MCR(val)	bfin_write16(UART2_MCR, val)
-#define bfin_read_UART2_LSR()		bfin_read16(UART2_LSR)
-#define bfin_write_UART2_LSR(val)	bfin_write16(UART2_LSR, val)
-#define bfin_read_UART2_MSR()		bfin_read16(UART2_MSR)
-#define bfin_write_UART2_MSR(val)	bfin_write16(UART2_MSR, val)
-#define bfin_read_UART2_SCR()		bfin_read16(UART2_SCR)
-#define bfin_write_UART2_SCR(val)	bfin_write16(UART2_SCR, val)
-#define bfin_read_UART2_IER_SET()	bfin_read16(UART2_IER_SET)
-#define bfin_write_UART2_IER_SET(val)	bfin_write16(UART2_IER_SET, val)
-#define bfin_read_UART2_IER_CLEAR()	bfin_read16(UART2_IER_CLEAR)
-#define bfin_write_UART2_IER_CLEAR(val)	bfin_write16(UART2_IER_CLEAR, val)
-#define bfin_read_UART2_RBR()		bfin_read16(UART2_RBR)
-#define bfin_write_UART2_RBR(val)	bfin_write16(UART2_RBR, val)
-
-/* Two Wire Interface Registers (TWI1) */
-
-/* SPI2  Registers */
-
-#define bfin_read_SPI2_CTL()		bfin_read16(SPI2_CTL)
-#define bfin_write_SPI2_CTL(val)	bfin_write16(SPI2_CTL, val)
-#define bfin_read_SPI2_FLG()		bfin_read16(SPI2_FLG)
-#define bfin_write_SPI2_FLG(val)	bfin_write16(SPI2_FLG, val)
-#define bfin_read_SPI2_STAT()		bfin_read16(SPI2_STAT)
-#define bfin_write_SPI2_STAT(val)	bfin_write16(SPI2_STAT, val)
-#define bfin_read_SPI2_TDBR()		bfin_read16(SPI2_TDBR)
-#define bfin_write_SPI2_TDBR(val)	bfin_write16(SPI2_TDBR, val)
-#define bfin_read_SPI2_RDBR()		bfin_read16(SPI2_RDBR)
-#define bfin_write_SPI2_RDBR(val)	bfin_write16(SPI2_RDBR, val)
-#define bfin_read_SPI2_BAUD()		bfin_read16(SPI2_BAUD)
-#define bfin_write_SPI2_BAUD(val)	bfin_write16(SPI2_BAUD, val)
-#define bfin_read_SPI2_SHADOW()		bfin_read16(SPI2_SHADOW)
-#define bfin_write_SPI2_SHADOW(val)	bfin_write16(SPI2_SHADOW, val)
+/* The BF548 is like the BF547, but has additional CANs */
+#include "cdefBF547.h"
 
 /* CAN Controller 1 Config 1 Registers */
 
@@ -923,631 +766,4 @@
 #define bfin_read_CAN1_MB31_ID1()		bfin_read16(CAN1_MB31_ID1)
 #define bfin_write_CAN1_MB31_ID1(val)		bfin_write16(CAN1_MB31_ID1, val)
 
-/* ATAPI Registers */
-
-#define bfin_read_ATAPI_CONTROL()		bfin_read16(ATAPI_CONTROL)
-#define bfin_write_ATAPI_CONTROL(val)		bfin_write16(ATAPI_CONTROL, val)
-#define bfin_read_ATAPI_STATUS()		bfin_read16(ATAPI_STATUS)
-#define bfin_write_ATAPI_STATUS(val)		bfin_write16(ATAPI_STATUS, val)
-#define bfin_read_ATAPI_DEV_ADDR()		bfin_read16(ATAPI_DEV_ADDR)
-#define bfin_write_ATAPI_DEV_ADDR(val)		bfin_write16(ATAPI_DEV_ADDR, val)
-#define bfin_read_ATAPI_DEV_TXBUF()		bfin_read16(ATAPI_DEV_TXBUF)
-#define bfin_write_ATAPI_DEV_TXBUF(val)		bfin_write16(ATAPI_DEV_TXBUF, val)
-#define bfin_read_ATAPI_DEV_RXBUF()		bfin_read16(ATAPI_DEV_RXBUF)
-#define bfin_write_ATAPI_DEV_RXBUF(val)		bfin_write16(ATAPI_DEV_RXBUF, val)
-#define bfin_read_ATAPI_INT_MASK()		bfin_read16(ATAPI_INT_MASK)
-#define bfin_write_ATAPI_INT_MASK(val)		bfin_write16(ATAPI_INT_MASK, val)
-#define bfin_read_ATAPI_INT_STATUS()		bfin_read16(ATAPI_INT_STATUS)
-#define bfin_write_ATAPI_INT_STATUS(val)	bfin_write16(ATAPI_INT_STATUS, val)
-#define bfin_read_ATAPI_XFER_LEN()		bfin_read16(ATAPI_XFER_LEN)
-#define bfin_write_ATAPI_XFER_LEN(val)		bfin_write16(ATAPI_XFER_LEN, val)
-#define bfin_read_ATAPI_LINE_STATUS()		bfin_read16(ATAPI_LINE_STATUS)
-#define bfin_write_ATAPI_LINE_STATUS(val)	bfin_write16(ATAPI_LINE_STATUS, val)
-#define bfin_read_ATAPI_SM_STATE()		bfin_read16(ATAPI_SM_STATE)
-#define bfin_write_ATAPI_SM_STATE(val)		bfin_write16(ATAPI_SM_STATE, val)
-#define bfin_read_ATAPI_TERMINATE()		bfin_read16(ATAPI_TERMINATE)
-#define bfin_write_ATAPI_TERMINATE(val)		bfin_write16(ATAPI_TERMINATE, val)
-#define bfin_read_ATAPI_PIO_TFRCNT()		bfin_read16(ATAPI_PIO_TFRCNT)
-#define bfin_write_ATAPI_PIO_TFRCNT(val)	bfin_write16(ATAPI_PIO_TFRCNT, val)
-#define bfin_read_ATAPI_DMA_TFRCNT()		bfin_read16(ATAPI_DMA_TFRCNT)
-#define bfin_write_ATAPI_DMA_TFRCNT(val)	bfin_write16(ATAPI_DMA_TFRCNT, val)
-#define bfin_read_ATAPI_UMAIN_TFRCNT()		bfin_read16(ATAPI_UMAIN_TFRCNT)
-#define bfin_write_ATAPI_UMAIN_TFRCNT(val)	bfin_write16(ATAPI_UMAIN_TFRCNT, val)
-#define bfin_read_ATAPI_UDMAOUT_TFRCNT()	bfin_read16(ATAPI_UDMAOUT_TFRCNT)
-#define bfin_write_ATAPI_UDMAOUT_TFRCNT(val)	bfin_write16(ATAPI_UDMAOUT_TFRCNT, val)
-#define bfin_read_ATAPI_REG_TIM_0()		bfin_read16(ATAPI_REG_TIM_0)
-#define bfin_write_ATAPI_REG_TIM_0(val)		bfin_write16(ATAPI_REG_TIM_0, val)
-#define bfin_read_ATAPI_PIO_TIM_0()		bfin_read16(ATAPI_PIO_TIM_0)
-#define bfin_write_ATAPI_PIO_TIM_0(val)		bfin_write16(ATAPI_PIO_TIM_0, val)
-#define bfin_read_ATAPI_PIO_TIM_1()		bfin_read16(ATAPI_PIO_TIM_1)
-#define bfin_write_ATAPI_PIO_TIM_1(val)		bfin_write16(ATAPI_PIO_TIM_1, val)
-#define bfin_read_ATAPI_MULTI_TIM_0()		bfin_read16(ATAPI_MULTI_TIM_0)
-#define bfin_write_ATAPI_MULTI_TIM_0(val)	bfin_write16(ATAPI_MULTI_TIM_0, val)
-#define bfin_read_ATAPI_MULTI_TIM_1()		bfin_read16(ATAPI_MULTI_TIM_1)
-#define bfin_write_ATAPI_MULTI_TIM_1(val)	bfin_write16(ATAPI_MULTI_TIM_1, val)
-#define bfin_read_ATAPI_MULTI_TIM_2()		bfin_read16(ATAPI_MULTI_TIM_2)
-#define bfin_write_ATAPI_MULTI_TIM_2(val)	bfin_write16(ATAPI_MULTI_TIM_2, val)
-#define bfin_read_ATAPI_ULTRA_TIM_0()		bfin_read16(ATAPI_ULTRA_TIM_0)
-#define bfin_write_ATAPI_ULTRA_TIM_0(val)	bfin_write16(ATAPI_ULTRA_TIM_0, val)
-#define bfin_read_ATAPI_ULTRA_TIM_1()		bfin_read16(ATAPI_ULTRA_TIM_1)
-#define bfin_write_ATAPI_ULTRA_TIM_1(val)	bfin_write16(ATAPI_ULTRA_TIM_1, val)
-#define bfin_read_ATAPI_ULTRA_TIM_2()		bfin_read16(ATAPI_ULTRA_TIM_2)
-#define bfin_write_ATAPI_ULTRA_TIM_2(val)	bfin_write16(ATAPI_ULTRA_TIM_2, val)
-#define bfin_read_ATAPI_ULTRA_TIM_3()		bfin_read16(ATAPI_ULTRA_TIM_3)
-#define bfin_write_ATAPI_ULTRA_TIM_3(val)	bfin_write16(ATAPI_ULTRA_TIM_3, val)
-
-/* SDH Registers */
-
-#define bfin_read_SDH_PWR_CTL()		bfin_read16(SDH_PWR_CTL)
-#define bfin_write_SDH_PWR_CTL(val)	bfin_write16(SDH_PWR_CTL, val)
-#define bfin_read_SDH_CLK_CTL()		bfin_read16(SDH_CLK_CTL)
-#define bfin_write_SDH_CLK_CTL(val)	bfin_write16(SDH_CLK_CTL, val)
-#define bfin_read_SDH_ARGUMENT()	bfin_read32(SDH_ARGUMENT)
-#define bfin_write_SDH_ARGUMENT(val)	bfin_write32(SDH_ARGUMENT, val)
-#define bfin_read_SDH_COMMAND()		bfin_read16(SDH_COMMAND)
-#define bfin_write_SDH_COMMAND(val)	bfin_write16(SDH_COMMAND, val)
-#define bfin_read_SDH_RESP_CMD()	bfin_read16(SDH_RESP_CMD)
-#define bfin_write_SDH_RESP_CMD(val)	bfin_write16(SDH_RESP_CMD, val)
-#define bfin_read_SDH_RESPONSE0()	bfin_read32(SDH_RESPONSE0)
-#define bfin_write_SDH_RESPONSE0(val)	bfin_write32(SDH_RESPONSE0, val)
-#define bfin_read_SDH_RESPONSE1()	bfin_read32(SDH_RESPONSE1)
-#define bfin_write_SDH_RESPONSE1(val)	bfin_write32(SDH_RESPONSE1, val)
-#define bfin_read_SDH_RESPONSE2()	bfin_read32(SDH_RESPONSE2)
-#define bfin_write_SDH_RESPONSE2(val)	bfin_write32(SDH_RESPONSE2, val)
-#define bfin_read_SDH_RESPONSE3()	bfin_read32(SDH_RESPONSE3)
-#define bfin_write_SDH_RESPONSE3(val)	bfin_write32(SDH_RESPONSE3, val)
-#define bfin_read_SDH_DATA_TIMER()	bfin_read32(SDH_DATA_TIMER)
-#define bfin_write_SDH_DATA_TIMER(val)	bfin_write32(SDH_DATA_TIMER, val)
-#define bfin_read_SDH_DATA_LGTH()	bfin_read16(SDH_DATA_LGTH)
-#define bfin_write_SDH_DATA_LGTH(val)	bfin_write16(SDH_DATA_LGTH, val)
-#define bfin_read_SDH_DATA_CTL()	bfin_read16(SDH_DATA_CTL)
-#define bfin_write_SDH_DATA_CTL(val)	bfin_write16(SDH_DATA_CTL, val)
-#define bfin_read_SDH_DATA_CNT()	bfin_read16(SDH_DATA_CNT)
-#define bfin_write_SDH_DATA_CNT(val)	bfin_write16(SDH_DATA_CNT, val)
-#define bfin_read_SDH_STATUS()		bfin_read32(SDH_STATUS)
-#define bfin_write_SDH_STATUS(val)	bfin_write32(SDH_STATUS, val)
-#define bfin_read_SDH_STATUS_CLR()	bfin_read16(SDH_STATUS_CLR)
-#define bfin_write_SDH_STATUS_CLR(val)	bfin_write16(SDH_STATUS_CLR, val)
-#define bfin_read_SDH_MASK0()		bfin_read32(SDH_MASK0)
-#define bfin_write_SDH_MASK0(val)	bfin_write32(SDH_MASK0, val)
-#define bfin_read_SDH_MASK1()		bfin_read32(SDH_MASK1)
-#define bfin_write_SDH_MASK1(val)	bfin_write32(SDH_MASK1, val)
-#define bfin_read_SDH_FIFO_CNT()	bfin_read16(SDH_FIFO_CNT)
-#define bfin_write_SDH_FIFO_CNT(val)	bfin_write16(SDH_FIFO_CNT, val)
-#define bfin_read_SDH_FIFO()		bfin_read32(SDH_FIFO)
-#define bfin_write_SDH_FIFO(val)	bfin_write32(SDH_FIFO, val)
-#define bfin_read_SDH_E_STATUS()	bfin_read16(SDH_E_STATUS)
-#define bfin_write_SDH_E_STATUS(val)	bfin_write16(SDH_E_STATUS, val)
-#define bfin_read_SDH_E_MASK()		bfin_read16(SDH_E_MASK)
-#define bfin_write_SDH_E_MASK(val)	bfin_write16(SDH_E_MASK, val)
-#define bfin_read_SDH_CFG()		bfin_read16(SDH_CFG)
-#define bfin_write_SDH_CFG(val)		bfin_write16(SDH_CFG, val)
-#define bfin_read_SDH_RD_WAIT_EN()	bfin_read16(SDH_RD_WAIT_EN)
-#define bfin_write_SDH_RD_WAIT_EN(val)	bfin_write16(SDH_RD_WAIT_EN, val)
-#define bfin_read_SDH_PID0()		bfin_read16(SDH_PID0)
-#define bfin_write_SDH_PID0(val)	bfin_write16(SDH_PID0, val)
-#define bfin_read_SDH_PID1()		bfin_read16(SDH_PID1)
-#define bfin_write_SDH_PID1(val)	bfin_write16(SDH_PID1, val)
-#define bfin_read_SDH_PID2()		bfin_read16(SDH_PID2)
-#define bfin_write_SDH_PID2(val)	bfin_write16(SDH_PID2, val)
-#define bfin_read_SDH_PID3()		bfin_read16(SDH_PID3)
-#define bfin_write_SDH_PID3(val)	bfin_write16(SDH_PID3, val)
-#define bfin_read_SDH_PID4()		bfin_read16(SDH_PID4)
-#define bfin_write_SDH_PID4(val)	bfin_write16(SDH_PID4, val)
-#define bfin_read_SDH_PID5()		bfin_read16(SDH_PID5)
-#define bfin_write_SDH_PID5(val)	bfin_write16(SDH_PID5, val)
-#define bfin_read_SDH_PID6()		bfin_read16(SDH_PID6)
-#define bfin_write_SDH_PID6(val)	bfin_write16(SDH_PID6, val)
-#define bfin_read_SDH_PID7()		bfin_read16(SDH_PID7)
-#define bfin_write_SDH_PID7(val)	bfin_write16(SDH_PID7, val)
-
-/* HOST Port Registers */
-
-#define bfin_read_HOST_CONTROL()	bfin_read16(HOST_CONTROL)
-#define bfin_write_HOST_CONTROL(val)	bfin_write16(HOST_CONTROL, val)
-#define bfin_read_HOST_STATUS()		bfin_read16(HOST_STATUS)
-#define bfin_write_HOST_STATUS(val)	bfin_write16(HOST_STATUS, val)
-#define bfin_read_HOST_TIMEOUT()	bfin_read16(HOST_TIMEOUT)
-#define bfin_write_HOST_TIMEOUT(val)	bfin_write16(HOST_TIMEOUT, val)
-
-/* USB Control Registers */
-
-#define bfin_read_USB_FADDR()		bfin_read16(USB_FADDR)
-#define bfin_write_USB_FADDR(val)	bfin_write16(USB_FADDR, val)
-#define bfin_read_USB_POWER()		bfin_read16(USB_POWER)
-#define bfin_write_USB_POWER(val)	bfin_write16(USB_POWER, val)
-#define bfin_read_USB_INTRTX()		bfin_read16(USB_INTRTX)
-#define bfin_write_USB_INTRTX(val)	bfin_write16(USB_INTRTX, val)
-#define bfin_read_USB_INTRRX()		bfin_read16(USB_INTRRX)
-#define bfin_write_USB_INTRRX(val)	bfin_write16(USB_INTRRX, val)
-#define bfin_read_USB_INTRTXE()		bfin_read16(USB_INTRTXE)
-#define bfin_write_USB_INTRTXE(val)	bfin_write16(USB_INTRTXE, val)
-#define bfin_read_USB_INTRRXE()		bfin_read16(USB_INTRRXE)
-#define bfin_write_USB_INTRRXE(val)	bfin_write16(USB_INTRRXE, val)
-#define bfin_read_USB_INTRUSB()		bfin_read16(USB_INTRUSB)
-#define bfin_write_USB_INTRUSB(val)	bfin_write16(USB_INTRUSB, val)
-#define bfin_read_USB_INTRUSBE()	bfin_read16(USB_INTRUSBE)
-#define bfin_write_USB_INTRUSBE(val)	bfin_write16(USB_INTRUSBE, val)
-#define bfin_read_USB_FRAME()		bfin_read16(USB_FRAME)
-#define bfin_write_USB_FRAME(val)	bfin_write16(USB_FRAME, val)
-#define bfin_read_USB_INDEX()		bfin_read16(USB_INDEX)
-#define bfin_write_USB_INDEX(val)	bfin_write16(USB_INDEX, val)
-#define bfin_read_USB_TESTMODE()	bfin_read16(USB_TESTMODE)
-#define bfin_write_USB_TESTMODE(val)	bfin_write16(USB_TESTMODE, val)
-#define bfin_read_USB_GLOBINTR()	bfin_read16(USB_GLOBINTR)
-#define bfin_write_USB_GLOBINTR(val)	bfin_write16(USB_GLOBINTR, val)
-#define bfin_read_USB_GLOBAL_CTL()	bfin_read16(USB_GLOBAL_CTL)
-#define bfin_write_USB_GLOBAL_CTL(val)		bfin_write16(USB_GLOBAL_CTL, val)
-
-/* USB Packet Control Registers */
-
-#define bfin_read_USB_TX_MAX_PACKET()		bfin_read16(USB_TX_MAX_PACKET)
-#define bfin_write_USB_TX_MAX_PACKET(val)	bfin_write16(USB_TX_MAX_PACKET, val)
-#define bfin_read_USB_CSR0()		bfin_read16(USB_CSR0)
-#define bfin_write_USB_CSR0(val)	bfin_write16(USB_CSR0, val)
-#define bfin_read_USB_TXCSR()		bfin_read16(USB_TXCSR)
-#define bfin_write_USB_TXCSR(val)	bfin_write16(USB_TXCSR, val)
-#define bfin_read_USB_RX_MAX_PACKET()		bfin_read16(USB_RX_MAX_PACKET)
-#define bfin_write_USB_RX_MAX_PACKET(val)	bfin_write16(USB_RX_MAX_PACKET, val)
-#define bfin_read_USB_RXCSR()		bfin_read16(USB_RXCSR)
-#define bfin_write_USB_RXCSR(val)	bfin_write16(USB_RXCSR, val)
-#define bfin_read_USB_COUNT0()		bfin_read16(USB_COUNT0)
-#define bfin_write_USB_COUNT0(val)	bfin_write16(USB_COUNT0, val)
-#define bfin_read_USB_RXCOUNT()		bfin_read16(USB_RXCOUNT)
-#define bfin_write_USB_RXCOUNT(val)	bfin_write16(USB_RXCOUNT, val)
-#define bfin_read_USB_TXTYPE()		bfin_read16(USB_TXTYPE)
-#define bfin_write_USB_TXTYPE(val)	bfin_write16(USB_TXTYPE, val)
-#define bfin_read_USB_NAKLIMIT0()	bfin_read16(USB_NAKLIMIT0)
-#define bfin_write_USB_NAKLIMIT0(val)	bfin_write16(USB_NAKLIMIT0, val)
-#define bfin_read_USB_TXINTERVAL()	bfin_read16(USB_TXINTERVAL)
-#define bfin_write_USB_TXINTERVAL(val)	bfin_write16(USB_TXINTERVAL, val)
-#define bfin_read_USB_RXTYPE()		bfin_read16(USB_RXTYPE)
-#define bfin_write_USB_RXTYPE(val)	bfin_write16(USB_RXTYPE, val)
-#define bfin_read_USB_RXINTERVAL()	bfin_read16(USB_RXINTERVAL)
-#define bfin_write_USB_RXINTERVAL(val)	bfin_write16(USB_RXINTERVAL, val)
-#define bfin_read_USB_TXCOUNT()		bfin_read16(USB_TXCOUNT)
-#define bfin_write_USB_TXCOUNT(val)	bfin_write16(USB_TXCOUNT, val)
-
-/* USB Endbfin_read_()oint FIFO Registers */
-
-#define bfin_read_USB_EP0_FIFO()	bfin_read16(USB_EP0_FIFO)
-#define bfin_write_USB_EP0_FIFO(val)	bfin_write16(USB_EP0_FIFO, val)
-#define bfin_read_USB_EP1_FIFO()	bfin_read16(USB_EP1_FIFO)
-#define bfin_write_USB_EP1_FIFO(val)	bfin_write16(USB_EP1_FIFO, val)
-#define bfin_read_USB_EP2_FIFO()	bfin_read16(USB_EP2_FIFO)
-#define bfin_write_USB_EP2_FIFO(val)	bfin_write16(USB_EP2_FIFO, val)
-#define bfin_read_USB_EP3_FIFO()	bfin_read16(USB_EP3_FIFO)
-#define bfin_write_USB_EP3_FIFO(val)	bfin_write16(USB_EP3_FIFO, val)
-#define bfin_read_USB_EP4_FIFO()	bfin_read16(USB_EP4_FIFO)
-#define bfin_write_USB_EP4_FIFO(val)	bfin_write16(USB_EP4_FIFO, val)
-#define bfin_read_USB_EP5_FIFO()	bfin_read16(USB_EP5_FIFO)
-#define bfin_write_USB_EP5_FIFO(val)	bfin_write16(USB_EP5_FIFO, val)
-#define bfin_read_USB_EP6_FIFO()	bfin_read16(USB_EP6_FIFO)
-#define bfin_write_USB_EP6_FIFO(val)	bfin_write16(USB_EP6_FIFO, val)
-#define bfin_read_USB_EP7_FIFO()	bfin_read16(USB_EP7_FIFO)
-#define bfin_write_USB_EP7_FIFO(val)	bfin_write16(USB_EP7_FIFO, val)
-
-/* USB OTG Control Registers */
-
-#define bfin_read_USB_OTG_DEV_CTL()		bfin_read16(USB_OTG_DEV_CTL)
-#define bfin_write_USB_OTG_DEV_CTL(val)		bfin_write16(USB_OTG_DEV_CTL, val)
-#define bfin_read_USB_OTG_VBUS_IRQ()		bfin_read16(USB_OTG_VBUS_IRQ)
-#define bfin_write_USB_OTG_VBUS_IRQ(val)	bfin_write16(USB_OTG_VBUS_IRQ, val)
-#define bfin_read_USB_OTG_VBUS_MASK()		bfin_read16(USB_OTG_VBUS_MASK)
-#define bfin_write_USB_OTG_VBUS_MASK(val)	bfin_write16(USB_OTG_VBUS_MASK, val)
-
-/* USB Phy Control Registers */
-
-#define bfin_read_USB_LINKINFO()	bfin_read16(USB_LINKINFO)
-#define bfin_write_USB_LINKINFO(val)	bfin_write16(USB_LINKINFO, val)
-#define bfin_read_USB_VPLEN()		bfin_read16(USB_VPLEN)
-#define bfin_write_USB_VPLEN(val)	bfin_write16(USB_VPLEN, val)
-#define bfin_read_USB_HS_EOF1()		bfin_read16(USB_HS_EOF1)
-#define bfin_write_USB_HS_EOF1(val)	bfin_write16(USB_HS_EOF1, val)
-#define bfin_read_USB_FS_EOF1()		bfin_read16(USB_FS_EOF1)
-#define bfin_write_USB_FS_EOF1(val)	bfin_write16(USB_FS_EOF1, val)
-#define bfin_read_USB_LS_EOF1()		bfin_read16(USB_LS_EOF1)
-#define bfin_write_USB_LS_EOF1(val)	bfin_write16(USB_LS_EOF1, val)
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CNTRL()		bfin_read16(USB_APHY_CNTRL)
-#define bfin_write_USB_APHY_CNTRL(val)		bfin_write16(USB_APHY_CNTRL, val)
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CALIB()		bfin_read16(USB_APHY_CALIB)
-#define bfin_write_USB_APHY_CALIB(val)		bfin_write16(USB_APHY_CALIB, val)
-#define bfin_read_USB_APHY_CNTRL2()		bfin_read16(USB_APHY_CNTRL2)
-#define bfin_write_USB_APHY_CNTRL2(val)		bfin_write16(USB_APHY_CNTRL2, val)
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define bfin_read_USB_PHY_TEST()		bfin_read16(USB_PHY_TEST)
-#define bfin_write_USB_PHY_TEST(val)		bfin_write16(USB_PHY_TEST, val)
-#define bfin_read_USB_PLLOSC_CTRL()		bfin_read16(USB_PLLOSC_CTRL)
-#define bfin_write_USB_PLLOSC_CTRL(val)		bfin_write16(USB_PLLOSC_CTRL, val)
-#define bfin_read_USB_SRP_CLKDIV()		bfin_read16(USB_SRP_CLKDIV)
-#define bfin_write_USB_SRP_CLKDIV(val)		bfin_write16(USB_SRP_CLKDIV, val)
-
-/* USB Endbfin_read_()oint 0 Control Registers */
-
-#define bfin_read_USB_EP_NI0_TXMAXP()		bfin_read16(USB_EP_NI0_TXMAXP)
-#define bfin_write_USB_EP_NI0_TXMAXP(val)	bfin_write16(USB_EP_NI0_TXMAXP, val)
-#define bfin_read_USB_EP_NI0_TXCSR()		bfin_read16(USB_EP_NI0_TXCSR)
-#define bfin_write_USB_EP_NI0_TXCSR(val)	bfin_write16(USB_EP_NI0_TXCSR, val)
-#define bfin_read_USB_EP_NI0_RXMAXP()		bfin_read16(USB_EP_NI0_RXMAXP)
-#define bfin_write_USB_EP_NI0_RXMAXP(val)	bfin_write16(USB_EP_NI0_RXMAXP, val)
-#define bfin_read_USB_EP_NI0_RXCSR()		bfin_read16(USB_EP_NI0_RXCSR)
-#define bfin_write_USB_EP_NI0_RXCSR(val)	bfin_write16(USB_EP_NI0_RXCSR, val)
-#define bfin_read_USB_EP_NI0_RXCOUNT()		bfin_read16(USB_EP_NI0_RXCOUNT)
-#define bfin_write_USB_EP_NI0_RXCOUNT(val)	bfin_write16(USB_EP_NI0_RXCOUNT, val)
-#define bfin_read_USB_EP_NI0_TXTYPE()		bfin_read16(USB_EP_NI0_TXTYPE)
-#define bfin_write_USB_EP_NI0_TXTYPE(val)	bfin_write16(USB_EP_NI0_TXTYPE, val)
-#define bfin_read_USB_EP_NI0_TXINTERVAL()	bfin_read16(USB_EP_NI0_TXINTERVAL)
-#define bfin_write_USB_EP_NI0_TXINTERVAL(val)	bfin_write16(USB_EP_NI0_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI0_RXTYPE()		bfin_read16(USB_EP_NI0_RXTYPE)
-#define bfin_write_USB_EP_NI0_RXTYPE(val)	bfin_write16(USB_EP_NI0_RXTYPE, val)
-#define bfin_read_USB_EP_NI0_RXINTERVAL()	bfin_read16(USB_EP_NI0_RXINTERVAL)
-#define bfin_write_USB_EP_NI0_RXINTERVAL(val)	bfin_write16(USB_EP_NI0_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 1 Control Registers */
-
-#define bfin_read_USB_EP_NI0_TXCOUNT()		bfin_read16(USB_EP_NI0_TXCOUNT)
-#define bfin_write_USB_EP_NI0_TXCOUNT(val)	bfin_write16(USB_EP_NI0_TXCOUNT, val)
-#define bfin_read_USB_EP_NI1_TXMAXP()		bfin_read16(USB_EP_NI1_TXMAXP)
-#define bfin_write_USB_EP_NI1_TXMAXP(val)	bfin_write16(USB_EP_NI1_TXMAXP, val)
-#define bfin_read_USB_EP_NI1_TXCSR()		bfin_read16(USB_EP_NI1_TXCSR)
-#define bfin_write_USB_EP_NI1_TXCSR(val)	bfin_write16(USB_EP_NI1_TXCSR, val)
-#define bfin_read_USB_EP_NI1_RXMAXP()		bfin_read16(USB_EP_NI1_RXMAXP)
-#define bfin_write_USB_EP_NI1_RXMAXP(val)	bfin_write16(USB_EP_NI1_RXMAXP, val)
-#define bfin_read_USB_EP_NI1_RXCSR()		bfin_read16(USB_EP_NI1_RXCSR)
-#define bfin_write_USB_EP_NI1_RXCSR(val)	bfin_write16(USB_EP_NI1_RXCSR, val)
-#define bfin_read_USB_EP_NI1_RXCOUNT()		bfin_read16(USB_EP_NI1_RXCOUNT)
-#define bfin_write_USB_EP_NI1_RXCOUNT(val)	bfin_write16(USB_EP_NI1_RXCOUNT, val)
-#define bfin_read_USB_EP_NI1_TXTYPE()		bfin_read16(USB_EP_NI1_TXTYPE)
-#define bfin_write_USB_EP_NI1_TXTYPE(val)	bfin_write16(USB_EP_NI1_TXTYPE, val)
-#define bfin_read_USB_EP_NI1_TXINTERVAL()	bfin_read16(USB_EP_NI1_TXINTERVAL)
-#define bfin_write_USB_EP_NI1_TXINTERVAL(val)	bfin_write16(USB_EP_NI1_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI1_RXTYPE()		bfin_read16(USB_EP_NI1_RXTYPE)
-#define bfin_write_USB_EP_NI1_RXTYPE(val)	bfin_write16(USB_EP_NI1_RXTYPE, val)
-#define bfin_read_USB_EP_NI1_RXINTERVAL()	bfin_read16(USB_EP_NI1_RXINTERVAL)
-#define bfin_write_USB_EP_NI1_RXINTERVAL(val)	bfin_write16(USB_EP_NI1_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 2 Control Registers */
-
-#define bfin_read_USB_EP_NI1_TXCOUNT()		bfin_read16(USB_EP_NI1_TXCOUNT)
-#define bfin_write_USB_EP_NI1_TXCOUNT(val)	bfin_write16(USB_EP_NI1_TXCOUNT, val)
-#define bfin_read_USB_EP_NI2_TXMAXP()		bfin_read16(USB_EP_NI2_TXMAXP)
-#define bfin_write_USB_EP_NI2_TXMAXP(val)	bfin_write16(USB_EP_NI2_TXMAXP, val)
-#define bfin_read_USB_EP_NI2_TXCSR()		bfin_read16(USB_EP_NI2_TXCSR)
-#define bfin_write_USB_EP_NI2_TXCSR(val)	bfin_write16(USB_EP_NI2_TXCSR, val)
-#define bfin_read_USB_EP_NI2_RXMAXP()		bfin_read16(USB_EP_NI2_RXMAXP)
-#define bfin_write_USB_EP_NI2_RXMAXP(val)	bfin_write16(USB_EP_NI2_RXMAXP, val)
-#define bfin_read_USB_EP_NI2_RXCSR()		bfin_read16(USB_EP_NI2_RXCSR)
-#define bfin_write_USB_EP_NI2_RXCSR(val)	bfin_write16(USB_EP_NI2_RXCSR, val)
-#define bfin_read_USB_EP_NI2_RXCOUNT()		bfin_read16(USB_EP_NI2_RXCOUNT)
-#define bfin_write_USB_EP_NI2_RXCOUNT(val)	bfin_write16(USB_EP_NI2_RXCOUNT, val)
-#define bfin_read_USB_EP_NI2_TXTYPE()		bfin_read16(USB_EP_NI2_TXTYPE)
-#define bfin_write_USB_EP_NI2_TXTYPE(val)	bfin_write16(USB_EP_NI2_TXTYPE, val)
-#define bfin_read_USB_EP_NI2_TXINTERVAL()	bfin_read16(USB_EP_NI2_TXINTERVAL)
-#define bfin_write_USB_EP_NI2_TXINTERVAL(val)	bfin_write16(USB_EP_NI2_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI2_RXTYPE()		bfin_read16(USB_EP_NI2_RXTYPE)
-#define bfin_write_USB_EP_NI2_RXTYPE(val)	bfin_write16(USB_EP_NI2_RXTYPE, val)
-#define bfin_read_USB_EP_NI2_RXINTERVAL()	bfin_read16(USB_EP_NI2_RXINTERVAL)
-#define bfin_write_USB_EP_NI2_RXINTERVAL(val)	bfin_write16(USB_EP_NI2_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 3 Control Registers */
-
-#define bfin_read_USB_EP_NI2_TXCOUNT()		bfin_read16(USB_EP_NI2_TXCOUNT)
-#define bfin_write_USB_EP_NI2_TXCOUNT(val)	bfin_write16(USB_EP_NI2_TXCOUNT, val)
-#define bfin_read_USB_EP_NI3_TXMAXP()		bfin_read16(USB_EP_NI3_TXMAXP)
-#define bfin_write_USB_EP_NI3_TXMAXP(val)	bfin_write16(USB_EP_NI3_TXMAXP, val)
-#define bfin_read_USB_EP_NI3_TXCSR()		bfin_read16(USB_EP_NI3_TXCSR)
-#define bfin_write_USB_EP_NI3_TXCSR(val)	bfin_write16(USB_EP_NI3_TXCSR, val)
-#define bfin_read_USB_EP_NI3_RXMAXP()		bfin_read16(USB_EP_NI3_RXMAXP)
-#define bfin_write_USB_EP_NI3_RXMAXP(val)	bfin_write16(USB_EP_NI3_RXMAXP, val)
-#define bfin_read_USB_EP_NI3_RXCSR()		bfin_read16(USB_EP_NI3_RXCSR)
-#define bfin_write_USB_EP_NI3_RXCSR(val)	bfin_write16(USB_EP_NI3_RXCSR, val)
-#define bfin_read_USB_EP_NI3_RXCOUNT()		bfin_read16(USB_EP_NI3_RXCOUNT)
-#define bfin_write_USB_EP_NI3_RXCOUNT(val)	bfin_write16(USB_EP_NI3_RXCOUNT, val)
-#define bfin_read_USB_EP_NI3_TXTYPE()		bfin_read16(USB_EP_NI3_TXTYPE)
-#define bfin_write_USB_EP_NI3_TXTYPE(val)	bfin_write16(USB_EP_NI3_TXTYPE, val)
-#define bfin_read_USB_EP_NI3_TXINTERVAL()	bfin_read16(USB_EP_NI3_TXINTERVAL)
-#define bfin_write_USB_EP_NI3_TXINTERVAL(val)	bfin_write16(USB_EP_NI3_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI3_RXTYPE()		bfin_read16(USB_EP_NI3_RXTYPE)
-#define bfin_write_USB_EP_NI3_RXTYPE(val)	bfin_write16(USB_EP_NI3_RXTYPE, val)
-#define bfin_read_USB_EP_NI3_RXINTERVAL()	bfin_read16(USB_EP_NI3_RXINTERVAL)
-#define bfin_write_USB_EP_NI3_RXINTERVAL(val)	bfin_write16(USB_EP_NI3_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 4 Control Registers */
-
-#define bfin_read_USB_EP_NI3_TXCOUNT()		bfin_read16(USB_EP_NI3_TXCOUNT)
-#define bfin_write_USB_EP_NI3_TXCOUNT(val)	bfin_write16(USB_EP_NI3_TXCOUNT, val)
-#define bfin_read_USB_EP_NI4_TXMAXP()		bfin_read16(USB_EP_NI4_TXMAXP)
-#define bfin_write_USB_EP_NI4_TXMAXP(val)	bfin_write16(USB_EP_NI4_TXMAXP, val)
-#define bfin_read_USB_EP_NI4_TXCSR()		bfin_read16(USB_EP_NI4_TXCSR)
-#define bfin_write_USB_EP_NI4_TXCSR(val)	bfin_write16(USB_EP_NI4_TXCSR, val)
-#define bfin_read_USB_EP_NI4_RXMAXP()		bfin_read16(USB_EP_NI4_RXMAXP)
-#define bfin_write_USB_EP_NI4_RXMAXP(val)	bfin_write16(USB_EP_NI4_RXMAXP, val)
-#define bfin_read_USB_EP_NI4_RXCSR()		bfin_read16(USB_EP_NI4_RXCSR)
-#define bfin_write_USB_EP_NI4_RXCSR(val)	bfin_write16(USB_EP_NI4_RXCSR, val)
-#define bfin_read_USB_EP_NI4_RXCOUNT()		bfin_read16(USB_EP_NI4_RXCOUNT)
-#define bfin_write_USB_EP_NI4_RXCOUNT(val)	bfin_write16(USB_EP_NI4_RXCOUNT, val)
-#define bfin_read_USB_EP_NI4_TXTYPE()		bfin_read16(USB_EP_NI4_TXTYPE)
-#define bfin_write_USB_EP_NI4_TXTYPE(val)	bfin_write16(USB_EP_NI4_TXTYPE, val)
-#define bfin_read_USB_EP_NI4_TXINTERVAL()	bfin_read16(USB_EP_NI4_TXINTERVAL)
-#define bfin_write_USB_EP_NI4_TXINTERVAL(val)	bfin_write16(USB_EP_NI4_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI4_RXTYPE()		bfin_read16(USB_EP_NI4_RXTYPE)
-#define bfin_write_USB_EP_NI4_RXTYPE(val)	bfin_write16(USB_EP_NI4_RXTYPE, val)
-#define bfin_read_USB_EP_NI4_RXINTERVAL()	bfin_read16(USB_EP_NI4_RXINTERVAL)
-#define bfin_write_USB_EP_NI4_RXINTERVAL(val)	bfin_write16(USB_EP_NI4_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 5 Control Registers */
-
-#define bfin_read_USB_EP_NI4_TXCOUNT()		bfin_read16(USB_EP_NI4_TXCOUNT)
-#define bfin_write_USB_EP_NI4_TXCOUNT(val)	bfin_write16(USB_EP_NI4_TXCOUNT, val)
-#define bfin_read_USB_EP_NI5_TXMAXP()		bfin_read16(USB_EP_NI5_TXMAXP)
-#define bfin_write_USB_EP_NI5_TXMAXP(val)	bfin_write16(USB_EP_NI5_TXMAXP, val)
-#define bfin_read_USB_EP_NI5_TXCSR()		bfin_read16(USB_EP_NI5_TXCSR)
-#define bfin_write_USB_EP_NI5_TXCSR(val)	bfin_write16(USB_EP_NI5_TXCSR, val)
-#define bfin_read_USB_EP_NI5_RXMAXP()		bfin_read16(USB_EP_NI5_RXMAXP)
-#define bfin_write_USB_EP_NI5_RXMAXP(val)	bfin_write16(USB_EP_NI5_RXMAXP, val)
-#define bfin_read_USB_EP_NI5_RXCSR()		bfin_read16(USB_EP_NI5_RXCSR)
-#define bfin_write_USB_EP_NI5_RXCSR(val)	bfin_write16(USB_EP_NI5_RXCSR, val)
-#define bfin_read_USB_EP_NI5_RXCOUNT()		bfin_read16(USB_EP_NI5_RXCOUNT)
-#define bfin_write_USB_EP_NI5_RXCOUNT(val)	bfin_write16(USB_EP_NI5_RXCOUNT, val)
-#define bfin_read_USB_EP_NI5_TXTYPE()		bfin_read16(USB_EP_NI5_TXTYPE)
-#define bfin_write_USB_EP_NI5_TXTYPE(val)	bfin_write16(USB_EP_NI5_TXTYPE, val)
-#define bfin_read_USB_EP_NI5_TXINTERVAL()	bfin_read16(USB_EP_NI5_TXINTERVAL)
-#define bfin_write_USB_EP_NI5_TXINTERVAL(val)	bfin_write16(USB_EP_NI5_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI5_RXTYPE()		bfin_read16(USB_EP_NI5_RXTYPE)
-#define bfin_write_USB_EP_NI5_RXTYPE(val)	bfin_write16(USB_EP_NI5_RXTYPE, val)
-#define bfin_read_USB_EP_NI5_RXINTERVAL()	bfin_read16(USB_EP_NI5_RXINTERVAL)
-#define bfin_write_USB_EP_NI5_RXINTERVAL(val)	bfin_write16(USB_EP_NI5_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 6 Control Registers */
-
-#define bfin_read_USB_EP_NI5_TXCOUNT()		bfin_read16(USB_EP_NI5_TXCOUNT)
-#define bfin_write_USB_EP_NI5_TXCOUNT(val)	bfin_write16(USB_EP_NI5_TXCOUNT, val)
-#define bfin_read_USB_EP_NI6_TXMAXP()		bfin_read16(USB_EP_NI6_TXMAXP)
-#define bfin_write_USB_EP_NI6_TXMAXP(val)	bfin_write16(USB_EP_NI6_TXMAXP, val)
-#define bfin_read_USB_EP_NI6_TXCSR()		bfin_read16(USB_EP_NI6_TXCSR)
-#define bfin_write_USB_EP_NI6_TXCSR(val)	bfin_write16(USB_EP_NI6_TXCSR, val)
-#define bfin_read_USB_EP_NI6_RXMAXP()		bfin_read16(USB_EP_NI6_RXMAXP)
-#define bfin_write_USB_EP_NI6_RXMAXP(val)	bfin_write16(USB_EP_NI6_RXMAXP, val)
-#define bfin_read_USB_EP_NI6_RXCSR()		bfin_read16(USB_EP_NI6_RXCSR)
-#define bfin_write_USB_EP_NI6_RXCSR(val)	bfin_write16(USB_EP_NI6_RXCSR, val)
-#define bfin_read_USB_EP_NI6_RXCOUNT()		bfin_read16(USB_EP_NI6_RXCOUNT)
-#define bfin_write_USB_EP_NI6_RXCOUNT(val)	bfin_write16(USB_EP_NI6_RXCOUNT, val)
-#define bfin_read_USB_EP_NI6_TXTYPE()		bfin_read16(USB_EP_NI6_TXTYPE)
-#define bfin_write_USB_EP_NI6_TXTYPE(val)	bfin_write16(USB_EP_NI6_TXTYPE, val)
-#define bfin_read_USB_EP_NI6_TXINTERVAL()	bfin_read16(USB_EP_NI6_TXINTERVAL)
-#define bfin_write_USB_EP_NI6_TXINTERVAL(val)	bfin_write16(USB_EP_NI6_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI6_RXTYPE()		bfin_read16(USB_EP_NI6_RXTYPE)
-#define bfin_write_USB_EP_NI6_RXTYPE(val)	bfin_write16(USB_EP_NI6_RXTYPE, val)
-#define bfin_read_USB_EP_NI6_RXINTERVAL()	bfin_read16(USB_EP_NI6_RXINTERVAL)
-#define bfin_write_USB_EP_NI6_RXINTERVAL(val)	bfin_write16(USB_EP_NI6_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 7 Control Registers */
-
-#define bfin_read_USB_EP_NI6_TXCOUNT()		bfin_read16(USB_EP_NI6_TXCOUNT)
-#define bfin_write_USB_EP_NI6_TXCOUNT(val)	bfin_write16(USB_EP_NI6_TXCOUNT, val)
-#define bfin_read_USB_EP_NI7_TXMAXP()		bfin_read16(USB_EP_NI7_TXMAXP)
-#define bfin_write_USB_EP_NI7_TXMAXP(val)	bfin_write16(USB_EP_NI7_TXMAXP, val)
-#define bfin_read_USB_EP_NI7_TXCSR()		bfin_read16(USB_EP_NI7_TXCSR)
-#define bfin_write_USB_EP_NI7_TXCSR(val)	bfin_write16(USB_EP_NI7_TXCSR, val)
-#define bfin_read_USB_EP_NI7_RXMAXP()		bfin_read16(USB_EP_NI7_RXMAXP)
-#define bfin_write_USB_EP_NI7_RXMAXP(val)	bfin_write16(USB_EP_NI7_RXMAXP, val)
-#define bfin_read_USB_EP_NI7_RXCSR()		bfin_read16(USB_EP_NI7_RXCSR)
-#define bfin_write_USB_EP_NI7_RXCSR(val)	bfin_write16(USB_EP_NI7_RXCSR, val)
-#define bfin_read_USB_EP_NI7_RXCOUNT()		bfin_read16(USB_EP_NI7_RXCOUNT)
-#define bfin_write_USB_EP_NI7_RXCOUNT(val)	bfin_write16(USB_EP_NI7_RXCOUNT, val)
-#define bfin_read_USB_EP_NI7_TXTYPE()		bfin_read16(USB_EP_NI7_TXTYPE)
-#define bfin_write_USB_EP_NI7_TXTYPE(val)	bfin_write16(USB_EP_NI7_TXTYPE, val)
-#define bfin_read_USB_EP_NI7_TXINTERVAL()	bfin_read16(USB_EP_NI7_TXINTERVAL)
-#define bfin_write_USB_EP_NI7_TXINTERVAL(val)	bfin_write16(USB_EP_NI7_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_RXTYPE()		bfin_read16(USB_EP_NI7_RXTYPE)
-#define bfin_write_USB_EP_NI7_RXTYPE(val)	bfin_write16(USB_EP_NI7_RXTYPE, val)
-#define bfin_read_USB_EP_NI7_RXINTERVAL()	bfin_read16(USB_EP_NI7_RXINTERVAL)
-#define bfin_write_USB_EP_NI7_RXINTERVAL(val)	bfin_write16(USB_EP_NI7_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_TXCOUNT()		bfin_read16(USB_EP_NI7_TXCOUNT)
-#define bfin_write_USB_EP_NI7_TXCOUNT(val)	bfin_write16(USB_EP_NI7_TXCOUNT, val)
-#define bfin_read_USB_DMA_INTERRUPT()		bfin_read16(USB_DMA_INTERRUPT)
-#define bfin_write_USB_DMA_INTERRUPT(val)	bfin_write16(USB_DMA_INTERRUPT, val)
-
-/* USB Channel 0 Config Registers */
-
-#define bfin_read_USB_DMA0CONTROL()		bfin_read16(USB_DMA0CONTROL)
-#define bfin_write_USB_DMA0CONTROL(val)		bfin_write16(USB_DMA0CONTROL, val)
-#define bfin_read_USB_DMA0ADDRLOW()		bfin_read16(USB_DMA0ADDRLOW)
-#define bfin_write_USB_DMA0ADDRLOW(val)		bfin_write16(USB_DMA0ADDRLOW, val)
-#define bfin_read_USB_DMA0ADDRHIGH()		bfin_read16(USB_DMA0ADDRHIGH)
-#define bfin_write_USB_DMA0ADDRHIGH(val)	bfin_write16(USB_DMA0ADDRHIGH, val)
-#define bfin_read_USB_DMA0COUNTLOW()		bfin_read16(USB_DMA0COUNTLOW)
-#define bfin_write_USB_DMA0COUNTLOW(val)	bfin_write16(USB_DMA0COUNTLOW, val)
-#define bfin_read_USB_DMA0COUNTHIGH()		bfin_read16(USB_DMA0COUNTHIGH)
-#define bfin_write_USB_DMA0COUNTHIGH(val)	bfin_write16(USB_DMA0COUNTHIGH, val)
-
-/* USB Channel 1 Config Registers */
-
-#define bfin_read_USB_DMA1CONTROL()		bfin_read16(USB_DMA1CONTROL)
-#define bfin_write_USB_DMA1CONTROL(val)		bfin_write16(USB_DMA1CONTROL, val)
-#define bfin_read_USB_DMA1ADDRLOW()		bfin_read16(USB_DMA1ADDRLOW)
-#define bfin_write_USB_DMA1ADDRLOW(val)		bfin_write16(USB_DMA1ADDRLOW, val)
-#define bfin_read_USB_DMA1ADDRHIGH()		bfin_read16(USB_DMA1ADDRHIGH)
-#define bfin_write_USB_DMA1ADDRHIGH(val)	bfin_write16(USB_DMA1ADDRHIGH, val)
-#define bfin_read_USB_DMA1COUNTLOW()		bfin_read16(USB_DMA1COUNTLOW)
-#define bfin_write_USB_DMA1COUNTLOW(val)	bfin_write16(USB_DMA1COUNTLOW, val)
-#define bfin_read_USB_DMA1COUNTHIGH()		bfin_read16(USB_DMA1COUNTHIGH)
-#define bfin_write_USB_DMA1COUNTHIGH(val)	bfin_write16(USB_DMA1COUNTHIGH, val)
-
-/* USB Channel 2 Config Registers */
-
-#define bfin_read_USB_DMA2CONTROL()		bfin_read16(USB_DMA2CONTROL)
-#define bfin_write_USB_DMA2CONTROL(val)		bfin_write16(USB_DMA2CONTROL, val)
-#define bfin_read_USB_DMA2ADDRLOW()		bfin_read16(USB_DMA2ADDRLOW)
-#define bfin_write_USB_DMA2ADDRLOW(val)		bfin_write16(USB_DMA2ADDRLOW, val)
-#define bfin_read_USB_DMA2ADDRHIGH()		bfin_read16(USB_DMA2ADDRHIGH)
-#define bfin_write_USB_DMA2ADDRHIGH(val)	bfin_write16(USB_DMA2ADDRHIGH, val)
-#define bfin_read_USB_DMA2COUNTLOW()		bfin_read16(USB_DMA2COUNTLOW)
-#define bfin_write_USB_DMA2COUNTLOW(val)	bfin_write16(USB_DMA2COUNTLOW, val)
-#define bfin_read_USB_DMA2COUNTHIGH()		bfin_read16(USB_DMA2COUNTHIGH)
-#define bfin_write_USB_DMA2COUNTHIGH(val)	bfin_write16(USB_DMA2COUNTHIGH, val)
-
-/* USB Channel 3 Config Registers */
-
-#define bfin_read_USB_DMA3CONTROL()		bfin_read16(USB_DMA3CONTROL)
-#define bfin_write_USB_DMA3CONTROL(val)		bfin_write16(USB_DMA3CONTROL, val)
-#define bfin_read_USB_DMA3ADDRLOW()		bfin_read16(USB_DMA3ADDRLOW)
-#define bfin_write_USB_DMA3ADDRLOW(val)		bfin_write16(USB_DMA3ADDRLOW, val)
-#define bfin_read_USB_DMA3ADDRHIGH()		bfin_read16(USB_DMA3ADDRHIGH)
-#define bfin_write_USB_DMA3ADDRHIGH(val)	bfin_write16(USB_DMA3ADDRHIGH, val)
-#define bfin_read_USB_DMA3COUNTLOW()		bfin_read16(USB_DMA3COUNTLOW)
-#define bfin_write_USB_DMA3COUNTLOW(val)	bfin_write16(USB_DMA3COUNTLOW, val)
-#define bfin_read_USB_DMA3COUNTHIGH()		bfin_read16(USB_DMA3COUNTHIGH)
-#define bfin_write_USB_DMA3COUNTHIGH(val)	bfin_write16(USB_DMA3COUNTHIGH, val)
-
-/* USB Channel 4 Config Registers */
-
-#define bfin_read_USB_DMA4CONTROL()		bfin_read16(USB_DMA4CONTROL)
-#define bfin_write_USB_DMA4CONTROL(val)		bfin_write16(USB_DMA4CONTROL, val)
-#define bfin_read_USB_DMA4ADDRLOW()		bfin_read16(USB_DMA4ADDRLOW)
-#define bfin_write_USB_DMA4ADDRLOW(val)		bfin_write16(USB_DMA4ADDRLOW, val)
-#define bfin_read_USB_DMA4ADDRHIGH()		bfin_read16(USB_DMA4ADDRHIGH)
-#define bfin_write_USB_DMA4ADDRHIGH(val)	bfin_write16(USB_DMA4ADDRHIGH, val)
-#define bfin_read_USB_DMA4COUNTLOW()		bfin_read16(USB_DMA4COUNTLOW)
-#define bfin_write_USB_DMA4COUNTLOW(val)	bfin_write16(USB_DMA4COUNTLOW, val)
-#define bfin_read_USB_DMA4COUNTHIGH()		bfin_read16(USB_DMA4COUNTHIGH)
-#define bfin_write_USB_DMA4COUNTHIGH(val)	bfin_write16(USB_DMA4COUNTHIGH, val)
-
-/* USB Channel 5 Config Registers */
-
-#define bfin_read_USB_DMA5CONTROL()		bfin_read16(USB_DMA5CONTROL)
-#define bfin_write_USB_DMA5CONTROL(val)		bfin_write16(USB_DMA5CONTROL, val)
-#define bfin_read_USB_DMA5ADDRLOW()		bfin_read16(USB_DMA5ADDRLOW)
-#define bfin_write_USB_DMA5ADDRLOW(val)		bfin_write16(USB_DMA5ADDRLOW, val)
-#define bfin_read_USB_DMA5ADDRHIGH()		bfin_read16(USB_DMA5ADDRHIGH)
-#define bfin_write_USB_DMA5ADDRHIGH(val)	bfin_write16(USB_DMA5ADDRHIGH, val)
-#define bfin_read_USB_DMA5COUNTLOW()		bfin_read16(USB_DMA5COUNTLOW)
-#define bfin_write_USB_DMA5COUNTLOW(val)	bfin_write16(USB_DMA5COUNTLOW, val)
-#define bfin_read_USB_DMA5COUNTHIGH()		bfin_read16(USB_DMA5COUNTHIGH)
-#define bfin_write_USB_DMA5COUNTHIGH(val)	bfin_write16(USB_DMA5COUNTHIGH, val)
-
-/* USB Channel 6 Config Registers */
-
-#define bfin_read_USB_DMA6CONTROL()		bfin_read16(USB_DMA6CONTROL)
-#define bfin_write_USB_DMA6CONTROL(val)		bfin_write16(USB_DMA6CONTROL, val)
-#define bfin_read_USB_DMA6ADDRLOW()		bfin_read16(USB_DMA6ADDRLOW)
-#define bfin_write_USB_DMA6ADDRLOW(val)		bfin_write16(USB_DMA6ADDRLOW, val)
-#define bfin_read_USB_DMA6ADDRHIGH()		bfin_read16(USB_DMA6ADDRHIGH)
-#define bfin_write_USB_DMA6ADDRHIGH(val)	bfin_write16(USB_DMA6ADDRHIGH, val)
-#define bfin_read_USB_DMA6COUNTLOW()		bfin_read16(USB_DMA6COUNTLOW)
-#define bfin_write_USB_DMA6COUNTLOW(val)	bfin_write16(USB_DMA6COUNTLOW, val)
-#define bfin_read_USB_DMA6COUNTHIGH()		bfin_read16(USB_DMA6COUNTHIGH)
-#define bfin_write_USB_DMA6COUNTHIGH(val)	bfin_write16(USB_DMA6COUNTHIGH, val)
-
-/* USB Channel 7 Config Registers */
-
-#define bfin_read_USB_DMA7CONTROL()		bfin_read16(USB_DMA7CONTROL)
-#define bfin_write_USB_DMA7CONTROL(val)		bfin_write16(USB_DMA7CONTROL, val)
-#define bfin_read_USB_DMA7ADDRLOW()		bfin_read16(USB_DMA7ADDRLOW)
-#define bfin_write_USB_DMA7ADDRLOW(val)		bfin_write16(USB_DMA7ADDRLOW, val)
-#define bfin_read_USB_DMA7ADDRHIGH()		bfin_read16(USB_DMA7ADDRHIGH)
-#define bfin_write_USB_DMA7ADDRHIGH(val)	bfin_write16(USB_DMA7ADDRHIGH, val)
-#define bfin_read_USB_DMA7COUNTLOW()		bfin_read16(USB_DMA7COUNTLOW)
-#define bfin_write_USB_DMA7COUNTLOW(val)	bfin_write16(USB_DMA7COUNTLOW, val)
-#define bfin_read_USB_DMA7COUNTHIGH()		bfin_read16(USB_DMA7COUNTHIGH)
-#define bfin_write_USB_DMA7COUNTHIGH(val)	bfin_write16(USB_DMA7COUNTHIGH, val)
-
-/* Keybfin_read_()ad Registers */
-
-#define bfin_read_KPAD_CTL()		bfin_read16(KPAD_CTL)
-#define bfin_write_KPAD_CTL(val)	bfin_write16(KPAD_CTL, val)
-#define bfin_read_KPAD_PRESCALE()	bfin_read16(KPAD_PRESCALE)
-#define bfin_write_KPAD_PRESCALE(val)	bfin_write16(KPAD_PRESCALE, val)
-#define bfin_read_KPAD_MSEL()		bfin_read16(KPAD_MSEL)
-#define bfin_write_KPAD_MSEL(val)	bfin_write16(KPAD_MSEL, val)
-#define bfin_read_KPAD_ROWCOL()		bfin_read16(KPAD_ROWCOL)
-#define bfin_write_KPAD_ROWCOL(val)	bfin_write16(KPAD_ROWCOL, val)
-#define bfin_read_KPAD_STAT()		bfin_read16(KPAD_STAT)
-#define bfin_write_KPAD_STAT(val)	bfin_write16(KPAD_STAT, val)
-#define bfin_read_KPAD_SOFTEVAL()	bfin_read16(KPAD_SOFTEVAL)
-#define bfin_write_KPAD_SOFTEVAL(val)	bfin_write16(KPAD_SOFTEVAL, val)
-
-/* Pixel Combfin_read_()ositor (PIXC) Registers */
-
-#define bfin_read_PIXC_CTL()		bfin_read16(PIXC_CTL)
-#define bfin_write_PIXC_CTL(val)	bfin_write16(PIXC_CTL, val)
-#define bfin_read_PIXC_PPL()		bfin_read16(PIXC_PPL)
-#define bfin_write_PIXC_PPL(val)	bfin_write16(PIXC_PPL, val)
-#define bfin_read_PIXC_LPF()		bfin_read16(PIXC_LPF)
-#define bfin_write_PIXC_LPF(val)	bfin_write16(PIXC_LPF, val)
-#define bfin_read_PIXC_AHSTART()	bfin_read16(PIXC_AHSTART)
-#define bfin_write_PIXC_AHSTART(val)	bfin_write16(PIXC_AHSTART, val)
-#define bfin_read_PIXC_AHEND()		bfin_read16(PIXC_AHEND)
-#define bfin_write_PIXC_AHEND(val)	bfin_write16(PIXC_AHEND, val)
-#define bfin_read_PIXC_AVSTART()	bfin_read16(PIXC_AVSTART)
-#define bfin_write_PIXC_AVSTART(val)	bfin_write16(PIXC_AVSTART, val)
-#define bfin_read_PIXC_AVEND()		bfin_read16(PIXC_AVEND)
-#define bfin_write_PIXC_AVEND(val)	bfin_write16(PIXC_AVEND, val)
-#define bfin_read_PIXC_ATRANSP()	bfin_read16(PIXC_ATRANSP)
-#define bfin_write_PIXC_ATRANSP(val)	bfin_write16(PIXC_ATRANSP, val)
-#define bfin_read_PIXC_BHSTART()	bfin_read16(PIXC_BHSTART)
-#define bfin_write_PIXC_BHSTART(val)	bfin_write16(PIXC_BHSTART, val)
-#define bfin_read_PIXC_BHEND()		bfin_read16(PIXC_BHEND)
-#define bfin_write_PIXC_BHEND(val)	bfin_write16(PIXC_BHEND, val)
-#define bfin_read_PIXC_BVSTART()	bfin_read16(PIXC_BVSTART)
-#define bfin_write_PIXC_BVSTART(val)	bfin_write16(PIXC_BVSTART, val)
-#define bfin_read_PIXC_BVEND()		bfin_read16(PIXC_BVEND)
-#define bfin_write_PIXC_BVEND(val)	bfin_write16(PIXC_BVEND, val)
-#define bfin_read_PIXC_BTRANSP()	bfin_read16(PIXC_BTRANSP)
-#define bfin_write_PIXC_BTRANSP(val)	bfin_write16(PIXC_BTRANSP, val)
-#define bfin_read_PIXC_INTRSTAT()	bfin_read16(PIXC_INTRSTAT)
-#define bfin_write_PIXC_INTRSTAT(val)	bfin_write16(PIXC_INTRSTAT, val)
-#define bfin_read_PIXC_RYCON()		bfin_read32(PIXC_RYCON)
-#define bfin_write_PIXC_RYCON(val)	bfin_write32(PIXC_RYCON, val)
-#define bfin_read_PIXC_GUCON()		bfin_read32(PIXC_GUCON)
-#define bfin_write_PIXC_GUCON(val)	bfin_write32(PIXC_GUCON, val)
-#define bfin_read_PIXC_BVCON()		bfin_read32(PIXC_BVCON)
-#define bfin_write_PIXC_BVCON(val)	bfin_write32(PIXC_BVCON, val)
-#define bfin_read_PIXC_CCBIAS()		bfin_read32(PIXC_CCBIAS)
-#define bfin_write_PIXC_CCBIAS(val)	bfin_write32(PIXC_CCBIAS, val)
-#define bfin_read_PIXC_TC()		bfin_read32(PIXC_TC)
-#define bfin_write_PIXC_TC(val)		bfin_write32(PIXC_TC, val)
-
-/* Handshake MDMA 0 Registers */
-
-#define bfin_read_HMDMA0_CONTROL()		bfin_read16(HMDMA0_CONTROL)
-#define bfin_write_HMDMA0_CONTROL(val)		bfin_write16(HMDMA0_CONTROL, val)
-#define bfin_read_HMDMA0_ECINIT()		bfin_read16(HMDMA0_ECINIT)
-#define bfin_write_HMDMA0_ECINIT(val)		bfin_write16(HMDMA0_ECINIT, val)
-#define bfin_read_HMDMA0_BCINIT()		bfin_read16(HMDMA0_BCINIT)
-#define bfin_write_HMDMA0_BCINIT(val)		bfin_write16(HMDMA0_BCINIT, val)
-#define bfin_read_HMDMA0_ECURGENT()		bfin_read16(HMDMA0_ECURGENT)
-#define bfin_write_HMDMA0_ECURGENT(val)		bfin_write16(HMDMA0_ECURGENT, val)
-#define bfin_read_HMDMA0_ECOVERFLOW()		bfin_read16(HMDMA0_ECOVERFLOW)
-#define bfin_write_HMDMA0_ECOVERFLOW(val)	bfin_write16(HMDMA0_ECOVERFLOW, val)
-#define bfin_read_HMDMA0_ECOUNT()		bfin_read16(HMDMA0_ECOUNT)
-#define bfin_write_HMDMA0_ECOUNT(val)		bfin_write16(HMDMA0_ECOUNT, val)
-#define bfin_read_HMDMA0_BCOUNT()		bfin_read16(HMDMA0_BCOUNT)
-#define bfin_write_HMDMA0_BCOUNT(val)		bfin_write16(HMDMA0_BCOUNT, val)
-
-/* Handshake MDMA 1 Registers */
-
-#define bfin_read_HMDMA1_CONTROL()		bfin_read16(HMDMA1_CONTROL)
-#define bfin_write_HMDMA1_CONTROL(val)		bfin_write16(HMDMA1_CONTROL, val)
-#define bfin_read_HMDMA1_ECINIT()		bfin_read16(HMDMA1_ECINIT)
-#define bfin_write_HMDMA1_ECINIT(val)		bfin_write16(HMDMA1_ECINIT, val)
-#define bfin_read_HMDMA1_BCINIT()		bfin_read16(HMDMA1_BCINIT)
-#define bfin_write_HMDMA1_BCINIT(val)		bfin_write16(HMDMA1_BCINIT, val)
-#define bfin_read_HMDMA1_ECURGENT()		bfin_read16(HMDMA1_ECURGENT)
-#define bfin_write_HMDMA1_ECURGENT(val)		bfin_write16(HMDMA1_ECURGENT, val)
-#define bfin_read_HMDMA1_ECOVERFLOW()		bfin_read16(HMDMA1_ECOVERFLOW)
-#define bfin_write_HMDMA1_ECOVERFLOW(val)	bfin_write16(HMDMA1_ECOVERFLOW, val)
-#define bfin_read_HMDMA1_ECOUNT()		bfin_read16(HMDMA1_ECOUNT)
-#define bfin_write_HMDMA1_ECOUNT(val)		bfin_write16(HMDMA1_ECOUNT, val)
-#define bfin_read_HMDMA1_BCOUNT()		bfin_read16(HMDMA1_BCOUNT)
-#define bfin_write_HMDMA1_BCOUNT(val)		bfin_write16(HMDMA1_BCOUNT, val)
-
 #endif /* _CDEF_BF548_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF549.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF549.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF549.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,165 +18,8 @@
 /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */
 #include "cdefBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF549 that are not in the common header */
-
-/* Timer Registers */
-
-#define bfin_read_TIMER8_CONFIG()		bfin_read16(TIMER8_CONFIG)
-#define bfin_write_TIMER8_CONFIG(val)		bfin_write16(TIMER8_CONFIG, val)
-#define bfin_read_TIMER8_COUNTER()		bfin_read32(TIMER8_COUNTER)
-#define bfin_write_TIMER8_COUNTER(val)		bfin_write32(TIMER8_COUNTER, val)
-#define bfin_read_TIMER8_PERIOD()		bfin_read32(TIMER8_PERIOD)
-#define bfin_write_TIMER8_PERIOD(val)		bfin_write32(TIMER8_PERIOD, val)
-#define bfin_read_TIMER8_WIDTH()		bfin_read32(TIMER8_WIDTH)
-#define bfin_write_TIMER8_WIDTH(val)		bfin_write32(TIMER8_WIDTH, val)
-#define bfin_read_TIMER9_CONFIG()		bfin_read16(TIMER9_CONFIG)
-#define bfin_write_TIMER9_CONFIG(val)		bfin_write16(TIMER9_CONFIG, val)
-#define bfin_read_TIMER9_COUNTER()		bfin_read32(TIMER9_COUNTER)
-#define bfin_write_TIMER9_COUNTER(val)		bfin_write32(TIMER9_COUNTER, val)
-#define bfin_read_TIMER9_PERIOD()		bfin_read32(TIMER9_PERIOD)
-#define bfin_write_TIMER9_PERIOD(val)		bfin_write32(TIMER9_PERIOD, val)
-#define bfin_read_TIMER9_WIDTH()		bfin_read32(TIMER9_WIDTH)
-#define bfin_write_TIMER9_WIDTH(val)		bfin_write32(TIMER9_WIDTH, val)
-#define bfin_read_TIMER10_CONFIG()		bfin_read16(TIMER10_CONFIG)
-#define bfin_write_TIMER10_CONFIG(val)		bfin_write16(TIMER10_CONFIG, val)
-#define bfin_read_TIMER10_COUNTER()		bfin_read32(TIMER10_COUNTER)
-#define bfin_write_TIMER10_COUNTER(val)		bfin_write32(TIMER10_COUNTER, val)
-#define bfin_read_TIMER10_PERIOD()		bfin_read32(TIMER10_PERIOD)
-#define bfin_write_TIMER10_PERIOD(val)		bfin_write32(TIMER10_PERIOD, val)
-#define bfin_read_TIMER10_WIDTH()		bfin_read32(TIMER10_WIDTH)
-#define bfin_write_TIMER10_WIDTH(val)		bfin_write32(TIMER10_WIDTH, val)
-
-/* Timer Groubfin_read_() of 3 */
-
-#define bfin_read_TIMER_ENABLE1()		bfin_read16(TIMER_ENABLE1)
-#define bfin_write_TIMER_ENABLE1(val)		bfin_write16(TIMER_ENABLE1, val)
-#define bfin_read_TIMER_DISABLE1()		bfin_read16(TIMER_DISABLE1)
-#define bfin_write_TIMER_DISABLE1(val)		bfin_write16(TIMER_DISABLE1, val)
-#define bfin_read_TIMER_STATUS1()		bfin_read32(TIMER_STATUS1)
-#define bfin_write_TIMER_STATUS1(val)		bfin_write32(TIMER_STATUS1, val)
-
-/* SPORT0 Registers */
-
-#define bfin_read_SPORT0_TCR1()			bfin_read16(SPORT0_TCR1)
-#define bfin_write_SPORT0_TCR1(val)		bfin_write16(SPORT0_TCR1, val)
-#define bfin_read_SPORT0_TCR2()			bfin_read16(SPORT0_TCR2)
-#define bfin_write_SPORT0_TCR2(val)		bfin_write16(SPORT0_TCR2, val)
-#define bfin_read_SPORT0_TCLKDIV()		bfin_read16(SPORT0_TCLKDIV)
-#define bfin_write_SPORT0_TCLKDIV(val)		bfin_write16(SPORT0_TCLKDIV, val)
-#define bfin_read_SPORT0_TFSDIV()		bfin_read16(SPORT0_TFSDIV)
-#define bfin_write_SPORT0_TFSDIV(val)		bfin_write16(SPORT0_TFSDIV, val)
-#define bfin_read_SPORT0_TX()			bfin_read32(SPORT0_TX)
-#define bfin_write_SPORT0_TX(val)		bfin_write32(SPORT0_TX, val)
-#define bfin_read_SPORT0_RX()			bfin_read32(SPORT0_RX)
-#define bfin_write_SPORT0_RX(val)		bfin_write32(SPORT0_RX, val)
-#define bfin_read_SPORT0_RCR1()			bfin_read16(SPORT0_RCR1)
-#define bfin_write_SPORT0_RCR1(val)		bfin_write16(SPORT0_RCR1, val)
-#define bfin_read_SPORT0_RCR2()			bfin_read16(SPORT0_RCR2)
-#define bfin_write_SPORT0_RCR2(val)		bfin_write16(SPORT0_RCR2, val)
-#define bfin_read_SPORT0_RCLKDIV()		bfin_read16(SPORT0_RCLKDIV)
-#define bfin_write_SPORT0_RCLKDIV(val)		bfin_write16(SPORT0_RCLKDIV, val)
-#define bfin_read_SPORT0_RFSDIV()		bfin_read16(SPORT0_RFSDIV)
-#define bfin_write_SPORT0_RFSDIV(val)		bfin_write16(SPORT0_RFSDIV, val)
-#define bfin_read_SPORT0_STAT()			bfin_read16(SPORT0_STAT)
-#define bfin_write_SPORT0_STAT(val)		bfin_write16(SPORT0_STAT, val)
-#define bfin_read_SPORT0_CHNL()			bfin_read16(SPORT0_CHNL)
-#define bfin_write_SPORT0_CHNL(val)		bfin_write16(SPORT0_CHNL, val)
-#define bfin_read_SPORT0_MCMC1()		bfin_read16(SPORT0_MCMC1)
-#define bfin_write_SPORT0_MCMC1(val)		bfin_write16(SPORT0_MCMC1, val)
-#define bfin_read_SPORT0_MCMC2()		bfin_read16(SPORT0_MCMC2)
-#define bfin_write_SPORT0_MCMC2(val)		bfin_write16(SPORT0_MCMC2, val)
-#define bfin_read_SPORT0_MTCS0()		bfin_read32(SPORT0_MTCS0)
-#define bfin_write_SPORT0_MTCS0(val)		bfin_write32(SPORT0_MTCS0, val)
-#define bfin_read_SPORT0_MTCS1()		bfin_read32(SPORT0_MTCS1)
-#define bfin_write_SPORT0_MTCS1(val)		bfin_write32(SPORT0_MTCS1, val)
-#define bfin_read_SPORT0_MTCS2()		bfin_read32(SPORT0_MTCS2)
-#define bfin_write_SPORT0_MTCS2(val)		bfin_write32(SPORT0_MTCS2, val)
-#define bfin_read_SPORT0_MTCS3()		bfin_read32(SPORT0_MTCS3)
-#define bfin_write_SPORT0_MTCS3(val)		bfin_write32(SPORT0_MTCS3, val)
-#define bfin_read_SPORT0_MRCS0()		bfin_read32(SPORT0_MRCS0)
-#define bfin_write_SPORT0_MRCS0(val)		bfin_write32(SPORT0_MRCS0, val)
-#define bfin_read_SPORT0_MRCS1()		bfin_read32(SPORT0_MRCS1)
-#define bfin_write_SPORT0_MRCS1(val)		bfin_write32(SPORT0_MRCS1, val)
-#define bfin_read_SPORT0_MRCS2()		bfin_read32(SPORT0_MRCS2)
-#define bfin_write_SPORT0_MRCS2(val)		bfin_write32(SPORT0_MRCS2, val)
-#define bfin_read_SPORT0_MRCS3()		bfin_read32(SPORT0_MRCS3)
-#define bfin_write_SPORT0_MRCS3(val)		bfin_write32(SPORT0_MRCS3, val)
-
-/* EPPI0 Registers */
-
-#define bfin_read_EPPI0_STATUS()		bfin_read16(EPPI0_STATUS)
-#define bfin_write_EPPI0_STATUS(val)		bfin_write16(EPPI0_STATUS, val)
-#define bfin_read_EPPI0_HCOUNT()		bfin_read16(EPPI0_HCOUNT)
-#define bfin_write_EPPI0_HCOUNT(val)		bfin_write16(EPPI0_HCOUNT, val)
-#define bfin_read_EPPI0_HDELAY()		bfin_read16(EPPI0_HDELAY)
-#define bfin_write_EPPI0_HDELAY(val)		bfin_write16(EPPI0_HDELAY, val)
-#define bfin_read_EPPI0_VCOUNT()		bfin_read16(EPPI0_VCOUNT)
-#define bfin_write_EPPI0_VCOUNT(val)		bfin_write16(EPPI0_VCOUNT, val)
-#define bfin_read_EPPI0_VDELAY()		bfin_read16(EPPI0_VDELAY)
-#define bfin_write_EPPI0_VDELAY(val)		bfin_write16(EPPI0_VDELAY, val)
-#define bfin_read_EPPI0_FRAME()			bfin_read16(EPPI0_FRAME)
-#define bfin_write_EPPI0_FRAME(val)		bfin_write16(EPPI0_FRAME, val)
-#define bfin_read_EPPI0_LINE()			bfin_read16(EPPI0_LINE)
-#define bfin_write_EPPI0_LINE(val)		bfin_write16(EPPI0_LINE, val)
-#define bfin_read_EPPI0_CLKDIV()		bfin_read16(EPPI0_CLKDIV)
-#define bfin_write_EPPI0_CLKDIV(val)		bfin_write16(EPPI0_CLKDIV, val)
-#define bfin_read_EPPI0_CONTROL()		bfin_read32(EPPI0_CONTROL)
-#define bfin_write_EPPI0_CONTROL(val)		bfin_write32(EPPI0_CONTROL, val)
-#define bfin_read_EPPI0_FS1W_HBL()		bfin_read32(EPPI0_FS1W_HBL)
-#define bfin_write_EPPI0_FS1W_HBL(val)		bfin_write32(EPPI0_FS1W_HBL, val)
-#define bfin_read_EPPI0_FS1P_AVPL()		bfin_read32(EPPI0_FS1P_AVPL)
-#define bfin_write_EPPI0_FS1P_AVPL(val)		bfin_write32(EPPI0_FS1P_AVPL, val)
-#define bfin_read_EPPI0_FS2W_LVB()		bfin_read32(EPPI0_FS2W_LVB)
-#define bfin_write_EPPI0_FS2W_LVB(val)		bfin_write32(EPPI0_FS2W_LVB, val)
-#define bfin_read_EPPI0_FS2P_LAVF()		bfin_read32(EPPI0_FS2P_LAVF)
-#define bfin_write_EPPI0_FS2P_LAVF(val)		bfin_write32(EPPI0_FS2P_LAVF, val)
-#define bfin_read_EPPI0_CLIP()			bfin_read32(EPPI0_CLIP)
-#define bfin_write_EPPI0_CLIP(val)		bfin_write32(EPPI0_CLIP, val)
-
-/* UART2 Registers */
-
-#define bfin_read_UART2_DLL()			bfin_read16(UART2_DLL)
-#define bfin_write_UART2_DLL(val)		bfin_write16(UART2_DLL, val)
-#define bfin_read_UART2_DLH()			bfin_read16(UART2_DLH)
-#define bfin_write_UART2_DLH(val)		bfin_write16(UART2_DLH, val)
-#define bfin_read_UART2_GCTL()			bfin_read16(UART2_GCTL)
-#define bfin_write_UART2_GCTL(val)		bfin_write16(UART2_GCTL, val)
-#define bfin_read_UART2_LCR()			bfin_read16(UART2_LCR)
-#define bfin_write_UART2_LCR(val)		bfin_write16(UART2_LCR, val)
-#define bfin_read_UART2_MCR()			bfin_read16(UART2_MCR)
-#define bfin_write_UART2_MCR(val)		bfin_write16(UART2_MCR, val)
-#define bfin_read_UART2_LSR()			bfin_read16(UART2_LSR)
-#define bfin_write_UART2_LSR(val)		bfin_write16(UART2_LSR, val)
-#define bfin_read_UART2_MSR()			bfin_read16(UART2_MSR)
-#define bfin_write_UART2_MSR(val)		bfin_write16(UART2_MSR, val)
-#define bfin_read_UART2_SCR()			bfin_read16(UART2_SCR)
-#define bfin_write_UART2_SCR(val)		bfin_write16(UART2_SCR, val)
-#define bfin_read_UART2_IER_SET()		bfin_read16(UART2_IER_SET)
-#define bfin_write_UART2_IER_SET(val)		bfin_write16(UART2_IER_SET, val)
-#define bfin_read_UART2_IER_CLEAR()		bfin_read16(UART2_IER_CLEAR)
-#define bfin_write_UART2_IER_CLEAR(val)		bfin_write16(UART2_IER_CLEAR, val)
-#define bfin_read_UART2_RBR()			bfin_read16(UART2_RBR)
-#define bfin_write_UART2_RBR(val)		bfin_write16(UART2_RBR, val)
-
-/* Two Wire Interface Registers (TWI1) */
-
-/* SPI2 Registers */
-
-#define bfin_read_SPI2_CTL()		bfin_read16(SPI2_CTL)
-#define bfin_write_SPI2_CTL(val)	bfin_write16(SPI2_CTL, val)
-#define bfin_read_SPI2_FLG()		bfin_read16(SPI2_FLG)
-#define bfin_write_SPI2_FLG(val)	bfin_write16(SPI2_FLG, val)
-#define bfin_read_SPI2_STAT()		bfin_read16(SPI2_STAT)
-#define bfin_write_SPI2_STAT(val)	bfin_write16(SPI2_STAT, val)
-#define bfin_read_SPI2_TDBR()		bfin_read16(SPI2_TDBR)
-#define bfin_write_SPI2_TDBR(val)	bfin_write16(SPI2_TDBR, val)
-#define bfin_read_SPI2_RDBR()		bfin_read16(SPI2_RDBR)
-#define bfin_write_SPI2_RDBR(val)	bfin_write16(SPI2_RDBR, val)
-#define bfin_read_SPI2_BAUD()		bfin_read16(SPI2_BAUD)
-#define bfin_write_SPI2_BAUD(val)	bfin_write16(SPI2_BAUD, val)
-#define bfin_read_SPI2_SHADOW()		bfin_read16(SPI2_SHADOW)
-#define bfin_write_SPI2_SHADOW(val)	bfin_write16(SPI2_SHADOW, val)
+/* The BF549 is like the BF544, but has MXVR */
+#include "cdefBF547.h"
 
 /* MXVR Registers */
 
@@ -464,1376 +307,4 @@
 #define bfin_read_MXVR_SCLK_CNT()		bfin_read16(MXVR_SCLK_CNT)
 #define bfin_write_MXVR_SCLK_CNT(val)		bfin_write16(MXVR_SCLK_CNT, val)
 
-/* CAN Controller 1 Config 1 Registers */
-
-#define bfin_read_CAN1_MC1()		bfin_read16(CAN1_MC1)
-#define bfin_write_CAN1_MC1(val)	bfin_write16(CAN1_MC1, val)
-#define bfin_read_CAN1_MD1()		bfin_read16(CAN1_MD1)
-#define bfin_write_CAN1_MD1(val)	bfin_write16(CAN1_MD1, val)
-#define bfin_read_CAN1_TRS1()		bfin_read16(CAN1_TRS1)
-#define bfin_write_CAN1_TRS1(val)	bfin_write16(CAN1_TRS1, val)
-#define bfin_read_CAN1_TRR1()		bfin_read16(CAN1_TRR1)
-#define bfin_write_CAN1_TRR1(val)	bfin_write16(CAN1_TRR1, val)
-#define bfin_read_CAN1_TA1()		bfin_read16(CAN1_TA1)
-#define bfin_write_CAN1_TA1(val)	bfin_write16(CAN1_TA1, val)
-#define bfin_read_CAN1_AA1()		bfin_read16(CAN1_AA1)
-#define bfin_write_CAN1_AA1(val)	bfin_write16(CAN1_AA1, val)
-#define bfin_read_CAN1_RMP1()		bfin_read16(CAN1_RMP1)
-#define bfin_write_CAN1_RMP1(val)	bfin_write16(CAN1_RMP1, val)
-#define bfin_read_CAN1_RML1()		bfin_read16(CAN1_RML1)
-#define bfin_write_CAN1_RML1(val)	bfin_write16(CAN1_RML1, val)
-#define bfin_read_CAN1_MBTIF1()		bfin_read16(CAN1_MBTIF1)
-#define bfin_write_CAN1_MBTIF1(val)	bfin_write16(CAN1_MBTIF1, val)
-#define bfin_read_CAN1_MBRIF1()		bfin_read16(CAN1_MBRIF1)
-#define bfin_write_CAN1_MBRIF1(val)	bfin_write16(CAN1_MBRIF1, val)
-#define bfin_read_CAN1_MBIM1()		bfin_read16(CAN1_MBIM1)
-#define bfin_write_CAN1_MBIM1(val)	bfin_write16(CAN1_MBIM1, val)
-#define bfin_read_CAN1_RFH1()		bfin_read16(CAN1_RFH1)
-#define bfin_write_CAN1_RFH1(val)	bfin_write16(CAN1_RFH1, val)
-#define bfin_read_CAN1_OPSS1()		bfin_read16(CAN1_OPSS1)
-#define bfin_write_CAN1_OPSS1(val)	bfin_write16(CAN1_OPSS1, val)
-
-/* CAN Controller 1 Config 2 Registers */
-
-#define bfin_read_CAN1_MC2()		bfin_read16(CAN1_MC2)
-#define bfin_write_CAN1_MC2(val)	bfin_write16(CAN1_MC2, val)
-#define bfin_read_CAN1_MD2()		bfin_read16(CAN1_MD2)
-#define bfin_write_CAN1_MD2(val)	bfin_write16(CAN1_MD2, val)
-#define bfin_read_CAN1_TRS2()		bfin_read16(CAN1_TRS2)
-#define bfin_write_CAN1_TRS2(val)	bfin_write16(CAN1_TRS2, val)
-#define bfin_read_CAN1_TRR2()		bfin_read16(CAN1_TRR2)
-#define bfin_write_CAN1_TRR2(val)	bfin_write16(CAN1_TRR2, val)
-#define bfin_read_CAN1_TA2()		bfin_read16(CAN1_TA2)
-#define bfin_write_CAN1_TA2(val)	bfin_write16(CAN1_TA2, val)
-#define bfin_read_CAN1_AA2()		bfin_read16(CAN1_AA2)
-#define bfin_write_CAN1_AA2(val)	bfin_write16(CAN1_AA2, val)
-#define bfin_read_CAN1_RMP2()		bfin_read16(CAN1_RMP2)
-#define bfin_write_CAN1_RMP2(val)	bfin_write16(CAN1_RMP2, val)
-#define bfin_read_CAN1_RML2()		bfin_read16(CAN1_RML2)
-#define bfin_write_CAN1_RML2(val)	bfin_write16(CAN1_RML2, val)
-#define bfin_read_CAN1_MBTIF2()		bfin_read16(CAN1_MBTIF2)
-#define bfin_write_CAN1_MBTIF2(val)	bfin_write16(CAN1_MBTIF2, val)
-#define bfin_read_CAN1_MBRIF2()		bfin_read16(CAN1_MBRIF2)
-#define bfin_write_CAN1_MBRIF2(val)	bfin_write16(CAN1_MBRIF2, val)
-#define bfin_read_CAN1_MBIM2()		bfin_read16(CAN1_MBIM2)
-#define bfin_write_CAN1_MBIM2(val)	bfin_write16(CAN1_MBIM2, val)
-#define bfin_read_CAN1_RFH2()		bfin_read16(CAN1_RFH2)
-#define bfin_write_CAN1_RFH2(val)	bfin_write16(CAN1_RFH2, val)
-#define bfin_read_CAN1_OPSS2()		bfin_read16(CAN1_OPSS2)
-#define bfin_write_CAN1_OPSS2(val)	bfin_write16(CAN1_OPSS2, val)
-
-/* CAN Controller 1 Clock/Interrubfin_read_()t/Counter Registers */
-
-#define bfin_read_CAN1_CLOCK()		bfin_read16(CAN1_CLOCK)
-#define bfin_write_CAN1_CLOCK(val)	bfin_write16(CAN1_CLOCK, val)
-#define bfin_read_CAN1_TIMING()		bfin_read16(CAN1_TIMING)
-#define bfin_write_CAN1_TIMING(val)	bfin_write16(CAN1_TIMING, val)
-#define bfin_read_CAN1_DEBUG()		bfin_read16(CAN1_DEBUG)
-#define bfin_write_CAN1_DEBUG(val)	bfin_write16(CAN1_DEBUG, val)
-#define bfin_read_CAN1_STATUS()		bfin_read16(CAN1_STATUS)
-#define bfin_write_CAN1_STATUS(val)	bfin_write16(CAN1_STATUS, val)
-#define bfin_read_CAN1_CEC()		bfin_read16(CAN1_CEC)
-#define bfin_write_CAN1_CEC(val)	bfin_write16(CAN1_CEC, val)
-#define bfin_read_CAN1_GIS()		bfin_read16(CAN1_GIS)
-#define bfin_write_CAN1_GIS(val)	bfin_write16(CAN1_GIS, val)
-#define bfin_read_CAN1_GIM()		bfin_read16(CAN1_GIM)
-#define bfin_write_CAN1_GIM(val)	bfin_write16(CAN1_GIM, val)
-#define bfin_read_CAN1_GIF()		bfin_read16(CAN1_GIF)
-#define bfin_write_CAN1_GIF(val)	bfin_write16(CAN1_GIF, val)
-#define bfin_read_CAN1_CONTROL()	bfin_read16(CAN1_CONTROL)
-#define bfin_write_CAN1_CONTROL(val)	bfin_write16(CAN1_CONTROL, val)
-#define bfin_read_CAN1_INTR()		bfin_read16(CAN1_INTR)
-#define bfin_write_CAN1_INTR(val)	bfin_write16(CAN1_INTR, val)
-#define bfin_read_CAN1_MBTD()		bfin_read16(CAN1_MBTD)
-#define bfin_write_CAN1_MBTD(val)	bfin_write16(CAN1_MBTD, val)
-#define bfin_read_CAN1_EWR()		bfin_read16(CAN1_EWR)
-#define bfin_write_CAN1_EWR(val)	bfin_write16(CAN1_EWR, val)
-#define bfin_read_CAN1_ESR()		bfin_read16(CAN1_ESR)
-#define bfin_write_CAN1_ESR(val)	bfin_write16(CAN1_ESR, val)
-#define bfin_read_CAN1_UCCNT()		bfin_read16(CAN1_UCCNT)
-#define bfin_write_CAN1_UCCNT(val)	bfin_write16(CAN1_UCCNT, val)
-#define bfin_read_CAN1_UCRC()		bfin_read16(CAN1_UCRC)
-#define bfin_write_CAN1_UCRC(val)	bfin_write16(CAN1_UCRC, val)
-#define bfin_read_CAN1_UCCNF()		bfin_read16(CAN1_UCCNF)
-#define bfin_write_CAN1_UCCNF(val)	bfin_write16(CAN1_UCCNF, val)
-
-/* CAN Controller 1 Mailbox Accebfin_read_()tance Registers */
-
-#define bfin_read_CAN1_AM00L()		bfin_read16(CAN1_AM00L)
-#define bfin_write_CAN1_AM00L(val)	bfin_write16(CAN1_AM00L, val)
-#define bfin_read_CAN1_AM00H()		bfin_read16(CAN1_AM00H)
-#define bfin_write_CAN1_AM00H(val)	bfin_write16(CAN1_AM00H, val)
-#define bfin_read_CAN1_AM01L()		bfin_read16(CAN1_AM01L)
-#define bfin_write_CAN1_AM01L(val)	bfin_write16(CAN1_AM01L, val)
-#define bfin_read_CAN1_AM01H()		bfin_read16(CAN1_AM01H)
-#define bfin_write_CAN1_AM01H(val)	bfin_write16(CAN1_AM01H, val)
-#define bfin_read_CAN1_AM02L()		bfin_read16(CAN1_AM02L)
-#define bfin_write_CAN1_AM02L(val)	bfin_write16(CAN1_AM02L, val)
-#define bfin_read_CAN1_AM02H()		bfin_read16(CAN1_AM02H)
-#define bfin_write_CAN1_AM02H(val)	bfin_write16(CAN1_AM02H, val)
-#define bfin_read_CAN1_AM03L()		bfin_read16(CAN1_AM03L)
-#define bfin_write_CAN1_AM03L(val)	bfin_write16(CAN1_AM03L, val)
-#define bfin_read_CAN1_AM03H()		bfin_read16(CAN1_AM03H)
-#define bfin_write_CAN1_AM03H(val)	bfin_write16(CAN1_AM03H, val)
-#define bfin_read_CAN1_AM04L()		bfin_read16(CAN1_AM04L)
-#define bfin_write_CAN1_AM04L(val)	bfin_write16(CAN1_AM04L, val)
-#define bfin_read_CAN1_AM04H()		bfin_read16(CAN1_AM04H)
-#define bfin_write_CAN1_AM04H(val)	bfin_write16(CAN1_AM04H, val)
-#define bfin_read_CAN1_AM05L()		bfin_read16(CAN1_AM05L)
-#define bfin_write_CAN1_AM05L(val)	bfin_write16(CAN1_AM05L, val)
-#define bfin_read_CAN1_AM05H()		bfin_read16(CAN1_AM05H)
-#define bfin_write_CAN1_AM05H(val)	bfin_write16(CAN1_AM05H, val)
-#define bfin_read_CAN1_AM06L()		bfin_read16(CAN1_AM06L)
-#define bfin_write_CAN1_AM06L(val)	bfin_write16(CAN1_AM06L, val)
-#define bfin_read_CAN1_AM06H()		bfin_read16(CAN1_AM06H)
-#define bfin_write_CAN1_AM06H(val)	bfin_write16(CAN1_AM06H, val)
-#define bfin_read_CAN1_AM07L()		bfin_read16(CAN1_AM07L)
-#define bfin_write_CAN1_AM07L(val)	bfin_write16(CAN1_AM07L, val)
-#define bfin_read_CAN1_AM07H()		bfin_read16(CAN1_AM07H)
-#define bfin_write_CAN1_AM07H(val)	bfin_write16(CAN1_AM07H, val)
-#define bfin_read_CAN1_AM08L()		bfin_read16(CAN1_AM08L)
-#define bfin_write_CAN1_AM08L(val)	bfin_write16(CAN1_AM08L, val)
-#define bfin_read_CAN1_AM08H()		bfin_read16(CAN1_AM08H)
-#define bfin_write_CAN1_AM08H(val)	bfin_write16(CAN1_AM08H, val)
-#define bfin_read_CAN1_AM09L()		bfin_read16(CAN1_AM09L)
-#define bfin_write_CAN1_AM09L(val)	bfin_write16(CAN1_AM09L, val)
-#define bfin_read_CAN1_AM09H()		bfin_read16(CAN1_AM09H)
-#define bfin_write_CAN1_AM09H(val)	bfin_write16(CAN1_AM09H, val)
-#define bfin_read_CAN1_AM10L()		bfin_read16(CAN1_AM10L)
-#define bfin_write_CAN1_AM10L(val)	bfin_write16(CAN1_AM10L, val)
-#define bfin_read_CAN1_AM10H()		bfin_read16(CAN1_AM10H)
-#define bfin_write_CAN1_AM10H(val)	bfin_write16(CAN1_AM10H, val)
-#define bfin_read_CAN1_AM11L()		bfin_read16(CAN1_AM11L)
-#define bfin_write_CAN1_AM11L(val)	bfin_write16(CAN1_AM11L, val)
-#define bfin_read_CAN1_AM11H()		bfin_read16(CAN1_AM11H)
-#define bfin_write_CAN1_AM11H(val)	bfin_write16(CAN1_AM11H, val)
-#define bfin_read_CAN1_AM12L()		bfin_read16(CAN1_AM12L)
-#define bfin_write_CAN1_AM12L(val)	bfin_write16(CAN1_AM12L, val)
-#define bfin_read_CAN1_AM12H()		bfin_read16(CAN1_AM12H)
-#define bfin_write_CAN1_AM12H(val)	bfin_write16(CAN1_AM12H, val)
-#define bfin_read_CAN1_AM13L()		bfin_read16(CAN1_AM13L)
-#define bfin_write_CAN1_AM13L(val)	bfin_write16(CAN1_AM13L, val)
-#define bfin_read_CAN1_AM13H()		bfin_read16(CAN1_AM13H)
-#define bfin_write_CAN1_AM13H(val)	bfin_write16(CAN1_AM13H, val)
-#define bfin_read_CAN1_AM14L()		bfin_read16(CAN1_AM14L)
-#define bfin_write_CAN1_AM14L(val)	bfin_write16(CAN1_AM14L, val)
-#define bfin_read_CAN1_AM14H()		bfin_read16(CAN1_AM14H)
-#define bfin_write_CAN1_AM14H(val)	bfin_write16(CAN1_AM14H, val)
-#define bfin_read_CAN1_AM15L()		bfin_read16(CAN1_AM15L)
-#define bfin_write_CAN1_AM15L(val)	bfin_write16(CAN1_AM15L, val)
-#define bfin_read_CAN1_AM15H()		bfin_read16(CAN1_AM15H)
-#define bfin_write_CAN1_AM15H(val)	bfin_write16(CAN1_AM15H, val)
-
-/* CAN Controller 1 Mailbox Accebfin_read_()tance Registers */
-
-#define bfin_read_CAN1_AM16L()		bfin_read16(CAN1_AM16L)
-#define bfin_write_CAN1_AM16L(val)	bfin_write16(CAN1_AM16L, val)
-#define bfin_read_CAN1_AM16H()		bfin_read16(CAN1_AM16H)
-#define bfin_write_CAN1_AM16H(val)	bfin_write16(CAN1_AM16H, val)
-#define bfin_read_CAN1_AM17L()		bfin_read16(CAN1_AM17L)
-#define bfin_write_CAN1_AM17L(val)	bfin_write16(CAN1_AM17L, val)
-#define bfin_read_CAN1_AM17H()		bfin_read16(CAN1_AM17H)
-#define bfin_write_CAN1_AM17H(val)	bfin_write16(CAN1_AM17H, val)
-#define bfin_read_CAN1_AM18L()		bfin_read16(CAN1_AM18L)
-#define bfin_write_CAN1_AM18L(val)	bfin_write16(CAN1_AM18L, val)
-#define bfin_read_CAN1_AM18H()		bfin_read16(CAN1_AM18H)
-#define bfin_write_CAN1_AM18H(val)	bfin_write16(CAN1_AM18H, val)
-#define bfin_read_CAN1_AM19L()		bfin_read16(CAN1_AM19L)
-#define bfin_write_CAN1_AM19L(val)	bfin_write16(CAN1_AM19L, val)
-#define bfin_read_CAN1_AM19H()		bfin_read16(CAN1_AM19H)
-#define bfin_write_CAN1_AM19H(val)	bfin_write16(CAN1_AM19H, val)
-#define bfin_read_CAN1_AM20L()		bfin_read16(CAN1_AM20L)
-#define bfin_write_CAN1_AM20L(val)	bfin_write16(CAN1_AM20L, val)
-#define bfin_read_CAN1_AM20H()		bfin_read16(CAN1_AM20H)
-#define bfin_write_CAN1_AM20H(val)	bfin_write16(CAN1_AM20H, val)
-#define bfin_read_CAN1_AM21L()		bfin_read16(CAN1_AM21L)
-#define bfin_write_CAN1_AM21L(val)	bfin_write16(CAN1_AM21L, val)
-#define bfin_read_CAN1_AM21H()		bfin_read16(CAN1_AM21H)
-#define bfin_write_CAN1_AM21H(val)	bfin_write16(CAN1_AM21H, val)
-#define bfin_read_CAN1_AM22L()		bfin_read16(CAN1_AM22L)
-#define bfin_write_CAN1_AM22L(val)	bfin_write16(CAN1_AM22L, val)
-#define bfin_read_CAN1_AM22H()		bfin_read16(CAN1_AM22H)
-#define bfin_write_CAN1_AM22H(val)	bfin_write16(CAN1_AM22H, val)
-#define bfin_read_CAN1_AM23L()		bfin_read16(CAN1_AM23L)
-#define bfin_write_CAN1_AM23L(val)	bfin_write16(CAN1_AM23L, val)
-#define bfin_read_CAN1_AM23H()		bfin_read16(CAN1_AM23H)
-#define bfin_write_CAN1_AM23H(val)	bfin_write16(CAN1_AM23H, val)
-#define bfin_read_CAN1_AM24L()		bfin_read16(CAN1_AM24L)
-#define bfin_write_CAN1_AM24L(val)	bfin_write16(CAN1_AM24L, val)
-#define bfin_read_CAN1_AM24H()		bfin_read16(CAN1_AM24H)
-#define bfin_write_CAN1_AM24H(val)	bfin_write16(CAN1_AM24H, val)
-#define bfin_read_CAN1_AM25L()		bfin_read16(CAN1_AM25L)
-#define bfin_write_CAN1_AM25L(val)	bfin_write16(CAN1_AM25L, val)
-#define bfin_read_CAN1_AM25H()		bfin_read16(CAN1_AM25H)
-#define bfin_write_CAN1_AM25H(val)	bfin_write16(CAN1_AM25H, val)
-#define bfin_read_CAN1_AM26L()		bfin_read16(CAN1_AM26L)
-#define bfin_write_CAN1_AM26L(val)	bfin_write16(CAN1_AM26L, val)
-#define bfin_read_CAN1_AM26H()		bfin_read16(CAN1_AM26H)
-#define bfin_write_CAN1_AM26H(val)	bfin_write16(CAN1_AM26H, val)
-#define bfin_read_CAN1_AM27L()		bfin_read16(CAN1_AM27L)
-#define bfin_write_CAN1_AM27L(val)	bfin_write16(CAN1_AM27L, val)
-#define bfin_read_CAN1_AM27H()		bfin_read16(CAN1_AM27H)
-#define bfin_write_CAN1_AM27H(val)	bfin_write16(CAN1_AM27H, val)
-#define bfin_read_CAN1_AM28L()		bfin_read16(CAN1_AM28L)
-#define bfin_write_CAN1_AM28L(val)	bfin_write16(CAN1_AM28L, val)
-#define bfin_read_CAN1_AM28H()		bfin_read16(CAN1_AM28H)
-#define bfin_write_CAN1_AM28H(val)	bfin_write16(CAN1_AM28H, val)
-#define bfin_read_CAN1_AM29L()		bfin_read16(CAN1_AM29L)
-#define bfin_write_CAN1_AM29L(val)	bfin_write16(CAN1_AM29L, val)
-#define bfin_read_CAN1_AM29H()		bfin_read16(CAN1_AM29H)
-#define bfin_write_CAN1_AM29H(val)	bfin_write16(CAN1_AM29H, val)
-#define bfin_read_CAN1_AM30L()		bfin_read16(CAN1_AM30L)
-#define bfin_write_CAN1_AM30L(val)	bfin_write16(CAN1_AM30L, val)
-#define bfin_read_CAN1_AM30H()		bfin_read16(CAN1_AM30H)
-#define bfin_write_CAN1_AM30H(val)	bfin_write16(CAN1_AM30H, val)
-#define bfin_read_CAN1_AM31L()		bfin_read16(CAN1_AM31L)
-#define bfin_write_CAN1_AM31L(val)	bfin_write16(CAN1_AM31L, val)
-#define bfin_read_CAN1_AM31H()		bfin_read16(CAN1_AM31H)
-#define bfin_write_CAN1_AM31H(val)	bfin_write16(CAN1_AM31H, val)
-
-/* CAN Controller 1 Mailbox Data Registers */
-
-#define bfin_read_CAN1_MB00_DATA0()		bfin_read16(CAN1_MB00_DATA0)
-#define bfin_write_CAN1_MB00_DATA0(val)		bfin_write16(CAN1_MB00_DATA0, val)
-#define bfin_read_CAN1_MB00_DATA1()		bfin_read16(CAN1_MB00_DATA1)
-#define bfin_write_CAN1_MB00_DATA1(val)		bfin_write16(CAN1_MB00_DATA1, val)
-#define bfin_read_CAN1_MB00_DATA2()		bfin_read16(CAN1_MB00_DATA2)
-#define bfin_write_CAN1_MB00_DATA2(val)		bfin_write16(CAN1_MB00_DATA2, val)
-#define bfin_read_CAN1_MB00_DATA3()		bfin_read16(CAN1_MB00_DATA3)
-#define bfin_write_CAN1_MB00_DATA3(val)		bfin_write16(CAN1_MB00_DATA3, val)
-#define bfin_read_CAN1_MB00_LENGTH()		bfin_read16(CAN1_MB00_LENGTH)
-#define bfin_write_CAN1_MB00_LENGTH(val)	bfin_write16(CAN1_MB00_LENGTH, val)
-#define bfin_read_CAN1_MB00_TIMESTAMP()		bfin_read16(CAN1_MB00_TIMESTAMP)
-#define bfin_write_CAN1_MB00_TIMESTAMP(val)	bfin_write16(CAN1_MB00_TIMESTAMP, val)
-#define bfin_read_CAN1_MB00_ID0()		bfin_read16(CAN1_MB00_ID0)
-#define bfin_write_CAN1_MB00_ID0(val)		bfin_write16(CAN1_MB00_ID0, val)
-#define bfin_read_CAN1_MB00_ID1()		bfin_read16(CAN1_MB00_ID1)
-#define bfin_write_CAN1_MB00_ID1(val)		bfin_write16(CAN1_MB00_ID1, val)
-#define bfin_read_CAN1_MB01_DATA0()		bfin_read16(CAN1_MB01_DATA0)
-#define bfin_write_CAN1_MB01_DATA0(val)		bfin_write16(CAN1_MB01_DATA0, val)
-#define bfin_read_CAN1_MB01_DATA1()		bfin_read16(CAN1_MB01_DATA1)
-#define bfin_write_CAN1_MB01_DATA1(val)		bfin_write16(CAN1_MB01_DATA1, val)
-#define bfin_read_CAN1_MB01_DATA2()		bfin_read16(CAN1_MB01_DATA2)
-#define bfin_write_CAN1_MB01_DATA2(val)		bfin_write16(CAN1_MB01_DATA2, val)
-#define bfin_read_CAN1_MB01_DATA3()		bfin_read16(CAN1_MB01_DATA3)
-#define bfin_write_CAN1_MB01_DATA3(val)		bfin_write16(CAN1_MB01_DATA3, val)
-#define bfin_read_CAN1_MB01_LENGTH()		bfin_read16(CAN1_MB01_LENGTH)
-#define bfin_write_CAN1_MB01_LENGTH(val)	bfin_write16(CAN1_MB01_LENGTH, val)
-#define bfin_read_CAN1_MB01_TIMESTAMP()		bfin_read16(CAN1_MB01_TIMESTAMP)
-#define bfin_write_CAN1_MB01_TIMESTAMP(val)	bfin_write16(CAN1_MB01_TIMESTAMP, val)
-#define bfin_read_CAN1_MB01_ID0()		bfin_read16(CAN1_MB01_ID0)
-#define bfin_write_CAN1_MB01_ID0(val)		bfin_write16(CAN1_MB01_ID0, val)
-#define bfin_read_CAN1_MB01_ID1()		bfin_read16(CAN1_MB01_ID1)
-#define bfin_write_CAN1_MB01_ID1(val)		bfin_write16(CAN1_MB01_ID1, val)
-#define bfin_read_CAN1_MB02_DATA0()		bfin_read16(CAN1_MB02_DATA0)
-#define bfin_write_CAN1_MB02_DATA0(val)		bfin_write16(CAN1_MB02_DATA0, val)
-#define bfin_read_CAN1_MB02_DATA1()		bfin_read16(CAN1_MB02_DATA1)
-#define bfin_write_CAN1_MB02_DATA1(val)		bfin_write16(CAN1_MB02_DATA1, val)
-#define bfin_read_CAN1_MB02_DATA2()		bfin_read16(CAN1_MB02_DATA2)
-#define bfin_write_CAN1_MB02_DATA2(val)		bfin_write16(CAN1_MB02_DATA2, val)
-#define bfin_read_CAN1_MB02_DATA3()		bfin_read16(CAN1_MB02_DATA3)
-#define bfin_write_CAN1_MB02_DATA3(val)		bfin_write16(CAN1_MB02_DATA3, val)
-#define bfin_read_CAN1_MB02_LENGTH()		bfin_read16(CAN1_MB02_LENGTH)
-#define bfin_write_CAN1_MB02_LENGTH(val)	bfin_write16(CAN1_MB02_LENGTH, val)
-#define bfin_read_CAN1_MB02_TIMESTAMP()		bfin_read16(CAN1_MB02_TIMESTAMP)
-#define bfin_write_CAN1_MB02_TIMESTAMP(val)	bfin_write16(CAN1_MB02_TIMESTAMP, val)
-#define bfin_read_CAN1_MB02_ID0()		bfin_read16(CAN1_MB02_ID0)
-#define bfin_write_CAN1_MB02_ID0(val)		bfin_write16(CAN1_MB02_ID0, val)
-#define bfin_read_CAN1_MB02_ID1()		bfin_read16(CAN1_MB02_ID1)
-#define bfin_write_CAN1_MB02_ID1(val)		bfin_write16(CAN1_MB02_ID1, val)
-#define bfin_read_CAN1_MB03_DATA0()		bfin_read16(CAN1_MB03_DATA0)
-#define bfin_write_CAN1_MB03_DATA0(val)		bfin_write16(CAN1_MB03_DATA0, val)
-#define bfin_read_CAN1_MB03_DATA1()		bfin_read16(CAN1_MB03_DATA1)
-#define bfin_write_CAN1_MB03_DATA1(val)		bfin_write16(CAN1_MB03_DATA1, val)
-#define bfin_read_CAN1_MB03_DATA2()		bfin_read16(CAN1_MB03_DATA2)
-#define bfin_write_CAN1_MB03_DATA2(val)		bfin_write16(CAN1_MB03_DATA2, val)
-#define bfin_read_CAN1_MB03_DATA3()		bfin_read16(CAN1_MB03_DATA3)
-#define bfin_write_CAN1_MB03_DATA3(val)		bfin_write16(CAN1_MB03_DATA3, val)
-#define bfin_read_CAN1_MB03_LENGTH()		bfin_read16(CAN1_MB03_LENGTH)
-#define bfin_write_CAN1_MB03_LENGTH(val)	bfin_write16(CAN1_MB03_LENGTH, val)
-#define bfin_read_CAN1_MB03_TIMESTAMP()		bfin_read16(CAN1_MB03_TIMESTAMP)
-#define bfin_write_CAN1_MB03_TIMESTAMP(val)	bfin_write16(CAN1_MB03_TIMESTAMP, val)
-#define bfin_read_CAN1_MB03_ID0()		bfin_read16(CAN1_MB03_ID0)
-#define bfin_write_CAN1_MB03_ID0(val)		bfin_write16(CAN1_MB03_ID0, val)
-#define bfin_read_CAN1_MB03_ID1()		bfin_read16(CAN1_MB03_ID1)
-#define bfin_write_CAN1_MB03_ID1(val)		bfin_write16(CAN1_MB03_ID1, val)
-#define bfin_read_CAN1_MB04_DATA0()		bfin_read16(CAN1_MB04_DATA0)
-#define bfin_write_CAN1_MB04_DATA0(val)		bfin_write16(CAN1_MB04_DATA0, val)
-#define bfin_read_CAN1_MB04_DATA1()		bfin_read16(CAN1_MB04_DATA1)
-#define bfin_write_CAN1_MB04_DATA1(val)		bfin_write16(CAN1_MB04_DATA1, val)
-#define bfin_read_CAN1_MB04_DATA2()		bfin_read16(CAN1_MB04_DATA2)
-#define bfin_write_CAN1_MB04_DATA2(val)		bfin_write16(CAN1_MB04_DATA2, val)
-#define bfin_read_CAN1_MB04_DATA3()		bfin_read16(CAN1_MB04_DATA3)
-#define bfin_write_CAN1_MB04_DATA3(val)		bfin_write16(CAN1_MB04_DATA3, val)
-#define bfin_read_CAN1_MB04_LENGTH()		bfin_read16(CAN1_MB04_LENGTH)
-#define bfin_write_CAN1_MB04_LENGTH(val)	bfin_write16(CAN1_MB04_LENGTH, val)
-#define bfin_read_CAN1_MB04_TIMESTAMP()		bfin_read16(CAN1_MB04_TIMESTAMP)
-#define bfin_write_CAN1_MB04_TIMESTAMP(val)	bfin_write16(CAN1_MB04_TIMESTAMP, val)
-#define bfin_read_CAN1_MB04_ID0()		bfin_read16(CAN1_MB04_ID0)
-#define bfin_write_CAN1_MB04_ID0(val)		bfin_write16(CAN1_MB04_ID0, val)
-#define bfin_read_CAN1_MB04_ID1()		bfin_read16(CAN1_MB04_ID1)
-#define bfin_write_CAN1_MB04_ID1(val)		bfin_write16(CAN1_MB04_ID1, val)
-#define bfin_read_CAN1_MB05_DATA0()		bfin_read16(CAN1_MB05_DATA0)
-#define bfin_write_CAN1_MB05_DATA0(val)		bfin_write16(CAN1_MB05_DATA0, val)
-#define bfin_read_CAN1_MB05_DATA1()		bfin_read16(CAN1_MB05_DATA1)
-#define bfin_write_CAN1_MB05_DATA1(val)		bfin_write16(CAN1_MB05_DATA1, val)
-#define bfin_read_CAN1_MB05_DATA2()		bfin_read16(CAN1_MB05_DATA2)
-#define bfin_write_CAN1_MB05_DATA2(val)		bfin_write16(CAN1_MB05_DATA2, val)
-#define bfin_read_CAN1_MB05_DATA3()		bfin_read16(CAN1_MB05_DATA3)
-#define bfin_write_CAN1_MB05_DATA3(val)		bfin_write16(CAN1_MB05_DATA3, val)
-#define bfin_read_CAN1_MB05_LENGTH()		bfin_read16(CAN1_MB05_LENGTH)
-#define bfin_write_CAN1_MB05_LENGTH(val)	bfin_write16(CAN1_MB05_LENGTH, val)
-#define bfin_read_CAN1_MB05_TIMESTAMP()		bfin_read16(CAN1_MB05_TIMESTAMP)
-#define bfin_write_CAN1_MB05_TIMESTAMP(val)	bfin_write16(CAN1_MB05_TIMESTAMP, val)
-#define bfin_read_CAN1_MB05_ID0()		bfin_read16(CAN1_MB05_ID0)
-#define bfin_write_CAN1_MB05_ID0(val)		bfin_write16(CAN1_MB05_ID0, val)
-#define bfin_read_CAN1_MB05_ID1()		bfin_read16(CAN1_MB05_ID1)
-#define bfin_write_CAN1_MB05_ID1(val)		bfin_write16(CAN1_MB05_ID1, val)
-#define bfin_read_CAN1_MB06_DATA0()		bfin_read16(CAN1_MB06_DATA0)
-#define bfin_write_CAN1_MB06_DATA0(val)		bfin_write16(CAN1_MB06_DATA0, val)
-#define bfin_read_CAN1_MB06_DATA1()		bfin_read16(CAN1_MB06_DATA1)
-#define bfin_write_CAN1_MB06_DATA1(val)		bfin_write16(CAN1_MB06_DATA1, val)
-#define bfin_read_CAN1_MB06_DATA2()		bfin_read16(CAN1_MB06_DATA2)
-#define bfin_write_CAN1_MB06_DATA2(val)		bfin_write16(CAN1_MB06_DATA2, val)
-#define bfin_read_CAN1_MB06_DATA3()		bfin_read16(CAN1_MB06_DATA3)
-#define bfin_write_CAN1_MB06_DATA3(val)		bfin_write16(CAN1_MB06_DATA3, val)
-#define bfin_read_CAN1_MB06_LENGTH()		bfin_read16(CAN1_MB06_LENGTH)
-#define bfin_write_CAN1_MB06_LENGTH(val)	bfin_write16(CAN1_MB06_LENGTH, val)
-#define bfin_read_CAN1_MB06_TIMESTAMP()		bfin_read16(CAN1_MB06_TIMESTAMP)
-#define bfin_write_CAN1_MB06_TIMESTAMP(val)	bfin_write16(CAN1_MB06_TIMESTAMP, val)
-#define bfin_read_CAN1_MB06_ID0()		bfin_read16(CAN1_MB06_ID0)
-#define bfin_write_CAN1_MB06_ID0(val)		bfin_write16(CAN1_MB06_ID0, val)
-#define bfin_read_CAN1_MB06_ID1()		bfin_read16(CAN1_MB06_ID1)
-#define bfin_write_CAN1_MB06_ID1(val)		bfin_write16(CAN1_MB06_ID1, val)
-#define bfin_read_CAN1_MB07_DATA0()		bfin_read16(CAN1_MB07_DATA0)
-#define bfin_write_CAN1_MB07_DATA0(val)		bfin_write16(CAN1_MB07_DATA0, val)
-#define bfin_read_CAN1_MB07_DATA1()		bfin_read16(CAN1_MB07_DATA1)
-#define bfin_write_CAN1_MB07_DATA1(val)		bfin_write16(CAN1_MB07_DATA1, val)
-#define bfin_read_CAN1_MB07_DATA2()		bfin_read16(CAN1_MB07_DATA2)
-#define bfin_write_CAN1_MB07_DATA2(val)		bfin_write16(CAN1_MB07_DATA2, val)
-#define bfin_read_CAN1_MB07_DATA3()		bfin_read16(CAN1_MB07_DATA3)
-#define bfin_write_CAN1_MB07_DATA3(val)		bfin_write16(CAN1_MB07_DATA3, val)
-#define bfin_read_CAN1_MB07_LENGTH()		bfin_read16(CAN1_MB07_LENGTH)
-#define bfin_write_CAN1_MB07_LENGTH(val)	bfin_write16(CAN1_MB07_LENGTH, val)
-#define bfin_read_CAN1_MB07_TIMESTAMP()		bfin_read16(CAN1_MB07_TIMESTAMP)
-#define bfin_write_CAN1_MB07_TIMESTAMP(val)	bfin_write16(CAN1_MB07_TIMESTAMP, val)
-#define bfin_read_CAN1_MB07_ID0()		bfin_read16(CAN1_MB07_ID0)
-#define bfin_write_CAN1_MB07_ID0(val)		bfin_write16(CAN1_MB07_ID0, val)
-#define bfin_read_CAN1_MB07_ID1()		bfin_read16(CAN1_MB07_ID1)
-#define bfin_write_CAN1_MB07_ID1(val)		bfin_write16(CAN1_MB07_ID1, val)
-#define bfin_read_CAN1_MB08_DATA0()		bfin_read16(CAN1_MB08_DATA0)
-#define bfin_write_CAN1_MB08_DATA0(val)		bfin_write16(CAN1_MB08_DATA0, val)
-#define bfin_read_CAN1_MB08_DATA1()		bfin_read16(CAN1_MB08_DATA1)
-#define bfin_write_CAN1_MB08_DATA1(val)		bfin_write16(CAN1_MB08_DATA1, val)
-#define bfin_read_CAN1_MB08_DATA2()		bfin_read16(CAN1_MB08_DATA2)
-#define bfin_write_CAN1_MB08_DATA2(val)		bfin_write16(CAN1_MB08_DATA2, val)
-#define bfin_read_CAN1_MB08_DATA3()		bfin_read16(CAN1_MB08_DATA3)
-#define bfin_write_CAN1_MB08_DATA3(val)		bfin_write16(CAN1_MB08_DATA3, val)
-#define bfin_read_CAN1_MB08_LENGTH()		bfin_read16(CAN1_MB08_LENGTH)
-#define bfin_write_CAN1_MB08_LENGTH(val)	bfin_write16(CAN1_MB08_LENGTH, val)
-#define bfin_read_CAN1_MB08_TIMESTAMP()		bfin_read16(CAN1_MB08_TIMESTAMP)
-#define bfin_write_CAN1_MB08_TIMESTAMP(val)	bfin_write16(CAN1_MB08_TIMESTAMP, val)
-#define bfin_read_CAN1_MB08_ID0()		bfin_read16(CAN1_MB08_ID0)
-#define bfin_write_CAN1_MB08_ID0(val)		bfin_write16(CAN1_MB08_ID0, val)
-#define bfin_read_CAN1_MB08_ID1()		bfin_read16(CAN1_MB08_ID1)
-#define bfin_write_CAN1_MB08_ID1(val)		bfin_write16(CAN1_MB08_ID1, val)
-#define bfin_read_CAN1_MB09_DATA0()		bfin_read16(CAN1_MB09_DATA0)
-#define bfin_write_CAN1_MB09_DATA0(val)		bfin_write16(CAN1_MB09_DATA0, val)
-#define bfin_read_CAN1_MB09_DATA1()		bfin_read16(CAN1_MB09_DATA1)
-#define bfin_write_CAN1_MB09_DATA1(val)		bfin_write16(CAN1_MB09_DATA1, val)
-#define bfin_read_CAN1_MB09_DATA2()		bfin_read16(CAN1_MB09_DATA2)
-#define bfin_write_CAN1_MB09_DATA2(val)		bfin_write16(CAN1_MB09_DATA2, val)
-#define bfin_read_CAN1_MB09_DATA3()		bfin_read16(CAN1_MB09_DATA3)
-#define bfin_write_CAN1_MB09_DATA3(val)		bfin_write16(CAN1_MB09_DATA3, val)
-#define bfin_read_CAN1_MB09_LENGTH()		bfin_read16(CAN1_MB09_LENGTH)
-#define bfin_write_CAN1_MB09_LENGTH(val)	bfin_write16(CAN1_MB09_LENGTH, val)
-#define bfin_read_CAN1_MB09_TIMESTAMP()		bfin_read16(CAN1_MB09_TIMESTAMP)
-#define bfin_write_CAN1_MB09_TIMESTAMP(val)	bfin_write16(CAN1_MB09_TIMESTAMP, val)
-#define bfin_read_CAN1_MB09_ID0()		bfin_read16(CAN1_MB09_ID0)
-#define bfin_write_CAN1_MB09_ID0(val)		bfin_write16(CAN1_MB09_ID0, val)
-#define bfin_read_CAN1_MB09_ID1()		bfin_read16(CAN1_MB09_ID1)
-#define bfin_write_CAN1_MB09_ID1(val)		bfin_write16(CAN1_MB09_ID1, val)
-#define bfin_read_CAN1_MB10_DATA0()		bfin_read16(CAN1_MB10_DATA0)
-#define bfin_write_CAN1_MB10_DATA0(val)		bfin_write16(CAN1_MB10_DATA0, val)
-#define bfin_read_CAN1_MB10_DATA1()		bfin_read16(CAN1_MB10_DATA1)
-#define bfin_write_CAN1_MB10_DATA1(val)		bfin_write16(CAN1_MB10_DATA1, val)
-#define bfin_read_CAN1_MB10_DATA2()		bfin_read16(CAN1_MB10_DATA2)
-#define bfin_write_CAN1_MB10_DATA2(val)		bfin_write16(CAN1_MB10_DATA2, val)
-#define bfin_read_CAN1_MB10_DATA3()		bfin_read16(CAN1_MB10_DATA3)
-#define bfin_write_CAN1_MB10_DATA3(val)		bfin_write16(CAN1_MB10_DATA3, val)
-#define bfin_read_CAN1_MB10_LENGTH()		bfin_read16(CAN1_MB10_LENGTH)
-#define bfin_write_CAN1_MB10_LENGTH(val)	bfin_write16(CAN1_MB10_LENGTH, val)
-#define bfin_read_CAN1_MB10_TIMESTAMP()		bfin_read16(CAN1_MB10_TIMESTAMP)
-#define bfin_write_CAN1_MB10_TIMESTAMP(val)	bfin_write16(CAN1_MB10_TIMESTAMP, val)
-#define bfin_read_CAN1_MB10_ID0()		bfin_read16(CAN1_MB10_ID0)
-#define bfin_write_CAN1_MB10_ID0(val)		bfin_write16(CAN1_MB10_ID0, val)
-#define bfin_read_CAN1_MB10_ID1()		bfin_read16(CAN1_MB10_ID1)
-#define bfin_write_CAN1_MB10_ID1(val)		bfin_write16(CAN1_MB10_ID1, val)
-#define bfin_read_CAN1_MB11_DATA0()		bfin_read16(CAN1_MB11_DATA0)
-#define bfin_write_CAN1_MB11_DATA0(val)		bfin_write16(CAN1_MB11_DATA0, val)
-#define bfin_read_CAN1_MB11_DATA1()		bfin_read16(CAN1_MB11_DATA1)
-#define bfin_write_CAN1_MB11_DATA1(val)		bfin_write16(CAN1_MB11_DATA1, val)
-#define bfin_read_CAN1_MB11_DATA2()		bfin_read16(CAN1_MB11_DATA2)
-#define bfin_write_CAN1_MB11_DATA2(val)		bfin_write16(CAN1_MB11_DATA2, val)
-#define bfin_read_CAN1_MB11_DATA3()		bfin_read16(CAN1_MB11_DATA3)
-#define bfin_write_CAN1_MB11_DATA3(val)		bfin_write16(CAN1_MB11_DATA3, val)
-#define bfin_read_CAN1_MB11_LENGTH()		bfin_read16(CAN1_MB11_LENGTH)
-#define bfin_write_CAN1_MB11_LENGTH(val)	bfin_write16(CAN1_MB11_LENGTH, val)
-#define bfin_read_CAN1_MB11_TIMESTAMP()		bfin_read16(CAN1_MB11_TIMESTAMP)
-#define bfin_write_CAN1_MB11_TIMESTAMP(val)	bfin_write16(CAN1_MB11_TIMESTAMP, val)
-#define bfin_read_CAN1_MB11_ID0()		bfin_read16(CAN1_MB11_ID0)
-#define bfin_write_CAN1_MB11_ID0(val)		bfin_write16(CAN1_MB11_ID0, val)
-#define bfin_read_CAN1_MB11_ID1()		bfin_read16(CAN1_MB11_ID1)
-#define bfin_write_CAN1_MB11_ID1(val)		bfin_write16(CAN1_MB11_ID1, val)
-#define bfin_read_CAN1_MB12_DATA0()		bfin_read16(CAN1_MB12_DATA0)
-#define bfin_write_CAN1_MB12_DATA0(val)		bfin_write16(CAN1_MB12_DATA0, val)
-#define bfin_read_CAN1_MB12_DATA1()		bfin_read16(CAN1_MB12_DATA1)
-#define bfin_write_CAN1_MB12_DATA1(val)		bfin_write16(CAN1_MB12_DATA1, val)
-#define bfin_read_CAN1_MB12_DATA2()		bfin_read16(CAN1_MB12_DATA2)
-#define bfin_write_CAN1_MB12_DATA2(val)		bfin_write16(CAN1_MB12_DATA2, val)
-#define bfin_read_CAN1_MB12_DATA3()		bfin_read16(CAN1_MB12_DATA3)
-#define bfin_write_CAN1_MB12_DATA3(val)		bfin_write16(CAN1_MB12_DATA3, val)
-#define bfin_read_CAN1_MB12_LENGTH()		bfin_read16(CAN1_MB12_LENGTH)
-#define bfin_write_CAN1_MB12_LENGTH(val)	bfin_write16(CAN1_MB12_LENGTH, val)
-#define bfin_read_CAN1_MB12_TIMESTAMP()		bfin_read16(CAN1_MB12_TIMESTAMP)
-#define bfin_write_CAN1_MB12_TIMESTAMP(val)	bfin_write16(CAN1_MB12_TIMESTAMP, val)
-#define bfin_read_CAN1_MB12_ID0()		bfin_read16(CAN1_MB12_ID0)
-#define bfin_write_CAN1_MB12_ID0(val)		bfin_write16(CAN1_MB12_ID0, val)
-#define bfin_read_CAN1_MB12_ID1()		bfin_read16(CAN1_MB12_ID1)
-#define bfin_write_CAN1_MB12_ID1(val)		bfin_write16(CAN1_MB12_ID1, val)
-#define bfin_read_CAN1_MB13_DATA0()		bfin_read16(CAN1_MB13_DATA0)
-#define bfin_write_CAN1_MB13_DATA0(val)		bfin_write16(CAN1_MB13_DATA0, val)
-#define bfin_read_CAN1_MB13_DATA1()		bfin_read16(CAN1_MB13_DATA1)
-#define bfin_write_CAN1_MB13_DATA1(val)		bfin_write16(CAN1_MB13_DATA1, val)
-#define bfin_read_CAN1_MB13_DATA2()		bfin_read16(CAN1_MB13_DATA2)
-#define bfin_write_CAN1_MB13_DATA2(val)		bfin_write16(CAN1_MB13_DATA2, val)
-#define bfin_read_CAN1_MB13_DATA3()		bfin_read16(CAN1_MB13_DATA3)
-#define bfin_write_CAN1_MB13_DATA3(val)		bfin_write16(CAN1_MB13_DATA3, val)
-#define bfin_read_CAN1_MB13_LENGTH()		bfin_read16(CAN1_MB13_LENGTH)
-#define bfin_write_CAN1_MB13_LENGTH(val)	bfin_write16(CAN1_MB13_LENGTH, val)
-#define bfin_read_CAN1_MB13_TIMESTAMP()		bfin_read16(CAN1_MB13_TIMESTAMP)
-#define bfin_write_CAN1_MB13_TIMESTAMP(val)	bfin_write16(CAN1_MB13_TIMESTAMP, val)
-#define bfin_read_CAN1_MB13_ID0()		bfin_read16(CAN1_MB13_ID0)
-#define bfin_write_CAN1_MB13_ID0(val)		bfin_write16(CAN1_MB13_ID0, val)
-#define bfin_read_CAN1_MB13_ID1()		bfin_read16(CAN1_MB13_ID1)
-#define bfin_write_CAN1_MB13_ID1(val)		bfin_write16(CAN1_MB13_ID1, val)
-#define bfin_read_CAN1_MB14_DATA0()		bfin_read16(CAN1_MB14_DATA0)
-#define bfin_write_CAN1_MB14_DATA0(val)		bfin_write16(CAN1_MB14_DATA0, val)
-#define bfin_read_CAN1_MB14_DATA1()		bfin_read16(CAN1_MB14_DATA1)
-#define bfin_write_CAN1_MB14_DATA1(val)		bfin_write16(CAN1_MB14_DATA1, val)
-#define bfin_read_CAN1_MB14_DATA2()		bfin_read16(CAN1_MB14_DATA2)
-#define bfin_write_CAN1_MB14_DATA2(val)		bfin_write16(CAN1_MB14_DATA2, val)
-#define bfin_read_CAN1_MB14_DATA3()		bfin_read16(CAN1_MB14_DATA3)
-#define bfin_write_CAN1_MB14_DATA3(val)		bfin_write16(CAN1_MB14_DATA3, val)
-#define bfin_read_CAN1_MB14_LENGTH()		bfin_read16(CAN1_MB14_LENGTH)
-#define bfin_write_CAN1_MB14_LENGTH(val)	bfin_write16(CAN1_MB14_LENGTH, val)
-#define bfin_read_CAN1_MB14_TIMESTAMP()		bfin_read16(CAN1_MB14_TIMESTAMP)
-#define bfin_write_CAN1_MB14_TIMESTAMP(val)	bfin_write16(CAN1_MB14_TIMESTAMP, val)
-#define bfin_read_CAN1_MB14_ID0()		bfin_read16(CAN1_MB14_ID0)
-#define bfin_write_CAN1_MB14_ID0(val)		bfin_write16(CAN1_MB14_ID0, val)
-#define bfin_read_CAN1_MB14_ID1()		bfin_read16(CAN1_MB14_ID1)
-#define bfin_write_CAN1_MB14_ID1(val)		bfin_write16(CAN1_MB14_ID1, val)
-#define bfin_read_CAN1_MB15_DATA0()		bfin_read16(CAN1_MB15_DATA0)
-#define bfin_write_CAN1_MB15_DATA0(val)		bfin_write16(CAN1_MB15_DATA0, val)
-#define bfin_read_CAN1_MB15_DATA1()		bfin_read16(CAN1_MB15_DATA1)
-#define bfin_write_CAN1_MB15_DATA1(val)		bfin_write16(CAN1_MB15_DATA1, val)
-#define bfin_read_CAN1_MB15_DATA2()		bfin_read16(CAN1_MB15_DATA2)
-#define bfin_write_CAN1_MB15_DATA2(val)		bfin_write16(CAN1_MB15_DATA2, val)
-#define bfin_read_CAN1_MB15_DATA3()		bfin_read16(CAN1_MB15_DATA3)
-#define bfin_write_CAN1_MB15_DATA3(val)		bfin_write16(CAN1_MB15_DATA3, val)
-#define bfin_read_CAN1_MB15_LENGTH()		bfin_read16(CAN1_MB15_LENGTH)
-#define bfin_write_CAN1_MB15_LENGTH(val)	bfin_write16(CAN1_MB15_LENGTH, val)
-#define bfin_read_CAN1_MB15_TIMESTAMP()		bfin_read16(CAN1_MB15_TIMESTAMP)
-#define bfin_write_CAN1_MB15_TIMESTAMP(val)	bfin_write16(CAN1_MB15_TIMESTAMP, val)
-#define bfin_read_CAN1_MB15_ID0()		bfin_read16(CAN1_MB15_ID0)
-#define bfin_write_CAN1_MB15_ID0(val)		bfin_write16(CAN1_MB15_ID0, val)
-#define bfin_read_CAN1_MB15_ID1()		bfin_read16(CAN1_MB15_ID1)
-#define bfin_write_CAN1_MB15_ID1(val)		bfin_write16(CAN1_MB15_ID1, val)
-
-/* CAN Controller 1 Mailbox Data Registers */
-
-#define bfin_read_CAN1_MB16_DATA0()		bfin_read16(CAN1_MB16_DATA0)
-#define bfin_write_CAN1_MB16_DATA0(val)		bfin_write16(CAN1_MB16_DATA0, val)
-#define bfin_read_CAN1_MB16_DATA1()		bfin_read16(CAN1_MB16_DATA1)
-#define bfin_write_CAN1_MB16_DATA1(val)		bfin_write16(CAN1_MB16_DATA1, val)
-#define bfin_read_CAN1_MB16_DATA2()		bfin_read16(CAN1_MB16_DATA2)
-#define bfin_write_CAN1_MB16_DATA2(val)		bfin_write16(CAN1_MB16_DATA2, val)
-#define bfin_read_CAN1_MB16_DATA3()		bfin_read16(CAN1_MB16_DATA3)
-#define bfin_write_CAN1_MB16_DATA3(val)		bfin_write16(CAN1_MB16_DATA3, val)
-#define bfin_read_CAN1_MB16_LENGTH()		bfin_read16(CAN1_MB16_LENGTH)
-#define bfin_write_CAN1_MB16_LENGTH(val)	bfin_write16(CAN1_MB16_LENGTH, val)
-#define bfin_read_CAN1_MB16_TIMESTAMP()		bfin_read16(CAN1_MB16_TIMESTAMP)
-#define bfin_write_CAN1_MB16_TIMESTAMP(val)	bfin_write16(CAN1_MB16_TIMESTAMP, val)
-#define bfin_read_CAN1_MB16_ID0()		bfin_read16(CAN1_MB16_ID0)
-#define bfin_write_CAN1_MB16_ID0(val)		bfin_write16(CAN1_MB16_ID0, val)
-#define bfin_read_CAN1_MB16_ID1()		bfin_read16(CAN1_MB16_ID1)
-#define bfin_write_CAN1_MB16_ID1(val)		bfin_write16(CAN1_MB16_ID1, val)
-#define bfin_read_CAN1_MB17_DATA0()		bfin_read16(CAN1_MB17_DATA0)
-#define bfin_write_CAN1_MB17_DATA0(val)		bfin_write16(CAN1_MB17_DATA0, val)
-#define bfin_read_CAN1_MB17_DATA1()		bfin_read16(CAN1_MB17_DATA1)
-#define bfin_write_CAN1_MB17_DATA1(val)		bfin_write16(CAN1_MB17_DATA1, val)
-#define bfin_read_CAN1_MB17_DATA2()		bfin_read16(CAN1_MB17_DATA2)
-#define bfin_write_CAN1_MB17_DATA2(val)		bfin_write16(CAN1_MB17_DATA2, val)
-#define bfin_read_CAN1_MB17_DATA3()		bfin_read16(CAN1_MB17_DATA3)
-#define bfin_write_CAN1_MB17_DATA3(val)		bfin_write16(CAN1_MB17_DATA3, val)
-#define bfin_read_CAN1_MB17_LENGTH()		bfin_read16(CAN1_MB17_LENGTH)
-#define bfin_write_CAN1_MB17_LENGTH(val)	bfin_write16(CAN1_MB17_LENGTH, val)
-#define bfin_read_CAN1_MB17_TIMESTAMP()		bfin_read16(CAN1_MB17_TIMESTAMP)
-#define bfin_write_CAN1_MB17_TIMESTAMP(val)	bfin_write16(CAN1_MB17_TIMESTAMP, val)
-#define bfin_read_CAN1_MB17_ID0()		bfin_read16(CAN1_MB17_ID0)
-#define bfin_write_CAN1_MB17_ID0(val)		bfin_write16(CAN1_MB17_ID0, val)
-#define bfin_read_CAN1_MB17_ID1()		bfin_read16(CAN1_MB17_ID1)
-#define bfin_write_CAN1_MB17_ID1(val)		bfin_write16(CAN1_MB17_ID1, val)
-#define bfin_read_CAN1_MB18_DATA0()		bfin_read16(CAN1_MB18_DATA0)
-#define bfin_write_CAN1_MB18_DATA0(val)		bfin_write16(CAN1_MB18_DATA0, val)
-#define bfin_read_CAN1_MB18_DATA1()		bfin_read16(CAN1_MB18_DATA1)
-#define bfin_write_CAN1_MB18_DATA1(val)		bfin_write16(CAN1_MB18_DATA1, val)
-#define bfin_read_CAN1_MB18_DATA2()		bfin_read16(CAN1_MB18_DATA2)
-#define bfin_write_CAN1_MB18_DATA2(val)		bfin_write16(CAN1_MB18_DATA2, val)
-#define bfin_read_CAN1_MB18_DATA3()		bfin_read16(CAN1_MB18_DATA3)
-#define bfin_write_CAN1_MB18_DATA3(val)		bfin_write16(CAN1_MB18_DATA3, val)
-#define bfin_read_CAN1_MB18_LENGTH()		bfin_read16(CAN1_MB18_LENGTH)
-#define bfin_write_CAN1_MB18_LENGTH(val)	bfin_write16(CAN1_MB18_LENGTH, val)
-#define bfin_read_CAN1_MB18_TIMESTAMP()		bfin_read16(CAN1_MB18_TIMESTAMP)
-#define bfin_write_CAN1_MB18_TIMESTAMP(val)	bfin_write16(CAN1_MB18_TIMESTAMP, val)
-#define bfin_read_CAN1_MB18_ID0()		bfin_read16(CAN1_MB18_ID0)
-#define bfin_write_CAN1_MB18_ID0(val)		bfin_write16(CAN1_MB18_ID0, val)
-#define bfin_read_CAN1_MB18_ID1()		bfin_read16(CAN1_MB18_ID1)
-#define bfin_write_CAN1_MB18_ID1(val)		bfin_write16(CAN1_MB18_ID1, val)
-#define bfin_read_CAN1_MB19_DATA0()		bfin_read16(CAN1_MB19_DATA0)
-#define bfin_write_CAN1_MB19_DATA0(val)		bfin_write16(CAN1_MB19_DATA0, val)
-#define bfin_read_CAN1_MB19_DATA1()		bfin_read16(CAN1_MB19_DATA1)
-#define bfin_write_CAN1_MB19_DATA1(val)		bfin_write16(CAN1_MB19_DATA1, val)
-#define bfin_read_CAN1_MB19_DATA2()		bfin_read16(CAN1_MB19_DATA2)
-#define bfin_write_CAN1_MB19_DATA2(val)		bfin_write16(CAN1_MB19_DATA2, val)
-#define bfin_read_CAN1_MB19_DATA3()		bfin_read16(CAN1_MB19_DATA3)
-#define bfin_write_CAN1_MB19_DATA3(val)		bfin_write16(CAN1_MB19_DATA3, val)
-#define bfin_read_CAN1_MB19_LENGTH()		bfin_read16(CAN1_MB19_LENGTH)
-#define bfin_write_CAN1_MB19_LENGTH(val)	bfin_write16(CAN1_MB19_LENGTH, val)
-#define bfin_read_CAN1_MB19_TIMESTAMP()		bfin_read16(CAN1_MB19_TIMESTAMP)
-#define bfin_write_CAN1_MB19_TIMESTAMP(val)	bfin_write16(CAN1_MB19_TIMESTAMP, val)
-#define bfin_read_CAN1_MB19_ID0()		bfin_read16(CAN1_MB19_ID0)
-#define bfin_write_CAN1_MB19_ID0(val)		bfin_write16(CAN1_MB19_ID0, val)
-#define bfin_read_CAN1_MB19_ID1()		bfin_read16(CAN1_MB19_ID1)
-#define bfin_write_CAN1_MB19_ID1(val)		bfin_write16(CAN1_MB19_ID1, val)
-#define bfin_read_CAN1_MB20_DATA0()		bfin_read16(CAN1_MB20_DATA0)
-#define bfin_write_CAN1_MB20_DATA0(val)		bfin_write16(CAN1_MB20_DATA0, val)
-#define bfin_read_CAN1_MB20_DATA1()		bfin_read16(CAN1_MB20_DATA1)
-#define bfin_write_CAN1_MB20_DATA1(val)		bfin_write16(CAN1_MB20_DATA1, val)
-#define bfin_read_CAN1_MB20_DATA2()		bfin_read16(CAN1_MB20_DATA2)
-#define bfin_write_CAN1_MB20_DATA2(val)		bfin_write16(CAN1_MB20_DATA2, val)
-#define bfin_read_CAN1_MB20_DATA3()		bfin_read16(CAN1_MB20_DATA3)
-#define bfin_write_CAN1_MB20_DATA3(val)		bfin_write16(CAN1_MB20_DATA3, val)
-#define bfin_read_CAN1_MB20_LENGTH()		bfin_read16(CAN1_MB20_LENGTH)
-#define bfin_write_CAN1_MB20_LENGTH(val)	bfin_write16(CAN1_MB20_LENGTH, val)
-#define bfin_read_CAN1_MB20_TIMESTAMP()		bfin_read16(CAN1_MB20_TIMESTAMP)
-#define bfin_write_CAN1_MB20_TIMESTAMP(val)	bfin_write16(CAN1_MB20_TIMESTAMP, val)
-#define bfin_read_CAN1_MB20_ID0()		bfin_read16(CAN1_MB20_ID0)
-#define bfin_write_CAN1_MB20_ID0(val)		bfin_write16(CAN1_MB20_ID0, val)
-#define bfin_read_CAN1_MB20_ID1()		bfin_read16(CAN1_MB20_ID1)
-#define bfin_write_CAN1_MB20_ID1(val)		bfin_write16(CAN1_MB20_ID1, val)
-#define bfin_read_CAN1_MB21_DATA0()		bfin_read16(CAN1_MB21_DATA0)
-#define bfin_write_CAN1_MB21_DATA0(val)		bfin_write16(CAN1_MB21_DATA0, val)
-#define bfin_read_CAN1_MB21_DATA1()		bfin_read16(CAN1_MB21_DATA1)
-#define bfin_write_CAN1_MB21_DATA1(val)		bfin_write16(CAN1_MB21_DATA1, val)
-#define bfin_read_CAN1_MB21_DATA2()		bfin_read16(CAN1_MB21_DATA2)
-#define bfin_write_CAN1_MB21_DATA2(val)		bfin_write16(CAN1_MB21_DATA2, val)
-#define bfin_read_CAN1_MB21_DATA3()		bfin_read16(CAN1_MB21_DATA3)
-#define bfin_write_CAN1_MB21_DATA3(val)		bfin_write16(CAN1_MB21_DATA3, val)
-#define bfin_read_CAN1_MB21_LENGTH()		bfin_read16(CAN1_MB21_LENGTH)
-#define bfin_write_CAN1_MB21_LENGTH(val)	bfin_write16(CAN1_MB21_LENGTH, val)
-#define bfin_read_CAN1_MB21_TIMESTAMP()		bfin_read16(CAN1_MB21_TIMESTAMP)
-#define bfin_write_CAN1_MB21_TIMESTAMP(val)	bfin_write16(CAN1_MB21_TIMESTAMP, val)
-#define bfin_read_CAN1_MB21_ID0()		bfin_read16(CAN1_MB21_ID0)
-#define bfin_write_CAN1_MB21_ID0(val)		bfin_write16(CAN1_MB21_ID0, val)
-#define bfin_read_CAN1_MB21_ID1()		bfin_read16(CAN1_MB21_ID1)
-#define bfin_write_CAN1_MB21_ID1(val)		bfin_write16(CAN1_MB21_ID1, val)
-#define bfin_read_CAN1_MB22_DATA0()		bfin_read16(CAN1_MB22_DATA0)
-#define bfin_write_CAN1_MB22_DATA0(val)		bfin_write16(CAN1_MB22_DATA0, val)
-#define bfin_read_CAN1_MB22_DATA1()		bfin_read16(CAN1_MB22_DATA1)
-#define bfin_write_CAN1_MB22_DATA1(val)		bfin_write16(CAN1_MB22_DATA1, val)
-#define bfin_read_CAN1_MB22_DATA2()		bfin_read16(CAN1_MB22_DATA2)
-#define bfin_write_CAN1_MB22_DATA2(val)		bfin_write16(CAN1_MB22_DATA2, val)
-#define bfin_read_CAN1_MB22_DATA3()		bfin_read16(CAN1_MB22_DATA3)
-#define bfin_write_CAN1_MB22_DATA3(val)		bfin_write16(CAN1_MB22_DATA3, val)
-#define bfin_read_CAN1_MB22_LENGTH()		bfin_read16(CAN1_MB22_LENGTH)
-#define bfin_write_CAN1_MB22_LENGTH(val)	bfin_write16(CAN1_MB22_LENGTH, val)
-#define bfin_read_CAN1_MB22_TIMESTAMP()		bfin_read16(CAN1_MB22_TIMESTAMP)
-#define bfin_write_CAN1_MB22_TIMESTAMP(val)	bfin_write16(CAN1_MB22_TIMESTAMP, val)
-#define bfin_read_CAN1_MB22_ID0()		bfin_read16(CAN1_MB22_ID0)
-#define bfin_write_CAN1_MB22_ID0(val)		bfin_write16(CAN1_MB22_ID0, val)
-#define bfin_read_CAN1_MB22_ID1()		bfin_read16(CAN1_MB22_ID1)
-#define bfin_write_CAN1_MB22_ID1(val)		bfin_write16(CAN1_MB22_ID1, val)
-#define bfin_read_CAN1_MB23_DATA0()		bfin_read16(CAN1_MB23_DATA0)
-#define bfin_write_CAN1_MB23_DATA0(val)		bfin_write16(CAN1_MB23_DATA0, val)
-#define bfin_read_CAN1_MB23_DATA1()		bfin_read16(CAN1_MB23_DATA1)
-#define bfin_write_CAN1_MB23_DATA1(val)		bfin_write16(CAN1_MB23_DATA1, val)
-#define bfin_read_CAN1_MB23_DATA2()		bfin_read16(CAN1_MB23_DATA2)
-#define bfin_write_CAN1_MB23_DATA2(val)		bfin_write16(CAN1_MB23_DATA2, val)
-#define bfin_read_CAN1_MB23_DATA3()		bfin_read16(CAN1_MB23_DATA3)
-#define bfin_write_CAN1_MB23_DATA3(val)		bfin_write16(CAN1_MB23_DATA3, val)
-#define bfin_read_CAN1_MB23_LENGTH()		bfin_read16(CAN1_MB23_LENGTH)
-#define bfin_write_CAN1_MB23_LENGTH(val)	bfin_write16(CAN1_MB23_LENGTH, val)
-#define bfin_read_CAN1_MB23_TIMESTAMP()		bfin_read16(CAN1_MB23_TIMESTAMP)
-#define bfin_write_CAN1_MB23_TIMESTAMP(val)	bfin_write16(CAN1_MB23_TIMESTAMP, val)
-#define bfin_read_CAN1_MB23_ID0()		bfin_read16(CAN1_MB23_ID0)
-#define bfin_write_CAN1_MB23_ID0(val)		bfin_write16(CAN1_MB23_ID0, val)
-#define bfin_read_CAN1_MB23_ID1()		bfin_read16(CAN1_MB23_ID1)
-#define bfin_write_CAN1_MB23_ID1(val)		bfin_write16(CAN1_MB23_ID1, val)
-#define bfin_read_CAN1_MB24_DATA0()		bfin_read16(CAN1_MB24_DATA0)
-#define bfin_write_CAN1_MB24_DATA0(val)		bfin_write16(CAN1_MB24_DATA0, val)
-#define bfin_read_CAN1_MB24_DATA1()		bfin_read16(CAN1_MB24_DATA1)
-#define bfin_write_CAN1_MB24_DATA1(val)		bfin_write16(CAN1_MB24_DATA1, val)
-#define bfin_read_CAN1_MB24_DATA2()		bfin_read16(CAN1_MB24_DATA2)
-#define bfin_write_CAN1_MB24_DATA2(val)		bfin_write16(CAN1_MB24_DATA2, val)
-#define bfin_read_CAN1_MB24_DATA3()		bfin_read16(CAN1_MB24_DATA3)
-#define bfin_write_CAN1_MB24_DATA3(val)		bfin_write16(CAN1_MB24_DATA3, val)
-#define bfin_read_CAN1_MB24_LENGTH()		bfin_read16(CAN1_MB24_LENGTH)
-#define bfin_write_CAN1_MB24_LENGTH(val)	bfin_write16(CAN1_MB24_LENGTH, val)
-#define bfin_read_CAN1_MB24_TIMESTAMP()		bfin_read16(CAN1_MB24_TIMESTAMP)
-#define bfin_write_CAN1_MB24_TIMESTAMP(val)	bfin_write16(CAN1_MB24_TIMESTAMP, val)
-#define bfin_read_CAN1_MB24_ID0()		bfin_read16(CAN1_MB24_ID0)
-#define bfin_write_CAN1_MB24_ID0(val)		bfin_write16(CAN1_MB24_ID0, val)
-#define bfin_read_CAN1_MB24_ID1()		bfin_read16(CAN1_MB24_ID1)
-#define bfin_write_CAN1_MB24_ID1(val)		bfin_write16(CAN1_MB24_ID1, val)
-#define bfin_read_CAN1_MB25_DATA0()		bfin_read16(CAN1_MB25_DATA0)
-#define bfin_write_CAN1_MB25_DATA0(val)		bfin_write16(CAN1_MB25_DATA0, val)
-#define bfin_read_CAN1_MB25_DATA1()		bfin_read16(CAN1_MB25_DATA1)
-#define bfin_write_CAN1_MB25_DATA1(val)		bfin_write16(CAN1_MB25_DATA1, val)
-#define bfin_read_CAN1_MB25_DATA2()		bfin_read16(CAN1_MB25_DATA2)
-#define bfin_write_CAN1_MB25_DATA2(val)		bfin_write16(CAN1_MB25_DATA2, val)
-#define bfin_read_CAN1_MB25_DATA3()		bfin_read16(CAN1_MB25_DATA3)
-#define bfin_write_CAN1_MB25_DATA3(val)		bfin_write16(CAN1_MB25_DATA3, val)
-#define bfin_read_CAN1_MB25_LENGTH()		bfin_read16(CAN1_MB25_LENGTH)
-#define bfin_write_CAN1_MB25_LENGTH(val)	bfin_write16(CAN1_MB25_LENGTH, val)
-#define bfin_read_CAN1_MB25_TIMESTAMP()		bfin_read16(CAN1_MB25_TIMESTAMP)
-#define bfin_write_CAN1_MB25_TIMESTAMP(val)	bfin_write16(CAN1_MB25_TIMESTAMP, val)
-#define bfin_read_CAN1_MB25_ID0()		bfin_read16(CAN1_MB25_ID0)
-#define bfin_write_CAN1_MB25_ID0(val)		bfin_write16(CAN1_MB25_ID0, val)
-#define bfin_read_CAN1_MB25_ID1()		bfin_read16(CAN1_MB25_ID1)
-#define bfin_write_CAN1_MB25_ID1(val)		bfin_write16(CAN1_MB25_ID1, val)
-#define bfin_read_CAN1_MB26_DATA0()		bfin_read16(CAN1_MB26_DATA0)
-#define bfin_write_CAN1_MB26_DATA0(val)		bfin_write16(CAN1_MB26_DATA0, val)
-#define bfin_read_CAN1_MB26_DATA1()		bfin_read16(CAN1_MB26_DATA1)
-#define bfin_write_CAN1_MB26_DATA1(val)		bfin_write16(CAN1_MB26_DATA1, val)
-#define bfin_read_CAN1_MB26_DATA2()		bfin_read16(CAN1_MB26_DATA2)
-#define bfin_write_CAN1_MB26_DATA2(val)		bfin_write16(CAN1_MB26_DATA2, val)
-#define bfin_read_CAN1_MB26_DATA3()		bfin_read16(CAN1_MB26_DATA3)
-#define bfin_write_CAN1_MB26_DATA3(val)		bfin_write16(CAN1_MB26_DATA3, val)
-#define bfin_read_CAN1_MB26_LENGTH()		bfin_read16(CAN1_MB26_LENGTH)
-#define bfin_write_CAN1_MB26_LENGTH(val)	bfin_write16(CAN1_MB26_LENGTH, val)
-#define bfin_read_CAN1_MB26_TIMESTAMP()		bfin_read16(CAN1_MB26_TIMESTAMP)
-#define bfin_write_CAN1_MB26_TIMESTAMP(val)	bfin_write16(CAN1_MB26_TIMESTAMP, val)
-#define bfin_read_CAN1_MB26_ID0()		bfin_read16(CAN1_MB26_ID0)
-#define bfin_write_CAN1_MB26_ID0(val)		bfin_write16(CAN1_MB26_ID0, val)
-#define bfin_read_CAN1_MB26_ID1()		bfin_read16(CAN1_MB26_ID1)
-#define bfin_write_CAN1_MB26_ID1(val)		bfin_write16(CAN1_MB26_ID1, val)
-#define bfin_read_CAN1_MB27_DATA0()		bfin_read16(CAN1_MB27_DATA0)
-#define bfin_write_CAN1_MB27_DATA0(val)		bfin_write16(CAN1_MB27_DATA0, val)
-#define bfin_read_CAN1_MB27_DATA1()		bfin_read16(CAN1_MB27_DATA1)
-#define bfin_write_CAN1_MB27_DATA1(val)		bfin_write16(CAN1_MB27_DATA1, val)
-#define bfin_read_CAN1_MB27_DATA2()		bfin_read16(CAN1_MB27_DATA2)
-#define bfin_write_CAN1_MB27_DATA2(val)		bfin_write16(CAN1_MB27_DATA2, val)
-#define bfin_read_CAN1_MB27_DATA3()		bfin_read16(CAN1_MB27_DATA3)
-#define bfin_write_CAN1_MB27_DATA3(val)		bfin_write16(CAN1_MB27_DATA3, val)
-#define bfin_read_CAN1_MB27_LENGTH()		bfin_read16(CAN1_MB27_LENGTH)
-#define bfin_write_CAN1_MB27_LENGTH(val)	bfin_write16(CAN1_MB27_LENGTH, val)
-#define bfin_read_CAN1_MB27_TIMESTAMP()		bfin_read16(CAN1_MB27_TIMESTAMP)
-#define bfin_write_CAN1_MB27_TIMESTAMP(val)	bfin_write16(CAN1_MB27_TIMESTAMP, val)
-#define bfin_read_CAN1_MB27_ID0()		bfin_read16(CAN1_MB27_ID0)
-#define bfin_write_CAN1_MB27_ID0(val)		bfin_write16(CAN1_MB27_ID0, val)
-#define bfin_read_CAN1_MB27_ID1()		bfin_read16(CAN1_MB27_ID1)
-#define bfin_write_CAN1_MB27_ID1(val)		bfin_write16(CAN1_MB27_ID1, val)
-#define bfin_read_CAN1_MB28_DATA0()		bfin_read16(CAN1_MB28_DATA0)
-#define bfin_write_CAN1_MB28_DATA0(val)		bfin_write16(CAN1_MB28_DATA0, val)
-#define bfin_read_CAN1_MB28_DATA1()		bfin_read16(CAN1_MB28_DATA1)
-#define bfin_write_CAN1_MB28_DATA1(val)		bfin_write16(CAN1_MB28_DATA1, val)
-#define bfin_read_CAN1_MB28_DATA2()		bfin_read16(CAN1_MB28_DATA2)
-#define bfin_write_CAN1_MB28_DATA2(val)		bfin_write16(CAN1_MB28_DATA2, val)
-#define bfin_read_CAN1_MB28_DATA3()		bfin_read16(CAN1_MB28_DATA3)
-#define bfin_write_CAN1_MB28_DATA3(val)		bfin_write16(CAN1_MB28_DATA3, val)
-#define bfin_read_CAN1_MB28_LENGTH()		bfin_read16(CAN1_MB28_LENGTH)
-#define bfin_write_CAN1_MB28_LENGTH(val)	bfin_write16(CAN1_MB28_LENGTH, val)
-#define bfin_read_CAN1_MB28_TIMESTAMP()		bfin_read16(CAN1_MB28_TIMESTAMP)
-#define bfin_write_CAN1_MB28_TIMESTAMP(val)	bfin_write16(CAN1_MB28_TIMESTAMP, val)
-#define bfin_read_CAN1_MB28_ID0()		bfin_read16(CAN1_MB28_ID0)
-#define bfin_write_CAN1_MB28_ID0(val)		bfin_write16(CAN1_MB28_ID0, val)
-#define bfin_read_CAN1_MB28_ID1()		bfin_read16(CAN1_MB28_ID1)
-#define bfin_write_CAN1_MB28_ID1(val)		bfin_write16(CAN1_MB28_ID1, val)
-#define bfin_read_CAN1_MB29_DATA0()		bfin_read16(CAN1_MB29_DATA0)
-#define bfin_write_CAN1_MB29_DATA0(val)		bfin_write16(CAN1_MB29_DATA0, val)
-#define bfin_read_CAN1_MB29_DATA1()		bfin_read16(CAN1_MB29_DATA1)
-#define bfin_write_CAN1_MB29_DATA1(val)		bfin_write16(CAN1_MB29_DATA1, val)
-#define bfin_read_CAN1_MB29_DATA2()		bfin_read16(CAN1_MB29_DATA2)
-#define bfin_write_CAN1_MB29_DATA2(val)		bfin_write16(CAN1_MB29_DATA2, val)
-#define bfin_read_CAN1_MB29_DATA3()		bfin_read16(CAN1_MB29_DATA3)
-#define bfin_write_CAN1_MB29_DATA3(val)		bfin_write16(CAN1_MB29_DATA3, val)
-#define bfin_read_CAN1_MB29_LENGTH()		bfin_read16(CAN1_MB29_LENGTH)
-#define bfin_write_CAN1_MB29_LENGTH(val)	bfin_write16(CAN1_MB29_LENGTH, val)
-#define bfin_read_CAN1_MB29_TIMESTAMP()		bfin_read16(CAN1_MB29_TIMESTAMP)
-#define bfin_write_CAN1_MB29_TIMESTAMP(val)	bfin_write16(CAN1_MB29_TIMESTAMP, val)
-#define bfin_read_CAN1_MB29_ID0()		bfin_read16(CAN1_MB29_ID0)
-#define bfin_write_CAN1_MB29_ID0(val)		bfin_write16(CAN1_MB29_ID0, val)
-#define bfin_read_CAN1_MB29_ID1()		bfin_read16(CAN1_MB29_ID1)
-#define bfin_write_CAN1_MB29_ID1(val)		bfin_write16(CAN1_MB29_ID1, val)
-#define bfin_read_CAN1_MB30_DATA0()		bfin_read16(CAN1_MB30_DATA0)
-#define bfin_write_CAN1_MB30_DATA0(val)		bfin_write16(CAN1_MB30_DATA0, val)
-#define bfin_read_CAN1_MB30_DATA1()		bfin_read16(CAN1_MB30_DATA1)
-#define bfin_write_CAN1_MB30_DATA1(val)		bfin_write16(CAN1_MB30_DATA1, val)
-#define bfin_read_CAN1_MB30_DATA2()		bfin_read16(CAN1_MB30_DATA2)
-#define bfin_write_CAN1_MB30_DATA2(val)		bfin_write16(CAN1_MB30_DATA2, val)
-#define bfin_read_CAN1_MB30_DATA3()		bfin_read16(CAN1_MB30_DATA3)
-#define bfin_write_CAN1_MB30_DATA3(val)		bfin_write16(CAN1_MB30_DATA3, val)
-#define bfin_read_CAN1_MB30_LENGTH()		bfin_read16(CAN1_MB30_LENGTH)
-#define bfin_write_CAN1_MB30_LENGTH(val)	bfin_write16(CAN1_MB30_LENGTH, val)
-#define bfin_read_CAN1_MB30_TIMESTAMP()		bfin_read16(CAN1_MB30_TIMESTAMP)
-#define bfin_write_CAN1_MB30_TIMESTAMP(val)	bfin_write16(CAN1_MB30_TIMESTAMP, val)
-#define bfin_read_CAN1_MB30_ID0()		bfin_read16(CAN1_MB30_ID0)
-#define bfin_write_CAN1_MB30_ID0(val)		bfin_write16(CAN1_MB30_ID0, val)
-#define bfin_read_CAN1_MB30_ID1()		bfin_read16(CAN1_MB30_ID1)
-#define bfin_write_CAN1_MB30_ID1(val)		bfin_write16(CAN1_MB30_ID1, val)
-#define bfin_read_CAN1_MB31_DATA0()		bfin_read16(CAN1_MB31_DATA0)
-#define bfin_write_CAN1_MB31_DATA0(val)		bfin_write16(CAN1_MB31_DATA0, val)
-#define bfin_read_CAN1_MB31_DATA1()		bfin_read16(CAN1_MB31_DATA1)
-#define bfin_write_CAN1_MB31_DATA1(val)		bfin_write16(CAN1_MB31_DATA1, val)
-#define bfin_read_CAN1_MB31_DATA2()		bfin_read16(CAN1_MB31_DATA2)
-#define bfin_write_CAN1_MB31_DATA2(val)		bfin_write16(CAN1_MB31_DATA2, val)
-#define bfin_read_CAN1_MB31_DATA3()		bfin_read16(CAN1_MB31_DATA3)
-#define bfin_write_CAN1_MB31_DATA3(val)		bfin_write16(CAN1_MB31_DATA3, val)
-#define bfin_read_CAN1_MB31_LENGTH()		bfin_read16(CAN1_MB31_LENGTH)
-#define bfin_write_CAN1_MB31_LENGTH(val)	bfin_write16(CAN1_MB31_LENGTH, val)
-#define bfin_read_CAN1_MB31_TIMESTAMP()		bfin_read16(CAN1_MB31_TIMESTAMP)
-#define bfin_write_CAN1_MB31_TIMESTAMP(val)	bfin_write16(CAN1_MB31_TIMESTAMP, val)
-#define bfin_read_CAN1_MB31_ID0()		bfin_read16(CAN1_MB31_ID0)
-#define bfin_write_CAN1_MB31_ID0(val)		bfin_write16(CAN1_MB31_ID0, val)
-#define bfin_read_CAN1_MB31_ID1()		bfin_read16(CAN1_MB31_ID1)
-#define bfin_write_CAN1_MB31_ID1(val)		bfin_write16(CAN1_MB31_ID1, val)
-
-/* ATAPI Registers */
-
-#define bfin_read_ATAPI_CONTROL()		bfin_read16(ATAPI_CONTROL)
-#define bfin_write_ATAPI_CONTROL(val)		bfin_write16(ATAPI_CONTROL, val)
-#define bfin_read_ATAPI_STATUS()		bfin_read16(ATAPI_STATUS)
-#define bfin_write_ATAPI_STATUS(val)		bfin_write16(ATAPI_STATUS, val)
-#define bfin_read_ATAPI_DEV_ADDR()		bfin_read16(ATAPI_DEV_ADDR)
-#define bfin_write_ATAPI_DEV_ADDR(val)		bfin_write16(ATAPI_DEV_ADDR, val)
-#define bfin_read_ATAPI_DEV_TXBUF()		bfin_read16(ATAPI_DEV_TXBUF)
-#define bfin_write_ATAPI_DEV_TXBUF(val)		bfin_write16(ATAPI_DEV_TXBUF, val)
-#define bfin_read_ATAPI_DEV_RXBUF()		bfin_read16(ATAPI_DEV_RXBUF)
-#define bfin_write_ATAPI_DEV_RXBUF(val)		bfin_write16(ATAPI_DEV_RXBUF, val)
-#define bfin_read_ATAPI_INT_MASK()		bfin_read16(ATAPI_INT_MASK)
-#define bfin_write_ATAPI_INT_MASK(val)		bfin_write16(ATAPI_INT_MASK, val)
-#define bfin_read_ATAPI_INT_STATUS()		bfin_read16(ATAPI_INT_STATUS)
-#define bfin_write_ATAPI_INT_STATUS(val)	bfin_write16(ATAPI_INT_STATUS, val)
-#define bfin_read_ATAPI_XFER_LEN()		bfin_read16(ATAPI_XFER_LEN)
-#define bfin_write_ATAPI_XFER_LEN(val)		bfin_write16(ATAPI_XFER_LEN, val)
-#define bfin_read_ATAPI_LINE_STATUS()		bfin_read16(ATAPI_LINE_STATUS)
-#define bfin_write_ATAPI_LINE_STATUS(val)	bfin_write16(ATAPI_LINE_STATUS, val)
-#define bfin_read_ATAPI_SM_STATE()		bfin_read16(ATAPI_SM_STATE)
-#define bfin_write_ATAPI_SM_STATE(val)		bfin_write16(ATAPI_SM_STATE, val)
-#define bfin_read_ATAPI_TERMINATE()		bfin_read16(ATAPI_TERMINATE)
-#define bfin_write_ATAPI_TERMINATE(val)		bfin_write16(ATAPI_TERMINATE, val)
-#define bfin_read_ATAPI_PIO_TFRCNT()		bfin_read16(ATAPI_PIO_TFRCNT)
-#define bfin_write_ATAPI_PIO_TFRCNT(val)	bfin_write16(ATAPI_PIO_TFRCNT, val)
-#define bfin_read_ATAPI_DMA_TFRCNT()		bfin_read16(ATAPI_DMA_TFRCNT)
-#define bfin_write_ATAPI_DMA_TFRCNT(val)	bfin_write16(ATAPI_DMA_TFRCNT, val)
-#define bfin_read_ATAPI_UMAIN_TFRCNT()		bfin_read16(ATAPI_UMAIN_TFRCNT)
-#define bfin_write_ATAPI_UMAIN_TFRCNT(val)	bfin_write16(ATAPI_UMAIN_TFRCNT, val)
-#define bfin_read_ATAPI_UDMAOUT_TFRCNT()	bfin_read16(ATAPI_UDMAOUT_TFRCNT)
-#define bfin_write_ATAPI_UDMAOUT_TFRCNT(val)	bfin_write16(ATAPI_UDMAOUT_TFRCNT, val)
-#define bfin_read_ATAPI_REG_TIM_0()		bfin_read16(ATAPI_REG_TIM_0)
-#define bfin_write_ATAPI_REG_TIM_0(val)		bfin_write16(ATAPI_REG_TIM_0, val)
-#define bfin_read_ATAPI_PIO_TIM_0()		bfin_read16(ATAPI_PIO_TIM_0)
-#define bfin_write_ATAPI_PIO_TIM_0(val)		bfin_write16(ATAPI_PIO_TIM_0, val)
-#define bfin_read_ATAPI_PIO_TIM_1()		bfin_read16(ATAPI_PIO_TIM_1)
-#define bfin_write_ATAPI_PIO_TIM_1(val)		bfin_write16(ATAPI_PIO_TIM_1, val)
-#define bfin_read_ATAPI_MULTI_TIM_0()		bfin_read16(ATAPI_MULTI_TIM_0)
-#define bfin_write_ATAPI_MULTI_TIM_0(val)	bfin_write16(ATAPI_MULTI_TIM_0, val)
-#define bfin_read_ATAPI_MULTI_TIM_1()		bfin_read16(ATAPI_MULTI_TIM_1)
-#define bfin_write_ATAPI_MULTI_TIM_1(val)	bfin_write16(ATAPI_MULTI_TIM_1, val)
-#define bfin_read_ATAPI_MULTI_TIM_2()		bfin_read16(ATAPI_MULTI_TIM_2)
-#define bfin_write_ATAPI_MULTI_TIM_2(val)	bfin_write16(ATAPI_MULTI_TIM_2, val)
-#define bfin_read_ATAPI_ULTRA_TIM_0()		bfin_read16(ATAPI_ULTRA_TIM_0)
-#define bfin_write_ATAPI_ULTRA_TIM_0(val)	bfin_write16(ATAPI_ULTRA_TIM_0, val)
-#define bfin_read_ATAPI_ULTRA_TIM_1()		bfin_read16(ATAPI_ULTRA_TIM_1)
-#define bfin_write_ATAPI_ULTRA_TIM_1(val)	bfin_write16(ATAPI_ULTRA_TIM_1, val)
-#define bfin_read_ATAPI_ULTRA_TIM_2()		bfin_read16(ATAPI_ULTRA_TIM_2)
-#define bfin_write_ATAPI_ULTRA_TIM_2(val)	bfin_write16(ATAPI_ULTRA_TIM_2, val)
-#define bfin_read_ATAPI_ULTRA_TIM_3()		bfin_read16(ATAPI_ULTRA_TIM_3)
-#define bfin_write_ATAPI_ULTRA_TIM_3(val)	bfin_write16(ATAPI_ULTRA_TIM_3, val)
-
-/* SDH Registers */
-
-#define bfin_read_SDH_PWR_CTL()		bfin_read16(SDH_PWR_CTL)
-#define bfin_write_SDH_PWR_CTL(val)	bfin_write16(SDH_PWR_CTL, val)
-#define bfin_read_SDH_CLK_CTL()		bfin_read16(SDH_CLK_CTL)
-#define bfin_write_SDH_CLK_CTL(val)	bfin_write16(SDH_CLK_CTL, val)
-#define bfin_read_SDH_ARGUMENT()	bfin_read32(SDH_ARGUMENT)
-#define bfin_write_SDH_ARGUMENT(val)	bfin_write32(SDH_ARGUMENT, val)
-#define bfin_read_SDH_COMMAND()		bfin_read16(SDH_COMMAND)
-#define bfin_write_SDH_COMMAND(val)	bfin_write16(SDH_COMMAND, val)
-#define bfin_read_SDH_RESP_CMD()	bfin_read16(SDH_RESP_CMD)
-#define bfin_write_SDH_RESP_CMD(val)	bfin_write16(SDH_RESP_CMD, val)
-#define bfin_read_SDH_RESPONSE0()	bfin_read32(SDH_RESPONSE0)
-#define bfin_write_SDH_RESPONSE0(val)	bfin_write32(SDH_RESPONSE0, val)
-#define bfin_read_SDH_RESPONSE1()	bfin_read32(SDH_RESPONSE1)
-#define bfin_write_SDH_RESPONSE1(val)	bfin_write32(SDH_RESPONSE1, val)
-#define bfin_read_SDH_RESPONSE2()	bfin_read32(SDH_RESPONSE2)
-#define bfin_write_SDH_RESPONSE2(val)	bfin_write32(SDH_RESPONSE2, val)
-#define bfin_read_SDH_RESPONSE3()	bfin_read32(SDH_RESPONSE3)
-#define bfin_write_SDH_RESPONSE3(val)	bfin_write32(SDH_RESPONSE3, val)
-#define bfin_read_SDH_DATA_TIMER()	bfin_read32(SDH_DATA_TIMER)
-#define bfin_write_SDH_DATA_TIMER(val)	bfin_write32(SDH_DATA_TIMER, val)
-#define bfin_read_SDH_DATA_LGTH()	bfin_read16(SDH_DATA_LGTH)
-#define bfin_write_SDH_DATA_LGTH(val)	bfin_write16(SDH_DATA_LGTH, val)
-#define bfin_read_SDH_DATA_CTL()	bfin_read16(SDH_DATA_CTL)
-#define bfin_write_SDH_DATA_CTL(val)	bfin_write16(SDH_DATA_CTL, val)
-#define bfin_read_SDH_DATA_CNT()	bfin_read16(SDH_DATA_CNT)
-#define bfin_write_SDH_DATA_CNT(val)	bfin_write16(SDH_DATA_CNT, val)
-#define bfin_read_SDH_STATUS()		bfin_read32(SDH_STATUS)
-#define bfin_write_SDH_STATUS(val)	bfin_write32(SDH_STATUS, val)
-#define bfin_read_SDH_STATUS_CLR()	bfin_read16(SDH_STATUS_CLR)
-#define bfin_write_SDH_STATUS_CLR(val)	bfin_write16(SDH_STATUS_CLR, val)
-#define bfin_read_SDH_MASK0()		bfin_read32(SDH_MASK0)
-#define bfin_write_SDH_MASK0(val)	bfin_write32(SDH_MASK0, val)
-#define bfin_read_SDH_MASK1()		bfin_read32(SDH_MASK1)
-#define bfin_write_SDH_MASK1(val)	bfin_write32(SDH_MASK1, val)
-#define bfin_read_SDH_FIFO_CNT()	bfin_read16(SDH_FIFO_CNT)
-#define bfin_write_SDH_FIFO_CNT(val)	bfin_write16(SDH_FIFO_CNT, val)
-#define bfin_read_SDH_FIFO()		bfin_read32(SDH_FIFO)
-#define bfin_write_SDH_FIFO(val)	bfin_write32(SDH_FIFO, val)
-#define bfin_read_SDH_E_STATUS()	bfin_read16(SDH_E_STATUS)
-#define bfin_write_SDH_E_STATUS(val)	bfin_write16(SDH_E_STATUS, val)
-#define bfin_read_SDH_E_MASK()		bfin_read16(SDH_E_MASK)
-#define bfin_write_SDH_E_MASK(val)	bfin_write16(SDH_E_MASK, val)
-#define bfin_read_SDH_CFG()		bfin_read16(SDH_CFG)
-#define bfin_write_SDH_CFG(val)		bfin_write16(SDH_CFG, val)
-#define bfin_read_SDH_RD_WAIT_EN()	bfin_read16(SDH_RD_WAIT_EN)
-#define bfin_write_SDH_RD_WAIT_EN(val)	bfin_write16(SDH_RD_WAIT_EN, val)
-#define bfin_read_SDH_PID0()		bfin_read16(SDH_PID0)
-#define bfin_write_SDH_PID0(val)	bfin_write16(SDH_PID0, val)
-#define bfin_read_SDH_PID1()		bfin_read16(SDH_PID1)
-#define bfin_write_SDH_PID1(val)	bfin_write16(SDH_PID1, val)
-#define bfin_read_SDH_PID2()		bfin_read16(SDH_PID2)
-#define bfin_write_SDH_PID2(val)	bfin_write16(SDH_PID2, val)
-#define bfin_read_SDH_PID3()		bfin_read16(SDH_PID3)
-#define bfin_write_SDH_PID3(val)	bfin_write16(SDH_PID3, val)
-#define bfin_read_SDH_PID4()		bfin_read16(SDH_PID4)
-#define bfin_write_SDH_PID4(val)	bfin_write16(SDH_PID4, val)
-#define bfin_read_SDH_PID5()		bfin_read16(SDH_PID5)
-#define bfin_write_SDH_PID5(val)	bfin_write16(SDH_PID5, val)
-#define bfin_read_SDH_PID6()		bfin_read16(SDH_PID6)
-#define bfin_write_SDH_PID6(val)	bfin_write16(SDH_PID6, val)
-#define bfin_read_SDH_PID7()		bfin_read16(SDH_PID7)
-#define bfin_write_SDH_PID7(val)	bfin_write16(SDH_PID7, val)
-
-/* HOST Port Registers */
-
-#define bfin_read_HOST_CONTROL()	bfin_read16(HOST_CONTROL)
-#define bfin_write_HOST_CONTROL(val)	bfin_write16(HOST_CONTROL, val)
-#define bfin_read_HOST_STATUS()		bfin_read16(HOST_STATUS)
-#define bfin_write_HOST_STATUS(val)	bfin_write16(HOST_STATUS, val)
-#define bfin_read_HOST_TIMEOUT()	bfin_read16(HOST_TIMEOUT)
-#define bfin_write_HOST_TIMEOUT(val)	bfin_write16(HOST_TIMEOUT, val)
-
-/* USB Control Registers */
-
-#define bfin_read_USB_FADDR()		bfin_read16(USB_FADDR)
-#define bfin_write_USB_FADDR(val)	bfin_write16(USB_FADDR, val)
-#define bfin_read_USB_POWER()		bfin_read16(USB_POWER)
-#define bfin_write_USB_POWER(val)	bfin_write16(USB_POWER, val)
-#define bfin_read_USB_INTRTX()		bfin_read16(USB_INTRTX)
-#define bfin_write_USB_INTRTX(val)	bfin_write16(USB_INTRTX, val)
-#define bfin_read_USB_INTRRX()		bfin_read16(USB_INTRRX)
-#define bfin_write_USB_INTRRX(val)	bfin_write16(USB_INTRRX, val)
-#define bfin_read_USB_INTRTXE()		bfin_read16(USB_INTRTXE)
-#define bfin_write_USB_INTRTXE(val)	bfin_write16(USB_INTRTXE, val)
-#define bfin_read_USB_INTRRXE()		bfin_read16(USB_INTRRXE)
-#define bfin_write_USB_INTRRXE(val)	bfin_write16(USB_INTRRXE, val)
-#define bfin_read_USB_INTRUSB()		bfin_read16(USB_INTRUSB)
-#define bfin_write_USB_INTRUSB(val)	bfin_write16(USB_INTRUSB, val)
-#define bfin_read_USB_INTRUSBE()	bfin_read16(USB_INTRUSBE)
-#define bfin_write_USB_INTRUSBE(val)	bfin_write16(USB_INTRUSBE, val)
-#define bfin_read_USB_FRAME()		bfin_read16(USB_FRAME)
-#define bfin_write_USB_FRAME(val)	bfin_write16(USB_FRAME, val)
-#define bfin_read_USB_INDEX()		bfin_read16(USB_INDEX)
-#define bfin_write_USB_INDEX(val)	bfin_write16(USB_INDEX, val)
-#define bfin_read_USB_TESTMODE()	bfin_read16(USB_TESTMODE)
-#define bfin_write_USB_TESTMODE(val)	bfin_write16(USB_TESTMODE, val)
-#define bfin_read_USB_GLOBINTR()	bfin_read16(USB_GLOBINTR)
-#define bfin_write_USB_GLOBINTR(val)	bfin_write16(USB_GLOBINTR, val)
-#define bfin_read_USB_GLOBAL_CTL()	bfin_read16(USB_GLOBAL_CTL)
-#define bfin_write_USB_GLOBAL_CTL(val)	bfin_write16(USB_GLOBAL_CTL, val)
-
-/* USB Packet Control Registers */
-
-#define bfin_read_USB_TX_MAX_PACKET()		bfin_read16(USB_TX_MAX_PACKET)
-#define bfin_write_USB_TX_MAX_PACKET(val)	bfin_write16(USB_TX_MAX_PACKET, val)
-#define bfin_read_USB_CSR0()			bfin_read16(USB_CSR0)
-#define bfin_write_USB_CSR0(val)		bfin_write16(USB_CSR0, val)
-#define bfin_read_USB_TXCSR()			bfin_read16(USB_TXCSR)
-#define bfin_write_USB_TXCSR(val)		bfin_write16(USB_TXCSR, val)
-#define bfin_read_USB_RX_MAX_PACKET()		bfin_read16(USB_RX_MAX_PACKET)
-#define bfin_write_USB_RX_MAX_PACKET(val)	bfin_write16(USB_RX_MAX_PACKET, val)
-#define bfin_read_USB_RXCSR()			bfin_read16(USB_RXCSR)
-#define bfin_write_USB_RXCSR(val)		bfin_write16(USB_RXCSR, val)
-#define bfin_read_USB_COUNT0()			bfin_read16(USB_COUNT0)
-#define bfin_write_USB_COUNT0(val)		bfin_write16(USB_COUNT0, val)
-#define bfin_read_USB_RXCOUNT()			bfin_read16(USB_RXCOUNT)
-#define bfin_write_USB_RXCOUNT(val)		bfin_write16(USB_RXCOUNT, val)
-#define bfin_read_USB_TXTYPE()			bfin_read16(USB_TXTYPE)
-#define bfin_write_USB_TXTYPE(val)		bfin_write16(USB_TXTYPE, val)
-#define bfin_read_USB_NAKLIMIT0()		bfin_read16(USB_NAKLIMIT0)
-#define bfin_write_USB_NAKLIMIT0(val)		bfin_write16(USB_NAKLIMIT0, val)
-#define bfin_read_USB_TXINTERVAL()		bfin_read16(USB_TXINTERVAL)
-#define bfin_write_USB_TXINTERVAL(val)		bfin_write16(USB_TXINTERVAL, val)
-#define bfin_read_USB_RXTYPE()			bfin_read16(USB_RXTYPE)
-#define bfin_write_USB_RXTYPE(val)		bfin_write16(USB_RXTYPE, val)
-#define bfin_read_USB_RXINTERVAL()		bfin_read16(USB_RXINTERVAL)
-#define bfin_write_USB_RXINTERVAL(val)		bfin_write16(USB_RXINTERVAL, val)
-#define bfin_read_USB_TXCOUNT()			bfin_read16(USB_TXCOUNT)
-#define bfin_write_USB_TXCOUNT(val)		bfin_write16(USB_TXCOUNT, val)
-
-/* USB Endbfin_read_()oint FIFO Registers */
-
-#define bfin_read_USB_EP0_FIFO()		bfin_read16(USB_EP0_FIFO)
-#define bfin_write_USB_EP0_FIFO(val)		bfin_write16(USB_EP0_FIFO, val)
-#define bfin_read_USB_EP1_FIFO()		bfin_read16(USB_EP1_FIFO)
-#define bfin_write_USB_EP1_FIFO(val)		bfin_write16(USB_EP1_FIFO, val)
-#define bfin_read_USB_EP2_FIFO()		bfin_read16(USB_EP2_FIFO)
-#define bfin_write_USB_EP2_FIFO(val)		bfin_write16(USB_EP2_FIFO, val)
-#define bfin_read_USB_EP3_FIFO()		bfin_read16(USB_EP3_FIFO)
-#define bfin_write_USB_EP3_FIFO(val)		bfin_write16(USB_EP3_FIFO, val)
-#define bfin_read_USB_EP4_FIFO()		bfin_read16(USB_EP4_FIFO)
-#define bfin_write_USB_EP4_FIFO(val)		bfin_write16(USB_EP4_FIFO, val)
-#define bfin_read_USB_EP5_FIFO()		bfin_read16(USB_EP5_FIFO)
-#define bfin_write_USB_EP5_FIFO(val)		bfin_write16(USB_EP5_FIFO, val)
-#define bfin_read_USB_EP6_FIFO()		bfin_read16(USB_EP6_FIFO)
-#define bfin_write_USB_EP6_FIFO(val)		bfin_write16(USB_EP6_FIFO, val)
-#define bfin_read_USB_EP7_FIFO()		bfin_read16(USB_EP7_FIFO)
-#define bfin_write_USB_EP7_FIFO(val)		bfin_write16(USB_EP7_FIFO, val)
-
-/* USB OTG Control Registers */
-
-#define bfin_read_USB_OTG_DEV_CTL()		bfin_read16(USB_OTG_DEV_CTL)
-#define bfin_write_USB_OTG_DEV_CTL(val)		bfin_write16(USB_OTG_DEV_CTL, val)
-#define bfin_read_USB_OTG_VBUS_IRQ()		bfin_read16(USB_OTG_VBUS_IRQ)
-#define bfin_write_USB_OTG_VBUS_IRQ(val)	bfin_write16(USB_OTG_VBUS_IRQ, val)
-#define bfin_read_USB_OTG_VBUS_MASK()		bfin_read16(USB_OTG_VBUS_MASK)
-#define bfin_write_USB_OTG_VBUS_MASK(val)	bfin_write16(USB_OTG_VBUS_MASK, val)
-
-/* USB Phy Control Registers */
-
-#define bfin_read_USB_LINKINFO()		bfin_read16(USB_LINKINFO)
-#define bfin_write_USB_LINKINFO(val)		bfin_write16(USB_LINKINFO, val)
-#define bfin_read_USB_VPLEN()			bfin_read16(USB_VPLEN)
-#define bfin_write_USB_VPLEN(val)		bfin_write16(USB_VPLEN, val)
-#define bfin_read_USB_HS_EOF1()			bfin_read16(USB_HS_EOF1)
-#define bfin_write_USB_HS_EOF1(val)		bfin_write16(USB_HS_EOF1, val)
-#define bfin_read_USB_FS_EOF1()			bfin_read16(USB_FS_EOF1)
-#define bfin_write_USB_FS_EOF1(val)		bfin_write16(USB_FS_EOF1, val)
-#define bfin_read_USB_LS_EOF1()			bfin_read16(USB_LS_EOF1)
-#define bfin_write_USB_LS_EOF1(val)		bfin_write16(USB_LS_EOF1, val)
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CNTRL()		bfin_read16(USB_APHY_CNTRL)
-#define bfin_write_USB_APHY_CNTRL(val)		bfin_write16(USB_APHY_CNTRL, val)
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define bfin_read_USB_APHY_CALIB()		bfin_read16(USB_APHY_CALIB)
-#define bfin_write_USB_APHY_CALIB(val)		bfin_write16(USB_APHY_CALIB, val)
-#define bfin_read_USB_APHY_CNTRL2()		bfin_read16(USB_APHY_CNTRL2)
-#define bfin_write_USB_APHY_CNTRL2(val)		bfin_write16(USB_APHY_CNTRL2, val)
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define bfin_read_USB_PHY_TEST()		bfin_read16(USB_PHY_TEST)
-#define bfin_write_USB_PHY_TEST(val)		bfin_write16(USB_PHY_TEST, val)
-#define bfin_read_USB_PLLOSC_CTRL()		bfin_read16(USB_PLLOSC_CTRL)
-#define bfin_write_USB_PLLOSC_CTRL(val)		bfin_write16(USB_PLLOSC_CTRL, val)
-#define bfin_read_USB_SRP_CLKDIV()		bfin_read16(USB_SRP_CLKDIV)
-#define bfin_write_USB_SRP_CLKDIV(val)		bfin_write16(USB_SRP_CLKDIV, val)
-
-/* USB Endbfin_read_()oint 0 Control Registers */
-
-#define bfin_read_USB_EP_NI0_TXMAXP()		bfin_read16(USB_EP_NI0_TXMAXP)
-#define bfin_write_USB_EP_NI0_TXMAXP(val)	bfin_write16(USB_EP_NI0_TXMAXP, val)
-#define bfin_read_USB_EP_NI0_TXCSR()		bfin_read16(USB_EP_NI0_TXCSR)
-#define bfin_write_USB_EP_NI0_TXCSR(val)	bfin_write16(USB_EP_NI0_TXCSR, val)
-#define bfin_read_USB_EP_NI0_RXMAXP()		bfin_read16(USB_EP_NI0_RXMAXP)
-#define bfin_write_USB_EP_NI0_RXMAXP(val)	bfin_write16(USB_EP_NI0_RXMAXP, val)
-#define bfin_read_USB_EP_NI0_RXCSR()		bfin_read16(USB_EP_NI0_RXCSR)
-#define bfin_write_USB_EP_NI0_RXCSR(val)	bfin_write16(USB_EP_NI0_RXCSR, val)
-#define bfin_read_USB_EP_NI0_RXCOUNT()		bfin_read16(USB_EP_NI0_RXCOUNT)
-#define bfin_write_USB_EP_NI0_RXCOUNT(val)	bfin_write16(USB_EP_NI0_RXCOUNT, val)
-#define bfin_read_USB_EP_NI0_TXTYPE()		bfin_read16(USB_EP_NI0_TXTYPE)
-#define bfin_write_USB_EP_NI0_TXTYPE(val)	bfin_write16(USB_EP_NI0_TXTYPE, val)
-#define bfin_read_USB_EP_NI0_TXINTERVAL()	bfin_read16(USB_EP_NI0_TXINTERVAL)
-#define bfin_write_USB_EP_NI0_TXINTERVAL(val)	bfin_write16(USB_EP_NI0_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI0_RXTYPE()		bfin_read16(USB_EP_NI0_RXTYPE)
-#define bfin_write_USB_EP_NI0_RXTYPE(val)	bfin_write16(USB_EP_NI0_RXTYPE, val)
-#define bfin_read_USB_EP_NI0_RXINTERVAL()	bfin_read16(USB_EP_NI0_RXINTERVAL)
-#define bfin_write_USB_EP_NI0_RXINTERVAL(val)	bfin_write16(USB_EP_NI0_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 1 Control Registers */
-
-#define bfin_read_USB_EP_NI0_TXCOUNT()		bfin_read16(USB_EP_NI0_TXCOUNT)
-#define bfin_write_USB_EP_NI0_TXCOUNT(val)	bfin_write16(USB_EP_NI0_TXCOUNT, val)
-#define bfin_read_USB_EP_NI1_TXMAXP()		bfin_read16(USB_EP_NI1_TXMAXP)
-#define bfin_write_USB_EP_NI1_TXMAXP(val)	bfin_write16(USB_EP_NI1_TXMAXP, val)
-#define bfin_read_USB_EP_NI1_TXCSR()		bfin_read16(USB_EP_NI1_TXCSR)
-#define bfin_write_USB_EP_NI1_TXCSR(val)	bfin_write16(USB_EP_NI1_TXCSR, val)
-#define bfin_read_USB_EP_NI1_RXMAXP()		bfin_read16(USB_EP_NI1_RXMAXP)
-#define bfin_write_USB_EP_NI1_RXMAXP(val)	bfin_write16(USB_EP_NI1_RXMAXP, val)
-#define bfin_read_USB_EP_NI1_RXCSR()		bfin_read16(USB_EP_NI1_RXCSR)
-#define bfin_write_USB_EP_NI1_RXCSR(val)	bfin_write16(USB_EP_NI1_RXCSR, val)
-#define bfin_read_USB_EP_NI1_RXCOUNT()		bfin_read16(USB_EP_NI1_RXCOUNT)
-#define bfin_write_USB_EP_NI1_RXCOUNT(val)	bfin_write16(USB_EP_NI1_RXCOUNT, val)
-#define bfin_read_USB_EP_NI1_TXTYPE()		bfin_read16(USB_EP_NI1_TXTYPE)
-#define bfin_write_USB_EP_NI1_TXTYPE(val)	bfin_write16(USB_EP_NI1_TXTYPE, val)
-#define bfin_read_USB_EP_NI1_TXINTERVAL()	bfin_read16(USB_EP_NI1_TXINTERVAL)
-#define bfin_write_USB_EP_NI1_TXINTERVAL(val)	bfin_write16(USB_EP_NI1_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI1_RXTYPE()		bfin_read16(USB_EP_NI1_RXTYPE)
-#define bfin_write_USB_EP_NI1_RXTYPE(val)	bfin_write16(USB_EP_NI1_RXTYPE, val)
-#define bfin_read_USB_EP_NI1_RXINTERVAL()	bfin_read16(USB_EP_NI1_RXINTERVAL)
-#define bfin_write_USB_EP_NI1_RXINTERVAL(val)	bfin_write16(USB_EP_NI1_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 2 Control Registers */
-
-#define bfin_read_USB_EP_NI1_TXCOUNT()		bfin_read16(USB_EP_NI1_TXCOUNT)
-#define bfin_write_USB_EP_NI1_TXCOUNT(val)	bfin_write16(USB_EP_NI1_TXCOUNT, val)
-#define bfin_read_USB_EP_NI2_TXMAXP()		bfin_read16(USB_EP_NI2_TXMAXP)
-#define bfin_write_USB_EP_NI2_TXMAXP(val)	bfin_write16(USB_EP_NI2_TXMAXP, val)
-#define bfin_read_USB_EP_NI2_TXCSR()		bfin_read16(USB_EP_NI2_TXCSR)
-#define bfin_write_USB_EP_NI2_TXCSR(val)	bfin_write16(USB_EP_NI2_TXCSR, val)
-#define bfin_read_USB_EP_NI2_RXMAXP()		bfin_read16(USB_EP_NI2_RXMAXP)
-#define bfin_write_USB_EP_NI2_RXMAXP(val)	bfin_write16(USB_EP_NI2_RXMAXP, val)
-#define bfin_read_USB_EP_NI2_RXCSR()		bfin_read16(USB_EP_NI2_RXCSR)
-#define bfin_write_USB_EP_NI2_RXCSR(val)	bfin_write16(USB_EP_NI2_RXCSR, val)
-#define bfin_read_USB_EP_NI2_RXCOUNT()		bfin_read16(USB_EP_NI2_RXCOUNT)
-#define bfin_write_USB_EP_NI2_RXCOUNT(val)	bfin_write16(USB_EP_NI2_RXCOUNT, val)
-#define bfin_read_USB_EP_NI2_TXTYPE()		bfin_read16(USB_EP_NI2_TXTYPE)
-#define bfin_write_USB_EP_NI2_TXTYPE(val)	bfin_write16(USB_EP_NI2_TXTYPE, val)
-#define bfin_read_USB_EP_NI2_TXINTERVAL()	bfin_read16(USB_EP_NI2_TXINTERVAL)
-#define bfin_write_USB_EP_NI2_TXINTERVAL(val)	bfin_write16(USB_EP_NI2_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI2_RXTYPE()		bfin_read16(USB_EP_NI2_RXTYPE)
-#define bfin_write_USB_EP_NI2_RXTYPE(val)	bfin_write16(USB_EP_NI2_RXTYPE, val)
-#define bfin_read_USB_EP_NI2_RXINTERVAL()	bfin_read16(USB_EP_NI2_RXINTERVAL)
-#define bfin_write_USB_EP_NI2_RXINTERVAL(val)	bfin_write16(USB_EP_NI2_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 3 Control Registers */
-
-#define bfin_read_USB_EP_NI2_TXCOUNT()		bfin_read16(USB_EP_NI2_TXCOUNT)
-#define bfin_write_USB_EP_NI2_TXCOUNT(val)	bfin_write16(USB_EP_NI2_TXCOUNT, val)
-#define bfin_read_USB_EP_NI3_TXMAXP()		bfin_read16(USB_EP_NI3_TXMAXP)
-#define bfin_write_USB_EP_NI3_TXMAXP(val)	bfin_write16(USB_EP_NI3_TXMAXP, val)
-#define bfin_read_USB_EP_NI3_TXCSR()		bfin_read16(USB_EP_NI3_TXCSR)
-#define bfin_write_USB_EP_NI3_TXCSR(val)	bfin_write16(USB_EP_NI3_TXCSR, val)
-#define bfin_read_USB_EP_NI3_RXMAXP()		bfin_read16(USB_EP_NI3_RXMAXP)
-#define bfin_write_USB_EP_NI3_RXMAXP(val)	bfin_write16(USB_EP_NI3_RXMAXP, val)
-#define bfin_read_USB_EP_NI3_RXCSR()		bfin_read16(USB_EP_NI3_RXCSR)
-#define bfin_write_USB_EP_NI3_RXCSR(val)	bfin_write16(USB_EP_NI3_RXCSR, val)
-#define bfin_read_USB_EP_NI3_RXCOUNT()		bfin_read16(USB_EP_NI3_RXCOUNT)
-#define bfin_write_USB_EP_NI3_RXCOUNT(val)	bfin_write16(USB_EP_NI3_RXCOUNT, val)
-#define bfin_read_USB_EP_NI3_TXTYPE()		bfin_read16(USB_EP_NI3_TXTYPE)
-#define bfin_write_USB_EP_NI3_TXTYPE(val)	bfin_write16(USB_EP_NI3_TXTYPE, val)
-#define bfin_read_USB_EP_NI3_TXINTERVAL()	bfin_read16(USB_EP_NI3_TXINTERVAL)
-#define bfin_write_USB_EP_NI3_TXINTERVAL(val)	bfin_write16(USB_EP_NI3_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI3_RXTYPE()		bfin_read16(USB_EP_NI3_RXTYPE)
-#define bfin_write_USB_EP_NI3_RXTYPE(val)	bfin_write16(USB_EP_NI3_RXTYPE, val)
-#define bfin_read_USB_EP_NI3_RXINTERVAL()	bfin_read16(USB_EP_NI3_RXINTERVAL)
-#define bfin_write_USB_EP_NI3_RXINTERVAL(val)	bfin_write16(USB_EP_NI3_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 4 Control Registers */
-
-#define bfin_read_USB_EP_NI3_TXCOUNT()		bfin_read16(USB_EP_NI3_TXCOUNT)
-#define bfin_write_USB_EP_NI3_TXCOUNT(val)	bfin_write16(USB_EP_NI3_TXCOUNT, val)
-#define bfin_read_USB_EP_NI4_TXMAXP()		bfin_read16(USB_EP_NI4_TXMAXP)
-#define bfin_write_USB_EP_NI4_TXMAXP(val)	bfin_write16(USB_EP_NI4_TXMAXP, val)
-#define bfin_read_USB_EP_NI4_TXCSR()		bfin_read16(USB_EP_NI4_TXCSR)
-#define bfin_write_USB_EP_NI4_TXCSR(val)	bfin_write16(USB_EP_NI4_TXCSR, val)
-#define bfin_read_USB_EP_NI4_RXMAXP()		bfin_read16(USB_EP_NI4_RXMAXP)
-#define bfin_write_USB_EP_NI4_RXMAXP(val)	bfin_write16(USB_EP_NI4_RXMAXP, val)
-#define bfin_read_USB_EP_NI4_RXCSR()		bfin_read16(USB_EP_NI4_RXCSR)
-#define bfin_write_USB_EP_NI4_RXCSR(val)	bfin_write16(USB_EP_NI4_RXCSR, val)
-#define bfin_read_USB_EP_NI4_RXCOUNT()		bfin_read16(USB_EP_NI4_RXCOUNT)
-#define bfin_write_USB_EP_NI4_RXCOUNT(val)	bfin_write16(USB_EP_NI4_RXCOUNT, val)
-#define bfin_read_USB_EP_NI4_TXTYPE()		bfin_read16(USB_EP_NI4_TXTYPE)
-#define bfin_write_USB_EP_NI4_TXTYPE(val)	bfin_write16(USB_EP_NI4_TXTYPE, val)
-#define bfin_read_USB_EP_NI4_TXINTERVAL()	bfin_read16(USB_EP_NI4_TXINTERVAL)
-#define bfin_write_USB_EP_NI4_TXINTERVAL(val)	bfin_write16(USB_EP_NI4_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI4_RXTYPE()		bfin_read16(USB_EP_NI4_RXTYPE)
-#define bfin_write_USB_EP_NI4_RXTYPE(val)	bfin_write16(USB_EP_NI4_RXTYPE, val)
-#define bfin_read_USB_EP_NI4_RXINTERVAL()	bfin_read16(USB_EP_NI4_RXINTERVAL)
-#define bfin_write_USB_EP_NI4_RXINTERVAL(val)	bfin_write16(USB_EP_NI4_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 5 Control Registers */
-
-#define bfin_read_USB_EP_NI4_TXCOUNT()		bfin_read16(USB_EP_NI4_TXCOUNT)
-#define bfin_write_USB_EP_NI4_TXCOUNT(val)	bfin_write16(USB_EP_NI4_TXCOUNT, val)
-#define bfin_read_USB_EP_NI5_TXMAXP()		bfin_read16(USB_EP_NI5_TXMAXP)
-#define bfin_write_USB_EP_NI5_TXMAXP(val)	bfin_write16(USB_EP_NI5_TXMAXP, val)
-#define bfin_read_USB_EP_NI5_TXCSR()		bfin_read16(USB_EP_NI5_TXCSR)
-#define bfin_write_USB_EP_NI5_TXCSR(val)	bfin_write16(USB_EP_NI5_TXCSR, val)
-#define bfin_read_USB_EP_NI5_RXMAXP()		bfin_read16(USB_EP_NI5_RXMAXP)
-#define bfin_write_USB_EP_NI5_RXMAXP(val)	bfin_write16(USB_EP_NI5_RXMAXP, val)
-#define bfin_read_USB_EP_NI5_RXCSR()		bfin_read16(USB_EP_NI5_RXCSR)
-#define bfin_write_USB_EP_NI5_RXCSR(val)	bfin_write16(USB_EP_NI5_RXCSR, val)
-#define bfin_read_USB_EP_NI5_RXCOUNT()		bfin_read16(USB_EP_NI5_RXCOUNT)
-#define bfin_write_USB_EP_NI5_RXCOUNT(val)	bfin_write16(USB_EP_NI5_RXCOUNT, val)
-#define bfin_read_USB_EP_NI5_TXTYPE()		bfin_read16(USB_EP_NI5_TXTYPE)
-#define bfin_write_USB_EP_NI5_TXTYPE(val)	bfin_write16(USB_EP_NI5_TXTYPE, val)
-#define bfin_read_USB_EP_NI5_TXINTERVAL()	bfin_read16(USB_EP_NI5_TXINTERVAL)
-#define bfin_write_USB_EP_NI5_TXINTERVAL(val)	bfin_write16(USB_EP_NI5_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI5_RXTYPE()		bfin_read16(USB_EP_NI5_RXTYPE)
-#define bfin_write_USB_EP_NI5_RXTYPE(val)	bfin_write16(USB_EP_NI5_RXTYPE, val)
-#define bfin_read_USB_EP_NI5_RXINTERVAL()	bfin_read16(USB_EP_NI5_RXINTERVAL)
-#define bfin_write_USB_EP_NI5_RXINTERVAL(val)	bfin_write16(USB_EP_NI5_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 6 Control Registers */
-
-#define bfin_read_USB_EP_NI5_TXCOUNT()		bfin_read16(USB_EP_NI5_TXCOUNT)
-#define bfin_write_USB_EP_NI5_TXCOUNT(val)	bfin_write16(USB_EP_NI5_TXCOUNT, val)
-#define bfin_read_USB_EP_NI6_TXMAXP()		bfin_read16(USB_EP_NI6_TXMAXP)
-#define bfin_write_USB_EP_NI6_TXMAXP(val)	bfin_write16(USB_EP_NI6_TXMAXP, val)
-#define bfin_read_USB_EP_NI6_TXCSR()		bfin_read16(USB_EP_NI6_TXCSR)
-#define bfin_write_USB_EP_NI6_TXCSR(val)	bfin_write16(USB_EP_NI6_TXCSR, val)
-#define bfin_read_USB_EP_NI6_RXMAXP()		bfin_read16(USB_EP_NI6_RXMAXP)
-#define bfin_write_USB_EP_NI6_RXMAXP(val)	bfin_write16(USB_EP_NI6_RXMAXP, val)
-#define bfin_read_USB_EP_NI6_RXCSR()		bfin_read16(USB_EP_NI6_RXCSR)
-#define bfin_write_USB_EP_NI6_RXCSR(val)	bfin_write16(USB_EP_NI6_RXCSR, val)
-#define bfin_read_USB_EP_NI6_RXCOUNT()		bfin_read16(USB_EP_NI6_RXCOUNT)
-#define bfin_write_USB_EP_NI6_RXCOUNT(val)	bfin_write16(USB_EP_NI6_RXCOUNT, val)
-#define bfin_read_USB_EP_NI6_TXTYPE()		bfin_read16(USB_EP_NI6_TXTYPE)
-#define bfin_write_USB_EP_NI6_TXTYPE(val)	bfin_write16(USB_EP_NI6_TXTYPE, val)
-#define bfin_read_USB_EP_NI6_TXINTERVAL()	bfin_read16(USB_EP_NI6_TXINTERVAL)
-#define bfin_write_USB_EP_NI6_TXINTERVAL(val)	bfin_write16(USB_EP_NI6_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI6_RXTYPE()		bfin_read16(USB_EP_NI6_RXTYPE)
-#define bfin_write_USB_EP_NI6_RXTYPE(val)	bfin_write16(USB_EP_NI6_RXTYPE, val)
-#define bfin_read_USB_EP_NI6_RXINTERVAL()	bfin_read16(USB_EP_NI6_RXINTERVAL)
-#define bfin_write_USB_EP_NI6_RXINTERVAL(val)	bfin_write16(USB_EP_NI6_RXINTERVAL, val)
-
-/* USB Endbfin_read_()oint 7 Control Registers */
-
-#define bfin_read_USB_EP_NI6_TXCOUNT()		bfin_read16(USB_EP_NI6_TXCOUNT)
-#define bfin_write_USB_EP_NI6_TXCOUNT(val)	bfin_write16(USB_EP_NI6_TXCOUNT, val)
-#define bfin_read_USB_EP_NI7_TXMAXP()		bfin_read16(USB_EP_NI7_TXMAXP)
-#define bfin_write_USB_EP_NI7_TXMAXP(val)	bfin_write16(USB_EP_NI7_TXMAXP, val)
-#define bfin_read_USB_EP_NI7_TXCSR()		bfin_read16(USB_EP_NI7_TXCSR)
-#define bfin_write_USB_EP_NI7_TXCSR(val)	bfin_write16(USB_EP_NI7_TXCSR, val)
-#define bfin_read_USB_EP_NI7_RXMAXP()		bfin_read16(USB_EP_NI7_RXMAXP)
-#define bfin_write_USB_EP_NI7_RXMAXP(val)	bfin_write16(USB_EP_NI7_RXMAXP, val)
-#define bfin_read_USB_EP_NI7_RXCSR()		bfin_read16(USB_EP_NI7_RXCSR)
-#define bfin_write_USB_EP_NI7_RXCSR(val)	bfin_write16(USB_EP_NI7_RXCSR, val)
-#define bfin_read_USB_EP_NI7_RXCOUNT()		bfin_read16(USB_EP_NI7_RXCOUNT)
-#define bfin_write_USB_EP_NI7_RXCOUNT(val)	bfin_write16(USB_EP_NI7_RXCOUNT, val)
-#define bfin_read_USB_EP_NI7_TXTYPE()		bfin_read16(USB_EP_NI7_TXTYPE)
-#define bfin_write_USB_EP_NI7_TXTYPE(val)	bfin_write16(USB_EP_NI7_TXTYPE, val)
-#define bfin_read_USB_EP_NI7_TXINTERVAL()	bfin_read16(USB_EP_NI7_TXINTERVAL)
-#define bfin_write_USB_EP_NI7_TXINTERVAL(val)	bfin_write16(USB_EP_NI7_TXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_RXTYPE()		bfin_read16(USB_EP_NI7_RXTYPE)
-#define bfin_write_USB_EP_NI7_RXTYPE(val)	bfin_write16(USB_EP_NI7_RXTYPE, val)
-#define bfin_read_USB_EP_NI7_RXINTERVAL()	bfin_read16(USB_EP_NI7_RXINTERVAL)
-#define bfin_write_USB_EP_NI7_RXINTERVAL(val)	bfin_write16(USB_EP_NI7_RXINTERVAL, val)
-#define bfin_read_USB_EP_NI7_TXCOUNT()		bfin_read16(USB_EP_NI7_TXCOUNT)
-#define bfin_write_USB_EP_NI7_TXCOUNT(val)	bfin_write16(USB_EP_NI7_TXCOUNT, val)
-#define bfin_read_USB_DMA_INTERRUPT()		bfin_read16(USB_DMA_INTERRUPT)
-#define bfin_write_USB_DMA_INTERRUPT(val)	bfin_write16(USB_DMA_INTERRUPT, val)
-
-/* USB Channel 0 Config Registers */
-
-#define bfin_read_USB_DMA0CONTROL()		bfin_read16(USB_DMA0CONTROL)
-#define bfin_write_USB_DMA0CONTROL(val)		bfin_write16(USB_DMA0CONTROL, val)
-#define bfin_read_USB_DMA0ADDRLOW()		bfin_read16(USB_DMA0ADDRLOW)
-#define bfin_write_USB_DMA0ADDRLOW(val)		bfin_write16(USB_DMA0ADDRLOW, val)
-#define bfin_read_USB_DMA0ADDRHIGH()		bfin_read16(USB_DMA0ADDRHIGH)
-#define bfin_write_USB_DMA0ADDRHIGH(val)	bfin_write16(USB_DMA0ADDRHIGH, val)
-#define bfin_read_USB_DMA0COUNTLOW()		bfin_read16(USB_DMA0COUNTLOW)
-#define bfin_write_USB_DMA0COUNTLOW(val)	bfin_write16(USB_DMA0COUNTLOW, val)
-#define bfin_read_USB_DMA0COUNTHIGH()		bfin_read16(USB_DMA0COUNTHIGH)
-#define bfin_write_USB_DMA0COUNTHIGH(val)	bfin_write16(USB_DMA0COUNTHIGH, val)
-
-/* USB Channel 1 Config Registers */
-
-#define bfin_read_USB_DMA1CONTROL()		bfin_read16(USB_DMA1CONTROL)
-#define bfin_write_USB_DMA1CONTROL(val)		bfin_write16(USB_DMA1CONTROL, val)
-#define bfin_read_USB_DMA1ADDRLOW()		bfin_read16(USB_DMA1ADDRLOW)
-#define bfin_write_USB_DMA1ADDRLOW(val)		bfin_write16(USB_DMA1ADDRLOW, val)
-#define bfin_read_USB_DMA1ADDRHIGH()		bfin_read16(USB_DMA1ADDRHIGH)
-#define bfin_write_USB_DMA1ADDRHIGH(val)	bfin_write16(USB_DMA1ADDRHIGH, val)
-#define bfin_read_USB_DMA1COUNTLOW()		bfin_read16(USB_DMA1COUNTLOW)
-#define bfin_write_USB_DMA1COUNTLOW(val)	bfin_write16(USB_DMA1COUNTLOW, val)
-#define bfin_read_USB_DMA1COUNTHIGH()		bfin_read16(USB_DMA1COUNTHIGH)
-#define bfin_write_USB_DMA1COUNTHIGH(val)	bfin_write16(USB_DMA1COUNTHIGH, val)
-
-/* USB Channel 2 Config Registers */
-
-#define bfin_read_USB_DMA2CONTROL()		bfin_read16(USB_DMA2CONTROL)
-#define bfin_write_USB_DMA2CONTROL(val)		bfin_write16(USB_DMA2CONTROL, val)
-#define bfin_read_USB_DMA2ADDRLOW()		bfin_read16(USB_DMA2ADDRLOW)
-#define bfin_write_USB_DMA2ADDRLOW(val)		bfin_write16(USB_DMA2ADDRLOW, val)
-#define bfin_read_USB_DMA2ADDRHIGH()		bfin_read16(USB_DMA2ADDRHIGH)
-#define bfin_write_USB_DMA2ADDRHIGH(val)	bfin_write16(USB_DMA2ADDRHIGH, val)
-#define bfin_read_USB_DMA2COUNTLOW()		bfin_read16(USB_DMA2COUNTLOW)
-#define bfin_write_USB_DMA2COUNTLOW(val)	bfin_write16(USB_DMA2COUNTLOW, val)
-#define bfin_read_USB_DMA2COUNTHIGH()		bfin_read16(USB_DMA2COUNTHIGH)
-#define bfin_write_USB_DMA2COUNTHIGH(val)	bfin_write16(USB_DMA2COUNTHIGH, val)
-
-/* USB Channel 3 Config Registers */
-
-#define bfin_read_USB_DMA3CONTROL()		bfin_read16(USB_DMA3CONTROL)
-#define bfin_write_USB_DMA3CONTROL(val)		bfin_write16(USB_DMA3CONTROL, val)
-#define bfin_read_USB_DMA3ADDRLOW()		bfin_read16(USB_DMA3ADDRLOW)
-#define bfin_write_USB_DMA3ADDRLOW(val)		bfin_write16(USB_DMA3ADDRLOW, val)
-#define bfin_read_USB_DMA3ADDRHIGH()		bfin_read16(USB_DMA3ADDRHIGH)
-#define bfin_write_USB_DMA3ADDRHIGH(val)	bfin_write16(USB_DMA3ADDRHIGH, val)
-#define bfin_read_USB_DMA3COUNTLOW()		bfin_read16(USB_DMA3COUNTLOW)
-#define bfin_write_USB_DMA3COUNTLOW(val)	bfin_write16(USB_DMA3COUNTLOW, val)
-#define bfin_read_USB_DMA3COUNTHIGH()		bfin_read16(USB_DMA3COUNTHIGH)
-#define bfin_write_USB_DMA3COUNTHIGH(val)	bfin_write16(USB_DMA3COUNTHIGH, val)
-
-/* USB Channel 4 Config Registers */
-
-#define bfin_read_USB_DMA4CONTROL()		bfin_read16(USB_DMA4CONTROL)
-#define bfin_write_USB_DMA4CONTROL(val)		bfin_write16(USB_DMA4CONTROL, val)
-#define bfin_read_USB_DMA4ADDRLOW()		bfin_read16(USB_DMA4ADDRLOW)
-#define bfin_write_USB_DMA4ADDRLOW(val)		bfin_write16(USB_DMA4ADDRLOW, val)
-#define bfin_read_USB_DMA4ADDRHIGH()		bfin_read16(USB_DMA4ADDRHIGH)
-#define bfin_write_USB_DMA4ADDRHIGH(val)	bfin_write16(USB_DMA4ADDRHIGH, val)
-#define bfin_read_USB_DMA4COUNTLOW()		bfin_read16(USB_DMA4COUNTLOW)
-#define bfin_write_USB_DMA4COUNTLOW(val)	bfin_write16(USB_DMA4COUNTLOW, val)
-#define bfin_read_USB_DMA4COUNTHIGH()		bfin_read16(USB_DMA4COUNTHIGH)
-#define bfin_write_USB_DMA4COUNTHIGH(val)	bfin_write16(USB_DMA4COUNTHIGH, val)
-
-/* USB Channel 5 Config Registers */
-
-#define bfin_read_USB_DMA5CONTROL()		bfin_read16(USB_DMA5CONTROL)
-#define bfin_write_USB_DMA5CONTROL(val)		bfin_write16(USB_DMA5CONTROL, val)
-#define bfin_read_USB_DMA5ADDRLOW()		bfin_read16(USB_DMA5ADDRLOW)
-#define bfin_write_USB_DMA5ADDRLOW(val)		bfin_write16(USB_DMA5ADDRLOW, val)
-#define bfin_read_USB_DMA5ADDRHIGH()		bfin_read16(USB_DMA5ADDRHIGH)
-#define bfin_write_USB_DMA5ADDRHIGH(val)		bfin_write16(USB_DMA5ADDRHIGH, val)
-#define bfin_read_USB_DMA5COUNTLOW()		bfin_read16(USB_DMA5COUNTLOW)
-#define bfin_write_USB_DMA5COUNTLOW(val)	bfin_write16(USB_DMA5COUNTLOW, val)
-#define bfin_read_USB_DMA5COUNTHIGH()		bfin_read16(USB_DMA5COUNTHIGH)
-#define bfin_write_USB_DMA5COUNTHIGH(val)	bfin_write16(USB_DMA5COUNTHIGH, val)
-
-/* USB Channel 6 Config Registers */
-
-#define bfin_read_USB_DMA6CONTROL()		bfin_read16(USB_DMA6CONTROL)
-#define bfin_write_USB_DMA6CONTROL(val)		bfin_write16(USB_DMA6CONTROL, val)
-#define bfin_read_USB_DMA6ADDRLOW()		bfin_read16(USB_DMA6ADDRLOW)
-#define bfin_write_USB_DMA6ADDRLOW(val)		bfin_write16(USB_DMA6ADDRLOW, val)
-#define bfin_read_USB_DMA6ADDRHIGH()		bfin_read16(USB_DMA6ADDRHIGH)
-#define bfin_write_USB_DMA6ADDRHIGH(val)	bfin_write16(USB_DMA6ADDRHIGH, val)
-#define bfin_read_USB_DMA6COUNTLOW()		bfin_read16(USB_DMA6COUNTLOW)
-#define bfin_write_USB_DMA6COUNTLOW(val)	bfin_write16(USB_DMA6COUNTLOW, val)
-#define bfin_read_USB_DMA6COUNTHIGH()		bfin_read16(USB_DMA6COUNTHIGH)
-#define bfin_write_USB_DMA6COUNTHIGH(val)	bfin_write16(USB_DMA6COUNTHIGH, val)
-
-/* USB Channel 7 Config Registers */
-
-#define bfin_read_USB_DMA7CONTROL()		bfin_read16(USB_DMA7CONTROL)
-#define bfin_write_USB_DMA7CONTROL(val)		bfin_write16(USB_DMA7CONTROL, val)
-#define bfin_read_USB_DMA7ADDRLOW()		bfin_read16(USB_DMA7ADDRLOW)
-#define bfin_write_USB_DMA7ADDRLOW(val)		bfin_write16(USB_DMA7ADDRLOW, val)
-#define bfin_read_USB_DMA7ADDRHIGH()		bfin_read16(USB_DMA7ADDRHIGH)
-#define bfin_write_USB_DMA7ADDRHIGH(val)	bfin_write16(USB_DMA7ADDRHIGH, val)
-#define bfin_read_USB_DMA7COUNTLOW()		bfin_read16(USB_DMA7COUNTLOW)
-#define bfin_write_USB_DMA7COUNTLOW(val)	bfin_write16(USB_DMA7COUNTLOW, val)
-#define bfin_read_USB_DMA7COUNTHIGH()		bfin_read16(USB_DMA7COUNTHIGH)
-#define bfin_write_USB_DMA7COUNTHIGH(val)	bfin_write16(USB_DMA7COUNTHIGH, val)
-
-/* Keybfin_read_()ad Registers */
-
-#define bfin_read_KPAD_CTL()		bfin_read16(KPAD_CTL)
-#define bfin_write_KPAD_CTL(val)	bfin_write16(KPAD_CTL, val)
-#define bfin_read_KPAD_PRESCALE()	bfin_read16(KPAD_PRESCALE)
-#define bfin_write_KPAD_PRESCALE(val)	bfin_write16(KPAD_PRESCALE, val)
-#define bfin_read_KPAD_MSEL()		bfin_read16(KPAD_MSEL)
-#define bfin_write_KPAD_MSEL(val)	bfin_write16(KPAD_MSEL, val)
-#define bfin_read_KPAD_ROWCOL()		bfin_read16(KPAD_ROWCOL)
-#define bfin_write_KPAD_ROWCOL(val)	bfin_write16(KPAD_ROWCOL, val)
-#define bfin_read_KPAD_STAT()		bfin_read16(KPAD_STAT)
-#define bfin_write_KPAD_STAT(val)	bfin_write16(KPAD_STAT, val)
-#define bfin_read_KPAD_SOFTEVAL()	bfin_read16(KPAD_SOFTEVAL)
-#define bfin_write_KPAD_SOFTEVAL(val)	bfin_write16(KPAD_SOFTEVAL, val)
-
-/* Pixel Combfin_read_()ositor (PIXC) Registers */
-
-#define bfin_read_PIXC_CTL()		bfin_read16(PIXC_CTL)
-#define bfin_write_PIXC_CTL(val)	bfin_write16(PIXC_CTL, val)
-#define bfin_read_PIXC_PPL()		bfin_read16(PIXC_PPL)
-#define bfin_write_PIXC_PPL(val)	bfin_write16(PIXC_PPL, val)
-#define bfin_read_PIXC_LPF()		bfin_read16(PIXC_LPF)
-#define bfin_write_PIXC_LPF(val)	bfin_write16(PIXC_LPF, val)
-#define bfin_read_PIXC_AHSTART()	bfin_read16(PIXC_AHSTART)
-#define bfin_write_PIXC_AHSTART(val)	bfin_write16(PIXC_AHSTART, val)
-#define bfin_read_PIXC_AHEND()		bfin_read16(PIXC_AHEND)
-#define bfin_write_PIXC_AHEND(val)	bfin_write16(PIXC_AHEND, val)
-#define bfin_read_PIXC_AVSTART()	bfin_read16(PIXC_AVSTART)
-#define bfin_write_PIXC_AVSTART(val)	bfin_write16(PIXC_AVSTART, val)
-#define bfin_read_PIXC_AVEND()		bfin_read16(PIXC_AVEND)
-#define bfin_write_PIXC_AVEND(val)	bfin_write16(PIXC_AVEND, val)
-#define bfin_read_PIXC_ATRANSP()	bfin_read16(PIXC_ATRANSP)
-#define bfin_write_PIXC_ATRANSP(val)	bfin_write16(PIXC_ATRANSP, val)
-#define bfin_read_PIXC_BHSTART()	bfin_read16(PIXC_BHSTART)
-#define bfin_write_PIXC_BHSTART(val)	bfin_write16(PIXC_BHSTART, val)
-#define bfin_read_PIXC_BHEND()		bfin_read16(PIXC_BHEND)
-#define bfin_write_PIXC_BHEND(val)	bfin_write16(PIXC_BHEND, val)
-#define bfin_read_PIXC_BVSTART()	bfin_read16(PIXC_BVSTART)
-#define bfin_write_PIXC_BVSTART(val)	bfin_write16(PIXC_BVSTART, val)
-#define bfin_read_PIXC_BVEND()		bfin_read16(PIXC_BVEND)
-#define bfin_write_PIXC_BVEND(val)	bfin_write16(PIXC_BVEND, val)
-#define bfin_read_PIXC_BTRANSP()	bfin_read16(PIXC_BTRANSP)
-#define bfin_write_PIXC_BTRANSP(val)	bfin_write16(PIXC_BTRANSP, val)
-#define bfin_read_PIXC_INTRSTAT()	bfin_read16(PIXC_INTRSTAT)
-#define bfin_write_PIXC_INTRSTAT(val)	bfin_write16(PIXC_INTRSTAT, val)
-#define bfin_read_PIXC_RYCON()		bfin_read32(PIXC_RYCON)
-#define bfin_write_PIXC_RYCON(val)	bfin_write32(PIXC_RYCON, val)
-#define bfin_read_PIXC_GUCON()		bfin_read32(PIXC_GUCON)
-#define bfin_write_PIXC_GUCON(val)	bfin_write32(PIXC_GUCON, val)
-#define bfin_read_PIXC_BVCON()		bfin_read32(PIXC_BVCON)
-#define bfin_write_PIXC_BVCON(val)	bfin_write32(PIXC_BVCON, val)
-#define bfin_read_PIXC_CCBIAS()		bfin_read32(PIXC_CCBIAS)
-#define bfin_write_PIXC_CCBIAS(val)	bfin_write32(PIXC_CCBIAS, val)
-#define bfin_read_PIXC_TC()		bfin_read32(PIXC_TC)
-#define bfin_write_PIXC_TC(val)		bfin_write32(PIXC_TC, val)
-
-/* Handshake MDMA 0 Registers */
-
-#define bfin_read_HMDMA0_CONTROL()		bfin_read16(HMDMA0_CONTROL)
-#define bfin_write_HMDMA0_CONTROL(val)		bfin_write16(HMDMA0_CONTROL, val)
-#define bfin_read_HMDMA0_ECINIT()		bfin_read16(HMDMA0_ECINIT)
-#define bfin_write_HMDMA0_ECINIT(val)		bfin_write16(HMDMA0_ECINIT, val)
-#define bfin_read_HMDMA0_BCINIT()		bfin_read16(HMDMA0_BCINIT)
-#define bfin_write_HMDMA0_BCINIT(val)		bfin_write16(HMDMA0_BCINIT, val)
-#define bfin_read_HMDMA0_ECURGENT()		bfin_read16(HMDMA0_ECURGENT)
-#define bfin_write_HMDMA0_ECURGENT(val)		bfin_write16(HMDMA0_ECURGENT, val)
-#define bfin_read_HMDMA0_ECOVERFLOW()		bfin_read16(HMDMA0_ECOVERFLOW)
-#define bfin_write_HMDMA0_ECOVERFLOW(val)	bfin_write16(HMDMA0_ECOVERFLOW, val)
-#define bfin_read_HMDMA0_ECOUNT()		bfin_read16(HMDMA0_ECOUNT)
-#define bfin_write_HMDMA0_ECOUNT(val)		bfin_write16(HMDMA0_ECOUNT, val)
-#define bfin_read_HMDMA0_BCOUNT()		bfin_read16(HMDMA0_BCOUNT)
-#define bfin_write_HMDMA0_BCOUNT(val)		bfin_write16(HMDMA0_BCOUNT, val)
-
-/* Handshake MDMA 1 Registers */
-
-#define bfin_read_HMDMA1_CONTROL()		bfin_read16(HMDMA1_CONTROL)
-#define bfin_write_HMDMA1_CONTROL(val)		bfin_write16(HMDMA1_CONTROL, val)
-#define bfin_read_HMDMA1_ECINIT()		bfin_read16(HMDMA1_ECINIT)
-#define bfin_write_HMDMA1_ECINIT(val)		bfin_write16(HMDMA1_ECINIT, val)
-#define bfin_read_HMDMA1_BCINIT()		bfin_read16(HMDMA1_BCINIT)
-#define bfin_write_HMDMA1_BCINIT(val)		bfin_write16(HMDMA1_BCINIT, val)
-#define bfin_read_HMDMA1_ECURGENT()		bfin_read16(HMDMA1_ECURGENT)
-#define bfin_write_HMDMA1_ECURGENT(val)		bfin_write16(HMDMA1_ECURGENT, val)
-#define bfin_read_HMDMA1_ECOVERFLOW()		bfin_read16(HMDMA1_ECOVERFLOW)
-#define bfin_write_HMDMA1_ECOVERFLOW(val)	bfin_write16(HMDMA1_ECOVERFLOW, val)
-#define bfin_read_HMDMA1_ECOUNT()		bfin_read16(HMDMA1_ECOUNT)
-#define bfin_write_HMDMA1_ECOUNT(val)		bfin_write16(HMDMA1_ECOUNT, val)
-#define bfin_read_HMDMA1_BCOUNT()		bfin_read16(HMDMA1_BCOUNT)
-#define bfin_write_HMDMA1_BCOUNT(val)		bfin_write16(HMDMA1_BCOUNT, val)
-
 #endif /* _CDEF_BF549_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -2615,17 +2615,6 @@
 #define bfin_read_CNT_MIN()		bfin_read32(CNT_MIN)
 #define bfin_write_CNT_MIN(val)		bfin_write32(CNT_MIN, val)
 
-/* OTP/FUSE Registers */
-
-#define bfin_read_OTP_CONTROL()		bfin_read16(OTP_CONTROL)
-#define bfin_write_OTP_CONTROL(val)	bfin_write16(OTP_CONTROL, val)
-#define bfin_read_OTP_BEN()		bfin_read16(OTP_BEN)
-#define bfin_write_OTP_BEN(val)		bfin_write16(OTP_BEN, val)
-#define bfin_read_OTP_STATUS()		bfin_read16(OTP_STATUS)
-#define bfin_write_OTP_STATUS(val)	bfin_write16(OTP_STATUS, val)
-#define bfin_read_OTP_TIMING()		bfin_read32(OTP_TIMING)
-#define bfin_write_OTP_TIMING(val)	bfin_write32(OTP_TIMING, val)
-
 /* Security Registers */
 
 #define bfin_read_SECURE_SYSSWT()	bfin_read32(SECURE_SYSSWT)
@@ -2640,17 +2629,6 @@
 #define bfin_read_DMAC1_PERIMUX()	bfin_read16(DMAC1_PERIMUX)
 #define bfin_write_DMAC1_PERIMUX(val)	bfin_write16(DMAC1_PERIMUX, val)
 
-/* OTP Read/Write Data Buffer Registers */
-
-#define bfin_read_OTP_DATA0()		bfin_read32(OTP_DATA0)
-#define bfin_write_OTP_DATA0(val)	bfin_write32(OTP_DATA0, val)
-#define bfin_read_OTP_DATA1()		bfin_read32(OTP_DATA1)
-#define bfin_write_OTP_DATA1(val)	bfin_write32(OTP_DATA1, val)
-#define bfin_read_OTP_DATA2()		bfin_read32(OTP_DATA2)
-#define bfin_write_OTP_DATA2(val)	bfin_write32(OTP_DATA2, val)
-#define bfin_read_OTP_DATA3()		bfin_read32(OTP_DATA3)
-#define bfin_write_OTP_DATA3(val)	bfin_write32(OTP_DATA3, val)
-
 /* Handshake MDMA is not defined in the shared file because it is not available on the ADSP-BF542 bfin_read_()rocessor */
 
 /* legacy definitions */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF544.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF544.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF544.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF544.h	2010-02-24 13:52:17.000000000 -0500
@@ -491,7 +491,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -501,7 +501,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
@@ -624,9 +624,9 @@
 #define                 DMA_READY  0x1        /* DMA Ready */
 #define                  FIFOFULL  0x2        /* FIFO Full */
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                  COMPLETE  0x8        /* DMA Complete */
+#define              DMA_COMPLETE  0x8        /* DMA Complete */
 #define                      HSHK  0x10       /* Host Handshake */
-#define                   TIMEOUT  0x20       /* Host Timeout */
+#define                 HSTIMEOUT  0x20       /* Host Timeout */
 #define                      HIRQ  0x40       /* Host Interrupt Request */
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
 #define                   DMA_DIR  0x100      /* DMA Direction */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF547.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF547.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF547.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF547.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,18 +4,18 @@
  * Licensed under the ADI BSD license or the GPL-2 (or later)
  */
 
-#ifndef _DEF_BF548_H
-#define _DEF_BF548_H
+#ifndef _DEF_BF547_H
+#define _DEF_BF547_H
 
 /* Include all Core registers and bit definitions */
 #include <asm/def_LPBlackfin.h>
 
-/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */
+/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */
 
 /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
 #include "defBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF548 that are not in the common header */
+/* The following are the #defines needed by ADSP-BF547 that are not in the common header */
 
 /* Timer Registers */
 
@@ -470,7 +470,7 @@
 #define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
 #define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
 #define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
+#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshold Register */
 #define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
 #define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
 #define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
@@ -480,7 +480,7 @@
 #define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
 #define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
 #define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
+#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshold Register */
 #define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
 #define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
 #define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
@@ -1217,4 +1217,4 @@
 /* ******************************************* */
 
 
-#endif /* _DEF_BF548_H */
+#endif /* _DEF_BF547_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF548.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF548.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF548.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF548.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,115 +15,8 @@
 /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
 #include "defBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF548 that are not in the common header */
-
-/* Timer Registers */
-
-#define                    TIMER8_CONFIG  0xffc00600   /* Timer 8 Configuration Register */
-#define                   TIMER8_COUNTER  0xffc00604   /* Timer 8 Counter Register */
-#define                    TIMER8_PERIOD  0xffc00608   /* Timer 8 Period Register */
-#define                     TIMER8_WIDTH  0xffc0060c   /* Timer 8 Width Register */
-#define                    TIMER9_CONFIG  0xffc00610   /* Timer 9 Configuration Register */
-#define                   TIMER9_COUNTER  0xffc00614   /* Timer 9 Counter Register */
-#define                    TIMER9_PERIOD  0xffc00618   /* Timer 9 Period Register */
-#define                     TIMER9_WIDTH  0xffc0061c   /* Timer 9 Width Register */
-#define                   TIMER10_CONFIG  0xffc00620   /* Timer 10 Configuration Register */
-#define                  TIMER10_COUNTER  0xffc00624   /* Timer 10 Counter Register */
-#define                   TIMER10_PERIOD  0xffc00628   /* Timer 10 Period Register */
-#define                    TIMER10_WIDTH  0xffc0062c   /* Timer 10 Width Register */
-
-/* Timer Group of 3 Registers */
-
-#define                    TIMER_ENABLE1  0xffc00640   /* Timer Group of 3 Enable Register */
-#define                   TIMER_DISABLE1  0xffc00644   /* Timer Group of 3 Disable Register */
-#define                    TIMER_STATUS1  0xffc00648   /* Timer Group of 3 Status Register */
-
-/* SPORT0 Registers */
-
-#define                      SPORT0_TCR1  0xffc00800   /* SPORT0 Transmit Configuration 1 Register */
-#define                      SPORT0_TCR2  0xffc00804   /* SPORT0 Transmit Configuration 2 Register */
-#define                   SPORT0_TCLKDIV  0xffc00808   /* SPORT0 Transmit Serial Clock Divider Register */
-#define                    SPORT0_TFSDIV  0xffc0080c   /* SPORT0 Transmit Frame Sync Divider Register */
-#define                        SPORT0_TX  0xffc00810   /* SPORT0 Transmit Data Register */
-#define                        SPORT0_RX  0xffc00818   /* SPORT0 Receive Data Register */
-#define                      SPORT0_RCR1  0xffc00820   /* SPORT0 Receive Configuration 1 Register */
-#define                      SPORT0_RCR2  0xffc00824   /* SPORT0 Receive Configuration 2 Register */
-#define                   SPORT0_RCLKDIV  0xffc00828   /* SPORT0 Receive Serial Clock Divider Register */
-#define                    SPORT0_RFSDIV  0xffc0082c   /* SPORT0 Receive Frame Sync Divider Register */
-#define                      SPORT0_STAT  0xffc00830   /* SPORT0 Status Register */
-#define                      SPORT0_CHNL  0xffc00834   /* SPORT0 Current Channel Register */
-#define                     SPORT0_MCMC1  0xffc00838   /* SPORT0 Multi channel Configuration Register 1 */
-#define                     SPORT0_MCMC2  0xffc0083c   /* SPORT0 Multi channel Configuration Register 2 */
-#define                     SPORT0_MTCS0  0xffc00840   /* SPORT0 Multi channel Transmit Select Register 0 */
-#define                     SPORT0_MTCS1  0xffc00844   /* SPORT0 Multi channel Transmit Select Register 1 */
-#define                     SPORT0_MTCS2  0xffc00848   /* SPORT0 Multi channel Transmit Select Register 2 */
-#define                     SPORT0_MTCS3  0xffc0084c   /* SPORT0 Multi channel Transmit Select Register 3 */
-#define                     SPORT0_MRCS0  0xffc00850   /* SPORT0 Multi channel Receive Select Register 0 */
-#define                     SPORT0_MRCS1  0xffc00854   /* SPORT0 Multi channel Receive Select Register 1 */
-#define                     SPORT0_MRCS2  0xffc00858   /* SPORT0 Multi channel Receive Select Register 2 */
-#define                     SPORT0_MRCS3  0xffc0085c   /* SPORT0 Multi channel Receive Select Register 3 */
-
-/* EPPI0 Registers */
-
-#define                     EPPI0_STATUS  0xffc01000   /* EPPI0 Status Register */
-#define                     EPPI0_HCOUNT  0xffc01004   /* EPPI0 Horizontal Transfer Count Register */
-#define                     EPPI0_HDELAY  0xffc01008   /* EPPI0 Horizontal Delay Count Register */
-#define                     EPPI0_VCOUNT  0xffc0100c   /* EPPI0 Vertical Transfer Count Register */
-#define                     EPPI0_VDELAY  0xffc01010   /* EPPI0 Vertical Delay Count Register */
-#define                      EPPI0_FRAME  0xffc01014   /* EPPI0 Lines per Frame Register */
-#define                       EPPI0_LINE  0xffc01018   /* EPPI0 Samples per Line Register */
-#define                     EPPI0_CLKDIV  0xffc0101c   /* EPPI0 Clock Divide Register */
-#define                    EPPI0_CONTROL  0xffc01020   /* EPPI0 Control Register */
-#define                   EPPI0_FS1W_HBL  0xffc01024   /* EPPI0 FS1 Width Register / EPPI0 Horizontal Blanking Samples Per Line Register */
-#define                  EPPI0_FS1P_AVPL  0xffc01028   /* EPPI0 FS1 Period Register / EPPI0 Active Video Samples Per Line Register */
-#define                   EPPI0_FS2W_LVB  0xffc0102c   /* EPPI0 FS2 Width Register / EPPI0 Lines of Vertical Blanking Register */
-#define                  EPPI0_FS2P_LAVF  0xffc01030   /* EPPI0 FS2 Period Register/ EPPI0 Lines of Active Video Per Field Register */
-#define                       EPPI0_CLIP  0xffc01034   /* EPPI0 Clipping Register */
-
-/* UART2 Registers */
-
-#define                        UART2_DLL  0xffc02100   /* Divisor Latch Low Byte */
-#define                        UART2_DLH  0xffc02104   /* Divisor Latch High Byte */
-#define                       UART2_GCTL  0xffc02108   /* Global Control Register */
-#define                        UART2_LCR  0xffc0210c   /* Line Control Register */
-#define                        UART2_MCR  0xffc02110   /* Modem Control Register */
-#define                        UART2_LSR  0xffc02114   /* Line Status Register */
-#define                        UART2_MSR  0xffc02118   /* Modem Status Register */
-#define                        UART2_SCR  0xffc0211c   /* Scratch Register */
-#define                    UART2_IER_SET  0xffc02120   /* Interrupt Enable Register Set */
-#define                  UART2_IER_CLEAR  0xffc02124   /* Interrupt Enable Register Clear */
-#define                        UART2_RBR  0xffc0212c   /* Receive Buffer Register */
-
-/* Two Wire Interface Registers (TWI1) */
-
-#define                     TWI1_REGBASE  0xffc02200
-#define                      TWI1_CLKDIV  0xffc02200   /* Clock Divider Register */
-#define                     TWI1_CONTROL  0xffc02204   /* TWI Control Register */
-#define                  TWI1_SLAVE_CTRL  0xffc02208   /* TWI Slave Mode Control Register */
-#define                  TWI1_SLAVE_STAT  0xffc0220c   /* TWI Slave Mode Status Register */
-#define                  TWI1_SLAVE_ADDR  0xffc02210   /* TWI Slave Mode Address Register */
-#define                 TWI1_MASTER_CTRL  0xffc02214   /* TWI Master Mode Control Register */
-#define                 TWI1_MASTER_STAT  0xffc02218   /* TWI Master Mode Status Register */
-#define                 TWI1_MASTER_ADDR  0xffc0221c   /* TWI Master Mode Address Register */
-#define                    TWI1_INT_STAT  0xffc02220   /* TWI Interrupt Status Register */
-#define                    TWI1_INT_MASK  0xffc02224   /* TWI Interrupt Mask Register */
-#define                   TWI1_FIFO_CTRL  0xffc02228   /* TWI FIFO Control Register */
-#define                   TWI1_FIFO_STAT  0xffc0222c   /* TWI FIFO Status Register */
-#define                   TWI1_XMT_DATA8  0xffc02280   /* TWI FIFO Transmit Data Single Byte Register */
-#define                  TWI1_XMT_DATA16  0xffc02284   /* TWI FIFO Transmit Data Double Byte Register */
-#define                   TWI1_RCV_DATA8  0xffc02288   /* TWI FIFO Receive Data Single Byte Register */
-#define                  TWI1_RCV_DATA16  0xffc0228c   /* TWI FIFO Receive Data Double Byte Register */
-
-/* SPI2  Registers */
-
-#define                     SPI2_REGBASE  0xffc02400
-#define                         SPI2_CTL  0xffc02400   /* SPI2 Control Register */
-#define                         SPI2_FLG  0xffc02404   /* SPI2 Flag Register */
-#define                        SPI2_STAT  0xffc02408   /* SPI2 Status Register */
-#define                        SPI2_TDBR  0xffc0240c   /* SPI2 Transmit Data Buffer Register */
-#define                        SPI2_RDBR  0xffc02410   /* SPI2 Receive Data Buffer Register */
-#define                        SPI2_BAUD  0xffc02414   /* SPI2 Baud Rate Register */
-#define                      SPI2_SHADOW  0xffc02418   /* SPI2 Receive Data Buffer Shadow Register */
+/* The BF548 is like the BF547, but has additional CANs */
+#include "defBF547.h"
 
 /* CAN Controller 1 Config 1 Registers */
 
@@ -508,1096 +401,4 @@
 #define                    CAN1_MB31_ID0  0xffc037f8   /* CAN Controller 1 Mailbox 31 ID0 Register */
 #define                    CAN1_MB31_ID1  0xffc037fc   /* CAN Controller 1 Mailbox 31 ID1 Register */
 
-/* ATAPI Registers */
-
-#define                    ATAPI_CONTROL  0xffc03800   /* ATAPI Control Register */
-#define                     ATAPI_STATUS  0xffc03804   /* ATAPI Status Register */
-#define                   ATAPI_DEV_ADDR  0xffc03808   /* ATAPI Device Register Address */
-#define                  ATAPI_DEV_TXBUF  0xffc0380c   /* ATAPI Device Register Write Data */
-#define                  ATAPI_DEV_RXBUF  0xffc03810   /* ATAPI Device Register Read Data */
-#define                   ATAPI_INT_MASK  0xffc03814   /* ATAPI Interrupt Mask Register */
-#define                 ATAPI_INT_STATUS  0xffc03818   /* ATAPI Interrupt Status Register */
-#define                   ATAPI_XFER_LEN  0xffc0381c   /* ATAPI Length of Transfer */
-#define                ATAPI_LINE_STATUS  0xffc03820   /* ATAPI Line Status */
-#define                   ATAPI_SM_STATE  0xffc03824   /* ATAPI State Machine Status */
-#define                  ATAPI_TERMINATE  0xffc03828   /* ATAPI Host Terminate */
-#define                 ATAPI_PIO_TFRCNT  0xffc0382c   /* ATAPI PIO mode transfer count */
-#define                 ATAPI_DMA_TFRCNT  0xffc03830   /* ATAPI DMA mode transfer count */
-#define               ATAPI_UMAIN_TFRCNT  0xffc03834   /* ATAPI UDMAIN transfer count */
-#define             ATAPI_UDMAOUT_TFRCNT  0xffc03838   /* ATAPI UDMAOUT transfer count */
-#define                  ATAPI_REG_TIM_0  0xffc03840   /* ATAPI Register Transfer Timing 0 */
-#define                  ATAPI_PIO_TIM_0  0xffc03844   /* ATAPI PIO Timing 0 Register */
-#define                  ATAPI_PIO_TIM_1  0xffc03848   /* ATAPI PIO Timing 1 Register */
-#define                ATAPI_MULTI_TIM_0  0xffc03850   /* ATAPI Multi-DMA Timing 0 Register */
-#define                ATAPI_MULTI_TIM_1  0xffc03854   /* ATAPI Multi-DMA Timing 1 Register */
-#define                ATAPI_MULTI_TIM_2  0xffc03858   /* ATAPI Multi-DMA Timing 2 Register */
-#define                ATAPI_ULTRA_TIM_0  0xffc03860   /* ATAPI Ultra-DMA Timing 0 Register */
-#define                ATAPI_ULTRA_TIM_1  0xffc03864   /* ATAPI Ultra-DMA Timing 1 Register */
-#define                ATAPI_ULTRA_TIM_2  0xffc03868   /* ATAPI Ultra-DMA Timing 2 Register */
-#define                ATAPI_ULTRA_TIM_3  0xffc0386c   /* ATAPI Ultra-DMA Timing 3 Register */
-
-/* SDH Registers */
-
-#define                      SDH_PWR_CTL  0xffc03900   /* SDH Power Control */
-#define                      SDH_CLK_CTL  0xffc03904   /* SDH Clock Control */
-#define                     SDH_ARGUMENT  0xffc03908   /* SDH Argument */
-#define                      SDH_COMMAND  0xffc0390c   /* SDH Command */
-#define                     SDH_RESP_CMD  0xffc03910   /* SDH Response Command */
-#define                    SDH_RESPONSE0  0xffc03914   /* SDH Response0 */
-#define                    SDH_RESPONSE1  0xffc03918   /* SDH Response1 */
-#define                    SDH_RESPONSE2  0xffc0391c   /* SDH Response2 */
-#define                    SDH_RESPONSE3  0xffc03920   /* SDH Response3 */
-#define                   SDH_DATA_TIMER  0xffc03924   /* SDH Data Timer */
-#define                    SDH_DATA_LGTH  0xffc03928   /* SDH Data Length */
-#define                     SDH_DATA_CTL  0xffc0392c   /* SDH Data Control */
-#define                     SDH_DATA_CNT  0xffc03930   /* SDH Data Counter */
-#define                       SDH_STATUS  0xffc03934   /* SDH Status */
-#define                   SDH_STATUS_CLR  0xffc03938   /* SDH Status Clear */
-#define                        SDH_MASK0  0xffc0393c   /* SDH Interrupt0 Mask */
-#define                        SDH_MASK1  0xffc03940   /* SDH Interrupt1 Mask */
-#define                     SDH_FIFO_CNT  0xffc03948   /* SDH FIFO Counter */
-#define                         SDH_FIFO  0xffc03980   /* SDH Data FIFO */
-#define                     SDH_E_STATUS  0xffc039c0   /* SDH Exception Status */
-#define                       SDH_E_MASK  0xffc039c4   /* SDH Exception Mask */
-#define                          SDH_CFG  0xffc039c8   /* SDH Configuration */
-#define                   SDH_RD_WAIT_EN  0xffc039cc   /* SDH Read Wait Enable */
-#define                         SDH_PID0  0xffc039d0   /* SDH Peripheral Identification0 */
-#define                         SDH_PID1  0xffc039d4   /* SDH Peripheral Identification1 */
-#define                         SDH_PID2  0xffc039d8   /* SDH Peripheral Identification2 */
-#define                         SDH_PID3  0xffc039dc   /* SDH Peripheral Identification3 */
-#define                         SDH_PID4  0xffc039e0   /* SDH Peripheral Identification4 */
-#define                         SDH_PID5  0xffc039e4   /* SDH Peripheral Identification5 */
-#define                         SDH_PID6  0xffc039e8   /* SDH Peripheral Identification6 */
-#define                         SDH_PID7  0xffc039ec   /* SDH Peripheral Identification7 */
-
-/* HOST Port Registers */
-
-#define                     HOST_CONTROL  0xffc03a00   /* HOST Control Register */
-#define                      HOST_STATUS  0xffc03a04   /* HOST Status Register */
-#define                     HOST_TIMEOUT  0xffc03a08   /* HOST Acknowledge Mode Timeout Register */
-
-/* USB Control Registers */
-
-#define                        USB_FADDR  0xffc03c00   /* Function address register */
-#define                        USB_POWER  0xffc03c04   /* Power management register */
-#define                       USB_INTRTX  0xffc03c08   /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */
-#define                       USB_INTRRX  0xffc03c0c   /* Interrupt register for Rx endpoints 1 to 7 */
-#define                      USB_INTRTXE  0xffc03c10   /* Interrupt enable register for IntrTx */
-#define                      USB_INTRRXE  0xffc03c14   /* Interrupt enable register for IntrRx */
-#define                      USB_INTRUSB  0xffc03c18   /* Interrupt register for common USB interrupts */
-#define                     USB_INTRUSBE  0xffc03c1c   /* Interrupt enable register for IntrUSB */
-#define                        USB_FRAME  0xffc03c20   /* USB frame number */
-#define                        USB_INDEX  0xffc03c24   /* Index register for selecting the indexed endpoint registers */
-#define                     USB_TESTMODE  0xffc03c28   /* Enabled USB 20 test modes */
-#define                     USB_GLOBINTR  0xffc03c2c   /* Global Interrupt Mask register and Wakeup Exception Interrupt */
-#define                   USB_GLOBAL_CTL  0xffc03c30   /* Global Clock Control for the core */
-
-/* USB Packet Control Registers */
-
-#define                USB_TX_MAX_PACKET  0xffc03c40   /* Maximum packet size for Host Tx endpoint */
-#define                         USB_CSR0  0xffc03c44   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                        USB_TXCSR  0xffc03c44   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                USB_RX_MAX_PACKET  0xffc03c48   /* Maximum packet size for Host Rx endpoint */
-#define                        USB_RXCSR  0xffc03c4c   /* Control Status register for Host Rx endpoint */
-#define                       USB_COUNT0  0xffc03c50   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                      USB_RXCOUNT  0xffc03c50   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                       USB_TXTYPE  0xffc03c54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */
-#define                    USB_NAKLIMIT0  0xffc03c58   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                   USB_TXINTERVAL  0xffc03c58   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                       USB_RXTYPE  0xffc03c5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */
-#define                   USB_RXINTERVAL  0xffc03c60   /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */
-#define                      USB_TXCOUNT  0xffc03c68   /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* USB Endpoint FIFO Registers */
-
-#define                     USB_EP0_FIFO  0xffc03c80   /* Endpoint 0 FIFO */
-#define                     USB_EP1_FIFO  0xffc03c88   /* Endpoint 1 FIFO */
-#define                     USB_EP2_FIFO  0xffc03c90   /* Endpoint 2 FIFO */
-#define                     USB_EP3_FIFO  0xffc03c98   /* Endpoint 3 FIFO */
-#define                     USB_EP4_FIFO  0xffc03ca0   /* Endpoint 4 FIFO */
-#define                     USB_EP5_FIFO  0xffc03ca8   /* Endpoint 5 FIFO */
-#define                     USB_EP6_FIFO  0xffc03cb0   /* Endpoint 6 FIFO */
-#define                     USB_EP7_FIFO  0xffc03cb8   /* Endpoint 7 FIFO */
-
-/* USB OTG Control Registers */
-
-#define                  USB_OTG_DEV_CTL  0xffc03d00   /* OTG Device Control Register */
-#define                 USB_OTG_VBUS_IRQ  0xffc03d04   /* OTG VBUS Control Interrupts */
-#define                USB_OTG_VBUS_MASK  0xffc03d08   /* VBUS Control Interrupt Enable */
-
-/* USB Phy Control Registers */
-
-#define                     USB_LINKINFO  0xffc03d48   /* Enables programming of some PHY-side delays */
-#define                        USB_VPLEN  0xffc03d4c   /* Determines duration of VBUS pulse for VBUS charging */
-#define                      USB_HS_EOF1  0xffc03d50   /* Time buffer for High-Speed transactions */
-#define                      USB_FS_EOF1  0xffc03d54   /* Time buffer for Full-Speed transactions */
-#define                      USB_LS_EOF1  0xffc03d58   /* Time buffer for Low-Speed transactions */
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define                   USB_APHY_CNTRL  0xffc03de0   /* Register that increases visibility of Analog PHY */
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define                   USB_APHY_CALIB  0xffc03de4   /* Register used to set some calibration values */
-#define                  USB_APHY_CNTRL2  0xffc03de8   /* Register used to prevent re-enumeration once Moab goes into hibernate mode */
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define                     USB_PHY_TEST  0xffc03dec   /* Used for reducing simulation time and simplifies FIFO testability */
-#define                  USB_PLLOSC_CTRL  0xffc03df0   /* Used to program different parameters for USB PLL and Oscillator */
-#define                   USB_SRP_CLKDIV  0xffc03df4   /* Used to program clock divide value for the clock fed to the SRP detection logic */
-
-/* USB Endpoint 0 Control Registers */
-
-#define                USB_EP_NI0_TXMAXP  0xffc03e00   /* Maximum packet size for Host Tx endpoint0 */
-#define                 USB_EP_NI0_TXCSR  0xffc03e04   /* Control Status register for endpoint 0 */
-#define                USB_EP_NI0_RXMAXP  0xffc03e08   /* Maximum packet size for Host Rx endpoint0 */
-#define                 USB_EP_NI0_RXCSR  0xffc03e0c   /* Control Status register for Host Rx endpoint0 */
-#define               USB_EP_NI0_RXCOUNT  0xffc03e10   /* Number of bytes received in endpoint 0 FIFO */
-#define                USB_EP_NI0_TXTYPE  0xffc03e14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */
-#define            USB_EP_NI0_TXINTERVAL  0xffc03e18   /* Sets the NAK response timeout on Endpoint 0 */
-#define                USB_EP_NI0_RXTYPE  0xffc03e1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */
-#define            USB_EP_NI0_RXINTERVAL  0xffc03e20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */
-
-/* USB Endpoint 1 Control Registers */
-
-#define               USB_EP_NI0_TXCOUNT  0xffc03e28   /* Number of bytes to be written to the endpoint0 Tx FIFO */
-#define                USB_EP_NI1_TXMAXP  0xffc03e40   /* Maximum packet size for Host Tx endpoint1 */
-#define                 USB_EP_NI1_TXCSR  0xffc03e44   /* Control Status register for endpoint1 */
-#define                USB_EP_NI1_RXMAXP  0xffc03e48   /* Maximum packet size for Host Rx endpoint1 */
-#define                 USB_EP_NI1_RXCSR  0xffc03e4c   /* Control Status register for Host Rx endpoint1 */
-#define               USB_EP_NI1_RXCOUNT  0xffc03e50   /* Number of bytes received in endpoint1 FIFO */
-#define                USB_EP_NI1_TXTYPE  0xffc03e54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */
-#define            USB_EP_NI1_TXINTERVAL  0xffc03e58   /* Sets the NAK response timeout on Endpoint1 */
-#define                USB_EP_NI1_RXTYPE  0xffc03e5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */
-#define            USB_EP_NI1_RXINTERVAL  0xffc03e60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */
-
-/* USB Endpoint 2 Control Registers */
-
-#define               USB_EP_NI1_TXCOUNT  0xffc03e68   /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */
-#define                USB_EP_NI2_TXMAXP  0xffc03e80   /* Maximum packet size for Host Tx endpoint2 */
-#define                 USB_EP_NI2_TXCSR  0xffc03e84   /* Control Status register for endpoint2 */
-#define                USB_EP_NI2_RXMAXP  0xffc03e88   /* Maximum packet size for Host Rx endpoint2 */
-#define                 USB_EP_NI2_RXCSR  0xffc03e8c   /* Control Status register for Host Rx endpoint2 */
-#define               USB_EP_NI2_RXCOUNT  0xffc03e90   /* Number of bytes received in endpoint2 FIFO */
-#define                USB_EP_NI2_TXTYPE  0xffc03e94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */
-#define            USB_EP_NI2_TXINTERVAL  0xffc03e98   /* Sets the NAK response timeout on Endpoint2 */
-#define                USB_EP_NI2_RXTYPE  0xffc03e9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */
-#define            USB_EP_NI2_RXINTERVAL  0xffc03ea0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */
-
-/* USB Endpoint 3 Control Registers */
-
-#define               USB_EP_NI2_TXCOUNT  0xffc03ea8   /* Number of bytes to be written to the endpoint2 Tx FIFO */
-#define                USB_EP_NI3_TXMAXP  0xffc03ec0   /* Maximum packet size for Host Tx endpoint3 */
-#define                 USB_EP_NI3_TXCSR  0xffc03ec4   /* Control Status register for endpoint3 */
-#define                USB_EP_NI3_RXMAXP  0xffc03ec8   /* Maximum packet size for Host Rx endpoint3 */
-#define                 USB_EP_NI3_RXCSR  0xffc03ecc   /* Control Status register for Host Rx endpoint3 */
-#define               USB_EP_NI3_RXCOUNT  0xffc03ed0   /* Number of bytes received in endpoint3 FIFO */
-#define                USB_EP_NI3_TXTYPE  0xffc03ed4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */
-#define            USB_EP_NI3_TXINTERVAL  0xffc03ed8   /* Sets the NAK response timeout on Endpoint3 */
-#define                USB_EP_NI3_RXTYPE  0xffc03edc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */
-#define            USB_EP_NI3_RXINTERVAL  0xffc03ee0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */
-
-/* USB Endpoint 4 Control Registers */
-
-#define               USB_EP_NI3_TXCOUNT  0xffc03ee8   /* Number of bytes to be written to the H124endpoint3 Tx FIFO */
-#define                USB_EP_NI4_TXMAXP  0xffc03f00   /* Maximum packet size for Host Tx endpoint4 */
-#define                 USB_EP_NI4_TXCSR  0xffc03f04   /* Control Status register for endpoint4 */
-#define                USB_EP_NI4_RXMAXP  0xffc03f08   /* Maximum packet size for Host Rx endpoint4 */
-#define                 USB_EP_NI4_RXCSR  0xffc03f0c   /* Control Status register for Host Rx endpoint4 */
-#define               USB_EP_NI4_RXCOUNT  0xffc03f10   /* Number of bytes received in endpoint4 FIFO */
-#define                USB_EP_NI4_TXTYPE  0xffc03f14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */
-#define            USB_EP_NI4_TXINTERVAL  0xffc03f18   /* Sets the NAK response timeout on Endpoint4 */
-#define                USB_EP_NI4_RXTYPE  0xffc03f1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */
-#define            USB_EP_NI4_RXINTERVAL  0xffc03f20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */
-
-/* USB Endpoint 5 Control Registers */
-
-#define               USB_EP_NI4_TXCOUNT  0xffc03f28   /* Number of bytes to be written to the endpoint4 Tx FIFO */
-#define                USB_EP_NI5_TXMAXP  0xffc03f40   /* Maximum packet size for Host Tx endpoint5 */
-#define                 USB_EP_NI5_TXCSR  0xffc03f44   /* Control Status register for endpoint5 */
-#define                USB_EP_NI5_RXMAXP  0xffc03f48   /* Maximum packet size for Host Rx endpoint5 */
-#define                 USB_EP_NI5_RXCSR  0xffc03f4c   /* Control Status register for Host Rx endpoint5 */
-#define               USB_EP_NI5_RXCOUNT  0xffc03f50   /* Number of bytes received in endpoint5 FIFO */
-#define                USB_EP_NI5_TXTYPE  0xffc03f54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */
-#define            USB_EP_NI5_TXINTERVAL  0xffc03f58   /* Sets the NAK response timeout on Endpoint5 */
-#define                USB_EP_NI5_RXTYPE  0xffc03f5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */
-#define            USB_EP_NI5_RXINTERVAL  0xffc03f60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */
-
-/* USB Endpoint 6 Control Registers */
-
-#define               USB_EP_NI5_TXCOUNT  0xffc03f68   /* Number of bytes to be written to the H145endpoint5 Tx FIFO */
-#define                USB_EP_NI6_TXMAXP  0xffc03f80   /* Maximum packet size for Host Tx endpoint6 */
-#define                 USB_EP_NI6_TXCSR  0xffc03f84   /* Control Status register for endpoint6 */
-#define                USB_EP_NI6_RXMAXP  0xffc03f88   /* Maximum packet size for Host Rx endpoint6 */
-#define                 USB_EP_NI6_RXCSR  0xffc03f8c   /* Control Status register for Host Rx endpoint6 */
-#define               USB_EP_NI6_RXCOUNT  0xffc03f90   /* Number of bytes received in endpoint6 FIFO */
-#define                USB_EP_NI6_TXTYPE  0xffc03f94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */
-#define            USB_EP_NI6_TXINTERVAL  0xffc03f98   /* Sets the NAK response timeout on Endpoint6 */
-#define                USB_EP_NI6_RXTYPE  0xffc03f9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */
-#define            USB_EP_NI6_RXINTERVAL  0xffc03fa0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */
-
-/* USB Endpoint 7 Control Registers */
-
-#define               USB_EP_NI6_TXCOUNT  0xffc03fa8   /* Number of bytes to be written to the endpoint6 Tx FIFO */
-#define                USB_EP_NI7_TXMAXP  0xffc03fc0   /* Maximum packet size for Host Tx endpoint7 */
-#define                 USB_EP_NI7_TXCSR  0xffc03fc4   /* Control Status register for endpoint7 */
-#define                USB_EP_NI7_RXMAXP  0xffc03fc8   /* Maximum packet size for Host Rx endpoint7 */
-#define                 USB_EP_NI7_RXCSR  0xffc03fcc   /* Control Status register for Host Rx endpoint7 */
-#define               USB_EP_NI7_RXCOUNT  0xffc03fd0   /* Number of bytes received in endpoint7 FIFO */
-#define                USB_EP_NI7_TXTYPE  0xffc03fd4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */
-#define            USB_EP_NI7_TXINTERVAL  0xffc03fd8   /* Sets the NAK response timeout on Endpoint7 */
-#define                USB_EP_NI7_RXTYPE  0xffc03fdc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */
-#define            USB_EP_NI7_RXINTERVAL  0xffc03ff0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
-#define               USB_EP_NI7_TXCOUNT  0xffc03ff8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
-#define                USB_DMA_INTERRUPT  0xffc04000   /* Indicates pending interrupts for the DMA channels */
-
-/* USB Channel 0 Config Registers */
-
-#define                  USB_DMA0CONTROL  0xffc04004   /* DMA master channel 0 configuration */
-#define                  USB_DMA0ADDRLOW  0xffc04008   /* Lower 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0ADDRHIGH  0xffc0400c   /* Upper 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0COUNTLOW  0xffc04010   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */
-#define                USB_DMA0COUNTHIGH  0xffc04014   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */
-
-/* USB Channel 1 Config Registers */
-
-#define                  USB_DMA1CONTROL  0xffc04024   /* DMA master channel 1 configuration */
-#define                  USB_DMA1ADDRLOW  0xffc04028   /* Lower 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1ADDRHIGH  0xffc0402c   /* Upper 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1COUNTLOW  0xffc04030   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */
-#define                USB_DMA1COUNTHIGH  0xffc04034   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */
-
-/* USB Channel 2 Config Registers */
-
-#define                  USB_DMA2CONTROL  0xffc04044   /* DMA master channel 2 configuration */
-#define                  USB_DMA2ADDRLOW  0xffc04048   /* Lower 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2ADDRHIGH  0xffc0404c   /* Upper 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2COUNTLOW  0xffc04050   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */
-#define                USB_DMA2COUNTHIGH  0xffc04054   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */
-
-/* USB Channel 3 Config Registers */
-
-#define                  USB_DMA3CONTROL  0xffc04064   /* DMA master channel 3 configuration */
-#define                  USB_DMA3ADDRLOW  0xffc04068   /* Lower 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3ADDRHIGH  0xffc0406c   /* Upper 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3COUNTLOW  0xffc04070   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */
-#define                USB_DMA3COUNTHIGH  0xffc04074   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */
-
-/* USB Channel 4 Config Registers */
-
-#define                  USB_DMA4CONTROL  0xffc04084   /* DMA master channel 4 configuration */
-#define                  USB_DMA4ADDRLOW  0xffc04088   /* Lower 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4ADDRHIGH  0xffc0408c   /* Upper 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4COUNTLOW  0xffc04090   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */
-#define                USB_DMA4COUNTHIGH  0xffc04094   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */
-
-/* USB Channel 5 Config Registers */
-
-#define                  USB_DMA5CONTROL  0xffc040a4   /* DMA master channel 5 configuration */
-#define                  USB_DMA5ADDRLOW  0xffc040a8   /* Lower 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5ADDRHIGH  0xffc040ac   /* Upper 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5COUNTLOW  0xffc040b0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */
-#define                USB_DMA5COUNTHIGH  0xffc040b4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */
-
-/* USB Channel 6 Config Registers */
-
-#define                  USB_DMA6CONTROL  0xffc040c4   /* DMA master channel 6 configuration */
-#define                  USB_DMA6ADDRLOW  0xffc040c8   /* Lower 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6ADDRHIGH  0xffc040cc   /* Upper 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6COUNTLOW  0xffc040d0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */
-#define                USB_DMA6COUNTHIGH  0xffc040d4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */
-
-/* USB Channel 7 Config Registers */
-
-#define                  USB_DMA7CONTROL  0xffc040e4   /* DMA master channel 7 configuration */
-#define                  USB_DMA7ADDRLOW  0xffc040e8   /* Lower 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7ADDRHIGH  0xffc040ec   /* Upper 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7COUNTLOW  0xffc040f0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */
-#define                USB_DMA7COUNTHIGH  0xffc040f4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */
-
-/* Keypad Registers */
-
-#define                         KPAD_CTL  0xffc04100   /* Controls keypad module enable and disable */
-#define                    KPAD_PRESCALE  0xffc04104   /* Establish a time base for programing the KPAD_MSEL register */
-#define                        KPAD_MSEL  0xffc04108   /* Selects delay parameters for keypad interface sensitivity */
-#define                      KPAD_ROWCOL  0xffc0410c   /* Captures the row and column output values of the keys pressed */
-#define                        KPAD_STAT  0xffc04110   /* Holds and clears the status of the keypad interface interrupt */
-#define                    KPAD_SOFTEVAL  0xffc04114   /* Lets software force keypad interface to check for keys being pressed */
-
-/* Pixel Compositor (PIXC) Registers */
-
-#define                         PIXC_CTL  0xffc04400   /* Overlay enable, resampling mode, I/O data format, transparency enable, watermark level, FIFO status */
-#define                         PIXC_PPL  0xffc04404   /* Holds the number of pixels per line of the display */
-#define                         PIXC_LPF  0xffc04408   /* Holds the number of lines per frame of the display */
-#define                     PIXC_AHSTART  0xffc0440c   /* Contains horizontal start pixel information of the overlay data (set A) */
-#define                       PIXC_AHEND  0xffc04410   /* Contains horizontal end pixel information of the overlay data (set A) */
-#define                     PIXC_AVSTART  0xffc04414   /* Contains vertical start pixel information of the overlay data (set A) */
-#define                       PIXC_AVEND  0xffc04418   /* Contains vertical end pixel information of the overlay data (set A) */
-#define                     PIXC_ATRANSP  0xffc0441c   /* Contains the transparency ratio (set A) */
-#define                     PIXC_BHSTART  0xffc04420   /* Contains horizontal start pixel information of the overlay data (set B) */
-#define                       PIXC_BHEND  0xffc04424   /* Contains horizontal end pixel information of the overlay data (set B) */
-#define                     PIXC_BVSTART  0xffc04428   /* Contains vertical start pixel information of the overlay data (set B) */
-#define                       PIXC_BVEND  0xffc0442c   /* Contains vertical end pixel information of the overlay data (set B) */
-#define                     PIXC_BTRANSP  0xffc04430   /* Contains the transparency ratio (set B) */
-#define                    PIXC_INTRSTAT  0xffc0443c   /* Overlay interrupt configuration/status */
-#define                       PIXC_RYCON  0xffc04440   /* Color space conversion matrix register. Contains the R/Y conversion coefficients */
-#define                       PIXC_GUCON  0xffc04444   /* Color space conversion matrix register. Contains the G/U conversion coefficients */
-#define                       PIXC_BVCON  0xffc04448   /* Color space conversion matrix register. Contains the B/V conversion coefficients */
-#define                      PIXC_CCBIAS  0xffc0444c   /* Bias values for the color space conversion matrix */
-#define                          PIXC_TC  0xffc04450   /* Holds the transparent color value */
-
-/* Handshake MDMA 0 Registers */
-
-#define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
-#define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
-#define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
-#define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
-#define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
-#define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
-
-/* Handshake MDMA 1 Registers */
-
-#define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
-#define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
-#define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
-#define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
-#define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
-#define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
-
-
-/* ********************************************************** */
-/*     SINGLE BIT MACRO PAIRS (bit mask and negated one)      */
-/*     and MULTI BIT READ MACROS                              */
-/* ********************************************************** */
-
-/* Bit masks for PIXC_CTL */
-
-#define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                  IMG_FORM  0x8        /* Image Data Format */
-#define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                  OUT_FORM  0x20       /* Output Data Format */
-#define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                  IMG_STAT  0x300      /* Image FIFO Status */
-#define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
-#define                    WM_LVL  0x3000     /* FIFO Watermark Level */
-
-/* Bit masks for PIXC_AHSTART */
-
-#define                  A_HSTART  0xfff      /* Horizontal Start Coordinates */
-
-/* Bit masks for PIXC_AHEND */
-
-#define                    A_HEND  0xfff      /* Horizontal End Coordinates */
-
-/* Bit masks for PIXC_AVSTART */
-
-#define                  A_VSTART  0x3ff      /* Vertical Start Coordinates */
-
-/* Bit masks for PIXC_AVEND */
-
-#define                    A_VEND  0x3ff      /* Vertical End Coordinates */
-
-/* Bit masks for PIXC_ATRANSP */
-
-#define                  A_TRANSP  0xf        /* Transparency Value */
-
-/* Bit masks for PIXC_BHSTART */
-
-#define                  B_HSTART  0xfff      /* Horizontal Start Coordinates */
-
-/* Bit masks for PIXC_BHEND */
-
-#define                    B_HEND  0xfff      /* Horizontal End Coordinates */
-
-/* Bit masks for PIXC_BVSTART */
-
-#define                  B_VSTART  0x3ff      /* Vertical Start Coordinates */
-
-/* Bit masks for PIXC_BVEND */
-
-#define                    B_VEND  0x3ff      /* Vertical End Coordinates */
-
-/* Bit masks for PIXC_BTRANSP */
-
-#define                  B_TRANSP  0xf        /* Transparency Value */
-
-/* Bit masks for PIXC_INTRSTAT */
-
-#define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-
-/* Bit masks for PIXC_RYCON */
-
-#define                       A11  0x3ff      /* A11 in the Coefficient Matrix */
-#define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
-#define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
-#define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_GUCON */
-
-#define                       A21  0x3ff      /* A21 in the Coefficient Matrix */
-#define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
-#define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
-#define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_BVCON */
-
-#define                       A31  0x3ff      /* A31 in the Coefficient Matrix */
-#define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
-#define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
-#define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_CCBIAS */
-
-#define                       A14  0x3ff      /* A14 in the Bias Vector */
-#define                       A24  0xffc00    /* A24 in the Bias Vector */
-#define                       A34  0x3ff00000 /* A34 in the Bias Vector */
-
-/* Bit masks for PIXC_TC */
-
-#define                  RY_TRANS  0xff       /* Transparent Color - R/Y Component */
-#define                  GU_TRANS  0xff00     /* Transparent Color - G/U Component */
-#define                  BV_TRANS  0xff0000   /* Transparent Color - B/V Component */
-
-/* Bit masks for HOST_CONTROL */
-
-#define                   HOST_EN  0x1        /* Host Enable */
-#define                  HOST_END  0x2        /* Host Endianess */
-#define                 DATA_SIZE  0x4        /* Data Size */
-#define                  HOST_RST  0x8        /* Host Reset */
-#define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                       EHW  0x100      /* Enable Host Write */
-#define                       EHR  0x200      /* Enable Host Read */
-#define                       BDR  0x400      /* Burst DMA Requests */
-
-/* Bit masks for HOST_STATUS */
-
-#define                 DMA_READY  0x1        /* DMA Ready */
-#define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define              DMA_COMPLETE  0x8        /* DMA Complete */
-#define                      HSHK  0x10       /* Host Handshake */
-#define                 HSTIMEOUT  0x20       /* Host Timeout */
-#define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define                   DMA_DIR  0x100      /* DMA Direction */
-#define                       BTE  0x200      /* Bus Timeout Enabled */
-
-/* Bit masks for HOST_TIMEOUT */
-
-#define             COUNT_TIMEOUT  0x7ff      /* Host Timeout count */
-
-/* Bit masks for KPAD_CTL */
-
-#define                   KPAD_EN  0x1        /* Keypad Enable */
-#define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
-#define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
-#define                KPAD_COLEN  0xe000     /* Column Enable Width */
-
-/* Bit masks for KPAD_PRESCALE */
-
-#define         KPAD_PRESCALE_VAL  0x3f       /* Key Prescale Value */
-
-/* Bit masks for KPAD_MSEL */
-
-#define                DBON_SCALE  0xff       /* Debounce Scale Value */
-#define              COLDRV_SCALE  0xff00     /* Column Driver Scale Value */
-
-/* Bit masks for KPAD_ROWCOL */
-
-#define                  KPAD_ROW  0xff       /* Rows Pressed */
-#define                  KPAD_COL  0xff00     /* Columns Pressed */
-
-/* Bit masks for KPAD_STAT */
-
-#define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
-#define              KPAD_PRESSED  0x8        /* Key press current status */
-
-/* Bit masks for KPAD_SOFTEVAL */
-
-#define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-
-/* Bit masks for SDH_COMMAND */
-
-#define                   CMD_IDX  0x3f       /* Command Index */
-#define                   CMD_RSP  0x40       /* Response */
-#define                 CMD_L_RSP  0x80       /* Long Response */
-#define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                CMD_PEND_E  0x200      /* Command Pending */
-#define                     CMD_E  0x400      /* Command Enable */
-
-/* Bit masks for SDH_PWR_CTL */
-
-#define                    PWR_ON  0x3        /* Power On */
-#if 0
-#define                       TBD  0x3c       /* TBD */
-#endif
-#define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                   ROD_CTL  0x80       /* Rod Control */
-
-/* Bit masks for SDH_CLK_CTL */
-
-#define                    CLKDIV  0xff       /* MC_CLK Divisor */
-#define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-
-/* Bit masks for SDH_RESP_CMD */
-
-#define                  RESP_CMD  0x3f       /* Response Command */
-
-/* Bit masks for SDH_DATA_CTL */
-
-#define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
-
-/* Bit masks for SDH_STATUS */
-
-#define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
-#define               DAT_TIME_OUT  0x8        /* Data Time Out */
-#define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define              CMD_RESP_END  0x40       /* CMD Response End */
-#define                  CMD_SENT  0x80       /* CMD Sent */
-#define                   DAT_END  0x100      /* Data End */
-#define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define               DAT_BLK_END  0x400      /* Data Block End */
-#define                   CMD_ACT  0x800      /* CMD Active */
-#define                    TX_ACT  0x1000     /* Transmit Active */
-#define                    RX_ACT  0x2000     /* Receive Active */
-#define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-
-/* Bit masks for SDH_STATUS_CLR */
-
-#define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define              DAT_END_STAT  0x100      /* Data End Status */
-#define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-
-/* Bit masks for SDH_MASK0 */
-
-#define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define              DAT_END_MASK  0x100      /* Data End Mask */
-#define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-
-/* Bit masks for SDH_FIFO_CNT */
-
-#define                FIFO_COUNT  0x7fff     /* FIFO Count */
-
-/* Bit masks for SDH_E_STATUS */
-
-#define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define               SD_CARD_DET  0x10       /* SD Card Detect */
-
-/* Bit masks for SDH_E_MASK */
-
-#define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                   SCD_MSK  0x40       /* Mask Card Detect */
-
-/* Bit masks for SDH_CFG */
-
-#define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                       MWE  0x8        /* Moving Window Enable */
-#define                    SD_RST  0x10       /* SDMMC Reset */
-#define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-
-/* Bit masks for SDH_RD_WAIT_EN */
-
-#define                       RWR  0x1        /* Read Wait Request */
-
-/* Bit masks for ATAPI_CONTROL */
-
-#define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define                  SOFT_RST  0x40       /* Soft Reset */
-#define                   DEV_RST  0x80       /* Device Reset */
-#define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
-
-/* Bit masks for ATAPI_STATUS */
-
-#define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
-
-/* Bit masks for ATAPI_DEV_ADDR */
-
-#define                  DEV_ADDR  0x1f       /* Device Address */
-
-/* Bit masks for ATAPI_INT_MASK */
-
-#define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-
-/* Bit masks for ATAPI_INT_STATUS */
-
-#define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-
-/* Bit masks for ATAPI_LINE_STATUS */
-
-#define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define                ATAPI_ADDR  0x70       /* ATAPI address line status */
-#define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-
-/* Bit masks for ATAPI_SM_STATE */
-
-#define                PIO_CSTATE  0xf        /* PIO mode state machine current state */
-#define                DMA_CSTATE  0xf0       /* DMA mode state machine current state */
-#define             UDMAIN_CSTATE  0xf00      /* Ultra DMA-In mode state machine current state */
-#define            UDMAOUT_CSTATE  0xf000     /* ATAPI IORDY line status */
-
-/* Bit masks for ATAPI_TERMINATE */
-
-#define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-
-/* Bit masks for ATAPI_REG_TIM_0 */
-
-#define                    T2_REG  0xff       /* End of cycle time for register access transfers */
-#define                  TEOC_REG  0xff00     /* Selects DIOR/DIOW pulsewidth */
-
-/* Bit masks for ATAPI_PIO_TIM_0 */
-
-#define                    T1_REG  0xf        /* Time from address valid to DIOR/DIOW */
-#define                T2_REG_PIO  0xff0      /* DIOR/DIOW pulsewidth */
-#define                    T4_REG  0xf000     /* DIOW data hold */
-
-/* Bit masks for ATAPI_PIO_TIM_1 */
-
-#define              TEOC_REG_PIO  0xff       /* End of cycle time for PIO access transfers. */
-
-/* Bit masks for ATAPI_MULTI_TIM_0 */
-
-#define                        TD  0xff       /* DIOR/DIOW asserted pulsewidth */
-#define                        TM  0xff00     /* Time from address valid to DIOR/DIOW */
-
-/* Bit masks for ATAPI_MULTI_TIM_1 */
-
-#define                       TKW  0xff       /* Selects DIOW negated pulsewidth */
-#define                       TKR  0xff00     /* Selects DIOR negated pulsewidth */
-
-/* Bit masks for ATAPI_MULTI_TIM_2 */
-
-#define                        TH  0xff       /* Selects DIOW data hold */
-#define                      TEOC  0xff00     /* Selects end of cycle for DMA */
-
-/* Bit masks for ATAPI_ULTRA_TIM_0 */
-
-#define                      TACK  0xff       /* Selects setup and hold times for TACK */
-#define                      TENV  0xff00     /* Selects envelope time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_1 */
-
-#define                      TDVS  0xff       /* Selects data valid setup time */
-#define                 TCYC_TDVS  0xff00     /* Selects cycle time - TDVS time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_2 */
-
-#define                       TSS  0xff       /* Selects time from STROBE edge to negation of DMARQ or assertion of STOP */
-#define                      TMLI  0xff00     /* Selects interlock time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_3 */
-
-#define                      TZAH  0xff       /* Selects minimum delay required for output */
-#define               READY_PAUSE  0xff00     /* Selects ready to pause */
-
-/* Bit masks for TIMER_ENABLE1 */
-
-#define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   TIMEN10  0x4        /* Timer 10 Enable */
-
-/* Bit masks for TIMER_DISABLE1 */
-
-#define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  TIMDIS10  0x4        /* Timer 10 Disable */
-
-/* Bit masks for TIMER_STATUS1 */
-
-#define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-
-/* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
-
-/* Bit masks for USB_FADDR */
-
-#define          FUNCTION_ADDRESS  0x7f       /* Function address */
-
-/* Bit masks for USB_POWER */
-
-#define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define               RESUME_MODE  0x4        /* DMA Mode */
-#define                     RESET  0x8        /* Reset indicator */
-#define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                 SOFT_CONN  0x40       /* Soft connect */
-#define                ISO_UPDATE  0x80       /* Isochronous update */
-
-/* Bit masks for USB_INTRTX */
-
-#define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-
-/* Bit masks for USB_INTRRX */
-
-#define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-
-/* Bit masks for USB_INTRTXE */
-
-#define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-
-/* Bit masks for USB_INTRRXE */
-
-#define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-
-/* Bit masks for USB_INTRUSB */
-
-#define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                  RESUME_B  0x2        /* Resume indicator */
-#define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define                     SOF_B  0x8        /* Start of frame */
-#define                    CONN_B  0x10       /* Connection indicator */
-#define                  DISCON_B  0x20       /* Disconnect indicator */
-#define             SESSION_REQ_B  0x40       /* Session Request */
-#define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-
-/* Bit masks for USB_INTRUSBE */
-
-#define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-
-/* Bit masks for USB_FRAME */
-
-#define              FRAME_NUMBER  0x7ff      /* Frame number */
-
-/* Bit masks for USB_INDEX */
-
-#define         SELECTED_ENDPOINT  0xf        /* selected endpoint */
-
-/* Bit masks for USB_GLOBAL_CTL */
-
-#define                GLOBAL_ENA  0x1        /* enables USB module */
-#define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-
-/* Bit masks for USB_OTG_DEV_CTL */
-
-#define                   SESSION  0x1        /* session indicator */
-#define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                     LSDEV  0x20       /* Low-speed indicator */
-#define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-
-/* Bit masks for USB_OTG_VBUS_IRQ */
-
-#define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-
-/* Bit masks for USB_OTG_VBUS_MASK */
-
-#define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-
-/* Bit masks for USB_CSR0 */
-
-#define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                STALL_SENT  0x4        /* STALL handshake sent */
-#define                   DATAEND  0x8        /* Data end indicator */
-#define                  SETUPEND  0x10       /* Setup end */
-#define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-
-/* Bit masks for USB_COUNT0 */
-
-#define              EP0_RX_COUNT  0x7f       /* number of received bytes in EP0 FIFO */
-
-/* Bit masks for USB_NAKLIMIT0 */
-
-#define             EP0_NAK_LIMIT  0x1f       /* number of frames/micro frames after which EP0 timeouts */
-
-/* Bit masks for USB_TX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_T  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_RX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_R  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_TXCSR */
-
-#define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                  ERROR_TH  0x4        /* error condition host mode */
-#define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-
-/* Bit masks for USB_TXCOUNT */
-
-#define                  TX_COUNT  0x1fff     /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* Bit masks for USB_RXCSR */
-
-#define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-
-/* Bit masks for USB_RXCOUNT */
-
-#define                  RX_COUNT  0x1fff     /* Number of received bytes in the packet in the Rx FIFO */
-
-/* Bit masks for USB_TXTYPE */
-
-#define            TARGET_EP_NO_T  0xf        /* EP number */
-#define                PROTOCOL_T  0xc        /* transfer type */
-
-/* Bit masks for USB_TXINTERVAL */
-
-#define          TX_POLL_INTERVAL  0xff       /* polling interval for selected Tx EP */
-
-/* Bit masks for USB_RXTYPE */
-
-#define            TARGET_EP_NO_R  0xf        /* EP number */
-#define                PROTOCOL_R  0xc        /* transfer type */
-
-/* Bit masks for USB_RXINTERVAL */
-
-#define          RX_POLL_INTERVAL  0xff       /* polling interval for selected Rx EP */
-
-/* Bit masks for USB_DMA_INTERRUPT */
-
-#define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-
-/* Bit masks for USB_DMAxCONTROL */
-
-#define                   DMA_ENA  0x1        /* DMA enable */
-#define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                      MODE  0x4        /* DMA Bus error */
-#define                   INT_ENA  0x8        /* Interrupt enable */
-#define                     EPNUM  0xf0       /* EP number */
-#define                  BUSERROR  0x100      /* DMA Bus error */
-
-/* Bit masks for USB_DMAxADDRHIGH */
-
-#define             DMA_ADDR_HIGH  0xffff     /* Upper 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxADDRLOW */
-
-#define              DMA_ADDR_LOW  0xffff     /* Lower 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTHIGH */
-
-#define            DMA_COUNT_HIGH  0xffff     /* Upper 16-bits of byte count of DMA transfer for DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTLOW */
-
-#define             DMA_COUNT_LOW  0xffff     /* Lower 16-bits of byte count of DMA transfer for DMA master channel */
-
-/* Bit masks for HMDMAx_CONTROL */
-
-#define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                       DRQ  0x300      /* Handshake MDMA Request Type */
-#define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                        PS  0x2000     /* Pin Status */
-#define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       BDI  0x8000     /* Block Done Interrupt Generated */
-
-/* ******************************************* */
-/*     MULTI BIT MACRO ENUMERATIONS            */
-/* ******************************************* */
-
-
 #endif /* _DEF_BF548_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF549.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF549.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF549.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF549.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,121 +10,13 @@
 /* Include all Core registers and bit definitions */
 #include <asm/def_LPBlackfin.h>
 
-
 /* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF549 */
 
 /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */
 #include "defBF54x_base.h"
 
-/* The following are the #defines needed by ADSP-BF549 that are not in the common header */
-
-/* Timer Registers */
-
-#define                    TIMER8_CONFIG  0xffc00600   /* Timer 8 Configuration Register */
-#define                   TIMER8_COUNTER  0xffc00604   /* Timer 8 Counter Register */
-#define                    TIMER8_PERIOD  0xffc00608   /* Timer 8 Period Register */
-#define                     TIMER8_WIDTH  0xffc0060c   /* Timer 8 Width Register */
-#define                    TIMER9_CONFIG  0xffc00610   /* Timer 9 Configuration Register */
-#define                   TIMER9_COUNTER  0xffc00614   /* Timer 9 Counter Register */
-#define                    TIMER9_PERIOD  0xffc00618   /* Timer 9 Period Register */
-#define                     TIMER9_WIDTH  0xffc0061c   /* Timer 9 Width Register */
-#define                   TIMER10_CONFIG  0xffc00620   /* Timer 10 Configuration Register */
-#define                  TIMER10_COUNTER  0xffc00624   /* Timer 10 Counter Register */
-#define                   TIMER10_PERIOD  0xffc00628   /* Timer 10 Period Register */
-#define                    TIMER10_WIDTH  0xffc0062c   /* Timer 10 Width Register */
-
-/* Timer Group of 3 Registers */
-
-#define                    TIMER_ENABLE1  0xffc00640   /* Timer Group of 3 Enable Register */
-#define                   TIMER_DISABLE1  0xffc00644   /* Timer Group of 3 Disable Register */
-#define                    TIMER_STATUS1  0xffc00648   /* Timer Group of 3 Status Register */
-
-/* SPORT0 Registers */
-
-#define                      SPORT0_TCR1  0xffc00800   /* SPORT0 Transmit Configuration 1 Register */
-#define                      SPORT0_TCR2  0xffc00804   /* SPORT0 Transmit Configuration 2 Register */
-#define                   SPORT0_TCLKDIV  0xffc00808   /* SPORT0 Transmit Serial Clock Divider Register */
-#define                    SPORT0_TFSDIV  0xffc0080c   /* SPORT0 Transmit Frame Sync Divider Register */
-#define                        SPORT0_TX  0xffc00810   /* SPORT0 Transmit Data Register */
-#define                        SPORT0_RX  0xffc00818   /* SPORT0 Receive Data Register */
-#define                      SPORT0_RCR1  0xffc00820   /* SPORT0 Receive Configuration 1 Register */
-#define                      SPORT0_RCR2  0xffc00824   /* SPORT0 Receive Configuration 2 Register */
-#define                   SPORT0_RCLKDIV  0xffc00828   /* SPORT0 Receive Serial Clock Divider Register */
-#define                    SPORT0_RFSDIV  0xffc0082c   /* SPORT0 Receive Frame Sync Divider Register */
-#define                      SPORT0_STAT  0xffc00830   /* SPORT0 Status Register */
-#define                      SPORT0_CHNL  0xffc00834   /* SPORT0 Current Channel Register */
-#define                     SPORT0_MCMC1  0xffc00838   /* SPORT0 Multi channel Configuration Register 1 */
-#define                     SPORT0_MCMC2  0xffc0083c   /* SPORT0 Multi channel Configuration Register 2 */
-#define                     SPORT0_MTCS0  0xffc00840   /* SPORT0 Multi channel Transmit Select Register 0 */
-#define                     SPORT0_MTCS1  0xffc00844   /* SPORT0 Multi channel Transmit Select Register 1 */
-#define                     SPORT0_MTCS2  0xffc00848   /* SPORT0 Multi channel Transmit Select Register 2 */
-#define                     SPORT0_MTCS3  0xffc0084c   /* SPORT0 Multi channel Transmit Select Register 3 */
-#define                     SPORT0_MRCS0  0xffc00850   /* SPORT0 Multi channel Receive Select Register 0 */
-#define                     SPORT0_MRCS1  0xffc00854   /* SPORT0 Multi channel Receive Select Register 1 */
-#define                     SPORT0_MRCS2  0xffc00858   /* SPORT0 Multi channel Receive Select Register 2 */
-#define                     SPORT0_MRCS3  0xffc0085c   /* SPORT0 Multi channel Receive Select Register 3 */
-
-/* EPPI0 Registers */
-
-#define                     EPPI0_STATUS  0xffc01000   /* EPPI0 Status Register */
-#define                     EPPI0_HCOUNT  0xffc01004   /* EPPI0 Horizontal Transfer Count Register */
-#define                     EPPI0_HDELAY  0xffc01008   /* EPPI0 Horizontal Delay Count Register */
-#define                     EPPI0_VCOUNT  0xffc0100c   /* EPPI0 Vertical Transfer Count Register */
-#define                     EPPI0_VDELAY  0xffc01010   /* EPPI0 Vertical Delay Count Register */
-#define                      EPPI0_FRAME  0xffc01014   /* EPPI0 Lines per Frame Register */
-#define                       EPPI0_LINE  0xffc01018   /* EPPI0 Samples per Line Register */
-#define                     EPPI0_CLKDIV  0xffc0101c   /* EPPI0 Clock Divide Register */
-#define                    EPPI0_CONTROL  0xffc01020   /* EPPI0 Control Register */
-#define                   EPPI0_FS1W_HBL  0xffc01024   /* EPPI0 FS1 Width Register / EPPI0 Horizontal Blanking Samples Per Line Register */
-#define                  EPPI0_FS1P_AVPL  0xffc01028   /* EPPI0 FS1 Period Register / EPPI0 Active Video Samples Per Line Register */
-#define                   EPPI0_FS2W_LVB  0xffc0102c   /* EPPI0 FS2 Width Register / EPPI0 Lines of Vertical Blanking Register */
-#define                  EPPI0_FS2P_LAVF  0xffc01030   /* EPPI0 FS2 Period Register/ EPPI0 Lines of Active Video Per Field Register */
-#define                       EPPI0_CLIP  0xffc01034   /* EPPI0 Clipping Register */
-
-/* UART2 Registers */
-
-#define                        UART2_DLL  0xffc02100   /* Divisor Latch Low Byte */
-#define                        UART2_DLH  0xffc02104   /* Divisor Latch High Byte */
-#define                       UART2_GCTL  0xffc02108   /* Global Control Register */
-#define                        UART2_LCR  0xffc0210c   /* Line Control Register */
-#define                        UART2_MCR  0xffc02110   /* Modem Control Register */
-#define                        UART2_LSR  0xffc02114   /* Line Status Register */
-#define                        UART2_MSR  0xffc02118   /* Modem Status Register */
-#define                        UART2_SCR  0xffc0211c   /* Scratch Register */
-#define                    UART2_IER_SET  0xffc02120   /* Interrupt Enable Register Set */
-#define                  UART2_IER_CLEAR  0xffc02124   /* Interrupt Enable Register Clear */
-#define                        UART2_RBR  0xffc0212c   /* Receive Buffer Register */
-
-/* Two Wire Interface Registers (TWI1) */
-
-#define                     TWI1_REGBASE  0xffc02200
-#define                      TWI1_CLKDIV  0xffc02200   /* Clock Divider Register */
-#define                     TWI1_CONTROL  0xffc02204   /* TWI Control Register */
-#define                  TWI1_SLAVE_CTRL  0xffc02208   /* TWI Slave Mode Control Register */
-#define                  TWI1_SLAVE_STAT  0xffc0220c   /* TWI Slave Mode Status Register */
-#define                  TWI1_SLAVE_ADDR  0xffc02210   /* TWI Slave Mode Address Register */
-#define                 TWI1_MASTER_CTRL  0xffc02214   /* TWI Master Mode Control Register */
-#define                 TWI1_MASTER_STAT  0xffc02218   /* TWI Master Mode Status Register */
-#define                 TWI1_MASTER_ADDR  0xffc0221c   /* TWI Master Mode Address Register */
-#define                    TWI1_INT_STAT  0xffc02220   /* TWI Interrupt Status Register */
-#define                    TWI1_INT_MASK  0xffc02224   /* TWI Interrupt Mask Register */
-#define                   TWI1_FIFO_CTRL  0xffc02228   /* TWI FIFO Control Register */
-#define                   TWI1_FIFO_STAT  0xffc0222c   /* TWI FIFO Status Register */
-#define                   TWI1_XMT_DATA8  0xffc02280   /* TWI FIFO Transmit Data Single Byte Register */
-#define                  TWI1_XMT_DATA16  0xffc02284   /* TWI FIFO Transmit Data Double Byte Register */
-#define                   TWI1_RCV_DATA8  0xffc02288   /* TWI FIFO Receive Data Single Byte Register */
-#define                  TWI1_RCV_DATA16  0xffc0228c   /* TWI FIFO Receive Data Double Byte Register */
-
-/* SPI2  Registers */
-
-#define                     SPI2_REGBASE  0xffc02400
-#define                         SPI2_CTL  0xffc02400   /* SPI2 Control Register */
-#define                         SPI2_FLG  0xffc02404   /* SPI2 Flag Register */
-#define                        SPI2_STAT  0xffc02408   /* SPI2 Status Register */
-#define                        SPI2_TDBR  0xffc0240c   /* SPI2 Transmit Data Buffer Register */
-#define                        SPI2_RDBR  0xffc02410   /* SPI2 Receive Data Buffer Register */
-#define                        SPI2_BAUD  0xffc02414   /* SPI2 Baud Rate Register */
-#define                      SPI2_SHADOW  0xffc02418   /* SPI2 Receive Data Buffer Shadow Register */
+/* The BF549 is like the BF544, but has MXVR */
+#include "defBF547.h"
 
 /* MXVR Registers */
 
@@ -296,2418 +188,4 @@
 #define                     MXVR_PIN_CTL  0xffc028dc   /* MXVR Pin Control Register */
 #define                    MXVR_SCLK_CNT  0xffc028e0   /* MXVR System Clock Counter Register */
 
-/* CAN Controller 1 Config 1 Registers */
-
-#define                         CAN1_MC1  0xffc03200   /* CAN Controller 1 Mailbox Configuration Register 1 */
-#define                         CAN1_MD1  0xffc03204   /* CAN Controller 1 Mailbox Direction Register 1 */
-#define                        CAN1_TRS1  0xffc03208   /* CAN Controller 1 Transmit Request Set Register 1 */
-#define                        CAN1_TRR1  0xffc0320c   /* CAN Controller 1 Transmit Request Reset Register 1 */
-#define                         CAN1_TA1  0xffc03210   /* CAN Controller 1 Transmit Acknowledge Register 1 */
-#define                         CAN1_AA1  0xffc03214   /* CAN Controller 1 Abort Acknowledge Register 1 */
-#define                        CAN1_RMP1  0xffc03218   /* CAN Controller 1 Receive Message Pending Register 1 */
-#define                        CAN1_RML1  0xffc0321c   /* CAN Controller 1 Receive Message Lost Register 1 */
-#define                      CAN1_MBTIF1  0xffc03220   /* CAN Controller 1 Mailbox Transmit Interrupt Flag Register 1 */
-#define                      CAN1_MBRIF1  0xffc03224   /* CAN Controller 1 Mailbox Receive Interrupt Flag Register 1 */
-#define                       CAN1_MBIM1  0xffc03228   /* CAN Controller 1 Mailbox Interrupt Mask Register 1 */
-#define                        CAN1_RFH1  0xffc0322c   /* CAN Controller 1 Remote Frame Handling Enable Register 1 */
-#define                       CAN1_OPSS1  0xffc03230   /* CAN Controller 1 Overwrite Protection Single Shot Transmit Register 1 */
-
-/* CAN Controller 1 Config 2 Registers */
-
-#define                         CAN1_MC2  0xffc03240   /* CAN Controller 1 Mailbox Configuration Register 2 */
-#define                         CAN1_MD2  0xffc03244   /* CAN Controller 1 Mailbox Direction Register 2 */
-#define                        CAN1_TRS2  0xffc03248   /* CAN Controller 1 Transmit Request Set Register 2 */
-#define                        CAN1_TRR2  0xffc0324c   /* CAN Controller 1 Transmit Request Reset Register 2 */
-#define                         CAN1_TA2  0xffc03250   /* CAN Controller 1 Transmit Acknowledge Register 2 */
-#define                         CAN1_AA2  0xffc03254   /* CAN Controller 1 Abort Acknowledge Register 2 */
-#define                        CAN1_RMP2  0xffc03258   /* CAN Controller 1 Receive Message Pending Register 2 */
-#define                        CAN1_RML2  0xffc0325c   /* CAN Controller 1 Receive Message Lost Register 2 */
-#define                      CAN1_MBTIF2  0xffc03260   /* CAN Controller 1 Mailbox Transmit Interrupt Flag Register 2 */
-#define                      CAN1_MBRIF2  0xffc03264   /* CAN Controller 1 Mailbox Receive Interrupt Flag Register 2 */
-#define                       CAN1_MBIM2  0xffc03268   /* CAN Controller 1 Mailbox Interrupt Mask Register 2 */
-#define                        CAN1_RFH2  0xffc0326c   /* CAN Controller 1 Remote Frame Handling Enable Register 2 */
-#define                       CAN1_OPSS2  0xffc03270   /* CAN Controller 1 Overwrite Protection Single Shot Transmit Register 2 */
-
-/* CAN Controller 1 Clock/Interrupt/Counter Registers */
-
-#define                       CAN1_CLOCK  0xffc03280   /* CAN Controller 1 Clock Register */
-#define                      CAN1_TIMING  0xffc03284   /* CAN Controller 1 Timing Register */
-#define                       CAN1_DEBUG  0xffc03288   /* CAN Controller 1 Debug Register */
-#define                      CAN1_STATUS  0xffc0328c   /* CAN Controller 1 Global Status Register */
-#define                         CAN1_CEC  0xffc03290   /* CAN Controller 1 Error Counter Register */
-#define                         CAN1_GIS  0xffc03294   /* CAN Controller 1 Global Interrupt Status Register */
-#define                         CAN1_GIM  0xffc03298   /* CAN Controller 1 Global Interrupt Mask Register */
-#define                         CAN1_GIF  0xffc0329c   /* CAN Controller 1 Global Interrupt Flag Register */
-#define                     CAN1_CONTROL  0xffc032a0   /* CAN Controller 1 Master Control Register */
-#define                        CAN1_INTR  0xffc032a4   /* CAN Controller 1 Interrupt Pending Register */
-#define                        CAN1_MBTD  0xffc032ac   /* CAN Controller 1 Mailbox Temporary Disable Register */
-#define                         CAN1_EWR  0xffc032b0   /* CAN Controller 1 Programmable Warning Level Register */
-#define                         CAN1_ESR  0xffc032b4   /* CAN Controller 1 Error Status Register */
-#define                       CAN1_UCCNT  0xffc032c4   /* CAN Controller 1 Universal Counter Register */
-#define                        CAN1_UCRC  0xffc032c8   /* CAN Controller 1 Universal Counter Force Reload Register */
-#define                       CAN1_UCCNF  0xffc032cc   /* CAN Controller 1 Universal Counter Configuration Register */
-
-/* CAN Controller 1 Mailbox Acceptance Registers */
-
-#define                       CAN1_AM00L  0xffc03300   /* CAN Controller 1 Mailbox 0 Acceptance Mask High Register */
-#define                       CAN1_AM00H  0xffc03304   /* CAN Controller 1 Mailbox 0 Acceptance Mask Low Register */
-#define                       CAN1_AM01L  0xffc03308   /* CAN Controller 1 Mailbox 1 Acceptance Mask High Register */
-#define                       CAN1_AM01H  0xffc0330c   /* CAN Controller 1 Mailbox 1 Acceptance Mask Low Register */
-#define                       CAN1_AM02L  0xffc03310   /* CAN Controller 1 Mailbox 2 Acceptance Mask High Register */
-#define                       CAN1_AM02H  0xffc03314   /* CAN Controller 1 Mailbox 2 Acceptance Mask Low Register */
-#define                       CAN1_AM03L  0xffc03318   /* CAN Controller 1 Mailbox 3 Acceptance Mask High Register */
-#define                       CAN1_AM03H  0xffc0331c   /* CAN Controller 1 Mailbox 3 Acceptance Mask Low Register */
-#define                       CAN1_AM04L  0xffc03320   /* CAN Controller 1 Mailbox 4 Acceptance Mask High Register */
-#define                       CAN1_AM04H  0xffc03324   /* CAN Controller 1 Mailbox 4 Acceptance Mask Low Register */
-#define                       CAN1_AM05L  0xffc03328   /* CAN Controller 1 Mailbox 5 Acceptance Mask High Register */
-#define                       CAN1_AM05H  0xffc0332c   /* CAN Controller 1 Mailbox 5 Acceptance Mask Low Register */
-#define                       CAN1_AM06L  0xffc03330   /* CAN Controller 1 Mailbox 6 Acceptance Mask High Register */
-#define                       CAN1_AM06H  0xffc03334   /* CAN Controller 1 Mailbox 6 Acceptance Mask Low Register */
-#define                       CAN1_AM07L  0xffc03338   /* CAN Controller 1 Mailbox 7 Acceptance Mask High Register */
-#define                       CAN1_AM07H  0xffc0333c   /* CAN Controller 1 Mailbox 7 Acceptance Mask Low Register */
-#define                       CAN1_AM08L  0xffc03340   /* CAN Controller 1 Mailbox 8 Acceptance Mask High Register */
-#define                       CAN1_AM08H  0xffc03344   /* CAN Controller 1 Mailbox 8 Acceptance Mask Low Register */
-#define                       CAN1_AM09L  0xffc03348   /* CAN Controller 1 Mailbox 9 Acceptance Mask High Register */
-#define                       CAN1_AM09H  0xffc0334c   /* CAN Controller 1 Mailbox 9 Acceptance Mask Low Register */
-#define                       CAN1_AM10L  0xffc03350   /* CAN Controller 1 Mailbox 10 Acceptance Mask High Register */
-#define                       CAN1_AM10H  0xffc03354   /* CAN Controller 1 Mailbox 10 Acceptance Mask Low Register */
-#define                       CAN1_AM11L  0xffc03358   /* CAN Controller 1 Mailbox 11 Acceptance Mask High Register */
-#define                       CAN1_AM11H  0xffc0335c   /* CAN Controller 1 Mailbox 11 Acceptance Mask Low Register */
-#define                       CAN1_AM12L  0xffc03360   /* CAN Controller 1 Mailbox 12 Acceptance Mask High Register */
-#define                       CAN1_AM12H  0xffc03364   /* CAN Controller 1 Mailbox 12 Acceptance Mask Low Register */
-#define                       CAN1_AM13L  0xffc03368   /* CAN Controller 1 Mailbox 13 Acceptance Mask High Register */
-#define                       CAN1_AM13H  0xffc0336c   /* CAN Controller 1 Mailbox 13 Acceptance Mask Low Register */
-#define                       CAN1_AM14L  0xffc03370   /* CAN Controller 1 Mailbox 14 Acceptance Mask High Register */
-#define                       CAN1_AM14H  0xffc03374   /* CAN Controller 1 Mailbox 14 Acceptance Mask Low Register */
-#define                       CAN1_AM15L  0xffc03378   /* CAN Controller 1 Mailbox 15 Acceptance Mask High Register */
-#define                       CAN1_AM15H  0xffc0337c   /* CAN Controller 1 Mailbox 15 Acceptance Mask Low Register */
-
-/* CAN Controller 1 Mailbox Acceptance Registers */
-
-#define                       CAN1_AM16L  0xffc03380   /* CAN Controller 1 Mailbox 16 Acceptance Mask High Register */
-#define                       CAN1_AM16H  0xffc03384   /* CAN Controller 1 Mailbox 16 Acceptance Mask Low Register */
-#define                       CAN1_AM17L  0xffc03388   /* CAN Controller 1 Mailbox 17 Acceptance Mask High Register */
-#define                       CAN1_AM17H  0xffc0338c   /* CAN Controller 1 Mailbox 17 Acceptance Mask Low Register */
-#define                       CAN1_AM18L  0xffc03390   /* CAN Controller 1 Mailbox 18 Acceptance Mask High Register */
-#define                       CAN1_AM18H  0xffc03394   /* CAN Controller 1 Mailbox 18 Acceptance Mask Low Register */
-#define                       CAN1_AM19L  0xffc03398   /* CAN Controller 1 Mailbox 19 Acceptance Mask High Register */
-#define                       CAN1_AM19H  0xffc0339c   /* CAN Controller 1 Mailbox 19 Acceptance Mask Low Register */
-#define                       CAN1_AM20L  0xffc033a0   /* CAN Controller 1 Mailbox 20 Acceptance Mask High Register */
-#define                       CAN1_AM20H  0xffc033a4   /* CAN Controller 1 Mailbox 20 Acceptance Mask Low Register */
-#define                       CAN1_AM21L  0xffc033a8   /* CAN Controller 1 Mailbox 21 Acceptance Mask High Register */
-#define                       CAN1_AM21H  0xffc033ac   /* CAN Controller 1 Mailbox 21 Acceptance Mask Low Register */
-#define                       CAN1_AM22L  0xffc033b0   /* CAN Controller 1 Mailbox 22 Acceptance Mask High Register */
-#define                       CAN1_AM22H  0xffc033b4   /* CAN Controller 1 Mailbox 22 Acceptance Mask Low Register */
-#define                       CAN1_AM23L  0xffc033b8   /* CAN Controller 1 Mailbox 23 Acceptance Mask High Register */
-#define                       CAN1_AM23H  0xffc033bc   /* CAN Controller 1 Mailbox 23 Acceptance Mask Low Register */
-#define                       CAN1_AM24L  0xffc033c0   /* CAN Controller 1 Mailbox 24 Acceptance Mask High Register */
-#define                       CAN1_AM24H  0xffc033c4   /* CAN Controller 1 Mailbox 24 Acceptance Mask Low Register */
-#define                       CAN1_AM25L  0xffc033c8   /* CAN Controller 1 Mailbox 25 Acceptance Mask High Register */
-#define                       CAN1_AM25H  0xffc033cc   /* CAN Controller 1 Mailbox 25 Acceptance Mask Low Register */
-#define                       CAN1_AM26L  0xffc033d0   /* CAN Controller 1 Mailbox 26 Acceptance Mask High Register */
-#define                       CAN1_AM26H  0xffc033d4   /* CAN Controller 1 Mailbox 26 Acceptance Mask Low Register */
-#define                       CAN1_AM27L  0xffc033d8   /* CAN Controller 1 Mailbox 27 Acceptance Mask High Register */
-#define                       CAN1_AM27H  0xffc033dc   /* CAN Controller 1 Mailbox 27 Acceptance Mask Low Register */
-#define                       CAN1_AM28L  0xffc033e0   /* CAN Controller 1 Mailbox 28 Acceptance Mask High Register */
-#define                       CAN1_AM28H  0xffc033e4   /* CAN Controller 1 Mailbox 28 Acceptance Mask Low Register */
-#define                       CAN1_AM29L  0xffc033e8   /* CAN Controller 1 Mailbox 29 Acceptance Mask High Register */
-#define                       CAN1_AM29H  0xffc033ec   /* CAN Controller 1 Mailbox 29 Acceptance Mask Low Register */
-#define                       CAN1_AM30L  0xffc033f0   /* CAN Controller 1 Mailbox 30 Acceptance Mask High Register */
-#define                       CAN1_AM30H  0xffc033f4   /* CAN Controller 1 Mailbox 30 Acceptance Mask Low Register */
-#define                       CAN1_AM31L  0xffc033f8   /* CAN Controller 1 Mailbox 31 Acceptance Mask High Register */
-#define                       CAN1_AM31H  0xffc033fc   /* CAN Controller 1 Mailbox 31 Acceptance Mask Low Register */
-
-/* CAN Controller 1 Mailbox Data Registers */
-
-#define                  CAN1_MB00_DATA0  0xffc03400   /* CAN Controller 1 Mailbox 0 Data 0 Register */
-#define                  CAN1_MB00_DATA1  0xffc03404   /* CAN Controller 1 Mailbox 0 Data 1 Register */
-#define                  CAN1_MB00_DATA2  0xffc03408   /* CAN Controller 1 Mailbox 0 Data 2 Register */
-#define                  CAN1_MB00_DATA3  0xffc0340c   /* CAN Controller 1 Mailbox 0 Data 3 Register */
-#define                 CAN1_MB00_LENGTH  0xffc03410   /* CAN Controller 1 Mailbox 0 Length Register */
-#define              CAN1_MB00_TIMESTAMP  0xffc03414   /* CAN Controller 1 Mailbox 0 Timestamp Register */
-#define                    CAN1_MB00_ID0  0xffc03418   /* CAN Controller 1 Mailbox 0 ID0 Register */
-#define                    CAN1_MB00_ID1  0xffc0341c   /* CAN Controller 1 Mailbox 0 ID1 Register */
-#define                  CAN1_MB01_DATA0  0xffc03420   /* CAN Controller 1 Mailbox 1 Data 0 Register */
-#define                  CAN1_MB01_DATA1  0xffc03424   /* CAN Controller 1 Mailbox 1 Data 1 Register */
-#define                  CAN1_MB01_DATA2  0xffc03428   /* CAN Controller 1 Mailbox 1 Data 2 Register */
-#define                  CAN1_MB01_DATA3  0xffc0342c   /* CAN Controller 1 Mailbox 1 Data 3 Register */
-#define                 CAN1_MB01_LENGTH  0xffc03430   /* CAN Controller 1 Mailbox 1 Length Register */
-#define              CAN1_MB01_TIMESTAMP  0xffc03434   /* CAN Controller 1 Mailbox 1 Timestamp Register */
-#define                    CAN1_MB01_ID0  0xffc03438   /* CAN Controller 1 Mailbox 1 ID0 Register */
-#define                    CAN1_MB01_ID1  0xffc0343c   /* CAN Controller 1 Mailbox 1 ID1 Register */
-#define                  CAN1_MB02_DATA0  0xffc03440   /* CAN Controller 1 Mailbox 2 Data 0 Register */
-#define                  CAN1_MB02_DATA1  0xffc03444   /* CAN Controller 1 Mailbox 2 Data 1 Register */
-#define                  CAN1_MB02_DATA2  0xffc03448   /* CAN Controller 1 Mailbox 2 Data 2 Register */
-#define                  CAN1_MB02_DATA3  0xffc0344c   /* CAN Controller 1 Mailbox 2 Data 3 Register */
-#define                 CAN1_MB02_LENGTH  0xffc03450   /* CAN Controller 1 Mailbox 2 Length Register */
-#define              CAN1_MB02_TIMESTAMP  0xffc03454   /* CAN Controller 1 Mailbox 2 Timestamp Register */
-#define                    CAN1_MB02_ID0  0xffc03458   /* CAN Controller 1 Mailbox 2 ID0 Register */
-#define                    CAN1_MB02_ID1  0xffc0345c   /* CAN Controller 1 Mailbox 2 ID1 Register */
-#define                  CAN1_MB03_DATA0  0xffc03460   /* CAN Controller 1 Mailbox 3 Data 0 Register */
-#define                  CAN1_MB03_DATA1  0xffc03464   /* CAN Controller 1 Mailbox 3 Data 1 Register */
-#define                  CAN1_MB03_DATA2  0xffc03468   /* CAN Controller 1 Mailbox 3 Data 2 Register */
-#define                  CAN1_MB03_DATA3  0xffc0346c   /* CAN Controller 1 Mailbox 3 Data 3 Register */
-#define                 CAN1_MB03_LENGTH  0xffc03470   /* CAN Controller 1 Mailbox 3 Length Register */
-#define              CAN1_MB03_TIMESTAMP  0xffc03474   /* CAN Controller 1 Mailbox 3 Timestamp Register */
-#define                    CAN1_MB03_ID0  0xffc03478   /* CAN Controller 1 Mailbox 3 ID0 Register */
-#define                    CAN1_MB03_ID1  0xffc0347c   /* CAN Controller 1 Mailbox 3 ID1 Register */
-#define                  CAN1_MB04_DATA0  0xffc03480   /* CAN Controller 1 Mailbox 4 Data 0 Register */
-#define                  CAN1_MB04_DATA1  0xffc03484   /* CAN Controller 1 Mailbox 4 Data 1 Register */
-#define                  CAN1_MB04_DATA2  0xffc03488   /* CAN Controller 1 Mailbox 4 Data 2 Register */
-#define                  CAN1_MB04_DATA3  0xffc0348c   /* CAN Controller 1 Mailbox 4 Data 3 Register */
-#define                 CAN1_MB04_LENGTH  0xffc03490   /* CAN Controller 1 Mailbox 4 Length Register */
-#define              CAN1_MB04_TIMESTAMP  0xffc03494   /* CAN Controller 1 Mailbox 4 Timestamp Register */
-#define                    CAN1_MB04_ID0  0xffc03498   /* CAN Controller 1 Mailbox 4 ID0 Register */
-#define                    CAN1_MB04_ID1  0xffc0349c   /* CAN Controller 1 Mailbox 4 ID1 Register */
-#define                  CAN1_MB05_DATA0  0xffc034a0   /* CAN Controller 1 Mailbox 5 Data 0 Register */
-#define                  CAN1_MB05_DATA1  0xffc034a4   /* CAN Controller 1 Mailbox 5 Data 1 Register */
-#define                  CAN1_MB05_DATA2  0xffc034a8   /* CAN Controller 1 Mailbox 5 Data 2 Register */
-#define                  CAN1_MB05_DATA3  0xffc034ac   /* CAN Controller 1 Mailbox 5 Data 3 Register */
-#define                 CAN1_MB05_LENGTH  0xffc034b0   /* CAN Controller 1 Mailbox 5 Length Register */
-#define              CAN1_MB05_TIMESTAMP  0xffc034b4   /* CAN Controller 1 Mailbox 5 Timestamp Register */
-#define                    CAN1_MB05_ID0  0xffc034b8   /* CAN Controller 1 Mailbox 5 ID0 Register */
-#define                    CAN1_MB05_ID1  0xffc034bc   /* CAN Controller 1 Mailbox 5 ID1 Register */
-#define                  CAN1_MB06_DATA0  0xffc034c0   /* CAN Controller 1 Mailbox 6 Data 0 Register */
-#define                  CAN1_MB06_DATA1  0xffc034c4   /* CAN Controller 1 Mailbox 6 Data 1 Register */
-#define                  CAN1_MB06_DATA2  0xffc034c8   /* CAN Controller 1 Mailbox 6 Data 2 Register */
-#define                  CAN1_MB06_DATA3  0xffc034cc   /* CAN Controller 1 Mailbox 6 Data 3 Register */
-#define                 CAN1_MB06_LENGTH  0xffc034d0   /* CAN Controller 1 Mailbox 6 Length Register */
-#define              CAN1_MB06_TIMESTAMP  0xffc034d4   /* CAN Controller 1 Mailbox 6 Timestamp Register */
-#define                    CAN1_MB06_ID0  0xffc034d8   /* CAN Controller 1 Mailbox 6 ID0 Register */
-#define                    CAN1_MB06_ID1  0xffc034dc   /* CAN Controller 1 Mailbox 6 ID1 Register */
-#define                  CAN1_MB07_DATA0  0xffc034e0   /* CAN Controller 1 Mailbox 7 Data 0 Register */
-#define                  CAN1_MB07_DATA1  0xffc034e4   /* CAN Controller 1 Mailbox 7 Data 1 Register */
-#define                  CAN1_MB07_DATA2  0xffc034e8   /* CAN Controller 1 Mailbox 7 Data 2 Register */
-#define                  CAN1_MB07_DATA3  0xffc034ec   /* CAN Controller 1 Mailbox 7 Data 3 Register */
-#define                 CAN1_MB07_LENGTH  0xffc034f0   /* CAN Controller 1 Mailbox 7 Length Register */
-#define              CAN1_MB07_TIMESTAMP  0xffc034f4   /* CAN Controller 1 Mailbox 7 Timestamp Register */
-#define                    CAN1_MB07_ID0  0xffc034f8   /* CAN Controller 1 Mailbox 7 ID0 Register */
-#define                    CAN1_MB07_ID1  0xffc034fc   /* CAN Controller 1 Mailbox 7 ID1 Register */
-#define                  CAN1_MB08_DATA0  0xffc03500   /* CAN Controller 1 Mailbox 8 Data 0 Register */
-#define                  CAN1_MB08_DATA1  0xffc03504   /* CAN Controller 1 Mailbox 8 Data 1 Register */
-#define                  CAN1_MB08_DATA2  0xffc03508   /* CAN Controller 1 Mailbox 8 Data 2 Register */
-#define                  CAN1_MB08_DATA3  0xffc0350c   /* CAN Controller 1 Mailbox 8 Data 3 Register */
-#define                 CAN1_MB08_LENGTH  0xffc03510   /* CAN Controller 1 Mailbox 8 Length Register */
-#define              CAN1_MB08_TIMESTAMP  0xffc03514   /* CAN Controller 1 Mailbox 8 Timestamp Register */
-#define                    CAN1_MB08_ID0  0xffc03518   /* CAN Controller 1 Mailbox 8 ID0 Register */
-#define                    CAN1_MB08_ID1  0xffc0351c   /* CAN Controller 1 Mailbox 8 ID1 Register */
-#define                  CAN1_MB09_DATA0  0xffc03520   /* CAN Controller 1 Mailbox 9 Data 0 Register */
-#define                  CAN1_MB09_DATA1  0xffc03524   /* CAN Controller 1 Mailbox 9 Data 1 Register */
-#define                  CAN1_MB09_DATA2  0xffc03528   /* CAN Controller 1 Mailbox 9 Data 2 Register */
-#define                  CAN1_MB09_DATA3  0xffc0352c   /* CAN Controller 1 Mailbox 9 Data 3 Register */
-#define                 CAN1_MB09_LENGTH  0xffc03530   /* CAN Controller 1 Mailbox 9 Length Register */
-#define              CAN1_MB09_TIMESTAMP  0xffc03534   /* CAN Controller 1 Mailbox 9 Timestamp Register */
-#define                    CAN1_MB09_ID0  0xffc03538   /* CAN Controller 1 Mailbox 9 ID0 Register */
-#define                    CAN1_MB09_ID1  0xffc0353c   /* CAN Controller 1 Mailbox 9 ID1 Register */
-#define                  CAN1_MB10_DATA0  0xffc03540   /* CAN Controller 1 Mailbox 10 Data 0 Register */
-#define                  CAN1_MB10_DATA1  0xffc03544   /* CAN Controller 1 Mailbox 10 Data 1 Register */
-#define                  CAN1_MB10_DATA2  0xffc03548   /* CAN Controller 1 Mailbox 10 Data 2 Register */
-#define                  CAN1_MB10_DATA3  0xffc0354c   /* CAN Controller 1 Mailbox 10 Data 3 Register */
-#define                 CAN1_MB10_LENGTH  0xffc03550   /* CAN Controller 1 Mailbox 10 Length Register */
-#define              CAN1_MB10_TIMESTAMP  0xffc03554   /* CAN Controller 1 Mailbox 10 Timestamp Register */
-#define                    CAN1_MB10_ID0  0xffc03558   /* CAN Controller 1 Mailbox 10 ID0 Register */
-#define                    CAN1_MB10_ID1  0xffc0355c   /* CAN Controller 1 Mailbox 10 ID1 Register */
-#define                  CAN1_MB11_DATA0  0xffc03560   /* CAN Controller 1 Mailbox 11 Data 0 Register */
-#define                  CAN1_MB11_DATA1  0xffc03564   /* CAN Controller 1 Mailbox 11 Data 1 Register */
-#define                  CAN1_MB11_DATA2  0xffc03568   /* CAN Controller 1 Mailbox 11 Data 2 Register */
-#define                  CAN1_MB11_DATA3  0xffc0356c   /* CAN Controller 1 Mailbox 11 Data 3 Register */
-#define                 CAN1_MB11_LENGTH  0xffc03570   /* CAN Controller 1 Mailbox 11 Length Register */
-#define              CAN1_MB11_TIMESTAMP  0xffc03574   /* CAN Controller 1 Mailbox 11 Timestamp Register */
-#define                    CAN1_MB11_ID0  0xffc03578   /* CAN Controller 1 Mailbox 11 ID0 Register */
-#define                    CAN1_MB11_ID1  0xffc0357c   /* CAN Controller 1 Mailbox 11 ID1 Register */
-#define                  CAN1_MB12_DATA0  0xffc03580   /* CAN Controller 1 Mailbox 12 Data 0 Register */
-#define                  CAN1_MB12_DATA1  0xffc03584   /* CAN Controller 1 Mailbox 12 Data 1 Register */
-#define                  CAN1_MB12_DATA2  0xffc03588   /* CAN Controller 1 Mailbox 12 Data 2 Register */
-#define                  CAN1_MB12_DATA3  0xffc0358c   /* CAN Controller 1 Mailbox 12 Data 3 Register */
-#define                 CAN1_MB12_LENGTH  0xffc03590   /* CAN Controller 1 Mailbox 12 Length Register */
-#define              CAN1_MB12_TIMESTAMP  0xffc03594   /* CAN Controller 1 Mailbox 12 Timestamp Register */
-#define                    CAN1_MB12_ID0  0xffc03598   /* CAN Controller 1 Mailbox 12 ID0 Register */
-#define                    CAN1_MB12_ID1  0xffc0359c   /* CAN Controller 1 Mailbox 12 ID1 Register */
-#define                  CAN1_MB13_DATA0  0xffc035a0   /* CAN Controller 1 Mailbox 13 Data 0 Register */
-#define                  CAN1_MB13_DATA1  0xffc035a4   /* CAN Controller 1 Mailbox 13 Data 1 Register */
-#define                  CAN1_MB13_DATA2  0xffc035a8   /* CAN Controller 1 Mailbox 13 Data 2 Register */
-#define                  CAN1_MB13_DATA3  0xffc035ac   /* CAN Controller 1 Mailbox 13 Data 3 Register */
-#define                 CAN1_MB13_LENGTH  0xffc035b0   /* CAN Controller 1 Mailbox 13 Length Register */
-#define              CAN1_MB13_TIMESTAMP  0xffc035b4   /* CAN Controller 1 Mailbox 13 Timestamp Register */
-#define                    CAN1_MB13_ID0  0xffc035b8   /* CAN Controller 1 Mailbox 13 ID0 Register */
-#define                    CAN1_MB13_ID1  0xffc035bc   /* CAN Controller 1 Mailbox 13 ID1 Register */
-#define                  CAN1_MB14_DATA0  0xffc035c0   /* CAN Controller 1 Mailbox 14 Data 0 Register */
-#define                  CAN1_MB14_DATA1  0xffc035c4   /* CAN Controller 1 Mailbox 14 Data 1 Register */
-#define                  CAN1_MB14_DATA2  0xffc035c8   /* CAN Controller 1 Mailbox 14 Data 2 Register */
-#define                  CAN1_MB14_DATA3  0xffc035cc   /* CAN Controller 1 Mailbox 14 Data 3 Register */
-#define                 CAN1_MB14_LENGTH  0xffc035d0   /* CAN Controller 1 Mailbox 14 Length Register */
-#define              CAN1_MB14_TIMESTAMP  0xffc035d4   /* CAN Controller 1 Mailbox 14 Timestamp Register */
-#define                    CAN1_MB14_ID0  0xffc035d8   /* CAN Controller 1 Mailbox 14 ID0 Register */
-#define                    CAN1_MB14_ID1  0xffc035dc   /* CAN Controller 1 Mailbox 14 ID1 Register */
-#define                  CAN1_MB15_DATA0  0xffc035e0   /* CAN Controller 1 Mailbox 15 Data 0 Register */
-#define                  CAN1_MB15_DATA1  0xffc035e4   /* CAN Controller 1 Mailbox 15 Data 1 Register */
-#define                  CAN1_MB15_DATA2  0xffc035e8   /* CAN Controller 1 Mailbox 15 Data 2 Register */
-#define                  CAN1_MB15_DATA3  0xffc035ec   /* CAN Controller 1 Mailbox 15 Data 3 Register */
-#define                 CAN1_MB15_LENGTH  0xffc035f0   /* CAN Controller 1 Mailbox 15 Length Register */
-#define              CAN1_MB15_TIMESTAMP  0xffc035f4   /* CAN Controller 1 Mailbox 15 Timestamp Register */
-#define                    CAN1_MB15_ID0  0xffc035f8   /* CAN Controller 1 Mailbox 15 ID0 Register */
-#define                    CAN1_MB15_ID1  0xffc035fc   /* CAN Controller 1 Mailbox 15 ID1 Register */
-
-/* CAN Controller 1 Mailbox Data Registers */
-
-#define                  CAN1_MB16_DATA0  0xffc03600   /* CAN Controller 1 Mailbox 16 Data 0 Register */
-#define                  CAN1_MB16_DATA1  0xffc03604   /* CAN Controller 1 Mailbox 16 Data 1 Register */
-#define                  CAN1_MB16_DATA2  0xffc03608   /* CAN Controller 1 Mailbox 16 Data 2 Register */
-#define                  CAN1_MB16_DATA3  0xffc0360c   /* CAN Controller 1 Mailbox 16 Data 3 Register */
-#define                 CAN1_MB16_LENGTH  0xffc03610   /* CAN Controller 1 Mailbox 16 Length Register */
-#define              CAN1_MB16_TIMESTAMP  0xffc03614   /* CAN Controller 1 Mailbox 16 Timestamp Register */
-#define                    CAN1_MB16_ID0  0xffc03618   /* CAN Controller 1 Mailbox 16 ID0 Register */
-#define                    CAN1_MB16_ID1  0xffc0361c   /* CAN Controller 1 Mailbox 16 ID1 Register */
-#define                  CAN1_MB17_DATA0  0xffc03620   /* CAN Controller 1 Mailbox 17 Data 0 Register */
-#define                  CAN1_MB17_DATA1  0xffc03624   /* CAN Controller 1 Mailbox 17 Data 1 Register */
-#define                  CAN1_MB17_DATA2  0xffc03628   /* CAN Controller 1 Mailbox 17 Data 2 Register */
-#define                  CAN1_MB17_DATA3  0xffc0362c   /* CAN Controller 1 Mailbox 17 Data 3 Register */
-#define                 CAN1_MB17_LENGTH  0xffc03630   /* CAN Controller 1 Mailbox 17 Length Register */
-#define              CAN1_MB17_TIMESTAMP  0xffc03634   /* CAN Controller 1 Mailbox 17 Timestamp Register */
-#define                    CAN1_MB17_ID0  0xffc03638   /* CAN Controller 1 Mailbox 17 ID0 Register */
-#define                    CAN1_MB17_ID1  0xffc0363c   /* CAN Controller 1 Mailbox 17 ID1 Register */
-#define                  CAN1_MB18_DATA0  0xffc03640   /* CAN Controller 1 Mailbox 18 Data 0 Register */
-#define                  CAN1_MB18_DATA1  0xffc03644   /* CAN Controller 1 Mailbox 18 Data 1 Register */
-#define                  CAN1_MB18_DATA2  0xffc03648   /* CAN Controller 1 Mailbox 18 Data 2 Register */
-#define                  CAN1_MB18_DATA3  0xffc0364c   /* CAN Controller 1 Mailbox 18 Data 3 Register */
-#define                 CAN1_MB18_LENGTH  0xffc03650   /* CAN Controller 1 Mailbox 18 Length Register */
-#define              CAN1_MB18_TIMESTAMP  0xffc03654   /* CAN Controller 1 Mailbox 18 Timestamp Register */
-#define                    CAN1_MB18_ID0  0xffc03658   /* CAN Controller 1 Mailbox 18 ID0 Register */
-#define                    CAN1_MB18_ID1  0xffc0365c   /* CAN Controller 1 Mailbox 18 ID1 Register */
-#define                  CAN1_MB19_DATA0  0xffc03660   /* CAN Controller 1 Mailbox 19 Data 0 Register */
-#define                  CAN1_MB19_DATA1  0xffc03664   /* CAN Controller 1 Mailbox 19 Data 1 Register */
-#define                  CAN1_MB19_DATA2  0xffc03668   /* CAN Controller 1 Mailbox 19 Data 2 Register */
-#define                  CAN1_MB19_DATA3  0xffc0366c   /* CAN Controller 1 Mailbox 19 Data 3 Register */
-#define                 CAN1_MB19_LENGTH  0xffc03670   /* CAN Controller 1 Mailbox 19 Length Register */
-#define              CAN1_MB19_TIMESTAMP  0xffc03674   /* CAN Controller 1 Mailbox 19 Timestamp Register */
-#define                    CAN1_MB19_ID0  0xffc03678   /* CAN Controller 1 Mailbox 19 ID0 Register */
-#define                    CAN1_MB19_ID1  0xffc0367c   /* CAN Controller 1 Mailbox 19 ID1 Register */
-#define                  CAN1_MB20_DATA0  0xffc03680   /* CAN Controller 1 Mailbox 20 Data 0 Register */
-#define                  CAN1_MB20_DATA1  0xffc03684   /* CAN Controller 1 Mailbox 20 Data 1 Register */
-#define                  CAN1_MB20_DATA2  0xffc03688   /* CAN Controller 1 Mailbox 20 Data 2 Register */
-#define                  CAN1_MB20_DATA3  0xffc0368c   /* CAN Controller 1 Mailbox 20 Data 3 Register */
-#define                 CAN1_MB20_LENGTH  0xffc03690   /* CAN Controller 1 Mailbox 20 Length Register */
-#define              CAN1_MB20_TIMESTAMP  0xffc03694   /* CAN Controller 1 Mailbox 20 Timestamp Register */
-#define                    CAN1_MB20_ID0  0xffc03698   /* CAN Controller 1 Mailbox 20 ID0 Register */
-#define                    CAN1_MB20_ID1  0xffc0369c   /* CAN Controller 1 Mailbox 20 ID1 Register */
-#define                  CAN1_MB21_DATA0  0xffc036a0   /* CAN Controller 1 Mailbox 21 Data 0 Register */
-#define                  CAN1_MB21_DATA1  0xffc036a4   /* CAN Controller 1 Mailbox 21 Data 1 Register */
-#define                  CAN1_MB21_DATA2  0xffc036a8   /* CAN Controller 1 Mailbox 21 Data 2 Register */
-#define                  CAN1_MB21_DATA3  0xffc036ac   /* CAN Controller 1 Mailbox 21 Data 3 Register */
-#define                 CAN1_MB21_LENGTH  0xffc036b0   /* CAN Controller 1 Mailbox 21 Length Register */
-#define              CAN1_MB21_TIMESTAMP  0xffc036b4   /* CAN Controller 1 Mailbox 21 Timestamp Register */
-#define                    CAN1_MB21_ID0  0xffc036b8   /* CAN Controller 1 Mailbox 21 ID0 Register */
-#define                    CAN1_MB21_ID1  0xffc036bc   /* CAN Controller 1 Mailbox 21 ID1 Register */
-#define                  CAN1_MB22_DATA0  0xffc036c0   /* CAN Controller 1 Mailbox 22 Data 0 Register */
-#define                  CAN1_MB22_DATA1  0xffc036c4   /* CAN Controller 1 Mailbox 22 Data 1 Register */
-#define                  CAN1_MB22_DATA2  0xffc036c8   /* CAN Controller 1 Mailbox 22 Data 2 Register */
-#define                  CAN1_MB22_DATA3  0xffc036cc   /* CAN Controller 1 Mailbox 22 Data 3 Register */
-#define                 CAN1_MB22_LENGTH  0xffc036d0   /* CAN Controller 1 Mailbox 22 Length Register */
-#define              CAN1_MB22_TIMESTAMP  0xffc036d4   /* CAN Controller 1 Mailbox 22 Timestamp Register */
-#define                    CAN1_MB22_ID0  0xffc036d8   /* CAN Controller 1 Mailbox 22 ID0 Register */
-#define                    CAN1_MB22_ID1  0xffc036dc   /* CAN Controller 1 Mailbox 22 ID1 Register */
-#define                  CAN1_MB23_DATA0  0xffc036e0   /* CAN Controller 1 Mailbox 23 Data 0 Register */
-#define                  CAN1_MB23_DATA1  0xffc036e4   /* CAN Controller 1 Mailbox 23 Data 1 Register */
-#define                  CAN1_MB23_DATA2  0xffc036e8   /* CAN Controller 1 Mailbox 23 Data 2 Register */
-#define                  CAN1_MB23_DATA3  0xffc036ec   /* CAN Controller 1 Mailbox 23 Data 3 Register */
-#define                 CAN1_MB23_LENGTH  0xffc036f0   /* CAN Controller 1 Mailbox 23 Length Register */
-#define              CAN1_MB23_TIMESTAMP  0xffc036f4   /* CAN Controller 1 Mailbox 23 Timestamp Register */
-#define                    CAN1_MB23_ID0  0xffc036f8   /* CAN Controller 1 Mailbox 23 ID0 Register */
-#define                    CAN1_MB23_ID1  0xffc036fc   /* CAN Controller 1 Mailbox 23 ID1 Register */
-#define                  CAN1_MB24_DATA0  0xffc03700   /* CAN Controller 1 Mailbox 24 Data 0 Register */
-#define                  CAN1_MB24_DATA1  0xffc03704   /* CAN Controller 1 Mailbox 24 Data 1 Register */
-#define                  CAN1_MB24_DATA2  0xffc03708   /* CAN Controller 1 Mailbox 24 Data 2 Register */
-#define                  CAN1_MB24_DATA3  0xffc0370c   /* CAN Controller 1 Mailbox 24 Data 3 Register */
-#define                 CAN1_MB24_LENGTH  0xffc03710   /* CAN Controller 1 Mailbox 24 Length Register */
-#define              CAN1_MB24_TIMESTAMP  0xffc03714   /* CAN Controller 1 Mailbox 24 Timestamp Register */
-#define                    CAN1_MB24_ID0  0xffc03718   /* CAN Controller 1 Mailbox 24 ID0 Register */
-#define                    CAN1_MB24_ID1  0xffc0371c   /* CAN Controller 1 Mailbox 24 ID1 Register */
-#define                  CAN1_MB25_DATA0  0xffc03720   /* CAN Controller 1 Mailbox 25 Data 0 Register */
-#define                  CAN1_MB25_DATA1  0xffc03724   /* CAN Controller 1 Mailbox 25 Data 1 Register */
-#define                  CAN1_MB25_DATA2  0xffc03728   /* CAN Controller 1 Mailbox 25 Data 2 Register */
-#define                  CAN1_MB25_DATA3  0xffc0372c   /* CAN Controller 1 Mailbox 25 Data 3 Register */
-#define                 CAN1_MB25_LENGTH  0xffc03730   /* CAN Controller 1 Mailbox 25 Length Register */
-#define              CAN1_MB25_TIMESTAMP  0xffc03734   /* CAN Controller 1 Mailbox 25 Timestamp Register */
-#define                    CAN1_MB25_ID0  0xffc03738   /* CAN Controller 1 Mailbox 25 ID0 Register */
-#define                    CAN1_MB25_ID1  0xffc0373c   /* CAN Controller 1 Mailbox 25 ID1 Register */
-#define                  CAN1_MB26_DATA0  0xffc03740   /* CAN Controller 1 Mailbox 26 Data 0 Register */
-#define                  CAN1_MB26_DATA1  0xffc03744   /* CAN Controller 1 Mailbox 26 Data 1 Register */
-#define                  CAN1_MB26_DATA2  0xffc03748   /* CAN Controller 1 Mailbox 26 Data 2 Register */
-#define                  CAN1_MB26_DATA3  0xffc0374c   /* CAN Controller 1 Mailbox 26 Data 3 Register */
-#define                 CAN1_MB26_LENGTH  0xffc03750   /* CAN Controller 1 Mailbox 26 Length Register */
-#define              CAN1_MB26_TIMESTAMP  0xffc03754   /* CAN Controller 1 Mailbox 26 Timestamp Register */
-#define                    CAN1_MB26_ID0  0xffc03758   /* CAN Controller 1 Mailbox 26 ID0 Register */
-#define                    CAN1_MB26_ID1  0xffc0375c   /* CAN Controller 1 Mailbox 26 ID1 Register */
-#define                  CAN1_MB27_DATA0  0xffc03760   /* CAN Controller 1 Mailbox 27 Data 0 Register */
-#define                  CAN1_MB27_DATA1  0xffc03764   /* CAN Controller 1 Mailbox 27 Data 1 Register */
-#define                  CAN1_MB27_DATA2  0xffc03768   /* CAN Controller 1 Mailbox 27 Data 2 Register */
-#define                  CAN1_MB27_DATA3  0xffc0376c   /* CAN Controller 1 Mailbox 27 Data 3 Register */
-#define                 CAN1_MB27_LENGTH  0xffc03770   /* CAN Controller 1 Mailbox 27 Length Register */
-#define              CAN1_MB27_TIMESTAMP  0xffc03774   /* CAN Controller 1 Mailbox 27 Timestamp Register */
-#define                    CAN1_MB27_ID0  0xffc03778   /* CAN Controller 1 Mailbox 27 ID0 Register */
-#define                    CAN1_MB27_ID1  0xffc0377c   /* CAN Controller 1 Mailbox 27 ID1 Register */
-#define                  CAN1_MB28_DATA0  0xffc03780   /* CAN Controller 1 Mailbox 28 Data 0 Register */
-#define                  CAN1_MB28_DATA1  0xffc03784   /* CAN Controller 1 Mailbox 28 Data 1 Register */
-#define                  CAN1_MB28_DATA2  0xffc03788   /* CAN Controller 1 Mailbox 28 Data 2 Register */
-#define                  CAN1_MB28_DATA3  0xffc0378c   /* CAN Controller 1 Mailbox 28 Data 3 Register */
-#define                 CAN1_MB28_LENGTH  0xffc03790   /* CAN Controller 1 Mailbox 28 Length Register */
-#define              CAN1_MB28_TIMESTAMP  0xffc03794   /* CAN Controller 1 Mailbox 28 Timestamp Register */
-#define                    CAN1_MB28_ID0  0xffc03798   /* CAN Controller 1 Mailbox 28 ID0 Register */
-#define                    CAN1_MB28_ID1  0xffc0379c   /* CAN Controller 1 Mailbox 28 ID1 Register */
-#define                  CAN1_MB29_DATA0  0xffc037a0   /* CAN Controller 1 Mailbox 29 Data 0 Register */
-#define                  CAN1_MB29_DATA1  0xffc037a4   /* CAN Controller 1 Mailbox 29 Data 1 Register */
-#define                  CAN1_MB29_DATA2  0xffc037a8   /* CAN Controller 1 Mailbox 29 Data 2 Register */
-#define                  CAN1_MB29_DATA3  0xffc037ac   /* CAN Controller 1 Mailbox 29 Data 3 Register */
-#define                 CAN1_MB29_LENGTH  0xffc037b0   /* CAN Controller 1 Mailbox 29 Length Register */
-#define              CAN1_MB29_TIMESTAMP  0xffc037b4   /* CAN Controller 1 Mailbox 29 Timestamp Register */
-#define                    CAN1_MB29_ID0  0xffc037b8   /* CAN Controller 1 Mailbox 29 ID0 Register */
-#define                    CAN1_MB29_ID1  0xffc037bc   /* CAN Controller 1 Mailbox 29 ID1 Register */
-#define                  CAN1_MB30_DATA0  0xffc037c0   /* CAN Controller 1 Mailbox 30 Data 0 Register */
-#define                  CAN1_MB30_DATA1  0xffc037c4   /* CAN Controller 1 Mailbox 30 Data 1 Register */
-#define                  CAN1_MB30_DATA2  0xffc037c8   /* CAN Controller 1 Mailbox 30 Data 2 Register */
-#define                  CAN1_MB30_DATA3  0xffc037cc   /* CAN Controller 1 Mailbox 30 Data 3 Register */
-#define                 CAN1_MB30_LENGTH  0xffc037d0   /* CAN Controller 1 Mailbox 30 Length Register */
-#define              CAN1_MB30_TIMESTAMP  0xffc037d4   /* CAN Controller 1 Mailbox 30 Timestamp Register */
-#define                    CAN1_MB30_ID0  0xffc037d8   /* CAN Controller 1 Mailbox 30 ID0 Register */
-#define                    CAN1_MB30_ID1  0xffc037dc   /* CAN Controller 1 Mailbox 30 ID1 Register */
-#define                  CAN1_MB31_DATA0  0xffc037e0   /* CAN Controller 1 Mailbox 31 Data 0 Register */
-#define                  CAN1_MB31_DATA1  0xffc037e4   /* CAN Controller 1 Mailbox 31 Data 1 Register */
-#define                  CAN1_MB31_DATA2  0xffc037e8   /* CAN Controller 1 Mailbox 31 Data 2 Register */
-#define                  CAN1_MB31_DATA3  0xffc037ec   /* CAN Controller 1 Mailbox 31 Data 3 Register */
-#define                 CAN1_MB31_LENGTH  0xffc037f0   /* CAN Controller 1 Mailbox 31 Length Register */
-#define              CAN1_MB31_TIMESTAMP  0xffc037f4   /* CAN Controller 1 Mailbox 31 Timestamp Register */
-#define                    CAN1_MB31_ID0  0xffc037f8   /* CAN Controller 1 Mailbox 31 ID0 Register */
-#define                    CAN1_MB31_ID1  0xffc037fc   /* CAN Controller 1 Mailbox 31 ID1 Register */
-
-/* ATAPI Registers */
-
-#define                    ATAPI_CONTROL  0xffc03800   /* ATAPI Control Register */
-#define                     ATAPI_STATUS  0xffc03804   /* ATAPI Status Register */
-#define                   ATAPI_DEV_ADDR  0xffc03808   /* ATAPI Device Register Address */
-#define                  ATAPI_DEV_TXBUF  0xffc0380c   /* ATAPI Device Register Write Data */
-#define                  ATAPI_DEV_RXBUF  0xffc03810   /* ATAPI Device Register Read Data */
-#define                   ATAPI_INT_MASK  0xffc03814   /* ATAPI Interrupt Mask Register */
-#define                 ATAPI_INT_STATUS  0xffc03818   /* ATAPI Interrupt Status Register */
-#define                   ATAPI_XFER_LEN  0xffc0381c   /* ATAPI Length of Transfer */
-#define                ATAPI_LINE_STATUS  0xffc03820   /* ATAPI Line Status */
-#define                   ATAPI_SM_STATE  0xffc03824   /* ATAPI State Machine Status */
-#define                  ATAPI_TERMINATE  0xffc03828   /* ATAPI Host Terminate */
-#define                 ATAPI_PIO_TFRCNT  0xffc0382c   /* ATAPI PIO mode transfer count */
-#define                 ATAPI_DMA_TFRCNT  0xffc03830   /* ATAPI DMA mode transfer count */
-#define               ATAPI_UMAIN_TFRCNT  0xffc03834   /* ATAPI UDMAIN transfer count */
-#define             ATAPI_UDMAOUT_TFRCNT  0xffc03838   /* ATAPI UDMAOUT transfer count */
-#define                  ATAPI_REG_TIM_0  0xffc03840   /* ATAPI Register Transfer Timing 0 */
-#define                  ATAPI_PIO_TIM_0  0xffc03844   /* ATAPI PIO Timing 0 Register */
-#define                  ATAPI_PIO_TIM_1  0xffc03848   /* ATAPI PIO Timing 1 Register */
-#define                ATAPI_MULTI_TIM_0  0xffc03850   /* ATAPI Multi-DMA Timing 0 Register */
-#define                ATAPI_MULTI_TIM_1  0xffc03854   /* ATAPI Multi-DMA Timing 1 Register */
-#define                ATAPI_MULTI_TIM_2  0xffc03858   /* ATAPI Multi-DMA Timing 2 Register */
-#define                ATAPI_ULTRA_TIM_0  0xffc03860   /* ATAPI Ultra-DMA Timing 0 Register */
-#define                ATAPI_ULTRA_TIM_1  0xffc03864   /* ATAPI Ultra-DMA Timing 1 Register */
-#define                ATAPI_ULTRA_TIM_2  0xffc03868   /* ATAPI Ultra-DMA Timing 2 Register */
-#define                ATAPI_ULTRA_TIM_3  0xffc0386c   /* ATAPI Ultra-DMA Timing 3 Register */
-
-/* SDH Registers */
-
-#define                      SDH_PWR_CTL  0xffc03900   /* SDH Power Control */
-#define                      SDH_CLK_CTL  0xffc03904   /* SDH Clock Control */
-#define                     SDH_ARGUMENT  0xffc03908   /* SDH Argument */
-#define                      SDH_COMMAND  0xffc0390c   /* SDH Command */
-#define                     SDH_RESP_CMD  0xffc03910   /* SDH Response Command */
-#define                    SDH_RESPONSE0  0xffc03914   /* SDH Response0 */
-#define                    SDH_RESPONSE1  0xffc03918   /* SDH Response1 */
-#define                    SDH_RESPONSE2  0xffc0391c   /* SDH Response2 */
-#define                    SDH_RESPONSE3  0xffc03920   /* SDH Response3 */
-#define                   SDH_DATA_TIMER  0xffc03924   /* SDH Data Timer */
-#define                    SDH_DATA_LGTH  0xffc03928   /* SDH Data Length */
-#define                     SDH_DATA_CTL  0xffc0392c   /* SDH Data Control */
-#define                     SDH_DATA_CNT  0xffc03930   /* SDH Data Counter */
-#define                       SDH_STATUS  0xffc03934   /* SDH Status */
-#define                   SDH_STATUS_CLR  0xffc03938   /* SDH Status Clear */
-#define                        SDH_MASK0  0xffc0393c   /* SDH Interrupt0 Mask */
-#define                        SDH_MASK1  0xffc03940   /* SDH Interrupt1 Mask */
-#define                     SDH_FIFO_CNT  0xffc03948   /* SDH FIFO Counter */
-#define                         SDH_FIFO  0xffc03980   /* SDH Data FIFO */
-#define                     SDH_E_STATUS  0xffc039c0   /* SDH Exception Status */
-#define                       SDH_E_MASK  0xffc039c4   /* SDH Exception Mask */
-#define                          SDH_CFG  0xffc039c8   /* SDH Configuration */
-#define                   SDH_RD_WAIT_EN  0xffc039cc   /* SDH Read Wait Enable */
-#define                         SDH_PID0  0xffc039d0   /* SDH Peripheral Identification0 */
-#define                         SDH_PID1  0xffc039d4   /* SDH Peripheral Identification1 */
-#define                         SDH_PID2  0xffc039d8   /* SDH Peripheral Identification2 */
-#define                         SDH_PID3  0xffc039dc   /* SDH Peripheral Identification3 */
-#define                         SDH_PID4  0xffc039e0   /* SDH Peripheral Identification4 */
-#define                         SDH_PID5  0xffc039e4   /* SDH Peripheral Identification5 */
-#define                         SDH_PID6  0xffc039e8   /* SDH Peripheral Identification6 */
-#define                         SDH_PID7  0xffc039ec   /* SDH Peripheral Identification7 */
-
-/* HOST Port Registers */
-
-#define                     HOST_CONTROL  0xffc03a00   /* HOST Control Register */
-#define                      HOST_STATUS  0xffc03a04   /* HOST Status Register */
-#define                     HOST_TIMEOUT  0xffc03a08   /* HOST Acknowledge Mode Timeout Register */
-
-/* USB Control Registers */
-
-#define                        USB_FADDR  0xffc03c00   /* Function address register */
-#define                        USB_POWER  0xffc03c04   /* Power management register */
-#define                       USB_INTRTX  0xffc03c08   /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */
-#define                       USB_INTRRX  0xffc03c0c   /* Interrupt register for Rx endpoints 1 to 7 */
-#define                      USB_INTRTXE  0xffc03c10   /* Interrupt enable register for IntrTx */
-#define                      USB_INTRRXE  0xffc03c14   /* Interrupt enable register for IntrRx */
-#define                      USB_INTRUSB  0xffc03c18   /* Interrupt register for common USB interrupts */
-#define                     USB_INTRUSBE  0xffc03c1c   /* Interrupt enable register for IntrUSB */
-#define                        USB_FRAME  0xffc03c20   /* USB frame number */
-#define                        USB_INDEX  0xffc03c24   /* Index register for selecting the indexed endpoint registers */
-#define                     USB_TESTMODE  0xffc03c28   /* Enabled USB 20 test modes */
-#define                     USB_GLOBINTR  0xffc03c2c   /* Global Interrupt Mask register and Wakeup Exception Interrupt */
-#define                   USB_GLOBAL_CTL  0xffc03c30   /* Global Clock Control for the core */
-
-/* USB Packet Control Registers */
-
-#define                USB_TX_MAX_PACKET  0xffc03c40   /* Maximum packet size for Host Tx endpoint */
-#define                         USB_CSR0  0xffc03c44   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                        USB_TXCSR  0xffc03c44   /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */
-#define                USB_RX_MAX_PACKET  0xffc03c48   /* Maximum packet size for Host Rx endpoint */
-#define                        USB_RXCSR  0xffc03c4c   /* Control Status register for Host Rx endpoint */
-#define                       USB_COUNT0  0xffc03c50   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                      USB_RXCOUNT  0xffc03c50   /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */
-#define                       USB_TXTYPE  0xffc03c54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */
-#define                    USB_NAKLIMIT0  0xffc03c58   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                   USB_TXINTERVAL  0xffc03c58   /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */
-#define                       USB_RXTYPE  0xffc03c5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */
-#define                   USB_RXINTERVAL  0xffc03c60   /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */
-#define                      USB_TXCOUNT  0xffc03c68   /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* USB Endpoint FIFO Registers */
-
-#define                     USB_EP0_FIFO  0xffc03c80   /* Endpoint 0 FIFO */
-#define                     USB_EP1_FIFO  0xffc03c88   /* Endpoint 1 FIFO */
-#define                     USB_EP2_FIFO  0xffc03c90   /* Endpoint 2 FIFO */
-#define                     USB_EP3_FIFO  0xffc03c98   /* Endpoint 3 FIFO */
-#define                     USB_EP4_FIFO  0xffc03ca0   /* Endpoint 4 FIFO */
-#define                     USB_EP5_FIFO  0xffc03ca8   /* Endpoint 5 FIFO */
-#define                     USB_EP6_FIFO  0xffc03cb0   /* Endpoint 6 FIFO */
-#define                     USB_EP7_FIFO  0xffc03cb8   /* Endpoint 7 FIFO */
-
-/* USB OTG Control Registers */
-
-#define                  USB_OTG_DEV_CTL  0xffc03d00   /* OTG Device Control Register */
-#define                 USB_OTG_VBUS_IRQ  0xffc03d04   /* OTG VBUS Control Interrupts */
-#define                USB_OTG_VBUS_MASK  0xffc03d08   /* VBUS Control Interrupt Enable */
-
-/* USB Phy Control Registers */
-
-#define                     USB_LINKINFO  0xffc03d48   /* Enables programming of some PHY-side delays */
-#define                        USB_VPLEN  0xffc03d4c   /* Determines duration of VBUS pulse for VBUS charging */
-#define                      USB_HS_EOF1  0xffc03d50   /* Time buffer for High-Speed transactions */
-#define                      USB_FS_EOF1  0xffc03d54   /* Time buffer for Full-Speed transactions */
-#define                      USB_LS_EOF1  0xffc03d58   /* Time buffer for Low-Speed transactions */
-
-/* (APHY_CNTRL is for ADI usage only) */
-
-#define                   USB_APHY_CNTRL  0xffc03de0   /* Register that increases visibility of Analog PHY */
-
-/* (APHY_CALIB is for ADI usage only) */
-
-#define                   USB_APHY_CALIB  0xffc03de4   /* Register used to set some calibration values */
-#define                  USB_APHY_CNTRL2  0xffc03de8   /* Register used to prevent re-enumeration once Moab goes into hibernate mode */
-
-/* (PHY_TEST is for ADI usage only) */
-
-#define                     USB_PHY_TEST  0xffc03dec   /* Used for reducing simulation time and simplifies FIFO testability */
-#define                  USB_PLLOSC_CTRL  0xffc03df0   /* Used to program different parameters for USB PLL and Oscillator */
-#define                   USB_SRP_CLKDIV  0xffc03df4   /* Used to program clock divide value for the clock fed to the SRP detection logic */
-
-/* USB Endpoint 0 Control Registers */
-
-#define                USB_EP_NI0_TXMAXP  0xffc03e00   /* Maximum packet size for Host Tx endpoint0 */
-#define                 USB_EP_NI0_TXCSR  0xffc03e04   /* Control Status register for endpoint 0 */
-#define                USB_EP_NI0_RXMAXP  0xffc03e08   /* Maximum packet size for Host Rx endpoint0 */
-#define                 USB_EP_NI0_RXCSR  0xffc03e0c   /* Control Status register for Host Rx endpoint0 */
-#define               USB_EP_NI0_RXCOUNT  0xffc03e10   /* Number of bytes received in endpoint 0 FIFO */
-#define                USB_EP_NI0_TXTYPE  0xffc03e14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */
-#define            USB_EP_NI0_TXINTERVAL  0xffc03e18   /* Sets the NAK response timeout on Endpoint 0 */
-#define                USB_EP_NI0_RXTYPE  0xffc03e1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */
-#define            USB_EP_NI0_RXINTERVAL  0xffc03e20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */
-
-/* USB Endpoint 1 Control Registers */
-
-#define               USB_EP_NI0_TXCOUNT  0xffc03e28   /* Number of bytes to be written to the endpoint0 Tx FIFO */
-#define                USB_EP_NI1_TXMAXP  0xffc03e40   /* Maximum packet size for Host Tx endpoint1 */
-#define                 USB_EP_NI1_TXCSR  0xffc03e44   /* Control Status register for endpoint1 */
-#define                USB_EP_NI1_RXMAXP  0xffc03e48   /* Maximum packet size for Host Rx endpoint1 */
-#define                 USB_EP_NI1_RXCSR  0xffc03e4c   /* Control Status register for Host Rx endpoint1 */
-#define               USB_EP_NI1_RXCOUNT  0xffc03e50   /* Number of bytes received in endpoint1 FIFO */
-#define                USB_EP_NI1_TXTYPE  0xffc03e54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */
-#define            USB_EP_NI1_TXINTERVAL  0xffc03e58   /* Sets the NAK response timeout on Endpoint1 */
-#define                USB_EP_NI1_RXTYPE  0xffc03e5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */
-#define            USB_EP_NI1_RXINTERVAL  0xffc03e60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */
-
-/* USB Endpoint 2 Control Registers */
-
-#define               USB_EP_NI1_TXCOUNT  0xffc03e68   /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */
-#define                USB_EP_NI2_TXMAXP  0xffc03e80   /* Maximum packet size for Host Tx endpoint2 */
-#define                 USB_EP_NI2_TXCSR  0xffc03e84   /* Control Status register for endpoint2 */
-#define                USB_EP_NI2_RXMAXP  0xffc03e88   /* Maximum packet size for Host Rx endpoint2 */
-#define                 USB_EP_NI2_RXCSR  0xffc03e8c   /* Control Status register for Host Rx endpoint2 */
-#define               USB_EP_NI2_RXCOUNT  0xffc03e90   /* Number of bytes received in endpoint2 FIFO */
-#define                USB_EP_NI2_TXTYPE  0xffc03e94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */
-#define            USB_EP_NI2_TXINTERVAL  0xffc03e98   /* Sets the NAK response timeout on Endpoint2 */
-#define                USB_EP_NI2_RXTYPE  0xffc03e9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */
-#define            USB_EP_NI2_RXINTERVAL  0xffc03ea0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */
-
-/* USB Endpoint 3 Control Registers */
-
-#define               USB_EP_NI2_TXCOUNT  0xffc03ea8   /* Number of bytes to be written to the endpoint2 Tx FIFO */
-#define                USB_EP_NI3_TXMAXP  0xffc03ec0   /* Maximum packet size for Host Tx endpoint3 */
-#define                 USB_EP_NI3_TXCSR  0xffc03ec4   /* Control Status register for endpoint3 */
-#define                USB_EP_NI3_RXMAXP  0xffc03ec8   /* Maximum packet size for Host Rx endpoint3 */
-#define                 USB_EP_NI3_RXCSR  0xffc03ecc   /* Control Status register for Host Rx endpoint3 */
-#define               USB_EP_NI3_RXCOUNT  0xffc03ed0   /* Number of bytes received in endpoint3 FIFO */
-#define                USB_EP_NI3_TXTYPE  0xffc03ed4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */
-#define            USB_EP_NI3_TXINTERVAL  0xffc03ed8   /* Sets the NAK response timeout on Endpoint3 */
-#define                USB_EP_NI3_RXTYPE  0xffc03edc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */
-#define            USB_EP_NI3_RXINTERVAL  0xffc03ee0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */
-
-/* USB Endpoint 4 Control Registers */
-
-#define               USB_EP_NI3_TXCOUNT  0xffc03ee8   /* Number of bytes to be written to the H124endpoint3 Tx FIFO */
-#define                USB_EP_NI4_TXMAXP  0xffc03f00   /* Maximum packet size for Host Tx endpoint4 */
-#define                 USB_EP_NI4_TXCSR  0xffc03f04   /* Control Status register for endpoint4 */
-#define                USB_EP_NI4_RXMAXP  0xffc03f08   /* Maximum packet size for Host Rx endpoint4 */
-#define                 USB_EP_NI4_RXCSR  0xffc03f0c   /* Control Status register for Host Rx endpoint4 */
-#define               USB_EP_NI4_RXCOUNT  0xffc03f10   /* Number of bytes received in endpoint4 FIFO */
-#define                USB_EP_NI4_TXTYPE  0xffc03f14   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */
-#define            USB_EP_NI4_TXINTERVAL  0xffc03f18   /* Sets the NAK response timeout on Endpoint4 */
-#define                USB_EP_NI4_RXTYPE  0xffc03f1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */
-#define            USB_EP_NI4_RXINTERVAL  0xffc03f20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */
-
-/* USB Endpoint 5 Control Registers */
-
-#define               USB_EP_NI4_TXCOUNT  0xffc03f28   /* Number of bytes to be written to the endpoint4 Tx FIFO */
-#define                USB_EP_NI5_TXMAXP  0xffc03f40   /* Maximum packet size for Host Tx endpoint5 */
-#define                 USB_EP_NI5_TXCSR  0xffc03f44   /* Control Status register for endpoint5 */
-#define                USB_EP_NI5_RXMAXP  0xffc03f48   /* Maximum packet size for Host Rx endpoint5 */
-#define                 USB_EP_NI5_RXCSR  0xffc03f4c   /* Control Status register for Host Rx endpoint5 */
-#define               USB_EP_NI5_RXCOUNT  0xffc03f50   /* Number of bytes received in endpoint5 FIFO */
-#define                USB_EP_NI5_TXTYPE  0xffc03f54   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */
-#define            USB_EP_NI5_TXINTERVAL  0xffc03f58   /* Sets the NAK response timeout on Endpoint5 */
-#define                USB_EP_NI5_RXTYPE  0xffc03f5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */
-#define            USB_EP_NI5_RXINTERVAL  0xffc03f60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */
-
-/* USB Endpoint 6 Control Registers */
-
-#define               USB_EP_NI5_TXCOUNT  0xffc03f68   /* Number of bytes to be written to the H145endpoint5 Tx FIFO */
-#define                USB_EP_NI6_TXMAXP  0xffc03f80   /* Maximum packet size for Host Tx endpoint6 */
-#define                 USB_EP_NI6_TXCSR  0xffc03f84   /* Control Status register for endpoint6 */
-#define                USB_EP_NI6_RXMAXP  0xffc03f88   /* Maximum packet size for Host Rx endpoint6 */
-#define                 USB_EP_NI6_RXCSR  0xffc03f8c   /* Control Status register for Host Rx endpoint6 */
-#define               USB_EP_NI6_RXCOUNT  0xffc03f90   /* Number of bytes received in endpoint6 FIFO */
-#define                USB_EP_NI6_TXTYPE  0xffc03f94   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */
-#define            USB_EP_NI6_TXINTERVAL  0xffc03f98   /* Sets the NAK response timeout on Endpoint6 */
-#define                USB_EP_NI6_RXTYPE  0xffc03f9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */
-#define            USB_EP_NI6_RXINTERVAL  0xffc03fa0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */
-
-/* USB Endpoint 7 Control Registers */
-
-#define               USB_EP_NI6_TXCOUNT  0xffc03fa8   /* Number of bytes to be written to the endpoint6 Tx FIFO */
-#define                USB_EP_NI7_TXMAXP  0xffc03fc0   /* Maximum packet size for Host Tx endpoint7 */
-#define                 USB_EP_NI7_TXCSR  0xffc03fc4   /* Control Status register for endpoint7 */
-#define                USB_EP_NI7_RXMAXP  0xffc03fc8   /* Maximum packet size for Host Rx endpoint7 */
-#define                 USB_EP_NI7_RXCSR  0xffc03fcc   /* Control Status register for Host Rx endpoint7 */
-#define               USB_EP_NI7_RXCOUNT  0xffc03fd0   /* Number of bytes received in endpoint7 FIFO */
-#define                USB_EP_NI7_TXTYPE  0xffc03fd4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */
-#define            USB_EP_NI7_TXINTERVAL  0xffc03fd8   /* Sets the NAK response timeout on Endpoint7 */
-#define                USB_EP_NI7_RXTYPE  0xffc03fdc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */
-#define            USB_EP_NI7_RXINTERVAL  0xffc03ff0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
-#define               USB_EP_NI7_TXCOUNT  0xffc03ff8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
-#define                USB_DMA_INTERRUPT  0xffc04000   /* Indicates pending interrupts for the DMA channels */
-
-/* USB Channel 0 Config Registers */
-
-#define                  USB_DMA0CONTROL  0xffc04004   /* DMA master channel 0 configuration */
-#define                  USB_DMA0ADDRLOW  0xffc04008   /* Lower 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0ADDRHIGH  0xffc0400c   /* Upper 16-bits of memory source/destination address for DMA master channel 0 */
-#define                 USB_DMA0COUNTLOW  0xffc04010   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */
-#define                USB_DMA0COUNTHIGH  0xffc04014   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */
-
-/* USB Channel 1 Config Registers */
-
-#define                  USB_DMA1CONTROL  0xffc04024   /* DMA master channel 1 configuration */
-#define                  USB_DMA1ADDRLOW  0xffc04028   /* Lower 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1ADDRHIGH  0xffc0402c   /* Upper 16-bits of memory source/destination address for DMA master channel 1 */
-#define                 USB_DMA1COUNTLOW  0xffc04030   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */
-#define                USB_DMA1COUNTHIGH  0xffc04034   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */
-
-/* USB Channel 2 Config Registers */
-
-#define                  USB_DMA2CONTROL  0xffc04044   /* DMA master channel 2 configuration */
-#define                  USB_DMA2ADDRLOW  0xffc04048   /* Lower 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2ADDRHIGH  0xffc0404c   /* Upper 16-bits of memory source/destination address for DMA master channel 2 */
-#define                 USB_DMA2COUNTLOW  0xffc04050   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */
-#define                USB_DMA2COUNTHIGH  0xffc04054   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */
-
-/* USB Channel 3 Config Registers */
-
-#define                  USB_DMA3CONTROL  0xffc04064   /* DMA master channel 3 configuration */
-#define                  USB_DMA3ADDRLOW  0xffc04068   /* Lower 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3ADDRHIGH  0xffc0406c   /* Upper 16-bits of memory source/destination address for DMA master channel 3 */
-#define                 USB_DMA3COUNTLOW  0xffc04070   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */
-#define                USB_DMA3COUNTHIGH  0xffc04074   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */
-
-/* USB Channel 4 Config Registers */
-
-#define                  USB_DMA4CONTROL  0xffc04084   /* DMA master channel 4 configuration */
-#define                  USB_DMA4ADDRLOW  0xffc04088   /* Lower 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4ADDRHIGH  0xffc0408c   /* Upper 16-bits of memory source/destination address for DMA master channel 4 */
-#define                 USB_DMA4COUNTLOW  0xffc04090   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */
-#define                USB_DMA4COUNTHIGH  0xffc04094   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */
-
-/* USB Channel 5 Config Registers */
-
-#define                  USB_DMA5CONTROL  0xffc040a4   /* DMA master channel 5 configuration */
-#define                  USB_DMA5ADDRLOW  0xffc040a8   /* Lower 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5ADDRHIGH  0xffc040ac   /* Upper 16-bits of memory source/destination address for DMA master channel 5 */
-#define                 USB_DMA5COUNTLOW  0xffc040b0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */
-#define                USB_DMA5COUNTHIGH  0xffc040b4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */
-
-/* USB Channel 6 Config Registers */
-
-#define                  USB_DMA6CONTROL  0xffc040c4   /* DMA master channel 6 configuration */
-#define                  USB_DMA6ADDRLOW  0xffc040c8   /* Lower 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6ADDRHIGH  0xffc040cc   /* Upper 16-bits of memory source/destination address for DMA master channel 6 */
-#define                 USB_DMA6COUNTLOW  0xffc040d0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */
-#define                USB_DMA6COUNTHIGH  0xffc040d4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */
-
-/* USB Channel 7 Config Registers */
-
-#define                  USB_DMA7CONTROL  0xffc040e4   /* DMA master channel 7 configuration */
-#define                  USB_DMA7ADDRLOW  0xffc040e8   /* Lower 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7ADDRHIGH  0xffc040ec   /* Upper 16-bits of memory source/destination address for DMA master channel 7 */
-#define                 USB_DMA7COUNTLOW  0xffc040f0   /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */
-#define                USB_DMA7COUNTHIGH  0xffc040f4   /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */
-
-/* Keypad Registers */
-
-#define                         KPAD_CTL  0xffc04100   /* Controls keypad module enable and disable */
-#define                    KPAD_PRESCALE  0xffc04104   /* Establish a time base for programing the KPAD_MSEL register */
-#define                        KPAD_MSEL  0xffc04108   /* Selects delay parameters for keypad interface sensitivity */
-#define                      KPAD_ROWCOL  0xffc0410c   /* Captures the row and column output values of the keys pressed */
-#define                        KPAD_STAT  0xffc04110   /* Holds and clears the status of the keypad interface interrupt */
-#define                    KPAD_SOFTEVAL  0xffc04114   /* Lets software force keypad interface to check for keys being pressed */
-
-/* Pixel Compositor (PIXC) Registers */
-
-#define                         PIXC_CTL  0xffc04400   /* Overlay enable, resampling mode, I/O data format, transparency enable, watermark level, FIFO status */
-#define                         PIXC_PPL  0xffc04404   /* Holds the number of pixels per line of the display */
-#define                         PIXC_LPF  0xffc04408   /* Holds the number of lines per frame of the display */
-#define                     PIXC_AHSTART  0xffc0440c   /* Contains horizontal start pixel information of the overlay data (set A) */
-#define                       PIXC_AHEND  0xffc04410   /* Contains horizontal end pixel information of the overlay data (set A) */
-#define                     PIXC_AVSTART  0xffc04414   /* Contains vertical start pixel information of the overlay data (set A) */
-#define                       PIXC_AVEND  0xffc04418   /* Contains vertical end pixel information of the overlay data (set A) */
-#define                     PIXC_ATRANSP  0xffc0441c   /* Contains the transparency ratio (set A) */
-#define                     PIXC_BHSTART  0xffc04420   /* Contains horizontal start pixel information of the overlay data (set B) */
-#define                       PIXC_BHEND  0xffc04424   /* Contains horizontal end pixel information of the overlay data (set B) */
-#define                     PIXC_BVSTART  0xffc04428   /* Contains vertical start pixel information of the overlay data (set B) */
-#define                       PIXC_BVEND  0xffc0442c   /* Contains vertical end pixel information of the overlay data (set B) */
-#define                     PIXC_BTRANSP  0xffc04430   /* Contains the transparency ratio (set B) */
-#define                    PIXC_INTRSTAT  0xffc0443c   /* Overlay interrupt configuration/status */
-#define                       PIXC_RYCON  0xffc04440   /* Color space conversion matrix register. Contains the R/Y conversion coefficients */
-#define                       PIXC_GUCON  0xffc04444   /* Color space conversion matrix register. Contains the G/U conversion coefficients */
-#define                       PIXC_BVCON  0xffc04448   /* Color space conversion matrix register. Contains the B/V conversion coefficients */
-#define                      PIXC_CCBIAS  0xffc0444c   /* Bias values for the color space conversion matrix */
-#define                          PIXC_TC  0xffc04450   /* Holds the transparent color value */
-
-/* Handshake MDMA 0 Registers */
-
-#define                   HMDMA0_CONTROL  0xffc04500   /* Handshake MDMA0 Control Register */
-#define                    HMDMA0_ECINIT  0xffc04504   /* Handshake MDMA0 Initial Edge Count Register */
-#define                    HMDMA0_BCINIT  0xffc04508   /* Handshake MDMA0 Initial Block Count Register */
-#define                  HMDMA0_ECURGENT  0xffc0450c   /* Handshake MDMA0 Urgent Edge Count Threshhold Register */
-#define                HMDMA0_ECOVERFLOW  0xffc04510   /* Handshake MDMA0 Edge Count Overflow Interrupt Register */
-#define                    HMDMA0_ECOUNT  0xffc04514   /* Handshake MDMA0 Current Edge Count Register */
-#define                    HMDMA0_BCOUNT  0xffc04518   /* Handshake MDMA0 Current Block Count Register */
-
-/* Handshake MDMA 1 Registers */
-
-#define                   HMDMA1_CONTROL  0xffc04540   /* Handshake MDMA1 Control Register */
-#define                    HMDMA1_ECINIT  0xffc04544   /* Handshake MDMA1 Initial Edge Count Register */
-#define                    HMDMA1_BCINIT  0xffc04548   /* Handshake MDMA1 Initial Block Count Register */
-#define                  HMDMA1_ECURGENT  0xffc0454c   /* Handshake MDMA1 Urgent Edge Count Threshhold Register */
-#define                HMDMA1_ECOVERFLOW  0xffc04550   /* Handshake MDMA1 Edge Count Overflow Interrupt Register */
-#define                    HMDMA1_ECOUNT  0xffc04554   /* Handshake MDMA1 Current Edge Count Register */
-#define                    HMDMA1_BCOUNT  0xffc04558   /* Handshake MDMA1 Current Block Count Register */
-
-
-/* ********************************************************** */
-/*     SINGLE BIT MACRO PAIRS (bit mask and negated one)      */
-/*     and MULTI BIT READ MACROS                              */
-/* ********************************************************** */
-
-/* Bit masks for PIXC_CTL */
-
-#define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                  IMG_FORM  0x8        /* Image Data Format */
-#define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                  OUT_FORM  0x20       /* Output Data Format */
-#define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                  IMG_STAT  0x300      /* Image FIFO Status */
-#define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
-#define                    WM_LVL  0x3000     /* FIFO Watermark Level */
-
-/* Bit masks for PIXC_AHSTART */
-
-#define                  A_HSTART  0xfff      /* Horizontal Start Coordinates */
-
-/* Bit masks for PIXC_AHEND */
-
-#define                    A_HEND  0xfff      /* Horizontal End Coordinates */
-
-/* Bit masks for PIXC_AVSTART */
-
-#define                  A_VSTART  0x3ff      /* Vertical Start Coordinates */
-
-/* Bit masks for PIXC_AVEND */
-
-#define                    A_VEND  0x3ff      /* Vertical End Coordinates */
-
-/* Bit masks for PIXC_ATRANSP */
-
-#define                  A_TRANSP  0xf        /* Transparency Value */
-
-/* Bit masks for PIXC_BHSTART */
-
-#define                  B_HSTART  0xfff      /* Horizontal Start Coordinates */
-
-/* Bit masks for PIXC_BHEND */
-
-#define                    B_HEND  0xfff      /* Horizontal End Coordinates */
-
-/* Bit masks for PIXC_BVSTART */
-
-#define                  B_VSTART  0x3ff      /* Vertical Start Coordinates */
-
-/* Bit masks for PIXC_BVEND */
-
-#define                    B_VEND  0x3ff      /* Vertical End Coordinates */
-
-/* Bit masks for PIXC_BTRANSP */
-
-#define                  B_TRANSP  0xf        /* Transparency Value */
-
-/* Bit masks for PIXC_INTRSTAT */
-
-#define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-
-/* Bit masks for PIXC_RYCON */
-
-#define                       A11  0x3ff      /* A11 in the Coefficient Matrix */
-#define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
-#define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
-#define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_GUCON */
-
-#define                       A21  0x3ff      /* A21 in the Coefficient Matrix */
-#define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
-#define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
-#define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_BVCON */
-
-#define                       A31  0x3ff      /* A31 in the Coefficient Matrix */
-#define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
-#define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
-#define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-
-/* Bit masks for PIXC_CCBIAS */
-
-#define                       A14  0x3ff      /* A14 in the Bias Vector */
-#define                       A24  0xffc00    /* A24 in the Bias Vector */
-#define                       A34  0x3ff00000 /* A34 in the Bias Vector */
-
-/* Bit masks for PIXC_TC */
-
-#define                  RY_TRANS  0xff       /* Transparent Color - R/Y Component */
-#define                  GU_TRANS  0xff00     /* Transparent Color - G/U Component */
-#define                  BV_TRANS  0xff0000   /* Transparent Color - B/V Component */
-
-/* Bit masks for HOST_CONTROL */
-
-#define                   HOST_EN  0x1        /* Host Enable */
-#define                  HOST_END  0x2        /* Host Endianess */
-#define                 DATA_SIZE  0x4        /* Data Size */
-#define                  HOST_RST  0x8        /* Host Reset */
-#define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                       EHW  0x100      /* Enable Host Write */
-#define                       EHR  0x200      /* Enable Host Read */
-#define                       BDR  0x400      /* Burst DMA Requests */
-
-/* Bit masks for HOST_STATUS */
-
-#define                 DMA_READY  0x1        /* DMA Ready */
-#define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define              DMA_COMPLETE  0x8        /* DMA Complete */
-#define                      HSHK  0x10       /* Host Handshake */
-#define                   TIMEOUT  0x20       /* Host Timeout */
-#define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define                   DMA_DIR  0x100      /* DMA Direction */
-#define                       BTE  0x200      /* Bus Timeout Enabled */
-
-/* Bit masks for HOST_TIMEOUT */
-
-#define             COUNT_TIMEOUT  0x7ff      /* Host Timeout count */
-
-/* Bit masks for MXVR_CONFIG */
-
-#define                    MXVREN  0x1        /* MXVR Enable */
-#define                      MMSM  0x2        /* MXVR Master/Slave Mode Select */
-#define                    ACTIVE  0x4        /* Active Mode */
-#define                    SDELAY  0x8        /* Synchronous Data Delay */
-#define                   NCMRXEN  0x10       /* Normal Control Message Receive Enable */
-#define                   RWRRXEN  0x20       /* Remote Write Receive Enable */
-#define                     MTXEN  0x40       /* MXVR Transmit Data Enable */
-#define                    MTXONB  0x80       /* MXVR Phy Transmitter On */
-#define                   EPARITY  0x100      /* Even Parity Select */
-#define                       MSB  0x1e00     /* Master Synchronous Boundary */
-#define                    APRXEN  0x2000     /* Asynchronous Packet Receive Enable */
-#define                    WAKEUP  0x4000     /* Wake-Up */
-#define                     LMECH  0x8000     /* Lock Mechanism Select */
-
-/* Bit masks for MXVR_STATE_0 */
-
-#define                      NACT  0x1        /* Network Activity */
-#define                    SBLOCK  0x2        /* Super Block Lock */
-#define                   FMPLLST  0xc        /* Frequency Multiply PLL SM State */
-#define                  CDRPLLST  0xe0       /* Clock/Data Recovery PLL SM State */
-#define                     APBSY  0x100      /* Asynchronous Packet Transmit Buffer Busy */
-#define                     APARB  0x200      /* Asynchronous Packet Arbitrating */
-#define                      APTX  0x400      /* Asynchronous Packet Transmitting */
-#define                      APRX  0x800      /* Receiving Asynchronous Packet */
-#define                     CMBSY  0x1000     /* Control Message Transmit Buffer Busy */
-#define                     CMARB  0x2000     /* Control Message Arbitrating */
-#define                      CMTX  0x4000     /* Control Message Transmitting */
-#define                      CMRX  0x8000     /* Receiving Control Message */
-#define                    MRXONB  0x10000    /* MRXONB Pin State */
-#define                     RGSIP  0x20000    /* Remote Get Source In Progress */
-#define                     DALIP  0x40000    /* Resource Deallocate In Progress */
-#define                      ALIP  0x80000    /* Resource Allocate In Progress */
-#define                     RRDIP  0x100000   /* Remote Read In Progress */
-#define                     RWRIP  0x200000   /* Remote Write In Progress */
-#define                     FLOCK  0x400000   /* Frame Lock */
-#define                     BLOCK  0x800000   /* Block Lock */
-#define                       RSB  0xf000000  /* Received Synchronous Boundary */
-#define                   DERRNUM  0xf0000000 /* DMA Error Channel Number */
-
-/* Bit masks for MXVR_STATE_1 */
-
-#define                   SRXNUMB  0xf        /* Synchronous Receive FIFO Number of Bytes */
-#define                   STXNUMB  0xf0       /* Synchronous Transmit FIFO Number of Bytes */
-#define                    APCONT  0x100      /* Asynchronous Packet Continuation */
-#define                  OBERRNUM  0xe00      /* DMA Out of Bounds Error Channel Number */
-#define                DMAACTIVE0  0x10000    /* DMA0 Active */
-#define                DMAACTIVE1  0x20000    /* DMA1 Active */
-#define                DMAACTIVE2  0x40000    /* DMA2 Active */
-#define                DMAACTIVE3  0x80000    /* DMA3 Active */
-#define                DMAACTIVE4  0x100000   /* DMA4 Active */
-#define                DMAACTIVE5  0x200000   /* DMA5 Active */
-#define                DMAACTIVE6  0x400000   /* DMA6 Active */
-#define                DMAACTIVE7  0x800000   /* DMA7 Active */
-#define                  DMAPMEN0  0x1000000  /* DMA0 Pattern Matching Enabled */
-#define                  DMAPMEN1  0x2000000  /* DMA1 Pattern Matching Enabled */
-#define                  DMAPMEN2  0x4000000  /* DMA2 Pattern Matching Enabled */
-#define                  DMAPMEN3  0x8000000  /* DMA3 Pattern Matching Enabled */
-#define                  DMAPMEN4  0x10000000 /* DMA4 Pattern Matching Enabled */
-#define                  DMAPMEN5  0x20000000 /* DMA5 Pattern Matching Enabled */
-#define                  DMAPMEN6  0x40000000 /* DMA6 Pattern Matching Enabled */
-#define                  DMAPMEN7  0x80000000 /* DMA7 Pattern Matching Enabled */
-
-/* Bit masks for MXVR_INT_STAT_0 */
-
-#define                      NI2A  0x1        /* Network Inactive to Active */
-#define                      NA2I  0x2        /* Network Active to Inactive */
-#define                     SBU2L  0x4        /* Super Block Unlock to Lock */
-#define                     SBL2U  0x8        /* Super Block Lock to Unlock */
-#define                       PRU  0x10       /* Position Register Updated */
-#define                      MPRU  0x20       /* Maximum Position Register Updated */
-#define                       DRU  0x40       /* Delay Register Updated */
-#define                      MDRU  0x80       /* Maximum Delay Register Updated */
-#define                       SBU  0x100      /* Synchronous Boundary Updated */
-#define                       ATU  0x200      /* Allocation Table Updated */
-#define                      FCZ0  0x400      /* Frame Counter 0 Zero */
-#define                      FCZ1  0x800      /* Frame Counter 1 Zero */
-#define                      PERR  0x1000     /* Parity Error */
-#define                      MH2L  0x2000     /* MRXONB High to Low */
-#define                      ML2H  0x4000     /* MRXONB Low to High */
-#define                       WUP  0x8000     /* Wake-Up Preamble Received */
-#define                      FU2L  0x10000    /* Frame Unlock to Lock */
-#define                      FL2U  0x20000    /* Frame Lock to Unlock */
-#define                      BU2L  0x40000    /* Block Unlock to Lock */
-#define                      BL2U  0x80000    /* Block Lock to Unlock */
-#define                     OBERR  0x100000   /* DMA Out of Bounds Error */
-#define                       PFL  0x200000   /* PLL Frequency Locked */
-#define                       SCZ  0x400000   /* System Clock Counter Zero */
-#define                      FERR  0x800000   /* FIFO Error */
-#define                       CMR  0x1000000  /* Control Message Received */
-#define                     CMROF  0x2000000  /* Control Message Receive Buffer Overflow */
-#define                      CMTS  0x4000000  /* Control Message Transmit Buffer Successfully Sent */
-#define                      CMTC  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled */
-#define                      RWRC  0x10000000 /* Remote Write Control Message Completed */
-#define                       BCZ  0x20000000 /* Block Counter Zero */
-#define                     BMERR  0x40000000 /* Biphase Mark Coding Error */
-#define                      DERR  0x80000000 /* DMA Error */
-
-/* Bit masks for MXVR_INT_STAT_1 */
-
-#define                    HDONE0  0x1        /* DMA0 Half Done */
-#define                     DONE0  0x2        /* DMA0 Done */
-#define                       APR  0x4        /* Asynchronous Packet Received */
-#define                     APROF  0x8        /* Asynchronous Packet Receive Buffer Overflow */
-#define                    HDONE1  0x10       /* DMA1 Half Done */
-#define                     DONE1  0x20       /* DMA1 Done */
-#define                      APTS  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent */
-#define                      APTC  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled */
-#define                    HDONE2  0x100      /* DMA2 Half Done */
-#define                     DONE2  0x200      /* DMA2 Done */
-#define                     APRCE  0x400      /* Asynchronous Packet Receive CRC Error */
-#define                     APRPE  0x800      /* Asynchronous Packet Receive Packet Error */
-#define                    HDONE3  0x1000     /* DMA3 Half Done */
-#define                     DONE3  0x2000     /* DMA3 Done */
-#define                    HDONE4  0x10000    /* DMA4 Half Done */
-#define                     DONE4  0x20000    /* DMA4 Done */
-#define                    HDONE5  0x100000   /* DMA5 Half Done */
-#define                     DONE5  0x200000   /* DMA5 Done */
-#define                    HDONE6  0x1000000  /* DMA6 Half Done */
-#define                     DONE6  0x2000000  /* DMA6 Done */
-#define                    HDONE7  0x10000000 /* DMA7 Half Done */
-#define                     DONE7  0x20000000 /* DMA7 Done */
-
-/* Bit masks for MXVR_INT_EN_0 */
-
-#define                    NI2AEN  0x1        /* Network Inactive to Active Interrupt Enable */
-#define                    NA2IEN  0x2        /* Network Active to Inactive Interrupt Enable */
-#define                   SBU2LEN  0x4        /* Super Block Unlock to Lock Interrupt Enable */
-#define                   SBL2UEN  0x8        /* Super Block Lock to Unlock Interrupt Enable */
-#define                     PRUEN  0x10       /* Position Register Updated Interrupt Enable */
-#define                    MPRUEN  0x20       /* Maximum Position Register Updated Interrupt Enable */
-#define                     DRUEN  0x40       /* Delay Register Updated Interrupt Enable */
-#define                    MDRUEN  0x80       /* Maximum Delay Register Updated Interrupt Enable */
-#define                     SBUEN  0x100      /* Synchronous Boundary Updated Interrupt Enable */
-#define                     ATUEN  0x200      /* Allocation Table Updated Interrupt Enable */
-#define                    FCZ0EN  0x400      /* Frame Counter 0 Zero Interrupt Enable */
-#define                    FCZ1EN  0x800      /* Frame Counter 1 Zero Interrupt Enable */
-#define                    PERREN  0x1000     /* Parity Error Interrupt Enable */
-#define                    MH2LEN  0x2000     /* MRXONB High to Low Interrupt Enable */
-#define                    ML2HEN  0x4000     /* MRXONB Low to High Interrupt Enable */
-#define                     WUPEN  0x8000     /* Wake-Up Preamble Received Interrupt Enable */
-#define                    FU2LEN  0x10000    /* Frame Unlock to Lock Interrupt Enable */
-#define                    FL2UEN  0x20000    /* Frame Lock to Unlock Interrupt Enable */
-#define                    BU2LEN  0x40000    /* Block Unlock to Lock Interrupt Enable */
-#define                    BL2UEN  0x80000    /* Block Lock to Unlock Interrupt Enable */
-#define                   OBERREN  0x100000   /* DMA Out of Bounds Error Interrupt Enable */
-#define                     PFLEN  0x200000   /* PLL Frequency Locked Interrupt Enable */
-#define                     SCZEN  0x400000   /* System Clock Counter Zero Interrupt Enable */
-#define                    FERREN  0x800000   /* FIFO Error Interrupt Enable */
-#define                     CMREN  0x1000000  /* Control Message Received Interrupt Enable */
-#define                   CMROFEN  0x2000000  /* Control Message Receive Buffer Overflow Interrupt Enable */
-#define                    CMTSEN  0x4000000  /* Control Message Transmit Buffer Successfully Sent Interrupt Enable */
-#define                    CMTCEN  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                    RWRCEN  0x10000000 /* Remote Write Control Message Completed Interrupt Enable */
-#define                     BCZEN  0x20000000 /* Block Counter Zero Interrupt Enable */
-#define                   BMERREN  0x40000000 /* Biphase Mark Coding Error Interrupt Enable */
-#define                    DERREN  0x80000000 /* DMA Error Interrupt Enable */
-
-/* Bit masks for MXVR_INT_EN_1 */
-
-#define                  HDONEEN0  0x1        /* DMA0 Half Done Interrupt Enable */
-#define                   DONEEN0  0x2        /* DMA0 Done Interrupt Enable */
-#define                     APREN  0x4        /* Asynchronous Packet Received Interrupt Enable */
-#define                   APROFEN  0x8        /* Asynchronous Packet Receive Buffer Overflow Interrupt Enable */
-#define                  HDONEEN1  0x10       /* DMA1 Half Done Interrupt Enable */
-#define                   DONEEN1  0x20       /* DMA1 Done Interrupt Enable */
-#define                    APTSEN  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent Interrupt Enable */
-#define                    APTCEN  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                  HDONEEN2  0x100      /* DMA2 Half Done Interrupt Enable */
-#define                   DONEEN2  0x200      /* DMA2 Done Interrupt Enable */
-#define                   APRCEEN  0x400      /* Asynchronous Packet Receive CRC Error Interrupt Enable */
-#define                   APRPEEN  0x800      /* Asynchronous Packet Receive Packet Error Interrupt Enable */
-#define                  HDONEEN3  0x1000     /* DMA3 Half Done Interrupt Enable */
-#define                   DONEEN3  0x2000     /* DMA3 Done Interrupt Enable */
-#define                  HDONEEN4  0x10000    /* DMA4 Half Done Interrupt Enable */
-#define                   DONEEN4  0x20000    /* DMA4 Done Interrupt Enable */
-#define                  HDONEEN5  0x100000   /* DMA5 Half Done Interrupt Enable */
-#define                   DONEEN5  0x200000   /* DMA5 Done Interrupt Enable */
-#define                  HDONEEN6  0x1000000  /* DMA6 Half Done Interrupt Enable */
-#define                   DONEEN6  0x2000000  /* DMA6 Done Interrupt Enable */
-#define                  HDONEEN7  0x10000000 /* DMA7 Half Done Interrupt Enable */
-#define                   DONEEN7  0x20000000 /* DMA7 Done Interrupt Enable */
-
-/* Bit masks for MXVR_POSITION */
-
-#define                  POSITION  0x3f       /* Node Position */
-#define                    PVALID  0x8000     /* Node Position Valid */
-
-/* Bit masks for MXVR_MAX_POSITION */
-
-#define                 MPOSITION  0x3f       /* Maximum Node Position */
-#define                   MPVALID  0x8000     /* Maximum Node Position Valid */
-
-/* Bit masks for MXVR_DELAY */
-
-#define                     DELAY  0x3f       /* Node Frame Delay */
-#define                    DVALID  0x8000     /* Node Frame Delay Valid */
-
-/* Bit masks for MXVR_MAX_DELAY */
-
-#define                    MDELAY  0x3f       /* Maximum Node Frame Delay */
-#define                   MDVALID  0x8000     /* Maximum Node Frame Delay Valid */
-
-/* Bit masks for MXVR_LADDR */
-
-#define                     LADDR  0xffff     /* Logical Address */
-#define                    LVALID  0x80000000 /* Logical Address Valid */
-
-/* Bit masks for MXVR_GADDR */
-
-#define                    GADDRL  0xff       /* Group Address Lower Byte */
-#define                    GVALID  0x8000     /* Group Address Valid */
-
-/* Bit masks for MXVR_AADDR */
-
-#define                     AADDR  0xffff     /* Alternate Address */
-#define                    AVALID  0x80000000 /* Alternate Address Valid */
-
-/* Bit masks for MXVR_ALLOC_0 */
-
-#define                       CL0  0x7f       /* Channel 0 Connection Label */
-#define                      CIU0  0x80       /* Channel 0 In Use */
-#define                       CL1  0x7f00     /* Channel 0 Connection Label */
-#define                      CIU1  0x8000     /* Channel 0 In Use */
-#define                       CL2  0x7f0000   /* Channel 0 Connection Label */
-#define                      CIU2  0x800000   /* Channel 0 In Use */
-#define                       CL3  0x7f000000 /* Channel 0 Connection Label */
-#define                      CIU3  0x80000000 /* Channel 0 In Use */
-
-/* Bit masks for MXVR_ALLOC_1 */
-
-#define                       CL4  0x7f       /* Channel 4 Connection Label */
-#define                      CIU4  0x80       /* Channel 4 In Use */
-#define                       CL5  0x7f00     /* Channel 5 Connection Label */
-#define                      CIU5  0x8000     /* Channel 5 In Use */
-#define                       CL6  0x7f0000   /* Channel 6 Connection Label */
-#define                      CIU6  0x800000   /* Channel 6 In Use */
-#define                       CL7  0x7f000000 /* Channel 7 Connection Label */
-#define                      CIU7  0x80000000 /* Channel 7 In Use */
-
-/* Bit masks for MXVR_ALLOC_2 */
-
-#define                       CL8  0x7f       /* Channel 8 Connection Label */
-#define                      CIU8  0x80       /* Channel 8 In Use */
-#define                       CL9  0x7f00     /* Channel 9 Connection Label */
-#define                      CIU9  0x8000     /* Channel 9 In Use */
-#define                      CL10  0x7f0000   /* Channel 10 Connection Label */
-#define                     CIU10  0x800000   /* Channel 10 In Use */
-#define                      CL11  0x7f000000 /* Channel 11 Connection Label */
-#define                     CIU11  0x80000000 /* Channel 11 In Use */
-
-/* Bit masks for MXVR_ALLOC_3 */
-
-#define                      CL12  0x7f       /* Channel 12 Connection Label */
-#define                     CIU12  0x80       /* Channel 12 In Use */
-#define                      CL13  0x7f00     /* Channel 13 Connection Label */
-#define                     CIU13  0x8000     /* Channel 13 In Use */
-#define                      CL14  0x7f0000   /* Channel 14 Connection Label */
-#define                     CIU14  0x800000   /* Channel 14 In Use */
-#define                      CL15  0x7f000000 /* Channel 15 Connection Label */
-#define                     CIU15  0x80000000 /* Channel 15 In Use */
-
-/* Bit masks for MXVR_ALLOC_4 */
-
-#define                      CL16  0x7f       /* Channel 16 Connection Label */
-#define                     CIU16  0x80       /* Channel 16 In Use */
-#define                      CL17  0x7f00     /* Channel 17 Connection Label */
-#define                     CIU17  0x8000     /* Channel 17 In Use */
-#define                      CL18  0x7f0000   /* Channel 18 Connection Label */
-#define                     CIU18  0x800000   /* Channel 18 In Use */
-#define                      CL19  0x7f000000 /* Channel 19 Connection Label */
-#define                     CIU19  0x80000000 /* Channel 19 In Use */
-
-/* Bit masks for MXVR_ALLOC_5 */
-
-#define                      CL20  0x7f       /* Channel 20 Connection Label */
-#define                     CIU20  0x80       /* Channel 20 In Use */
-#define                      CL21  0x7f00     /* Channel 21 Connection Label */
-#define                     CIU21  0x8000     /* Channel 21 In Use */
-#define                      CL22  0x7f0000   /* Channel 22 Connection Label */
-#define                     CIU22  0x800000   /* Channel 22 In Use */
-#define                      CL23  0x7f000000 /* Channel 23 Connection Label */
-#define                     CIU23  0x80000000 /* Channel 23 In Use */
-
-/* Bit masks for MXVR_ALLOC_6 */
-
-#define                      CL24  0x7f       /* Channel 24 Connection Label */
-#define                     CIU24  0x80       /* Channel 24 In Use */
-#define                      CL25  0x7f00     /* Channel 25 Connection Label */
-#define                     CIU25  0x8000     /* Channel 25 In Use */
-#define                      CL26  0x7f0000   /* Channel 26 Connection Label */
-#define                     CIU26  0x800000   /* Channel 26 In Use */
-#define                      CL27  0x7f000000 /* Channel 27 Connection Label */
-#define                     CIU27  0x80000000 /* Channel 27 In Use */
-
-/* Bit masks for MXVR_ALLOC_7 */
-
-#define                      CL28  0x7f       /* Channel 28 Connection Label */
-#define                     CIU28  0x80       /* Channel 28 In Use */
-#define                      CL29  0x7f00     /* Channel 29 Connection Label */
-#define                     CIU29  0x8000     /* Channel 29 In Use */
-#define                      CL30  0x7f0000   /* Channel 30 Connection Label */
-#define                     CIU30  0x800000   /* Channel 30 In Use */
-#define                      CL31  0x7f000000 /* Channel 31 Connection Label */
-#define                     CIU31  0x80000000 /* Channel 31 In Use */
-
-/* Bit masks for MXVR_ALLOC_8 */
-
-#define                      CL32  0x7f       /* Channel 32 Connection Label */
-#define                     CIU32  0x80       /* Channel 32 In Use */
-#define                      CL33  0x7f00     /* Channel 33 Connection Label */
-#define                     CIU33  0x8000     /* Channel 33 In Use */
-#define                      CL34  0x7f0000   /* Channel 34 Connection Label */
-#define                     CIU34  0x800000   /* Channel 34 In Use */
-#define                      CL35  0x7f000000 /* Channel 35 Connection Label */
-#define                     CIU35  0x80000000 /* Channel 35 In Use */
-
-/* Bit masks for MXVR_ALLOC_9 */
-
-#define                      CL36  0x7f       /* Channel 36 Connection Label */
-#define                     CIU36  0x80       /* Channel 36 In Use */
-#define                      CL37  0x7f00     /* Channel 37 Connection Label */
-#define                     CIU37  0x8000     /* Channel 37 In Use */
-#define                      CL38  0x7f0000   /* Channel 38 Connection Label */
-#define                     CIU38  0x800000   /* Channel 38 In Use */
-#define                      CL39  0x7f000000 /* Channel 39 Connection Label */
-#define                     CIU39  0x80000000 /* Channel 39 In Use */
-
-/* Bit masks for MXVR_ALLOC_10 */
-
-#define                      CL40  0x7f       /* Channel 40 Connection Label */
-#define                     CIU40  0x80       /* Channel 40 In Use */
-#define                      CL41  0x7f00     /* Channel 41 Connection Label */
-#define                     CIU41  0x8000     /* Channel 41 In Use */
-#define                      CL42  0x7f0000   /* Channel 42 Connection Label */
-#define                     CIU42  0x800000   /* Channel 42 In Use */
-#define                      CL43  0x7f000000 /* Channel 43 Connection Label */
-#define                     CIU43  0x80000000 /* Channel 43 In Use */
-
-/* Bit masks for MXVR_ALLOC_11 */
-
-#define                      CL44  0x7f       /* Channel 44 Connection Label */
-#define                     CIU44  0x80       /* Channel 44 In Use */
-#define                      CL45  0x7f00     /* Channel 45 Connection Label */
-#define                     CIU45  0x8000     /* Channel 45 In Use */
-#define                      CL46  0x7f0000   /* Channel 46 Connection Label */
-#define                     CIU46  0x800000   /* Channel 46 In Use */
-#define                      CL47  0x7f000000 /* Channel 47 Connection Label */
-#define                     CIU47  0x80000000 /* Channel 47 In Use */
-
-/* Bit masks for MXVR_ALLOC_12 */
-
-#define                      CL48  0x7f       /* Channel 48 Connection Label */
-#define                     CIU48  0x80       /* Channel 48 In Use */
-#define                      CL49  0x7f00     /* Channel 49 Connection Label */
-#define                     CIU49  0x8000     /* Channel 49 In Use */
-#define                      CL50  0x7f0000   /* Channel 50 Connection Label */
-#define                     CIU50  0x800000   /* Channel 50 In Use */
-#define                      CL51  0x7f000000 /* Channel 51 Connection Label */
-#define                     CIU51  0x80000000 /* Channel 51 In Use */
-
-/* Bit masks for MXVR_ALLOC_13 */
-
-#define                      CL52  0x7f       /* Channel 52 Connection Label */
-#define                     CIU52  0x80       /* Channel 52 In Use */
-#define                      CL53  0x7f00     /* Channel 53 Connection Label */
-#define                     CIU53  0x8000     /* Channel 53 In Use */
-#define                      CL54  0x7f0000   /* Channel 54 Connection Label */
-#define                     CIU54  0x800000   /* Channel 54 In Use */
-#define                      CL55  0x7f000000 /* Channel 55 Connection Label */
-#define                     CIU55  0x80000000 /* Channel 55 In Use */
-
-/* Bit masks for MXVR_ALLOC_14 */
-
-#define                      CL56  0x7f       /* Channel 56 Connection Label */
-#define                     CIU56  0x80       /* Channel 56 In Use */
-#define                      CL57  0x7f00     /* Channel 57 Connection Label */
-#define                     CIU57  0x8000     /* Channel 57 In Use */
-#define                      CL58  0x7f0000   /* Channel 58 Connection Label */
-#define                     CIU58  0x800000   /* Channel 58 In Use */
-#define                      CL59  0x7f000000 /* Channel 59 Connection Label */
-#define                     CIU59  0x80000000 /* Channel 59 In Use */
-
-/* MXVR_SYNC_LCHAN_0 Masks */
-
-#define LCHANPC0     0x0000000Flu
-#define LCHANPC1     0x000000F0lu
-#define LCHANPC2     0x00000F00lu
-#define LCHANPC3     0x0000F000lu
-#define LCHANPC4     0x000F0000lu
-#define LCHANPC5     0x00F00000lu
-#define LCHANPC6     0x0F000000lu
-#define LCHANPC7     0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_1 Masks */
-
-#define LCHANPC8     0x0000000Flu
-#define LCHANPC9     0x000000F0lu
-#define LCHANPC10    0x00000F00lu
-#define LCHANPC11    0x0000F000lu
-#define LCHANPC12    0x000F0000lu
-#define LCHANPC13    0x00F00000lu
-#define LCHANPC14    0x0F000000lu
-#define LCHANPC15    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_2 Masks */
-
-#define LCHANPC16    0x0000000Flu
-#define LCHANPC17    0x000000F0lu
-#define LCHANPC18    0x00000F00lu
-#define LCHANPC19    0x0000F000lu
-#define LCHANPC20    0x000F0000lu
-#define LCHANPC21    0x00F00000lu
-#define LCHANPC22    0x0F000000lu
-#define LCHANPC23    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_3 Masks */
-
-#define LCHANPC24    0x0000000Flu
-#define LCHANPC25    0x000000F0lu
-#define LCHANPC26    0x00000F00lu
-#define LCHANPC27    0x0000F000lu
-#define LCHANPC28    0x000F0000lu
-#define LCHANPC29    0x00F00000lu
-#define LCHANPC30    0x0F000000lu
-#define LCHANPC31    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_4 Masks */
-
-#define LCHANPC32    0x0000000Flu
-#define LCHANPC33    0x000000F0lu
-#define LCHANPC34    0x00000F00lu
-#define LCHANPC35    0x0000F000lu
-#define LCHANPC36    0x000F0000lu
-#define LCHANPC37    0x00F00000lu
-#define LCHANPC38    0x0F000000lu
-#define LCHANPC39    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_5 Masks */
-
-#define LCHANPC40    0x0000000Flu
-#define LCHANPC41    0x000000F0lu
-#define LCHANPC42    0x00000F00lu
-#define LCHANPC43    0x0000F000lu
-#define LCHANPC44    0x000F0000lu
-#define LCHANPC45    0x00F00000lu
-#define LCHANPC46    0x0F000000lu
-#define LCHANPC47    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_6 Masks */
-
-#define LCHANPC48    0x0000000Flu
-#define LCHANPC49    0x000000F0lu
-#define LCHANPC50    0x00000F00lu
-#define LCHANPC51    0x0000F000lu
-#define LCHANPC52    0x000F0000lu
-#define LCHANPC53    0x00F00000lu
-#define LCHANPC54    0x0F000000lu
-#define LCHANPC55    0xF0000000lu
-
-
-/* MXVR_SYNC_LCHAN_7 Masks */
-
-#define LCHANPC56    0x0000000Flu
-#define LCHANPC57    0x000000F0lu
-#define LCHANPC58    0x00000F00lu
-#define LCHANPC59    0x0000F000lu
-
-/* Bit masks for MXVR_DMAx_CONFIG */
-
-#define                    MDMAEN  0x1        /* DMA Channel Enable */
-#define                     DMADD  0x2        /* DMA Channel Direction */
-#define                 BY4SWAPEN  0x20       /* DMA Channel Four Byte Swap Enable */
-#define                     LCHAN  0x3c0      /* DMA Channel Logical Channel */
-#define                 BITSWAPEN  0x400      /* DMA Channel Bit Swap Enable */
-#define                 BY2SWAPEN  0x800      /* DMA Channel Two Byte Swap Enable */
-#define                     MFLOW  0x7000     /* DMA Channel Operation Flow */
-#define                   FIXEDPM  0x80000    /* DMA Channel Fixed Pattern Matching Select */
-#define                  STARTPAT  0x300000   /* DMA Channel Start Pattern Select */
-#define                   STOPPAT  0xc00000   /* DMA Channel Stop Pattern Select */
-#define                  COUNTPOS  0x1c000000 /* DMA Channel Count Position */
-
-/* Bit masks for MXVR_AP_CTL */
-
-#define                   STARTAP  0x1        /* Start Asynchronous Packet Transmission */
-#define                  CANCELAP  0x2        /* Cancel Asynchronous Packet Transmission */
-#define                   RESETAP  0x4        /* Reset Asynchronous Packet Arbitration */
-#define                    APRBE0  0x4000     /* Asynchronous Packet Receive Buffer Entry 0 */
-#define                    APRBE1  0x8000     /* Asynchronous Packet Receive Buffer Entry 1 */
-
-/* Bit masks for MXVR_APRB_START_ADDR */
-
-#define      MXVR_APRB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Receive Buffer Start Address */
-
-/* Bit masks for MXVR_APRB_CURR_ADDR */
-
-#define       MXVR_APRB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Receive Buffer Current Address */
-
-/* Bit masks for MXVR_APTB_START_ADDR */
-
-#define       MXVR_APTB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Transmit Buffer Start Address */
-
-/* Bit masks for MXVR_APTB_CURR_ADDR */
-
-#define        MXVR_APTB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */
-
-/* Bit masks for MXVR_CM_CTL */
-
-#define                   STARTCM  0x1        /* Start Control Message Transmission */
-#define                  CANCELCM  0x2        /* Cancel Control Message Transmission */
-#define                    CMRBE0  0x10000    /* Control Message Receive Buffer Entry 0 */
-#define                    CMRBE1  0x20000    /* Control Message Receive Buffer Entry 1 */
-#define                    CMRBE2  0x40000    /* Control Message Receive Buffer Entry 2 */
-#define                    CMRBE3  0x80000    /* Control Message Receive Buffer Entry 3 */
-#define                    CMRBE4  0x100000   /* Control Message Receive Buffer Entry 4 */
-#define                    CMRBE5  0x200000   /* Control Message Receive Buffer Entry 5 */
-#define                    CMRBE6  0x400000   /* Control Message Receive Buffer Entry 6 */
-#define                    CMRBE7  0x800000   /* Control Message Receive Buffer Entry 7 */
-#define                    CMRBE8  0x1000000  /* Control Message Receive Buffer Entry 8 */
-#define                    CMRBE9  0x2000000  /* Control Message Receive Buffer Entry 9 */
-#define                   CMRBE10  0x4000000  /* Control Message Receive Buffer Entry 10 */
-#define                   CMRBE11  0x8000000  /* Control Message Receive Buffer Entry 11 */
-#define                   CMRBE12  0x10000000 /* Control Message Receive Buffer Entry 12 */
-#define                   CMRBE13  0x20000000 /* Control Message Receive Buffer Entry 13 */
-#define                   CMRBE14  0x40000000 /* Control Message Receive Buffer Entry 14 */
-#define                   CMRBE15  0x80000000 /* Control Message Receive Buffer Entry 15 */
-
-/* Bit masks for MXVR_CMRB_START_ADDR */
-
-#define      MXVR_CMRB_START_ADDR_MASK  0x1fffffe  /* Control Message Receive Buffer Start Address */
-
-/* Bit masks for MXVR_CMRB_CURR_ADDR */
-
-#define       MXVR_CMRB_CURR_ADDR_MASK  0xffffffff /* Control Message Receive Buffer Current Address */
-
-/* Bit masks for MXVR_CMTB_START_ADDR */
-
-#define      MXVR_CMTB_START_ADDR_MASK  0x1fffffe  /* Control Message Transmit Buffer Start Address */
-
-/* Bit masks for MXVR_CMTB_CURR_ADDR */
-
-#define       MXVR_CMTB_CURR_ADDR_MASK  0xffffffff /* Control Message Transmit Buffer Current Address */
-
-/* Bit masks for MXVR_RRDB_START_ADDR */
-
-#define      MXVR_RRDB_START_ADDR_MASK  0x1fffffe  /* Remote Read Buffer Start Address */
-
-/* Bit masks for MXVR_RRDB_CURR_ADDR */
-
-#define       MXVR_RRDB_CURR_ADDR_MASK  0xffffffff /* Remote Read Buffer Current Address */
-
-/* Bit masks for MXVR_PAT_DATAx */
-
-#define              MATCH_DATA_0  0xff       /* Pattern Match Data Byte 0 */
-#define              MATCH_DATA_1  0xff00     /* Pattern Match Data Byte 1 */
-#define              MATCH_DATA_2  0xff0000   /* Pattern Match Data Byte 2 */
-#define              MATCH_DATA_3  0xff000000 /* Pattern Match Data Byte 3 */
-
-/* Bit masks for MXVR_PAT_EN_0 */
-
-#define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-
-/* Bit masks for MXVR_PAT_EN_1 */
-
-#define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-
-/* Bit masks for MXVR_FRAME_CNT_0 */
-
-#define                      FCNT  0xffff     /* Frame Count */
-
-/* Bit masks for MXVR_FRAME_CNT_1 */
-
-#define                      FCNT  0xffff     /* Frame Count */
-
-/* Bit masks for MXVR_ROUTING_0 */
-
-#define                    TX_CH0  0x3f       /* Transmit Channel 0 */
-#define                  MUTE_CH0  0x80       /* Mute Channel 0 */
-#define                    TX_CH1  0x3f00     /* Transmit Channel 0 */
-#define                  MUTE_CH1  0x8000     /* Mute Channel 0 */
-#define                    TX_CH2  0x3f0000   /* Transmit Channel 0 */
-#define                  MUTE_CH2  0x800000   /* Mute Channel 0 */
-#define                    TX_CH3  0x3f000000 /* Transmit Channel 0 */
-#define                  MUTE_CH3  0x80000000 /* Mute Channel 0 */
-
-/* Bit masks for MXVR_ROUTING_1 */
-
-#define                    TX_CH4  0x3f       /* Transmit Channel 4 */
-#define                  MUTE_CH4  0x80       /* Mute Channel 4 */
-#define                    TX_CH5  0x3f00     /* Transmit Channel 5 */
-#define                  MUTE_CH5  0x8000     /* Mute Channel 5 */
-#define                    TX_CH6  0x3f0000   /* Transmit Channel 6 */
-#define                  MUTE_CH6  0x800000   /* Mute Channel 6 */
-#define                    TX_CH7  0x3f000000 /* Transmit Channel 7 */
-#define                  MUTE_CH7  0x80000000 /* Mute Channel 7 */
-
-/* Bit masks for MXVR_ROUTING_2 */
-
-#define                    TX_CH8  0x3f       /* Transmit Channel 8 */
-#define                  MUTE_CH8  0x80       /* Mute Channel 8 */
-#define                    TX_CH9  0x3f00     /* Transmit Channel 9 */
-#define                  MUTE_CH9  0x8000     /* Mute Channel 9 */
-#define                   TX_CH10  0x3f0000   /* Transmit Channel 10 */
-#define                 MUTE_CH10  0x800000   /* Mute Channel 10 */
-#define                   TX_CH11  0x3f000000 /* Transmit Channel 11 */
-#define                 MUTE_CH11  0x80000000 /* Mute Channel 11 */
-
-/* Bit masks for MXVR_ROUTING_3 */
-
-#define                   TX_CH12  0x3f       /* Transmit Channel 12 */
-#define                 MUTE_CH12  0x80       /* Mute Channel 12 */
-#define                   TX_CH13  0x3f00     /* Transmit Channel 13 */
-#define                 MUTE_CH13  0x8000     /* Mute Channel 13 */
-#define                   TX_CH14  0x3f0000   /* Transmit Channel 14 */
-#define                 MUTE_CH14  0x800000   /* Mute Channel 14 */
-#define                   TX_CH15  0x3f000000 /* Transmit Channel 15 */
-#define                 MUTE_CH15  0x80000000 /* Mute Channel 15 */
-
-/* Bit masks for MXVR_ROUTING_4 */
-
-#define                   TX_CH16  0x3f       /* Transmit Channel 16 */
-#define                 MUTE_CH16  0x80       /* Mute Channel 16 */
-#define                   TX_CH17  0x3f00     /* Transmit Channel 17 */
-#define                 MUTE_CH17  0x8000     /* Mute Channel 17 */
-#define                   TX_CH18  0x3f0000   /* Transmit Channel 18 */
-#define                 MUTE_CH18  0x800000   /* Mute Channel 18 */
-#define                   TX_CH19  0x3f000000 /* Transmit Channel 19 */
-#define                 MUTE_CH19  0x80000000 /* Mute Channel 19 */
-
-/* Bit masks for MXVR_ROUTING_5 */
-
-#define                   TX_CH20  0x3f       /* Transmit Channel 20 */
-#define                 MUTE_CH20  0x80       /* Mute Channel 20 */
-#define                   TX_CH21  0x3f00     /* Transmit Channel 21 */
-#define                 MUTE_CH21  0x8000     /* Mute Channel 21 */
-#define                   TX_CH22  0x3f0000   /* Transmit Channel 22 */
-#define                 MUTE_CH22  0x800000   /* Mute Channel 22 */
-#define                   TX_CH23  0x3f000000 /* Transmit Channel 23 */
-#define                 MUTE_CH23  0x80000000 /* Mute Channel 23 */
-
-/* Bit masks for MXVR_ROUTING_6 */
-
-#define                   TX_CH24  0x3f       /* Transmit Channel 24 */
-#define                 MUTE_CH24  0x80       /* Mute Channel 24 */
-#define                   TX_CH25  0x3f00     /* Transmit Channel 25 */
-#define                 MUTE_CH25  0x8000     /* Mute Channel 25 */
-#define                   TX_CH26  0x3f0000   /* Transmit Channel 26 */
-#define                 MUTE_CH26  0x800000   /* Mute Channel 26 */
-#define                   TX_CH27  0x3f000000 /* Transmit Channel 27 */
-#define                 MUTE_CH27  0x80000000 /* Mute Channel 27 */
-
-/* Bit masks for MXVR_ROUTING_7 */
-
-#define                   TX_CH28  0x3f       /* Transmit Channel 28 */
-#define                 MUTE_CH28  0x80       /* Mute Channel 28 */
-#define                   TX_CH29  0x3f00     /* Transmit Channel 29 */
-#define                 MUTE_CH29  0x8000     /* Mute Channel 29 */
-#define                   TX_CH30  0x3f0000   /* Transmit Channel 30 */
-#define                 MUTE_CH30  0x800000   /* Mute Channel 30 */
-#define                   TX_CH31  0x3f000000 /* Transmit Channel 31 */
-#define                 MUTE_CH31  0x80000000 /* Mute Channel 31 */
-
-/* Bit masks for MXVR_ROUTING_8 */
-
-#define                   TX_CH32  0x3f       /* Transmit Channel 32 */
-#define                 MUTE_CH32  0x80       /* Mute Channel 32 */
-#define                   TX_CH33  0x3f00     /* Transmit Channel 33 */
-#define                 MUTE_CH33  0x8000     /* Mute Channel 33 */
-#define                   TX_CH34  0x3f0000   /* Transmit Channel 34 */
-#define                 MUTE_CH34  0x800000   /* Mute Channel 34 */
-#define                   TX_CH35  0x3f000000 /* Transmit Channel 35 */
-#define                 MUTE_CH35  0x80000000 /* Mute Channel 35 */
-
-/* Bit masks for MXVR_ROUTING_9 */
-
-#define                   TX_CH36  0x3f       /* Transmit Channel 36 */
-#define                 MUTE_CH36  0x80       /* Mute Channel 36 */
-#define                   TX_CH37  0x3f00     /* Transmit Channel 37 */
-#define                 MUTE_CH37  0x8000     /* Mute Channel 37 */
-#define                   TX_CH38  0x3f0000   /* Transmit Channel 38 */
-#define                 MUTE_CH38  0x800000   /* Mute Channel 38 */
-#define                   TX_CH39  0x3f000000 /* Transmit Channel 39 */
-#define                 MUTE_CH39  0x80000000 /* Mute Channel 39 */
-
-/* Bit masks for MXVR_ROUTING_10 */
-
-#define                   TX_CH40  0x3f       /* Transmit Channel 40 */
-#define                 MUTE_CH40  0x80       /* Mute Channel 40 */
-#define                   TX_CH41  0x3f00     /* Transmit Channel 41 */
-#define                 MUTE_CH41  0x8000     /* Mute Channel 41 */
-#define                   TX_CH42  0x3f0000   /* Transmit Channel 42 */
-#define                 MUTE_CH42  0x800000   /* Mute Channel 42 */
-#define                   TX_CH43  0x3f000000 /* Transmit Channel 43 */
-#define                 MUTE_CH43  0x80000000 /* Mute Channel 43 */
-
-/* Bit masks for MXVR_ROUTING_11 */
-
-#define                   TX_CH44  0x3f       /* Transmit Channel 44 */
-#define                 MUTE_CH44  0x80       /* Mute Channel 44 */
-#define                   TX_CH45  0x3f00     /* Transmit Channel 45 */
-#define                 MUTE_CH45  0x8000     /* Mute Channel 45 */
-#define                   TX_CH46  0x3f0000   /* Transmit Channel 46 */
-#define                 MUTE_CH46  0x800000   /* Mute Channel 46 */
-#define                   TX_CH47  0x3f000000 /* Transmit Channel 47 */
-#define                 MUTE_CH47  0x80000000 /* Mute Channel 47 */
-
-/* Bit masks for MXVR_ROUTING_12 */
-
-#define                   TX_CH48  0x3f       /* Transmit Channel 48 */
-#define                 MUTE_CH48  0x80       /* Mute Channel 48 */
-#define                   TX_CH49  0x3f00     /* Transmit Channel 49 */
-#define                 MUTE_CH49  0x8000     /* Mute Channel 49 */
-#define                   TX_CH50  0x3f0000   /* Transmit Channel 50 */
-#define                 MUTE_CH50  0x800000   /* Mute Channel 50 */
-#define                   TX_CH51  0x3f000000 /* Transmit Channel 51 */
-#define                 MUTE_CH51  0x80000000 /* Mute Channel 51 */
-
-/* Bit masks for MXVR_ROUTING_13 */
-
-#define                   TX_CH52  0x3f       /* Transmit Channel 52 */
-#define                 MUTE_CH52  0x80       /* Mute Channel 52 */
-#define                   TX_CH53  0x3f00     /* Transmit Channel 53 */
-#define                 MUTE_CH53  0x8000     /* Mute Channel 53 */
-#define                   TX_CH54  0x3f0000   /* Transmit Channel 54 */
-#define                 MUTE_CH54  0x800000   /* Mute Channel 54 */
-#define                   TX_CH55  0x3f000000 /* Transmit Channel 55 */
-#define                 MUTE_CH55  0x80000000 /* Mute Channel 55 */
-
-/* Bit masks for MXVR_ROUTING_14 */
-
-#define                   TX_CH56  0x3f       /* Transmit Channel 56 */
-#define                 MUTE_CH56  0x80       /* Mute Channel 56 */
-#define                   TX_CH57  0x3f00     /* Transmit Channel 57 */
-#define                 MUTE_CH57  0x8000     /* Mute Channel 57 */
-#define                   TX_CH58  0x3f0000   /* Transmit Channel 58 */
-#define                 MUTE_CH58  0x800000   /* Mute Channel 58 */
-#define                   TX_CH59  0x3f000000 /* Transmit Channel 59 */
-#define                 MUTE_CH59  0x80000000 /* Mute Channel 59 */
-
-/* Bit masks for MXVR_BLOCK_CNT */
-
-#define                      BCNT  0xffff     /* Block Count */
-
-/* Bit masks for MXVR_CLK_CTL */
-
-#define                  MXTALCEN  0x1        /* MXVR Crystal Oscillator Clock Enable */
-#define                  MXTALFEN  0x2        /* MXVR Crystal Oscillator Feedback Enable */
-#define                  MXTALMUL  0x30       /* MXVR Crystal Multiplier */
-#define                  CLKX3SEL  0x80       /* Clock Generation Source Select */
-#define                   MMCLKEN  0x100      /* Master Clock Enable */
-#define                  MMCLKMUL  0x1e00     /* Master Clock Multiplication Factor */
-#define                   PLLSMPS  0xe000     /* MXVR PLL State Machine Prescaler */
-#define                   MBCLKEN  0x10000    /* Bit Clock Enable */
-#define                  MBCLKDIV  0x1e0000   /* Bit Clock Divide Factor */
-#define                     INVRX  0x800000   /* Invert Receive Data */
-#define                     MFSEN  0x1000000  /* Frame Sync Enable */
-#define                    MFSDIV  0x1e000000 /* Frame Sync Divide Factor */
-#define                    MFSSEL  0x60000000 /* Frame Sync Select */
-#define                   MFSSYNC  0x80000000 /* Frame Sync Synchronization Select */
-
-/* Bit masks for MXVR_CDRPLL_CTL */
-
-#define                   CDRSMEN  0x1        /* MXVR CDRPLL State Machine Enable */
-#define                   CDRRSTB  0x2        /* MXVR CDRPLL Reset */
-#define                   CDRSVCO  0x4        /* MXVR CDRPLL Start VCO */
-#define                   CDRMODE  0x8        /* MXVR CDRPLL CDR Mode Select */
-#define                   CDRSCNT  0x3f0      /* MXVR CDRPLL Start Counter */
-#define                   CDRLCNT  0xfc00     /* MXVR CDRPLL Lock Counter */
-#define                 CDRSHPSEL  0x3f0000   /* MXVR CDRPLL Shaper Select */
-#define                  CDRSHPEN  0x800000   /* MXVR CDRPLL Shaper Enable */
-#define                  CDRCPSEL  0xff000000 /* MXVR CDRPLL Charge Pump Current Select */
-
-/* Bit masks for MXVR_FMPLL_CTL */
-
-#define                    FMSMEN  0x1        /* MXVR FMPLL State Machine Enable */
-#define                    FMRSTB  0x2        /* MXVR FMPLL Reset */
-#define                    FMSVCO  0x4        /* MXVR FMPLL Start VCO */
-#define                    FMSCNT  0x3f0      /* MXVR FMPLL Start Counter */
-#define                    FMLCNT  0xfc00     /* MXVR FMPLL Lock Counter */
-#define                   FMCPSEL  0xff000000 /* MXVR FMPLL Charge Pump Current Select */
-
-/* Bit masks for MXVR_PIN_CTL */
-
-#define                  MTXONBOD  0x1        /* MTXONB Open Drain Select */
-#define                   MTXONBG  0x2        /* MTXONB Gates MTX Select */
-#define                     MFSOE  0x10       /* MFS Output Enable */
-#define                  MFSGPSEL  0x20       /* MFS General Purpose Output Select */
-#define                  MFSGPDAT  0x40       /* MFS General Purpose Output Data */
-
-/* Bit masks for MXVR_SCLK_CNT */
-
-#define                      SCNT  0xffff     /* System Clock Count */
-
-/* Bit masks for KPAD_CTL */
-
-#define                   KPAD_EN  0x1        /* Keypad Enable */
-#define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
-#define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
-#define                KPAD_COLEN  0xe000     /* Column Enable Width */
-
-/* Bit masks for KPAD_PRESCALE */
-
-#define         KPAD_PRESCALE_VAL  0x3f       /* Key Prescale Value */
-
-/* Bit masks for KPAD_MSEL */
-
-#define                DBON_SCALE  0xff       /* Debounce Scale Value */
-#define              COLDRV_SCALE  0xff00     /* Column Driver Scale Value */
-
-/* Bit masks for KPAD_ROWCOL */
-
-#define                  KPAD_ROW  0xff       /* Rows Pressed */
-#define                  KPAD_COL  0xff00     /* Columns Pressed */
-
-/* Bit masks for KPAD_STAT */
-
-#define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
-#define              KPAD_PRESSED  0x8        /* Key press current status */
-
-/* Bit masks for KPAD_SOFTEVAL */
-
-#define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-
-/* Bit masks for SDH_COMMAND */
-
-#define                   CMD_IDX  0x3f       /* Command Index */
-#define                   CMD_RSP  0x40       /* Response */
-#define                 CMD_L_RSP  0x80       /* Long Response */
-#define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                CMD_PEND_E  0x200      /* Command Pending */
-#define                     CMD_E  0x400      /* Command Enable */
-
-/* Bit masks for SDH_PWR_CTL */
-
-#define                    PWR_ON  0x3        /* Power On */
-#if 0
-#define                       TBD  0x3c       /* TBD */
-#endif
-#define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                   ROD_CTL  0x80       /* Rod Control */
-
-/* Bit masks for SDH_CLK_CTL */
-
-#define                    CLKDIV  0xff       /* MC_CLK Divisor */
-#define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-
-/* Bit masks for SDH_RESP_CMD */
-
-#define                  RESP_CMD  0x3f       /* Response Command */
-
-/* Bit masks for SDH_DATA_CTL */
-
-#define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
-
-/* Bit masks for SDH_STATUS */
-
-#define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
-#define               DAT_TIME_OUT  0x8        /* Data Time Out */
-#define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define              CMD_RESP_END  0x40       /* CMD Response End */
-#define                  CMD_SENT  0x80       /* CMD Sent */
-#define                   DAT_END  0x100      /* Data End */
-#define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define               DAT_BLK_END  0x400      /* Data Block End */
-#define                   CMD_ACT  0x800      /* CMD Active */
-#define                    TX_ACT  0x1000     /* Transmit Active */
-#define                    RX_ACT  0x2000     /* Receive Active */
-#define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-
-/* Bit masks for SDH_STATUS_CLR */
-
-#define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define              DAT_END_STAT  0x100      /* Data End Status */
-#define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-
-/* Bit masks for SDH_MASK0 */
-
-#define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define              DAT_END_MASK  0x100      /* Data End Mask */
-#define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-
-/* Bit masks for SDH_FIFO_CNT */
-
-#define                FIFO_COUNT  0x7fff     /* FIFO Count */
-
-/* Bit masks for SDH_E_STATUS */
-
-#define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define               SD_CARD_DET  0x10       /* SD Card Detect */
-
-/* Bit masks for SDH_E_MASK */
-
-#define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                   SCD_MSK  0x40       /* Mask Card Detect */
-
-/* Bit masks for SDH_CFG */
-
-#define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                       MWE  0x8        /* Moving Window Enable */
-#define                    SD_RST  0x10       /* SDMMC Reset */
-#define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-
-/* Bit masks for SDH_RD_WAIT_EN */
-
-#define                       RWR  0x1        /* Read Wait Request */
-
-/* Bit masks for ATAPI_CONTROL */
-
-#define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define                  SOFT_RST  0x40       /* Soft Reset */
-#define                   DEV_RST  0x80       /* Device Reset */
-#define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
-
-/* Bit masks for ATAPI_STATUS */
-
-#define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
-
-/* Bit masks for ATAPI_DEV_ADDR */
-
-#define                  DEV_ADDR  0x1f       /* Device Address */
-
-/* Bit masks for ATAPI_INT_MASK */
-
-#define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-
-/* Bit masks for ATAPI_INT_STATUS */
-
-#define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-
-/* Bit masks for ATAPI_LINE_STATUS */
-
-#define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define                ATAPI_ADDR  0x70       /* ATAPI address line status */
-#define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-
-/* Bit masks for ATAPI_SM_STATE */
-
-#define                PIO_CSTATE  0xf        /* PIO mode state machine current state */
-#define                DMA_CSTATE  0xf0       /* DMA mode state machine current state */
-#define             UDMAIN_CSTATE  0xf00      /* Ultra DMA-In mode state machine current state */
-#define            UDMAOUT_CSTATE  0xf000     /* ATAPI IORDY line status */
-
-/* Bit masks for ATAPI_TERMINATE */
-
-#define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-
-/* Bit masks for ATAPI_REG_TIM_0 */
-
-#define                    T2_REG  0xff       /* End of cycle time for register access transfers */
-#define                  TEOC_REG  0xff00     /* Selects DIOR/DIOW pulsewidth */
-
-/* Bit masks for ATAPI_PIO_TIM_0 */
-
-#define                    T1_REG  0xf        /* Time from address valid to DIOR/DIOW */
-#define                T2_REG_PIO  0xff0      /* DIOR/DIOW pulsewidth */
-#define                    T4_REG  0xf000     /* DIOW data hold */
-
-/* Bit masks for ATAPI_PIO_TIM_1 */
-
-#define              TEOC_REG_PIO  0xff       /* End of cycle time for PIO access transfers. */
-
-/* Bit masks for ATAPI_MULTI_TIM_0 */
-
-#define                        TD  0xff       /* DIOR/DIOW asserted pulsewidth */
-#define                        TM  0xff00     /* Time from address valid to DIOR/DIOW */
-
-/* Bit masks for ATAPI_MULTI_TIM_1 */
-
-#define                       TKW  0xff       /* Selects DIOW negated pulsewidth */
-#define                       TKR  0xff00     /* Selects DIOR negated pulsewidth */
-
-/* Bit masks for ATAPI_MULTI_TIM_2 */
-
-#define                        TH  0xff       /* Selects DIOW data hold */
-#define                      TEOC  0xff00     /* Selects end of cycle for DMA */
-
-/* Bit masks for ATAPI_ULTRA_TIM_0 */
-
-#define                      TACK  0xff       /* Selects setup and hold times for TACK */
-#define                      TENV  0xff00     /* Selects envelope time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_1 */
-
-#define                      TDVS  0xff       /* Selects data valid setup time */
-#define                 TCYC_TDVS  0xff00     /* Selects cycle time - TDVS time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_2 */
-
-#define                       TSS  0xff       /* Selects time from STROBE edge to negation of DMARQ or assertion of STOP */
-#define                      TMLI  0xff00     /* Selects interlock time */
-
-/* Bit masks for ATAPI_ULTRA_TIM_3 */
-
-#define                      TZAH  0xff       /* Selects minimum delay required for output */
-#define               READY_PAUSE  0xff00     /* Selects ready to pause */
-
-/* Bit masks for TIMER_ENABLE1 */
-
-#define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   TIMEN10  0x4        /* Timer 10 Enable */
-
-/* Bit masks for TIMER_DISABLE1 */
-
-#define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  TIMDIS10  0x4        /* Timer 10 Disable */
-
-/* Bit masks for TIMER_STATUS1 */
-
-#define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-
-/* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
-
-/* Bit masks for USB_FADDR */
-
-#define          FUNCTION_ADDRESS  0x7f       /* Function address */
-
-/* Bit masks for USB_POWER */
-
-#define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define               RESUME_MODE  0x4        /* DMA Mode */
-#define                     RESET  0x8        /* Reset indicator */
-#define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                 SOFT_CONN  0x40       /* Soft connect */
-#define                ISO_UPDATE  0x80       /* Isochronous update */
-
-/* Bit masks for USB_INTRTX */
-
-#define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-
-/* Bit masks for USB_INTRRX */
-
-#define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-
-/* Bit masks for USB_INTRTXE */
-
-#define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-
-/* Bit masks for USB_INTRRXE */
-
-#define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-
-/* Bit masks for USB_INTRUSB */
-
-#define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                  RESUME_B  0x2        /* Resume indicator */
-#define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define                     SOF_B  0x8        /* Start of frame */
-#define                    CONN_B  0x10       /* Connection indicator */
-#define                  DISCON_B  0x20       /* Disconnect indicator */
-#define             SESSION_REQ_B  0x40       /* Session Request */
-#define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-
-/* Bit masks for USB_INTRUSBE */
-
-#define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-
-/* Bit masks for USB_FRAME */
-
-#define              FRAME_NUMBER  0x7ff      /* Frame number */
-
-/* Bit masks for USB_INDEX */
-
-#define         SELECTED_ENDPOINT  0xf        /* selected endpoint */
-
-/* Bit masks for USB_GLOBAL_CTL */
-
-#define                GLOBAL_ENA  0x1        /* enables USB module */
-#define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-
-/* Bit masks for USB_OTG_DEV_CTL */
-
-#define                   SESSION  0x1        /* session indicator */
-#define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                     LSDEV  0x20       /* Low-speed indicator */
-#define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-
-/* Bit masks for USB_OTG_VBUS_IRQ */
-
-#define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-
-/* Bit masks for USB_OTG_VBUS_MASK */
-
-#define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-
-/* Bit masks for USB_CSR0 */
-
-#define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                STALL_SENT  0x4        /* STALL handshake sent */
-#define                   DATAEND  0x8        /* Data end indicator */
-#define                  SETUPEND  0x10       /* Setup end */
-#define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-
-/* Bit masks for USB_COUNT0 */
-
-#define              EP0_RX_COUNT  0x7f       /* number of received bytes in EP0 FIFO */
-
-/* Bit masks for USB_NAKLIMIT0 */
-
-#define             EP0_NAK_LIMIT  0x1f       /* number of frames/micro frames after which EP0 timeouts */
-
-/* Bit masks for USB_TX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_T  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_RX_MAX_PACKET */
-
-#define         MAX_PACKET_SIZE_R  0x7ff      /* maximum data pay load in a frame */
-
-/* Bit masks for USB_TXCSR */
-
-#define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                  ERROR_TH  0x4        /* error condition host mode */
-#define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-
-/* Bit masks for USB_TXCOUNT */
-
-#define                  TX_COUNT  0x1fff     /* Number of bytes to be written to the selected endpoint Tx FIFO */
-
-/* Bit masks for USB_RXCSR */
-
-#define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-
-/* Bit masks for USB_RXCOUNT */
-
-#define                  RX_COUNT  0x1fff     /* Number of received bytes in the packet in the Rx FIFO */
-
-/* Bit masks for USB_TXTYPE */
-
-#define            TARGET_EP_NO_T  0xf        /* EP number */
-#define                PROTOCOL_T  0xc        /* transfer type */
-
-/* Bit masks for USB_TXINTERVAL */
-
-#define          TX_POLL_INTERVAL  0xff       /* polling interval for selected Tx EP */
-
-/* Bit masks for USB_RXTYPE */
-
-#define            TARGET_EP_NO_R  0xf        /* EP number */
-#define                PROTOCOL_R  0xc        /* transfer type */
-
-/* Bit masks for USB_RXINTERVAL */
-
-#define          RX_POLL_INTERVAL  0xff       /* polling interval for selected Rx EP */
-
-/* Bit masks for USB_DMA_INTERRUPT */
-
-#define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-
-/* Bit masks for USB_DMAxCONTROL */
-
-#define                   DMA_ENA  0x1        /* DMA enable */
-#define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                      MODE  0x4        /* DMA Bus error */
-#define                   INT_ENA  0x8        /* Interrupt enable */
-#define                     EPNUM  0xf0       /* EP number */
-#define                  BUSERROR  0x100      /* DMA Bus error */
-
-/* Bit masks for USB_DMAxADDRHIGH */
-
-#define             DMA_ADDR_HIGH  0xffff     /* Upper 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxADDRLOW */
-
-#define              DMA_ADDR_LOW  0xffff     /* Lower 16-bits of memory source/destination address for the DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTHIGH */
-
-#define            DMA_COUNT_HIGH  0xffff     /* Upper 16-bits of byte count of DMA transfer for DMA master channel */
-
-/* Bit masks for USB_DMAxCOUNTLOW */
-
-#define             DMA_COUNT_LOW  0xffff     /* Lower 16-bits of byte count of DMA transfer for DMA master channel */
-
-/* Bit masks for HMDMAx_CONTROL */
-
-#define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                       DRQ  0x300      /* Handshake MDMA Request Type */
-#define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                        PS  0x2000     /* Pin Status */
-#define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       BDI  0x8000     /* Block Done Interrupt Generated */
-
-/* ******************************************* */
-/*     MULTI BIT MACRO ENUMERATIONS            */
-/* ******************************************* */
-
-/* ************************ */
-/*   MXVR Address Offsets   */
-/* ************************ */
-
-/* Control Message Receive Buffer (CMRB) Address Offsets */
-
-#define CMRB_STRIDE       0x00000016lu
-
-#define CMRB_DST_OFFSET   0x00000000lu
-#define CMRB_SRC_OFFSET   0x00000002lu
-#define CMRB_DATA_OFFSET  0x00000005lu
-
-/* Control Message Transmit Buffer (CMTB) Address Offsets */
-
-#define CMTB_PRIO_OFFSET    0x00000000lu
-#define CMTB_DST_OFFSET     0x00000002lu
-#define CMTB_SRC_OFFSET     0x00000004lu
-#define CMTB_TYPE_OFFSET    0x00000006lu
-#define CMTB_DATA_OFFSET    0x00000007lu
-
-#define CMTB_ANSWER_OFFSET  0x0000000Alu
-
-#define CMTB_STAT_N_OFFSET  0x00000018lu
-#define CMTB_STAT_A_OFFSET  0x00000016lu
-#define CMTB_STAT_D_OFFSET  0x0000000Elu
-#define CMTB_STAT_R_OFFSET  0x00000014lu
-#define CMTB_STAT_W_OFFSET  0x00000014lu
-#define CMTB_STAT_G_OFFSET  0x00000014lu
-
-/* Asynchronous Packet Receive Buffer (APRB) Address Offsets */
-
-#define APRB_STRIDE       0x00000400lu
-
-#define APRB_DST_OFFSET   0x00000000lu
-#define APRB_LEN_OFFSET   0x00000002lu
-#define APRB_SRC_OFFSET   0x00000004lu
-#define APRB_DATA_OFFSET  0x00000006lu
-
-/* Asynchronous Packet Transmit Buffer (APTB) Address Offsets */
-
-#define APTB_PRIO_OFFSET  0x00000000lu
-#define APTB_DST_OFFSET   0x00000002lu
-#define APTB_LEN_OFFSET   0x00000004lu
-#define APTB_SRC_OFFSET   0x00000006lu
-#define APTB_DATA_OFFSET  0x00000008lu
-
-/* Remote Read Buffer (RRDB) Address Offsets */
-
-#define RRDB_WADDR_OFFSET 0x00000100lu
-#define RRDB_WLEN_OFFSET  0x00000101lu
-
-/* **************** */
-/*   MXVR Macros    */
-/* **************** */
-
-/* MXVR_CONFIG Macros */
-
-#define SET_MSB(x)       ( ( (x) & 0xF  ) << 9)
-
-/* MXVR_INT_STAT_1 Macros */
-
-#define DONEX(x)         (0x00000002 << (4 * (x)))
-#define HDONEX(x)        (0x00000001 << (4 * (x)))
-
-/* MXVR_INT_EN_1 Macros */
-
-#define DONEENX(x)       (0x00000002 << (4 * (x)))
-#define HDONEENX(x)      (0x00000001 << (4 * (x)))
-
-/* MXVR_CDRPLL_CTL Macros */
-
-#define SET_CDRSHPSEL(x) ( ( (x) & 0x3F ) << 16)
-
-/* MXVR_FMPLL_CTL Macros */
-
-#define SET_CDRCPSEL(x)  ( ( (x) & 0xFF ) << 24)
-#define SET_FMCPSEL(x)   ( ( (x) & 0xFF ) << 24)
-
 #endif /* _DEF_BF549_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -1609,44 +1609,6 @@
 #define                 PINT2  0x40000000 /* Pin Interrupt 2 */
 #define                 PINT3  0x80000000 /* Pin Interrupt 3 */
 
-/* Bit masks for DMAx_CONFIG, MDMA_Sx_CONFIG, MDMA_Dx_CONFIG */
-
-#define                     DMAEN  0x1        /* DMA Channel Enable */
-#define                       WNR  0x2        /* DMA Direction */
-#define                  WDSIZE_8  0x0        /* Transfer Word Size = 8 */
-#define                 WDSIZE_16  0x4        /* Transfer Word Size = 16 */
-#define                 WDSIZE_32  0x8        /* Transfer Word Size = 32 */
-#define                     DMA2D  0x10       /* DMA Mode */
-#define                   RESTART  0x20       /* Work Unit Transitions */
-#define                    DI_SEL  0x40       /* Data Interrupt Timing Select */
-#define                     DI_EN  0x80       /* Data Interrupt Enable */
-
-#define                    NDSIZE  0xf00      /* Flex Descriptor Size */
-#define                  NDSIZE_0 0x0000      /* Next Descriptor Size = 0 (Stop/Autobuffer) */
-#define                  NDSIZE_1 0x0100      /* Next Descriptor Size = 1 */
-#define                  NDSIZE_2 0x0200      /* Next Descriptor Size = 2 */
-#define                  NDSIZE_3 0x0300      /* Next Descriptor Size = 3 */
-#define                  NDSIZE_4 0x0400      /* Next Descriptor Size = 4 */
-#define                  NDSIZE_5 0x0500      /* Next Descriptor Size = 5 */
-#define                  NDSIZE_6 0x0600      /* Next Descriptor Size = 6 */
-#define                  NDSIZE_7 0x0700      /* Next Descriptor Size = 7 */
-#define                  NDSIZE_8 0x0800      /* Next Descriptor Size = 8 */
-#define                  NDSIZE_9 0x0900      /* Next Descriptor Size = 9 */
-
-#define                   DMAFLOW  0xf000     /* Next Operation */
-#define              DMAFLOW_STOP  0x0000     /* Stop Mode */
-#define              DMAFLOW_AUTO  0x1000     /* Autobuffer Mode */
-#define             DMAFLOW_ARRAY  0x4000     /* Descriptor Array Mode */
-#define             DMAFLOW_SMALL  0x6000     /* Small Model Descriptor List Mode */
-#define             DMAFLOW_LARGE  0x7000     /* Large Model Descriptor List Mode */
-
-/* Bit masks for DMAx_IRQ_STATUS, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
-
-#define                  DMA_DONE  0x1        /* DMA Completion Interrupt Status */
-#define                   DMA_ERR  0x2        /* DMA Error Interrupt Status */
-#define                    DFETCH  0x4        /* DMA Descriptor Fetch */
-#define                   DMA_RUN  0x8        /* DMA Channel Running */
-
 /* Bit masks for DMAx_PERIPHERAL_MAP, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
 #define                     CTYPE  0x40       /* DMA Channel Type */
@@ -1815,10 +1777,6 @@
 #define               DEB3_MERROR  0x40       /* DEB3 Error (2nd) */
 #define               CORE_MERROR  0x80       /* Core Error (2nd) */
 
-/* Bit masks for EBIU_ERRADD */
-
-#define             ERROR_ADDRESS  0xffffffff /* Error Address */
-
 /* Bit masks for EBIU_RSTCTL */
 
 #define                 DDRSRESET  0x1        /* DDR soft reset */
@@ -1827,98 +1785,6 @@
 #define                     SRACK  0x10       /* Self-refresh acknowledge */
 #define                MDDRENABLE  0x20       /* Mobile DDR enable */
 
-/* Bit masks for EBIU_DDRBRC0 */
-
-#define                      BRC0  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC1 */
-
-#define                      BRC1  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC2 */
-
-#define                      BRC2  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC3 */
-
-#define                      BRC3  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC4 */
-
-#define                      BRC4  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC5 */
-
-#define                      BRC5  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC6 */
-
-#define                      BRC6  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBRC7 */
-
-#define                      BRC7  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC0 */
-
-#define                      BWC0  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC1 */
-
-#define                      BWC1  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC2 */
-
-#define                      BWC2  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC3 */
-
-#define                      BWC3  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC4 */
-
-#define                      BWC4  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC5 */
-
-#define                      BWC5  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC6 */
-
-#define                      BWC6  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRBWC7 */
-
-#define                      BWC7  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRACCT */
-
-#define                      ACCT  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRTACT */
-
-#define                      TECT  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRARCT */
-
-#define                      ARCT  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRGC0 */
-
-#define                       GC0  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRGC1 */
-
-#define                       GC1  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRGC2 */
-
-#define                       GC2  0xffffffff /* Count */
-
-/* Bit masks for EBIU_DDRGC3 */
-
-#define                       GC3  0xffffffff /* Count */
-
 /* Bit masks for EBIU_DDRMCEN */
 
 #define                B0WCENABLE  0x1        /* Bank 0 write count enable */
@@ -2092,12 +1958,6 @@
 #define                     TRUN6  0x40000000 /* Timer 6 Slave Enable Status */
 #define                     TRUN7  0x80000000 /* Timer 7 Slave Enable Status */
 
-/* Bit masks for WDOG_CTL */
-
-#define                      WDEV  0x6        /* Watchdog Event */
-#define                      WDEN  0xff0      /* Watchdog Enable */
-#define                      WDRO  0x8000     /* Watchdog Rolled Over */
-
 /* Bit masks for CNT_CONFIG */
 
 #define                      CNTE  0x1        /* Counter Enable */
@@ -2149,81 +2009,6 @@
 
 #define                 DPRESCALE  0xf        /* Load Counter Register */
 
-/* Bit masks for RTC_STAT */
-
-#define                   SECONDS  0x3f       /* Seconds */
-#define                   MINUTES  0xfc0      /* Minutes */
-#define                     HOURS  0x1f000    /* Hours */
-#define               DAY_COUNTER  0xfffe0000 /* Day Counter */
-
-/* Bit masks for RTC_ICTL */
-
-#define STOPWATCH_INTERRUPT_ENABLE  0x1        /* Stopwatch Interrupt Enable */
-#define    ALARM_INTERRUPT_ENABLE  0x2        /* Alarm Interrupt Enable */
-#define  SECONDS_INTERRUPT_ENABLE  0x4        /* Seconds Interrupt Enable */
-#define  MINUTES_INTERRUPT_ENABLE  0x8        /* Minutes Interrupt Enable */
-#define    HOURS_INTERRUPT_ENABLE  0x10       /* Hours Interrupt Enable */
-#define TWENTY_FOUR_HOURS_INTERRUPT_ENABLE  0x20       /* 24 Hours Interrupt Enable */
-#define DAY_ALARM_INTERRUPT_ENABLE  0x40       /* Day Alarm Interrupt Enable */
-#define WRITE_COMPLETE_INTERRUPT_ENABLE  0x8000     /* Write Complete Interrupt Enable */
-
-/* Bit masks for RTC_ISTAT */
-
-#define      STOPWATCH_EVENT_FLAG  0x1        /* Stopwatch Event Flag */
-#define          ALARM_EVENT_FLAG  0x2        /* Alarm Event Flag */
-#define        SECONDS_EVENT_FLAG  0x4        /* Seconds Event Flag */
-#define        MINUTES_EVENT_FLAG  0x8        /* Minutes Event Flag */
-#define          HOURS_EVENT_FLAG  0x10       /* Hours Event Flag */
-#define TWENTY_FOUR_HOURS_EVENT_FLAG  0x20       /* 24 Hours Event Flag */
-#define      DAY_ALARM_EVENT_FLAG  0x40       /* Day Alarm Event Flag */
-#define     WRITE_PENDING__STATUS  0x4000     /* Write Pending  Status */
-#define            WRITE_COMPLETE  0x8000     /* Write Complete */
-
-/* Bit masks for RTC_SWCNT */
-
-#define           STOPWATCH_COUNT  0xffff     /* Stopwatch Count */
-
-/* Bit masks for RTC_ALARM */
-
-#define                   SECONDS  0x3f       /* Seconds */
-#define                   MINUTES  0xfc0      /* Minutes */
-#define                     HOURS  0x1f000    /* Hours */
-#define                       DAY  0xfffe0000 /* Day */
-
-/* Bit masks for RTC_PREN */
-
-#define                      PREN  0x1        /* Prescaler Enable */
-
-/* Bit masks for OTP_CONTROL */
-
-#define                FUSE_FADDR  0x1ff      /* OTP/Fuse Address */
-#define                      FIEN  0x800      /* OTP/Fuse Interrupt Enable */
-#define                  FTESTDEC  0x1000     /* OTP/Fuse Test Decoder */
-#define                   FWRTEST  0x2000     /* OTP/Fuse Write Test */
-#define                     FRDEN  0x4000     /* OTP/Fuse Read Enable */
-#define                     FWREN  0x8000     /* OTP/Fuse Write Enable */
-
-/* Bit masks for OTP_BEN */
-
-#define                      FBEN  0xffff     /* OTP/Fuse Byte Enable */
-
-/* Bit masks for OTP_STATUS */
-
-#define                     FCOMP  0x1        /* OTP/Fuse Access Complete */
-#define                    FERROR  0x2        /* OTP/Fuse Access Error */
-#define                  MMRGLOAD  0x10       /* Memory Mapped Register Gasket Load */
-#define                  MMRGLOCK  0x20       /* Memory Mapped Register Gasket Lock */
-#define                    FPGMEN  0x40       /* OTP/Fuse Program Enable */
-
-/* Bit masks for OTP_TIMING */
-
-#define                   USECDIV  0xff       /* Micro Second Divider */
-#define                   READACC  0x7f00     /* Read Access Time */
-#define                   CPUMPRL  0x38000    /* Charge Pump Release Time */
-#define                   CPUMPSU  0xc0000    /* Charge Pump Setup Time */
-#define                   CPUMPHD  0xf00000   /* Charge Pump Hold Time */
-#define                   PGMTIME  0xff000000 /* Program Time */
-
 /* Bit masks for SECURE_SYSSWT */
 
 #define                   EMUDABL  0x1        /* Emulation Disable. */
@@ -2252,26 +2037,6 @@
 #define                    AFEXIT  0x10       /* Authentication Firmware Exit */
 #define                   SECSTAT  0xe0       /* Secure Status */
 
-/* Bit masks for PLL_DIV */
-
-#define                      CSEL  0x30       /* Core Select */
-#define                      SSEL  0xf        /* System Select */
-#define			CSEL_DIV1	0x0000	/* CCLK = VCO / 1 */
-#define			CSEL_DIV2	0x0010	/* CCLK = VCO / 2 */
-#define			CSEL_DIV4	0x0020	/* CCLK = VCO / 4 */
-#define			CSEL_DIV8	0x0030	/* CCLK = VCO / 8 */
-
-/* Bit masks for PLL_CTL */
-
-#define                      MSEL  0x7e00     /* Multiplier Select */
-#define                    BYPASS  0x100      /* PLL Bypass Enable */
-#define              OUTPUT_DELAY  0x80       /* External Memory Output Delay Enable */
-#define               INPUT_DELAY  0x40       /* External Memory Input Delay Enable */
-#define                      PDWN  0x20       /* Power Down */
-#define                    STOPCK  0x8        /* Stop Clock */
-#define                   PLL_OFF  0x2        /* Disable PLL */
-#define                        DF  0x1        /* Divide Frequency */
-
 /* SWRST Masks */
 #define              SYSTEM_RESET 0x0007       /* Initiates A System Software Reset */
 #define              DOUBLE_FAULT 0x0008       /* Core Double Fault Causes Reset */
@@ -2279,52 +2044,6 @@
 #define                RESET_WDOG 0x4000       /* SW Reset Generated By Watchdog Timer */
 #define            RESET_SOFTWARE 0x8000       /* SW Reset Occurred Since Last Read Of SWRST */
 
-/* Bit masks for PLL_STAT */
-
-#define                PLL_LOCKED  0x20       /* PLL Locked Status */
-#define        ACTIVE_PLLDISABLED  0x4        /* Active Mode With PLL Disabled */
-#define                   FULL_ON  0x2        /* Full-On Mode */
-#define         ACTIVE_PLLENABLED  0x1        /* Active Mode With PLL Enabled */
-#define                     RTCWS  0x400      /* RTC/Reset Wake-Up Status */
-#define                     CANWS  0x800      /* CAN Wake-Up Status */
-#define                     USBWS  0x2000     /* USB Wake-Up Status */
-#define                    KPADWS  0x4000     /* Keypad Wake-Up Status */
-#define                     ROTWS  0x8000     /* Rotary Wake-Up Status */
-#define                      GPWS  0x1000     /* General-Purpose Wake-Up Status */
-
-/* Bit masks for VR_CTL */
-
-#define                      FREQ  0x3        /* Regulator Switching Frequency */
-#define                      GAIN  0xc        /* Voltage Output Level Gain */
-#define                      VLEV  0xf0       /* Internal Voltage Level */
-#define                   SCKELOW  0x8000     /* Drive SCKE Low During Reset Enable */
-#define                      WAKE  0x100      /* RTC/Reset Wake-Up Enable */
-#define                     CANWE  0x200      /* CAN0/1 Wake-Up Enable */
-#define                      GPWE  0x400      /* General-Purpose Wake-Up Enable */
-#define                     USBWE  0x800      /* USB Wake-Up Enable */
-#define                    KPADWE  0x1000     /* Keypad Wake-Up Enable */
-#define                     ROTWE  0x2000     /* Rotary Wake-Up Enable */
-
-#define	FREQ_333		0x0001	/* Switching Frequency Is 333 kHz */
-#define	FREQ_667		0x0002	/* Switching Frequency Is 667 kHz */
-#define	FREQ_1000		0x0003	/* Switching Frequency Is 1 MHz */
-
-#define	GAIN_5			0x0000	/* GAIN = 5*/
-#define	GAIN_10			0x0004	/* GAIN = 1*/
-#define	GAIN_20			0x0008	/* GAIN = 2*/
-#define	GAIN_50			0x000C	/* GAIN = 5*/
-
-#define	VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
-#define	VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
-#define	VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
-#define	VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
-#define	VLEV_105		0x00A0	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
-#define	VLEV_110		0x00B0	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
-#define	VLEV_115		0x00C0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
-#define	VLEV_120		0x00D0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
-#define	VLEV_125		0x00E0	/* VLEV = 1.25 V (-5% - +10% Accuracy) */
-#define	VLEV_130		0x00F0	/* VLEV = 1.30 V (-5% - +10% Accuracy) */
-
 /* Bit masks for NFC_CTL */
 
 #define                    WR_DLY  0xf        /* Write Strobe Delay */
@@ -2489,14 +2208,6 @@
 #define                      UCCT  0x40       /* Universal Counter CAN Trigger */
 #define                       UCE  0x80       /* Universal Counter Enable */
 
-/* Bit masks for CAN0_UCCNT */
-
-#define                     UCCNT  0xffff     /* Universal Counter Count Value */
-
-/* Bit masks for CAN0_UCRC */
-
-#define                     UCVAL  0xffff     /* Universal Counter Reload/Capture Value */
-
 /* Bit masks for CAN0_CEC */
 
 #define                    RXECNT  0xff       /* Receive Error Counter */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/Kconfig linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/Kconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf548/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf548/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,27 @@
+config BF542
+	def_bool y
+	depends on BF542_std || BF542M
+config BF544
+	def_bool y
+	depends on BF544_std || BF544M
+config BF547
+	def_bool y
+	depends on BF547_std || BF547M
+config BF548
+	def_bool y
+	depends on BF548_std || BF548M
+config BF549
+	def_bool y
+	depends on BF549_std || BF549M
+
+config BF54xM
+	def_bool y
+	depends on (BF542M || BF544M || BF547M || BF548M || BF549M)
+
+config BF54x
+	def_bool y
+	depends on (BF542 || BF544 || BF547 || BF548 || BF549)
+
 if (BF54x)
 
 source "arch/blackfin/mach-bf548/boards/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,551 @@
+/*
+ * File:         arch/blackfin/mach-bf561/acvilon.c
+ * Based on:     arch/blackfin/mach-bf561/ezkit.c
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *               Copyright 2009 CJSC "NII STT"
+ *
+ * Bugs:
+ *
+ * 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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * For more information about Acvilon BF561 SoM please
+ * go to http://www.niistt.ru/
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/i2c-pca-platform.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <asm/cacheflush.h>
+#include <linux/i2c.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Acvilon board";
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+#include <linux/usb/isp1760.h>
+static struct resource bfin_isp1760_resources[] = {
+	[0] = {
+	       .start = 0x20000000,
+	       .end = 0x20000000 + 0x000fffff,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = IRQ_PF15,
+	       .end = IRQ_PF15,
+	       .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	       },
+};
+
+static struct isp1760_platform_data isp1760_priv = {
+	.is_isp1761 = 0,
+	.port1_disable = 0,
+	.bus_width_16 = 1,
+	.port1_otg = 0,
+	.analog_oc = 0,
+	.dack_polarity_high = 0,
+	.dreq_polarity_high = 0,
+};
+
+static struct platform_device bfin_isp1760_device = {
+	.name = "isp1760-hcd",
+	.id = 0,
+	.dev = {
+		.platform_data = &isp1760_priv,
+		},
+	.num_resources = ARRAY_SIZE(bfin_isp1760_resources),
+	.resource = bfin_isp1760_resources,
+};
+#endif
+
+static struct resource bfin_i2c_pca_resources[] = {
+	{
+	 .name = "pca9564-regs",
+	 .start = 0x2C000000,
+	 .end = 0x2C000000 + 16,
+	 .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+	 }, {
+
+	     .start = IRQ_PF8,
+	     .end = IRQ_PF8,
+	     .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	     },
+};
+
+struct i2c_pca9564_pf_platform_data pca9564_platform_data = {
+	.gpio = -1,
+	.i2c_clock_speed = 330000,
+	.timeout = 10000
+};
+
+/* PCA9564 I2C Bus driver */
+static struct platform_device bfin_i2c_pca_device = {
+	.name = "i2c-pca-platform",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_i2c_pca_resources),
+	.resource = bfin_i2c_pca_resources,
+	.dev = {
+		.platform_data = &pca9564_platform_data,
+		}
+};
+
+/* I2C devices fitted. */
+static struct i2c_board_info acvilon_i2c_devs[] __initdata = {
+	{
+	 I2C_BOARD_INFO("ds1339", 0x68),
+	 },
+	{
+	 I2C_BOARD_INFO("tcn75", 0x49),
+	 },
+};
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+static struct platdata_mtd_ram mtd_ram_data = {
+	.mapname = "rootfs(RAM)",
+	.bankwidth = 4,
+};
+
+static struct resource mtd_ram_resource = {
+	.start = 0x4000000,
+	.end = 0x5ffffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mtd_ram_device = {
+	.name = "mtd-ram",
+	.id = 0,
+	.dev = {
+		.platform_data = &mtd_ram_data,
+		},
+	.num_resources = 1,
+	.resource = &mtd_ram_resource,
+};
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+static struct resource smsc911x_resources[] = {
+	{
+	 .name = "smsc911x-memory",
+	 .start = 0x28000000,
+	 .end = 0x28000000 + 0xFF,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = IRQ_PF7,
+	 .end = IRQ_PF7,
+	 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	 },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags = SMSC911X_USE_32BIT,
+	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+	.name = "smsc911x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smsc911x_resources),
+	.resource = smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+		},
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+	{
+	 .start = BFIN_UART_THR,
+	 .end = BFIN_UART_GCTL + 2,
+	 .flags = IORESOURCE_MEM,
+	 },
+	{
+	 .start = IRQ_UART_RX,
+	 .end = IRQ_UART_RX + 1,
+	 .flags = IORESOURCE_IRQ,
+	 },
+	{
+	 .start = IRQ_UART_ERROR,
+	 .end = IRQ_UART_ERROR,
+	 .flags = IORESOURCE_IRQ,
+	 },
+	{
+	 .start = CH_UART_TX,
+	 .end = CH_UART_TX,
+	 .flags = IORESOURCE_DMA,
+	 },
+	{
+	 .start = CH_UART_RX,
+	 .end = CH_UART_RX,
+	 .flags = IORESOURCE_DMA,
+	 },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+	P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+	.dev = {
+		/* Passed to driver */
+		.platform_data = &bfin_uart0_peripherals,
+		},
+};
+#endif
+#endif
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+
+#ifdef CONFIG_MTD_PARTITIONS
+const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition bfin_plat_nand_partitions[] = {
+	{
+	 .name = "params(nand)",
+	 .size = 32 * 1024 * 1024,
+	 .offset = 0,
+	 }, {
+	     .name = "userfs(nand)",
+	     .size = MTDPART_SIZ_FULL,
+	     .offset = MTDPART_OFS_APPEND,
+	     },
+};
+#endif
+
+#define BFIN_NAND_PLAT_CLE 2
+#define BFIN_NAND_PLAT_ALE 3
+
+static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+				    unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_CLE));
+	else
+		writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_ALE));
+}
+
+#define BFIN_NAND_PLAT_READY GPIO_PF10
+static int bfin_plat_nand_dev_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(BFIN_NAND_PLAT_READY);
+}
+
+static struct platform_nand_data bfin_plat_nand_data = {
+	.chip = {
+		 .chip_delay = 30,
+#ifdef CONFIG_MTD_PARTITIONS
+		 .part_probe_types = part_probes,
+		 .partitions = bfin_plat_nand_partitions,
+		 .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions),
+#endif
+		 },
+	.ctrl = {
+		 .cmd_ctrl = bfin_plat_nand_cmd_ctrl,
+		 .dev_ready = bfin_plat_nand_dev_ready,
+		 },
+};
+
+#define MAX(x, y) (x > y ? x : y)
+static struct resource bfin_plat_nand_resources = {
+	.start = 0x24000000,
+	.end = 0x24000000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)),
+	.flags = IORESOURCE_IO,
+};
+
+static struct platform_device bfin_async_nand_device = {
+	.name = "gen_nand",
+	.id = -1,
+	.num_resources = 1,
+	.resource = &bfin_plat_nand_resources,
+	.dev = {
+		.platform_data = &bfin_plat_nand_data,
+		},
+};
+
+static void bfin_plat_nand_init(void)
+{
+	gpio_request(BFIN_NAND_PLAT_READY, "bfin_nand_plat");
+}
+#else
+static void bfin_plat_nand_init(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_DATAFLASH) || defined(CONFIG_MTD_DATAFLASH_MODULE)
+static struct mtd_partition bfin_spi_dataflash_partitions[] = {
+	{
+	 .name = "bootloader",
+	 .size = 0x4200,
+	 .offset = 0,
+	 .mask_flags = MTD_CAP_ROM},
+	{
+	 .name = "u-boot",
+	 .size = 0x42000,
+	 .offset = MTDPART_OFS_APPEND,
+	 },
+	{
+	 .name = "u-boot(params)",
+	 .size = 0x4200,
+	 .offset = MTDPART_OFS_APPEND,
+	 },
+	{
+	 .name = "kernel",
+	 .size = 0x294000,
+	 .offset = MTDPART_OFS_APPEND,
+	 },
+	{
+	 .name = "params",
+	 .size = 0x42000,
+	 .offset = MTDPART_OFS_APPEND,
+	 },
+	{
+	 .name = "rootfs",
+	 .size = MTDPART_SIZ_FULL,
+	 .offset = MTDPART_OFS_APPEND,
+	 }
+};
+
+static struct flash_platform_data bfin_spi_dataflash_data = {
+	.name = "SPI Dataflash",
+	.parts = bfin_spi_dataflash_partitions,
+	.nr_parts = ARRAY_SIZE(bfin_spi_dataflash_partitions),
+};
+
+/* DataFlash chip */
+static struct bfin5xx_spi_chip data_flash_chip_info = {
+	.enable_dma = 0,	/* use dma transfer with this chip */
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+	[0] = {
+	       .start = SPI0_REGBASE,
+	       .end = SPI0_REGBASE + 0xFF,
+	       .flags = IORESOURCE_MEM,
+	       },
+	[1] = {
+	       .start = CH_SPI,
+	       .end = CH_SPI,
+	       .flags = IORESOURCE_DMA,
+	       },
+	[2] = {
+	       .start = IRQ_SPI,
+	       .end = IRQ_SPI,
+	       .flags = IORESOURCE_IRQ,
+	       },
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+	.num_chipselect = 8,
+	.enable_dma = 1,	/* master has the ability to do dma transfer */
+	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct platform_device bfin_spi0_device = {
+	.name = "bfin-spi",
+	.id = 0,		/* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
+	.resource = bfin_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_spi0_info,	/* Passed to driver */
+		},
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+	{
+	 .modalias = "spidev",
+	 .max_speed_hz = 3125000,	/* max spi clock (SCK) speed in HZ */
+	 .bus_num = 0,
+	 .chip_select = 3,
+	 .controller_data = &spidev_chip_info,
+	 },
+#endif
+#if defined(CONFIG_MTD_DATAFLASH) || defined(CONFIG_MTD_DATAFLASH_MODULE)
+	{			/* DataFlash chip */
+	 .modalias = "mtd_dataflash",
+	 .max_speed_hz = 33250000,	/* max spi clock (SCK) speed in HZ */
+	 .bus_num = 0,		/* Framework bus number */
+	 .chip_select = 2,	/* Framework chip select */
+	 .platform_data = &bfin_spi_dataflash_data,
+	 .controller_data = &data_flash_chip_info,
+	 .mode = SPI_MODE_3,
+	 },
+#endif
+};
+
+static struct resource bfin_gpios_resources = {
+	.start = 31,
+/*      .end   = MAX_BLACKFIN_GPIOS - 1, */
+	.end = 32,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+	.name = "simple-gpio",
+	.id = -1,
+	.num_resources = 1,
+	.resource = &bfin_gpios_resources,
+};
+
+static const unsigned int cclk_vlev_datasheet[] = {
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 300000000),
+	VRPAIR(VLEV_095, 313000000),
+	VRPAIR(VLEV_100, 350000000),
+	VRPAIR(VLEV_105, 400000000),
+	VRPAIR(VLEV_110, 444000000),
+	VRPAIR(VLEV_115, 450000000),
+	VRPAIR(VLEV_120, 475000000),
+	VRPAIR(VLEV_125, 500000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */ ,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+		},
+};
+
+static struct platform_device *acvilon_devices[] __initdata = {
+	&bfin_dpmc,
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	&bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+
+	&bfin_gpios_device,
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+	&smsc911x_device,
+#endif
+
+	&bfin_i2c_pca_device,
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+	&bfin_async_nand_device,
+#endif
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+	&mtd_ram_device,
+#endif
+
+};
+
+static int __init acvilon_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+
+	bfin_plat_nand_init();
+	ret =
+	    platform_add_devices(acvilon_devices, ARRAY_SIZE(acvilon_devices));
+	if (ret < 0)
+		return ret;
+
+	i2c_register_board_info(0, acvilon_i2c_devs,
+				ARRAY_SIZE(acvilon_i2c_devs));
+
+	bfin_write_FIO0_FLAG_C(1 << 14);
+	msleep(5);
+	bfin_write_FIO0_FLAG_S(1 << 14);
+
+	spi_register_board_info(bfin_spi_board_info,
+				ARRAY_SIZE(bfin_spi_board_info));
+	return 0;
+}
+
+arch_initcall(acvilon_init);
+
+static struct platform_device *acvilon_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+	printk(KERN_INFO "register early platform devices\n");
+	early_platform_add_devices(acvilon_early_devices,
+				   ARRAY_SIZE(acvilon_early_devices));
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/ezkit.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,7 @@ static struct isp1760_platform_data isp1
 };
 
 static struct platform_device bfin_isp1760_device = {
-	.name           = "isp1760-hcd",
+	.name           = "isp1760",
 	.id             = 0,
 	.dev = {
 		.platform_data = &isp1760_priv,
@@ -159,28 +159,6 @@ static struct platform_device smc91x_dev
 };
 #endif
 
-#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE)
-static struct resource ax88180_resources[] = {
-	[0] = {
-		.start	= 0x2c000000,
-		.end	= 0x2c000000 + 0x8000,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PF10,
-		.end	= IRQ_PF10,
-		.flags	= (IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL),
-	},
-};
-
-static struct platform_device ax88180_device = {
-	.name		= "ax88180",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ax88180_resources),
-	.resource	= ax88180_resources,
-};
-#endif
-
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 	{
@@ -421,10 +399,6 @@ static struct platform_device *ezkit_dev
 	&smc91x_device,
 #endif
 
-#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE)
-	&ax88180_device,
-#endif
-
 #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
 	&net2272_bfin_device,
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/Kconfig linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/Kconfig
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -19,4 +19,11 @@ config BFIN561_BLUETECHNIX_CM
 	help
 	  CM-BF561 support for EVAL- and DEV-Board.
 
+config BFIN561_ACVILON
+	bool "BF561-ACVILON"
+	help
+	  BF561-ACVILON System On Module support (SO-DIMM 144).
+	  For more information about Acvilon BF561 SoM
+	  please go to http://www.niistt.ru/
+
 endchoice
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/boards/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/boards/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
 # arch/blackfin/mach-bf561/boards/Makefile
 #
 
+obj-$(CONFIG_BFIN561_ACVILON)          += acvilon.o
 obj-$(CONFIG_BFIN561_BLUETECHNIX_CM)   += cm_bf561.o
 obj-$(CONFIG_BFIN561_EZKIT)            += ezkit.o
 obj-$(CONFIG_BFIN561_TEPLA)            += tepla.o
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/coreb.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/coreb.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/coreb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/coreb.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,8 +22,8 @@
 #define CMD_COREB_STOP		3
 #define CMD_COREB_RESET		4
 
-static int
-coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long
+coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int ret = 0;
 
@@ -49,8 +49,8 @@ coreb_ioctl(struct inode *inode, struct
 }
 
 static const struct file_operations coreb_fops = {
-	.owner   = THIS_MODULE,
-	.ioctl   = coreb_ioctl,
+	.owner          = THIS_MODULE,
+	.unlocked_ioctl = coreb_ioctl,
 };
 
 static struct miscdevice coreb_dev = {
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/include/mach/defBF561.h linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/defBF561.h
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/include/mach/defBF561.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/include/mach/defBF561.h	2010-02-24 13:52:17.000000000 -0500
@@ -884,65 +884,11 @@
 /* System MMR Register Bits */
 /******************************************************************************* */
 
-/* ********************* PLL AND RESET MASKS ************************ */
-
-/* PLL_CTL Masks */
-#define PLL_CLKIN              0x00000000	/* Pass CLKIN to PLL */
-#define PLL_CLKIN_DIV2         0x00000001	/* Pass CLKIN/2 to PLL */
-#define PLL_OFF                0x00000002	/* Shut off PLL clocks */
-#define STOPCK_OFF             0x00000008	/* Core clock off */
-#define PDWN                   0x00000020	/* Put the PLL in a Deep Sleep state */
-#define BYPASS                 0x00000100	/* Bypass the PLL */
-
 /* CHIPID Masks */
 #define CHIPID_VERSION         0xF0000000
 #define CHIPID_FAMILY          0x0FFFF000
 #define CHIPID_MANUFACTURE     0x00000FFE
 
-/* VR_CTL Masks																	*/
-#define	FREQ			0x0003	/* Switching Oscillator Frequency For Regulator	*/
-#define	HIBERNATE		0x0000	/* Powerdown/Bypass On-Board Regulation	*/
-#define	FREQ_333		0x0001	/* Switching Frequency Is 333 kHz */
-#define	FREQ_667		0x0002	/* Switching Frequency Is 667 kHz */
-#define	FREQ_1000		0x0003	/* Switching Frequency Is 1 MHz */
-
-#define	GAIN			0x000C	/* Voltage Level Gain	*/
-#define	GAIN_5			0x0000	/* GAIN = 5*/
-#define	GAIN_10			0x0004	/* GAIN = 1*/
-#define	GAIN_20			0x0008	/* GAIN = 2*/
-#define	GAIN_50			0x000C	/* GAIN = 5*/
-
-#define	VLEV			0x00F0	/* Internal Voltage Level */
-#define	VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
-#define	VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
-#define	VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
-#define	VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
-#define	VLEV_105		0x00A0	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
-#define	VLEV_110		0x00B0	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
-#define	VLEV_115		0x00C0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
-#define	VLEV_120		0x00D0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
-#define	VLEV_125		0x00E0	/* VLEV = 1.25 V (-5% - +10% Accuracy) */
-#define	VLEV_130		0x00F0	/* VLEV = 1.30 V (-5% - +10% Accuracy) */
-
-#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate */
-#define	SCKELOW			0x8000	/* Do Not Drive SCKE High During Reset After Hibernate */
-
-/* PLL_DIV Masks */
-#define SCLK_DIV(x)  (x)	/* SCLK = VCO / x */
-
-#define CSEL			0x30		/* Core Select */
-#define SSEL			0xf		/* System Select */
-#define CCLK_DIV1              0x00000000	/* CCLK = VCO / 1 */
-#define CCLK_DIV2              0x00000010	/* CCLK = VCO / 2 */
-#define CCLK_DIV4              0x00000020	/* CCLK = VCO / 4 */
-#define CCLK_DIV8              0x00000030	/* CCLK = VCO / 8 */
-
-/* PLL_STAT Masks																	*/
-#define ACTIVE_PLLENABLED	0x0001	/* Processor In Active Mode With PLL Enabled    */
-#define	FULL_ON				0x0002	/* Processor In Full On Mode                                    */
-#define ACTIVE_PLLDISABLED	0x0004	/* Processor In Active Mode With PLL Disabled   */
-#define	PLL_LOCKED			0x0020	/* PLL_LOCKCNT Has Been Reached                                 */
-
 /* SICA_SYSCR Masks */
 #define COREB_SRAM_INIT		0x0020
 
@@ -1150,53 +1096,6 @@
 
 /* **********  DMA CONTROLLER MASKS  *********************8 */
 
-/* DMAx_CONFIG, MDMA_yy_CONFIG, IMDMA_yy_CONFIG Masks */
-#define DMAEN	        0x00000001	/* Channel Enable */
-#define WNR	   	0x00000002	/* Channel Direction (W/R*) */
-#define WDSIZE_8	0x00000000	/* Word Size 8 bits */
-#define WDSIZE_16	0x00000004	/* Word Size 16 bits */
-#define WDSIZE_32	0x00000008	/* Word Size 32 bits */
-#define DMA2D	        0x00000010	/* 2D/1D* Mode */
-#define RESTART         0x00000020	/* Restart */
-#define DI_SEL	        0x00000040	/* Data Interrupt Select */
-#define DI_EN	        0x00000080	/* Data Interrupt Enable */
-#define NDSIZE_0		0x0000	/* Next Descriptor Size = 0 (Stop/Autobuffer)   */
-#define NDSIZE_1		0x0100	/* Next Descriptor Size = 1                                             */
-#define NDSIZE_2		0x0200	/* Next Descriptor Size = 2                                             */
-#define NDSIZE_3		0x0300	/* Next Descriptor Size = 3                                             */
-#define NDSIZE_4		0x0400	/* Next Descriptor Size = 4                                             */
-#define NDSIZE_5		0x0500	/* Next Descriptor Size = 5                                             */
-#define NDSIZE_6		0x0600	/* Next Descriptor Size = 6                                             */
-#define NDSIZE_7		0x0700	/* Next Descriptor Size = 7                                             */
-#define NDSIZE_8		0x0800	/* Next Descriptor Size = 8                                             */
-#define NDSIZE_9		0x0900	/* Next Descriptor Size = 9                                             */
-#define NDSIZE	        0x00000900	/* Next Descriptor Size */
-#define DMAFLOW	        0x00007000	/* Flow Control */
-#define DMAFLOW_STOP		0x0000	/* Stop Mode */
-#define DMAFLOW_AUTO		0x1000	/* Autobuffer Mode */
-#define DMAFLOW_ARRAY		0x4000	/* Descriptor Array Mode */
-#define DMAFLOW_SMALL		0x6000	/* Small Model Descriptor List Mode */
-#define DMAFLOW_LARGE		0x7000	/* Large Model Descriptor List Mode */
-
-#define DMAEN_P	            	0	/* Channel Enable */
-#define WNR_P	            	1	/* Channel Direction (W/R*) */
-#define DMA2D_P	        	4	/* 2D/1D* Mode */
-#define RESTART_P	      	5	/* Restart */
-#define DI_SEL_P	     	6	/* Data Interrupt Select */
-#define DI_EN_P	            	7	/* Data Interrupt Enable */
-
-/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS, IMDMA_yy_IRQ_STATUS Masks */
-
-#define DMA_DONE		0x00000001	/* DMA Done Indicator */
-#define DMA_ERR	        	0x00000002	/* DMA Error Indicator */
-#define DFETCH	            	0x00000004	/* Descriptor Fetch Indicator */
-#define DMA_RUN	            	0x00000008	/* DMA Running Indicator */
-
-#define DMA_DONE_P	    	0	/* DMA Done Indicator */
-#define DMA_ERR_P     		1	/* DMA Error Indicator */
-#define DFETCH_P     		2	/* Descriptor Fetch Indicator */
-#define DMA_RUN_P     		3	/* DMA Running Indicator */
-
 /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP, IMDMA_yy_PERIPHERAL_MAP Masks */
 
 #define CTYPE	            0x00000040	/* DMA Channel Type Indicator */
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/smp.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/smp.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-bf561/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-bf561/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,8 +52,6 @@ int __init setup_profiling_timer(unsigne
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
 {
-	local_irq_disable();
-
 	/* Clone setup for peripheral interrupt sources from CoreA. */
 	bfin_write_SICB_IMASK0(bfin_read_SICA_IMASK0());
 	bfin_write_SICB_IMASK1(bfin_read_SICA_IMASK1());
@@ -70,11 +68,6 @@ void __cpuinit platform_secondary_init(u
 	bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
 	SSYNC();
 
-	local_irq_enable();
-
-	/* Calibrate loops per jiffy value. */
-	calibrate_delay();
-
 	/* Store CPU-private information to the cpu_data array. */
 	bfin_setup_cpudata(cpu);
 
@@ -108,9 +101,13 @@ int __cpuinit platform_boot_secondary(un
 		barrier();
 	}
 
-	spin_unlock(&boot_lock);
-
-	return cpu_isset(cpu, cpu_callin_map) ? 0 : -ENOSYS;
+	if (cpu_isset(cpu, cpu_callin_map)) {
+		cpu_set(cpu, cpu_online_map);
+		/* release the lock and let coreb run */
+		spin_unlock(&boot_lock);
+		return 0;
+	} else
+		panic("CPU%u: processor failed to boot\n", cpu);
 }
 
 void __init platform_request_ipi(irq_handler_t handler)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/clocks-init.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/clocks-init.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/clocks-init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/clocks-init.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <asm/dma.h>
 #include <asm/clocks.h>
 #include <asm/mem_init.h>
+#include <asm/dpmc.h>
 
 #define SDGCTL_WIDTH (1 << 31)	/* SDRAM external data path width */
 #define PLL_CTL_VAL \
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/cpufreq.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/cpufreq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,7 @@
 #include <linux/fs.h>
 #include <asm/blackfin.h>
 #include <asm/time.h>
-
+#include <asm/dpmc.h>
 
 /* this is the table of CCLK frequencies, in Hz */
 /* .index is the entry in the auxillary dpm_state_table[] */
@@ -138,7 +138,8 @@ static int __init __bfin_cpu_init(struct
 						 dpm_state_table[index].tscale);
 	}
 
-	policy->cpuinfo.transition_latency = (bfin_read_PLL_LOCKCNT() / (sclk / 1000000)) * 1000;
+	policy->cpuinfo.transition_latency = 50000; /* 50us assumed */
+
 	/*Now ,only support one cpu */
 	policy->cur = cclk;
 	cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu);
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/dpmc_modes.S linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/dpmc_modes.S
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/dpmc_modes.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/dpmc_modes.S	2010-02-24 13:52:17.000000000 -0500
@@ -404,6 +404,21 @@ ENTRY(_do_hibernate)
 	PM_SYS_PUSH(EBIU_FCTL)
 #endif
 
+#ifdef PORTCIO_FER
+	PM_SYS_PUSH16(PORTCIO_DIR)
+	PM_SYS_PUSH16(PORTCIO_INEN)
+	PM_SYS_PUSH16(PORTCIO)
+	PM_SYS_PUSH16(PORTCIO_FER)
+	PM_SYS_PUSH16(PORTDIO_DIR)
+	PM_SYS_PUSH16(PORTDIO_INEN)
+	PM_SYS_PUSH16(PORTDIO)
+	PM_SYS_PUSH16(PORTDIO_FER)
+	PM_SYS_PUSH16(PORTEIO_DIR)
+	PM_SYS_PUSH16(PORTEIO_INEN)
+	PM_SYS_PUSH16(PORTEIO)
+	PM_SYS_PUSH16(PORTEIO_FER)
+#endif
+
 	PM_SYS_PUSH16(SYSCR)
 
 	/* Save Core MMRs */
@@ -716,6 +731,21 @@ ENTRY(_do_hibernate)
 	P0.L = lo(PLL_CTL);
 	PM_SYS_POP16(SYSCR)
 
+#ifdef PORTCIO_FER
+	PM_SYS_POP16(PORTEIO_FER)
+	PM_SYS_POP16(PORTEIO)
+	PM_SYS_POP16(PORTEIO_INEN)
+	PM_SYS_POP16(PORTEIO_DIR)
+	PM_SYS_POP16(PORTDIO_FER)
+	PM_SYS_POP16(PORTDIO)
+	PM_SYS_POP16(PORTDIO_INEN)
+	PM_SYS_POP16(PORTDIO_DIR)
+	PM_SYS_POP16(PORTCIO_FER)
+	PM_SYS_POP16(PORTCIO)
+	PM_SYS_POP16(PORTCIO_INEN)
+	PM_SYS_POP16(PORTCIO_DIR)
+#endif
+
 #ifdef EBIU_FCTL
 	PM_SYS_POP(EBIU_FCTL)
 	PM_SYS_POP(EBIU_MODE)
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/entry.S linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/entry.S
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -713,6 +713,8 @@ ENTRY(_system_call)
 	cc = BITTST(r7, TIF_RESTORE_SIGMASK);
 	if cc jump .Lsyscall_do_signals;
 	cc = BITTST(r7, TIF_SIGPENDING);
+	if cc jump .Lsyscall_do_signals;
+	cc = BITTST(r7, TIF_NOTIFY_RESUME);
 	if !cc jump .Lsyscall_really_exit;
 .Lsyscall_do_signals:
 	/* Reenable interrupts.  */
@@ -721,7 +723,7 @@ ENTRY(_system_call)
 
 	r0 = sp;
 	SP += -12;
-	call _do_signal;
+	call _do_notify_resume;
 	SP += 12;
 
 .Lsyscall_really_exit:
@@ -1422,7 +1424,7 @@ ENTRY(_sys_call_table)
 	.long _sys_ni_syscall	/* streams2 */
 	.long _sys_vfork		/* 190 */
 	.long _sys_getrlimit
-	.long _sys_mmap2
+	.long _sys_mmap_pgoff
 	.long _sys_truncate64
 	.long _sys_ftruncate64
 	.long _sys_stat64	/* 195 */
@@ -1600,6 +1602,7 @@ ENTRY(_sys_call_table)
 	.long _sys_pwritev
 	.long _sys_rt_tgsigqueueinfo
 	.long _sys_perf_event_open
+	.long _sys_recvmmsg		/* 370 */
 
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/ints-priority.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/ints-priority.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/ints-priority.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/ints-priority.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,11 +25,20 @@
 #include <asm/blackfin.h>
 #include <asm/gpio.h>
 #include <asm/irq_handler.h>
+#include <asm/dpmc.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/bfin_sport.h>
 
 #define SIC_SYSIRQ(irq)	(irq - (IRQ_CORETMR + 1))
 
 #ifdef BF537_FAMILY
 # define BF537_GENERIC_ERROR_INT_DEMUX
+# define SPI_ERR_MASK   (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE)	/* SPI_STAT */
+# define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF)	/* SPORT_STAT */
+# define PPI_ERR_MASK   (0xFFFF & ~FLD)	/* PPI_STATUS */
+# define EMAC_ERR_MASK  (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE)	/* EMAC_SYSTAT */
+# define UART_ERR_MASK  (0x6)	/* UART_IIR */
+# define CAN_ERR_MASK   (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF)	/* CAN_GIF */
 #else
 # undef BF537_GENERIC_ERROR_INT_DEMUX
 #endif
@@ -324,11 +333,9 @@ static void bfin_demux_error_irq(unsigne
 		irq = IRQ_CAN_ERROR;
 	else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
 		irq = IRQ_SPI_ERROR;
-	else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) &&
-		 (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0))
+	else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
 		irq = IRQ_UART0_ERROR;
-	else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) &&
-		 (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0))
+	else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
 		irq = IRQ_UART1_ERROR;
 
 	if (irq) {
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/smp.c linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/smp.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mach-common/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mach-common/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -336,13 +336,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 	ret = platform_boot_secondary(cpu, idle);
 
-	if (ret) {
-		cpu_clear(cpu, cpu_present_map);
-		printk(KERN_CRIT "CPU%u: processor failed to boot (%d)\n", cpu, ret);
-		free_task(idle);
-	} else
-		cpu_set(cpu, cpu_online_map);
-
 	secondary_stack = NULL;
 
 	return ret;
@@ -418,9 +411,16 @@ void __cpuinit secondary_start_kernel(vo
 
 	setup_secondary(cpu);
 
+	platform_secondary_init(cpu);
+
 	local_irq_enable();
 
-	platform_secondary_init(cpu);
+	/*
+	 * Calibrate loops per jiffy value.
+	 * IRQs need to be enabled here - D-cache can be invalidated
+	 * in timer irq handler, so core B can read correct jiffies.
+	 */
+	calibrate_delay();
 
 	cpu_idle();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@ GZFLAGS          := -9
 KBUILD_CFLAGS           += $(call cc-option,-mno-fdpic)
 KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
 CFLAGS_MODULE    += -mlong-calls
+LDFLAGS_MODULE   += -m elf32bfin
 KALLSYMS         += --symbol-prefix=_
 
 KBUILD_DEFCONFIG := BF537-STAMP_defconfig
@@ -137,7 +138,7 @@ archclean:
 
 INSTALL_PATH ?= /tftpboot
 boot := arch/$(ARCH)/boot
-BOOT_TARGETS = vmImage vmImage.bz2 vmImage.gz vmImage.lzma
+BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
 PHONY += $(BOOT_TARGETS) install
 KBUILD_IMAGE := $(boot)/vmImage
 
@@ -151,6 +152,7 @@ install:
 
 define archhelp
   echo  '* vmImage         - Alias to selected kernel format (vmImage.gz by default)'
+  echo  '  vmImage.bin     - Uncompressed Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bin)'
   echo  '  vmImage.bz2     - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
   echo  '* vmImage.gz      - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
   echo  '  vmImage.lzma    - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mm/maccess.c linux-libre-2.6.33-gnu1/arch/blackfin/mm/maccess.c
--- linux-libre-2.6.32-gnu1/arch/blackfin/mm/maccess.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mm/maccess.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,97 @@
+/*
+ * safe read and write memory routines callable while atomic
+ *
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/uaccess.h>
+#include <asm/dma.h>
+
+static int validate_memory_access_address(unsigned long addr, int size)
+{
+	if (size < 0 || addr == 0)
+		return -EFAULT;
+	return bfin_mem_access_type(addr, size);
+}
+
+long probe_kernel_read(void *dst, void *src, size_t size)
+{
+	unsigned long lsrc = (unsigned long)src;
+	int mem_type;
+
+	mem_type = validate_memory_access_address(lsrc, size);
+	if (mem_type < 0)
+		return mem_type;
+
+	if (lsrc >= SYSMMR_BASE) {
+		if (size == 2 && lsrc % 2 == 0) {
+			u16 mmr = bfin_read16(src);
+			memcpy(dst, &mmr, sizeof(mmr));
+			return 0;
+		} else if (size == 4 && lsrc % 4 == 0) {
+			u32 mmr = bfin_read32(src);
+			memcpy(dst, &mmr, sizeof(mmr));
+			return 0;
+		}
+	} else {
+		switch (mem_type) {
+		case BFIN_MEM_ACCESS_CORE:
+		case BFIN_MEM_ACCESS_CORE_ONLY:
+			return __probe_kernel_read(dst, src, size);
+			/* XXX: should support IDMA here with SMP */
+		case BFIN_MEM_ACCESS_DMA:
+			if (dma_memcpy(dst, src, size))
+				return 0;
+			break;
+		case BFIN_MEM_ACCESS_ITEST:
+			if (isram_memcpy(dst, src, size))
+				return 0;
+			break;
+		}
+	}
+
+	return -EFAULT;
+}
+
+long probe_kernel_write(void *dst, void *src, size_t size)
+{
+	unsigned long ldst = (unsigned long)dst;
+	int mem_type;
+
+	mem_type = validate_memory_access_address(ldst, size);
+	if (mem_type < 0)
+		return mem_type;
+
+	if (ldst >= SYSMMR_BASE) {
+		if (size == 2 && ldst % 2 == 0) {
+			u16 mmr;
+			memcpy(&mmr, src, sizeof(mmr));
+			bfin_write16(dst, mmr);
+			return 0;
+		} else if (size == 4 && ldst % 4 == 0) {
+			u32 mmr;
+			memcpy(&mmr, src, sizeof(mmr));
+			bfin_write32(dst, mmr);
+			return 0;
+		}
+	} else {
+		switch (mem_type) {
+		case BFIN_MEM_ACCESS_CORE:
+		case BFIN_MEM_ACCESS_CORE_ONLY:
+			return __probe_kernel_write(dst, src, size);
+			/* XXX: should support IDMA here with SMP */
+		case BFIN_MEM_ACCESS_DMA:
+			if (dma_memcpy(dst, src, size))
+				return 0;
+			break;
+		case BFIN_MEM_ACCESS_ITEST:
+			if (isram_memcpy(dst, src, size))
+				return 0;
+			break;
+		}
+	}
+
+	return -EFAULT;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/blackfin/mm/Makefile linux-libre-2.6.33-gnu1/arch/blackfin/mm/Makefile
--- linux-libre-2.6.32-gnu1/arch/blackfin/mm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/blackfin/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,4 +2,4 @@
 # arch/blackfin/mm/Makefile
 #
 
-obj-y := sram-alloc.o isram-driver.o init.o
+obj-y := sram-alloc.o isram-driver.o init.o maccess.o
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/arch-v10/mm/fault.c linux-libre-2.6.33-gnu1/arch/cris/arch-v10/mm/fault.c
--- linux-libre-2.6.32-gnu1/arch/cris/arch-v10/mm/fault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/arch-v10/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
@@ -80,8 +80,7 @@ handle_mmu_bus_fault(struct pt_regs *reg
 	 * do_page_fault may have flushed the TLB so we have to restore
 	 * the MMU registers.
 	 */
-	local_save_flags(flags);
-	local_irq_disable();
+	local_irq_save(flags);
 	pmd = (pmd_t *)(pgd + pgd_index(address));
 	if (pmd_none(*pmd))
 		goto exit;
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/arch-v10/mm/tlb.c linux-libre-2.6.33-gnu1/arch/cris/arch-v10/mm/tlb.c
--- linux-libre-2.6.32-gnu1/arch/cris/arch-v10/mm/tlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/arch-v10/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,28 +134,6 @@ void flush_tlb_page(struct vm_area_struc
 	local_irq_restore(flags);
 }
 
-/* dump the entire TLB for debug purposes */
-
-#if 0
-void
-dump_tlb_all(void)
-{
-	int i;
-	unsigned long flags;
-
-	printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we  |\n");
-
-	local_save_flags(flags);
-	local_irq_disable();
-	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
-		*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
-		printk("Entry %d: HI 0x%08lx, LO 0x%08lx\n",
-		       i, *R_TLB_HI, *R_TLB_LO);
-	}
-	local_irq_restore(flags);
-}
-#endif
-
 /*
  * Initialize the context related info for a new mm_struct
  * instance.
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/arch-v32/kernel/head.S linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/head.S
--- linux-libre-2.6.32-gnu1/arch/cris/arch-v32/kernel/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/arch-v32/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@
  * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so
  * -traditional must not be used when assembling this file.
  */
-#include <linux/autoconf.h>
 #include <arch/memmap.h>
 #include <hwregs/reg_rdwr.h>
 #include <hwregs/intr_vect.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/include/arch-v32/arch/spinlock.h linux-libre-2.6.33-gnu1/arch/cris/include/arch-v32/arch/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/cris/include/arch-v32/arch/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/include/arch-v32/arch/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,12 +9,12 @@ extern void cris_spin_unlock(void *l, in
 extern void cris_spin_lock(void *l);
 extern int cris_spin_trylock(void *l);
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *x)
+static inline int arch_spin_is_locked(arch_spinlock_t *x)
 {
 	return *(volatile signed char *)(&(x)->slock) <= 0;
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__asm__ volatile ("move.d %1,%0" \
 			  : "=m" (lock->slock) \
@@ -22,26 +22,26 @@ static inline void __raw_spin_unlock(raw
 			  : "memory");
 }
 
-static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
-	while (__raw_spin_is_locked(lock))
+	while (arch_spin_is_locked(lock))
 		cpu_relax();
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	return cris_spin_trylock((void *)&lock->slock);
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	cris_spin_lock((void *)&lock->slock);
 }
 
 static inline void
-__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 {
-	__raw_spin_lock(lock);
+	arch_spin_lock(lock);
 }
 
 /*
@@ -56,76 +56,76 @@ __raw_spin_lock_flags(raw_spinlock_t *lo
  *
  */
 
-static inline int __raw_read_can_lock(raw_rwlock_t *x)
+static inline int arch_read_can_lock(arch_rwlock_t *x)
 {
 	return (int)(x)->lock > 0;
 }
 
-static inline int __raw_write_can_lock(raw_rwlock_t *x)
+static inline int arch_write_can_lock(arch_rwlock_t *x)
 {
 	return (x)->lock == RW_LOCK_BIAS;
 }
 
-static  inline void __raw_read_lock(raw_rwlock_t *rw)
+static  inline void arch_read_lock(arch_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	while (rw->lock == 0);
 	rw->lock--;
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 }
 
-static  inline void __raw_write_lock(raw_rwlock_t *rw)
+static  inline void arch_write_lock(arch_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	while (rw->lock != RW_LOCK_BIAS);
 	rw->lock = 0;
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 }
 
-static  inline void __raw_read_unlock(raw_rwlock_t *rw)
+static  inline void arch_read_unlock(arch_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	rw->lock++;
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 }
 
-static  inline void __raw_write_unlock(raw_rwlock_t *rw)
+static  inline void arch_write_unlock(arch_rwlock_t *rw)
 {
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	while (rw->lock != RW_LOCK_BIAS);
 	rw->lock = RW_LOCK_BIAS;
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 }
 
-static  inline int __raw_read_trylock(raw_rwlock_t *rw)
+static  inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	if (rw->lock != 0) {
 		rw->lock--;
 		ret = 1;
 	}
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 	return ret;
 }
 
-static  inline int __raw_write_trylock(raw_rwlock_t *rw)
+static  inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
-	__raw_spin_lock(&rw->slock);
+	arch_spin_lock(&rw->slock);
 	if (rw->lock == RW_LOCK_BIAS) {
 		rw->lock = 0;
 		ret = 1;
 	}
-	__raw_spin_unlock(&rw->slock);
+	arch_spin_unlock(&rw->slock);
 	return 1;
 }
 
 #define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock)
 #define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* __ASM_ARCH_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/cris/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/cris/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/cris/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/cris/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/cris/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/cris/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,8 +64,6 @@ typedef unsigned long elf_fpregset_t;
 #define EF_CRIS_VARIANT_COMMON_V10_V32	0x00000004
 /* End of excerpt from {binutils}/include/elf/cris.h.  */
 
-#define USE_ELF_CORE_DUMP
-
 #define ELF_EXEC_PAGESIZE	8192
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/cris/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/cris/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,8 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/kernel/asm-offsets.c linux-libre-2.6.33-gnu1/arch/cris/kernel/asm-offsets.c
--- linux-libre-2.6.32-gnu1/arch/cris/kernel/asm-offsets.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
 #include <linux/sched.h>
 #include <asm/thread_info.h>
-#include <linux/autoconf.h>
 
 /*
  * Generate definitions needed by assembly language modules.
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/kernel/irq.c linux-libre-2.6.33-gnu1/arch/cris/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/cris/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -71,7 +71,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/kernel/sys_cris.c linux-libre-2.6.33-gnu1/arch/cris/kernel/sys_cris.c
--- linux-libre-2.6.32-gnu1/arch/cris/kernel/sys_cris.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/kernel/sys_cris.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,31 +26,6 @@
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 
-/* common code for old and new mmaps */
-static inline long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-        unsigned long flags, unsigned long fd, unsigned long pgoff)
-{
-        int error = -EBADF;
-        struct file * file = NULL;
-
-        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-        if (!(flags & MAP_ANONYMOUS)) {
-                file = fget(fd);
-                if (!file)
-                        goto out;
-        }
-
-        down_write(&current->mm->mmap_sem);
-        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-        up_write(&current->mm->mmap_sem);
-
-        if (file)
-                fput(file);
-out:
-        return error;
-}
-
 asmlinkage unsigned long old_mmap(unsigned long __user *args)
 {        
 	unsigned long buffer[6];
@@ -63,7 +38,7 @@ asmlinkage unsigned long old_mmap(unsign
 	if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
 		goto out;
 
-	err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
+	err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
                        buffer[4], buffer[5] >> PAGE_SHIFT);
 out:
 	return err;
@@ -73,7 +48,8 @@ asmlinkage long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
-        return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	/* bug(?): 8Kb pages here */
+        return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/cris/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/cris/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,6 @@
  * the kernel has booted.
  */
 
-#include <linux/autoconf.h>
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/page.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/cris/mm/fault.c linux-libre-2.6.33-gnu1/arch/cris/mm/fault.c
--- linux-libre-2.6.32-gnu1/arch/cris/mm/fault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/cris/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,7 +209,7 @@ do_page_fault(unsigned long address, str
 	/* Are we prepared to handle this kernel fault?
 	 *
 	 * (The kernel has valid exception-points in the source
-	 *  when it acesses user-memory. When it fails in one
+	 *  when it accesses user-memory. When it fails in one
 	 *  of those points, we find it in a table and do a jump
 	 *  to some fixup code that loads an appropriate error
 	 *  code)
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/frv/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/frv/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/frv/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/frv/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,7 @@ static inline void __flush_cache_all(voi
 }
 
 /* dcache/icache coherency... */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #ifdef CONFIG_MMU
 extern void flush_dcache_page(struct page *page);
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/frv/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/frv/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -115,7 +115,6 @@ do {											\
 	__kernel_frame0_ptr->gr29	= 0;						\
 } while(0)
 
-#define USE_ELF_CORE_DUMP
 #define CORE_DUMP_USE_REGSET
 #define ELF_FDPIC_CORE_EFLAGS	EF_FRV_FDPIC
 #define ELF_EXEC_PAGESIZE	16384
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/include/asm/page.h linux-libre-2.6.33-gnu1/arch/frv/include/asm/page.h
--- linux-libre-2.6.32-gnu1/arch/frv/include/asm/page.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,12 +63,10 @@ extern unsigned long max_pfn;
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
 
-#ifdef CONFIG_MMU
 #define VM_DATA_DEFAULT_FLAGS \
 	(VM_READ | VM_WRITE | \
 	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#endif
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/frv/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/frv/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,5 +60,7 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/irq.c linux-libre-2.6.33-gnu1/arch/frv/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (action) {
 			seq_printf(p, "%3d: ", i);
@@ -85,7 +85,7 @@ int show_interrupts(struct seq_file *p,
 			seq_putc(p, '\n');
 		}
 
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/pm.c linux-libre-2.6.33-gnu1/arch/frv/kernel/pm.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,37 +211,6 @@ static int cmode_procctl(ctl_table *ctl,
 	return try_set_cmode(new_cmode)?:*lenp;
 }
 
-static int cmode_sysctl(ctl_table *table,
-			void __user *oldval, size_t __user *oldlenp,
-			void __user *newval, size_t newlen)
-{
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(int))
-			return -EINVAL;
-
-		if (put_user(clock_cmode_current, (unsigned __user *)oldval) ||
-		    put_user(sizeof(int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		int new_cmode;
-
-		if (newlen != sizeof(int))
-			return -EINVAL;
-
-		if (get_user(new_cmode, (int __user *)newval))
-			return -EFAULT;
-
-		return try_set_cmode(new_cmode)?:1;
-	}
-	return 1;
-}
-
 static int try_set_p0(int new_p0)
 {
 	unsigned long flags, clkc;
@@ -314,37 +283,6 @@ static int p0_procctl(ctl_table *ctl, in
 	return try_set_p0(new_p0)?:*lenp;
 }
 
-static int p0_sysctl(ctl_table *table,
-		     void __user *oldval, size_t __user *oldlenp,
-		     void __user *newval, size_t newlen)
-{
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(int))
-			return -EINVAL;
-
-		if (put_user(clock_p0_current, (unsigned __user *)oldval) ||
-		    put_user(sizeof(int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		int new_p0;
-
-		if (newlen != sizeof(int))
-			return -EINVAL;
-
-		if (get_user(new_p0, (int __user *)newval))
-			return -EFAULT;
-
-		return try_set_p0(new_p0)?:1;
-	}
-	return 1;
-}
-
 static int cm_procctl(ctl_table *ctl, int write,
 		      void __user *buffer, size_t *lenp, loff_t *fpos)
 {
@@ -358,87 +296,47 @@ static int cm_procctl(ctl_table *ctl, in
 	return try_set_cm(new_cm)?:*lenp;
 }
 
-static int cm_sysctl(ctl_table *table,
-		     void __user *oldval, size_t __user *oldlenp,
-		     void __user *newval, size_t newlen)
-{
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(int))
-			return -EINVAL;
-
-		if (put_user(clock_cm_current, (unsigned __user *)oldval) ||
-		    put_user(sizeof(int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		int new_cm;
-
-		if (newlen != sizeof(int))
-			return -EINVAL;
-
-		if (get_user(new_cm, (int __user *)newval))
-			return -EFAULT;
-
-		return try_set_cm(new_cm)?:1;
-	}
-	return 1;
-}
-
-
 static struct ctl_table pm_table[] =
 {
 	{
-		.ctl_name	= CTL_PM_SUSPEND,
 		.procname	= "suspend",
 		.data		= NULL,
 		.maxlen		= 0,
 		.mode		= 0200,
-		.proc_handler	= &sysctl_pm_do_suspend,
+		.proc_handler	= sysctl_pm_do_suspend,
 	},
 	{
-		.ctl_name	= CTL_PM_CMODE,
 		.procname	= "cmode",
 		.data		= &clock_cmode_current,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cmode_procctl,
-		.strategy	= &cmode_sysctl,
+		.proc_handler	= cmode_procctl,
 	},
 	{
-		.ctl_name	= CTL_PM_P0,
 		.procname	= "p0",
 		.data		= &clock_p0_current,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &p0_procctl,
-		.strategy	= &p0_sysctl,
+		.proc_handler	= p0_procctl,
 	},
 	{
-		.ctl_name	= CTL_PM_CM,
 		.procname	= "cm",
 		.data		= &clock_cm_current,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cm_procctl,
-		.strategy	= &cm_sysctl,
+		.proc_handler	= cm_procctl,
 	},
-	{ .ctl_name = 0}
+	{ }
 };
 
 static struct ctl_table pm_dir_table[] =
 {
 	{
-		.ctl_name	= CTL_PM,
 		.procname	= "pm",
 		.mode		= 0555,
 		.child		= pm_table,
 	},
-	{ .ctl_name = 0}
+	{ }
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/process.c linux-libre-2.6.33-gnu1/arch/frv/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -255,15 +255,12 @@ asmlinkage int sys_execve(char __user *n
 	int error;
 	char * filename;
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, __frame);
 	putname(filename);
- out:
-	unlock_kernel();
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/setup.c linux-libre-2.6.33-gnu1/arch/frv/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/sysctl.c linux-libre-2.6.33-gnu1/arch/frv/kernel/sysctl.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/sysctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/sysctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -176,21 +176,19 @@ static int procctl_frv_pin_cxnr(ctl_tabl
 static struct ctl_table frv_table[] =
 {
 	{
-		.ctl_name 	= 1,
 		.procname 	= "cache-mode",
 		.data		= NULL,
 		.maxlen		= 0,
 		.mode		= 0644,
-		.proc_handler	= &procctl_frv_cachemode,
+		.proc_handler	= procctl_frv_cachemode,
 	},
 #ifdef CONFIG_MMU
 	{
-		.ctl_name	= 2,
 		.procname	= "pin-cxnr",
 		.data		= NULL,
 		.maxlen		= 0,
 		.mode		= 0644,
-		.proc_handler	= &procctl_frv_pin_cxnr
+		.proc_handler	= procctl_frv_pin_cxnr
 	},
 #endif
 	{}
@@ -203,7 +201,6 @@ static struct ctl_table frv_table[] =
 static struct ctl_table frv_dir_table[] =
 {
 	{
-		.ctl_name	= CTL_FRV,
 		.procname	= "frv",
 		.mode 		= 0555,
 		.child		= frv_table
diff -druNp linux-libre-2.6.32-gnu1/arch/frv/kernel/sys_frv.c linux-libre-2.6.33-gnu1/arch/frv/kernel/sys_frv.c
--- linux-libre-2.6.32-gnu1/arch/frv/kernel/sys_frv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/frv/kernel/sys_frv.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,9 +31,6 @@ asmlinkage long sys_mmap2(unsigned long
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
-	struct file * file = NULL;
-
 	/* As with sparc32, make sure the shift for mmap2 is constant
 	   (12), no matter what PAGE_SIZE we have.... */
 
@@ -41,69 +38,10 @@ asmlinkage long sys_mmap2(unsigned long
 	   trying to map something we can't */
 	if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
 		return -EINVAL;
-	pgoff >>= PAGE_SHIFT - 12;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
-#if 0 /* DAVIDM - do we want this */
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
 
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return error;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
-#endif
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/h8300/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/h8300/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/h8300/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/h8300/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #define	flush_cache_dup_mm(mm)		do { } while (0)
 #define	flush_cache_range(vma,a,b)
 #define	flush_cache_page(vma,p,pfn)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define	flush_dcache_page(page)
 #define	flush_dcache_mmap_lock(mapping)
 #define	flush_dcache_mmap_unlock(mapping)
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/h8300/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/h8300/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,6 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLAT_INIT(_r)	_r->er1 = 0
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/include/asm/module.h linux-libre-2.6.33-gnu1/arch/h8300/include/asm/module.h
--- linux-libre-2.6.32-gnu1/arch/h8300/include/asm/module.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/include/asm/module.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,4 @@ struct mod_arch_specific { };
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
 
-#define MODULE_SYMBOL_PREFIX "_"
-
 #endif /* _ASM_H8/300_MODULE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/h8300/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/h8300/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/Kconfig linux-libre-2.6.33-gnu1/arch/h8300/Kconfig
--- linux-libre-2.6.32-gnu1/arch/h8300/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,10 @@ config H8300
 	default y
 	select HAVE_IDE
 
+config SYMBOL_PREFIX
+	string
+	default "_"
+
 config MMU
 	bool
 	default n
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/kernel/irq.c linux-libre-2.6.33-gnu1/arch/h8300/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/h8300/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,7 @@ int show_interrupts(struct seq_file *p,
 		seq_puts(p, "           CPU0");
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto unlock;
@@ -200,7 +200,7 @@ int show_interrupts(struct seq_file *p,
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
 unlock:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/kernel/process.c linux-libre-2.6.33-gnu1/arch/h8300/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/h8300/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -218,15 +218,12 @@ asmlinkage int sys_execve(char *name, ch
 	char * filename;
 	struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-out:
-	unlock_kernel();
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/kernel/syscalls.S linux-libre-2.6.33-gnu1/arch/h8300/kernel/syscalls.S
--- linux-libre-2.6.32-gnu1/arch/h8300/kernel/syscalls.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/kernel/syscalls.S	2010-02-24 13:52:17.000000000 -0500
@@ -206,7 +206,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
 	.long SYMBOL_NAME(sys_getrlimit)
-	.long SYMBOL_NAME(sys_mmap2)
+	.long SYMBOL_NAME(sys_mmap_pgoff)
 	.long SYMBOL_NAME(sys_truncate64)
 	.long SYMBOL_NAME(sys_ftruncate64)
 	.long SYMBOL_NAME(sys_stat64)		/* 195 */
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/kernel/sys_h8300.c linux-libre-2.6.33-gnu1/arch/h8300/kernel/sys_h8300.c
--- linux-libre-2.6.32-gnu1/arch/h8300/kernel/sys_h8300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/kernel/sys_h8300.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,39 +26,6 @@
 #include <asm/traps.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
@@ -87,57 +54,11 @@ asmlinkage int old_mmap(struct mmap_arg_
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-#if 0 /* DAVIDM - do we want this */
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
-
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			       a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
-#endif
 
 struct sel_arg_struct {
 	unsigned long n;
diff -druNp linux-libre-2.6.32-gnu1/arch/h8300/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/h8300/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/h8300/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/h8300/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,3 @@
-#define VMLINUX_SYMBOL(_sym_) _##_sym_
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/page.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/hp/common/sba_iommu.c linux-libre-2.6.33-gnu1/arch/ia64/hp/common/sba_iommu.c
--- linux-libre-2.6.32-gnu1/arch/ia64/hp/common/sba_iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/hp/common/sba_iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -677,12 +677,19 @@ sba_alloc_range(struct ioc *ioc, struct
 			spin_unlock_irqrestore(&ioc->saved_lock, flags);
 
 			pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
-			if (unlikely(pide >= (ioc->res_size << 3)))
-				panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
-				      ioc->ioc_hpa);
+			if (unlikely(pide >= (ioc->res_size << 3))) {
+				printk(KERN_WARNING "%s: I/O MMU @ %p is"
+				       "out of mapping resources, %u %u %lx\n",
+				       __func__, ioc->ioc_hpa, ioc->res_size,
+				       pages_needed, dma_get_seg_boundary(dev));
+				return -1;
+			}
 #else
-			panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
-			      ioc->ioc_hpa);
+			printk(KERN_WARNING "%s: I/O MMU @ %p is"
+			       "out of mapping resources, %u %u %lx\n",
+			       __func__, ioc->ioc_hpa, ioc->res_size,
+			       pages_needed, dma_get_seg_boundary(dev));
+			return -1;
 #endif
 		}
 	}
@@ -965,6 +972,8 @@ static dma_addr_t sba_map_page(struct de
 #endif
 
 	pide = sba_alloc_range(ioc, dev, size);
+	if (pide < 0)
+		return 0;
 
 	iovp = (dma_addr_t) pide << iovp_shift;
 
@@ -1320,6 +1329,7 @@ sba_coalesce_chunks(struct ioc *ioc, str
 	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
 	int n_mappings = 0;
 	unsigned int max_seg_size = dma_get_max_seg_size(dev);
+	int idx;
 
 	while (nents > 0) {
 		unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
@@ -1381,7 +1391,7 @@ sba_coalesce_chunks(struct ioc *ioc, str
 #endif
 
 			/*
-			** Not virtually contigous.
+			** Not virtually contiguous.
 			** Terminate prev chunk.
 			** Start a new chunk.
 			**
@@ -1418,16 +1428,22 @@ sba_coalesce_chunks(struct ioc *ioc, str
 		vcontig_sg->dma_length = vcontig_len;
 		dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask;
 		ASSERT(dma_len <= DMA_CHUNK_SIZE);
-		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
-			| (sba_alloc_range(ioc, dev, dma_len) << iovp_shift)
-			| dma_offset);
+		idx = sba_alloc_range(ioc, dev, dma_len);
+		if (idx < 0) {
+			dma_sg->dma_length = 0;
+			return -1;
+		}
+		dma_sg->dma_address = (dma_addr_t)(PIDE_FLAG | (idx << iovp_shift)
+						   | dma_offset);
 		n_mappings++;
 	}
 
 	return n_mappings;
 }
 
-
+static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
+			       int nents, enum dma_data_direction dir,
+			       struct dma_attrs *attrs);
 /**
  * sba_map_sg - map Scatter/Gather list
  * @dev: instance of PCI owned by the driver that's asking.
@@ -1493,6 +1509,10 @@ static int sba_map_sg_attrs(struct devic
 	** Access to the virtual address is what forces a two pass algorithm.
 	*/
 	coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents);
+	if (coalesced < 0) {
+		sba_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
+		return 0;
+	}
 
 	/*
 	** Program the I/O Pdir
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/ia32/elfcore32.h linux-libre-2.6.33-gnu1/arch/ia64/ia32/elfcore32.h
--- linux-libre-2.6.32-gnu1/arch/ia64/ia32/elfcore32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/ia32/elfcore32.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,8 +11,6 @@
 #include <asm/intrinsics.h>
 #include <asm/uaccess.h>
 
-#define USE_ELF_CORE_DUMP 1
-
 /* Override elfcore.h */
 #define _LINUX_ELFCORE_H 1
 typedef unsigned int elf_greg_t;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/ia32/ia32_entry.S linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_entry.S
--- linux-libre-2.6.32-gnu1/arch/ia64/ia32/ia32_entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/ia32/ia32_entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ GLOBAL_ENTRY(ia32_ret_from_clone)
 (p6)	br.cond.spnt .ia32_strace_check_retval
 	;;					// prevent RAW on r8
 END(ia32_ret_from_clone)
-	// fall thrugh
+	// fall through
 GLOBAL_ENTRY(ia32_ret_from_syscall)
 	PT_REGS_UNWIND_INFO(0)
 
@@ -327,7 +327,7 @@ ia32_syscall_table:
 	data8 compat_sys_writev
 	data8 sys_getsid
 	data8 sys_fdatasync
-	data8 sys32_sysctl
+	data8 compat_sys_sysctl
 	data8 sys_mlock		  /* 150 */
 	data8 sys_munlock
 	data8 sys_mlockall
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/ia32/sys_ia32.c linux-libre-2.6.33-gnu1/arch/ia64/ia32/sys_ia32.c
--- linux-libre-2.6.32-gnu1/arch/ia64/ia32/sys_ia32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/ia32/sys_ia32.c	2010-02-24 13:52:17.000000000 -0500
@@ -858,6 +858,9 @@ ia32_do_mmap (struct file *file, unsigne
 
 	prot = get_prot32(prot);
 
+	if (flags & MAP_HUGETLB)
+		return -ENOMEM;
+
 #if PAGE_SHIFT > IA32_PAGE_SHIFT
 	mutex_lock(&ia32_mmap_mutex);
 	{
@@ -1628,61 +1631,6 @@ sys32_msync (unsigned int start, unsigne
 	return sys_msync(addr, len + (start - addr), flags);
 }
 
-struct sysctl32 {
-	unsigned int	name;
-	int		nlen;
-	unsigned int	oldval;
-	unsigned int	oldlenp;
-	unsigned int	newval;
-	unsigned int	newlen;
-	unsigned int	__unused[4];
-};
-
-#ifdef CONFIG_SYSCTL_SYSCALL
-asmlinkage long
-sys32_sysctl (struct sysctl32 __user *args)
-{
-	struct sysctl32 a32;
-	mm_segment_t old_fs = get_fs ();
-	void __user *oldvalp, *newvalp;
-	size_t oldlen;
-	int __user *namep;
-	long ret;
-
-	if (copy_from_user(&a32, args, sizeof(a32)))
-		return -EFAULT;
-
-	/*
-	 * We need to pre-validate these because we have to disable address checking
-	 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
-	 * user specifying bad addresses here.  Well, since we're dealing with 32 bit
-	 * addresses, we KNOW that access_ok() will always succeed, so this is an
-	 * expensive NOP, but so what...
-	 */
-	namep = (int __user *) compat_ptr(a32.name);
-	oldvalp = compat_ptr(a32.oldval);
-	newvalp = compat_ptr(a32.newval);
-
-	if ((oldvalp && get_user(oldlen, (int __user *) compat_ptr(a32.oldlenp)))
-	    || !access_ok(VERIFY_WRITE, namep, 0)
-	    || !access_ok(VERIFY_WRITE, oldvalp, 0)
-	    || !access_ok(VERIFY_WRITE, newvalp, 0))
-		return -EFAULT;
-
-	set_fs(KERNEL_DS);
-	lock_kernel();
-	ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *) &oldlen,
-			newvalp, (size_t) a32.newlen);
-	unlock_kernel();
-	set_fs(old_fs);
-
-	if (oldvalp && put_user (oldlen, (int __user *) compat_ptr(a32.oldlenp)))
-		return -EFAULT;
-
-	return ret;
-}
-#endif
-
 asmlinkage long
 sys32_newuname (struct new_utsname __user *name)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/acpi.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/acpi.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/acpi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/acpi.h	2010-02-24 13:52:17.000000000 -0500
@@ -94,6 +94,7 @@ ia64_acpi_release_global_lock (unsigned
 #define acpi_noirq 0	/* ACPI always enabled on IA64 */
 #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
 #define acpi_strict 1	/* no ACPI spec workarounds on IA64 */
+#define acpi_ht 0	/* no HT-only mode on IA64 */
 #endif
 #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
 static inline void disable_acpi(void) { }
@@ -132,6 +133,12 @@ extern int __devinitdata pxm_to_nid_map[
 extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
 #endif
 
+static inline bool arch_has_acpi_pdc(void) { return true; }
+static inline void arch_acpi_set_pdc_bits(u32 *buf)
+{
+	buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+}
+
 #define acpi_unlazy_tlb(x)
 
 #ifdef CONFIG_ACPI_NUMA
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/bitops.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/bitops.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/bitops.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
@@ -127,7 +127,7 @@ clear_bit_unlock (int nr, volatile void
  * @addr: Address to start counting from
  *
  * Similarly to clear_bit_unlock, the implementation uses a store
- * with release semantics. See also __raw_spin_unlock().
+ * with release semantics. See also arch_spin_unlock().
  */
 static __inline__ void
 __clear_bit_unlock(int nr, void *addr)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #define flush_cache_vmap(start, end)		do { } while (0)
 #define flush_cache_vunmap(start, end)		do { } while (0)
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)			\
 do {						\
 	clear_bit(PG_arch_1, &(page)->flags);	\
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -73,7 +73,7 @@ static inline bool dma_capable(struct de
 	if (!dev->dma_mask)
 		return 0;
 
-	return addr + size <= *dev->dma_mask;
+	return addr + size - 1 <= *dev->dma_mask;
 }
 
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,7 +25,6 @@
 #define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_IA_64
 
-#define USE_ELF_CORE_DUMP
 #define CORE_DUMP_USE_REGSET
 
 /* Least-significant four bits of ELF header's e_flags are OS-specific.  The bits are
@@ -202,7 +201,9 @@ extern void ia64_elf_core_copy_regs (str
    relevant until we have real hardware to play with... */
 #define ELF_PLATFORM	NULL
 
-#define SET_PERSONALITY(ex)	set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex)	\
+	set_personality((current->personality & ~PER_MASK) | PER_LINUX)
+
 #define elf_read_implies_exec(ex, executable_stack)					\
 	((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/ftrace.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ftrace.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/ftrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,6 @@
 extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0);
 #define mcount _mcount
 
-#include <asm/kprobes.h>
 /* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */
 #define MCOUNT_ADDR (((struct fnptr *)mcount)->ip)
 #define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/hw_irq.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/hw_irq.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/hw_irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/hw_irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,13 @@ typedef u16 ia64_vector;
 extern int ia64_first_device_vector;
 extern int ia64_last_device_vector;
 
+#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_DIG))
+/* Reserve the lower priority vector than device vectors for "move IRQ" IPI */
+#define IA64_IRQ_MOVE_VECTOR		0x30	/* "move IRQ" IPI */
+#define IA64_DEF_FIRST_DEVICE_VECTOR	0x31
+#else
 #define IA64_DEF_FIRST_DEVICE_VECTOR	0x30
+#endif
 #define IA64_DEF_LAST_DEVICE_VECTOR	0xe7
 #define IA64_FIRST_DEVICE_VECTOR	ia64_first_device_vector
 #define IA64_LAST_DEVICE_VECTOR		ia64_last_device_vector
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/io.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/io.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -424,6 +424,8 @@ __writeq (unsigned long val, volatile vo
 extern void __iomem * ioremap(unsigned long offset, unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
 extern void iounmap (volatile void __iomem *addr);
+extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
+extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 
 /*
  * String version of IO memory access ops:
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/irq.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/irq.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,7 @@
 
 #include <linux/types.h>
 #include <linux/cpumask.h>
-#include <asm-ia64/nr-irqs.h>
+#include <generated/nr-irqs.h>
 
 static __inline__ int
 irq_canonicalize (int irq)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kprobes.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kprobes.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kprobes.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kprobes.h	2010-02-24 13:52:17.000000000 -0500
@@ -103,11 +103,6 @@ typedef struct kprobe_opcode {
 	bundle_t bundle;
 } kprobe_opcode_t;
 
-struct fnptr {
-	unsigned long ip;
-	unsigned long gp;
-};
-
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
 	/* copy of the instruction to be emulated */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kvm.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kvm.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kvm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kvm.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,6 +60,7 @@ struct kvm_ioapic_state {
 #define KVM_IRQCHIP_PIC_MASTER   0
 #define KVM_IRQCHIP_PIC_SLAVE    1
 #define KVM_IRQCHIP_IOAPIC       2
+#define KVM_NR_IRQCHIPS          3
 
 #define KVM_CONTEXT_SIZE	8*1024
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kvm_host.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kvm_host.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/kvm_host.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/kvm_host.h	2010-02-24 13:52:17.000000000 -0500
@@ -475,7 +475,6 @@ struct kvm_arch {
 	struct list_head assigned_dev_head;
 	struct iommu_domain *iommu_domain;
 	int iommu_flags;
-	struct hlist_head irq_ack_notifier_list;
 
 	unsigned long irq_sources_bitmap;
 	unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/mca.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/mca.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/mca.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/mca.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,6 +106,11 @@ struct ia64_sal_os_state {
 	unsigned long		os_status;		/* OS status to SAL, enum below */
 	unsigned long		context;		/* 0 if return to same context
 							   1 if return to new context */
+
+	/* I-resources */
+	unsigned long		iip;
+	unsigned long		ipsr;
+	unsigned long		ifs;
 };
 
 enum {
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/meminit.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/meminit.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/meminit.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/meminit.h	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ extern int register_active_ranges(u64 st
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 # define LARGE_GAP	0x40000000 /* Use virtual mem map if hole is > than this */
-  extern unsigned long vmalloc_end;
+  extern unsigned long VMALLOC_END;
   extern struct page *vmem_map;
   extern int find_largest_hole(u64 start, u64 end, void *arg);
   extern int create_mem_map_page_table(u64 start, u64 end, void *arg);
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/numa.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/numa.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/numa.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/numa.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,8 +22,6 @@
 
 #include <asm/mmzone.h>
 
-#define NUMA_NO_NODE	-1
-
 extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
 extern pg_data_t *pgdat_list[MAX_NUMNODES];
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/perfmon_default_smpl.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/perfmon_default_smpl.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/perfmon_default_smpl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/perfmon_default_smpl.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,7 @@ typedef struct {
         unsigned long   ip;                     /* where did the overflow interrupt happened  */
         unsigned long   tstamp;                 /* ar.itc when entering perfmon intr. handler */
 
-        unsigned short  cpu;                    /* cpu on which the overfow occured */
+        unsigned short  cpu;                    /* cpu on which the overflow occured */
         unsigned short  set;                    /* event set active when overflow ocurred   */
         int    		tgid;              	/* thread group id (for NPTL, this is getpid()) */
 } pfm_default_smpl_entry_t;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -228,8 +228,7 @@ ia64_phys_addr_valid (unsigned long addr
 #define VMALLOC_START		(RGN_BASE(RGN_GATE) + 0x200000000UL)
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 # define VMALLOC_END_INIT	(RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
-# define VMALLOC_END		vmalloc_end
-  extern unsigned long vmalloc_end;
+extern unsigned long VMALLOC_END;
 #else
 #if defined(CONFIG_SPARSEMEM) && defined(CONFIG_SPARSEMEM_VMEMMAP)
 /* SPARSEMEM_VMEMMAP uses half of vmalloc... */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/processor.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/processor.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/processor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
@@ -229,7 +229,7 @@ struct cpuinfo_ia64 {
 #endif
 };
 
-DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info);
+DECLARE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
 
 /*
  * The "local" data variable.  It refers to the per-CPU data of the currently executing
@@ -237,8 +237,8 @@ DECLARE_PER_CPU(struct cpuinfo_ia64, cpu
  * Do not use the address of local_cpu_data, since it will be different from
  * cpu_data(smp_processor_id())!
  */
-#define local_cpu_data		(&__ia64_per_cpu_var(cpu_info))
-#define cpu_data(cpu)		(&per_cpu(cpu_info, cpu))
+#define local_cpu_data		(&__ia64_per_cpu_var(ia64_cpu_info))
+#define cpu_data(cpu)		(&per_cpu(ia64_cpu_info, cpu))
 
 extern void print_cpu_info (struct cpuinfo_ia64 *);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/rwsem.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/rwsem.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/rwsem.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/rwsem.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ struct rw_semaphore {
 #define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 
 #define __RWSEM_INITIALIZER(name) \
-	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+	{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
 	  LIST_HEAD_INIT((name).wait_list) }
 
 #define DECLARE_RWSEM(name) \
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/sn/shubio.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/sn/shubio.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/sn/shubio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/sn/shubio.h	2010-02-24 13:52:17.000000000 -0500
@@ -3289,7 +3289,7 @@ typedef ii_icrb0_e_u_t icrbe_t;
 #define IIO_IIDSR_LVL_SHIFT     0
 #define IIO_IIDSR_LVL_MASK      0x000000ff
 
-/* Xtalk timeout threshhold register (IIO_IXTT) */
+/* Xtalk timeout threshold register (IIO_IXTT) */
 #define IXTT_RRSP_TO_SHFT	55	/* read response timeout */
 #define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
 #define IXTT_RRSP_PS_SHFT	32	/* read responsed TO prescalar */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -69,4 +69,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_IA64_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,7 @@
 #include <asm/intrinsics.h>
 #include <asm/system.h>
 
-#define __raw_spin_lock_init(x)			((x)->lock = 0)
+#define arch_spin_lock_init(x)			((x)->lock = 0)
 
 /*
  * Ticket locks are conceptually two parts, one indicating the current head of
@@ -38,7 +38,7 @@
 #define TICKET_BITS	15
 #define	TICKET_MASK	((1 << TICKET_BITS) - 1)
 
-static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
 {
 	int	*p = (int *)&lock->lock, ticket, serve;
 
@@ -58,7 +58,7 @@ static __always_inline void __ticket_spi
 	}
 }
 
-static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
 {
 	int tmp = ACCESS_ONCE(lock->lock);
 
@@ -67,7 +67,7 @@ static __always_inline int __ticket_spin
 	return 0;
 }
 
-static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
 {
 	unsigned short	*p = (unsigned short *)&lock->lock + 1, tmp;
 
@@ -75,7 +75,7 @@ static __always_inline void __ticket_spi
 	ACCESS_ONCE(*p) = (tmp + 2) & ~1;
 }
 
-static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock)
 {
 	int	*p = (int *)&lock->lock, ticket;
 
@@ -89,64 +89,64 @@ static __always_inline void __ticket_spi
 	}
 }
 
-static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(arch_spinlock_t *lock)
 {
 	long tmp = ACCESS_ONCE(lock->lock);
 
 	return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK);
 }
 
-static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(arch_spinlock_t *lock)
 {
 	long tmp = ACCESS_ONCE(lock->lock);
 
 	return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1;
 }
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
 {
 	return __ticket_spin_is_locked(lock);
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
 {
 	return __ticket_spin_is_contended(lock);
 }
-#define __raw_spin_is_contended	__raw_spin_is_contended
+#define arch_spin_is_contended	arch_spin_is_contended
 
-static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	__ticket_spin_lock(lock);
 }
 
-static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	return __ticket_spin_trylock(lock);
 }
 
-static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__ticket_spin_unlock(lock);
 }
 
-static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
+static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock,
 						  unsigned long flags)
 {
-	__raw_spin_lock(lock);
+	arch_spin_lock(lock);
 }
 
-static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
 	__ticket_spin_unlock_wait(lock);
 }
 
-#define __raw_read_can_lock(rw)		(*(volatile int *)(rw) >= 0)
-#define __raw_write_can_lock(rw)	(*(volatile int *)(rw) == 0)
+#define arch_read_can_lock(rw)		(*(volatile int *)(rw) >= 0)
+#define arch_write_can_lock(rw)	(*(volatile int *)(rw) == 0)
 
 #ifdef ASM_SUPPORTED
 
 static __always_inline void
-__raw_read_lock_flags(raw_rwlock_t *lock, unsigned long flags)
+arch_read_lock_flags(arch_rwlock_t *lock, unsigned long flags)
 {
 	__asm__ __volatile__ (
 		"tbit.nz p6, p0 = %1,%2\n"
@@ -169,15 +169,15 @@ __raw_read_lock_flags(raw_rwlock_t *lock
 		: "p6", "p7", "r2", "memory");
 }
 
-#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0)
+#define arch_read_lock(lock) arch_read_lock_flags(lock, 0)
 
 #else /* !ASM_SUPPORTED */
 
-#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
+#define arch_read_lock_flags(rw, flags) arch_read_lock(rw)
 
-#define __raw_read_lock(rw)								\
+#define arch_read_lock(rw)								\
 do {											\
-	raw_rwlock_t *__read_lock_ptr = (rw);						\
+	arch_rwlock_t *__read_lock_ptr = (rw);						\
 											\
 	while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) {		\
 		ia64_fetchadd(-1, (int *) __read_lock_ptr, rel);			\
@@ -188,16 +188,16 @@ do {											\
 
 #endif /* !ASM_SUPPORTED */
 
-#define __raw_read_unlock(rw)					\
+#define arch_read_unlock(rw)					\
 do {								\
-	raw_rwlock_t *__read_lock_ptr = (rw);			\
+	arch_rwlock_t *__read_lock_ptr = (rw);			\
 	ia64_fetchadd(-1, (int *) __read_lock_ptr, rel);	\
 } while (0)
 
 #ifdef ASM_SUPPORTED
 
 static __always_inline void
-__raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags)
+arch_write_lock_flags(arch_rwlock_t *lock, unsigned long flags)
 {
 	__asm__ __volatile__ (
 		"tbit.nz p6, p0 = %1, %2\n"
@@ -221,9 +221,9 @@ __raw_write_lock_flags(raw_rwlock_t *loc
 		: "ar.ccv", "p6", "p7", "r2", "r29", "memory");
 }
 
-#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0)
+#define arch_write_lock(rw) arch_write_lock_flags(rw, 0)
 
-#define __raw_write_trylock(rw)							\
+#define arch_write_trylock(rw)							\
 ({										\
 	register long result;							\
 										\
@@ -235,7 +235,7 @@ __raw_write_lock_flags(raw_rwlock_t *loc
 	(result == 0);								\
 })
 
-static inline void __raw_write_unlock(raw_rwlock_t *x)
+static inline void arch_write_unlock(arch_rwlock_t *x)
 {
 	u8 *y = (u8 *)x;
 	barrier();
@@ -244,9 +244,9 @@ static inline void __raw_write_unlock(ra
 
 #else /* !ASM_SUPPORTED */
 
-#define __raw_write_lock_flags(l, flags) __raw_write_lock(l)
+#define arch_write_lock_flags(l, flags) arch_write_lock(l)
 
-#define __raw_write_lock(l)								\
+#define arch_write_lock(l)								\
 ({											\
 	__u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1);			\
 	__u32 *ia64_write_lock_ptr = (__u32 *) (l);					\
@@ -257,7 +257,7 @@ static inline void __raw_write_unlock(ra
 	} while (ia64_val);								\
 })
 
-#define __raw_write_trylock(rw)						\
+#define arch_write_trylock(rw)						\
 ({									\
 	__u64 ia64_val;							\
 	__u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1);			\
@@ -265,7 +265,7 @@ static inline void __raw_write_unlock(ra
 	(ia64_val == 0);						\
 })
 
-static inline void __raw_write_unlock(raw_rwlock_t *x)
+static inline void arch_write_unlock(arch_rwlock_t *x)
 {
 	barrier();
 	x->write_lock = 0;
@@ -273,10 +273,10 @@ static inline void __raw_write_unlock(ra
 
 #endif /* !ASM_SUPPORTED */
 
-static inline int __raw_read_trylock(raw_rwlock_t *x)
+static inline int arch_read_trylock(arch_rwlock_t *x)
 {
 	union {
-		raw_rwlock_t lock;
+		arch_rwlock_t lock;
 		__u32 word;
 	} old, new;
 	old.lock = new.lock = *x;
@@ -285,8 +285,8 @@ static inline int __raw_read_trylock(raw
 	return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word;
 }
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /*  _ASM_IA64_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,15 +7,15 @@
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int read_counter	: 31;
 	volatile unsigned int write_lock	:  1;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0, 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0, 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/swiotlb.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/swiotlb.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/swiotlb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/swiotlb.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,8 +4,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/swiotlb.h>
 
-extern int swiotlb_force;
-
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
 extern void pci_swiotlb_init(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/tlb.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/tlb.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/tlb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/tlb.h	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ struct ia64_tr_entry {
 extern int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size);
 extern void ia64_ptr_entry(u64 target_mask, int slot);
 
-extern struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX];
+extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
 
 /*
  region register macros
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/topology.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/topology.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,9 @@
 /*
  * Returns a bitmask of CPUs on Node 'node'.
  */
-#define cpumask_of_node(node) (&node_to_cpu_mask[node])
+#define cpumask_of_node(node) ((node) == -1 ?				\
+			       cpu_all_mask :				\
+			       &node_to_cpu_mask[node])
 
 /*
  * Returns the number of the node containing Node 'nid'.
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/types.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/types.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/types.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,11 @@ typedef unsigned int umode_t;
  */
 # ifdef __KERNEL__
 
+struct fnptr {
+	unsigned long ip;
+	unsigned long gp;
+};
+
 /* DMA addresses are 64-bits wide, in general.  */
 typedef u64 dma_addr_t;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -311,11 +311,12 @@
 #define __NR_preadv			1319
 #define __NR_pwritev			1320
 #define __NR_rt_tgsigqueueinfo		1321
+#define __NR_recvmmsg			1322
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls			298 /* length of syscall table */
+#define NR_syscalls			299 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/include/asm/xen/hypervisor.h linux-libre-2.6.33-gnu1/arch/ia64/include/asm/xen/hypervisor.h
--- linux-libre-2.6.32-gnu1/arch/ia64/include/asm/xen/hypervisor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/include/asm/xen/hypervisor.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,35 +37,9 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>	/* to compile feature.c */
 #include <xen/features.h>		/* to comiple xen-netfront.c */
+#include <xen/xen.h>
 #include <asm/xen/hypercall.h>
 
-/* xen_domain_type is set before executing any C code by early_xen_setup */
-enum xen_domain_type {
-	XEN_NATIVE,	/* running on bare hardware */
-	XEN_PV_DOMAIN,	/* running in a PV domain */
-	XEN_HVM_DOMAIN,	/* running in a Xen hvm domain*/
-};
-
-#ifdef CONFIG_XEN
-extern enum xen_domain_type xen_domain_type;
-#else
-#define xen_domain_type		XEN_NATIVE
-#endif
-
-#define xen_domain()		(xen_domain_type != XEN_NATIVE)
-#define xen_pv_domain()		(xen_domain() &&			\
-				 xen_domain_type == XEN_PV_DOMAIN)
-#define xen_hvm_domain()	(xen_domain() &&			\
-				 xen_domain_type == XEN_HVM_DOMAIN)
-
-#ifdef CONFIG_XEN_DOM0
-#define xen_initial_domain()	(xen_pv_domain() &&			\
-				 (xen_start_info->flags & SIF_INITDOMAIN))
-#else
-#define xen_initial_domain()	(0)
-#endif
-
-
 #ifdef CONFIG_XEN
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/Kconfig linux-libre-2.6.33-gnu1/arch/ia64/Kconfig
--- linux-libre-2.6.32-gnu1/arch/ia64/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -87,9 +87,6 @@ config GENERIC_TIME_VSYSCALL
 	bool
 	default y
 
-config HAVE_LEGACY_PER_CPU_AREA
-	def_bool y
-
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/acpi.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -702,11 +702,23 @@ int __init early_acpi_boot_init(void)
 		printk(KERN_ERR PREFIX
 		       "Error parsing MADT - no LAPIC entries\n");
 
+#ifdef CONFIG_SMP
+	if (available_cpus == 0) {
+		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
+		printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
+		smp_boot_data.cpu_phys_id[available_cpus] =
+		    hard_smp_processor_id();
+		available_cpus = 1;	/* We've got at least one of these, no? */
+	}
+	smp_boot_data.cpu_count = available_cpus;
+#endif
+	/* Make boot-up look pretty */
+	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus,
+	       total_cpus);
+
 	return 0;
 }
 
-
-
 int __init acpi_boot_init(void)
 {
 
@@ -769,18 +781,8 @@ int __init acpi_boot_init(void)
 	if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
 		printk(KERN_ERR PREFIX "Can't find FADT\n");
 
+#ifdef CONFIG_ACPI_NUMA
 #ifdef CONFIG_SMP
-	if (available_cpus == 0) {
-		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
-		printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
-		smp_boot_data.cpu_phys_id[available_cpus] =
-		    hard_smp_processor_id();
-		available_cpus = 1;	/* We've got at least one of these, no? */
-	}
-	smp_boot_data.cpu_count = available_cpus;
-
-	smp_build_cpu_map();
-# ifdef CONFIG_ACPI_NUMA
 	if (srat_num_cpus == 0) {
 		int cpu, i = 1;
 		for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
@@ -789,14 +791,9 @@ int __init acpi_boot_init(void)
 				node_cpuid[i++].phys_id =
 				    smp_boot_data.cpu_phys_id[cpu];
 	}
-# endif
 #endif
-#ifdef CONFIG_ACPI_NUMA
 	build_cpu_to_node_map();
 #endif
-	/* Make boot-up look pretty */
-	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus,
-	       total_cpus);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/acpi-processor.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi-processor.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/acpi-processor.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/acpi-processor.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * arch/ia64/kernel/acpi-processor.c
- *
- * Copyright (C) 2005 Intel Corporation
- * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- * 	- Added _PDC for platforms with Intel CPUs
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-
-#include <acpi/processor.h>
-#include <asm/acpi.h>
-
-static void init_intel_pdc(struct acpi_processor *pr)
-{
-	struct acpi_object_list *obj_list;
-	union acpi_object *obj;
-	u32 *buf;
-
-	/* allocate and initialize pdc. It will be used later. */
-	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
-	if (!obj_list) {
-		printk(KERN_ERR "Memory allocation error\n");
-		return;
-	}
-
-	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-	if (!obj) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj_list);
-		return;
-	}
-
-	buf = kmalloc(12, GFP_KERNEL);
-	if (!buf) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj);
-		kfree(obj_list);
-		return;
-	}
-
-	buf[0] = ACPI_PDC_REVISION_ID;
-	buf[1] = 1;
-	buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
-	/*
-	 * The default of PDC_SMP_T_SWCOORD bit is set for IA64 cpu so
-	 * that OSPM is capable of native ACPI throttling software
-	 * coordination using BIOS supplied _TSD info.
-	 */
-	buf[2] |= ACPI_PDC_SMP_T_SWCOORD;
-
-	obj->type = ACPI_TYPE_BUFFER;
-	obj->buffer.length = 12;
-	obj->buffer.pointer = (u8 *) buf;
-	obj_list->count = 1;
-	obj_list->pointer = obj;
-	pr->pdc = obj_list;
-
-	return;
-}
-
-/* Initialize _PDC data based on the CPU vendor */
-void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
-{
-	pr->pdc = NULL;
-	init_intel_pdc(pr);
-	return;
-}
-
-EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
-
-void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr)
-{
-	if (pr->pdc) {
-		kfree(pr->pdc->pointer->buffer.pointer);
-		kfree(pr->pdc->pointer);
-		kfree(pr->pdc);
-		pr->pdc = NULL;
-	}
-}
-
-EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc);
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/crash.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/crash.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/crash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/crash.c	2010-02-24 13:52:17.000000000 -0500
@@ -239,32 +239,29 @@ kdump_init_notifier(struct notifier_bloc
 #ifdef CONFIG_SYSCTL
 static ctl_table kdump_ctl_table[] = {
 	{
-		.ctl_name = CTL_UNNUMBERED,
 		.procname = "kdump_on_init",
 		.data = &kdump_on_init,
 		.maxlen = sizeof(int),
 		.mode = 0644,
-		.proc_handler = &proc_dointvec,
+		.proc_handler = proc_dointvec,
 	},
 	{
-		.ctl_name = CTL_UNNUMBERED,
 		.procname = "kdump_on_fatal_mca",
 		.data = &kdump_on_fatal_mca,
 		.maxlen = sizeof(int),
 		.mode = 0644,
-		.proc_handler = &proc_dointvec,
+		.proc_handler = proc_dointvec,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table sys_table[] = {
 	{
-	  .ctl_name = CTL_KERN,
 	  .procname = "kernel",
 	  .mode = 0555,
 	  .child = kdump_ctl_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/entry.S linux-libre-2.6.33-gnu1/arch/ia64/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -1806,6 +1806,7 @@ sys_call_table:
 	data8 sys_preadv
 	data8 sys_pwritev			// 1320
 	data8 sys_rt_tgsigqueueinfo
+	data8 sys_recvmmsg
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/esi.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/esi.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/esi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/esi.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,7 +84,7 @@ static int __init esi_init (void)
 		      case ESI_DESC_ENTRY_POINT:
 			break;
 		      default:
-			printk(KERN_WARNING "Unkown table type %d found in "
+			printk(KERN_WARNING "Unknown table type %d found in "
 			       "ESI table, ignoring rest of table\n", *p);
 			return -ENODEV;
 		}
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/head.S linux-libre-2.6.33-gnu1/arch/ia64/kernel/head.S
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -1051,7 +1051,7 @@ END(ia64_delay_loop)
  * intermediate precision so that we can produce a full 64-bit result.
  */
 GLOBAL_ENTRY(ia64_native_sched_clock)
-	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+	addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
 	mov.m r9=ar.itc		// fetch cycle-counter				(35 cyc)
 	;;
 	ldf8 f8=[r8]
@@ -1077,7 +1077,7 @@ sched_clock = ia64_native_sched_clock
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 GLOBAL_ENTRY(cycle_to_cputime)
 	alloc r16=ar.pfs,1,0,0,0
-	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+	addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
 	;;
 	ldf8 f8=[r8]
 	;;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/ia64_ksyms.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/ia64_ksyms.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/ia64_ksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/ia64_ksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,7 @@ EXPORT_SYMBOL(max_low_pfn);	/* defined b
 #endif
 
 #include <asm/processor.h>
-EXPORT_SYMBOL(per_cpu__cpu_info);
+EXPORT_SYMBOL(per_cpu__ia64_cpu_info);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(per_cpu__local_per_cpu_offset);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/iosapic.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/iosapic.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/iosapic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/iosapic.c	2010-02-24 13:52:17.000000000 -0500
@@ -793,12 +793,12 @@ iosapic_register_intr (unsigned int gsi,
 			goto unlock_iosapic_lock;
 	}
 
-	spin_lock(&irq_desc[irq].lock);
+	raw_spin_lock(&irq_desc[irq].lock);
 	dest = get_target_cpu(gsi, irq);
 	dmode = choose_dmode();
 	err = register_intr(gsi, irq, dmode, polarity, trigger);
 	if (err < 0) {
-		spin_unlock(&irq_desc[irq].lock);
+		raw_spin_unlock(&irq_desc[irq].lock);
 		irq = err;
 		goto unlock_iosapic_lock;
 	}
@@ -817,7 +817,7 @@ iosapic_register_intr (unsigned int gsi,
 	       (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
 	       cpu_logical_id(dest), dest, irq_to_vector(irq));
 
-	spin_unlock(&irq_desc[irq].lock);
+	raw_spin_unlock(&irq_desc[irq].lock);
  unlock_iosapic_lock:
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 	return irq;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/irq.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,7 +71,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -91,7 +91,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS)
 		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/irq_ia64.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq_ia64.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/irq_ia64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/irq_ia64.c	2010-02-24 13:52:17.000000000 -0500
@@ -260,7 +260,6 @@ void __setup_vector_irq(int cpu)
 }
 
 #if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
-#define IA64_IRQ_MOVE_VECTOR	IA64_DEF_FIRST_DEVICE_VECTOR
 
 static enum vector_domain_type {
 	VECTOR_DOMAIN_NONE,
@@ -345,7 +344,7 @@ static irqreturn_t smp_irq_move_cleanup_
 
 		desc = irq_desc + irq;
 		cfg = irq_cfg + irq;
-		spin_lock(&desc->lock);
+		raw_spin_lock(&desc->lock);
 		if (!cfg->move_cleanup_count)
 			goto unlock;
 
@@ -358,7 +357,7 @@ static irqreturn_t smp_irq_move_cleanup_
 		spin_unlock_irqrestore(&vector_lock, flags);
 		cfg->move_cleanup_count--;
 	unlock:
-		spin_unlock(&desc->lock);
+		raw_spin_unlock(&desc->lock);
 	}
 	return IRQ_HANDLED;
 }
@@ -659,11 +658,8 @@ init_IRQ (void)
 	register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
-	if (vector_domain_type != VECTOR_DOMAIN_NONE) {
-		BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
-		IA64_FIRST_DEVICE_VECTOR++;
+	if (vector_domain_type != VECTOR_DOMAIN_NONE)
 		register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction);
-	}
 #endif
 #endif
 #ifdef CONFIG_PERFMON
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/Makefile linux-libre-2.6.33-gnu1/arch/ia64/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -18,10 +18,6 @@ obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
 
-ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y				+= acpi-processor.o
-endif
-
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
@@ -81,17 +77,14 @@ define cmd_nr_irqs
 endef
 
 # We use internal kbuild rules to avoid the "is up to date" message from make
-arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \
-				$(wildcard $(srctree)/include/asm-ia64/*/irq.h)
+arch/$(SRCARCH)/kernel/nr-irqs.s: arch/$(SRCARCH)/kernel/nr-irqs.c
 	$(Q)mkdir -p $(dir $@)
 	$(call if_changed_dep,cc_s_c)
 
-include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
+include/generated/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
 	$(Q)mkdir -p $(dir $@)
 	$(call cmd,nr_irqs)
 
-clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
-
 #
 # native ivt.S, entry.S and fsys.S
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/mca_asm.S linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca_asm.S
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/mca_asm.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca_asm.S	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@
 ia64_do_tlb_purge:
 #define O(member)	IA64_CPUINFO_##member##_OFFSET
 
-	GET_THIS_PADDR(r2, cpu_info)	// load phys addr of cpu_info into r2
+	GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
 	;;
 	addl r17=O(PTCE_STRIDE),r2
 	addl r2=O(PTCE_BASE),r2
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/mca.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/mca.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/mca.c	2010-02-24 13:52:17.000000000 -0500
@@ -888,9 +888,10 @@ ia64_mca_modify_comm(const struct task_s
 }
 
 static void
-finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms,
+finish_pt_regs(struct pt_regs *regs, struct ia64_sal_os_state *sos,
 		unsigned long *nat)
 {
+	const pal_min_state_area_t *ms = sos->pal_min_state;
 	const u64 *bank;
 
 	/* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
@@ -904,6 +905,10 @@ finish_pt_regs(struct pt_regs *regs, con
 		regs->cr_iip = ms->pmsa_xip;
 		regs->cr_ipsr = ms->pmsa_xpsr;
 		regs->cr_ifs = ms->pmsa_xfs;
+
+		sos->iip = ms->pmsa_iip;
+		sos->ipsr = ms->pmsa_ipsr;
+		sos->ifs = ms->pmsa_ifs;
 	}
 	regs->pr = ms->pmsa_pr;
 	regs->b0 = ms->pmsa_br0;
@@ -1079,7 +1084,7 @@ ia64_mca_modify_original_stack(struct pt
 	memcpy(old_regs, regs, sizeof(*regs));
 	old_regs->loadrs = loadrs;
 	old_unat = old_regs->ar_unat;
-	finish_pt_regs(old_regs, ms, &old_unat);
+	finish_pt_regs(old_regs, sos, &old_unat);
 
 	/* Next stack a struct switch_stack.  mca_asm.S built a partial
 	 * switch_stack, copy it and fill in the blanks using pt_regs and
@@ -1150,7 +1155,7 @@ no_mod:
 	mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n",
 			smp_processor_id(), type, msg);
 	old_unat = regs->ar_unat;
-	finish_pt_regs(regs, ms, &old_unat);
+	finish_pt_regs(regs, sos, &old_unat);
 	return previous_current;
 }
 
@@ -1220,9 +1225,12 @@ static void mca_insert_tr(u64 iord)
 	unsigned long psr;
 	int cpu = smp_processor_id();
 
+	if (!ia64_idtrs[cpu])
+		return;
+
 	psr = ia64_clear_ic();
 	for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) {
-		p = &__per_cpu_idtrs[cpu][iord-1][i];
+		p = ia64_idtrs[cpu] + (iord - 1) * IA64_TR_ALLOC_MAX;
 		if (p->pte & 0x1) {
 			old_rr = ia64_get_rr(p->ifa);
 			if (old_rr != p->rr) {
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/pci-swiotlb.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/pci-swiotlb.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/pci-swiotlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/pci-swiotlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,7 +41,7 @@ struct dma_map_ops swiotlb_dma_ops = {
 void __init swiotlb_dma_init(void)
 {
 	dma_ops = &swiotlb_dma_ops;
-	swiotlb_init();
+	swiotlb_init(1);
 }
 
 void __init pci_swiotlb_init(void)
@@ -51,7 +51,7 @@ void __init pci_swiotlb_init(void)
 		swiotlb = 1;
 		printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
 		machvec_init("dig");
-		swiotlb_init();
+		swiotlb_init(1);
 		dma_ops = &swiotlb_dma_ops;
 #else
 		panic("Unable to find Intel IOMMU");
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/perfmon.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/perfmon.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/perfmon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/perfmon.c	2010-02-24 13:52:17.000000000 -0500
@@ -522,42 +522,37 @@ EXPORT_SYMBOL(pfm_sysctl);
 
 static ctl_table pfm_ctl_table[]={
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "debug",
 		.data		= &pfm_sysctl.debug,
 		.maxlen		= sizeof(int),
 		.mode		= 0666,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "debug_ovfl",
 		.data		= &pfm_sysctl.debug_ovfl,
 		.maxlen		= sizeof(int),
 		.mode		= 0666,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "fastctxsw",
 		.data		= &pfm_sysctl.fastctxsw,
 		.maxlen		= sizeof(int),
 		.mode		= 0600,
-		.proc_handler	=  &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "expert_mode",
 		.data		= &pfm_sysctl.expert_mode,
 		.maxlen		= sizeof(int),
 		.mode		= 0600,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{}
 };
 static ctl_table pfm_sysctl_dir[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "perfmon",
 		.mode		= 0555,
 		.child		= pfm_ctl_table,
@@ -566,7 +561,6 @@ static ctl_table pfm_sysctl_dir[] = {
 };
 static ctl_table pfm_sysctl_root[] = {
 	{
-		.ctl_name	= CTL_KERN,
 		.procname	= "kernel",
 		.mode		= 0555,
 		.child		= pfm_sysctl_dir,
@@ -2206,7 +2200,7 @@ pfm_alloc_file(pfm_context_t *ctx)
 {
 	struct file *file;
 	struct inode *inode;
-	struct dentry *dentry;
+	struct path path;
 	char name[32];
 	struct qstr this;
 
@@ -2231,18 +2225,19 @@ pfm_alloc_file(pfm_context_t *ctx)
 	/*
 	 * allocate a new dcache entry
 	 */
-	dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
-	if (!dentry) {
+	path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
+	if (!path.dentry) {
 		iput(inode);
 		return ERR_PTR(-ENOMEM);
 	}
+	path.mnt = mntget(pfmfs_mnt);
 
-	dentry->d_op = &pfmfs_dentry_operations;
-	d_add(dentry, inode);
+	path.dentry->d_op = &pfmfs_dentry_operations;
+	d_add(path.dentry, inode);
 
-	file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops);
+	file = alloc_file(&path, FMODE_READ, &pfm_file_ops);
 	if (!file) {
-		dput(dentry);
+		path_put(&path);
 		return ERR_PTR(-ENFILE);
 	}
 
@@ -2298,7 +2293,7 @@ pfm_smpl_buffer_alloc(struct task_struct
 	 * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
 	 * 	return -ENOMEM;
 	 */
-	if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+	if (size > task_rlimit(task, RLIMIT_MEMLOCK))
 		return -ENOMEM;
 
 	/*
@@ -3523,7 +3518,7 @@ pfm_use_debug_registers(struct task_stru
  * IA64_THREAD_DBG_VALID set. This indicates a task which was
  * able to use the debug registers for debugging purposes via
  * ptrace(). Therefore we know it was not using them for
- * perfmormance monitoring, so we only decrement the number
+ * performance monitoring, so we only decrement the number
  * of "ptraced" debug register users to keep the count up to date
  */
 int
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/relocate_kernel.S linux-libre-2.6.33-gnu1/arch/ia64/kernel/relocate_kernel.S
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/relocate_kernel.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/relocate_kernel.S	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ GLOBAL_ENTRY(relocate_new_kernel)
 
 	// purge all TC entries
 #define O(member)       IA64_CPUINFO_##member##_OFFSET
-        GET_THIS_PADDR(r2, cpu_info)    // load phys addr of cpu_info into r2
+        GET_THIS_PADDR(r2, ia64_cpu_info) // load phys addr of cpu_info into r2
         ;;
         addl r17=O(PTCE_STRIDE),r2
         addl r2=O(PTCE_BASE),r2
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/setup.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ unsigned long __per_cpu_offset[NR_CPUS];
 EXPORT_SYMBOL(__per_cpu_offset);
 #endif
 
-DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
+DEFINE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
 DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
 unsigned long ia64_cycles_per_usec;
 struct ia64_boot_param *ia64_boot_param;
@@ -566,19 +566,18 @@ setup_arch (char **cmdline_p)
 	early_acpi_boot_init();
 # ifdef CONFIG_ACPI_NUMA
 	acpi_numa_init();
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
+#  ifdef CONFIG_ACPI_HOTPLUG_CPU
 	prefill_possible_map();
-#endif
+#  endif
 	per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ?
 		32 : cpus_weight(early_cpu_possible_map)),
 		additional_cpus > 0 ? additional_cpus : 0);
 # endif
-#else
-# ifdef CONFIG_SMP
-	smp_build_cpu_map();	/* happens, e.g., with the Ski simulator */
-# endif
 #endif /* CONFIG_APCI_BOOT */
 
+#ifdef CONFIG_SMP
+	smp_build_cpu_map();
+#endif
 	find_memory();
 
 	/* process SAL system table: */
@@ -856,18 +855,6 @@ identify_cpu (struct cpuinfo_ia64 *c)
 }
 
 /*
- * In UP configuration, setup_per_cpu_areas() is defined in
- * include/linux/percpu.h
- */
-#ifdef CONFIG_SMP
-void __init
-setup_per_cpu_areas (void)
-{
-	/* start_kernel() requires this... */
-}
-#endif
-
-/*
  * Do the following calculations:
  *
  * 1. the max. cache line size.
@@ -980,7 +967,7 @@ cpu_init (void)
 	 * depends on the data returned by identify_cpu().  We break the dependency by
 	 * accessing cpu_data() through the canonical per-CPU address.
 	 */
-	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
+	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(ia64_cpu_info) - __per_cpu_start);
 	identify_cpu(cpu_info);
 
 #ifdef CONFIG_MCKINLEY
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/sys_ia64.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/sys_ia64.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/sys_ia64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/sys_ia64.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,51 +100,7 @@ sys_getpagesize (void)
 asmlinkage unsigned long
 ia64_brk (unsigned long brk)
 {
-	unsigned long rlim, retval, newbrk, oldbrk;
-	struct mm_struct *mm = current->mm;
-
-	/*
-	 * Most of this replicates the code in sys_brk() except for an additional safety
-	 * check and the clearing of r8.  However, we can't call sys_brk() because we need
-	 * to acquire the mmap_sem before we can do the test...
-	 */
-	down_write(&mm->mmap_sem);
-
-	if (brk < mm->end_code)
-		goto out;
-	newbrk = PAGE_ALIGN(brk);
-	oldbrk = PAGE_ALIGN(mm->brk);
-	if (oldbrk == newbrk)
-		goto set_brk;
-
-	/* Always allow shrinking brk. */
-	if (brk <= mm->brk) {
-		if (!do_munmap(mm, newbrk, oldbrk-newbrk))
-			goto set_brk;
-		goto out;
-	}
-
-	/* Check against unimplemented/unmapped addresses: */
-	if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT)
-		goto out;
-
-	/* Check against rlimit.. */
-	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
-	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
-		goto out;
-
-	/* Check against existing mmap mappings. */
-	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
-		goto out;
-
-	/* Ok, looks good - let it rip. */
-	if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
-		goto out;
-set_brk:
-	mm->brk = brk;
-out:
-	retval = mm->brk;
-	up_write(&mm->mmap_sem);
+	unsigned long retval = sys_brk(brk);
 	force_successful_syscall_return();
 	return retval;
 }
@@ -185,39 +141,6 @@ int ia64_mmap_check(unsigned long addr,
 	return 0;
 }
 
-static inline unsigned long
-do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return -EBADF;
-
-		if (!file->f_op || !file->f_op->mmap) {
-			addr = -ENODEV;
-			goto out;
-		}
-	}
-
-	/* Careful about overflows.. */
-	len = PAGE_ALIGN(len);
-	if (!len || len > TASK_SIZE) {
-		addr = -EINVAL;
-		goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-out:	if (file)
-		fput(file);
-	return addr;
-}
-
 /*
  * mmap2() is like mmap() except that the offset is expressed in units
  * of PAGE_SIZE (instead of bytes).  This allows to mmap2() (pieces
@@ -226,7 +149,7 @@ out:	if (file)
 asmlinkage unsigned long
 sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
 {
-	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
+	addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 	if (!IS_ERR((void *) addr))
 		force_successful_syscall_return();
 	return addr;
@@ -238,7 +161,7 @@ sys_mmap (unsigned long addr, unsigned l
 	if (offset_in_page(off) != 0)
 		return -EINVAL;
 
-	addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+	addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 	if (!IS_ERR((void *) addr))
 		force_successful_syscall_return();
 	return addr;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/time.c linux-libre-2.6.33-gnu1/arch/ia64/kernel/time.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -473,7 +473,7 @@ void update_vsyscall_tz(void)
 {
 }
 
-void update_vsyscall(struct timespec *wall, struct clocksource *c)
+void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
 {
         unsigned long flags;
 
@@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wa
 
         /* copy fsyscall clock data */
         fsyscall_gtod_data.clk_mask = c->mask;
-        fsyscall_gtod_data.clk_mult = c->mult;
+        fsyscall_gtod_data.clk_mult = mult;
         fsyscall_gtod_data.clk_shift = c->shift;
         fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio;
         fsyscall_gtod_data.clk_cycle_last = c->cycle_last;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/ia64/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/ia64/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -166,6 +166,12 @@ SECTIONS
 	}
 #endif
 
+#ifdef	CONFIG_SMP
+  . = ALIGN(PERCPU_PAGE_SIZE);
+  __cpu0_per_cpu = .;
+  . = . + PERCPU_PAGE_SIZE;	/* cpu0 per-cpu space */
+#endif
+
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
@@ -198,11 +204,6 @@ SECTIONS
   data : { } :data
   .data : AT(ADDR(.data) - LOAD_OFFSET)
 	{
-#ifdef	CONFIG_SMP
-  . = ALIGN(PERCPU_PAGE_SIZE);
-		__cpu0_per_cpu = .;
-  . = . + PERCPU_PAGE_SIZE;	/* cpu0 per-cpu space */
-#endif
 		INIT_TASK_DATA(PAGE_SIZE)
 		CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
 		READ_MOSTLY_DATA(SMP_CACHE_BYTES)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/asm-offsets.c linux-libre-2.6.33-gnu1/arch/ia64/kvm/asm-offsets.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/asm-offsets.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@
  *
  */
 
-#include <linux/autoconf.h>
 #include <linux/kvm_host.h>
 #include <linux/kbuild.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/kvm-ia64.c linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm-ia64.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/kvm-ia64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/kvm-ia64.c	2010-02-24 13:52:17.000000000 -0500
@@ -124,7 +124,7 @@ long ia64_pal_vp_create(u64 *vpd, u64 *h
 
 static  DEFINE_SPINLOCK(vp_lock);
 
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
 {
 	long  status;
 	long  tmp_base;
@@ -137,7 +137,7 @@ void kvm_arch_hardware_enable(void *garb
 	slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
 	local_irq_restore(saved_psr);
 	if (slot < 0)
-		return;
+		return -EINVAL;
 
 	spin_lock(&vp_lock);
 	status = ia64_pal_vp_init_env(kvm_vsa_base ?
@@ -145,7 +145,7 @@ void kvm_arch_hardware_enable(void *garb
 			__pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base);
 	if (status != 0) {
 		printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n");
-		return ;
+		return -EINVAL;
 	}
 
 	if (!kvm_vsa_base) {
@@ -154,6 +154,8 @@ void kvm_arch_hardware_enable(void *garb
 	}
 	spin_unlock(&vp_lock);
 	ia64_ptr_entry(0x3, slot);
+
+	return 0;
 }
 
 void kvm_arch_hardware_disable(void *garbage)
@@ -851,8 +853,7 @@ static int kvm_vm_ioctl_get_irqchip(stru
 	r = 0;
 	switch (chip->chip_id) {
 	case KVM_IRQCHIP_IOAPIC:
-		memcpy(&chip->chip.ioapic, ioapic_irqchip(kvm),
-				sizeof(struct kvm_ioapic_state));
+		r = kvm_get_ioapic(kvm, &chip->chip.ioapic);
 		break;
 	default:
 		r = -EINVAL;
@@ -868,9 +869,7 @@ static int kvm_vm_ioctl_set_irqchip(stru
 	r = 0;
 	switch (chip->chip_id) {
 	case KVM_IRQCHIP_IOAPIC:
-		memcpy(ioapic_irqchip(kvm),
-				&chip->chip.ioapic,
-				sizeof(struct kvm_ioapic_state));
+		r = kvm_set_ioapic(kvm, &chip->chip.ioapic);
 		break;
 	default:
 		r = -EINVAL;
@@ -944,7 +943,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
-	int r = -EINVAL;
+	int r = -ENOTTY;
 
 	switch (ioctl) {
 	case KVM_SET_MEMORY_REGION: {
@@ -985,10 +984,8 @@ long kvm_arch_vm_ioctl(struct file *filp
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
 			__s32 status;
-			mutex_lock(&kvm->irq_lock);
 			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 				    irq_event.irq, irq_event.level);
-			mutex_unlock(&kvm->irq_lock);
 			if (ioctl == KVM_IRQ_LINE_STATUS) {
 				irq_event.status = status;
 				if (copy_to_user(argp, &irq_event,
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/Makefile linux-libre-2.6.33-gnu1/arch/ia64/kvm/Makefile
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,7 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/k
 EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
 
 common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
-		coalesced_mmio.o irq_comm.o)
+		coalesced_mmio.o irq_comm.o assigned-dev.o)
 
 ifeq ($(CONFIG_IOMMU_API),y)
 common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/vcpu.h linux-libre-2.6.33-gnu1/arch/ia64/kvm/vcpu.h
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/vcpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/vcpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -388,6 +388,9 @@ static inline u64 __gpfn_is_io(u64 gpfn)
 #define _vmm_raw_spin_lock(x)	 do {}while(0)
 #define _vmm_raw_spin_unlock(x) do {}while(0)
 #else
+typedef struct {
+	volatile unsigned int lock;
+} vmm_spinlock_t;
 #define _vmm_raw_spin_lock(x)						\
 	do {								\
 		__u32 *ia64_spinlock_ptr = (__u32 *) (x);		\
@@ -405,12 +408,12 @@ static inline u64 __gpfn_is_io(u64 gpfn)
 
 #define _vmm_raw_spin_unlock(x)				\
 	do { barrier();				\
-		((spinlock_t *)x)->raw_lock.lock = 0; } \
+		((vmm_spinlock_t *)x)->lock = 0; } \
 while (0)
 #endif
 
-void vmm_spin_lock(spinlock_t *lock);
-void vmm_spin_unlock(spinlock_t *lock);
+void vmm_spin_lock(vmm_spinlock_t *lock);
+void vmm_spin_unlock(vmm_spinlock_t *lock);
 enum {
 	I_TLB = 1,
 	D_TLB = 2
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/vmm.c linux-libre-2.6.33-gnu1/arch/ia64/kvm/vmm.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/vmm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/vmm.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,12 +60,12 @@ static void __exit kvm_vmm_exit(void)
 	return ;
 }
 
-void vmm_spin_lock(spinlock_t *lock)
+void vmm_spin_lock(vmm_spinlock_t *lock)
 {
 	_vmm_raw_spin_lock(lock);
 }
 
-void vmm_spin_unlock(spinlock_t *lock)
+void vmm_spin_unlock(vmm_spinlock_t *lock)
 {
 	_vmm_raw_spin_unlock(lock);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/kvm/vtlb.c linux-libre-2.6.33-gnu1/arch/ia64/kvm/vtlb.c
--- linux-libre-2.6.32-gnu1/arch/ia64/kvm/vtlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/kvm/vtlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -182,7 +182,7 @@ void mark_pages_dirty(struct kvm_vcpu *v
 {
 	u64 i, dirty_pages = 1;
 	u64 base_gfn = (pte&_PAGE_PPN_MASK) >> PAGE_SHIFT;
-	spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa);
+	vmm_spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa);
 	void *dirty_bitmap = (void *)KVM_MEM_DIRTY_LOG_BASE;
 
 	dirty_pages <<= ps <= PAGE_SHIFT ? 0 : ps - PAGE_SHIFT;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/Makefile linux-libre-2.6.33-gnu1/arch/ia64/Makefile
--- linux-libre-2.6.32-gnu1/arch/ia64/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -103,4 +103,4 @@ archprepare: make_nr_irqs_h FORCE
 PHONY += make_nr_irqs_h FORCE
 
 make_nr_irqs_h: FORCE
-	$(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h
+	$(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/mm/contig.c linux-libre-2.6.33-gnu1/arch/ia64/mm/contig.c
--- linux-libre-2.6.32-gnu1/arch/ia64/mm/contig.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/mm/contig.c	2010-02-24 13:52:17.000000000 -0500
@@ -154,38 +154,99 @@ static void *cpu_data;
 void * __cpuinit
 per_cpu_init (void)
 {
-	int cpu;
-	static int first_time=1;
+	static bool first_time = true;
+	void *cpu0_data = __cpu0_per_cpu;
+	unsigned int cpu;
+
+	if (!first_time)
+		goto skip;
+	first_time = false;
 
 	/*
-	 * get_free_pages() cannot be used before cpu_init() done.  BSP
-	 * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
-	 * get_zeroed_page().
+	 * get_free_pages() cannot be used before cpu_init() done.
+	 * BSP allocates PERCPU_PAGE_SIZE bytes for all possible CPUs
+	 * to avoid that AP calls get_zeroed_page().
 	 */
-	if (first_time) {
-		void *cpu0_data = __cpu0_per_cpu;
+	for_each_possible_cpu(cpu) {
+		void *src = cpu == 0 ? cpu0_data : __phys_per_cpu_start;
 
-		first_time=0;
+		memcpy(cpu_data, src, __per_cpu_end - __per_cpu_start);
+		__per_cpu_offset[cpu] = (char *)cpu_data - __per_cpu_start;
+		per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
 
-		__per_cpu_offset[0] = (char *) cpu0_data - __per_cpu_start;
-		per_cpu(local_per_cpu_offset, 0) = __per_cpu_offset[0];
+		/*
+		 * percpu area for cpu0 is moved from the __init area
+		 * which is setup by head.S and used till this point.
+		 * Update ar.k3.  This move is ensures that percpu
+		 * area for cpu0 is on the correct node and its
+		 * virtual address isn't insanely far from other
+		 * percpu areas which is important for congruent
+		 * percpu allocator.
+		 */
+		if (cpu == 0)
+			ia64_set_kr(IA64_KR_PER_CPU_DATA, __pa(cpu_data) -
+				    (unsigned long)__per_cpu_start);
 
-		for (cpu = 1; cpu < NR_CPUS; cpu++) {
-			memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
-			__per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
-			cpu_data += PERCPU_PAGE_SIZE;
-			per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
-		}
+		cpu_data += PERCPU_PAGE_SIZE;
 	}
+skip:
 	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
 }
 
 static inline void
 alloc_per_cpu_data(void)
 {
-	cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS-1,
+	cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * num_possible_cpus(),
 				   PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
 }
+
+/**
+ * setup_per_cpu_areas - setup percpu areas
+ *
+ * Arch code has already allocated and initialized percpu areas.  All
+ * this function has to do is to teach the determined layout to the
+ * dynamic percpu allocator, which happens to be more complex than
+ * creating whole new ones using helpers.
+ */
+void __init
+setup_per_cpu_areas(void)
+{
+	struct pcpu_alloc_info *ai;
+	struct pcpu_group_info *gi;
+	unsigned int cpu;
+	ssize_t static_size, reserved_size, dyn_size;
+	int rc;
+
+	ai = pcpu_alloc_alloc_info(1, num_possible_cpus());
+	if (!ai)
+		panic("failed to allocate pcpu_alloc_info");
+	gi = &ai->groups[0];
+
+	/* units are assigned consecutively to possible cpus */
+	for_each_possible_cpu(cpu)
+		gi->cpu_map[gi->nr_units++] = cpu;
+
+	/* set parameters */
+	static_size = __per_cpu_end - __per_cpu_start;
+	reserved_size = PERCPU_MODULE_RESERVE;
+	dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size;
+	if (dyn_size < 0)
+		panic("percpu area overflow static=%zd reserved=%zd\n",
+		      static_size, reserved_size);
+
+	ai->static_size		= static_size;
+	ai->reserved_size	= reserved_size;
+	ai->dyn_size		= dyn_size;
+	ai->unit_size		= PERCPU_PAGE_SIZE;
+	ai->atom_size		= PAGE_SIZE;
+	ai->alloc_size		= PERCPU_PAGE_SIZE;
+
+	rc = pcpu_setup_first_chunk(ai, __per_cpu_start + __per_cpu_offset[0]);
+	if (rc)
+		panic("failed to setup percpu area (err=%d)", rc);
+
+	pcpu_free_alloc_info(ai);
+}
 #else
 #define alloc_per_cpu_data() do { } while (0)
 #endif /* CONFIG_SMP */
@@ -270,8 +331,8 @@ paging_init (void)
 
 		map_size = PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) *
 			sizeof(struct page));
-		vmalloc_end -= map_size;
-		vmem_map = (struct page *) vmalloc_end;
+		VMALLOC_END -= map_size;
+		vmem_map = (struct page *) VMALLOC_END;
 		efi_memmap_walk(create_mem_map_page_table, NULL);
 
 		/*
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/mm/discontig.c linux-libre-2.6.33-gnu1/arch/ia64/mm/discontig.c
--- linux-libre-2.6.32-gnu1/arch/ia64/mm/discontig.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/mm/discontig.c	2010-02-24 13:52:17.000000000 -0500
@@ -143,22 +143,120 @@ static void *per_cpu_node_setup(void *cp
 	int cpu;
 
 	for_each_possible_early_cpu(cpu) {
-		if (cpu == 0) {
-			void *cpu0_data = __cpu0_per_cpu;
-			__per_cpu_offset[cpu] = (char*)cpu0_data -
-				__per_cpu_start;
-		} else if (node == node_cpuid[cpu].nid) {
-			memcpy(__va(cpu_data), __phys_per_cpu_start,
-			       __per_cpu_end - __per_cpu_start);
-			__per_cpu_offset[cpu] = (char*)__va(cpu_data) -
-				__per_cpu_start;
-			cpu_data += PERCPU_PAGE_SIZE;
-		}
+		void *src = cpu == 0 ? __cpu0_per_cpu : __phys_per_cpu_start;
+
+		if (node != node_cpuid[cpu].nid)
+			continue;
+
+		memcpy(__va(cpu_data), src, __per_cpu_end - __per_cpu_start);
+		__per_cpu_offset[cpu] = (char *)__va(cpu_data) -
+			__per_cpu_start;
+
+		/*
+		 * percpu area for cpu0 is moved from the __init area
+		 * which is setup by head.S and used till this point.
+		 * Update ar.k3.  This move is ensures that percpu
+		 * area for cpu0 is on the correct node and its
+		 * virtual address isn't insanely far from other
+		 * percpu areas which is important for congruent
+		 * percpu allocator.
+		 */
+		if (cpu == 0)
+			ia64_set_kr(IA64_KR_PER_CPU_DATA,
+				    (unsigned long)cpu_data -
+				    (unsigned long)__per_cpu_start);
+
+		cpu_data += PERCPU_PAGE_SIZE;
 	}
 #endif
 	return cpu_data;
 }
 
+#ifdef CONFIG_SMP
+/**
+ * setup_per_cpu_areas - setup percpu areas
+ *
+ * Arch code has already allocated and initialized percpu areas.  All
+ * this function has to do is to teach the determined layout to the
+ * dynamic percpu allocator, which happens to be more complex than
+ * creating whole new ones using helpers.
+ */
+void __init setup_per_cpu_areas(void)
+{
+	struct pcpu_alloc_info *ai;
+	struct pcpu_group_info *uninitialized_var(gi);
+	unsigned int *cpu_map;
+	void *base;
+	unsigned long base_offset;
+	unsigned int cpu;
+	ssize_t static_size, reserved_size, dyn_size;
+	int node, prev_node, unit, nr_units, rc;
+
+	ai = pcpu_alloc_alloc_info(MAX_NUMNODES, nr_cpu_ids);
+	if (!ai)
+		panic("failed to allocate pcpu_alloc_info");
+	cpu_map = ai->groups[0].cpu_map;
+
+	/* determine base */
+	base = (void *)ULONG_MAX;
+	for_each_possible_cpu(cpu)
+		base = min(base,
+			   (void *)(__per_cpu_offset[cpu] + __per_cpu_start));
+	base_offset = (void *)__per_cpu_start - base;
+
+	/* build cpu_map, units are grouped by node */
+	unit = 0;
+	for_each_node(node)
+		for_each_possible_cpu(cpu)
+			if (node == node_cpuid[cpu].nid)
+				cpu_map[unit++] = cpu;
+	nr_units = unit;
+
+	/* set basic parameters */
+	static_size = __per_cpu_end - __per_cpu_start;
+	reserved_size = PERCPU_MODULE_RESERVE;
+	dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size;
+	if (dyn_size < 0)
+		panic("percpu area overflow static=%zd reserved=%zd\n",
+		      static_size, reserved_size);
+
+	ai->static_size		= static_size;
+	ai->reserved_size	= reserved_size;
+	ai->dyn_size		= dyn_size;
+	ai->unit_size		= PERCPU_PAGE_SIZE;
+	ai->atom_size		= PAGE_SIZE;
+	ai->alloc_size		= PERCPU_PAGE_SIZE;
+
+	/*
+	 * CPUs are put into groups according to node.  Walk cpu_map
+	 * and create new groups at node boundaries.
+	 */
+	prev_node = -1;
+	ai->nr_groups = 0;
+	for (unit = 0; unit < nr_units; unit++) {
+		cpu = cpu_map[unit];
+		node = node_cpuid[cpu].nid;
+
+		if (node == prev_node) {
+			gi->nr_units++;
+			continue;
+		}
+		prev_node = node;
+
+		gi = &ai->groups[ai->nr_groups++];
+		gi->nr_units		= 1;
+		gi->base_offset		= __per_cpu_offset[cpu] + base_offset;
+		gi->cpu_map		= &cpu_map[unit];
+	}
+
+	rc = pcpu_setup_first_chunk(ai, base);
+	if (rc)
+		panic("failed to setup percpu area (err=%d)", rc);
+
+	pcpu_free_alloc_info(ai);
+}
+#endif
+
 /**
  * fill_pernode - initialize pernode data.
  * @node: the node id.
@@ -352,7 +450,8 @@ static void __init initialize_pernode_da
 	/* Set the node_data pointer for each per-cpu struct */
 	for_each_possible_early_cpu(cpu) {
 		node = node_cpuid[cpu].nid;
-		per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data;
+		per_cpu(ia64_cpu_info, cpu).node_data =
+			mem_data[node].node_data;
 	}
 #else
 	{
@@ -360,7 +459,7 @@ static void __init initialize_pernode_da
 		cpu = 0;
 		node = node_cpuid[cpu].nid;
 		cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start +
-			((char *)&per_cpu__cpu_info - __per_cpu_start));
+			((char *)&per_cpu__ia64_cpu_info - __per_cpu_start));
 		cpu0_cpu_info->node_data = mem_data[node].node_data;
 	}
 #endif /* CONFIG_SMP */
@@ -666,9 +765,9 @@ void __init paging_init(void)
 	sparse_init();
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-	vmalloc_end -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) *
+	VMALLOC_END -= PAGE_ALIGN(ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) *
 		sizeof(struct page));
-	vmem_map = (struct page *) vmalloc_end;
+	vmem_map = (struct page *) VMALLOC_END;
 	efi_memmap_walk(create_mem_map_page_table, NULL);
 	printk("Virtual mem_map starts at 0x%p\n", vmem_map);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/mm/init.c linux-libre-2.6.33-gnu1/arch/ia64/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/ia64/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,8 +44,8 @@ extern void ia64_tlb_init (void);
 unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-unsigned long vmalloc_end = VMALLOC_END_INIT;
-EXPORT_SYMBOL(vmalloc_end);
+unsigned long VMALLOC_END = VMALLOC_END_INIT;
+EXPORT_SYMBOL(VMALLOC_END);
 struct page *vmem_map;
 EXPORT_SYMBOL(vmem_map);
 #endif
@@ -91,7 +91,7 @@ dma_mark_clean(void *addr, size_t size)
 inline void
 ia64_set_rbs_bot (void)
 {
-	unsigned long stack_size = current->signal->rlim[RLIMIT_STACK].rlim_max & -16;
+	unsigned long stack_size = rlimit_max(RLIMIT_STACK) & -16;
 
 	if (stack_size > MAX_USER_STACK_SIZE)
 		stack_size = MAX_USER_STACK_SIZE;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/mm/ioremap.c linux-libre-2.6.33-gnu1/arch/ia64/mm/ioremap.c
--- linux-libre-2.6.32-gnu1/arch/ia64/mm/ioremap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,12 @@ __ioremap (unsigned long phys_addr)
 }
 
 void __iomem *
+early_ioremap (unsigned long phys_addr, unsigned long size)
+{
+	return __ioremap(phys_addr);
+}
+
+void __iomem *
 ioremap (unsigned long phys_addr, unsigned long size)
 {
 	void __iomem *addr;
@@ -102,6 +108,11 @@ ioremap_nocache (unsigned long phys_addr
 EXPORT_SYMBOL(ioremap_nocache);
 
 void
+early_iounmap (volatile void __iomem *addr, unsigned long size)
+{
+}
+
+void
 iounmap (volatile void __iomem *addr)
 {
 	if (REGION_NUMBER(addr) == RGN_GATE)
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/mm/tlb.c linux-libre-2.6.33-gnu1/arch/ia64/mm/tlb.c
--- linux-libre-2.6.32-gnu1/arch/ia64/mm/tlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,7 @@ DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
 DEFINE_PER_CPU(u8, ia64_tr_num);  /*Number of TR slots in current processor*/
 DEFINE_PER_CPU(u8, ia64_tr_used); /*Max Slot number used by kernel*/
 
-struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX];
+struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
 
 /*
  * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
@@ -429,10 +429,16 @@ int ia64_itr_entry(u64 target_mask, u64
 	struct ia64_tr_entry *p;
 	int cpu = smp_processor_id();
 
+	if (!ia64_idtrs[cpu]) {
+		ia64_idtrs[cpu] = kmalloc(2 * IA64_TR_ALLOC_MAX *
+				sizeof (struct ia64_tr_entry), GFP_KERNEL);
+		if (!ia64_idtrs[cpu])
+			return -ENOMEM;
+	}
 	r = -EINVAL;
 	/*Check overlap with existing TR entries*/
 	if (target_mask & 0x1) {
-		p = &__per_cpu_idtrs[cpu][0][0];
+		p = ia64_idtrs[cpu];
 		for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
 								i++, p++) {
 			if (p->pte & 0x1)
@@ -444,7 +450,7 @@ int ia64_itr_entry(u64 target_mask, u64
 		}
 	}
 	if (target_mask & 0x2) {
-		p = &__per_cpu_idtrs[cpu][1][0];
+		p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX;
 		for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
 								i++, p++) {
 			if (p->pte & 0x1)
@@ -459,16 +465,16 @@ int ia64_itr_entry(u64 target_mask, u64
 	for (i = IA64_TR_ALLOC_BASE; i < per_cpu(ia64_tr_num, cpu); i++) {
 		switch (target_mask & 0x3) {
 		case 1:
-			if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1))
+			if (!((ia64_idtrs[cpu] + i)->pte & 0x1))
 				goto found;
 			continue;
 		case 2:
-			if (!(__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+			if (!((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
 				goto found;
 			continue;
 		case 3:
-			if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1) &&
-				!(__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+			if (!((ia64_idtrs[cpu] + i)->pte & 0x1) &&
+			    !((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
 				goto found;
 			continue;
 		default:
@@ -488,7 +494,7 @@ found:
 	if (target_mask & 0x1) {
 		ia64_itr(0x1, i, va, pte, log_size);
 		ia64_srlz_i();
-		p = &__per_cpu_idtrs[cpu][0][i];
+		p = ia64_idtrs[cpu] + i;
 		p->ifa = va;
 		p->pte = pte;
 		p->itir = log_size << 2;
@@ -497,7 +503,7 @@ found:
 	if (target_mask & 0x2) {
 		ia64_itr(0x2, i, va, pte, log_size);
 		ia64_srlz_i();
-		p = &__per_cpu_idtrs[cpu][1][i];
+		p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i;
 		p->ifa = va;
 		p->pte = pte;
 		p->itir = log_size << 2;
@@ -528,7 +534,7 @@ void ia64_ptr_entry(u64 target_mask, int
 		return;
 
 	if (target_mask & 0x1) {
-		p = &__per_cpu_idtrs[cpu][0][slot];
+		p = ia64_idtrs[cpu] + slot;
 		if ((p->pte&0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
 			p->pte = 0;
 			ia64_ptr(0x1, p->ifa, p->itir>>2);
@@ -537,7 +543,7 @@ void ia64_ptr_entry(u64 target_mask, int
 	}
 
 	if (target_mask & 0x2) {
-		p = &__per_cpu_idtrs[cpu][1][slot];
+		p = ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + slot;
 		if ((p->pte & 0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
 			p->pte = 0;
 			ia64_ptr(0x2, p->ifa, p->itir>>2);
@@ -546,8 +552,8 @@ void ia64_ptr_entry(u64 target_mask, int
 	}
 
 	for (i = per_cpu(ia64_tr_used, cpu); i >= IA64_TR_ALLOC_BASE; i--) {
-		if ((__per_cpu_idtrs[cpu][0][i].pte & 0x1) ||
-				(__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+		if (((ia64_idtrs[cpu] + i)->pte & 0x1) ||
+		    ((ia64_idtrs[cpu] + IA64_TR_ALLOC_MAX + i)->pte & 0x1))
 			break;
 	}
 	per_cpu(ia64_tr_used, cpu) = i;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/pci/pci.c linux-libre-2.6.33-gnu1/arch/ia64/pci/pci.c
--- linux-libre-2.6.32-gnu1/arch/ia64/pci/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,6 +131,7 @@ alloc_pci_controller (int seg)
 }
 
 struct pci_root_info {
+	struct acpi_device *bridge;
 	struct pci_controller *controller;
 	char *name;
 };
@@ -297,9 +298,20 @@ static __devinit acpi_status add_window(
 	window->offset = offset;
 
 	if (insert_resource(root, &window->resource)) {
-		printk(KERN_ERR "alloc 0x%llx-0x%llx from %s for %s failed\n",
-			window->resource.start, window->resource.end,
-			root->name, info->name);
+		dev_err(&info->bridge->dev,
+			"can't allocate host bridge window %pR\n",
+			&window->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);
+		else
+			dev_info(&info->bridge->dev,
+				 "host bridge window %pR\n",
+				 &window->resource);
 	}
 
 	return AE_OK;
@@ -319,8 +331,9 @@ pcibios_setup_root_windows(struct pci_bu
 		    (res->end - res->start < 16))
 			continue;
 		if (j >= PCI_BUS_NUM_RESOURCES) {
-			printk("Ignoring range [%#llx-%#llx] (%lx)\n",
-					res->start, res->end, res->flags);
+			dev_warn(&bus->dev,
+				 "ignoring host bridge window %pR (no space)\n",
+				 res);
 			continue;
 		}
 		bus->resource[j++] = res;
@@ -364,6 +377,7 @@ pci_acpi_scan_root(struct acpi_device *d
 			goto out3;
 
 		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,
@@ -720,9 +734,6 @@ int ia64_pci_legacy_write(struct pci_bus
 	return ret;
 }
 
-/* It's defined in drivers/pci/pci.c */
-extern u8 pci_cache_line_size;
-
 /**
  * set_pci_cacheline_size - determine cacheline size for PCI devices
  *
@@ -731,7 +742,7 @@ extern u8 pci_cache_line_size;
  *
  * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
  */
-static void __init set_pci_cacheline_size(void)
+static void __init set_pci_dfl_cacheline_size(void)
 {
 	unsigned long levels, unique_caches;
 	long status;
@@ -751,7 +762,7 @@ static void __init set_pci_cacheline_siz
 			"(status=%ld)\n", __func__, status);
 		return;
 	}
-	pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
+	pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
 }
 
 u64 ia64_dma_get_required_mask(struct device *dev)
@@ -782,7 +793,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask)
 
 static int __init pcibios_init(void)
 {
-	set_pci_cacheline_size();
+	set_pci_dfl_cacheline_size();
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/io_acpi_init.c linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_acpi_init.c
--- linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/io_acpi_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/io_acpi_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -390,7 +390,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *
 	pcidev_match.handle = NULL;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
-			    find_matching_device, &pcidev_match, NULL);
+			    find_matching_device, NULL, &pcidev_match, NULL);
 
 	if (!pcidev_match.handle) {
 		printk(KERN_ERR
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/setup.c linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,7 +71,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
 DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
 EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
 
-DEFINE_PER_CPU(short [MAX_COMPACT_NODES], __sn_cnodeid_to_nasid);
+DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
 EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
 
 DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- linux-libre-2.6.32-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -496,13 +496,13 @@ static int sn2_ptc_seq_show(struct seq_f
 		seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
 				stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
 				stat->deadlocks,
-				1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
-				1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
-				1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec,
+				1000 * stat->lock_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
+				1000 * stat->shub_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
+				1000 * stat->shub_itc_clocks_max / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
 				stat->shub_ptc_flushes_not_my_mm,
 				stat->deadlocks2,
 				stat->shub_ipi_flushes,
-				1000 * stat->shub_ipi_flushes_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec);
+				1000 * stat->shub_ipi_flushes_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/sn/pci/tioca_provider.c linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioca_provider.c
--- linux-libre-2.6.32-gnu1/arch/ia64/sn/pci/tioca_provider.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/sn/pci/tioca_provider.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/bitmap.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
@@ -369,7 +370,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64
 static dma_addr_t
 tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size)
 {
-	int i, ps, ps_shift, entry, entries, mapsize, last_entry;
+	int ps, ps_shift, entry, entries, mapsize;
 	u64 xio_addr, end_xio_addr;
 	struct tioca_common *tioca_common;
 	struct tioca_kernel *tioca_kern;
@@ -410,23 +411,13 @@ tioca_dma_mapped(struct pci_dev *pdev, u
 	map = tioca_kern->ca_pcigart_pagemap;
 	mapsize = tioca_kern->ca_pcigart_entries;
 
-	entry = find_first_zero_bit(map, mapsize);
-	while (entry < mapsize) {
-		last_entry = find_next_bit(map, mapsize, entry);
-
-		if (last_entry - entry >= entries)
-			break;
-
-		entry = find_next_zero_bit(map, mapsize, last_entry);
-	}
-
-	if (entry > mapsize) {
+	entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0);
+	if (entry >= mapsize) {
 		kfree(ca_dmamap);
 		goto map_return;
 	}
 
-	for (i = 0; i < entries; i++)
-		set_bit(entry + i, map);
+	bitmap_set(map, entry, entries);
 
 	bus_addr = tioca_kern->ca_pciap_base + (entry * ps);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/xen/irq_xen.c linux-libre-2.6.33-gnu1/arch/ia64/xen/irq_xen.c
--- linux-libre-2.6.32-gnu1/arch/ia64/xen/irq_xen.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/xen/irq_xen.c	2010-02-24 13:52:17.000000000 -0500
@@ -63,19 +63,19 @@ xen_free_irq_vector(int vector)
 }
 
 
-static DEFINE_PER_CPU(int, timer_irq) = -1;
-static DEFINE_PER_CPU(int, ipi_irq) = -1;
-static DEFINE_PER_CPU(int, resched_irq) = -1;
-static DEFINE_PER_CPU(int, cmc_irq) = -1;
-static DEFINE_PER_CPU(int, cmcp_irq) = -1;
-static DEFINE_PER_CPU(int, cpep_irq) = -1;
+static DEFINE_PER_CPU(int, xen_timer_irq) = -1;
+static DEFINE_PER_CPU(int, xen_ipi_irq) = -1;
+static DEFINE_PER_CPU(int, xen_resched_irq) = -1;
+static DEFINE_PER_CPU(int, xen_cmc_irq) = -1;
+static DEFINE_PER_CPU(int, xen_cmcp_irq) = -1;
+static DEFINE_PER_CPU(int, xen_cpep_irq) = -1;
 #define NAME_SIZE	15
-static DEFINE_PER_CPU(char[NAME_SIZE], timer_name);
-static DEFINE_PER_CPU(char[NAME_SIZE], ipi_name);
-static DEFINE_PER_CPU(char[NAME_SIZE], resched_name);
-static DEFINE_PER_CPU(char[NAME_SIZE], cmc_name);
-static DEFINE_PER_CPU(char[NAME_SIZE], cmcp_name);
-static DEFINE_PER_CPU(char[NAME_SIZE], cpep_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_timer_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_ipi_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_resched_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_cmc_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_cmcp_name);
+static DEFINE_PER_CPU(char[NAME_SIZE], xen_cpep_name);
 #undef NAME_SIZE
 
 struct saved_irq {
@@ -144,64 +144,64 @@ __xen_register_percpu_irq(unsigned int c
 	if (xen_slab_ready) {
 		switch (vec) {
 		case IA64_TIMER_VECTOR:
-			snprintf(per_cpu(timer_name, cpu),
-				 sizeof(per_cpu(timer_name, cpu)),
+			snprintf(per_cpu(xen_timer_name, cpu),
+				 sizeof(per_cpu(xen_timer_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
 				action->handler, action->flags,
-				per_cpu(timer_name, cpu), action->dev_id);
-			per_cpu(timer_irq, cpu) = irq;
+				per_cpu(xen_timer_name, cpu), action->dev_id);
+			per_cpu(xen_timer_irq, cpu) = irq;
 			break;
 		case IA64_IPI_RESCHEDULE:
-			snprintf(per_cpu(resched_name, cpu),
-				 sizeof(per_cpu(resched_name, cpu)),
+			snprintf(per_cpu(xen_resched_name, cpu),
+				 sizeof(per_cpu(xen_resched_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, cpu,
 				action->handler, action->flags,
-				per_cpu(resched_name, cpu), action->dev_id);
-			per_cpu(resched_irq, cpu) = irq;
+				per_cpu(xen_resched_name, cpu), action->dev_id);
+			per_cpu(xen_resched_irq, cpu) = irq;
 			break;
 		case IA64_IPI_VECTOR:
-			snprintf(per_cpu(ipi_name, cpu),
-				 sizeof(per_cpu(ipi_name, cpu)),
+			snprintf(per_cpu(xen_ipi_name, cpu),
+				 sizeof(per_cpu(xen_ipi_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_ipi_to_irqhandler(XEN_IPI_VECTOR, cpu,
 				action->handler, action->flags,
-				per_cpu(ipi_name, cpu), action->dev_id);
-			per_cpu(ipi_irq, cpu) = irq;
+				per_cpu(xen_ipi_name, cpu), action->dev_id);
+			per_cpu(xen_ipi_irq, cpu) = irq;
 			break;
 		case IA64_CMC_VECTOR:
-			snprintf(per_cpu(cmc_name, cpu),
-				 sizeof(per_cpu(cmc_name, cpu)),
+			snprintf(per_cpu(xen_cmc_name, cpu),
+				 sizeof(per_cpu(xen_cmc_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu,
-						      action->handler,
-						      action->flags,
-						      per_cpu(cmc_name, cpu),
-						      action->dev_id);
-			per_cpu(cmc_irq, cpu) = irq;
+						action->handler,
+						action->flags,
+						per_cpu(xen_cmc_name, cpu),
+						action->dev_id);
+			per_cpu(xen_cmc_irq, cpu) = irq;
 			break;
 		case IA64_CMCP_VECTOR:
-			snprintf(per_cpu(cmcp_name, cpu),
-				 sizeof(per_cpu(cmcp_name, cpu)),
+			snprintf(per_cpu(xen_cmcp_name, cpu),
+				 sizeof(per_cpu(xen_cmcp_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_ipi_to_irqhandler(XEN_CMCP_VECTOR, cpu,
-						     action->handler,
-						     action->flags,
-						     per_cpu(cmcp_name, cpu),
-						     action->dev_id);
-			per_cpu(cmcp_irq, cpu) = irq;
+						action->handler,
+						action->flags,
+						per_cpu(xen_cmcp_name, cpu),
+						action->dev_id);
+			per_cpu(xen_cmcp_irq, cpu) = irq;
 			break;
 		case IA64_CPEP_VECTOR:
-			snprintf(per_cpu(cpep_name, cpu),
-				 sizeof(per_cpu(cpep_name, cpu)),
+			snprintf(per_cpu(xen_cpep_name, cpu),
+				 sizeof(per_cpu(xen_cpep_name, cpu)),
 				 "%s%d", action->name, cpu);
 			irq = bind_ipi_to_irqhandler(XEN_CPEP_VECTOR, cpu,
-						     action->handler,
-						     action->flags,
-						     per_cpu(cpep_name, cpu),
-						     action->dev_id);
-			per_cpu(cpep_irq, cpu) = irq;
+						action->handler,
+						action->flags,
+						per_cpu(xen_cpep_name, cpu),
+						action->dev_id);
+			per_cpu(xen_cpep_irq, cpu) = irq;
 			break;
 		case IA64_CPE_VECTOR:
 		case IA64_MCA_RENDEZ_VECTOR:
@@ -275,30 +275,33 @@ unbind_evtchn_callback(struct notifier_b
 
 	if (action == CPU_DEAD) {
 		/* Unregister evtchn.  */
-		if (per_cpu(cpep_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(cpep_irq, cpu), NULL);
-			per_cpu(cpep_irq, cpu) = -1;
+		if (per_cpu(xen_cpep_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_cpep_irq, cpu),
+					       NULL);
+			per_cpu(xen_cpep_irq, cpu) = -1;
 		}
-		if (per_cpu(cmcp_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(cmcp_irq, cpu), NULL);
-			per_cpu(cmcp_irq, cpu) = -1;
+		if (per_cpu(xen_cmcp_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_cmcp_irq, cpu),
+					       NULL);
+			per_cpu(xen_cmcp_irq, cpu) = -1;
 		}
-		if (per_cpu(cmc_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(cmc_irq, cpu), NULL);
-			per_cpu(cmc_irq, cpu) = -1;
+		if (per_cpu(xen_cmc_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_cmc_irq, cpu), NULL);
+			per_cpu(xen_cmc_irq, cpu) = -1;
 		}
-		if (per_cpu(ipi_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(ipi_irq, cpu), NULL);
-			per_cpu(ipi_irq, cpu) = -1;
+		if (per_cpu(xen_ipi_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_ipi_irq, cpu), NULL);
+			per_cpu(xen_ipi_irq, cpu) = -1;
 		}
-		if (per_cpu(resched_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(resched_irq, cpu),
-						NULL);
-			per_cpu(resched_irq, cpu) = -1;
+		if (per_cpu(xen_resched_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu),
+					       NULL);
+			per_cpu(xen_resched_irq, cpu) = -1;
 		}
-		if (per_cpu(timer_irq, cpu) >= 0) {
-			unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
-			per_cpu(timer_irq, cpu) = -1;
+		if (per_cpu(xen_timer_irq, cpu) >= 0) {
+			unbind_from_irqhandler(per_cpu(xen_timer_irq, cpu),
+					       NULL);
+			per_cpu(xen_timer_irq, cpu) = -1;
 		}
 	}
 	return NOTIFY_OK;
diff -druNp linux-libre-2.6.32-gnu1/arch/ia64/xen/time.c linux-libre-2.6.33-gnu1/arch/ia64/xen/time.c
--- linux-libre-2.6.32-gnu1/arch/ia64/xen/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/ia64/xen/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,15 +34,15 @@
 
 #include "../kernel/fsyscall_gtod_data.h"
 
-DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
-DEFINE_PER_CPU(unsigned long, processed_stolen_time);
-DEFINE_PER_CPU(unsigned long, processed_blocked_time);
+static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
+static DEFINE_PER_CPU(unsigned long, xen_stolen_time);
+static DEFINE_PER_CPU(unsigned long, xen_blocked_time);
 
 /* taken from i386/kernel/time-xen.c */
 static void xen_init_missing_ticks_accounting(int cpu)
 {
 	struct vcpu_register_runstate_memory_area area;
-	struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
+	struct vcpu_runstate_info *runstate = &per_cpu(xen_runstate, cpu);
 	int rc;
 
 	memset(runstate, 0, sizeof(*runstate));
@@ -52,8 +52,8 @@ static void xen_init_missing_ticks_accou
 				&area);
 	WARN_ON(rc && rc != -ENOSYS);
 
-	per_cpu(processed_blocked_time, cpu) = runstate->time[RUNSTATE_blocked];
-	per_cpu(processed_stolen_time, cpu) = runstate->time[RUNSTATE_runnable]
+	per_cpu(xen_blocked_time, cpu) = runstate->time[RUNSTATE_blocked];
+	per_cpu(xen_stolen_time, cpu) = runstate->time[RUNSTATE_runnable]
 					    + runstate->time[RUNSTATE_offline];
 }
 
@@ -68,7 +68,7 @@ static void get_runstate_snapshot(struct
 
 	BUG_ON(preemptible());
 
-	state = &__get_cpu_var(runstate);
+	state = &__get_cpu_var(xen_runstate);
 
 	/*
 	 * The runstate info is always updated by the hypervisor on
@@ -103,12 +103,12 @@ consider_steal_time(unsigned long new_it
 	 * This function just checks and reject this effect.
 	 */
 	if (!time_after_eq(runstate.time[RUNSTATE_blocked],
-			   per_cpu(processed_blocked_time, cpu)))
+			   per_cpu(xen_blocked_time, cpu)))
 		blocked = 0;
 
 	if (!time_after_eq(runstate.time[RUNSTATE_runnable] +
 			   runstate.time[RUNSTATE_offline],
-			   per_cpu(processed_stolen_time, cpu)))
+			   per_cpu(xen_stolen_time, cpu)))
 		stolen = 0;
 
 	if (!time_after(delta_itm + new_itm, ia64_get_itc()))
@@ -147,8 +147,8 @@ consider_steal_time(unsigned long new_it
 		} else {
 			local_cpu_data->itm_next = delta_itm + new_itm;
 		}
-		per_cpu(processed_stolen_time, cpu) += NS_PER_TICK * stolen;
-		per_cpu(processed_blocked_time, cpu) += NS_PER_TICK * blocked;
+		per_cpu(xen_stolen_time, cpu) += NS_PER_TICK * stolen;
+		per_cpu(xen_blocked_time, cpu) += NS_PER_TICK * blocked;
 	}
 	return delta_itm;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/Kconfig linux-libre-2.6.33-gnu1/arch/Kconfig
--- linux-libre-2.6.32-gnu1/arch/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -83,6 +83,13 @@ config KRETPROBES
 	def_bool y
 	depends on KPROBES && HAVE_KRETPROBES
 
+config USER_RETURN_NOTIFIER
+	bool
+	depends on HAVE_USER_RETURN_NOTIFIER
+	help
+	  Provide a kernel-internal notification when a cpu is about to
+	  switch to user mode.
+
 config HAVE_IOREMAP_PROT
 	bool
 
@@ -126,4 +133,11 @@ config HAVE_DMA_API_DEBUG
 config HAVE_DEFAULT_NO_SPIN_MUTEXES
 	bool
 
+config HAVE_HW_BREAKPOINT
+	bool
+	depends on PERF_EVENTS
+
+config HAVE_USER_RETURN_NOTIFIER
+	bool
+
 source "kernel/gcov/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/m32r/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/m32r/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@ extern void _flush_cache_copyback_all(vo
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
@@ -33,6 +34,7 @@ extern void smp_flush_cache_all(void);
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
@@ -46,6 +48,7 @@ extern void smp_flush_cache_all(void);
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/m32r/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/m32r/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -102,7 +102,6 @@ typedef elf_fpreg_t elf_fpregset_t;
  */
 #define ELF_PLAT_INIT(_r, load_addr)	(_r)->r0 = 0
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/m32r/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/m32r/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_M32R_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/m32r/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/m32r/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,19 +24,19 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define __raw_spin_is_locked(x)		(*(volatile int *)(&(x)->slock) <= 0)
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_spin_unlock_wait(x) \
-		do { cpu_relax(); } while (__raw_spin_is_locked(x))
+#define arch_spin_is_locked(x)		(*(volatile int *)(&(x)->slock) <= 0)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_unlock_wait(x) \
+		do { cpu_relax(); } while (arch_spin_is_locked(x))
 
 /**
- * __raw_spin_trylock - Try spin lock and return a result
+ * arch_spin_trylock - Try spin lock and return a result
  * @lock: Pointer to the lock variable
  *
- * __raw_spin_trylock() tries to get the lock and returns a result.
+ * arch_spin_trylock() tries to get the lock and returns a result.
  * On the m32r, the result value is 1 (= Success) or 0 (= Failure).
  */
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	int oldval;
 	unsigned long tmp1, tmp2;
@@ -50,7 +50,7 @@ static inline int __raw_spin_trylock(raw
 	 * }
 	 */
 	__asm__ __volatile__ (
-		"# __raw_spin_trylock		\n\t"
+		"# arch_spin_trylock		\n\t"
 		"ldi	%1, #0;			\n\t"
 		"mvfc	%2, psw;		\n\t"
 		"clrpsw	#0x40 -> nop;		\n\t"
@@ -69,7 +69,7 @@ static inline int __raw_spin_trylock(raw
 	return (oldval > 0);
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned long tmp0, tmp1;
 
@@ -84,7 +84,7 @@ static inline void __raw_spin_lock(raw_s
 	 * }
 	 */
 	__asm__ __volatile__ (
-		"# __raw_spin_lock		\n\t"
+		"# arch_spin_lock		\n\t"
 		".fillinsn			\n"
 		"1:				\n\t"
 		"mvfc	%1, psw;		\n\t"
@@ -111,7 +111,7 @@ static inline void __raw_spin_lock(raw_s
 	);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	mb();
 	lock->slock = 1;
@@ -140,15 +140,15 @@ static inline void __raw_spin_unlock(raw
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_read_can_lock(x) ((int)(x)->lock > 0)
+#define arch_read_can_lock(x) ((int)(x)->lock > 0)
 
 /**
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
+#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp0, tmp1;
 
@@ -199,7 +199,7 @@ static inline void __raw_read_lock(raw_r
 	);
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp0, tmp1, tmp2;
 
@@ -252,7 +252,7 @@ static inline void __raw_write_lock(raw_
 	);
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp0, tmp1;
 
@@ -274,7 +274,7 @@ static inline void __raw_read_unlock(raw
 	);
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp0, tmp1, tmp2;
 
@@ -298,7 +298,7 @@ static inline void __raw_write_unlock(ra
 	);
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *lock)
+static inline int arch_read_trylock(arch_rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t*)lock;
 	if (atomic_dec_return(count) >= 0)
@@ -307,7 +307,7 @@ static inline int __raw_read_trylock(raw
 	return 0;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *lock)
+static inline int arch_write_trylock(arch_rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t *)lock;
 	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
@@ -316,11 +316,11 @@ static inline int __raw_write_trylock(ra
 	return 0;
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif	/* _ASM_M32R_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/m32r/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/m32r/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,17 +7,17 @@
 
 typedef struct {
 	volatile int slock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 1 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 1 }
 
 typedef struct {
 	volatile int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
 #define RW_LOCK_BIAS			0x01000000
 #define RW_LOCK_BIAS_STR		"0x01000000"
 
-#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
+#define __ARCH_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
 
 #endif /* _ASM_M32R_SPINLOCK_TYPES_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/kernel/irq.c linux-libre-2.6.33-gnu1/arch/m32r/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/m32r/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -59,7 +59,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/kernel/syscall_table.S linux-libre-2.6.33-gnu1/arch/m32r/kernel/syscall_table.S
--- linux-libre-2.6.32-gnu1/arch/m32r/kernel/syscall_table.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/kernel/syscall_table.S	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall		/* streams2 */
 	.long sys_vfork			/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64		/* 195 */
diff -druNp linux-libre-2.6.32-gnu1/arch/m32r/kernel/sys_m32r.c linux-libre-2.6.33-gnu1/arch/m32r/kernel/sys_m32r.c
--- linux-libre-2.6.32-gnu1/arch/m32r/kernel/sys_m32r.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m32r/kernel/sys_m32r.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,30 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
 	return oldval;
 }
 
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/ifpsp060/src/fpsp.S linux-libre-2.6.33-gnu1/arch/m68k/ifpsp060/src/fpsp.S
--- linux-libre-2.6.32-gnu1/arch/m68k/ifpsp060/src/fpsp.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/ifpsp060/src/fpsp.S	2010-02-24 13:52:17.000000000 -0500
@@ -753,7 +753,7 @@ fovfl_ovfl_on:
 
 	bra.l		_real_ovfl
 
-# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 fovfl_inex_on:
 
@@ -1015,7 +1015,7 @@ funfl_unfl_on2:
 
 	bra.l		_real_unfl
 
-# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 funfl_inex_on:
 
@@ -2963,7 +2963,7 @@ iea_disabled:
 
 	tst.w		%d0			# is instr fmovm?
 	bmi.b		iea_dis_fmovm		# yes
-# instruction is using an extended precision immediate operand. therefore,
+# instruction is using an extended precision immediate operand. Therefore,
 # the total instruction length is 16 bytes.
 iea_dis_immed:
 	mov.l		&0x10,%d0		# 16 bytes of instruction
@@ -9624,7 +9624,7 @@ sok_dnrm:
 	bge.b		sok_norm2		# thank goodness no
 
 # the multiply factor that we're trying to create should be a denorm
-# for the multiply to work. therefore, we're going to actually do a
+# for the multiply to work. Therefore, we're going to actually do a
 # multiply with a denorm which will cause an unimplemented data type
 # exception to be put into the machine which will be caught and corrected
 # later. we don't do this with the DENORMs above because this method
@@ -12216,7 +12216,7 @@ fin_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow or inexact is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fin_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -12746,7 +12746,7 @@ fdiv_zero_load_p:
 
 #
 # The destination was In Range and the source was a ZERO. The result,
-# therefore, is an INF w/ the proper sign.
+# Therefore, is an INF w/ the proper sign.
 # So, determine the sign and return a new INF (w/ the j-bit cleared).
 #
 	global		fdiv_inf_load		# global for fsgldiv
@@ -12996,7 +12996,7 @@ fneg_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fneg_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -13611,7 +13611,7 @@ fabs_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fabs_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -14973,7 +14973,7 @@ fadd_zero_2:
 
 #
 # the ZEROes have opposite signs:
-# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
+# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
 # - -ZERO is returned in the case of RM.
 #
 fadd_zero_2_chk_rm:
@@ -15425,7 +15425,7 @@ fsub_zero_2:
 
 #
 # the ZEROes have the same signs:
-# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
+# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
 # - -ZERO is returned in the case of RM.
 #
 fsub_zero_2_chk_rm:
@@ -15693,7 +15693,7 @@ fsqrt_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fsqrt_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -21000,7 +21000,7 @@ fout_pack_type:
 	tst.l		%d0
 	bne.b		fout_pack_set
 # "mantissa" is all zero which means that the answer is zero. but, the '040
-# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
+# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
 # if the mantissa is zero, I will zero the exponent, too.
 # the question now is whether the exponents sign bit is allowed to be non-zero
 # for a zero, also...
@@ -21743,7 +21743,7 @@ denorm_set_stky:
 	rts
 
 #									#
-# dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
+# dnrm_lp(): normalize exponent/mantissa to specified threshold		#
 #									#
 # INPUT:								#
 #	%a0	   : points to the operand to be denormalized		#
@@ -22402,7 +22402,7 @@ unnorm_shift:
 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
 
 #
-# exponent would not go < 0. therefore, number stays normalized
+# exponent would not go < 0. Therefore, number stays normalized
 #
 	sub.w		%d0, %d1		# shift exponent value
 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/ifpsp060/src/pfpsp.S linux-libre-2.6.33-gnu1/arch/m68k/ifpsp060/src/pfpsp.S
--- linux-libre-2.6.32-gnu1/arch/m68k/ifpsp060/src/pfpsp.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/ifpsp060/src/pfpsp.S	2010-02-24 13:52:17.000000000 -0500
@@ -752,7 +752,7 @@ fovfl_ovfl_on:
 
 	bra.l		_real_ovfl
 
-# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 fovfl_inex_on:
 
@@ -1014,7 +1014,7 @@ funfl_unfl_on2:
 
 	bra.l		_real_unfl
 
-# undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
+# underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
 # we must jump to real_inex().
 funfl_inex_on:
 
@@ -2962,7 +2962,7 @@ iea_disabled:
 
 	tst.w		%d0			# is instr fmovm?
 	bmi.b		iea_dis_fmovm		# yes
-# instruction is using an extended precision immediate operand. therefore,
+# instruction is using an extended precision immediate operand. Therefore,
 # the total instruction length is 16 bytes.
 iea_dis_immed:
 	mov.l		&0x10,%d0		# 16 bytes of instruction
@@ -5865,7 +5865,7 @@ denorm_set_stky:
 	rts
 
 #									#
-# dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
+# dnrm_lp(): normalize exponent/mantissa to specified threshold		#
 #									#
 # INPUT:								#
 #	%a0	   : points to the operand to be denormalized		#
@@ -6524,7 +6524,7 @@ unnorm_shift:
 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
 
 #
-# exponent would not go < 0. therefore, number stays normalized
+# exponent would not go < 0. Therefore, number stays normalized
 #
 	sub.w		%d0, %d1		# shift exponent value
 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
@@ -7901,7 +7901,7 @@ fout_pack_type:
 	tst.l		%d0
 	bne.b		fout_pack_set
 # "mantissa" is all zero which means that the answer is zero. but, the '040
-# algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
+# algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
 # if the mantissa is zero, I will zero the exponent, too.
 # the question now is whether the exponents sign bit is allowed to be non-zero
 # for a zero, also...
@@ -8647,7 +8647,7 @@ fin_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow or inexact is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fin_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -9177,7 +9177,7 @@ fdiv_zero_load_p:
 
 #
 # The destination was In Range and the source was a ZERO. The result,
-# therefore, is an INF w/ the proper sign.
+# Therefore, is an INF w/ the proper sign.
 # So, determine the sign and return a new INF (w/ the j-bit cleared).
 #
 	global		fdiv_inf_load		# global for fsgldiv
@@ -9427,7 +9427,7 @@ fneg_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fneg_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -10042,7 +10042,7 @@ fabs_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fabs_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
@@ -11404,7 +11404,7 @@ fadd_zero_2:
 
 #
 # the ZEROes have opposite signs:
-# - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
+# - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
 # - -ZERO is returned in the case of RM.
 #
 fadd_zero_2_chk_rm:
@@ -11856,7 +11856,7 @@ fsub_zero_2:
 
 #
 # the ZEROes have the same signs:
-# - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
+# - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
 # - -ZERO is returned in the case of RM.
 #
 fsub_zero_2_chk_rm:
@@ -12124,7 +12124,7 @@ fsqrt_sd_unfl_dis:
 
 #
 # operand will underflow AND underflow is enabled.
-# therefore, we must return the result rounded to extended precision.
+# Therefore, we must return the result rounded to extended precision.
 #
 fsqrt_sd_unfl_ena:
 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/bootinfo.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/bootinfo.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/bootinfo.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/bootinfo.h	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,7 @@ struct bi_record {
 
     /*
      *  Macintosh hardware profile data - unused, see macintosh.h for
-     *  resonable type values
+     *  reasonable type values
      */
 
 #define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/cacheflush_mm.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/cacheflush_mm.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/cacheflush_mm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/cacheflush_mm.h	2010-02-24 13:52:17.000000000 -0500
@@ -128,6 +128,7 @@ static inline void __flush_page_to_ram(v
 	}
 }
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)		__flush_page_to_ram(page_address(page))
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/cacheflush_no.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/cacheflush_no.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/cacheflush_no.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/cacheflush_no.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #define flush_cache_range(vma, start, end)	__flush_cache_all()
 #define flush_cache_page(vma, vmaddr)		do { } while (0)
 #define flush_dcache_range(start,len)		__flush_cache_all()
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,6 @@ typedef struct user_m68kfp_struct elf_fp
    is actually used on ASV.  */
 #define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
 
-#define USE_ELF_CORE_DUMP
 #ifndef CONFIG_SUN3
 #define ELF_EXEC_PAGESIZE	4096
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/io_no.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/io_no.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/io_no.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/io_no.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,6 +3,7 @@
 
 #ifdef __KERNEL__
 
+#include <asm/virtconvert.h>
 
 /*
  * These are for ISA/PCI shared memory _only_ and should never be used
@@ -165,19 +166,6 @@ static inline void *ioremap_fullcache(un
 
 extern void iounmap(void *addr);
 
-/* Pages to physical address... */
-#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
-#define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
-
-/*
- * Macros used for converting between virtual and physical mappings.
- */
-#define phys_to_virt(vaddr)	((void *) (vaddr))
-#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
-
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/page_no.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/page_no.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/page_no.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/page_no.h	2010-02-24 13:52:17.000000000 -0500
@@ -56,8 +56,8 @@ extern unsigned long memory_end;
 
 #ifndef __ASSEMBLY__
 
-#define __pa(vaddr)		virt_to_phys((void *)(vaddr))
-#define __va(paddr)		phys_to_virt((unsigned long)(paddr))
+#define __pa(vaddr)		((unsigned long)(vaddr))
+#define __va(paddr)		((void *)(paddr))
 
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/pgtable_mm.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/pgtable_mm.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/pgtable_mm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/pgtable_mm.h	2010-02-24 13:52:17.000000000 -0500
@@ -83,9 +83,9 @@
 #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_END KMAP_START
 #else
-extern unsigned long vmalloc_end;
+extern unsigned long m68k_vmalloc_end;
 #define VMALLOC_START 0x0f800000
-#define VMALLOC_END vmalloc_end
+#define VMALLOC_END m68k_vmalloc_end
 #endif /* CONFIG_SUN3 */
 
 /* zero page used for uninitialized stuff */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/processor.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/processor.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/processor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
@@ -165,6 +165,8 @@ unsigned long get_wchan(struct task_stru
 	eip; })
 #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
+#define task_pt_regs(tsk)	((struct pt_regs *) ((tsk)->thread.esp0))
+
 #define cpu_relax()	barrier()
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,8 @@ struct switch_stack {
 #define PTRACE_GETFPREGS          14
 #define PTRACE_SETFPREGS          15
 
+#define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
+
 #ifdef __KERNEL__
 
 #ifndef PS_S
@@ -82,6 +84,21 @@ struct switch_stack {
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
+
+/*
+ * These are defined as per linux/ptrace.h.
+ */
+struct task_struct;
+
+#define arch_has_single_step()	(1)
+extern void user_enable_single_step(struct task_struct *);
+extern void user_disable_single_step(struct task_struct *);
+
+#ifdef CONFIG_MMU
+#define arch_has_block_step()	(1)
+extern void user_enable_block_step(struct task_struct *);
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _M68K_PTRACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/thread_info_mm.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_mm.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/thread_info_mm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_mm.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,10 +4,12 @@
 #ifndef ASM_OFFSETS_C
 #include <asm/asm-offsets.h>
 #endif
-#include <asm/current.h>
 #include <asm/types.h>
 #include <asm/page.h>
 
+#ifndef __ASSEMBLY__
+#include <asm/current.h>
+
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	unsigned long		flags;
@@ -16,6 +18,7 @@ struct thread_info {
 	__u32 cpu; /* should always be 0 on m68k */
 	struct restart_block    restart_block;
 };
+#endif /* __ASSEMBLY__ */
 
 #define PREEMPT_ACTIVE		0x4000000
 
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/thread_info_no.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_no.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/thread_info_no.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/thread_info_no.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,8 +12,6 @@
 
 #ifdef __KERNEL__
 
-#ifndef __ASSEMBLY__
-
 /*
  * Size of kernel stack for each process. This must be a power of 2...
  */
@@ -28,6 +26,8 @@
  */
 #define THREAD_SIZE (PAGE_SIZE<<THREAD_SIZE_ORDER)
 
+#ifndef __ASSEMBLY__
+
 /*
  * low level task data.
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/include/asm/virtconvert.h linux-libre-2.6.33-gnu1/arch/m68k/include/asm/virtconvert.h
--- linux-libre-2.6.32-gnu1/arch/m68k/include/asm/virtconvert.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/include/asm/virtconvert.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@ static inline void *phys_to_virt(unsigne
 }
 
 /* Permanent address of a page. */
+#ifdef CONFIG_MMU
 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
 #define page_to_phys(page) \
 	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
@@ -37,6 +38,9 @@ static inline void *phys_to_virt(unsigne
 	page_to_pfn(__page) << PAGE_SHIFT;				\
 })
 #endif
+#else
+#define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT)
+#endif
 
 /*
  * IO bus memory addresses are 1:1 with the physical address,
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/entry.S linux-libre-2.6.33-gnu1/arch/m68k/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -179,7 +179,11 @@ do_signal_return:
 	addql	#8,%sp
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
-	jbra	resume_userspace
+	tstl	%d0
+	jeq	resume_userspace
+	| when single stepping into handler stop at the first insn
+	btst	#6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
+	jeq	resume_userspace
 
 do_delayed_trace:
 	bclr	#7,%sp@(PT_OFF_SR)	| clear trace bit in SR
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/head.S linux-libre-2.6.33-gnu1/arch/m68k/kernel/head.S
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,7 @@
  * for them and trying to understand what they mean.
  *
  * CONFIG_xxx:	These are the obvious machine configuration defines created
- * during configuration.  These are defined in include/linux/autoconf.h.
+ * during configuration.  These are defined in autoconf.h.
  *
  * CONSOLE:	There is support for head.S console in this file.  This
  * console can talk to a Mac frame buffer, but could easily be extrapolated
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/process.c linux-libre-2.6.33-gnu1/arch/m68k/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -317,15 +317,12 @@ asmlinkage int sys_execve(char __user *n
 	char * filename;
 	struct pt_regs *regs = (struct pt_regs *) &name;
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-out:
-	unlock_kernel();
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/ptrace.c linux-libre-2.6.33-gnu1/arch/m68k/kernel/ptrace.c
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/ptrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,9 @@
 #define SR_MASK 0x001f
 
 /* sets the trace bits. */
-#define TRACE_BITS 0x8000
+#define TRACE_BITS 0xC000
+#define T1_BIT 0x8000
+#define T0_BIT 0x4000
 
 /* Find the stack offset for a register, relative to thread.esp0. */
 #define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
@@ -44,7 +46,7 @@
 /* Mapping from PT_xxx to the stack offset at which the register is
    saved.  Notice that usp has no stack-slot and needs to be treated
    specially (see get_reg/put_reg below). */
-static int regoff[] = {
+static const int regoff[] = {
 	[0]	= PT_REG(d1),
 	[1]	= PT_REG(d2),
 	[2]	= PT_REG(d3),
@@ -79,6 +81,14 @@ static inline long get_reg(struct task_s
 		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
 	else
 		return 0;
+	/* Need to take stkadj into account. */
+	if (regno == PT_SR || regno == PT_PC) {
+		long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
+		addr = (unsigned long *) ((unsigned long)addr + stkadj);
+		/* The sr is actually a 16 bit register.  */
+		if (regno == PT_SR)
+			return *(unsigned short *)addr;
+	}
 	return *addr;
 }
 
@@ -96,6 +106,16 @@ static inline int put_reg(struct task_st
 		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
 	else
 		return -1;
+	/* Need to take stkadj into account. */
+	if (regno == PT_SR || regno == PT_PC) {
+		long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
+		addr = (unsigned long *) ((unsigned long)addr + stkadj);
+		/* The sr is actually a 16 bit register.  */
+		if (regno == PT_SR) {
+			*(unsigned short *)addr = data;
+			return 0;
+		}
+	}
 	*addr = data;
 	return 0;
 }
@@ -105,7 +125,7 @@ static inline int put_reg(struct task_st
  */
 static inline void singlestep_disable(struct task_struct *child)
 {
-	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
 	put_reg(child, PT_SR, tmp);
 	clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
 }
@@ -118,18 +138,30 @@ void ptrace_disable(struct task_struct *
 	singlestep_disable(child);
 }
 
+void user_enable_single_step(struct task_struct *child)
+{
+	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+	put_reg(child, PT_SR, tmp | T1_BIT);
+	set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+}
+
+void user_enable_block_step(struct task_struct *child)
+{
+	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+	put_reg(child, PT_SR, tmp | T0_BIT);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	singlestep_disable(child);
+}
+
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	unsigned long tmp;
 	int i, ret = 0;
 
 	switch (request) {
-	/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT:	/* read word at location addr. */
-	case PTRACE_PEEKDATA:
-		ret = generic_ptrace_peekdata(child, addr, data);
-		break;
-
 	/* read the word at location addr in the USER area. */
 	case PTRACE_PEEKUSR:
 		if (addr & 3)
@@ -138,8 +170,6 @@ long arch_ptrace(struct task_struct *chi
 
 		if (addr >= 0 && addr < 19) {
 			tmp = get_reg(child, addr);
-			if (addr == PT_SR)
-				tmp >>= 16;
 		} else if (addr >= 21 && addr < 49) {
 			tmp = child->thread.fp[addr - 21];
 			/* Convert internal fpu reg representation
@@ -149,16 +179,10 @@ long arch_ptrace(struct task_struct *chi
 				tmp = ((tmp & 0xffff0000) << 15) |
 				      ((tmp & 0x0000ffff) << 16);
 		} else
-			break;
+			goto out_eio;
 		ret = put_user(tmp, (unsigned long *)data);
 		break;
 
-	/* when I and D space are separate, this will have to be fixed. */
-	case PTRACE_POKETEXT:	/* write the word at location addr. */
-	case PTRACE_POKEDATA:
-		ret = generic_ptrace_pokedata(child, addr, data);
-		break;
-
 	case PTRACE_POKEUSR:	/* write the word at location addr in the USER area */
 		if (addr & 3)
 			goto out_eio;
@@ -166,9 +190,9 @@ long arch_ptrace(struct task_struct *chi
 
 		if (addr == PT_SR) {
 			data &= SR_MASK;
-			data <<= 16;
-			data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
-		} else if (addr >= 0 && addr < 19) {
+			data |= get_reg(child, PT_SR) & ~SR_MASK;
+		}
+		if (addr >= 0 && addr < 19) {
 			if (put_reg(child, addr, data))
 				goto out_eio;
 		} else if (addr >= 21 && addr < 48) {
@@ -185,52 +209,9 @@ long arch_ptrace(struct task_struct *chi
 			goto out_eio;
 		break;
 
-	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
-	case PTRACE_CONT:	/* restart after signal. */
-		if (!valid_signal(data))
-			goto out_eio;
-
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		singlestep_disable(child);
-		wake_up_process(child);
-		break;
-
-	/*
-	 * make the child exit.  Best I can do is send it a sigkill.
-	 * perhaps it should be put in the status that it wants to
-	 * exit.
-	 */
-	case PTRACE_KILL:
-		if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-			break;
-		child->exit_code = SIGKILL;
-		singlestep_disable(child);
-		wake_up_process(child);
-		break;
-
-	case PTRACE_SINGLESTEP:	/* set the trap flag. */
-		if (!valid_signal(data))
-			goto out_eio;
-
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
-		put_reg(child, PT_SR, tmp);
-		set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
-
-		child->exit_code = data;
-		/* give it a chance to run. */
-		wake_up_process(child);
-		break;
-
 	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
 		for (i = 0; i < 19; i++) {
 			tmp = get_reg(child, i);
-			if (i == PT_SR)
-				tmp >>= 16;
 			ret = put_user(tmp, (unsigned long *)data);
 			if (ret)
 				break;
@@ -245,8 +226,7 @@ long arch_ptrace(struct task_struct *chi
 				break;
 			if (i == PT_SR) {
 				tmp &= SR_MASK;
-				tmp <<= 16;
-				tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+				tmp |= get_reg(child, PT_SR) & ~SR_MASK;
 			}
 			put_reg(child, i, tmp);
 			data += sizeof(long);
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/sys_m68k.c linux-libre-2.6.33-gnu1/arch/m68k/kernel/sys_m68k.c
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/sys_m68k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/sys_m68k.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,37 +29,16 @@
 #include <asm/page.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
 {
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	/*
+	 * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
+	 * so we need to shift the argument down by 1; m68k mmap64(3)
+	 * (in libc) expects the last argument of mmap2 in 4Kb units.
+	 */
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
@@ -90,57 +69,11 @@ asmlinkage int old_mmap(struct mmap_arg_
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
-	return error;
-}
-
-#if 0
-struct mmap_arg_struct64 {
-	__u32 addr;
-	__u32 len;
-	__u32 prot;
-	__u32 flags;
-	__u64 offset; /* 64 bits */
-	__u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
-	int error = -EFAULT;
-	struct file * file = NULL;
-	struct mmap_arg_struct64 a;
-	unsigned long pgoff;
-
-	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
-
-	if ((long)a.offset & ~PAGE_MASK)
-		return -EINVAL;
-
-	pgoff = a.offset >> PAGE_SHIFT;
-	if ((a.offset >> PAGE_SHIFT) != pgoff)
-		return -EINVAL;
-
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(a.fd);
-		if (!file)
-			goto out;
-	}
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			       a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
-#endif
 
 struct sel_arg_struct {
 	unsigned long n;
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/vmlinux-std.lds linux-libre-2.6.33-gnu1/arch/m68k/kernel/vmlinux-std.lds
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/vmlinux-std.lds	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/vmlinux-std.lds	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
 OUTPUT_ARCH(m68k)
@@ -22,73 +23,37 @@ SECTIONS
 
   _etext = .;			/* End of text section */
 
-  . = ALIGN(16);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
+  EXCEPTION_TABLE(16)
 
   RODATA
 
-  .data : {			/* Data */
-	DATA_DATA
-	CONSTRUCTORS
-	}
-
-  . = ALIGN(16);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
 
-  .bss : { *(.bss) }		/* BSS */
+  BSS_SECTION(0, 0, 0)
 
   _edata = .;			/* End of data section */
 
   /* will be freed after init */
   . = ALIGN(PAGE_SIZE);		/* Init code and data */
   __init_begin = .;
-  .init.text : {
-	_sinittext = .;
-	INIT_TEXT
-	_einittext = .;
-  } :data
-  .init.data : { INIT_DATA }
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : {
-	INITCALLS
-  }
-  __initcall_end = .;
-  __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
-  __con_initcall_end = .;
+  INIT_TEXT_SECTION(PAGE_SIZE) :data
+  INIT_DATA_SECTION(16)
   .m68k_fixup : {
 	__start_fixup = .;
 	*(.m68k_fixup)
 	__stop_fixup = .;
   }
-  SECURITY_INIT
-#ifdef CONFIG_BLK_DEV_INITRD
-  . = ALIGN(8192);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
-#endif
   NOTES
-  . = ALIGN(8192);
-  __init_end = .;
-
-  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */
+  .init_end : {
+	/* This ALIGN be in a section so that _end is at the end of the
+	   load segment. */
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
+  }
 
   _end = . ;
 
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
+  STABS_DEBUG
   .comment 0 : { *(.comment) }
 
   /* Sections to be discarded */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/kernel/vmlinux-sun3.lds linux-libre-2.6.33-gnu1/arch/m68k/kernel/vmlinux-sun3.lds
--- linux-libre-2.6.32-gnu1/arch/m68k/kernel/vmlinux-sun3.lds	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/kernel/vmlinux-sun3.lds	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
 OUTPUT_ARCH(m68k)
@@ -23,14 +24,8 @@ SECTIONS
 
   _etext = .;			/* End of text section */
 
-  .data : {			/* Data */
-	DATA_DATA
-	CONSTRUCTORS
-	. = ALIGN(16);		/* Exception table */
-	__start___ex_table = .;
-	*(__ex_table)
-	__stop___ex_table = .;
-	} :data
+  EXCEPTION_TABLE(16) :data
+  RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) :data
   /* End of data goes *here* so that freeing init code works properly. */
   _edata = .;
   NOTES
@@ -38,56 +33,21 @@ SECTIONS
   /* will be freed after init */
   . = ALIGN(PAGE_SIZE);	/* Init code and data */
 __init_begin = .;
-	.init.text : {
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-	}
-	.init.data : { INIT_DATA }
-	. = ALIGN(16);
-	__setup_start = .;
-	.init.setup : { *(.init.setup) }
-	__setup_end = .;
-	__initcall_start = .;
-	.initcall.init : {
-		INITCALLS
-	}
-	__initcall_end = .;
-	__con_initcall_start = .;
-	.con_initcall.init : { *(.con_initcall.init) }
-	__con_initcall_end = .;
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(16)
 	.m68k_fixup : {
 		__start_fixup = .;
 		*(.m68k_fixup)
 		__stop_fixup = .;
 	}
-	SECURITY_INIT
-#ifdef CONFIG_BLK_DEV_INITRD
-	. = ALIGN(PAGE_SIZE);
-	__initramfs_start = .;
-	.init.ramfs : { *(.init.ramfs) }
-	__initramfs_end = .;
-#endif
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
-	.data.init.task : { *(.data.init_task) }
-
 
-  .bss : { *(.bss) }		/* BSS */
+  BSS_SECTION(0, 0, 0)
 
   _end = . ;
 
-  .crap : {
-	/* Stabs debugging sections.  */
-	*(.stab)
-	*(.stabstr)
-	*(.stab.excl)
-	*(.stab.exclstr)
-	*(.stab.index)
-	*(.stab.indexstr)
-	*(.comment)
-	*(.note)
-  }
+  STABS_DEBUG
 
   /* Sections to be discarded */
   DISCARDS
diff -druNp linux-libre-2.6.32-gnu1/arch/m68k/sun3/mmu_emu.c linux-libre-2.6.33-gnu1/arch/m68k/sun3/mmu_emu.c
--- linux-libre-2.6.32-gnu1/arch/m68k/sun3/mmu_emu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68k/sun3/mmu_emu.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,8 +45,8 @@
 ** Globals
 */
 
-unsigned long vmalloc_end;
-EXPORT_SYMBOL(vmalloc_end);
+unsigned long m68k_vmalloc_end;
+EXPORT_SYMBOL(m68k_vmalloc_end);
 
 unsigned long pmeg_vaddr[PMEGS_NUM];
 unsigned char pmeg_alloc[PMEGS_NUM];
@@ -172,8 +172,8 @@ void mmu_emu_init(unsigned long bootmem_
 #endif
 			// the lowest mapping here is the end of our
 			// vmalloc region
-			if(!vmalloc_end)
-				vmalloc_end = seg;
+			if (!m68k_vmalloc_end)
+				m68k_vmalloc_end = seg;
 
 			// mark the segmap alloc'd, and reserve any
 			// of the first 0xbff pages the hardware is
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/Kconfig linux-libre-2.6.33-gnu1/arch/m68knommu/Kconfig
--- linux-libre-2.6.32-gnu1/arch/m68knommu/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -533,6 +533,13 @@ config AVNET
 	default y
 	depends on (AVNET5282)
 
+config UBOOT
+	bool "Support for U-Boot command line parameters"
+	help
+	  If you say Y here kernel will try to collect command
+	  line parameters from the initial u-boot stack.
+	default n
+
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	default y
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/process.c linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -352,15 +352,12 @@ asmlinkage int sys_execve(char *name, ch
 	char * filename;
 	struct pt_regs *regs = (struct pt_regs *) &name;
 
-	lock_kernel();
 	filename = getname(name);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
-		goto out;
+		return error;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-out:
-	unlock_kernel();
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/ptrace.c linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/ptrace.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/ptrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,6 +86,20 @@ static inline int put_reg(struct task_st
 	return 0;
 }
 
+void user_enable_single_step(struct task_struct *task)
+{
+	unsigned long srflags;
+	srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
+	put_reg(task, PT_SR, srflags);
+}
+
+void user_disable_single_step(struct task_struct *task)
+{
+	unsigned long srflags;
+	srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
+	put_reg(task, PT_SR, srflags);
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -93,10 +107,8 @@ static inline int put_reg(struct task_st
  */
 void ptrace_disable(struct task_struct *child)
 {
-	unsigned long tmp;
 	/* make sure the single step bit is not set. */
-	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-	put_reg(child, PT_SR, tmp);
+	user_disable_single_step(child);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/setup.c linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,8 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -52,7 +54,6 @@ void (*mach_reset)(void);
 void (*mach_halt)(void);
 void (*mach_power_off)(void);
 
-
 #ifdef CONFIG_M68000
 	#define CPU "MC68000"
 #endif
@@ -111,6 +112,69 @@ void (*mach_power_off)(void);
 extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
 extern int _ramstart, _ramend;
 
+#if defined(CONFIG_UBOOT)
+/*
+ * parse_uboot_commandline
+ *
+ * Copies u-boot commandline arguments and store them in the proper linux
+ * variables.
+ *
+ * Assumes:
+ *	_init_sp global contains the address in the stack pointer when the
+ *	kernel starts (see head.S::_start)
+ *
+ *	U-Boot calling convention:
+ *	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
+ *
+ *	_init_sp can be parsed as such
+ *
+ *	_init_sp+00 = u-boot cmd after jsr into kernel (skip)
+ *	_init_sp+04 = &kernel board_info (residual data)
+ *	_init_sp+08 = &initrd_start
+ *	_init_sp+12 = &initrd_end
+ *	_init_sp+16 = &cmd_start
+ *	_init_sp+20 = &cmd_end
+ *
+ *	This also assumes that the memory locations pointed to are still
+ *	unmodified. U-boot places them near the end of external SDRAM.
+ *
+ * Argument(s):
+ *	commandp = the linux commandline arg container to fill.
+ *	size     = the sizeof commandp.
+ *
+ * Returns:
+ */
+void parse_uboot_commandline(char *commandp, int size)
+{
+	extern unsigned long _init_sp;
+	unsigned long *sp;
+	unsigned long uboot_kbd;
+	unsigned long uboot_initrd_start, uboot_initrd_end;
+	unsigned long uboot_cmd_start, uboot_cmd_end;
+
+
+	sp = (unsigned long *)_init_sp;
+	uboot_kbd = sp[1];
+	uboot_initrd_start = sp[2];
+	uboot_initrd_end = sp[3];
+	uboot_cmd_start = sp[4];
+	uboot_cmd_end = sp[5];
+
+	if (uboot_cmd_start && uboot_cmd_end)
+		strncpy(commandp, (const char *)uboot_cmd_start, size);
+#if defined(CONFIG_BLK_DEV_INITRD)
+	if (uboot_initrd_start && uboot_initrd_end &&
+		(uboot_initrd_end > uboot_initrd_start)) {
+		initrd_start = uboot_initrd_start;
+		initrd_end = uboot_initrd_end;
+		ROOT_DEV = Root_RAM0;
+		printk(KERN_INFO "initrd at 0x%lx:0x%lx\n",
+			initrd_start, initrd_end);
+	}
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+}
+#endif /* #if defined(CONFIG_UBOOT) */
+
 void __init setup_arch(char **cmdline_p)
 {
 	int bootmap_size;
@@ -128,7 +192,24 @@ void __init setup_arch(char **cmdline_p)
 #if defined(CONFIG_BOOTPARAM)
 	strncpy(&command_line[0], CONFIG_BOOTPARAM_STRING, sizeof(command_line));
 	command_line[sizeof(command_line) - 1] = 0;
-#endif
+#endif /* CONFIG_BOOTPARAM */
+
+#if defined(CONFIG_UBOOT)
+	/* CONFIG_UBOOT and CONFIG_BOOTPARAM defined, concatenate cmdline */
+	#if defined(CONFIG_BOOTPARAM)
+		/* Add the whitespace separator */
+		command_line[strlen(CONFIG_BOOTPARAM_STRING)] = ' ';
+		/* Parse uboot command line into the rest of the buffer */
+		parse_uboot_commandline(
+			&command_line[(strlen(CONFIG_BOOTPARAM_STRING)+1)],
+			(sizeof(command_line) -
+			(strlen(CONFIG_BOOTPARAM_STRING)+1)));
+	/* Only CONFIG_UBOOT defined, create cmdline */
+	#else
+		parse_uboot_commandline(&command_line[0], sizeof(command_line));
+	#endif /* CONFIG_BOOTPARAM */
+	command_line[sizeof(command_line) - 1] = 0;
+#endif /* CONFIG_UBOOT */
 
 	printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
 
@@ -204,6 +285,13 @@ void __init setup_arch(char **cmdline_p)
 	free_bootmem(memory_start, memory_end - memory_start);
 	reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
 
+#if defined(CONFIG_UBOOT) && defined(CONFIG_BLK_DEV_INITRD)
+	if ((initrd_start > 0) && (initrd_start < initrd_end) &&
+			(initrd_end < memory_end))
+		reserve_bootmem(initrd_start, initrd_end - initrd_start,
+				 BOOTMEM_DEFAULT);
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+
 	/*
 	 * Get kmalloc into gear.
 	 */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/syscalltable.S linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/syscalltable.S
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/syscalltable.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/syscalltable.S	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall	/* streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/sys_m68k.c linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/sys_m68k.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/sys_m68k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/sys_m68k.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,39 +27,6 @@
 #include <asm/cacheflush.h>
 #include <asm/unistd.h>
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
@@ -88,9 +55,8 @@ asmlinkage int old_mmap(struct mmap_arg_
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+				a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/m68knommu/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,8 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
 
 #if defined(CONFIG_RAMKERNEL)
 #define	RAM_START	CONFIG_KERNELBASE
@@ -15,7 +17,7 @@
 #define	TEXT		ram
 #define	DATA		ram
 #define	INIT		ram
-#define	BSS		ram
+#define	BSSS		ram
 #endif
 #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
 #define	RAM_START	CONFIG_RAMBASE
@@ -27,7 +29,7 @@
 #define	TEXT		rom
 #define	DATA		ram
 #define	INIT		ram
-#define	BSS		ram
+#define	BSSS		ram
 #endif
 
 #ifndef DATA_ADDR
@@ -147,40 +149,19 @@ SECTIONS {
 		. = ALIGN(4);
 		_sdata = . ;
 		DATA_DATA
-		. = ALIGN(32);
-		*(.data.cacheline_aligned)
-		. = ALIGN(8192) ;
-		*(.data.init_task)
+		CACHELINE_ALIGNED_DATA(32)
+		INIT_TASK_DATA(THREAD_SIZE)
 		_edata = . ;
 	} > DATA
 
-	.init : {
-		. = ALIGN(4096);
+	.init.text : {
+		. = ALIGN(PAGE_SIZE);
 		__init_begin = .;
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-		INIT_DATA
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-		__security_initcall_start = .;
-		*(.security_initcall.init)
-		__security_initcall_end = .;
-#ifdef CONFIG_BLK_DEV_INITRD
-		. = ALIGN(4);
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-#endif
-		. = ALIGN(4096);
+	} > INIT
+	INIT_TEXT_SECTION(PAGE_SIZE) > INIT
+	INIT_DATA_SECTION(16) > INIT
+	.init.data : {
+		. = ALIGN(PAGE_SIZE);
 		__init_end = .;
 	} > INIT
 
@@ -192,7 +173,7 @@ SECTIONS {
 		. = ALIGN(4) ;
 		_ebss = . ;
 	 	_end = . ;
-	} > BSS
+	} > BSSS
 
 	DISCARDS
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/523x/gpio.c linux-libre-2.6.33-gnu1/arch/m68knommu/platform/523x/gpio.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/523x/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/523x/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,8 @@ static struct mcf_gpio_chip mcf_gpio_chi
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
@@ -244,7 +245,7 @@ static struct mcf_gpio_chip mcf_gpio_chi
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value_fast,
 			.base			= 96,
-			.ngpio			= 4,
+			.ngpio			= 8,
 		},
 		.pddr				= MCFGPIO_PDDR_TIMER,
 		.podr				= MCFGPIO_PODR_TIMER,
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/527x/gpio.c linux-libre-2.6.33-gnu1/arch/m68knommu/platform/527x/gpio.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/527x/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/527x/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,8 @@ static struct mcf_gpio_chip mcf_gpio_chi
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
@@ -263,7 +264,8 @@ static struct mcf_gpio_chip mcf_gpio_chi
 			.direction_output	= mcf_gpio_direction_output,
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
-			.ngpio			= 8,
+			.base			= 1,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/528x/gpio.c linux-libre-2.6.33-gnu1/arch/m68knommu/platform/528x/gpio.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/528x/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/528x/gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@ static struct mcf_gpio_chip mcf_gpio_chi
 			.get			= mcf_gpio_get_value,
 			.set			= mcf_gpio_set_value,
 			.base			= 1,
-			.ngpio			= 8,
+			.ngpio			= 7,
 		},
 		.pddr				= MCFEPORT_EPDDR,
 		.podr				= MCFEPORT_EPDR,
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/clk.c linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/clk.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/clk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/clk.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <asm/coldfire.h>
 
@@ -18,23 +19,27 @@ struct clk *clk_get(struct device *dev,
 {
 	return NULL;
 }
+EXPORT_SYMBOL(clk_get);
 
 int clk_enable(struct clk *clk)
 {
 	return 0;
 }
+EXPORT_SYMBOL(clk_enable);
 
 void clk_disable(struct clk *clk)
 {
 }
+EXPORT_SYMBOL(clk_disable);
 
 void clk_put(struct clk *clk)
 {
 }
+EXPORT_SYMBOL(clk_put);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return MCF_CLK;
 }
-
+EXPORT_SYMBOL(clk_get_rate);
 /***************************************************************************/
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/head.S linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/head.S
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -106,6 +106,9 @@
 .global _ramvec
 .global	_ramstart
 .global	_ramend
+#if defined(CONFIG_UBOOT)
+.global	_init_sp
+#endif
 
 /*****************************************************************************/
 
@@ -124,6 +127,10 @@ _ramstart:
 .long	0
 _ramend:
 .long	0
+#if defined(CONFIG_UBOOT)
+_init_sp:
+.long	0
+#endif
 
 /*****************************************************************************/
 
@@ -137,6 +144,9 @@ __HEAD
 _start:
 	nop					/* filler */
 	movew	#0x2700, %sr			/* no interrupts */
+#if defined(CONFIG_UBOOT)
+	movel	%sp,_init_sp			/* save initial stack pointer */
+#endif
 
 	/*
 	 *	Do any platform or board specific setup now. Most boards
diff -druNp linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/pit.c linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/pit.c
--- linux-libre-2.6.32-gnu1/arch/m68knommu/platform/coldfire/pit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/m68knommu/platform/coldfire/pit.c	2010-02-24 13:52:17.000000000 -0500
@@ -146,7 +146,6 @@ static struct clocksource pit_clk = {
 	.read	= pit_read_clk,
 	.shift	= 20,
 	.mask	= CLOCKSOURCE_MASK(32),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 /***************************************************************************/
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/boot/dts/system.dts linux-libre-2.6.33-gnu1/arch/microblaze/boot/dts/system.dts
--- linux-libre-2.6.32-gnu1/arch/microblaze/boot/dts/system.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/boot/dts/system.dts	2010-02-24 13:52:17.000000000 -0500
@@ -32,11 +32,16 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 	compatible = "xlnx,microblaze";
+	hard-reset-gpios = <&LEDs_8Bit 2 1>;
 	model = "testing";
 	DDR2_SDRAM: memory@90000000 {
 		device_type = "memory";
 		reg = < 0x90000000 0x10000000 >;
 	} ;
+	aliases {
+		ethernet0 = &Hard_Ethernet_MAC;
+		serial0 = &RS232_Uart_1;
+	} ;
 	chosen {
 		bootargs = "console=ttyUL0,115200 highres=on";
 		linux,stdout-path = "/plb@0/serial@84000000";
@@ -127,7 +132,7 @@
 	mb_plb: plb@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+		compatible = "xlnx,plb-v46-1.03.a", "xlnx,plb-v46-1.00.a", "simple-bus";
 		ranges ;
 		FLASH: flash@a0000000 {
 			bank-width = <2>;
@@ -214,12 +219,12 @@
 			#size-cells = <1>;
 			compatible = "xlnx,compound";
 			ethernet@81c00000 {
-				compatible = "xlnx,xps-ll-temac-1.01.b";
+				compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
 				device_type = "network";
 				interrupt-parent = <&xps_intc_0>;
 				interrupts = < 5 2 >;
 				llink-connected = <&PIM3>;
-				local-mac-address = [ 02 00 00 00 00 00 ];
+				local-mac-address = [ 00 0a 35 00 00 00 ];
 				reg = < 0x81c00000 0x40 >;
 				xlnx,bus2core-clk-ratio = <0x1>;
 				xlnx,phy-type = <0x1>;
@@ -261,6 +266,33 @@
 			xlnx,is-dual = <0x0>;
 			xlnx,tri-default = <0xffffffff>;
 			xlnx,tri-default-2 = <0xffffffff>;
+			#gpio-cells = <2>;
+			gpio-controller;
+		} ;
+
+		gpio-leds {
+			compatible = "gpio-leds";
+
+			heartbeat {
+				label = "Heartbeat";
+				gpios = <&LEDs_8Bit 4 1>;
+				linux,default-trigger = "heartbeat";
+			};
+
+			yellow {
+				label = "Yellow";
+				gpios = <&LEDs_8Bit 5 1>;
+			};
+
+			red {
+				label = "Red";
+				gpios = <&LEDs_8Bit 6 1>;
+			};
+
+			green {
+				label = "Green";
+				gpios = <&LEDs_8Bit 7 1>;
+			};
 		} ;
 		RS232_Uart_1: serial@84000000 {
 			clock-frequency = <125000000>;
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/boot/Makefile linux-libre-2.6.33-gnu1/arch/microblaze/boot/Makefile
--- linux-libre-2.6.32-gnu1/arch/microblaze/boot/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,11 +2,13 @@
 # arch/microblaze/boot/Makefile
 #
 
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
 obj-y += linked_dtb.o
 
 targets := linux.bin linux.bin.gz simpleImage.%
 
-OBJCOPYFLAGS_linux.bin  := -O binary
+OBJCOPYFLAGS := -O binary
 
 # Where the DTS files live
 dtstree         := $(srctree)/$(src)/dts
@@ -24,6 +26,7 @@ $(obj)/linux.bin: vmlinux FORCE
 	[ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \
 	touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image"
 	$(call if_changed,objcopy)
+	$(call if_changed,uimage)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
 
 $(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
@@ -36,8 +39,16 @@ quiet_cmd_cp = CP      $< $@$2
 quiet_cmd_strip = STRIP   $@
       cmd_strip = $(STRIP) -K _start -K _end -K __log_buf -K _fdt_start vmlinux -o $@
 
+quiet_cmd_uimage = UIMAGE  $@.ub
+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A microblaze -O linux -T kernel \
+                   -C none -n 'Linux-$(KERNELRELEASE)' \
+                   -a $(CONFIG_KERNEL_BASE_ADDR) -e $(CONFIG_KERNEL_BASE_ADDR) \
+                   -d $@ $@.ub
+
 $(obj)/simpleImage.%: vmlinux FORCE
 	$(call if_changed,cp,.unstrip)
+	$(call if_changed,objcopy)
+	$(call if_changed,uimage)
 	$(call if_changed,strip)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
 
@@ -53,4 +64,4 @@ $(obj)/%.dtb: $(dtstree)/%.dts FORCE
 
 clean-kernel += linux.bin linux.bin.gz simpleImage.*
 
-clean-files += *.dtb
+clean-files += *.dtb simpleImage.*.unstrip
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/configs/mmu_defconfig linux-libre-2.6.33-gnu1/arch/microblaze/configs/mmu_defconfig
--- linux-libre-2.6.32-gnu1/arch/microblaze/configs/mmu_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/configs/mmu_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 10:28:50 2009
+# Linux kernel version: 2.6.33-rc6
+# Wed Feb  3 10:02:59 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -19,8 +19,12 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_CSUM=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_PCI is not set
 CONFIG_NO_DMA=y
+CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -44,6 +48,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -64,10 +69,12 @@ CONFIG_INITRAMFS_ROOT_GID=0
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_INITRAMFS_COMPRESSION_NONE is not set
 CONFIG_INITRAMFS_COMPRESSION_GZIP=y
 # CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
 # CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -90,21 +97,20 @@ CONFIG_EVENTFD=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
 # GCOV-based kernel profiling
 #
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=1
@@ -123,14 +129,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -139,11 +172,6 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_PLATFORM_GENERIC=y
 CONFIG_OPT_LIB_FUNCTION=y
 CONFIG_OPT_LIB_ASM=y
-CONFIG_ALLOW_EDIT_AUTO=y
-
-#
-# Automatic platform settings from Kconfig.auto
-#
 
 #
 # Definitions for MICROBLAZE0
@@ -203,12 +231,11 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
 #
@@ -289,7 +316,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -313,6 +346,10 @@ CONFIG_OF_DEVICE=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -349,7 +386,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -359,12 +395,12 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_XILINX_EMACLITE=y
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -408,6 +444,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -433,7 +470,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -526,8 +562,6 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -638,11 +672,13 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -662,6 +698,9 @@ CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
 CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -680,10 +719,29 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
-# CONFIG_KMEMCHECK is not set
 CONFIG_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
 CONFIG_DEBUG_BOOTMEM=y
@@ -694,7 +752,11 @@ CONFIG_DEBUG_BOOTMEM=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/configs/nommu_defconfig linux-libre-2.6.33-gnu1/arch/microblaze/configs/nommu_defconfig
--- linux-libre-2.6.32-gnu1/arch/microblaze/configs/nommu_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/configs/nommu_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 10:29:43 2009
+# Linux kernel version: 2.6.33-rc6
+# Wed Feb  3 10:03:21 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -19,8 +19,12 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_CSUM=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_PCI is not set
 CONFIG_NO_DMA=y
+CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,6 +50,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -81,16 +86,16 @@ CONFIG_EVENTFD=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
 
 #
 # GCOV-based kernel profiling
@@ -116,14 +121,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -132,7 +164,10 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_PLATFORM_GENERIC=y
 # CONFIG_SELFMOD is not set
 # CONFIG_OPT_LIB_FUNCTION is not set
-# CONFIG_ALLOW_EDIT_AUTO is not set
+
+#
+# Definitions for MICROBLAZE0
+#
 CONFIG_KERNEL_BASE_ADDR=0x90000000
 CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5"
 CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
@@ -190,7 +225,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -274,9 +308,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -301,9 +332,9 @@ CONFIG_STANDALONE=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_OF_PARTS is not set
@@ -387,6 +418,10 @@ CONFIG_OF_DEVICE=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -423,7 +458,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -433,12 +467,12 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -482,6 +516,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -508,7 +543,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -616,7 +650,6 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -672,11 +705,13 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_UNUSED_SYMBOLS=y
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -695,12 +730,16 @@ CONFIG_DEBUG_OBJECTS=y
 CONFIG_DEBUG_OBJECTS_SELFTEST=y
 CONFIG_DEBUG_OBJECTS_FREE=y
 CONFIG_DEBUG_OBJECTS_TIMERS=y
+# CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -720,8 +759,28 @@ CONFIG_DEBUG_SG=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_EARLY_PRINTK=y
@@ -734,7 +793,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,8 @@
 /* Somebody depends on this; sigh... */
 #include <linux/mm.h>
 
+/* Look at Documentation/cachetlb.txt */
+
 /*
  * Cache handling functions.
  * Microblaze has a write-through data cache, meaning that the data cache
@@ -27,77 +29,81 @@
  * instruction cache to make sure we don't fetch old, bad code.
  */
 
-/* FIXME for LL-temac driver */
-#define invalidate_dcache_range(start, end) \
-			__invalidate_dcache_range(start, end)
-
-#define flush_cache_all()			__invalidate_cache_all()
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	__invalidate_cache_all()
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-
-#define flush_dcache_range(start, end)	__invalidate_dcache_range(start, end)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-#define flush_icache_range(start, len)	__invalidate_icache_range(start, len)
-#define flush_icache_page(vma, pg)		do { } while (0)
+/* struct cache, d=dcache, i=icache, fl = flush, iv = invalidate,
+ * suffix r = range */
+struct scache {
+	/* icache */
+	void (*ie)(void); /* enable */
+	void (*id)(void); /* disable */
+	void (*ifl)(void); /* flush */
+	void (*iflr)(unsigned long a, unsigned long b);
+	void (*iin)(void); /* invalidate */
+	void (*iinr)(unsigned long a, unsigned long b);
+	/* dcache */
+	void (*de)(void); /* enable */
+	void (*dd)(void); /* disable */
+	void (*dfl)(void); /* flush */
+	void (*dflr)(unsigned long a, unsigned long b);
+	void (*din)(void); /* invalidate */
+	void (*dinr)(unsigned long a, unsigned long b);
+};
 
-#ifndef CONFIG_MMU
-# define flush_icache_user_range(start, len)	do { } while (0)
-#else
-# define flush_icache_user_range(vma, pg, adr, len) __invalidate_icache_all()
+/* microblaze cache */
+extern struct scache *mbc;
 
-# define flush_page_to_ram(page)		do { } while (0)
+void microblaze_cache_init(void);
 
-# define flush_icache()			__invalidate_icache_all()
-# define flush_cache_sigtramp(vaddr) \
-			__invalidate_icache_range(vaddr, vaddr + 8)
+#define enable_icache()					mbc->ie();
+#define disable_icache()				mbc->id();
+#define flush_icache()					mbc->ifl();
+#define flush_icache_range(start, end)			mbc->iflr(start, end);
+#define invalidate_icache()				mbc->iin();
+#define invalidate_icache_range(start, end)		mbc->iinr(start, end);
 
-# define flush_dcache_mmap_lock(mapping)	do { } while (0)
-# define flush_dcache_mmap_unlock(mapping)	do { } while (0)
 
-# define flush_cache_dup_mm(mm)			do { } while (0)
-#endif
+#define flush_icache_user_range(vma, pg, adr, len)	flush_icache();
+#define flush_icache_page(vma, pg)			do { } while (0)
 
-#define flush_cache_vmap(start, end)		do { } while (0)
-#define flush_cache_vunmap(start, end)		do { } while (0)
+#define enable_dcache()					mbc->de();
+#define disable_dcache()				mbc->dd();
+/* FIXME for LL-temac driver */
+#define invalidate_dcache()				mbc->din();
+#define invalidate_dcache_range(start, end)		mbc->dinr(start, end);
+#define flush_dcache()					mbc->dfl();
+#define flush_dcache_range(start, end)			mbc->dflr(start, end);
 
-struct page;
-struct mm_struct;
-struct vm_area_struct;
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
+/* D-cache aliasing problem can't happen - cache is between MMU and ram */
+#define flush_dcache_page(page)			do { } while (0)
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
 
-/* see arch/microblaze/kernel/cache.c */
-extern void __invalidate_icache_all(void);
-extern void __invalidate_icache_range(unsigned long start, unsigned long end);
-extern void __invalidate_icache_page(struct vm_area_struct *vma,
-				struct page *page);
-extern void __invalidate_icache_user_range(struct vm_area_struct *vma,
-				struct page *page,
-				unsigned long adr, int len);
-extern void __invalidate_cache_sigtramp(unsigned long addr);
 
-extern void __invalidate_dcache_all(void);
-extern void __invalidate_dcache_range(unsigned long start, unsigned long end);
-extern void __invalidate_dcache_page(struct vm_area_struct *vma,
-				struct page *page);
-extern void __invalidate_dcache_user_range(struct vm_area_struct *vma,
-				struct page *page,
-				unsigned long adr, int len);
+#define flush_cache_dup_mm(mm)				do { } while (0)
+#define flush_cache_vmap(start, end)			do { } while (0)
+#define flush_cache_vunmap(start, end)			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
 
-extern inline void __invalidate_cache_all(void)
-{
-	__invalidate_icache_all();
-	__invalidate_dcache_all();
+/* MS: kgdb code use this macro, wrong len with FLASH */
+#if 0
+#define flush_cache_range(vma, start, len)	{	\
+	flush_icache_range((unsigned) (start), (unsigned) (start) + (len)); \
+	flush_dcache_range((unsigned) (start), (unsigned) (start) + (len)); \
 }
+#endif
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy((dst), (src), (len)); \
-	flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
+#define flush_cache_range(vma, start, len) do { } while (0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)		\
+do {									\
+	memcpy((dst), (src), (len));					\
+	flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len));	\
 } while (0)
 
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-	memcpy((dst), (src), (len))
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)		\
+do {									\
+	memcpy((dst), (src), (len));					\
+} while (0)
 
 #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cache.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cache.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cache.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cache.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,20 +21,4 @@
 
 #define SMP_CACHE_BYTES	L1_CACHE_BYTES
 
-void _enable_icache(void);
-void _disable_icache(void);
-void _invalidate_icache(unsigned int addr);
-
-#define __enable_icache()		_enable_icache()
-#define __disable_icache()		_disable_icache()
-#define __invalidate_icache(addr)	_invalidate_icache(addr)
-
-void _enable_dcache(void);
-void _disable_dcache(void);
-void _invalidate_dcache(unsigned int addr);
-
-#define __enable_dcache()		_enable_dcache()
-#define __disable_dcache()		_disable_dcache()
-#define __invalidate_dcache(addr)	_invalidate_dcache(addr)
-
 #endif /* _ASM_MICROBLAZE_CACHE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cpuinfo.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cpuinfo.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/cpuinfo.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/cpuinfo.h	2010-02-24 13:52:17.000000000 -0500
@@ -43,7 +43,7 @@ struct cpuinfo {
 	u32 use_icache;
 	u32 icache_tagbits;
 	u32 icache_write;
-	u32 icache_line;
+	u32 icache_line_length;
 	u32 icache_size;
 	unsigned long icache_base;
 	unsigned long icache_high;
@@ -51,8 +51,9 @@ struct cpuinfo {
 	u32 use_dcache;
 	u32 dcache_tagbits;
 	u32 dcache_write;
-	u32 dcache_line;
+	u32 dcache_line_length;
 	u32 dcache_size;
+	u32 dcache_wb;
 	unsigned long dcache_base;
 	unsigned long dcache_high;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/device.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/device.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/device.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/device.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,18 @@ struct dev_archdata {
 struct pdev_archdata {
 };
 
+static inline void dev_archdata_set_node(struct dev_archdata *ad,
+					 struct device_node *np)
+{
+	ad->of_node = np;
+}
+
+static inline struct device_node *
+dev_archdata_get_node(const struct dev_archdata *ad)
+{
+	return ad->of_node;
+}
+
 #endif /* _ASM_MICROBLAZE_DEVICE_H */
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
 #define ELF_DATA	ELFDATA2MSB
 #endif
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/ftrace.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/ftrace.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/ftrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -1 +1,26 @@
+#ifndef _ASM_MICROBLAZE_FTRACE
+#define _ASM_MICROBLAZE_FTRACE
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_ADDR		((long)(_mcount))
+#define MCOUNT_INSN_SIZE	8 /* sizeof mcount call */
 
+#ifndef __ASSEMBLY__
+extern void _mcount(void);
+extern void ftrace_call_graph(void);
+#endif
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+/* reloction of mcount call site is the same as the address */
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+	return addr;
+}
+
+struct dyn_arch_ftrace {
+};
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#endif /* CONFIG_FUNCTION_TRACER */
+#endif /* _ASM_MICROBLAZE_FTRACE */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/futex.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/futex.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/futex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/futex.h	2010-02-24 13:52:17.000000000 -0500
@@ -1 +1,126 @@
-#include <asm-generic/futex.h>
+#ifndef _ASM_MICROBLAZE_FUTEX_H
+#define _ASM_MICROBLAZE_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+({									\
+	__asm__ __volatile__ (						\
+			"1:	lwx	%0, %2, r0; "			\
+				insn					\
+			"2:	swx	%1, %2, r0;			\
+				addic	%1, r0, 0;			\
+				bnei	%1, 1b;				\
+			3:						\
+			.section .fixup,\"ax\";				\
+			4:	brid	3b;				\
+				addik	%1, r0, %3;			\
+			.previous;					\
+			.section __ex_table,\"a\";			\
+			.word	1b,4b,2b,4b;				\
+			.previous;"					\
+	: "=&r" (oldval), "=&r" (ret)					\
+	: "b" (uaddr), "i" (-EFAULT), "r" (oparg)			\
+	);								\
+})
+
+static inline int
+futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	pagefault_disable();
+
+	switch (op) {
+	case FUTEX_OP_SET:
+		__futex_atomic_op("or %1,%4,%4;", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ADD:
+		__futex_atomic_op("add %1,%0,%4;", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_OR:
+		__futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ANDN:
+		__futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_XOR:
+		__futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
+		break;
+	default:
+		ret = -ENOSYS;
+	}
+
+	pagefault_enable();
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ:
+			ret = (oldval == cmparg);
+			break;
+		case FUTEX_OP_CMP_NE:
+			ret = (oldval != cmparg);
+			break;
+		case FUTEX_OP_CMP_LT:
+			ret = (oldval < cmparg);
+			break;
+		case FUTEX_OP_CMP_GE:
+			ret = (oldval >= cmparg);
+			break;
+		case FUTEX_OP_CMP_LE:
+			ret = (oldval <= cmparg);
+			break;
+		case FUTEX_OP_CMP_GT:
+			ret = (oldval > cmparg);
+			break;
+		default:
+			ret = -ENOSYS;
+		}
+	}
+	return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+	int prev, cmp;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	__asm__ __volatile__ ("1:	lwx	%0, %2, r0;		\
+					cmp	%1, %0, %3;		\
+					beqi	%1, 3f;			\
+				2:	swx	%4, %2, r0;		\
+					addic	%1, r0, 0;		\
+					bnei	%1, 1b;			\
+				3:					\
+				.section .fixup,\"ax\";			\
+				4:	brid	3b;			\
+					addik	%0, r0, %5;		\
+				.previous;				\
+				.section __ex_table,\"a\";		\
+				.word	1b,4b,2b,4b;			\
+				.previous;"				\
+		: "=&r" (prev), "=&r"(cmp)				\
+		: "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
+
+	return prev;
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/io.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/io.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -217,7 +217,7 @@ static inline void __iomem *__ioremap(ph
  * Little endian
  */
 
-#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a));
+#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a))
 #define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a))
 
 #define in_le32(a) __le32_to_cpu(__raw_readl(a))
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/irqflags.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/irqflags.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/irqflags.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/irqflags.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,78 +10,73 @@
 #define _ASM_MICROBLAZE_IRQFLAGS_H
 
 #include <linux/irqflags.h>
+#include <asm/registers.h>
 
 # if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
 
-# define local_irq_save(flags)				\
+# define raw_local_irq_save(flags)			\
 	do {						\
-		asm volatile ("# local_irq_save	\n\t"	\
-				"msrclr %0, %1	\n\t"	\
-				"nop	\n\t"		\
+		asm volatile ("	msrclr %0, %1;		\
+				nop;"			\
 				: "=r"(flags)		\
 				: "i"(MSR_IE)		\
 				: "memory");		\
 	} while (0)
 
-# define local_irq_disable()					\
-	do {							\
-		asm volatile ("# local_irq_disable \n\t"	\
-				"msrclr r0, %0 \n\t"		\
-				"nop	\n\t"			\
-				:				\
-				: "i"(MSR_IE)			\
-				: "memory");			\
+# define raw_local_irq_disable()			\
+	do {						\
+		asm volatile ("	msrclr r0, %0;		\
+				nop;"			\
+				:			\
+				: "i"(MSR_IE)		\
+				: "memory");		\
 	} while (0)
 
-# define local_irq_enable()					\
-	do {							\
-		asm volatile ("# local_irq_enable \n\t"		\
-				"msrset	r0, %0 \n\t"		\
-				"nop	\n\t"			\
-				:				\
-				: "i"(MSR_IE)			\
-				: "memory");			\
+# define raw_local_irq_enable()				\
+	do {						\
+		asm volatile ("	msrset	r0, %0;		\
+				nop;"			\
+				:			\
+				: "i"(MSR_IE)		\
+				: "memory");		\
 	} while (0)
 
 # else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
 
-# define local_irq_save(flags)					\
+# define raw_local_irq_save(flags)				\
 	do {							\
 		register unsigned tmp;				\
-		asm volatile ("# local_irq_save	\n\t"		\
-				"mfs	%0, rmsr \n\t"		\
-				"nop \n\t"			\
-				"andi	%1, %0, %2 \n\t"	\
-				"mts	rmsr, %1 \n\t"		\
-				"nop \n\t"			\
+		asm volatile ("	mfs	%0, rmsr;		\
+				nop;				\
+				andi	%1, %0, %2;		\
+				mts	rmsr, %1;		\
+				nop;"				\
 				: "=r"(flags), "=r" (tmp)	\
 				: "i"(~MSR_IE)			\
 				: "memory");			\
 	} while (0)
 
-# define local_irq_disable()					\
+# define raw_local_irq_disable()				\
 	do {							\
 		register unsigned tmp;				\
-		asm volatile ("# local_irq_disable \n\t"	\
-				"mfs	%0, rmsr \n\t"		\
-				"nop \n\t"			\
-				"andi	%0, %0, %1 \n\t"	\
-				"mts	rmsr, %0 \n\t"		\
-				"nop \n\t"			\
+		asm volatile ("	mfs	%0, rmsr;		\
+				nop;				\
+				andi	%0, %0, %1;		\
+				mts	rmsr, %0;		\
+				nop;"			\
 				: "=r"(tmp)			\
 				: "i"(~MSR_IE)			\
 				: "memory");			\
 	} while (0)
 
-# define local_irq_enable()					\
+# define raw_local_irq_enable()					\
 	do {							\
 		register unsigned tmp;				\
-		asm volatile ("# local_irq_enable \n\t"		\
-				"mfs	%0, rmsr \n\t"		\
-				"nop \n\t"			\
-				"ori	%0, %0, %1 \n\t"	\
-				"mts	rmsr, %0 \n\t"		\
-				"nop \n\t"			\
+		asm volatile ("	mfs	%0, rmsr;		\
+				nop;				\
+				ori	%0, %0, %1;		\
+				mts	rmsr, %0;		\
+				nop;"				\
 				: "=r"(tmp)			\
 				: "i"(MSR_IE)			\
 				: "memory");			\
@@ -89,35 +84,28 @@
 
 # endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
 
-#define local_save_flags(flags)					\
+#define raw_local_irq_restore(flags)				\
 	do {							\
-		asm volatile ("# local_save_flags \n\t"		\
-				"mfs	%0, rmsr \n\t"		\
-				"nop	\n\t"			\
-				: "=r"(flags)			\
+		asm volatile ("	mts	rmsr, %0;		\
+				nop;"				\
 				:				\
+				: "r"(flags)			\
 				: "memory");			\
 	} while (0)
 
-#define local_irq_restore(flags)			\
-	do {						\
-		asm volatile ("# local_irq_restore \n\t"\
-				"mts	rmsr, %0 \n\t"	\
-				"nop	\n\t"		\
-				:			\
-				: "r"(flags)		\
-				: "memory");		\
-	} while (0)
-
-static inline int irqs_disabled(void)
+static inline unsigned long get_msr(void)
 {
 	unsigned long flags;
-
-	local_save_flags(flags);
-	return ((flags & MSR_IE) == 0);
+	asm volatile ("	mfs	%0, rmsr;	\
+			nop;"			\
+			: "=r"(flags)		\
+			:			\
+			: "memory");		\
+	return flags;
 }
 
-#define raw_irqs_disabled irqs_disabled
-#define raw_irqs_disabled_flags(flags)	((flags) == 0)
+#define raw_local_save_flags(flags)	((flags) = get_msr())
+#define raw_irqs_disabled()		((get_msr() & MSR_IE) == 0)
+#define raw_irqs_disabled_flags(flags)	((flags & MSR_IE) == 0)
 
 #endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/page.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/page.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/page.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,8 @@ extern int page_is_ram(unsigned long pfn
 #  endif /* CONFIG_MMU */
 
 #  ifndef CONFIG_MMU
-#  define pfn_valid(pfn)	((pfn) >= min_low_pfn && (pfn) <= max_mapnr)
+#  define pfn_valid(pfn)	(((pfn) >= min_low_pfn) && \
+				((pfn) <= (min_low_pfn + max_mapnr)))
 #  define ARCH_PFN_OFFSET	(PAGE_OFFSET >> PAGE_SHIFT)
 #  else /* CONFIG_MMU */
 #  define ARCH_PFN_OFFSET	(memory_start >> PAGE_SHIFT)
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/pgalloc.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgalloc.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/pgalloc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,9 +106,6 @@ extern inline void free_pgd_slow(pgd_t *
  */
 #define pmd_alloc_one_fast(mm, address)	({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
-/* FIXME two definition - look below */
-#define pmd_free(mm, x)			do { } while (0)
-#define pgd_populate(mm, pmd, pte)	BUG()
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 		unsigned long address)
@@ -192,14 +189,14 @@ extern inline void pte_free(struct mm_st
  * the pgd will always be present..
  */
 #define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
-/*#define pmd_free(mm, x)			do { } while (0)*/
-#define __pmd_free_tlb(tlb, x, addr)	do { } while (0)
+#define pmd_free(mm, x)			do { } while (0)
+#define __pmd_free_tlb(tlb, x, addr)	pmd_free((tlb)->mm, x)
 #define pgd_populate(mm, pmd, pte)	BUG()
 
 extern int do_check_pgt_cache(int, int);
 
 #endif /* CONFIG_MMU */
 
-#define check_pgt_cache()	do {} while (0)
+#define check_pgt_cache()		do { } while (0)
 
 #endif /* _ASM_MICROBLAZE_PGALLOC_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/prom.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/prom.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/prom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/prom.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,23 +12,15 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/of.h>	/* linux/of.h gets to determine #include ordering */
+
 #ifndef _ASM_MICROBLAZE_PROM_H
 #define _ASM_MICROBLAZE_PROM_H
 #ifdef __KERNEL__
-
-/* Definitions used by the flattened device tree */
-#define OF_DT_HEADER		0xd00dfeed /* marker */
-#define OF_DT_BEGIN_NODE	0x1 /* Start of node, full name */
-#define OF_DT_END_NODE		0x2 /* End node */
-#define OF_DT_PROP		0x3 /* Property: name off, size, content */
-#define OF_DT_NOP		0x4 /* nop */
-#define OF_DT_END		0x9
-
-#define OF_DT_VERSION		0x10
-
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/of_fdt.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
 #include <asm/irq.h>
@@ -41,122 +33,19 @@
 #define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
 #define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
 
-/*
- * This is what gets passed to the kernel by prom_init or kexec
- *
- * The dt struct contains the device tree structure, full pathes and
- * property contents. The dt strings contain a separate block with just
- * the strings for the property names, and is fully page aligned and
- * self contained in a page, so that it can be kept around by the kernel,
- * each property name appears only once in this page (cheap compression)
- *
- * the mem_rsvmap contains a map of reserved ranges of physical memory,
- * passing it here instead of in the device-tree itself greatly simplifies
- * the job of everybody. It's just a list of u64 pairs (base/size) that
- * ends when size is 0
- */
-struct boot_param_header {
-	u32	magic; /* magic word OF_DT_HEADER */
-	u32	totalsize; /* total size of DT block */
-	u32	off_dt_struct; /* offset to structure */
-	u32	off_dt_strings; /* offset to strings */
-	u32	off_mem_rsvmap; /* offset to memory reserve map */
-	u32	version; /* format version */
-	u32	last_comp_version; /* last compatible version */
-	/* version 2 fields below */
-	u32	boot_cpuid_phys; /* Physical CPU id we're booting on */
-	/* version 3 fields below */
-	u32	dt_strings_size; /* size of the DT strings block */
-	/* version 17 fields below */
-	u32	dt_struct_size; /* size of the DT structure block */
-};
-
-typedef u32 phandle;
-typedef u32 ihandle;
-
-struct property {
-	char	*name;
-	int	length;
-	void	*value;
-	struct property *next;
-};
-
-struct device_node {
-	const char *name;
-	const char *type;
-	phandle	node;
-	phandle linux_phandle;
-	char	*full_name;
-
-	struct	property *properties;
-	struct	property *deadprops; /* removed properties */
-	struct	device_node *parent;
-	struct	device_node *child;
-	struct	device_node *sibling;
-	struct	device_node *next; /* next device of same type */
-	struct	device_node *allnext; /* next in list of all nodes */
-	struct	proc_dir_entry *pde; /* this node's proc directory */
-	struct	kref kref;
-	unsigned long _flags;
-	void	*data;
-};
-
 extern struct device_node *of_chosen;
 
-static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
-{
-	return test_bit(flag, &n->_flags);
-}
-
-static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
-{
-	set_bit(flag, &n->_flags);
-}
-
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
-static inline void set_node_proc_entry(struct device_node *dn,
-					struct proc_dir_entry *de)
-{
-	dn->pde = de;
-}
-
 extern struct device_node *allnodes;	/* temporary while merging */
 extern rwlock_t devtree_lock;	/* temporary while merging */
 
-extern struct device_node *of_find_all_nodes(struct device_node *prev);
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-
-/* For scanning the flat device-tree at boot time */
-extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
-					const char *uname, int depth,
-					void *data),
-				void *data);
-extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
-					unsigned long *size);
-extern int __init
-		of_flat_dt_is_compatible(unsigned long node, const char *name);
-extern unsigned long __init of_get_flat_dt_root(void);
-
 /* For updating the device tree at runtime */
 extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 
 /* Other Prototypes */
-extern void finish_device_tree(void);
-extern void unflatten_device_tree(void);
 extern int early_uartlite_console(void);
-extern void early_init_devtree(void *);
-extern int machine_is_compatible(const char *compat);
-extern void print_properties(struct device_node *node);
-extern int prom_n_intr_cells(struct device_node *np);
-extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern int prom_add_property(struct device_node *np, struct property *prop);
-extern int prom_remove_property(struct device_node *np, struct property *prop);
-extern int prom_update_property(struct device_node *np,
-				struct property *newprop,
-				struct property *oldprop);
 
 extern struct resource *request_OF_resource(struct device_node *node,
 				int index, const char *name_postfix);
@@ -166,18 +55,6 @@ extern int release_OF_resource(struct de
  * OF address retreival & translation
  */
 
-/* Helper to read a big number; size is in cells (not bytes) */
-static inline u64 of_read_number(const u32 *cell, int size)
-{
-	u64 r = 0;
-	while (size--)
-		r = (r << 32) | *(cell++);
-	return r;
-}
-
-/* Like of_read_number, but we want an unsigned long result */
-#define of_read_ulong(cell, size)	of_read_number(cell, size)
-
 /* Translate an OF address block into a CPU physical address
  */
 extern u64 of_translate_address(struct device_node *np, const u32 *addr);
@@ -305,12 +182,6 @@ extern int of_irq_to_resource(struct dev
  */
 extern void __iomem *of_iomap(struct device_node *device, int index);
 
-/*
- * NB: This is here while we transition from using asm/prom.h
- * to linux/of.h
- */
-#include <linux/of.h>
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_MICROBLAZE_PROM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,6 +54,7 @@ struct pt_regs {
 	int pt_mode;
 };
 
+#ifdef __KERNEL__
 #define kernel_mode(regs)		((regs)->pt_mode)
 #define user_mode(regs)			(!kernel_mode(regs))
 
@@ -62,6 +63,19 @@ struct pt_regs {
 
 void show_regs(struct pt_regs *);
 
+#else /* __KERNEL__ */
+
+/* pt_regs offsets used by gdbserver etc in ptrace syscalls */
+#define PT_GPR(n)       ((n) * sizeof(microblaze_reg_t))
+#define PT_PC           (32 * sizeof(microblaze_reg_t))
+#define PT_MSR          (33 * sizeof(microblaze_reg_t))
+#define PT_EAR          (34 * sizeof(microblaze_reg_t))
+#define PT_ESR          (35 * sizeof(microblaze_reg_t))
+#define PT_FSR          (36 * sizeof(microblaze_reg_t))
+#define PT_KERNEL_MODE  (37 * sizeof(microblaze_reg_t))
+
+#endif /* __KERNEL */
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_MICROBLAZE_PTRACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/pvr.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pvr.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/pvr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/pvr.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,20 +76,23 @@ struct pvr_s {
 #define PVR3_FSL_LINKS_MASK		0x00000380
 
 /* ICache config PVR masks */
-#define PVR4_USE_ICACHE_MASK		0x80000000
-#define PVR4_ICACHE_ADDR_TAG_BITS_MASK	0x7C000000
-#define PVR4_ICACHE_USE_FSL_MASK	0x02000000
-#define PVR4_ICACHE_ALLOW_WR_MASK	0x01000000
-#define PVR4_ICACHE_LINE_LEN_MASK	0x00E00000
-#define PVR4_ICACHE_BYTE_SIZE_MASK	0x001F0000
+#define PVR4_USE_ICACHE_MASK		0x80000000 /* ICU */
+#define PVR4_ICACHE_ADDR_TAG_BITS_MASK	0x7C000000 /* ICTS */
+#define PVR4_ICACHE_ALLOW_WR_MASK	0x01000000 /* ICW */
+#define PVR4_ICACHE_LINE_LEN_MASK	0x00E00000 /* ICLL */
+#define PVR4_ICACHE_BYTE_SIZE_MASK	0x001F0000 /* ICBS */
+#define PVR4_ICACHE_ALWAYS_USED		0x00008000 /* IAU */
+#define PVR4_ICACHE_INTERFACE		0x00002000 /* ICI */
 
 /* DCache config PVR masks */
-#define PVR5_USE_DCACHE_MASK		0x80000000
-#define PVR5_DCACHE_ADDR_TAG_BITS_MASK	0x7C000000
-#define PVR5_DCACHE_USE_FSL_MASK	0x02000000
-#define PVR5_DCACHE_ALLOW_WR_MASK	0x01000000
-#define PVR5_DCACHE_LINE_LEN_MASK	0x00E00000
-#define PVR5_DCACHE_BYTE_SIZE_MASK	0x001F0000
+#define PVR5_USE_DCACHE_MASK		0x80000000 /* DCU */
+#define PVR5_DCACHE_ADDR_TAG_BITS_MASK	0x7C000000 /* DCTS */
+#define PVR5_DCACHE_ALLOW_WR_MASK	0x01000000 /* DCW */
+#define PVR5_DCACHE_LINE_LEN_MASK	0x00E00000 /* DCLL */
+#define PVR5_DCACHE_BYTE_SIZE_MASK	0x001F0000 /* DCBS */
+#define PVR5_DCACHE_ALWAYS_USED		0x00008000 /* DAU */
+#define PVR5_DCACHE_USE_WRITEBACK	0x00004000 /* DWB */
+#define PVR5_DCACHE_INTERFACE		0x00002000 /* DCI */
 
 /* ICache base address PVR mask */
 #define PVR6_ICACHE_BASEADDR_MASK	0xFFFFFFFF
@@ -178,11 +181,14 @@ struct pvr_s {
 			((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
 #define PVR_DCACHE_USE_FSL(pvr)		(pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
 #define PVR_DCACHE_ALLOW_WR(pvr)	(pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
+/* FIXME two shifts on one line needs any comment */
 #define PVR_DCACHE_LINE_LEN(pvr) \
 			(1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
 #define PVR_DCACHE_BYTE_SIZE(pvr) \
 			(1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
 
+#define PVR_DCACHE_USE_WRITEBACK(pvr) \
+			((pvr.pvr[5] & PVR5_DCACHE_USE_WRITEBACK) >> 14)
 
 #define PVR_ICACHE_BASEADDR(pvr)	(pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
 #define PVR_ICACHE_HIGHADDR(pvr)	(pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/setup.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/setup.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/setup.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,8 @@ extern void mmu_reset(void);
 extern void early_console_reg_tlb_alloc(unsigned int addr);
 #   endif /* CONFIG_MMU */
 
+extern void of_platform_reset_gpio_probe(void);
+
 void time_init(void);
 void init_IRQ(void);
 void machine_early_init(const char *cmdline, unsigned int ram,
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/system.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/system.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,8 @@
 #include <asm-generic/cmpxchg.h>
 #include <asm-generic/cmpxchg-local.h>
 
+#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
+
 struct task_struct;
 struct thread_info;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/uaccess.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/uaccess.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/uaccess.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
@@ -272,8 +272,9 @@ static inline int clear_user(char *to, i
 	return size;
 }
 
-extern unsigned long __copy_tofrom_user(void __user *to,
-		const void __user *from, unsigned long size);
+#define __copy_from_user(to, from, n)	copy_from_user((to), (from), (n))
+#define __copy_from_user_inatomic(to, from, n) \
+		copy_from_user((to), (from), (n))
 
 #define copy_to_user(to, from, n)					\
 	(access_ok(VERIFY_WRITE, (to), (n)) ?				\
@@ -290,10 +291,6 @@ extern unsigned long __copy_tofrom_user(
 			(void __user *)(from), (n))			\
 		: -EFAULT)
 
-#define __copy_from_user(to, from, n)	copy_from_user((to), (from), (n))
-#define __copy_from_user_inatomic(to, from, n) \
-		copy_from_user((to), (from), (n))
-
 extern int __strncpy_user(char *to, const char __user *from, int len);
 extern int __strnlen_user(const char __user *sstr, int len);
 
@@ -305,6 +302,9 @@ extern int __strnlen_user(const char __u
 
 #endif /* CONFIG_MMU */
 
+extern unsigned long __copy_tofrom_user(void __user *to,
+		const void __user *from, unsigned long size);
+
 /*
  * The exception table consists of pairs of addresses: the first is the
  * address of an instruction that is allowed to fault, and the second is
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/microblaze/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -377,13 +377,14 @@
 #define __NR_shutdown		359 /* new */
 #define __NR_sendmsg		360 /* new */
 #define __NR_recvmsg		361 /* new */
-#define __NR_accept04		362 /* new */
+#define __NR_accept4		362 /* new */
 #define __NR_preadv		363 /* new */
 #define __NR_pwritev		364 /* new */
 #define __NR_rt_tgsigqueueinfo	365 /* new */
 #define __NR_perf_event_open	366 /* new */
+#define __NR_recvmmsg		367 /* new */
 
-#define __NR_syscalls		367
+#define __NR_syscalls		368
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/Kconfig linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig
--- linux-libre-2.6.32-gnu1/arch/microblaze/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -6,8 +6,15 @@ mainmenu "Linux/Microblaze Kernel Config
 config MICROBLAZE
 	def_bool y
 	select HAVE_LMB
+	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_DYNAMIC_FTRACE
+	select HAVE_FTRACE_MCOUNT_RECORD
 	select USB_ARCH_HAS_EHCI
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select HAVE_OPROFILE
+	select TRACING_SUPPORT
 
 config SWAP
 	def_bool n
@@ -57,12 +64,24 @@ config GENERIC_GPIO
 config GENERIC_CSUM
 	def_bool y
 
+config STACKTRACE_SUPPORT
+	def_bool y
+
+config LOCKDEP_SUPPORT
+	def_bool y
+
+config HAVE_LATENCYTOP_SUPPORT
+	def_bool y
+
 config PCI
 	def_bool n
 
 config NO_DMA
 	def_bool y
 
+config DTC
+	def_bool y
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -71,7 +90,7 @@ source "arch/microblaze/platform/Kconfig
 
 menu "Processor type and features"
 
-source kernel/time/Kconfig
+source "kernel/time/Kconfig"
 
 source "kernel/Kconfig.preempt"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/Kconfig.debug linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/microblaze/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -3,6 +3,9 @@
 
 menu "Kernel hacking"
 
+config TRACE_IRQFLAGS_SUPPORT
+	def_bool y
+
 source "lib/Kconfig.debug"
 
 config EARLY_PRINTK
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cache.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cache.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cache.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cache.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
  * Copyright (C) 2007-2009 PetaLogix
- * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007-2009 John Williams <john.williams@petalogix.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
@@ -13,243 +13,523 @@
 #include <asm/cacheflush.h>
 #include <linux/cache.h>
 #include <asm/cpuinfo.h>
+#include <asm/pvr.h>
 
-/* Exported functions */
+static inline void __invalidate_flush_icache(unsigned int addr)
+{
+	__asm__ __volatile__ ("wic	%0, r0;"	\
+					: : "r" (addr));
+}
 
-void _enable_icache(void)
+static inline void __flush_dcache(unsigned int addr)
 {
-	if (cpuinfo.use_icache) {
-#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
-		__asm__ __volatile__ ("					\
-				msrset	r0, %0;				\
-				nop; "					\
-				:					\
-				: "i" (MSR_ICE)				\
+	__asm__ __volatile__ ("wdc.flush	%0, r0;"	\
+					: : "r" (addr));
+}
+
+static inline void __invalidate_dcache(unsigned int baseaddr,
+						unsigned int offset)
+{
+	__asm__ __volatile__ ("wdc.clear	%0, %1;"	\
+					: : "r" (baseaddr), "r" (offset));
+}
+
+static inline void __enable_icache_msr(void)
+{
+	__asm__ __volatile__ ("	msrset	r0, %0;		\
+				nop; "			\
+			: : "i" (MSR_ICE) : "memory");
+}
+
+static inline void __disable_icache_msr(void)
+{
+	__asm__ __volatile__ ("	msrclr	r0, %0;		\
+				nop; "			\
+			: : "i" (MSR_ICE) : "memory");
+}
+
+static inline void __enable_dcache_msr(void)
+{
+	__asm__ __volatile__ ("	msrset	r0, %0;		\
+				nop; "			\
+				:			\
+				: "i" (MSR_DCE)		\
 				: "memory");
-#else
-		__asm__ __volatile__ ("					\
-				mfs	r12, rmsr;			\
-				nop;					\
-				ori	r12, r12, %0;			\
-				mts	rmsr, r12;			\
-				nop; "					\
-				:					\
-				: "i" (MSR_ICE)				\
-				: "memory", "r12");
-#endif
-	}
 }
 
-void _disable_icache(void)
+static inline void __disable_dcache_msr(void)
 {
-	if (cpuinfo.use_icache) {
-#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
-		__asm__ __volatile__ ("					\
-				msrclr r0, %0;				\
-				nop; "					\
-				:					\
-				: "i" (MSR_ICE)				\
+	__asm__ __volatile__ ("	msrclr	r0, %0;		\
+				nop; "			\
+				:			\
+				: "i" (MSR_DCE)		\
 				: "memory");
-#else
-		__asm__ __volatile__ ("					\
-				mfs	r12, rmsr;			\
-				nop;					\
-				andi	r12, r12, ~%0;			\
-				mts	rmsr, r12;			\
-				nop; "					\
-				:					\
-				: "i" (MSR_ICE)				\
+}
+
+static inline void __enable_icache_nomsr(void)
+{
+	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
+				nop;			\
+				ori	r12, r12, %0;	\
+				mts	rmsr, r12;	\
+				nop; "			\
+				:			\
+				: "i" (MSR_ICE)		\
 				: "memory", "r12");
-#endif
-	}
 }
 
-void _invalidate_icache(unsigned int addr)
+static inline void __disable_icache_nomsr(void)
 {
-	if (cpuinfo.use_icache) {
-		__asm__ __volatile__ ("					\
-				wic	%0, r0"				\
-				:					\
-				: "r" (addr));
-	}
+	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
+				nop;			\
+				andi	r12, r12, ~%0;	\
+				mts	rmsr, r12;	\
+				nop; "			\
+				:			\
+				: "i" (MSR_ICE)		\
+				: "memory", "r12");
 }
 
-void _enable_dcache(void)
+static inline void __enable_dcache_nomsr(void)
 {
-	if (cpuinfo.use_dcache) {
-#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
-		__asm__ __volatile__ ("					\
-				msrset	r0, %0;				\
-				nop; "					\
-				:					\
-				: "i" (MSR_DCE)				\
-				: "memory");
-#else
-		__asm__ __volatile__ ("					\
-				mfs	r12, rmsr;			\
-				nop;					\
-				ori	r12, r12, %0;			\
-				mts	rmsr, r12;			\
-				nop; "					\
-				:					\
-				: "i" (MSR_DCE)			\
+	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
+				nop;			\
+				ori	r12, r12, %0;	\
+				mts	rmsr, r12;	\
+				nop; "			\
+				:			\
+				: "i" (MSR_DCE)		\
 				: "memory", "r12");
-#endif
-	}
 }
 
-void _disable_dcache(void)
+static inline void __disable_dcache_nomsr(void)
 {
-#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
-		__asm__ __volatile__ ("					\
-				msrclr	r0, %0;				\
-				nop; "					\
-				:					\
-				: "i" (MSR_DCE)			\
-				: "memory");
-#else
-		__asm__ __volatile__ ("					\
-				mfs	r12, rmsr;			\
-				nop;					\
-				andi	r12, r12, ~%0;			\
-				mts	rmsr, r12;			\
-				nop; "					\
-				:					\
-				: "i" (MSR_DCE)			\
+	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
+				nop;			\
+				andi	r12, r12, ~%0;	\
+				mts	rmsr, r12;	\
+				nop; "			\
+				:			\
+				: "i" (MSR_DCE)		\
 				: "memory", "r12");
-#endif
 }
 
-void _invalidate_dcache(unsigned int addr)
+
+/* Helper macro for computing the limits of cache range loops */
+#define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)	\
+do {									\
+	int align = ~(cache_line_length - 1);				\
+	end = min(start + cache_size, end);				\
+	start &= align;							\
+	end = ((end & align) + cache_line_length);			\
+} while (0);
+
+/*
+ * Helper macro to loop over the specified cache_size/line_length and
+ * execute 'op' on that cacheline
+ */
+#define CACHE_ALL_LOOP(cache_size, line_length, op)			\
+do {									\
+	unsigned int len = cache_size;					\
+	int step = -line_length;					\
+	BUG_ON(step >= 0);						\
+									\
+	__asm__ __volatile__ (" 1:      " #op " %0, r0;			\
+					bgtid   %0, 1b;			\
+					addk    %0, %0, %1;		\
+					" : : "r" (len), "r" (step)	\
+					: "memory");			\
+} while (0);
+
+
+#define CACHE_ALL_LOOP2(cache_size, line_length, op)			\
+do {									\
+	unsigned int len = cache_size;					\
+	int step = -line_length;					\
+	BUG_ON(step >= 0);						\
+									\
+	__asm__ __volatile__ (" 1:      " #op " r0, %0;			\
+					bgtid   %0, 1b;			\
+					addk    %0, %0, %1;		\
+					" : : "r" (len), "r" (step)	\
+					: "memory");			\
+} while (0);
+
+/* for wdc.flush/clear */
+#define CACHE_RANGE_LOOP_2(start, end, line_length, op)			\
+do {									\
+	int step = -line_length;					\
+	int count = end - start;					\
+	BUG_ON(count <= 0);						\
+									\
+	__asm__ __volatile__ (" 1:	" #op " %0, %1;			\
+					bgtid   %1, 1b;			\
+					addk    %1, %1, %2;		\
+					" : : "r" (start), "r" (count),	\
+					"r" (step) : "memory");		\
+} while (0);
+
+/* It is used only first parameter for OP - for wic, wdc */
+#define CACHE_RANGE_LOOP_1(start, end, line_length, op)			\
+do {									\
+	int volatile temp;						\
+	BUG_ON(end - start <= 0);					\
+									\
+	__asm__ __volatile__ (" 1:	" #op " %1, r0;			\
+					cmpu	%0, %1, %2;		\
+					bgtid	%0, 1b;			\
+					addk	%1, %1, %3;		\
+				" : : "r" (temp), "r" (start), "r" (end),\
+					"r" (line_length) : "memory");	\
+} while (0);
+
+static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 {
-		__asm__ __volatile__ ("					\
-				wdc	%0, r0"				\
-				:					\
-				: "r" (addr));
+	unsigned long flags;
+
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
+
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.icache_line_length, cpuinfo.icache_size);
+
+	local_irq_save(flags);
+	__disable_icache_msr();
+
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+
+	__enable_icache_msr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_icache_all(void)
+static void __flush_icache_range_nomsr_irq(unsigned long start,
+				unsigned long end)
 {
-	unsigned int i;
-	unsigned flags;
+	unsigned long flags;
 
-	if (cpuinfo.use_icache) {
-		local_irq_save(flags);
-		__disable_icache();
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
 
-		/* Just loop through cache size and invalidate, no need to add
-			CACHE_BASE address */
-		for (i = 0; i < cpuinfo.icache_size;
-			i += cpuinfo.icache_line)
-				__invalidate_icache(i);
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.icache_line_length, cpuinfo.icache_size);
 
-		__enable_icache();
-		local_irq_restore(flags);
-	}
+	local_irq_save(flags);
+	__disable_icache_nomsr();
+
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+
+	__enable_icache_nomsr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_icache_range(unsigned long start, unsigned long end)
+static void __flush_icache_range_noirq(unsigned long start,
+				unsigned long end)
 {
-	unsigned int i;
-	unsigned flags;
-	unsigned int align;
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
 
-	if (cpuinfo.use_icache) {
-		/*
-		 * No need to cover entire cache range,
-		 * just cover cache footprint
-		 */
-		end = min(start + cpuinfo.icache_size, end);
-		align = ~(cpuinfo.icache_line - 1);
-		start &= align; /* Make sure we are aligned */
-		/* Push end up to the next cache line */
-		end = ((end & align) + cpuinfo.icache_line);
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.icache_line_length, cpuinfo.icache_size);
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+}
 
-		local_irq_save(flags);
-		__disable_icache();
+static void __flush_icache_all_msr_irq(void)
+{
+	unsigned long flags;
 
-		for (i = start; i < end; i += cpuinfo.icache_line)
-			__invalidate_icache(i);
+	pr_debug("%s\n", __func__);
 
-		__enable_icache();
-		local_irq_restore(flags);
-	}
+	local_irq_save(flags);
+	__disable_icache_msr();
+
+	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+
+	__enable_icache_msr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page)
+static void __flush_icache_all_nomsr_irq(void)
 {
-	__invalidate_icache_all();
+	unsigned long flags;
+
+	pr_debug("%s\n", __func__);
+
+	local_irq_save(flags);
+	__disable_icache_nomsr();
+
+	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+
+	__enable_icache_nomsr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_icache_user_range(struct vm_area_struct *vma,
-				struct page *page, unsigned long adr,
-				int len)
+static void __flush_icache_all_noirq(void)
 {
-	__invalidate_icache_all();
+	pr_debug("%s\n", __func__);
+	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
 }
 
-void __invalidate_cache_sigtramp(unsigned long addr)
+static void __invalidate_dcache_all_msr_irq(void)
 {
-	__invalidate_icache_range(addr, addr + 8);
+	unsigned long flags;
+
+	pr_debug("%s\n", __func__);
+
+	local_irq_save(flags);
+	__disable_dcache_msr();
+
+	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
+
+	__enable_dcache_msr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_dcache_all(void)
+static void __invalidate_dcache_all_nomsr_irq(void)
 {
-	unsigned int i;
-	unsigned flags;
+	unsigned long flags;
 
-	if (cpuinfo.use_dcache) {
-		local_irq_save(flags);
-		__disable_dcache();
+	pr_debug("%s\n", __func__);
 
-		/*
-		 * Just loop through cache size and invalidate,
-		 * no need to add CACHE_BASE address
-		 */
-		for (i = 0; i < cpuinfo.dcache_size;
-			i += cpuinfo.dcache_line)
-				__invalidate_dcache(i);
+	local_irq_save(flags);
+	__disable_dcache_nomsr();
 
-		__enable_dcache();
-		local_irq_restore(flags);
-	}
+	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
+
+	__enable_dcache_nomsr();
+	local_irq_restore(flags);
 }
 
-void __invalidate_dcache_range(unsigned long start, unsigned long end)
+static void __invalidate_dcache_all_noirq_wt(void)
 {
-	unsigned int i;
-	unsigned flags;
-	unsigned int align;
+	pr_debug("%s\n", __func__);
+	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
+}
 
-	if (cpuinfo.use_dcache) {
-		/*
-		 * No need to cover entire cache range,
-		 * just cover cache footprint
-		 */
-		end = min(start + cpuinfo.dcache_size, end);
-		align = ~(cpuinfo.dcache_line - 1);
-		start &= align; /* Make sure we are aligned */
-		/* Push end up to the next cache line */
-		end = ((end & align) + cpuinfo.dcache_line);
-		local_irq_save(flags);
-		__disable_dcache();
+/* FIXME this is weird - should be only wdc but not work
+ * MS: I am getting bus errors and other weird things */
+static void __invalidate_dcache_all_wb(void)
+{
+	pr_debug("%s\n", __func__);
+	CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+					wdc.clear)
+}
 
-		for (i = start; i < end; i += cpuinfo.dcache_line)
-			__invalidate_dcache(i);
+static void __invalidate_dcache_range_wb(unsigned long start,
+						unsigned long end)
+{
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
 
-		__enable_dcache();
-		local_irq_restore(flags);
-	}
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
 }
 
-void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page)
+static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
+							unsigned long end)
 {
-	__invalidate_dcache_all();
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 }
 
-void __invalidate_dcache_user_range(struct vm_area_struct *vma,
-				struct page *page, unsigned long adr,
-				int len)
+static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
+							unsigned long end)
 {
-	__invalidate_dcache_all();
+	unsigned long flags;
+
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+
+	local_irq_save(flags);
+	__disable_dcache_msr();
+
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+
+	__enable_dcache_msr();
+	local_irq_restore(flags);
+}
+
+static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
+							unsigned long end)
+{
+	unsigned long flags;
+
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
+
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+
+	local_irq_save(flags);
+	__disable_dcache_nomsr();
+
+	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+
+	__enable_dcache_nomsr();
+	local_irq_restore(flags);
+}
+
+static void __flush_dcache_all_wb(void)
+{
+	pr_debug("%s\n", __func__);
+	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+				wdc.flush);
+}
+
+static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
+{
+	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
+				(unsigned int)start, (unsigned int) end);
+
+	CACHE_LOOP_LIMITS(start, end,
+			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
+}
+
+/* struct for wb caches and for wt caches */
+struct scache *mbc;
+
+/* new wb cache model */
+const struct scache wb_msr = {
+	.ie = __enable_icache_msr,
+	.id = __disable_icache_msr,
+	.ifl = __flush_icache_all_noirq,
+	.iflr = __flush_icache_range_noirq,
+	.iin = __flush_icache_all_noirq,
+	.iinr = __flush_icache_range_noirq,
+	.de = __enable_dcache_msr,
+	.dd = __disable_dcache_msr,
+	.dfl = __flush_dcache_all_wb,
+	.dflr = __flush_dcache_range_wb,
+	.din = __invalidate_dcache_all_wb,
+	.dinr = __invalidate_dcache_range_wb,
+};
+
+/* There is only difference in ie, id, de, dd functions */
+const struct scache wb_nomsr = {
+	.ie = __enable_icache_nomsr,
+	.id = __disable_icache_nomsr,
+	.ifl = __flush_icache_all_noirq,
+	.iflr = __flush_icache_range_noirq,
+	.iin = __flush_icache_all_noirq,
+	.iinr = __flush_icache_range_noirq,
+	.de = __enable_dcache_nomsr,
+	.dd = __disable_dcache_nomsr,
+	.dfl = __flush_dcache_all_wb,
+	.dflr = __flush_dcache_range_wb,
+	.din = __invalidate_dcache_all_wb,
+	.dinr = __invalidate_dcache_range_wb,
+};
+
+/* Old wt cache model with disabling irq and turn off cache */
+const struct scache wt_msr = {
+	.ie = __enable_icache_msr,
+	.id = __disable_icache_msr,
+	.ifl = __flush_icache_all_msr_irq,
+	.iflr = __flush_icache_range_msr_irq,
+	.iin = __flush_icache_all_msr_irq,
+	.iinr = __flush_icache_range_msr_irq,
+	.de = __enable_dcache_msr,
+	.dd = __disable_dcache_msr,
+	.dfl = __invalidate_dcache_all_msr_irq,
+	.dflr = __invalidate_dcache_range_msr_irq_wt,
+	.din = __invalidate_dcache_all_msr_irq,
+	.dinr = __invalidate_dcache_range_msr_irq_wt,
+};
+
+const struct scache wt_nomsr = {
+	.ie = __enable_icache_nomsr,
+	.id = __disable_icache_nomsr,
+	.ifl = __flush_icache_all_nomsr_irq,
+	.iflr = __flush_icache_range_nomsr_irq,
+	.iin = __flush_icache_all_nomsr_irq,
+	.iinr = __flush_icache_range_nomsr_irq,
+	.de = __enable_dcache_nomsr,
+	.dd = __disable_dcache_nomsr,
+	.dfl = __invalidate_dcache_all_nomsr_irq,
+	.dflr = __invalidate_dcache_range_nomsr_irq,
+	.din = __invalidate_dcache_all_nomsr_irq,
+	.dinr = __invalidate_dcache_range_nomsr_irq,
+};
+
+/* New wt cache model for newer Microblaze versions */
+const struct scache wt_msr_noirq = {
+	.ie = __enable_icache_msr,
+	.id = __disable_icache_msr,
+	.ifl = __flush_icache_all_noirq,
+	.iflr = __flush_icache_range_noirq,
+	.iin = __flush_icache_all_noirq,
+	.iinr = __flush_icache_range_noirq,
+	.de = __enable_dcache_msr,
+	.dd = __disable_dcache_msr,
+	.dfl = __invalidate_dcache_all_noirq_wt,
+	.dflr = __invalidate_dcache_range_nomsr_wt,
+	.din = __invalidate_dcache_all_noirq_wt,
+	.dinr = __invalidate_dcache_range_nomsr_wt,
+};
+
+const struct scache wt_nomsr_noirq = {
+	.ie = __enable_icache_nomsr,
+	.id = __disable_icache_nomsr,
+	.ifl = __flush_icache_all_noirq,
+	.iflr = __flush_icache_range_noirq,
+	.iin = __flush_icache_all_noirq,
+	.iinr = __flush_icache_range_noirq,
+	.de = __enable_dcache_nomsr,
+	.dd = __disable_dcache_nomsr,
+	.dfl = __invalidate_dcache_all_noirq_wt,
+	.dflr = __invalidate_dcache_range_nomsr_wt,
+	.din = __invalidate_dcache_all_noirq_wt,
+	.dinr = __invalidate_dcache_range_nomsr_wt,
+};
+
+/* CPU version code for 7.20.c - see arch/microblaze/kernel/cpu/cpuinfo.c */
+#define CPUVER_7_20_A	0x0c
+#define CPUVER_7_20_D	0x0f
+
+#define INFO(s)	printk(KERN_INFO "cache: " s " \n");
+
+void microblaze_cache_init(void)
+{
+	if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
+		if (cpuinfo.dcache_wb) {
+			INFO("wb_msr");
+			mbc = (struct scache *)&wb_msr;
+			if (cpuinfo.ver_code < CPUVER_7_20_D) {
+				/* MS: problem with signal handling - hw bug */
+				INFO("WB won't work properly");
+			}
+		} else {
+			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
+				INFO("wt_msr_noirq");
+				mbc = (struct scache *)&wt_msr_noirq;
+			} else {
+				INFO("wt_msr");
+				mbc = (struct scache *)&wt_msr;
+			}
+		}
+	} else {
+		if (cpuinfo.dcache_wb) {
+			INFO("wb_nomsr");
+			mbc = (struct scache *)&wb_nomsr;
+			if (cpuinfo.ver_code < CPUVER_7_20_D) {
+				/* MS: problem with signal handling - hw bug */
+				INFO("WB won't work properly");
+			}
+		} else {
+			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
+				INFO("wt_nomsr_noirq");
+				mbc = (struct scache *)&wt_nomsr_noirq;
+			} else {
+				INFO("wt_nomsr");
+				mbc = (struct scache *)&wt_nomsr;
+			}
+		}
+	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,11 +29,8 @@ const struct cpu_ver_key cpu_ver_lookup[
 	{"7.20.a", 0x0c},
 	{"7.20.b", 0x0d},
 	{"7.20.c", 0x0e},
-	/* FIXME There is no keycode defined in MBV for these versions */
-	{"2.10.a", 0x10},
-	{"3.00.a", 0x20},
-	{"4.00.a", 0x30},
-	{"4.00.b", 0x40},
+	{"7.20.d", 0x0f},
+	{"7.30.a", 0x10},
 	{NULL, 0},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,8 +21,14 @@
  */
 
 #define CI(c, p) { ci->c = PVR_##p(pvr); }
+
+#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
 #define err_printk(x) \
 	early_printk("ERROR: Microblaze " x "-different for PVR and DTS\n");
+#else
+#define err_printk(x) \
+	printk(KERN_INFO "ERROR: Microblaze " x "-different for PVR and DTS\n");
+#endif
 
 void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
 {
@@ -70,7 +76,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo
 	CI(use_icache, USE_ICACHE);
 	CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
 	CI(icache_write, ICACHE_ALLOW_WR);
-	CI(icache_line, ICACHE_LINE_LEN);
+	ci->icache_line_length = PVR_ICACHE_LINE_LEN(pvr) << 2;
 	CI(icache_size, ICACHE_BYTE_SIZE);
 	CI(icache_base, ICACHE_BASEADDR);
 	CI(icache_high, ICACHE_HIGHADDR);
@@ -78,11 +84,16 @@ void set_cpuinfo_pvr_full(struct cpuinfo
 	CI(use_dcache, USE_DCACHE);
 	CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS);
 	CI(dcache_write, DCACHE_ALLOW_WR);
-	CI(dcache_line, DCACHE_LINE_LEN);
+	ci->dcache_line_length = PVR_DCACHE_LINE_LEN(pvr) << 2;
 	CI(dcache_size, DCACHE_BYTE_SIZE);
 	CI(dcache_base, DCACHE_BASEADDR);
 	CI(dcache_high, DCACHE_HIGHADDR);
 
+	temp = PVR_DCACHE_USE_WRITEBACK(pvr);
+	if (ci->dcache_wb != temp)
+		err_printk("DCACHE WB");
+	ci->dcache_wb = temp;
+
 	CI(use_dopb, D_OPB);
 	CI(use_iopb, I_OPB);
 	CI(use_dlmb, D_LMB);
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,12 +72,12 @@ void __init set_cpuinfo_static(struct cp
 	ci->use_icache = fcpu(cpu, "xlnx,use-icache");
 	ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits");
 	ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr");
-	ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2;
-	if (!ci->icache_line) {
+	ci->icache_line_length = fcpu(cpu, "xlnx,icache-line-len") << 2;
+	if (!ci->icache_line_length) {
 		if (fcpu(cpu, "xlnx,icache-use-fsl"))
-			ci->icache_line = 4 << 2;
+			ci->icache_line_length = 4 << 2;
 		else
-			ci->icache_line = 1 << 2;
+			ci->icache_line_length = 1 << 2;
 	}
 	ci->icache_size = fcpu(cpu, "i-cache-size");
 	ci->icache_base = fcpu(cpu, "i-cache-baseaddr");
@@ -86,16 +86,17 @@ void __init set_cpuinfo_static(struct cp
 	ci->use_dcache = fcpu(cpu, "xlnx,use-dcache");
 	ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag");
 	ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr");
-	ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2;
-	if (!ci->dcache_line) {
+	ci->dcache_line_length = fcpu(cpu, "xlnx,dcache-line-len") << 2;
+	if (!ci->dcache_line_length) {
 		if (fcpu(cpu, "xlnx,dcache-use-fsl"))
-			ci->dcache_line = 4 << 2;
+			ci->dcache_line_length = 4 << 2;
 		else
-			ci->dcache_line = 1 << 2;
+			ci->dcache_line_length = 1 << 2;
 	}
 	ci->dcache_size = fcpu(cpu, "d-cache-size");
 	ci->dcache_base = fcpu(cpu, "d-cache-baseaddr");
 	ci->dcache_high = fcpu(cpu, "d-cache-highaddr");
+	ci->dcache_wb = fcpu(cpu, "xlnx,dcache-use-writeback");
 
 	ci->use_dopb = fcpu(cpu, "xlnx,d-opb");
 	ci->use_iopb = fcpu(cpu, "xlnx,i-opb");
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/Makefile linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/Makefile
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,10 @@
 # Build the appropriate CPU version support
 #
 
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_cache.o = -pg
+endif
+
 EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
 		-DCPU_REV=$(CPU_REV)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/mb.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/mb.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/mb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/mb.c	2010-02-24 13:52:17.000000000 -0500
@@ -103,11 +103,15 @@ static int show_cpuinfo(struct seq_file
 	else
 		count += seq_printf(m, "Icache:\t\tno\n");
 
-	if (cpuinfo.use_dcache)
+	if (cpuinfo.use_dcache) {
 		count += seq_printf(m,
 				"Dcache:\t\t%ukB\n",
 				cpuinfo.dcache_size >> 10);
-	else
+		if (cpuinfo.dcache_wb)
+			count += seq_printf(m, "\t\twrite-back\n");
+		else
+			count += seq_printf(m, "\t\twrite-through\n");
+	} else
 		count += seq_printf(m, "Dcache:\t\tno\n");
 
 	count += seq_printf(m,
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/pvr.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/pvr.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/cpu/pvr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/cpu/pvr.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,7 +45,7 @@
 
 int cpu_has_pvr(void)
 {
-	unsigned flags;
+	unsigned long flags;
 	unsigned pvr0;
 
 	local_save_flags(flags);
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/entry-nommu.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry-nommu.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/entry-nommu.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry-nommu.S	2010-02-24 13:52:17.000000000 -0500
@@ -122,7 +122,7 @@ ENTRY(_interrupt)
 
 ret_from_intr:
 	lwi	r11, r1, PT_MODE
-	bneid	r11, 3f
+	bneid	r11, no_intr_resched
 
 	lwi	r6, r31, TS_THREAD_INFO	/* get thread info */
 	lwi	r19, r6, TI_FLAGS	/* get flags in thread info */
@@ -133,16 +133,18 @@ ret_from_intr:
 	bralid	r15, schedule
 	nop
 1:	andi	r11, r19, _TIF_SIGPENDING
-	beqid	r11, no_intr_reshed
+	beqid	r11, no_intr_resched
 	addk	r5, r1, r0
 	addk	r7, r0, r0
 	bralid	r15, do_signal
 	addk	r6, r0, r0
 
-no_intr_reshed:
+no_intr_resched:
+	/* Disable interrupts, we are now committed to the state restore */
+	disable_irq
+
 	/* save mode indicator */
 	lwi	r11, r1, PT_MODE
-3:
 	swi	r11, r0, PER_CPU(KM)
 
 	/* save r31 */
@@ -208,8 +210,6 @@ ENTRY(_user_exception)
 	lwi	r1, r1, TS_THREAD_INFO		/* get the thread info */
 	/* calculate kernel stack pointer */
 	addik	r1, r1, THREAD_SIZE - PT_SIZE
-	swi	r11, r0, PER_CPU(R11_SAVE)	/* temporarily save r11 */
-	lwi	r11, r0, PER_CPU(KM)		/* load mode indicator */
 2:
 	swi	r11, r1, PT_MODE		/* store the mode */
 	lwi	r11, r0, PER_CPU(R11_SAVE)	/* reload r11 */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/entry.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,8 @@
 #include <linux/errno.h>
 #include <asm/signal.h>
 
+#undef DEBUG
+
 /* The size of a state save frame. */
 #define STATE_SAVE_SIZE		(PT_SIZE + STATE_SAVE_ARG_SPACE)
 
@@ -352,10 +354,12 @@ C_ENTRY(_user_exception):
 	add	r12, r12, r12;			/* convert num -> ptr */
 	add	r12, r12, r12;
 
+#ifdef DEBUG
 	/* Trac syscalls and stored them to r0_ram */
 	lwi	r3, r12, 0x400 + r0_ram
 	addi	r3, r3, 1
 	swi	r3, r12, 0x400 + r0_ram
+#endif
 
 	# Find and jump into the syscall handler.
 	lwi	r12, r12, sys_call_table
@@ -496,17 +500,6 @@ C_ENTRY(sys_execve):
 	brid	microblaze_execve;	/* Do real work (tail-call).*/
 	nop;
 
-C_ENTRY(sys_rt_sigsuspend_wrapper):
-	swi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
-	swi	r4, r1, PTO+PT_R4;
-	la	r7, r1, PTO;		/* add user context as 3rd arg */
-	brlid	r15, sys_rt_sigsuspend;	/* Do real work.*/
-	nop;
-	lwi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
-	lwi	r4, r1, PTO+PT_R4;
-	bri ret_from_trap /* fall through will not work here due to align */
-	nop;
-
 C_ENTRY(sys_rt_sigreturn_wrapper):
 	swi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
 	swi	r4, r1, PTO+PT_R4;
@@ -711,15 +704,11 @@ C_ENTRY(ret_from_exc):
 	 * (in a possibly modified form) after do_signal returns.
 	 * store return registers separately because this macros is use
 	 * for others exceptions */
-	swi	r3, r1, PTO + PT_R3;
-	swi	r4, r1, PTO + PT_R4;
 	la	r5, r1, PTO;		/* Arg 1: struct pt_regs *regs */
 	add	r6, r0, r0;		/* Arg 2: sigset_t *oldset */
 	addi	r7, r0, 0;		/* Arg 3: int in_syscall */
 	bralid	r15, do_signal;	/* Handle any signals */
 	nop;
-	lwi	r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
-	lwi	r4, r1, PTO+PT_R4;
 
 /* Finally, return to user state.  */
 1:	swi	r0, r0, PER_CPU(KM);	/* Now officially in user state. */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/ftrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,237 @@
+/*
+ * Ftrace support for Microblaze.
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * Based on MIPS and PowerPC ftrace code
+ *
+ * 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 <asm/cacheflush.h>
+#include <linux/ftrace.h>
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+	unsigned long old;
+	int faulted, err;
+	struct ftrace_graph_ent trace;
+	unsigned long return_hooker = (unsigned long)
+				&return_to_handler;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	/*
+	 * Protect against fault, even if it shouldn't
+	 * happen. This tool is too much intrusive to
+	 * ignore such a protection.
+	 */
+	asm volatile("	1:	lwi	%0, %2, 0;		\
+			2:	swi	%3, %2, 0;		\
+				addik	%1, r0, 0;		\
+			3:					\
+				.section .fixup, \"ax\";	\
+			4:	brid	3b;			\
+				addik	%1, r0, 1;		\
+				.previous;			\
+				.section __ex_table,\"a\";	\
+				.word	1b,4b;			\
+				.word	2b,4b;			\
+				.previous;"			\
+			: "=&r" (old), "=r" (faulted)
+			: "r" (parent), "r" (return_hooker)
+	);
+
+	if (unlikely(faulted)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		return;
+	}
+
+	err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
+	if (err == -EBUSY) {
+		*parent = old;
+		return;
+	}
+
+	trace.func = self_addr;
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		*parent = old;
+	}
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+/* save value to addr - it is save to do it in asm */
+static int ftrace_modify_code(unsigned long addr, unsigned int value)
+{
+	int faulted = 0;
+
+	__asm__ __volatile__("	1:	swi	%2, %1, 0;		\
+					addik	%0, r0, 0;		\
+				2:					\
+					.section .fixup, \"ax\";	\
+				3:	brid	2b;			\
+					addik	%0, r0, 1;		\
+					.previous;			\
+					.section __ex_table,\"a\";	\
+					.word	1b,3b;			\
+					.previous;"			\
+				: "=r" (faulted)
+				: "r" (addr), "r" (value)
+	);
+
+	if (unlikely(faulted))
+		return -EFAULT;
+
+	return 0;
+}
+
+#define MICROBLAZE_NOP 0x80000000
+#define MICROBLAZE_BRI 0xb800000C
+
+static unsigned int recorded; /* if save was or not */
+static unsigned int imm; /* saving whole imm instruction */
+
+/* There are two approaches howto solve ftrace_make nop function - look below */
+#undef USE_FTRACE_NOP
+
+#ifdef USE_FTRACE_NOP
+static unsigned int bralid; /* saving whole bralid instruction */
+#endif
+
+int ftrace_make_nop(struct module *mod,
+			struct dyn_ftrace *rec, unsigned long addr)
+{
+	/* we have this part of code which we are working with
+	 * b000c000        imm     -16384
+	 * b9fc8e30        bralid  r15, -29136     // c0008e30 <_mcount>
+	 * 80000000        or      r0, r0, r0
+	 *
+	 * The first solution (!USE_FTRACE_NOP-could be called branch solution)
+	 * b000c000        bri	12 (0xC - jump to any other instruction)
+	 * b9fc8e30        bralid  r15, -29136     // c0008e30 <_mcount>
+	 * 80000000        or      r0, r0, r0
+	 * any other instruction
+	 *
+	 * The second solution (USE_FTRACE_NOP) - no jump just nops
+	 * 80000000        or      r0, r0, r0
+	 * 80000000        or      r0, r0, r0
+	 * 80000000        or      r0, r0, r0
+	 */
+	int ret = 0;
+
+	if (recorded == 0) {
+		recorded = 1;
+		imm = *(unsigned int *)rec->ip;
+		pr_debug("%s: imm:0x%x\n", __func__, imm);
+#ifdef USE_FTRACE_NOP
+		bralid = *(unsigned int *)(rec->ip + 4);
+		pr_debug("%s: bralid 0x%x\n", __func__, bralid);
+#endif /* USE_FTRACE_NOP */
+	}
+
+#ifdef USE_FTRACE_NOP
+	ret = ftrace_modify_code(rec->ip, MICROBLAZE_NOP);
+	ret += ftrace_modify_code(rec->ip + 4, MICROBLAZE_NOP);
+#else /* USE_FTRACE_NOP */
+	ret = ftrace_modify_code(rec->ip, MICROBLAZE_BRI);
+#endif /* USE_FTRACE_NOP */
+	return ret;
+}
+
+static int ret_addr; /* initialized as 0 by default */
+
+/* I believe that first is called ftrace_make_nop before this function */
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	int ret;
+	ret_addr = addr; /* saving where the barrier jump is */
+	pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
+		__func__, (unsigned int)addr, (unsigned int)rec->ip, imm);
+	ret = ftrace_modify_code(rec->ip, imm);
+#ifdef USE_FTRACE_NOP
+	pr_debug("%s: bralid:0x%x\n", __func__, bralid);
+	ret += ftrace_modify_code(rec->ip + 4, bralid);
+#endif /* USE_FTRACE_NOP */
+	return ret;
+}
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+	/* The return code is retured via data */
+	*(unsigned long *)data = 0;
+
+	return 0;
+}
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+	unsigned long ip = (unsigned long)(&ftrace_call);
+	unsigned int upper = (unsigned int)func;
+	unsigned int lower = (unsigned int)func;
+	int ret = 0;
+
+	/* create proper saving to ftrace_call poll */
+	upper = 0xb0000000 + (upper >> 16); /* imm func_upper */
+	lower = 0x32800000 + (lower & 0xFFFF); /* addik r20, r0, func_lower */
+
+	pr_debug("%s: func=0x%x, ip=0x%x, upper=0x%x, lower=0x%x\n",
+		__func__, (unsigned int)func, (unsigned int)ip, upper, lower);
+
+	/* save upper and lower code */
+	ret = ftrace_modify_code(ip, upper);
+	ret += ftrace_modify_code(ip + 4, lower);
+
+	/* We just need to remove the rtsd r15, 8 by NOP */
+	BUG_ON(!ret_addr);
+	if (ret_addr)
+		ret += ftrace_modify_code(ret_addr, MICROBLAZE_NOP);
+	else
+		ret = 1; /* fault */
+
+	/* All changes are done - lets do caches consistent */
+	flush_icache();
+	return ret;
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+unsigned int old_jump; /* saving place for jump instruction */
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	unsigned int ret;
+	unsigned long ip = (unsigned long)(&ftrace_call_graph);
+
+	old_jump = *(unsigned int *)ip; /* save jump over instruction */
+	ret = ftrace_modify_code(ip, MICROBLAZE_NOP);
+	flush_icache();
+
+	pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump);
+	return ret;
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned int ret;
+	unsigned long ip = (unsigned long)(&ftrace_call_graph);
+
+	ret = ftrace_modify_code(ip, old_jump);
+	flush_icache();
+
+	pr_debug("%s\n", __func__);
+	return ret;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_DYNAMIC_FTRACE */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/head.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/head.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
-#include <asm/prom.h>		/* for OF_DT_HEADER */
+#include <linux/of_fdt.h>		/* for OF_DT_HEADER */
 
 #ifdef CONFIG_MMU
 #include <asm/setup.h> /* COMMAND_LINE_SIZE */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/heartbeat.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/heartbeat.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/heartbeat.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/heartbeat.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,6 +45,7 @@ void heartbeat(void)
 void setup_heartbeat(void)
 {
 	struct device_node *gpio = NULL;
+	int *prop;
 	int j;
 	char *gpio_list[] = {
 				"xlnx,xps-gpio-1.00.a",
@@ -58,10 +59,14 @@ void setup_heartbeat(void)
 			break;
 	}
 
-	base_addr = *(int *) of_get_property(gpio, "reg", NULL);
-	base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
-	printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
+	if (gpio) {
+		base_addr = *(int *) of_get_property(gpio, "reg", NULL);
+		base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
+		printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
 
-	if (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL))
-		out_be32(base_addr + 4, 0); /* GPIO is configured as output */
+		/* GPIO is configured as output */
+		prop = (int *) of_get_property(gpio, "xlnx,is-bidir", NULL);
+		if (prop)
+			out_be32(base_addr + 4, 0);
+	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/intc.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/intc.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/intc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/intc.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,8 +42,16 @@ unsigned int nr_irq;
 
 static void intc_enable_or_unmask(unsigned int irq)
 {
+	unsigned long mask = 1 << irq;
 	pr_debug("enable_or_unmask: %d\n", irq);
-	out_be32(INTC_BASE + SIE, 1 << irq);
+	out_be32(INTC_BASE + SIE, mask);
+
+	/* ack level irqs because they can't be acked during
+	 * ack function since the handle_level_irq function
+	 * acks the irq before calling the interrupt handler
+	 */
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		out_be32(INTC_BASE + IAR, mask);
 }
 
 static void intc_disable_or_mask(unsigned int irq)
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/irq.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,7 +68,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < nr_irq) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -89,7 +89,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/Makefile linux-libre-2.6.33-gnu1/arch/microblaze/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,12 +2,22 @@
 # Makefile
 #
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not trace early boot code and low level code
+CFLAGS_REMOVE_timer.o = -pg
+CFLAGS_REMOVE_intc.o = -pg
+CFLAGS_REMOVE_early_printk.o = -pg
+CFLAGS_REMOVE_selfmod.o = -pg
+CFLAGS_REMOVE_heartbeat.o = -pg
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
 extra-y := head.o vmlinux.lds
 
 obj-y += exceptions.o \
 	hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
 	of_platform.o process.o prom.o prom_parse.o ptrace.o \
-	setup.o signal.o sys_microblaze.o timer.o traps.o
+	setup.o signal.o sys_microblaze.o timer.o traps.o reset.o
 
 obj-y += cpu/
 
@@ -16,5 +26,7 @@ obj-$(CONFIG_SELFMOD)		+= selfmod.o
 obj-$(CONFIG_HEART_BEAT)	+= heartbeat.o
 obj-$(CONFIG_MODULES)		+= microblaze_ksyms.o module.o
 obj-$(CONFIG_MMU)		+= misc.o
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o mcount.o
 
 obj-y	+= entry$(MMU).o
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/mcount.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/mcount.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/mcount.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/mcount.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,170 @@
+/*
+ * Low-level ftrace handling
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * 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/linkage.h>
+
+#define NOALIGN_ENTRY(name)	.globl name; name:
+
+/* FIXME MS: I think that I don't need to save all regs */
+#define SAVE_REGS		\
+	addik	r1, r1, -120;	\
+	swi	r2, r1, 4;	\
+	swi	r3, r1, 8;	\
+	swi	r4, r1, 12;	\
+	swi	r5, r1, 116;	\
+	swi	r6, r1, 16;	\
+	swi	r7, r1, 20;	\
+	swi	r8, r1, 24;	\
+	swi	r9, r1, 28;	\
+	swi	r10, r1, 32;	\
+	swi	r11, r1, 36;	\
+	swi	r12, r1, 40;	\
+	swi	r13, r1, 44;	\
+	swi	r14, r1, 48;	\
+	swi	r16, r1, 52;	\
+	swi	r17, r1, 56;	\
+	swi	r18, r1, 60;	\
+	swi	r19, r1, 64;	\
+	swi	r20, r1, 68;	\
+	swi	r21, r1, 72;	\
+	swi	r22, r1, 76;	\
+	swi	r23, r1, 80;	\
+	swi	r24, r1, 84;	\
+	swi	r25, r1, 88;	\
+	swi	r26, r1, 92;	\
+	swi	r27, r1, 96;	\
+	swi	r28, r1, 100;	\
+	swi	r29, r1, 104;	\
+	swi	r30, r1, 108;	\
+	swi	r31, r1, 112;
+
+#define RESTORE_REGS		\
+	lwi	r2, r1, 4;	\
+	lwi	r3, r1, 8;	\
+	lwi	r4, r1, 12;	\
+	lwi	r5, r1, 116;	\
+	lwi	r6, r1, 16;	\
+	lwi	r7, r1, 20;	\
+	lwi	r8, r1, 24;	\
+	lwi	r9, r1, 28;	\
+	lwi	r10, r1, 32;	\
+	lwi	r11, r1, 36;	\
+	lwi	r12, r1, 40;	\
+	lwi	r13, r1, 44;	\
+	lwi	r14, r1, 48;	\
+	lwi	r16, r1, 52;	\
+	lwi	r17, r1, 56;	\
+	lwi	r18, r1, 60;	\
+	lwi	r19, r1, 64;	\
+	lwi	r20, r1, 68;	\
+	lwi	r21, r1, 72;	\
+	lwi	r22, r1, 76;	\
+	lwi	r23, r1, 80;	\
+	lwi	r24, r1, 84;	\
+	lwi	r25, r1, 88;	\
+	lwi	r26, r1, 92;	\
+	lwi	r27, r1, 96;	\
+	lwi	r28, r1, 100;	\
+	lwi	r29, r1, 104;	\
+	lwi	r30, r1, 108;	\
+	lwi	r31, r1, 112;	\
+	addik	r1, r1, 120;
+
+ENTRY(ftrace_stub)
+	rtsd	r15, 8;
+	nop;
+
+ENTRY(_mcount)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ENTRY(ftrace_caller)
+	/* MS: It is just barrier which is removed from C code */
+	rtsd	r15, 8
+	nop
+#endif /* CONFIG_DYNAMIC_FTRACE */
+	SAVE_REGS
+	swi	r15, r1, 0;
+	/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */
+	lwi	r5, r0, function_trace_stop;
+	bneid	r5, end;
+	nop;
+	/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#ifndef CONFIG_DYNAMIC_FTRACE
+	lwi	r5, r0, ftrace_graph_return;
+	addik	r6, r0, ftrace_stub; /* asm implementation */
+	cmpu	r5, r5, r6; /* ftrace_graph_return != ftrace_stub */
+	beqid	r5, end_graph_tracer;
+	nop;
+
+	lwi	r6, r0, ftrace_graph_entry;
+	addik	r5, r0, ftrace_graph_entry_stub; /* implemented in C */
+	cmpu	r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */
+	beqid	r5, end_graph_tracer;
+	nop;
+#else /* CONFIG_DYNAMIC_FTRACE */
+NOALIGN_ENTRY(ftrace_call_graph)
+	/* MS: jump over graph function - replaced from C code */
+	bri	end_graph_tracer
+#endif /* CONFIG_DYNAMIC_FTRACE */
+	addik	r5, r1, 120; /* MS: load parent addr */
+	addik	r6, r15, 0; /* MS: load current function addr */
+	bralid	r15, prepare_ftrace_return;
+	nop;
+	/* MS: graph was taken that's why - can jump over function trace */
+	brid	end;
+	nop;
+end_graph_tracer:
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#ifndef CONFIG_DYNAMIC_FTRACE
+	/* MS: test function trace if is taken or not */
+	lwi	r20, r0, ftrace_trace_function;
+	addik	r6, r0, ftrace_stub;
+	cmpu	r5, r20, r6; /* ftrace_trace_function != ftrace_stub */
+	beqid	r5, end; /* MS: not taken -> jump over */
+	nop;
+#else /* CONFIG_DYNAMIC_FTRACE */
+NOALIGN_ENTRY(ftrace_call)
+/* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */
+	nop
+	nop
+#endif /* CONFIG_DYNAMIC_FTRACE */
+/* static normal trace */
+	lwi	r6, r1, 120; /* MS: load parent addr */
+	addik	r5, r15, 0; /* MS: load current function addr */
+	/* MS: here is dependency on previous code */
+	brald	r15, r20; /* MS: jump to ftrace handler */
+	nop;
+end:
+	lwi	r15, r1, 0;
+	RESTORE_REGS
+
+	rtsd	r15, 8; /* MS: jump back */
+	nop;
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(return_to_handler)
+	nop; /* MS: just barrier for rtsd r15, 8 */
+	nop;
+	SAVE_REGS
+	swi	r15, r1, 0;
+
+	/* MS: find out returning address */
+	bralid	r15, ftrace_return_to_handler;
+	nop;
+
+	/* MS: return value from ftrace_return_to_handler is my returning addr
+	 * must be before restore regs because I have to restore r3 content */
+	addik	r15, r3, 0;
+	RESTORE_REGS
+
+	rtsd	r15, 8; /* MS: jump back */
+	nop;
+#endif	/* CONFIG_FUNCTION_TRACER */
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/microblaze_ksyms.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/microblaze_ksyms.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <asm/page.h>
 #include <asm/system.h>
+#include <linux/ftrace.h>
 #include <linux/uaccess.h>
 
 /*
@@ -47,3 +48,7 @@ extern void __umodsi3(void);
 EXPORT_SYMBOL(__umodsi3);
 extern char *_ebss;
 EXPORT_SYMBOL_GPL(_ebss);
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/process.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/bitops.h>
 #include <asm/system.h>
 #include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
 
 void show_regs(struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/prom.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -860,29 +860,6 @@ struct device_node *of_find_node_by_phan
 EXPORT_SYMBOL(of_find_node_by_phandle);
 
 /**
- *	of_find_all_nodes - Get next node in global list
- *	@prev:	Previous node or NULL to start iteration
- *		of_node_put() will be called on it
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_all_nodes(struct device_node *prev)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = prev ? prev->allnext : allnodes;
-	for (; np != NULL; np = np->allnext)
-		if (of_node_get(np))
-			break;
-	of_node_put(prev);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_all_nodes);
-
-/**
  *	of_node_get - Increment refcount of a node
  *	@node:	Node to inc refcount, NULL is supported to
  *		simplify writing of callers
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/prom_parse.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom_parse.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/prom_parse.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/prom_parse.c	2010-02-24 13:52:17.000000000 -0500
@@ -256,7 +256,7 @@ int of_irq_map_pci(struct pci_dev *pdev,
 		if (ppdev == NULL) {
 			struct pci_controller *host;
 			host = pci_bus_to_host(pdev->bus);
-			ppnode = host ? host->arch_data : NULL;
+			ppnode = host ? host->dn : NULL;
 			/* No node for host bridge ? give up */
 			if (ppnode == NULL)
 				return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/reset.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/reset.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * 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/of_platform.h>
+#include <asm/prom.h>
+
+/* Trigger specific functions */
+#ifdef CONFIG_GPIOLIB
+
+#include <linux/of_gpio.h>
+
+static int handle; /* reset pin handle */
+static unsigned int reset_val;
+
+static int of_reset_gpio_handle(void)
+{
+	int ret; /* variable which stored handle reset gpio pin */
+	struct device_node *root; /* root node */
+	struct device_node *gpio; /* gpio node */
+	struct of_gpio_chip *of_gc = NULL;
+	enum of_gpio_flags flags ;
+	const void *gpio_spec;
+
+	/* find out root node */
+	root = of_find_node_by_path("/");
+
+	/* give me handle for gpio node to be possible allocate pin */
+	ret = of_parse_phandles_with_args(root, "hard-reset-gpios",
+				"#gpio-cells", 0, &gpio, &gpio_spec);
+	if (ret) {
+		pr_debug("%s: can't parse gpios property\n", __func__);
+		goto err0;
+	}
+
+	of_gc = gpio->data;
+	if (!of_gc) {
+		pr_debug("%s: gpio controller %s isn't registered\n",
+			 root->full_name, gpio->full_name);
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	ret = of_gc->xlate(of_gc, root, gpio_spec, &flags);
+	if (ret < 0)
+		goto err1;
+
+	ret += of_gc->gc.base;
+err1:
+	of_node_put(gpio);
+err0:
+	pr_debug("%s exited with status %d\n", __func__, ret);
+	return ret;
+}
+
+void of_platform_reset_gpio_probe(void)
+{
+	int ret;
+	handle = of_reset_gpio_handle();
+
+	if (!gpio_is_valid(handle)) {
+		printk(KERN_INFO "Skipping unavailable RESET gpio %d (%s)\n",
+				handle, "reset");
+	}
+
+	ret = gpio_request(handle, "reset");
+	if (ret < 0) {
+		printk(KERN_INFO "GPIO pin is already allocated\n");
+		return;
+	}
+
+	/* get current setup value */
+	reset_val = gpio_get_value(handle);
+	/* FIXME maybe worth to perform any action */
+	pr_debug("Reset: Gpio output state: 0x%x\n", reset_val);
+
+	/* Setup GPIO as output */
+	ret = gpio_direction_output(handle, 0);
+	if (ret < 0)
+		goto err;
+
+	/* Setup output direction */
+	gpio_set_value(handle, 0);
+
+	printk(KERN_INFO "RESET: Registered gpio device: %d, current val: %d\n",
+							handle, reset_val);
+	return;
+err:
+	gpio_free(handle);
+	return;
+}
+
+
+static void gpio_system_reset(void)
+{
+	gpio_set_value(handle, 1 - reset_val);
+}
+#else
+#define gpio_system_reset() do {} while (0)
+void of_platform_reset_gpio_probe(void)
+{
+	return;
+}
+#endif
+
+void machine_restart(char *cmd)
+{
+	printk(KERN_NOTICE "Machine restart...\n");
+	gpio_system_reset();
+	dump_stack();
+	while (1)
+		;
+}
+
+void machine_shutdown(void)
+{
+	printk(KERN_NOTICE "Machine shutdown...\n");
+	while (1)
+		;
+}
+
+void machine_halt(void)
+{
+	printk(KERN_NOTICE "Machine halt...\n");
+	while (1)
+		;
+}
+
+void machine_power_off(void)
+{
+	printk(KERN_NOTICE "Machine power off...\n");
+	while (1)
+		;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/setup.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,13 +52,13 @@ void __init setup_arch(char **cmdline_p)
 	/* irq_early_init(); */
 	setup_cpuinfo();
 
-	__invalidate_icache_all();
-	__enable_icache();
+	microblaze_cache_init();
 
-	__invalidate_dcache_all();
-	__enable_dcache();
+	invalidate_dcache();
+	enable_dcache();
 
-	panic_timeout = 120;
+	invalidate_icache();
+	enable_icache();
 
 	setup_memory();
 
@@ -131,6 +131,8 @@ void __init machine_early_init(const cha
 		strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
 #endif
 
+	lockdep_init();
+
 /* initialize device tree for usage in early_printk */
 	early_init_devtree((void *)_fdt_start);
 
@@ -186,32 +188,3 @@ static int microblaze_debugfs_init(void)
 }
 arch_initcall(microblaze_debugfs_init);
 #endif
-
-void machine_restart(char *cmd)
-{
-	printk(KERN_NOTICE "Machine restart...\n");
-	dump_stack();
-	while (1)
-		;
-}
-
-void machine_shutdown(void)
-{
-	printk(KERN_NOTICE "Machine shutdown...\n");
-	while (1)
-		;
-}
-
-void machine_halt(void)
-{
-	printk(KERN_NOTICE "Machine halt...\n");
-	while (1)
-		;
-}
-
-void machine_power_off(void)
-{
-	printk(KERN_NOTICE "Machine power off...\n");
-	while (1)
-		;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/signal.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,6 @@
 
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
 
-
 asmlinkage long
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 		struct pt_regs *regs)
@@ -176,6 +175,11 @@ static void setup_rt_frame(int sig, stru
 	struct rt_sigframe __user *frame;
 	int err = 0;
 	int signal;
+	unsigned long address = 0;
+#ifdef CONFIG_MMU
+	pmd_t *pmdp;
+	pte_t *ptep;
+#endif
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
 
@@ -216,8 +220,29 @@ static void setup_rt_frame(int sig, stru
 	 Negative 8 offset because return is rtsd r15, 8 */
 	regs->r15 = ((unsigned long)frame->tramp)-8;
 
-	__invalidate_cache_sigtramp((unsigned long)frame->tramp);
+	address = ((unsigned long)frame->tramp);
+#ifdef CONFIG_MMU
+	pmdp = pmd_offset(pud_offset(
+			pgd_offset(current->mm, address),
+					address), address);
 
+	preempt_disable();
+	ptep = pte_offset_map(pmdp, address);
+	if (pte_present(*ptep)) {
+		address = (unsigned long) page_address(pte_page(*ptep));
+		/* MS: I need add offset in page */
+		address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
+		/* MS address is virtual */
+		address = virt_to_phys(address);
+		invalidate_icache_range(address, address + 8);
+		flush_dcache_range(address, address + 8);
+	}
+	pte_unmap(ptep);
+	preempt_enable();
+#else
+	flush_icache_range(address, address + 8);
+	flush_dcache_range(address, address + 8);
+#endif
 	if (err)
 		goto give_sigsegv;
 
@@ -233,6 +258,10 @@ static void setup_rt_frame(int sig, stru
 
 	set_fs(USER_DS);
 
+	/* the tracer may want to single-step inside the handler */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
+
 #ifdef DEBUG_SIG
 	printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
 		current->comm, current->pid, frame, regs->pc);
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/stacktrace.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/stacktrace.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/stacktrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/stacktrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,65 @@
+/*
+ * Stack trace support for Microblaze.
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * 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/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/thread_info.h>
+#include <linux/ptrace.h>
+#include <linux/module.h>
+
+/* FIXME initial support */
+void save_stack_trace(struct stack_trace *trace)
+{
+	unsigned long *sp;
+	unsigned long addr;
+	asm("addik %0, r1, 0" : "=r" (sp));
+
+	while (!kstack_end(sp)) {
+		addr = *sp++;
+		if (__kernel_text_address(addr)) {
+			if (trace->skip > 0)
+				trace->skip--;
+			else
+				trace->entries[trace->nr_entries++] = addr;
+
+			if (trace->nr_entries >= trace->max_entries)
+				break;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+	unsigned int *sp;
+	unsigned long addr;
+
+	struct thread_info *ti = task_thread_info(tsk);
+
+	if (tsk == current)
+		asm("addik %0, r1, 0" : "=r" (sp));
+	else
+		sp = (unsigned int *)ti->cpu_context.r1;
+
+	while (!kstack_end(sp)) {
+		addr = *sp++;
+		if (__kernel_text_address(addr)) {
+			if (trace->skip > 0)
+				trace->skip--;
+			else
+				trace->entries[trace->nr_entries++] = addr;
+
+			if (trace->nr_entries >= trace->max_entries)
+				break;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/syscall_table.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/syscall_table.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/syscall_table.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/syscall_table.S	2010-02-24 13:52:17.000000000 -0500
@@ -183,7 +183,7 @@ ENTRY(sys_call_table)
 	.long sys_rt_sigpending
 	.long sys_rt_sigtimedwait
 	.long sys_rt_sigqueueinfo
-	.long sys_rt_sigsuspend_wrapper
+	.long sys_rt_sigsuspend
 	.long sys_pread64		/* 180 */
 	.long sys_pwrite64
 	.long sys_chown
@@ -196,7 +196,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall		/* reserved for streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2			/* mmap2 */
+	.long sys_mmap_pgoff		/* mmap2 */
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64		/* 195 */
@@ -303,7 +303,7 @@ ENTRY(sys_call_table)
 	.long sys_mkdirat
 	.long sys_mknodat
 	.long sys_fchownat
-	.long sys_ni_syscall
+	.long sys_futimesat
 	.long sys_fstatat64		/* 300 */
 	.long sys_unlinkat
 	.long sys_renameat
@@ -366,8 +366,9 @@ ENTRY(sys_call_table)
 	.long sys_shutdown
 	.long sys_sendmsg		/* 360 */
 	.long sys_recvmsg
-	.long sys_ni_syscall
+	.long sys_accept4
 	.long sys_ni_syscall
 	.long sys_ni_syscall
 	.long sys_rt_tgsigqueueinfo	/* 365 */
 	.long sys_perf_event_open
+	.long sys_recvmmsg
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/sys_microblaze.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/sys_microblaze.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/sys_microblaze.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/sys_microblaze.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,46 +62,14 @@ out:
 	return error;
 }
 
-asmlinkage long
-sys_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-	int ret = -EBADF;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file) {
-			printk(KERN_INFO "no fd in mmap\r\n");
-			goto out;
-		}
-	}
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-out:
-	return ret;
-}
-
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, off_t pgoff)
 {
-	int err = -EINVAL;
-
-	if (pgoff & ~PAGE_MASK) {
-		printk(KERN_INFO "no pagemask in mmap\r\n");
-		goto out;
-	}
+	if (pgoff & ~PAGE_MASK)
+		return -EINVAL;
 
-	err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
-out:
-	return err;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/timer.c linux-libre-2.6.33-gnu1/arch/microblaze/kernel/timer.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/timer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -183,6 +183,31 @@ static cycle_t microblaze_read(struct cl
 	return (cycle_t) (in_be32(TIMER_BASE + TCR1));
 }
 
+static struct timecounter microblaze_tc = {
+	.cc = NULL,
+};
+
+static cycle_t microblaze_cc_read(const struct cyclecounter *cc)
+{
+	return microblaze_read(NULL);
+}
+
+static struct cyclecounter microblaze_cc = {
+	.read = microblaze_cc_read,
+	.mask = CLOCKSOURCE_MASK(32),
+	.shift = 24,
+};
+
+int __init init_microblaze_timecounter(void)
+{
+	microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+				microblaze_cc.shift);
+
+	timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
+
+	return 0;
+}
+
 static struct clocksource clocksource_microblaze = {
 	.name		= "microblaze_clocksource",
 	.rating		= 300,
@@ -204,6 +229,9 @@ static int __init microblaze_clocksource
 	out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT);
 	/* start timer1 - up counting without interrupt */
 	out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
+
+	/* register timecounter - for ftrace support */
+	init_microblaze_timecounter();
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/microblaze/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/microblaze/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -26,11 +26,12 @@ SECTIONS {
 		_stext = . ;
 		*(.text .text.*)
 		*(.fixup)
-               EXIT_TEXT
-               EXIT_CALL
+		EXIT_TEXT
+		EXIT_CALL
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
+		IRQENTRY_TEXT
 		. = ALIGN (4) ;
 		_etext = . ;
 	}
@@ -86,6 +87,7 @@ SECTIONS {
 		_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
 	}
 
+	. = ALIGN(PAGE_SIZE);
 	__init_begin = .;
 
 	INIT_TEXT_SECTION(PAGE_SIZE)
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/lib/memcpy.c linux-libre-2.6.33-gnu1/arch/microblaze/lib/memcpy.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/lib/memcpy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/lib/memcpy.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/lib/memmove.c linux-libre-2.6.33-gnu1/arch/microblaze/lib/memmove.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/lib/memmove.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/lib/memmove.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/lib/memset.c linux-libre-2.6.33-gnu1/arch/microblaze/lib/memset.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/lib/memset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/lib/memset.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
  * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
  * http://www.embedded.com/showArticle.jhtml?articleID=19205567
  *
- * Attempts were made, unsuccesfully, to contact the original
+ * Attempts were made, unsuccessfully, to contact the original
  * author of this code (Michael Morrow, Intel).  Below is the original
  * copyright notice.
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/lib/uaccess.c linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/lib/uaccess.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/lib/uaccess.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,3 +39,10 @@ long strncpy_from_user(char *dst, const
 		__do_strncpy_from_user(dst, src, count, res);
 	return res;
 }
+
+unsigned long __copy_tofrom_user(void __user *to,
+		const void __user *from, unsigned long size)
+{
+	memcpy(to, from, size);
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/Makefile linux-libre-2.6.33-gnu1/arch/microblaze/Makefile
--- linux-libre-2.6.32-gnu1/arch/microblaze/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,8 @@ core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/platform/
 
+drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/
+
 boot := arch/microblaze/boot
 
 # Are we making a simpleImage.<boardname> target? If so, crack out the boardname
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/mm/init.c linux-libre-2.6.33-gnu1/arch/microblaze/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,7 @@ char *klimit = _end;
  * have available.
  */
 unsigned long memory_start;
+EXPORT_SYMBOL(memory_start);
 unsigned long memory_end; /* due to mm/nommu.c */
 unsigned long memory_size;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/mm/pgtable.c linux-libre-2.6.33-gnu1/arch/microblaze/mm/pgtable.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/mm/pgtable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
@@ -144,7 +144,6 @@ int map_page(unsigned long va, phys_addr
 	pmd_t *pd;
 	pte_t *pg;
 	int err = -ENOMEM;
-	/* spin_lock(&init_mm.page_table_lock); */
 	/* Use upper 10 bits of VA to index the first level map */
 	pd = pmd_offset(pgd_offset_k(va), va);
 	/* Use middle 10 bits of VA to index the second-level map */
@@ -158,9 +157,7 @@ int map_page(unsigned long va, phys_addr
 		if (mem_init_done)
 			flush_HPTE(0, va, pmd_val(*pd));
 			/* flush_HPTE(0, va, pg); */
-
 	}
-	/* spin_unlock(&init_mm.page_table_lock); */
 	return err;
 }
 
@@ -182,12 +179,6 @@ void __init adjust_total_lowmem(void)
 #endif
 }
 
-static void show_tmem(unsigned long tmem)
-{
-	volatile unsigned long a;
-	a = a + tmem;
-}
-
 /*
  * Map in all of physical memory starting at CONFIG_KERNEL_START.
  */
@@ -197,7 +188,6 @@ void __init mapin_ram(void)
 
 	v = CONFIG_KERNEL_START;
 	p = memory_start;
-	show_tmem(memory_size);
 	for (s = 0; s < memory_size; s += PAGE_SIZE) {
 		f = _PAGE_PRESENT | _PAGE_ACCESSED |
 				_PAGE_SHARED | _PAGE_HWEXEC;
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/oprofile/Makefile linux-libre-2.6.33-gnu1/arch/microblaze/oprofile/Makefile
--- linux-libre-2.6.32-gnu1/arch/microblaze/oprofile/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/oprofile/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,13 @@
+#
+# arch/microblaze/oprofile/Makefile
+#
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) microblaze_oprofile.o
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/oprofile/microblaze_oprofile.c linux-libre-2.6.33-gnu1/arch/microblaze/oprofile/microblaze_oprofile.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/oprofile/microblaze_oprofile.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/oprofile/microblaze_oprofile.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,22 @@
+/*
+ * Microblaze oprofile code
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * 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/oprofile.h>
+#include <linux/init.h>
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	return -1;
+}
+
+void oprofile_arch_exit(void)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/platform/generic/Kconfig.auto linux-libre-2.6.33-gnu1/arch/microblaze/platform/generic/Kconfig.auto
--- linux-libre-2.6.32-gnu1/arch/microblaze/platform/generic/Kconfig.auto	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/platform/generic/Kconfig.auto	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@
 
 # Definitions for MICROBLAZE0
 comment "Definitions for MICROBLAZE0"
-	depends on ALLOW_EDIT_AUTO
 
 config KERNEL_BASE_ADDR
 	hex "Physical address where Linux Kernel is"
@@ -30,33 +29,33 @@ config KERNEL_BASE_ADDR
 	  BASE Address for kernel
 
 config XILINX_MICROBLAZE0_FAMILY
-	string "Targetted FPGA family" if ALLOW_EDIT_AUTO
+	string "Targetted FPGA family"
 	default "virtex5"
 
 config XILINX_MICROBLAZE0_USE_MSR_INSTR
-	int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO
-	default 1
+	int "USE_MSR_INSTR range (0:1)"
+	default 0
 
 config XILINX_MICROBLAZE0_USE_PCMP_INSTR
-	int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO
-	default 1
+	int "USE_PCMP_INSTR range (0:1)"
+	default 0
 
 config XILINX_MICROBLAZE0_USE_BARREL
-	int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
-	default 1
+	int "USE_BARREL range (0:1)"
+	default 0
 
 config XILINX_MICROBLAZE0_USE_DIV
-	int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
-	default 1
+	int "USE_DIV range (0:1)"
+	default 0
 
 config XILINX_MICROBLAZE0_USE_HW_MUL
-	int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO
-	default 2
+	int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)"
+	default 0
 
 config XILINX_MICROBLAZE0_USE_FPU
-	int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO
-	default 2
+	int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)"
+	default 0
 
 config XILINX_MICROBLAZE0_HW_VER
-	string "Core version number" if ALLOW_EDIT_AUTO
+	string "Core version number"
 	default 7.10.d
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/platform/generic/system.dts linux-libre-2.6.33-gnu1/arch/microblaze/platform/generic/system.dts
--- linux-libre-2.6.32-gnu1/arch/microblaze/platform/generic/system.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/platform/generic/system.dts	2010-02-24 13:52:17.000000000 -0500
@@ -32,11 +32,16 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 	compatible = "xlnx,microblaze";
+	hard-reset-gpios = <&LEDs_8Bit 2 1>;
 	model = "testing";
 	DDR2_SDRAM: memory@90000000 {
 		device_type = "memory";
 		reg = < 0x90000000 0x10000000 >;
 	} ;
+	aliases {
+		ethernet0 = &Hard_Ethernet_MAC;
+		serial0 = &RS232_Uart_1;
+	} ;
 	chosen {
 		bootargs = "console=ttyUL0,115200 highres=on";
 		linux,stdout-path = "/plb@0/serial@84000000";
@@ -127,7 +132,7 @@
 	mb_plb: plb@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+		compatible = "xlnx,plb-v46-1.03.a", "xlnx,plb-v46-1.00.a", "simple-bus";
 		ranges ;
 		FLASH: flash@a0000000 {
 			bank-width = <2>;
@@ -214,12 +219,12 @@
 			#size-cells = <1>;
 			compatible = "xlnx,compound";
 			ethernet@81c00000 {
-				compatible = "xlnx,xps-ll-temac-1.01.b";
+				compatible = "xlnx,xps-ll-temac-1.01.b", "xlnx,xps-ll-temac-1.00.a";
 				device_type = "network";
 				interrupt-parent = <&xps_intc_0>;
 				interrupts = < 5 2 >;
 				llink-connected = <&PIM3>;
-				local-mac-address = [ 02 00 00 00 00 00 ];
+				local-mac-address = [ 00 0a 35 00 00 00 ];
 				reg = < 0x81c00000 0x40 >;
 				xlnx,bus2core-clk-ratio = <0x1>;
 				xlnx,phy-type = <0x1>;
@@ -261,6 +266,33 @@
 			xlnx,is-dual = <0x0>;
 			xlnx,tri-default = <0xffffffff>;
 			xlnx,tri-default-2 = <0xffffffff>;
+			#gpio-cells = <2>;
+			gpio-controller;
+		} ;
+
+		gpio-leds {
+			compatible = "gpio-leds";
+
+			heartbeat {
+				label = "Heartbeat";
+				gpios = <&LEDs_8Bit 4 1>;
+				linux,default-trigger = "heartbeat";
+			};
+
+			yellow {
+				label = "Yellow";
+				gpios = <&LEDs_8Bit 5 1>;
+			};
+
+			red {
+				label = "Red";
+				gpios = <&LEDs_8Bit 6 1>;
+			};
+
+			green {
+				label = "Green";
+				gpios = <&LEDs_8Bit 7 1>;
+			};
 		} ;
 		RS232_Uart_1: serial@84000000 {
 			clock-frequency = <125000000>;
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/platform/Kconfig.platform linux-libre-2.6.33-gnu1/arch/microblaze/platform/Kconfig.platform
--- linux-libre-2.6.32-gnu1/arch/microblaze/platform/Kconfig.platform	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/platform/Kconfig.platform	2010-02-24 13:52:17.000000000 -0500
@@ -53,31 +53,12 @@ config OPT_LIB_FUNCTION
 
 config OPT_LIB_ASM
 	bool "Optimalized lib function ASM"
-	depends on OPT_LIB_FUNCTION
+	depends on OPT_LIB_FUNCTION && (XILINX_MICROBLAZE0_USE_BARREL = 1)
 	default n
 	help
 	  Allows turn on optimalized library function (memcpy and memmove).
 	  Function are written in asm code.
 
-# This is still a bit broken - disabling for now JW 20070504
-config ALLOW_EDIT_AUTO
-	bool "Permit Display/edit of Kconfig.auto platform settings"
-	default n
-	help
-	  Allows the editing of auto-generated platform settings from
-	  the Kconfig.auto file. Obviously this does not change the
-	  underlying hardware, so be very careful if you go editing
-	  these settings.
-
-	  Also, if you enable this, and edit various Kconfig.auto
-	  settings, YOUR CHANGES WILL BE LOST if you then disable it
-	  again. You have been warned!
-
-	  If unsure, say no.
-
-comment "Automatic platform settings from Kconfig.auto"
-	depends on ALLOW_EDIT_AUTO
-
 if PLATFORM_GENERIC=y
 	source "arch/microblaze/platform/generic/Kconfig.auto"
 endif
diff -druNp linux-libre-2.6.32-gnu1/arch/microblaze/platform/platform.c linux-libre-2.6.33-gnu1/arch/microblaze/platform/platform.c
--- linux-libre-2.6.32-gnu1/arch/microblaze/platform/platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/microblaze/platform/platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/of_platform.h>
 #include <asm/prom.h>
+#include <asm/setup.h>
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
 	{ .compatible = "simple-bus", },
@@ -26,6 +27,7 @@ static struct of_device_id xilinx_of_bus
 static int __init microblaze_device_probe(void)
 {
 	of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+	of_platform_reset_gpio_probe();
 	return 0;
 }
 device_initcall(microblaze_device_probe);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/alchemy/common/dbdma.c linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dbdma.c
--- linux-libre-2.6.32-gnu1/arch/mips/alchemy/common/dbdma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/alchemy/common/dbdma.c	2010-02-24 13:52:17.000000000 -0500
@@ -412,8 +412,11 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid,
 		if (desc_base == 0)
 			return 0;
 
+		ctp->cdb_membase = desc_base;
 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
-	}
+	} else
+		ctp->cdb_membase = desc_base;
+
 	dp = (au1x_ddma_desc_t *)desc_base;
 
 	/* Keep track of the base descriptor. */
@@ -613,7 +616,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid,
 	dma_cache_wback_inv((unsigned long)buf, nbytes);
 	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
 	au_sync();
-	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+	dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
 	ctp->chan_ptr->ddma_dbell = 0;
 
 	/* Get next descriptor pointer.	*/
@@ -676,7 +679,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void
 	dma_cache_inv((unsigned long)buf, nbytes);
 	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
 	au_sync();
-	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+	dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
 	ctp->chan_ptr->ddma_dbell = 0;
 
 	/* Get next descriptor pointer.	*/
@@ -831,7 +834,7 @@ void au1xxx_dbdma_chan_free(u32 chanid)
 
 	au1xxx_dbdma_stop(chanid);
 
-	kfree((void *)ctp->chan_desc_base);
+	kfree((void *)ctp->cdb_membase);
 
 	stp->dev_flags &= ~DEV_FLAGS_INUSE;
 	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/ar7/platform.c linux-libre-2.6.33-gnu1/arch/mips/ar7/platform.c
--- linux-libre-2.6.32-gnu1/arch/mips/ar7/platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/ar7/platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -202,7 +202,7 @@ static struct resource usb_res[] = {
 		.name = "mem",
 		.flags = IORESOURCE_MEM,
 		.start = 0x03400000,
-		.end = 0x034001fff,
+		.end = 0x03401fff,
 	},
 };
 
@@ -505,7 +505,7 @@ static int __init ar7_register_devices(v
 	int res;
 	u32 *bootcr, val;
 #ifdef CONFIG_SERIAL_8250
-	static struct uart_port uart_port[2];
+	static struct uart_port uart_port[2] __initdata;
 
 	memset(uart_port, 0, sizeof(struct uart_port) * 2);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/ar7/prom.c linux-libre-2.6.33-gnu1/arch/mips/ar7/prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/ar7/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/ar7/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -219,14 +219,6 @@ static void __init console_config(void)
 	if (strstr(prom_getcmdline(), "console="))
 		return;
 
-#ifdef CONFIG_KGDB
-	if (!strstr(prom_getcmdline(), "nokgdb")) {
-		strcat(prom_getcmdline(), " console=kgdb");
-		kgdb_enabled = 1;
-		return;
-	}
-#endif
-
 	s = prom_getenv("modetty0");
 	if (s) {
 		baud = simple_strtoul(s, &p, 10);
@@ -280,13 +272,6 @@ static inline void serial_out(int offset
 	writel(value, (void *)PORT(offset));
 }
 
-char prom_getchar(void)
-{
-	while (!(serial_in(UART_LSR) & UART_LSR_DR))
-		;
-	return serial_in(UART_RX);
-}
-
 int prom_putchar(char c)
 {
 	while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_device.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_device.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_device.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_device.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,403 +0,0 @@
-/*
- *  Copyright (C) 2004 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.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/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/err.h>
-#include <linux/jiffies.h>
-#include <linux/sched.h>
-#include <asm/types.h>
-#include <asm/rm9k-ocd.h>
-
-#include <excite.h>
-#include <rm9k_eth.h>
-#include <rm9k_wdt.h>
-#include <rm9k_xicap.h>
-#include <excite_nandflash.h>
-
-#include "excite_iodev.h"
-
-#define RM9K_GE_UNIT	0
-#define XICAP_UNIT	0
-#define NAND_UNIT	0
-
-#define DLL_TIMEOUT	3		/* seconds */
-
-
-#define RINIT(__start__, __end__, __name__, __parent__) {	\
-	.name	= __name__ "_0",				\
-	.start	= (__start__),					\
-	.end	= (__end__),					\
-	.flags	= 0,						\
-	.parent	= (__parent__)					\
-}
-
-#define RINIT_IRQ(__irq__, __name__) {	\
-	.name	= __name__ "_0",	\
-	.start	= (__irq__),		\
-	.end	= (__irq__),		\
-	.flags	= IORESOURCE_IRQ,	\
-	.parent	= NULL			\
-}
-
-
-
-enum {
-	slice_xicap,
-	slice_eth
-};
-
-
-
-static struct resource
-	excite_ctr_resource __maybe_unused = {
-		.name		= "GPI counters",
-		.start		= 0,
-		.end		= 5,
-		.flags		= 0,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_gpislice_resource __maybe_unused = {
-		.name		= "GPI slices",
-		.start		= 0,
-		.end		= 1,
-		.flags		= 0,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_mdio_channel_resource __maybe_unused = {
-		.name		= "MDIO channels",
-		.start		= 0,
-		.end		= 1,
-		.flags		= 0,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_fifomem_resource __maybe_unused = {
-		.name		= "FIFO memory",
-		.start		= 0,
-		.end		= 767,
-		.flags		= 0,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_scram_resource __maybe_unused = {
-		.name		= "Scratch RAM",
-		.start		= EXCITE_PHYS_SCRAM,
-		.end		= EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
-		.flags		= IORESOURCE_MEM,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_fpga_resource __maybe_unused = {
-		.name		= "System FPGA",
-		.start		= EXCITE_PHYS_FPGA,
-		.end		= EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
-		.flags		= IORESOURCE_MEM,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_nand_resource __maybe_unused = {
-		.name		= "NAND flash control",
-		.start		= EXCITE_PHYS_NAND,
-		.end		= EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
-		.flags		= IORESOURCE_MEM,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	},
-	excite_titan_resource __maybe_unused = {
-		.name		= "TITAN registers",
-		.start		= EXCITE_PHYS_TITAN,
-		.end		= EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
-		.flags		= IORESOURCE_MEM,
-		.parent		= NULL,
-		.sibling	= NULL,
-		.child		= NULL
-	};
-
-
-
-static void adjust_resources(struct resource *res, unsigned int n)
-{
-	struct resource *p;
-	const unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM
-				   | IORESOURCE_IRQ | IORESOURCE_DMA;
-
-	for (p = res; p < res + n; p++) {
-		const struct resource * const parent = p->parent;
-		if (parent) {
-			p->start += parent->start;
-			p->end   += parent->start;
-			p->flags =  parent->flags & mask;
-		}
-	}
-}
-
-
-
-#if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE)
-static struct resource xicap_rsrc[] = {
-	RINIT(0x4840, 0x486f, XICAP_RESOURCE_FIFO_RX, &excite_titan_resource),
-	RINIT(0x4940, 0x494b, XICAP_RESOURCE_FIFO_TX, &excite_titan_resource),
-	RINIT(0x5040, 0x5127, XICAP_RESOURCE_XDMA, &excite_titan_resource),
-	RINIT(0x1000, 0x112f, XICAP_RESOURCE_PKTPROC, &excite_titan_resource),
-	RINIT(0x1100, 0x110f, XICAP_RESOURCE_PKT_STREAM, &excite_fpga_resource),
-	RINIT(0x0800, 0x0bff, XICAP_RESOURCE_DMADESC, &excite_scram_resource),
-	RINIT(slice_xicap, slice_xicap, XICAP_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
-	RINIT(0x0100, 0x02ff, XICAP_RESOURCE_FIFO_BLK, &excite_fifomem_resource),
-	RINIT_IRQ(TITAN_IRQ,  XICAP_RESOURCE_IRQ)
-};
-
-static struct platform_device xicap_pdev = {
-	.name		= XICAP_NAME,
-	.id		= XICAP_UNIT,
-	.num_resources	= ARRAY_SIZE(xicap_rsrc),
-	.resource	= xicap_rsrc
-};
-
-/*
- * Create a platform device for the GPI port that receives the
- * image data from the embedded camera.
- */
-static int __init xicap_devinit(void)
-{
-	unsigned long tend;
-	u32 reg;
-	int retval;
-
-	adjust_resources(xicap_rsrc, ARRAY_SIZE(xicap_rsrc));
-
-	/* Power up the slice and configure it. */
-	reg = titan_readl(CPTC1R);
-	reg &= ~(0x11100 << slice_xicap);
-	titan_writel(reg, CPTC1R);
-
-	/* Enable slice & DLL. */
-	reg= titan_readl(CPRR);
-	reg &= ~(0x00030003 << (slice_xicap * 2));
-	titan_writel(reg, CPRR);
-
-	/* Wait for DLLs to lock */
-	tend = jiffies + DLL_TIMEOUT * HZ;
-	while (time_before(jiffies, tend)) {
-		if (!(~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))))
-			break;
-		yield();
-	}
-
-	if (~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))) {
-		printk(KERN_ERR "%s: DLL not locked after %u seconds\n",
-		       xicap_pdev.name, DLL_TIMEOUT);
-		retval = -ETIME;
-	} else {
-		/* Register platform device */
-		retval = platform_device_register(&xicap_pdev);
-	}
-
-	return retval;
-}
-
-device_initcall(xicap_devinit);
-#endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */
-
-
-
-#if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE)
-static struct resource wdt_rsrc[] = {
-	RINIT(0, 0, WDT_RESOURCE_COUNTER, &excite_ctr_resource),
-	RINIT(0x0084, 0x008f, WDT_RESOURCE_REGS, &excite_titan_resource),
-	RINIT_IRQ(TITAN_IRQ,  WDT_RESOURCE_IRQ)
-};
-
-static struct platform_device wdt_pdev = {
-	.name		= WDT_NAME,
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(wdt_rsrc),
-	.resource	= wdt_rsrc
-};
-
-/*
- * Create a platform device for the GPI port that receives the
- * image data from the embedded camera.
- */
-static int __init wdt_devinit(void)
-{
-	adjust_resources(wdt_rsrc, ARRAY_SIZE(wdt_rsrc));
-	return platform_device_register(&wdt_pdev);
-}
-
-device_initcall(wdt_devinit);
-#endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */
-
-
-
-static struct resource excite_nandflash_rsrc[] = {
- 	RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS,  &excite_nand_resource)
-};
-
-static struct platform_device excite_nandflash_pdev = {
-	.name		= "excite_nand",
-	.id		= NAND_UNIT,
-	.num_resources	= ARRAY_SIZE(excite_nandflash_rsrc),
-	.resource	= excite_nandflash_rsrc
-};
-
-/*
- * Create a platform device for the access to the nand-flash
- * port
- */
-static int __init excite_nandflash_devinit(void)
-{
-	adjust_resources(excite_nandflash_rsrc, ARRAY_SIZE(excite_nandflash_rsrc));
-
-        /* nothing to be done here */
-
-        /* Register platform device */
-	return platform_device_register(&excite_nandflash_pdev);
-}
-
-device_initcall(excite_nandflash_devinit);
-
-
-
-static struct resource iodev_rsrc[] = {
-	RINIT_IRQ(FPGA1_IRQ,  IODEV_RESOURCE_IRQ)
-};
-
-static struct platform_device io_pdev = {
-	.name		= IODEV_NAME,
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(iodev_rsrc),
-	.resource	= iodev_rsrc
-};
-
-/*
- * Create a platform device for the external I/O ports.
- */
-static int __init io_devinit(void)
-{
-	adjust_resources(iodev_rsrc, ARRAY_SIZE(iodev_rsrc));
-	return platform_device_register(&io_pdev);
-}
-
-device_initcall(io_devinit);
-
-
-
-
-#if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE)
-static struct resource rm9k_ge_rsrc[] = {
-	RINIT(0x2200, 0x27ff, RM9K_GE_RESOURCE_MAC, &excite_titan_resource),
-	RINIT(0x1800, 0x1fff, RM9K_GE_RESOURCE_MSTAT, &excite_titan_resource),
-	RINIT(0x2000, 0x212f, RM9K_GE_RESOURCE_PKTPROC, &excite_titan_resource),
-	RINIT(0x5140, 0x5227, RM9K_GE_RESOURCE_XDMA, &excite_titan_resource),
-	RINIT(0x4870, 0x489f, RM9K_GE_RESOURCE_FIFO_RX, &excite_titan_resource),
-	RINIT(0x494c, 0x4957, RM9K_GE_RESOURCE_FIFO_TX, &excite_titan_resource),
-	RINIT(0x0000, 0x007f, RM9K_GE_RESOURCE_FIFOMEM_RX, &excite_fifomem_resource),
-	RINIT(0x0080, 0x00ff, RM9K_GE_RESOURCE_FIFOMEM_TX, &excite_fifomem_resource),
-	RINIT(0x0180, 0x019f, RM9K_GE_RESOURCE_PHY, &excite_titan_resource),
-	RINIT(0x0000, 0x03ff, RM9K_GE_RESOURCE_DMADESC_RX, &excite_scram_resource),
-	RINIT(0x0400, 0x07ff, RM9K_GE_RESOURCE_DMADESC_TX, &excite_scram_resource),
-	RINIT(slice_eth, slice_eth, RM9K_GE_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
-	RINIT(0, 0, RM9K_GE_RESOURCE_MDIO_CHANNEL, &excite_mdio_channel_resource),
-	RINIT_IRQ(TITAN_IRQ,  RM9K_GE_RESOURCE_IRQ_MAIN),
-	RINIT_IRQ(PHY_IRQ, RM9K_GE_RESOURCE_IRQ_PHY)
-};
-
-static struct platform_device rm9k_ge_pdev = {
-	.name		= RM9K_GE_NAME,
-	.id		= RM9K_GE_UNIT,
-	.num_resources	= ARRAY_SIZE(rm9k_ge_rsrc),
-	.resource	= rm9k_ge_rsrc
-};
-
-
-
-/*
- * Create a platform device for the Ethernet port.
- */
-static int __init rm9k_ge_devinit(void)
-{
-	u32 reg;
-
-	adjust_resources(rm9k_ge_rsrc, ARRAY_SIZE(rm9k_ge_rsrc));
-
-	/* Power up the slice and configure it. */
-	reg = titan_readl(CPTC1R);
-	reg &= ~(0x11000 << slice_eth);
-	reg |= 0x100 << slice_eth;
-	titan_writel(reg, CPTC1R);
-
-	/* Take the MAC out of reset, reset the DLLs. */
-	reg = titan_readl(CPRR);
-	reg &= ~(0x00030000 << (slice_eth * 2));
-	reg |= 0x3 << (slice_eth * 2);
-	titan_writel(reg, CPRR);
-
-	return platform_device_register(&rm9k_ge_pdev);
-}
-
-device_initcall(rm9k_ge_devinit);
-#endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */
-
-
-
-static int __init excite_setup_devs(void)
-{
-	int res;
-	u32 reg;
-
-	/* Enable xdma and fifo interrupts */
-	reg = titan_readl(0x0050);
-	titan_writel(reg | 0x18000000, 0x0050);
-
-	res = request_resource(&iomem_resource, &excite_titan_resource);
-	if (res)
-		return res;
-	res = request_resource(&iomem_resource, &excite_scram_resource);
-	if (res)
-		return res;
-	res = request_resource(&iomem_resource, &excite_fpga_resource);
-	if (res)
-		return res;
-	res = request_resource(&iomem_resource, &excite_nand_resource);
-	if (res)
-		return res;
-	excite_fpga_resource.flags = excite_fpga_resource.parent->flags &
-				   ( IORESOURCE_IO | IORESOURCE_MEM
-				   | IORESOURCE_IRQ | IORESOURCE_DMA);
-	excite_nand_resource.flags = excite_nand_resource.parent->flags &
-				   ( IORESOURCE_IO | IORESOURCE_MEM
-				   | IORESOURCE_IRQ | IORESOURCE_DMA);
-
-	return 0;
-}
-
-arch_initcall(excite_setup_devs);
-
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_iodev.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_iodev.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_iodev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_iodev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,178 +0,0 @@
-/*
- *  Copyright (C) 2005 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.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/compiler.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
-
-#include "excite_iodev.h"
-
-
-
-static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
-static int __init iodev_probe(struct platform_device *);
-static int __exit iodev_remove(struct platform_device *);
-static int iodev_open(struct inode *, struct file *);
-static int iodev_release(struct inode *, struct file *);
-static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
-static unsigned int iodev_poll(struct file *, struct poll_table_struct *);
-static irqreturn_t iodev_irqhdl(int, void *);
-
-
-
-static const char iodev_name[] = "iodev";
-static unsigned int iodev_irq;
-static DECLARE_WAIT_QUEUE_HEAD(wq);
-
-
-
-static const struct file_operations fops =
-{
-	.owner		= THIS_MODULE,
-	.open		= iodev_open,
-	.release	= iodev_release,
-	.read		= iodev_read,
-	.poll		= iodev_poll
-};
-
-static struct miscdevice miscdev =
-{
-	.minor		= MISC_DYNAMIC_MINOR,
-	.name		= iodev_name,
-	.fops		= &fops
-};
-
-static struct platform_driver iodev_driver = {
-	.driver = {
-		.name		= iodev_name,
-		.owner		= THIS_MODULE,
-	},
-	.probe		= iodev_probe,
-	.remove		= __devexit_p(iodev_remove),
-};
-
-
-
-static const struct resource *
-iodev_get_resource(struct platform_device *pdv, const char *name,
-		     unsigned int type)
-{
-	char buf[80];
-	if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
-		return NULL;
-	return platform_get_resource_byname(pdv, type, buf);
-}
-
-
-
-/* No hotplugging on the platform bus - use __init */
-static int __init iodev_probe(struct platform_device *dev)
-{
-	const struct resource * const ri =
-		iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
-
-	if (unlikely(!ri))
-		return -ENXIO;
-
-	iodev_irq = ri->start;
-	return misc_register(&miscdev);
-}
-
-
-
-static int __exit iodev_remove(struct platform_device *dev)
-{
-	return misc_deregister(&miscdev);
-}
-
-static int iodev_open(struct inode *i, struct file *f)
-{
-	int ret;
-
-	ret = request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
-			   iodev_name, &miscdev);
-
-	return ret;
-}
-
-static int iodev_release(struct inode *i, struct file *f)
-{
-	free_irq(iodev_irq, &miscdev);
-	return 0;
-}
-
-
-
-
-static ssize_t
-iodev_read(struct file *f, char __user *d, size_t s, loff_t *o)
-{
-	ssize_t ret;
-	DEFINE_WAIT(w);
-
-	prepare_to_wait(&wq, &w, TASK_INTERRUPTIBLE);
-	if (!signal_pending(current))
-		schedule();
-	ret = signal_pending(current) ? -ERESTARTSYS : 0;
-	finish_wait(&wq, &w);
-	return ret;
-}
-
-
-static unsigned int iodev_poll(struct file *f, struct poll_table_struct *p)
-{
-	poll_wait(f, &wq, p);
-	return POLLOUT | POLLWRNORM;
-}
-
-static irqreturn_t iodev_irqhdl(int irq, void *ctxt)
-{
-	wake_up(&wq);
-
-	return IRQ_HANDLED;
-}
-
-static int __init iodev_init_module(void)
-{
-	return platform_driver_register(&iodev_driver);
-}
-
-
-
-static void __exit iodev_cleanup_module(void)
-{
-	platform_driver_unregister(&iodev_driver);
-}
-
-module_init(iodev_init_module);
-module_exit(iodev_cleanup_module);
-
-
-
-MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
-MODULE_DESCRIPTION("Basler eXcite i/o interrupt handler");
-MODULE_VERSION("0.0");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_iodev.h linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_iodev.h
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_iodev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_iodev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-#ifndef __EXCITE_IODEV_H__
-#define __EXCITE_IODEV_H__
-
-/* Device name */
-#define IODEV_NAME		"iodev"
-
-/* Resource names */
-#define IODEV_RESOURCE_IRQ	"excite_iodev_irq"
-
-#endif /* __EXCITE_IODEV_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_irq.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/*
- *  Copyright (C) by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslereb.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/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.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/slab.h>
-#include <linux/random.h>
-#include <linux/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/rm9k-ocd.h>
-
-#include <excite.h>
-
-extern asmlinkage void excite_handle_int(void);
-
-/*
- * Initialize the interrupt handler
- */
-void __init arch_init_irq(void)
-{
-	mips_cpu_irq_init();
-	rm7k_cpu_irq_init();
-	rm9k_cpu_irq_init();
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-	const u32
-		interrupts = read_c0_cause() >> 8,
-		mask = ((read_c0_status() >> 8) & 0x000000ff) |
-		       (read_c0_intcontrol() & 0x0000ff00),
-		pending = interrupts & mask;
-	u32 msgintflags, msgintmask, msgint;
-
-	/* process timer interrupt */
-	if (pending & (1 << TIMER_IRQ)) {
-		do_IRQ(TIMER_IRQ);
-		return;
-	}
-
-	/* Process PCI interrupts */
-#if USB_IRQ < 10
-	msgintflags = ocd_readl(INTP0Status0 + (USB_MSGINT / 0x20 * 0x10));
-	msgintmask  = ocd_readl(INTP0Mask0 + (USB_MSGINT / 0x20 * 0x10));
-	msgint	    = msgintflags & msgintmask & (0x1 << (USB_MSGINT % 0x20));
-	if ((pending & (1 << USB_IRQ)) && msgint) {
-#else
-	if (pending & (1 << USB_IRQ)) {
-#endif
-		do_IRQ(USB_IRQ);
-		return;
-	}
-
-	/* Process TITAN interrupts */
-	msgintflags = ocd_readl(INTP0Status0 + (TITAN_MSGINT / 0x20 * 0x10));
-	msgintmask  = ocd_readl(INTP0Mask0 + (TITAN_MSGINT / 0x20 * 0x10));
-	msgint	    = msgintflags & msgintmask & (0x1 << (TITAN_MSGINT % 0x20));
-	if ((pending & (1 << TITAN_IRQ)) && msgint) {
-		ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10));
-		do_IRQ(TITAN_IRQ);
-		return;
-	}
-
-	/* Process FPGA line #0 interrupts */
-	msgintflags = ocd_readl(INTP0Status0 + (FPGA0_MSGINT / 0x20 * 0x10));
-	msgintmask  = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10));
-	msgint	    = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20));
-	if ((pending & (1 << FPGA0_IRQ)) && msgint) {
-		do_IRQ(FPGA0_IRQ);
-		return;
-	}
-
-	/* Process FPGA line #1 interrupts */
-	msgintflags = ocd_readl(INTP0Status0 + (FPGA1_MSGINT / 0x20 * 0x10));
-	msgintmask  = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10));
-	msgint	    = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20));
-	if ((pending & (1 << FPGA1_IRQ)) && msgint) {
-		do_IRQ(FPGA1_IRQ);
-		return;
-	}
-
-	/* Process PHY interrupts */
-	msgintflags = ocd_readl(INTP0Status0 + (PHY_MSGINT / 0x20 * 0x10));
-	msgintmask  = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10));
-	msgint	    = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20));
-	if ((pending & (1 << PHY_IRQ)) && msgint) {
-		do_IRQ(PHY_IRQ);
-		return;
-	}
-
-	/* Process spurious interrupts */
-	spurious_interrupt();
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_procfs.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_procfs.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_procfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_procfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,92 +0,0 @@
-/*
- *  Copyright (C) 2004, 2005 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
- *
- *  Procfs support for Basler eXcite
- *
- *  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/module.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/stat.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/rm9k-ocd.h>
-
-#include <excite.h>
-
-static int excite_unit_id_proc_show(struct seq_file *m, void *v)
-{
-	seq_printf(m, "%06x", unit_id);
-	return 0;
-}
-
-static int excite_unit_id_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, excite_unit_id_proc_show, NULL);
-}
-
-static const struct file_operations excite_unit_id_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= excite_unit_id_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static int
-excite_bootrom_read(char *page, char **start, off_t off, int count,
-		  int *eof, void *data)
-{
-	void __iomem * src;
-
-	if (off >= EXCITE_SIZE_BOOTROM) {
-		*eof = 1;
-		return 0;
-	}
-
-	if ((off + count) > EXCITE_SIZE_BOOTROM)
-		count = EXCITE_SIZE_BOOTROM - off;
-
-	src = ioremap(EXCITE_PHYS_BOOTROM + off, count);
-	if (src) {
-		memcpy_fromio(page, src, count);
-		iounmap(src);
-		*start = page;
-	} else {
-		count = -ENOMEM;
-	}
-
-	return count;
-}
-
-void excite_procfs_init(void)
-{
-	/* Create & populate /proc/excite */
-	struct proc_dir_entry * const pdir = proc_mkdir("excite", NULL);
-	if (pdir) {
-		struct proc_dir_entry * e;
-
-		e = proc_create("unit_id", S_IRUGO, pdir,
-				&excite_unit_id_proc_fops);
-		if (e) e->size = 6;
-
-		e = create_proc_read_entry("bootrom", S_IRUGO, pdir,
-					   excite_bootrom_read, NULL);
-		if (e) e->size = EXCITE_SIZE_BOOTROM;
-	}
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_prom.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_prom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,144 +0,0 @@
-/*
- *  Copyright (C) 2004, 2005 by Thomas Koeller (thomas.koeller@baslerweb.com)
- *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
- *  Manish Lachwani.
- *
- *  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/init.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <asm/bootinfo.h>
-#include <asm/string.h>
-
-#include <excite.h>
-
-/* This struct is used by Redboot to pass arguments to the kernel */
-typedef struct
-{
-	char *name;
-	char *val;
-} t_env_var;
-
-struct parmblock {
-	t_env_var memsize;
-	t_env_var modetty0;
-	t_env_var ethaddr;
-	t_env_var env_end;
-	char *argv[2];
-	char text[0];
-};
-
-static unsigned int prom_argc;
-static const char ** prom_argv;
-static const t_env_var * prom_env;
-
-static void prom_halt(void) __attribute__((noreturn));
-static void prom_exit(void) __attribute__((noreturn));
-
-
-
-const char *get_system_type(void)
-{
-	return "Basler eXcite";
-}
-
-/*
- * Halt the system
- */
-static void prom_halt(void)
-{
-	printk(KERN_NOTICE "\n** System halted.\n");
-	while (1)
-		asm volatile (
-			"\t.set\tmips3\n"
-			"\twait\n"
-			"\t.set\tmips0\n"
-		);
-}
-
-/*
- * Reset the CPU and re-enter Redboot
- */
-static void prom_exit(void)
-{
-	unsigned int i;
-	volatile unsigned char * const flg =
-		(volatile unsigned char *) (EXCITE_ADDR_FPGA + EXCITE_FPGA_DPR);
-
-	/* Clear the watchdog reset flag, set the reboot flag */
-	*flg &= ~0x01;
-	*flg |= 0x80;
-
-	for (i = 0; i < 10; i++) {
-		*(volatile unsigned char *)  (EXCITE_ADDR_FPGA + EXCITE_FPGA_SYSCTL) = 0x02;
-		iob();
-		mdelay(1000);
-	}
-
-	printk(KERN_NOTICE "Reset failed\n");
-	prom_halt();
-}
-
-static const char __init *prom_getenv(char *name)
-{
-	const t_env_var * p;
-	for (p = prom_env; p->name != NULL; p++)
-		if(strcmp(name, p->name) == 0)
-			break;
-	return p->val;
-}
-
-/*
- * Init routine which accepts the variables from Redboot
- */
-void __init prom_init(void)
-{
-	const struct parmblock * const pb = (struct parmblock *) fw_arg2;
-
-	prom_argc = fw_arg0;
-	prom_argv = (const char **) fw_arg1;
-	prom_env = &pb->memsize;
-
-	/* Callbacks for halt, restart */
-	_machine_restart = (void (*)(char *)) prom_exit;
-	_machine_halt = prom_halt;
-
-#ifdef CONFIG_32BIT
-	/* copy command line */
-	strcpy(arcs_cmdline, prom_argv[1]);
-	memsize = simple_strtol(prom_getenv("memsize"), NULL, 16);
-	strcpy(modetty, prom_getenv("modetty0"));
-#endif /* CONFIG_32BIT */
-
-#ifdef CONFIG_64BIT
-#	error 64 bit support not implemented
-#endif /* CONFIG_64BIT */
-}
-
-/* This is called from free_initmem(), so we need to provide it */
-void __init prom_free_prom_memory(void)
-{
-	/* Nothing to do */
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_setup.c linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/excite_setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/excite_setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,302 +0,0 @@
-/*
- *  Copyright (C) 2004, 2005 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
- *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
- *  Manish Lachwani.
- *
- *  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/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <asm/bootinfo.h>
-#include <asm/mipsregs.h>
-#include <asm/pgtable-32.h>
-#include <asm/io.h>
-#include <asm/time.h>
-#include <asm/rm9k-ocd.h>
-
-#include <excite.h>
-
-#define TITAN_UART_CLK	25000000
-
-#if 1
-/* normal serial port assignment */
-#define REGBASE_SER0	0x0208
-#define REGBASE_SER1	0x0238
-#define MASK_SER0	0x1
-#define MASK_SER1	0x2
-#else
-/* serial ports swapped */
-#define REGBASE_SER0	0x0238
-#define REGBASE_SER1	0x0208
-#define MASK_SER0	0x2
-#define MASK_SER1	0x1
-#endif
-
-unsigned long memsize;
-char modetty[30];
-unsigned int titan_irq = TITAN_IRQ;
-static void __iomem * ctl_regs;
-u32 unit_id;
-
-volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD);
-volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN);
-
-/* Protect access to shared GPI registers */
-DEFINE_SPINLOCK(titan_lock);
-int titan_irqflags;
-
-
-/*
- * The eXcite platform uses the alternate timer interrupt
- *
- * Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how
- * to handle the alternate timer interrupt of the RM9000.
- */
-void __init plat_time_init(void)
-{
-	const u32 modebit5 = ocd_readl(0x00e4);
-	unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2;
-	unsigned int div = ((modebit5 >> 16) & 0x1f) + 2;
-
-	if (div == 33)
-		div = 1;
-	mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2;
-}
-
-static int __init excite_init_console(void)
-{
-#if defined(CONFIG_SERIAL_8250)
-	static __initdata char serr[] =
-		KERN_ERR "Serial port #%u setup failed\n";
-	struct uart_port up;
-
-	/* Take the DUART out of reset */
-	titan_writel(0x00ff1cff, CPRR);
-
-#if (CONFIG_SERIAL_8250_NR_UARTS > 1)
-	/* Enable both ports */
-	titan_writel(MASK_SER0 | MASK_SER1, UACFG);
-#else
-	/* Enable port #0 only */
-	titan_writel(MASK_SER0, UACFG);
-#endif
-
- 	/*
-	 * Set up serial port #0. Do not use autodetection; the result is
-	 * not what we want.
- 	 */
-	memset(&up, 0, sizeof(up));
-	up.membase	= (char *) titan_addr(REGBASE_SER0);
-	up.irq		= TITAN_IRQ;
-	up.uartclk	= TITAN_UART_CLK;
-	up.regshift	= 0;
-	up.iotype	= UPIO_RM9000;
-	up.type		= PORT_RM9000;
-	up.flags	= UPF_SHARE_IRQ;
-	up.line		= 0;
-	if (early_serial_setup(&up))
-		printk(serr, up.line);
-
-#if CONFIG_SERIAL_8250_NR_UARTS > 1
-	/* And now for port #1. */
-	up.membase	= (char *) titan_addr(REGBASE_SER1);
-	up.line		= 1;
- 	if (early_serial_setup(&up))
-		printk(serr, up.line);
-#endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */
-#else
-	/* Leave the DUART in reset */
-	titan_writel(0x00ff3cff, CPRR);
-#endif  /* defined(CONFIG_SERIAL_8250) */
-
-	return 0;
-}
-
-static int __init excite_platform_init(void)
-{
-	unsigned int i;
-	unsigned char buf[3];
-	u8 reg;
-	void __iomem * dpr;
-
-	/* BIU buffer allocations */
-	ocd_writel(8, CPURSLMT);	/* CPU */
-	titan_writel(4, CPGRWL);	/* GPI / Ethernet */
-
-	/* Map control registers located in FPGA */
-	ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16);
-	if (!ctl_regs)
-		panic("eXcite: failed to map platform control registers\n");
-	memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf));
-	unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16);
-
-	/* Clear the reboot flag */
-	dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1);
-	reg = __raw_readb(dpr);
-	__raw_writeb(reg & 0x7f, dpr);
-	iounmap(dpr);
-
-	/* Interrupt controller setup */
-	for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) {
-		ocd_writel(0x00000000, i + 0x04);
-		ocd_writel(0xffffffff, i + 0x0c);
-	}
-	ocd_writel(0x2, NMICONFIG);
-
-	ocd_writel(0x1 << (TITAN_MSGINT % 0x20),
-		   INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20)));
-	ocd_writel((0x1 << (FPGA0_MSGINT % 0x20))
-		   | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))),
-		   INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20)));
-	ocd_writel((0x1 << (FPGA1_MSGINT % 0x20))
-		   | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))),
-		   INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20)));
-	ocd_writel((0x1 << (PHY_MSGINT % 0x20))
-		   | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))),
-		   INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20)));
-#if USB_IRQ < 10
-	ocd_writel((0x1 << (USB_MSGINT % 0x20))
-		   | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))),
-		   INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20)));
-#endif
-	/* Enable the packet FIFO, XDMA and XDMA arbiter */
-	titan_writel(0x00ff18ff, CPRR);
-
-	/*
-	 * Set up the PADMUX. Power down all ethernet slices,
-	 * they will be powered up and configured at device startup.
-	 */
-	titan_writel(0x00878206, CPTC1R);
-	titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */
-
-	/* Reset and enable the FIFO block */
-	titan_writel(0x00000001, SDRXFCIE);
-	titan_writel(0x00000001, SDTXFCIE);
-	titan_writel(0x00000100, SDRXFCIE);
-	titan_writel(0x00000000, SDTXFCIE);
-
-	/*
-	 * Initialize the common interrupt shared by all components of
-	 * the GPI/Ethernet subsystem.
-	 */
-	titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0);
-	titan_writel(TITAN_MSGINT, CPCFG1);
-
-	/*
-	 * XDMA configuration.
-	 * In order for the XDMA to be sharable among multiple drivers,
-	 * the setup must be done here in the platform. The reason is that
-	 * this setup can only be done while the XDMA is in reset. If this
-	 * were done in a driver, it would interrupt all other drivers
-	 * using the XDMA.
-	 */
-	titan_writel(0x80021dff, GXCFG);	/* XDMA reset */
-	titan_writel(0x00000000, CPXCISRA);
-	titan_writel(0x00000000, CPXCISRB);	/* clear pending interrupts */
-#if defined(CONFIG_HIGHMEM)
-#	error change for HIGHMEM support!
-#else
-	titan_writel(0x00000000, GXDMADRPFX);	/* buffer address prefix */
-#endif
-	titan_writel(0, GXDMA_DESCADR);
-
-	for (i = 0x5040; i <= 0x5300; i += 0x0040)
-		titan_writel(0x80080000, i);	/* reset channel */
-
-	titan_writel((0x1 << 29)			/* no sparse tx descr. */
-		     | (0x1 << 28)			/* no sparse rx descr. */
-		     | (0x1 << 23) | (0x1 << 24)	/* descriptor coherency */
-		     | (0x1 << 21) | (0x1 << 22)	/* data coherency */
-		     | (0x1 << 17)
-		     | 0x1dff,
-		     GXCFG);
-
-#if defined(CONFIG_SMP)
-#	error No SMP support
-#else
-	/* All interrupts go to core #0 only. */
-	titan_writel(0x1f007fff, CPDST0A);
-	titan_writel(0x00000000, CPDST0B);
-	titan_writel(0x0000ff3f, CPDST1A);
-	titan_writel(0x00000000, CPDST1B);
-	titan_writel(0x00ffffff, CPXDSTA);
-	titan_writel(0x00000000, CPXDSTB);
-#endif
-
-	/* Enable DUART interrupts, disable everything else. */
-	titan_writel(0x04000000, CPGIG0ER);
-	titan_writel(0x000000c0, CPGIG1ER);
-
-	excite_procfs_init();
-	return 0;
-}
-
-void __init plat_mem_setup(void)
-{
-	volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000;
-
-	/* Announce RAM to system */
-	add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
-
-	/* Set up the peripheral address map */
-	*(boot_ocd_base + (LKB9 / sizeof(u32))) = 0;
-	*(boot_ocd_base + (LKB10 / sizeof(u32))) = 0;
-	*(boot_ocd_base + (LKB11 / sizeof(u32))) = 0;
-	*(boot_ocd_base + (LKB12 / sizeof(u32))) = 0;
-	wmb();
-	*(boot_ocd_base + (LKB0 / sizeof(u32))) = EXCITE_PHYS_OCD >> 4;
-	wmb();
-
-	ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5);
-	ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5);
-	ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13);
-	ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13);
-
-	/* Local bus slot #0 */
-	ocd_writel(0x00040510, LDP0);
-	ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9);
-	ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9);
-
-	/* Local bus slot #2 */
-	ocd_writel(0x00000330, LDP2);
-	ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11);
-	ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11);
-
-	/* Local bus slot #3 */
-	ocd_writel(0x00123413, LDP3);
-	ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12);
-	ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12);
-}
-
-
-
-console_initcall(excite_init_console);
-arch_initcall(excite_platform_init);
-
-EXPORT_SYMBOL(titan_lock);
-EXPORT_SYMBOL(titan_irqflags);
-EXPORT_SYMBOL(titan_irq);
-EXPORT_SYMBOL(ocd_base);
-EXPORT_SYMBOL(titan_base);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/Kconfig linux-libre-2.6.33-gnu1/arch/mips/basler/excite/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-config BASLER_EXCITE_PROTOTYPE
-	bool "Support for pre-release units"
-	depends on BASLER_EXCITE
-	default n
-	help
-	  Pre-series (prototype) units are different from later ones in
-	  some ways. Select this option if you have one of these. Please
-	  note that a kernel built with this option selected will not be
-	  able to run on normal units.
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/basler/excite/Makefile linux-libre-2.6.33-gnu1/arch/mips/basler/excite/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/basler/excite/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/basler/excite/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#
-# Makefile for Basler eXcite
-#
-
-obj-$(CONFIG_BASLER_EXCITE)	+= excite_irq.o excite_prom.o excite_setup.o \
-				   excite_device.o excite_procfs.o
-
-obj-m				+= excite_iodev.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/bcm47xx/prom.c linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/bcm47xx/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/bcm47xx/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,11 +100,11 @@ static __init void prom_init_console(voi
 
 static __init void prom_init_cmdline(void)
 {
-	static char buf[CL_SIZE] __initdata;
+	static char buf[COMMAND_LINE_SIZE] __initdata;
 
 	/* Get the kernel command line from CFE */
-	if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) {
-		buf[CL_SIZE-1] = 0;
+	if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) {
+		buf[COMMAND_LINE_SIZE - 1] = 0;
 		strcpy(arcs_cmdline, buf);
 	}
 
@@ -112,13 +112,13 @@ static __init void prom_init_cmdline(voi
 	 * as CFE is not available anymore later in the boot process. */
 	if ((strstr(arcs_cmdline, "console=")) == NULL) {
 		/* Try to read the default serial port used by CFE */
-		if ((cfe_getenv("BOOT_CONSOLE", buf, CL_SIZE) < 0)
+		if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0)
 		    || (strncmp("uart", buf, 4)))
 			/* Default to uart0 */
 			strcpy(buf, "uart0");
 
 		/* Compute the new command line */
-		snprintf(arcs_cmdline, CL_SIZE, "%s console=ttyS%c,115200",
+		snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200",
 			 arcs_cmdline, buf[4]);
 	}
 }
@@ -141,6 +141,14 @@ static __init void prom_init_mem(void)
 			break;
 	}
 
+	/* Ignoring the last page when ddr size is 128M. Cached
+	 * accesses to last page is causing the processor to prefetch
+	 * using address above 128M stepping out of the ddr address
+	 * space.
+	 */
+	if (mem == 0x8000000)
+		mem -= 0x1000;
+
 	add_memory_region(0, mem, BOOT_MEM_RAM);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c
--- linux-libre-2.6.32-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/boards/board_bcm963xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -346,27 +346,26 @@ static struct board_info __initdata boar
 };
 
 static struct board_info __initdata board_FAST2404 = {
-        .name                           = "F@ST2404",
-        .expected_cpu_id                = 0x6348,
-
-        .has_enet0                      = 1,
-        .has_enet1                      = 1,
-        .has_pci                        = 1,
+	.name				= "F@ST2404",
+	.expected_cpu_id		= 0x6348,
 
-        .enet0 = {
-                .has_phy                = 1,
-                .use_internal_phy       = 1,
-        },
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
 
-        .enet1 = {
-                .force_speed_100        = 1,
-                .force_duplex_full      = 1,
-        },
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
 
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
 
-        .has_ohci0 = 1,
-        .has_pccard = 1,
-        .has_ehci0 = 1,
+	.has_ohci0			= 1,
+	.has_pccard			= 1,
+	.has_ehci0			= 1,
 };
 
 static struct board_info __initdata board_DV201AMR = {
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/bcm63xx/prom.c linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/bcm63xx/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/bcm63xx/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,9 +40,6 @@ void __init prom_init(void)
 	reg &= ~mask;
 	bcm_perf_writel(reg, PERF_CKCTL_REG);
 
-	/* assign command line from kernel config */
-	strcpy(arcs_cmdline, CONFIG_CMDLINE);
-
 	/* register gpiochip */
 	bcm63xx_gpio_init();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/addinitrd.c linux-libre-2.6.33-gnu1/arch/mips/boot/addinitrd.c
--- linux-libre-2.6.32-gnu1/arch/mips/boot/addinitrd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/addinitrd.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,131 +0,0 @@
-/*
- * addinitrd - program to add a initrd image to an ecoff kernel
- *
- * (C) 1999 Thomas Bogendoerfer
- * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
- * further cleanup: Maciej W. Rozycki
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <netinet/in.h>
-
-#include "ecoff.h"
-
-#define MIPS_PAGE_SIZE	4096
-#define MIPS_PAGE_MASK	(MIPS_PAGE_SIZE-1)
-
-#define swab16(x) \
-        ((unsigned short)( \
-                (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
-                (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
-
-#define swab32(x) \
-        ((unsigned int)( \
-                (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
-                (((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
-                (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
-                (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
-
-#define SWAB(a)	(swab ? swab32(a) : (a))
-
-void die(char *s)
-{
-	perror(s);
-	exit(1);
-}
-
-int main(int argc, char *argv[])
-{
-	int fd_vmlinux, fd_initrd, fd_outfile;
-	FILHDR efile;
-	AOUTHDR eaout;
-	SCNHDR esecs[3];
-	struct stat st;
-	char buf[1024];
-	unsigned long loadaddr;
-	unsigned long initrd_header[2];
-	int i, cnt;
-	int swab = 0;
-
-	if (argc != 4) {
-		printf("Usage: %s <vmlinux> <initrd> <outfile>\n", argv[0]);
-		exit(1);
-	}
-
-	if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0)
-		 die("open vmlinux");
-	if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
-		die("read file header");
-	if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
-		die("read aout header");
-	if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
-		die("read section headers");
-	/*
-	 * check whether the file is good for us
-	 */
-	/* TBD */
-
-	/*
-	 * check, if we have to swab words
-	 */
-	if (ntohs(0xaa55) == 0xaa55) {
-		if (efile.f_magic == swab16(MIPSELMAGIC))
-			swab = 1;
-	} else {
-		if (efile.f_magic == swab16(MIPSEBMAGIC))
-			swab = 1;
-	}
-
-	/* make sure we have an empty data segment for the initrd */
-	if (eaout.dsize || esecs[1].s_size) {
-		fprintf(stderr, "Data segment not empty. Giving up!\n");
-		exit(1);
-	}
-	if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
-		die("open initrd");
-	if (fstat (fd_initrd, &st) < 0)
-		die("fstat initrd");
-	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
-			+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
-	if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
-		loadaddr += MIPS_PAGE_SIZE;
-	initrd_header[0] = SWAB(0x494E5244);
-	initrd_header[1] = SWAB(st.st_size);
-	eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
-	eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
-
-	if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
-		die("open outfile");
-	if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
-		die("write file header");
-	if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
-		die("write aout header");
-	if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
-		die("write section headers");
-	/* skip padding */
-	if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
-		die("lseek vmlinux");
-	if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
-		die("lseek outfile");
-	/* copy text segment */
-	cnt = SWAB(eaout.tsize);
-	while (cnt) {
-		if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
-			die("read vmlinux");
-		if (write (fd_outfile, buf, i) != i)
-			die("write vmlinux");
-		cnt -= i;
-	}
-	if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
-		die("write initrd header");
-	while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
-		if (write (fd_outfile, buf, i) != i)
-			die("write initrd");
-	close(fd_vmlinux);
-	close(fd_initrd);
-	return 0;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/dbg.c linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dbg.c
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/dbg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dbg.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,37 @@
+/*
+ * MIPS-specific debug support for pre-boot environment
+ *
+ * NOTE: putc() is board specific, if your board have a 16550 compatible uart,
+ * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
+ * need to implement your own putc().
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+
+void __attribute__ ((weak)) putc(char c)
+{
+}
+
+void puts(const char *s)
+{
+	char c;
+	while ((c = *s++) != '\0') {
+		putc(c);
+		if (c == '\n')
+			putc('\r');
+	}
+}
+
+void puthex(unsigned long long val)
+{
+
+	unsigned char buf[10];
+	int i;
+	for (i = 7; i >= 0; i--) {
+		buf[i] = "0123456789ABCDEF"[val & 0x0F];
+		val >>= 4;
+	}
+	buf[8] = '\0';
+	puts(buf);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/decompress.c linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/decompress.c
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/decompress.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/decompress.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,120 @@
+/*
+ * Misc. bootloader code for many machines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Matt Porter <mporter@mvista.com> Derived from
+ * arch/ppc/boot/prep/misc.c
+ *
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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/types.h>
+#include <linux/kernel.h>
+
+#include <asm/addrspace.h>
+
+/* These two variables specify the free mem region
+ * that can be used for temporary malloc area
+ */
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
+char *zimage_start;
+
+/* The linker tells us where the image is. */
+extern unsigned char __image_begin, __image_end;
+
+/* debug interfaces  */
+extern void puts(const char *s);
+extern void puthex(unsigned long long val);
+
+void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while (1)
+		;	/* Halt */
+}
+
+/* activate the code for pre-boot environment */
+#define STATIC static
+
+#ifdef CONFIG_KERNEL_GZIP
+void *memcpy(void *dest, const void *src, size_t n)
+{
+	int i;
+	const char *s = src;
+	char *d = dest;
+
+	for (i = 0; i < n; i++)
+		d[i] = s[i];
+	return dest;
+}
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss = s;
+
+	for (i = 0; i < n; i++)
+		ss[i] = c;
+	return s;
+}
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+void decompress_kernel(unsigned long boot_heap_start)
+{
+	int zimage_size;
+
+	/*
+	 * We link ourself to an arbitrary low address.  When we run, we
+	 * relocate outself to that address.  __image_beign points to
+	 * the part of the image where the zImage is. -- Tom
+	 */
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+	    (unsigned long)(&__image_begin);
+
+	/*
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
+	 */
+	puts("zimage at:     ");
+	puthex((unsigned long)zimage_start);
+	puts(" ");
+	puthex((unsigned long)(zimage_size + zimage_start));
+	puts("\n");
+
+	/* this area are prepared for mallocing when decompressing */
+	free_mem_ptr = boot_heap_start;
+	free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
+
+	/* Display standard Linux/MIPS boot prompt for kernel args */
+	puts("Uncompressing Linux at load address ");
+	puthex(VMLINUX_LOAD_ADDRESS_ULL);
+	puts("\n");
+	/* Decompress the kernel with according algorithm */
+	decompress(zimage_start, zimage_size, 0, 0,
+		   (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
+	/* FIXME: is there a need to flush cache here? */
+	puts("Now, booting the kernel...\n");
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/dummy.c linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dummy.c
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/dummy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/dummy.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,4 @@
+int main(void)
+{
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/head.S linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/head.S
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/head.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,56 @@
+/*
+ * 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) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+	.set noreorder
+	.cprestore
+	LEAF(start)
+start:
+	/* Save boot rom start args */
+	move	s0, a0
+	move	s1, a1
+	move	s2, a2
+	move	s3, a3
+
+	/* Clear BSS */
+	PTR_LA	a0, _edata
+	PTR_LA	a2, _end
+1:	sw	zero, 0(a0)
+	bne	a2, a0, 1b
+	 addiu	a0, a0, 4
+
+	PTR_LA	a0, (.heap)          /* heap address */
+	PTR_LA  sp, (.stack + 8192)  /* stack address */
+
+	PTR_LA	ra, 2f
+	PTR_LA	k0, decompress_kernel
+	jr	k0
+	 nop
+2:
+	move	a0, s0
+	move	a1, s1
+	move	a2, s2
+	move	a3, s3
+	PTR_LI	k0, KERNEL_ENTRY
+	jr	k0
+	 nop
+3:
+	b	3b
+	 nop
+	END(start)
+
+	.comm .heap,BOOT_HEAP_SIZE,4
+	.comm .stack,4096*2,4
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/ld.script linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/ld.script
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/ld.script	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/ld.script	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,67 @@
+/*
+ * ld.script for compressed kernel support of MIPS
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ */
+
+OUTPUT_ARCH(mips)
+ENTRY(start)
+SECTIONS
+{
+	/* . = VMLINUZ_LOAD_ADDRESS */
+	/* read-only */
+	_text = .;	/* Text and read-only data */
+	.text	: {
+		_ftext = . ;
+		*(.text)
+		*(.rodata)
+	} = 0
+	_etext = .;	/* End of text section */
+
+	/* writable */
+	.data	: {	/* Data */
+		_fdata = . ;
+		*(.data)
+		/* Put the compressed image here, so bss is on the end. */
+		__image_begin = .;
+		*(.image)
+		__image_end = .;
+		CONSTRUCTORS
+	}
+	.sdata	: { *(.sdata) }
+	. = ALIGN(4);
+	_edata  =  .;	/* End of data section */
+
+	/* BSS */
+	__bss_start = .;
+	_fbss = .;
+	.sbss	: { *(.sbss) *(.scommon) }
+	.bss	: {
+		*(.dynbss)
+		*(.bss)
+		*(COMMON)
+	}
+	.  = ALIGN(4);
+	_end = . ;
+
+	/* These are needed for ELF backends which have not yet been converted
+	 * to the new style linker.  */
+
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+
+	/* These must appear regardless of  .  */
+	.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+	.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+
+	/* Sections to be discarded */
+	/DISCARD/	: {
+		*(.MIPS.options)
+		*(.options)
+		*(.pdr)
+		*(.reginfo)
+		*(.comment)
+		*(.note)
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/Makefile linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.
+#
+# Adapted for MIPS Pete Popov, Dan Malek
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
+# Author: Wu Zhangjin <wuzj@lemote.com>
+#
+
+# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
+VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1)
+VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536))))
+# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE"
+HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10)))
+LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8)
+VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32))))
+
+# set the default size of the mallocing area for decompressing
+BOOT_HEAP_SIZE := 0x400000
+
+# Disable Function Tracer
+KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
+
+KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
+	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
+
+KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
+	-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
+	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
+
+obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
+
+obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+
+OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
+$(obj)/vmlinux.bin: $(KBUILD_IMAGE)
+	$(call if_changed,objcopy)
+
+suffix_$(CONFIG_KERNEL_GZIP)  = gz
+suffix_$(CONFIG_KERNEL_BZIP2) = bz2
+suffix_$(CONFIG_KERNEL_LZMA)  = lzma
+suffix_$(CONFIG_KERNEL_LZO)   = lzo
+tool_$(CONFIG_KERNEL_GZIP)    = gzip
+tool_$(CONFIG_KERNEL_BZIP2)   = bzip2
+tool_$(CONFIG_KERNEL_LZMA)    = lzma
+tool_$(CONFIG_KERNEL_LZO)     = lzo
+$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
+	$(call if_changed,$(tool_y))
+
+$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o
+	$(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \
+		--add-section=.image=$< \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		$(obj)/dummy.o $@
+
+LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T
+vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o
+	$(call if_changed,ld)
+	$(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_MACH_DECSTATION
+  E2EFLAGS = -a
+else
+  E2EFLAGS =
+endif
+
+# elf2ecoff can only handle 32bit image
+
+ifdef CONFIG_32BIT
+	VMLINUZ = vmlinuz
+else
+	VMLINUZ = vmlinuz.32
+endif
+
+vmlinuz.32: vmlinuz
+	$(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
+	$(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS)
+
+$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c
+	$(Q)$(HOSTCC) -o $@ $^
+
+OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
+vmlinuz.bin: vmlinuz
+	$(call if_changed,objcopy)
+
+OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
+vmlinuz.srec: vmlinuz
+	$(call if_changed,objcopy)
+
+clean:
+clean-files += *.o \
+	       vmlinu*
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/uart-16550.c linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/uart-16550.c
--- linux-libre-2.6.32-gnu1/arch/mips/boot/compressed/uart-16550.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/compressed/uart-16550.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,43 @@
+/*
+ * 16550 compatible uart based serial debug support for zboot
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+
+#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
+#define UART_BASE 0x1fd003f8
+#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
+#endif
+
+#ifdef CONFIG_AR7
+#include <ar7.h>
+#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
+#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));
+}
+
+static inline void serial_out(int offset, int value)
+{
+	*((char *)PORT(offset)) = value;
+}
+
+void putc(char c)
+{
+	int timeout = 1024;
+
+	while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
+		;
+
+	serial_out(UART_TX, c);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/.gitignore linux-libre-2.6.33-gnu1/arch/mips/boot/.gitignore
--- linux-libre-2.6.32-gnu1/arch/mips/boot/.gitignore	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/.gitignore	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,5 @@
 mkboot
 elf2ecoff
+vmlinux.*
 zImage
 zImage.tmp
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/boot/Makefile linux-libre-2.6.33-gnu1/arch/mips/boot/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/boot/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -25,10 +25,10 @@ strip-flags	= $(addprefix --remove-secti
 
 VMLINUX = vmlinux
 
-all: vmlinux.ecoff vmlinux.srec addinitrd
+all: vmlinux.ecoff vmlinux.srec
 
 vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
-	$(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
+	$(obj)/elf2ecoff $(VMLINUX) $(obj)/vmlinux.ecoff $(E2EFLAGS)
 
 $(obj)/elf2ecoff: $(obj)/elf2ecoff.c
 	$(HOSTCC) -o $@ $^
@@ -39,11 +39,7 @@ vmlinux.bin: $(VMLINUX)
 vmlinux.srec: $(VMLINUX)
 	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
 
-$(obj)/addinitrd: $(obj)/addinitrd.c
-	$(HOSTCC) -o $@ $^
-
-clean-files += addinitrd \
-	       elf2ecoff \
+clean-files += elf2ecoff \
 	       vmlinux.bin \
 	       vmlinux.ecoff \
 	       vmlinux.srec
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/cpu.c linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/cpu.c
--- linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * 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) 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/octeon/octeon.h>
+
+static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
+	void *data)
+{
+	unsigned long flags;
+	unsigned int status;
+
+	switch (action) {
+	case CU2_EXCEPTION:
+		prefetch(&current->thread.cp2);
+		local_irq_save(flags);
+		KSTK_STATUS(current) |= ST0_CU2;
+		status = read_c0_status();
+		write_c0_status(status | ST0_CU2);
+		octeon_cop2_restore(&(current->thread.cp2));
+		write_c0_status(status & ~ST0_CU2);
+		local_irq_restore(flags);
+
+		return NOTIFY_BAD;	/* Don't call default notifier */
+	}
+
+	return NOTIFY_OK;		/* Let default notifier send signals */
+}
+
+static struct notifier_block cnmips_cu2_notifier = {
+	.notifier_call = cnmips_cu2_call,
+};
+
+static int cnmips_cu2_setup(void)
+{
+	return register_cu2_notifier(&cnmips_cu2_notifier);
+}
+early_initcall(cnmips_cu2_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/csrc-octeon.c linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/csrc-octeon.c
--- linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/csrc-octeon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/csrc-octeon.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,6 +50,38 @@ static struct clocksource clocksource_mi
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+unsigned long long notrace sched_clock(void)
+{
+	/* 64-bit arithmatic can overflow, so use 128-bit.  */
+#if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 3))
+	u64 t1, t2, t3;
+	unsigned long long rv;
+	u64 mult = clocksource_mips.mult;
+	u64 shift = clocksource_mips.shift;
+	u64 cnt = read_c0_cvmcount();
+
+	asm (
+		"dmultu\t%[cnt],%[mult]\n\t"
+		"nor\t%[t1],$0,%[shift]\n\t"
+		"mfhi\t%[t2]\n\t"
+		"mflo\t%[t3]\n\t"
+		"dsll\t%[t2],%[t2],1\n\t"
+		"dsrlv\t%[rv],%[t3],%[shift]\n\t"
+		"dsllv\t%[t1],%[t2],%[t1]\n\t"
+		"or\t%[rv],%[t1],%[rv]\n\t"
+		: [rv] "=&r" (rv), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3)
+		: [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift)
+		: "hi", "lo");
+	return rv;
+#else
+	/* GCC > 4.3 do it the easy way.  */
+	unsigned int __attribute__((mode(TI))) t;
+	t = read_c0_cvmcount();
+	t = t * clocksource_mips.mult;
+	return (unsigned long long)(t >> clocksource_mips.shift);
+#endif
+}
+
 void __init plat_time_init(void)
 {
 	clocksource_mips.rating = 300;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/Makefile linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
 # Copyright (C) 2005-2009 Cavium Networks
 #
 
-obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
+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 += octeon-memcpy.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/octeon-platform.c linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-platform.c
--- linux-libre-2.6.32-gnu1/arch/mips/cavium-octeon/octeon-platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/cavium-octeon/octeon-platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -159,6 +159,94 @@ out:
 }
 device_initcall(octeon_rng_device_init);
 
+/* Octeon SMI/MDIO interface.  */
+static int __init octeon_mdiobus_device_init(void)
+{
+	struct platform_device *pd;
+	int ret = 0;
+
+	if (octeon_is_simulation())
+		return 0; /* No mdio in the simulator. */
+
+	/* The bus number is the platform_device id.  */
+	pd = platform_device_alloc("mdio-octeon", 0);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = platform_device_add(pd);
+	if (ret)
+		goto fail;
+
+	return ret;
+fail:
+	platform_device_put(pd);
+
+out:
+	return ret;
+
+}
+device_initcall(octeon_mdiobus_device_init);
+
+/* Octeon mgmt port Ethernet interface.  */
+static int __init octeon_mgmt_device_init(void)
+{
+	struct platform_device *pd;
+	int ret = 0;
+	int port, num_ports;
+
+	struct resource mgmt_port_resource = {
+		.flags	= IORESOURCE_IRQ,
+		.start	= -1,
+		.end	= -1
+	};
+
+	if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
+		return 0;
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+		num_ports = 1;
+	else
+		num_ports = 2;
+
+	for (port = 0; port < num_ports; port++) {
+		pd = platform_device_alloc("octeon_mgmt", port);
+		if (!pd) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		switch (port) {
+		case 0:
+			mgmt_port_resource.start = OCTEON_IRQ_MII0;
+			break;
+		case 1:
+			mgmt_port_resource.start = OCTEON_IRQ_MII1;
+			break;
+		default:
+			BUG();
+		}
+		mgmt_port_resource.end = mgmt_port_resource.start;
+
+		ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
+
+		if (ret)
+			goto fail;
+
+		ret = platform_device_add(pd);
+		if (ret)
+			goto fail;
+	}
+	return ret;
+fail:
+	platform_device_put(pd);
+
+out:
+	return ret;
+
+}
+device_initcall(octeon_mgmt_device_init);
+
 MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/cobalt/setup.c linux-libre-2.6.33-gnu1/arch/mips/cobalt/setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/cobalt/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/cobalt/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,26 +97,18 @@ void __init plat_mem_setup(void)
 
 void __init prom_init(void)
 {
-	int narg, indx, posn, nchr;
 	unsigned long memsz;
+	int argc, i;
 	char **argv;
 
 	memsz = fw_arg0 & 0x7fff0000;
-	narg = fw_arg0 & 0x0000ffff;
+	argc = fw_arg0 & 0x0000ffff;
+	argv = (char **)fw_arg1;
 
-	if (narg) {
-		arcs_cmdline[0] = '\0';
-		argv = (char **) fw_arg1;
-		posn = 0;
-		for (indx = 1; indx < narg; ++indx) {
-			nchr = strlen(argv[indx]);
-			if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
-				break;
-			if (posn)
-				arcs_cmdline[posn++] = ' ';
-			strcpy(arcs_cmdline + posn, argv[indx]);
-			posn += nchr;
-		}
+	for (i = 1; i < argc; i++) {
+		strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+		if (i < (argc - 1))
+			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 	}
 
 	add_memory_region(0x0, memsz, BOOT_MEM_RAM);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/ar7_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/ar7_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/ar7_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/ar7_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@ CONFIG_MIPS=y
 #
 # CONFIG_MACH_ALCHEMY is not set
 CONFIG_AR7=y
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -265,7 +264,6 @@ CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_PROBE_INITRD_HEADER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -1053,7 +1051,9 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/bcm47xx_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/bcm47xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/bcm47xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/bcm47xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 CONFIG_BCM47XX=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1853,7 +1852,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/bcm63xx_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/bcm63xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/bcm63xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/bcm63xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 CONFIG_BCM63XX=y
 # CONFIG_MIPS_COBALT is not set
@@ -942,7 +941,9 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/bigsur_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/bigsur_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/bigsur_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/bigsur_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1237,7 +1236,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_SB1XXX_CORELIS is not set
 # CONFIG_RUNTIME_DEBUG is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/capcella_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/capcella_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/capcella_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/capcella_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -783,7 +782,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/cavium-octeon_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/cavium-octeon_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/cavium-octeon_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/cavium-octeon_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -269,7 +268,6 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
-# CONFIG_PROBE_INITRD_HEADER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -822,7 +820,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/cobalt_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/cobalt_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/cobalt_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/cobalt_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 CONFIG_MIPS_COBALT=y
 # CONFIG_MACH_DECSTATION is not set
@@ -1126,7 +1125,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/db1000_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/db1000_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/db1000_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/db1000_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_DB1000=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1090,7 +1089,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/db1100_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/db1100_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/db1100_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/db1100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_DB1100=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1090,7 +1089,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/db1200_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/db1200_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/db1200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/db1200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MACH_ALCHEMY=y
 # CONFIG_MIPS_DB1550 is not set
 CONFIG_MIPS_DB1200=y
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1172,7 +1171,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="mem=48M"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/db1500_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/db1500_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/db1500_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/db1500_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_DB1500=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1390,7 +1389,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/db1550_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/db1550_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/db1550_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/db1550_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MACH_ALCHEMY=y
 CONFIG_MIPS_DB1550=y
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1207,7 +1206,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/decstation_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/decstation_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/decstation_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/decstation_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 CONFIG_MACH_DECSTATION=y
 # CONFIG_MACH_JAZZ is not set
@@ -882,7 +881,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/e55_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/e55_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/e55_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/e55_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -561,7 +560,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/excite_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/excite_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/excite_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/excite_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1335 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:31 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-CONFIG_BASLER_EXCITE=y
-# CONFIG_BASLER_EXCITE_PROTOTYPE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
-CONFIG_DMA_COHERENT=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_IRQ_CPU_RM7K=y
-CONFIG_IRQ_CPU_RM9K=y
-CONFIG_MIPS_RM9122=y
-CONFIG_SERIAL_RM9000=y
-CONFIG_GPI_RM9000=y
-CONFIG_WDT_RM9000=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-CONFIG_CPU_RM9000=y
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_RM9000=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-# CONFIG_PREEMPT_NONE is not set
-# CONFIG_PREEMPT_VOLUNTARY is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
-# CONFIG_KEXEC is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-# CONFIG_MTD_NAND_ECC_SMC is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_BASLER_EXCITE is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=m
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_PROC_FS is not set
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-CONFIG_SCSI_SAS_ATTRS=m
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_AIC94XX=m
-# CONFIG_AIC94XX_DEBUG is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=m
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_WDT_RM9K_GPI=m
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB=y
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=m
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_MON is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-CONFIG_GENERIC_ACL=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_SUMMARY is not set
-# CONFIG_JFFS2_FS_XATTR is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
-CONFIG_DLM=m
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_MANAGER=m
-# CONFIG_CRYPTO_HMAC is not set
-CONFIG_CRYPTO_XCBC=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-# CONFIG_CRYPTO_DES is not set
-CONFIG_CRYPTO_FCRYPT=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/fuloong2e_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/fuloong2e_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/fuloong2e_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/fuloong2e_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc1
-# Thu Jul  2 22:37:00 2009
+# Linux kernel version: 2.6.32-rc4
+# Fri Oct 16 13:18:01 2009
 #
 CONFIG_MIPS=y
 
@@ -10,8 +10,8 @@ CONFIG_MIPS=y
 #
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_AR7 is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -105,6 +105,8 @@ CONFIG_CPU_LOONGSON2E=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
 # CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
 CONFIG_CPU_LOONGSON2=y
 CONFIG_SYS_HAS_CPU_LOONGSON2E=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -135,12 +137,16 @@ CONFIG_SYS_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
+# CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_PHYS_ADDR_T_64BIT=y
@@ -148,6 +154,7 @@ CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -180,6 +187,12 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION="-fuloong2e"
 # CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -193,11 +206,12 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -235,18 +249,16 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -255,8 +267,8 @@ CONFIG_HAVE_SYSCALL_WRAPPERS=y
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
@@ -283,7 +295,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_FREEZER is not set
+CONFIG_FREEZER=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -321,9 +333,14 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
 # CONFIG_SUSPEND is not set
-# CONFIG_HIBERNATION is not set
+CONFIG_HIBERNATION_NVS=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/hda3"
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
@@ -442,6 +459,7 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -473,6 +491,7 @@ CONFIG_NET_CLS_ROUTE=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_WIRELESS_OLD_REGULATORY=y
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
@@ -481,7 +500,6 @@ CONFIG_WIRELESS_EXT_SYSFS=y
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 CONFIG_NET_9P=m
@@ -495,6 +513,7 @@ CONFIG_NET_9P=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
@@ -504,9 +523,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=m
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_PARTITIONS is not set
-# CONFIG_MTD_TESTS is not set
 
 #
 # User Modules And Translation Layers
@@ -820,6 +839,7 @@ CONFIG_8139TOO=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -867,10 +887,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -886,6 +903,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_CDC_PHONET is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -933,12 +951,16 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
@@ -946,6 +968,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=y
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -1015,6 +1038,7 @@ CONFIG_RTC=y
 CONFIG_DEVPORT=y
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -1070,9 +1094,6 @@ CONFIG_I2C_VIAPRO=m
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1088,7 +1109,6 @@ CONFIG_I2C_VIAPRO=m
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -1105,6 +1125,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
@@ -1114,6 +1135,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1198,6 +1220,7 @@ CONFIG_FONT_8x16=y
 # CONFIG_LOGO is not set
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1304,7 +1327,6 @@ CONFIG_SND_USB=y
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 CONFIG_HIDRAW=y
 
 #
@@ -1356,6 +1378,7 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_ISP1760_HCD=m
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1453,6 +1476,7 @@ CONFIG_UIO_CIF=m
 # CONFIG_UIO_SMX is not set
 # CONFIG_UIO_AEC is not set
 # CONFIG_UIO_SERCOS3 is not set
+# CONFIG_UIO_PCI_GENERIC is not set
 
 #
 # TI VLYNQ
@@ -1469,10 +1493,10 @@ CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_EXT4_FS=m
-CONFIG_EXT4DEV_COMPAT=y
 CONFIG_EXT4_FS_XATTR=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_FS_XIP=y
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
@@ -1489,6 +1513,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1557,7 +1582,6 @@ CONFIG_OMFS_FS=m
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
@@ -1666,6 +1690,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=2048
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1678,13 +1703,14 @@ CONFIG_NOP_TRACER=y
 CONFIG_RING_BUFFER=y
 CONFIG_EVENT_TRACING=y
 CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
 CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
@@ -1742,11 +1768,13 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/ip22_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/ip22_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/ip22_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/ip22_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1188,7 +1187,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DYNAMIC_PRINTK_DEBUG=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/ip27_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/ip27_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/ip27_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/ip27_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc2
-# Tue Aug  7 13:04:24 2007
+# Linux kernel version: 2.6.33-rc6
+# Wed Feb  3 18:12:31 2010
 #
 CONFIG_MIPS=y
 
@@ -9,21 +9,28 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_NEC_MARKEINS is not set
 # CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
+# CONFIG_SGI_IP28 is not set
 # CONFIG_SGI_IP32 is not set
 # CONFIG_SIBYTE_CRHINE is not set
 # CONFIG_SIBYTE_CARMEL is not set
@@ -34,32 +41,39 @@ CONFIG_SGI_IP27=y
 # CONFIG_SIBYTE_SENTOSA is not set
 # CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
 # CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_SGI_SN_M_MODE=y
 # CONFIG_SGI_SN_N_MODE is not set
 # CONFIG_MAPPED_KERNEL is not set
 # CONFIG_REPLICATE_KTEXT is not set
 # CONFIG_REPLICATE_EXHANDLERS is not set
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_ARC=y
 CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_DEFAULT_SGI_PARTITION=y
 CONFIG_MIPS_L1_CACHE_SHIFT=7
 CONFIG_ARC64=y
 CONFIG_BOOT_ELF64=y
@@ -67,7 +81,8 @@ CONFIG_BOOT_ELF64=y
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -80,6 +95,7 @@ CONFIG_BOOT_ELF64=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -87,6 +103,7 @@ CONFIG_CPU_R10000=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_HAS_CPU_R10000=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@@ -100,6 +117,7 @@ CONFIG_64BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
@@ -111,6 +129,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_NUMA=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_NODES_SHIFT=6
@@ -121,16 +140,22 @@ CONFIG_DISCONTIGMEM_MANUAL=y
 CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
-# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_64=y
 CONFIG_NR_CPUS=64
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
@@ -143,13 +168,13 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_BKL=y
 # CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_KEXEC is not set
 CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -163,20 +188,41 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
 CONFIG_CPUSETS=y
-CONFIG_SYSFS_DEPRECATED=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -185,44 +231,92 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_SLOW_WORK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -231,11 +325,10 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -243,8 +336,9 @@ CONFIG_MMU=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
@@ -256,13 +350,10 @@ CONFIG_BINFMT_ELF32=y
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
@@ -274,6 +365,8 @@ CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -293,19 +386,40 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -315,9 +429,11 @@ CONFIG_IP_SCTP=m
 # CONFIG_SCTP_HMAC_NONE is not set
 # CONFIG_SCTP_HMAC_SHA1 is not set
 CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -327,12 +443,9 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=y
 
 #
 # Queueing/Scheduling
@@ -341,7 +454,7 @@ CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
 CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RR=m
+CONFIG_NET_SCH_MULTIQ=y
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -349,6 +462,7 @@ CONFIG_NET_SCH_TBF=m
 CONFIG_NET_SCH_GRED=m
 CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
+# CONFIG_NET_SCH_DRR is not set
 CONFIG_NET_SCH_INGRESS=m
 
 #
@@ -365,41 +479,63 @@ CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
 # CONFIG_NET_EMATCH is not set
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_ACT_GACT=m
 CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_NAT=m
 CONFIG_NET_ACT_PEDIT=m
 # CONFIG_NET_ACT_SIMP is not set
-CONFIG_NET_CLS_POLICE=y
+CONFIG_NET_ACT_SKBEDIT=m
 # CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-CONFIG_CFG80211=m
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
 CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+CONFIG_LIB80211_CRYPT_WEP=m
+CONFIG_LIB80211_CRYPT_CCMP=m
+CONFIG_LIB80211_CRYPT_TKIP=m
+# CONFIG_LIB80211_DEBUG is not set
 CONFIG_MAC80211=m
-# CONFIG_MAC80211_DEBUG is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
 CONFIG_RFKILL=m
+CONFIG_RFKILL_LEDS=y
 # CONFIG_NET_9P is not set
 
 #
@@ -409,9 +545,13 @@ CONFIG_RFKILL=m
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -424,14 +564,19 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_OSD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
+CONFIG_EEPROM_93CX6=m
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -454,10 +599,6 @@ CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
@@ -472,11 +613,18 @@ CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_HOST_SMP=y
 # CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+CONFIG_SCSI_HPSA=m
 # CONFIG_SCSI_3W_9XXX is not set
+CONFIG_SCSI_3W_SAS=m
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -484,11 +632,21 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_AIC79XX is not set
 CONFIG_SCSI_AIC94XX=m
 # CONFIG_AIC94XX_DEBUG is not set
+CONFIG_SCSI_MVSAS=m
+# CONFIG_SCSI_MVSAS_DEBUG is not set
+CONFIG_SCSI_DPT_I2O=m
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+CONFIG_SCSI_MPT2SAS=m
+CONFIG_SCSI_MPT2SAS_MAX_SGE=128
+# CONFIG_SCSI_MPT2SAS_LOGGING is not set
 # CONFIG_SCSI_HPTIOP is not set
+CONFIG_LIBFC=m
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -503,16 +661,31 @@ CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_PMCRAID=m
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+CONFIG_SCSI_BFA_FC=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_SCSI_OSD_DPRINT_SENSE=1
+# CONFIG_SCSI_OSD_DEBUG is not set
 # CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
@@ -520,36 +693,39 @@ CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
 # CONFIG_DM_DELAY is not set
+CONFIG_DM_UEVENT=y
+# CONFIG_FUSION is not set
 
 #
-# Fusion MPT device support
+# IEEE 1394 (FireWire) support
 #
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
-# IEEE 1394 (FireWire) support
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-CONFIG_NETDEVICES_MULTIQUEUE=y
 CONFIG_IFB=m
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+CONFIG_VETH=m
 # CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
+CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
@@ -563,23 +739,51 @@ CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
 # CONFIG_BROADCOM_PHY is not set
 CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_NATIONAL_PHY=m
+CONFIG_STE10XP=m
+CONFIG_LSI_ET1011C_PHY=m
 # CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=m
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_AX88796=m
+CONFIG_AX88796_93CX6=y
 CONFIG_SGI_IOC3_ETH=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+CONFIG_SMC91X=m
 # CONFIG_DM9000 is not set
+CONFIG_ETHOC=m
+CONFIG_SMSC911X=m
+CONFIG_DNET=m
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
+CONFIG_B44=m
+CONFIG_B44_PCI_AUTOSELECT=y
+CONFIG_B44_PCICORE_AUTOSELECT=y
+CONFIG_B44_PCI=y
+CONFIG_KS8842=m
+CONFIG_KS8851_MLL=m
+CONFIG_ATL2=m
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+CONFIG_E1000E=m
+CONFIG_IP1000=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -589,24 +793,75 @@ CONFIG_NETDEV_1000=y
 # CONFIG_SKY2 is not set
 CONFIG_VIA_VELOCITY=m
 # CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
+CONFIG_BNX2=m
+CONFIG_CNIC=m
 CONFIG_QLA3XXX=m
 # CONFIG_ATL1 is not set
+CONFIG_ATL1E=m
+CONFIG_ATL1C=m
+CONFIG_JME=m
 CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+CONFIG_ENIC=m
+CONFIG_IXGBE=m
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+CONFIG_VXGE=m
+# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
 # CONFIG_MYRI10GE is not set
 CONFIG_NETXEN_NIC=m
-# CONFIG_MLX4_CORE is not set
+CONFIG_NIU=m
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
+# CONFIG_MLX4_DEBUG is not set
+CONFIG_TEHUTI=m
+CONFIG_BNX2X=m
+CONFIG_QLGE=m
+CONFIG_SFC=m
+CONFIG_BE2NET=m
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
+CONFIG_WLAN=y
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+CONFIG_PRISM54=m
+CONFIG_RTL8180=m
+CONFIG_ADM8211=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_MWL8K=m
+CONFIG_ATH_COMMON=m
+# CONFIG_ATH_DEBUG is not set
+CONFIG_ATH5K=m
+# CONFIG_ATH5K_DEBUG is not set
+CONFIG_ATH9K_HW=m
+CONFIG_ATH9K_COMMON=m
+CONFIG_ATH9K=m
+CONFIG_B43=m
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+CONFIG_B43_PHY_LP=y
+CONFIG_B43_LEDS=y
+CONFIG_B43_HWRNG=y
+# CONFIG_B43_DEBUG is not set
+CONFIG_B43LEGACY=m
+CONFIG_B43LEGACY_PCI_AUTOSELECT=y
+CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
+CONFIG_B43LEGACY_LEDS=y
+CONFIG_B43LEGACY_HWRNG=y
+# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_B43LEGACY_DMA=y
+CONFIG_B43LEGACY_PIO=y
+CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
+# CONFIG_B43LEGACY_DMA_MODE is not set
+# CONFIG_B43LEGACY_PIO_MODE is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_IPW2100_DEBUG=y
@@ -616,38 +871,57 @@ CONFIG_IPW2200_RADIOTAP=y
 CONFIG_IPW2200_PROMISCUOUS=y
 CONFIG_IPW2200_QOS=y
 CONFIG_IPW2200_DEBUG=y
+CONFIG_LIBIPW=m
+# CONFIG_LIBIPW_DEBUG is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
+# CONFIG_IWLWIFI_DEBUG is not set
+CONFIG_IWLAGN=m
+CONFIG_IWL4965=y
+CONFIG_IWL5000=y
+CONFIG_IWL3945=m
+CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
 CONFIG_LIBERTAS=m
 # CONFIG_LIBERTAS_DEBUG is not set
 CONFIG_HERMES=m
+# CONFIG_HERMES_CACHE_FW_ON_INIT is not set
 CONFIG_PLX_HERMES=m
 CONFIG_TMD_HERMES=m
 CONFIG_NORTEL_HERMES=m
 CONFIG_PCI_HERMES=m
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
-CONFIG_PRISM54=m
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-CONFIG_HOSTAP_PLX=m
-CONFIG_HOSTAP_PCI=m
-CONFIG_BCM43XX=m
-CONFIG_BCM43XX_DEBUG=y
-CONFIG_BCM43XX_DMA=y
-CONFIG_BCM43XX_PIO=y
-CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
-# CONFIG_BCM43XX_DMA_MODE is not set
-# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_P54_COMMON=m
+CONFIG_P54_PCI=m
+CONFIG_P54_LEDS=y
+CONFIG_RT2X00=m
+CONFIG_RT2400PCI=m
+CONFIG_RT2500PCI=m
+CONFIG_RT61PCI=m
+CONFIG_RT2800PCI_PCI=m
+CONFIG_RT2800PCI=m
+CONFIG_RT2800_LIB=m
+CONFIG_RT2X00_LIB_PCI=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_HT=y
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+# CONFIG_RT2X00_DEBUG is not set
+CONFIG_WL12XX=m
+CONFIG_WL1251=m
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -665,13 +939,16 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=m
 CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_NOZOMI=m
 
 #
 # Serial drivers
@@ -694,95 +971,258 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=m
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM_TIMERIOMEM=m
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCA=m
 
 #
-# SPI support
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
 #
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_ISCH=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_SIMTEC=m
+
+#
+# External I2C/SMBus adapter drivers
+#
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_STUB=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_TSL2550=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+
+#
+# PPS support
+#
+CONFIG_PPS=m
+# CONFIG_PPS_DEBUG is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+CONFIG_THERMAL=m
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
-# Multifunction device drivers
+# Sonics Silicon Backplane
 #
-# CONFIG_MFD_SM501 is not set
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+CONFIG_SSB_B43_PCI_BRIDGE=y
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_DRIVER_MIPS is not set
 
 #
-# Multimedia devices
+# Multifunction device drivers
 #
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_WM8400 is not set
+CONFIG_MFD_WM8350=m
+CONFIG_MFD_WM8350_I2C=m
+CONFIG_MFD_PCF50633=m
+CONFIG_PCF50633_ADC=m
+CONFIG_PCF50633_GPIO=m
+CONFIG_AB3100_CORE=m
+CONFIG_AB3100_OTP=m
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Sound
+# Display device support
 #
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_WM8350=m
+CONFIG_LEDS_BD2802=m
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
-# CONFIG_DMA_ENGINE is not set
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# DMA Clients
+# I2C RTC drivers
 #
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
-# DMA Devices
+# SPI RTC drivers
 #
 
 #
-# Userspace I/O
+# Platform RTC drivers
 #
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_M48T35=y
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_WM8350 is not set
+# CONFIG_RTC_DRV_PCF50633 is not set
+CONFIG_RTC_DRV_AB3100=m
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_CIF is not set
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+CONFIG_UIO_SMX=m
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -793,36 +1233,58 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_JBD=y
-CONFIG_JBD_DEBUG=y
+CONFIG_JBD2=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
+CONFIG_QUOTA_NETLINK_INTERFACE=y
 CONFIG_QUOTACTL=y
-CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_GENERIC_ACL=y
 
 #
+# Caches
+#
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -841,16 +1303,13 @@ CONFIG_GENERIC_ACL=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -860,28 +1319,32 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_OMFS_FS=m
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_EXOFS_FS=m
+# CONFIG_EXOFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 # CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -911,36 +1374,38 @@ CONFIG_SGI_PARTITION=y
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 CONFIG_DLM=m
 # CONFIG_DLM_DEBUG is not set
 
 #
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
@@ -948,65 +1413,140 @@ CONFIG_CMDLINE=""
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-CONFIG_XOR_BLOCKS=m
-CONFIG_ASYNC_CORE=m
-CONFIG_ASYNC_MEMCPY=m
-CONFIG_ASYNC_XOR=m
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ABLKCIPHER=m
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=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_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
 CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+# CONFIG_CRYPTO_DEV_HIFN_795X_RNG is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/ip28_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/ip28_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/ip28_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/ip28_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -816,7 +815,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/ip32_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/ip32_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/ip32_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/ip32_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1126,7 +1125,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/jazz_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/jazz_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/jazz_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/jazz_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 CONFIG_MACH_JAZZ=y
@@ -1374,7 +1373,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/jmr3927_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/jmr3927_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/jmr3927_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/jmr3927_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -835,7 +834,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/lasat_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/lasat_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/lasat_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/lasat_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -798,7 +797,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/lemote2f_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/lemote2f_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/lemote2f_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/lemote2f_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1835 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc6
+# Mon Nov  9 23:42:42 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+CONFIG_MACH_LOONGSON=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+# CONFIG_LEMOTE_FULOONG2E is not set
+CONFIG_LEMOTE_MACH2F=y
+CONFIG_CS5536=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2E is not set
+CONFIG_CPU_LOONGSON2F=y
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
+CONFIG_CPU_LOONGSON2=y
+CONFIG_SYS_HAS_CPU_LOONGSON2F=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
+# CONFIG_PAGE_SIZE_4KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATION_NVS=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/hda3"
+# CONFIG_PM_RUNTIME is not set
+CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
+# CONFIG_TCP_CONG_LP is not set
+# CONFIG_TCP_CONG_VENO is not set
+# CONFIG_TCP_CONG_YEAH is not set
+# CONFIG_TCP_CONG_ILLINOIS is not set
+CONFIG_DEFAULT_BIC=y
+# CONFIG_DEFAULT_CUBIC is not set
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="bic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+# CONFIG_NET_SCH_INGRESS is not set
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+# CONFIG_NET_EMATCH_CMP is not set
+# CONFIG_NET_EMATCH_NBYTE is not set
+# CONFIG_NET_EMATCH_U32 is not set
+# CONFIG_NET_EMATCH_META is not set
+# CONFIG_NET_EMATCH_TEXT is not set
+CONFIG_NET_CLS_ACT=y
+# CONFIG_NET_ACT_POLICE is not set
+# CONFIG_NET_ACT_GACT is not set
+# CONFIG_NET_ACT_MIRRED is not set
+# CONFIG_NET_ACT_NAT is not set
+# CONFIG_NET_ACT_PEDIT is not set
+# CONFIG_NET_ACT_SIMP is not set
+# CONFIG_NET_ACT_SKBEDIT is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=m
+# CONFIG_RFKILL_INPUT is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+
+#
+# Other IDE chipsets support
+#
+
+#
+# Note: most of these also require special kernel boot parameters
+#
+# CONFIG_BLK_DEV_4DRIVES is not set
+# CONFIG_BLK_DEV_ALI14XX is not set
+# CONFIG_BLK_DEV_DTC2278 is not set
+# CONFIG_BLK_DEV_HT6560B is not set
+# CONFIG_BLK_DEV_QD65XX is not set
+# CONFIG_BLK_DEV_UMC8672 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TC35815 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_8139TOO_TUNE_TWISTER=y
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+CONFIG_WLAN_PRE80211=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+# CONFIG_MOUSE_PS2_TRACKPOINT is not set
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_STALDRV is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_FOURPORT=y
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=m
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_STRADIS is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+CONFIG_VGA_ARB=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+CONFIG_FB_BOOT_VESA_SUPPORT=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+CONFIG_FB_SIS=y
+CONFIG_FB_SIS_300=y
+CONFIG_FB_SIS_315=y
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_7x14=y
+CONFIG_FONT_PEARL_8x8=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+CONFIG_FONT_10x18=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_RTCTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+CONFIG_SND_CS5535AUDIO=m
+# CONFIG_SND_CTXFI is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LX6464ES is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+CONFIG_USB_OTG_WHITELIST=y
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+# CONFIG_USB_PRINTER is not set
+CONFIG_USB_WDM=m
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ET131X is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_ALTERA_PCIE_CHDMA is not set
+# CONFIG_RTL8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192E is not set
+# CONFIG_INPUT_MIMIO is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_DST is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_B3DFG is not set
+# CONFIG_PLAN9AUTH is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_USB_SERIAL_QUATECH2 is not set
+# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_VME_BUS is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+CONFIG_FB_SM7XX=y
+CONFIG_FB_SM7XX_ACCEL=y
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf-8"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/malta_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/malta_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/malta_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/malta_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@ CONFIG_MIPS=y
 #
 CONFIG_ZONE_DMA=y
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1591,7 +1590,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/markeins_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/markeins_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/markeins_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/markeins_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1366,7 +1365,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/mipssim_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/mipssim_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/mipssim_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/mipssim_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -635,7 +634,9 @@ CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
+# CONFIG_CMDLINE_OVERRIDE is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/mpc30x_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/mpc30x_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/mpc30x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/mpc30x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -817,7 +816,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/msp71xx_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/msp71xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/msp71xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/msp71xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1412,7 +1411,7 @@ CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/mtx1_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/mtx1_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/mtx1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/mtx1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 CONFIG_MACH_ALCHEMY=y
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -3018,7 +3017,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pb1100_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pb1100_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pb1100_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pb1100_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_PB1100=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1083,7 +1082,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pb1500_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pb1500_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pb1500_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pb1500_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_PB1500=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1200,7 +1199,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pb1550_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pb1550_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pb1550_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pb1550_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@ CONFIG_MIPS_PB1550=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1193,7 +1192,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8335-stb225_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8335-stb225_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8335-stb225_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8335-stb225_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1034,7 +1033,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_KERNEL_TESTS is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8550-jbs_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8550-jbs_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8550-jbs_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8550-jbs_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1215,7 +1214,9 @@ CONFIG_DEBUG_MUTEXES=y
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp"
+# CONFIG_CMDLINE_OVERRIDE is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8550-stb810_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8550-stb810_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/pnx8550-stb810_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/pnx8550-stb810_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1205,7 +1204,9 @@ CONFIG_DEBUG_SLAB=y
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp"
+# CONFIG_CMDLINE_OVERRIDE is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/powertv_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/powertv_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/powertv_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/powertv_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1550 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc5
+# Fri Aug 28 14:49:33 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+CONFIG_POWERTV=y
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+# CONFIG_MIN_RUNTIME_RESOURCES is not set
+# CONFIG_BOOTLOADER_DRIVER is not set
+CONFIG_BOOTLOADER_FAMILY="R2"
+CONFIG_CSRC_POWERTV=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_HIGHMEM is not set
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+CONFIG_HZ_1000=y
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=1000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+CONFIG_TIMERFD=y
+# CONFIG_EVENTFD is not set
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_PROBE_INITRD_HEADER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# 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_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_TUNNEL=y
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+# CONFIG_BRIDGE_NETFILTER is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+# CONFIG_IP6_NF_TARGET_LOG is not set
+CONFIG_IP6_NF_FILTER=y
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+# CONFIG_IP6_NF_MANGLE is not set
+# CONFIG_IP6_NF_RAW is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+CONFIG_NET_SCH_TBF=y
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_RTL8150=y
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+CONFIG_USB_SERIAL_CP210X=y
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M"
+# CONFIG_CMDLINE_OVERRIDE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/rb532_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/rb532_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/rb532_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/rb532_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1204,7 +1203,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/rbtx49xx_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/rbtx49xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/rbtx49xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/rbtx49xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@ CONFIG_MIPS=y
 #
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_AR7 is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
@@ -284,7 +283,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_PROBE_INITRD_HEADER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -1063,7 +1061,7 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/rm200_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/rm200_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/rm200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/rm200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -1694,7 +1693,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/sb1250-swarm_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/sb1250-swarm_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/sb1250-swarm_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/sb1250-swarm_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -961,7 +960,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_SB1XXX_CORELIS is not set
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/tb0219_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/tb0219_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/tb0219_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/tb0219_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -892,7 +891,9 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/tb0226_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/tb0226_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/tb0226_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/tb0226_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -895,7 +894,9 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="cca=3 mem=32M console=ttyVR0,115200"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/tb0287_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/tb0287_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/tb0287_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/tb0287_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
@@ -1077,7 +1076,9 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SAMPLES is not set
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/workpad_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/workpad_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/workpad_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/workpad_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -755,7 +754,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/wrppmc_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/wrppmc_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/wrppmc_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/wrppmc_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -887,7 +886,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
+# CONFIG_CMDLINE_OVERRIDE is not set
 
 #
 # Security options
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/configs/yosemite_defconfig linux-libre-2.6.33-gnu1/arch/mips/configs/yosemite_defconfig
--- linux-libre-2.6.32-gnu1/arch/mips/configs/yosemite_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/configs/yosemite_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@ CONFIG_ZONE_DMA=y
 # CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_DB1200 is not set
 # CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -824,7 +823,7 @@ CONFIG_DEBUG_MUTEXES=y
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/fw/arc/cmdline.c linux-libre-2.6.33-gnu1/arch/mips/fw/arc/cmdline.c
--- linux-libre-2.6.32-gnu1/arch/mips/fw/arc/cmdline.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/fw/arc/cmdline.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,11 +16,6 @@
 
 #undef DEBUG_CMDLINE
 
-char * __init prom_getcmdline(void)
-{
-	return arcs_cmdline;
-}
-
 static char *ignored[] = {
 	"ConsoleIn=",
 	"ConsoleOut=",
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/bootinfo.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/bootinfo.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/bootinfo.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/bootinfo.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,9 +67,9 @@
 #define MACH_LEMOTE_ML2F7      3
 #define MACH_LEMOTE_YL2F89     4
 #define MACH_DEXXON_GDIUM2F10  5
-#define MACH_LOONGSON_END      6
-
-#define CL_SIZE			COMMAND_LINE_SIZE
+#define MACH_LEMOTE_NAS        6
+#define MACH_LEMOTE_LL2F       7
+#define MACH_LOONGSON_END      8
 
 extern char *system_type;
 const char *get_system_type(void);
@@ -107,7 +107,7 @@ extern void free_init_pages(const char *
 /*
  * Initial kernel command line, usually setup by prom_init()
  */
-extern char arcs_cmdline[CL_SIZE];
+extern char arcs_cmdline[COMMAND_LINE_SIZE];
 
 /*
  * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,9 +11,7 @@
 static inline void __noreturn BUG(void)
 {
 	__asm__ __volatile__("break %0" : : "i" (BRK_BUG));
-	/* Fool GCC into thinking the function doesn't return. */
-	while (1)
-		;
+	unreachable();
 }
 
 #define HAVE_ARCH_BUG
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,7 @@ extern void (*flush_cache_range)(struct
 extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
 extern void __flush_dcache_page(struct page *page);
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 static inline void flush_dcache_page(struct page *page)
 {
 	if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/clock.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/clock.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,64 @@
+#ifndef __ASM_MIPS_CLOCK_H
+#define __ASM_MIPS_CLOCK_H
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include <linux/clk.h>
+
+extern void (*cpu_wait) (void);
+
+struct clk;
+
+struct clk_ops {
+	void (*init) (struct clk *clk);
+	void (*enable) (struct clk *clk);
+	void (*disable) (struct clk *clk);
+	void (*recalc) (struct clk *clk);
+	int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id);
+	long (*round_rate) (struct clk *clk, unsigned long rate);
+};
+
+struct clk {
+	struct list_head node;
+	const char *name;
+	int id;
+	struct module *owner;
+
+	struct clk *parent;
+	struct clk_ops *ops;
+
+	struct kref kref;
+
+	unsigned long rate;
+	unsigned long flags;
+};
+
+#define CLK_ALWAYS_ENABLED	(1 << 0)
+#define CLK_RATE_PROPAGATES	(1 << 1)
+
+/* Should be defined by processor-specific code */
+void arch_init_clk_ops(struct clk_ops **, int type);
+
+int clk_init(void);
+
+int __clk_enable(struct clk *);
+void __clk_disable(struct clk *);
+
+void clk_recalc_rate(struct clk *);
+
+int clk_register(struct clk *);
+void clk_unregister(struct clk *);
+
+/* the exported API, in addition to clk_set_rate */
+/**
+ * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ * @algo_id: algorithm id to be passed down to ops->set_rate
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
+
+#endif				/* __ASM_MIPS_CLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/cop2.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/cop2.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/cop2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/cop2.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,23 @@
+/*
+ * 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) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_COP2_H
+#define __ASM_COP2_H
+
+enum cu2_ops {
+	CU2_EXCEPTION,
+	CU2_LWC2_OP,
+	CU2_LDC2_OP,
+	CU2_SWC2_OP,
+	CU2_SDC2_OP,
+};
+
+extern int register_cu2_notifier(struct notifier_block *nb);
+extern int cu2_notifier_call_chain(unsigned long val, void *v);
+
+#endif /* __ASM_COP2_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu-features.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-features.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu-features.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-features.h	2010-02-24 13:52:17.000000000 -0500
@@ -191,6 +191,9 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	0
 # endif
+# ifndef cpu_vmbits
+# define cpu_vmbits 31
+# endif
 #endif
 
 #ifdef CONFIG_64BIT
@@ -209,6 +212,10 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	1
 # endif
+# ifndef cpu_vmbits
+# define cpu_vmbits cpu_data[0].vmbits
+# define __NEED_VMBITS_PROBE
+# endif
 #endif
 
 #if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -154,6 +154,8 @@
 #define PRID_REV_VR4181A	0x0070	/* Same as VR4122 */
 #define PRID_REV_VR4130		0x0080
 #define PRID_REV_34K_V1_0_2	0x0022
+#define PRID_REV_LOONGSON2E	0x0002
+#define PRID_REV_LOONGSON2F	0x0003
 
 /*
  * Older processors used to encode processor version and revision in two
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu-info.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-info.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/cpu-info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/cpu-info.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,6 +58,9 @@ struct cpuinfo_mips {
 	struct cache_desc	tcache;	/* Tertiary/split secondary cache */
 	int			srsets;	/* Shadow register sets */
 	int			core;	/* physical core number */
+#ifdef CONFIG_64BIT
+	int			vmbits;	/* Virtual memory size in bits */
+#endif
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
 	/*
 	 * In the MIPS MT "SMTC" model, each TC is considered
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -326,7 +326,6 @@ extern int dump_task_fpu(struct task_str
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)			\
 	dump_task_fpu(tsk, elf_fpregs)
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /* This yields a mask that user programs can use to figure out what
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/fcntl.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/fcntl.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/fcntl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/fcntl.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
 
 
 #define O_APPEND	0x0008
-#define O_SYNC		0x0010
+#define O_DSYNC		0x0010	/* used to be O_SYNC, see below */
 #define O_NONBLOCK	0x0080
 #define O_CREAT         0x0100	/* not fcntl */
 #define O_TRUNC		0x0200	/* not fcntl */
@@ -18,6 +18,21 @@
 #define O_NOCTTY	0x0800	/* not fcntl */
 #define FASYNC		0x1000	/* fcntl, for BSD compatibility */
 #define O_LARGEFILE	0x2000	/* allow large file opens */
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	0x4000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 #define O_DIRECT	0x8000	/* direct disk access hint */
 
 #define F_GETLK		14
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/fpu_emulator.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu_emulator.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/fpu_emulator.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu_emulator.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,17 +25,27 @@
 
 #include <asm/break.h>
 #include <asm/inst.h>
+#include <asm/local.h>
+
+#ifdef CONFIG_DEBUG_FS
 
 struct mips_fpu_emulator_stats {
-	unsigned int emulated;
-	unsigned int loads;
-	unsigned int stores;
-	unsigned int cp1ops;
-	unsigned int cp1xops;
-	unsigned int errors;
+	local_t emulated;
+	local_t loads;
+	local_t stores;
+	local_t cp1ops;
+	local_t cp1xops;
+	local_t errors;
 };
 
-extern struct mips_fpu_emulator_stats fpuemustats;
+DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+
+#define MIPS_FPU_EMU_INC_STATS(M)					\
+	cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+
+#else
+#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
+#endif /* CONFIG_DEBUG_FS */
 
 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
 	unsigned long cpc);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/fpu.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/fpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/fpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,15 +28,7 @@
 struct sigcontext;
 struct sigcontext32;
 
-extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
-extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
-
-extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
-extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
-
 extern void fpu_emulator_init_fpu(void);
-extern int fpu_emulator_save_context(struct sigcontext __user *sc);
-extern int fpu_emulator_restore_context(struct sigcontext __user *sc);
 extern void _init_fpu(void);
 extern void _save_fp(struct task_struct *);
 extern void _restore_fp(struct task_struct *);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/ftrace.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/ftrace.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/ftrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -1 +1,90 @@
-/* empty */
+/*
+ * 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) 2009 DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ */
+
+#ifndef _ASM_MIPS_FTRACE_H
+#define _ASM_MIPS_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+#define MCOUNT_INSN_SIZE 4		/* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void _mcount(void);
+#define mcount _mcount
+
+#define safe_load(load, src, dst, error)		\
+do {							\
+	asm volatile (					\
+		"1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\
+		"   li %[" STR(error) "], 0\n"		\
+		"2:\n"					\
+							\
+		".section .fixup, \"ax\"\n"		\
+		"3: li %[" STR(error) "], 1\n"		\
+		"   j 2b\n"				\
+		".previous\n"				\
+							\
+		".section\t__ex_table,\"a\"\n\t"	\
+		STR(PTR) "\t1b, 3b\n\t"			\
+		".previous\n"				\
+							\
+		: [dst] "=&r" (dst), [error] "=r" (error)\
+		: [src] "r" (src)			\
+		: "memory"				\
+	);						\
+} while (0)
+
+#define safe_store(store, src, dst, error)	\
+do {						\
+	asm volatile (				\
+		"1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\
+		"   li %[" STR(error) "], 0\n"	\
+		"2:\n"				\
+						\
+		".section .fixup, \"ax\"\n"	\
+		"3: li %[" STR(error) "], 1\n"	\
+		"   j 2b\n"			\
+		".previous\n"			\
+						\
+		".section\t__ex_table,\"a\"\n\t"\
+		STR(PTR) "\t1b, 3b\n\t"		\
+		".previous\n"			\
+						\
+		: [error] "=r" (error)		\
+		: [dst] "r" (dst), [src] "r" (src)\
+		: "memory"			\
+	);					\
+} while (0)
+
+#define safe_load_code(dst, src, error) \
+	safe_load(STR(lw), src, dst, error)
+#define safe_store_code(src, dst, error) \
+	safe_store(STR(sw), src, dst, error)
+
+#define safe_load_stack(dst, src, error) \
+	safe_load(STR(PTR_L), src, dst, error)
+
+#define safe_store_stack(src, dst, error) \
+	safe_store(STR(PTR_S), src, dst, error)
+
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+	return addr;
+}
+
+struct dyn_arch_ftrace {
+};
+
+#endif /*  CONFIG_DYNAMIC_FTRACE */
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_FUNCTION_TRACER */
+#endif /* _ASM_MIPS_FTRACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/irq.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/irq.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -113,36 +113,11 @@ do {									\
 
 #endif
 
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- *
- * Ideally there should be away to get this into kernel/irq/handle.c to
- * avoid the overhead of a call for just a tiny function ...
- */
-#define do_IRQ(irq)							\
-do {									\
-	irq_enter();							\
-	__DO_IRQ_SMTC_HOOK(irq);					\
-	generic_handle_irq(irq);					\
-	irq_exit();							\
-} while (0)
+extern void do_IRQ(unsigned int irq);
 
 #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
-/*
- * To avoid inefficient and in some cases pathological re-checking of
- * IRQ affinity, we have this variant that skips the affinity check.
- */
-
 
-#define do_IRQ_no_affinity(irq)						\
-do {									\
-	irq_enter();							\
-	__NO_AFFINITY_IRQ_SMTC_HOOK(irq);				\
-	generic_handle_irq(irq);					\
-	irq_exit();							\
-} while (0)
+extern void do_IRQ_no_affinity(unsigned int irq);
 
 #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
 
@@ -160,6 +135,7 @@ extern void free_irqno(unsigned int irq)
 #define CP0_LEGACY_COMPARE_IRQ 7
 
 extern int cp0_compare_irq;
+extern int cp0_compare_irq_shift;
 extern int cp0_perfcount_irq;
 
 #endif /* _ASM_IRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2010-02-24 13:52:17.000000000 -0500
@@ -305,6 +305,7 @@ typedef struct dbdma_chan_config {
 	dbdev_tab_t		*chan_dest;
 	au1x_dma_chan_t		*chan_ptr;
 	au1x_ddma_desc_t	*chan_desc_base;
+	u32			cdb_membase; /* kmalloc base of above */
 	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
 	void			*chan_callparam;
 	void			(*chan_callback)(int, void *);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/cpu-feature-overrides.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +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 Thomas Koeller <thomas.koeller@baslerweb.com>
- * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
- */
-#ifndef __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H
-
-/*
- * Basler eXcite has an RM9122 processor.
- */
-#define cpu_has_watch		1
-#define cpu_has_mips16		0
-#define cpu_has_divec		0
-#define cpu_has_vce		0
-#define cpu_has_cache_cdex_p	0
-#define cpu_has_cache_cdex_s	0
-#define cpu_has_prefetch	1
-#define cpu_has_mcheck		0
-#define cpu_has_ejtag		0
-
-#define cpu_has_llsc		1
-#define cpu_has_vtag_icache	0
-#define cpu_has_dc_aliases	0
-#define cpu_has_ic_fills_f_dc	0
-#define cpu_has_dsp		0
-#define cpu_icache_snoops_remote_store	0
-#define cpu_has_mipsmt		0
-#define cpu_has_userlocal	0
-
-#define cpu_has_nofpuex		0
-#define cpu_has_64bits		1
-
-#define cpu_has_mips32r1	0
-#define cpu_has_mips32r2	0
-#define cpu_has_mips64r1	0
-#define cpu_has_mips64r2	0
-
-#define cpu_has_inclusive_pcaches	0
-
-#define cpu_dcache_line_size()	32
-#define cpu_icache_line_size()	32
-#define cpu_scache_line_size()	32
-
-#endif /* __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite_fpga.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite_fpga.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite_fpga.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite_fpga.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-#ifndef EXCITE_FPGA_H_INCLUDED
-#define EXCITE_FPGA_H_INCLUDED
-
-
-/**
- * Address alignment of the individual FPGA bytes.
- * The address arrangement of the individual bytes of the FPGA is two
- * byte aligned at the embedded MK2 platform.
- */
-#ifdef EXCITE_CCI_FPGA_MK2
-typedef unsigned char excite_cci_fpga_align_t __attribute__ ((aligned(2)));
-#else
-typedef unsigned char excite_cci_fpga_align_t;
-#endif
-
-
-/**
- * Size of Dual Ported RAM.
- */
-#define EXCITE_DPR_SIZE 263
-
-
-/**
- * Size of Reserved Status Fields in Dual Ported RAM.
- */
-#define EXCITE_DPR_STATUS_SIZE 7
-
-
-
-/**
- * FPGA.
- * Hardware register layout of the FPGA interface. The FPGA must accessed
- * byte wise solely.
- * @see EXCITE_CCI_DPR_MK2
- */
-typedef struct excite_fpga {
-
-	/**
-	 * Dual Ported RAM.
-	 */
-	excite_cci_fpga_align_t dpr[EXCITE_DPR_SIZE];
-
-	/**
-	 * Status.
-	 */
-	excite_cci_fpga_align_t status[EXCITE_DPR_STATUS_SIZE];
-
-#ifdef EXCITE_CCI_FPGA_MK2
-	/**
-	 * RM9000 Interrupt.
-	 * Write access initiates interrupt at the RM9000 (MIPS) processor of the eXcite.
-	 */
-	excite_cci_fpga_align_t rm9k_int;
-#else
-	/**
-	 * MK2 Interrupt.
-	 * Write access initiates interrupt at the ARM processor of the MK2.
-	 */
-	excite_cci_fpga_align_t mk2_int;
-
-	excite_cci_fpga_align_t gap[0x1000-0x10f];
-
-	/**
-	 * IRQ Source/Acknowledge.
-	 */
-	excite_cci_fpga_align_t rm9k_irq_src;
-
-	/**
-	 * IRQ Mask.
-	 * Set bits enable the related interrupt.
-	 */
-	excite_cci_fpga_align_t rm9k_irq_mask;
-#endif
-
-
-} excite_fpga;
-
-
-
-#endif	/* ndef EXCITE_FPGA_H_INCLUDED */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,154 +0,0 @@
-#ifndef __EXCITE_H__
-#define __EXCITE_H__
-
-#include <linux/init.h>
-#include <asm/addrspace.h>
-#include <asm/types.h>
-
-#define EXCITE_CPU_EXT_CLOCK 100000000
-
-#if !defined(__ASSEMBLY__)
-void __init excite_kgdb_init(void);
-void excite_procfs_init(void);
-extern unsigned long memsize;
-extern char modetty[];
-extern u32 unit_id;
-#endif
-
-/* Base name for XICAP devices */
-#define XICAP_NAME	"xicap_gpi"
-
-/* OCD register offsets */
-#define LKB0		0x0038
-#define LKB5		0x0128
-#define LKM5		0x012C
-#define LKB7		0x0138
-#define LKM7		0x013c
-#define LKB8		0x0140
-#define LKM8		0x0144
-#define LKB9		0x0148
-#define LKM9		0x014c
-#define LKB10		0x0150
-#define LKM10		0x0154
-#define LKB11		0x0158
-#define LKM11		0x015c
-#define LKB12		0x0160
-#define LKM12		0x0164
-#define LKB13		0x0168
-#define LKM13		0x016c
-#define LDP0		0x0200
-#define LDP1		0x0210
-#define LDP2		0x0220
-#define LDP3		0x0230
-#define INTPIN0		0x0A40
-#define INTPIN1		0x0A44
-#define INTPIN2		0x0A48
-#define INTPIN3		0x0A4C
-#define INTPIN4		0x0A50
-#define INTPIN5		0x0A54
-#define INTPIN6		0x0A58
-#define INTPIN7		0x0A5C
-
-
-
-
-/* TITAN register offsets */
-#define CPRR		0x0004
-#define CPDSR		0x0008
-#define CPTC0R		0x000c
-#define CPTC1R		0x0010
-#define CPCFG0		0x0020
-#define CPCFG1		0x0024
-#define CPDST0A		0x0028
-#define CPDST0B		0x002c
-#define CPDST1A		0x0030
-#define CPDST1B		0x0034
-#define CPXDSTA		0x0038
-#define CPXDSTB		0x003c
-#define CPXCISRA	0x0048
-#define CPXCISRB	0x004c
-#define CPGIG0ER	0x0050
-#define CPGIG1ER	0x0054
-#define CPGRWL		0x0068
-#define CPURSLMT	0x00f8
-#define UACFG		0x0200
-#define UAINTS		0x0204
-#define SDRXFCIE	0x4828
-#define SDTXFCIE	0x4928
-#define INTP0Status0	0x1B00
-#define INTP0Mask0	0x1B04
-#define INTP0Set0	0x1B08
-#define INTP0Clear0	0x1B0C
-#define GXCFG		0x5000
-#define GXDMADRPFX	0x5018
-#define GXDMA_DESCADR	0x501c
-#define GXCH0TDESSTRT	0x5054
-
-/* IRQ definitions */
-#define NMICONFIG		0xac0
-#define TITAN_MSGINT	0xc4
-#define TITAN_IRQ	((TITAN_MSGINT / 0x20) + 2)
-#define FPGA0_MSGINT	0x5a
-#define FPGA0_IRQ	((FPGA0_MSGINT / 0x20) + 2)
-#define FPGA1_MSGINT	0x7b
-#define FPGA1_IRQ	((FPGA1_MSGINT / 0x20) + 2)
-#define PHY_MSGINT	0x9c
-#define PHY_IRQ		((PHY_MSGINT   / 0x20) + 2)
-
-#if defined(CONFIG_BASLER_EXCITE_PROTOTYPE)
-/* Pre-release units used interrupt pin #9 */
-#define USB_IRQ		11
-#else
-/* Re-designed units use interrupt pin #1 */
-#define USB_MSGINT	0x39
-#define USB_IRQ		((USB_MSGINT / 0x20) + 2)
-#endif
-#define TIMER_IRQ	12
-
-
-/* Device address ranges */
-#define EXCITE_OFFS_OCD		0x1fffc000
-#define	EXCITE_SIZE_OCD		(16 * 1024)
-#define EXCITE_PHYS_OCD		CPHYSADDR(EXCITE_OFFS_OCD)
-#define EXCITE_ADDR_OCD		CKSEG1ADDR(EXCITE_OFFS_OCD)
-
-#define EXCITE_OFFS_SCRAM 	0x1fffa000
-#define	EXCITE_SIZE_SCRAM	(8 << 10)
-#define EXCITE_PHYS_SCRAM 	CPHYSADDR(EXCITE_OFFS_SCRAM)
-#define EXCITE_ADDR_SCRAM 	CKSEG1ADDR(EXCITE_OFFS_SCRAM)
-
-#define EXCITE_OFFS_PCI_IO	0x1fff8000
-#define	EXCITE_SIZE_PCI_IO	(8 << 10)
-#define EXCITE_PHYS_PCI_IO	CPHYSADDR(EXCITE_OFFS_PCI_IO)
-#define EXCITE_ADDR_PCI_IO 	CKSEG1ADDR(EXCITE_OFFS_PCI_IO)
-
-#define EXCITE_OFFS_TITAN	0x1fff0000
-#define EXCITE_SIZE_TITAN	(32 << 10)
-#define EXCITE_PHYS_TITAN	CPHYSADDR(EXCITE_OFFS_TITAN)
-#define EXCITE_ADDR_TITAN	CKSEG1ADDR(EXCITE_OFFS_TITAN)
-
-#define EXCITE_OFFS_PCI_MEM	0x1ffe0000
-#define EXCITE_SIZE_PCI_MEM	(64 << 10)
-#define EXCITE_PHYS_PCI_MEM	CPHYSADDR(EXCITE_OFFS_PCI_MEM)
-#define EXCITE_ADDR_PCI_MEM	CKSEG1ADDR(EXCITE_OFFS_PCI_MEM)
-
-#define EXCITE_OFFS_FPGA	0x1ffdc000
-#define EXCITE_SIZE_FPGA	(16 << 10)
-#define EXCITE_PHYS_FPGA	CPHYSADDR(EXCITE_OFFS_FPGA)
-#define EXCITE_ADDR_FPGA	CKSEG1ADDR(EXCITE_OFFS_FPGA)
-
-#define EXCITE_OFFS_NAND	0x1ffd8000
-#define EXCITE_SIZE_NAND	(16 << 10)
-#define EXCITE_PHYS_NAND	CPHYSADDR(EXCITE_OFFS_NAND)
-#define EXCITE_ADDR_NAND	CKSEG1ADDR(EXCITE_OFFS_NAND)
-
-#define EXCITE_OFFS_BOOTROM	0x1f000000
-#define EXCITE_SIZE_BOOTROM	(8 << 20)
-#define EXCITE_PHYS_BOOTROM	CPHYSADDR(EXCITE_OFFS_BOOTROM)
-#define EXCITE_ADDR_BOOTROM	CKSEG1ADDR(EXCITE_OFFS_BOOTROM)
-
-/* FPGA address offsets */
-#define EXCITE_FPGA_DPR		0x0104	/* dual-ported ram */
-#define EXCITE_FPGA_SYSCTL	0x0200	/* system control register block */
-
-#endif /* __EXCITE_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite_nandflash.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite_nandflash.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/excite_nandflash.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/excite_nandflash.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-#ifndef __EXCITE_NANDFLASH_H__
-#define __EXCITE_NANDFLASH_H__
-
-/* Resource names */
-#define EXCITE_NANDFLASH_RESOURCE_REGS	"excite_nandflash_regs"
-
-#endif /* __EXCITE_NANDFLASH_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_eth.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_eth.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_eth.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_eth.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-#if !defined(__RM9K_ETH_H__)
-#define __RM9K_ETH_H__
-
-#define RM9K_GE_NAME			"rm9k_ge"
-
-/* Resource names */
-#define RM9K_GE_RESOURCE_MAC      	"rm9k_ge_mac"
-#define RM9K_GE_RESOURCE_MSTAT      	"rm9k_ge_mstat"
-#define RM9K_GE_RESOURCE_PKTPROC	"rm9k_ge_pktproc"
-#define RM9K_GE_RESOURCE_XDMA		"rm9k_ge_xdma"
-#define RM9K_GE_RESOURCE_FIFO_RX  	"rm9k_ge_fifo_rx"
-#define RM9K_GE_RESOURCE_FIFO_TX  	"rm9k_ge_fifo_tx"
-#define RM9K_GE_RESOURCE_FIFOMEM_RX  	"rm9k_ge_fifo_memory_rx"
-#define RM9K_GE_RESOURCE_FIFOMEM_TX  	"rm9k_ge_fifo_memory_tx"
-#define RM9K_GE_RESOURCE_PHY      	"rm9k_ge_phy"
-#define RM9K_GE_RESOURCE_DMADESC_RX  	"rm9k_ge_dmadesc_rx"
-#define RM9K_GE_RESOURCE_DMADESC_TX  	"rm9k_ge_dmadesc_tx"
-#define RM9K_GE_RESOURCE_IRQ_MAIN	"rm9k_ge_irq_main"
-#define RM9K_GE_RESOURCE_IRQ_PHY	"rm9k_ge_irq_phy"
-#define RM9K_GE_RESOURCE_GPI_SLICE	"rm9k_ge_gpi_slice"
-#define RM9K_GE_RESOURCE_MDIO_CHANNEL	"rm9k_ge_mdio_channel"
-
-#endif /* !defined(__RM9K_ETH_H__) */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_wdt.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_wdt.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_wdt.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_wdt.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef __RM9K_WDT_H__
-#define __RM9K_WDT_H__
-
-/* Device name */
-#define WDT_NAME		"wdt_gpi"
-
-/* Resource names */
-#define WDT_RESOURCE_REGS	"excite_watchdog_regs"
-#define WDT_RESOURCE_IRQ	"excite_watchdog_irq"
-#define WDT_RESOURCE_COUNTER	"excite_watchdog_counter"
-
-#endif /* __RM9K_WDT_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_xicap.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_xicap.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/rm9k_xicap.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/rm9k_xicap.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-#ifndef __EXCITE_XICAP_H__
-#define __EXCITE_XICAP_H__
-
-
-/* Resource names */
-#define XICAP_RESOURCE_FIFO_RX		"xicap_fifo_rx"
-#define XICAP_RESOURCE_FIFO_TX		"xicap_fifo_tx"
-#define XICAP_RESOURCE_XDMA 		"xicap_xdma"
-#define XICAP_RESOURCE_DMADESC		"xicap_dmadesc"
-#define XICAP_RESOURCE_PKTPROC  	"xicap_pktproc"
-#define XICAP_RESOURCE_IRQ		"xicap_irq"
-#define XICAP_RESOURCE_GPI_SLICE	"xicap_gpi_slice"
-#define XICAP_RESOURCE_FIFO_BLK		"xicap_fifo_blocks"
-#define XICAP_RESOURCE_PKT_STREAM	"xicap_pkt_stream"
-
-#endif /* __EXCITE_XICAP_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/war.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/war.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-excite/war.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-excite/war.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +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_EXCITE_WAR_H
-#define __ASM_MIPS_MACH_EXCITE_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 RM9000_CDEX_SMP_WAR		1
-#define ICACHE_REFILLS_WORKAROUND_WAR   1
-#define R10000_LLSC_WAR			0
-#define MIPS34K_MISSED_ITLB_WAR	0
-
-#endif /* __ASM_MIPS_MACH_EXCITE_WAR_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-ip27/topology.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ip27/topology.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-ip27/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-ip27/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,9 @@ extern struct cpuinfo_ip27 sn_cpu_info[N
 
 #define cpu_to_node(cpu)	(sn_cpu_info[(cpu)].p_nodeid)
 #define parent_node(node)	(node)
-#define cpumask_of_node(node)	(&hub_data(node)->h_cpus)
+#define cpumask_of_node(node)	((node) == -1 ?				\
+				 cpu_all_mask :				\
+				 &hub_data(node)->h_cpus)
 struct pci_bus;
 extern int pcibus_to_node(struct pci_bus *);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,305 @@
+/*
+ * The header file of cs5536 sourth bridge.
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu <liujl@lemote.com>
+ */
+
+#ifndef	_CS5536_H
+#define	_CS5536_H
+
+#include <linux/types.h>
+
+extern void _rdmsr(u32 msr, u32 *hi, u32 *lo);
+extern void _wrmsr(u32 msr, u32 hi, u32 lo);
+
+/*
+ * MSR module base
+ */
+#define	CS5536_SB_MSR_BASE	(0x00000000)
+#define	CS5536_GLIU_MSR_BASE	(0x10000000)
+#define	CS5536_ILLEGAL_MSR_BASE	(0x20000000)
+#define	CS5536_USB_MSR_BASE	(0x40000000)
+#define	CS5536_IDE_MSR_BASE	(0x60000000)
+#define	CS5536_DIVIL_MSR_BASE	(0x80000000)
+#define	CS5536_ACC_MSR_BASE	(0xa0000000)
+#define	CS5536_UNUSED_MSR_BASE	(0xc0000000)
+#define	CS5536_GLCP_MSR_BASE	(0xe0000000)
+
+#define	SB_MSR_REG(offset)	(CS5536_SB_MSR_BASE	| (offset))
+#define	GLIU_MSR_REG(offset)	(CS5536_GLIU_MSR_BASE	| (offset))
+#define	ILLEGAL_MSR_REG(offset)	(CS5536_ILLEGAL_MSR_BASE | (offset))
+#define	USB_MSR_REG(offset)	(CS5536_USB_MSR_BASE	| (offset))
+#define	IDE_MSR_REG(offset)	(CS5536_IDE_MSR_BASE	| (offset))
+#define	DIVIL_MSR_REG(offset)	(CS5536_DIVIL_MSR_BASE	| (offset))
+#define	ACC_MSR_REG(offset)	(CS5536_ACC_MSR_BASE	| (offset))
+#define	UNUSED_MSR_REG(offset)	(CS5536_UNUSED_MSR_BASE	| (offset))
+#define	GLCP_MSR_REG(offset)	(CS5536_GLCP_MSR_BASE	| (offset))
+
+/*
+ * BAR SPACE OF VIRTUAL PCI :
+ * range for pci probe use, length is the actual size.
+ */
+/* IO space for all DIVIL modules */
+#define	CS5536_IRQ_RANGE	0xffffffe0 /* USERD FOR PCI PROBE */
+#define	CS5536_IRQ_LENGTH	0x20	/* THE REGS ACTUAL LENGTH */
+#define	CS5536_SMB_RANGE	0xfffffff8
+#define	CS5536_SMB_LENGTH	0x08
+#define	CS5536_GPIO_RANGE	0xffffff00
+#define	CS5536_GPIO_LENGTH	0x100
+#define	CS5536_MFGPT_RANGE	0xffffffc0
+#define	CS5536_MFGPT_LENGTH	0x40
+#define	CS5536_ACPI_RANGE	0xffffffe0
+#define	CS5536_ACPI_LENGTH	0x20
+#define	CS5536_PMS_RANGE	0xffffff80
+#define	CS5536_PMS_LENGTH	0x80
+/* IO space for IDE */
+#define	CS5536_IDE_RANGE	0xfffffff0
+#define	CS5536_IDE_LENGTH	0x10
+/* IO space for ACC */
+#define	CS5536_ACC_RANGE	0xffffff80
+#define	CS5536_ACC_LENGTH	0x80
+/* MEM space for ALL USB modules */
+#define	CS5536_OHCI_RANGE	0xfffff000
+#define	CS5536_OHCI_LENGTH	0x1000
+#define	CS5536_EHCI_RANGE	0xfffff000
+#define	CS5536_EHCI_LENGTH	0x1000
+
+/*
+ * PCI MSR ACCESS
+ */
+#define	PCI_MSR_CTRL		0xF0
+#define	PCI_MSR_ADDR		0xF4
+#define	PCI_MSR_DATA_LO		0xF8
+#define	PCI_MSR_DATA_HI		0xFC
+
+/**************** MSR *****************************/
+
+/*
+ * GLIU STANDARD MSR
+ */
+#define	GLIU_CAP		0x00
+#define	GLIU_CONFIG		0x01
+#define	GLIU_SMI		0x02
+#define	GLIU_ERROR		0x03
+#define	GLIU_PM			0x04
+#define	GLIU_DIAG		0x05
+
+/*
+ * GLIU SPEC. MSR
+ */
+#define	GLIU_P2D_BM0		0x20
+#define	GLIU_P2D_BM1		0x21
+#define	GLIU_P2D_BM2		0x22
+#define	GLIU_P2D_BMK0		0x23
+#define	GLIU_P2D_BMK1		0x24
+#define	GLIU_P2D_BM3		0x25
+#define	GLIU_P2D_BM4		0x26
+#define	GLIU_COH		0x80
+#define	GLIU_PAE		0x81
+#define	GLIU_ARB		0x82
+#define	GLIU_ASMI		0x83
+#define	GLIU_AERR		0x84
+#define	GLIU_DEBUG		0x85
+#define	GLIU_PHY_CAP		0x86
+#define	GLIU_NOUT_RESP		0x87
+#define	GLIU_NOUT_WDATA		0x88
+#define	GLIU_WHOAMI		0x8B
+#define	GLIU_SLV_DIS		0x8C
+#define	GLIU_IOD_BM0		0xE0
+#define	GLIU_IOD_BM1		0xE1
+#define	GLIU_IOD_BM2		0xE2
+#define	GLIU_IOD_BM3		0xE3
+#define	GLIU_IOD_BM4		0xE4
+#define	GLIU_IOD_BM5		0xE5
+#define	GLIU_IOD_BM6		0xE6
+#define	GLIU_IOD_BM7		0xE7
+#define	GLIU_IOD_BM8		0xE8
+#define	GLIU_IOD_BM9		0xE9
+#define	GLIU_IOD_SC0		0xEA
+#define	GLIU_IOD_SC1		0xEB
+#define	GLIU_IOD_SC2		0xEC
+#define	GLIU_IOD_SC3		0xED
+#define	GLIU_IOD_SC4		0xEE
+#define	GLIU_IOD_SC5		0xEF
+#define	GLIU_IOD_SC6		0xF0
+#define	GLIU_IOD_SC7		0xF1
+
+/*
+ * SB STANDARD
+ */
+#define	SB_CAP		0x00
+#define	SB_CONFIG	0x01
+#define	SB_SMI		0x02
+#define	SB_ERROR	0x03
+#define	SB_MAR_ERR_EN		0x00000001
+#define	SB_TAR_ERR_EN		0x00000002
+#define	SB_RSVD_BIT1		0x00000004
+#define	SB_EXCEP_ERR_EN		0x00000008
+#define	SB_SYSE_ERR_EN		0x00000010
+#define	SB_PARE_ERR_EN		0x00000020
+#define	SB_TAS_ERR_EN		0x00000040
+#define	SB_MAR_ERR_FLAG		0x00010000
+#define	SB_TAR_ERR_FLAG		0x00020000
+#define	SB_RSVD_BIT2		0x00040000
+#define	SB_EXCEP_ERR_FLAG	0x00080000
+#define	SB_SYSE_ERR_FLAG	0x00100000
+#define	SB_PARE_ERR_FLAG	0x00200000
+#define	SB_TAS_ERR_FLAG		0x00400000
+#define	SB_PM		0x04
+#define	SB_DIAG		0x05
+
+/*
+ * SB SPEC.
+ */
+#define	SB_CTRL		0x10
+#define	SB_R0		0x20
+#define	SB_R1		0x21
+#define	SB_R2		0x22
+#define	SB_R3		0x23
+#define	SB_R4		0x24
+#define	SB_R5		0x25
+#define	SB_R6		0x26
+#define	SB_R7		0x27
+#define	SB_R8		0x28
+#define	SB_R9		0x29
+#define	SB_R10		0x2A
+#define	SB_R11		0x2B
+#define	SB_R12		0x2C
+#define	SB_R13		0x2D
+#define	SB_R14		0x2E
+#define	SB_R15		0x2F
+
+/*
+ * GLCP STANDARD
+ */
+#define	GLCP_CAP		0x00
+#define	GLCP_CONFIG		0x01
+#define	GLCP_SMI		0x02
+#define	GLCP_ERROR		0x03
+#define	GLCP_PM			0x04
+#define	GLCP_DIAG		0x05
+
+/*
+ * GLCP SPEC.
+ */
+#define	GLCP_CLK_DIS_DELAY	0x08
+#define	GLCP_PM_CLK_DISABLE	0x09
+#define	GLCP_GLB_PM		0x0B
+#define	GLCP_DBG_OUT		0x0C
+#define	GLCP_RSVD1		0x0D
+#define	GLCP_SOFT_COM		0x0E
+#define	SOFT_BAR_SMB_FLAG	0x00000001
+#define	SOFT_BAR_GPIO_FLAG	0x00000002
+#define	SOFT_BAR_MFGPT_FLAG	0x00000004
+#define	SOFT_BAR_IRQ_FLAG	0x00000008
+#define	SOFT_BAR_PMS_FLAG	0x00000010
+#define	SOFT_BAR_ACPI_FLAG	0x00000020
+#define	SOFT_BAR_IDE_FLAG	0x00000400
+#define	SOFT_BAR_ACC_FLAG	0x00000800
+#define	SOFT_BAR_OHCI_FLAG	0x00001000
+#define	SOFT_BAR_EHCI_FLAG	0x00002000
+#define	GLCP_RSVD2		0x0F
+#define	GLCP_CLK_OFF		0x10
+#define	GLCP_CLK_ACTIVE		0x11
+#define	GLCP_CLK_DISABLE	0x12
+#define	GLCP_CLK4ACK		0x13
+#define	GLCP_SYS_RST		0x14
+#define	GLCP_RSVD3		0x15
+#define	GLCP_DBG_CLK_CTRL	0x16
+#define	GLCP_CHIP_REV_ID	0x17
+
+/* PIC */
+#define	PIC_YSEL_LOW		0x20
+#define	PIC_YSEL_LOW_USB_SHIFT		8
+#define	PIC_YSEL_LOW_ACC_SHIFT		16
+#define	PIC_YSEL_LOW_FLASH_SHIFT	24
+#define	PIC_YSEL_HIGH		0x21
+#define	PIC_ZSEL_LOW		0x22
+#define	PIC_ZSEL_HIGH		0x23
+#define	PIC_IRQM_PRIM		0x24
+#define	PIC_IRQM_LPC		0x25
+#define	PIC_XIRR_STS_LOW	0x26
+#define	PIC_XIRR_STS_HIGH	0x27
+#define	PCI_SHDW		0x34
+
+/*
+ * DIVIL STANDARD
+ */
+#define	DIVIL_CAP		0x00
+#define	DIVIL_CONFIG		0x01
+#define	DIVIL_SMI		0x02
+#define	DIVIL_ERROR		0x03
+#define	DIVIL_PM		0x04
+#define	DIVIL_DIAG		0x05
+
+/*
+ * DIVIL SPEC.
+ */
+#define	DIVIL_LBAR_IRQ		0x08
+#define	DIVIL_LBAR_KEL		0x09
+#define	DIVIL_LBAR_SMB		0x0B
+#define	DIVIL_LBAR_GPIO		0x0C
+#define	DIVIL_LBAR_MFGPT	0x0D
+#define	DIVIL_LBAR_ACPI		0x0E
+#define	DIVIL_LBAR_PMS		0x0F
+#define	DIVIL_LEG_IO		0x14
+#define	DIVIL_BALL_OPTS		0x15
+#define	DIVIL_SOFT_IRQ		0x16
+#define	DIVIL_SOFT_RESET	0x17
+
+/* MFGPT */
+#define MFGPT_IRQ	0x28
+
+/*
+ * IDE STANDARD
+ */
+#define	IDE_CAP		0x00
+#define	IDE_CONFIG	0x01
+#define	IDE_SMI		0x02
+#define	IDE_ERROR	0x03
+#define	IDE_PM		0x04
+#define	IDE_DIAG	0x05
+
+/*
+ * IDE SPEC.
+ */
+#define	IDE_IO_BAR	0x08
+#define	IDE_CFG		0x10
+#define	IDE_DTC		0x12
+#define	IDE_CAST	0x13
+#define	IDE_ETC		0x14
+#define	IDE_INTERNAL_PM	0x15
+
+/*
+ * ACC STANDARD
+ */
+#define	ACC_CAP		0x00
+#define	ACC_CONFIG	0x01
+#define	ACC_SMI		0x02
+#define	ACC_ERROR	0x03
+#define	ACC_PM		0x04
+#define	ACC_DIAG	0x05
+
+/*
+ * USB STANDARD
+ */
+#define	USB_CAP		0x00
+#define	USB_CONFIG	0x01
+#define	USB_SMI		0x02
+#define	USB_ERROR	0x03
+#define	USB_PM		0x04
+#define	USB_DIAG	0x05
+
+/*
+ * USB SPEC.
+ */
+#define	USB_OHCI	0x08
+#define	USB_EHCI	0x09
+
+/****************** NATIVE ***************************/
+/* GPIO : I/O SPACE; REG : 32BITS */
+#define	GPIOL_OUT_VAL		0x00
+#define	GPIOL_OUT_EN		0x04
+
+#endif				/* _CS5536_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+ * cs5536 mfgpt header file
+ */
+
+#ifndef _CS5536_MFGPT_H
+#define _CS5536_MFGPT_H
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+#ifdef CONFIG_CS5536_MFGPT
+extern void setup_mfgpt0_timer(void);
+extern void disable_mfgpt0_counter(void);
+extern void enable_mfgpt0_counter(void);
+#else
+static inline void __maybe_unused setup_mfgpt0_timer(void)
+{
+}
+static inline void __maybe_unused disable_mfgpt0_counter(void)
+{
+}
+static inline void __maybe_unused enable_mfgpt0_counter(void)
+{
+}
+#endif
+
+#define MFGPT_TICK_RATE 14318000
+#define COMPARE  ((MFGPT_TICK_RATE + HZ/2) / HZ)
+
+#define MFGPT_BASE	mfgpt_base
+#define MFGPT0_CMP2	(MFGPT_BASE + 2)
+#define MFGPT0_CNT	(MFGPT_BASE + 4)
+#define MFGPT0_SETUP	(MFGPT_BASE + 6)
+
+#endif /*!_CS5536_MFGPT_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,153 @@
+/*
+ * the definition file of cs5536 Virtual Support Module(VSM).
+ * pci configuration space can be accessed through the VSM, so
+ * there is no need of the MSR read/write now, except the spec.
+ * MSR registers which are not implemented yet.
+ *
+ * Copyright (C) 2007 Lemote Inc.
+ * Author : jlliu, liujl@lemote.com
+ */
+
+#ifndef	_CS5536_PCI_H
+#define	_CS5536_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci_regs.h>
+
+extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
+extern u32 cs5536_pci_conf_read4(int function, int reg);
+
+#define	CS5536_ACC_INTR		9
+#define	CS5536_IDE_INTR		14
+#define	CS5536_USB_INTR		11
+#define	CS5536_MFGPT_INTR	5
+#define	CS5536_UART1_INTR	4
+#define	CS5536_UART2_INTR	3
+
+/************** PCI BUS DEVICE FUNCTION ***************/
+
+/*
+ * PCI bus device function
+ */
+#define	PCI_BUS_CS5536		0
+#define	PCI_IDSEL_CS5536	14
+
+/********** STANDARD PCI-2.2 EXPANSION ****************/
+
+/*
+ * PCI configuration space
+ * we have to virtualize the PCI configure space head, so we should
+ * define the necessary IDs and some others.
+ */
+
+/* CONFIG of PCI VENDOR ID*/
+#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \
+	(((mod_dev_id) << 16) | (sys_vendor_id))
+
+/* VENDOR ID */
+#define	CS5536_VENDOR_ID	0x1022
+
+/* DEVICE ID */
+#define	CS5536_ISA_DEVICE_ID		0x2090
+#define	CS5536_IDE_DEVICE_ID		0x209a
+#define	CS5536_ACC_DEVICE_ID		0x2093
+#define	CS5536_OHCI_DEVICE_ID		0x2094
+#define	CS5536_EHCI_DEVICE_ID		0x2095
+
+/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
+#define	CS5536_ISA_CLASS_CODE		0x060100
+#define CS5536_IDE_CLASS_CODE		0x010180
+#define	CS5536_ACC_CLASS_CODE		0x040100
+#define	CS5536_OHCI_CLASS_CODE		0x0C0310
+#define	CS5536_EHCI_CLASS_CODE		0x0C0320
+
+/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
+
+#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer)	\
+	((PCI_NONE_BIST << 24) | ((header_type) << 16) \
+		| ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE);
+
+#define	PCI_NONE_BIST			0x00	/* RO not implemented yet. */
+#define	PCI_BRIDGE_HEADER_TYPE		0x80	/* RO */
+#define	PCI_NORMAL_HEADER_TYPE		0x00
+#define	PCI_NORMAL_LATENCY_TIMER	0x00
+#define	PCI_NORMAL_CACHE_LINE_SIZE	0x08	/* RW */
+
+/* BAR */
+#define	PCI_BAR0_REG			0x10
+#define	PCI_BAR1_REG			0x14
+#define	PCI_BAR2_REG			0x18
+#define	PCI_BAR3_REG			0x1c
+#define	PCI_BAR4_REG			0x20
+#define	PCI_BAR5_REG			0x24
+#define	PCI_BAR_COUNT			6
+#define	PCI_BAR_RANGE_MASK		0xFFFFFFFF
+
+/* CARDBUS CIS POINTER */
+#define	PCI_CARDBUS_CIS_POINTER		0x00000000
+
+/* SUBSYSTEM VENDOR ID  */
+#define	CS5536_SUB_VENDOR_ID		CS5536_VENDOR_ID
+
+/* SUBSYSTEM ID */
+#define	CS5536_ISA_SUB_ID		CS5536_ISA_DEVICE_ID
+#define	CS5536_IDE_SUB_ID		CS5536_IDE_DEVICE_ID
+#define	CS5536_ACC_SUB_ID		CS5536_ACC_DEVICE_ID
+#define	CS5536_OHCI_SUB_ID		CS5536_OHCI_DEVICE_ID
+#define	CS5536_EHCI_SUB_ID		CS5536_EHCI_DEVICE_ID
+
+/* EXPANSION ROM BAR */
+#define	PCI_EXPANSION_ROM_BAR		0x00000000
+
+/* CAPABILITIES POINTER */
+#define	PCI_CAPLIST_POINTER		0x00000000
+#define PCI_CAPLIST_USB_POINTER		0x40
+/* INTERRUPT */
+
+#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \
+	((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \
+		((pin) << 8) | (mod_intr))
+
+#define	PCI_MAX_LATENCY			0x40
+#define	PCI_MIN_GRANT			0x00
+#define	PCI_DEFAULT_PIN			0x01
+
+/*********** EXPANSION PCI REG ************************/
+
+/*
+ * ISA EXPANSION
+ */
+#define	PCI_UART1_INT_REG 	0x50
+#define PCI_UART2_INT_REG	0x54
+#define	PCI_ISA_FIXUP_REG	0x58
+
+/*
+ * IDE EXPANSION
+ */
+#define	PCI_IDE_CFG_REG		0x40
+#define	CS5536_IDE_FLASH_SIGNATURE	0xDEADBEEF
+#define	PCI_IDE_DTC_REG		0x48
+#define	PCI_IDE_CAST_REG	0x4C
+#define	PCI_IDE_ETC_REG		0x50
+#define	PCI_IDE_PM_REG		0x54
+#define	PCI_IDE_INT_REG		0x60
+
+/*
+ * ACC EXPANSION
+ */
+#define	PCI_ACC_INT_REG		0x50
+
+/*
+ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
+ */
+#define	PCI_OHCI_PM_REG		0x40
+#define	PCI_OHCI_INT_REG	0x50
+
+/*
+ * EHCI EXPANSION
+ */
+#define	PCI_EHCI_LEGSMIEN_REG	0x50
+#define	PCI_EHCI_LEGSMISTS_REG	0x54
+#define	PCI_EHCI_FLADJ_REG	0x60
+
+#endif				/* _CS5536_PCI_H_ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,31 @@
+/*
+ * the read/write interfaces for Virtual Support Module(VSM)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ */
+
+#ifndef	_CS5536_VSM_H
+#define	_CS5536_VSM_H
+
+#include <linux/types.h>
+
+typedef void (*cs5536_pci_vsm_write)(int reg, u32 value);
+typedef u32 (*cs5536_pci_vsm_read)(int reg);
+
+#define DECLARE_CS5536_MODULE(name) \
+extern void pci_##name##_write_reg(int reg, u32 value); \
+extern u32 pci_##name##_read_reg(int reg);
+
+/* ide module */
+DECLARE_CS5536_MODULE(ide)
+/* acc module */
+DECLARE_CS5536_MODULE(acc)
+/* ohci module */
+DECLARE_CS5536_MODULE(ohci)
+/* isa module */
+DECLARE_CS5536_MODULE(isa)
+/* ehci module */
+DECLARE_CS5536_MODULE(ehci)
+
+#endif				/* _CS5536_VSM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/dma-coherence.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/dma-coherence.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/dma-coherence.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/dma-coherence.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,11 @@ static inline dma_addr_t plat_map_dma_me
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
 	dma_addr_t dma_addr)
 {
+#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
+	return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
+#else
 	return dma_addr & 0x7fffffff;
+#endif
 }
 
 static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/loongson.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/loongson.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/loongson.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/loongson.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Copyright (C) 2009 Lemote, Inc.
  * Author: Wu Zhangjin <wuzj@lemote.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -15,9 +15,6 @@
 #include <linux/io.h>
 #include <linux/init.h>
 
-/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */
-#include <asm/mips-boards/bonito64.h>
-
 /* loongson internal northbridge initialization */
 extern void bonito_irq_init(void);
 
@@ -32,7 +29,19 @@ extern unsigned long memsize, highmemsiz
 /* loongson-specific command line, env and memory initialization */
 extern void __init prom_init_memory(void);
 extern void __init prom_init_cmdline(void);
+extern void __init prom_init_machtype(void);
 extern void __init prom_init_env(void);
+#ifdef CONFIG_LOONGSON_UART_BASE
+extern unsigned long _loongson_uart_base, loongson_uart_base;
+extern void prom_init_loongson_uart_base(void);
+#endif
+
+static inline void prom_init_uart_base(void)
+{
+#ifdef CONFIG_LOONGSON_UART_BASE
+	prom_init_loongson_uart_base();
+#endif
+}
 
 /* irq operation functions */
 extern void bonito_irqdispatch(void);
@@ -40,25 +49,276 @@ extern void __init bonito_irq_init(void)
 extern void __init set_irq_trigger_mode(void);
 extern void __init mach_init_irq(void);
 extern void mach_irq_dispatch(unsigned int pending);
+extern int mach_i8259_irq(void);
+
+/* We need this in some places... */
+#define delay()	({		\
+	int x;				\
+	for (x = 0; x < 100000; x++)	\
+		__asm__ __volatile__(""); \
+})
+
+#define LOONGSON_REG(x) \
+	(*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
+
+#define LOONGSON_IRQ_BASE	32
+#define LOONGSON2_PERFCNT_IRQ	(MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
+
+#define LOONGSON_FLASH_BASE	0x1c000000
+#define LOONGSON_FLASH_SIZE	0x02000000	/* 32M */
+#define LOONGSON_FLASH_TOP	(LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
+
+#define LOONGSON_LIO0_BASE	0x1e000000
+#define LOONGSON_LIO0_SIZE	0x01C00000	/* 28M */
+#define LOONGSON_LIO0_TOP	(LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
+
+#define LOONGSON_BOOT_BASE	0x1fc00000
+#define LOONGSON_BOOT_SIZE	0x00100000	/* 1M */
+#define LOONGSON_BOOT_TOP 	(LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
+#define LOONGSON_REG_BASE 	0x1fe00000
+#define LOONGSON_REG_SIZE 	0x00100000	/* 256Bytes + 256Bytes + ??? */
+#define LOONGSON_REG_TOP	(LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
+
+#define LOONGSON_LIO1_BASE 	0x1ff00000
+#define LOONGSON_LIO1_SIZE 	0x00100000	/* 1M */
+#define LOONGSON_LIO1_TOP	(LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
+
+#define LOONGSON_PCILO0_BASE	0x10000000
+#define LOONGSON_PCILO1_BASE	0x14000000
+#define LOONGSON_PCILO2_BASE	0x18000000
+#define LOONGSON_PCILO_BASE	LOONGSON_PCILO0_BASE
+#define LOONGSON_PCILO_SIZE	0x0c000000	/* 64M * 3 */
+#define LOONGSON_PCILO_TOP	(LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
+
+#define LOONGSON_PCICFG_BASE	0x1fe80000
+#define LOONGSON_PCICFG_SIZE	0x00000800	/* 2K */
+#define LOONGSON_PCICFG_TOP	(LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
+#define LOONGSON_PCIIO_BASE	0x1fd00000
+#define LOONGSON_PCIIO_SIZE	0x00100000	/* 1M */
+#define LOONGSON_PCIIO_TOP	(LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
+
+/* Loongson Register Bases */
+
+#define LOONGSON_PCICONFIGBASE	0x00
+#define LOONGSON_REGBASE	0x100
 
 /* PCI Configuration Registers */
-#define LOONGSON_PCI_ISR4C  BONITO_PCI_REG(0x4c)
+
+#define LOONGSON_PCI_REG(x)	LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
+#define LOONGSON_PCIDID		LOONGSON_PCI_REG(0x00)
+#define LOONGSON_PCICMD		LOONGSON_PCI_REG(0x04)
+#define LOONGSON_PCICLASS 	LOONGSON_PCI_REG(0x08)
+#define LOONGSON_PCILTIMER	LOONGSON_PCI_REG(0x0c)
+#define LOONGSON_PCIBASE0 	LOONGSON_PCI_REG(0x10)
+#define LOONGSON_PCIBASE1 	LOONGSON_PCI_REG(0x14)
+#define LOONGSON_PCIBASE2 	LOONGSON_PCI_REG(0x18)
+#define LOONGSON_PCIBASE3 	LOONGSON_PCI_REG(0x1c)
+#define LOONGSON_PCIBASE4 	LOONGSON_PCI_REG(0x20)
+#define LOONGSON_PCIEXPRBASE	LOONGSON_PCI_REG(0x30)
+#define LOONGSON_PCIINT		LOONGSON_PCI_REG(0x3c)
+
+#define LOONGSON_PCI_ISR4C	LOONGSON_PCI_REG(0x4c)
+
+#define LOONGSON_PCICMD_PERR_CLR	0x80000000
+#define LOONGSON_PCICMD_SERR_CLR	0x40000000
+#define LOONGSON_PCICMD_MABORT_CLR	0x20000000
+#define LOONGSON_PCICMD_MTABORT_CLR	0x10000000
+#define LOONGSON_PCICMD_TABORT_CLR	0x08000000
+#define LOONGSON_PCICMD_MPERR_CLR 	0x01000000
+#define LOONGSON_PCICMD_PERRRESPEN	0x00000040
+#define LOONGSON_PCICMD_ASTEPEN		0x00000080
+#define LOONGSON_PCICMD_SERREN		0x00000100
+#define LOONGSON_PCILTIMER_BUSLATENCY	0x0000ff00
+#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT	8
+
+/* Loongson h/w Configuration */
+
+#define LOONGSON_GENCFG_OFFSET		0x4
+#define LOONGSON_GENCFG	LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
+
+#define LOONGSON_GENCFG_DEBUGMODE	0x00000001
+#define LOONGSON_GENCFG_SNOOPEN		0x00000002
+#define LOONGSON_GENCFG_CPUSELFRESET	0x00000004
+
+#define LOONGSON_GENCFG_FORCE_IRQA	0x00000008
+#define LOONGSON_GENCFG_IRQA_ISOUT	0x00000010
+#define LOONGSON_GENCFG_IRQA_FROM_INT1	0x00000020
+#define LOONGSON_GENCFG_BYTESWAP	0x00000040
+
+#define LOONGSON_GENCFG_UNCACHED	0x00000080
+#define LOONGSON_GENCFG_PREFETCHEN	0x00000100
+#define LOONGSON_GENCFG_WBEHINDEN	0x00000200
+#define LOONGSON_GENCFG_CACHEALG	0x00000c00
+#define LOONGSON_GENCFG_CACHEALG_SHIFT	10
+#define LOONGSON_GENCFG_PCIQUEUE	0x00001000
+#define LOONGSON_GENCFG_CACHESTOP	0x00002000
+#define LOONGSON_GENCFG_MSTRBYTESWAP	0x00004000
+#define LOONGSON_GENCFG_BUSERREN	0x00008000
+#define LOONGSON_GENCFG_NORETRYTIMEOUT	0x00010000
+#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT	0x00020000
+
+/* PCI address map control */
+
+#define LOONGSON_PCIMAP			LOONGSON_REG(LOONGSON_REGBASE + 0x10)
+#define LOONGSON_PCIMEMBASECFG		LOONGSON_REG(LOONGSON_REGBASE + 0x14)
+#define LOONGSON_PCIMAP_CFG		LOONGSON_REG(LOONGSON_REGBASE + 0x18)
+
+/* GPIO Regs - r/w */
+
+#define LOONGSON_GPIODATA 		LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
+#define LOONGSON_GPIOIE			LOONGSON_REG(LOONGSON_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define LOONGSON_INTEDGE		LOONGSON_REG(LOONGSON_REGBASE + 0x24)
+#define LOONGSON_INTSTEER 		LOONGSON_REG(LOONGSON_REGBASE + 0x28)
+#define LOONGSON_INTPOL			LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define LOONGSON_INTENSET 		LOONGSON_REG(LOONGSON_REGBASE + 0x30)
+#define LOONGSON_INTENCLR 		LOONGSON_REG(LOONGSON_REGBASE + 0x34)
+#define LOONGSON_INTEN			LOONGSON_REG(LOONGSON_REGBASE + 0x38)
+#define LOONGSON_INTISR			LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
+
+/* ICU */
+#define LOONGSON_ICU_MBOXES		0x0000000f
+#define LOONGSON_ICU_MBOXES_SHIFT 	0
+#define LOONGSON_ICU_DMARDY		0x00000010
+#define LOONGSON_ICU_DMAEMPTY		0x00000020
+#define LOONGSON_ICU_COPYRDY		0x00000040
+#define LOONGSON_ICU_COPYEMPTY		0x00000080
+#define LOONGSON_ICU_COPYERR		0x00000100
+#define LOONGSON_ICU_PCIIRQ		0x00000200
+#define LOONGSON_ICU_MASTERERR		0x00000400
+#define LOONGSON_ICU_SYSTEMERR		0x00000800
+#define LOONGSON_ICU_DRAMPERR		0x00001000
+#define LOONGSON_ICU_RETRYERR		0x00002000
+#define LOONGSON_ICU_GPIOS		0x01ff0000
+#define LOONGSON_ICU_GPIOS_SHIFT		16
+#define LOONGSON_ICU_GPINS		0x7e000000
+#define LOONGSON_ICU_GPINS_SHIFT		25
+#define LOONGSON_ICU_MBOX(N)		(1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
+#define LOONGSON_ICU_GPIO(N)		(1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
+#define LOONGSON_ICU_GPIN(N)		(1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
+
+/* PCI prefetch window base & mask */
+
+#define LOONGSON_MEM_WIN_BASE_L 	LOONGSON_REG(LOONGSON_REGBASE + 0x40)
+#define LOONGSON_MEM_WIN_BASE_H 	LOONGSON_REG(LOONGSON_REGBASE + 0x44)
+#define LOONGSON_MEM_WIN_MASK_L 	LOONGSON_REG(LOONGSON_REGBASE + 0x48)
+#define LOONGSON_MEM_WIN_MASK_H 	LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
 
 /* PCI_Hit*_Sel_* */
 
-#define LOONGSON_PCI_HIT0_SEL_L     BONITO(BONITO_REGBASE + 0x50)
-#define LOONGSON_PCI_HIT0_SEL_H     BONITO(BONITO_REGBASE + 0x54)
-#define LOONGSON_PCI_HIT1_SEL_L     BONITO(BONITO_REGBASE + 0x58)
-#define LOONGSON_PCI_HIT1_SEL_H     BONITO(BONITO_REGBASE + 0x5c)
-#define LOONGSON_PCI_HIT2_SEL_L     BONITO(BONITO_REGBASE + 0x60)
-#define LOONGSON_PCI_HIT2_SEL_H     BONITO(BONITO_REGBASE + 0x64)
+#define LOONGSON_PCI_HIT0_SEL_L		LOONGSON_REG(LOONGSON_REGBASE + 0x50)
+#define LOONGSON_PCI_HIT0_SEL_H		LOONGSON_REG(LOONGSON_REGBASE + 0x54)
+#define LOONGSON_PCI_HIT1_SEL_L		LOONGSON_REG(LOONGSON_REGBASE + 0x58)
+#define LOONGSON_PCI_HIT1_SEL_H		LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
+#define LOONGSON_PCI_HIT2_SEL_L		LOONGSON_REG(LOONGSON_REGBASE + 0x60)
+#define LOONGSON_PCI_HIT2_SEL_H		LOONGSON_REG(LOONGSON_REGBASE + 0x64)
 
 /* PXArb Config & Status */
 
-#define LOONGSON_PXARB_CFG      BONITO(BONITO_REGBASE + 0x68)
-#define LOONGSON_PXARB_STATUS       BONITO(BONITO_REGBASE + 0x6c)
+#define LOONGSON_PXARB_CFG		LOONGSON_REG(LOONGSON_REGBASE + 0x68)
+#define LOONGSON_PXARB_STATUS		LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
 
-/* loongson2-specific perf counter IRQ */
-#define LOONGSON2_PERFCNT_IRQ   (MIPS_CPU_IRQ_BASE + 6)
+/* pcimap */
+
+#define LOONGSON_PCIMAP_PCIMAP_LO0	0x0000003f
+#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT	0
+#define LOONGSON_PCIMAP_PCIMAP_LO1	0x00000fc0
+#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT	6
+#define LOONGSON_PCIMAP_PCIMAP_LO2	0x0003f000
+#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT	12
+#define LOONGSON_PCIMAP_PCIMAP_2	0x00040000
+#define LOONGSON_PCIMAP_WIN(WIN, ADDR)	\
+	((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
+#include <linux/cpufreq.h>
+extern void loongson2_cpu_wait(void);
+extern struct cpufreq_frequency_table loongson2_clockmod_table[];
+
+/* Chip Config */
+#define LOONGSON_CHIPCFG0		LOONGSON_REG(LOONGSON_REGBASE + 0x80)
+#endif
+
+/*
+ * address windows configuration module
+ *
+ * loongson2e do not have this module
+ */
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/* address window config module base address */
+#define LOONGSON_ADDRWINCFG_BASE		0x3ff00000ul
+#define LOONGSON_ADDRWINCFG_SIZE		0x180
+
+extern unsigned long _loongson_addrwincfg_base;
+#define LOONGSON_ADDRWINCFG(offset) \
+	(*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
+
+#define CPU_WIN0_BASE	LOONGSON_ADDRWINCFG(0x00)
+#define CPU_WIN1_BASE	LOONGSON_ADDRWINCFG(0x08)
+#define CPU_WIN2_BASE	LOONGSON_ADDRWINCFG(0x10)
+#define CPU_WIN3_BASE	LOONGSON_ADDRWINCFG(0x18)
+
+#define CPU_WIN0_MASK	LOONGSON_ADDRWINCFG(0x20)
+#define CPU_WIN1_MASK	LOONGSON_ADDRWINCFG(0x28)
+#define CPU_WIN2_MASK	LOONGSON_ADDRWINCFG(0x30)
+#define CPU_WIN3_MASK	LOONGSON_ADDRWINCFG(0x38)
+
+#define CPU_WIN0_MMAP	LOONGSON_ADDRWINCFG(0x40)
+#define CPU_WIN1_MMAP	LOONGSON_ADDRWINCFG(0x48)
+#define CPU_WIN2_MMAP	LOONGSON_ADDRWINCFG(0x50)
+#define CPU_WIN3_MMAP	LOONGSON_ADDRWINCFG(0x58)
+
+#define PCIDMA_WIN0_BASE	LOONGSON_ADDRWINCFG(0x60)
+#define PCIDMA_WIN1_BASE	LOONGSON_ADDRWINCFG(0x68)
+#define PCIDMA_WIN2_BASE	LOONGSON_ADDRWINCFG(0x70)
+#define PCIDMA_WIN3_BASE	LOONGSON_ADDRWINCFG(0x78)
+
+#define PCIDMA_WIN0_MASK	LOONGSON_ADDRWINCFG(0x80)
+#define PCIDMA_WIN1_MASK	LOONGSON_ADDRWINCFG(0x88)
+#define PCIDMA_WIN2_MASK	LOONGSON_ADDRWINCFG(0x90)
+#define PCIDMA_WIN3_MASK	LOONGSON_ADDRWINCFG(0x98)
+
+#define PCIDMA_WIN0_MMAP	LOONGSON_ADDRWINCFG(0xa0)
+#define PCIDMA_WIN1_MMAP	LOONGSON_ADDRWINCFG(0xa8)
+#define PCIDMA_WIN2_MMAP	LOONGSON_ADDRWINCFG(0xb0)
+#define PCIDMA_WIN3_MMAP	LOONGSON_ADDRWINCFG(0xb8)
+
+#define ADDRWIN_WIN0	0
+#define ADDRWIN_WIN1	1
+#define ADDRWIN_WIN2	2
+#define ADDRWIN_WIN3	3
+
+#define ADDRWIN_MAP_DST_DDR	0
+#define ADDRWIN_MAP_DST_PCI	1
+#define ADDRWIN_MAP_DST_LIO	1
+
+/*
+ * s: CPU, PCIDMA
+ * d: DDR, PCI, LIO
+ * win: 0, 1, 2, 3
+ * src: map source
+ * dst: map destination
+ * size: ~mask + 1
+ */
+#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
+	s##_WIN##w##_BASE = (src); \
+	s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
+	s##_WIN##w##_MASK = ~(size-1); \
+} while (0)
+
+#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
+	LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
+#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
+	LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
+#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
+	LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
+
+#endif	/* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
 
 #endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/machine.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/machine.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/machine.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/machine.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,10 +13,15 @@
 
 #ifdef CONFIG_LEMOTE_FULOONG2E
 
-#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8)
-
 #define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
 
 #endif
 
+/* use fuloong2f as the default machine of LEMOTE_MACH2F */
+#ifdef CONFIG_LEMOTE_MACH2F
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F
+
+#endif
+
 #endif /* __ASM_MACH_LOONGSON_MACHINE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/mem.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/mem.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/mem.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/mem.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Copyright (C) 2009 Lemote, Inc.
  * Author: Wu Zhangjin <wuzj@lemote.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -12,19 +12,30 @@
 #define __ASM_MACH_LOONGSON_MEM_H
 
 /*
- * On Lemote Loongson 2e
+ * high memory space
  *
- * the high memory space starts from 512M.
- * the peripheral registers reside between 0x1000:0000 and 0x2000:0000.
+ * in loongson2e, starts from 512M
+ * in loongson2f, starts from 2G 256M
  */
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_HIGHMEM_START	0x20000000
+#else
+#define LOONGSON_HIGHMEM_START	0x90000000
+#endif
 
-#ifdef CONFIG_LEMOTE_FULOONG2E
-
-#define LOONGSON_HIGHMEM_START  0x20000000
+/*
+ * the peripheral registers(MMIO):
+ *
+ * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000.
+ * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000.
+ */
 
 #define LOONGSON_MMIO_MEM_START 0x10000000
-#define LOONGSON_MMIO_MEM_END   0x20000000
 
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_MMIO_MEM_END	0x20000000
+#else
+#define LOONGSON_MMIO_MEM_END	0x80000000
 #endif
 
 #endif /* __ASM_MACH_LOONGSON_MEM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/pci.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/pci.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-loongson/pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-loongson/pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
+ * Copyright (c) 2009 Wu Zhangjin <wuzj@lemote.com>
  *
  * This program is free software; you can redistribute it
  * and/or modify it under the terms of the GNU General
@@ -22,16 +23,39 @@
 #ifndef __ASM_MACH_LOONGSON_PCI_H_
 #define __ASM_MACH_LOONGSON_PCI_H_
 
-extern struct pci_ops bonito64_pci_ops;
+extern struct pci_ops loongson_pci_ops;
 
-#ifdef CONFIG_LEMOTE_FULOONG2E
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START	0x00004000UL
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/*
+ * we use address window2 to map cpu address space to pci space
+ * window2: cpu [1G, 2G] -> pci [1G, 2G]
+ * why not use window 0 & 1? because they are used by cpu when booting.
+ * window0: cpu [0, 256M] -> ddr [0, 256M]
+ * window1: cpu [256M, 512M] -> pci [256M, 512M]
+ */
+
+/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
+#define LOONGSON_CPU_MEM_SRC	0x40000000ul		/* 1G */
+#define LOONGSON_PCI_MEM_DST	LOONGSON_CPU_MEM_SRC
+
+#define LOONGSON_PCI_MEM_START	LOONGSON_PCI_MEM_DST
+#define LOONGSON_PCI_MEM_END	(0x80000000ul-1)	/* 2G */
+
+#define MMAP_CPUTOPCI_SIZE	(LOONGSON_PCI_MEM_END - \
+					LOONGSON_PCI_MEM_START + 1)
+
+#else	/* loongson2f/32bit & loongson2e */
 
 /* this pci memory space is mapped by pcimap in pci.c */
-#define LOONGSON_PCI_MEM_START	BONITO_PCILO1_BASE
-#define LOONGSON_PCI_MEM_END	(BONITO_PCILO1_BASE + 0x04000000 * 2)
+#define LOONGSON_PCI_MEM_START	LOONGSON_PCILO1_BASE
+#define LOONGSON_PCI_MEM_END	(LOONGSON_PCILO1_BASE + 0x04000000 * 2)
 /* this is an offset from mips_io_port_base */
 #define LOONGSON_PCI_IO_START	0x00004000UL
 
-#endif
+#endif	/* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
 
 #endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-pnx833x/gpio.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pnx833x/gpio.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-pnx833x/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-pnx833x/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 
 /* BIG FAT WARNING: races danger!
    No protections exist here. Current users are only early init code,
-   when locking is not needed because no cuncurency yet exists there,
+   when locking is not needed because no concurrency yet exists there,
    and GPIO IRQ dispatcher, which does locking.
    However, if many uses will ever happen, proper locking will be needed
    - including locking between different uses
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 _ASM_MACH_POWERTV_ASIC_H
+#define _ASM_MACH_POWERTV_ASIC_H
+
+#include <linux/ioport.h>
+#include <asm/mach-powertv/asic_regs.h>
+
+#define DVR_CAPABLE     (1<<0)
+#define PCIE_CAPABLE    (1<<1)
+#define FFS_CAPABLE     (1<<2)
+#define DISPLAY_CAPABLE (1<<3)
+
+/* Platform Family types
+ * For compitability, the new value must be added in the end */
+enum family_type {
+	FAMILY_8500,
+	FAMILY_8500RNG,
+	FAMILY_4500,
+	FAMILY_1500,
+	FAMILY_8600,
+	FAMILY_4600,
+	FAMILY_4600VZA,
+	FAMILY_8600VZB,
+	FAMILY_1500VZE,
+	FAMILY_1500VZF,
+	FAMILIES
+};
+
+/* Register maps for each ASIC */
+extern const struct register_map calliope_register_map;
+extern const struct register_map cronus_register_map;
+extern const struct register_map zeus_register_map;
+
+extern struct resource dvr_cronus_resources[];
+extern struct resource dvr_zeus_resources[];
+extern struct resource non_dvr_calliope_resources[];
+extern struct resource non_dvr_cronus_resources[];
+extern struct resource non_dvr_cronuslite_resources[];
+extern struct resource non_dvr_vz_calliope_resources[];
+extern struct resource non_dvr_vze_calliope_resources[];
+extern struct resource non_dvr_vzf_calliope_resources[];
+extern struct resource non_dvr_zeus_resources[];
+
+extern void powertv_platform_init(void);
+extern void platform_alloc_bootmem(void);
+extern enum asic_type platform_get_asic(void);
+extern enum family_type platform_get_family(void);
+extern int platform_supports_dvr(void);
+extern int platform_supports_ffs(void);
+extern int platform_supports_pcie(void);
+extern int platform_supports_display(void);
+extern void configure_platform(void);
+extern void platform_configure_usb_ehci(void);
+extern void platform_unconfigure_usb_ehci(void);
+extern void platform_configure_usb_ohci(void);
+extern void platform_unconfigure_usb_ohci(void);
+
+/* Platform Resources */
+#define ASIC_RESOURCE_GET_EXISTS 1
+extern struct resource *asic_resource_get(const char *name);
+extern void platform_release_memory(void *baddr, int size);
+
+/* Reboot Cause */
+extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
+extern void set_locked_reboot_cause(char code, unsigned int data,
+	unsigned int data2);
+
+enum sys_reboot_type {
+	sys_unknown_reboot = 0x00,	/* Unknown reboot cause */
+	sys_davic_change = 0x01,	/* Reboot due to change in DAVIC
+					 * mode */
+	sys_user_reboot = 0x02,		/* Reboot initiated by user */
+	sys_system_reboot = 0x03,	/* Reboot initiated by OS */
+	sys_trap_reboot = 0x04,		/* Reboot due to a CPU trap */
+	sys_silent_reboot = 0x05,	/* Silent reboot */
+	sys_boot_ldr_reboot = 0x06,	/* Bootloader reboot */
+	sys_power_up_reboot = 0x07,	/* Power on bootup.  Older
+					 * drivers may report as
+					 * userReboot. */
+	sys_code_change = 0x08,		/* Reboot to take code change.
+					 * Older drivers may report as
+					 * userReboot. */
+	sys_hardware_reset = 0x09,	/* HW watchdog or front-panel
+					 * reset button reset.  Older
+					 * drivers may report as
+					 * userReboot. */
+	sys_watchdogInterrupt = 0x0A	/* Pre-watchdog interrupt */
+};
+
+#endif /* _ASM_MACH_POWERTV_ASIC_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic_reg_map.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic_reg_map.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic_reg_map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic_reg_map.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,90 @@
+/*
+ *				asic_reg_map.h
+ *
+ * A macro-enclosed list of the elements for the register_map structure for
+ * use in defining and manipulating the structure.
+ *
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ */
+
+REGISTER_MAP_ELEMENT(eic_slow0_strt_add)
+REGISTER_MAP_ELEMENT(eic_cfg_bits)
+REGISTER_MAP_ELEMENT(eic_ready_status)
+REGISTER_MAP_ELEMENT(chipver3)
+REGISTER_MAP_ELEMENT(chipver2)
+REGISTER_MAP_ELEMENT(chipver1)
+REGISTER_MAP_ELEMENT(chipver0)
+REGISTER_MAP_ELEMENT(uart1_intstat)
+REGISTER_MAP_ELEMENT(uart1_inten)
+REGISTER_MAP_ELEMENT(uart1_config1)
+REGISTER_MAP_ELEMENT(uart1_config2)
+REGISTER_MAP_ELEMENT(uart1_divisorhi)
+REGISTER_MAP_ELEMENT(uart1_divisorlo)
+REGISTER_MAP_ELEMENT(uart1_data)
+REGISTER_MAP_ELEMENT(uart1_status)
+REGISTER_MAP_ELEMENT(int_stat_3)
+REGISTER_MAP_ELEMENT(int_stat_2)
+REGISTER_MAP_ELEMENT(int_stat_1)
+REGISTER_MAP_ELEMENT(int_stat_0)
+REGISTER_MAP_ELEMENT(int_config)
+REGISTER_MAP_ELEMENT(int_int_scan)
+REGISTER_MAP_ELEMENT(ien_int_3)
+REGISTER_MAP_ELEMENT(ien_int_2)
+REGISTER_MAP_ELEMENT(ien_int_1)
+REGISTER_MAP_ELEMENT(ien_int_0)
+REGISTER_MAP_ELEMENT(int_level_3_3)
+REGISTER_MAP_ELEMENT(int_level_3_2)
+REGISTER_MAP_ELEMENT(int_level_3_1)
+REGISTER_MAP_ELEMENT(int_level_3_0)
+REGISTER_MAP_ELEMENT(int_level_2_3)
+REGISTER_MAP_ELEMENT(int_level_2_2)
+REGISTER_MAP_ELEMENT(int_level_2_1)
+REGISTER_MAP_ELEMENT(int_level_2_0)
+REGISTER_MAP_ELEMENT(int_level_1_3)
+REGISTER_MAP_ELEMENT(int_level_1_2)
+REGISTER_MAP_ELEMENT(int_level_1_1)
+REGISTER_MAP_ELEMENT(int_level_1_0)
+REGISTER_MAP_ELEMENT(int_level_0_3)
+REGISTER_MAP_ELEMENT(int_level_0_2)
+REGISTER_MAP_ELEMENT(int_level_0_1)
+REGISTER_MAP_ELEMENT(int_level_0_0)
+REGISTER_MAP_ELEMENT(int_docsis_en)
+REGISTER_MAP_ELEMENT(mips_pll_setup)
+REGISTER_MAP_ELEMENT(usb_fs)
+REGISTER_MAP_ELEMENT(test_bus)
+REGISTER_MAP_ELEMENT(crt_spare)
+REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
+REGISTER_MAP_ELEMENT(usb2_strap)
+REGISTER_MAP_ELEMENT(ehci_hcapbase)
+REGISTER_MAP_ELEMENT(ohci_hc_revision)
+REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer)
+REGISTER_MAP_ELEMENT(usb2_control)
+REGISTER_MAP_ELEMENT(usb2_stbus_obc)
+REGISTER_MAP_ELEMENT(usb2_stbus_mess_size)
+REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size)
+REGISTER_MAP_ELEMENT(pcie_regs)
+REGISTER_MAP_ELEMENT(tim_ch)
+REGISTER_MAP_ELEMENT(tim_cl)
+REGISTER_MAP_ELEMENT(gpio_dout)
+REGISTER_MAP_ELEMENT(gpio_din)
+REGISTER_MAP_ELEMENT(gpio_dir)
+REGISTER_MAP_ELEMENT(watchdog)
+REGISTER_MAP_ELEMENT(front_panel)
+REGISTER_MAP_ELEMENT(misc_clk_ctl1)
+REGISTER_MAP_ELEMENT(misc_clk_ctl2)
+REGISTER_MAP_ELEMENT(crt_ext_ctl)
+REGISTER_MAP_ELEMENT(register_maps)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic_regs.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic_regs.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/asic_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/asic_regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 __ASM_MACH_POWERTV_ASIC_H_
+#define __ASM_MACH_POWERTV_ASIC_H_
+#include <linux/io.h>
+
+/* ASIC types */
+enum asic_type {
+	ASIC_UNKNOWN,
+	ASIC_ZEUS,
+	ASIC_CALLIOPE,
+	ASIC_CRONUS,
+	ASIC_CRONUSLITE,
+	ASICS
+};
+
+/* hardcoded values read from Chip Version registers */
+#define CRONUS_10	0x0B4C1C20
+#define CRONUS_11	0x0B4C1C21
+#define CRONUSLITE_10	0x0B4C1C40
+
+#define NAND_FLASH_BASE		0x03000000
+#define CALLIOPE_IO_BASE	0x08000000
+#define CRONUS_IO_BASE		0x09000000
+#define ZEUS_IO_BASE		0x09000000
+
+#define ASIC_IO_SIZE		0x01000000
+
+/* Definitions for backward compatibility */
+#define UART1_INTSTAT	uart1_intstat
+#define UART1_INTEN	uart1_inten
+#define UART1_CONFIG1	uart1_config1
+#define UART1_CONFIG2	uart1_config2
+#define UART1_DIVISORHI	uart1_divisorhi
+#define UART1_DIVISORLO	uart1_divisorlo
+#define UART1_DATA	uart1_data
+#define UART1_STATUS	uart1_status
+
+/* ASIC register enumeration */
+union register_map_entry {
+	unsigned long phys;
+	u32 *virt;
+};
+
+#define REGISTER_MAP_ELEMENT(x) union register_map_entry x;
+struct register_map {
+#include <asm/mach-powertv/asic_reg_map.h>
+};
+#undef REGISTER_MAP_ELEMENT
+
+/**
+ * register_map_offset_phys - add an offset to the physical address
+ * @map:	Pointer to the &struct register_map
+ * @offset:	Value to add
+ *
+ * Only adds the base to non-zero physical addresses
+ */
+static inline void register_map_offset_phys(struct register_map *map,
+	unsigned long offset)
+{
+#define REGISTER_MAP_ELEMENT(x)		do {				\
+		if (map->x.phys != 0)					\
+			map->x.phys += offset;				\
+	} while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+/**
+ * register_map_virtualize - Convert &register_map to virtual addresses
+ * @map:	Pointer to &register_map to virtualize
+ */
+static inline void register_map_virtualize(struct register_map *map)
+{
+#define REGISTER_MAP_ELEMENT(x)		do {				\
+		map->x.virt = (!map->x.phys) ? NULL :			\
+			UNCAC_ADDR(phys_to_virt(map->x.phys));		\
+	} while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+extern struct register_map _asic_register_map;
+
+/*
+ * Macros to interface to registers through their ioremapped address
+ * asic_reg_phys_addr	Returns the physical address of the given register
+ * asic_reg_addr	Returns the iomapped virtual address of the given
+ *			register.
+ */
+#define asic_reg_addr(x)	(_asic_register_map.x.virt)
+#define asic_reg_phys_addr(x)	(virt_to_phys((void *) CAC_ADDR(	\
+					(unsigned long) asic_reg_addr(x))))
+
+/*
+ * The asic_reg macro is gone. It should be replaced by either asic_read or
+ * asic_write, as appropriate.
+ */
+
+#define asic_read(x)		readl(asic_reg_addr(x))
+#define asic_write(v, x)	writel(v, asic_reg_addr(x))
+
+extern void asic_irq_init(void);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/dma-coherence.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/dma-coherence.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/dma-coherence.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/dma-coherence.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ * Version from mach-generic modified to support PowerTV port
+ * Portions Copyright (C) 2009  Cisco Systems, Inc.
+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+
+#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H
+#define __ASM_MACH_POWERTV_DMA_COHERENCE_H
+
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <asm/mach-powertv/asic.h>
+
+static inline bool is_kseg2(void *addr)
+{
+	return (unsigned long)addr >= KSEG2;
+}
+
+static inline unsigned long virt_to_phys_from_pte(void *addr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	unsigned long virt_addr = (unsigned long)addr;
+	unsigned long phys_addr = 0UL;
+
+	/* get the page global directory. */
+	pgd = pgd_offset_k(virt_addr);
+
+	if (!pgd_none(*pgd)) {
+		/* get the page upper directory */
+		pud = pud_offset(pgd, virt_addr);
+		if (!pud_none(*pud)) {
+			/* get the page middle directory */
+			pmd = pmd_offset(pud, virt_addr);
+			if (!pmd_none(*pmd)) {
+				/* get a pointer to the page table entry */
+				ptep = pte_offset(pmd, virt_addr);
+				pte = *ptep;
+				/* check for a valid page */
+				if (pte_present(pte)) {
+					/* get the physical address the page is
+					 * refering to */
+					phys_addr = (unsigned long)
+						page_to_phys(pte_page(pte));
+					/* add the offset within the page */
+					phys_addr |= (virt_addr & ~PAGE_MASK);
+				}
+			}
+		}
+	}
+
+	return phys_addr;
+}
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+	size_t size)
+{
+	if (is_kseg2(addr))
+		return phys_to_bus(virt_to_phys_from_pte(addr));
+	else
+		return phys_to_bus(virt_to_phys(addr));
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+	struct page *page)
+{
+	return phys_to_bus(page_to_phys(page));
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
+{
+	return bus_to_phys(dma_addr);
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < DMA_BIT_MASK(24))
+		return 0;
+
+	return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+	return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+					 dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+	return 0;
+}
+
+#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/interrupts.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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	_ASM_MACH_POWERTV_INTERRUPTS_H_
+#define _ASM_MACH_POWERTV_INTERRUPTS_H_
+
+/*
+ * Defines for all of the interrupt lines
+ */
+
+/* Definitions for backward compatibility */
+#define kIrq_Uart1		irq_uart1
+
+#define ibase 0
+
+/*------------- Register: int_stat_3 */
+/* 126 unused (bit 31) */
+#define irq_asc2video		(ibase+126)	/* ASC 2 Video Interrupt */
+#define irq_asc1video		(ibase+125)	/* ASC 1 Video Interrupt */
+#define irq_comms_block_wd	(ibase+124)	/* ASC 1 Video Interrupt */
+#define irq_fdma_mailbox	(ibase+123)	/* FDMA Mailbox Output */
+#define irq_fdma_gp		(ibase+122)	/* FDMA GP Output */
+#define irq_mips_pic		(ibase+121)	/* MIPS Performance Counter
+						 * Interrupt */
+#define irq_mips_timer		(ibase+120)	/* MIPS Timer Interrupt */
+#define irq_memory_protect	(ibase+119)	/* Memory Protection Interrupt
+						 * -- Ored by glue logic inside
+						 *  SPARC ILC (see
+						 *  INT_MEM_PROT_STAT, below,
+						 *  for individual interrupts)
+						 */
+/* 118 unused (bit 22) */
+#define irq_sbag		(ibase+117)	/* SBAG Interrupt -- Ored by
+						 * glue logic inside SPARC ILC
+						 * (see INT_SBAG_STAT, below,
+						 * for individual interrupts) */
+#define irq_qam_b_fec		(ibase+116)	/* QAM  B FEC Interrupt */
+#define irq_qam_a_fec		(ibase+115)	/* QAM A FEC Interrupt */
+/* 114 unused 	(bit 18) */
+#define irq_mailbox		(ibase+113)	/* Mailbox Debug Interrupt  --
+						 * Ored by glue logic inside
+						 * SPARC ILC (see
+						 * INT_MAILBOX_STAT, below, for
+						 * individual interrupts) */
+#define irq_fuse_stat1		(ibase+112)	/* Fuse Status 1 */
+#define irq_fuse_stat2		(ibase+111)	/* Fuse Status 2 */
+#define irq_fuse_stat3		(ibase+110)	/* Blitter Interrupt / Fuse
+						 * Status 3 */
+#define irq_blitter		(ibase+110)	/* Blitter Interrupt / Fuse
+						 * Status 3 */
+#define irq_avc1_pp0		(ibase+109)	/* AVC Decoder #1 PP0
+						 * Interrupt */
+#define irq_avc1_pp1		(ibase+108)	/* AVC Decoder #1 PP1
+						 * Interrupt */
+#define irq_avc1_mbe		(ibase+107)	/* AVC Decoder #1 MBE
+						 * Interrupt */
+#define irq_avc2_pp0		(ibase+106)	/* AVC Decoder #2 PP0
+						 * Interrupt */
+#define irq_avc2_pp1		(ibase+105)	/* AVC Decoder #2 PP1
+						 * Interrupt */
+#define irq_avc2_mbe		(ibase+104)	/* AVC Decoder #2 MBE
+						 * Interrupt */
+#define irq_zbug_spi		(ibase+103)	/* Zbug SPI Slave Interrupt */
+#define irq_qam_mod2		(ibase+102)	/* QAM Modulator 2 DMA
+						 * Interrupt */
+#define irq_ir_rx		(ibase+101)	/* IR RX 2 Interrupt */
+#define irq_aud_dsp2		(ibase+100)	/* Audio DSP #2 Interrupt */
+#define irq_aud_dsp1		(ibase+99)	/* Audio DSP #1 Interrupt */
+#define irq_docsis		(ibase+98)	/* DOCSIS Debug Interrupt */
+#define irq_sd_dvp1		(ibase+97)	/* SD DVP #1 Interrupt */
+#define irq_sd_dvp2		(ibase+96)	/* SD DVP #2 Interrupt */
+/*------------- Register: int_stat_2 */
+#define irq_hd_dvp		(ibase+95)	/* HD DVP Interrupt */
+#define kIrq_Prewatchdog	(ibase+94)	/* watchdog Pre-Interrupt */
+#define irq_timer2		(ibase+93)	/* Programmable Timer
+						 * Interrupt 2 */
+#define irq_1394		(ibase+92)	/* 1394 Firewire Interrupt */
+#define irq_usbohci		(ibase+91)	/* USB 2.0 OHCI Interrupt */
+#define irq_usbehci		(ibase+90)	/* USB 2.0 EHCI Interrupt */
+#define irq_pciexp		(ibase+89)	/* PCI Express 0 Interrupt */
+#define irq_pciexp0		(ibase+89)	/* PCI Express 0 Interrupt */
+#define irq_afe1		(ibase+88)	/* AFE 1 Interrupt */
+#define irq_sata		(ibase+87)	/* SATA 1 Interrupt */
+#define irq_sata1		(ibase+87)	/* SATA 1 Interrupt */
+#define irq_dtcp		(ibase+86)	/* DTCP Interrupt */
+#define irq_pciexp1		(ibase+85)	/* PCI Express 1 Interrupt */
+/* 84 unused 	(bit 20) */
+/* 83 unused 	(bit 19) */
+/* 82 unused 	(bit 18) */
+#define irq_sata2		(ibase+81)	/* SATA2 Interrupt */
+#define irq_uart2		(ibase+80)	/* UART2 Interrupt */
+#define irq_legacy_usb		(ibase+79)	/* Legacy USB Host ISR (1.1
+						 * Host module) */
+#define irq_pod			(ibase+78)	/* POD Interrupt */
+#define irq_slave_usb		(ibase+77)	/* Slave USB */
+#define irq_denc1		(ibase+76)	/* DENC #1 VTG Interrupt */
+#define irq_vbi_vtg		(ibase+75)	/* VBI VTG Interrupt */
+#define irq_afe2		(ibase+74)	/* AFE 2 Interrupt */
+#define irq_denc2		(ibase+73)	/* DENC #2 VTG Interrupt */
+#define irq_asc2		(ibase+72)	/* ASC #2 Interrupt */
+#define irq_asc1		(ibase+71)	/* ASC #1 Interrupt */
+#define irq_mod_dma		(ibase+70)	/* Modulator DMA Interrupt */
+#define irq_byte_eng1		(ibase+69)	/* Byte Engine Interrupt [1] */
+#define irq_byte_eng0		(ibase+68)	/* Byte Engine Interrupt [0] */
+/* 67 unused 	(bit 03) */
+/* 66 unused 	(bit 02) */
+/* 65 unused 	(bit 01) */
+/* 64 unused 	(bit 00) */
+/*------------- Register: int_stat_1 */
+/* 63 unused 	(bit 31) */
+/* 62 unused 	(bit 30) */
+/* 61 unused 	(bit 29) */
+/* 60 unused 	(bit 28) */
+/* 59 unused 	(bit 27) */
+/* 58 unused 	(bit 26) */
+/* 57 unused 	(bit 25) */
+/* 56 unused 	(bit 24) */
+#define irq_buf_dma_mem2mem	(ibase+55)	/* BufDMA Memory to Memory
+						 * Interrupt */
+#define irq_buf_dma_usbtransmit	(ibase+54)	/* BufDMA USB Transmit
+						 * Interrupt */
+#define irq_buf_dma_qpskpodtransmit (ibase+53)	/* BufDMA QPSK/POD Tramsit
+						 * Interrupt */
+#define irq_buf_dma_transmit_error (ibase+52)	/* BufDMA Transmit Error
+						 * Interrupt */
+#define irq_buf_dma_usbrecv	(ibase+51)	/* BufDMA USB Receive
+						 * Interrupt */
+#define irq_buf_dma_qpskpodrecv	(ibase+50)	/* BufDMA QPSK/POD Receive
+						 * Interrupt */
+#define irq_buf_dma_recv_error	(ibase+49)	/* BufDMA Receive Error
+						 * Interrupt */
+#define irq_qamdma_transmit_play (ibase+48)	/* QAMDMA Transmit/Play
+						 * Interrupt */
+#define irq_qamdma_transmit_error (ibase+47)	/* QAMDMA Transmit Error
+						 * Interrupt */
+#define irq_qamdma_recv2high	(ibase+46)	/* QAMDMA Receive 2 High
+						 * (Chans 63-32) */
+#define irq_qamdma_recv2low	(ibase+45)	/* QAMDMA Receive 2 Low
+						 * (Chans 31-0) */
+#define irq_qamdma_recv1high	(ibase+44)	/* QAMDMA Receive 1 High
+						 * (Chans 63-32) */
+#define irq_qamdma_recv1low	(ibase+43)	/* QAMDMA Receive 1 Low
+						 * (Chans 31-0) */
+#define irq_qamdma_recv_error	(ibase+42)	/* QAMDMA Receive Error
+						 * Interrupt */
+#define irq_mpegsplice		(ibase+41)	/* MPEG Splice Interrupt */
+#define irq_deinterlace_rdy	(ibase+40)	/* Deinterlacer Frame Ready
+						 * Interrupt */
+#define irq_ext_in0		(ibase+39)	/* External Interrupt irq_in0 */
+#define irq_gpio3		(ibase+38)	/* GP I/O IRQ 3 - From GP I/O
+						 * Module */
+#define irq_gpio2		(ibase+37)	/* GP I/O IRQ 2 - From GP I/O
+						 * Module (ABE_intN) */
+#define irq_pcrcmplt1		(ibase+36)	/* PCR Capture Complete  or
+						 * Discontinuity 1 */
+#define irq_pcrcmplt2		(ibase+35)	/* PCR Capture Complete or
+						 * Discontinuity 2 */
+#define irq_parse_peierr	(ibase+34)	/* PID Parser Error Detect
+						 * (PEI) */
+#define irq_parse_cont_err	(ibase+33)	/* PID Parser continuity error
+						 * detect */
+#define irq_ds1framer		(ibase+32)	/* DS1 Framer Interrupt */
+/*------------- Register: int_stat_0 */
+#define irq_gpio1		(ibase+31)	/* GP I/O IRQ 1 - From GP I/O
+						 * Module */
+#define irq_gpio0		(ibase+30)	/* GP I/O IRQ 0 - From GP I/O
+						 * Module */
+#define irq_qpsk_out_aloha	(ibase+29)	/* QPSK Output Slotted Aloha
+						 * (chan 3) Transmission
+						 * Completed OK */
+#define irq_qpsk_out_tdma	(ibase+28)	/* QPSK Output TDMA (chan 2)
+						 * Transmission Completed OK */
+#define irq_qpsk_out_reserve	(ibase+27)	/* QPSK Output Reservation
+						 * (chan 1) Transmission
+						 * Completed OK */
+#define irq_qpsk_out_aloha_err	(ibase+26)	/* QPSK Output Slotted Aloha
+						 * (chan 3)Transmission
+						 * completed with Errors. */
+#define irq_qpsk_out_tdma_err	(ibase+25)	/* QPSK Output TDMA (chan 2)
+						 * Transmission completed with
+						 * Errors. */
+#define irq_qpsk_out_rsrv_err	(ibase+24)	/* QPSK Output Reservation
+						 * (chan 1) Transmission
+						 * completed with Errors */
+#define irq_aloha_fail		(ibase+23)	/* Unsuccessful Resend of Aloha
+						 * for N times. Aloha retry
+						 * timeout for channel 3. */
+#define irq_timer1		(ibase+22)	/* Programmable Timer
+						 * Interrupt */
+#define irq_keyboard		(ibase+21)	/* Keyboard Module Interrupt */
+#define irq_i2c			(ibase+20)	/* I2C Module Interrupt */
+#define irq_spi			(ibase+19)	/* SPI Module Interrupt */
+#define irq_irblaster		(ibase+18)	/* IR Blaster Interrupt */
+#define irq_splice_detect	(ibase+17)	/* PID Key Change Interrupt or
+						 * Splice Detect Interrupt */
+#define irq_se_micro		(ibase+16)	/* Secure Micro I/F Module
+						 * Interrupt */
+#define irq_uart1		(ibase+15)	/* UART Interrupt */
+#define irq_irrecv		(ibase+14)	/* IR Receiver Interrupt */
+#define irq_host_int1		(ibase+13)	/* Host-to-Host Interrupt 1 */
+#define irq_host_int0		(ibase+12)	/* Host-to-Host Interrupt 0 */
+#define irq_qpsk_hecerr		(ibase+11)	/* QPSK HEC Error Interrupt */
+#define irq_qpsk_crcerr		(ibase+10)	/* QPSK AAL-5 CRC Error
+						 * Interrupt */
+/* 9 unused 	(bit 09) */
+/* 8 unused 	(bit 08) */
+#define irq_psicrcerr		(ibase+7) 	/* QAM PSI CRC Error
+						 * Interrupt */
+#define irq_psilength_err	(ibase+6) 	/* QAM PSI Length Error
+						 * Interrupt */
+#define irq_esfforward		(ibase+5) 	/* ESF Interrupt Mark From
+						 * Forward Path Reference -
+						 * every 3ms when forward Mbits
+						 * and forward slot control
+						 * bytes are updated. */
+#define irq_esfreverse		(ibase+4) 	/* ESF Interrupt Mark from
+						 * Reverse Path Reference -
+						 * delayed from forward mark by
+						 * the ranging delay plus a
+						 * fixed amount. When reverse
+						 * Mbits and reverse slot
+						 * control bytes are updated.
+						 * Occurs every 3ms for 3.0M and
+						 * 1.554 M upstream rates and
+						 * every 6 ms for 256K upstream
+						 * rate. */
+#define irq_aloha_timeout	(ibase+3) 	/* Slotted-Aloha timeout on
+						 * Channel 1. */
+#define irq_reservation		(ibase+2) 	/* Partial (or Incremental)
+						 * Reservation Message Completed
+						 * or Slotted aloha verify for
+						 * channel 1. */
+#define irq_aloha3		(ibase+1) 	/* Slotted-Aloha Message Verify
+						 * Interrupt or Reservation
+						 * increment completed for
+						 * channel 3. */
+#define irq_mpeg_d		(ibase+0) 	/* MPEG Decoder Interrupt */
+#endif	/* _ASM_MACH_POWERTV_INTERRUPTS_H_ */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/ioremap.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/ioremap.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/ioremap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/ioremap.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,90 @@
+/*
+ *	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.
+ *
+ * Portions Copyright (C)  Cisco Systems, Inc.
+ */
+#ifndef __ASM_MACH_POWERTV_IOREMAP_H
+#define __ASM_MACH_POWERTV_IOREMAP_H
+
+#include <linux/types.h>
+
+#define LOW_MEM_BOUNDARY_PHYS	0x20000000
+#define LOW_MEM_BOUNDARY_MASK	(~(LOW_MEM_BOUNDARY_PHYS - 1))
+
+/*
+ * The bus addresses are different than the physical addresses that
+ * the processor sees by an offset. This offset varies by ASIC
+ * version. Define a variable to hold the offset and some macros to
+ * make the conversion simpler. */
+extern unsigned long phys_to_bus_offset;
+
+#ifdef CONFIG_HIGHMEM
+#define MEM_GAP_PHYS		0x60000000
+/*
+ * TODO: We will use the hard code for conversion between physical and
+ * bus until the bootloader releases their device tree to us.
+ */
+#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \
+	((x) + phys_to_bus_offset) : (x))
+#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \
+	((x) - phys_to_bus_offset) : (x))
+#else
+#define phys_to_bus(x) ((x) + phys_to_bus_offset)
+#define bus_to_phys(x) ((x) - phys_to_bus_offset)
+#endif
+
+/*
+ * Determine whether the address we are given is for an ASIC device
+ * Params:  addr    Address to check
+ * Returns: Zero if the address is not for ASIC devices, non-zero
+ *      if it is.
+ */
+static inline int asic_is_device_addr(phys_t addr)
+{
+	return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK);
+}
+
+/*
+ * Determine whether the address we are given is external RAM mappable
+ * into KSEG1.
+ * Params:  addr    Address to check
+ * Returns: Zero if the address is not for external RAM and
+ */
+static inline int asic_is_lowmem_ram_addr(phys_t addr)
+{
+	/*
+	 * The RAM always starts at the following address in the processor's
+	 * physical address space
+	 */
+	static const phys_t phys_ram_base = 0x10000000;
+	phys_t bus_ram_base;
+
+	bus_ram_base = phys_to_bus_offset + phys_ram_base;
+
+	return addr >= bus_ram_base &&
+		addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base));
+}
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+	unsigned long flags)
+{
+	return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+	return 0;
+}
+#endif /* __ASM_MACH_POWERTV_IOREMAP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/irq.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/irq.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 _ASM_MACH_POWERTV_IRQ_H
+#define _ASM_MACH_POWERTV_IRQ_H
+#include <asm/mach-powertv/interrupts.h>
+
+#define MIPS_CPU_IRQ_BASE	ibase
+#define NR_IRQS			127
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/powertv-clock.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/powertv-clock.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/powertv-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/powertv-clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ */
+/*
+ * Local definitions for the powertv PCI code
+ */
+
+#ifndef _POWERTV_PCI_POWERTV_PCI_H_
+#define _POWERTV_PCI_POWERTV_PCI_H_
+extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int asic_pcie_init(void);
+extern int asic_pcie_init(void);
+
+extern int log_level;
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/war.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/war.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mach-powertv/war.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mach-powertv/war.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ * This version for the PowerTV platform copied from the Malta version.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ */
+#ifndef __ASM_MACH_POWERTV_WAR_H
+#define __ASM_MACH_POWERTV_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	1
+#define MIPS_CACHE_SYNC_WAR		1
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	1
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MACH_POWERTV_WAR_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mips-boards/bonito64.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mips-boards/bonito64.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mips-boards/bonito64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mips-boards/bonito64.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,11 +26,6 @@
 /* offsets from base register */
 #define BONITO(x)	(x)
 
-#elif defined(CONFIG_LEMOTE_FULOONG2E)
-
-#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
-#define BONITO_IRQ_BASE   32
-
 #else
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mipsregs.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mipsregs.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mipsregs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mipsregs.h	2010-02-24 13:52:17.000000000 -0500
@@ -406,6 +406,16 @@
 #define ST0_XX			0x80000000	/* MIPS IV naming */
 
 /*
+ * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2)
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define INTCTLB_IPPCI		26
+#define INTCTLF_IPPCI		(_ULCAST_(7) << INTCTLB_IPPCI)
+#define INTCTLB_IPTI		29
+#define INTCTLF_IPTI		(_ULCAST_(7) << INTCTLB_IPTI)
+
+/*
  * Bitfields and bit numbers in the coprocessor 0 cause register.
  *
  * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
@@ -434,6 +444,8 @@
 #define  CAUSEF_IV		(_ULCAST_(1)   << 23)
 #define  CAUSEB_CE		28
 #define  CAUSEF_CE		(_ULCAST_(3)   << 28)
+#define  CAUSEB_TI		30
+#define  CAUSEF_TI		(_ULCAST_(1)   << 30)
 #define  CAUSEB_BD		31
 #define  CAUSEF_BD		(_ULCAST_(1)   << 31)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/mmu_context.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu_context.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/mmu_context.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,33 @@
 #endif /* SMTC */
 #include <asm-generic/mm_hooks.h>
 
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+
+#define TLBMISS_HANDLER_SETUP_PGD(pgd)				\
+	tlbmiss_handler_setup_pgd((unsigned long)(pgd))
+
+static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
+{
+	/* Check for swapper_pg_dir and convert to physical address. */
+	if ((pgd & CKSEG3) == CKSEG0)
+		pgd = CPHYSADDR(pgd);
+	write_c0_context(pgd << 11);
+}
+
+#define TLBMISS_HANDLER_SETUP()						\
+	do {								\
+		TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);		\
+		write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+	} while (0)
+
+
+static inline unsigned long get_current_pgd(void)
+{
+	return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
+}
+
+#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
+
 /*
  * For the fast tlb miss handlers, we keep a per cpu array of pointers
  * to the current pgd for each processor. Also, the proc. id is stuffed
@@ -46,7 +73,7 @@ extern unsigned long pgd_current[];
 	back_to_back_c0_hazard();					\
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define ASID_INC	0x40
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-agl-defs.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-agl-defs.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-agl-defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-agl-defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1194 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_AGL_DEFS_H__
+#define __CVMX_AGL_DEFS_H__
+
+#define CVMX_AGL_GMX_BAD_REG \
+	 CVMX_ADD_IO_SEG(0x00011800E0000518ull)
+#define CVMX_AGL_GMX_BIST \
+	 CVMX_ADD_IO_SEG(0x00011800E0000400ull)
+#define CVMX_AGL_GMX_DRV_CTL \
+	 CVMX_ADD_IO_SEG(0x00011800E00007F0ull)
+#define CVMX_AGL_GMX_INF_MODE \
+	 CVMX_ADD_IO_SEG(0x00011800E00007F8ull)
+#define CVMX_AGL_GMX_PRTX_CFG(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_DECISION(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_IFG(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_INT_EN(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_INT_REG(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_JABBER(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8))
+#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8))
+#define CVMX_AGL_GMX_RX_BP_ONX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8))
+#define CVMX_AGL_GMX_RX_PRT_INFO \
+	 CVMX_ADD_IO_SEG(0x00011800E00004E8ull)
+#define CVMX_AGL_GMX_RX_TX_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011800E00007E8ull)
+#define CVMX_AGL_GMX_SMACX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_STAT_BP \
+	 CVMX_ADD_IO_SEG(0x00011800E0000520ull)
+#define CVMX_AGL_GMX_TXX_APPEND(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT0(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT1(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT2(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT3(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT4(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT5(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT6(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT7(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT8(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STAT9(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TXX_THRESH(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048))
+#define CVMX_AGL_GMX_TX_BP \
+	 CVMX_ADD_IO_SEG(0x00011800E00004D0ull)
+#define CVMX_AGL_GMX_TX_COL_ATTEMPT \
+	 CVMX_ADD_IO_SEG(0x00011800E0000498ull)
+#define CVMX_AGL_GMX_TX_IFG \
+	 CVMX_ADD_IO_SEG(0x00011800E0000488ull)
+#define CVMX_AGL_GMX_TX_INT_EN \
+	 CVMX_ADD_IO_SEG(0x00011800E0000508ull)
+#define CVMX_AGL_GMX_TX_INT_REG \
+	 CVMX_ADD_IO_SEG(0x00011800E0000500ull)
+#define CVMX_AGL_GMX_TX_JAM \
+	 CVMX_ADD_IO_SEG(0x00011800E0000490ull)
+#define CVMX_AGL_GMX_TX_LFSR \
+	 CVMX_ADD_IO_SEG(0x00011800E00004F8ull)
+#define CVMX_AGL_GMX_TX_OVR_BP \
+	 CVMX_ADD_IO_SEG(0x00011800E00004C8ull)
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \
+	 CVMX_ADD_IO_SEG(0x00011800E00004A0ull)
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \
+	 CVMX_ADD_IO_SEG(0x00011800E00004A8ull)
+
+union cvmx_agl_gmx_bad_reg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_bad_reg_s {
+		uint64_t reserved_38_63:26;
+		uint64_t txpsh1:1;
+		uint64_t txpop1:1;
+		uint64_t ovrflw1:1;
+		uint64_t txpsh:1;
+		uint64_t txpop:1;
+		uint64_t ovrflw:1;
+		uint64_t reserved_27_31:5;
+		uint64_t statovr:1;
+		uint64_t reserved_23_25:3;
+		uint64_t loststat:1;
+		uint64_t reserved_4_21:18;
+		uint64_t out_ovr:2;
+		uint64_t reserved_0_1:2;
+	} s;
+	struct cvmx_agl_gmx_bad_reg_s cn52xx;
+	struct cvmx_agl_gmx_bad_reg_s cn52xxp1;
+	struct cvmx_agl_gmx_bad_reg_cn56xx {
+		uint64_t reserved_35_63:29;
+		uint64_t txpsh:1;
+		uint64_t txpop:1;
+		uint64_t ovrflw:1;
+		uint64_t reserved_27_31:5;
+		uint64_t statovr:1;
+		uint64_t reserved_23_25:3;
+		uint64_t loststat:1;
+		uint64_t reserved_3_21:19;
+		uint64_t out_ovr:1;
+		uint64_t reserved_0_1:2;
+	} cn56xx;
+	struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_bist {
+	uint64_t u64;
+	struct cvmx_agl_gmx_bist_s {
+		uint64_t reserved_10_63:54;
+		uint64_t status:10;
+	} s;
+	struct cvmx_agl_gmx_bist_s cn52xx;
+	struct cvmx_agl_gmx_bist_s cn52xxp1;
+	struct cvmx_agl_gmx_bist_s cn56xx;
+	struct cvmx_agl_gmx_bist_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_drv_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_drv_ctl_s {
+		uint64_t reserved_49_63:15;
+		uint64_t byp_en1:1;
+		uint64_t reserved_45_47:3;
+		uint64_t pctl1:5;
+		uint64_t reserved_37_39:3;
+		uint64_t nctl1:5;
+		uint64_t reserved_17_31:15;
+		uint64_t byp_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t nctl:5;
+	} s;
+	struct cvmx_agl_gmx_drv_ctl_s cn52xx;
+	struct cvmx_agl_gmx_drv_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_drv_ctl_cn56xx {
+		uint64_t reserved_17_63:47;
+		uint64_t byp_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t nctl:5;
+	} cn56xx;
+	struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_inf_mode {
+	uint64_t u64;
+	struct cvmx_agl_gmx_inf_mode_s {
+		uint64_t reserved_2_63:62;
+		uint64_t en:1;
+		uint64_t reserved_0_0:1;
+	} s;
+	struct cvmx_agl_gmx_inf_mode_s cn52xx;
+	struct cvmx_agl_gmx_inf_mode_s cn52xxp1;
+	struct cvmx_agl_gmx_inf_mode_s cn56xx;
+	struct cvmx_agl_gmx_inf_mode_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_prtx_cfg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_prtx_cfg_s {
+		uint64_t reserved_6_63:58;
+		uint64_t tx_en:1;
+		uint64_t rx_en:1;
+		uint64_t slottime:1;
+		uint64_t duplex:1;
+		uint64_t speed:1;
+		uint64_t en:1;
+	} s;
+	struct cvmx_agl_gmx_prtx_cfg_s cn52xx;
+	struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1;
+	struct cvmx_agl_gmx_prtx_cfg_s cn56xx;
+	struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam0 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam1 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam2 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam3 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam4 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam5 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam_en {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s {
+		uint64_t reserved_8_63:56;
+		uint64_t en:8;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s {
+		uint64_t reserved_4_63:60;
+		uint64_t cam_mode:1;
+		uint64_t mcst:2;
+		uint64_t bcst:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_decision {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_decision_s {
+		uint64_t reserved_5_63:59;
+		uint64_t cnt:5;
+	} s;
+	struct cvmx_agl_gmx_rxx_decision_s cn52xx;
+	struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_decision_s cn56xx;
+	struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_chk {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_frm_chk_s {
+		uint64_t reserved_9_63:55;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s {
+		uint64_t reserved_10_63:54;
+		uint64_t pre_align:1;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_max {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_frm_max_s {
+		uint64_t reserved_16_63:48;
+		uint64_t len:16;
+	} s;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn52xx;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_min {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_frm_min_s {
+		uint64_t reserved_16_63:48;
+		uint64_t len:16;
+	} s;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn52xx;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_ifg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_ifg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t ifg:4;
+	} s;
+	struct cvmx_agl_gmx_rxx_ifg_s cn52xx;
+	struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
+	struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_int_en {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_int_en_s {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_int_en_s cn52xx;
+	struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_int_en_s cn56xx;
+	struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_int_reg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_int_reg_s {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn52xx;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn56xx;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_jabber {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_jabber_s {
+		uint64_t reserved_16_63:48;
+		uint64_t cnt:16;
+	} s;
+	struct cvmx_agl_gmx_rxx_jabber_s cn52xx;
+	struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
+	struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_pause_drop_time {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s {
+		uint64_t reserved_16_63:48;
+		uint64_t status:16;
+	} s;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rd_clr:1;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_octs_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_dmac {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_drp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_bad {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_dmac {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_drp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rxx_udd_skp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rxx_udd_skp_s {
+		uint64_t reserved_9_63:55;
+		uint64_t fcssel:1;
+		uint64_t reserved_7_7:1;
+		uint64_t len:7;
+	} s;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_dropx {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rx_bp_dropx_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mark:6;
+	} s;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_offx {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rx_bp_offx_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mark:6;
+	} s;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn52xx;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_onx {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rx_bp_onx_s {
+		uint64_t reserved_9_63:55;
+		uint64_t mark:9;
+	} s;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn52xx;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_rx_prt_info {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rx_prt_info_s {
+		uint64_t reserved_18_63:46;
+		uint64_t drop:2;
+		uint64_t reserved_2_15:14;
+		uint64_t commit:2;
+	} s;
+	struct cvmx_agl_gmx_rx_prt_info_s cn52xx;
+	struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1;
+	struct cvmx_agl_gmx_rx_prt_info_cn56xx {
+		uint64_t reserved_17_63:47;
+		uint64_t drop:1;
+		uint64_t reserved_1_15:15;
+		uint64_t commit:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_rx_tx_status {
+	uint64_t u64;
+	struct cvmx_agl_gmx_rx_tx_status_s {
+		uint64_t reserved_6_63:58;
+		uint64_t tx:2;
+		uint64_t reserved_2_3:2;
+		uint64_t rx:2;
+	} s;
+	struct cvmx_agl_gmx_rx_tx_status_s cn52xx;
+	struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1;
+	struct cvmx_agl_gmx_rx_tx_status_cn56xx {
+		uint64_t reserved_5_63:59;
+		uint64_t tx:1;
+		uint64_t reserved_1_3:3;
+		uint64_t rx:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_smacx {
+	uint64_t u64;
+	struct cvmx_agl_gmx_smacx_s {
+		uint64_t reserved_48_63:16;
+		uint64_t smac:48;
+	} s;
+	struct cvmx_agl_gmx_smacx_s cn52xx;
+	struct cvmx_agl_gmx_smacx_s cn52xxp1;
+	struct cvmx_agl_gmx_smacx_s cn56xx;
+	struct cvmx_agl_gmx_smacx_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_stat_bp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_stat_bp_s {
+		uint64_t reserved_17_63:47;
+		uint64_t bp:1;
+		uint64_t cnt:16;
+	} s;
+	struct cvmx_agl_gmx_stat_bp_s cn52xx;
+	struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
+	struct cvmx_agl_gmx_stat_bp_s cn56xx;
+	struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_append {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_append_s {
+		uint64_t reserved_4_63:60;
+		uint64_t force_fcs:1;
+		uint64_t fcs:1;
+		uint64_t pad:1;
+		uint64_t preamble:1;
+	} s;
+	struct cvmx_agl_gmx_txx_append_s cn52xx;
+	struct cvmx_agl_gmx_txx_append_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_append_s cn56xx;
+	struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_ctl_s {
+		uint64_t reserved_2_63:62;
+		uint64_t xsdef_en:1;
+		uint64_t xscol_en:1;
+	} s;
+	struct cvmx_agl_gmx_txx_ctl_s cn52xx;
+	struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_ctl_s cn56xx;
+	struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_min_pkt {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_min_pkt_s {
+		uint64_t reserved_8_63:56;
+		uint64_t min_size:8;
+	} s;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn52xx;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_pkt_interval {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s {
+		uint64_t reserved_16_63:48;
+		uint64_t interval:16;
+	} s;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_pkt_time {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} s;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_togo {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_pause_togo_s {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} s;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn52xx;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_zero {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_pause_zero_s {
+		uint64_t reserved_1_63:63;
+		uint64_t send:1;
+	} s;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn52xx;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_soft_pause {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_soft_pause_s {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} s;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn52xx;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat0 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat0_s {
+		uint64_t xsdef:32;
+		uint64_t xscol:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat0_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat0_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat1 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat1_s {
+		uint64_t scol:32;
+		uint64_t mcol:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat1_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat1_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat2 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat2_s {
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+	} s;
+	struct cvmx_agl_gmx_txx_stat2_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat2_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat3 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat3_s {
+		uint64_t reserved_32_63:32;
+		uint64_t pkts:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat3_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat3_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat4 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat4_s {
+		uint64_t hist1:32;
+		uint64_t hist0:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat4_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat4_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat5 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat5_s {
+		uint64_t hist3:32;
+		uint64_t hist2:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat5_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat5_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat6 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat6_s {
+		uint64_t hist5:32;
+		uint64_t hist4:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat6_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat6_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat7 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat7_s {
+		uint64_t hist7:32;
+		uint64_t hist6:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat7_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat7_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat8 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat8_s {
+		uint64_t mcst:32;
+		uint64_t bcst:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat8_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat8_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat9 {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stat9_s {
+		uint64_t undflw:32;
+		uint64_t ctl:32;
+	} s;
+	struct cvmx_agl_gmx_txx_stat9_s cn52xx;
+	struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stat9_s cn56xx;
+	struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_stats_ctl {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_stats_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rd_clr:1;
+	} s;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_txx_thresh {
+	uint64_t u64;
+	struct cvmx_agl_gmx_txx_thresh_s {
+		uint64_t reserved_6_63:58;
+		uint64_t cnt:6;
+	} s;
+	struct cvmx_agl_gmx_txx_thresh_s cn52xx;
+	struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
+	struct cvmx_agl_gmx_txx_thresh_s cn56xx;
+	struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_bp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_bp_s {
+		uint64_t reserved_2_63:62;
+		uint64_t bp:2;
+	} s;
+	struct cvmx_agl_gmx_tx_bp_s cn52xx;
+	struct cvmx_agl_gmx_tx_bp_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_bp_cn56xx {
+		uint64_t reserved_1_63:63;
+		uint64_t bp:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_col_attempt {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_col_attempt_s {
+		uint64_t reserved_5_63:59;
+		uint64_t limit:5;
+	} s;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn52xx;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_ifg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_ifg_s {
+		uint64_t reserved_8_63:56;
+		uint64_t ifg2:4;
+		uint64_t ifg1:4;
+	} s;
+	struct cvmx_agl_gmx_tx_ifg_s cn52xx;
+	struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_ifg_s cn56xx;
+	struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_int_en {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_int_en_s {
+		uint64_t reserved_18_63:46;
+		uint64_t late_col:2;
+		uint64_t reserved_14_15:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xscol:2;
+		uint64_t reserved_4_7:4;
+		uint64_t undflw:2;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} s;
+	struct cvmx_agl_gmx_tx_int_en_s cn52xx;
+	struct cvmx_agl_gmx_tx_int_en_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_int_en_cn56xx {
+		uint64_t reserved_17_63:47;
+		uint64_t late_col:1;
+		uint64_t reserved_13_15:3;
+		uint64_t xsdef:1;
+		uint64_t reserved_9_11:3;
+		uint64_t xscol:1;
+		uint64_t reserved_3_7:5;
+		uint64_t undflw:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_int_reg {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_int_reg_s {
+		uint64_t reserved_18_63:46;
+		uint64_t late_col:2;
+		uint64_t reserved_14_15:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xscol:2;
+		uint64_t reserved_4_7:4;
+		uint64_t undflw:2;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} s;
+	struct cvmx_agl_gmx_tx_int_reg_s cn52xx;
+	struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_int_reg_cn56xx {
+		uint64_t reserved_17_63:47;
+		uint64_t late_col:1;
+		uint64_t reserved_13_15:3;
+		uint64_t xsdef:1;
+		uint64_t reserved_9_11:3;
+		uint64_t xscol:1;
+		uint64_t reserved_3_7:5;
+		uint64_t undflw:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_jam {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_jam_s {
+		uint64_t reserved_8_63:56;
+		uint64_t jam:8;
+	} s;
+	struct cvmx_agl_gmx_tx_jam_s cn52xx;
+	struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_jam_s cn56xx;
+	struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_lfsr {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_lfsr_s {
+		uint64_t reserved_16_63:48;
+		uint64_t lfsr:16;
+	} s;
+	struct cvmx_agl_gmx_tx_lfsr_s cn52xx;
+	struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
+	struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_ovr_bp {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_ovr_bp_s {
+		uint64_t reserved_10_63:54;
+		uint64_t en:2;
+		uint64_t reserved_6_7:2;
+		uint64_t bp:2;
+		uint64_t reserved_2_3:2;
+		uint64_t ign_full:2;
+	} s;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_ovr_bp_cn56xx {
+		uint64_t reserved_9_63:55;
+		uint64_t en:1;
+		uint64_t reserved_5_7:3;
+		uint64_t bp:1;
+		uint64_t reserved_1_3:3;
+		uint64_t ign_full:1;
+	} cn56xx;
+	struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_pause_pkt_dmac {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s {
+		uint64_t reserved_48_63:16;
+		uint64_t dmac:48;
+	} s;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_tx_pause_pkt_type {
+	uint64_t u64;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s {
+		uint64_t reserved_16_63:48;
+		uint64_t type:16;
+	} s;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-mixx-defs.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-mixx-defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-mixx-defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,248 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MIXX_DEFS_H__
+#define __CVMX_MIXX_DEFS_H__
+
+#define CVMX_MIXX_BIST(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_CTL(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_INTENA(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_IRCNT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_IRHWM(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_IRING1(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_IRING2(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_ISR(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_ORCNT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_ORHWM(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_ORING1(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_ORING2(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_REMCNT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048))
+
+union cvmx_mixx_bist {
+	uint64_t u64;
+	struct cvmx_mixx_bist_s {
+		uint64_t reserved_4_63:60;
+		uint64_t mrqdat:1;
+		uint64_t ipfdat:1;
+		uint64_t irfdat:1;
+		uint64_t orfdat:1;
+	} s;
+	struct cvmx_mixx_bist_s cn52xx;
+	struct cvmx_mixx_bist_s cn52xxp1;
+	struct cvmx_mixx_bist_s cn56xx;
+	struct cvmx_mixx_bist_s cn56xxp1;
+};
+
+union cvmx_mixx_ctl {
+	uint64_t u64;
+	struct cvmx_mixx_ctl_s {
+		uint64_t reserved_8_63:56;
+		uint64_t crc_strip:1;
+		uint64_t busy:1;
+		uint64_t en:1;
+		uint64_t reset:1;
+		uint64_t lendian:1;
+		uint64_t nbtarb:1;
+		uint64_t mrq_hwm:2;
+	} s;
+	struct cvmx_mixx_ctl_s cn52xx;
+	struct cvmx_mixx_ctl_s cn52xxp1;
+	struct cvmx_mixx_ctl_s cn56xx;
+	struct cvmx_mixx_ctl_s cn56xxp1;
+};
+
+union cvmx_mixx_intena {
+	uint64_t u64;
+	struct cvmx_mixx_intena_s {
+		uint64_t reserved_7_63:57;
+		uint64_t orunena:1;
+		uint64_t irunena:1;
+		uint64_t data_drpena:1;
+		uint64_t ithena:1;
+		uint64_t othena:1;
+		uint64_t ivfena:1;
+		uint64_t ovfena:1;
+	} s;
+	struct cvmx_mixx_intena_s cn52xx;
+	struct cvmx_mixx_intena_s cn52xxp1;
+	struct cvmx_mixx_intena_s cn56xx;
+	struct cvmx_mixx_intena_s cn56xxp1;
+};
+
+union cvmx_mixx_ircnt {
+	uint64_t u64;
+	struct cvmx_mixx_ircnt_s {
+		uint64_t reserved_20_63:44;
+		uint64_t ircnt:20;
+	} s;
+	struct cvmx_mixx_ircnt_s cn52xx;
+	struct cvmx_mixx_ircnt_s cn52xxp1;
+	struct cvmx_mixx_ircnt_s cn56xx;
+	struct cvmx_mixx_ircnt_s cn56xxp1;
+};
+
+union cvmx_mixx_irhwm {
+	uint64_t u64;
+	struct cvmx_mixx_irhwm_s {
+		uint64_t reserved_40_63:24;
+		uint64_t ibplwm:20;
+		uint64_t irhwm:20;
+	} s;
+	struct cvmx_mixx_irhwm_s cn52xx;
+	struct cvmx_mixx_irhwm_s cn52xxp1;
+	struct cvmx_mixx_irhwm_s cn56xx;
+	struct cvmx_mixx_irhwm_s cn56xxp1;
+};
+
+union cvmx_mixx_iring1 {
+	uint64_t u64;
+	struct cvmx_mixx_iring1_s {
+		uint64_t reserved_60_63:4;
+		uint64_t isize:20;
+		uint64_t reserved_36_39:4;
+		uint64_t ibase:33;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_mixx_iring1_s cn52xx;
+	struct cvmx_mixx_iring1_s cn52xxp1;
+	struct cvmx_mixx_iring1_s cn56xx;
+	struct cvmx_mixx_iring1_s cn56xxp1;
+};
+
+union cvmx_mixx_iring2 {
+	uint64_t u64;
+	struct cvmx_mixx_iring2_s {
+		uint64_t reserved_52_63:12;
+		uint64_t itlptr:20;
+		uint64_t reserved_20_31:12;
+		uint64_t idbell:20;
+	} s;
+	struct cvmx_mixx_iring2_s cn52xx;
+	struct cvmx_mixx_iring2_s cn52xxp1;
+	struct cvmx_mixx_iring2_s cn56xx;
+	struct cvmx_mixx_iring2_s cn56xxp1;
+};
+
+union cvmx_mixx_isr {
+	uint64_t u64;
+	struct cvmx_mixx_isr_s {
+		uint64_t reserved_7_63:57;
+		uint64_t orun:1;
+		uint64_t irun:1;
+		uint64_t data_drp:1;
+		uint64_t irthresh:1;
+		uint64_t orthresh:1;
+		uint64_t idblovf:1;
+		uint64_t odblovf:1;
+	} s;
+	struct cvmx_mixx_isr_s cn52xx;
+	struct cvmx_mixx_isr_s cn52xxp1;
+	struct cvmx_mixx_isr_s cn56xx;
+	struct cvmx_mixx_isr_s cn56xxp1;
+};
+
+union cvmx_mixx_orcnt {
+	uint64_t u64;
+	struct cvmx_mixx_orcnt_s {
+		uint64_t reserved_20_63:44;
+		uint64_t orcnt:20;
+	} s;
+	struct cvmx_mixx_orcnt_s cn52xx;
+	struct cvmx_mixx_orcnt_s cn52xxp1;
+	struct cvmx_mixx_orcnt_s cn56xx;
+	struct cvmx_mixx_orcnt_s cn56xxp1;
+};
+
+union cvmx_mixx_orhwm {
+	uint64_t u64;
+	struct cvmx_mixx_orhwm_s {
+		uint64_t reserved_20_63:44;
+		uint64_t orhwm:20;
+	} s;
+	struct cvmx_mixx_orhwm_s cn52xx;
+	struct cvmx_mixx_orhwm_s cn52xxp1;
+	struct cvmx_mixx_orhwm_s cn56xx;
+	struct cvmx_mixx_orhwm_s cn56xxp1;
+};
+
+union cvmx_mixx_oring1 {
+	uint64_t u64;
+	struct cvmx_mixx_oring1_s {
+		uint64_t reserved_60_63:4;
+		uint64_t osize:20;
+		uint64_t reserved_36_39:4;
+		uint64_t obase:33;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_mixx_oring1_s cn52xx;
+	struct cvmx_mixx_oring1_s cn52xxp1;
+	struct cvmx_mixx_oring1_s cn56xx;
+	struct cvmx_mixx_oring1_s cn56xxp1;
+};
+
+union cvmx_mixx_oring2 {
+	uint64_t u64;
+	struct cvmx_mixx_oring2_s {
+		uint64_t reserved_52_63:12;
+		uint64_t otlptr:20;
+		uint64_t reserved_20_31:12;
+		uint64_t odbell:20;
+	} s;
+	struct cvmx_mixx_oring2_s cn52xx;
+	struct cvmx_mixx_oring2_s cn52xxp1;
+	struct cvmx_mixx_oring2_s cn56xx;
+	struct cvmx_mixx_oring2_s cn56xxp1;
+};
+
+union cvmx_mixx_remcnt {
+	uint64_t u64;
+	struct cvmx_mixx_remcnt_s {
+		uint64_t reserved_52_63:12;
+		uint64_t iremcnt:20;
+		uint64_t reserved_20_31:12;
+		uint64_t oremcnt:20;
+	} s;
+	struct cvmx_mixx_remcnt_s cn52xx;
+	struct cvmx_mixx_remcnt_s cn52xxp1;
+	struct cvmx_mixx_remcnt_s cn56xx;
+	struct cvmx_mixx_remcnt_s cn56xxp1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-smix-defs.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-smix-defs.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/cvmx-smix-defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/cvmx-smix-defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,178 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SMIX_DEFS_H__
+#define __CVMX_SMIX_DEFS_H__
+
+#define CVMX_SMIX_CLK(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_CMD(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_EN(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_RD_DAT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_WR_DAT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
+
+union cvmx_smix_clk {
+	uint64_t u64;
+	struct cvmx_smix_clk_s {
+		uint64_t reserved_25_63:39;
+		uint64_t mode:1;
+		uint64_t reserved_21_23:3;
+		uint64_t sample_hi:5;
+		uint64_t sample_mode:1;
+		uint64_t reserved_14_14:1;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} s;
+	struct cvmx_smix_clk_cn30xx {
+		uint64_t reserved_21_63:43;
+		uint64_t sample_hi:5;
+		uint64_t reserved_14_15:2;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} cn30xx;
+	struct cvmx_smix_clk_cn30xx cn31xx;
+	struct cvmx_smix_clk_cn30xx cn38xx;
+	struct cvmx_smix_clk_cn30xx cn38xxp2;
+	struct cvmx_smix_clk_cn50xx {
+		uint64_t reserved_25_63:39;
+		uint64_t mode:1;
+		uint64_t reserved_21_23:3;
+		uint64_t sample_hi:5;
+		uint64_t reserved_14_15:2;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} cn50xx;
+	struct cvmx_smix_clk_s cn52xx;
+	struct cvmx_smix_clk_cn50xx cn52xxp1;
+	struct cvmx_smix_clk_s cn56xx;
+	struct cvmx_smix_clk_cn50xx cn56xxp1;
+	struct cvmx_smix_clk_cn30xx cn58xx;
+	struct cvmx_smix_clk_cn30xx cn58xxp1;
+};
+
+union cvmx_smix_cmd {
+	uint64_t u64;
+	struct cvmx_smix_cmd_s {
+		uint64_t reserved_18_63:46;
+		uint64_t phy_op:2;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t reg_adr:5;
+	} s;
+	struct cvmx_smix_cmd_cn30xx {
+		uint64_t reserved_17_63:47;
+		uint64_t phy_op:1;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t reg_adr:5;
+	} cn30xx;
+	struct cvmx_smix_cmd_cn30xx cn31xx;
+	struct cvmx_smix_cmd_cn30xx cn38xx;
+	struct cvmx_smix_cmd_cn30xx cn38xxp2;
+	struct cvmx_smix_cmd_s cn50xx;
+	struct cvmx_smix_cmd_s cn52xx;
+	struct cvmx_smix_cmd_s cn52xxp1;
+	struct cvmx_smix_cmd_s cn56xx;
+	struct cvmx_smix_cmd_s cn56xxp1;
+	struct cvmx_smix_cmd_cn30xx cn58xx;
+	struct cvmx_smix_cmd_cn30xx cn58xxp1;
+};
+
+union cvmx_smix_en {
+	uint64_t u64;
+	struct cvmx_smix_en_s {
+		uint64_t reserved_1_63:63;
+		uint64_t en:1;
+	} s;
+	struct cvmx_smix_en_s cn30xx;
+	struct cvmx_smix_en_s cn31xx;
+	struct cvmx_smix_en_s cn38xx;
+	struct cvmx_smix_en_s cn38xxp2;
+	struct cvmx_smix_en_s cn50xx;
+	struct cvmx_smix_en_s cn52xx;
+	struct cvmx_smix_en_s cn52xxp1;
+	struct cvmx_smix_en_s cn56xx;
+	struct cvmx_smix_en_s cn56xxp1;
+	struct cvmx_smix_en_s cn58xx;
+	struct cvmx_smix_en_s cn58xxp1;
+};
+
+union cvmx_smix_rd_dat {
+	uint64_t u64;
+	struct cvmx_smix_rd_dat_s {
+		uint64_t reserved_18_63:46;
+		uint64_t pending:1;
+		uint64_t val:1;
+		uint64_t dat:16;
+	} s;
+	struct cvmx_smix_rd_dat_s cn30xx;
+	struct cvmx_smix_rd_dat_s cn31xx;
+	struct cvmx_smix_rd_dat_s cn38xx;
+	struct cvmx_smix_rd_dat_s cn38xxp2;
+	struct cvmx_smix_rd_dat_s cn50xx;
+	struct cvmx_smix_rd_dat_s cn52xx;
+	struct cvmx_smix_rd_dat_s cn52xxp1;
+	struct cvmx_smix_rd_dat_s cn56xx;
+	struct cvmx_smix_rd_dat_s cn56xxp1;
+	struct cvmx_smix_rd_dat_s cn58xx;
+	struct cvmx_smix_rd_dat_s cn58xxp1;
+};
+
+union cvmx_smix_wr_dat {
+	uint64_t u64;
+	struct cvmx_smix_wr_dat_s {
+		uint64_t reserved_18_63:46;
+		uint64_t pending:1;
+		uint64_t val:1;
+		uint64_t dat:16;
+	} s;
+	struct cvmx_smix_wr_dat_s cn30xx;
+	struct cvmx_smix_wr_dat_s cn31xx;
+	struct cvmx_smix_wr_dat_s cn38xx;
+	struct cvmx_smix_wr_dat_s cn38xxp2;
+	struct cvmx_smix_wr_dat_s cn50xx;
+	struct cvmx_smix_wr_dat_s cn52xx;
+	struct cvmx_smix_wr_dat_s cn52xxp1;
+	struct cvmx_smix_wr_dat_s cn56xx;
+	struct cvmx_smix_wr_dat_s cn56xxp1;
+	struct cvmx_smix_wr_dat_s cn58xx;
+	struct cvmx_smix_wr_dat_s cn58xxp1;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/octeon.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/octeon/octeon.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/octeon/octeon.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,7 @@ struct octeon_cop2_state;
 extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state);
 extern void octeon_crypto_disable(struct octeon_cop2_state *state,
 				  unsigned long flags);
+extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
 
 extern void octeon_init_cvmcount(void);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/pgtable-64.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-64.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/pgtable-64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable-64.h	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,9 @@
 #define VMALLOC_START		MAP_BASE
 #define VMALLOC_END	\
 	(VMALLOC_START + \
-	 PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32))
+	 min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
+	     (1UL << cpu_vmbits)) - (1UL << 32))
+
 #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
 	VMALLOC_START != CKSSEG
 /* Load modules into 32bit-compatible segment. */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -390,6 +390,19 @@ static inline int io_remap_pfn_range(str
 #include <asm-generic/pgtable.h>
 
 /*
+ * uncached accelerated TLB map for video memory access
+ */
+#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+struct file;
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+		unsigned long size, pgprot_t vma_prot);
+int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
+		unsigned long size, pgprot_t *vma_prot);
+#endif
+
+/*
  * We provide our own get_unmapped area to cope with the virtual aliasing
  * constraints placed on us by the cache architecture.
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/sgi/ioc.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgi/ioc.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/sgi/ioc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgi/ioc.h	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ struct sgioc_regs {
 	u32 _unused5;
 	u8 _write[3];
 	volatile u8 write;
-#define SGIOC_WRITE_NTHRESH	0x01	/* use 4.5db threshhold */
+#define SGIOC_WRITE_NTHRESH	0x01	/* use 4.5db threshold */
 #define SGIOC_WRITE_TPSPEED	0x02	/* use 100ohm TP speed */
 #define SGIOC_WRITE_EPSEL	0x04	/* force cable mode: 1=AUI 0=TP */
 #define SGIOC_WRITE_EASEL	0x08	/* 1=autoselect 0=manual cable selection */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/sgialib.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgialib.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/sgialib.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/sgialib.h	2010-02-24 13:52:17.000000000 -0500
@@ -85,8 +85,7 @@ extern void prom_identify_arch(void);
 extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
 extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
 
-/* ARCS command line acquisition and parsing. */
-extern char *prom_getcmdline(void);
+/* ARCS command line parsing. */
 extern void prom_init_cmdline(void);
 
 /* Acquiring info about the current time, etc. */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/sibyte/sb1250_mac.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/sb1250_mac.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/sibyte/sb1250_mac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/sibyte/sb1250_mac.h	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,7 @@
 #define G_MAC_TXD_WEIGHT1(x)        _SB_GETVALUE(x, S_MAC_TXD_WEIGHT1, M_MAC_TXD_WEIGHT1)
 
 /*
- * MAC Fifo Threshhold registers (Table 9-14)
+ * MAC Fifo Threshold registers (Table 9-14)
  * Register: MAC_THRSH_CFG_0
  * Register: MAC_THRSH_CFG_1
  * Register: MAC_THRSH_CFG_2
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/sn/sn0/hubio.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/sn/sn0/hubio.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/sn/sn0/hubio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/sn/sn0/hubio.h	2010-02-24 13:52:17.000000000 -0500
@@ -825,7 +825,7 @@ typedef union iprb_u {
 	struct {
 	    u64	rsvd1:	15,
 		error:	1,	/* Widget rcvd wr resp pkt w/ error */
-		ovflow:	5,	/* Over flow count. perf measurement */
+		ovflow:	5,	/* Overflow count. perf measurement */
 		fire_and_forget: 1, /* Launch Write without response */
 		mode:	2,	/* Widget operation Mode	*/
 		rsvd2:	2,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -80,6 +80,8 @@ To add: #define SO_REUSEPORT 0x0200	/* A
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_RXQ_OVFL             40
+
 #ifdef __KERNEL__
 
 /** sock_type - Socket types
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,33 +34,33 @@
  * becomes equal to the the initial value of the tail.
  */
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
 {
 	unsigned int counters = ACCESS_ONCE(lock->lock);
 
 	return ((counters >> 14) ^ counters) & 0x1fff;
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_spin_unlock_wait(x) \
-	while (__raw_spin_is_locked(x)) { cpu_relax(); }
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_unlock_wait(x) \
+	while (arch_spin_is_locked(x)) { cpu_relax(); }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
 {
 	unsigned int counters = ACCESS_ONCE(lock->lock);
 
 	return (((counters >> 14) - counters) & 0x1fff) > 1;
 }
-#define __raw_spin_is_contended	__raw_spin_is_contended
+#define arch_spin_is_contended	arch_spin_is_contended
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	int my_ticket;
 	int tmp;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__ (
-		"	.set push		# __raw_spin_lock	\n"
+		"	.set push		# arch_spin_lock	\n"
 		"	.set noreorder					\n"
 		"							\n"
 		"1:	ll	%[ticket], %[ticket_ptr]		\n"
@@ -94,7 +94,7 @@ static inline void __raw_spin_lock(raw_s
 		  [my_ticket] "=&r" (my_ticket));
 	} else {
 		__asm__ __volatile__ (
-		"	.set push		# __raw_spin_lock	\n"
+		"	.set push		# arch_spin_lock	\n"
 		"	.set noreorder					\n"
 		"							\n"
 		"	ll	%[ticket], %[ticket_ptr]		\n"
@@ -134,7 +134,7 @@ static inline void __raw_spin_lock(raw_s
 	smp_llsc_mb();
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	int tmp;
 
@@ -142,7 +142,7 @@ static inline void __raw_spin_unlock(raw
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__ (
-		"				# __raw_spin_unlock	\n"
+		"				# arch_spin_unlock	\n"
 		"1:	ll	%[ticket], %[ticket_ptr]		\n"
 		"	addiu	%[ticket], %[ticket], 1			\n"
 		"	ori	%[ticket], %[ticket], 0x2000		\n"
@@ -153,7 +153,7 @@ static inline void __raw_spin_unlock(raw
 		  [ticket] "=&r" (tmp));
 	} else {
 		__asm__ __volatile__ (
-		"	.set push		# __raw_spin_unlock	\n"
+		"	.set push		# arch_spin_unlock	\n"
 		"	.set noreorder					\n"
 		"							\n"
 		"	ll	%[ticket], %[ticket_ptr]		\n"
@@ -174,13 +174,13 @@ static inline void __raw_spin_unlock(raw
 	}
 }
 
-static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	int tmp, tmp2, tmp3;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__ (
-		"	.set push		# __raw_spin_trylock	\n"
+		"	.set push		# arch_spin_trylock	\n"
 		"	.set noreorder					\n"
 		"							\n"
 		"1:	ll	%[ticket], %[ticket_ptr]		\n"
@@ -204,7 +204,7 @@ static inline unsigned int __raw_spin_tr
 		  [now_serving] "=&r" (tmp3));
 	} else {
 		__asm__ __volatile__ (
-		"	.set push		# __raw_spin_trylock	\n"
+		"	.set push		# arch_spin_trylock	\n"
 		"	.set noreorder					\n"
 		"							\n"
 		"	ll	%[ticket], %[ticket_ptr]		\n"
@@ -248,21 +248,21 @@ static inline unsigned int __raw_spin_tr
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_read_can_lock(rw)	((rw)->lock >= 0)
+#define arch_read_can_lock(rw)	((rw)->lock >= 0)
 
 /*
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_write_can_lock(rw)	(!(rw)->lock)
+#define arch_write_can_lock(rw)	(!(rw)->lock)
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned int tmp;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_read_lock	\n"
+		"	.set	noreorder	# arch_read_lock	\n"
 		"1:	ll	%1, %2					\n"
 		"	bltz	%1, 1b					\n"
 		"	 addu	%1, 1					\n"
@@ -275,7 +275,7 @@ static inline void __raw_read_lock(raw_r
 		: "memory");
 	} else {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_read_lock	\n"
+		"	.set	noreorder	# arch_read_lock	\n"
 		"1:	ll	%1, %2					\n"
 		"	bltz	%1, 2f					\n"
 		"	 addu	%1, 1					\n"
@@ -301,7 +301,7 @@ static inline void __raw_read_lock(raw_r
 /* Note the use of sub, not subu which will make the kernel die with an
    overflow exception if we ever try to unlock an rwlock that is already
    unlocked or is being held by a writer.  */
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned int tmp;
 
@@ -309,7 +309,7 @@ static inline void __raw_read_unlock(raw
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
-		"1:	ll	%1, %2		# __raw_read_unlock	\n"
+		"1:	ll	%1, %2		# arch_read_unlock	\n"
 		"	sub	%1, 1					\n"
 		"	sc	%1, %0					\n"
 		"	beqzl	%1, 1b					\n"
@@ -318,7 +318,7 @@ static inline void __raw_read_unlock(raw
 		: "memory");
 	} else {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_read_unlock	\n"
+		"	.set	noreorder	# arch_read_unlock	\n"
 		"1:	ll	%1, %2					\n"
 		"	sub	%1, 1					\n"
 		"	sc	%1, %0					\n"
@@ -335,13 +335,13 @@ static inline void __raw_read_unlock(raw
 	}
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned int tmp;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_write_lock	\n"
+		"	.set	noreorder	# arch_write_lock	\n"
 		"1:	ll	%1, %2					\n"
 		"	bnez	%1, 1b					\n"
 		"	 lui	%1, 0x8000				\n"
@@ -354,7 +354,7 @@ static inline void __raw_write_lock(raw_
 		: "memory");
 	} else {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_write_lock	\n"
+		"	.set	noreorder	# arch_write_lock	\n"
 		"1:	ll	%1, %2					\n"
 		"	bnez	%1, 2f					\n"
 		"	 lui	%1, 0x8000				\n"
@@ -377,26 +377,26 @@ static inline void __raw_write_lock(raw_
 	smp_llsc_mb();
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	smp_mb();
 
 	__asm__ __volatile__(
-	"				# __raw_write_unlock	\n"
+	"				# arch_write_unlock	\n"
 	"	sw	$0, %0					\n"
 	: "=m" (rw->lock)
 	: "m" (rw->lock)
 	: "memory");
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned int tmp;
 	int ret;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_read_trylock	\n"
+		"	.set	noreorder	# arch_read_trylock	\n"
 		"	li	%2, 0					\n"
 		"1:	ll	%1, %3					\n"
 		"	bltz	%1, 2f					\n"
@@ -413,7 +413,7 @@ static inline int __raw_read_trylock(raw
 		: "memory");
 	} else {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_read_trylock	\n"
+		"	.set	noreorder	# arch_read_trylock	\n"
 		"	li	%2, 0					\n"
 		"1:	ll	%1, %3					\n"
 		"	bltz	%1, 2f					\n"
@@ -433,14 +433,14 @@ static inline int __raw_read_trylock(raw
 	return ret;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned int tmp;
 	int ret;
 
 	if (R10000_LLSC_WAR) {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_write_trylock	\n"
+		"	.set	noreorder	# arch_write_trylock	\n"
 		"	li	%2, 0					\n"
 		"1:	ll	%1, %3					\n"
 		"	bnez	%1, 2f					\n"
@@ -457,7 +457,7 @@ static inline int __raw_write_trylock(ra
 		: "memory");
 	} else {
 		__asm__ __volatile__(
-		"	.set	noreorder	# __raw_write_trylock	\n"
+		"	.set	noreorder	# arch_write_trylock	\n"
 		"	li	%2, 0					\n"
 		"1:	ll	%1, %3					\n"
 		"	bnez	%1, 2f					\n"
@@ -480,11 +480,11 @@ static inline int __raw_write_trylock(ra
 	return ret;
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* _ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,14 +12,14 @@ typedef struct {
 	 * bits 15..28: ticket
 	 */
 	unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/stackframe.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/stackframe.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/stackframe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/stackframe.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,9 +51,6 @@
 		LONG_S	v1, PT_ACX(sp)
 #else
 		mfhi	v1
-		LONG_S	v1, PT_HI(sp)
-		mflo	v1
-		LONG_S	v1, PT_LO(sp)
 #endif
 #ifdef CONFIG_32BIT
 		LONG_S	$8, PT_R8(sp)
@@ -62,10 +59,17 @@
 		LONG_S	$10, PT_R10(sp)
 		LONG_S	$11, PT_R11(sp)
 		LONG_S	$12, PT_R12(sp)
+#ifndef CONFIG_CPU_HAS_SMARTMIPS
+		LONG_S	v1, PT_HI(sp)
+		mflo	v1
+#endif
 		LONG_S	$13, PT_R13(sp)
 		LONG_S	$14, PT_R14(sp)
 		LONG_S	$15, PT_R15(sp)
 		LONG_S	$24, PT_R24(sp)
+#ifndef CONFIG_CPU_HAS_SMARTMIPS
+		LONG_S	v1, PT_LO(sp)
+#endif
 		.endm
 
 		.macro	SAVE_STATIC
@@ -83,15 +87,19 @@
 #ifdef CONFIG_SMP
 #ifdef CONFIG_MIPS_MT_SMTC
 #define PTEBASE_SHIFT	19	/* TCBIND */
+#define CPU_ID_REG CP0_TCBIND
+#define CPU_ID_MFC0 mfc0
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#define PTEBASE_SHIFT	48	/* XCONTEXT */
+#define CPU_ID_REG CP0_XCONTEXT
+#define CPU_ID_MFC0 MFC0
 #else
 #define PTEBASE_SHIFT	23	/* CONTEXT */
+#define CPU_ID_REG CP0_CONTEXT
+#define CPU_ID_MFC0 MFC0
 #endif
 		.macro	get_saved_sp	/* SMP variation */
-#ifdef CONFIG_MIPS_MT_SMTC
-		mfc0	k0, CP0_TCBIND
-#else
-		MFC0	k0, CP0_CONTEXT
-#endif
+		CPU_ID_MFC0	k0, CPU_ID_REG
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 		lui	k1, %hi(kernelsp)
 #else
@@ -107,11 +115,7 @@
 		.endm
 
 		.macro	set_saved_sp stackp temp temp2
-#ifdef CONFIG_MIPS_MT_SMTC
-		mfc0	\temp, CP0_TCBIND
-#else
-		MFC0	\temp, CP0_CONTEXT
-#endif
+		CPU_ID_MFC0	\temp, CPU_ID_REG
 		LONG_SRL	\temp, PTEBASE_SHIFT
 		LONG_S	\stackp, kernelsp(\temp)
 		.endm
@@ -166,7 +170,6 @@
 		LONG_S	$0, PT_R0(sp)
 		mfc0	v1, CP0_STATUS
 		LONG_S	$2, PT_R2(sp)
-		LONG_S	v1, PT_STATUS(sp)
 #ifdef CONFIG_MIPS_MT_SMTC
 		/*
 		 * Ideally, these instructions would be shuffled in
@@ -178,20 +181,21 @@
 		LONG_S	v1, PT_TCSTATUS(sp)
 #endif /* CONFIG_MIPS_MT_SMTC */
 		LONG_S	$4, PT_R4(sp)
-		mfc0	v1, CP0_CAUSE
 		LONG_S	$5, PT_R5(sp)
-		LONG_S	v1, PT_CAUSE(sp)
+		LONG_S	v1, PT_STATUS(sp)
+		mfc0	v1, CP0_CAUSE
 		LONG_S	$6, PT_R6(sp)
-		MFC0	v1, CP0_EPC
 		LONG_S	$7, PT_R7(sp)
+		LONG_S	v1, PT_CAUSE(sp)
+		MFC0	v1, CP0_EPC
 #ifdef CONFIG_64BIT
 		LONG_S	$8, PT_R8(sp)
 		LONG_S	$9, PT_R9(sp)
 #endif
-		LONG_S	v1, PT_EPC(sp)
 		LONG_S	$25, PT_R25(sp)
 		LONG_S	$28, PT_R28(sp)
 		LONG_S	$31, PT_R31(sp)
+		LONG_S	v1, PT_EPC(sp)
 		ori	$28, sp, _THREAD_MASK
 		xori	$28, _THREAD_MASK
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/time.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/time.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/time.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/time.h	2010-02-24 13:52:17.000000000 -0500
@@ -84,8 +84,16 @@ static inline int init_mips_clocksource(
 #endif
 }
 
-extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
-extern void clockevent_set_clock(struct clock_event_device *cd,
-		unsigned int clock);
+static inline void clocksource_set_clock(struct clocksource *cs,
+					 unsigned int clock)
+{
+	clocksource_calc_mult_shift(cs, clock, 4);
+}
+
+static inline void clockevent_set_clock(struct clock_event_device *cd,
+					unsigned int clock)
+{
+	clockevents_calc_mult_shift(cd, clock, 4);
+}
 
 #endif /* _ASM_TIME_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/mips/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/mips/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -355,16 +355,17 @@
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 332)
 #define __NR_perf_event_open		(__NR_Linux + 333)
 #define __NR_accept4			(__NR_Linux + 334)
+#define __NR_recvmmsg			(__NR_Linux + 335)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		334
+#define __NR_Linux_syscalls		335
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		334
+#define __NR_O32_Linux_syscalls		335
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -666,16 +667,17 @@
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 291)
 #define __NR_perf_event_open		(__NR_Linux + 292)
 #define __NR_accept4			(__NR_Linux + 293)
+#define __NR_recvmmsg			(__NR_Linux + 294)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		293
+#define __NR_Linux_syscalls		294
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		293
+#define __NR_64_Linux_syscalls		294
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -981,16 +983,17 @@
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 295)
 #define __NR_perf_event_open		(__NR_Linux + 296)
 #define __NR_accept4			(__NR_Linux + 297)
+#define __NR_recvmmsg			(__NR_Linux + 298)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		297
+#define __NR_Linux_syscalls		298
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		297
+#define __NR_N32_Linux_syscalls		298
 
 #ifdef __KERNEL__
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/Kconfig linux-libre-2.6.33-gnu1/arch/mips/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,9 +5,12 @@ config MIPS
 	select HAVE_IDE
 	select HAVE_OPROFILE
 	select HAVE_ARCH_KGDB
-	# Horrible source of confusion.  Die, die, die ...
-	select EMBEDDED
-	select RTC_LIB if !LEMOTE_FULOONG2E
+	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_DYNAMIC_FTRACE
+	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_FUNCTION_GRAPH_TRACER
+	select RTC_LIB if !MACH_LOONGSON
 
 mainmenu "Linux/MIPS Kernel Configuration"
 
@@ -22,6 +25,7 @@ choice
 
 config MACH_ALCHEMY
 	bool "Alchemy processor based machines"
+	select SYS_SUPPORTS_ZBOOT
 
 config AR7
 	bool "Texas Instruments AR7"
@@ -36,6 +40,7 @@ config AR7
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_ZBOOT_UART16550
 	select GENERIC_GPIO
 	select GCD
 	select VLYNQ
@@ -43,23 +48,6 @@ config AR7
 	  Support for the Texas Instruments AR7 System-on-a-Chip
 	  family: TNETD7100, 7200 and 7300.
 
-config BASLER_EXCITE
-	bool "Basler eXcite smart camera"
-	select CEVT_R4K
-	select CSRC_R4K
-	select DMA_COHERENT
-	select HW_HAS_PCI
-	select IRQ_CPU
-	select IRQ_CPU_RM7K
-	select IRQ_CPU_RM9K
-	select MIPS_RM9122
-	select SYS_HAS_CPU_RM9000
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_BIG_ENDIAN
-	help
-	  The eXcite is a smart camera platform manufactured by
-	  Basler Vision Technologies AG.
-
 config BCM47XX
 	bool "BCM47XX based boards"
 	select CEVT_R4K
@@ -192,6 +180,7 @@ config LASAT
 
 config MACH_LOONGSON
 	bool "Loongson family of machines"
+	select SYS_SUPPORTS_ZBOOT_UART16550
 	help
 	  This enables the support of Loongson family of machines.
 
@@ -233,6 +222,7 @@ config MIPS_MALTA
 	select SYS_SUPPORTS_MIPS_CMP
 	select SYS_SUPPORTS_MULTITHREADING
 	select SYS_SUPPORTS_SMARTMIPS
+	select SYS_SUPPORTS_ZBOOT
 	help
 	  This enables support for the MIPS Technologies Malta evaluation
 	  board.
@@ -334,6 +324,24 @@ config PMC_YOSEMITE
 	  Yosemite is an evaluation board for the RM9000x2 processor
 	  manufactured by PMC-Sierra.
 
+config POWERTV
+	bool "Cisco PowerTV"
+	select BOOT_ELF32
+	select CEVT_R4K
+	select CPU_MIPSR2_IRQ_VI
+	select CPU_MIPSR2_IRQ_EI
+	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
+	select SYS_SUPPORTS_HIGHMEM
+	select USB_OHCI_LITTLE_ENDIAN
+	help
+	  This enables support for the Cisco PowerTV Platform.
+
 config SGI_IP22
 	bool "SGI IP22 (Indy/Indigo2)"
 	select ARC
@@ -674,11 +682,11 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
-source "arch/mips/basler/excite/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
+source "arch/mips/powertv/Kconfig"
 source "arch/mips/sgi-ip27/Kconfig"
 source "arch/mips/sibyte/Kconfig"
 source "arch/mips/txx9/Kconfig"
@@ -778,6 +786,9 @@ config CSRC_BCM1480
 config CSRC_IOASIC
 	bool
 
+config CSRC_POWERTV
+	bool
+
 config CSRC_R4K_LIB
 	bool
 
@@ -806,20 +817,6 @@ config DMA_NONCOHERENT
 config DMA_NEED_PCI_MAP_STATE
 	bool
 
-config EARLY_PRINTK
-	bool "Early printk" if EMBEDDED && DEBUG_KERNEL
-	depends on SYS_HAS_EARLY_PRINTK
-	default y
-	help
-	  This option enables special console drivers which allow the kernel
-	  to print messages very early in the bootup process.
-
-	  This is useful for kernel debugging when your machine crashes very
-	  early before the console code is initialized. For normal operation,
-	  it is not recommended because it looks ugly on some machines and
-	  doesn't cooperate with an X server. You should normally say N here,
-	  unless you want to debug such a crash.
-
 config SYS_HAS_EARLY_PRINTK
 	bool
 
@@ -1069,6 +1066,21 @@ config CPU_LOONGSON2E
 	  The Loongson 2E processor implements the MIPS III instruction set
 	  with many extensions.
 
+	  It has an internal FPGA northbridge, which is compatiable to
+	  bonito64.
+
+config CPU_LOONGSON2F
+	bool "Loongson 2F"
+	depends on SYS_HAS_CPU_LOONGSON2F
+	select CPU_LOONGSON2
+	help
+	  The Loongson 2F processor implements the MIPS III instruction set
+	  with many extensions.
+
+	  Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller
+	  have a similar programming interface with FPGA northbridge used in
+	  Loongson2E.
+
 config CPU_MIPS32_R1
 	bool "MIPS32 Release 1"
 	depends on SYS_HAS_CPU_MIPS32_R1
@@ -1294,6 +1306,17 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
+config SYS_SUPPORTS_ZBOOT
+	bool
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZMA
+	select HAVE_KERNEL_LZO
+
+config SYS_SUPPORTS_ZBOOT_UART16550
+	bool
+	select SYS_SUPPORTS_ZBOOT
+
 config CPU_LOONGSON2
 	bool
 	select CPU_SUPPORTS_32BIT_KERNEL
@@ -1303,6 +1326,12 @@ config CPU_LOONGSON2
 config SYS_HAS_CPU_LOONGSON2E
 	bool
 
+config SYS_HAS_CPU_LOONGSON2F
+	bool
+	select CPU_SUPPORTS_CPUFREQ
+	select CPU_SUPPORTS_ADDRWINCFG if 64BIT
+	select CPU_SUPPORTS_UNCACHED_ACCELERATED
+
 config SYS_HAS_CPU_MIPS32_R1
 	bool
 
@@ -1411,8 +1440,17 @@ config CPU_SUPPORTS_32BIT_KERNEL
 	bool
 config CPU_SUPPORTS_64BIT_KERNEL
 	bool
+config CPU_SUPPORTS_CPUFREQ
+	bool
+config CPU_SUPPORTS_ADDRWINCFG
+	bool
 config CPU_SUPPORTS_HUGEPAGES
 	bool
+config CPU_SUPPORTS_UNCACHED_ACCELERATED
+	bool
+config MIPS_PGD_C0_CONTEXT
+	bool
+	default y if 64BIT && CPU_MIPSR2
 
 #
 # Set to y for ptrace access to watch registers.
@@ -2024,15 +2062,6 @@ config STACKTRACE_SUPPORT
 
 source "init/Kconfig"
 
-config PROBE_INITRD_HEADER
-	bool "Probe initrd header created by addinitrd"
-	depends on BLK_DEV_INITRD
-	help
-	  Probe initrd header at the last page of kernel image.
-	  Say Y here if you are using arch/mips/boot/addinitrd.c to
-	  add initrd or initramfs image to the kernel image.
-	  Otherwise, say N.
-
 source "kernel/Kconfig.freezer"
 
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
@@ -2104,6 +2133,7 @@ config MMU
 
 config I8253
 	bool
+	select MIPS_EXTERNAL_TIMER
 
 config ZONE_DMA32
 	bool
@@ -2180,6 +2210,8 @@ source "kernel/power/Kconfig"
 
 endmenu
 
+source "arch/mips/kernel/cpufreq/Kconfig"
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/Kconfig.debug linux-libre-2.6.33-gnu1/arch/mips/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/mips/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -6,15 +6,66 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config EARLY_PRINTK
+	bool "Early printk" if EMBEDDED
+	depends on SYS_HAS_EARLY_PRINTK
+	default y
+	help
+	  This option enables special console drivers which allow the kernel
+	  to print messages very early in the bootup process.
+
+	  This is useful for kernel debugging when your machine crashes very
+	  early before the console code is initialized. For normal operation,
+	  it is not recommended because it looks ugly on some machines and
+	  doesn't cooperate with an X server. You should normally say N here,
+	  unless you want to debug such a crash.
+
+config CMDLINE_BOOL
+	bool "Built-in kernel command line"
+	default n
+	help
+	  For most systems, it is firmware or second stage bootloader that
+	  by default specifies the kernel command line options.  However,
+	  it might be necessary or advantageous to either override the
+	  default kernel command line or add a few extra options to it.
+	  For such cases, this option allows you to hardcode your own
+	  command line options directly into the kernel.  For that, you
+	  should choose 'Y' here, and fill in the extra boot arguments
+	  in CONFIG_CMDLINE.
+
+	  The built-in options will be concatenated to the default command
+	  line if CMDLINE_OVERRIDE is set to 'N'. Otherwise, the default
+	  command line will be ignored and replaced by the built-in string.
+
+	  Most MIPS systems will normally expect 'N' here and rely upon
+	  the command line from the firmware or the second-stage bootloader.
+
 config CMDLINE
 	string "Default kernel command string"
+	depends on CMDLINE_BOOL
 	default ""
 	help
 	  On some platforms, there is currently no way for the boot loader to
-	  pass arguments to the kernel. For these platforms, you can supply
-	  some command-line options at build time by entering them here.  In
-	  other cases you can specify kernel args so that you don't have
-	  to set them up in board prom initialization routines.
+	  pass arguments to the kernel.  For these platforms, and for the cases
+	  when you want to add some extra options to the command line or ignore
+	  the default command line, you can supply some command-line options at
+	  build time by entering them here.  In other cases you can specify
+	  kernel args so that you don't have to set them up in board prom
+	  initialization routines.
+
+	  For more information, see the CMDLINE_BOOL and CMDLINE_OVERRIDE
+	  options.
+
+config CMDLINE_OVERRIDE
+	bool "Built-in command line overrides firware arguments"
+	default n
+	depends on CMDLINE_BOOL
+	help
+	  By setting this option to 'Y' you will have your kernel ignore
+	  command line arguments from firmware or second stage bootloader.
+	  Instead, the built-in command line will be used exclusively.
+
+	  Normally, you will choose 'N' here.
 
 config DEBUG_STACK_USAGE
 	bool "Enable stack utilization instrumentation"
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cevt-r4k.c linux-libre-2.6.33-gnu1/arch/mips/kernel/cevt-r4k.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cevt-r4k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cevt-r4k.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,7 +97,7 @@ void mips_event_handler(struct clock_eve
  */
 static int c0_compare_int_pending(void)
 {
-	return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+	return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/Kconfig linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,41 @@
+#
+# CPU Frequency scaling
+#
+
+config MIPS_EXTERNAL_TIMER
+	bool
+
+config MIPS_CPUFREQ
+	bool
+	default y
+	depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
+
+if MIPS_CPUFREQ
+
+menu "CPU Frequency scaling"
+
+source "drivers/cpufreq/Kconfig"
+
+if CPU_FREQ
+
+comment "CPUFreq processor drivers"
+
+config LOONGSON2_CPUFREQ
+	tristate "Loongson2 CPUFreq Driver"
+	select CPU_FREQ_TABLE
+	depends on MIPS_CPUFREQ
+	help
+	  This option adds a CPUFreq driver for loongson processors which
+	  support software configurable cpu frequency.
+
+	  Loongson2F and it's successors support this feature.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+endif	# CPU_FREQ
+
+endmenu
+
+endif	# MIPS_CPUFREQ
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.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/cpufreq.h>
+#include <linux/platform_device.h>
+
+#include <asm/clock.h>
+
+#include <loongson.h>
+
+static LIST_HEAD(clock_list);
+static DEFINE_SPINLOCK(clock_lock);
+static DEFINE_MUTEX(clock_list_sem);
+
+/* Minimum CLK support */
+enum {
+	DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT,
+	DC_87PT, DC_DISABLE, DC_RESV
+};
+
+struct cpufreq_frequency_table loongson2_clockmod_table[] = {
+	{DC_RESV, CPUFREQ_ENTRY_INVALID},
+	{DC_ZERO, CPUFREQ_ENTRY_INVALID},
+	{DC_25PT, 0},
+	{DC_37PT, 0},
+	{DC_50PT, 0},
+	{DC_62PT, 0},
+	{DC_75PT, 0},
+	{DC_87PT, 0},
+	{DC_DISABLE, 0},
+	{DC_RESV, CPUFREQ_TABLE_END},
+};
+EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
+
+static struct clk cpu_clk = {
+	.name = "cpu_clk",
+	.flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
+	.rate = 800000000,
+};
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	return &cpu_clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+static void propagate_rate(struct clk *clk)
+{
+	struct clk *clkp;
+
+	list_for_each_entry(clkp, &clock_list, node) {
+		if (likely(clkp->parent != clk))
+			continue;
+		if (likely(clkp->ops && clkp->ops->recalc))
+			clkp->ops->recalc(clkp);
+		if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
+			propagate_rate(clkp);
+	}
+}
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return (unsigned long)clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return clk_set_rate_ex(clk, rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
+{
+	int ret = 0;
+	int regval;
+	int i;
+
+	if (likely(clk->ops && clk->ops->set_rate)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		ret = clk->ops->set_rate(clk, rate, algo_id);
+		spin_unlock_irqrestore(&clock_lock, flags);
+	}
+
+	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+		propagate_rate(clk);
+
+	for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END;
+	     i++) {
+		if (loongson2_clockmod_table[i].frequency ==
+		    CPUFREQ_ENTRY_INVALID)
+			continue;
+		if (rate == loongson2_clockmod_table[i].frequency)
+			break;
+	}
+	if (rate != loongson2_clockmod_table[i].frequency)
+		return -ENOTSUPP;
+
+	clk->rate = rate;
+
+	regval = LOONGSON_CHIPCFG0;
+	regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1);
+	LOONGSON_CHIPCFG0 = regval;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (likely(clk->ops && clk->ops->round_rate)) {
+		unsigned long flags, rounded;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		rounded = clk->ops->round_rate(clk, rate);
+		spin_unlock_irqrestore(&clock_lock, flags);
+
+		return rounded;
+	}
+
+	return rate;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/*
+ * This is the simple version of Loongson-2 wait, Maybe we need do this in
+ * interrupt disabled content
+ */
+
+DEFINE_SPINLOCK(loongson2_wait_lock);
+void loongson2_cpu_wait(void)
+{
+	u32 cpu_freq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&loongson2_wait_lock, flags);
+	cpu_freq = LOONGSON_CHIPCFG0;
+	LOONGSON_CHIPCFG0 &= ~0x7;	/* Put CPU into wait mode */
+	LOONGSON_CHIPCFG0 = cpu_freq;	/* Restore CPU state */
+	spin_unlock_irqrestore(&loongson2_wait_lock, flags);
+}
+EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/loongson2_cpufreq.c linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/loongson2_cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/loongson2_cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,227 @@
+/*
+ * Cpufreq driver for the loongson-2 processors
+ *
+ * The 2E revision of loongson processor not support this feature.
+ *
+ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.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/cpufreq.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sched.h>	/* set_cpus_allowed() */
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/clock.h>
+
+#include <loongson.h>
+
+static uint nowait;
+
+static struct clk *cpuclk;
+
+static void (*saved_cpu_wait) (void);
+
+static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
+					unsigned long val, void *data);
+
+static struct notifier_block loongson2_cpufreq_notifier_block = {
+	.notifier_call = loongson2_cpu_freq_notifier
+};
+
+static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
+					unsigned long val, void *data)
+{
+	if (val == CPUFREQ_POSTCHANGE)
+		current_cpu_data.udelay_val = loops_per_jiffy;
+
+	return 0;
+}
+
+static unsigned int loongson2_cpufreq_get(unsigned int cpu)
+{
+	return clk_get_rate(cpuclk);
+}
+
+/*
+ * Here we notify other drivers of the proposed change and the final change.
+ */
+static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
+				     unsigned int target_freq,
+				     unsigned int relation)
+{
+	unsigned int cpu = policy->cpu;
+	unsigned int newstate = 0;
+	cpumask_t cpus_allowed;
+	struct cpufreq_freqs freqs;
+	unsigned int freq;
+
+	if (!cpu_online(cpu))
+		return -ENODEV;
+
+	cpus_allowed = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+	if (cpufreq_frequency_table_target
+	    (policy, &loongson2_clockmod_table[0], target_freq, relation,
+	     &newstate))
+		return -EINVAL;
+
+	freq =
+	    ((cpu_clock_freq / 1000) *
+	     loongson2_clockmod_table[newstate].index) / 8;
+	if (freq < policy->min || freq > policy->max)
+		return -EINVAL;
+
+	pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
+
+	freqs.cpu = cpu;
+	freqs.old = loongson2_cpufreq_get(cpu);
+	freqs.new = freq;
+	freqs.flags = 0;
+
+	if (freqs.new == freqs.old)
+		return 0;
+
+	/* notifiers */
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	set_cpus_allowed(current, cpus_allowed);
+
+	/* setting the cpu frequency */
+	clk_set_rate(cpuclk, freq);
+
+	/* notifiers */
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	pr_debug("cpufreq: set frequency %u kHz\n", freq);
+
+	return 0;
+}
+
+static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	int i;
+
+	if (!cpu_online(policy->cpu))
+		return -ENODEV;
+
+	cpuclk = clk_get(NULL, "cpu_clk");
+	if (IS_ERR(cpuclk)) {
+		printk(KERN_ERR "cpufreq: couldn't get CPU clk\n");
+		return PTR_ERR(cpuclk);
+	}
+
+	cpuclk->rate = cpu_clock_freq / 1000;
+	if (!cpuclk->rate)
+		return -EINVAL;
+
+	/* clock table init */
+	for (i = 2;
+	     (loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END);
+	     i++)
+		loongson2_clockmod_table[i].frequency = (cpuclk->rate * i) / 8;
+
+	policy->cur = loongson2_cpufreq_get(policy->cpu);
+
+	cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0],
+					 policy->cpu);
+
+	return cpufreq_frequency_table_cpuinfo(policy,
+					    &loongson2_clockmod_table[0]);
+}
+
+static int loongson2_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy,
+					      &loongson2_clockmod_table[0]);
+}
+
+static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	clk_put(cpuclk);
+	return 0;
+}
+
+static struct freq_attr *loongson2_table_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver loongson2_cpufreq_driver = {
+	.owner = THIS_MODULE,
+	.name = "loongson2",
+	.init = loongson2_cpufreq_cpu_init,
+	.verify = loongson2_cpufreq_verify,
+	.target = loongson2_cpufreq_target,
+	.get = loongson2_cpufreq_get,
+	.exit = loongson2_cpufreq_exit,
+	.attr = loongson2_table_attr,
+};
+
+static struct platform_device_id platform_device_ids[] = {
+	{
+		.name = "loongson2_cpufreq",
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(platform, platform_device_ids);
+
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = "loongson2_cpufreq",
+		.owner = THIS_MODULE,
+	},
+	.id_table = platform_device_ids,
+};
+
+static int __init cpufreq_init(void)
+{
+	int ret;
+
+	/* Register platform stuff */
+	ret = platform_driver_register(&platform_driver);
+	if (ret)
+		return ret;
+
+	pr_info("cpufreq: Loongson-2F CPU frequency driver.\n");
+
+	cpufreq_register_notifier(&loongson2_cpufreq_notifier_block,
+				  CPUFREQ_TRANSITION_NOTIFIER);
+
+	ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
+
+	if (!ret && !nowait) {
+		saved_cpu_wait = cpu_wait;
+		cpu_wait = loongson2_cpu_wait;
+	}
+
+	return ret;
+}
+
+static void __exit cpufreq_exit(void)
+{
+	if (!nowait && saved_cpu_wait)
+		cpu_wait = saved_cpu_wait;
+	cpufreq_unregister_driver(&loongson2_cpufreq_driver);
+	cpufreq_unregister_notifier(&loongson2_cpufreq_notifier_block,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+
+	platform_driver_unregister(&platform_driver);
+}
+
+module_init(cpufreq_init);
+module_exit(cpufreq_exit);
+
+module_param(nowait, uint, 0644);
+MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait");
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson2F");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/Makefile linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cpufreq/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cpufreq/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+#
+# Makefile for the Linux/MIPS cpufreq.
+#
+
+obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/cpu-probe.c linux-libre-2.6.33-gnu1/arch/mips/kernel/cpu-probe.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/cpu-probe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/cpu-probe.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
+#include <linux/module.h>
 
 #include <asm/bugs.h>
 #include <asm/cpu.h>
@@ -32,6 +33,7 @@
  * the CPU very much.
  */
 void (*cpu_wait)(void);
+EXPORT_SYMBOL(cpu_wait);
 
 static void r3081_wait(void)
 {
@@ -282,6 +284,15 @@ static inline int __cpu_has_fpu(void)
 	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
 }
 
+static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
+{
+#ifdef __NEED_VMBITS_PROBE
+	write_c0_entryhi(0x3fffffffffffe000ULL);
+	back_to_back_c0_hazard();
+	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
+#endif
+}
+
 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
 		| MIPS_CPU_COUNTER)
 
@@ -967,6 +978,8 @@ __cpuinit void cpu_probe(void)
 		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
 	else
 		c->srsets = 1;
+
+	cpu_probe_vmbits(c);
 }
 
 __cpuinit void cpu_report(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/csrc-powertv.c linux-libre-2.6.33-gnu1/arch/mips/kernel/csrc-powertv.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/csrc-powertv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/csrc-powertv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2008 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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 file comes from kernel/csrc-r4k.c
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h>			/* Not included in linux/time.h */
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "powertv-clock.h"
+
+/* MIPS PLL Register Definitions */
+#define PLL_GET_M(x)		(((x) >> 8) & 0x000000FF)
+#define PLL_GET_N(x)		(((x) >> 16) & 0x000000FF)
+#define PLL_GET_P(x)		(((x) >> 24) & 0x00000007)
+
+/*
+ * returns:  Clock frequency in kHz
+ */
+unsigned int __init mips_get_pll_freq(void)
+{
+	unsigned int pll_reg, m, n, p;
+	unsigned int fin = 54000; /* Base frequency in kHz */
+	unsigned int fout;
+
+	/* Read PLL register setting */
+	pll_reg = asic_read(mips_pll_setup);
+	m = PLL_GET_M(pll_reg);
+	n = PLL_GET_N(pll_reg);
+	p = PLL_GET_P(pll_reg);
+	pr_info("MIPS PLL Register:0x%x  M=%d  N=%d  P=%d\n", pll_reg, m, n, p);
+
+	/* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
+	fout = ((2 * n * fin) / (m * (0x01 << p)));
+
+	pr_info("MIPS Clock Freq=%d kHz\n", fout);
+
+	return fout;
+}
+
+static cycle_t c0_hpt_read(struct clocksource *cs)
+{
+	return read_c0_count();
+}
+
+static struct clocksource clocksource_mips = {
+	.name		= "powertv-counter",
+	.read		= c0_hpt_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init powertv_c0_hpt_clocksource_init(void)
+{
+	unsigned int pll_freq = mips_get_pll_freq();
+
+	pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000,
+		(pll_freq % 1000) * 100 / 1000);
+
+	mips_hpt_frequency = pll_freq / 2 * 1000;
+
+	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+
+	clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+
+	clocksource_register(&clocksource_mips);
+}
+
+/**
+ * struct tim_c - free running counter
+ * @hi:	High 16 bits of the counter
+ * @lo:	Low 32 bits of the counter
+ *
+ * Lays out the structure of the free running counter in memory. This counter
+ * increments at a rate of 27 MHz/8 on all platforms.
+ */
+struct tim_c {
+	unsigned int hi;
+	unsigned int lo;
+};
+
+static struct tim_c *tim_c;
+
+static cycle_t tim_c_read(struct clocksource *cs)
+{
+	unsigned int hi;
+	unsigned int next_hi;
+	unsigned int lo;
+
+	hi = readl(&tim_c->hi);
+
+	for (;;) {
+		lo = readl(&tim_c->lo);
+		next_hi = readl(&tim_c->hi);
+		if (next_hi == hi)
+			break;
+		hi = next_hi;
+	}
+
+pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo);
+	return ((u64) hi << 32) | lo;
+}
+
+#define TIM_C_SIZE		48		/* # bits in the timer */
+
+static struct clocksource clocksource_tim_c = {
+	.name		= "powertv-tim_c",
+	.read		= tim_c_read,
+	.mask		= CLOCKSOURCE_MASK(TIM_C_SIZE),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/**
+ * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
+ *
+ * The hard part here is coming up with a constant k and shift s such that
+ * the 48-bit TIM_C value multiplied by k doesn't overflow and that value,
+ * when shifted right by s, yields the corresponding number of nanoseconds.
+ * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
+ * 1 / (27,000,000/8) seconds. Multiply that by a billion and you get the
+ * number of nanoseconds. Since the TIM_C value has 48 bits and the math is
+ * done in 64 bits, avoiding an overflow means that k must be less than
+ * 64 - 48 = 16 bits.
+ */
+static void __init powertv_tim_c_clocksource_init(void)
+{
+	int			prescale;
+	unsigned long		dividend;
+	unsigned long		k;
+	int			s;
+	const int		max_k_bits = (64 - 48) - 1;
+	const unsigned long	billion = 1000000000;
+	const unsigned long	counts_per_second = 27000000 / 8;
+
+	prescale = BITS_PER_LONG - ilog2(billion) - 1;
+	dividend = billion << prescale;
+	k = dividend / counts_per_second;
+	s = ilog2(k) - max_k_bits;
+
+	if (s < 0)
+		s = prescale;
+
+	else {
+		k >>= s;
+		s += prescale;
+	}
+
+	clocksource_tim_c.mult = k;
+	clocksource_tim_c.shift = s;
+	clocksource_tim_c.rating = 200;
+
+	clocksource_register(&clocksource_tim_c);
+	tim_c = (struct tim_c *) asic_reg_addr(tim_ch);
+}
+
+/**
+ powertv_clocksource_init - initialize all clocksources
+ */
+void __init powertv_clocksource_init(void)
+{
+	powertv_c0_hpt_clocksource_init();
+	powertv_tim_c_clocksource_init();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/mips/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/ftrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,275 @@
+/*
+ * Code for replacing ftrace calls with jumps.
+ *
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ * Copyright (C) 2009 DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ * Thanks goes to Steven Rostedt for writing the original x86 version.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/cacheflush.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+#define JAL 0x0c000000		/* jump & link: ip --> ra, jump to target */
+#define ADDR_MASK 0x03ffffff	/*  op_code|addr : 31...26|25 ....0 */
+#define jump_insn_encode(op_code, addr) \
+	((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK)))
+
+static unsigned int ftrace_nop = 0x00000000;
+
+static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
+{
+	int faulted;
+
+	/* *(unsigned int *)ip = new_code; */
+	safe_store_code(new_code, ip, faulted);
+
+	if (unlikely(faulted))
+		return -EFAULT;
+
+	flush_icache_range(ip, ip + 8);
+
+	return 0;
+}
+
+static int lui_v1;
+static int jal_mcount;
+
+int ftrace_make_nop(struct module *mod,
+		    struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned int new;
+	int faulted;
+	unsigned long ip = rec->ip;
+
+	/* We have compiled module with -mlong-calls, but compiled the kernel
+	 * without it, we need to cope with them respectively. */
+	if (ip & 0x40000000) {
+		/* record it for ftrace_make_call */
+		if (lui_v1 == 0) {
+			/* lui_v1 = *(unsigned int *)ip; */
+			safe_load_code(lui_v1, ip, faulted);
+
+			if (unlikely(faulted))
+				return -EFAULT;
+		}
+
+		/* lui v1, hi_16bit_of_mcount        --> b 1f (0x10000004)
+		 * addiu v1, v1, low_16bit_of_mcount
+		 * move at, ra
+		 * jalr v1
+		 * nop
+		 * 				     1f: (ip + 12)
+		 */
+		new = 0x10000004;
+	} else {
+		/* record/calculate it for ftrace_make_call */
+		if (jal_mcount == 0) {
+			/* We can record it directly like this:
+			 *     jal_mcount = *(unsigned int *)ip;
+			 * Herein, jump over the first two nop instructions */
+			jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8));
+		}
+
+		/* move at, ra
+		 * jalr v1		--> nop
+		 */
+		new = ftrace_nop;
+	}
+	return ftrace_modify_code(ip, new);
+}
+
+static int modified;	/* initialized as 0 by default */
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned int new;
+	unsigned long ip = rec->ip;
+
+	/* We just need to remove the "b ftrace_stub" at the fist time! */
+	if (modified == 0) {
+		modified = 1;
+		ftrace_modify_code(addr, ftrace_nop);
+	}
+	/* ip, module: 0xc0000000, kernel: 0x80000000 */
+	new = (ip & 0x40000000) ? lui_v1 : jal_mcount;
+
+	return ftrace_modify_code(ip, new);
+}
+
+#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+	unsigned int new;
+
+	new = jump_insn_encode(JAL, (unsigned long)func);
+
+	return ftrace_modify_code(FTRACE_CALL_IP, new);
+}
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+	/* The return code is retured via data */
+	*(unsigned long *)data = 0;
+
+	return 0;
+}
+#endif				/* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+extern void ftrace_graph_call(void);
+#define JMP	0x08000000	/* jump to target directly */
+#define CALL_FTRACE_GRAPH_CALLER \
+	jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller))
+#define FTRACE_GRAPH_CALL_IP	((unsigned long)(&ftrace_graph_call))
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
+				  CALL_FTRACE_GRAPH_CALLER);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop);
+}
+
+#endif				/* !CONFIG_DYNAMIC_FTRACE */
+
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
+#define S_RA_SP	(0xafbf << 16)	/* s{d,w} ra, offset(sp) */
+#define S_R_SP	(0xafb0 << 16)  /* s{d,w} R, offset(sp) */
+#define OFFSET_MASK	0xffff	/* stack offset range: 0 ~ PT_SIZE */
+
+unsigned long ftrace_get_parent_addr(unsigned long self_addr,
+				     unsigned long parent,
+				     unsigned long parent_addr,
+				     unsigned long fp)
+{
+	unsigned long sp, ip, ra;
+	unsigned int code;
+	int faulted;
+
+	/* in module or kernel? */
+	if (self_addr & 0x40000000) {
+		/* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */
+		ip = self_addr - 20;
+	} else {
+		/* kernel: move to the instruction "move ra, at" */
+		ip = self_addr - 12;
+	}
+
+	/* search the text until finding the non-store instruction or "s{d,w}
+	 * ra, offset(sp)" instruction */
+	do {
+		ip -= 4;
+
+		/* get the code at "ip": code = *(unsigned int *)ip; */
+		safe_load_code(code, ip, faulted);
+
+		if (unlikely(faulted))
+			return 0;
+
+		/* If we hit the non-store instruction before finding where the
+		 * ra is stored, then this is a leaf function and it does not
+		 * store the ra on the stack. */
+		if ((code & S_R_SP) != S_R_SP)
+			return parent_addr;
+
+	} while (((code & S_RA_SP) != S_RA_SP));
+
+	sp = fp + (code & OFFSET_MASK);
+
+	/* ra = *(unsigned long *)sp; */
+	safe_load_stack(ra, sp, faulted);
+	if (unlikely(faulted))
+		return 0;
+
+	if (ra == parent)
+		return sp;
+	return 0;
+}
+
+#endif
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+			   unsigned long fp)
+{
+	unsigned long old;
+	struct ftrace_graph_ent trace;
+	unsigned long return_hooker = (unsigned long)
+	    &return_to_handler;
+	int faulted;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	/* "parent" is the stack address saved the return address of the caller
+	 * of _mcount.
+	 *
+	 * if the gcc < 4.5, a leaf function does not save the return address
+	 * in the stack address, so, we "emulate" one in _mcount's stack space,
+	 * and hijack it directly, but for a non-leaf function, it save the
+	 * return address to the its own stack space, we can not hijack it
+	 * directly, but need to find the real stack address,
+	 * ftrace_get_parent_addr() does it!
+	 *
+	 * if gcc>= 4.5, with the new -mmcount-ra-address option, for a
+	 * non-leaf function, the location of the return address will be saved
+	 * to $12 for us, and for a leaf function, only put a zero into $12. we
+	 * do it in ftrace_graph_caller of mcount.S.
+	 */
+
+	/* old = *parent; */
+	safe_load_stack(old, parent, faulted);
+	if (unlikely(faulted))
+		goto out;
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
+	parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
+							 (unsigned long)parent,
+							 fp);
+	/* If fails when getting the stack address of the non-leaf function's
+	 * ra, stop function graph tracer and return */
+	if (parent == 0)
+		goto out;
+#endif
+	/* *parent = return_hooker; */
+	safe_store_stack(return_hooker, parent, faulted);
+	if (unlikely(faulted))
+		goto out;
+
+	if (ftrace_push_return_trace(old, self_addr, &trace.depth, fp) ==
+	    -EBUSY) {
+		*parent = old;
+		return;
+	}
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		*parent = old;
+	}
+	return;
+out:
+	ftrace_graph_stop();
+	WARN_ON(1);
+}
+#endif				/* CONFIG_FUNCTION_GRAPH_TRACER */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/irq.c linux-libre-2.6.33-gnu1/arch/mips/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
 #include <linux/kgdb.h>
+#include <linux/ftrace.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -99,7 +100,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -118,7 +119,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_putc(p, '\n');
 		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -150,3 +151,32 @@ void __init init_IRQ(void)
 		kgdb_early_setup = 1;
 #endif
 }
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+void __irq_entry do_IRQ(unsigned int irq)
+{
+	irq_enter();
+	__DO_IRQ_SMTC_HOOK(irq);
+	generic_handle_irq(irq);
+	irq_exit();
+}
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+/*
+ * To avoid inefficient and in some cases pathological re-checking of
+ * IRQ affinity, we have this variant that skips the affinity check.
+ */
+
+void __irq_entry do_IRQ_no_affinity(unsigned int irq)
+{
+	irq_enter();
+	__NO_AFFINITY_IRQ_SMTC_HOOK(irq);
+	generic_handle_irq(irq);
+	irq_exit();
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/kspd.c linux-libre-2.6.33-gnu1/arch/mips/kernel/kspd.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/kspd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/kspd.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,6 +82,7 @@ static int sp_stopping;
 #define MTSP_O_SHLOCK		0x0010
 #define MTSP_O_EXLOCK		0x0020
 #define MTSP_O_ASYNC		0x0040
+/* XXX: check which of these is actually O_SYNC vs O_DSYNC */
 #define MTSP_O_FSYNC		O_SYNC
 #define MTSP_O_NOFOLLOW		0x0100
 #define MTSP_O_SYNC		0x0080
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/linux32.c linux-libre-2.6.33-gnu1/arch/mips/kernel/linux32.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/linux32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/linux32.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,28 +67,13 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long,
 	unsigned long, prot, unsigned long, flags, unsigned long, fd,
 	unsigned long, pgoff)
 {
-	struct file * file = NULL;
 	unsigned long error;
 
 	error = -EINVAL;
 	if (pgoff & (~PAGE_MASK >> 12))
 		goto out;
-	pgoff >>= PAGE_SHIFT-12;
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		error = -EBADF;
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
-
+	error = sys_mmap_pgoff(addr, len, prot, flags, fd,
+			       pgoff >> (PAGE_SHIFT-12));
 out:
 	return error;
 }
@@ -265,67 +250,6 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid,
 }
 #endif
 
-struct sysctl_args32
-{
-	compat_caddr_t name;
-	int nlen;
-	compat_caddr_t oldval;
-	compat_caddr_t oldlenp;
-	compat_caddr_t newval;
-	compat_size_t newlen;
-	unsigned int __unused[4];
-};
-
-#ifdef CONFIG_SYSCTL_SYSCALL
-
-SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
-{
-	struct sysctl_args32 tmp;
-	int error;
-	size_t oldlen;
-	size_t __user *oldlenp = NULL;
-	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
-
-	if (copy_from_user(&tmp, args, sizeof(tmp)))
-		return -EFAULT;
-
-	if (tmp.oldval && tmp.oldlenp) {
-		/* Duh, this is ugly and might not work if sysctl_args
-		   is in read-only memory, but do_sysctl does indirectly
-		   a lot of uaccess in both directions and we'd have to
-		   basically copy the whole sysctl.c here, and
-		   glibc's __sysctl uses rw memory for the structure
-		   anyway.  */
-		if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) ||
-		    put_user(oldlen, (size_t __user *)addr))
-			return -EFAULT;
-		oldlenp = (size_t __user *)addr;
-	}
-
-	lock_kernel();
-	error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, (void __user *)A(tmp.oldval),
-			  oldlenp, (void __user *)A(tmp.newval), tmp.newlen);
-	unlock_kernel();
-	if (oldlenp) {
-		if (!error) {
-			if (get_user(oldlen, (size_t __user *)addr) ||
-			    put_user(oldlen, (u32 __user *)A(tmp.oldlenp)))
-				error = -EFAULT;
-		}
-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
-	}
-	return error;
-}
-
-#else
-
-SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
-{
-	return -ENOSYS;
-}
-
-#endif /* CONFIG_SYSCTL_SYSCALL */
-
 SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
 {
 	int ret = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/Makefile linux-libre-2.6.33-gnu1/arch/mips/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,14 +2,17 @@
 # Makefile for the Linux/MIPS kernel.
 #
 
-CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
-
 extra-y		:= head.o init_task.o vmlinux.lds
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 		   ptrace.o reset.o setup.o signal.o syscall.o \
 		   time.o topology.o traps.o unaligned.o watch.o
 
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_early_printk.o = -pg
+endif
+
 obj-$(CONFIG_CEVT_BCM1480)	+= cevt-bcm1480.o
 obj-$(CONFIG_CEVT_R4K_LIB)	+= cevt-r4k.o
 obj-$(CONFIG_MIPS_MT_SMTC)	+= cevt-smtc.o
@@ -19,6 +22,7 @@ obj-$(CONFIG_CEVT_SB1250)	+= cevt-sb1250
 obj-$(CONFIG_CEVT_TXX9)		+= cevt-txx9.o
 obj-$(CONFIG_CSRC_BCM1480)	+= csrc-bcm1480.o
 obj-$(CONFIG_CSRC_IOASIC)	+= csrc-ioasic.o
+obj-$(CONFIG_CSRC_POWERTV)	+= csrc-powertv.o
 obj-$(CONFIG_CSRC_R4K_LIB)	+= csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)	+= csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)		+= sync-r4k.o
@@ -26,6 +30,8 @@ obj-$(CONFIG_SYNC_R4K)		+= sync-r4k.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o module.o
 
+obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
+
 obj-$(CONFIG_CPU_LOONGSON2)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_MIPS32)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_MIPS64)	+= r4k_fpu.o r4k_switch.o
@@ -92,4 +98,8 @@ CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $
 
 obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
 
+obj-$(CONFIG_MIPS_CPUFREQ)	+= cpufreq/
+
 EXTRA_CFLAGS += -Werror
+
+CPPFLAGS_vmlinux.lds		:= $(KBUILD_CFLAGS)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/mcount.S linux-libre-2.6.33-gnu1/arch/mips/kernel/mcount.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/mcount.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/mcount.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,189 @@
+/*
+ * MIPS 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) 2009 Lemote Inc. & DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ */
+
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/ftrace.h>
+
+	.text
+	.set noreorder
+	.set noat
+
+	.macro MCOUNT_SAVE_REGS
+	PTR_SUBU	sp, PT_SIZE
+	PTR_S	ra, PT_R31(sp)
+	PTR_S	AT, PT_R1(sp)
+	PTR_S	a0, PT_R4(sp)
+	PTR_S	a1, PT_R5(sp)
+	PTR_S	a2, PT_R6(sp)
+	PTR_S	a3, PT_R7(sp)
+#ifdef CONFIG_64BIT
+	PTR_S	a4, PT_R8(sp)
+	PTR_S	a5, PT_R9(sp)
+	PTR_S	a6, PT_R10(sp)
+	PTR_S	a7, PT_R11(sp)
+#endif
+	.endm
+
+	.macro MCOUNT_RESTORE_REGS
+	PTR_L	ra, PT_R31(sp)
+	PTR_L	AT, PT_R1(sp)
+	PTR_L	a0, PT_R4(sp)
+	PTR_L	a1, PT_R5(sp)
+	PTR_L	a2, PT_R6(sp)
+	PTR_L	a3, PT_R7(sp)
+#ifdef CONFIG_64BIT
+	PTR_L	a4, PT_R8(sp)
+	PTR_L	a5, PT_R9(sp)
+	PTR_L	a6, PT_R10(sp)
+	PTR_L	a7, PT_R11(sp)
+#endif
+#ifdef CONFIG_64BIT
+	PTR_ADDIU	sp, PT_SIZE
+#else
+	PTR_ADDIU	sp, (PT_SIZE + 8)
+#endif
+.endm
+
+	.macro RETURN_BACK
+	jr ra
+	 move ra, AT
+	.endm
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+NESTED(ftrace_caller, PT_SIZE, ra)
+	.globl _mcount
+_mcount:
+	b	ftrace_stub
+	 nop
+	lw	t1, function_trace_stop
+	bnez	t1, ftrace_stub
+	 nop
+
+	MCOUNT_SAVE_REGS
+#ifdef KBUILD_MCOUNT_RA_ADDRESS
+	PTR_S	t0, PT_R12(sp)	/* t0 saved the location of the return address(at) by -mmcount-ra-address */
+#endif
+
+	move	a0, ra		/* arg1: next ip, selfaddr */
+	.globl ftrace_call
+ftrace_call:
+	nop	/* a placeholder for the call to a real tracing function */
+	 move	a1, AT		/* arg2: the caller's next ip, parent */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.globl ftrace_graph_call
+ftrace_graph_call:
+	nop
+	 nop
+#endif
+
+	MCOUNT_RESTORE_REGS
+	.globl ftrace_stub
+ftrace_stub:
+	RETURN_BACK
+	END(ftrace_caller)
+
+#else	/* ! CONFIG_DYNAMIC_FTRACE */
+
+NESTED(_mcount, PT_SIZE, ra)
+	lw	t1, function_trace_stop
+	bnez	t1, ftrace_stub
+	 nop
+	PTR_LA	t1, ftrace_stub
+	PTR_L	t2, ftrace_trace_function /* Prepare t2 for (1) */
+	bne	t1, t2, static_trace
+	 nop
+
+#ifdef	CONFIG_FUNCTION_GRAPH_TRACER
+	PTR_L	t3, ftrace_graph_return
+	bne	t1, t3, ftrace_graph_caller
+	 nop
+	PTR_LA	t1, ftrace_graph_entry_stub
+	PTR_L	t3, ftrace_graph_entry
+	bne	t1, t3, ftrace_graph_caller
+	 nop
+#endif
+	b	ftrace_stub
+	 nop
+
+static_trace:
+	MCOUNT_SAVE_REGS
+
+	move	a0, ra		/* arg1: next ip, selfaddr */
+	jalr	t2		/* (1) call *ftrace_trace_function */
+	 move	a1, AT		/* arg2: the caller's next ip, parent */
+
+	MCOUNT_RESTORE_REGS
+	.globl ftrace_stub
+ftrace_stub:
+	RETURN_BACK
+	END(_mcount)
+
+#endif	/* ! CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+NESTED(ftrace_graph_caller, PT_SIZE, ra)
+#ifdef CONFIG_DYNAMIC_FTRACE
+	PTR_L	a1, PT_R31(sp)	/* load the original ra from the stack */
+#ifdef KBUILD_MCOUNT_RA_ADDRESS
+	PTR_L	t0, PT_R12(sp)	/* load the original t0 from the stack */
+#endif
+#else
+	MCOUNT_SAVE_REGS
+	move	a1, ra		/* arg2: next ip, selfaddr */
+#endif
+
+#ifdef KBUILD_MCOUNT_RA_ADDRESS
+	bnez	t0, 1f		/* non-leaf func: t0 saved the location of the return address */
+	 nop
+	PTR_LA	t0, PT_R1(sp)	/* leaf func: get the location of at(old ra) from our own stack */
+1:	move	a0, t0		/* arg1: the location of the return address */
+#else
+	PTR_LA	a0, PT_R1(sp)	/* arg1: &AT -> a0 */
+#endif
+	jal	prepare_ftrace_return
+#ifdef CONFIG_FRAME_POINTER
+	 move	a2, fp		/* arg3: frame pointer */
+#else
+#ifdef CONFIG_64BIT
+	 PTR_LA	a2, PT_SIZE(sp)
+#else
+	 PTR_LA	a2, (PT_SIZE+8)(sp)
+#endif
+#endif
+
+	MCOUNT_RESTORE_REGS
+	RETURN_BACK
+	END(ftrace_graph_caller)
+
+	.align	2
+	.globl	return_to_handler
+return_to_handler:
+	PTR_SUBU	sp, PT_SIZE
+	PTR_S	v0, PT_R2(sp)
+
+	jal	ftrace_return_to_handler
+	 PTR_S	v1, PT_R3(sp)
+
+	/* restore the real parent address: v0 -> ra */
+	move	ra, v0
+
+	PTR_L	v0, PT_R2(sp)
+	PTR_L	v1, PT_R3(sp)
+	jr	ra
+	 PTR_ADDIU	sp, PT_SIZE
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+	.set at
+	.set reorder
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/mips_ksyms.c linux-libre-2.6.33-gnu1/arch/mips/kernel/mips_ksyms.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/mips_ksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/mips_ksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
+#include <asm/ftrace.h>
 
 extern void *__bzero(void *__s, size_t __count);
 extern long __strncpy_from_user_nocheck_asm(char *__to,
@@ -51,3 +52,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck)
 EXPORT_SYMBOL(__csum_partial_copy_user);
 
 EXPORT_SYMBOL(invalid_pte_table);
+#ifdef CONFIG_FUNCTION_TRACER
+/* _mcount is defined in arch/mips/kernel/mcount.S */
+EXPORT_SYMBOL(_mcount);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/scall32-o32.S linux-libre-2.6.33-gnu1/arch/mips/kernel/scall32-o32.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/scall32-o32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/scall32-o32.S	2010-02-24 13:52:17.000000000 -0500
@@ -583,6 +583,7 @@ einval:	li	v0, -ENOSYS
 	sys	sys_rt_tgsigqueueinfo	4
 	sys	sys_perf_event_open	5
 	sys	sys_accept4		4
+	sys     sys_recvmmsg            5
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-64.S linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-64.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-64.S	2010-02-24 13:52:17.000000000 -0500
@@ -420,4 +420,5 @@ sys_call_table:
 	PTR	sys_rt_tgsigqueueinfo
 	PTR	sys_perf_event_open
 	PTR	sys_accept4
+	PTR     sys_recvmmsg
 	.size	sys_call_table,.-sys_call_table
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-n32.S linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-n32.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-n32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-n32.S	2010-02-24 13:52:17.000000000 -0500
@@ -272,7 +272,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_munlockall
 	PTR	sys_vhangup			/* 6150 */
 	PTR	sys_pivot_root
-	PTR	sys_32_sysctl
+	PTR	compat_sys_sysctl
 	PTR	sys_prctl
 	PTR	compat_sys_adjtimex
 	PTR	compat_sys_setrlimit		/* 6155 */
@@ -418,4 +418,5 @@ EXPORT(sysn32_call_table)
 	PTR	compat_sys_rt_tgsigqueueinfo	/* 5295 */
 	PTR	sys_perf_event_open
 	PTR	sys_accept4
+	PTR     compat_sys_recvmmsg
 	.size	sysn32_call_table,.-sysn32_call_table
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-o32.S linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-o32.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/scall64-o32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/scall64-o32.S	2010-02-24 13:52:17.000000000 -0500
@@ -356,7 +356,7 @@ sys_call_table:
 	PTR	sys_ni_syscall			/* 4150 */
 	PTR	sys_getsid
 	PTR	sys_fdatasync
-	PTR	sys_32_sysctl
+	PTR	compat_sys_sysctl
 	PTR	sys_mlock
 	PTR	sys_munlock			/* 4155 */
 	PTR	sys_mlockall
@@ -538,4 +538,5 @@ sys_call_table:
 	PTR	compat_sys_rt_tgsigqueueinfo
 	PTR	sys_perf_event_open
 	PTR	sys_accept4
+	PTR     compat_sys_recvmmsg
 	.size	sys_call_table,.-sys_call_table
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/setup.c linux-libre-2.6.33-gnu1/arch/mips/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,8 +58,12 @@ EXPORT_SYMBOL(mips_machtype);
 
 struct boot_mem_map boot_mem_map;
 
-static char command_line[CL_SIZE];
-       char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE;
+static char __initdata command_line[COMMAND_LINE_SIZE];
+char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
+
+#ifdef CONFIG_CMDLINE_BOOL
+static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
+#endif
 
 /*
  * mips_io_port_base is the begin of the address space to which x86 style
@@ -166,26 +170,8 @@ static unsigned long __init init_initrd(
 	 * already set up initrd_start and initrd_end. In these cases
 	 * perfom sanity checks and use them if all looks good.
 	 */
-	if (!initrd_start || initrd_end <= initrd_start) {
-#ifdef CONFIG_PROBE_INITRD_HEADER
-		u32 *initrd_header;
-
-		/*
-		 * See if initrd has been added to the kernel image by
-		 * arch/mips/boot/addinitrd.c. In that case a header is
-		 * prepended to initrd and is made up by 8 bytes. The first
-		 * word is a magic number and the second one is the size of
-		 * initrd.  Initrd start must be page aligned in any cases.
-		 */
-		initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
-		if (initrd_header[0] != 0x494E5244)
-			goto disable;
-		initrd_start = (unsigned long)(initrd_header + 2);
-		initrd_end = initrd_start + initrd_header[1];
-#else
+	if (!initrd_start || initrd_end <= initrd_start)
 		goto disable;
-#endif
-	}
 
 	if (initrd_start & ~PAGE_MASK) {
 		pr_err("initrd start must be page aligned\n");
@@ -476,8 +462,20 @@ static void __init arch_mem_init(char **
 	pr_info("Determined physical RAM map:\n");
 	print_memory_map();
 
-	strlcpy(command_line, arcs_cmdline, sizeof(command_line));
-	strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+	if (builtin_cmdline[0]) {
+		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+		strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
+	}
+	strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+#endif
+#else
+	strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+#endif
+	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 
 	*cmdline_p = command_line;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/signal32.c linux-libre-2.6.33-gnu1/arch/mips/kernel/signal32.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/signal32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/signal32.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,15 @@
 
 #include "signal-common.h"
 
+static int (*save_fp_context32)(struct sigcontext32 __user *sc);
+static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
+
+extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
+
+extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
+
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
@@ -828,3 +837,18 @@ SYSCALL_DEFINE5(32_waitid, int, which, c
 	info.si_code |= __SI_CHLD;
 	return copy_siginfo_to_user32(uinfo, &info);
 }
+
+static int signal32_init(void)
+{
+	if (cpu_has_fpu) {
+		save_fp_context32 = _save_fp_context32;
+		restore_fp_context32 = _restore_fp_context32;
+	} else {
+		save_fp_context32 = fpu_emulator_save_context32;
+		restore_fp_context32 = fpu_emulator_restore_context32;
+	}
+
+	return 0;
+}
+
+arch_initcall(signal32_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/signal.c linux-libre-2.6.33-gnu1/arch/mips/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,15 @@
 
 #include "signal-common.h"
 
+static int (*save_fp_context)(struct sigcontext __user *sc);
+static int (*restore_fp_context)(struct sigcontext __user *sc);
+
+extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
+
+extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
+extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
+
 /*
  * Horribly complicated - with the bloody RM9000 workarounds enabled
  * the signal trampolines is moving to the end of the structure so we can
@@ -709,3 +718,40 @@ asmlinkage void do_notify_resume(struct
 			key_replace_session_keyring();
 	}
 }
+
+#ifdef CONFIG_SMP
+static int smp_save_fp_context(struct sigcontext __user *sc)
+{
+	return raw_cpu_has_fpu
+	       ? _save_fp_context(sc)
+	       : fpu_emulator_save_context(sc);
+}
+
+static int smp_restore_fp_context(struct sigcontext __user *sc)
+{
+	return raw_cpu_has_fpu
+	       ? _restore_fp_context(sc)
+	       : fpu_emulator_restore_context(sc);
+}
+#endif
+
+static int signal_setup(void)
+{
+#ifdef CONFIG_SMP
+	/* For now just do the cpu_has_fpu check when the functions are invoked */
+	save_fp_context = smp_save_fp_context;
+	restore_fp_context = smp_restore_fp_context;
+#else
+	if (cpu_has_fpu) {
+		save_fp_context = _save_fp_context;
+		restore_fp_context = _restore_fp_context;
+	} else {
+		save_fp_context = fpu_emulator_save_context;
+		restore_fp_context = fpu_emulator_restore_context;
+	}
+#endif
+
+	return 0;
+}
+
+arch_initcall(signal_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/smp.c linux-libre-2.6.33-gnu1/arch/mips/kernel/smp.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/err.h>
+#include <linux/ftrace.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -130,7 +131,7 @@ asmlinkage __cpuinit void start_secondar
 /*
  * Call into both interrupt handlers, as we share the IPI for them
  */
-void smp_call_function_interrupt(void)
+void __irq_entry smp_call_function_interrupt(void)
 {
 	irq_enter();
 	generic_smp_call_function_single_interrupt();
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/smtc.c linux-libre-2.6.33-gnu1/arch/mips/kernel/smtc.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/smtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/smtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/ftrace.h>
 
 #include <asm/cpu.h>
 #include <asm/processor.h>
@@ -939,23 +940,29 @@ static void ipi_call_interrupt(void)
 
 DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
 
-void ipi_decode(struct smtc_ipi *pipi)
+static void __irq_entry smtc_clock_tick_interrupt(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd;
+	int irq = MIPS_CPU_IRQ_BASE + 1;
+
+	irq_enter();
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+	cd = &per_cpu(mips_clockevent_device, cpu);
+	cd->event_handler(cd);
+	irq_exit();
+}
+
+void ipi_decode(struct smtc_ipi *pipi)
+{
 	void *arg_copy = pipi->arg;
 	int type_copy = pipi->type;
-	int irq = MIPS_CPU_IRQ_BASE + 1;
 
 	smtc_ipi_nq(&freeIPIq, pipi);
 
 	switch (type_copy) {
 	case SMTC_CLOCK_TICK:
-		irq_enter();
-		kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
-		cd = &per_cpu(mips_clockevent_device, cpu);
-		cd->event_handler(cd);
-		irq_exit();
+		smtc_clock_tick_interrupt();
 		break;
 
 	case LINUX_SMP_IPI:
@@ -1331,7 +1338,7 @@ void smtc_get_new_mmu_context(struct mm_
 		if (!((asid += ASID_INC) & ASID_MASK) ) {
 			if (cpu_has_vtag_icache)
 				flush_icache_all();
-			/* Traverse all online CPUs (hack requires contigous range) */
+			/* Traverse all online CPUs (hack requires contiguous range) */
 			for_each_online_cpu(i) {
 				/*
 				 * We don't need to worry about our own CPU, nor those of
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/syscall.c linux-libre-2.6.33-gnu1/arch/mips/kernel/syscall.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/syscall.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/syscall.c	2010-02-24 13:52:17.000000000 -0500
@@ -93,7 +93,8 @@ unsigned long arch_get_unmapped_area(str
 		 * We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
 			return -EINVAL;
 		return addr;
 	}
@@ -129,31 +130,6 @@ unsigned long arch_get_unmapped_area(str
 	}
 }
 
-/* common code for old and new mmaps */
-static inline unsigned long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-        unsigned long flags, unsigned long fd, unsigned long pgoff)
-{
-	unsigned long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags, unsigned long,
 	fd, off_t, offset)
@@ -164,7 +140,7 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 
 out:
 	return result;
@@ -177,7 +153,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned lon
 	if (pgoff & (~PAGE_MASK >> 12))
 		return -EINVAL;
 
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
 }
 
 save_static_function(sys_fork);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/time.c linux-libre-2.6.33-gnu1/arch/mips/kernel/time.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,39 +71,6 @@ EXPORT_SYMBOL(perf_irq);
 
 unsigned int mips_hpt_frequency;
 
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) NSEC_PER_SEC << shift;
-		do_div(temp, clock);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cs->shift = shift;
-	cs->mult = (u32) temp;
-}
-
-void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
-	unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) clock << shift;
-		do_div(temp, NSEC_PER_SEC);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cd->shift = shift;
-	cd->mult = (u32) temp;
-}
-
 /*
  * This function exists in order to cause an error due to a duplicate
  * definition if platform code should have its own implementation.  The hook
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/traps.c linux-libre-2.6.33-gnu1/arch/mips/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,10 +25,12 @@
 #include <linux/ptrace.h>
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/notifier.h>
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
 #include <asm/break.h>
+#include <asm/cop2.h>
 #include <asm/cpu.h>
 #include <asm/dsp.h>
 #include <asm/fpu.h>
@@ -79,10 +81,6 @@ extern asmlinkage void handle_reserved(v
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
-#endif
-
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -857,6 +855,44 @@ static void mt_ase_fp_affinity(void)
 #endif /* CONFIG_MIPS_MT_FPAFF */
 }
 
+/*
+ * No lock; only written during early bootup by CPU 0.
+ */
+static RAW_NOTIFIER_HEAD(cu2_chain);
+
+int __ref register_cu2_notifier(struct notifier_block *nb)
+{
+	return raw_notifier_chain_register(&cu2_chain, nb);
+}
+
+int cu2_notifier_call_chain(unsigned long val, void *v)
+{
+	return raw_notifier_call_chain(&cu2_chain, val, v);
+}
+
+static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
+        void *data)
+{
+	struct pt_regs *regs = data;
+
+	switch (action) {
+	default:
+		die_if_kernel("Unhandled kernel unaligned access or invalid "
+			      "instruction", regs);
+		/* Fall through  */
+
+	case CU2_EXCEPTION:
+		force_sig(SIGILL, current);
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block default_cu2_notifier = {
+	.notifier_call	= default_cu2_call,
+	.priority	= 0x80000000,		/* Run last  */
+};
+
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
 	unsigned int __user *epc;
@@ -920,17 +956,9 @@ asmlinkage void do_cpu(struct pt_regs *r
 		return;
 
 	case 2:
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-		prefetch(&current->thread.cp2);
-		local_irq_save(flags);
-		KSTK_STATUS(current) |= ST0_CU2;
-		status = read_c0_status();
-		write_c0_status(status | ST0_CU2);
-		octeon_cop2_restore(&(current->thread.cp2));
-		write_c0_status(status & ~ST0_CU2);
-		local_irq_restore(flags);
-		return;
-#endif
+		raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
+		break;
+
 	case 3:
 		break;
 	}
@@ -1367,77 +1395,6 @@ void *set_vi_handler(int n, vi_handler_t
 	return set_vi_srs_handler(n, addr, 0);
 }
 
-/*
- * This is used by native signal handling
- */
-asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
-asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
-
-extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
-extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
-
-extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
-extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
-
-#ifdef CONFIG_SMP
-static int smp_save_fp_context(struct sigcontext __user *sc)
-{
-	return raw_cpu_has_fpu
-	       ? _save_fp_context(sc)
-	       : fpu_emulator_save_context(sc);
-}
-
-static int smp_restore_fp_context(struct sigcontext __user *sc)
-{
-	return raw_cpu_has_fpu
-	       ? _restore_fp_context(sc)
-	       : fpu_emulator_restore_context(sc);
-}
-#endif
-
-static inline void signal_init(void)
-{
-#ifdef CONFIG_SMP
-	/* For now just do the cpu_has_fpu check when the functions are invoked */
-	save_fp_context = smp_save_fp_context;
-	restore_fp_context = smp_restore_fp_context;
-#else
-	if (cpu_has_fpu) {
-		save_fp_context = _save_fp_context;
-		restore_fp_context = _restore_fp_context;
-	} else {
-		save_fp_context = fpu_emulator_save_context;
-		restore_fp_context = fpu_emulator_restore_context;
-	}
-#endif
-}
-
-#ifdef CONFIG_MIPS32_COMPAT
-
-/*
- * This is used by 32-bit signal stuff on the 64-bit kernel
- */
-asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
-asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
-
-extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
-extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
-
-extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
-extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
-
-static inline void signal32_init(void)
-{
-	if (cpu_has_fpu) {
-		save_fp_context32 = _save_fp_context32;
-		restore_fp_context32 = _restore_fp_context32;
-	} else {
-		save_fp_context32 = fpu_emulator_save_context32;
-		restore_fp_context32 = fpu_emulator_restore_context32;
-	}
-}
-#endif
-
 extern void cpu_cache_init(void);
 extern void tlb_init(void);
 extern void flush_tlb_handlers(void);
@@ -1446,6 +1403,7 @@ extern void flush_tlb_handlers(void);
  * Timer interrupt
  */
 int cp0_compare_irq;
+int cp0_compare_irq_shift;
 
 /*
  * Performance counter IRQ or -1 if shared with timer
@@ -1536,12 +1494,14 @@ void __cpuinit per_cpu_trap_init(void)
 	 *  o read IntCtl.IPPCI to determine the performance counter interrupt
 	 */
 	if (cpu_has_mips_r2) {
-		cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
-		cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
+		cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
+		cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
+		cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
 		if (cp0_perfcount_irq == cp0_compare_irq)
 			cp0_perfcount_irq = -1;
 	} else {
 		cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
+		cp0_compare_irq_shift = cp0_compare_irq;
 		cp0_perfcount_irq = -1;
 	}
 
@@ -1751,13 +1711,10 @@ void __init trap_init(void)
 	else
 		memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80);
 
-	signal_init();
-#ifdef CONFIG_MIPS32_COMPAT
-	signal32_init();
-#endif
-
 	local_flush_icache_range(ebase, ebase + 0x400);
 	flush_tlb_handlers();
 
 	sort_extable(__start___dbe_table, __stop___dbe_table);
+
+	register_cu2_notifier(&default_cu2_notifier);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/unaligned.c linux-libre-2.6.33-gnu1/arch/mips/kernel/unaligned.c
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/unaligned.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/unaligned.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,6 +81,7 @@
 #include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/byteorder.h>
+#include <asm/cop2.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -451,17 +452,27 @@ static void emulate_load_store_insn(stru
 		 */
 		goto sigbus;
 
+	/*
+	 * COP2 is available to implementor for application specific use.
+	 * It's up to applications to register a notifier chain and do
+	 * whatever they have to do, including possible sending of signals.
+	 */
 	case lwc2_op:
+		cu2_notifier_call_chain(CU2_LWC2_OP, regs);
+		break;
+
 	case ldc2_op:
+		cu2_notifier_call_chain(CU2_LDC2_OP, regs);
+		break;
+
 	case swc2_op:
+		cu2_notifier_call_chain(CU2_SWC2_OP, regs);
+		break;
+
 	case sdc2_op:
-		/*
-		 * These are the coprocessor 2 load/stores.  The current
-		 * implementations don't use cp2 and cp2 should always be
-		 * disabled in c0_status.  So send SIGILL.
-                 * (No longer true: The Sony Praystation uses cp2 for
-                 * 3D matrix operations.  Dunno if that thingy has a MMU ...)
-		 */
+		cu2_notifier_call_chain(CU2_SDC2_OP, regs);
+		break;
+
 	default:
 		/*
 		 * Pheeee...  We encountered an yet unknown instruction or
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/mips/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/mips/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@ SECTIONS
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
+		IRQENTRY_TEXT
 		*(.text.*)
 		*(.fixup)
 		*(.gnu.warning)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/lasat/picvue_proc.c linux-libre-2.6.33-gnu1/arch/mips/lasat/picvue_proc.c
--- linux-libre-2.6.32-gnu1/arch/mips/lasat/picvue_proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/lasat/picvue_proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -4,12 +4,14 @@
  * Brian Murphy <brian.murphy@eicon.com>
  *
  */
+#include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/interrupt.h>
 
 #include <linux/timer.h>
@@ -38,12 +40,9 @@ static void pvc_display(unsigned long da
 
 static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
 
-static int pvc_proc_read_line(char *page, char **start,
-			     off_t off, int count,
-			     int *eof, void *data)
+static int pvc_line_proc_show(struct seq_file *m, void *v)
 {
-	char *origpage = page;
-	int lineno = *(int *)data;
+	int lineno = *(int *)m->private;
 
 	if (lineno < 0 || lineno > PVC_NLINES) {
 		printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);
@@ -51,45 +50,66 @@ static int pvc_proc_read_line(char *page
 	}
 
 	mutex_lock(&pvc_mutex);
-	page += sprintf(page, "%s\n", pvc_lines[lineno]);
+	seq_printf(m, "%s\n", pvc_lines[lineno]);
 	mutex_unlock(&pvc_mutex);
 
-	return page - origpage;
+	return 0;
 }
 
-static int pvc_proc_write_line(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
+static int pvc_line_proc_open(struct inode *inode, struct file *file)
 {
-	int origcount = count;
-	int lineno = *(int *)data;
+	return single_open(file, pvc_line_proc_show, PDE(inode)->data);
+}
 
-	if (lineno < 0 || lineno > PVC_NLINES) {
-		printk(KERN_WARNING "proc_write_line: invalid lineno %d\n",
-		       lineno);
-		return origcount;
-	}
+static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
+				   size_t count, loff_t *pos)
+{
+	int lineno = *(int *)PDE(file->f_path.dentry->d_inode)->data;
+	char kbuf[PVC_LINELEN];
+	size_t len;
 
-	if (count > PVC_LINELEN)
-		count = PVC_LINELEN;
+	BUG_ON(lineno < 0 || lineno > PVC_NLINES);
 
-	if (buffer[count-1] == '\n')
-		count--;
+	len = min(count, sizeof(kbuf) - 1);
+	if (copy_from_user(kbuf, buf, len))
+		return -EFAULT;
+	kbuf[len] = '\0';
+
+	if (len > 0 && kbuf[len - 1] == '\n')
+		len--;
 
 	mutex_lock(&pvc_mutex);
-	strncpy(pvc_lines[lineno], buffer, count);
-	pvc_lines[lineno][count] = '\0';
+	strncpy(pvc_lines[lineno], kbuf, len);
+	pvc_lines[lineno][len] = '\0';
 	mutex_unlock(&pvc_mutex);
 
 	tasklet_schedule(&pvc_display_tasklet);
 
-	return origcount;
+	return count;
 }
 
-static int pvc_proc_write_scroll(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
+static const struct file_operations pvc_line_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pvc_line_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= pvc_line_proc_write,
+};
+
+static ssize_t pvc_scroll_proc_write(struct file *file, const char __user *buf,
+				     size_t count, loff_t *pos)
 {
-	int origcount = count;
-	int cmd = simple_strtol(buffer, NULL, 10);
+	char kbuf[42];
+	size_t len;
+	int cmd;
+
+	len = min(count, sizeof(kbuf) - 1);
+	if (copy_from_user(kbuf, buf, len))
+		return -EFAULT;
+	kbuf[len] = '\0';
+
+	cmd = simple_strtol(kbuf, NULL, 10);
 
 	mutex_lock(&pvc_mutex);
 	if (scroll_interval != 0)
@@ -110,22 +130,31 @@ static int pvc_proc_write_scroll(struct
 	}
 	mutex_unlock(&pvc_mutex);
 
-	return origcount;
+	return count;
 }
 
-static int pvc_proc_read_scroll(char *page, char **start,
-			     off_t off, int count,
-			     int *eof, void *data)
+static int pvc_scroll_proc_show(struct seq_file *m, void *v)
 {
-	char *origpage = page;
-
 	mutex_lock(&pvc_mutex);
-	page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
+	seq_printf(m, "%d\n", scroll_dir * scroll_interval);
 	mutex_unlock(&pvc_mutex);
 
-	return page - origpage;
+	return 0;
 }
 
+static int pvc_scroll_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pvc_scroll_proc_show, NULL);
+}
+
+static const struct file_operations pvc_scroll_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pvc_scroll_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= pvc_scroll_proc_write,
+};
 
 void pvc_proc_timerfunc(unsigned long data)
 {
@@ -163,22 +192,16 @@ static int __init pvc_proc_init(void)
 		pvc_linedata[i] = i;
 	}
 	for (i = 0; i < PVC_NLINES; i++) {
-		proc_entry = create_proc_entry(pvc_linename[i], 0644,
-					       pvc_display_dir);
+		proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir,
+					&pvc_line_proc_fops, &pvc_linedata[i]);
 		if (proc_entry == NULL)
 			goto error;
-
-		proc_entry->read_proc = pvc_proc_read_line;
-		proc_entry->write_proc = pvc_proc_write_line;
-		proc_entry->data = &pvc_linedata[i];
 	}
-	proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
+	proc_entry = proc_create("scroll", 0644, pvc_display_dir,
+				 &pvc_scroll_proc_fops);
 	if (proc_entry == NULL)
 		goto error;
 
-	proc_entry->write_proc = pvc_proc_write_scroll;
-	proc_entry->read_proc = pvc_proc_read_scroll;
-
 	init_timer(&timer);
 	timer.function = pvc_proc_timerfunc;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/lasat/prom.c linux-libre-2.6.33-gnu1/arch/mips/lasat/prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/lasat/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/lasat/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,8 +100,8 @@ void __init prom_init(void)
 
 	/* Get the command line */
 	if (argc > 0) {
-		strncpy(arcs_cmdline, argv[0], CL_SIZE-1);
-		arcs_cmdline[CL_SIZE-1] = '\0';
+		strncpy(arcs_cmdline, argv[0], COMMAND_LINE_SIZE-1);
+		arcs_cmdline[COMMAND_LINE_SIZE-1] = '\0';
 	}
 
 	/* Set the I/O base address */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/lasat/sysctl.c linux-libre-2.6.33-gnu1/arch/mips/lasat/sysctl.c
--- linux-libre-2.6.32-gnu1/arch/mips/lasat/sysctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/lasat/sysctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,23 +37,6 @@
 #include "ds1603.h"
 #endif
 
-/* Strategy function to write EEPROM after changing string entry */
-int sysctl_lasatstring(ctl_table *table,
-		void *oldval, size_t *oldlenp,
-		void *newval, size_t newlen)
-{
-	int r;
-
-	r = sysctl_string(table, oldval, oldlenp, newval, newlen);
-	if (r < 0)
-		return r;
-
-	if (newval && newlen)
-		lasat_write_eeprom_info();
-
-	return 0;
-}
-
 
 /* And the same for proc */
 int proc_dolasatstring(ctl_table *table, int write,
@@ -113,46 +96,6 @@ int proc_dolasatrtc(ctl_table *table, in
 }
 #endif
 
-/* Sysctl for setting the IP addresses */
-int sysctl_lasat_intvec(ctl_table *table,
-		    void *oldval, size_t *oldlenp,
-		    void *newval, size_t newlen)
-{
-	int r;
-
-	r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
-	if (r < 0)
-		return r;
-
-	if (newval && newlen)
-		lasat_write_eeprom_info();
-
-	return 0;
-}
-
-#ifdef CONFIG_DS1603
-/* Same for RTC */
-int sysctl_lasat_rtc(ctl_table *table,
-		    void *oldval, size_t *oldlenp,
-		    void *newval, size_t newlen)
-{
-	struct timespec ts;
-	int r;
-
-	read_persistent_clock(&ts);
-	rtctmp = ts.tv_sec;
-	if (rtctmp < 0)
-		rtctmp = 0;
-	r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
-	if (r < 0)
-		return r;
-	if (newval && newlen)
-		rtc_mips_set_mmss(rtctmp);
-
-	return r;
-}
-#endif
-
 #ifdef CONFIG_INET
 int proc_lasat_ip(ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
@@ -214,23 +157,6 @@ int proc_lasat_ip(ctl_table *table, int
 }
 #endif
 
-static int sysctl_lasat_prid(ctl_table *table,
-				     void *oldval, size_t *oldlenp,
-				     void *newval, size_t newlen)
-{
-	int r;
-
-	r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
-	if (r < 0)
-		return r;
-	if (newval && newlen) {
-		lasat_board_info.li_eeprom_info.prid = *(int *)newval;
-		lasat_write_eeprom_info();
-		lasat_init_board_info();
-	}
-	return 0;
-}
-
 int proc_lasat_prid(ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -252,115 +178,92 @@ extern int lasat_boot_to_service;
 
 static ctl_table lasat_table[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "cpu-hz",
 		.data		= &lasat_board_info.li_cpu_hz,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
-		.strategy	= &sysctl_intvec
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "bus-hz",
 		.data		= &lasat_board_info.li_bus_hz,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
-		.strategy	= &sysctl_intvec
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "bmid",
 		.data		= &lasat_board_info.li_bmid,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
-		.strategy	= &sysctl_intvec
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "prid",
 		.data		= &lasat_board_info.li_prid,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_lasat_prid,
-		.strategy	= &sysctl_lasat_prid
+		.proc_handler	= proc_lasat_prid,
 	},
 #ifdef CONFIG_INET
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "ipaddr",
 		.data		= &lasat_board_info.li_eeprom_info.ipaddr,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_lasat_ip,
-		.strategy	= &sysctl_lasat_intvec
+		.proc_handler	= proc_lasat_ip,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "netmask",
 		.data		= &lasat_board_info.li_eeprom_info.netmask,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_lasat_ip,
-		.strategy	= &sysctl_lasat_intvec
+		.proc_handler	= proc_lasat_ip,
 	},
 #endif
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "passwd_hash",
 		.data		= &lasat_board_info.li_eeprom_info.passwd_hash,
 		.maxlen		=
 			sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
 		.mode		= 0600,
-		.proc_handler	= &proc_dolasatstring,
-		.strategy	= &sysctl_lasatstring
+		.proc_handler	= proc_dolasatstring,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "boot-service",
 		.data		= &lasat_boot_to_service,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-		.strategy	= &sysctl_intvec
+		.proc_handler	= proc_dointvec,
 	},
 #ifdef CONFIG_DS1603
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "rtc",
 		.data		= &rtctmp,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dolasatrtc,
-		.strategy	= &sysctl_lasat_rtc
+		.proc_handler	= proc_dolasatrtc,
 	},
 #endif
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "namestr",
 		.data		= &lasat_board_info.li_namestr,
 		.maxlen		= sizeof(lasat_board_info.li_namestr),
 		.mode		= 0444,
-		.proc_handler	= &proc_dostring,
-		.strategy	= &sysctl_string
+		.proc_handler	= proc_dostring,
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "typestr",
 		.data		= &lasat_board_info.li_typestr,
 		.maxlen		= sizeof(lasat_board_info.li_typestr),
 		.mode		= 0444,
-		.proc_handler	= &proc_dostring,
-		.strategy	= &sysctl_string
+		.proc_handler	= proc_dostring,
 	},
 	{}
 };
 
 static ctl_table lasat_root_table[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "lasat",
 		.mode		=  0555,
 		.child		= lasat_table
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/bonito-irq.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/bonito-irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/bonito-irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/bonito-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,18 +12,19 @@
  *  option) any later version.
  */
 #include <linux/interrupt.h>
+#include <linux/compiler.h>
 
 #include <loongson.h>
 
 static inline void bonito_irq_enable(unsigned int irq)
 {
-	BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
+	LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
 
 static inline void bonito_irq_disable(unsigned int irq)
 {
-	BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+	LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
 	mmiowb();
 }
 
@@ -35,7 +36,7 @@ static struct irq_chip bonito_irq_type =
 	.unmask	= bonito_irq_enable,
 };
 
-static struct irqaction dma_timeout_irqaction = {
+static struct irqaction __maybe_unused dma_timeout_irqaction = {
 	.handler	= no_action,
 	.name		= "dma_timeout",
 };
@@ -44,8 +45,10 @@ void bonito_irq_init(void)
 {
 	u32 i;
 
-	for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++)
+	for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
 		set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
 
-	setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
+#ifdef CONFIG_CPU_LOONGSON2E
+	setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
+#endif
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cmdline.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cmdline.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cmdline.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cmdline.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,7 @@
  * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
  * Author: Fuxin Zhang, zhangfx@lemote.com
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Copyright (C) 2009 Lemote Inc.
  * Author: Wu Zhangjin, wuzj@lemote.com
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -49,4 +49,6 @@ void __init prom_init_cmdline(void)
 		strcat(arcs_cmdline, " console=ttyS0,115200");
 	if ((strstr(arcs_cmdline, "root=")) == NULL)
 		strcat(arcs_cmdline, " root=/dev/hda1");
+
+	prom_init_machtype();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_acc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,140 @@
+/*
+ * the ACC Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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 <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_acc_write_reg(int reg, u32 value)
+{
+	u32 hi = 0, lo = value;
+
+	switch (reg) {
+	case PCI_COMMAND:
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if (value & PCI_COMMAND_MASTER)
+			lo |= (0x03 << 8);
+		else
+			lo &= ~(0x03 << 8);
+		_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		break;
+	case PCI_STATUS:
+		if (value & PCI_STATUS_PARITY) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_ACC_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			value &= 0xfffffffc;
+			hi = 0xA0000000 | ((value & 0x000ff000) >> 12);
+			lo = 0x000fff80 | ((value & 0x00000fff) << 20);
+			_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo);
+		}
+		break;
+	case PCI_ACC_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+		/* disable all the usb interrupt in PIC */
+		lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+		if (value)	/* enable all the acc interrupt in PIC */
+			lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT);
+		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		break;
+	default:
+		break;
+	}
+}
+
+u32 pci_acc_read_reg(int reg)
+{
+	u32 hi, lo;
+	u32 conf_data = 0;
+
+	switch (reg) {
+	case PCI_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND:
+		_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+		if (((lo & 0xfff00000) || (hi & 0x000000ff))
+		    && ((hi & 0xf0000000) == 0xa0000000))
+			conf_data |= PCI_COMMAND_IO;
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if ((lo & 0x300) == 0x300)
+			conf_data |= PCI_COMMAND_MASTER;
+		break;
+	case PCI_STATUS:
+		conf_data |= PCI_STATUS_66MHZ;
+		conf_data |= PCI_STATUS_FAST_BACK;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REVISION:
+		_rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_ACC_CLASS_CODE << 8);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		conf_data =
+		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+					    PCI_NORMAL_LATENCY_TIMER);
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_ACC_FLAG) {
+			conf_data = CS5536_ACC_RANGE |
+			    PCI_BASE_ADDRESS_SPACE_IO;
+			lo &= ~SOFT_BAR_ACC_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+			conf_data = (hi & 0x000000ff) << 12;
+			conf_data |= (lo & 0xfff00000) >> 20;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_CARDBUS_CIS:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYSTEM_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
+		break;
+	case PCI_ROM_ADDRESS:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPABILITY_LIST:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_LINE:
+		conf_data =
+		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
+		break;
+	default:
+		break;
+	}
+
+	return conf_data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * the EHCI Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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 <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ehci_write_reg(int reg, u32 value)
+{
+	u32 hi = 0, lo = value;
+
+	switch (reg) {
+	case PCI_COMMAND:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		if (value & PCI_COMMAND_MASTER)
+			hi |= PCI_COMMAND_MASTER;
+		else
+			hi &= ~PCI_COMMAND_MASTER;
+
+		if (value & PCI_COMMAND_MEMORY)
+			hi |= PCI_COMMAND_MEMORY;
+		else
+			hi &= ~PCI_COMMAND_MEMORY;
+		_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		break;
+	case PCI_STATUS:
+		if (value & PCI_STATUS_PARITY) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_EHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo);
+		}
+		break;
+	case PCI_EHCI_LEGSMIEN_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		hi &= 0x003f0000;
+		hi |= (value & 0x3f) << 16;
+		_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		break;
+	case PCI_EHCI_FLADJ_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		hi &= ~0x00003f00;
+		hi |= value & 0x00003f00;
+		_wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+		break;
+	default:
+		break;
+	}
+}
+
+u32 pci_ehci_read_reg(int reg)
+{
+	u32 conf_data = 0;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		if (hi & PCI_COMMAND_MASTER)
+			conf_data |= PCI_COMMAND_MASTER;
+		if (hi & PCI_COMMAND_MEMORY)
+			conf_data |= PCI_COMMAND_MEMORY;
+		break;
+	case PCI_STATUS:
+		conf_data |= PCI_STATUS_66MHZ;
+		conf_data |= PCI_STATUS_FAST_BACK;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REVISION:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		conf_data =
+		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+					    PCI_NORMAL_LATENCY_TIMER);
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_EHCI_FLAG) {
+			conf_data = CS5536_EHCI_RANGE |
+			    PCI_BASE_ADDRESS_SPACE_MEMORY;
+			lo &= ~SOFT_BAR_EHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+			conf_data = lo & 0xfffff000;
+		}
+		break;
+	case PCI_CARDBUS_CIS:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYSTEM_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
+		break;
+	case PCI_ROM_ADDRESS:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPABILITY_LIST:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_LINE:
+		conf_data =
+		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
+		break;
+	case PCI_EHCI_LEGSMIEN_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = (hi & 0x003f0000) >> 16;
+		break;
+	case PCI_EHCI_LEGSMISTS_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = (hi & 0x3f000000) >> 24;
+		break;
+	case PCI_EHCI_FLADJ_REG:
+		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+		conf_data = hi & 0x00003f00;
+		break;
+	default:
+		break;
+	}
+
+	return conf_data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ide.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,179 @@
+/*
+ * the IDE Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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 <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ide_write_reg(int reg, u32 value)
+{
+	u32 hi = 0, lo = value;
+
+	switch (reg) {
+	case PCI_COMMAND:
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if (value & PCI_COMMAND_MASTER)
+			lo |= (0x03 << 4);
+		else
+			lo &= ~(0x03 << 4);
+		_wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+		break;
+	case PCI_STATUS:
+		if (value & PCI_STATUS_PARITY) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		value &= 0x0000ff00;
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0xffffff00;
+		hi |= (value >> 8);
+		_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+		break;
+	case PCI_BAR4_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_IDE_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if (value & 0x01) {
+			lo = (value & 0xfffffff0) | 0x1;
+			_wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
+
+			value &= 0xfffffffc;
+			hi = 0x60000000 | ((value & 0x000ff000) >> 12);
+			lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
+			_wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
+		}
+		break;
+	case PCI_IDE_CFG_REG:
+		if (value == CS5536_IDE_FLASH_SIGNATURE) {
+			_rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+			lo |= 0x01;
+			_wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+		} else
+			_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
+		break;
+	case PCI_IDE_DTC_REG:
+		_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
+		break;
+	case PCI_IDE_CAST_REG:
+		_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
+		break;
+	case PCI_IDE_ETC_REG:
+		_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
+		break;
+	case PCI_IDE_PM_REG:
+		_wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
+		break;
+	default:
+		break;
+	}
+}
+
+u32 pci_ide_read_reg(int reg)
+{
+	u32 conf_data = 0;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND:
+		_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+		if (lo & 0xfffffff0)
+			conf_data |= PCI_COMMAND_IO;
+		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+		if ((lo & 0x30) == 0x30)
+			conf_data |= PCI_COMMAND_MASTER;
+		break;
+	case PCI_STATUS:
+		conf_data |= PCI_STATUS_66MHZ;
+		conf_data |= PCI_STATUS_FAST_BACK;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REVISION:
+		_rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_IDE_CLASS_CODE << 8);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0x000000f8;
+		conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
+		break;
+	case PCI_BAR4_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_IDE_FLAG) {
+			conf_data = CS5536_IDE_RANGE |
+			    PCI_BASE_ADDRESS_SPACE_IO;
+			lo &= ~SOFT_BAR_IDE_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+			conf_data = lo & 0xfffffff0;
+			conf_data |= 0x01;
+			conf_data &= ~0x02;
+		}
+		break;
+	case PCI_CARDBUS_CIS:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYSTEM_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
+		break;
+	case PCI_ROM_ADDRESS:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPABILITY_LIST:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_LINE:
+		conf_data =
+		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
+		break;
+	case PCI_IDE_CFG_REG:
+		_rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_IDE_DTC_REG:
+		_rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_IDE_CAST_REG:
+		_rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+		conf_data = lo;
+		break;
+	case PCI_IDE_ETC_REG:
+		_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+		conf_data = lo;
+	case PCI_IDE_PM_REG:
+		_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+		conf_data = lo;
+		break;
+	default:
+		break;
+	}
+
+	return conf_data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_isa.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,316 @@
+/*
+ * the ISA Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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 <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+/* common variables for PCI_ISA_READ/WRITE_BAR */
+static const u32 divil_msr_reg[6] = {
+	DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO),
+	DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ),
+	DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI),
+};
+
+static const u32 soft_bar_flag[6] = {
+	SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG,
+	SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG,
+};
+
+static const u32 sb_msr_reg[6] = {
+	SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2),
+	SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5),
+};
+
+static const u32 bar_space_range[6] = {
+	CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE,
+	CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE,
+};
+
+static const int bar_space_len[6] = {
+	CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH,
+	CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH,
+};
+
+/*
+ * enable the divil module bar space.
+ *
+ * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
+ * and the RCONFx(0~5) reg to use the modules.
+ */
+static void divil_lbar_enable(void)
+{
+	u32 hi, lo;
+	int offset;
+
+	/*
+	 * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
+	 */
+
+	for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
+		_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
+		hi |= 0x01;
+		_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+	}
+}
+
+/*
+ * disable the divil module bar space.
+ */
+static void divil_lbar_disable(void)
+{
+	u32 hi, lo;
+	int offset;
+
+	for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
+		_rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
+		hi &= ~0x01;
+		_wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
+	}
+}
+
+/*
+ * BAR write: write value to the n BAR
+ */
+
+void pci_isa_write_bar(int n, u32 value)
+{
+	u32 hi = 0, lo = value;
+
+	if (value == PCI_BAR_RANGE_MASK) {
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		lo |= soft_bar_flag[n];
+		_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+	} else if (value & 0x01) {
+		/* NATIVE reg */
+		hi = 0x0000f001;
+		lo &= bar_space_range[n];
+		_wrmsr(divil_msr_reg[n], hi, lo);
+
+		/* RCONFx is 4bytes in units for I/O space */
+		hi = ((value & 0x000ffffc) << 12) |
+		    ((bar_space_len[n] - 4) << 12) | 0x01;
+		lo = ((value & 0x000ffffc) << 12) | 0x01;
+		_wrmsr(sb_msr_reg[n], hi, lo);
+	}
+}
+
+/*
+ * BAR read: read the n BAR
+ */
+
+u32 pci_isa_read_bar(int n)
+{
+	u32 conf_data = 0;
+	u32 hi, lo;
+
+	_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+	if (lo & soft_bar_flag[n]) {
+		conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
+		lo &= ~soft_bar_flag[n];
+		_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+	} else {
+		_rdmsr(divil_msr_reg[n], &hi, &lo);
+		conf_data = lo & bar_space_range[n];
+		conf_data |= 0x01;
+		conf_data &= ~0x02;
+	}
+	return conf_data;
+}
+
+/*
+ * isa_write: ISA write transfer
+ *
+ * We assume that this is not a bus master transfer.
+ */
+void pci_isa_write_reg(int reg, u32 value)
+{
+	u32 hi = 0, lo = value;
+	u32 temp;
+
+	switch (reg) {
+	case PCI_COMMAND:
+		if (value & PCI_COMMAND_IO)
+			divil_lbar_enable();
+		else
+			divil_lbar_disable();
+		break;
+	case PCI_STATUS:
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		temp = lo & 0x0000ffff;
+		if ((value & PCI_STATUS_SIG_TARGET_ABORT) &&
+		    (lo & SB_TAS_ERR_EN))
+			temp |= SB_TAS_ERR_FLAG;
+
+		if ((value & PCI_STATUS_REC_TARGET_ABORT) &&
+		    (lo & SB_TAR_ERR_EN))
+			temp |= SB_TAR_ERR_FLAG;
+
+		if ((value & PCI_STATUS_REC_MASTER_ABORT)
+		    && (lo & SB_MAR_ERR_EN))
+			temp |= SB_MAR_ERR_FLAG;
+
+		if ((value & PCI_STATUS_DETECTED_PARITY)
+		    && (lo & SB_PARE_ERR_EN))
+			temp |= SB_PARE_ERR_FLAG;
+
+		lo = temp;
+		_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		value &= 0x0000ff00;
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0xffffff00;
+		hi |= (value >> 8);
+		_wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+		break;
+	case PCI_BAR0_REG:
+		pci_isa_write_bar(0, value);
+		break;
+	case PCI_BAR1_REG:
+		pci_isa_write_bar(1, value);
+		break;
+	case PCI_BAR2_REG:
+		pci_isa_write_bar(2, value);
+		break;
+	case PCI_BAR3_REG:
+		pci_isa_write_bar(3, value);
+		break;
+	case PCI_BAR4_REG:
+		pci_isa_write_bar(4, value);
+		break;
+	case PCI_BAR5_REG:
+		pci_isa_write_bar(5, value);
+		break;
+	case PCI_UART1_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+		/* disable uart1 interrupt in PIC */
+		lo &= ~(0xf << 24);
+		if (value)	/* enable uart1 interrupt in PIC */
+			lo |= (CS5536_UART1_INTR << 24);
+		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		break;
+	case PCI_UART2_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+		/* disable uart2 interrupt in PIC */
+		lo &= ~(0xf << 28);
+		if (value)	/* enable uart2 interrupt in PIC */
+			lo |= (CS5536_UART2_INTR << 28);
+		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+		break;
+	case PCI_ISA_FIXUP_REG:
+		if (value) {
+			/* enable the TARGET ABORT/MASTER ABORT etc. */
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			lo |= 0x00000063;
+			_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+		}
+
+	default:
+		/* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
+		break;
+	}
+}
+
+/*
+ * isa_read: ISA read transfers
+ *
+ * We assume that this is not a bus master transfer.
+ */
+u32 pci_isa_read_reg(int reg)
+{
+	u32 conf_data = 0;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND:
+		/* we just check the first LBAR for the IO enable bit, */
+		/* maybe we should changed later. */
+		_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+		if (hi & 0x01)
+			conf_data |= PCI_COMMAND_IO;
+		break;
+	case PCI_STATUS:
+		conf_data |= PCI_STATUS_66MHZ;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		conf_data |= PCI_STATUS_FAST_BACK;
+
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_TAS_ERR_FLAG)
+			conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
+		if (lo & SB_TAR_ERR_FLAG)
+			conf_data |= PCI_STATUS_REC_TARGET_ABORT;
+		if (lo & SB_MAR_ERR_FLAG)
+			conf_data |= PCI_STATUS_REC_MASTER_ABORT;
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_DETECTED_PARITY;
+		break;
+	case PCI_CLASS_REVISION:
+		_rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_ISA_CLASS_CODE << 8);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+		hi &= 0x000000f8;
+		conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
+		break;
+		/*
+		 * we only use the LBAR of DIVIL, no RCONF used.
+		 * all of them are IO space.
+		 */
+	case PCI_BAR0_REG:
+		return pci_isa_read_bar(0);
+		break;
+	case PCI_BAR1_REG:
+		return pci_isa_read_bar(1);
+		break;
+	case PCI_BAR2_REG:
+		return pci_isa_read_bar(2);
+		break;
+	case PCI_BAR3_REG:
+		break;
+	case PCI_BAR4_REG:
+		return pci_isa_read_bar(4);
+		break;
+	case PCI_BAR5_REG:
+		return pci_isa_read_bar(5);
+		break;
+	case PCI_CARDBUS_CIS:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYSTEM_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
+		break;
+	case PCI_ROM_ADDRESS:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPABILITY_LIST:
+		conf_data = PCI_CAPLIST_POINTER;
+		break;
+	case PCI_INTERRUPT_LINE:
+		/* no interrupt used here */
+		conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
+		break;
+	default:
+		break;
+	}
+
+	return conf_data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,217 @@
+/*
+ * CS5536 General timer functions
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu zhangjin, wuzj@lemote.com
+ *
+ * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
+ *
+ *  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/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <asm/time.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+
+DEFINE_SPINLOCK(mfgpt_lock);
+EXPORT_SYMBOL(mfgpt_lock);
+
+static u32 mfgpt_base;
+
+/*
+ * Initialize the MFGPT timer.
+ *
+ * This is also called after resume to bring the MFGPT into operation again.
+ */
+
+/* disable counter */
+void disable_mfgpt0_counter(void)
+{
+	outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP);
+}
+EXPORT_SYMBOL(disable_mfgpt0_counter);
+
+/* enable counter, comparator2 to event mode, 14.318MHz clock */
+void enable_mfgpt0_counter(void)
+{
+	outw(0xe310, MFGPT0_SETUP);
+}
+EXPORT_SYMBOL(enable_mfgpt0_counter);
+
+static void init_mfgpt_timer(enum clock_event_mode mode,
+			     struct clock_event_device *evt)
+{
+	spin_lock(&mfgpt_lock);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		outw(COMPARE, MFGPT0_CMP2);	/* set comparator2 */
+		outw(0, MFGPT0_CNT);	/* set counter to 0 */
+		enable_mfgpt0_counter();
+		break;
+
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
+		    evt->mode == CLOCK_EVT_MODE_ONESHOT)
+			disable_mfgpt0_counter();
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* The oneshot mode have very high deviation, Not use it! */
+		break;
+
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do here */
+		break;
+	}
+	spin_unlock(&mfgpt_lock);
+}
+
+static struct clock_event_device mfgpt_clockevent = {
+	.name = "mfgpt",
+	.features = CLOCK_EVT_FEAT_PERIODIC,
+	.set_mode = init_mfgpt_timer,
+	.irq = CS5536_MFGPT_INTR,
+};
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	u32 basehi;
+
+	/*
+	 * get MFGPT base address
+	 *
+	 * NOTE: do not remove me, it's need for the value of mfgpt_base is
+	 * variable
+	 */
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
+
+	/* ack */
+	outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP);
+
+	mfgpt_clockevent.event_handler(&mfgpt_clockevent);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction irq5 = {
+	.handler = timer_interrupt,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+	.name = "timer"
+};
+
+/*
+ * Initialize the conversion factor and the min/max deltas of the clock event
+ * structure and register the clock event source with the framework.
+ */
+void __init setup_mfgpt0_timer(void)
+{
+	u32 basehi;
+	struct clock_event_device *cd = &mfgpt_clockevent;
+	unsigned int cpu = smp_processor_id();
+
+	cd->cpumask = cpumask_of(cpu);
+	clockevent_set_clock(cd, MFGPT_TICK_RATE);
+	cd->max_delta_ns = clockevent_delta2ns(0xffff, cd);
+	cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
+
+	/* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */
+	_wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100);
+
+	/* Enable Interrupt Gate 5 */
+	_wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000);
+
+	/* get MFGPT base address */
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
+
+	clockevents_register_device(cd);
+
+	setup_irq(CS5536_MFGPT_INTR, &irq5);
+}
+
+/*
+ * Since the MFGPT overflows every tick, its not very useful
+ * to just read by itself. So use jiffies to emulate a free
+ * running counter:
+ */
+static cycle_t mfgpt_read(struct clocksource *cs)
+{
+	unsigned long flags;
+	int count;
+	u32 jifs;
+	static int old_count;
+	static u32 old_jifs;
+
+	spin_lock_irqsave(&mfgpt_lock, flags);
+	/*
+	 * Although our caller may have the read side of xtime_lock,
+	 * this is now a seqlock, and we are cheating in this routine
+	 * by having side effects on state that we cannot undo if
+	 * there is a collision on the seqlock and our caller has to
+	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
+	 * jiffies as volatile despite the lock.  We read jiffies
+	 * before latching the timer count to guarantee that although
+	 * the jiffies value might be older than the count (that is,
+	 * the counter may underflow between the last point where
+	 * jiffies was incremented and the point where we latch the
+	 * count), it cannot be newer.
+	 */
+	jifs = jiffies;
+	/* read the count */
+	count = inw(MFGPT0_CNT);
+
+	/*
+	 * It's possible for count to appear to go the wrong way for this
+	 * reason:
+	 *
+	 *  The timer counter underflows, but we haven't handled the resulting
+	 *  interrupt and incremented jiffies yet.
+	 *
+	 * Previous attempts to handle these cases intelligently were buggy, so
+	 * we just do the simple thing now.
+	 */
+	if (count < old_count && jifs == old_jifs)
+		count = old_count;
+
+	old_count = count;
+	old_jifs = jifs;
+
+	spin_unlock_irqrestore(&mfgpt_lock, flags);
+
+	return (cycle_t) (jifs * COMPARE) + count;
+}
+
+static struct clocksource clocksource_mfgpt = {
+	.name = "mfgpt",
+	.rating = 120, /* Functional for real use, but not desired */
+	.read = mfgpt_read,
+	.mask = CLOCKSOURCE_MASK(32),
+	.mult = 0,
+	.shift = 22,
+};
+
+int __init init_mfgpt_clocksource(void)
+{
+	if (num_possible_cpus() > 1)	/* MFGPT does not scale! */
+		return 0;
+
+	clocksource_mfgpt.mult = clocksource_hz2mult(MFGPT_TICK_RATE, 22);
+	return clocksource_register(&clocksource_mfgpt);
+}
+
+arch_initcall(init_mfgpt_clocksource);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,147 @@
+/*
+ * the OHCI Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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 <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ohci_write_reg(int reg, u32 value)
+{
+	u32 hi = 0, lo = value;
+
+	switch (reg) {
+	case PCI_COMMAND:
+		_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+		if (value & PCI_COMMAND_MASTER)
+			hi |= PCI_COMMAND_MASTER;
+		else
+			hi &= ~PCI_COMMAND_MASTER;
+
+		if (value & PCI_COMMAND_MEMORY)
+			hi |= PCI_COMMAND_MEMORY;
+		else
+			hi &= ~PCI_COMMAND_MEMORY;
+		_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+		break;
+	case PCI_STATUS:
+		if (value & PCI_STATUS_PARITY) {
+			_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+			if (lo & SB_PARE_ERR_FLAG) {
+				lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+				_wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+			}
+		}
+		break;
+	case PCI_BAR0_REG:
+		if (value == PCI_BAR_RANGE_MASK) {
+			_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+			lo |= SOFT_BAR_OHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else if ((value & 0x01) == 0x00) {
+			_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+
+			value &= 0xfffffff0;
+			hi = 0x40000000 | ((value & 0xff000000) >> 24);
+			lo = 0x000fffff | ((value & 0x00fff000) << 8);
+			_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
+		}
+		break;
+	case PCI_OHCI_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+		lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT);
+		if (value)	/* enable all the usb interrupt in PIC */
+			lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT);
+		_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+		break;
+	default:
+		break;
+	}
+}
+
+u32 pci_ohci_read_reg(int reg)
+{
+	u32 conf_data = 0;
+	u32 hi, lo;
+
+	switch (reg) {
+	case PCI_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
+		break;
+	case PCI_COMMAND:
+		_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+		if (hi & PCI_COMMAND_MASTER)
+			conf_data |= PCI_COMMAND_MASTER;
+		if (hi & PCI_COMMAND_MEMORY)
+			conf_data |= PCI_COMMAND_MEMORY;
+		break;
+	case PCI_STATUS:
+		conf_data |= PCI_STATUS_66MHZ;
+		conf_data |= PCI_STATUS_FAST_BACK;
+		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+		if (lo & SB_PARE_ERR_FLAG)
+			conf_data |= PCI_STATUS_PARITY;
+		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+		break;
+	case PCI_CLASS_REVISION:
+		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+		conf_data = lo & 0x000000ff;
+		conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
+		break;
+	case PCI_CACHE_LINE_SIZE:
+		conf_data =
+		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+					    PCI_NORMAL_LATENCY_TIMER);
+		break;
+	case PCI_BAR0_REG:
+		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+		if (lo & SOFT_BAR_OHCI_FLAG) {
+			conf_data = CS5536_OHCI_RANGE |
+			    PCI_BASE_ADDRESS_SPACE_MEMORY;
+			lo &= ~SOFT_BAR_OHCI_FLAG;
+			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+		} else {
+			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+			conf_data = lo & 0xffffff00;
+			conf_data &= ~0x0000000f;	/* 32bit mem */
+		}
+		break;
+	case PCI_CARDBUS_CIS:
+		conf_data = PCI_CARDBUS_CIS_POINTER;
+		break;
+	case PCI_SUBSYSTEM_VENDOR_ID:
+		conf_data =
+		    CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
+		break;
+	case PCI_ROM_ADDRESS:
+		conf_data = PCI_EXPANSION_ROM_BAR;
+		break;
+	case PCI_CAPABILITY_LIST:
+		conf_data = PCI_CAPLIST_USB_POINTER;
+		break;
+	case PCI_INTERRUPT_LINE:
+		conf_data =
+		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
+		break;
+	case PCI_OHCI_INT_REG:
+		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+		if ((lo & 0x00000f00) == CS5536_USB_INTR)
+			conf_data = 1;
+		break;
+	default:
+		break;
+	}
+
+	return conf_data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/cs5536_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,87 @@
+/*
+ * read/write operation to the PCI config space of CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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.
+ *
+ *	the Virtual Support Module(VSM) for virtulizing the PCI
+ *	configure space are defined in cs5536_modulename.c respectively,
+ *
+ *	after this virtulizing, user can access the PCI configure space
+ *	directly as a normal multi-function PCI device which follows
+ *	the PCI-2.2 spec.
+ */
+
+#include <linux/types.h>
+#include <cs5536/cs5536_vsm.h>
+
+enum {
+	CS5536_FUNC_START = -1,
+	CS5536_ISA_FUNC,
+	reserved_func,
+	CS5536_IDE_FUNC,
+	CS5536_ACC_FUNC,
+	CS5536_OHCI_FUNC,
+	CS5536_EHCI_FUNC,
+	CS5536_FUNC_END,
+};
+
+static const cs5536_pci_vsm_write vsm_conf_write[] = {
+	[CS5536_ISA_FUNC]	pci_isa_write_reg,
+	[reserved_func]		NULL,
+	[CS5536_IDE_FUNC]	pci_ide_write_reg,
+	[CS5536_ACC_FUNC]	pci_acc_write_reg,
+	[CS5536_OHCI_FUNC]	pci_ohci_write_reg,
+	[CS5536_EHCI_FUNC]	pci_ehci_write_reg,
+};
+
+static const cs5536_pci_vsm_read vsm_conf_read[] = {
+	[CS5536_ISA_FUNC]	pci_isa_read_reg,
+	[reserved_func]		NULL,
+	[CS5536_IDE_FUNC]	pci_ide_read_reg,
+	[CS5536_ACC_FUNC]	pci_acc_read_reg,
+	[CS5536_OHCI_FUNC]	pci_ohci_read_reg,
+	[CS5536_EHCI_FUNC]	pci_ehci_read_reg,
+};
+
+/*
+ * write to PCI config space and transfer it to MSR write.
+ */
+void cs5536_pci_conf_write4(int function, int reg, u32 value)
+{
+	if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
+		return;
+	if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0))
+		return;
+
+	if (vsm_conf_write[function] != NULL)
+		vsm_conf_write[function](reg, value);
+}
+
+/*
+ * read PCI config space and transfer it to MSR access.
+ */
+u32 cs5536_pci_conf_read4(int function, int reg)
+{
+	u32 data = 0;
+
+	if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
+		return 0;
+	if ((reg < 0) || ((reg & 0x03) != 0))
+		return 0;
+	if (reg > 0x100)
+		return 0xffffffff;
+
+	if (vsm_conf_read[function] != NULL)
+		data = vsm_conf_read[function](reg);
+
+	return data;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/Makefile linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/cs5536/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/cs5536/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,13 @@
+#
+# Makefile for CS5536 support.
+#
+
+obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \
+			cs5536_isa.o cs5536_ehci.o
+
+#
+# Enable cs5536 mfgpt Timer
+#
+obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o
+
+EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/early_printk.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/early_printk.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/early_printk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/early_printk.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*  early printk support
  *
  *  Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- *  Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ *  Copyright (c) 2009 Lemote Inc.
  *  Author: Wu Zhangjin, wuzj@lemote.com
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -12,26 +12,29 @@
 #include <linux/serial_reg.h>
 
 #include <loongson.h>
-#include <machine.h>
 
 #define PORT(base, offset) (u8 *)(base + offset)
 
-static inline unsigned int serial_in(phys_addr_t base, int offset)
+static inline unsigned int serial_in(unsigned char *base, int offset)
 {
 	return readb(PORT(base, offset));
 }
 
-static inline void serial_out(phys_addr_t base, int offset, int value)
+static inline void serial_out(unsigned char *base, int offset, int value)
 {
 	writeb(value, PORT(base, offset));
 }
 
 void prom_putchar(char c)
 {
-	phys_addr_t uart_base =
-		(phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8);
+	int timeout;
+	unsigned char *uart_base;
 
-	while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0)
+	uart_base = (unsigned char *)_loongson_uart_base;
+	timeout = 1024;
+
+	while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
+			(timeout-- > 0))
 		;
 
 	serial_out(uart_base, UART_TX, c);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/env.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/env.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/env.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/env.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,11 +17,14 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
+#include <linux/module.h>
+
 #include <asm/bootinfo.h>
 
 #include <loongson.h>
 
 unsigned long bus_clock, cpu_clock_freq;
+EXPORT_SYMBOL(cpu_clock_freq);
 unsigned long memsize, highmemsize;
 
 /* pmon passes arguments in 32bit pointers */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/init.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/init.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Copyright (C) 2009 Lemote Inc.
  * Author: Wu Zhangjin, wuzj@lemote.com
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -10,19 +10,28 @@
 
 #include <linux/bootmem.h>
 
-#include <asm/bootinfo.h>
-
 #include <loongson.h>
 
+/* Loongson CPU address windows config space base address */
+unsigned long __maybe_unused _loongson_addrwincfg_base;
+
 void __init prom_init(void)
 {
-    /* init base address of io space */
+	/* init base address of io space */
 	set_io_port_base((unsigned long)
-		ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE));
+		ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+	_loongson_addrwincfg_base = (unsigned long)
+		ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE);
+#endif
 
 	prom_init_cmdline();
 	prom_init_env();
 	prom_init_memory();
+
+	/*init the uart base address */
+	prom_init_uart_base();
 }
 
 void __init prom_free_prom_memory(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/irq.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,21 +20,21 @@ void bonito_irqdispatch(void)
 	int i;
 
 	/* workaround the IO dma problem: let cpu looping to allow DMA finish */
-	int_status = BONITO_INTISR;
+	int_status = LOONGSON_INTISR;
 	if (int_status & (1 << 10)) {
 		while (int_status & (1 << 10)) {
 			udelay(1);
-			int_status = BONITO_INTISR;
+			int_status = LOONGSON_INTISR;
 		}
 	}
 
 	/* Get pending sources, masked by current enables */
-	int_status = BONITO_INTISR & BONITO_INTEN;
+	int_status = LOONGSON_INTISR & LOONGSON_INTEN;
 
 	if (int_status != 0) {
 		i = __ffs(int_status);
 		int_status &= ~(1 << i);
-		do_IRQ(BONITO_IRQ_BASE + i);
+		do_IRQ(LOONGSON_IRQ_BASE + i);
 	}
 }
 
@@ -60,13 +60,13 @@ void __init arch_init_irq(void)
 	set_irq_trigger_mode();
 
 	/* no steer */
-	BONITO_INTSTEER = 0;
+	LOONGSON_INTSTEER = 0;
 
 	/*
 	 * Mask out all interrupt by writing "1" to all bit position in
 	 * the interrupt reset reg.
 	 */
-	BONITO_INTENCLR = ~0;
+	LOONGSON_INTENCLR = ~0;
 
 	/* machine specific irq init */
 	mach_init_irq();
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/machtype.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/machtype.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/machtype.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/machtype.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,9 @@
 #include <loongson.h>
 #include <machine.h>
 
+/* please ensure the length of the machtype string is less than 50 */
+#define MACHTYPE_LEN 50
+
 static const char *system_types[] = {
 	[MACH_LOONGSON_UNKNOWN]         "unknown loongson machine",
 	[MACH_LEMOTE_FL2E]              "lemote-fuloong-2e-box",
@@ -22,29 +25,35 @@ static const char *system_types[] = {
 	[MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
 	[MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
 	[MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+	[MACH_LEMOTE_NAS]		"lemote-nas-2f",
+	[MACH_LEMOTE_LL2F]              "lemote-lynloong-2f",
 	[MACH_LOONGSON_END]             NULL,
 };
 
 const char *get_system_type(void)
 {
-	if (mips_machtype == MACH_UNKNOWN)
-		mips_machtype = LOONGSON_MACHTYPE;
-
 	return system_types[mips_machtype];
 }
 
-static __init int machtype_setup(char *str)
+void __init prom_init_machtype(void)
 {
+	char *p, str[MACHTYPE_LEN];
 	int machtype = MACH_LEMOTE_FL2E;
 
-	if (!str)
-		return -EINVAL;
+	mips_machtype = LOONGSON_MACHTYPE;
+
+	p = strstr(arcs_cmdline, "machtype=");
+	if (!p)
+		return;
+	p += strlen("machtype=");
+	strncpy(str, p, MACHTYPE_LEN);
+	p = strstr(str, " ");
+	if (p)
+		*p = '\0';
 
 	for (; system_types[machtype]; machtype++)
 		if (strstr(system_types[machtype], str)) {
 			mips_machtype = machtype;
 			break;
 		}
-	return 0;
 }
-__setup("machtype=", machtype_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/Makefile linux-libre-2.6.33-gnu1/arch/mips/loongson/common/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,9 +3,23 @@
 #
 
 obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
-    pci.o bonito-irq.o mem.o machtype.o
+    pci.o bonito-irq.o mem.o machtype.o platform.o
 
 #
-# Early printk support
+# Serial port support
 #
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_SERIAL_8250) += serial.o
+obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
+
+#
+# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
+# space
+#
+obj-$(CONFIG_CS5536) += cs5536/
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/mem.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/mem.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/mem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/mem.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,24 +12,107 @@
 
 #include <loongson.h>
 #include <mem.h>
+#include <pci.h>
 
 void __init prom_init_memory(void)
 {
     add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+
+    add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
+			    20), BOOT_MEM_RESERVED);
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+	{
+		int bit;
+
+		bit = fls(memsize + highmemsize);
+		if (bit != ffs(memsize + highmemsize))
+			bit += 20;
+		else
+			bit = bit + 20 - 1;
+
+		/* set cpu window3 to map CPU to DDR: 2G -> 2G */
+		LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
+					  0x80000000ul, (1 << bit));
+		mmiowb();
+	}
+#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
 #ifdef CONFIG_64BIT
-    if (highmemsize > 0)
-	add_memory_region(LOONGSON_HIGHMEM_START,
-		highmemsize << 20, BOOT_MEM_RAM);
-#endif /* CONFIG_64BIT */
+	if (highmemsize > 0)
+		add_memory_region(LOONGSON_HIGHMEM_START,
+				  highmemsize << 20, BOOT_MEM_RAM);
+
+	add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
+			  LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
+
+#endif /* !CONFIG_64BIT */
 }
 
 /* override of arch/mips/mm/cache.c: __uncached_access */
 int __uncached_access(struct file *file, unsigned long addr)
 {
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 
 	return addr >= __pa(high_memory) ||
 		((addr >= LOONGSON_MMIO_MEM_START) &&
 		 (addr < LOONGSON_MMIO_MEM_END));
 }
+
+#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
+
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+
+static unsigned long uca_start, uca_end;
+
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+			      unsigned long size, pgprot_t vma_prot)
+{
+	unsigned long offset = pfn << PAGE_SHIFT;
+	unsigned long end = offset + size;
+
+	if (__uncached_access(file, offset)) {
+		if (((uca_start && offset) >= uca_start) &&
+		    (end <= uca_end))
+			return __pgprot((pgprot_val(vma_prot) &
+					 ~_CACHE_MASK) |
+					_CACHE_UNCACHED_ACCELERATED);
+		else
+			return pgprot_noncached(vma_prot);
+	}
+	return vma_prot;
+}
+
+static int __init find_vga_mem_init(void)
+{
+	struct pci_dev *dev = 0;
+	struct resource *r;
+	int idx;
+
+	if (uca_start)
+		return 0;
+
+	for_each_pci_dev(dev) {
+		if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+			for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+				r = &dev->resource[idx];
+				if (!r->start && r->end)
+					continue;
+				if (r->flags & IORESOURCE_IO)
+					continue;
+				if (r->flags & IORESOURCE_MEM) {
+					uca_start = r->start;
+					uca_end = r->end;
+					return 0;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+late_initcall(find_vga_mem_init);
+#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/pci.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pci.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@ static struct resource loongson_pci_io_r
 };
 
 static struct pci_controller  loongson_pci_controller = {
-	.pci_ops        = &bonito64_pci_ops,
+	.pci_ops        = &loongson_pci_ops,
 	.io_resource    = &loongson_pci_io_resource,
 	.mem_resource   = &loongson_pci_mem_resource,
 	.mem_offset     = 0x00000000UL,
@@ -44,15 +44,15 @@ static void __init setup_pcimap(void)
 	 * pcimap: PCI_MAP2  PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
 	 * 	     [<2G]   [384M,448M] [320M,384M] [0M,64M]
 	 */
-	BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 |
-		BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) |
-		BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) |
-		BONITO_PCIMAP_WIN(0, 0);
+	LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
+		LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
+		LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
+		LOONGSON_PCIMAP_WIN(0, 0);
 
 	/*
 	 * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
 	 */
-	BONITO_PCIBASE0 = 0x80000000ul;   /* base: 2G -> mmap: 0M */
+	LOONGSON_PCIBASE0 = 0x80000000ul;   /* base: 2G -> mmap: 0M */
 	/* size: 256M, burst transmission, pre-fetch enable, 64bit */
 	LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
 	LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
@@ -67,6 +67,14 @@ static void __init setup_pcimap(void)
 	/* can not change gnt to break pci transfer when device's gnt not
 	deassert for some broken device */
 	LOONGSON_PXARB_CFG = 0x00fe0105ul;
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+	/*
+	 * set cpu addr window2 to map CPU address space to PCI address space
+	 */
+	LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
+		LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
+#endif
 }
 
 static int __init pcibios_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/platform.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/platform.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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/err.h>
+#include <linux/platform_device.h>
+
+static struct platform_device loongson2_cpufreq_device = {
+	.name = "loongson2_cpufreq",
+	.id = -1,
+};
+
+static int __init loongson2_cpufreq_init(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	/* Only 2F revision and it's successors support CPUFreq */
+	if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
+		return platform_device_register(&loongson2_cpufreq_device);
+
+	return -ENODEV;
+}
+
+arch_initcall(loongson2_cpufreq_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/pm.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pm.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,161 @@
+/*
+ * loongson-specific suspend support
+ *
+ *  Copyright (C) 2009 Lemote Inc.
+ *  Author: Wu Zhangjin <wuzj@lemote.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/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+
+static unsigned int __maybe_unused cached_master_mask;	/* i8259A */
+static unsigned int __maybe_unused cached_slave_mask;
+static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
+
+void arch_suspend_disable_irqs(void)
+{
+	/* disable all mips events */
+	local_irq_disable();
+
+#ifdef CONFIG_I8259
+	/* disable all events of i8259A */
+	cached_slave_mask = inb(PIC_SLAVE_IMR);
+	cached_master_mask = inb(PIC_MASTER_IMR);
+
+	outb(0xff, PIC_SLAVE_IMR);
+	inb(PIC_SLAVE_IMR);
+	outb(0xff, PIC_MASTER_IMR);
+	inb(PIC_MASTER_IMR);
+#endif
+	/* disable all events of bonito */
+	cached_bonito_irq_mask = LOONGSON_INTEN;
+	LOONGSON_INTENCLR = 0xffff;
+	(void)LOONGSON_INTENCLR;
+}
+
+void arch_suspend_enable_irqs(void)
+{
+	/* enable all mips events */
+	local_irq_enable();
+#ifdef CONFIG_I8259
+	/* only enable the cached events of i8259A */
+	outb(cached_slave_mask, PIC_SLAVE_IMR);
+	outb(cached_master_mask, PIC_MASTER_IMR);
+#endif
+	/* enable all cached events of bonito */
+	LOONGSON_INTENSET = cached_bonito_irq_mask;
+	(void)LOONGSON_INTENSET;
+}
+
+/*
+ * Setup the board-specific events for waking up loongson from wait mode
+ */
+void __weak setup_wakeup_events(void)
+{
+}
+
+/*
+ * Check wakeup events
+ */
+int __weak wakeup_loongson(void)
+{
+	return 1;
+}
+
+/*
+ * If the events are really what we want to wakeup the CPU, wake it up
+ * otherwise put the CPU asleep again.
+ */
+static void wait_for_wakeup_events(void)
+{
+	while (!wakeup_loongson())
+		LOONGSON_CHIPCFG0 &= ~0x7;
+}
+
+/*
+ * Stop all perf counters
+ *
+ * $24 is the control register of Loongson perf counter
+ */
+static inline void stop_perf_counters(void)
+{
+	__write_64bit_c0_register($24, 0, 0);
+}
+
+
+static void loongson_suspend_enter(void)
+{
+	static unsigned int cached_cpu_freq;
+
+	/* setup wakeup events via enabling the IRQs */
+	setup_wakeup_events();
+
+	stop_perf_counters();
+
+	cached_cpu_freq = LOONGSON_CHIPCFG0;
+
+	/* Put CPU into wait mode */
+	LOONGSON_CHIPCFG0 &= ~0x7;
+
+	/* wait for the given events to wakeup cpu from wait mode */
+	wait_for_wakeup_events();
+
+	LOONGSON_CHIPCFG0 = cached_cpu_freq;
+	mmiowb();
+}
+
+void __weak mach_suspend(void)
+{
+}
+
+void __weak mach_resume(void)
+{
+}
+
+static int loongson_pm_enter(suspend_state_t state)
+{
+	mach_suspend();
+
+	/* processor specific suspend */
+	loongson_suspend_enter();
+
+	mach_resume();
+
+	return 0;
+}
+
+static int loongson_pm_valid_state(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_ON:
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
+static struct platform_suspend_ops loongson_pm_ops = {
+	.valid	= loongson_pm_valid_state,
+	.enter	= loongson_pm_enter,
+};
+
+static int __init loongson_pm_init(void)
+{
+	suspend_set_ops(&loongson_pm_ops);
+
+	return 0;
+}
+arch_initcall(loongson_pm_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/reset.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/reset.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/reset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,7 @@ static void loongson_restart(char *comma
 	mach_prepare_reboot();
 
 	/* reboot via jumping to boot base address */
-	((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) ();
+	((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
 }
 
 static void loongson_halt(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/serial.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/serial.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/serial.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/serial.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,76 @@
+/*
+ * 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) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Yan hua (yanhua@lemote.com)
+ * Author: Wu Zhangjin (wuzj@lemote.com)
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define PORT(int)			\
+{								\
+	.irq		= int,					\
+	.uartclk	= 1843200,				\
+	.iotype		= UPIO_PORT,				\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
+	.regshift	= 0,					\
+}
+
+#define PORT_M(int)				\
+{								\
+	.irq		= MIPS_CPU_IRQ_BASE + (int),		\
+	.uartclk	= 3686400,				\
+	.iotype		= UPIO_MEM,				\
+	.membase	= (void __iomem *)NULL,			\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
+	.regshift	= 0,					\
+}
+
+static struct plat_serial8250_port uart8250_data[][2] = {
+	[MACH_LOONGSON_UNKNOWN]         {},
+	[MACH_LEMOTE_FL2E]              {PORT(4), {} },
+	[MACH_LEMOTE_FL2F]              {PORT(3), {} },
+	[MACH_LEMOTE_ML2F7]             {PORT_M(3), {} },
+	[MACH_LEMOTE_YL2F89]            {PORT_M(3), {} },
+	[MACH_DEXXON_GDIUM2F10]         {PORT_M(3), {} },
+	[MACH_LEMOTE_NAS]               {PORT_M(3), {} },
+	[MACH_LEMOTE_LL2F]              {PORT(3), {} },
+	[MACH_LOONGSON_END]             {},
+};
+
+static struct platform_device uart8250_device = {
+	.name = "serial8250",
+	.id = PLAT8250_DEV_PLATFORM,
+};
+
+static int __init serial_init(void)
+{
+	unsigned char iotype;
+
+	iotype = uart8250_data[mips_machtype][0].iotype;
+
+	if (UPIO_MEM == iotype)
+		uart8250_data[mips_machtype][0].membase =
+			(void __iomem *)_loongson_uart_base;
+	else if (UPIO_PORT == iotype)
+		uart8250_data[mips_machtype][0].iobase =
+		    loongson_uart_base - LOONGSON_PCIIO_BASE;
+
+	uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
+
+	return platform_device_register(&uart8250_device);
+}
+
+device_initcall(serial_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/time.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/time.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,11 +14,14 @@
 #include <asm/time.h>
 
 #include <loongson.h>
+#include <cs5536/cs5536_mfgpt.h>
 
 void __init plat_time_init(void)
 {
 	/* setup mips r4k timer */
 	mips_hpt_frequency = cpu_clock_freq / 2;
+
+	setup_mfgpt0_timer();
 }
 
 void read_persistent_clock(struct timespec *ts)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/common/uart_base.c linux-libre-2.6.33-gnu1/arch/mips/loongson/common/uart_base.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/common/uart_base.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/common/uart_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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/module.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+/* ioremapped */
+unsigned long _loongson_uart_base;
+EXPORT_SYMBOL(_loongson_uart_base);
+/* raw */
+unsigned long loongson_uart_base;
+EXPORT_SYMBOL(loongson_uart_base);
+
+void prom_init_loongson_uart_base(void)
+{
+	switch (mips_machtype) {
+	case MACH_LEMOTE_FL2E:
+		loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8;
+		break;
+	case MACH_LEMOTE_FL2F:
+	case MACH_LEMOTE_LL2F:
+		loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8;
+		break;
+	case MACH_LEMOTE_ML2F7:
+	case MACH_LEMOTE_YL2F89:
+	case MACH_DEXXON_GDIUM2F10:
+	case MACH_LEMOTE_NAS:
+	default:
+		/* The CPU provided serial port */
+		loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8;
+		break;
+	}
+
+	_loongson_uart_base =
+		(unsigned long)ioremap_nocache(loongson_uart_base, 8);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/fuloong-2e/irq.c linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/fuloong-2e/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,8 +47,8 @@ static struct irqaction cascade_irqactio
 void __init set_irq_trigger_mode(void)
 {
 	/* most bonito irq should be level triggered */
-	BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
-	    BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
+	LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
+	    LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
 }
 
 void __init mach_init_irq(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/fuloong-2e/reset.c linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/reset.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/fuloong-2e/reset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/fuloong-2e/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,8 +14,8 @@
 
 void mach_prepare_reboot(void)
 {
-	BONITO_BONGENCFG &= ~(1 << 2);
-	BONITO_BONGENCFG |= (1 << 2);
+	LOONGSON_GENCFG &= ~(1 << 2);
+	LOONGSON_GENCFG |= (1 << 2);
 }
 
 void mach_prepare_shutdown(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/Kconfig linux-libre-2.6.33-gnu1/arch/mips/loongson/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,31 +1,85 @@
 choice
-    prompt "Machine Type"
-    depends on MACH_LOONGSON
+	prompt "Machine Type"
+	depends on MACH_LOONGSON
 
 config LEMOTE_FULOONG2E
-    bool "Lemote Fuloong(2e) mini-PC"
-    select ARCH_SPARSEMEM_ENABLE
-    select CEVT_R4K
-    select CSRC_R4K
-    select SYS_HAS_CPU_LOONGSON2E
-    select DMA_NONCOHERENT
-    select BOOT_ELF32
-    select BOARD_SCACHE
-    select HW_HAS_PCI
-    select I8259
-    select ISA
-    select IRQ_CPU
-    select SYS_SUPPORTS_32BIT_KERNEL
-    select SYS_SUPPORTS_64BIT_KERNEL
-    select SYS_SUPPORTS_LITTLE_ENDIAN
-    select SYS_SUPPORTS_HIGHMEM
-    select SYS_HAS_EARLY_PRINTK
-    select GENERIC_HARDIRQS_NO__DO_IRQ
-    select GENERIC_ISA_DMA_SUPPORT_BROKEN
-    select CPU_HAS_WB
-    help
-      Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
-      an FPGA northbridge
+	bool "Lemote Fuloong(2e) mini-PC"
+	select ARCH_SPARSEMEM_ENABLE
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_LOONGSON2E
+	select DMA_NONCOHERENT
+	select BOOT_ELF32
+	select BOARD_SCACHE
+	select HW_HAS_PCI
+	select I8259
+	select ISA
+	select IRQ_CPU
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_HIGHMEM
+	select SYS_HAS_EARLY_PRINTK
+	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select GENERIC_ISA_DMA_SUPPORT_BROKEN
+	select CPU_HAS_WB
+	help
+	  Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+	  an FPGA northbridge
 
-      Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+	  Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+
+config LEMOTE_MACH2F
+	bool "Lemote Loongson 2F family machines"
+	select ARCH_SPARSEMEM_ENABLE
+	select BOARD_SCACHE
+	select BOOT_ELF32
+	select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
+	select CPU_HAS_WB
+	select CS5536
+	select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
+	select DMA_NONCOHERENT
+	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select GENERIC_ISA_DMA_SUPPORT_BROKEN
+	select HW_HAS_PCI
+	select I8259
+	select IRQ_CPU
+	select ISA
+	select SYS_HAS_CPU_LOONGSON2F
+	select SYS_HAS_EARLY_PRINTK
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select SYS_SUPPORTS_HIGHMEM
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	help
+	  Lemote Loongson 2F family machines utilize the 2F revision of
+	  Loongson processor and the AMD CS5536 south bridge.
+
+	  These family machines include fuloong2f mini PC, yeeloong2f notebook,
+	  LingLoong allinone PC and so forth.
 endchoice
+
+config CS5536
+	bool
+
+config CS5536_MFGPT
+	bool "CS5536 MFGPT Timer"
+	depends on CS5536
+	select MIPS_EXTERNAL_TIMER
+	help
+	  This option enables the mfgpt0 timer of AMD CS5536.
+
+	  If you want to enable the Loongson2 CPUFreq Driver, Please enable
+	  this option at first, otherwise, You will get wrong system time.
+
+	  If unsure, say Yes.
+
+config LOONGSON_SUSPEND
+	bool
+	default y
+	depends on CPU_SUPPORTS_CPUFREQ && SUSPEND
+
+config LOONGSON_UART_BASE
+	bool
+	default y
+	depends on EARLY_PRINTK || SERIAL_8250
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,130 @@
+/*
+ * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
+ *
+ *  Copyright (C) 2008 Lemote Inc.
+ *  Author: liujl <liujl@lemote.com>, 2008-04-20
+ *
+ * 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/spinlock.h>
+#include <linux/delay.h>
+
+#include "ec_kb3310b.h"
+
+static DEFINE_SPINLOCK(index_access_lock);
+static DEFINE_SPINLOCK(port_access_lock);
+
+unsigned char ec_read(unsigned short addr)
+{
+	unsigned char value;
+	unsigned long flags;
+
+	spin_lock_irqsave(&index_access_lock, flags);
+	outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
+	outb((addr & 0x00ff), EC_IO_PORT_LOW);
+	value = inb(EC_IO_PORT_DATA);
+	spin_unlock_irqrestore(&index_access_lock, flags);
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(ec_read);
+
+void ec_write(unsigned short addr, unsigned char val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&index_access_lock, flags);
+	outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
+	outb((addr & 0x00ff), EC_IO_PORT_LOW);
+	outb(val, EC_IO_PORT_DATA);
+	/*  flush the write action */
+	inb(EC_IO_PORT_DATA);
+	spin_unlock_irqrestore(&index_access_lock, flags);
+
+	return;
+}
+EXPORT_SYMBOL_GPL(ec_write);
+
+/*
+ * This function is used for EC command writes and corresponding status queries.
+ */
+int ec_query_seq(unsigned char cmd)
+{
+	int timeout;
+	unsigned char status;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&port_access_lock, flags);
+
+	/* make chip goto reset mode */
+	udelay(EC_REG_DELAY);
+	outb(cmd, EC_CMD_PORT);
+	udelay(EC_REG_DELAY);
+
+	/* check if the command is received by ec */
+	timeout = EC_CMD_TIMEOUT;
+	status = inb(EC_STS_PORT);
+	while (timeout-- && (status & (1 << 1))) {
+		status = inb(EC_STS_PORT);
+		udelay(EC_REG_DELAY);
+	}
+
+	if (timeout <= 0) {
+		printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
+		ret = -EINVAL;
+	} else
+		printk(KERN_INFO
+			   "(%x/%d)ec issued command %d status : 0x%x\n",
+			   timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
+
+	spin_unlock_irqrestore(&port_access_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ec_query_seq);
+
+/*
+ * Send query command to EC to get the proper event number
+ */
+int ec_query_event_num(void)
+{
+	return ec_query_seq(CMD_GET_EVENT_NUM);
+}
+EXPORT_SYMBOL(ec_query_event_num);
+
+/*
+ * Get event number from EC
+ *
+ * NOTE: This routine must follow the query_event_num function in the
+ * interrupt.
+ */
+int ec_get_event_num(void)
+{
+	int timeout = 100;
+	unsigned char value;
+	unsigned char status;
+
+	udelay(EC_REG_DELAY);
+	status = inb(EC_STS_PORT);
+	udelay(EC_REG_DELAY);
+	while (timeout-- && !(status & (1 << 0))) {
+		status = inb(EC_STS_PORT);
+		udelay(EC_REG_DELAY);
+	}
+	if (timeout <= 0) {
+		pr_info("%s: get event number timeout.\n", __func__);
+
+		return -EINVAL;
+	}
+	value = inb(EC_DAT_PORT);
+	udelay(EC_REG_DELAY);
+
+	return value;
+}
+EXPORT_SYMBOL(ec_get_event_num);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.h
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/ec_kb3310b.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,188 @@
+/*
+ * KB3310B Embedded Controller
+ *
+ *  Copyright (C) 2008 Lemote Inc.
+ *  Author: liujl <liujl@lemote.com>, 2008-03-14
+ *
+ * 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 _EC_KB3310B_H
+#define _EC_KB3310B_H
+
+extern unsigned char ec_read(unsigned short addr);
+extern void ec_write(unsigned short addr, unsigned char val);
+extern int ec_query_seq(unsigned char cmd);
+extern int ec_query_event_num(void);
+extern int ec_get_event_num(void);
+
+typedef int (*sci_handler) (int status);
+extern sci_handler yeeloong_report_lid_status;
+
+#define SCI_IRQ_NUM 0x0A
+
+/*
+ * The following registers are determined by the EC index configuration.
+ * 1, fill the PORT_HIGH as EC register high part.
+ * 2, fill the PORT_LOW as EC register low part.
+ * 3, fill the PORT_DATA as EC register write data or get the data from it.
+ */
+#define	EC_IO_PORT_HIGH	0x0381
+#define	EC_IO_PORT_LOW	0x0382
+#define	EC_IO_PORT_DATA	0x0383
+
+/*
+ * EC delay time is 500us for register and status access
+ */
+#define	EC_REG_DELAY	500	/* unit : us */
+#define	EC_CMD_TIMEOUT	0x1000
+
+/*
+ * EC access port for SCI communication
+ */
+#define	EC_CMD_PORT		0x66
+#define	EC_STS_PORT		0x66
+#define	EC_DAT_PORT		0x62
+#define	CMD_INIT_IDLE_MODE	0xdd
+#define	CMD_EXIT_IDLE_MODE	0xdf
+#define	CMD_INIT_RESET_MODE	0xd8
+#define	CMD_REBOOT_SYSTEM	0x8c
+#define	CMD_GET_EVENT_NUM	0x84
+#define	CMD_PROGRAM_PIECE	0xda
+
+/* temperature & fan registers */
+#define	REG_TEMPERATURE_VALUE	0xF458
+#define	REG_FAN_AUTO_MAN_SWITCH 0xF459
+#define	BIT_FAN_AUTO		0
+#define	BIT_FAN_MANUAL		1
+#define	REG_FAN_CONTROL		0xF4D2
+#define	BIT_FAN_CONTROL_ON	(1 << 0)
+#define	BIT_FAN_CONTROL_OFF	(0 << 0)
+#define	REG_FAN_STATUS		0xF4DA
+#define	BIT_FAN_STATUS_ON	(1 << 0)
+#define	BIT_FAN_STATUS_OFF	(0 << 0)
+#define	REG_FAN_SPEED_HIGH	0xFE22
+#define	REG_FAN_SPEED_LOW	0xFE23
+#define	REG_FAN_SPEED_LEVEL	0xF4CC
+/* fan speed divider */
+#define	FAN_SPEED_DIVIDER	480000	/* (60*1000*1000/62.5/2)*/
+
+/* battery registers */
+#define	REG_BAT_DESIGN_CAP_HIGH		0xF77D
+#define	REG_BAT_DESIGN_CAP_LOW		0xF77E
+#define	REG_BAT_FULLCHG_CAP_HIGH	0xF780
+#define	REG_BAT_FULLCHG_CAP_LOW		0xF781
+#define	REG_BAT_DESIGN_VOL_HIGH		0xF782
+#define	REG_BAT_DESIGN_VOL_LOW		0xF783
+#define	REG_BAT_CURRENT_HIGH		0xF784
+#define	REG_BAT_CURRENT_LOW		0xF785
+#define	REG_BAT_VOLTAGE_HIGH		0xF786
+#define	REG_BAT_VOLTAGE_LOW		0xF787
+#define	REG_BAT_TEMPERATURE_HIGH	0xF788
+#define	REG_BAT_TEMPERATURE_LOW		0xF789
+#define	REG_BAT_RELATIVE_CAP_HIGH	0xF492
+#define	REG_BAT_RELATIVE_CAP_LOW	0xF493
+#define	REG_BAT_VENDOR			0xF4C4
+#define	FLAG_BAT_VENDOR_SANYO		0x01
+#define	FLAG_BAT_VENDOR_SIMPLO		0x02
+#define	REG_BAT_CELL_COUNT		0xF4C6
+#define	FLAG_BAT_CELL_3S1P		0x03
+#define	FLAG_BAT_CELL_3S2P		0x06
+#define	REG_BAT_CHARGE			0xF4A2
+#define	FLAG_BAT_CHARGE_DISCHARGE	0x01
+#define	FLAG_BAT_CHARGE_CHARGE		0x02
+#define	FLAG_BAT_CHARGE_ACPOWER		0x00
+#define	REG_BAT_STATUS			0xF4B0
+#define	BIT_BAT_STATUS_LOW		(1 << 5)
+#define	BIT_BAT_STATUS_DESTROY		(1 << 2)
+#define	BIT_BAT_STATUS_FULL		(1 << 1)
+#define	BIT_BAT_STATUS_IN		(1 << 0)
+#define	REG_BAT_CHARGE_STATUS		0xF4B1
+#define	BIT_BAT_CHARGE_STATUS_OVERTEMP	(1 << 2)
+#define	BIT_BAT_CHARGE_STATUS_PRECHG	(1 << 1)
+#define	REG_BAT_STATE			0xF482
+#define	BIT_BAT_STATE_CHARGING		(1 << 1)
+#define	BIT_BAT_STATE_DISCHARGING	(1 << 0)
+#define	REG_BAT_POWER			0xF440
+#define	BIT_BAT_POWER_S3		(1 << 2)
+#define	BIT_BAT_POWER_ON		(1 << 1)
+#define	BIT_BAT_POWER_ACIN		(1 << 0)
+
+/* other registers */
+/* Audio: rd/wr */
+#define	REG_AUDIO_VOLUME	0xF46C
+#define	REG_AUDIO_MUTE		0xF4E7
+#define	REG_AUDIO_BEEP		0xF4D0
+/* USB port power or not: rd/wr */
+#define	REG_USB0_FLAG		0xF461
+#define	REG_USB1_FLAG		0xF462
+#define	REG_USB2_FLAG		0xF463
+#define	BIT_USB_FLAG_ON		1
+#define	BIT_USB_FLAG_OFF	0
+/* LID */
+#define	REG_LID_DETECT		0xF4BD
+#define	BIT_LID_DETECT_ON	1
+#define	BIT_LID_DETECT_OFF	0
+/* CRT */
+#define	REG_CRT_DETECT		0xF4AD
+#define	BIT_CRT_DETECT_PLUG	1
+#define	BIT_CRT_DETECT_UNPLUG	0
+/* LCD backlight brightness adjust: 9 levels */
+#define	REG_DISPLAY_BRIGHTNESS	0xF4F5
+/* Black screen Status */
+#define	BIT_DISPLAY_LCD_ON	1
+#define	BIT_DISPLAY_LCD_OFF	0
+/* LCD backlight control: off/restore */
+#define	REG_BACKLIGHT_CTRL	0xF7BD
+#define	BIT_BACKLIGHT_ON	1
+#define	BIT_BACKLIGHT_OFF	0
+/* Reset the machine auto-clear: rd/wr */
+#define	REG_RESET		0xF4EC
+#define	BIT_RESET_ON		1
+/* Light the led: rd/wr */
+#define	REG_LED			0xF4C8
+#define	BIT_LED_RED_POWER	(1 << 0)
+#define	BIT_LED_ORANGE_POWER	(1 << 1)
+#define	BIT_LED_GREEN_CHARGE	(1 << 2)
+#define	BIT_LED_RED_CHARGE	(1 << 3)
+#define	BIT_LED_NUMLOCK		(1 << 4)
+/* Test led mode, all led on/off */
+#define	REG_LED_TEST		0xF4C2
+#define	BIT_LED_TEST_IN		1
+#define	BIT_LED_TEST_OUT	0
+/* Camera on/off */
+#define	REG_CAMERA_STATUS	0xF46A
+#define	BIT_CAMERA_STATUS_ON	1
+#define	BIT_CAMERA_STATUS_OFF	0
+#define	REG_CAMERA_CONTROL	0xF7B7
+#define	BIT_CAMERA_CONTROL_OFF	0
+#define	BIT_CAMERA_CONTROL_ON	1
+/* Wlan Status */
+#define	REG_WLAN		0xF4FA
+#define	BIT_WLAN_ON		1
+#define	BIT_WLAN_OFF		0
+#define	REG_DISPLAY_LCD		0xF79F
+
+/* SCI Event Number from EC */
+enum {
+	EVENT_LID = 0x23,	/*  LID open/close */
+	EVENT_DISPLAY_TOGGLE,	/*  Fn+F3 for display switch */
+	EVENT_SLEEP,		/*  Fn+F1 for entering sleep mode */
+	EVENT_OVERTEMP,		/*  Over-temperature happened */
+	EVENT_CRT_DETECT,	/*  CRT is connected */
+	EVENT_CAMERA,		/*  Camera on/off */
+	EVENT_USB_OC2,		/*  USB2 Over Current occurred */
+	EVENT_USB_OC0,		/*  USB0 Over Current occurred */
+	EVENT_BLACK_SCREEN,	/*  Turn on/off backlight */
+	EVENT_AUDIO_MUTE,	/*  Mute on/off */
+	EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
+	EVENT_AC_BAT,		/*  AC & Battery relative issue */
+	EVENT_AUDIO_VOLUME,	/*  Volume adjust */
+	EVENT_WLAN,		/*  Wlan on/off */
+	EVENT_END
+};
+
+#endif /* !_EC_KB3310B_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/irq.c linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/irq.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 Lemote Inc.
+ * Author: Fuxin Zhang, zhangfx@lemote.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/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define LOONGSON_TIMER_IRQ	(MIPS_CPU_IRQ_BASE + 7)	/* cpu timer */
+#define LOONGSON_PERFCNT_IRQ	(MIPS_CPU_IRQ_BASE + 6)	/* cpu perf counter */
+#define LOONGSON_NORTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 6)	/* bonito */
+#define LOONGSON_UART_IRQ	(MIPS_CPU_IRQ_BASE + 3)	/* cpu serial port */
+#define LOONGSON_SOUTH_BRIDGE_IRQ	(MIPS_CPU_IRQ_BASE + 2)	/* i8259 */
+
+#define LOONGSON_INT_BIT_INT0		(1 << 11)
+#define LOONGSON_INT_BIT_INT1		(1 << 12)
+
+/*
+ * The generic i8259_irq() make the kernel hang on booting.  Since we cannot
+ * get the irq via the IRR directly, we access the ISR instead.
+ */
+int mach_i8259_irq(void)
+{
+	int irq, isr;
+
+	irq = -1;
+
+	if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) {
+		spin_lock(&i8259A_lock);
+		isr = inb(PIC_MASTER_CMD) &
+			~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR);
+		if (!isr)
+			isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8;
+		irq = ffs(isr) - 1;
+		if (unlikely(irq == 7)) {
+			/*
+			 * This may be a spurious interrupt.
+			 *
+			 * Read the interrupt status register (ISR). If the most
+			 * significant bit is not set then there is no valid
+			 * interrupt.
+			 */
+			outb(0x0B, PIC_MASTER_ISR);	/* ISR register */
+			if (~inb(PIC_MASTER_ISR) & 0x80)
+				irq = -1;
+		}
+		spin_unlock(&i8259A_lock);
+	}
+
+	return irq;
+}
+EXPORT_SYMBOL(mach_i8259_irq);
+
+static void i8259_irqdispatch(void)
+{
+	int irq;
+
+	irq = mach_i8259_irq();
+	if (irq >= 0)
+		do_IRQ(irq);
+	else
+		spurious_interrupt();
+}
+
+void mach_irq_dispatch(unsigned int pending)
+{
+	if (pending & CAUSEF_IP7)
+		do_IRQ(LOONGSON_TIMER_IRQ);
+	else if (pending & CAUSEF_IP6) {	/* North Bridge, Perf counter */
+#ifdef CONFIG_OPROFILE
+		do_IRQ(LOONGSON2_PERFCNT_IRQ);
+#endif
+		bonito_irqdispatch();
+	} else if (pending & CAUSEF_IP3)	/* CPU UART */
+		do_IRQ(LOONGSON_UART_IRQ);
+	else if (pending & CAUSEF_IP2)	/* South Bridge */
+		i8259_irqdispatch();
+	else
+		spurious_interrupt();
+}
+
+void __init set_irq_trigger_mode(void)
+{
+	/* setup cs5536 as high level trigger */
+	LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
+	LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
+}
+
+static irqreturn_t ip6_action(int cpl, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+struct irqaction ip6_irqaction = {
+	.handler = ip6_action,
+	.name = "cascade",
+	.flags = IRQF_SHARED,
+};
+
+struct irqaction cascade_irqaction = {
+	.handler = no_action,
+	.name = "cascade",
+};
+
+void __init mach_init_irq(void)
+{
+	/* init all controller
+	 *   0-15         ------> i8259 interrupt
+	 *   16-23        ------> mips cpu interrupt
+	 *   32-63        ------> bonito irq
+	 */
+
+	/* Sets the first-level interrupt dispatcher. */
+	mips_cpu_irq_init();
+	init_i8259_irqs();
+	bonito_irq_init();
+
+	/* setup north bridge irq (bonito) */
+	setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction);
+	/* setup source bridge irq (i8259) */
+	setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/Makefile linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,11 @@
+#
+# Makefile for lemote loongson2f family machines
+#
+
+obj-y += irq.o reset.o ec_kb3310b.o
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/pm.c linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/pm.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,149 @@
+/*
+ *  Lemote loongson2f family machines' specific suspend support
+ *
+ *  Copyright (C) 2009 Lemote Inc.
+ *  Author: Wu Zhangjin <wuzj@lemote.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/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/i8042.h>
+#include <linux/module.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+#include "ec_kb3310b.h"
+
+#define I8042_KBD_IRQ		1
+#define I8042_CTR_KBDINT	0x01
+#define I8042_CTR_KBDDIS	0x10
+
+static unsigned char i8042_ctr;
+
+static int i8042_enable_kbd_port(void)
+{
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
+		pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port."
+		       "\n");
+		return -EIO;
+	}
+
+	i8042_ctr &= ~I8042_CTR_KBDDIS;
+	i8042_ctr |= I8042_CTR_KBDINT;
+
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+		i8042_ctr &= ~I8042_CTR_KBDINT;
+		i8042_ctr |= I8042_CTR_KBDDIS;
+		pr_err("i8042.c: Failed to enable KBD port.\n");
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+void setup_wakeup_events(void)
+{
+	int irq_mask;
+
+	switch (mips_machtype) {
+	case MACH_LEMOTE_ML2F7:
+	case MACH_LEMOTE_YL2F89:
+		/* open the keyboard irq in i8259A */
+		outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR);
+		irq_mask = inb(PIC_MASTER_IMR);
+
+		/* enable keyboard port */
+		i8042_enable_kbd_port();
+
+		/* Wakeup CPU via SCI lid open event */
+		outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
+		inb(PIC_MASTER_IMR);
+		outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
+		inb(PIC_SLAVE_IMR);
+
+		break;
+
+	default:
+		break;
+	}
+}
+
+static struct delayed_work lid_task;
+static int initialized;
+/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
+sci_handler yeeloong_report_lid_status;
+EXPORT_SYMBOL(yeeloong_report_lid_status);
+static void yeeloong_lid_update_task(struct work_struct *work)
+{
+	if (yeeloong_report_lid_status)
+		yeeloong_report_lid_status(BIT_LID_DETECT_ON);
+}
+
+int wakeup_loongson(void)
+{
+	int irq;
+
+	/* query the interrupt number */
+	irq = mach_i8259_irq();
+	if (irq < 0)
+		return 0;
+
+	printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
+
+	if (irq == I8042_KBD_IRQ)
+		return 1;
+	else if (irq == SCI_IRQ_NUM) {
+		int ret, sci_event;
+		/* query the event number */
+		ret = ec_query_seq(CMD_GET_EVENT_NUM);
+		if (ret < 0)
+			return 0;
+		sci_event = ec_get_event_num();
+		if (sci_event < 0)
+			return 0;
+		if (sci_event == EVENT_LID) {
+			int lid_status;
+			/* check the LID status */
+			lid_status = ec_read(REG_LID_DETECT);
+			/* wakeup cpu when people open the LID */
+			if (lid_status == BIT_LID_DETECT_ON) {
+				/* If we call it directly here, the WARNING
+				 * will be sent out by getnstimeofday
+				 * via "WARN_ON(timekeeping_suspended);"
+				 * because we can not schedule in suspend mode.
+				 */
+				if (initialized == 0) {
+					INIT_DELAYED_WORK(&lid_task,
+						yeeloong_lid_update_task);
+					initialized = 1;
+				}
+				schedule_delayed_work(&lid_task, 1);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+void __weak mach_suspend(void)
+{
+	disable_mfgpt0_counter();
+}
+
+void __weak mach_resume(void)
+{
+	enable_mfgpt0_counter();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/reset.c linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/reset.c
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/lemote-2f/reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/lemote-2f/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,159 @@
+/* Board-specific reboot/shutdown routines
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzj@lemote.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/io.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536.h>
+#include "ec_kb3310b.h"
+
+static void reset_cpu(void)
+{
+	/*
+	 * reset cpu to full speed, this is needed when enabling cpu frequency
+	 * scalling
+	 */
+	LOONGSON_CHIPCFG0 |= 0x7;
+}
+
+/* reset support for fuloong2f */
+
+static void fl2f_reboot(void)
+{
+	reset_cpu();
+
+	/* send a reset signal to south bridge.
+	 *
+	 * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
+	 * normally with this reset operation and it will not work in PMON, but
+	 * you can type halt command and then reboot, seems the hardware reset
+	 * logic not work normally.
+	 */
+	{
+		u32 hi, lo;
+		_rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
+		lo |= 0x00000001;
+		_wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
+	}
+}
+
+static void fl2f_shutdown(void)
+{
+	u32 hi, lo, val;
+	int gpio_base;
+
+	/* get gpio base */
+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+	gpio_base = lo & 0xff00;
+
+	/* make cs5536 gpio13 output enable */
+	val = inl(gpio_base + GPIOL_OUT_EN);
+	val &= ~(1 << (16 + 13));
+	val |= (1 << 13);
+	outl(val, gpio_base + GPIOL_OUT_EN);
+	mmiowb();
+	/* make cs5536 gpio13 output low level voltage. */
+	val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
+	val |= (1 << (16 + 13));
+	outl(val, gpio_base + GPIOL_OUT_VAL);
+	mmiowb();
+}
+
+/* reset support for yeeloong2f and mengloong2f notebook */
+
+void ml2f_reboot(void)
+{
+	reset_cpu();
+
+	/* sending an reset signal to EC(embedded controller) */
+	ec_write(REG_RESET, BIT_RESET_ON);
+}
+
+#define yl2f89_reboot ml2f_reboot
+
+/* menglong(7inches) laptop has different shutdown logic from 8.9inches */
+#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
+#define EC_SHUTDOWN_IO_PORT_LOW	 0xff2e
+#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
+#define REG_SHUTDOWN_HIGH        0xFC
+#define REG_SHUTDOWN_LOW         0x29
+#define BIT_SHUTDOWN_ON          (1 << 1)
+
+static void ml2f_shutdown(void)
+{
+	u8 val;
+	u64 i;
+
+	outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
+	outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
+	mmiowb();
+	val = inb(EC_SHUTDOWN_IO_PORT_DATA);
+	outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
+	mmiowb();
+	/* need enough wait here... how many microseconds needs? */
+	for (i = 0; i < 0x10000; i++)
+		delay();
+	outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
+	mmiowb();
+}
+
+static void yl2f89_shutdown(void)
+{
+	/* cpu-gpio0 output low */
+	LOONGSON_GPIODATA &= ~0x00000001;
+	/* cpu-gpio0 as output */
+	LOONGSON_GPIOIE &= ~0x00000001;
+}
+
+void mach_prepare_reboot(void)
+{
+	switch (mips_machtype) {
+	case MACH_LEMOTE_FL2F:
+	case MACH_LEMOTE_NAS:
+	case MACH_LEMOTE_LL2F:
+		fl2f_reboot();
+		break;
+	case MACH_LEMOTE_ML2F7:
+		ml2f_reboot();
+		break;
+	case MACH_LEMOTE_YL2F89:
+		yl2f89_reboot();
+		break;
+	default:
+		break;
+	}
+}
+
+void mach_prepare_shutdown(void)
+{
+	switch (mips_machtype) {
+	case MACH_LEMOTE_FL2F:
+	case MACH_LEMOTE_NAS:
+	case MACH_LEMOTE_LL2F:
+		fl2f_shutdown();
+		break;
+	case MACH_LEMOTE_ML2F7:
+		ml2f_shutdown();
+		break;
+	case MACH_LEMOTE_YL2F89:
+		yl2f89_shutdown();
+		break;
+	default:
+		break;
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/loongson/Makefile linux-libre-2.6.33-gnu1/arch/mips/loongson/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/loongson/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/loongson/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,3 +9,9 @@ obj-$(CONFIG_MACH_LOONGSON) += common/
 #
 
 obj-$(CONFIG_LEMOTE_FULOONG2E)  += fuloong-2e/
+
+#
+# Lemote loongson2f family machines
+#
+
+obj-$(CONFIG_LEMOTE_MACH2F)  += lemote-2f/
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/Makefile linux-libre-2.6.33-gnu1/arch/mips/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,16 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
+ifndef CONFIG_FUNCTION_TRACER
 cflags-y := -ffunction-sections
+endif
+ifdef CONFIG_FUNCTION_GRAPH_TRACER
+  ifndef KBUILD_MCOUNT_RA_ADDRESS
+    ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
+      cflags-y += -mmcount-ra-address -DKBUILD_MCOUNT_RA_ADDRESS
+    endif
+  endif
+endif
 cflags-y += $(call cc-option, -mno-check-zero-division)
 
 ifdef CONFIG_32BIT
@@ -69,6 +78,7 @@ endif
 
 all-$(CONFIG_BOOT_ELF32)	:= $(vmlinux-32)
 all-$(CONFIG_BOOT_ELF64)	:= $(vmlinux-64)
+all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz
 
 #
 # GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
@@ -124,6 +134,8 @@ cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4
 cflags-$(CONFIG_CPU_LOONGSON2)	+= -Wa,--trap
 cflags-$(CONFIG_CPU_LOONGSON2E) += \
 	$(call cc-option,-march=loongson2e,-march=r4600)
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+	$(call cc-option,-march=loongson2f,-march=r4600)
 
 cflags-$(CONFIG_CPU_MIPS32_R1)	+= $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
 			-Wa,-mips32 -Wa,--trap
@@ -324,6 +336,7 @@ core-$(CONFIG_MACH_LOONGSON) +=arch/mips
 cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
                     -mno-branch-likely
 load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
 
 #
 # MIPS Malta board
@@ -331,7 +344,7 @@ load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffff
 core-$(CONFIG_MIPS_MALTA)	+= arch/mips/mti-malta/
 cflags-$(CONFIG_MIPS_MALTA)	+= -I$(srctree)/arch/mips/include/asm/mach-malta
 load-$(CONFIG_MIPS_MALTA)	+= 0xffffffff80100000
-all-$(CONFIG_MIPS_MALTA)	:= vmlinux.bin
+all-$(CONFIG_MIPS_MALTA)	:= vmlinuz.bin
 
 #
 # MIPS SIM
@@ -356,13 +369,6 @@ cflags-$(CONFIG_PMC_YOSEMITE)	+= -I$(src
 load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
 
 #
-# Basler eXcite
-#
-core-$(CONFIG_BASLER_EXCITE)	+= arch/mips/basler/excite/
-cflags-$(CONFIG_BASLER_EXCITE)	+= -I$(srctree)/arch/mips/include/asm/mach-excite
-load-$(CONFIG_BASLER_EXCITE)	+= 0x80100000
-
-#
 # LASAT platforms
 #
 core-$(CONFIG_LASAT)		+= arch/mips/lasat/
@@ -441,6 +447,13 @@ core-$(CONFIG_NEC_MARKEINS)	+= arch/mips
 load-$(CONFIG_NEC_MARKEINS)	+= 0xffffffff88100000
 
 #
+# Cisco PowerTV Platform
+#
+core-$(CONFIG_POWERTV)		+= arch/mips/powertv/
+cflags-$(CONFIG_POWERTV)        += -I$(srctree)/arch/mips/include/asm/mach-powertv
+load-$(CONFIG_POWERTV)		+= 0xffffffff90800000
+
+#
 # SGI IP22 (Indy/Indigo2)
 #
 # Set the load address to >= 0xffffffff88069000 if you want to leave space for
@@ -581,7 +594,7 @@ load-$(CONFIG_SNI_RM)		+= 0xffffffff8060
 else
 load-$(CONFIG_SNI_RM)		+= 0xffffffff80030000
 endif
-all-$(CONFIG_SNI_RM)		:= vmlinux.ecoff
+all-$(CONFIG_SNI_RM)		:= vmlinuz.ecoff
 
 #
 # Common TXx9
@@ -699,9 +712,23 @@ vmlinux.64: vmlinux
 	$(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
 
 makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
+makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
+	   VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1)
 
 all:	$(all-y)
 
+vmlinuz: vmlinux FORCE
+	+@$(call makezboot,$@)
+
+vmlinuz.bin: vmlinux
+	+@$(call makezboot,$@)
+
+vmlinuz.ecoff: vmlinux
+	+@$(call makezboot,$@)
+
+vmlinuz.srec: vmlinux
+	+@$(call makezboot,$@)
+
 vmlinux.bin: $(vmlinux-32)
 	+@$(call makeboot,$@)
 
@@ -726,11 +753,13 @@ endif
 
 install:
 	$(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+	$(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
 	$(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
 	$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
 
 archclean:
 	@$(MAKE) $(clean)=arch/mips/boot
+	@$(MAKE) $(clean)=arch/mips/boot/compressed
 	@$(MAKE) $(clean)=arch/mips/lasat
 
 define archhelp
@@ -738,10 +767,18 @@ define archhelp
 	echo '  vmlinux.ecoff        - ECOFF boot image'
 	echo '  vmlinux.bin          - Raw binary boot image'
 	echo '  vmlinux.srec         - SREC boot image'
+	echo '  vmlinuz              - Compressed boot(zboot) image'
+	echo '  vmlinuz.ecoff        - ECOFF zboot image'
+	echo '  vmlinuz.bin          - Raw binary zboot image'
+	echo '  vmlinuz.srec         - SREC zboot image'
 	echo
 	echo '  These will be default as apropriate for a configured platform.'
 endef
 
 CLEAN_FILES += vmlinux.32 \
 	       vmlinux.64 \
-	       vmlinux.ecoff
+	       vmlinux.ecoff \
+	       vmlinuz \
+	       vmlinuz.ecoff \
+	       vmlinuz.bin \
+	       vmlinuz.srec
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/math-emu/cp1emu.c linux-libre-2.6.33-gnu1/arch/mips/math-emu/cp1emu.c
--- linux-libre-2.6.32-gnu1/arch/mips/math-emu/cp1emu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/math-emu/cp1emu.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
  * better performance by compiling with -msoft-float!
  */
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/debugfs.h>
 
 #include <asm/inst.h>
@@ -68,7 +69,9 @@ static int fpux_emu(struct pt_regs *,
 
 /* Further private data for which no space exists in mips_fpu_struct */
 
-struct mips_fpu_emulator_stats fpuemustats;
+#ifdef CONFIG_DEBUG_FS
+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+#endif
 
 /* Control registers */
 
@@ -209,7 +212,7 @@ static int cop1Emulate(struct pt_regs *x
 	unsigned int cond;
 
 	if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
-		fpuemustats.errors++;
+		MIPS_FPU_EMU_INC_STATS(errors);
 		return SIGBUS;
 	}
 
@@ -240,7 +243,7 @@ static int cop1Emulate(struct pt_regs *x
 			return SIGILL;
 		}
 		if (get_user(ir, (mips_instruction __user *) emulpc)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		/* __compute_return_epc() will have updated cp0_epc */
@@ -253,16 +256,16 @@ static int cop1Emulate(struct pt_regs *x
 	}
 
       emul:
-	fpuemustats.emulated++;
+	MIPS_FPU_EMU_INC_STATS(emulated);
 	switch (MIPSInst_OPCODE(ir)) {
 	case ldc1_op:{
 		u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
 			MIPSInst_SIMM(ir));
 		u64 val;
 
-		fpuemustats.loads++;
+		MIPS_FPU_EMU_INC_STATS(loads);
 		if (get_user(val, va)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		DITOREG(val, MIPSInst_RT(ir));
@@ -274,10 +277,10 @@ static int cop1Emulate(struct pt_regs *x
 			MIPSInst_SIMM(ir));
 		u64 val;
 
-		fpuemustats.stores++;
+		MIPS_FPU_EMU_INC_STATS(stores);
 		DIFROMREG(val, MIPSInst_RT(ir));
 		if (put_user(val, va)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		break;
@@ -288,9 +291,9 @@ static int cop1Emulate(struct pt_regs *x
 			MIPSInst_SIMM(ir));
 		u32 val;
 
-		fpuemustats.loads++;
+		MIPS_FPU_EMU_INC_STATS(loads);
 		if (get_user(val, va)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		SITOREG(val, MIPSInst_RT(ir));
@@ -302,10 +305,10 @@ static int cop1Emulate(struct pt_regs *x
 			MIPSInst_SIMM(ir));
 		u32 val;
 
-		fpuemustats.stores++;
+		MIPS_FPU_EMU_INC_STATS(stores);
 		SIFROMREG(val, MIPSInst_RT(ir));
 		if (put_user(val, va)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		break;
@@ -429,7 +432,7 @@ static int cop1Emulate(struct pt_regs *x
 
 				if (get_user(ir,
 				    (mips_instruction __user *) xcp->cp0_epc)) {
-					fpuemustats.errors++;
+					MIPS_FPU_EMU_INC_STATS(errors);
 					return SIGBUS;
 				}
 
@@ -595,7 +598,7 @@ static int fpux_emu(struct pt_regs *xcp,
 {
 	unsigned rcsr = 0;	/* resulting csr */
 
-	fpuemustats.cp1xops++;
+	MIPS_FPU_EMU_INC_STATS(cp1xops);
 
 	switch (MIPSInst_FMA_FFMT(ir)) {
 	case s_fmt:{		/* 0 */
@@ -610,9 +613,9 @@ static int fpux_emu(struct pt_regs *xcp,
 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
 				xcp->regs[MIPSInst_FT(ir)]);
 
-			fpuemustats.loads++;
+			MIPS_FPU_EMU_INC_STATS(loads);
 			if (get_user(val, va)) {
-				fpuemustats.errors++;
+				MIPS_FPU_EMU_INC_STATS(errors);
 				return SIGBUS;
 			}
 			SITOREG(val, MIPSInst_FD(ir));
@@ -622,11 +625,11 @@ static int fpux_emu(struct pt_regs *xcp,
 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
 				xcp->regs[MIPSInst_FT(ir)]);
 
-			fpuemustats.stores++;
+			MIPS_FPU_EMU_INC_STATS(stores);
 
 			SIFROMREG(val, MIPSInst_FS(ir));
 			if (put_user(val, va)) {
-				fpuemustats.errors++;
+				MIPS_FPU_EMU_INC_STATS(errors);
 				return SIGBUS;
 			}
 			break;
@@ -687,9 +690,9 @@ static int fpux_emu(struct pt_regs *xcp,
 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
 				xcp->regs[MIPSInst_FT(ir)]);
 
-			fpuemustats.loads++;
+			MIPS_FPU_EMU_INC_STATS(loads);
 			if (get_user(val, va)) {
-				fpuemustats.errors++;
+				MIPS_FPU_EMU_INC_STATS(errors);
 				return SIGBUS;
 			}
 			DITOREG(val, MIPSInst_FD(ir));
@@ -699,10 +702,10 @@ static int fpux_emu(struct pt_regs *xcp,
 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
 				xcp->regs[MIPSInst_FT(ir)]);
 
-			fpuemustats.stores++;
+			MIPS_FPU_EMU_INC_STATS(stores);
 			DIFROMREG(val, MIPSInst_FS(ir));
 			if (put_user(val, va)) {
-				fpuemustats.errors++;
+				MIPS_FPU_EMU_INC_STATS(errors);
 				return SIGBUS;
 			}
 			break;
@@ -769,7 +772,7 @@ static int fpu_emu(struct pt_regs *xcp,
 #endif
 	} rv;			/* resulting value */
 
-	fpuemustats.cp1ops++;
+	MIPS_FPU_EMU_INC_STATS(cp1ops);
 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
 	case s_fmt:{		/* 0 */
 		union {
@@ -1240,7 +1243,7 @@ int fpu_emulator_cop1Handler(struct pt_r
 		prevepc = xcp->cp0_epc;
 
 		if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
-			fpuemustats.errors++;
+			MIPS_FPU_EMU_INC_STATS(errors);
 			return SIGBUS;
 		}
 		if (insn == 0)
@@ -1276,33 +1279,50 @@ int fpu_emulator_cop1Handler(struct pt_r
 }
 
 #ifdef CONFIG_DEBUG_FS
+
+static int fpuemu_stat_get(void *data, u64 *val)
+{
+	int cpu;
+	unsigned long sum = 0;
+	for_each_online_cpu(cpu) {
+		struct mips_fpu_emulator_stats *ps;
+		local_t *pv;
+		ps = &per_cpu(fpuemustats, cpu);
+		pv = (void *)ps + (unsigned long)data;
+		sum += local_read(pv);
+	}
+	*val = sum;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
+
 extern struct dentry *mips_debugfs_dir;
 static int __init debugfs_fpuemu(void)
 {
 	struct dentry *d, *dir;
-	int i;
-	static struct {
-		const char *name;
-		unsigned int *v;
-	} vars[] __initdata = {
-		{ "emulated", &fpuemustats.emulated },
-		{ "loads",    &fpuemustats.loads },
-		{ "stores",   &fpuemustats.stores },
-		{ "cp1ops",   &fpuemustats.cp1ops },
-		{ "cp1xops",  &fpuemustats.cp1xops },
-		{ "errors",   &fpuemustats.errors },
-	};
 
 	if (!mips_debugfs_dir)
 		return -ENODEV;
 	dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
 	if (!dir)
 		return -ENOMEM;
-	for (i = 0; i < ARRAY_SIZE(vars); i++) {
-		d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v);
-		if (!d)
-			return -ENOMEM;
-	}
+
+#define FPU_STAT_CREATE(M)						\
+	do {								\
+		d = debugfs_create_file(#M , S_IRUGO, dir,		\
+			(void *)offsetof(struct mips_fpu_emulator_stats, M), \
+			&fops_fpuemu_stat);				\
+		if (!d)							\
+			return -ENOMEM;					\
+	} while (0)
+
+	FPU_STAT_CREATE(emulated);
+	FPU_STAT_CREATE(loads);
+	FPU_STAT_CREATE(stores);
+	FPU_STAT_CREATE(cp1ops);
+	FPU_STAT_CREATE(cp1xops);
+	FPU_STAT_CREATE(errors);
+
 	return 0;
 }
 __initcall(debugfs_fpuemu);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/math-emu/dp_sub.c linux-libre-2.6.33-gnu1/arch/mips/math-emu/dp_sub.c
--- linux-libre-2.6.32-gnu1/arch/mips/math-emu/dp_sub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/math-emu/dp_sub.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,7 @@ ieee754dp ieee754dp_sub(ieee754dp x, iee
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
-		/* FAAL THOROUGH */
+		/* FALL THROUGH */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		/* normalize ym,ye */
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/math-emu/dsemul.c linux-libre-2.6.33-gnu1/arch/mips/math-emu/dsemul.c
--- linux-libre-2.6.32-gnu1/arch/mips/math-emu/dsemul.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/math-emu/dsemul.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,7 +98,7 @@ int mips_dsemul(struct pt_regs *regs, mi
 	err |= __put_user(cpc, &fr->epc);
 
 	if (unlikely(err)) {
-		fpuemustats.errors++;
+		MIPS_FPU_EMU_INC_STATS(errors);
 		return SIGBUS;
 	}
 
@@ -136,7 +136,7 @@ int do_dsemulret(struct pt_regs *xcp)
 	err |= __get_user(cookie, &fr->cookie);
 
 	if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
-		fpuemustats.errors++;
+		MIPS_FPU_EMU_INC_STATS(errors);
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mipssim/Makefile linux-libre-2.6.33-gnu1/arch/mips/mipssim/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/mipssim/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mipssim/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,7 @@
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
 
-obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \
-	 sim_cmdline.o
+obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
 
 obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
 obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mipssim/sim_cmdline.c linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_cmdline.c
--- linux-libre-2.6.32-gnu1/arch/mips/mipssim/sim_cmdline.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_cmdline.c	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.
- *
- */
-#include <linux/init.h>
-#include <linux/string.h>
-#include <asm/bootinfo.h>
-
-extern char arcs_cmdline[];
-
-char * __init prom_getcmdline(void)
-{
-	return arcs_cmdline;
-}
-
-void  __init prom_init_cmdline(void)
-{
-	/* XXX: Get boot line from environment? */
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mipssim/sim_setup.c linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/mipssim/sim_setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mipssim/sim_setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,9 +49,6 @@ void __init plat_mem_setup(void)
 	set_io_port_base(0xbfd00000);
 
 	serial_init();
-
-	pr_info("Linux started...\n");
-
 }
 
 extern struct plat_smp_ops ssmtc_smp_ops;
@@ -60,8 +57,6 @@ void __init prom_init(void)
 {
 	set_io_port_base(0xbfd00000);
 
-	pr_info("\nLINUX started...\n");
-	prom_init_cmdline();
 	prom_meminit();
 
 #ifdef CONFIG_MIPS_MT_SMP
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/cache.c linux-libre-2.6.33-gnu1/arch/mips/mm/cache.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/cache.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
@@ -155,7 +155,7 @@ static inline void setup_protection_map(
 	protection_map[15] = PAGE_SHARED;
 }
 
-void __devinit cpu_cache_init(void)
+void __cpuinit cpu_cache_init(void)
 {
 	if (cpu_has_3k_cache) {
 		extern void __weak r3k_cache_init(void);
@@ -194,7 +194,7 @@ void __devinit cpu_cache_init(void)
 
 int __weak __uncached_access(struct file *file, unsigned long addr)
 {
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 
 	return addr >= __pa(high_memory);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/cerr-sb1.c linux-libre-2.6.33-gnu1/arch/mips/mm/cerr-sb1.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/cerr-sb1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/cerr-sb1.c	2010-02-24 13:52:17.000000000 -0500
@@ -567,13 +567,10 @@ static uint32_t extract_dc(unsigned shor
 				datalo = ((unsigned long long)datalohi << 32) | datalolo;
 				ecc = dc_ecc(datalo);
 				if (ecc != datahi) {
-					int bits = 0;
+					int bits;
 					bad_ecc |= 1 << (3-offset);
 					ecc ^= datahi;
-					while (ecc) {
-						if (ecc & 1) bits++;
-						ecc >>= 1;
-					}
+					bits = hweight8(ecc);
 					res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
 				}
 				printk("  %02X-%016llX", datahi, datalo);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/c-octeon.c linux-libre-2.6.33-gnu1/arch/mips/mm/c-octeon.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/c-octeon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/c-octeon.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,7 +174,7 @@ static void octeon_flush_cache_page(stru
  * Probe Octeon's caches
  *
  */
-static void __devinit probe_octeon(void)
+static void __cpuinit probe_octeon(void)
 {
 	unsigned long icache_size;
 	unsigned long dcache_size;
@@ -235,7 +235,7 @@ static void __devinit probe_octeon(void)
  * Setup the Octeon cache flush routines
  *
  */
-void __devinit octeon_cache_init(void)
+void __cpuinit octeon_cache_init(void)
 {
 	extern unsigned long ebase;
 	extern char except_vec2_octeon;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/highmem.c linux-libre-2.6.33-gnu1/arch/mips/mm/highmem.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/highmem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/highmem.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 #include <linux/module.h>
 #include <linux/highmem.h>
+#include <linux/sched.h>
 #include <linux/smp.h>
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/init.c linux-libre-2.6.33-gnu1/arch/mips/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -424,7 +424,7 @@ void __init mem_init(void)
 	       reservedpages << (PAGE_SHIFT-10),
 	       datasize >> 10,
 	       initsize >> 10,
-	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+	       totalhigh_pages << (PAGE_SHIFT-10));
 }
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
@@ -462,7 +462,9 @@ void __init_refok free_initmem(void)
 			__pa_symbol(&__init_end));
 }
 
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 unsigned long pgd_current[NR_CPUS];
+#endif
 /*
  * On 64-bit we've got three-level pagetables with a slightly
  * different layout ...
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/tlbex.c linux-libre-2.6.33-gnu1/arch/mips/mm/tlbex.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/tlbex.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/tlbex.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,9 +73,6 @@ static int __cpuinit m4kc_tlbp_war(void)
 enum label_id {
 	label_second_part = 1,
 	label_leave,
-#ifdef MODULE_START
-	label_module_alloc,
-#endif
 	label_vmalloc,
 	label_vmalloc_done,
 	label_tlbw_hazard,
@@ -92,9 +89,6 @@ enum label_id {
 
 UASM_L_LA(_second_part)
 UASM_L_LA(_leave)
-#ifdef MODULE_START
-UASM_L_LA(_module_alloc)
-#endif
 UASM_L_LA(_vmalloc)
 UASM_L_LA(_vmalloc_done)
 UASM_L_LA(_tlbw_hazard)
@@ -160,6 +154,12 @@ static u32 tlb_handler[128] __cpuinitdat
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+/*
+ * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
+ * we cannot do r3000 under these circumstances.
+ */
+
 /*
  * The R3000 TLB handler is simple.
  */
@@ -199,6 +199,7 @@ static void __cpuinit build_r3000_tlb_re
 
 	dump_handler((u32 *)ebase, 32);
 }
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
 /*
  * The R4000 TLB handler is much more complicated. We have two
@@ -497,8 +498,9 @@ static void __cpuinit
 build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 		 unsigned int tmp, unsigned int ptr)
 {
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 	long pgdc = (long)pgd_current;
-
+#endif
 	/*
 	 * The vmalloc handling is not in the hotpath.
 	 */
@@ -506,7 +508,15 @@ build_get_pmde64(u32 **p, struct uasm_la
 	uasm_il_bltz(p, r, tmp, label_vmalloc);
 	/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+	/*
+	 * &pgd << 11 stored in CONTEXT [23..63].
+	 */
+	UASM_i_MFC0(p, ptr, C0_CONTEXT);
+	uasm_i_dins(p, ptr, 0, 0, 23); /* Clear lower 23 bits of context. */
+	uasm_i_ori(p, ptr, ptr, 0x540); /* 1 0  1 0 1  << 6  xkphys cached */
+	uasm_i_drotr(p, ptr, ptr, 11);
+#elif defined(CONFIG_SMP)
 # ifdef  CONFIG_MIPS_MT_SMTC
 	/*
 	 * SMTC uses TCBind value as "CPU" index
@@ -520,7 +530,7 @@ build_get_pmde64(u32 **p, struct uasm_la
 	 */
 	uasm_i_dmfc0(p, ptr, C0_CONTEXT);
 	uasm_i_dsrl(p, ptr, ptr, 23);
-#endif
+# endif
 	UASM_i_LA_mostly(p, tmp, pgdc);
 	uasm_i_daddu(p, ptr, ptr, tmp);
 	uasm_i_dmfc0(p, tmp, C0_BADVADDR);
@@ -802,8 +812,6 @@ static void __cpuinit build_r4000_tlb_re
 	} else {
 #if defined(CONFIG_HUGETLB_PAGE)
 		const enum label_id ls = label_tlb_huge_update;
-#elif defined(MODULE_START)
-		const enum label_id ls = label_module_alloc;
 #else
 		const enum label_id ls = label_vmalloc;
 #endif
@@ -1033,6 +1041,7 @@ build_pte_modifiable(u32 **p, struct uas
 	iPTE_LW(p, pte, ptr);
 }
 
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 /*
  * R3000 style TLB load/store/modify handlers.
  */
@@ -1184,6 +1193,7 @@ static void __cpuinit build_r3000_tlb_mo
 
 	dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
 }
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
 /*
  * R4000 style TLB load/store/modify handlers.
@@ -1400,6 +1410,7 @@ void __cpuinit build_tlb_refill_handler(
 	case CPU_TX3912:
 	case CPU_TX3922:
 	case CPU_TX3927:
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 		build_r3000_tlb_refill_handler();
 		if (!run_once) {
 			build_r3000_tlb_load_handler();
@@ -1407,6 +1418,9 @@ void __cpuinit build_tlb_refill_handler(
 			build_r3000_tlb_modify_handler();
 			run_once++;
 		}
+#else
+		panic("No R3000 TLB refill handler");
+#endif
 		break;
 
 	case CPU_R6000:
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/uasm.c linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.c
--- linux-libre-2.6.32-gnu1/arch/mips/mm/uasm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,11 +60,11 @@ enum opcode {
 	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
 	insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
 	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
-	insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr,
-	insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
+	insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
+	insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
 	insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
 	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
-	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
+	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, insn_dins
 };
 
 struct insn {
@@ -104,6 +104,7 @@ static struct insn insn_table[] __cpuini
 	{ insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
 	{ insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
 	{ insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
+	{ insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
 	{ insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
 	{ insn_eret,  M(cop0_op, cop_op, 0, 0, 0, eret_op),  0 },
 	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
@@ -132,6 +133,7 @@ static struct insn insn_table[] __cpuini
 	{ insn_tlbwr,  M(cop0_op, cop_op, 0, 0, 0, tlbwr_op),  0 },
 	{ insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
 	{ insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
+	{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
 	{ insn_invalid, 0, 0 }
 };
 
@@ -304,6 +306,12 @@ Ip_u2u1s3(op)						\
 	build_insn(buf, insn##op, b, a, c);		\
 }
 
+#define I_u2u1msbu3(op)					\
+Ip_u2u1msbu3(op)					\
+{							\
+	build_insn(buf, insn##op, b, a, c+d-1, c);	\
+}
+
 #define I_u1u2(op)					\
 Ip_u1u2(op)						\
 {							\
@@ -349,6 +357,7 @@ I_u2u1u3(_dsll32)
 I_u2u1u3(_dsra)
 I_u2u1u3(_dsrl)
 I_u2u1u3(_dsrl32)
+I_u2u1u3(_drotr)
 I_u3u1u2(_dsubu)
 I_0(_eret)
 I_u1(_j)
@@ -377,6 +386,7 @@ I_0(_tlbwi)
 I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
+I_u2u1msbu3(_dins);
 
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mm/uasm.h linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.h
--- linux-libre-2.6.32-gnu1/arch/mips/mm/uasm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mm/uasm.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,11 @@ uasm_i##op(u32 **buf, unsigned int a, si
 void __cpuinit								\
 uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
+#define Ip_u2u1msbu3(op)						\
+void __cpuinit								\
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c,	\
+	   unsigned int d)
+
 #define Ip_u1u2(op)							\
 void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
 
@@ -65,6 +70,7 @@ Ip_u2u1u3(_dsll32);
 Ip_u2u1u3(_dsra);
 Ip_u2u1u3(_dsrl);
 Ip_u2u1u3(_dsrl32);
+Ip_u2u1u3(_drotr);
 Ip_u3u1u2(_dsubu);
 Ip_0(_eret);
 Ip_u1(_j);
@@ -93,6 +99,7 @@ Ip_0(_tlbwi);
 Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
+Ip_u2u1msbu3(_dins);
 
 /* Handle labels. */
 struct uasm_label {
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mti-malta/malta-init.c linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-init.c
--- linux-libre-2.6.32-gnu1/arch/mips/mti-malta/malta-init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-init.c	2010-02-24 13:52:17.000000000 -0500
@@ -355,7 +355,6 @@ void __init prom_init(void)
 	board_nmi_handler_setup = mips_nmi_setup;
 	board_ejtag_handler_setup = mips_ejtag_setup;
 
-	pr_info("\nLINUX started...\n");
 	prom_init_cmdline();
 	prom_meminit();
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/mti-malta/malta-memory.c linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-memory.c
--- linux-libre-2.6.32-gnu1/arch/mips/mti-malta/malta-memory.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/mti-malta/malta-memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,7 @@ static struct prom_pmemblock * __init pr
 	char *memsize_str;
 	unsigned int memsize;
 	char *ptr;
-	static char cmdline[CL_SIZE] __initdata;
+	static char cmdline[COMMAND_LINE_SIZE] __initdata;
 
 	/* otherwise look in the environment */
 	memsize_str = prom_getenv("memsize");
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c
--- linux-libre-2.6.32-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/nxp/pnx833x/common/interrupts.c	2010-02-24 13:52:17.000000000 -0500
@@ -295,7 +295,7 @@ static int pnx833x_set_type_gpio_irq(uns
 }
 
 static struct irq_chip pnx833x_pic_irq_type = {
-	.typename = "PNX-PIC",
+	.name = "PNX-PIC",
 	.startup = pnx833x_startup_pic_irq,
 	.shutdown = pnx833x_shutdown_pic_irq,
 	.enable = pnx833x_enable_pic_irq,
@@ -305,7 +305,7 @@ static struct irq_chip pnx833x_pic_irq_t
 };
 
 static struct irq_chip pnx833x_gpio_irq_type = {
-	.typename = "PNX-GPIO",
+	.name = "PNX-GPIO",
 	.startup = pnx833x_startup_gpio_irq,
 	.shutdown = pnx833x_disable_gpio_irq,
 	.enable = pnx833x_enable_gpio_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/oprofile/op_model_loongson2.c linux-libre-2.6.33-gnu1/arch/mips/oprofile/op_model_loongson2.c
--- linux-libre-2.6.32-gnu1/arch/mips/oprofile/op_model_loongson2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/oprofile/op_model_loongson2.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Loongson2 performance counter driver for oprofile
  *
- * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Copyright (C) 2009 Lemote Inc.
  * Author: Yanhua <yanh@lemote.com>
  * Author: Wu Zhangjin <wuzj@lemote.com>
  *
@@ -125,6 +125,9 @@ static irqreturn_t loongson2_perfcount_h
 	 */
 
 	/* Check whether the irq belongs to me */
+	enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
+	if (!enabled)
+		return IRQ_NONE;
 	enabled = reg.cnt1_enabled | reg.cnt2_enabled;
 	if (!enabled)
 		return IRQ_NONE;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-excite.c linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-excite.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-excite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-excite.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/*
- *  Copyright (C) 2004 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.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/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <excite.h>
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	if (pin == 0)
-		return -1;
-
-	return USB_IRQ;		/* USB controller is the only PCI device */
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-fuloong2e.c linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-fuloong2e.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-fuloong2e.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-fuloong2e.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,8 @@
  */
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <asm/mips-boards/bonito64.h>
+
+#include <loongson.h>
 
 /* South bridge slot number is set by the pci probe process */
 static u8 sb_slot = 5;
@@ -35,7 +36,7 @@ int __init pcibios_map_irq(const struct
 			break;
 		}
 	} else {
-		irq = BONITO_IRQ_BASE + 25 + pin;
+		irq = LOONGSON_IRQ_BASE + 25 + pin;
 	}
 	return irq;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-lemote2f.c linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-lemote2f.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/fixup-lemote2f.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/fixup-lemote2f.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2008 Lemote Technology
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author: Fuxin Zhang, zhangfx@lemote.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/init.h>
+#include <linux/pci.h>
+
+#include <loongson.h>
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+/* PCI interrupt pins
+ *
+ * These should not be changed, or you should consider loongson2f interrupt
+ * register and your pci card dispatch
+ */
+
+#define PCIA		4
+#define PCIB		5
+#define PCIC		6
+#define PCID		7
+
+/* all the pci device has the PCIA pin, check the datasheet. */
+static char irq_tab[][5] __initdata = {
+	/*      INTA    INTB    INTC    INTD */
+	{0, 0, 0, 0, 0},	/*  11: Unused */
+	{0, 0, 0, 0, 0},	/*  12: Unused */
+	{0, 0, 0, 0, 0},	/*  13: Unused */
+	{0, 0, 0, 0, 0},	/*  14: Unused */
+	{0, 0, 0, 0, 0},	/*  15: Unused */
+	{0, 0, 0, 0, 0},	/*  16: Unused */
+	{0, PCIA, 0, 0, 0},	/*  17: RTL8110-0 */
+	{0, PCIB, 0, 0, 0},	/*  18: RTL8110-1 */
+	{0, PCIC, 0, 0, 0},	/*  19: SiI3114 */
+	{0, PCID, 0, 0, 0},	/*  20: 3-ports nec usb */
+	{0, PCIA, PCIB, PCIC, PCID},	/*  21: PCI-SLOT */
+	{0, 0, 0, 0, 0},	/*  22: Unused */
+	{0, 0, 0, 0, 0},	/*  23: Unused */
+	{0, 0, 0, 0, 0},	/*  24: Unused */
+	{0, 0, 0, 0, 0},	/*  25: Unused */
+	{0, 0, 0, 0, 0},	/*  26: Unused */
+	{0, 0, 0, 0, 0},	/*  27: Unused */
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int virq;
+
+	if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
+	    && (PCI_SLOT(dev->devfn) < 32)) {
+		virq = irq_tab[slot][pin];
+		printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
+		       virq + LOONGSON_IRQ_BASE);
+		if (virq != 0)
+			return LOONGSON_IRQ_BASE + virq;
+		else
+			return 0;
+	} else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) {	/*  cs5536 */
+		switch (PCI_FUNC(dev->devfn)) {
+		case 2:
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+					      CS5536_IDE_INTR);
+			return CS5536_IDE_INTR;	/*  for IDE */
+		case 3:
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+					      CS5536_ACC_INTR);
+			return CS5536_ACC_INTR;	/*  for AUDIO */
+		case 4:	/*  for OHCI */
+		case 5:	/*  for EHCI */
+		case 6:	/*  for UDC */
+		case 7:	/*  for OTG */
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+					      CS5536_USB_INTR);
+			return CS5536_USB_INTR;
+		}
+		return dev->irq;
+	} else {
+		printk(KERN_INFO " strange pci slot number.\n");
+		return 0;
+	}
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+/* CS5536 SPEC. fixup */
+static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev)
+{
+	/* the uart1 and uart2 interrupt in PIC is enabled as default */
+	pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
+	pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
+}
+
+static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev)
+{
+	/* setting the mutex pin as IDE function */
+	pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
+			       CS5536_IDE_FLASH_SIGNATURE);
+}
+
+static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev)
+{
+	/* enable the AUDIO interrupt in PIC  */
+	pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
+
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
+}
+
+static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
+{
+	/* enable the OHCI interrupt in PIC */
+	/* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
+	pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
+}
+
+static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
+{
+	u32 hi, lo;
+
+	/* Serial short detect enable */
+	_rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
+	_wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
+
+	/* setting the USB2.0 micro frame length */
+	pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
+}
+
+static void __init loongson_nec_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+
+	pci_read_config_dword(pdev, 0xe0, &val);
+	/* Only 2 port be used */
+	pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+			 loongson_cs5536_isa_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
+			 loongson_cs5536_ohci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
+			 loongson_cs5536_ehci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
+			 loongson_cs5536_acc_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
+			 loongson_cs5536_ide_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+			 loongson_nec_fixup);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/Makefile linux-libre-2.6.33-gnu1/arch/mips/pci/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/pci/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -22,13 +22,13 @@ obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o
 #
 # These are still pretty much in the old state, watch, go blind.
 #
-obj-$(CONFIG_BASLER_EXCITE)	+= ops-titan.o pci-excite.o fixup-excite.o
 obj-$(CONFIG_LASAT)		+= pci-lasat.o
 obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
 obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
-obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-bonito64.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_PMC_MSP7120_GW)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL)	+= fixup-pmcmsp.o ops-pmcmsp.o
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/ops-bonito64.c linux-libre-2.6.33-gnu1/arch/mips/pci/ops-bonito64.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/ops-bonito64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/ops-bonito64.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,13 +29,8 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-#ifdef CONFIG_LEMOTE_FULOONG2E
-#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
-#define ID_SEL_BEGIN 11
-#else
 #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
 #define ID_SEL_BEGIN 10
-#endif
 #define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
 
 
@@ -77,10 +72,8 @@ static int bonito64_pcibios_config_acces
 	addrp = CFG_SPACE_REG(addr & 0xffff);
 	if (access_type == PCI_ACCESS_WRITE) {
 		writel(cpu_to_le32(*data), addrp);
-#ifndef CONFIG_LEMOTE_FULOONG2E
 		/* Wait till done */
 		while (BONITO_PCIMSTAT & 0xF);
-#endif
 	} else {
 		*data = le32_to_cpu(readl(addrp));
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/ops-loongson2.c linux-libre-2.6.33-gnu1/arch/mips/pci/ops-loongson2.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/ops-loongson2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/ops-loongson2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,208 @@
+/*
+ * fuloong2e specific PCI support.
+ *
+ * Copyright (C) 1999, 2000, 2004  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ *  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.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_CS5536
+#include <cs5536/cs5536_pci.h>
+#include <cs5536/cs5536.h>
+#endif
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#define CFG_SPACE_REG(offset) \
+	(void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset))
+#define ID_SEL_BEGIN 11
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
+
+
+static int loongson_pcibios_config_access(unsigned char access_type,
+				      struct pci_bus *bus,
+				      unsigned int devfn, int where,
+				      u32 *data)
+{
+	u32 busnum = bus->number;
+	u32 addr, type;
+	u32 dummy;
+	void *addrp;
+	int device = PCI_SLOT(devfn);
+	int function = PCI_FUNC(devfn);
+	int reg = where & ~3;
+
+	if (busnum == 0) {
+		/* board-specific part,currently,only fuloong2f,yeeloong2f
+		 * use CS5536, fuloong2e use via686b, gdium has no
+		 * south bridge
+		 */
+#ifdef CONFIG_CS5536
+		/* cs5536_pci_conf_read4/write4() will call _rdmsr/_wrmsr() to
+		 * access the regsters PCI_MSR_ADDR, PCI_MSR_DATA_LO,
+		 * PCI_MSR_DATA_HI, which is bigger than PCI_MSR_CTRL, so, it
+		 * will not go this branch, but the others. so, no calling dead
+		 * loop here.
+		 */
+		if ((PCI_IDSEL_CS5536 == device) && (reg < PCI_MSR_CTRL)) {
+			switch (access_type) {
+			case PCI_ACCESS_READ:
+				*data = cs5536_pci_conf_read4(function, reg);
+				break;
+			case PCI_ACCESS_WRITE:
+				cs5536_pci_conf_write4(function, reg, *data);
+				break;
+			}
+			return 0;
+		}
+#endif
+		/* Type 0 configuration for onboard PCI bus */
+		if (device > MAX_DEV_NUM)
+			return -1;
+
+		addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+		type = 0;
+	} else {
+		/* Type 1 configuration for offboard PCI bus */
+		addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+		type = 0x10000;
+	}
+
+	/* Clear aborts */
+	LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \
+				LOONGSON_PCICMD_MTABORT_CLR;
+
+	LOONGSON_PCIMAP_CFG = (addr >> 16) | type;
+
+	/* Flush Bonito register block */
+	dummy = LOONGSON_PCIMAP_CFG;
+	mmiowb();
+
+	addrp = CFG_SPACE_REG(addr & 0xffff);
+	if (access_type == PCI_ACCESS_WRITE)
+		writel(cpu_to_le32(*data), addrp);
+	else
+		*data = le32_to_cpu(readl(addrp));
+
+	/* Detect Master/Target abort */
+	if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR |
+			     LOONGSON_PCICMD_MTABORT_CLR)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR |
+				  LOONGSON_PCICMD_MTABORT_CLR);
+
+		return -1;
+	}
+
+	return 0;
+
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+			     int where, int size, u32 *val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+				       &data))
+		return -1;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+					where, &data))
+			return -1;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+				       &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops loongson_pci_ops = {
+	.read = loongson_pcibios_read,
+	.write = loongson_pcibios_write
+};
+
+#ifdef CONFIG_CS5536
+void _rdmsr(u32 msr, u32 *hi, u32 *lo)
+{
+	struct pci_bus bus = {
+		.number = PCI_BUS_CS5536
+	};
+	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
+	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
+	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+}
+EXPORT_SYMBOL(_rdmsr);
+
+void _wrmsr(u32 msr, u32 hi, u32 lo)
+{
+	struct pci_bus bus = {
+		.number = PCI_BUS_CS5536
+	};
+	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
+	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
+	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+}
+EXPORT_SYMBOL(_wrmsr);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/pci/pci-excite.c linux-libre-2.6.33-gnu1/arch/mips/pci/pci-excite.c
--- linux-libre-2.6.32-gnu1/arch/mips/pci/pci-excite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/pci/pci-excite.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,149 +0,0 @@
-/*
- *  Copyright (C) 2004 by Basler Vision Technologies AG
- *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
- *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle.
- *
- *  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/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <asm/rm9k-ocd.h>
-#include <excite.h>
-
-
-extern struct pci_ops titan_pci_ops;
-
-
-static struct resource
-	mem_resource = 	{
-		.name	= "PCI memory",
-		.start	= EXCITE_PHYS_PCI_MEM,
-		.end	= EXCITE_PHYS_PCI_MEM + EXCITE_SIZE_PCI_MEM - 1,
-		.flags	= IORESOURCE_MEM
-	},
-	io_resource = {
-		.name	= "PCI I/O",
-		.start	= EXCITE_PHYS_PCI_IO,
-		.end	= EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1,
-		.flags	= IORESOURCE_IO
-	};
-
-
-static struct pci_controller bx_controller = {
-	.pci_ops	= &titan_pci_ops,
-	.mem_resource	= &mem_resource,
-	.mem_offset	= 0x00000000UL,
-	.io_resource	= &io_resource,
-	.io_offset	= 0x00000000UL
-};
-
-
-static char
-	iopage_failed[] __initdata   = "Cannot allocate PCI I/O page",
-	modebits_no_pci[] __initdata = "PCI is not configured in mode bits";
-
-#define RM9000x2_OCD_HTSC	0x0604
-#define RM9000x2_OCD_HTBHL	0x060c
-#define RM9000x2_OCD_PCIHRST	0x078c
-
-#define RM9K_OCD_MODEBIT1	0x00d4 /* (MODEBIT1) Mode Bit 1 */
-#define RM9K_OCD_CPHDCR		0x00f4 /* CPU-PCI/HT Data Control. */
-
-#define PCISC_FB2B 		0x00000200
-#define PCISC_MWICG		0x00000010
-#define PCISC_EMC		0x00000004
-#define PCISC_ERMA		0x00000002
-
-
-
-static int __init basler_excite_pci_setup(void)
-{
-	const unsigned int fullbars = memsize / (256 << 20);
-	unsigned int i;
-
-	/* Check modebits to see if PCI is really enabled. */
-	if (!((ocd_readl(RM9K_OCD_MODEBIT1) >> (47-32)) & 0x1))
-		panic(modebits_no_pci);
-
-	if (NULL == request_mem_region(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO,
-				       "Memory-mapped PCI I/O page"))
-		panic(iopage_failed);
-
-	/* Enable PCI 0 as master for config cycles */
-	ocd_writel(PCISC_EMC | PCISC_ERMA, RM9000x2_OCD_HTSC);
-
-
-	/* Set up latency timer */
-	ocd_writel(0x8008, RM9000x2_OCD_HTBHL);
-
-	/*  Setup host IO and Memory space */
-	ocd_writel((EXCITE_PHYS_PCI_IO >> 4) | 1, LKB7);
-	ocd_writel(((EXCITE_SIZE_PCI_IO >> 4) & 0x7fffff00) - 0x100, LKM7);
-	ocd_writel((EXCITE_PHYS_PCI_MEM >> 4) | 1, LKB8);
-	ocd_writel(((EXCITE_SIZE_PCI_MEM >> 4) & 0x7fffff00) - 0x100, LKM8);
-
-	/* Set up PCI BARs to map all installed memory */
-	for (i = 0; i < 6; i++) {
-		const unsigned int bar = 0x610 + i * 4;
-
-	     	if (i < fullbars) {
-			ocd_writel(0x10000000 * i, bar);
-			ocd_writel(0x01000000 * i, bar + 0x140);
-			ocd_writel(0x0ffff029, bar + 0x100);
-			continue;
-		}
-
-	     	if (i == fullbars) {
-			int o;
-			u32 mask;
-
-			const unsigned long rem = memsize - i * 0x10000000;
-			if (!rem) {
-				ocd_writel(0x00000000, bar + 0x100);
-				continue;
-			}
-
-			o = ffs(rem) - 1;
-			if (rem & ~(0x1 << o))
-				o++;
-			mask = ((0x1 << o) & 0x0ffff000) - 0x1000;
-			ocd_writel(0x10000000 * i, bar);
-			ocd_writel(0x01000000 * i, bar + 0x140);
-			ocd_writel(0x00000029 | mask, bar + 0x100);
-			continue;
-		}
-
-		ocd_writel(0x00000000, bar + 0x100);
-	}
-
-	/* Finally, enable the PCI interrupt */
-#if USB_IRQ > 7
-	set_c0_intcontrol(1 << USB_IRQ);
-#else
-	set_c0_status(1 << (USB_IRQ + 8));
-#endif
-
-	ioport_resource.start = EXCITE_PHYS_PCI_IO;
-	ioport_resource.end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1;
-	set_io_port_base((unsigned long) ioremap_nocache(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO));
-	register_pci_controller(&bx_controller);
-	return 0;
-}
-
-
-arch_initcall(basler_excite_pci_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-calliope.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-calliope.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-calliope.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-calliope.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Calliope ASIC.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define CALLIOPE_ADDR(x)	(CALLIOPE_IO_BASE + (x))
+
+const struct register_map calliope_register_map __initdata = {
+	.eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)},
+	.eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)},
+	.eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)},
+
+	.chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)},
+	.chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)},
+	.chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)},
+	.chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)},
+
+	/* The registers of IRBlaster */
+	.uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)},
+	.uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)},
+	.uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)},
+	.uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)},
+	.uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)},
+	.uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)},
+	.uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)},
+	.uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)},
+
+	.int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)},
+	.int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)},
+	.int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)},
+	.int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)},
+	.int_config = {.phys = CALLIOPE_ADDR(0xA02810)},
+	.int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)},
+	.ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)},
+	.ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)},
+	.ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)},
+	.ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)},
+	.int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)},
+	.int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)},
+	.int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)},
+	.int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)},
+	.int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)},
+	.int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)},
+	.int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)},
+	.int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)},
+	.int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)},
+	.int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)},
+	.int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)},
+	.int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)},
+	.int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)},
+	.int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)},
+	.int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)},
+	.int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)},
+	.int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
+
+	.mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
+	.usb_fs = {.phys = CALLIOPE_ADDR(0x980030)},
+	.test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
+	.crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
+	.usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
+	.usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)},
+	.ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)},
+	.ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)},
+	.bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)},
+	.usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)},
+	.usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)},
+	.usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)},
+	.usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)},
+
+	.pcie_regs = {.phys = 0x000000},      	/* -doesn't exist- */
+	.tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)},
+	.tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)},
+	.gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)},
+	.gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)},
+	.gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)},
+	.watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)},
+	.front_panel = {.phys = 0x000000},    	/* -not used- */
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-cronus.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-cronus.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-cronus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-cronus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Cronus ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define CRONUS_ADDR(x)	(CRONUS_IO_BASE + (x))
+
+const struct register_map cronus_register_map __initdata = {
+	.eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)},
+	.eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)},
+	.eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)},
+
+	.chipver3 = {.phys = CRONUS_ADDR(0x2A0800)},
+	.chipver2 = {.phys = CRONUS_ADDR(0x2A0804)},
+	.chipver1 = {.phys = CRONUS_ADDR(0x2A0808)},
+	.chipver0 = {.phys = CRONUS_ADDR(0x2A080C)},
+
+	/* The registers of IRBlaster */
+	.uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)},
+	.uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)},
+	.uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)},
+	.uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)},
+	.uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)},
+	.uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)},
+	.uart1_data = {.phys = CRONUS_ADDR(0x2A1818)},
+	.uart1_status = {.phys = CRONUS_ADDR(0x2A181C)},
+
+	.int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)},
+	.int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)},
+	.int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)},
+	.int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)},
+	.int_config = {.phys = CRONUS_ADDR(0x2A2810)},
+	.int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)},
+	.ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)},
+	.ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)},
+	.ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)},
+	.ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)},
+	.int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)},
+	.int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)},
+	.int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)},
+	.int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)},
+	.int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)},
+	.int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)},
+	.int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)},
+	.int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)},
+	.int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)},
+	.int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)},
+	.int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)},
+	.int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)},
+	.int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)},
+	.int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)},
+	.int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)},
+	.int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)},
+	.int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
+
+	.mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
+	.usb_fs = {.phys = CRONUS_ADDR(0x1C0018)},
+	.test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
+	.crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
+	.usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
+	.usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
+	.ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
+	.ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)},
+	.bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
+	.usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
+	.usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
+	.usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)},
+	.usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)},
+
+	.pcie_regs = {.phys = CRONUS_ADDR(0x220000)},
+	.tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)},
+	.tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)},
+	.gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)},
+	.gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)},
+	.gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)},
+	.watchdog = {.phys = CRONUS_ADDR(0x2A2C30)},
+	.front_panel = {.phys = CRONUS_ADDR(0x2A3800)},
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic_devices.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_devices.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic_devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_devices.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,779 @@
+/*
+ *                   ASIC Device List Intialization
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <asm/page.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/asic_regs.h>
+#include <asm/mach-powertv/interrupts.h>
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+#include <asm/bootinfo.h>
+
+#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
+
+/*
+ * Forward Prototypes
+ */
+static void pmem_setup_resource(void);
+
+/*
+ * Global Variables
+ */
+enum asic_type asic;
+
+unsigned int platform_features;
+unsigned int platform_family;
+struct register_map _asic_register_map;
+EXPORT_SYMBOL(_asic_register_map);		/* Exported for testing */
+unsigned long asic_phy_base;
+unsigned long asic_base;
+EXPORT_SYMBOL(asic_base);			/* Exported for testing */
+struct resource *gp_resources;
+static bool usb_configured;
+
+/*
+ * Don't recommend to use it directly, it is usually used by kernel internally.
+ * Portable code should be using interfaces such as ioremp, dma_map_single, etc.
+ */
+unsigned long phys_to_bus_offset;
+EXPORT_SYMBOL(phys_to_bus_offset);
+
+/*
+ *
+ * IO Resource Definition
+ *
+ */
+
+struct resource asic_resource = {
+	.name  = "ASIC Resource",
+	.start = 0,
+	.end   = ASIC_IO_SIZE,
+	.flags = IORESOURCE_MEM,
+};
+
+/*
+ *
+ * USB Host Resource Definition
+ *
+ */
+
+static struct resource ehci_resources[] = {
+	{
+		.parent = &asic_resource,
+		.start  = 0,
+		.end    = 0xff,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = irq_usbehci,
+		.end    = irq_usbehci,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device ehci_device = {
+	.name = "powertv-ehci",
+	.id = 0,
+	.num_resources = 2,
+	.resource = ehci_resources,
+	.dev = {
+		.dma_mask = &ehci_dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+};
+
+static struct resource ohci_resources[] = {
+	{
+		.parent = &asic_resource,
+		.start  = 0,
+		.end    = 0xff,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = irq_usbohci,
+		.end    = irq_usbohci,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device ohci_device = {
+	.name = "powertv-ohci",
+	.id = 0,
+	.num_resources = 2,
+	.resource = ohci_resources,
+	.dev = {
+		.dma_mask = &ohci_dmamask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+};
+
+static struct platform_device *platform_devices[] = {
+	&ehci_device,
+	&ohci_device,
+};
+
+/*
+ *
+ * Platform Configuration and Device Initialization
+ *
+ */
+static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3)
+{
+	int en_prg, byp, pwr, nsb, val;
+	int sout;
+
+	sout = 1;
+	en_prg = 1;
+	byp = 0;
+	nsb = 1;
+	pwr = 1;
+
+	val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) |
+		(nsb<<1) | (disable_div_by_3<<5));
+
+	asic_write(val, usb_fs);
+	asic_write(val | (en_prg<<4), usb_fs);
+	asic_write(val | (en_prg<<4) | pwr, usb_fs);
+}
+
+/*
+ * Allow override of bootloader-specified model
+ */
+static char __initdata cmdline[COMMAND_LINE_SIZE];
+
+#define	FORCEFAMILY_PARAM	"forcefamily"
+
+static __init int check_forcefamily(unsigned char forced_family[2])
+{
+	const char *p;
+
+	forced_family[0] = '\0';
+	forced_family[1] = '\0';
+
+	/* Check the command line for a forcefamily directive */
+	strncpy(cmdline, arcs_cmdline, COMMAND_LINE_SIZE - 1);
+	p = strstr(cmdline, FORCEFAMILY_PARAM);
+	if (p && (p != cmdline) && (*(p - 1) != ' '))
+		p = strstr(p, " " FORCEFAMILY_PARAM "=");
+
+	if (p) {
+		p += strlen(FORCEFAMILY_PARAM "=");
+
+		if (*p == '\0' || *(p + 1) == '\0' ||
+			(*(p + 2) != '\0' && *(p + 2) != ' '))
+			pr_err(FORCEFAMILY_PARAM " must be exactly two "
+				"characters long, ignoring value\n");
+
+		else {
+			forced_family[0] = *p;
+			forced_family[1] = *(p + 1);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * platform_set_family - determine major platform family type.
+ *
+ * Returns family type; -1 if none
+ * Returns the family type; -1 if none
+ *
+ */
+static __init noinline void platform_set_family(void)
+{
+#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
+
+	unsigned char forced_family[2];
+	unsigned short bootldr_family;
+
+	check_forcefamily(forced_family);
+
+	if (forced_family[0] != '\0' && forced_family[1] != '\0')
+		bootldr_family = BOOTLDRFAMILY(forced_family[0],
+			forced_family[1]);
+	else {
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+		bootldr_family = (unsigned short) kbldr_GetSWFamily();
+#else
+#if defined(CONFIG_BOOTLOADER_FAMILY)
+		bootldr_family = (unsigned short) BOOTLDRFAMILY(
+			CONFIG_BOOTLOADER_FAMILY[0],
+			CONFIG_BOOTLOADER_FAMILY[1]);
+#else
+#error "Unknown Bootloader Family"
+#endif
+#endif
+	}
+
+	pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
+
+	switch (bootldr_family) {
+	case BOOTLDRFAMILY('R', '1'):
+		platform_family = FAMILY_1500;
+		break;
+	case BOOTLDRFAMILY('4', '4'):
+		platform_family = FAMILY_4500;
+		break;
+	case BOOTLDRFAMILY('4', '6'):
+		platform_family = FAMILY_4600;
+		break;
+	case BOOTLDRFAMILY('A', '1'):
+		platform_family = FAMILY_4600VZA;
+		break;
+	case BOOTLDRFAMILY('8', '5'):
+		platform_family = FAMILY_8500;
+		break;
+	case BOOTLDRFAMILY('R', '2'):
+		platform_family = FAMILY_8500RNG;
+		break;
+	case BOOTLDRFAMILY('8', '6'):
+		platform_family = FAMILY_8600;
+		break;
+	case BOOTLDRFAMILY('B', '1'):
+		platform_family = FAMILY_8600VZB;
+		break;
+	case BOOTLDRFAMILY('E', '1'):
+		platform_family = FAMILY_1500VZE;
+		break;
+	case BOOTLDRFAMILY('F', '1'):
+		platform_family = FAMILY_1500VZF;
+		break;
+	default:
+		platform_family = -1;
+	}
+}
+
+unsigned int platform_get_family(void)
+{
+	return platform_family;
+}
+EXPORT_SYMBOL(platform_get_family);
+
+/*
+ * \brief usb_eye_configure() for optimizing the USB eye on Calliope.
+ *
+ * \param     unsigned int value saved to the register.
+ *
+ * \return    none
+ *
+ */
+static void __init usb_eye_configure(unsigned int value)
+{
+	asic_write(asic_read(crt_spare) | value, crt_spare);
+}
+
+/*
+ * platform_get_asic - determine the ASIC type.
+ *
+ * \param     none
+ *
+ * \return    ASIC type; ASIC_UNKNOWN if none
+ *
+ */
+enum asic_type platform_get_asic(void)
+{
+	return asic;
+}
+EXPORT_SYMBOL(platform_get_asic);
+
+/*
+ * platform_configure_usb - usb configuration based on platform type.
+ * @bcm1_usb2_ctl:	value for the BCM1_USB2_CTL register, which is
+ *			quirky
+ */
+static void __init platform_configure_usb(void)
+{
+	u32 bcm1_usb2_ctl;
+
+	if (usb_configured)
+		return;
+
+	switch (asic) {
+	case ASIC_ZEUS:
+		fs_update(0x0000, 0x11, 0x02, 0);
+		bcm1_usb2_ctl = 0x803;
+		break;
+
+	case ASIC_CRONUS:
+	case ASIC_CRONUSLITE:
+		fs_update(0x0000, 0x11, 0x02, 0);
+		bcm1_usb2_ctl = 0x803;
+		break;
+
+	case ASIC_CALLIOPE:
+		fs_update(0x0000, 0x11, 0x02, 1);
+
+		switch (platform_family) {
+		case FAMILY_1500VZE:
+			break;
+
+		case FAMILY_1500VZF:
+			usb_eye_configure(0x003c0000);
+			break;
+
+		default:
+			usb_eye_configure(0x00300000);
+			break;
+		}
+
+		bcm1_usb2_ctl = 0x803;
+		break;
+
+	default:
+		pr_err("Unknown ASIC type: %d\n", asic);
+		break;
+	}
+
+	/* turn on USB power */
+	asic_write(0, usb2_strap);
+	/* Enable all OHCI interrupts */
+	asic_write(bcm1_usb2_ctl, usb2_control);
+	/* USB2_STBUS_OBC store32/load32 */
+	asic_write(3, usb2_stbus_obc);
+	/* USB2_STBUS_MESS_SIZE 2 packets */
+	asic_write(1, usb2_stbus_mess_size);
+	/* USB2_STBUS_CHUNK_SIZE 2 packets */
+	asic_write(1, usb2_stbus_chunk_size);
+
+	usb_configured = true;
+}
+
+/*
+ * Set up the USB EHCI interface
+ */
+void platform_configure_usb_ehci()
+{
+	platform_configure_usb();
+}
+
+/*
+ * Set up the USB OHCI interface
+ */
+void platform_configure_usb_ohci()
+{
+	platform_configure_usb();
+}
+
+/*
+ * Shut the USB EHCI interface down--currently a NOP
+ */
+void platform_unconfigure_usb_ehci()
+{
+}
+
+/*
+ * Shut the USB OHCI interface down--currently a NOP
+ */
+void platform_unconfigure_usb_ohci()
+{
+}
+
+static void __init set_register_map(unsigned long phys_base,
+	const struct register_map *map)
+{
+	asic_phy_base = phys_base;
+	_asic_register_map = *map;
+	register_map_virtualize(&_asic_register_map);
+	asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE);
+}
+
+/**
+ * configure_platform - configuration based on platform type.
+ */
+void __init configure_platform(void)
+{
+	platform_set_family();
+
+	switch (platform_family) {
+	case FAMILY_1500:
+	case FAMILY_1500VZE:
+	case FAMILY_1500VZF:
+		platform_features = FFS_CAPABLE;
+		asic = ASIC_CALLIOPE;
+		set_register_map(CALLIOPE_IO_BASE, &calliope_register_map);
+
+		if (platform_family == FAMILY_1500VZE) {
+			gp_resources = non_dvr_vze_calliope_resources;
+			pr_info("Platform: 1500/Vz Class E - "
+				"CALLIOPE, NON_DVR_CAPABLE\n");
+		} else if (platform_family == FAMILY_1500VZF) {
+			gp_resources = non_dvr_vzf_calliope_resources;
+			pr_info("Platform: 1500/Vz Class F - "
+				"CALLIOPE, NON_DVR_CAPABLE\n");
+		} else {
+			gp_resources = non_dvr_calliope_resources;
+			pr_info("Platform: 1500/RNG100 - CALLIOPE, "
+				"NON_DVR_CAPABLE\n");
+		}
+		break;
+
+	case FAMILY_4500:
+		platform_features = FFS_CAPABLE | PCIE_CAPABLE |
+			DISPLAY_CAPABLE;
+		asic = ASIC_ZEUS;
+		set_register_map(ZEUS_IO_BASE, &zeus_register_map);
+		gp_resources = non_dvr_zeus_resources;
+
+		pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
+		break;
+
+	case FAMILY_4600:
+	{
+		unsigned int chipversion = 0;
+
+		/* The settop has PCIE but it isn't used, so don't advertise
+		 * it*/
+		platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
+
+		/* ASIC version will determine if this is a real CronusLite or
+		 * Castrati(Cronus) */
+		chipversion  = asic_read(chipver3) << 24;
+		chipversion |= asic_read(chipver2) << 16;
+		chipversion |= asic_read(chipver1) << 8;
+		chipversion |= asic_read(chipver0);
+
+		if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11))
+			asic = ASIC_CRONUS;
+		else
+			asic = ASIC_CRONUSLITE;
+
+		/* Cronus and Cronus Lite have the same register map */
+		set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+		gp_resources = non_dvr_cronuslite_resources;
+		pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
+			"chipversion=0x%08X\n",
+			(asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
+			chipversion);
+		break;
+	}
+	case FAMILY_4600VZA:
+		platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
+		asic = ASIC_CRONUS;
+		set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+		gp_resources = non_dvr_cronus_resources;
+
+		pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
+		break;
+
+	case FAMILY_8500:
+	case FAMILY_8500RNG:
+		platform_features = DVR_CAPABLE | PCIE_CAPABLE |
+			DISPLAY_CAPABLE;
+		asic = ASIC_ZEUS;
+		set_register_map(ZEUS_IO_BASE, &zeus_register_map);
+		gp_resources = dvr_zeus_resources;
+
+		pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n");
+		break;
+
+	case FAMILY_8600:
+	case FAMILY_8600VZB:
+		platform_features = DVR_CAPABLE | PCIE_CAPABLE |
+			DISPLAY_CAPABLE;
+		asic = ASIC_CRONUS;
+		set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+		gp_resources = dvr_cronus_resources;
+
+		pr_info("Platform: 8600/Vz Class B - CRONUS, "
+			"DVR_CAPABLE\n");
+		break;
+
+	default:
+		pr_crit("Platform:  UNKNOWN PLATFORM\n");
+		break;
+	}
+
+	switch (asic) {
+	case ASIC_ZEUS:
+		phys_to_bus_offset = 0x30000000;
+		break;
+	case ASIC_CALLIOPE:
+		phys_to_bus_offset = 0x10000000;
+		break;
+	case ASIC_CRONUSLITE:
+		/* Fall through */
+	case ASIC_CRONUS:
+		/*
+		 * TODO: We suppose 0x10000000 aliases into 0x20000000-
+		 * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
+		 * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
+		 */
+		phys_to_bus_offset = 0x10000000;
+		break;
+	default:
+		phys_to_bus_offset = 0x00000000;
+		break;
+	}
+}
+
+/**
+ * platform_devices_init - sets up USB device resourse.
+ */
+static int __init platform_devices_init(void)
+{
+	pr_notice("%s: ----- Initializing USB resources -----\n", __func__);
+
+	asic_resource.start = asic_phy_base;
+	asic_resource.end += asic_resource.start;
+
+	ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
+	ehci_resources[0].end += ehci_resources[0].start;
+
+	ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
+	ohci_resources[0].end += ohci_resources[0].start;
+
+	set_io_port_base(0);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+	return 0;
+}
+
+arch_initcall(platform_devices_init);
+
+/*
+ *
+ * BOOTMEM ALLOCATION
+ *
+ */
+/*
+ * Allocates/reserves the Platform memory resources early in the boot process.
+ * This ignores any resources that are designated IORESOURCE_IO
+ */
+void __init platform_alloc_bootmem(void)
+{
+	int i;
+	int total = 0;
+
+	/* Get persistent memory data from command line before allocating
+	 * resources. This need to happen before normal command line parsing
+	 * has been done */
+	pmem_setup_resource();
+
+	/* Loop through looking for resources that want a particular address */
+	for (i = 0; gp_resources[i].flags != 0; i++) {
+		int size = gp_resources[i].end - gp_resources[i].start + 1;
+		if ((gp_resources[i].start != 0) &&
+			((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
+			reserve_bootmem(bus_to_phys(gp_resources[i].start),
+				size, 0);
+			total += gp_resources[i].end -
+				gp_resources[i].start + 1;
+			pr_info("reserve resource %s at %08x (%u bytes)\n",
+				gp_resources[i].name, gp_resources[i].start,
+				gp_resources[i].end -
+					gp_resources[i].start + 1);
+		}
+	}
+
+	/* Loop through assigning addresses for those that are left */
+	for (i = 0; gp_resources[i].flags != 0; i++) {
+		int size = gp_resources[i].end - gp_resources[i].start + 1;
+		if ((gp_resources[i].start == 0) &&
+			((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
+			void *mem = alloc_bootmem_pages(size);
+
+			if (mem == NULL)
+				pr_err("Unable to allocate bootmem pages "
+					"for %s\n", gp_resources[i].name);
+
+			else {
+				gp_resources[i].start =
+					phys_to_bus(virt_to_phys(mem));
+				gp_resources[i].end =
+					gp_resources[i].start + size - 1;
+				total += size;
+				pr_info("allocate resource %s at %08x "
+						"(%u bytes)\n",
+					gp_resources[i].name,
+					gp_resources[i].start, size);
+			}
+		}
+	}
+
+	pr_info("Total Platform driver memory allocation: 0x%08x\n", total);
+
+	/* indicate resources that are platform I/O related */
+	for (i = 0; gp_resources[i].flags != 0; i++) {
+		if ((gp_resources[i].start != 0) &&
+			((gp_resources[i].flags & IORESOURCE_IO) != 0)) {
+			pr_info("reserved platform resource %s at %08x\n",
+				gp_resources[i].name, gp_resources[i].start);
+		}
+	}
+}
+
+/*
+ *
+ * PERSISTENT MEMORY (PMEM) CONFIGURATION
+ *
+ */
+static unsigned long pmemaddr __initdata;
+
+static int __init early_param_pmemaddr(char *p)
+{
+	pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0);
+	return 0;
+}
+early_param("pmemaddr", early_param_pmemaddr);
+
+static long pmemlen __initdata;
+
+static int __init early_param_pmemlen(char *p)
+{
+/* TODO: we can use this code when and if the bootloader ever changes this */
+#if 0
+	pmemlen = (unsigned long)simple_strtoul(p, NULL, 0);
+#else
+	pmemlen = 0x20000;
+#endif
+	return 0;
+}
+early_param("pmemlen", early_param_pmemlen);
+
+/*
+ * Set up persistent memory. If we were given values, we patch the array of
+ * resources. Otherwise, persistent memory may be allocated anywhere at all.
+ */
+static void __init pmem_setup_resource(void)
+{
+	struct resource *resource;
+	resource = asic_resource_get("DiagPersistentMemory");
+
+	if (resource && pmemaddr && pmemlen) {
+		/* The address provided by bootloader is in kseg0. Convert to
+		 * a bus address. */
+		resource->start = phys_to_bus(pmemaddr - 0x80000000);
+		resource->end = resource->start + pmemlen - 1;
+
+		pr_info("persistent memory: start=0x%x  end=0x%x\n",
+			resource->start, resource->end);
+	}
+}
+
+/*
+ *
+ * RESOURCE ACCESS FUNCTIONS
+ *
+ */
+
+/**
+ * asic_resource_get - retrieves parameters for a platform resource.
+ * @name:	string to match resource
+ *
+ * Returns a pointer to a struct resource corresponding to the given name.
+ *
+ * CANNOT BE NAMED platform_resource_get, which would be the obvious choice,
+ * as this function name is already declared
+ */
+struct resource *asic_resource_get(const char *name)
+{
+	int i;
+
+	for (i = 0; gp_resources[i].flags != 0; i++) {
+		if (strcmp(gp_resources[i].name, name) == 0)
+			return &gp_resources[i];
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(asic_resource_get);
+
+/**
+ * platform_release_memory - release pre-allocated memory
+ * @ptr:	pointer to memory to release
+ * @size:	size of resource
+ *
+ * This must only be called for memory allocated or reserved via the boot
+ * memory allocator.
+ */
+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));
+	}
+}
+EXPORT_SYMBOL(platform_release_memory);
+
+/*
+ *
+ * FEATURE AVAILABILITY FUNCTIONS
+ *
+ */
+int platform_supports_dvr(void)
+{
+	return (platform_features & DVR_CAPABLE) != 0;
+}
+
+int platform_supports_ffs(void)
+{
+	return (platform_features & FFS_CAPABLE) != 0;
+}
+
+int platform_supports_pcie(void)
+{
+	return (platform_features & PCIE_CAPABLE) != 0;
+}
+
+int platform_supports_display(void)
+{
+	return (platform_features & DISPLAY_CAPABLE) != 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic_int.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_int.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic_int.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic_int.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,125 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ * Portions copyright (C) 2009  Cisco Systems, Inc.
+ *
+ *  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.
+ *
+ * Routines for generic manipulation of the interrupts found on the PowerTV
+ * platform.
+ *
+ * The interrupt controller is located in the South Bridge a PIIX4 device
+ * with two internal 82C95 interrupt controllers.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+
+#include <asm/irq_cpu.h>
+#include <linux/io.h>
+#include <asm/irq_regs.h>
+#include <asm/mips-boards/generic.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static DEFINE_SPINLOCK(asic_irq_lock);
+
+static inline int get_int(void)
+{
+	unsigned long flags;
+	int irq;
+
+	spin_lock_irqsave(&asic_irq_lock, flags);
+
+	irq = (asic_read(int_int_scan) >> 4) - 1;
+
+	if (irq == 0 || irq >= NR_IRQS)
+		irq = -1;
+
+	spin_unlock_irqrestore(&asic_irq_lock, flags);
+
+	return irq;
+}
+
+static void asic_irqdispatch(void)
+{
+	int irq;
+
+	irq = get_int();
+	if (irq < 0)
+		return;  /* interrupt has already been cleared */
+
+	do_IRQ(irq);
+}
+
+static inline int clz(unsigned long x)
+{
+	__asm__(
+	"	.set	push					\n"
+	"	.set	mips32					\n"
+	"	clz	%0, %1					\n"
+	"	.set	pop					\n"
+	: "=r" (x)
+	: "r" (x));
+
+	return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+	return fls(pending) - 1 + CAUSEB_IP;
+}
+
+/*
+ * TODO: check how it works under EIC mode.
+ */
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+	int irq;
+
+	irq = irq_ffs(pending);
+
+	if (irq == CAUSEF_IP3)
+		asic_irqdispatch();
+	else if (irq >= 0)
+		do_IRQ(irq);
+	else
+		spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	asic_irq_init();
+
+	/*
+	 * Initialize interrupt exception vectors.
+	 */
+	if (cpu_has_veic || cpu_has_vint) {
+		int nvec = cpu_has_veic ? 64 : 8;
+		for (i = 0; i < nvec; i++)
+			set_vi_handler(i, asic_irqdispatch);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-zeus.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-zeus.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/asic-zeus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/asic-zeus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Zeus ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ *
+ * Description:  Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define ZEUS_ADDR(x)	(ZEUS_IO_BASE + (x))
+
+const struct register_map zeus_register_map __initdata = {
+	.eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)},
+	.eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)},
+	.eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)},
+
+	.chipver3 = {.phys = ZEUS_ADDR(0x280800)},
+	.chipver2 = {.phys = ZEUS_ADDR(0x280804)},
+	.chipver1 = {.phys = ZEUS_ADDR(0x280808)},
+	.chipver0 = {.phys = ZEUS_ADDR(0x28080c)},
+
+	/* The registers of IRBlaster */
+	.uart1_intstat = {.phys = ZEUS_ADDR(0x281800)},
+	.uart1_inten = {.phys = ZEUS_ADDR(0x281804)},
+	.uart1_config1 = {.phys = ZEUS_ADDR(0x281808)},
+	.uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)},
+	.uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)},
+	.uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)},
+	.uart1_data = {.phys = ZEUS_ADDR(0x281818)},
+	.uart1_status = {.phys = ZEUS_ADDR(0x28181C)},
+
+	.int_stat_3 = {.phys = ZEUS_ADDR(0x282800)},
+	.int_stat_2 = {.phys = ZEUS_ADDR(0x282804)},
+	.int_stat_1 = {.phys = ZEUS_ADDR(0x282808)},
+	.int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)},
+	.int_config = {.phys = ZEUS_ADDR(0x282810)},
+	.int_int_scan = {.phys = ZEUS_ADDR(0x282818)},
+	.ien_int_3 = {.phys = ZEUS_ADDR(0x282830)},
+	.ien_int_2 = {.phys = ZEUS_ADDR(0x282834)},
+	.ien_int_1 = {.phys = ZEUS_ADDR(0x282838)},
+	.ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)},
+	.int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)},
+	.int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)},
+	.int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)},
+	.int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)},
+	.int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)},
+	.int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)},
+	.int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)},
+	.int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)},
+	.int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)},
+	.int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)},
+	.int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)},
+	.int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)},
+	.int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)},
+	.int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)},
+	.int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)},
+	.int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)},
+	.int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
+
+	.mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
+	.usb_fs = {.phys = ZEUS_ADDR(0x1a0018)},
+	.test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
+	.crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
+	.usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
+	.usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)},
+	.ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)},
+	.ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)},
+	.bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)},
+	.usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)},
+	.usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)},
+	.usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)},
+	.usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)},
+
+	.pcie_regs = {.phys = ZEUS_ADDR(0x200000)},
+	.tim_ch = {.phys = ZEUS_ADDR(0x282C10)},
+	.tim_cl = {.phys = ZEUS_ADDR(0x282C14)},
+	.gpio_dout = {.phys = ZEUS_ADDR(0x282c20)},
+	.gpio_din = {.phys = ZEUS_ADDR(0x282c24)},
+	.gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)},
+	.watchdog = {.phys = ZEUS_ADDR(0x282c30)},
+	.front_panel = {.phys = ZEUS_ADDR(0x283800)},
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/irq_asic.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/irq_asic.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/irq_asic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/irq_asic.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,116 @@
+/*
+ * Portions copyright (C) 2005-2009 Scientific Atlanta
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * Modified from arch/mips/kernel/irq-rm7000.c:
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * 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/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static inline void unmask_asic_irq(unsigned int irq)
+{
+	unsigned long enable_bit;
+
+	enable_bit = (1 << (irq & 0x1f));
+
+	switch (irq >> 5) {
+	case 0:
+		asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
+		break;
+	case 1:
+		asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
+		break;
+	case 2:
+		asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
+		break;
+	case 3:
+		asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static inline void mask_asic_irq(unsigned int irq)
+{
+	unsigned long disable_mask;
+
+	disable_mask = ~(1 << (irq & 0x1f));
+
+	switch (irq >> 5) {
+	case 0:
+		asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
+		break;
+	case 1:
+		asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
+		break;
+	case 2:
+		asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
+		break;
+	case 3:
+		asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static struct irq_chip asic_irq_chip = {
+	.name = "ASIC Level",
+	.ack = mask_asic_irq,
+	.mask = mask_asic_irq,
+	.mask_ack = mask_asic_irq,
+	.unmask = unmask_asic_irq,
+	.eoi = unmask_asic_irq,
+};
+
+void __init asic_irq_init(void)
+{
+	int i;
+
+	/* set priority to 0 */
+	write_c0_status(read_c0_status() & ~(0x0000fc00));
+
+	asic_write(0, ien_int_0);
+	asic_write(0, ien_int_1);
+	asic_write(0, ien_int_2);
+	asic_write(0, ien_int_3);
+
+	asic_write(0x0fffffff, int_level_3_3);
+	asic_write(0xffffffff, int_level_3_2);
+	asic_write(0xffffffff, int_level_3_1);
+	asic_write(0xffffffff, int_level_3_0);
+	asic_write(0xffffffff, int_level_2_3);
+	asic_write(0xffffffff, int_level_2_2);
+	asic_write(0xffffffff, int_level_2_1);
+	asic_write(0xffffffff, int_level_2_0);
+	asic_write(0xffffffff, int_level_1_3);
+	asic_write(0xffffffff, int_level_1_2);
+	asic_write(0xffffffff, int_level_1_1);
+	asic_write(0xffffffff, int_level_1_0);
+	asic_write(0xffffffff, int_level_0_3);
+	asic_write(0xffffffff, int_level_0_2);
+	asic_write(0xffffffff, int_level_0_1);
+	asic_write(0xffffffff, int_level_0_0);
+
+	asic_write(0xf, int_int_scan);
+
+	/*
+	 * Initialize interrupt handlers.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/Kconfig linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+config MIN_RUNTIME_RESOURCES
+	bool "Support for minimum runtime resources"
+	default n
+	depends on POWERTV
+	help
+	  Enables support for minimizing the number of (SA asic) runtime
+	  resources that are preallocated by the kernel.
+
+config MIN_RUNTIME_DOCSIS
+	bool "Support for minimum DOCSIS resource"
+	default y
+	depends on MIN_RUNTIME_RESOURCES
+	help
+	  Enables support for the preallocated DOCSIS resource.
+
+config MIN_RUNTIME_PMEM
+	bool "Support for minimum PMEM resource"
+	default y
+	depends on MIN_RUNTIME_RESOURCES
+	help
+	  Enables support for the preallocated Memory resource.
+
+config MIN_RUNTIME_TFTP
+	bool "Support for minimum TFTP resource"
+	default y
+	depends on MIN_RUNTIME_RESOURCES
+	help
+	  Enables support for the preallocated TFTP resource.
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/Makefile linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2009  Scientific-Atlanta, 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You 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
+#
+
+obj-y += asic-calliope.o asic-cronus.o asic-zeus.o asic_devices.o asic_int.o \
+	 irq_asic.o prealloc-calliope.o prealloc-cronus.o \
+	 prealloc-cronuslite.o prealloc-zeus.o
+
+EXTRA_CFLAGS += -Wall -Werror
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-calliope.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-calliope.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-calliope.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-calliope.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,620 @@
+/*
+ * Memory pre-allocations for Calliope boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * NON_DVR_CAPABLE CALLIOPE RESOURCES
+ */
+struct resource non_dvr_calliope_resources[] __initdata =
+{
+	/*
+	 * VIDEO / LX1
+	 */
+	{
+		.name   = "ST231aImage",     	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x24200000 - 1,	/*2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",   /*8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24202000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		.end    = 0x26700000 - 1, /*~36.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Sysaudio Driver
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * STAVEM driver/STAPI
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x00000000,
+		.end    = 0x00600000 - 1,	/* 6 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DOCSIS Subsystem
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x22000000,
+		.end    = 0x22700000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * GHW HAL Driver
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x22700000,
+		.end    = 0x23500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * multi com buffer area
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x23700000,
+		.end    = 0x23720000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DMA Ring buffer (don't need recording buffers)
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit0
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x00000000,
+		.end    = 0x002c4c00 - 1,	/* 945K * 3 for playback */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * PMEM
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Smartcard
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE + 0x400 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Synopsys GMAC Memory Region
+	 */
+	{
+		.name   = "GMAC",
+		.start  = 0x00000000,
+		.end    = 0x00010000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Add other resources here
+	 *
+	 */
+	{ },
+};
+
+struct resource non_dvr_vz_calliope_resources[] __initdata =
+{
+	/*
+	 * VIDEO / LX1
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x24200000 - 1, /*2 Meg */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8k block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24202000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x22202000,
+		.end    = 0x22C20B85 - 1,	/* 10.12 Meg */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Sysaudio Driver
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * STAVEM driver/STAPI
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x20300000,
+		.end    = 0x20620000-1,  /*3.125 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * GHW HAL Driver
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x20100000,
+		.end    = 0x20300000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * multi com buffer area
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x23900000,
+		.end    = 0x23920000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DMA Ring buffer
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit0
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * PMEM
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Smartcard
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE+0x400 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Synopsys GMAC Memory Region
+	 */
+	{
+		.name   = "GMAC",
+		.start  = 0x00000000,
+		.end    = 0x00010000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
+
+struct resource non_dvr_vze_calliope_resources[] __initdata =
+{
+	/*
+	 * VIDEO / LX1
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x22000000,
+		.end    = 0x22200000 - 1,	/*2  Meg */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8k block ST231a monitor */
+		.start  = 0x22200000,
+		.end    = 0x22202000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x22202000,
+		.end    = 0x22C20B85 - 1,	/* 10.12 Meg */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Sysaudio Driver
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * STAVEM driver/STAPI
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x20396000,
+		.end    = 0x206B6000 - 1,		/* 3.125 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * GHW HAL Driver
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x20100000,
+		.end    = 0x20396000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * multi com buffer area
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x206B6000,
+		.end    = 0x206D6000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DMA Ring buffer
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit0
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * PMEM
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Smartcard
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE+0x400 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Synopsys GMAC Memory Region
+	 */
+	{
+		.name   = "GMAC",
+		.start  = 0x00000000,
+		.end    = 0x00010000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
+
+struct resource non_dvr_vzf_calliope_resources[] __initdata =
+{
+	/*
+	 * VIDEO / LX1
+	 */
+	{
+		.name   = "ST231aImage",	/*Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x24200000 - 1,	/*2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/*8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24202000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		/* ~19.4 (21.5MiB - (2MiB + 8KiB)) */
+		.end    = 0x25580000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Sysaudio Driver
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * STAVEM driver/STAPI
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x00000000,
+		.end    = 0x00480000 - 1,  /* 4.5 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * GHW HAL Driver
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x22700000,
+		.end    = 0x23500000 - 1, /* 14 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * multi com buffer area
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x23700000,
+		.end    = 0x23720000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DMA Ring buffer (don't need recording buffers)
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit0
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,  /* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit1
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,  /* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x00000000,
+		.end    = 0x002c4c00 - 1,  /* 945K * 3 for playback */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * PMEM
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Smartcard
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE + 0x400 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Synopsys GMAC Memory Region
+	 */
+	{
+		.name   = "GMAC",
+		.start  = 0x00000000,
+		.end    = 0x00010000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-cronus.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-cronus.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-cronus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-cronus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,608 @@
+/*
+ * Memory pre-allocations for Cronus boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * DVR_CAPABLE CRONUS RESOURCES
+ */
+struct resource dvr_cronus_resources[] __initdata =
+{
+	/*
+	 *
+	 * VIDEO1 / LX1
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x241FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24201FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		.end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231bImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x60000000,
+		.end    = 0x601FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231bMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x60200000,
+		.end    = 0x60201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory2",
+		.start  = 0x60202000,
+		.end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x63580000,
+		.end    = 0x64180000 - 1,  /* 12 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x62000000,
+		.end    = 0x62700000 - 1,	/* 7 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x62700000,
+		.end    = 0x63500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x26000000,
+		.end    = 0x26020000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x00280000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x64AD4000,
+		.end    = 0x64AD5000 - 1,  /* 4 KB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * ITFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "ITFS",
+		.start  = 0x64180000,
+		/* 815,104 bytes each for 2 ITFS partitions. */
+		.end    = 0x6430DFFF,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * AVFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x6430E000,
+		/* (945K * 8) = (128K *3) 5 playbacks / 3 server */
+		.end    = 0x64AD0000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "AvfsFileSys",
+		.start  = 0x64AD0000,
+		.end    = 0x64AD1000 - 1,  /* 4K */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * PMEM
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Persistent memory for diagnostics.
+	 *
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x64AD1000,
+		.end    = 0x64AD3800 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * KAVNET
+	 *    NP Reset Vector - must be of the form xxCxxxxx
+	 *	   NP Image - must be video bank 1
+	 *	   NP IPC - must be video bank 2
+	 */
+	{
+		.name   = "NP_Reset_Vector",
+		.start  = 0x27c00000,
+		.end    = 0x27c01000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_Image",
+		.start  = 0x27020000,
+		.end    = 0x27060000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_IPC",
+		.start  = 0x63500000,
+		.end    = 0x63580000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
+
+/*
+ * NON_DVR_CAPABLE CRONUS RESOURCES
+ */
+struct resource non_dvr_cronus_resources[] __initdata =
+{
+	/*
+	 *
+	 * VIDEO1 / LX1
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x24000000,
+		.end    = 0x241FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x24200000,
+		.end    = 0x24201FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x24202000,
+		.end    = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231bImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x60000000,
+		.end    = 0x601FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231bMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x60200000,
+		.end    = 0x60201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory2",
+		.start  = 0x60202000,
+		.end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x63580000,
+		.end    = 0x64180000 - 1,  /* 12 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x62000000,
+		.end    = 0x62700000 - 1,	/* 7 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x62700000,
+		.end    = 0x63500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x26000000,
+		.end    = 0x26020000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x64AD4000,
+		.end    = 0x64AD5000 - 1,  /* 4 KB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x6430E000,
+		.end    = 0x645D2C00 - 1,  /* 945K * 3 for playback */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * PMEM
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Persistent memory for diagnostics.
+	 *
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x64AD1000,
+		.end    = 0x64AD3800 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * KAVNET
+	 *    NP Reset Vector - must be of the form xxCxxxxx
+	 *	   NP Image - must be video bank 1
+	 *	   NP IPC - must be video bank 2
+	 */
+	{
+		.name   = "NP_Reset_Vector",
+		.start  = 0x27c00000,
+		.end    = 0x27c01000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_Image",
+		.start  = 0x27020000,
+		.end    = 0x27060000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_IPC",
+		.start  = 0x63500000,
+		.end    = 0x63580000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	{ },
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-cronuslite.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-cronuslite.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-cronuslite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-cronuslite.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,290 @@
+/*
+ * Memory pre-allocations for Cronus Lite boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * NON_DVR_CAPABLE CRONUSLITE RESOURCES
+ */
+struct resource non_dvr_cronuslite_resources[] __initdata =
+{
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x60000000,
+		.end    = 0x601FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x60200000,
+		.end    = 0x60201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x60202000,
+		.end    = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x63580000,
+		.end    = 0x63B80000 - 1,  /* 6 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x62000000,
+		.end    = 0x62700000 - 1,	/* 7 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x62700000,
+		.end    = 0x63500000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x26000000,
+		.end    = 0x26020000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x000AA000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x63B83000,
+		.end    = 0x63B84000 - 1,  /* 4 KB total */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x63B84000,
+		.end    = 0x63E48C00 - 1,  /* 945K * 3 for playback */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * PMEM
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Persistent memory for diagnostics.
+	 *
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x63B80000,
+		.end    = 0x63B82800 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * KAVNET
+	 *    NP Reset Vector - must be of the form xxCxxxxx
+	 *	   NP Image - must be video bank 1
+	 *	   NP IPC - must be video bank 2
+	 */
+	{
+		.name   = "NP_Reset_Vector",
+		.start  = 0x27c00000,
+		.end    = 0x27c01000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_Image",
+		.start  = 0x27020000,
+		.end    = 0x27060000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "NP_IPC",
+		.start  = 0x63500000,
+		.end    = 0x63580000 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE + 0x400 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-zeus.c linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-zeus.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/asic/prealloc-zeus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/asic/prealloc-zeus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,459 @@
+/*
+ * Memory pre-allocations for Zeus boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author:       Ken Eppinett
+ *               David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * DVR_CAPABLE RESOURCES
+ */
+struct resource dvr_zeus_resources[] __initdata =
+{
+	/*
+	 *
+	 * VIDEO1 / LX1
+	 *
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x20000000,
+		.end    = 0x201FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x20200000,
+		.end    = 0x20201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x20202000,
+		.end    = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * VIDEO2 / LX2
+	 *
+	 */
+	{
+		.name   = "ST231bImage",	/* Delta-Mu 2 image and ram */
+		.start  = 0x30000000,
+		.end    = 0x301FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231bMonitor",	/* 8KiB block ST231b monitor */
+		.start  = 0x30200000,
+		.end    = 0x30201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory2",
+		.start  = 0x30202000,
+		.end    = 0x31FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 *
+	 * Sysaudio Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  DSP_Image_Buff - DSP code and data images (1MB)
+	 *  ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+	 *  ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+	 *  ADSC_Main_Buff - ADSC Main buffer (16KB)
+	 *
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * STAVEM driver/STAPI
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  This memory area is used for allocating buffers for Video decoding
+	 *  purposes.  Allocation/De-allocation within this buffer is managed
+	 *  by the STAVMEM driver of the STAPI.  They could be Decimated
+	 *  Picture Buffers, Intermediate Buffers, as deemed necessary for
+	 *  video decoding purposes, for any video decoders on Zeus.
+	 *
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x00000000,
+		.end    = 0x00c00000 - 1,	/* 12 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DOCSIS Subsystem
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x40100000,
+		.end    = 0x407fffff,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * GHW HAL Driver
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  GraphicsHeap - PowerTV Graphics Heap
+	 *
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x46900000,
+		.end    = 0x47700000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * multi com buffer area
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x47900000,
+		.end    = 0x47920000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * DMA Ring buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x00280000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer for unit0
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit0
+	 *
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,	/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Display bins buffer
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Display Bins for unit1
+	 *
+	 */
+	{
+		.name   = "DisplayBins1",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,	/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * ITFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "ITFS",
+		.start  = 0x00000000,
+		/* 815,104 bytes each for 2 ITFS partitions. */
+		.end    = 0x0018DFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * AVFS
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Docsis -
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x00000000,
+		/* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
+		.end    = 0x007c2000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "AvfsFileSys",
+		.start  = 0x00000000,
+		.end    = 0x00001000 - 1,  /* 4K */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * PMEM
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Persistent memory for diagnostics.
+	 *
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * Smartcard
+	 *
+	 * This driver requires:
+	 *
+	 * Arbitrary Based Buffers:
+	 *  Read and write buffers for Internal/External cards
+	 *
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
+
+/*
+ * NON_DVR_CAPABLE ZEUS RESOURCES
+ */
+struct resource non_dvr_zeus_resources[] __initdata =
+{
+	/*
+	 * VIDEO1 / LX1
+	 */
+	{
+		.name   = "ST231aImage",	/* Delta-Mu 1 image and ram */
+		.start  = 0x20000000,
+		.end    = 0x201FFFFF,		/* 2MiB */
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "ST231aMonitor",	/* 8KiB block ST231a monitor */
+		.start  = 0x20200000,
+		.end    = 0x20201FFF,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "MediaMemory1",
+		.start  = 0x20202000,
+		.end    = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Sysaudio Driver
+	 */
+	{
+		.name   = "DSP_Image_Buff",
+		.start  = 0x00000000,
+		.end    = 0x000FFFFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_CPU_PCM_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00009FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_AUX_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "ADSC_Main_Buff",
+		.start  = 0x00000000,
+		.end    = 0x00003FFF,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * STAVEM driver/STAPI
+	 */
+	{
+		.name   = "AVMEMPartition0",
+		.start  = 0x00000000,
+		.end    = 0x00600000 - 1,	/* 6 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DOCSIS Subsystem
+	 */
+	{
+		.name   = "Docsis",
+		.start  = 0x40100000,
+		.end    = 0x407fffff,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * GHW HAL Driver
+	 */
+	{
+		.name   = "GraphicsHeap",
+		.start  = 0x46900000,
+		.end    = 0x47700000 - 1,	/* 14 MB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * multi com buffer area
+	 */
+	{
+		.name   = "MulticomSHM",
+		.start  = 0x47900000,
+		.end    = 0x47920000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * DMA Ring buffer
+	 */
+	{
+		.name   = "BMM_Buffer",
+		.start  = 0x00000000,
+		.end    = 0x00280000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Display bins buffer for unit0
+	 */
+	{
+		.name   = "DisplayBins0",
+		.start  = 0x00000000,
+		.end    = 0x00000FFF,		/* 4 KB total */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 *
+	 * AVFS: player HAL memory
+	 *
+	 *
+	 */
+	{
+		.name   = "AvfsDmaMem",
+		.start  = 0x00000000,
+		.end    = 0x002c4c00 - 1,	/* 945K * 3 for playback */
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * PMEM
+	 */
+	{
+		.name   = "DiagPersistentMemory",
+		.start  = 0x00000000,
+		.end    = 0x10000 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * Smartcard
+	 */
+	{
+		.name   = "SmartCardInfo",
+		.start  = 0x00000000,
+		.end    = 0x2800 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	/*
+	 * NAND Flash
+	 */
+	{
+		.name   = "NandFlash",
+		.start  = NAND_FLASH_BASE,
+		.end    = NAND_FLASH_BASE + 0x400 - 1,
+		.flags  = IORESOURCE_IO,
+	},
+	/*
+	 * Add other resources here
+	 */
+	{ },
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/init.c linux-libre-2.6.33-gnu1/arch/mips/powertv/init.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ *  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.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mach-powertv/asic.h>
+
+static int *_prom_envp;
+unsigned long _prom_memsize;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+char *prom_getenv(char *envname)
+{
+	char *result = NULL;
+
+	if (_prom_envp != NULL) {
+		/*
+		 * Return a pointer to the given environment variable.
+		 * In 64-bit mode: we're using 64-bit pointers, but all pointers
+		 * in the PROM structures are only 32-bit, so we need some
+		 * workarounds, if we are running in 64-bit mode.
+		 */
+		int i, index = 0;
+
+		i = strlen(envname);
+
+		while (prom_envp(index)) {
+			if (strncmp(envname, prom_envp(index), i) == 0) {
+				result = prom_envp(index + 1);
+				break;
+			}
+			index += 2;
+		}
+	}
+
+	return result;
+}
+
+/* TODO: Verify on linux-mips mailing list that the following two  */
+/* functions are correct                                           */
+/* TODO: Copy NMI and EJTAG exception vectors to memory from the   */
+/* BootROM exception vectors. Flush their cache entries. test it.  */
+
+static void __init mips_nmi_setup(void)
+{
+	void *base;
+#if defined(CONFIG_CPU_MIPS32_R1)
+	base = cpu_has_veic ?
+		(void *)(CAC_BASE + 0xa80) :
+		(void *)(CAC_BASE + 0x380);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+	base = (void *)0xbfc00000;
+#else
+#error NMI exception handler address not defined
+#endif
+}
+
+static void __init mips_ejtag_setup(void)
+{
+	void *base;
+
+#if defined(CONFIG_CPU_MIPS32_R1)
+	base = cpu_has_veic ?
+		(void *)(CAC_BASE + 0xa00) :
+		(void *)(CAC_BASE + 0x300);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+	base = (void *)0xbfc00480;
+#else
+#error EJTAG exception handler address not defined
+#endif
+}
+
+void __init prom_init(void)
+{
+	int prom_argc;
+	char *prom_argv;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char *) fw_arg1;
+	_prom_envp = (int *) fw_arg2;
+	_prom_memsize = (unsigned long) fw_arg3;
+
+	board_nmi_handler_setup = mips_nmi_setup;
+	board_ejtag_handler_setup = mips_ejtag_setup;
+
+	if (prom_argc == 1)
+		strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
+
+	configure_platform();
+	prom_meminit();
+
+#ifndef CONFIG_BOOTLOADER_DRIVER
+	pr_info("\nBootloader driver isn't loaded...\n");
+#endif
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/init.h linux-libre-2.6.33-gnu1/arch/mips/powertv/init.h
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/init.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/init.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ * Definitions from powertv init.c file
+ *
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_INIT_H
+#define _POWERTV_INIT_H
+extern unsigned long _prom_memsize;
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/Kconfig linux-libre-2.6.33-gnu1/arch/mips/powertv/Kconfig
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,21 @@
+source "arch/mips/powertv/asic/Kconfig"
+
+config BOOTLOADER_DRIVER
+	bool "PowerTV Bootloader Driver Support"
+	default n
+	depends on POWERTV
+	help
+	  Use this option if you want to load bootloader driver.
+
+config BOOTLOADER_FAMILY
+	string "POWERTV Bootloader Family string"
+	default "85"
+	depends on POWERTV && !BOOTLOADER_DRIVER
+	help
+	  This value should be specified when the bootloader driver is disabled
+	  and must be exactly two characters long. Families supported are:
+	    R1 - RNG-100  R2 - RNG-200
+	    A1 - Class A  B1 - Class B
+	    E1 - Class E  F1 - Class F
+	    44 - 45xx     46 - 46xx
+	    85 - 85xx     86 - 86xx
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/Makefile linux-libre-2.6.33-gnu1/arch/mips/powertv/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+# Portions copyright (C)  2009 Cisco Systems, Inc.
+#
+# 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.
+#
+# Makefile for the Cisco PowerTV-specific kernel interface routines
+# under Linux.
+#
+
+obj-y += init.o memory.o reset.o time.o powertv_setup.o asic/ pci/
+
+EXTRA_CFLAGS += -Wall -Werror
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/memory.c linux-libre-2.6.33-gnu1/arch/mips/powertv/memory.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/memory.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,181 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ *  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.
+ *
+ * Apparently originally from arch/mips/malta-memory.c. Modified to work
+ * with the PowerTV bootloader.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mips-boards/prom.h>
+
+#include "init.h"
+
+/* Memory constants */
+#define KIBIBYTE(n)		((n) * 1024)	/* Number of kibibytes */
+#define MEBIBYTE(n)		((n) * KIBIBYTE(1024)) /* Number of mebibytes */
+#define DEFAULT_MEMSIZE		MEBIBYTE(256)	/* If no memsize provided */
+#define LOW_MEM_MAX		MEBIBYTE(252)	/* Max usable low mem */
+#define RES_BOOTLDR_MEMSIZE	MEBIBYTE(1)	/* Memory reserved for bldr */
+#define BOOT_MEM_SIZE		KIBIBYTE(256)	/* Memory reserved for bldr */
+#define PHYS_MEM_START		0x10000000	/* Start of physical memory */
+
+char __initdata cmdline[COMMAND_LINE_SIZE];
+
+void __init prom_meminit(void)
+{
+	char *memsize_str;
+	unsigned long memsize = 0;
+	unsigned int physend;
+	char *ptr;
+	int low_mem;
+	int high_mem;
+
+	/* Check the command line first for a memsize directive */
+	strcpy(cmdline, arcs_cmdline);
+	ptr = strstr(cmdline, "memsize=");
+	if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+		ptr = strstr(ptr, " memsize=");
+
+	if (ptr) {
+		memsize = memparse(ptr + 8, &ptr);
+	} else {
+		/* otherwise look in the environment */
+		memsize_str = prom_getenv("memsize");
+
+		if (memsize_str != NULL) {
+			pr_info("prom memsize = %s\n", memsize_str);
+			memsize = simple_strtol(memsize_str, NULL, 0);
+		}
+
+		if (memsize == 0) {
+			if (_prom_memsize != 0) {
+				memsize = _prom_memsize;
+				pr_info("_prom_memsize = 0x%lx\n", memsize);
+				/* add in memory that the bootloader doesn't
+				 * report */
+				memsize += BOOT_MEM_SIZE;
+			} else {
+				memsize = DEFAULT_MEMSIZE;
+				pr_info("Memsize not passed by bootloader, "
+					"defaulting to 0x%lx\n", memsize);
+			}
+		}
+	}
+
+	physend = PFN_ALIGN(&_end) - 0x80000000;
+	if (memsize > LOW_MEM_MAX) {
+		low_mem = LOW_MEM_MAX;
+		high_mem = memsize - low_mem;
+	} else {
+		low_mem = memsize;
+		high_mem = 0;
+	}
+
+/*
+ * TODO: We will use the hard code for memory configuration until
+ * the bootloader releases their device tree to us.
+ */
+	/*
+	 * Add the memory reserved for use by the bootloader to the
+	 * memory map.
+	 */
+	add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
+		BOOT_MEM_RESERVED);
+#ifdef CONFIG_HIGHMEM_256_128
+	/*
+	 * Add memory in low for general use by the kernel and its friends
+	 * (like drivers, applications, etc).
+	 */
+	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+		LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+	/*
+	 * Add the memory reserved for reset vector.
+	 */
+	add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
+	/*
+	 * Add the memory reserved.
+	 */
+	add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
+	/*
+	 * Add memory in high for general use by the kernel and its friends
+	 * (like drivers, applications, etc).
+	 *
+	 * 75MB is reserved for devices which are using the memory in high.
+	 */
+	add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
+		BOOT_MEM_RAM);
+#elif defined CONFIG_HIGHMEM_128_128
+	/*
+	 * Add memory in low for general use by the kernel and its friends
+	 * (like drivers, applications, etc).
+	 */
+	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+		MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+	/*
+	 * Add the memory reserved.
+	 */
+	add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
+		MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
+	/*
+	 * Add memory in high for general use by the kernel and its friends
+	 * (like drivers, applications, etc).
+	 *
+	 * 75MB is reserved for devices which are using the memory in high.
+	 */
+	add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
+		BOOT_MEM_RAM);
+#else
+	/* Add low memory regions for either:
+	 *   - no-highmemory configuration case -OR-
+	 *   - highmemory "HIGHMEM_LOWBANK_ONLY" case
+	 */
+	/*
+	 * Add memory for general use by the kernel and its friends
+	 * (like drivers, applications, etc).
+	 */
+	add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+		low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+	/*
+	 * Add the memory reserved for reset vector.
+	 */
+	add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+	unsigned long addr;
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+			continue;
+
+		addr = boot_mem_map.map[i].addr;
+		free_init_pages("prom memory",
+				addr, addr + boot_mem_map.map[i].size);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/fixup-powertv.c linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/fixup-powertv.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/fixup-powertv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/fixup-powertv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,36 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/mach-powertv/interrupts.h>
+#include "powertv-pci.h"
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return asic_pcie_map_irq(dev, slot, pin);
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+/*
+ * asic_pcie_map_irq
+ *
+ * Parameters:
+ * *dev - pointer to a pci_dev structure  (not used)
+ * slot - slot number  (not used)
+ * pin - pin number  (not used)
+ *
+ * Return Value:
+ * Returns: IRQ number (always the PCI Express IRQ number)
+ *
+ * Description:
+ * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt.
+ *
+ */
+int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_pciexp;
+}
+EXPORT_SYMBOL(asic_pcie_map_irq);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/Makefile linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/Makefile
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2009  Scientific-Atlanta, 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You 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
+#
+
+obj-$(CONFIG_PCI)	+= fixup-powertv.o
+
+EXTRA_CFLAGS += -Wall -Werror
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/powertv-pci.h linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/powertv-pci.h
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/pci/powertv-pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/pci/powertv-pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,31 @@
+/*
+ *				powertv-pci.c
+ *
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ */
+/*
+ * Local definitions for the powertv PCI code
+ */
+
+#ifndef _POWERTV_PCI_POWERTV_PCI_H_
+#define _POWERTV_PCI_POWERTV_PCI_H_
+extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int asic_pcie_init(void);
+extern int asic_pcie_init(void);
+
+extern int log_level;
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/powertv-clock.h linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv-clock.h
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/powertv-clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv-clock.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_POWERTV_CLOCK_H
+#define _POWERTV_POWERTV_CLOCK_H
+extern int powertv_clockevent_init(void);
+extern void powertv_clocksource_init(void);
+extern unsigned int mips_get_pll_freq(void);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/powertv_setup.c linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv_setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/powertv_setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/powertv_setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,330 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ *  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.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/screen_info.h>
+#include <linux/notifier.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <linux/ctype.h>
+
+#include <linux/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/dma.h>
+#include <linux/time.h>
+#include <asm/traps.h>
+#include <asm/asm-offsets.h>
+#include "reset.h"
+
+#define VAL(n)		STR(n)
+
+/*
+ * Macros for loading addresses and storing registers:
+ * PTR_LA	Load the address into a register
+ * LONG_S	Store the full width of the given register.
+ * LONG_L	Load the full width of the given register
+ * PTR_ADDIU	Add a constant value to a register used as a pointer
+ * REG_SIZE	Number of 8-bit bytes in a full width register
+ */
+#ifdef CONFIG_64BIT
+#warning TODO: 64-bit code needs to be verified
+#define PTR_LA		"dla	"
+#define LONG_S		"sd	"
+#define LONG_L		"ld	"
+#define PTR_ADDIU	"daddiu	"
+#define REG_SIZE	"8"		/* In bytes */
+#endif
+
+#ifdef CONFIG_32BIT
+#define PTR_LA		"la	"
+#define LONG_S		"sw	"
+#define LONG_L		"lw	"
+#define PTR_ADDIU	"addiu	"
+#define REG_SIZE	"4"		/* In bytes */
+#endif
+
+static void register_panic_notifier(void);
+static int panic_handler(struct notifier_block *notifier_block,
+	unsigned long event, void *cause_string);
+
+const char *get_system_type(void)
+{
+	return "PowerTV";
+}
+
+void __init plat_mem_setup(void)
+{
+	panic_on_oops = 1;
+	register_panic_notifier();
+
+#if 0
+	mips_pcibios_init();
+#endif
+	mips_reboot_setup();
+}
+
+/*
+ * Install a panic notifier for platform-specific diagnostics
+ */
+static void register_panic_notifier()
+{
+	static struct notifier_block panic_notifier = {
+		.notifier_call = panic_handler,
+		.next = NULL,
+		.priority	= INT_MAX
+	};
+	atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
+}
+
+static int panic_handler(struct notifier_block *notifier_block,
+	unsigned long event, void *cause_string)
+{
+	struct pt_regs	my_regs;
+
+	/* Save all of the registers */
+	{
+		unsigned long	at, v0, v1; /* Must be on the stack */
+
+		/* Start by saving $at and v0 on the stack. We use $at
+		 * ourselves, but it looks like the compiler may use v0 or v1
+		 * to load the address of the pt_regs structure. We'll come
+		 * back later to store the registers in the pt_regs
+		 * structure. */
+		__asm__ __volatile__ (
+			".set	noat\n"
+			LONG_S		"$at, %[at]\n"
+			LONG_S		"$2, %[v0]\n"
+			LONG_S		"$3, %[v1]\n"
+		:
+			[at] "=m" (at),
+			[v0] "=m" (v0),
+			[v1] "=m" (v1)
+		:
+		:	"at"
+		);
+
+		__asm__ __volatile__ (
+			".set	noat\n"
+			"move		$at, %[pt_regs]\n"
+
+			/* Argument registers */
+			LONG_S		"$4, " VAL(PT_R4) "($at)\n"
+			LONG_S		"$5, " VAL(PT_R5) "($at)\n"
+			LONG_S		"$6, " VAL(PT_R6) "($at)\n"
+			LONG_S		"$7, " VAL(PT_R7) "($at)\n"
+
+			/* Temporary regs */
+			LONG_S		"$8, " VAL(PT_R8) "($at)\n"
+			LONG_S		"$9, " VAL(PT_R9) "($at)\n"
+			LONG_S		"$10, " VAL(PT_R10) "($at)\n"
+			LONG_S		"$11, " VAL(PT_R11) "($at)\n"
+			LONG_S		"$12, " VAL(PT_R12) "($at)\n"
+			LONG_S		"$13, " VAL(PT_R13) "($at)\n"
+			LONG_S		"$14, " VAL(PT_R14) "($at)\n"
+			LONG_S		"$15, " VAL(PT_R15) "($at)\n"
+
+			/* "Saved" registers */
+			LONG_S		"$16, " VAL(PT_R16) "($at)\n"
+			LONG_S		"$17, " VAL(PT_R17) "($at)\n"
+			LONG_S		"$18, " VAL(PT_R18) "($at)\n"
+			LONG_S		"$19, " VAL(PT_R19) "($at)\n"
+			LONG_S		"$20, " VAL(PT_R20) "($at)\n"
+			LONG_S		"$21, " VAL(PT_R21) "($at)\n"
+			LONG_S		"$22, " VAL(PT_R22) "($at)\n"
+			LONG_S		"$23, " VAL(PT_R23) "($at)\n"
+
+			/* Add'l temp regs */
+			LONG_S		"$24, " VAL(PT_R24) "($at)\n"
+			LONG_S		"$25, " VAL(PT_R25) "($at)\n"
+
+			/* Kernel temp regs */
+			LONG_S		"$26, " VAL(PT_R26) "($at)\n"
+			LONG_S		"$27, " VAL(PT_R27) "($at)\n"
+
+			/* Global pointer, stack pointer, frame pointer and
+			 * return address */
+			LONG_S		"$gp, " VAL(PT_R28) "($at)\n"
+			LONG_S		"$sp, " VAL(PT_R29) "($at)\n"
+			LONG_S		"$fp, " VAL(PT_R30) "($at)\n"
+			LONG_S		"$ra, " VAL(PT_R31) "($at)\n"
+
+			/* Now we can get the $at and v0 registers back and
+			 * store them */
+			LONG_L		"$8, %[at]\n"
+			LONG_S		"$8, " VAL(PT_R1) "($at)\n"
+			LONG_L		"$8, %[v0]\n"
+			LONG_S		"$8, " VAL(PT_R2) "($at)\n"
+			LONG_L		"$8, %[v1]\n"
+			LONG_S		"$8, " VAL(PT_R3) "($at)\n"
+		:
+		:
+			[at] "m" (at),
+			[v0] "m" (v0),
+			[v1] "m" (v1),
+			[pt_regs] "r" (&my_regs)
+		:	"at", "t0"
+		);
+
+		/* Set the current EPC value to be the current location in this
+		 * function */
+		__asm__ __volatile__ (
+			".set	noat\n"
+		"1:\n"
+			PTR_LA		"$at, 1b\n"
+			LONG_S		"$at, %[cp0_epc]\n"
+		:
+			[cp0_epc] "=m" (my_regs.cp0_epc)
+		:
+		:	"at"
+		);
+
+		my_regs.cp0_cause = read_c0_cause();
+		my_regs.cp0_status = read_c0_status();
+	}
+
+#ifdef CONFIG_DIAGNOSTICS
+	failure_report((char *) cause_string,
+		have_die_regs ? &die_regs : &my_regs);
+	have_die_regs = false;
+#else
+	pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
+		"zzzz... \n");
+#endif
+
+	return NOTIFY_DONE;
+}
+
+/* Information about the RF MAC address, if one was supplied on the
+ * command line. */
+static bool have_rfmac;
+static u8 rfmac[ETH_ALEN];
+
+static int rfmac_param(char *p)
+{
+	u8	*q;
+	bool	is_high_nibble;
+	int	c;
+
+	/* Skip a leading "0x", if present */
+	if (*p == '0' && *(p+1) == 'x')
+		p += 2;
+
+	q = rfmac;
+	is_high_nibble = true;
+
+	for (c = (unsigned char) *p++;
+		isxdigit(c) && q - rfmac < ETH_ALEN;
+		c = (unsigned char) *p++) {
+		int	nibble;
+
+		nibble = (isdigit(c) ? (c - '0') :
+			(isupper(c) ? c - 'A' + 10 : c - 'a' + 10));
+
+		if (is_high_nibble)
+			*q = nibble << 4;
+		else
+			*q++ |= nibble;
+
+		is_high_nibble = !is_high_nibble;
+	}
+
+	/* If we parsed all the way to the end of the parameter value and
+	 * parsed all ETH_ALEN bytes, we have a usable RF MAC address */
+	have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN);
+
+	return 0;
+}
+
+early_param("rfmac", rfmac_param);
+
+/*
+ * Generate an Ethernet MAC address that has a good chance of being unique.
+ * @addr:	Pointer to six-byte array containing the Ethernet address
+ * Generates an Ethernet MAC address that is highly likely to be unique for
+ * this particular system on a network with other systems of the same type.
+ *
+ * The problem we are solving is that, when random_ether_addr() is used to
+ * generate MAC addresses at startup, there isn't much entropy for the random
+ * number generator to use and the addresses it produces are fairly likely to
+ * be the same as those of other identical systems on the same local network.
+ * This is true even for relatively small numbers of systems (for the reason
+ * why, see the Wikipedia entry for "Birthday problem" at:
+ *	http://en.wikipedia.org/wiki/Birthday_problem
+ *
+ * The good news is that we already have a MAC address known to be unique, the
+ * RF MAC address. The bad news is that this address is already in use on the
+ * RF interface. Worse, the obvious trick, taking the RF MAC address and
+ * turning on the locally managed bit, has already been used for other devices.
+ * Still, this does give us something to work with.
+ *
+ * The approach we take is:
+ * 1.	If we can't get the RF MAC Address, just call random_ether_addr.
+ * 2.	Use the 24-bit NIC-specific bits of the RF MAC address as the last 24
+ *	bits of the new address. This is very likely to be unique, except for
+ *	the current box.
+ * 3.	To avoid using addresses already on the current box, we set the top
+ *	six bits of the address with a value different from any currently
+ *	registered Scientific Atlanta organizationally unique identifyer
+ *	(OUI). This avoids duplication with any addresses on the system that
+ *	were generated from valid Scientific Atlanta-registered address by
+ *	simply flipping the locally managed bit.
+ * 4.	We aren't generating a multicast address, so we leave the multicast
+ *	bit off. Since we aren't using a registered address, we have to set
+ *	the locally managed bit.
+ * 5.	We then randomly generate the remaining 16-bits. This does two
+ *	things:
+ *	a.	It allows us to call this function for more than one device
+ *		in this system
+ *	b.	It ensures that things will probably still work even if
+ *		some device on the device network has a locally managed
+ *		address that matches the top six bits from step 2.
+ */
+void platform_random_ether_addr(u8 addr[ETH_ALEN])
+{
+	const int num_random_bytes = 2;
+	const unsigned char non_sciatl_oui_bits = 0xc0u;
+	const unsigned char mac_addr_locally_managed = (1 << 1);
+
+	if (!have_rfmac) {
+		pr_warning("rfmac not available on command line; "
+			"generating random MAC address\n");
+		random_ether_addr(addr);
+	}
+
+	else {
+		int	i;
+
+		/* Set the first byte to something that won't match a Scientific
+		 * Atlanta OUI, is locally managed, and isn't a multicast
+		 * address */
+		addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed;
+
+		/* Get some bytes of random address information */
+		get_random_bytes(&addr[1], num_random_bytes);
+
+		/* Copy over the NIC-specific bits of the RF MAC address */
+		for (i = 1 + num_random_bytes; i < ETH_ALEN; i++)
+			addr[i] = rfmac[i];
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/reset.c linux-libre-2.6.33-gnu1/arch/mips/powertv/reset.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ *  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.
+ */
+#include <linux/pm.h>
+
+#include <linux/io.h>
+#include <asm/reboot.h>			/* Not included by linux/reboot.h */
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "reset.h"
+
+static void mips_machine_restart(char *command)
+{
+#ifdef CONFIG_BOOTLOADER_DRIVER
+	/*
+	 * Call the bootloader's reset function to ensure
+	 * that persistent data is flushed before hard reset
+	 */
+	kbldr_SetCauseAndReset();
+#else
+	writel(0x1, asic_reg_addr(watchdog));
+#endif
+}
+
+void mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/reset.h linux-libre-2.6.33-gnu1/arch/mips/powertv/reset.h
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/reset.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/reset.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+ * Definitions from powertv reset.c file
+ *
+ * Copyright (C) 2009  Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_POWERTV_RESET_H
+#define _POWERTV_POWERTV_RESET_H
+extern void mips_reboot_setup(void);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/powertv/time.c linux-libre-2.6.33-gnu1/arch/mips/powertv/time.c
--- linux-libre-2.6.32-gnu1/arch/mips/powertv/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/powertv/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,36 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ *  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.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/interrupts.h>
+#include <asm/time.h>
+
+#include "powertv-clock.h"
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	return irq_mips_timer;
+}
+
+void __init plat_time_init(void)
+{
+	powertv_clocksource_init();
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/rb532/prom.c linux-libre-2.6.33-gnu1/arch/mips/rb532/prom.c
--- linux-libre-2.6.32-gnu1/arch/mips/rb532/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/rb532/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,7 +69,7 @@ static inline unsigned long tag2ul(char
 
 void __init prom_setup_cmdline(void)
 {
-	static char cmd_line[CL_SIZE] __initdata;
+	static char cmd_line[COMMAND_LINE_SIZE] __initdata;
 	char *cp, *board;
 	int prom_argc;
 	char **prom_argv, **prom_envp;
@@ -115,7 +115,7 @@ void __init prom_setup_cmdline(void)
 		strcpy(cp, arcs_cmdline);
 		cp += strlen(arcs_cmdline);
 	}
-	cmd_line[CL_SIZE-1] = '\0';
+	cmd_line[COMMAND_LINE_SIZE - 1] = '\0';
 
 	strcpy(arcs_cmdline, cmd_line);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-eisa.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-eisa.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-eisa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-eisa.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,9 +50,9 @@
 
 static char __init *decode_eisa_sig(unsigned long addr)
 {
-        static char sig_str[EISA_SIG_LEN];
+	static char sig_str[EISA_SIG_LEN] __initdata;
 	u8 sig[4];
-        u16 rev;
+	u16 rev;
 	int i;
 
 	for (i = 0; i < 4; i++) {
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-int.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-int.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-int.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-int.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/ftrace.h>
 
 #include <asm/irq_cpu.h>
 #include <asm/sgi/hpc3.h>
@@ -150,7 +151,7 @@ static void indy_local1_irqdispatch(void
 
 extern void ip22_be_interrupt(int irq);
 
-static void indy_buserror_irq(void)
+static void __irq_entry indy_buserror_irq(void)
 {
 	int irq = SGI_BUSERR_IRQ;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-setup.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,7 @@ void __init plat_mem_setup(void)
 	cserial = ArcGetEnvironmentVariable("ConsoleOut");
 
 	if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) {
-		static char options[8];
+		static char options[8] __initdata;
 		char *baud = ArcGetEnvironmentVariable("dbaud");
 		if (baud)
 			strcpy(options, baud);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-time.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-time.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip22/ip22-time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip22/ip22-time.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/time.h>
+#include <linux/ftrace.h>
 
 #include <asm/cpu.h>
 #include <asm/mipsregs.h>
@@ -115,7 +116,7 @@ __init void plat_time_init(void)
 }
 
 /* Generic SGI handler for (spurious) 8254 interrupts */
-void indy_8254timer_irq(void)
+void __irq_entry indy_8254timer_irq(void)
 {
 	int irq = SGI_8254_0_IRQ;
 	ULONG cnt;
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip27/ip27-memory.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-memory.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip27/ip27-memory.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip27/ip27-memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -505,5 +505,5 @@ void __init mem_init(void)
 	       (num_physpages - tmp) << (PAGE_SHIFT-10),
 	       datasize >> 10,
 	       initsize >> 10,
-	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+	       totalhigh_pages << (PAGE_SHIFT-10));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sgi-ip32/ip32-setup.c linux-libre-2.6.33-gnu1/arch/mips/sgi-ip32/ip32-setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/sgi-ip32/ip32-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sgi-ip32/ip32-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,7 +90,7 @@ void __init plat_mem_setup(void)
 	{
 		char* con = ArcGetEnvironmentVariable("console");
 		if (con && *con == 'd') {
-			static char options[8];
+			static char options[8] __initdata;
 			char *baud = ArcGetEnvironmentVariable("dbaud");
 			if (baud)
 				strcpy(options, baud);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sibyte/common/cfe.c linux-libre-2.6.33-gnu1/arch/mips/sibyte/common/cfe.c
--- linux-libre-2.6.32-gnu1/arch/mips/sibyte/common/cfe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sibyte/common/cfe.c	2010-02-24 13:52:17.000000000 -0500
@@ -287,7 +287,7 @@ void __init prom_init(void)
 	 * boot console
 	 */
 	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
-	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
+	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, COMMAND_LINE_SIZE) < 0) {
 		if (argc >= 0) {
 			/* The loader should have set the command line */
 			/* too early for panic to do any good */
@@ -318,7 +318,7 @@ void __init prom_init(void)
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 	/* Not sure this is needed, but it's the safe way. */
-	arcs_cmdline[CL_SIZE-1] = 0;
+	arcs_cmdline[COMMAND_LINE_SIZE-1] = 0;
 
 	prom_meminit();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sni/a20r.c linux-libre-2.6.33-gnu1/arch/mips/sni/a20r.c
--- linux-libre-2.6.32-gnu1/arch/mips/sni/a20r.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sni/a20r.c	2010-02-24 13:52:17.000000000 -0500
@@ -188,7 +188,7 @@ static void end_a20r_irq(unsigned int ir
 }
 
 static struct irq_chip a20r_irq_type = {
-	.typename	= "A20R",
+	.name		= "A20R",
 	.ack		= mask_a20r_irq,
 	.mask		= mask_a20r_irq,
 	.mask_ack	= mask_a20r_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sni/pcimt.c linux-libre-2.6.33-gnu1/arch/mips/sni/pcimt.c
--- linux-libre-2.6.32-gnu1/arch/mips/sni/pcimt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sni/pcimt.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,7 @@ static void end_pcimt_irq(unsigned int i
 }
 
 static struct irq_chip pcimt_irq_type = {
-	.typename = "PCIMT",
+	.name = "PCIMT",
 	.ack = disable_pcimt_irq,
 	.mask = disable_pcimt_irq,
 	.mask_ack = disable_pcimt_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sni/pcit.c linux-libre-2.6.33-gnu1/arch/mips/sni/pcit.c
--- linux-libre-2.6.32-gnu1/arch/mips/sni/pcit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sni/pcit.c	2010-02-24 13:52:17.000000000 -0500
@@ -176,7 +176,7 @@ void end_pcit_irq(unsigned int irq)
 }
 
 static struct irq_chip pcit_irq_type = {
-	.typename = "PCIT",
+	.name = "PCIT",
 	.ack = disable_pcit_irq,
 	.mask = disable_pcit_irq,
 	.mask_ack = disable_pcit_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sni/rm200.c linux-libre-2.6.33-gnu1/arch/mips/sni/rm200.c
--- linux-libre-2.6.32-gnu1/arch/mips/sni/rm200.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sni/rm200.c	2010-02-24 13:52:17.000000000 -0500
@@ -404,7 +404,7 @@ void __init sni_rm200_i8259_irqs(void)
 	if (!rm200_pic_master)
 		return;
 	rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
-	if (!rm200_pic_master) {
+	if (!rm200_pic_slave) {
 		iounmap(rm200_pic_master);
 		return;
 	}
@@ -449,7 +449,7 @@ void end_rm200_irq(unsigned int irq)
 }
 
 static struct irq_chip rm200_irq_type = {
-	.typename = "RM200",
+	.name = "RM200",
 	.ack = disable_rm200_irq,
 	.mask = disable_rm200_irq,
 	.mask_ack = disable_rm200_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/sni/setup.c linux-libre-2.6.33-gnu1/arch/mips/sni/setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/sni/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/sni/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,7 +60,7 @@ static void __init sni_console_setup(voi
 	char *cdev;
 	char *baud;
 	int port;
-	static char options[8];
+	static char options[8] __initdata;
 
 	cdev = prom_getenv("console_dev");
 	if (strncmp(cdev, "tty", 3) == 0) {
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/txx9/generic/setup.c linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/setup.c
--- linux-libre-2.6.32-gnu1/arch/mips/txx9/generic/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -160,7 +160,6 @@ static void __init prom_init_cmdline(voi
 	int argc;
 	int *argv32;
 	int i;			/* Always ignore the "-c" at argv[0] */
-	static char builtin[CL_SIZE] __initdata;
 
 	if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
 		/*
@@ -174,20 +173,6 @@ static void __init prom_init_cmdline(voi
 		argv32 = (int *)fw_arg1;
 	}
 
-	/* ignore all built-in args if any f/w args given */
-	/*
-	 * But if built-in strings was started with '+', append them
-	 * to command line args.  If built-in was started with '-',
-	 * ignore all f/w args.
-	 */
-	builtin[0] = '\0';
-	if (arcs_cmdline[0] == '+')
-		strcpy(builtin, arcs_cmdline + 1);
-	else if (arcs_cmdline[0] == '-') {
-		strcpy(builtin, arcs_cmdline + 1);
-		argc = 0;
-	} else if (argc <= 1)
-		strcpy(builtin, arcs_cmdline);
 	arcs_cmdline[0] = '\0';
 
 	for (i = 1; i < argc; i++) {
@@ -201,12 +186,6 @@ static void __init prom_init_cmdline(voi
 		} else
 			strcat(arcs_cmdline, str);
 	}
-	/* append saved builtin args */
-	if (builtin[0]) {
-		if (arcs_cmdline[0])
-			strcat(arcs_cmdline, " ");
-		strcat(arcs_cmdline, builtin);
-	}
 }
 
 static int txx9_ic_disable __initdata;
@@ -315,7 +294,7 @@ static inline void txx9_cache_fixup(void
 
 static void __init preprocess_cmdline(void)
 {
-	static char cmdline[CL_SIZE] __initdata;
+	static char cmdline[COMMAND_LINE_SIZE] __initdata;
 	char *s;
 
 	strcpy(cmdline, arcs_cmdline);
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/txx9/generic/smsc_fdc37m81x.c linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/smsc_fdc37m81x.c
--- linux-libre-2.6.32-gnu1/arch/mips/txx9/generic/smsc_fdc37m81x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/txx9/generic/smsc_fdc37m81x.c	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,7 @@ unsigned long __init smsc_fdc37m81x_init
 	if (chip_id == SMSC_FDC37M81X_CHIP_ID)
 		smsc_fdc37m81x_config_end();
 	else {
-		printk(KERN_WARNING "%s: unknow chip id 0x%02x\n", __func__,
+		printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__,
 		       chip_id);
 		g_smsc_fdc37m81x_base = 0;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/vr41xx/common/icu.c linux-libre-2.6.33-gnu1/arch/mips/vr41xx/common/icu.c
--- linux-libre-2.6.32-gnu1/arch/mips/vr41xx/common/icu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/vr41xx/common/icu.c	2010-02-24 13:52:17.000000000 -0500
@@ -159,9 +159,9 @@ void vr41xx_enable_piuint(uint16_t mask)
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_set(MPIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -174,9 +174,9 @@ void vr41xx_disable_piuint(uint16_t mask
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_clear(MPIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -189,9 +189,9 @@ void vr41xx_enable_aiuint(uint16_t mask)
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_set(MAIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -204,9 +204,9 @@ void vr41xx_disable_aiuint(uint16_t mask
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_clear(MAIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -219,9 +219,9 @@ void vr41xx_enable_kiuint(uint16_t mask)
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_set(MKIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -234,9 +234,9 @@ void vr41xx_disable_kiuint(uint16_t mask
 
 	if (current_cpu_type() == CPU_VR4111 ||
 	    current_cpu_type() == CPU_VR4121) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu1_clear(MKIUINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -247,9 +247,9 @@ void vr41xx_enable_macint(uint16_t mask)
 	struct irq_desc *desc = irq_desc + ETHERNET_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu1_set(MMACINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_enable_macint);
@@ -259,9 +259,9 @@ void vr41xx_disable_macint(uint16_t mask
 	struct irq_desc *desc = irq_desc + ETHERNET_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu1_clear(MMACINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_disable_macint);
@@ -271,9 +271,9 @@ void vr41xx_enable_dsiuint(uint16_t mask
 	struct irq_desc *desc = irq_desc + DSIU_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu1_set(MDSIUINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_enable_dsiuint);
@@ -283,9 +283,9 @@ void vr41xx_disable_dsiuint(uint16_t mas
 	struct irq_desc *desc = irq_desc + DSIU_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu1_clear(MDSIUINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_disable_dsiuint);
@@ -295,9 +295,9 @@ void vr41xx_enable_firint(uint16_t mask)
 	struct irq_desc *desc = irq_desc + FIR_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu2_set(MFIRINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_enable_firint);
@@ -307,9 +307,9 @@ void vr41xx_disable_firint(uint16_t mask
 	struct irq_desc *desc = irq_desc + FIR_IRQ;
 	unsigned long flags;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	icu2_clear(MFIRINTREG, mask);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 EXPORT_SYMBOL(vr41xx_disable_firint);
@@ -322,9 +322,9 @@ void vr41xx_enable_pciint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MPCIINTREG, PCIINT0);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -338,9 +338,9 @@ void vr41xx_disable_pciint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MPCIINTREG, 0);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -354,9 +354,9 @@ void vr41xx_enable_scuint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MSCUINTREG, SCUINT0);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -370,9 +370,9 @@ void vr41xx_disable_scuint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MSCUINTREG, 0);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -386,9 +386,9 @@ void vr41xx_enable_csiint(uint16_t mask)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_set(MCSIINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -402,9 +402,9 @@ void vr41xx_disable_csiint(uint16_t mask
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_clear(MCSIINTREG, mask);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -418,9 +418,9 @@ void vr41xx_enable_bcuint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MBCUINTREG, BCUINTR);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -434,9 +434,9 @@ void vr41xx_disable_bcuint(void)
 	if (current_cpu_type() == CPU_VR4122 ||
 	    current_cpu_type() == CPU_VR4131 ||
 	    current_cpu_type() == CPU_VR4133) {
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 		icu2_write(MBCUINTREG, 0);
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 
@@ -486,7 +486,7 @@ static inline int set_sysint1_assign(uns
 
 	pin = SYSINT1_IRQ_TO_PIN(irq);
 
-	spin_lock_irq(&desc->lock);
+	raw_spin_lock_irq(&desc->lock);
 
 	intassign0 = icu1_read(INTASSIGN0);
 	intassign1 = icu1_read(INTASSIGN1);
@@ -525,7 +525,7 @@ static inline int set_sysint1_assign(uns
 		intassign1 |= (uint16_t)assign << 9;
 		break;
 	default:
-		spin_unlock_irq(&desc->lock);
+		raw_spin_unlock_irq(&desc->lock);
 		return -EINVAL;
 	}
 
@@ -533,7 +533,7 @@ static inline int set_sysint1_assign(uns
 	icu1_write(INTASSIGN0, intassign0);
 	icu1_write(INTASSIGN1, intassign1);
 
-	spin_unlock_irq(&desc->lock);
+	raw_spin_unlock_irq(&desc->lock);
 
 	return 0;
 }
@@ -546,7 +546,7 @@ static inline int set_sysint2_assign(uns
 
 	pin = SYSINT2_IRQ_TO_PIN(irq);
 
-	spin_lock_irq(&desc->lock);
+	raw_spin_lock_irq(&desc->lock);
 
 	intassign2 = icu1_read(INTASSIGN2);
 	intassign3 = icu1_read(INTASSIGN3);
@@ -593,7 +593,7 @@ static inline int set_sysint2_assign(uns
 		intassign3 |= (uint16_t)assign << 12;
 		break;
 	default:
-		spin_unlock_irq(&desc->lock);
+		raw_spin_unlock_irq(&desc->lock);
 		return -EINVAL;
 	}
 
@@ -601,7 +601,7 @@ static inline int set_sysint2_assign(uns
 	icu1_write(INTASSIGN2, intassign2);
 	icu1_write(INTASSIGN3, intassign3);
 
-	spin_unlock_irq(&desc->lock);
+	raw_spin_unlock_irq(&desc->lock);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mips/vr41xx/common/init.c linux-libre-2.6.33-gnu1/arch/mips/vr41xx/common/init.c
--- linux-libre-2.6.32-gnu1/arch/mips/vr41xx/common/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mips/vr41xx/common/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  *  init.c, Common initialization routines for NEC VR4100 series.
  *
- *  Copyright (C) 2003-2008  Yoichi Yuasa <yuasa@linux-mips.org>
+ *  Copyright (C) 2003-2009  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
@@ -66,9 +66,9 @@ void __init prom_init(void)
 	argv = (char **)fw_arg1;
 
 	for (i = 1; i < argc; i++) {
-		strcat(arcs_cmdline, argv[i]);
+		strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
 		if (i < (argc - 1))
-			strcat(arcs_cmdline, " ");
+			strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/configs/asb2303_defconfig linux-libre-2.6.33-gnu1/arch/mn10300/configs/asb2303_defconfig
--- linux-libre-2.6.32-gnu1/arch/mn10300/configs/asb2303_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/configs/asb2303_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 11:13:22 2009
+# Linux kernel version: 2.6.33-rc1
+# Tue Dec 22 19:26:25 2009
 #
 CONFIG_MN10300=y
 CONFIG_AM33=y
@@ -22,6 +22,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HOTPLUG_CPU is not set
 CONFIG_HZ=1000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -43,11 +44,10 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
 # CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -62,7 +62,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
-CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -75,14 +74,22 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -90,6 +97,35 @@ CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -145,9 +181,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
 #
 # Power management options
@@ -202,6 +237,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -216,6 +252,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,7 +378,6 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -362,14 +398,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -430,11 +463,15 @@ CONFIG_RTC=y
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -451,22 +488,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -490,11 +512,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
 # File systems
 #
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -539,6 +567,7 @@ CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
@@ -561,13 +590,13 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_SAMPLES is not set
 
@@ -577,7 +606,11 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/bitops.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/bitops.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/bitops.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
@@ -165,7 +165,7 @@ static inline __attribute__((const))
 unsigned long __ffs(unsigned long x)
 {
 	int bit;
-	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x));
+	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x) : "cc");
 	return bit;
 }
 
@@ -177,7 +177,7 @@ static inline __attribute__((const))
 int __ilog2_u32(u32 n)
 {
 	int bit;
-	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n));
+	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n) : "cc");
 	return bit;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #define flush_cache_page(vma, vmaddr, pfn)	do {} while (0)
 #define flush_cache_vmap(start, end)		do {} while (0)
 #define flush_cache_vunmap(start, end)		do {} while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do {} while (0)
 #define flush_dcache_mmap_lock(mapping)		do {} while (0)
 #define flush_dcache_mmap_unlock(mapping)	do {} while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/div64.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/div64.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/div64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/div64.h	2010-02-24 13:52:17.000000000 -0500
@@ -72,6 +72,7 @@ unsigned __muldiv64u(unsigned val, unsig
 					 * MDR = MDR:val%div */
 	    : "=r"(result)
 	    : "0"(val), "ir"(mult), "r"(div)
+	    : "cc"
 	    );
 
 	return result;
@@ -92,6 +93,7 @@ signed __muldiv64s(signed val, signed mu
 					 * MDR = MDR:val%div */
 	    : "=r"(result)
 	    : "0"(val), "ir"(mult), "r"(div)
+	    : "cc"
 	    );
 
 	return result;
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,6 @@ do {									\
 	_ur->a1   = 0;	_ur->a0   = 0;	_ur->d1   = 0;	_ur->d0   = 0;	\
 } while (0)
 
-#define USE_ELF_CORE_DUMP
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	4096
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/mman.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/mman.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/mman.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/mman.h	2010-02-24 13:52:17.000000000 -0500
@@ -1 +1,6 @@
 #include <asm-generic/mman.h>
+
+#define MIN_MAP_ADDR	PAGE_SIZE	/* minimum fixed mmap address */
+
+#define arch_mmap_check(addr, len, flags) \
+	(((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0)
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,4 +60,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/system.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/system.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -143,6 +143,7 @@ do {									\
 		"	mov	%0,epsw		\n"			\
 		: "=&d"(tmp)						\
 		: "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw)	\
+		: "cc"							\
 		);							\
 } while (0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/tlbflush.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/tlbflush.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/tlbflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/tlbflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,7 @@ do {								\
 		 "	mov %0,%1		\n"		\
 		 : "=d"(w)					\
 		 : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV)	\
-		 : "memory"					\
+		 : "cc", "memory"				\
 		 );						\
 } while (0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/uaccess.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/uaccess.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/uaccess.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
@@ -316,7 +316,7 @@ do {									\
 			"	.previous\n"				\
 			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
 			: "0"(__from), "1"(__to), "2"(size)		\
-			: "memory");					\
+			: "cc", "memory");				\
 	}								\
 } while (0)
 
@@ -352,7 +352,7 @@ do {									\
 			"	.previous\n"				\
 			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
 			: "0"(__from), "1"(__to), "2"(size)		\
-			: "memory");					\
+			: "cc", "memory");				\
 	}								\
 } while (0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -348,10 +348,11 @@
 #define __NR_pwritev		335
 #define __NR_rt_tgsigqueueinfo	336
 #define __NR_perf_event_open	337
+#define __NR_recvmmsg		338
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 338
+#define NR_syscalls 339
 
 /*
  * specify the deprecated syscalls we want to support on this arch
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/entry.S linux-libre-2.6.33-gnu1/arch/mn10300/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -578,7 +578,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall	/* reserved for streams2 */
 	.long sys_vfork		/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
@@ -724,6 +724,7 @@ ENTRY(sys_call_table)
 	.long sys_pwritev		/* 335 */
 	.long sys_rt_tgsigqueueinfo
 	.long sys_perf_event_open
+	.long sys_recvmmsg
 
 
 nr_syscalls=(.-sys_call_table)/4
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/irq.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -215,7 +215,7 @@ int show_interrupts(struct seq_file *p,
 
 		/* display information rows, one per active CPU */
 	case 1 ... NR_IRQS - 1:
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 
 		action = irq_desc[i].action;
 		if (action) {
@@ -235,7 +235,7 @@ int show_interrupts(struct seq_file *p,
 			seq_putc(p, '\n');
 		}
 
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 		break;
 
 		/* polish off with NMI and error counters */
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/kprobes.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/kprobes.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/kprobes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,13 +31,13 @@ const int kretprobe_blacklist_size = ARR
 #define KPROBE_HIT_ACTIVE	0x00000001
 #define KPROBE_HIT_SS		0x00000002
 
-static struct kprobe *current_kprobe;
-static unsigned long current_kprobe_orig_pc;
-static unsigned long current_kprobe_next_pc;
-static int current_kprobe_ss_flags;
+static struct kprobe *cur_kprobe;
+static unsigned long cur_kprobe_orig_pc;
+static unsigned long cur_kprobe_next_pc;
+static int cur_kprobe_ss_flags;
 static unsigned long kprobe_status;
-static kprobe_opcode_t current_kprobe_ss_buf[MAX_INSN_SIZE + 2];
-static unsigned long current_kprobe_bp_addr;
+static kprobe_opcode_t cur_kprobe_ss_buf[MAX_INSN_SIZE + 2];
+static unsigned long cur_kprobe_bp_addr;
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 
@@ -399,26 +399,25 @@ void __kprobes prepare_singlestep(struct
 {
 	unsigned long nextpc;
 
-	current_kprobe_orig_pc = regs->pc;
-	memcpy(current_kprobe_ss_buf, &p->ainsn.insn[0], MAX_INSN_SIZE);
-	regs->pc = (unsigned long) current_kprobe_ss_buf;
+	cur_kprobe_orig_pc = regs->pc;
+	memcpy(cur_kprobe_ss_buf, &p->ainsn.insn[0], MAX_INSN_SIZE);
+	regs->pc = (unsigned long) cur_kprobe_ss_buf;
 
-	nextpc = find_nextpc(regs, &current_kprobe_ss_flags);
-	if (current_kprobe_ss_flags & SINGLESTEP_PCREL)
-		current_kprobe_next_pc =
-			current_kprobe_orig_pc + (nextpc - regs->pc);
+	nextpc = find_nextpc(regs, &cur_kprobe_ss_flags);
+	if (cur_kprobe_ss_flags & SINGLESTEP_PCREL)
+		cur_kprobe_next_pc = cur_kprobe_orig_pc + (nextpc - regs->pc);
 	else
-		current_kprobe_next_pc = nextpc;
+		cur_kprobe_next_pc = nextpc;
 
 	/* branching instructions need special handling */
-	if (current_kprobe_ss_flags & SINGLESTEP_BRANCH)
+	if (cur_kprobe_ss_flags & SINGLESTEP_BRANCH)
 		nextpc = singlestep_branch_setup(regs);
 
-	current_kprobe_bp_addr = nextpc;
+	cur_kprobe_bp_addr = nextpc;
 
 	*(u8 *) nextpc = BREAKPOINT_INSTRUCTION;
-	mn10300_dcache_flush_range2((unsigned) current_kprobe_ss_buf,
-				    sizeof(current_kprobe_ss_buf));
+	mn10300_dcache_flush_range2((unsigned) cur_kprobe_ss_buf,
+				    sizeof(cur_kprobe_ss_buf));
 	mn10300_icache_inv();
 }
 
@@ -440,7 +439,7 @@ static inline int __kprobes kprobe_handl
 			disarm_kprobe(p, regs);
 			ret = 1;
 		} else {
-			p = current_kprobe;
+			p = cur_kprobe;
 			if (p->break_handler && p->break_handler(p, regs))
 				goto ss_probe;
 		}
@@ -464,7 +463,7 @@ static inline int __kprobes kprobe_handl
 	}
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
+	cur_kprobe = p;
 	if (p->pre_handler(p, regs)) {
 		/* handler has already set things up, so skip ss setup */
 		return 1;
@@ -491,8 +490,8 @@ no_kprobe:
 static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	/* we may need to fixup regs/stack after singlestepping a call insn */
-	if (current_kprobe_ss_flags & SINGLESTEP_BRANCH) {
-		regs->pc = current_kprobe_orig_pc;
+	if (cur_kprobe_ss_flags & SINGLESTEP_BRANCH) {
+		regs->pc = cur_kprobe_orig_pc;
 		switch (p->ainsn.insn[0]) {
 		case 0xcd:	/* CALL (d16,PC) */
 			*(unsigned *) regs->sp = regs->mdr = regs->pc + 5;
@@ -523,8 +522,8 @@ static void __kprobes resume_execution(s
 		}
 	}
 
-	regs->pc = current_kprobe_next_pc;
-	current_kprobe_bp_addr = 0;
+	regs->pc = cur_kprobe_next_pc;
+	cur_kprobe_bp_addr = 0;
 }
 
 static inline int __kprobes post_kprobe_handler(struct pt_regs *regs)
@@ -532,10 +531,10 @@ static inline int __kprobes post_kprobe_
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if (cur_kprobe->post_handler)
+		cur_kprobe->post_handler(cur_kprobe, regs, 0);
 
-	resume_execution(current_kprobe, regs);
+	resume_execution(cur_kprobe, regs);
 	reset_current_kprobe();
 	preempt_enable_no_resched();
 	return 1;
@@ -545,12 +544,12 @@ static inline int __kprobes post_kprobe_
 static inline
 int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (current_kprobe->fault_handler &&
-	    current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	if (cur_kprobe->fault_handler &&
+	    cur_kprobe->fault_handler(cur_kprobe, regs, trapnr))
 		return 1;
 
 	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
+		resume_execution(cur_kprobe, regs);
 		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
@@ -567,7 +566,7 @@ int __kprobes kprobe_exceptions_notify(s
 
 	switch (val) {
 	case DIE_BREAKPOINT:
-		if (current_kprobe_bp_addr != args->regs->pc) {
+		if (cur_kprobe_bp_addr != args->regs->pc) {
 			if (kprobe_handler(args->regs))
 				return NOTIFY_STOP;
 		} else {
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/mn10300-serial.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/mn10300-serial.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/mn10300-serial.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/mn10300-serial.c	2010-02-24 13:52:17.000000000 -0500
@@ -380,7 +380,8 @@ static int mask_test_and_clear(volatile
 	u32 epsw;
 	asm volatile("	bclr	%1,(%2)		\n"
 		     "	mov	epsw,%0		\n"
-		     : "=d"(epsw) : "d"(mask), "a"(ptr));
+		     : "=d"(epsw) : "d"(mask), "a"(ptr)
+		     : "cc", "memory");
 	return !(epsw & EPSW_FLAG_Z);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/process.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -275,16 +275,12 @@ asmlinkage long sys_execve(char __user *
 	char *filename;
 	int error;
 
-	lock_kernel();
-
 	filename = getname(name);
 	error = PTR_ERR(filename);
-	if (!IS_ERR(filename)) {
-		error = do_execve(filename, argv, envp, __frame);
-		putname(filename);
-	}
-
-	unlock_kernel();
+	if (IS_ERR(filename))
+		return error;
+	error = do_execve(filename, argv, envp, __frame);
+	putname(filename);
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/signal.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -264,7 +264,7 @@ static inline void __user *get_sigframe(
 
 	/* this is the X/Open sanctioned signal stack switching.  */
 	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (!on_sig_stack(sp))
+		if (sas_ss_flags(sp) == 0)
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/kernel/sys_mn10300.c linux-libre-2.6.33-gnu1/arch/mn10300/kernel/sys_mn10300.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/kernel/sys_mn10300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/kernel/sys_mn10300.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,47 +23,13 @@
 
 #include <asm/uaccess.h>
 
-#define MIN_MAP_ADDR	PAGE_SIZE	/* minimum fixed mmap address */
-
-/*
- * memory mapping syscall
- */
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	struct file *file = NULL;
-	long error = -EINVAL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
-		goto out;
-
-	error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long old_mmap(unsigned long addr, unsigned long len,
 			 unsigned long prot, unsigned long flags,
 			 unsigned long fd, unsigned long offset)
 {
 	if (offset & ~PAGE_MASK)
 		return -EINVAL;
-	return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
 struct sel_arg_struct {
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/lib/checksum.c linux-libre-2.6.33-gnu1/arch/mn10300/lib/checksum.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/lib/checksum.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/lib/checksum.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@ static inline unsigned short from32to16(
 	    "	addc	0xffff,%0	\n"
 	    : "=r" (sum)
 	    : "r" (sum << 16), "0" (sum & 0xffff0000)
+	    : "cc"
 	    );
 	return sum >> 16;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/lib/delay.c linux-libre-2.6.33-gnu1/arch/mn10300/lib/delay.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/lib/delay.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/lib/delay.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,8 @@ void __delay(unsigned long loops)
 		"2:	add	-1,%0	\n"
 		"	bne	2b	\n"
 		: "=&d" (d0)
-		: "0" (loops));
+		: "0" (loops)
+		: "cc");
 }
 EXPORT_SYMBOL(__delay);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/lib/usercopy.c linux-libre-2.6.33-gnu1/arch/mn10300/lib/usercopy.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/lib/usercopy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/lib/usercopy.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,7 +62,7 @@ do {								\
 		"	.previous"				\
 		:"=&r"(res), "=r"(count), "=&r"(w)		\
 		:"i"(-EFAULT), "1"(count), "a"(src), "a"(dst)	\
-		:"memory");					\
+		: "memory", "cc");					\
 } while (0)
 
 long
@@ -109,7 +109,7 @@ do {						\
 		".previous\n"			\
 		: "+r"(size), "=&r"(w)		\
 		: "a"(addr), "d"(0)		\
-		: "memory");			\
+		: "memory", "cc");		\
 } while (0)
 
 unsigned long
@@ -161,6 +161,6 @@ long strnlen_user(const char *s, long n)
 		".previous\n"
 		:"=d"(res), "=&r"(w)
 		:"0"(0), "a"(s), "r"(n)
-		:"memory");
+		: "memory", "cc");
 	return res;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/Makefile linux-libre-2.6.33-gnu1/arch/mn10300/Makefile
--- linux-libre-2.6.32-gnu1/arch/mn10300/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@ CCDIR	:= $(strip $(patsubst %/specs,%,$(
 KBUILD_CPPFLAGS += -nostdinc -I$(CCDIR)/include
 
 LDFLAGS		:=
-OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
+OBJCOPYFLAGS	:= -O binary -R .note -R .comment -R .GCC-command-line -R .note.gnu.build-id -S
 #LDFLAGS_vmlinux := -Map linkmap.txt
 CHECKFLAGS	+=
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/mm/dma-alloc.c linux-libre-2.6.33-gnu1/arch/mn10300/mm/dma-alloc.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/mm/dma-alloc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/mm/dma-alloc.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,12 +16,24 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 
+static unsigned long pci_sram_allocated = 0xbc000000;
+
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, int gfp)
 {
 	unsigned long addr;
 	void *ret;
 
+	printk("dma_alloc_coherent(%s,%zu,,%x)\n", dev_name(dev), size, gfp);
+
+	if (0xbe000000 - pci_sram_allocated >= size) {
+		size = (size + 255) & ~255;
+		addr = pci_sram_allocated;
+		pci_sram_allocated += size;
+		ret = (void *) addr;
+		goto done;
+	}
+
 	/* ignore region specifiers */
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
@@ -41,7 +53,9 @@ void *dma_alloc_coherent(struct device *
 	/* write back and evict all cache lines covering this region */
 	mn10300_dcache_flush_inv_range2(virt_to_phys((void *) addr), PAGE_SIZE);
 
+done:
 	*dma_handle = virt_to_bus((void *) addr);
+	printk("dma_alloc_coherent() = %p [%x]\n", ret, *dma_handle);
 	return ret;
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
@@ -51,6 +65,9 @@ void dma_free_coherent(struct device *de
 {
 	unsigned long addr = (unsigned long) vaddr & ~0x20000000;
 
+	if (addr >= 0x9c000000)
+		return;
+
 	free_pages(addr, get_order(size));
 }
 EXPORT_SYMBOL(dma_free_coherent);
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/mm/init.c linux-libre-2.6.33-gnu1/arch/mn10300/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,8 +118,7 @@ void __init mem_init(void)
 	       reservedpages << (PAGE_SHIFT - 10),
 	       datasize >> 10,
 	       initsize >> 10,
-	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT - 10))
-	       );
+	       totalhigh_pages << (PAGE_SHIFT - 10));
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/mm/misalignment.c linux-libre-2.6.33-gnu1/arch/mn10300/mm/misalignment.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/mm/misalignment.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/mm/misalignment.c	2010-02-24 13:52:17.000000000 -0500
@@ -633,13 +633,13 @@ static int misalignment_addr(unsigned lo
 			goto displace_or_inc;
 		case SD24:
 			tmp = disp << 8;
-			asm("asr 8,%0" : "=r"(tmp) : "0"(tmp));
+			asm("asr 8,%0" : "=r"(tmp) : "0"(tmp) : "cc");
 			disp = (long) tmp;
 			goto displace_or_inc;
 		case SIMM4_2:
 			tmp = opcode >> 4 & 0x0f;
 			tmp <<= 28;
-			asm("asr 28,%0" : "=r"(tmp) : "0"(tmp));
+			asm("asr 28,%0" : "=r"(tmp) : "0"(tmp) : "cc");
 			disp = (long) tmp;
 			goto displace_or_inc;
 		case IMM8:
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,7 +11,7 @@
 #ifndef _ASM_UNIT_SERIAL_H
 #define _ASM_UNIT_SERIAL_H
 
-#include <asm/cpu/cpu-regs.h>
+#include <asm/cpu-regs.h>
 #include <proc/irq.h>
 #include <linux/serial_reg.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
 #include <linux/irq.h>
 #endif /* __ASSEMBLY__ */
 
-#include <asm/cpu/timer-regs.h>
+#include <asm/timer-regs.h>
 #include <unit/clock.h>
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/leds.c linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/leds.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,8 +13,8 @@
 #include <linux/init.h>
 #include <asm/io.h>
 #include <asm/processor.h>
-#include <asm/cpu/intctl-regs.h>
-#include <asm/cpu/rtc-regs.h>
+#include <asm/intctl-regs.h>
+#include <asm/rtc-regs.h>
 #include <unit/leds.h>
 
 static const u8 asb2305_led_hex_tbl[16] = {
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.c	2010-02-24 13:52:17.000000000 -0500
@@ -218,45 +218,6 @@ void __init pcibios_resource_survey(void
 	pcibios_allocate_resources(1);
 }
 
-int pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-
-	for (idx = 0; idx < 6; idx++) {
-		/* Only set up the requested stuff */
-		if (!(mask & (1 << idx)))
-			continue;
-
-		r = &dev->resource[idx];
-
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because of"
-			       " resource collisions\n",
-			       pci_name(dev));
-			return -EINVAL;
-		}
-
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-
-	if (cmd != old_cmd)
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-
-	return 0;
-}
-
 /*
  *  If we set up a device for bus mastering, we need to check the latency
  *  timer as certain crappy BIOSes forget to set it properly.
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.h linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.h
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci-asb2305.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,6 @@ extern unsigned int pci_probe;
 extern unsigned int pcibios_max_latency;
 
 extern void pcibios_resource_survey(void);
-extern int pcibios_enable_resources(struct pci_dev *dev, int mask);
 
 /* pci.c */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci.c linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,29 @@ struct pci_bus *pci_root_bus;
 struct pci_ops *pci_root_ops;
 
 /*
+ * The accessible PCI window does not cover the entire CPU address space, but
+ * there are devices we want to access outside of that window, so we need to
+ * insert specific PCI bus resources instead of using the platform-level bus
+ * resources directly for the PCI root bus.
+ *
+ * These are configured and inserted by pcibios_init() and are attached to the
+ * root bus by pcibios_fixup_bus().
+ */
+static struct resource pci_ioport_resource = {
+	.name	= "PCI IO",
+	.start	= 0xbe000000,
+	.end	= 0xbe03ffff,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pci_iomem_resource = {
+	.name	= "PCI mem",
+	.start	= 0xb8000000,
+	.end	= 0xbbffffff,
+	.flags	= IORESOURCE_MEM,
+};
+
+/*
  * Functions for accessing PCI configuration space
  */
 
@@ -279,7 +302,7 @@ static int __init pci_sanity_check(struc
 	     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
 		return 1;
 
-	printk(KERN_ERROR "PCI: Sanity check failed\n");
+	printk(KERN_ERR "PCI: Sanity check failed\n");
 	return 0;
 }
 
@@ -297,6 +320,7 @@ static int __init pci_check_direct(void)
 		printk(KERN_INFO "PCI: Using configuration ampci\n");
 		request_mem_region(0xBE040000, 256, "AMPCI bridge");
 		request_mem_region(0xBFFFFFF4, 12, "PCI ampci");
+		request_mem_region(0xBC000000, 32 * 1024 * 1024, "PCI SRAM");
 		return 0;
 	}
 
@@ -358,6 +382,11 @@ void __devinit pcibios_fixup_bus(struct
 {
 	struct pci_dev *dev;
 
+	if (bus->number == 0) {
+		bus->resource[0] = &pci_ioport_resource;
+		bus->resource[1] = &pci_iomem_resource;
+	}
+
 	if (bus->self) {
 		pci_read_bridge_bases(bus);
 		pcibios_fixup_device_resources(bus->self);
@@ -380,6 +409,11 @@ static int __init pcibios_init(void)
 	iomem_resource.start	= 0xA0000000;
 	iomem_resource.end	= 0xDFFFFFFF;
 
+	if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
+		panic("Unable to insert PCI IOMEM resource\n");
+	if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
+		panic("Unable to insert PCI IOPORT resource\n");
+
 	if (!pci_probe)
 		return 0;
 
@@ -391,32 +425,11 @@ static int __init pcibios_init(void)
 	printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
 	       MEM_PAGING_REG);
 
-	{
-#if 0
-		static struct pci_bus am33_root_bus = {
-			.children  = LIST_HEAD_INIT(am33_root_bus.children),
-			.devices   = LIST_HEAD_INIT(am33_root_bus.devices),
-			.number    = 0,
-			.secondary = 0,
-			.resource = { &ioport_resource, &iomem_resource },
-		};
-
-		am33_root_bus.ops = pci_root_ops;
-		list_add_tail(&am33_root_bus.node, &pci_root_buses);
-
-		am33_root_bus.subordinate = pci_do_scan_bus(0);
-
-		pci_root_bus = &am33_root_bus;
-#else
-		pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL);
-#endif
-	}
+	pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL);
 
 	pcibios_irq_init();
 	pcibios_fixup_irqs();
-#if 0
 	pcibios_resource_survey();
-#endif
 	return 0;
 }
 
@@ -440,7 +453,7 @@ int pcibios_enable_device(struct pci_dev
 {
 	int err;
 
-	err = pcibios_enable_resources(dev, mask);
+	err = pci_enable_resources(dev, mask);
 	if (err == 0)
 		pcibios_enable_irq(dev);
 	return err;
@@ -455,6 +468,7 @@ static void __init unit_disable_pcnet(st
 
 	bus->number = 0;
 
+	o->read (bus, PCI_DEVFN(2, 0), PCI_VENDOR_ID,		4, &x);
 	o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND,		2, &x);
 	x |= PCI_COMMAND_MASTER |
 		PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
diff -druNp linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/unit-init.c linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/unit-init.c
--- linux-libre-2.6.32-gnu1/arch/mn10300/unit-asb2305/unit-init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/mn10300/unit-asb2305/unit-init.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,8 @@
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/processor.h>
-#include <asm/cpu/intctl-regs.h>
-#include <asm/cpu/rtc-regs.h>
-#include <asm/cpu/serial-regs.h>
+#include <asm/intctl-regs.h>
+#include <asm/serial-regs.h>
 #include <unit/serial.h>
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/hpux/sys_hpux.c linux-libre-2.6.33-gnu1/arch/parisc/hpux/sys_hpux.c
--- linux-libre-2.6.32-gnu1/arch/parisc/hpux/sys_hpux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/hpux/sys_hpux.c	2010-02-24 13:52:17.000000000 -0500
@@ -445,12 +445,7 @@ done:
 
 int hpux_pipe(int *kstack_fildes)
 {
-	int error;
-
-	lock_kernel();
-	error = do_pipe_flags(kstack_fildes, 0);
-	unlock_kernel();
-	return error;
+	return do_pipe_flags(kstack_fildes, 0);
 }
 
 /* lies - says it works, but it really didn't lock anything */
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/atomic.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/atomic.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/atomic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,19 +27,19 @@
 #  define ATOMIC_HASH_SIZE 4
 #  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
 
-extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
+extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
 
 /* Can't use raw_spin_lock_irq because of #include problems, so
  * this is the substitute */
 #define _atomic_spin_lock_irqsave(l,f) do {	\
-	raw_spinlock_t *s = ATOMIC_HASH(l);		\
+	arch_spinlock_t *s = ATOMIC_HASH(l);		\
 	local_irq_save(f);			\
-	__raw_spin_lock(s);			\
+	arch_spin_lock(s);			\
 } while(0)
 
 #define _atomic_spin_unlock_irqrestore(l,f) do {	\
-	raw_spinlock_t *s = ATOMIC_HASH(l);			\
-	__raw_spin_unlock(s);				\
+	arch_spinlock_t *s = ATOMIC_HASH(l);			\
+	arch_spin_unlock(s);				\
 	local_irq_restore(f);				\
 } while(0)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,14 +32,14 @@
 			     "\t.popsection"				\
 			     : : "i" (__FILE__), "i" (__LINE__),	\
 			     "i" (0), "i" (sizeof(struct bug_entry)) ); \
-		for(;;) ;						\
+		unreachable();						\
 	} while(0)
 
 #else
 #define BUG()								\
 	do {								\
 		asm volatile(PARISC_BUG_BREAK_ASM : : );		\
-		for(;;) ;						\
+		unreachable();						\
 	} while(0)
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@ void flush_cache_mm(struct mm_struct *mm
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
 
 #define flush_dcache_mmap_lock(mapping) \
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -328,7 +328,6 @@ struct pt_regs;	/* forward declaration..
    such function.  */
 #define ELF_PLAT_INIT(_r, load_addr)       _r->gr[23] = 0
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/fcntl.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/fcntl.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/fcntl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/fcntl.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,13 @@
 #ifndef _PARISC_FCNTL_H
 #define _PARISC_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_APPEND	000000010
 #define O_BLKSEEK	000000100 /* HPUX only */
 #define O_CREAT		000000400 /* not fcntl */
 #define O_EXCL		000002000 /* not fcntl */
 #define O_LARGEFILE	000004000
-#define O_SYNC		000100000
+#define __O_SYNC	000100000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 #define O_NONBLOCK	000200004 /* HPUX has separate NDELAY & NONBLOCK */
 #define O_NOCTTY	000400000 /* not fcntl */
 #define O_DSYNC		001000000 /* HPUX only */
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/ftrace.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/ftrace.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/ftrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,20 @@ struct ftrace_ret_stack {
  * Defined in entry.S
  */
 extern void return_to_handler(void);
+
+
+extern unsigned long return_address(unsigned int);
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 return_address(1)
+#define CALLER_ADDR2 return_address(2)
+#define CALLER_ADDR3 return_address(3)
+#define CALLER_ADDR4 return_address(4)
+#define CALLER_ADDR5 return_address(5)
+#define CALLER_ADDR6 return_address(6)
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_PARISC_FTRACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,8 @@
 #define SO_TIMESTAMPING		0x4020
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_RXQ_OVFL             0x4021
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,17 +5,17 @@
 #include <asm/processor.h>
 #include <asm/spinlock_types.h>
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *x)
+static inline int arch_spin_is_locked(arch_spinlock_t *x)
 {
 	volatile unsigned int *a = __ldcw_align(x);
 	return *a == 0;
 }
 
-#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0)
-#define __raw_spin_unlock_wait(x) \
-		do { cpu_relax(); } while (__raw_spin_is_locked(x))
+#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0)
+#define arch_spin_unlock_wait(x) \
+		do { cpu_relax(); } while (arch_spin_is_locked(x))
 
-static inline void __raw_spin_lock_flags(raw_spinlock_t *x,
+static inline void arch_spin_lock_flags(arch_spinlock_t *x,
 					 unsigned long flags)
 {
 	volatile unsigned int *a;
@@ -33,7 +33,7 @@ static inline void __raw_spin_lock_flags
 	mb();
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *x)
+static inline void arch_spin_unlock(arch_spinlock_t *x)
 {
 	volatile unsigned int *a;
 	mb();
@@ -42,7 +42,7 @@ static inline void __raw_spin_unlock(raw
 	mb();
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *x)
+static inline int arch_spin_trylock(arch_spinlock_t *x)
 {
 	volatile unsigned int *a;
 	int ret;
@@ -69,38 +69,38 @@ static inline int __raw_spin_trylock(raw
 
 /* Note that we have to ensure interrupts are disabled in case we're
  * interrupted by some other code that wants to grab the same read lock */
-static  __inline__ void __raw_read_lock(raw_rwlock_t *rw)
+static  __inline__ void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long flags;
 	local_irq_save(flags);
-	__raw_spin_lock_flags(&rw->lock, flags);
+	arch_spin_lock_flags(&rw->lock, flags);
 	rw->counter++;
-	__raw_spin_unlock(&rw->lock);
+	arch_spin_unlock(&rw->lock);
 	local_irq_restore(flags);
 }
 
 /* Note that we have to ensure interrupts are disabled in case we're
  * interrupted by some other code that wants to grab the same read lock */
-static  __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
+static  __inline__ void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned long flags;
 	local_irq_save(flags);
-	__raw_spin_lock_flags(&rw->lock, flags);
+	arch_spin_lock_flags(&rw->lock, flags);
 	rw->counter--;
-	__raw_spin_unlock(&rw->lock);
+	arch_spin_unlock(&rw->lock);
 	local_irq_restore(flags);
 }
 
 /* Note that we have to ensure interrupts are disabled in case we're
  * interrupted by some other code that wants to grab the same read lock */
-static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
+static __inline__ int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned long flags;
  retry:
 	local_irq_save(flags);
-	if (__raw_spin_trylock(&rw->lock)) {
+	if (arch_spin_trylock(&rw->lock)) {
 		rw->counter++;
-		__raw_spin_unlock(&rw->lock);
+		arch_spin_unlock(&rw->lock);
 		local_irq_restore(flags);
 		return 1;
 	}
@@ -111,7 +111,7 @@ static __inline__ int __raw_read_trylock
 		return 0;
 
 	/* Wait until we have a realistic chance at the lock */
-	while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0)
+	while (arch_spin_is_locked(&rw->lock) && rw->counter >= 0)
 		cpu_relax();
 
 	goto retry;
@@ -119,15 +119,15 @@ static __inline__ int __raw_read_trylock
 
 /* Note that we have to ensure interrupts are disabled in case we're
  * interrupted by some other code that wants to read_trylock() this lock */
-static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
+static __inline__ void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long flags;
 retry:
 	local_irq_save(flags);
-	__raw_spin_lock_flags(&rw->lock, flags);
+	arch_spin_lock_flags(&rw->lock, flags);
 
 	if (rw->counter != 0) {
-		__raw_spin_unlock(&rw->lock);
+		arch_spin_unlock(&rw->lock);
 		local_irq_restore(flags);
 
 		while (rw->counter != 0)
@@ -141,27 +141,27 @@ retry:
 	local_irq_restore(flags);
 }
 
-static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
+static __inline__ void arch_write_unlock(arch_rwlock_t *rw)
 {
 	rw->counter = 0;
-	__raw_spin_unlock(&rw->lock);
+	arch_spin_unlock(&rw->lock);
 }
 
 /* Note that we have to ensure interrupts are disabled in case we're
  * interrupted by some other code that wants to read_trylock() this lock */
-static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
+static __inline__ int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned long flags;
 	int result = 0;
 
 	local_irq_save(flags);
-	if (__raw_spin_trylock(&rw->lock)) {
+	if (arch_spin_trylock(&rw->lock)) {
 		if (rw->counter == 0) {
 			rw->counter = -1;
 			result = 1;
 		} else {
 			/* Read-locked.  Oh well. */
-			__raw_spin_unlock(&rw->lock);
+			arch_spin_unlock(&rw->lock);
 		}
 	}
 	local_irq_restore(flags);
@@ -173,7 +173,7 @@ static __inline__ int __raw_write_tryloc
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-static __inline__ int __raw_read_can_lock(raw_rwlock_t *rw)
+static __inline__ int arch_read_can_lock(arch_rwlock_t *rw)
 {
 	return rw->counter >= 0;
 }
@@ -182,16 +182,16 @@ static __inline__ int __raw_read_can_loc
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw)
+static __inline__ int arch_write_can_lock(arch_rwlock_t *rw)
 {
 	return !rw->counter;
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* __ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/parisc/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/parisc/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,18 +4,18 @@
 typedef struct {
 #ifdef CONFIG_PA20
 	volatile unsigned int slock;
-# define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+# define __ARCH_SPIN_LOCK_UNLOCKED { 1 }
 #else
 	volatile unsigned int lock[4];
-# define __RAW_SPIN_LOCK_UNLOCKED	{ { 1, 1, 1, 1 } }
+# define __ARCH_SPIN_LOCK_UNLOCKED	{ { 1, 1, 1, 1 } }
 #endif
-} raw_spinlock_t;
+} arch_spinlock_t;
 
 typedef struct {
-	raw_spinlock_t lock;
+	arch_spinlock_t lock;
 	volatile int counter;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ __RAW_SPIN_LOCK_UNLOCKED, 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ __ARCH_SPIN_LOCK_UNLOCKED, 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/Kconfig linux-libre-2.6.33-gnu1/arch/parisc/Kconfig
--- linux-libre-2.6.32-gnu1/arch/parisc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,6 @@ config PARISC
 	select BUG
 	select HAVE_PERF_EVENTS
 	select GENERIC_ATOMIC64 if !64BIT
-	select HAVE_ARCH_TRACEHOOK
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
 	  in many of their workstations & servers (HP9000 700 and 800 series,
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/asm-offsets.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/asm-offsets.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/asm-offsets.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
@@ -244,9 +244,6 @@ int main(void)
 	DEFINE(THREAD_SZ, sizeof(struct thread_info));
 	DEFINE(THREAD_SZ_ALGN, align(sizeof(struct thread_info), 64));
 	BLANK();
-	DEFINE(IRQSTAT_SIRQ_PEND, offsetof(irq_cpustat_t, __softirq_pending));
-	DEFINE(IRQSTAT_SZ, sizeof(irq_cpustat_t));
-	BLANK();
 	DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
 	DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
 	DEFINE(ICACHE_COUNT, offsetof(struct pdc_cache_info, ic_count));
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/irq.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,7 @@ static int cpu_set_affinity_irq(unsigned
 #endif
 
 static struct irq_chip cpu_interrupt_type = {
-	.typename	= "CPU",
+	.name		= "CPU",
 	.startup	= cpu_startup_irq,
 	.shutdown	= cpu_disable_irq,
 	.enable		= cpu_enable_irq,
@@ -180,7 +180,7 @@ int show_interrupts(struct seq_file *p,
 	if (i < NR_IRQS) {
 		struct irqaction *action;
 
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -192,7 +192,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
 
-		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, " %14s", irq_desc[i].chip->name);
 #ifndef PARISC_IRQ_CR16_COUNTS
 		seq_printf(p, "  %s", action->name);
 
@@ -224,7 +224,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
  skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/pci.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,6 @@
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/cache.h>		/* for L1_CACHE_BYTES */
 #include <asm/superio.h>
 
 #define DEBUG_RESOURCES 0
@@ -123,6 +122,10 @@ static int __init pcibios_init(void)
 	} else {
 		printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
 	}
+
+	/* Set the CLS for PCI as early as possible. */
+	pci_cache_line_size = pci_dfl_cache_line_size;
+
 	return 0;
 }
 
@@ -171,7 +174,7 @@ void pcibios_set_master(struct pci_dev *
 	** upper byte is PCI_LATENCY_TIMER.
 	*/
 	pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
-				(0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+			      (0x80 << 8) | pci_cache_line_size);
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/perf.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/perf.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/perf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/perf.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
  *
  *  This driver programs the PCX-U/PCX-W performance counters
  *  on the PA-RISC 2.0 chips.  The driver keeps all images now
- *  internally to the kernel to hopefully eliminate the possiblity
+ *  internally to the kernel to hopefully eliminate the possibility
  *  of a bad image halting the CPU.  Also, there are different
  *  images for the PCX-W and later chips vs the PCX-U chips.
  *
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/signal.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,6 @@
 #include <linux/stddef.h>
 #include <linux/compat.h>
 #include <linux/elf.h>
-#include <linux/tracehook.h>
 #include <asm/ucontext.h>
 #include <asm/rt_sigframe.h>
 #include <asm/uaccess.h>
@@ -469,7 +468,9 @@ handle_signal(unsigned long sig, siginfo
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	tracehook_signal_handler(sig, info, ka, regs, 0);
+	tracehook_signal_handler(sig, info, ka, regs, 
+		test_thread_flag(TIF_SINGLESTEP) ||
+		test_thread_flag(TIF_BLOCKSTEP));
 
 	return 1;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/smp.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/smp.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,8 +60,6 @@ static int smp_debug_lvl = 0;
 #define smp_debug(lvl, ...)	do { } while(0)
 #endif /* DEBUG_SMP */
 
-DEFINE_SPINLOCK(smp_lock);
-
 volatile struct task_struct *smp_init_current_idle_task;
 
 /* track which CPU is booting */
@@ -69,7 +67,7 @@ static volatile int cpu_now_booting __cp
 
 static int parisc_max_cpus __cpuinitdata = 1;
 
-DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
+static DEFINE_PER_CPU(spinlock_t, ipi_lock);
 
 enum ipi_message_type {
 	IPI_NOP=0,
@@ -438,6 +436,11 @@ void __init smp_prepare_boot_cpu(void)
 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		spin_lock_init(&per_cpu(ipi_lock, cpu));
+
 	init_cpu_present(cpumask_of(0));
 
 	parisc_max_cpus = max_cpus;
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/syscall_table.S linux-libre-2.6.33-gnu1/arch/parisc/kernel/syscall_table.S
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/syscall_table.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/syscall_table.S	2010-02-24 13:52:17.000000000 -0500
@@ -234,7 +234,7 @@
 	ENTRY_SAME(getsid)
 	ENTRY_SAME(fdatasync)
 	/* struct __sysctl_args is a mess */
-	ENTRY_DIFF(sysctl)
+	ENTRY_COMP(sysctl)
 	ENTRY_SAME(mlock)		/* 150 */
 	ENTRY_SAME(munlock)
 	ENTRY_SAME(mlockall)
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/sys_parisc32.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc32.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/sys_parisc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,13 +26,7 @@
 #include <linux/shm.h>
 #include <linux/slab.h>
 #include <linux/uio.h>
-#include <linux/nfs_fs.h>
 #include <linux/ncp_fs.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
@@ -90,77 +84,6 @@ asmlinkage long sys32_unimplemented(int
     return -ENOSYS;
 }
 
-#ifdef CONFIG_SYSCTL
-
-struct __sysctl_args32 {
-	u32 name;
-	int nlen;
-	u32 oldval;
-	u32 oldlenp;
-	u32 newval;
-	u32 newlen;
-	u32 __unused[4];
-};
-
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
-{
-#ifndef CONFIG_SYSCTL_SYSCALL
-	return -ENOSYS;
-#else
-	struct __sysctl_args32 tmp;
-	int error;
-	unsigned int oldlen32;
-	size_t oldlen, __user *oldlenp = NULL;
-	unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7;
-
-	DBG(("sysctl32(%p)\n", args));
-
-	if (copy_from_user(&tmp, args, sizeof(tmp)))
-		return -EFAULT;
-
-	if (tmp.oldval && tmp.oldlenp) {
-		/* Duh, this is ugly and might not work if sysctl_args
-		   is in read-only memory, but do_sysctl does indirectly
-		   a lot of uaccess in both directions and we'd have to
-		   basically copy the whole sysctl.c here, and
-		   glibc's __sysctl uses rw memory for the structure
-		   anyway.  */
-		/* a possibly better hack than this, which will avoid the
-		 * problem if the struct is read only, is to push the
-		 * 'oldlen' value out to the user's stack instead. -PB
-		 */
-		if (get_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
-			return -EFAULT;
-		oldlen = oldlen32;
-		if (put_user(oldlen, (size_t *)addr))
-			return -EFAULT;
-		oldlenp = (size_t *)addr;
-	}
-
-	lock_kernel();
-	error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen,
-			  (void __user *)(u64)tmp.oldval, oldlenp,
-			  (void __user *)(u64)tmp.newval, tmp.newlen);
-	unlock_kernel();
-	if (oldlenp) {
-		if (!error) {
-			if (get_user(oldlen, (size_t *)addr)) {
-				error = -EFAULT;
-			} else {
-				oldlen32 = oldlen;
-				if (put_user(oldlen32, (u32 *)(u64)tmp.oldlenp))
-					error = -EFAULT;
-			}
-		}
-		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
-			error = -EFAULT;
-	}
-	return error;
-#endif
-}
-
-#endif /* CONFIG_SYSCTL */
-
 asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
 	struct compat_timespec __user *interval)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/sys_parisc.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/sys_parisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/sys_parisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,37 +110,14 @@ unsigned long arch_get_unmapped_area(str
 	return addr;
 }
 
-static unsigned long do_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long fd,
-	unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long error = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file != NULL)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
 	unsigned long pgoff)
 {
 	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
 	   we have. */
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
 
 asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
@@ -148,7 +125,8 @@ asmlinkage unsigned long sys_mmap(unsign
 		unsigned long offset)
 {
 	if (!(offset & ~PAGE_MASK)) {
-		return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+		return sys_mmap_pgoff(addr, len, prot, flags, fd,
+					offset >> PAGE_SHIFT);
 	} else {
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/kernel/unwind.c linux-libre-2.6.33-gnu1/arch/parisc/kernel/unwind.c
--- linux-libre-2.6.32-gnu1/arch/parisc/kernel/unwind.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/kernel/unwind.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/kallsyms.h>
+#include <linux/sort.h>
 
 #include <asm/uaccess.h>
 #include <asm/assembly.h>
@@ -115,24 +116,18 @@ unwind_table_init(struct unwind_table *t
 	}
 }
 
+static int cmp_unwind_table_entry(const void *a, const void *b)
+{
+	return ((const struct unwind_table_entry *)a)->region_start
+	     - ((const struct unwind_table_entry *)b)->region_start;
+}
+
 static void
 unwind_table_sort(struct unwind_table_entry *start,
 		  struct unwind_table_entry *finish)
 {
-	struct unwind_table_entry el, *p, *q;
-
-	for (p = start + 1; p < finish; ++p) {
-		if (p[0].region_start < p[-1].region_start) {
-			el = *p;
-			q = p;
-			do {
-				q[0] = q[-1];
-				--q;
-			} while (q > start && 
-				 el.region_start < q[-1].region_start);
-			*q = el;
-		}
-	}
+	sort(start, finish - start, sizeof(struct unwind_table_entry),
+	     cmp_unwind_table_entry, NULL);
 }
 
 struct unwind_table *
@@ -417,3 +412,30 @@ int unwind_to_user(struct unwind_frame_i
 
 	return ret;
 }
+
+unsigned long return_address(unsigned int level)
+{
+	struct unwind_frame_info info;
+	struct pt_regs r;
+	unsigned long sp;
+
+	/* initialize unwind info */
+	asm volatile ("copy %%r30, %0" : "=r"(sp));
+	memset(&r, 0, sizeof(struct pt_regs));
+	r.iaoq[0] = (unsigned long) current_text_addr();
+	r.gr[2] = (unsigned long) __builtin_return_address(0);
+	r.gr[30] = sp;
+	unwind_frame_init(&info, current, &r);
+
+	/* unwind stack */
+	++level;
+	do {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			return 0;
+		if (!__kernel_text_address(info.ip)) {
+			return 0;
+		}
+	} while (info.ip && level--);
+
+	return info.ip;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/parisc/lib/bitops.c linux-libre-2.6.33-gnu1/arch/parisc/lib/bitops.c
--- linux-libre-2.6.32-gnu1/arch/parisc/lib/bitops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/parisc/lib/bitops.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,8 +12,8 @@
 #include <asm/atomic.h>
 
 #ifdef CONFIG_SMP
-raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
-	[0 ... (ATOMIC_HASH_SIZE-1)]  = __RAW_SPIN_LOCK_UNLOCKED
+arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
+	[0 ... (ATOMIC_HASH_SIZE-1)]  = __ARCH_SPIN_LOCK_UNLOCKED
 };
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/canyonlands.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/canyonlands.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/canyonlands.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/canyonlands.dts	2010-02-24 13:52:17.000000000 -0500
@@ -352,6 +352,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -381,6 +382,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/eiger.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/eiger.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/eiger.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/eiger.dts	2010-02-24 13:52:17.000000000 -0500
@@ -316,6 +316,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -345,6 +346,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -375,6 +377,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>; /* emac2&3 only */
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII1>;
@@ -403,6 +407,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>; /* emac2&3 only */
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII1>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gamecube.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gamecube.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gamecube.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gamecube.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,114 @@
+/*
+ * arch/powerpc/boot/dts/gamecube.dts
+ *
+ * Nintendo GameCube platform device tree source
+ * Copyright (C) 2007-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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/;
+
+/ {
+	model = "nintendo,gamecube";
+	compatible = "nintendo,gamecube";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen {
+		bootargs = "root=/dev/gcnsda2 rootwait udbg-immortal";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x01800000>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,gekko@0 {
+			device_type = "cpu";
+			reg = <0>;
+			clock-frequency = <486000000>; /* 486MHz */
+			bus-frequency = <162000000>; /* 162MHz core-to-bus 3x */
+			timebase-frequency = <40500000>; /* 162MHz / 4 */
+			i-cache-line-size = <32>;
+			d-cache-line-size = <32>;
+			i-cache-size = <32768>;
+			d-cache-size = <32768>;
+		};
+	};
+
+	/* devices contained int the flipper chipset */
+	flipper {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "nintendo,flipper";
+		ranges = <0x0c000000 0x0c000000 0x00010000>;
+		interrupt-parent = <&PIC>;
+
+		video@0c002000 {
+			compatible = "nintendo,flipper-vi";
+			reg = <0x0c002000 0x100>;
+			interrupts = <8>;
+		};
+
+		processor-interface@0c003000 {
+			compatible = "nintendo,flipper-pi";
+			reg = <0x0c003000 0x100>;
+
+			PIC: pic {
+				#interrupt-cells = <1>;
+				compatible = "nintendo,flipper-pic";
+				interrupt-controller;
+			};
+		};
+
+		dsp@0c005000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "nintendo,flipper-dsp";
+			reg = <0x0c005000 0x200>;
+			interrupts = <6>;
+
+			memory@0 {
+				compatible = "nintendo,flipper-aram";
+				reg = <0 0x1000000>;	/* 16MB */
+			};
+		};
+
+		disk@0c006000 {
+			compatible = "nintendo,flipper-di";
+			reg = <0x0c006000 0x40>;
+			interrupts = <2>;
+		};
+
+		audio@0c006c00 {
+			compatible = "nintendo,flipper-ai";
+			reg = <0x0c006c00 0x20>;
+			interrupts = <6>;
+		};
+
+		gamepad-controller@0c006400 {
+			compatible = "nintendo,flipper-si";
+			reg = <0x0c006400 0x100>;
+			interrupts = <3>;
+		};
+
+		/* External Interface bus */
+		exi@0c006800 {
+			compatible = "nintendo,flipper-exi";
+			reg = <0x0c006800 0x40>;
+			virtual-reg = <0x0c006800>;
+			interrupts = <4>;
+		};
+        };
+};
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	2010-02-24 13:52:17.000000000 -0500
@@ -118,6 +118,12 @@
 			};
 		};
 
+		nvram@3,0 {
+			device_type = "nvram";
+			compatible = "simtek,stk14ca8";
+			reg = <0x3 0x0 0x20000>;
+		};
+
 		fpga@4,0 {
 			compatible = "gef,ppc9a-fpga-regs";
 			reg = <0x4 0x0 0x40>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	2010-02-24 13:52:17.000000000 -0500
@@ -115,6 +115,12 @@
 			};
 		};
 
+		nvram@3,0 {
+			device_type = "nvram";
+			compatible = "simtek,stk14ca8";
+			reg = <0x3 0x0 0x20000>;
+		};
+
 		fpga@4,0 {
 			compatible = "gef,fpga-regs";
 			reg = <0x4 0x0 0x40>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,12 @@
 			  6 0 0xfd000000 0x00800000     // IO FPGA (8-bit)
 			  7 0 0xfd800000 0x00800000>;   // IO FPGA (32-bit)
 
+		nvram@3,0 {
+			device_type = "nvram";
+			compatible = "simtek,stk14ca8";
+			reg = <0x3 0x0 0x20000>;
+		};
+
 		fpga@4,0 {
 			compatible = "gef,fpga-regs";
 			reg = <0x4 0x0 0x40>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/glacier.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/glacier.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/glacier.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/glacier.dts	2010-02-24 13:52:17.000000000 -0500
@@ -292,6 +292,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -321,6 +322,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -351,6 +353,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>; /* emac2&3 only */
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII1>;
@@ -379,6 +383,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>; /* emac2&3 only */
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII1>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/haleakala.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/haleakala.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/haleakala.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/haleakala.dts	2010-02-24 13:52:17.000000000 -0500
@@ -226,6 +226,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/katmai.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/katmai.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/katmai.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/katmai.dts	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 
 / {
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 	model = "amcc,katmai";
 	compatible = "amcc,katmai";
 	dcr-parent = <&{/cpus/cpu@0}>;
@@ -49,7 +49,7 @@
 
 	memory {
 		device_type = "memory";
-		reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */
+		reg = <0x0 0x00000000 0x0 0x00000000>; /* Filled in by U-Boot */
 	};
 
 	UIC0: interrupt-controller0 {
@@ -108,11 +108,26 @@
 		dcr-reg = <0x00c 0x002>;
 	};
 
+	MQ0: mq {
+		compatible = "ibm,mq-440spe";
+		dcr-reg = <0x040 0x020>;
+	};
+
 	plb {
 		compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges;
+		/*        addr-child     addr-parent    size */
+		ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000
+			  0x4 0x00200000 0x4 0x00200000 0x00000400
+			  0x4 0xe0000000 0x4 0xe0000000 0x20000000
+			  0xc 0x00000000 0xc 0x00000000 0x20000000
+			  0xd 0x00000000 0xd 0x00000000 0x80000000
+			  0xd 0x80000000 0xd 0x80000000 0x80000000
+			  0xe 0x00000000 0xe 0x00000000 0x80000000
+			  0xe 0x80000000 0xe 0x80000000 0x80000000
+			  0xf 0x00000000 0xf 0x00000000 0x80000000
+			  0xf 0x80000000 0xf 0x80000000 0x80000000>;
 		clock-frequency = <0>; /* Filled in by zImage */
 
 		SDRAM0: sdram {
@@ -245,8 +260,8 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
 			/* This drives busses 0 to 0xf */
 			bus-range = <0x0 0xf>;
@@ -289,10 +304,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x10 to 0x1f */
 			bus-range = <0x10 0x1f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
@@ -330,10 +345,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x20 to 0x2f */
 			bus-range = <0x20 0x2f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
@@ -371,10 +386,10 @@
 			ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000
 				  0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>;
 
-			/* Inbound 2GB range starting at 0 */
-			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
+			/* Inbound 4GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>;
 
-			/* This drives busses 10 to 0x1f */
+			/* This drives busses 0x30 to 0x3f */
 			bus-range = <0x30 0x3f>;
 
 			/* Legacy interrupts (note the weird polarity, the bridge seems
@@ -392,6 +407,49 @@
 				0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */
 				0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
 		};
+
+		I2O: i2o@400100000 {
+			compatible = "ibm,i2o-440spe";
+			reg = <0x00000004 0x00100000 0x100>;
+			dcr-reg = <0x060 0x020>;
+		};
+
+		DMA0: dma0@400100100 {
+			compatible = "ibm,dma-440spe";
+			cell-index = <0>;
+			reg = <0x00000004 0x00100100 0x100>;
+			dcr-reg = <0x060 0x020>;
+			interrupt-parent = <&DMA0>;
+			interrupts = <0 1>;
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-map = <
+				0 &UIC0 0x14 4
+				1 &UIC1 0x16 4>;
+		};
+
+		DMA1: dma1@400100200 {
+			compatible = "ibm,dma-440spe";
+			cell-index = <1>;
+			reg = <0x00000004 0x00100200 0x100>;
+			dcr-reg = <0x060 0x020>;
+			interrupt-parent = <&DMA1>;
+			interrupts = <0 1>;
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-map = <
+				0 &UIC0 0x16 4
+				1 &UIC1 0x16 4>;
+		};
+
+		xor-accel@400200000 {
+			compatible = "amcc,xor-accelerator";
+			reg = <0x00000004 0x00200000 0x400>;
+			interrupt-parent = <&UIC1>;
+			interrupts = <0x1f 4>;
+		};
 	};
 
 	chosen {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/kilauea.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kilauea.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/kilauea.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kilauea.dts	2010-02-24 13:52:17.000000000 -0500
@@ -272,6 +272,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
@@ -300,6 +302,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/kmeter1.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kmeter1.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/kmeter1.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/kmeter1.dts	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,13 @@
 		reg = <0xe0000000 0x00000200>;
 		bus-frequency = <0>;	/* Filled in by U-Boot */
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/makalu.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/makalu.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/makalu.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/makalu.dts	2010-02-24 13:52:17.000000000 -0500
@@ -227,6 +227,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
+				tx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x0000003f>;	/* Start at 6 */
 				rgmii-device = <&RGMII0>;
@@ -255,6 +257,8 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+                                rx-fifo-size-gige = <16384>;
+                                tx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts	2010-02-24 13:52:17.000000000 -0500
@@ -204,6 +204,7 @@
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = < &phy0 >;
+			fsl,magic-packet;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -246,6 +247,7 @@
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = < &phy1 >;
+			fsl,magic-packet;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -309,6 +311,22 @@
 			interrupt-parent = <&ipic>;
 		};
 
+		gtm1: timer@500 {
+			compatible = "fsl,mpc8315-gtm", "fsl,gtm";
+			reg = <0x500 0x100>;
+			interrupts = <90 8 78 8 84 8 72 8>;
+			interrupt-parent = <&ipic>;
+			clock-frequency = <133333333>;
+		};
+
+		timer@600 {
+			compatible = "fsl,mpc8315-gtm", "fsl,gtm";
+			reg = <0x600 0x100>;
+			interrupts = <91 8 79 8 85 8 73 8>;
+			interrupt-parent = <&ipic>;
+			clock-frequency = <133333333>;
+		};
+
 		/* IPIC
 		 * interrupts cell = <intr #, sense>
 		 * sense values match linux IORESOURCE_IRQ_* defines:
@@ -337,6 +355,15 @@
 				      0x59 0x8>;
 			interrupt-parent = < &ipic >;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc",
+				     "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 8>;
+			interrupt-parent = <&ipic>;
+			fsl,mpc8313-wakeup-timer = <&gtm1>;
+		};
 	};
 
 	pci0: pci@e0008500 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc832x_mds.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc832x_mds.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc832x_mds.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc832x_mds.dts	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8323-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -163,6 +170,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x4c>;
 			fsl,descriptor-types-mask = <0x0122003f>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: pic@700 {
@@ -428,5 +436,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8323-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -141,6 +148,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x4c>;
 			fsl,descriptor-types-mask = <0x0122003f>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic:pic@700 {
@@ -360,5 +368,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2010-02-24 13:52:17.000000000 -0500
@@ -63,6 +63,24 @@
 			reg = <0x200 0x100>;
 		};
 
+		gpio1: gpio-controller@c00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8349-gpio";
+			reg = <0xc00 0x100>;
+			interrupts = <74 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		gpio2: gpio-controller@d00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8349-gpio";
+			reg = <0xd00 0x100>;
+			interrupts = <75 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -72,6 +90,12 @@
 			interrupts = <14 0x8>;
 			interrupt-parent = <&ipic>;
 			dfsrr;
+
+			eeprom: at24@50 {
+				compatible = "st-micro,24c256";
+				reg = <0x50>;
+			};
+
 		};
 
 		i2c@3100 {
@@ -91,6 +115,25 @@
 				interrupt-parent = <&ipic>;
 			};
 
+			pcf1: iexp@38 {
+				#gpio-cells = <2>;
+				compatible = "ti,pcf8574a";
+				reg = <0x38>;
+				gpio-controller;
+			};
+
+			pcf2: iexp@39 {
+				#gpio-cells = <2>;
+				compatible = "ti,pcf8574a";
+				reg = <0x39>;
+				gpio-controller;
+			};
+
+			spd: at24@51 {
+				compatible = "at24,spd";
+				reg = <0x51>;
+			};
+
 			mcu_pio: mcu@a {
 				#gpio-cells = <2>;
 				compatible = "fsl,mc9s08qg8-mpc8349emitx",
@@ -275,6 +318,24 @@
 			reg = <0x700 0x100>;
 			device_type = "ipic";
 		};
+
+		gpio-leds {
+			compatible = "gpio-leds";
+
+			green {
+				label = "Green";
+				gpios = <&pcf1 0 1>;
+				linux,default-trigger = "heartbeat";
+			};
+
+			yellow {
+				label = "Yellow";
+				gpios = <&pcf1 1 1>;
+				/* linux,default-trigger = "heartbeat"; */
+				default-state = "on";
+			};
+		};
+
 	};
 
 	pci0: pci@e0008500 {
@@ -331,7 +392,26 @@
 		compatible = "fsl,mpc8349e-localbus",
 			     "fsl,pq2pro-localbus";
 		reg = <0xe0005000 0xd8>;
-		ranges = <0x3 0x0 0xf0000000 0x210>;
+		ranges = <0x0 0x0 0xfe000000 0x1000000	/* flash */
+			  0x1 0x0 0xf8000000 0x20000	/* VSC 7385 */
+			  0x2 0x0 0xf9000000 0x200000	/* exp slot */
+			  0x3 0x0 0xf0000000 0x210>;	/* CF slot */
+
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0x0      0x0 0x800000>;
+			bank-width = <2>;
+			device-width = <1>;
+		};
+
+		flash@0,800000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x800000 0x800000>;
+			bank-width = <2>;
+			device-width = <1>;
+		};
 
 		pata@3,0 {
 			compatible = "fsl,mpc8349emitx-pata", "ata-generic";
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc836x_mds.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc836x_mds.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc836x_mds.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc836x_mds.dts	2010-02-24 13:52:17.000000000 -0500
@@ -99,6 +99,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -194,6 +201,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x7e>;
 			fsl,descriptor-types-mask = <0x01010ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: pic@700 {
@@ -470,5 +478,6 @@
 		       0xe0008300 0x8>;		/* config space access registers */
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
+		sleep = <&pmc 0x00010000>;
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc836x_rdk.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc836x_rdk.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc836x_rdk.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc836x_rdk.dts	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,13 @@
 			reg = <0x200 0x100>;
 		};
 
+		pmc: power@b00 {
+			compatible = "fsl,mpc8360-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
 		i2c@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -161,6 +168,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x7e>;
 			fsl,descriptor-types-mask = <0x01010ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		ipic: interrupt-controller@700 {
@@ -455,6 +463,7 @@
 				 0xa800 0 0 2 &ipic 20 8
 				 0xa800 0 0 3 &ipic 21 8
 				 0xa800 0 0 4 &ipic 18 8>;
+		sleep = <&pmc 0x00010000>;
 		/* filled by u-boot */
 		bus-range = <0 0>;
 		clock-frequency = <0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,8 @@
 			i-cache-line-size = <32>;	// 32 bytes
 			d-cache-size = <0x8000>;		// L1, 32K
 			i-cache-size = <0x8000>;		// L1, 32K
+			sleep = <&pmc 0x00008000	// core
+				 &pmc 0x00004000>;	// timebase
 			timebase-frequency = <0>;
 			bus-frequency = <0>;
 			clock-frequency = <0>;
@@ -94,31 +96,41 @@
 			interrupts = <16 2>;
 		};
 
-		i2c@3000 {
+		i2c-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000004>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <3 1>;
+					interrupt-parent = <&mpic>;
+				};
 			};
-		};
 
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			i2c@3100 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <1>;
+				compatible = "fsl-i2c";
+				reg = <0x3100 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+			};
 		};
 
 		dma@21300 {
@@ -128,6 +140,8 @@
 			reg = <0x21300 0x4>;
 			ranges = <0x0 0x21100 0x200>;
 			cell-index = <0>;
+			sleep = <&pmc 0x00000400>;
+
 			dma-channel@0 {
 				compatible = "fsl,mpc8568-dma-channel",
 						"fsl,eloplus-dma-channel";
@@ -176,6 +190,7 @@
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0x00000080>;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -228,6 +243,7 @@
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy3>;
+			sleep = <&pmc 0x00000040>;
 
 			mdio@520 {
 				#address-cells = <1>;
@@ -242,30 +258,47 @@
 			};
 		};
 
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+		duart-sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000002>;
+			ranges;
+
+			serial0: serial@4500 {
+				cell-index = <0>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4500 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
+
+			serial1: serial@4600 {
+				cell-index = <1>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4600 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 		};
 
-		global-utilities@e0000 {	//global utilities block
-			compatible = "fsl,mpc8548-guts";
+		global-utilities@e0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8568-guts", "fsl,mpc8548-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
-		};
 
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+			pmc: power@70 {
+				compatible = "fsl,mpc8568-pmc",
+					     "fsl,mpc8548-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		crypto@30000 {
@@ -277,6 +310,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0xfe>;
 			fsl,descriptor-types-mask = <0x12b0ebf>;
+			sleep = <&pmc 0x01000000>;
 		};
 
 		mpic: pic@40000 {
@@ -376,6 +410,7 @@
 		compatible = "fsl,qe";
 		ranges = <0x0 0xe0080000 0x40000>;
 		reg = <0xe0080000 0x480>;
+		sleep = <&pmc 0x00000800>;
 		brg-frequency = <0>;
 		bus-frequency = <396000000>;
 		fsl,qe-num-riscs = <2>;
@@ -509,6 +544,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x0 0xe2000000 0x0 0x800000>;
+		sleep = <&pmc 0x80000000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -534,6 +570,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x1000000 0x0 0x0 0xe2800000 0x0 0x800000>;
+		sleep = <&pmc 0x20000000>;
 		clock-frequency = <33333333>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -570,5 +607,7 @@
 			      55 2 /* msg2_tx   */
 			      56 2 /* msg2_rx   */>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x00080000   /* controller */
+			 &pmc 0x00040000>; /* message unit */
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8569mds.dts	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,8 @@
 			i-cache-line-size = <32>;	// 32 bytes
 			d-cache-size = <0x8000>;		// L1, 32K
 			i-cache-size = <0x8000>;		// L1, 32K
+			sleep = <&pmc 0x00008000	// core
+				 &pmc 0x00004000>;	// timebase
 			timebase-frequency = <0>;
 			bus-frequency = <0>;
 			clock-frequency = <0>;
@@ -59,6 +61,7 @@
 		reg = <0xe0005000 0x1000>;
 		interrupts = <19 2>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x08000000>;
 
 		ranges = <0x0 0x0 0xfe000000 0x02000000
 			  0x1 0x0 0xf8000000 0x00008000
@@ -158,51 +161,69 @@
 			interrupts = <18 2>;
 		};
 
-		i2c@3000 {
+		i2c-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000004>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <3 1>;
+					interrupt-parent = <&mpic>;
+				};
+			};
+
+			i2c@3100 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <1>;
+				compatible = "fsl-i2c";
+				reg = <0x3100 0x100>;
+				interrupts = <43 2>;
+				interrupt-parent = <&mpic>;
+				dfsrr;
 			};
 		};
 
-		i2c@3100 {
+		duart-sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x00000002>;
+			ranges;
 
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
+			serial0: serial@4500 {
+				cell-index = <0>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4500 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
+			serial1: serial@4600 {
+				cell-index = <1>;
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0x4600 0x100>;
+				clock-frequency = <0>;
+				interrupts = <42 2>;
+				interrupt-parent = <&mpic>;
+			};
 		};
 
 		L2: l2-cache-controller@20000 {
@@ -260,6 +281,7 @@
 			reg = <0x2e000 0x1000>;
 			interrupts = <72 0x8>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00200000>;
 			/* Filled in by U-Boot */
 			clock-frequency = <0>;
 			status = "disabled";
@@ -276,6 +298,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0xbfe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x01000000>;
 		};
 
 		mpic: pic@40000 {
@@ -304,9 +327,18 @@
 		};
 
 		global-utilities@e0000 {
-			compatible = "fsl,mpc8569-guts";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8569-guts", "fsl,mpc8548-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
+
+			pmc: power@70 {
+				compatible = "fsl,mpc8569-pmc",
+					     "fsl,mpc8548-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		par_io@e0100 {
@@ -422,6 +454,7 @@
 		compatible = "fsl,qe";
 		ranges = <0x0 0xe0080000 0x40000>;
 		reg = <0xe0080000 0x480>;
+		sleep = <&pmc 0x00000800>;
 		brg-frequency = <0>;
 		bus-frequency = <0>;
 		fsl,qe-num-riscs = <4>;
@@ -684,6 +717,7 @@
 		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x1000000 0x0 0x00000000 0xe2800000 0x0 0x00800000>;
+		sleep = <&pmc 0x20000000>;
 		clock-frequency = <33333333>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
@@ -714,5 +748,6 @@
 			      55 2 /* msg2_tx   */
 			      56 2 /* msg2_rx   */>;
 		interrupt-parent = <&mpic>;
+		sleep = <&pmc 0x00080000>;
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,8 @@
 			i-cache-line-size = <32>;
 			d-cache-size = <32768>;		// L1
 			i-cache-size = <32768>;		// L1
+			sleep = <&pmc 0x00008000 0	// core
+				 &pmc 0x00004000 0>;	// timebase
 			timebase-frequency = <0>;	// From uboot
 			bus-frequency = <0>;		// From uboot
 			clock-frequency = <0>;		// From uboot
@@ -60,6 +62,7 @@
 			  5 0 0xe8480000 0x00008000
 			  6 0 0xe84c0000 0x00008000
 			  3 0 0xe8000000 0x00000020>;
+		sleep = <&pmc 0x08000000 0>;
 
 		flash@0,0 {
 			compatible = "cfi-flash";
@@ -105,6 +108,8 @@
 			compatible = "fsl,fpga-pixis";
 			reg = <3 0 0x20>;
 			ranges = <0 3 0 0x20>;
+			interrupt-parent = <&mpic>;
+			interrupts = <8 8>;
 
 			sdcsr_pio: gpio-controller@a {
 				#gpio-cells = <2>;
@@ -163,6 +168,7 @@
 			reg = <0x3100 0x100>;
 			interrupts = <43 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000004 0>;
 			dfsrr;
 		};
 
@@ -174,6 +180,7 @@
 			clock-frequency = <0>;
 			interrupts = <42 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000002 0>;
 		};
 
 		serial1: serial@4600 {
@@ -184,6 +191,7 @@
 			clock-frequency = <0>;
 			interrupts = <42 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x00000008 0>;
 		};
 
 		spi@7000 {
@@ -196,6 +204,7 @@
 			interrupt-parent = <&mpic>;
 			mode = "cpu";
 			gpios = <&sdcsr_pio 7 0>;
+			sleep = <&pmc 0x00000800 0>;
 
 			mmc-slot@0 {
 				compatible = "fsl,mpc8610hpcd-mmc-slot",
@@ -213,6 +222,7 @@
 			reg = <0x2c000 100>;
 			interrupts = <72 2>;
 			interrupt-parent = <&mpic>;
+			sleep = <&pmc 0x04000000 0>;
 		};
 
 		mpic: interrupt-controller@40000 {
@@ -241,9 +251,18 @@
 		};
 
 		global-utilities@e0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			compatible = "fsl,mpc8610-guts";
 			reg = <0xe0000 0x1000>;
+			ranges = <0 0xe0000 0x1000>;
 			fsl,has-rstcr;
+
+			pmc: power@70 {
+				compatible = "fsl,mpc8610-pmc",
+					     "fsl,mpc8641d-pmc";
+				reg = <0x70 0x20>;
+			};
 		};
 
 		wdt@e4000 {
@@ -262,6 +281,7 @@
 			fsl,playback-dma = <&dma00>;
 			fsl,capture-dma = <&dma01>;
 			fsl,fifo-depth = <8>;
+			sleep = <&pmc 0 0x08000000>;
 		};
 
 		ssi@16100 {
@@ -271,6 +291,7 @@
 			interrupt-parent = <&mpic>;
 			interrupts = <63 2>;
 			fsl,fifo-depth = <8>;
+			sleep = <&pmc 0 0x04000000>;
 		};
 
 		dma@21300 {
@@ -280,6 +301,7 @@
 			cell-index = <0>;
 			reg = <0x21300 0x4>; /* DMA general status register */
 			ranges = <0x0 0x21100 0x200>;
+			sleep = <&pmc 0x00000400 0>;
 
 			dma00: dma-channel@0 {
 				compatible = "fsl,mpc8610-dma-channel",
@@ -322,6 +344,7 @@
 			cell-index = <1>;
 			reg = <0xc300 0x4>; /* DMA general status register */
 			ranges = <0x0 0xc100 0x200>;
+			sleep = <&pmc 0x00000200 0>;
 
 			dma-channel@0 {
 				compatible = "fsl,mpc8610-dma-channel",
@@ -369,6 +392,7 @@
 		bus-range = <0 0>;
 		ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 			  0x01000000 0x0 0x00000000 0xe1000000 0x0 0x00100000>;
+		sleep = <&pmc 0x80000000 0>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <24 2>;
@@ -398,6 +422,7 @@
 		bus-range = <1 3>;
 		ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
 			  0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>;
+		sleep = <&pmc 0x40000000 0>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <26 2>;
@@ -474,6 +499,7 @@
 				 0x0000 0 0 4 &mpic 7 1>;
 		interrupt-parent = <&mpic>;
 		interrupts = <25 2>;
+		sleep = <&pmc 0x20000000 0>;
 		clock-frequency = <33333333>;
 	};
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p1020rdb.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p1020rdb.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p1020rdb.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p1020rdb.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,477 @@
+/*
+ * P1020 RDB Device Tree Source
+ *
+ * Copyright 2009 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/;
+/ {
+	model = "fsl,P1020";
+	compatible = "fsl,P1020RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P1020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P1020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		/* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xffa00000 0x00040000
+			  0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 256KB for Vitesse 7385 Switch firmware */
+				reg = <0x0 0x00040000>;
+				label = "NOR (RO) Vitesse-7385 Firmware";
+				read-only;
+			};
+
+			partition@40000 {
+				/* 256KB for DTB Image */
+				reg = <0x00040000 0x00040000>;
+				label = "NOR (RO) DTB Image";
+				read-only;
+			};
+
+			partition@80000 {
+				/* 3.5 MB for Linux Kernel Image */
+				reg = <0x00080000 0x00380000>;
+				label = "NOR (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@400000 {
+				/* 11MB for JFFS2 based Root file System */
+				reg = <0x00400000 0x00b00000>;
+				label = "NOR (RW) JFFS2 Root File System";
+			};
+
+			partition@f00000 {
+				/* This location must not be altered  */
+				/* 512KB for u-boot Bootloader Image */
+				/* 512KB for u-boot Environment Variables */
+				reg = <0x00f00000 0x00100000>;
+				label = "NOR (RO) U-Boot Image";
+				read-only;
+			};
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p1020-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x1 0x0 0x40000>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND (RO) U-Boot Image";
+				read-only;
+			};
+
+			partition@100000 {
+				/* 1MB for DTB Image */
+				reg = <0x00100000 0x00100000>;
+				label = "NAND (RO) DTB Image";
+				read-only;
+			};
+
+			partition@200000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00200000 0x00400000>;
+				label = "NAND (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@600000 {
+				/* 4MB for Compressed Root file System Image */
+				reg = <0x00600000 0x00400000>;
+				label = "NAND (RO) Compressed RFS Image";
+				read-only;
+			};
+
+			partition@a00000 {
+				/* 7MB for JFFS2 based Root file System */
+				reg = <0x00a00000 0x00700000>;
+				label = "NAND (RW) JFFS2 Root File System";
+			};
+
+			partition@1100000 {
+				/* 15MB for JFFS2 based Root file System */
+				reg = <0x01100000 0x00f00000>;
+				label = "NAND (RW) Writable User area";
+			};
+		};
+
+		L2switch@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "vitesse-7385";
+			reg = <0x2 0x0 0x20000>;
+		};
+
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p1020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p1020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <16 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p1020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p1020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x40000>; // L2,256K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		usb@23000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x23000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <46 0x2>;
+			phy_type = "ulpi";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p1020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p1020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,363 @@
+/*
+ * P2020 RDB  Core0 Device Tree Source in CAMP mode.
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb,
+ * eth1, eth2, sdhc, crypto, global-util, pci0.
+ *
+ * Copyright 2009 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/;
+/ {
+	model = "fsl,P2020";
+	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		serial0 = &serial0;
+		pci0 = &pci0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P2020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p2020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p2020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <17 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p2020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p2020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x80000>; // L2,512K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,gianfar-mdio";
+			reg = <0x24520 0x20>;
+
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
+				interrupts = <3 1>;
+				reg = <0x0>;
+			};
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
+				interrupts = <3 1>;
+				reg = <0x1>;
+			};
+		};
+
+		mdio@25520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,gianfar-tbi";
+			reg = <0x26520 0x20>;
+
+			tbi0: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
+		};
+
+		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 2 36 2 40 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "sgmii";
+
+		};
+
+		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <2>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <31 2 32 2 33 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+			protected-sources = <
+			42 76 77 78 79 /* serial1 , dma2 */
+			29 30 34 26 /* enet0, pci1 */
+			0xe0 0xe1 0xe2 0xe3 /* msi */
+			0xe4 0xe5 0xe6 0xe7
+			>;
+		};
+
+		global-utilities@e0000 {
+			compatible = "fsl,p2020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,184 @@
+/*
+ * P2020 RDB Core1 Device Tree Source in CAMP mode.
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts allows core1 to have l2, dma2, eth0, pci1, msi.
+ *
+ * Please note to add "-b 1" for core1's dts compiling.
+ *
+ * Copyright 2009 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/;
+/ {
+	model = "fsl,P2020";
+	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &enet0;
+		serial0 = &serial0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P2020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p2020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		serial0: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+		};
+
+		dma@c300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0xc300 0x4>;
+			ranges = <0x0 0xc100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <76 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <77 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <78 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <79 2>;
+			};
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p2020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x80000>; // L2,512K
+			interrupt-parent = <&mpic>;
+		};
+
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <29 2 30 2 34 2>;
+			interrupt-parent = <&mpic>;
+			fixed-link = <1 1 1000 0 0>;
+			phy-connection-type = "rgmii-id";
+
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+			protected-sources = <
+			17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */
+			16 20 21 22 23 28 	/* L2, dma1, USB */
+			03 35 36 40 31 32 33 	/* mdio, enet1, enet2 */
+			72 45 58 25 		/* sdhci, crypto , pci */
+			>;
+		};
+
+		msi@41600 {
+			compatible = "fsl,p2020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p4080ds.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p4080ds.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/p4080ds.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/p4080ds.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,554 @@
+/*
+ * P4080DS Device Tree Source
+ *
+ * Copyright 2009 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/;
+
+/ {
+	model = "fsl,P4080DS";
+	compatible = "fsl,P4080DS";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ccsr = &soc;
+
+		serial0 = &serial0;
+		serial1 = &serial1;
+		serial2 = &serial2;
+		serial3 = &serial3;
+		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
+		usb0 = &usb0;
+		usb1 = &usb1;
+		dma0 = &dma0;
+		dma1 = &dma1;
+		sdhc = &sdhc;
+
+		rio0 = &rapidio0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: PowerPC,4080@0 {
+			device_type = "cpu";
+			reg = <0>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+			};
+		};
+		cpu1: PowerPC,4080@1 {
+			device_type = "cpu";
+			reg = <1>;
+			next-level-cache = <&L2_1>;
+			L2_1: l2-cache {
+			};
+		};
+		cpu2: PowerPC,4080@2 {
+			device_type = "cpu";
+			reg = <2>;
+			next-level-cache = <&L2_2>;
+			L2_2: l2-cache {
+			};
+		};
+		cpu3: PowerPC,4080@3 {
+			device_type = "cpu";
+			reg = <3>;
+			next-level-cache = <&L2_3>;
+			L2_3: l2-cache {
+			};
+		};
+		cpu4: PowerPC,4080@4 {
+			device_type = "cpu";
+			reg = <4>;
+			next-level-cache = <&L2_4>;
+			L2_4: l2-cache {
+			};
+		};
+		cpu5: PowerPC,4080@5 {
+			device_type = "cpu";
+			reg = <5>;
+			next-level-cache = <&L2_5>;
+			L2_5: l2-cache {
+			};
+		};
+		cpu6: PowerPC,4080@6 {
+			device_type = "cpu";
+			reg = <6>;
+			next-level-cache = <&L2_6>;
+			L2_6: l2-cache {
+			};
+		};
+		cpu7: PowerPC,4080@7 {
+			device_type = "cpu";
+			reg = <7>;
+			next-level-cache = <&L2_7>;
+			L2_7: l2-cache {
+			};
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	soc: soc@ffe000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+		reg = <0xf 0xfe000000 0 0x00001000>;
+
+		corenet-law@0 {
+			compatible = "fsl,corenet-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <32>;
+		};
+
+		memory-controller@8000 {
+			compatible = "fsl,p4080-memory-controller";
+			reg = <0x8000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <0x12 2>;
+		};
+
+		memory-controller@9000 {
+			compatible = "fsl,p4080-memory-controller";
+			reg = <0x9000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <0x12 2>;
+		};
+
+		corenet-cf@18000 {
+			compatible = "fsl,corenet-cf";
+			reg = <0x18000 0x1000>;
+			fsl,ccf-num-csdids = <32>;
+			fsl,ccf-num-snoopids = <32>;
+		};
+
+		iommu@20000 {
+			compatible = "fsl,p4080-pamu";
+			reg = <0x20000 0x10000>;
+			interrupts = <24 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		dma0: dma@100300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p4080-dma", "fsl,eloplus-dma";
+			reg = <0x100300 0x4>;
+			ranges = <0x0 0x100100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <28 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <29 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <30 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <31 2>;
+			};
+		};
+
+		dma1: dma@101300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p4080-dma", "fsl,eloplus-dma";
+			reg = <0x101300 0x4>;
+			ranges = <0x0 0x101100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <32 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <33 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <34 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,p4080-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <35 2>;
+			};
+		};
+
+		spi@110000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x110000 0x1000>;
+			interrupts = <53 0x2>;
+			interrupt-parent = <&mpic>;
+			espi,num-ss-bits = <4>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				spi-max-frequency = <40000000>; /* input clock */
+				partition@u-boot {
+					label = "u-boot";
+					reg = <0x00000000 0x00100000>;
+					read-only;
+				};
+				partition@kernel {
+					label = "kernel";
+					reg = <0x00100000 0x00500000>;
+					read-only;
+				};
+				partition@dtb {
+					label = "dtb";
+					reg = <0x00600000 0x00100000>;
+					read-only;
+				};
+				partition@fs {
+					label = "file system";
+					reg = <0x00700000 0x00900000>;
+				};
+			};
+		};
+
+		sdhc: sdhc@114000 {
+			compatible = "fsl,p4080-esdhc", "fsl,esdhc";
+			reg = <0x114000 0x1000>;
+			interrupts = <48 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		i2c@118000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x118000 0x100>;
+			interrupts = <38 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		i2c@118100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x118100 0x100>;
+			interrupts = <38 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			eeprom@51 {
+				compatible = "at24,24c256";
+				reg = <0x51>;
+			};
+			eeprom@52 {
+				compatible = "at24,24c256";
+				reg = <0x52>;
+			};
+			rtc@68 {
+				compatible = "dallas,ds3232";
+				reg = <0x68>;
+				interrupts = <0 0x1>;
+				interrupt-parent = <&mpic>;
+			};
+		};
+
+		i2c@119000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <2>;
+			compatible = "fsl-i2c";
+			reg = <0x119000 0x100>;
+			interrupts = <39 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		i2c@119100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <3>;
+			compatible = "fsl-i2c";
+			reg = <0x119100 0x100>;
+			interrupts = <39 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@11c500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x11c500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <36 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@11c600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x11c600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <36 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial2: serial@11d500 {
+			cell-index = <2>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x11d500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <37 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial3: serial@11d600 {
+			cell-index = <3>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x11d600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <37 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		gpio0: gpio@130000 {
+			compatible = "fsl,p4080-gpio";
+			reg = <0x130000 0x1000>;
+			interrupts = <55 2>;
+			interrupt-parent = <&mpic>;
+			#gpio-cells = <2>;
+			gpio-controller;
+		};
+
+		usb0: usb@210000 {
+			compatible = "fsl,p4080-usb2-mph",
+					"fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+			reg = <0x210000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&mpic>;
+			interrupts = <44 0x2>;
+			phy_type = "ulpi";
+		};
+
+		usb1: usb@211000 {
+			compatible = "fsl,p4080-usb2-dr",
+					"fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+			reg = <0x211000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&mpic>;
+			interrupts = <45 0x2>;
+			dr_mode = "host";
+			phy_type = "ulpi";
+		};
+	};
+
+	rapidio0: rapidio@ffe0c0000 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "fsl,rapidio-delta";
+		reg = <0xf 0xfe0c0000 0 0x20000>;
+		ranges = <0 0 0xf 0xf5000000 0 0x01000000>;
+		interrupt-parent = <&mpic>;
+		/* err_irq bell_outb_irq bell_inb_irq
+			msg1_tx_irq msg1_rx_irq	msg2_tx_irq msg2_rx_irq */
+		interrupts = <16 2 56 2 57 2 60 2 61 2 62 2 63 2>;
+	};
+
+	localbus@ffe124000 {
+		compatible = "fsl,p4080-elbc", "fsl,elbc", "simple-bus";
+		reg = <0xf 0xfe124000 0 0x1000>;
+		interrupts = <25 2>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		ranges = <0 0 0xf 0xe8000000 0x08000000>;
+
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x08000000>;
+			bank-width = <2>;
+			device-width = <2>;
+		};
+	};
+
+	pci0: pcie@ffe200000 {
+		compatible = "fsl,p4080-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xfe200000 0 0x1000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+		clock-frequency = <0x1fca055>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 40 1
+			0000 0 0 2 &mpic 1 1
+			0000 0 0 3 &mpic 2 1
+			0000 0 0 4 &mpic 3 1
+			>;
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci1: pcie@ffe201000 {
+		compatible = "fsl,p4080-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xfe201000 0 0x1000>;
+		bus-range = <0 0xff>;
+		ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+			  0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+		clock-frequency = <0x1fca055>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 41 1
+			0000 0 0 2 &mpic 5 1
+			0000 0 0 3 &mpic 6 1
+			0000 0 0 4 &mpic 7 1
+			>;
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@ffe202000 {
+		compatible = "fsl,p4080-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xfe202000 0 0x1000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+		clock-frequency = <0x1fca055>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 42 1
+			0000 0 0 2 &mpic 9 1
+			0000 0 0 3 &mpic 10 1
+			0000 0 0 4 &mpic 11 1
+			>;
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/redwood.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/redwood.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/redwood.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/redwood.dts	2010-02-24 13:52:17.000000000 -0500
@@ -226,6 +226,7 @@
 				max-frame-size = <9000>;
 				rx-fifo-size = <4096>;
 				tx-fifo-size = <2048>;
+				rx-fifo-size-gige = <16384>;
 				phy-mode = "rgmii";
 				phy-map = <0x00000000>;
 				rgmii-device = <&RGMII0>;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/warp.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/warp.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/warp.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/warp.dts	2010-02-24 13:52:17.000000000 -0500
@@ -146,7 +146,7 @@
 
 				fpga@2,4000 {
 					compatible = "pika,fpga-sd";
-					reg = <0x00000002 0x00004000 0x00000A00>;
+					reg = <0x00000002 0x00004000 0x00004000>;
 				};
 
 				nor@0,0 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/wii.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/wii.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/wii.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/wii.dts	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,218 @@
+/*
+ * arch/powerpc/boot/dts/wii.dts
+ *
+ * Nintendo Wii platform device tree source
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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/;
+
+/*
+ * This is commented-out for now.
+ * Until a later patch is merged, the kernel can use only the first
+ * contiguous RAM range and will BUG() if the memreserve is outside
+ * that range.
+ */
+/*/memreserve/ 0x10000000 0x0004000;*/	/* DSP RAM */
+
+/ {
+	model = "nintendo,wii";
+	compatible = "nintendo,wii";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen {
+		bootargs = "root=/dev/mmcblk0p2 rootwait udbg-immortal";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x01800000	/* MEM1 24MB 1T-SRAM */
+		       0x10000000 0x04000000>;	/* MEM2 64MB GDDR3 */
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,broadway@0 {
+			device_type = "cpu";
+			reg = <0>;
+			clock-frequency = <729000000>; /* 729MHz */
+			bus-frequency = <243000000>; /* 243MHz core-to-bus 3x */
+			timebase-frequency = <60750000>; /* 243MHz / 4 */
+			i-cache-line-size = <32>;
+			d-cache-line-size = <32>;
+			i-cache-size = <32768>;
+			d-cache-size = <32768>;
+		};
+	};
+
+	/* devices contained in the hollywood chipset */
+	hollywood {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "nintendo,hollywood";
+                ranges = <0x0c000000 0x0c000000 0x01000000
+			  0x0d000000 0x0d000000 0x00800000
+			  0x0d800000 0x0d800000 0x00800000>;
+		interrupt-parent = <&PIC0>;
+
+		video@0c002000 {
+			compatible = "nintendo,hollywood-vi",
+					"nintendo,flipper-vi";
+			reg = <0x0c002000 0x100>;
+			interrupts = <8>;
+		};
+
+		processor-interface@0c003000 {
+			compatible = "nintendo,hollywood-pi",
+					"nintendo,flipper-pi";
+			reg = <0x0c003000 0x100>;
+
+			PIC0: pic0 {
+				#interrupt-cells = <1>;
+				compatible = "nintendo,flipper-pic";
+				interrupt-controller;
+			};
+		};
+
+		dsp@0c005000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "nintendo,hollywood-dsp",
+					"nintendo,flipper-dsp";
+			reg = <0x0c005000 0x200>;
+			interrupts = <6>;
+		};
+
+		gamepad-controller@0d006400 {
+			compatible = "nintendo,hollywood-si",
+					"nintendo,flipper-si";
+			reg = <0x0d006400 0x100>;
+			interrupts = <3>;
+		};
+
+		audio@0c006c00 {
+			compatible = "nintendo,hollywood-ai",
+					"nintendo,flipper-ai";
+			reg = <0x0d006c00 0x20>;
+			interrupts = <6>;
+		};
+
+		/* External Interface bus */
+		exi@0d006800 {
+			compatible = "nintendo,hollywood-exi",
+					"nintendo,flipper-exi";
+			reg = <0x0d006800 0x40>;
+			virtual-reg = <0x0d006800>;
+			interrupts = <4>;
+		};
+
+		usb@0d040000 {
+			compatible = "nintendo,hollywood-usb-ehci",
+					"usb-ehci";
+			reg = <0x0d040000 0x100>;
+			interrupts = <4>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		usb@0d050000 {
+			compatible = "nintendo,hollywood-usb-ohci",
+					"usb-ohci";
+			reg = <0x0d050000 0x100>;
+			interrupts = <5>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		usb@0d060000 {
+			compatible = "nintendo,hollywood-usb-ohci",
+					"usb-ohci";
+			reg = <0x0d060000 0x100>;
+			interrupts = <6>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		sd@0d070000 {
+			compatible = "nintendo,hollywood-sdhci",
+					"sdhci";
+			reg = <0x0d070000 0x200>;
+			interrupts = <7>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		sdio@0d080000 {
+			compatible = "nintendo,hollywood-sdhci",
+					"sdhci";
+			reg = <0x0d080000 0x200>;
+			interrupts = <8>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		ipc@0d000000 {
+			compatible = "nintendo,hollywood-ipc";
+			reg = <0x0d000000 0x10>;
+			interrupts = <30>;
+			interrupt-parent = <&PIC1>;
+		};
+
+		PIC1: pic1@0d800030 {
+			#interrupt-cells = <1>;
+			compatible = "nintendo,hollywood-pic";
+			reg = <0x0d800030 0x10>;
+			interrupt-controller;
+			interrupts = <14>;
+		};
+
+		GPIO: gpio@0d8000c0 {
+			#gpio-cells = <2>;
+			compatible = "nintendo,hollywood-gpio";
+			reg = <0x0d8000c0 0x40>;
+			gpio-controller;
+
+			/*
+			 * This is commented out while a standard binding
+			 * for i2c over gpio is defined.
+			 */
+			/*
+			i2c-video {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			        compatible = "i2c-gpio";
+
+			        gpios = <&GPIO 15 0
+			                 &GPIO 14 0>;
+			        clock-frequency = <250000>;
+				no-clock-stretching;
+			        scl-is-open-drain;
+			        sda-is-open-drain;
+			        sda-enforce-dir;
+
+			        AVE: audio-video-encoder@70 {
+			                compatible = "nintendo,wii-audio-video-encoder";
+			                reg = <0x70>;
+			        };
+			};
+			*/
+		};
+
+		control@0d800100 {
+			compatible = "nintendo,hollywood-control";
+			reg = <0x0d800100 0x300>;
+		};
+
+		disk@0d806000 {
+			compatible = "nintendo,hollywood-di";
+			reg = <0x0d806000 0x40>;
+			interrupts = <2>;
+		};
+	};
+};
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/yosemite.dts linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/yosemite.dts
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/dts/yosemite.dts	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/dts/yosemite.dts	2010-02-24 13:52:17.000000000 -0500
@@ -282,20 +282,10 @@
 			/* Inbound 2GB range starting at 0 */
 			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
 
-			/* Bamboo has all 4 IRQ pins tied together per slot */
 			interrupt-map-mask = <0xf800 0x0 0x0 0x0>;
 			interrupt-map = <
-				/* IDSEL 1 */
-				0x800 0x0 0x0 0x0 &UIC0 0x1c 0x8
-
-				/* IDSEL 2 */
-				0x1000 0x0 0x0 0x0 &UIC0 0x1b 0x8
-
-				/* IDSEL 3 */
-				0x1800 0x0 0x0 0x0 &UIC0 0x1a 0x8
-
-				/* IDSEL 4 */
-				0x2000 0x0 0x0 0x0 &UIC0 0x19 0x8
+				/* IDSEL 12 */
+				0x6000 0x0 0x0 0x0 &UIC0 0x19 0x8
 			>;
 		};
 	};
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/gamecube.c linux-libre-2.6.33-gnu1/arch/powerpc/boot/gamecube.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/gamecube.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/gamecube.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+ * arch/powerpc/boot/gamecube.c
+ *
+ * Nintendo GameCube bootwrapper support
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 <stddef.h>
+#include "stdio.h"
+#include "types.h"
+#include "io.h"
+#include "ops.h"
+
+#include "ugecon.h"
+
+BSS_STACK(8192);
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
+{
+	u32 heapsize = 16*1024*1024 - (u32)_end;
+
+	simple_alloc_init(_end, heapsize, 32, 64);
+	fdt_init(_dtb_start);
+
+	if (ug_probe())
+		console_ops.write = ug_console_write;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/gamecube-head.S linux-libre-2.6.33-gnu1/arch/powerpc/boot/gamecube-head.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/gamecube-head.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/gamecube-head.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,111 @@
+/*
+ * arch/powerpc/boot/gamecube-head.S
+ *
+ * Nintendo GameCube bootwrapper entry.
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 "ppc_asm.h"
+
+/*
+ * The entry code does no assumptions regarding:
+ * - if the data and instruction caches are enabled or not
+ * - if the MMU is enabled or not
+ *
+ * We enable the caches if not already enabled, enable the MMU with an
+ * identity mapping scheme and jump to the start code.
+ */
+
+	.text
+
+	.globl _zimage_start
+_zimage_start:
+
+	/* turn the MMU off */
+	mfmsr	9
+	rlwinm	9, 9, 0, ~((1<<4)|(1<<5)) /* MSR_DR|MSR_IR */
+	bcl	20, 31, 1f
+1:
+	mflr	8
+	clrlwi	8, 8, 3		/* convert to a real address */
+	addi	8, 8, _mmu_off - 1b
+	mtsrr0	8
+	mtsrr1	9
+	rfi
+_mmu_off:
+	/* MMU disabled */
+
+	/* setup BATs */
+	isync
+	li      8, 0
+	mtspr	0x210, 8	/* IBAT0U */
+	mtspr	0x212, 8	/* IBAT1U */
+	mtspr	0x214, 8	/* IBAT2U */
+	mtspr	0x216, 8	/* IBAT3U */
+	mtspr	0x218, 8	/* DBAT0U */
+	mtspr	0x21a, 8	/* DBAT1U */
+	mtspr	0x21c, 8	/* DBAT2U */
+	mtspr	0x21e, 8	/* DBAT3U */
+
+	li	8, 0x01ff	/* first 16MiB */
+	li	9, 0x0002	/* rw */
+	mtspr	0x211, 9	/* IBAT0L */
+	mtspr	0x210, 8	/* IBAT0U */
+	mtspr	0x219, 9	/* DBAT0L */
+	mtspr	0x218, 8	/* DBAT0U */
+
+	lis	8, 0x0c00	/* I/O mem */
+	ori	8, 8, 0x3ff	/* 32MiB */
+	lis	9, 0x0c00
+	ori	9, 9, 0x002a	/* uncached, guarded, rw */
+	mtspr	0x21b, 9	/* DBAT1L */
+	mtspr	0x21a, 8	/* DBAT1U */
+
+	lis	8, 0x0100	/* next 8MiB */
+	ori	8, 8, 0x00ff	/* 8MiB */
+	lis	9, 0x0100
+	ori	9, 9, 0x0002	/* rw */
+	mtspr	0x215, 9	/* IBAT2L */
+	mtspr	0x214, 8	/* IBAT2U */
+	mtspr	0x21d, 9	/* DBAT2L */
+	mtspr	0x21c, 8	/* DBAT2U */
+
+	/* enable and invalidate the caches if not already enabled */
+	mfspr	8, 0x3f0	/* HID0 */
+	andi.	0, 8, (1<<15)		/* HID0_ICE */
+	bne	1f
+	ori	8, 8, (1<<15)|(1<<11)	/* HID0_ICE|HID0_ICFI*/
+1:
+	andi.	0, 8, (1<<14)		/* HID0_DCE */
+	bne	1f
+	ori	8, 8, (1<<14)|(1<<10)	/* HID0_DCE|HID0_DCFI*/
+1:
+	mtspr	0x3f0, 8	/* HID0 */
+	isync
+
+	/* initialize arguments */
+	li	3, 0
+	li	4, 0
+	li	5, 0
+
+	/* turn the MMU on */
+	bcl	20, 31, 1f
+1:
+	mflr	8
+	addi	8, 8, _mmu_on - 1b
+	mfmsr	9
+	ori	9, 9, (1<<4)|(1<<5) /* MSR_DR|MSR_IR */
+	mtsrr0	8
+	mtsrr1	9
+	sync
+	rfi
+_mmu_on:
+	b _zimage_start_lib
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/boot/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@ src-wlib := string.S crt0.S crtsavres.S
 		gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
 		4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
-		fsl-soc.c mpc8xx.c pq2.c
+		fsl-soc.c mpc8xx.c pq2.c ugecon.c
 src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
 		cuboot-ebony.c cuboot-hotfoot.c treeboot-ebony.c prpmc2800.c \
 		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
@@ -76,7 +76,8 @@ src-plat := of.c cuboot-52xx.c cuboot-82
 		cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
 		cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
 		virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
-		cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c
+		cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \
+		gamecube-head.S gamecube.c wii-head.S wii.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -254,6 +255,8 @@ image-$(CONFIG_KSI8560)			+= cuImage.ksi
 image-$(CONFIG_STORCENTER)		+= cuImage.storcenter
 image-$(CONFIG_MPC7448HPC2)		+= cuImage.mpc7448hpc2
 image-$(CONFIG_PPC_C2K)			+= cuImage.c2k
+image-$(CONFIG_GAMECUBE)		+= dtbImage.gamecube
+image-$(CONFIG_WII)			+= dtbImage.wii
 
 # Board port in arch/powerpc/platform/amigaone/Kconfig
 image-$(CONFIG_AMIGAONE)		+= cuImage.amigaone
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/ugecon.c linux-libre-2.6.33-gnu1/arch/powerpc/boot/ugecon.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/ugecon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/ugecon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,147 @@
+/*
+ * arch/powerpc/boot/ugecon.c
+ *
+ * USB Gecko bootwrapper console.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 <stddef.h>
+#include "stdio.h"
+#include "types.h"
+#include "io.h"
+#include "ops.h"
+
+
+#define EXI_CLK_32MHZ           5
+
+#define EXI_CSR                 0x00
+#define   EXI_CSR_CLKMASK       (0x7<<4)
+#define     EXI_CSR_CLK_32MHZ   (EXI_CLK_32MHZ<<4)
+#define   EXI_CSR_CSMASK        (0x7<<7)
+#define     EXI_CSR_CS_0        (0x1<<7)  /* Chip Select 001 */
+
+#define EXI_CR                  0x0c
+#define   EXI_CR_TSTART         (1<<0)
+#define   EXI_CR_WRITE		(1<<2)
+#define   EXI_CR_READ_WRITE     (2<<2)
+#define   EXI_CR_TLEN(len)      (((len)-1)<<4)
+
+#define EXI_DATA                0x10
+
+
+/* virtual address base for input/output, retrieved from device tree */
+static void *ug_io_base;
+
+
+static u32 ug_io_transaction(u32 in)
+{
+	u32 *csr_reg = ug_io_base + EXI_CSR;
+	u32 *data_reg = ug_io_base + EXI_DATA;
+	u32 *cr_reg = ug_io_base + EXI_CR;
+	u32 csr, data, cr;
+
+	/* select */
+	csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
+	out_be32(csr_reg, csr);
+
+	/* read/write */
+	data = in;
+	out_be32(data_reg, data);
+	cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
+	out_be32(cr_reg, cr);
+
+	while (in_be32(cr_reg) & EXI_CR_TSTART)
+		barrier();
+
+	/* deselect */
+	out_be32(csr_reg, 0);
+
+	data = in_be32(data_reg);
+	return data;
+}
+
+static int ug_is_txfifo_ready(void)
+{
+	return ug_io_transaction(0xc0000000) & 0x04000000;
+}
+
+static void ug_raw_putc(char ch)
+{
+	ug_io_transaction(0xb0000000 | (ch << 20));
+}
+
+static void ug_putc(char ch)
+{
+	int count = 16;
+
+	if (!ug_io_base)
+		return;
+
+	while (!ug_is_txfifo_ready() && count--)
+		barrier();
+	if (count >= 0)
+		ug_raw_putc(ch);
+}
+
+void ug_console_write(const char *buf, int len)
+{
+	char *b = (char *)buf;
+
+	while (len--) {
+		if (*b == '\n')
+			ug_putc('\r');
+		ug_putc(*b++);
+	}
+}
+
+static int ug_is_adapter_present(void)
+{
+	if (!ug_io_base)
+		return 0;
+	return ug_io_transaction(0x90000000) == 0x04700000;
+}
+
+static void *ug_grab_exi_io_base(void)
+{
+	u32 v;
+	void *devp;
+
+	devp = find_node_by_compatible(NULL, "nintendo,flipper-exi");
+	if (devp == NULL)
+		goto err_out;
+	if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+		goto err_out;
+
+	return (void *)v;
+
+err_out:
+	return NULL;
+}
+
+void *ug_probe(void)
+{
+	void *exi_io_base;
+	int i;
+
+	exi_io_base = ug_grab_exi_io_base();
+	if (!exi_io_base)
+		return NULL;
+
+	/* look for a usbgecko on memcard slots A and B */
+	for (i = 0; i < 2; i++) {
+		ug_io_base = exi_io_base + 0x14 * i;
+		if (ug_is_adapter_present())
+			break;
+	}
+	if (i == 2)
+		ug_io_base = NULL;
+	return ug_io_base;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/ugecon.h linux-libre-2.6.33-gnu1/arch/powerpc/boot/ugecon.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/ugecon.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/ugecon.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+/*
+ * arch/powerpc/boot/ugecon.h
+ *
+ * USB Gecko early bootwrapper console.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 __UGECON_H
+#define __UGECON_H
+
+extern void *ug_probe(void);
+
+extern void ug_putc(char ch);
+extern void ug_console_write(const char *buf, int len);
+
+#endif /* __UGECON_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/wii.c linux-libre-2.6.33-gnu1/arch/powerpc/boot/wii.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/wii.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/wii.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * arch/powerpc/boot/wii.c
+ *
+ * Nintendo Wii bootwrapper support
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 <stddef.h>
+#include "stdio.h"
+#include "types.h"
+#include "io.h"
+#include "ops.h"
+
+#include "ugecon.h"
+
+BSS_STACK(8192);
+
+#define HW_REG(x)		((void *)(x))
+
+#define EXI_CTRL		HW_REG(0x0d800070)
+#define EXI_CTRL_ENABLE		(1<<0)
+
+#define MEM2_TOP		(0x10000000 + 64*1024*1024)
+#define FIRMWARE_DEFAULT_SIZE	(12*1024*1024)
+
+
+struct mipc_infohdr {
+	char magic[3];
+	u8 version;
+	u32 mem2_boundary;
+	u32 ipc_in;
+	size_t ipc_in_size;
+	u32 ipc_out;
+	size_t ipc_out_size;
+};
+
+static int mipc_check_address(u32 pa)
+{
+	/* only MEM2 addresses */
+	if (pa < 0x10000000 || pa > 0x14000000)
+		return -EINVAL;
+	return 0;
+}
+
+static struct mipc_infohdr *mipc_get_infohdr(void)
+{
+	struct mipc_infohdr **hdrp, *hdr;
+
+	/* 'mini' header pointer is the last word of MEM2 memory */
+	hdrp = (struct mipc_infohdr **)0x13fffffc;
+	if (mipc_check_address((u32)hdrp)) {
+		printf("mini: invalid hdrp %08X\n", (u32)hdrp);
+		hdr = NULL;
+		goto out;
+	}
+
+	hdr = *hdrp;
+	if (mipc_check_address((u32)hdr)) {
+		printf("mini: invalid hdr %08X\n", (u32)hdr);
+		hdr = NULL;
+		goto out;
+	}
+	if (memcmp(hdr->magic, "IPC", 3)) {
+		printf("mini: invalid magic\n");
+		hdr = NULL;
+		goto out;
+	}
+
+out:
+	return hdr;
+}
+
+static int mipc_get_mem2_boundary(u32 *mem2_boundary)
+{
+	struct mipc_infohdr *hdr;
+	int error;
+
+	hdr = mipc_get_infohdr();
+	if (!hdr) {
+		error = -1;
+		goto out;
+	}
+
+	if (mipc_check_address(hdr->mem2_boundary)) {
+		printf("mini: invalid mem2_boundary %08X\n",
+		       hdr->mem2_boundary);
+		error = -EINVAL;
+		goto out;
+	}
+	*mem2_boundary = hdr->mem2_boundary;
+	error = 0;
+out:
+	return error;
+
+}
+
+static void platform_fixups(void)
+{
+	void *mem;
+	u32 reg[4];
+	u32 mem2_boundary;
+	int len;
+	int error;
+
+	mem = finddevice("/memory");
+	if (!mem)
+		fatal("Can't find memory node\n");
+
+	/* two ranges of (address, size) words */
+	len = getprop(mem, "reg", reg, sizeof(reg));
+	if (len != sizeof(reg)) {
+		/* nothing to do */
+		goto out;
+	}
+
+	/* retrieve MEM2 boundary from 'mini' */
+	error = mipc_get_mem2_boundary(&mem2_boundary);
+	if (error) {
+		/* if that fails use a sane value */
+		mem2_boundary = MEM2_TOP - FIRMWARE_DEFAULT_SIZE;
+	}
+
+	if (mem2_boundary > reg[2] && mem2_boundary < reg[2] + reg[3]) {
+		reg[3] = mem2_boundary - reg[2];
+		printf("top of MEM2 @ %08X\n", reg[2] + reg[3]);
+		setprop(mem, "reg", reg, sizeof(reg));
+	}
+
+out:
+	return;
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
+{
+	u32 heapsize = 24*1024*1024 - (u32)_end;
+
+	simple_alloc_init(_end, heapsize, 32, 64);
+	fdt_init(_dtb_start);
+
+	/*
+	 * 'mini' boots the Broadway processor with EXI disabled.
+	 * We need it enabled before probing for the USB Gecko.
+	 */
+	out_be32(EXI_CTRL, in_be32(EXI_CTRL) | EXI_CTRL_ENABLE);
+
+	if (ug_probe())
+		console_ops.write = ug_console_write;
+
+	platform_ops.fixups = platform_fixups;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/wii-head.S linux-libre-2.6.33-gnu1/arch/powerpc/boot/wii-head.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/wii-head.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/wii-head.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,142 @@
+/*
+ * arch/powerpc/boot/wii-head.S
+ *
+ * Nintendo Wii bootwrapper entry.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 "ppc_asm.h"
+
+/*
+ * The entry code does no assumptions regarding:
+ * - if the data and instruction caches are enabled or not
+ * - if the MMU is enabled or not
+ * - if the high BATs are enabled or not
+ *
+ * We enable the high BATs, enable the caches if not already enabled,
+ * enable the MMU with an identity mapping scheme and jump to the start code.
+ */
+
+	.text
+
+	.globl _zimage_start
+_zimage_start:
+
+	/* turn the MMU off */
+	mfmsr	9
+	rlwinm	9, 9, 0, ~((1<<4)|(1<<5)) /* MSR_DR|MSR_IR */
+	bcl	20, 31, 1f
+1:
+	mflr	8
+	clrlwi	8, 8, 3		/* convert to a real address */
+	addi	8, 8, _mmu_off - 1b
+	mtsrr0	8
+	mtsrr1	9
+	rfi
+_mmu_off:
+	/* MMU disabled */
+
+	/* setup BATs */
+	isync
+	li      8, 0
+	mtspr	0x210, 8	/* IBAT0U */
+	mtspr	0x212, 8	/* IBAT1U */
+	mtspr	0x214, 8	/* IBAT2U */
+	mtspr	0x216, 8	/* IBAT3U */
+	mtspr	0x218, 8	/* DBAT0U */
+	mtspr	0x21a, 8	/* DBAT1U */
+	mtspr	0x21c, 8	/* DBAT2U */
+	mtspr	0x21e, 8	/* DBAT3U */
+
+	mtspr	0x230, 8	/* IBAT4U */
+	mtspr	0x232, 8	/* IBAT5U */
+	mtspr	0x234, 8	/* IBAT6U */
+	mtspr	0x236, 8	/* IBAT7U */
+	mtspr	0x238, 8	/* DBAT4U */
+	mtspr	0x23a, 8	/* DBAT5U */
+	mtspr	0x23c, 8	/* DBAT6U */
+	mtspr	0x23e, 8	/* DBAT7U */
+
+	li	8, 0x01ff	/* first 16MiB */
+	li	9, 0x0002	/* rw */
+	mtspr	0x211, 9	/* IBAT0L */
+	mtspr	0x210, 8	/* IBAT0U */
+	mtspr	0x219, 9	/* DBAT0L */
+	mtspr	0x218, 8	/* DBAT0U */
+
+	lis	8, 0x0c00	/* I/O mem */
+	ori	8, 8, 0x3ff	/* 32MiB */
+	lis	9, 0x0c00
+	ori	9, 9, 0x002a	/* uncached, guarded, rw */
+	mtspr	0x21b, 9	/* DBAT1L */
+	mtspr	0x21a, 8	/* DBAT1U */
+
+	lis	8, 0x0100	/* next 8MiB */
+	ori	8, 8, 0x00ff	/* 8MiB */
+	lis	9, 0x0100
+	ori	9, 9, 0x0002	/* rw */
+	mtspr	0x215, 9	/* IBAT2L */
+	mtspr	0x214, 8	/* IBAT2U */
+	mtspr	0x21d, 9	/* DBAT2L */
+	mtspr	0x21c, 8	/* DBAT2U */
+
+	lis	8, 0x1000	/* MEM2 */
+	ori	8, 8, 0x07ff	/* 64MiB */
+	lis	9, 0x1000
+	ori	9, 9, 0x0002	/* rw */
+	mtspr	0x216, 8	/* IBAT3U */
+	mtspr	0x217, 9	/* IBAT3L */
+	mtspr	0x21e, 8	/* DBAT3U */
+	mtspr	0x21f, 9	/* DBAT3L */
+
+	/* enable the high BATs */
+	mfspr	8, 0x3f3	/* HID4 */
+	oris	8, 8, 0x0200
+	mtspr	0x3f3, 8	/* HID4 */
+
+	/* enable and invalidate the caches if not already enabled */
+	mfspr	8, 0x3f0	/* HID0 */
+	andi.	0, 8, (1<<15)		/* HID0_ICE */
+	bne	1f
+	ori	8, 8, (1<<15)|(1<<11)	/* HID0_ICE|HID0_ICFI*/
+1:
+	andi.	0, 8, (1<<14)		/* HID0_DCE */
+	bne	1f
+	ori	8, 8, (1<<14)|(1<<10)	/* HID0_DCE|HID0_DCFI*/
+1:
+	mtspr	0x3f0, 8	/* HID0 */
+	isync
+
+	/* initialize arguments */
+	li	3, 0
+	li	4, 0
+	li	5, 0
+
+	/* turn the MMU on */
+	bcl	20, 31, 1f
+1:
+	mflr	8
+	addi	8, 8, _mmu_on - 1b
+	mfmsr	9
+	ori	9, 9, (1<<4)|(1<<5) /* MSR_DR|MSR_IR */
+	mtsrr0	8
+	mtsrr1	9
+	sync
+	rfi
+_mmu_on:
+	/* turn on the front blue led (aka: yay! we got here!) */
+	lis	8, 0x0d00
+	ori	8, 8, 0x00c0
+	lwz	9, 0(8)
+	ori	9, 9, 0x20
+	stw	9, 0(8)
+
+	b _zimage_start_lib
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/boot/wrapper linux-libre-2.6.33-gnu1/arch/powerpc/boot/wrapper
--- linux-libre-2.6.32-gnu1/arch/powerpc/boot/wrapper	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/boot/wrapper	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,9 @@ gzip=.gz
 # cross-compilation prefix
 CROSS=
 
+# mkimage wrapper script
+MKIMAGE=$srctree/scripts/mkuboot.sh
+
 # directory for object and other files used by this script
 object=arch/powerpc/boot
 objbin=$object
@@ -230,6 +233,10 @@ xpedite52*)
     link_address='0x1400000'
     platformo=$object/cuboot-85xx.o
     ;;
+gamecube|wii)
+    link_address='0x600000'
+    platformo="$object/$platform-head.o $object/$platform.o"
+    ;;
 esac
 
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -263,7 +270,7 @@ membase=`${CROSS}objdump -p "$kernel" |
 case "$platform" in
 uboot)
     rm -f "$ofile"
-    mkimage -A ppc -O linux -T kernel -C gzip -a $membase -e $membase \
+    ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a $membase -e $membase \
 	$uboot_version -d "$vmz" "$ofile"
     if [ -z "$cacheit" ]; then
 	rm -f "$vmz"
@@ -323,7 +330,7 @@ coff)
     ;;
 cuboot*)
     gzip -f -9 "$ofile"
-    mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
+    ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
             $uboot_version -d "$ofile".gz "$ofile"
     ;;
 treeboot*)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/acadia_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/acadia_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/acadia_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/acadia_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:46 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:33:07 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -27,15 +28,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -49,11 +53,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -67,9 +75,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,31 +104,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -120,6 +149,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,8 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -140,19 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -166,6 +224,7 @@ CONFIG_CLASSIC_RCU=y
 CONFIG_ACADIA=y
 # CONFIG_EP405 is not set
 # CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
 # CONFIG_KILAUEA is not set
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
@@ -208,10 +267,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -227,10 +288,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -255,6 +318,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +336,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -316,6 +378,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -329,6 +392,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,8 +406,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -355,6 +425,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -367,9 +438,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -445,7 +516,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -461,6 +531,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -491,7 +562,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -512,6 +587,8 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -530,17 +607,18 @@ CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT=y
 CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -553,6 +631,7 @@ CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -598,6 +677,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -614,6 +694,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -636,27 +721,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -678,7 +749,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -689,14 +765,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -706,6 +785,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -760,7 +844,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -776,6 +859,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -790,11 +874,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -804,6 +890,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -812,16 +899,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -833,35 +927,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -877,13 +981,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -892,10 +999,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -923,11 +1032,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -964,6 +1075,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -972,5 +1084,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/ep405_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/ep405_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/ep405_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/ep405_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:48 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:37:34 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -27,15 +28,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -49,11 +53,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -67,9 +75,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,31 +104,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -120,6 +149,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,8 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -140,19 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -166,6 +224,7 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ACADIA is not set
 CONFIG_EP405=y
 # CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
 # CONFIG_KILAUEA is not set
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
@@ -210,10 +269,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -229,10 +290,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -257,6 +320,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -274,14 +338,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -318,6 +380,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -331,6 +394,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -343,8 +408,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -357,6 +427,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -369,9 +440,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -447,7 +518,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -463,6 +533,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -476,12 +547,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -501,7 +577,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -522,6 +602,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +622,10 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -548,6 +633,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -558,9 +644,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -570,6 +660,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -579,14 +670,14 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -608,6 +699,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -653,6 +745,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -669,6 +762,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -691,27 +789,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -748,14 +832,16 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PCI=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -775,11 +861,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -807,7 +893,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -822,6 +907,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -831,7 +917,12 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -842,14 +933,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -859,6 +953,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -913,7 +1012,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -927,8 +1025,48 @@ CONFIG_SUNRPC=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -943,11 +1081,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -957,6 +1097,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -965,16 +1106,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -986,35 +1134,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1030,13 +1188,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1045,10 +1206,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1076,11 +1239,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1117,6 +1282,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1125,5 +1291,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/hcu4_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/hcu4_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/hcu4_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/hcu4_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:50 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:45:11 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -27,15 +28,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -49,11 +53,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -67,9 +75,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,31 +104,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -120,6 +149,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,8 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -140,19 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -166,6 +224,7 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ACADIA is not set
 # CONFIG_EP405 is not set
 CONFIG_HCU4=y
+# CONFIG_HOTFOOT is not set
 # CONFIG_KILAUEA is not set
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
@@ -208,10 +267,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -227,10 +288,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -255,6 +318,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +336,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -316,6 +378,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -329,6 +392,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,8 +406,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -355,6 +425,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -367,9 +438,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -445,7 +516,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -461,6 +531,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -473,12 +544,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -498,7 +574,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -519,6 +599,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -537,7 +619,10 @@ CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -545,6 +630,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -555,9 +641,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -567,6 +657,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -576,14 +667,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -596,6 +686,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -641,6 +732,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -657,13 +749,17 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -680,27 +776,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -722,7 +804,12 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -733,14 +820,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -750,6 +840,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -804,7 +899,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -820,6 +914,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -834,11 +929,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -848,6 +945,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -856,16 +954,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -877,35 +982,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -921,13 +1036,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -936,10 +1054,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -967,11 +1087,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1008,6 +1130,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1016,5 +1139,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/kilauea_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/kilauea_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/kilauea_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/kilauea_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 13:28:37 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:51:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -29,7 +30,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -52,6 +55,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
@@ -79,11 +83,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -121,22 +127,21 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -144,6 +149,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -169,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -190,6 +224,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 # CONFIG_ACADIA is not set
 # CONFIG_EP405 is not set
 # CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
 CONFIG_KILAUEA=y
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
@@ -233,10 +268,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
 # CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -252,8 +288,7 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
@@ -343,6 +378,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -370,7 +406,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -383,6 +425,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -395,9 +438,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -498,6 +541,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -574,16 +618,17 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -596,6 +641,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -641,6 +687,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -656,6 +703,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -696,11 +744,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -709,10 +752,6 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -730,6 +769,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -753,6 +797,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -779,6 +824,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -790,7 +836,6 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
@@ -810,10 +855,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -821,6 +869,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -868,6 +917,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -889,7 +939,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -913,6 +965,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -920,6 +973,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -979,7 +1033,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1037,6 +1090,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1054,6 +1108,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1072,10 +1127,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1099,10 +1156,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_PPC_DISABLE_WERROR is not set
 CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1124,13 +1181,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1172,11 +1232,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/makalu_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/makalu_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/makalu_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/makalu_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc7
-# Wed Jun  3 09:11:02 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:55:12 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -29,14 +30,16 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +55,13 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -78,11 +83,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -108,7 +115,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -121,6 +127,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -129,7 +142,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -137,6 +149,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -149,7 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -157,14 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -178,6 +224,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 # CONFIG_ACADIA is not set
 # CONFIG_EP405 is not set
 # CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
 # CONFIG_KILAUEA is not set
 CONFIG_MAKALU=y
 # CONFIG_WALNUT is not set
@@ -220,10 +267,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -239,9 +288,8 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -330,6 +378,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -344,6 +393,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -356,7 +406,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -369,6 +425,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -381,9 +438,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -474,6 +531,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -504,14 +562,17 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -546,16 +607,18 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -568,6 +631,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -613,6 +677,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -629,6 +694,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -651,27 +721,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -695,6 +751,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -705,14 +765,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -770,7 +833,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -818,6 +880,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -827,6 +890,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -844,10 +908,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -859,11 +927,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -873,24 +942,26 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -910,13 +981,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -958,11 +1032,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/walnut_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/walnut_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/40x/walnut_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/40x/walnut_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:57 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:56:30 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -27,15 +28,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -49,11 +53,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -67,9 +75,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,31 +104,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -120,6 +149,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,8 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -140,19 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -166,6 +224,7 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ACADIA is not set
 # CONFIG_EP405 is not set
 # CONFIG_HCU4 is not set
+# CONFIG_HOTFOOT is not set
 # CONFIG_KILAUEA is not set
 # CONFIG_MAKALU is not set
 CONFIG_WALNUT=y
@@ -211,10 +270,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -230,10 +291,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -258,6 +321,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -275,14 +339,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -319,6 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -332,6 +395,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -344,8 +409,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -358,6 +428,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -370,9 +441,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -448,7 +519,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -464,6 +534,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -476,12 +547,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -501,7 +577,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -522,6 +602,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +622,10 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -548,6 +633,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -558,9 +644,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -570,6 +660,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -579,14 +670,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -599,6 +689,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -644,6 +735,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -660,6 +752,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -682,27 +779,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -727,7 +810,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -743,7 +826,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -754,14 +842,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -771,6 +862,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -825,7 +921,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -841,6 +936,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -855,11 +951,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -869,6 +967,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -877,16 +976,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -898,35 +1004,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -942,13 +1058,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -957,10 +1076,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -988,11 +1109,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1029,6 +1152,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1037,5 +1161,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/arches_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/arches_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/arches_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/arches_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc5
-# Thu Aug 13 14:14:07 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:02:35 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -33,7 +34,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -56,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
@@ -83,11 +87,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -121,22 +127,21 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -144,6 +149,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -169,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -198,6 +232,7 @@ CONFIG_ARCHES=y
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
 # CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -241,10 +276,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
 # CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -260,8 +296,7 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
@@ -352,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -379,7 +415,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -392,6 +434,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -404,9 +447,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -497,6 +540,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -573,16 +617,17 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -595,6 +640,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -640,6 +686,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -656,6 +703,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -696,11 +744,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -709,10 +752,6 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -730,6 +769,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -753,6 +797,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -779,6 +824,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -790,9 +836,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -810,10 +854,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -821,6 +868,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -858,6 +906,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -865,6 +914,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -934,7 +984,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -993,6 +1042,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1010,6 +1060,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1028,10 +1079,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1055,10 +1108,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_PPC_DISABLE_WERROR is not set
 CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1080,7 +1133,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/bamboo_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/bamboo_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/bamboo_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/bamboo_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:33 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:09:03 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,11 +57,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -71,9 +79,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -88,8 +108,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -99,19 +123,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -123,6 +153,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -134,8 +172,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,19 +180,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -176,6 +235,8 @@ CONFIG_BAMBOO=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -218,10 +279,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -237,10 +300,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -265,6 +331,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -282,14 +349,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -326,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -339,6 +405,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -351,8 +419,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -365,6 +438,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -386,6 +460,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -398,12 +473,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -423,7 +503,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -444,6 +528,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -462,7 +548,10 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -470,6 +559,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -480,9 +570,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -492,6 +586,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -501,14 +596,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -521,6 +615,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -566,6 +661,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -582,6 +678,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -604,27 +705,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -649,7 +736,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -665,7 +752,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -676,14 +768,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -693,6 +788,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -746,7 +846,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -762,6 +861,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -776,11 +876,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -790,6 +892,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -798,16 +901,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -819,35 +929,45 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -863,13 +983,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -878,10 +1001,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -909,11 +1034,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -950,6 +1077,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -958,5 +1086,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 17:27:20 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:12:20 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -33,7 +34,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -56,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
@@ -83,11 +87,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -121,22 +127,21 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -144,6 +149,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -169,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -198,6 +232,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 CONFIG_CANYONLANDS=y
 # CONFIG_GLACIER is not set
 # CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -241,10 +276,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
 # CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -260,8 +296,7 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
@@ -352,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -379,7 +415,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -392,6 +434,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -404,9 +447,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -508,6 +551,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -585,16 +629,18 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -616,6 +662,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -661,6 +708,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -676,6 +724,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -717,11 +766,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -730,10 +774,6 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -751,6 +791,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -774,6 +819,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -800,6 +846,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -811,9 +858,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -831,10 +876,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -842,6 +890,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -882,10 +931,12 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
@@ -993,6 +1044,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 CONFIG_RTC_DRV_M41T80=y
 # CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1014,7 +1066,9 @@ CONFIG_RTC_DRV_M41T80=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1038,6 +1092,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1045,6 +1100,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1104,7 +1160,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1201,6 +1256,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1218,6 +1274,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1236,10 +1293,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1263,10 +1322,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_PPC_DISABLE_WERROR is not set
 CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1288,7 +1347,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/ebony_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/ebony_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/ebony_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/ebony_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:36 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:20:46 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -19,6 +19,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -30,15 +31,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -70,9 +78,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,31 +107,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -123,6 +152,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -134,8 +171,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,19 +179,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -176,6 +234,8 @@ CONFIG_EBONY=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 # CONFIG_PPC44x_SIMPLE is not set
@@ -218,10 +278,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -237,10 +299,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -264,6 +329,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -281,14 +347,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -325,6 +389,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -338,6 +403,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -350,8 +417,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -364,6 +436,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -376,9 +449,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 CONFIG_MTD_OF_PARTS=y
@@ -453,7 +526,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -469,6 +541,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -481,12 +554,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -506,7 +584,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -527,6 +609,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -545,7 +629,10 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -553,6 +640,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -563,9 +651,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -575,6 +667,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -584,14 +677,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -604,6 +696,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -649,6 +742,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -665,6 +759,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -687,27 +786,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -732,7 +817,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -748,7 +833,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -759,14 +849,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -776,6 +869,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -840,7 +938,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -856,6 +953,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -871,11 +969,13 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -885,6 +985,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -893,16 +994,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -914,35 +1022,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -958,13 +1076,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -973,10 +1094,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1004,11 +1127,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1045,6 +1170,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/eiger_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/eiger_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/eiger_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/eiger_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc6
-# Wed Aug 19 13:06:50 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:33:04 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -34,7 +34,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -57,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
@@ -84,11 +87,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -122,22 +127,21 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -145,6 +149,8 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -170,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -243,10 +276,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
 # CONFIG_SWIOTLB is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -262,8 +296,7 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
@@ -358,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -387,14 +421,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -407,6 +438,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -419,9 +451,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -522,6 +554,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -573,8 +606,11 @@ CONFIG_SCSI_SAS_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -611,7 +647,10 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -682,7 +721,9 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -711,12 +752,11 @@ CONFIG_E1000E=y
 # CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -730,6 +770,7 @@ CONFIG_E1000E=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -775,6 +816,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -791,6 +833,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -831,11 +874,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -844,10 +882,6 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
@@ -865,7 +899,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -883,10 +916,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -894,6 +930,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -935,6 +972,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -942,6 +980,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1001,7 +1040,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1059,6 +1097,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1095,10 +1134,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1122,10 +1163,10 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_PPC_DISABLE_WERROR is not set
 CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1147,13 +1188,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
@@ -1197,11 +1241,13 @@ CONFIG_CRYPTO_XTS=y
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/katmai_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/katmai_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/katmai_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/katmai_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:38 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:55:34 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -19,6 +19,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -30,15 +31,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -70,9 +78,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -83,8 +103,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -94,19 +118,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -118,6 +148,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -129,8 +166,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -138,19 +174,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -171,6 +229,8 @@ CONFIG_KATMAI=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -212,10 +272,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -231,10 +293,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -259,6 +324,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -276,14 +342,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -320,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -333,6 +398,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -345,8 +412,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -359,6 +431,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -380,6 +453,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -392,12 +466,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -417,7 +496,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -440,6 +523,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -458,7 +543,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -466,6 +554,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -476,9 +565,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -488,6 +581,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -497,14 +591,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -517,6 +610,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -562,6 +656,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -578,13 +673,17 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -601,27 +700,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -646,7 +731,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -662,7 +747,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -673,14 +763,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -690,6 +783,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -743,7 +841,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -759,6 +856,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -773,11 +871,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -787,6 +887,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -795,16 +896,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -816,35 +924,43 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -859,13 +975,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -874,10 +993,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -905,11 +1026,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -946,6 +1069,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -954,5 +1078,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/rainier_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/rainier_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/rainier_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/rainier_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:41 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 14:59:12 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -19,6 +19,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -30,15 +31,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -70,9 +78,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,8 +107,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -98,19 +122,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -122,6 +152,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -133,8 +171,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -142,19 +179,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -175,6 +234,8 @@ CONFIG_RAINIER=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -216,10 +277,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -235,10 +298,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -263,6 +329,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -280,14 +347,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -324,6 +389,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -337,6 +403,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -349,8 +417,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -363,6 +436,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -375,9 +449,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -453,7 +527,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -469,6 +542,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -481,12 +555,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -506,7 +585,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -533,6 +616,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -543,9 +627,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -555,6 +643,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -564,14 +653,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -584,6 +672,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -629,6 +718,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -645,6 +735,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -667,27 +762,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -712,7 +793,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -728,7 +809,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -739,14 +825,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -756,6 +845,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -820,7 +914,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -836,6 +929,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -851,11 +945,13 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -865,6 +961,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -873,16 +970,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -894,35 +998,45 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -942,6 +1056,7 @@ CONFIG_PPC_EARLY_DEBUG=y
 CONFIG_PPC_EARLY_DEBUG_44x=y
 # CONFIG_PPC_EARLY_DEBUG_40x is not set
 # CONFIG_PPC_EARLY_DEBUG_CPM is not set
+# CONFIG_PPC_EARLY_DEBUG_USBGECKO is not set
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
 
@@ -951,13 +1066,16 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -966,10 +1084,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -997,11 +1117,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1038,6 +1160,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1046,5 +1169,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/redwood_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/redwood_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/redwood_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/redwood_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc3
-# Wed Feb  4 14:31:09 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:05:05 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,11 +57,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -71,6 +79,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
@@ -78,11 +87,13 @@ CONFIG_POSIX_MQUEUE=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -93,8 +104,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -104,19 +119,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -128,6 +149,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -139,8 +168,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,14 +176,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -177,6 +232,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
 CONFIG_REDWOOD=y
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -219,10 +275,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -238,10 +296,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -262,12 +323,15 @@ CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+# CONFIG_PCIEAER_INJECT is not set
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -285,14 +349,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -329,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -342,6 +405,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -354,13 +419,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -373,6 +438,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -385,9 +451,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -462,7 +528,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -479,6 +544,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -512,10 +578,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -533,23 +595,30 @@ CONFIG_SCSI_SAS_ATTRS=y
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 # CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
@@ -558,7 +627,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
@@ -569,8 +637,12 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_FUSION=y
@@ -586,7 +658,11 @@ CONFIG_FUSION_MAX_SGE=128
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -614,6 +690,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -632,7 +710,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -640,6 +721,7 @@ CONFIG_NETDEV_1000=y
 CONFIG_E1000E=y
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -650,19 +732,21 @@ CONFIG_E1000E=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -676,6 +760,7 @@ CONFIG_E1000E=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -721,6 +806,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -737,6 +823,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -777,11 +864,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -790,25 +872,23 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
 CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -826,31 +906,21 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -876,7 +946,12 @@ CONFIG_DMADEVICES=y
 #
 # DMA Devices
 #
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -887,14 +962,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -904,6 +982,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -958,7 +1041,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -974,6 +1056,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -988,11 +1071,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1002,6 +1087,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1010,16 +1096,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1031,35 +1124,45 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1075,13 +1178,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=y
@@ -1092,10 +1198,12 @@ CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=y
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 CONFIG_CRYPTO_CRYPTD=y
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1123,11 +1231,13 @@ CONFIG_CRYPTO_XTS=y
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=y
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1164,6 +1274,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1172,5 +1283,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/sam440ep_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/sam440ep_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/sam440ep_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/sam440ep_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:42 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:11:24 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,11 +57,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -71,9 +79,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_LOG_BUF_SHIFT=14
@@ -89,8 +109,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -99,19 +123,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -123,6 +153,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -134,8 +171,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,19 +179,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -176,6 +234,8 @@ CONFIG_SAM440EP=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 # CONFIG_PPC44x_SIMPLE is not set
@@ -218,10 +278,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -237,10 +299,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -264,6 +329,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -281,14 +347,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -325,6 +389,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -338,6 +403,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -350,8 +417,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -364,6 +436,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -385,6 +458,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -420,10 +494,6 @@ CONFIG_BLK_DEV_SR=y
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -440,8 +510,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 # CONFIG_SATA_PMP is not set
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
@@ -463,6 +535,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -488,14 +561,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -508,7 +583,11 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -529,6 +608,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -547,17 +628,19 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -580,6 +663,7 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -589,6 +673,7 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -605,25 +690,30 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
 CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -639,6 +729,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -676,6 +767,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -691,6 +783,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=y
@@ -733,11 +826,6 @@ CONFIG_I2C_IBM_IIC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -746,27 +834,23 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -784,31 +868,21 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -870,6 +944,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_ILI9320 is not set
@@ -899,7 +974,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -912,15 +986,18 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -933,10 +1010,11 @@ CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
 # CONFIG_HID_TOPSEED is not set
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -962,17 +1040,20 @@ CONFIG_USB_DEVICEFS=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PCI=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -992,11 +1073,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1038,7 +1119,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1054,6 +1134,7 @@ CONFIG_USB_STORAGE=m
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1090,9 +1171,11 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_M41T80_WDT=y
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1110,15 +1193,22 @@ CONFIG_RTC_DRV_M41T80_WDT=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
-# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_RTC_DRV_GENERIC is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1130,6 +1220,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -1142,10 +1233,13 @@ CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1155,6 +1249,11 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -1267,6 +1366,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1281,11 +1381,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1295,27 +1397,29 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_IRQSTACKS is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
@@ -1326,7 +1430,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/sequoia_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/sequoia_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/sequoia_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/sequoia_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29
-# Tue Apr  7 17:04:52 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:15:51 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,12 +57,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -72,6 +79,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
@@ -79,11 +87,13 @@ CONFIG_POSIX_MQUEUE=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -121,6 +131,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -129,7 +146,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -137,6 +153,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -149,7 +172,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -157,14 +180,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -186,6 +236,7 @@ CONFIG_SEQUOIA=y
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
 # CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -228,10 +279,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -247,9 +300,8 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
@@ -293,11 +345,11 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # Default settings for advanced configuration options are used
 #
 CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_LOWMEM_CAM_NUM=3
 CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
@@ -339,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -353,6 +406,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -365,7 +419,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -378,6 +438,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -390,9 +451,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -493,6 +554,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -515,6 +577,7 @@ CONFIG_MISC_DEVICES=y
 # EEPROM support
 #
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -534,14 +597,17 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -576,7 +642,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -584,6 +653,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -594,6 +664,9 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -619,12 +692,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -637,6 +709,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -682,6 +755,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -698,6 +772,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -720,27 +799,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -783,6 +848,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -793,14 +862,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -916,6 +988,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -925,6 +998,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -933,16 +1007,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -954,11 +1035,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -968,27 +1050,30 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1004,13 +1089,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1052,11 +1140,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/taishan_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/taishan_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/taishan_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/taishan_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:47 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:21:04 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -19,6 +19,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -30,15 +31,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -70,9 +78,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,8 +107,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -98,19 +122,25 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -122,6 +152,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -133,8 +171,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -142,19 +179,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -175,6 +234,8 @@ CONFIG_TAISHAN=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -216,10 +277,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -235,10 +298,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -263,6 +329,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -280,14 +347,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -324,6 +389,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -337,6 +403,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -349,8 +417,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -363,6 +436,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -375,9 +449,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_OF_PARTS is not set
@@ -453,7 +527,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -469,6 +542,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -481,12 +555,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -506,7 +585,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -529,6 +612,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -547,7 +632,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -555,6 +643,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -565,9 +654,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -577,6 +670,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -586,14 +680,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -606,6 +699,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -651,6 +745,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -667,6 +762,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -689,27 +789,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -734,7 +820,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -750,7 +836,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -761,14 +852,17 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -778,6 +872,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -832,7 +931,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -848,6 +946,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -862,11 +961,13 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -876,6 +977,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -884,16 +986,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -905,35 +1014,45 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -949,13 +1068,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -964,10 +1086,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -995,11 +1119,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1036,6 +1162,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1044,5 +1171,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/warp_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/warp_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/44x/warp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/44x/warp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Tue Jun  9 23:35:36 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 15:27:46 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
@@ -56,11 +60,13 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -81,11 +87,13 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -111,7 +119,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -124,6 +131,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -131,7 +145,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -139,6 +152,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -151,7 +171,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -159,14 +179,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -187,6 +234,7 @@ CONFIG_WARP=y
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
 # CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 # CONFIG_PPC44x_SIMPLE is not set
@@ -229,10 +277,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -248,9 +298,8 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
@@ -356,6 +405,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_IP_NF_ARPTABLES is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -371,6 +421,7 @@ CONFIG_VLAN_8021Q=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -383,7 +434,13 @@ CONFIG_VLAN_8021Q=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -396,6 +453,7 @@ CONFIG_VLAN_8021Q=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -407,9 +465,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -513,6 +571,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -524,9 +586,11 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_XILINX_SYSACE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -534,7 +598,9 @@ CONFIG_MISC_DEVICES=y
 #
 CONFIG_EEPROM_AT24=y
 # CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -557,15 +623,11 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 # CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_WAIT_SCAN is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
 # SCSI Transports
@@ -582,7 +644,6 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -609,14 +670,14 @@ CONFIG_IBM_NEW_EMAC_ZMII=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -678,6 +739,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -693,6 +755,7 @@ CONFIG_HW_RANDOM=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -725,17 +788,17 @@ CONFIG_I2C_IBM_IIC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
@@ -761,10 +824,19 @@ CONFIG_GPIO_SYSFS=y
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -787,6 +859,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -812,6 +885,8 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -821,7 +896,6 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
 CONFIG_THERMAL_HWMON=y
 CONFIG_WATCHDOG=y
@@ -855,26 +929,15 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -917,10 +980,11 @@ CONFIG_USB_MON=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -988,6 +1052,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
@@ -1014,7 +1079,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_WBSD is not set
-CONFIG_MMC_PIKASD=y
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
@@ -1025,9 +1091,10 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 # CONFIG_LEDS_GPIO_PLATFORM is not set
 CONFIG_LEDS_GPIO_OF=y
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -1048,6 +1115,10 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1065,10 +1136,13 @@ CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1145,7 +1219,6 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1235,6 +1308,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1244,6 +1318,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1261,10 +1336,14 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1276,11 +1355,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1290,27 +1370,30 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1326,13 +1409,16 @@ CONFIG_IRQSTACKS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 # CONFIG_CRYPTO_MANAGER is not set
@@ -1366,11 +1452,13 @@ CONFIG_CRYPTO_ALGAPI2=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:22 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 14:45:07 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -166,14 +169,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -189,6 +219,7 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
+# CONFIG_PPC_MPC5200_LPBFIFO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -243,6 +274,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -259,8 +291,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -273,6 +303,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -378,7 +409,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -489,6 +526,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -587,8 +628,8 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -643,6 +684,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -688,7 +730,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -735,11 +776,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -797,7 +840,6 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1137,6 +1179,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1180,7 +1223,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:24 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 14:45:09 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -86,6 +88,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -196,6 +226,7 @@ CONFIG_PPC_LITE5200=y
 # CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
+# CONFIG_PPC_MPC5200_LPBFIFO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -252,6 +283,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -268,8 +300,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -285,6 +315,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -398,7 +429,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -433,6 +470,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -443,6 +484,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -450,6 +492,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -502,7 +545,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -541,6 +586,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -596,15 +642,16 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -726,8 +773,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -741,6 +790,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -778,6 +828,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -836,11 +887,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -849,7 +895,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -884,11 +929,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1129,6 +1176,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1172,7 +1220,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:22 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 14:45:08 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -166,14 +169,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -189,6 +219,7 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
+# CONFIG_PPC_MPC5200_LPBFIFO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -244,6 +275,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -260,8 +292,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -274,6 +304,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -379,7 +410,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -490,6 +527,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -499,9 +540,11 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -610,8 +653,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -657,6 +699,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -700,7 +743,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -745,6 +787,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -805,11 +848,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -881,6 +926,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -902,7 +948,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1172,6 +1220,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1215,7 +1264,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:25 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 14:45:10 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -87,6 +89,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -172,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -195,6 +225,7 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
+# CONFIG_PPC_MPC5200_LPBFIFO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -251,6 +282,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -267,8 +299,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -385,7 +415,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -585,15 +621,16 @@ CONFIG_PATA_MPC52xx=m
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -673,8 +710,11 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -697,6 +737,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -734,6 +775,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -791,11 +833,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -804,7 +841,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -839,11 +875,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -908,7 +946,6 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_WHCI_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1011,6 +1048,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1032,7 +1070,9 @@ CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1243,10 +1283,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1269,7 +1310,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:23 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 14:45:09 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -171,14 +174,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -194,6 +224,7 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_MEDIA5200 is not set
 CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_MPC5200_GPIO is not set
+# CONFIG_PPC_MPC5200_LPBFIFO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -249,6 +280,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -265,8 +297,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -279,6 +309,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -384,7 +415,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -496,6 +533,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -607,8 +648,8 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -663,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -708,7 +750,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -753,6 +794,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -818,11 +860,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -880,7 +924,6 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -984,6 +1027,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1005,7 +1049,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1275,6 +1321,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1318,7 +1365,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:20 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:14 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +61,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_REDBOOT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -88,6 +90,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -174,14 +177,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -260,6 +290,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +307,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -530,6 +556,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -541,6 +571,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -548,6 +579,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -581,7 +613,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -668,8 +700,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -691,6 +726,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -700,6 +736,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -751,6 +788,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -807,11 +845,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -820,7 +853,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -866,6 +898,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -904,6 +937,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 CONFIG_THERMAL=y
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -942,11 +976,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -996,6 +1032,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1101,6 +1138,7 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1122,7 +1160,9 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1347,7 +1387,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1374,7 +1414,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/kmeter1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:21 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:14 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -89,6 +91,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -168,14 +171,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -253,6 +283,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -269,8 +300,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -384,7 +413,13 @@ CONFIG_LLC=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -512,6 +547,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -581,8 +620,7 @@ CONFIG_UCC_GETH=y
 # CONFIG_MV643XX_ETH is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -652,6 +690,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -697,7 +736,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -732,11 +770,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -933,7 +973,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -963,7 +1003,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_PPC_CLOCK is not set
 CONFIG_PPC_LIB_RHEAP=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:22 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:15 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -544,6 +570,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -555,6 +585,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -562,6 +593,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -615,7 +648,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -653,6 +688,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -680,7 +716,7 @@ CONFIG_MD_RAID1=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -805,8 +841,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -829,6 +868,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -838,6 +878,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -890,6 +931,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -947,11 +989,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -960,7 +997,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -975,6 +1011,8 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1022,6 +1060,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1062,6 +1101,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1099,6 +1139,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1106,6 +1147,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1173,6 +1216,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1287,15 +1331,17 @@ CONFIG_USB_NET2280=y
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
 # CONFIG_USB_AUDIO is not set
-CONFIG_USB_ETH=y
+CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_ETH_EEM is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1336,6 +1382,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1365,7 +1412,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1676,7 +1725,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:23 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:16 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -544,6 +570,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -555,6 +585,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -562,6 +593,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -615,7 +648,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -654,6 +689,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -709,15 +745,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -744,7 +781,7 @@ CONFIG_MD_RAID1=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -869,8 +906,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -893,6 +933,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -902,6 +943,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -954,6 +996,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1011,11 +1054,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1024,7 +1062,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1039,6 +1076,8 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1086,6 +1125,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1126,6 +1166,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1163,6 +1204,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1170,6 +1212,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1237,6 +1281,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1351,15 +1396,17 @@ CONFIG_USB_NET2280=y
 CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
 # CONFIG_USB_AUDIO is not set
-CONFIG_USB_ETH=y
+CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_ETH_EEM is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1400,6 +1447,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1429,7 +1477,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1740,7 +1790,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:24 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:17 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -260,6 +290,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +307,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -444,6 +470,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -454,6 +484,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -461,6 +492,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -513,7 +545,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -551,6 +585,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -568,7 +603,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -675,8 +710,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -690,6 +727,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -699,6 +737,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -751,6 +790,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -807,11 +847,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -820,7 +855,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -866,6 +900,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -904,6 +939,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -936,11 +972,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1023,6 +1061,7 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1044,7 +1083,9 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1220,7 +1261,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1247,7 +1288,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:24 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:18 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -260,6 +290,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +307,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -445,6 +471,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -456,6 +486,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -463,6 +494,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -474,6 +507,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_CB710_CORE is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -516,7 +550,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -554,6 +590,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -571,7 +608,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -680,8 +717,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -704,6 +744,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -713,6 +754,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -766,6 +808,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -825,11 +868,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -838,7 +876,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -852,6 +889,8 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -899,6 +938,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -939,6 +979,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -976,6 +1017,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -983,6 +1025,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1050,6 +1094,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1387,7 +1432,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1414,7 +1459,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:25 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:19 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -528,6 +554,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -539,6 +569,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -546,6 +577,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -647,7 +680,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -686,6 +721,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -741,15 +777,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -777,7 +814,7 @@ CONFIG_MD_RAID1=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -860,8 +897,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -884,6 +924,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -925,6 +966,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -982,11 +1024,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -995,7 +1032,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1009,6 +1045,8 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1062,6 +1100,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1069,6 +1108,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1117,6 +1158,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1235,6 +1277,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1264,7 +1307,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1485,7 +1530,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1512,7 +1557,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:26 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:20 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -528,6 +554,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -539,6 +569,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -546,6 +577,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -599,7 +632,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -637,6 +672,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -654,7 +690,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -737,8 +773,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -761,6 +800,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -802,6 +842,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -859,11 +900,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -872,7 +908,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -886,6 +921,8 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -939,6 +976,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -946,6 +984,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +1034,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1112,6 +1153,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1141,7 +1183,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1362,7 +1406,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1389,7 +1433,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:27 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:21 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -443,6 +469,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -453,6 +483,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -460,6 +491,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -493,7 +525,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -616,8 +648,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -630,6 +664,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -639,6 +674,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -690,6 +726,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -745,11 +782,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -758,7 +790,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -804,6 +835,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -842,6 +874,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -874,11 +907,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -961,6 +996,7 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -982,7 +1018,9 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1156,7 +1194,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1183,7 +1221,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:28 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:21 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +176,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -258,6 +288,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -274,8 +305,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -402,9 +431,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -525,6 +551,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -535,6 +565,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -542,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -594,7 +626,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -632,6 +666,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -649,7 +684,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -756,8 +791,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -771,6 +808,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -780,6 +818,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -832,6 +871,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -888,11 +928,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -901,7 +936,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -947,6 +981,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -985,6 +1020,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1017,11 +1053,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1104,6 +1142,7 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1125,7 +1164,9 @@ CONFIG_RTC_DRV_DS1374=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1302,7 +1343,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1329,7 +1370,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:30 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +61,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -88,6 +90,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -174,14 +177,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -258,6 +288,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -274,8 +305,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +433,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -539,6 +565,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -549,6 +579,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -556,6 +587,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -590,7 +623,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -657,8 +690,10 @@ CONFIG_UCC_GETH=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -671,6 +706,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -680,6 +716,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -737,6 +774,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -795,11 +833,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -808,7 +841,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -823,6 +855,8 @@ CONFIG_SPI_MASTER=y
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_GPIO is not set
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -854,6 +888,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -903,6 +938,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -910,6 +946,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1199,7 +1237,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1230,6 +1268,7 @@ CONFIG_PPC_EARLY_DEBUG=y
 # CONFIG_PPC_EARLY_DEBUG_44x is not set
 # CONFIG_PPC_EARLY_DEBUG_40x is not set
 # CONFIG_PPC_EARLY_DEBUG_CPM is not set
+# CONFIG_PPC_EARLY_DEBUG_USBGECKO is not set
 
 #
 # Security options
@@ -1237,7 +1276,11 @@ CONFIG_PPC_EARLY_DEBUG=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:29 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -174,14 +177,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -443,6 +469,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -453,6 +483,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -460,6 +491,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -512,7 +544,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -551,6 +585,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -606,15 +641,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -631,7 +667,7 @@ CONFIG_ATA_SFF=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -736,8 +772,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -751,6 +789,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -760,6 +799,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -811,6 +851,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -868,11 +909,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -881,7 +917,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -927,6 +962,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -965,6 +1001,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -997,11 +1034,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1226,7 +1265,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1253,7 +1292,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:30 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -174,14 +177,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -259,6 +289,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -398,9 +427,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -438,6 +464,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -449,6 +479,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -456,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -507,7 +539,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -546,6 +580,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -601,15 +636,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -638,7 +674,7 @@ CONFIG_MD_RAID6_PQ=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -725,8 +761,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -749,6 +788,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -758,6 +798,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -809,6 +850,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -867,11 +909,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -880,7 +917,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -926,6 +962,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -964,6 +1001,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1001,11 +1039,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1097,6 +1137,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1385,7 +1426,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1412,7 +1453,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:31 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -172,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -257,6 +287,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -273,8 +304,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -401,9 +430,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -524,6 +550,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -535,6 +565,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -542,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -604,7 +636,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -691,8 +723,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -715,6 +750,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -724,6 +760,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -775,6 +812,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -833,11 +871,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -846,7 +879,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -892,6 +924,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -930,6 +963,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -967,11 +1001,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1039,6 +1075,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1321,7 +1358,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1348,7 +1385,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:32 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:26 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -169,14 +173,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -185,7 +216,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -204,6 +235,7 @@ CONFIG_KSI8560=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -248,6 +280,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -264,8 +297,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -385,9 +416,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -503,6 +531,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -603,8 +635,7 @@ CONFIG_GIANFAR=y
 # CONFIG_MV643XX_ETH is not set
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -624,6 +655,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -669,6 +701,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1051,7 +1084,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:33 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:27 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -170,14 +174,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -186,7 +217,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 CONFIG_MPC8540_ADS=y
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -205,6 +236,7 @@ CONFIG_MPC8540_ADS=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -249,6 +281,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -265,8 +298,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -386,9 +417,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -423,6 +451,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -500,8 +532,7 @@ CONFIG_GIANFAR=y
 # CONFIG_MV643XX_ETH is not set
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -521,6 +552,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -570,6 +602,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -920,7 +953,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:34 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:28 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,14 +177,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -189,7 +220,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 CONFIG_MPC8560_ADS=y
 # CONFIG_MPC85xx_CDS is not set
@@ -208,6 +239,7 @@ CONFIG_MPC8560_ADS=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -252,6 +284,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -268,8 +301,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -398,9 +429,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -440,6 +468,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -485,7 +517,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -594,8 +626,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -608,6 +642,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -617,6 +652,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -664,6 +700,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -705,6 +742,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1054,7 +1092,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:35 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:29 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -171,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -187,7 +218,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 CONFIG_MPC85xx_CDS=y
@@ -206,6 +237,7 @@ CONFIG_MPC85xx_CDS=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -250,6 +282,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -266,8 +299,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -396,9 +427,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -437,6 +465,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -537,7 +569,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -642,8 +674,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -656,6 +690,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -665,6 +700,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -717,6 +753,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1079,7 +1116,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:36 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:29 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -169,14 +173,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -185,7 +216,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -204,6 +235,7 @@ CONFIG_MPC85xx=y
 # CONFIG_TQM8560 is not set
 CONFIG_SBC8548=y
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -247,6 +279,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -263,8 +296,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -392,9 +423,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -431,6 +459,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -476,7 +508,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -581,8 +613,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -595,6 +629,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -604,6 +639,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -656,6 +692,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -889,7 +926,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -915,7 +952,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:37 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:30 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -169,14 +173,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -185,7 +216,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -204,6 +235,7 @@ CONFIG_MPC85xx=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 CONFIG_SBC8560=y
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -247,6 +279,7 @@ CONFIG_BINFMT_MISC=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -263,8 +296,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -384,9 +415,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -421,6 +449,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -498,8 +530,7 @@ CONFIG_GIANFAR=y
 # CONFIG_MV643XX_ETH is not set
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -519,6 +550,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -568,6 +600,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -702,7 +735,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -948,6 +983,7 @@ CONFIG_PPC_EARLY_DEBUG=y
 # CONFIG_PPC_EARLY_DEBUG_44x is not set
 # CONFIG_PPC_EARLY_DEBUG_40x is not set
 # CONFIG_PPC_EARLY_DEBUG_CPM is not set
+# CONFIG_PPC_EARLY_DEBUG_USBGECKO is not set
 
 #
 # Security options
@@ -955,7 +991,11 @@ CONFIG_PPC_EARLY_DEBUG=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/socrates_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/socrates_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:37 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -174,14 +178,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -190,7 +221,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -209,6 +240,7 @@ CONFIG_SOCRATES=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -252,6 +284,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -268,8 +301,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,9 +435,6 @@ CONFIG_CAN_BCM=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -540,6 +568,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -551,6 +583,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -558,6 +591,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -621,7 +656,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -710,8 +745,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -734,6 +772,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -743,6 +782,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -768,6 +808,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
 # CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
@@ -826,6 +867,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -883,11 +925,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -896,7 +933,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -910,6 +946,8 @@ CONFIG_SPI_MASTER=y
 #
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_MPC8xxx is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -957,6 +995,7 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -997,6 +1036,7 @@ CONFIG_SENSORS_W83781D=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1015,6 +1055,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1022,6 +1063,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1192,6 +1235,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1318,6 +1362,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1347,7 +1392,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1574,7 +1621,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1600,7 +1647,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:38 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:32 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -178,14 +182,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -194,7 +225,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -213,6 +244,7 @@ CONFIG_STX_GP3=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -257,6 +289,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -273,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -463,9 +494,6 @@ CONFIG_NET_PKTGEN=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -513,6 +541,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -523,6 +555,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -530,6 +563,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -633,7 +667,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -673,6 +709,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -690,7 +727,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -797,8 +834,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -813,6 +852,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -822,6 +862,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -881,6 +922,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -905,6 +947,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -970,11 +1013,6 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -983,7 +1021,6 @@ CONFIG_I2C_ALGOBIT=m
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1016,6 +1053,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1058,6 +1096,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1097,6 +1136,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1115,7 +1155,6 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
@@ -1465,7 +1504,11 @@ CONFIG_BDI_SWITCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:39 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:33 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -169,14 +173,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -185,7 +216,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -204,6 +235,7 @@ CONFIG_TQM8540=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -248,6 +280,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -264,8 +297,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -391,9 +422,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -510,6 +538,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -520,6 +552,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -527,6 +560,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -615,7 +649,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -738,8 +772,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -752,6 +788,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -761,6 +798,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -813,6 +851,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -871,11 +910,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -883,7 +917,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -929,6 +962,7 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -967,6 +1001,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -985,11 +1020,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1220,7 +1257,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1246,7 +1283,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:40 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:34 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -171,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -187,7 +218,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -206,6 +237,7 @@ CONFIG_TQM8541=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -251,6 +283,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -267,8 +300,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -394,9 +425,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -514,6 +542,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -524,6 +556,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -531,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -619,7 +653,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -743,8 +777,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -757,6 +793,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -766,6 +803,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -820,6 +858,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -881,11 +920,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -893,7 +927,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -925,6 +958,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -967,6 +1001,7 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1006,6 +1041,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1025,11 +1061,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1260,7 +1298,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1286,7 +1324,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:41 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:35 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -177,14 +181,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -193,7 +224,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -212,6 +243,7 @@ CONFIG_TQM8548=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -257,6 +289,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -273,8 +306,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -406,7 +437,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -535,6 +572,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -545,6 +586,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -552,6 +594,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -585,7 +628,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -690,8 +733,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -704,6 +749,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -713,6 +759,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -765,6 +812,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -820,11 +868,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -833,7 +876,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -879,6 +921,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -917,6 +960,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -935,11 +979,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1003,6 +1049,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1024,7 +1071,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1280,7 +1329,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:42 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:36 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -171,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -187,7 +218,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -206,6 +237,7 @@ CONFIG_TQM8555=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -251,6 +283,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -267,8 +300,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -394,9 +425,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -514,6 +542,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -524,6 +556,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -531,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -619,7 +653,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -743,8 +777,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -757,6 +793,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -766,6 +803,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -820,6 +858,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -881,11 +920,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -893,7 +927,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -925,6 +958,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -967,6 +1001,7 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1006,6 +1041,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1025,11 +1061,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1260,7 +1298,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1286,7 +1324,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:43 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:36 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -89,6 +92,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -171,14 +175,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -187,7 +218,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -206,6 +237,7 @@ CONFIG_MPC85xx=y
 CONFIG_TQM8560=y
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -251,6 +283,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -267,8 +300,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -394,9 +425,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -514,6 +542,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -524,6 +556,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -531,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -619,7 +653,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -743,8 +777,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -757,6 +793,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -766,6 +803,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -820,6 +858,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -881,11 +920,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -893,7 +927,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -925,6 +958,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -967,6 +1001,7 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1006,6 +1041,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1025,11 +1061,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1260,7 +1298,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1286,7 +1324,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:44 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:37 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -40,6 +40,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -63,6 +64,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -93,6 +96,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -181,14 +185,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 CONFIG_PPC_MSI_BITMAP=y
 
@@ -198,7 +229,7 @@ CONFIG_PPC_MSI_BITMAP=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 # CONFIG_MPC8540_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC85xx_CDS is not set
@@ -217,6 +248,7 @@ CONFIG_XES_MPC85xx=y
 # CONFIG_TQM8560 is not set
 # CONFIG_SBC8548 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -261,6 +293,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -277,8 +310,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -404,6 +435,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -441,7 +473,13 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -576,6 +614,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -587,6 +629,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -594,6 +637,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -646,7 +690,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -685,6 +731,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -740,15 +787,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -765,7 +813,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -852,8 +900,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -876,6 +927,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -885,6 +937,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -914,6 +967,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -950,6 +1004,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1007,11 +1062,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1020,7 +1070,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1053,6 +1102,7 @@ CONFIG_GPIO_PCA953X=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1095,6 +1145,7 @@ CONFIG_SENSORS_DS1621=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1134,6 +1185,7 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1172,11 +1224,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1368,6 +1422,7 @@ CONFIG_LEDS_GPIO_OF=y
 # CONFIG_LEDS_LP3944 is not set
 CONFIG_LEDS_PCA955X=y
 # CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -1391,7 +1446,6 @@ CONFIG_EDAC=y
 #
 # CONFIG_EDAC_DEBUG is not set
 CONFIG_EDAC_MM_EDAC=y
-CONFIG_EDAC_MPC85XX=y
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1420,6 +1474,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1441,7 +1496,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1772,7 +1829,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:49 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:43 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -91,6 +94,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -181,14 +185,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -218,7 +249,7 @@ CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
 # CONFIG_PPC_RTAS is not set
-# CONFIG_MMIO_NVRAM is not set
+CONFIG_MMIO_NVRAM=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
@@ -259,6 +290,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +307,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -314,7 +344,6 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
 # CONFIG_PCMCIA_IOCTL is not set
@@ -414,6 +443,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -451,7 +481,13 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -570,6 +606,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -581,6 +621,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -588,6 +629,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
 #
@@ -689,7 +731,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -728,6 +772,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
@@ -785,15 +830,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -810,7 +856,7 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -897,8 +943,14 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -937,6 +989,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -946,6 +999,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -1005,6 +1059,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -1070,11 +1125,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1083,7 +1133,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-CONFIG_DS1682=y
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1115,6 +1164,7 @@ CONFIG_GPIO_SYSFS=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1157,6 +1207,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1196,6 +1247,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1235,11 +1287,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1338,6 +1392,7 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1464,6 +1519,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 CONFIG_RTC_DRV_RX8581=y
@@ -1485,7 +1541,9 @@ CONFIG_RTC_DRV_RX8581=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1710,7 +1768,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1737,7 +1795,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:47 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:41 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -91,6 +94,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -181,14 +185,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -218,7 +249,7 @@ CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
 # CONFIG_PPC_RTAS is not set
-# CONFIG_MMIO_NVRAM is not set
+CONFIG_MMIO_NVRAM=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
@@ -259,6 +290,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -275,8 +307,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -314,7 +344,6 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
 # CONFIG_PCMCIA_IOCTL is not set
@@ -414,6 +443,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -451,7 +481,13 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -570,6 +606,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -581,6 +621,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -588,6 +629,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
 #
@@ -689,7 +731,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -728,6 +772,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
@@ -753,7 +798,7 @@ CONFIG_SATA_SIL24=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -840,8 +885,14 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -880,6 +931,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -889,6 +941,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -948,6 +1001,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -1013,11 +1067,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1026,7 +1075,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-CONFIG_DS1682=y
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1058,6 +1106,7 @@ CONFIG_GPIO_SYSFS=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1100,6 +1149,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1139,6 +1189,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1178,11 +1229,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1281,6 +1334,7 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1407,6 +1461,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 CONFIG_RTC_DRV_RX8581=y
@@ -1428,7 +1483,9 @@ CONFIG_RTC_DRV_RX8581=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1653,7 +1710,7 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1680,7 +1737,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:48 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:42 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -91,6 +94,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -182,14 +186,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -219,7 +250,7 @@ CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
 # CONFIG_PPC_RTAS is not set
-# CONFIG_MMIO_NVRAM is not set
+CONFIG_MMIO_NVRAM=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
@@ -260,6 +291,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +308,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -400,6 +430,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -588,9 +619,6 @@ CONFIG_NET_PKTGEN=m
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -719,6 +747,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -730,6 +762,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -737,6 +770,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
 #
@@ -789,7 +823,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -828,6 +864,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -883,15 +920,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -908,7 +946,7 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -995,8 +1033,11 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -1050,6 +1091,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -1059,6 +1101,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -1117,6 +1160,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -1124,7 +1168,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_NVRAM is not set
+CONFIG_NVRAM=y
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1174,11 +1218,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1187,7 +1226,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-CONFIG_DS1682=y
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1220,6 +1258,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1262,6 +1301,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1301,6 +1341,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1340,11 +1381,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1443,6 +1486,7 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1570,6 +1614,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 CONFIG_RTC_DRV_RX8581=y
@@ -1591,7 +1636,9 @@ CONFIG_RTC_DRV_RX8581=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1891,9 +1938,12 @@ CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
 # CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
 # CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:45 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:39 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -176,14 +180,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -254,6 +285,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -270,8 +302,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -382,6 +412,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -420,9 +451,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -555,6 +583,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -565,6 +597,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -572,6 +605,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -671,7 +705,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -710,6 +746,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -765,15 +802,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -790,7 +828,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -838,8 +876,10 @@ CONFIG_ULI526X=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -853,6 +893,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -862,6 +903,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -891,6 +933,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -927,6 +970,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -981,11 +1025,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -994,7 +1033,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1029,11 +1067,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1163,6 +1203,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1282,6 +1323,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1303,7 +1345,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1606,7 +1650,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:46 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +61,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -90,6 +93,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -182,14 +186,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -260,6 +291,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +308,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -395,6 +425,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -439,9 +470,6 @@ CONFIG_SCTP_HMAC_MD5=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -483,6 +511,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -494,6 +526,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -501,6 +534,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -554,7 +588,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -593,6 +629,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -648,15 +685,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -673,7 +711,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -778,8 +816,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -802,6 +843,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -811,6 +853,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -840,6 +883,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -876,6 +920,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -932,11 +977,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -945,7 +985,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -980,11 +1019,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1059,6 +1100,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1186,6 +1228,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1312,6 +1355,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1333,7 +1377,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1648,7 +1694,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:45 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:38 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -90,6 +93,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -162,6 +166,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y
 #
 # CONFIG_GCOV_KERNEL is not set
 CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -182,14 +187,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -260,6 +292,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -276,8 +309,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -399,6 +430,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -587,9 +619,6 @@ CONFIG_NET_PKTGEN=m
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -717,6 +746,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -727,6 +760,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -734,6 +768,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -786,7 +821,7 @@ CONFIG_DM_ZERO=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -873,8 +908,10 @@ CONFIG_GIANFAR=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -918,6 +955,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -927,6 +965,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -985,6 +1024,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1042,11 +1082,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1055,7 +1090,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1101,6 +1135,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1139,6 +1174,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1171,11 +1207,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1281,7 +1319,6 @@ CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_STATS=y
 CONFIG_OCFS2_DEBUG_MASKLOG=y
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_FS_POSIX_ACL is not set
 # CONFIG_BTRFS_FS is not set
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
@@ -1556,8 +1593,12 @@ CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
 # CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/adder875_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/adder875_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/adder875_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/adder875_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:04 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:23:58 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -55,6 +56,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_REDBOOT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -82,6 +84,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -161,14 +164,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -242,6 +272,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -258,8 +289,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -373,9 +402,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -546,8 +572,7 @@ CONFIG_FS_ENET_MDIO_FEC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -567,6 +592,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -615,6 +641,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -637,6 +664,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -898,6 +926,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -943,7 +972,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/c2k_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/c2k_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/c2k_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/c2k_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:05 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:23:59 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -92,6 +94,7 @@ CONFIG_AUDIT_TREE=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -173,6 +176,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y
 #
 # CONFIG_GCOV_KERNEL is not set
 CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -192,14 +196,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -224,6 +255,8 @@ CONFIG_EMBEDDED6xx=y
 # CONFIG_PPC_PRPMC2800 is not set
 CONFIG_PPC_C2K=y
 CONFIG_MV64X60=y
+# CONFIG_GAMECUBE is not set
+# CONFIG_WII is not set
 # CONFIG_AMIGAONE is not set
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
@@ -286,6 +319,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -296,14 +330,12 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -316,6 +348,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -424,6 +457,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -687,10 +721,6 @@ CONFIG_BT_HCIVHCI=m
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -773,7 +803,6 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_PCI is not set
-# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -817,6 +846,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -870,7 +903,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 CONFIG_BLK_DEV_3W_XXXX_RAID=m
+# CONFIG_SCSI_HPSA is not set
 CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_3W_SAS is not set
 CONFIG_SCSI_ACARD=m
 CONFIG_SCSI_AACRAID=m
 CONFIG_SCSI_AIC7XXX=m
@@ -925,6 +960,7 @@ CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -942,7 +978,7 @@ CONFIG_SCSI_LPFC=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -1027,8 +1063,11 @@ CONFIG_MV643XX_ETH=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -1054,6 +1093,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETPOLL=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -1063,6 +1103,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -1121,8 +1162,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 # CONFIG_NOZOMI is not set
 
@@ -1140,6 +1179,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -1200,11 +1240,6 @@ CONFIG_I2C_MV64XXX=m
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1213,7 +1248,6 @@ CONFIG_I2C_MV64XXX=m
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1259,6 +1293,7 @@ CONFIG_SENSORS_GL518SM=m
 # CONFIG_SENSORS_GL520SM is not set
 CONFIG_SENSORS_IT87=m
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM77=m
 CONFIG_SENSORS_LM78=m
@@ -1297,6 +1332,7 @@ CONFIG_SENSORS_W83L785TS=m
 # CONFIG_SENSORS_W83L786NG is not set
 CONFIG_SENSORS_W83627HF=m
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1333,7 +1369,6 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
@@ -1392,6 +1427,7 @@ CONFIG_USB_MON=m
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
@@ -1923,7 +1959,6 @@ CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
 # CONFIG_SECURITY_PATH is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_LSM_MMAP_MIN_ADDR=65536
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
@@ -1934,6 +1969,11 @@ CONFIG_SECURITY_SELINUX_AVC_STATS=y
 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
 # CONFIG_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_SELINUX=y
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_DAC is not set
+CONFIG_DEFAULT_SECURITY="selinux"
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ep8248e_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep8248e_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ep8248e_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep8248e_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:06 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:23:59 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -160,14 +163,41 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -237,6 +267,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -249,8 +280,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -400,9 +429,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_BT is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -523,6 +549,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -553,7 +583,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -658,8 +688,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -670,6 +701,7 @@ CONFIG_WLAN=y
 # CONFIG_SLIP is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -705,6 +737,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -741,6 +774,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1061,7 +1095,11 @@ CONFIG_BDI_SWITCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ep88xc_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep88xc_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ep88xc_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ep88xc_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:07 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:00 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -54,6 +55,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -81,6 +83,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -159,14 +162,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -241,6 +271,7 @@ CONFIG_8XX_MINIMAL_FPEMU=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -257,8 +288,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -372,9 +401,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -545,8 +571,7 @@ CONFIG_FS_ENET_MDIO_FEC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -591,6 +616,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -851,6 +877,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -893,7 +920,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/g5_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/g5_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/g5_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/g5_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -757,7 +757,7 @@ CONFIG_SUNGEM=y
 # CONFIG_B44 is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -794,8 +794,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/gamecube_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/gamecube_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/gamecube_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/gamecube_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1061 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Sun Nov 22 21:07:30 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_PPC_BOOK3S_32=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-gcn"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_LINKSTATION is not set
+# CONFIG_STORCENTER is not set
+# CONFIG_MPC7448HPC2 is not set
+# CONFIG_PPC_HOLLY is not set
+# CONFIG_PPC_PRPMC2800 is not set
+# CONFIG_PPC_C2K is not set
+CONFIG_GAMECUBE_COMMON=y
+CONFIG_USBGECKO_UDBG=y
+CONFIG_FLIPPER_PIC=y
+CONFIG_GAMECUBE=y
+# CONFIG_WII is not set
+# CONFIG_AMIGAONE is not set
+# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MIGRATION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_PAGE_OFFSET_BOOL is not set
+CONFIG_PAGE_OFFSET=0xc0000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0xc0000000
+# CONFIG_CONSISTENT_SIZE_BOOL is not set
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# 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_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_ZHENHUA is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=64
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_OF is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+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=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PPC=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_GENERIC=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+CONFIG_SCHED_TRACER=y
+CONFIG_BOOT_TRACER=y
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+CONFIG_DMA_API_DEBUG=y
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+CONFIG_PPC_EARLY_DEBUG=y
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+# CONFIG_PPC_EARLY_DEBUG_44x is not set
+# CONFIG_PPC_EARLY_DEBUG_40x is not set
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
+CONFIG_PPC_EARLY_DEBUG_USBGECKO=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/iseries_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/iseries_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/iseries_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/iseries_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -714,8 +714,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/linkstation_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/linkstation_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/linkstation_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/linkstation_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:08 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,6 +88,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -181,14 +184,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -215,6 +245,8 @@ CONFIG_LINKSTATION=y
 CONFIG_MPC10X_BRIDGE=y
 CONFIG_MPC10X_OPENPIC=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
+# CONFIG_GAMECUBE is not set
+# CONFIG_WII is not set
 # CONFIG_AMIGAONE is not set
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
@@ -261,6 +293,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -277,8 +310,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -517,10 +548,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -650,6 +677,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -661,6 +692,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -668,6 +700,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -720,7 +753,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -759,6 +794,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -814,15 +850,16 @@ CONFIG_PATA_IT821X=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 CONFIG_PATA_SIL680=y
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -839,7 +876,7 @@ CONFIG_PATA_SIL680=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -934,8 +971,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -960,6 +1000,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 # CONFIG_NETPOLL_TRAP is not set
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -969,6 +1010,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -1007,6 +1049,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -1039,6 +1082,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1096,11 +1140,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1109,7 +1148,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1155,6 +1193,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1193,6 +1232,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1211,11 +1251,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1281,6 +1323,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1454,6 +1497,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1475,7 +1519,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1786,7 +1832,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mgcoge_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgcoge_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mgcoge_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgcoge_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:09 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:02 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,7 +60,6 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
-CONFIG_HIBERNATE_32=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -168,14 +169,41 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -208,7 +236,8 @@ CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 CONFIG_PPC_I8259=y
 CONFIG_PPC_RTAS=y
-# CONFIG_RTAS_ERROR_LOGGING is not set
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_PPC_RTAS_DAEMON=y
 CONFIG_RTAS_PROC=y
 # CONFIG_MMIO_NVRAM is not set
 CONFIG_PPC_MPC106=y
@@ -250,6 +279,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -262,8 +292,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -395,9 +423,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_BT is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -525,6 +550,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -558,7 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -625,8 +654,9 @@ CONFIG_FS_ENET_MDIO_FCC=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -637,6 +667,7 @@ CONFIG_WLAN=y
 # CONFIG_SLIP is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -673,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -734,11 +766,6 @@ CONFIG_I2C_CPM=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -775,6 +802,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -807,11 +835,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1118,7 +1148,11 @@ CONFIG_BDI_SWITCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mgsuvd_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgsuvd_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:10 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:03 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -53,6 +54,7 @@ CONFIG_OF=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -80,6 +82,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -162,14 +165,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -244,6 +274,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -260,8 +291,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -379,9 +408,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -497,6 +523,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -568,8 +598,7 @@ CONFIG_FS_ENET_HAS_SCC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -614,6 +643,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -863,6 +893,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -887,7 +918,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc5200_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc5200_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc5200_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc5200_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc4
-# Thu Oct 15 10:33:21 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Dec 30 15:08:52 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -87,6 +89,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -170,14 +173,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -193,6 +223,7 @@ CONFIG_PPC_LITE5200=y
 CONFIG_PPC_MEDIA5200=y
 CONFIG_PPC_MPC5200_BUGFIX=y
 CONFIG_PPC_MPC5200_GPIO=y
+CONFIG_PPC_MPC5200_LPBFIFO=m
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -211,6 +242,7 @@ CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_PPC_I8259 is not set
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERROR_LOGGING is not set
+# CONFIG_PPC_RTAS_DAEMON is not set
 CONFIG_RTAS_PROC=y
 # CONFIG_MMIO_NVRAM is not set
 # CONFIG_PPC_MPC106 is not set
@@ -223,6 +255,7 @@ CONFIG_RTAS_PROC=y
 CONFIG_PPC_BESTCOMM=y
 CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
+CONFIG_PPC_BESTCOMM_GEN_BD=m
 CONFIG_SIMPLE_GPIO=y
 
 #
@@ -253,6 +286,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -269,8 +303,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -286,6 +318,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -399,7 +432,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -530,6 +569,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -541,6 +584,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -548,6 +592,8 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -600,7 +646,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -639,6 +687,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -694,15 +743,16 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -785,8 +835,11 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -809,6 +862,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -818,6 +872,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -874,6 +929,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -934,11 +990,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -947,7 +998,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -962,7 +1012,10 @@ CONFIG_SPI_MASTER=y
 #
 # CONFIG_SPI_BITBANG is not set
 # CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_MPC52xx is not set
 CONFIG_SPI_MPC52xx_PSC=m
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -995,6 +1048,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1042,6 +1096,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1083,6 +1138,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1122,6 +1178,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -1129,6 +1186,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1322,7 +1381,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_WHCI_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1440,6 +1498,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1469,7 +1528,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1731,6 +1792,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1774,7 +1836,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:10 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:04 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -167,14 +170,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -199,6 +229,8 @@ CONFIG_MPC7448HPC2=y
 # CONFIG_PPC_PRPMC2800 is not set
 # CONFIG_PPC_C2K is not set
 CONFIG_TSI108_BRIDGE=y
+# CONFIG_GAMECUBE is not set
+# CONFIG_WII is not set
 # CONFIG_AMIGAONE is not set
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
@@ -244,6 +276,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -260,8 +293,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -385,9 +416,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -424,6 +452,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -487,7 +519,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -526,6 +560,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -580,15 +615,16 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -605,7 +641,7 @@ CONFIG_SATA_MV=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -731,8 +767,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -746,6 +784,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -755,6 +794,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -806,6 +846,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1091,7 +1132,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1118,7 +1159,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:11 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:05 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -161,14 +164,41 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -240,6 +270,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -252,8 +283,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -403,9 +432,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_BT is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -526,6 +552,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -556,7 +586,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -661,8 +691,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -679,6 +710,7 @@ CONFIG_PPP_DEFLATE=y
 CONFIG_SLHC=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -688,6 +720,7 @@ CONFIG_SLHC=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -740,6 +773,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -763,6 +797,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -799,6 +834,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1131,7 +1167,11 @@ CONFIG_BDI_SWITCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc83xx_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc83xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:12 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:06 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -37,6 +37,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 CONFIG_REDBOOT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
@@ -89,6 +91,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -176,14 +179,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -266,6 +296,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -282,8 +313,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -413,9 +442,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -548,6 +574,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -559,6 +589,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -566,6 +597,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -618,7 +650,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -657,6 +691,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -712,15 +747,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -737,7 +773,7 @@ CONFIG_ATA_SFF=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -844,8 +880,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -868,6 +907,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -877,6 +917,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -929,6 +970,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -989,11 +1031,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1002,7 +1039,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1034,6 +1070,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1076,6 +1113,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1115,6 +1153,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1153,11 +1192,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1249,6 +1290,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1542,7 +1584,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1569,7 +1611,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc85xx_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:25:20 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:06 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -39,6 +39,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -62,6 +63,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -92,6 +95,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -184,14 +188,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC_MSI_BITMAP=y
 
@@ -201,7 +232,7 @@ CONFIG_PPC_MSI_BITMAP=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 CONFIG_MPC8540_ADS=y
 CONFIG_MPC8560_ADS=y
 CONFIG_MPC85xx_CDS=y
@@ -220,6 +251,7 @@ CONFIG_TQM8555=y
 CONFIG_TQM8560=y
 CONFIG_SBC8548=y
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -267,6 +299,7 @@ CONFIG_SWIOTLB=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -283,8 +316,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -405,6 +436,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -449,9 +481,6 @@ CONFIG_SCTP_HMAC_MD5=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -494,6 +523,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -505,6 +538,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -512,6 +546,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -565,7 +600,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -604,6 +641,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -659,15 +697,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -684,7 +723,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -795,8 +834,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -820,6 +862,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -829,6 +872,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -858,6 +902,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -896,6 +941,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -956,11 +1002,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -969,7 +1010,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1002,6 +1042,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1035,11 +1076,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1114,6 +1157,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1241,6 +1285,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1347,7 +1392,6 @@ CONFIG_EDAC=y
 #
 # CONFIG_EDAC_DEBUG is not set
 CONFIG_EDAC_MM_EDAC=y
-CONFIG_EDAC_MPC85XX=y
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1376,6 +1420,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1397,7 +1442,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1731,7 +1778,11 @@ CONFIG_VIRQ_DEBUG=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:26:01 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:07 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -16,9 +16,9 @@ CONFIG_PPC_85xx=y
 # CONFIG_E200 is not set
 CONFIG_E500=y
 # CONFIG_PPC_E500MC is not set
+CONFIG_FSL_EMB_PERFMON=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
-CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
@@ -40,6 +40,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -63,6 +64,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -93,6 +96,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -187,14 +191,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 CONFIG_PPC_MSI_BITMAP=y
 
@@ -204,7 +235,7 @@ CONFIG_PPC_MSI_BITMAP=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
+CONFIG_FSL_SOC_BOOKE=y
 CONFIG_MPC8540_ADS=y
 CONFIG_MPC8560_ADS=y
 CONFIG_MPC85xx_CDS=y
@@ -223,6 +254,7 @@ CONFIG_TQM8555=y
 CONFIG_TQM8560=y
 CONFIG_SBC8548=y
 # CONFIG_SBC8560 is not set
+# CONFIG_P4080_DS is not set
 CONFIG_TQM85xx=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -271,6 +303,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -287,8 +320,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -409,6 +440,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -453,9 +485,6 @@ CONFIG_SCTP_HMAC_MD5=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -498,6 +527,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -509,6 +542,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -516,6 +550,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -569,7 +604,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -608,6 +645,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -663,15 +701,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -688,7 +727,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -799,8 +838,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -824,6 +866,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -833,6 +876,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -862,6 +906,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -900,6 +945,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -960,11 +1006,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -973,7 +1014,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1006,6 +1046,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1039,11 +1080,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1118,6 +1161,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1245,6 +1289,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_FSL=y
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1351,7 +1396,6 @@ CONFIG_EDAC=y
 #
 # CONFIG_EDAC_DEBUG is not set
 CONFIG_EDAC_MM_EDAC=y
-CONFIG_EDAC_MPC85XX=y
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1380,6 +1424,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1401,7 +1446,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1735,7 +1782,11 @@ CONFIG_VIRQ_DEBUG=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc866_ads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc866_ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:15 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:08 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -53,6 +54,7 @@ CONFIG_OF=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -80,6 +82,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -158,14 +161,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -240,6 +270,7 @@ CONFIG_MATH_EMULATION=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -256,8 +287,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -375,9 +404,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -407,6 +433,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -485,8 +515,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_MV643XX_ETH is not set
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -506,6 +535,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -554,6 +584,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -576,6 +607,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -855,6 +887,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -876,7 +909,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc86xx_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc86xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:16 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:09 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -61,6 +62,8 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -91,6 +94,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -183,14 +187,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -221,7 +252,7 @@ CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 CONFIG_PPC_I8259=y
 # CONFIG_PPC_RTAS is not set
-# CONFIG_MMIO_NVRAM is not set
+CONFIG_MMIO_NVRAM=y
 # CONFIG_PPC_MPC106 is not set
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
@@ -262,6 +293,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -278,8 +310,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -397,6 +427,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -441,9 +472,6 @@ CONFIG_SCTP_HMAC_MD5=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -486,6 +514,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -497,6 +529,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -504,6 +537,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -557,7 +591,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -596,6 +632,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -651,15 +688,16 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -676,7 +714,7 @@ CONFIG_PATA_ALI=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -781,8 +819,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -805,6 +846,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -814,6 +856,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -843,6 +886,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -879,6 +923,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -936,11 +981,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -949,7 +989,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -982,6 +1021,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1015,11 +1055,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1094,6 +1136,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1221,6 +1264,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1348,6 +1392,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1369,7 +1414,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1684,7 +1731,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc885_ads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc885_ads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:17 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:10 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -54,6 +55,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -81,6 +83,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -159,14 +162,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -248,6 +278,7 @@ CONFIG_8XX_MINIMAL_FPEMU=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -264,8 +295,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -379,9 +408,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -556,8 +582,7 @@ CONFIG_FS_ENET_MDIO_FEC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -602,6 +627,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -862,6 +888,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -904,7 +931,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc40x_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc40x_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc40x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc40x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Fri Jan 23 08:44:03 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 13:54:06 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -16,6 +16,7 @@ CONFIG_40x=y
 # CONFIG_E200 is not set
 CONFIG_4xx=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -27,15 +28,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
@@ -50,11 +54,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
-# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_DTC=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -68,9 +76,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -85,31 +105,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -121,6 +150,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,8 +169,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -141,19 +177,41 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -168,12 +226,14 @@ CONFIG_XILINX_VIRTEX=y
 CONFIG_ACADIA=y
 CONFIG_EP405=y
 CONFIG_HCU4=y
+CONFIG_HOTFOOT=y
 CONFIG_KILAUEA=y
 CONFIG_MAKALU=y
 CONFIG_WALNUT=y
 CONFIG_XILINX_VIRTEX_GENERIC_BOARD=y
 CONFIG_PPC40x_SIMPLE=y
 CONFIG_405GP=y
+CONFIG_405EP=y
 CONFIG_405EX=y
 CONFIG_405EZ=y
 CONFIG_405GPR=y
@@ -195,6 +255,7 @@ CONFIG_IBM405_ERR51=y
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_OF_RTC=y
 # CONFIG_SIMPLE_GPIO is not set
+# CONFIG_XILINX_PCI is not set
 
 #
 # Kernel options
@@ -218,10 +279,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -237,10 +300,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -265,6 +330,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -282,14 +348,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -341,6 +405,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -349,6 +414,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -362,6 +428,8 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -374,13 +442,13 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -393,6 +461,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -405,9 +474,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -483,7 +552,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -491,7 +559,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_WL_THRESHOLD=4096
 CONFIG_MTD_UBI_BEB_RESERVE=1
-CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_MTD_UBI_GLUEBI=m
 
 #
 # UBI debugging options
@@ -509,6 +577,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -520,14 +589,25 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_XILINX_SYSACE=m
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -547,7 +627,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -568,6 +652,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -586,7 +672,10 @@ CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT=y
 CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -594,6 +683,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -604,9 +694,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -616,6 +710,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -625,14 +720,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -645,6 +739,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -663,6 +758,7 @@ CONFIG_SERIO=m
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 CONFIG_SERIO_XILINX_XPS_PS2=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -697,6 +793,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -714,6 +811,7 @@ CONFIG_XILINX_HWICAP=m
 CONFIG_DEVPORT=y
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
@@ -756,11 +854,6 @@ CONFIG_I2C_IBM_IIC=m
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -769,20 +862,17 @@ CONFIG_I2C_IBM_IIC=m
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
@@ -804,11 +894,17 @@ CONFIG_GPIO_XILINX=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -832,28 +928,15 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -909,6 +992,7 @@ CONFIG_FB_XILINX=m
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -930,7 +1014,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -946,7 +1030,12 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -956,6 +1045,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -966,11 +1056,13 @@ CONFIG_FS_MBCACHE=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -980,6 +1072,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1053,7 +1150,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1108,6 +1204,7 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1125,11 +1222,13 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
 CONFIG_LZO_DECOMPRESS=m
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1139,6 +1238,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1147,16 +1247,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1168,35 +1275,45 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1212,13 +1329,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1227,10 +1347,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1258,11 +1380,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1299,6 +1423,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1307,5 +1432,6 @@ CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc44x_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc44x_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc44x_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc44x_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Fri Jan 23 08:43:46 2009
+# Linux kernel version: 2.6.33-rc1
+# Mon Jan  4 13:42:17 2010
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -20,6 +20,7 @@ CONFIG_BOOKE=y
 CONFIG_PTE_64BIT=y
 CONFIG_PHYS_64BIT=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
@@ -31,15 +32,18 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
@@ -54,11 +58,15 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
-# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_DTC=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -72,9 +80,21 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,31 +109,40 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -125,6 +154,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -136,8 +172,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -145,20 +180,42 @@ CONFIG_LBD=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_PREEMPT_NOTIFIERS=y
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -179,8 +236,11 @@ CONFIG_WARP=y
 CONFIG_ARCHES=y
 CONFIG_CANYONLANDS=y
 CONFIG_GLACIER=y
+CONFIG_REDWOOD=y
+CONFIG_EIGER=y
 CONFIG_YOSEMITE=y
 CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
+# CONFIG_XILINX_ML510 is not set
 CONFIG_PPC44x_SIMPLE=y
 CONFIG_PPC4xx_GPIO=y
 CONFIG_440EP=y
@@ -190,6 +250,7 @@ CONFIG_440GP=y
 CONFIG_440GX=y
 CONFIG_440SPe=y
 CONFIG_460EX=y
+CONFIG_460SX=y
 CONFIG_IBM440EP_ERR42=y
 CONFIG_XILINX_VIRTEX=y
 CONFIG_XILINX_VIRTEX_5_FXT=y
@@ -207,6 +268,7 @@ CONFIG_XILINX_VIRTEX_5_FXT=y
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_OF_RTC=y
 # CONFIG_SIMPLE_GPIO is not set
+# CONFIG_XILINX_PCI is not set
 
 #
 # Kernel options
@@ -230,10 +292,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -249,10 +313,13 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -276,6 +343,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -293,14 +361,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -352,6 +418,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -360,6 +427,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_STP=m
@@ -375,6 +443,8 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -387,8 +457,13 @@ CONFIG_LLC=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -401,6 +476,7 @@ CONFIG_LLC=m
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -413,9 +489,9 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 CONFIG_MTD_OF_PARTS=y
@@ -490,7 +566,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -498,7 +573,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_WL_THRESHOLD=4096
 CONFIG_MTD_UBI_BEB_RESERVE=1
-CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_MTD_UBI_GLUEBI=m
 
 #
 # UBI debugging options
@@ -516,6 +591,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -528,14 +604,25 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_XILINX_SYSACE=m
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -558,10 +645,6 @@ CONFIG_BLK_DEV_SD=m
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -578,6 +661,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -587,7 +671,11 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -608,6 +696,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -626,7 +716,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -634,6 +727,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -644,9 +738,13 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -656,6 +754,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -665,14 +764,14 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -695,6 +794,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -713,6 +813,7 @@ CONFIG_SERIO=m
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 CONFIG_SERIO_XILINX_XPS_PS2=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -747,6 +848,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -764,6 +866,7 @@ CONFIG_XILINX_HWICAP=m
 CONFIG_DEVPORT=y
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
@@ -807,11 +910,6 @@ CONFIG_I2C_IBM_IIC=m
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -820,20 +918,17 @@ CONFIG_I2C_IBM_IIC=m
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
@@ -855,16 +950,21 @@ CONFIG_GPIO_XILINX=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -884,28 +984,15 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -961,6 +1048,7 @@ CONFIG_FB_XILINX=m
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -994,19 +1082,22 @@ CONFIG_USB_DEVICE_CLASS=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 # CONFIG_USB_OHCI_HCD_PCI is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -1030,11 +1121,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1075,7 +1166,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1083,6 +1173,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
@@ -1091,6 +1182,7 @@ CONFIG_USB_STORAGE=m
 # OTG and related infrastructure
 #
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1100,7 +1192,12 @@ CONFIG_USB_STORAGE=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1110,6 +1207,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -1119,11 +1217,13 @@ CONFIG_FS_MBCACHE=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1133,6 +1233,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1206,7 +1311,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1261,6 +1365,7 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1278,11 +1383,13 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=m
 CONFIG_LZO_DECOMPRESS=m
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1292,6 +1399,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1300,16 +1408,23 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1321,35 +1436,43 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -1363,13 +1486,16 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1378,10 +1504,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1409,11 +1537,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1450,6 +1580,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=m
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc64_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc64_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -304,11 +304,11 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
+CONFIG_HZ=100
 CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
@@ -980,7 +980,7 @@ CONFIG_E100=y
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -1023,8 +1023,8 @@ CONFIG_PASEMI_MAC=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
@@ -1863,7 +1863,7 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc64e_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64e_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/ppc64e_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/ppc64e_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1008,8 +1008,8 @@ CONFIG_IXGB=m
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 CONFIG_WLAN=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/pq2fads_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/pq2fads_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/pq2fads_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/pq2fads_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:17 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:11 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -59,6 +60,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -165,14 +168,41 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -243,6 +273,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -255,8 +286,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -407,9 +436,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_BT is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -530,6 +556,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -616,7 +646,7 @@ CONFIG_IDE_PROC_FS=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -721,8 +751,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -739,6 +770,7 @@ CONFIG_PPP_DEFLATE=y
 CONFIG_SLHC=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -748,6 +780,7 @@ CONFIG_SLHC=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -802,6 +835,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -825,6 +859,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -861,6 +896,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -955,10 +991,12 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_ETH_EEM is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1248,7 +1286,11 @@ CONFIG_BDI_SWITCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/prpmc2800_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/prpmc2800_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:18 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:12 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -38,6 +38,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +61,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -88,6 +90,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -175,14 +178,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -207,6 +237,8 @@ CONFIG_EMBEDDED6xx=y
 CONFIG_PPC_PRPMC2800=y
 # CONFIG_PPC_C2K is not set
 CONFIG_MV64X60=y
+# CONFIG_GAMECUBE is not set
+# CONFIG_WII is not set
 # CONFIG_AMIGAONE is not set
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
@@ -252,6 +284,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -268,8 +301,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -394,9 +425,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -518,6 +546,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -529,6 +561,7 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -536,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -641,7 +675,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -680,6 +716,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -734,15 +771,16 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -759,7 +797,7 @@ CONFIG_SATA_MV=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -886,8 +924,11 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -910,6 +951,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -919,6 +961,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -973,6 +1016,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1030,11 +1074,6 @@ CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1042,7 +1081,6 @@ CONFIG_I2C_MV64XXX=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1088,6 +1126,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1126,6 +1165,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1144,11 +1184,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1250,6 +1292,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
@@ -1362,6 +1405,7 @@ CONFIG_RTC_DRV_MAX6900=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1383,7 +1427,9 @@ CONFIG_RTC_DRV_MAX6900=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1626,7 +1672,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/pseries_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/pseries_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/pseries_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/pseries_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -230,11 +230,11 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
+CONFIG_HZ=100
 CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
@@ -796,7 +796,7 @@ CONFIG_E100=y
 # CONFIG_NET_POCKET is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
-CONFIG_ACENIC=y
+CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
@@ -834,8 +834,8 @@ CONFIG_S2IO=m
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
-CONFIG_TR=y
-CONFIG_IBMOL=y
+# CONFIG_TR is not set
+# CONFIG_IBMOL is not set
 # CONFIG_3C359 is not set
 # CONFIG_TMS380TR is not set
 
@@ -1494,7 +1494,7 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1683,7 +1683,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_HCALL_STATS=y
+# CONFIG_HCALL_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/storcenter_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/storcenter_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/storcenter_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/storcenter_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc5
-# Thu Nov  5 08:20:19 2009
+# Linux kernel version: 2.6.33-rc3
+# Wed Jan  6 09:24:13 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -36,6 +36,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 # CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -58,6 +59,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -85,6 +87,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -167,14 +170,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -201,6 +231,8 @@ CONFIG_STORCENTER=y
 CONFIG_MPC10X_BRIDGE=y
 CONFIG_MPC10X_OPENPIC=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
+# CONFIG_GAMECUBE is not set
+# CONFIG_WII is not set
 # CONFIG_AMIGAONE is not set
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
@@ -246,6 +278,7 @@ CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
 CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -262,8 +295,6 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
@@ -384,9 +415,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -507,6 +535,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -515,6 +547,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -522,6 +555,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -628,7 +662,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -666,6 +702,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
@@ -695,7 +732,7 @@ CONFIG_MD_RAID6_PQ=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -741,8 +778,11 @@ CONFIG_R8169=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_AIRO is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -765,6 +805,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -805,6 +846,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -862,11 +904,6 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -875,7 +912,6 @@ CONFIG_I2C_MPC=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -910,11 +946,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -963,6 +1001,7 @@ CONFIG_USB_DEVICE_CLASS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_XPS_USB_HCD_XILINX is not set
 # CONFIG_USB_EHCI_FSL is not set
 CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_OXU210HP_HCD is not set
@@ -1087,6 +1126,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1108,7 +1148,9 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1322,7 +1364,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1349,7 +1391,11 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/configs/wii_defconfig linux-libre-2.6.33-gnu1/arch/powerpc/configs/wii_defconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/configs/wii_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/configs/wii_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1406 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Sun Nov 22 20:37:21 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_PPC_BOOK3S_32=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-wii"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_LINKSTATION is not set
+# CONFIG_STORCENTER is not set
+# CONFIG_MPC7448HPC2 is not set
+# CONFIG_PPC_HOLLY is not set
+# CONFIG_PPC_PRPMC2800 is not set
+# CONFIG_PPC_C2K is not set
+CONFIG_GAMECUBE_COMMON=y
+CONFIG_USBGECKO_UDBG=y
+CONFIG_FLIPPER_PIC=y
+# CONFIG_GAMECUBE is not set
+CONFIG_HLWD_PIC=y
+CONFIG_STARLET_MINI=y
+CONFIG_WII=y
+# CONFIG_AMIGAONE is not set
+# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MIGRATION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_PAGE_OFFSET_BOOL is not set
+CONFIG_PAGE_OFFSET=0xc0000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0xc0000000
+# CONFIG_CONSISTENT_SIZE_BOOL is not set
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# 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_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+# CONFIG_BT_SCO is not set
+CONFIG_BT_RFCOMM=y
+# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+# CONFIG_CFG80211_DEBUGFS is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_HOSTAP is not set
+CONFIG_B43=y
+CONFIG_B43_SDIO=y
+CONFIG_B43_PIO=y
+# CONFIG_B43_PHY_LP is not set
+CONFIG_B43_DEBUG=y
+# CONFIG_B43_FORCE_PIO is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_JOYDEV=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_ZHENHUA is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=64
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_XILINX is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=y
+CONFIG_SSB_BLOCKIO=y
+CONFIG_SSB_SDIOHOST_POSSIBLE=y
+CONFIG_SSB_SDIOHOST=y
+# CONFIG_SSB_SILENT is not set
+CONFIG_SSB_DEBUG=y
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_OF is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PPC=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_APPLE=m
+CONFIG_HID_WACOM=m
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_OF is not set
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MMC_WBSD is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_GENERIC=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+CONFIG_SCHED_TRACER=y
+CONFIG_BOOT_TRACER=y
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+CONFIG_DMA_API_DEBUG=y
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+CONFIG_PPC_EARLY_DEBUG=y
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+# CONFIG_PPC_EARLY_DEBUG_44x is not set
+# CONFIG_PPC_EARLY_DEBUG_40x is not set
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
+CONFIG_PPC_EARLY_DEBUG_USBGECKO=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/async_tx.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/async_tx.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/async_tx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/async_tx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 DENX Software Engineering.
+ *
+ * Author: Yuri Tikhonov <yur@emcraft.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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef _ASM_POWERPC_ASYNC_TX_H_
+#define _ASM_POWERPC_ASYNC_TX_H_
+
+#if defined(CONFIG_440SPe) || defined(CONFIG_440SP)
+extern struct dma_chan *
+ppc440spe_async_tx_find_best_channel(enum dma_transaction_type cap,
+	struct page **dst_lst, int dst_cnt, struct page **src_lst,
+	int src_cnt, size_t src_sz);
+
+#define async_tx_find_channel(dep, cap, dst_lst, dst_cnt, src_lst, \
+			      src_cnt, src_sz) \
+	ppc440spe_async_tx_find_best_channel(cap, dst_lst, dst_cnt, src_lst, \
+					     src_cnt, src_sz)
+#else
+
+#define async_tx_find_channel(dep, type, dst, dst_count, src, src_count, len) \
+	__async_tx_find_channel(dep, type)
+
+struct dma_chan *
+__async_tx_find_channel(struct async_submit_ctl *submit,
+			enum dma_transaction_type tx_type);
+
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -68,7 +68,7 @@
 		_EMIT_BUG_ENTRY					\
 		: : "i" (__FILE__), "i" (__LINE__),		\
 		    "i" (0), "i"  (sizeof(struct bug_entry)));	\
-	for(;;) ;						\
+	unreachable();						\
 } while (0)
 
 #define BUG_ON(x) do {						\
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #define flush_cache_vmap(start, end)		do { } while (0)
 #define flush_cache_vunmap(start, end)		do { } while (0)
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm1.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm1.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm1.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm1.h	2010-02-24 13:52:17.000000000 -0500
@@ -478,51 +478,6 @@ typedef struct iic {
 	char	res2[2];	/* Reserved */
 } iic_t;
 
-/* SPI parameter RAM.
-*/
-typedef struct spi {
-	ushort	spi_rbase;	/* Rx Buffer descriptor base address */
-	ushort	spi_tbase;	/* Tx Buffer descriptor base address */
-	u_char	spi_rfcr;	/* Rx function code */
-	u_char	spi_tfcr;	/* Tx function code */
-	ushort	spi_mrblr;	/* Max receive buffer length */
-	uint	spi_rstate;	/* Internal */
-	uint	spi_rdp;	/* Internal */
-	ushort	spi_rbptr;	/* Internal */
-	ushort	spi_rbc;	/* Internal */
-	uint	spi_rxtmp;	/* Internal */
-	uint	spi_tstate;	/* Internal */
-	uint	spi_tdp;	/* Internal */
-	ushort	spi_tbptr;	/* Internal */
-	ushort	spi_tbc;	/* Internal */
-	uint	spi_txtmp;	/* Internal */
-	uint	spi_res;
-	ushort	spi_rpbase;	/* Relocation pointer */
-	ushort	spi_res2;
-} spi_t;
-
-/* SPI Mode register.
-*/
-#define SPMODE_LOOP	((ushort)0x4000)	/* Loopback */
-#define SPMODE_CI	((ushort)0x2000)	/* Clock Invert */
-#define SPMODE_CP	((ushort)0x1000)	/* Clock Phase */
-#define SPMODE_DIV16	((ushort)0x0800)	/* BRG/16 mode */
-#define SPMODE_REV	((ushort)0x0400)	/* Reversed Data */
-#define SPMODE_MSTR	((ushort)0x0200)	/* SPI Master */
-#define SPMODE_EN	((ushort)0x0100)	/* Enable */
-#define SPMODE_LENMSK	((ushort)0x00f0)	/* character length */
-#define SPMODE_LEN4	((ushort)0x0030)	/*  4 bits per char */
-#define SPMODE_LEN8	((ushort)0x0070)	/*  8 bits per char */
-#define SPMODE_LEN16	((ushort)0x00f0)	/* 16 bits per char */
-#define SPMODE_PMMSK	((ushort)0x000f)	/* prescale modulus */
-
-/* SPIE fields */
-#define SPIE_MME	0x20
-#define SPIE_TXE	0x10
-#define SPIE_BSY	0x04
-#define SPIE_TXB	0x02
-#define SPIE_RXB	0x01
-
 /*
  * RISC Controller Configuration Register definitons
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm2.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm2.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm2.h	2010-02-24 13:52:17.000000000 -0500
@@ -124,14 +124,6 @@ static inline void cpm2_fastbrg(uint brg
 	__cpm2_setbrg(brg, rate, CPM2_BRG_INT_CLK, div16, CPM_BRG_EXTC_INT);
 }
 
-/* Function code bits, usually generic to devices.
-*/
-#define CPMFCR_GBL	((u_char)0x20)	/* Set memory snooping */
-#define CPMFCR_EB	((u_char)0x10)	/* Set big endian byte order */
-#define CPMFCR_TC2	((u_char)0x04)	/* Transfer code 2 value */
-#define CPMFCR_DTB	((u_char)0x02)	/* Use local bus for data when set */
-#define CPMFCR_BDB	((u_char)0x01)	/* Use local bus for BD when set */
-
 /* Parameter RAM offsets from the base.
 */
 #define PROFF_SCC1		((uint)0x8000)
@@ -654,45 +646,6 @@ typedef struct iic {
 	uint	iic_txtmp;	/* Internal */
 } iic_t;
 
-/* SPI parameter RAM.
-*/
-typedef struct spi {
-	ushort	spi_rbase;	/* Rx Buffer descriptor base address */
-	ushort	spi_tbase;	/* Tx Buffer descriptor base address */
-	u_char	spi_rfcr;	/* Rx function code */
-	u_char	spi_tfcr;	/* Tx function code */
-	ushort	spi_mrblr;	/* Max receive buffer length */
-	uint	spi_rstate;	/* Internal */
-	uint	spi_rdp;	/* Internal */
-	ushort	spi_rbptr;	/* Internal */
-	ushort	spi_rbc;	/* Internal */
-	uint	spi_rxtmp;	/* Internal */
-	uint	spi_tstate;	/* Internal */
-	uint	spi_tdp;	/* Internal */
-	ushort	spi_tbptr;	/* Internal */
-	ushort	spi_tbc;	/* Internal */
-	uint	spi_txtmp;	/* Internal */
-	uint	spi_res;	/* Tx temp. */
-	uint	spi_res1[4];	/* SDMA temp. */
-} spi_t;
-
-/* SPI Mode register.
-*/
-#define SPMODE_LOOP	((ushort)0x4000)	/* Loopback */
-#define SPMODE_CI	((ushort)0x2000)	/* Clock Invert */
-#define SPMODE_CP	((ushort)0x1000)	/* Clock Phase */
-#define SPMODE_DIV16	((ushort)0x0800)	/* BRG/16 mode */
-#define SPMODE_REV	((ushort)0x0400)	/* Reversed Data */
-#define SPMODE_MSTR	((ushort)0x0200)	/* SPI Master */
-#define SPMODE_EN	((ushort)0x0100)	/* Enable */
-#define SPMODE_LENMSK	((ushort)0x00f0)	/* character length */
-#define SPMODE_PMMSK	((ushort)0x000f)	/* prescale modulus */
-
-#define SPMODE_LEN(x)	((((x)-1)&0xF)<<4)
-#define SPMODE_PM(x)	((x) &0xF)
-
-#define SPI_EB		((u_char)0x10)		/* big endian byte order */
-
 /* IDMA parameter RAM
 */
 typedef struct idma {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/cpm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/cpm.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,8 +3,47 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/errno.h>
 #include <linux/of.h>
 
+/*
+ * USB Controller pram common to QE and CPM.
+ */
+struct usb_ctlr {
+	u8	usb_usmod;
+	u8	usb_usadr;
+	u8	usb_uscom;
+	u8	res1[1];
+	__be16	usb_usep[4];
+	u8	res2[4];
+	__be16	usb_usber;
+	u8	res3[2];
+	__be16	usb_usbmr;
+	u8	res4[1];
+	u8	usb_usbs;
+	/* Fields down below are QE-only */
+	__be16	usb_ussft;
+	u8	res5[2];
+	__be16	usb_usfrn;
+	u8	res6[0x22];
+} __attribute__ ((packed));
+
+/*
+ * Function code bits, usually generic to devices.
+ */
+#ifdef CONFIG_CPM1
+#define CPMFCR_GBL	((u_char)0x00)	/* Flag doesn't exist in CPM1 */
+#define CPMFCR_TC2	((u_char)0x00)	/* Flag doesn't exist in CPM1 */
+#define CPMFCR_DTB	((u_char)0x00)	/* Flag doesn't exist in CPM1 */
+#define CPMFCR_BDB	((u_char)0x00)	/* Flag doesn't exist in CPM1 */
+#else
+#define CPMFCR_GBL	((u_char)0x20)	/* Set memory snooping */
+#define CPMFCR_TC2	((u_char)0x04)	/* Transfer code 2 value */
+#define CPMFCR_DTB	((u_char)0x02)	/* Use local bus for data when set */
+#define CPMFCR_BDB	((u_char)0x01)	/* Use local bus for BD when set */
+#endif
+#define CPMFCR_EB	((u_char)0x10)	/* Set big endian byte order */
+
 /* Opcodes common to CPM1 and CPM2
 */
 #define CPM_CR_INIT_TRX		((ushort)0x0000)
@@ -93,13 +132,56 @@ typedef struct cpm_buf_desc {
 #define BD_I2C_START		(0x0400)
 
 int cpm_muram_init(void);
+
+#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE)
 unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
 int cpm_muram_free(unsigned long offset);
 unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
 void __iomem *cpm_muram_addr(unsigned long offset);
 unsigned long cpm_muram_offset(void __iomem *addr);
 dma_addr_t cpm_muram_dma(void __iomem *addr);
+#else
+static inline unsigned long cpm_muram_alloc(unsigned long size,
+					    unsigned long align)
+{
+	return -ENOSYS;
+}
+
+static inline int cpm_muram_free(unsigned long offset)
+{
+	return -ENOSYS;
+}
+
+static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset,
+						  unsigned long size)
+{
+	return -ENOSYS;
+}
+
+static inline void __iomem *cpm_muram_addr(unsigned long offset)
+{
+	return NULL;
+}
+
+static inline unsigned long cpm_muram_offset(void __iomem *addr)
+{
+	return -ENOSYS;
+}
+
+static inline dma_addr_t cpm_muram_dma(void __iomem *addr)
+{
+	return 0;
+}
+#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */
+
+#ifdef CONFIG_CPM
 int cpm_command(u32 command, u8 opcode);
+#else
+static inline int cpm_command(u32 command, u8 opcode)
+{
+	return -ENOSYS;
+}
+#endif /* CONFIG_CPM */
 
 int cpm2_gpiochip_add32(struct device_node *np);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/dcr-regs.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dcr-regs.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/dcr-regs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dcr-regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -157,4 +157,27 @@
 #define  L2C_SNP_SSR_32G	0x0000f000
 #define  L2C_SNP_ESR		0x00000800
 
+/*
+ * DCR register offsets for 440SP/440SPe I2O/DMA controller.
+ * The base address is configured in the device tree.
+ */
+#define DCRN_I2O0_IBAL		0x006
+#define DCRN_I2O0_IBAH		0x007
+#define I2O_REG_ENABLE		0x00000001	/* Enable I2O/DMA access */
+
+/* 440SP/440SPe Software Reset DCR */
+#define DCRN_SDR0_SRST		0x0200
+#define DCRN_SDR0_SRST_I2ODMA	(0x80000000 >> 15)	/* Reset I2O/DMA */
+
+/* 440SP/440SPe Memory Queue DCR offsets */
+#define DCRN_MQ0_XORBA		0x04
+#define DCRN_MQ0_CF2H		0x06
+#define DCRN_MQ0_CFBHL		0x0f
+#define DCRN_MQ0_BAUH		0x10
+
+/* HB/LL Paths Configuration Register */
+#define MQ0_CFBHL_TPLM		28
+#define MQ0_CFBHL_HBCL		23
+#define MQ0_CFBHL_POLY		15
+
 #endif /* __DCR_REGS_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -197,7 +197,7 @@ static inline bool dma_capable(struct de
 	if (!dev->dma_mask)
 		return 0;
 
-	return addr + size <= *dev->dma_mask;
+	return addr + size - 1 <= *dev->dma_mask;
 }
 
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -170,7 +170,6 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
 #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
 #define compat_elf_check_arch(x)	((x)->e_machine == EM_PPC)
 
-#define USE_ELF_CORE_DUMP
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
@@ -236,14 +235,10 @@ typedef elf_vrregset_t elf_fpxregset_t;
 #ifdef __powerpc64__
 # define SET_PERSONALITY(ex)					\
 do {								\
-	unsigned long new_flags = 0;				\
 	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
-		new_flags = _TIF_32BIT;				\
-	if ((current_thread_info()->flags & _TIF_32BIT)		\
-	    != new_flags)					\
-		set_thread_flag(TIF_ABI_PENDING);		\
+		set_thread_flag(TIF_32BIT);			\
 	else							\
-		clear_thread_flag(TIF_ABI_PENDING);		\
+		clear_thread_flag(TIF_32BIT);			\
 	if (personality(current->personality) != PER_LINUX32)	\
 		set_personality(PER_LINUX |			\
 			(current->personality & (~PER_MASK)));	\
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/emulated_ops.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/emulated_ops.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/emulated_ops.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/emulated_ops.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #define _ASM_POWERPC_EMULATED_OPS_H
 
 #include <asm/atomic.h>
+#include <linux/perf_event.h>
 
 
 #ifdef CONFIG_PPC_EMULATED_STATS
@@ -57,7 +58,7 @@ extern u32 ppc_warn_emulated;
 
 extern void ppc_warn_emulated_print(const char *type);
 
-#define PPC_WARN_EMULATED(type)						 \
+#define __PPC_WARN_EMULATED(type)					 \
 	do {								 \
 		atomic_inc(&ppc_emulated.type.val);			 \
 		if (ppc_warn_emulated)					 \
@@ -66,8 +67,22 @@ extern void ppc_warn_emulated_print(cons
 
 #else /* !CONFIG_PPC_EMULATED_STATS */
 
-#define PPC_WARN_EMULATED(type)	do { } while (0)
+#define __PPC_WARN_EMULATED(type)	do { } while (0)
 
 #endif /* !CONFIG_PPC_EMULATED_STATS */
 
+#define PPC_WARN_EMULATED(type, regs)					\
+	do {								\
+		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,		\
+			1, 0, regs, 0);					\
+		__PPC_WARN_EMULATED(type);				\
+	} while (0)
+
+#define PPC_WARN_ALIGNMENT(type, regs)					\
+	do {								\
+		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,		\
+			1, 0, regs, regs->dar);				\
+		__PPC_WARN_EMULATED(type);				\
+	} while (0)
+
 #endif /* _ASM_POWERPC_EMULATED_OPS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/exception-64s.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/exception-64s.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/exception-64s.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/exception-64s.h	2010-02-24 13:52:17.000000000 -0500
@@ -147,6 +147,7 @@
 	.globl label##_pSeries;				\
 label##_pSeries:					\
 	HMT_MEDIUM;					\
+	DO_KVM	n;					\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
@@ -170,6 +171,7 @@ label##_pSeries:					\
 	.globl label##_pSeries;						\
 label##_pSeries:							\
 	HMT_MEDIUM;							\
+	DO_KVM	n;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
 	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/fixmap.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/fixmap.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/fixmap.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/fixmap.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,9 @@
  */
 enum fixed_addresses {
 	FIX_HOLE,
+	/* reserve the top 128K for early debugging purposes */
+	FIX_EARLY_DEBUG_TOP = FIX_HOLE,
+	FIX_EARLY_DEBUG_BASE = FIX_EARLY_DEBUG_TOP+((128*1024)/PAGE_SIZE)-1,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/gpio.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/gpio.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned
 	return __gpio_cansleep(gpio);
 }
 
-/*
- * Not implemented, yet.
- */
 static inline int gpio_to_irq(unsigned int gpio)
 {
-	return -ENOSYS;
+	return __gpio_to_irq(gpio);
 }
 
 static inline int irq_to_gpio(unsigned int irq)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hugetlb.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hugetlb.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hugetlb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hugetlb.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,6 +3,10 @@
 
 #include <asm/page.h>
 
+pte_t *huge_pte_offset_and_shift(struct mm_struct *mm,
+				 unsigned long addr, unsigned *shift);
+
+void flush_dcache_icache_hugepage(struct page *page);
 
 int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
 			   unsigned long len);
@@ -11,12 +15,6 @@ void hugetlb_free_pgd_range(struct mmu_g
 			    unsigned long end, unsigned long floor,
 			    unsigned long ceiling);
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
-		     pte_t *ptep, pte_t pte);
-
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep);
-
 /*
  * The version of vma_mmu_pagesize() in arch/powerpc/mm/hugetlbpage.c needs
  * to override the version in mm/hugetlb.c
@@ -42,9 +40,26 @@ static inline void hugetlb_prefault_arch
 {
 }
 
+
+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 pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+					    unsigned long addr, pte_t *ptep)
+{
+	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1);
+	return __pte(old);
+}
+
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
 					 unsigned long addr, pte_t *ptep)
 {
+	pte_t pte;
+	pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+	flush_tlb_page(vma, addr);
 }
 
 static inline int huge_pte_none(pte_t pte)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hvcall.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hvcall.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hvcall.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hvcall.h	2010-02-24 13:52:17.000000000 -0500
@@ -212,6 +212,19 @@
 #define H_QUERY_INT_STATE       0x1E4
 #define H_POLL_PENDING		0x1D8
 #define H_ILLAN_ATTRIBUTES	0x244
+#define H_MODIFY_HEA_QP		0x250
+#define H_QUERY_HEA_QP		0x254
+#define H_QUERY_HEA		0x258
+#define H_QUERY_HEA_PORT	0x25C
+#define H_MODIFY_HEA_PORT	0x260
+#define H_REG_BCMC		0x264
+#define H_DEREG_BCMC		0x268
+#define H_REGISTER_HEA_RPAGES	0x26C
+#define H_DISABLE_AND_GET_HEA	0x270
+#define H_GET_HEA_INFO		0x274
+#define H_ALLOC_HEA_RESOURCE	0x278
+#define H_ADD_CONN		0x284
+#define H_DEL_CONN		0x288
 #define H_JOIN			0x298
 #define H_VASI_STATE            0x2A4
 #define H_ENABLE_CRQ		0x2B0
@@ -274,6 +287,8 @@ struct hcall_stats {
 	unsigned long	num_calls;	/* number of calls (on this CPU) */
 	unsigned long	tb_total;	/* total wall time (mftb) of calls. */
 	unsigned long	purr_total;	/* total cpu time (PURR) of calls. */
+	unsigned long	tb_start;
+	unsigned long	purr_start;
 };
 #define HCALL_STAT_ARRAY_SIZE	((MAX_HCALL_OPCODE >> 2) + 1)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hw_irq.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hw_irq.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/hw_irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/hw_irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,11 +64,6 @@ extern void iseries_handle_interrupts(vo
 		get_paca()->hard_enabled = 0;	\
 	} while(0)
 
-static inline int irqs_disabled_flags(unsigned long flags)
-{
-	return flags == 0;
-}
-
 #else
 
 #if defined(CONFIG_BOOKE)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/immap_cpm2.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/immap_cpm2.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/immap_cpm2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/immap_cpm2.h	2010-02-24 13:52:17.000000000 -0500
@@ -549,7 +549,7 @@ typedef struct comm_proc {
 
 /* USB Controller.
 */
-typedef struct usb_ctlr {
+typedef struct cpm_usb_ctlr {
 	u8	usb_usmod;
 	u8	usb_usadr;
 	u8	usb_uscom;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/immap_qe.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/immap_qe.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/immap_qe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/immap_qe.h	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,7 @@ struct sir {
 } __attribute__ ((packed));
 
 /* USB Controller */
-struct usb_ctlr {
+struct qe_usb_ctlr {
 	u8	usb_usmod;
 	u8	usb_usadr;
 	u8	usb_uscom;
@@ -229,7 +229,7 @@ struct usb_ctlr {
 } __attribute__ ((packed));
 
 /* MCC */
-struct mcc {
+struct qe_mcc {
 	__be32	mcce;		/* MCC event register */
 	__be32	mccm;		/* MCC mask register */
 	__be32	mccf;		/* MCC configuration register */
@@ -431,9 +431,9 @@ struct qe_immap {
 	struct qe_mux		qmx;		/* QE Multiplexer */
 	struct qe_timers	qet;		/* QE Timers */
 	struct spi		spi[0x2];	/* spi */
-	struct mcc		mcc;		/* mcc */
+	struct qe_mcc		mcc;		/* mcc */
 	struct qe_brg		brg;		/* brg */
-	struct usb_ctlr		usb;		/* USB */
+	struct qe_usb_ctlr	usb;		/* USB */
 	struct si1		si1;		/* SI */
 	u8			res11[0x800];
 	struct sir		sir;		/* SI Routing Tables */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/irq.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/irq.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,6 @@
 #include <asm/atomic.h>
 
 
-#define get_irq_desc(irq) (&irq_desc[(irq)])
-
 /* Define a way to iterate across irqs. */
 #define for_each_irq(i) \
 	for ((i) = 0; (i) < NR_IRQS; ++(i))
@@ -34,12 +32,15 @@ extern atomic_t ppc_n_lost_interrupts;
  */
 #define NO_IRQ_IGNORE		((unsigned int)-1)
 
-/* Total number of virq in the platform (make it a CONFIG_* option ? */
-#define NR_IRQS		512
+/* Total number of virq in the platform */
+#define NR_IRQS		CONFIG_NR_IRQS
 
 /* Number of irqs reserved for the legacy controller */
 #define NUM_ISA_INTERRUPTS	16
 
+/* Same thing, used by the generic IRQ code */
+#define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
+
 /* This type is the placeholder for a hardware interrupt number. It has to
  * be big enough to enclose whatever representation is used by a given
  * platform.
@@ -99,7 +100,7 @@ struct irq_host_ops {
 	 * interrupt controller has for that line)
 	 */
 	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
-		     u32 *intspec, unsigned int intsize,
+		     const u32 *intspec, unsigned int intsize,
 		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
 };
 
@@ -313,7 +314,7 @@ extern void irq_free_virt(unsigned int v
  * of the of_irq_map_*() functions.
  */
 extern unsigned int irq_create_of_mapping(struct device_node *controller,
-					  u32 *intspec, unsigned int intsize);
+					  const u32 *intspec, unsigned int intsize);
 
 /**
  * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_asm.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_asm.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_asm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_asm.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,46 @@
 #define BOOKE_INTERRUPT_SPE_FP_ROUND 34
 #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
 
+/* book3s */
+
+#define BOOK3S_INTERRUPT_SYSTEM_RESET	0x100
+#define BOOK3S_INTERRUPT_MACHINE_CHECK	0x200
+#define BOOK3S_INTERRUPT_DATA_STORAGE	0x300
+#define BOOK3S_INTERRUPT_DATA_SEGMENT	0x380
+#define BOOK3S_INTERRUPT_INST_STORAGE	0x400
+#define BOOK3S_INTERRUPT_INST_SEGMENT	0x480
+#define BOOK3S_INTERRUPT_EXTERNAL	0x500
+#define BOOK3S_INTERRUPT_ALIGNMENT	0x600
+#define BOOK3S_INTERRUPT_PROGRAM	0x700
+#define BOOK3S_INTERRUPT_FP_UNAVAIL	0x800
+#define BOOK3S_INTERRUPT_DECREMENTER	0x900
+#define BOOK3S_INTERRUPT_SYSCALL	0xc00
+#define BOOK3S_INTERRUPT_TRACE		0xd00
+#define BOOK3S_INTERRUPT_PERFMON	0xf00
+#define BOOK3S_INTERRUPT_ALTIVEC	0xf20
+#define BOOK3S_INTERRUPT_VSX		0xf40
+
+#define BOOK3S_IRQPRIO_SYSTEM_RESET		0
+#define BOOK3S_IRQPRIO_DATA_SEGMENT		1
+#define BOOK3S_IRQPRIO_INST_SEGMENT		2
+#define BOOK3S_IRQPRIO_DATA_STORAGE		3
+#define BOOK3S_IRQPRIO_INST_STORAGE		4
+#define BOOK3S_IRQPRIO_ALIGNMENT		5
+#define BOOK3S_IRQPRIO_PROGRAM			6
+#define BOOK3S_IRQPRIO_FP_UNAVAIL		7
+#define BOOK3S_IRQPRIO_ALTIVEC			8
+#define BOOK3S_IRQPRIO_VSX			9
+#define BOOK3S_IRQPRIO_SYSCALL			10
+#define BOOK3S_IRQPRIO_MACHINE_CHECK		11
+#define BOOK3S_IRQPRIO_DEBUG			12
+#define BOOK3S_IRQPRIO_EXTERNAL			13
+#define BOOK3S_IRQPRIO_DECREMENTER		14
+#define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR	15
+#define BOOK3S_IRQPRIO_MAX			16
+
+#define BOOK3S_HFLAG_DCBZ32			0x1
+#define BOOK3S_HFLAG_SLB			0x2
+
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s_64_asm.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#ifndef __ASM_KVM_BOOK3S_ASM_H__
+#define __ASM_KVM_BOOK3S_ASM_H__
+
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+
+#include <asm/kvm_asm.h>
+
+.macro DO_KVM intno
+	.if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \
+	    (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \
+	    (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \
+	    (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \
+	    (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
+	    (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
+	    (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
+	    (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
+	    (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
+	    (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
+	    (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \
+	    (\intno == BOOK3S_INTERRUPT_SYSCALL) || \
+	    (\intno == BOOK3S_INTERRUPT_TRACE) || \
+	    (\intno == BOOK3S_INTERRUPT_PERFMON) || \
+	    (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \
+	    (\intno == BOOK3S_INTERRUPT_VSX)
+
+	b	kvmppc_trampoline_\intno
+kvmppc_resume_\intno:
+
+	.endif
+.endm
+
+#else
+
+.macro DO_KVM intno
+.endm
+
+#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */
+
+#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_book3s.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_book3s.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_book3s.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,139 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#ifndef __ASM_KVM_BOOK3S_H__
+#define __ASM_KVM_BOOK3S_H__
+
+#include <linux/types.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_ppc.h>
+
+struct kvmppc_slb {
+	u64 esid;
+	u64 vsid;
+	u64 orige;
+	u64 origv;
+	bool valid;
+	bool Ks;
+	bool Kp;
+	bool nx;
+	bool large;
+	bool class;
+};
+
+struct kvmppc_sr {
+	u32 raw;
+	u32 vsid;
+	bool Ks;
+	bool Kp;
+	bool nx;
+};
+
+struct kvmppc_bat {
+	u64 raw;
+	u32 bepi;
+	u32 bepi_mask;
+	bool vs;
+	bool vp;
+	u32 brpn;
+	u8 wimg;
+	u8 pp;
+};
+
+struct kvmppc_sid_map {
+	u64 guest_vsid;
+	u64 guest_esid;
+	u64 host_vsid;
+	bool valid;
+};
+
+#define SID_MAP_BITS    9
+#define SID_MAP_NUM     (1 << SID_MAP_BITS)
+#define SID_MAP_MASK    (SID_MAP_NUM - 1)
+
+struct kvmppc_vcpu_book3s {
+	struct kvm_vcpu vcpu;
+	struct kvmppc_sid_map sid_map[SID_MAP_NUM];
+	struct kvmppc_slb slb[64];
+	struct {
+		u64 esid;
+		u64 vsid;
+	} slb_shadow[64];
+	u8 slb_shadow_max;
+	struct kvmppc_sr sr[16];
+	struct kvmppc_bat ibat[8];
+	struct kvmppc_bat dbat[8];
+	u64 hid[6];
+	int slb_nr;
+	u64 sdr1;
+	u64 dsisr;
+	u64 hior;
+	u64 msr_mask;
+	u64 vsid_first;
+	u64 vsid_next;
+	u64 vsid_max;
+	int context_id;
+};
+
+#define CONTEXT_HOST		0
+#define CONTEXT_GUEST		1
+#define CONTEXT_GUEST_END	2
+
+#define VSID_REAL	0xfffffffffff00000
+#define VSID_REAL_DR	0xffffffffffe00000
+#define VSID_REAL_IR	0xffffffffffd00000
+#define VSID_BAT	0xffffffffffc00000
+#define VSID_PR		0x8000000000000000
+
+extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask);
+extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask);
+extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end);
+extern void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 new_msr);
+extern void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu);
+extern void kvmppc_mmu_book3s_32_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_segments(struct kvm_vcpu *vcpu);
+extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data);
+extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data);
+extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
+extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
+extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
+			   bool upper, u32 val);
+
+extern u32 kvmppc_trampoline_lowmem;
+extern u32 kvmppc_trampoline_enter;
+
+static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
+{
+	return container_of(vcpu, struct kvmppc_vcpu_book3s, vcpu);
+}
+
+static inline ulong dsisr(void)
+{
+	ulong r;
+	asm ( "mfdsisr %0 " : "=r" (r) );
+	return r;
+}
+
+extern void kvm_return_point(void);
+
+#define INS_DCBZ			0x7c0007ec
+
+#endif /* __ASM_KVM_BOOK3S_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm.h	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,24 @@ struct kvm_regs {
 };
 
 struct kvm_sregs {
+	__u32 pvr;
+	union {
+		struct {
+			__u64 sdr1;
+			struct {
+				struct {
+					__u64 slbe;
+					__u64 slbv;
+				} slb[64];
+			} ppc64;
+			struct {
+				__u32 sr[16];
+				__u64 ibat[8]; 
+				__u64 dbat[8]; 
+			} ppc32;
+		} s;
+		__u8 pad[1020];
+	} u;
 };
 
 struct kvm_fpu {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_host.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_host.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_host.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_host.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,8 @@
 #define __POWERPC_KVM_HOST_H__
 
 #include <linux/mutex.h>
-#include <linux/timer.h>
+#include <linux/hrtimer.h>
+#include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/kvm_types.h>
 #include <asm/kvm_asm.h>
@@ -37,6 +38,8 @@
 #define KVM_NR_PAGE_SIZES	1
 #define KVM_PAGES_PER_HPAGE(x)	(1UL<<31)
 
+#define HPTEG_CACHE_NUM 1024
+
 struct kvm;
 struct kvm_run;
 struct kvm_vcpu;
@@ -63,6 +66,17 @@ struct kvm_vcpu_stat {
 	u32 dec_exits;
 	u32 ext_intr_exits;
 	u32 halt_wakeup;
+#ifdef CONFIG_PPC64
+	u32 pf_storage;
+	u32 pf_instruc;
+	u32 sp_storage;
+	u32 sp_instruc;
+	u32 queue_intr;
+	u32 ld;
+	u32 ld_slow;
+	u32 st;
+	u32 st_slow;
+#endif
 };
 
 enum kvm_exit_types {
@@ -109,9 +123,53 @@ struct kvmppc_exit_timing {
 struct kvm_arch {
 };
 
+struct kvmppc_pte {
+	u64 eaddr;
+	u64 vpage;
+	u64 raddr;
+	bool may_read;
+	bool may_write;
+	bool may_execute;
+};
+
+struct kvmppc_mmu {
+	/* book3s_64 only */
+	void (*slbmte)(struct kvm_vcpu *vcpu, u64 rb, u64 rs);
+	u64  (*slbmfee)(struct kvm_vcpu *vcpu, u64 slb_nr);
+	u64  (*slbmfev)(struct kvm_vcpu *vcpu, u64 slb_nr);
+	void (*slbie)(struct kvm_vcpu *vcpu, u64 slb_nr);
+	void (*slbia)(struct kvm_vcpu *vcpu);
+	/* book3s */
+	void (*mtsrin)(struct kvm_vcpu *vcpu, u32 srnum, ulong value);
+	u32  (*mfsrin)(struct kvm_vcpu *vcpu, u32 srnum);
+	int  (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data);
+	void (*reset_msr)(struct kvm_vcpu *vcpu);
+	void (*tlbie)(struct kvm_vcpu *vcpu, ulong addr, bool large);
+	int  (*esid_to_vsid)(struct kvm_vcpu *vcpu, u64 esid, u64 *vsid);
+	u64  (*ea_to_vp)(struct kvm_vcpu *vcpu, gva_t eaddr, bool data);
+	bool (*is_dcbz32)(struct kvm_vcpu *vcpu);
+};
+
+struct hpte_cache {
+	u64 host_va;
+	u64 pfn;
+	ulong slot;
+	struct kvmppc_pte pte;
+};
+
 struct kvm_vcpu_arch {
-	u32 host_stack;
+	ulong host_stack;
 	u32 host_pid;
+#ifdef CONFIG_PPC64
+	ulong host_msr;
+	ulong host_r2;
+	void *host_retip;
+	ulong trampoline_lowmem;
+	ulong trampoline_enter;
+	ulong highmem_handler;
+	ulong host_paca_phys;
+	struct kvmppc_mmu mmu;
+#endif
 
 	u64 fpr[32];
 	ulong gpr[32];
@@ -123,6 +181,10 @@ struct kvm_vcpu_arch {
 	ulong xer;
 
 	ulong msr;
+#ifdef CONFIG_PPC64
+	ulong shadow_msr;
+	ulong hflags;
+#endif
 	u32 mmucr;
 	ulong sprg0;
 	ulong sprg1;
@@ -149,6 +211,7 @@ struct kvm_vcpu_arch {
 	u32 ivor[64];
 	ulong ivpr;
 	u32 pir;
+	u32 pvr;
 
 	u32 shadow_pid;
 	u32 pid;
@@ -174,6 +237,9 @@ struct kvm_vcpu_arch {
 #endif
 
 	u32 last_inst;
+#ifdef CONFIG_PPC64
+	ulong fault_dsisr;
+#endif
 	ulong fault_dear;
 	ulong fault_esr;
 	gpa_t paddr_accessed;
@@ -185,8 +251,15 @@ struct kvm_vcpu_arch {
 
 	u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
 
-	struct timer_list dec_timer;
+	struct hrtimer dec_timer;
+	struct tasklet_struct tasklet;
+	u64 dec_jiffies;
 	unsigned long pending_exceptions;
+
+#ifdef CONFIG_PPC64
+	struct hpte_cache hpte_cache[HPTEG_CACHE_NUM];
+	int hpte_cache_offset;
+#endif
 };
 
 #endif /* __POWERPC_KVM_HOST_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_ppc.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_ppc.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,7 @@ enum emulation_result {
 extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 extern char kvmppc_handlers_start[];
 extern unsigned long kvmppc_handler_len;
+extern void kvmppc_handler_highmem(void);
 
 extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
 extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/lppaca.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/lppaca.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/lppaca.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/lppaca.h	2010-02-24 13:52:17.000000000 -0500
@@ -100,7 +100,14 @@ struct lppaca {
 	// Used to pass parms from the OS to PLIC for SetAsrAndRfid
 	u64	saved_gpr3;		// Saved GPR3                   x20-x27
 	u64	saved_gpr4;		// Saved GPR4                   x28-x2F
-	u64	saved_gpr5;		// Saved GPR5                   x30-x37
+	union {
+		u64	saved_gpr5;	/* Saved GPR5               x30-x37 */
+		struct {
+			u8	cede_latency_hint;  /*			x30 */
+			u8	reserved[7];        /*		    x31-x36 */
+		} fields;
+	} gpr5_dword;
+
 
 	u8	dtl_enable_mask;	// Dispatch Trace Log mask	x38-x38
 	u8	donate_dedicated_cpu;	// Donate dedicated CPU cycles  x39-x39
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/machdep.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/machdep.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/machdep.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/machdep.h	2010-02-24 13:52:17.000000000 -0500
@@ -266,6 +266,11 @@ struct machdep_calls {
 	void (*suspend_disable_irqs)(void);
 	void (*suspend_enable_irqs)(void);
 #endif
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+	ssize_t (*cpu_probe)(const char *, size_t);
+	ssize_t (*cpu_release)(const char *, size_t);
+#endif
 };
 
 extern void e500_idle(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/macio.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/macio.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/macio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/macio.h	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,7 @@ struct macio_dev
 	struct macio_bus	*bus;		/* macio bus this device is on */
 	struct macio_dev	*media_bay;	/* Device is part of a media bay */
 	struct of_device	ofdev;
+	struct device_dma_parameters dma_parms; /* ide needs that */
 	int			n_resources;
 	struct resource		resource[MACIO_DEV_COUNT_RESOURCES];
 	int			n_interrupts;
@@ -78,6 +79,8 @@ static inline unsigned long macio_resour
 	return res->end - res->start + 1;
 }
 
+extern int macio_enable_devres(struct macio_dev *dev);
+
 extern int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name);
 extern void macio_release_resource(struct macio_dev *dev, int resource_no);
 extern int macio_request_resources(struct macio_dev *dev, const char *name);
@@ -131,6 +134,9 @@ struct macio_driver
 	int	(*resume)(struct macio_dev* dev);
 	int	(*shutdown)(struct macio_dev* dev);
 
+#ifdef CONFIG_PMAC_MEDIABAY
+	void	(*mediabay_event)(struct macio_dev* dev, int mb_state);
+#endif
 	struct device_driver	driver;
 };
 #define	to_macio_driver(drv) container_of(drv,struct macio_driver, driver)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mediabay.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mediabay.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mediabay.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mediabay.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,26 +17,31 @@
 #define MB_POWER	6	/* media bay contains a Power device (???) */
 #define MB_NO		7	/* media bay contains nothing */
 
-/* Number of bays in the machine or 0 */
-extern int media_bay_count;
+struct macio_dev;
 
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-#include <linux/ide.h>
+#ifdef CONFIG_PMAC_MEDIABAY
 
-int check_media_bay_by_base(unsigned long base, int what);
-/* called by IDE PMAC host driver to register IDE controller for media bay */
-int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
-			    int irq, ide_hwif_t *hwif);
+/* Check the content type of the bay, returns MB_NO if the bay is still
+ * transitionning
+ */
+extern int check_media_bay(struct macio_dev *bay);
 
-int check_media_bay(struct device_node *which_bay, int what);
+/* The ATA driver uses the calls below to temporarily hold on the
+ * media bay callbacks while initializing the interface
+ */
+extern void lock_media_bay(struct macio_dev *bay);
+extern void unlock_media_bay(struct macio_dev *bay);
 
 #else
 
-static inline int check_media_bay(struct device_node *which_bay, int what)
+static inline int check_media_bay(struct macio_dev *bay)
 {
-	return -ENODEV;
+	return MB_NO;
 }
 
+static inline void lock_media_bay(struct macio_dev *bay) { }
+static inline void unlock_media_bay(struct macio_dev *bay) { }
+
 #endif
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mmu_context.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mmu_context.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mmu_context.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,8 @@ extern void switch_slb(struct task_struc
 extern void set_context(unsigned long id, pgd_t *pgd);
 
 #ifdef CONFIG_PPC_BOOK3S_64
+extern int __init_new_context(void);
+extern void __destroy_context(int context_id);
 static inline void mmu_context_init(void) { }
 #else
 extern void mmu_context_init(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mmu-hash64.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mmu-hash64.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2010-02-24 13:52:17.000000000 -0500
@@ -173,14 +173,6 @@ extern unsigned long tce_alloc_start, tc
  */
 extern int mmu_ci_restrictions;
 
-#ifdef CONFIG_HUGETLB_PAGE
-/*
- * The page size indexes of the huge pages for use by hugetlbfs
- */
-extern unsigned int mmu_huge_psizes[MMU_PAGE_COUNT];
-
-#endif /* CONFIG_HUGETLB_PAGE */
-
 /*
  * This function sets the AVPN and L fields of the HPTE  appropriately
  * for the page size
@@ -253,10 +245,11 @@ extern int __hash_page_64K(unsigned long
 			   unsigned long vsid, pte_t *ptep, unsigned long trap,
 			   unsigned int local, int ssize);
 struct mm_struct;
+unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
 extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap);
-extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
-			  unsigned long ea, unsigned long vsid, int local,
-			  unsigned long trap);
+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);
 
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
 			     unsigned long pstart, unsigned long prot,
@@ -380,6 +373,38 @@ extern void slb_set_size(u16 size);
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * For the sub-page protection option, we extend the PGD with one of
+ * these.  Basically we have a 3-level tree, with the top level being
+ * the protptrs array.  To optimize speed and memory consumption when
+ * only addresses < 4GB are being protected, pointers to the first
+ * four pages of sub-page protection words are stored in the low_prot
+ * array.
+ * Each page of sub-page protection words protects 1GB (4 bytes
+ * protects 64k).  For the 3-level tree, each page of pointers then
+ * protects 8TB.
+ */
+struct subpage_prot_table {
+	unsigned long maxaddr;	/* only addresses < this are protected */
+	unsigned int **protptrs[2];
+	unsigned int *low_prot[4];
+};
+
+#define SBP_L1_BITS		(PAGE_SHIFT - 2)
+#define SBP_L2_BITS		(PAGE_SHIFT - 3)
+#define SBP_L1_COUNT		(1 << SBP_L1_BITS)
+#define SBP_L2_COUNT		(1 << SBP_L2_BITS)
+#define SBP_L2_SHIFT		(PAGE_SHIFT + SBP_L1_BITS)
+#define SBP_L3_SHIFT		(SBP_L2_SHIFT + SBP_L2_BITS)
+
+extern void subpage_prot_free(struct mm_struct *mm);
+extern void subpage_prot_init_new_context(struct mm_struct *mm);
+#else
+static inline void subpage_prot_free(struct mm_struct *mm) {}
+static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+
 typedef unsigned long mm_context_id_t;
 
 typedef struct {
@@ -393,6 +418,9 @@ typedef struct {
 	u16 sllp;		/* SLB page size encoding */
 #endif
 	unsigned long vdso_base;
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+	struct subpage_prot_table spt;
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
 } mm_context_t;
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/module.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/module.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/module.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/module.h	2010-02-24 13:52:17.000000000 -0500
@@ -87,5 +87,10 @@ struct exception_table_entry;
 void sort_ex_table(struct exception_table_entry *start,
 		   struct exception_table_entry *finish);
 
+#ifdef CONFIG_MODVERSIONS
+#define ARCH_RELOCATES_KCRCTAB
+
+extern const unsigned long reloc_start[];
+#endif
 #endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_MODULE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mpc52xx.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc52xx.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/mpc52xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/mpc52xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -276,6 +276,53 @@ extern int mpc52xx_set_psc_clkdiv(int ps
 extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
 extern void mpc52xx_restart(char *cmd);
 
+/* mpc52xx_gpt.c */
+struct mpc52xx_gpt_priv;
+extern struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq);
+extern int mpc52xx_gpt_start_timer(struct mpc52xx_gpt_priv *gpt, u64 period,
+                            int continuous);
+extern u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt);
+extern int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt);
+
+/* mpc52xx_lpbfifo.c */
+#define MPC52XX_LPBFIFO_FLAG_READ		(0)
+#define MPC52XX_LPBFIFO_FLAG_WRITE		(1<<0)
+#define MPC52XX_LPBFIFO_FLAG_NO_INCREMENT	(1<<1)
+#define MPC52XX_LPBFIFO_FLAG_NO_DMA		(1<<2)
+#define MPC52XX_LPBFIFO_FLAG_POLL_DMA		(1<<3)
+
+struct mpc52xx_lpbfifo_request {
+	struct list_head list;
+
+	/* localplus bus address */
+	unsigned int cs;
+	size_t offset;
+
+	/* Memory address */
+	void *data;
+	phys_addr_t data_phys;
+
+	/* Details of transfer */
+	size_t size;
+	size_t pos;	/* current position of transfer */
+	int flags;
+
+	/* What to do when finished */
+	void (*callback)(struct mpc52xx_lpbfifo_request *);
+
+	void *priv;		/* Driver private data */
+
+	/* statistics */
+	int irq_count;
+	int irq_ticks;
+	u8 last_byte;
+	int buffer_not_done_cnt;
+};
+
+extern int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req);
+extern void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req);
+extern void mpc52xx_lpbfifo_poll(void);
+
 /* mpc52xx_pic.c */
 extern void mpc52xx_init_irq(void);
 extern unsigned int mpc52xx_get_irq(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/nvram.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/nvram.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/nvram.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/nvram.h	2010-02-24 13:52:17.000000000 -0500
@@ -73,7 +73,6 @@ extern int nvram_write_error_log(char *
 extern int nvram_read_error_log(char * buff, int length,
 					 unsigned int * err_type, unsigned int *err_seq);
 extern int nvram_clear_error_log(void);
-extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
 
 extern int pSeries_nvram_init(void);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/paca.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/paca.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/paca.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/paca.h	2010-02-24 13:52:17.000000000 -0500
@@ -129,6 +129,15 @@ struct paca_struct {
 	u64 system_time;		/* accumulated system TB ticks */
 	u64 startpurr;			/* PURR/TB value snapshot */
 	u64 startspurr;			/* SPURR value snapshot */
+
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+	struct  {
+		u64     esid;
+		u64     vsid;
+	} kvm_slb[64];			/* guest SLB */
+	u8 kvm_slb_max;			/* highest used guest slb entry */
+	u8 kvm_in_guest;		/* are we inside the guest? */
+#endif
 };
 
 extern struct paca_struct paca[];
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/page_64.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page_64.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/page_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -90,7 +90,7 @@ extern unsigned int HPAGE_SHIFT;
 #define HPAGE_SIZE		((1UL) << HPAGE_SHIFT)
 #define HPAGE_MASK		(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
-#define HUGE_MAX_HSTATE		3
+#define HUGE_MAX_HSTATE		(MMU_PAGE_COUNT-1)
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/page.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/page.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
@@ -229,6 +229,20 @@ typedef unsigned long pgprot_t;
 
 #endif
 
+typedef struct { signed long pd; } hugepd_t;
+#define HUGEPD_SHIFT_MASK     0x3f
+
+#ifdef CONFIG_HUGETLB_PAGE
+static inline int hugepd_ok(hugepd_t hpd)
+{
+	return (hpd.pd > 0);
+}
+
+#define is_hugepd(pdep)               (hugepd_ok(*((hugepd_t *)(pdep))))
+#else /* CONFIG_HUGETLB_PAGE */
+#define is_hugepd(pdep)			0
+#endif /* CONFIG_HUGETLB_PAGE */
+
 struct page;
 extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
 extern void copy_user_page(void *to, void *from, unsigned long vaddr,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc-32.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc-32.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc-32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc-32.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,8 @@
 
 #include <linux/threads.h>
 
-#define PTE_NONCACHE_NUM	0  /* dummy for now to share code w/ppc64 */
+/* For 32-bit, all levels of page tables are just drawn from get_free_page() */
+#define MAX_PGTABLE_INDEX_SIZE	0
 
 extern void __bad_pte(pmd_t *pmd);
 
@@ -36,11 +37,10 @@ extern void pgd_free(struct mm_struct *m
 extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
 extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
 
-static inline void pgtable_free(pgtable_free_t pgf)
+static inline void pgtable_free(void *table, unsigned index_size)
 {
-	void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
-
-	free_page((unsigned long)p);
+	BUG_ON(index_size); /* 32-bit doesn't use this */
+	free_page((unsigned long)table);
 }
 
 #define check_pgt_cache()	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc-64.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc-64.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc-64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc-64.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,27 +11,34 @@
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
 
-#ifndef CONFIG_PPC_SUBPAGE_PROT
-static inline void subpage_prot_free(pgd_t *pgd) {}
-#endif
+/*
+ * Functions that deal with pagetables that could be at any level of
+ * the table need to be passed an "index_size" so they know how to
+ * handle allocation.  For PTE pages (which are linked to a struct
+ * page for now, and drawn from the main get_free_pages() pool), the
+ * allocation size will be (2^index_size * sizeof(pointer)) and
+ * allocations are drawn from the kmem_cache in PGT_CACHE(index_size).
+ *
+ * The maximum index size needs to be big enough to allow any
+ * pagetable sizes we need, but small enough to fit in the low bits of
+ * any page table pointer.  In other words all pagetables, even tiny
+ * ones, must be aligned to allow at least enough low 0 bits to
+ * contain this value.  This value is also used as a mask, so it must
+ * be one less than a power of two.
+ */
+#define MAX_PGTABLE_INDEX_SIZE	0xf
 
 extern struct kmem_cache *pgtable_cache[];
-
-#define PGD_CACHE_NUM		0
-#define PUD_CACHE_NUM		1
-#define PMD_CACHE_NUM		1
-#define HUGEPTE_CACHE_NUM	2
-#define PTE_NONCACHE_NUM	7  /* from GFP rather than kmem_cache */
+#define PGT_CACHE(shift) (pgtable_cache[(shift)-1])
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
+	return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL);
 }
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	subpage_prot_free(pgd);
-	kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
+	kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
 }
 
 #ifndef CONFIG_PPC_64K_PAGES
@@ -40,13 +47,13 @@ static inline void pgd_free(struct mm_st
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
+	return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
 				GFP_KERNEL|__GFP_REPEAT);
 }
 
 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
-	kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
+	kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
 }
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
@@ -78,13 +85,13 @@ static inline void pmd_populate_kernel(s
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
+	return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE),
 				GFP_KERNEL|__GFP_REPEAT);
 }
 
 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
-	kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
+	kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd);
 }
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
@@ -107,24 +114,22 @@ static inline pgtable_t pte_alloc_one(st
 	return page;
 }
 
-static inline void pgtable_free(pgtable_free_t pgf)
+static inline void pgtable_free(void *table, unsigned index_size)
 {
-	void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
-	int cachenum = pgf.val & PGF_CACHENUM_MASK;
-
-	if (cachenum == PTE_NONCACHE_NUM)
-		free_page((unsigned long)p);
-	else
-		kmem_cache_free(pgtable_cache[cachenum], p);
+	if (!index_size)
+		free_page((unsigned long)table);
+	else {
+		BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
+		kmem_cache_free(PGT_CACHE(index_size), table);
+	}
 }
 
-#define __pmd_free_tlb(tlb, pmd,addr)		      \
-	pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
-		PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
+#define __pmd_free_tlb(tlb, pmd, addr)		      \
+	pgtable_free_tlb(tlb, pmd, PMD_INDEX_SIZE)
 #ifndef CONFIG_PPC_64K_PAGES
 #define __pud_free_tlb(tlb, pud, addr)		      \
-	pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
-		PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
+	pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
+
 #endif /* CONFIG_PPC_64K_PAGES */
 
 #define check_pgt_cache()	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgalloc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,25 +24,6 @@ static inline void pte_free(struct mm_st
 	__free_page(ptepage);
 }
 
-typedef struct pgtable_free {
-	unsigned long val;
-} pgtable_free_t;
-
-/* This needs to be big enough to allow for MMU_PAGE_COUNT + 2 to be stored
- * and small enough to fit in the low bits of any naturally aligned page
- * table cache entry. Arbitrarily set to 0x1f, that should give us some
- * room to grow
- */
-#define PGF_CACHENUM_MASK	0x1f
-
-static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
-						unsigned long mask)
-{
-	BUG_ON(cachenum > PGF_CACHENUM_MASK);
-
-	return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
-}
-
 #ifdef CONFIG_PPC64
 #include <asm/pgalloc-64.h>
 #else
@@ -50,12 +31,12 @@ static inline pgtable_free_t pgtable_fre
 #endif
 
 #ifdef CONFIG_SMP
-extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
+extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift);
 extern void pte_free_finish(void);
 #else /* CONFIG_SMP */
-static inline void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
+static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
 {
-	pgtable_free(pgf);
+	pgtable_free(table, shift);
 }
 static inline void pte_free_finish(void) { }
 #endif /* !CONFIG_SMP */
@@ -63,12 +44,9 @@ static inline void pte_free_finish(void)
 static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
 				  unsigned long address)
 {
-	pgtable_free_t pgf = pgtable_free_cache(page_address(ptepage),
-						PTE_NONCACHE_NUM,
-						PTE_TABLE_SIZE-1);
 	tlb_flush_pgtable(tlb, address);
 	pgtable_page_dtor(ptepage);
-	pgtable_free_tlb(tlb, pgf);
+	pgtable_free_tlb(tlb, page_address(ptepage), 0);
 }
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -211,6 +211,9 @@ extern void paging_init(void);
  */
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
+extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr,
+		      unsigned long end, int write, struct page **pages, int *nr);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h	2010-02-24 13:52:17.000000000 -0500
@@ -354,6 +354,7 @@ static inline void __ptep_set_access_fla
 #define pgoff_to_pte(off)	((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
 #define PTE_FILE_MAX_BITS	(BITS_PER_LONG - PTE_RPN_SHIFT)
 
+void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
 void pgtable_cache_init(void);
 
 /*
@@ -378,7 +379,18 @@ void pgtable_cache_init(void);
 	return pt;
 }
 
-pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long address);
+#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)
+{
+	if (shift)
+		*shift = 0;
+	return find_linux_pte(pgdir, ea);
+}
+#endif /* !CONFIG_HUGETLB_PAGE */
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pmac_low_i2c.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pmac_low_i2c.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pmac_low_i2c.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pmac_low_i2c.h	2010-02-24 13:52:17.000000000 -0500
@@ -72,11 +72,7 @@ extern int pmac_i2c_get_type(struct pmac
 extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus);
 extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus);
 
-/* i2c layer adapter attach/detach */
-extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
-				    struct i2c_adapter *adapter);
-extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
-				    struct i2c_adapter *adapter);
+/* i2c layer adapter helpers */
 extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus);
 extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/prom.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/prom.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/prom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/prom.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,4 @@
+#include <linux/of.h>	/* linux/of.h gets to determine #include ordering */
 #ifndef _POWERPC_PROM_H
 #define _POWERPC_PROM_H
 #ifdef __KERNEL__
@@ -16,6 +17,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/types.h>
+#include <linux/of_fdt.h>
 #include <linux/proc_fs.h>
 #include <linux/platform_device.h>
 #include <asm/irq.h>
@@ -28,133 +30,14 @@
 #define of_prop_cmp(s1, s2)		strcmp((s1), (s2))
 #define of_node_cmp(s1, s2)		strcasecmp((s1), (s2))
 
-/* Definitions used by the flattened device tree */
-#define OF_DT_HEADER		0xd00dfeed	/* marker */
-#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
-#define OF_DT_END_NODE		0x2		/* End node */
-#define OF_DT_PROP		0x3		/* Property: name off, size,
-						 * content */
-#define OF_DT_NOP		0x4		/* nop */
-#define OF_DT_END		0x9
-
-#define OF_DT_VERSION		0x10
-
-/*
- * This is what gets passed to the kernel by prom_init or kexec
- *
- * The dt struct contains the device tree structure, full pathes and
- * property contents. The dt strings contain a separate block with just
- * the strings for the property names, and is fully page aligned and
- * self contained in a page, so that it can be kept around by the kernel,
- * each property name appears only once in this page (cheap compression)
- *
- * the mem_rsvmap contains a map of reserved ranges of physical memory,
- * passing it here instead of in the device-tree itself greatly simplifies
- * the job of everybody. It's just a list of u64 pairs (base/size) that
- * ends when size is 0
- */
-struct boot_param_header
-{
-	u32	magic;			/* magic word OF_DT_HEADER */
-	u32	totalsize;		/* total size of DT block */
-	u32	off_dt_struct;		/* offset to structure */
-	u32	off_dt_strings;		/* offset to strings */
-	u32	off_mem_rsvmap;		/* offset to memory reserve map */
-	u32	version;		/* format version */
-	u32	last_comp_version;	/* last compatible version */
-	/* version 2 fields below */
-	u32	boot_cpuid_phys;	/* Physical CPU id we're booting on */
-	/* version 3 fields below */
-	u32	dt_strings_size;	/* size of the DT strings block */
-	/* version 17 fields below */
-	u32	dt_struct_size;		/* size of the DT structure block */
-};
-
-
-
-typedef u32 phandle;
-typedef u32 ihandle;
-
-struct property {
-	char	*name;
-	int	length;
-	void	*value;
-	struct property *next;
-};
-
-struct device_node {
-	const char *name;
-	const char *type;
-	phandle	node;
-	phandle linux_phandle;
-	char	*full_name;
-
-	struct	property *properties;
-	struct  property *deadprops; /* removed properties */
-	struct	device_node *parent;
-	struct	device_node *child;
-	struct	device_node *sibling;
-	struct	device_node *next;	/* next device of same type */
-	struct	device_node *allnext;	/* next in list of all nodes */
-	struct  proc_dir_entry *pde;	/* this node's proc directory */
-	struct  kref kref;
-	unsigned long _flags;
-	void	*data;
-};
-
 extern struct device_node *of_chosen;
 
-static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
-{
-	return test_bit(flag, &n->_flags);
-}
-
-static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
-{
-	set_bit(flag, &n->_flags);
-}
-
-
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
-static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
-{
-	dn->pde = de;
-}
-
-
-extern struct device_node *of_find_all_nodes(struct device_node *prev);
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-
-/* For scanning the flat device-tree at boot time */
-extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
-					    const char *uname, int depth,
-					    void *data),
-				  void *data);
-extern void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
-					unsigned long *size);
-extern int __init of_flat_dt_is_compatible(unsigned long node, const char *name);
-extern unsigned long __init of_get_flat_dt_root(void);
-
 /* For updating the device tree at runtime */
 extern void of_attach_node(struct device_node *);
 extern void of_detach_node(struct device_node *);
 
-/* Other Prototypes */
-extern void finish_device_tree(void);
-extern void unflatten_device_tree(void);
-extern void early_init_devtree(void *);
-extern int machine_is_compatible(const char *compat);
-extern void print_properties(struct device_node *node);
-extern int prom_n_intr_cells(struct device_node* np);
-extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern int prom_add_property(struct device_node* np, struct property* prop);
-extern int prom_remove_property(struct device_node *np, struct property *prop);
-extern int prom_update_property(struct device_node *np,
-				struct property *newprop,
-				struct property *oldprop);
-
 #ifdef CONFIG_PPC32
 /*
  * PCI <-> OF matching functions
@@ -178,26 +61,6 @@ extern int release_OF_resource(struct de
  * OF address retreival & translation
  */
 
-
-/* Helper to read a big number; size is in cells (not bytes) */
-static inline u64 of_read_number(const u32 *cell, int size)
-{
-	u64 r = 0;
-	while (size--)
-		r = (r << 32) | *(cell++);
-	return r;
-}
-
-/* Like of_read_number, but we want an unsigned long result */
-#ifdef CONFIG_PPC32
-static inline unsigned long of_read_ulong(const u32 *cell, int size)
-{
-	return cell[size-1];
-}
-#else
-#define of_read_ulong(cell, size)	of_read_number(cell, size)
-#endif
-
 /* Translate an OF address block into a CPU physical address
  */
 extern u64 of_translate_address(struct device_node *np, const u32 *addr);
@@ -349,11 +212,5 @@ extern int of_irq_to_resource(struct dev
  */
 extern void __iomem *of_iomap(struct device_node *device, int index);
 
-/*
- * NB:  This is here while we transition from using asm/prom.h
- * to linux/of.h
- */
-#include <linux/of.h>
-
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pSeries_reconfig.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pSeries_reconfig.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pSeries_reconfig.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pSeries_reconfig.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 #ifdef CONFIG_PPC_PSERIES
 extern int pSeries_reconfig_notifier_register(struct notifier_block *);
 extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
+extern struct blocking_notifier_head pSeries_reconfig_chain;
 #else /* !CONFIG_PPC_PSERIES */
 static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pte-8xx.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pte-8xx.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pte-8xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pte-8xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,21 +33,21 @@
 #define _PAGE_NO_CACHE	0x0002	/* I: cache inhibit */
 #define _PAGE_SHARED	0x0004	/* No ASID (context) compare */
 #define _PAGE_SPECIAL	0x0008	/* SW entry, forced to 0 by the TLB miss */
+#define _PAGE_DIRTY	0x0100	/* C: page changed */
 
-/* These five software bits must be masked out when the entry is loaded
- * into the TLB.
+/* These 4 software bits must be masked out when the entry is loaded
+ * into the TLB, 1 SW bit left(0x0080).
  */
 #define _PAGE_GUARDED	0x0010	/* software: guarded access */
-#define _PAGE_DIRTY	0x0020	/* software: page changed */
-#define _PAGE_RW	0x0040	/* software: user write access allowed */
-#define _PAGE_ACCESSED	0x0080	/* software: page referenced */
+#define _PAGE_ACCESSED	0x0020	/* software: page referenced */
+#define _PAGE_WRITETHRU	0x0040	/* software: caching is write through */
 
 /* Setting any bits in the nibble with the follow two controls will
  * require a TLB exception handler change.  It is assumed unused bits
  * are always zero.
  */
-#define _PAGE_HWWRITE	0x0100	/* h/w write enable: never set in Linux PTE */
-#define _PAGE_USER	0x0800	/* One of the PP bits, the other is USER&~RW */
+#define _PAGE_RW	0x0400	/* lsb PP bits, inverted in HW */
+#define _PAGE_USER	0x0800	/* msb PP bits */
 
 #define _PMD_PRESENT	0x0001
 #define _PMD_BAD	0x0ff0
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,41 +76,4 @@
 	remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE,		\
 			__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
 
-
-#ifdef CONFIG_PPC_SUBPAGE_PROT
-/*
- * For the sub-page protection option, we extend the PGD with one of
- * these.  Basically we have a 3-level tree, with the top level being
- * the protptrs array.  To optimize speed and memory consumption when
- * only addresses < 4GB are being protected, pointers to the first
- * four pages of sub-page protection words are stored in the low_prot
- * array.
- * Each page of sub-page protection words protects 1GB (4 bytes
- * protects 64k).  For the 3-level tree, each page of pointers then
- * protects 8TB.
- */
-struct subpage_prot_table {
-	unsigned long maxaddr;	/* only addresses < this are protected */
-	unsigned int **protptrs[2];
-	unsigned int *low_prot[4];
-};
-
-#undef PGD_TABLE_SIZE
-#define PGD_TABLE_SIZE		((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
-				 sizeof(struct subpage_prot_table))
-
-#define SBP_L1_BITS		(PAGE_SHIFT - 2)
-#define SBP_L2_BITS		(PAGE_SHIFT - 3)
-#define SBP_L1_COUNT		(1 << SBP_L1_BITS)
-#define SBP_L2_COUNT		(1 << SBP_L2_BITS)
-#define SBP_L2_SHIFT		(PAGE_SHIFT + SBP_L1_BITS)
-#define SBP_L3_SHIFT		(SBP_L2_SHIFT + SBP_L2_BITS)
-
-extern void subpage_prot_free(pgd_t *pgd);
-
-static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
-{
-	return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
-}
-#endif /* CONFIG_PPC_SUBPAGE_PROT */
 #endif	/* __ASSEMBLY__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -140,6 +140,8 @@ extern void user_enable_single_step(stru
 extern void user_enable_block_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
+#define ARCH_HAS_USER_SINGLE_STEP_INFO
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/qe.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/qe.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/qe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/qe.h	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,7 @@ extern spinlock_t cmxgcr_lock;
 
 /* Export QE common operations */
 #ifdef CONFIG_QUICC_ENGINE
-extern void __init qe_reset(void);
+extern void qe_reset(void);
 #else
 static inline void qe_reset(void) {}
 #endif
@@ -145,8 +145,17 @@ static inline void qe_pin_set_gpio(struc
 static inline void qe_pin_set_dedicated(struct qe_pin *pin) {}
 #endif /* CONFIG_QE_GPIO */
 
-/* QE internal API */
+#ifdef CONFIG_QUICC_ENGINE
 int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
+#else
+static inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
+			       u32 cmd_input)
+{
+	return -ENOSYS;
+}
+#endif /* CONFIG_QUICC_ENGINE */
+
+/* QE internal API */
 enum qe_clock qe_clock_source(const char *source);
 unsigned int qe_get_brg_clk(void);
 int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
@@ -154,7 +163,28 @@ int qe_get_snum(void);
 void qe_put_snum(u8 snum);
 unsigned int qe_get_num_of_risc(void);
 unsigned int qe_get_num_of_snums(void);
-int qe_alive_during_sleep(void);
+
+static inline int qe_alive_during_sleep(void)
+{
+	/*
+	 * MPC8568E reference manual says:
+	 *
+	 * "...power down sequence waits for all I/O interfaces to become idle.
+	 *  In some applications this may happen eventually without actively
+	 *  shutting down interfaces, but most likely, software will have to
+	 *  take steps to shut down the eTSEC, QUICC Engine Block, and PCI
+	 *  interfaces before issuing the command (either the write to the core
+	 *  MSR[WE] as described above or writing to POWMGTCSR) to put the
+	 *  device into sleep state."
+	 *
+	 * MPC8569E reference manual has a similar paragraph.
+	 */
+#ifdef CONFIG_PPC_85xx
+	return 0;
+#else
+	return 1;
+#endif
+}
 
 /* we actually use cpm_muram implementation, define this for convenience */
 #define qe_muram_init cpm_muram_init
@@ -210,8 +240,15 @@ struct qe_firmware_info {
 	u64 extended_modes;	/* Extended modes */
 };
 
+#ifdef CONFIG_QUICC_ENGINE
 /* Upload a firmware to the QE */
 int qe_upload_firmware(const struct qe_firmware *firmware);
+#else
+static inline int qe_upload_firmware(const struct qe_firmware *firmware)
+{
+	return -ENOSYS;
+}
+#endif /* CONFIG_QUICC_ENGINE */
 
 /* Obtain information on the uploaded firmware */
 struct qe_firmware_info *qe_get_firmware_info(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg_fsl_emb.h	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,7 @@
 #define PMRN_PMLCB2	0x112	/* PM Local Control B2 */
 #define PMRN_PMLCB3	0x113	/* PM Local Control B3 */
 
-#define PMLCB_THRESHMUL_MASK	0x0700	/* Threshhold Multiple Field */
+#define PMLCB_THRESHMUL_MASK	0x0700	/* Threshold Multiple Field */
 #define PMLCB_THRESHMUL_SHIFT	8
 
 #define PMLCB_THRESHOLD_MASK	0x003f	/* Threshold Field */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/reg.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -489,6 +489,8 @@
 #define SPRN_MMCR1	798
 #define SPRN_MMCRA	0x312
 #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
+#define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
+#define   MMCRA_SDAR_ERAT_MISS   0x20000000UL
 #define   MMCRA_SIHV	0x10000000UL /* state of MSR HV when SIAR set */
 #define   MMCRA_SIPR	0x08000000UL /* state of MSR PR when SIAR set */
 #define   MMCRA_SLOT	0x07000000UL /* SLOT bits (37-39) */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/rtas.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/rtas.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/rtas.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/rtas.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@ struct rtas_t {
 	unsigned long entry;		/* physical address pointer */
 	unsigned long base;		/* physical address pointer */
 	unsigned long size;
-	raw_spinlock_t lock;
+	arch_spinlock_t lock;
 	struct rtas_args args;
 	struct device_node *dev;	/* virtual address pointer */
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/smp.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/smp.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/smp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,7 +37,7 @@ extern void cpu_die(void);
 extern void smp_send_debugger_break(int cpu);
 extern void smp_message_recv(int);
 
-DECLARE_PER_CPU(unsigned int, pvr);
+DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
 #ifdef CONFIG_HOTPLUG_CPU
 extern void fixup_irqs(cpumask_t map);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,4 +67,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@
 #include <asm/asm-compat.h>
 #include <asm/synch.h>
 
-#define __raw_spin_is_locked(x)		((x)->slock != 0)
+#define arch_spin_is_locked(x)		((x)->slock != 0)
 
 #ifdef CONFIG_PPC64
 /* use 0x800000yy when locked, where yy == CPU number */
@@ -54,7 +54,7 @@
  * This returns the old value in the lock, so we succeeded
  * in getting the lock if the return value is 0.
  */
-static inline unsigned long arch_spin_trylock(raw_spinlock_t *lock)
+static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned long tmp, token;
 
@@ -73,10 +73,10 @@ static inline unsigned long arch_spin_tr
 	return tmp;
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	CLEAR_IO_SYNC;
-	return arch_spin_trylock(lock) == 0;
+	return __arch_spin_trylock(lock) == 0;
 }
 
 /*
@@ -96,19 +96,19 @@ static inline int __raw_spin_trylock(raw
 #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
 /* We only yield to the hypervisor if we are in shared processor mode */
 #define SHARED_PROCESSOR (get_lppaca()->shared_proc)
-extern void __spin_yield(raw_spinlock_t *lock);
-extern void __rw_yield(raw_rwlock_t *lock);
+extern void __spin_yield(arch_spinlock_t *lock);
+extern void __rw_yield(arch_rwlock_t *lock);
 #else /* SPLPAR || ISERIES */
 #define __spin_yield(x)	barrier()
 #define __rw_yield(x)	barrier()
 #define SHARED_PROCESSOR	0
 #endif
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	CLEAR_IO_SYNC;
 	while (1) {
-		if (likely(arch_spin_trylock(lock) == 0))
+		if (likely(__arch_spin_trylock(lock) == 0))
 			break;
 		do {
 			HMT_low();
@@ -120,13 +120,13 @@ static inline void __raw_spin_lock(raw_s
 }
 
 static inline
-void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 {
 	unsigned long flags_dis;
 
 	CLEAR_IO_SYNC;
 	while (1) {
-		if (likely(arch_spin_trylock(lock) == 0))
+		if (likely(__arch_spin_trylock(lock) == 0))
 			break;
 		local_save_flags(flags_dis);
 		local_irq_restore(flags);
@@ -140,19 +140,19 @@ void __raw_spin_lock_flags(raw_spinlock_
 	}
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	SYNC_IO;
-	__asm__ __volatile__("# __raw_spin_unlock\n\t"
+	__asm__ __volatile__("# arch_spin_unlock\n\t"
 				LWSYNC_ON_SMP: : :"memory");
 	lock->slock = 0;
 }
 
 #ifdef CONFIG_PPC64
-extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
+extern void arch_spin_unlock_wait(arch_spinlock_t *lock);
 #else
-#define __raw_spin_unlock_wait(lock) \
-	do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define arch_spin_unlock_wait(lock) \
+	do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 #endif
 
 /*
@@ -166,8 +166,8 @@ extern void __raw_spin_unlock_wait(raw_s
  * read-locks.
  */
 
-#define __raw_read_can_lock(rw)		((rw)->lock >= 0)
-#define __raw_write_can_lock(rw)	(!(rw)->lock)
+#define arch_read_can_lock(rw)		((rw)->lock >= 0)
+#define arch_write_can_lock(rw)	(!(rw)->lock)
 
 #ifdef CONFIG_PPC64
 #define __DO_SIGN_EXTEND	"extsw	%0,%0\n"
@@ -181,7 +181,7 @@ extern void __raw_spin_unlock_wait(raw_s
  * This returns the old value in the lock + 1,
  * so we got a read lock if the return value is > 0.
  */
-static inline long arch_read_trylock(raw_rwlock_t *rw)
+static inline long __arch_read_trylock(arch_rwlock_t *rw)
 {
 	long tmp;
 
@@ -205,7 +205,7 @@ static inline long arch_read_trylock(raw
  * This returns the old value in the lock,
  * so we got the write lock if the return value is 0.
  */
-static inline long arch_write_trylock(raw_rwlock_t *rw)
+static inline long __arch_write_trylock(arch_rwlock_t *rw)
 {
 	long tmp, token;
 
@@ -225,10 +225,10 @@ static inline long arch_write_trylock(ra
 	return tmp;
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	while (1) {
-		if (likely(arch_read_trylock(rw) > 0))
+		if (likely(__arch_read_trylock(rw) > 0))
 			break;
 		do {
 			HMT_low();
@@ -239,10 +239,10 @@ static inline void __raw_read_lock(raw_r
 	}
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	while (1) {
-		if (likely(arch_write_trylock(rw) == 0))
+		if (likely(__arch_write_trylock(rw) == 0))
 			break;
 		do {
 			HMT_low();
@@ -253,17 +253,17 @@ static inline void __raw_write_lock(raw_
 	}
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
-	return arch_read_trylock(rw) > 0;
+	return __arch_read_trylock(rw) > 0;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
-	return arch_write_trylock(rw) == 0;
+	return __arch_write_trylock(rw) == 0;
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	long tmp;
 
@@ -280,19 +280,19 @@ static inline void __raw_read_unlock(raw
 	: "cr0", "xer", "memory");
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	__asm__ __volatile__("# write_unlock\n\t"
 				LWSYNC_ON_SMP: : :"memory");
 	rw->lock = 0;
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	__spin_yield(lock)
-#define _raw_read_relax(lock)	__rw_yield(lock)
-#define _raw_write_relax(lock)	__rw_yield(lock)
+#define arch_spin_relax(lock)	__spin_yield(lock)
+#define arch_read_relax(lock)	__rw_yield(lock)
+#define arch_write_relax(lock)	__rw_yield(lock)
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,14 +7,14 @@
 
 typedef struct {
 	volatile unsigned int slock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile signed int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/systbl.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/systbl.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/systbl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/systbl.h	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,7 @@ SYSCALL_SPU(setfsuid)
 SYSCALL_SPU(setfsgid)
 SYSCALL_SPU(llseek)
 COMPAT_SYS_SPU(getdents)
-SYSX_SPU(sys_select,ppc32_select,ppc_select)
+SYSX_SPU(sys_select,ppc32_select,sys_select)
 SYSCALL_SPU(flock)
 SYSCALL_SPU(msync)
 COMPAT_SYS_SPU(readv)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/thread_info.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/thread_info.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/thread_info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
@@ -111,7 +111,6 @@ static inline struct thread_info *curren
 #define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
 #define TIF_FREEZE		14	/* Freezing for suspend */
 #define TIF_RUNLATCH		15	/* Is the runlatch enabled? */
-#define TIF_ABI_PENDING		16	/* 32/64 bit switch needed */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -129,7 +128,6 @@ static inline struct thread_info *curren
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
 #define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
-#define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/topology.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/topology.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,9 @@ static inline int cpu_to_node(int cpu)
 
 #define parent_node(node)	(node)
 
-#define cpumask_of_node(node) (&numa_cpumask_lookup_table[node])
+#define cpumask_of_node(node) ((node) == -1 ?				\
+			       cpu_all_mask :				\
+			       &numa_cpumask_lookup_table[node])
 
 int of_node_to_nid(struct device_node *device);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/trace.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/trace.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/trace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/trace.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,133 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM powerpc
+
+#if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_POWERPC_H
+
+#include <linux/tracepoint.h>
+
+struct pt_regs;
+
+TRACE_EVENT(irq_entry,
+
+	TP_PROTO(struct pt_regs *regs),
+
+	TP_ARGS(regs),
+
+	TP_STRUCT__entry(
+		__field(struct pt_regs *, regs)
+	),
+
+	TP_fast_assign(
+		__entry->regs = regs;
+	),
+
+	TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(irq_exit,
+
+	TP_PROTO(struct pt_regs *regs),
+
+	TP_ARGS(regs),
+
+	TP_STRUCT__entry(
+		__field(struct pt_regs *, regs)
+	),
+
+	TP_fast_assign(
+		__entry->regs = regs;
+	),
+
+	TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(timer_interrupt_entry,
+
+	TP_PROTO(struct pt_regs *regs),
+
+	TP_ARGS(regs),
+
+	TP_STRUCT__entry(
+		__field(struct pt_regs *, regs)
+	),
+
+	TP_fast_assign(
+		__entry->regs = regs;
+	),
+
+	TP_printk("pt_regs=%p", __entry->regs)
+);
+
+TRACE_EVENT(timer_interrupt_exit,
+
+	TP_PROTO(struct pt_regs *regs),
+
+	TP_ARGS(regs),
+
+	TP_STRUCT__entry(
+		__field(struct pt_regs *, regs)
+	),
+
+	TP_fast_assign(
+		__entry->regs = regs;
+	),
+
+	TP_printk("pt_regs=%p", __entry->regs)
+);
+
+#ifdef CONFIG_PPC_PSERIES
+extern void hcall_tracepoint_regfunc(void);
+extern void hcall_tracepoint_unregfunc(void);
+
+TRACE_EVENT_FN(hcall_entry,
+
+	TP_PROTO(unsigned long opcode, unsigned long *args),
+
+	TP_ARGS(opcode, args),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, opcode)
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+	),
+
+	TP_printk("opcode=%lu", __entry->opcode),
+
+	hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
+);
+
+TRACE_EVENT_FN(hcall_exit,
+
+	TP_PROTO(unsigned long opcode, unsigned long retval,
+		unsigned long *retbuf),
+
+	TP_ARGS(opcode, retval, retbuf),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, opcode)
+		__field(unsigned long, retval)
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->retval = retval;
+	),
+
+	TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
+
+	hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
+);
+#endif
+
+#endif /* _TRACE_POWERPC_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/udbg.h linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/udbg.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/include/asm/udbg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/include/asm/udbg.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,7 @@ extern void __init udbg_init_btext(void)
 extern void __init udbg_init_44x_as1(void);
 extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
+extern void __init udbg_init_usbgecko(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,16 @@ config IRQ_PER_CPU
 	bool
 	default y
 
+config NR_IRQS
+	int "Number of virtual interrupt numbers"
+	range 32 512
+	default "512"
+	help
+	  This defines the number of virtual interrupt numbers the kernel
+	  can manage. Virtual interrupt numbers are what you see in
+	  /proc/interrupts. If you configure your system to have too few,
+	  drivers will fail to load or worse - handle with care.
+
 config STACKTRACE_SUPPORT
 	bool
 	default y
@@ -199,24 +209,14 @@ config DEFAULT_UIMAGE
 config REDBOOT
 	bool
 
-config HIBERNATE_32
-	bool
-	depends on (PPC_PMAC && !SMP) || BROKEN
-	default y
-
-config HIBERNATE_64
-	bool
-	depends on BROKEN || (PPC_PMAC64 && EXPERIMENTAL)
-	default y
-
 config ARCH_HIBERNATION_POSSIBLE
 	bool
-	depends on (PPC64 && HIBERNATE_64) || (PPC32 && HIBERNATE_32)
 	default y
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
+	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
+		   PPC_85xx || PPC_86xx
 
 config PPC_DCR_NATIVE
 	bool
@@ -320,6 +320,10 @@ config HOTPLUG_CPU
 
 	  Say N if you are unsure.
 
+config ARCH_CPU_PROBE_RELEASE
+	def_bool y
+	depends on HOTPLUG_CPU
+
 config ARCH_ENABLE_MEMORY_HOTPLUG
 	def_bool y
 
@@ -378,6 +382,19 @@ config IRQ_ALL_CPUS
 	  CPU.  Generally saying Y is safe, although some problems have been
 	  reported with SMP Power Macintoshes with this option enabled.
 
+config SPARSE_IRQ
+	bool "Support sparse irq numbering"
+	default y
+	help
+	  This enables support for sparse irqs. This is useful for distro
+	  kernels that want to define a high CONFIG_NR_CPUS value but still
+	  want to have low kernel memory footprint on smaller machines.
+
+	  ( Sparse IRQs can also be beneficial on NUMA boxes, as they spread
+	    out the irq_desc[] array in a more NUMA-friendly way. )
+
+	  If you don't know what to do here, say Y.
+
 config NUMA
 	bool "NUMA support"
 	depends on PPC64
@@ -652,6 +669,14 @@ config FSL_PCI
 	select PPC_INDIRECT_PCI
 	select PCI_QUIRKS
 
+config FSL_PMC
+	bool
+	default y
+	depends on SUSPEND && (PPC_85xx || PPC_86xx)
+	help
+	  Freescale MPC85xx/MPC86xx power management controller support
+	  (suspend/resume). For MPC83xx see platforms/83xx/suspend.c
+
 config 4xx_SOC
 	bool
 
@@ -679,7 +704,7 @@ config PPC_PCI_CHOICE
 config PCI
 	bool "PCI support" if PPC_PCI_CHOICE
 	default y if !40x && !CPM2 && !8xx && !PPC_83xx \
-		&& !PPC_85xx && !PPC_86xx
+		&& !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
 	default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
 	default PCI_QSPAN if !4xx && !CPM2 && 8xx
 	select ARCH_SUPPORTS_MSI
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/Kconfig.debug linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/powerpc/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,7 @@ config DEBUG_STACK_USAGE
 
 config HCALL_STATS
 	bool "Hypervisor call instrumentation"
-	depends on PPC_PSERIES && DEBUG_FS
+	depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
 	help
 	  Adds code to keep track of the number of hypervisor calls made and
 	  the amount of time spent in hypervisor calls.  Wall time spent in
@@ -254,6 +254,14 @@ config PPC_EARLY_DEBUG_CPM
 	  using a CPM-based serial port.  This assumes that the bootwrapper
 	  has run, and set up the CPM in a particular way.
 
+config PPC_EARLY_DEBUG_USBGECKO
+	bool "Early debugging through the USB Gecko adapter"
+	depends on GAMECUBE_COMMON
+	select USBGECKO_UDBG
+	help
+	  Select this to enable early debugging for Nintendo GameCube/Wii
+	  consoles via an external USB Gecko adapter.
+
 endchoice
 
 config PPC_EARLY_DEBUG_44x_PHYSLOW
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/align.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/align.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/align.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/align.c	2010-02-24 13:52:17.000000000 -0500
@@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *r
  */
 static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
 		       unsigned int areg, struct pt_regs *regs,
-		       unsigned int flags, unsigned int length)
+		       unsigned int flags, unsigned int length,
+		       unsigned int elsize)
 {
 	char *ptr;
+	unsigned long *lptr;
 	int ret = 0;
+	int sw = 0;
+	int i, j;
 
 	flush_vsx_to_thread(current);
 
@@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __u
 	else
 		ptr = (char *) &current->thread.vr[reg - 32];
 
-	if (flags & ST)
-		ret = __copy_to_user(addr, ptr, length);
-        else {
-		if (flags & SPLT){
-			ret = __copy_from_user(ptr, addr, length);
-			ptr += length;
+	lptr = (unsigned long *) ptr;
+
+	if (flags & SW)
+		sw = elsize-1;
+
+	for (j = 0; j < length; j += elsize) {
+		for (i = 0; i < elsize; ++i) {
+			if (flags & ST)
+				ret |= __put_user(ptr[i^sw], addr + i);
+			else
+				ret |= __get_user(ptr[i^sw], addr + i);
 		}
-		ret |= __copy_from_user(ptr, addr, length);
+		ptr  += elsize;
+		addr += elsize;
 	}
-	if (flags & U)
-		regs->gpr[areg] = regs->dar;
-	if (ret)
+
+	if (!ret) {
+		if (flags & U)
+			regs->gpr[areg] = regs->dar;
+
+		/* Splat load copies the same data to top and bottom 8 bytes */
+		if (flags & SPLT)
+			lptr[1] = lptr[0];
+		/* For 8 byte loads, zero the top 8 bytes */
+		else if (!(flags & ST) && (8 == length))
+			lptr[1] = 0;
+	} else
 		return -EFAULT;
+
 	return 1;
 }
 #endif
@@ -732,7 +752,7 @@ int fix_alignment(struct pt_regs *regs)
 
 #ifdef CONFIG_SPE
 	if ((instr >> 26) == 0x4) {
-		PPC_WARN_EMULATED(spe);
+		PPC_WARN_ALIGNMENT(spe, regs);
 		return emulate_spe(regs, reg, instr);
 	}
 #endif
@@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs)
 
 #ifdef CONFIG_VSX
 	if ((instruction & 0xfc00003e) == 0x7c000018) {
-		/* Additional register addressing bit (64 VSX vs 32 FPR/GPR */
+		unsigned int elsize;
+
+		/* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */
 		reg |= (instruction & 0x1) << 5;
 		/* Simple inline decoder instead of a table */
+		/* VSX has only 8 and 16 byte memory accesses */
+		nb = 8;
 		if (instruction & 0x200)
 			nb = 16;
-		else if (instruction & 0x080)
-			nb = 8;
-		else
-			nb = 4;
+
+		/* Vector stores in little-endian mode swap individual
+		   elements, so process them separately */
+		elsize = 4;
+		if (instruction & 0x80)
+			elsize = 8;
+
 		flags = 0;
+		if (regs->msr & MSR_LE)
+			flags |= SW;
 		if (instruction & 0x100)
 			flags |= ST;
 		if (instruction & 0x040)
@@ -786,15 +815,15 @@ int fix_alignment(struct pt_regs *regs)
 			flags |= SPLT;
 			nb = 8;
 		}
-		PPC_WARN_EMULATED(vsx);
-		return emulate_vsx(addr, reg, areg, regs, flags, nb);
+		PPC_WARN_ALIGNMENT(vsx, regs);
+		return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize);
 	}
 #endif
 	/* A size of 0 indicates an instruction we don't support, with
 	 * the exception of DCBZ which is handled as a special case here
 	 */
 	if (instr == DCBZ) {
-		PPC_WARN_EMULATED(dcbz);
+		PPC_WARN_ALIGNMENT(dcbz, regs);
 		return emulate_dcbz(regs, addr);
 	}
 	if (unlikely(nb == 0))
@@ -804,7 +833,7 @@ int fix_alignment(struct pt_regs *regs)
 	 * function
 	 */
 	if (flags & M) {
-		PPC_WARN_EMULATED(multiple);
+		PPC_WARN_ALIGNMENT(multiple, regs);
 		return emulate_multiple(regs, addr, reg, nb,
 					flags, instr, swiz);
 	}
@@ -825,11 +854,11 @@ int fix_alignment(struct pt_regs *regs)
 
 	/* Special case for 16-byte FP loads and stores */
 	if (nb == 16) {
-		PPC_WARN_EMULATED(fp_pair);
+		PPC_WARN_ALIGNMENT(fp_pair, regs);
 		return emulate_fp_pair(addr, reg, flags);
 	}
 
-	PPC_WARN_EMULATED(unaligned);
+	PPC_WARN_ALIGNMENT(unaligned, regs);
 
 	/* If we are loading, get the data from user space, else
 	 * get it from register values
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/asm-offsets.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/asm-offsets.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
@@ -190,6 +190,11 @@ int main(void)
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
 	DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
 	DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+	DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest));
+	DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb));
+	DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max));
+#endif
 #endif /* CONFIG_PPC64 */
 
 	/* RTAS */
@@ -398,14 +403,24 @@ int main(void)
 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
+
+	/* book3s_64 */
+#ifdef CONFIG_PPC64
+	DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr));
+	DEFINE(VCPU_HOST_RETIP, offsetof(struct kvm_vcpu, arch.host_retip));
+	DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
+	DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
+	DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
+	DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
+	DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
+	DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
+	DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
+#endif
 #endif
 #ifdef CONFIG_44x
 	DEFINE(PGD_T_LOG2, PGD_T_LOG2);
 	DEFINE(PTE_T_LOG2, PTE_T_LOG2);
 #endif
-#ifdef CONFIG_FSL_BOOKE
-	DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam));
-#endif
 
 #ifdef CONFIG_KVM_EXIT_TIMING
 	DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/cputable.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cputable.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/cputable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/cputable.c	2010-02-24 13:52:17.000000000 -0500
@@ -697,9 +697,9 @@ static struct cpu_spec __initdata cpu_sp
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
 	},
-	{	/* 750CL */
-		.pvr_mask		= 0xfffff0f0,
-		.pvr_value		= 0x00087010,
+	{	/* 750CL (and "Broadway") */
+		.pvr_mask		= 0xfffff0e0,
+		.pvr_value		= 0x00087000,
 		.cpu_name		= "750CL",
 		.cpu_features		= CPU_FTRS_750CL,
 		.cpu_user_features	= COMMON_USER | PPC_FEATURE_PPC_LE,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/crash.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/crash.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/crash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/crash.c	2010-02-24 13:52:17.000000000 -0500
@@ -373,7 +373,7 @@ void default_machine_crash_shutdown(stru
 	hard_irq_disable();
 
 	for_each_irq(i) {
-		struct irq_desc *desc = irq_desc + i;
+		struct irq_desc *desc = irq_to_desc(i);
 
 		if (desc->status & IRQ_INPROGRESS)
 			desc->chip->eoi(i);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/dma-swiotlb.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma-swiotlb.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/dma-swiotlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/dma-swiotlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@
 #include <asm/dma.h>
 #include <asm/abs_addr.h>
 
-int swiotlb __read_mostly;
 unsigned int ppc_swiotlb_enable;
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/entry_64.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/entry_64.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/entry_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/entry_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -551,7 +551,7 @@ restore:
 BEGIN_FW_FTR_SECTION
 	ld	r5,SOFTE(r1)
 FW_FTR_SECTION_ELSE
-	b	iseries_check_pending_irqs
+	b	.Liseries_check_pending_irqs
 ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 2:
 	TRACE_AND_RESTORE_IRQ(r5);
@@ -623,7 +623,7 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_
 
 #endif /* CONFIG_PPC_BOOK3E */
 
-iseries_check_pending_irqs:
+.Liseries_check_pending_irqs:
 #ifdef CONFIG_PPC_ISERIES
 	ld	r5,SOFTE(r1)
 	cmpdi	0,r5,0
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/exceptions-64s.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/exceptions-64s.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/exceptions-64s.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/exceptions-64s.S	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,7 @@ __start_interrupts:
 	. = 0x200
 _machine_check_pSeries:
 	HMT_MEDIUM
+	DO_KVM	0x200
 	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
@@ -48,6 +49,7 @@ _machine_check_pSeries:
 	.globl data_access_pSeries
 data_access_pSeries:
 	HMT_MEDIUM
+	DO_KVM	0x300
 	mtspr	SPRN_SPRG_SCRATCH0,r13
 BEGIN_FTR_SECTION
 	mfspr	r13,SPRN_SPRG_PACA
@@ -77,6 +79,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 	.globl data_access_slb_pSeries
 data_access_slb_pSeries:
 	HMT_MEDIUM
+	DO_KVM	0x380
 	mtspr	SPRN_SPRG_SCRATCH0,r13
 	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -115,6 +118,7 @@ data_access_slb_pSeries:
 	.globl instruction_access_slb_pSeries
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
+	DO_KVM	0x480
 	mtspr	SPRN_SPRG_SCRATCH0,r13
 	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -154,6 +158,7 @@ instruction_access_slb_pSeries:
 	.globl	system_call_pSeries
 system_call_pSeries:
 	HMT_MEDIUM
+	DO_KVM	0xc00
 BEGIN_FTR_SECTION
 	cmpdi	r0,0x1ebe
 	beq-	1f
@@ -185,13 +190,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
 	 * prolog code of the PerformanceMonitor one. A little
 	 * trickery is thus necessary
 	 */
+performance_monitor_pSeries_1:
 	. = 0xf00
+	DO_KVM	0xf00
 	b	performance_monitor_pSeries
 
+altivec_unavailable_pSeries_1:
 	. = 0xf20
+	DO_KVM	0xf20
 	b	altivec_unavailable_pSeries
 
+vsx_unavailable_pSeries_1:
 	. = 0xf40
+	DO_KVM	0xf40
 	b	vsx_unavailable_pSeries
 
 #ifdef CONFIG_CBE_RAS
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_32.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_32.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -164,6 +164,9 @@ __after_mmu_off:
 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
 	bl	setup_cpm_bat
 #endif
+#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
+	bl	setup_usbgecko_bat
+#endif
 
 /*
  * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -1203,6 +1206,28 @@ setup_cpm_bat:
 	blr
 #endif
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
+setup_usbgecko_bat:
+	/* prepare a BAT for early io */
+#if defined(CONFIG_GAMECUBE)
+	lis	r8, 0x0c00
+#elif defined(CONFIG_WII)
+	lis	r8, 0x0d00
+#else
+#error Invalid platform for USB Gecko based early debugging.
+#endif
+	/*
+	 * The virtual address used must match the virtual address
+	 * associated to the fixmap entry FIX_EARLY_DEBUG_BASE.
+	 */
+	lis	r11, 0xfffe	/* top 128K */
+	ori	r8, r8, 0x002a	/* uncached, guarded ,rw */
+	ori	r11, r11, 0x2	/* 128K, Vs=1, Vp=0 */
+	mtspr	SPRN_DBAT1L, r8
+	mtspr	SPRN_DBAT1U, r11
+	blr
+#endif
+
 #ifdef CONFIG_8260
 /* Jump into the system reset for the rom.
  * We first disable the MMU, and then jump to the ROM reset address.
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_64.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_64.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,7 @@
 #include <asm/firmware.h>
 #include <asm/page_64.h>
 #include <asm/irqflags.h>
+#include <asm/kvm_book3s_64_asm.h>
 
 /* The physical memory is layed out such that the secondary processor
  * spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -165,6 +166,12 @@ exception_marker:
 #include "exceptions-64s.S"
 #endif
 
+/* KVM trampoline code needs to be close to the interrupt handlers */
+
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include "../kvm/book3s_64_rmhandlers.S"
+#endif
+
 _GLOBAL(generic_secondary_thread_init)
 	mr	r24,r3
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_8xx.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_8xx.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_8xx.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_8xx.S	2010-02-24 13:52:17.000000000 -0500
@@ -206,6 +206,8 @@ MachineCheck:
 	EXCEPTION_PROLOG
 	mfspr r4,SPRN_DAR
 	stw r4,_DAR(r11)
+	li r5,0x00f0
+	mtspr SPRN_DAR,r5	/* Tag DAR, to be used in DTLB Error */
 	mfspr r5,SPRN_DSISR
 	stw r5,_DSISR(r11)
 	addi r3,r1,STACK_FRAME_OVERHEAD
@@ -222,6 +224,8 @@ DataAccess:
 	stw	r10,_DSISR(r11)
 	mr	r5,r10
 	mfspr	r4,SPRN_DAR
+	li	r10,0x00f0
+	mtspr	SPRN_DAR,r10	/* Tag DAR, to be used in DTLB Error */
 	EXC_XFER_EE_LITE(0x300, handle_page_fault)
 
 /* Instruction access exception.
@@ -244,6 +248,8 @@ Alignment:
 	EXCEPTION_PROLOG
 	mfspr	r4,SPRN_DAR
 	stw	r4,_DAR(r11)
+	li	r5,0x00f0
+	mtspr	SPRN_DAR,r5	/* Tag DAR, to be used in DTLB Error */
 	mfspr	r5,SPRN_DSISR
 	stw	r5,_DSISR(r11)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -333,26 +339,20 @@ InstructionTLBMiss:
 	mfspr	r11, SPRN_MD_TWC	/* ....and get the pte address */
 	lwz	r10, 0(r11)	/* Get the pte */
 
-#ifdef CONFIG_SWAP
-	/* do not set the _PAGE_ACCESSED bit of a non-present page */
-	andi.	r11, r10, _PAGE_PRESENT
-	beq	4f
-	ori	r10, r10, _PAGE_ACCESSED
-	mfspr	r11, SPRN_MD_TWC	/* get the pte address again */
-	stw	r10, 0(r11)
-4:
-#else
-	ori	r10, r10, _PAGE_ACCESSED
-	stw	r10, 0(r11)
-#endif
+	andi.	r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
+	cmpwi	cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
+	bne-	cr0, 2f
+
+	/* Clear PP lsb, 0x400 */
+	rlwinm 	r10, r10, 0, 22, 20
 
 	/* The Linux PTE won't go exactly into the MMU TLB.
-	 * Software indicator bits 21, 22 and 28 must be clear.
+	 * Software indicator bits 22 and 28 must be clear.
 	 * Software indicator bits 24, 25, 26, and 27 must be
 	 * set.  All other Linux PTE bits control the behavior
 	 * of the MMU.
 	 */
-2:	li	r11, 0x00f0
+	li	r11, 0x00f0
 	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
 	DO_8xx_CPU6(0x2d80, r3)
 	mtspr	SPRN_MI_RPN, r10	/* Update TLB entry */
@@ -365,6 +365,22 @@ InstructionTLBMiss:
 	lwz	r3, 8(r0)
 #endif
 	rfi
+2:
+	mfspr	r11, SPRN_SRR1
+	/* clear all error bits as TLB Miss
+	 * sets a few unconditionally
+	*/
+	rlwinm	r11, r11, 0, 0xffff
+	mtspr	SPRN_SRR1, r11
+
+	mfspr	r10, SPRN_M_TW	/* Restore registers */
+	lwz	r11, 0(r0)
+	mtcr	r11
+	lwz	r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+	lwz	r3, 8(r0)
+#endif
+	b	InstructionAccess
 
 	. = 0x1200
 DataStoreTLBMiss:
@@ -406,29 +422,45 @@ DataStoreTLBMiss:
 	 * above.
 	 */
 	rlwimi	r11, r10, 0, 27, 27
+	/* Insert the WriteThru flag into the TWC from the Linux PTE.
+	 * It is bit 25 in the Linux PTE and bit 30 in the TWC
+	 */
+	rlwimi	r11, r10, 32-5, 30, 30
 	DO_8xx_CPU6(0x3b80, r3)
 	mtspr	SPRN_MD_TWC, r11
 
-#ifdef CONFIG_SWAP
-	/* do not set the _PAGE_ACCESSED bit of a non-present page */
-	andi.	r11, r10, _PAGE_PRESENT
-	beq	4f
-	ori	r10, r10, _PAGE_ACCESSED
-4:
-	/* and update pte in table */
-#else
-	ori	r10, r10, _PAGE_ACCESSED
-#endif
-	mfspr	r11, SPRN_MD_TWC	/* get the pte address again */
-	stw	r10, 0(r11)
+	/* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
+	 * We also need to know if the insn is a load/store, so:
+	 * Clear _PAGE_PRESENT and load that which will
+	 * trap into DTLB Error with store bit set accordinly.
+	 */
+	/* PRESENT=0x1, ACCESSED=0x20
+	 * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
+	 * r10 = (r10 & ~PRESENT) | r11;
+	 */
+	rlwinm	r11, r10, 32-5, _PAGE_PRESENT
+	and	r11, r11, r10
+	rlwimi	r10, r11, 0, _PAGE_PRESENT
+
+	/* Honour kernel RO, User NA */
+	/* 0x200 == Extended encoding, bit 22 */
+	/* r11 =  (r10 & _PAGE_USER) >> 2 */
+	rlwinm	r11, r10, 32-2, 0x200
+	or	r10, r11, r10
+	/* r11 =  (r10 & _PAGE_RW) >> 1 */
+	rlwinm	r11, r10, 32-1, 0x200
+	or	r10, r11, r10
+	/* invert RW and 0x200 bits */
+	xori	r10, r10, _PAGE_RW | 0x200
 
 	/* The Linux PTE won't go exactly into the MMU TLB.
-	 * Software indicator bits 21, 22 and 28 must be clear.
+	 * Software indicator bits 22 and 28 must be clear.
 	 * Software indicator bits 24, 25, 26, and 27 must be
 	 * set.  All other Linux PTE bits control the behavior
 	 * of the MMU.
 	 */
 2:	li	r11, 0x00f0
+	mtspr	SPRN_DAR,r11	/* Tag DAR */
 	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
 	DO_8xx_CPU6(0x3d80, r3)
 	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */
@@ -469,97 +501,10 @@ DataTLBError:
 	stw	r10, 0(r0)
 	stw	r11, 4(r0)
 
-	/* First, make sure this was a store operation.
-	*/
-	mfspr	r10, SPRN_DSISR
-	andis.	r11, r10, 0x0200	/* If set, indicates store op */
-	beq	2f
-
-	/* The EA of a data TLB miss is automatically stored in the MD_EPN
-	 * register.  The EA of a data TLB error is automatically stored in
-	 * the DAR, but not the MD_EPN register.  We must copy the 20 most
-	 * significant bits of the EA from the DAR to MD_EPN before we
-	 * start walking the page tables.  We also need to copy the CASID
-	 * value from the M_CASID register.
-	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored
-	 * in DAR, but it seems that this doesn't happen in some cases, such
-	 * as when the error is due to a dcbi instruction to a page with a
-	 * TLB that doesn't have the changed bit set.  In such cases, there
-	 * does not appear to be any way  to recover the EA of the error
-	 * since it is neither in DAR nor MD_EPN.  As a workaround, the
-	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
-	 * are initialized in mapin_ram().  This will avoid the problem,
-	 * assuming we only use the dcbi instruction on kernel addresses.
-	 */
 	mfspr	r10, SPRN_DAR
-	rlwinm	r11, r10, 0, 0, 19
-	ori	r11, r11, MD_EVALID
-	mfspr	r10, SPRN_M_CASID
-	rlwimi	r11, r10, 0, 28, 31
-	DO_8xx_CPU6(0x3780, r3)
-	mtspr	SPRN_MD_EPN, r11
-
-	mfspr	r10, SPRN_M_TWB	/* Get level 1 table entry address */
-
-	/* If we are faulting a kernel address, we have to use the
-	 * kernel page tables.
-	 */
-	andi.	r11, r10, 0x0800
-	beq	3f
-	lis	r11, swapper_pg_dir@h
-	ori	r11, r11, swapper_pg_dir@l
-	rlwimi	r10, r11, 0, 2, 19
-3:
-	lwz	r11, 0(r10)	/* Get the level 1 entry */
-	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
-	beq	2f		/* If zero, bail */
-
-	/* We have a pte table, so fetch the pte from the table.
-	 */
-	ori	r11, r11, 1		/* Set valid bit in physical L2 page */
-	DO_8xx_CPU6(0x3b80, r3)
-	mtspr	SPRN_MD_TWC, r11		/* Load pte table base address */
-	mfspr	r11, SPRN_MD_TWC		/* ....and get the pte address */
-	lwz	r10, 0(r11)		/* Get the pte */
-
-	andi.	r11, r10, _PAGE_RW	/* Is it writeable? */
-	beq	2f			/* Bail out if not */
-
-	/* Update 'changed', among others.
-	*/
-#ifdef CONFIG_SWAP
-	ori	r10, r10, _PAGE_DIRTY|_PAGE_HWWRITE
-	/* do not set the _PAGE_ACCESSED bit of a non-present page */
-	andi.	r11, r10, _PAGE_PRESENT
-	beq	4f
-	ori	r10, r10, _PAGE_ACCESSED
-4:
-#else
-	ori	r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
-#endif
-	mfspr	r11, SPRN_MD_TWC		/* Get pte address again */
-	stw	r10, 0(r11)		/* and update pte in table */
-
-	/* The Linux PTE won't go exactly into the MMU TLB.
-	 * Software indicator bits 21, 22 and 28 must be clear.
-	 * Software indicator bits 24, 25, 26, and 27 must be
-	 * set.  All other Linux PTE bits control the behavior
-	 * of the MMU.
-	 */
-	li	r11, 0x00f0
-	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
-	DO_8xx_CPU6(0x3d80, r3)
-	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */
-
-	mfspr	r10, SPRN_M_TW	/* Restore registers */
-	lwz	r11, 0(r0)
-	mtcr	r11
-	lwz	r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
-	lwz	r3, 8(r0)
-#endif
-	rfi
-2:
+	cmpwi	cr0, r10, 0x00f0
+	beq-	FixupDAR	/* must be a buggy dcbX, icbi insn. */
+DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
 	mfspr	r10, SPRN_M_TW	/* Restore registers */
 	lwz	r11, 0(r0)
 	mtcr	r11
@@ -588,6 +533,140 @@ DataTLBError:
 
 	. = 0x2000
 
+/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
+ * by decoding the registers used by the dcbx instruction and adding them.
+ * DAR is set to the calculated address and r10 also holds the EA on exit.
+ */
+ /* define if you don't want to use self modifying code */
+#define NO_SELF_MODIFYING_CODE
+FixupDAR:/* Entry point for dcbx workaround. */
+	/* fetch instruction from memory. */
+	mfspr	r10, SPRN_SRR0
+	andis.	r11, r10, 0x8000	/* Address >= 0x80000000 */
+	DO_8xx_CPU6(0x3780, r3)
+	mtspr	SPRN_MD_EPN, r10
+	mfspr	r11, SPRN_M_TWB	/* Get level 1 table entry address */
+	beq-	3f		/* Branch if user space */
+	lis	r11, (swapper_pg_dir-PAGE_OFFSET)@h
+	ori	r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
+	rlwimi	r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */
+3:	lwz	r11, 0(r11)	/* Get the level 1 entry */
+	DO_8xx_CPU6(0x3b80, r3)
+	mtspr	SPRN_MD_TWC, r11	/* Load pte table base address */
+	mfspr	r11, SPRN_MD_TWC	/* ....and get the pte address */
+	lwz	r11, 0(r11)	/* Get the pte */
+	/* concat physical page address(r11) and page offset(r10) */
+	rlwimi	r11, r10, 0, 20, 31
+	lwz	r11,0(r11)
+/* Check if it really is a dcbx instruction. */
+/* dcbt and dcbtst does not generate DTLB Misses/Errors,
+ * no need to include them here */
+	srwi	r10, r11, 26	/* check if major OP code is 31 */
+	cmpwi	cr0, r10, 31
+	bne-	141f
+	rlwinm	r10, r11, 0, 21, 30
+	cmpwi	cr0, r10, 2028	/* Is dcbz? */
+	beq+	142f
+	cmpwi	cr0, r10, 940	/* Is dcbi? */
+	beq+	142f
+	cmpwi	cr0, r10, 108	/* Is dcbst? */
+	beq+	144f		/* Fix up store bit! */
+	cmpwi	cr0, r10, 172	/* Is dcbf? */
+	beq+	142f
+	cmpwi	cr0, r10, 1964	/* Is icbi? */
+	beq+	142f
+141:	mfspr	r10, SPRN_DAR	/* r10 must hold DAR at exit */
+	b	DARFixed	/* Nope, go back to normal TLB processing */
+
+144:	mfspr	r10, SPRN_DSISR
+	rlwinm	r10, r10,0,7,5	/* Clear store bit for buggy dcbst insn */
+	mtspr	SPRN_DSISR, r10
+142:	/* continue, it was a dcbx, dcbi instruction. */
+#ifdef CONFIG_8xx_CPU6
+	lwz	r3, 8(r0)	/* restore r3 from memory */
+#endif
+#ifndef NO_SELF_MODIFYING_CODE
+	andis.	r10,r11,0x1f	/* test if reg RA is r0 */
+	li	r10,modified_instr@l
+	dcbtst	r0,r10		/* touch for store */
+	rlwinm	r11,r11,0,0,20	/* Zero lower 10 bits */
+	oris	r11,r11,640	/* Transform instr. to a "add r10,RA,RB" */
+	ori	r11,r11,532
+	stw	r11,0(r10)	/* store add/and instruction */
+	dcbf	0,r10		/* flush new instr. to memory. */
+	icbi	0,r10		/* invalidate instr. cache line */
+	lwz	r11, 4(r0)	/* restore r11 from memory */
+	mfspr	r10, SPRN_M_TW	/* restore r10 from M_TW */
+	isync			/* Wait until new instr is loaded from memory */
+modified_instr:
+	.space	4		/* this is where the add instr. is stored */
+	bne+	143f
+	subf	r10,r0,r10	/* r10=r10-r0, only if reg RA is r0 */
+143:	mtdar	r10		/* store faulting EA in DAR */
+	b	DARFixed	/* Go back to normal TLB handling */
+#else
+	mfctr	r10
+	mtdar	r10			/* save ctr reg in DAR */
+	rlwinm	r10, r11, 24, 24, 28	/* offset into jump table for reg RB */
+	addi	r10, r10, 150f@l	/* add start of table */
+	mtctr	r10			/* load ctr with jump address */
+	xor	r10, r10, r10		/* sum starts at zero */
+	bctr				/* jump into table */
+150:
+	add	r10, r10, r0	;b	151f
+	add	r10, r10, r1	;b	151f
+	add	r10, r10, r2	;b	151f
+	add	r10, r10, r3	;b	151f
+	add	r10, r10, r4	;b	151f
+	add	r10, r10, r5	;b	151f
+	add	r10, r10, r6	;b	151f
+	add	r10, r10, r7	;b	151f
+	add	r10, r10, r8	;b	151f
+	add	r10, r10, r9	;b	151f
+	mtctr	r11	;b	154f	/* r10 needs special handling */
+	mtctr	r11	;b	153f	/* r11 needs special handling */
+	add	r10, r10, r12	;b	151f
+	add	r10, r10, r13	;b	151f
+	add	r10, r10, r14	;b	151f
+	add	r10, r10, r15	;b	151f
+	add	r10, r10, r16	;b	151f
+	add	r10, r10, r17	;b	151f
+	add	r10, r10, r18	;b	151f
+	add	r10, r10, r19	;b	151f
+	add	r10, r10, r20	;b	151f
+	add	r10, r10, r21	;b	151f
+	add	r10, r10, r22	;b	151f
+	add	r10, r10, r23	;b	151f
+	add	r10, r10, r24	;b	151f
+	add	r10, r10, r25	;b	151f
+	add	r10, r10, r26	;b	151f
+	add	r10, r10, r27	;b	151f
+	add	r10, r10, r28	;b	151f
+	add	r10, r10, r29	;b	151f
+	add	r10, r10, r30	;b	151f
+	add	r10, r10, r31
+151:
+	rlwinm. r11,r11,19,24,28	/* offset into jump table for reg RA */
+	beq	152f			/* if reg RA is zero, don't add it */
+	addi	r11, r11, 150b@l	/* add start of table */
+	mtctr	r11			/* load ctr with jump address */
+	rlwinm	r11,r11,0,16,10		/* make sure we don't execute this more than once */
+	bctr				/* jump into table */
+152:
+	mfdar	r11
+	mtctr	r11			/* restore ctr reg from DAR */
+	mtdar	r10			/* save fault EA to DAR */
+	b	DARFixed		/* Go back to normal TLB handling */
+
+	/* special handling for r10,r11 since these are modified already */
+153:	lwz	r11, 4(r0)	/* load r11 from memory */
+	b	155f
+154:	mfspr	r11, SPRN_M_TW	/* load r10 from M_TW */
+155:	add	r10, r10, r11	/* add it */
+	mfctr	r11		/* restore r11 */
+	b	151b
+#endif
+
 	.globl	giveup_fpu
 giveup_fpu:
 	blr
@@ -689,12 +768,12 @@ start_here:
  */
 initial_mmu:
 	tlbia			/* Invalidate all TLB entries */
-#ifdef CONFIG_PIN_TLB
+/* Always pin the first 8 MB ITLB to prevent ITLB
+   misses while mucking around with SRR0/SRR1 in asm
+*/
 	lis	r8, MI_RSV4I@h
 	ori	r8, r8, 0x1c00
-#else
-	li	r8, 0
-#endif
+
 	mtspr	SPRN_MI_CTR, r8	/* Set instruction MMU control */
 
 #ifdef CONFIG_PIN_TLB
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_fsl_booke.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_fsl_booke.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2010-02-24 13:52:17.000000000 -0500
@@ -944,28 +944,6 @@ _GLOBAL(__setup_e500mc_ivors)
 	blr
 
 /*
- * extern void loadcam_entry(unsigned int index)
- *
- * Load TLBCAM[index] entry in to the L2 CAM MMU
- */
-_GLOBAL(loadcam_entry)
-	lis	r4,TLBCAM@ha
-	addi	r4,r4,TLBCAM@l
-	mulli	r5,r3,TLBCAM_SIZE
-	add	r3,r5,r4
-	lwz	r4,0(r3)
-	mtspr	SPRN_MAS0,r4
-	lwz	r4,4(r3)
-	mtspr	SPRN_MAS1,r4
-	lwz	r4,8(r3)
-	mtspr	SPRN_MAS2,r4
-	lwz	r4,12(r3)
-	mtspr	SPRN_MAS3,r4
-	tlbwe
-	isync
-	blr
-
-/*
  * extern void giveup_altivec(struct task_struct *prev)
  *
  * The e500 core does not have an AltiVec unit.
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/idle.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/idle.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/idle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/idle.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,18 +110,16 @@ int powersave_nap;
  */
 static ctl_table powersave_nap_ctl_table[]={
 	{
-		.ctl_name	= KERN_PPC_POWERSAVE_NAP,
 		.procname	= "powersave-nap",
 		.data		= &powersave_nap,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{}
 };
 static ctl_table powersave_nap_sysctl_root[] = {
 	{
-		.ctl_name	= CTL_KERN,
 		.procname	= "kernel",
 		.mode		= 0555,
 		.child		= powersave_nap_ctl_table,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/io.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/io.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/io.c	2010-02-24 13:52:17.000000000 -0500
@@ -161,7 +161,7 @@ void _memcpy_fromio(void *dest, const vo
 		dest++;
 		n--;
 	}
-	while(n > 4) {
+	while(n >= 4) {
 		*((u32 *)dest) = *((volatile u32 *)vsrc);
 		eieio();
 		vsrc += 4;
@@ -190,7 +190,7 @@ void _memcpy_toio(volatile void __iomem
 		vdest++;
 		n--;
 	}
-	while(n > 4) {
+	while(n >= 4) {
 		*((volatile u32 *)vdest) = *((volatile u32 *)src);
 		src += 4;
 		vdest += 4;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/iommu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/iommu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/dma-mapping.h>
-#include <linux/bitops.h>
+#include <linux/bitmap.h>
 #include <linux/iommu-helper.h>
 #include <linux/crash_dump.h>
 #include <asm/io.h>
@@ -251,7 +251,7 @@ static void __iommu_free(struct iommu_ta
 	}
 
 	ppc_md.tce_free(tbl, entry, npages);
-	iommu_area_free(tbl->it_map, free_entry, npages);
+	bitmap_clear(tbl->it_map, free_entry, npages);
 }
 
 static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/irq.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,8 @@
 #include <asm/firmware.h>
 #include <asm/lv1call.h>
 #endif
+#define CREATE_TRACE_POINTS
+#include <asm/trace.h>
 
 int __irq_offset_value;
 static int ppc_spurious_interrupts;
@@ -85,7 +87,10 @@ extern int tau_interrupts(int);
 #endif /* CONFIG_PPC32 */
 
 #ifdef CONFIG_PPC64
+
+#ifndef CONFIG_SPARSE_IRQ
 EXPORT_SYMBOL(irq_desc);
+#endif
 
 int distribute_irqs = 1;
 
@@ -187,33 +192,7 @@ int show_interrupts(struct seq_file *p,
 		for_each_online_cpu(j)
 			seq_printf(p, "CPU%d       ", j);
 		seq_putc(p, '\n');
-	}
-
-	if (i < NR_IRQS) {
-		desc = get_irq_desc(i);
-		spin_lock_irqsave(&desc->lock, flags);
-		action = desc->action;
-		if (!action || !action->handler)
-			goto skip;
-		seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
-		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#else
-		seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
-		if (desc->chip)
-			seq_printf(p, " %s ", desc->chip->typename);
-		else
-			seq_puts(p, "  None      ");
-		seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
-		seq_printf(p, "    %s", action->name);
-		for (action = action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
-		seq_putc(p, '\n');
-skip:
-		spin_unlock_irqrestore(&desc->lock, flags);
-	} else if (i == NR_IRQS) {
+	} else if (i == nr_irqs) {
 #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
 		if (tau_initialized){
 			seq_puts(p, "TAU: ");
@@ -223,30 +202,68 @@ skip:
 		}
 #endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/
 		seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+
+		return 0;
 	}
+
+	desc = irq_to_desc(i);
+	if (!desc)
+		return 0;
+
+	raw_spin_lock_irqsave(&desc->lock, flags);
+
+	action = desc->action;
+	if (!action || !action->handler)
+		goto skip;
+
+	seq_printf(p, "%3d: ", i);
+#ifdef CONFIG_SMP
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+#else
+	seq_printf(p, "%10u ", kstat_irqs(i));
+#endif /* CONFIG_SMP */
+
+	if (desc->chip)
+		seq_printf(p, " %s ", desc->chip->name);
+	else
+		seq_puts(p, "  None      ");
+
+	seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
+	seq_printf(p, "    %s", action->name);
+
+	for (action = action->next; action; action = action->next)
+		seq_printf(p, ", %s", action->name);
+	seq_putc(p, '\n');
+
+skip:
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+
 	return 0;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 void fixup_irqs(cpumask_t map)
 {
+	struct irq_desc *desc;
 	unsigned int irq;
 	static int warned;
 
 	for_each_irq(irq) {
 		cpumask_t mask;
 
-		if (irq_desc[irq].status & IRQ_PER_CPU)
+		desc = irq_to_desc(irq);
+		if (desc && desc->status & IRQ_PER_CPU)
 			continue;
 
-		cpumask_and(&mask, irq_desc[irq].affinity, &map);
+		cpumask_and(&mask, desc->affinity, &map);
 		if (any_online_cpu(mask) == NR_CPUS) {
 			printk("Breaking affinity for irq %i\n", irq);
 			mask = map;
 		}
-		if (irq_desc[irq].chip->set_affinity)
-			irq_desc[irq].chip->set_affinity(irq, &mask);
-		else if (irq_desc[irq].action && !(warned++))
+		if (desc->chip->set_affinity)
+			desc->chip->set_affinity(irq, &mask);
+		else if (desc->action && !(warned++))
 			printk("Cannot set affinity for irq %i\n", irq);
 	}
 
@@ -273,7 +290,7 @@ static inline void handle_one_irq(unsign
 		return;
 	}
 
-	desc = irq_desc + irq;
+	desc = irq_to_desc(irq);
 	saved_sp_limit = current->thread.ksp_limit;
 
 	irqtp->task = curtp->task;
@@ -325,6 +342,8 @@ void do_IRQ(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 	unsigned int irq;
 
+	trace_irq_entry(regs);
+
 	irq_enter();
 
 	check_stack_overflow();
@@ -348,6 +367,8 @@ void do_IRQ(struct pt_regs *regs)
 		timer_interrupt(regs);
 	}
 #endif
+
+	trace_irq_exit(regs);
 }
 
 void __init init_IRQ(void)
@@ -535,7 +556,7 @@ struct irq_host *irq_alloc_host(struct d
 			smp_wmb();
 
 			/* Clear norequest flags */
-			get_irq_desc(i)->status &= ~IRQ_NOREQUEST;
+			irq_to_desc(i)->status &= ~IRQ_NOREQUEST;
 
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
@@ -601,8 +622,16 @@ void irq_set_virq_count(unsigned int cou
 static int irq_setup_virq(struct irq_host *host, unsigned int virq,
 			    irq_hw_number_t hwirq)
 {
+	struct irq_desc *desc;
+
+	desc = irq_to_desc_alloc_node(virq, 0);
+	if (!desc) {
+		pr_debug("irq: -> allocating desc failed\n");
+		goto error;
+	}
+
 	/* Clear IRQ_NOREQUEST flag */
-	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
+	desc->status &= ~IRQ_NOREQUEST;
 
 	/* map it */
 	smp_wmb();
@@ -611,11 +640,14 @@ static int irq_setup_virq(struct irq_hos
 
 	if (host->ops->map(host, virq, hwirq)) {
 		pr_debug("irq: -> mapping failed, freeing\n");
-		irq_free_virt(virq, 1);
-		return -1;
+		goto error;
 	}
 
 	return 0;
+
+error:
+	irq_free_virt(virq, 1);
+	return -1;
 }
 
 unsigned int irq_create_direct_mapping(struct irq_host *host)
@@ -699,7 +731,7 @@ unsigned int irq_create_mapping(struct i
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 
 unsigned int irq_create_of_mapping(struct device_node *controller,
-				   u32 *intspec, unsigned int intsize)
+				   const u32 *intspec, unsigned int intsize)
 {
 	struct irq_host *host;
 	irq_hw_number_t hwirq;
@@ -732,7 +764,7 @@ unsigned int irq_create_of_mapping(struc
 
 	/* Set type if specified and different than the current one */
 	if (type != IRQ_TYPE_NONE &&
-	    type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK))
+	    type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
 		set_irq_type(virq, type);
 	return virq;
 }
@@ -804,7 +836,7 @@ void irq_dispose_mapping(unsigned int vi
 	irq_map[virq].hwirq = host->inval_irq;
 
 	/* Set some flags */
-	get_irq_desc(virq)->status |= IRQ_NOREQUEST;
+	irq_to_desc(virq)->status |= IRQ_NOREQUEST;
 
 	/* Free it */
 	irq_free_virt(virq, 1);
@@ -996,12 +1028,24 @@ void irq_free_virt(unsigned int virq, un
 	spin_unlock_irqrestore(&irq_big_lock, flags);
 }
 
-void irq_early_init(void)
+int arch_early_irq_init(void)
 {
-	unsigned int i;
+	struct irq_desc *desc;
+	int i;
 
-	for (i = 0; i < NR_IRQS; i++)
-		get_irq_desc(i)->status |= IRQ_NOREQUEST;
+	for (i = 0; i < NR_IRQS; i++) {
+		desc = irq_to_desc(i);
+		if (desc)
+			desc->status |= IRQ_NOREQUEST;
+	}
+
+	return 0;
+}
+
+int arch_init_chip_data(struct irq_desc *desc, int node)
+{
+	desc->status |= IRQ_NOREQUEST;
+	return 0;
 }
 
 /* We need to create the radix trees late */
@@ -1063,16 +1107,19 @@ static int virq_debug_show(struct seq_fi
 	seq_printf(m, "%-5s  %-7s  %-15s  %s\n", "virq", "hwirq",
 		      "chip name", "host name");
 
-	for (i = 1; i < NR_IRQS; i++) {
-		desc = get_irq_desc(i);
-		spin_lock_irqsave(&desc->lock, flags);
+	for (i = 1; i < nr_irqs; i++) {
+		desc = irq_to_desc(i);
+		if (!desc)
+			continue;
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
 
 		if (desc->action && desc->action->handler) {
 			seq_printf(m, "%5d  ", i);
 			seq_printf(m, "0x%05lx  ", virq_to_hw(i));
 
-			if (desc->chip && desc->chip->typename)
-				p = desc->chip->typename;
+			if (desc->chip && desc->chip->name)
+				p = desc->chip->name;
 			else
 				p = none;
 			seq_printf(m, "%-15s  ", p);
@@ -1084,7 +1131,7 @@ static int virq_debug_show(struct seq_fi
 			seq_printf(m, "%s\n", p);
 		}
 
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/kgdb.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kgdb.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/kgdb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,7 @@ static struct hard_trap_info
 	{ 0x2030, 0x08 /* SIGFPE */  },		/* spe fp data */
 	{ 0x2040, 0x08 /* SIGFPE */  },		/* spe fp data */
 	{ 0x2050, 0x08 /* SIGFPE */  },		/* spe fp round */
-	{ 0x2060, 0x0e /* SIGILL */  },		/* performace monitor */
+	{ 0x2060, 0x0e /* SIGILL */  },		/* performance monitor */
 	{ 0x2900, 0x08 /* SIGFPE */  },		/* apu unavailable */
 	{ 0x3100, 0x0e /* SIGALRM */ },		/* fixed interval timer */
 	{ 0x3200, 0x02 /* SIGINT */  }, 	/* watchdog */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/lparcfg.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/lparcfg.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/lparcfg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/lparcfg.c	2010-02-24 13:52:17.000000000 -0500
@@ -781,9 +781,9 @@ static int __init lparcfg_init(void)
 			!firmware_has_feature(FW_FEATURE_ISERIES))
 		mode |= S_IWUSR;
 
-	ent = proc_create("ppc64/lparcfg", mode, NULL, &lparcfg_fops);
+	ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops);
 	if (!ent) {
-		printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
+		printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
 		return -EIO;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -42,10 +42,11 @@ obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
 obj-$(CONFIG_PPC_OF)		+= of_device.o of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)		+= clock.o
-procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
+procfs-y			:= proc_powerpc.o
 obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
 rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI)	:= rtas_pci.o
 obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas-rtc.o $(rtaspci-y-y)
+obj-$(CONFIG_PPC_RTAS_DAEMON)	+= rtasd.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_LPARCFG)		+= lparcfg.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/misc_32.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/misc_32.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/misc_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/misc_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -502,15 +502,7 @@ _GLOBAL(clear_pages)
 	li	r0,PAGE_SIZE/L1_CACHE_BYTES
 	slw	r0,r0,r4
 	mtctr	r0
-#ifdef CONFIG_8xx
-	li	r4, 0
-1:	stw	r4, 0(r3)
-	stw	r4, 4(r3)
-	stw	r4, 8(r3)
-	stw	r4, 12(r3)
-#else
 1:	dcbz	0,r3
-#endif
 	addi	r3,r3,L1_CACHE_BYTES
 	bdnz	1b
 	blr
@@ -535,15 +527,6 @@ _GLOBAL(copy_page)
 	addi	r3,r3,-4
 	addi	r4,r4,-4
 
-#ifdef CONFIG_8xx
-	/* don't use prefetch on 8xx */
-    	li	r0,4096/L1_CACHE_BYTES
-	mtctr	r0
-1:	COPY_16_BYTES
-	bdnz	1b
-	blr
-
-#else	/* not 8xx, we can prefetch */
 	li	r5,4
 
 #if MAX_COPY_PREFETCH > 1
@@ -584,7 +567,6 @@ _GLOBAL(copy_page)
 	li	r0,MAX_COPY_PREFETCH
 	li	r11,4
 	b	2b
-#endif	/* CONFIG_8xx */
 
 /*
  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/nvram_64.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/nvram_64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/nvram_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/nvram_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,8 +139,8 @@ out:
 
 }
 
-static int dev_nvram_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg)
+static long dev_nvram_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg)
 {
 	switch(cmd) {
 #ifdef CONFIG_PPC_PMAC
@@ -169,11 +169,11 @@ static int dev_nvram_ioctl(struct inode
 }
 
 const struct file_operations nvram_fops = {
-	.owner =	THIS_MODULE,
-	.llseek =	dev_nvram_llseek,
-	.read =		dev_nvram_read,
-	.write =	dev_nvram_write,
-	.ioctl =	dev_nvram_ioctl,
+	.owner		= THIS_MODULE,
+	.llseek		= dev_nvram_llseek,
+	.read		= dev_nvram_read,
+	.write		= dev_nvram_write,
+	.unlocked_ioctl	= dev_nvram_ioctl,
 };
 
 static struct miscdevice nvram_dev = {
@@ -184,7 +184,7 @@ static struct miscdevice nvram_dev = {
 
 
 #ifdef DEBUG_NVRAM
-static void nvram_print_partitions(char * label)
+static void __init nvram_print_partitions(char * label)
 {
 	struct list_head * p;
 	struct nvram_partition * tmp_part;
@@ -202,7 +202,7 @@ static void nvram_print_partitions(char
 #endif
 
 
-static int nvram_write_header(struct nvram_partition * part)
+static int __init nvram_write_header(struct nvram_partition * part)
 {
 	loff_t tmp_index;
 	int rc;
@@ -214,7 +214,7 @@ static int nvram_write_header(struct nvr
 }
 
 
-static unsigned char nvram_checksum(struct nvram_header *p)
+static unsigned char __init nvram_checksum(struct nvram_header *p)
 {
 	unsigned int c_sum, c_sum2;
 	unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */
@@ -228,32 +228,7 @@ static unsigned char nvram_checksum(stru
 	return c_sum;
 }
 
-
-/*
- * Find an nvram partition, sig can be 0 for any
- * partition or name can be NULL for any name, else
- * tries to match both
- */
-struct nvram_partition *nvram_find_partition(int sig, const char *name)
-{
-	struct nvram_partition * part;
-	struct list_head * p;
-
-	list_for_each(p, &nvram_part->partition) {
-		part = list_entry(p, struct nvram_partition, partition);
-
-		if (sig && part->header.signature != sig)
-			continue;
-		if (name && 0 != strncmp(name, part->header.name, 12))
-			continue;
-		return part; 
-	}
-	return NULL;
-}
-EXPORT_SYMBOL(nvram_find_partition);
-
-
-static int nvram_remove_os_partition(void)
+static int __init nvram_remove_os_partition(void)
 {
 	struct list_head *i;
 	struct list_head *j;
@@ -319,7 +294,7 @@ static int nvram_remove_os_partition(voi
  * Will create a partition starting at the first free
  * space found if space has enough room.
  */
-static int nvram_create_os_partition(void)
+static int __init nvram_create_os_partition(void)
 {
 	struct nvram_partition *part;
 	struct nvram_partition *new_part;
@@ -422,7 +397,7 @@ static int nvram_create_os_partition(voi
  * 5.) If the max chunk cannot be allocated then try finding a chunk
  * that will satisfy the minum needed (NVRAM_MIN_REQ).
  */
-static int nvram_setup_partition(void)
+static int __init nvram_setup_partition(void)
 {
 	struct list_head * p;
 	struct nvram_partition * part;
@@ -480,7 +455,7 @@ static int nvram_setup_partition(void)
 }
 
 
-static int nvram_scan_partitions(void)
+static int __init nvram_scan_partitions(void)
 {
 	loff_t cur_index = 0;
 	struct nvram_header phead;
@@ -706,6 +681,9 @@ int nvram_clear_error_log(void)
 	int clear_word = ERR_FLAG_ALREADY_LOGGED;
 	int rc;
 
+	if (nvram_error_log_index == -1)
+		return -1;
+
 	tmp_index = nvram_error_log_index;
 	
 	rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/pci-common.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci-common.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/pci-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		struct dev_archdata *sd = &dev->dev.archdata;
 
+		/* Cardbus can call us to add new devices to a bus, so ignore
+		 * those who are already fully discovered
+		 */
+		if (dev->is_added)
+			continue;
+
 		/* Setup OF node pointer in archdata */
 		sd->of_node = pci_device_to_OF_node(dev);
 
@@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct
 }
 EXPORT_SYMBOL(pcibios_fixup_bus);
 
+void __devinit pci_fixup_cardbus(struct pci_bus *bus)
+{
+	/* Now fixup devices on that bus */
+	pcibios_setup_bus_devices(bus);
+}
+
+
 static int skip_isa_ioresource_align(struct pci_dev *dev)
 {
 	if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/pci_of_scan.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_of_scan.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/pci_of_scan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/pci_of_scan.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,6 +123,7 @@ struct pci_dev *of_create_pci_dev(struct
 {
 	struct pci_dev *dev;
 	const char *type;
+	struct pci_slot *slot;
 
 	dev = alloc_pci_dev();
 	if (!dev)
@@ -140,6 +141,11 @@ struct pci_dev *of_create_pci_dev(struct
 	dev->devfn = devfn;
 	dev->multifunction = 0;		/* maybe a lie? */
 	dev->needs_freset = 0;		/* pcie fundamental reset required */
+	set_pcie_port_type(dev);
+
+	list_for_each_entry(slot, &dev->bus->slots, list)
+		if (PCI_SLOT(dev->devfn) == slot->number)
+			dev->slot = slot;
 
 	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
 	dev->device = get_int_prop(node, "device-id", 0xffff);
@@ -160,10 +166,14 @@ struct pci_dev *of_create_pci_dev(struct
 	dev->error_state = pci_channel_io_normal;
 	dev->dma_mask = 0xffffffff;
 
+	/* Early fixups, before probing the BARs */
+	pci_fixup_device(pci_fixup_early, dev);
+
 	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
 		/* a PCI-PCI bridge */
 		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
 		dev->rom_base_reg = PCI_ROM_ADDRESS1;
+		set_pcie_hotplug_bridge(dev);
 	} else if (!strcmp(type, "cardbus")) {
 		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
 	} else {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/perf_callchain.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_callchain.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/perf_callchain.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_callchain.c	2010-02-24 13:52:17.000000000 -0500
@@ -119,13 +119,6 @@ static void perf_callchain_kernel(struct
 }
 
 #ifdef CONFIG_PPC64
-
-#ifdef CONFIG_HUGETLB_PAGE
-#define is_huge_psize(pagesize)	(HPAGE_SHIFT && mmu_huge_psizes[pagesize])
-#else
-#define is_huge_psize(pagesize)	0
-#endif
-
 /*
  * On 64-bit we don't want to invoke hash_page on user addresses from
  * interrupt context, so if the access faults, we read the page tables
@@ -135,7 +128,7 @@ static int read_user_stack_slow(void __u
 {
 	pgd_t *pgdir;
 	pte_t *ptep, pte;
-	int pagesize;
+	unsigned shift;
 	unsigned long addr = (unsigned long) ptr;
 	unsigned long offset;
 	unsigned long pfn;
@@ -145,17 +138,14 @@ static int read_user_stack_slow(void __u
 	if (!pgdir)
 		return -EFAULT;
 
-	pagesize = get_slice_psize(current->mm, addr);
+	ptep = find_linux_pte_or_hugepte(pgdir, addr, &shift);
+	if (!shift)
+		shift = PAGE_SHIFT;
 
 	/* align address to page boundary */
-	offset = addr & ((1ul << mmu_psize_defs[pagesize].shift) - 1);
+	offset = addr & ((1UL << shift) - 1);
 	addr -= offset;
 
-	if (is_huge_psize(pagesize))
-		ptep = huge_pte_offset(current->mm, addr);
-	else
-		ptep = find_linux_pte(pgdir, addr);
-
 	if (ptep == NULL)
 		return -EFAULT;
 	pte = *ptep;
@@ -497,11 +487,11 @@ static void perf_callchain_user_32(struc
  * Since we can't get PMU interrupts inside a PMU interrupt handler,
  * we don't need separate irq and nmi entries here.
  */
-static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
+static DEFINE_PER_CPU(struct perf_callchain_entry, cpu_perf_callchain);
 
 struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
 {
-	struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
+	struct perf_callchain_entry *entry = &__get_cpu_var(cpu_perf_callchain);
 
 	entry->nr = 0;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/perf_event.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/perf_event.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -1165,7 +1165,7 @@ static void record_and_restart(struct pe
 	 */
 	if (record) {
 		struct perf_sample_data data = {
-			.addr	= 0,
+			.addr	= ~0ULL,
 			.period	= event->hw.last_period,
 		};
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power5-pmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power5-pmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power5-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power5-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,10 +73,6 @@
 #define MMCR1_PMCSEL_MSK	0x7f
 
 /*
- * Bits in MMCRA
- */
-
-/*
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
@@ -390,7 +386,7 @@ static int power5_compute_mmcr(u64 event
 			       unsigned int hwc[], unsigned long mmcr[])
 {
 	unsigned long mmcr1 = 0;
-	unsigned long mmcra = 0;
+	unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
 	unsigned int pmc, unit, byte, psel;
 	unsigned int ttm, grp;
 	int i, isbus, bit, grsel;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power5+-pmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power5+-pmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power5+-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power5+-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,10 +73,6 @@
 #define MMCR1_PMCSEL_MSK	0x7f
 
 /*
- * Bits in MMCRA
- */
-
-/*
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power6-pmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power6-pmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power6-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power6-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -178,7 +178,7 @@ static int p6_compute_mmcr(u64 event[],
 			   unsigned int hwc[], unsigned long mmcr[])
 {
 	unsigned long mmcr1 = 0;
-	unsigned long mmcra = 0;
+	unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
 	int i;
 	unsigned int pmc, ev, b, u, s, psel;
 	unsigned int ttmset = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power7-pmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power7-pmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/power7-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/power7-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,10 +51,6 @@
 #define MMCR1_PMCSEL_MSK	0xff
 
 /*
- * Bits in MMCRA
- */
-
-/*
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
@@ -230,7 +226,7 @@ static int power7_compute_mmcr(u64 event
 			       unsigned int hwc[], unsigned long mmcr[])
 {
 	unsigned long mmcr1 = 0;
-	unsigned long mmcra = 0;
+	unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
 	unsigned int pmc, unit, combine, l2sel, psel;
 	unsigned int pmc_inuse = 0;
 	int i;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/ppc970-pmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc970-pmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/ppc970-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc970-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,10 +84,6 @@ static short mmcr1_adder_bits[8] = {
 };
 
 /*
- * Bits in MMCRA
- */
-
-/*
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/ppc_ksyms.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc_ksyms.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/ppc_ksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/ppc_ksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,8 +96,6 @@ EXPORT_SYMBOL(copy_4K_page);
 EXPORT_SYMBOL(isa_io_base);
 EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_dram_offset);
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL(start_thread);
@@ -162,7 +160,6 @@ EXPORT_SYMBOL(screen_info);
 
 #ifdef CONFIG_PPC32
 EXPORT_SYMBOL(timer_interrupt);
-EXPORT_SYMBOL(irq_desc);
 EXPORT_SYMBOL(tb_ticks_per_jiffy);
 EXPORT_SYMBOL(cacheable_memcpy);
 EXPORT_SYMBOL(cacheable_memzero);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/process.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -554,18 +554,6 @@ void exit_thread(void)
 
 void flush_thread(void)
 {
-#ifdef CONFIG_PPC64
-	struct thread_info *t = current_thread_info();
-
-	if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
-		clear_ti_thread_flag(t, TIF_ABI_PENDING);
-		if (test_ti_thread_flag(t, TIF_32BIT))
-			clear_ti_thread_flag(t, TIF_32BIT);
-		else
-			set_ti_thread_flag(t, TIF_32BIT);
-	}
-#endif
-
 	discard_lazy_cpu_state();
 
 	if (current->thread.dabr) {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/proc_powerpc.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_powerpc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/proc_powerpc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_powerpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen 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
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+
+#include <asm/machdep.h>
+#include <asm/vdso_datapage.h>
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+
+#ifdef CONFIG_PPC64
+
+static loff_t page_map_seek( struct file *file, loff_t off, int whence)
+{
+	loff_t new;
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+
+	switch(whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	case 2:
+		new = dp->size + off;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if ( new < 0 || new > dp->size )
+		return -EINVAL;
+	return (file->f_pos = new);
+}
+
+static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
+			      loff_t *ppos)
+{
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+	return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
+}
+
+static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
+{
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+
+	if ((vma->vm_end - vma->vm_start) > dp->size)
+		return -EINVAL;
+
+	remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
+						dp->size, vma->vm_page_prot);
+	return 0;
+}
+
+static const struct file_operations page_map_fops = {
+	.llseek	= page_map_seek,
+	.read	= page_map_read,
+	.mmap	= page_map_mmap
+};
+
+
+static int __init proc_ppc64_init(void)
+{
+	struct proc_dir_entry *pde;
+
+	pde = proc_create_data("powerpc/systemcfg", S_IFREG|S_IRUGO, NULL,
+			       &page_map_fops, vdso_data);
+	if (!pde)
+		return 1;
+	pde->size = PAGE_SIZE;
+
+	return 0;
+}
+__initcall(proc_ppc64_init);
+
+#endif /* CONFIG_PPC64 */
+
+/*
+ * Create the ppc64 and ppc64/rtas directories early. This allows us to
+ * assume that they have been previously created in drivers.
+ */
+static int __init proc_ppc64_create(void)
+{
+	struct proc_dir_entry *root;
+
+	root = proc_mkdir("powerpc", NULL);
+	if (!root)
+		return 1;
+
+#ifdef CONFIG_PPC64
+	if (!proc_symlink("ppc64", NULL, "powerpc"))
+		pr_err("Failed to create link /proc/ppc64 -> /proc/powerpc\n");
+#endif
+
+	if (!of_find_node_by_path("/rtas"))
+		return 0;
+
+	if (!proc_mkdir("rtas", root))
+		return 1;
+
+	if (!proc_symlink("rtas", NULL, "powerpc/rtas"))
+		return 1;
+
+	return 0;
+}
+core_initcall(proc_ppc64_create);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/proc_ppc64.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_ppc64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/proc_ppc64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/proc_ppc64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen 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
- */
-
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include <asm/machdep.h>
-#include <asm/vdso_datapage.h>
-#include <asm/rtas.h>
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-
-static loff_t  page_map_seek( struct file *file, loff_t off, int whence);
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-			      loff_t *ppos);
-static int     page_map_mmap( struct file *file, struct vm_area_struct *vma );
-
-static const struct file_operations page_map_fops = {
-	.llseek	= page_map_seek,
-	.read	= page_map_read,
-	.mmap	= page_map_mmap
-};
-
-/*
- * Create the ppc64 and ppc64/rtas directories early. This allows us to
- * assume that they have been previously created in drivers.
- */
-static int __init proc_ppc64_create(void)
-{
-	struct proc_dir_entry *root;
-
-	root = proc_mkdir("ppc64", NULL);
-	if (!root)
-		return 1;
-
-	if (!of_find_node_by_path("/rtas"))
-		return 0;
-
-	if (!proc_mkdir("rtas", root))
-		return 1;
-
-	if (!proc_symlink("rtas", NULL, "ppc64/rtas"))
-		return 1;
-
-	return 0;
-}
-core_initcall(proc_ppc64_create);
-
-static int __init proc_ppc64_init(void)
-{
-	struct proc_dir_entry *pde;
-
-	pde = proc_create_data("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL,
-			       &page_map_fops, vdso_data);
-	if (!pde)
-		return 1;
-	pde->size = PAGE_SIZE;
-
-	return 0;
-}
-__initcall(proc_ppc64_init);
-
-static loff_t page_map_seek( struct file *file, loff_t off, int whence)
-{
-	loff_t new;
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-
-	switch(whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	case 2:
-		new = dp->size + off;
-		break;
-	default:
-		return -EINVAL;
-	}
-	if ( new < 0 || new > dp->size )
-		return -EINVAL;
-	return (file->f_pos = new);
-}
-
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-			      loff_t *ppos)
-{
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-	return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
-}
-
-static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
-{
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-
-	if ((vma->vm_end - vma->vm_start) > dp->size)
-		return -EINVAL;
-
-	remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
-						dp->size, vma->vm_page_prot);
-	return 0;
-}
-
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/prom.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/prom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/prom.c	2010-02-24 13:52:17.000000000 -0500
@@ -1317,29 +1317,6 @@ struct device_node *of_find_next_cache_n
 }
 
 /**
- *	of_find_all_nodes - Get next node in global list
- *	@prev:	Previous node or NULL to start iteration
- *		of_node_put() will be called on it
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_all_nodes(struct device_node *prev)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = prev ? prev->allnext : allnodes;
-	for (; np != 0; np = np->allnext)
-		if (of_node_get(np))
-			break;
-	of_node_put(prev);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_all_nodes);
-
-/**
  *	of_node_get - Increment refcount of a node
  *	@node:	Node to inc refcount, NULL is supported to
  *		simplify writing of callers
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,7 @@
 #include <asm/mmu.h>
 
 struct rtas_t rtas = {
-	.lock = __RAW_SPIN_LOCK_UNLOCKED
+	.lock = __ARCH_SPIN_LOCK_UNLOCKED
 };
 EXPORT_SYMBOL(rtas);
 
@@ -80,13 +80,13 @@ static unsigned long lock_rtas(void)
 
 	local_irq_save(flags);
 	preempt_disable();
-	__raw_spin_lock_flags(&rtas.lock, flags);
+	arch_spin_lock_flags(&rtas.lock, flags);
 	return flags;
 }
 
 static void unlock_rtas(unsigned long flags)
 {
-	__raw_spin_unlock(&rtas.lock);
+	arch_spin_unlock(&rtas.lock);
 	local_irq_restore(flags);
 	preempt_enable();
 }
@@ -978,7 +978,7 @@ int __init early_init_dt_scan_rtas(unsig
 	return 1;
 }
 
-static raw_spinlock_t timebase_lock;
+static arch_spinlock_t timebase_lock;
 static u64 timebase = 0;
 
 void __cpuinit rtas_give_timebase(void)
@@ -987,10 +987,10 @@ void __cpuinit rtas_give_timebase(void)
 
 	local_irq_save(flags);
 	hard_irq_disable();
-	__raw_spin_lock(&timebase_lock);
+	arch_spin_lock(&timebase_lock);
 	rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
 	timebase = get_tb();
-	__raw_spin_unlock(&timebase_lock);
+	arch_spin_unlock(&timebase_lock);
 
 	while (timebase)
 		barrier();
@@ -1002,8 +1002,8 @@ void __cpuinit rtas_take_timebase(void)
 {
 	while (!timebase)
 		barrier();
-	__raw_spin_lock(&timebase_lock);
+	arch_spin_lock(&timebase_lock);
 	set_tb(timebase >> 32, timebase & 0xffffffff);
 	timebase = 0;
-	__raw_spin_unlock(&timebase_lock);
+	arch_spin_unlock(&timebase_lock);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtasd.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtasd.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtasd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtasd.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * 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.
+ *
+ * Communication to userspace based on kernel/printk.c
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+#include <linux/cpu.h>
+#include <linux/workqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+#include <asm/nvram.h>
+#include <asm/atomic.h>
+#include <asm/machdep.h>
+
+
+static DEFINE_SPINLOCK(rtasd_log_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
+
+static char *rtas_log_buf;
+static unsigned long rtas_log_start;
+static unsigned long rtas_log_size;
+
+static int surveillance_timeout = -1;
+
+static unsigned int rtas_error_log_max;
+static unsigned int rtas_error_log_buffer_max;
+
+/* RTAS service tokens */
+static unsigned int event_scan;
+static unsigned int rtas_event_scan_rate;
+
+static int full_rtas_msgs = 0;
+
+/* Stop logging to nvram after first fatal error */
+static int logging_enabled; /* Until we initialize everything,
+                             * make sure we don't try logging
+                             * anything */
+static int error_log_cnt;
+
+/*
+ * Since we use 32 bit RTAS, the physical address of this must be below
+ * 4G or else bad things happen. Allocate this in the kernel data and
+ * make it big enough.
+ */
+static unsigned char logdata[RTAS_ERROR_LOG_MAX];
+
+static char *rtas_type[] = {
+	"Unknown", "Retry", "TCE Error", "Internal Device Failure",
+	"Timeout", "Data Parity", "Address Parity", "Cache Parity",
+	"Address Invalid", "ECC Uncorrected", "ECC Corrupted",
+};
+
+static char *rtas_event_type(int type)
+{
+	if ((type > 0) && (type < 11))
+		return rtas_type[type];
+
+	switch (type) {
+		case RTAS_TYPE_EPOW:
+			return "EPOW";
+		case RTAS_TYPE_PLATFORM:
+			return "Platform Error";
+		case RTAS_TYPE_IO:
+			return "I/O Event";
+		case RTAS_TYPE_INFO:
+			return "Platform Information Event";
+		case RTAS_TYPE_DEALLOC:
+			return "Resource Deallocation Event";
+		case RTAS_TYPE_DUMP:
+			return "Dump Notification Event";
+	}
+
+	return rtas_type[0];
+}
+
+/* To see this info, grep RTAS /var/log/messages and each entry
+ * will be collected together with obvious begin/end.
+ * There will be a unique identifier on the begin and end lines.
+ * This will persist across reboots.
+ *
+ * format of error logs returned from RTAS:
+ * bytes	(size)	: contents
+ * --------------------------------------------------------
+ * 0-7		(8)	: rtas_error_log
+ * 8-47		(40)	: extended info
+ * 48-51	(4)	: vendor id
+ * 52-1023 (vendor specific) : location code and debug data
+ */
+static void printk_log_rtas(char *buf, int len)
+{
+
+	int i,j,n = 0;
+	int perline = 16;
+	char buffer[64];
+	char * str = "RTAS event";
+
+	if (full_rtas_msgs) {
+		printk(RTAS_DEBUG "%d -------- %s begin --------\n",
+		       error_log_cnt, str);
+
+		/*
+		 * Print perline bytes on each line, each line will start
+		 * with RTAS and a changing number, so syslogd will
+		 * print lines that are otherwise the same.  Separate every
+		 * 4 bytes with a space.
+		 */
+		for (i = 0; i < len; i++) {
+			j = i % perline;
+			if (j == 0) {
+				memset(buffer, 0, sizeof(buffer));
+				n = sprintf(buffer, "RTAS %d:", i/perline);
+			}
+
+			if ((i % 4) == 0)
+				n += sprintf(buffer+n, " ");
+
+			n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
+
+			if (j == (perline-1))
+				printk(KERN_DEBUG "%s\n", buffer);
+		}
+		if ((i % perline) != 0)
+			printk(KERN_DEBUG "%s\n", buffer);
+
+		printk(RTAS_DEBUG "%d -------- %s end ----------\n",
+		       error_log_cnt, str);
+	} else {
+		struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
+
+		printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
+		       error_log_cnt, rtas_event_type(errlog->type),
+		       errlog->severity);
+	}
+}
+
+static int log_rtas_len(char * buf)
+{
+	int len;
+	struct rtas_error_log *err;
+
+	/* rtas fixed header */
+	len = 8;
+	err = (struct rtas_error_log *)buf;
+	if (err->extended_log_length) {
+
+		/* extended header */
+		len += err->extended_log_length;
+	}
+
+	if (rtas_error_log_max == 0)
+		rtas_error_log_max = rtas_get_error_log_max();
+
+	if (len > rtas_error_log_max)
+		len = rtas_error_log_max;
+
+	return len;
+}
+
+/*
+ * First write to nvram, if fatal error, that is the only
+ * place we log the info.  The error will be picked up
+ * on the next reboot by rtasd.  If not fatal, run the
+ * method for the type of error.  Currently, only RTAS
+ * errors have methods implemented, but in the future
+ * there might be a need to store data in nvram before a
+ * call to panic().
+ *
+ * XXX We write to nvram periodically, to indicate error has
+ * been written and sync'd, but there is a possibility
+ * that if we don't shutdown correctly, a duplicate error
+ * record will be created on next reboot.
+ */
+void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
+{
+	unsigned long offset;
+	unsigned long s;
+	int len = 0;
+
+	pr_debug("rtasd: logging event\n");
+	if (buf == NULL)
+		return;
+
+	spin_lock_irqsave(&rtasd_log_lock, s);
+
+	/* get length and increase count */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		len = log_rtas_len(buf);
+		if (!(err_type & ERR_FLAG_BOOT))
+			error_log_cnt++;
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+#ifdef CONFIG_PPC64
+	/* Write error to NVRAM */
+	if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
+		nvram_write_error_log(buf, len, err_type, error_log_cnt);
+#endif /* CONFIG_PPC64 */
+
+	/*
+	 * rtas errors can occur during boot, and we do want to capture
+	 * those somewhere, even if nvram isn't ready (why not?), and even
+	 * if rtasd isn't ready. Put them into the boot log, at least.
+	 */
+	if ((err_type & ERR_TYPE_MASK) == ERR_TYPE_RTAS_LOG)
+		printk_log_rtas(buf, len);
+
+	/* Check to see if we need to or have stopped logging */
+	if (fatal || !logging_enabled) {
+		logging_enabled = 0;
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+	/* call type specific method for error */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		offset = rtas_error_log_buffer_max *
+			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
+
+		/* First copy over sequence number */
+		memcpy(&rtas_log_buf[offset], (void *) &error_log_cnt, sizeof(int));
+
+		/* Second copy over error log data */
+		offset += sizeof(int);
+		memcpy(&rtas_log_buf[offset], buf, len);
+
+		if (rtas_log_size < LOG_NUMBER)
+			rtas_log_size += 1;
+		else
+			rtas_log_start += 1;
+
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		wake_up_interruptible(&rtas_log_wait);
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+}
+
+static int rtas_log_open(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+static int rtas_log_release(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+/* This will check if all events are logged, if they are then, we
+ * know that we can safely clear the events in NVRAM.
+ * Next we'll sit and wait for something else to log.
+ */
+static ssize_t rtas_log_read(struct file * file, char __user * buf,
+			 size_t count, loff_t *ppos)
+{
+	int error;
+	char *tmp;
+	unsigned long s;
+	unsigned long offset;
+
+	if (!buf || count < rtas_error_log_buffer_max)
+		return -EINVAL;
+
+	count = rtas_error_log_buffer_max;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	tmp = kmalloc(count, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&rtasd_log_lock, s);
+
+	/* if it's 0, then we know we got the last one (the one in NVRAM) */
+	while (rtas_log_size == 0) {
+		if (file->f_flags & O_NONBLOCK) {
+			spin_unlock_irqrestore(&rtasd_log_lock, s);
+			error = -EAGAIN;
+			goto out;
+		}
+
+		if (!logging_enabled) {
+			spin_unlock_irqrestore(&rtasd_log_lock, s);
+			error = -ENODATA;
+			goto out;
+		}
+#ifdef CONFIG_PPC64
+		nvram_clear_error_log();
+#endif /* CONFIG_PPC64 */
+
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
+		if (error)
+			goto out;
+		spin_lock_irqsave(&rtasd_log_lock, s);
+	}
+
+	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
+	memcpy(tmp, &rtas_log_buf[offset], count);
+
+	rtas_log_start += 1;
+	rtas_log_size -= 1;
+	spin_unlock_irqrestore(&rtasd_log_lock, s);
+
+	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
+out:
+	kfree(tmp);
+	return error;
+}
+
+static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &rtas_log_wait, wait);
+	if (rtas_log_size)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static const struct file_operations proc_rtas_log_operations = {
+	.read =		rtas_log_read,
+	.poll =		rtas_log_poll,
+	.open =		rtas_log_open,
+	.release =	rtas_log_release,
+};
+
+static int enable_surveillance(int timeout)
+{
+	int error;
+
+	error = rtas_set_indicator(SURVEILLANCE_TOKEN, 0, timeout);
+
+	if (error == 0)
+		return 0;
+
+	if (error == -EINVAL) {
+		printk(KERN_DEBUG "rtasd: surveillance not supported\n");
+		return 0;
+	}
+
+	printk(KERN_ERR "rtasd: could not update surveillance\n");
+	return -1;
+}
+
+static void do_event_scan(void)
+{
+	int error;
+	do {
+		memset(logdata, 0, rtas_error_log_max);
+		error = rtas_call(event_scan, 4, 1, NULL,
+				  RTAS_EVENT_SCAN_ALL_EVENTS, 0,
+				  __pa(logdata), rtas_error_log_max);
+		if (error == -1) {
+			printk(KERN_ERR "event-scan failed\n");
+			break;
+		}
+
+		if (error == 0)
+			pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
+
+	} while(error == 0);
+}
+
+static void rtas_event_scan(struct work_struct *w);
+DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
+
+/*
+ * Delay should be at least one second since some machines have problems if
+ * we call event-scan too quickly.
+ */
+static unsigned long event_scan_delay = 1*HZ;
+static int first_pass = 1;
+
+static void rtas_event_scan(struct work_struct *w)
+{
+	unsigned int cpu;
+
+	do_event_scan();
+
+	get_online_cpus();
+
+	cpu = next_cpu(smp_processor_id(), cpu_online_map);
+	if (cpu == NR_CPUS) {
+		cpu = first_cpu(cpu_online_map);
+
+		if (first_pass) {
+			first_pass = 0;
+			event_scan_delay = 30*HZ/rtas_event_scan_rate;
+
+			if (surveillance_timeout != -1) {
+				pr_debug("rtasd: enabling surveillance\n");
+				enable_surveillance(surveillance_timeout);
+				pr_debug("rtasd: surveillance enabled\n");
+			}
+		}
+	}
+
+	schedule_delayed_work_on(cpu, &event_scan_work,
+		__round_jiffies_relative(event_scan_delay, cpu));
+
+	put_online_cpus();
+}
+
+#ifdef CONFIG_PPC64
+static void retreive_nvram_error_log(void)
+{
+	unsigned int err_type ;
+	int rc ;
+
+	/* See if we have any error stored in NVRAM */
+	memset(logdata, 0, rtas_error_log_max);
+	rc = nvram_read_error_log(logdata, rtas_error_log_max,
+	                          &err_type, &error_log_cnt);
+	/* We can use rtas_log_buf now */
+	logging_enabled = 1;
+	if (!rc) {
+		if (err_type != ERR_FLAG_ALREADY_LOGGED) {
+			pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
+		}
+	}
+}
+#else /* CONFIG_PPC64 */
+static void retreive_nvram_error_log(void)
+{
+}
+#endif /* CONFIG_PPC64 */
+
+static void start_event_scan(void)
+{
+	printk(KERN_DEBUG "RTAS daemon started\n");
+	pr_debug("rtasd: will sleep for %d milliseconds\n",
+		 (30000 / rtas_event_scan_rate));
+
+	/* Retreive errors from nvram if any */
+	retreive_nvram_error_log();
+
+	schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
+				 event_scan_delay);
+}
+
+static int __init rtas_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	if (!machine_is(pseries) && !machine_is(chrp))
+		return 0;
+
+	/* No RTAS */
+	event_scan = rtas_token("event-scan");
+	if (event_scan == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_INFO "rtasd: No event-scan on system\n");
+		return -ENODEV;
+	}
+
+	rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
+	if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
+		return -ENODEV;
+	}
+
+	/* Make room for the sequence number */
+	rtas_error_log_max = rtas_get_error_log_max();
+	rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
+
+	rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
+	if (!rtas_log_buf) {
+		printk(KERN_ERR "rtasd: no memory\n");
+		return -ENOMEM;
+	}
+
+	entry = proc_create("powerpc/rtas/error_log", S_IRUSR, NULL,
+			    &proc_rtas_log_operations);
+	if (!entry)
+		printk(KERN_ERR "Failed to create error_log proc entry\n");
+
+	start_event_scan();
+
+	return 0;
+}
+__initcall(rtas_init);
+
+static int __init surveillance_setup(char *str)
+{
+	int i;
+
+	/* We only do surveillance on pseries */
+	if (!machine_is(pseries))
+		return 0;
+
+	if (get_option(&str,&i)) {
+		if (i >= 0 && i <= 255)
+			surveillance_timeout = i;
+	}
+
+	return 1;
+}
+__setup("surveillance=", surveillance_setup);
+
+static int __init rtasmsgs_setup(char *str)
+{
+	if (strcmp(str, "on") == 0)
+		full_rtas_msgs = 1;
+	else if (strcmp(str, "off") == 0)
+		full_rtas_msgs = 0;
+
+	return 1;
+}
+__setup("rtasmsgs=", rtasmsgs_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas_flash.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas_flash.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas_flash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas_flash.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  *
- * /proc/ppc64/rtas/firmware_flash interface
+ * /proc/powerpc/rtas/firmware_flash interface
  *
  * This file implements a firmware_flash interface to pump a firmware
  * image into the kernel.  At reboot time rtas_restart() will see the
@@ -740,7 +740,7 @@ static int __init rtas_flash_init(void)
 		return 1;
 	}
 
-	firmware_flash_pde = create_flash_pde("ppc64/rtas/"
+	firmware_flash_pde = create_flash_pde("powerpc/rtas/"
 					      FIRMWARE_FLASH_NAME,
 					      &rtas_flash_operations);
 	if (firmware_flash_pde == NULL) {
@@ -754,7 +754,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	firmware_update_pde = create_flash_pde("ppc64/rtas/"
+	firmware_update_pde = create_flash_pde("powerpc/rtas/"
 					       FIRMWARE_UPDATE_NAME,
 					       &rtas_flash_operations);
 	if (firmware_update_pde == NULL) {
@@ -768,7 +768,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	validate_pde = create_flash_pde("ppc64/rtas/" VALIDATE_FLASH_NAME,
+	validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME,
 			      		&validate_flash_operations);
 	if (validate_pde == NULL) {
 		rc = -ENOMEM;
@@ -781,7 +781,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	manage_pde = create_flash_pde("ppc64/rtas/" MANAGE_FLASH_NAME,
+	manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME,
 				      &manage_flash_operations);
 	if (manage_pde == NULL) {
 		rc = -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas-proc.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas-proc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/rtas-proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/rtas-proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -262,19 +262,19 @@ static int __init proc_rtas_init(void)
 	if (rtas_node == NULL)
 		return -ENODEV;
 
-	proc_create("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL,
+	proc_create("powerpc/rtas/progress", S_IRUGO|S_IWUSR, NULL,
 		    &ppc_rtas_progress_operations);
-	proc_create("ppc64/rtas/clock", S_IRUGO|S_IWUSR, NULL,
+	proc_create("powerpc/rtas/clock", S_IRUGO|S_IWUSR, NULL,
 		    &ppc_rtas_clock_operations);
-	proc_create("ppc64/rtas/poweron", S_IWUSR|S_IRUGO, NULL,
+	proc_create("powerpc/rtas/poweron", S_IWUSR|S_IRUGO, NULL,
 		    &ppc_rtas_poweron_operations);
-	proc_create("ppc64/rtas/sensors", S_IRUGO, NULL,
+	proc_create("powerpc/rtas/sensors", S_IRUGO, NULL,
 		    &ppc_rtas_sensors_operations);
-	proc_create("ppc64/rtas/frequency", S_IWUSR|S_IRUGO, NULL,
+	proc_create("powerpc/rtas/frequency", S_IWUSR|S_IRUGO, NULL,
 		    &ppc_rtas_tone_freq_operations);
-	proc_create("ppc64/rtas/volume", S_IWUSR|S_IRUGO, NULL,
+	proc_create("powerpc/rtas/volume", S_IWUSR|S_IRUGO, NULL,
 		    &ppc_rtas_tone_volume_operations);
-	proc_create("ppc64/rtas/rmo_buffer", S_IRUSR, NULL,
+	proc_create("powerpc/rtas/rmo_buffer", S_IRUSR, NULL,
 		    &ppc_rtas_rmo_buf_ops);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup_32.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_32.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_SWIOTLB
 	if (ppc_swiotlb_enable)
-		swiotlb_init();
+		swiotlb_init(1);
 #endif
 
 	paging_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup_64.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -356,11 +356,6 @@ void __init setup_system(void)
 	 */
 	initialize_cache_info();
 
-	/*
-	 * Initialize irq remapping subsystem
-	 */
-	irq_early_init();
-
 #ifdef CONFIG_PPC_RTAS
 	/*
 	 * Initialize RTAS if available
@@ -550,7 +545,7 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_SWIOTLB
 	if (ppc_swiotlb_enable)
-		swiotlb_init();
+		swiotlb_init(1);
 #endif
 
 	paging_init();
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup-common.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup-common.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/setup-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/setup-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -157,7 +157,7 @@ extern u32 cpu_temp_both(unsigned long c
 #endif /* CONFIG_TAU */
 
 #ifdef CONFIG_SMP
-DEFINE_PER_CPU(unsigned int, pvr);
+DEFINE_PER_CPU(unsigned int, cpu_pvr);
 #endif
 
 static int show_cpuinfo(struct seq_file *m, void *v)
@@ -209,7 +209,7 @@ static int show_cpuinfo(struct seq_file
 	}
 
 #ifdef CONFIG_SMP
-	pvr = per_cpu(pvr, cpu_id);
+	pvr = per_cpu(cpu_pvr, cpu_id);
 #else
 	pvr = mfspr(SPRN_PVR);
 #endif
@@ -660,6 +660,7 @@ late_initcall(check_cache_coherency);
 
 #ifdef CONFIG_DEBUG_FS
 struct dentry *powerpc_debugfs_root;
+EXPORT_SYMBOL(powerpc_debugfs_root);
 
 static int powerpc_debugfs_init(void)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/smp.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/smp.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -218,6 +218,9 @@ void crash_send_ipi(void (*crash_ipi_cal
 
 static void stop_this_cpu(void *dummy)
 {
+	/* Remove this CPU */
+	set_cpu_online(smp_processor_id(), false);
+
 	local_irq_disable();
 	while (1)
 		;
@@ -232,7 +235,7 @@ struct thread_info *current_set[NR_CPUS]
 
 static void __devinit smp_store_cpu_info(int id)
 {
-	per_cpu(pvr, id) = mfspr(SPRN_PVR);
+	per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
 }
 
 static void __init smp_create_idle(unsigned int cpu)
@@ -616,4 +619,16 @@ void __cpu_die(unsigned int cpu)
 	if (smp_ops->cpu_die)
 		smp_ops->cpu_die(cpu);
 }
+
+static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex);
+
+void cpu_hotplug_driver_lock()
+{
+	mutex_lock(&powerpc_cpu_hotplug_driver_mutex);
+}
+
+void cpu_hotplug_driver_unlock()
+{
+	mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
+}
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/swsusp_32.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/swsusp_32.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/swsusp_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/swsusp_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -303,7 +303,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HI
 	lis	r4,0x1000
 1:	addic.	r4,r4,-0x1000
 	tlbie	r4
-	blt	1b
+	bgt	1b
 	sync
 
 	/* restore the MSR and turn on the MMU */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/syscalls.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/syscalls.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/syscalls.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/syscalls.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,7 +140,6 @@ static inline unsigned long do_mmap2(uns
 			unsigned long prot, unsigned long flags,
 			unsigned long fd, unsigned long off, int shift)
 {
-	struct file * file = NULL;
 	unsigned long ret = -EINVAL;
 
 	if (!arch_validate_prot(prot))
@@ -151,20 +150,8 @@ static inline unsigned long do_mmap2(uns
 			goto out;
 		off >>= shift;
 	}
-		
-	ret = -EBADF;
-	if (!(flags & MAP_ANONYMOUS)) {
-		if (!(file = fget(fd)))
-			goto out;
-	}
 
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
-	if (file)
-		fput(file);
+	ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off);
 out:
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/sysfs.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sysfs.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -461,6 +461,25 @@ static void unregister_cpu_online(unsign
 
 	cacheinfo_cpu_offline(cpu);
 }
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+ssize_t arch_cpu_probe(const char *buf, size_t count)
+{
+	if (ppc_md.cpu_probe)
+		return ppc_md.cpu_probe(buf, count);
+
+	return -EINVAL;
+}
+
+ssize_t arch_cpu_release(const char *buf, size_t count)
+{
+	if (ppc_md.cpu_release)
+		return ppc_md.cpu_release(buf, count);
+
+	return -EINVAL;
+}
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
 #endif /* CONFIG_HOTPLUG_CPU */
 
 static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/sys_ppc32.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sys_ppc32.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/sys_ppc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/sys_ppc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -520,58 +520,6 @@ asmlinkage long compat_sys_umask(u32 mas
 	return sys_umask((int)mask);
 }
 
-#ifdef CONFIG_SYSCTL_SYSCALL
-struct __sysctl_args32 {
-	u32 name;
-	int nlen;
-	u32 oldval;
-	u32 oldlenp;
-	u32 newval;
-	u32 newlen;
-	u32 __unused[4];
-};
-
-asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args)
-{
-	struct __sysctl_args32 tmp;
-	int error;
-	size_t oldlen;
-	size_t __user *oldlenp = NULL;
-	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
-
-	if (copy_from_user(&tmp, args, sizeof(tmp)))
-		return -EFAULT;
-
-	if (tmp.oldval && tmp.oldlenp) {
-		/* Duh, this is ugly and might not work if sysctl_args
-		   is in read-only memory, but do_sysctl does indirectly
-		   a lot of uaccess in both directions and we'd have to
-		   basically copy the whole sysctl.c here, and
-		   glibc's __sysctl uses rw memory for the structure
-		   anyway.  */
-		oldlenp = (size_t __user *)addr;
-		if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) ||
-		    put_user(oldlen, oldlenp))
-			return -EFAULT;
-	}
-
-	lock_kernel();
-	error = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
-			  compat_ptr(tmp.oldval), oldlenp,
-			  compat_ptr(tmp.newval), tmp.newlen);
-	unlock_kernel();
-	if (oldlenp) {
-		if (!error) {
-			if (get_user(oldlen, oldlenp) ||
-			    put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)))
-				error = -EFAULT;
-		}
-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
-	}
-	return error;
-}
-#endif
-
 unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/tau_6xx.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/tau_6xx.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/tau_6xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/tau_6xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@ void set_thresholds(unsigned long cpu)
 	mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID);
 
 	/* setup THRM2,
-	 * threshold, valid bit, enable interrupts, interrupt when above threshhold
+	 * threshold, valid bit, enable interrupts, interrupt when above threshold
 	 */
 	mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE);
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/time.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/time.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,6 +54,7 @@
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/perf_event.h>
+#include <asm/trace.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -268,6 +269,7 @@ void account_system_vtime(struct task_st
 	per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
 	local_irq_restore(flags);
 }
+EXPORT_SYMBOL_GPL(account_system_vtime);
 
 /*
  * Transfer the user and system times accumulated in the paca
@@ -571,6 +573,8 @@ void timer_interrupt(struct pt_regs * re
 	struct clock_event_device *evt = &decrementer->event;
 	u64 now;
 
+	trace_timer_interrupt_entry(regs);
+
 	/* Ensure a positive value is written to the decrementer, or else
 	 * some CPUs will continuue to take decrementer exceptions */
 	set_dec(DECREMENTER_MAX);
@@ -590,6 +594,7 @@ void timer_interrupt(struct pt_regs * re
 		now = decrementer->next_tb - now;
 		if (now <= DECREMENTER_MAX)
 			set_dec((int)now);
+		trace_timer_interrupt_exit(regs);
 		return;
 	}
 	old_regs = set_irq_regs(regs);
@@ -620,6 +625,8 @@ void timer_interrupt(struct pt_regs * re
 
 	irq_exit();
 	set_irq_regs(old_regs);
+
+	trace_timer_interrupt_exit(regs);
 }
 
 void wakeup_decrementer(void)
@@ -828,7 +835,8 @@ static cycle_t timebase_read(struct cloc
 	return (cycle_t)get_tb();
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	u64 t2x, stamp_xsec;
 
@@ -841,7 +849,7 @@ void update_vsyscall(struct timespec *wa
 
 	/* XXX this assumes clock->shift == 22 */
 	/* 4611686018 ~= 2^(20+64-22) / 1e9 */
-	t2x = (u64) clock->mult * 4611686018ULL;
+	t2x = (u64) mult * 4611686018ULL;
 	stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
 	do_div(stamp_xsec, 1000000000);
 	stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
@@ -895,12 +903,21 @@ static void decrementer_set_mode(enum cl
 		decrementer_set_next_event(DECREMENTER_MAX, dev);
 }
 
+static inline uint64_t div_sc64(unsigned long ticks, unsigned long nsec,
+				int shift)
+{
+	uint64_t tmp = ((uint64_t)ticks) << shift;
+
+	do_div(tmp, nsec);
+	return tmp;
+}
+
 static void __init setup_clockevent_multiplier(unsigned long hz)
 {
 	u64 mult, shift = 32;
 
 	while (1) {
-		mult = div_sc(hz, NSEC_PER_SEC, shift);
+		mult = div_sc64(hz, NSEC_PER_SEC, shift);
 		if (mult && (mult >> 32UL) == 0UL)
 			break;
 
@@ -918,7 +935,7 @@ static void register_decrementer_clockev
 	*dec = decrementer_clockevent;
 	dec->cpumask = cpumask_of(cpu);
 
-	printk(KERN_DEBUG "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
+	printk(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
 	       dec->name, dec->mult, dec->shift, cpu);
 
 	clockevents_register_device(dec);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/traps.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,6 +174,15 @@ int die(const char *str, struct pt_regs
 	return 0;
 }
 
+void user_single_step_siginfo(struct task_struct *tsk,
+				struct pt_regs *regs, siginfo_t *info)
+{
+	memset(info, 0, sizeof(*info));
+	info->si_signo = SIGTRAP;
+	info->si_code = TRAP_TRACE;
+	info->si_addr = (void __user *)regs->nip;
+}
+
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 {
 	siginfo_t info;
@@ -198,28 +207,6 @@ void _exception(int signr, struct pt_reg
 	info.si_code = code;
 	info.si_addr = (void __user *) addr;
 	force_sig_info(signr, &info, current);
-
-	/*
-	 * Init gets no signals that it doesn't have a handler for.
-	 * That's all very well, but if it has caused a synchronous
-	 * exception and we ignore the resulting signal, it will just
-	 * generate the same exception over and over again and we get
-	 * nowhere.  Better to kill it and let the kernel panic.
-	 */
-	if (is_global_init(current)) {
-		__sighandler_t handler;
-
-		spin_lock_irq(&current->sighand->siglock);
-		handler = current->sighand->action[signr-1].sa.sa_handler;
-		spin_unlock_irq(&current->sighand->siglock);
-		if (handler == SIG_DFL) {
-			/* init has generated a synchronous exception
-			   and it doesn't have a handler for the signal */
-			printk(KERN_CRIT "init has generated signal %d "
-			       "but has no handler for it\n", signr);
-			do_exit(signr);
-		}
-	}
 }
 
 #ifdef CONFIG_PPC64
@@ -759,7 +746,7 @@ static int emulate_instruction(struct pt
 
 	/* Emulate the mfspr rD, PVR. */
 	if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
-		PPC_WARN_EMULATED(mfpvr);
+		PPC_WARN_EMULATED(mfpvr, regs);
 		rd = (instword >> 21) & 0x1f;
 		regs->gpr[rd] = mfspr(SPRN_PVR);
 		return 0;
@@ -767,7 +754,7 @@ static int emulate_instruction(struct pt
 
 	/* Emulating the dcba insn is just a no-op.  */
 	if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
-		PPC_WARN_EMULATED(dcba);
+		PPC_WARN_EMULATED(dcba, regs);
 		return 0;
 	}
 
@@ -776,7 +763,7 @@ static int emulate_instruction(struct pt
 		int shift = (instword >> 21) & 0x1c;
 		unsigned long msk = 0xf0000000UL >> shift;
 
-		PPC_WARN_EMULATED(mcrxr);
+		PPC_WARN_EMULATED(mcrxr, regs);
 		regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
 		regs->xer &= ~0xf0000000UL;
 		return 0;
@@ -784,19 +771,19 @@ static int emulate_instruction(struct pt
 
 	/* Emulate load/store string insn. */
 	if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
-		PPC_WARN_EMULATED(string);
+		PPC_WARN_EMULATED(string, regs);
 		return emulate_string_inst(regs, instword);
 	}
 
 	/* Emulate the popcntb (Population Count Bytes) instruction. */
 	if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
-		PPC_WARN_EMULATED(popcntb);
+		PPC_WARN_EMULATED(popcntb, regs);
 		return emulate_popcntb_inst(regs, instword);
 	}
 
 	/* Emulate isel (Integer Select) instruction */
 	if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
-		PPC_WARN_EMULATED(isel);
+		PPC_WARN_EMULATED(isel, regs);
 		return emulate_isel(regs, instword);
 	}
 
@@ -995,7 +982,7 @@ void SoftwareEmulation(struct pt_regs *r
 #ifdef CONFIG_MATH_EMULATION
 	errcode = do_mathemu(regs);
 	if (errcode >= 0)
-		PPC_WARN_EMULATED(math);
+		PPC_WARN_EMULATED(math, regs);
 
 	switch (errcode) {
 	case 0:
@@ -1018,7 +1005,7 @@ void SoftwareEmulation(struct pt_regs *r
 #elif defined(CONFIG_8XX_MINIMAL_FPEMU)
 	errcode = Soft_emulate_8xx(regs);
 	if (errcode >= 0)
-		PPC_WARN_EMULATED(8xx);
+		PPC_WARN_EMULATED(8xx, regs);
 
 	switch (errcode) {
 	case 0:
@@ -1129,7 +1116,7 @@ void altivec_assist_exception(struct pt_
 
 	flush_altivec_to_thread(current);
 
-	PPC_WARN_EMULATED(altivec);
+	PPC_WARN_EMULATED(altivec, regs);
 	err = emulate_altivec(regs);
 	if (err == 0) {
 		regs->nip += 4;		/* skip emulated instruction */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/udbg.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/udbg.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/udbg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/udbg.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,6 +60,8 @@ void __init udbg_early_init(void)
 	udbg_init_40x_realmode();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
 	udbg_init_cpm();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
+	udbg_init_usbgecko();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vdso.c linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vdso.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vdso.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vdso.c	2010-02-24 13:52:17.000000000 -0500
@@ -721,7 +721,7 @@ static int __init vdso_init(void)
 
 #ifdef CONFIG_PPC64
 	/*
-	 * Fill up the "systemcfg" stuff for backward compatiblity
+	 * Fill up the "systemcfg" stuff for backward compatibility
 	 */
 	strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
 	vdso_data->version.major = SYSTEMCFG_MAJOR;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vector.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vector.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vector.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vector.S	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@ _GLOBAL(load_up_altivec)
 	 * all 1's
 	 */
 	mfspr	r4,SPRN_VRSAVE
-	cmpdi	0,r4,0
+	cmpwi	0,r4,0
 	bne+	1f
 	li	r4,-1
 	mtspr	SPRN_VRSAVE,r4
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4;
 #endif
 SECTIONS
 {
+	. = 0;
+	reloc_start = .;
+
 	. = KERNELBASE;
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_32_mmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_32_mmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_32_mmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_32_mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,372 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/highmem.h>
+
+#include <asm/tlbflush.h>
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s.h>
+
+/* #define DEBUG_MMU */
+/* #define DEBUG_MMU_PTE */
+/* #define DEBUG_MMU_PTE_IP 0xfff14c40 */
+
+#ifdef DEBUG_MMU
+#define dprintk(X...) printk(KERN_INFO X)
+#else
+#define dprintk(X...) do { } while(0)
+#endif
+
+#ifdef DEBUG_PTE
+#define dprintk_pte(X...) printk(KERN_INFO X)
+#else
+#define dprintk_pte(X...) do { } while(0)
+#endif
+
+#define PTEG_FLAG_ACCESSED	0x00000100
+#define PTEG_FLAG_DIRTY		0x00000080
+
+static inline bool check_debug_ip(struct kvm_vcpu *vcpu)
+{
+#ifdef DEBUG_MMU_PTE_IP
+	return vcpu->arch.pc == DEBUG_MMU_PTE_IP;
+#else
+	return true;
+#endif
+}
+
+static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
+					  struct kvmppc_pte *pte, bool data);
+
+static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr)
+{
+	return &vcpu_book3s->sr[(eaddr >> 28) & 0xf];
+}
+
+static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
+					 bool data)
+{
+	struct kvmppc_sr *sre = find_sr(to_book3s(vcpu), eaddr);
+	struct kvmppc_pte pte;
+
+	if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data))
+		return pte.vpage;
+
+	return (((u64)eaddr >> 12) & 0xffff) | (((u64)sre->vsid) << 16);
+}
+
+static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
+{
+	kvmppc_set_msr(vcpu, 0);
+}
+
+static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s,
+				      struct kvmppc_sr *sre, gva_t eaddr,
+				      bool primary)
+{
+	u32 page, hash, pteg, htabmask;
+	hva_t r;
+
+	page = (eaddr & 0x0FFFFFFF) >> 12;
+	htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0;
+
+	hash = ((sre->vsid ^ page) << 6);
+	if (!primary)
+		hash = ~hash;
+	hash &= htabmask;
+
+	pteg = (vcpu_book3s->sdr1 & 0xffff0000) | hash;
+
+	dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n",
+		vcpu_book3s->vcpu.arch.pc, eaddr, vcpu_book3s->sdr1, pteg,
+		sre->vsid);
+
+	r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
+	if (kvm_is_error_hva(r))
+		return r;
+	return r | (pteg & ~PAGE_MASK);
+}
+
+static u32 kvmppc_mmu_book3s_32_get_ptem(struct kvmppc_sr *sre, gva_t eaddr,
+				    bool primary)
+{
+	return ((eaddr & 0x0fffffff) >> 22) | (sre->vsid << 7) |
+	       (primary ? 0 : 0x40) | 0x80000000;
+}
+
+static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
+					  struct kvmppc_pte *pte, bool data)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_bat *bat;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		if (data)
+			bat = &vcpu_book3s->dbat[i];
+		else
+			bat = &vcpu_book3s->ibat[i];
+
+		if (vcpu->arch.msr & MSR_PR) {
+			if (!bat->vp)
+				continue;
+		} else {
+			if (!bat->vs)
+				continue;
+		}
+
+		if (check_debug_ip(vcpu))
+		{
+			dprintk_pte("%cBAT %02d: 0x%lx - 0x%x (0x%x)\n",
+				    data ? 'd' : 'i', i, eaddr, bat->bepi,
+				    bat->bepi_mask);
+		}
+		if ((eaddr & bat->bepi_mask) == bat->bepi) {
+			pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask);
+			pte->vpage = (eaddr >> 12) | VSID_BAT;
+			pte->may_read = bat->pp;
+			pte->may_write = bat->pp > 1;
+			pte->may_execute = true;
+			if (!pte->may_read) {
+				printk(KERN_INFO "BAT is not readable!\n");
+				continue;
+			}
+			if (!pte->may_write) {
+				/* let's treat r/o BATs as not-readable for now */
+				dprintk_pte("BAT is read-only!\n");
+				continue;
+			}
+
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
+				     struct kvmppc_pte *pte, bool data,
+				     bool primary)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_sr *sre;
+	hva_t ptegp;
+	u32 pteg[16];
+	u64 ptem = 0;
+	int i;
+	int found = 0;
+
+	sre = find_sr(vcpu_book3s, eaddr);
+
+	dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28,
+		    sre->vsid, sre->raw);
+
+	pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
+
+	ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu_book3s, sre, eaddr, primary);
+	if (kvm_is_error_hva(ptegp)) {
+		printk(KERN_INFO "KVM: Invalid PTEG!\n");
+		goto no_page_found;
+	}
+
+	ptem = kvmppc_mmu_book3s_32_get_ptem(sre, eaddr, primary);
+
+	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;
+	}
+
+	for (i=0; i<16; i+=2) {
+		if (ptem == pteg[i]) {
+			u8 pp;
+
+			pte->raddr = (pteg[i+1] & ~(0xFFFULL)) | (eaddr & 0xFFF);
+			pp = pteg[i+1] & 3;
+
+			if ((sre->Kp &&  (vcpu->arch.msr & MSR_PR)) ||
+			    (sre->Ks && !(vcpu->arch.msr & MSR_PR)))
+				pp |= 4;
+
+			pte->may_write = false;
+			pte->may_read = false;
+			pte->may_execute = true;
+			switch (pp) {
+				case 0:
+				case 1:
+				case 2:
+				case 6:
+					pte->may_write = true;
+				case 3:
+				case 5:
+				case 7:
+					pte->may_read = true;
+					break;
+			}
+
+			if ( !pte->may_read )
+				continue;
+
+			dprintk_pte("MMU: Found PTE -> %x %x - %x\n",
+				    pteg[i], pteg[i+1], pp);
+			found = 1;
+			break;
+		}
+	}
+
+	/* Update PTE C and A bits, so the guest's swapper knows we used the
+	   page */
+	if (found) {
+		u32 oldpte = pteg[i+1];
+
+		if (pte->may_read)
+			pteg[i+1] |= PTEG_FLAG_ACCESSED;
+		if (pte->may_write)
+			pteg[i+1] |= PTEG_FLAG_DIRTY;
+		else
+			dprintk_pte("KVM: Mapping read-only page!\n");
+
+		/* Write back into the PTEG */
+		if (pteg[i+1] != oldpte)
+			copy_to_user((void __user *)ptegp, pteg, sizeof(pteg));
+
+		return 0;
+	}
+
+no_page_found:
+
+	if (check_debug_ip(vcpu)) {
+		dprintk_pte("KVM MMU: No PTE found (sdr1=0x%llx ptegp=0x%lx)\n",
+			    to_book3s(vcpu)->sdr1, ptegp);
+		for (i=0; i<16; i+=2) {
+			dprintk_pte("   %02d: 0x%x - 0x%x (0x%llx)\n",
+				    i, pteg[i], pteg[i+1], ptem);
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
+				      struct kvmppc_pte *pte, bool data)
+{
+	int r;
+
+	pte->eaddr = eaddr;
+	r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data);
+	if (r < 0)
+	       r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, true);
+	if (r < 0)
+	       r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte, data, false);
+
+	return r;
+}
+
+
+static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum)
+{
+	return to_book3s(vcpu)->sr[srnum].raw;
+}
+
+static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
+					ulong value)
+{
+	struct kvmppc_sr *sre;
+
+	sre = &to_book3s(vcpu)->sr[srnum];
+
+	/* Flush any left-over shadows from the previous SR */
+
+	/* XXX Not necessary? */
+	/* kvmppc_mmu_pte_flush(vcpu, ((u64)sre->vsid) << 28, 0xf0000000ULL); */
+
+	/* And then put in the new SR */
+	sre->raw = value;
+	sre->vsid = (value & 0x0fffffff);
+	sre->Ks = (value & 0x40000000) ? true : false;
+	sre->Kp = (value & 0x20000000) ? true : false;
+	sre->nx = (value & 0x10000000) ? true : false;
+
+	/* Map the new segment */
+	kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT);
+}
+
+static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large)
+{
+	kvmppc_mmu_pte_flush(vcpu, ea, ~0xFFFULL);
+}
+
+static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid,
+					     u64 *vsid)
+{
+	/* In case we only have one of MSR_IR or MSR_DR set, let's put
+	   that in the real-mode context (and hope RM doesn't access
+	   high memory) */
+	switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+	case 0:
+		*vsid = (VSID_REAL >> 16) | esid;
+		break;
+	case MSR_IR:
+		*vsid = (VSID_REAL_IR >> 16) | esid;
+		break;
+	case MSR_DR:
+		*vsid = (VSID_REAL_DR >> 16) | esid;
+		break;
+	case MSR_DR|MSR_IR:
+	{
+		ulong ea;
+		ea = esid << SID_SHIFT;
+		*vsid = find_sr(to_book3s(vcpu), ea)->vsid;
+		break;
+	}
+	default:
+		BUG();
+	}
+
+	return 0;
+}
+
+static bool kvmppc_mmu_book3s_32_is_dcbz32(struct kvm_vcpu *vcpu)
+{
+	return true;
+}
+
+
+void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
+
+	mmu->mtsrin = kvmppc_mmu_book3s_32_mtsrin;
+	mmu->mfsrin = kvmppc_mmu_book3s_32_mfsrin;
+	mmu->xlate = kvmppc_mmu_book3s_32_xlate;
+	mmu->reset_msr = kvmppc_mmu_book3s_32_reset_msr;
+	mmu->tlbie = kvmppc_mmu_book3s_32_tlbie;
+	mmu->esid_to_vsid = kvmppc_mmu_book3s_32_esid_to_vsid;
+	mmu->ea_to_vp = kvmppc_mmu_book3s_32_ea_to_vp;
+	mmu->is_dcbz32 = kvmppc_mmu_book3s_32_is_dcbz32;
+
+	mmu->slbmte = NULL;
+	mmu->slbmfee = NULL;
+	mmu->slbmfev = NULL;
+	mmu->slbie = NULL;
+	mmu->slbia = NULL;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_emulate.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_emulate.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_emulate.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_emulate.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,345 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <asm/kvm_ppc.h>
+#include <asm/disassemble.h>
+#include <asm/kvm_book3s.h>
+#include <asm/reg.h>
+
+#define OP_19_XOP_RFID		18
+#define OP_19_XOP_RFI		50
+
+#define OP_31_XOP_MFMSR		83
+#define OP_31_XOP_MTMSR		146
+#define OP_31_XOP_MTMSRD	178
+#define OP_31_XOP_MTSRIN	242
+#define OP_31_XOP_TLBIEL	274
+#define OP_31_XOP_TLBIE		306
+#define OP_31_XOP_SLBMTE	402
+#define OP_31_XOP_SLBIE		434
+#define OP_31_XOP_SLBIA		498
+#define OP_31_XOP_MFSRIN	659
+#define OP_31_XOP_SLBMFEV	851
+#define OP_31_XOP_EIOIO		854
+#define OP_31_XOP_SLBMFEE	915
+
+/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */
+#define OP_31_XOP_DCBZ		1010
+
+int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                           unsigned int inst, int *advance)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (get_op(inst)) {
+	case 19:
+		switch (get_xop(inst)) {
+		case OP_19_XOP_RFID:
+		case OP_19_XOP_RFI:
+			vcpu->arch.pc = vcpu->arch.srr0;
+			kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+			*advance = 0;
+			break;
+
+		default:
+			emulated = EMULATE_FAIL;
+			break;
+		}
+		break;
+	case 31:
+		switch (get_xop(inst)) {
+		case OP_31_XOP_MFMSR:
+			vcpu->arch.gpr[get_rt(inst)] = vcpu->arch.msr;
+			break;
+		case OP_31_XOP_MTMSRD:
+		{
+			ulong rs = vcpu->arch.gpr[get_rs(inst)];
+			if (inst & 0x10000) {
+				vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
+				vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
+			} else
+				kvmppc_set_msr(vcpu, rs);
+			break;
+		}
+		case OP_31_XOP_MTMSR:
+			kvmppc_set_msr(vcpu, vcpu->arch.gpr[get_rs(inst)]);
+			break;
+		case OP_31_XOP_MFSRIN:
+		{
+			int srnum;
+
+			srnum = (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf;
+			if (vcpu->arch.mmu.mfsrin) {
+				u32 sr;
+				sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
+				vcpu->arch.gpr[get_rt(inst)] = sr;
+			}
+			break;
+		}
+		case OP_31_XOP_MTSRIN:
+			vcpu->arch.mmu.mtsrin(vcpu,
+				(vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf,
+				vcpu->arch.gpr[get_rs(inst)]);
+			break;
+		case OP_31_XOP_TLBIE:
+		case OP_31_XOP_TLBIEL:
+		{
+			bool large = (inst & 0x00200000) ? true : false;
+			ulong addr = vcpu->arch.gpr[get_rb(inst)];
+			vcpu->arch.mmu.tlbie(vcpu, addr, large);
+			break;
+		}
+		case OP_31_XOP_EIOIO:
+			break;
+		case OP_31_XOP_SLBMTE:
+			if (!vcpu->arch.mmu.slbmte)
+				return EMULATE_FAIL;
+
+			vcpu->arch.mmu.slbmte(vcpu, vcpu->arch.gpr[get_rs(inst)],
+						vcpu->arch.gpr[get_rb(inst)]);
+			break;
+		case OP_31_XOP_SLBIE:
+			if (!vcpu->arch.mmu.slbie)
+				return EMULATE_FAIL;
+
+			vcpu->arch.mmu.slbie(vcpu, vcpu->arch.gpr[get_rb(inst)]);
+			break;
+		case OP_31_XOP_SLBIA:
+			if (!vcpu->arch.mmu.slbia)
+				return EMULATE_FAIL;
+
+			vcpu->arch.mmu.slbia(vcpu);
+			break;
+		case OP_31_XOP_SLBMFEE:
+			if (!vcpu->arch.mmu.slbmfee) {
+				emulated = EMULATE_FAIL;
+			} else {
+				ulong t, rb;
+
+				rb = vcpu->arch.gpr[get_rb(inst)];
+				t = vcpu->arch.mmu.slbmfee(vcpu, rb);
+				vcpu->arch.gpr[get_rt(inst)] = t;
+			}
+			break;
+		case OP_31_XOP_SLBMFEV:
+			if (!vcpu->arch.mmu.slbmfev) {
+				emulated = EMULATE_FAIL;
+			} else {
+				ulong t, rb;
+
+				rb = vcpu->arch.gpr[get_rb(inst)];
+				t = vcpu->arch.mmu.slbmfev(vcpu, rb);
+				vcpu->arch.gpr[get_rt(inst)] = t;
+			}
+			break;
+		case OP_31_XOP_DCBZ:
+		{
+			ulong rb =  vcpu->arch.gpr[get_rb(inst)];
+			ulong ra = 0;
+			ulong addr;
+			u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+			if (get_ra(inst))
+				ra = vcpu->arch.gpr[get_ra(inst)];
+
+			addr = (ra + rb) & ~31ULL;
+			if (!(vcpu->arch.msr & MSR_SF))
+				addr &= 0xffffffff;
+
+			if (kvmppc_st(vcpu, addr, 32, zeros)) {
+				vcpu->arch.dear = addr;
+				vcpu->arch.fault_dear = addr;
+				to_book3s(vcpu)->dsisr = DSISR_PROTFAULT |
+						      DSISR_ISSTORE;
+				kvmppc_book3s_queue_irqprio(vcpu,
+					BOOK3S_INTERRUPT_DATA_STORAGE);
+				kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL);
+			}
+
+			break;
+		}
+		default:
+			emulated = EMULATE_FAIL;
+		}
+		break;
+	default:
+		emulated = EMULATE_FAIL;
+	}
+
+	return emulated;
+}
+
+void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
+                    u32 val)
+{
+	if (upper) {
+		/* Upper BAT */
+		u32 bl = (val >> 2) & 0x7ff;
+		bat->bepi_mask = (~bl << 17);
+		bat->bepi = val & 0xfffe0000;
+		bat->vs = (val & 2) ? 1 : 0;
+		bat->vp = (val & 1) ? 1 : 0;
+		bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
+	} else {
+		/* Lower BAT */
+		bat->brpn = val & 0xfffe0000;
+		bat->wimg = (val >> 3) & 0xf;
+		bat->pp = val & 3;
+		bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
+	}
+}
+
+static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_bat *bat;
+
+	switch (sprn) {
+	case SPRN_IBAT0U ... SPRN_IBAT3L:
+		bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
+		break;
+	case SPRN_IBAT4U ... SPRN_IBAT7L:
+		bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT4U) / 2];
+		break;
+	case SPRN_DBAT0U ... SPRN_DBAT3L:
+		bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
+		break;
+	case SPRN_DBAT4U ... SPRN_DBAT7L:
+		bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT4U) / 2];
+		break;
+	default:
+		BUG();
+	}
+
+	kvmppc_set_bat(vcpu, bat, !(sprn % 2), val);
+}
+
+int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_SDR1:
+		to_book3s(vcpu)->sdr1 = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_DSISR:
+		to_book3s(vcpu)->dsisr = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_DAR:
+		vcpu->arch.dear = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_HIOR:
+		to_book3s(vcpu)->hior = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IBAT0U ... SPRN_IBAT3L:
+	case SPRN_IBAT4U ... SPRN_IBAT7L:
+	case SPRN_DBAT0U ... SPRN_DBAT3L:
+	case SPRN_DBAT4U ... SPRN_DBAT7L:
+		kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
+		/* BAT writes happen so rarely that we're ok to flush
+		 * everything here */
+		kvmppc_mmu_pte_flush(vcpu, 0, 0);
+		break;
+	case SPRN_HID0:
+		to_book3s(vcpu)->hid[0] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_HID1:
+		to_book3s(vcpu)->hid[1] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_HID2:
+		to_book3s(vcpu)->hid[2] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_HID4:
+		to_book3s(vcpu)->hid[4] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_HID5:
+		to_book3s(vcpu)->hid[5] = vcpu->arch.gpr[rs];
+		/* guest HID5 set can change is_dcbz32 */
+		if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
+		    (mfmsr() & MSR_HV))
+			vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
+		break;
+	case SPRN_ICTC:
+	case SPRN_THRM1:
+	case SPRN_THRM2:
+	case SPRN_THRM3:
+	case SPRN_CTRLF:
+	case SPRN_CTRLT:
+		break;
+	default:
+		printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
+#ifndef DEBUG_SPR
+		emulated = EMULATE_FAIL;
+#endif
+		break;
+	}
+
+	return emulated;
+}
+
+int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_SDR1:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->sdr1;
+		break;
+	case SPRN_DSISR:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->dsisr;
+		break;
+	case SPRN_DAR:
+		vcpu->arch.gpr[rt] = vcpu->arch.dear;
+		break;
+	case SPRN_HIOR:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hior;
+		break;
+	case SPRN_HID0:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[0];
+		break;
+	case SPRN_HID1:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[1];
+		break;
+	case SPRN_HID2:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[2];
+		break;
+	case SPRN_HID4:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[4];
+		break;
+	case SPRN_HID5:
+		vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[5];
+		break;
+	case SPRN_THRM1:
+	case SPRN_THRM2:
+	case SPRN_THRM3:
+	case SPRN_CTRLF:
+	case SPRN_CTRLT:
+		vcpu->arch.gpr[rt] = 0;
+		break;
+	default:
+		printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
+#ifndef DEBUG_SPR
+		emulated = EMULATE_FAIL;
+#endif
+		break;
+	}
+
+	return emulated;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_exports.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_exports.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_exports.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_exports.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,24 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <linux/module.h>
+#include <asm/kvm_book3s.h>
+
+EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
+EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_interrupts.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,392 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/kvm_asm.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+#include <asm/exception-64s.h>
+
+#define KVMPPC_HANDLE_EXIT .kvmppc_handle_exit
+#define ULONG_SIZE 8
+#define VCPU_GPR(n)     (VCPU_GPRS + (n * ULONG_SIZE))
+
+.macro mfpaca tmp_reg, src_reg, offset, vcpu_reg
+	ld	\tmp_reg, (PACA_EXMC+\offset)(r13)
+	std	\tmp_reg, VCPU_GPR(\src_reg)(\vcpu_reg)
+.endm
+
+.macro DISABLE_INTERRUPTS
+       mfmsr   r0
+       rldicl  r0,r0,48,1
+       rotldi  r0,r0,16
+       mtmsrd  r0,1
+.endm
+
+/*****************************************************************************
+ *                                                                           *
+ *     Guest entry / exit code that is in kernel module memory (highmem)     *
+ *                                                                           *
+ ****************************************************************************/
+
+/* Registers:
+ *  r3: kvm_run pointer
+ *  r4: vcpu pointer
+ */
+_GLOBAL(__kvmppc_vcpu_entry)
+
+kvm_start_entry:
+	/* Write correct stack frame */
+	mflr    r0
+	std     r0,16(r1)
+
+	/* Save host state to the stack */
+	stdu	r1, -SWITCH_FRAME_SIZE(r1)
+
+	/* Save r3 (kvm_run) and r4 (vcpu) */
+	SAVE_2GPRS(3, r1)
+
+	/* Save non-volatile registers (r14 - r31) */
+	SAVE_NVGPRS(r1)
+
+	/* Save LR */
+	mflr	r14
+	std	r14, _LINK(r1)
+
+/* XXX optimize non-volatile loading away */
+kvm_start_lightweight:
+
+	DISABLE_INTERRUPTS
+
+	/* Save R1/R2 in the PACA */
+	std	r1, PACAR1(r13)
+	std	r2, (PACA_EXMC+EX_SRR0)(r13)
+	ld	r3, VCPU_HIGHMEM_HANDLER(r4)
+	std	r3, PACASAVEDMSR(r13)
+
+	/* Load non-volatile guest state from the vcpu */
+	ld	r14, VCPU_GPR(r14)(r4)
+	ld	r15, VCPU_GPR(r15)(r4)
+	ld	r16, VCPU_GPR(r16)(r4)
+	ld	r17, VCPU_GPR(r17)(r4)
+	ld	r18, VCPU_GPR(r18)(r4)
+	ld	r19, VCPU_GPR(r19)(r4)
+	ld	r20, VCPU_GPR(r20)(r4)
+	ld	r21, VCPU_GPR(r21)(r4)
+	ld	r22, VCPU_GPR(r22)(r4)
+	ld	r23, VCPU_GPR(r23)(r4)
+	ld	r24, VCPU_GPR(r24)(r4)
+	ld	r25, VCPU_GPR(r25)(r4)
+	ld	r26, VCPU_GPR(r26)(r4)
+	ld	r27, VCPU_GPR(r27)(r4)
+	ld	r28, VCPU_GPR(r28)(r4)
+	ld	r29, VCPU_GPR(r29)(r4)
+	ld	r30, VCPU_GPR(r30)(r4)
+	ld	r31, VCPU_GPR(r31)(r4)
+
+	ld	r9, VCPU_PC(r4)			/* r9 = vcpu->arch.pc */
+	ld	r10, VCPU_SHADOW_MSR(r4)	/* r10 = vcpu->arch.shadow_msr */
+
+	ld	r3, VCPU_TRAMPOLINE_ENTER(r4)
+	mtsrr0	r3
+
+	LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
+	mtsrr1	r3
+
+	/* Load guest state in the respective registers */
+	lwz	r3, VCPU_CR(r4)		/* r3 = vcpu->arch.cr */
+	stw	r3, (PACA_EXMC + EX_CCR)(r13)
+
+	ld	r3, VCPU_CTR(r4)	/* r3 = vcpu->arch.ctr */
+	mtctr	r3			/* CTR = r3 */
+
+	ld	r3, VCPU_LR(r4)		/* r3 = vcpu->arch.lr */
+	mtlr	r3			/* LR = r3 */
+
+	ld	r3, VCPU_XER(r4)	/* r3 = vcpu->arch.xer */
+	std	r3, (PACA_EXMC + EX_R3)(r13)
+
+	/* Some guests may need to have dcbz set to 32 byte length.
+	 *
+	 * Usually we ensure that by patching the guest's instructions
+	 * to trap on dcbz and emulate it in the hypervisor.
+	 *
+	 * If we can, we should tell the CPU to use 32 byte dcbz though,
+	 * because that's a lot faster.
+	 */
+
+	ld	r3, VCPU_HFLAGS(r4)
+	rldicl.	r3, r3, 0, 63		/* CR = ((r3 & 1) == 0) */
+	beq	no_dcbz32_on
+
+	mfspr   r3,SPRN_HID5
+	ori     r3, r3, 0x80		/* XXX HID5_dcbz32 = 0x80 */
+	mtspr   SPRN_HID5,r3
+
+no_dcbz32_on:
+	/*	Load guest GPRs */
+
+	ld	r3, VCPU_GPR(r9)(r4)
+	std	r3, (PACA_EXMC + EX_R9)(r13)
+	ld	r3, VCPU_GPR(r10)(r4)
+	std	r3, (PACA_EXMC + EX_R10)(r13)
+	ld	r3, VCPU_GPR(r11)(r4)
+	std	r3, (PACA_EXMC + EX_R11)(r13)
+	ld	r3, VCPU_GPR(r12)(r4)
+	std	r3, (PACA_EXMC + EX_R12)(r13)
+	ld	r3, VCPU_GPR(r13)(r4)
+	std	r3, (PACA_EXMC + EX_R13)(r13)
+
+	ld	r0, VCPU_GPR(r0)(r4)
+	ld	r1, VCPU_GPR(r1)(r4)
+	ld	r2, VCPU_GPR(r2)(r4)
+	ld	r3, VCPU_GPR(r3)(r4)
+	ld	r5, VCPU_GPR(r5)(r4)
+	ld	r6, VCPU_GPR(r6)(r4)
+	ld	r7, VCPU_GPR(r7)(r4)
+	ld	r8, VCPU_GPR(r8)(r4)
+	ld	r4, VCPU_GPR(r4)(r4)
+
+	/* This sets the Magic value for the trampoline */
+
+	li	r11, 1
+	stb	r11, PACA_KVM_IN_GUEST(r13)
+
+	/* Jump to SLB patching handlder and into our guest */
+	RFI
+
+/*
+ * This is the handler in module memory. It gets jumped at from the
+ * lowmem trampoline code, so it's basically the guest exit code.
+ *
+ */
+
+.global kvmppc_handler_highmem
+kvmppc_handler_highmem:
+
+	/*
+	 * Register usage at this point:
+	 *
+	 * R00   = guest R13
+	 * R01   = host R1
+	 * R02   = host R2
+	 * R10   = guest PC
+	 * R11   = guest MSR
+	 * R12   = exit handler id
+	 * R13   = PACA
+	 * PACA.exmc.R9    = guest R1
+	 * PACA.exmc.R10   = guest R10
+	 * PACA.exmc.R11   = guest R11
+	 * PACA.exmc.R12   = guest R12
+	 * PACA.exmc.R13   = guest R2
+	 * PACA.exmc.DAR   = guest DAR
+	 * PACA.exmc.DSISR = guest DSISR
+	 * PACA.exmc.LR    = guest instruction
+	 * PACA.exmc.CCR   = guest CR
+	 * PACA.exmc.SRR0  = guest R0
+	 *
+	 */
+
+	std	r3, (PACA_EXMC+EX_R3)(r13)
+
+	/* save the exit id in R3 */
+	mr	r3, r12
+
+	/* R12 = vcpu */
+	ld	r12, GPR4(r1)
+
+	/* Now save the guest state */
+
+	std	r0, VCPU_GPR(r13)(r12)
+	std	r4, VCPU_GPR(r4)(r12)
+	std	r5, VCPU_GPR(r5)(r12)
+	std	r6, VCPU_GPR(r6)(r12)
+	std	r7, VCPU_GPR(r7)(r12)
+	std	r8, VCPU_GPR(r8)(r12)
+	std	r9, VCPU_GPR(r9)(r12)
+
+	/* get registers from PACA */
+	mfpaca	r5, r0, EX_SRR0, r12
+	mfpaca	r5, r3, EX_R3, r12
+	mfpaca	r5, r1, EX_R9, r12
+	mfpaca	r5, r10, EX_R10, r12
+	mfpaca	r5, r11, EX_R11, r12
+	mfpaca	r5, r12, EX_R12, r12
+	mfpaca	r5, r2, EX_R13, r12
+
+	lwz	r5, (PACA_EXMC+EX_LR)(r13)
+	stw	r5, VCPU_LAST_INST(r12)
+
+	lwz	r5, (PACA_EXMC+EX_CCR)(r13)
+	stw	r5, VCPU_CR(r12)
+
+	ld	r5, VCPU_HFLAGS(r12)
+	rldicl.	r5, r5, 0, 63		/* CR = ((r5 & 1) == 0) */
+	beq	no_dcbz32_off
+
+	mfspr   r5,SPRN_HID5
+	rldimi  r5,r5,6,56
+	mtspr   SPRN_HID5,r5
+
+no_dcbz32_off:
+
+	/* XXX maybe skip on lightweight? */
+	std	r14, VCPU_GPR(r14)(r12)
+	std	r15, VCPU_GPR(r15)(r12)
+	std	r16, VCPU_GPR(r16)(r12)
+	std	r17, VCPU_GPR(r17)(r12)
+	std	r18, VCPU_GPR(r18)(r12)
+	std	r19, VCPU_GPR(r19)(r12)
+	std	r20, VCPU_GPR(r20)(r12)
+	std	r21, VCPU_GPR(r21)(r12)
+	std	r22, VCPU_GPR(r22)(r12)
+	std	r23, VCPU_GPR(r23)(r12)
+	std	r24, VCPU_GPR(r24)(r12)
+	std	r25, VCPU_GPR(r25)(r12)
+	std	r26, VCPU_GPR(r26)(r12)
+	std	r27, VCPU_GPR(r27)(r12)
+	std	r28, VCPU_GPR(r28)(r12)
+	std	r29, VCPU_GPR(r29)(r12)
+	std	r30, VCPU_GPR(r30)(r12)
+	std	r31, VCPU_GPR(r31)(r12)
+
+	/* Restore non-volatile host registers (r14 - r31) */
+	REST_NVGPRS(r1)
+
+	/* Save guest PC (R10) */
+	std	r10, VCPU_PC(r12)
+
+	/* Save guest msr (R11) */
+	std	r11, VCPU_SHADOW_MSR(r12)
+
+	/* Save guest CTR (in R12) */
+	mfctr	r5
+	std	r5, VCPU_CTR(r12)
+
+	/* Save guest LR */
+	mflr	r5
+	std	r5, VCPU_LR(r12)
+
+	/* Save guest XER */
+	mfxer	r5
+	std	r5, VCPU_XER(r12)
+
+	/* Save guest DAR */
+	ld	r5, (PACA_EXMC+EX_DAR)(r13)
+	std	r5, VCPU_FAULT_DEAR(r12)
+
+	/* Save guest DSISR */
+	lwz	r5, (PACA_EXMC+EX_DSISR)(r13)
+	std	r5, VCPU_FAULT_DSISR(r12)
+
+	/* Restore host msr -> SRR1 */
+	ld	r7, VCPU_HOST_MSR(r12)
+	mtsrr1	r7
+
+	/* Restore host IP -> SRR0 */
+	ld	r6, VCPU_HOST_RETIP(r12)
+	mtsrr0	r6
+
+	/*
+	 * For some interrupts, we need to call the real Linux
+	 * handler, so it can do work for us. This has to happen
+	 * as if the interrupt arrived from the kernel though,
+	 * so let's fake it here where most state is restored.
+	 *
+	 * Call Linux for hardware interrupts/decrementer
+	 * r3 = address of interrupt handler (exit reason)
+	 */
+
+	cmpwi	r3, BOOK3S_INTERRUPT_EXTERNAL
+	beq	call_linux_handler
+	cmpwi	r3, BOOK3S_INTERRUPT_DECREMENTER
+	beq	call_linux_handler
+
+	/* Back to Interruptable Mode! (goto kvm_return_point) */
+	RFI
+
+call_linux_handler:
+
+	/*
+	 * If we land here we need to jump back to the handler we
+	 * came from.
+	 *
+	 * We have a page that we can access from real mode, so let's
+	 * jump back to that and use it as a trampoline to get back into the
+	 * interrupt handler!
+	 *
+	 * R3 still contains the exit code,
+	 * R6 VCPU_HOST_RETIP and
+	 * R7 VCPU_HOST_MSR
+	 */
+
+	mtlr	r3
+
+	ld	r5, VCPU_TRAMPOLINE_LOWMEM(r12)
+	mtsrr0	r5
+	LOAD_REG_IMMEDIATE(r5, MSR_KERNEL & ~(MSR_IR | MSR_DR))
+	mtsrr1	r5
+
+	RFI
+
+.global kvm_return_point
+kvm_return_point:
+
+	/* Jump back to lightweight entry if we're supposed to */
+	/* go back into the guest */
+	mr	r5, r3
+	/* Restore r3 (kvm_run) and r4 (vcpu) */
+	REST_2GPRS(3, r1)
+	bl	KVMPPC_HANDLE_EXIT
+
+#if 0 /* XXX get lightweight exits back */
+	cmpwi	r3, RESUME_GUEST
+	bne	kvm_exit_heavyweight
+
+	/* put VCPU and KVM_RUN back into place and roll again! */
+	REST_2GPRS(3, r1)
+	b	kvm_start_lightweight
+
+kvm_exit_heavyweight:
+	/* Restore non-volatile host registers */
+	ld	r14, _LINK(r1)
+	mtlr	r14
+	REST_NVGPRS(r1)
+
+	addi    r1, r1, SWITCH_FRAME_SIZE
+#else
+	ld	r4, _LINK(r1)
+	mtlr	r4
+
+	cmpwi	r3, RESUME_GUEST
+	bne	kvm_exit_heavyweight
+
+	REST_2GPRS(3, r1)
+
+	addi    r1, r1, SWITCH_FRAME_SIZE
+
+	b	kvm_start_entry
+
+kvm_exit_heavyweight:
+
+	addi    r1, r1, SWITCH_FRAME_SIZE
+#endif
+
+	blr
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_mmu.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_mmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,498 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/highmem.h>
+
+#include <asm/tlbflush.h>
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s.h>
+
+/* #define DEBUG_MMU */
+
+#ifdef DEBUG_MMU
+#define dprintk(X...) printk(KERN_INFO X)
+#else
+#define dprintk(X...) do { } while(0)
+#endif
+
+static void kvmppc_mmu_book3s_64_reset_msr(struct kvm_vcpu *vcpu)
+{
+	kvmppc_set_msr(vcpu, MSR_SF);
+}
+
+static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
+				struct kvmppc_vcpu_book3s *vcpu_book3s,
+				gva_t eaddr)
+{
+	int i;
+	u64 esid = GET_ESID(eaddr);
+	u64 esid_1t = GET_ESID_1T(eaddr);
+
+	for (i = 0; i < vcpu_book3s->slb_nr; i++) {
+		u64 cmp_esid = esid;
+
+		if (!vcpu_book3s->slb[i].valid)
+			continue;
+
+		if (vcpu_book3s->slb[i].large)
+			cmp_esid = esid_1t;
+
+		if (vcpu_book3s->slb[i].esid == cmp_esid)
+			return &vcpu_book3s->slb[i];
+	}
+
+	dprintk("KVM: No SLB entry found for 0x%lx [%llx | %llx]\n",
+		eaddr, esid, esid_1t);
+	for (i = 0; i < vcpu_book3s->slb_nr; i++) {
+	    if (vcpu_book3s->slb[i].vsid)
+		dprintk("  %d: %c%c %llx %llx\n", i,
+			vcpu_book3s->slb[i].valid ? 'v' : ' ',
+			vcpu_book3s->slb[i].large ? 'l' : ' ',
+			vcpu_book3s->slb[i].esid,
+			vcpu_book3s->slb[i].vsid);
+	}
+
+	return NULL;
+}
+
+static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
+					 bool data)
+{
+	struct kvmppc_slb *slb;
+
+	slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), eaddr);
+	if (!slb)
+		return 0;
+
+	if (slb->large)
+		return (((u64)eaddr >> 12) & 0xfffffff) |
+		       (((u64)slb->vsid) << 28);
+
+	return (((u64)eaddr >> 12) & 0xffff) | (((u64)slb->vsid) << 16);
+}
+
+static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe)
+{
+	return slbe->large ? 24 : 12;
+}
+
+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);
+}
+
+static hva_t kvmppc_mmu_book3s_64_get_pteg(
+				struct kvmppc_vcpu_book3s *vcpu_book3s,
+				struct kvmppc_slb *slbe, gva_t eaddr,
+				bool second)
+{
+	u64 hash, pteg, htabsize;
+	u32 page;
+	hva_t r;
+
+	page = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
+	htabsize = ((1 << ((vcpu_book3s->sdr1 & 0x1f) + 11)) - 1);
+
+	hash = slbe->vsid ^ page;
+	if (second)
+		hash = ~hash;
+	hash &= ((1ULL << 39ULL) - 1ULL);
+	hash &= htabsize;
+	hash <<= 7ULL;
+
+	pteg = vcpu_book3s->sdr1 & 0xfffffffffffc0000ULL;
+	pteg |= hash;
+
+	dprintk("MMU: page=0x%x sdr1=0x%llx pteg=0x%llx vsid=0x%llx\n",
+		page, vcpu_book3s->sdr1, pteg, slbe->vsid);
+
+	r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT);
+	if (kvm_is_error_hva(r))
+		return r;
+	return r | (pteg & ~PAGE_MASK);
+}
+
+static u64 kvmppc_mmu_book3s_64_get_avpn(struct kvmppc_slb *slbe, gva_t eaddr)
+{
+	int p = kvmppc_mmu_book3s_64_get_pagesize(slbe);
+	u64 avpn;
+
+	avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
+	avpn |= slbe->vsid << (28 - p);
+
+	if (p < 24)
+		avpn >>= ((80 - p) - 56) - 8;
+	else
+		avpn <<= 8;
+
+	return avpn;
+}
+
+static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
+				struct kvmppc_pte *gpte, bool data)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_slb *slbe;
+	hva_t ptegp;
+	u64 pteg[16];
+	u64 avpn = 0;
+	int i;
+	u8 key = 0;
+	bool found = false;
+	bool perm_err = false;
+	int second = 0;
+
+	slbe = kvmppc_mmu_book3s_64_find_slbe(vcpu_book3s, eaddr);
+	if (!slbe)
+		goto no_seg_found;
+
+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;
+	}
+
+	if ((vcpu->arch.msr & MSR_PR) && slbe->Kp)
+		key = 4;
+	else if (!(vcpu->arch.msr & MSR_PR) && slbe->Ks)
+		key = 4;
+
+	for (i=0; i<16; i+=2) {
+		u64 v = pteg[i];
+		u64 r = pteg[i+1];
+
+		/* Valid check */
+		if (!(v & HPTE_V_VALID))
+			continue;
+		/* Hash check */
+		if ((v & HPTE_V_SECONDARY) != second)
+			continue;
+
+		/* AVPN compare */
+		if (HPTE_V_AVPN_VAL(avpn) == HPTE_V_AVPN_VAL(v)) {
+			u8 pp = (r & HPTE_R_PP) | key;
+			int eaddr_mask = 0xFFF;
+
+			gpte->eaddr = eaddr;
+			gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu,
+								    eaddr,
+								    data);
+			if (slbe->large)
+				eaddr_mask = 0xFFFFFF;
+			gpte->raddr = (r & HPTE_R_RPN) | (eaddr & eaddr_mask);
+			gpte->may_execute = ((r & HPTE_R_N) ? false : true);
+			gpte->may_read = false;
+			gpte->may_write = false;
+
+			switch (pp) {
+			case 0:
+			case 1:
+			case 2:
+			case 6:
+				gpte->may_write = true;
+				/* fall through */
+			case 3:
+			case 5:
+			case 7:
+				gpte->may_read = true;
+				break;
+			}
+
+			if (!gpte->may_read) {
+				perm_err = true;
+				continue;
+			}
+
+			dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx "
+				"-> 0x%llx\n",
+				eaddr, avpn, gpte->vpage, gpte->raddr);
+			found = true;
+			break;
+		}
+	}
+
+	/* Update PTE R and C bits, so the guest's swapper knows we used the
+	 * page */
+	if (found) {
+		u32 oldr = pteg[i+1];
+
+		if (gpte->may_read) {
+			/* Set the accessed flag */
+			pteg[i+1] |= HPTE_R_R;
+		}
+		if (gpte->may_write) {
+			/* Set the dirty flag */
+			pteg[i+1] |= HPTE_R_C;
+		} else {
+			dprintk("KVM: Mapping read-only page!\n");
+		}
+
+		/* Write back into the PTEG */
+		if (pteg[i+1] != oldr)
+			copy_to_user((void __user *)ptegp, pteg, sizeof(pteg));
+
+		return 0;
+	} else {
+		dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx "
+			"ptegp=0x%lx)\n",
+			eaddr, to_book3s(vcpu)->sdr1, ptegp);
+		for (i = 0; i < 16; i += 2)
+			dprintk("   %02d: 0x%llx - 0x%llx (0x%llx)\n",
+				i, pteg[i], pteg[i+1], avpn);
+
+		if (!second) {
+			second = HPTE_V_SECONDARY;
+			goto do_second;
+		}
+	}
+
+
+no_page_found:
+
+
+	if (perm_err)
+		return -EPERM;
+
+	return -ENOENT;
+
+no_seg_found:
+
+	dprintk("KVM MMU: Trigger segment fault\n");
+	return -EINVAL;
+}
+
+static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s;
+	u64 esid, esid_1t;
+	int slb_nr;
+	struct kvmppc_slb *slbe;
+
+	dprintk("KVM MMU: slbmte(0x%llx, 0x%llx)\n", rs, rb);
+
+	vcpu_book3s = to_book3s(vcpu);
+
+	esid = GET_ESID(rb);
+	esid_1t = GET_ESID_1T(rb);
+	slb_nr = rb & 0xfff;
+
+	if (slb_nr > vcpu_book3s->slb_nr)
+		return;
+
+	slbe = &vcpu_book3s->slb[slb_nr];
+
+	slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
+	slbe->esid  = slbe->large ? esid_1t : esid;
+	slbe->vsid  = rs >> 12;
+	slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
+	slbe->Ks    = (rs & SLB_VSID_KS) ? 1 : 0;
+	slbe->Kp    = (rs & SLB_VSID_KP) ? 1 : 0;
+	slbe->nx    = (rs & SLB_VSID_N) ? 1 : 0;
+	slbe->class = (rs & SLB_VSID_C) ? 1 : 0;
+
+	slbe->orige = rb & (ESID_MASK | SLB_ESID_V);
+	slbe->origv = rs;
+
+	/* Map the new segment */
+	kvmppc_mmu_map_segment(vcpu, esid << SID_SHIFT);
+}
+
+static u64 kvmppc_mmu_book3s_64_slbmfee(struct kvm_vcpu *vcpu, u64 slb_nr)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_slb *slbe;
+
+	if (slb_nr > vcpu_book3s->slb_nr)
+		return 0;
+
+	slbe = &vcpu_book3s->slb[slb_nr];
+
+	return slbe->orige;
+}
+
+static u64 kvmppc_mmu_book3s_64_slbmfev(struct kvm_vcpu *vcpu, u64 slb_nr)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_slb *slbe;
+
+	if (slb_nr > vcpu_book3s->slb_nr)
+		return 0;
+
+	slbe = &vcpu_book3s->slb[slb_nr];
+
+	return slbe->origv;
+}
+
+static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	struct kvmppc_slb *slbe;
+
+	dprintk("KVM MMU: slbie(0x%llx)\n", ea);
+
+	slbe = kvmppc_mmu_book3s_64_find_slbe(vcpu_book3s, ea);
+
+	if (!slbe)
+		return;
+
+	dprintk("KVM MMU: slbie(0x%llx, 0x%llx)\n", ea, slbe->esid);
+
+	slbe->valid = false;
+
+	kvmppc_mmu_map_segment(vcpu, ea);
+}
+
+static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	int i;
+
+	dprintk("KVM MMU: slbia()\n");
+
+	for (i = 1; i < vcpu_book3s->slb_nr; i++)
+		vcpu_book3s->slb[i].valid = false;
+
+	if (vcpu->arch.msr & MSR_IR) {
+		kvmppc_mmu_flush_segments(vcpu);
+		kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc);
+	}
+}
+
+static void kvmppc_mmu_book3s_64_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
+					ulong value)
+{
+	u64 rb = 0, rs = 0;
+
+	/*
+	 * According to Book3 2.01 mtsrin is implemented as:
+	 *
+	 * The SLB entry specified by (RB)32:35 is loaded from register
+	 * RS, as follows.
+	 *
+	 * SLBE Bit	Source			SLB Field
+	 *
+	 * 0:31		0x0000_0000		ESID-0:31
+	 * 32:35	(RB)32:35		ESID-32:35
+	 * 36		0b1			V
+	 * 37:61	0x00_0000|| 0b0		VSID-0:24
+	 * 62:88	(RS)37:63		VSID-25:51
+	 * 89:91	(RS)33:35		Ks Kp N
+	 * 92		(RS)36			L ((RS)36 must be 0b0)
+	 * 93		0b0			C
+	 */
+
+	dprintk("KVM MMU: mtsrin(0x%x, 0x%lx)\n", srnum, value);
+
+	/* ESID = srnum */
+	rb |= (srnum & 0xf) << 28;
+	/* Set the valid bit */
+	rb |= 1 << 27;
+	/* Index = ESID */
+	rb |= srnum;
+
+	/* VSID = VSID */
+	rs |= (value & 0xfffffff) << 12;
+	/* flags = flags */
+	rs |= ((value >> 28) & 0x7) << 9;
+
+	kvmppc_mmu_book3s_64_slbmte(vcpu, rs, rb);
+}
+
+static void kvmppc_mmu_book3s_64_tlbie(struct kvm_vcpu *vcpu, ulong va,
+				       bool large)
+{
+	u64 mask = 0xFFFFFFFFFULL;
+
+	dprintk("KVM MMU: tlbie(0x%lx)\n", va);
+
+	if (large)
+		mask = 0xFFFFFF000ULL;
+	kvmppc_mmu_pte_vflush(vcpu, va >> 12, mask);
+}
+
+static int kvmppc_mmu_book3s_64_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid,
+					     u64 *vsid)
+{
+	switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+	case 0:
+		*vsid = (VSID_REAL >> 16) | esid;
+		break;
+	case MSR_IR:
+		*vsid = (VSID_REAL_IR >> 16) | esid;
+		break;
+	case MSR_DR:
+		*vsid = (VSID_REAL_DR >> 16) | esid;
+		break;
+	case MSR_DR|MSR_IR:
+	{
+		ulong ea;
+		struct kvmppc_slb *slb;
+		ea = esid << SID_SHIFT;
+		slb = kvmppc_mmu_book3s_64_find_slbe(to_book3s(vcpu), ea);
+		if (slb)
+			*vsid = slb->vsid;
+		else
+			return -ENOENT;
+
+		break;
+	}
+	default:
+		BUG();
+		break;
+	}
+
+	return 0;
+}
+
+static bool kvmppc_mmu_book3s_64_is_dcbz32(struct kvm_vcpu *vcpu)
+{
+	return (to_book3s(vcpu)->hid[5] & 0x80);
+}
+
+void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
+
+	mmu->mfsrin = NULL;
+	mmu->mtsrin = kvmppc_mmu_book3s_64_mtsrin;
+	mmu->slbmte = kvmppc_mmu_book3s_64_slbmte;
+	mmu->slbmfee = kvmppc_mmu_book3s_64_slbmfee;
+	mmu->slbmfev = kvmppc_mmu_book3s_64_slbmfev;
+	mmu->slbie = kvmppc_mmu_book3s_64_slbie;
+	mmu->slbia = kvmppc_mmu_book3s_64_slbia;
+	mmu->xlate = kvmppc_mmu_book3s_64_xlate;
+	mmu->reset_msr = kvmppc_mmu_book3s_64_reset_msr;
+	mmu->tlbie = kvmppc_mmu_book3s_64_tlbie;
+	mmu->esid_to_vsid = kvmppc_mmu_book3s_64_esid_to_vsid;
+	mmu->ea_to_vp = kvmppc_mmu_book3s_64_ea_to_vp;
+	mmu->is_dcbz32 = kvmppc_mmu_book3s_64_is_dcbz32;
+
+	vcpu->arch.hflags |= BOOK3S_HFLAG_SLB;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_mmu_host.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu_host.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_mmu_host.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_mmu_host.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2009 SUSE Linux Products GmbH. All rights reserved.
+ *
+ * Authors:
+ *     Alexander Graf <agraf@suse.de>
+ *     Kevin Wolf <mail@kevin-wolf.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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s.h>
+#include <asm/mmu-hash64.h>
+#include <asm/machdep.h>
+#include <asm/mmu_context.h>
+#include <asm/hw_irq.h>
+
+#define PTE_SIZE 12
+#define VSID_ALL 0
+
+/* #define DEBUG_MMU */
+/* #define DEBUG_SLB */
+
+#ifdef DEBUG_MMU
+#define dprintk_mmu(a, ...) printk(KERN_INFO a, __VA_ARGS__)
+#else
+#define dprintk_mmu(a, ...) do { } while(0)
+#endif
+
+#ifdef DEBUG_SLB
+#define dprintk_slb(a, ...) printk(KERN_INFO a, __VA_ARGS__)
+#else
+#define dprintk_slb(a, ...) do { } while(0)
+#endif
+
+static void invalidate_pte(struct hpte_cache *pte)
+{
+	dprintk_mmu("KVM: Flushing SPT %d: 0x%llx (0x%llx) -> 0x%llx\n",
+		    i, pte->pte.eaddr, pte->pte.vpage, pte->host_va);
+
+	ppc_md.hpte_invalidate(pte->slot, pte->host_va,
+			       MMU_PAGE_4K, MMU_SEGSIZE_256M,
+			       false);
+	pte->host_va = 0;
+	kvm_release_pfn_dirty(pte->pfn);
+}
+
+void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 guest_ea, u64 ea_mask)
+{
+	int i;
+
+	dprintk_mmu("KVM: Flushing %d Shadow PTEs: 0x%llx & 0x%llx\n",
+		    vcpu->arch.hpte_cache_offset, guest_ea, ea_mask);
+	BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
+
+	guest_ea &= ea_mask;
+	for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
+		struct hpte_cache *pte;
+
+		pte = &vcpu->arch.hpte_cache[i];
+		if (!pte->host_va)
+			continue;
+
+		if ((pte->pte.eaddr & ea_mask) == guest_ea) {
+			invalidate_pte(pte);
+		}
+	}
+
+	/* Doing a complete flush -> start from scratch */
+	if (!ea_mask)
+		vcpu->arch.hpte_cache_offset = 0;
+}
+
+void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 guest_vp, u64 vp_mask)
+{
+	int i;
+
+	dprintk_mmu("KVM: Flushing %d Shadow vPTEs: 0x%llx & 0x%llx\n",
+		    vcpu->arch.hpte_cache_offset, guest_vp, vp_mask);
+	BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
+
+	guest_vp &= vp_mask;
+	for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
+		struct hpte_cache *pte;
+
+		pte = &vcpu->arch.hpte_cache[i];
+		if (!pte->host_va)
+			continue;
+
+		if ((pte->pte.vpage & vp_mask) == guest_vp) {
+			invalidate_pte(pte);
+		}
+	}
+}
+
+void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end)
+{
+	int i;
+
+	dprintk_mmu("KVM: Flushing %d Shadow pPTEs: 0x%llx & 0x%llx\n",
+		    vcpu->arch.hpte_cache_offset, guest_pa, pa_mask);
+	BUG_ON(vcpu->arch.hpte_cache_offset > HPTEG_CACHE_NUM);
+
+	for (i = 0; i < vcpu->arch.hpte_cache_offset; i++) {
+		struct hpte_cache *pte;
+
+		pte = &vcpu->arch.hpte_cache[i];
+		if (!pte->host_va)
+			continue;
+
+		if ((pte->pte.raddr >= pa_start) &&
+		    (pte->pte.raddr < pa_end)) {
+			invalidate_pte(pte);
+		}
+	}
+}
+
+struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data)
+{
+	int i;
+	u64 guest_vp;
+
+	guest_vp = vcpu->arch.mmu.ea_to_vp(vcpu, ea, false);
+	for (i=0; i<vcpu->arch.hpte_cache_offset; i++) {
+		struct hpte_cache *pte;
+
+		pte = &vcpu->arch.hpte_cache[i];
+		if (!pte->host_va)
+			continue;
+
+		if (pte->pte.vpage == guest_vp)
+			return &pte->pte;
+	}
+
+	return NULL;
+}
+
+static int kvmppc_mmu_hpte_cache_next(struct kvm_vcpu *vcpu)
+{
+	if (vcpu->arch.hpte_cache_offset == HPTEG_CACHE_NUM)
+		kvmppc_mmu_pte_flush(vcpu, 0, 0);
+
+	return vcpu->arch.hpte_cache_offset++;
+}
+
+/* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using
+ * a hash, so we don't waste cycles on looping */
+static u16 kvmppc_sid_hash(struct kvm_vcpu *vcpu, u64 gvsid)
+{
+	return (u16)(((gvsid >> (SID_MAP_BITS * 7)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 6)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 5)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 4)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 3)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 2)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 1)) & SID_MAP_MASK) ^
+		     ((gvsid >> (SID_MAP_BITS * 0)) & SID_MAP_MASK));
+}
+
+
+static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
+{
+	struct kvmppc_sid_map *map;
+	u16 sid_map_mask;
+
+	if (vcpu->arch.msr & MSR_PR)
+		gvsid |= VSID_PR;
+
+	sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
+	map = &to_book3s(vcpu)->sid_map[sid_map_mask];
+	if (map->guest_vsid == gvsid) {
+		dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n",
+			    gvsid, map->host_vsid);
+		return map;
+	}
+
+	map = &to_book3s(vcpu)->sid_map[SID_MAP_MASK - sid_map_mask];
+	if (map->guest_vsid == gvsid) {
+		dprintk_slb("SLB: Searching 0x%llx -> 0x%llx\n",
+			    gvsid, map->host_vsid);
+		return map;
+	}
+
+	dprintk_slb("SLB: Searching 0x%llx -> not found\n", gvsid);
+	return NULL;
+}
+
+int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
+{
+	pfn_t hpaddr;
+	ulong hash, hpteg, va;
+	u64 vsid;
+	int ret;
+	int rflags = 0x192;
+	int vflags = 0;
+	int attempt = 0;
+	struct kvmppc_sid_map *map;
+
+	/* Get host physical address for gpa */
+	hpaddr = gfn_to_pfn(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
+	if (kvm_is_error_hva(hpaddr)) {
+		printk(KERN_INFO "Couldn't get guest page for gfn %llx!\n", orig_pte->eaddr);
+		return -EINVAL;
+	}
+	hpaddr <<= PAGE_SHIFT;
+#if PAGE_SHIFT == 12
+#elif PAGE_SHIFT == 16
+	hpaddr |= orig_pte->raddr & 0xf000;
+#else
+#error Unknown page size
+#endif
+
+	/* and write the mapping ea -> hpa into the pt */
+	vcpu->arch.mmu.esid_to_vsid(vcpu, orig_pte->eaddr >> SID_SHIFT, &vsid);
+	map = find_sid_vsid(vcpu, vsid);
+	if (!map) {
+		kvmppc_mmu_map_segment(vcpu, orig_pte->eaddr);
+		map = find_sid_vsid(vcpu, vsid);
+	}
+	BUG_ON(!map);
+
+	vsid = map->host_vsid;
+	va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M);
+
+	if (!orig_pte->may_write)
+		rflags |= HPTE_R_PP;
+	else
+		mark_page_dirty(vcpu->kvm, orig_pte->raddr >> PAGE_SHIFT);
+
+	if (!orig_pte->may_execute)
+		rflags |= HPTE_R_N;
+
+	hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M);
+
+map_again:
+	hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
+
+	/* In case we tried normal mapping already, let's nuke old entries */
+	if (attempt > 1)
+		if (ppc_md.hpte_remove(hpteg) < 0)
+			return -1;
+
+	ret = ppc_md.hpte_insert(hpteg, va, hpaddr, rflags, vflags, MMU_PAGE_4K, MMU_SEGSIZE_256M);
+
+	if (ret < 0) {
+		/* If we couldn't map a primary PTE, try a secondary */
+#ifdef USE_SECONDARY
+		hash = ~hash;
+		attempt++;
+		if (attempt % 2)
+			vflags = HPTE_V_SECONDARY;
+		else
+			vflags = 0;
+#else
+		attempt = 2;
+#endif
+		goto map_again;
+	} else {
+		int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu);
+		struct hpte_cache *pte = &vcpu->arch.hpte_cache[hpte_id];
+
+		dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%lx (0x%llx) -> %lx\n",
+			    ((rflags & HPTE_R_PP) == 3) ? '-' : 'w',
+			    (rflags & HPTE_R_N) ? '-' : 'x',
+			    orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr);
+
+		pte->slot = hpteg + (ret & 7);
+		pte->host_va = va;
+		pte->pte = *orig_pte;
+		pte->pfn = hpaddr >> PAGE_SHIFT;
+	}
+
+	return 0;
+}
+
+static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
+{
+	struct kvmppc_sid_map *map;
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+	u16 sid_map_mask;
+	static int backwards_map = 0;
+
+	if (vcpu->arch.msr & MSR_PR)
+		gvsid |= VSID_PR;
+
+	/* We might get collisions that trap in preceding order, so let's
+	   map them differently */
+
+	sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
+	if (backwards_map)
+		sid_map_mask = SID_MAP_MASK - sid_map_mask;
+
+	map = &to_book3s(vcpu)->sid_map[sid_map_mask];
+
+	/* Make sure we're taking the other map next time */
+	backwards_map = !backwards_map;
+
+	/* Uh-oh ... out of mappings. Let's flush! */
+	if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) {
+		vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
+		memset(vcpu_book3s->sid_map, 0,
+		       sizeof(struct kvmppc_sid_map) * SID_MAP_NUM);
+		kvmppc_mmu_pte_flush(vcpu, 0, 0);
+		kvmppc_mmu_flush_segments(vcpu);
+	}
+	map->host_vsid = vcpu_book3s->vsid_next++;
+
+	map->guest_vsid = gvsid;
+	map->valid = true;
+
+	return map;
+}
+
+static int kvmppc_mmu_next_segment(struct kvm_vcpu *vcpu, ulong esid)
+{
+	int i;
+	int max_slb_size = 64;
+	int found_inval = -1;
+	int r;
+
+	if (!get_paca()->kvm_slb_max)
+		get_paca()->kvm_slb_max = 1;
+
+	/* Are we overwriting? */
+	for (i = 1; i < get_paca()->kvm_slb_max; i++) {
+		if (!(get_paca()->kvm_slb[i].esid & SLB_ESID_V))
+			found_inval = i;
+		else if ((get_paca()->kvm_slb[i].esid & ESID_MASK) == esid)
+			return i;
+	}
+
+	/* Found a spare entry that was invalidated before */
+	if (found_inval > 0)
+		return found_inval;
+
+	/* No spare invalid entry, so create one */
+
+	if (mmu_slb_size < 64)
+		max_slb_size = mmu_slb_size;
+
+	/* Overflowing -> purge */
+	if ((get_paca()->kvm_slb_max) == max_slb_size)
+		kvmppc_mmu_flush_segments(vcpu);
+
+	r = get_paca()->kvm_slb_max;
+	get_paca()->kvm_slb_max++;
+
+	return r;
+}
+
+int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr)
+{
+	u64 esid = eaddr >> SID_SHIFT;
+	u64 slb_esid = (eaddr & ESID_MASK) | SLB_ESID_V;
+	u64 slb_vsid = SLB_VSID_USER;
+	u64 gvsid;
+	int slb_index;
+	struct kvmppc_sid_map *map;
+
+	slb_index = kvmppc_mmu_next_segment(vcpu, eaddr & ESID_MASK);
+
+	if (vcpu->arch.mmu.esid_to_vsid(vcpu, esid, &gvsid)) {
+		/* Invalidate an entry */
+		get_paca()->kvm_slb[slb_index].esid = 0;
+		return -ENOENT;
+	}
+
+	map = find_sid_vsid(vcpu, gvsid);
+	if (!map)
+		map = create_sid_map(vcpu, gvsid);
+
+	map->guest_esid = esid;
+
+	slb_vsid |= (map->host_vsid << 12);
+	slb_vsid &= ~SLB_VSID_KP;
+	slb_esid |= slb_index;
+
+	get_paca()->kvm_slb[slb_index].esid = slb_esid;
+	get_paca()->kvm_slb[slb_index].vsid = slb_vsid;
+
+	dprintk_slb("slbmte %#llx, %#llx\n", slb_vsid, slb_esid);
+
+	return 0;
+}
+
+void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu)
+{
+	get_paca()->kvm_slb_max = 1;
+	get_paca()->kvm_slb[0].esid = 0;
+}
+
+void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
+{
+	kvmppc_mmu_pte_flush(vcpu, 0, 0);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_rmhandlers.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,131 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/kvm_asm.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/asm-offsets.h>
+#include <asm/exception-64s.h>
+
+/*****************************************************************************
+ *                                                                           *
+ *        Real Mode handlers that need to be in low physical memory          *
+ *                                                                           *
+ ****************************************************************************/
+
+
+.macro INTERRUPT_TRAMPOLINE intno
+
+.global kvmppc_trampoline_\intno
+kvmppc_trampoline_\intno:
+
+	mtspr	SPRN_SPRG_SCRATCH0, r13		/* Save r13 */
+
+	/*
+	 * First thing to do is to find out if we're coming
+	 * from a KVM guest or a Linux process.
+	 *
+	 * To distinguish, we check a magic byte in the PACA
+	 */
+	mfspr	r13, SPRN_SPRG_PACA		/* r13 = PACA */
+	std	r12, (PACA_EXMC + EX_R12)(r13)
+	mfcr	r12
+	stw	r12, (PACA_EXMC + EX_CCR)(r13)
+	lbz	r12, PACA_KVM_IN_GUEST(r13)
+	cmpwi	r12, 0
+	bne	..kvmppc_handler_hasmagic_\intno
+	/* No KVM guest? Then jump back to the Linux handler! */
+	lwz	r12, (PACA_EXMC + EX_CCR)(r13)
+	mtcr	r12
+	ld	r12, (PACA_EXMC + EX_R12)(r13)
+	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
+	b	kvmppc_resume_\intno		/* Get back original handler */
+
+	/* Now we know we're handling a KVM guest */
+..kvmppc_handler_hasmagic_\intno:
+	/* Unset guest state */
+	li	r12, 0
+	stb	r12, PACA_KVM_IN_GUEST(r13)
+
+	std	r1, (PACA_EXMC+EX_R9)(r13)
+	std	r10, (PACA_EXMC+EX_R10)(r13)
+	std	r11, (PACA_EXMC+EX_R11)(r13)
+	std	r2, (PACA_EXMC+EX_R13)(r13)
+
+	mfsrr0	r10
+	mfsrr1	r11
+
+	/* Restore R1/R2 so we can handle faults */
+	ld	r1, PACAR1(r13)
+	ld	r2, (PACA_EXMC+EX_SRR0)(r13)
+
+	/* Let's store which interrupt we're handling */
+	li	r12, \intno
+
+	/* Jump into the SLB exit code that goes to the highmem handler */
+	b	kvmppc_handler_trampoline_exit
+
+.endm
+
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_SYSTEM_RESET
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_MACHINE_CHECK
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DATA_STORAGE
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DATA_SEGMENT
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_INST_STORAGE
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_INST_SEGMENT
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALIGNMENT
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PROGRAM
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_FP_UNAVAIL
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DECREMENTER
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_SYSCALL
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_TRACE
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PERFMON
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALTIVEC
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_VSX
+
+/*
+ * This trampoline brings us back to a real mode handler
+ *
+ * Input Registers:
+ *
+ * R6 = SRR0
+ * R7 = SRR1
+ * LR = real-mode IP
+ *
+ */
+.global kvmppc_handler_lowmem_trampoline
+kvmppc_handler_lowmem_trampoline:
+
+	mtsrr0	r6
+	mtsrr1	r7
+	blr
+kvmppc_handler_lowmem_trampoline_end:
+
+.global kvmppc_trampoline_lowmem
+kvmppc_trampoline_lowmem:
+	.long kvmppc_handler_lowmem_trampoline - _stext
+
+.global kvmppc_trampoline_enter
+kvmppc_trampoline_enter:
+	.long kvmppc_handler_trampoline_enter - _stext
+
+#include "book3s_64_slb.S"
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_slb.S linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_slb.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s_64_slb.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s_64_slb.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,262 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright SUSE Linux Products GmbH 2009
+ *
+ * Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#define SHADOW_SLB_ESID(num)	(SLBSHADOW_SAVEAREA + (num * 0x10))
+#define SHADOW_SLB_VSID(num)	(SLBSHADOW_SAVEAREA + (num * 0x10) + 0x8)
+#define UNBOLT_SLB_ENTRY(num) \
+	ld	r9, SHADOW_SLB_ESID(num)(r12); \
+	/* Invalid? Skip. */; \
+	rldicl. r0, r9, 37, 63; \
+	beq	slb_entry_skip_ ## num; \
+	xoris	r9, r9, SLB_ESID_V@h; \
+	std	r9, SHADOW_SLB_ESID(num)(r12); \
+  slb_entry_skip_ ## num:
+
+#define REBOLT_SLB_ENTRY(num) \
+	ld	r10, SHADOW_SLB_ESID(num)(r11); \
+	cmpdi	r10, 0; \
+	beq	slb_exit_skip_1; \
+	oris	r10, r10, SLB_ESID_V@h; \
+	ld	r9, SHADOW_SLB_VSID(num)(r11); \
+	slbmte	r9, r10; \
+	std	r10, SHADOW_SLB_ESID(num)(r11); \
+slb_exit_skip_ ## num:
+
+/******************************************************************************
+ *                                                                            *
+ *                               Entry code                                   *
+ *                                                                            *
+ *****************************************************************************/
+
+.global kvmppc_handler_trampoline_enter
+kvmppc_handler_trampoline_enter:
+
+	/* Required state:
+	 *
+	 * MSR = ~IR|DR
+	 * R13 = PACA
+	 * R9 = guest IP
+	 * R10 = guest MSR
+	 * R11 = free
+	 * R12 = free
+	 * PACA[PACA_EXMC + EX_R9] = guest R9
+	 * PACA[PACA_EXMC + EX_R10] = guest R10
+	 * PACA[PACA_EXMC + EX_R11] = guest R11
+	 * PACA[PACA_EXMC + EX_R12] = guest R12
+	 * PACA[PACA_EXMC + EX_R13] = guest R13
+	 * PACA[PACA_EXMC + EX_CCR] = guest CR
+	 * PACA[PACA_EXMC + EX_R3] = guest XER
+	 */
+
+	mtsrr0	r9
+	mtsrr1	r10
+
+	mtspr	SPRN_SPRG_SCRATCH0, r0
+
+	/* Remove LPAR shadow entries */
+
+#if SLB_NUM_BOLTED == 3
+
+	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)
+	UNBOLT_SLB_ENTRY(2)
+	
+#else
+#error unknown number of bolted entries
+#endif
+
+	/* Flush SLB */
+
+	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
+
+	isync
+
+	/* Fill SLB with our shadow */
+
+	lbz	r12, PACA_KVM_SLB_MAX(r13)
+	mulli	r12, r12, 16
+	addi	r12, r12, PACA_KVM_SLB
+	add	r12, r12, r13
+
+	/* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
+	li	r11, PACA_KVM_SLB
+	add	r11, r11, r13
+
+slb_loop_enter:
+
+	ld	r10, 0(r11)
+
+	rldicl. r0, r10, 37, 63
+	beq	slb_loop_enter_skip
+
+	ld	r9, 8(r11)
+	slbmte	r9, r10
+
+slb_loop_enter_skip:
+	addi	r11, r11, 16
+	cmpd	cr0, r11, r12
+	blt	slb_loop_enter
+
+slb_do_enter:
+
+	/* Enter guest */
+
+	mfspr	r0, SPRN_SPRG_SCRATCH0
+
+	ld	r9, (PACA_EXMC+EX_R9)(r13)
+	ld	r10, (PACA_EXMC+EX_R10)(r13)
+	ld	r12, (PACA_EXMC+EX_R12)(r13)
+
+	lwz	r11, (PACA_EXMC+EX_CCR)(r13)
+	mtcr	r11
+
+	ld	r11, (PACA_EXMC+EX_R3)(r13)
+	mtxer	r11
+
+	ld	r11, (PACA_EXMC+EX_R11)(r13)
+	ld	r13, (PACA_EXMC+EX_R13)(r13)
+
+	RFI
+kvmppc_handler_trampoline_enter_end:
+
+
+
+/******************************************************************************
+ *                                                                            *
+ *                               Exit code                                    *
+ *                                                                            *
+ *****************************************************************************/
+
+.global kvmppc_handler_trampoline_exit
+kvmppc_handler_trampoline_exit:
+
+	/* Register usage at this point:
+	 *
+	 * SPRG_SCRATCH0 = guest R13
+	 * R01           = host R1
+	 * R02           = host R2
+	 * R10           = guest PC
+	 * R11           = guest MSR
+	 * R12           = exit handler id
+	 * R13           = PACA
+	 * PACA.exmc.CCR  = guest CR
+	 * PACA.exmc.R9  = guest R1
+	 * PACA.exmc.R10 = guest R10
+	 * PACA.exmc.R11 = guest R11
+	 * PACA.exmc.R12 = guest R12
+	 * PACA.exmc.R13 = guest R2
+	 *
+	 */
+
+	/* Save registers */
+
+	std	r0, (PACA_EXMC+EX_SRR0)(r13)
+	std	r9, (PACA_EXMC+EX_R3)(r13)
+	std	r10, (PACA_EXMC+EX_LR)(r13)
+	std	r11, (PACA_EXMC+EX_DAR)(r13)
+
+	/*
+	 * In order for us to easily get the last instruction,
+	 * we got the #vmexit at, we exploit the fact that the
+	 * virtual layout is still the same here, so we can just
+	 * ld from the guest's PC address
+	 */
+
+	/* We only load the last instruction when it's safe */
+	cmpwi	r12, BOOK3S_INTERRUPT_DATA_STORAGE
+	beq	ld_last_inst
+	cmpwi	r12, BOOK3S_INTERRUPT_PROGRAM
+	beq	ld_last_inst
+
+	b	no_ld_last_inst
+
+ld_last_inst:
+	/* Save off the guest instruction we're at */
+	/*    1) enable paging for data */
+	mfmsr	r9
+	ori	r11, r9, MSR_DR			/* Enable paging for data */
+	mtmsr	r11
+	/*    2) fetch the instruction */
+	lwz	r0, 0(r10)
+	/*    3) disable paging again */
+	mtmsr	r9
+
+no_ld_last_inst:
+
+	/* Restore bolted entries from the shadow and fix it along the way */
+
+	/* We don't store anything in entry 0, so we don't need to take care of it */
+	slbia
+	isync
+
+#if SLB_NUM_BOLTED == 3
+
+	ld	r11, PACA_SLBSHADOWPTR(r13)
+
+	REBOLT_SLB_ENTRY(0)
+	REBOLT_SLB_ENTRY(1)
+	REBOLT_SLB_ENTRY(2)
+	
+#else
+#error unknown number of bolted entries
+#endif
+
+slb_do_exit:
+
+	/* Restore registers */
+
+	ld	r11, (PACA_EXMC+EX_DAR)(r13)
+	ld	r10, (PACA_EXMC+EX_LR)(r13)
+	ld	r9, (PACA_EXMC+EX_R3)(r13)
+
+	/* Save last inst */
+	stw	r0, (PACA_EXMC+EX_LR)(r13)
+
+	/* Save DAR and DSISR before going to paged mode */
+	mfdar	r0
+	std	r0, (PACA_EXMC+EX_DAR)(r13)
+	mfdsisr	r0
+	stw	r0, (PACA_EXMC+EX_DSISR)(r13)
+
+	/* RFI into the highmem handler */
+	mfmsr	r0
+	ori	r0, r0, MSR_IR|MSR_DR|MSR_RI	/* Enable paging */
+	mtsrr1	r0
+	ld	r0, PACASAVEDMSR(r13)		/* Highmem handler address */
+	mtsrr0	r0
+
+	mfspr	r0, SPRN_SPRG_SCRATCH0
+
+	RFI
+kvmppc_handler_trampoline_exit_end:
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/book3s.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/book3s.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,974 @@
+/*
+ * Copyright (C) 2009. SUSE Linux Products GmbH. All rights reserved.
+ *
+ * Authors:
+ *    Alexander Graf <agraf@suse.de>
+ *    Kevin Wolf <mail@kevin-wolf.de>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x.c,
+ * by Hollis Blanchard <hollisb@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, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/err.h>
+
+#include <asm/reg.h>
+#include <asm/cputable.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s.h>
+#include <asm/mmu_context.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+
+#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+
+/* #define EXIT_DEBUG */
+/* #define EXIT_DEBUG_SIMPLE */
+
+/* Without AGGRESSIVE_DEC we only fire off a DEC interrupt when DEC turns 0.
+ * When set, we retrigger a DEC interrupt after that if DEC <= 0.
+ * PPC32 Linux runs faster without AGGRESSIVE_DEC, PPC64 Linux requires it. */
+
+/* #define AGGRESSIVE_DEC */
+
+struct kvm_stats_debugfs_item debugfs_entries[] = {
+	{ "exits",       VCPU_STAT(sum_exits) },
+	{ "mmio",        VCPU_STAT(mmio_exits) },
+	{ "sig",         VCPU_STAT(signal_exits) },
+	{ "sysc",        VCPU_STAT(syscall_exits) },
+	{ "inst_emu",    VCPU_STAT(emulated_inst_exits) },
+	{ "dec",         VCPU_STAT(dec_exits) },
+	{ "ext_intr",    VCPU_STAT(ext_intr_exits) },
+	{ "queue_intr",  VCPU_STAT(queue_intr) },
+	{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
+	{ "pf_storage",  VCPU_STAT(pf_storage) },
+	{ "sp_storage",  VCPU_STAT(sp_storage) },
+	{ "pf_instruc",  VCPU_STAT(pf_instruc) },
+	{ "sp_instruc",  VCPU_STAT(sp_instruc) },
+	{ "ld",          VCPU_STAT(ld) },
+	{ "ld_slow",     VCPU_STAT(ld_slow) },
+	{ "st",          VCPU_STAT(st) },
+	{ "st_slow",     VCPU_STAT(st_slow) },
+	{ NULL }
+};
+
+void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+	memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb));
+	get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max;
+}
+
+void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
+{
+	memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb));
+	to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max;
+}
+
+#if defined(AGGRESSIVE_DEC) || defined(EXIT_DEBUG)
+static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
+{
+	u64 jd = mftb() - vcpu->arch.dec_jiffies;
+	return vcpu->arch.dec - jd;
+}
+#endif
+
+void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
+{
+	ulong old_msr = vcpu->arch.msr;
+
+#ifdef EXIT_DEBUG
+	printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
+#endif
+	msr &= to_book3s(vcpu)->msr_mask;
+	vcpu->arch.msr = msr;
+	vcpu->arch.shadow_msr = msr | MSR_USER32;
+	vcpu->arch.shadow_msr &= ( MSR_VEC | MSR_VSX | MSR_FP | MSR_FE0 |
+				   MSR_USER64 | MSR_SE | MSR_BE | MSR_DE |
+				   MSR_FE1);
+
+	if (msr & (MSR_WE|MSR_POW)) {
+		if (!vcpu->arch.pending_exceptions) {
+			kvm_vcpu_block(vcpu);
+			vcpu->stat.halt_wakeup++;
+		}
+	}
+
+	if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) ||
+	    (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) {
+		kvmppc_mmu_flush_segments(vcpu);
+		kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc);
+	}
+}
+
+void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
+{
+	vcpu->arch.srr0 = vcpu->arch.pc;
+	vcpu->arch.srr1 = vcpu->arch.msr | flags;
+	vcpu->arch.pc = to_book3s(vcpu)->hior + vec;
+	vcpu->arch.mmu.reset_msr(vcpu);
+}
+
+void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+{
+	unsigned int prio;
+
+	vcpu->stat.queue_intr++;
+	switch (vec) {
+	case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET;		break;
+	case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK;	break;
+	case 0x300: prio = BOOK3S_IRQPRIO_DATA_STORAGE;		break;
+	case 0x380: prio = BOOK3S_IRQPRIO_DATA_SEGMENT;		break;
+	case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE;		break;
+	case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT;		break;
+	case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL;		break;
+	case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT;		break;
+	case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM;		break;
+	case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL;		break;
+	case 0x900: prio = BOOK3S_IRQPRIO_DECREMENTER;		break;
+	case 0xc00: prio = BOOK3S_IRQPRIO_SYSCALL;		break;
+	case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG;		break;
+	case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC;		break;
+	case 0xf40: prio = BOOK3S_IRQPRIO_VSX;			break;
+	default:    prio = BOOK3S_IRQPRIO_MAX;			break;
+	}
+
+	set_bit(prio, &vcpu->arch.pending_exceptions);
+#ifdef EXIT_DEBUG
+	printk(KERN_INFO "Queueing interrupt %x\n", vec);
+#endif
+}
+
+
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+{
+	kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
+}
+
+void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
+{
+	kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
+}
+
+int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
+{
+	return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
+                                struct kvm_interrupt *irq)
+{
+	kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
+}
+
+int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
+{
+	int deliver = 1;
+	int vec = 0;
+
+	switch (priority) {
+	case BOOK3S_IRQPRIO_DECREMENTER:
+		deliver = vcpu->arch.msr & MSR_EE;
+		vec = BOOK3S_INTERRUPT_DECREMENTER;
+		break;
+	case BOOK3S_IRQPRIO_EXTERNAL:
+		deliver = vcpu->arch.msr & MSR_EE;
+		vec = BOOK3S_INTERRUPT_EXTERNAL;
+		break;
+	case BOOK3S_IRQPRIO_SYSTEM_RESET:
+		vec = BOOK3S_INTERRUPT_SYSTEM_RESET;
+		break;
+	case BOOK3S_IRQPRIO_MACHINE_CHECK:
+		vec = BOOK3S_INTERRUPT_MACHINE_CHECK;
+		break;
+	case BOOK3S_IRQPRIO_DATA_STORAGE:
+		vec = BOOK3S_INTERRUPT_DATA_STORAGE;
+		break;
+	case BOOK3S_IRQPRIO_INST_STORAGE:
+		vec = BOOK3S_INTERRUPT_INST_STORAGE;
+		break;
+	case BOOK3S_IRQPRIO_DATA_SEGMENT:
+		vec = BOOK3S_INTERRUPT_DATA_SEGMENT;
+		break;
+	case BOOK3S_IRQPRIO_INST_SEGMENT:
+		vec = BOOK3S_INTERRUPT_INST_SEGMENT;
+		break;
+	case BOOK3S_IRQPRIO_ALIGNMENT:
+		vec = BOOK3S_INTERRUPT_ALIGNMENT;
+		break;
+	case BOOK3S_IRQPRIO_PROGRAM:
+		vec = BOOK3S_INTERRUPT_PROGRAM;
+		break;
+	case BOOK3S_IRQPRIO_VSX:
+		vec = BOOK3S_INTERRUPT_VSX;
+		break;
+	case BOOK3S_IRQPRIO_ALTIVEC:
+		vec = BOOK3S_INTERRUPT_ALTIVEC;
+		break;
+	case BOOK3S_IRQPRIO_FP_UNAVAIL:
+		vec = BOOK3S_INTERRUPT_FP_UNAVAIL;
+		break;
+	case BOOK3S_IRQPRIO_SYSCALL:
+		vec = BOOK3S_INTERRUPT_SYSCALL;
+		break;
+	case BOOK3S_IRQPRIO_DEBUG:
+		vec = BOOK3S_INTERRUPT_TRACE;
+		break;
+	case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR:
+		vec = BOOK3S_INTERRUPT_PERFMON;
+		break;
+	default:
+		deliver = 0;
+		printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);
+		break;
+	}
+
+#if 0
+	printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver);
+#endif
+
+	if (deliver)
+		kvmppc_inject_interrupt(vcpu, vec, 0ULL);
+
+	return deliver;
+}
+
+void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
+{
+	unsigned long *pending = &vcpu->arch.pending_exceptions;
+	unsigned int priority;
+
+	/* XXX be more clever here - no need to mftb() on every entry */
+	/* Issue DEC again if it's still active */
+#ifdef AGGRESSIVE_DEC
+	if (vcpu->arch.msr & MSR_EE)
+		if (kvmppc_get_dec(vcpu) & 0x80000000)
+			kvmppc_core_queue_dec(vcpu);
+#endif
+
+#ifdef EXIT_DEBUG
+	if (vcpu->arch.pending_exceptions)
+		printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
+#endif
+	priority = __ffs(*pending);
+	while (priority <= (sizeof(unsigned int) * 8)) {
+		if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) {
+			clear_bit(priority, &vcpu->arch.pending_exceptions);
+			break;
+		}
+
+		priority = find_next_bit(pending,
+					 BITS_PER_BYTE * sizeof(*pending),
+					 priority + 1);
+	}
+}
+
+void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
+{
+	vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB;
+	vcpu->arch.pvr = pvr;
+	if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
+		kvmppc_mmu_book3s_64_init(vcpu);
+		to_book3s(vcpu)->hior = 0xfff00000;
+		to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL;
+	} else {
+		kvmppc_mmu_book3s_32_init(vcpu);
+		to_book3s(vcpu)->hior = 0;
+		to_book3s(vcpu)->msr_mask = 0xffffffffULL;
+	}
+
+	/* If we are in hypervisor level on 970, we can tell the CPU to
+	 * treat DCBZ as 32 bytes store */
+	vcpu->arch.hflags &= ~BOOK3S_HFLAG_DCBZ32;
+	if (vcpu->arch.mmu.is_dcbz32(vcpu) && (mfmsr() & MSR_HV) &&
+	    !strcmp(cur_cpu_spec->platform, "ppc970"))
+		vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
+
+}
+
+/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
+ * make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to
+ * emulate 32 bytes dcbz length.
+ *
+ * The Book3s_64 inventors also realized this case and implemented a special bit
+ * in the HID5 register, which is a hypervisor ressource. Thus we can't use it.
+ *
+ * My approach here is to patch the dcbz instruction on executing pages.
+ */
+static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
+{
+	bool touched = false;
+	hva_t hpage;
+	u32 *page;
+	int i;
+
+	hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
+	if (kvm_is_error_hva(hpage))
+		return;
+
+	hpage |= pte->raddr & ~PAGE_MASK;
+	hpage &= ~0xFFFULL;
+
+	page = vmalloc(HW_PAGE_SIZE);
+
+	if (copy_from_user(page, (void __user *)hpage, HW_PAGE_SIZE))
+		goto out;
+
+	for (i=0; i < HW_PAGE_SIZE / 4; i++)
+		if ((page[i] & 0xff0007ff) == INS_DCBZ) {
+			page[i] &= 0xfffffff7; // reserved instruction, so we trap
+			touched = true;
+		}
+
+	if (touched)
+		copy_to_user((void __user *)hpage, page, HW_PAGE_SIZE);
+
+out:
+	vfree(page);
+}
+
+static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data,
+			 struct kvmppc_pte *pte)
+{
+	int relocated = (vcpu->arch.msr & (data ? MSR_DR : MSR_IR));
+	int r;
+
+	if (relocated) {
+		r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data);
+	} else {
+		pte->eaddr = eaddr;
+		pte->raddr = eaddr & 0xffffffff;
+		pte->vpage = eaddr >> 12;
+		switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+		case 0:
+			pte->vpage |= VSID_REAL;
+		case MSR_DR:
+			pte->vpage |= VSID_REAL_DR;
+		case MSR_IR:
+			pte->vpage |= VSID_REAL_IR;
+		}
+		pte->may_read = true;
+		pte->may_write = true;
+		pte->may_execute = true;
+		r = 0;
+	}
+
+	return r;
+}
+
+static hva_t kvmppc_bad_hva(void)
+{
+	return PAGE_OFFSET;
+}
+
+static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte,
+			       bool read)
+{
+	hva_t hpage;
+
+	if (read && !pte->may_read)
+		goto err;
+
+	if (!read && !pte->may_write)
+		goto err;
+
+	hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
+	if (kvm_is_error_hva(hpage))
+		goto err;
+
+	return hpage | (pte->raddr & ~PAGE_MASK);
+err:
+	return kvmppc_bad_hva();
+}
+
+int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr)
+{
+	struct kvmppc_pte pte;
+	hva_t hva = eaddr;
+
+	vcpu->stat.st++;
+
+	if (kvmppc_xlate(vcpu, eaddr, false, &pte))
+		goto err;
+
+	hva = kvmppc_pte_to_hva(vcpu, &pte, false);
+	if (kvm_is_error_hva(hva))
+		goto err;
+
+	if (copy_to_user((void __user *)hva, ptr, size)) {
+		printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	return -ENOENT;
+}
+
+int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr,
+		      bool data)
+{
+	struct kvmppc_pte pte;
+	hva_t hva = eaddr;
+
+	vcpu->stat.ld++;
+
+	if (kvmppc_xlate(vcpu, eaddr, data, &pte))
+		goto err;
+
+	hva = kvmppc_pte_to_hva(vcpu, &pte, true);
+	if (kvm_is_error_hva(hva))
+		goto err;
+
+	if (copy_from_user(ptr, (void __user *)hva, size)) {
+		printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	return -ENOENT;
+}
+
+static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+	return kvm_is_visible_gfn(vcpu->kvm, gfn);
+}
+
+int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
+			    ulong eaddr, int vec)
+{
+	bool data = (vec == BOOK3S_INTERRUPT_DATA_STORAGE);
+	int r = RESUME_GUEST;
+	int relocated;
+	int page_found = 0;
+	struct kvmppc_pte pte;
+	bool is_mmio = false;
+
+	if ( vec == BOOK3S_INTERRUPT_DATA_STORAGE ) {
+		relocated = (vcpu->arch.msr & MSR_DR);
+	} else {
+		relocated = (vcpu->arch.msr & MSR_IR);
+	}
+
+	/* Resolve real address if translation turned on */
+	if (relocated) {
+		page_found = vcpu->arch.mmu.xlate(vcpu, eaddr, &pte, data);
+	} else {
+		pte.may_execute = true;
+		pte.may_read = true;
+		pte.may_write = true;
+		pte.raddr = eaddr & 0xffffffff;
+		pte.eaddr = eaddr;
+		pte.vpage = eaddr >> 12;
+		switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) {
+		case 0:
+			pte.vpage |= VSID_REAL;
+		case MSR_DR:
+			pte.vpage |= VSID_REAL_DR;
+		case MSR_IR:
+			pte.vpage |= VSID_REAL_IR;
+		}
+	}
+
+	if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
+	   (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
+		/*
+		 * If we do the dcbz hack, we have to NX on every execution,
+		 * so we can patch the executing code. This renders our guest
+		 * NX-less.
+		 */
+		pte.may_execute = !data;
+	}
+
+	if (page_found == -ENOENT) {
+		/* Page not found in guest PTE entries */
+		vcpu->arch.dear = vcpu->arch.fault_dear;
+		to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
+		vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+		kvmppc_book3s_queue_irqprio(vcpu, vec);
+	} else if (page_found == -EPERM) {
+		/* Storage protection */
+		vcpu->arch.dear = vcpu->arch.fault_dear;
+		to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
+		to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
+		vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+		kvmppc_book3s_queue_irqprio(vcpu, vec);
+	} else if (page_found == -EINVAL) {
+		/* Page not found in guest SLB */
+		vcpu->arch.dear = vcpu->arch.fault_dear;
+		kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80);
+	} else if (!is_mmio &&
+		   kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) {
+		/* The guest's PTE is not mapped yet. Map on the host */
+		kvmppc_mmu_map_page(vcpu, &pte);
+		if (data)
+			vcpu->stat.sp_storage++;
+		else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
+			(!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32)))
+			kvmppc_patch_dcbz(vcpu, &pte);
+	} else {
+		/* MMIO */
+		vcpu->stat.mmio_exits++;
+		vcpu->arch.paddr_accessed = pte.raddr;
+		r = kvmppc_emulate_mmio(run, vcpu);
+		if ( r == RESUME_HOST_NV )
+			r = RESUME_HOST;
+		if ( r == RESUME_GUEST_NV )
+			r = RESUME_GUEST;
+	}
+
+	return r;
+}
+
+int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                       unsigned int exit_nr)
+{
+	int r = RESUME_HOST;
+
+	vcpu->stat.sum_exits++;
+
+	run->exit_reason = KVM_EXIT_UNKNOWN;
+	run->ready_for_interrupt_injection = 1;
+#ifdef EXIT_DEBUG
+	printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | dec=0x%x | msr=0x%lx\n",
+		exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear,
+		kvmppc_get_dec(vcpu), vcpu->arch.msr);
+#elif defined (EXIT_DEBUG_SIMPLE)
+	if ((exit_nr != 0x900) && (exit_nr != 0x500))
+		printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | dar=0x%lx | msr=0x%lx\n",
+			exit_nr, vcpu->arch.pc, vcpu->arch.fault_dear,
+			vcpu->arch.msr);
+#endif
+	kvm_resched(vcpu);
+	switch (exit_nr) {
+	case BOOK3S_INTERRUPT_INST_STORAGE:
+		vcpu->stat.pf_instruc++;
+		/* only care about PTEG not found errors, but leave NX alone */
+		if (vcpu->arch.shadow_msr & 0x40000000) {
+			r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
+			vcpu->stat.sp_instruc++;
+		} else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
+			  (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
+			/*
+			 * XXX If we do the dcbz hack we use the NX bit to flush&patch the page,
+			 *     so we can't use the NX bit inside the guest. Let's cross our fingers,
+			 *     that no guest that needs the dcbz hack does NX.
+			 */
+			kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
+		} else {
+			vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
+			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+			kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
+			r = RESUME_GUEST;
+		}
+		break;
+	case BOOK3S_INTERRUPT_DATA_STORAGE:
+		vcpu->stat.pf_storage++;
+		/* The only case we need to handle is missing shadow PTEs */
+		if (vcpu->arch.fault_dsisr & DSISR_NOHPTE) {
+			r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.fault_dear, exit_nr);
+		} else {
+			vcpu->arch.dear = vcpu->arch.fault_dear;
+			to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
+			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+			kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFULL);
+			r = RESUME_GUEST;
+		}
+		break;
+	case BOOK3S_INTERRUPT_DATA_SEGMENT:
+		if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.fault_dear) < 0) {
+			vcpu->arch.dear = vcpu->arch.fault_dear;
+			kvmppc_book3s_queue_irqprio(vcpu,
+				BOOK3S_INTERRUPT_DATA_SEGMENT);
+		}
+		r = RESUME_GUEST;
+		break;
+	case BOOK3S_INTERRUPT_INST_SEGMENT:
+		if (kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc) < 0) {
+			kvmppc_book3s_queue_irqprio(vcpu,
+				BOOK3S_INTERRUPT_INST_SEGMENT);
+		}
+		r = RESUME_GUEST;
+		break;
+	/* We're good on these - the host merely wanted to get our attention */
+	case BOOK3S_INTERRUPT_DECREMENTER:
+		vcpu->stat.dec_exits++;
+		r = RESUME_GUEST;
+		break;
+	case BOOK3S_INTERRUPT_EXTERNAL:
+		vcpu->stat.ext_intr_exits++;
+		r = RESUME_GUEST;
+		break;
+	case BOOK3S_INTERRUPT_PROGRAM:
+	{
+		enum emulation_result er;
+
+		if (vcpu->arch.msr & MSR_PR) {
+#ifdef EXIT_DEBUG
+			printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", vcpu->arch.pc, vcpu->arch.last_inst);
+#endif
+			if ((vcpu->arch.last_inst & 0xff0007ff) !=
+			    (INS_DCBZ & 0xfffffff7)) {
+				kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+				r = RESUME_GUEST;
+				break;
+			}
+		}
+
+		vcpu->stat.emulated_inst_exits++;
+		er = kvmppc_emulate_instruction(run, vcpu);
+		switch (er) {
+		case EMULATE_DONE:
+			r = RESUME_GUEST;
+			break;
+		case EMULATE_FAIL:
+			printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
+			       __func__, vcpu->arch.pc, vcpu->arch.last_inst);
+			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+			r = RESUME_GUEST;
+			break;
+		default:
+			BUG();
+		}
+		break;
+	}
+	case BOOK3S_INTERRUPT_SYSCALL:
+#ifdef EXIT_DEBUG
+		printk(KERN_INFO "Syscall Nr %d\n", (int)vcpu->arch.gpr[0]);
+#endif
+		vcpu->stat.syscall_exits++;
+		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+		r = RESUME_GUEST;
+		break;
+	case BOOK3S_INTERRUPT_MACHINE_CHECK:
+	case BOOK3S_INTERRUPT_FP_UNAVAIL:
+	case BOOK3S_INTERRUPT_TRACE:
+	case BOOK3S_INTERRUPT_ALTIVEC:
+	case BOOK3S_INTERRUPT_VSX:
+		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+		r = RESUME_GUEST;
+		break;
+	default:
+		/* Ugh - bork here! What did we get? */
+		printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
+		r = RESUME_HOST;
+		BUG();
+		break;
+	}
+
+
+	if (!(r & RESUME_HOST)) {
+		/* To avoid clobbering exit_reason, only check for signals if
+		 * we aren't already exiting to userspace for some other
+		 * reason. */
+		if (signal_pending(current)) {
+#ifdef EXIT_DEBUG
+			printk(KERN_EMERG "KVM: Going back to host\n");
+#endif
+			vcpu->stat.signal_exits++;
+			run->exit_reason = KVM_EXIT_INTR;
+			r = -EINTR;
+		} else {
+			/* In case an interrupt came in that was triggered
+			 * from userspace (like DEC), we need to check what
+			 * to inject now! */
+			kvmppc_core_deliver_interrupts(vcpu);
+		}
+	}
+
+#ifdef EXIT_DEBUG
+	printk(KERN_EMERG "KVM exit: vcpu=0x%p pc=0x%lx r=0x%x\n", vcpu, vcpu->arch.pc, r);
+#endif
+
+	return r;
+}
+
+int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	int i;
+
+	regs->pc = vcpu->arch.pc;
+	regs->cr = vcpu->arch.cr;
+	regs->ctr = vcpu->arch.ctr;
+	regs->lr = vcpu->arch.lr;
+	regs->xer = vcpu->arch.xer;
+	regs->msr = vcpu->arch.msr;
+	regs->srr0 = vcpu->arch.srr0;
+	regs->srr1 = vcpu->arch.srr1;
+	regs->pid = vcpu->arch.pid;
+	regs->sprg0 = vcpu->arch.sprg0;
+	regs->sprg1 = vcpu->arch.sprg1;
+	regs->sprg2 = vcpu->arch.sprg2;
+	regs->sprg3 = vcpu->arch.sprg3;
+	regs->sprg5 = vcpu->arch.sprg4;
+	regs->sprg6 = vcpu->arch.sprg5;
+	regs->sprg7 = vcpu->arch.sprg6;
+
+	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+		regs->gpr[i] = vcpu->arch.gpr[i];
+
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	int i;
+
+	vcpu->arch.pc = regs->pc;
+	vcpu->arch.cr = regs->cr;
+	vcpu->arch.ctr = regs->ctr;
+	vcpu->arch.lr = regs->lr;
+	vcpu->arch.xer = regs->xer;
+	kvmppc_set_msr(vcpu, regs->msr);
+	vcpu->arch.srr0 = regs->srr0;
+	vcpu->arch.srr1 = regs->srr1;
+	vcpu->arch.sprg0 = regs->sprg0;
+	vcpu->arch.sprg1 = regs->sprg1;
+	vcpu->arch.sprg2 = regs->sprg2;
+	vcpu->arch.sprg3 = regs->sprg3;
+	vcpu->arch.sprg5 = regs->sprg4;
+	vcpu->arch.sprg6 = regs->sprg5;
+	vcpu->arch.sprg7 = regs->sprg6;
+
+	for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
+		vcpu->arch.gpr[i] = regs->gpr[i];
+
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+                                  struct kvm_sregs *sregs)
+{
+	struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
+	int i;
+
+	sregs->pvr = vcpu->arch.pvr;
+
+	sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			sregs->u.s.ppc64.slb[i].slbe = vcpu3s->slb[i].orige | i;
+			sregs->u.s.ppc64.slb[i].slbv = vcpu3s->slb[i].origv;
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
+			sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
+		}
+		for (i = 0; i < 8; i++) {
+			sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw;
+			sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw;
+		}
+	}
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+                                  struct kvm_sregs *sregs)
+{
+	struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
+	int i;
+
+	kvmppc_set_pvr(vcpu, sregs->pvr);
+
+	vcpu3s->sdr1 = sregs->u.s.sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			vcpu->arch.mmu.slbmte(vcpu, sregs->u.s.ppc64.slb[i].slbv,
+						    sregs->u.s.ppc64.slb[i].slbe);
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			vcpu->arch.mmu.mtsrin(vcpu, i, sregs->u.s.ppc32.sr[i]);
+		}
+		for (i = 0; i < 8; i++) {
+			kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), false,
+				       (u32)sregs->u.s.ppc32.ibat[i]);
+			kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), true,
+				       (u32)(sregs->u.s.ppc32.ibat[i] >> 32));
+			kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), false,
+				       (u32)sregs->u.s.ppc32.dbat[i]);
+			kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), true,
+				       (u32)(sregs->u.s.ppc32.dbat[i] >> 32));
+		}
+	}
+
+	/* Flush the MMU after messing with the segments */
+	kvmppc_mmu_pte_flush(vcpu, 0, 0);
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+	return -ENOTSUPP;
+}
+
+int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+	return -ENOTSUPP;
+}
+
+int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
+                                  struct kvm_translation *tr)
+{
+	return 0;
+}
+
+/*
+ * Get (and clear) the dirty memory log for a memory slot.
+ */
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
+				      struct kvm_dirty_log *log)
+{
+	struct kvm_memory_slot *memslot;
+	struct kvm_vcpu *vcpu;
+	ulong ga, ga_end;
+	int is_dirty = 0;
+	int r, n;
+
+	down_write(&kvm->slots_lock);
+
+	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	if (r)
+		goto out;
+
+	/* If nothing is dirty, don't bother messing with page tables. */
+	if (is_dirty) {
+		memslot = &kvm->memslots[log->slot];
+
+		ga = memslot->base_gfn << PAGE_SHIFT;
+		ga_end = ga + (memslot->npages << PAGE_SHIFT);
+
+		kvm_for_each_vcpu(n, vcpu, kvm)
+			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
+
+		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+		memset(memslot->dirty_bitmap, 0, n);
+	}
+
+	r = 0;
+out:
+	up_write(&kvm->slots_lock);
+	return r;
+}
+
+int kvmppc_core_check_processor_compat(void)
+{
+	return 0;
+}
+
+struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s;
+	struct kvm_vcpu *vcpu;
+	int err;
+
+	vcpu_book3s = (struct kvmppc_vcpu_book3s *)__get_free_pages( GFP_KERNEL | __GFP_ZERO,
+			get_order(sizeof(struct kvmppc_vcpu_book3s)));
+	if (!vcpu_book3s) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	vcpu = &vcpu_book3s->vcpu;
+	err = kvm_vcpu_init(vcpu, kvm, id);
+	if (err)
+		goto free_vcpu;
+
+	vcpu->arch.host_retip = kvm_return_point;
+	vcpu->arch.host_msr = mfmsr();
+	/* default to book3s_64 (970fx) */
+	vcpu->arch.pvr = 0x3C0301;
+	kvmppc_set_pvr(vcpu, vcpu->arch.pvr);
+	vcpu_book3s->slb_nr = 64;
+
+	/* remember where some real-mode handlers are */
+	vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
+	vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
+	vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
+
+	vcpu->arch.shadow_msr = MSR_USER64;
+
+	err = __init_new_context();
+	if (err < 0)
+		goto free_vcpu;
+	vcpu_book3s->context_id = err;
+
+	vcpu_book3s->vsid_max = ((vcpu_book3s->context_id + 1) << USER_ESID_BITS) - 1;
+	vcpu_book3s->vsid_first = vcpu_book3s->context_id << USER_ESID_BITS;
+	vcpu_book3s->vsid_next = vcpu_book3s->vsid_first;
+
+	return vcpu;
+
+free_vcpu:
+	free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s)));
+out:
+	return ERR_PTR(err);
+}
+
+void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
+
+	__destroy_context(vcpu_book3s->context_id);
+	kvm_vcpu_uninit(vcpu);
+	free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s)));
+}
+
+extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
+int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+{
+	int ret;
+
+	/* No need to go into the guest when all we do is going out */
+	if (signal_pending(current)) {
+		kvm_run->exit_reason = KVM_EXIT_INTR;
+		return -EINTR;
+	}
+
+	/* XXX we get called with irq disabled - change that! */
+	local_irq_enable();
+
+	ret = __kvmppc_vcpu_entry(kvm_run, vcpu);
+
+	local_irq_disable();
+
+	return ret;
+}
+
+static int kvmppc_book3s_init(void)
+{
+	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), THIS_MODULE);
+}
+
+static void kvmppc_book3s_exit(void)
+{
+	kvm_exit();
+}
+
+module_init(kvmppc_book3s_init);
+module_exit(kvmppc_book3s_exit);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/booke.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/booke.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/booke.c	2010-02-24 13:52:17.000000000 -0500
@@ -520,6 +520,11 @@ int kvm_arch_vcpu_ioctl_translate(struct
 	return kvmppc_core_vcpu_translate(vcpu, tr);
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return -ENOTSUPP;
+}
+
 int __init kvmppc_booke_init(void)
 {
 	unsigned long ivor[16];
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/emulate.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/emulate.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/emulate.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/emulate.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
  */
 
 #include <linux/jiffies.h>
-#include <linux/timer.h>
+#include <linux/hrtimer.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kvm_host.h>
@@ -32,6 +32,7 @@
 #include "trace.h"
 
 #define OP_TRAP 3
+#define OP_TRAP_64 2
 
 #define OP_31_XOP_LWZX      23
 #define OP_31_XOP_LBZX      87
@@ -64,19 +65,45 @@
 #define OP_STH  44
 #define OP_STHU 45
 
+#ifdef CONFIG_PPC64
+static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
+{
+	return 1;
+}
+#else
+static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.tcr & TCR_DIE;
+}
+#endif
+
 void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
 {
-	if (vcpu->arch.tcr & TCR_DIE) {
+	unsigned long dec_nsec;
+
+	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
+#ifdef CONFIG_PPC64
+	/* POWER4+ triggers a dec interrupt if the value is < 0 */
+	if (vcpu->arch.dec & 0x80000000) {
+		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
+		kvmppc_core_queue_dec(vcpu);
+		return;
+	}
+#endif
+	if (kvmppc_dec_enabled(vcpu)) {
 		/* The decrementer ticks at the same rate as the timebase, so
 		 * that's how we convert the guest DEC value to the number of
 		 * host ticks. */
-		unsigned long nr_jiffies;
 
-		nr_jiffies = vcpu->arch.dec / tb_ticks_per_jiffy;
-		mod_timer(&vcpu->arch.dec_timer,
-		          get_jiffies_64() + nr_jiffies);
+		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
+		dec_nsec = vcpu->arch.dec;
+		dec_nsec *= 1000;
+		dec_nsec /= tb_ticks_per_usec;
+		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
+			      HRTIMER_MODE_REL);
+		vcpu->arch.dec_jiffies = get_tb();
 	} else {
-		del_timer(&vcpu->arch.dec_timer);
+		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
 	}
 }
 
@@ -111,9 +138,15 @@ int kvmppc_emulate_instruction(struct kv
 	/* this default type might be overwritten by subcategories */
 	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
 
+	pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
+
 	switch (get_op(inst)) {
 	case OP_TRAP:
+#ifdef CONFIG_PPC64
+	case OP_TRAP_64:
+#else
 		vcpu->arch.esr |= ESR_PTR;
+#endif
 		kvmppc_core_queue_program(vcpu);
 		advance = 0;
 		break;
@@ -188,17 +221,19 @@ int kvmppc_emulate_instruction(struct kv
 			case SPRN_SRR1:
 				vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
 			case SPRN_PVR:
-				vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break;
+				vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
 			case SPRN_PIR:
-				vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break;
+				vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
+			case SPRN_MSSSR0:
+				vcpu->arch.gpr[rt] = 0; break;
 
 			/* Note: mftb and TBRL/TBWL are user-accessible, so
 			 * the guest can always access the real TB anyways.
 			 * In fact, we probably will never see these traps. */
 			case SPRN_TBWL:
-				vcpu->arch.gpr[rt] = mftbl(); break;
+				vcpu->arch.gpr[rt] = get_tb() >> 32; break;
 			case SPRN_TBWU:
-				vcpu->arch.gpr[rt] = mftbu(); break;
+				vcpu->arch.gpr[rt] = get_tb(); break;
 
 			case SPRN_SPRG0:
 				vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
@@ -211,6 +246,13 @@ int kvmppc_emulate_instruction(struct kv
 			/* Note: SPRG4-7 are user-readable, so we don't get
 			 * a trap. */
 
+			case SPRN_DEC:
+			{
+				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
+				vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
+				pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
+				break;
+			}
 			default:
 				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
 				if (emulated == EMULATE_FAIL) {
@@ -260,6 +302,8 @@ int kvmppc_emulate_instruction(struct kv
 			case SPRN_TBWL: break;
 			case SPRN_TBWU: break;
 
+			case SPRN_MSSSR0: break;
+
 			case SPRN_DEC:
 				vcpu->arch.dec = vcpu->arch.gpr[rs];
 				kvmppc_emulate_dec(vcpu);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,23 @@ config KVM
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
 
+config KVM_BOOK3S_64_HANDLER
+	bool
+
+config KVM_BOOK3S_64
+	tristate "KVM support for PowerPC book3s_64 processors"
+	depends on EXPERIMENTAL && PPC64
+	select KVM
+	select KVM_BOOK3S_64_HANDLER
+	---help---
+	  Support running unmodified book3s_64 and book3s_32 guest kernels
+	  in virtual machines on book3s_64 host processors.
+
+	  This module provides access to the hardware capabilities through
+	  a character device node named /dev/kvm.
+
+	  If unsure, say N.
+
 config KVM_440
 	bool "KVM support for PowerPC 440 processors"
 	depends on EXPERIMENTAL && 44x
@@ -36,7 +53,7 @@ config KVM_440
 
 config KVM_EXIT_TIMING
 	bool "Detailed exit timing"
-	depends on KVM
+	depends on KVM_440 || KVM_E500
 	---help---
 	  Calculate elapsed time for every exit/enter cycle. A per-vcpu
 	  report is available in debugfs kvm/vm#_vcpu#_timing.
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -12,26 +12,45 @@ CFLAGS_44x_tlb.o  := -I.
 CFLAGS_e500_tlb.o := -I.
 CFLAGS_emulate.o  := -I.
 
-kvm-objs := $(common-objs-y) powerpc.o emulate.o
+common-objs-y += powerpc.o emulate.o
 obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o
-obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_KVM_BOOK3S_64_HANDLER) += book3s_64_exports.o
 
 AFLAGS_booke_interrupts.o := -I$(obj)
 
 kvm-440-objs := \
+	$(common-objs-y) \
 	booke.o \
 	booke_emulate.o \
 	booke_interrupts.o \
 	44x.o \
 	44x_tlb.o \
 	44x_emulate.o
-obj-$(CONFIG_KVM_440) += kvm-440.o
+kvm-objs-$(CONFIG_KVM_440) := $(kvm-440-objs)
 
 kvm-e500-objs := \
+	$(common-objs-y) \
 	booke.o \
 	booke_emulate.o \
 	booke_interrupts.o \
 	e500.o \
 	e500_tlb.o \
 	e500_emulate.o
-obj-$(CONFIG_KVM_E500) += kvm-e500.o
+kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs)
+
+kvm-book3s_64-objs := \
+	$(common-objs-y) \
+	book3s.o \
+	book3s_64_emulate.o \
+	book3s_64_interrupts.o \
+	book3s_64_mmu_host.o \
+	book3s_64_mmu.o \
+	book3s_32_mmu.o
+kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-objs)
+
+kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
+
+obj-$(CONFIG_KVM_440) += kvm.o
+obj-$(CONFIG_KVM_E500) += kvm.o
+obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/powerpc.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/powerpc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/powerpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/powerpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/kvm_host.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/hrtimer.h>
 #include <linux/fs.h>
 #include <asm/cputable.h>
 #include <asm/uaccess.h>
@@ -78,8 +79,9 @@ int kvmppc_emulate_mmio(struct kvm_run *
 	return r;
 }
 
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
 {
+	return 0;
 }
 
 void kvm_arch_hardware_disable(void *garbage)
@@ -143,6 +145,9 @@ int kvm_dev_ioctl_check_extension(long e
 	int r;
 
 	switch (ext) {
+	case KVM_CAP_PPC_SEGSTATE:
+		r = 1;
+		break;
 	case KVM_CAP_COALESCED_MMIO:
 		r = KVM_COALESCED_MMIO_PAGE_OFFSET;
 		break;
@@ -208,10 +213,25 @@ static void kvmppc_decrementer_func(unsi
 	}
 }
 
+/*
+ * low level hrtimer wake routine. Because this runs in hardirq context
+ * we schedule a tasklet to do the real work.
+ */
+enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
+{
+	struct kvm_vcpu *vcpu;
+
+	vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
+	tasklet_schedule(&vcpu->arch.tasklet);
+
+	return HRTIMER_NORESTART;
+}
+
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 {
-	setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func,
-	            (unsigned long)vcpu);
+	hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+	tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
+	vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
 
 	return 0;
 }
@@ -409,11 +429,6 @@ out:
 	return r;
 }
 
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
-{
-	return -ENOTSUPP;
-}
-
 long kvm_arch_vm_ioctl(struct file *filp,
                        unsigned int ioctl, unsigned long arg)
 {
@@ -421,7 +436,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 
 	switch (ioctl) {
 	default:
-		r = -EINVAL;
+		r = -ENOTTY;
 	}
 
 	return r;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/timing.c linux-libre-2.6.33-gnu1/arch/powerpc/kvm/timing.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/timing.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/timing.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <asm/time.h>
 #include <asm-generic/div64.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/timing.h linux-libre-2.6.33-gnu1/arch/powerpc/kvm/timing.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/timing.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/timing.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ static inline void kvmppc_account_exit_s
 
 	/* The BUILD_BUG_ON below breaks in funny ways, commented out
 	 * for now ... -BenH
-	BUILD_BUG_ON(__builtin_constant_p(type));
+	BUILD_BUG_ON(!__builtin_constant_p(type));
 	*/
 	switch (type) {
 	case EXT_INTR_EXITS:
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/kvm/trace.h linux-libre-2.6.33-gnu1/arch/powerpc/kvm/trace.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/kvm/trace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/kvm/trace.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,8 +12,8 @@
  * Tracepoint for guest mode entry.
  */
 TRACE_EVENT(kvm_ppc_instr,
-	TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate),
-	TP_ARGS(inst, pc, emulate),
+	TP_PROTO(unsigned int inst, unsigned long _pc, unsigned int emulate),
+	TP_ARGS(inst, _pc, emulate),
 
 	TP_STRUCT__entry(
 		__field(	unsigned int,	inst		)
@@ -23,7 +23,7 @@ TRACE_EVENT(kvm_ppc_instr,
 
 	TP_fast_assign(
 		__entry->inst		= inst;
-		__entry->pc		= pc;
+		__entry->pc		= _pc;
 		__entry->emulate	= emulate;
 	),
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/lib/copy_32.S linux-libre-2.6.33-gnu1/arch/powerpc/lib/copy_32.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/lib/copy_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/lib/copy_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -98,20 +98,7 @@ _GLOBAL(cacheable_memzero)
 	bdnz	4b
 3:	mtctr	r9
 	li	r7,4
-#if !defined(CONFIG_8xx)
 10:	dcbz	r7,r6
-#else
-10:	stw	r4, 4(r6)
-	stw	r4, 8(r6)
-	stw	r4, 12(r6)
-	stw	r4, 16(r6)
-#if CACHE_LINE_SIZE >= 32
-	stw	r4, 20(r6)
-	stw	r4, 24(r6)
-	stw	r4, 28(r6)
-	stw	r4, 32(r6)
-#endif /* CACHE_LINE_SIZE */
-#endif
 	addi	r6,r6,CACHELINE_BYTES
 	bdnz	10b
 	clrlwi	r5,r8,32-LG_CACHELINE_BYTES
@@ -200,9 +187,7 @@ _GLOBAL(cacheable_memcpy)
 	mtctr	r0
 	beq	63f
 53:
-#if !defined(CONFIG_8xx)
 	dcbz	r11,r6
-#endif
 	COPY_16_BYTES
 #if L1_CACHE_BYTES >= 32
 	COPY_16_BYTES
@@ -356,14 +341,6 @@ _GLOBAL(__copy_tofrom_user)
 	li	r11,4
 	beq	63f
 
-#ifdef CONFIG_8xx
-	/* Don't use prefetch on 8xx */
-	mtctr	r0
-	li	r0,0
-53:	COPY_16_BYTES_WITHEX(0)
-	bdnz	53b
-
-#else /* not CONFIG_8xx */
 	/* Here we decide how far ahead to prefetch the source */
 	li	r3,4
 	cmpwi	r0,1
@@ -416,7 +393,6 @@ _GLOBAL(__copy_tofrom_user)
 	li	r3,4
 	li	r7,0
 	bne	114b
-#endif /* CONFIG_8xx */
 
 63:	srwi.	r0,r5,2
 	mtctr	r0
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/lib/copypage_64.S linux-libre-2.6.33-gnu1/arch/powerpc/lib/copypage_64.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/lib/copypage_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/lib/copypage_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -26,11 +26,11 @@ BEGIN_FTR_SECTION
 	srd	r8,r5,r11
 
 	mtctr	r8
-setup:
+.Lsetup:
 	dcbt	r9,r4
 	dcbz	r9,r3
 	add	r9,r9,r12
-	bdnz	setup
+	bdnz	.Lsetup
 END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
 	addi	r3,r3,-8
 	srdi    r8,r5,7		/* page is copied in 128 byte strides */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/lib/locks.c linux-libre-2.6.33-gnu1/arch/powerpc/lib/locks.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/lib/locks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/lib/locks.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,7 +25,7 @@
 #include <asm/smp.h>
 #include <asm/firmware.h>
 
-void __spin_yield(raw_spinlock_t *lock)
+void __spin_yield(arch_spinlock_t *lock)
 {
 	unsigned int lock_value, holder_cpu, yield_count;
 
@@ -55,7 +55,7 @@ void __spin_yield(raw_spinlock_t *lock)
  * This turns out to be the same for read and write locks, since
  * we only know the holder if it is write-locked.
  */
-void __rw_yield(raw_rwlock_t *rw)
+void __rw_yield(arch_rwlock_t *rw)
 {
 	int lock_value;
 	unsigned int holder_cpu, yield_count;
@@ -82,7 +82,7 @@ void __rw_yield(raw_rwlock_t *rw)
 }
 #endif
 
-void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
 	while (lock->slock) {
 		HMT_low();
@@ -92,4 +92,4 @@ void __raw_spin_unlock_wait(raw_spinlock
 	HMT_medium();
 }
 
-EXPORT_SYMBOL(__raw_spin_unlock_wait);
+EXPORT_SYMBOL(arch_spin_unlock_wait);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/40x_mmu.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/40x_mmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/40x_mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/40x_mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -91,7 +91,7 @@ void __init MMU_init_hw(void)
 #define LARGE_PAGE_SIZE_16M	(1<<24)
 #define LARGE_PAGE_SIZE_4M	(1<<22)
 
-unsigned long __init mmu_mapin_ram(void)
+unsigned long __init mmu_mapin_ram(unsigned long top)
 {
 	unsigned long v, s, mapped;
 	phys_addr_t p;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/44x_mmu.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/44x_mmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/44x_mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/44x_mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -88,7 +88,7 @@ void __init MMU_init_hw(void)
 	flush_instruction_cache();
 }
 
-unsigned long __init mmu_mapin_ram(void)
+unsigned long __init mmu_mapin_ram(unsigned long top)
 {
 	unsigned long addr;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/fault.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/fault.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/fault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/siginfo.h>
-
+#include <mm/mmu_decl.h>
 
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs *regs)
@@ -246,6 +246,12 @@ good_area:
 		goto bad_area;
 #endif /* CONFIG_6xx */
 #if defined(CONFIG_8xx)
+	/* 8xx sometimes need to load a invalid/non-present TLBs.
+	 * These must be invalidated separately as linux mm don't.
+	 */
+	if (error_code & 0x40000000) /* no translation? */
+		_tlbil_va(address, 0, 0, 0);
+
         /* The MPC8xx seems to always set 0x80000000, which is
          * "undefined".  Of those that can be set, this is the only
          * one which seems bad.
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/fsl_booke_mmu.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/fsl_booke_mmu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,26 +54,35 @@
 
 #include "mmu_decl.h"
 
-extern void loadcam_entry(unsigned int index);
 unsigned int tlbcam_index;
-static unsigned long cam[CONFIG_LOWMEM_CAM_NUM];
 
-#define NUM_TLBCAMS	(16)
+#define NUM_TLBCAMS	(64)
 
 #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
 #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
 #endif
 
-struct tlbcam TLBCAM[NUM_TLBCAMS];
+struct tlbcam {
+	u32	MAS0;
+	u32	MAS1;
+	unsigned long	MAS2;
+	u32	MAS3;
+	u32	MAS7;
+} TLBCAM[NUM_TLBCAMS];
 
 struct tlbcamrange {
-   	unsigned long start;
+	unsigned long start;
 	unsigned long limit;
 	phys_addr_t phys;
 } tlbcam_addrs[NUM_TLBCAMS];
 
 extern unsigned int tlbcam_index;
 
+unsigned long tlbcam_sz(int idx)
+{
+	return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1;
+}
+
 /*
  * Return PA for this VA if it is mapped by a CAM, or 0
  */
@@ -94,23 +103,36 @@ unsigned long p_mapped_by_tlbcam(phys_ad
 	int b;
 	for (b = 0; b < tlbcam_index; ++b)
 		if (pa >= tlbcam_addrs[b].phys
-	    	    && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
+			&& pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
 		              +tlbcam_addrs[b].phys)
 			return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
 	return 0;
 }
 
+void loadcam_entry(int idx)
+{
+	mtspr(SPRN_MAS0, TLBCAM[idx].MAS0);
+	mtspr(SPRN_MAS1, TLBCAM[idx].MAS1);
+	mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
+	mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
+
+	if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+		mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
+
+	asm volatile("isync;tlbwe;isync" : : : "memory");
+}
+
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
  * of 4 between 4k and 256M.
  */
-void settlbcam(int index, unsigned long virt, phys_addr_t phys,
-		unsigned int size, int flags, unsigned int pid)
+static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+		unsigned long size, unsigned long flags, unsigned int pid)
 {
 	unsigned int tsize, lz;
 
-	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
+	asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (size));
 	tsize = 21 - lz;
 
 #ifdef CONFIG_SMP
@@ -128,8 +150,10 @@ void settlbcam(int index, unsigned long
 	TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
 	TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
 
-	TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
+	TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
 	TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
+	if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+		TLBCAM[index].MAS7 = (u64)phys >> 32;
 
 #ifndef CONFIG_KGDB /* want user access for breakpoints */
 	if (flags & _PAGE_USER) {
@@ -148,27 +172,44 @@ void settlbcam(int index, unsigned long
 	loadcam_entry(index);
 }
 
-void invalidate_tlbcam_entry(int index)
-{
-	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
-	TLBCAM[index].MAS1 = ~MAS1_VALID;
-
-	loadcam_entry(index);
-}
-
-unsigned long __init mmu_mapin_ram(void)
+unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
 {
+	int i;
 	unsigned long virt = PAGE_OFFSET;
 	phys_addr_t phys = memstart_addr;
+	unsigned long amount_mapped = 0;
+	unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
 
-	while (tlbcam_index < ARRAY_SIZE(cam) && cam[tlbcam_index]) {
-		settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], PAGE_KERNEL_X, 0);
-		virt += cam[tlbcam_index];
-		phys += cam[tlbcam_index];
-		tlbcam_index++;
+	/* Convert (4^max) kB to (2^max) bytes */
+	max_cam = max_cam * 2 + 10;
+
+	/* Calculate CAM values */
+	for (i = 0; ram && i < max_cam_idx; i++) {
+		unsigned int camsize = __ilog2(ram) & ~1U;
+		unsigned int align = __ffs(virt | phys) & ~1U;
+		unsigned long cam_sz;
+
+		if (camsize > align)
+			camsize = align;
+		if (camsize > max_cam)
+			camsize = max_cam;
+
+		cam_sz = 1UL << camsize;
+		settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0);
+
+		ram -= cam_sz;
+		amount_mapped += cam_sz;
+		virt += cam_sz;
+		phys += cam_sz;
 	}
+	tlbcam_index = i;
 
-	return virt - PAGE_OFFSET;
+	return amount_mapped;
+}
+
+unsigned long __init mmu_mapin_ram(unsigned long top)
+{
+	return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
 }
 
 /*
@@ -179,46 +220,21 @@ void __init MMU_init_hw(void)
 	flush_instruction_cache();
 }
 
-void __init
-adjust_total_lowmem(void)
+void __init adjust_total_lowmem(void)
 {
-	phys_addr_t ram;
-	unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff;
-	char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
+	unsigned long ram;
 	int i;
-	unsigned long virt = PAGE_OFFSET & 0xffffffffUL;
-	unsigned long phys = memstart_addr & 0xffffffffUL;
-
-	/* Convert (4^max) kB to (2^max) bytes */
-	max_cam = max_cam * 2 + 10;
 
 	/* adjust lowmem size to __max_low_memory */
 	ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
 
-	/* Calculate CAM values */
-	__max_low_memory = 0;
-	for (i = 0; ram && i < ARRAY_SIZE(cam); i++) {
-		unsigned int camsize = __ilog2(ram) & ~1U;
-		unsigned int align = __ffs(virt | phys) & ~1U;
-
-		if (camsize > align)
-			camsize = align;
-		if (camsize > max_cam)
-			camsize = max_cam;
-
-		cam[i] = 1UL << camsize;
-		ram -= cam[i];
-		__max_low_memory += cam[i];
-		virt += cam[i];
-		phys += cam[i];
-
-		p += sprintf(p, "%lu/", cam[i] >> 20);
-	}
-	for (; i < ARRAY_SIZE(cam); i++)
-		p += sprintf(p, "0/");
-	p[-1] = '\0';
+	__max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM);
 
-	pr_info("Memory CAM mapping: %s Mb, residual: %dMb\n", buf,
+	pr_info("Memory CAM mapping: ");
+	for (i = 0; i < tlbcam_index - 1; i++)
+		pr_cont("%lu/", tlbcam_sz(i) >> 20);
+	pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
 	        (unsigned int)((total_lowmem - __max_low_memory) >> 20));
+
 	__initial_memory_limit_addr = memstart_addr + __max_low_memory;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/gup.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/gup.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/gup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/gup.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,57 +55,6 @@ static noinline int gup_pte_range(pmd_t
 	return 1;
 }
 
-#ifdef CONFIG_HUGETLB_PAGE
-static noinline int gup_huge_pte(pte_t *ptep, struct hstate *hstate,
-				 unsigned long *addr, unsigned long end,
-				 int write, struct page **pages, int *nr)
-{
-	unsigned long mask;
-	unsigned long pte_end;
-	struct page *head, *page;
-	pte_t pte;
-	int refs;
-
-	pte_end = (*addr + huge_page_size(hstate)) & huge_page_mask(hstate);
-	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 & ~huge_page_mask(hstate)) >> PAGE_SHIFT);
-	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 */
-		while (*nr) {
-			put_page(page);
-			(*nr)--;
-		}
-	}
-
-	return 1;
-}
-#endif /* CONFIG_HUGETLB_PAGE */
-
 static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
 		int write, struct page **pages, int *nr)
 {
@@ -119,7 +68,11 @@ static int gup_pmd_range(pud_t pud, unsi
 		next = pmd_addr_end(addr, end);
 		if (pmd_none(pmd))
 			return 0;
-		if (!gup_pte_range(pmd, addr, next, write, pages, nr))
+		if (is_hugepd(pmdp)) {
+			if (!gup_hugepd((hugepd_t *)pmdp, PMD_SHIFT,
+					addr, next, write, pages, nr))
+				return 0;
+		} else if (!gup_pte_range(pmd, addr, next, write, pages, nr))
 			return 0;
 	} while (pmdp++, addr = next, addr != end);
 
@@ -139,7 +92,11 @@ static int gup_pud_range(pgd_t pgd, unsi
 		next = pud_addr_end(addr, end);
 		if (pud_none(pud))
 			return 0;
-		if (!gup_pmd_range(pud, addr, next, write, pages, nr))
+		if (is_hugepd(pudp)) {
+			if (!gup_hugepd((hugepd_t *)pudp, PUD_SHIFT,
+					addr, next, write, pages, nr))
+				return 0;
+		} else if (!gup_pmd_range(pud, addr, next, write, pages, nr))
 			return 0;
 	} while (pudp++, addr = next, addr != end);
 
@@ -154,10 +111,6 @@ int get_user_pages_fast(unsigned long st
 	unsigned long next;
 	pgd_t *pgdp;
 	int nr = 0;
-#ifdef CONFIG_PPC64
-	unsigned int shift;
-	int psize;
-#endif
 
 	pr_devel("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
 
@@ -172,25 +125,6 @@ int get_user_pages_fast(unsigned long st
 
 	pr_devel("  aligned: %lx .. %lx\n", start, end);
 
-#ifdef CONFIG_HUGETLB_PAGE
-	/* We bail out on slice boundary crossing when hugetlb is
-	 * enabled in order to not have to deal with two different
-	 * page table formats
-	 */
-	if (addr < SLICE_LOW_TOP) {
-		if (end > SLICE_LOW_TOP)
-			goto slow_irqon;
-
-		if (unlikely(GET_LOW_SLICE_INDEX(addr) !=
-			     GET_LOW_SLICE_INDEX(end - 1)))
-			goto slow_irqon;
-	} else {
-		if (unlikely(GET_HIGH_SLICE_INDEX(addr) !=
-			     GET_HIGH_SLICE_INDEX(end - 1)))
-			goto slow_irqon;
-	}
-#endif /* CONFIG_HUGETLB_PAGE */
-
 	/*
 	 * XXX: batch / limit 'nr', to avoid large irq off latency
 	 * needs some instrumenting to determine the common sizes used by
@@ -210,54 +144,23 @@ int get_user_pages_fast(unsigned long st
 	 */
 	local_irq_disable();
 
-#ifdef CONFIG_PPC64
-	/* Those bits are related to hugetlbfs implementation and only exist
-	 * on 64-bit for now
-	 */
-	psize = get_slice_psize(mm, addr);
-	shift = mmu_psize_defs[psize].shift;
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_HUGETLB_PAGE
-	if (unlikely(mmu_huge_psizes[psize])) {
-		pte_t *ptep;
-		unsigned long a = addr;
-		unsigned long sz = ((1UL) << shift);
-		struct hstate *hstate = size_to_hstate(sz);
-
-		BUG_ON(!hstate);
-		/*
-		 * XXX: could be optimized to avoid hstate
-		 * lookup entirely (just use shift)
-		 */
+	pgdp = pgd_offset(mm, addr);
+	do {
+		pgd_t pgd = *pgdp;
 
-		do {
-			VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, a)].shift);
-			ptep = huge_pte_offset(mm, a);
-			pr_devel(" %016lx: huge ptep %p\n", a, ptep);
-			if (!ptep || !gup_huge_pte(ptep, hstate, &a, end, write, pages,
-						   &nr))
+		pr_devel("  %016lx: normal pgd %p\n", addr,
+			 (void *)pgd_val(pgd));
+		next = pgd_addr_end(addr, end);
+		if (pgd_none(pgd))
+			goto slow;
+		if (is_hugepd(pgdp)) {
+			if (!gup_hugepd((hugepd_t *)pgdp, PGDIR_SHIFT,
+					addr, next, write, pages, &nr))
 				goto slow;
-		} while (a != end);
-	} else
-#endif /* CONFIG_HUGETLB_PAGE */
-	{
-		pgdp = pgd_offset(mm, addr);
-		do {
-			pgd_t pgd = *pgdp;
+		} else if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+			goto slow;
+	} while (pgdp++, addr = next, addr != end);
 
-#ifdef CONFIG_PPC64
-			VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
-#endif
-			pr_devel("  %016lx: normal pgd %p\n", addr,
-				 (void *)pgd_val(pgd));
-			next = pgd_addr_end(addr, end);
-			if (pgd_none(pgd))
-				goto slow;
-			if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
-				goto slow;
-		} while (pgdp++, addr = next, addr != end);
-	}
 	local_irq_enable();
 
 	VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/hash_utils_64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/hash_utils_64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/hash_utils_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/hash_utils_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,6 +92,7 @@ struct mmu_psize_def mmu_psize_defs[MMU_
 struct hash_pte *htab_address;
 unsigned long htab_size_bytes;
 unsigned long htab_hash_mask;
+EXPORT_SYMBOL_GPL(htab_hash_mask);
 int mmu_linear_psize = MMU_PAGE_4K;
 int mmu_virtual_psize = MMU_PAGE_4K;
 int mmu_vmalloc_psize = MMU_PAGE_4K;
@@ -102,6 +103,7 @@ int mmu_io_psize = MMU_PAGE_4K;
 int mmu_kernel_ssize = MMU_SEGSIZE_256M;
 int mmu_highuser_ssize = MMU_SEGSIZE_256M;
 u16 mmu_slb_size = 64;
+EXPORT_SYMBOL_GPL(mmu_slb_size);
 #ifdef CONFIG_HUGETLB_PAGE
 unsigned int HPAGE_SHIFT;
 #endif
@@ -338,7 +340,7 @@ static int __init htab_dt_scan_page_size
 			else
 				def->tlbiel = 0;
 
-			DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, "
+			DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, "
 			    "tlbiel=%d, penc=%d\n",
 			    idx, shift, def->sllp, def->avpnm, def->tlbiel,
 			    def->penc);
@@ -481,16 +483,6 @@ static void __init htab_init_page_sizes(
 #ifdef CONFIG_HUGETLB_PAGE
 	/* Reserve 16G huge page memory sections for huge pages */
 	of_scan_flat_dt(htab_dt_scan_hugepage_blocks, NULL);
-
-/* Set default large page size. Currently, we pick 16M or 1M depending
-	 * on what is available
-	 */
-	if (mmu_psize_defs[MMU_PAGE_16M].shift)
-		HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_16M].shift;
-	/* With 4k/4level pagetables, we can't (for now) cope with a
-	 * huge page size < PMD_SIZE */
-	else if (mmu_psize_defs[MMU_PAGE_1M].shift)
-		HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_1M].shift;
 #endif /* CONFIG_HUGETLB_PAGE */
 }
 
@@ -671,7 +663,7 @@ static void __init htab_initialize(void)
 		base = (unsigned long)__va(lmb.memory.region[i].base);
 		size = lmb.memory.region[i].size;
 
-		DBG("creating mapping for region: %lx..%lx (prot: %x)\n",
+		DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
 		    base, size, prot);
 
 #ifdef CONFIG_U3_DART
@@ -785,7 +777,7 @@ unsigned int hash_page_do_lazy_icache(un
 	/* page is dirty */
 	if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
 		if (trap == 0x400) {
-			__flush_dcache_icache(page_address(page));
+			flush_dcache_icache_page(page);
 			set_bit(PG_arch_1, &page->flags);
 		} else
 			pp |= HPTE_R_N;
@@ -843,9 +835,9 @@ void demote_segment_4k(struct mm_struct
  * Result is 0: full permissions, _PAGE_RW: read-only,
  * _PAGE_USER or _PAGE_USER|_PAGE_RW: no access.
  */
-static int subpage_protection(pgd_t *pgdir, unsigned long ea)
+static int subpage_protection(struct mm_struct *mm, unsigned long ea)
 {
-	struct subpage_prot_table *spt = pgd_subpage_prot(pgdir);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 spp = 0;
 	u32 **sbpm, *sbpp;
 
@@ -873,7 +865,7 @@ static int subpage_protection(pgd_t *pgd
 }
 
 #else /* CONFIG_PPC_SUBPAGE_PROT */
-static inline int subpage_protection(pgd_t *pgdir, unsigned long ea)
+static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
 {
 	return 0;
 }
@@ -887,10 +879,11 @@ static inline int subpage_protection(pgd
  */
 int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
 {
-	void *pgdir;
+	pgd_t *pgdir;
 	unsigned long vsid;
 	struct mm_struct *mm;
 	pte_t *ptep;
+	unsigned hugeshift;
 	const struct cpumask *tmp;
 	int rc, user_region = 0, local = 0;
 	int psize, ssize;
@@ -943,30 +936,31 @@ int hash_page(unsigned long ea, unsigned
 	if (user_region && cpumask_equal(mm_cpumask(mm), tmp))
 		local = 1;
 
-#ifdef CONFIG_HUGETLB_PAGE
-	/* Handle hugepage regions */
-	if (HPAGE_SHIFT && mmu_huge_psizes[psize]) {
-		DBG_LOW(" -> huge page !\n");
-		return hash_huge_page(mm, access, ea, vsid, local, trap);
-	}
-#endif /* CONFIG_HUGETLB_PAGE */
-
 #ifndef CONFIG_PPC_64K_PAGES
-	/* If we use 4K pages and our psize is not 4K, then we are hitting
-	 * a special driver mapping, we need to align the address before
-	 * we fetch the PTE
+	/* If we use 4K pages and our psize is not 4K, then we might
+	 * be hitting a special driver mapping, and need to align the
+	 * address before we fetch the PTE.
+	 *
+	 * It could also be a hugepage mapping, in which case this is
+	 * not necessary, but it's not harmful, either.
 	 */
 	if (psize != MMU_PAGE_4K)
 		ea &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
 #endif /* CONFIG_PPC_64K_PAGES */
 
 	/* Get PTE and page size from page tables */
-	ptep = find_linux_pte(pgdir, ea);
+	ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift);
 	if (ptep == NULL || !pte_present(*ptep)) {
 		DBG_LOW(" no PTE !\n");
 		return 1;
 	}
 
+#ifdef CONFIG_HUGETLB_PAGE
+	if (hugeshift)
+		return __hash_page_huge(ea, access, vsid, ptep, trap, local,
+					ssize, hugeshift, psize);
+#endif /* CONFIG_HUGETLB_PAGE */
+
 #ifndef CONFIG_PPC_64K_PAGES
 	DBG_LOW(" i-pte: %016lx\n", pte_val(*ptep));
 #else
@@ -1031,7 +1025,7 @@ int hash_page(unsigned long ea, unsigned
 	else
 #endif /* CONFIG_PPC_HAS_HASH_64K */
 	{
-		int spp = subpage_protection(pgdir, ea);
+		int spp = subpage_protection(mm, ea);
 		if (access & spp)
 			rc = -2;
 		else
@@ -1121,7 +1115,7 @@ void flush_hash_page(unsigned long va, r
 {
 	unsigned long hash, index, shift, hidx, slot;
 
-	DBG_LOW("flush_hash_page(va=%016x)\n", va);
+	DBG_LOW("flush_hash_page(va=%016lx)\n", va);
 	pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
 		hash = hpt_hash(va, shift, ssize);
 		hidx = __rpte_to_hidx(pte, index);
@@ -1129,7 +1123,7 @@ void flush_hash_page(unsigned long va, r
 			hash = ~hash;
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += hidx & _PTEIDX_GROUP_IX;
-		DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx);
+		DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
 		ppc_md.hpte_invalidate(slot, va, psize, ssize, local);
 	} pte_iterate_hashed_end();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/hugetlbpage.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/hugetlbpage.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,29 +7,17 @@
  * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
  */
 
-#include <linux/init.h>
-#include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 #include <linux/hugetlb.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/sysctl.h>
-#include <asm/mman.h>
+#include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-#include <asm/machdep.h>
-#include <asm/cputable.h>
-#include <asm/spu.h>
 
 #define PAGE_SHIFT_64K	16
 #define PAGE_SHIFT_16M	24
 #define PAGE_SHIFT_16G	34
 
-#define NUM_LOW_AREAS	(0x100000000UL >> SID_SHIFT)
-#define NUM_HIGH_AREAS	(PGTABLE_RANGE >> HTLB_AREA_SHIFT)
 #define MAX_NUMBER_GPAGES	1024
 
 /* Tracks the 16G pages after the device tree is scanned and before the
@@ -37,53 +25,17 @@
 static unsigned long gpage_freearray[MAX_NUMBER_GPAGES];
 static unsigned nr_gpages;
 
-/* Array of valid huge page sizes - non-zero value(hugepte_shift) is
- * stored for the huge page sizes that are valid.
- */
-unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */
-
-#define hugepte_shift			mmu_huge_psizes
-#define PTRS_PER_HUGEPTE(psize)		(1 << hugepte_shift[psize])
-#define HUGEPTE_TABLE_SIZE(psize)	(sizeof(pte_t) << hugepte_shift[psize])
-
-#define HUGEPD_SHIFT(psize)		(mmu_psize_to_shift(psize) \
-						+ hugepte_shift[psize])
-#define HUGEPD_SIZE(psize)		(1UL << HUGEPD_SHIFT(psize))
-#define HUGEPD_MASK(psize)		(~(HUGEPD_SIZE(psize)-1))
-
-/* Subtract one from array size because we don't need a cache for 4K since
- * is not a huge page size */
-#define HUGE_PGTABLE_INDEX(psize)	(HUGEPTE_CACHE_NUM + psize - 1)
-#define HUGEPTE_CACHE_NAME(psize)	(huge_pgtable_cache_name[psize])
-
-static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = {
-	[MMU_PAGE_64K]	= "hugepte_cache_64K",
-	[MMU_PAGE_1M]	= "hugepte_cache_1M",
-	[MMU_PAGE_16M]	= "hugepte_cache_16M",
-	[MMU_PAGE_16G]	= "hugepte_cache_16G",
-};
-
 /* Flag to mark huge PD pointers.  This means pmd_bad() and pud_bad()
  * will choke on pointers to hugepte tables, which is handy for
  * catching screwups early. */
-#define HUGEPD_OK	0x1
-
-typedef struct { unsigned long pd; } hugepd_t;
-
-#define hugepd_none(hpd)	((hpd).pd == 0)
 
 static inline int shift_to_mmu_psize(unsigned int shift)
 {
-	switch (shift) {
-#ifndef CONFIG_PPC_64K_PAGES
-	case PAGE_SHIFT_64K:
-	    return MMU_PAGE_64K;
-#endif
-	case PAGE_SHIFT_16M:
-	    return MMU_PAGE_16M;
-	case PAGE_SHIFT_16G:
-	    return MMU_PAGE_16G;
-	}
+	int psize;
+
+	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize)
+		if (mmu_psize_defs[psize].shift == shift)
+			return psize;
 	return -1;
 }
 
@@ -94,71 +46,126 @@ static inline unsigned int mmu_psize_to_
 	BUG();
 }
 
+#define hugepd_none(hpd)	((hpd).pd == 0)
+
 static inline pte_t *hugepd_page(hugepd_t hpd)
 {
-	BUG_ON(!(hpd.pd & HUGEPD_OK));
-	return (pte_t *)(hpd.pd & ~HUGEPD_OK);
+	BUG_ON(!hugepd_ok(hpd));
+	return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | 0xc000000000000000);
 }
 
-static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
-				    struct hstate *hstate)
+static inline unsigned int hugepd_shift(hugepd_t hpd)
 {
-	unsigned int shift = huge_page_shift(hstate);
-	int psize = shift_to_mmu_psize(shift);
-	unsigned long idx = ((addr >> shift) & (PTRS_PER_HUGEPTE(psize)-1));
+	return hpd.pd & HUGEPD_SHIFT_MASK;
+}
+
+static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift)
+{
+	unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp);
 	pte_t *dir = hugepd_page(*hpdp);
 
 	return dir + idx;
 }
 
+pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift)
+{
+	pgd_t *pg;
+	pud_t *pu;
+	pmd_t *pm;
+	hugepd_t *hpdp = NULL;
+	unsigned pdshift = PGDIR_SHIFT;
+
+	if (shift)
+		*shift = 0;
+
+	pg = pgdir + pgd_index(ea);
+	if (is_hugepd(pg)) {
+		hpdp = (hugepd_t *)pg;
+	} else if (!pgd_none(*pg)) {
+		pdshift = PUD_SHIFT;
+		pu = pud_offset(pg, ea);
+		if (is_hugepd(pu))
+			hpdp = (hugepd_t *)pu;
+		else if (!pud_none(*pu)) {
+			pdshift = PMD_SHIFT;
+			pm = pmd_offset(pu, ea);
+			if (is_hugepd(pm))
+				hpdp = (hugepd_t *)pm;
+			else if (!pmd_none(*pm)) {
+				return pte_offset_map(pm, ea);
+			}
+		}
+	}
+
+	if (!hpdp)
+		return NULL;
+
+	if (shift)
+		*shift = hugepd_shift(*hpdp);
+	return hugepte_offset(hpdp, ea, pdshift);
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+	return find_linux_pte_or_hugepte(mm->pgd, addr, NULL);
+}
+
 static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
-			   unsigned long address, unsigned int psize)
+			   unsigned long address, unsigned pdshift, unsigned pshift)
 {
-	pte_t *new = kmem_cache_zalloc(pgtable_cache[HUGE_PGTABLE_INDEX(psize)],
-				      GFP_KERNEL|__GFP_REPEAT);
+	pte_t *new = kmem_cache_zalloc(PGT_CACHE(pdshift - pshift),
+				       GFP_KERNEL|__GFP_REPEAT);
+
+	BUG_ON(pshift > HUGEPD_SHIFT_MASK);
+	BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK);
 
 	if (! new)
 		return -ENOMEM;
 
 	spin_lock(&mm->page_table_lock);
 	if (!hugepd_none(*hpdp))
-		kmem_cache_free(pgtable_cache[HUGE_PGTABLE_INDEX(psize)], new);
+		kmem_cache_free(PGT_CACHE(pdshift - pshift), new);
 	else
-		hpdp->pd = (unsigned long)new | HUGEPD_OK;
+		hpdp->pd = ((unsigned long)new & ~0x8000000000000000) | pshift;
 	spin_unlock(&mm->page_table_lock);
 	return 0;
 }
 
-
-static pud_t *hpud_offset(pgd_t *pgd, unsigned long addr, struct hstate *hstate)
-{
-	if (huge_page_shift(hstate) < PUD_SHIFT)
-		return pud_offset(pgd, addr);
-	else
-		return (pud_t *) pgd;
-}
-static pud_t *hpud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long addr,
-			 struct hstate *hstate)
-{
-	if (huge_page_shift(hstate) < PUD_SHIFT)
-		return pud_alloc(mm, pgd, addr);
-	else
-		return (pud_t *) pgd;
-}
-static pmd_t *hpmd_offset(pud_t *pud, unsigned long addr, struct hstate *hstate)
-{
-	if (huge_page_shift(hstate) < PMD_SHIFT)
-		return pmd_offset(pud, addr);
-	else
-		return (pmd_t *) pud;
-}
-static pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr,
-			 struct hstate *hstate)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
 {
-	if (huge_page_shift(hstate) < PMD_SHIFT)
-		return pmd_alloc(mm, pud, addr);
-	else
-		return (pmd_t *) pud;
+	pgd_t *pg;
+	pud_t *pu;
+	pmd_t *pm;
+	hugepd_t *hpdp = NULL;
+	unsigned pshift = __ffs(sz);
+	unsigned pdshift = PGDIR_SHIFT;
+
+	addr &= ~(sz-1);
+
+	pg = pgd_offset(mm, addr);
+	if (pshift >= PUD_SHIFT) {
+		hpdp = (hugepd_t *)pg;
+	} else {
+		pdshift = PUD_SHIFT;
+		pu = pud_alloc(mm, pg, addr);
+		if (pshift >= PMD_SHIFT) {
+			hpdp = (hugepd_t *)pu;
+		} else {
+			pdshift = PMD_SHIFT;
+			pm = pmd_alloc(mm, pu, addr);
+			hpdp = (hugepd_t *)pm;
+		}
+	}
+
+	if (!hpdp)
+		return NULL;
+
+	BUG_ON(!hugepd_none(*hpdp) && !hugepd_ok(*hpdp));
+
+	if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift))
+		return NULL;
+
+	return hugepte_offset(hpdp, addr, pdshift);
 }
 
 /* Build list of addresses of gigantic pages.  This function is used in early
@@ -192,94 +199,38 @@ int alloc_bootmem_huge_page(struct hstat
 	return 1;
 }
 
-
-/* Modelled after find_linux_pte() */
-pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
-{
-	pgd_t *pg;
-	pud_t *pu;
-	pmd_t *pm;
-
-	unsigned int psize;
-	unsigned int shift;
-	unsigned long sz;
-	struct hstate *hstate;
-	psize = get_slice_psize(mm, addr);
-	shift = mmu_psize_to_shift(psize);
-	sz = ((1UL) << shift);
-	hstate = size_to_hstate(sz);
-
-	addr &= hstate->mask;
-
-	pg = pgd_offset(mm, addr);
-	if (!pgd_none(*pg)) {
-		pu = hpud_offset(pg, addr, hstate);
-		if (!pud_none(*pu)) {
-			pm = hpmd_offset(pu, addr, hstate);
-			if (!pmd_none(*pm))
-				return hugepte_offset((hugepd_t *)pm, addr,
-						      hstate);
-		}
-	}
-
-	return NULL;
-}
-
-pte_t *huge_pte_alloc(struct mm_struct *mm,
-			unsigned long addr, unsigned long sz)
-{
-	pgd_t *pg;
-	pud_t *pu;
-	pmd_t *pm;
-	hugepd_t *hpdp = NULL;
-	struct hstate *hstate;
-	unsigned int psize;
-	hstate = size_to_hstate(sz);
-
-	psize = get_slice_psize(mm, addr);
-	BUG_ON(!mmu_huge_psizes[psize]);
-
-	addr &= hstate->mask;
-
-	pg = pgd_offset(mm, addr);
-	pu = hpud_alloc(mm, pg, addr, hstate);
-
-	if (pu) {
-		pm = hpmd_alloc(mm, pu, addr, hstate);
-		if (pm)
-			hpdp = (hugepd_t *)pm;
-	}
-
-	if (! hpdp)
-		return NULL;
-
-	if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, psize))
-		return NULL;
-
-	return hugepte_offset(hpdp, addr, hstate);
-}
-
 int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
 {
 	return 0;
 }
 
-static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp,
-			       unsigned int psize)
+static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift,
+			      unsigned long start, unsigned long end,
+			      unsigned long floor, unsigned long ceiling)
 {
 	pte_t *hugepte = hugepd_page(*hpdp);
+	unsigned shift = hugepd_shift(*hpdp);
+	unsigned long pdmask = ~((1UL << pdshift) - 1);
+
+	start &= pdmask;
+	if (start < floor)
+		return;
+	if (ceiling) {
+		ceiling &= pdmask;
+		if (! ceiling)
+			return;
+	}
+	if (end - 1 > ceiling - 1)
+		return;
 
 	hpdp->pd = 0;
 	tlb->need_flush = 1;
-	pgtable_free_tlb(tlb, pgtable_free_cache(hugepte,
-						 HUGEPTE_CACHE_NUM+psize-1,
-						 PGF_CACHENUM_MASK));
+	pgtable_free_tlb(tlb, hugepte, pdshift - shift);
 }
 
 static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
 				   unsigned long addr, unsigned long end,
-				   unsigned long floor, unsigned long ceiling,
-				   unsigned int psize)
+				   unsigned long floor, unsigned long ceiling)
 {
 	pmd_t *pmd;
 	unsigned long next;
@@ -291,7 +242,8 @@ static void hugetlb_free_pmd_range(struc
 		next = pmd_addr_end(addr, end);
 		if (pmd_none(*pmd))
 			continue;
-		free_hugepte_range(tlb, (hugepd_t *)pmd, psize);
+		free_hugepd_range(tlb, (hugepd_t *)pmd, PMD_SHIFT,
+				  addr, next, floor, ceiling);
 	} while (pmd++, addr = next, addr != end);
 
 	start &= PUD_MASK;
@@ -317,23 +269,19 @@ static void hugetlb_free_pud_range(struc
 	pud_t *pud;
 	unsigned long next;
 	unsigned long start;
-	unsigned int shift;
-	unsigned int psize = get_slice_psize(tlb->mm, addr);
-	shift = mmu_psize_to_shift(psize);
 
 	start = addr;
 	pud = pud_offset(pgd, addr);
 	do {
 		next = pud_addr_end(addr, end);
-		if (shift < PMD_SHIFT) {
+		if (!is_hugepd(pud)) {
 			if (pud_none_or_clear_bad(pud))
 				continue;
 			hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
-					       ceiling, psize);
+					       ceiling);
 		} else {
-			if (pud_none(*pud))
-				continue;
-			free_hugepte_range(tlb, (hugepd_t *)pud, psize);
+			free_hugepd_range(tlb, (hugepd_t *)pud, PUD_SHIFT,
+					  addr, next, floor, ceiling);
 		}
 	} while (pud++, addr = next, addr != end);
 
@@ -364,121 +312,56 @@ void hugetlb_free_pgd_range(struct mmu_g
 {
 	pgd_t *pgd;
 	unsigned long next;
-	unsigned long start;
 
 	/*
-	 * Comments below take from the normal free_pgd_range().  They
-	 * apply here too.  The tests against HUGEPD_MASK below are
-	 * essential, because we *don't* test for this at the bottom
-	 * level.  Without them we'll attempt to free a hugepte table
-	 * when we unmap just part of it, even if there are other
-	 * active mappings using it.
-	 *
-	 * The next few lines have given us lots of grief...
-	 *
-	 * Why are we testing HUGEPD* at this top level?  Because
-	 * often there will be no work to do at all, and we'd prefer
-	 * not to go all the way down to the bottom just to discover
-	 * that.
-	 *
-	 * Why all these "- 1"s?  Because 0 represents both the bottom
-	 * of the address space and the top of it (using -1 for the
-	 * top wouldn't help much: the masks would do the wrong thing).
-	 * The rule is that addr 0 and floor 0 refer to the bottom of
-	 * the address space, but end 0 and ceiling 0 refer to the top
-	 * Comparisons need to use "end - 1" and "ceiling - 1" (though
-	 * that end 0 case should be mythical).
-	 *
-	 * Wherever addr is brought up or ceiling brought down, we
-	 * must be careful to reject "the opposite 0" before it
-	 * confuses the subsequent tests.  But what about where end is
-	 * brought down by HUGEPD_SIZE below? no, end can't go down to
-	 * 0 there.
+	 * Because there are a number of different possible pagetable
+	 * layouts for hugepage ranges, we limit knowledge of how
+	 * things should be laid out to the allocation path
+	 * (huge_pte_alloc(), above).  Everything else works out the
+	 * structure as it goes from information in the hugepd
+	 * pointers.  That means that we can't here use the
+	 * optimization used in the normal page free_pgd_range(), of
+	 * checking whether we're actually covering a large enough
+	 * range to have to do anything at the top level of the walk
+	 * instead of at the bottom.
 	 *
-	 * Whereas we round start (addr) and ceiling down, by different
-	 * masks at different levels, in order to test whether a table
-	 * now has no other vmas using it, so can be freed, we don't
-	 * bother to round floor or end up - the tests don't need that.
+	 * To make sense of this, you should probably go read the big
+	 * block comment at the top of the normal free_pgd_range(),
+	 * too.
 	 */
-	unsigned int psize = get_slice_psize(tlb->mm, addr);
 
-	addr &= HUGEPD_MASK(psize);
-	if (addr < floor) {
-		addr += HUGEPD_SIZE(psize);
-		if (!addr)
-			return;
-	}
-	if (ceiling) {
-		ceiling &= HUGEPD_MASK(psize);
-		if (!ceiling)
-			return;
-	}
-	if (end - 1 > ceiling - 1)
-		end -= HUGEPD_SIZE(psize);
-	if (addr > end - 1)
-		return;
-
-	start = addr;
 	pgd = pgd_offset(tlb->mm, addr);
 	do {
-		psize = get_slice_psize(tlb->mm, addr);
-		BUG_ON(!mmu_huge_psizes[psize]);
 		next = pgd_addr_end(addr, end);
-		if (mmu_psize_to_shift(psize) < PUD_SHIFT) {
+		if (!is_hugepd(pgd)) {
 			if (pgd_none_or_clear_bad(pgd))
 				continue;
 			hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
 		} else {
-			if (pgd_none(*pgd))
-				continue;
-			free_hugepte_range(tlb, (hugepd_t *)pgd, psize);
+			free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT,
+					  addr, next, floor, ceiling);
 		}
 	} while (pgd++, addr = next, addr != end);
 }
 
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
-		     pte_t *ptep, pte_t pte)
-{
-	if (pte_present(*ptep)) {
-		/* We open-code pte_clear because we need to pass the right
-		 * argument to hpte_need_flush (huge / !huge). Might not be
-		 * necessary anymore if we make hpte_need_flush() get the
-		 * page size from the slices
-		 */
-		unsigned int psize = get_slice_psize(mm, addr);
-		unsigned int shift = mmu_psize_to_shift(psize);
-		unsigned long sz = ((1UL) << shift);
-		struct hstate *hstate = size_to_hstate(sz);
-		pte_update(mm, addr & hstate->mask, ptep, ~0UL, 1);
-	}
-	*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
-}
-
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep)
-{
-	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1);
-	return __pte(old);
-}
-
 struct page *
 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
 {
 	pte_t *ptep;
 	struct page *page;
-	unsigned int mmu_psize = get_slice_psize(mm, address);
+	unsigned shift;
+	unsigned long mask;
+
+	ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
 
 	/* Verify it is a huge page else bail. */
-	if (!mmu_huge_psizes[mmu_psize])
+	if (!ptep || !shift)
 		return ERR_PTR(-EINVAL);
 
-	ptep = huge_pte_offset(mm, address);
+	mask = (1UL << shift) - 1;
 	page = pte_page(*ptep);
-	if (page) {
-		unsigned int shift = mmu_psize_to_shift(mmu_psize);
-		unsigned long sz = ((1UL) << shift);
-		page += (address % sz) / PAGE_SIZE;
-	}
+	if (page)
+		page += (address & mask) / PAGE_SIZE;
 
 	return page;
 }
@@ -501,249 +384,140 @@ follow_huge_pmd(struct mm_struct *mm, un
 	return NULL;
 }
 
-
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-					unsigned long len, unsigned long pgoff,
-					unsigned long flags)
+static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
+		       unsigned long end, int write, struct page **pages, int *nr)
 {
-	struct hstate *hstate = hstate_file(file);
-	int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
+	unsigned long mask;
+	unsigned long pte_end;
+	struct page *head, *page;
+	pte_t pte;
+	int refs;
 
-	if (!mmu_huge_psizes[mmu_psize])
-		return -EINVAL;
-	return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0);
-}
+	pte_end = (addr + sz) & ~(sz-1);
+	if (pte_end < end)
+		end = pte_end;
 
-unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
-{
-	unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
+	pte = *ptep;
+	mask = _PAGE_PRESENT | _PAGE_USER;
+	if (write)
+		mask |= _PAGE_RW;
 
-	return 1UL << mmu_psize_to_shift(psize);
-}
+	if ((pte_val(pte) & mask) != mask)
+		return 0;
 
-/*
- * Called by asm hashtable.S for doing lazy icache flush
- */
-static unsigned int hash_huge_page_do_lazy_icache(unsigned long rflags,
-					pte_t pte, int trap, unsigned long sz)
-{
-	struct page *page;
-	int i;
+	/* hugepages are never "special" */
+	VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-	if (!pfn_valid(pte_pfn(pte)))
-		return rflags;
+	refs = 0;
+	head = pte_page(pte);
 
-	page = pte_page(pte);
+	page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
+	do {
+		VM_BUG_ON(compound_head(page) != head);
+		pages[*nr] = page;
+		(*nr)++;
+		page++;
+		refs++;
+	} while (addr += PAGE_SIZE, addr != end);
 
-	/* page is dirty */
-	if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
-		if (trap == 0x400) {
-			for (i = 0; i < (sz / PAGE_SIZE); i++)
-				__flush_dcache_icache(page_address(page+i));
-			set_bit(PG_arch_1, &page->flags);
-		} else {
-			rflags |= HPTE_R_N;
+	if (!page_cache_add_speculative(head, refs)) {
+		*nr -= refs;
+		return 0;
+	}
+
+	if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+		/* Could be optimized better */
+		while (*nr) {
+			put_page(page);
+			(*nr)--;
 		}
 	}
-	return rflags;
+
+	return 1;
 }
 
-int hash_huge_page(struct mm_struct *mm, unsigned long access,
-		   unsigned long ea, unsigned long vsid, int local,
-		   unsigned long trap)
+static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
+				      unsigned long sz)
 {
-	pte_t *ptep;
-	unsigned long old_pte, new_pte;
-	unsigned long va, rflags, pa, sz;
-	long slot;
-	int err = 1;
-	int ssize = user_segment_size(ea);
-	unsigned int mmu_psize;
-	int shift;
-	mmu_psize = get_slice_psize(mm, ea);
-
-	if (!mmu_huge_psizes[mmu_psize])
-		goto out;
-	ptep = huge_pte_offset(mm, ea);
-
-	/* Search the Linux page table for a match with va */
-	va = hpt_va(ea, vsid, ssize);
-
-	/*
-	 * If no pte found or not present, send the problem up to
-	 * do_page_fault
-	 */
-	if (unlikely(!ptep || pte_none(*ptep)))
-		goto out;
-
-	/* 
-	 * Check the user's access rights to the page.  If access should be
-	 * prevented then send the problem up to do_page_fault.
-	 */
-	if (unlikely(access & ~pte_val(*ptep)))
-		goto out;
-	/*
-	 * At this point, we have a pte (old_pte) which can be used to build
-	 * or update an HPTE. There are 2 cases:
-	 *
-	 * 1. There is a valid (present) pte with no associated HPTE (this is 
-	 *	the most common case)
-	 * 2. There is a valid (present) pte with an associated HPTE. The
-	 *	current values of the pp bits in the HPTE prevent access
-	 *	because we are doing software DIRTY bit management and the
-	 *	page is currently not DIRTY. 
-	 */
+	unsigned long __boundary = (addr + sz) & ~(sz-1);
+	return (__boundary - 1 < end - 1) ? __boundary : end;
+}
 
+int gup_hugepd(hugepd_t *hugepd, unsigned pdshift,
+	       unsigned long addr, unsigned long end,
+	       int write, struct page **pages, int *nr)
+{
+	pte_t *ptep;
+	unsigned long sz = 1UL << hugepd_shift(*hugepd);
+	unsigned long next;
 
+	ptep = hugepte_offset(hugepd, addr, pdshift);
 	do {
-		old_pte = pte_val(*ptep);
-		if (old_pte & _PAGE_BUSY)
-			goto out;
-		new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
-	} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
-					 old_pte, new_pte));
-
-	rflags = 0x2 | (!(new_pte & _PAGE_RW));
- 	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
-	rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
-	shift = mmu_psize_to_shift(mmu_psize);
-	sz = ((1UL) << shift);
-	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_huge_page_do_lazy_icache(rflags, __pte(old_pte),
-						       trap, sz);
-
-	/* Check if pte already has an hpte (case 2) */
-	if (unlikely(old_pte & _PAGE_HASHPTE)) {
-		/* There MIGHT be an HPTE for this pte */
-		unsigned long hash, slot;
-
-		hash = hpt_hash(va, shift, ssize);
-		if (old_pte & _PAGE_F_SECOND)
-			hash = ~hash;
-		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
-		slot += (old_pte & _PAGE_F_GIX) >> 12;
-
-		if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_psize,
-					 ssize, local) == -1)
-			old_pte &= ~_PAGE_HPTEFLAGS;
-	}
-
-	if (likely(!(old_pte & _PAGE_HASHPTE))) {
-		unsigned long hash = hpt_hash(va, shift, ssize);
-		unsigned long hpte_group;
+		next = hugepte_addr_end(addr, end, sz);
+		if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
+			return 0;
+	} while (ptep++, addr = next, addr != end);
 
-		pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
+	return 1;
+}
 
-repeat:
-		hpte_group = ((hash & htab_hash_mask) *
-			      HPTES_PER_GROUP) & ~0x7UL;
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+					unsigned long len, unsigned long pgoff,
+					unsigned long flags)
+{
+	struct hstate *hstate = hstate_file(file);
+	int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
 
-		/* clear HPTE slot informations in new PTE */
-#ifdef CONFIG_PPC_64K_PAGES
-		new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0;
-#else
-		new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
-#endif
-		/* Add in WIMG bits */
-		rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
-				      _PAGE_COHERENT | _PAGE_GUARDED));
+	return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0);
+}
 
-		/* Insert into the hash table, primary slot */
-		slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0,
-					  mmu_psize, ssize);
+unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
+{
+	unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
 
-		/* 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, va, pa, rflags,
-						  HPTE_V_SECONDARY,
-						  mmu_psize, ssize);
-			if (slot == -1) {
-				if (mftb() & 0x1)
-					hpte_group = ((hash & htab_hash_mask) *
-						      HPTES_PER_GROUP)&~0x7UL;
+	return 1UL << mmu_psize_to_shift(psize);
+}
 
-				ppc_md.hpte_remove(hpte_group);
-				goto repeat;
-                        }
-		}
+static int __init add_huge_page_size(unsigned long long size)
+{
+	int shift = __ffs(size);
+	int mmu_psize;
 
-		if (unlikely(slot == -2))
-			panic("hash_huge_page: pte_insert failed\n");
+	/* Check that it is a page size supported by the hardware and
+	 * that it fits within pagetable and slice limits. */
+	if (!is_power_of_2(size)
+	    || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT))
+		return -EINVAL;
 
-		new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX);
-	}
+	if ((mmu_psize = shift_to_mmu_psize(shift)) < 0)
+		return -EINVAL;
 
-	/*
-	 * No need to use ldarx/stdcx here
+#ifdef CONFIG_SPU_FS_64K_LS
+	/* Disable support for 64K huge pages when 64K SPU local store
+	 * support is enabled as the current implementation conflicts.
 	 */
-	*ptep = __pte(new_pte & ~_PAGE_BUSY);
+	if (shift == PAGE_SHIFT_64K)
+		return -EINVAL;
+#endif /* CONFIG_SPU_FS_64K_LS */
 
-	err = 0;
+	BUG_ON(mmu_psize_defs[mmu_psize].shift != shift);
 
- out:
-	return err;
-}
+	/* Return if huge page size has already been setup */
+	if (size_to_hstate(size))
+		return 0;
 
-static void __init set_huge_psize(int psize)
-{
-	/* Check that it is a page size supported by the hardware and
-	 * that it fits within pagetable limits. */
-	if (mmu_psize_defs[psize].shift &&
-		mmu_psize_defs[psize].shift < SID_SHIFT_1T &&
-		(mmu_psize_defs[psize].shift > MIN_HUGEPTE_SHIFT ||
-		 mmu_psize_defs[psize].shift == PAGE_SHIFT_64K ||
-		 mmu_psize_defs[psize].shift == PAGE_SHIFT_16G)) {
-		/* Return if huge page size has already been setup or is the
-		 * same as the base page size. */
-		if (mmu_huge_psizes[psize] ||
-		   mmu_psize_defs[psize].shift == PAGE_SHIFT)
-			return;
-		if (WARN_ON(HUGEPTE_CACHE_NAME(psize) == NULL))
-			return;
-		hugetlb_add_hstate(mmu_psize_defs[psize].shift - PAGE_SHIFT);
+	hugetlb_add_hstate(shift - PAGE_SHIFT);
 
-		switch (mmu_psize_defs[psize].shift) {
-		case PAGE_SHIFT_64K:
-		    /* We only allow 64k hpages with 4k base page,
-		     * which was checked above, and always put them
-		     * at the PMD */
-		    hugepte_shift[psize] = PMD_SHIFT;
-		    break;
-		case PAGE_SHIFT_16M:
-		    /* 16M pages can be at two different levels
-		     * of pagestables based on base page size */
-		    if (PAGE_SHIFT == PAGE_SHIFT_64K)
-			    hugepte_shift[psize] = PMD_SHIFT;
-		    else /* 4k base page */
-			    hugepte_shift[psize] = PUD_SHIFT;
-		    break;
-		case PAGE_SHIFT_16G:
-		    /* 16G pages are always at PGD level */
-		    hugepte_shift[psize] = PGDIR_SHIFT;
-		    break;
-		}
-		hugepte_shift[psize] -= mmu_psize_defs[psize].shift;
-	} else
-		hugepte_shift[psize] = 0;
+	return 0;
 }
 
 static int __init hugepage_setup_sz(char *str)
 {
 	unsigned long long size;
-	int mmu_psize;
-	int shift;
 
 	size = memparse(str, &str);
 
-	shift = __ffs(size);
-	mmu_psize = shift_to_mmu_psize(shift);
-	if (mmu_psize >= 0 && mmu_psize_defs[mmu_psize].shift)
-		set_huge_psize(mmu_psize);
-	else
+	if (add_huge_page_size(size) != 0)
 		printk(KERN_WARNING "Invalid huge page size specified(%llu)\n", size);
 
 	return 1;
@@ -752,41 +526,55 @@ __setup("hugepagesz=", hugepage_setup_sz
 
 static int __init hugetlbpage_init(void)
 {
-	unsigned int psize;
+	int psize;
 
 	if (!cpu_has_feature(CPU_FTR_16M_PAGE))
 		return -ENODEV;
 
-	/* Add supported huge page sizes.  Need to change HUGE_MAX_HSTATE
-	 * and adjust PTE_NONCACHE_NUM if the number of supported huge page
-	 * sizes changes.
-	 */
-	set_huge_psize(MMU_PAGE_16M);
-	set_huge_psize(MMU_PAGE_16G);
+	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+		unsigned shift;
+		unsigned pdshift;
 
-	/* Temporarily disable support for 64K huge pages when 64K SPU local
-	 * store support is enabled as the current implementation conflicts.
-	 */
-#ifndef CONFIG_SPU_FS_64K_LS
-	set_huge_psize(MMU_PAGE_64K);
-#endif
+		if (!mmu_psize_defs[psize].shift)
+			continue;
 
-	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-		if (mmu_huge_psizes[psize]) {
-			pgtable_cache[HUGE_PGTABLE_INDEX(psize)] =
-				kmem_cache_create(
-					HUGEPTE_CACHE_NAME(psize),
-					HUGEPTE_TABLE_SIZE(psize),
-					HUGEPTE_TABLE_SIZE(psize),
-					0,
-					NULL);
-			if (!pgtable_cache[HUGE_PGTABLE_INDEX(psize)])
-				panic("hugetlbpage_init(): could not create %s"\
-				      "\n", HUGEPTE_CACHE_NAME(psize));
-		}
+		shift = mmu_psize_to_shift(psize);
+
+		if (add_huge_page_size(1ULL << shift) < 0)
+			continue;
+
+		if (shift < PMD_SHIFT)
+			pdshift = PMD_SHIFT;
+		else if (shift < PUD_SHIFT)
+			pdshift = PUD_SHIFT;
+		else
+			pdshift = PGDIR_SHIFT;
+
+		pgtable_cache_add(pdshift - shift, NULL);
+		if (!PGT_CACHE(pdshift - shift))
+			panic("hugetlbpage_init(): could not create "
+			      "pgtable cache for %d bit pagesize\n", shift);
 	}
 
+	/* Set default large page size. Currently, we pick 16M or 1M
+	 * depending on what is available
+	 */
+	if (mmu_psize_defs[MMU_PAGE_16M].shift)
+		HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_16M].shift;
+	else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+		HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_1M].shift;
+
 	return 0;
 }
 
 module_init(hugetlbpage_init);
+
+void flush_dcache_icache_hugepage(struct page *page)
+{
+	int i;
+
+	BUG_ON(!PageCompound(page));
+
+	for (i = 0; i < (1UL << compound_order(page)); i++)
+		__flush_dcache_icache(page_address(page+i));
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/hugetlbpage-hash64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage-hash64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/hugetlbpage-hash64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/hugetlbpage-hash64.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,139 @@
+/*
+ * PPC64 Huge TLB Page Support for hash based MMUs (POWER4 and later)
+ *
+ * Copyright (C) 2003 David Gibson, IBM Corporation.
+ *
+ * Based on the IA-32 version:
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/machdep.h>
+
+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)
+{
+	unsigned long old_pte, new_pte;
+	unsigned long va, rflags, pa, sz;
+	long slot;
+	int err = 1;
+
+	BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
+
+	/* Search the Linux page table for a match with va */
+	va = hpt_va(ea, vsid, ssize);
+
+	/*
+	 * Check the user's access rights to the page.  If access should be
+	 * prevented then send the problem up to do_page_fault.
+	 */
+	if (unlikely(access & ~pte_val(*ptep)))
+		goto out;
+	/*
+	 * At this point, we have a pte (old_pte) which can be used to build
+	 * or update an HPTE. There are 2 cases:
+	 *
+	 * 1. There is a valid (present) pte with no associated HPTE (this is
+	 *	the most common case)
+	 * 2. There is a valid (present) pte with an associated HPTE. The
+	 *	current values of the pp bits in the HPTE prevent access
+	 *	because we are doing software DIRTY bit management and the
+	 *	page is currently not DIRTY.
+	 */
+
+
+	do {
+		old_pte = pte_val(*ptep);
+		if (old_pte & _PAGE_BUSY)
+			goto out;
+		new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
+	} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
+					 old_pte, new_pte));
+
+	rflags = 0x2 | (!(new_pte & _PAGE_RW));
+	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
+	rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
+	sz = ((1UL) << shift);
+	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);
+
+	/* Check if pte already has an hpte (case 2) */
+	if (unlikely(old_pte & _PAGE_HASHPTE)) {
+		/* There MIGHT be an HPTE for this pte */
+		unsigned long hash, slot;
+
+		hash = hpt_hash(va, shift, ssize);
+		if (old_pte & _PAGE_F_SECOND)
+			hash = ~hash;
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		slot += (old_pte & _PAGE_F_GIX) >> 12;
+
+		if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_psize,
+					 ssize, local) == -1)
+			old_pte &= ~_PAGE_HPTEFLAGS;
+	}
+
+	if (likely(!(old_pte & _PAGE_HASHPTE))) {
+		unsigned long hash = hpt_hash(va, shift, ssize);
+		unsigned long hpte_group;
+
+		pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
+
+repeat:
+		hpte_group = ((hash & htab_hash_mask) *
+			      HPTES_PER_GROUP) & ~0x7UL;
+
+		/* clear HPTE slot informations in new PTE */
+#ifdef CONFIG_PPC_64K_PAGES
+		new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0;
+#else
+		new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
+#endif
+		/* Add in WIMG bits */
+		rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
+				      _PAGE_COHERENT | _PAGE_GUARDED));
+
+		/* Insert into the hash table, primary slot */
+		slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0,
+					  mmu_psize, 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, va, pa, rflags,
+						  HPTE_V_SECONDARY,
+						  mmu_psize, 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;
+                        }
+		}
+
+		if (unlikely(slot == -2))
+			panic("hash_huge_page: pte_insert failed\n");
+
+		new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX);
+	}
+
+	/*
+	 * No need to use ldarx/stdcx here
+	 */
+	*ptep = __pte(new_pte & ~_PAGE_BUSY);
+
+	err = 0;
+
+ out:
+	return err;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/init_32.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_32.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/init_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,6 +82,11 @@ extern struct task_struct *current_set[N
 int __map_without_bats;
 int __map_without_ltlbs;
 
+/*
+ * This tells the system to allow ioremapping memory marked as reserved.
+ */
+int __allow_ioremap_reserved;
+
 /* max amount of low RAM to map in */
 unsigned long __max_low_memory = MAX_LOW_MEM;
 
@@ -131,9 +136,13 @@ void __init MMU_init(void)
 	MMU_setup();
 
 	if (lmb.memory.cnt > 1) {
+#ifndef CONFIG_WII
 		lmb.memory.cnt = 1;
 		lmb_analyze();
 		printk(KERN_WARNING "Only using first contiguous memory region");
+#else
+		wii_memory_fixups();
+#endif
 	}
 
 	total_lowmem = total_memory = lmb_end_of_DRAM() - memstart_addr;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/init_64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/init_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/init_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,7 @@
 #include <linux/module.h>
 #include <linux/poison.h>
 #include <linux/lmb.h>
+#include <linux/hugetlb.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
@@ -119,30 +120,63 @@ static void pmd_ctor(void *addr)
 	memset(addr, 0, PMD_TABLE_SIZE);
 }
 
-static const unsigned int pgtable_cache_size[2] = {
-	PGD_TABLE_SIZE, PMD_TABLE_SIZE
-};
-static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
-#ifdef CONFIG_PPC_64K_PAGES
-	"pgd_cache", "pmd_cache",
-#else
-	"pgd_cache", "pud_pmd_cache",
-#endif /* CONFIG_PPC_64K_PAGES */
-};
+struct kmem_cache *pgtable_cache[MAX_PGTABLE_INDEX_SIZE];
+
+/*
+ * Create a kmem_cache() for pagetables.  This is not used for PTE
+ * pages - they're linked to struct page, come from the normal free
+ * pages pool and have a different entry size (see real_pte_t) to
+ * everything else.  Caches created by this function are used for all
+ * the higher level pagetables, and for hugepage pagetables.
+ */
+void pgtable_cache_add(unsigned shift, void (*ctor)(void *))
+{
+	char *name;
+	unsigned long table_size = sizeof(void *) << shift;
+	unsigned long align = table_size;
+
+	/* When batching pgtable pointers for RCU freeing, we store
+	 * the index size in the low bits.  Table alignment must be
+	 * big enough to fit it.
+	 *
+	 * Likewise, hugeapge pagetable pointers contain a (different)
+	 * shift value in the low bits.  All tables must be aligned so
+	 * as to leave enough 0 bits in the address to contain it. */
+	unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1,
+				     HUGEPD_SHIFT_MASK + 1);
+	struct kmem_cache *new;
+
+	/* It would be nice if this was a BUILD_BUG_ON(), but at the
+	 * moment, gcc doesn't seem to recognize is_power_of_2 as a
+	 * constant expression, so so much for that. */
+	BUG_ON(!is_power_of_2(minalign));
+	BUG_ON((shift < 1) || (shift > MAX_PGTABLE_INDEX_SIZE));
+
+	if (PGT_CACHE(shift))
+		return; /* Already have a cache of this size */
+
+	align = max_t(unsigned long, align, minalign);
+	name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift);
+	new = kmem_cache_create(name, table_size, align, 0, ctor);
+	PGT_CACHE(shift) = new;
+
+	pr_debug("Allocated pgtable cache for order %d\n", shift);
+}
 
-#ifdef CONFIG_HUGETLB_PAGE
-/* Hugepages need an extra cache per hugepagesize, initialized in
- * hugetlbpage.c.  We can't put into the tables above, because HPAGE_SHIFT
- * is not compile time constant. */
-struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+MMU_PAGE_COUNT];
-#else
-struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
-#endif
 
 void pgtable_cache_init(void)
 {
-	pgtable_cache[0] = kmem_cache_create(pgtable_cache_name[0], PGD_TABLE_SIZE, PGD_TABLE_SIZE, SLAB_PANIC, pgd_ctor);
-	pgtable_cache[1] = kmem_cache_create(pgtable_cache_name[1], PMD_TABLE_SIZE, PMD_TABLE_SIZE, SLAB_PANIC, pmd_ctor);
+	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))
+		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
+	 * will need re-examiniation if we add new possibilities for
+	 * the pagetable layout. */
+	BUG_ON(PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE));
 }
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/mm/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,10 @@ obj-$(CONFIG_44x)		+= 44x_mmu.o
 obj-$(CONFIG_FSL_BOOKE)		+= fsl_booke_mmu.o
 obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
 obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+ifeq ($(CONFIG_HUGETLB_PAGE),y)
+obj-y				+= hugetlbpage.o
+obj-$(CONFIG_PPC_STD_MMU_64)	+= hugetlbpage-hash64.o
+endif
 obj-$(CONFIG_PPC_SUBPAGE_PROT)	+= subpage-prot.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/mem.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/mem.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/mem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/mem.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <linux/pagemap.h>
 #include <linux/suspend.h>
 #include <linux/lmb.h>
+#include <linux/hugetlb.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -417,18 +418,26 @@ EXPORT_SYMBOL(flush_dcache_page);
 
 void flush_dcache_icache_page(struct page *page)
 {
+#ifdef CONFIG_HUGETLB_PAGE
+	if (PageCompound(page)) {
+		flush_dcache_icache_hugepage(page);
+		return;
+	}
+#endif
 #ifdef CONFIG_BOOKE
-	void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
-	__flush_dcache_icache(start);
-	kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+	{
+		void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
+		__flush_dcache_icache(start);
+		kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+	}
 #elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
 	/* On 8xx there is no need to kmap since highmem is not supported */
 	__flush_dcache_icache(page_address(page)); 
 #else
 	__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
 #endif
-
 }
+
 void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
 	clear_page(page);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmap_64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmap_64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmap_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmap_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ static inline int mmap_is_legacy(void)
 	if (current->personality & ADDR_COMPAT_LAYOUT)
 		return 1;
 
-	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+	if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
 		return 1;
 
 	return sysctl_legacy_va_layout;
@@ -77,7 +77,7 @@ static unsigned long mmap_rnd(void)
 
 static inline unsigned long mmap_base(void)
 {
-	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = rlimit(RLIMIT_STACK);
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_context_hash64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_hash64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_context_hash64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_hash64.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
+#include <linux/module.h>
 
 #include <asm/mmu_context.h>
 
@@ -32,7 +33,7 @@ static DEFINE_IDR(mmu_context_idr);
 #define NO_CONTEXT	0
 #define MAX_CONTEXT	((1UL << 19) - 1)
 
-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+int __init_new_context(void)
 {
 	int index;
 	int err;
@@ -57,22 +58,41 @@ again:
 		return -ENOMEM;
 	}
 
+	return index;
+}
+EXPORT_SYMBOL_GPL(__init_new_context);
+
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	int index;
+
+	index = __init_new_context();
+	if (index < 0)
+		return index;
+
 	/* The old code would re-promote on fork, we don't do that
 	 * when using slices as it could cause problem promoting slices
 	 * that have been forced down to 4K
 	 */
 	if (slice_mm_new_context(mm))
 		slice_set_user_psize(mm, mmu_virtual_psize);
+	subpage_prot_init_new_context(mm);
 	mm->context.id = index;
 
 	return 0;
 }
 
-void destroy_context(struct mm_struct *mm)
+void __destroy_context(int context_id)
 {
 	spin_lock(&mmu_context_lock);
-	idr_remove(&mmu_context_idr, mm->context.id);
+	idr_remove(&mmu_context_idr, context_id);
 	spin_unlock(&mmu_context_lock);
+}
+EXPORT_SYMBOL_GPL(__destroy_context);
 
+void destroy_context(struct mm_struct *mm)
+{
+	__destroy_context(mm->context.id);
+	subpage_prot_free(mm);
 	mm->context.id = NO_CONTEXT;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_context_nohash.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_nohash.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2010-02-24 13:52:17.000000000 -0500
@@ -353,7 +353,7 @@ static int __cpuinit mmu_context_cpu_not
 		read_lock(&tasklist_lock);
 		for_each_process(p) {
 			if (p->mm)
-				cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm));
+				cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
 		}
 		read_unlock(&tasklist_lock);
 	break;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_decl.h linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_decl.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/mmu_decl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/mmu_decl.h	2010-02-24 13:52:17.000000000 -0500
@@ -98,23 +98,13 @@ extern void _tlbia(void);
 
 #ifdef CONFIG_PPC32
 
-struct tlbcam {
-	u32	MAS0;
-	u32	MAS1;
-	u32	MAS2;
-	u32	MAS3;
-	u32	MAS7;
-};
-
 extern void mapin_ram(void);
 extern int map_page(unsigned long va, phys_addr_t pa, int flags);
 extern void setbat(int index, unsigned long virt, phys_addr_t phys,
 		   unsigned int size, int flags);
-extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
-		      unsigned int size, int flags, unsigned int pid);
-extern void invalidate_tlbcam_entry(int index);
 
 extern int __map_without_bats;
+extern int __allow_ioremap_reserved;
 extern unsigned long ioremap_base;
 extern unsigned int rtas_data, rtas_size;
 
@@ -136,24 +126,32 @@ extern phys_addr_t total_lowmem;
 extern phys_addr_t memstart_addr;
 extern phys_addr_t lowmem_end_addr;
 
+#ifdef CONFIG_WII
+extern unsigned long wii_hole_start;
+extern unsigned long wii_hole_size;
+
+extern unsigned long wii_mmu_mapin_mem2(unsigned long top);
+extern void wii_memory_fixups(void);
+#endif
+
 /* ...and now those things that may be slightly different between processor
  * architectures.  -- Dan
  */
 #if defined(CONFIG_8xx)
 #define MMU_init_hw()		do { } while(0)
-#define mmu_mapin_ram()		(0UL)
+#define mmu_mapin_ram(top)	(0UL)
 
 #elif defined(CONFIG_4xx)
 extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(void);
+extern unsigned long mmu_mapin_ram(unsigned long top);
 
 #elif defined(CONFIG_FSL_BOOKE)
 extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(void);
+extern unsigned long mmu_mapin_ram(unsigned long top);
 extern void adjust_total_lowmem(void);
 
 #elif defined(CONFIG_PPC32)
 /* anything 32-bit except 4xx or 8xx */
 extern void MMU_init_hw(void);
-extern unsigned long mmu_mapin_ram(void);
+extern unsigned long mmu_mapin_ram(unsigned long top);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/pgtable_32.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_32.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/pgtable_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -191,7 +192,8 @@ __ioremap_caller(phys_addr_t addr, unsig
 	 * Don't allow anybody to remap normal RAM that we're using.
 	 * mem_init() sets high_memory so only do the check after that.
 	 */
-	if (mem_init_done && (p < virt_to_phys(high_memory))) {
+	if (mem_init_done && (p < virt_to_phys(high_memory)) &&
+	    !(__allow_ioremap_reserved && lmb_is_region_reserved(p, size))) {
 		printk("__ioremap(): phys addr 0x%llx is RAM lr %p\n",
 		       (unsigned long long)p, __builtin_return_address(0));
 		return NULL;
@@ -283,18 +285,18 @@ int map_page(unsigned long va, phys_addr
 }
 
 /*
- * Map in a big chunk of physical memory starting at PAGE_OFFSET.
+ * Map in a chunk of physical memory starting at start.
  */
-void __init mapin_ram(void)
+void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
 {
 	unsigned long v, s, f;
 	phys_addr_t p;
 	int ktext;
 
-	s = mmu_mapin_ram();
+	s = offset;
 	v = PAGE_OFFSET + s;
 	p = memstart_addr + s;
-	for (; s < total_lowmem; s += PAGE_SIZE) {
+	for (; s < top; s += PAGE_SIZE) {
 		ktext = ((char *) v >= _stext && (char *) v < etext);
 		f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL;
 		map_page(v, p, f);
@@ -307,6 +309,30 @@ void __init mapin_ram(void)
 	}
 }
 
+void __init mapin_ram(void)
+{
+	unsigned long s, top;
+
+#ifndef CONFIG_WII
+	top = total_lowmem;
+	s = mmu_mapin_ram(top);
+	__mapin_ram_chunk(s, top);
+#else
+	if (!wii_hole_size) {
+		s = mmu_mapin_ram(total_lowmem);
+		__mapin_ram_chunk(s, total_lowmem);
+	} else {
+		top = wii_hole_start;
+		s = mmu_mapin_ram(top);
+		__mapin_ram_chunk(s, top);
+
+		top = lmb_end_of_DRAM();
+		s = wii_mmu_mapin_mem2(top);
+		__mapin_ram_chunk(s, top);
+	}
+#endif
+}
+
 /* Scan the real Linux page tables and return a PTE pointer for
  * a virtual address in a context.
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
@@ -356,7 +382,7 @@ static int __change_page_attr(struct pag
 		return 0;
 	if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
 		return -EINVAL;
-	set_pte_at(&init_mm, address, kpte, mk_pte(page, prot));
+	__set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
 	wmb();
 #ifdef CONFIG_PPC_STD_MMU
 	flush_hash_pages(0, address, pmd_val(*kpmd), 1);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/pgtable.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/pgtable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,12 +49,12 @@ struct pte_freelist_batch
 {
 	struct rcu_head	rcu;
 	unsigned int	index;
-	pgtable_free_t	tables[0];
+	unsigned long	tables[0];
 };
 
 #define PTE_FREELIST_SIZE \
 	((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
-	  / sizeof(pgtable_free_t))
+	  / sizeof(unsigned long))
 
 static void pte_free_smp_sync(void *arg)
 {
@@ -64,13 +64,13 @@ static void pte_free_smp_sync(void *arg)
 /* This is only called when we are critically out of memory
  * (and fail to get a page in pte_free_tlb).
  */
-static void pgtable_free_now(pgtable_free_t pgf)
+static void pgtable_free_now(void *table, unsigned shift)
 {
 	pte_freelist_forced_free++;
 
 	smp_call_function(pte_free_smp_sync, NULL, 1);
 
-	pgtable_free(pgf);
+	pgtable_free(table, shift);
 }
 
 static void pte_free_rcu_callback(struct rcu_head *head)
@@ -79,8 +79,12 @@ static void pte_free_rcu_callback(struct
 		container_of(head, struct pte_freelist_batch, rcu);
 	unsigned int i;
 
-	for (i = 0; i < batch->index; i++)
-		pgtable_free(batch->tables[i]);
+	for (i = 0; i < batch->index; i++) {
+		void *table = (void *)(batch->tables[i] & ~MAX_PGTABLE_INDEX_SIZE);
+		unsigned shift = batch->tables[i] & MAX_PGTABLE_INDEX_SIZE;
+
+		pgtable_free(table, shift);
+	}
 
 	free_page((unsigned long)batch);
 }
@@ -91,25 +95,28 @@ static void pte_free_submit(struct pte_f
 	call_rcu(&batch->rcu, pte_free_rcu_callback);
 }
 
-void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
+void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
 {
 	/* This is safe since tlb_gather_mmu has disabled preemption */
 	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+	unsigned long pgf;
 
 	if (atomic_read(&tlb->mm->mm_users) < 2 ||
 	    cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))){
-		pgtable_free(pgf);
+		pgtable_free(table, shift);
 		return;
 	}
 
 	if (*batchp == NULL) {
 		*batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
 		if (*batchp == NULL) {
-			pgtable_free_now(pgf);
+			pgtable_free_now(table, shift);
 			return;
 		}
 		(*batchp)->index = 0;
 	}
+	BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
+	pgf = (unsigned long)table | shift;
 	(*batchp)->tables[(*batchp)->index++] = pgf;
 	if ((*batchp)->index == PTE_FREELIST_SIZE) {
 		pte_free_submit(*batchp);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/ppc_mmu_32.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/ppc_mmu_32.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/ppc_mmu_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/ppc_mmu_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,7 +72,7 @@ unsigned long p_mapped_by_bats(phys_addr
 	return 0;
 }
 
-unsigned long __init mmu_mapin_ram(void)
+unsigned long __init mmu_mapin_ram(unsigned long top)
 {
 	unsigned long tot, bl, done;
 	unsigned long max_size = (256<<20);
@@ -86,7 +86,7 @@ unsigned long __init mmu_mapin_ram(void)
 
 	/* Make sure we don't map a block larger than the
 	   smallest alignment of the physical address. */
-	tot = total_lowmem;
+	tot = top;
 	for (bl = 128<<10; bl < max_size; bl <<= 1) {
 		if (bl * 2 > tot)
 			break;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/subpage-prot.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/subpage-prot.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/subpage-prot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/subpage-prot.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,9 +24,9 @@
  * Also makes sure that the subpage_prot_table structure is
  * reinitialized for the next user.
  */
-void subpage_prot_free(pgd_t *pgd)
+void subpage_prot_free(struct mm_struct *mm)
 {
-	struct subpage_prot_table *spt = pgd_subpage_prot(pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	unsigned long i, j, addr;
 	u32 **p;
 
@@ -51,6 +51,13 @@ void subpage_prot_free(pgd_t *pgd)
 	spt->maxaddr = 0;
 }
 
+void subpage_prot_init_new_context(struct mm_struct *mm)
+{
+	struct subpage_prot_table *spt = &mm->context.spt;
+
+	memset(spt, 0, sizeof(*spt));
+}
+
 static void hpte_flush_range(struct mm_struct *mm, unsigned long addr,
 			     int npages)
 {
@@ -87,7 +94,7 @@ static void hpte_flush_range(struct mm_s
 static void subpage_prot_clear(unsigned long addr, unsigned long len)
 {
 	struct mm_struct *mm = current->mm;
-	struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 **spm, *spp;
 	int i, nw;
 	unsigned long next, limit;
@@ -136,7 +143,7 @@ static void subpage_prot_clear(unsigned
 long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
 {
 	struct mm_struct *mm = current->mm;
-	struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
+	struct subpage_prot_table *spt = &mm->context.spt;
 	u32 **spm, *spp;
 	int i, nw;
 	unsigned long next, limit;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/mm/tlb_hash64.c linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_hash64.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/mm/tlb_hash64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/mm/tlb_hash64.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,11 +53,6 @@ void hpte_need_flush(struct mm_struct *m
 
 	i = batch->index;
 
-	/* We mask the address for the base page size. Huge pages will
-	 * have applied their own masking already
-	 */
-	addr &= PAGE_MASK;
-
 	/* Get page size (maybe move back to caller).
 	 *
 	 * NOTE: when using special 64K mappings in 4K environment like
@@ -68,12 +63,21 @@ void hpte_need_flush(struct mm_struct *m
 	if (huge) {
 #ifdef CONFIG_HUGETLB_PAGE
 		psize = get_slice_psize(mm, addr);
+		/* Mask the address for the correct page size */
+		addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1);
 #else
 		BUG();
 		psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
 #endif
-	} else
+	} else {
 		psize = pte_pagesize_index(mm, addr, pte);
+		/* Mask the address for the standard page size.  If we
+		 * have a 64k page kernel, but the hardware does not
+		 * support 64k pages, this might be different from the
+		 * hardware page size encoded in the slice table. */
+		addr &= PAGE_MASK;
+	}
+
 
 	/* Build full vaddr */
 	if (!is_kernel_addr(addr)) {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/oprofile/op_model_cell.c linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/op_model_cell.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/oprofile/op_model_cell.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/oprofile/op_model_cell.c	2010-02-24 13:52:17.000000000 -0500
@@ -248,7 +248,7 @@ static int pm_rtas_activate_signals(u32
 	 * There is no debug setup required for the cycles event.
 	 * Note that only events in the same group can be used.
 	 * Otherwise, there will be conflicts in correctly routing
-	 * the signals on the debug bus.  It is the responsiblity
+	 * the signals on the debug bus.  It is the responsibility
 	 * of the OProfile user tool to check the events are in
 	 * the same group.
 	 */
@@ -1594,7 +1594,7 @@ static void cell_handle_interrupt_spu(st
 		 * to a latch.  The new values (interrupt setting bits, reset
 		 * counter value etc.) are not copied to the actual registers
 		 * until the performance monitor is enabled.  In order to get
-		 * this to work as desired, the permormance monitor needs to
+		 * this to work as desired, the performance monitor needs to
 		 * be disabled while writing to the latches.  This is a
 		 * HW design issue.
 		 */
@@ -1668,7 +1668,7 @@ static void cell_handle_interrupt_ppu(st
 		 * to a latch.	The new values (interrupt setting bits, reset
 		 * counter value etc.) are not copied to the actual registers
 		 * until the performance monitor is enabled.  In order to get
-		 * this to work as desired, the permormance monitor needs to
+		 * this to work as desired, the performance monitor needs to
 		 * be disabled while writing to the latches.  This is a
 		 * HW design issue.
 		 */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq)
 }
 
 static struct irq_chip cpld_pic = {
-	.typename = " CPLD PIC ",
+	.name = " CPLD PIC ",
 	.mask = cpld_mask_irq,
 	.ack = cpld_mask_irq,
 	.unmask = cpld_unmask_irq,
@@ -132,7 +132,7 @@ static int
 cpld_pic_host_map(struct irq_host *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/efika.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/efika.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/efika.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/efika.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/pci.h>
 #include <linux/of.h>
 #include <asm/prom.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -62,3 +62,8 @@ config PPC_MPC5200_GPIO
 	select GENERIC_GPIO
 	help
 	  Enable gpiolib support for mpc5200 based boards
+
+config PPC_MPC5200_LPBFIFO
+	tristate "MPC5200 LocalPlus bus FIFO driver"
+	depends on PPC_MPC52xx
+	select PPC_BESTCOMM_GEN_BD
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,3 +15,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y)
 endif
 
 obj-$(CONFIG_PPC_MPC5200_GPIO)	+= mpc52xx_gpio.o
+obj-$(CONFIG_PPC_MPC5200_LPBFIFO)	+= mpc52xx_lpbfifo.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/media5200.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/media5200.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/media5200.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/media5200.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ static void media5200_irq_mask(unsigned
 }
 
 static struct irq_chip media5200_irq_chip = {
-	.typename = "Media5200 FPGA",
+	.name = "Media5200 FPGA",
 	.unmask = media5200_irq_unmask,
 	.mask = media5200_irq_mask,
 	.mask_ack = media5200_irq_mask,
@@ -86,9 +86,9 @@ void media5200_irq_cascade(unsigned int
 	u32 status, enable;
 
 	/* Mask off the cascaded IRQ */
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	desc->chip->mask(virq);
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 
 	/* Ask the FPGA for IRQ status.  If 'val' is 0, then no irqs
 	 * are pending.  'ffs()' is 1 based */
@@ -104,17 +104,17 @@ void media5200_irq_cascade(unsigned int
 	}
 
 	/* Processing done; can reenable the cascade now */
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	desc->chip->ack(virq);
 	if (!(desc->status & IRQ_DISABLED))
 		desc->chip->unmask(virq);
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 }
 
 static int media5200_irq_map(struct irq_host *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 
 	pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
 	set_irq_chip_data(virq, &media5200_irq);
@@ -127,7 +127,7 @@ static int media5200_irq_map(struct irq_
 }
 
 static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
-				 u32 *intspec, unsigned int intsize,
+				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,8 +16,14 @@
  * output signals or measure input signals.
  *
  * This driver supports the GPIO and IRQ controller functions of the GPT
- * device.  Timer functions are not yet supported, nor is the watchdog
- * timer.
+ * device.  Timer functions are not yet supported.
+ *
+ * The timer gpt0 can be used as watchdog (wdt).  If the wdt mode is used,
+ * this prevents the use of any gpt0 gpt function (i.e. they will fail with
+ * -EBUSY).  Thus, the safety wdt function always has precedence over the gpt
+ * function.  If the kernel has been compiled with CONFIG_WATCHDOG_NOWAYOUT,
+ * this means that gpt0 is locked in wdt mode until the next reboot - this
+ * may be a requirement in safety applications.
  *
  * To use the GPIO function, the following two properties must be added
  * to the device tree node for the gpt device (typically in the .dts file
@@ -46,17 +52,24 @@
  * the output mode.  This driver does not change the output mode setting.
  */
 
+#include <linux/device.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/kernel.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <asm/div64.h>
 #include <asm/mpc52xx.h>
 
 MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
-MODULE_AUTHOR("Sascha Hauer, Grant Likely");
+MODULE_AUTHOR("Sascha Hauer, Grant Likely, Albrecht Dreß");
 MODULE_LICENSE("GPL");
 
 /**
@@ -66,18 +79,27 @@ MODULE_LICENSE("GPL");
  * @lock: spinlock to coordinate between different functions.
  * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
  * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
+ * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
+ *   if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
+ *   if the timer is actively used as wdt which blocks gpt functions
  */
 struct mpc52xx_gpt_priv {
+	struct list_head list;		/* List of all GPT devices */
 	struct device *dev;
 	struct mpc52xx_gpt __iomem *regs;
 	spinlock_t lock;
 	struct irq_host *irqhost;
+	u32 ipb_freq;
+	u8 wdt_mode;
 
 #if defined(CONFIG_GPIOLIB)
 	struct of_gpio_chip of_gc;
 #endif
 };
 
+LIST_HEAD(mpc52xx_gpt_list);
+DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
+
 #define MPC52xx_GPT_MODE_MS_MASK	(0x07)
 #define MPC52xx_GPT_MODE_MS_IC		(0x01)
 #define MPC52xx_GPT_MODE_MS_OC		(0x02)
@@ -88,15 +110,25 @@ struct mpc52xx_gpt_priv {
 #define MPC52xx_GPT_MODE_GPIO_OUT_LOW	(0x20)
 #define MPC52xx_GPT_MODE_GPIO_OUT_HIGH	(0x30)
 
+#define MPC52xx_GPT_MODE_COUNTER_ENABLE	(0x1000)
+#define MPC52xx_GPT_MODE_CONTINUOUS	(0x0400)
+#define MPC52xx_GPT_MODE_OPEN_DRAIN	(0x0200)
 #define MPC52xx_GPT_MODE_IRQ_EN		(0x0100)
+#define MPC52xx_GPT_MODE_WDT_EN		(0x8000)
 
 #define MPC52xx_GPT_MODE_ICT_MASK	(0x030000)
 #define MPC52xx_GPT_MODE_ICT_RISING	(0x010000)
 #define MPC52xx_GPT_MODE_ICT_FALLING	(0x020000)
 #define MPC52xx_GPT_MODE_ICT_TOGGLE	(0x030000)
 
+#define MPC52xx_GPT_MODE_WDT_PING	(0xa5)
+
 #define MPC52xx_GPT_STATUS_IRQMASK	(0x000f)
 
+#define MPC52xx_GPT_CAN_WDT		(1 << 0)
+#define MPC52xx_GPT_IS_WDT		(1 << 1)
+
+
 /* ---------------------------------------------------------------------
  * Cascaded interrupt controller hooks
  */
@@ -149,7 +181,7 @@ static int mpc52xx_gpt_irq_set_type(unsi
 }
 
 static struct irq_chip mpc52xx_gpt_irq_chip = {
-	.typename = "MPC52xx GPT",
+	.name = "MPC52xx GPT",
 	.unmask = mpc52xx_gpt_irq_unmask,
 	.mask = mpc52xx_gpt_irq_mask,
 	.ack = mpc52xx_gpt_irq_ack,
@@ -182,7 +214,7 @@ static int mpc52xx_gpt_irq_map(struct ir
 }
 
 static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
-				 u32 *intspec, unsigned int intsize,
+				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
 {
@@ -190,7 +222,7 @@ static int mpc52xx_gpt_irq_xlate(struct
 
 	dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
 
-	if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) {
+	if ((intsize < 1) || (intspec[0] > 3)) {
 		dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name);
 		return -EINVAL;
 	}
@@ -211,13 +243,11 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt
 {
 	int cascade_virq;
 	unsigned long flags;
-
-	/* Only setup cascaded IRQ if device tree claims the GPT is
-	 * an interrupt controller */
-	if (!of_find_property(node, "interrupt-controller", NULL))
-		return;
+	u32 mode;
 
 	cascade_virq = irq_of_parse_and_map(node, 0);
+	if (!cascade_virq)
+		return;
 
 	gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
 				      &mpc52xx_gpt_irq_ops, -1);
@@ -227,14 +257,16 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt
 	}
 
 	gpt->irqhost->host_data = gpt;
-
 	set_irq_data(cascade_virq, gpt);
 	set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
 
-	/* Set to Input Capture mode */
+	/* If the GPT is currently disabled, then change it to be in Input
+	 * Capture mode.  If the mode is non-zero, then the pin could be
+	 * already in use for something. */
 	spin_lock_irqsave(&gpt->lock, flags);
-	clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
-			MPC52xx_GPT_MODE_MS_IC);
+	mode = in_be32(&gpt->regs->mode);
+	if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
+		out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
 	spin_unlock_irqrestore(&gpt->lock, flags);
 
 	dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
@@ -335,6 +367,354 @@ static void
 mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { }
 #endif /* defined(CONFIG_GPIOLIB) */
 
+/***********************************************************************
+ * Timer API
+ */
+
+/**
+ * mpc52xx_gpt_from_irq - Return the GPT device associated with an IRQ number
+ * @irq: irq of timer.
+ */
+struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq)
+{
+	struct mpc52xx_gpt_priv *gpt;
+	struct list_head *pos;
+
+	/* Iterate over the list of timers looking for a matching device */
+	mutex_lock(&mpc52xx_gpt_list_mutex);
+	list_for_each(pos, &mpc52xx_gpt_list) {
+		gpt = container_of(pos, struct mpc52xx_gpt_priv, list);
+		if (gpt->irqhost && irq == irq_linear_revmap(gpt->irqhost, 0)) {
+			mutex_unlock(&mpc52xx_gpt_list_mutex);
+			return gpt;
+		}
+	}
+	mutex_unlock(&mpc52xx_gpt_list_mutex);
+
+	return NULL;
+}
+EXPORT_SYMBOL(mpc52xx_gpt_from_irq);
+
+static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
+				int continuous, int as_wdt)
+{
+	u32 clear, set;
+	u64 clocks;
+	u32 prescale;
+	unsigned long flags;
+
+	clear = MPC52xx_GPT_MODE_MS_MASK | MPC52xx_GPT_MODE_CONTINUOUS;
+	set = MPC52xx_GPT_MODE_MS_GPIO | MPC52xx_GPT_MODE_COUNTER_ENABLE;
+	if (as_wdt) {
+		clear |= MPC52xx_GPT_MODE_IRQ_EN;
+		set |= MPC52xx_GPT_MODE_WDT_EN;
+	} else if (continuous)
+		set |= MPC52xx_GPT_MODE_CONTINUOUS;
+
+	/* Determine the number of clocks in the requested period.  64 bit
+	 * arithmatic is done here to preserve the precision until the value
+	 * is scaled back down into the u32 range.  Period is in 'ns', bus
+	 * frequency is in Hz. */
+	clocks = period * (u64)gpt->ipb_freq;
+	do_div(clocks, 1000000000); /* Scale it down to ns range */
+
+	/* This device cannot handle a clock count greater than 32 bits */
+	if (clocks > 0xffffffff)
+		return -EINVAL;
+
+	/* Calculate the prescaler and count values from the clocks value.
+	 * 'clocks' is the number of clock ticks in the period.  The timer
+	 * has 16 bit precision and a 16 bit prescaler.  Prescaler is
+	 * calculated by integer dividing the clocks by 0x10000 (shifting
+	 * down 16 bits) to obtain the smallest possible divisor for clocks
+	 * to get a 16 bit count value.
+	 *
+	 * Note: the prescale register is '1' based, not '0' based.  ie. a
+	 * value of '1' means divide the clock by one.  0xffff divides the
+	 * clock by 0xffff.  '0x0000' does not divide by zero, but wraps
+	 * around and divides by 0x10000.  That is why prescale must be
+	 * a u32 variable, not a u16, for this calculation. */
+	prescale = (clocks >> 16) + 1;
+	do_div(clocks, prescale);
+	if (clocks > 0xffff) {
+		pr_err("calculation error; prescale:%x clocks:%llx\n",
+		       prescale, clocks);
+		return -EINVAL;
+	}
+
+	/* Set and enable the timer, reject an attempt to use a wdt as gpt */
+	spin_lock_irqsave(&gpt->lock, flags);
+	if (as_wdt)
+		gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
+	else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
+		spin_unlock_irqrestore(&gpt->lock, flags);
+		return -EBUSY;
+	}
+	out_be32(&gpt->regs->count, prescale << 16 | clocks);
+	clrsetbits_be32(&gpt->regs->mode, clear, set);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+
+	return 0;
+}
+
+/**
+ * mpc52xx_gpt_start_timer - Set and enable the GPT timer
+ * @gpt: Pointer to gpt private data structure
+ * @period: period of timer in ns; max. ~130s @ 33MHz IPB clock
+ * @continuous: set to 1 to make timer continuous free running
+ *
+ * An interrupt will be generated every time the timer fires
+ */
+int mpc52xx_gpt_start_timer(struct mpc52xx_gpt_priv *gpt, u64 period,
+                            int continuous)
+{
+	return mpc52xx_gpt_do_start(gpt, period, continuous, 0);
+}
+EXPORT_SYMBOL(mpc52xx_gpt_start_timer);
+
+/**
+ * mpc52xx_gpt_stop_timer - Stop a gpt
+ * @gpt: Pointer to gpt private data structure
+ *
+ * Returns an error if attempting to stop a wdt
+ */
+int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
+{
+	unsigned long flags;
+
+	/* reject the operation if the timer is used as watchdog (gpt 0 only) */
+	spin_lock_irqsave(&gpt->lock, flags);
+	if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
+		spin_unlock_irqrestore(&gpt->lock, flags);
+		return -EBUSY;
+	}
+
+	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
+
+/**
+ * mpc52xx_gpt_timer_period - Read the timer period
+ * @gpt: Pointer to gpt private data structure
+ *
+ * Returns the timer period in ns
+ */
+u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
+{
+	u64 period;
+	u64 prescale;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	period = in_be32(&gpt->regs->count);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+
+	prescale = period >> 16;
+	period &= 0xffff;
+	if (prescale == 0)
+		prescale = 0x10000;
+	period = period * prescale * 1000000000ULL;
+	do_div(period, (u64)gpt->ipb_freq);
+	return period;
+}
+EXPORT_SYMBOL(mpc52xx_gpt_timer_period);
+
+#if defined(CONFIG_MPC5200_WDT)
+/***********************************************************************
+ * Watchdog API for gpt0
+ */
+
+#define WDT_IDENTITY	    "mpc52xx watchdog on GPT0"
+
+/* wdt_is_active stores wether or not the /dev/watchdog device is opened */
+static unsigned long wdt_is_active;
+
+/* wdt-capable gpt */
+static struct mpc52xx_gpt_priv *mpc52xx_gpt_wdt;
+
+/* low-level wdt functions */
+static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpt_wdt->lock, flags);
+	out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
+	spin_unlock_irqrestore(&gpt_wdt->lock, flags);
+}
+
+/* wdt misc device api */
+static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
+				 size_t len, loff_t *ppos)
+{
+	struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
+	mpc52xx_gpt_wdt_ping(gpt_wdt);
+	return 0;
+}
+
+static struct watchdog_info mpc5200_wdt_info = {
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+	.identity	= WDT_IDENTITY,
+};
+
+static long mpc52xx_wdt_ioctl(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
+	int __user *data = (int __user *)arg;
+	int timeout;
+	u64 real_timeout;
+	int ret = 0;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user(data, &mpc5200_wdt_info,
+				   sizeof(mpc5200_wdt_info));
+		if (ret)
+			ret = -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(0, data);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		mpc52xx_gpt_wdt_ping(gpt_wdt);
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(timeout, data);
+		if (ret)
+			break;
+		real_timeout = (u64) timeout * 1000000000ULL;
+		ret = mpc52xx_gpt_do_start(gpt_wdt, real_timeout, 0, 1);
+		if (ret)
+			break;
+		/* fall through and return the timeout */
+
+	case WDIOC_GETTIMEOUT:
+		/* we need to round here as to avoid e.g. the following
+		 * situation:
+		 * - timeout requested is 1 second;
+		 * - real timeout @33MHz is 999997090ns
+		 * - the int divide by 10^9 will return 0.
+		 */
+		real_timeout =
+			mpc52xx_gpt_timer_period(gpt_wdt) + 500000000ULL;
+		do_div(real_timeout, 1000000000ULL);
+		timeout = (int) real_timeout;
+		ret = put_user(timeout, data);
+		break;
+
+	default:
+		ret = -ENOTTY;
+	}
+	return ret;
+}
+
+static int mpc52xx_wdt_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	/* sanity check */
+	if (!mpc52xx_gpt_wdt)
+		return -ENODEV;
+
+	/* /dev/watchdog can only be opened once */
+	if (test_and_set_bit(0, &wdt_is_active))
+		return -EBUSY;
+
+	/* Set and activate the watchdog with 30 seconds timeout */
+	ret = mpc52xx_gpt_do_start(mpc52xx_gpt_wdt, 30ULL * 1000000000ULL,
+				   0, 1);
+	if (ret) {
+		clear_bit(0, &wdt_is_active);
+		return ret;
+	}
+
+	file->private_data = mpc52xx_gpt_wdt;
+	return nonseekable_open(inode, file);
+}
+
+static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
+{
+	/* note: releasing the wdt in NOWAYOUT-mode does not stop it */
+#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
+	struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpt_wdt->lock, flags);
+	clrbits32(&gpt_wdt->regs->mode,
+		  MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
+	gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
+	spin_unlock_irqrestore(&gpt_wdt->lock, flags);
+#endif
+	clear_bit(0, &wdt_is_active);
+	return 0;
+}
+
+
+static const struct file_operations mpc52xx_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= mpc52xx_wdt_write,
+	.unlocked_ioctl = mpc52xx_wdt_ioctl,
+	.open		= mpc52xx_wdt_open,
+	.release	= mpc52xx_wdt_release,
+};
+
+static struct miscdevice mpc52xx_wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &mpc52xx_wdt_fops,
+};
+
+static int __devinit mpc52xx_gpt_wdt_init(void)
+{
+	int err;
+
+	/* try to register the watchdog misc device */
+	err = misc_register(&mpc52xx_wdt_miscdev);
+	if (err)
+		pr_err("%s: cannot register watchdog device\n", WDT_IDENTITY);
+	else
+		pr_info("%s: watchdog device registered\n", WDT_IDENTITY);
+	return err;
+}
+
+static int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
+				 const u32 *period)
+{
+	u64 real_timeout;
+
+	/* remember the gpt for the wdt operation */
+	mpc52xx_gpt_wdt = gpt;
+
+	/* configure the wdt if the device tree contained a timeout */
+	if (!period || *period == 0)
+		return 0;
+
+	real_timeout = (u64) *period * 1000000000ULL;
+	if (mpc52xx_gpt_do_start(gpt, real_timeout, 0, 1))
+		dev_warn(gpt->dev, "starting as wdt failed\n");
+	else
+		dev_info(gpt->dev, "watchdog set to %us timeout\n", *period);
+	return 0;
+}
+
+#else
+
+static int __devinit mpc52xx_gpt_wdt_init(void)
+{
+	return 0;
+}
+
+#define mpc52xx_gpt_wdt_setup(x, y)		(0)
+
+#endif	/*  CONFIG_MPC5200_WDT	*/
+
 /* ---------------------------------------------------------------------
  * of_platform bus binding code
  */
@@ -349,6 +729,7 @@ static int __devinit mpc52xx_gpt_probe(s
 
 	spin_lock_init(&gpt->lock);
 	gpt->dev = &ofdev->dev;
+	gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node);
 	gpt->regs = of_iomap(ofdev->node, 0);
 	if (!gpt->regs) {
 		kfree(gpt);
@@ -360,6 +741,26 @@ static int __devinit mpc52xx_gpt_probe(s
 	mpc52xx_gpt_gpio_setup(gpt, ofdev->node);
 	mpc52xx_gpt_irq_setup(gpt, ofdev->node);
 
+	mutex_lock(&mpc52xx_gpt_list_mutex);
+	list_add(&gpt->list, &mpc52xx_gpt_list);
+	mutex_unlock(&mpc52xx_gpt_list_mutex);
+
+	/* check if this device could be a watchdog */
+	if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) ||
+	    of_get_property(ofdev->node, "has-wdt", NULL)) {
+		const u32 *on_boot_wdt;
+
+		gpt->wdt_mode = MPC52xx_GPT_CAN_WDT;
+		on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot",
+					      NULL);
+		if (on_boot_wdt) {
+			dev_info(gpt->dev, "used as watchdog\n");
+			gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
+		} else
+			dev_info(gpt->dev, "can function as watchdog\n");
+		mpc52xx_gpt_wdt_setup(gpt, on_boot_wdt);
+	}
+
 	return 0;
 }
 
@@ -394,3 +795,4 @@ static int __init mpc52xx_gpt_init(void)
 
 /* Make sure GPIOs and IRQs get set up before anyone tries to use them */
 subsys_initcall(mpc52xx_gpt_init);
+device_initcall(mpc52xx_gpt_wdt_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,560 @@
+/*
+ * LocalPlus Bus FIFO driver for the Freescale MPC52xx.
+ *
+ * Copyright (C) 2009 Secret Lab Technologies Ltd.
+ *
+ * This file is released under the GPLv2
+ *
+ * Todo:
+ * - Add support for multiple requests to be queued.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/mpc52xx.h>
+#include <asm/time.h>
+
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/bestcomm_priv.h>
+#include <sysdev/bestcomm/gen_bd.h>
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
+MODULE_LICENSE("GPL");
+
+#define LPBFIFO_REG_PACKET_SIZE		(0x00)
+#define LPBFIFO_REG_START_ADDRESS	(0x04)
+#define LPBFIFO_REG_CONTROL		(0x08)
+#define LPBFIFO_REG_ENABLE		(0x0C)
+#define LPBFIFO_REG_BYTES_DONE_STATUS	(0x14)
+#define LPBFIFO_REG_FIFO_DATA		(0x40)
+#define LPBFIFO_REG_FIFO_STATUS		(0x44)
+#define LPBFIFO_REG_FIFO_CONTROL	(0x48)
+#define LPBFIFO_REG_FIFO_ALARM		(0x4C)
+
+struct mpc52xx_lpbfifo {
+	struct device *dev;
+	phys_addr_t regs_phys;
+	void __iomem *regs;
+	int irq;
+	spinlock_t lock;
+
+	struct bcom_task *bcom_tx_task;
+	struct bcom_task *bcom_rx_task;
+	struct bcom_task *bcom_cur_task;
+
+	/* Current state data */
+	struct mpc52xx_lpbfifo_request *req;
+	int dma_irqs_enabled;
+};
+
+/* The MPC5200 has only one fifo, so only need one instance structure */
+static struct mpc52xx_lpbfifo lpbfifo;
+
+/**
+ * mpc52xx_lpbfifo_kick - Trigger the next block of data to be transfered
+ */
+static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
+{
+	size_t transfer_size = req->size - req->pos;
+	struct bcom_bd *bd;
+	void __iomem *reg;
+	u32 *data;
+	int i;
+	int bit_fields;
+	int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
+	int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
+	int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
+
+	/* Set and clear the reset bits; is good practice in User Manual */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	/* set master enable bit */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
+	if (!dma) {
+		/* While the FIFO can be setup for transfer sizes as large as
+		 * 16M-1, the FIFO itself is only 512 bytes deep and it does
+		 * not generate interrupts for FIFO full events (only transfer
+		 * complete will raise an IRQ).  Therefore when not using
+		 * Bestcomm to drive the FIFO it needs to either be polled, or
+		 * transfers need to constrained to the size of the fifo.
+		 *
+		 * This driver restricts the size of the transfer
+		 */
+		if (transfer_size > 512)
+			transfer_size = 512;
+
+		/* Load the FIFO with data */
+		if (write) {
+			reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+			data = req->data + req->pos;
+			for (i = 0; i < transfer_size; i += 4)
+				out_be32(reg, *data++);
+		}
+
+		/* Unmask both error and completion irqs */
+		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
+	} else {
+		/* Choose the correct direction
+		 *
+		 * Configure the watermarks so DMA will always complete correctly.
+		 * It may be worth experimenting with the ALARM value to see if
+		 * there is a performance impacit.  However, if it is wrong there
+		 * is a risk of DMA not transferring the last chunk of data
+		 */
+		if (write) {
+			out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
+			out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
+			lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
+		} else {
+			out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
+			out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
+			lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
+
+			if (poll_dma) {
+				if (lpbfifo.dma_irqs_enabled) {
+					disable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
+					lpbfifo.dma_irqs_enabled = 0;
+				}
+			} else {
+				if (!lpbfifo.dma_irqs_enabled) {
+					enable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
+					lpbfifo.dma_irqs_enabled = 1;
+				}
+			}
+		}
+
+		bd = bcom_prepare_next_buffer(lpbfifo.bcom_cur_task);
+		bd->status = transfer_size;
+		if (!write) {
+			/*
+			 * In the DMA read case, the DMA doesn't complete,
+			 * possibly due to incorrect watermarks in the ALARM
+			 * and CONTROL regs. For now instead of trying to
+			 * determine the right watermarks that will make this
+			 * work, just increase the number of bytes the FIFO is
+			 * expecting.
+			 *
+			 * When submitting another operation, the FIFO will get
+			 * reset, so the condition of the FIFO waiting for a
+			 * non-existent 4 bytes will get cleared.
+			 */
+			transfer_size += 4; /* BLECH! */
+		}
+		bd->data[0] = req->data_phys + req->pos;
+		bcom_submit_next_buffer(lpbfifo.bcom_cur_task, NULL);
+
+		/* error irq & master enabled bit */
+		bit_fields = 0x00000201;
+
+		/* Unmask irqs */
+		if (write && (!poll_dma))
+			bit_fields |= 0x00000100; /* completion irq too */
+		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
+	}
+
+	/* Set transfer size, width, chip select and READ mode */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
+		 req->offset + req->pos);
+	out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
+
+	bit_fields = req->cs << 24 | 0x000008;
+	if (!write)
+		bit_fields |= 0x010000; /* read mode */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
+
+	/* Kick it off */
+	out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
+	if (dma)
+		bcom_enable(lpbfifo.bcom_cur_task);
+}
+
+/**
+ * mpc52xx_lpbfifo_irq - IRQ handler for LPB FIFO
+ *
+ * On transmit, the dma completion irq triggers before the fifo completion
+ * triggers.  Handle the dma completion here instead of the LPB FIFO Bestcomm
+ * task completion irq becuase everyting is not really done until the LPB FIFO
+ * completion irq triggers.
+ *
+ * In other words:
+ * For DMA, on receive, the "Fat Lady" is the bestcom completion irq. on
+ * transmit, the fifo completion irq is the "Fat Lady". The opera (or in this
+ * case the DMA/FIFO operation) is not finished until the "Fat Lady" sings.
+ *
+ * Reasons for entering this routine:
+ * 1) PIO mode rx and tx completion irq
+ * 2) DMA interrupt mode tx completion irq
+ * 3) DMA polled mode tx
+ *
+ * Exit conditions:
+ * 1) Transfer aborted
+ * 2) FIFO complete without DMA; more data to do
+ * 3) FIFO complete without DMA; all data transfered
+ * 4) FIFO complete using DMA
+ *
+ * Condition 1 can occur regardless of whether or not DMA is used.
+ * It requires executing the callback to report the error and exiting
+ * immediately.
+ *
+ * Condition 2 requires programming the FIFO with the next block of data
+ *
+ * Condition 3 requires executing the callback to report completion
+ *
+ * Condition 4 means the same as 3, except that we also retrieve the bcom
+ * buffer so DMA doesn't get clogged up.
+ *
+ * To make things trickier, the spinlock must be dropped before
+ * executing the callback, otherwise we could end up with a deadlock
+ * or nested spinlock condition.  The out path is non-trivial, so
+ * extra fiddling is done to make sure all paths lead to the same
+ * outbound code.
+ */
+static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
+{
+	struct mpc52xx_lpbfifo_request *req;
+	u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+	void __iomem *reg;
+	u32 *data;
+	int count, i;
+	int do_callback = 0;
+	u32 ts;
+	unsigned long flags;
+	int dma, write, poll_dma;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+	ts = get_tbl();
+
+	req = lpbfifo.req;
+	if (!req) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		pr_err("bogus LPBFIFO IRQ\n");
+		return IRQ_HANDLED;
+	}
+
+	dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
+	write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
+	poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
+
+	if (dma && !write) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		pr_err("bogus LPBFIFO IRQ (dma and not writting)\n");
+		return IRQ_HANDLED;
+	}
+
+	if ((status & 0x01) == 0) {
+		goto out;
+	}
+
+	/* check abort bit */
+	if (status & 0x10) {
+		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+		do_callback = 1;
+		goto out;
+	}
+
+	/* Read result from hardware */
+	count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+	count &= 0x00ffffff;
+
+	if (!dma && !write) {
+		/* copy the data out of the FIFO */
+		reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+		data = req->data + req->pos;
+		for (i = 0; i < count; i += 4)
+			*data++ = in_be32(reg);
+	}
+
+	/* Update transfer position and count */
+	req->pos += count;
+
+	/* Decide what to do next */
+	if (req->size - req->pos)
+		mpc52xx_lpbfifo_kick(req); /* more work to do */
+	else
+		do_callback = 1;
+
+ out:
+	/* Clear the IRQ */
+	out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
+
+	if (dma && (status & 0x11)) {
+		/*
+		 * Count the DMA as complete only when the FIFO completion
+		 * status or abort bits are set.
+		 *
+		 * (status & 0x01) should always be the case except sometimes
+		 * when using polled DMA.
+		 *
+		 * (status & 0x10) {transfer aborted}: This case needs more
+		 * testing.
+		 */
+		bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
+	}
+	req->last_byte = ((u8 *)req->data)[req->size - 1];
+
+	/* When the do_callback flag is set; it means the transfer is finished
+	 * so set the FIFO as idle */
+	if (do_callback)
+		lpbfifo.req = NULL;
+
+	if (irq != 0) /* don't increment on polled case */
+		req->irq_count++;
+
+	req->irq_ticks += get_tbl() - ts;
+	spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+	/* Spinlock is released; it is now safe to call the callback */
+	if (do_callback && req->callback)
+		req->callback(req);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * mpc52xx_lpbfifo_bcom_irq - IRQ handler for LPB FIFO Bestcomm task
+ *
+ * Only used when receiving data.
+ */
+static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id)
+{
+	struct mpc52xx_lpbfifo_request *req;
+	unsigned long flags;
+	u32 status;
+	u32 ts;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+	ts = get_tbl();
+
+	req = lpbfifo.req;
+	if (!req || (req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA)) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		return IRQ_HANDLED;
+	}
+
+	if (irq != 0) /* don't increment on polled case */
+		req->irq_count++;
+
+	if (!bcom_buffer_done(lpbfifo.bcom_cur_task)) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+		req->buffer_not_done_cnt++;
+		if ((req->buffer_not_done_cnt % 1000) == 0)
+			pr_err("transfer stalled\n");
+
+		return IRQ_HANDLED;
+	}
+
+	bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
+
+	req->last_byte = ((u8 *)req->data)[req->size - 1];
+
+	req->pos = status & 0x00ffffff;
+
+	/* Mark the FIFO as idle */
+	lpbfifo.req = NULL;
+
+	/* Release the lock before calling out to the callback. */
+	req->irq_ticks += get_tbl() - ts;
+	spin_unlock_irqrestore(&lpbfifo.lock, flags);
+
+	if (req->callback)
+		req->callback(req);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * mpc52xx_lpbfifo_bcom_poll - Poll for DMA completion
+ */
+void mpc52xx_lpbfifo_poll(void)
+{
+	struct mpc52xx_lpbfifo_request *req = lpbfifo.req;
+	int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
+	int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
+
+	/*
+	 * For more information, see comments on the "Fat Lady" 
+	 */
+	if (dma && write)
+		mpc52xx_lpbfifo_irq(0, NULL);
+	else 
+		mpc52xx_lpbfifo_bcom_irq(0, NULL);
+}
+EXPORT_SYMBOL(mpc52xx_lpbfifo_poll);
+
+/**
+ * mpc52xx_lpbfifo_submit - Submit an LPB FIFO transfer request.
+ * @req: Pointer to request structure
+ */
+int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req)
+{
+	unsigned long flags;
+
+	if (!lpbfifo.regs)
+		return -ENODEV;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+
+	/* If the req pointer is already set, then a transfer is in progress */
+	if (lpbfifo.req) {
+		spin_unlock_irqrestore(&lpbfifo.lock, flags);
+		return -EBUSY;
+	}
+
+	/* Setup the transfer */
+	lpbfifo.req = req;
+	req->irq_count = 0;
+	req->irq_ticks = 0;
+	req->buffer_not_done_cnt = 0;
+	req->pos = 0;
+
+	mpc52xx_lpbfifo_kick(req);
+	spin_unlock_irqrestore(&lpbfifo.lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(mpc52xx_lpbfifo_submit);
+
+void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&lpbfifo.lock, flags);
+	if (lpbfifo.req == req) {
+		/* Put it into reset and clear the state */
+		bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
+		bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
+		out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+		lpbfifo.req = NULL;
+	}
+	spin_unlock_irqrestore(&lpbfifo.lock, flags);
+}
+EXPORT_SYMBOL(mpc52xx_lpbfifo_abort);
+
+static int __devinit
+mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct resource res;
+	int rc = -ENOMEM;
+
+	if (lpbfifo.dev != NULL)
+		return -ENOSPC;
+
+	lpbfifo.irq = irq_of_parse_and_map(op->node, 0);
+	if (!lpbfifo.irq)
+		return -ENODEV;
+
+	if (of_address_to_resource(op->node, 0, &res))
+		return -ENODEV;
+	lpbfifo.regs_phys = res.start;
+	lpbfifo.regs = of_iomap(op->node, 0);
+	if (!lpbfifo.regs)
+		return -ENOMEM;
+
+	spin_lock_init(&lpbfifo.lock);
+
+	/* Put FIFO into reset */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	/* Register the interrupt handler */
+	rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
+			 "mpc52xx-lpbfifo", &lpbfifo);
+	if (rc)
+		goto err_irq;
+
+	/* Request the Bestcomm receive (fifo --> memory) task and IRQ */
+	lpbfifo.bcom_rx_task =
+		bcom_gen_bd_rx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
+				    BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
+				    16*1024*1024);
+	if (!lpbfifo.bcom_rx_task)
+		goto err_bcom_rx;
+
+	rc = request_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task),
+			 mpc52xx_lpbfifo_bcom_irq, 0,
+			 "mpc52xx-lpbfifo-rx", &lpbfifo);
+	if (rc)
+		goto err_bcom_rx_irq;
+
+	/* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
+	lpbfifo.bcom_tx_task =
+		bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
+				    BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC);
+	if (!lpbfifo.bcom_tx_task)
+		goto err_bcom_tx;
+
+	lpbfifo.dev = &op->dev;
+	return 0;
+
+ err_bcom_tx:
+	free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
+ err_bcom_rx_irq:
+	bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
+ err_bcom_rx:
+ err_irq:
+	iounmap(lpbfifo.regs);
+	lpbfifo.regs = NULL;
+
+	dev_err(&op->dev, "mpc52xx_lpbfifo_probe() failed\n");
+	return -ENODEV;
+}
+
+
+static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
+{
+	if (lpbfifo.dev != &op->dev)
+		return 0;
+
+	/* Put FIFO in reset */
+	out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+
+	/* Release the bestcomm transmit task */
+	free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
+	bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
+	
+	/* Release the bestcomm receive task */
+	free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
+	bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
+
+	free_irq(lpbfifo.irq, &lpbfifo);
+	iounmap(lpbfifo.regs);
+	lpbfifo.regs = NULL;
+	lpbfifo.dev = NULL;
+
+	return 0;
+}
+
+static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = {
+	{ .compatible = "fsl,mpc5200-lpbfifo", },
+	{},
+};
+
+static struct of_platform_driver mpc52xx_lpbfifo_driver = {
+	.owner = THIS_MODULE,
+	.name = "mpc52xx-lpbfifo",
+	.match_table = mpc52xx_lpbfifo_match,
+	.probe = mpc52xx_lpbfifo_probe,
+	.remove = __devexit_p(mpc52xx_lpbfifo_remove),
+};
+
+/***********************************************************************
+ * Module init/exit
+ */
+static int __init mpc52xx_lpbfifo_init(void)
+{
+	pr_debug("Registering LocalPlus bus FIFO driver\n");
+	return of_register_platform_driver(&mpc52xx_lpbfifo_driver);
+}
+module_init(mpc52xx_lpbfifo_init);
+
+static void __exit mpc52xx_lpbfifo_exit(void)
+{
+	pr_debug("Unregistering LocalPlus bus FIFO driver\n");
+	of_unregister_platform_driver(&mpc52xx_lpbfifo_driver);
+}
+module_exit(mpc52xx_lpbfifo_exit);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pci.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pci.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,7 +100,7 @@ const struct of_device_id mpc52xx_pci_id
 };
 
 /* ======================================================================== */
-/* PCI configuration acess                                                  */
+/* PCI configuration access                                                 */
 /* ======================================================================== */
 
 static int
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -220,7 +220,7 @@ static int mpc52xx_extirq_set_type(unsig
 }
 
 static struct irq_chip mpc52xx_extirq_irqchip = {
-	.typename = "MPC52xx External",
+	.name = "MPC52xx External",
 	.mask = mpc52xx_extirq_mask,
 	.unmask = mpc52xx_extirq_unmask,
 	.ack = mpc52xx_extirq_ack,
@@ -258,7 +258,7 @@ static void mpc52xx_main_unmask(unsigned
 }
 
 static struct irq_chip mpc52xx_main_irqchip = {
-	.typename = "MPC52xx Main",
+	.name = "MPC52xx Main",
 	.mask = mpc52xx_main_mask,
 	.mask_ack = mpc52xx_main_mask,
 	.unmask = mpc52xx_main_unmask,
@@ -291,7 +291,7 @@ static void mpc52xx_periph_unmask(unsign
 }
 
 static struct irq_chip mpc52xx_periph_irqchip = {
-	.typename = "MPC52xx Peripherals",
+	.name = "MPC52xx Peripherals",
 	.mask = mpc52xx_periph_mask,
 	.mask_ack = mpc52xx_periph_mask,
 	.unmask = mpc52xx_periph_unmask,
@@ -335,7 +335,7 @@ static void mpc52xx_sdma_ack(unsigned in
 }
 
 static struct irq_chip mpc52xx_sdma_irqchip = {
-	.typename = "MPC52xx SDMA",
+	.name = "MPC52xx SDMA",
 	.mask = mpc52xx_sdma_mask,
 	.unmask = mpc52xx_sdma_unmask,
 	.ack = mpc52xx_sdma_ack,
@@ -355,7 +355,7 @@ static int mpc52xx_is_extirq(int l1, int
  * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
  */
 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
-				 u32 *intspec, unsigned int intsize,
+				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,7 +69,6 @@ static void pq2ads_pci_unmask_irq(unsign
 }
 
 static struct irq_chip pq2ads_pci_ic = {
-	.typename = "PQ2 ADS PCI",
 	.name = "PQ2 ADS PCI",
 	.end = pq2ads_pci_unmask_irq,
 	.mask = pq2ads_pci_mask_irq,
@@ -107,7 +106,7 @@ static void pq2ads_pci_irq_demux(unsigne
 static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
 			    irq_hw_number_t hw)
 {
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_data(virq, h->host_data);
 	set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ static int __init of_fsl_spi_probe(char
 
 		prop = of_get_property(np, "mode", NULL);
 		if (prop && !strcmp(prop, "cpu-qe"))
-			pdata.qe_mode = 1;
+			pdata.flags = SPI_QE_CPU_MODE;
 
 		for (j = 0; j < num_board_infos; j++) {
 			if (board_infos[j].bus_num == pdata.bus_num)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/83xx/suspend.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/suspend.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/83xx/suspend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/83xx/suspend.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #define PMCCR1_NEXT_STATE       0x0C /* Next state for power management */
 #define PMCCR1_NEXT_STATE_SHIFT 2
 #define PMCCR1_CURR_STATE       0x03 /* Current state for power management*/
+#define IMMR_SYSCR_OFFSET       0x100
 #define IMMR_RCW_OFFSET         0x900
 #define RCW_PCI_HOST            0x80000000
 
@@ -78,6 +79,22 @@ struct mpc83xx_clock {
 	u32 sccr;
 };
 
+struct mpc83xx_syscr {
+	__be32 sgprl;
+	__be32 sgprh;
+	__be32 spridr;
+	__be32 :32;
+	__be32 spcr;
+	__be32 sicrl;
+	__be32 sicrh;
+};
+
+struct mpc83xx_saved {
+	u32 sicrl;
+	u32 sicrh;
+	u32 sccr;
+};
+
 struct pmc_type {
 	int has_deep_sleep;
 };
@@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping
 static int pmc_irq;
 static struct mpc83xx_pmc __iomem *pmc_regs;
 static struct mpc83xx_clock __iomem *clock_regs;
+static struct mpc83xx_syscr __iomem *syscr_regs;
+static struct mpc83xx_saved saved_regs;
 static int is_pci_agent, wake_from_pci;
 static phys_addr_t immrbase;
 static int pci_pm_state;
@@ -96,6 +115,7 @@ int fsl_deep_sleep(void)
 {
 	return deep_sleeping;
 }
+EXPORT_SYMBOL(fsl_deep_sleep);
 
 static int mpc83xx_change_state(void)
 {
@@ -136,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int i
 	return ret;
 }
 
+static void mpc83xx_suspend_restore_regs(void)
+{
+	out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
+	out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
+	out_be32(&clock_regs->sccr, saved_regs.sccr);
+}
+
+static void mpc83xx_suspend_save_regs(void)
+{
+	saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
+	saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
+	saved_regs.sccr = in_be32(&clock_regs->sccr);
+}
+
 static int mpc83xx_suspend_enter(suspend_state_t state)
 {
 	int ret = -EAGAIN;
@@ -165,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend
 	 */
 
 	if (deep_sleeping) {
+		mpc83xx_suspend_save_regs();
+
 		out_be32(&pmc_regs->mask, PMCER_ALL);
 
 		out_be32(&pmc_regs->config1,
@@ -178,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend
 		         in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
 
 		out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+		mpc83xx_suspend_restore_regs();
 	} else {
 		out_be32(&pmc_regs->mask, PMCER_PMCI);
 
@@ -193,7 +231,7 @@ out:
 	return ret;
 }
 
-static void mpc83xx_suspend_finish(void)
+static void mpc83xx_suspend_end(void)
 {
 	deep_sleeping = 0;
 }
@@ -277,7 +315,7 @@ static struct platform_suspend_ops mpc83
 	.valid = mpc83xx_suspend_valid,
 	.begin = mpc83xx_suspend_begin,
 	.enter = mpc83xx_suspend_enter,
-	.finish = mpc83xx_suspend_finish,
+	.end = mpc83xx_suspend_end,
 };
 
 static int pmc_probe(struct of_device *ofdev,
@@ -332,12 +370,23 @@ static int pmc_probe(struct of_device *o
 		goto out_pmc;
 	}
 
+	if (has_deep_sleep) {
+		syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
+				     sizeof(*syscr_regs));
+		if (!syscr_regs) {
+			ret = -ENOMEM;
+			goto out_syscr;
+		}
+	}
+
 	if (is_pci_agent)
 		mpc83xx_set_agent();
 
 	suspend_set_ops(&mpc83xx_suspend_ops);
 	return 0;
 
+out_syscr:
+	iounmap(clock_regs);
 out_pmc:
 	iounmap(pmc_regs);
 out:
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/corenet_ds.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/corenet_ds.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/corenet_ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/corenet_ds.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,125 @@
+/*
+ * Corenet based SoC DS Setup
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2009 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/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/lmb.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+void __init corenet_ds_pic_init(void)
+{
+	struct mpic *mpic;
+	struct resource r;
+	struct device_node *np = NULL;
+	unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN |
+				MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU;
+
+	np = of_find_node_by_type(np, "open-pic");
+
+	if (np == NULL) {
+		printk(KERN_ERR "Could not find open-pic node\n");
+		return;
+	}
+
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "Failed to map mpic register space\n");
+		of_node_put(np);
+		return;
+	}
+
+	if (ppc_md.get_irq == mpic_get_coreint_irq)
+		flags |= MPIC_ENABLE_COREINT;
+
+	mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC  ");
+	BUG_ON(mpic == NULL);
+
+	mpic_init(mpic);
+}
+
+#ifdef CONFIG_PCI
+static int primary_phb_addr;
+#endif
+
+/*
+ * Setup the architecture
+ */
+#ifdef CONFIG_SMP
+void __init mpc85xx_smp_init(void);
+#endif
+
+void __init corenet_ds_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+	struct device_node *np;
+	struct pci_controller *hose;
+#endif
+	dma_addr_t max = 0xffffffff;
+
+#ifdef CONFIG_SMP
+	mpc85xx_smp_init();
+#endif
+
+#ifdef CONFIG_PCI
+	for_each_compatible_node(np, "pci", "fsl,p4080-pcie") {
+		struct resource rsrc;
+		of_address_to_resource(np, 0, &rsrc);
+		if ((rsrc.start & 0xfffff) == primary_phb_addr)
+			fsl_add_bridge(np, 1);
+		else
+			fsl_add_bridge(np, 0);
+
+		hose = pci_find_hose_for_OF_device(np);
+		max = min(max, hose->dma_window_base_cur +
+				hose->dma_window_size);
+	}
+#endif
+
+#ifdef CONFIG_SWIOTLB
+	if (lmb_end_of_DRAM() > max) {
+		ppc_swiotlb_enable = 1;
+		set_pci_dma_ops(&swiotlb_dma_ops);
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
+	}
+#endif
+	pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
+}
+
+static const struct of_device_id of_device_ids[] __devinitconst = {
+	{
+		.compatible	= "simple-bus"
+	},
+	{
+		.compatible	= "fsl,rapidio-delta",
+	},
+	{}
+};
+
+int __init corenet_ds_publish_devices(void)
+{
+	return of_platform_bus_probe(NULL, of_device_ids, NULL);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/corenet_ds.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/corenet_ds.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/corenet_ds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/corenet_ds.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,19 @@
+/*
+ * Corenet based SoC DS Setup
+ *
+ * Copyright 2009 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 CORENET_DS_H
+#define CORENET_DS_H
+
+extern void __init corenet_ds_pic_init(void);
+extern void __init corenet_ds_setup_arch(void);
+extern int __init corenet_ds_publish_devices(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
-menuconfig MPC85xx
-	bool "Machine Type"
-	depends on PPC_85xx
+menuconfig FSL_SOC_BOOKE
+	bool "Freescale Book-E Machine Type"
+	depends on PPC_85xx || PPC_BOOK3E
+	select FSL_SOC
 	select PPC_UDBG_16550
 	select MPIC
 	select PPC_PCI_CHOICE
@@ -8,7 +9,7 @@ menuconfig MPC85xx
 	select SERIAL_8250_SHARE_IRQ if SERIAL_8250
 	default y
 
-if MPC85xx
+if FSL_SOC_BOOKE
 
 config MPC8540_ADS
 	bool "Freescale MPC8540 ADS"
@@ -144,7 +145,19 @@ config SBC8560
 	help
 	  This option enables support for the Wind River SBC8560 board
 
-endif # MPC85xx
+config P4080_DS
+	bool "Freescale P4080 DS"
+	select DEFAULT_UIMAGE
+	select PPC_FSL_BOOK3E
+	select PPC_E500MC
+	select PHYS_64BIT
+	select SWIOTLB
+	select MPC8xxx_GPIO
+	select HAS_RAPIDIO
+	help
+	  This option enables support for the P4080 DS board
+
+endif # FSL_SOC_BOOKE
 
 config TQM85xx
 	bool
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@ obj-$(CONFIG_MPC8536_DS)  += mpc8536_ds.
 obj-$(CONFIG_MPC85xx_DS)  += mpc85xx_ds.o
 obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
 obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
+obj-$(CONFIG_P4080_DS)    += p4080_ds.o corenet_ds.o
 obj-$(CONFIG_STX_GP3)	  += stx_gp3.o
 obj-$(CONFIG_TQM85xx)	  += tqm85xx.o
 obj-$(CONFIG_SBC8560)     += sbc8560.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struc
 	scr = phy_read(phydev, MV88E1111_SCR);
 
 	if (scr < 0)
-		return err;
+		return scr;
 
 	err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
 
@@ -301,6 +301,7 @@ static struct of_device_id mpc85xx_ids[]
 	{ .compatible = "fsl,qe", },
 	{ .compatible = "gianfar", },
 	{ .compatible = "fsl,rapidio-delta", },
+	{ .compatible = "fsl,mpc8548-guts", },
 	{},
 };
 
@@ -337,7 +338,8 @@ static void __init mpc85xx_mds_pic_init(
 	}
 
 	mpic = mpic_alloc(np, r.start,
-			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
+			MPIC_BROKEN_FRR_NIRQS,
 			0, 256, " OpenPIC  ");
 	BUG_ON(mpic == NULL);
 	of_node_put(np);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/mpc85xx_rdb.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/mpc85xx_rdb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/mpc85xx_rdb.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,7 @@ void __init mpc85xx_rdb_pic_init(void)
 	struct mpic *mpic;
 	struct resource r;
 	struct device_node *np;
+	unsigned long root = of_get_flat_dt_root();
 
 	np = of_find_node_by_type(NULL, "open-pic");
 	if (np == NULL) {
@@ -57,11 +58,18 @@ void __init mpc85xx_rdb_pic_init(void)
 		return;
 	}
 
-	mpic = mpic_alloc(np, r.start,
+	if (of_flat_dt_is_compatible(root, "fsl,85XXRDB-CAMP")) {
+		mpic = mpic_alloc(np, r.start,
+			MPIC_PRIMARY |
+			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
+			0, 256, " OpenPIC  ");
+	} else {
+		mpic = mpic_alloc(np, r.start,
 		  MPIC_PRIMARY | MPIC_WANTS_RESET |
 		  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
 		  MPIC_SINGLE_DEST_CPU,
 		  0, 256, " OpenPIC  ");
+	}
 
 	BUG_ON(mpic == NULL);
 	of_node_put(np);
@@ -113,6 +121,7 @@ static int __init mpc85xxrdb_publish_dev
 	return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
 }
 machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
+machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices);
 
 /*
  * Called very early, device-tree isn't unflattened
@@ -126,12 +135,35 @@ static int __init p2020_rdb_probe(void)
 	return 0;
 }
 
+static int __init p1020_rdb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P1020RDB"))
+		return 1;
+	return 0;
+}
+
 define_machine(p2020_rdb) {
 	.name			= "P2020 RDB",
 	.probe			= p2020_rdb_probe,
 	.setup_arch		= mpc85xx_rdb_setup_arch,
 	.init_IRQ		= mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
+
+define_machine(p1020_rdb) {
+	.name			= "P1020 RDB",
+	.probe			= p1020_rdb_probe,
+	.setup_arch		= mpc85xx_rdb_setup_arch,
+	.init_IRQ		= mpc85xx_rdb_pic_init,
+#ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
 #endif
 	.get_irq		= mpic_get_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/p4080_ds.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/p4080_ds.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/p4080_ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/p4080_ds.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,74 @@
+/*
+ * P4080 DS Setup
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2009 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/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "corenet_ds.h"
+
+#ifdef CONFIG_PCI
+static int primary_phb_addr;
+#endif
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p4080_ds_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P4080DS")) {
+#ifdef CONFIG_PCI
+		/* treat PCIe1 as primary,
+		 * shouldn't matter as we have no ISA on the board
+		 */
+		primary_phb_addr = 0x0000;
+#endif
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+define_machine(p4080_ds) {
+	.name			= "P4080 DS",
+	.probe			= p4080_ds_probe,
+	.setup_arch		= corenet_ds_setup_arch,
+	.init_IRQ		= corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_coreint_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
+
+machine_device_initcall(p4080_ds, corenet_ds_publish_devices);
+machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/smp.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/smp.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@ smp_85xx_kick_cpu(int nr)
 	__iomem u32 *bptr_vaddr;
 	struct device_node *np;
 	int n = 0;
+	int ioremappable;
 
 	WARN_ON (nr < 0 || nr >= NR_CPUS);
 
@@ -59,21 +60,37 @@ smp_85xx_kick_cpu(int nr)
 		return;
 	}
 
+	/*
+	 * A secondary core could be in a spinloop in the bootpage
+	 * (0xfffff000), somewhere in highmem, or somewhere in lowmem.
+	 * The bootpage and highmem can be accessed via ioremap(), but
+	 * we need to directly access the spinloop if its in lowmem.
+	 */
+	ioremappable = *cpu_rel_addr > virt_to_phys(high_memory);
+
 	/* Map the spin table */
-	bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
+	if (ioremappable)
+		bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
+	else
+		bptr_vaddr = phys_to_virt(*cpu_rel_addr);
 
 	local_irq_save(flags);
 
 	out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
 	out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
 
+	if (!ioremappable)
+		flush_dcache_range((ulong)bptr_vaddr,
+				(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
+
 	/* Wait a bit for the CPU to ack. */
 	while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
 		mdelay(1);
 
 	local_irq_restore(flags);
 
-	iounmap(bptr_vaddr);
+	if (ioremappable)
+		iounmap(bptr_vaddr);
 
 	pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,7 @@ static int socrates_fpga_pic_set_type(un
 }
 
 static struct irq_chip socrates_fpga_pic_chip = {
-	.typename       = " FPGA-PIC ",
+	.name		= " FPGA-PIC ",
 	.ack		= socrates_fpga_pic_ack,
 	.mask           = socrates_fpga_pic_mask,
 	.mask_ack       = socrates_fpga_pic_mask_ack,
@@ -245,7 +245,7 @@ static int socrates_fpga_pic_host_map(st
 		irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip,
 			handle_fasteoi_irq);
 
@@ -253,7 +253,7 @@ static int socrates_fpga_pic_host_map(st
 }
 
 static int socrates_fpga_pic_host_xlate(struct irq_host *h,
-		struct device_node *ct,	u32 *intspec, unsigned int intsize,
+		struct device_node *ct,	const u32 *intspec, unsigned int intsize,
 		irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 	struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]];
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -149,7 +149,7 @@ static void gef_pic_unmask(unsigned int
 }
 
 static struct irq_chip gef_pic_chip = {
-	.typename	= "gefp",
+	.name		= "gefp",
 	.mask		= gef_pic_mask,
 	.mask_ack	= gef_pic_mask_ack,
 	.unmask		= gef_pic_unmask,
@@ -163,14 +163,14 @@ static int gef_pic_host_map(struct irq_h
 			  irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
 
 	return 0;
 }
 
 static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 *intspec, unsigned int intsize,
+			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <asm/udbg.h>
 
 #include <asm/mpic.h>
+#include <asm/nvram.h>
 
 #include <sysdev/fsl_pci.h>
 #include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_ppc9a_setup_arch(
 			printk(KERN_WARNING "Unable to map board registers\n");
 		of_node_put(regs);
 	}
+
+#if defined(CONFIG_MMIO_NVRAM)
+	mmio_nvram_init();
+#endif
 }
 
 /* Return the PCB revision */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <asm/udbg.h>
 
 #include <asm/mpic.h>
+#include <asm/nvram.h>
 
 #include <sysdev/fsl_pci.h>
 #include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_sbc310_setup_arch
 			printk(KERN_WARNING "Unable to map board registers\n");
 		of_node_put(regs);
 	}
+
+#if defined(CONFIG_MMIO_NVRAM)
+	mmio_nvram_init();
+#endif
 }
 
 /* Return the PCB revision */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <asm/udbg.h>
 
 #include <asm/mpic.h>
+#include <asm/nvram.h>
 
 #include <sysdev/fsl_pci.h>
 #include <sysdev/fsl_soc.h>
@@ -95,6 +96,10 @@ static void __init gef_sbc610_setup_arch
 			printk(KERN_WARNING "Unable to map board registers\n");
 		of_node_put(regs);
 	}
+
+#if defined(CONFIG_MMIO_NVRAM)
+	mmio_nvram_init();
+#endif
 }
 
 /* Return the PCB revision */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@ config MPC8610_HPCD
 config GEF_PPC9A
 	bool "GE Fanuc PPC9A"
 	select DEFAULT_UIMAGE
+	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
@@ -43,6 +44,7 @@ config GEF_PPC9A
 config GEF_SBC310
 	bool "GE Fanuc SBC310"
 	select DEFAULT_UIMAGE
+	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
@@ -51,6 +53,7 @@ config GEF_SBC310
 config GEF_SBC610
 	bool "GE Fanuc SBC610"
 	select DEFAULT_UIMAGE
+	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	select HAS_RAPIDIO
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
@@ -41,10 +42,46 @@
 
 #include "mpc86xx.h"
 
+static struct device_node *pixis_node;
 static unsigned char *pixis_bdcfg0, *pixis_arch;
 
+#ifdef CONFIG_SUSPEND
+static irqreturn_t mpc8610_sw9_irq(int irq, void *data)
+{
+	pr_debug("%s: PIXIS' event (sw9/wakeup) IRQ handled\n", __func__);
+	return IRQ_HANDLED;
+}
+
+static void __init mpc8610_suspend_init(void)
+{
+	int irq;
+	int ret;
+
+	if (!pixis_node)
+		return;
+
+	irq = irq_of_parse_and_map(pixis_node, 0);
+	if (!irq) {
+		pr_err("%s: can't map pixis event IRQ.\n", __func__);
+		return;
+	}
+
+	ret = request_irq(irq, mpc8610_sw9_irq, 0, "sw9/wakeup", NULL);
+	if (ret) {
+		pr_err("%s: can't request pixis event IRQ: %d\n",
+		       __func__, ret);
+		irq_dispose_mapping(irq);
+	}
+
+	enable_irq_wake(irq);
+}
+#else
+static inline void mpc8610_suspend_init(void) { }
+#endif /* CONFIG_SUSPEND */
+
 static struct of_device_id __initdata mpc8610_ids[] = {
 	{ .compatible = "fsl,mpc8610-immr", },
+	{ .compatible = "fsl,mpc8610-guts", },
 	{ .compatible = "simple-bus", },
 	{ .compatible = "gianfar", },
 	{}
@@ -55,6 +92,9 @@ static int __init mpc8610_declare_of_pla
 	/* Firstly, register PIXIS GPIOs. */
 	simple_gpiochip_init("fsl,fpga-pixis-gpio-bank");
 
+	/* Enable wakeup on PIXIS' event IRQ. */
+	mpc8610_suspend_init();
+
 	/* Without this call, the SSI device driver won't get probed. */
 	of_platform_bus_probe(NULL, mpc8610_ids, NULL);
 
@@ -250,10 +290,10 @@ static void __init mpc86xx_hpcd_setup_ar
 	diu_ops.set_sysfs_monitor_port	= mpc8610hpcd_set_sysfs_monitor_port;
 #endif
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
-	if (np) {
-		of_address_to_resource(np, 0, &r);
-		of_node_put(np);
+	pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
+	if (pixis_node) {
+		of_address_to_resource(pixis_node, 0, &r);
+		of_node_put(pixis_node);
 		pixis = ioremap(r.start, 32);
 		if (!pixis) {
 			printk(KERN_ERR "Err: can't map FPGA cfg register!\n");
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -222,7 +222,7 @@ static void cpm_cascade(unsigned int irq
 	int cascade_irq;
 
 	if ((cascade_irq = cpm_get_irq()) >= 0) {
-		struct irq_desc *cdesc = irq_desc + cascade_irq;
+		struct irq_desc *cdesc = irq_to_desc(cascade_irq);
 
 		generic_handle_irq(cascade_irq);
 		cdesc->chip->eoi(cascade_irq);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/amigaone/setup.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/amigaone/setup.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/amigaone/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/amigaone/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/seq_file.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 
 #include <asm/machdep.h>
 #include <asm/cputable.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/axon_msi.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/axon_msi.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/axon_msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/axon_msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -312,7 +312,7 @@ static struct irq_chip msic_irq_chip = {
 	.mask		= mask_msi_irq,
 	.unmask		= unmask_msi_irq,
 	.shutdown	= unmask_msi_irq,
-	.typename	= "AXON-MSI",
+	.name		= "AXON-MSI",
 };
 
 static int msic_host_map(struct irq_host *h, unsigned int virq,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/beat_interrupt.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,7 @@ static void beatic_end_irq(unsigned int
 }
 
 static struct irq_chip beatic_pic = {
-	.typename = " CELL-BEAT ",
+	.name = " CELL-BEAT ",
 	.unmask = beatic_unmask_irq,
 	.mask = beatic_mask_irq,
 	.eoi = beatic_end_irq,
@@ -136,7 +136,7 @@ static void beatic_pic_host_unmap(struct
 static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
 			       irq_hw_number_t hw)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	int64_t	err;
 
 	err = beat_construct_and_connect_irq_plug(virq, hw);
@@ -166,11 +166,11 @@ static void beatic_pic_host_remap(struct
  * Note: We have only 1 entry to translate.
  */
 static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-				 u32 *intspec, unsigned int intsize,
+				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
 {
-	u64 *intspec2 = (u64 *)intspec;
+	const u64 *intspec2 = (const u64 *)intspec;
 
 	*out_hwirq = *intspec2;
 	*out_flags |= IRQ_TYPE_LEVEL_LOW;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/interrupt.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/interrupt.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/interrupt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/interrupt.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@ struct iic {
 	struct device_node *node;
 };
 
-static DEFINE_PER_CPU(struct iic, iic);
+static DEFINE_PER_CPU(struct iic, cpu_iic);
 #define IIC_NODE_COUNT	2
 static struct irq_host *iic_host;
 
@@ -82,13 +82,13 @@ static void iic_unmask(unsigned int irq)
 
 static void iic_eoi(unsigned int irq)
 {
-	struct iic *iic = &__get_cpu_var(iic);
+	struct iic *iic = &__get_cpu_var(cpu_iic);
 	out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
 	BUG_ON(iic->eoi_ptr < 0);
 }
 
 static struct irq_chip iic_chip = {
-	.typename = " CELL-IIC ",
+	.name = " CELL-IIC ",
 	.mask = iic_mask,
 	.unmask = iic_unmask,
 	.eoi = iic_eoi,
@@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned i
 
 
 static struct irq_chip iic_ioexc_chip = {
-	.typename = " CELL-IOEX",
+	.name = " CELL-IOEX",
 	.mask = iic_mask,
 	.unmask = iic_unmask,
 	.eoi = iic_ioexc_eoi,
@@ -146,7 +146,7 @@ static unsigned int iic_get_irq(void)
 	struct iic *iic;
 	unsigned int virq;
 
-	iic = &__get_cpu_var(iic);
+	iic = &__get_cpu_var(cpu_iic);
 	*(unsigned long *) &pending =
 		in_be64((u64 __iomem *) &iic->regs->pending_destr);
 	if (!(pending.flags & CBE_IIC_IRQ_VALID))
@@ -161,12 +161,12 @@ static unsigned int iic_get_irq(void)
 
 void iic_setup_cpu(void)
 {
-	out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+	out_be64(&__get_cpu_var(cpu_iic).regs->prio, 0xff);
 }
 
 u8 iic_get_target_id(int cpu)
 {
-	return per_cpu(iic, cpu).target_id;
+	return per_cpu(cpu_iic, cpu).target_id;
 }
 
 EXPORT_SYMBOL_GPL(iic_get_target_id);
@@ -181,7 +181,7 @@ static inline int iic_ipi_to_irq(int ipi
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-	out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
+	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - mesg) << 4);
 }
 
 struct irq_host *iic_get_irq_host(int node)
@@ -237,7 +237,7 @@ extern int noirqdebug;
 
 static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
 {
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
 
@@ -265,18 +265,18 @@ static void handle_iic_irq(unsigned int
 			goto out_eoi;
 
 		desc->status &= ~IRQ_PENDING;
-		spin_unlock(&desc->lock);
+		raw_spin_unlock(&desc->lock);
 		action_ret = handle_IRQ_event(irq, action);
 		if (!noirqdebug)
 			note_interrupt(irq, desc, action_ret);
-		spin_lock(&desc->lock);
+		raw_spin_lock(&desc->lock);
 
 	} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
 
 	desc->status &= ~IRQ_INPROGRESS;
 out_eoi:
 	desc->chip->eoi(irq);
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 }
 
 static int iic_host_map(struct irq_host *h, unsigned int virq,
@@ -297,7 +297,7 @@ static int iic_host_map(struct irq_host
 }
 
 static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
-			   u32 *intspec, unsigned int intsize,
+			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
@@ -348,7 +348,7 @@ static void __init init_one_iic(unsigned
 	/* XXX FIXME: should locate the linux CPU number from the HW cpu
 	 * number properly. We are lucky for now
 	 */
-	struct iic *iic = &per_cpu(iic, hw_cpu);
+	struct iic *iic = &per_cpu(cpu_iic, hw_cpu);
 
 	iic->regs = ioremap(addr, sizeof(struct cbe_iic_thread_regs));
 	BUG_ON(iic->regs == NULL);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spider-pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spider-pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spider-pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -102,7 +102,7 @@ static void spider_ack_irq(unsigned int
 
 	/* Reset edge detection logic if necessary
 	 */
-	if (get_irq_desc(virq)->status & IRQ_LEVEL)
+	if (irq_to_desc(virq)->status & IRQ_LEVEL)
 		return;
 
 	/* Only interrupts 47 to 50 can be set to edge */
@@ -119,7 +119,7 @@ static int spider_set_irq_type(unsigned
 	struct spider_pic *pic = spider_virq_to_pic(virq);
 	unsigned int hw = irq_map[virq].hwirq;
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	u32 old_mask;
 	u32 ic;
 
@@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned
 }
 
 static struct irq_chip spider_pic = {
-	.typename = " SPIDER   ",
+	.name = " SPIDER   ",
 	.unmask = spider_unmask_irq,
 	.mask = spider_mask_irq,
 	.ack = spider_ack_irq,
@@ -187,7 +187,7 @@ static int spider_host_map(struct irq_ho
 }
 
 static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
-			   u32 *intspec, unsigned int intsize,
+			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/coredump.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@ static ssize_t do_coredump_read(int num,
  */
 static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
 {
-	unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+	unsigned long limit = rlimit(RLIMIT_CORE);
 	ssize_t written;
 
 	if (*foffset + nr > limit)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/file.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/file.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2010-02-24 13:52:17.000000000 -0500
@@ -2494,7 +2494,7 @@ static ssize_t spufs_switch_log_read(str
 	struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
 	int error = 0, cnt = 0;
 
-	if (!buf || len < 0)
+	if (!buf)
 		return -EINVAL;
 
 	error = spu_acquire(ctx);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/cell/spufs/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/cell/spufs/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -13,10 +13,8 @@ SPU_CC		:= $(SPU_CROSS)gcc
 SPU_AS		:= $(SPU_CROSS)gcc
 SPU_LD		:= $(SPU_CROSS)ld
 SPU_OBJCOPY	:= $(SPU_CROSS)objcopy
-SPU_CFLAGS	:= -O2 -Wall -I$(srctree)/include \
-		   -I$(objtree)/include2 -D__KERNEL__
-SPU_AFLAGS	:= -c -D__ASSEMBLY__ -I$(srctree)/include \
-		   -I$(objtree)/include2 -D__KERNEL__
+SPU_CFLAGS	:= -O2 -Wall -I$(srctree)/include -D__KERNEL__
+SPU_AFLAGS	:= -c -D__ASSEMBLY__ -I$(srctree)/include -D__KERNEL__
 SPU_LDFLAGS	:= -N -Ttext=0x0
 
 $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/chrp/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/chrp/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,8 @@ config PPC_CHRP
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	select PPC_RTAS
+	select PPC_RTAS_DAEMON
+	select RTAS_ERROR_LOGGING
 	select PPC_MPC106
 	select PPC_UDBG_16550
 	select PPC_NATIVE
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/chrp/setup.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/setup.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/chrp/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/chrp/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <linux/adb.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -364,19 +364,6 @@ void __init chrp_setup_arch(void)
 	if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
 }
 
-void
-chrp_event_scan(unsigned long unused)
-{
-	unsigned char log[1024];
-	int ret = 0;
-
-	/* XXX: we should loop until the hardware says no more error logs -- Cort */
-	rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
-		  __pa(log), 1024);
-	mod_timer(&__get_cpu_var(heartbeat_timer),
-		  jiffies + event_scan_interval);
-}
-
 static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int cascade_irq = i8259_irq();
@@ -568,9 +555,6 @@ void __init chrp_init_IRQ(void)
 void __init
 chrp_init2(void)
 {
-	struct device_node *device;
-	const unsigned int *p = NULL;
-
 #ifdef CONFIG_NVRAM
 	chrp_nvram_init();
 #endif
@@ -582,40 +566,6 @@ chrp_init2(void)
 	request_region(0x80,0x10,"dma page reg");
 	request_region(0xc0,0x20,"dma2");
 
-	/* Get the event scan rate for the rtas so we know how
-	 * often it expects a heartbeat. -- Cort
-	 */
-	device = of_find_node_by_name(NULL, "rtas");
-	if (device)
-		p = of_get_property(device, "rtas-event-scan-rate", NULL);
-	if (p && *p) {
-		/*
-		 * Arrange to call chrp_event_scan at least *p times
-		 * per minute.  We use 59 rather than 60 here so that
-		 * the rate will be slightly higher than the minimum.
-		 * This all assumes we don't do hotplug CPU on any
-		 * machine that needs the event scans done.
-		 */
-		unsigned long interval, offset;
-		int cpu, ncpus;
-		struct timer_list *timer;
-
-		interval = HZ * 59 / *p;
-		offset = HZ;
-		ncpus = num_online_cpus();
-		event_scan_interval = ncpus * interval;
-		for (cpu = 0; cpu < ncpus; ++cpu) {
-			timer = &per_cpu(heartbeat_timer, cpu);
-			setup_timer(timer, chrp_event_scan, 0);
-			timer->expires = jiffies + offset;
-			add_timer_on(timer, cpu);
-			offset += interval;
-		}
-		printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
-		       *p, interval);
-	}
-	of_node_put(device);
-
 	if (ppc_md.progress)
 		ppc_md.progress("  Have fun!    ", 0x7777);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,263 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/flipper-pic.c
+ *
+ * Nintendo GameCube/Wii "Flipper" interrupt controller support.
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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.
+ *
+ */
+#define DRV_MODULE_NAME "flipper-pic"
+#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <asm/io.h>
+
+#include "flipper-pic.h"
+
+#define FLIPPER_NR_IRQS		32
+
+/*
+ * Each interrupt has a corresponding bit in both
+ * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
+ *
+ * Enabling/disabling an interrupt line involves setting/clearing
+ * the corresponding bit in IMR.
+ * Except for the RSW interrupt, all interrupts get deasserted automatically
+ * when the source deasserts the interrupt.
+ */
+#define FLIPPER_ICR		0x00
+#define FLIPPER_ICR_RSS		(1<<16) /* reset switch state */
+
+#define FLIPPER_IMR		0x04
+
+#define FLIPPER_RESET		0x24
+
+
+/*
+ * IRQ chip hooks.
+ *
+ */
+
+static void flipper_pic_mask_and_ack(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+	u32 mask = 1 << irq;
+
+	clrbits32(io_base + FLIPPER_IMR, mask);
+	/* this is at least needed for RSW */
+	out_be32(io_base + FLIPPER_ICR, mask);
+}
+
+static void flipper_pic_ack(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	/* this is at least needed for RSW */
+	out_be32(io_base + FLIPPER_ICR, 1 << irq);
+}
+
+static void flipper_pic_mask(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
+}
+
+static void flipper_pic_unmask(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	setbits32(io_base + FLIPPER_IMR, 1 << irq);
+}
+
+
+static struct irq_chip flipper_pic = {
+	.name		= "flipper-pic",
+	.ack		= flipper_pic_ack,
+	.mask_ack	= flipper_pic_mask_and_ack,
+	.mask		= flipper_pic_mask,
+	.unmask		= flipper_pic_unmask,
+};
+
+/*
+ * IRQ host hooks.
+ *
+ */
+
+static struct irq_host *flipper_irq_host;
+
+static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+			   irq_hw_number_t hwirq)
+{
+	set_irq_chip_data(virq, h->host_data);
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
+	set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
+	return 0;
+}
+
+static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
+{
+	set_irq_chip_data(irq, NULL);
+	set_irq_chip(irq, NULL);
+}
+
+static int flipper_pic_match(struct irq_host *h, struct device_node *np)
+{
+	return 1;
+}
+
+
+static struct irq_host_ops flipper_irq_host_ops = {
+	.map = flipper_pic_map,
+	.unmap = flipper_pic_unmap,
+	.match = flipper_pic_match,
+};
+
+/*
+ * Platform hooks.
+ *
+ */
+
+static void __flipper_quiesce(void __iomem *io_base)
+{
+	/* mask and ack all IRQs */
+	out_be32(io_base + FLIPPER_IMR, 0x00000000);
+	out_be32(io_base + FLIPPER_ICR, 0xffffffff);
+}
+
+struct irq_host * __init flipper_pic_init(struct device_node *np)
+{
+	struct device_node *pi;
+	struct irq_host *irq_host = NULL;
+	struct resource res;
+	void __iomem *io_base;
+	int retval;
+
+	pi = of_get_parent(np);
+	if (!pi) {
+		pr_err("no parent found\n");
+		goto out;
+	}
+	if (!of_device_is_compatible(pi, "nintendo,flipper-pi")) {
+		pr_err("unexpected parent compatible\n");
+		goto out;
+	}
+
+	retval = of_address_to_resource(pi, 0, &res);
+	if (retval) {
+		pr_err("no io memory range found\n");
+		goto out;
+	}
+	io_base = ioremap(res.start, resource_size(&res));
+
+	pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
+
+	__flipper_quiesce(io_base);
+
+	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
+				  &flipper_irq_host_ops, -1);
+	if (!irq_host) {
+		pr_err("failed to allocate irq_host\n");
+		return NULL;
+	}
+
+	irq_host->host_data = io_base;
+
+out:
+	return irq_host;
+}
+
+unsigned int flipper_pic_get_irq(void)
+{
+	void __iomem *io_base = flipper_irq_host->host_data;
+	int irq;
+	u32 irq_status;
+
+	irq_status = in_be32(io_base + FLIPPER_ICR) &
+		     in_be32(io_base + FLIPPER_IMR);
+	if (irq_status == 0)
+		return NO_IRQ;	/* no more IRQs pending */
+
+	irq = __ffs(irq_status);
+	return irq_linear_revmap(flipper_irq_host, irq);
+}
+
+/*
+ * Probe function.
+ *
+ */
+
+void __init flipper_pic_probe(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic");
+	BUG_ON(!np);
+
+	flipper_irq_host = flipper_pic_init(np);
+	BUG_ON(!flipper_irq_host);
+
+	irq_set_default_host(flipper_irq_host);
+
+	of_node_put(np);
+}
+
+/*
+ * Misc functions related to the flipper chipset.
+ *
+ */
+
+/**
+ * flipper_quiesce() - quiesce flipper irq controller
+ *
+ * Mask and ack all interrupt sources.
+ *
+ */
+void flipper_quiesce(void)
+{
+	void __iomem *io_base = flipper_irq_host->host_data;
+
+	__flipper_quiesce(io_base);
+}
+
+/*
+ * Resets the platform.
+ */
+void flipper_platform_reset(void)
+{
+	void __iomem *io_base;
+
+	if (flipper_irq_host && flipper_irq_host->host_data) {
+		io_base = flipper_irq_host->host_data;
+		out_8(io_base + FLIPPER_RESET, 0x00);
+	}
+}
+
+/*
+ * Returns non-zero if the reset button is pressed.
+ */
+int flipper_is_reset_button_pressed(void)
+{
+	void __iomem *io_base;
+	u32 icr;
+
+	if (flipper_irq_host && flipper_irq_host->host_data) {
+		io_base = flipper_irq_host->host_data;
+		icr = in_be32(io_base + FLIPPER_ICR);
+		return !(icr & FLIPPER_ICR_RSS);
+	}
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/flipper-pic.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,25 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/flipper-pic.h
+ *
+ * Nintendo GameCube/Wii "Flipper" interrupt controller support.
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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 __FLIPPER_PIC_H
+#define __FLIPPER_PIC_H
+
+unsigned int flipper_pic_get_irq(void);
+void __init flipper_pic_probe(void);
+
+void flipper_quiesce(void);
+void flipper_platform_reset(void);
+int flipper_is_reset_button_pressed(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/gamecube.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/gamecube.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/gamecube.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/gamecube.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,118 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/gamecube.c
+ *
+ * Nintendo GameCube board-specific support
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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/irq.h>
+#include <linux/kexec.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+#include "flipper-pic.h"
+#include "usbgecko_udbg.h"
+
+
+static void gamecube_spin(void)
+{
+	/* spin until power button pressed */
+	for (;;)
+		cpu_relax();
+}
+
+static void gamecube_restart(char *cmd)
+{
+	local_irq_disable();
+	flipper_platform_reset();
+	gamecube_spin();
+}
+
+static void gamecube_power_off(void)
+{
+	local_irq_disable();
+	gamecube_spin();
+}
+
+static void gamecube_halt(void)
+{
+	gamecube_restart(NULL);
+}
+
+static void __init gamecube_init_early(void)
+{
+	ug_udbg_init();
+}
+
+static int __init gamecube_probe(void)
+{
+	unsigned long dt_root;
+
+	dt_root = of_get_flat_dt_root();
+	if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
+		return 0;
+
+	return 1;
+}
+
+static void gamecube_shutdown(void)
+{
+	flipper_quiesce();
+}
+
+#ifdef CONFIG_KEXEC
+static int gamecube_kexec_prepare(struct kimage *image)
+{
+	return 0;
+}
+#endif /* CONFIG_KEXEC */
+
+
+define_machine(gamecube) {
+	.name			= "gamecube",
+	.probe			= gamecube_probe,
+	.init_early		= gamecube_init_early,
+	.restart		= gamecube_restart,
+	.power_off		= gamecube_power_off,
+	.halt			= gamecube_halt,
+	.init_IRQ		= flipper_pic_probe,
+	.get_irq		= flipper_pic_get_irq,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+	.machine_shutdown	= gamecube_shutdown,
+#ifdef CONFIG_KEXEC
+	.machine_kexec_prepare	= gamecube_kexec_prepare,
+#endif
+};
+
+
+static struct of_device_id gamecube_of_bus[] = {
+	{ .compatible = "nintendo,flipper", },
+	{ },
+};
+
+static int __init gamecube_device_probe(void)
+{
+	if (!machine_is(gamecube))
+		return 0;
+
+	of_platform_bus_probe(NULL, gamecube_of_bus, NULL);
+	return 0;
+}
+device_initcall(gamecube_device_probe);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,241 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+ *
+ * Nintendo Wii "Hollywood" interrupt controller support.
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * 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.
+ *
+ */
+#define DRV_MODULE_NAME "hlwd-pic"
+#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <asm/io.h>
+
+#include "hlwd-pic.h"
+
+#define HLWD_NR_IRQS	32
+
+/*
+ * Each interrupt has a corresponding bit in both
+ * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
+ *
+ * Enabling/disabling an interrupt line involves asserting/clearing
+ * the corresponding bit in IMR. ACK'ing a request simply involves
+ * asserting the corresponding bit in ICR.
+ */
+#define HW_BROADWAY_ICR		0x00
+#define HW_BROADWAY_IMR		0x04
+
+
+/*
+ * IRQ chip hooks.
+ *
+ */
+
+static void hlwd_pic_mask_and_ack(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+	u32 mask = 1 << irq;
+
+	clrbits32(io_base + HW_BROADWAY_IMR, mask);
+	out_be32(io_base + HW_BROADWAY_ICR, mask);
+}
+
+static void hlwd_pic_ack(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
+}
+
+static void hlwd_pic_mask(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+}
+
+static void hlwd_pic_unmask(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void __iomem *io_base = get_irq_chip_data(virq);
+
+	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+}
+
+
+static struct irq_chip hlwd_pic = {
+	.name		= "hlwd-pic",
+	.ack		= hlwd_pic_ack,
+	.mask_ack	= hlwd_pic_mask_and_ack,
+	.mask		= hlwd_pic_mask,
+	.unmask		= hlwd_pic_unmask,
+};
+
+/*
+ * IRQ host hooks.
+ *
+ */
+
+static struct irq_host *hlwd_irq_host;
+
+static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
+			   irq_hw_number_t hwirq)
+{
+	set_irq_chip_data(virq, h->host_data);
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
+	set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
+	return 0;
+}
+
+static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq)
+{
+	set_irq_chip_data(irq, NULL);
+	set_irq_chip(irq, NULL);
+}
+
+static struct irq_host_ops hlwd_irq_host_ops = {
+	.map = hlwd_pic_map,
+	.unmap = hlwd_pic_unmap,
+};
+
+static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
+{
+	void __iomem *io_base = h->host_data;
+	int irq;
+	u32 irq_status;
+
+	irq_status = in_be32(io_base + HW_BROADWAY_ICR) &
+		     in_be32(io_base + HW_BROADWAY_IMR);
+	if (irq_status == 0)
+		return NO_IRQ;	/* no more IRQs pending */
+
+	irq = __ffs(irq_status);
+	return irq_linear_revmap(h, irq);
+}
+
+static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
+				      struct irq_desc *desc)
+{
+	struct irq_host *irq_host = get_irq_data(cascade_virq);
+	unsigned int virq;
+
+	raw_spin_lock(&desc->lock);
+	desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
+	raw_spin_unlock(&desc->lock);
+
+	virq = __hlwd_pic_get_irq(irq_host);
+	if (virq != NO_IRQ)
+		generic_handle_irq(virq);
+	else
+		pr_err("spurious interrupt!\n");
+
+	raw_spin_lock(&desc->lock);
+	desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
+	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
+		desc->chip->unmask(cascade_virq);
+	raw_spin_unlock(&desc->lock);
+}
+
+/*
+ * Platform hooks.
+ *
+ */
+
+static void __hlwd_quiesce(void __iomem *io_base)
+{
+	/* mask and ack all IRQs */
+	out_be32(io_base + HW_BROADWAY_IMR, 0);
+	out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
+}
+
+struct irq_host *hlwd_pic_init(struct device_node *np)
+{
+	struct irq_host *irq_host;
+	struct resource res;
+	void __iomem *io_base;
+	int retval;
+
+	retval = of_address_to_resource(np, 0, &res);
+	if (retval) {
+		pr_err("no io memory range found\n");
+		return NULL;
+	}
+	io_base = ioremap(res.start, resource_size(&res));
+	if (!io_base) {
+		pr_err("ioremap failed\n");
+		return NULL;
+	}
+
+	pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base);
+
+	__hlwd_quiesce(io_base);
+
+	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS,
+				  &hlwd_irq_host_ops, -1);
+	if (!irq_host) {
+		pr_err("failed to allocate irq_host\n");
+		return NULL;
+	}
+	irq_host->host_data = io_base;
+
+	return irq_host;
+}
+
+unsigned int hlwd_pic_get_irq(void)
+{
+	return __hlwd_pic_get_irq(hlwd_irq_host);
+}
+
+/*
+ * Probe function.
+ *
+ */
+
+void hlwd_pic_probe(void)
+{
+	struct irq_host *host;
+	struct device_node *np;
+	const u32 *interrupts;
+	int cascade_virq;
+
+	for_each_compatible_node(np, NULL, "nintendo,hollywood-pic") {
+		interrupts = of_get_property(np, "interrupts", NULL);
+		if (interrupts) {
+			host = hlwd_pic_init(np);
+			BUG_ON(!host);
+			cascade_virq = irq_of_parse_and_map(np, 0);
+			set_irq_data(cascade_virq, host);
+			set_irq_chained_handler(cascade_virq,
+						hlwd_pic_irq_cascade);
+			hlwd_irq_host = host;
+			break;
+		}
+	}
+}
+
+/**
+ * hlwd_quiesce() - quiesce hollywood irq controller
+ *
+ * Mask and ack all interrupt sources.
+ *
+ */
+void hlwd_quiesce(void)
+{
+	void __iomem *io_base = hlwd_irq_host->host_data;
+
+	__hlwd_quiesce(io_base);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/hlwd-pic.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,22 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/hlwd-pic.h
+ *
+ * Nintendo Wii "Hollywood" interrupt controller support.
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * 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 __HLWD_PIC_H
+#define __HLWD_PIC_H
+
+extern unsigned int hlwd_pic_get_irq(void);
+extern void hlwd_pic_probe(void);
+extern void hlwd_quiesce(void);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -90,3 +90,36 @@ config MPC10X_OPENPIC
 config MPC10X_STORE_GATHERING
 	bool "Enable MPC10x store gathering"
 	depends on MPC10X_BRIDGE
+
+config GAMECUBE_COMMON
+	bool
+
+config USBGECKO_UDBG
+	bool "USB Gecko udbg console for the Nintendo GameCube/Wii"
+	depends on GAMECUBE_COMMON
+	help
+	  If you say yes to this option, support will be included for the
+	  USB Gecko adapter as an udbg console.
+	  The USB Gecko is a EXI to USB Serial converter that can be plugged
+	  into a memcard slot in the Nintendo GameCube/Wii.
+
+	  This driver bypasses the EXI layer completely.
+
+	  If in doubt, say N here.
+
+config GAMECUBE
+	bool "Nintendo-GameCube"
+	depends on EMBEDDED6xx
+	select GAMECUBE_COMMON
+	help
+	  Select GAMECUBE if configuring for the Nintendo GameCube.
+	  More information at: <http://gc-linux.sourceforge.net/>
+
+config WII
+	bool "Nintendo-Wii"
+	depends on EMBEDDED6xx
+	select GAMECUBE_COMMON
+	help
+	  Select WII if configuring for the Nintendo Wii.
+	  More information at: <http://gc-linux.sourceforge.net/>
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -7,3 +7,7 @@ obj-$(CONFIG_STORCENTER)	+= storcenter.o
 obj-$(CONFIG_PPC_HOLLY)		+= holly.o
 obj-$(CONFIG_PPC_PRPMC2800)	+= prpmc2800.o
 obj-$(CONFIG_PPC_C2K)		+= c2k.o
+obj-$(CONFIG_USBGECKO_UDBG)	+= usbgecko_udbg.o
+obj-$(CONFIG_GAMECUBE_COMMON)	+= flipper-pic.o
+obj-$(CONFIG_GAMECUBE)		+= gamecube.o
+obj-$(CONFIG_WII)		+= wii.o hlwd-pic.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,328 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
+ *
+ * udbg serial input/output routines for the USB Gecko adapter.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 <mm/mmu_decl.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/fixmap.h>
+
+#include "usbgecko_udbg.h"
+
+
+#define EXI_CLK_32MHZ           5
+
+#define EXI_CSR                 0x00
+#define   EXI_CSR_CLKMASK       (0x7<<4)
+#define     EXI_CSR_CLK_32MHZ   (EXI_CLK_32MHZ<<4)
+#define   EXI_CSR_CSMASK        (0x7<<7)
+#define     EXI_CSR_CS_0        (0x1<<7)  /* Chip Select 001 */
+
+#define EXI_CR                  0x0c
+#define   EXI_CR_TSTART         (1<<0)
+#define   EXI_CR_WRITE		(1<<2)
+#define   EXI_CR_READ_WRITE     (2<<2)
+#define   EXI_CR_TLEN(len)      (((len)-1)<<4)
+
+#define EXI_DATA                0x10
+
+#define UG_READ_ATTEMPTS	100
+#define UG_WRITE_ATTEMPTS	100
+
+
+static void __iomem *ug_io_base;
+
+/*
+ * Performs one input/output transaction between the exi host and the usbgecko.
+ */
+static u32 ug_io_transaction(u32 in)
+{
+	u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
+	u32 __iomem *data_reg = ug_io_base + EXI_DATA;
+	u32 __iomem *cr_reg = ug_io_base + EXI_CR;
+	u32 csr, data, cr;
+
+	/* select */
+	csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
+	out_be32(csr_reg, csr);
+
+	/* read/write */
+	data = in;
+	out_be32(data_reg, data);
+	cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
+	out_be32(cr_reg, cr);
+
+	while (in_be32(cr_reg) & EXI_CR_TSTART)
+		barrier();
+
+	/* deselect */
+	out_be32(csr_reg, 0);
+
+	/* result */
+	data = in_be32(data_reg);
+
+	return data;
+}
+
+/*
+ * Returns true if an usbgecko adapter is found.
+ */
+static int ug_is_adapter_present(void)
+{
+	if (!ug_io_base)
+		return 0;
+
+	return ug_io_transaction(0x90000000) == 0x04700000;
+}
+
+/*
+ * Returns true if the TX fifo is ready for transmission.
+ */
+static int ug_is_txfifo_ready(void)
+{
+	return ug_io_transaction(0xc0000000) & 0x04000000;
+}
+
+/*
+ * Tries to transmit a character.
+ * If the TX fifo is not ready the result is undefined.
+ */
+static void ug_raw_putc(char ch)
+{
+	ug_io_transaction(0xb0000000 | (ch << 20));
+}
+
+/*
+ * Transmits a character.
+ * It silently fails if the TX fifo is not ready after a number of retries.
+ */
+static void ug_putc(char ch)
+{
+	int count = UG_WRITE_ATTEMPTS;
+
+	if (!ug_io_base)
+		return;
+
+	if (ch == '\n')
+		ug_putc('\r');
+
+	while (!ug_is_txfifo_ready() && count--)
+		barrier();
+	if (count >= 0)
+		ug_raw_putc(ch);
+}
+
+/*
+ * Returns true if the RX fifo is ready for transmission.
+ */
+static int ug_is_rxfifo_ready(void)
+{
+	return ug_io_transaction(0xd0000000) & 0x04000000;
+}
+
+/*
+ * Tries to receive a character.
+ * If a character is unavailable the function returns -1.
+ */
+static int ug_raw_getc(void)
+{
+	u32 data = ug_io_transaction(0xa0000000);
+	if (data & 0x08000000)
+		return (data >> 16) & 0xff;
+	else
+		return -1;
+}
+
+/*
+ * Receives a character.
+ * It fails if the RX fifo is not ready after a number of retries.
+ */
+static int ug_getc(void)
+{
+	int count = UG_READ_ATTEMPTS;
+
+	if (!ug_io_base)
+		return -1;
+
+	while (!ug_is_rxfifo_ready() && count--)
+		barrier();
+	return ug_raw_getc();
+}
+
+/*
+ * udbg functions.
+ *
+ */
+
+/*
+ * Transmits a character.
+ */
+void ug_udbg_putc(char ch)
+{
+	ug_putc(ch);
+}
+
+/*
+ * Receives a character. Waits until a character is available.
+ */
+static int ug_udbg_getc(void)
+{
+	int ch;
+
+	while ((ch = ug_getc()) == -1)
+		barrier();
+	return ch;
+}
+
+/*
+ * Receives a character. If a character is not available, returns -1.
+ */
+static int ug_udbg_getc_poll(void)
+{
+	if (!ug_is_rxfifo_ready())
+		return -1;
+	return ug_getc();
+}
+
+/*
+ * Retrieves and prepares the virtual address needed to access the hardware.
+ */
+static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np)
+{
+	void __iomem *exi_io_base = NULL;
+	phys_addr_t paddr;
+	const unsigned int *reg;
+
+	reg = of_get_property(np, "reg", NULL);
+	if (reg) {
+		paddr = of_translate_address(np, reg);
+		if (paddr)
+			exi_io_base = ioremap(paddr, reg[1]);
+	}
+	return exi_io_base;
+}
+
+/*
+ * Checks if a USB Gecko adapter is inserted in any memory card slot.
+ */
+static void __iomem *ug_udbg_probe(void __iomem *exi_io_base)
+{
+	int i;
+
+	/* look for a usbgecko on memcard slots A and B */
+	for (i = 0; i < 2; i++) {
+		ug_io_base = exi_io_base + 0x14 * i;
+		if (ug_is_adapter_present())
+			break;
+	}
+	if (i == 2)
+		ug_io_base = NULL;
+	return ug_io_base;
+
+}
+
+/*
+ * USB Gecko udbg support initialization.
+ */
+void __init ug_udbg_init(void)
+{
+	struct device_node *np;
+	void __iomem *exi_io_base;
+
+	if (ug_io_base)
+		udbg_printf("%s: early -> final\n", __func__);
+
+	np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
+	if (!np) {
+		udbg_printf("%s: EXI node not found\n", __func__);
+		goto done;
+	}
+
+	exi_io_base = ug_udbg_setup_exi_io_base(np);
+	if (!exi_io_base) {
+		udbg_printf("%s: failed to setup EXI io base\n", __func__);
+		goto done;
+	}
+
+	if (!ug_udbg_probe(exi_io_base)) {
+		udbg_printf("usbgecko_udbg: not found\n");
+		iounmap(exi_io_base);
+	} else {
+		udbg_putc = ug_udbg_putc;
+		udbg_getc = ug_udbg_getc;
+		udbg_getc_poll = ug_udbg_getc_poll;
+		udbg_printf("usbgecko_udbg: ready\n");
+	}
+
+done:
+	if (np)
+		of_node_put(np);
+	return;
+}
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
+
+static phys_addr_t __init ug_early_grab_io_addr(void)
+{
+#if defined(CONFIG_GAMECUBE)
+	return 0x0c000000;
+#elif defined(CONFIG_WII)
+	return 0x0d000000;
+#else
+#error Invalid platform for USB Gecko based early debugging.
+#endif
+}
+
+/*
+ * USB Gecko early debug support initialization for udbg.
+ */
+void __init udbg_init_usbgecko(void)
+{
+	void __iomem *early_debug_area;
+	void __iomem *exi_io_base;
+
+	/*
+	 * At this point we have a BAT already setup that enables I/O
+	 * to the EXI hardware.
+	 *
+	 * The BAT uses a virtual address range reserved at the fixmap.
+	 * This must match the virtual address configured in
+	 * head_32.S:setup_usbgecko_bat().
+	 */
+	early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE);
+	exi_io_base = early_debug_area + 0x00006800;
+
+	/* try to detect a USB Gecko */
+	if (!ug_udbg_probe(exi_io_base))
+		return;
+
+	/* we found a USB Gecko, load udbg hooks */
+	udbg_putc = ug_udbg_putc;
+	udbg_getc = ug_udbg_getc;
+	udbg_getc_poll = ug_udbg_getc_poll;
+
+	/*
+	 * Prepare again the same BAT for MMU_init.
+	 * This allows udbg I/O to continue working after the MMU is
+	 * turned on for real.
+	 * It is safe to continue using the same virtual address as it is
+	 * a reserved fixmap area.
+	 */
+	setbat(1, (unsigned long)early_debug_area,
+	       ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG);
+}
+
+#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h
+ *
+ * udbg serial input/output routines for the USB Gecko adapter.
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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 __USBGECKO_UDBG_H
+#define __USBGECKO_UDBG_H
+
+#ifdef CONFIG_USBGECKO_UDBG
+
+extern void __init ug_udbg_init(void);
+
+#else
+
+static inline void __init ug_udbg_init(void)
+{
+}
+
+#endif /* CONFIG_USBGECKO_UDBG */
+
+void __init udbg_init_usbgecko(void);
+
+#endif /* __USBGECKO_UDBG_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/wii.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/wii.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/embedded6xx/wii.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/embedded6xx/wii.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,268 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/wii.c
+ *
+ * Nintendo Wii board-specific support
+ * Copyright (C) 2008-2009 The GameCube Linux Team
+ * Copyright (C) 2008,2009 Albert Herranz
+ *
+ * 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.
+ *
+ */
+#define DRV_MODULE_NAME "wii"
+#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/kexec.h>
+#include <linux/of_platform.h>
+#include <linux/lmb.h>
+#include <mm/mmu_decl.h>
+
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+#include "flipper-pic.h"
+#include "hlwd-pic.h"
+#include "usbgecko_udbg.h"
+
+/* control block */
+#define HW_CTRL_COMPATIBLE	"nintendo,hollywood-control"
+
+#define HW_CTRL_RESETS		0x94
+#define HW_CTRL_RESETS_SYS	(1<<0)
+
+/* gpio */
+#define HW_GPIO_COMPATIBLE	"nintendo,hollywood-gpio"
+
+#define HW_GPIO_BASE(idx)	(idx * 0x20)
+#define HW_GPIO_OUT(idx)	(HW_GPIO_BASE(idx) + 0)
+#define HW_GPIO_DIR(idx)	(HW_GPIO_BASE(idx) + 4)
+
+#define HW_GPIO_SHUTDOWN	(1<<1)
+#define HW_GPIO_SLOT_LED	(1<<5)
+#define HW_GPIO_SENSOR_BAR	(1<<8)
+
+
+static void __iomem *hw_ctrl;
+static void __iomem *hw_gpio;
+
+unsigned long wii_hole_start;
+unsigned long wii_hole_size;
+
+
+static int __init page_aligned(unsigned long x)
+{
+	return !(x & (PAGE_SIZE-1));
+}
+
+void __init wii_memory_fixups(void)
+{
+	struct lmb_property *p = lmb.memory.region;
+
+	/*
+	 * This is part of a workaround to allow the use of two
+	 * discontiguous RAM ranges on the Wii, even if this is
+	 * currently unsupported on 32-bit PowerPC Linux.
+	 *
+	 * We coealesce the two memory ranges of the Wii into a
+	 * single range, then create a reservation for the "hole"
+	 * between both ranges.
+	 */
+
+	BUG_ON(lmb.memory.cnt != 2);
+	BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base));
+
+	p[0].size = _ALIGN_DOWN(p[0].size, PAGE_SIZE);
+	p[1].size = _ALIGN_DOWN(p[1].size, PAGE_SIZE);
+
+	wii_hole_start = p[0].base + p[0].size;
+	wii_hole_size = p[1].base - wii_hole_start;
+
+	pr_info("MEM1: <%08llx %08llx>\n", p[0].base, p[0].size);
+	pr_info("HOLE: <%08lx %08lx>\n", wii_hole_start, wii_hole_size);
+	pr_info("MEM2: <%08llx %08llx>\n", p[1].base, p[1].size);
+
+	p[0].size += wii_hole_size + p[1].size;
+
+	lmb.memory.cnt = 1;
+	lmb_analyze();
+
+	/* reserve the hole */
+	lmb_reserve(wii_hole_start, wii_hole_size);
+
+	/* allow ioremapping the address space in the hole */
+	__allow_ioremap_reserved = 1;
+}
+
+unsigned long __init wii_mmu_mapin_mem2(unsigned long top)
+{
+	unsigned long delta, size, bl;
+	unsigned long max_size = (256<<20);
+
+	/* MEM2 64MB@0x10000000 */
+	delta = wii_hole_start + wii_hole_size;
+	size = top - delta;
+	for (bl = 128<<10; bl < max_size; bl <<= 1) {
+		if (bl * 2 > size)
+			break;
+	}
+	setbat(4, PAGE_OFFSET+delta, delta, bl, PAGE_KERNEL_X);
+	return delta + bl;
+}
+
+static void wii_spin(void)
+{
+	local_irq_disable();
+	for (;;)
+		cpu_relax();
+}
+
+static void __iomem *wii_ioremap_hw_regs(char *name, char *compatible)
+{
+	void __iomem *hw_regs = NULL;
+	struct device_node *np;
+	struct resource res;
+	int error = -ENODEV;
+
+	np = of_find_compatible_node(NULL, NULL, compatible);
+	if (!np) {
+		pr_err("no compatible node found for %s\n", compatible);
+		goto out;
+	}
+	error = of_address_to_resource(np, 0, &res);
+	if (error) {
+		pr_err("no valid reg found for %s\n", np->name);
+		goto out_put;
+	}
+
+	hw_regs = ioremap(res.start, resource_size(&res));
+	if (hw_regs) {
+		pr_info("%s at 0x%08x mapped to 0x%p\n", name,
+			res.start, hw_regs);
+	}
+
+out_put:
+	of_node_put(np);
+out:
+	return hw_regs;
+}
+
+static void __init wii_setup_arch(void)
+{
+	hw_ctrl = wii_ioremap_hw_regs("hw_ctrl", HW_CTRL_COMPATIBLE);
+	hw_gpio = wii_ioremap_hw_regs("hw_gpio", HW_GPIO_COMPATIBLE);
+	if (hw_gpio) {
+		/* turn off the front blue led and IR light */
+		clrbits32(hw_gpio + HW_GPIO_OUT(0),
+			  HW_GPIO_SLOT_LED | HW_GPIO_SENSOR_BAR);
+	}
+}
+
+static void wii_restart(char *cmd)
+{
+	local_irq_disable();
+
+	if (hw_ctrl) {
+		/* clear the system reset pin to cause a reset */
+		clrbits32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
+	}
+	wii_spin();
+}
+
+static void wii_power_off(void)
+{
+	local_irq_disable();
+
+	if (hw_gpio) {
+		/* make sure that the poweroff GPIO is configured as output */
+		setbits32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
+
+		/* drive the poweroff GPIO high */
+		setbits32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
+	}
+	wii_spin();
+}
+
+static void wii_halt(void)
+{
+	if (ppc_md.restart)
+		ppc_md.restart(NULL);
+	wii_spin();
+}
+
+static void __init wii_init_early(void)
+{
+	ug_udbg_init();
+}
+
+static void __init wii_pic_probe(void)
+{
+	flipper_pic_probe();
+	hlwd_pic_probe();
+}
+
+static int __init wii_probe(void)
+{
+	unsigned long dt_root;
+
+	dt_root = of_get_flat_dt_root();
+	if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
+		return 0;
+
+	return 1;
+}
+
+static void wii_shutdown(void)
+{
+	hlwd_quiesce();
+	flipper_quiesce();
+}
+
+#ifdef CONFIG_KEXEC
+static int wii_machine_kexec_prepare(struct kimage *image)
+{
+	return 0;
+}
+#endif /* CONFIG_KEXEC */
+
+define_machine(wii) {
+	.name			= "wii",
+	.probe			= wii_probe,
+	.init_early		= wii_init_early,
+	.setup_arch		= wii_setup_arch,
+	.restart		= wii_restart,
+	.power_off		= wii_power_off,
+	.halt			= wii_halt,
+	.init_IRQ		= wii_pic_probe,
+	.get_irq		= flipper_pic_get_irq,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+	.machine_shutdown	= wii_shutdown,
+#ifdef CONFIG_KEXEC
+	.machine_kexec_prepare	= wii_machine_kexec_prepare,
+#endif
+};
+
+static struct of_device_id wii_of_bus[] = {
+	{ .compatible = "nintendo,hollywood", },
+	{ },
+};
+
+static int __init wii_device_probe(void)
+{
+	if (!machine_is(wii))
+		return 0;
+
+	of_platform_bus_probe(NULL, wii_of_bus, NULL);
+	return 0;
+}
+device_initcall(wii_device_probe);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/htab.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/htab.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/htab.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/htab.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,8 +19,7 @@
 
 #include "call_hpt.h"
 
-static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
-	{ [0 ... 63] = SPIN_LOCK_UNLOCKED};
+static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp;
 
 /*
  * Very primitive algorithm for picking up a lock
@@ -245,6 +244,11 @@ static void iSeries_hpte_invalidate(unsi
 
 void __init hpte_init_iSeries(void)
 {
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(iSeries_hlocks); i++)
+		spin_lock_init(&iSeries_hlocks[i]);
+
 	ppc_md.hpte_invalidate	= iSeries_hpte_invalidate;
 	ppc_md.hpte_updatepp	= iSeries_hpte_updatepp;
 	ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/irq.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/irq.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,12 +214,12 @@ void __init iSeries_activate_IRQs()
 	unsigned long flags;
 
 	for_each_irq (irq) {
-		struct irq_desc *desc = get_irq_desc(irq);
+		struct irq_desc *desc = irq_to_desc(irq);
 
 		if (desc && desc->chip && desc->chip->startup) {
-			spin_lock_irqsave(&desc->lock, flags);
+			raw_spin_lock_irqsave(&desc->lock, flags);
 			desc->chip->startup(irq);
-			spin_unlock_irqrestore(&desc->lock, flags);
+			raw_spin_unlock_irqrestore(&desc->lock, flags);
 		}
 	}
 }
@@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int
 }
 
 static struct irq_chip iseries_pic = {
-	.typename	= "iSeries irq controller",
+	.name	= "iSeries irq controller",
 	.startup	= iseries_startup_IRQ,
 	.shutdown	= iseries_shutdown_IRQ,
 	.unmask		= iseries_enable_IRQ,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/mf.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/mf.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/mf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/mf.c	2010-02-24 13:52:17.000000000 -0500
@@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_ti
 }
 
 #ifdef CONFIG_PROC_FS
-
-static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int mf_cmdline_proc_show(struct seq_file *m, void *v)
 {
-	int len;
-	char *p;
+	char *page, *p;
 	struct vsp_cmd_data vsp_cmd;
 	int rc;
 	dma_addr_t dma_addr;
 
 	/* The HV appears to return no more than 256 bytes of command line */
-	if (off >= 256)
-		return 0;
-	if ((off + count) > 256)
-		count = 256 - off;
+	page = kmalloc(256, GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
 
-	dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
-	if (dma_addr == DMA_ERROR_CODE)
+	dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE);
+	if (dma_addr == DMA_ERROR_CODE) {
+		kfree(page);
 		return -ENOMEM;
-	memset(page, 0, off + count);
+	}
+	memset(page, 0, 256);
 	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
 	vsp_cmd.cmd = 33;
 	vsp_cmd.sub_data.kern.token = dma_addr;
 	vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
-	vsp_cmd.sub_data.kern.side = (u64)data;
-	vsp_cmd.sub_data.kern.length = off + count;
+	vsp_cmd.sub_data.kern.side = (u64)m->private;
+	vsp_cmd.sub_data.kern.length = 256;
 	mb();
 	rc = signal_vsp_instruction(&vsp_cmd);
-	iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE);
-	if (rc)
+	iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE);
+	if (rc) {
+		kfree(page);
 		return rc;
-	if (vsp_cmd.result_code != 0)
+	}
+	if (vsp_cmd.result_code != 0) {
+		kfree(page);
 		return -ENOMEM;
+	}
 	p = page;
-	len = 0;
-	while (len < (off + count)) {
-		if ((*p == '\0') || (*p == '\n')) {
-			if (*p == '\0')
-				*p = '\n';
-			p++;
-			len++;
-			*eof = 1;
+	while (p - page < 256) {
+		if (*p == '\0' || *p == '\n') {
+			*p = '\n';
 			break;
 		}
 		p++;
-		len++;
-	}
 
-	if (len < off) {
-		*eof = 1;
-		len = 0;
 	}
-	return len;
+	seq_write(m, page, p - page);
+	kfree(page);
+	return 0;
+}
+
+static int mf_cmdline_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mf_cmdline_proc_show, PDE(inode)->data);
 }
 
 #if 0
@@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *pa
 }
 #endif
 
-static int proc_mf_dump_side(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int mf_side_proc_show(struct seq_file *m, void *v)
 {
-	int len;
 	char mf_current_side = ' ';
 	struct vsp_cmd_data vsp_cmd;
 
@@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page,
 		}
 	}
 
-	len = sprintf(page, "%c\n", mf_current_side);
+	seq_printf(m, "%c\n", mf_current_side);
+	return 0;
+}
 
-	if (len <= (off + count))
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+static int mf_side_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mf_side_proc_show, NULL);
 }
 
-static int proc_mf_change_side(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer,
+				  size_t count, loff_t *pos)
 {
 	char side;
 	u64 newSide;
@@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct fi
 	return count;
 }
 
+static const struct file_operations mf_side_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mf_side_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= mf_side_proc_write,
+};
+
 #if 0
 static void mf_getSrcHistory(char *buffer, int size)
 {
@@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffe
 }
 #endif
 
-static int proc_mf_dump_src(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int mf_src_proc_show(struct seq_file *m, void *v)
 {
 #if 0
 	int len;
@@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page,
 #endif
 }
 
-static int proc_mf_change_src(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static int mf_src_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mf_src_proc_show, NULL);
+}
+
+static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer,
+				 size_t count, loff_t *pos)
 {
 	char stkbuf[10];
 
@@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct fil
 	return count;
 }
 
-static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static const struct file_operations mf_src_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mf_src_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= mf_src_proc_write,
+};
+
+static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer,
+				     size_t count, loff_t *pos)
 {
+	void *data = PDE(file->f_path.dentry->d_inode)->data;
 	struct vsp_cmd_data vsp_cmd;
 	dma_addr_t dma_addr;
 	char *page;
@@ -1172,6 +1188,15 @@ out:
 	return ret;
 }
 
+static const struct file_operations mf_cmdline_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mf_cmdline_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= mf_cmdline_proc_write,
+};
+
 static ssize_t proc_mf_change_vmlinux(struct file *file,
 				      const char __user *buf,
 				      size_t count, loff_t *ppos)
@@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void)
 		if (!mf)
 			return 1;
 
-		ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf);
+		ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf,
+				       &mf_cmdline_proc_fops, (void *)(long)i);
 		if (!ent)
 			return 1;
-		ent->data = (void *)(long)i;
-		ent->read_proc = proc_mf_dump_cmdline;
-		ent->write_proc = proc_mf_change_cmdline;
 
 		if (i == 3)	/* no vmlinux entry for 'D' */
 			continue;
@@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void)
 			return 1;
 	}
 
-	ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+	ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
+			  &mf_side_proc_fops);
 	if (!ent)
 		return 1;
-	ent->data = (void *)0;
-	ent->read_proc = proc_mf_dump_side;
-	ent->write_proc = proc_mf_change_side;
 
-	ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
+	ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
+			  &mf_src_proc_fops);
 	if (!ent)
 		return 1;
-	ent->data = (void *)0;
-	ent->read_proc = proc_mf_dump_src;
-	ent->write_proc = proc_mf_change_src;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/vio.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/vio.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/vio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/vio.c	2010-02-24 13:52:17.000000000 -0500
@@ -474,6 +474,8 @@ static void __init get_viotape_info(stru
 	struct vio_waitevent we;
 	int ret;
 
+	init_completion(&we.com);
+
 	ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
 	if (ret) {
 		printk(KERN_WARNING "get_viotape_info: "
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/viopath.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/viopath.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/iseries/viopath.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/iseries/viopath.c	2010-02-24 13:52:17.000000000 -0500
@@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_
 	u16 vlanMap;
 	dma_addr_t handle;
 	HvLpEvent_Rc hvrc;
-	DECLARE_COMPLETION(done);
+	DECLARE_COMPLETION_ONSTACK(done);
 	struct device_node *node;
 	const char *sysid;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -86,6 +86,11 @@ config RTAS_ERROR_LOGGING
 	depends on PPC_RTAS
 	default n
 
+config PPC_RTAS_DAEMON
+	bool
+	depends on PPC_RTAS
+	default n
+
 config RTAS_PROC
 	bool "Proc interface to RTAS"
 	depends on PPC_RTAS
@@ -255,7 +260,7 @@ config QE_GPIO
 
 config CPM2
 	bool "Enable support for the CPM2 (Communications Processor Module)"
-	depends on MPC85xx || 8260
+	depends on (FSL_SOC_BOOKE && PPC32) || 8260
 	select CPM
 	select PPC_LIB_RHEAP
 	select PPC_PCI_CHOICE
@@ -300,7 +305,7 @@ source "arch/powerpc/sysdev/bestcomm/Kco
 
 config MPC8xxx_GPIO
 	bool "MPC8xxx GPIO support"
-	depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || PPC_85xx || PPC_86xx
+	depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || FSL_SOC_BOOKE || PPC_86xx
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Kconfig.cputype linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig.cputype
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Kconfig.cputype	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Kconfig.cputype	2010-02-24 13:52:17.000000000 -0500
@@ -28,8 +28,6 @@ config PPC_BOOK3S_32
 config PPC_85xx
 	bool "Freescale 85xx"
 	select E500
-	select FSL_SOC
-	select MPC85xx
 
 config PPC_8xx
 	bool "Freescale 8xx"
@@ -138,6 +136,14 @@ config PPC_FPU
 	bool
 	default y if PPC64
 
+config FSL_EMB_PERFMON
+	bool "Freescale Embedded Perfmon"
+	depends on E500 || PPC_83xx
+	help
+	  This is the Performance Monitor support found on the e500 core
+	  and some e300 cores (c3 and c4).  Select this only if your
+	  core supports the Embedded Performance Monitor APU
+
 config 4xx
 	bool
 	depends on 40x || 44x
@@ -153,13 +159,6 @@ config FSL_BOOKE
 	depends on E200 || E500
 	default y
 
-config FSL_EMB_PERFMON
-	bool "Freescale Embedded Perfmon"
-	depends on E500 || PPC_83xx
-	help
-	  This is the Performance Monitor support found on the e500 core
-	  and some e300 cores (c3 and c4).  Select this only if your
-	  core supports the Embedded Performance Monitor APU
 
 config PTE_64BIT
 	bool
@@ -312,7 +311,7 @@ config NR_CPUS
 
 config NOT_COHERENT_CACHE
 	bool
-	depends on 4xx || 8xx || E200 || PPC_MPC512x
+	depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
 	default y
 
 config CHECK_CACHE_COHERENCY
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@ obj-$(CONFIG_PPC_MPC52xx)	+= 52xx/
 obj-$(CONFIG_PPC_8xx)		+= 8xx/
 obj-$(CONFIG_PPC_82xx)		+= 82xx/
 obj-$(CONFIG_PPC_83xx)		+= 83xx/
-obj-$(CONFIG_PPC_85xx)		+= 85xx/
+obj-$(CONFIG_FSL_SOC_BOOKE)	+= 85xx/
 obj-$(CONFIG_PPC_86xx)		+= 86xx/
 obj-$(CONFIG_PPC_PSERIES)	+= pseries/
 obj-$(CONFIG_PPC_ISERIES)	+= iseries/
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pasemi/setup.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/setup.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pasemi/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pasemi/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,7 +71,7 @@ static void pas_restart(char *cmd)
 }
 
 #ifdef CONFIG_SMP
-static raw_spinlock_t timebase_lock;
+static arch_spinlock_t timebase_lock;
 static unsigned long timebase;
 
 static void __devinit pas_give_timebase(void)
@@ -80,11 +80,11 @@ static void __devinit pas_give_timebase(
 
 	local_irq_save(flags);
 	hard_irq_disable();
-	__raw_spin_lock(&timebase_lock);
+	arch_spin_lock(&timebase_lock);
 	mtspr(SPRN_TBCTL, TBCTL_FREEZE);
 	isync();
 	timebase = get_tb();
-	__raw_spin_unlock(&timebase_lock);
+	arch_spin_unlock(&timebase_lock);
 
 	while (timebase)
 		barrier();
@@ -97,10 +97,10 @@ static void __devinit pas_take_timebase(
 	while (!timebase)
 		smp_rmb();
 
-	__raw_spin_lock(&timebase_lock);
+	arch_spin_lock(&timebase_lock);
 	set_tb(timebase >> 32, timebase & 0xffffffff);
 	timebase = 0;
-	__raw_spin_unlock(&timebase_lock);
+	arch_spin_unlock(&timebase_lock);
 }
 
 struct smp_ops_t pas_smp_ops = {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/bootx_init.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/bootx_init.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/bootx_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/bootx_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/low_i2c.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/low_i2c.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/low_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/low_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/mutex.h>
+#include <linux/i2c.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
@@ -80,7 +81,7 @@ struct pmac_i2c_bus
 	struct device_node	*busnode;
 	int			type;
 	int			flags;
-	struct i2c_adapter	*adapter;
+	struct i2c_adapter	adapter;
 	void			*hostdata;
 	int			channel;	/* some hosts have multiple */
 	int			mode;		/* current mode */
@@ -1014,25 +1015,9 @@ int pmac_i2c_get_channel(struct pmac_i2c
 EXPORT_SYMBOL_GPL(pmac_i2c_get_channel);
 
 
-void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
-			     struct i2c_adapter *adapter)
-{
-	WARN_ON(bus->adapter != NULL);
-	bus->adapter = adapter;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter);
-
-void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
-			     struct i2c_adapter *adapter)
-{
-	WARN_ON(bus->adapter != adapter);
-	bus->adapter = NULL;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter);
-
 struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus)
 {
-	return bus->adapter;
+	return &bus->adapter;
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter);
 
@@ -1041,7 +1026,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to
 	struct pmac_i2c_bus *bus;
 
 	list_for_each_entry(bus, &pmac_i2c_busses, link)
-		if (bus->adapter == adapter)
+		if (&bus->adapter == adapter)
 			return bus;
 	return NULL;
 }
@@ -1053,7 +1038,7 @@ int pmac_i2c_match_adapter(struct device
 
 	if (bus == NULL)
 		return 0;
-	return (bus->adapter == adapter);
+	return (&bus->adapter == adapter);
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/pci.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pci.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -302,7 +302,7 @@ static void __init setup_chaos(struct pc
  *  1 -> Skip the device but act as if the access was successfull
  *       (return 0xff's on reads, eventually, cache config space
  *       accesses in a later version)
- * -1 -> Hide the device (unsuccessful acess)
+ * -1 -> Hide the device (unsuccessful access)
  */
 static int u3_ht_skip_device(struct pci_controller *hose,
 			     struct pci_bus *bus, unsigned int devfn)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/pic.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/powermac/pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/powermac/pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(uns
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
 
-  	spin_lock_irqsave(&pmac_pic_lock, flags);
-	if ((irq_desc[virq].status & IRQ_LEVEL) == 0)
+	spin_lock_irqsave(&pmac_pic_lock, flags);
+	if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
 		out_le32(&pmac_irq_hw[i]->ack, bit);
         __set_bit(src, ppc_cached_irq_mask);
         __pmac_set_irq_mask(src, 0);
-  	spin_unlock_irqrestore(&pmac_pic_lock, flags);
+	spin_unlock_irqrestore(&pmac_pic_lock, flags);
 
 	return 0;
 }
@@ -195,7 +195,7 @@ static int pmac_retrigger(unsigned int v
 }
 
 static struct irq_chip pmac_pic = {
-	.typename	= " PMAC-PIC ",
+	.name		= " PMAC-PIC ",
 	.startup	= pmac_startup_irq,
 	.mask		= pmac_mask_irq,
 	.ack		= pmac_ack_irq,
@@ -285,7 +285,7 @@ static int pmac_pic_host_match(struct ir
 static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	int level;
 
 	if (hw >= max_irqs)
@@ -303,7 +303,7 @@ static int pmac_pic_host_map(struct irq_
 }
 
 static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			       u32 *intspec, unsigned int intsize,
+			       const u32 *intspec, unsigned int intsize,
 			       irq_hw_number_t *out_hwirq,
 			       unsigned int *out_flags)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/ps3/interrupt.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/interrupt.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/ps3/interrupt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/interrupt.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,7 +152,7 @@ static void ps3_chip_eoi(unsigned int vi
  */
 
 static struct irq_chip ps3_irq_chip = {
-	.typename = "ps3",
+	.name = "ps3",
 	.mask = ps3_chip_mask,
 	.unmask = ps3_chip_unmask,
 	.eoi = ps3_chip_eoi,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/ps3/mm.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/mm.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/ps3/mm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/ps3/mm.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@
 #if defined(DEBUG)
 #define DBG udbg_printf
 #else
-#define DBG pr_debug
+#define DBG pr_devel
 #endif
 
 enum {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/cmm.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/cmm.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/cmm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/cmm.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,19 +38,28 @@
 #include <asm/mmu.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
+#include <linux/memory.h>
 
 #include "plpar_wrappers.h"
 
 #define CMM_DRIVER_VERSION	"1.0.0"
 #define CMM_DEFAULT_DELAY	1
+#define CMM_HOTPLUG_DELAY	5
 #define CMM_DEBUG			0
 #define CMM_DISABLE		0
 #define CMM_OOM_KB		1024
 #define CMM_MIN_MEM_MB		256
 #define KB2PAGES(_p)		((_p)>>(PAGE_SHIFT-10))
 #define PAGES2KB(_p)		((_p)<<(PAGE_SHIFT-10))
+/*
+ * The priority level tries to ensure that this notifier is called as
+ * late as possible to reduce thrashing in the shared memory pool.
+ */
+#define CMM_MEM_HOTPLUG_PRI	1
+#define CMM_MEM_ISOLATE_PRI	15
 
 static unsigned int delay = CMM_DEFAULT_DELAY;
+static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY;
 static unsigned int oom_kb = CMM_OOM_KB;
 static unsigned int cmm_debug = CMM_DEBUG;
 static unsigned int cmm_disabled = CMM_DISABLE;
@@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION);
 module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. "
 		 "[Default=" __stringify(CMM_DEFAULT_DELAY) "]");
+module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove "
+		 "before loaning resumes. "
+		 "[Default=" __stringify(CMM_HOTPLUG_DELAY) "]");
 module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. "
 		 "[Default=" __stringify(CMM_OOM_KB) "]");
@@ -92,6 +105,9 @@ static unsigned long oom_freed_pages;
 static struct cmm_page_array *cmm_page_list;
 static DEFINE_SPINLOCK(cmm_lock);
 
+static DEFINE_MUTEX(hotplug_mutex);
+static int hotplug_occurred; /* protected by the hotplug mutex */
+
 static struct task_struct *cmm_thread_ptr;
 
 /**
@@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr)
 	cmm_dbg("Begin request for %ld pages\n", nr);
 
 	while (nr) {
+		/* Exit if a hotplug operation is in progress or occurred */
+		if (mutex_trylock(&hotplug_mutex)) {
+			if (hotplug_occurred) {
+				mutex_unlock(&hotplug_mutex);
+				break;
+			}
+			mutex_unlock(&hotplug_mutex);
+		} else {
+			break;
+		}
+
 		addr = __get_free_page(GFP_NOIO | __GFP_NOWARN |
 				       __GFP_NORETRY | __GFP_NOMEMALLOC);
 		if (!addr)
@@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr)
 		if (!pa || pa->index >= CMM_NR_PAGES) {
 			/* Need a new page for the page list. */
 			spin_unlock(&cmm_lock);
-			npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN |
-								       __GFP_NORETRY | __GFP_NOMEMALLOC);
+			npa = (struct cmm_page_array *)__get_free_page(
+					GFP_NOIO | __GFP_NOWARN |
+					__GFP_NORETRY | __GFP_NOMEMALLOC);
 			if (!npa) {
 				pr_info("%s: Can not allocate new page list\n", __func__);
 				free_page(addr);
@@ -229,8 +257,9 @@ static void cmm_get_mpp(void)
 {
 	int rc;
 	struct hvcall_mpp_data mpp_data;
-	unsigned long active_pages_target;
-	signed long page_loan_request;
+	signed long active_pages_target, page_loan_request, target;
+	signed long total_pages = totalram_pages + loaned_pages;
+	signed long min_mem_pages = (min_mem_mb * 1024 * 1024) / PAGE_SIZE;
 
 	rc = h_get_mpp(&mpp_data);
 
@@ -238,17 +267,25 @@ static void cmm_get_mpp(void)
 		return;
 
 	page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE);
-	loaned_pages_target = page_loan_request + loaned_pages;
-	if (loaned_pages_target > oom_freed_pages)
-		loaned_pages_target -= oom_freed_pages;
+	target = page_loan_request + (signed long)loaned_pages;
+
+	if (target < 0 || total_pages < min_mem_pages)
+		target = 0;
+
+	if (target > oom_freed_pages)
+		target -= oom_freed_pages;
 	else
-		loaned_pages_target = 0;
+		target = 0;
 
-	active_pages_target = totalram_pages + loaned_pages - loaned_pages_target;
+	active_pages_target = total_pages - target;
 
-	if ((min_mem_mb * 1024 * 1024) > (active_pages_target * PAGE_SIZE))
-		loaned_pages_target = totalram_pages + loaned_pages -
-			((min_mem_mb * 1024 * 1024) / PAGE_SIZE);
+	if (min_mem_pages > active_pages_target)
+		target = total_pages - min_mem_pages;
+
+	if (target < 0)
+		target = 0;
+
+	loaned_pages_target = target;
 
 	cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n",
 		page_loan_request, loaned_pages, loaned_pages_target,
@@ -273,9 +310,28 @@ static int cmm_thread(void *dummy)
 	while (1) {
 		timeleft = msleep_interruptible(delay * 1000);
 
-		if (kthread_should_stop() || timeleft) {
-			loaned_pages_target = loaned_pages;
+		if (kthread_should_stop() || timeleft)
 			break;
+
+		if (mutex_trylock(&hotplug_mutex)) {
+			if (hotplug_occurred) {
+				hotplug_occurred = 0;
+				mutex_unlock(&hotplug_mutex);
+				cmm_dbg("Hotplug operation has occurred, "
+						"loaning activity suspended "
+						"for %d seconds.\n",
+						hotplug_delay);
+				timeleft = msleep_interruptible(hotplug_delay *
+						1000);
+				if (kthread_should_stop() || timeleft)
+					break;
+				continue;
+			}
+			mutex_unlock(&hotplug_mutex);
+		} else {
+			cmm_dbg("Hotplug operation in progress, activity "
+					"suspended\n");
+			continue;
 		}
 
 		cmm_get_mpp();
@@ -405,6 +461,193 @@ static struct notifier_block cmm_reboot_
 };
 
 /**
+ * cmm_count_pages - Count the number of pages loaned in a particular range.
+ *
+ * @arg: memory_isolate_notify structure with address range and count
+ *
+ * Return value:
+ *      0 on success
+ **/
+static unsigned long cmm_count_pages(void *arg)
+{
+	struct memory_isolate_notify *marg = arg;
+	struct cmm_page_array *pa;
+	unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn);
+	unsigned long end = start + (marg->nr_pages << PAGE_SHIFT);
+	unsigned long idx;
+
+	spin_lock(&cmm_lock);
+	pa = cmm_page_list;
+	while (pa) {
+		if ((unsigned long)pa >= start && (unsigned long)pa < end)
+			marg->pages_found++;
+		for (idx = 0; idx < pa->index; idx++)
+			if (pa->page[idx] >= start && pa->page[idx] < end)
+				marg->pages_found++;
+		pa = pa->next;
+	}
+	spin_unlock(&cmm_lock);
+	return 0;
+}
+
+/**
+ * cmm_memory_isolate_cb - Handle memory isolation notifier calls
+ * @self:	notifier block struct
+ * @action:	action to take
+ * @arg:	struct memory_isolate_notify data for handler
+ *
+ * Return value:
+ *	NOTIFY_OK or notifier error based on subfunction return value
+ **/
+static int cmm_memory_isolate_cb(struct notifier_block *self,
+				 unsigned long action, void *arg)
+{
+	int ret = 0;
+
+	if (action == MEM_ISOLATE_COUNT)
+		ret = cmm_count_pages(arg);
+
+	if (ret)
+		ret = notifier_from_errno(ret);
+	else
+		ret = NOTIFY_OK;
+
+	return ret;
+}
+
+static struct notifier_block cmm_mem_isolate_nb = {
+	.notifier_call = cmm_memory_isolate_cb,
+	.priority = CMM_MEM_ISOLATE_PRI
+};
+
+/**
+ * cmm_mem_going_offline - Unloan pages where memory is to be removed
+ * @arg: memory_notify structure with page range to be offlined
+ *
+ * Return value:
+ *	0 on success
+ **/
+static int cmm_mem_going_offline(void *arg)
+{
+	struct memory_notify *marg = arg;
+	unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn);
+	unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT);
+	struct cmm_page_array *pa_curr, *pa_last, *npa;
+	unsigned long idx;
+	unsigned long freed = 0;
+
+	cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n",
+			start_page, marg->nr_pages);
+	spin_lock(&cmm_lock);
+
+	/* Search the page list for pages in the range to be offlined */
+	pa_last = pa_curr = cmm_page_list;
+	while (pa_curr) {
+		for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) {
+			if ((pa_curr->page[idx] < start_page) ||
+			    (pa_curr->page[idx] >= end_page))
+				continue;
+
+			plpar_page_set_active(__pa(pa_curr->page[idx]));
+			free_page(pa_curr->page[idx]);
+			freed++;
+			loaned_pages--;
+			totalram_pages++;
+			pa_curr->page[idx] = pa_last->page[--pa_last->index];
+			if (pa_last->index == 0) {
+				if (pa_curr == pa_last)
+					pa_curr = pa_last->next;
+				pa_last = pa_last->next;
+				free_page((unsigned long)cmm_page_list);
+				cmm_page_list = pa_last;
+				continue;
+			}
+		}
+		pa_curr = pa_curr->next;
+	}
+
+	/* Search for page list structures in the range to be offlined */
+	pa_last = NULL;
+	pa_curr = cmm_page_list;
+	while (pa_curr) {
+		if (((unsigned long)pa_curr >= start_page) &&
+				((unsigned long)pa_curr < end_page)) {
+			npa = (struct cmm_page_array *)__get_free_page(
+					GFP_NOIO | __GFP_NOWARN |
+					__GFP_NORETRY | __GFP_NOMEMALLOC);
+			if (!npa) {
+				spin_unlock(&cmm_lock);
+				cmm_dbg("Failed to allocate memory for list "
+						"management. Memory hotplug "
+						"failed.\n");
+				return ENOMEM;
+			}
+			memcpy(npa, pa_curr, PAGE_SIZE);
+			if (pa_curr == cmm_page_list)
+				cmm_page_list = npa;
+			if (pa_last)
+				pa_last->next = npa;
+			free_page((unsigned long) pa_curr);
+			freed++;
+			pa_curr = npa;
+		}
+
+		pa_last = pa_curr;
+		pa_curr = pa_curr->next;
+	}
+
+	spin_unlock(&cmm_lock);
+	cmm_dbg("Released %ld pages in the search range.\n", freed);
+
+	return 0;
+}
+
+/**
+ * cmm_memory_cb - Handle memory hotplug notifier calls
+ * @self:	notifier block struct
+ * @action:	action to take
+ * @arg:	struct memory_notify data for handler
+ *
+ * Return value:
+ *	NOTIFY_OK or notifier error based on subfunction return value
+ *
+ **/
+static int cmm_memory_cb(struct notifier_block *self,
+			unsigned long action, void *arg)
+{
+	int ret = 0;
+
+	switch (action) {
+	case MEM_GOING_OFFLINE:
+		mutex_lock(&hotplug_mutex);
+		hotplug_occurred = 1;
+		ret = cmm_mem_going_offline(arg);
+		break;
+	case MEM_OFFLINE:
+	case MEM_CANCEL_OFFLINE:
+		mutex_unlock(&hotplug_mutex);
+		cmm_dbg("Memory offline operation complete.\n");
+		break;
+	case MEM_GOING_ONLINE:
+	case MEM_ONLINE:
+	case MEM_CANCEL_ONLINE:
+		break;
+	}
+
+	if (ret)
+		ret = notifier_from_errno(ret);
+	else
+		ret = NOTIFY_OK;
+
+	return ret;
+}
+
+static struct notifier_block cmm_mem_nb = {
+	.notifier_call = cmm_memory_cb,
+	.priority = CMM_MEM_HOTPLUG_PRI
+};
+
+/**
  * cmm_init - Module initialization
  *
  * Return value:
@@ -426,18 +669,24 @@ static int cmm_init(void)
 	if ((rc = cmm_sysfs_register(&cmm_sysdev)))
 		goto out_reboot_notifier;
 
+	if (register_memory_notifier(&cmm_mem_nb) ||
+	    register_memory_isolate_notifier(&cmm_mem_isolate_nb))
+		goto out_unregister_notifier;
+
 	if (cmm_disabled)
 		return rc;
 
 	cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
 	if (IS_ERR(cmm_thread_ptr)) {
 		rc = PTR_ERR(cmm_thread_ptr);
-		goto out_unregister_sysfs;
+		goto out_unregister_notifier;
 	}
 
 	return rc;
 
-out_unregister_sysfs:
+out_unregister_notifier:
+	unregister_memory_notifier(&cmm_mem_nb);
+	unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
 	cmm_unregister_sysfs(&cmm_sysdev);
 out_reboot_notifier:
 	unregister_reboot_notifier(&cmm_reboot_nb);
@@ -458,6 +707,8 @@ static void cmm_exit(void)
 		kthread_stop(cmm_thread_ptr);
 	unregister_oom_notifier(&cmm_oom_nb);
 	unregister_reboot_notifier(&cmm_reboot_nb);
+	unregister_memory_notifier(&cmm_mem_nb);
+	unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
 	cmm_free_pages(loaned_pages);
 	cmm_unregister_sysfs(&cmm_sysdev);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/dlpar.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dlpar.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/dlpar.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dlpar.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,548 @@
+/*
+ * Support for dynamic reconfiguration for PCI, Memory, and CPU
+ * Hotplug and Dynamic Logical Partitioning on RPA platforms.
+ *
+ * Copyright (C) 2009 Nathan Fontenot
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/cpu.h>
+#include "offline_states.h"
+
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/uaccess.h>
+#include <asm/rtas.h>
+#include <asm/pSeries_reconfig.h>
+
+struct cc_workarea {
+	u32	drc_index;
+	u32	zero;
+	u32	name_offset;
+	u32	prop_length;
+	u32	prop_offset;
+};
+
+static void dlpar_free_cc_property(struct property *prop)
+{
+	kfree(prop->name);
+	kfree(prop->value);
+	kfree(prop);
+}
+
+static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
+{
+	struct property *prop;
+	char *name;
+	char *value;
+
+	prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+	if (!prop)
+		return NULL;
+
+	name = (char *)ccwa + ccwa->name_offset;
+	prop->name = kstrdup(name, GFP_KERNEL);
+
+	prop->length = ccwa->prop_length;
+	value = (char *)ccwa + ccwa->prop_offset;
+	prop->value = kzalloc(prop->length, GFP_KERNEL);
+	if (!prop->value) {
+		dlpar_free_cc_property(prop);
+		return NULL;
+	}
+
+	memcpy(prop->value, value, prop->length);
+	return prop;
+}
+
+static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
+{
+	struct device_node *dn;
+	char *name;
+
+	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+	if (!dn)
+		return NULL;
+
+	/* The configure connector reported name does not contain a
+	 * preceeding '/', so we allocate a buffer large enough to
+	 * prepend this to the full_name.
+	 */
+	name = (char *)ccwa + ccwa->name_offset;
+	dn->full_name = kmalloc(strlen(name) + 2, GFP_KERNEL);
+	if (!dn->full_name) {
+		kfree(dn);
+		return NULL;
+	}
+
+	sprintf(dn->full_name, "/%s", name);
+	return dn;
+}
+
+static void dlpar_free_one_cc_node(struct device_node *dn)
+{
+	struct property *prop;
+
+	while (dn->properties) {
+		prop = dn->properties;
+		dn->properties = prop->next;
+		dlpar_free_cc_property(prop);
+	}
+
+	kfree(dn->full_name);
+	kfree(dn);
+}
+
+static void dlpar_free_cc_nodes(struct device_node *dn)
+{
+	if (dn->child)
+		dlpar_free_cc_nodes(dn->child);
+
+	if (dn->sibling)
+		dlpar_free_cc_nodes(dn->sibling);
+
+	dlpar_free_one_cc_node(dn);
+}
+
+#define NEXT_SIBLING    1
+#define NEXT_CHILD      2
+#define NEXT_PROPERTY   3
+#define PREV_PARENT     4
+#define MORE_MEMORY     5
+#define CALL_AGAIN	-2
+#define ERR_CFG_USE     -9003
+
+struct device_node *dlpar_configure_connector(u32 drc_index)
+{
+	struct device_node *dn;
+	struct device_node *first_dn = NULL;
+	struct device_node *last_dn = NULL;
+	struct property *property;
+	struct property *last_property = NULL;
+	struct cc_workarea *ccwa;
+	int cc_token;
+	int rc;
+
+	cc_token = rtas_token("ibm,configure-connector");
+	if (cc_token == RTAS_UNKNOWN_SERVICE)
+		return NULL;
+
+	spin_lock(&rtas_data_buf_lock);
+	ccwa = (struct cc_workarea *)&rtas_data_buf[0];
+	ccwa->drc_index = drc_index;
+	ccwa->zero = 0;
+
+	rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
+	while (rc) {
+		switch (rc) {
+		case NEXT_SIBLING:
+			dn = dlpar_parse_cc_node(ccwa);
+			if (!dn)
+				goto cc_error;
+
+			dn->parent = last_dn->parent;
+			last_dn->sibling = dn;
+			last_dn = dn;
+			break;
+
+		case NEXT_CHILD:
+			dn = dlpar_parse_cc_node(ccwa);
+			if (!dn)
+				goto cc_error;
+
+			if (!first_dn)
+				first_dn = dn;
+			else {
+				dn->parent = last_dn;
+				if (last_dn)
+					last_dn->child = dn;
+			}
+
+			last_dn = dn;
+			break;
+
+		case NEXT_PROPERTY:
+			property = dlpar_parse_cc_property(ccwa);
+			if (!property)
+				goto cc_error;
+
+			if (!last_dn->properties)
+				last_dn->properties = property;
+			else
+				last_property->next = property;
+
+			last_property = property;
+			break;
+
+		case PREV_PARENT:
+			last_dn = last_dn->parent;
+			break;
+
+		case CALL_AGAIN:
+			break;
+
+		case MORE_MEMORY:
+		case ERR_CFG_USE:
+		default:
+			printk(KERN_ERR "Unexpected Error (%d) "
+			       "returned from configure-connector\n", rc);
+			goto cc_error;
+		}
+
+		rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
+	}
+
+	spin_unlock(&rtas_data_buf_lock);
+	return first_dn;
+
+cc_error:
+	if (first_dn)
+		dlpar_free_cc_nodes(first_dn);
+	spin_unlock(&rtas_data_buf_lock);
+	return NULL;
+}
+
+static struct device_node *derive_parent(const char *path)
+{
+	struct device_node *parent;
+	char *last_slash;
+
+	last_slash = strrchr(path, '/');
+	if (last_slash == path) {
+		parent = of_find_node_by_path("/");
+	} else {
+		char *parent_path;
+		int parent_path_len = last_slash - path + 1;
+		parent_path = kmalloc(parent_path_len, GFP_KERNEL);
+		if (!parent_path)
+			return NULL;
+
+		strlcpy(parent_path, path, parent_path_len);
+		parent = of_find_node_by_path(parent_path);
+		kfree(parent_path);
+	}
+
+	return parent;
+}
+
+int dlpar_attach_node(struct device_node *dn)
+{
+#ifdef CONFIG_PROC_DEVICETREE
+	struct proc_dir_entry *ent;
+#endif
+	int rc;
+
+	of_node_set_flag(dn, OF_DYNAMIC);
+	kref_init(&dn->kref);
+	dn->parent = derive_parent(dn->full_name);
+	if (!dn->parent)
+		return -ENOMEM;
+
+	rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
+					  PSERIES_RECONFIG_ADD, dn);
+	if (rc == NOTIFY_BAD) {
+		printk(KERN_ERR "Failed to add device node %s\n",
+		       dn->full_name);
+		return -ENOMEM; /* For now, safe to assume kmalloc failure */
+	}
+
+	of_attach_node(dn);
+
+#ifdef CONFIG_PROC_DEVICETREE
+	ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
+	if (ent)
+		proc_device_tree_add_node(dn, ent);
+#endif
+
+	of_node_put(dn->parent);
+	return 0;
+}
+
+int dlpar_detach_node(struct device_node *dn)
+{
+#ifdef CONFIG_PROC_DEVICETREE
+	struct device_node *parent = dn->parent;
+	struct property *prop = dn->properties;
+
+	while (prop) {
+		remove_proc_entry(prop->name, dn->pde);
+		prop = prop->next;
+	}
+
+	if (dn->pde)
+		remove_proc_entry(dn->pde->name, parent->pde);
+#endif
+
+	blocking_notifier_call_chain(&pSeries_reconfig_chain,
+			    PSERIES_RECONFIG_REMOVE, dn);
+	of_detach_node(dn);
+	of_node_put(dn); /* Must decrement the refcount */
+
+	return 0;
+}
+
+#define DR_ENTITY_SENSE		9003
+#define DR_ENTITY_PRESENT	1
+#define DR_ENTITY_UNUSABLE	2
+#define ALLOCATION_STATE	9003
+#define ALLOC_UNUSABLE		0
+#define ALLOC_USABLE		1
+#define ISOLATION_STATE		9001
+#define ISOLATE			0
+#define UNISOLATE		1
+
+int dlpar_acquire_drc(u32 drc_index)
+{
+	int dr_status, rc;
+
+	rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
+		       DR_ENTITY_SENSE, drc_index);
+	if (rc || dr_status != DR_ENTITY_UNUSABLE)
+		return -1;
+
+	rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_USABLE);
+	if (rc)
+		return rc;
+
+	rc = rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
+	if (rc) {
+		rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
+		return rc;
+	}
+
+	return 0;
+}
+
+int dlpar_release_drc(u32 drc_index)
+{
+	int dr_status, rc;
+
+	rc = rtas_call(rtas_token("get-sensor-state"), 2, 2, &dr_status,
+		       DR_ENTITY_SENSE, drc_index);
+	if (rc || dr_status != DR_ENTITY_PRESENT)
+		return -1;
+
+	rc = rtas_set_indicator(ISOLATION_STATE, drc_index, ISOLATE);
+	if (rc)
+		return rc;
+
+	rc = rtas_set_indicator(ALLOCATION_STATE, drc_index, ALLOC_UNUSABLE);
+	if (rc) {
+		rtas_set_indicator(ISOLATION_STATE, drc_index, UNISOLATE);
+		return rc;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+
+static int dlpar_online_cpu(struct device_node *dn)
+{
+	int rc = 0;
+	unsigned int cpu;
+	int len, nthreads, i;
+	const u32 *intserv;
+
+	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+	if (!intserv)
+		return -EINVAL;
+
+	nthreads = len / sizeof(u32);
+
+	cpu_maps_update_begin();
+	for (i = 0; i < nthreads; i++) {
+		for_each_present_cpu(cpu) {
+			if (get_hard_smp_processor_id(cpu) != intserv[i])
+				continue;
+			BUG_ON(get_cpu_current_state(cpu)
+					!= CPU_STATE_OFFLINE);
+			cpu_maps_update_done();
+			rc = cpu_up(cpu);
+			if (rc)
+				goto out;
+			cpu_maps_update_begin();
+
+			break;
+		}
+		if (cpu == num_possible_cpus())
+			printk(KERN_WARNING "Could not find cpu to online "
+			       "with physical id 0x%x\n", intserv[i]);
+	}
+	cpu_maps_update_done();
+
+out:
+	return rc;
+
+}
+
+static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
+{
+	struct device_node *dn;
+	unsigned long drc_index;
+	char *cpu_name;
+	int rc;
+
+	cpu_hotplug_driver_lock();
+	rc = strict_strtoul(buf, 0, &drc_index);
+	if (rc) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	dn = dlpar_configure_connector(drc_index);
+	if (!dn) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* configure-connector reports cpus as living in the base
+	 * directory of the device tree.  CPUs actually live in the
+	 * cpus directory so we need to fixup the full_name.
+	 */
+	cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1,
+			   GFP_KERNEL);
+	if (!cpu_name) {
+		dlpar_free_cc_nodes(dn);
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	sprintf(cpu_name, "/cpus%s", dn->full_name);
+	kfree(dn->full_name);
+	dn->full_name = cpu_name;
+
+	rc = dlpar_acquire_drc(drc_index);
+	if (rc) {
+		dlpar_free_cc_nodes(dn);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = dlpar_attach_node(dn);
+	if (rc) {
+		dlpar_release_drc(drc_index);
+		dlpar_free_cc_nodes(dn);
+	}
+
+	rc = dlpar_online_cpu(dn);
+out:
+	cpu_hotplug_driver_unlock();
+
+	return rc ? rc : count;
+}
+
+static int dlpar_offline_cpu(struct device_node *dn)
+{
+	int rc = 0;
+	unsigned int cpu;
+	int len, nthreads, i;
+	const u32 *intserv;
+
+	intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+	if (!intserv)
+		return -EINVAL;
+
+	nthreads = len / sizeof(u32);
+
+	cpu_maps_update_begin();
+	for (i = 0; i < nthreads; i++) {
+		for_each_present_cpu(cpu) {
+			if (get_hard_smp_processor_id(cpu) != intserv[i])
+				continue;
+
+			if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
+				break;
+
+			if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
+				cpu_maps_update_done();
+				rc = cpu_down(cpu);
+				if (rc)
+					goto out;
+				cpu_maps_update_begin();
+				break;
+
+			}
+
+			/*
+			 * The cpu is in CPU_STATE_INACTIVE.
+			 * Upgrade it's state to CPU_STATE_OFFLINE.
+			 */
+			set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
+			BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
+								!= H_SUCCESS);
+			__cpu_die(cpu);
+			break;
+		}
+		if (cpu == num_possible_cpus())
+			printk(KERN_WARNING "Could not find cpu to offline "
+			       "with physical id 0x%x\n", intserv[i]);
+	}
+	cpu_maps_update_done();
+
+out:
+	return rc;
+
+}
+
+static ssize_t dlpar_cpu_release(const char *buf, size_t count)
+{
+	struct device_node *dn;
+	const u32 *drc_index;
+	int rc;
+
+	dn = of_find_node_by_path(buf);
+	if (!dn)
+		return -EINVAL;
+
+	drc_index = of_get_property(dn, "ibm,my-drc-index", NULL);
+	if (!drc_index) {
+		of_node_put(dn);
+		return -EINVAL;
+	}
+
+	cpu_hotplug_driver_lock();
+	rc = dlpar_offline_cpu(dn);
+	if (rc) {
+		of_node_put(dn);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	rc = dlpar_release_drc(*drc_index);
+	if (rc) {
+		of_node_put(dn);
+		goto out;
+	}
+
+	rc = dlpar_detach_node(dn);
+	if (rc) {
+		dlpar_acquire_drc(*drc_index);
+		goto out;
+	}
+
+	of_node_put(dn);
+out:
+	cpu_hotplug_driver_unlock();
+	return rc ? rc : count;
+}
+
+static int __init pseries_dlpar_init(void)
+{
+	ppc_md.cpu_probe = dlpar_cpu_probe;
+	ppc_md.cpu_release = dlpar_cpu_release;
+
+	return 0;
+}
+machine_device_initcall(pseries, pseries_dlpar_init);
+
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/dtl.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dtl.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/dtl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/dtl.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@ struct dtl {
 	int			buf_entries;
 	u64			last_idx;
 };
-static DEFINE_PER_CPU(struct dtl, dtl);
+static DEFINE_PER_CPU(struct dtl, cpu_dtl);
 
 /*
  * Dispatch trace log event mask:
@@ -261,7 +261,7 @@ static int dtl_init(void)
 
 	/* set up the per-cpu log structures */
 	for_each_possible_cpu(i) {
-		struct dtl *dtl = &per_cpu(dtl, i);
+		struct dtl *dtl = &per_cpu(cpu_dtl, i);
 		dtl->cpu = i;
 
 		rc = dtl_setup_file(dtl);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -63,22 +63,6 @@ static void print_device_node_tree(struc
 }
 #endif
 
-/** 
- * irq_in_use - return true if this irq is being used 
- */
-static int irq_in_use(unsigned int irq)
-{
-	int rc = 0;
-	unsigned long flags;
-   struct irq_desc *desc = irq_desc + irq;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (desc->action)
-		rc = 1;
-	spin_unlock_irqrestore(&desc->lock, flags);
-	return rc;
-}
-
 /**
  * eeh_disable_irq - disable interrupt for the recovering device
  */
@@ -93,7 +77,7 @@ static void eeh_disable_irq(struct pci_d
 	if (dev->msi_enabled || dev->msix_enabled)
 		return;
 
-	if (!irq_in_use(dev->irq))
+	if (!irq_has_action(dev->irq))
 		return;
 
 	PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <asm/pSeries_reconfig.h>
 #include "xics.h"
 #include "plpar_wrappers.h"
+#include "offline_states.h"
 
 /* This version can't take the spinlock, because it never returns */
 static struct rtas_args rtas_stop_self_args = {
@@ -39,6 +40,55 @@ static struct rtas_args rtas_stop_self_a
 	.rets = &rtas_stop_self_args.args[0],
 };
 
+static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
+							CPU_STATE_OFFLINE;
+static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE;
+
+static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
+
+static int cede_offline_enabled __read_mostly = 1;
+
+/*
+ * Enable/disable cede_offline when available.
+ */
+static int __init setup_cede_offline(char *str)
+{
+	if (!strcmp(str, "off"))
+		cede_offline_enabled = 0;
+	else if (!strcmp(str, "on"))
+		cede_offline_enabled = 1;
+	else
+		return 0;
+	return 1;
+}
+
+__setup("cede_offline=", setup_cede_offline);
+
+enum cpu_state_vals get_cpu_current_state(int cpu)
+{
+	return per_cpu(current_state, cpu);
+}
+
+void set_cpu_current_state(int cpu, enum cpu_state_vals state)
+{
+	per_cpu(current_state, cpu) = state;
+}
+
+enum cpu_state_vals get_preferred_offline_state(int cpu)
+{
+	return per_cpu(preferred_offline_state, cpu);
+}
+
+void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
+{
+	per_cpu(preferred_offline_state, cpu) = state;
+}
+
+void set_default_offline_state(int cpu)
+{
+	per_cpu(preferred_offline_state, cpu) = default_offline_state;
+}
+
 static void rtas_stop_self(void)
 {
 	struct rtas_args *args = &rtas_stop_self_args;
@@ -56,11 +106,61 @@ static void rtas_stop_self(void)
 
 static void pseries_mach_cpu_die(void)
 {
+	unsigned int cpu = smp_processor_id();
+	unsigned int hwcpu = hard_smp_processor_id();
+	u8 cede_latency_hint = 0;
+
 	local_irq_disable();
 	idle_task_exit();
 	xics_teardown_cpu();
-	unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
-	rtas_stop_self();
+
+	if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
+		set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
+		cede_latency_hint = 2;
+
+		get_lppaca()->idle = 1;
+		if (!get_lppaca()->shared_proc)
+			get_lppaca()->donate_dedicated_cpu = 1;
+
+		printk(KERN_INFO
+			"cpu %u (hwid %u) ceding for offline with hint %d\n",
+			cpu, hwcpu, cede_latency_hint);
+		while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
+			extended_cede_processor(cede_latency_hint);
+			printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
+				cpu, hwcpu);
+			printk(KERN_INFO
+			"Decrementer value = %x Timebase value = %llx\n",
+			get_dec(), get_tb());
+		}
+
+		printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
+			cpu, hwcpu);
+
+		if (!get_lppaca()->shared_proc)
+			get_lppaca()->donate_dedicated_cpu = 0;
+		get_lppaca()->idle = 0;
+	}
+
+	if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+		unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+
+		/*
+		 * NOTE: Calling start_secondary() here for now to
+		 * start new context.
+		 * However, need to do it cleanly by resetting the
+		 * stack pointer.
+		 */
+		start_secondary();
+
+	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+
+		set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+		unregister_slb_shadow(hard_smp_processor_id(),
+					__pa(get_slb_shadow()));
+		rtas_stop_self();
+	}
+
 	/* Should never get here... */
 	BUG();
 	for(;;);
@@ -106,18 +206,43 @@ static int pseries_cpu_disable(void)
 	return 0;
 }
 
+/*
+ * pseries_cpu_die: Wait for the cpu to die.
+ * @cpu: logical processor id of the CPU whose death we're awaiting.
+ *
+ * This function is called from the context of the thread which is performing
+ * the cpu-offline. Here we wait for long enough to allow the cpu in question
+ * to self-destroy so that the cpu-offline thread can send the CPU_DEAD
+ * notifications.
+ *
+ * OTOH, pseries_mach_cpu_die() is called by the @cpu when it wants to
+ * self-destruct.
+ */
 static void pseries_cpu_die(unsigned int cpu)
 {
 	int tries;
-	int cpu_status;
+	int cpu_status = 1;
 	unsigned int pcpu = get_hard_smp_processor_id(cpu);
 
-	for (tries = 0; tries < 25; tries++) {
-		cpu_status = query_cpu_stopped(pcpu);
-		if (cpu_status == 0 || cpu_status == -1)
-			break;
-		cpu_relax();
+	if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
+		cpu_status = 1;
+		for (tries = 0; tries < 1000; tries++) {
+			if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) {
+				cpu_status = 0;
+				break;
+			}
+			cpu_relax();
+		}
+	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+
+		for (tries = 0; tries < 25; tries++) {
+			cpu_status = query_cpu_stopped(pcpu);
+			if (cpu_status == 0 || cpu_status == -1)
+				break;
+			cpu_relax();
+		}
 	}
+
 	if (cpu_status != 0) {
 		printk("Querying DEAD? cpu %i (%i) shows %i\n",
 		       cpu, pcpu, cpu_status);
@@ -252,10 +377,41 @@ static struct notifier_block pseries_smp
 	.notifier_call = pseries_smp_notifier,
 };
 
+#define MAX_CEDE_LATENCY_LEVELS		4
+#define	CEDE_LATENCY_PARAM_LENGTH	10
+#define CEDE_LATENCY_PARAM_MAX_LENGTH	\
+	(MAX_CEDE_LATENCY_LEVELS * CEDE_LATENCY_PARAM_LENGTH * sizeof(char))
+#define CEDE_LATENCY_TOKEN		45
+
+static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH];
+
+static int parse_cede_parameters(void)
+{
+	int call_status;
+
+	memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
+	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+				NULL,
+				CEDE_LATENCY_TOKEN,
+				__pa(cede_parameters),
+				CEDE_LATENCY_PARAM_MAX_LENGTH);
+
+	if (call_status != 0)
+		printk(KERN_INFO "CEDE_LATENCY: \
+			%s %s Error calling get-system-parameter(0x%x)\n",
+			__FILE__, __func__, call_status);
+	else
+		printk(KERN_INFO "CEDE_LATENCY: \
+			get-system-parameter successful.\n");
+
+	return call_status;
+}
+
 static int __init pseries_cpu_hotplug_init(void)
 {
 	struct device_node *np;
 	const char *typep;
+	int cpu;
 
 	for_each_node_by_name(np, "interrupt-controller") {
 		typep = of_get_property(np, "compatible", NULL);
@@ -283,8 +439,16 @@ static int __init pseries_cpu_hotplug_in
 	smp_ops->cpu_die = pseries_cpu_die;
 
 	/* Processors can be added/removed only on LPAR */
-	if (firmware_has_feature(FW_FEATURE_LPAR))
+	if (firmware_has_feature(FW_FEATURE_LPAR)) {
 		pSeries_reconfig_notifier_register(&pseries_smp_nb);
+		cpu_maps_update_begin();
+		if (cede_offline_enabled && parse_cede_parameters() == 0) {
+			default_offline_state = CPU_STATE_INACTIVE;
+			for_each_online_cpu(cpu)
+				set_default_offline_state(cpu);
+		}
+		cpu_maps_update_done();
+	}
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall_inst.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <asm/hvcall.h>
 #include <asm/firmware.h>
 #include <asm/cputable.h>
+#include <asm/trace.h>
 
 DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
 
@@ -100,6 +101,35 @@ static const struct file_operations hcal
 #define	HCALL_ROOT_DIR		"hcall_inst"
 #define CPU_NAME_BUF_SIZE	32
 
+
+static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
+{
+	struct hcall_stats *h;
+
+	if (opcode > MAX_HCALL_OPCODE)
+		return;
+
+	h = &get_cpu_var(hcall_stats)[opcode / 4];
+	h->tb_start = mftb();
+	h->purr_start = mfspr(SPRN_PURR);
+}
+
+static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
+			     unsigned long *retbuf)
+{
+	struct hcall_stats *h;
+
+	if (opcode > MAX_HCALL_OPCODE)
+		return;
+
+	h = &__get_cpu_var(hcall_stats)[opcode / 4];
+	h->num_calls++;
+	h->tb_total = mftb() - h->tb_start;
+	h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
+
+	put_cpu_var(hcall_stats);
+}
+
 static int __init hcall_inst_init(void)
 {
 	struct dentry *hcall_root;
@@ -110,6 +140,14 @@ static int __init hcall_inst_init(void)
 	if (!firmware_has_feature(FW_FEATURE_LPAR))
 		return 0;
 
+	if (register_trace_hcall_entry(probe_hcall_entry))
+		return -EINVAL;
+
+	if (register_trace_hcall_exit(probe_hcall_exit)) {
+		unregister_trace_hcall_entry(probe_hcall_entry);
+		return -EINVAL;
+	}
+
 	hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
 	if (!hcall_root)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hvCall.S linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall.S
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/hvCall.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/hvCall.S	2010-02-24 13:52:17.000000000 -0500
@@ -14,68 +14,94 @@
 	
 #define STK_PARM(i)     (48 + ((i)-3)*8)
 
-#ifdef CONFIG_HCALL_STATS
+#ifdef CONFIG_TRACEPOINTS
+
+	.section	".toc","aw"
+
+	.globl hcall_tracepoint_refcount
+hcall_tracepoint_refcount:
+	.llong	0
+
+	.section	".text"
+
 /*
  * precall must preserve all registers.  use unused STK_PARM()
- * areas to save snapshots and opcode.
+ * areas to save snapshots and opcode. We branch around this
+ * in early init (eg when populating the MMU hashtable) by using an
+ * unconditional cpu feature.
  */
-#define HCALL_INST_PRECALL					\
-	std	r3,STK_PARM(r3)(r1);	/* save opcode */	\
-	mftb	r0;			/* get timebase and */	\
-	std     r0,STK_PARM(r5)(r1);	/* save for later */	\
+#define HCALL_INST_PRECALL(FIRST_REG)				\
 BEGIN_FTR_SECTION;						\
-	mfspr	r0,SPRN_PURR;		/* get PURR and */	\
-	std	r0,STK_PARM(r6)(r1);	/* save for later */	\
-END_FTR_SECTION_IFSET(CPU_FTR_PURR);
-	
+	b	1f;						\
+END_FTR_SECTION(0, 1);						\
+	ld      r12,hcall_tracepoint_refcount@toc(r2);		\
+	cmpdi	r12,0;						\
+	beq+	1f;						\
+	mflr	r0;						\
+	std	r3,STK_PARM(r3)(r1);				\
+	std	r4,STK_PARM(r4)(r1);				\
+	std	r5,STK_PARM(r5)(r1);				\
+	std	r6,STK_PARM(r6)(r1);				\
+	std	r7,STK_PARM(r7)(r1);				\
+	std	r8,STK_PARM(r8)(r1);				\
+	std	r9,STK_PARM(r9)(r1);				\
+	std	r10,STK_PARM(r10)(r1);				\
+	std	r0,16(r1);					\
+	addi	r4,r1,STK_PARM(FIRST_REG);			\
+	stdu	r1,-STACK_FRAME_OVERHEAD(r1);			\
+	bl	.__trace_hcall_entry;				\
+	addi	r1,r1,STACK_FRAME_OVERHEAD;			\
+	ld	r0,16(r1);					\
+	ld	r3,STK_PARM(r3)(r1);				\
+	ld	r4,STK_PARM(r4)(r1);				\
+	ld	r5,STK_PARM(r5)(r1);				\
+	ld	r6,STK_PARM(r6)(r1);				\
+	ld	r7,STK_PARM(r7)(r1);				\
+	ld	r8,STK_PARM(r8)(r1);				\
+	ld	r9,STK_PARM(r9)(r1);				\
+	ld	r10,STK_PARM(r10)(r1);				\
+	mtlr	r0;						\
+1:
+
 /*
  * postcall is performed immediately before function return which
  * allows liberal use of volatile registers.  We branch around this
  * in early init (eg when populating the MMU hashtable) by using an
  * unconditional cpu feature.
  */
-#define HCALL_INST_POSTCALL					\
+#define __HCALL_INST_POSTCALL					\
 BEGIN_FTR_SECTION;						\
 	b	1f;						\
 END_FTR_SECTION(0, 1);						\
-	ld	r4,STK_PARM(r3)(r1);	/* validate opcode */	\
-	cmpldi	cr7,r4,MAX_HCALL_OPCODE;			\
-	bgt-	cr7,1f;						\
-								\
-	/* get time and PURR snapshots after hcall */		\
-	mftb	r7;			/* timebase after */	\
-BEGIN_FTR_SECTION;						\
-	mfspr	r8,SPRN_PURR;		/* PURR after */	\
-	ld	r6,STK_PARM(r6)(r1);	/* PURR before */	\
-	subf	r6,r6,r8;		/* delta */		\
-END_FTR_SECTION_IFSET(CPU_FTR_PURR);				\
-	ld	r5,STK_PARM(r5)(r1);	/* timebase before */	\
-	subf	r5,r5,r7;		/* time delta */	\
-								\
-	/* calculate address of stat structure r4 = opcode */	\
-	srdi	r4,r4,2;		/* index into array */	\
-	mulli	r4,r4,HCALL_STAT_SIZE;				\
-	LOAD_REG_ADDR(r7, per_cpu__hcall_stats);		\
-	add	r4,r4,r7;					\
-	ld	r7,PACA_DATA_OFFSET(r13); /* per cpu offset */	\
-	add	r4,r4,r7;					\
-								\
-	/* update stats	*/					\
-	ld	r7,HCALL_STAT_CALLS(r4); /* count */		\
-	addi	r7,r7,1;					\
-	std	r7,HCALL_STAT_CALLS(r4);			\
-	ld      r7,HCALL_STAT_TB(r4);	/* timebase */		\
-	add	r7,r7,r5;					\
-	std	r7,HCALL_STAT_TB(r4);				\
-BEGIN_FTR_SECTION;						\
-	ld	r7,HCALL_STAT_PURR(r4);	/* PURR */		\
-	add	r7,r7,r6;					\
-	std	r7,HCALL_STAT_PURR(r4);				\
-END_FTR_SECTION_IFSET(CPU_FTR_PURR);				\
+	ld      r12,hcall_tracepoint_refcount@toc(r2);		\
+	cmpdi	r12,0;						\
+	beq+	1f;						\
+	mflr	r0;						\
+	ld	r6,STK_PARM(r3)(r1);				\
+	std	r3,STK_PARM(r3)(r1);				\
+	mr	r4,r3;						\
+	mr	r3,r6;						\
+	std	r0,16(r1);					\
+	stdu	r1,-STACK_FRAME_OVERHEAD(r1);			\
+	bl	.__trace_hcall_exit;				\
+	addi	r1,r1,STACK_FRAME_OVERHEAD;			\
+	ld	r0,16(r1);					\
+	ld	r3,STK_PARM(r3)(r1);				\
+	mtlr	r0;						\
 1:
+
+#define HCALL_INST_POSTCALL_NORETS				\
+	li	r5,0;						\
+	__HCALL_INST_POSTCALL
+
+#define HCALL_INST_POSTCALL(BUFREG)				\
+	mr	r5,BUFREG;					\
+	__HCALL_INST_POSTCALL
+
 #else
-#define HCALL_INST_PRECALL
-#define HCALL_INST_POSTCALL
+#define HCALL_INST_PRECALL(FIRST_ARG)
+#define HCALL_INST_POSTCALL_NORETS
+#define HCALL_INST_POSTCALL(BUFREG)
 #endif
 
 	.text
@@ -86,11 +112,11 @@ _GLOBAL(plpar_hcall_norets)
 	mfcr	r0
 	stw	r0,8(r1)
 
-	HCALL_INST_PRECALL
+	HCALL_INST_PRECALL(r4)
 
 	HVSC				/* invoke the hypervisor */
 
-	HCALL_INST_POSTCALL
+	HCALL_INST_POSTCALL_NORETS
 
 	lwz	r0,8(r1)
 	mtcrf	0xff,r0
@@ -102,7 +128,7 @@ _GLOBAL(plpar_hcall)
 	mfcr	r0
 	stw	r0,8(r1)
 
-	HCALL_INST_PRECALL
+	HCALL_INST_PRECALL(r5)
 
 	std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
 
@@ -121,7 +147,7 @@ _GLOBAL(plpar_hcall)
 	std	r6, 16(r12)
 	std	r7, 24(r12)
 
-	HCALL_INST_POSTCALL
+	HCALL_INST_POSTCALL(r12)
 
 	lwz	r0,8(r1)
 	mtcrf	0xff,r0
@@ -168,7 +194,7 @@ _GLOBAL(plpar_hcall9)
 	mfcr	r0
 	stw	r0,8(r1)
 
-	HCALL_INST_PRECALL
+	HCALL_INST_PRECALL(r5)
 
 	std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
 
@@ -196,7 +222,7 @@ _GLOBAL(plpar_hcall9)
 	std	r11,56(r12)
 	std	r0, 64(r12)
 
-	HCALL_INST_POSTCALL
+	HCALL_INST_POSTCALL(r12)
 
 	lwz	r0,8(r1)
 	mtcrf	0xff,r0
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/Kconfig linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/Kconfig
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -2,8 +2,11 @@ config PPC_PSERIES
 	depends on PPC64 && PPC_BOOK3S
 	bool "IBM pSeries & new (POWER5-based) iSeries"
 	select MPIC
+	select PCI_MSI
+	select XICS
 	select PPC_I8259
 	select PPC_RTAS
+	select PPC_RTAS_DAEMON
 	select RTAS_ERROR_LOGGING
 	select PPC_UDBG_16550
 	select PPC_NATIVE
@@ -59,7 +62,7 @@ config PPC_SMLPAR
 
 config CMM
 	tristate "Collaborative memory management"
-	depends on PPC_SMLPAR && !CRASH_DUMP
+	depends on PPC_SMLPAR
 	default y
 	help
 	  Select this option, if you want to enable the kernel interface
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/lpar.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/lpar.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/lpar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/lpar.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,7 @@
 #include <asm/cputable.h>
 #include <asm/udbg.h>
 #include <asm/smp.h>
+#include <asm/trace.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
@@ -661,3 +662,35 @@ void arch_free_page(struct page *page, i
 EXPORT_SYMBOL(arch_free_page);
 
 #endif
+
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * We optimise our hcall path by placing hcall_tracepoint_refcount
+ * directly in the TOC so we can check if the hcall tracepoints are
+ * enabled via a single load.
+ */
+
+/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
+extern long hcall_tracepoint_refcount;
+
+void hcall_tracepoint_regfunc(void)
+{
+	hcall_tracepoint_refcount++;
+}
+
+void hcall_tracepoint_unregfunc(void)
+{
+	hcall_tracepoint_refcount--;
+}
+
+void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
+{
+	trace_hcall_entry(opcode, args);
+}
+
+void __trace_hcall_exit(long opcode, unsigned long retval,
+			unsigned long *retbuf)
+{
+	trace_hcall_exit(opcode, retval, retbuf);
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -7,8 +7,8 @@ EXTRA_CFLAGS		+= -DDEBUG
 endif
 
 obj-y			:= lpar.o hvCall.o nvram.o reconfig.o \
-			   setup.o iommu.o ras.o rtasd.o \
-			   firmware.o power.o
+			   setup.o iommu.o ras.o \
+			   firmware.o power.o dlpar.o
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_XICS)	+= xics.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/offline_states.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/offline_states.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/offline_states.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/offline_states.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,18 @@
+#ifndef _OFFLINE_STATES_H_
+#define _OFFLINE_STATES_H_
+
+/* Cpu offline states go here */
+enum cpu_state_vals {
+	CPU_STATE_OFFLINE,
+	CPU_STATE_INACTIVE,
+	CPU_STATE_ONLINE,
+	CPU_MAX_OFFLINE_STATES
+};
+
+extern enum cpu_state_vals get_cpu_current_state(int cpu);
+extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
+extern enum cpu_state_vals get_preferred_offline_state(int cpu);
+extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
+extern void set_default_offline_state(int cpu);
+extern int start_secondary(void);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,11 +9,33 @@ static inline long poll_pending(void)
 	return plpar_hcall_norets(H_POLL_PENDING);
 }
 
+static inline u8 get_cede_latency_hint(void)
+{
+	return get_lppaca()->gpr5_dword.fields.cede_latency_hint;
+}
+
+static inline void set_cede_latency_hint(u8 latency_hint)
+{
+	get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint;
+}
+
 static inline long cede_processor(void)
 {
 	return plpar_hcall_norets(H_CEDE);
 }
 
+static inline long extended_cede_processor(unsigned long latency_hint)
+{
+	long rc;
+	u8 old_latency_hint = get_cede_latency_hint();
+
+	set_cede_latency_hint(latency_hint);
+	rc = cede_processor();
+	set_cede_latency_hint(old_latency_hint);
+
+	return rc;
+}
+
 static inline long vpa_call(unsigned long flags, unsigned long cpu,
 		unsigned long vpa)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/reconfig.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/reconfig.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ static struct device_node *derive_parent
 	return parent;
 }
 
-static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
+BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
 
 int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
@@ -184,7 +184,7 @@ static int pSeries_reconfig_remove_node(
 }
 
 /*
- * /proc/ppc64/ofdt - yucky binary interface for adding and removing
+ * /proc/powerpc/ofdt - yucky binary interface for adding and removing
  * OF device nodes.  Should be deprecated as soon as we get an
  * in-kernel wrapper for the RTAS ibm,configure-connector call.
  */
@@ -543,7 +543,7 @@ static const struct file_operations ofdt
 	.write = ofdt_write
 };
 
-/* create /proc/ppc64/ofdt write-only by root */
+/* create /proc/powerpc/ofdt write-only by root */
 static int proc_ppc64_create_ofdt(void)
 {
 	struct proc_dir_entry *ent;
@@ -551,7 +551,7 @@ static int proc_ppc64_create_ofdt(void)
 	if (!machine_is(pseries))
 		return 0;
 
-	ent = proc_create("ppc64/ofdt", S_IWUSR, NULL, &ofdt_fops);
+	ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
 	if (ent)
 		ent->size = 0;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/rtasd.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/rtasd.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/rtasd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/rtasd.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * 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.
- *
- * Communication to userspace based on kernel/printk.c
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/spinlock.h>
-#include <linux/cpu.h>
-#include <linux/workqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/rtas.h>
-#include <asm/prom.h>
-#include <asm/nvram.h>
-#include <asm/atomic.h>
-#include <asm/machdep.h>
-
-
-static DEFINE_SPINLOCK(rtasd_log_lock);
-
-static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
-
-static char *rtas_log_buf;
-static unsigned long rtas_log_start;
-static unsigned long rtas_log_size;
-
-static int surveillance_timeout = -1;
-static unsigned int rtas_error_log_max;
-static unsigned int rtas_error_log_buffer_max;
-
-/* RTAS service tokens */
-static unsigned int event_scan;
-static unsigned int rtas_event_scan_rate;
-
-static int full_rtas_msgs = 0;
-
-/* Stop logging to nvram after first fatal error */
-static int logging_enabled; /* Until we initialize everything,
-                             * make sure we don't try logging
-                             * anything */
-static int error_log_cnt;
-
-/*
- * Since we use 32 bit RTAS, the physical address of this must be below
- * 4G or else bad things happen. Allocate this in the kernel data and
- * make it big enough.
- */
-static unsigned char logdata[RTAS_ERROR_LOG_MAX];
-
-static char *rtas_type[] = {
-	"Unknown", "Retry", "TCE Error", "Internal Device Failure",
-	"Timeout", "Data Parity", "Address Parity", "Cache Parity",
-	"Address Invalid", "ECC Uncorrected", "ECC Corrupted",
-};
-
-static char *rtas_event_type(int type)
-{
-	if ((type > 0) && (type < 11))
-		return rtas_type[type];
-
-	switch (type) {
-		case RTAS_TYPE_EPOW:
-			return "EPOW";
-		case RTAS_TYPE_PLATFORM:
-			return "Platform Error";
-		case RTAS_TYPE_IO:
-			return "I/O Event";
-		case RTAS_TYPE_INFO:
-			return "Platform Information Event";
-		case RTAS_TYPE_DEALLOC:
-			return "Resource Deallocation Event";
-		case RTAS_TYPE_DUMP:
-			return "Dump Notification Event";
-	}
-
-	return rtas_type[0];
-}
-
-/* To see this info, grep RTAS /var/log/messages and each entry
- * will be collected together with obvious begin/end.
- * There will be a unique identifier on the begin and end lines.
- * This will persist across reboots.
- *
- * format of error logs returned from RTAS:
- * bytes	(size)	: contents
- * --------------------------------------------------------
- * 0-7		(8)	: rtas_error_log
- * 8-47		(40)	: extended info
- * 48-51	(4)	: vendor id
- * 52-1023 (vendor specific) : location code and debug data
- */
-static void printk_log_rtas(char *buf, int len)
-{
-
-	int i,j,n = 0;
-	int perline = 16;
-	char buffer[64];
-	char * str = "RTAS event";
-
-	if (full_rtas_msgs) {
-		printk(RTAS_DEBUG "%d -------- %s begin --------\n",
-		       error_log_cnt, str);
-
-		/*
-		 * Print perline bytes on each line, each line will start
-		 * with RTAS and a changing number, so syslogd will
-		 * print lines that are otherwise the same.  Separate every
-		 * 4 bytes with a space.
-		 */
-		for (i = 0; i < len; i++) {
-			j = i % perline;
-			if (j == 0) {
-				memset(buffer, 0, sizeof(buffer));
-				n = sprintf(buffer, "RTAS %d:", i/perline);
-			}
-
-			if ((i % 4) == 0)
-				n += sprintf(buffer+n, " ");
-
-			n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
-
-			if (j == (perline-1))
-				printk(KERN_DEBUG "%s\n", buffer);
-		}
-		if ((i % perline) != 0)
-			printk(KERN_DEBUG "%s\n", buffer);
-
-		printk(RTAS_DEBUG "%d -------- %s end ----------\n",
-		       error_log_cnt, str);
-	} else {
-		struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
-
-		printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
-		       error_log_cnt, rtas_event_type(errlog->type),
-		       errlog->severity);
-	}
-}
-
-static int log_rtas_len(char * buf)
-{
-	int len;
-	struct rtas_error_log *err;
-
-	/* rtas fixed header */
-	len = 8;
-	err = (struct rtas_error_log *)buf;
-	if (err->extended_log_length) {
-
-		/* extended header */
-		len += err->extended_log_length;
-	}
-
-	if (rtas_error_log_max == 0)
-		rtas_error_log_max = rtas_get_error_log_max();
-
-	if (len > rtas_error_log_max)
-		len = rtas_error_log_max;
-
-	return len;
-}
-
-/*
- * First write to nvram, if fatal error, that is the only
- * place we log the info.  The error will be picked up
- * on the next reboot by rtasd.  If not fatal, run the
- * method for the type of error.  Currently, only RTAS
- * errors have methods implemented, but in the future
- * there might be a need to store data in nvram before a
- * call to panic().
- *
- * XXX We write to nvram periodically, to indicate error has
- * been written and sync'd, but there is a possibility
- * that if we don't shutdown correctly, a duplicate error
- * record will be created on next reboot.
- */
-void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
-{
-	unsigned long offset;
-	unsigned long s;
-	int len = 0;
-
-	pr_debug("rtasd: logging event\n");
-	if (buf == NULL)
-		return;
-
-	spin_lock_irqsave(&rtasd_log_lock, s);
-
-	/* get length and increase count */
-	switch (err_type & ERR_TYPE_MASK) {
-	case ERR_TYPE_RTAS_LOG:
-		len = log_rtas_len(buf);
-		if (!(err_type & ERR_FLAG_BOOT))
-			error_log_cnt++;
-		break;
-	case ERR_TYPE_KERNEL_PANIC:
-	default:
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-	/* Write error to NVRAM */
-	if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
-		nvram_write_error_log(buf, len, err_type, error_log_cnt);
-
-	/*
-	 * rtas errors can occur during boot, and we do want to capture
-	 * those somewhere, even if nvram isn't ready (why not?), and even
-	 * if rtasd isn't ready. Put them into the boot log, at least.
-	 */
-	if ((err_type & ERR_TYPE_MASK) == ERR_TYPE_RTAS_LOG)
-		printk_log_rtas(buf, len);
-
-	/* Check to see if we need to or have stopped logging */
-	if (fatal || !logging_enabled) {
-		logging_enabled = 0;
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-	/* call type specific method for error */
-	switch (err_type & ERR_TYPE_MASK) {
-	case ERR_TYPE_RTAS_LOG:
-		offset = rtas_error_log_buffer_max *
-			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
-
-		/* First copy over sequence number */
-		memcpy(&rtas_log_buf[offset], (void *) &error_log_cnt, sizeof(int));
-
-		/* Second copy over error log data */
-		offset += sizeof(int);
-		memcpy(&rtas_log_buf[offset], buf, len);
-
-		if (rtas_log_size < LOG_NUMBER)
-			rtas_log_size += 1;
-		else
-			rtas_log_start += 1;
-
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		wake_up_interruptible(&rtas_log_wait);
-		break;
-	case ERR_TYPE_KERNEL_PANIC:
-	default:
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-}
-
-
-static int rtas_log_open(struct inode * inode, struct file * file)
-{
-	return 0;
-}
-
-static int rtas_log_release(struct inode * inode, struct file * file)
-{
-	return 0;
-}
-
-/* This will check if all events are logged, if they are then, we
- * know that we can safely clear the events in NVRAM.
- * Next we'll sit and wait for something else to log.
- */
-static ssize_t rtas_log_read(struct file * file, char __user * buf,
-			 size_t count, loff_t *ppos)
-{
-	int error;
-	char *tmp;
-	unsigned long s;
-	unsigned long offset;
-
-	if (!buf || count < rtas_error_log_buffer_max)
-		return -EINVAL;
-
-	count = rtas_error_log_buffer_max;
-
-	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT;
-
-	tmp = kmalloc(count, GFP_KERNEL);
-	if (!tmp)
-		return -ENOMEM;
-
-	spin_lock_irqsave(&rtasd_log_lock, s);
-	/* if it's 0, then we know we got the last one (the one in NVRAM) */
-	while (rtas_log_size == 0) {
-		if (file->f_flags & O_NONBLOCK) {
-			spin_unlock_irqrestore(&rtasd_log_lock, s);
-			error = -EAGAIN;
-			goto out;
-		}
-
-		if (!logging_enabled) {
-			spin_unlock_irqrestore(&rtasd_log_lock, s);
-			error = -ENODATA;
-			goto out;
-		}
-		nvram_clear_error_log();
-
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
-		if (error)
-			goto out;
-		spin_lock_irqsave(&rtasd_log_lock, s);
-	}
-
-	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
-	memcpy(tmp, &rtas_log_buf[offset], count);
-
-	rtas_log_start += 1;
-	rtas_log_size -= 1;
-	spin_unlock_irqrestore(&rtasd_log_lock, s);
-
-	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
-out:
-	kfree(tmp);
-	return error;
-}
-
-static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
-{
-	poll_wait(file, &rtas_log_wait, wait);
-	if (rtas_log_size)
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-static const struct file_operations proc_rtas_log_operations = {
-	.read =		rtas_log_read,
-	.poll =		rtas_log_poll,
-	.open =		rtas_log_open,
-	.release =	rtas_log_release,
-};
-
-static int enable_surveillance(int timeout)
-{
-	int error;
-
-	error = rtas_set_indicator(SURVEILLANCE_TOKEN, 0, timeout);
-
-	if (error == 0)
-		return 0;
-
-	if (error == -EINVAL) {
-		printk(KERN_DEBUG "rtasd: surveillance not supported\n");
-		return 0;
-	}
-
-	printk(KERN_ERR "rtasd: could not update surveillance\n");
-	return -1;
-}
-
-static void do_event_scan(void)
-{
-	int error;
-	do {
-		memset(logdata, 0, rtas_error_log_max);
-		error = rtas_call(event_scan, 4, 1, NULL,
-				  RTAS_EVENT_SCAN_ALL_EVENTS, 0,
-				  __pa(logdata), rtas_error_log_max);
-		if (error == -1) {
-			printk(KERN_ERR "event-scan failed\n");
-			break;
-		}
-
-		if (error == 0)
-			pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
-
-	} while(error == 0);
-}
-
-static void rtas_event_scan(struct work_struct *w);
-DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
-
-/*
- * Delay should be at least one second since some machines have problems if
- * we call event-scan too quickly.
- */
-static unsigned long event_scan_delay = 1*HZ;
-static int first_pass = 1;
-
-static void rtas_event_scan(struct work_struct *w)
-{
-	unsigned int cpu;
-
-	do_event_scan();
-
-	get_online_cpus();
-
-	cpu = next_cpu(smp_processor_id(), cpu_online_map);
-	if (cpu == NR_CPUS) {
-		cpu = first_cpu(cpu_online_map);
-
-		if (first_pass) {
-			first_pass = 0;
-			event_scan_delay = 30*HZ/rtas_event_scan_rate;
-
-			if (surveillance_timeout != -1) {
-				pr_debug("rtasd: enabling surveillance\n");
-				enable_surveillance(surveillance_timeout);
-				pr_debug("rtasd: surveillance enabled\n");
-			}
-		}
-	}
-
-	schedule_delayed_work_on(cpu, &event_scan_work,
-		__round_jiffies_relative(event_scan_delay, cpu));
-
-	put_online_cpus();
-}
-
-static void start_event_scan(void)
-{
-	unsigned int err_type;
-	int rc;
-
-	printk(KERN_DEBUG "RTAS daemon started\n");
-	pr_debug("rtasd: will sleep for %d milliseconds\n",
-		 (30000 / rtas_event_scan_rate));
-
-	/* See if we have any error stored in NVRAM */
-	memset(logdata, 0, rtas_error_log_max);
-	rc = nvram_read_error_log(logdata, rtas_error_log_max,
-	                          &err_type, &error_log_cnt);
-	/* We can use rtas_log_buf now */
-	logging_enabled = 1;
-
-	if (!rc) {
-		if (err_type != ERR_FLAG_ALREADY_LOGGED) {
-			pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
-		}
-	}
-
-	schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
-				 event_scan_delay);
-}
-
-static int __init rtas_init(void)
-{
-	struct proc_dir_entry *entry;
-
-	if (!machine_is(pseries))
-		return 0;
-
-	/* No RTAS */
-	event_scan = rtas_token("event-scan");
-	if (event_scan == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_DEBUG "rtasd: no event-scan on system\n");
-		return -ENODEV;
-	}
-
-	rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
-	if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
-		return -ENODEV;
-	}
-
-	/* Make room for the sequence number */
-	rtas_error_log_max = rtas_get_error_log_max();
-	rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
-
-	rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
-	if (!rtas_log_buf) {
-		printk(KERN_ERR "rtasd: no memory\n");
-		return -ENOMEM;
-	}
-
-	entry = proc_create("ppc64/rtas/error_log", S_IRUSR, NULL,
-			    &proc_rtas_log_operations);
-	if (!entry)
-		printk(KERN_ERR "Failed to create error_log proc entry\n");
-
-	start_event_scan();
-
-	return 0;
-}
-
-static int __init surveillance_setup(char *str)
-{
-	int i;
-
-	if (get_option(&str,&i)) {
-		if (i >= 0 && i <= 255)
-			surveillance_timeout = i;
-	}
-
-	return 1;
-}
-
-static int __init rtasmsgs_setup(char *str)
-{
-	if (strcmp(str, "on") == 0)
-		full_rtas_msgs = 1;
-	else if (strcmp(str, "off") == 0)
-		full_rtas_msgs = 0;
-
-	return 1;
-}
-__initcall(rtas_init);
-__setup("surveillance=", surveillance_setup);
-__setup("rtasmsgs=", rtasmsgs_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/scanlog.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/scanlog.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/scanlog.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/scanlog.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,7 @@
  * of this data using this driver.  A dump exists if the device-tree
  * /chosen/ibm,scan-log-data property exists.
  *
- * This driver exports /proc/ppc64/scan-log-dump which can be read.
+ * This driver exports /proc/powerpc/scan-log-dump which can be read.
  * The driver supports only sequential reads.
  *
  * The driver looks at a write to the driver for the single word "reset".
@@ -186,7 +186,7 @@ static int __init scanlog_init(void)
 	if (!data)
 		goto err;
 
-	ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
+	ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
 			       &scanlog_fops, data);
 	if (!ent)
 		goto err;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/smp.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/smp.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,7 @@
 #include "plpar_wrappers.h"
 #include "pseries.h"
 #include "xics.h"
+#include "offline_states.h"
 
 
 /*
@@ -84,6 +85,9 @@ static inline int __devinit smp_startup_
 	/* Fixup atomic count: it exited inside IRQ handler. */
 	task_thread_info(paca[lcpu].__current)->preempt_count	= 0;
 
+	if (get_cpu_current_state(lcpu) == CPU_STATE_INACTIVE)
+		goto out;
+
 	/* 
 	 * If the RTAS start-cpu token does not exist then presume the
 	 * cpu is already spinning.
@@ -98,6 +102,7 @@ static inline int __devinit smp_startup_
 		return 0;
 	}
 
+out:
 	return 1;
 }
 
@@ -111,12 +116,16 @@ static void __devinit smp_xics_setup_cpu
 		vpa_init(cpu);
 
 	cpu_clear(cpu, of_spin_map);
+	set_cpu_current_state(cpu, CPU_STATE_ONLINE);
+	set_default_offline_state(cpu);
 
 }
 #endif /* CONFIG_XICS */
 
 static void __devinit smp_pSeries_kick_cpu(int nr)
 {
+	long rc;
+	unsigned long hcpuid;
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
 	if (!smp_startup_cpu(nr))
@@ -128,6 +137,16 @@ static void __devinit smp_pSeries_kick_c
 	 * the processor will continue on to secondary_start
 	 */
 	paca[nr].cpu_start = 1;
+
+	set_preferred_offline_state(nr, CPU_STATE_ONLINE);
+
+	if (get_cpu_current_state(nr) == CPU_STATE_INACTIVE) {
+		hcpuid = get_hard_smp_processor_id(nr);
+		rc = plpar_hcall_norets(H_PROD, hcpuid);
+		if (rc != H_SUCCESS)
+			printk(KERN_ERR "Error: Prod to wake up processor %d\
+						Ret= %ld\n", nr, rc);
+	}
 }
 
 static int smp_pSeries_cpu_bootable(unsigned int nr)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/xics.c linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/xics.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/platforms/pseries/xics.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/platforms/pseries/xics.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #include <linux/cpu.h>
 #include <linux/msi.h>
 #include <linux/of.h>
+#include <linux/percpu.h>
 
 #include <asm/firmware.h>
 #include <asm/io.h>
@@ -46,6 +47,12 @@ static struct irq_host *xics_host;
  */
 #define IPI_PRIORITY		4
 
+/* The least favored priority */
+#define LOWEST_PRIORITY		0xFF
+
+/* The number of priorities defined above */
+#define MAX_NUM_PRIORITIES	3
+
 static unsigned int default_server = 0xFF;
 static unsigned int default_distrib_server = 0;
 static unsigned int interrupt_server_size = 8;
@@ -56,6 +63,12 @@ static int ibm_set_xive;
 static int ibm_int_on;
 static int ibm_int_off;
 
+struct xics_cppr {
+	unsigned char stack[MAX_NUM_PRIORITIES];
+	int index;
+};
+
+static DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
 
 /* Direct hardware low level accessors */
 
@@ -150,14 +163,13 @@ static inline void lpar_qirr_info(int n_
 /* Interface to generic irq subsystem */
 
 #ifdef CONFIG_SMP
-static int get_irq_server(unsigned int virq, unsigned int strict_check)
+static int get_irq_server(unsigned int virq, cpumask_t cpumask,
+			  unsigned int strict_check)
 {
 	int server;
 	/* For the moment only implement delivery to all cpus or one cpu */
-	cpumask_t cpumask;
 	cpumask_t tmp = CPU_MASK_NONE;
 
-	cpumask_copy(&cpumask, irq_desc[virq].affinity);
 	if (!distribute_irqs)
 		return default_server;
 
@@ -179,10 +191,7 @@ static int get_irq_server(unsigned int v
 	return default_server;
 }
 #else
-static int get_irq_server(unsigned int virq, unsigned int strict_check)
-{
-	return default_server;
-}
+#define get_irq_server(virq, cpumask, strict_check) (default_server)
 #endif
 
 static void xics_unmask_irq(unsigned int virq)
@@ -198,7 +207,7 @@ static void xics_unmask_irq(unsigned int
 	if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
 		return;
 
-	server = get_irq_server(virq, 0);
+	server = get_irq_server(virq, *(irq_to_desc(virq)->affinity), 0);
 
 	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
 				DEFAULT_PRIORITY);
@@ -284,6 +293,19 @@ static inline unsigned int xics_xirr_vec
 	return xirr & 0x00ffffff;
 }
 
+static void push_cppr(unsigned int vec)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
+		return;
+
+	if (vec == XICS_IPI)
+		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
+	else
+		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
+}
+
 static unsigned int xics_get_irq_direct(void)
 {
 	unsigned int xirr = direct_xirr_info_get();
@@ -294,8 +316,10 @@ static unsigned int xics_get_irq_direct(
 		return NO_IRQ;
 
 	irq = irq_radix_revmap_lookup(xics_host, vec);
-	if (likely(irq != NO_IRQ))
+	if (likely(irq != NO_IRQ)) {
+		push_cppr(vec);
 		return irq;
+	}
 
 	/* We don't have a linux mapping, so have rtas mask it. */
 	xics_mask_unknown_vec(vec);
@@ -315,8 +339,10 @@ static unsigned int xics_get_irq_lpar(vo
 		return NO_IRQ;
 
 	irq = irq_radix_revmap_lookup(xics_host, vec);
-	if (likely(irq != NO_IRQ))
+	if (likely(irq != NO_IRQ)) {
+		push_cppr(vec);
 		return irq;
+	}
 
 	/* We don't have a linux mapping, so have RTAS mask it. */
 	xics_mask_unknown_vec(vec);
@@ -326,12 +352,22 @@ static unsigned int xics_get_irq_lpar(vo
 	return NO_IRQ;
 }
 
+static unsigned char pop_cppr(void)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	if (WARN_ON(os_cppr->index < 1))
+		return LOWEST_PRIORITY;
+
+	return os_cppr->stack[--os_cppr->index];
+}
+
 static void xics_eoi_direct(unsigned int virq)
 {
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
-	direct_xirr_info_set((0xff << 24) | irq);
+	direct_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
 static void xics_eoi_lpar(unsigned int virq)
@@ -339,7 +375,7 @@ static void xics_eoi_lpar(unsigned int v
 	unsigned int irq = (unsigned int)irq_map[virq].hwirq;
 
 	iosync();
-	lpar_xirr_info_set((0xff << 24) | irq);
+	lpar_xirr_info_set((pop_cppr() << 24) | irq);
 }
 
 static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
@@ -365,7 +401,7 @@ static int xics_set_affinity(unsigned in
 	 * For the moment only implement delivery to all cpus or one cpu.
 	 * Get current irq_server for the given irq
 	 */
-	irq_server = get_irq_server(virq, 1);
+	irq_server = get_irq_server(virq, *cpumask, 1);
 	if (irq_server == -1) {
 		char cpulist[128];
 		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
@@ -388,7 +424,7 @@ static int xics_set_affinity(unsigned in
 }
 
 static struct irq_chip xics_pic_direct = {
-	.typename = " XICS     ",
+	.name = " XICS     ",
 	.startup = xics_startup,
 	.mask = xics_mask_irq,
 	.unmask = xics_unmask_irq,
@@ -397,7 +433,7 @@ static struct irq_chip xics_pic_direct =
 };
 
 static struct irq_chip xics_pic_lpar = {
-	.typename = " XICS     ",
+	.name = " XICS     ",
 	.startup = xics_startup,
 	.mask = xics_mask_irq,
 	.unmask = xics_unmask_irq,
@@ -428,13 +464,13 @@ static int xics_host_map(struct irq_host
 	/* Insert the interrupt mapping into the radix tree for fast lookup */
 	irq_radix_revmap_insert(xics_host, virq, hw);
 
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
 	return 0;
 }
 
 static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
-			   u32 *intspec, unsigned int intsize,
+			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
@@ -746,6 +782,16 @@ void __init xics_init_IRQ(void)
 
 static void xics_set_cpu_priority(unsigned char cppr)
 {
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	/*
+	 * we only really want to set the priority when there's
+	 * just one cppr value on the stack
+	 */
+	WARN_ON(os_cppr->index != 0);
+
+	os_cppr->stack[0] = cppr;
+
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		lpar_cppr_info(cppr);
 	else
@@ -772,15 +818,21 @@ static void xics_set_cpu_giq(unsigned in
 
 void xics_setup_cpu(void)
 {
-	xics_set_cpu_priority(0xff);
+	xics_set_cpu_priority(LOWEST_PRIORITY);
 
 	xics_set_cpu_giq(default_distrib_server, 1);
 }
 
 void xics_teardown_cpu(void)
 {
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
 	int cpu = smp_processor_id();
 
+	/*
+	 * we have to reset the cppr index to 0 because we're
+	 * not going to return from the IPI
+	 */
+	os_cppr->index = 0;
 	xics_set_cpu_priority(0);
 
 	/* Clear any pending IPI request */
@@ -852,7 +904,7 @@ void xics_migrate_irqs_away(void)
 		/* We need to get IPIs still. */
 		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
 			continue;
-		desc = get_irq_desc(virq);
+		desc = irq_to_desc(virq);
 
 		/* We only need to migrate enabled IRQS */
 		if (desc == NULL || desc->chip == NULL
@@ -860,7 +912,7 @@ void xics_migrate_irqs_away(void)
 		    || desc->chip->set_affinity == NULL)
 			continue;
 
-		spin_lock_irqsave(&desc->lock, flags);
+		raw_spin_lock_irqsave(&desc->lock, flags);
 
 		status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
 		if (status) {
@@ -881,10 +933,10 @@ void xics_migrate_irqs_away(void)
 		       virq, cpu);
 
 		/* Reset affinity to all cpus */
-		cpumask_setall(irq_desc[virq].affinity);
+		cpumask_setall(irq_to_desc(virq)->affinity);
 		desc->chip->set_affinity(virq, cpu_all_mask);
 unlock:
-		spin_unlock_irqrestore(&desc->lock, flags);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
 	}
 }
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm1.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm1.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm1.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,7 @@ static void cpm_end_irq(unsigned int irq
 }
 
 static struct irq_chip cpm_pic = {
-	.typename = " CPM PIC ",
+	.name = " CPM PIC ",
 	.mask = cpm_mask_irq,
 	.unmask = cpm_unmask_irq,
 	.eoi = cpm_end_irq,
@@ -102,7 +102,7 @@ static int cpm_pic_host_map(struct irq_h
 {
 	pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
 
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm2_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm2_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm2_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,11 +115,13 @@ static void cpm2_ack(unsigned int virq)
 
 static void cpm2_end_irq(unsigned int virq)
 {
+	struct irq_desc *desc;
 	int	bit, word;
 	unsigned int irq_nr = virq_to_hw(virq);
 
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
-			&& irq_desc[irq_nr].action) {
+	desc = irq_to_desc(irq_nr);
+	if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
+			&& desc->action) {
 
 		bit = irq_to_siubit[irq_nr];
 		word = irq_to_siureg[irq_nr];
@@ -138,16 +140,26 @@ static void cpm2_end_irq(unsigned int vi
 static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
 {
 	unsigned int src = virq_to_hw(virq);
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
-	if (flow_type == IRQ_TYPE_NONE)
-		flow_type = IRQ_TYPE_LEVEL_LOW;
+	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
+	 * IRQ_TYPE_EDGE_BOTH (default).  All others are IRQ_TYPE_EDGE_FALLING
+	 * or IRQ_TYPE_LEVEL_LOW (default)
+	 */
+	if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) {
+		if (flow_type == IRQ_TYPE_NONE)
+			flow_type = IRQ_TYPE_EDGE_BOTH;
 
-	if (flow_type & IRQ_TYPE_EDGE_RISING) {
-		printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
-			flow_type);
-		return -EINVAL;
+		if (flow_type != IRQ_TYPE_EDGE_BOTH &&
+		    flow_type != IRQ_TYPE_EDGE_FALLING)
+			goto err_sense;
+	} else {
+		if (flow_type == IRQ_TYPE_NONE)
+			flow_type = IRQ_TYPE_LEVEL_LOW;
+
+		if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+			goto err_sense;
 	}
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
@@ -179,10 +191,14 @@ static int cpm2_set_irq_type(unsigned in
 	if (vold != vnew)
 		out_be32(&cpm2_intctl->ic_siexr, vnew);
 	return 0;
+
+err_sense:
+	pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
+	return -EINVAL;
 }
 
 static struct irq_chip cpm2_pic = {
-	.typename = " CPM2 SIU ",
+	.name = " CPM2 SIU ",
 	.mask = cpm2_mask_irq,
 	.unmask = cpm2_unmask_irq,
 	.ack = cpm2_ack,
@@ -210,13 +226,13 @@ static int cpm2_pic_host_map(struct irq_
 {
 	pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
 
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
 	return 0;
 }
 
 static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 *intspec, unsigned int intsize,
+			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 	*out_hwirq = intspec[0];
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm_common.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm_common.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/cpm_common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/cpm_common.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,7 +72,7 @@ static phys_addr_t muram_pbase;
 /* Max address size we deal with */
 #define OF_MAX_ADDR_CELLS	4
 
-int __init cpm_muram_init(void)
+int cpm_muram_init(void)
 {
 	struct device_node *np;
 	struct resource r;
@@ -81,6 +81,9 @@ int __init cpm_muram_init(void)
 	int i = 0;
 	int ret = 0;
 
+	if (muram_pbase)
+		return 0;
+
 	spin_lock_init(&cpm_muram_lock);
 	/* initialize the info header */
 	rh_init(&cpm_muram_info, 1,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/dart_iommu.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/dart_iommu.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/dart_iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/dart_iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -160,7 +160,7 @@ static int dart_build(struct iommu_table
 
 	dp = ((unsigned int*)tbl->it_base) + index;
 
-	/* On U3, all memory is contigous, so we can move this
+	/* On U3, all memory is contiguous, so we can move this
 	 * out of the loop.
 	 */
 	l = npages;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_msi.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_msi.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ static struct irq_chip fsl_msi_chip = {
 	.mask		= mask_msi_irq,
 	.unmask		= unmask_msi_irq,
 	.ack		= fsl_msi_end_irq,
-	.typename	= " FSL-MSI  ",
+	.name	= " FSL-MSI  ",
 };
 
 static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
@@ -55,7 +55,7 @@ static int fsl_msi_host_map(struct irq_h
 {
 	struct irq_chip *chip = &fsl_msi_chip;
 
-	get_irq_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
+	irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
 
 	set_irq_chip_and_handler(virq, chip, handle_edge_irq);
 
@@ -173,7 +173,7 @@ static void fsl_msi_cascade(unsigned int
 	u32 intr_index;
 	u32 have_shift = 0;
 
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	if ((msi_data->feature &  FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
 		if (desc->chip->mask_ack)
 			desc->chip->mask_ack(irq);
@@ -225,7 +225,7 @@ static void fsl_msi_cascade(unsigned int
 		break;
 	}
 unlock:
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 }
 
 static int __devinit fsl_of_msi_probe(struct of_device *dev,
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_pci.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pci.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@ static int __init fsl_pcie_check_link(st
 	return 0;
 }
 
-#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
 	unsigned int index, const struct resource *res,
 	resource_size_t offset)
@@ -392,9 +392,23 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEV
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1011, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
-#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4040, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P4080, quirk_fsl_pcie_header);
+#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
 
 #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header);
@@ -450,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_
 {
 	struct pci_controller *hose = pci_bus_to_host(bus);
 	struct mpc83xx_pcie_priv *pcie = hose->dn->data;
-	u8 bus_no = bus->number - hose->first_busno;
-	u32 dev_base = bus_no << 24 | devfn << 16;
+	u32 dev_base = bus->number << 24 | devfn << 16;
 	int ret;
 
 	ret = mpc83xx_pcie_exclude_device(bus, devfn);
@@ -501,12 +514,17 @@ static int mpc83xx_pcie_read_config(stru
 static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
 				     int offset, int len, u32 val)
 {
+	struct pci_controller *hose = pci_bus_to_host(bus);
 	void __iomem *cfg_addr;
 
 	cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
 	if (!cfg_addr)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
+	/* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
+	if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
+		val &= 0xffffff00;
+
 	switch (len) {
 	case 1:
 		out_8(cfg_addr, val);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_pmc.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pmc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_pmc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_pmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,88 @@
+/*
+ * Suspend/resume support
+ *
+ * Copyright 2009  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/suspend.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+
+struct pmc_regs {
+	__be32 devdisr;
+	__be32 devdisr2;
+	__be32 :32;
+	__be32 :32;
+	__be32 pmcsr;
+#define PMCSR_SLP	(1 << 17)
+};
+
+static struct device *pmc_dev;
+static struct pmc_regs __iomem *pmc_regs;
+
+static int pmc_suspend_enter(suspend_state_t state)
+{
+	int ret;
+
+	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
+	/* At this point, the CPU is asleep. */
+
+	/* Upon resume, wait for SLP bit to be clear. */
+	ret = spin_event_timeout((in_be32(&pmc_regs->pmcsr) & PMCSR_SLP) == 0,
+				 10000, 10) ? 0 : -ETIMEDOUT;
+	if (ret)
+		dev_err(pmc_dev, "tired waiting for SLP bit to clear\n");
+	return ret;
+}
+
+static int pmc_suspend_valid(suspend_state_t state)
+{
+	if (state != PM_SUSPEND_STANDBY)
+		return 0;
+	return 1;
+}
+
+static struct platform_suspend_ops pmc_suspend_ops = {
+	.valid = pmc_suspend_valid,
+	.enter = pmc_suspend_enter,
+};
+
+static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id)
+{
+	pmc_regs = of_iomap(ofdev->node, 0);
+	if (!pmc_regs)
+		return -ENOMEM;
+
+	pmc_dev = &ofdev->dev;
+	suspend_set_ops(&pmc_suspend_ops);
+	return 0;
+}
+
+static const struct of_device_id pmc_ids[] = {
+	{ .compatible = "fsl,mpc8548-pmc", },
+	{ .compatible = "fsl,mpc8641d-pmc", },
+	{ },
+};
+
+static struct of_platform_driver pmc_driver = {
+	.driver.name = "fsl-pmc",
+	.match_table = pmc_ids,
+	.probe = pmc_probe,
+};
+
+static int __init pmc_init(void)
+{
+	return of_register_platform_driver(&pmc_driver);
+}
+device_initcall(pmc_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_soc.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_soc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/fsl_soc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/fsl_soc.c	2010-02-24 13:52:17.000000000 -0500
@@ -372,7 +372,7 @@ err:
 
 arch_initcall(fsl_usb_of_init);
 
-#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static __be32 __iomem *rstcr;
 
 static int __init setup_rstcr(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/i8259.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/i8259.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/i8259.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/i8259.c	2010-02-24 13:52:17.000000000 -0500
@@ -135,7 +135,7 @@ static void i8259_unmask_irq(unsigned in
 }
 
 static struct irq_chip i8259_pic = {
-	.typename	= " i8259    ",
+	.name		= " i8259    ",
 	.mask		= i8259_mask_irq,
 	.disable	= i8259_mask_irq,
 	.unmask		= i8259_unmask_irq,
@@ -175,12 +175,12 @@ static int i8259_host_map(struct irq_hos
 
 	/* We block the internal cascade */
 	if (hw == 2)
-		get_irq_desc(virq)->status |= IRQ_NOREQUEST;
+		irq_to_desc(virq)->status |= IRQ_NOREQUEST;
 
 	/* We use the level handler only for now, we might want to
 	 * be more cautious here but that works for now
 	 */
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 	set_irq_chip_and_handler(virq, &i8259_pic, handle_level_irq);
 	return 0;
 }
@@ -198,7 +198,7 @@ static void i8259_host_unmap(struct irq_
 }
 
 static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 *intspec, unsigned int intsize,
+			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 	static unsigned char map_isa_senses[4] = {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/ipic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ipic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/ipic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ipic.c	2010-02-24 13:52:17.000000000 -0500
@@ -605,7 +605,7 @@ static int ipic_set_irq_type(unsigned in
 {
 	struct ipic *ipic = ipic_from_irq(virq);
 	unsigned int src = ipic_irq_to_hw(virq);
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vold, vnew, edibit;
 
 	if (flow_type == IRQ_TYPE_NONE)
@@ -660,7 +660,7 @@ static int ipic_set_irq_type(unsigned in
 
 /* level interrupts and edge interrupts have different ack operations */
 static struct irq_chip ipic_level_irq_chip = {
-	.typename	= " IPIC  ",
+	.name		= " IPIC  ",
 	.unmask		= ipic_unmask_irq,
 	.mask		= ipic_mask_irq,
 	.mask_ack	= ipic_mask_irq,
@@ -668,7 +668,7 @@ static struct irq_chip ipic_level_irq_ch
 };
 
 static struct irq_chip ipic_edge_irq_chip = {
-	.typename	= " IPIC  ",
+	.name		= " IPIC  ",
 	.unmask		= ipic_unmask_irq,
 	.mask		= ipic_mask_irq,
 	.mask_ack	= ipic_mask_irq_and_ack,
@@ -697,7 +697,7 @@ static int ipic_host_map(struct irq_host
 }
 
 static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
-			   u32 *intspec, unsigned int intsize,
+			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/Makefile linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/Makefile
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@ obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o $(fsl-msi-obj-y)
+obj-$(CONFIG_FSL_PMC)		+= fsl_pmc.o
 obj-$(CONFIG_FSL_LBC)		+= fsl_lbc.o
 obj-$(CONFIG_FSL_GTM)		+= fsl_gtm.o
 obj-$(CONFIG_MPC8xxx_GPIO)	+= mpc8xxx_gpio.o
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xx_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,7 +72,7 @@ static void mpc8xx_end_irq(unsigned int
 
 static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@@ -94,7 +94,7 @@ static int mpc8xx_set_irq_type(unsigned
 }
 
 static struct irq_chip mpc8xx_pic = {
-	.typename = " MPC8XX SIU ",
+	.name = " MPC8XX SIU ",
 	.unmask = mpc8xx_unmask_irq,
 	.mask = mpc8xx_mask_irq,
 	.ack = mpc8xx_ack,
@@ -130,7 +130,7 @@ static int mpc8xx_pic_host_map(struct ir
 
 
 static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 *intspec, unsigned int intsize,
+			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 	static unsigned char map_pic_senses[4] = {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpc8xxx_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struc
 	mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
 }
 
+/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
+ * defined as output cannot be determined by reading GPDAT register,
+ * so we use shadow data register instead. The status of input pins
+ * is determined by reading GPDAT register.
+ */
+static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	u32 val;
+	struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+	struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+	val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+
+	return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+}
+
 static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
@@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controlle
 	gc->ngpio = MPC8XXX_GPIO_PINS;
 	gc->direction_input = mpc8xxx_gpio_dir_in;
 	gc->direction_output = mpc8xxx_gpio_dir_out;
-	gc->get = mpc8xxx_gpio_get;
+	if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
+		gc->get = mpc8572_gpio_get;
+	else
+		gc->get = mpc8xxx_gpio_get;
 	gc->set = mpc8xxx_gpio_set;
 
 	ret = of_mm_gpiochip_add(np, mm_gc);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic.c	2010-02-24 13:52:17.000000000 -0500
@@ -567,13 +567,11 @@ static void __init mpic_scan_ht_pics(str
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(const cpumask_t *mask)
 {
-	cpumask_t mask;
 	int cpuid;
 
-	cpumask_copy(&mask, irq_desc[virt_irq].affinity);
-	if (cpus_equal(mask, CPU_MASK_ALL)) {
+	if (cpumask_equal(mask, cpu_all_mask)) {
 		static int irq_rover;
 		static DEFINE_SPINLOCK(irq_rover_lock);
 		unsigned long flags;
@@ -594,20 +592,15 @@ static int irq_choose_cpu(unsigned int v
 
 		spin_unlock_irqrestore(&irq_rover_lock, flags);
 	} else {
-		cpumask_t tmp;
-
-		cpus_and(tmp, cpu_online_map, mask);
-
-		if (cpus_empty(tmp))
+		cpuid = cpumask_first_and(mask, cpu_online_mask);
+		if (cpuid >= nr_cpu_ids)
 			goto do_round_robin;
-
-		cpuid = first_cpu(tmp);
 	}
 
 	return get_hard_smp_processor_id(cpuid);
 }
 #else
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(const cpumask_t *mask)
 {
 	return hard_smp_processor_id();
 }
@@ -621,7 +614,7 @@ static struct mpic *mpic_find(unsigned i
 	if (irq < NUM_ISA_INTERRUPTS)
 		return NULL;
 
-	return irq_desc[irq].chip_data;
+	return irq_to_desc(irq)->chip_data;
 }
 
 /* Determine if the linux irq is an IPI */
@@ -648,14 +641,14 @@ static inline u32 mpic_physmask(u32 cpum
 /* Get the mpic structure from the IPI number */
 static inline struct mpic * mpic_from_ipi(unsigned int ipi)
 {
-	return irq_desc[ipi].chip_data;
+	return irq_to_desc(ipi)->chip_data;
 }
 #endif
 
 /* Get the mpic structure from the irq number */
 static inline struct mpic * mpic_from_irq(unsigned int irq)
 {
-	return irq_desc[irq].chip_data;
+	return irq_to_desc(irq)->chip_data;
 }
 
 /* Send an EOI */
@@ -735,7 +728,7 @@ static void mpic_unmask_ht_irq(unsigned
 
 	mpic_unmask_irq(irq);
 
-	if (irq_desc[irq].status & IRQ_LEVEL)
+	if (irq_to_desc(irq)->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 }
 
@@ -745,7 +738,7 @@ static unsigned int mpic_startup_ht_irq(
 	unsigned int src = mpic_irq_to_hw(irq);
 
 	mpic_unmask_irq(irq);
-	mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status);
+	mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
 
 	return 0;
 }
@@ -755,7 +748,7 @@ static void mpic_shutdown_ht_irq(unsigne
 	struct mpic *mpic = mpic_from_irq(irq);
 	unsigned int src = mpic_irq_to_hw(irq);
 
-	mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status);
+	mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
 	mpic_mask_irq(irq);
 }
 
@@ -772,7 +765,7 @@ static void mpic_end_ht_irq(unsigned int
 	 * latched another edge interrupt coming in anyway
 	 */
 
-	if (irq_desc[irq].status & IRQ_LEVEL)
+	if (irq_to_desc(irq)->status & IRQ_LEVEL)
 		mpic_ht_end_irq(mpic, src);
 	mpic_eoi(mpic);
 }
@@ -816,7 +809,7 @@ int mpic_set_affinity(unsigned int irq,
 	unsigned int src = mpic_irq_to_hw(irq);
 
 	if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
-		int cpuid = irq_choose_cpu(irq);
+		int cpuid = irq_choose_cpu(cpumask);
 
 		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
 	} else {
@@ -856,7 +849,7 @@ int mpic_set_irq_type(unsigned int virq,
 {
 	struct mpic *mpic = mpic_from_irq(virq);
 	unsigned int src = mpic_irq_to_hw(virq);
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned int vecpri, vold, vnew;
 
 	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
@@ -994,7 +987,7 @@ static int mpic_host_map(struct irq_host
 }
 
 static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
-			   u32 *intspec, unsigned int intsize,
+			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
@@ -1062,19 +1055,19 @@ struct mpic * __init mpic_alloc(struct d
 	mpic->name = name;
 
 	mpic->hc_irq = mpic_irq_chip;
-	mpic->hc_irq.typename = name;
+	mpic->hc_irq.name = name;
 	if (flags & MPIC_PRIMARY)
 		mpic->hc_irq.set_affinity = mpic_set_affinity;
 #ifdef CONFIG_MPIC_U3_HT_IRQS
 	mpic->hc_ht_irq = mpic_irq_ht_chip;
-	mpic->hc_ht_irq.typename = name;
+	mpic->hc_ht_irq.name = name;
 	if (flags & MPIC_PRIMARY)
 		mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 #ifdef CONFIG_SMP
 	mpic->hc_ipi = mpic_ipi_chip;
-	mpic->hc_ipi.typename = name;
+	mpic->hc_ipi.name = name;
 #endif /* CONFIG_SMP */
 
 	mpic->flags = flags;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_msi.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_msi.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,12 @@ static int mpic_msi_reserve_u3_hwirqs(st
 
 	pr_debug("mpic: found U3, guessing msi allocator setup\n");
 
-	/* Reserve source numbers we know are reserved in the HW */
+	/* Reserve source numbers we know are reserved in the HW.
+	 *
+	 * This is a bit of a mix of U3 and U4 reserves but that's going
+	 * to work fine, we have plenty enugh numbers left so let's just
+	 * mark anything we don't like reserved.
+	 */
 	for (i = 0;   i < 8;   i++)
 		msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
@@ -49,6 +54,10 @@ static int mpic_msi_reserve_u3_hwirqs(st
 	for (i = 100; i < 105; i++)
 		msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
 
+	for (i = 124; i < mpic->irq_count; i++)
+		msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
+
+
 	np = NULL;
 	while ((np = of_find_all_nodes(np))) {
 		pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_pasemi_msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,7 +60,7 @@ static struct irq_chip mpic_pasemi_msi_c
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
-	.typename	= "PASEMI-MSI ",
+	.name		= "PASEMI-MSI ",
 };
 
 static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_u3msi.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_u3msi.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mpic_u3msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mpic_u3msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,7 @@ static struct irq_chip mpic_u3msi_chip =
 	.eoi		= mpic_end_irq,
 	.set_type	= mpic_set_irq_type,
 	.set_affinity	= mpic_set_affinity,
-	.typename	= "MPIC-U3MSI",
+	.name		= "MPIC-U3MSI",
 };
 
 static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
@@ -64,12 +64,12 @@ static u64 read_ht_magic_addr(struct pci
 	return addr;
 }
 
-static u64 find_ht_magic_addr(struct pci_dev *pdev)
+static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
 {
 	struct pci_bus *bus;
 	unsigned int pos;
 
-	for (bus = pdev->bus; bus; bus = bus->parent) {
+	for (bus = pdev->bus; bus && bus->self; bus = bus->parent) {
 		pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
 		if (pos)
 			return read_ht_magic_addr(bus->self, pos);
@@ -78,13 +78,41 @@ static u64 find_ht_magic_addr(struct pci
 	return 0;
 }
 
+static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
+{
+	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+
+	/* U4 PCIe MSIs need to write to the special register in
+	 * the bridge that generates interrupts. There should be
+	 * theorically a register at 0xf8005000 where you just write
+	 * the MSI number and that triggers the right interrupt, but
+	 * unfortunately, this is busted in HW, the bridge endian swaps
+	 * the value and hits the wrong nibble in the register.
+	 *
+	 * So instead we use another register set which is used normally
+	 * for converting HT interrupts to MPIC interrupts, which decodes
+	 * the interrupt number as part of the low address bits
+	 *
+	 * This will not work if we ever use more than one legacy MSI in
+	 * a block but we never do. For one MSI or multiple MSI-X where
+	 * each interrupt address can be specified separately, it works
+	 * just fine.
+	 */
+	if (of_device_is_compatible(hose->dn, "u4-pcie") ||
+	    of_device_is_compatible(hose->dn, "U4-pcie"))
+		return 0xf8004000 | (hwirq << 4);
+
+	return 0;
+}
+
 static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 {
 	if (type == PCI_CAP_ID_MSIX)
 		pr_debug("u3msi: MSI-X untested, trying anyway.\n");
 
 	/* If we can't find a magic address then MSI ain't gonna work */
-	if (find_ht_magic_addr(pdev) == 0) {
+	if (find_ht_magic_addr(pdev, 0) == 0 &&
+	    find_u4_magic_addr(pdev, 0) == 0) {
 		pr_debug("u3msi: no magic address found for %s\n",
 			 pci_name(pdev));
 		return -ENXIO;
@@ -118,10 +146,6 @@ static int u3msi_setup_msi_irqs(struct p
 	u64 addr;
 	int hwirq;
 
-	addr = find_ht_magic_addr(pdev);
-	msg.address_lo = addr & 0xFFFFFFFF;
-	msg.address_hi = addr >> 32;
-
 	list_for_each_entry(entry, &pdev->msi_list, list) {
 		hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
 		if (hwirq < 0) {
@@ -129,6 +153,12 @@ static int u3msi_setup_msi_irqs(struct p
 			return hwirq;
 		}
 
+		addr = find_ht_magic_addr(pdev, hwirq);
+		if (addr == 0)
+			addr = find_u4_magic_addr(pdev, hwirq);
+		msg.address_lo = addr & 0xFFFFFFFF;
+		msg.address_hi = addr >> 32;
+
 		virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
 		if (virq == NO_IRQ) {
 			pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq);
@@ -143,6 +173,8 @@ static int u3msi_setup_msi_irqs(struct p
 		pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
 			  virq, hwirq, (unsigned long)addr);
 
+		printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
+			  virq, hwirq, (unsigned long)addr);
 		msg.data = hwirq;
 		write_msi_msg(virq, &msg);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mv64x60_pic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mv64x60_pic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/mv64x60_pic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/mv64x60_pic.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,7 +213,7 @@ static int mv64x60_host_map(struct irq_h
 {
 	int level1;
 
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 
 	level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
 	BUG_ON(level1 > MV64x60_LEVEL1_GPP);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -569,7 +569,8 @@ static void __init ppc4xx_probe_pcix_bri
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
 	/* Setup config space */
-	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
+	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4,
+					PPC_INDIRECT_TYPE_SET_CFG_TYPE);
 
 	/* Disable all windows */
 	writel(0, reg + PCIX0_POM0SA);
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/qe_lib/qe.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/qe_lib/qe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,8 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/crc32.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_platform.h>
 #include <asm/irq.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -65,19 +67,6 @@ static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
-int qe_alive_during_sleep(void)
-{
-	static int ret = -1;
-
-	if (ret != -1)
-		return ret;
-
-	ret = !of_find_compatible_node(NULL, NULL, "fsl,mpc8569-pmc");
-
-	return ret;
-}
-EXPORT_SYMBOL(qe_alive_during_sleep);
-
 phys_addr_t get_qe_base(void)
 {
 	struct device_node *qe;
@@ -104,7 +93,7 @@ phys_addr_t get_qe_base(void)
 
 EXPORT_SYMBOL(get_qe_base);
 
-void __init qe_reset(void)
+void qe_reset(void)
 {
 	if (qe_immr == NULL)
 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
@@ -330,16 +319,18 @@ EXPORT_SYMBOL(qe_put_snum);
 static int qe_sdma_init(void)
 {
 	struct sdma __iomem *sdma = &qe_immr->sdma;
-	unsigned long sdma_buf_offset;
+	static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
 
 	if (!sdma)
 		return -ENODEV;
 
 	/* allocate 2 internal temporary buffers (512 bytes size each) for
 	 * the SDMA */
- 	sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
-	if (IS_ERR_VALUE(sdma_buf_offset))
-		return -ENOMEM;
+	if (IS_ERR_VALUE(sdma_buf_offset)) {
+		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
+		if (IS_ERR_VALUE(sdma_buf_offset))
+			return -ENOMEM;
+	}
 
 	out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
  	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
@@ -349,7 +340,7 @@ static int qe_sdma_init(void)
 }
 
 /* The maximum number of RISCs we support */
-#define MAX_QE_RISC     2
+#define MAX_QE_RISC     4
 
 /* Firmware information stored here for qe_get_firmware_info() */
 static struct qe_firmware_info qe_firmware_info;
@@ -658,3 +649,35 @@ unsigned int qe_get_num_of_snums(void)
 	return num_of_snums;
 }
 EXPORT_SYMBOL(qe_get_num_of_snums);
+
+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
+static int qe_resume(struct of_device *ofdev)
+{
+	if (!qe_alive_during_sleep())
+		qe_reset();
+	return 0;
+}
+
+static int qe_probe(struct of_device *ofdev, const struct of_device_id *id)
+{
+	return 0;
+}
+
+static const struct of_device_id qe_ids[] = {
+	{ .compatible = "fsl,qe", },
+	{ },
+};
+
+static struct of_platform_driver qe_driver = {
+	.driver.name = "fsl-qe",
+	.match_table = qe_ids,
+	.probe = qe_probe,
+	.resume = qe_resume,
+};
+
+static int __init qe_drv_init(void)
+{
+	return of_register_platform_driver(&qe_driver);
+}
+device_initcall(qe_drv_init);
+#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/qe_lib/qe_ic.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,7 @@ static inline void qe_ic_write(volatile
 
 static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
 {
-	return irq_desc[virq].chip_data;
+	return irq_to_desc(virq)->chip_data;
 }
 
 #define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
@@ -237,7 +237,7 @@ static void qe_ic_mask_irq(unsigned int
 }
 
 static struct irq_chip qe_ic_irq_chip = {
-	.typename = " QEIC  ",
+	.name = " QEIC  ",
 	.unmask = qe_ic_unmask_irq,
 	.mask = qe_ic_mask_irq,
 	.mask_ack = qe_ic_mask_irq,
@@ -263,7 +263,7 @@ static int qe_ic_host_map(struct irq_hos
 	chip = &qe_ic->hc_irq;
 
 	set_irq_chip_data(virq, qe_ic);
-	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	irq_to_desc(virq)->status |= IRQ_LEVEL;
 
 	set_irq_chip_and_handler(virq, chip, handle_level_irq);
 
@@ -271,7 +271,7 @@ static int qe_ic_host_map(struct irq_hos
 }
 
 static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 * intspec, unsigned int intsize,
+			    const u32 * intspec, unsigned int intsize,
 			    irq_hw_number_t * out_hwirq,
 			    unsigned int *out_flags)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/tsi108_pci.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/tsi108_pci.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/tsi108_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/tsi108_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -376,7 +376,7 @@ static void tsi108_pci_irq_end(u_int irq
  */
 
 static struct irq_chip tsi108_pci_irq = {
-	.typename = "tsi108_PCI_int",
+	.name = "tsi108_PCI_int",
 	.mask = tsi108_pci_irq_disable,
 	.ack = tsi108_pci_irq_ack,
 	.end = tsi108_pci_irq_end,
@@ -384,7 +384,7 @@ static struct irq_chip tsi108_pci_irq =
 };
 
 static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
-			    u32 *intspec, unsigned int intsize,
+			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
 	*out_hwirq = intspec[0];
@@ -398,7 +398,7 @@ static int pci_irq_host_map(struct irq_h
 	DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
 	if ((virq >= 1) && (virq <= 4)){
 		irq = virq + IRQ_PCI_INTAD_BASE - 1;
-		get_irq_desc(irq)->status |= IRQ_LEVEL;
+		irq_to_desc(irq)->status |= IRQ_LEVEL;
 		set_irq_chip(irq, &tsi108_pci_irq);
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/uic.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/uic.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/uic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/uic.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,7 +57,7 @@ struct uic {
 
 static void uic_unmask_irq(unsigned int virq)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	struct uic *uic = get_irq_chip_data(virq);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
@@ -101,7 +101,7 @@ static void uic_ack_irq(unsigned int vir
 
 static void uic_mask_ack_irq(unsigned int virq)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	struct uic *uic = get_irq_chip_data(virq);
 	unsigned int src = uic_irq_to_hw(virq);
 	unsigned long flags;
@@ -129,7 +129,7 @@ static int uic_set_irq_type(unsigned int
 {
 	struct uic *uic = get_irq_chip_data(virq);
 	unsigned int src = uic_irq_to_hw(virq);
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 	unsigned long flags;
 	int trigger, polarity;
 	u32 tr, pr, mask;
@@ -177,7 +177,7 @@ static int uic_set_irq_type(unsigned int
 }
 
 static struct irq_chip uic_irq_chip = {
-	.typename	= " UIC  ",
+	.name		= " UIC  ",
 	.unmask		= uic_unmask_irq,
 	.mask		= uic_mask_irq,
  	.mask_ack	= uic_mask_ack_irq,
@@ -202,7 +202,7 @@ static int uic_host_map(struct irq_host
 }
 
 static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
-			  u32 *intspec, unsigned int intsize,
+			  const u32 *intspec, unsigned int intsize,
 			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
 
 {
@@ -225,12 +225,12 @@ void uic_irq_cascade(unsigned int virq,
 	int src;
 	int subvirq;
 
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
 		desc->chip->mask(virq);
 	else
 		desc->chip->mask_ack(virq);
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 
 	msr = mfdcr(uic->dcrbase + UIC_MSR);
 	if (!msr) /* spurious interrupt */
@@ -242,12 +242,12 @@ void uic_irq_cascade(unsigned int virq,
 	generic_handle_irq(subvirq);
 
 uic_irq_ret:
-	spin_lock(&desc->lock);
+	raw_spin_lock(&desc->lock);
 	if (desc->status & IRQ_LEVEL)
 		desc->chip->ack(virq);
 	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
 		desc->chip->unmask(virq);
-	spin_unlock(&desc->lock);
+	raw_spin_unlock(&desc->lock);
 }
 
 static struct uic * __init uic_init_one(struct device_node *node)
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/xilinx_intc.c linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/xilinx_intc.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/sysdev/xilinx_intc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/sysdev/xilinx_intc.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ static void xilinx_intc_mask(unsigned in
 
 static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
+	struct irq_desc *desc = irq_to_desc(virq);
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@@ -106,7 +106,7 @@ static void xilinx_intc_level_unmask(uns
 }
 
 static struct irq_chip xilinx_intc_level_irqchip = {
-	.typename = "Xilinx Level INTC",
+	.name = "Xilinx Level INTC",
 	.mask = xilinx_intc_mask,
 	.mask_ack = xilinx_intc_mask,
 	.unmask = xilinx_intc_level_unmask,
@@ -133,7 +133,7 @@ static void xilinx_intc_edge_ack(unsigne
 }
 
 static struct irq_chip xilinx_intc_edge_irqchip = {
-	.typename = "Xilinx Edge  INTC",
+	.name = "Xilinx Edge  INTC",
 	.mask = xilinx_intc_mask,
 	.unmask = xilinx_intc_edge_unmask,
 	.ack = xilinx_intc_edge_ack,
@@ -148,7 +148,7 @@ static struct irq_chip xilinx_intc_edge_
  * xilinx_intc_xlate - translate virq# from device tree interrupts property
  */
 static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
-				u32 *intspec, unsigned int intsize,
+				const u32 *intspec, unsigned int intsize,
 				irq_hw_number_t *out_hwirq,
 				unsigned int *out_flags)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/powerpc/xmon/xmon.c linux-libre-2.6.33-gnu1/arch/powerpc/xmon/xmon.c
--- linux-libre-2.6.32-gnu1/arch/powerpc/xmon/xmon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/powerpc/xmon/xmon.c	2010-02-24 13:52:17.000000000 -0500
@@ -1641,7 +1641,8 @@ static void super_regs(void)
 			       ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
 			printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
 			       ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
-			printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
+			printf("    Saved Gpr5=%.16lx \n",
+				ptrLpPaca->gpr5_dword.saved_gpr5);
 		}
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/appldata/appldata_base.c linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_base.c
--- linux-libre-2.6.32-gnu1/arch/s390/appldata/appldata_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,12 +61,12 @@ static struct ctl_table appldata_table[]
 	{
 		.procname	= "timer",
 		.mode		= S_IRUGO | S_IWUSR,
-		.proc_handler	= &appldata_timer_handler,
+		.proc_handler	= appldata_timer_handler,
 	},
 	{
 		.procname	= "interval",
 		.mode		= S_IRUGO | S_IWUSR,
-		.proc_handler	= &appldata_interval_handler,
+		.proc_handler	= appldata_interval_handler,
 	},
 	{ },
 };
@@ -551,7 +551,7 @@ static int appldata_thaw(struct device *
 	return appldata_restore(dev);
 }
 
-static struct dev_pm_ops appldata_pm_ops = {
+static const struct dev_pm_ops appldata_pm_ops = {
 	.freeze		= appldata_freeze,
 	.thaw		= appldata_thaw,
 	.restore	= appldata_restore,
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/appldata/appldata_net_sum.c linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_net_sum.c
--- linux-libre-2.6.32-gnu1/arch/s390/appldata/appldata_net_sum.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/appldata/appldata_net_sum.c	2010-02-24 13:52:17.000000000 -0500
@@ -83,8 +83,9 @@ static void appldata_get_net_sum_data(vo
 	rx_dropped = 0;
 	tx_dropped = 0;
 	collisions = 0;
-	read_lock(&dev_base_lock);
-	for_each_netdev(&init_net, dev) {
+
+	rcu_read_lock();
+	for_each_netdev_rcu(&init_net, dev) {
 		const struct net_device_stats *stats = dev_get_stats(dev);
 
 		rx_packets += stats->rx_packets;
@@ -98,7 +99,8 @@ static void appldata_get_net_sum_data(vo
 		collisions += stats->collisions;
 		i++;
 	}
-	read_unlock(&dev_base_lock);
+	rcu_read_unlock();
+
 	net_data->nr_interfaces = i;
 	net_data->rx_packets = rx_packets;
 	net_data->tx_packets = tx_packets;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/crypto/aes_s390.c linux-libre-2.6.33-gnu1/arch/s390/crypto/aes_s390.c
--- linux-libre-2.6.32-gnu1/arch/s390/crypto/aes_s390.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/crypto/aes_s390.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,7 +174,7 @@ static int fallback_init_cip(struct cryp
 	if (IS_ERR(sctx->fallback.cip)) {
 		pr_err("Allocating AES fallback algorithm %s failed\n",
 		       name);
-		return PTR_ERR(sctx->fallback.blk);
+		return PTR_ERR(sctx->fallback.cip);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/crypto/prng.c linux-libre-2.6.33-gnu1/arch/s390/crypto/prng.c
--- linux-libre-2.6.32-gnu1/arch/s390/crypto/prng.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/crypto/prng.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -49,7 +48,6 @@ static unsigned char parm_block[32] = {
 
 static int prng_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
 	return nonseekable_open(inode, file);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/defconfig linux-libre-2.6.33-gnu1/arch/s390/defconfig
--- linux-libre-2.6.32-gnu1/arch/s390/defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Tue Sep 22 17:43:13 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 09:03:07 2010
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -51,6 +51,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -113,7 +114,6 @@ CONFIG_HAVE_PERF_EVENTS=y
 # CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -149,21 +149,78 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_PREEMPT_NOTIFIERS=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_READ_TRYLOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK=y
+CONFIG_ARCH_INLINE_READ_LOCK_BH=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_READ_UNLOCK=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -185,7 +242,6 @@ CONFIG_HOTPLUG_CPU=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
-CONFIG_S390_SWITCH_AMODE=y
 CONFIG_S390_EXEC_PROTECT=y
 
 #
@@ -228,14 +284,13 @@ CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
 #
@@ -340,6 +395,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -505,6 +561,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_OSD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -711,7 +771,6 @@ CONFIG_S390_VMUR=m
 # CONFIG_PPS is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEMSTICK is not set
@@ -865,6 +924,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -932,7 +992,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_SAMPLES=y
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
-# CONFIG_KMEMCHECK is not set
 
 #
 # Security options
@@ -940,7 +999,11 @@ CONFIG_SAMPLES=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/hypfs/hypfs_diag.c linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_diag.c
--- linux-libre-2.6.32-gnu1/arch/s390/hypfs/hypfs_diag.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_diag.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ static inline void part_hdr__part_name(e
 		       LPAR_NAME_LEN);
 	EBCASC(name, LPAR_NAME_LEN);
 	name[LPAR_NAME_LEN] = 0;
-	strstrip(name);
+	strim(name);
 }
 
 struct cpu_info {
@@ -523,7 +523,7 @@ static int diag224_idx2name(int index, c
 	memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN),
 		CPU_NAME_LEN);
 	name[CPU_NAME_LEN] = 0;
-	strstrip(name);
+	strim(name);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/hypfs/hypfs_vm.c linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_vm.c
--- linux-libre-2.6.32-gnu1/arch/s390/hypfs/hypfs_vm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/hypfs/hypfs_vm.c	2010-02-24 13:52:17.000000000 -0500
@@ -124,7 +124,7 @@ static int hpyfs_vm_create_guest(struct
 	/* guest dir */
 	memcpy(guest_name, data->guest_name, NAME_LEN);
 	EBCASC(guest_name, NAME_LEN);
-	strstrip(guest_name);
+	strim(guest_name);
 	guest_dir = hypfs_mkdir(sb, systems_dir, guest_name);
 	if (IS_ERR(guest_dir))
 		return PTR_ERR(guest_dir);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/atomic.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/atomic.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/atomic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,7 @@
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 
 #define __CS_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	int old_val, new_val;						\
 	asm volatile(							\
 		"	l	%0,%2\n"				\
 		"0:	lr	%1,%0\n"				\
@@ -38,7 +38,7 @@
 #else /* __GNUC__ */
 
 #define __CS_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	int old_val, new_val;						\
 	asm volatile(							\
 		"	l	%0,0(%3)\n"				\
 		"0:	lr	%1,%0\n"				\
@@ -143,7 +143,7 @@ static inline int atomic_add_unless(atom
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 
 #define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	long long old_val, new_val;					\
 	asm volatile(							\
 		"	lg	%0,%2\n"				\
 		"0:	lgr	%1,%0\n"				\
@@ -160,7 +160,7 @@ static inline int atomic_add_unless(atom
 #else /* __GNUC__ */
 
 #define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
+	long long old_val, new_val;					\
 	asm volatile(							\
 		"	lg	%0,0(%3)\n"				\
 		"0:	lgr	%1,%0\n"				\
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,11 @@
 
 #define BUG() do {					\
 	__EMIT_BUG(0);					\
-	for (;;);					\
+	unreachable();					\
+} while (0)
+
+#define __WARN() do {					\
+	__EMIT_BUG(BUGFLAG_WARNING);			\
 } while (0)
 
 #define WARN_ON(x) ({					\
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@
 #define flush_cache_dup_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_page(page)			do { } while (0)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/ccwdev.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/ccwdev.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/ccwdev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/ccwdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -142,6 +142,8 @@ struct ccw1;
 extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
 extern int ccw_device_set_options(struct ccw_device *, unsigned long);
 extern void ccw_device_clear_options(struct ccw_device *, unsigned long);
+int ccw_device_is_pathgroup(struct ccw_device *cdev);
+int ccw_device_is_multipath(struct ccw_device *cdev);
 
 /* Allow for i/o completion notification after primary interrupt status. */
 #define CCWDEV_EARLY_NOTIFICATION	0x0001
@@ -151,6 +153,8 @@ extern void ccw_device_clear_options(str
 #define CCWDEV_DO_PATHGROUP             0x0004
 /* Allow forced onlining of boxed devices. */
 #define CCWDEV_ALLOW_FORCE              0x0008
+/* Try to use multipath mode. */
+#define CCWDEV_DO_MULTIPATH		0x0010
 
 extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
 			    unsigned long, __u8, unsigned long);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/cputime.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/cputime.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/cputime.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/cputime.h	2010-02-24 13:52:17.000000000 -0500
@@ -183,6 +183,7 @@ struct s390_idle_data {
 	unsigned long long idle_count;
 	unsigned long long idle_enter;
 	unsigned long long idle_time;
+	int nohz_delay;
 };
 
 DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
@@ -198,4 +199,11 @@ static inline void s390_idle_check(void)
 		vtime_start_cpu();
 }
 
+static inline int s390_nohz_delay(int cpu)
+{
+	return per_cpu(s390_idle, cpu).nohz_delay != 0;
+}
+
+#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
+
 #endif /* _S390_CPUTIME_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -155,7 +155,6 @@ extern unsigned int vdso_enabled;
 	} while (0)
 
 #define CORE_DUMP_USE_REGSET
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/irqflags.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/irqflags.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/irqflags.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/irqflags.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,12 @@
 /*
- *  include/asm-s390/irqflags.h
- *
- *    Copyright (C) IBM Corp. 2006
- *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ *    Copyright IBM Corp. 2006,2010
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
 #ifndef __ASM_IRQFLAGS_H
 #define __ASM_IRQFLAGS_H
 
-#ifdef __KERNEL__
+#include <linux/types.h>
 
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
 
@@ -102,5 +100,4 @@ static inline int raw_irqs_disabled_flag
 /* For spinlocks etc */
 #define raw_local_irq_save(x)	((x) = raw_local_irq_disable())
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_IRQFLAGS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/kvm.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/kvm.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/kvm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/kvm.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
 #ifndef __LINUX_KVM_S390_H
 #define __LINUX_KVM_S390_H
-
 /*
  * asm-s390/kvm.h - KVM s390 specific structures and definitions
  *
@@ -15,6 +14,8 @@
  */
 #include <linux/types.h>
 
+#define __KVM_S390
+
 /* for KVM_GET_REGS and KVM_SET_REGS */
 struct kvm_regs {
 	/* general purpose regs for s390 */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/lowcore.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/lowcore.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/lowcore.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/lowcore.h	2010-02-24 13:52:17.000000000 -0500
@@ -293,12 +293,12 @@ struct _lowcore
 	__u64	clock_comparator;		/* 0x02d0 */
 	__u32	machine_flags;			/* 0x02d8 */
 	__u32	ftrace_func;			/* 0x02dc */
-	__u8	pad_0x02f0[0x0300-0x02f0];	/* 0x02f0 */
+	__u8	pad_0x02e0[0x0300-0x02e0];	/* 0x02e0 */
 
 	/* Interrupt response block */
 	__u8	irb[64];			/* 0x0300 */
 
-	__u8	pad_0x0400[0x0e00-0x0400];	/* 0x0400 */
+	__u8	pad_0x0340[0x0e00-0x0340];	/* 0x0340 */
 
 	/*
 	 * 0xe00 contains the address of the IPL Parameter Information
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/mmu_context.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/mmu_context.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/mmu_context.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/mmu_context.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,7 +36,7 @@ static inline int init_new_context(struc
 		mm->context.has_pgste = 1;
 		mm->context.alloc_pgste = 1;
 	} else {
-		mm->context.noexec = s390_noexec;
+		mm->context.noexec = (user_mode == SECONDARY_SPACE_MODE);
 		mm->context.has_pgste = 0;
 		mm->context.alloc_pgste = 0;
 	}
@@ -58,7 +58,7 @@ static inline void update_mm(struct mm_s
 	pgd_t *pgd = mm->pgd;
 
 	S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
-	if (switch_amode) {
+	if (user_mode != HOME_SPACE_MODE) {
 		/* Load primary space page table origin. */
 		pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd;
 		S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/param.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/param.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/param.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/param.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,30 +1,6 @@
-/*
- *  include/asm-s390/param.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/param.h"
- */
-
 #ifndef _ASMS390_PARAM_H
 #define _ASMS390_PARAM_H
 
-#ifdef __KERNEL__
-# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
-# define USER_HZ	100		/* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE	4096
-
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
+#include <asm-generic/param.h>
 
-#endif
+#endif /* _ASMS390_PARAM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/pgalloc.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgalloc.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/pgalloc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgalloc.h	2010-02-24 13:52:17.000000000 -0500
@@ -143,7 +143,8 @@ static inline pgd_t *pgd_alloc(struct mm
 	spin_lock_init(&mm->context.list_lock);
 	INIT_LIST_HEAD(&mm->context.crst_list);
 	INIT_LIST_HEAD(&mm->context.pgtable_list);
-	return (pgd_t *) crst_table_alloc(mm, s390_noexec);
+	return (pgd_t *)
+		crst_table_alloc(mm, user_mode == SECONDARY_SPACE_MODE);
 }
 #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -169,12 +169,13 @@ extern unsigned long VMALLOC_START;
  * STL Segment-Table-Length:  Segment-table length (STL+1*16 entries -> up to 2048)
  *
  * A 64 bit pagetable entry of S390 has following format:
- * |                     PFRA                         |0IP0|  OS  |
+ * |			 PFRA			      |0IPC|  OS  |
  * 0000000000111111111122222222223333333333444444444455555555556666
  * 0123456789012345678901234567890123456789012345678901234567890123
  *
  * I Page-Invalid Bit:    Page is not available for address-translation
  * P Page-Protection Bit: Store access not possible for page
+ * C Change-bit override: HW is not required to set change bit
  *
  * A 64 bit segmenttable entry of S390 has following format:
  * |        P-table origin                              |      TT
@@ -218,6 +219,7 @@ extern unsigned long VMALLOC_START;
  */
 
 /* Hardware bits in the page table entry */
+#define _PAGE_CO	0x100		/* HW Change-bit override */
 #define _PAGE_RO	0x200		/* HW read-only bit  */
 #define _PAGE_INVALID	0x400		/* HW invalid bit    */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/setup.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/setup.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/setup.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/setup.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,17 +49,12 @@ extern unsigned long memory_end;
 
 void detect_memory_layout(struct mem_chunk chunk[]);
 
-#ifdef CONFIG_S390_SWITCH_AMODE
-extern unsigned int switch_amode;
-#else
-#define switch_amode	(0)
-#endif
+#define PRIMARY_SPACE_MODE	0
+#define ACCESS_REGISTER_MODE	1
+#define SECONDARY_SPACE_MODE	2
+#define HOME_SPACE_MODE		3
 
-#ifdef CONFIG_S390_EXEC_PROTECT
-extern unsigned int s390_noexec;
-#else
-#define s390_noexec	(0)
-#endif
+extern unsigned int user_mode;
 
 /*
  * Machine features detected in head.S
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/sigp.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/sigp.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/sigp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/sigp.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,11 +15,19 @@
 #ifndef __SIGP__
 #define __SIGP__
 
-#include <asm/ptrace.h>
-#include <asm/atomic.h>
+#include <asm/system.h>
 
 /* get real cpu address from logical cpu number */
-extern volatile int __cpu_logical_map[];
+extern int __cpu_logical_map[];
+
+static inline int cpu_logical_map(int cpu)
+{
+#ifdef CONFIG_SMP
+	return __cpu_logical_map[cpu];
+#else
+	return stap();
+#endif
+}
 
 typedef enum
 {
@@ -79,7 +87,7 @@ signal_processor(__u16 cpu_addr, sigp_or
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		:	"=d"	(ccode)
-		: "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
+		: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
 		  "a" (order_code) : "cc" , "memory");
 	return ccode;
 }
@@ -98,7 +106,7 @@ signal_processor_p(__u32 parameter, __u1
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		: "=d" (ccode)
-		: "d" (reg1), "d" (__cpu_logical_map[cpu_addr]),
+		: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
 		  "a" (order_code) : "cc" , "memory");
 	return ccode;
 }
@@ -118,7 +126,7 @@ signal_processor_ps(__u32 *statusptr, __
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		: "=d" (ccode), "+d" (reg1)
-		: "d" (__cpu_logical_map[cpu_addr]), "a" (order_code)
+		: "d" (cpu_logical_map(cpu_addr)), "a" (order_code)
 		: "cc" , "memory");
 	*statusptr = reg1;
 	return ccode;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/smp.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/smp.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/smp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/smp.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,57 +1,22 @@
 /*
- *  include/asm-s390/smp.h
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com)
- *               Heiko Carstens (heiko.carstens@de.ibm.com)
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Denis Joseph Barrow,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
  */
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/bitops.h>
-
-#if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__)
+#ifdef CONFIG_SMP
 
-#include <asm/lowcore.h>
-#include <asm/sigp.h>
-#include <asm/ptrace.h>
 #include <asm/system.h>
-
-/*
-  s390 specific smp.c headers
- */
-typedef struct
-{
-	int        intresting;
-	sigp_ccode ccode; 
-	__u32      status;
-	__u16      cpu;
-} sigp_info;
+#include <asm/sigp.h>
 
 extern void machine_restart_smp(char *);
 extern void machine_halt_smp(void);
 extern void machine_power_off_smp(void);
 
-#define NO_PROC_ID		0xFF		/* No processor magic marker */
-
-/*
- *	This magic constant controls our willingness to transfer
- *	a process across CPUs. Such a transfer incurs misses on the L1
- *	cache, and on a P6 or P5 with multiple L2 caches L2 hits. My
- *	gut feeling is this will vary by board in value. For a board
- *	with separate L2 cache it probably depends also on the RSS, and
- *	for a board with shared L2 cache it ought to decay fast as other
- *	processes are run.
- */
- 
-#define PROC_CHANGE_PENALTY	20		/* Schedule penalty */
-
 #define raw_smp_processor_id()	(S390_lowcore.cpu_nr)
-#define cpu_logical_map(cpu)	(cpu)
 
 extern int __cpu_disable (void);
 extern void __cpu_die (unsigned int cpu);
@@ -64,7 +29,9 @@ extern int smp_cpu_polarization[];
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-#endif
+extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
+
+#endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
 extern int smp_rescan_cpus(void);
@@ -72,5 +39,4 @@ extern int smp_rescan_cpus(void);
 static inline int smp_rescan_cpus(void) { return 0; }
 #endif
 
-extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
-#endif
+#endif /* __ASM_SMP_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -68,4 +68,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/sockios.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/sockios.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/sockios.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/sockios.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,21 +1,6 @@
-/*
- *  include/asm-s390/sockios.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/sockios.h"
- */
-
-#ifndef __ARCH_S390_SOCKIOS__
-#define __ARCH_S390_SOCKIOS__
+#ifndef _ASM_S390_SOCKIOS_H
+#define _ASM_S390_SOCKIOS_H
 
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 	0x8901
-#define SIOCSPGRP	0x8902
-#define FIOGETOWN	0x8903
-#define SIOCGPGRP	0x8904
-#define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
-#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
+#include <asm-generic/sockios.h>
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -52,27 +52,27 @@ _raw_compare_and_swap(volatile unsigned
  * (the type definitions are in asm/spinlock_types.h)
  */
 
-#define __raw_spin_is_locked(x) ((x)->owner_cpu != 0)
-#define __raw_spin_unlock_wait(lock) \
-	do { while (__raw_spin_is_locked(lock)) \
-		 _raw_spin_relax(lock); } while (0)
+#define arch_spin_is_locked(x) ((x)->owner_cpu != 0)
+#define arch_spin_unlock_wait(lock) \
+	do { while (arch_spin_is_locked(lock)) \
+		 arch_spin_relax(lock); } while (0)
 
-extern void _raw_spin_lock_wait(raw_spinlock_t *);
-extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags);
-extern int _raw_spin_trylock_retry(raw_spinlock_t *);
-extern void _raw_spin_relax(raw_spinlock_t *lock);
+extern void arch_spin_lock_wait(arch_spinlock_t *);
+extern void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags);
+extern int arch_spin_trylock_retry(arch_spinlock_t *);
+extern void arch_spin_relax(arch_spinlock_t *lock);
 
-static inline void __raw_spin_lock(raw_spinlock_t *lp)
+static inline void arch_spin_lock(arch_spinlock_t *lp)
 {
 	int old;
 
 	old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id());
 	if (likely(old == 0))
 		return;
-	_raw_spin_lock_wait(lp);
+	arch_spin_lock_wait(lp);
 }
 
-static inline void __raw_spin_lock_flags(raw_spinlock_t *lp,
+static inline void arch_spin_lock_flags(arch_spinlock_t *lp,
 					 unsigned long flags)
 {
 	int old;
@@ -80,20 +80,20 @@ static inline void __raw_spin_lock_flags
 	old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id());
 	if (likely(old == 0))
 		return;
-	_raw_spin_lock_wait_flags(lp, flags);
+	arch_spin_lock_wait_flags(lp, flags);
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lp)
+static inline int arch_spin_trylock(arch_spinlock_t *lp)
 {
 	int old;
 
 	old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id());
 	if (likely(old == 0))
 		return 1;
-	return _raw_spin_trylock_retry(lp);
+	return arch_spin_trylock_retry(lp);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lp)
+static inline void arch_spin_unlock(arch_spinlock_t *lp)
 {
 	_raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0);
 }
@@ -113,22 +113,22 @@ static inline void __raw_spin_unlock(raw
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_read_can_lock(x) ((int)(x)->lock >= 0)
+#define arch_read_can_lock(x) ((int)(x)->lock >= 0)
 
 /**
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_write_can_lock(x) ((x)->lock == 0)
+#define arch_write_can_lock(x) ((x)->lock == 0)
 
-extern void _raw_read_lock_wait(raw_rwlock_t *lp);
-extern void _raw_read_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags);
-extern int _raw_read_trylock_retry(raw_rwlock_t *lp);
-extern void _raw_write_lock_wait(raw_rwlock_t *lp);
-extern void _raw_write_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags);
-extern int _raw_write_trylock_retry(raw_rwlock_t *lp);
+extern void _raw_read_lock_wait(arch_rwlock_t *lp);
+extern void _raw_read_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags);
+extern int _raw_read_trylock_retry(arch_rwlock_t *lp);
+extern void _raw_write_lock_wait(arch_rwlock_t *lp);
+extern void _raw_write_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags);
+extern int _raw_write_trylock_retry(arch_rwlock_t *lp);
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned int old;
 	old = rw->lock & 0x7fffffffU;
@@ -136,7 +136,7 @@ static inline void __raw_read_lock(raw_r
 		_raw_read_lock_wait(rw);
 }
 
-static inline void __raw_read_lock_flags(raw_rwlock_t *rw, unsigned long flags)
+static inline void arch_read_lock_flags(arch_rwlock_t *rw, unsigned long flags)
 {
 	unsigned int old;
 	old = rw->lock & 0x7fffffffU;
@@ -144,7 +144,7 @@ static inline void __raw_read_lock_flags
 		_raw_read_lock_wait_flags(rw, flags);
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned int old, cmp;
 
@@ -155,24 +155,24 @@ static inline void __raw_read_unlock(raw
 	} while (cmp != old);
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0))
 		_raw_write_lock_wait(rw);
 }
 
-static inline void __raw_write_lock_flags(raw_rwlock_t *rw, unsigned long flags)
+static inline void arch_write_lock_flags(arch_rwlock_t *rw, unsigned long flags)
 {
 	if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0))
 		_raw_write_lock_wait_flags(rw, flags);
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	_raw_compare_and_swap(&rw->lock, 0x80000000, 0);
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned int old;
 	old = rw->lock & 0x7fffffffU;
@@ -181,43 +181,14 @@ static inline int __raw_read_trylock(raw
 	return _raw_read_trylock_retry(rw);
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0))
 		return 1;
 	return _raw_write_trylock_retry(rw);
 }
 
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
-
-#define __always_inline__spin_lock
-#define __always_inline__read_lock
-#define __always_inline__write_lock
-#define __always_inline__spin_lock_bh
-#define __always_inline__read_lock_bh
-#define __always_inline__write_lock_bh
-#define __always_inline__spin_lock_irq
-#define __always_inline__read_lock_irq
-#define __always_inline__write_lock_irq
-#define __always_inline__spin_lock_irqsave
-#define __always_inline__read_lock_irqsave
-#define __always_inline__write_lock_irqsave
-#define __always_inline__spin_trylock
-#define __always_inline__read_trylock
-#define __always_inline__write_trylock
-#define __always_inline__spin_trylock_bh
-#define __always_inline__spin_unlock
-#define __always_inline__read_unlock
-#define __always_inline__write_unlock
-#define __always_inline__spin_unlock_bh
-#define __always_inline__read_unlock_bh
-#define __always_inline__write_unlock_bh
-#define __always_inline__spin_unlock_irq
-#define __always_inline__read_unlock_irq
-#define __always_inline__write_unlock_irq
-#define __always_inline__spin_unlock_irqrestore
-#define __always_inline__read_unlock_irqrestore
-#define __always_inline__write_unlock_irqrestore
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* __ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,14 +7,14 @@
 
 typedef struct {
 	volatile unsigned int owner_cpu;
-} __attribute__ ((aligned (4))) raw_spinlock_t;
+} __attribute__ ((aligned (4))) arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/termbits.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/termbits.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/termbits.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/termbits.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,206 +1,6 @@
-/*
- *  include/asm-s390/termbits.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/termbits.h"
- */
-
-#ifndef __ARCH_S390_TERMBITS_H__
-#define __ARCH_S390_TERMBITS_H__
-
-#include <linux/posix_types.h>
-
-typedef unsigned char	cc_t;
-typedef unsigned int	speed_t;
-typedef unsigned int	tcflag_t;
-
-#define NCCS 19
-struct termios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-};
-
-struct termios2 {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-struct ktermios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK	0000001
-#define BRKINT	0000002
-#define IGNPAR	0000004
-#define PARMRK	0000010
-#define INPCK	0000020
-#define ISTRIP	0000040
-#define INLCR	0000100
-#define IGNCR	0000200
-#define ICRNL	0000400
-#define IUCLC	0001000
-#define IXON	0002000
-#define IXANY	0004000
-#define IXOFF	0010000
-#define IMAXBEL	0020000
-#define IUTF8	0040000
-
-/* c_oflag bits */
-#define OPOST	0000001
-#define OLCUC	0000002
-#define ONLCR	0000004
-#define OCRNL	0000010
-#define ONOCR	0000020
-#define ONLRET	0000040
-#define OFILL	0000100
-#define OFDEL	0000200
-#define NLDLY	0000400
-#define   NL0	0000000
-#define   NL1	0000400
-#define CRDLY	0003000
-#define   CR0	0000000
-#define   CR1	0001000
-#define   CR2	0002000
-#define   CR3	0003000
-#define TABDLY	0014000
-#define   TAB0	0000000
-#define   TAB1	0004000
-#define   TAB2	0010000
-#define   TAB3	0014000
-#define   XTABS	0014000
-#define BSDLY	0020000
-#define   BS0	0000000
-#define   BS1	0020000
-#define VTDLY	0040000
-#define   VT0	0000000
-#define   VT1	0040000
-#define FFDLY	0100000
-#define   FF0	0000000
-#define   FF1	0100000
-
-/* c_cflag bit meaning */
-#define CBAUD	0010017
-#define  B0	0000000		/* hang up */
-#define  B50	0000001
-#define  B75	0000002
-#define  B110	0000003
-#define  B134	0000004
-#define  B150	0000005
-#define  B200	0000006
-#define  B300	0000007
-#define  B600	0000010
-#define  B1200	0000011
-#define  B1800	0000012
-#define  B2400	0000013
-#define  B4800	0000014
-#define  B9600	0000015
-#define  B19200	0000016
-#define  B38400	0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE	0000060
-#define   CS5	0000000
-#define   CS6	0000020
-#define   CS7	0000040
-#define   CS8	0000060
-#define CSTOPB	0000100
-#define CREAD	0000200
-#define PARENB	0000400
-#define PARODD	0001000
-#define HUPCL	0002000
-#define CLOCAL	0004000
-#define CBAUDEX 0010000
-#define  BOTHER  0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
-#define   B500000 0010005
-#define   B576000 0010006
-#define   B921600 0010007
-#define  B1000000 0010010
-#define  B1152000 0010011
-#define  B1500000 0010012
-#define  B2000000 0010013
-#define  B2500000 0010014
-#define  B3000000 0010015
-#define  B3500000 0010016
-#define  B4000000 0010017
-#define CIBAUD	  002003600000	/* input baud rate */
-#define CMSPAR	  010000000000		/* mark or space (stick) parity */
-#define CRTSCTS	  020000000000		/* flow control */
-
-#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG	0000001
-#define ICANON	0000002
-#define XCASE	0000004
-#define ECHO	0000010
-#define ECHOE	0000020
-#define ECHOK	0000040
-#define ECHONL	0000100
-#define NOFLSH	0000200
-#define TOSTOP	0000400
-#define ECHOCTL	0001000
-#define ECHOPRT	0002000
-#define ECHOKE	0004000
-#define FLUSHO	0010000
-#define PENDIN	0040000
-#define IEXTEN	0100000
-
-/* tcflow() and TCXONC use these */
-#define	TCOOFF		0
-#define	TCOON		1
-#define	TCIOFF		2
-#define	TCION		3
-
-/* tcflush() and TCFLSH use these */
-#define	TCIFLUSH	0
-#define	TCOFLUSH	1
-#define	TCIOFLUSH	2
+#ifndef _ASM_S390_TERMBITS_H
+#define _ASM_S390_TERMBITS_H
 
-/* tcsetattr uses these */
-#define	TCSANOW		0
-#define	TCSADRAIN	1
-#define	TCSAFLUSH	2
+#include <asm-generic/termbits.h>
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/thread_info.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/thread_info.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/thread_info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
@@ -93,13 +93,12 @@ static inline struct thread_info *curren
 #define TIF_SYSCALL_AUDIT	9	/* syscall auditing active */
 #define TIF_SECCOMP		10	/* secure computing */
 #define TIF_SYSCALL_TRACEPOINT	11	/* syscall tracepoint instrumentation */
-#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling 
+#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
-#define TIF_31BIT		18	/* 32bit process */ 
-#define TIF_MEMDIE		19
-#define TIF_RESTORE_SIGMASK	20	/* restore signal mask in do_signal() */
-#define TIF_FREEZE		21	/* thread is freezing for suspend */
+#define TIF_31BIT		17	/* 32bit process */
+#define TIF_MEMDIE		18
+#define TIF_RESTORE_SIGMASK	19	/* restore signal mask in do_signal() */
+#define TIF_FREEZE		20	/* thread is freezing for suspend */
 
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
@@ -112,7 +111,6 @@ static inline struct thread_info *curren
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT		(1<<TIF_31BIT)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/todclk.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/todclk.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/todclk.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/todclk.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * File...........: linux/include/asm/todclk.h
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef __ASM_TODCLK_H
-#define __ASM_TODCLK_H
-
-#ifdef __KERNEL__
-
-#define TOD_uSEC (0x1000ULL)
-#define TOD_mSEC (1000 * TOD_uSEC)
-#define TOD_SEC (1000 * TOD_mSEC)
-#define TOD_MIN (60 * TOD_SEC)
-#define TOD_HOUR (60 * TOD_MIN)
-
-#endif
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/uaccess.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/uaccess.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/uaccess.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
@@ -93,6 +93,8 @@ extern struct uaccess_ops uaccess_mvcos;
 extern struct uaccess_ops uaccess_mvcos_switch;
 extern struct uaccess_ops uaccess_pt;
 
+extern int __handle_fault(unsigned long, unsigned long, int);
+
 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
 {
 	size = uaccess.copy_to_user_small(size, ptr, x);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/s390/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/s390/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -376,6 +376,9 @@
 #define __IGNORE_migrate_pages
 #define __IGNORE_move_pages
 
+/* Ignore system calls that are also reachable via sys_socket */
+#define __IGNORE_recvmmsg
+
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/Kconfig linux-libre-2.6.33-gnu1/arch/s390/Kconfig
--- linux-libre-2.6.32-gnu1/arch/s390/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -95,6 +95,34 @@ config S390
 	select HAVE_ARCH_TRACEHOOK
 	select INIT_ALL_POSSIBLE
 	select HAVE_PERF_EVENTS
+	select ARCH_INLINE_SPIN_TRYLOCK
+	select ARCH_INLINE_SPIN_TRYLOCK_BH
+	select ARCH_INLINE_SPIN_LOCK
+	select ARCH_INLINE_SPIN_LOCK_BH
+	select ARCH_INLINE_SPIN_LOCK_IRQ
+	select ARCH_INLINE_SPIN_LOCK_IRQSAVE
+	select ARCH_INLINE_SPIN_UNLOCK
+	select ARCH_INLINE_SPIN_UNLOCK_BH
+	select ARCH_INLINE_SPIN_UNLOCK_IRQ
+	select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+	select ARCH_INLINE_READ_TRYLOCK
+	select ARCH_INLINE_READ_LOCK
+	select ARCH_INLINE_READ_LOCK_BH
+	select ARCH_INLINE_READ_LOCK_IRQ
+	select ARCH_INLINE_READ_LOCK_IRQSAVE
+	select ARCH_INLINE_READ_UNLOCK
+	select ARCH_INLINE_READ_UNLOCK_BH
+	select ARCH_INLINE_READ_UNLOCK_IRQ
+	select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+	select ARCH_INLINE_WRITE_TRYLOCK
+	select ARCH_INLINE_WRITE_LOCK
+	select ARCH_INLINE_WRITE_LOCK_BH
+	select ARCH_INLINE_WRITE_LOCK_IRQ
+	select ARCH_INLINE_WRITE_LOCK_IRQSAVE
+	select ARCH_INLINE_WRITE_UNLOCK
+	select ARCH_INLINE_WRITE_UNLOCK_BH
+	select ARCH_INLINE_WRITE_UNLOCK_IRQ
+	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
 
 config SCHED_OMIT_FRAME_POINTER
 	bool
@@ -192,23 +220,8 @@ config AUDIT_ARCH
 	bool
 	default y
 
-config S390_SWITCH_AMODE
-	bool "Switch kernel/user addressing modes"
-	help
-	  This option allows to switch the addressing modes of kernel and user
-	  space. The kernel parameter switch_amode=on will enable this feature,
-	  default is disabled. Enabling this (via kernel parameter) on machines
-	  earlier than IBM System z9-109 EC/BC will reduce system performance.
-
-	  Note that this option will also be selected by selecting the execute
-	  protection option below. Enabling the execute protection via the
-	  noexec kernel parameter will also switch the addressing modes,
-	  independent of the switch_amode kernel parameter.
-
-
 config S390_EXEC_PROTECT
 	bool "Data execute protection"
-	select S390_SWITCH_AMODE
 	help
 	  This option allows to enable a buffer overflow protection for user
 	  space programs and it also selects the addressing mode option above.
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_linux.c linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_linux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,14 +31,8 @@
 #include <linux/shm.h>
 #include <linux/slab.h>
 #include <linux/uio.h>
-#include <linux/nfs_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
@@ -527,59 +521,6 @@ asmlinkage long sys32_sendfile64(int out
 	return ret;
 }
 
-#ifdef CONFIG_SYSCTL_SYSCALL
-struct __sysctl_args32 {
-	u32 name;
-	int nlen;
-	u32 oldval;
-	u32 oldlenp;
-	u32 newval;
-	u32 newlen;
-	u32 __unused[4];
-};
-
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
-{
-	struct __sysctl_args32 tmp;
-	int error;
-	size_t oldlen;
-	size_t __user *oldlenp = NULL;
-	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
-
-	if (copy_from_user(&tmp, args, sizeof(tmp)))
-		return -EFAULT;
-
-	if (tmp.oldval && tmp.oldlenp) {
-		/* Duh, this is ugly and might not work if sysctl_args
-		   is in read-only memory, but do_sysctl does indirectly
-		   a lot of uaccess in both directions and we'd have to
-		   basically copy the whole sysctl.c here, and
-		   glibc's __sysctl uses rw memory for the structure
-		   anyway.  */
-		if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) ||
-		    put_user(oldlen, (size_t __user *)addr))
-			return -EFAULT;
-		oldlenp = (size_t __user *)addr;
-	}
-
-	lock_kernel();
-	error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval),
-			  oldlenp, compat_ptr(tmp.newval), tmp.newlen);
-	unlock_kernel();
-	if (oldlenp) {
-		if (!error) {
-			if (get_user(oldlen, (size_t __user *)addr) ||
-			    put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
-				error = -EFAULT;
-		}
-		if (copy_to_user(args->__unused, tmp.__unused,
-				 sizeof(tmp.__unused)))
-			error = -EFAULT;
-	}
-	return error;
-}
-#endif
-
 struct stat64_emu31 {
 	unsigned long long  st_dev;
 	unsigned int    __pad1;
@@ -675,75 +616,35 @@ asmlinkage long sys32_fstatat64(unsigned
  */
 
 struct mmap_arg_struct_emu31 {
-	u32	addr;
-	u32	len;
-	u32	prot;
-	u32	flags;
-	u32	fd;
-	u32	offset;
+	compat_ulong_t addr;
+	compat_ulong_t len;
+	compat_ulong_t prot;
+	compat_ulong_t flags;
+	compat_ulong_t fd;
+	compat_ulong_t offset;
 };
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long error = -EBADF;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
-		/* Result is out of bounds.  */
-		do_munmap(current->mm, addr, len);
-		error = -ENOMEM;
-	}
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:    
-	return error;
-}
-
-
-asmlinkage unsigned long
-old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
+asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
 {
 	struct mmap_arg_struct_emu31 a;
-	int error = -EFAULT;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-
-	error = -EINVAL;
+		return -EFAULT;
 	if (a.offset & ~PAGE_MASK)
-		goto out;
-
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); 
-out:
-	return error;
+		return -EINVAL;
+	a.addr = (unsigned long) compat_ptr(a.addr);
+	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+			      a.offset >> PAGE_SHIFT);
 }
 
-asmlinkage long 
-sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
+asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
 {
 	struct mmap_arg_struct_emu31 a;
-	int error = -EFAULT;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
-		goto out;
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
-out:
-	return error;
+		return -EFAULT;
+	a.addr = (unsigned long) compat_ptr(a.addr);
+	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 }
 
 asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_linux.h linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.h
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_linux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_linux.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,10 +4,6 @@
 #include <linux/compat.h>
 #include <linux/socket.h>
 #include <linux/syscalls.h>
-#include <linux/nfs_fs.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/export.h>
 
 /* Macro that masks the high order bit of an 32 bit pointer and converts it*/
 /*       to a 64 bit pointer */
@@ -162,7 +158,6 @@ struct ucontext32 {
 	compat_sigset_t		uc_sigmask;	/* mask last for extensibility */
 };
 
-struct __sysctl_args32;
 struct stat64_emu31;
 struct mmap_arg_struct_emu31;
 struct fadvise64_64_args;
@@ -212,7 +207,6 @@ long sys32_sendfile(int out_fd, int in_f
 		    size_t count);
 long sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset,
 		      s32 count);
-long sys32_sysctl(struct __sysctl_args32 __user *args);
 long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf);
 long sys32_lstat64(char __user * filename,
 		   struct stat64_emu31 __user * statbuf);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_wrapper.S linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_wrapper.S
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/compat_wrapper.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/compat_wrapper.S	2010-02-24 13:52:17.000000000 -0500
@@ -689,8 +689,6 @@ sys32_fdatasync_wrapper:
 	llgfr	%r2,%r2			# unsigned int
 	jg	sys_fdatasync		# branch to system call
 
-#sys32_sysctl_wrapper			# tbd
-
 	.globl	sys32_mlock_wrapper
 sys32_mlock_wrapper:
 	llgfr	%r2,%r2			# unsigned long
@@ -1087,8 +1085,8 @@ sys32_stime_wrapper:
 
 	.globl	sys32_sysctl_wrapper
 sys32_sysctl_wrapper:
-	llgtr	%r2,%r2 		# struct __sysctl_args32 *
-	jg	sys32_sysctl
+	llgtr	%r2,%r2 		# struct compat_sysctl_args *
+	jg	compat_sys_sysctl
 
 	.globl	sys32_fstat64_wrapper
 sys32_fstat64_wrapper:
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/debug.c linux-libre-2.6.33-gnu1/arch/s390/kernel/debug.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/sysctl.h>
 #include <asm/uaccess.h>
 #include <linux/module.h>
@@ -893,35 +894,30 @@ s390dbf_procactive(ctl_table *table, int
 
 static struct ctl_table s390dbf_table[] = {
 	{
-		.ctl_name       = CTL_S390DBF_STOPPABLE,
 		.procname       = "debug_stoppable",
 		.data		= &debug_stoppable,
 		.maxlen		= sizeof(int),
 		.mode           = S_IRUGO | S_IWUSR,
-		.proc_handler   = &proc_dointvec,
-		.strategy	= &sysctl_intvec,
+		.proc_handler   = proc_dointvec,
 	},
 	 {
-		.ctl_name       = CTL_S390DBF_ACTIVE,
 		.procname       = "debug_active",
 		.data		= &debug_active,
 		.maxlen		= sizeof(int),
 		.mode           = S_IRUGO | S_IWUSR,
-		.proc_handler   = &s390dbf_procactive,
-		.strategy	= &sysctl_intvec,
+		.proc_handler   = s390dbf_procactive,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static struct ctl_table s390dbf_dir_table[] = {
 	{
-		.ctl_name       = CTL_S390DBF,
 		.procname       = "s390dbf",
 		.maxlen         = 0,
 		.mode           = S_IRUGO | S_IXUGO,
 		.child          = s390dbf_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static struct ctl_table_header *s390dbf_sysctl_header;
@@ -1183,7 +1179,7 @@ debug_get_uint(char *buf)
 {
 	int rc;
 
-	for(; isspace(*buf); buf++);
+	buf = skip_spaces(buf);
 	rc = simple_strtoul(buf, &buf, 10);
 	if(*buf){
 		rc = -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/entry64.S linux-libre-2.6.33-gnu1/arch/s390/kernel/entry64.S
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/entry64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/entry64.S	2010-02-24 13:52:17.000000000 -0500
@@ -549,6 +549,7 @@ pgm_svcper:
 	mvc	__THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
 	oi	__TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
 	TRACE_IRQS_ON
+	lmg	%r2,%r6,SP_R2(%r15)	# load svc arguments
 	stosm	__SF_EMPTY(%r15),0x03	# reenable interrupts
 	j	sysc_do_svc
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/entry.S linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -571,6 +571,7 @@ pgm_svcper:
 	mvc	__THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
 	oi	__TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
 	TRACE_IRQS_ON
+	lm	%r2,%r6,SP_R2(%r15)	# load svc arguments
 	stosm	__SF_EMPTY(%r15),0x03	# reenable interrupts
 	b	BASED(sysc_do_svc)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/s390/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/ftrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -203,73 +203,10 @@ out:
 
 #ifdef CONFIG_FTRACE_SYSCALLS
 
-extern unsigned long __start_syscalls_metadata[];
-extern unsigned long __stop_syscalls_metadata[];
 extern unsigned int sys_call_table[];
 
-static struct syscall_metadata **syscalls_metadata;
-
-struct syscall_metadata *syscall_nr_to_meta(int nr)
-{
-	if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
-		return NULL;
-
-	return syscalls_metadata[nr];
-}
-
-int syscall_name_to_nr(char *name)
-{
-	int i;
-
-	if (!syscalls_metadata)
-		return -1;
-	for (i = 0; i < NR_syscalls; i++)
-		if (syscalls_metadata[i])
-			if (!strcmp(syscalls_metadata[i]->name, name))
-				return i;
-	return -1;
-}
-
-void set_syscall_enter_id(int num, int id)
-{
-	syscalls_metadata[num]->enter_id = id;
-}
-
-void set_syscall_exit_id(int num, int id)
-{
-	syscalls_metadata[num]->exit_id = id;
-}
-
-static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
-{
-	struct syscall_metadata *start;
-	struct syscall_metadata *stop;
-	char str[KSYM_SYMBOL_LEN];
-
-	start = (struct syscall_metadata *)__start_syscalls_metadata;
-	stop = (struct syscall_metadata *)__stop_syscalls_metadata;
-	kallsyms_lookup(syscall, NULL, NULL, NULL, str);
-
-	for ( ; start < stop; start++) {
-		if (start->name && !strcmp(start->name + 3, str + 3))
-			return start;
-	}
-	return NULL;
-}
-
-static int __init arch_init_ftrace_syscalls(void)
+unsigned long __init arch_syscall_addr(int nr)
 {
-	struct syscall_metadata *meta;
-	int i;
-	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls,
-				    GFP_KERNEL);
-	if (!syscalls_metadata)
-		return -ENOMEM;
-	for (i = 0; i < NR_syscalls; i++) {
-		meta = find_syscall_meta((unsigned long)sys_call_table[i]);
-		syscalls_metadata[i] = meta;
-	}
-	return 0;
+	return (unsigned long)sys_call_table[nr];
 }
-arch_initcall(arch_init_ftrace_syscalls);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/head64.S linux-libre-2.6.33-gnu1/arch/s390/kernel/head64.S
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/head64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/head64.S	2010-02-24 13:52:17.000000000 -0500
@@ -83,6 +83,8 @@ startup_continue:
 	slr	%r0,%r0 		# set cpuid to zero
 	sigp	%r1,%r0,0x12		# switch to esame mode
 	sam64				# switch to 64 bit mode
+	llgfr	%r13,%r13		# clear high-order half of base reg
+	lmh	%r0,%r15,.Lzero64-.LPG1(%r13)	# clear high-order half
 	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers
 	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area
 					# move IPL device to lowcore
@@ -127,6 +129,7 @@ startup_continue:
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad	0x80000000 + 0x20000 - 8	# 2GB + 128K - 8
 .Lnop:	.long	0x07000700
+.Lzero64:.fill	16,4,0x0
 #ifdef CONFIG_ZFCPDUMP
 .Lcurrent_cpu:
 	.long 0x0
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/ipl.c linux-libre-2.6.33-gnu1/arch/s390/kernel/ipl.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/ipl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/ipl.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,7 +221,7 @@ static ssize_t sys_##_prefix##_##_name##
 		const char *buf, size_t len)				\
 {									\
 	strncpy(_value, buf, sizeof(_value) - 1);			\
-	strstrip(_value);						\
+	strim(_value);							\
 	return len;							\
 }									\
 static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
@@ -472,7 +472,7 @@ static ssize_t ipl_ccw_loadparm_show(str
 		return sprintf(page, "#unknown#\n");
 	memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
 	EBCASC(loadparm, LOADPARM_LEN);
-	strstrip(loadparm);
+	strim(loadparm);
 	return sprintf(page, "%s\n", loadparm);
 }
 
@@ -776,7 +776,7 @@ static void reipl_get_ascii_loadparm(cha
 	memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN);
 	EBCASC(loadparm, LOADPARM_LEN);
 	loadparm[LOADPARM_LEN] = 0;
-	strstrip(loadparm);
+	strim(loadparm);
 }
 
 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/Makefile linux-libre-2.6.33-gnu1/arch/s390/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,7 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_FUNCTION_TRACER)	+= $(if $(CONFIG_64BIT),mcount64.o,mcount.o)
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/process.c linux-libre-2.6.33-gnu1/arch/s390/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -153,8 +153,6 @@ void exit_thread(void)
 
 void flush_thread(void)
 {
-	clear_used_math();
-	clear_tsk_thread_flag(current, TIF_USEDFPU);
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -217,6 +215,7 @@ int copy_thread(unsigned long clone_flag
 	p->thread.mm_segment = get_fs();
 	/* Don't copy debug registers */
 	memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
+	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
 	/* Initialize per thread user and system timer values */
 	ti = task_thread_info(p);
 	ti->user_timer = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/ptrace.c linux-libre-2.6.33-gnu1/arch/s390/kernel/ptrace.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/ptrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,6 +65,7 @@ FixPerRegisters(struct task_struct *task
 {
 	struct pt_regs *regs;
 	per_struct *per_info;
+	per_cr_words cr_words;
 
 	regs = task_pt_regs(task);
 	per_info = (per_struct *) &task->thread.per_info;
@@ -98,6 +99,13 @@ FixPerRegisters(struct task_struct *task
 		per_info->control_regs.bits.storage_alt_space_ctl = 1;
 	else
 		per_info->control_regs.bits.storage_alt_space_ctl = 0;
+
+	if (task == current) {
+		__ctl_store(cr_words, 9, 11);
+		if (memcmp(&cr_words, &per_info->control_regs.words,
+			   sizeof(cr_words)) != 0)
+			__ctl_load(per_info->control_regs.words, 9, 11);
+	}
 }
 
 void user_enable_single_step(struct task_struct *task)
@@ -959,7 +967,7 @@ static const struct user_regset s390_com
 		.set = s390_fpregs_set,
 	},
 	[REGSET_GENERAL_EXTENDED] = {
-		.core_note_type = NT_PRXSTATUS,
+		.core_note_type = NT_S390_HIGH_GPRS,
 		.n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
 		.size = sizeof(compat_long_t),
 		.align = sizeof(compat_long_t),
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/s390_ext.c linux-libre-2.6.33-gnu1/arch/s390/kernel/s390_ext.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/s390_ext.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/s390_ext.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,6 +126,8 @@ void __irq_entry do_extint(struct pt_reg
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
 	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
+	if (code != 0x1004)
+		__get_cpu_var(s390_idle).nohz_delay = 1;
         index = ext_hash(code);
 	for (p = ext_int_hash[index]; p; p = p->next) {
 		if (likely(p->code == code))
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/setup.c linux-libre-2.6.33-gnu1/arch/s390/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,6 @@ unsigned long elf_hwcap = 0;
 char elf_platform[ELF_PLATFORM_SIZE];
 
 struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
-volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
 int __initdata memory_end_set;
 unsigned long __initdata memory_end;
@@ -124,12 +123,6 @@ void __cpuinit cpu_init(void)
          */
 	get_cpu_id(&S390_lowcore.cpu_id);
 
-        /*
-         * Force FPU initialization:
-         */
-        clear_thread_flag(TIF_USEDFPU);
-        clear_used_math();
-
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 	BUG_ON(current->mm);
@@ -305,9 +298,8 @@ static int __init early_parse_mem(char *
 }
 early_param("mem", early_parse_mem);
 
-#ifdef CONFIG_S390_SWITCH_AMODE
-unsigned int switch_amode = 0;
-EXPORT_SYMBOL_GPL(switch_amode);
+unsigned int user_mode = HOME_SPACE_MODE;
+EXPORT_SYMBOL_GPL(user_mode);
 
 static int set_amode_and_uaccess(unsigned long user_amode,
 				 unsigned long user32_amode)
@@ -340,23 +332,29 @@ static int set_amode_and_uaccess(unsigne
  */
 static int __init early_parse_switch_amode(char *p)
 {
-	switch_amode = 1;
+	if (user_mode != SECONDARY_SPACE_MODE)
+		user_mode = PRIMARY_SPACE_MODE;
 	return 0;
 }
 early_param("switch_amode", early_parse_switch_amode);
 
-#else /* CONFIG_S390_SWITCH_AMODE */
-static inline int set_amode_and_uaccess(unsigned long user_amode,
-					unsigned long user32_amode)
+static int __init early_parse_user_mode(char *p)
 {
+	if (p && strcmp(p, "primary") == 0)
+		user_mode = PRIMARY_SPACE_MODE;
+#ifdef CONFIG_S390_EXEC_PROTECT
+	else if (p && strcmp(p, "secondary") == 0)
+		user_mode = SECONDARY_SPACE_MODE;
+#endif
+	else if (!p || strcmp(p, "home") == 0)
+		user_mode = HOME_SPACE_MODE;
+	else
+		return 1;
 	return 0;
 }
-#endif /* CONFIG_S390_SWITCH_AMODE */
+early_param("user_mode", early_parse_user_mode);
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-unsigned int s390_noexec = 0;
-EXPORT_SYMBOL_GPL(s390_noexec);
-
 /*
  * Enable execute protection?
  */
@@ -364,8 +362,7 @@ static int __init early_parse_noexec(cha
 {
 	if (!strncmp(p, "off", 3))
 		return 0;
-	switch_amode = 1;
-	s390_noexec = 1;
+	user_mode = SECONDARY_SPACE_MODE;
 	return 0;
 }
 early_param("noexec", early_parse_noexec);
@@ -373,7 +370,7 @@ early_param("noexec", early_parse_noexec
 
 static void setup_addressing_mode(void)
 {
-	if (s390_noexec) {
+	if (user_mode == SECONDARY_SPACE_MODE) {
 		if (set_amode_and_uaccess(PSW_ASC_SECONDARY,
 					  PSW32_ASC_SECONDARY))
 			pr_info("Execute protection active, "
@@ -381,7 +378,7 @@ static void setup_addressing_mode(void)
 		else
 			pr_info("Execute protection active, "
 				"mvcos not available\n");
-	} else if (switch_amode) {
+	} else if (user_mode == PRIMARY_SPACE_MODE) {
 		if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY))
 			pr_info("Address spaces switched, "
 				"mvcos available\n");
@@ -411,7 +408,7 @@ setup_lowcore(void)
 	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
 	lc->restart_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
-	if (switch_amode)
+	if (user_mode != HOME_SPACE_MODE)
 		lc->restart_psw.mask |= PSW_ASC_HOME;
 	lc->external_new_psw.mask = psw_kernel_bits;
 	lc->external_new_psw.addr =
@@ -851,7 +848,6 @@ setup_arch(char **cmdline_p)
 	setup_lowcore();
 
         cpu_init();
-	__cpu_logical_map[0] = stap();
 	s390_init_cpu_topology();
 
 	/*
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/signal.c linux-libre-2.6.33-gnu1/arch/s390/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,7 +64,7 @@ SYSCALL_DEFINE3(sigsuspend, int, history
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	current->state = TASK_INTERRUPTIBLE;
+	set_current_state(TASK_INTERRUPTIBLE);
 	schedule();
 	set_thread_flag(TIF_RESTORE_SIGMASK);
 
@@ -500,18 +500,10 @@ void do_signal(struct pt_regs *regs)
 				clear_thread_flag(TIF_RESTORE_SIGMASK);
 
 			/*
-			 * If we would have taken a single-step trap
-			 * for a normal instruction, act like we took
-			 * one for the handler setup.
-			 */
-			if (current->thread.per_info.single_step)
-				set_thread_flag(TIF_SINGLE_STEP);
-
-			/*
 			 * Let tracing know that we've done the handler setup.
 			 */
 			tracehook_signal_handler(signr, &info, &ka, regs,
-					 test_thread_flag(TIF_SINGLE_STEP));
+					current->thread.per_info.single_step);
 		}
 		return;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/smp.c linux-libre-2.6.33-gnu1/arch/s390/kernel/smp.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,6 +52,9 @@
 #include <asm/cpu.h>
 #include "entry.h"
 
+/* logical cpu to cpu address */
+int __cpu_logical_map[NR_CPUS];
+
 static struct task_struct *current_set[NR_CPUS];
 
 static u8 smp_cpu_type;
@@ -717,6 +720,12 @@ void __init smp_cpus_done(unsigned int m
 {
 }
 
+void __init smp_setup_processor_id(void)
+{
+	S390_lowcore.cpu_nr = 0;
+	__cpu_logical_map[0] = stap();
+}
+
 /*
  * the frequency of the profiling timer can be changed
  * by writing a multiplier value into /proc/profile.
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/sys_s390.c linux-libre-2.6.33-gnu1/arch/s390/kernel/sys_s390.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/sys_s390.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/sys_s390.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,32 +32,6 @@
 #include <asm/uaccess.h>
 #include "entry.h"
 
-/* common code for old and new mmaps */
-static inline long do_mmap2(
-	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags,
-	unsigned long fd, unsigned long pgoff)
-{
-	long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux for S/390 isn't able to handle more than 5
@@ -81,7 +55,7 @@ SYSCALL_DEFINE1(mmap2, struct mmap_arg_s
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		goto out;
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
 out:
 	return error;
 }
@@ -98,7 +72,7 @@ SYSCALL_DEFINE1(s390_old_mmap, struct mm
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+	error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return error;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/time.c linux-libre-2.6.33-gnu1/arch/s390/kernel/time.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,8 @@ struct clocksource * __init clocksource_
 	return &clocksource_tod;
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	if (clock != &clocksource_tod)
 		return;
@@ -334,7 +335,7 @@ int get_sync_clock(unsigned long long *c
 	sw0 = atomic_read(sw_ptr);
 	*clock = get_clock();
 	sw1 = atomic_read(sw_ptr);
-	put_cpu_var(clock_sync_sync);
+	put_cpu_var(clock_sync_word);
 	if (sw0 == sw1 && (sw0 & 0x80000000U))
 		/* Success: time is in sync. */
 		return 0;
@@ -384,7 +385,7 @@ static inline int check_sync_clock(void)
 
 	sw_ptr = &get_cpu_var(clock_sync_word);
 	rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
-	put_cpu_var(clock_sync_sync);
+	put_cpu_var(clock_sync_word);
 	return rc;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/topology.c linux-libre-2.6.33-gnu1/arch/s390/kernel/topology.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/topology.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/topology.c	2010-02-24 13:52:17.000000000 -0500
@@ -114,7 +114,7 @@ static void add_cpus_to_core(struct tl_c
 
 		rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin;
 		for_each_present_cpu(lcpu) {
-			if (__cpu_logical_map[lcpu] == rcpu) {
+			if (cpu_logical_map(lcpu) == rcpu) {
 				cpu_set(lcpu, core->mask);
 				smp_cpu_polarization[lcpu] = tl_cpu->pp;
 			}
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/traps.c linux-libre-2.6.33-gnu1/arch/s390/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -382,7 +382,7 @@ void __kprobes do_single_step(struct pt_
 					SIGTRAP) == NOTIFY_STOP){
 		return;
 	}
-	if ((current->ptrace & PT_PTRACED) != 0)
+	if (tracehook_consider_fatal_signal(current, SIGTRAP))
 		force_sig(SIGTRAP, current);
 }
 
@@ -483,7 +483,7 @@ static void illegal_op(struct pt_regs *
 		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
 			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-			if (current->ptrace & PT_PTRACED)
+			if (tracehook_consider_fatal_signal(current, SIGTRAP))
 				force_sig(SIGTRAP, current);
 			else
 				signal = SIGILL;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/vdso.c linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/vdso.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/vdso.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,7 +86,8 @@ static void vdso_init_data(struct vdso_d
 	unsigned int facility_list;
 
 	facility_list = stfl();
-	vd->ectg_available = switch_amode && (facility_list & 1);
+	vd->ectg_available =
+		user_mode != HOME_SPACE_MODE && (facility_list & 1);
 }
 
 #ifdef CONFIG_64BIT
@@ -114,7 +115,7 @@ int vdso_alloc_per_cpu(int cpu, struct _
 
 	lowcore->vdso_per_cpu_data = __LC_PASTE;
 
-	if (!switch_amode || !vdso_enabled)
+	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return 0;
 
 	segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -160,7 +161,7 @@ void vdso_free_per_cpu(int cpu, struct _
 	unsigned long segment_table, page_table, page_frame;
 	u32 *psal, *aste;
 
-	if (!switch_amode || !vdso_enabled)
+	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return;
 
 	psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -184,7 +185,7 @@ static void __vdso_init_cr5(void *dummy)
 
 static void vdso_init_cr5(void)
 {
-	if (switch_amode && vdso_enabled)
+	if (user_mode != HOME_SPACE_MODE && vdso_enabled)
 		on_each_cpu(__vdso_init_cr5, NULL, 1);
 }
 #endif /* CONFIG_64BIT */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kernel/vtime.c linux-libre-2.6.33-gnu1/arch/s390/kernel/vtime.c
--- linux-libre-2.6.32-gnu1/arch/s390/kernel/vtime.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kernel/vtime.c	2010-02-24 13:52:17.000000000 -0500
@@ -167,6 +167,8 @@ void vtime_stop_cpu(void)
 	/* Wait for external, I/O or machine check interrupt. */
 	psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT;
 
+	idle->nohz_delay = 0;
+
 	/* Check if the CPU timer needs to be reprogrammed. */
 	if (vq->do_spt) {
 		__u64 vmax = VTIMER_MAX_SLICE;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kvm/intercept.c linux-libre-2.6.33-gnu1/arch/s390/kvm/intercept.c
--- linux-libre-2.6.32-gnu1/arch/s390/kvm/intercept.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kvm/intercept.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,7 +213,7 @@ static int handle_instruction_and_prog(s
 	return rc2;
 }
 
-static const intercept_handler_t intercept_funcs[0x48 >> 2] = {
+static const intercept_handler_t intercept_funcs[] = {
 	[0x00 >> 2] = handle_noop,
 	[0x04 >> 2] = handle_instruction,
 	[0x08 >> 2] = handle_prog,
@@ -230,7 +230,7 @@ int kvm_handle_sie_intercept(struct kvm_
 	intercept_handler_t func;
 	u8 code = vcpu->arch.sie_block->icptcode;
 
-	if (code & 3 || code > 0x48)
+	if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs))
 		return -ENOTSUPP;
 	func = intercept_funcs[code >> 2];
 	if (func)
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kvm/Kconfig linux-libre-2.6.33-gnu1/arch/s390/kvm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/s390/kvm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,6 @@ config KVM
 	depends on HAVE_KVM && EXPERIMENTAL
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
-	select S390_SWITCH_AMODE
 	---help---
 	  Support hosting paravirtualized guest machines using the SIE
 	  virtualization capability on the mainframe. This should work
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kvm/kvm-s390.c linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.c
--- linux-libre-2.6.32-gnu1/arch/s390/kvm/kvm-s390.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kvm/kvm-s390.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,9 +74,10 @@ struct kvm_stats_debugfs_item debugfs_en
 static unsigned long long *facilities;
 
 /* Section: not file related */
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
 {
 	/* every s390 is virtualization enabled ;-) */
+	return 0;
 }
 
 void kvm_arch_hardware_disable(void *garbage)
@@ -116,10 +117,16 @@ long kvm_arch_dev_ioctl(struct file *fil
 
 int kvm_dev_ioctl_check_extension(long ext)
 {
+	int r;
+
 	switch (ext) {
+	case KVM_CAP_S390_PSW:
+		r = 1;
+		break;
 	default:
-		return 0;
+		r = 0;
 	}
+	return r;
 }
 
 /* Section: vm related */
@@ -150,7 +157,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 		break;
 	}
 	default:
-		r = -EINVAL;
+		r = -ENOTTY;
 	}
 
 	return r;
@@ -419,8 +426,10 @@ static int kvm_arch_vcpu_ioctl_set_initi
 	vcpu_load(vcpu);
 	if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
 		rc = -EBUSY;
-	else
-		vcpu->arch.sie_block->gpsw = psw;
+	else {
+		vcpu->run->psw_mask = psw.mask;
+		vcpu->run->psw_addr = psw.addr;
+	}
 	vcpu_put(vcpu);
 	return rc;
 }
@@ -508,9 +517,6 @@ rerun_vcpu:
 
 	switch (kvm_run->exit_reason) {
 	case KVM_EXIT_S390_SIEIC:
-		vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
-		vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
-		break;
 	case KVM_EXIT_UNKNOWN:
 	case KVM_EXIT_INTR:
 	case KVM_EXIT_S390_RESET:
@@ -519,6 +525,9 @@ rerun_vcpu:
 		BUG();
 	}
 
+	vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
+	vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
+
 	might_fault();
 
 	do {
@@ -538,8 +547,6 @@ rerun_vcpu:
 		/* intercept cannot be handled in-kernel, prepare kvm-run */
 		kvm_run->exit_reason         = KVM_EXIT_S390_SIEIC;
 		kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
-		kvm_run->s390_sieic.mask     = vcpu->arch.sie_block->gpsw.mask;
-		kvm_run->s390_sieic.addr     = vcpu->arch.sie_block->gpsw.addr;
 		kvm_run->s390_sieic.ipa      = vcpu->arch.sie_block->ipa;
 		kvm_run->s390_sieic.ipb      = vcpu->arch.sie_block->ipb;
 		rc = 0;
@@ -551,6 +558,9 @@ rerun_vcpu:
 		rc = 0;
 	}
 
+	kvm_run->psw_mask     = vcpu->arch.sie_block->gpsw.mask;
+	kvm_run->psw_addr     = vcpu->arch.sie_block->gpsw.addr;
+
 	if (vcpu->sigset_active)
 		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/kvm/sigp.c linux-libre-2.6.33-gnu1/arch/s390/kvm/sigp.c
--- linux-libre-2.6.32-gnu1/arch/s390/kvm/sigp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/kvm/sigp.c	2010-02-24 13:52:17.000000000 -0500
@@ -188,9 +188,9 @@ static int __sigp_set_prefix(struct kvm_
 
 	/* make sure that the new value is valid memory */
 	address = address & 0x7fffe000u;
-	if ((copy_from_guest(vcpu, &tmp,
-		(u64) (address + vcpu->arch.sie_block->gmsor) , 1)) ||
-	   (copy_from_guest(vcpu, &tmp, (u64) (address +
+	if ((copy_from_user(&tmp, (void __user *)
+		(address + vcpu->arch.sie_block->gmsor) , 1)) ||
+	   (copy_from_user(&tmp, (void __user *)(address +
 			vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) {
 		*reg |= SIGP_STAT_INVALID_PARAMETER;
 		return 1; /* invalid parameter */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/lib/spinlock.c linux-libre-2.6.33-gnu1/arch/s390/lib/spinlock.c
--- linux-libre-2.6.32-gnu1/arch/s390/lib/spinlock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/lib/spinlock.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,12 +34,12 @@ static inline void _raw_yield_cpu(int cp
 {
 	if (MACHINE_HAS_DIAG9C)
 		asm volatile("diag %0,0,0x9c"
-			     : : "d" (__cpu_logical_map[cpu]));
+			     : : "d" (cpu_logical_map(cpu)));
 	else
 		_raw_yield();
 }
 
-void _raw_spin_lock_wait(raw_spinlock_t *lp)
+void arch_spin_lock_wait(arch_spinlock_t *lp)
 {
 	int count = spin_retry;
 	unsigned int cpu = ~smp_processor_id();
@@ -51,15 +51,15 @@ void _raw_spin_lock_wait(raw_spinlock_t
 				_raw_yield_cpu(~owner);
 			count = spin_retry;
 		}
-		if (__raw_spin_is_locked(lp))
+		if (arch_spin_is_locked(lp))
 			continue;
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return;
 	}
 }
-EXPORT_SYMBOL(_raw_spin_lock_wait);
+EXPORT_SYMBOL(arch_spin_lock_wait);
 
-void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags)
+void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
 {
 	int count = spin_retry;
 	unsigned int cpu = ~smp_processor_id();
@@ -72,7 +72,7 @@ void _raw_spin_lock_wait_flags(raw_spinl
 				_raw_yield_cpu(~owner);
 			count = spin_retry;
 		}
-		if (__raw_spin_is_locked(lp))
+		if (arch_spin_is_locked(lp))
 			continue;
 		local_irq_disable();
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
@@ -80,32 +80,32 @@ void _raw_spin_lock_wait_flags(raw_spinl
 		local_irq_restore(flags);
 	}
 }
-EXPORT_SYMBOL(_raw_spin_lock_wait_flags);
+EXPORT_SYMBOL(arch_spin_lock_wait_flags);
 
-int _raw_spin_trylock_retry(raw_spinlock_t *lp)
+int arch_spin_trylock_retry(arch_spinlock_t *lp)
 {
 	unsigned int cpu = ~smp_processor_id();
 	int count;
 
 	for (count = spin_retry; count > 0; count--) {
-		if (__raw_spin_is_locked(lp))
+		if (arch_spin_is_locked(lp))
 			continue;
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return 1;
 	}
 	return 0;
 }
-EXPORT_SYMBOL(_raw_spin_trylock_retry);
+EXPORT_SYMBOL(arch_spin_trylock_retry);
 
-void _raw_spin_relax(raw_spinlock_t *lock)
+void arch_spin_relax(arch_spinlock_t *lock)
 {
 	unsigned int cpu = lock->owner_cpu;
 	if (cpu != 0)
 		_raw_yield_cpu(~cpu);
 }
-EXPORT_SYMBOL(_raw_spin_relax);
+EXPORT_SYMBOL(arch_spin_relax);
 
-void _raw_read_lock_wait(raw_rwlock_t *rw)
+void _raw_read_lock_wait(arch_rwlock_t *rw)
 {
 	unsigned int old;
 	int count = spin_retry;
@@ -115,7 +115,7 @@ void _raw_read_lock_wait(raw_rwlock_t *r
 			_raw_yield();
 			count = spin_retry;
 		}
-		if (!__raw_read_can_lock(rw))
+		if (!arch_read_can_lock(rw))
 			continue;
 		old = rw->lock & 0x7fffffffU;
 		if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
@@ -124,7 +124,7 @@ void _raw_read_lock_wait(raw_rwlock_t *r
 }
 EXPORT_SYMBOL(_raw_read_lock_wait);
 
-void _raw_read_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags)
+void _raw_read_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags)
 {
 	unsigned int old;
 	int count = spin_retry;
@@ -135,7 +135,7 @@ void _raw_read_lock_wait_flags(raw_rwloc
 			_raw_yield();
 			count = spin_retry;
 		}
-		if (!__raw_read_can_lock(rw))
+		if (!arch_read_can_lock(rw))
 			continue;
 		old = rw->lock & 0x7fffffffU;
 		local_irq_disable();
@@ -145,13 +145,13 @@ void _raw_read_lock_wait_flags(raw_rwloc
 }
 EXPORT_SYMBOL(_raw_read_lock_wait_flags);
 
-int _raw_read_trylock_retry(raw_rwlock_t *rw)
+int _raw_read_trylock_retry(arch_rwlock_t *rw)
 {
 	unsigned int old;
 	int count = spin_retry;
 
 	while (count-- > 0) {
-		if (!__raw_read_can_lock(rw))
+		if (!arch_read_can_lock(rw))
 			continue;
 		old = rw->lock & 0x7fffffffU;
 		if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
@@ -161,7 +161,7 @@ int _raw_read_trylock_retry(raw_rwlock_t
 }
 EXPORT_SYMBOL(_raw_read_trylock_retry);
 
-void _raw_write_lock_wait(raw_rwlock_t *rw)
+void _raw_write_lock_wait(arch_rwlock_t *rw)
 {
 	int count = spin_retry;
 
@@ -170,7 +170,7 @@ void _raw_write_lock_wait(raw_rwlock_t *
 			_raw_yield();
 			count = spin_retry;
 		}
-		if (!__raw_write_can_lock(rw))
+		if (!arch_write_can_lock(rw))
 			continue;
 		if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
 			return;
@@ -178,7 +178,7 @@ void _raw_write_lock_wait(raw_rwlock_t *
 }
 EXPORT_SYMBOL(_raw_write_lock_wait);
 
-void _raw_write_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags)
+void _raw_write_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags)
 {
 	int count = spin_retry;
 
@@ -188,7 +188,7 @@ void _raw_write_lock_wait_flags(raw_rwlo
 			_raw_yield();
 			count = spin_retry;
 		}
-		if (!__raw_write_can_lock(rw))
+		if (!arch_write_can_lock(rw))
 			continue;
 		local_irq_disable();
 		if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
@@ -197,12 +197,12 @@ void _raw_write_lock_wait_flags(raw_rwlo
 }
 EXPORT_SYMBOL(_raw_write_lock_wait_flags);
 
-int _raw_write_trylock_retry(raw_rwlock_t *rw)
+int _raw_write_trylock_retry(arch_rwlock_t *rw)
 {
 	int count = spin_retry;
 
 	while (count-- > 0) {
-		if (!__raw_write_can_lock(rw))
+		if (!arch_write_can_lock(rw))
 			continue;
 		if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
 			return 1;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/lib/uaccess_mvcos.c linux-libre-2.6.33-gnu1/arch/s390/lib/uaccess_mvcos.c
--- linux-libre-2.6.32-gnu1/arch/s390/lib/uaccess_mvcos.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/lib/uaccess_mvcos.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,7 +162,6 @@ static size_t clear_user_mvcos(size_t si
 	return size;
 }
 
-#ifdef CONFIG_S390_SWITCH_AMODE
 static size_t strnlen_user_mvcos(size_t count, const char __user *src)
 {
 	char buf[256];
@@ -200,7 +199,6 @@ static size_t strncpy_from_user_mvcos(si
 	} while ((len_str == len) && (done < count));
 	return done;
 }
-#endif /* CONFIG_S390_SWITCH_AMODE */
 
 struct uaccess_ops uaccess_mvcos = {
 	.copy_from_user = copy_from_user_mvcos_check,
@@ -215,7 +213,6 @@ struct uaccess_ops uaccess_mvcos = {
 	.futex_atomic_cmpxchg = futex_atomic_cmpxchg_std,
 };
 
-#ifdef CONFIG_S390_SWITCH_AMODE
 struct uaccess_ops uaccess_mvcos_switch = {
 	.copy_from_user = copy_from_user_mvcos,
 	.copy_from_user_small = copy_from_user_mvcos,
@@ -228,4 +225,3 @@ struct uaccess_ops uaccess_mvcos_switch
 	.futex_atomic_op = futex_atomic_op_pt,
 	.futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt,
 };
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/lib/uaccess_pt.c linux-libre-2.6.33-gnu1/arch/s390/lib/uaccess_pt.c
--- linux-libre-2.6.32-gnu1/arch/s390/lib/uaccess_pt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/lib/uaccess_pt.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,86 +23,21 @@ static inline pte_t *follow_table(struct
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-		return NULL;
+		return (pte_t *) 0x3a;
 
 	pud = pud_offset(pgd, addr);
 	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-		return NULL;
+		return (pte_t *) 0x3b;
 
 	pmd = pmd_offset(pud, addr);
 	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-		return NULL;
+		return (pte_t *) 0x10;
 
 	return pte_offset_map(pmd, addr);
 }
 
-static int __handle_fault(struct mm_struct *mm, unsigned long address,
-			  int write_access)
-{
-	struct vm_area_struct *vma;
-	int ret = -EFAULT;
-	int fault;
-
-	if (in_atomic())
-		return ret;
-	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, address);
-	if (unlikely(!vma))
-		goto out;
-	if (unlikely(vma->vm_start > address)) {
-		if (!(vma->vm_flags & VM_GROWSDOWN))
-			goto out;
-		if (expand_stack(vma, address))
-			goto out;
-	}
-
-	if (!write_access) {
-		/* page not present, check vm flags */
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-			goto out;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto out;
-	}
-
-survive:
-	fault = handle_mm_fault(mm, vma, address, write_access ? FAULT_FLAG_WRITE : 0);
-	if (unlikely(fault & VM_FAULT_ERROR)) {
-		if (fault & VM_FAULT_OOM)
-			goto out_of_memory;
-		else if (fault & VM_FAULT_SIGBUS)
-			goto out_sigbus;
-		BUG();
-	}
-	if (fault & VM_FAULT_MAJOR)
-		current->maj_flt++;
-	else
-		current->min_flt++;
-	ret = 0;
-out:
-	up_read(&mm->mmap_sem);
-	return ret;
-
-out_of_memory:
-	up_read(&mm->mmap_sem);
-	if (is_global_init(current)) {
-		yield();
-		down_read(&mm->mmap_sem);
-		goto survive;
-	}
-	printk("VM: killing process %s\n", current->comm);
-	return ret;
-
-out_sigbus:
-	up_read(&mm->mmap_sem);
-	current->thread.prot_addr = address;
-	current->thread.trap_no = 0x11;
-	force_sig(SIGBUS, current);
-	return ret;
-}
-
-static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
-			     size_t n, int write_user)
+static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
+					     size_t n, int write_user)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long offset, pfn, done, size;
@@ -114,12 +49,17 @@ retry:
 	spin_lock(&mm->page_table_lock);
 	do {
 		pte = follow_table(mm, uaddr);
-		if (!pte || !pte_present(*pte) ||
-		    (write_user && !pte_write(*pte)))
+		if ((unsigned long) pte < 0x1000)
+			goto fault;
+		if (!pte_present(*pte)) {
+			pte = (pte_t *) 0x11;
+			goto fault;
+		} else if (write_user && !pte_write(*pte)) {
+			pte = (pte_t *) 0x04;
 			goto fault;
+		}
 
 		pfn = pte_pfn(*pte);
-
 		offset = uaddr & (PAGE_SIZE - 1);
 		size = min(n - done, PAGE_SIZE - offset);
 		if (write_user) {
@@ -137,7 +77,7 @@ retry:
 	return n - done;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, write_user))
+	if (__handle_fault(uaddr, (unsigned long) pte, write_user))
 		return n - done;
 	goto retry;
 }
@@ -146,30 +86,31 @@ fault:
  * Do DAT for user address by page table walk, return kernel address.
  * This function needs to be called with current->mm->page_table_lock held.
  */
-static unsigned long __dat_user_addr(unsigned long uaddr)
+static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long pfn, ret;
+	unsigned long pfn;
 	pte_t *pte;
 	int rc;
 
-	ret = 0;
 retry:
 	pte = follow_table(mm, uaddr);
-	if (!pte || !pte_present(*pte))
+	if ((unsigned long) pte < 0x1000)
+		goto fault;
+	if (!pte_present(*pte)) {
+		pte = (pte_t *) 0x11;
 		goto fault;
+	}
 
 	pfn = pte_pfn(*pte);
-	ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
-out:
-	return ret;
+	return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
 fault:
 	spin_unlock(&mm->page_table_lock);
-	rc = __handle_fault(mm, uaddr, 0);
+	rc = __handle_fault(uaddr, (unsigned long) pte, 0);
 	spin_lock(&mm->page_table_lock);
-	if (rc)
-		goto out;
-	goto retry;
+	if (!rc)
+		goto retry;
+	return 0;
 }
 
 size_t copy_from_user_pt(size_t n, const void __user *from, void *to)
@@ -234,8 +175,12 @@ retry:
 	spin_lock(&mm->page_table_lock);
 	do {
 		pte = follow_table(mm, uaddr);
-		if (!pte || !pte_present(*pte))
+		if ((unsigned long) pte < 0x1000)
+			goto fault;
+		if (!pte_present(*pte)) {
+			pte = (pte_t *) 0x11;
 			goto fault;
+		}
 
 		pfn = pte_pfn(*pte);
 		offset = uaddr & (PAGE_SIZE-1);
@@ -249,9 +194,8 @@ retry:
 	return done + 1;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, 0)) {
+	if (__handle_fault(uaddr, (unsigned long) pte, 0))
 		return 0;
-	}
 	goto retry;
 }
 
@@ -284,7 +228,7 @@ static size_t copy_in_user_pt(size_t n,
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
-		      uaddr, done, size;
+		      uaddr, done, size, error_code;
 	unsigned long uaddr_from = (unsigned long) from;
 	unsigned long uaddr_to = (unsigned long) to;
 	pte_t *pte_from, *pte_to;
@@ -298,17 +242,28 @@ static size_t copy_in_user_pt(size_t n,
 retry:
 	spin_lock(&mm->page_table_lock);
 	do {
+		write_user = 0;
+		uaddr = uaddr_from;
 		pte_from = follow_table(mm, uaddr_from);
-		if (!pte_from || !pte_present(*pte_from)) {
-			uaddr = uaddr_from;
-			write_user = 0;
+		error_code = (unsigned long) pte_from;
+		if (error_code < 0x1000)
+			goto fault;
+		if (!pte_present(*pte_from)) {
+			error_code = 0x11;
 			goto fault;
 		}
 
+		write_user = 1;
+		uaddr = uaddr_to;
 		pte_to = follow_table(mm, uaddr_to);
-		if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
-			uaddr = uaddr_to;
-			write_user = 1;
+		error_code = (unsigned long) pte_to;
+		if (error_code < 0x1000)
+			goto fault;
+		if (!pte_present(*pte_to)) {
+			error_code = 0x11;
+			goto fault;
+		} else if (!pte_write(*pte_to)) {
+			error_code = 0x04;
 			goto fault;
 		}
 
@@ -329,7 +284,7 @@ retry:
 	return n - done;
 fault:
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(mm, uaddr, write_user))
+	if (__handle_fault(uaddr, error_code, write_user))
 		return n - done;
 	goto retry;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/math-emu/math.c linux-libre-2.6.33-gnu1/arch/s390/math-emu/math.c
--- linux-libre-2.6.32-gnu1/arch/s390/math-emu/math.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/math-emu/math.c	2010-02-24 13:52:17.000000000 -0500
@@ -2088,7 +2088,7 @@ int math_emu_ldr(__u8 *opcode) {
         __u16 opc = *((__u16 *) opcode);
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
+                /* we got an exception therefore ry can't be in {0,2,4,6} */
 		asm volatile(		/* load rx from fp_regs.fprs[ry] */
 			"	bras	1,0f\n"
 			"	ld	0,0(%1)\n"
@@ -2118,7 +2118,7 @@ int math_emu_ler(__u8 *opcode) {
         __u16 opc = *((__u16 *) opcode);
 
         if ((opc & 0x90) == 0) {           /* test if rx in {0,2,4,6} */
-                /* we got an exception therfore ry can't be in {0,2,4,6} */
+                /* we got an exception therefore ry can't be in {0,2,4,6} */
 		asm volatile(		/* load rx from fp_regs.fprs[ry] */
 			"	bras	1,0f\n"
 			"	le	0,0(%1)\n"
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/mm/cmm.c linux-libre-2.6.33-gnu1/arch/s390/mm/cmm.c
--- linux-libre-2.6.32-gnu1/arch/s390/mm/cmm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/mm/cmm.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/swap.h>
 #include <linux/kthread.h>
 #include <linux/oom.h>
+#include <linux/suspend.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -44,6 +45,7 @@ static volatile long cmm_pages_target;
 static volatile long cmm_timed_pages_target;
 static long cmm_timeout_pages;
 static long cmm_timeout_seconds;
+static int cmm_suspended;
 
 static struct cmm_page_array *cmm_page_list;
 static struct cmm_page_array *cmm_timed_page_list;
@@ -147,9 +149,9 @@ cmm_thread(void *dummy)
 
 	while (1) {
 		rc = wait_event_interruptible(cmm_thread_wait,
-			(cmm_pages != cmm_pages_target ||
-			 cmm_timed_pages != cmm_timed_pages_target ||
-			 kthread_should_stop()));
+			(!cmm_suspended && (cmm_pages != cmm_pages_target ||
+			 cmm_timed_pages != cmm_timed_pages_target)) ||
+			 kthread_should_stop());
 		if (kthread_should_stop() || rc == -ERESTARTSYS) {
 			cmm_pages_target = cmm_pages;
 			cmm_timed_pages_target = cmm_timed_pages;
@@ -343,30 +345,29 @@ static struct ctl_table cmm_table[] = {
 	{
 		.procname	= "cmm_pages",
 		.mode		= 0644,
-		.proc_handler	= &cmm_pages_handler,
+		.proc_handler	= cmm_pages_handler,
 	},
 	{
 		.procname	= "cmm_timed_pages",
 		.mode		= 0644,
-		.proc_handler	= &cmm_pages_handler,
+		.proc_handler	= cmm_pages_handler,
 	},
 	{
 		.procname	= "cmm_timeout",
 		.mode		= 0644,
-		.proc_handler	= &cmm_timeout_handler,
+		.proc_handler	= cmm_timeout_handler,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static struct ctl_table cmm_dir_table[] = {
 	{
-		.ctl_name	= CTL_VM,
 		.procname	= "vm",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= cmm_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 #endif
 
@@ -411,6 +412,38 @@ cmm_smsg_target(char *from, char *msg)
 
 static struct ctl_table_header *cmm_sysctl_header;
 
+static int cmm_suspend(void)
+{
+	cmm_suspended = 1;
+	cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
+	cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
+	return 0;
+}
+
+static int cmm_resume(void)
+{
+	cmm_suspended = 0;
+	cmm_kick_thread();
+	return 0;
+}
+
+static int cmm_power_event(struct notifier_block *this,
+			   unsigned long event, void *ptr)
+{
+	switch (event) {
+	case PM_POST_HIBERNATION:
+		return cmm_resume();
+	case PM_HIBERNATION_PREPARE:
+		return cmm_suspend();
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static struct notifier_block cmm_power_notifier = {
+	.notifier_call = cmm_power_event,
+};
+
 static int
 cmm_init (void)
 {
@@ -419,7 +452,7 @@ cmm_init (void)
 #ifdef CONFIG_CMM_PROC
 	cmm_sysctl_header = register_sysctl_table(cmm_dir_table);
 	if (!cmm_sysctl_header)
-		goto out;
+		goto out_sysctl;
 #endif
 #ifdef CONFIG_CMM_IUCV
 	rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
@@ -429,17 +462,21 @@ cmm_init (void)
 	rc = register_oom_notifier(&cmm_oom_nb);
 	if (rc < 0)
 		goto out_oom_notify;
+	rc = register_pm_notifier(&cmm_power_notifier);
+	if (rc)
+		goto out_pm;
 	init_waitqueue_head(&cmm_thread_wait);
 	init_timer(&cmm_timer);
 	cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
 	rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0;
-	if (!rc)
-		goto out;
-	/*
-	 * kthread_create failed. undo all the stuff from above again.
-	 */
-	unregister_oom_notifier(&cmm_oom_nb);
+	if (rc)
+		goto out_kthread;
+	return 0;
 
+out_kthread:
+	unregister_pm_notifier(&cmm_power_notifier);
+out_pm:
+	unregister_oom_notifier(&cmm_oom_nb);
 out_oom_notify:
 #ifdef CONFIG_CMM_IUCV
 	smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
@@ -447,8 +484,8 @@ out_smsg:
 #endif
 #ifdef CONFIG_CMM_PROC
 	unregister_sysctl_table(cmm_sysctl_header);
+out_sysctl:
 #endif
-out:
 	return rc;
 }
 
@@ -456,6 +493,7 @@ static void
 cmm_exit(void)
 {
 	kthread_stop(cmm_thread_ptr);
+	unregister_pm_notifier(&cmm_power_notifier);
 	unregister_oom_notifier(&cmm_oom_nb);
 	cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
 	cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/mm/fault.c linux-libre-2.6.33-gnu1/arch/s390/mm/fault.c
--- linux-libre-2.6.32-gnu1/arch/s390/mm/fault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,16 +34,15 @@
 #include <asm/pgtable.h>
 #include <asm/s390_ext.h>
 #include <asm/mmu_context.h>
+#include <asm/compat.h>
 #include "../kernel/entry.h"
 
 #ifndef CONFIG_64BIT
 #define __FAIL_ADDR_MASK 0x7ffff000
-#define __FIXUP_MASK 0x7fffffff
 #define __SUBCODE_MASK 0x0200
 #define __PF_RES_FIELD 0ULL
 #else /* CONFIG_64BIT */
 #define __FAIL_ADDR_MASK -4096L
-#define __FIXUP_MASK ~0L
 #define __SUBCODE_MASK 0x0600
 #define __PF_RES_FIELD 0x8000000000000000ULL
 #endif /* CONFIG_64BIT */
@@ -52,11 +51,15 @@
 extern int sysctl_userprocess_debug;
 #endif
 
-#ifdef CONFIG_KPROBES
-static inline int notify_page_fault(struct pt_regs *regs, long err)
+#define VM_FAULT_BADCONTEXT	0x010000
+#define VM_FAULT_BADMAP		0x020000
+#define VM_FAULT_BADACCESS	0x040000
+
+static inline int notify_page_fault(struct pt_regs *regs)
 {
 	int ret = 0;
 
+#ifdef CONFIG_KPROBES
 	/* kprobe_running() needs smp_processor_id() */
 	if (!user_mode(regs)) {
 		preempt_disable();
@@ -64,15 +67,9 @@ static inline int notify_page_fault(stru
 			ret = 1;
 		preempt_enable();
 	}
-
+#endif
 	return ret;
 }
-#else
-static inline int notify_page_fault(struct pt_regs *regs, long err)
-{
-	return 0;
-}
-#endif
 
 
 /*
@@ -100,57 +97,50 @@ void bust_spinlocks(int yes)
 
 /*
  * Returns the address space associated with the fault.
- * Returns 0 for kernel space, 1 for user space and
- * 2 for code execution in user space with noexec=on.
+ * Returns 0 for kernel space and 1 for user space.
  */
-static inline int check_space(struct task_struct *tsk)
+static inline int user_space_fault(unsigned long trans_exc_code)
 {
 	/*
-	 * The lowest two bits of S390_lowcore.trans_exc_code
-	 * indicate which paging table was used.
+	 * The lowest two bits of the translation exception
+	 * identification indicate which paging table was used.
 	 */
-	int desc = S390_lowcore.trans_exc_code & 3;
-
-	if (desc == 3)	/* Home Segment Table Descriptor */
-		return switch_amode == 0;
-	if (desc == 2)	/* Secondary Segment Table Descriptor */
-		return tsk->thread.mm_segment.ar4;
-#ifdef CONFIG_S390_SWITCH_AMODE
-	if (unlikely(desc == 1)) { /* STD determined via access register */
-		/* %a0 always indicates primary space. */
-		if (S390_lowcore.exc_access_id != 0) {
-			save_access_regs(tsk->thread.acrs);
-			/*
-			 * An alet of 0 indicates primary space.
-			 * An alet of 1 indicates secondary space.
-			 * Any other alet values generate an
-			 * alen-translation exception.
-			 */
-			if (tsk->thread.acrs[S390_lowcore.exc_access_id])
-				return tsk->thread.mm_segment.ar4;
-		}
-	}
-#endif
-	/* Primary Segment Table Descriptor */
-	return switch_amode << s390_noexec;
+	trans_exc_code &= 3;
+	if (trans_exc_code == 2)
+		/* Access via secondary space, set_fs setting decides */
+		return current->thread.mm_segment.ar4;
+	if (user_mode == HOME_SPACE_MODE)
+		/* User space if the access has been done via home space. */
+		return trans_exc_code == 3;
+	/*
+	 * If the user space is not the home space the kernel runs in home
+	 * space. Access via secondary space has already been covered,
+	 * access via primary space or access register is from user space
+	 * and access via home space is from the kernel.
+	 */
+	return trans_exc_code != 3;
 }
 
 /*
  * Send SIGSEGV to task.  This is an external routine
  * to keep the stack usage of do_page_fault small.
  */
-static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
-		       int si_code, unsigned long address)
+static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
+				int si_code, unsigned long trans_exc_code)
 {
 	struct siginfo si;
+	unsigned long address;
 
+	address = trans_exc_code & __FAIL_ADDR_MASK;
+	current->thread.prot_addr = address;
+	current->thread.trap_no = int_code;
 #if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
 #if defined(CONFIG_SYSCTL)
 	if (sysctl_userprocess_debug)
 #endif
 	{
 		printk("User process fault: interruption code 0x%lX\n",
-		       error_code);
+		       int_code);
 		printk("failing address: %lX\n", address);
 		show_regs(regs);
 	}
@@ -161,13 +151,14 @@ static void do_sigsegv(struct pt_regs *r
 	force_sig_info(SIGSEGV, &si, current);
 }
 
-static void do_no_context(struct pt_regs *regs, unsigned long error_code,
-			  unsigned long address)
+static noinline void do_no_context(struct pt_regs *regs, long int_code,
+				   unsigned long trans_exc_code)
 {
 	const struct exception_table_entry *fixup;
+	unsigned long address;
 
 	/* Are we prepared to handle this kernel fault?  */
-	fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK);
+	fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
 	if (fixup) {
 		regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE;
 		return;
@@ -177,129 +168,149 @@ static void do_no_context(struct pt_regs
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice.
 	 */
-	if (check_space(current) == 0)
+	address = trans_exc_code & __FAIL_ADDR_MASK;
+	if (!user_space_fault(trans_exc_code))
 		printk(KERN_ALERT "Unable to handle kernel pointer dereference"
 		       " at virtual kernel address %p\n", (void *)address);
 	else
 		printk(KERN_ALERT "Unable to handle kernel paging request"
 		       " at virtual user address %p\n", (void *)address);
 
-	die("Oops", regs, error_code);
+	die("Oops", regs, int_code);
 	do_exit(SIGKILL);
 }
 
-static void do_low_address(struct pt_regs *regs, unsigned long error_code)
+static noinline void do_low_address(struct pt_regs *regs, long int_code,
+				    unsigned long trans_exc_code)
 {
 	/* Low-address protection hit in kernel mode means
 	   NULL pointer write access in kernel mode.  */
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
 		/* Low-address protection hit in user mode 'cannot happen'. */
-		die ("Low-address protection", regs, error_code);
+		die ("Low-address protection", regs, int_code);
 		do_exit(SIGKILL);
 	}
 
-	do_no_context(regs, error_code, 0);
+	do_no_context(regs, int_code, trans_exc_code);
 }
 
-static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
-		      unsigned long address)
+static noinline void do_sigbus(struct pt_regs *regs, long int_code,
+			       unsigned long trans_exc_code)
 {
 	struct task_struct *tsk = current;
-	struct mm_struct *mm = tsk->mm;
 
-	up_read(&mm->mmap_sem);
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	tsk->thread.prot_addr = address;
-	tsk->thread.trap_no = error_code;
+	tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK;
+	tsk->thread.trap_no = int_code;
 	force_sig(SIGBUS, tsk);
-
-	/* Kernel mode? Handle exceptions or die */
-	if (!(regs->psw.mask & PSW_MASK_PSTATE))
-		do_no_context(regs, error_code, address);
 }
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
-			 unsigned long address, unsigned long error_code)
+static noinline int signal_return(struct pt_regs *regs, long int_code,
+				  unsigned long trans_exc_code)
 {
 	u16 instruction;
 	int rc;
-#ifdef CONFIG_COMPAT
-	int compat;
-#endif
 
-	pagefault_disable();
 	rc = __get_user(instruction, (u16 __user *) regs->psw.addr);
-	pagefault_enable();
-	if (rc)
-		return -EFAULT;
 
-	up_read(&mm->mmap_sem);
-	clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
-#ifdef CONFIG_COMPAT
-	compat = is_compat_task();
-	if (compat && instruction == 0x0a77)
-		sys32_sigreturn();
-	else if (compat && instruction == 0x0aad)
-		sys32_rt_sigreturn();
-	else
-#endif
-	if (instruction == 0x0a77)
-		sys_sigreturn();
-	else if (instruction == 0x0aad)
-		sys_rt_sigreturn();
-	else {
-		current->thread.prot_addr = address;
-		current->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, SEGV_MAPERR, address);
-	}
+	if (!rc && instruction == 0x0a77) {
+		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+		if (is_compat_task())
+			sys32_sigreturn();
+		else
+			sys_sigreturn();
+	} else if (!rc && instruction == 0x0aad) {
+		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
+		if (is_compat_task())
+			sys32_rt_sigreturn();
+		else
+			sys_rt_sigreturn();
+	} else
+		do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
 	return 0;
 }
 #endif /* CONFIG_S390_EXEC_PROTECT */
 
+static noinline void do_fault_error(struct pt_regs *regs, long int_code,
+				    unsigned long trans_exc_code, int fault)
+{
+	int si_code;
+
+	switch (fault) {
+	case VM_FAULT_BADACCESS:
+#ifdef CONFIG_S390_EXEC_PROTECT
+		if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
+		    (trans_exc_code & 3) == 0) {
+			signal_return(regs, int_code, trans_exc_code);
+			break;
+		}
+#endif /* CONFIG_S390_EXEC_PROTECT */
+	case VM_FAULT_BADMAP:
+		/* Bad memory access. Check if it is kernel or user space. */
+		if (regs->psw.mask & PSW_MASK_PSTATE) {
+			/* User mode accesses just cause a SIGSEGV */
+			si_code = (fault == VM_FAULT_BADMAP) ?
+				SEGV_MAPERR : SEGV_ACCERR;
+			do_sigsegv(regs, int_code, si_code, trans_exc_code);
+			return;
+		}
+	case VM_FAULT_BADCONTEXT:
+		do_no_context(regs, int_code, trans_exc_code);
+		break;
+	default: /* fault & VM_FAULT_ERROR */
+		if (fault & VM_FAULT_OOM)
+			pagefault_out_of_memory();
+		else if (fault & VM_FAULT_SIGBUS) {
+			do_sigbus(regs, int_code, trans_exc_code);
+			/* Kernel mode? Handle exceptions or die */
+			if (!(regs->psw.mask & PSW_MASK_PSTATE))
+				do_no_context(regs, int_code, trans_exc_code);
+		} else
+			BUG();
+		break;
+	}
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  *
- * error_code:
+ * interruption code (int_code):
  *   04       Protection           ->  Write-Protection  (suprression)
  *   10       Segment translation  ->  Not present       (nullification)
  *   11       Page translation     ->  Not present       (nullification)
  *   3b       Region third trans.  ->  Not present       (nullification)
  */
-static inline void
-do_exception(struct pt_regs *regs, unsigned long error_code, int write)
+static inline int do_exception(struct pt_regs *regs, int access,
+			       unsigned long trans_exc_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	unsigned long address;
-	int space;
-	int si_code;
 	int fault;
 
-	if (notify_page_fault(regs, error_code))
-		return;
+	if (notify_page_fault(regs))
+		return 0;
 
 	tsk = current;
 	mm = tsk->mm;
 
-	/* get the failing address and the affected space */
-	address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
-	space = check_space(tsk);
-
 	/*
 	 * Verify that the fault happened in user space, that
 	 * we are not in an interrupt and that there is a 
 	 * user context.
 	 */
-	if (unlikely(space == 0 || in_atomic() || !mm))
-		goto no_context;
+	fault = VM_FAULT_BADCONTEXT;
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
+		goto out;
 
+	address = trans_exc_code & __FAIL_ADDR_MASK;
 	/*
 	 * When we get here, the fault happened in the current
 	 * task's user address space, so we can switch on the
@@ -309,42 +320,26 @@ do_exception(struct pt_regs *regs, unsig
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 	down_read(&mm->mmap_sem);
 
-	si_code = SEGV_MAPERR;
+	fault = VM_FAULT_BADMAP;
 	vma = find_vma(mm, address);
 	if (!vma)
-		goto bad_area;
-
-#ifdef CONFIG_S390_EXEC_PROTECT
-	if (unlikely((space == 2) && !(vma->vm_flags & VM_EXEC)))
-		if (!signal_return(mm, regs, address, error_code))
-			/*
-			 * signal_return() has done an up_read(&mm->mmap_sem)
-			 * if it returns 0.
-			 */
-			return;
-#endif
+		goto out_up;
 
-	if (vma->vm_start <= address)
-		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN))
-		goto bad_area;
-	if (expand_stack(vma, address))
-		goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
-good_area:
-	si_code = SEGV_ACCERR;
-	if (!write) {
-		/* page not present, check vm flags */
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-			goto bad_area;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
+	if (unlikely(vma->vm_start > address)) {
+		if (!(vma->vm_flags & VM_GROWSDOWN))
+			goto out_up;
+		if (expand_stack(vma, address))
+			goto out_up;
 	}
 
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+	fault = VM_FAULT_BADACCESS;
+	if (unlikely(!(vma->vm_flags & access)))
+		goto out_up;
+
 	if (is_vm_hugetlb_page(vma))
 		address &= HPAGE_MASK;
 	/*
@@ -352,18 +347,11 @@ good_area:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
-	if (unlikely(fault & VM_FAULT_ERROR)) {
-		if (fault & VM_FAULT_OOM) {
-			up_read(&mm->mmap_sem);
-			pagefault_out_of_memory();
-			return;
-		} else if (fault & VM_FAULT_SIGBUS) {
-			do_sigbus(regs, error_code, address);
-			return;
-		}
-		BUG();
-	}
+	fault = handle_mm_fault(mm, vma, address,
+				(access == VM_WRITE) ? FAULT_FLAG_WRITE : 0);
+	if (unlikely(fault & VM_FAULT_ERROR))
+		goto out_up;
+
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
 		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
@@ -373,74 +361,69 @@ good_area:
 		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
-        up_read(&mm->mmap_sem);
 	/*
 	 * The instruction that caused the program check will
 	 * be repeated. Don't signal single step via SIGTRAP.
 	 */
 	clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
-        return;
-
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
-bad_area:
+	fault = 0;
+out_up:
 	up_read(&mm->mmap_sem);
-
-	/* User mode accesses just cause a SIGSEGV */
-	if (regs->psw.mask & PSW_MASK_PSTATE) {
-		tsk->thread.prot_addr = address;
-		tsk->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, si_code, address);
-		return;
-	}
-
-no_context:
-	do_no_context(regs, error_code, address);
+out:
+	return fault;
 }
 
-void __kprobes do_protection_exception(struct pt_regs *regs,
-				       long error_code)
+void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
 {
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	int fault;
+
 	/* Protection exception is supressing, decrement psw address. */
-	regs->psw.addr -= (error_code >> 16);
+	regs->psw.addr -= (int_code >> 16);
 	/*
 	 * Check for low-address protection.  This needs to be treated
 	 * as a special case because the translation exception code
 	 * field is not guaranteed to contain valid data in this case.
 	 */
-	if (unlikely(!(S390_lowcore.trans_exc_code & 4))) {
-		do_low_address(regs, error_code);
+	if (unlikely(!(trans_exc_code & 4))) {
+		do_low_address(regs, int_code, trans_exc_code);
 		return;
 	}
-	do_exception(regs, 4, 1);
+	fault = do_exception(regs, VM_WRITE, trans_exc_code);
+	if (unlikely(fault))
+		do_fault_error(regs, 4, trans_exc_code, fault);
 }
 
-void __kprobes do_dat_exception(struct pt_regs *regs, long error_code)
+void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
 {
-	do_exception(regs, error_code & 0xff, 0);
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	int access, fault;
+
+	access = VM_READ | VM_EXEC | VM_WRITE;
+#ifdef CONFIG_S390_EXEC_PROTECT
+	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
+	    (trans_exc_code & 3) == 0)
+		access = VM_EXEC;
+#endif
+	fault = do_exception(regs, access, trans_exc_code);
+	if (unlikely(fault))
+		do_fault_error(regs, int_code & 255, trans_exc_code, fault);
 }
 
 #ifdef CONFIG_64BIT
-void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code)
+void __kprobes do_asce_exception(struct pt_regs *regs, long int_code)
 {
-	struct mm_struct *mm;
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
-	unsigned long address;
-	int space;
-
-	mm = current->mm;
-	address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
-	space = check_space(current);
 
-	if (unlikely(space == 0 || in_atomic() || !mm))
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
 		goto no_context;
 
 	local_irq_enable();
 
 	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, address);
+	vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK);
 	up_read(&mm->mmap_sem);
 
 	if (vma) {
@@ -450,17 +433,38 @@ void __kprobes do_asce_exception(struct
 
 	/* User mode accesses just cause a SIGSEGV */
 	if (regs->psw.mask & PSW_MASK_PSTATE) {
-		current->thread.prot_addr = address;
-		current->thread.trap_no = error_code;
-		do_sigsegv(regs, error_code, SEGV_MAPERR, address);
+		do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
 		return;
 	}
 
 no_context:
-	do_no_context(regs, error_code, address);
+	do_no_context(regs, int_code, trans_exc_code);
 }
 #endif
 
+int __handle_fault(unsigned long uaddr, unsigned long int_code, int write_user)
+{
+	struct pt_regs regs;
+	int access, fault;
+
+	regs.psw.mask = psw_kernel_bits;
+	if (!irqs_disabled())
+		regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
+	regs.psw.addr = (unsigned long) __builtin_return_address(0);
+	regs.psw.addr |= PSW_ADDR_AMODE;
+	uaddr &= PAGE_MASK;
+	access = write_user ? VM_WRITE : VM_READ;
+	fault = do_exception(&regs, access, uaddr | 2);
+	if (unlikely(fault)) {
+		if (fault & VM_FAULT_OOM) {
+			pagefault_out_of_memory();
+			fault = 0;
+		} else if (fault & VM_FAULT_SIGBUS)
+			do_sigbus(&regs, int_code, uaddr);
+	}
+	return fault ? -EFAULT : 0;
+}
+
 #ifdef CONFIG_PFAULT 
 /*
  * 'pfault' pseudo page faults routines.
@@ -522,7 +526,7 @@ void pfault_fini(void)
 		: : "a" (&refbk), "m" (refbk) : "cc");
 }
 
-static void pfault_interrupt(__u16 error_code)
+static void pfault_interrupt(__u16 int_code)
 {
 	struct task_struct *tsk;
 	__u16 subcode;
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/mm/mmap.c linux-libre-2.6.33-gnu1/arch/s390/mm/mmap.c
--- linux-libre-2.6.32-gnu1/arch/s390/mm/mmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/mm/mmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@
 
 static inline unsigned long mmap_base(void)
 {
-	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+	unsigned long gap = rlimit(RLIMIT_STACK);
 
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
@@ -61,7 +61,7 @@ static inline int mmap_is_legacy(void)
 #endif
 	return sysctl_legacy_va_layout ||
 	    (current->personality & ADDR_COMPAT_LAYOUT) ||
-	    current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
+	    rlimit(RLIMIT_STACK) == RLIM_INFINITY;
 }
 
 #ifndef CONFIG_64BIT
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/mm/pgtable.c linux-libre-2.6.33-gnu1/arch/s390/mm/pgtable.c
--- linux-libre-2.6.32-gnu1/arch/s390/mm/pgtable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/mm/pgtable.c	2010-02-24 13:52:17.000000000 -0500
@@ -269,7 +269,7 @@ int s390_enable_sie(void)
 	struct mm_struct *mm, *old_mm;
 
 	/* Do we have switched amode? If no, we cannot do sie */
-	if (!switch_amode)
+	if (user_mode == HOME_SPACE_MODE)
 		return -EINVAL;
 
 	/* Do we have pgstes? if yes, we are done */
diff -druNp linux-libre-2.6.32-gnu1/arch/s390/mm/vmem.c linux-libre-2.6.33-gnu1/arch/s390/mm/vmem.c
--- linux-libre-2.6.32-gnu1/arch/s390/mm/vmem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/s390/mm/vmem.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,8 +70,12 @@ static pte_t __ref *vmem_pte_alloc(void)
 		pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
 	if (!pte)
 		return NULL;
-	clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-		    PTRS_PER_PTE * sizeof(pte_t));
+	if (MACHINE_HAS_HPAGE)
+		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
+			    PTRS_PER_PTE * sizeof(pte_t));
+	else
+		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+			    PTRS_PER_PTE * sizeof(pte_t));
 	return pte;
 }
 
@@ -112,7 +116,8 @@ static int vmem_add_mem(unsigned long st
 		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
 		    (address + HPAGE_SIZE <= start + size) &&
 		    (address >= HPAGE_SIZE)) {
-			pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
+			pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
+					_SEGMENT_ENTRY_CO;
 			pmd_val(*pm_dir) = pte_val(pte);
 			address += HPAGE_SIZE - PAGE_SIZE;
 			continue;
diff -druNp linux-libre-2.6.32-gnu1/arch/score/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/score/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/score/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/score/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/score/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/score/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,9 +14,12 @@ extern void flush_cache_sigtramp(unsigne
 extern void flush_icache_all(void);
 extern void flush_icache_range(unsigned long start, unsigned long end);
 extern void flush_dcache_range(unsigned long start, unsigned long end);
+extern void flush_dcache_page(struct page *page);
+
+#define PG_dcache_dirty         PG_arch_1
 
 #define flush_cache_dup_mm(mm)			do {} while (0)
-#define flush_dcache_page(page)			do {} while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #define flush_dcache_mmap_lock(mapping)		do {} while (0)
 #define flush_dcache_mmap_unlock(mapping)	do {} while (0)
 #define flush_cache_vmap(start, end)		do {} while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/score/include/asm/delay.h linux-libre-2.6.33-gnu1/arch/score/include/asm/delay.h
--- linux-libre-2.6.32-gnu1/arch/score/include/asm/delay.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/include/asm/delay.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,8 @@
 #ifndef _ASM_SCORE_DELAY_H
 #define _ASM_SCORE_DELAY_H
 
+#include <asm-generic/param.h>
+
 static inline void __delay(unsigned long loops)
 {
 	/* 3 cycles per loop. */
diff -druNp linux-libre-2.6.32-gnu1/arch/score/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/score/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/score/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,6 @@ struct task_struct;
 struct pt_regs;
 
 #define CORE_DUMP_USE_REGSET
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /* This yields a mask that user programs can use to figure out what
diff -druNp linux-libre-2.6.32-gnu1/arch/score/include/asm/page.h linux-libre-2.6.33-gnu1/arch/score/include/asm/page.h
--- linux-libre-2.6.32-gnu1/arch/score/include/asm/page.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/include/asm/page.h	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ extern unsigned long max_pfn;
 #define page_to_bus(page)	(page_to_phys(page))
 #define phys_to_page(paddr)	(pfn_to_page(phys_to_pfn(paddr)))
 
-#define pfn_valid(pfn)		((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+#define pfn_valid(pfn)		(((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn))
 
 #define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/score/kernel/setup.c linux-libre-2.6.33-gnu1/arch/score/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/score/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,7 @@ static void __init bootmem_init(void)
 
 	min_low_pfn = PFN_UP(MEMORY_START);
 	max_low_pfn = PFN_UP(MEMORY_START + MEMORY_SIZE);
+	max_mapnr = max_low_pfn - min_low_pfn;
 
 	/* Initialize the boot-time allocator with low memory only. */
 	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
diff -druNp linux-libre-2.6.32-gnu1/arch/score/kernel/sys_score.c linux-libre-2.6.33-gnu1/arch/score/kernel/sys_score.c
--- linux-libre-2.6.32-gnu1/arch/score/kernel/sys_score.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/kernel/sys_score.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,34 +36,16 @@ asmlinkage long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
 	  unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	if (pgoff & (~PAGE_MASK >> 12))
-		return -EINVAL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return error;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-
-	return error;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 asmlinkage long
 sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
-	unsigned long flags, unsigned long fd, off_t pgoff)
+	unsigned long flags, unsigned long fd, off_t offset)
 {
-	return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
+	if (unlikely(offset & ~PAGE_MASK))
+		return -EINVAL;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
 asmlinkage long
diff -druNp linux-libre-2.6.32-gnu1/arch/score/mm/cache.c linux-libre-2.6.33-gnu1/arch/score/mm/cache.c
--- linux-libre-2.6.32-gnu1/arch/score/mm/cache.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/fs.h>
 
 #include <asm/mmu_context.h>
 
@@ -51,6 +52,27 @@ static void flush_data_cache_page(unsign
 	}
 }
 
+void flush_dcache_page(struct page *page)
+{
+	struct address_space *mapping = page_mapping(page);
+	unsigned long addr;
+
+	if (PageHighMem(page))
+		return;
+	if (mapping && !mapping_mapped(mapping)) {
+		set_bit(PG_dcache_dirty, &(page)->flags);
+		return;
+	}
+
+	/*
+	 * We could delay the flush for the !page_mapping case too.  But that
+	 * case is for exec env/arg pages and those are %99 certainly going to
+	 * get faulted into the tlb (and thus flushed) anyways.
+	 */
+	addr = (unsigned long) page_address(page);
+	flush_data_cache_page(addr);
+}
+
 /* called by update_mmu_cache. */
 void __update_cache(struct vm_area_struct *vma, unsigned long address,
 		pte_t pte)
@@ -63,11 +85,11 @@ void __update_cache(struct vm_area_struc
 	if (unlikely(!pfn_valid(pfn)))
 		return;
 	page = pfn_to_page(pfn);
-	if (page_mapping(page) && test_bit(PG_arch_1, &page->flags)) {
+	if (page_mapping(page) && test_bit(PG_dcache_dirty, &(page)->flags)) {
 		addr = (unsigned long) page_address(page);
 		if (exec)
 			flush_data_cache_page(addr);
-		clear_bit(PG_arch_1, &page->flags);
+		clear_bit(PG_dcache_dirty, &(page)->flags);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/score/mm/init.c linux-libre-2.6.33-gnu1/arch/score/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/score/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/score/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,6 @@ void __init mem_init(void)
 	unsigned long codesize, reservedpages, datasize, initsize;
 	unsigned long tmp, ram = 0;
 
-	max_mapnr = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 	totalram_pages += free_all_bootmem();
 	totalram_pages -= setup_zero_page();	/* Setup zeroed pages. */
@@ -101,17 +100,13 @@ void __init mem_init(void)
 	datasize = (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-	kclist_add(&kcore_vmalloc, (void *) VMALLOC_START,
-			VMALLOC_END - VMALLOC_START);
-
 	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,
-			(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+			totalhigh_pages << (PAGE_SHIFT-10));
 }
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/board-ap325rxa.c linux-libre-2.6.33-gnu1/arch/sh/boards/board-ap325rxa.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/board-ap325rxa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/board-ap325rxa.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,606 +0,0 @@
-/*
- * Renesas - AP-325RXA
- * (Compatible with Algo System ., LTD. - AP-320A)
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Author : Yusuke Goda <goda.yuske@renesas.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/device.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/sh_flctl.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/smsc911x.h>
-#include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <media/ov772x.h>
-#include <media/soc_camera.h>
-#include <media/soc_camera_platform.h>
-#include <media/sh_mobile_ceu.h>
-#include <video/sh_mobile_lcdc.h>
-#include <asm/io.h>
-#include <asm/clock.h>
-#include <cpu/sh7723.h>
-
-static struct smsc911x_platform_config smsc911x_config = {
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT,
-};
-
-static struct resource smsc9118_resources[] = {
-	[0] = {
-		.start	= 0xb6080000,
-		.end	= 0xb60fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 35,
-		.end	= 35,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device smsc9118_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smsc9118_resources),
-	.resource	= smsc9118_resources,
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	},
-};
-
-/*
- * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
- * If this area erased, this board can not boot.
- */
-static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
-	{
-		.name = "uboot",
-		.offset = 0,
-		.size = (1 * 1024 * 1024),
-		.mask_flags = MTD_WRITEABLE,	/* Read-only */
-	}, {
-		.name = "kernel",
-		.offset = MTDPART_OFS_APPEND,
-		.size = (2 * 1024 * 1024),
-	}, {
-		.name = "free-area0",
-		.offset = MTDPART_OFS_APPEND,
-		.size = ((7 * 1024 * 1024) + (512 * 1024)),
-	}, {
-		.name = "CPLD-Data",
-		.offset = MTDPART_OFS_APPEND,
-		.mask_flags = MTD_WRITEABLE,	/* Read-only */
-		.size = (1024 * 128 * 2),
-	}, {
-		.name = "free-area1",
-		.offset = MTDPART_OFS_APPEND,
-		.size = MTDPART_SIZ_FULL,
-	},
-};
-
-static struct physmap_flash_data ap325rxa_nor_flash_data = {
-	.width		= 2,
-	.parts		= ap325rxa_nor_flash_partitions,
-	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
-};
-
-static struct resource ap325rxa_nor_flash_resources[] = {
-	[0] = {
-		.name	= "NOR Flash",
-		.start	= 0x00000000,
-		.end	= 0x00ffffff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device ap325rxa_nor_flash_device = {
-	.name		= "physmap-flash",
-	.resource	= ap325rxa_nor_flash_resources,
-	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
-	.dev		= {
-		.platform_data = &ap325rxa_nor_flash_data,
-	},
-};
-
-static struct mtd_partition nand_partition_info[] = {
-	{
-		.name	= "nand_data",
-		.offset	= 0,
-		.size	= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct resource nand_flash_resources[] = {
-	[0] = {
-		.start	= 0xa4530000,
-		.end	= 0xa45300ff,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct sh_flctl_platform_data nand_flash_data = {
-	.parts		= nand_partition_info,
-	.nr_parts	= ARRAY_SIZE(nand_partition_info),
-	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
-	.has_hwecc	= 1,
-};
-
-static struct platform_device nand_flash_device = {
-	.name		= "sh_flctl",
-	.resource	= nand_flash_resources,
-	.num_resources	= ARRAY_SIZE(nand_flash_resources),
-	.dev		= {
-		.platform_data = &nand_flash_data,
-	},
-};
-
-#define FPGA_LCDREG	0xB4100180
-#define FPGA_BKLREG	0xB4100212
-#define FPGA_LCDREG_VAL	0x0018
-#define PORT_MSELCRB	0xA4050182
-#define PORT_HIZCRC	0xA405015C
-#define PORT_DRVCRA	0xA405018A
-#define PORT_DRVCRB	0xA405018C
-
-static void ap320_wvga_power_on(void *board_data)
-{
-	msleep(100);
-
-	/* ASD AP-320/325 LCD ON */
-	ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
-
-	/* backlight */
-	gpio_set_value(GPIO_PTS3, 0);
-	ctrl_outw(0x100, FPGA_BKLREG);
-}
-
-static void ap320_wvga_power_off(void *board_data)
-{
-	/* backlight */
-	ctrl_outw(0, FPGA_BKLREG);
-	gpio_set_value(GPIO_PTS3, 1);
-
-	/* ASD AP-320/325 LCD OFF */
-	ctrl_outw(0, FPGA_LCDREG);
-}
-
-static struct sh_mobile_lcdc_info lcdc_info = {
-	.clock_source = LCDC_CLK_EXTERNAL,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.bpp = 16,
-		.interface_type = RGB18,
-		.clock_divider = 1,
-		.lcd_cfg = {
-			.name = "LB070WV1",
-			.xres = 800,
-			.yres = 480,
-			.left_margin = 32,
-			.right_margin = 160,
-			.hsync_len = 8,
-			.upper_margin = 63,
-			.lower_margin = 80,
-			.vsync_len = 1,
-			.sync = 0, /* hsync and vsync are active low */
-		},
-		.lcd_size_cfg = { /* 7.0 inch */
-			.width = 152,
-			.height = 91,
-		},
-		.board_cfg = {
-			.display_on = ap320_wvga_power_on,
-			.display_off = ap320_wvga_power_off,
-		},
-	}
-};
-
-static struct resource lcdc_resources[] = {
-	[0] = {
-		.name	= "LCDC",
-		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe942fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 28,
-		.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,
-	},
-	.archdata = {
-		.hwblk_id = HWBLK_LCDC,
-	},
-};
-
-static void camera_power(int val)
-{
-	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
-	mdelay(10);
-}
-
-#ifdef CONFIG_I2C
-/* support for the old ncm03j camera */
-static unsigned char camera_ncm03j_magic[] =
-{
-	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
-	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
-	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
-	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
-	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
-	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
-	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
-	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
-	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
-	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
-	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
-	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
-	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
-	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
-	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
-	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
-};
-
-static int camera_probe(void)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	int ret;
-
-	if (!a)
-		return -ENODEV;
-
-	camera_power(1);
-	msg.addr = 0x6e;
-	msg.buf = camera_ncm03j_magic;
-	msg.len = 2;
-	msg.flags = 0;
-	ret = i2c_transfer(a, &msg, 1);
-	camera_power(0);
-
-	return ret;
-}
-
-static int camera_set_capture(struct soc_camera_platform_info *info,
-			      int enable)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	int ret = 0;
-	int i;
-
-	camera_power(0);
-	if (!enable)
-		return 0; /* no disable for now */
-
-	camera_power(1);
-	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
-		u_int8_t buf[8];
-
-		msg.addr = 0x6e;
-		msg.buf = buf;
-		msg.len = 2;
-		msg.flags = 0;
-
-		buf[0] = camera_ncm03j_magic[i];
-		buf[1] = camera_ncm03j_magic[i + 1];
-
-		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
-	}
-
-	return ret;
-}
-
-static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
-static void ap325rxa_camera_del(struct soc_camera_link *icl);
-
-static struct soc_camera_platform_info camera_info = {
-	.format_name = "UYVY",
-	.format_depth = 16,
-	.format = {
-		.pixelformat = V4L2_PIX_FMT_UYVY,
-		.colorspace = V4L2_COLORSPACE_SMPTE170M,
-		.width = 640,
-		.height = 480,
-	},
-	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
-	.set_capture = camera_set_capture,
-	.link = {
-		.bus_id		= 0,
-		.add_device	= ap325rxa_camera_add,
-		.del_device	= ap325rxa_camera_del,
-		.module_name	= "soc_camera_platform",
-	},
-};
-
-static void dummy_release(struct device *dev)
-{
-}
-
-static struct platform_device camera_device = {
-	.name		= "soc_camera_platform",
-	.dev		= {
-		.platform_data	= &camera_info,
-		.release	= dummy_release,
-	},
-};
-
-static int ap325rxa_camera_add(struct soc_camera_link *icl,
-			       struct device *dev)
-{
-	if (icl != &camera_info.link || camera_probe() <= 0)
-		return -ENODEV;
-
-	camera_info.dev = dev;
-
-	return platform_device_register(&camera_device);
-}
-
-static void ap325rxa_camera_del(struct soc_camera_link *icl)
-{
-	if (icl != &camera_info.link)
-		return;
-
-	platform_device_unregister(&camera_device);
-	memset(&camera_device.dev.kobj, 0,
-	       sizeof(camera_device.dev.kobj));
-}
-#endif /* CONFIG_I2C */
-
-static int ov7725_power(struct device *dev, int mode)
-{
-	camera_power(0);
-	if (mode)
-		camera_power(1);
-
-	return 0;
-}
-
-static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
-};
-
-static struct resource ceu_resources[] = {
-	[0] = {
-		.name	= "CEU",
-		.start	= 0xfe910000,
-		.end	= 0xfe91009f,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = 52,
-		.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,
-	},
-	.archdata = {
-		.hwblk_id = HWBLK_CEU,
-	},
-};
-
-struct spi_gpio_platform_data sdcard_cn3_platform_data = {
-	.sck = GPIO_PTD0,
-	.mosi = GPIO_PTD1,
-	.miso = GPIO_PTD2,
-	.num_chipselect = 1,
-};
-
-static struct platform_device sdcard_cn3_device = {
-	.name		= "spi_gpio",
-	.dev	= {
-		.platform_data	= &sdcard_cn3_platform_data,
-	},
-};
-
-static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	},
-};
-
-static struct i2c_board_info ap325rxa_i2c_camera[] = {
-	{
-		I2C_BOARD_INFO("ov772x", 0x21),
-	},
-};
-
-static struct ov772x_camera_info ov7725_info = {
-	.buswidth	= SOCAM_DATAWIDTH_8,
-	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
-	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
-	.link = {
-		.bus_id		= 0,
-		.power		= ov7725_power,
-		.board_info	= &ap325rxa_i2c_camera[0],
-		.i2c_adapter_id	= 0,
-		.module_name	= "ov772x",
-	},
-};
-
-static struct platform_device ap325rxa_camera[] = {
-	{
-		.name	= "soc-camera-pdrv",
-		.id	= 0,
-		.dev	= {
-			.platform_data = &ov7725_info.link,
-		},
-	}, {
-		.name	= "soc-camera-pdrv",
-		.id	= 1,
-		.dev	= {
-			.platform_data = &camera_info.link,
-		},
-	},
-};
-
-static struct platform_device *ap325rxa_devices[] __initdata = {
-	&smsc9118_device,
-	&ap325rxa_nor_flash_device,
-	&lcdc_device,
-	&ceu_device,
-	&nand_flash_device,
-	&sdcard_cn3_device,
-	&ap325rxa_camera[0],
-	&ap325rxa_camera[1],
-};
-
-static struct spi_board_info ap325rxa_spi_devices[] = {
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 5000000,
-		.chip_select = 0,
-		.controller_data = (void *) GPIO_PTD5,
-	},
-};
-
-static int __init ap325rxa_devices_setup(void)
-{
-	/* LD3 and LD4 LEDs */
-	gpio_request(GPIO_PTX5, NULL); /* RUN */
-	gpio_direction_output(GPIO_PTX5, 1);
-	gpio_export(GPIO_PTX5, 0);
-
-	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
-	gpio_direction_output(GPIO_PTX4, 0);
-	gpio_export(GPIO_PTX4, 0);
-
-	/* SW1 input */
-	gpio_request(GPIO_PTF7, NULL); /* MODE */
-	gpio_direction_input(GPIO_PTF7);
-	gpio_export(GPIO_PTF7, 0);
-
-	/* LCDC */
-	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_LCDLCLK_PTR, NULL);
-	gpio_request(GPIO_FN_LCDDCK, NULL);
-	gpio_request(GPIO_FN_LCDVEPWC, NULL);
-	gpio_request(GPIO_FN_LCDVCPWC, NULL);
-	gpio_request(GPIO_FN_LCDVSYN, NULL);
-	gpio_request(GPIO_FN_LCDHSYN, NULL);
-	gpio_request(GPIO_FN_LCDDISP, NULL);
-	gpio_request(GPIO_FN_LCDDON, NULL);
-
-	/* LCD backlight */
-	gpio_request(GPIO_PTS3, NULL);
-	gpio_direction_output(GPIO_PTS3, 1);
-
-	/* CEU */
-	gpio_request(GPIO_FN_VIO_CLK2, NULL);
-	gpio_request(GPIO_FN_VIO_VD2, NULL);
-	gpio_request(GPIO_FN_VIO_HD2, NULL);
-	gpio_request(GPIO_FN_VIO_FLD, NULL);
-	gpio_request(GPIO_FN_VIO_CKO, NULL);
-	gpio_request(GPIO_FN_VIO_D15, NULL);
-	gpio_request(GPIO_FN_VIO_D14, NULL);
-	gpio_request(GPIO_FN_VIO_D13, NULL);
-	gpio_request(GPIO_FN_VIO_D12, NULL);
-	gpio_request(GPIO_FN_VIO_D11, NULL);
-	gpio_request(GPIO_FN_VIO_D10, NULL);
-	gpio_request(GPIO_FN_VIO_D9, NULL);
-	gpio_request(GPIO_FN_VIO_D8, NULL);
-
-	gpio_request(GPIO_PTZ7, NULL);
-	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
-	gpio_request(GPIO_PTZ6, NULL);
-	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
-	gpio_request(GPIO_PTZ5, NULL);
-	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
-	gpio_request(GPIO_PTZ4, NULL);
-	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
-
-	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
-
-	/* FLCTL */
-	gpio_request(GPIO_FN_FCE, NULL);
-	gpio_request(GPIO_FN_NAF7, NULL);
-	gpio_request(GPIO_FN_NAF6, NULL);
-	gpio_request(GPIO_FN_NAF5, NULL);
-	gpio_request(GPIO_FN_NAF4, NULL);
-	gpio_request(GPIO_FN_NAF3, NULL);
-	gpio_request(GPIO_FN_NAF2, NULL);
-	gpio_request(GPIO_FN_NAF1, NULL);
-	gpio_request(GPIO_FN_NAF0, NULL);
-	gpio_request(GPIO_FN_FCDE, NULL);
-	gpio_request(GPIO_FN_FOE, NULL);
-	gpio_request(GPIO_FN_FSC, NULL);
-	gpio_request(GPIO_FN_FWE, NULL);
-	gpio_request(GPIO_FN_FRB, NULL);
-
-	ctrl_outw(0, PORT_HIZCRC);
-	ctrl_outw(0xFFFF, PORT_DRVCRA);
-	ctrl_outw(0xFFFF, PORT_DRVCRB);
-
-	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
-
-	i2c_register_board_info(0, ap325rxa_i2c_devices,
-				ARRAY_SIZE(ap325rxa_i2c_devices));
-
-	spi_register_board_info(ap325rxa_spi_devices,
-				ARRAY_SIZE(ap325rxa_spi_devices));
-
-	return platform_add_devices(ap325rxa_devices,
-				ARRAY_SIZE(ap325rxa_devices));
-}
-arch_initcall(ap325rxa_devices_setup);
-
-/* Return the board specific boot mode pin configuration */
-static int ap325rxa_mode_pins(void)
-{
-	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
-	 * MD3=0: 16-bit Area0 Bus Width
-	 * MD5=1: Little Endian
-	 * TSTMD=1, MD8=1: Test Mode Disabled
-	 */
-	return MODE_PIN5 | MODE_PIN8;
-}
-
-static struct sh_machine_vector mv_ap325rxa __initmv = {
-	.mv_name = "AP-325RXA",
-	.mv_mode_pins = ap325rxa_mode_pins,
-};
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2 @@
+obj-y	 := setup.o sdram.o
+
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/sdram.S linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/sdram.S
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/sdram.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/sdram.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,69 @@
+/*
+ * AP325RXA sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ap325rxa_sdram_enter_start)
+
+	/* SBSC: disable power down and put in self-refresh mode */
+	mov.l	1f, r4
+	mov.l	2f, r1
+	mov.l	@r4, r2
+	or	r1, r2
+	mov.l   3f, r3
+	and	r3, r2
+	mov.l	r2, @r4
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+2:	.long	0x00000400
+3:	.long	0xffff7fff
+ENTRY(ap325rxa_sdram_enter_end)
+
+	.balign 4
+ENTRY(ap325rxa_sdram_leave_start)
+
+	/* SBSC: set auto-refresh mode */
+	mov.l	1f, r4
+	mov.l	@r4, r0
+	mov.l   4f, r1
+	and	r1, r0
+	mov.l	r0, @r4
+	mov.l	6f, r4
+	mov.l	8f, r0
+	mov.l	@r4, r1
+	mov	#-1, r4
+	add	r4, r1
+	or	r1, r0
+	mov.l	7f, r1
+	mov.l	r0, @r1
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+4:	.long	0xfffffbff
+6:	.long   0xfe40001c /* RTCOR */
+7:	.long   0xfe400018 /* RTCNT */
+8:	.long   0xa55a0000
+ENTRY(ap325rxa_sdram_leave_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ap325rxa/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ap325rxa/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,663 @@
+/*
+ * Renesas - AP-325RXA
+ * (Compatible with Algo System ., LTD. - AP-320A)
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Author : Yusuke Goda <goda.yuske@renesas.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/device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <media/ov772x.h>
+#include <media/soc_camera.h>
+#include <media/soc_camera_platform.h>
+#include <media/sh_mobile_ceu.h>
+#include <video/sh_mobile_lcdc.h>
+#include <asm/io.h>
+#include <asm/clock.h>
+#include <asm/suspend.h>
+#include <cpu/sh7723.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT,
+};
+
+static struct resource smsc9118_resources[] = {
+	[0] = {
+		.start	= 0xb6080000,
+		.end	= 0xb60fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 35,
+		.end	= 35,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smsc9118_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smsc9118_resources),
+	.resource	= smsc9118_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+/*
+ * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
+ * If this area erased, this board can not boot.
+ */
+static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
+	{
+		.name = "uboot",
+		.offset = 0,
+		.size = (1 * 1024 * 1024),
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+	}, {
+		.name = "kernel",
+		.offset = MTDPART_OFS_APPEND,
+		.size = (2 * 1024 * 1024),
+	}, {
+		.name = "free-area0",
+		.offset = MTDPART_OFS_APPEND,
+		.size = ((7 * 1024 * 1024) + (512 * 1024)),
+	}, {
+		.name = "CPLD-Data",
+		.offset = MTDPART_OFS_APPEND,
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+		.size = (1024 * 128 * 2),
+	}, {
+		.name = "free-area1",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data ap325rxa_nor_flash_data = {
+	.width		= 2,
+	.parts		= ap325rxa_nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
+};
+
+static struct resource ap325rxa_nor_flash_resources[] = {
+	[0] = {
+		.name	= "NOR Flash",
+		.start	= 0x00000000,
+		.end	= 0x00ffffff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device ap325rxa_nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= ap325rxa_nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
+	.dev		= {
+		.platform_data = &ap325rxa_nor_flash_data,
+	},
+};
+
+static struct mtd_partition nand_partition_info[] = {
+	{
+		.name	= "nand_data",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct resource nand_flash_resources[] = {
+	[0] = {
+		.start	= 0xa4530000,
+		.end	= 0xa45300ff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+	.parts		= nand_partition_info,
+	.nr_parts	= ARRAY_SIZE(nand_partition_info),
+	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
+	.has_hwecc	= 1,
+};
+
+static struct platform_device nand_flash_device = {
+	.name		= "sh_flctl",
+	.resource	= nand_flash_resources,
+	.num_resources	= ARRAY_SIZE(nand_flash_resources),
+	.dev		= {
+		.platform_data = &nand_flash_data,
+	},
+};
+
+#define FPGA_LCDREG	0xB4100180
+#define FPGA_BKLREG	0xB4100212
+#define FPGA_LCDREG_VAL	0x0018
+#define PORT_MSELCRB	0xA4050182
+#define PORT_HIZCRC	0xA405015C
+#define PORT_DRVCRA	0xA405018A
+#define PORT_DRVCRB	0xA405018C
+
+static void ap320_wvga_power_on(void *board_data)
+{
+	msleep(100);
+
+	/* ASD AP-320/325 LCD ON */
+	ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
+
+	/* backlight */
+	gpio_set_value(GPIO_PTS3, 0);
+	ctrl_outw(0x100, FPGA_BKLREG);
+}
+
+static void ap320_wvga_power_off(void *board_data)
+{
+	/* backlight */
+	ctrl_outw(0, FPGA_BKLREG);
+	gpio_set_value(GPIO_PTS3, 1);
+
+	/* ASD AP-320/325 LCD OFF */
+	ctrl_outw(0, FPGA_LCDREG);
+}
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+	.clock_source = LCDC_CLK_EXTERNAL,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.interface_type = RGB18,
+		.clock_divider = 1,
+		.lcd_cfg = {
+			.name = "LB070WV1",
+			.xres = 800,
+			.yres = 480,
+			.left_margin = 32,
+			.right_margin = 160,
+			.hsync_len = 8,
+			.upper_margin = 63,
+			.lower_margin = 80,
+			.vsync_len = 1,
+			.sync = 0, /* hsync and vsync are active low */
+		},
+		.lcd_size_cfg = { /* 7.0 inch */
+			.width = 152,
+			.height = 91,
+		},
+		.board_cfg = {
+			.display_on = ap320_wvga_power_on,
+			.display_off = ap320_wvga_power_off,
+		},
+	}
+};
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000, /* P4-only space */
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 28,
+		.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,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+static void camera_power(int val)
+{
+	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
+	mdelay(10);
+}
+
+#ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
+static unsigned char camera_ncm03j_magic[] =
+{
+	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
+	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
+	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
+	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
+	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
+	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
+	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
+	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
+	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
+	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
+	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
+	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
+	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
+	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
+	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
+	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
+};
+
+static int camera_probe(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret;
+
+	if (!a)
+		return -ENODEV;
+
+	camera_power(1);
+	msg.addr = 0x6e;
+	msg.buf = camera_ncm03j_magic;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	camera_power(0);
+
+	return ret;
+}
+
+static int camera_set_capture(struct soc_camera_platform_info *info,
+			      int enable)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret = 0;
+	int i;
+
+	camera_power(0);
+	if (!enable)
+		return 0; /* no disable for now */
+
+	camera_power(1);
+	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
+		u_int8_t buf[8];
+
+		msg.addr = 0x6e;
+		msg.buf = buf;
+		msg.len = 2;
+		msg.flags = 0;
+
+		buf[0] = camera_ncm03j_magic[i];
+		buf[1] = camera_ncm03j_magic[i + 1];
+
+		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
+	}
+
+	return ret;
+}
+
+static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
+static void ap325rxa_camera_del(struct soc_camera_link *icl);
+
+static struct soc_camera_platform_info camera_info = {
+	.format_name = "UYVY",
+	.format_depth = 16,
+	.format = {
+		.code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
+		.field = V4L2_FIELD_NONE,
+		.width = 640,
+		.height = 480,
+	},
+	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
+	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
+	SOCAM_DATA_ACTIVE_HIGH,
+	.set_capture = camera_set_capture,
+};
+
+struct soc_camera_link camera_link = {
+	.bus_id		= 0,
+	.add_device	= ap325rxa_camera_add,
+	.del_device	= ap325rxa_camera_del,
+	.module_name	= "soc_camera_platform",
+	.priv		= &camera_info,
+};
+
+static void dummy_release(struct device *dev)
+{
+}
+
+static struct platform_device camera_device = {
+	.name		= "soc_camera_platform",
+	.dev		= {
+		.platform_data	= &camera_info,
+		.release	= dummy_release,
+	},
+};
+
+static int ap325rxa_camera_add(struct soc_camera_link *icl,
+			       struct device *dev)
+{
+	if (icl != &camera_link || camera_probe() <= 0)
+		return -ENODEV;
+
+	camera_info.dev = dev;
+
+	return platform_device_register(&camera_device);
+}
+
+static void ap325rxa_camera_del(struct soc_camera_link *icl)
+{
+	if (icl != &camera_link)
+		return;
+
+	platform_device_unregister(&camera_device);
+	memset(&camera_device.dev.kobj, 0,
+	       sizeof(camera_device.dev.kobj));
+}
+#endif /* CONFIG_I2C */
+
+static int ov7725_power(struct device *dev, int mode)
+{
+	camera_power(0);
+	if (mode)
+		camera_power(1);
+
+	return 0;
+}
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu_resources[] = {
+	[0] = {
+		.name	= "CEU",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.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,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
+};
+
+static struct resource sdhi0_cn3_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start	= 0x04ce0000,
+		.end	= 0x04ce01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_cn3_device = {
+	.name		= "sh_mobile_sdhi",
+	.id             = 0, /* "sdhi0" clock */
+	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
+	.resource	= sdhi0_cn3_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+static struct resource sdhi1_cn7_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start	= 0x04cf0000,
+		.end	= 0x04cf01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 24,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_cn7_device = {
+	.name		= "sh_mobile_sdhi",
+	.id             = 1, /* "sdhi1" clock */
+	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
+	.resource	= sdhi1_cn7_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
+static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	},
+};
+
+static struct i2c_board_info ap325rxa_i2c_camera[] = {
+	{
+		I2C_BOARD_INFO("ov772x", 0x21),
+	},
+};
+
+static struct ov772x_camera_info ov7725_info = {
+	.buswidth	= SOCAM_DATAWIDTH_8,
+	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
+};
+
+static struct soc_camera_link ov7725_link = {
+	.bus_id		= 0,
+	.power		= ov7725_power,
+	.board_info	= &ap325rxa_i2c_camera[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "ov772x",
+	.priv		= &ov7725_info,
+};
+
+static struct platform_device ap325rxa_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &ov7725_link,
+		},
+	}, {
+		.name	= "soc-camera-pdrv",
+		.id	= 1,
+		.dev	= {
+			.platform_data = &camera_link,
+		},
+	},
+};
+
+static struct platform_device *ap325rxa_devices[] __initdata = {
+	&smsc9118_device,
+	&ap325rxa_nor_flash_device,
+	&lcdc_device,
+	&ceu_device,
+	&nand_flash_device,
+	&sdhi0_cn3_device,
+	&sdhi1_cn7_device,
+	&ap325rxa_camera[0],
+	&ap325rxa_camera[1],
+};
+
+extern char ap325rxa_sdram_enter_start;
+extern char ap325rxa_sdram_enter_end;
+extern char ap325rxa_sdram_leave_start;
+extern char ap325rxa_sdram_leave_end;
+
+static int __init ap325rxa_devices_setup(void)
+{
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ap325rxa_sdram_enter_start,
+					&ap325rxa_sdram_enter_end,
+					&ap325rxa_sdram_leave_start,
+					&ap325rxa_sdram_leave_end);
+
+	/* LD3 and LD4 LEDs */
+	gpio_request(GPIO_PTX5, NULL); /* RUN */
+	gpio_direction_output(GPIO_PTX5, 1);
+	gpio_export(GPIO_PTX5, 0);
+
+	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
+	gpio_direction_output(GPIO_PTX4, 0);
+	gpio_export(GPIO_PTX4, 0);
+
+	/* SW1 input */
+	gpio_request(GPIO_PTF7, NULL); /* MODE */
+	gpio_direction_input(GPIO_PTF7);
+	gpio_export(GPIO_PTF7, 0);
+
+	/* LCDC */
+	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_LCDLCLK_PTR, NULL);
+	gpio_request(GPIO_FN_LCDDCK, NULL);
+	gpio_request(GPIO_FN_LCDVEPWC, NULL);
+	gpio_request(GPIO_FN_LCDVCPWC, NULL);
+	gpio_request(GPIO_FN_LCDVSYN, NULL);
+	gpio_request(GPIO_FN_LCDHSYN, NULL);
+	gpio_request(GPIO_FN_LCDDISP, NULL);
+	gpio_request(GPIO_FN_LCDDON, NULL);
+
+	/* LCD backlight */
+	gpio_request(GPIO_PTS3, NULL);
+	gpio_direction_output(GPIO_PTS3, 1);
+
+	/* CEU */
+	gpio_request(GPIO_FN_VIO_CLK2, NULL);
+	gpio_request(GPIO_FN_VIO_VD2, NULL);
+	gpio_request(GPIO_FN_VIO_HD2, NULL);
+	gpio_request(GPIO_FN_VIO_FLD, NULL);
+	gpio_request(GPIO_FN_VIO_CKO, NULL);
+	gpio_request(GPIO_FN_VIO_D15, NULL);
+	gpio_request(GPIO_FN_VIO_D14, NULL);
+	gpio_request(GPIO_FN_VIO_D13, NULL);
+	gpio_request(GPIO_FN_VIO_D12, NULL);
+	gpio_request(GPIO_FN_VIO_D11, NULL);
+	gpio_request(GPIO_FN_VIO_D10, NULL);
+	gpio_request(GPIO_FN_VIO_D9, NULL);
+	gpio_request(GPIO_FN_VIO_D8, NULL);
+
+	gpio_request(GPIO_PTZ7, NULL);
+	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
+	gpio_request(GPIO_PTZ6, NULL);
+	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
+	gpio_request(GPIO_PTZ5, NULL);
+	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
+	gpio_request(GPIO_PTZ4, NULL);
+	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
+
+	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
+
+	/* FLCTL */
+	gpio_request(GPIO_FN_FCE, NULL);
+	gpio_request(GPIO_FN_NAF7, NULL);
+	gpio_request(GPIO_FN_NAF6, NULL);
+	gpio_request(GPIO_FN_NAF5, NULL);
+	gpio_request(GPIO_FN_NAF4, NULL);
+	gpio_request(GPIO_FN_NAF3, NULL);
+	gpio_request(GPIO_FN_NAF2, NULL);
+	gpio_request(GPIO_FN_NAF1, NULL);
+	gpio_request(GPIO_FN_NAF0, NULL);
+	gpio_request(GPIO_FN_FCDE, NULL);
+	gpio_request(GPIO_FN_FOE, NULL);
+	gpio_request(GPIO_FN_FSC, NULL);
+	gpio_request(GPIO_FN_FWE, NULL);
+	gpio_request(GPIO_FN_FRB, NULL);
+
+	ctrl_outw(0, PORT_HIZCRC);
+	ctrl_outw(0xFFFF, PORT_DRVCRA);
+	ctrl_outw(0xFFFF, PORT_DRVCRB);
+
+	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
+
+	/* SDHI0 - CN3 - SD CARD */
+	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
+
+	/* SDHI1 - CN7 - MICRO SD CARD */
+	gpio_request(GPIO_FN_SDHI1CD, NULL);
+	gpio_request(GPIO_FN_SDHI1D3, NULL);
+	gpio_request(GPIO_FN_SDHI1D2, NULL);
+	gpio_request(GPIO_FN_SDHI1D1, NULL);
+	gpio_request(GPIO_FN_SDHI1D0, NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
+	i2c_register_board_info(0, ap325rxa_i2c_devices,
+				ARRAY_SIZE(ap325rxa_i2c_devices));
+
+	return platform_add_devices(ap325rxa_devices,
+				ARRAY_SIZE(ap325rxa_devices));
+}
+arch_initcall(ap325rxa_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int ap325rxa_mode_pins(void)
+{
+	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
+	 * MD3=0: 16-bit Area0 Bus Width
+	 * MD5=1: Little Endian
+	 * TSTMD=1, MD8=1: Test Mode Disabled
+	 */
+	return MODE_PIN5 | MODE_PIN8;
+}
+
+static struct sh_machine_vector mv_ap325rxa __initmv = {
+	.mv_name = "AP-325RXA",
+	.mv_mode_pins = ap325rxa_mode_pins,
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,4 +6,4 @@
 # for more details.
 #
 
-obj-y	 := setup.o
\ No newline at end of file
+obj-y	 := setup.o sdram.o
\ No newline at end of file
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/sdram.S linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/sdram.S
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/sdram.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/sdram.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * Ecovec24 sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ecovec24_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ecovec24_sdram_enter_end)
+
+	.balign 4
+ENTRY(ecovec24_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ecovec24_sdram_leave_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-ecovec24/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-ecovec24/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,13 +19,22 @@
 #include <linux/usb/r8a66597.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/sh_msiof.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/mmc/host.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
 #include <video/sh_mobile_lcdc.h>
+#include <sound/sh_fsi.h>
 #include <media/sh_mobile_ceu.h>
+#include <media/tw9910.h>
+#include <media/mt9t112.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_eth.h>
-#include <asm/sh_keysc.h>
 #include <asm/clock.h>
+#include <asm/suspend.h>
 #include <cpu/sh7724.h>
 
 /*
@@ -119,8 +128,6 @@ static struct platform_device nor_flash_
 
 /* SH Eth */
 #define SH_ETH_ADDR	(0xA4600000)
-#define SH_ETH_MAHR	(SH_ETH_ADDR + 0x1C0)
-#define SH_ETH_MALR	(SH_ETH_ADDR + 0x1C8)
 static struct resource sh_eth_resources[] = {
 	[0] = {
 		.start = SH_ETH_ADDR,
@@ -147,6 +154,9 @@ static struct platform_device sh_eth_dev
 	},
 	.num_resources = ARRAY_SIZE(sh_eth_resources),
 	.resource = sh_eth_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_ETHER,
+	},
 };
 
 /* USB0 host */
@@ -185,30 +195,18 @@ static struct platform_device usb0_host_
 	.resource	= usb0_host_resources,
 };
 
-/*
- * USB1
- *
- * CN5 can use both host/function,
- * and we can determine it by checking PTB[3]
- *
- * This time only USB1 host is supported.
- */
+/* USB1 host/function */
 void usb1_port_power(int port, int power)
 {
-	if (!gpio_get_value(GPIO_PTB3)) {
-		printk(KERN_ERR "USB1 function is not supported\n");
-		return;
-	}
-
 	gpio_set_value(GPIO_PTB5, power);
 }
 
-static struct r8a66597_platdata usb1_host_data = {
+static struct r8a66597_platdata usb1_common_data = {
 	.on_chip = 1,
 	.port_power = usb1_port_power,
 };
 
-static struct resource usb1_host_resources[] = {
+static struct resource usb1_common_resources[] = {
 	[0] = {
 		.start	= 0xa4d90000,
 		.end	= 0xa4d90124 - 1,
@@ -221,16 +219,16 @@ static struct resource usb1_host_resourc
 	},
 };
 
-static struct platform_device usb1_host_device = {
-	.name		= "r8a66597_hcd",
+static struct platform_device usb1_common_device = {
+	/* .name will be added in arch_setup */
 	.id		= 1,
 	.dev = {
 		.dma_mask		= NULL,         /*  not use dma */
 		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &usb1_host_data,
+		.platform_data		= &usb1_common_data,
 	},
-	.num_resources	= ARRAY_SIZE(usb1_host_resources),
-	.resource	= usb1_host_resources,
+	.num_resources	= ARRAY_SIZE(usb1_common_resources),
+	.resource	= usb1_common_resources,
 };
 
 /* LCDC */
@@ -345,10 +343,20 @@ static struct platform_device ceu1_devic
 };
 
 /* I2C device */
+static struct i2c_board_info i2c0_devices[] = {
+	{
+		I2C_BOARD_INFO("da7210", 0x1a),
+	},
+};
+
 static struct i2c_board_info i2c1_devices[] = {
 	{
 		I2C_BOARD_INFO("r2025sd", 0x32),
 	},
+	{
+		I2C_BOARD_INFO("lis3lv02d", 0x1c),
+		.irq = 33,
+	}
 };
 
 /* KEYSC */
@@ -428,16 +436,343 @@ static struct i2c_board_info ts_i2c_clie
 	.irq		= IRQ0,
 };
 
+#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+/* SHDI0 */
+static void sdhi0_set_pwr(struct platform_device *pdev, int state)
+{
+	gpio_set_value(GPIO_PTB6, state);
+}
+
+static struct sh_mobile_sdhi_info sdhi0_info = {
+	.set_pwr = sdhi0_set_pwr,
+};
+
+static struct resource sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.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,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+/* SHDI1 */
+static void sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+	gpio_set_value(GPIO_PTB7, state);
+}
+
+static struct sh_mobile_sdhi_info sdhi1_info = {
+	.set_pwr = sdhi1_set_pwr,
+};
+
+static struct resource sdhi1_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start  = 0x04cf0000,
+		.end    = 0x04cf01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 24,
+		.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,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
+#else
+
+/* MMC SPI */
+static int mmc_spi_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_PTY6);
+}
+
+static int mmc_spi_get_cd(struct device *dev)
+{
+	return !gpio_get_value(GPIO_PTY7);
+}
+
+static void mmc_spi_setpower(struct device *dev, unsigned int maskval)
+{
+	gpio_set_value(GPIO_PTB6, maskval ? 1 : 0);
+}
+
+static struct mmc_spi_platform_data mmc_spi_info = {
+	.get_ro = mmc_spi_get_ro,
+	.get_cd = mmc_spi_get_cd,
+	.caps = MMC_CAP_NEEDS_POLL,
+	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */
+	.setpower = mmc_spi_setpower,
+};
+
+static struct spi_board_info spi_bus[] = {
+	{
+		.modalias	= "mmc_spi",
+		.platform_data	= &mmc_spi_info,
+		.max_speed_hz	= 5000000,
+		.mode		= SPI_MODE_0,
+		.controller_data = (void *) GPIO_PTM4,
+	},
+};
+
+/* MSIOF0 */
+static struct sh_msiof_spi_info msiof0_data = {
+	.num_chipselect = 1,
+};
+
+static struct resource msiof0_resources[] = {
+	[0] = {
+		.name	= "MSIOF0",
+		.start	= 0xa4c40000,
+		.end	= 0xa4c40063,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 84,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device msiof0_device = {
+	.name		= "spi_sh_msiof",
+	.id		= 0, /* MSIOF0 */
+	.dev = {
+		.platform_data = &msiof0_data,
+	},
+	.num_resources	= ARRAY_SIZE(msiof0_resources),
+	.resource	= msiof0_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_MSIOF0,
+	},
+};
+
+#endif
+
+/* I2C Video/Camera */
+static struct i2c_board_info i2c_camera[] = {
+	{
+		I2C_BOARD_INFO("tw9910", 0x45),
+	},
+	{
+		/* 1st camera */
+		I2C_BOARD_INFO("mt9t112", 0x3c),
+	},
+	{
+		/* 2nd camera */
+		I2C_BOARD_INFO("mt9t112", 0x3c),
+	},
+};
+
+/* tw9910 */
+static int tw9910_power(struct device *dev, int mode)
+{
+	int val = mode ? 0 : 1;
+
+	gpio_set_value(GPIO_PTU2, val);
+	if (mode)
+		mdelay(100);
+
+	return 0;
+}
+
+static struct tw9910_video_info tw9910_info = {
+	.buswidth	= SOCAM_DATAWIDTH_8,
+	.mpout		= TW9910_MPO_FIELD,
+};
+
+static struct soc_camera_link tw9910_link = {
+	.i2c_adapter_id	= 0,
+	.bus_id		= 1,
+	.power		= tw9910_power,
+	.board_info	= &i2c_camera[0],
+	.module_name	= "tw9910",
+	.priv		= &tw9910_info,
+};
+
+/* mt9t112 */
+static int mt9t112_power1(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_PTA3, mode);
+	if (mode)
+		mdelay(100);
+
+	return 0;
+}
+
+static struct mt9t112_camera_info mt9t112_info1 = {
+	.flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8,
+	.divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */
+};
+
+static struct soc_camera_link mt9t112_link1 = {
+	.i2c_adapter_id	= 0,
+	.power		= mt9t112_power1,
+	.bus_id		= 0,
+	.board_info	= &i2c_camera[1],
+	.module_name	= "mt9t112",
+	.priv		= &mt9t112_info1,
+};
+
+static int mt9t112_power2(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_PTA4, mode);
+	if (mode)
+		mdelay(100);
+
+	return 0;
+}
+
+static struct mt9t112_camera_info mt9t112_info2 = {
+	.flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8,
+	.divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */
+};
+
+static struct soc_camera_link mt9t112_link2 = {
+	.i2c_adapter_id	= 1,
+	.power		= mt9t112_power2,
+	.bus_id		= 1,
+	.board_info	= &i2c_camera[2],
+	.module_name	= "mt9t112",
+	.priv		= &mt9t112_info2,
+};
+
+static struct platform_device camera_devices[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &tw9910_link,
+		},
+	},
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 1,
+		.dev	= {
+			.platform_data = &mt9t112_link1,
+		},
+	},
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 2,
+		.dev	= {
+			.platform_data = &mt9t112_link2,
+		},
+	},
+};
+
+/* FSI */
+/*
+ * FSI-B use external clock which came from da7210.
+ * So, we should change parent of fsi
+ */
+#define FCLKBCR		0xa415000c
+static void fsimck_init(struct clk *clk)
+{
+	u32 status = ctrl_inl(clk->enable_reg);
+
+	/* use external clock */
+	status &= ~0x000000ff;
+	status |= 0x00000080;
+
+	ctrl_outl(status, clk->enable_reg);
+}
+
+static struct clk_ops fsimck_clk_ops = {
+	.init = fsimck_init,
+};
+
+static struct clk fsimckb_clk = {
+	.name		= "fsimckb_clk",
+	.id		= -1,
+	.ops		= &fsimck_clk_ops,
+	.enable_reg	= (void __iomem *)FCLKBCR,
+	.rate		= 0, /* unknown */
+};
+
+struct sh_fsi_platform_info fsi_info = {
+	.portb_flags = SH_FSI_BRS_INV |
+		       SH_FSI_OUT_SLAVE_MODE |
+		       SH_FSI_IN_SLAVE_MODE |
+		       SH_FSI_OFMT(I2S) |
+		       SH_FSI_IFMT(I2S),
+};
+
+static struct resource fsi_resources[] = {
+	[0] = {
+		.name	= "FSI",
+		.start	= 0xFE3C0000,
+		.end	= 0xFE3C021d,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 108,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device fsi_device = {
+	.name		= "sh_fsi",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(fsi_resources),
+	.resource	= fsi_resources,
+	.dev	= {
+		.platform_data	= &fsi_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
+	},
+};
+
 static struct platform_device *ecovec_devices[] __initdata = {
 	&heartbeat_device,
 	&nor_flash_device,
 	&sh_eth_device,
 	&usb0_host_device,
-	&usb1_host_device, /* USB1 host support */
+	&usb1_common_device,
 	&lcdc_device,
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
+#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+	&sdhi0_device,
+	&sdhi1_device,
+#else
+	&msiof0_device,
+#endif
+	&camera_devices[0],
+	&camera_devices[1],
+	&camera_devices[2],
+	&fsi_device,
 };
 
 #define EEPROM_ADDR 0x50
@@ -466,12 +801,9 @@ static u8 mac_read(struct i2c_adapter *a
 	return buf;
 }
 
-#define MAC_LEN 6
-static void __init sh_eth_init(void)
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
 {
 	struct i2c_adapter *a = i2c_get_adapter(1);
-	struct clk *eth_clk;
-	u8 mac[MAC_LEN];
 	int i;
 
 	if (!a) {
@@ -479,39 +811,32 @@ static void __init sh_eth_init(void)
 		return;
 	}
 
-	eth_clk = clk_get(NULL, "eth0");
-	if (!eth_clk) {
-		pr_err("can not get eth0 clk\n");
-		return;
-	}
-
 	/* read MAC address frome EEPROM */
-	for (i = 0; i < MAC_LEN; i++) {
-		mac[i] = mac_read(a, 0x10 + i);
+	for (i = 0; i < sizeof(pd->mac_addr); i++) {
+		pd->mac_addr[i] = mac_read(a, 0x10 + i);
 		msleep(10);
 	}
-
-	/* clock enable */
-	clk_enable(eth_clk);
-
-	/* reset sh-eth */
-	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
-
-	/* set MAC addr */
-	ctrl_outl((mac[0] << 24) |
-		  (mac[1] << 16) |
-		  (mac[2] <<  8) |
-		  (mac[3] <<  0), SH_ETH_MAHR);
-	ctrl_outl((mac[4] <<  8) |
-		  (mac[5] <<  0), SH_ETH_MALR);
-
-	clk_put(eth_clk);
 }
 
 #define PORT_HIZA 0xA4050158
 #define IODRIVEA  0xA405018A
+
+extern char ecovec24_sdram_enter_start;
+extern char ecovec24_sdram_enter_end;
+extern char ecovec24_sdram_leave_start;
+extern char ecovec24_sdram_leave_end;
+
 static int __init arch_setup(void)
 {
+	struct clk *clk;
+
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ecovec24_sdram_enter_start,
+					&ecovec24_sdram_enter_end,
+					&ecovec24_sdram_leave_start,
+					&ecovec24_sdram_leave_end);
+
 	/* enable STATUS0, STATUS2 and PDSTATUS */
 	gpio_request(GPIO_FN_STATUS0, NULL);
 	gpio_request(GPIO_FN_STATUS2, NULL);
@@ -561,6 +886,14 @@ static int __init arch_setup(void)
 	ctrl_outw(0x0600, 0xa40501d4);
 	ctrl_outw(0x0600, 0xa4050192);
 
+	if (gpio_get_value(GPIO_PTB3)) {
+		printk(KERN_INFO "USB1 function is selected\n");
+		usb1_common_device.name = "r8a66597_udc";
+	} else {
+		printk(KERN_INFO "USB1 host is selected\n");
+		usb1_common_device.name = "r8a66597_hcd";
+	}
+
 	/* enable LCDC */
 	gpio_request(GPIO_FN_LCDD23,   NULL);
 	gpio_request(GPIO_FN_LCDD22,   NULL);
@@ -603,8 +936,8 @@ static int __init arch_setup(void)
 	gpio_direction_output(GPIO_PTR1, 0);
 	gpio_direction_output(GPIO_PTA2, 0);
 
-	/* I/O buffer drive ability is low */
-	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA);
+	/* I/O buffer drive ability is high */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
 
 	if (gpio_get_value(GPIO_PTE6)) {
 		/* DVI */
@@ -710,7 +1043,90 @@ static int __init arch_setup(void)
 	gpio_direction_input(GPIO_PTR5);
 	gpio_direction_input(GPIO_PTR6);
 
+#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+	/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
+	gpio_request(GPIO_FN_SDHI0CD,  NULL);
+	gpio_request(GPIO_FN_SDHI0WP,  NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+	gpio_request(GPIO_FN_SDHI0D3,  NULL);
+	gpio_request(GPIO_FN_SDHI0D2,  NULL);
+	gpio_request(GPIO_FN_SDHI0D1,  NULL);
+	gpio_request(GPIO_FN_SDHI0D0,  NULL);
+	gpio_request(GPIO_PTB6, NULL);
+	gpio_direction_output(GPIO_PTB6, 0);
+
+	/* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */
+	gpio_request(GPIO_FN_SDHI1CD,  NULL);
+	gpio_request(GPIO_FN_SDHI1WP,  NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+	gpio_request(GPIO_FN_SDHI1D3,  NULL);
+	gpio_request(GPIO_FN_SDHI1D2,  NULL);
+	gpio_request(GPIO_FN_SDHI1D1,  NULL);
+	gpio_request(GPIO_FN_SDHI1D0,  NULL);
+	gpio_request(GPIO_PTB7, NULL);
+	gpio_direction_output(GPIO_PTB7, 0);
+
+	/* I/O buffer drive ability is high for SDHI1 */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
+#else
+	/* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
+	gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
+	gpio_request(GPIO_FN_MSIOF0_RXD, NULL);
+	gpio_request(GPIO_FN_MSIOF0_TSCK, NULL);
+	gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */
+	gpio_direction_output(GPIO_PTM4, 1); /* active low CS */
+	gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */
+	gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */
+	gpio_request(GPIO_PTY6, NULL); /* write protect */
+	gpio_direction_input(GPIO_PTY6);
+	gpio_request(GPIO_PTY7, NULL); /* card detect */
+	gpio_direction_input(GPIO_PTY7);
+
+	spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
+#endif
+
+	/* enable Video */
+	gpio_request(GPIO_PTU2, NULL);
+	gpio_direction_output(GPIO_PTU2, 1);
+
+	/* enable Camera */
+	gpio_request(GPIO_PTA3, NULL);
+	gpio_request(GPIO_PTA4, NULL);
+	gpio_direction_output(GPIO_PTA3, 0);
+	gpio_direction_output(GPIO_PTA4, 0);
+
+	/* enable FSI */
+	gpio_request(GPIO_FN_FSIMCKB,    NULL);
+	gpio_request(GPIO_FN_FSIIBSD,    NULL);
+	gpio_request(GPIO_FN_FSIOBSD,    NULL);
+	gpio_request(GPIO_FN_FSIIBBCK,   NULL);
+	gpio_request(GPIO_FN_FSIIBLRCK,  NULL);
+	gpio_request(GPIO_FN_FSIOBBCK,   NULL);
+	gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
+	gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
+
+	/* change parent of FSI B */
+	clk = clk_get(NULL, "fsib_clk");
+	clk_register(&fsimckb_clk);
+	clk_set_parent(clk, &fsimckb_clk);
+	clk_set_rate(clk, 11000);
+	clk_set_rate(&fsimckb_clk, 11000);
+	clk_put(clk);
+
+	gpio_request(GPIO_PTU0, NULL);
+	gpio_direction_output(GPIO_PTU0, 0);
+	mdelay(20);
+
+	/* enable motion sensor */
+	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
+	gpio_direction_input(GPIO_FN_INTC_IRQ1);
+
 	/* enable I2C device */
+	i2c_register_board_info(0, i2c0_devices,
+				ARRAY_SIZE(i2c0_devices));
+
 	i2c_register_board_info(1, i2c1_devices,
 				ARRAY_SIZE(i2c1_devices));
 
@@ -721,12 +1137,11 @@ arch_initcall(arch_setup);
 
 static int __init devices_setup(void)
 {
-	sh_eth_init();
+	sh_eth_init(&sh_eth_plat);
 	return 0;
 }
 device_initcall(devices_setup);
 
-
 static struct sh_machine_vector mv_ecovec __initmv = {
 	.mv_name	= "R0P7724 (EcoVec)",
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-highlander/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-highlander/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-highlander/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -384,7 +384,7 @@ static unsigned char irl2irq[HL_NR_IRL];
 
 static int highlander_irq_demux(int irq)
 {
-	if (irq >= HL_NR_IRL || !irl2irq[irq])
+	if (irq >= HL_NR_IRL || irq < 0 || !irl2irq[irq])
 		return irq;
 
 	return irl2irq[irq];
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-hp6xx/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <sound/sh_dac_audio.h>
 #include <asm/hd64461.h>
 #include <asm/io.h>
 #include <mach/hp6xx.h>
@@ -51,9 +52,63 @@ static struct platform_device jornadakbd
 	.id		= -1,
 };
 
+static void dac_audio_start(struct dac_audio_pdata *pdata)
+{
+	u16 v;
+	u8 v8;
+
+	/* HP Jornada 680/690 speaker on */
+	v = inw(HD64461_GPADR);
+	v &= ~HD64461_GPADR_SPEAKER;
+	outw(v, HD64461_GPADR);
+
+	/* HP Palmtop 620lx/660lx speaker on */
+	v8 = inb(PKDR);
+	v8 &= ~PKDR_SPEAKER;
+	outb(v8, PKDR);
+
+	sh_dac_enable(pdata->channel);
+}
+
+static void dac_audio_stop(struct dac_audio_pdata *pdata)
+{
+	u16 v;
+	u8 v8;
+
+	/* HP Jornada 680/690 speaker off */
+	v = inw(HD64461_GPADR);
+	v |= HD64461_GPADR_SPEAKER;
+	outw(v, HD64461_GPADR);
+
+	/* HP Palmtop 620lx/660lx speaker off */
+	v8 = inb(PKDR);
+	v8 |= PKDR_SPEAKER;
+	outb(v8, PKDR);
+
+	sh_dac_output(0, pdata->channel);
+	sh_dac_disable(pdata->channel);
+}
+
+static struct dac_audio_pdata dac_audio_platform_data = {
+	.buffer_size		= 64000,
+	.channel		= 1,
+	.start			= dac_audio_start,
+	.stop			= dac_audio_stop,
+};
+
+static struct platform_device dac_audio_device = {
+	.name		= "dac_audio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &dac_audio_platform_data,
+	}
+
+};
+
 static struct platform_device *hp6xx_devices[] __initdata = {
 	&cf_ide_device,
 	&jornadakbd_device,
+	&dac_audio_device,
 };
 
 static void __init hp6xx_init_irq(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c	2010-02-24 13:52:17.000000000 -0500
@@ -273,6 +273,12 @@ int kfr2r09_lcd_setup(void *board_data,
 	return 0;
 }
 
+void kfr2r09_lcd_start(void *board_data, void *sohandle,
+		       struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	write_memory_start(sohandle, so);
+}
+
 #define CTRL_CKSW       0x10
 #define CTRL_C10        0x20
 #define CTRL_CPSW       0x80
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,2 +1,2 @@
-obj-y	 := setup.o
+obj-y	 := setup.o sdram.o
 obj-$(CONFIG_FB_SH_MOBILE_LCDC)	+=  lcd_wqvga.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/sdram.S linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/sdram.S
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/sdram.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/sdram.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,80 @@
+/*
+ * KFR2R09 sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(kfr2r09_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(kfr2r09_sdram_enter_end)
+
+	.balign 4
+ENTRY(kfr2r09_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_RSTANDBY, r0
+	bf	resume_rstandby
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+resume_rstandby:
+
+	/* DBSC: re-initialize and put in auto-refresh */
+
+	ED 0xFD000108, 0x40000301 /* DBPDCNT0 */
+	ED 0xFD000020, 0x011B0002 /* DBCONF */
+	ED 0xFD000030, 0x03060E02 /* DBTR0 */
+	ED 0xFD000034, 0x01020102 /* DBTR1 */
+	ED 0xFD000038, 0x01090406 /* DBTR2 */
+	ED 0xFD000008, 0x00000004 /* DBKIND */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000018, 0x00000001 /* DBCKECNT */
+	WAIT 1
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000044, 0x000004AF /* DBRFPDN1 */
+	ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000108, 0x40000300 /* DBPDCNT0 */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(kfr2r09_sdram_leave_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-kfr2r09/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-kfr2r09/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,13 +16,17 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/i2c.h>
 #include <linux/usb/r8a66597.h>
+#include <media/rj54n1cb0c.h>
+#include <media/soc_camera.h>
+#include <media/sh_mobile_ceu.h>
 #include <video/sh_mobile_lcdc.h>
+#include <asm/suspend.h>
 #include <asm/clock.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
-#include <asm/sh_keysc.h>
 #include <cpu/sh7724.h>
 #include <mach/kfr2r09.h>
 
@@ -146,6 +150,7 @@ static struct sh_mobile_lcdc_info kfr2r0
 		},
 		.board_cfg = {
 			.setup_sys = kfr2r09_lcd_setup,
+			.start_transfer = kfr2r09_lcd_start,
 			.display_on = kfr2r09_lcd_on,
 			.display_off = kfr2r09_lcd_off,
 		},
@@ -212,11 +217,162 @@ static struct platform_device kfr2r09_us
 	.resource	= kfr2r09_usb0_gadget_resources,
 };
 
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource kfr2r09_ceu_resources[] = {
+	[0] = {
+		.name	= "CEU",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.end  = 52,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device kfr2r09_ceu_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
+	.num_resources	= ARRAY_SIZE(kfr2r09_ceu_resources),
+	.resource	= kfr2r09_ceu_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
+};
+
+static struct i2c_board_info kfr2r09_i2c_camera = {
+	I2C_BOARD_INFO("rj54n1cb0c", 0x50),
+};
+
+static struct clk *camera_clk;
+
+/* set VIO_CKO clock to 25MHz */
+#define CEU_MCLK_FREQ 25000000
+
+#define DRVCRB 0xA405018C
+static int camera_power(struct device *dev, int mode)
+{
+	int ret;
+
+	if (mode) {
+		long rate;
+
+		camera_clk = clk_get(NULL, "video_clk");
+		if (IS_ERR(camera_clk))
+			return PTR_ERR(camera_clk);
+
+		rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ);
+		ret = clk_set_rate(camera_clk, rate);
+		if (ret < 0)
+			goto eclkrate;
+
+		/* set DRVCRB
+		 *
+		 * use 1.8 V for VccQ_VIO
+		 * use 2.85V for VccQ_SR
+		 */
+		ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
+
+		/* reset clear */
+		ret = gpio_request(GPIO_PTB4, NULL);
+		if (ret < 0)
+			goto eptb4;
+		ret = gpio_request(GPIO_PTB7, NULL);
+		if (ret < 0)
+			goto eptb7;
+
+		ret = gpio_direction_output(GPIO_PTB4, 1);
+		if (!ret)
+			ret = gpio_direction_output(GPIO_PTB7, 1);
+		if (ret < 0)
+			goto egpioout;
+		msleep(1);
+
+		ret = clk_enable(camera_clk);	/* start VIO_CKO */
+		if (ret < 0)
+			goto eclkon;
+
+		return 0;
+	}
+
+	ret = 0;
+
+	clk_disable(camera_clk);
+eclkon:
+	gpio_set_value(GPIO_PTB7, 0);
+egpioout:
+	gpio_set_value(GPIO_PTB4, 0);
+	gpio_free(GPIO_PTB7);
+eptb7:
+	gpio_free(GPIO_PTB4);
+eptb4:
+eclkrate:
+	clk_put(camera_clk);
+	return ret;
+}
+
+static struct rj54n1_pdata rj54n1_priv = {
+	.mclk_freq	= CEU_MCLK_FREQ,
+	.ioctl_high	= false,
+};
+
+static struct soc_camera_link rj54n1_link = {
+	.power		= camera_power,
+	.board_info	= &kfr2r09_i2c_camera,
+	.i2c_adapter_id	= 1,
+	.module_name	= "rj54n1cb0c",
+	.priv		= &rj54n1_priv,
+};
+
+static struct platform_device kfr2r09_camera = {
+	.name	= "soc-camera-pdrv",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &rj54n1_link,
+	},
+};
+
+static struct resource kfr2r09_sh_sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_sdhi0_device = {
+	.name           = "sh_mobile_sdhi",
+	.num_resources  = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources),
+	.resource       = kfr2r09_sh_sdhi0_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
 static struct platform_device *kfr2r09_devices[] __initdata = {
 	&kfr2r09_nor_flash_device,
 	&kfr2r09_nand_flash_device,
 	&kfr2r09_sh_keysc_device,
 	&kfr2r09_sh_lcdc_device,
+	&kfr2r09_ceu_device,
+	&kfr2r09_camera,
+	&kfr2r09_sh_sdhi0_device,
 };
 
 #define BSC_CS0BCR 0xfec10004
@@ -268,11 +424,59 @@ static int kfr2r09_usb0_gadget_i2c_setup
 
 	return 0;
 }
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	/* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[1] = buf[0] | (1 << 6);
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
 #else
 static int kfr2r09_usb0_gadget_i2c_setup(void)
 {
 	return -ENODEV;
 }
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+	return -ENODEV;
+}
 #endif
 
 static int kfr2r09_usb0_gadget_setup(void)
@@ -299,11 +503,27 @@ static int kfr2r09_usb0_gadget_setup(voi
 	return 0;
 }
 
+extern char kfr2r09_sdram_enter_start;
+extern char kfr2r09_sdram_enter_end;
+extern char kfr2r09_sdram_leave_start;
+extern char kfr2r09_sdram_leave_end;
+
 static int __init kfr2r09_devices_setup(void)
 {
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+					SUSP_SH_RSTANDBY,
+					&kfr2r09_sdram_enter_start,
+					&kfr2r09_sdram_enter_end,
+					&kfr2r09_sdram_leave_start,
+					&kfr2r09_sdram_leave_end);
+
 	/* enable SCIF1 serial port for YC401 console support */
 	gpio_request(GPIO_FN_SCIF1_RXD, NULL);
 	gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+	kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */
+	gpio_request(GPIO_PTG3, NULL); /* HPON_ON */
+	gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */
 
 	/* setup NOR flash at CS0 */
 	ctrl_outl(0x36db0400, BSC_CS0BCR);
@@ -361,6 +581,32 @@ static int __init kfr2r09_devices_setup(
 	if (kfr2r09_usb0_gadget_setup() == 0)
 		platform_device_register(&kfr2r09_usb0_gadget_device);
 
+	/* CEU */
+	gpio_request(GPIO_FN_VIO_CKO, NULL);
+	gpio_request(GPIO_FN_VIO0_CLK, NULL);
+	gpio_request(GPIO_FN_VIO0_VD, NULL);
+	gpio_request(GPIO_FN_VIO0_HD, NULL);
+	gpio_request(GPIO_FN_VIO0_FLD, NULL);
+	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);
+
+	platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20);
+
+	/* SDHI0 connected to yc304 */
+	gpio_request(GPIO_FN_SDHI0CD, NULL);
+	gpio_request(GPIO_FN_SDHI0D3, NULL);
+	gpio_request(GPIO_FN_SDHI0D2, NULL);
+	gpio_request(GPIO_FN_SDHI0D1, NULL);
+	gpio_request(GPIO_FN_SDHI0D0, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
 	return platform_add_devices(kfr2r09_devices,
 				    ARRAY_SIZE(kfr2r09_devices));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,2 +1,2 @@
-obj-y	 := setup.o
+obj-y	 := setup.o sdram.o
 obj-$(CONFIG_SH_MIGOR_QVGA)	+=  lcd_qvga.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/sdram.S linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/sdram.S
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/sdram.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/sdram.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,69 @@
+/*
+ * Migo-R sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(migor_sdram_enter_start)
+
+	/* SBSC: disable power down and put in self-refresh mode */
+	mov.l	1f, r4
+	mov.l	2f, r1
+	mov.l	@r4, r2
+	or	r1, r2
+	mov.l   3f, r3
+	and	r3, r2
+	mov.l	r2, @r4
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+2:	.long	0x00000400
+3:	.long	0xffff7fff
+ENTRY(migor_sdram_enter_end)
+
+	.balign 4
+ENTRY(migor_sdram_leave_start)
+
+	/* SBSC: set auto-refresh mode */
+	mov.l	1f, r4
+	mov.l	@r4, r0
+	mov.l   4f, r1
+	and	r1, r0
+	mov.l	r0, @r4
+	mov.l	6f, r4
+	mov.l	8f, r0
+	mov.l	@r4, r1
+	mov	#-1, r4
+	add	r4, r1
+	or	r1, r0
+	mov.l	7f, r1
+	mov.l	r0, @r1
+
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+4:	.long	0xfffffbff
+6:	.long   0xfe40001c /* RTCOR */
+7:	.long   0xfe400018 /* RTCNT */
+8:	.long   0xa55a0000
+ENTRY(migor_sdram_leave_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-migor/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-migor/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
@@ -18,8 +19,6 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
 #include <media/ov772x.h>
@@ -27,7 +26,7 @@
 #include <asm/clock.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
-#include <asm/sh_keysc.h>
+#include <asm/suspend.h>
 #include <mach/migor.h>
 #include <cpu/sh7722.h>
 
@@ -390,17 +389,25 @@ static struct platform_device migor_ceu_
 	},
 };
 
-struct spi_gpio_platform_data sdcard_cn9_platform_data = {
-	.sck = GPIO_PTD0,
-	.mosi = GPIO_PTD1,
-	.miso = GPIO_PTD2,
-	.num_chipselect = 1,
+static struct resource sdhi_cn9_resources[] = {
+	[0] = {
+		.name	= "SDHI",
+		.start	= 0x04ce0000,
+		.end	= 0x04ce01ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 101,
+		.flags  = IORESOURCE_IRQ,
+	},
 };
 
-static struct platform_device sdcard_cn9_device = {
-	.name		= "spi_gpio",
-	.dev	= {
-		.platform_data	= &sdcard_cn9_platform_data,
+static struct platform_device sdhi_cn9_device = {
+	.name		= "sh_mobile_sdhi",
+	.num_resources	= ARRAY_SIZE(sdhi_cn9_resources),
+	.resource	= sdhi_cn9_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI,
 	},
 };
 
@@ -425,23 +432,27 @@ static struct i2c_board_info migor_i2c_c
 
 static struct ov772x_camera_info ov7725_info = {
 	.buswidth	= SOCAM_DATAWIDTH_8,
-	.link = {
-		.power		= ov7725_power,
-		.board_info	= &migor_i2c_camera[0],
-		.i2c_adapter_id	= 0,
-		.module_name	= "ov772x",
-	},
+};
+
+static struct soc_camera_link ov7725_link = {
+	.power		= ov7725_power,
+	.board_info	= &migor_i2c_camera[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "ov772x",
+	.priv		= &ov7725_info,
 };
 
 static struct tw9910_video_info tw9910_info = {
 	.buswidth	= SOCAM_DATAWIDTH_8,
 	.mpout		= TW9910_MPO_FIELD,
-	.link = {
-		.power		= tw9910_power,
-		.board_info	= &migor_i2c_camera[1],
-		.i2c_adapter_id	= 0,
-		.module_name	= "tw9910",
-	}
+};
+
+static struct soc_camera_link tw9910_link = {
+	.power		= tw9910_power,
+	.board_info	= &migor_i2c_camera[1],
+	.i2c_adapter_id	= 0,
+	.module_name	= "tw9910",
+	.priv		= &tw9910_info,
 };
 
 static struct platform_device migor_camera[] = {
@@ -449,13 +460,13 @@ static struct platform_device migor_came
 		.name	= "soc-camera-pdrv",
 		.id	= 0,
 		.dev	= {
-			.platform_data = &ov7725_info.link,
+			.platform_data = &ov7725_link,
 		},
 	}, {
 		.name	= "soc-camera-pdrv",
 		.id	= 1,
 		.dev	= {
-			.platform_data = &tw9910_info.link,
+			.platform_data = &tw9910_link,
 		},
 	},
 };
@@ -467,23 +478,24 @@ static struct platform_device *migor_dev
 	&migor_ceu_device,
 	&migor_nor_flash_device,
 	&migor_nand_flash_device,
-	&sdcard_cn9_device,
+	&sdhi_cn9_device,
 	&migor_camera[0],
 	&migor_camera[1],
 };
 
-static struct spi_board_info migor_spi_devices[] = {
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 5000000,
-		.chip_select = 0,
-		.controller_data = (void *) GPIO_PTD5,
-	},
-};
+extern char migor_sdram_enter_start;
+extern char migor_sdram_enter_end;
+extern char migor_sdram_leave_start;
+extern char migor_sdram_leave_end;
 
 static int __init migor_devices_setup(void)
 {
-
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&migor_sdram_enter_start,
+					&migor_sdram_enter_end,
+					&migor_sdram_leave_start,
+					&migor_sdram_leave_end);
 #ifdef CONFIG_PM
 	/* Let D11 LED show STATUS0 */
 	gpio_request(GPIO_FN_STATUS0, NULL);
@@ -525,6 +537,16 @@ static int __init migor_devices_setup(vo
 	gpio_request(GPIO_PTA1, NULL);
 	gpio_direction_input(GPIO_PTA1);
 
+	/* SDHI */
+	gpio_request(GPIO_FN_SDHICD, NULL);
+	gpio_request(GPIO_FN_SDHIWP, NULL);
+	gpio_request(GPIO_FN_SDHID3, NULL);
+	gpio_request(GPIO_FN_SDHID2, NULL);
+	gpio_request(GPIO_FN_SDHID1, NULL);
+	gpio_request(GPIO_FN_SDHID0, NULL);
+	gpio_request(GPIO_FN_SDHICMD, NULL);
+	gpio_request(GPIO_FN_SDHICLK, NULL);
+
 	/* Touch Panel */
 	gpio_request(GPIO_FN_IRQ6, NULL);
 
@@ -612,9 +634,6 @@ static int __init migor_devices_setup(vo
 	i2c_register_board_info(0, migor_i2c_devices,
 				ARRAY_SIZE(migor_i2c_devices));
 
-	spi_register_board_info(migor_spi_devices,
-				ARRAY_SIZE(migor_spi_devices));
-
 	return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
 }
 arch_initcall(migor_devices_setup);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-r2d/irq.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/irq.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-r2d/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-r2d/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -116,7 +116,7 @@ static unsigned char irl2irq[R2D_NR_IRL]
 
 int rts7751r2d_irq_demux(int irq)
 {
-	if (irq >= R2D_NR_IRL || !irl2irq[irq])
+	if (irq >= R2D_NR_IRL || irq < 0 || !irl2irq[irq])
 		return irq;
 
 	return irl2irq[irq];
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7722/irq.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/irq.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7722/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,15 +16,17 @@
 #include <asm/io.h>
 #include <mach-se/mach/se7722.h>
 
+unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
+
 static void disable_se7722_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
 	ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
 }
 
 static void enable_se7722_irq(unsigned int irq)
 {
-	unsigned int bit = irq - SE7722_FPGA_IRQ_BASE;
+	unsigned int bit = (unsigned int)get_irq_chip_data(irq);
 	ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
 }
 
@@ -38,18 +40,15 @@ static struct irq_chip se7722_irq_chip _
 static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned short intv = ctrl_inw(IRQ01_STS);
-	struct irq_desc *ext_desc;
-	unsigned int ext_irq = SE7722_FPGA_IRQ_BASE;
+	unsigned int ext_irq = 0;
 
 	intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
 
-	while (intv) {
-		if (intv & 1) {
-			ext_desc = irq_desc + ext_irq;
-			handle_level_irq(ext_irq, ext_desc);
-		}
-		intv >>= 1;
-		ext_irq++;
+	for (; intv; intv >>= 1, ext_irq++) {
+		if (!(intv & 1))
+			continue;
+
+		generic_handle_irq(se7722_fpga_irq[ext_irq]);
 	}
 }
 
@@ -58,16 +57,24 @@ static void se7722_irq_demux(unsigned in
  */
 void __init init_se7722_IRQ(void)
 {
-	int i;
+	int i, irq;
 
 	ctrl_outw(0, IRQ01_MASK);       /* disable all irqs */
 	ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
 
-	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++)
-		set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i,
+	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
+		irq = create_irq();
+		if (irq < 0)
+			return;
+		se7722_fpga_irq[i] = irq;
+
+		set_irq_chip_and_handler_name(se7722_fpga_irq[i],
 					      &se7722_irq_chip,
 					      handle_level_irq, "level");
 
+		set_irq_chip_data(se7722_fpga_irq[i], (void *)i);
+	}
+
 	set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
 	set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7722/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7722/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7722/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/smc91x.h>
 #include <mach-se/mach/se7722.h>
 #include <mach-se/mach/mrshpc.h>
@@ -21,7 +22,6 @@
 #include <asm/clock.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
-#include <asm/sh_keysc.h>
 #include <cpu/sh7722.h>
 
 /* Heartbeat */
@@ -60,8 +60,7 @@ static struct resource smc91x_eth_resour
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = SMC_IRQ,
-		.end    = SMC_IRQ,
+		/* Filled in later */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -90,8 +89,7 @@ static struct resource cf_ide_resources[
 		.flags  = IORESOURCE_IO,
 	},
 	[2] = {
-		.start  = MRSHPC_IRQ0,
-		.end    = MRSHPC_IRQ0,
+		/* Filled in later */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
@@ -153,6 +151,14 @@ static struct platform_device *se7722_de
 static int __init se7722_devices_setup(void)
 {
 	mrshpc_setup_windows();
+
+	/* Wire-up dynamic vectors */
+	cf_ide_resources[2].start = cf_ide_resources[2].end =
+		se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0];
+
+	smc91x_eth_resources[1].start = smc91x_eth_resources[1].end =
+		se7722_fpga_irq[SE7722_FPGA_IRQ_SMC];
+
 	return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
 }
 device_initcall(se7722_devices_setup);
@@ -193,6 +199,5 @@ static void __init se7722_setup(char **c
 static struct sh_machine_vector mv_se7722 __initmv = {
 	.mv_name                = "Solution Engine 7722" ,
 	.mv_setup               = se7722_setup ,
-	.mv_nr_irqs		= SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR,
 	.mv_init_irq		= init_se7722_IRQ,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -7,4 +7,4 @@
 #
 #
 
-obj-y	 := setup.o irq.o
\ No newline at end of file
+obj-y	 := setup.o irq.o sdram.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/sdram.S linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/sdram.S
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/sdram.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/sdram.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * MS7724SE sdram self/auto-refresh setup code
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+	.balign 4
+ENTRY(ms7724se_sdram_enter_start)
+
+	/* DBSC: put memory in self-refresh mode */
+
+	ED 0xFD000010, 0x00000000 /* DBEN */
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ms7724se_sdram_enter_end)
+
+	.balign 4
+ENTRY(ms7724se_sdram_leave_start)
+
+	/* DBSC: put memory in auto-refresh mode */
+
+	ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+	WAIT 1
+	ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+	ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+	ED 0xFD000010, 0x00000001 /* DBEN */
+	ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+	rts
+	 nop
+
+ENTRY(ms7724se_sdram_leave_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/setup.c linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/boards/mach-se/7724/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/mach-se/7724/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/smc91x.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
@@ -27,7 +28,7 @@
 #include <asm/heartbeat.h>
 #include <asm/sh_eth.h>
 #include <asm/clock.h>
-#include <asm/sh_keysc.h>
+#include <asm/suspend.h>
 #include <cpu/sh7724.h>
 #include <mach-se/mach/se7724.h>
 
@@ -313,6 +314,9 @@ static struct platform_device fsi_device
 	.dev	= {
 		.platform_data	= &fsi_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
+	},
 };
 
 /* KEYSC in SoC (Needs SW33-2 set to ON) */
@@ -448,6 +452,52 @@ static struct platform_device sh7724_usb
 	.resource	= sh7724_usb1_gadget_resources,
 };
 
+static struct resource sdhi0_cn7_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start  = 0x04ce0000,
+		.end    = 0x04ce01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 101,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_cn7_device = {
+	.name           = "sh_mobile_sdhi",
+	.id		= 0,
+	.num_resources  = ARRAY_SIZE(sdhi0_cn7_resources),
+	.resource       = sdhi0_cn7_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI0,
+	},
+};
+
+static struct resource sdhi1_cn8_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start  = 0x04cf0000,
+		.end    = 0x04cf01ff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 24,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_cn8_device = {
+	.name           = "sh_mobile_sdhi",
+	.id		= 1,
+	.num_resources  = ARRAY_SIZE(sdhi1_cn8_resources),
+	.resource       = sdhi1_cn8_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_SDHI1,
+	},
+};
+
 static struct platform_device *ms7724se_devices[] __initdata = {
 	&heartbeat_device,
 	&smc91x_eth_device,
@@ -460,6 +510,15 @@ static struct platform_device *ms7724se_
 	&sh7724_usb0_host_device,
 	&sh7724_usb1_gadget_device,
 	&fsi_device,
+	&sdhi0_cn7_device,
+	&sdhi1_cn8_device,
+};
+
+/* I2C device */
+static struct i2c_board_info i2c0_devices[] = {
+	{
+		I2C_BOARD_INFO("ak4642", 0x12),
+	},
 };
 
 #define EEPROM_OP   0xBA206000
@@ -474,7 +533,7 @@ static int __init sh_eth_is_eeprom_ready
 	while (t--) {
 		if (!ctrl_inw(EEPROM_STAT))
 			return 1;
-		cpu_relax();
+		udelay(1);
 	}
 
 	printk(KERN_ERR "ms7724se can not access to eeprom\n");
@@ -484,7 +543,7 @@ static int __init sh_eth_is_eeprom_ready
 static void __init sh_eth_init(void)
 {
 	int i;
-	u16 mac[3];
+	u16 mac;
 
 	/* check EEPROM status */
 	if (!sh_eth_is_eeprom_ready())
@@ -498,16 +557,10 @@ static void __init sh_eth_init(void)
 		if (!sh_eth_is_eeprom_ready())
 			return;
 
-		mac[i] = ctrl_inw(EEPROM_DATA);
-		mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */
+		mac = ctrl_inw(EEPROM_DATA);
+		sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
+		sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
 	}
-
-	/* reset sh-eth */
-	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
-
-	/* set MAC addr */
-	ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR);
-	ctrl_outl((mac[2]), SH_ETH_MALR);
 }
 
 #define SW4140    0xBA201000
@@ -524,11 +577,32 @@ static void __init sh_eth_init(void)
 #define SW41_G    0x4000
 #define SW41_H    0x8000
 
+extern char ms7724se_sdram_enter_start;
+extern char ms7724se_sdram_enter_end;
+extern char ms7724se_sdram_leave_start;
+extern char ms7724se_sdram_leave_end;
+
+
+static int __init arch_setup(void)
+{
+	/* enable I2C device */
+	i2c_register_board_info(0, i2c0_devices,
+				ARRAY_SIZE(i2c0_devices));
+	return 0;
+}
+arch_initcall(arch_setup);
+
 static int __init devices_setup(void)
 {
 	u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
 	struct clk *fsia_clk;
 
+	/* register board specific self-refresh code */
+	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+					&ms7724se_sdram_enter_start,
+					&ms7724se_sdram_enter_end,
+					&ms7724se_sdram_leave_start,
+					&ms7724se_sdram_leave_end);
 	/* Reset Release */
 	ctrl_outw(ctrl_inw(FPGA_OUT) &
 		  ~((1 << 1)  | /* LAN */
@@ -698,6 +772,26 @@ static int __init devices_setup(void)
 	clk_set_rate(&fsimcka_clk, 11000);
 	clk_put(fsia_clk);
 
+	/* SDHI0 connected to cn7 */
+	gpio_request(GPIO_FN_SDHI0CD, NULL);
+	gpio_request(GPIO_FN_SDHI0WP, NULL);
+	gpio_request(GPIO_FN_SDHI0D3, NULL);
+	gpio_request(GPIO_FN_SDHI0D2, NULL);
+	gpio_request(GPIO_FN_SDHI0D1, NULL);
+	gpio_request(GPIO_FN_SDHI0D0, NULL);
+	gpio_request(GPIO_FN_SDHI0CMD, NULL);
+	gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
+	/* SDHI1 connected to cn8 */
+	gpio_request(GPIO_FN_SDHI1CD, NULL);
+	gpio_request(GPIO_FN_SDHI1WP, NULL);
+	gpio_request(GPIO_FN_SDHI1D3, NULL);
+	gpio_request(GPIO_FN_SDHI1D2, NULL);
+	gpio_request(GPIO_FN_SDHI1D1, NULL);
+	gpio_request(GPIO_FN_SDHI1D0, NULL);
+	gpio_request(GPIO_FN_SDHI1CMD, NULL);
+	gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
 	/*
 	 * enable SH-Eth
 	 *
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boards/Makefile linux-libre-2.6.33-gnu1/arch/sh/boards/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boards/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boards/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,6 @@
 #
 # Specific board support, not covered by a mach group.
 #
-obj-$(CONFIG_SH_AP325RXA)	+= board-ap325rxa.o
 obj-$(CONFIG_SH_MAGIC_PANEL_R2)	+= board-magicpanelr2.o
 obj-$(CONFIG_SH_SH7785LCR)	+= board-sh7785lcr.o
 obj-$(CONFIG_SH_URQUELL)	+= board-urquell.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boot/compressed/misc.c linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/misc.c
--- linux-libre-2.6.32-gnu1/arch/sh/boot/compressed/misc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,7 +131,7 @@ void decompress_kernel(void)
 #ifdef CONFIG_SUPERH64
 	output_addr = (CONFIG_MEMORY_START + 0x2000);
 #else
-	output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
+	output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
 #ifdef CONFIG_29BIT
 	output_addr |= P2SEG;
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boot/romimage/head.S linux-libre-2.6.33-gnu1/arch/sh/boot/romimage/head.S
--- linux-libre-2.6.32-gnu1/arch/sh/boot/romimage/head.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boot/romimage/head.S	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,44 @@
  */
 
 .text
+	#include <asm/page.h>
+
 	.global	romstart
 romstart:
+	/* include board specific setup code */
 #include <mach/romimage.h>
+
+	/* copy the empty_zero_page contents to where vmlinux expects it */
+	mova	empty_zero_page_src, r0
+	mov.l	empty_zero_page_dst, r1
+	mov	#(PAGE_SHIFT - 4), r4
+	mov	#1, r3
+	shld	r4, r3 /* r3 = PAGE_SIZE / 16 */
+
+1:
+	mov.l	@r0, r4
+	mov.l	@(4, r0), r5
+	mov.l	@(8, r0), r6
+	mov.l	@(12, r0), r7
+	add	#16,r0
+	mov.l	r4, @r1
+	mov.l	r5, @(4, r1)
+	mov.l	r6, @(8, r1)
+	mov.l	r7, @(12, r1)
+	dt	r3
+	add	#16,r1
+	bf	1b
+
+	/* jump to the zImage entry point located after the zero page data */
+	mov	#PAGE_SHIFT, r4
+	mov	#1, r1
+	shld	r4, r1
+	mova	empty_zero_page_src, r0
+	add	r1, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+empty_zero_page_dst:
+	.long	_text
+empty_zero_page_src:
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/boot/romimage/Makefile linux-libre-2.6.33-gnu1/arch/sh/boot/romimage/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/boot/romimage/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/boot/romimage/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,16 +4,22 @@
 # create an image suitable for burning to flash from zImage
 #
 
-targets		:= vmlinux head.o
+targets		:= vmlinux head.o zeropage.bin piggy.o
 
 OBJECTS = $(obj)/head.o
-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart \
+		   -T $(obj)/../../kernel/vmlinux.lds
 
 $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
 
+OBJCOPYFLAGS += -j .empty_zero_page
+
+$(obj)/zeropage.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
 LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE
 	$(call if_changed,ld)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/ap325rxa_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/ap325rxa_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/ap325rxa_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/ap325rxa_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Fri Sep 25 11:22:50 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:10:59 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -99,6 +102,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -142,14 +147,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -205,6 +237,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -262,7 +293,6 @@ CONFIG_SH_AP325RXA=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -418,9 +448,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -550,6 +577,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=4
@@ -559,9 +590,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -572,6 +606,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -664,11 +699,11 @@ CONFIG_SMSC911X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -688,6 +723,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -782,7 +818,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -796,7 +831,10 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 CONFIG_SPI_GPIO=y
+# CONFIG_SPI_SH_MSIOF is not set
 # CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -854,11 +892,13 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -866,6 +906,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -882,6 +924,8 @@ CONFIG_VIDEO_MEDIA=y
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -901,6 +945,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -908,10 +953,13 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
 # CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
 # CONFIG_SOC_CAMERA_TW9910 is not set
 CONFIG_SOC_CAMERA_PLATFORM=y
 CONFIG_SOC_CAMERA_OV772X=y
+# CONFIG_SOC_CAMERA_OV9640 is not set
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 # CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
@@ -996,6 +1044,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1027,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1055,7 +1105,9 @@ CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1248,7 +1300,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1265,7 +1317,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1274,7 +1325,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/cayman_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/cayman_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/cayman_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/cayman_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Thu Jun 18 12:21:54 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:14:50 2010
 #
 CONFIG_SUPERH=y
 # CONFIG_SUPERH32 is not set
@@ -14,11 +14,13 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -28,7 +30,10 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -39,6 +44,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 CONFIG_POSIX_MQUEUE=y
@@ -50,11 +61,13 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -85,24 +98,32 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -115,7 +136,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -123,14 +144,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -178,8 +226,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
 #
@@ -255,13 +302,13 @@ CONFIG_PREEMPT=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00400000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_CMDLINE_OVERWRITE is not set
+# CONFIG_CMDLINE_EXTEND is not set
 
 #
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -330,6 +377,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -359,14 +407,11 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -379,6 +424,7 @@ CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -395,6 +441,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -405,6 +455,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -412,6 +463,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -462,8 +514,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -495,7 +550,10 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -507,7 +565,11 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -546,6 +608,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
@@ -565,6 +628,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -590,12 +654,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -609,6 +671,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -618,6 +681,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -682,6 +746,7 @@ CONFIG_HW_RANDOM=y
 CONFIG_DEVPORT=y
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -710,6 +775,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -721,11 +787,6 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -734,20 +795,26 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -771,6 +838,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -797,6 +865,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -808,9 +877,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -837,17 +905,20 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -939,7 +1010,6 @@ CONFIG_LOGO_SUPERH_CLUT224=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
@@ -1002,8 +1072,10 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1067,7 +1139,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y
 CONFIG_ROMFS_ON_BLOCK=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1120,6 +1191,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1155,21 +1227,25 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
 # CONFIG_BOOT_TRACER is not set
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
@@ -1180,11 +1256,9 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
-# CONFIG_KMEMCHECK is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_DEBUG_BOOTMEM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
+# CONFIG_DWARF_UNWINDER is not set
 # CONFIG_SH_NO_BSS_INIT is not set
 CONFIG_SH64_SR_WATCH=y
 
@@ -1194,13 +1268,16 @@ CONFIG_SH64_SR_WATCH=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
@@ -1232,11 +1309,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1299,5 +1378,6 @@ CONFIG_CRC32=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
 CONFIG_GENERIC_ATOMIC64=y
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/dreamcast_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/dreamcast_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/dreamcast_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/dreamcast_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:56:07 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:17:35 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -97,6 +100,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -143,14 +148,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -232,8 +264,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -294,9 +324,9 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 CONFIG_NR_DMA_CHANNELS_BOOL=y
 CONFIG_NR_DMA_CHANNELS=9
@@ -338,7 +368,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
@@ -348,7 +377,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 pa
 #
 CONFIG_MAPLE=y
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -443,9 +471,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -478,6 +503,10 @@ CONFIG_GDROM=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -579,6 +608,7 @@ CONFIG_8139TOO=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -586,8 +616,9 @@ CONFIG_8139TOO=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -600,6 +631,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -609,6 +641,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -655,6 +688,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -734,6 +768,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -883,6 +918,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -981,10 +1017,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -997,7 +1034,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1006,7 +1042,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/ecovec24_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/ecovec24_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:45:39 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:20:36 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -99,6 +102,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -143,14 +148,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -204,8 +236,9 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -230,8 +263,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -265,7 +296,6 @@ CONFIG_SH_ECOVEC=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -420,9 +450,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -552,6 +579,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -562,9 +593,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -575,6 +609,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -669,11 +704,12 @@ CONFIG_SH_ETH=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -702,6 +738,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -810,7 +847,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -824,7 +860,10 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_SH_MSIOF is not set
 # CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -882,11 +921,13 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -894,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -910,6 +953,8 @@ CONFIG_VIDEO_MEDIA=y
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -930,6 +975,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_CPIA2 is not set
@@ -939,10 +985,13 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
 # CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
 # CONFIG_SOC_CAMERA_TW9910 is not set
 # CONFIG_SOC_CAMERA_PLATFORM is not set
 # CONFIG_SOC_CAMERA_OV772X is not set
+# CONFIG_SOC_CAMERA_OV9640 is not set
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 # CONFIG_V4L_USB_DRIVERS is not set
 CONFIG_RADIO_ADAPTERS=y
@@ -952,6 +1001,7 @@ CONFIG_RADIO_ADAPTERS=y
 # CONFIG_RADIO_SI470X is not set
 # CONFIG_USB_MR800 is not set
 # CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_TEF6862 is not set
 # CONFIG_DAB is not set
 
 #
@@ -1177,6 +1227,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1208,6 +1259,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1236,7 +1288,9 @@ CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1430,7 +1484,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1448,7 +1502,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1457,7 +1510,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/ecovec24-romimage_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24-romimage_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/ecovec24-romimage_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/ecovec24-romimage_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:56:41 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:18:17 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -120,6 +124,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -142,14 +147,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -203,8 +235,9 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -264,7 +295,6 @@ CONFIG_SH_ECOVEC=y
 #
 # CONFIG_SH_TIMER_TMU is not set
 CONFIG_SH_TIMER_CMT=y
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -406,7 +436,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -432,6 +468,10 @@ CONFIG_EXTRA_FIRMWARE=""
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -526,11 +566,12 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -559,6 +600,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -652,7 +694,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -707,16 +748,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -867,6 +911,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -979,7 +1024,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -997,7 +1042,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1006,7 +1050,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/edosk7705_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/edosk7705_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/edosk7705_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/edosk7705_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:57:13 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:24:26 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -53,6 +54,7 @@ CONFIG_KERNEL_GZIP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -66,7 +68,6 @@ CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PRINTK is not set
@@ -81,6 +82,7 @@ CONFIG_EMBEDDED=y
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -98,6 +100,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -109,6 +112,35 @@ CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -186,8 +218,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -359,6 +389,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -416,7 +447,6 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_PROC_FS is not set
 # CONFIG_SYSFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_NLS is not set
@@ -448,7 +478,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -456,7 +485,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/edosk7760_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/edosk7760_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/edosk7760_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/edosk7760_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:57:30 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:24:44 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +105,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -147,14 +152,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -230,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -278,9 +308,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 # CONFIG_SH_DMABRG is not set
@@ -320,7 +350,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x02000000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="mem=64M console=ttySC2,115200 root=/dev/nfs rw nfsroot=192.168.0.3:/scripts/filesys ip=192.168.0.4"
@@ -415,9 +444,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -534,6 +560,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -581,11 +611,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -605,6 +635,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -698,7 +729,6 @@ CONFIG_I2C_SH7760=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
@@ -727,15 +757,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1072,9 +1105,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1088,7 +1118,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/espt_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/espt_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/espt_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/espt_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:58:18 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:26:55 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -150,14 +155,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -237,8 +270,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -419,7 +450,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -498,7 +535,6 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -531,6 +567,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -629,11 +669,12 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -662,6 +703,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -745,6 +787,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1102,10 +1145,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1125,7 +1169,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1134,7 +1177,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/hp6xx_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/hp6xx_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/hp6xx_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/hp6xx_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 17:59:45 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:30:31 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -57,6 +58,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -92,6 +94,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -109,6 +112,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -130,14 +134,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -213,8 +244,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -261,8 +290,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -313,7 +342,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 #
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
@@ -363,6 +391,10 @@ CONFIG_EXTRA_FIRMWARE=""
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -432,6 +464,7 @@ CONFIG_PATA_PLATFORM=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -460,6 +493,7 @@ CONFIG_KEYBOARD_HP6XX=y
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
@@ -483,6 +517,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -550,6 +585,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -659,7 +695,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -684,6 +722,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -731,7 +770,6 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -813,10 +851,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -829,7 +868,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -838,7 +876,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/kfr2r09_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/kfr2r09_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/kfr2r09_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/kfr2r09_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Fri Sep 25 11:54:22 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:32:55 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -104,6 +107,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -148,14 +153,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -235,8 +268,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -270,7 +301,6 @@ CONFIG_SH_KFR2R09=y
 #
 # CONFIG_SH_TIMER_TMU is not set
 CONFIG_SH_TIMER_CMT=y
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -534,6 +564,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -562,6 +596,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -668,7 +703,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -723,16 +757,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -847,10 +884,12 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
-CONFIG_USB_CDC_COMPOSITE=y
+CONFIG_USB_CDC_COMPOSITE=m
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -875,6 +914,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -906,6 +946,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -926,7 +967,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -953,6 +996,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1027,7 +1071,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1045,7 +1089,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1054,7 +1097,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/kfr2r09-romimage_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/kfr2r09-romimage_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/kfr2r09-romimage_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/kfr2r09-romimage_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:01:48 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:31:09 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +105,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -119,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -133,6 +138,35 @@ CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -188,6 +222,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -212,8 +247,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -247,7 +280,6 @@ CONFIG_SH_KFR2R09=y
 #
 # CONFIG_SH_TIMER_TMU is not set
 CONFIG_SH_TIMER_CMT=y
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -429,6 +461,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -520,7 +553,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -575,16 +607,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -650,10 +685,12 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 CONFIG_USB_CDC_COMPOSITE=y
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -725,7 +762,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -743,7 +780,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -752,7 +788,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/landisk_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/landisk_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/landisk_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/landisk_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:05:49 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:35:31 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -94,6 +97,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -139,14 +144,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -222,8 +254,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -311,7 +341,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_OVERWRITE is not set
 # CONFIG_CMDLINE_EXTEND is not set
 
@@ -319,14 +348,12 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
@@ -461,9 +488,6 @@ CONFIG_ATALK=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -498,6 +522,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -618,8 +646,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -652,7 +683,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -733,6 +766,7 @@ CONFIG_8139CP=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -781,8 +815,13 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -806,6 +845,7 @@ CONFIG_USB_RTL8150=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -815,6 +855,7 @@ CONFIG_USB_RTL8150=m
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -933,6 +974,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1371,10 +1413,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1387,8 +1430,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1397,7 +1438,11 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/lboxre2_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/lboxre2_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/lboxre2_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/lboxre2_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:09:59 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:37:01 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -94,6 +97,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -139,14 +144,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -222,8 +254,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -311,7 +341,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1"
@@ -320,14 +349,12 @@ CONFIG_CMDLINE="console=ttySC1,115200 ro
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
-CONFIG_PCMCIA_DEBUG=y
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
@@ -459,9 +486,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -496,6 +520,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -558,8 +586,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -593,7 +624,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -648,15 +681,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -732,6 +766,7 @@ CONFIG_8139TOO_TUNE_TWISTER=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -780,8 +815,12 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -804,6 +843,7 @@ CONFIG_PCMCIA_PCNET=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -813,6 +853,7 @@ CONFIG_PCMCIA_PCNET=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -931,6 +972,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1020,7 +1062,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1195,10 +1239,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1211,8 +1256,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1221,7 +1264,11 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/magicpanelr2_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/magicpanelr2_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/magicpanelr2_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/magicpanelr2_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:10:49 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:37:42 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +64,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +104,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -120,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -146,14 +150,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -229,8 +260,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -283,8 +312,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -416,9 +445,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -534,6 +560,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -607,11 +637,11 @@ CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -631,6 +661,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -675,6 +706,7 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -766,6 +798,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -824,7 +857,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -898,7 +933,6 @@ CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -1072,9 +1106,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4430000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1088,7 +1119,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/microdev_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/microdev_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/microdev_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/microdev_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:14:35 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:40:41 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -98,6 +101,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -115,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -136,14 +141,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -225,8 +257,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -272,8 +302,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -312,7 +342,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/hda1"
@@ -412,9 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -443,6 +469,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -517,11 +547,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -616,6 +646,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -835,10 +866,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -851,7 +883,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -860,7 +891,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/migor_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/migor_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/migor_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/migor_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:17:41 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:41:41 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -100,6 +103,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -121,6 +125,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -147,14 +152,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -240,8 +272,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -277,7 +307,6 @@ CONFIG_SH_MIGOR_QVGA=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -433,10 +462,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -554,6 +579,10 @@ CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -563,9 +592,11 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -646,11 +677,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -670,6 +701,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -776,7 +808,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -831,16 +862,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -857,6 +891,8 @@ CONFIG_VIDEO_MEDIA=y
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -876,6 +912,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -883,10 +920,13 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
 # CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
 CONFIG_SOC_CAMERA_TW9910=y
 # CONFIG_SOC_CAMERA_PLATFORM is not set
 CONFIG_SOC_CAMERA_OV772X=y
+# CONFIG_SOC_CAMERA_OV9640 is not set
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 # CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
@@ -1009,10 +1049,12 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
-CONFIG_USB_G_SERIAL=y
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1051,6 +1093,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1071,7 +1114,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1098,6 +1143,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1206,10 +1252,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1229,9 +1276,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1240,7 +1284,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/polaris_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/polaris_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/polaris_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/polaris_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:20:53 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 11:45:25 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +64,7 @@ CONFIG_AUDIT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +104,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -120,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -146,14 +150,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -225,12 +256,10 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -279,8 +308,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -409,7 +438,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -525,6 +560,10 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -595,11 +634,11 @@ CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -619,6 +658,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -657,7 +697,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 
 #
@@ -705,6 +744,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -764,7 +804,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -787,6 +829,7 @@ CONFIG_RTC_DRV_SH=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -833,7 +876,6 @@ CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -977,9 +1019,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4000150
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -993,7 +1032,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/r7780mp_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/r7780mp_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/r7780mp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/r7780mp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:24:31 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:16:13 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -110,6 +114,7 @@ CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -125,6 +130,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -135,6 +141,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -151,14 +158,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -245,8 +279,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -342,7 +374,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 ro
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -449,10 +480,6 @@ CONFIG_LLC=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -535,7 +562,6 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PCI is not set
-# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -573,6 +599,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -583,6 +613,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -590,6 +621,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -640,8 +672,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -675,7 +710,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -728,15 +765,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -813,6 +851,7 @@ CONFIG_8139TOO_8129=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
 # CONFIG_SC92031 is not set
@@ -862,8 +901,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -877,6 +917,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -886,6 +927,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -928,6 +970,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -1008,11 +1051,6 @@ CONFIG_I2C_HIGHLANDER=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -1021,7 +1059,6 @@ CONFIG_I2C_HIGHLANDER=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1065,6 +1102,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1103,6 +1141,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 CONFIG_THERMAL=y
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
@@ -1118,15 +1157,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1211,6 +1253,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1231,7 +1274,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1436,6 +1481,8 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -1462,6 +1509,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1498,9 +1546,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1514,7 +1559,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/r7785rp_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/r7785rp_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/r7785rp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/r7785rp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:29:23 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:19:35 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -32,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -67,6 +69,7 @@ CONFIG_AUDIT_TREE=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 CONFIG_RCU_TRACE=y
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -110,6 +114,7 @@ CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -126,6 +131,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -153,14 +159,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -248,13 +281,11 @@ CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
 # CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -289,7 +320,6 @@ CONFIG_SH_R7785RP=y
 # Timer and clock configuration
 #
 CONFIG_SH_TIMER_TMU=y
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -363,7 +393,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 ro
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
@@ -471,10 +500,6 @@ CONFIG_LLC=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -510,6 +535,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -520,6 +549,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -527,6 +557,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -577,8 +608,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -612,7 +646,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -665,15 +701,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -730,6 +767,7 @@ CONFIG_AX88796_93CX6=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
@@ -776,8 +814,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -791,6 +830,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -800,6 +840,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -844,6 +885,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -925,11 +967,6 @@ CONFIG_I2C_HIGHLANDER=y
 # CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -938,7 +975,6 @@ CONFIG_I2C_HIGHLANDER=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -969,6 +1005,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1011,6 +1048,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1050,6 +1088,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1064,16 +1103,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1211,6 +1253,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1231,7 +1274,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1463,6 +1508,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1499,8 +1545,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_4KSTACKS=y
@@ -1514,7 +1558,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/rsk7201_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/rsk7201_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/rsk7201_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/rsk7201_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:34:29 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:23:12 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -56,6 +57,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -97,6 +99,7 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -109,6 +112,7 @@ CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
@@ -117,6 +121,7 @@ CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -142,14 +147,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -224,7 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -433,6 +464,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -464,6 +499,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -540,6 +576,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -594,7 +631,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -618,6 +657,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -717,7 +757,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -741,7 +781,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -750,7 +789,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_BINARY_PRINTF=y
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/rsk7203_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/rsk7203_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/rsk7203_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/rsk7203_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:35:04 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:23:54 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -104,6 +106,7 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -111,11 +114,13 @@ CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
@@ -124,6 +129,7 @@ CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -149,14 +155,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -231,7 +264,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -424,9 +456,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -539,6 +568,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -610,11 +643,12 @@ CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -643,6 +677,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -743,6 +778,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 CONFIG_REGULATOR=y
@@ -910,6 +946,8 @@ CONFIG_LEDS_CLASS=y
 #
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_LT3593 is not set
 
 #
 # LED Triggers
@@ -955,7 +993,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -978,6 +1018,7 @@ CONFIG_RTC_DRV_SH=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1137,6 +1178,7 @@ CONFIG_DEBUG_OBJECTS=y
 # CONFIG_DEBUG_OBJECTS_SELFTEST is not set
 # CONFIG_DEBUG_OBJECTS_FREE is not set
 # CONFIG_DEBUG_OBJECTS_TIMERS is not set
+# CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1203,9 +1245,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xfffe8000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DUMP_CODE=y
@@ -1218,7 +1257,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_BINARY_PRINTF=y
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/rts7751r2d1_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2d1_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:36:25 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:25:36 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -95,6 +98,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -143,14 +148,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,8 +258,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -321,16 +351,14 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00010000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
+CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1"
 
 #
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -429,10 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -466,6 +490,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -482,6 +510,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -530,8 +559,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -565,7 +597,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -618,15 +652,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -704,6 +739,7 @@ CONFIG_8139TOO=y
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -752,8 +788,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -776,6 +814,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -785,6 +824,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -862,7 +902,10 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_SH_MSIOF is not set
 CONFIG_SPI_SH_SCI=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -915,10 +958,12 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1055,6 +1100,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1308,7 +1354,9 @@ CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1333,6 +1381,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1474,10 +1523,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1497,9 +1547,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1508,7 +1555,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/rts7751r2dplus_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2dplus_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:39:48 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:26:39 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -31,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -95,6 +98,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -143,14 +148,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,8 +258,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -321,16 +351,14 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00010000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
+CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1"
 
 #
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -429,10 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -552,6 +576,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -568,6 +596,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -616,8 +645,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -651,7 +683,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -704,15 +738,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
@@ -790,6 +825,7 @@ CONFIG_8139TOO=y
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -838,8 +874,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -862,6 +900,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -871,6 +910,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -948,7 +988,10 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_SH_MSIOF is not set
 CONFIG_SPI_SH_SCI=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -1001,10 +1044,12 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1141,6 +1186,7 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1394,7 +1440,9 @@ CONFIG_RTC_DRV_R9701=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1419,6 +1467,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1561,10 +1610,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1584,9 +1634,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1595,7 +1642,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sdk7780_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sdk7780_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sdk7780_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sdk7780_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:40:25 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:27:20 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -99,6 +102,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -119,6 +123,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -145,14 +150,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -239,8 +271,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -291,9 +321,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=12
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -339,7 +369,6 @@ CONFIG_CMDLINE="mem=128M console=tty0 co
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
@@ -347,7 +376,6 @@ CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
 CONFIG_PCMCIA_IOCTL=y
@@ -445,6 +473,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -515,9 +544,6 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -558,6 +584,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -663,8 +693,11 @@ CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -698,7 +731,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -753,15 +788,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -827,14 +863,20 @@ CONFIG_SMC91X=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NET_POCKET is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -861,6 +903,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 # CONFIG_NETPOLL_TRAP is not set
 CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -870,6 +913,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -922,6 +966,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -1009,6 +1054,7 @@ CONFIG_SSB_DRIVER_PCICORE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1534,8 +1580,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1549,7 +1593,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7206_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7206_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7206_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7206_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:45:28 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:30:00 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -30,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -64,6 +65,7 @@ CONFIG_AUDIT_TREE=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 CONFIG_RCU_TRACE=y
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -115,6 +117,7 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -122,11 +125,13 @@ CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
@@ -135,6 +140,7 @@ CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -156,19 +162,47 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -243,7 +277,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -438,9 +471,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -551,6 +581,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -605,11 +639,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -685,6 +719,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -738,7 +773,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -762,6 +799,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -911,6 +949,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -947,7 +986,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_STACK_DEBUG is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DUMP_CODE=y
@@ -960,7 +998,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7343_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7343_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7343_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7343_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:46:55 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:30:41 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -99,6 +102,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -117,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -126,6 +131,7 @@ CONFIG_HAVE_DMA_API_DEBUG=y
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -142,14 +148,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -228,8 +261,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -263,7 +294,6 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -413,9 +443,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -525,6 +552,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -585,8 +616,8 @@ CONFIG_MII=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -628,6 +659,7 @@ CONFIG_USB_NET_DM9601=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -724,7 +756,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -753,15 +784,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1173,10 +1207,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1189,9 +1224,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1200,7 +1232,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7619_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7619_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7619_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7619_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:50:05 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:34:15 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -54,6 +55,7 @@ CONFIG_KERNEL_GZIP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -84,6 +86,7 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -95,11 +98,13 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -120,14 +125,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -201,7 +233,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -401,6 +432,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -432,6 +467,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -508,6 +544,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -575,6 +612,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -661,10 +699,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -677,7 +716,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -685,7 +723,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7705_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7705_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7705_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7705_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:50:52 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:34:37 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -59,6 +60,7 @@ CONFIG_KERNEL_GZIP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -94,6 +96,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -111,6 +114,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -136,14 +140,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -219,8 +250,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -403,9 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -510,6 +536,10 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -564,11 +594,11 @@ CONFIG_STNIC=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -598,6 +628,7 @@ CONFIG_SLHC=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -625,6 +656,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -696,6 +728,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -765,6 +798,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -809,7 +843,6 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_SYSFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
@@ -877,10 +910,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -893,7 +927,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -901,7 +934,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7712_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7712_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7712_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7712_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:53:32 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:44:56 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +61,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -95,6 +97,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -113,6 +116,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -138,14 +142,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -221,8 +252,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -452,9 +481,6 @@ CONFIG_NET_SCH_FIFO=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -565,6 +591,10 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -675,11 +705,11 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -757,6 +787,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -888,7 +919,6 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -1021,7 +1051,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1035,7 +1064,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7721_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7721_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7721_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7721_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:57:11 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:46:58 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -100,6 +102,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -118,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -143,14 +147,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,8 +257,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -457,9 +486,6 @@ CONFIG_NET_SCH_FIFO=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -570,6 +596,10 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -642,8 +672,8 @@ CONFIG_NETDEVICES=y
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -672,6 +702,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -765,6 +796,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1029,7 +1061,6 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -1186,7 +1217,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1200,7 +1230,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7722_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7722_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7722_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7722_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:57:41 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 13:49:15 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +105,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -122,6 +126,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -149,14 +154,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -248,8 +280,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -284,7 +314,6 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -436,9 +465,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -467,6 +493,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -560,11 +590,11 @@ CONFIG_SMC91X=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -584,6 +614,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -622,6 +653,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -694,6 +726,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -774,7 +807,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -906,7 +941,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -924,8 +959,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -934,7 +967,11 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7724_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7724_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7724_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7724_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Fri Sep 25 11:50:59 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:36:56 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -62,6 +64,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -99,6 +102,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -142,14 +147,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -205,6 +237,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -229,8 +262,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -265,7 +296,6 @@ CONFIG_SH_7724_SOLUTION_ENGINE=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -279,8 +309,8 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=12
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -423,9 +453,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -555,6 +582,10 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -565,9 +596,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -578,6 +612,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -672,11 +707,12 @@ CONFIG_SMC91X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -705,6 +741,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -813,7 +850,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -827,7 +863,10 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=y
 # CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_SH_MSIOF is not set
 # CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -885,11 +924,13 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
@@ -897,6 +938,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -913,6 +956,8 @@ CONFIG_VIDEO_MEDIA=m
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -932,6 +977,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -940,10 +986,13 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
 # CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
 # CONFIG_SOC_CAMERA_TW9910 is not set
 # CONFIG_SOC_CAMERA_PLATFORM is not set
 CONFIG_SOC_CAMERA_OV772X=y
+# CONFIG_SOC_CAMERA_OV9640 is not set
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 CONFIG_V4L_USB_DRIVERS=y
 # CONFIG_USB_VIDEO_CLASS is not set
@@ -961,6 +1010,7 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_GSPCA_OV519 is not set
 # CONFIG_USB_GSPCA_OV534 is not set
 # CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
 # CONFIG_USB_GSPCA_PAC7311 is not set
 # CONFIG_USB_GSPCA_SN9C20X is not set
 # CONFIG_USB_GSPCA_SONIXB is not set
@@ -974,6 +1024,7 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_GSPCA_SQ905 is not set
 # CONFIG_USB_GSPCA_SQ905C is not set
 # CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
 # CONFIG_USB_GSPCA_SUNPLUS is not set
 # CONFIG_USB_GSPCA_T613 is not set
 # CONFIG_USB_GSPCA_TV8532 is not set
@@ -1110,9 +1161,11 @@ CONFIG_SND_SOC_WM_HUBS=m
 CONFIG_SND_SOC_AD1836=m
 CONFIG_SND_SOC_AD1938=m
 CONFIG_SND_SOC_AD73311=m
+CONFIG_SND_SOC_ADS117X=m
 CONFIG_SND_SOC_AK4104=m
 CONFIG_SND_SOC_AK4535=m
 CONFIG_SND_SOC_AK4642=m
+CONFIG_SND_SOC_AK4671=m
 CONFIG_SND_SOC_CS4270=m
 CONFIG_SND_SOC_L3=m
 CONFIG_SND_SOC_PCM3008=m
@@ -1121,11 +1174,14 @@ CONFIG_SND_SOC_SSM2602=m
 CONFIG_SND_SOC_TLV320AIC23=m
 CONFIG_SND_SOC_TLV320AIC26=m
 CONFIG_SND_SOC_TLV320AIC3X=m
+CONFIG_SND_SOC_TLV320DAC33=m
 CONFIG_SND_SOC_UDA134X=m
 CONFIG_SND_SOC_UDA1380=m
 CONFIG_SND_SOC_WM8510=m
 CONFIG_SND_SOC_WM8523=m
 CONFIG_SND_SOC_WM8580=m
+CONFIG_SND_SOC_WM8711=m
+CONFIG_SND_SOC_WM8727=m
 CONFIG_SND_SOC_WM8728=m
 CONFIG_SND_SOC_WM8731=m
 CONFIG_SND_SOC_WM8750=m
@@ -1143,6 +1199,7 @@ CONFIG_SND_SOC_WM8990=m
 CONFIG_SND_SOC_WM8993=m
 CONFIG_SND_SOC_WM9081=m
 CONFIG_SND_SOC_MAX9877=m
+CONFIG_SND_SOC_TPA6130A2=m
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
@@ -1316,10 +1373,12 @@ CONFIG_USB_ETH_RNDIS=y
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
 # CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
 CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1345,6 +1404,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1376,6 +1436,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1404,7 +1465,9 @@ CONFIG_RTC_DRV_PCF8563=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1597,7 +1660,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1614,7 +1677,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1623,7 +1685,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7750_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7750_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7750_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7750_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 18:58:58 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:39:10 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -95,6 +98,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -113,6 +117,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -138,14 +143,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -221,8 +253,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -307,7 +337,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_OVERWRITE is not set
 # CONFIG_CMDLINE_EXTEND is not set
 
@@ -406,9 +435,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -513,6 +539,10 @@ CONFIG_MTD_ROM=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -615,11 +645,11 @@ CONFIG_STNIC=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -726,6 +756,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -785,6 +816,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -914,10 +946,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -930,7 +963,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -939,7 +971,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7751_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7751_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7751_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7751_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:01:41 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:39:56 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +62,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -98,6 +101,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -116,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -141,14 +146,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -224,8 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -311,7 +341,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00010000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC1,38400"
@@ -430,9 +459,6 @@ CONFIG_IP_NF_QUEUE=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -537,6 +563,10 @@ CONFIG_MTD_RAM=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
@@ -591,11 +621,11 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -693,6 +723,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -754,6 +785,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -863,10 +895,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -879,7 +912,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -888,7 +920,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/se7780_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/se7780_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/se7780_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/se7780_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:03:59 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:40:32 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -92,6 +95,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -110,6 +114,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -136,14 +141,41 @@ CONFIG_BLK_DEV_BSG=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -222,8 +254,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -313,7 +343,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 ro
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -401,9 +430,6 @@ CONFIG_IPV6=y
 # CONFIG_BT is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -517,6 +543,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -574,8 +604,11 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -608,7 +641,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -642,6 +677,8 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_EFAR is not set
 # CONFIG_ATA_GENERIC is not set
 # CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
 # CONFIG_PATA_HPT3X3 is not set
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_JMICRON is not set
@@ -650,14 +687,15 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
 # CONFIG_PATA_NS87410 is not set
 # CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
@@ -748,14 +786,16 @@ CONFIG_NET_PCI=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -774,6 +814,7 @@ CONFIG_WLAN=y
 # CONFIG_NET_FC is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -783,6 +824,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -883,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1149,6 +1192,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1285,7 +1329,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1303,7 +1347,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1312,7 +1355,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh03_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh03_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh03_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh03_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:07:14 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:41:25 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -21,6 +21,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -64,6 +66,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +105,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -151,14 +156,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -234,8 +266,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -320,7 +350,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00004000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
@@ -329,7 +358,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 me
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -433,9 +461,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -468,6 +493,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -580,8 +609,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -614,7 +646,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -685,6 +719,7 @@ CONFIG_8139CP=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -733,8 +768,9 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -748,6 +784,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -757,6 +794,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -886,6 +924,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1149,10 +1188,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1172,8 +1212,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1182,7 +1220,11 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7710voipgw_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7710voipgw_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7710voipgw_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7710voipgw_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:11:49 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 14:43:04 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -29,6 +29,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -60,6 +61,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -98,6 +100,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -116,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -142,14 +146,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -225,8 +256,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -460,9 +489,6 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -571,6 +597,10 @@ CONFIG_MTD_RAM=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -623,11 +653,11 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -647,6 +677,7 @@ CONFIG_PHONE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -725,6 +756,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -792,6 +824,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -836,7 +869,6 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -899,10 +931,11 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -916,7 +949,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -925,7 +957,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7724_generic_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7724_generic_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7724_generic_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7724_generic_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:14:00 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:03:45 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -49,7 +51,6 @@ CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_LZMA is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 
 #
@@ -57,6 +58,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -80,11 +82,9 @@ CONFIG_CGROUPS=y
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
-CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -100,6 +100,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -120,6 +121,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -136,19 +138,48 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -204,6 +235,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -225,17 +257,12 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-
-#
-# Memory hotplug is currently incompatible with Software Suspend
-#
+# CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -269,7 +296,6 @@ CONFIG_CPU_HAS_FPU=y
 #
 CONFIG_SH_TIMER_TMU=y
 CONFIG_SH_TIMER_CMT=y
-CONFIG_SH_PCLK_FREQ=41666666
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -388,6 +414,10 @@ CONFIG_EXTRA_FIRMWARE=""
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -476,7 +506,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -505,15 +534,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -561,6 +593,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -581,7 +614,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -608,6 +643,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -675,11 +711,10 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -699,7 +734,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -707,7 +741,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_BINARY_PRINTF=y
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7763rdp_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7763rdp_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7763rdp_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7763rdp_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:15:37 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:05:29 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -59,6 +61,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -124,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -150,14 +155,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -211,6 +243,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -237,8 +270,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -421,10 +452,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -509,7 +536,6 @@ CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -542,6 +568,10 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -640,11 +670,12 @@ CONFIG_SH_ETH=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -673,6 +704,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -756,6 +788,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -949,6 +982,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1129,10 +1163,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1152,7 +1187,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1161,7 +1195,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7770_generic_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7770_generic_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7770_generic_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7770_generic_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:17:16 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:06:28 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,7 +50,6 @@ CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_LZMA is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 
 #
@@ -56,6 +57,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -79,11 +81,9 @@ CONFIG_CGROUPS=y
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
-CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -99,6 +99,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -119,6 +120,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -135,19 +137,48 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -201,6 +232,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -221,17 +253,12 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
-
-#
-# Memory hotplug is currently incompatible with Software Suspend
-#
+# CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -379,6 +406,10 @@ CONFIG_EXTRA_FIRMWARE=""
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -467,7 +498,6 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -496,15 +526,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -552,6 +585,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -572,7 +606,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -599,6 +635,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -666,11 +703,10 @@ CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -690,7 +726,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -698,7 +733,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 CONFIG_BINARY_PRINTF=y
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Fri Sep 25 11:39:20 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:07:40 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -64,6 +66,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,6 +106,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -126,6 +130,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -153,14 +158,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -253,8 +285,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -287,7 +317,6 @@ CONFIG_SH_SH7785LCR=y
 # Timer and clock configuration
 #
 CONFIG_SH_TIMER_TMU=y
-CONFIG_SH_PCLK_FREQ=50000000
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
@@ -360,7 +389,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
@@ -470,10 +498,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -588,6 +612,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -688,15 +716,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -777,6 +806,7 @@ CONFIG_R8169=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -786,6 +816,7 @@ CONFIG_R8169=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -841,6 +872,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -924,11 +956,6 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 CONFIG_I2C_PCA_PLATFORM=y
@@ -937,7 +964,6 @@ CONFIG_I2C_PCA_PLATFORM=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -986,15 +1012,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1129,6 +1158,7 @@ CONFIG_SND_CMIPCI=y
 # CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1363,6 +1393,7 @@ CONFIG_MMC_SDHCI_PLTFM=m
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MMC_CB710 is not set
 # CONFIG_MMC_VIA_SDMMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1397,6 +1428,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1417,7 +1449,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1622,13 +1656,14 @@ CONFIG_SCHED_DEBUG=y
 CONFIG_SCHEDSTATS=y
 CONFIG_TRACE_IRQFLAGS=y
 CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE_NMI_ENTER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1637,6 +1672,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_TRACER_MAX_TRACE=y
 CONFIG_RING_BUFFER=y
+CONFIG_FTRACE_NMI_ENTER=y
 CONFIG_EVENT_TRACING=y
 CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
@@ -1668,7 +1704,6 @@ CONFIG_FTRACE_MCOUNT_RECORD=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 CONFIG_DWARF_UNWINDER=y
 CONFIG_MCOUNT=y
 
@@ -1678,7 +1713,11 @@ CONFIG_MCOUNT=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/sh7785lcr_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/sh7785lcr_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/sh7785lcr_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/sh7785lcr_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:23:18 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:09:09 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -103,12 +106,14 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -123,6 +128,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -149,14 +155,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -237,8 +270,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -271,7 +302,6 @@ CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y
 # Timer and clock configuration
 #
 CONFIG_SH_TIMER_TMU=y
-CONFIG_SH_PCLK_FREQ=50000000
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -329,7 +359,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -433,10 +462,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -552,6 +577,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -652,15 +681,16 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -719,8 +749,10 @@ CONFIG_R8169=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -743,6 +775,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -752,6 +785,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -874,11 +908,6 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 CONFIG_I2C_PCA_PLATFORM=y
@@ -887,7 +916,6 @@ CONFIG_I2C_PCA_PLATFORM=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -916,15 +944,18 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1205,6 +1236,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1225,7 +1257,9 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1484,7 +1518,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1498,7 +1531,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/shmin_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/shmin_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/shmin_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/shmin_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:27:17 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:10:09 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -28,6 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -57,6 +58,7 @@ CONFIG_KERNEL_GZIP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -88,6 +90,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -105,6 +108,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -124,14 +128,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -207,8 +238,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -387,9 +416,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -495,6 +521,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -546,11 +576,11 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -629,6 +659,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -688,6 +719,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -731,7 +763,6 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_SYSFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
@@ -794,6 +825,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -806,8 +838,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-CONFIG_EARLY_PRINTK=y
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -815,7 +845,11 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/shx3_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/shx3_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/shx3_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/shx3_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:29:26 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:10:45 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -22,6 +22,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 CONFIG_GENERIC_LOCKBREAK=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -32,6 +33,8 @@ CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_DMA_NONCOHERENT is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -66,6 +69,7 @@ CONFIG_AUDIT_TREE=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 CONFIG_RCU_TRACE=y
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -121,6 +125,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -128,6 +133,7 @@ CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
@@ -143,6 +149,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
@@ -166,19 +173,48 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_FREEZER=y
 
 #
@@ -233,6 +269,7 @@ CONFIG_FORCE_MAX_ZONEORDER=7
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
@@ -271,10 +308,9 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_SCHED_MC=y
 
 #
 # Cache configuration
@@ -449,6 +485,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -496,7 +533,13 @@ CONFIG_CAN_VCAN=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -522,6 +565,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -532,9 +579,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -624,11 +674,12 @@ CONFIG_SMC91X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -726,7 +777,6 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -740,7 +790,10 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_SH_MSIOF is not set
 # CONFIG_SPI_SH_SCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
 
 #
 # SPI Protocol Masters
@@ -781,15 +834,16 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -924,10 +978,12 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -965,6 +1021,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -993,7 +1050,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1244,8 +1303,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DUMP_CODE=y
@@ -1258,7 +1315,11 @@ CONFIG_DUMP_CODE=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/snapgear_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/snapgear_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/snapgear_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/snapgear_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:33:00 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:14:18 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -59,6 +61,7 @@ CONFIG_KERNEL_GZIP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -97,6 +100,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -115,6 +119,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -136,14 +141,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -219,8 +251,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -272,9 +302,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -313,7 +343,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_OVERWRITE is not set
 # CONFIG_CMDLINE_EXTEND is not set
 
@@ -321,7 +350,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -407,9 +435,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -524,6 +549,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -616,6 +645,7 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -623,8 +653,9 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -637,6 +668,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -646,6 +678,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -728,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -787,7 +821,9 @@ CONFIG_RTC_DRV_DS1302=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -812,6 +848,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -915,10 +952,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -931,7 +969,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -940,7 +977,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/systemh_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/systemh_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/systemh_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/systemh_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:35:03 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:14:50 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -29,6 +30,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -56,6 +58,7 @@ CONFIG_SWAP=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -94,6 +97,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -112,6 +116,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -138,14 +143,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -221,8 +253,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -310,7 +340,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 # CONFIG_CMDLINE_OVERWRITE is not set
 # CONFIG_CMDLINE_EXTEND is not set
 
@@ -349,6 +378,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=1024
@@ -390,6 +423,7 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -458,6 +492,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -517,6 +552,7 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -609,10 +645,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -625,7 +662,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -634,7 +670,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/titan_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/titan_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/titan_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/titan_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:36:36 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:17:20 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -30,6 +31,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -61,6 +63,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -101,6 +104,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -120,13 +124,14 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
 #
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -146,14 +151,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -229,8 +261,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -282,9 +312,9 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 # DMA support
 #
-CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
 CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -323,7 +353,6 @@ CONFIG_GUSA=y
 CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x009e0000
 CONFIG_ENTRY_OFFSET=0x00001000
-# CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
 CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw"
@@ -332,7 +361,6 @@ CONFIG_CMDLINE="console=ttySC1,38400N81
 # Bus options
 #
 CONFIG_PCI=y
-CONFIG_SH_PCIDMA_NONCOHERENT=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
@@ -425,6 +453,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=y
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -614,10 +643,6 @@ CONFIG_NET_SCH_FIFO=y
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -743,6 +768,11 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -807,8 +837,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -841,7 +874,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -935,6 +970,7 @@ CONFIG_8139_OLD_RX_RESET=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -983,8 +1019,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -1033,6 +1071,7 @@ CONFIG_SLIP_SMART=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -1042,6 +1081,7 @@ CONFIG_SLIP_SMART=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -1172,6 +1212,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -1409,7 +1450,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1664,6 +1707,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -1691,7 +1735,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1705,7 +1748,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/ul2_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/ul2_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/ul2_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/ul2_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:42:33 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:18:53 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_SYS_SUPPORTS_TMU=y
@@ -31,6 +32,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -63,6 +65,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -102,6 +105,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
@@ -122,6 +126,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -148,14 +153,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -247,8 +279,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -280,7 +310,6 @@ CONFIG_CPU_HAS_DSP=y
 #
 CONFIG_SH_TIMER_TMU=y
 # CONFIG_SH_TIMER_CMT is not set
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -435,14 +464,17 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
 CONFIG_CFG80211=y
 # CONFIG_NL80211_TESTMODE is not set
 # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_CFG80211_DEFAULT_PS=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=1
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=m
 # CONFIG_LIB80211_DEBUG is not set
@@ -559,6 +591,10 @@ CONFIG_MTD_RAM=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -576,6 +612,7 @@ CONFIG_MISC_DEVICES=y
 # EEPROM support
 #
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -653,30 +690,29 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-CONFIG_LIBERTAS=m
-# CONFIG_LIBERTAS_USB is not set
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_DEBUG=y
 # CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AT76C50X_USB is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
 # CONFIG_MAC80211_HWSIM is not set
-# CONFIG_P54_COMMON is not set
 # CONFIG_ATH_COMMON is not set
-# CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_DEBUG=y
+# CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
 # CONFIG_WL12XX is not set
-# CONFIG_IWM is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -718,6 +754,7 @@ CONFIG_USB_NET_CDCETHER=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -810,6 +847,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
@@ -951,6 +989,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_AT91 is not set
 # CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1133,7 +1172,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
@@ -1150,7 +1189,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DWARF_UNWINDER is not set
 
 #
@@ -1159,7 +1197,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/configs/urquell_defconfig linux-libre-2.6.33-gnu1/arch/sh/configs/urquell_defconfig
--- linux-libre-2.6.32-gnu1/arch/sh/configs/urquell_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/configs/urquell_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Thu Sep 24 19:46:13 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan  4 15:27:53 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -20,6 +20,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
@@ -32,6 +33,8 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_DMA_NONCOHERENT is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -66,6 +69,7 @@ CONFIG_AUDIT_TREE=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -120,12 +124,14 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -140,6 +146,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 
@@ -162,19 +169,48 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
+# CONFIG_CFQ_GROUP_IOSCHED is not set
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 CONFIG_FREEZER=y
 
 #
@@ -229,6 +265,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
@@ -263,8 +300,6 @@ CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -356,7 +391,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCIEAER=y
 # CONFIG_PCIE_ECRC is not set
@@ -469,10 +503,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 
 #
@@ -588,6 +618,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -688,15 +722,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_SIL680 is not set
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -787,6 +822,7 @@ CONFIG_8139CP=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -818,8 +854,10 @@ CONFIG_SKY2_DEBUG=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -842,6 +880,7 @@ CONFIG_WLAN=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -851,6 +890,7 @@ CONFIG_WLAN=y
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -976,11 +1016,6 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 CONFIG_I2C_PCA_PLATFORM=y
@@ -989,7 +1024,6 @@ CONFIG_I2C_PCA_PLATFORM=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -1020,6 +1054,7 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
 # CONFIG_GPIO_LANGWELL is not set
 
@@ -1062,6 +1097,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -1101,6 +1137,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
@@ -1116,16 +1153,19 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 CONFIG_MFD_SM501=y
 # CONFIG_MFD_SM501_GPIO is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -1139,6 +1179,8 @@ CONFIG_MEDIA_SUPPORT=y
 #
 # Multimedia drivers
 #
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
 # CONFIG_DAB is not set
 
 #
@@ -1417,6 +1459,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1437,7 +1480,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1466,7 +1511,6 @@ CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
 CONFIG_EXT4_FS=y
-# CONFIG_EXT4DEV_COMPAT is not set
 CONFIG_EXT4_FS_XATTR=y
 # CONFIG_EXT4_FS_POSIX_ACL is not set
 # CONFIG_EXT4_FS_SECURITY is not set
@@ -1687,9 +1731,6 @@ CONFIG_TRACING_SUPPORT=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
-CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffeb0000
-CONFIG_EARLY_PRINTK=y
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
@@ -1703,7 +1744,11 @@ CONFIG_EARLY_PRINTK=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/drivers/dma/dma-sysfs.c linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-sysfs.c
--- linux-libre-2.6.32-gnu1/arch/sh/drivers/dma/dma-sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/drivers/dma/dma-sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/platform_device.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/string.h>
 #include <asm/dma.h>
@@ -21,7 +20,6 @@
 static struct sysdev_class dma_sysclass = {
 	.name = "dma",
 };
-EXPORT_SYMBOL(dma_sysclass);
 
 static ssize_t dma_show_devices(struct sys_device *dev,
 				struct sysdev_attribute *attr, char *buf)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c
--- linux-libre-2.6.32-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/fixups-rts7751r2d.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
 #include <mach/lboxre2.h>
 #include <mach/r2d.h>
 #include "pci-sh4.h"
-#include <asm/machtypes.h>
+#include <generated/machtypes.h>
 
 #define PCIMCR_MRSET_OFF	0xBFFFFFFF
 #define PCIMCR_RFSH_OFF		0xFFFFFFFB
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/drivers/pci/Kconfig linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/Kconfig
--- linux-libre-2.6.32-gnu1/arch/sh/drivers/pci/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/drivers/pci/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-config PCI
-	bool "PCI support"
-	depends on SYS_SUPPORTS_PCI
-	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. If you have PCI, say Y, otherwise N.
-
-config SH_PCIDMA_NONCOHERENT
-	bool "Cache and PCI noncoherent"
-	depends on PCI
-	default y
-	help
-	  Enable this option if your platform does not have a CPU cache which
-	  remains coherent with PCI DMA. It is safest to say 'Y', although you
-	  will see better performance if you can say 'N', because the PCI DMA
-	  code will not have to flush the CPU's caches. If you have a PCI host
-	  bridge integrated with your SH CPU, refer carefully to the chip specs
-	  to see if you can say 'N' here. Otherwise, leave it as 'Y'.
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/addrspace.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/addrspace.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/addrspace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/addrspace.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,9 +28,6 @@
 /* Returns the privileged segment base of a given address  */
 #define PXSEG(a)	(((unsigned long)(a)) & 0xe0000000)
 
-/* Returns the physical address of a PnSEG (n=1,2) address   */
-#define PHYSADDR(a)	(((unsigned long)(a)) & 0x1fffffff)
-
 #if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
 /*
  * Map an address to a certain privileged segment
@@ -60,5 +57,11 @@
 #define P3_ADDR_MAX		P4SEG
 #endif
 
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PMB
+extern int __in_29bit_mode(void);
+#endif /* CONFIG_PMB */
+#endif /* __ASSEMBLY__ */
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_ADDRSPACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/atomic.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/atomic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/atomic.h	2010-02-24 13:52:17.000000000 -0500
@@ -78,11 +78,10 @@ static inline int atomic_add_unless(atom
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-/* Atomic operations are already serializing on SH */
-#define smp_mb__before_atomic_dec()	barrier()
-#define smp_mb__after_atomic_dec()	barrier()
-#define smp_mb__before_atomic_inc()	barrier()
-#define smp_mb__after_atomic_inc()	barrier()
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
 
 #include <asm-generic/atomic-long.h>
 #include <asm-generic/atomic64.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/bitops.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/bitops.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/bitops.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/bitops.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,8 +26,8 @@
 /*
  * clear_bit() doesn't provide any barrier for the compiler.
  */
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
 
 #ifdef CONFIG_SUPERH32
 static inline unsigned long ffz(unsigned long word)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/bugs.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/bugs.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/bugs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/bugs.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,11 +14,15 @@
 
 #include <asm/processor.h>
 
+extern void select_idle_routine(void);
+
 static void __init check_bugs(void)
 {
 	extern unsigned long loops_per_jiffy;
 	char *p = &init_utsname()->machine[2]; /* "sh" */
 
+	select_idle_routine();
+
 	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
 
 	switch (current_cpu_data.family) {
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@ extern void flush_cache_page(struct vm_a
 				unsigned long addr, unsigned long pfn);
 extern void flush_cache_range(struct vm_area_struct *vma,
 				 unsigned long start, unsigned long end);
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
 extern void flush_icache_range(unsigned long start, unsigned long end);
 extern void flush_icache_page(struct vm_area_struct *vma,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/dma.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,9 +19,11 @@
 #include <asm-generic/dma.h>
 
 #ifdef CONFIG_NR_DMA_CHANNELS
-#  define MAX_DMA_CHANNELS   (CONFIG_NR_DMA_CHANNELS)
+#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
+#elif defined(CONFIG_NR_ONCHIP_DMA_CHANNELS)
+#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
 #else
-#  define MAX_DMA_CHANNELS   (CONFIG_NR_ONCHIP_DMA_CHANNELS)
+#  define MAX_DMA_CHANNELS	0
 #endif
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,219 +1,108 @@
 #ifndef __ASM_SH_DMA_MAPPING_H
 #define __ASM_SH_DMA_MAPPING_H
 
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
+extern struct dma_map_ops *dma_ops;
+extern void no_iommu_init(void);
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	return dma_ops;
+}
+
 #include <asm-generic/dma-coherent.h>
+#include <asm-generic/dma-mapping-common.h>
 
-extern struct bus_type pci_bus_type;
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
-#define dma_supported(dev, mask)	(1)
+	if (ops->dma_supported)
+		return ops->dma_supported(dev, mask);
+
+	return 1;
+}
 
 static inline int dma_set_mask(struct device *dev, u64 mask)
 {
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
 	if (!dev->dma_mask || !dma_supported(dev, mask))
 		return -EIO;
+	if (ops->set_dma_mask)
+		return ops->set_dma_mask(dev, mask);
 
 	*dev->dma_mask = mask;
 
 	return 0;
 }
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-			 dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
-		       void *vaddr, dma_addr_t dma_handle);
-
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		    enum dma_data_direction dir);
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d, h) (1)
 
-static inline dma_addr_t dma_map_single(struct device *dev,
-					void *ptr, size_t size,
-					enum dma_data_direction dir)
-{
-	dma_addr_t addr = virt_to_phys(ptr);
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return addr;
-#endif
-	dma_cache_sync(dev, ptr, size, dir);
-
-	debug_dma_map_page(dev, virt_to_page(ptr),
-			   (unsigned long)ptr & ~PAGE_MASK, size,
-			   dir, addr, true);
-
-	return addr;
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
-				    size_t size, enum dma_data_direction dir)
-{
-	debug_dma_unmap_page(dev, addr, size, dir, true);
-}
-
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
-			     int nents, enum dma_data_direction dir)
-{
-	int i;
-
-	for (i = 0; i < nents; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
+#ifdef CONFIG_DMA_COHERENT
+#define dma_is_consistent(d, h) (1)
+#else
+#define dma_is_consistent(d, h) (0)
 #endif
-		sg[i].dma_address = sg_phys(&sg[i]);
-		sg[i].dma_length = sg[i].length;
-	}
-
-	debug_dma_map_sg(dev, sg, nents, i, dir);
-
-	return nents;
-}
-
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction dir)
-{
-	debug_dma_unmap_sg(dev, sg, nents, dir);
-}
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir)
-{
-	return dma_map_single(dev, page_address(page) + offset, size, dir);
-}
 
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-				  size_t size, enum dma_data_direction dir)
-{
-	dma_unmap_single(dev, dma_address, size, dir);
-}
-
-static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle,
-				   size_t size, enum dma_data_direction dir)
+static inline int dma_get_cache_alignment(void)
 {
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return;
-#endif
-	dma_cache_sync(dev, phys_to_virt(dma_handle), size, dir);
+	/*
+	 * Each processor family will define its own L1_CACHE_SHIFT,
+	 * L1_CACHE_BYTES wraps to this, so this is always safe.
+	 */
+	return L1_CACHE_BYTES;
 }
 
-static inline void dma_sync_single_range(struct device *dev,
-					 dma_addr_t dma_handle,
-					 unsigned long offset, size_t size,
-					 enum dma_data_direction dir)
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-	if (dev->bus == &pci_bus_type)
-		return;
-#endif
-	dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir);
-}
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
-static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg,
-			       int nelems, enum dma_data_direction dir)
-{
-	int i;
+	if (ops->mapping_error)
+		return ops->mapping_error(dev, dma_addr);
 
-	for (i = 0; i < nelems; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
-#endif
-		sg[i].dma_address = sg_phys(&sg[i]);
-		sg[i].dma_length = sg[i].length;
-	}
+	return dma_addr == 0;
 }
 
-static inline void dma_sync_single_for_cpu(struct device *dev,
-					   dma_addr_t dma_handle, size_t size,
-					   enum dma_data_direction dir)
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t gfp)
 {
-	__dma_sync_single(dev, dma_handle, size, dir);
-	debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
-}
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	void *memory;
 
-static inline void dma_sync_single_for_device(struct device *dev,
-					      dma_addr_t dma_handle,
-					      size_t size,
-					      enum dma_data_direction dir)
-{
-	__dma_sync_single(dev, dma_handle, size, dir);
-	debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
-}
+	if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
+		return memory;
+	if (!ops->alloc_coherent)
+		return NULL;
 
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-						 dma_addr_t dma_handle,
-						 unsigned long offset,
-						 size_t size,
-						 enum dma_data_direction direction)
-{
-	dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
-	debug_dma_sync_single_range_for_cpu(dev, dma_handle,
-					    offset, size, direction);
-}
+	memory = ops->alloc_coherent(dev, size, dma_handle, gfp);
+	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 
-static inline void dma_sync_single_range_for_device(struct device *dev,
-						    dma_addr_t dma_handle,
-						    unsigned long offset,
-						    size_t size,
-						    enum dma_data_direction direction)
-{
-	dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
-	debug_dma_sync_single_range_for_device(dev, dma_handle,
-					       offset, size, direction);
+	return memory;
 }
 
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-				       struct scatterlist *sg, int nelems,
-				       enum dma_data_direction dir)
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dma_handle)
 {
-	__dma_sync_sg(dev, sg, nelems, dir);
-	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
-static inline void dma_sync_sg_for_device(struct device *dev,
-					  struct scatterlist *sg, int nelems,
-					  enum dma_data_direction dir)
-{
-	__dma_sync_sg(dev, sg, nelems, dir);
-	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
-}
+	WARN_ON(irqs_disabled());	/* for portability */
 
-static inline int dma_get_cache_alignment(void)
-{
-	/*
-	 * Each processor family will define its own L1_CACHE_SHIFT,
-	 * L1_CACHE_BYTES wraps to this, so this is always safe.
-	 */
-	return L1_CACHE_BYTES;
-}
+	if (dma_release_from_coherent(dev, get_order(size), vaddr))
+		return;
 
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return dma_addr == 0;
+	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+	if (ops->free_coherent)
+		ops->free_coherent(dev, size, vaddr, dma_handle);
 }
 
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-extern int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int flags);
-
-extern void
-dma_release_declared_memory(struct device *dev);
-
-extern void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size);
+/* arch/sh/mm/consistent.c */
+extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+					dma_addr_t *dma_addr, gfp_t flag);
+extern void dma_generic_free_coherent(struct device *dev, size_t size,
+				      void *vaddr, dma_addr_t dma_handle);
 
 #endif /* __ASM_SH_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/dwarf.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/dwarf.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/dwarf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/dwarf.h	2010-02-24 13:52:17.000000000 -0500
@@ -194,6 +194,12 @@
 #define DWARF_ARCH_RA_REG	17
 
 #ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <linux/bug.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
 /*
  * Read either the frame pointer (r14) or the stack pointer (r15).
  * NOTE: this MUST be inlined.
@@ -241,6 +247,12 @@ struct dwarf_cie {
 
 	unsigned long flags;
 #define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
+
+	/*
+	 * 'mod' will be non-NULL if this CIE came from a module's
+	 * .eh_frame section.
+	 */
+	struct module *mod;
 };
 
 /**
@@ -255,6 +267,12 @@ struct dwarf_fde {
 	unsigned char *instructions;
 	unsigned char *end;
 	struct list_head link;
+
+	/*
+	 * 'mod' will be non-NULL if this FDE came from a module's
+	 * .eh_frame section.
+	 */
+	struct module *mod;
 };
 
 /**
@@ -364,6 +382,12 @@ static inline unsigned int DW_CFA_operan
 
 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
 					      struct dwarf_frame *);
+extern void dwarf_free_frame(struct dwarf_frame *);
+
+extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+				 struct module *);
+extern void module_dwarf_cleanup(struct module *);
+
 #endif /* !__ASSEMBLY__ */
 
 #define CFI_STARTPROC	.cfi_startproc
@@ -391,6 +415,10 @@ extern struct dwarf_frame *dwarf_unwind_
 static inline void dwarf_unwinder_init(void)
 {
 }
+
+#define module_dwarf_finalize(hdr, sechdrs, me)	(0)
+#define module_dwarf_cleanup(mod)		do { } while (0)
+
 #endif
 
 #endif /* CONFIG_DWARF_UNWINDER */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -114,7 +114,6 @@ typedef struct user_fpu_struct elf_fpreg
  */
 #define CORE_DUMP_USE_REGSET
 
-#define USE_ELF_CORE_DUMP
 #define ELF_FDPIC_CORE_EFLAGS	EF_SH_FDPIC
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/fixmap.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/fixmap.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/fixmap.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/fixmap.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,9 +14,9 @@
 #define _ASM_FIXMAP_H
 
 #include <linux/kernel.h>
+#include <linux/threads.h>
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
-#include <linux/threads.h>
 #include <asm/kmap_types.h>
 #endif
 
@@ -46,9 +46,15 @@
  * fix-mapped?
  */
 enum fixed_addresses {
-#define FIX_N_COLOURS 16
+	/*
+	 * The FIX_CMAP entries are used by kmap_coherent() to get virtual
+	 * addresses which are of a known color, and so their values are
+	 * important. __fix_to_virt(FIX_CMAP_END - n) must give an address
+	 * which is the same color as a page (n<<PAGE_SHIFT).
+	 */
+#define FIX_N_COLOURS 8
 	FIX_CMAP_BEGIN,
-	FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
 	FIX_UNCACHED,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/fpu.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/fpu.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/fpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/fpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,16 +18,15 @@ static inline void grab_fpu(struct pt_re
 
 struct task_struct;
 
-extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
+extern void save_fpu(struct task_struct *__tsk);
+void fpu_state_restore(struct pt_regs *regs);
 #else
 
+#define save_fpu(tsk)		do { } while (0)
 #define release_fpu(regs)	do { } while (0)
 #define grab_fpu(regs)		do { } while (0)
+#define fpu_state_restore(regs)	do { } while (0)
 
-static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
-{
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
-}
 #endif
 
 struct user_regset;
@@ -39,19 +38,28 @@ extern int fpregs_get(struct task_struct
 		      unsigned int pos, unsigned int count,
 		      void *kbuf, void __user *ubuf);
 
+static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
+{
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;
+		save_fpu(tsk);
+		release_fpu(regs);
+	} else
+		tsk->fpu_counter = 0;
+}
+
 static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
 {
 	preempt_disable();
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU))
-		save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	preempt_enable();
 }
 
 static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
 {
 	preempt_disable();
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
-		clear_tsk_thread_flag(tsk, TIF_USEDFPU);
+	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+		task_thread_info(tsk)->status &= ~TS_USEDFPU;
 		release_fpu(regs);
 	}
 	preempt_enable();
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/ftrace.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/ftrace.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/ftrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/ftrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,4 +35,21 @@ static inline unsigned long ftrace_call_
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_FUNCTION_TRACER */
 
+#ifndef __ASSEMBLY__
+
+/* arch/sh/kernel/return_address.c */
+extern void *return_address(unsigned int);
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_SH_FTRACE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/.gitignore linux-libre-2.6.33-gnu1/arch/sh/include/asm/.gitignore
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/.gitignore	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/.gitignore	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-machtypes.h
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/gpio.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/gpio.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/gpio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/gpio.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@
 #endif
 
 #define ARCH_NR_GPIOS 512
-#include <asm-generic/gpio.h>
+#include <linux/sh_pfc.h>
 
 #ifdef CONFIG_GPIOLIB
 
@@ -53,84 +53,4 @@ static inline int irq_to_gpio(unsigned i
 
 #endif /* CONFIG_GPIOLIB */
 
-typedef unsigned short pinmux_enum_t;
-typedef unsigned short pinmux_flag_t;
-
-#define PINMUX_TYPE_NONE            0
-#define PINMUX_TYPE_FUNCTION        1
-#define PINMUX_TYPE_GPIO            2
-#define PINMUX_TYPE_OUTPUT          3
-#define PINMUX_TYPE_INPUT           4
-#define PINMUX_TYPE_INPUT_PULLUP    5
-#define PINMUX_TYPE_INPUT_PULLDOWN  6
-
-#define PINMUX_FLAG_TYPE            (0x7)
-#define PINMUX_FLAG_WANT_PULLUP     (1 << 3)
-#define PINMUX_FLAG_WANT_PULLDOWN   (1 << 4)
-
-#define PINMUX_FLAG_DBIT_SHIFT      5
-#define PINMUX_FLAG_DBIT            (0x1f << PINMUX_FLAG_DBIT_SHIFT)
-#define PINMUX_FLAG_DREG_SHIFT      10
-#define PINMUX_FLAG_DREG            (0x3f << PINMUX_FLAG_DREG_SHIFT)
-
-struct pinmux_gpio {
-	pinmux_enum_t enum_id;
-	pinmux_flag_t flags;
-};
-
-#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark }
-#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
-
-struct pinmux_cfg_reg {
-	unsigned long reg, reg_width, field_width;
-	unsigned long *cnt;
-	pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_CFG_REG(name, r, r_width, f_width) \
-	.reg = r, .reg_width = r_width, .field_width = f_width,		\
-	.cnt = (unsigned long [r_width / f_width]) {}, \
-	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
-
-struct pinmux_data_reg {
-	unsigned long reg, reg_width, reg_shadow;
-	pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_DATA_REG(name, r, r_width) \
-	.reg = r, .reg_width = r_width,	\
-	.enum_ids = (pinmux_enum_t [r_width]) \
-
-struct pinmux_range {
-	pinmux_enum_t begin;
-	pinmux_enum_t end;
-	pinmux_enum_t force;
-};
-
-struct pinmux_info {
-	char *name;
-	pinmux_enum_t reserved_id;
-	struct pinmux_range data;
-	struct pinmux_range input;
-	struct pinmux_range input_pd;
-	struct pinmux_range input_pu;
-	struct pinmux_range output;
-	struct pinmux_range mark;
-	struct pinmux_range function;
-
-	unsigned first_gpio, last_gpio;
-
-	struct pinmux_gpio *gpios;
-	struct pinmux_cfg_reg *cfg_regs;
-	struct pinmux_data_reg *data_regs;
-
-	pinmux_enum_t *gpio_data;
-	unsigned int gpio_data_size;
-
-	unsigned long *gpio_in_use;
-	struct gpio_chip chip;
-};
-
-int register_pinmux(struct pinmux_info *pip);
-
 #endif /* __ASM_SH_GPIO_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/hardirq.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/hardirq.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/hardirq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/hardirq.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,16 @@
 #ifndef __ASM_SH_HARDIRQ_H
 #define __ASM_SH_HARDIRQ_H
 
-extern void ack_bad_irq(unsigned int irq);
-#define ack_bad_irq ack_bad_irq
+#include <linux/threads.h>
+#include <linux/irq.h>
 
-#include <asm-generic/hardirq.h>
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __nmi_count;		/* arch dependent */
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+extern void ack_bad_irq(unsigned int irq);
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/io.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/io.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -90,15 +90,11 @@
 #define ctrl_outl		__raw_writel
 #define ctrl_outq		__raw_writeq
 
+extern unsigned long generic_io_base;
+
 static inline void ctrl_delay(void)
 {
-#ifdef CONFIG_CPU_SH4
-	__raw_readw(CCN_PVR);
-#elif defined(P2SEG)
-	__raw_readw(P2SEG);
-#else
-#error "Need a dummy address for delay"
-#endif
+	__raw_readw(generic_io_base);
 }
 
 #define __BUILD_MEMORY_STRING(bwlq, type)				\
@@ -186,8 +182,6 @@ __BUILD_MEMORY_STRING(q, u64)
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-extern unsigned long generic_io_base;
-
 /*
  * This function provides a method for the generic case where a
  * board-specific ioport_map simply needs to return the port + some
@@ -239,14 +233,20 @@ unsigned long long poke_real_address_q(u
  * doesn't exist, so everything must go through page tables.
  */
 #ifdef CONFIG_MMU
-void __iomem *__ioremap(unsigned long offset, unsigned long size,
-			unsigned long flags);
+void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
+			       unsigned long flags, void *caller);
 void __iounmap(void __iomem *addr);
 
 static inline void __iomem *
+__ioremap(unsigned long offset, unsigned long size, unsigned long flags)
+{
+	return __ioremap_caller(offset, size, flags, __builtin_return_address(0));
+}
+
+static inline void __iomem *
 __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 {
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
 	unsigned long last_addr = offset + size - 1;
 #endif
 	void __iomem *ret;
@@ -255,7 +255,7 @@ __ioremap_mode(unsigned long offset, uns
 	if (ret)
 		return ret;
 
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB)
 	/*
 	 * For P1 and P2 space this is trivial, as everything is already
 	 * mapped. Uncached access for P1 addresses are done through P2.
@@ -277,6 +277,7 @@ __ioremap_mode(unsigned long offset, uns
 	return __ioremap(offset, size, flags);
 }
 #else
+#define __ioremap(offset, size, flags)		((void __iomem *)(offset))
 #define __ioremap_mode(offset, size, flags)	((void __iomem *)(offset))
 #define __iounmap(addr)				do { } while (0)
 #endif /* CONFIG_MMU */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags_32.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags_32.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,99 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_32_H
-#define __ASM_SH_IRQFLAGS_32_H
-
-static inline void raw_local_irq_enable(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	%1, %0\n\t"
-#ifdef CONFIG_CPU_HAS_SR_RB
-		"stc	r6_bank, %1\n\t"
-		"or	%1, %0\n\t"
-#endif
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "1" (~0x000000f0)
-		: "memory"
-	);
-}
-
-static inline void raw_local_irq_disable(void)
-{
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"or	#0xf0, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&z" (flags)
-		: /* no inputs */
-		: "memory"
-	);
-}
-
-static inline void set_bl_bit(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"or	%2, %0\n\t"
-		"and	%3, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "r" (0x10000000), "r" (0xffffff0f)
-		: "memory"
-	);
-}
-
-static inline void clear_bl_bit(void)
-{
-	unsigned long __dummy0, __dummy1;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	%2, %0\n\t"
-		"ldc	%0, sr\n\t"
-		: "=&r" (__dummy0), "=r" (__dummy1)
-		: "1" (~0x10000000)
-		: "memory"
-	);
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"stc	sr, %0\n\t"
-		"and	#0xf0, %0\n\t"
-		: "=&z" (flags)
-		: /* no inputs */
-		: "memory"
-	);
-
-	return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
-	unsigned long flags, __dummy;
-
-	__asm__ __volatile__ (
-		"stc	sr, %1\n\t"
-		"mov	%1, %0\n\t"
-		"or	#0xf0, %0\n\t"
-		"ldc	%0, sr\n\t"
-		"mov	%1, %0\n\t"
-		"and	#0xf0, %0\n\t"
-		: "=&z" (flags), "=&r" (__dummy)
-		: /* no inputs */
-		: "memory"
-	);
-
-	return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_32_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags_64.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags_64.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_64_H
-#define __ASM_SH_IRQFLAGS_64_H
-
-#include <cpu/registers.h>
-
-#define SR_MASK_LL	0x00000000000000f0LL
-#define SR_BL_LL	0x0000000010000000LL
-
-static inline void raw_local_irq_enable(void)
-{
-	unsigned long long __dummy0, __dummy1 = ~SR_MASK_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "and	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline void raw_local_irq_disable(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "or	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline void set_bl_bit(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_BL_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "or	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-
-}
-
-static inline void clear_bl_bit(void)
-{
-	unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
-
-	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
-			     "and	%0, %1, %0\n\t"
-			     "putcon	%0, " __SR "\n\t"
-			     : "=&r" (__dummy0)
-			     : "r" (__dummy1));
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
-	unsigned long long __dummy = SR_MASK_LL;
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"getcon	" __SR ", %0\n\t"
-		"and	%0, %1, %0"
-		: "=&r" (flags)
-		: "r" (__dummy));
-
-	return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
-	unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
-	unsigned long flags;
-
-	__asm__ __volatile__ (
-		"getcon	" __SR ", %1\n\t"
-		"or	%1, r63, %0\n\t"
-		"or	%1, %2, %1\n\t"
-		"putcon	%1, " __SR "\n\t"
-		"and	%0, %2, %0"
-		: "=&r" (flags), "=&r" (__dummy0)
-		: "r" (__dummy1));
-
-	return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_64_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/irqflags.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/irqflags.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,34 +1,9 @@
 #ifndef __ASM_SH_IRQFLAGS_H
 #define __ASM_SH_IRQFLAGS_H
 
-#ifdef CONFIG_SUPERH32
-#include "irqflags_32.h"
-#else
-#include "irqflags_64.h"
-#endif
-
-#define raw_local_save_flags(flags) \
-		do { (flags) = __raw_local_save_flags(); } while (0)
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
-{
-	return (flags != 0);
-}
-
-static inline int raw_irqs_disabled(void)
-{
-	unsigned long flags = __raw_local_save_flags();
-
-	return raw_irqs_disabled_flags(flags);
-}
-
-#define raw_local_irq_save(flags) \
-		do { (flags) = __raw_local_irq_save(); } while (0)
+#define RAW_IRQ_DISABLED	0xf0
+#define RAW_IRQ_ENABLED		0x00
 
-static inline void raw_local_irq_restore(unsigned long flags)
-{
-	if ((flags & 0xf0) != 0xf0)
-		raw_local_irq_enable();
-}
+#include <asm-generic/irqflags.h>
 
 #endif /* __ASM_SH_IRQFLAGS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/machvec.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/machvec.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/machvec.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/machvec.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <asm/machtypes.h>
+#include <generated/machtypes.h>
 
 struct sh_machine_vector {
 	void (*mv_setup)(char **cmdline_p);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/mmu.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/mmu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/mmu.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,12 +7,16 @@
 #define PMB_PASCR		0xff000070
 #define PMB_IRMCR		0xff000078
 
+#define PASCR_SE		0x80000000
+
 #define PMB_ADDR		0xf6100000
 #define PMB_DATA		0xf7100000
 #define PMB_ENTRY_MAX		16
 #define PMB_E_MASK		0x0000000f
 #define PMB_E_SHIFT		8
 
+#define PMB_PFN_MASK		0xff000000
+
 #define PMB_SZ_16M		0x00000000
 #define PMB_SZ_64M		0x00000010
 #define PMB_SZ_128M		0x00000080
@@ -62,17 +66,10 @@ struct pmb_entry {
 };
 
 /* arch/sh/mm/pmb.c */
-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
-		    unsigned long flags, int *entry);
-int set_pmb_entry(struct pmb_entry *pmbe);
-void clear_pmb_entry(struct pmb_entry *pmbe);
-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
-			    unsigned long flags);
-void pmb_free(struct pmb_entry *pmbe);
 long pmb_remap(unsigned long virt, unsigned long phys,
 	       unsigned long size, unsigned long flags);
 void pmb_unmap(unsigned long addr);
+int pmb_init(void);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __MMU_H */
-
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/pci.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/pci.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,8 +3,6 @@
 
 #ifdef __KERNEL__
 
-#include <linux/dma-mapping.h>
-
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
@@ -54,30 +52,18 @@ static inline void pcibios_penalize_isa_
  * address space.  The networking and block device layers use
  * this boolean for bounce buffer decisions.
  */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/scatterlist.h>
-#include <linux/string.h>
-#include <asm/io.h>
+#define PCI_DMA_BUS_IS_PHYS	(dma_ops->is_phys)
 
 /* pci_unmap_{single,page} being a nop depends upon the
  * configuration.
  */
-#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
-	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
-	__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)			\
-	((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
-	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)			\
-	((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
-	(((PTR)->LEN_NAME) = (VAL))
+#ifdef CONFIG_DMA_NONCOHERENT
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		__u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)		((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	(((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
 #else
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/perf_event.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/perf_event.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/perf_event.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/perf_event.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,35 @@
 #ifndef __ASM_SH_PERF_EVENT_H
 #define __ASM_SH_PERF_EVENT_H
 
-/* SH only supports software events through this interface. */
-static inline void set_perf_event_pending(void) {}
+struct hw_perf_event;
+
+#define MAX_HWEVENTS	2
+
+struct sh_pmu {
+	const char	*name;
+	unsigned int	num_events;
+	void		(*disable_all)(void);
+	void		(*enable_all)(void);
+	void		(*enable)(struct hw_perf_event *, int);
+	void		(*disable)(struct hw_perf_event *, int);
+	u64		(*read)(int);
+	int		(*event_map)(int);
+	unsigned int	max_events;
+	unsigned long	raw_event_mask;
+	const int	(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+				       [PERF_COUNT_HW_CACHE_OP_MAX]
+				       [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/* arch/sh/kernel/perf_event.c */
+extern int register_sh_pmu(struct sh_pmu *);
+extern int reserve_pmc_hardware(void);
+extern void release_pmc_hardware(void);
+
+static inline void set_perf_event_pending(void)
+{
+	/* Nothing to see here, move along. */
+}
 
 #define PERF_EVENT_INDEX_OFFSET	0
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/pgtable_32.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_32.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/pgtable_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -108,7 +108,7 @@ static inline unsigned long copy_ptea_at
 #define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE)
 #endif
 
-#define _PAGE_FLAGS_HARDWARE_MASK	(PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS))
+#define _PAGE_FLAGS_HARDWARE_MASK	(phys_addr_mask() & ~(_PAGE_CLEAR_FLAGS))
 
 /* Hardware flags, page size encoding */
 #if !defined(CONFIG_MMU)
@@ -344,7 +344,8 @@ static inline void set_pte(pte_t *ptep,
 #define pte_special(pte)	((pte).pte_low & _PAGE_SPECIAL)
 
 #ifdef CONFIG_X2TLB
-#define pte_write(pte)		((pte).pte_high & _PAGE_EXT_USER_WRITE)
+#define pte_write(pte) \
+	((pte).pte_high & (_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE))
 #else
 #define pte_write(pte)		((pte).pte_low & _PAGE_RW)
 #endif
@@ -358,7 +359,7 @@ static inline pte_t pte_##fn(pte_t pte)
  * individually toggled (and user permissions are entirely decoupled from
  * kernel permissions), we attempt to couple them a bit more sanely here.
  */
-PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE);
+PTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE));
 PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE);
 PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE);
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -75,13 +75,31 @@ static inline unsigned long long neff_si
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_ADDRESS	0
 
-#ifdef CONFIG_32BIT
-#define PHYS_ADDR_MASK		0xffffffff
+#define PHYS_ADDR_MASK29		0x1fffffff
+#define PHYS_ADDR_MASK32		0xffffffff
+
+#ifdef CONFIG_PMB
+static inline unsigned long phys_addr_mask(void)
+{
+	/* Is the MMU in 29bit mode? */
+	if (__in_29bit_mode())
+		return PHYS_ADDR_MASK29;
+
+	return PHYS_ADDR_MASK32;
+}
+#elif defined(CONFIG_32BIT)
+static inline unsigned long phys_addr_mask(void)
+{
+	return PHYS_ADDR_MASK32;
+}
 #else
-#define PHYS_ADDR_MASK		0x1fffffff
+static inline unsigned long phys_addr_mask(void)
+{
+	return PHYS_ADDR_MASK29;
+}
 #endif
 
-#define PTE_PHYS_MASK		(PHYS_ADDR_MASK & PAGE_MASK)
+#define PTE_PHYS_MASK		(phys_addr_mask() & PAGE_MASK)
 #define PTE_FLAGS_MASK		(~(PTE_PHYS_MASK) << PAGE_SHIFT)
 
 #ifdef CONFIG_SUPERH32
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/processor_32.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_32.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/processor_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/processor_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,7 @@ asmlinkage void __init sh_cpu_init(void)
 #define SR_DSP		0x00001000
 #define SR_IMASK	0x000000f0
 #define SR_FD		0x00008000
+#define SR_MD		0x40000000
 
 /*
  * DSP structure and data
@@ -136,7 +137,7 @@ struct mm_struct;
 extern void release_thread(struct task_struct *);
 
 /* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)	do { } while (0)
+void prepare_to_copy(struct task_struct *tsk);
 
 /*
  * create a kernel thread without removing it from tasklists
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/scatterlist.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/scatterlist.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/scatterlist.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/scatterlist.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #ifndef __ASM_SH_SCATTERLIST_H
 #define __ASM_SH_SCATTERLIST_H
 
-#define ISA_DMA_THRESHOLD	PHYS_ADDR_MASK
+#define ISA_DMA_THRESHOLD	phys_addr_mask()
 
 #include <asm-generic/scatterlist.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/sh_eth.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_eth.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/sh_eth.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_eth.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,7 @@ struct sh_eth_plat_data {
 	int phy;
 	int edmac_endian;
 
+	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
 	unsigned ether_link_active_low:1;
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/sh_keysc.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_keysc.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/sh_keysc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/sh_keysc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef __ASM_KEYSC_H__
-#define __ASM_KEYSC_H__
-
-#define SH_KEYSC_MAXKEYS 30
-
-struct sh_keysc_info {
-	enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
-	int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
-	int delay;
-	int kycr2_delay;
-	int keycodes[SH_KEYSC_MAXKEYS];
-};
-
-#endif /* __ASM_KEYSC_H__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,10 +23,10 @@
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  */
 
-#define __raw_spin_is_locked(x)		((x)->lock <= 0)
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_spin_unlock_wait(x) \
-	do { while (__raw_spin_is_locked(x)) cpu_relax(); } while (0)
+#define arch_spin_is_locked(x)		((x)->lock <= 0)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_unlock_wait(x) \
+	do { while (arch_spin_is_locked(x)) cpu_relax(); } while (0)
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
@@ -34,14 +34,14 @@
  *
  * We make no fairness assumptions.  They have a cost.
  */
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 	unsigned long oldval;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%2, %0	! __raw_spin_lock	\n\t"
+		"movli.l	@%2, %0	! arch_spin_lock	\n\t"
 		"mov		%0, %1				\n\t"
 		"mov		#0, %0				\n\t"
 		"movco.l	%0, @%2				\n\t"
@@ -54,12 +54,12 @@ static inline void __raw_spin_lock(raw_s
 	);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
 	__asm__ __volatile__ (
-		"mov		#1, %0 ! __raw_spin_unlock	\n\t"
+		"mov		#1, %0 ! arch_spin_unlock	\n\t"
 		"mov.l		%0, @%1				\n\t"
 		: "=&z" (tmp)
 		: "r" (&lock->lock)
@@ -67,13 +67,13 @@ static inline void __raw_spin_unlock(raw
 	);
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned long tmp, oldval;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%2, %0	! __raw_spin_trylock	\n\t"
+		"movli.l	@%2, %0	! arch_spin_trylock	\n\t"
 		"mov		%0, %1				\n\t"
 		"mov		#0, %0				\n\t"
 		"movco.l	%0, @%2				\n\t"
@@ -100,21 +100,21 @@ static inline int __raw_spin_trylock(raw
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_read_can_lock(x)	((x)->lock > 0)
+#define arch_read_can_lock(x)	((x)->lock > 0)
 
 /**
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-#define __raw_write_can_lock(x)	((x)->lock == RW_LOCK_BIAS)
+#define arch_write_can_lock(x)	((x)->lock == RW_LOCK_BIAS)
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! __raw_read_lock	\n\t"
+		"movli.l	@%1, %0	! arch_read_lock	\n\t"
 		"cmp/pl		%0				\n\t"
 		"bf		1b				\n\t"
 		"add		#-1, %0				\n\t"
@@ -126,13 +126,13 @@ static inline void __raw_read_lock(raw_r
 	);
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! __raw_read_unlock	\n\t"
+		"movli.l	@%1, %0	! arch_read_unlock	\n\t"
 		"add		#1, %0				\n\t"
 		"movco.l	%0, @%1				\n\t"
 		"bf		1b				\n\t"
@@ -142,13 +142,13 @@ static inline void __raw_read_unlock(raw
 	);
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! __raw_write_lock	\n\t"
+		"movli.l	@%1, %0	! arch_write_lock	\n\t"
 		"cmp/hs		%2, %0				\n\t"
 		"bf		1b				\n\t"
 		"sub		%2, %0				\n\t"
@@ -160,23 +160,23 @@ static inline void __raw_write_lock(raw_
 	);
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	__asm__ __volatile__ (
-		"mov.l		%1, @%0 ! __raw_write_unlock	\n\t"
+		"mov.l		%1, @%0 ! arch_write_unlock	\n\t"
 		:
 		: "r" (&rw->lock), "r" (RW_LOCK_BIAS)
 		: "t", "memory"
 	);
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned long tmp, oldval;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%2, %0	! __raw_read_trylock	\n\t"
+		"movli.l	@%2, %0	! arch_read_trylock	\n\t"
 		"mov		%0, %1				\n\t"
 		"cmp/pl		%0				\n\t"
 		"bf		2f				\n\t"
@@ -193,13 +193,13 @@ static inline int __raw_read_trylock(raw
 	return (oldval > 0);
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned long tmp, oldval;
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%2, %0	! __raw_write_trylock	\n\t"
+		"movli.l	@%2, %0	! arch_write_trylock	\n\t"
 		"mov		%0, %1				\n\t"
 		"cmp/hs		%3, %0				\n\t"
 		"bf		2f				\n\t"
@@ -216,11 +216,11 @@ static inline int __raw_write_trylock(ra
 	return (oldval > (RW_LOCK_BIAS - 1));
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* __ASM_SH_SPINLOCK_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,15 +7,15 @@
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED		{ 1 }
+#define __ARCH_SPIN_LOCK_UNLOCKED		{ 1 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
 #define RW_LOCK_BIAS			0x01000000
-#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
+#define __ARCH_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/suspend.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/suspend.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/suspend.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/suspend.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
 #define _ASM_SH_SUSPEND_H
 
 #ifndef __ASSEMBLY__
+#include <linux/notifier.h>
 static inline int arch_prepare_suspend(void) { return 0; }
 
 #include <asm/ptrace.h>
@@ -19,6 +20,69 @@ void sh_mobile_setup_cpuidle(void);
 static inline void sh_mobile_setup_cpuidle(void) {}
 #endif
 
+/* notifier chains for pre/post sleep hooks */
+extern struct atomic_notifier_head sh_mobile_pre_sleep_notifier_list;
+extern struct atomic_notifier_head sh_mobile_post_sleep_notifier_list;
+
+/* priority levels for notifiers */
+#define SH_MOBILE_SLEEP_BOARD	0
+#define SH_MOBILE_SLEEP_CPU	1
+#define SH_MOBILE_PRE(x)	(x)
+#define SH_MOBILE_POST(x)	(-(x))
+
+/* board code registration function for self-refresh assembly snippets */
+void sh_mobile_register_self_refresh(unsigned long flags,
+				     void *pre_start, void *pre_end,
+				     void *post_start, void *post_end);
+
+/* register structure for address/data information */
+struct sh_sleep_regs {
+	unsigned long stbcr;
+	unsigned long bar;
+
+	/* MMU */
+	unsigned long pteh;
+	unsigned long ptel;
+	unsigned long ttb;
+	unsigned long tea;
+	unsigned long mmucr;
+	unsigned long ptea;
+	unsigned long pascr;
+	unsigned long irmcr;
+
+	/* Cache */
+	unsigned long ccr;
+	unsigned long ramcr;
+};
+
+/* data area for low-level sleep code */
+struct sh_sleep_data {
+	/* current sleep mode (SUSP_SH_...) */
+	unsigned long mode;
+
+	/* addresses of board specific self-refresh snippets */
+	unsigned long sf_pre;
+	unsigned long sf_post;
+
+	/* address of resume code */
+	unsigned long resume;
+
+	/* register state saved and restored by the assembly code */
+	unsigned long vbr;
+	unsigned long spc;
+	unsigned long sr;
+	unsigned long sp;
+
+	/* structure for keeping register addresses */
+	struct sh_sleep_regs addr;
+
+	/* structure for saving/restoring register state */
+	struct sh_sleep_regs data;
+};
+
+/* a bitmap of supported sleep modes (SUSP_SH..) */
+extern unsigned long sh_mobile_sleep_supported;
+
 #endif
 
 /* flags passed to assembly suspend code */
@@ -27,5 +91,6 @@ static inline void sh_mobile_setup_cpuid
 #define SUSP_SH_RSTANDBY	(1 << 2) /* SH-Mobile R-standby mode */
 #define SUSP_SH_USTANDBY	(1 << 3) /* SH-Mobile U-standby mode */
 #define SUSP_SH_SF		(1 << 4) /* Enable self-refresh */
+#define SUSP_SH_MMU		(1 << 5) /* Save/restore MMU and cache */
 
 #endif /* _ASM_SH_SUSPEND_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/system_32.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_32.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/system_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -232,4 +232,33 @@ asmlinkage void do_exception_error(unsig
 				   unsigned long r6, unsigned long r7,
 				   struct pt_regs __regs);
 
+static inline void set_bl_bit(void)
+{
+	unsigned long __dummy0, __dummy1;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"or	%2, %0\n\t"
+		"and	%3, %0\n\t"
+		"ldc	%0, sr\n\t"
+		: "=&r" (__dummy0), "=r" (__dummy1)
+		: "r" (0x10000000), "r" (0xffffff0f)
+		: "memory"
+	);
+}
+
+static inline void clear_bl_bit(void)
+{
+	unsigned long __dummy0, __dummy1;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"and	%2, %0\n\t"
+		"ldc	%0, sr\n\t"
+		: "=&r" (__dummy0), "=r" (__dummy1)
+		: "1" (~0x10000000)
+		: "memory"
+	);
+}
+
 #endif /* __ASM_SH_SYSTEM_32_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/system_64.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_64.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/system_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/system_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#include <cpu/registers.h>
 #include <asm/processor.h>
 
 /*
@@ -47,4 +48,29 @@ static inline reg_size_t register_align(
 	return (unsigned long long)(signed long long)(signed long)val;
 }
 
+#define SR_BL_LL	0x0000000010000000LL
+
+static inline void set_bl_bit(void)
+{
+	unsigned long long __dummy0, __dummy1 = SR_BL_LL;
+
+	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
+			     "or	%0, %1, %0\n\t"
+			     "putcon	%0, " __SR "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+
+}
+
+static inline void clear_bl_bit(void)
+{
+	unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
+
+	__asm__ __volatile__("getcon	" __SR ", %0\n\t"
+			     "and	%0, %1, %0\n\t"
+			     "putcon	%0, " __SR "\n\t"
+			     : "=&r" (__dummy0)
+			     : "r" (__dummy1));
+}
+
 #endif /* __ASM_SH_SYSTEM_64_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/system.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/system.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -171,10 +171,6 @@ BUILD_TRAP_HANDLER(fpu_error);
 BUILD_TRAP_HANDLER(fpu_state_restore);
 BUILD_TRAP_HANDLER(nmi);
 
-#ifdef CONFIG_BUG
-extern void handle_BUG(struct pt_regs *);
-#endif
-
 #define arch_align_stack(x) (x)
 
 struct mem_access {
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/thread_info.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/thread_info.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/thread_info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@ struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
+	__u32			status;		/* thread synchronous flags */
 	__u32			cpu;
 	int			preempt_count; /* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;	/* thread address space */
@@ -50,6 +51,7 @@ struct thread_info {
 	.task		= &tsk,			\
 	.exec_domain	= &default_exec_domain,	\
 	.flags		= 0,			\
+	.status		= 0,			\
 	.cpu		= 0,			\
 	.preempt_count	= INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
@@ -111,13 +113,11 @@ extern void free_thread_info(struct thre
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_RESTORE_SIGMASK	3	/* restore signal mask in do_signal() */
 #define TIF_SINGLESTEP		4	/* singlestepping active */
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SECCOMP		6	/* secure computing */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
 #define TIF_SYSCALL_TRACEPOINT	8	/* for ftrace syscall instrumentation */
-#define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
 #define TIF_FREEZE		19	/* Freezing for suspend */
@@ -125,13 +125,11 @@ extern void free_thread_info(struct thre
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_USEDFPU		(1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
 
@@ -149,13 +147,33 @@ extern void free_thread_info(struct thre
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK	(_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
 				 _TIF_NEED_RESCHED  | _TIF_SYSCALL_AUDIT   | \
-				 _TIF_SINGLESTEP    | _TIF_RESTORE_SIGMASK | \
-				 _TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT)
+				 _TIF_SINGLESTEP    | _TIF_NOTIFY_RESUME   | \
+				 _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
 				 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
 
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_RESTORE_SIGMASK	0x0001	/* restore signal mask in do_signal() */
+#define TS_USEDFPU		0x0002	/* FPU used by this task this quantum */
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK	1
+static inline void set_restore_sigmask(void)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->status |= TS_RESTORE_SIGMASK;
+	set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags);
+}
+#endif	/* !__ASSEMBLY__ */
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_THREAD_INFO_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/timex.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/timex.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/timex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/timex.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,17 @@
 #ifndef __ASM_SH_TIMEX_H
 #define __ASM_SH_TIMEX_H
 
+/*
+ * Only parts using the legacy CPG code for their clock framework
+ * implementation need to define their own Pclk value. If provided, this
+ * can be used for accurately setting CLOCK_TICK_RATE, otherwise we
+ * simply fall back on the i8253 PIT value.
+ */
+#ifdef CONFIG_SH_PCLK_FREQ
 #define CLOCK_TICK_RATE		(CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */
+#else
+#define CLOCK_TICK_RATE		1193180
+#endif
 
 #include <asm-generic/timex.h>
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/topology.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/topology.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,14 @@
 
 #endif
 
+#define mc_capable()    (1)
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+
+extern cpumask_t cpu_core_map[NR_CPUS];
+
+#define topology_core_cpumask(cpu)	(&cpu_core_map[cpu])
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_SH_TOPOLOGY_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/ubc.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/ubc.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/ubc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/ubc.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,16 +60,5 @@
 #define BRCR_UBDE		(1 << 0)
 #endif
 
-#ifndef __ASSEMBLY__
-/* arch/sh/kernel/cpu/ubc.S */
-extern void ubc_sleep(void);
-
-#ifdef CONFIG_UBC_WAKEUP
-extern void ubc_wakeup(void);
-#else
-#define ubc_wakeup()	do { } while (0)
-#endif
-#endif
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_UBC_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/unistd_32.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_32.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/unistd_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -350,6 +350,8 @@
 
 #ifdef __KERNEL__
 
+#define __IGNORE_recvmmsg
+
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/unistd_64.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_64.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/unistd_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/unistd_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -385,10 +385,12 @@
 #define __NR_pwritev		362
 #define __NR_rt_tgsigqueueinfo	363
 #define __NR_perf_event_open	364
+#define __NR_recvmmsg		365
+#define __NR_accept4		366
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 365
+#define NR_syscalls 367
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/asm/watchdog.h linux-libre-2.6.33-gnu1/arch/sh/include/asm/watchdog.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/asm/watchdog.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/asm/watchdog.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,8 @@
  * include/asm-sh/watchdog.h
  *
  * Copyright (C) 2002, 2003 Paul Mundt
+ * Copyright (C) 2009 Siemens AG
+ * Copyright (C) 2009 Valentin Sitdikov
  *
  * 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
@@ -61,6 +63,61 @@
 #define WTCSR_CKS_2048	0x06
 #define WTCSR_CKS_4096	0x07
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+/**
+ * 	sh_wdt_read_cnt - Read from Counter
+ * 	Reads back the WTCNT value.
+ */
+static inline __u32 sh_wdt_read_cnt(void)
+{
+	return ctrl_inl(WTCNT_R);
+}
+
+/**
+ *	sh_wdt_write_cnt - Write to Counter
+ *	@val: Value to write
+ *
+ *	Writes the given value @val to the lower byte of the timer counter.
+ *	The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_cnt(__u32 val)
+{
+	ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
+}
+
+/**
+ *	sh_wdt_write_bst - Write to Counter
+ *	@val: Value to write
+ *
+ *	Writes the given value @val to the lower byte of the timer counter.
+ *	The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_bst(__u32 val)
+{
+	ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST);
+}
+/**
+ * 	sh_wdt_read_csr - Read from Control/Status Register
+ *
+ *	Reads back the WTCSR value.
+ */
+static inline __u32 sh_wdt_read_csr(void)
+{
+	return ctrl_inl(WTCSR_R);
+}
+
+/**
+ * 	sh_wdt_write_csr - Write to Control/Status Register
+ * 	@val: Value to write
+ *
+ * 	Writes the given value @val to the lower byte of the control/status
+ * 	register. The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_csr(__u32 val)
+{
+	ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
+}
+#else
 /**
  * 	sh_wdt_read_cnt - Read from Counter
  * 	Reads back the WTCNT value.
@@ -103,6 +160,6 @@ static inline void sh_wdt_write_csr(__u8
 {
 	ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
 }
-
+#endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_WATCHDOG_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,10 +19,10 @@
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
       defined(CONFIG_CPU_SUBTYPE_SH7724)
 #define DMTE0_IRQ	48	/* DMAC0A*/
-#define DMTE4_IRQ	40	/* DMAC0B */
-#define DMTE6_IRQ	42
-#define DMTE8_IRQ	76	/* DMAC1A */
-#define DMTE9_IRQ	77
+#define DMTE4_IRQ	76	/* DMAC0B */
+#define DMTE6_IRQ	40
+#define DMTE8_IRQ	42	/* DMAC1A */
+#define DMTE9_IRQ	43
 #define DMTE10_IRQ	72	/* DMAC1B */
 #define DMTE11_IRQ	73
 #define DMAE0_IRQ	78	/* DMA Error IRQ*/
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/cpu-sh4/cpu/watchdog.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,8 @@
  * include/asm-sh/cpu-sh4/watchdog.h
  *
  * Copyright (C) 2002, 2003 Paul Mundt
+ * Copyright (C) 2009 Siemens AG
+ * Copyright (C) 2009 Sitdikov Valentin
  *
  * 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
@@ -10,9 +12,20 @@
 #ifndef __ASM_CPU_SH4_WATCHDOG_H
 #define __ASM_CPU_SH4_WATCHDOG_H
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+/* Prefix definition */
+#define WTBST_HIGH	0x55
+/* Register definitions */
+#define WTCNT_R		0xffcc0010 /*WDTCNT*/
+#define WTCSR		0xffcc0004 /*WDTCSR*/
+#define WTCNT		0xffcc0000 /*WDTST*/
+#define WTST		WTCNT
+#define WTBST		0xffcc0008 /*WDTBST*/
+#else
 /* Register definitions */
 #define WTCNT		0xffc00008
 #define WTCSR		0xffc0000c
+#endif
 
 /* Bit definitions */
 #define WTCSR_TME	0x80
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/mach-common/mach/hp6xx.h linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/hp6xx.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/mach-common/mach/hp6xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/hp6xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,9 @@
 
 #define PKDR_LED_GREEN		0x10
 
+/* HP Palmtop 620lx/660lx speaker on/off */
+#define PKDR_SPEAKER		0x20
+
 #define SCPDR_TS_SCAN_ENABLE	0x20
 #define SCPDR_TS_SCAN_Y		0x02
 #define SCPDR_TS_SCAN_X		0x01
@@ -42,6 +45,7 @@
 #define ADC_CHANNEL_BACKUP	4
 #define ADC_CHANNEL_CHARGE	5
 
+/* HP Jornada 680/690 speaker on/off */
 #define HD64461_GPADR_SPEAKER	0x01
 #define HD64461_GPADR_PCMCIA0	(0x02|0x08)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/mach-common/mach/titan.h linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/titan.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/mach-common/mach/titan.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/mach-common/mach/titan.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Platform defintions for Titan
+ * Platform definitions for Titan
  */
 #ifndef _ASM_SH_TITAN_H
 #define _ASM_SH_TITAN_H
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt linux-libre-2.6.33-gnu1/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
--- linux-libre-2.6.32-gnu1/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt	2010-02-24 13:52:17.000000000 -0500
@@ -22,13 +22,12 @@ ED 0xff000010, 0x00000004
 LIST "setup clocks"
 ED 0xa4150024, 0x00004000
 ED 0xa4150000, 0x8E003508
-ED 0xa4150004, 0x00000000
 
 WAIT 1
 
 LIST "BSC"
 ED 0xff800020, 0xa5a50000
-ED 0xfec10000, 0x00000013
+ED 0xfec10000, 0x00001013
 ED 0xfec10004, 0x11110400
 ED 0xfec10024, 0x00000440
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h linux-libre-2.6.33-gnu1/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,8 @@ void kfr2r09_lcd_on(void *board_data);
 void kfr2r09_lcd_off(void *board_data);
 int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
 		      struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+		       struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
 #else
 static inline void kfr2r09_lcd_on(void *board_data) {}
 static inline void kfr2r09_lcd_off(void *board_data) {}
@@ -16,6 +18,10 @@ static inline int kfr2r09_lcd_setup(void
 {
 	return -ENODEV;
 }
+static inline void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+				     struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
+{
+}
 #endif
 
 #endif /* __ASM_SH_KFR2R09_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/include/mach-se/mach/se7722.h linux-libre-2.6.33-gnu1/arch/sh/include/mach-se/mach/se7722.h
--- linux-libre-2.6.32-gnu1/arch/sh/include/mach-se/mach/se7722.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/include/mach-se/mach/se7722.h	2010-02-24 13:52:17.000000000 -0500
@@ -92,18 +92,11 @@
 #define SE7722_FPGA_IRQ_MRSHPC1	3 /* IRQ1 */
 #define SE7722_FPGA_IRQ_MRSHPC2	4 /* IRQ1 */
 #define SE7722_FPGA_IRQ_MRSHPC3	5 /* IRQ1 */
-
 #define SE7722_FPGA_IRQ_NR	6
-#define SE7722_FPGA_IRQ_BASE	110
-
-#define MRSHPC_IRQ3    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3)
-#define MRSHPC_IRQ2    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2)
-#define MRSHPC_IRQ1    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1)
-#define MRSHPC_IRQ0    	(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0)
-#define SMC_IRQ		(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC)
-#define USB_IRQ		(SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB)
 
 /* arch/sh/boards/se/7722/irq.c */
+extern unsigned int se7722_fpga_irq[];
+
 void init_se7722_IRQ(void);
 
 #define __IO_PREFIX		se7722
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/Kconfig linux-libre-2.6.33-gnu1/arch/sh/Kconfig
--- linux-libre-2.6.32-gnu1/arch/sh/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,9 @@ config SUPERH
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
+	select HAVE_DMA_ATTRS
 	select HAVE_PERF_EVENTS
+	select PERF_USE_VMALLOC
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
@@ -37,6 +39,7 @@ config SUPERH32
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_ARCH_KGDB
 	select ARCH_HIBERNATION_POSSIBLE if MMU
@@ -170,6 +173,12 @@ config ARCH_HAS_CPU_IDLE_WAIT
 config IO_TRAPPED
 	bool
 
+config DMA_COHERENT
+	bool
+
+config DMA_NONCOHERENT
+	def_bool !DMA_COHERENT
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -220,6 +229,7 @@ config CPU_SHX2
 
 config CPU_SHX3
 	bool
+	select DMA_COHERENT
 
 config ARCH_SHMOBILE
 	bool
@@ -530,14 +540,16 @@ config SH_TIMER_MTU2
 
 config SH_PCLK_FREQ
 	int "Peripheral clock frequency (in Hz)"
-	default "27000000" if CPU_SUBTYPE_SH7343
+	depends on SH_CLK_CPG_LEGACY
 	default "31250000" if CPU_SUBTYPE_SH7619
-	default "32000000" if CPU_SUBTYPE_SH7722
-	default "33333333" if CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7723 || \
-			      CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
-			      CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \
-			      CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG    || \
-			      CPU_SUBTYPE_SH7786 || CPU_SUBTYPE_SH7724
+	default "33333333" if CPU_SUBTYPE_SH7770 || \
+			      CPU_SUBTYPE_SH7760 || \
+			      CPU_SUBTYPE_SH7705 || \
+			      CPU_SUBTYPE_SH7203 || \
+			      CPU_SUBTYPE_SH7206 || \
+			      CPU_SUBTYPE_SH7263 || \
+			      CPU_SUBTYPE_MXG    || \
+			      CPU_SUBTYPE_SH7786
 	default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
 	default "66000000" if CPU_SUBTYPE_SH4_202
 	default "50000000"
@@ -761,17 +773,6 @@ config ENTRY_OFFSET
 	default "0x00010000" if PAGE_SIZE_64KB
 	default "0x00000000"
 
-config UBC_WAKEUP
-	bool "Wakeup UBC on startup"
-	depends on CPU_SH4 && !CPU_SH4A
-	help
-	  Selecting this option will wakeup the User Break Controller (UBC) on
-	  startup. Although the UBC is left in an awake state when the processor
-	  comes up, some boot loaders misbehave by putting the UBC to sleep in a
-	  power saving state, which causes issues with things like ptrace().
-
-	  If unsure, say N.
-
 choice
 	prompt "Kernel command line"
 	optional
@@ -818,7 +819,13 @@ config MAPLE
 	 Dreamcast with a serial line terminal or a remote network
 	 connection.
 
-source "arch/sh/drivers/pci/Kconfig"
+config PCI
+	bool "PCI support"
+	depends on SYS_SUPPORTS_PCI
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. If you have PCI, say Y, otherwise N.
 
 source "drivers/pci/pcie/Kconfig"
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/Kconfig.debug linux-libre-2.6.33-gnu1/arch/sh/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/sh/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -19,50 +19,6 @@ config SH_STANDARD_BIOS
 	  mask ROM and no flash (WindowsCE machines fall in this category).
 	  If unsure, say N.
 
-config EARLY_SCIF_CONSOLE
-	bool "Use early SCIF console"
-	help
-	  This enables an early console using a fixed SCIF port. This can
-	  be used by platforms that are either not running the SH
-	  standard BIOS, or do not wish to use the BIOS callbacks for the
-	  serial I/O.
-
-config EARLY_SCIF_CONSOLE_PORT
-	hex
-	depends on EARLY_SCIF_CONSOLE
-	default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705
-	default "0xa4430000" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
-	default "0xf8420000" if CPU_SUBTYPE_SH7619
-	default "0xff804000" if CPU_SUBTYPE_MXG
-	default "0xffc30000" if CPU_SUBTYPE_SHX3
-	default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
-				CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
-				CPU_SUBTYPE_SH7343
-	default "0xfe4c0000" if CPU_SUBTYPE_SH7757
-	default "0xffeb0000" if CPU_SUBTYPE_SH7785
-	default "0xffeb0000" if CPU_SUBTYPE_SH7786
-	default "0xfffe8000" if CPU_SUBTYPE_SH7203
-	default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
-	default "0xffe80000" if CPU_SH4
-	default "0xa4000150" if CPU_SH3
-	default "0x00000000"
-
-config EARLY_PRINTK
-	bool "Early printk support"
-	depends on SH_STANDARD_BIOS || EARLY_SCIF_CONSOLE
-	help
-	  Say Y here to redirect kernel printk messages to the serial port
-	  used by the SH-IPL bootloader, starting very early in the boot
-	  process and ending when the kernel's serial console is initialised.
-	  This option is only useful porting the kernel to a new machine,
-	  when the kernel may crash or hang before the serial console is
-	  initialised. If unsure, say N.
-
-	  On devices that are running SH-IPL and want to keep the port
-	  initialization consistent while not using the BIOS callbacks,
-	  select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
-	  the kernel command line option to toggle back and forth.
-
 config STACK_DEBUG
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL && SUPERH32
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/asm-offsets.c linux-libre-2.6.33-gnu1/arch/sh/kernel/asm-offsets.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/asm-offsets.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/asm-offsets.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,5 +34,28 @@ int main(void)
 	DEFINE(PBE_NEXT, offsetof(struct pbe, next));
 	DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
 #endif
+
+	DEFINE(SH_SLEEP_MODE, offsetof(struct sh_sleep_data, mode));
+	DEFINE(SH_SLEEP_SF_PRE, offsetof(struct sh_sleep_data, sf_pre));
+	DEFINE(SH_SLEEP_SF_POST, offsetof(struct sh_sleep_data, sf_post));
+	DEFINE(SH_SLEEP_RESUME, offsetof(struct sh_sleep_data, resume));
+	DEFINE(SH_SLEEP_VBR, offsetof(struct sh_sleep_data, vbr));
+	DEFINE(SH_SLEEP_SPC, offsetof(struct sh_sleep_data, spc));
+	DEFINE(SH_SLEEP_SR, offsetof(struct sh_sleep_data, sr));
+	DEFINE(SH_SLEEP_SP, offsetof(struct sh_sleep_data, sp));
+	DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr));
+	DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data));
+	DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr));
+	DEFINE(SH_SLEEP_REG_BAR, offsetof(struct sh_sleep_regs, bar));
+	DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh));
+	DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel));
+	DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb));
+	DEFINE(SH_SLEEP_REG_TEA, offsetof(struct sh_sleep_regs, tea));
+	DEFINE(SH_SLEEP_REG_MMUCR, offsetof(struct sh_sleep_regs, mmucr));
+	DEFINE(SH_SLEEP_REG_PTEA, offsetof(struct sh_sleep_regs, ptea));
+	DEFINE(SH_SLEEP_REG_PASCR, offsetof(struct sh_sleep_regs, pascr));
+	DEFINE(SH_SLEEP_REG_IRMCR, offsetof(struct sh_sleep_regs, irmcr));
+	DEFINE(SH_SLEEP_REG_CCR, offsetof(struct sh_sleep_regs, ccr));
+	DEFINE(SH_SLEEP_REG_RAMCR, offsetof(struct sh_sleep_regs, ramcr));
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/clock.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/clock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/clock.c	2010-02-24 13:52:17.000000000 -0500
@@ -598,7 +598,7 @@ static struct dentry *clk_debugfs_root;
 static int clk_debugfs_register_one(struct clk *c)
 {
 	int err;
-	struct dentry *d, *child;
+	struct dentry *d, *child, *child_tmp;
 	struct clk *pa = c->parent;
 	char s[255];
 	char *p = s;
@@ -630,7 +630,7 @@ static int clk_debugfs_register_one(stru
 
 err_out:
 	d = c->dentry;
-	list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
+	list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
 		debugfs_remove(child);
 	debugfs_remove(c->dentry);
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/init.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/init.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,16 +75,11 @@ static void __init expmask_init(void)
 	/*
 	 * Future proofing.
 	 *
-	 * Disable support for slottable sleep instruction
-	 * and non-nop instructions in the rte delay slot.
-	 */
-	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
-
-	/*
-	 * Enable associative writes to the memory-mapped cache array
-	 * until the cache flush ops have been rewritten.
+	 * Disable support for slottable sleep instruction, non-nop
+	 * instructions in the rte delay slot, and associative writes to
+	 * the memory-mapped cache array.
 	 */
-	expmask |= EXPMASK_MMCAW;
+	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP | EXPMASK_MMCAW);
 
 	__raw_writel(expmask, EXPMASK);
 	ctrl_barrier();
@@ -311,12 +306,12 @@ asmlinkage void __init sh_cpu_init(void)
 	if (fpu_disabled) {
 		printk("FPU Disabled\n");
 		current_cpu_data.flags &= ~CPU_HAS_FPU;
-		disable_fpu();
 	}
 
 	/* FPU initialization */
+	disable_fpu();
 	if ((current_cpu_data.flags & CPU_HAS_FPU)) {
-		clear_thread_flag(TIF_USEDFPU);
+		current_thread_info()->status &= ~TS_USEDFPU;
 		clear_used_math();
 	}
 
@@ -338,17 +333,6 @@ asmlinkage void __init sh_cpu_init(void)
 	}
 #endif
 
-	/*
-	 * Some brain-damaged loaders decided it would be a good idea to put
-	 * the UBC to sleep. This causes some issues when it comes to things
-	 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB.  So ..
-	 * we wake it up and hope that all is well.
-	 */
-#ifdef CONFIG_SUPERH32
-	if (raw_smp_processor_id() == 0)
-		ubc_wakeup();
-#endif
-
 	speculative_execution_init();
 	expmask_init();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/irq/ipr.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/irq/ipr.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/irq/ipr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/irq/ipr.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,16 +17,17 @@
  * for more details.
  */
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
 #include <linux/topology.h>
 
 static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
 {
 	struct irq_chip *chip = get_irq_chip(irq);
-	return (void *)((char *)chip - offsetof(struct ipr_desc, chip));
+	return container_of(chip, struct ipr_desc, chip);
 }
 
 static void disable_ipr_irq(unsigned int irq)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/Makefile linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,6 @@ obj-$(CONFIG_ARCH_SHMOBILE)	+= shmobile/
 
 # Common interfaces.
 
-obj-$(CONFIG_UBC_WAKEUP)	+= ubc.o
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG)	+= clock-cpg.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,32 +59,48 @@ static struct intc_prio_reg prio_registe
 static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xf8400000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 88, 88, 88, 88 },
-	}, {
-		.mapbase	= 0xf8410000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 92, 92, 92, 92 },
-	}, {
-		.mapbase	= 0xf8420000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 96, 96, 96, 96 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xf8400000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 88, 88, 88, 88 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xf8410000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 92, 92, 92, 92 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xf8420000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 96, 96, 96, 96 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
 	},
 };
 
@@ -176,7 +192,9 @@ static struct platform_device cmt1_devic
 };
 
 static struct platform_device *sh7619_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&eth_device,
 	&cmt0_device,
 	&cmt1_device,
@@ -195,6 +213,9 @@ void __init plat_irq_setup(void)
 }
 
 static struct platform_device *sh7619_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&cmt0_device,
 	&cmt1_device,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/fpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,14 +25,12 @@
 
 /*
  * Save FPU registers onto task structure.
- * Assume called with FPU enabled (SR.FD=0).
  */
 void
-save_fpu(struct task_struct *tsk, struct pt_regs *regs)
+save_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 	enable_fpu();
 	asm volatile("sts.l	fpul, @-%0\n\t"
 		     "sts.l	fpscr, @-%0\n\t"
@@ -60,7 +58,6 @@ save_fpu(struct task_struct *tsk, struct
 		     : "memory");
 
 	disable_fpu();
-	release_fpu(regs);
 }
 
 static void
@@ -598,31 +595,31 @@ BUILD_TRAP_HANDLER(fpu_error)
 	struct task_struct *tsk = current;
 	TRAP_HANDLER_DECL;
 
-	save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	if (ieee_fpe_handler(regs)) {
 		tsk->thread.fpu.hard.fpscr &=
 			~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 		grab_fpu(regs);
 		restore_fpu(tsk);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 		return;
 	}
 
 	force_sig(SIGFPE, tsk);
 }
 
-BUILD_TRAP_HANDLER(fpu_state_restore)
+void fpu_state_restore(struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	TRAP_HANDLER_DECL;
 
 	grab_fpu(regs);
-	if (!user_mode(regs)) {
+	if (unlikely(!user_mode(regs))) {
 		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+		BUG();
 		return;
 	}
 
-	if (used_math()) {
+	if (likely(used_math())) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
 	} else	{
@@ -630,5 +627,13 @@ BUILD_TRAP_HANDLER(fpu_state_restore)
 		fpu_init();
 		set_used_math();
 	}
-	set_tsk_thread_flag(tsk, TIF_USEDFPU);
+	task_thread_info(tsk)->status |= TS_USEDFPU;
+	tsk->fpu_counter++;
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+	TRAP_HANDLER_DECL;
+
+	fpu_state_restore(regs);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c	2010-02-24 13:52:17.000000000 -0500
@@ -207,27 +207,23 @@ static struct platform_device mtu2_2_dev
 	.num_resources	= ARRAY_SIZE(mtu2_2_resources),
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xff804000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 220, 220, 220, 220 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xff804000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 220, 220, 220, 220 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
 	},
 };
 
 static struct platform_device *mxg_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
@@ -246,6 +242,7 @@ void __init plat_irq_setup(void)
 }
 
 static struct platform_device *mxg_early_devices[] __initdata = {
+	&scif0_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c	2010-02-24 13:52:17.000000000 -0500
@@ -177,57 +177,123 @@ static struct intc_mask_reg mask_registe
 static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
 			 mask_registers, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfffe8000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 180, 180, 180, 180 }
-	}, {
-		.mapbase	= 0xfffe8800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 184, 184, 184, 184 }
-	}, {
-		.mapbase	= 0xfffe9000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 188, 188, 188, 188 }
-	}, {
-		.mapbase	= 0xfffe9800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 192, 192, 192, 192 }
-	}, {
-		.mapbase	= 0xfffea000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 196, 196, 196, 196 }
-	}, {
-		.mapbase	= 0xfffea800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 200, 200, 200, 200 }
-	}, {
-		.mapbase	= 0xfffeb000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 204, 204, 204, 204 }
-	}, {
-		.mapbase	= 0xfffeb800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 208, 208, 208, 208 }
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xfffe8000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 180, 180, 180, 180 }
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xfffe8800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 184, 184, 184, 184 }
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xfffe9000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 188, 188, 188, 188 }
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xfffe9800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 192, 192, 192, 192 }
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xfffea000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 196, 196, 196, 196 }
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xfffea800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 200, 200, 200, 200 }
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+static struct plat_sci_port scif6_platform_data = {
+	.mapbase	= 0xfffeb000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 204, 204, 204, 204 }
+};
+
+static struct platform_device scif6_device = {
+	.name		= "sh-sci",
+	.id		= 6,
+	.dev		= {
+		.platform_data	= &scif6_platform_data,
+	},
+};
+
+static struct plat_sci_port scif7_platform_data = {
+	.mapbase	= 0xfffeb800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 208, 208, 208, 208 }
+};
+
+static struct platform_device scif7_device = {
+	.name		= "sh-sci",
+	.id		= 7,
+	.dev		= {
+		.platform_data	= &scif7_platform_data,
 	},
 };
 
@@ -345,7 +411,14 @@ static struct platform_device mtu2_2_dev
 };
 
 static struct platform_device *sh7201_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&scif7_device,
 	&rtc_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
@@ -365,6 +438,14 @@ void __init plat_irq_setup(void)
 }
 
 static struct platform_device *sh7201_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&scif7_device,
 	&mtu2_0_device,
 	&mtu2_1_device,
 	&mtu2_2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c	2010-02-24 13:52:17.000000000 -0500
@@ -173,37 +173,63 @@ static struct intc_mask_reg mask_registe
 static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups,
 			 mask_registers, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfffe8000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		=  { 192, 192, 192, 192 },
-	}, {
-		.mapbase	= 0xfffe8800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		=  { 196, 196, 196, 196 },
-	}, {
-		.mapbase	= 0xfffe9000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		=  { 200, 200, 200, 200 },
-	}, {
-		.mapbase	= 0xfffe9800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		=  { 204, 204, 204, 204 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xfffe8000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		=  { 192, 192, 192, 192 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xfffe8800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		=  { 196, 196, 196, 196 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xfffe9000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		=  { 200, 200, 200, 200 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xfffe9800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		=  { 204, 204, 204, 204 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
 	},
 };
 
@@ -354,7 +380,10 @@ static struct platform_device rtc_device
 };
 
 static struct platform_device *sh7203_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt0_device,
 	&cmt1_device,
 	&mtu2_0_device,
@@ -375,6 +404,10 @@ void __init plat_irq_setup(void)
 }
 
 static struct platform_device *sh7203_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt0_device,
 	&cmt1_device,
 	&mtu2_0_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c	2010-02-24 13:52:17.000000000 -0500
@@ -133,37 +133,63 @@ static struct intc_mask_reg mask_registe
 static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
 			 mask_registers, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfffe8000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 240, 240, 240, 240 },
-	}, {
-		.mapbase	= 0xfffe8800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 244, 244, 244, 244 },
-	}, {
-		.mapbase	= 0xfffe9000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 248, 248, 248, 248 },
-	}, {
-		.mapbase	= 0xfffe9800,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 252, 252, 252, 252 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xfffe8000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 240, 240, 240, 240 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xfffe8800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 244, 244, 244, 244 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xfffe9000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 248, 248, 248, 248 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xfffe9800,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 252, 252, 252, 252 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
 	},
 };
 
@@ -325,7 +351,10 @@ static struct platform_device mtu2_2_dev
 };
 
 static struct platform_device *sh7206_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt0_device,
 	&cmt1_device,
 	&mtu2_0_device,
@@ -346,6 +375,10 @@ void __init plat_irq_setup(void)
 }
 
 static struct platform_device *sh7206_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt0_device,
 	&cmt1_device,
 	&mtu2_0_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/entry.S linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/entry.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -132,7 +132,6 @@ ENTRY(tlb_protection_violation_store)
 	 mov	#1, r5
 
 call_handle_tlbmiss:
-	setup_frame_reg
 	mov.l	1f, r0
 	mov	r5, r8
 	mov.l	@r0, r6
@@ -297,41 +296,8 @@ ENTRY(vbr_base)
 !
 	.balign 	256,0,256
 general_exception:
-#ifndef CONFIG_CPU_SUBTYPE_SHX3
 	bra	handle_exception
 	 sts	pr, k3		! save original pr value in k3
-#else
-	mov.l	1f, k4
-	mov.l	@k4, k4
-
-	! Is EXPEVT larger than 0x800?
-	mov	#0x8, k0
-	shll8	k0
-	cmp/hs	k0, k4
-	bf	0f
-
-	! then add 0x580 (k2 is 0xd80 or 0xda0)
-	mov	#0x58, k0
-	shll2	k0
-	shll2	k0
-	add	k0, k4
-0:
-	! Setup stack and save DSP context (k0 contains original r15 on return)
-	bsr	prepare_stack
-	 nop
-
-	! Save registers / Switch to bank 0
-	mov		k4, k2		! keep vector in k2
-	mov.l	1f, k4		! SR bits to clear in k4
-	bsr	save_regs	! needs original pr value in k3
-	 nop
-
-	bra	handle_exception_special
-	 nop
-
-	.align	2
-1:	.long	EXPEVT
-#endif
 
 ! prepare_stack()
 ! - roll back gRB
@@ -398,6 +364,8 @@ handle_exception:
 	 mov.l	@k2, k2		! read out vector and keep in k2
 
 handle_exception_special:
+	setup_frame_reg
+
 	! Setup return address and jump to exception handler
 	mov.l	7f, r9		! fetch return address
 	stc	r2_bank, r0	! k2 (vector)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,27 +67,33 @@ static struct intc_prio_reg prio_registe
 static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xa4410000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 56, 56, 56 },
-	}, {
-		.mapbase	= 0xa4400000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 52, 52, 52 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xa4410000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 56, 56, 56 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xa4400000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 52, 52, 52 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
 	},
 };
 
@@ -210,10 +216,11 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh7705_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
-	&sci_device,
 	&rtc_device,
 };
 
@@ -225,6 +232,8 @@ static int __init sh7705_devices_setup(v
 arch_initcall(sh7705_devices_setup);
 
 static struct platform_device *sh7705_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c	2010-02-24 13:52:17.000000000 -0500
@@ -106,44 +106,55 @@ static struct platform_device rtc_device
 	.resource	= rtc_resources,
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfffffe80,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCI,
-		.irqs		= { 23, 23, 23, 0 },
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xfffffe80,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCI,
+	.irqs		= { 23, 23, 23, 0 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
 	},
+};
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
-	{
-		.mapbase	= 0xa4000150,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 56, 56, 56, 56 },
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xa4000150,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 56, 56, 56, 56 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
 	},
+};
 #endif
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
-	{
-		.mapbase	= 0xa4000140,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_IRDA,
-		.irqs		= { 52, 52, 52, 52 },
-	},
-#endif
-	{
-		.flags = 0,
-	}
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xa4000140,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_IRDA,
+	.irqs		= { 52, 52, 52, 52 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif2_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 2,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif2_platform_data,
 	},
 };
+#endif
 
 static struct sh_timer_config tmu0_platform_data = {
 	.name = "TMU0",
@@ -238,10 +249,19 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh770x_devices[] __initdata = {
+	&scif0_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
+	&scif1_device,
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
+	&scif2_device,
+#endif
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
-	&sci_device,
 	&rtc_device,
 };
 
@@ -253,6 +273,16 @@ static int __init sh770x_devices_setup(v
 arch_initcall(sh770x_devices_setup);
 
 static struct platform_device *sh770x_early_devices[] __initdata = {
+	&scif0_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
+	&scif1_device,
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
+	&scif2_device,
+#endif
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,28 +96,33 @@ static struct platform_device rtc_device
 	},
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xa4400000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 52, 52, 52, 52 },
-	}, {
-		.mapbase	= 0xa4410000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs           = { 56, 56, 56, 56 },
-	}, {
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xa4400000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 52, 52, 52, 52 },
+};
 
-		.flags = 0,
-	}
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
 };
 
-static struct platform_device sci_device = {
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xa4410000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 56, 56, 56, 56 },
+};
+
+static struct platform_device scif1_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 1,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif1_platform_data,
 	},
 };
 
@@ -214,10 +219,11 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh7710_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
-	&sci_device,
 	&rtc_device,
 };
 
@@ -229,6 +235,8 @@ static int __init sh7710_devices_setup(v
 arch_initcall(sh7710_devices_setup);
 
 static struct platform_device *sh7710_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,28 +48,33 @@ static struct platform_device rtc_device
 	},
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xa4430000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 80, 80, 80, 80 },
-	}, {
-		.mapbase	= 0xa4438000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs           = { 81, 81, 81, 81 },
-	}, {
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xa4430000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 80, 80, 80, 80 },
+};
 
-		.flags = 0,
-	}
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
 };
 
-static struct platform_device sci_device = {
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xa4438000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 1,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif1_platform_data,
 	},
 };
 
@@ -369,6 +374,8 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh7720_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&cmt0_device,
 	&cmt1_device,
 	&cmt2_device,
@@ -378,7 +385,6 @@ static struct platform_device *sh7720_de
 	&tmu1_device,
 	&tmu2_device,
 	&rtc_device,
-	&sci_device,
 	&usb_ohci_device,
 	&usbf_device,
 };
@@ -391,6 +397,8 @@ static int __init sh7720_devices_setup(v
 arch_initcall(sh7720_devices_setup);
 
 static struct platform_device *sh7720_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&cmt0_device,
 	&cmt1_device,
 	&cmt2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/fpu.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/fpu.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/fpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/fpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,13 +41,11 @@ static unsigned int fpu_exception_flags;
 
 /*
  * Save FPU registers onto task structure.
- * Assume called with FPU enabled (SR.FD=0).
  */
-void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
+void save_fpu(struct task_struct *tsk)
 {
 	unsigned long dummy;
 
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 	enable_fpu();
 	asm volatile ("sts.l	fpul, @-%0\n\t"
 		      "sts.l	fpscr, @-%0\n\t"
@@ -92,7 +90,6 @@ void save_fpu(struct task_struct *tsk, s
 		      :"memory");
 
 	disable_fpu();
-	release_fpu(regs);
 }
 
 static void restore_fpu(struct task_struct *tsk)
@@ -285,7 +282,6 @@ static int ieee_fpe_handler(struct pt_re
 		/* fcnvsd */
 		struct task_struct *tsk = current;
 
-		save_fpu(tsk, regs);
 		if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR))
 			/* FPU error */
 			denormal_to_double(&tsk->thread.fpu.hard,
@@ -462,7 +458,7 @@ BUILD_TRAP_HANDLER(fpu_error)
 	struct task_struct *tsk = current;
 	TRAP_HANDLER_DECL;
 
-	save_fpu(tsk, regs);
+	__unlazy_fpu(tsk, regs);
 	fpu_exception_flags = 0;
 	if (ieee_fpe_handler(regs)) {
 		tsk->thread.fpu.hard.fpscr &=
@@ -473,7 +469,7 @@ BUILD_TRAP_HANDLER(fpu_error)
 		tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10);
 		grab_fpu(regs);
 		restore_fpu(tsk);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 		if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) &
 		     (fpu_exception_flags >> 2)) == 0) {
 			return;
@@ -483,18 +479,18 @@ BUILD_TRAP_HANDLER(fpu_error)
 	force_sig(SIGFPE, tsk);
 }
 
-BUILD_TRAP_HANDLER(fpu_state_restore)
+void fpu_state_restore(struct pt_regs *regs)
 {
 	struct task_struct *tsk = current;
-	TRAP_HANDLER_DECL;
 
 	grab_fpu(regs);
-	if (!user_mode(regs)) {
+	if (unlikely(!user_mode(regs))) {
 		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
+		BUG();
 		return;
 	}
 
-	if (used_math()) {
+	if (likely(used_math())) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
 	} else {
@@ -502,5 +498,13 @@ BUILD_TRAP_HANDLER(fpu_state_restore)
 		fpu_init();
 		set_used_math();
 	}
-	set_tsk_thread_flag(tsk, TIF_USEDFPU);
+	task_thread_info(tsk)->status |= TS_USEDFPU;
+	tsk->fpu_counter++;
+}
+
+BUILD_TRAP_HANDLER(fpu_state_restore)
+{
+	TRAP_HANDLER_DECL;
+
+	fpu_state_restore(regs);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/Makefile linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,11 @@ obj-$(CONFIG_HIBERNATION)		+= $(addprefi
 obj-$(CONFIG_SH_FPU)			+= fpu.o softfloat.o
 obj-$(CONFIG_SH_STORE_QUEUES)		+= sq.o
 
+# Perf events
+perf-$(CONFIG_CPU_SUBTYPE_SH7750)	:= perf_event.o
+perf-$(CONFIG_CPU_SUBTYPE_SH7750S)	:= perf_event.o
+perf-$(CONFIG_CPU_SUBTYPE_SH7091)	:= perf_event.o
+
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7750)	+= setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7750R)	+= setup-sh7750.o
@@ -27,4 +32,5 @@ endif
 # Additional clocks by subtype
 clock-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= clock-sh4-202.o
 
-obj-y	+= $(clock-y)
+obj-y					+= $(clock-y)
+obj-$(CONFIG_PERF_EVENTS)		+= $(perf-y)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/perf_event.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/perf_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,253 @@
+/*
+ * Performance events support for SH7750-style performance counters
+ *
+ *  Copyright (C) 2009  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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+#define PM_CR_BASE	0xff000084	/* 16-bit */
+#define PM_CTR_BASE	0xff100004	/* 32-bit */
+
+#define PMCR(n)		(PM_CR_BASE + ((n) * 0x04))
+#define PMCTRH(n)	(PM_CTR_BASE + 0x00 + ((n) * 0x08))
+#define PMCTRL(n)	(PM_CTR_BASE + 0x04 + ((n) * 0x08))
+
+#define PMCR_PMM_MASK	0x0000003f
+
+#define PMCR_CLKF	0x00000100
+#define PMCR_PMCLR	0x00002000
+#define PMCR_PMST	0x00004000
+#define PMCR_PMEN	0x00008000
+
+static struct sh_pmu sh7750_pmu;
+
+/*
+ * There are a number of events supported by each counter (33 in total).
+ * Since we have 2 counters, each counter will take the event code as it
+ * corresponds to the PMCR PMM setting. Each counter can be configured
+ * independently.
+ *
+ *	Event Code	Description
+ *	----------	-----------
+ *
+ *	0x01		Operand read access
+ *	0x02		Operand write access
+ *	0x03		UTLB miss
+ *	0x04		Operand cache read miss
+ *	0x05		Operand cache write miss
+ *	0x06		Instruction fetch (w/ cache)
+ *	0x07		Instruction TLB miss
+ *	0x08		Instruction cache miss
+ *	0x09		All operand accesses
+ *	0x0a		All instruction accesses
+ *	0x0b		OC RAM operand access
+ *	0x0d		On-chip I/O space access
+ *	0x0e		Operand access (r/w)
+ *	0x0f		Operand cache miss (r/w)
+ *	0x10		Branch instruction
+ *	0x11		Branch taken
+ *	0x12		BSR/BSRF/JSR
+ *	0x13		Instruction execution
+ *	0x14		Instruction execution in parallel
+ *	0x15		FPU Instruction execution
+ *	0x16		Interrupt
+ *	0x17		NMI
+ *	0x18		trapa instruction execution
+ *	0x19		UBCA match
+ *	0x1a		UBCB match
+ *	0x21		Instruction cache fill
+ *	0x22		Operand cache fill
+ *	0x23		Elapsed time
+ *	0x24		Pipeline freeze by I-cache miss
+ *	0x25		Pipeline freeze by D-cache miss
+ *	0x27		Pipeline freeze by branch instruction
+ *	0x28		Pipeline freeze by CPU register
+ *	0x29		Pipeline freeze by FPU
+ */
+
+static const int sh7750_general_events[] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0023,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x000a,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0006,	/* I-cache */
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x0008,	/* I-cache */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0010,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= -1,
+	[PERF_COUNT_HW_BUS_CYCLES]		= -1,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+static const int sh7750_cache_events
+			[PERF_COUNT_HW_CACHE_MAX]
+			[PERF_COUNT_HW_CACHE_OP_MAX]
+			[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+	[ C(L1D) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0001,
+			[ C(RESULT_MISS)   ] = 0x0004,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0002,
+			[ C(RESULT_MISS)   ] = 0x0005,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(L1I) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0006,
+			[ C(RESULT_MISS)   ] = 0x0008,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(LL) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(DTLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x0003,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(ITLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x0007,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+
+	[ C(BPU) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+};
+
+static int sh7750_event_map(int event)
+{
+	return sh7750_general_events[event];
+}
+
+static u64 sh7750_pmu_read(int idx)
+{
+	return (u64)((u64)(__raw_readl(PMCTRH(idx)) & 0xffff) << 32) |
+			   __raw_readl(PMCTRL(idx));
+}
+
+static void sh7750_pmu_disable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readw(PMCR(idx));
+	tmp &= ~(PMCR_PMM_MASK | PMCR_PMEN);
+	__raw_writew(tmp, PMCR(idx));
+}
+
+static void sh7750_pmu_enable(struct hw_perf_event *hwc, int idx)
+{
+	__raw_writew(__raw_readw(PMCR(idx)) | PMCR_PMCLR, PMCR(idx));
+	__raw_writew(hwc->config | PMCR_PMEN | PMCR_PMST, PMCR(idx));
+}
+
+static void sh7750_pmu_disable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh7750_pmu.num_events; i++)
+		__raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
+}
+
+static void sh7750_pmu_enable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh7750_pmu.num_events; i++)
+		__raw_writew(__raw_readw(PMCR(i)) | PMCR_PMEN, PMCR(i));
+}
+
+static struct sh_pmu sh7750_pmu = {
+	.name		= "SH7750",
+	.num_events	= 2,
+	.event_map	= sh7750_event_map,
+	.max_events	= ARRAY_SIZE(sh7750_general_events),
+	.raw_event_mask	= PMCR_PMM_MASK,
+	.cache_events	= &sh7750_cache_events,
+	.read		= sh7750_pmu_read,
+	.disable	= sh7750_pmu_disable,
+	.enable		= sh7750_pmu_enable,
+	.disable_all	= sh7750_pmu_disable_all,
+	.enable_all	= sh7750_pmu_enable_all,
+};
+
+static int __init sh7750_pmu_init(void)
+{
+	/*
+	 * Make sure this CPU actually has perf counters.
+	 */
+	if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
+		pr_notice("HW perf events unsupported, software events only.\n");
+		return -ENODEV;
+	}
+
+	return register_sh_pmu(&sh7750_pmu);
+}
+arch_initcall(sh7750_pmu_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh4-202.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,22 +15,18 @@
 #include <linux/sh_timer.h>
 #include <linux/io.h>
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe80000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe80000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 41, 43, 42 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
 	},
 };
 
@@ -127,7 +123,7 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh4202_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -141,6 +137,7 @@ static int __init sh4202_devices_setup(v
 arch_initcall(sh4202_devices_setup);
 
 static struct platform_device *sh4202_early_devices[] __initdata = {
+	&scif0_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,29 +35,33 @@ static struct platform_device rtc_device
 	.resource	= rtc_resources,
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-#ifndef CONFIG_SH_RTS7751R2D
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCI,
-		.irqs		= { 23, 23, 23, 0 },
-	}, {
-#endif
-		.mapbase	= 0xffe80000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 40, 40, 40 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe00000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCI,
+	.irqs		= { 23, 23, 23, 0 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffe80000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 40, 40, 40 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
 	},
 };
 
@@ -221,8 +225,9 @@ static struct platform_device tmu4_devic
 #endif
 
 static struct platform_device *sh7750_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&rtc_device,
-	&sci_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -242,6 +247,8 @@ static int __init sh7750_devices_setup(v
 arch_initcall(sh7750_devices_setup);
 
 static struct platform_device *sh7750_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7760.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,37 +126,63 @@ static struct intc_vect vectors_irq[] __
 static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups,
 			 mask_registers, prio_registers, NULL);
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfe600000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 52, 53, 55, 54 },
-	}, {
-		.mapbase	= 0xfe610000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 72, 73, 75, 74 },
-	}, {
-		.mapbase	= 0xfe620000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 76, 77, 79, 78 },
-	}, {
-		.mapbase	= 0xfe480000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCI,
-		.irqs		= { 80, 81, 82, 0 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xfe600000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 52, 53, 55, 54 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xfe610000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 72, 73, 75, 74 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xfe620000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 76, 77, 79, 78 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xfe480000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCI,
+	.irqs		= { 80, 81, 82, 0 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
 	},
 };
 
@@ -254,7 +280,10 @@ static struct platform_device tmu2_devic
 
 
 static struct platform_device *sh7760_devices[] __initdata = {
-	&sci_device,
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -268,6 +297,10 @@ static int __init sh7760_devices_setup(v
 arch_initcall(sh7760_devices_setup);
 
 static struct platform_device *sh7760_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,7 +152,7 @@ struct clk div6_clks[] = {
 	SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0),
 	SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0),
 	SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0),
-	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
+	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
 };
 
 #define R_CLK (&r_clk)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/Makefile linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -44,3 +44,4 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= p
 obj-y				+= $(clock-y)
 obj-$(CONFIG_SMP)		+= $(smp-y)
 obj-$(CONFIG_GENERIC_GPIO)	+= $(pinmux-y)
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/perf_event.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/perf_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,269 @@
+/*
+ * Performance events support for SH-4A performance counters
+ *
+ *  Copyright (C) 2009  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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+#define PPC_CCBR(idx)	(0xff200800 + (sizeof(u32) * idx))
+#define PPC_PMCTR(idx)	(0xfc100000 + (sizeof(u32) * idx))
+
+#define CCBR_CIT_MASK	(0x7ff << 6)
+#define CCBR_DUC	(1 << 3)
+#define CCBR_CMDS	(1 << 1)
+#define CCBR_PPCE	(1 << 0)
+
+#define PPC_PMCAT	0xfc100080
+
+#define PMCAT_OVF3	(1 << 27)
+#define PMCAT_CNN3	(1 << 26)
+#define PMCAT_CLR3	(1 << 25)
+#define PMCAT_OVF2	(1 << 19)
+#define PMCAT_CLR2	(1 << 17)
+#define PMCAT_OVF1	(1 << 11)
+#define PMCAT_CNN1	(1 << 10)
+#define PMCAT_CLR1	(1 << 9)
+#define PMCAT_OVF0	(1 << 3)
+#define PMCAT_CLR0	(1 << 1)
+
+static struct sh_pmu sh4a_pmu;
+
+/*
+ * Supported raw event codes:
+ *
+ *	Event Code	Description
+ *	----------	-----------
+ *
+ *	0x0000		number of elapsed cycles
+ *	0x0200		number of elapsed cycles in privileged mode
+ *	0x0280		number of elapsed cycles while SR.BL is asserted
+ *	0x0202		instruction execution
+ *	0x0203		instruction execution in parallel
+ *	0x0204		number of unconditional branches
+ *	0x0208		number of exceptions
+ *	0x0209		number of interrupts
+ *	0x0220		UTLB miss caused by instruction fetch
+ *	0x0222		UTLB miss caused by operand access
+ *	0x02a0		number of ITLB misses
+ *	0x0028		number of accesses to instruction memories
+ *	0x0029		number of accesses to instruction cache
+ *	0x002a		instruction cache miss
+ *	0x022e		number of access to instruction X/Y memory
+ *	0x0030		number of reads to operand memories
+ *	0x0038		number of writes to operand memories
+ *	0x0031		number of operand cache read accesses
+ *	0x0039		number of operand cache write accesses
+ *	0x0032		operand cache read miss
+ *	0x003a		operand cache write miss
+ *	0x0236		number of reads to operand X/Y memory
+ *	0x023e		number of writes to operand X/Y memory
+ *	0x0237		number of reads to operand U memory
+ *	0x023f		number of writes to operand U memory
+ *	0x0337		number of U memory read buffer misses
+ *	0x02b4		number of wait cycles due to operand read access
+ *	0x02bc		number of wait cycles due to operand write access
+ *	0x0033		number of wait cycles due to operand cache read miss
+ *	0x003b		number of wait cycles due to operand cache write miss
+ */
+
+/*
+ * Special reserved bits used by hardware emulators, read values will
+ * vary, but writes must always be 0.
+ */
+#define PMCAT_EMU_CLR_MASK	((1 << 24) | (1 << 16) | (1 << 8) | (1 << 0))
+
+static const int sh4a_general_events[] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0000,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x0202,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0029,	/* I-cache */
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x002a,	/* I-cache */
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x0204,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= -1,
+	[PERF_COUNT_HW_BUS_CYCLES]		= -1,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+static const int sh4a_cache_events
+			[PERF_COUNT_HW_CACHE_MAX]
+			[PERF_COUNT_HW_CACHE_OP_MAX]
+			[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+	[ C(L1D) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0031,
+			[ C(RESULT_MISS)   ] = 0x0032,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0039,
+			[ C(RESULT_MISS)   ] = 0x003a,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(L1I) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0029,
+			[ C(RESULT_MISS)   ] = 0x002a,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(LL) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0030,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0038,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(DTLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0x0222,
+			[ C(RESULT_MISS)   ] = 0x0220,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0,
+		},
+	},
+
+	[ C(ITLB) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = 0,
+			[ C(RESULT_MISS)   ] = 0x02a0,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+
+	[ C(BPU) ] = {
+		[ C(OP_READ) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_WRITE) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+		[ C(OP_PREFETCH) ] = {
+			[ C(RESULT_ACCESS) ] = -1,
+			[ C(RESULT_MISS)   ] = -1,
+		},
+	},
+};
+
+static int sh4a_event_map(int event)
+{
+	return sh4a_general_events[event];
+}
+
+static u64 sh4a_pmu_read(int idx)
+{
+	return __raw_readl(PPC_PMCTR(idx));
+}
+
+static void sh4a_pmu_disable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(PPC_CCBR(idx));
+	tmp &= ~(CCBR_CIT_MASK | CCBR_DUC);
+	__raw_writel(tmp, PPC_CCBR(idx));
+}
+
+static void sh4a_pmu_enable(struct hw_perf_event *hwc, int idx)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(PPC_PMCAT);
+	tmp &= ~PMCAT_EMU_CLR_MASK;
+	tmp |= idx ? PMCAT_CLR1 : PMCAT_CLR0;
+	__raw_writel(tmp, PPC_PMCAT);
+
+	tmp = __raw_readl(PPC_CCBR(idx));
+	tmp |= (hwc->config << 6) | CCBR_CMDS | CCBR_PPCE;
+	__raw_writel(tmp, PPC_CCBR(idx));
+
+	__raw_writel(__raw_readl(PPC_CCBR(idx)) | CCBR_DUC, PPC_CCBR(idx));
+}
+
+static void sh4a_pmu_disable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh4a_pmu.num_events; i++)
+		__raw_writel(__raw_readl(PPC_CCBR(i)) & ~CCBR_DUC, PPC_CCBR(i));
+}
+
+static void sh4a_pmu_enable_all(void)
+{
+	int i;
+
+	for (i = 0; i < sh4a_pmu.num_events; i++)
+		__raw_writel(__raw_readl(PPC_CCBR(i)) | CCBR_DUC, PPC_CCBR(i));
+}
+
+static struct sh_pmu sh4a_pmu = {
+	.name		= "SH-4A",
+	.num_events	= 2,
+	.event_map	= sh4a_event_map,
+	.max_events	= ARRAY_SIZE(sh4a_general_events),
+	.raw_event_mask	= 0x3ff,
+	.cache_events	= &sh4a_cache_events,
+	.read		= sh4a_pmu_read,
+	.disable	= sh4a_pmu_disable,
+	.enable		= sh4a_pmu_enable,
+	.disable_all	= sh4a_pmu_disable_all,
+	.enable_all	= sh4a_pmu_enable_all,
+};
+
+static int __init sh4a_pmu_init(void)
+{
+	/*
+	 * Make sure this CPU actually has perf counters.
+	 */
+	if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
+		pr_notice("HW perf events unsupported, software events only.\n");
+		return -ENODEV;
+	}
+
+	return register_sh_pmu(&sh4a_pmu);
+}
+arch_initcall(sh4a_pmu_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,71 @@
 #include <linux/sh_timer.h>
 #include <asm/clock.h>
 
+/* Serial */
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase        = 0xffe00000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 80, 80, 80, 80 },
+	.clk		= "scif0",
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase        = 0xffe10000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+	.clk		= "scif1",
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase        = 0xffe20000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+	.clk		= "scif2",
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase        = 0xffe30000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 83, 83, 83, 83 },
+	.clk		= "scif3",
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
 static struct resource iic0_resources[] = {
 	[0] = {
 		.name	= "IIC0",
@@ -265,52 +330,17 @@ static struct platform_device tmu2_devic
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 80, 80, 80, 80 },
-		.clk		= "scif0",
-	}, {
-		.mapbase	= 0xffe10000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 81, 81, 81, 81 },
-		.clk		= "scif1",
-	}, {
-		.mapbase	= 0xffe20000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 82, 82, 82, 82 },
-		.clk		= "scif2",
-	}, {
-		.mapbase	= 0xffe30000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 83, 83, 83, 83 },
-		.clk		= "scif3",
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct platform_device *sh7343_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
 	&iic0_device,
 	&iic1_device,
-	&sci_device,
 	&vpu_device,
 	&veu_device,
 	&jpu_device,
@@ -328,6 +358,10 @@ static int __init sh7343_devices_setup(v
 arch_initcall(sh7343_devices_setup);
 
 static struct platform_device *sh7343_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,22 @@
 #include <linux/usb/r8a66597.h>
 #include <asm/clock.h>
 
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe00000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 80, 80, 80, 80 },
+	.clk		= "scif0",
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
 static struct resource iic_resources[] = {
 	[0] = {
 		.name	= "IIC",
@@ -276,33 +292,13 @@ static struct platform_device tmu2_devic
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 80, 80, 80, 80 },
-		.clk		= "scif0",
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct platform_device *sh7366_devices[] __initdata = {
+	&scif0_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
 	&iic_device,
-	&sci_device,
 	&usb_host_device,
 	&vpu_device,
 	&veu0_device,
@@ -321,6 +317,7 @@ static int __init sh7366_devices_setup(v
 arch_initcall(sh7366_devices_setup);
 
 static struct platform_device *sh7366_early_devices[] __initdata = {
+	&scif0_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,55 @@
 #include <asm/dma-sh.h>
 #include <cpu/sh7722.h>
 
+/* Serial */
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase        = 0xffe00000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 80, 80, 80, 80 },
+	.clk		= "scif0",
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase        = 0xffe10000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+	.clk		= "scif1",
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase        = 0xffe20000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+	.clk		= "scif2",
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
 static struct resource rtc_resources[] = {
 	[0] = {
 		.start	= 0xa465fec0,
@@ -339,41 +388,6 @@ static struct platform_device tmu2_devic
 	},
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 80, 80, 80, 80 },
-		.clk		= "scif0",
-	},
-	{
-		.mapbase	= 0xffe10000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 81, 81, 81, 81 },
-		.clk		= "scif1",
-	},
-	{
-		.mapbase	= 0xffe20000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 82, 82, 82, 82 },
-		.clk		= "scif2",
-	},
-	{
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct sh_dmae_pdata dma_platform_data = {
 	.mode = 0,
 };
@@ -387,6 +401,9 @@ static struct platform_device dma_device
 };
 
 static struct platform_device *sh7722_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
@@ -394,7 +411,6 @@ static struct platform_device *sh7722_de
 	&rtc_device,
 	&usbf_device,
 	&iic_device,
-	&sci_device,
 	&vpu_device,
 	&veu_device,
 	&jpu_device,
@@ -413,6 +429,9 @@ static int __init sh7722_devices_setup(v
 arch_initcall(sh7722_devices_setup);
 
 static struct platform_device *sh7722_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,103 @@
 #include <asm/mmzone.h>
 #include <cpu/sh7723.h>
 
+/* Serial */
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase        = 0xffe00000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 80, 80, 80, 80 },
+	.clk		= "scif0",
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase        = 0xffe10000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+	.clk		= "scif1",
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase        = 0xffe20000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+	.clk		= "scif2",
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase        = 0xa4e30000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 56, 56, 56, 56 },
+	.clk		= "scif3",
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase        = 0xa4e40000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 88, 88, 88, 88 },
+	.clk		= "scif4",
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase        = 0xa4e50000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 109, 109, 109, 109 },
+	.clk		= "scif5",
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
 static struct uio_info vpu_platform_data = {
 	.name = "VPU5",
 	.version = "0",
@@ -348,56 +445,6 @@ static struct platform_device tmu5_devic
 	},
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase        = 0xffe00000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 80, 80, 80, 80 },
-		.clk		= "scif0",
-	},{
-		.mapbase        = 0xffe10000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 81, 81, 81, 81 },
-		.clk		= "scif1",
-	},{
-		.mapbase        = 0xffe20000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 82, 82, 82, 82 },
-		.clk		= "scif2",
-	},{
-		.mapbase	= 0xa4e30000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 56, 56, 56, 56 },
-		.clk		= "scif3",
-	},{
-		.mapbase	= 0xa4e40000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 88, 88, 88, 88 },
-		.clk		= "scif4",
-	},{
-		.mapbase	= 0xa4e50000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 109, 109, 109, 109 },
-		.clk		= "scif5",
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct resource rtc_resources[] = {
 	[0] = {
 		.start	= 0xa465fec0,
@@ -488,6 +535,12 @@ static struct platform_device iic_device
 };
 
 static struct platform_device *sh7723_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
@@ -495,7 +548,6 @@ static struct platform_device *sh7723_de
 	&tmu3_device,
 	&tmu4_device,
 	&tmu5_device,
-	&sci_device,
 	&rtc_device,
 	&iic_device,
 	&sh7723_usb_host_device,
@@ -516,6 +568,12 @@ static int __init sh7723_devices_setup(v
 arch_initcall(sh7723_devices_setup);
 
 static struct platform_device *sh7723_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,58 +20,120 @@
 #include <linux/uio_driver.h>
 #include <linux/sh_timer.h>
 #include <linux/io.h>
+#include <linux/notifier.h>
+#include <asm/suspend.h>
 #include <asm/clock.h>
+#include <asm/dma-sh.h>
 #include <asm/mmzone.h>
 #include <cpu/sh7724.h>
 
+/* DMA */
+static struct sh_dmae_pdata dma_platform_data = {
+	.mode = SHDMA_DMAOR1,
+};
+
+static struct platform_device dma_device = {
+	.name	= "sh-dma-engine",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= &dma_platform_data,
+	},
+};
+
 /* Serial */
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase        = 0xffe00000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 80, 80, 80, 80 },
-		.clk		= "scif0",
-	}, {
-		.mapbase        = 0xffe10000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 81, 81, 81, 81 },
-		.clk		= "scif1",
-	}, {
-		.mapbase        = 0xffe20000,
-		.flags          = UPF_BOOT_AUTOCONF,
-		.type           = PORT_SCIF,
-		.irqs           = { 82, 82, 82, 82 },
-		.clk		= "scif2",
-	}, {
-		.mapbase	= 0xa4e30000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 56, 56, 56, 56 },
-		.clk		= "scif3",
-	}, {
-		.mapbase	= 0xa4e40000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 88, 88, 88, 88 },
-		.clk		= "scif4",
-	}, {
-		.mapbase	= 0xa4e50000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIFA,
-		.irqs		= { 109, 109, 109, 109 },
-		.clk		= "scif5",
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase        = 0xffe00000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 80, 80, 80, 80 },
+	.clk		= "scif0",
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase        = 0xffe10000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 81, 81, 81, 81 },
+	.clk		= "scif1",
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase        = 0xffe20000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIF,
+	.irqs           = { 82, 82, 82, 82 },
+	.clk		= "scif2",
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase        = 0xa4e30000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 56, 56, 56, 56 },
+	.clk		= "scif3",
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase        = 0xa4e40000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 88, 88, 88, 88 },
+	.clk		= "scif4",
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase        = 0xa4e50000,
+	.flags          = UPF_BOOT_AUTOCONF,
+	.type           = PORT_SCIFA,
+	.irqs           = { 109, 109, 109, 109 },
+	.clk		= "scif5",
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
 	},
 };
 
@@ -202,7 +264,7 @@ static struct resource veu0_resources[]
 	[0] = {
 		.name	= "VEU3F0",
 		.start	= 0xfe920000,
-		.end	= 0xfe9200cb - 1,
+		.end	= 0xfe9200cb,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -234,7 +296,7 @@ static struct resource veu1_resources[]
 	[0] = {
 		.name	= "VEU3F1",
 		.start	= 0xfe924000,
-		.end	= 0xfe9240cb - 1,
+		.end	= 0xfe9240cb,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -523,7 +585,77 @@ static struct platform_device jpu_device
 	},
 };
 
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+	.name = "SPU2DSP0",
+	.version = "0",
+	.irq = 86,
+};
+
+static struct resource spu0_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP0",
+		.start	= 0xFE200000,
+		.end	= 0xFE2FFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device spu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 4,
+	.dev = {
+		.platform_data	= &spu0_platform_data,
+	},
+	.resource	= spu0_resources,
+	.num_resources	= ARRAY_SIZE(spu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_SPU,
+	},
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+	.name = "SPU2DSP1",
+	.version = "0",
+	.irq = 87,
+};
+
+static struct resource spu1_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP1",
+		.start	= 0xFE300000,
+		.end	= 0xFE3FFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device spu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 5,
+	.dev = {
+		.platform_data	= &spu1_platform_data,
+	},
+	.resource	= spu1_resources,
+	.num_resources	= ARRAY_SIZE(spu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_SPU,
+	},
+};
+
 static struct platform_device *sh7724_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
@@ -531,7 +663,7 @@ static struct platform_device *sh7724_de
 	&tmu3_device,
 	&tmu4_device,
 	&tmu5_device,
-	&sci_device,
+	&dma_device,
 	&rtc_device,
 	&iic0_device,
 	&iic1_device,
@@ -539,6 +671,8 @@ static struct platform_device *sh7724_de
 	&veu0_device,
 	&veu1_device,
 	&jpu_device,
+	&spu0_device,
+	&spu1_device,
 };
 
 static int __init sh7724_devices_setup(void)
@@ -547,6 +681,8 @@ static int __init sh7724_devices_setup(v
 	platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
 	platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
 	platform_resource_setup_memory(&jpu_device,  "jpu",  2 << 20);
+	platform_resource_setup_memory(&spu0_device, "spu0", 2 << 20);
+	platform_resource_setup_memory(&spu1_device, "spu1", 2 << 20);
 
 	return platform_add_devices(sh7724_devices,
 				    ARRAY_SIZE(sh7724_devices));
@@ -554,6 +690,12 @@ static int __init sh7724_devices_setup(v
 arch_initcall(sh7724_devices_setup);
 
 static struct platform_device *sh7724_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&cmt_device,
 	&tmu0_device,
 	&tmu1_device,
@@ -827,3 +969,193 @@ void __init plat_irq_setup(void)
 {
 	register_intc_controller(&intc_desc);
 }
+
+static struct {
+	/* BSC */
+	unsigned long mmselr;
+	unsigned long cs0bcr;
+	unsigned long cs4bcr;
+	unsigned long cs5abcr;
+	unsigned long cs5bbcr;
+	unsigned long cs6abcr;
+	unsigned long cs6bbcr;
+	unsigned long cs4wcr;
+	unsigned long cs5awcr;
+	unsigned long cs5bwcr;
+	unsigned long cs6awcr;
+	unsigned long cs6bwcr;
+	/* INTC */
+	unsigned short ipra;
+	unsigned short iprb;
+	unsigned short iprc;
+	unsigned short iprd;
+	unsigned short ipre;
+	unsigned short iprf;
+	unsigned short iprg;
+	unsigned short iprh;
+	unsigned short ipri;
+	unsigned short iprj;
+	unsigned short iprk;
+	unsigned short iprl;
+	unsigned char imr0;
+	unsigned char imr1;
+	unsigned char imr2;
+	unsigned char imr3;
+	unsigned char imr4;
+	unsigned char imr5;
+	unsigned char imr6;
+	unsigned char imr7;
+	unsigned char imr8;
+	unsigned char imr9;
+	unsigned char imr10;
+	unsigned char imr11;
+	unsigned char imr12;
+	/* RWDT */
+	unsigned short rwtcnt;
+	unsigned short rwtcsr;
+	/* CPG */
+	unsigned long irdaclk;
+	unsigned long spuclk;
+} sh7724_rstandby_state;
+
+static int sh7724_pre_sleep_notifier_call(struct notifier_block *nb,
+					  unsigned long flags, void *unused)
+{
+	if (!(flags & SUSP_SH_RSTANDBY))
+		return NOTIFY_DONE;
+
+	/* BCR */
+	sh7724_rstandby_state.mmselr = __raw_readl(0xff800020); /* MMSELR */
+	sh7724_rstandby_state.mmselr |= 0xa5a50000;
+	sh7724_rstandby_state.cs0bcr = __raw_readl(0xfec10004); /* CS0BCR */
+	sh7724_rstandby_state.cs4bcr = __raw_readl(0xfec10010); /* CS4BCR */
+	sh7724_rstandby_state.cs5abcr = __raw_readl(0xfec10014); /* CS5ABCR */
+	sh7724_rstandby_state.cs5bbcr = __raw_readl(0xfec10018); /* CS5BBCR */
+	sh7724_rstandby_state.cs6abcr = __raw_readl(0xfec1001c); /* CS6ABCR */
+	sh7724_rstandby_state.cs6bbcr = __raw_readl(0xfec10020); /* CS6BBCR */
+	sh7724_rstandby_state.cs4wcr = __raw_readl(0xfec10030); /* CS4WCR */
+	sh7724_rstandby_state.cs5awcr = __raw_readl(0xfec10034); /* CS5AWCR */
+	sh7724_rstandby_state.cs5bwcr = __raw_readl(0xfec10038); /* CS5BWCR */
+	sh7724_rstandby_state.cs6awcr = __raw_readl(0xfec1003c); /* CS6AWCR */
+	sh7724_rstandby_state.cs6bwcr = __raw_readl(0xfec10040); /* CS6BWCR */
+
+	/* INTC */
+	sh7724_rstandby_state.ipra = __raw_readw(0xa4080000); /* IPRA */
+	sh7724_rstandby_state.iprb = __raw_readw(0xa4080004); /* IPRB */
+	sh7724_rstandby_state.iprc = __raw_readw(0xa4080008); /* IPRC */
+	sh7724_rstandby_state.iprd = __raw_readw(0xa408000c); /* IPRD */
+	sh7724_rstandby_state.ipre = __raw_readw(0xa4080010); /* IPRE */
+	sh7724_rstandby_state.iprf = __raw_readw(0xa4080014); /* IPRF */
+	sh7724_rstandby_state.iprg = __raw_readw(0xa4080018); /* IPRG */
+	sh7724_rstandby_state.iprh = __raw_readw(0xa408001c); /* IPRH */
+	sh7724_rstandby_state.ipri = __raw_readw(0xa4080020); /* IPRI */
+	sh7724_rstandby_state.iprj = __raw_readw(0xa4080024); /* IPRJ */
+	sh7724_rstandby_state.iprk = __raw_readw(0xa4080028); /* IPRK */
+	sh7724_rstandby_state.iprl = __raw_readw(0xa408002c); /* IPRL */
+	sh7724_rstandby_state.imr0 = __raw_readb(0xa4080080); /* IMR0 */
+	sh7724_rstandby_state.imr1 = __raw_readb(0xa4080084); /* IMR1 */
+	sh7724_rstandby_state.imr2 = __raw_readb(0xa4080088); /* IMR2 */
+	sh7724_rstandby_state.imr3 = __raw_readb(0xa408008c); /* IMR3 */
+	sh7724_rstandby_state.imr4 = __raw_readb(0xa4080090); /* IMR4 */
+	sh7724_rstandby_state.imr5 = __raw_readb(0xa4080094); /* IMR5 */
+	sh7724_rstandby_state.imr6 = __raw_readb(0xa4080098); /* IMR6 */
+	sh7724_rstandby_state.imr7 = __raw_readb(0xa408009c); /* IMR7 */
+	sh7724_rstandby_state.imr8 = __raw_readb(0xa40800a0); /* IMR8 */
+	sh7724_rstandby_state.imr9 = __raw_readb(0xa40800a4); /* IMR9 */
+	sh7724_rstandby_state.imr10 = __raw_readb(0xa40800a8); /* IMR10 */
+	sh7724_rstandby_state.imr11 = __raw_readb(0xa40800ac); /* IMR11 */
+	sh7724_rstandby_state.imr12 = __raw_readb(0xa40800b0); /* IMR12 */
+
+	/* RWDT */
+	sh7724_rstandby_state.rwtcnt = __raw_readb(0xa4520000); /* RWTCNT */
+	sh7724_rstandby_state.rwtcnt |= 0x5a00;
+	sh7724_rstandby_state.rwtcsr = __raw_readb(0xa4520004); /* RWTCSR */
+	sh7724_rstandby_state.rwtcsr |= 0xa500;
+	__raw_writew(sh7724_rstandby_state.rwtcsr & 0x07, 0xa4520004);
+
+	/* CPG */
+	sh7724_rstandby_state.irdaclk = __raw_readl(0xa4150018); /* IRDACLKCR */
+	sh7724_rstandby_state.spuclk = __raw_readl(0xa415003c); /* SPUCLKCR */
+
+	return NOTIFY_DONE;
+}
+
+static int sh7724_post_sleep_notifier_call(struct notifier_block *nb,
+					   unsigned long flags, void *unused)
+{
+	if (!(flags & SUSP_SH_RSTANDBY))
+		return NOTIFY_DONE;
+
+	/* BCR */
+	__raw_writel(sh7724_rstandby_state.mmselr, 0xff800020); /* MMSELR */
+	__raw_writel(sh7724_rstandby_state.cs0bcr, 0xfec10004); /* CS0BCR */
+	__raw_writel(sh7724_rstandby_state.cs4bcr, 0xfec10010); /* CS4BCR */
+	__raw_writel(sh7724_rstandby_state.cs5abcr, 0xfec10014); /* CS5ABCR */
+	__raw_writel(sh7724_rstandby_state.cs5bbcr, 0xfec10018); /* CS5BBCR */
+	__raw_writel(sh7724_rstandby_state.cs6abcr, 0xfec1001c); /* CS6ABCR */
+	__raw_writel(sh7724_rstandby_state.cs6bbcr, 0xfec10020); /* CS6BBCR */
+	__raw_writel(sh7724_rstandby_state.cs4wcr, 0xfec10030); /* CS4WCR */
+	__raw_writel(sh7724_rstandby_state.cs5awcr, 0xfec10034); /* CS5AWCR */
+	__raw_writel(sh7724_rstandby_state.cs5bwcr, 0xfec10038); /* CS5BWCR */
+	__raw_writel(sh7724_rstandby_state.cs6awcr, 0xfec1003c); /* CS6AWCR */
+	__raw_writel(sh7724_rstandby_state.cs6bwcr, 0xfec10040); /* CS6BWCR */
+
+	/* INTC */
+	__raw_writew(sh7724_rstandby_state.ipra, 0xa4080000); /* IPRA */
+	__raw_writew(sh7724_rstandby_state.iprb, 0xa4080004); /* IPRB */
+	__raw_writew(sh7724_rstandby_state.iprc, 0xa4080008); /* IPRC */
+	__raw_writew(sh7724_rstandby_state.iprd, 0xa408000c); /* IPRD */
+	__raw_writew(sh7724_rstandby_state.ipre, 0xa4080010); /* IPRE */
+	__raw_writew(sh7724_rstandby_state.iprf, 0xa4080014); /* IPRF */
+	__raw_writew(sh7724_rstandby_state.iprg, 0xa4080018); /* IPRG */
+	__raw_writew(sh7724_rstandby_state.iprh, 0xa408001c); /* IPRH */
+	__raw_writew(sh7724_rstandby_state.ipri, 0xa4080020); /* IPRI */
+	__raw_writew(sh7724_rstandby_state.iprj, 0xa4080024); /* IPRJ */
+	__raw_writew(sh7724_rstandby_state.iprk, 0xa4080028); /* IPRK */
+	__raw_writew(sh7724_rstandby_state.iprl, 0xa408002c); /* IPRL */
+	__raw_writeb(sh7724_rstandby_state.imr0, 0xa4080080); /* IMR0 */
+	__raw_writeb(sh7724_rstandby_state.imr1, 0xa4080084); /* IMR1 */
+	__raw_writeb(sh7724_rstandby_state.imr2, 0xa4080088); /* IMR2 */
+	__raw_writeb(sh7724_rstandby_state.imr3, 0xa408008c); /* IMR3 */
+	__raw_writeb(sh7724_rstandby_state.imr4, 0xa4080090); /* IMR4 */
+	__raw_writeb(sh7724_rstandby_state.imr5, 0xa4080094); /* IMR5 */
+	__raw_writeb(sh7724_rstandby_state.imr6, 0xa4080098); /* IMR6 */
+	__raw_writeb(sh7724_rstandby_state.imr7, 0xa408009c); /* IMR7 */
+	__raw_writeb(sh7724_rstandby_state.imr8, 0xa40800a0); /* IMR8 */
+	__raw_writeb(sh7724_rstandby_state.imr9, 0xa40800a4); /* IMR9 */
+	__raw_writeb(sh7724_rstandby_state.imr10, 0xa40800a8); /* IMR10 */
+	__raw_writeb(sh7724_rstandby_state.imr11, 0xa40800ac); /* IMR11 */
+	__raw_writeb(sh7724_rstandby_state.imr12, 0xa40800b0); /* IMR12 */
+
+	/* RWDT */
+	__raw_writew(sh7724_rstandby_state.rwtcnt, 0xa4520000); /* RWTCNT */
+	__raw_writew(sh7724_rstandby_state.rwtcsr, 0xa4520004); /* RWTCSR */
+
+	/* CPG */
+	__raw_writel(sh7724_rstandby_state.irdaclk, 0xa4150018); /* IRDACLKCR */
+	__raw_writel(sh7724_rstandby_state.spuclk, 0xa415003c); /* SPUCLKCR */
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sh7724_pre_sleep_notifier = {
+	.notifier_call = sh7724_pre_sleep_notifier_call,
+	.priority = SH_MOBILE_PRE(SH_MOBILE_SLEEP_CPU),
+};
+
+static struct notifier_block sh7724_post_sleep_notifier = {
+	.notifier_call = sh7724_post_sleep_notifier_call,
+	.priority = SH_MOBILE_POST(SH_MOBILE_SLEEP_CPU),
+};
+
+static int __init sh7724_sleep_setup(void)
+{
+	atomic_notifier_chain_register(&sh_mobile_pre_sleep_notifier_list,
+				       &sh7724_pre_sleep_notifier);
+
+	atomic_notifier_chain_register(&sh_mobile_post_sleep_notifier_list,
+				       &sh7724_post_sleep_notifier);
+	return 0;
+}
+arch_initcall(sh7724_sleep_setup);
+
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,51 @@
 #include <linux/mm.h>
 #include <linux/sh_timer.h>
 
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xfe4b0000,		/* SCIF2 */
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 40, 40, 40 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xfe4c0000,		/* SCIF3 */
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 76, 76, 76, 76 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xfe4d0000,		/* SCIF4 */
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 104, 104, 104, 104 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
 static struct sh_timer_config tmu0_platform_data = {
 	.name = "TMU0",
 	.channel_offset = 0x04,
@@ -79,39 +124,12 @@ static struct platform_device tmu1_devic
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xfe4b0000,		/* SCIF2 */
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 40, 40, 40 },
-	}, {
-		.mapbase	= 0xfe4c0000,		/* SCIF3 */
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 76, 76, 76, 76 },
-	}, {
-		.mapbase	= 0xfe4d0000,		/* SCIF4 */
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 104, 104, 104, 104 },
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct platform_device *sh7757_devices[] __initdata = {
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
 	&tmu0_device,
 	&tmu1_device,
-	&sci_device,
 };
 
 static int __init sh7757_devices_setup(void)
@@ -121,6 +139,20 @@ static int __init sh7757_devices_setup(v
 }
 arch_initcall(sh7757_devices_setup);
 
+static struct platform_device *sh7757_early_devices[] __initdata = {
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&tmu0_device,
+	&tmu1_device,
+};
+
+void __init plat_early_device_setup(void)
+{
+	early_platform_add_devices(sh7757_early_devices,
+				   ARRAY_SIZE(sh7757_early_devices));
+}
+
 enum {
 	UNUSED = 0,
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,51 @@
 #include <linux/io.h>
 #include <linux/serial_sci.h>
 
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe00000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 40, 40, 40 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffe08000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 76, 76, 76, 76 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffe10000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 104, 104, 104, 104 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
 static struct resource rtc_resources[] = {
 	[0] = {
 		.start	= 0xffe80000,
@@ -36,35 +81,6 @@ static struct platform_device rtc_device
 	.resource	= rtc_resources,
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 40, 40, 40 },
-	}, {
-		.mapbase	= 0xffe08000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 76, 76, 76, 76 },
-	}, {
-		.mapbase	= 0xffe10000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 104, 104, 104, 104 },
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct resource usb_ohci_resources[] = {
 	[0] = {
 		.start	= 0xffec8000,
@@ -297,6 +313,9 @@ static struct platform_device tmu5_devic
 };
 
 static struct platform_device *sh7763_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -304,7 +323,6 @@ static struct platform_device *sh7763_de
 	&tmu4_device,
 	&tmu5_device,
 	&rtc_device,
-	&sci_device,
 	&usb_ohci_device,
 	&usbf_device,
 };
@@ -317,6 +335,9 @@ static int __init sh7763_devices_setup(v
 arch_initcall(sh7763_devices_setup);
 
 static struct platform_device *sh7763_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7770.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,67 +14,153 @@
 #include <linux/sh_timer.h>
 #include <linux/io.h>
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xff923000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 61, 61, 61, 61 },
-	}, {
-		.mapbase	= 0xff924000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 62, 62, 62, 62 },
-	}, {
-		.mapbase	= 0xff925000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 63, 63, 63, 63 },
-	}, {
-		.mapbase	= 0xff926000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 64, 64, 64, 64 },
-	}, {
-		.mapbase	= 0xff927000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 65, 65, 65, 65 },
-	}, {
-		.mapbase	= 0xff928000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 66, 66, 66, 66 },
-	}, {
-		.mapbase	= 0xff929000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 67, 67, 67, 67 },
-	}, {
-		.mapbase	= 0xff92a000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 68, 68, 68, 68 },
-	}, {
-		.mapbase	= 0xff92b000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 69, 69, 69, 69 },
-	}, {
-		.mapbase	= 0xff92c000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 70, 70, 70, 70 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xff923000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 61, 61, 61, 61 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xff924000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 62, 62, 62, 62 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xff925000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 63, 63, 63, 63 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xff926000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 64, 64, 64, 64 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xff927000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 65, 65, 65, 65 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xff928000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 66, 66, 66, 66 },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+static struct plat_sci_port scif6_platform_data = {
+	.mapbase	= 0xff929000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 67, 67, 67, 67 },
+};
+
+static struct platform_device scif6_device = {
+	.name		= "sh-sci",
+	.id		= 6,
+	.dev		= {
+		.platform_data	= &scif6_platform_data,
+	},
+};
+
+static struct plat_sci_port scif7_platform_data = {
+	.mapbase	= 0xff92a000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 68, 68, 68, 68 },
+};
+
+static struct platform_device scif7_device = {
+	.name		= "sh-sci",
+	.id		= 7,
+	.dev		= {
+		.platform_data	= &scif7_platform_data,
+	},
+};
+
+static struct plat_sci_port scif8_platform_data = {
+	.mapbase	= 0xff92b000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 69, 69, 69, 69 },
+};
+
+static struct platform_device scif8_device = {
+	.name		= "sh-sci",
+	.id		= 8,
+	.dev		= {
+		.platform_data	= &scif8_platform_data,
+	},
+};
+
+static struct plat_sci_port scif9_platform_data = {
+	.mapbase	= 0xff92c000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 70, 70, 70, 70 },
+};
+
+static struct platform_device scif9_device = {
+	.name		= "sh-sci",
+	.id		= 9,
+	.dev		= {
+		.platform_data	= &scif9_platform_data,
 	},
 };
 
@@ -351,6 +437,16 @@ static struct platform_device tmu8_devic
 };
 
 static struct platform_device *sh7770_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&scif7_device,
+	&scif8_device,
+	&scif9_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -360,7 +456,6 @@ static struct platform_device *sh7770_de
 	&tmu6_device,
 	&tmu7_device,
 	&tmu8_device,
-	&sci_device,
 };
 
 static int __init sh7770_devices_setup(void)
@@ -371,6 +466,16 @@ static int __init sh7770_devices_setup(v
 arch_initcall(sh7770_devices_setup);
 
 static struct platform_device *sh7770_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&scif6_device,
+	&scif7_device,
+	&scif8_device,
+	&scif9_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,36 @@
 #include <linux/sh_timer.h>
 #include <asm/dma-sh.h>
 
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe00000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 40, 40, 40 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffe10000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 76, 76, 76, 76 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
 static struct sh_timer_config tmu0_platform_data = {
 	.name = "TMU0",
 	.channel_offset = 0x04,
@@ -217,30 +247,6 @@ static struct platform_device rtc_device
 	.resource	= rtc_resources,
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffe00000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 40, 40, 40 },
-	}, {
-		.mapbase	= 0xffe10000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 76, 76, 76, 76 },
-	}, {
-		.flags = 0,
-	}
-};
-
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
-	},
-};
-
 static struct sh_dmae_pdata dma_platform_data = {
 	.mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
 };
@@ -254,6 +260,8 @@ static struct platform_device dma_device
 };
 
 static struct platform_device *sh7780_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -261,7 +269,6 @@ static struct platform_device *sh7780_de
 	&tmu4_device,
 	&tmu5_device,
 	&rtc_device,
-	&sci_device,
 	&dma_device,
 };
 
@@ -271,8 +278,9 @@ static int __init sh7780_devices_setup(v
 				    ARRAY_SIZE(sh7780_devices));
 }
 arch_initcall(sh7780_devices_setup);
-
 static struct platform_device *sh7780_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,8 +14,105 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/sh_timer.h>
+#include <asm/dma-sh.h>
 #include <asm/mmzone.h>
 
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffea0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 40, 40, 40 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffeb0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 44, 44, 44, 44 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffec0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 60, 60, 60, 60 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xffed0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 61, 61, 61, 61 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xffee0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 62, 62, 62, 62 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xffef0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 63, 63, 63, 63 },
+	.clk		= "scif_fck",
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
 static struct sh_timer_config tmu0_platform_data = {
 	.name = "TMU0",
 	.channel_offset = 0x04,
@@ -198,64 +295,32 @@ static struct platform_device tmu5_devic
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
 };
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffea0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 40, 40, 40 },
-		.clk		= "scif_fck",
-	}, {
-		.mapbase	= 0xffeb0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 44, 44, 44, 44 },
-		.clk		= "scif_fck",
-	}, {
-		.mapbase	= 0xffec0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 60, 60, 60, 60 },
-		.clk		= "scif_fck",
-	}, {
-		.mapbase	= 0xffed0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 61, 61, 61, 61 },
-		.clk		= "scif_fck",
-	}, {
-		.mapbase	= 0xffee0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 62, 62, 62, 62 },
-		.clk		= "scif_fck",
-	}, {
-		.mapbase	= 0xffef0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 63, 63, 63, 63 },
-		.clk		= "scif_fck",
-	}, {
-		.flags = 0,
-	}
+static struct sh_dmae_pdata dma_platform_data = {
+	.mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
 };
 
-static struct platform_device sci_device = {
-	.name		= "sh-sci",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= sci_platform_data,
+static struct platform_device dma_device = {
+	.name           = "sh-dma-engine",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &dma_platform_data,
 	},
 };
 
 static struct platform_device *sh7785_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
 	&tmu3_device,
 	&tmu4_device,
 	&tmu5_device,
-	&sci_device,
+	&dma_device,
 };
 
 static int __init sh7785_devices_setup(void)
@@ -266,6 +331,12 @@ static int __init sh7785_devices_setup(v
 arch_initcall(sh7785_devices_setup);
 
 static struct platform_device *sh7785_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,51 +23,96 @@
 #include <linux/sh_timer.h>
 #include <asm/mmzone.h>
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffea0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffea0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 41, 43, 42 },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
 	},
-	/*
-	 * The rest of these all have multiplexed IRQs
-	 */
-	{
-		.mapbase	= 0xffeb0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 44, 44, 44, 44 },
-	}, {
-		.mapbase	= 0xffec0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 50, 50, 50, 50 },
-	}, {
-		.mapbase	= 0xffed0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 51, 51, 51, 51 },
-	}, {
-		.mapbase	= 0xffee0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 52, 52, 52, 52 },
-	}, {
-		.mapbase	= 0xffef0000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 53, 53, 53, 53 },
-	}, {
-		.flags = 0,
-	}
 };
 
-static struct platform_device sci_device = {
+/*
+ * The rest of these all have multiplexed IRQs
+ */
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffeb0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 44, 44, 44, 44 },
+};
+
+static struct platform_device scif1_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 1,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffec0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 50, 50, 50, 50 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xffed0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 51, 51, 51, 51 },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xffee0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 52, 52, 52, 52 },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xffef0000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 53, 53, 53, 53 },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
 	},
 };
 
@@ -459,6 +504,12 @@ static struct platform_device usb_ohci_d
 };
 
 static struct platform_device *sh7786_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -474,7 +525,6 @@ static struct platform_device *sh7786_ea
 };
 
 static struct platform_device *sh7786_devices[] __initdata = {
-	&sci_device,
 	&usb_ohci_device,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-shx3.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-shx3.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/setup-shx3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/setup-shx3.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,37 +15,57 @@
 #include <linux/sh_timer.h>
 #include <asm/mmzone.h>
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= 0xffc30000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
-	}, {
-		.mapbase	= 0xffc40000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 44, 45, 47, 46 },
-	}, {
-		.mapbase	= 0xffc50000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 48, 49, 51, 50 },
-	}, {
-		.mapbase	= 0xffc60000,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.type		= PORT_SCIF,
-		.irqs		= { 52, 53, 55, 54 },
-	}, {
-		.flags = 0,
-	}
+/*
+ * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
+ * INTEVT values overlap with the FPU EXPEVT ones, requiring special
+ * demuxing in the exception dispatch path.
+ *
+ * As this overlap is something that never should have made it in to
+ * silicon in the first place, we just refuse to deal with the port at
+ * all rather than adding infrastructure to hack around it.
+ */
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffc30000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 40, 41, 43, 42 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffc40000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 44, 45, 47, 46 },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffc60000,
+	.flags		= UPF_BOOT_AUTOCONF,
+	.type		= PORT_SCIF,
+	.irqs		= { 52, 53, 55, 54 },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
 	},
 };
 
@@ -232,6 +252,9 @@ static struct platform_device tmu5_devic
 };
 
 static struct platform_device *shx3_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
@@ -240,21 +263,10 @@ static struct platform_device *shx3_earl
 	&tmu5_device,
 };
 
-static struct platform_device *shx3_devices[] __initdata = {
-	&sci_device,
-};
-
 static int __init shx3_devices_setup(void)
 {
-	int ret;
-
-	ret = platform_add_devices(shx3_early_devices,
+	return platform_add_devices(shx3_early_devices,
 				   ARRAY_SIZE(shx3_early_devices));
-	if (unlikely(ret != 0))
-		return ret;
-
-	return platform_add_devices(shx3_devices,
-				    ARRAY_SIZE(shx3_devices));
 }
 arch_initcall(shx3_devices_setup);
 
@@ -268,7 +280,11 @@ enum {
 	UNUSED = 0,
 
 	/* interrupt sources */
-	IRL, IRQ0, IRQ1, IRQ2, IRQ3,
+	IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
+	IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
+	IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
+	IRL_HHLL, IRL_HHLH, IRL_HHHL,
+	IRQ0, IRQ1, IRQ2, IRQ3,
 	HUDII,
 	TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
 	PCII0, PCII1, PCII2, PCII3, PCII4,
@@ -291,7 +307,7 @@ enum {
 	INTICI4, INTICI5, INTICI6, INTICI7,
 
 	/* interrupt groups */
-	PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
+	IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
 	DMAC0, DMAC1,
 };
 
@@ -309,8 +325,6 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
 	INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
 	INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
-	INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
-	INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
 	INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
 	INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
 	INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
@@ -344,10 +358,13 @@ static struct intc_vect vectors[] __init
 };
 
 static struct intc_group groups[] __initdata = {
+	INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
+		   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
+		   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
+		   IRL_HHLL, IRL_HHLH, IRL_HHHL),
 	INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
 	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
 	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
 	INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
 	INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
 		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
@@ -419,14 +436,14 @@ static DECLARE_INTC_DESC(intc_desc_irq,
 
 /* External interrupt pins in IRL mode */
 static struct intc_vect vectors_irl[] __initdata = {
-	INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220),
-	INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260),
-	INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0),
-	INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0),
-	INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320),
-	INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360),
-	INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0),
-	INTC_VECT(IRL, 0x3c0),
+	INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
+	INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
+	INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
+	INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
+	INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
+	INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
+	INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
+	INTC_VECT(IRL_HHHL, 0x3c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,13 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
+#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
+#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
+
+#define STBCR_MSTP	0x00000001
+#define STBCR_RESET	0x00000002
+#define STBCR_LTSLP	0x80000000
+
 static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
 {
 	unsigned int message = (unsigned int)(long)arg;
@@ -21,9 +28,9 @@ static irqreturn_t ipi_interrupt_handler
 	unsigned int offs = 4 * cpu;
 	unsigned int x;
 
-	x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
+	x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
 	x &= (1 << (message << 2));
-	ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
+	__raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
 
 	smp_message_recv(message);
 
@@ -37,6 +44,9 @@ void __init plat_smp_setup(void)
 
 	init_cpu_possible(cpumask_of(cpu));
 
+	/* Enable light sleep for the boot CPU */
+	__raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu));
+
 	__cpu_number_map[0] = 0;
 	__cpu_logical_map[0] = 0;
 
@@ -66,32 +76,23 @@ void __init plat_prepare_cpus(unsigned i
 			    "IPI", (void *)(long)i);
 }
 
-#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
-#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
-
-#define STBCR_MSTP	0x00000001
-#define STBCR_RESET	0x00000002
-#define STBCR_LTSLP	0x80000000
-
-#define STBCR_AP_VAL	(STBCR_RESET | STBCR_LTSLP)
-
 void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
 {
-	ctrl_outl(entry_point, RESET_REG(cpu));
+	__raw_writel(entry_point, RESET_REG(cpu));
 
-	if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
-		ctrl_outl(STBCR_MSTP, STBCR_REG(cpu));
+	if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
+		__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
 
-	while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
+	while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
 		cpu_relax();
 
 	/* Start up secondary processor by sending a reset */
-	ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu));
+	__raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
 }
 
 int plat_smp_processor_id(void)
 {
-	return ctrl_inl(0xff000048); /* CPIDR */
+	return __raw_readl(0xff000048); /* CPIDR */
 }
 
 void plat_send_ipi(unsigned int cpu, unsigned int message)
@@ -100,5 +101,5 @@ void plat_send_ipi(unsigned int cpu, uns
 
 	BUG_ON(cpu >= 4);
 
-	ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
+	__raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/entry.S linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/entry.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -933,7 +933,7 @@ ret_with_reschedule:
 
 	pta	restore_all, tr1
 
-	movi	(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8
+	movi	_TIF_SIGPENDING, r8
 	and	r8, r7, r8
 	pta	work_notifysig, tr0
 	bne	r8, ZERO, tr0
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/fpu.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/fpu.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/fpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/fpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@ static union sh_fpu_union init_fpuregs =
 	}
 };
 
-void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
+void save_fpu(struct task_struct *tsk)
 {
 	asm volatile("fst.p     %0, (0*8), fp0\n\t"
 		     "fst.p     %0, (1*8), fp2\n\t"
@@ -153,7 +153,7 @@ do_fpu_state_restore(unsigned long ex, s
 	enable_fpu();
 	if (last_task_used_math != NULL)
 		/* Other processes fpu state, save away */
-		save_fpu(last_task_used_math, regs);
+		save_fpu(last_task_used_math);
 
         last_task_used_math = current;
         if (used_math()) {
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/setup-sh5.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/setup-sh5.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/sh5/setup-sh5.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/sh5/setup-sh5.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,22 +16,18 @@
 #include <linux/sh_timer.h>
 #include <asm/addrspace.h>
 
-static struct plat_sci_port sci_platform_data[] = {
-	{
-		.mapbase	= PHYS_PERIPHERAL_BLOCK + 0x01030000,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-		.type		= PORT_SCIF,
-		.irqs		= { 39, 40, 42, 0 },
-	}, {
-		.flags = 0,
-	}
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= PHYS_PERIPHERAL_BLOCK + 0x01030000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.type		= PORT_SCIF,
+	.irqs		= { 39, 40, 42, 0 },
 };
 
-static struct platform_device sci_device = {
+static struct platform_device scif0_device = {
 	.name		= "sh-sci",
-	.id		= -1,
+	.id		= 0,
 	.dev		= {
-		.platform_data	= sci_platform_data,
+		.platform_data	= &scif0_platform_data,
 	},
 };
 
@@ -164,13 +160,13 @@ static struct platform_device tmu2_devic
 };
 
 static struct platform_device *sh5_early_devices[] __initdata = {
+	&scif0_device,
 	&tmu0_device,
 	&tmu1_device,
 	&tmu2_device,
 };
 
 static struct platform_device *sh5_devices[] __initdata = {
-	&sci_device,
 	&rtc_device,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/cpuidle.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/cpuidle.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/cpuidle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/cpuidle.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,25 +87,31 @@ void sh_mobile_setup_cpuidle(void)
 
 	dev->safe_state = state;
 
-	state = &dev->states[i++];
-	snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
-	strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
-	state->exit_latency = 100;
-	state->target_residency = 1 * 2;
-	state->power_usage = 1;
-	state->flags = 0;
-	state->flags |= CPUIDLE_FLAG_TIME_VALID;
-	state->enter = cpuidle_sleep_enter;
+	if (sh_mobile_sleep_supported & SUSP_SH_SF) {
+		state = &dev->states[i++];
+		snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+		strncpy(state->desc, "SuperH Sleep Mode [SF]",
+			CPUIDLE_DESC_LEN);
+		state->exit_latency = 100;
+		state->target_residency = 1 * 2;
+		state->power_usage = 1;
+		state->flags = 0;
+		state->flags |= CPUIDLE_FLAG_TIME_VALID;
+		state->enter = cpuidle_sleep_enter;
+	}
 
-	state = &dev->states[i++];
-	snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
-	strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
-	state->exit_latency = 2300;
-	state->target_residency = 1 * 2;
-	state->power_usage = 1;
-	state->flags = 0;
-	state->flags |= CPUIDLE_FLAG_TIME_VALID;
-	state->enter = cpuidle_sleep_enter;
+	if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
+		state = &dev->states[i++];
+		snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+		strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
+			CPUIDLE_DESC_LEN);
+		state->exit_latency = 2300;
+		state->target_residency = 1 * 2;
+		state->power_usage = 1;
+		state->flags = 0;
+		state->flags |= CPUIDLE_FLAG_TIME_VALID;
+		state->enter = cpuidle_sleep_enter;
+	}
 
 	dev->state_count = i;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/pm.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,13 @@
 #include <linux/suspend.h>
 #include <asm/suspend.h>
 #include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Notifier lists for pre/post sleep notification
+ */
+ATOMIC_NOTIFIER_HEAD(sh_mobile_pre_sleep_notifier_list);
+ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list);
 
 /*
  * Sleep modes available on SuperH Mobile:
@@ -26,30 +33,105 @@
 #define SUSP_MODE_SLEEP		(SUSP_SH_SLEEP)
 #define SUSP_MODE_SLEEP_SF	(SUSP_SH_SLEEP | SUSP_SH_SF)
 #define SUSP_MODE_STANDBY_SF	(SUSP_SH_STANDBY | SUSP_SH_SF)
+#define SUSP_MODE_RSTANDBY	(SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF)
+ /*
+  * U-standby mode is unsupported since it needs bootloader hacks
+  */
 
-/*
- * The following modes are not there yet:
- *
- * R-standby mode is unsupported, but will be added in the future
- * U-standby mode is low priority since it needs bootloader hacks
- */
-
-#define ILRAM_BASE 0xe5200000
-
-extern const unsigned char sh_mobile_standby[];
-extern const unsigned int sh_mobile_standby_size;
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+#define RAM_BASE 0xfd800000 /* RSMEM */
+#else
+#define RAM_BASE 0xe5200000 /* ILRAM */
+#endif
 
 void sh_mobile_call_standby(unsigned long mode)
 {
-	void *onchip_mem = (void *)ILRAM_BASE;
-	void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem;
+	void *onchip_mem = (void *)RAM_BASE;
+	struct sh_sleep_data *sdp = onchip_mem;
+	void (*standby_onchip_mem)(unsigned long, unsigned long);
+
+	/* code located directly after data structure */
+	standby_onchip_mem = (void *)(sdp + 1);
+
+	atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list,
+				   mode, NULL);
+
+	/* flush the caches if MMU flag is set */
+	if (mode & SUSP_SH_MMU)
+		flush_cache_all();
 
 	/* Let assembly snippet in on-chip memory handle the rest */
-	standby_onchip_mem(mode, ILRAM_BASE);
+	standby_onchip_mem(mode, RAM_BASE);
+
+	atomic_notifier_call_chain(&sh_mobile_post_sleep_notifier_list,
+				   mode, NULL);
+}
+
+extern char sh_mobile_sleep_enter_start;
+extern char sh_mobile_sleep_enter_end;
+
+extern char sh_mobile_sleep_resume_start;
+extern char sh_mobile_sleep_resume_end;
+
+unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP;
+
+void sh_mobile_register_self_refresh(unsigned long flags,
+				     void *pre_start, void *pre_end,
+				     void *post_start, void *post_end)
+{
+	void *onchip_mem = (void *)RAM_BASE;
+	void *vp;
+	struct sh_sleep_data *sdp;
+	int n;
+
+	/* part 0: data area */
+	sdp = onchip_mem;
+	sdp->addr.stbcr = 0xa4150020; /* STBCR */
+	sdp->addr.bar = 0xa4150040; /* BAR */
+	sdp->addr.pteh = 0xff000000; /* PTEH */
+	sdp->addr.ptel = 0xff000004; /* PTEL */
+	sdp->addr.ttb = 0xff000008; /* TTB */
+	sdp->addr.tea = 0xff00000c; /* TEA */
+	sdp->addr.mmucr = 0xff000010; /* MMUCR */
+	sdp->addr.ptea = 0xff000034; /* PTEA */
+	sdp->addr.pascr = 0xff000070; /* PASCR */
+	sdp->addr.irmcr = 0xff000078; /* IRMCR */
+	sdp->addr.ccr = 0xff00001c; /* CCR */
+	sdp->addr.ramcr = 0xff000074; /* RAMCR */
+	vp = sdp + 1;
+
+	/* part 1: common code to enter sleep mode */
+	n = &sh_mobile_sleep_enter_end - &sh_mobile_sleep_enter_start;
+	memcpy(vp, &sh_mobile_sleep_enter_start, n);
+	vp += roundup(n, 4);
+
+	/* part 2: board specific code to enter self-refresh mode */
+	n = pre_end - pre_start;
+	memcpy(vp, pre_start, n);
+	sdp->sf_pre = (unsigned long)vp;
+	vp += roundup(n, 4);
+
+	/* part 3: board specific code to resume from self-refresh mode */
+	n = post_end - post_start;
+	memcpy(vp, post_start, n);
+	sdp->sf_post = (unsigned long)vp;
+	vp += roundup(n, 4);
+
+	/* part 4: common code to resume from sleep mode */
+	WARN_ON(vp > (onchip_mem + 0x600));
+	vp = onchip_mem + 0x600; /* located at interrupt vector */
+	n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start;
+	memcpy(vp, &sh_mobile_sleep_resume_start, n);
+	sdp->resume = (unsigned long)vp;
+
+	sh_mobile_sleep_supported |= flags;
 }
 
 static int sh_pm_enter(suspend_state_t state)
 {
+	if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF))
+		return -ENXIO;
+
 	local_irq_disable();
 	set_bl_bit();
 	sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);
@@ -65,13 +147,6 @@ static struct platform_suspend_ops sh_pm
 
 static int __init sh_pm_init(void)
 {
-	void *onchip_mem = (void *)ILRAM_BASE;
-
-	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
-	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
-	wmb();
-	ctrl_barrier();
-
 	suspend_set_ops(&sh_pm_ops);
 	sh_mobile_setup_cpuidle();
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/pm_runtime.c linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm_runtime.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/pm_runtime.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/pm_runtime.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,12 +45,14 @@ static int __platform_pm_runtime_resume(
 
 	dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
 
-	if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) {
+	if (d->driver) {
 		hwblk_enable(hwblk_info, hwblk);
 		ret = 0;
 
 		if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
-			ret = d->driver->pm->runtime_resume(d);
+			if (d->driver->pm && d->driver->pm->runtime_resume)
+				ret = d->driver->pm->runtime_resume(d);
+
 			if (!ret)
 				clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
 			else
@@ -73,12 +75,15 @@ static int __platform_pm_runtime_suspend
 
 	dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
 
-	if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) {
+	if (d->driver) {
 		BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
+		ret = 0;
 
-		hwblk_enable(hwblk_info, hwblk);
-		ret = d->driver->pm->runtime_suspend(d);
-		hwblk_disable(hwblk_info, hwblk);
+		if (d->driver->pm && d->driver->pm->runtime_suspend) {
+			hwblk_enable(hwblk_info, hwblk);
+			ret = d->driver->pm->runtime_suspend(d);
+			hwblk_disable(hwblk_info, hwblk);
+		}
 
 		if (!ret) {
 			set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	2010-02-24 13:52:17.000000000 -0500
@@ -20,79 +20,103 @@
  * Kernel mode register usage, see entry.S:
  *	k0	scratch
  *	k1	scratch
- *	k4	scratch
  */
 #define k0	r0
 #define k1	r1
-#define k4	r4
 
-/* manage self-refresh and enter standby mode.
+/* manage self-refresh and enter standby mode. must be self-contained.
  * this code will be copied to on-chip memory and executed from there.
  */
+	.balign 4
+ENTRY(sh_mobile_sleep_enter_start)
 
-	.balign 	4096,0,4096
-ENTRY(sh_mobile_standby)
+	/* save mode flags */
+	mov.l	r4, @(SH_SLEEP_MODE, r5)
 
 	/* save original vbr */
-	stc	vbr, r1
-	mova	saved_vbr, r0
-	mov.l	r1, @r0
+	stc	vbr, r0
+	mov.l	r0, @(SH_SLEEP_VBR, r5)
 
 	/* point vbr to our on-chip memory page */
 	ldc	r5, vbr
 
 	/* save return address */
-	mova	saved_spc, r0
-	sts	pr, r5
-	mov.l	r5, @r0
+	sts	pr, r0
+	mov.l	r0, @(SH_SLEEP_SPC, r5)
 
 	/* save sr */
-	mova	saved_sr, r0
-	stc	sr, r5
-	mov.l	r5, @r0
+	stc	sr, r0
+	mov.l	r0, @(SH_SLEEP_SR, r5)
 
-	/* save mode flags */
-	mova	saved_mode, r0
-	mov.l	r4, @r0
+	/* save sp */
+	mov.l	r15, @(SH_SLEEP_SP, r5)
 
-	/* put mode flags in r0 */
-	mov	r4, r0
+	/* save stbcr */
+	bsr     save_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
 
-	tst	#SUSP_SH_SF, r0
-	bt	skip_set_sf
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-	/* DBSC: put memory in self-refresh mode */
-	mov.l	dben_reg, r4
-	mov.l	dben_data0, r1
-	mov.l	r1, @r4
+	/* save mmu and cache context if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_MMU, r0
+	bt	skip_mmu_save_disable
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data0, r1
-	mov.l	r1, @r4
+       /* save mmu state */
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEH, r0
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data0, r1
-	mov.l	r1, @r4
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEL, r0
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data1, r1
-	mov.l	r1, @r4
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_TTB, r0
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data1, r1
-	mov.l	r1, @r4
-#else
-	/* SBSC: disable power down and put in self-refresh mode */
-	mov.l	1f, r4
-	mov.l	2f, r1
-	mov.l	@r4, r2
-	or	r1, r2
-	mov.l   3f, r3
-	and	r3, r2
-	mov.l	r2, @r4
-#endif
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_TEA, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PTEA, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_PASCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_IRMCR, r0
+
+	/* invalidate TLBs and disable the MMU */
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+	mov	#4, r1
+	mov.l	r1, @r0
+	icbi	@r0
+
+	/* save cache registers and disable caches */
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+
+	bsr	save_register
+	 mov	#SH_SLEEP_REG_RAMCR, r0
+
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+	mov	#0, r1
+	mov.l	r1, @r0
+	icbi	@r0
+
+skip_mmu_save_disable:
+	/* call self-refresh entering code if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_SF, r0
+	bt	skip_set_sf
+
+	mov.l	@(SH_SLEEP_SF_PRE, r5), r0
+	jsr	@r0
+	 nop
 
 skip_set_sf:
+	mov.l	@(SH_SLEEP_MODE, r5), r0
 	tst	#SUSP_SH_STANDBY, r0
 	bt	test_rstandby
 
@@ -104,6 +128,12 @@ test_rstandby:
 	tst	#SUSP_SH_RSTANDBY, r0
 	bt	test_ustandby
 
+	/* setup BAR register */
+	bsr	get_register
+	 mov	#SH_SLEEP_REG_BAR, r0
+	mov.l	@(SH_SLEEP_RESUME, r5), r1
+	mov.l	r1, @r0
+
 	/* set mode to "r-standby mode" */
 	bra	do_sleep
 	 mov	#0x20, r1
@@ -123,124 +153,136 @@ force_sleep:
 
 do_sleep:
 	/* setup and enter selected standby mode */
-	mov.l	5f, r4
-	mov.l	r1, @r4
+	bsr     get_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
+	mov.l	r1, @r0
 again:
 	sleep
 	bra	again
 	 nop
 
-restore_jump_vbr:
+save_register:
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r1
+	add	#-SH_SLEEP_BASE_ADDR, r0
+	mov.l	@r1, r1
+	add	#SH_SLEEP_BASE_DATA, r0
+	mov.l	r1, @(r0, r5)
+	add	#-SH_SLEEP_BASE_DATA, r0
+	rts
+	 nop
+
+get_register:
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r0
+	rts
+	 nop
+ENTRY(sh_mobile_sleep_enter_end)
+
+	.balign 4
+ENTRY(sh_mobile_sleep_resume_start)
+
+	/* figure out start address */
+	bsr	0f
+	 nop
+0:
+	sts	pr, k1
+	mov.l	1f, k0
+	and	k0, k1
+
+	/* store pointer to data area in VBR */
+	ldc	k1, vbr
+
+	/* setup sr with saved sr */
+	mov.l	@(SH_SLEEP_SR, k1), k0
+	ldc	k0, sr
+
+	/* now: user register set! */
+	stc	vbr, r5
+
 	/* setup spc with return address to c code */
-	mov.l	saved_spc, k0
-	ldc	k0, spc
+	mov.l	@(SH_SLEEP_SPC, r5), r0
+	ldc	r0, spc
 
 	/* restore vbr */
-	mov.l	saved_vbr, k0
-	ldc	k0, vbr
+	mov.l	@(SH_SLEEP_VBR, r5), r0
+	ldc	r0, vbr
 
 	/* setup ssr with saved sr */
-	mov.l	saved_sr, k0
-	ldc	k0, ssr
+	mov.l	@(SH_SLEEP_SR, r5), r0
+	ldc	r0, ssr
 
-	/* get mode flags */
-	mov.l	saved_mode, k0
+	/* restore sp */
+	mov.l   @(SH_SLEEP_SP, r5), r15
 
-done_sleep:
-	/* reset standby mode to sleep mode */
-	mov.l	5f, k4
-	mov	#0x00, k1
-	mov.l	k1, @k4
+	/* restore sleep mode register */
+	bsr     restore_register
+	 mov    #SH_SLEEP_REG_STBCR, r0
 
-	tst	#SUSP_SH_SF, k0
+	/* call self-refresh resume code if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_SF, r0
 	bt	skip_restore_sf
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-	/* DBSC: put memory in auto-refresh mode */
-	mov.l	dbrfpdn0_reg, k4
-	mov.l	dbrfpdn0_data0, k1
-	mov.l	k1, @k4
+	mov.l	@(SH_SLEEP_SF_POST, r5), r0
+	jsr	@r0
+	 nop
 
-	nop /* sleep 140 ns */
-	nop
-	nop
-	nop
+skip_restore_sf:
+	/* restore mmu and cache state if needed */
+	mov.l	@(SH_SLEEP_MODE, r5), r0
+	tst	#SUSP_SH_MMU, r0
+	bt	skip_restore_mmu
 
-	mov.l	dbcmdcnt_reg, k4
-	mov.l	dbcmdcnt_data0, k1
-	mov.l	k1, @k4
+	/* restore mmu state */
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEH, r0
 
-	mov.l	dbcmdcnt_reg, k4
-	mov.l	dbcmdcnt_data1, k1
-	mov.l	k1, @k4
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEL, r0
 
-	mov.l	dben_reg, k4
-	mov.l	dben_data1, k1
-	mov.l	k1, @k4
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_TTB, r0
 
-	mov.l	dbrfpdn0_reg, k4
-	mov.l	dbrfpdn0_data2, k1
-	mov.l	k1, @k4
-#else
-	/* SBSC: set auto-refresh mode */
-	mov.l	1f, k4
-	mov.l	@k4, k0
-	mov.l   4f, k1
-	and	k1, k0
-	mov.l	k0, @k4
-	mov.l	6f, k4
-	mov.l	8f, k0
-	mov.l	@k4, k1
-	mov	#-1, k4
-	add	k4, k1
-	or	k1, k0
-	mov.l	7f, k1
-	mov.l	k0, @k1
-#endif
-skip_restore_sf:
-	/* jump to vbr vector */
-	mov.l	saved_vbr, k0
-	mov.l	offset_vbr, k4
-	add	k4, k0
-	jmp	@k0
-	 nop
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_TEA, r0
 
-	.balign 4
-saved_mode:	.long	0
-saved_spc:	.long	0
-saved_sr:	.long	0
-saved_vbr:	.long	0
-offset_vbr:	.long	0x600
-#ifdef CONFIG_CPU_SUBTYPE_SH7724
-dben_reg:	.long	0xfd000010 /* DBEN */
-dben_data0:	.long	0
-dben_data1:	.long	1
-dbrfpdn0_reg:	.long	0xfd000040 /* DBRFPDN0 */
-dbrfpdn0_data0:	.long	0
-dbrfpdn0_data1:	.long	1
-dbrfpdn0_data2:	.long	0x00010000
-dbcmdcnt_reg:	.long	0xfd000014 /* DBCMDCNT */
-dbcmdcnt_data0:	.long	2
-dbcmdcnt_data1:	.long	4
-#else
-1:	.long	0xfe400008 /* SDCR0 */
-2:	.long	0x00000400
-3:	.long	0xffff7fff
-4:	.long	0xfffffbff
-#endif
-5:	.long	0xa4150020 /* STBCR */
-6:	.long   0xfe40001c /* RTCOR */
-7:	.long   0xfe400018 /* RTCNT */
-8:	.long   0xa55a0000
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PTEA, r0
 
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_PASCR, r0
 
-/* interrupt vector @ 0x600 */
-	.balign 	0x400,0,0x400
-	.long	0xdeadbeef
-	.balign 	0x200,0,0x200
-	bra	restore_jump_vbr
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_IRMCR, r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_MMUCR, r0
+	icbi	@r0
+
+	/* restore cache settings */
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_RAMCR, r0
+	icbi	@r0
+
+	bsr	restore_register
+	 mov	#SH_SLEEP_REG_CCR, r0
+	icbi	@r0
+
+skip_restore_mmu:
+	rte
 	 nop
-sh_mobile_standby_end:
 
-ENTRY(sh_mobile_standby_size)
-	.long sh_mobile_standby_end - sh_mobile_standby
+restore_register:
+	add	#SH_SLEEP_BASE_DATA, r0
+	mov.l	@(r0, r5), r1
+	add	#-SH_SLEEP_BASE_DATA, r0
+	add	#SH_SLEEP_BASE_ADDR, r0
+	mov.l	@(r0, r5), r0
+	mov.l	r1, @r0
+	rts
+	 nop
+
+	.balign 4
+1:	.long	~0x7ff
+ENTRY(sh_mobile_sleep_resume_end)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/ubc.S linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/ubc.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/cpu/ubc.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/cpu/ubc.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/*
- * arch/sh/kernel/cpu/ubc.S
- *
- * Set of management routines for the User Break Controller (UBC)
- *
- * Copyright (C) 2002 Paul Mundt
- *
- * 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 <asm/ubc.h>
-
-#define STBCR2		0xffc00010
-
-ENTRY(ubc_sleep)
-	mov	#0, r0
-
-	mov.l	1f, r1		! Zero out UBC_BBRA ..
-	mov.w	r0, @r1
-
-	mov.l	2f, r1		! .. same for BBRB ..
-	mov.w	r0, @r1
-
-	mov.l	3f, r1		! .. and again for BRCR.
-	mov.w	r0, @r1
-
-	mov.w	@r1, r0		! Dummy read BRCR
-
-	mov.l	4f, r1		! Set MSTP5 in STBCR2
-	mov.b	@r1, r0
-	or	#0x01, r0
-	mov.b	r0, @r1
-
-	mov.b	@r1, r0		! Two dummy reads ..
-	mov.b	@r1, r0
-
-	rts
-	nop
-
-ENTRY(ubc_wakeup)
-	mov.l	4f, r1		! Clear MSTP5
-	mov.b	@r1, r0
-	and	#0xfe, r0
-	mov.b	r0, @r1
-
-	mov.b	@r1, r0		! Two more dummy reads ..
-	mov.b	@r1, r0
-
-	rts
-	nop
-
-1:	.long	UBC_BBRA
-2:	.long	UBC_BBRB
-3:	.long	UBC_BRCR
-4:	.long	STBCR2
-
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/dma-nommu.c linux-libre-2.6.33-gnu1/arch/sh/kernel/dma-nommu.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/dma-nommu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/dma-nommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,82 @@
+/*
+ * DMA mapping support for platforms lacking IOMMUs.
+ *
+ * Copyright (C) 2009  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/dma-mapping.h>
+#include <linux/io.h>
+
+static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction dir,
+				 struct dma_attrs *attrs)
+{
+	dma_addr_t addr = page_to_phys(page) + offset;
+
+	WARN_ON(size == 0);
+	dma_cache_sync(dev, page_address(page) + offset, size, dir);
+
+	return addr;
+}
+
+static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir,
+			struct dma_attrs *attrs)
+{
+	struct scatterlist *s;
+	int i;
+
+	WARN_ON(nents == 0 || sg[0].length == 0);
+
+	for_each_sg(sg, s, nents, i) {
+		BUG_ON(!sg_page(s));
+
+		dma_cache_sync(dev, sg_virt(s), s->length, dir);
+
+		s->dma_address = sg_phys(s);
+		s->dma_length = s->length;
+	}
+
+	return nents;
+}
+
+#ifdef CONFIG_DMA_NONCOHERENT
+static void nommu_sync_single(struct device *dev, dma_addr_t addr,
+			      size_t size, enum dma_data_direction dir)
+{
+	dma_cache_sync(dev, phys_to_virt(addr), size, dir);
+}
+
+static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,
+			  int nelems, enum dma_data_direction dir)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nelems, i)
+		dma_cache_sync(dev, sg_virt(s), s->length, dir);
+}
+#endif
+
+struct dma_map_ops nommu_dma_ops = {
+	.alloc_coherent		= dma_generic_alloc_coherent,
+	.free_coherent		= dma_generic_free_coherent,
+	.map_page		= nommu_map_page,
+	.map_sg			= nommu_map_sg,
+#ifdef CONFIG_DMA_NONCOHERENT
+	.sync_single_for_device	= nommu_sync_single,
+	.sync_sg_for_device	= nommu_sync_sg,
+#endif
+	.is_phys		= 1,
+};
+
+void __init no_iommu_init(void)
+{
+	if (dma_ops)
+		return;
+	dma_ops = &nommu_dma_ops;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/dwarf.c linux-libre-2.6.33-gnu1/arch/sh/kernel/dwarf.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/dwarf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/dwarf.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/mempool.h>
 #include <linux/mm.h>
+#include <linux/elf.h>
 #include <linux/ftrace.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
@@ -530,7 +531,20 @@ static int dwarf_cfa_execute_insns(unsig
 }
 
 /**
- *	dwarf_unwind_stack - recursively unwind the stack
+ *	dwarf_free_frame - free the memory allocated for @frame
+ *	@frame: the frame to free
+ */
+void dwarf_free_frame(struct dwarf_frame *frame)
+{
+	dwarf_frame_free_regs(frame);
+	mempool_free(frame, dwarf_frame_pool);
+}
+
+extern void ret_from_irq(void);
+
+/**
+ *	dwarf_unwind_stack - unwind the stack
+ *
  *	@pc: address of the function to unwind
  *	@prev: struct dwarf_frame of the previous stackframe on the callstack
  *
@@ -548,9 +562,9 @@ struct dwarf_frame * dwarf_unwind_stack(
 	unsigned long addr;
 
 	/*
-	 * If this is the first invocation of this recursive function we
-	 * need get the contents of a physical register to get the CFA
-	 * in order to begin the virtual unwinding of the stack.
+	 * If we're starting at the top of the stack we need get the
+	 * contents of a physical register to get the CFA in order to
+	 * begin the virtual unwinding of the stack.
 	 *
 	 * NOTE: the return address is guaranteed to be setup by the
 	 * time this function makes its first function call.
@@ -593,9 +607,8 @@ struct dwarf_frame * dwarf_unwind_stack(
 	fde = dwarf_lookup_fde(pc);
 	if (!fde) {
 		/*
-		 * This is our normal exit path - the one that stops the
-		 * recursion. There's two reasons why we might exit
-		 * here,
+		 * This is our normal exit path. There are two reasons
+		 * why we might exit here,
 		 *
 		 *	a) pc has no asscociated DWARF frame info and so
 		 *	we don't know how to unwind this frame. This is
@@ -637,10 +650,10 @@ struct dwarf_frame * dwarf_unwind_stack(
 
 		} else {
 			/*
-			 * Again, this is the first invocation of this
-			 * recurisve function. We need to physically
-			 * read the contents of a register in order to
-			 * get the Canonical Frame Address for this
+			 * Again, we're starting from the top of the
+			 * stack. We need to physically read
+			 * the contents of a register in order to get
+			 * the Canonical Frame Address for this
 			 * function.
 			 */
 			frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
@@ -667,16 +680,33 @@ struct dwarf_frame * dwarf_unwind_stack(
 	addr = frame->cfa + reg->addr;
 	frame->return_addr = __raw_readl(addr);
 
+	/*
+	 * Ah, the joys of unwinding through interrupts.
+	 *
+	 * Interrupts are tricky - the DWARF info needs to be _really_
+	 * accurate and unfortunately I'm seeing a lot of bogus DWARF
+	 * info. For example, I've seen interrupts occur in epilogues
+	 * just after the frame pointer (r14) had been restored. The
+	 * problem was that the DWARF info claimed that the CFA could be
+	 * reached by using the value of the frame pointer before it was
+	 * restored.
+	 *
+	 * So until the compiler can be trusted to produce reliable
+	 * DWARF info when it really matters, let's stop unwinding once
+	 * we've calculated the function that was interrupted.
+	 */
+	if (prev && prev->pc == (unsigned long)ret_from_irq)
+		frame->return_addr = 0;
+
 	return frame;
 
 bail:
-	dwarf_frame_free_regs(frame);
-	mempool_free(frame, dwarf_frame_pool);
+	dwarf_free_frame(frame);
 	return NULL;
 }
 
 static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
-			   unsigned char *end)
+			   unsigned char *end, struct module *mod)
 {
 	struct dwarf_cie *cie;
 	unsigned long flags;
@@ -772,6 +802,8 @@ static int dwarf_parse_cie(void *entry,
 	cie->initial_instructions = p;
 	cie->instructions_end = end;
 
+	cie->mod = mod;
+
 	/* Add to list */
 	spin_lock_irqsave(&dwarf_cie_lock, flags);
 	list_add_tail(&cie->link, &dwarf_cie_list);
@@ -782,7 +814,7 @@ static int dwarf_parse_cie(void *entry,
 
 static int dwarf_parse_fde(void *entry, u32 entry_type,
 			   void *start, unsigned long len,
-			   unsigned char *end)
+			   unsigned char *end, struct module *mod)
 {
 	struct dwarf_fde *fde;
 	struct dwarf_cie *cie;
@@ -831,6 +863,8 @@ static int dwarf_parse_fde(void *entry,
 	fde->instructions = p;
 	fde->end = end;
 
+	fde->mod = mod;
+
 	/* Add to list. */
 	spin_lock_irqsave(&dwarf_fde_lock, flags);
 	list_add_tail(&fde->link, &dwarf_fde_list);
@@ -854,10 +888,8 @@ static void dwarf_unwinder_dump(struct t
 	while (1) {
 		frame = dwarf_unwind_stack(return_addr, _frame);
 
-		if (_frame) {
-			dwarf_frame_free_regs(_frame);
-			mempool_free(_frame, dwarf_frame_pool);
-		}
+		if (_frame)
+			dwarf_free_frame(_frame);
 
 		_frame = frame;
 
@@ -867,6 +899,9 @@ static void dwarf_unwinder_dump(struct t
 		return_addr = frame->return_addr;
 		ops->address(data, return_addr, 1);
 	}
+
+	if (frame)
+		dwarf_free_frame(frame);
 }
 
 static struct unwinder dwarf_unwinder = {
@@ -877,18 +912,18 @@ static struct unwinder dwarf_unwinder =
 
 static void dwarf_unwinder_cleanup(void)
 {
-	struct dwarf_cie *cie;
-	struct dwarf_fde *fde;
+	struct dwarf_cie *cie, *cie_tmp;
+	struct dwarf_fde *fde, *fde_tmp;
 
 	/*
 	 * Deallocate all the memory allocated for the DWARF unwinder.
 	 * Traverse all the FDE/CIE lists and remove and free all the
 	 * memory associated with those data structures.
 	 */
-	list_for_each_entry(cie, &dwarf_cie_list, link)
+	list_for_each_entry_safe(cie, cie_tmp, &dwarf_cie_list, link)
 		kfree(cie);
 
-	list_for_each_entry(fde, &dwarf_fde_list, link)
+	list_for_each_entry_safe(fde, fde_tmp, &dwarf_fde_list, link)
 		kfree(fde);
 
 	kmem_cache_destroy(dwarf_reg_cachep);
@@ -896,48 +931,28 @@ static void dwarf_unwinder_cleanup(void)
 }
 
 /**
- *	dwarf_unwinder_init - initialise the dwarf unwinder
+ *	dwarf_parse_section - parse DWARF section
+ *	@eh_frame_start: start address of the .eh_frame section
+ *	@eh_frame_end: end address of the .eh_frame section
+ *	@mod: the kernel module containing the .eh_frame section
  *
- *	Build the data structures describing the .dwarf_frame section to
- *	make it easier to lookup CIE and FDE entries. Because the
- *	.eh_frame section is packed as tightly as possible it is not
- *	easy to lookup the FDE for a given PC, so we build a list of FDE
- *	and CIE entries that make it easier.
+ *	Parse the information in a .eh_frame section.
  */
-static int __init dwarf_unwinder_init(void)
+static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
+			       struct module *mod)
 {
 	u32 entry_type;
 	void *p, *entry;
 	int count, err = 0;
-	unsigned long len;
+	unsigned long len = 0;
 	unsigned int c_entries, f_entries;
 	unsigned char *end;
-	INIT_LIST_HEAD(&dwarf_cie_list);
-	INIT_LIST_HEAD(&dwarf_fde_list);
 
 	c_entries = 0;
 	f_entries = 0;
-	entry = &__start_eh_frame;
-
-	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
-			sizeof(struct dwarf_frame), 0,
-			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
-
-	dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
-			sizeof(struct dwarf_reg), 0,
-			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
-
-	dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ,
-					  mempool_alloc_slab,
-					  mempool_free_slab,
-					  dwarf_frame_cachep);
-
-	dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
-					 mempool_alloc_slab,
-					 mempool_free_slab,
-					 dwarf_reg_cachep);
+	entry = eh_frame_start;
 
-	while ((char *)entry < __stop_eh_frame) {
+	while ((char *)entry < eh_frame_end) {
 		p = entry;
 
 		count = dwarf_entry_len(p, &len);
@@ -949,6 +964,7 @@ static int __init dwarf_unwinder_init(vo
 			 * entry and move to the next one because 'len'
 			 * tells us where our next entry is.
 			 */
+			err = -EINVAL;
 			goto out;
 		} else
 			p += count;
@@ -960,13 +976,14 @@ static int __init dwarf_unwinder_init(vo
 		p += 4;
 
 		if (entry_type == DW_EH_FRAME_CIE) {
-			err = dwarf_parse_cie(entry, p, len, end);
+			err = dwarf_parse_cie(entry, p, len, end, mod);
 			if (err < 0)
 				goto out;
 			else
 				c_entries++;
 		} else {
-			err = dwarf_parse_fde(entry, entry_type, p, len, end);
+			err = dwarf_parse_fde(entry, entry_type, p, len,
+					      end, mod);
 			if (err < 0)
 				goto out;
 			else
@@ -979,6 +996,129 @@ static int __init dwarf_unwinder_init(vo
 	printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
 	       c_entries, f_entries);
 
+	return 0;
+
+out:
+	return err;
+}
+
+#ifdef CONFIG_MODULES
+int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+			  struct module *me)
+{
+	unsigned int i, err;
+	unsigned long start, end;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	start = end = 0;
+
+	for (i = 1; i < hdr->e_shnum; i++) {
+		/* Alloc bit cleared means "ignore it." */
+		if ((sechdrs[i].sh_flags & SHF_ALLOC)
+		    && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
+			start = sechdrs[i].sh_addr;
+			end = start + sechdrs[i].sh_size;
+			break;
+		}
+	}
+
+	/* Did we find the .eh_frame section? */
+	if (i != hdr->e_shnum) {
+		err = dwarf_parse_section((char *)start, (char *)end, me);
+		if (err) {
+			printk(KERN_WARNING "%s: failed to parse DWARF info\n",
+			       me->name);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *	module_dwarf_cleanup - remove FDE/CIEs associated with @mod
+ *	@mod: the module that is being unloaded
+ *
+ *	Remove any FDEs and CIEs from the global lists that came from
+ *	@mod's .eh_frame section because @mod is being unloaded.
+ */
+void module_dwarf_cleanup(struct module *mod)
+{
+	struct dwarf_fde *fde;
+	struct dwarf_cie *cie;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+
+again_cie:
+	list_for_each_entry(cie, &dwarf_cie_list, link) {
+		if (cie->mod == mod)
+			break;
+	}
+
+	if (&cie->link != &dwarf_cie_list) {
+		list_del(&cie->link);
+		kfree(cie);
+		goto again_cie;
+	}
+
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+
+again_fde:
+	list_for_each_entry(fde, &dwarf_fde_list, link) {
+		if (fde->mod == mod)
+			break;
+	}
+
+	if (&fde->link != &dwarf_fde_list) {
+		list_del(&fde->link);
+		kfree(fde);
+		goto again_fde;
+	}
+
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+}
+#endif /* CONFIG_MODULES */
+
+/**
+ *	dwarf_unwinder_init - initialise the dwarf unwinder
+ *
+ *	Build the data structures describing the .dwarf_frame section to
+ *	make it easier to lookup CIE and FDE entries. Because the
+ *	.eh_frame section is packed as tightly as possible it is not
+ *	easy to lookup the FDE for a given PC, so we build a list of FDE
+ *	and CIE entries that make it easier.
+ */
+static int __init dwarf_unwinder_init(void)
+{
+	int err;
+	INIT_LIST_HEAD(&dwarf_cie_list);
+	INIT_LIST_HEAD(&dwarf_fde_list);
+
+	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
+			sizeof(struct dwarf_frame), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
+			sizeof(struct dwarf_reg), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ,
+					  mempool_alloc_slab,
+					  mempool_free_slab,
+					  dwarf_frame_cachep);
+
+	dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
+					 mempool_alloc_slab,
+					 mempool_free_slab,
+					 dwarf_reg_cachep);
+
+	err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL);
+	if (err)
+		goto out;
+
 	err = unwinder_register(&dwarf_unwinder);
 	if (err)
 		goto out;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/early_printk.c linux-libre-2.6.33-gnu1/arch/sh/kernel/early_printk.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/early_printk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/early_printk.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,6 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 
-#ifdef CONFIG_SH_STANDARD_BIOS
 #include <asm/sh_bios.h>
 
 /*
@@ -57,149 +56,8 @@ static struct console bios_console = {
 	.flags		= CON_PRINTBUFFER,
 	.index		= -1,
 };
-#endif
-
-#ifdef CONFIG_EARLY_SCIF_CONSOLE
-#include <linux/serial_core.h>
-#include "../../../drivers/serial/sh-sci.h"
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define EPK_SCSMR_VALUE 0x000
-#define EPK_SCBRR_VALUE 0x00C
-#define EPK_FIFO_SIZE 64
-#define EPK_FIFO_BITS (0x7f00 >> 8)
-#else
-#define EPK_FIFO_SIZE 16
-#define EPK_FIFO_BITS (0x1f00 >> 8)
-#endif
-
-static struct uart_port scif_port = {
-	.type		= PORT_SCIF,
-	.mapbase	= CONFIG_EARLY_SCIF_CONSOLE_PORT,
-	.membase	= (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
-};
-
-static void scif_sercon_putc(int c)
-{
-	while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
-		;
-
-	sci_in(&scif_port, SCxSR);
-	sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
-	sci_out(&scif_port, SCxTDR, c);
-
-	while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
-		;
 
-	if (c == '\n')
-		scif_sercon_putc('\r');
-}
-
-static void scif_sercon_write(struct console *con, const char *s,
-			      unsigned count)
-{
-	while (count-- > 0)
-		scif_sercon_putc(*s++);
-}
-
-static int __init scif_sercon_setup(struct console *con, char *options)
-{
-	con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8;
-
-	return 0;
-}
-
-static struct console scif_console = {
-	.name		= "sercon",
-	.write		= scif_sercon_write,
-	.setup		= scif_sercon_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= -1,
-};
-
-#if !defined(CONFIG_SH_STANDARD_BIOS)
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
-static void scif_sercon_init(char *s)
-{
-	sci_out(&scif_port, SCSCR, 0x0000);	/* clear TE and RE */
-	sci_out(&scif_port, SCFCR, 0x4006);	/* reset */
-	sci_out(&scif_port, SCSCR, 0x0000);	/* select internal clock */
-	sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE);
-	sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE);
-
-	mdelay(1);	/* wait 1-bit time */
-
-	sci_out(&scif_port, SCFCR, 0x0030);	/* TTRG=b'11 */
-	sci_out(&scif_port, SCSCR, 0x0030);	/* TE, RE */
-}
-#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
-#define DEFAULT_BAUD 115200
-/*
- * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
- * devices that aren't using sh-ipl+g.
- */
-static void scif_sercon_init(char *s)
-{
-	struct uart_port *port = &scif_port;
-	unsigned baud = DEFAULT_BAUD;
-	unsigned int status;
-	char *e;
-
-	if (*s == ',')
-		++s;
-
-	if (*s) {
-		/* ignore ioport/device name */
-		s += strcspn(s, ",");
-		if (*s == ',')
-			s++;
-	}
-
-	if (*s) {
-		baud = simple_strtoul(s, &e, 0);
-		if (baud == 0 || s == e)
-			baud = DEFAULT_BAUD;
-	}
-
-	do {
-		status = sci_in(port, SCxSR);
-	} while (!(status & SCxSR_TEND(port)));
-
-	sci_out(port, SCSCR, 0);	 /* TE=0, RE=0 */
-	sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
-	sci_out(port, SCSMR, 0);
-
-	/* Set baud rate */
-	sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) /
-		(32 * baud) - 1);
-	udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
-
-	sci_out(port, SCSPTR, 0);
-	sci_out(port, SCxSR, 0x60);
-	sci_out(port, SCLSR, 0);
-
-	sci_out(port, SCFCR, 0);
-	sci_out(port, SCSCR, 0x30);	 /* TE=1, RE=1 */
-}
-#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
-#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
-#endif /* CONFIG_EARLY_SCIF_CONSOLE */
-
-/*
- * Setup a default console, if more than one is compiled in, rely on the
- * earlyprintk= parsing to give priority.
- */
-static struct console *early_console =
-#ifdef CONFIG_SH_STANDARD_BIOS
-	&bios_console
-#elif defined(CONFIG_EARLY_SCIF_CONSOLE)
-	&scif_console
-#else
-	NULL
-#endif
-	;
+static struct console *early_console;
 
 static int __init setup_early_printk(char *buf)
 {
@@ -211,21 +69,8 @@ static int __init setup_early_printk(cha
 	if (strstr(buf, "keep"))
 		keep_early = 1;
 
-#ifdef CONFIG_SH_STANDARD_BIOS
 	if (!strncmp(buf, "bios", 4))
 		early_console = &bios_console;
-#endif
-#if defined(CONFIG_EARLY_SCIF_CONSOLE)
-	if (!strncmp(buf, "serial", 6)) {
-		early_console = &scif_console;
-
-#if !defined(CONFIG_SH_STANDARD_BIOS)
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
-		scif_sercon_init(buf + 6);
-#endif
-#endif
-	}
-#endif
 
 	if (likely(early_console)) {
 		if (keep_early)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/entry-common.S linux-libre-2.6.33-gnu1/arch/sh/kernel/entry-common.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/entry-common.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/entry-common.S	2010-02-24 13:52:17.000000000 -0500
@@ -70,8 +70,14 @@ ret_from_exception:
 	CFI_STARTPROC simple
 	CFI_DEF_CFA r14, 0
 	CFI_REL_OFFSET 17, 64
-	CFI_REL_OFFSET 15, 0
+	CFI_REL_OFFSET 15, 60
 	CFI_REL_OFFSET 14, 56
+	CFI_REL_OFFSET 13, 52
+	CFI_REL_OFFSET 12, 48
+	CFI_REL_OFFSET 11, 44
+	CFI_REL_OFFSET 10, 40
+	CFI_REL_OFFSET 9, 36
+	CFI_REL_OFFSET 8, 32
 	preempt_stop()
 ENTRY(ret_from_irq)
 	!
@@ -133,7 +139,7 @@ work_pending:
 	! r8: current_thread_info
 	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
 	bf/s	work_resched
-	 tst	#(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
+	 tst	#_TIF_SIGPENDING, r0
 work_notifysig:
 	bt/s	__restore_all
 	 mov	r15, r4
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/sh/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/ftrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,150 @@ static unsigned char *ftrace_call_replac
 	return ftrace_replaced_code;
 }
 
+/*
+ * Modifying code must take extra care. On an SMP machine, if
+ * the code being modified is also being executed on another CPU
+ * that CPU will have undefined results and possibly take a GPF.
+ * We use kstop_machine to stop other CPUS from exectuing code.
+ * But this does not stop NMIs from happening. We still need
+ * to protect against that. We separate out the modification of
+ * the code to take care of this.
+ *
+ * Two buffers are added: An IP buffer and a "code" buffer.
+ *
+ * 1) Put the instruction pointer into the IP buffer
+ *    and the new code into the "code" buffer.
+ * 2) Wait for any running NMIs to finish and set a flag that says
+ *    we are modifying code, it is done in an atomic operation.
+ * 3) Write the code
+ * 4) clear the flag.
+ * 5) Wait for any running NMIs to finish.
+ *
+ * If an NMI is executed, the first thing it does is to call
+ * "ftrace_nmi_enter". This will check if the flag is set to write
+ * and if it is, it will write what is in the IP and "code" buffers.
+ *
+ * The trick is, it does not matter if everyone is writing the same
+ * content to the code location. Also, if a CPU is executing code
+ * it is OK to write to that code location if the contents being written
+ * are the same as what exists.
+ */
+#define MOD_CODE_WRITE_FLAG (1 << 31)	/* set when NMI should do the write */
+static atomic_t nmi_running = ATOMIC_INIT(0);
+static int mod_code_status;		/* holds return value of text write */
+static void *mod_code_ip;		/* holds the IP to write to */
+static void *mod_code_newcode;		/* holds the text to write to the IP */
+
+static unsigned nmi_wait_count;
+static atomic_t nmi_update_count = ATOMIC_INIT(0);
+
+int ftrace_arch_read_dyn_info(char *buf, int size)
+{
+	int r;
+
+	r = snprintf(buf, size, "%u %u",
+		     nmi_wait_count,
+		     atomic_read(&nmi_update_count));
+	return r;
+}
+
+static void clear_mod_flag(void)
+{
+	int old = atomic_read(&nmi_running);
+
+	for (;;) {
+		int new = old & ~MOD_CODE_WRITE_FLAG;
+
+		if (old == new)
+			break;
+
+		old = atomic_cmpxchg(&nmi_running, old, new);
+	}
+}
+
+static void ftrace_mod_code(void)
+{
+	/*
+	 * Yes, more than one CPU process can be writing to mod_code_status.
+	 *    (and the code itself)
+	 * But if one were to fail, then they all should, and if one were
+	 * to succeed, then they all should.
+	 */
+	mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
+					     MCOUNT_INSN_SIZE);
+
+	/* if we fail, then kill any new writers */
+	if (mod_code_status)
+		clear_mod_flag();
+}
+
+void ftrace_nmi_enter(void)
+{
+	if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
+		smp_rmb();
+		ftrace_mod_code();
+		atomic_inc(&nmi_update_count);
+	}
+	/* Must have previous changes seen before executions */
+	smp_mb();
+}
+
+void ftrace_nmi_exit(void)
+{
+	/* Finish all executions before clearing nmi_running */
+	smp_mb();
+	atomic_dec(&nmi_running);
+}
+
+static void wait_for_nmi_and_set_mod_flag(void)
+{
+	if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))
+		return;
+
+	do {
+		cpu_relax();
+	} while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));
+
+	nmi_wait_count++;
+}
+
+static void wait_for_nmi(void)
+{
+	if (!atomic_read(&nmi_running))
+		return;
+
+	do {
+		cpu_relax();
+	} while (atomic_read(&nmi_running));
+
+	nmi_wait_count++;
+}
+
+static int
+do_ftrace_mod_code(unsigned long ip, void *new_code)
+{
+	mod_code_ip = (void *)ip;
+	mod_code_newcode = new_code;
+
+	/* The buffers need to be visible before we let NMIs write them */
+	smp_mb();
+
+	wait_for_nmi_and_set_mod_flag();
+
+	/* Make sure all running NMIs have finished before we write the code */
+	smp_mb();
+
+	ftrace_mod_code();
+
+	/* Make sure the write happens before clearing the bit */
+	smp_mb();
+
+	clear_mod_flag();
+	wait_for_nmi();
+
+	return mod_code_status;
+}
+
 static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
 		       unsigned char *new_code)
 {
@@ -86,7 +230,7 @@ static int ftrace_modify_code(unsigned l
 		return -EINVAL;
 
 	/* replace the text with the new text */
-	if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
+	if (do_ftrace_mod_code(ip, new_code))
 		return -EPERM;
 
 	flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
@@ -257,82 +401,10 @@ void prepare_ftrace_return(unsigned long
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
 #ifdef CONFIG_FTRACE_SYSCALLS
-
-extern unsigned long __start_syscalls_metadata[];
-extern unsigned long __stop_syscalls_metadata[];
 extern unsigned long *sys_call_table;
 
-static struct syscall_metadata **syscalls_metadata;
-
-static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
-{
-	struct syscall_metadata *start;
-	struct syscall_metadata *stop;
-	char str[KSYM_SYMBOL_LEN];
-
-
-	start = (struct syscall_metadata *)__start_syscalls_metadata;
-	stop = (struct syscall_metadata *)__stop_syscalls_metadata;
-	kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
-
-	for ( ; start < stop; start++) {
-		if (start->name && !strcmp(start->name, str))
-			return start;
-	}
-
-	return NULL;
-}
-
-struct syscall_metadata *syscall_nr_to_meta(int nr)
-{
-	if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
-		return NULL;
-
-	return syscalls_metadata[nr];
-}
-
-int syscall_name_to_nr(char *name)
-{
-	int i;
-
-	if (!syscalls_metadata)
-		return -1;
-	for (i = 0; i < NR_syscalls; i++)
-		if (syscalls_metadata[i])
-			if (!strcmp(syscalls_metadata[i]->name, name))
-				return i;
-	return -1;
-}
-
-void set_syscall_enter_id(int num, int id)
-{
-	syscalls_metadata[num]->enter_id = id;
-}
-
-void set_syscall_exit_id(int num, int id)
-{
-	syscalls_metadata[num]->exit_id = id;
-}
-
-static int __init arch_init_ftrace_syscalls(void)
+unsigned long __init arch_syscall_addr(int nr)
 {
-	int i;
-	struct syscall_metadata *meta;
-	unsigned long **psys_syscall_table = &sys_call_table;
-
-	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
-					FTRACE_SYSCALL_MAX, GFP_KERNEL);
-	if (!syscalls_metadata) {
-		WARN_ON(1);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
-		meta = find_syscall_meta(psys_syscall_table[i]);
-		syscalls_metadata[i] = meta;
-	}
-
-	return 0;
+	return (unsigned long)sys_call_table[nr];
 }
-arch_initcall(arch_init_ftrace_syscalls);
 #endif /* CONFIG_FTRACE_SYSCALLS */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/gpio.c linux-libre-2.6.33-gnu1/arch/sh/kernel/gpio.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,584 +0,0 @@
-/*
- * Pinmuxed GPIO support for SuperH.
- *
- * Copyright (C) 2008 Magnus Damm
- *
- * 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/errno.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/bitops.h>
-#include <linux/gpio.h>
-
-static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
-{
-	if (enum_id < r->begin)
-		return 0;
-
-	if (enum_id > r->end)
-		return 0;
-
-	return 1;
-}
-
-static unsigned long gpio_read_raw_reg(unsigned long reg,
-				       unsigned long reg_width)
-{
-	switch (reg_width) {
-	case 8:
-		return ctrl_inb(reg);
-	case 16:
-		return ctrl_inw(reg);
-	case 32:
-		return ctrl_inl(reg);
-	}
-
-	BUG();
-	return 0;
-}
-
-static void gpio_write_raw_reg(unsigned long reg,
-			       unsigned long reg_width,
-			       unsigned long data)
-{
-	switch (reg_width) {
-	case 8:
-		ctrl_outb(data, reg);
-		return;
-	case 16:
-		ctrl_outw(data, reg);
-		return;
-	case 32:
-		ctrl_outl(data, reg);
-		return;
-	}
-
-	BUG();
-}
-
-static void gpio_write_bit(struct pinmux_data_reg *dr,
-			   unsigned long in_pos, unsigned long value)
-{
-	unsigned long pos;
-
-	pos = dr->reg_width - (in_pos + 1);
-
-#ifdef DEBUG
-	pr_info("write_bit addr = %lx, value = %ld, pos = %ld, "
-		"r_width = %ld\n",
-		dr->reg, !!value, pos, dr->reg_width);
-#endif
-
-	if (value)
-		set_bit(pos, &dr->reg_shadow);
-	else
-		clear_bit(pos, &dr->reg_shadow);
-
-	gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
-}
-
-static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
-			 unsigned long field_width, unsigned long in_pos)
-{
-	unsigned long data, mask, pos;
-
-	data = 0;
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
-
-#ifdef DEBUG
-	pr_info("read_reg: addr = %lx, pos = %ld, "
-		"r_width = %ld, f_width = %ld\n",
-		reg, pos, reg_width, field_width);
-#endif
-
-	data = gpio_read_raw_reg(reg, reg_width);
-	return (data >> pos) & mask;
-}
-
-static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
-			   unsigned long field_width, unsigned long in_pos,
-			   unsigned long value)
-{
-	unsigned long mask, pos;
-
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
-
-#ifdef DEBUG
-	pr_info("write_reg addr = %lx, value = %ld, pos = %ld, "
-		"r_width = %ld, f_width = %ld\n",
-		reg, value, pos, reg_width, field_width);
-#endif
-
-	mask = ~(mask << pos);
-	value = value << pos;
-
-	switch (reg_width) {
-	case 8:
-		ctrl_outb((ctrl_inb(reg) & mask) | value, reg);
-		break;
-	case 16:
-		ctrl_outw((ctrl_inw(reg) & mask) | value, reg);
-		break;
-	case 32:
-		ctrl_outl((ctrl_inl(reg) & mask) | value, reg);
-		break;
-	}
-}
-
-static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
-{
-	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
-	struct pinmux_data_reg *data_reg;
-	int k, n;
-
-	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
-		return -1;
-
-	k = 0;
-	while (1) {
-		data_reg = gpioc->data_regs + k;
-
-		if (!data_reg->reg_width)
-			break;
-
-		for (n = 0; n < data_reg->reg_width; n++) {
-			if (data_reg->enum_ids[n] == gpiop->enum_id) {
-				gpiop->flags &= ~PINMUX_FLAG_DREG;
-				gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
-				gpiop->flags &= ~PINMUX_FLAG_DBIT;
-				gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
-				return 0;
-			}
-		}
-		k++;
-	}
-
-	BUG();
-
-	return -1;
-}
-
-static void setup_data_regs(struct pinmux_info *gpioc)
-{
-	struct pinmux_data_reg *drp;
-	int k;
-
-	for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
-		setup_data_reg(gpioc, k);
-
-	k = 0;
-	while (1) {
-		drp = gpioc->data_regs + k;
-
-		if (!drp->reg_width)
-			break;
-
-		drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
-		k++;
-	}
-}
-
-static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
-			struct pinmux_data_reg **drp, int *bitp)
-{
-	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
-	int k, n;
-
-	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
-		return -1;
-
-	k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
-	n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
-	*drp = gpioc->data_regs + k;
-	*bitp = n;
-	return 0;
-}
-
-static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
-			  struct pinmux_cfg_reg **crp, int *indexp,
-			  unsigned long **cntp)
-{
-	struct pinmux_cfg_reg *config_reg;
-	unsigned long r_width, f_width;
-	int k, n;
-
-	k = 0;
-	while (1) {
-		config_reg = gpioc->cfg_regs + k;
-
-		r_width = config_reg->reg_width;
-		f_width = config_reg->field_width;
-
-		if (!r_width)
-			break;
-		for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
-			if (config_reg->enum_ids[n] == enum_id) {
-				*crp = config_reg;
-				*indexp = n;
-				*cntp = &config_reg->cnt[n / (1 << f_width)];
-				return 0;
-			}
-		}
-		k++;
-	}
-
-	return -1;
-}
-
-static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
-			    int pos, pinmux_enum_t *enum_idp)
-{
-	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
-	pinmux_enum_t *data = gpioc->gpio_data;
-	int k;
-
-	if (!enum_in_range(enum_id, &gpioc->data)) {
-		if (!enum_in_range(enum_id, &gpioc->mark)) {
-			pr_err("non data/mark enum_id for gpio %d\n", gpio);
-			return -1;
-		}
-	}
-
-	if (pos) {
-		*enum_idp = data[pos + 1];
-		return pos + 1;
-	}
-
-	for (k = 0; k < gpioc->gpio_data_size; k++) {
-		if (data[k] == enum_id) {
-			*enum_idp = data[k + 1];
-			return k + 1;
-		}
-	}
-
-	pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
-	return -1;
-}
-
-static void write_config_reg(struct pinmux_info *gpioc,
-			     struct pinmux_cfg_reg *crp,
-			     int index)
-{
-	unsigned long ncomb, pos, value;
-
-	ncomb = 1 << crp->field_width;
-	pos = index / ncomb;
-	value = index % ncomb;
-
-	gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
-}
-
-static int check_config_reg(struct pinmux_info *gpioc,
-			    struct pinmux_cfg_reg *crp,
-			    int index)
-{
-	unsigned long ncomb, pos, value;
-
-	ncomb = 1 << crp->field_width;
-	pos = index / ncomb;
-	value = index % ncomb;
-
-	if (gpio_read_reg(crp->reg, crp->reg_width,
-			  crp->field_width, pos) == value)
-		return 0;
-
-	return -1;
-}
-
-enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
-
-static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
-			      int pinmux_type, int cfg_mode)
-{
-	struct pinmux_cfg_reg *cr = NULL;
-	pinmux_enum_t enum_id;
-	struct pinmux_range *range;
-	int in_range, pos, index;
-	unsigned long *cntp;
-
-	switch (pinmux_type) {
-
-	case PINMUX_TYPE_FUNCTION:
-		range = NULL;
-		break;
-
-	case PINMUX_TYPE_OUTPUT:
-		range = &gpioc->output;
-		break;
-
-	case PINMUX_TYPE_INPUT:
-		range = &gpioc->input;
-		break;
-
-	case PINMUX_TYPE_INPUT_PULLUP:
-		range = &gpioc->input_pu;
-		break;
-
-	case PINMUX_TYPE_INPUT_PULLDOWN:
-		range = &gpioc->input_pd;
-		break;
-
-	default:
-		goto out_err;
-	}
-
-	pos = 0;
-	enum_id = 0;
-	index = 0;
-	while (1) {
-		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
-		if (pos <= 0)
-			goto out_err;
-
-		if (!enum_id)
-			break;
-
-		in_range = enum_in_range(enum_id, &gpioc->function);
-		if (!in_range && range) {
-			in_range = enum_in_range(enum_id, range);
-
-			if (in_range && enum_id == range->force)
-				continue;
-		}
-
-		if (!in_range)
-			continue;
-
-		if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
-			goto out_err;
-
-		switch (cfg_mode) {
-		case GPIO_CFG_DRYRUN:
-			if (!*cntp || !check_config_reg(gpioc, cr, index))
-				continue;
-			break;
-
-		case GPIO_CFG_REQ:
-			write_config_reg(gpioc, cr, index);
-			*cntp = *cntp + 1;
-			break;
-
-		case GPIO_CFG_FREE:
-			*cntp = *cntp - 1;
-			break;
-		}
-	}
-
-	return 0;
- out_err:
-	return -1;
-}
-
-static DEFINE_SPINLOCK(gpio_lock);
-
-static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
-{
-	return container_of(chip, struct pinmux_info, chip);
-}
-
-static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	struct pinmux_data_reg *dummy;
-	unsigned long flags;
-	int i, ret, pinmux_type;
-
-	ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
-		goto err_unlock;
-
-	/* setup pin function here if no data is associated with pin */
-
-	if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
-		pinmux_type = PINMUX_TYPE_FUNCTION;
-	else
-		pinmux_type = PINMUX_TYPE_GPIO;
-
-	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
-		if (pinmux_config_gpio(gpioc, offset,
-				       pinmux_type,
-				       GPIO_CFG_DRYRUN) != 0)
-			goto err_unlock;
-
-		if (pinmux_config_gpio(gpioc, offset,
-				       pinmux_type,
-				       GPIO_CFG_REQ) != 0)
-			BUG();
-	}
-
-	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[offset].flags |= pinmux_type;
-
-	ret = 0;
- err_unlock:
-	spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
-	return ret;
-}
-
-static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int pinmux_type;
-
-	if (!gpioc)
-		return;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
-	pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
-	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-
-static int pinmux_direction(struct pinmux_info *gpioc,
-			    unsigned gpio, int new_pinmux_type)
-{
-	int pinmux_type;
-	int ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
-
-	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
-
-	switch (pinmux_type) {
-	case PINMUX_TYPE_GPIO:
-		break;
-	case PINMUX_TYPE_OUTPUT:
-	case PINMUX_TYPE_INPUT:
-	case PINMUX_TYPE_INPUT_PULLUP:
-	case PINMUX_TYPE_INPUT_PULLDOWN:
-		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
-		break;
-	default:
-		goto err_out;
-	}
-
-	if (pinmux_config_gpio(gpioc, gpio,
-			       new_pinmux_type,
-			       GPIO_CFG_DRYRUN) != 0)
-		goto err_out;
-
-	if (pinmux_config_gpio(gpioc, gpio,
-			       new_pinmux_type,
-			       GPIO_CFG_REQ) != 0)
-		BUG();
-
-	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
-	gpioc->gpios[gpio].flags |= new_pinmux_type;
-
-	ret = 0;
- err_out:
-	return ret;
-}
-
-static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return ret;
-}
-
-static void sh_gpio_set_value(struct pinmux_info *gpioc,
-			     unsigned gpio, int value)
-{
-	struct pinmux_data_reg *dr = NULL;
-	int bit = 0;
-
-	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
-		BUG();
-	else
-		gpio_write_bit(dr, bit, value);
-}
-
-static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
-				    int value)
-{
-	struct pinmux_info *gpioc = chip_to_pinmux(chip);
-	unsigned long flags;
-	int ret;
-
-	sh_gpio_set_value(gpioc, offset, value);
-	spin_lock_irqsave(&gpio_lock, flags);
-	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return ret;
-}
-
-static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
-{
-	struct pinmux_data_reg *dr = NULL;
-	int bit = 0;
-
-	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
-		BUG();
-		return 0;
-	}
-
-	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
-}
-
-static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	return sh_gpio_get_value(chip_to_pinmux(chip), offset);
-}
-
-static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
-}
-
-int register_pinmux(struct pinmux_info *pip)
-{
-	struct gpio_chip *chip = &pip->chip;
-
-	pr_info("sh pinmux: %s handling gpio %d -> %d\n",
-		pip->name, pip->first_gpio, pip->last_gpio);
-
-	setup_data_regs(pip);
-
-	chip->request = sh_gpio_request;
-	chip->free = sh_gpio_free;
-	chip->direction_input = sh_gpio_direction_input;
-	chip->get = sh_gpio_get;
-	chip->direction_output = sh_gpio_direction_output;
-	chip->set = sh_gpio_set;
-
-	WARN_ON(pip->first_gpio != 0); /* needs testing */
-
-	chip->label = pip->name;
-	chip->owner = THIS_MODULE;
-	chip->base = pip->first_gpio;
-	chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
-
-	return gpiochip_add(chip);
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/head_32.S linux-libre-2.6.33-gnu1/arch/sh/kernel/head_32.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/head_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,7 @@ ENTRY(empty_zero_page)
 	.long	1		/* LOADER_TYPE */
 	.long	0x00000000	/* INITRD_START */
 	.long	0x00000000	/* INITRD_SIZE */
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED)
 	.long	0x53453f00 + 32	/* "SE?" = 32 bit */
 #else
 	.long	0x53453f00 + 29	/* "SE?" = 29 bit */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/idle.c linux-libre-2.6.33-gnu1/arch/sh/kernel/idle.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/idle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/idle.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,7 @@
 #include <asm/atomic.h>
 
 static int hlt_counter;
-void (*pm_idle)(void);
+void (*pm_idle)(void) = NULL;
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
@@ -39,48 +39,94 @@ static int __init hlt_setup(char *__unus
 }
 __setup("hlt", hlt_setup);
 
+static inline int hlt_works(void)
+{
+	return !hlt_counter;
+}
+
+/*
+ * On SMP it's slightly faster (but much more power-consuming!)
+ * to poll the ->work.need_resched flag instead of waiting for the
+ * cross-CPU IPI to arrive. Use this option with caution.
+ */
+static void poll_idle(void)
+{
+	local_irq_enable();
+	while (!need_resched())
+		cpu_relax();
+}
+
 void default_idle(void)
 {
-	if (!hlt_counter) {
+	if (hlt_works()) {
 		clear_thread_flag(TIF_POLLING_NRFLAG);
 		smp_mb__after_clear_bit();
-		set_bl_bit();
-		stop_critical_timings();
 
-		while (!need_resched())
+		set_bl_bit();
+		if (!need_resched()) {
+			local_irq_enable();
 			cpu_sleep();
+		} else
+			local_irq_enable();
 
-		start_critical_timings();
-		clear_bl_bit();
 		set_thread_flag(TIF_POLLING_NRFLAG);
+		clear_bl_bit();
 	} else
-		while (!need_resched())
-			cpu_relax();
+		poll_idle();
 }
 
+/*
+ * The idle thread. There's no useful work to be done, so just try to conserve
+ * power and have a low exit latency (ie sit in a loop waiting for somebody to
+ * say that they'd like to reschedule)
+ */
 void cpu_idle(void)
 {
+	unsigned int cpu = smp_processor_id();
+
 	set_thread_flag(TIF_POLLING_NRFLAG);
 
 	/* endless idle loop with no priority at all */
 	while (1) {
-		void (*idle)(void) = pm_idle;
+		tick_nohz_stop_sched_tick(1);
 
-		if (!idle)
-			idle = default_idle;
+		while (!need_resched() && cpu_online(cpu)) {
+			check_pgt_cache();
+			rmb();
 
-		tick_nohz_stop_sched_tick(1);
-		while (!need_resched())
-			idle();
-		tick_nohz_restart_sched_tick();
+			local_irq_disable();
+			/* Don't trace irqs off for idle */
+			stop_critical_timings();
+			pm_idle();
+			/*
+			 * Sanity check to ensure that pm_idle() returns
+			 * with IRQs enabled
+			 */
+			WARN_ON(irqs_disabled());
+			start_critical_timings();
+		}
 
+		tick_nohz_restart_sched_tick();
 		preempt_enable_no_resched();
 		schedule();
 		preempt_disable();
-		check_pgt_cache();
 	}
 }
 
+void __cpuinit select_idle_routine(void)
+{
+	/*
+	 * If a platform has set its own idle routine, leave it alone.
+	 */
+	if (pm_idle)
+		return;
+
+	if (hlt_works())
+		pm_idle = default_idle;
+	else
+		pm_idle = poll_idle;
+}
+
 static void do_nothing(void *unused)
 {
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/io_generic.c linux-libre-2.6.33-gnu1/arch/sh/kernel/io_generic.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/io_generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/io_generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #define dummy_read()
 #endif
 
-unsigned long generic_io_base;
+unsigned long generic_io_base = 0;
 
 u8 generic_inb(unsigned long port)
 {
@@ -147,8 +147,10 @@ void generic_outsl(unsigned long port, c
 
 void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
 {
+#ifdef P1SEG
 	if (PXSEG(addr) >= P1SEG)
 		return (void __iomem *)addr;
+#endif
 
 	return (void __iomem *)(addr + generic_io_base);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/irq_32.c linux-libre-2.6.33-gnu1/arch/sh/kernel/irq_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/irq_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/irq_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ * SHcompact irqflags support
+ *
+ * Copyright (C) 2006 - 2009 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/irqflags.h>
+#include <linux/module.h>
+
+void notrace raw_local_irq_restore(unsigned long flags)
+{
+	unsigned long __dummy0, __dummy1;
+
+	if (flags == RAW_IRQ_DISABLED) {
+		__asm__ __volatile__ (
+			"stc	sr, %0\n\t"
+			"or	#0xf0, %0\n\t"
+			"ldc	%0, sr\n\t"
+			: "=&z" (__dummy0)
+			: /* no inputs */
+			: "memory"
+		);
+	} else {
+		__asm__ __volatile__ (
+			"stc	sr, %0\n\t"
+			"and	%1, %0\n\t"
+#ifdef CONFIG_CPU_HAS_SR_RB
+			"stc	r6_bank, %1\n\t"
+			"or	%1, %0\n\t"
+#endif
+			"ldc	%0, sr\n\t"
+			: "=&r" (__dummy0), "=r" (__dummy1)
+			: "1" (~RAW_IRQ_DISABLED)
+			: "memory"
+		);
+	}
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+unsigned long notrace __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__ (
+		"stc	sr, %0\n\t"
+		"and	#0xf0, %0\n\t"
+		: "=&z" (flags)
+		: /* no inputs */
+		: "memory"
+	);
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/irq_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/irq_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/irq_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/irq_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,51 @@
+/*
+ * SHmedia irqflags support
+ *
+ * Copyright (C) 2006 - 2009 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/irqflags.h>
+#include <linux/module.h>
+#include <cpu/registers.h>
+
+void notrace raw_local_irq_restore(unsigned long flags)
+{
+	unsigned long long __dummy;
+
+	if (flags == RAW_IRQ_DISABLED) {
+		__asm__ __volatile__ (
+			"getcon	" __SR ", %0\n\t"
+			"or	%0, %1, %0\n\t"
+			"putcon	%0, " __SR "\n\t"
+			: "=&r" (__dummy)
+			: "r" (RAW_IRQ_DISABLED)
+		);
+	} else {
+		__asm__ __volatile__ (
+			"getcon	" __SR ", %0\n\t"
+			"and	%0, %1, %0\n\t"
+			"putcon	%0, " __SR "\n\t"
+			: "=&r" (__dummy)
+			: "r" (~RAW_IRQ_DISABLED)
+		);
+	}
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+unsigned long notrace __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__ (
+		"getcon	" __SR ", %0\n\t"
+		"and	%0, %1, %0"
+		: "=&r" (flags)
+		: "r" (RAW_IRQ_DISABLED)
+	);
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/irq.c linux-libre-2.6.33-gnu1/arch/sh/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,7 +37,15 @@ void ack_bad_irq(unsigned int irq)
  */
 static int show_other_interrupts(struct seq_file *p, int prec)
 {
+	int j;
+
+	seq_printf(p, "%*s: ", prec, "NMI");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stat[j].__nmi_count);
+	seq_printf(p, "  Non-maskable interrupts\n");
+
 	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
+
 	return 0;
 }
 
@@ -68,7 +76,7 @@ int show_interrupts(struct seq_file *p,
 	if (!desc)
 		return 0;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	for_each_online_cpu(j)
 		any_count |= kstat_irqs_cpu(i, j);
 	action = desc->action;
@@ -89,7 +97,7 @@ int show_interrupts(struct seq_file *p,
 
 	seq_putc(p, '\n');
 out:
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return 0;
 }
 #endif
@@ -255,6 +263,12 @@ void __init init_IRQ(void)
 {
 	plat_irq_setup();
 
+	/*
+	 * Pin any of the legacy IRQ vectors that haven't already been
+	 * grabbed by the platform
+	 */
+	reserve_irq_legacy();
+
 	/* Perform the machine specific initialisation */
 	if (sh_mv.mv_init_irq)
 		sh_mv.mv_init_irq();
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/machine_kexec.c linux-libre-2.6.33-gnu1/arch/sh/kernel/machine_kexec.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/machine_kexec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/machine_kexec.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,12 +46,6 @@ void machine_crash_shutdown(struct pt_re
  */
 int machine_kexec_prepare(struct kimage *image)
 {
-	/* older versions of kexec-tools are passing
-	 * the zImage entry point as a virtual address.
-	 */
-	if (image->start != PHYSADDR(image->start))
-		return -EINVAL; /* upgrade your kexec-tools */
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/machvec.c linux-libre-2.6.33-gnu1/arch/sh/kernel/machvec.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/machvec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/machvec.c	2010-02-24 13:52:17.000000000 -0500
@@ -135,5 +135,9 @@ void __init sh_mv_setup(void)
 	if (!sh_mv.mv_nr_irqs)
 		sh_mv.mv_nr_irqs = NR_IRQS;
 
+#ifdef P2SEG
 	__set_io_port_base(P2SEG);
+#else
+	__set_io_port_base(0);
+#endif
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/Makefile linux-libre-2.6.33-gnu1/arch/sh/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,8 +9,12 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
 endif
 
-obj-y	:= debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o	\
-	   machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o	\
+CFLAGS_REMOVE_return_address.o = -pg
+
+obj-y	:= debugtraps.o dma-nommu.o dumpstack.o 			\
+	   idle.o io.o io_generic.o irq.o				\
+	   irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o 	\
+	   ptrace_$(BITS).o return_address.o				\
 	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
 	   syscalls_$(BITS).o time.o topology.o traps.o			\
 	   traps_$(BITS).o unwinder.o
@@ -18,23 +22,22 @@ obj-y	:= debugtraps.o dumpstack.o idle.o
 obj-y				+= cpu/
 obj-$(CONFIG_VSYSCALL)		+= vsyscall/
 obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
+obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o early_printk.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
 obj-$(CONFIG_MODULES)		+= sh_ksyms_$(BITS).o module.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o
 obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o perf_callchain.o
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/module.c linux-libre-2.6.33-gnu1/arch/sh/kernel/module.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/module.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/module.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <asm/unaligned.h>
+#include <asm/dwarf.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -145,10 +146,16 @@ int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
-	return module_bug_finalize(hdr, sechdrs, me);
+	int ret = 0;
+
+	ret |= module_dwarf_finalize(hdr, sechdrs, me);
+	ret |= module_bug_finalize(hdr, sechdrs, me);
+
+	return ret;
 }
 
 void module_arch_cleanup(struct module *mod)
 {
 	module_bug_cleanup(mod);
+	module_dwarf_cleanup(mod);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/perf_callchain.c linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_callchain.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/perf_callchain.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_callchain.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,98 @@
+/*
+ * Performance event callchain support - SuperH architecture code
+ *
+ * Copyright (C) 2009  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/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <asm/unwinder.h>
+#include <asm/ptrace.h>
+
+static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
+{
+	if (entry->nr < PERF_MAX_STACK_DEPTH)
+		entry->ip[entry->nr++] = ip;
+}
+
+static void callchain_warning(void *data, char *msg)
+{
+}
+
+static void
+callchain_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int callchain_stack(void *data, char *name)
+{
+	return 0;
+}
+
+static void callchain_address(void *data, unsigned long addr, int reliable)
+{
+	struct perf_callchain_entry *entry = data;
+
+	if (reliable)
+		callchain_store(entry, addr);
+}
+
+static const struct stacktrace_ops callchain_ops = {
+	.warning	= callchain_warning,
+	.warning_symbol	= callchain_warning_symbol,
+	.stack		= callchain_stack,
+	.address	= callchain_address,
+};
+
+static void
+perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	callchain_store(entry, PERF_CONTEXT_KERNEL);
+	callchain_store(entry, regs->pc);
+
+	unwind_stack(NULL, regs, NULL, &callchain_ops, entry);
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	int is_user;
+
+	if (!regs)
+		return;
+
+	is_user = user_mode(regs);
+
+	if (!current || current->pid == 0)
+		return;
+
+	if (is_user && current->state != TASK_RUNNING)
+		return;
+
+	/*
+	 * Only the kernel side is implemented for now.
+	 */
+	if (!is_user)
+		perf_callchain_kernel(regs, entry);
+}
+
+/*
+ * No need for separate IRQ and NMI entries.
+ */
+static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
+
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+	struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
+
+	entry->nr = 0;
+
+	perf_do_callchain(regs, entry);
+
+	return entry;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/perf_event.c linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/perf_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,312 @@
+/*
+ * Performance event support framework for SuperH hardware counters.
+ *
+ *  Copyright (C) 2009  Paul Mundt
+ *
+ * Heavily based on the x86 and PowerPC implementations.
+ *
+ * x86:
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *
+ * ppc:
+ *  Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+#include <asm/processor.h>
+
+struct cpu_hw_events {
+	struct perf_event	*events[MAX_HWEVENTS];
+	unsigned long		used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+	unsigned long		active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+};
+
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+static struct sh_pmu *sh_pmu __read_mostly;
+
+/* Number of perf_events counting hardware events */
+static atomic_t num_events;
+/* Used to avoid races in calling reserve/release_pmc_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/*
+ * Stub these out for now, do something more profound later.
+ */
+int reserve_pmc_hardware(void)
+{
+	return 0;
+}
+
+void release_pmc_hardware(void)
+{
+}
+
+static inline int sh_pmu_initialized(void)
+{
+	return !!sh_pmu;
+}
+
+/*
+ * Release the PMU if this is the last perf_event.
+ */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (!atomic_add_unless(&num_events, -1, 1)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_dec_return(&num_events) == 0)
+			release_pmc_hardware();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+static int hw_perf_cache_event(int config, int *evp)
+{
+	unsigned long type, op, result;
+	int ev;
+
+	if (!sh_pmu->cache_events)
+		return -EINVAL;
+
+	/* unpack config */
+	type = config & 0xff;
+	op = (config >> 8) & 0xff;
+	result = (config >> 16) & 0xff;
+
+	if (type >= PERF_COUNT_HW_CACHE_MAX ||
+	    op >= PERF_COUNT_HW_CACHE_OP_MAX ||
+	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	ev = (*sh_pmu->cache_events)[type][op][result];
+	if (ev == 0)
+		return -EOPNOTSUPP;
+	if (ev == -1)
+		return -EINVAL;
+	*evp = ev;
+	return 0;
+}
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	int config = -1;
+	int err;
+
+	if (!sh_pmu_initialized())
+		return -ENODEV;
+
+	/*
+	 * All of the on-chip counters are "limited", in that they have
+	 * no interrupts, and are therefore unable to do sampling without
+	 * further work and timer assistance.
+	 */
+	if (hwc->sample_period)
+		return -EINVAL;
+
+	/*
+	 * See if we need to reserve the counter.
+	 *
+	 * 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
+	 * reserve_pmc_hardware or release_pmc_hardware.
+	 */
+	err = 0;
+	if (!atomic_inc_not_zero(&num_events)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&num_events) == 0 &&
+		    reserve_pmc_hardware())
+			err = -EBUSY;
+		else
+			atomic_inc(&num_events);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+
+	if (err)
+		return err;
+
+	event->destroy = hw_perf_event_destroy;
+
+	switch (attr->type) {
+	case PERF_TYPE_RAW:
+		config = attr->config & sh_pmu->raw_event_mask;
+		break;
+	case PERF_TYPE_HW_CACHE:
+		err = hw_perf_cache_event(attr->config, &config);
+		if (err)
+			return err;
+		break;
+	case PERF_TYPE_HARDWARE:
+		if (attr->config >= sh_pmu->max_events)
+			return -EINVAL;
+
+		config = sh_pmu->event_map(attr->config);
+		break;
+	}
+
+	if (config == -1)
+		return -EINVAL;
+
+	hwc->config |= config;
+
+	return 0;
+}
+
+static void sh_perf_event_update(struct perf_event *event,
+				   struct hw_perf_event *hwc, int idx)
+{
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+	int shift = 0;
+
+	/*
+	 * Depending on the counter configuration, they may or may not
+	 * be chained, in which case the previous counter value can be
+	 * updated underneath us if the lower-half overflows.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic counter atomically.
+	 *
+	 * As there is no interrupt associated with the overflow events,
+	 * this is the simplest approach for maintaining consistency.
+	 */
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	new_raw_count = sh_pmu->read(idx);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (counter-)time and add that to the generic counter.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+}
+
+static void sh_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	clear_bit(idx, cpuc->active_mask);
+	sh_pmu->disable(hwc, idx);
+
+	barrier();
+
+	sh_perf_event_update(event, &event->hw, idx);
+
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static int sh_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (test_and_set_bit(idx, cpuc->used_mask)) {
+		idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events);
+		if (idx == sh_pmu->num_events)
+			return -EAGAIN;
+
+		set_bit(idx, cpuc->used_mask);
+		hwc->idx = idx;
+	}
+
+	sh_pmu->disable(hwc, idx);
+
+	cpuc->events[idx] = event;
+	set_bit(idx, cpuc->active_mask);
+
+	sh_pmu->enable(hwc, idx);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+static void sh_pmu_read(struct perf_event *event)
+{
+	sh_perf_event_update(event, &event->hw, event->hw.idx);
+}
+
+static const struct pmu pmu = {
+	.enable		= sh_pmu_enable,
+	.disable	= sh_pmu_disable,
+	.read		= sh_pmu_read,
+};
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	int err = __hw_perf_event_init(event);
+	if (unlikely(err)) {
+		if (event->destroy)
+			event->destroy(event);
+		return ERR_PTR(err);
+	}
+
+	return &pmu;
+}
+
+void hw_perf_event_setup(int cpu)
+{
+	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
+}
+
+void hw_perf_enable(void)
+{
+	if (!sh_pmu_initialized())
+		return;
+
+	sh_pmu->enable_all();
+}
+
+void hw_perf_disable(void)
+{
+	if (!sh_pmu_initialized())
+		return;
+
+	sh_pmu->disable_all();
+}
+
+int register_sh_pmu(struct sh_pmu *pmu)
+{
+	if (sh_pmu)
+		return -EBUSY;
+	sh_pmu = pmu;
+
+	pr_info("Performance Events: %s support registered\n", pmu->name);
+
+	WARN_ON(pmu->num_events > MAX_HWEVENTS);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/process_32.c linux-libre-2.6.33-gnu1/arch/sh/kernel/process_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/process_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,7 +134,10 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.regs[5] = (unsigned long)fn;
 
 	regs.pc = (unsigned long)kernel_thread_helper;
-	regs.sr = (1 << 30);
+	regs.sr = SR_MD;
+#if defined(CONFIG_SH_FPU)
+	regs.sr |= SR_FD;
+#endif
 
 	/* Ok, create the new process.. */
 	pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
@@ -142,6 +145,7 @@ int kernel_thread(int (*fn)(void *), voi
 
 	return pid;
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -186,6 +190,16 @@ int dump_fpu(struct pt_regs *regs, elf_f
 
 	return fpvalid;
 }
+EXPORT_SYMBOL(dump_fpu);
+
+/*
+ * This gets called before we allocate a new thread and copy
+ * the current task into it.
+ */
+void prepare_to_copy(struct task_struct *tsk)
+{
+	unlazy_fpu(tsk, task_pt_regs(tsk));
+}
 
 asmlinkage void ret_from_fork(void);
 
@@ -195,16 +209,10 @@ int copy_thread(unsigned long clone_flag
 {
 	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
+#if defined(CONFIG_SH_DSP)
 	struct task_struct *tsk = current;
 #endif
 
-#if defined(CONFIG_SH_FPU)
-	unlazy_fpu(tsk, regs);
-	p->thread.fpu = tsk->thread.fpu;
-	copy_to_stopped_child_used_math(p);
-#endif
-
 #if defined(CONFIG_SH_DSP)
 	if (is_dsp_enabled(tsk)) {
 		/* We can use the __save_dsp or just copy the struct:
@@ -224,6 +232,8 @@ int copy_thread(unsigned long clone_flag
 	} else {
 		childregs->regs[15] = (unsigned long)childregs;
 		ti->addr_limit = KERNEL_DS;
+		ti->status &= ~TS_USEDFPU;
+		p->fpu_counter = 0;
 	}
 
 	if (clone_flags & CLONE_SETTLS)
@@ -288,9 +298,13 @@ static void ubc_set_tracing(int asid, un
 __notrace_funcgraph struct task_struct *
 __switch_to(struct task_struct *prev, struct task_struct *next)
 {
-#if defined(CONFIG_SH_FPU)
+	struct thread_struct *next_t = &next->thread;
+
 	unlazy_fpu(prev, task_pt_regs(prev));
-#endif
+
+	/* we're going to use this soon, after a few expensive things */
+	if (next->fpu_counter > 5)
+		prefetch(&next_t->fpu.hard);
 
 #ifdef CONFIG_MMU
 	/*
@@ -321,6 +335,14 @@ __switch_to(struct task_struct *prev, st
 #endif
 	}
 
+	/*
+	 * If the task has used fpu the last 5 timeslices, just do a full
+	 * restore of the math state immediately to avoid the trap; the
+	 * chances of needing FPU soon are obviously high now
+	 */
+	if (next->fpu_counter > 5)
+		fpu_state_restore(task_pt_regs(next));
+
 	return prev;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/process_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/process_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/process_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -335,6 +335,7 @@ int kernel_thread(int (*fn)(void *), voi
 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
 		      &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -367,7 +368,7 @@ void exit_thread(void)
 void flush_thread(void)
 {
 
-	/* Called by fs/exec.c (flush_old_exec) to remove traces of a
+	/* Called by fs/exec.c (setup_new_exec) to remove traces of a
 	 * previously running executable. */
 #ifdef CONFIG_SH_FPU
 	if (last_task_used_math == current) {
@@ -403,7 +404,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 	if (fpvalid) {
 		if (current == last_task_used_math) {
 			enable_fpu();
-			save_fpu(tsk, regs);
+			save_fpu(tsk);
 			disable_fpu();
 			last_task_used_math = 0;
 			regs->sr |= SR_FD;
@@ -417,6 +418,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 	return 0; /* Task didn't use the fpu at all. */
 #endif
 }
+EXPORT_SYMBOL(dump_fpu);
 
 asmlinkage void ret_from_fork(void);
 
@@ -429,7 +431,7 @@ int copy_thread(unsigned long clone_flag
 #ifdef CONFIG_SH_FPU
 	if(last_task_used_math == current) {
 		enable_fpu();
-		save_fpu(current, regs);
+		save_fpu(current);
 		disable_fpu();
 		last_task_used_math = NULL;
 		regs->sr |= SR_FD;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/ptrace_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/ptrace_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/ptrace_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,7 @@ get_fpu_long(struct task_struct *task, u
 
 	if (last_task_used_math == task) {
 		enable_fpu();
-		save_fpu(task, regs);
+		save_fpu(task);
 		disable_fpu();
 		last_task_used_math = 0;
 		regs->sr |= SR_FD;
@@ -118,7 +118,7 @@ put_fpu_long(struct task_struct *task, u
 		set_stopped_child_used_math(task);
 	} else if (last_task_used_math == task) {
 		enable_fpu();
-		save_fpu(task, regs);
+		save_fpu(task);
 		disable_fpu();
 		last_task_used_math = 0;
 		regs->sr |= SR_FD;
@@ -133,6 +133,8 @@ void user_enable_single_step(struct task
 	struct pt_regs *regs = child->thread.uregs;
 
 	regs->sr |= SR_SSTEP;	/* auto-resetting upon exception */
+
+	set_tsk_thread_flag(child, TIF_SINGLESTEP);
 }
 
 void user_disable_single_step(struct task_struct *child)
@@ -140,6 +142,8 @@ void user_disable_single_step(struct tas
 	struct pt_regs *regs = child->thread.uregs;
 
 	regs->sr &= ~SR_SSTEP;
+
+	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 }
 
 static int genregs_get(struct task_struct *target,
@@ -454,6 +458,8 @@ asmlinkage long long do_syscall_trace_en
 
 asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
 {
+	int step;
+
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
 				   regs->regs[9]);
@@ -461,8 +467,9 @@ asmlinkage void do_syscall_trace_leave(s
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_exit(regs, regs->regs[9]);
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE))
-		tracehook_report_syscall_exit(regs, 0);
+	step = test_thread_flag(TIF_SINGLESTEP);
+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(regs, step);
 }
 
 /* Called with interrupts disabled */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/return_address.c linux-libre-2.6.33-gnu1/arch/sh/kernel/return_address.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/return_address.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/return_address.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,54 @@
+/*
+ * arch/sh/kernel/return_address.c
+ *
+ * Copyright (C) 2009  Matt Fleming
+ * Copyright (C) 2009  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/kernel.h>
+#include <asm/dwarf.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+void *return_address(unsigned int depth)
+{
+	struct dwarf_frame *frame;
+	unsigned long ra;
+	int i;
+
+	for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
+		struct dwarf_frame *tmp;
+
+		tmp = dwarf_unwind_stack(ra, frame);
+
+		if (frame)
+			dwarf_free_frame(frame);
+
+		frame = tmp;
+
+		if (!frame || !frame->return_addr)
+			break;
+
+		ra = frame->return_addr;
+	}
+
+	/* Failed to unwind the stack to the specified depth. */
+	WARN_ON(i != depth + 1);
+
+	if (frame)
+		dwarf_free_frame(frame);
+
+	return (void *)ra;
+}
+
+#else
+
+void *return_address(unsigned int depth)
+{
+	return NULL;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/setup.c linux-libre-2.6.33-gnu1/arch/sh/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -423,6 +423,9 @@ void __init setup_arch(char **cmdline_p)
 
 	plat_early_device_setup();
 
+	/* Let earlyprintk output early console messages */
+	early_platform_driver_probe("earlyprintk", 1, 1);
+
 	sh_mv_setup();
 
 	/*
@@ -453,6 +456,10 @@ void __init setup_arch(char **cmdline_p)
 
 	paging_init();
 
+#ifdef CONFIG_PMB_ENABLE
+	pmb_init();
+#endif
+
 #ifdef CONFIG_SMP
 	plat_smp_setup();
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/sh_ksyms_32.c linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_ksyms_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/sh_ksyms_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_ksyms_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,37 +1,11 @@
 #include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/sched.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <asm/sections.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
 #include <asm/checksum.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
-#include <asm/ftrace.h>
-
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
-/* platform dependent support */
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(strlen);
-
-/* PCI exports */
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-#endif
+#include <asm/sections.h>
 
-/* mem exports */
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
@@ -40,6 +14,13 @@ EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
 EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_generic);
+EXPORT_SYMBOL(copy_page);
+EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(_ebss);
+EXPORT_SYMBOL(empty_zero_page);
 
 #define DECLARE_EXPORT(name)		\
 	extern void name(void);EXPORT_SYMBOL(name)
@@ -107,30 +88,6 @@ DECLARE_EXPORT(__sdivsi3_i4);
 DECLARE_EXPORT(__udivsi3_i4);
 DECLARE_EXPORT(__sdivsi3_i4i);
 DECLARE_EXPORT(__udivsi3_i4i);
-
-#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
-	defined(CONFIG_SH7705_CACHE_32KB))
-/* needed by some modules */
-EXPORT_SYMBOL(flush_cache_all);
-EXPORT_SYMBOL(flush_cache_range);
-EXPORT_SYMBOL(flush_dcache_page);
-#endif
-
 #ifdef CONFIG_MCOUNT
 DECLARE_EXPORT(mcount);
 #endif
-EXPORT_SYMBOL(csum_partial);
-EXPORT_SYMBOL(csum_partial_copy_generic);
-#ifdef CONFIG_IPV6
-EXPORT_SYMBOL(csum_ipv6_magic);
-#endif
-EXPORT_SYMBOL(copy_page);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(_ebss);
-EXPORT_SYMBOL(empty_zero_page);
-
-#ifndef CONFIG_CACHE_OFF
-EXPORT_SYMBOL(__flush_purge_region);
-EXPORT_SYMBOL(__flush_wback_region);
-EXPORT_SYMBOL(__flush_invalidate_region);
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/sh_ksyms_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_ksyms_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/sh_ksyms_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/sh_ksyms_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,16 +24,6 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
-/* platform dependent support */
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(kernel_thread);
-
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(screen_info);
-#endif
-
 EXPORT_SYMBOL(__put_user_asm_b);
 EXPORT_SYMBOL(__put_user_asm_w);
 EXPORT_SYMBOL(__put_user_asm_l);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/signal_32.c linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/signal_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,8 @@ sys_sigsuspend(old_sigset_t mask,
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
-	set_thread_flag(TIF_RESTORE_SIGMASK);
+	set_restore_sigmask();
+
 	return -ERESTARTNOHAND;
 }
 
@@ -590,7 +591,7 @@ static void do_signal(struct pt_regs *re
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
@@ -602,12 +603,13 @@ static void do_signal(struct pt_regs *re
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &ka, &info, oldset,
 				  regs, save_r0) == 0) {
-			/* a signal was successfully delivered; the saved
+			/*
+			 * A signal was successfully delivered; the saved
 			 * sigmask will have been stored in the signal frame,
 			 * and will be restored by sigreturn, so we can simply
-			 * clear the TIF_RESTORE_SIGMASK flag */
-			if (test_thread_flag(TIF_RESTORE_SIGMASK))
-				clear_thread_flag(TIF_RESTORE_SIGMASK);
+			 * clear the TS_RESTORE_SIGMASK flag
+			 */
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 
 			tracehook_signal_handler(signr, &info, &ka, regs,
 					test_thread_flag(TIF_SINGLESTEP));
@@ -631,10 +633,12 @@ no_signal:
 		}
 	}
 
-	/* if there's no signal to deliver, we just put the saved sigmask
-	 * back */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	/*
+	 * If there's no signal to deliver, we just put the saved sigmask
+	 * back.
+	 */
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/signal_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/signal_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/signal_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -101,7 +101,7 @@ static int do_signal(struct pt_regs *reg
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
 	else if (!oldset)
 		oldset = &current->blocked;
@@ -115,12 +115,12 @@ static int do_signal(struct pt_regs *reg
 			/*
 			 * If a signal was successfully delivered, the
 			 * saved sigmask is in its frame, and we can
-			 * clear the TIF_RESTORE_SIGMASK flag.
+			 * clear the TS_RESTORE_SIGMASK flag.
 			 */
-			if (test_thread_flag(TIF_RESTORE_SIGMASK))
-				clear_thread_flag(TIF_RESTORE_SIGMASK);
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 
-			tracehook_signal_handler(signr, &info, &ka, regs, 0);
+			tracehook_signal_handler(signr, &info, &ka, regs,
+					test_thread_flag(TIF_SINGLESTEP));
 			return 1;
 		}
 	}
@@ -146,8 +146,8 @@ no_signal:
 	}
 
 	/* No signal to deliver -- put the saved sigmask back */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 
@@ -176,6 +176,7 @@ sys_sigsuspend(old_sigset_t mask,
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
+		set_restore_sigmask();
 		regs->pc += 4;    /* because sys_sigreturn decrements the pc */
 		if (do_signal(regs, &saveset)) {
 			/* pc now points at signal handler. Need to decrement
@@ -315,7 +316,7 @@ setup_sigcontext_fpu(struct pt_regs *reg
 
 	if (current == last_task_used_math) {
 		enable_fpu();
-		save_fpu(current, regs);
+		save_fpu(current);
 		disable_fpu();
 		last_task_used_math = NULL;
 		regs->sr |= SR_FD;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/smp.c linux-libre-2.6.33-gnu1/arch/sh/kernel/smp.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -122,7 +122,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	stack_start.bss_start = 0; /* don't clear bss for secondary cpus */
 	stack_start.start_kernel_fn = start_secondary;
 
-	flush_cache_all();
+	flush_icache_range((unsigned long)&stack_start,
+			   (unsigned long)&stack_start + sizeof(stack_start));
+	wmb();
 
 	plat_start_cpu(cpu, (unsigned long)_stext);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/syscalls_64.S linux-libre-2.6.33-gnu1/arch/sh/kernel/syscalls_64.S
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/syscalls_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/syscalls_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -391,3 +391,5 @@ sys_call_table:
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo
 	.long sys_perf_event_open
+	.long sys_recvmmsg		/* 365 */
+	.long sys_accept4
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/sys_sh.c linux-libre-2.6.33-gnu1/arch/sh/kernel/sys_sh.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/sys_sh.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/sys_sh.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,37 +28,13 @@
 #include <asm/cacheflush.h>
 #include <asm/cachectl.h>
 
-static inline long
-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-	 unsigned long flags, int fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage int old_mmap(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	int fd, unsigned long off)
 {
 	if (off & ~PAGE_MASK)
 		return -EINVAL;
-	return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
 }
 
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
@@ -74,7 +50,7 @@ asmlinkage long sys_mmap2(unsigned long
 
 	pgoff >>= PAGE_SHIFT - 12;
 
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/topology.c linux-libre-2.6.33-gnu1/arch/sh/kernel/topology.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/topology.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/topology.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,32 @@
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
+cpumask_t cpu_core_map[NR_CPUS];
+
+static cpumask_t cpu_coregroup_map(unsigned int cpu)
+{
+	/*
+	 * Presently all SH-X3 SMP cores are multi-cores, so just keep it
+	 * simple until we have a method for determining topology..
+	 */
+	return cpu_possible_map;
+}
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+{
+	return &cpu_core_map[cpu];
+}
+
+int arch_update_cpu_topology(void)
+{
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu)
+		cpu_core_map[cpu] = cpu_coregroup_map(cpu);
+
+	return 0;
+}
+
 static int __init topology_init(void)
 {
 	int i, ret;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/traps_32.c linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/traps_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #include <linux/kexec.h>
 #include <linux/limits.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/sysfs.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -68,61 +69,49 @@ static const char *se_usermode_action[]
 	"signal+warn"
 };
 
-static int
-proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
-		    void *data)
+static int alignment_proc_show(struct seq_file *m, void *v)
 {
-	char *p = page;
-	int len;
-
-	p += sprintf(p, "User:\t\t%lu\n", se_user);
-	p += sprintf(p, "System:\t\t%lu\n", se_sys);
-	p += sprintf(p, "Half:\t\t%lu\n", se_half);
-	p += sprintf(p, "Word:\t\t%lu\n", se_word);
-	p += sprintf(p, "DWord:\t\t%lu\n", se_dword);
-	p += sprintf(p, "Multi:\t\t%lu\n", se_multi);
-	p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode,
+	seq_printf(m, "User:\t\t%lu\n", se_user);
+	seq_printf(m, "System:\t\t%lu\n", se_sys);
+	seq_printf(m, "Half:\t\t%lu\n", se_half);
+	seq_printf(m, "Word:\t\t%lu\n", se_word);
+	seq_printf(m, "DWord:\t\t%lu\n", se_dword);
+	seq_printf(m, "Multi:\t\t%lu\n", se_multi);
+	seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
 			se_usermode_action[se_usermode]);
-	p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+	seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
 			se_kernmode_warn ? "+warn" : "");
-
-	len = (p - page) - off;
-	if (len < 0)
-		len = 0;
-
-	*eof = (len <= count) ? 1 : 0;
-	*start = page + off;
-
-	return len;
+	return 0;
 }
 
-static int proc_alignment_write(struct file *file, const char __user *buffer,
-				unsigned long count, void *data)
+static int alignment_proc_open(struct inode *inode, struct file *file)
 {
-	char mode;
-
-	if (count > 0) {
-		if (get_user(mode, buffer))
-			return -EFAULT;
-		if (mode >= '0' && mode <= '5')
-			se_usermode = mode - '0';
-	}
-	return count;
+	return single_open(file, alignment_proc_show, NULL);
 }
 
-static int proc_alignment_kern_write(struct file *file, const char __user *buffer,
-				     unsigned long count, void *data)
+static ssize_t alignment_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
+	int *data = PDE(file->f_path.dentry->d_inode)->data;
 	char mode;
 
 	if (count > 0) {
 		if (get_user(mode, buffer))
 			return -EFAULT;
-		if (mode >= '0' && mode <= '1')
-			se_kernmode_warn = mode - '0';
+		if (mode >= '0' && mode <= '5')
+			*data = mode - '0';
 	}
 	return count;
 }
+
+static const struct file_operations alignment_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= alignment_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= alignment_proc_write,
+};
 #endif
 
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
@@ -463,12 +452,18 @@ int handle_unaligned_access(insn_size_t
 	rm = regs->regs[index];
 
 	/* shout about fixups */
-	if (!expected && printk_ratelimit())
-		printk(KERN_NOTICE "Fixing up unaligned %s access "
-		       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-		       user_mode(regs) ? "userspace" : "kernel",
-		       current->comm, task_pid_nr(current),
-		       (void *)regs->pc, instruction);
+	if (!expected) {
+		if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit())
+			pr_notice("Fixing up unaligned userspace access "
+				  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+				  current->comm, task_pid_nr(current),
+				  (void *)regs->pc, instruction);
+		else if (se_kernmode_warn && printk_ratelimit())
+			pr_notice("Fixing up unaligned kernel access "
+				  "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+				  current->comm, task_pid_nr(current),
+				  (void *)regs->pc, instruction);
+	}
 
 	ret = -EFAULT;
 	switch (instruction&0xF000) {
@@ -945,14 +940,9 @@ void __init trap_init(void)
 	set_exception_table_evt(0x800, do_reserved_inst);
 	set_exception_table_evt(0x820, do_illegal_slot_inst);
 #elif defined(CONFIG_SH_FPU)
-#ifdef CONFIG_CPU_SUBTYPE_SHX3
-	set_exception_table_evt(0xd80, fpu_state_restore_trap_handler);
-	set_exception_table_evt(0xda0, fpu_state_restore_trap_handler);
-#else
 	set_exception_table_evt(0x800, fpu_state_restore_trap_handler);
 	set_exception_table_evt(0x820, fpu_state_restore_trap_handler);
 #endif
-#endif
 
 #ifdef CONFIG_CPU_SH2
 	set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler);
@@ -1011,20 +1001,16 @@ static int __init alignment_init(void)
 	if (!dir)
 		return -ENOMEM;
 
-	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir);
+	res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_usermode);
 	if (!res)
 		return -ENOMEM;
 
-	res->read_proc = proc_alignment_read;
-	res->write_proc = proc_alignment_write;
-
-        res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir);
+        res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
+			       &alignment_proc_fops, &se_kernmode_warn);
         if (!res)
                 return -ENOMEM;
 
-        res->read_proc = proc_alignment_read;
-        res->write_proc = proc_alignment_kern_write;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/traps_64.c linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/traps_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/traps_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -600,7 +600,7 @@ static int misaligned_fpu_load(struct pt
 		   indexed by register number. */
 		if (last_task_used_math == current) {
 			enable_fpu();
-			save_fpu(current, regs);
+			save_fpu(current);
 			disable_fpu();
 			last_task_used_math = NULL;
 			regs->sr |= SR_FD;
@@ -673,7 +673,7 @@ static int misaligned_fpu_store(struct p
 		   indexed by register number. */
 		if (last_task_used_math == current) {
 			enable_fpu();
-			save_fpu(current, regs);
+			save_fpu(current);
 			disable_fpu();
 			last_task_used_math = NULL;
 			regs->sr |= SR_FD;
@@ -877,44 +877,39 @@ static int misaligned_fixup(struct pt_re
 
 static ctl_table unaligned_table[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "kernel_reports",
 		.data		= &kernel_mode_unaligned_fixup_count,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
+		.proc_handler	= proc_dointvec
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "user_reports",
 		.data		= &user_mode_unaligned_fixup_count,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
+		.proc_handler	= proc_dointvec
 	},
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "user_enable",
 		.data		= &user_mode_unaligned_fixup_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec},
+		.proc_handler	= proc_dointvec},
 	{}
 };
 
 static ctl_table unaligned_root[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "unaligned_fixup",
 		.mode		= 0555,
-		unaligned_table
+		.child		= unaligned_table
 	},
 	{}
 };
 
 static ctl_table sh64_root[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "sh64",
 		.mode		= 0555,
 		.child		= unaligned_root
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/kernel/traps.c linux-libre-2.6.33-gnu1/arch/sh/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/sh/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,8 +9,8 @@
 #include <asm/unwinder.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_BUG
-void handle_BUG(struct pt_regs *regs)
+#ifdef CONFIG_GENERIC_BUG
+static void handle_BUG(struct pt_regs *regs)
 {
 	const struct bug_entry *bug;
 	unsigned long bugaddr = regs->pc;
@@ -81,7 +81,7 @@ BUILD_TRAP_HANDLER(bug)
 		       SIGTRAP) == NOTIFY_STOP)
 		return;
 
-#ifdef CONFIG_BUG
+#ifdef CONFIG_GENERIC_BUG
 	if (__kernel_text_address(instruction_pointer(regs))) {
 		insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
 		if (insn == TRAPA_BUG_OPCODE)
@@ -95,9 +95,11 @@ BUILD_TRAP_HANDLER(bug)
 
 BUILD_TRAP_HANDLER(nmi)
 {
+	unsigned int cpu = smp_processor_id();
 	TRAP_HANDLER_DECL;
 
 	nmi_enter();
+	nmi_count(cpu)++;
 
 	switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
 	case NOTIFY_OK:
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/lib/Makefile linux-libre-2.6.33-gnu1/arch/sh/lib/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/lib/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
 # Makefile for SuperH-specific library files..
 #
 
-lib-y  = delay.o memset.o memmove.o memchr.o \
+lib-y  = delay.o memmove.o memchr.o \
 	 checksum.o strlen.o div64.o div64-generic.o
 
 # Extracted from libgcc
@@ -23,8 +23,11 @@ obj-y				+= io.o
 memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
+memset-y			:= memset.o
+memset-$(CONFIG_CPU_SH4)	:= memset-sh4.o
+
 lib-$(CONFIG_MMU)		+= copy_page.o __clear_user.o
 lib-$(CONFIG_MCOUNT)		+= mcount.o
-lib-y				+= $(memcpy-y) $(udivsi3-y)
+lib-y				+= $(memcpy-y) $(memset-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/lib/memset-sh4.S linux-libre-2.6.33-gnu1/arch/sh/lib/memset-sh4.S
--- linux-libre-2.6.32-gnu1/arch/sh/lib/memset-sh4.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/lib/memset-sh4.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,107 @@
+/*
+ * "memset" implementation for SH4
+ *
+ * Copyright (C) 1999  Niibe Yutaka
+ * Copyright (c) 2009  STMicroelectronics Limited
+ * Author: Stuart Menefy <stuart.menefy:st.com>
+ */
+
+/*
+ *            void *memset(void *s, int c, size_t n);
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(memset)
+	mov	#12,r0
+	add	r6,r4
+	cmp/gt	r6,r0
+	bt/s	40f		! if it's too small, set a byte at once
+	 mov	r4,r0
+	and	#3,r0
+	cmp/eq	#0,r0
+	bt/s	2f		! It's aligned
+	 sub	r0,r6
+1:
+	dt	r0
+	bf/s	1b
+	 mov.b	r5,@-r4
+2:				! make VVVV
+	extu.b	r5,r5
+	swap.b	r5,r0		!   V0
+	or	r0,r5		!   VV
+	swap.w	r5,r0		! VV00
+	or	r0,r5		! VVVV
+
+	! Check if enough bytes need to be copied to be worth the big loop
+	mov	#0x40, r0	! (MT)
+	cmp/gt	r6,r0		! (MT)  64 > len => slow loop
+
+	bt/s	22f
+	 mov	r6,r0
+
+	! align the dst to the cache block size if necessary
+	mov	r4, r3
+	mov	#~(0x1f), r1
+
+	and	r3, r1
+	cmp/eq	r3, r1
+
+	bt/s	11f		! dst is already aligned
+	 sub	r1, r3		! r3-r1 -> r3
+	shlr2	r3		! number of loops
+
+10:	mov.l	r5,@-r4
+	dt	r3
+	bf/s	10b
+	 add	#-4, r6
+
+11:	! dst is 32byte aligned
+	mov	r6,r2
+	mov	#-5,r0
+	shld	r0,r2		! number of loops
+
+	add	#-32, r4
+	mov	r5, r0
+12:
+	movca.l	r0,@r4
+	mov.l	r5,@(4, r4)
+	mov.l	r5,@(8, r4)
+	mov.l	r5,@(12,r4)
+	mov.l	r5,@(16,r4)
+	mov.l	r5,@(20,r4)
+	add	#-0x20, r6
+	mov.l	r5,@(24,r4)
+	dt	r2
+	mov.l	r5,@(28,r4)
+	bf/s	12b
+	 add	#-32, r4
+
+	add	#32, r4
+	mov	#8, r0
+	cmp/ge	r0, r6
+	bf	40f
+
+	mov	r6,r0
+22:
+	shlr2	r0
+	shlr	r0		! r0 = r6 >> 3
+3:
+	dt	r0
+	mov.l	r5,@-r4		! set 8-byte at once
+	bf/s	3b
+	 mov.l	r5,@-r4
+	!
+	mov	#7,r0
+	and	r0,r6
+
+	! fill bytes (length may be zero)
+40:	tst	r6,r6
+	bt	5f
+4:
+	dt	r6
+	bf/s	4b
+	 mov.b	r5,@-r4
+5:
+	rts
+	 mov	r4,r0
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/Makefile linux-libre-2.6.33-gnu1/arch/sh/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -78,6 +78,9 @@ defaultimage-$(CONFIG_SUPERH32)			:= zIm
 defaultimage-$(CONFIG_SH_SH7785LCR)		:= uImage
 defaultimage-$(CONFIG_SH_RSK)			:= uImage
 defaultimage-$(CONFIG_SH_URQUELL)		:= uImage
+defaultimage-$(CONFIG_SH_MIGOR)			:= uImage
+defaultimage-$(CONFIG_SH_AP325RXA)		:= uImage
+defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE)	:= uImage
 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE)	:= vmlinux
 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE)	:= vmlinux
 
@@ -136,6 +139,7 @@ machdir-$(CONFIG_SH_7751_SYSTEMH)		+= ma
 machdir-$(CONFIG_SH_EDOSK7705)			+= mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)			+= mach-highlander
 machdir-$(CONFIG_SH_MIGOR)			+= mach-migor
+machdir-$(CONFIG_SH_AP325RXA)			+= mach-ap325rxa
 machdir-$(CONFIG_SH_KFR2R09)			+= mach-kfr2r09
 machdir-$(CONFIG_SH_ECOVEC)			+= mach-ecovec24
 machdir-$(CONFIG_SH_SDK7780)			+= mach-sdk7780
@@ -201,10 +205,7 @@ libs-$(CONFIG_SUPERH64)		:= arch/sh/lib6
 
 BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \
 	       zImage vmlinux.srec romImage
-PHONY += maketools $(BOOT_TARGETS) FORCE
-
-maketools:  include/linux/version.h FORCE
-	$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
+PHONY += $(BOOT_TARGETS)
 
 all: $(KBUILD_IMAGE)
 
@@ -213,7 +214,8 @@ $(BOOT_TARGETS): vmlinux
 
 compressed: zImage
 
-archprepare: maketools
+archprepare:
+	$(Q)$(MAKE) $(build)=arch/sh/tools include/generated/machtypes.h
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
@@ -230,5 +232,3 @@ define archhelp
 	@echo '  uImage.bz2	           - Kernel-only image for U-Boot (bzip2)'
 	@echo '  uImage.lzma	           - Kernel-only image for U-Boot (lzma)'
 endef
-
-CLEAN_FILES += include/asm-sh/machtypes.h
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/math-emu/math.c linux-libre-2.6.33-gnu1/arch/sh/math-emu/math.c
--- linux-libre-2.6.32-gnu1/arch/sh/math-emu/math.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/math-emu/math.c	2010-02-24 13:52:17.000000000 -0500
@@ -558,7 +558,7 @@ static int ieee_fpe_handler(struct pt_re
 					    (finsn >> 8) & 0xf);
 			tsk->thread.fpu.hard.fpscr &=
 				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
-			set_tsk_thread_flag(tsk, TIF_USEDFPU);
+			task_thread_info(tsk)->status |= TS_USEDFPU;
 		} else {
 			info.si_signo = SIGFPE;
 			info.si_errno = 0;
@@ -619,10 +619,10 @@ int do_fpu_inst(unsigned short inst, str
 	struct task_struct *tsk = current;
 	struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft);
 
-	if (!test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
+	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
 		/* initialize once. */
 		fpu_init(fpu);
-		set_tsk_thread_flag(tsk, TIF_USEDFPU);
+		task_thread_info(tsk)->status |= TS_USEDFPU;
 	}
 
 	return fpu_emulate(inst, fpu, regs);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/cache.c linux-libre-2.6.33-gnu1/arch/sh/mm/cache.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/cache.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/cache.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,8 +27,11 @@ void (*local_flush_icache_page)(void *ar
 void (*local_flush_cache_sigtramp)(void *args) = cache_noop;
 
 void (*__flush_wback_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_wback_region);
 void (*__flush_purge_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_purge_region);
 void (*__flush_invalidate_region)(void *start, int size);
+EXPORT_SYMBOL(__flush_invalidate_region);
 
 static inline void noop__flush_region(void *start, int size)
 {
@@ -130,12 +133,8 @@ void __update_cache(struct vm_area_struc
 	page = pfn_to_page(pfn);
 	if (pfn_valid(pfn)) {
 		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
-		if (dirty) {
-			unsigned long addr = (unsigned long)page_address(page);
-
-			if (pages_do_alias(addr, address & PAGE_MASK))
-				__flush_purge_region((void *)addr, PAGE_SIZE);
-		}
+		if (dirty)
+			__flush_purge_region(page_address(page), PAGE_SIZE);
 	}
 }
 
@@ -161,14 +160,21 @@ void flush_cache_all(void)
 {
 	cacheop_on_each_cpu(local_flush_cache_all, NULL, 1);
 }
+EXPORT_SYMBOL(flush_cache_all);
 
 void flush_cache_mm(struct mm_struct *mm)
 {
+	if (boot_cpu_data.dcache.n_aliases == 0)
+		return;
+
 	cacheop_on_each_cpu(local_flush_cache_mm, mm, 1);
 }
 
 void flush_cache_dup_mm(struct mm_struct *mm)
 {
+	if (boot_cpu_data.dcache.n_aliases == 0)
+		return;
+
 	cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1);
 }
 
@@ -195,11 +201,13 @@ void flush_cache_range(struct vm_area_st
 
 	cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1);
 }
+EXPORT_SYMBOL(flush_cache_range);
 
 void flush_dcache_page(struct page *page)
 {
 	cacheop_on_each_cpu(local_flush_dcache_page, page, 1);
 }
+EXPORT_SYMBOL(flush_dcache_page);
 
 void flush_icache_range(unsigned long start, unsigned long end)
 {
@@ -265,7 +273,11 @@ static void __init emit_cache_params(voi
 
 void __init cpu_cache_init(void)
 {
-	unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+	unsigned int cache_disabled = 0;
+
+#ifdef CCR
+	cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+#endif
 
 	compute_alias(&boot_cpu_data.icache);
 	compute_alias(&boot_cpu_data.dcache);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh4.c linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh4.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh4.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  * arch/sh/mm/cache-sh4.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2001 - 2007  Paul Mundt
+ * Copyright (C) 2001 - 2009  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  * Copyright (c) 2007 STMicroelectronics (R&D) Ltd.
  *
@@ -15,6 +15,8 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/fs.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
@@ -23,21 +25,12 @@
  * flushing. Anything exceeding this will simply flush the dcache in its
  * entirety.
  */
-#define MAX_DCACHE_PAGES	64	/* XXX: Tune for ways */
 #define MAX_ICACHE_PAGES	32
 
 static void __flush_cache_one(unsigned long addr, unsigned long phys,
 			       unsigned long exec_offset);
 
 /*
- * This is initialised here to ensure that it is not placed in the BSS.  If
- * that were to happen, note that cache_init gets called before the BSS is
- * cleared, so this would get nulled out which would be hopeless.
- */
-static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
-	(void (*)(unsigned long, unsigned long))0xdeadbeef;
-
-/*
  * Write back the range of D-cache, and purge the I-cache.
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format,
@@ -97,15 +90,15 @@ static inline void flush_cache_one(unsig
 	unsigned long flags, exec_offset = 0;
 
 	/*
-	 * All types of SH-4 require PC to be in P2 to operate on the I-cache.
-	 * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
+	 * All types of SH-4 require PC to be uncached to operate on the I-cache.
+	 * Some types of SH-4 require PC to be uncached to operate on the D-cache.
 	 */
 	if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
 	    (start < CACHE_OC_ADDRESS_ARRAY))
-		exec_offset = 0x20000000;
+		exec_offset = cached_to_uncached;
 
 	local_irq_save(flags);
-	__flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset);
+	__flush_cache_one(start, phys, exec_offset);
 	local_irq_restore(flags);
 }
 
@@ -124,7 +117,7 @@ static void sh4_flush_dcache_page(void *
 	else
 #endif
 	{
-		unsigned long phys = PHYSADDR(page_address(page));
+		unsigned long phys = page_to_phys(page);
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
 		int i, n;
 
@@ -159,10 +152,27 @@ static void __uses_jump_to_uncached flus
 	local_irq_restore(flags);
 }
 
-static inline void flush_dcache_all(void)
+static void flush_dcache_all(void)
 {
-	(*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
-	wmb();
+	unsigned long addr, end_addr, entry_offset;
+
+	end_addr = CACHE_OC_ADDRESS_ARRAY +
+		(current_cpu_data.dcache.sets <<
+		 current_cpu_data.dcache.entry_shift) *
+			current_cpu_data.dcache.ways;
+
+	entry_offset = 1 << current_cpu_data.dcache.entry_shift;
+
+	for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; ) {
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+		__raw_writel(0, addr); addr += entry_offset;
+	}
 }
 
 static void sh4_flush_cache_all(void *unused)
@@ -171,89 +181,13 @@ static void sh4_flush_cache_all(void *un
 	flush_icache_all();
 }
 
-static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
-			     unsigned long end)
-{
-	unsigned long d = 0, p = start & PAGE_MASK;
-	unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;
-	unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;
-	unsigned long select_bit;
-	unsigned long all_aliases_mask;
-	unsigned long addr_offset;
-	pgd_t *dir;
-	pmd_t *pmd;
-	pud_t *pud;
-	pte_t *pte;
-	int i;
-
-	dir = pgd_offset(mm, p);
-	pud = pud_offset(dir, p);
-	pmd = pmd_offset(pud, p);
-	end = PAGE_ALIGN(end);
-
-	all_aliases_mask = (1 << n_aliases) - 1;
-
-	do {
-		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) {
-			p &= PMD_MASK;
-			p += PMD_SIZE;
-			pmd++;
-
-			continue;
-		}
-
-		pte = pte_offset_kernel(pmd, p);
-
-		do {
-			unsigned long phys;
-			pte_t entry = *pte;
-
-			if (!(pte_val(entry) & _PAGE_PRESENT)) {
-				pte++;
-				p += PAGE_SIZE;
-				continue;
-			}
-
-			phys = pte_val(entry) & PTE_PHYS_MASK;
-
-			if ((p ^ phys) & alias_mask) {
-				d |= 1 << ((p & alias_mask) >> PAGE_SHIFT);
-				d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT);
-
-				if (d == all_aliases_mask)
-					goto loop_exit;
-			}
-
-			pte++;
-			p += PAGE_SIZE;
-		} while (p < end && ((unsigned long)pte & ~PAGE_MASK));
-		pmd++;
-	} while (p < end);
-
-loop_exit:
-	addr_offset = 0;
-	select_bit = 1;
-
-	for (i = 0; i < n_aliases; i++) {
-		if (d & select_bit) {
-			(*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE);
-			wmb();
-		}
-
-		select_bit <<= 1;
-		addr_offset += PAGE_SIZE;
-	}
-}
-
 /*
  * Note : (RPC) since the caches are physically tagged, the only point
  * of flush_cache_mm for SH-4 is to get rid of aliases from the
  * D-cache.  The assumption elsewhere, e.g. flush_cache_range, is that
  * lines can stay resident so long as the virtual address they were
  * accessed with (hence cache set) is in accord with the physical
- * address (i.e. tag).  It's no different here.  So I reckon we don't
- * need to flush the I-cache, since aliases don't matter for that.  We
- * should try that.
+ * address (i.e. tag).  It's no different here.
  *
  * Caller takes mm->mmap_sem.
  */
@@ -264,33 +198,7 @@ static void sh4_flush_cache_mm(void *arg
 	if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
 		return;
 
-	/*
-	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
-	 * the cache is physically tagged, the data can just be left in there.
-	 */
-	if (boot_cpu_data.dcache.n_aliases == 0)
-		return;
-
-	/*
-	 * Don't bother groveling around the dcache for the VMA ranges
-	 * if there are too many PTEs to make it worthwhile.
-	 */
-	if (mm->nr_ptes >= MAX_DCACHE_PAGES)
-		flush_dcache_all();
-	else {
-		struct vm_area_struct *vma;
-
-		/*
-		 * In this case there are reasonably sized ranges to flush,
-		 * iterate through the VMA list and take care of any aliases.
-		 */
-		for (vma = mm->mmap; vma; vma = vma->vm_next)
-			__flush_cache_mm(mm, vma->vm_start, vma->vm_end);
-	}
-
-	/* Only touch the icache if one of the VMAs has VM_EXEC set. */
-	if (mm->exec_vm)
-		flush_icache_all();
+	flush_dcache_all();
 }
 
 /*
@@ -303,44 +211,62 @@ static void sh4_flush_cache_page(void *a
 {
 	struct flusher_data *data = args;
 	struct vm_area_struct *vma;
+	struct page *page;
 	unsigned long address, pfn, phys;
-	unsigned int alias_mask;
+	int map_coherent = 0;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	void *vaddr;
 
 	vma = data->vma;
-	address = data->addr1;
+	address = data->addr1 & PAGE_MASK;
 	pfn = data->addr2;
 	phys = pfn << PAGE_SHIFT;
+	page = pfn_to_page(pfn);
 
 	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
 		return;
 
-	alias_mask = boot_cpu_data.dcache.alias_mask;
+	pgd = pgd_offset(vma->vm_mm, address);
+	pud = pud_offset(pgd, address);
+	pmd = pmd_offset(pud, address);
+	pte = pte_offset_kernel(pmd, address);
 
-	/* We only need to flush D-cache when we have alias */
-	if ((address^phys) & alias_mask) {
-		/* Loop 4K of the D-cache */
-		flush_cache_one(
-			CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
-			phys);
-		/* Loop another 4K of the D-cache */
-		flush_cache_one(
-			CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
-			phys);
-	}
+	/* If the page isn't present, there is nothing to do here. */
+	if (!(pte_val(*pte) & _PAGE_PRESENT))
+		return;
 
-	alias_mask = boot_cpu_data.icache.alias_mask;
-	if (vma->vm_flags & VM_EXEC) {
+	if ((vma->vm_mm == current->active_mm))
+		vaddr = NULL;
+	else {
 		/*
-		 * Evict entries from the portion of the cache from which code
-		 * may have been executed at this address (virtual).  There's
-		 * no need to evict from the portion corresponding to the
-		 * physical address as for the D-cache, because we know the
-		 * kernel has never executed the code through its identity
-		 * translation.
+		 * Use kmap_coherent or kmap_atomic to do flushes for
+		 * another ASID than the current one.
 		 */
-		flush_cache_one(
-			CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
-			phys);
+		map_coherent = (current_cpu_data.dcache.n_aliases &&
+			!test_bit(PG_dcache_dirty, &page->flags) &&
+			page_mapped(page));
+		if (map_coherent)
+			vaddr = kmap_coherent(page, address);
+		else
+			vaddr = kmap_atomic(page, KM_USER0);
+
+		address = (unsigned long)vaddr;
+	}
+
+	flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
+			(address & shm_align_mask), phys);
+
+	if (vma->vm_flags & VM_EXEC)
+		flush_icache_all();
+
+	if (vaddr) {
+		if (map_coherent)
+			kunmap_coherent(vaddr);
+		else
+			kunmap_atomic(vaddr, KM_USER0);
 	}
 }
 
@@ -373,24 +299,10 @@ static void sh4_flush_cache_range(void *
 	if (boot_cpu_data.dcache.n_aliases == 0)
 		return;
 
-	/*
-	 * Don't bother with the lookup and alias check if we have a
-	 * wide range to cover, just blow away the dcache in its
-	 * entirety instead. -- PFM.
-	 */
-	if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES)
-		flush_dcache_all();
-	else
-		__flush_cache_mm(vma->vm_mm, start, end);
+	flush_dcache_all();
 
-	if (vma->vm_flags & VM_EXEC) {
-		/*
-		 * TODO: Is this required???  Need to look at how I-cache
-		 * coherency is assured when new programs are loaded to see if
-		 * this matters.
-		 */
+	if (vma->vm_flags & VM_EXEC)
 		flush_icache_all();
-	}
 }
 
 /**
@@ -464,245 +376,6 @@ static void __flush_cache_one(unsigned l
 	} while (--way_count != 0);
 }
 
-/*
- * Break the 1, 2 and 4 way variants of this out into separate functions to
- * avoid nearly all the overhead of having the conditional stuff in the function
- * bodies (+ the 1 and 2 way cases avoid saving any registers too).
- *
- * We want to eliminate unnecessary bus transactions, so this code uses
- * a non-obvious technique.
- *
- * Loop over a cache way sized block of, one cache line at a time. For each
- * line, use movca.a to cause the current cache line contents to be written
- * back, but without reading anything from main memory. However this has the
- * side effect that the cache is now caching that memory location. So follow
- * this with a cache invalidate to mark the cache line invalid. And do all
- * this with interrupts disabled, to avoid the cache line being accidently
- * evicted while it is holding garbage.
- *
- * This also breaks in a number of circumstances:
- * - if there are modifications to the region of memory just above
- *   empty_zero_page (for example because a breakpoint has been placed
- *   there), then these can be lost.
- *
- *   This is because the the memory address which the cache temporarily
- *   caches in the above description is empty_zero_page. So the
- *   movca.l hits the cache (it is assumed that it misses, or at least
- *   isn't dirty), modifies the line and then invalidates it, losing the
- *   required change.
- *
- * - If caches are disabled or configured in write-through mode, then
- *   the movca.l writes garbage directly into memory.
- */
-static void __flush_dcache_segment_writethrough(unsigned long start,
-					        unsigned long extent_per_way)
-{
-	unsigned long addr;
-	int i;
-
-	addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask);
-
-	while (extent_per_way) {
-		for (i = 0; i < cpu_data->dcache.ways; i++)
-			__raw_writel(0, addr + cpu_data->dcache.way_incr * i);
-
-		addr += cpu_data->dcache.linesz;
-		extent_per_way -= cpu_data->dcache.linesz;
-	}
-}
-
-static void __flush_dcache_segment_1way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/*
-	 * The previous code aligned base_addr to 16k, i.e. the way_size of all
-	 * existing SH-4 D-caches.  Whilst I don't see a need to have this
-	 * aligned to any better than the cache line size (which it will be
-	 * anyway by construction), let's align it to at least the way_size of
-	 * any existing or conceivable SH-4 D-cache.  -- RPC
-	 */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		a0 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "ocbi @%0" : : "r" (a0));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-	} while (a0 < a0e);
-}
-
-static void __flush_dcache_segment_2way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a1, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/* See comment under 1-way above */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a1 = a0 + way_incr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		a0 += linesz;
-		a1 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1" : :
-			     "r" (a0), "r" (a1));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-		a1 += linesz;
-	} while (a0 < a0e);
-}
-
-static void __flush_dcache_segment_4way(unsigned long start,
-					unsigned long extent_per_way)
-{
-	unsigned long orig_sr, sr_with_bl;
-	unsigned long base_addr;
-	unsigned long way_incr, linesz, way_size;
-	struct cache_info *dcache;
-	register unsigned long a0, a1, a2, a3, a0e;
-
-	asm volatile("stc sr, %0" : "=r" (orig_sr));
-	sr_with_bl = orig_sr | (1<<28);
-	base_addr = ((unsigned long)&empty_zero_page[0]);
-
-	/* See comment under 1-way above */
-	base_addr = ((base_addr >> 16) << 16);
-	base_addr |= start;
-
-	dcache = &boot_cpu_data.dcache;
-	linesz = dcache->linesz;
-	way_incr = dcache->way_incr;
-	way_size = dcache->way_size;
-
-	a0 = base_addr;
-	a1 = a0 + way_incr;
-	a2 = a1 + way_incr;
-	a3 = a2 + way_incr;
-	a0e = base_addr + extent_per_way;
-	do {
-		asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-		asm volatile("movca.l r0, @%0\n\t"
-			     "movca.l r0, @%1\n\t"
-			     "movca.l r0, @%2\n\t"
-			     "movca.l r0, @%3\n\t"
-			     "ocbi @%0\n\t"
-			     "ocbi @%1\n\t"
-			     "ocbi @%2\n\t"
-			     "ocbi @%3\n\t" : :
-			     "r" (a0), "r" (a1), "r" (a2), "r" (a3));
-		asm volatile("ldc %0, sr" : : "r" (orig_sr));
-		a0 += linesz;
-		a1 += linesz;
-		a2 += linesz;
-		a3 += linesz;
-	} while (a0 < a0e);
-}
-
 extern void __weak sh4__flush_region_init(void);
 
 /*
@@ -710,32 +383,11 @@ extern void __weak sh4__flush_region_ini
  */
 void __init sh4_cache_init(void)
 {
-	unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT);
-
 	printk("PVR=%08x CVR=%08x PRR=%08x\n",
 		ctrl_inl(CCN_PVR),
 		ctrl_inl(CCN_CVR),
 		ctrl_inl(CCN_PRR));
 
-	if (wt_enabled)
-		__flush_dcache_segment_fn = __flush_dcache_segment_writethrough;
-	else {
-		switch (boot_cpu_data.dcache.ways) {
-		case 1:
-			__flush_dcache_segment_fn = __flush_dcache_segment_1way;
-			break;
-		case 2:
-			__flush_dcache_segment_fn = __flush_dcache_segment_2way;
-			break;
-		case 4:
-			__flush_dcache_segment_fn = __flush_dcache_segment_4way;
-			break;
-		default:
-			panic("unknown number of cache ways\n");
-			break;
-		}
-	}
-
 	local_flush_icache_range	= sh4_flush_icache_range;
 	local_flush_dcache_page		= sh4_flush_dcache_page;
 	local_flush_cache_all		= sh4_flush_cache_all;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh5.c linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh5.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh5.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh5.c	2010-02-24 13:52:17.000000000 -0500
@@ -563,7 +563,7 @@ static void sh5_flush_cache_page(void *a
 
 static void sh5_flush_dcache_page(void *page)
 {
-	sh64_dcache_purge_phy_page(page_to_phys(page));
+	sh64_dcache_purge_phy_page(page_to_phys((struct page *)page));
 	wmb();
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh7705.c linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh7705.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/cache-sh7705.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/cache-sh7705.c	2010-02-24 13:52:17.000000000 -0500
@@ -141,7 +141,7 @@ static void sh7705_flush_dcache_page(voi
 	if (mapping && !mapping_mapped(mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
 	else
-		__flush_dcache_page(PHYSADDR(page_address(page)));
+		__flush_dcache_page(__pa(page_address(page)));
 }
 
 static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/consistent.c linux-libre-2.6.33-gnu1/arch/sh/mm/consistent.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/consistent.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/consistent.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,11 +15,15 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
 
 #define PREALLOC_DMA_DEBUG_ENTRIES	4096
 
+struct dma_map_ops *dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
 static int __init dma_init(void)
 {
 	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
@@ -27,15 +31,12 @@ static int __init dma_init(void)
 }
 fs_initcall(dma_init);
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t gfp)
+void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+				 dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret, *ret_nocache;
 	int order = get_order(size);
 
-	if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
-		return ret;
-
 	ret = (void *)__get_free_pages(gfp, order);
 	if (!ret)
 		return NULL;
@@ -57,35 +58,26 @@ void *dma_alloc_coherent(struct device *
 
 	*dma_handle = virt_to_phys(ret);
 
-	debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache);
-
 	return ret_nocache;
 }
-EXPORT_SYMBOL(dma_alloc_coherent);
 
-void dma_free_coherent(struct device *dev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
+void dma_generic_free_coherent(struct device *dev, size_t size,
+			       void *vaddr, dma_addr_t dma_handle)
 {
 	int order = get_order(size);
 	unsigned long pfn = dma_handle >> PAGE_SHIFT;
 	int k;
 
-	WARN_ON(irqs_disabled());	/* for portability */
-
-	if (dma_release_from_coherent(dev, order, vaddr))
-		return;
-
-	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
 	for (k = 0; k < (1 << order); k++)
 		__free_pages(pfn_to_page(pfn + k), 0);
+
 	iounmap(vaddr);
 }
-EXPORT_SYMBOL(dma_free_coherent);
 
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		    enum dma_data_direction direction)
 {
-#ifdef CONFIG_CPU_SH5
+#if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB)
 	void *p1addr = vaddr;
 #else
 	void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/init.c linux-libre-2.6.33-gnu1/arch/sh/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/pagemap.h>
 #include <linux/percpu.h>
 #include <linux/io.h>
+#include <linux/dma-mapping.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
 #include <asm/cacheflush.h>
@@ -186,11 +187,21 @@ void __init paging_init(void)
 	set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
 }
 
+/*
+ * Early initialization for any I/O MMUs we might have.
+ */
+static void __init iommu_init(void)
+{
+	no_iommu_init();
+}
+
 void __init mem_init(void)
 {
 	int codesize, datasize, initsize;
 	int nid;
 
+	iommu_init();
+
 	num_physpages = 0;
 	high_memory = NULL;
 
@@ -323,4 +334,12 @@ int memory_add_physaddr_to_nid(u64 addr)
 }
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
+
 #endif /* CONFIG_MEMORY_HOTPLUG */
+
+#ifdef CONFIG_PMB
+int __in_29bit_mode(void)
+{
+	return !(ctrl_inl(PMB_PASCR) & PASCR_SE);
+}
+#endif /* CONFIG_PMB */
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/ioremap_32.c linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_32.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/ioremap_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,10 +33,10 @@
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
-			unsigned long flags)
+void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size,
+			       unsigned long flags, void *caller)
 {
-	struct vm_struct * area;
+	struct vm_struct *area;
 	unsigned long offset, last_addr, addr, orig_addr;
 	pgprot_t pgprot;
 
@@ -67,7 +67,7 @@ void __iomem *__ioremap(unsigned long ph
 	/*
 	 * Ok, go for it..
 	 */
-	area = get_vm_area(size, VM_IOREMAP);
+	area = get_vm_area_caller(size, VM_IOREMAP, caller);
 	if (!area)
 		return NULL;
 	area->phys_addr = phys_addr;
@@ -103,7 +103,7 @@ void __iomem *__ioremap(unsigned long ph
 
 	return (void __iomem *)(offset + (char *)orig_addr);
 }
-EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__ioremap_caller);
 
 void __iounmap(void __iomem *addr)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/ioremap_64.c linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_64.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/ioremap_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/ioremap_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -258,15 +258,15 @@ static void shmedia_unmapioaddr(unsigned
 	pte_clear(&init_mm, vaddr, ptep);
 }
 
-void __iomem *__ioremap(unsigned long offset, unsigned long size,
-			unsigned long flags)
+void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
+			       unsigned long flags, void *caller)
 {
 	char name[14];
 
 	sprintf(name, "phys_%08x", (u32)offset);
 	return shmedia_alloc_io(offset, size, name, flags);
 }
-EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__ioremap_caller);
 
 void __iounmap(void __iomem *virtual)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/Kconfig linux-libre-2.6.33-gnu1/arch/sh/mm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/sh/mm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -82,9 +82,7 @@ config 32BIT
 
 config PMB_ENABLE
 	bool "Support 32-bit physical addressing through PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
-	select 32BIT
-	default y
+	depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
 	help
 	  If you say Y here, physical addressing will be extended to
 	  32-bits through the SH-4A PMB. If this is not set, legacy
@@ -97,8 +95,7 @@ choice
 
 config PMB
 	bool "PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
-	select 32BIT
+	depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
 	help
 	  If you say Y here, physical addressing will be extended to
 	  32-bits through the SH-4A PMB. If this is not set, legacy
@@ -106,9 +103,7 @@ config PMB
 
 config PMB_FIXED
 	bool "fixed PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \
-					   CPU_SUBTYPE_SH7780 || \
-					   CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP
 	select 32BIT
 	help
 	  If this option is enabled, fixed PMB mappings are inherited
@@ -258,6 +253,15 @@ endchoice
 
 source "mm/Kconfig"
 
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on SMP
+	default y
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
 endmenu
 
 menu "Cache configuration"
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/kmap.c linux-libre-2.6.33-gnu1/arch/sh/mm/kmap.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/kmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/kmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,9 @@ void *kmap_coherent(struct page *page, u
 	pagefault_disable();
 
 	idx = FIX_CMAP_END -
-		((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT);
+		(((addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1)) +
+		 (FIX_N_COLOURS * smp_processor_id()));
+
 	vaddr = __fix_to_virt(idx);
 
 	BUG_ON(!pte_none(*(kmap_coherent_pte - idx)));
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/Makefile linux-libre-2.6.33-gnu1/arch/sh/mm/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/mm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -33,8 +33,7 @@ obj-y				+= $(tlb-y)
 endif
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB)		+= pmb.o
-obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
+obj-$(CONFIG_PMB_ENABLE)	+= pmb.o
 obj-$(CONFIG_NUMA)		+= numa.o
 
 # Special flags for fault_64.o.  This puts restrictions on the number of
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/mmap.c linux-libre-2.6.33-gnu1/arch/sh/mm/mmap.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/mmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/mmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,8 @@ unsigned long arch_get_unmapped_area(str
 		/* We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
 			return -EINVAL;
 		return addr;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/numa.c linux-libre-2.6.33-gnu1/arch/sh/mm/numa.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/numa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/numa.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ void __init setup_memory(void)
 {
 	unsigned long free_pfn = PFN_UP(__pa(_end));
 	u64 base = min_low_pfn << PAGE_SHIFT;
-	u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
+	u64 size = (max_low_pfn << PAGE_SHIFT) - base;
 
 	lmb_add(base, size);
 
@@ -38,6 +38,15 @@ void __init setup_memory(void)
 		    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
 
 	/*
+	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+	 */
+	if (CONFIG_ZERO_PAGE_OFFSET != 0)
+		lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
+
+	lmb_analyze();
+	lmb_dump_all();
+
+	/*
 	 * Node 0 sets up its pgdat at the first available pfn,
 	 * and bumps it up before setting up the bootmem allocator.
 	 */
@@ -60,7 +69,7 @@ void __init setup_bootmem_node(int nid,
 	unsigned long bootmem_paddr;
 
 	/* Don't allow bogus node assignment */
-	BUG_ON(nid > MAX_NUMNODES || nid == 0);
+	BUG_ON(nid > MAX_NUMNODES || nid <= 0);
 
 	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
@@ -71,7 +80,7 @@ void __init setup_bootmem_node(int nid,
 
 	/* Node-local pgdat */
 	NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
-					     SMP_CACHE_BYTES, end_pfn));
+					     SMP_CACHE_BYTES, end));
 	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
 	NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
@@ -81,7 +90,7 @@ void __init setup_bootmem_node(int nid,
 	/* Node-local bootmap */
 	bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
 	bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
-				       PAGE_SIZE, end_pfn);
+				       PAGE_SIZE, end);
 	init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
 			  start_pfn, end_pfn);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/pmb.c linux-libre-2.6.33-gnu1/arch/sh/mm/pmb.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/pmb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/pmb.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,29 +35,9 @@
 
 static void __pmb_unmap(struct pmb_entry *);
 
-static struct kmem_cache *pmb_cache;
+static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
 static unsigned long pmb_map;
 
-static struct pmb_entry pmb_init_map[] = {
-	/* vpn         ppn         flags (ub/sz/c/wt) */
-
-	/* P1 Section Mappings */
-	{ 0x80000000, 0x00000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x84000000, 0x04000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, },
-	{ 0x90000000, 0x10000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x94000000, 0x14000000, PMB_SZ_64M  | PMB_C, },
-	{ 0x98000000, 0x18000000, PMB_SZ_64M  | PMB_C, },
-
-	/* P2 Section Mappings */
-	{ 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, },
-	{ 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-	{ 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M  | PMB_WT, },
-};
-
 static inline unsigned long mk_pmb_entry(unsigned int entry)
 {
 	return (entry & PMB_E_MASK) << PMB_E_SHIFT;
@@ -73,81 +53,68 @@ static inline unsigned long mk_pmb_data(
 	return mk_pmb_entry(entry) | PMB_DATA;
 }
 
-static DEFINE_SPINLOCK(pmb_list_lock);
-static struct pmb_entry *pmb_list;
-
-static inline void pmb_list_add(struct pmb_entry *pmbe)
+static int pmb_alloc_entry(void)
 {
-	struct pmb_entry **p, *tmp;
+	unsigned int pos;
 
-	p = &pmb_list;
-	while ((tmp = *p) != NULL)
-		p = &tmp->next;
+repeat:
+	pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
 
-	pmbe->next = tmp;
-	*p = pmbe;
-}
+	if (unlikely(pos > NR_PMB_ENTRIES))
+		return -ENOSPC;
 
-static inline void pmb_list_del(struct pmb_entry *pmbe)
-{
-	struct pmb_entry **p, *tmp;
+	if (test_and_set_bit(pos, &pmb_map))
+		goto repeat;
 
-	for (p = &pmb_list; (tmp = *p); p = &tmp->next)
-		if (tmp == pmbe) {
-			*p = tmp->next;
-			return;
-		}
+	return pos;
 }
 
-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
-			    unsigned long flags)
+static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
+				   unsigned long flags, int entry)
 {
 	struct pmb_entry *pmbe;
+	int pos;
 
-	pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL);
+	if (entry == PMB_NO_ENTRY) {
+		pos = pmb_alloc_entry();
+		if (pos < 0)
+			return ERR_PTR(pos);
+	} else {
+		if (test_bit(entry, &pmb_map))
+			return ERR_PTR(-ENOSPC);
+		pos = entry;
+	}
+
+	pmbe = &pmb_entry_list[pos];
 	if (!pmbe)
 		return ERR_PTR(-ENOMEM);
 
 	pmbe->vpn	= vpn;
 	pmbe->ppn	= ppn;
 	pmbe->flags	= flags;
-
-	spin_lock_irq(&pmb_list_lock);
-	pmb_list_add(pmbe);
-	spin_unlock_irq(&pmb_list_lock);
+	pmbe->entry	= pos;
 
 	return pmbe;
 }
 
-void pmb_free(struct pmb_entry *pmbe)
+static void pmb_free(struct pmb_entry *pmbe)
 {
-	spin_lock_irq(&pmb_list_lock);
-	pmb_list_del(pmbe);
-	spin_unlock_irq(&pmb_list_lock);
+	int pos = pmbe->entry;
 
-	kmem_cache_free(pmb_cache, pmbe);
+	pmbe->vpn	= 0;
+	pmbe->ppn	= 0;
+	pmbe->flags	= 0;
+	pmbe->entry	= 0;
+
+	clear_bit(pos, &pmb_map);
 }
 
 /*
  * Must be in P2 for __set_pmb_entry()
  */
-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
-		    unsigned long flags, int *entry)
+static void __set_pmb_entry(unsigned long vpn, unsigned long ppn,
+			    unsigned long flags, int pos)
 {
-	unsigned int pos = *entry;
-
-	if (unlikely(pos == PMB_NO_ENTRY))
-		pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
-
-repeat:
-	if (unlikely(pos > NR_PMB_ENTRIES))
-		return -ENOSPC;
-
-	if (test_and_set_bit(pos, &pmb_map)) {
-		pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
-		goto repeat;
-	}
-
 	ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
 
 #ifdef CONFIG_CACHE_WRITETHROUGH
@@ -161,35 +128,21 @@ repeat:
 #endif
 
 	ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));
-
-	*entry = pos;
-
-	return 0;
 }
 
-int __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
+static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe)
 {
-	int ret;
-
 	jump_to_uncached();
-	ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry);
+	__set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry);
 	back_to_cached();
-
-	return ret;
 }
 
-void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
+static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe)
 {
 	unsigned int entry = pmbe->entry;
 	unsigned long addr;
 
-	/*
-	 * Don't allow clearing of wired init entries, P1 or P2 access
-	 * without a corresponding mapping in the PMB will lead to reset
-	 * by the TLB.
-	 */
-	if (unlikely(entry < ARRAY_SIZE(pmb_init_map) ||
-		     entry >= NR_PMB_ENTRIES))
+	if (unlikely(entry >= NR_PMB_ENTRIES))
 		return;
 
 	jump_to_uncached();
@@ -202,8 +155,6 @@ void __uses_jump_to_uncached clear_pmb_e
 	ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
 
 	back_to_cached();
-
-	clear_bit(entry, &pmb_map);
 }
 
 
@@ -239,23 +190,17 @@ long pmb_remap(unsigned long vaddr, unsi
 
 again:
 	for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
-		int ret;
-
 		if (size < pmb_sizes[i].size)
 			continue;
 
-		pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
+		pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag,
+				 PMB_NO_ENTRY);
 		if (IS_ERR(pmbe)) {
 			err = PTR_ERR(pmbe);
 			goto out;
 		}
 
-		ret = set_pmb_entry(pmbe);
-		if (ret != 0) {
-			pmb_free(pmbe);
-			err = -EBUSY;
-			goto out;
-		}
+		set_pmb_entry(pmbe);
 
 		phys	+= pmb_sizes[i].size;
 		vaddr	+= pmb_sizes[i].size;
@@ -292,11 +237,16 @@ out:
 
 void pmb_unmap(unsigned long addr)
 {
-	struct pmb_entry **p, *pmbe;
+	struct pmb_entry *pmbe = NULL;
+	int i;
 
-	for (p = &pmb_list; (pmbe = *p); p = &pmbe->next)
-		if (pmbe->vpn == addr)
-			break;
+	for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+		if (test_bit(i, &pmb_map)) {
+			pmbe = &pmb_entry_list[i];
+			if (pmbe->vpn == addr)
+				break;
+		}
+	}
 
 	if (unlikely(!pmbe))
 		return;
@@ -306,13 +256,22 @@ void pmb_unmap(unsigned long addr)
 
 static void __pmb_unmap(struct pmb_entry *pmbe)
 {
-	WARN_ON(!test_bit(pmbe->entry, &pmb_map));
+	BUG_ON(!test_bit(pmbe->entry, &pmb_map));
 
 	do {
 		struct pmb_entry *pmblink = pmbe;
 
-		if (pmbe->entry != PMB_NO_ENTRY)
-			clear_pmb_entry(pmbe);
+		/*
+		 * We may be called before this pmb_entry has been
+		 * entered into the PMB table via set_pmb_entry(), but
+		 * that's OK because we've allocated a unique slot for
+		 * this entry in pmb_alloc() (even if we haven't filled
+		 * it yet).
+		 *
+		 * Therefore, calling clear_pmb_entry() is safe as no
+		 * other mapping can be using that slot.
+		 */
+		clear_pmb_entry(pmbe);
 
 		pmbe = pmblink->link;
 
@@ -320,42 +279,34 @@ static void __pmb_unmap(struct pmb_entry
 	} while (pmbe);
 }
 
-static void pmb_cache_ctor(void *pmb)
-{
-	struct pmb_entry *pmbe = pmb;
-
-	memset(pmb, 0, sizeof(struct pmb_entry));
-
-	pmbe->entry = PMB_NO_ENTRY;
-}
-
-static int __uses_jump_to_uncached pmb_init(void)
+#ifdef CONFIG_PMB
+int __uses_jump_to_uncached pmb_init(void)
 {
-	unsigned int nr_entries = ARRAY_SIZE(pmb_init_map);
-	unsigned int entry, i;
-
-	BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
-
-	pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
-				      SLAB_PANIC, pmb_cache_ctor);
+	unsigned int i;
+	long size, ret;
 
 	jump_to_uncached();
 
 	/*
-	 * Ordering is important, P2 must be mapped in the PMB before we
-	 * can set PMB.SE, and P1 must be mapped before we jump back to
-	 * P1 space.
+	 * Insert PMB entries for the P1 and P2 areas so that, after
+	 * we've switched the MMU to 32-bit mode, the semantics of P1
+	 * and P2 are the same as in 29-bit mode, e.g.
+	 *
+	 *	P1 - provides a cached window onto physical memory
+	 *	P2 - provides an uncached window onto physical memory
 	 */
-	for (entry = 0; entry < nr_entries; entry++) {
-		struct pmb_entry *pmbe = pmb_init_map + entry;
+	size = __MEMORY_START + __MEMORY_SIZE;
 
-		__set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry);
-	}
+	ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C);
+	BUG_ON(ret != size);
+
+	ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB);
+	BUG_ON(ret != size);
 
 	ctrl_outl(0, PMB_IRMCR);
 
 	/* PMB.SE and UB[7] */
-	ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR);
+	ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR);
 
 	/* Flush out the TLB */
 	i =  ctrl_inl(MMUCR);
@@ -366,7 +317,53 @@ static int __uses_jump_to_uncached pmb_i
 
 	return 0;
 }
-arch_initcall(pmb_init);
+#else
+int __uses_jump_to_uncached pmb_init(void)
+{
+	int i;
+	unsigned long addr, data;
+
+	jump_to_uncached();
+
+	for (i = 0; i < PMB_ENTRY_MAX; i++) {
+		struct pmb_entry *pmbe;
+		unsigned long vpn, ppn, flags;
+
+		addr = PMB_DATA + (i << PMB_E_SHIFT);
+		data = ctrl_inl(addr);
+		if (!(data & PMB_V))
+			continue;
+
+		if (data & PMB_C) {
+#if defined(CONFIG_CACHE_WRITETHROUGH)
+			data |= PMB_WT;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+			data &= ~PMB_WT;
+#else
+			data &= ~(PMB_C | PMB_WT);
+#endif
+		}
+		ctrl_outl(data, addr);
+
+		ppn = data & PMB_PFN_MASK;
+
+		flags = data & (PMB_C | PMB_WT | PMB_UB);
+		flags |= data & PMB_SZ_MASK;
+
+		addr = PMB_ADDR + (i << PMB_E_SHIFT);
+		data = ctrl_inl(addr);
+
+		vpn = data & PMB_PFN_MASK;
+
+		pmbe = pmb_alloc(vpn, ppn, flags, i);
+		WARN_ON(IS_ERR(pmbe));
+	}
+
+	back_to_cached();
+
+	return 0;
+}
+#endif /* CONFIG_PMB */
 
 static int pmb_seq_show(struct seq_file *file, void *iter)
 {
@@ -434,15 +431,18 @@ postcore_initcall(pmb_debugfs_init);
 static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
 {
 	static pm_message_t prev_state;
+	int i;
 
 	/* Restore the PMB after a resume from hibernation */
 	if (state.event == PM_EVENT_ON &&
 	    prev_state.event == PM_EVENT_FREEZE) {
 		struct pmb_entry *pmbe;
-		spin_lock_irq(&pmb_list_lock);
-		for (pmbe = pmb_list; pmbe; pmbe = pmbe->next)
-			set_pmb_entry(pmbe);
-		spin_unlock_irq(&pmb_list_lock);
+		for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+			if (test_bit(i, &pmb_map)) {
+				pmbe = &pmb_entry_list[i];
+				set_pmb_entry(pmbe);
+			}
+		}
 	}
 	prev_state = state;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/mm/pmb-fixed.c linux-libre-2.6.33-gnu1/arch/sh/mm/pmb-fixed.c
--- linux-libre-2.6.32-gnu1/arch/sh/mm/pmb-fixed.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/mm/pmb-fixed.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- * arch/sh/mm/fixed_pmb.c
- *
- * Copyright (C) 2009  Renesas Solutions Corp.
- *
- * 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/mm.h>
-#include <linux/io.h>
-#include <asm/mmu.h>
-#include <asm/mmu_context.h>
-
-static int __uses_jump_to_uncached fixed_pmb_init(void)
-{
-	int i;
-	unsigned long addr, data;
-
-	jump_to_uncached();
-
-	for (i = 0; i < PMB_ENTRY_MAX; i++) {
-		addr = PMB_DATA + (i << PMB_E_SHIFT);
-		data = ctrl_inl(addr);
-		if (!(data & PMB_V))
-			continue;
-
-		if (data & PMB_C) {
-#if defined(CONFIG_CACHE_WRITETHROUGH)
-			data |= PMB_WT;
-#elif defined(CONFIG_CACHE_WRITEBACK)
-			data &= ~PMB_WT;
-#else
-			data &= ~(PMB_C | PMB_WT);
-#endif
-		}
-		ctrl_outl(data, addr);
-	}
-
-	back_to_cached();
-
-	return 0;
-}
-arch_initcall(fixed_pmb_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/oprofile/common.c linux-libre-2.6.33-gnu1/arch/sh/oprofile/common.c
--- linux-libre-2.6.32-gnu1/arch/sh/oprofile/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/oprofile/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,9 +20,6 @@
 #include <asm/processor.h>
 #include "op_impl.h"
 
-extern struct op_sh_model op_model_sh7750_ops __weak;
-extern struct op_sh_model op_model_sh4a_ops __weak;
-
 static struct op_sh_model *model;
 
 static struct op_counter_config ctr[20];
@@ -94,33 +91,14 @@ int __init oprofile_arch_init(struct opr
 	 */
 	ops->backtrace = sh_backtrace;
 
-	switch (current_cpu_data.type) {
-	/* SH-4 types */
-	case CPU_SH7750:
-	case CPU_SH7750S:
-		lmodel = &op_model_sh7750_ops;
-		break;
-
-        /* SH-4A types */
-	case CPU_SH7763:
-	case CPU_SH7770:
-	case CPU_SH7780:
-	case CPU_SH7781:
-	case CPU_SH7785:
-	case CPU_SH7786:
-	case CPU_SH7723:
-	case CPU_SH7724:
-	case CPU_SHX3:
-		lmodel = &op_model_sh4a_ops;
-		break;
-
-	/* SH4AL-DSP types */
-	case CPU_SH7343:
-	case CPU_SH7722:
-	case CPU_SH7366:
-		lmodel = &op_model_sh4a_ops;
-		break;
-	}
+	/*
+	 * XXX
+	 *
+	 * All of the SH7750/SH-4A counters have been converted to perf,
+	 * this infrastructure hook is left for other users until they've
+	 * had a chance to convert over, at which point all of this
+	 * will be deleted.
+	 */
 
 	if (!lmodel)
 		return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/oprofile/Makefile linux-libre-2.6.33-gnu1/arch/sh/oprofile/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/oprofile/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/oprofile/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,3 @@ DRIVER_OBJS = $(addprefix ../../../drive
 		timer_int.o )
 
 oprofile-y	:= $(DRIVER_OBJS) common.o backtrace.o
-
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7750S)	+= op_model_sh7750.o
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7750)	+= op_model_sh7750.o
-oprofile-$(CONFIG_CPU_SUBTYPE_SH7091)	+= op_model_sh7750.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/oprofile/op_impl.h linux-libre-2.6.33-gnu1/arch/sh/oprofile/op_impl.h
--- linux-libre-2.6.32-gnu1/arch/sh/oprofile/op_impl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/oprofile/op_impl.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@ struct op_counter_config {
 	unsigned long enabled;
 	unsigned long event;
 
-	unsigned long long count;
+	unsigned long count;
 
 	/* Dummy values for userspace tool compliance */
 	unsigned long kernel;
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/oprofile/op_model_sh7750.c linux-libre-2.6.33-gnu1/arch/sh/oprofile/op_model_sh7750.c
--- linux-libre-2.6.32-gnu1/arch/sh/oprofile/op_model_sh7750.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/oprofile/op_model_sh7750.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,255 +0,0 @@
-/*
- * arch/sh/oprofile/op_model_sh7750.c
- *
- * OProfile support for SH7750/SH7750S Performance Counters
- *
- * Copyright (C) 2003 - 2008  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/kernel.h>
-#include <linux/oprofile.h>
-#include <linux/profile.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/fs.h>
-#include "op_impl.h"
-
-#define PM_CR_BASE	0xff000084	/* 16-bit */
-#define PM_CTR_BASE	0xff100004	/* 32-bit */
-
-#define PMCR(n)		(PM_CR_BASE + ((n) * 0x04))
-#define PMCTRH(n)	(PM_CTR_BASE + 0x00 + ((n) * 0x08))
-#define PMCTRL(n)	(PM_CTR_BASE + 0x04 + ((n) * 0x08))
-
-#define PMCR_PMM_MASK	0x0000003f
-
-#define PMCR_CLKF	0x00000100
-#define PMCR_PMCLR	0x00002000
-#define PMCR_PMST	0x00004000
-#define PMCR_PMEN	0x00008000
-
-struct op_sh_model op_model_sh7750_ops;
-
-#define NR_CNTRS	2
-
-static struct sh7750_ppc_register_config {
-	unsigned int ctrl;
-	unsigned long cnt_hi;
-	unsigned long cnt_lo;
-} regcache[NR_CNTRS];
-
-/*
- * There are a number of events supported by each counter (33 in total).
- * Since we have 2 counters, each counter will take the event code as it
- * corresponds to the PMCR PMM setting. Each counter can be configured
- * independently.
- *
- *	Event Code	Description
- *	----------	-----------
- *
- *	0x01		Operand read access
- *	0x02		Operand write access
- *	0x03		UTLB miss
- *	0x04		Operand cache read miss
- *	0x05		Operand cache write miss
- *	0x06		Instruction fetch (w/ cache)
- *	0x07		Instruction TLB miss
- *	0x08		Instruction cache miss
- *	0x09		All operand accesses
- *	0x0a		All instruction accesses
- *	0x0b		OC RAM operand access
- *	0x0d		On-chip I/O space access
- *	0x0e		Operand access (r/w)
- *	0x0f		Operand cache miss (r/w)
- *	0x10		Branch instruction
- *	0x11		Branch taken
- *	0x12		BSR/BSRF/JSR
- *	0x13		Instruction execution
- *	0x14		Instruction execution in parallel
- *	0x15		FPU Instruction execution
- *	0x16		Interrupt
- *	0x17		NMI
- *	0x18		trapa instruction execution
- *	0x19		UBCA match
- *	0x1a		UBCB match
- *	0x21		Instruction cache fill
- *	0x22		Operand cache fill
- *	0x23		Elapsed time
- *	0x24		Pipeline freeze by I-cache miss
- *	0x25		Pipeline freeze by D-cache miss
- *	0x27		Pipeline freeze by branch instruction
- *	0x28		Pipeline freeze by CPU register
- *	0x29		Pipeline freeze by FPU
- *
- * Unfortunately we don't have a native exception or interrupt for counter
- * overflow (although since these counters can run for 16.3 days without
- * overflowing, it's not really necessary).
- *
- * OProfile on the other hand likes to have samples taken periodically, so
- * for now we just piggyback the timer interrupt to get the expected
- * behavior.
- */
-
-static int sh7750_timer_notify(struct pt_regs *regs)
-{
-	oprofile_add_sample(regs, 0);
-	return 0;
-}
-
-static u64 sh7750_read_counter(int counter)
-{
-	return (u64)((u64)(__raw_readl(PMCTRH(counter)) & 0xffff) << 32) |
-			   __raw_readl(PMCTRL(counter));
-}
-
-/*
- * Files will be in a path like:
- *
- *  /<oprofilefs mount point>/<counter number>/<file>
- *
- * So when dealing with <file>, we look to the parent dentry for the counter
- * number.
- */
-static inline int to_counter(struct file *file)
-{
-	const unsigned char *name = file->f_path.dentry->d_parent->d_name.name;
-
-	return (int)simple_strtol(name, NULL, 10);
-}
-
-/*
- * XXX: We have 48-bit counters, so we're probably going to want something
- * more along the lines of oprofilefs_ullong_to_user().. Truncating to
- * unsigned long works fine for now though, as long as we don't attempt to
- * profile for too horribly long.
- */
-static ssize_t sh7750_read_count(struct file *file, char __user *buf,
-				 size_t count, loff_t *ppos)
-{
-	int counter = to_counter(file);
-	u64 val = sh7750_read_counter(counter);
-
-	return oprofilefs_ulong_to_user((unsigned long)val, buf, count, ppos);
-}
-
-static ssize_t sh7750_write_count(struct file *file, const char __user *buf,
-				  size_t count, loff_t *ppos)
-{
-	int counter = to_counter(file);
-	unsigned long val;
-
-	if (oprofilefs_ulong_from_user(&val, buf, count))
-		return -EFAULT;
-
-	/*
-	 * Any write will clear the counter, although only 0 should be
-	 * written for this purpose, as we do not support setting the
-	 * counter to an arbitrary value.
-	 */
-	WARN_ON(val != 0);
-
-	__raw_writew(__raw_readw(PMCR(counter)) | PMCR_PMCLR, PMCR(counter));
-
-	return count;
-}
-
-static const struct file_operations count_fops = {
-	.read		= sh7750_read_count,
-	.write		= sh7750_write_count,
-};
-
-static int sh7750_ppc_create_files(struct super_block *sb, struct dentry *dir)
-{
-	return oprofilefs_create_file(sb, dir, "count", &count_fops);
-}
-
-static void sh7750_ppc_reg_setup(struct op_counter_config *ctr)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++) {
-		regcache[i].ctrl	= 0;
-		regcache[i].cnt_hi	= 0;
-		regcache[i].cnt_lo	= 0;
-
-		if (!ctr[i].enabled)
-			continue;
-
-		regcache[i].ctrl |= ctr[i].event | PMCR_PMEN | PMCR_PMST;
-		regcache[i].cnt_hi = (unsigned long)((ctr->count >> 32) & 0xffff);
-		regcache[i].cnt_lo = (unsigned long)(ctr->count & 0xffffffff);
-	}
-}
-
-static void sh7750_ppc_cpu_setup(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++) {
-		__raw_writew(0, PMCR(i));
-		__raw_writel(regcache[i].cnt_hi, PMCTRH(i));
-		__raw_writel(regcache[i].cnt_lo, PMCTRL(i));
-	}
-}
-
-static void sh7750_ppc_cpu_start(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	for (i = 0; i < counters; i++)
-		__raw_writew(regcache[i].ctrl, PMCR(i));
-}
-
-static void sh7750_ppc_cpu_stop(void *args)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	/* Disable the counters */
-	for (i = 0; i < counters; i++)
-		__raw_writew(__raw_readw(PMCR(i)) & ~PMCR_PMEN, PMCR(i));
-}
-
-static inline void sh7750_ppc_reset(void)
-{
-	unsigned int counters = op_model_sh7750_ops.num_counters;
-	int i;
-
-	/* Clear the counters */
-	for (i = 0; i < counters; i++)
-		__raw_writew(__raw_readw(PMCR(i)) | PMCR_PMCLR, PMCR(i));
-}
-
-static int sh7750_ppc_init(void)
-{
-	sh7750_ppc_reset();
-
-	return register_timer_hook(sh7750_timer_notify);
-}
-
-static void sh7750_ppc_exit(void)
-{
-	unregister_timer_hook(sh7750_timer_notify);
-
-	sh7750_ppc_reset();
-}
-
-struct op_sh_model op_model_sh7750_ops = {
-	.cpu_type	= "sh/sh7750",
-	.num_counters	= NR_CNTRS,
-	.reg_setup	= sh7750_ppc_reg_setup,
-	.cpu_setup	= sh7750_ppc_cpu_setup,
-	.cpu_start	= sh7750_ppc_cpu_start,
-	.cpu_stop	= sh7750_ppc_cpu_stop,
-	.init		= sh7750_ppc_init,
-	.exit		= sh7750_ppc_exit,
-	.create_files	= sh7750_ppc_create_files,
-};
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/tools/gen-mach-types linux-libre-2.6.33-gnu1/arch/sh/tools/gen-mach-types
--- linux-libre-2.6.32-gnu1/arch/sh/tools/gen-mach-types	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/tools/gen-mach-types	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 #!/bin/awk
 #
-# Awk script to generate include/asm-sh/machtypes.h
+# Awk script to generate include/generated/machtypes.h
 # Heavily based on arch/arm/tools/gen-mach-types
 #
 BEGIN	{ nr = 0 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sh/tools/Makefile linux-libre-2.6.33-gnu1/arch/sh/tools/Makefile
--- linux-libre-2.6.32-gnu1/arch/sh/tools/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sh/tools/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
 # Shamelessly cloned from ARM.
 #
 
-include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
+include/generated/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
 	@echo '  Generating $@'
-	$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
-	$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
+	$(Q)mkdir -p $(dir $@)
+	$(Q)LC_ALL=C $(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/configs/sparc32_defconfig linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc32_defconfig
--- linux-libre-2.6.32-gnu1/arch/sparc/configs/sparc32_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc32_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Wed Sep 16 00:03:43 2009
+# Linux kernel version: 2.6.33-rc2
+# Mon Jan 11 23:20:31 2010
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -41,6 +41,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -88,21 +89,21 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
@@ -131,14 +132,41 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -168,8 +196,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SUN_PM=y
 # CONFIG_SPARC_LED is not set
@@ -257,6 +284,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -295,9 +323,6 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -335,6 +360,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
@@ -398,8 +427,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -434,7 +466,9 @@ CONFIG_SCSI_QLOGICPTI=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_SUNESP=y
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -450,7 +484,7 @@ CONFIG_SCSI_SUNESP=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -487,6 +521,7 @@ CONFIG_SUNQE=m
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
@@ -546,6 +581,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -555,6 +591,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -574,6 +611,7 @@ CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=m
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_KEYBOARD_SUNKBD=m
 # CONFIG_KEYBOARD_XTKBD is not set
@@ -604,6 +642,7 @@ CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -636,6 +675,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_CONSOLE_POLL=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -661,6 +701,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
@@ -675,9 +720,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -699,6 +742,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
@@ -776,7 +820,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -955,6 +1001,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1003,9 +1050,9 @@ CONFIG_KGDB=y
 CONFIG_KGDB_SERIAL_CONSOLE=y
 CONFIG_KGDB_TESTS=y
 # CONFIG_KGDB_TESTS_ON_BOOT is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 #
 # Security options
@@ -1013,7 +1060,11 @@ CONFIG_KGDB_TESTS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/configs/sparc64_defconfig linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc64_defconfig
--- linux-libre-2.6.32-gnu1/arch/sparc/configs/sparc64_defconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/configs/sparc64_defconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31
-# Tue Sep 15 17:06:03 2009
+# Linux kernel version: 2.6.33-rc2
+# Wed Jan 20 16:31:47 2010
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -20,6 +20,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -50,6 +51,7 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 CONFIG_TREE_RCU=y
 # CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
@@ -62,8 +64,7 @@ CONFIG_RT_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
@@ -97,24 +98,25 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
-CONFIG_PERF_COUNTERS=y
+CONFIG_PERF_EVENTS=y
 CONFIG_EVENT_PROFILE=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
@@ -152,14 +154,41 @@ CONFIG_BLOCK_COMPAT=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 # CONFIG_FREEZER is not set
 
 #
@@ -179,6 +208,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_SPARC64_SMP=y
+CONFIG_EARLYFB=y
 CONFIG_SPARC64_PAGE_SIZE_8KB=y
 # CONFIG_SPARC64_PAGE_SIZE_64KB is not set
 CONFIG_SECCOMP=y
@@ -216,8 +246,7 @@ CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=1
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=8192
 CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
@@ -315,6 +344,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -356,9 +386,6 @@ CONFIG_NET_TCPPROBE=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 
 #
@@ -376,6 +403,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
@@ -397,6 +425,11 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_DRBD is not set
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
@@ -408,6 +441,7 @@ CONFIG_ATA_OVER_ETH=m
 CONFIG_SUNVDC=m
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
@@ -415,6 +449,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -522,8 +557,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -557,7 +595,9 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SUNESP is not set
 # CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
@@ -568,7 +608,9 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=m
+# CONFIG_MULTICORE_RAID456 is not set
 CONFIG_MD_RAID6_PQ=m
+# CONFIG_ASYNC_RAID6_TEST is not set
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -592,7 +634,7 @@ CONFIG_DM_ZERO=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -664,6 +706,7 @@ CONFIG_NET_PCI=y
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_SC92031 is not set
 # CONFIG_ATL2 is not set
@@ -745,6 +788,7 @@ CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -754,6 +798,7 @@ CONFIG_SLHC=m
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -770,9 +815,13 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
 CONFIG_KEYBOARD_LKKBD=m
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_KEYBOARD_SUNKBD=y
 # CONFIG_KEYBOARD_XTKBD is not set
@@ -812,6 +861,7 @@ CONFIG_SERIO_I8042=y
 CONFIG_SERIO_PCIPS2=m
 CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -844,6 +894,7 @@ CONFIG_SERIAL_SUNHV=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -858,6 +909,7 @@ CONFIG_HW_RANDOM_N2RNG=m
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=y
@@ -898,11 +950,6 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_TINY_USB is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
@@ -911,10 +958,6 @@ CONFIG_I2C_ALGOBIT=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -932,6 +975,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -955,6 +1003,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
 # CONFIG_SENSORS_LM78 is not set
@@ -981,6 +1030,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -993,9 +1043,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_ULTRA45 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -1013,16 +1062,20 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1176,6 +1229,7 @@ CONFIG_SND_ALI5451=m
 # CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_CTXFI is not set
 # CONFIG_SND_DARLA20 is not set
 # CONFIG_SND_GINA20 is not set
@@ -1311,6 +1365,7 @@ CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1426,6 +1481,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
@@ -1447,7 +1503,9 @@ CONFIG_RTC_DRV_CMOS=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_MSM6242 is not set
 CONFIG_RTC_DRV_BQ4802=y
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1625,6 +1683,7 @@ CONFIG_PRINTK_TIME=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1678,9 +1737,11 @@ CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
 CONFIG_EVENT_TRACING=y
 CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
 CONFIG_TRACING=y
 CONFIG_GENERIC_TRACER=y
 CONFIG_TRACING_SUPPORT=y
@@ -1688,6 +1749,7 @@ CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
+# CONFIG_FTRACE_SYSCALLS is not set
 # CONFIG_BOOT_TRACER is not set
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
@@ -1706,6 +1768,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 #
 # Security options
@@ -1714,11 +1777,17 @@ CONFIG_KEYS=y
 # CONFIG_KEYS_DEBUG_PROC_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_XOR_BLOCKS=m
 CONFIG_ASYNC_CORE=m
 CONFIG_ASYNC_MEMCPY=m
 CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
 CONFIG_CRYPTO=y
 
 #
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/btext.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/btext.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/btext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/btext.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6 @@
+#ifndef _SPARC_BTEXT_H
+#define _SPARC_BTEXT_H
+
+extern int btext_find_display(void);
+
+#endif /* _SPARC_BTEXT_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/cacheflush_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cacheflush_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/cacheflush_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cacheflush_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -75,6 +75,7 @@ BTFIXUPDEF_CALL(void, flush_sig_insns, s
 
 extern void sparc_flush_page_to_ram(struct page *page);
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)			sparc_flush_page_to_ram(page)
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/cacheflush_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cacheflush_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/cacheflush_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/cacheflush_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,7 @@ extern void flush_dcache_page_all(struct
 #endif
 
 extern void __flush_dcache_range(unsigned long start, unsigned long end);
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
 
 #define flush_icache_page(vma, pg)	do { } while(0)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/elf_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/elf_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/elf_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/elf_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -104,8 +104,6 @@ typedef struct {
 #define ELF_CLASS	ELFCLASS32
 #define ELF_DATA	ELFDATA2MSB
 
-#define USE_ELF_CORE_DUMP
-
 #define ELF_EXEC_PAGESIZE	4096
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/elf_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/elf_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/elf_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/elf_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -152,7 +152,6 @@ typedef struct {
 					 (x)->e_machine == EM_SPARC32PLUS)
 #define compat_start_thread		start_thread32
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
@@ -196,17 +195,10 @@ static inline unsigned int sparc64_elf_h
 #define ELF_PLATFORM	(NULL)
 
 #define SET_PERSONALITY(ex)				\
-do {	unsigned long new_flags = current_thread_info()->flags; \
-	new_flags &= _TIF_32BIT;			\
-	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\
-		new_flags |= _TIF_32BIT;		\
-	else						\
-		new_flags &= ~_TIF_32BIT;		\
-	if ((current_thread_info()->flags & _TIF_32BIT) \
-	    != new_flags)				\
-		set_thread_flag(TIF_ABI_PENDING);	\
+do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\
+		set_thread_flag(TIF_32BIT);		\
 	else						\
-		clear_thread_flag(TIF_ABI_PENDING);	\
+		clear_thread_flag(TIF_32BIT);		\
 	/* flush_thread will update pgd cache */	\
 	if (personality(current->personality) != PER_LINUX32)	\
 		set_personality(PER_LINUX |		\
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/fcntl.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/fcntl.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/fcntl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/fcntl.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,14 +1,12 @@
 #ifndef _SPARC_FCNTL_H
 #define _SPARC_FCNTL_H
 
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
 #define O_APPEND	0x0008
 #define FASYNC		0x0040	/* fcntl, for BSD compatibility */
 #define O_CREAT		0x0200	/* not fcntl */
 #define O_TRUNC		0x0400	/* not fcntl */
 #define O_EXCL		0x0800	/* not fcntl */
-#define O_SYNC		0x2000
+#define O_DSYNC		0x2000	/* used to be O_SYNC, see below */
 #define O_NONBLOCK	0x4000
 #if defined(__sparc__) && defined(__arch64__)
 #define O_NDELAY	0x0004
@@ -20,6 +18,21 @@
 #define O_DIRECT        0x100000 /* direct disk access hint */
 #define O_NOATIME	0x200000
 #define O_CLOEXEC	0x400000
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag.  We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics.  It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC	0x800000
+#define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/io_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/io_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/io_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
 #include <asm/page.h>      /* IO address mapping routines need this */
 #include <asm/system.h>
 
-#define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT)
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
 static inline u32 flip_dword (u32 l)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/leon.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/leon.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/leon.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/leon.h	2010-02-24 13:52:17.000000000 -0500
@@ -148,7 +148,7 @@ static inline unsigned long leon_load_re
 	return retval;
 }
 
-extern inline void leon_srmmu_disabletlb(void)
+static inline void leon_srmmu_disabletlb(void)
 {
 	unsigned int retval;
 	__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
@@ -158,7 +158,7 @@ extern inline void leon_srmmu_disabletlb
 			     "i"(ASI_LEON_MMUREGS) : "memory");
 }
 
-extern inline void leon_srmmu_enabletlb(void)
+static inline void leon_srmmu_enabletlb(void)
 {
 	unsigned int retval;
 	__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
@@ -190,7 +190,7 @@ extern void leon_init_IRQ(void);
 
 extern unsigned long last_valid_pfn;
 
-extern inline unsigned long sparc_leon3_get_dcachecfg(void)
+static inline unsigned long sparc_leon3_get_dcachecfg(void)
 {
 	unsigned int retval;
 	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
@@ -201,7 +201,7 @@ extern inline unsigned long sparc_leon3_
 }
 
 /* enable snooping */
-extern inline void sparc_leon3_enable_snooping(void)
+static inline void sparc_leon3_enable_snooping(void)
 {
 	__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
 			  "set 0x800000, %%l2\n\t"
@@ -209,7 +209,14 @@ extern inline void sparc_leon3_enable_sn
 			  "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
 };
 
-extern inline void sparc_leon3_disable_cache(void)
+static inline int sparc_leon3_snooping_enabled(void)
+{
+	u32 cctrl;
+	__asm__ __volatile__("lda [%%g0] 2, %0\n\t" : "=r"(cctrl));
+        return (cctrl >> 23) & 1;
+};
+
+static inline void sparc_leon3_disable_cache(void)
 {
 	__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
 			  "set 0x00000f, %%l2\n\t"
@@ -340,6 +347,30 @@ extern int leon_flush_needed(void);
 extern void leon_switch_mm(void);
 extern int srmmu_swprobe_trace;
 
+#ifdef CONFIG_SMP
+extern int leon_smp_nrcpus(void);
+extern void leon_clear_profile_irq(int cpu);
+extern void leon_smp_done(void);
+extern void leon_boot_cpus(void);
+extern int leon_boot_one_cpu(int i);
+void leon_init_smp(void);
+extern void cpu_probe(void);
+extern void cpu_idle(void);
+extern void init_IRQ(void);
+extern void cpu_panic(void);
+extern int __leon_processor_id(void);
+void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
+
+extern unsigned int real_irq_entry[], smpleon_ticker[];
+extern unsigned int patchme_maybe_smp_msg[];
+extern unsigned long trapbase_cpu1[];
+extern unsigned long trapbase_cpu2[];
+extern unsigned long trapbase_cpu3[];
+extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
+extern unsigned int linux_trap_ipi15_sun4m[];
+
+#endif /* CONFIG_SMP */
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
@@ -356,6 +387,10 @@ extern int srmmu_swprobe_trace;
 #define leon_switch_mm() do {} while (0)
 #define leon_init_IRQ() do {} while (0)
 #define init_leon() do {} while (0)
+#define leon_smp_done() do {} while (0)
+#define leon_boot_cpus() do {} while (0)
+#define leon_boot_one_cpu(i) 1
+#define leon_init_smp() do {} while (0)
 
 #endif /* !defined(CONFIG_SPARC_LEON) */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/page_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/page_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/page_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/page_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -143,7 +143,7 @@ extern unsigned long pfn_base;
 #define phys_to_virt		__va
 
 #define ARCH_PFN_OFFSET		(pfn_base)
-#define virt_to_page(kaddr)	(mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 #define pfn_valid(pfn)		(((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
 #define virt_addr_valid(kaddr)	((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/param.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/param.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/param.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/param.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,22 +1,7 @@
 #ifndef _ASMSPARC_PARAM_H
 #define _ASMSPARC_PARAM_H
 
-#ifdef __KERNEL__
-# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
-# define USER_HZ	100	/* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ)
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
 #define EXEC_PAGESIZE	8192    /* Thanks for sun4's we carry baggage... */
+#include <asm-generic/param.h>
 
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#endif
+#endif /* _ASMSPARC_PARAM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/pci_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/pci_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/pci_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,8 +16,6 @@
 
 #define PCI_IRQ_NONE		0xffffffff
 
-#define PCI_CACHE_LINE_BYTES	64
-
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
 	/* No special bus mastering setup handling */
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/prom.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/prom.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/prom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/prom.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,4 @@
+#include <linux/of.h>	/* linux/of.h gets to determine #include ordering */
 #ifndef _SPARC_PROM_H
 #define _SPARC_PROM_H
 #ifdef __KERNEL__
@@ -28,50 +29,11 @@
 #define of_prop_cmp(s1, s2)		strcasecmp((s1), (s2))
 #define of_node_cmp(s1, s2)		strcmp((s1), (s2))
 
-typedef u32 phandle;
-typedef u32 ihandle;
-
-struct property {
-	char	*name;
-	int	length;
-	void	*value;
-	struct property *next;
-	unsigned long _flags;
-	unsigned int unique_id;
-};
-
-struct of_irq_controller;
-struct device_node {
-	const char	*name;
-	const char	*type;
-	phandle	node;
-	char	*path_component_name;
-	char	*full_name;
-
-	struct	property *properties;
-	struct  property *deadprops; /* removed properties */
-	struct	device_node *parent;
-	struct	device_node *child;
-	struct	device_node *sibling;
-	struct	device_node *next;	/* next device of same type */
-	struct	device_node *allnext;	/* next in list of all nodes */
-	struct  proc_dir_entry *pde;	/* this node's proc directory */
-	struct  kref kref;
-	unsigned long _flags;
-	void	*data;
-	unsigned int unique_id;
-
-	struct of_irq_controller *irq_trans;
-};
-
 struct of_irq_controller {
 	unsigned int	(*irq_build)(struct device_node *, unsigned int, void *);
 	void		*data;
 };
 
-#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
-#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
-
 extern struct device_node *of_find_node_by_cpuid(int cpuid);
 extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
 extern struct mutex of_set_property_mutex;
@@ -89,15 +51,6 @@ extern void prom_build_devicetree(void);
 extern void of_populate_present_mask(void);
 extern void of_fill_in_cpu_data(void);
 
-/* Dummy ref counting routines - to be implemented later */
-static inline struct device_node *of_node_get(struct device_node *node)
-{
-	return node;
-}
-static inline void of_node_put(struct device_node *node)
-{
-}
-
 /* These routines are here to provide compatibility with how powerpc
  * handles IRQ mapping for OF device nodes.  We precompute and permanently
  * register them in the of_device objects, whereas powerpc computes them
@@ -108,12 +61,6 @@ static inline void irq_dispose_mapping(u
 {
 }
 
-/*
- * NB:  This is here while we transition from using asm/prom.h
- * to linux/of.h
- */
-#include <linux/of.h>
-
 extern struct device_node *of_console_device;
 extern char *of_console_path;
 extern char *of_console_options;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/rwsem.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/rwsem.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/rwsem.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/rwsem.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,8 +35,8 @@ struct rw_semaphore {
 #endif
 
 #define __RWSEM_INITIALIZER(name) \
-{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
-  __RWSEM_DEP_MAP_INIT(name) }
+{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
+  LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
 
 #define DECLARE_RWSEM(name) \
 	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/smp_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/smp_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/smp_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/smp_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,6 +106,15 @@ static inline int hard_smp4d_processor_i
 	return cpuid;
 }
 
+extern inline int hard_smpleon_processor_id(void)
+{
+	int cpuid;
+	__asm__ __volatile__("rd     %%asr17,%0\n\t"
+			     "srl    %0,28,%0" :
+			     "=&r" (cpuid) : );
+	return cpuid;
+}
+
 #ifndef MODULE
 static inline int hard_smp_processor_id(void)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,8 @@
 #define SO_TIMESTAMPING		0x0023
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_RXQ_OVFL             0x0024
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT	0x5002
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,12 +10,12 @@
 
 #include <asm/psr.h>
 
-#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
+#define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
 
-#define __raw_spin_unlock_wait(lock) \
-	do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#define arch_spin_unlock_wait(lock) \
+	do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	__asm__ __volatile__(
 	"\n1:\n\t"
@@ -35,7 +35,7 @@ static inline void __raw_spin_lock(raw_s
 	: "g2", "memory", "cc");
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned int result;
 	__asm__ __volatile__("ldstub [%1], %0"
@@ -45,7 +45,7 @@ static inline int __raw_spin_trylock(raw
 	return (result == 0);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
 }
@@ -65,7 +65,7 @@ static inline void __raw_spin_unlock(raw
  * Sort of like atomic_t's on Sparc, but even more clever.
  *
  *	------------------------------------
- *	| 24-bit counter           | wlock |  raw_rwlock_t
+ *	| 24-bit counter           | wlock |  arch_rwlock_t
  *	------------------------------------
  *	 31                       8 7     0
  *
@@ -76,9 +76,9 @@ static inline void __raw_spin_unlock(raw
  *
  * Unfortunately this scheme limits us to ~16,000,000 cpus.
  */
-static inline void arch_read_lock(raw_rwlock_t *rw)
+static inline void __arch_read_lock(arch_rwlock_t *rw)
 {
-	register raw_rwlock_t *lp asm("g1");
+	register arch_rwlock_t *lp asm("g1");
 	lp = rw;
 	__asm__ __volatile__(
 	"mov	%%o7, %%g4\n\t"
@@ -89,16 +89,16 @@ static inline void arch_read_lock(raw_rw
 	: "g2", "g4", "memory", "cc");
 }
 
-#define __raw_read_lock(lock) \
+#define arch_read_lock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
-	arch_read_lock(lock); \
+	__arch_read_lock(lock); \
 	local_irq_restore(flags); \
 } while(0)
 
-static inline void arch_read_unlock(raw_rwlock_t *rw)
+static inline void __arch_read_unlock(arch_rwlock_t *rw)
 {
-	register raw_rwlock_t *lp asm("g1");
+	register arch_rwlock_t *lp asm("g1");
 	lp = rw;
 	__asm__ __volatile__(
 	"mov	%%o7, %%g4\n\t"
@@ -109,16 +109,16 @@ static inline void arch_read_unlock(raw_
 	: "g2", "g4", "memory", "cc");
 }
 
-#define __raw_read_unlock(lock) \
+#define arch_read_unlock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
-	arch_read_unlock(lock); \
+	__arch_read_unlock(lock); \
 	local_irq_restore(flags); \
 } while(0)
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
-	register raw_rwlock_t *lp asm("g1");
+	register arch_rwlock_t *lp asm("g1");
 	lp = rw;
 	__asm__ __volatile__(
 	"mov	%%o7, %%g4\n\t"
@@ -130,7 +130,7 @@ static inline void __raw_write_lock(raw_
 	*(volatile __u32 *)&lp->lock = ~0U;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned int val;
 
@@ -150,9 +150,9 @@ static inline int __raw_write_trylock(ra
 	return (val == 0);
 }
 
-static inline int arch_read_trylock(raw_rwlock_t *rw)
+static inline int __arch_read_trylock(arch_rwlock_t *rw)
 {
-	register raw_rwlock_t *lp asm("g1");
+	register arch_rwlock_t *lp asm("g1");
 	register int res asm("o0");
 	lp = rw;
 	__asm__ __volatile__(
@@ -165,27 +165,27 @@ static inline int arch_read_trylock(raw_
 	return res;
 }
 
-#define __raw_read_trylock(lock) \
+#define arch_read_trylock(lock) \
 ({	unsigned long flags; \
 	int res; \
 	local_irq_save(flags); \
-	res = arch_read_trylock(lock); \
+	res = __arch_read_trylock(lock); \
 	local_irq_restore(flags); \
 	res; \
 })
 
-#define __raw_write_unlock(rw)	do { (rw)->lock = 0; } while(0)
+#define arch_write_unlock(rw)	do { (rw)->lock = 0; } while(0)
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_read_lock_flags(rw, flags)   __raw_read_lock(rw)
-#define __raw_write_lock_flags(rw, flags)  __raw_write_lock(rw)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_read_lock_flags(rw, flags)   arch_read_lock(rw)
+#define arch_write_lock_flags(rw, flags)  arch_write_lock(rw)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
-#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff))
-#define __raw_write_can_lock(rw) (!(rw)->lock)
+#define arch_read_can_lock(rw) (!((rw)->lock & 0xff))
+#define arch_write_can_lock(rw) (!(rw)->lock)
 
 #endif /* !(__ASSEMBLY__) */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,13 +21,13 @@
  * the spinner sections must be pre-V9 branches.
  */
 
-#define __raw_spin_is_locked(lp)	((lp)->lock != 0)
+#define arch_spin_is_locked(lp)	((lp)->lock != 0)
 
-#define __raw_spin_unlock_wait(lp)	\
+#define arch_spin_unlock_wait(lp)	\
 	do {	rmb();			\
 	} while((lp)->lock)
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -46,7 +46,7 @@ static inline void __raw_spin_lock(raw_s
 	: "memory");
 }
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned long result;
 
@@ -59,7 +59,7 @@ static inline int __raw_spin_trylock(raw
 	return (result == 0UL);
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__asm__ __volatile__(
 "	stb		%%g0, [%0]"
@@ -68,7 +68,7 @@ static inline void __raw_spin_unlock(raw
 	: "memory");
 }
 
-static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 {
 	unsigned long tmp1, tmp2;
 
@@ -92,7 +92,7 @@ static inline void __raw_spin_lock_flags
 
 /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
 
-static void inline arch_read_lock(raw_rwlock_t *lock)
+static void inline arch_read_lock(arch_rwlock_t *lock)
 {
 	unsigned long tmp1, tmp2;
 
@@ -115,7 +115,7 @@ static void inline arch_read_lock(raw_rw
 	: "memory");
 }
 
-static int inline arch_read_trylock(raw_rwlock_t *lock)
+static int inline arch_read_trylock(arch_rwlock_t *lock)
 {
 	int tmp1, tmp2;
 
@@ -136,7 +136,7 @@ static int inline arch_read_trylock(raw_
 	return tmp1;
 }
 
-static void inline arch_read_unlock(raw_rwlock_t *lock)
+static void inline arch_read_unlock(arch_rwlock_t *lock)
 {
 	unsigned long tmp1, tmp2;
 
@@ -152,7 +152,7 @@ static void inline arch_read_unlock(raw_
 	: "memory");
 }
 
-static void inline arch_write_lock(raw_rwlock_t *lock)
+static void inline arch_write_lock(arch_rwlock_t *lock)
 {
 	unsigned long mask, tmp1, tmp2;
 
@@ -177,7 +177,7 @@ static void inline arch_write_lock(raw_r
 	: "memory");
 }
 
-static void inline arch_write_unlock(raw_rwlock_t *lock)
+static void inline arch_write_unlock(arch_rwlock_t *lock)
 {
 	__asm__ __volatile__(
 "	stw		%%g0, [%0]"
@@ -186,7 +186,7 @@ static void inline arch_write_unlock(raw
 	: "memory");
 }
 
-static int inline arch_write_trylock(raw_rwlock_t *lock)
+static int inline arch_write_trylock(arch_rwlock_t *lock)
 {
 	unsigned long mask, tmp1, tmp2, result;
 
@@ -210,21 +210,21 @@ static int inline arch_write_trylock(raw
 	return result;
 }
 
-#define __raw_read_lock(p)	arch_read_lock(p)
-#define __raw_read_lock_flags(p, f) arch_read_lock(p)
-#define __raw_read_trylock(p)	arch_read_trylock(p)
-#define __raw_read_unlock(p)	arch_read_unlock(p)
-#define __raw_write_lock(p)	arch_write_lock(p)
-#define __raw_write_lock_flags(p, f) arch_write_lock(p)
-#define __raw_write_unlock(p)	arch_write_unlock(p)
-#define __raw_write_trylock(p)	arch_write_trylock(p)
+#define arch_read_lock(p)	arch_read_lock(p)
+#define arch_read_lock_flags(p, f) arch_read_lock(p)
+#define arch_read_trylock(p)	arch_read_trylock(p)
+#define arch_read_unlock(p)	arch_read_unlock(p)
+#define arch_write_lock(p)	arch_write_lock(p)
+#define arch_write_lock_flags(p, f) arch_write_lock(p)
+#define arch_write_unlock(p)	arch_write_unlock(p)
+#define arch_write_trylock(p)	arch_write_trylock(p)
 
-#define __raw_read_can_lock(rw)		(!((rw)->lock & 0x80000000UL))
-#define __raw_write_can_lock(rw)	(!(rw)->lock)
+#define arch_read_can_lock(rw)		(!((rw)->lock & 0x80000000UL))
+#define arch_write_can_lock(rw)	(!(rw)->lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#define arch_read_relax(lock)	cpu_relax()
+#define arch_write_relax(lock)	cpu_relax()
 
 #endif /* !(__ASSEMBLY__) */
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,14 +7,14 @@
 
 typedef struct {
 	volatile unsigned char lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ 0 }
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/stat.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/stat.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/stat.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/stat.h	2010-02-24 13:52:17.000000000 -0500
@@ -53,8 +53,8 @@ struct stat {
 	ino_t		st_ino;
 	mode_t		st_mode;
 	short		st_nlink;
-	uid_t		st_uid;
-	gid_t		st_gid;
+	uid16_t		st_uid;
+	gid16_t		st_gid;
 	unsigned short	st_rdev;
 	off_t		st_size;
 	time_t		st_atime;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/string_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/string_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/string_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/string_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,8 +16,6 @@
 #ifdef __KERNEL__
 
 extern void __memmove(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memset(void *,int,__kernel_size_t);
 
 #ifndef EXPORT_SYMTAB_STROPS
 
@@ -32,82 +30,10 @@ extern __kernel_size_t __memset(void *,i
 })
 
 #define __HAVE_ARCH_MEMCPY
-
-static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
-	extern void __copy_1page(void *, const void *);
-
-	if(n <= 32) {
-		__builtin_memcpy(to, from, n);
-	} else if (((unsigned int) to & 7) != 0) {
-		/* Destination is not aligned on the double-word boundary */
-		__memcpy(to, from, n);
-	} else {
-		switch(n) {
-		case PAGE_SIZE:
-			__copy_1page(to, from);
-			break;
-		default:
-			__memcpy(to, from, n);
-			break;
-		}
-	}
-	return to;
-}
-
-static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
-	__memcpy(to, from, n);
-	return to;
-}
-
-#undef memcpy
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __nonconstant_memcpy((t),(f),(n)))
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
 
 #define __HAVE_ARCH_MEMSET
-
-static inline void *__constant_c_and_count_memset(void *s, char c, __kernel_size_t count)
-{
-	extern void bzero_1page(void *);
-	extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-	if(!c) {
-		if(count == PAGE_SIZE)
-			bzero_1page(s);
-		else
-			__bzero(s, count);
-	} else {
-		__memset(s, c, count);
-	}
-	return s;
-}
-
-static inline void *__constant_c_memset(void *s, char c, __kernel_size_t count)
-{
-	extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-	if(!c)
-		__bzero(s, count);
-	else
-		__memset(s, c, count);
-	return s;
-}
-
-static inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count)
-{
-	__memset(s, c, count);
-	return s;
-}
-
-#undef memset
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
-                            __constant_c_and_count_memset((s), (c), (count)) : \
-                            __constant_c_memset((s), (c), (count))) \
-                          : __nonconstant_memset((s), (c), (count)))
+#define memset(s, c, count) __builtin_memset(s, c, count)
 
 #define __HAVE_ARCH_MEMSCAN
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/string_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/string_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/string_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/string_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -15,8 +15,6 @@
 
 #include <asm/asi.h>
 
-extern void *__memset(void *,int,__kernel_size_t);
-
 #ifndef EXPORT_SYMTAB_STROPS
 
 /* First the mem*() things. */
@@ -24,29 +22,10 @@ extern void *__memset(void *,int,__kerne
 extern void *memmove(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
 
 #define __HAVE_ARCH_MEMSET
-extern void *__builtin_memset(void *,int,__kernel_size_t);
-
-static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
-{
-	extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-	if (!c) {
-		__bzero(s, count);
-		return s;
-	} else
-		return __memset(s, c, count);
-}
-
-#undef memset
-#define memset(s, c, count) \
-((__builtin_constant_p(count) && (count) <= 32) ? \
- __builtin_memset((s), (c), (count)) : \
- (__builtin_constant_p(c) ? \
-  __constant_memset((s), (c), (count)) : \
-  __memset((s), (c), (count))))
+#define memset(s, c, count) __builtin_memset(s, c, count)
 
 #define __HAVE_ARCH_MEMSCAN
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/thread_info_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/thread_info_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/thread_info_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/thread_info_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -227,12 +227,12 @@ register struct thread_info *current_thr
 /* flag bit 8 is available */
 #define TIF_SECCOMP		9	/* secure computing */
 #define TIF_SYSCALL_AUDIT	10	/* syscall auditing active */
-/* flag bit 11 is available */
+#define TIF_SYSCALL_TRACEPOINT	11	/* syscall tracepoint instrumentation */
 /* NOTE: Thread flags >= 12 should be ones we have no interest
  *       in using in assembly, else we can't use the mask as
  *       an immediate value in instructions such as andcc.
  */
-#define TIF_ABI_PENDING		12
+/* flag bit 12 is available */
 #define TIF_MEMDIE		13
 #define TIF_POLLING_NRFLAG	14
 #define TIF_FREEZE		15	/* is freezing for suspend */
@@ -246,7 +246,7 @@ register struct thread_info *current_thr
 #define _TIF_32BIT		(1<<TIF_32BIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
-#define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
+#define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/timex_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/timex_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/timex_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/timex_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,4 +12,5 @@
 typedef unsigned long cycles_t;
 #define get_cycles()	(0)
 
+extern u32 (*do_arch_gettimeoffset)(void);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/topology_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/topology_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/topology_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/topology_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,9 @@ static inline int cpu_to_node(int cpu)
 
 #define parent_node(node)	(node)
 
-#define cpumask_of_node(node) (&numa_cpumask_lookup_table[node])
+#define cpumask_of_node(node) ((node) == -1 ?				\
+			       cpu_all_mask :				\
+			       &numa_cpumask_lookup_table[node])
 
 struct pci_bus;
 #ifdef CONFIG_PCI
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/uaccess_32.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/uaccess_32.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/uaccess_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/uaccess_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -260,8 +260,23 @@ static inline unsigned long __copy_to_us
 	return __copy_user(to, (__force void __user *) from, n);
 }
 
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+	__compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+	__compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+	int sz = __compiletime_object_size(to);
+
+	if (unlikely(sz != -1 && sz < n)) {
+		copy_from_user_overflow();
+		return n;
+	}
+
 	if (n && __access_ok((unsigned long) from, n))
 		return __copy_user((__force void __user *) to, from, n);
 	else
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/uaccess_64.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/uaccess_64.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/uaccess_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/uaccess_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,6 +6,7 @@
  */
 
 #ifdef __KERNEL__
+#include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/string.h>
 #include <linux/thread_info.h>
@@ -204,6 +205,14 @@ __asm__ __volatile__(							\
 
 extern int __get_user_bad(void);
 
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+	__compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+	__compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
 extern unsigned long __must_check ___copy_from_user(void *to,
 						    const void __user *from,
 						    unsigned long size);
@@ -212,10 +221,16 @@ extern unsigned long copy_from_user_fixu
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long size)
 {
-	unsigned long ret = ___copy_from_user(to, from, size);
+	int sz = __compiletime_object_size(to);
+	unsigned long ret = size;
 
-	if (unlikely(ret))
-		ret = copy_from_user_fixup(to, from, size);
+	if (likely(sz == -1 || sz >= size)) {
+		ret = ___copy_from_user(to, from, size);
+		if (unlikely(ret))
+			ret = copy_from_user_fixup(to, from, size);
+	} else {
+		copy_from_user_overflow();
+	}
 	return ret;
 }
 #define __copy_from_user copy_from_user
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/sparc/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/sparc/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -396,8 +396,9 @@
 #define __NR_pwritev		325
 #define __NR_rt_tgsigqueueinfo	326
 #define __NR_perf_event_open	327
+#define __NR_recvmmsg		328
 
-#define NR_SYSCALLS		328
+#define NR_syscalls		329
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/Kconfig linux-libre-2.6.33-gnu1/arch/sparc/Kconfig
--- linux-libre-2.6.32-gnu1/arch/sparc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,7 @@ config SPARC64
 	select HAVE_SYSCALL_WRAPPERS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_SYSCALL_TRACEPOINTS
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select RTC_DRV_CMOS
 	select RTC_DRV_BQ4802
@@ -63,8 +64,11 @@ config BITS
 	default 64 if SPARC64
 
 config GENERIC_TIME
+	def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
 	bool
-	default y if SPARC64
+	default y if SPARC32
 
 config GENERIC_CMOS_UPDATE
 	bool
@@ -221,6 +225,13 @@ config SPARC64_SMP
 	default y
 	depends on SPARC64 && SMP
 
+config EARLYFB
+	bool "Support for early boot text console"
+	default y
+	depends on SPARC64
+	help
+	  Say Y here to enable a faster early framebuffer boot console.
+
 choice
 	prompt "Kernel page size" if SPARC64
 	default SPARC64_PAGE_SIZE_8KB
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/Kconfig.debug linux-libre-2.6.33-gnu1/arch/sparc/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/sparc/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -33,4 +33,18 @@ config FRAME_POINTER
 	depends on MCOUNT
 	default y
 
+config DEBUG_STRICT_USER_COPY_CHECKS
+	bool "Strict copy size checks"
+	depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+	---help---
+	  Enabling this option turns a certain set of sanity checks for user
+	  copy operations into compile time failures.
+
+	  The copy_from_user() etc checks are there to help test if there
+	  are sufficient security checks on the length argument of
+	  the copy operation, by having gcc prove that the argument is
+	  within bounds.
+
+	  If unsure, or if you run an older (pre 4.4) gcc, say N.
+
 endmenu
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/apc.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/apc.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/apc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/apc.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
 #include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -76,7 +75,6 @@ static inline void apc_free(struct of_de
 
 static int apc_open(struct inode *inode, struct file *f)
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
@@ -87,61 +85,46 @@ static int apc_release(struct inode *ino
 
 static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)
 {
-	__u8 inarg, __user *arg;
-
-	arg = (__u8 __user *) __arg;
-
-	lock_kernel();
+	__u8 inarg, __user *arg = (__u8 __user *) __arg;
 
 	switch (cmd) {
 	case APCIOCGFANCTL:
-		if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) {
-			unlock_kernel();
+		if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))
 			return -EFAULT;
-		}
 		break;
 
 	case APCIOCGCPWR:
-		if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) {
-			unlock_kernel();
+		if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg))
 			return -EFAULT;
-		}
 		break;
 
 	case APCIOCGBPORT:
-		if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) {
-			unlock_kernel();
+		if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg))
 			return -EFAULT;
-		}
 		break;
 
 	case APCIOCSFANCTL:
-		if (get_user(inarg, arg)) {
-			unlock_kernel();
+		if (get_user(inarg, arg))
 			return -EFAULT;
-		}
 		apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
 		break;
+
 	case APCIOCSCPWR:
-		if (get_user(inarg, arg)) {
-			unlock_kernel();
+		if (get_user(inarg, arg))
 			return -EFAULT;
-		}
 		apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
 		break;
+
 	case APCIOCSBPORT:
-		if (get_user(inarg, arg)) {
-			unlock_kernel();
+		if (get_user(inarg, arg))
 			return -EFAULT;
-		}
 		apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
 		break;
+
 	default:
-		unlock_kernel();
 		return -EINVAL;
 	};
 
-	unlock_kernel();
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/auxio_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/auxio_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/auxio_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/auxio_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@ void __init auxio_probe(void)
 	struct resource r;
 
 	switch (sparc_cpu_model) {
+	case sparc_leon:
 	case sun4d:
 	case sun4:
 		return;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/btext.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/btext.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/btext.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/btext.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,673 @@
+/*
+ * Procedures for drawing on the screen early on in the boot process.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/console.h>
+
+#include <asm/btext.h>
+#include <asm/oplib.h>
+#include <asm/io.h>
+
+#define NO_SCROLL
+
+#ifndef NO_SCROLL
+static void scrollscreen(void);
+#endif
+
+static void draw_byte(unsigned char c, long locX, long locY);
+static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
+
+#define __force_data __attribute__((__section__(".data")))
+
+static int g_loc_X __force_data;
+static int g_loc_Y __force_data;
+static int g_max_loc_X __force_data;
+static int g_max_loc_Y __force_data;
+
+static int dispDeviceRowBytes __force_data;
+static int dispDeviceDepth  __force_data;
+static int dispDeviceRect[4] __force_data;
+static unsigned char *dispDeviceBase __force_data;
+
+#define cmapsz	(16*256)
+
+static unsigned char vga_font[cmapsz];
+
+static int __init btext_initialize(unsigned int node)
+{
+	unsigned int width, height, depth, pitch;
+	unsigned long address = 0;
+	u32 prop;
+
+	if (prom_getproperty(node, "width", (char *)&width, 4) < 0)
+		return -EINVAL;
+	if (prom_getproperty(node, "height", (char *)&height, 4) < 0)
+		return -EINVAL;
+	if (prom_getproperty(node, "depth", (char *)&depth, 4) < 0)
+		return -EINVAL;
+	pitch = width * ((depth + 7) / 8);
+
+	if (prom_getproperty(node, "linebytes", (char *)&prop, 4) >= 0 &&
+	    prop != 0xffffffffu)
+		pitch = prop;
+
+	if (pitch == 1)
+		pitch = 0x1000;
+
+	if (prom_getproperty(node, "address", (char *)&prop, 4) >= 0)
+		address = prop;
+
+	/* FIXME: Add support for PCI reg properties. Right now, only
+	 * reliable on macs
+	 */
+	if (address == 0)
+		return -EINVAL;
+
+	g_loc_X = 0;
+	g_loc_Y = 0;
+	g_max_loc_X = width / 8;
+	g_max_loc_Y = height / 16;
+	dispDeviceBase = (unsigned char *)address;
+	dispDeviceRowBytes = pitch;
+	dispDeviceDepth = depth == 15 ? 16 : depth;
+	dispDeviceRect[0] = dispDeviceRect[1] = 0;
+	dispDeviceRect[2] = width;
+	dispDeviceRect[3] = height;
+
+	return 0;
+}
+
+/* Calc the base address of a given point (x,y) */
+static unsigned char * calc_base(int x, int y)
+{
+	unsigned char *base = dispDeviceBase;
+
+	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
+	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
+	return base;
+}
+
+static void btext_clearscreen(void)
+{
+	unsigned int *base	= (unsigned int *)calc_base(0, 0);
+	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
+					(dispDeviceDepth >> 3)) >> 2;
+	int i,j;
+
+	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
+	{
+		unsigned int *ptr = base;
+		for(j=width; j; --j)
+			*(ptr++) = 0;
+		base += (dispDeviceRowBytes >> 2);
+	}
+}
+
+#ifndef NO_SCROLL
+static void scrollscreen(void)
+{
+	unsigned int *src     	= (unsigned int *)calc_base(0,16);
+	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
+	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
+				   (dispDeviceDepth >> 3)) >> 2;
+	int i,j;
+
+	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
+	{
+		unsigned int *src_ptr = src;
+		unsigned int *dst_ptr = dst;
+		for(j=width; j; --j)
+			*(dst_ptr++) = *(src_ptr++);
+		src += (dispDeviceRowBytes >> 2);
+		dst += (dispDeviceRowBytes >> 2);
+	}
+	for (i=0; i<16; i++)
+	{
+		unsigned int *dst_ptr = dst;
+		for(j=width; j; --j)
+			*(dst_ptr++) = 0;
+		dst += (dispDeviceRowBytes >> 2);
+	}
+}
+#endif /* ndef NO_SCROLL */
+
+void btext_drawchar(char c)
+{
+	int cline = 0;
+#ifdef NO_SCROLL
+	int x;
+#endif
+	switch (c) {
+	case '\b':
+		if (g_loc_X > 0)
+			--g_loc_X;
+		break;
+	case '\t':
+		g_loc_X = (g_loc_X & -8) + 8;
+		break;
+	case '\r':
+		g_loc_X = 0;
+		break;
+	case '\n':
+		g_loc_X = 0;
+		g_loc_Y++;
+		cline = 1;
+		break;
+	default:
+		draw_byte(c, g_loc_X++, g_loc_Y);
+	}
+	if (g_loc_X >= g_max_loc_X) {
+		g_loc_X = 0;
+		g_loc_Y++;
+		cline = 1;
+	}
+#ifndef NO_SCROLL
+	while (g_loc_Y >= g_max_loc_Y) {
+		scrollscreen();
+		g_loc_Y--;
+	}
+#else
+	/* wrap around from bottom to top of screen so we don't
+	   waste time scrolling each line.  -- paulus. */
+	if (g_loc_Y >= g_max_loc_Y)
+		g_loc_Y = 0;
+	if (cline) {
+		for (x = 0; x < g_max_loc_X; ++x)
+			draw_byte(' ', x, g_loc_Y);
+	}
+#endif
+}
+
+static void btext_drawtext(const char *c, unsigned int len)
+{
+	while (len--)
+		btext_drawchar(*c++);
+}
+
+static void draw_byte(unsigned char c, long locX, long locY)
+{
+	unsigned char *base	= calc_base(locX << 3, locY << 4);
+	unsigned char *font	= &vga_font[((unsigned int)c) * 16];
+	int rb			= dispDeviceRowBytes;
+
+	switch(dispDeviceDepth) {
+	case 24:
+	case 32:
+		draw_byte_32(font, (unsigned int *)base, rb);
+		break;
+	case 15:
+	case 16:
+		draw_byte_16(font, (unsigned int *)base, rb);
+		break;
+	case 8:
+		draw_byte_8(font, (unsigned int *)base, rb);
+		break;
+	}
+}
+
+static unsigned int expand_bits_8[16] = {
+	0x00000000,
+	0x000000ff,
+	0x0000ff00,
+	0x0000ffff,
+	0x00ff0000,
+	0x00ff00ff,
+	0x00ffff00,
+	0x00ffffff,
+	0xff000000,
+	0xff0000ff,
+	0xff00ff00,
+	0xff00ffff,
+	0xffff0000,
+	0xffff00ff,
+	0xffffff00,
+	0xffffffff
+};
+
+static unsigned int expand_bits_16[4] = {
+	0x00000000,
+	0x0000ffff,
+	0xffff0000,
+	0xffffffff
+};
+
+
+static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+{
+	int l, bits;
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (-(bits >> 7) & fg) ^ bg;
+		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+		base[7] = (-(bits & 1) & fg) ^ bg;
+		base = (unsigned int *) ((char *)base + rb);
+	}
+}
+
+static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+{
+	int l, bits;
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+	unsigned int *eb = (int *)expand_bits_16;
+
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (eb[bits >> 6] & fg) ^ bg;
+		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+		base[3] = (eb[bits & 3] & fg) ^ bg;
+		base = (unsigned int *) ((char *)base + rb);
+	}
+}
+
+static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+{
+	int l, bits;
+	int fg = 0x0F0F0F0FUL;
+	int bg = 0x00000000UL;
+	unsigned int *eb = (int *)expand_bits_8;
+
+	for (l = 0; l < 16; ++l)
+	{
+		bits = *font++;
+		base[0] = (eb[bits >> 4] & fg) ^ bg;
+		base[1] = (eb[bits & 0xf] & fg) ^ bg;
+		base = (unsigned int *) ((char *)base + rb);
+	}
+}
+
+static void btext_console_write(struct console *con, const char *s,
+				unsigned int n)
+{
+	btext_drawtext(s, n);
+}
+
+static struct console btext_console = {
+	.name	= "btext",
+	.write	= btext_console_write,
+	.flags	= CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
+	.index	= 0,
+};
+
+int __init btext_find_display(void)
+{
+	unsigned int node;
+	char type[32];
+	int ret;
+
+	node = prom_inst2pkg(prom_stdout);
+	if (prom_getproperty(node, "device_type", type, 32) < 0)
+		return -ENODEV;
+	if (strcmp(type, "display"))
+		return -ENODEV;
+
+	ret = btext_initialize(node);
+	if (!ret) {
+		btext_clearscreen();
+		register_console(&btext_console);
+	}
+	return ret;
+}
+
+static unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 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, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/central.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/central.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/central.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/central.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,7 +99,7 @@ static int __devinit clock_board_probe(s
 
 	p->leds_resource.start = (unsigned long)
 		(p->clock_regs + CLOCK_CTRL);
-	p->leds_resource.end = p->leds_resource.end;
+	p->leds_resource.end = p->leds_resource.start;
 	p->leds_resource.name = "leds";
 
 	p->leds_pdev.name = "sunfire-clockboard-leds";
@@ -194,7 +194,7 @@ static int __devinit fhc_probe(struct of
 	if (!p->central) {
 		p->leds_resource.start = (unsigned long)
 			(p->pregs + FHC_PREGS_CTRL);
-		p->leds_resource.end = p->leds_resource.end;
+		p->leds_resource.end = p->leds_resource.start;
 		p->leds_resource.name = "leds";
 
 		p->leds_pdev.name = "sunfire-fhc-leds";
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/cpu.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/cpu.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,6 +185,17 @@ static const struct manufacturer_info __
 		FPU(-1, NULL)
 	}
 },{
+	0xF,		/* Aeroflex Gaisler */
+	.cpu_info = {
+		CPU(3, "LEON"),
+		CPU(-1, NULL)
+	},
+	.fpu_info = {
+		FPU(2, "GRFPU"),
+		FPU(3, "GRFPU-Lite"),
+		FPU(-1, NULL)
+	}
+},{
 	0x17,
 	.cpu_info = {
 		CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/entry.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/entry.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -400,6 +400,39 @@ linux_trap_ipi15_sun4d:
 	/* FIXME */
 1:	b,a	1b
 
+#ifdef CONFIG_SPARC_LEON
+
+	.globl	smpleon_ticker
+	/* SMP per-cpu ticker interrupts are handled specially. */
+smpleon_ticker:
+        SAVE_ALL
+	or	%l0, PSR_PIL, %g2
+	wr	%g2, 0x0, %psr
+	WRITE_PAUSE
+	wr	%g2, PSR_ET, %psr
+	WRITE_PAUSE
+	call	leon_percpu_timer_interrupt
+	 add	%sp, STACKFRAME_SZ, %o0
+	wr	%l0, PSR_ET, %psr
+	WRITE_PAUSE
+	RESTORE_ALL
+
+	.align	4
+	.globl	linux_trap_ipi15_leon
+linux_trap_ipi15_leon:
+	SAVE_ALL
+	or	%l0, PSR_PIL, %l4
+	wr	%l4, 0x0, %psr
+	WRITE_PAUSE
+	wr	%l4, PSR_ET, %psr
+	WRITE_PAUSE
+	call	leon_cross_call_irq
+	 nop
+	b	ret_trap_lockless_ipi
+	 clr	%l6
+
+#endif /* CONFIG_SPARC_LEON */
+
 #endif /* CONFIG_SMP */
 
 	/* This routine handles illegal instructions and privileged
@@ -1261,7 +1294,7 @@ linux_sparc_syscall:
 	sethi	%hi(PSR_SYSCALL), %l4
 	or	%l0, %l4, %l0
 	/* Direct access to user regs, must faster. */
-	cmp	%g1, NR_SYSCALLS
+	cmp	%g1, NR_syscalls
 	bgeu	linux_sparc_ni_syscall
 	 sll	%g1, 2, %l4
 	ld	[%l7 + %l4], %l7
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/ftrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <trace/syscall.h>
 
 #include <asm/ftrace.h>
 
@@ -91,3 +92,13 @@ int __init ftrace_dyn_arch_init(void *da
 }
 #endif
 
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned int sys_call_table[];
+
+unsigned long __init arch_syscall_addr(int nr)
+{
+	return (unsigned long)sys_call_table[nr];
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/head_32.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/head_32.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/head_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -811,9 +811,31 @@ found_version:
 got_prop:
 #ifdef CONFIG_SPARC_LEON
 	        /* no cpu-type check is needed, it is a SPARC-LEON */
+#ifdef CONFIG_SMP
+		ba leon_smp_init
+		 nop
+
+		.global leon_smp_init
+leon_smp_init:
+		sethi	%hi(boot_cpu_id), %g1    ! master always 0
+		stb	%g0, [%g1 + %lo(boot_cpu_id)]
+		sethi	%hi(boot_cpu_id4), %g1   ! master always 0
+		stb	%g0, [%g1 + %lo(boot_cpu_id4)]
+
+		rd     %asr17,%g1
+		srl    %g1,28,%g1
+
+		cmp %g0,%g1
+		 beq sun4c_continue_boot         !continue with master
+		nop
+
+		ba leon_smp_cpu_startup
+		 nop
+#else
 		ba sun4c_continue_boot
 		 nop
 #endif
+#endif
 		set	cputypval, %o2
 		ldub	[%o2 + 0x4], %l1
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/iommu.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/iommu.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/iommu-helper.h>
+#include <linux/bitmap.h>
 
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
@@ -169,7 +170,7 @@ void iommu_range_free(struct iommu *iomm
 
 	entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT;
 
-	iommu_area_free(arena->map, entry, npages);
+	bitmap_clear(arena->map, entry, npages);
 }
 
 int iommu_table_init(struct iommu *iommu, int tsbsize,
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/ioport.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/ioport.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/ioport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/ioport.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,8 +48,13 @@
 #include <asm/dma.h>
 #include <asm/iommu.h>
 #include <asm/io-unit.h>
+#include <asm/leon.h>
 
+#ifdef CONFIG_SPARC_LEON
+#define mmu_inval_dma_area(p, l) leon_flush_dcache_all()
+#else
 #define mmu_inval_dma_area(p, l)	/* Anton pulled it out for 2.4.0-xx */
+#endif
 
 static struct resource *_sparc_find_resource(struct resource *r,
 					     unsigned long);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/irq_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/irq_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/irq_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/irq_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -176,7 +176,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -187,7 +187,7 @@ int show_interrupts(struct seq_file *p,
 		for_each_online_cpu(j)
 			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
-		seq_printf(p, " %9s", irq_desc[i].chip->typename);
+		seq_printf(p, " %9s", irq_desc[i].chip->name);
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
@@ -195,7 +195,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "NMI: ");
 		for_each_online_cpu(j)
@@ -250,12 +250,12 @@ struct irq_handler_data {
 };
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(unsigned int virt_irq)
+static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity)
 {
 	cpumask_t mask;
 	int cpuid;
 
-	cpumask_copy(&mask, irq_desc[virt_irq].affinity);
+	cpumask_copy(&mask, affinity);
 	if (cpus_equal(mask, cpu_online_map)) {
 		cpuid = map_to_cpu(virt_irq);
 	} else {
@@ -268,10 +268,8 @@ static int irq_choose_cpu(unsigned int v
 	return cpuid;
 }
 #else
-static int irq_choose_cpu(unsigned int virt_irq)
-{
-	return real_hard_smp_processor_id();
-}
+#define irq_choose_cpu(virt_irq, affinity)	\
+	real_hard_smp_processor_id()
 #endif
 
 static void sun4u_irq_enable(unsigned int virt_irq)
@@ -282,7 +280,8 @@ static void sun4u_irq_enable(unsigned in
 		unsigned long cpuid, imap, val;
 		unsigned int tid;
 
-		cpuid = irq_choose_cpu(virt_irq);
+		cpuid = irq_choose_cpu(virt_irq,
+				       irq_desc[virt_irq].affinity);
 		imap = data->imap;
 
 		tid = sun4u_compute_tid(imap, cpuid);
@@ -299,7 +298,24 @@ static void sun4u_irq_enable(unsigned in
 static int sun4u_set_affinity(unsigned int virt_irq,
 			       const struct cpumask *mask)
 {
-	sun4u_irq_enable(virt_irq);
+	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+
+	if (likely(data)) {
+		unsigned long cpuid, imap, val;
+		unsigned int tid;
+
+		cpuid = irq_choose_cpu(virt_irq, mask);
+		imap = data->imap;
+
+		tid = sun4u_compute_tid(imap, cpuid);
+
+		val = upa_readq(imap);
+		val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
+			 IMAP_AID_SAFARI | IMAP_NID_SAFARI);
+		val |= tid | IMAP_VALID;
+		upa_writeq(val, imap);
+		upa_writeq(ICLR_IDLE, data->iclr);
+	}
 
 	return 0;
 }
@@ -340,7 +356,8 @@ static void sun4u_irq_eoi(unsigned int v
 static void sun4v_irq_enable(unsigned int virt_irq)
 {
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq);
+	unsigned long cpuid = irq_choose_cpu(virt_irq,
+					     irq_desc[virt_irq].affinity);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -361,7 +378,7 @@ static int sun4v_set_affinity(unsigned i
 			       const struct cpumask *mask)
 {
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
-	unsigned long cpuid = irq_choose_cpu(virt_irq);
+	unsigned long cpuid = irq_choose_cpu(virt_irq, mask);
 	int err;
 
 	err = sun4v_intr_settarget(ino, cpuid);
@@ -403,7 +420,7 @@ static void sun4v_virq_enable(unsigned i
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq);
+	cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -433,7 +450,7 @@ static int sun4v_virt_set_affinity(unsig
 	unsigned long cpuid, dev_handle, dev_ino;
 	int err;
 
-	cpuid = irq_choose_cpu(virt_irq);
+	cpuid = irq_choose_cpu(virt_irq, mask);
 
 	dev_handle = virt_irq_table[virt_irq].dev_handle;
 	dev_ino = virt_irq_table[virt_irq].dev_ino;
@@ -484,7 +501,7 @@ static void sun4v_virq_eoi(unsigned int
 }
 
 static struct irq_chip sun4u_irq = {
-	.typename	= "sun4u",
+	.name		= "sun4u",
 	.enable		= sun4u_irq_enable,
 	.disable	= sun4u_irq_disable,
 	.eoi		= sun4u_irq_eoi,
@@ -492,7 +509,7 @@ static struct irq_chip sun4u_irq = {
 };
 
 static struct irq_chip sun4v_irq = {
-	.typename	= "sun4v",
+	.name		= "sun4v",
 	.enable		= sun4v_irq_enable,
 	.disable	= sun4v_irq_disable,
 	.eoi		= sun4v_irq_eoi,
@@ -500,7 +517,7 @@ static struct irq_chip sun4v_irq = {
 };
 
 static struct irq_chip sun4v_virq = {
-	.typename	= "vsun4v",
+	.name		= "vsun4v",
 	.enable		= sun4v_virq_enable,
 	.disable	= sun4v_virq_disable,
 	.eoi		= sun4v_virq_eoi,
@@ -785,14 +802,14 @@ void fixup_irqs(void)
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		unsigned long flags;
 
-		spin_lock_irqsave(&irq_desc[irq].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
 		if (irq_desc[irq].action &&
 		    !(irq_desc[irq].status & IRQ_PER_CPU)) {
 			if (irq_desc[irq].chip->set_affinity)
 				irq_desc[irq].chip->set_affinity(irq,
 					irq_desc[irq].affinity);
 		}
-		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
 	}
 
 	tick_ops->disable_irq();
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/kprobes.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/kprobes.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/kprobes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,9 @@ struct kretprobe_blackpoint kretprobe_bl
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
+	if ((unsigned long) p->addr & 0x3UL)
+		return -EILSEQ;
+
 	p->ainsn.insn[0] = *p->addr;
 	flushi(&p->ainsn.insn[0]);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/kstack.h linux-libre-2.6.33-gnu1/arch/sparc/kernel/kstack.h
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/kstack.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/kstack.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,10 @@ static inline bool kstack_valid(struct t
 {
 	unsigned long base = (unsigned long) tp;
 
+	/* Stack pointer must be 16-byte aligned.  */
+	if (sp & (16UL - 1))
+		return false;
+
 	if (sp >= (base + sizeof(struct thread_info)) &&
 	    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
 		return true;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/ldc.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/ldc.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/ldc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/ldc.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/init.h>
+#include <linux/bitmap.h>
 
 #include <asm/hypervisor.h>
 #include <asm/iommu.h>
@@ -1242,13 +1243,13 @@ int ldc_bind(struct ldc_channel *lp, con
 	snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
 
 	err = request_irq(lp->cfg.rx_irq, ldc_rx,
-			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
 			  lp->rx_irq_name, lp);
 	if (err)
 		return err;
 
 	err = request_irq(lp->cfg.tx_irq, ldc_tx,
-			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
+			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
 			  lp->tx_irq_name, lp);
 	if (err) {
 		free_irq(lp->cfg.rx_irq, lp);
@@ -1875,7 +1876,7 @@ EXPORT_SYMBOL(ldc_read);
 static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages)
 {
 	struct iommu_arena *arena = &iommu->arena;
-	unsigned long n, i, start, end, limit;
+	unsigned long n, start, end, limit;
 	int pass;
 
 	limit = arena->limit;
@@ -1883,7 +1884,7 @@ static long arena_alloc(struct ldc_iommu
 	pass = 0;
 
 again:
-	n = find_next_zero_bit(arena->map, limit, start);
+	n = bitmap_find_next_zero_area(arena->map, limit, start, npages, 0);
 	end = n + npages;
 	if (unlikely(end >= limit)) {
 		if (likely(pass < 1)) {
@@ -1896,16 +1897,7 @@ again:
 			return -1;
 		}
 	}
-
-	for (i = n; i < end; i++) {
-		if (test_bit(i, arena->map)) {
-			start = i + 1;
-			goto again;
-		}
-	}
-
-	for (i = n; i < end; i++)
-		__set_bit(i, arena->map);
+	bitmap_set(arena->map, n, npages);
 
 	arena->hint = end;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/leon_kernel.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_kernel.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/leon_kernel.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_kernel.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,11 +12,14 @@
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
 #include <linux/of_device.h>
+
 #include <asm/oplib.h>
 #include <asm/timer.h>
 #include <asm/prom.h>
 #include <asm/leon.h>
 #include <asm/leon_amba.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
 
 #include "prom.h"
 #include "irq.h"
@@ -115,6 +118,21 @@ void __init leon_init_timers(irq_handler
 				      (((1000000 / 100) - 1)));
 		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
 
+#ifdef CONFIG_SMP
+		leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
+		leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1;
+
+		if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
+		      (1<<LEON3_GPTIMER_SEPIRQ))) {
+			prom_printf("irq timer not configured with seperate irqs \n");
+			BUG();
+		}
+
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
+# endif
+
 	} else {
 		printk(KERN_ERR "No Timer/irqctrl found\n");
 		BUG();
@@ -130,11 +148,41 @@ void __init leon_init_timers(irq_handler
 		prom_halt();
 	}
 
+# ifdef CONFIG_SMP
+	{
+		unsigned long flags;
+		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)];
+
+		/* For SMP we use the level 14 ticker, however the bootup code
+		 * has copied the firmwares level 14 vector into boot cpu's
+		 * trap table, we must fix this now or we get squashed.
+		 */
+		local_irq_save(flags);
+
+		patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
+
+		/* Adjust so that we jump directly to smpleon_ticker */
+		trap_table->inst_three += smpleon_ticker - real_irq_entry;
+
+		local_flush_cache_all();
+		local_irq_restore(flags);
+	}
+# endif
+
 	if (leon3_gptimer_regs) {
 		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
 				      LEON3_GPTIMER_EN |
 				      LEON3_GPTIMER_RL |
 				      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+
+#ifdef CONFIG_SMP
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl,
+				      LEON3_GPTIMER_EN |
+				      LEON3_GPTIMER_RL |
+				      LEON3_GPTIMER_LD |
+				      LEON3_GPTIMER_IRQEN);
+#endif
+
 	}
 }
 
@@ -175,6 +223,42 @@ void __init leon_node_init(struct device
 	}
 }
 
+#ifdef CONFIG_SMP
+
+void leon_set_cpu_int(int cpu, int level)
+{
+	unsigned long mask;
+	mask = get_irqmask(level);
+	LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask);
+}
+
+static void leon_clear_ipi(int cpu, int level)
+{
+	unsigned long mask;
+	mask = get_irqmask(level);
+	LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16);
+}
+
+static void leon_set_udt(int cpu)
+{
+}
+
+void leon_clear_profile_irq(int cpu)
+{
+}
+
+void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)
+{
+	unsigned long mask, flags, *addr;
+	mask = get_irqmask(irq_nr);
+	local_irq_save(flags);
+	addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]);
+	LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask)));
+	local_irq_restore(flags);
+}
+
+#endif
+
 void __init leon_init_IRQ(void)
 {
 	sparc_init_timers = leon_init_timers;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/leon_smp.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_smp.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/leon_smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/leon_smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,468 @@
+/* leon_smp.c: Sparc-Leon SMP support.
+ *
+ * based on sun4m_smp.c
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
+ * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+ */
+
+#include <asm/head.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/profile.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+#include <asm/irq_regs.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/oplib.h>
+#include <asm/cpudata.h>
+#include <asm/asi.h>
+#include <asm/leon.h>
+#include <asm/leon_amba.h>
+
+#ifdef CONFIG_SPARC_LEON
+
+#include "irq.h"
+
+extern ctxd_t *srmmu_ctx_table_phys;
+static int smp_processors_ready;
+extern volatile unsigned long cpu_callin_map[NR_CPUS];
+extern unsigned char boot_cpu_id;
+extern cpumask_t smp_commenced_mask;
+void __init leon_configure_cache_smp(void);
+
+static inline unsigned long do_swap(volatile unsigned long *ptr,
+				    unsigned long val)
+{
+	__asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
+			     : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
+			     : "memory");
+	return val;
+}
+
+static void smp_setup_percpu_timer(void);
+
+void __cpuinit leon_callin(void)
+{
+	int cpuid = hard_smpleon_processor_id();
+
+	local_flush_cache_all();
+	local_flush_tlb_all();
+	leon_configure_cache_smp();
+
+	/* Get our local ticker going. */
+	smp_setup_percpu_timer();
+
+	calibrate_delay();
+	smp_store_cpu_info(cpuid);
+
+	local_flush_cache_all();
+	local_flush_tlb_all();
+
+	/*
+	 * Unblock the master CPU _only_ when the scheduler state
+	 * of all secondary CPUs will be up-to-date, so after
+	 * the SMP initialization the master will be just allowed
+	 * to call the scheduler code.
+	 * Allow master to continue.
+	 */
+	do_swap(&cpu_callin_map[cpuid], 1);
+
+	local_flush_cache_all();
+	local_flush_tlb_all();
+
+	cpu_probe();
+
+	/* Fix idle thread fields. */
+	__asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(&current_set[cpuid])
+			     : "memory" /* paranoid */);
+
+	/* Attach to the address space of init_task. */
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
+
+	while (!cpu_isset(cpuid, smp_commenced_mask))
+		mb();
+
+	local_irq_enable();
+	cpu_set(cpuid, cpu_online_map);
+}
+
+/*
+ *	Cycle through the processors asking the PROM to start each one.
+ */
+
+extern struct linux_prom_registers smp_penguin_ctable;
+
+void __init leon_configure_cache_smp(void)
+{
+	unsigned long cfg = sparc_leon3_get_dcachecfg();
+	int me = smp_processor_id();
+
+	if (ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg) > 4) {
+		printk(KERN_INFO "Note: SMP with snooping only works on 4k cache, found %dk(0x%x) on cpu %d, disabling caches\n",
+		     (unsigned int)ASI_LEON3_SYSCTRL_CFG_SSIZE(cfg),
+		     (unsigned int)cfg, (unsigned int)me);
+		sparc_leon3_disable_cache();
+	} else {
+		if (cfg & ASI_LEON3_SYSCTRL_CFG_SNOOPING) {
+			sparc_leon3_enable_snooping();
+		} else {
+			printk(KERN_INFO "Note: You have to enable snooping in the vhdl model cpu %d, disabling caches\n",
+			     me);
+			sparc_leon3_disable_cache();
+		}
+	}
+
+	local_flush_cache_all();
+	local_flush_tlb_all();
+}
+
+void leon_smp_setbroadcast(unsigned int mask)
+{
+	int broadcast =
+	    ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >>
+	      LEON3_IRQMPSTATUS_BROADCAST) & 1);
+	if (!broadcast) {
+		prom_printf("######## !!!! The irqmp-ctrl must have broadcast enabled, smp wont work !!!!! ####### nr cpus: %d\n",
+		     leon_smp_nrcpus());
+		if (leon_smp_nrcpus() > 1) {
+			BUG();
+		} else {
+			prom_printf("continue anyway\n");
+			return;
+		}
+	}
+	LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask);
+}
+
+unsigned int leon_smp_getbroadcast(void)
+{
+	unsigned int mask;
+	mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast));
+	return mask;
+}
+
+int leon_smp_nrcpus(void)
+{
+	int nrcpu =
+	    ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >>
+	      LEON3_IRQMPSTATUS_CPUNR) & 0xf) + 1;
+	return nrcpu;
+}
+
+void __init leon_boot_cpus(void)
+{
+	int nrcpu = leon_smp_nrcpus();
+	int me = smp_processor_id();
+
+	printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x \n", (unsigned int)me,
+	       (unsigned int)nrcpu, (unsigned int)NR_CPUS,
+	       (unsigned int)&(leon3_irqctrl_regs->mpstatus));
+
+	leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, me);
+	leon_enable_irq_cpu(LEON3_IRQ_TICKER, me);
+	leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, me);
+
+	leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER);
+
+	leon_configure_cache_smp();
+	smp_setup_percpu_timer();
+	local_flush_cache_all();
+
+}
+
+int __cpuinit leon_boot_one_cpu(int i)
+{
+
+	struct task_struct *p;
+	int timeout;
+
+	/* Cook up an idler for this guy. */
+	p = fork_idle(i);
+
+	current_set[i] = task_thread_info(p);
+
+	/* See trampoline.S:leon_smp_cpu_startup for details...
+	 * Initialize the contexts table
+	 * Since the call to prom_startcpu() trashes the structure,
+	 * we need to re-initialize it for each cpu
+	 */
+	smp_penguin_ctable.which_io = 0;
+	smp_penguin_ctable.phys_addr = (unsigned int)srmmu_ctx_table_phys;
+	smp_penguin_ctable.reg_size = 0;
+
+	/* whirrr, whirrr, whirrrrrrrrr... */
+	printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i,
+	       (unsigned int)&leon3_irqctrl_regs->mpstatus);
+	local_flush_cache_all();
+
+	LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpstatus), 1 << i);
+
+	/* wheee... it's going... */
+	for (timeout = 0; timeout < 10000; timeout++) {
+		if (cpu_callin_map[i])
+			break;
+		udelay(200);
+	}
+	printk(KERN_INFO "Started CPU %d \n", (unsigned int)i);
+
+	if (!(cpu_callin_map[i])) {
+		printk(KERN_ERR "Processor %d is stuck.\n", i);
+		return -ENODEV;
+	} else {
+		leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, i);
+		leon_enable_irq_cpu(LEON3_IRQ_TICKER, i);
+		leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, i);
+	}
+
+	local_flush_cache_all();
+	return 0;
+}
+
+void __init leon_smp_done(void)
+{
+
+	int i, first;
+	int *prev;
+
+	/* setup cpu list for irq rotation */
+	first = 0;
+	prev = &first;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_online(i)) {
+			*prev = i;
+			prev = &cpu_data(i).next;
+		}
+	}
+	*prev = first;
+	local_flush_cache_all();
+
+	/* Free unneeded trap tables */
+	if (!cpu_isset(1, cpu_present_map)) {
+		ClearPageReserved(virt_to_page(trapbase_cpu1));
+		init_page_count(virt_to_page(trapbase_cpu1));
+		free_page((unsigned long)trapbase_cpu1);
+		totalram_pages++;
+		num_physpages++;
+	}
+	if (!cpu_isset(2, cpu_present_map)) {
+		ClearPageReserved(virt_to_page(trapbase_cpu2));
+		init_page_count(virt_to_page(trapbase_cpu2));
+		free_page((unsigned long)trapbase_cpu2);
+		totalram_pages++;
+		num_physpages++;
+	}
+	if (!cpu_isset(3, cpu_present_map)) {
+		ClearPageReserved(virt_to_page(trapbase_cpu3));
+		init_page_count(virt_to_page(trapbase_cpu3));
+		free_page((unsigned long)trapbase_cpu3);
+		totalram_pages++;
+		num_physpages++;
+	}
+	/* Ok, they are spinning and ready to go. */
+	smp_processors_ready = 1;
+
+}
+
+void leon_irq_rotate(int cpu)
+{
+}
+
+static struct smp_funcall {
+	smpfunc_t func;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long processors_in[NR_CPUS];	/* Set when ipi entered. */
+	unsigned long processors_out[NR_CPUS];	/* Set when ipi exited. */
+} ccall_info;
+
+static DEFINE_SPINLOCK(cross_call_lock);
+
+/* Cross calls must be serialized, at least currently. */
+static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+			    unsigned long arg2, unsigned long arg3,
+			    unsigned long arg4)
+{
+	if (smp_processors_ready) {
+		register int high = NR_CPUS - 1;
+		unsigned long flags;
+
+		spin_lock_irqsave(&cross_call_lock, flags);
+
+		{
+			/* If you make changes here, make sure gcc generates proper code... */
+			register smpfunc_t f asm("i0") = func;
+			register unsigned long a1 asm("i1") = arg1;
+			register unsigned long a2 asm("i2") = arg2;
+			register unsigned long a3 asm("i3") = arg3;
+			register unsigned long a4 asm("i4") = arg4;
+			register unsigned long a5 asm("i5") = 0;
+
+			__asm__ __volatile__("std %0, [%6]\n\t"
+					     "std %2, [%6 + 8]\n\t"
+					     "std %4, [%6 + 16]\n\t" : :
+					     "r"(f), "r"(a1), "r"(a2), "r"(a3),
+					     "r"(a4), "r"(a5),
+					     "r"(&ccall_info.func));
+		}
+
+		/* Init receive/complete mapping, plus fire the IPI's off. */
+		{
+			register int i;
+
+			cpu_clear(smp_processor_id(), mask);
+			cpus_and(mask, cpu_online_map, mask);
+			for (i = 0; i <= high; i++) {
+				if (cpu_isset(i, mask)) {
+					ccall_info.processors_in[i] = 0;
+					ccall_info.processors_out[i] = 0;
+					set_cpu_int(i, LEON3_IRQ_CROSS_CALL);
+
+				}
+			}
+		}
+
+		{
+			register int i;
+
+			i = 0;
+			do {
+				if (!cpu_isset(i, mask))
+					continue;
+
+				while (!ccall_info.processors_in[i])
+					barrier();
+			} while (++i <= high);
+
+			i = 0;
+			do {
+				if (!cpu_isset(i, mask))
+					continue;
+
+				while (!ccall_info.processors_out[i])
+					barrier();
+			} while (++i <= high);
+		}
+
+		spin_unlock_irqrestore(&cross_call_lock, flags);
+	}
+}
+
+/* Running cross calls. */
+void leon_cross_call_irq(void)
+{
+	int i = smp_processor_id();
+
+	ccall_info.processors_in[i] = 1;
+	ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+			ccall_info.arg4, ccall_info.arg5);
+	ccall_info.processors_out[i] = 1;
+}
+
+void leon_percpu_timer_interrupt(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs;
+	int cpu = smp_processor_id();
+
+	old_regs = set_irq_regs(regs);
+
+	leon_clear_profile_irq(cpu);
+
+	profile_tick(CPU_PROFILING);
+
+	if (!--prof_counter(cpu)) {
+		int user = user_mode(regs);
+
+		irq_enter();
+		update_process_times(user);
+		irq_exit();
+
+		prof_counter(cpu) = prof_multiplier(cpu);
+	}
+	set_irq_regs(old_regs);
+}
+
+static void __init smp_setup_percpu_timer(void)
+{
+	int cpu = smp_processor_id();
+
+	prof_counter(cpu) = prof_multiplier(cpu) = 1;
+}
+
+void __init leon_blackbox_id(unsigned *addr)
+{
+	int rd = *addr & 0x3e000000;
+	int rs1 = rd >> 11;
+
+	/* patch places where ___b_hard_smp_processor_id appears */
+	addr[0] = 0x81444000 | rd;	/* rd %asr17, reg */
+	addr[1] = 0x8130201c | rd | rs1;	/* srl reg, 0x1c, reg */
+	addr[2] = 0x01000000;	/* nop */
+}
+
+void __init leon_blackbox_current(unsigned *addr)
+{
+	int rd = *addr & 0x3e000000;
+	int rs1 = rd >> 11;
+
+	/* patch LOAD_CURRENT macro where ___b_load_current appears */
+	addr[0] = 0x81444000 | rd;	/* rd %asr17, reg */
+	addr[2] = 0x8130201c | rd | rs1;	/* srl reg, 0x1c, reg */
+	addr[4] = 0x81282002 | rd | rs1;	/* sll reg, 0x2, reg */
+
+}
+
+/*
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void pmc_leon_idle(void)
+{
+	__asm__ volatile ("mov %g0, %asr19");
+}
+
+void __init leon_init_smp(void)
+{
+	/* Patch ipi15 trap table */
+	t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m);
+
+	BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id);
+	BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current);
+	BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id,
+			BTFIXUPCALL_NORM);
+
+#ifndef PMC_NO_IDLE
+	/* Assign power management IDLE handler */
+	pm_idle = pmc_leon_idle;
+	printk(KERN_INFO "leon: power management initialized\n");
+#endif
+
+}
+
+#endif /* CONFIG_SPARC_LEON */
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/Makefile linux-libre-2.6.33-gnu1/arch/sparc/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -72,7 +72,7 @@ obj-y                     += dma.o
 obj-$(CONFIG_SPARC32_PCI) += pcic.o
 
 obj-$(CONFIG_SMP)         += trampoline_$(BITS).o smp_$(BITS).o
-obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o
+obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
 obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
 
 obj-y                     += auxio_$(BITS).o
@@ -87,6 +87,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
 CFLAGS_REMOVE_ftrace.o := -pg
 
+obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
 # sparc64 PCI
 obj-$(CONFIG_SPARC64_PCI)    += pci.o pci_common.o psycho_common.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/mdesc.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/mdesc.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/mdesc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/mdesc.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
+#include <linux/bootmem.h>
 
 #include <asm/cpudata.h>
 #include <asm/hypervisor.h>
@@ -108,25 +109,15 @@ static struct mdesc_handle * __init mdes
 
 static void mdesc_lmb_free(struct mdesc_handle *hp)
 {
-	unsigned int alloc_size, handle_size = hp->handle_size;
-	unsigned long start, end;
+	unsigned int alloc_size;
+	unsigned long start;
 
 	BUG_ON(atomic_read(&hp->refcnt) != 0);
 	BUG_ON(!list_empty(&hp->list));
 
-	alloc_size = PAGE_ALIGN(handle_size);
-
-	start = (unsigned long) hp;
-	end = start + alloc_size;
-
-	while (start < end) {
-		struct page *p;
-
-		p = virt_to_page(start);
-		ClearPageReserved(p);
-		__free_page(p);
-		start += PAGE_SIZE;
-	}
+	alloc_size = PAGE_ALIGN(hp->handle_size);
+	start = __pa(hp);
+	free_bootmem_late(start, alloc_size);
 }
 
 static struct mdesc_mem_ops lmb_mdesc_ops = {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/nmi.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/nmi.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/nmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/nmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ static DEFINE_PER_CPU(short, wd_enabled)
 static int endflag __initdata;
 
 static DEFINE_PER_CPU(unsigned int, last_irq_sum);
-static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(long, alert_counter);
 static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog(void)
@@ -96,7 +96,6 @@ notrace __kprobes void perfctr_irq(int i
 	int cpu = smp_processor_id();
 
 	clear_softint(1 << irq);
-	pcr_ops->write(PCR_PIC_PRIV);
 
 	local_cpu_data().__nmi_count++;
 
@@ -105,6 +104,8 @@ notrace __kprobes void perfctr_irq(int i
 	if (notify_die(DIE_NMI, "nmi", regs, 0,
 		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
 		touched = 1;
+	else
+		pcr_ops->write(PCR_PIC_PRIV);
 
 	sum = kstat_irqs_cpu(0, cpu);
 	if (__get_cpu_var(nmi_touch)) {
@@ -112,13 +113,13 @@ notrace __kprobes void perfctr_irq(int i
 		touched = 1;
 	}
 	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
-		local_inc(&__get_cpu_var(alert_counter));
-		if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz)
+		__this_cpu_inc(per_cpu_var(alert_counter));
+		if (__this_cpu_read(per_cpu_var(alert_counter)) == 30 * nmi_hz)
 			die_nmi("BUG: NMI Watchdog detected LOCKUP",
 				regs, panic_on_timeout);
 	} else {
 		__get_cpu_var(last_irq_sum) = sum;
-		local_set(&__get_cpu_var(alert_counter), 0);
+		__this_cpu_write(per_cpu_var(alert_counter), 0);
 	}
 	if (__get_cpu_var(wd_enabled)) {
 		write_pic(picl_value(nmi_hz));
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/of_device_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/of_device_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,7 +105,7 @@ static unsigned long of_bus_sbus_get_fla
 
 static int of_bus_ambapp_match(struct device_node *np)
 {
-	return !strcmp(np->name, "ambapp");
+	return !strcmp(np->type, "ambapp");
 }
 
 static void of_bus_ambapp_count_cells(struct device_node *child,
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/of_device_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/of_device_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/of_device_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, con
 	int i;
 
 	/* Check address type match */
-	if ((addr[0] ^ range[0]) & 0x03000000)
-		return -EINVAL;
+	if (!((addr[0] ^ range[0]) & 0x03000000))
+		goto type_match;
+
+	/* Special exception, we can map a 64-bit address into
+	 * a 32-bit range.
+	 */
+	if ((addr[0] & 0x03000000) == 0x03000000 &&
+	    (range[0] & 0x03000000) == 0x02000000)
+		goto type_match;
 
+	return -EINVAL;
+
+type_match:
 	if (of_out_of_range(addr + 1, range + 1, range + na + pna,
 			    na - 1, ns))
 		return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/pci.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -247,6 +247,7 @@ static struct pci_dev *of_create_pci_dev
 					 struct pci_bus *bus, int devfn)
 {
 	struct dev_archdata *sd;
+	struct pci_slot *slot;
 	struct of_device *op;
 	struct pci_dev *dev;
 	const char *type;
@@ -286,6 +287,11 @@ static struct pci_dev *of_create_pci_dev
 	dev->dev.bus = &pci_bus_type;
 	dev->devfn = devfn;
 	dev->multifunction = 0;		/* maybe a lie? */
+	set_pcie_port_type(dev);
+
+	list_for_each_entry(slot, &dev->bus->slots, list)
+		if (PCI_SLOT(dev->devfn) == slot->number)
+			dev->slot = slot;
 
 	dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
 	dev->device = of_getintprop_default(node, "device-id", 0xffff);
@@ -322,6 +328,7 @@ static struct pci_dev *of_create_pci_dev
 
 	dev->current_state = 4;		/* unknown power state */
 	dev->error_state = pci_channel_io_normal;
+	dev->dma_mask = 0xffffffff;
 
 	if (!strcmp(node->name, "pci")) {
 		/* a PCI-PCI bridge */
@@ -1064,7 +1071,6 @@ int pci64_dma_supported(struct pci_dev *
 
 	return (device_mask & dma_addr_mask) == dma_addr_mask;
 }
-EXPORT_SYMBOL(pci_dma_supported);
 
 void pci_resource_to_user(const struct pci_dev *pdev, int bar,
 			  const struct resource *rp, resource_size_t *start,
@@ -1081,3 +1087,10 @@ void pci_resource_to_user(const struct p
 	*start = rp->start - offset;
 	*end = rp->end - offset;
 }
+
+static int __init pcibios_init(void)
+{
+	pci_dfl_cache_line_size = 64 >> 2;
+	return 0;
+}
+subsys_initcall(pcibios_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/pcic.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcic.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/pcic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/pcic.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <asm/oplib.h>
 #include <asm/prom.h>
 #include <asm/pcic.h>
+#include <asm/timex.h>
 #include <asm/timer.h>
 #include <asm/uaccess.h>
 #include <asm/irq_regs.h>
@@ -163,8 +164,6 @@ void __iomem *pcic_regs;
 volatile int pcic_speculative;
 volatile int pcic_trapped;
 
-static void pci_do_gettimeofday(struct timeval *tv);
-static int pci_do_settimeofday(struct timespec *tv);
 
 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
 
@@ -716,19 +715,27 @@ static irqreturn_t pcic_timer_handler (i
 #define USECS_PER_JIFFY  10000  /* We have 100HZ "standard" timer for sparc */
 #define TICK_TIMER_LIMIT ((100*1000000/4)/100)
 
+u32 pci_gettimeoffset(void)
+{
+	/*
+	 * We divide all by 100
+	 * to have microsecond resolution and to avoid overflow
+	 */
+	unsigned long count =
+	    readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
+	count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
+	return count * 1000;
+}
+
+
 void __init pci_time_init(void)
 {
 	struct linux_pcic *pcic = &pcic0;
 	unsigned long v;
 	int timer_irq, irq;
 
-	/* A hack until do_gettimeofday prototype is moved to arch specific headers
-	   and btfixupped. Patch do_gettimeofday with ba pci_do_gettimeofday; nop */
-	((unsigned int *)do_gettimeofday)[0] = 
-	    0x10800000 | ((((unsigned long)pci_do_gettimeofday -
-	     (unsigned long)do_gettimeofday) >> 2) & 0x003fffff);
-	((unsigned int *)do_gettimeofday)[1] = 0x01000000;
-	BTFIXUPSET_CALL(bus_do_settimeofday, pci_do_settimeofday, BTFIXUPCALL_NORM);
+	do_arch_gettimeoffset = pci_gettimeoffset;
+
 	btfixup();
 
 	writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
@@ -746,84 +753,6 @@ void __init pci_time_init(void)
 	local_irq_enable();
 }
 
-static inline unsigned long do_gettimeoffset(void)
-{
-	/*
-	 * We divide all by 100
-	 * to have microsecond resolution and to avoid overflow
-	 */
-	unsigned long count =
-	    readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW;
-	count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100);
-	return count;
-}
-
-static void pci_do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long seq;
-	unsigned long usec, sec;
-	unsigned long max_ntp_tick = tick_usec - tickadj;
-
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-		usec = do_gettimeoffset();
-
-		/*
-		 * If time_adjust is negative then NTP is slowing the clock
-		 * so make sure not to go into next possible interval.
-		 * Better to lose some accuracy than have time go backwards..
-		 */
-		if (unlikely(time_adjust < 0))
-			usec = min(usec, max_ntp_tick);
-
-		sec = xtime.tv_sec;
-		usec += (xtime.tv_nsec / 1000);
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-static int pci_do_settimeofday(struct timespec *tv)
-{
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	/*
-	 * This is revolting. We need to set "xtime" correctly. However, the
-	 * value in this location is the value at the most recent update of
-	 * wall time.  Discover what correction gettimeofday() would have
-	 * made, and then undo it!
-	 */
-	tv->tv_nsec -= 1000 * do_gettimeoffset();
-	while (tv->tv_nsec < 0) {
-		tv->tv_nsec += NSEC_PER_SEC;
-		tv->tv_sec--;
-	}
-
-	wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec;
-	wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec;
-
-	if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
-		wall_to_monotonic.tv_nsec -= NSEC_PER_SEC;
-		wall_to_monotonic.tv_sec++;
-	}
-	if (wall_to_monotonic.tv_nsec < 0) {
-		wall_to_monotonic.tv_nsec += NSEC_PER_SEC;
-		wall_to_monotonic.tv_sec--;
-	}
-
-	xtime.tv_sec = tv->tv_sec;
-	xtime.tv_nsec = tv->tv_nsec;
-	ntp_clear();
-	return 0;
-}
 
 #if 0
 static void watchdog_reset() {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/pci_msi.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_msi.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/pci_msi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/pci_msi.c	2010-02-24 13:52:17.000000000 -0500
@@ -112,7 +112,7 @@ static void free_msi(struct pci_pbm_info
 }
 
 static struct irq_chip msi_irq = {
-	.typename	= "PCI-MSI",
+	.name		= "PCI-MSI",
 	.mask		= mask_msi_irq,
 	.unmask		= unmask_msi_irq,
 	.enable		= unmask_msi_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/perf_event.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/perf_event.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /* Performance event support for sparc64.
  *
- * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2009, 2010 David S. Miller <davem@davemloft.net>
  *
  * This code is based almost entirely upon the x86 perf event
  * code, which is:
@@ -18,11 +18,15 @@
 #include <linux/kdebug.h>
 #include <linux/mutex.h>
 
+#include <asm/stacktrace.h>
 #include <asm/cpudata.h>
+#include <asm/uaccess.h>
 #include <asm/atomic.h>
 #include <asm/nmi.h>
 #include <asm/pcr.h>
 
+#include "kstack.h"
+
 /* Sparc64 chips have two performance counters, 32-bits each, with
  * overflow interrupts generated on transition from 0xffffffff to 0.
  * The counters are accessed in one go using a 64-bit register.
@@ -51,16 +55,49 @@
 
 #define PIC_UPPER_INDEX			0
 #define PIC_LOWER_INDEX			1
+#define PIC_NO_INDEX			-1
 
 struct cpu_hw_events {
-	struct perf_event	*events[MAX_HWEVENTS];
-	unsigned long		used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
-	unsigned long		active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+	/* Number of events currently scheduled onto this cpu.
+	 * This tells how many entries in the arrays below
+	 * are valid.
+	 */
+	int			n_events;
+
+	/* Number of new events added since the last hw_perf_disable().
+	 * This works because the perf event layer always adds new
+	 * events inside of a perf_{disable,enable}() sequence.
+	 */
+	int			n_added;
+
+	/* Array of events current scheduled on this cpu.  */
+	struct perf_event	*event[MAX_HWEVENTS];
+
+	/* Array of encoded longs, specifying the %pcr register
+	 * encoding and the mask of PIC counters this even can
+	 * be scheduled on.  See perf_event_encode() et al.
+	 */
+	unsigned long		events[MAX_HWEVENTS];
+
+	/* The current counter index assigned to an event.  When the
+	 * event hasn't been programmed into the cpu yet, this will
+	 * hold PIC_NO_INDEX.  The event->hw.idx value tells us where
+	 * we ought to schedule the event.
+	 */
+	int			current_idx[MAX_HWEVENTS];
+
+	/* Software copy of %pcr register on this cpu.  */
 	u64			pcr;
+
+	/* Enabled/disable state.  */
 	int			enabled;
 };
 DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
 
+/* An event map describes the characteristics of a performance
+ * counter event.  In particular it gives the encoding as well as
+ * a mask telling which counters the event can be measured on.
+ */
 struct perf_event_map {
 	u16	encoding;
 	u8	pic_mask;
@@ -69,15 +106,20 @@ struct perf_event_map {
 #define PIC_LOWER	0x02
 };
 
+/* Encode a perf_event_map entry into a long.  */
 static unsigned long perf_event_encode(const struct perf_event_map *pmap)
 {
 	return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask;
 }
 
-static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk)
+static u8 perf_event_get_msk(unsigned long val)
 {
-	*msk = val & 0xff;
-	*enc = val >> 16;
+	return val & 0xff;
+}
+
+static u64 perf_event_get_enc(unsigned long val)
+{
+	return val >> 16;
 }
 
 #define C(x) PERF_COUNT_HW_CACHE_##x
@@ -491,53 +533,6 @@ static inline void sparc_pmu_disable_eve
 	pcr_ops->write(cpuc->pcr);
 }
 
-void hw_perf_enable(void)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	u64 val;
-	int i;
-
-	if (cpuc->enabled)
-		return;
-
-	cpuc->enabled = 1;
-	barrier();
-
-	val = cpuc->pcr;
-
-	for (i = 0; i < MAX_HWEVENTS; i++) {
-		struct perf_event *cp = cpuc->events[i];
-		struct hw_perf_event *hwc;
-
-		if (!cp)
-			continue;
-		hwc = &cp->hw;
-		val |= hwc->config_base;
-	}
-
-	cpuc->pcr = val;
-
-	pcr_ops->write(cpuc->pcr);
-}
-
-void hw_perf_disable(void)
-{
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	u64 val;
-
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->enabled = 0;
-
-	val = cpuc->pcr;
-	val &= ~(PCR_UTRACE | PCR_STRACE |
-		 sparc_pmu->hv_bit | sparc_pmu->irq_bit);
-	cpuc->pcr = val;
-
-	pcr_ops->write(cpuc->pcr);
-}
-
 static u32 read_pmc(int idx)
 {
 	u64 val;
@@ -566,6 +561,30 @@ static void write_pmc(int idx, u64 val)
 	write_pic(pic);
 }
 
+static u64 sparc_perf_event_update(struct perf_event *event,
+				   struct hw_perf_event *hwc, int idx)
+{
+	int shift = 64 - 32;
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	new_raw_count = read_pmc(idx);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &hwc->period_left);
+
+	return new_raw_count;
+}
+
 static int sparc_perf_event_set_period(struct perf_event *event,
 				       struct hw_perf_event *hwc, int idx)
 {
@@ -598,81 +617,166 @@ static int sparc_perf_event_set_period(s
 	return ret;
 }
 
-static int sparc_pmu_enable(struct perf_event *event)
+/* If performance event entries have been added, move existing
+ * events around (if necessary) and then assign new entries to
+ * counters.
+ */
+static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
+	int i;
 
-	if (test_and_set_bit(idx, cpuc->used_mask))
-		return -EAGAIN;
+	if (!cpuc->n_added)
+		goto out;
 
-	sparc_pmu_disable_event(cpuc, hwc, idx);
+	/* Read in the counters which are moving.  */
+	for (i = 0; i < cpuc->n_events; i++) {
+		struct perf_event *cp = cpuc->event[i];
 
-	cpuc->events[idx] = event;
-	set_bit(idx, cpuc->active_mask);
+		if (cpuc->current_idx[i] != PIC_NO_INDEX &&
+		    cpuc->current_idx[i] != cp->hw.idx) {
+			sparc_perf_event_update(cp, &cp->hw,
+						cpuc->current_idx[i]);
+			cpuc->current_idx[i] = PIC_NO_INDEX;
+		}
+	}
 
-	sparc_perf_event_set_period(event, hwc, idx);
-	sparc_pmu_enable_event(cpuc, hwc, idx);
-	perf_event_update_userpage(event);
-	return 0;
+	/* Assign to counters all unassigned events.  */
+	for (i = 0; i < cpuc->n_events; i++) {
+		struct perf_event *cp = cpuc->event[i];
+		struct hw_perf_event *hwc = &cp->hw;
+		int idx = hwc->idx;
+		u64 enc;
+
+		if (cpuc->current_idx[i] != PIC_NO_INDEX)
+			continue;
+
+		sparc_perf_event_set_period(cp, hwc, idx);
+		cpuc->current_idx[i] = idx;
+
+		enc = perf_event_get_enc(cpuc->events[i]);
+		pcr |= event_encoding(enc, idx);
+	}
+out:
+	return pcr;
 }
 
-static u64 sparc_perf_event_update(struct perf_event *event,
-				   struct hw_perf_event *hwc, int idx)
+void hw_perf_enable(void)
 {
-	int shift = 64 - 32;
-	u64 prev_raw_count, new_raw_count;
-	s64 delta;
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 pcr;
 
-again:
-	prev_raw_count = atomic64_read(&hwc->prev_count);
-	new_raw_count = read_pmc(idx);
+	if (cpuc->enabled)
+		return;
 
-	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
-			     new_raw_count) != prev_raw_count)
-		goto again;
+	cpuc->enabled = 1;
+	barrier();
 
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
+	pcr = cpuc->pcr;
+	if (!cpuc->n_events) {
+		pcr = 0;
+	} else {
+		pcr = maybe_change_configuration(cpuc, pcr);
 
-	atomic64_add(delta, &event->count);
-	atomic64_sub(delta, &hwc->period_left);
+		/* We require that all of the events have the same
+		 * configuration, so just fetch the settings from the
+		 * first entry.
+		 */
+		cpuc->pcr = pcr | cpuc->event[0]->hw.config_base;
+	}
 
-	return new_raw_count;
+	pcr_ops->write(cpuc->pcr);
+}
+
+void hw_perf_disable(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val;
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->enabled = 0;
+	cpuc->n_added = 0;
+
+	val = cpuc->pcr;
+	val &= ~(PCR_UTRACE | PCR_STRACE |
+		 sparc_pmu->hv_bit | sparc_pmu->irq_bit);
+	cpuc->pcr = val;
+
+	pcr_ops->write(cpuc->pcr);
 }
 
 static void sparc_pmu_disable(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
-	int idx = hwc->idx;
+	unsigned long flags;
+	int i;
 
-	clear_bit(idx, cpuc->active_mask);
-	sparc_pmu_disable_event(cpuc, hwc, idx);
+	local_irq_save(flags);
+	perf_disable();
 
-	barrier();
+	for (i = 0; i < cpuc->n_events; i++) {
+		if (event == cpuc->event[i]) {
+			int idx = cpuc->current_idx[i];
 
-	sparc_perf_event_update(event, hwc, idx);
-	cpuc->events[idx] = NULL;
-	clear_bit(idx, cpuc->used_mask);
+			/* Shift remaining entries down into
+			 * the existing slot.
+			 */
+			while (++i < cpuc->n_events) {
+				cpuc->event[i - 1] = cpuc->event[i];
+				cpuc->events[i - 1] = cpuc->events[i];
+				cpuc->current_idx[i - 1] =
+					cpuc->current_idx[i];
+			}
 
-	perf_event_update_userpage(event);
+			/* Absorb the final count and turn off the
+			 * event.
+			 */
+			sparc_pmu_disable_event(cpuc, hwc, idx);
+			barrier();
+			sparc_perf_event_update(event, hwc, idx);
+
+			perf_event_update_userpage(event);
+
+			cpuc->n_events--;
+			break;
+		}
+	}
+
+	perf_enable();
+	local_irq_restore(flags);
+}
+
+static int active_event_index(struct cpu_hw_events *cpuc,
+			      struct perf_event *event)
+{
+	int i;
+
+	for (i = 0; i < cpuc->n_events; i++) {
+		if (cpuc->event[i] == event)
+			break;
+	}
+	BUG_ON(i == cpuc->n_events);
+	return cpuc->current_idx[i];
 }
 
 static void sparc_pmu_read(struct perf_event *event)
 {
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int idx = active_event_index(cpuc, event);
 	struct hw_perf_event *hwc = &event->hw;
 
-	sparc_perf_event_update(event, hwc, hwc->idx);
+	sparc_perf_event_update(event, hwc, idx);
 }
 
 static void sparc_pmu_unthrottle(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int idx = active_event_index(cpuc, event);
 	struct hw_perf_event *hwc = &event->hw;
 
-	sparc_pmu_enable_event(cpuc, hwc, hwc->idx);
+	sparc_pmu_enable_event(cpuc, hwc, idx);
 }
 
 static atomic_t active_events = ATOMIC_INIT(0);
@@ -750,43 +854,75 @@ static void hw_perf_event_destroy(struct
 /* Make sure all events can be scheduled into the hardware at
  * the same time.  This is simplified by the fact that we only
  * need to support 2 simultaneous HW events.
+ *
+ * As a side effect, the evts[]->hw.idx values will be assigned
+ * on success.  These are pending indexes.  When the events are
+ * actually programmed into the chip, these values will propagate
+ * to the per-cpu cpuc->current_idx[] slots, see the code in
+ * maybe_change_configuration() for details.
  */
-static int sparc_check_constraints(unsigned long *events, int n_ev)
+static int sparc_check_constraints(struct perf_event **evts,
+				   unsigned long *events, int n_ev)
 {
-	if (n_ev <= perf_max_events) {
-		u8 msk1, msk2;
-		u16 dummy;
+	u8 msk0 = 0, msk1 = 0;
+	int idx0 = 0;
 
-		if (n_ev == 1)
-			return 0;
-		BUG_ON(n_ev != 2);
-		perf_event_decode(events[0], &dummy, &msk1);
-		perf_event_decode(events[1], &dummy, &msk2);
+	/* This case is possible when we are invoked from
+	 * hw_perf_group_sched_in().
+	 */
+	if (!n_ev)
+		return 0;
 
-		/* If both events can go on any counter, OK.  */
-		if (msk1 == (PIC_UPPER | PIC_LOWER) &&
-		    msk2 == (PIC_UPPER | PIC_LOWER))
-			return 0;
+	if (n_ev > perf_max_events)
+		return -1;
 
-		/* If one event is limited to a specific counter,
-		 * and the other can go on both, OK.
-		 */
-		if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
-		    msk2 == (PIC_UPPER | PIC_LOWER))
-			return 0;
-		if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) &&
-		    msk1 == (PIC_UPPER | PIC_LOWER))
-			return 0;
+	msk0 = perf_event_get_msk(events[0]);
+	if (n_ev == 1) {
+		if (msk0 & PIC_LOWER)
+			idx0 = 1;
+		goto success;
+	}
+	BUG_ON(n_ev != 2);
+	msk1 = perf_event_get_msk(events[1]);
 
-		/* If the events are fixed to different counters, OK.  */
-		if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) ||
-		    (msk1 == PIC_LOWER && msk2 == PIC_UPPER))
-			return 0;
+	/* If both events can go on any counter, OK.  */
+	if (msk0 == (PIC_UPPER | PIC_LOWER) &&
+	    msk1 == (PIC_UPPER | PIC_LOWER))
+		goto success;
 
-		/* Otherwise, there is a conflict.  */
+	/* If one event is limited to a specific counter,
+	 * and the other can go on both, OK.
+	 */
+	if ((msk0 == PIC_UPPER || msk0 == PIC_LOWER) &&
+	    msk1 == (PIC_UPPER | PIC_LOWER)) {
+		if (msk0 & PIC_LOWER)
+			idx0 = 1;
+		goto success;
 	}
 
+	if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
+	    msk0 == (PIC_UPPER | PIC_LOWER)) {
+		if (msk1 & PIC_UPPER)
+			idx0 = 1;
+		goto success;
+	}
+
+	/* If the events are fixed to different counters, OK.  */
+	if ((msk0 == PIC_UPPER && msk1 == PIC_LOWER) ||
+	    (msk0 == PIC_LOWER && msk1 == PIC_UPPER)) {
+		if (msk0 & PIC_LOWER)
+			idx0 = 1;
+		goto success;
+	}
+
+	/* Otherwise, there is a conflict.  */
 	return -1;
+
+success:
+	evts[0]->hw.idx = idx0;
+	if (n_ev == 2)
+		evts[1]->hw.idx = idx0 ^ 1;
+	return 0;
 }
 
 static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
@@ -818,7 +954,8 @@ static int check_excludes(struct perf_ev
 }
 
 static int collect_events(struct perf_event *group, int max_count,
-			  struct perf_event *evts[], unsigned long *events)
+			  struct perf_event *evts[], unsigned long *events,
+			  int *current_idx)
 {
 	struct perf_event *event;
 	int n = 0;
@@ -827,7 +964,8 @@ static int collect_events(struct perf_ev
 		if (n >= max_count)
 			return -1;
 		evts[n] = group;
-		events[n++] = group->hw.event_base;
+		events[n] = group->hw.event_base;
+		current_idx[n++] = PIC_NO_INDEX;
 	}
 	list_for_each_entry(event, &group->sibling_list, group_entry) {
 		if (!is_software_event(event) &&
@@ -835,20 +973,100 @@ static int collect_events(struct perf_ev
 			if (n >= max_count)
 				return -1;
 			evts[n] = event;
-			events[n++] = event->hw.event_base;
+			events[n] = event->hw.event_base;
+			current_idx[n++] = PIC_NO_INDEX;
 		}
 	}
 	return n;
 }
 
+static void event_sched_in(struct perf_event *event, int cpu)
+{
+	event->state = PERF_EVENT_STATE_ACTIVE;
+	event->oncpu = cpu;
+	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+	if (is_software_event(event))
+		event->pmu->enable(event);
+}
+
+int hw_perf_group_sched_in(struct perf_event *group_leader,
+			   struct perf_cpu_context *cpuctx,
+			   struct perf_event_context *ctx, int cpu)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *sub;
+	int n0, n;
+
+	if (!sparc_pmu)
+		return 0;
+
+	n0 = cpuc->n_events;
+	n = collect_events(group_leader, perf_max_events - n0,
+			   &cpuc->event[n0], &cpuc->events[n0],
+			   &cpuc->current_idx[n0]);
+	if (n < 0)
+		return -EAGAIN;
+	if (check_excludes(cpuc->event, n0, n))
+		return -EINVAL;
+	if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0))
+		return -EAGAIN;
+	cpuc->n_events = n0 + n;
+	cpuc->n_added += n;
+
+	cpuctx->active_oncpu += n;
+	n = 1;
+	event_sched_in(group_leader, cpu);
+	list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
+		if (sub->state != PERF_EVENT_STATE_OFF) {
+			event_sched_in(sub, cpu);
+			n++;
+		}
+	}
+	ctx->nr_active += n;
+
+	return 1;
+}
+
+static int sparc_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int n0, ret = -EAGAIN;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	perf_disable();
+
+	n0 = cpuc->n_events;
+	if (n0 >= perf_max_events)
+		goto out;
+
+	cpuc->event[n0] = event;
+	cpuc->events[n0] = event->hw.event_base;
+	cpuc->current_idx[n0] = PIC_NO_INDEX;
+
+	if (check_excludes(cpuc->event, n0, 1))
+		goto out;
+	if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1))
+		goto out;
+
+	cpuc->n_events++;
+	cpuc->n_added++;
+
+	ret = 0;
+out:
+	perf_enable();
+	local_irq_restore(flags);
+	return ret;
+}
+
 static int __hw_perf_event_init(struct perf_event *event)
 {
 	struct perf_event_attr *attr = &event->attr;
 	struct perf_event *evts[MAX_HWEVENTS];
 	struct hw_perf_event *hwc = &event->hw;
 	unsigned long events[MAX_HWEVENTS];
+	int current_idx_dmy[MAX_HWEVENTS];
 	const struct perf_event_map *pmap;
-	u64 enc;
 	int n;
 
 	if (atomic_read(&nmi_active) < 0)
@@ -865,10 +1083,7 @@ static int __hw_perf_event_init(struct p
 	} else
 		return -EOPNOTSUPP;
 
-	/* We save the enable bits in the config_base.  So to
-	 * turn off sampling just write 'config', and to enable
-	 * things write 'config | config_base'.
-	 */
+	/* We save the enable bits in the config_base.  */
 	hwc->config_base = sparc_pmu->irq_bit;
 	if (!attr->exclude_user)
 		hwc->config_base |= PCR_UTRACE;
@@ -879,13 +1094,11 @@ static int __hw_perf_event_init(struct p
 
 	hwc->event_base = perf_event_encode(pmap);
 
-	enc = pmap->encoding;
-
 	n = 0;
 	if (event->group_leader != event) {
 		n = collect_events(event->group_leader,
 				   perf_max_events - 1,
-				   evts, events);
+				   evts, events, current_idx_dmy);
 		if (n < 0)
 			return -EINVAL;
 	}
@@ -895,9 +1108,11 @@ static int __hw_perf_event_init(struct p
 	if (check_excludes(evts, n, 1))
 		return -EINVAL;
 
-	if (sparc_check_constraints(events, n + 1))
+	if (sparc_check_constraints(evts, events, n + 1))
 		return -EINVAL;
 
+	hwc->idx = PIC_NO_INDEX;
+
 	/* Try to do all error checking before this point, as unwinding
 	 * state after grabbing the PMC is difficult.
 	 */
@@ -910,15 +1125,6 @@ static int __hw_perf_event_init(struct p
 		atomic64_set(&hwc->period_left, hwc->sample_period);
 	}
 
-	if (pmap->pic_mask & PIC_UPPER) {
-		hwc->idx = PIC_UPPER_INDEX;
-		enc <<= sparc_pmu->upper_shift;
-	} else {
-		hwc->idx = PIC_LOWER_INDEX;
-		enc <<= sparc_pmu->lower_shift;
-	}
-
-	hwc->config |= enc;
 	return 0;
 }
 
@@ -968,7 +1174,7 @@ static int __kprobes perf_event_nmi_hand
 	struct perf_sample_data data;
 	struct cpu_hw_events *cpuc;
 	struct pt_regs *regs;
-	int idx;
+	int i;
 
 	if (!atomic_read(&active_events))
 		return NOTIFY_DONE;
@@ -986,13 +1192,23 @@ static int __kprobes perf_event_nmi_hand
 	data.addr = 0;
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
-	for (idx = 0; idx < MAX_HWEVENTS; idx++) {
-		struct perf_event *event = cpuc->events[idx];
+
+	/* If the PMU has the TOE IRQ enable bits, we need to do a
+	 * dummy write to the %pcr to clear the overflow bits and thus
+	 * the interrupt.
+	 *
+	 * Do this before we peek at the counters to determine
+	 * overflow so we don't lose any events.
+	 */
+	if (sparc_pmu->irq_bit)
+		pcr_ops->write(cpuc->pcr);
+
+	for (i = 0; i < cpuc->n_events; i++) {
+		struct perf_event *event = cpuc->event[i];
+		int idx = cpuc->current_idx[i];
 		struct hw_perf_event *hwc;
 		u64 val;
 
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
 		hwc = &event->hw;
 		val = sparc_perf_event_update(event, hwc, idx);
 		if (val & (1ULL << 31))
@@ -1044,10 +1260,122 @@ void __init init_hw_perf_events(void)
 
 	pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
 
-	/* All sparc64 PMUs currently have 2 events.  But this simple
-	 * driver only supports one active event at a time.
-	 */
-	perf_max_events = 1;
+	/* All sparc64 PMUs currently have 2 events.  */
+	perf_max_events = 2;
 
 	register_die_notifier(&perf_event_nmi_notifier);
 }
+
+static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
+{
+	if (entry->nr < PERF_MAX_STACK_DEPTH)
+		entry->ip[entry->nr++] = ip;
+}
+
+static void perf_callchain_kernel(struct pt_regs *regs,
+				  struct perf_callchain_entry *entry)
+{
+	unsigned long ksp, fp;
+
+	callchain_store(entry, PERF_CONTEXT_KERNEL);
+	callchain_store(entry, regs->tpc);
+
+	ksp = regs->u_regs[UREG_I6];
+	fp = ksp + STACK_BIAS;
+	do {
+		struct sparc_stackf *sf;
+		struct pt_regs *regs;
+		unsigned long pc;
+
+		if (!kstack_valid(current_thread_info(), fp))
+			break;
+
+		sf = (struct sparc_stackf *) fp;
+		regs = (struct pt_regs *) (sf + 1);
+
+		if (kstack_is_trap_frame(current_thread_info(), regs)) {
+			if (user_mode(regs))
+				break;
+			pc = regs->tpc;
+			fp = regs->u_regs[UREG_I6] + STACK_BIAS;
+		} else {
+			pc = sf->callers_pc;
+			fp = (unsigned long)sf->fp + STACK_BIAS;
+		}
+		callchain_store(entry, pc);
+	} while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+static void perf_callchain_user_64(struct pt_regs *regs,
+				   struct perf_callchain_entry *entry)
+{
+	unsigned long ufp;
+
+	callchain_store(entry, PERF_CONTEXT_USER);
+	callchain_store(entry, regs->tpc);
+
+	ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
+	do {
+		struct sparc_stackf *usf, sf;
+		unsigned long pc;
+
+		usf = (struct sparc_stackf *) ufp;
+		if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+			break;
+
+		pc = sf.callers_pc;
+		ufp = (unsigned long)sf.fp + STACK_BIAS;
+		callchain_store(entry, pc);
+	} while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+static void perf_callchain_user_32(struct pt_regs *regs,
+				   struct perf_callchain_entry *entry)
+{
+	unsigned long ufp;
+
+	callchain_store(entry, PERF_CONTEXT_USER);
+	callchain_store(entry, regs->tpc);
+
+	ufp = regs->u_regs[UREG_I6];
+	do {
+		struct sparc_stackf32 *usf, sf;
+		unsigned long pc;
+
+		usf = (struct sparc_stackf32 *) ufp;
+		if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+			break;
+
+		pc = sf.callers_pc;
+		ufp = (unsigned long)sf.fp;
+		callchain_store(entry, pc);
+	} while (entry->nr < PERF_MAX_STACK_DEPTH);
+}
+
+/* Like powerpc we can't get PMU interrupts within the PMU handler,
+ * so no need for seperate NMI and IRQ chains as on x86.
+ */
+static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
+
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+	struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
+
+	entry->nr = 0;
+	if (!user_mode(regs)) {
+		stack_trace_flush();
+		perf_callchain_kernel(regs, entry);
+		if (current->mm)
+			regs = task_pt_regs(current);
+		else
+			regs = NULL;
+	}
+	if (regs) {
+		flushw_user();
+		if (test_thread_flag(TIF_32BIT))
+			perf_callchain_user_32(regs, entry);
+		else
+			perf_callchain_user_64(regs, entry);
+	}
+	return entry;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/process_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/process_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flag
 			 * Set some valid stack frames to give to the child.
 			 */
 			childstack = (struct sparc_stackf __user *)
-				(sp & ~0x7UL);
+				(sp & ~0xfUL);
 			parentstack = (struct sparc_stackf __user *)
 				regs->u_regs[UREG_FP];
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/process_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/process_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -365,14 +365,6 @@ void flush_thread(void)
 	struct thread_info *t = current_thread_info();
 	struct mm_struct *mm;
 
-	if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
-		clear_ti_thread_flag(t, TIF_ABI_PENDING);
-		if (test_ti_thread_flag(t, TIF_32BIT))
-			clear_ti_thread_flag(t, TIF_32BIT);
-		else
-			set_ti_thread_flag(t, TIF_32BIT);
-	}
-
 	mm = t->task->mm;
 	if (mm)
 		tsb_context_switch(mm);
@@ -406,11 +398,11 @@ static unsigned long clone_stackframe(un
 	} else
 		__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
 
-	/* Now 8-byte align the stack as this is mandatory in the
-	 * Sparc ABI due to how register windows work.  This hides
-	 * the restriction from thread libraries etc.  -DaveM
+	/* Now align the stack as this is mandatory in the Sparc ABI
+	 * due to how register windows work.  This hides the
+	 * restriction from thread libraries etc.
 	 */
-	csp &= ~7UL;
+	csp &= ~15UL;
 
 	distance = fp - psp;
 	rval = (csp - distance);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/ptrace_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/ptrace_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/ptrace_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/signal.h>
 #include <linux/regset.h>
 #include <linux/tracehook.h>
+#include <trace/syscall.h>
 #include <linux/compat.h>
 #include <linux/elf.h>
 
@@ -37,6 +38,9 @@
 #include <asm/cpudata.h>
 #include <asm/cacheflush.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 #include "entry.h"
 
 /* #define ALLOW_INIT_TRACING */
@@ -1059,6 +1063,9 @@ asmlinkage int syscall_trace_enter(struc
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		ret = tracehook_report_syscall_entry(regs);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_enter(regs, regs->u_regs[UREG_G1]);
+
 	if (unlikely(current->audit_context) && !ret)
 		audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
 				     AUDIT_ARCH_SPARC :
@@ -1084,6 +1091,9 @@ asmlinkage void syscall_trace_leave(stru
 		audit_syscall_exit(result, regs->u_regs[UREG_I0]);
 	}
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_exit(regs, regs->u_regs[UREG_G1]);
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, 0);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/setup_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/setup_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/setup_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@
 #include <asm/setup.h>
 #include <asm/mmu.h>
 #include <asm/ns87303.h>
+#include <asm/btext.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
@@ -286,7 +287,10 @@ void __init setup_arch(char **cmdline_p)
 	parse_early_param();
 
 	boot_flags_init(*cmdline_p);
-	register_console(&prom_early_console);
+#ifdef CONFIG_EARLYFB
+	if (btext_find_display())
+#endif
+		register_console(&prom_early_console);
 
 	if (tlb_type == hypervisor)
 		printk("ARCH: SUN4V\n");
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -267,15 +267,17 @@ static inline void __user *get_sigframe(
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
+	sp -= framesize;
+
 	/* Always align the stack frame.  This handles two cases.  First,
 	 * sigaltstack need not be mindful of platform specific stack
 	 * alignment.  Second, if we took this signal because the stack
 	 * is not aligned properly, we'd like to take the signal cleanly
 	 * and report that.
 	 */
-	sp &= ~7UL;
+	sp &= ~15UL;
 
-	return (void __user *)(sp - framesize);
+	return (void __user *) sp;
 }
 
 static inline int
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal32.c	2010-02-24 13:52:17.000000000 -0500
@@ -120,8 +120,8 @@ struct rt_signal_frame32 {
 };
 
 /* Align macros */
-#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 7) & (~7)))
-#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
+#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 15) & (~15)))
+#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
 
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
@@ -420,15 +420,17 @@ static void __user *get_sigframe(struct
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
+	sp -= framesize;
+
 	/* Always align the stack frame.  This handles two cases.  First,
 	 * sigaltstack need not be mindful of platform specific stack
 	 * alignment.  Second, if we took this signal because the stack
 	 * is not aligned properly, we'd like to take the signal cleanly
 	 * and report that.
 	 */
-	sp &= ~7UL;
+	sp &= ~15UL;
 
-	return (void __user *)(sp - framesize);
+	return (void __user *) sp;
 }
 
 static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/signal_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/signal_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -353,7 +353,7 @@ segv:
 /* Checks if the fp is valid */
 static int invalid_frame_pointer(void __user *fp, int fplen)
 {
-	if (((unsigned long) fp) & 7)
+	if (((unsigned long) fp) & 15)
 		return 1;
 	return 0;
 }
@@ -396,15 +396,17 @@ static inline void __user *get_sigframe(
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
+	sp -= framesize;
+
 	/* Always align the stack frame.  This handles two cases.  First,
 	 * sigaltstack need not be mindful of platform specific stack
 	 * alignment.  Second, if we took this signal because the stack
 	 * is not aligned properly, we'd like to take the signal cleanly
 	 * and report that.
 	 */
-	sp &= ~7UL;
+	sp &= ~15UL;
 
-	return (void __user *)(sp - framesize);
+	return (void __user *) sp;
 }
 
 static inline void
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/smp_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/smp_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/smp_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/smp_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/cpudata.h>
+#include <asm/leon.h>
 
 #include "irq.h"
 
@@ -96,6 +97,9 @@ void __init smp_cpus_done(unsigned int m
 	case sun4d:
 		smp4d_smp_done();
 		break;
+	case sparc_leon:
+		leon_smp_done();
+		break;
 	case sun4e:
 		printk("SUN4E\n");
 		BUG();
@@ -306,6 +310,9 @@ void __init smp_prepare_cpus(unsigned in
 	case sun4d:
 		smp4d_boot_cpus();
 		break;
+	case sparc_leon:
+		leon_boot_cpus();
+		break;
 	case sun4e:
 		printk("SUN4E\n");
 		BUG();
@@ -376,6 +383,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	case sun4d:
 		ret = smp4d_boot_one_cpu(cpu);
 		break;
+	case sparc_leon:
+		ret = leon_boot_one_cpu(cpu);
+		break;
 	case sun4e:
 		printk("SUN4E\n");
 		BUG();
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/sparc_ksyms_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/sparc_ksyms_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/sparc_ksyms_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/sparc_ksyms_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,17 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf);
 EXPORT_SYMBOL(sun4v_niagara2_getperf);
 EXPORT_SYMBOL(sun4v_niagara2_setperf);
 
-#ifdef CONFIG_PCI
-/* inline functions in asm/pci_64.h */
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
-EXPORT_SYMBOL(pci_map_sg);
-EXPORT_SYMBOL(pci_unmap_sg);
-EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
-EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
-#endif
-
 /* Exporting a symbol from /init/main.c */
 EXPORT_SYMBOL(saved_command_line);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/syscalls.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/syscalls.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/syscalls.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/syscalls.S	2010-02-24 13:52:17.000000000 -0500
@@ -62,7 +62,7 @@ sys32_rt_sigreturn:
 #endif
 	.align	32
 1:	ldx	[%g6 + TI_FLAGS], %l5
-	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+	andcc	%l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
 	be,pt	%icc, rtrap
 	 nop
 	call	syscall_trace_leave
@@ -187,7 +187,7 @@ linux_syscall_trace:
 	.globl	linux_sparc_syscall32
 linux_sparc_syscall32:
 	/* Direct access to user regs, much faster. */
-	cmp	%g1, NR_SYSCALLS			! IEU1	Group
+	cmp	%g1, NR_syscalls			! IEU1	Group
 	bgeu,pn	%xcc, linux_sparc_ni_syscall		! CTI
 	 srl	%i0, 0, %o0				! IEU0
 	sll	%g1, 2, %l4				! IEU0	Group
@@ -198,7 +198,7 @@ linux_sparc_syscall32:
 
 	srl	%i5, 0, %o5				! IEU1
 	srl	%i2, 0, %o2				! IEU0	Group
-	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
 	bne,pn	%icc, linux_syscall_trace32		! CTI
 	 mov	%i0, %l5				! IEU1
 	call	%l7					! CTI	Group brk forced
@@ -210,7 +210,7 @@ linux_sparc_syscall32:
 	.globl	linux_sparc_syscall
 linux_sparc_syscall:
 	/* Direct access to user regs, much faster. */
-	cmp	%g1, NR_SYSCALLS			! IEU1	Group
+	cmp	%g1, NR_syscalls			! IEU1	Group
 	bgeu,pn	%xcc, linux_sparc_ni_syscall		! CTI
 	 mov	%i0, %o0				! IEU0
 	sll	%g1, 2, %l4				! IEU0	Group
@@ -221,7 +221,7 @@ linux_sparc_syscall:
 
 	mov	%i3, %o3				! IEU1
 	mov	%i4, %o4				! IEU0	Group
-	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
+	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
 	bne,pn	%icc, linux_syscall_trace		! CTI	Group
 	 mov	%i0, %l5				! IEU0
 2:	call	%l7					! CTI	Group brk forced
@@ -245,7 +245,7 @@ ret_sys_call:
 
 	cmp	%o0, -ERESTART_RESTARTBLOCK
 	bgeu,pn	%xcc, 1f
-	 andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
+	 andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
 80:
 	/* System call success, clear Carry condition code. */
 	andn	%g3, %g2, %g3
@@ -260,7 +260,7 @@ ret_sys_call:
 	/* System call failure, set Carry condition code.
 	 * Also, get abs(errno) to return to the process.
 	 */
-	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6	
+	andcc	%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6	
 	sub	%g0, %o0, %o0
 	or	%g3, %g2, %g3
 	stx	%o0, [%sp + PTREGS_OFF + PT_V9_I0]
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(str
 		/* We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
 		 */
-		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
 			return -EINVAL;
 		return addr;
 	}
@@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(str
 	}
 }
 
-asmlinkage unsigned long sparc_brk(unsigned long brk)
-{
-	if(ARCH_SUN4C) {
-		if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
-			return current->mm->brk;
-	}
-	return sys_brk(brk);
-}
-
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
@@ -234,31 +226,6 @@ int sparc_mmap_check(unsigned long addr,
 }
 
 /* Linux version of mmap */
-static unsigned long do_mmap2(unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long fd,
-	unsigned long pgoff)
-{
-	struct file * file = NULL;
-	unsigned long retval = -EBADF;
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	len = PAGE_ALIGN(len);
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return retval;
-}
 
 asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
@@ -266,14 +233,16 @@ asmlinkage unsigned long sys_mmap2(unsig
 {
 	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
 	   we have. */
-	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+			      pgoff >> (PAGE_SHIFT - 12));
 }
 
 asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
 	unsigned long off)
 {
-	return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
+	/* no alignment check? */
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 }
 
 long sparc_remap_file_pages(unsigned long start, unsigned long size,
@@ -287,27 +256,6 @@ long sparc_remap_file_pages(unsigned lon
 				    (pgoff >> (PAGE_SHIFT - 12)), flags);
 }
 
-extern unsigned long do_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr);
-                
-asmlinkage unsigned long sparc_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr)
-{
-	unsigned long ret = -EINVAL;
-
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-out:
-	return ret;       
-}
-
 /* we come to here via sys_nis_syscall so it can setup the regs argument */
 asmlinkage unsigned long
 c_sys_nis_syscall (struct pt_regs *regs)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,11 +26,6 @@
 #include <linux/nfs_fs.h>
 #include <linux/quota.h>
 #include <linux/module.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
@@ -569,85 +564,6 @@ asmlinkage long sparc32_open(const char
 	return do_sys_open(AT_FDCWD, filename, flags, mode);
 }
 
-extern unsigned long do_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, unsigned long new_addr);
-                
-asmlinkage unsigned long sys32_mremap(unsigned long addr,
-	unsigned long old_len, unsigned long new_len,
-	unsigned long flags, u32 __new_addr)
-{
-	unsigned long ret = -EINVAL;
-	unsigned long new_addr = __new_addr;
-
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
-	down_write(&current->mm->mmap_sem);
-	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-	up_write(&current->mm->mmap_sem);
-out:
-	return ret;       
-}
-
-struct __sysctl_args32 {
-	u32 name;
-	int nlen;
-	u32 oldval;
-	u32 oldlenp;
-	u32 newval;
-	u32 newlen;
-	u32 __unused[4];
-};
-
-asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
-{
-#ifndef CONFIG_SYSCTL_SYSCALL
-	return -ENOSYS;
-#else
-	struct __sysctl_args32 tmp;
-	int error;
-	size_t oldlen, __user *oldlenp = NULL;
-	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL;
-
-	if (copy_from_user(&tmp, args, sizeof(tmp)))
-		return -EFAULT;
-
-	if (tmp.oldval && tmp.oldlenp) {
-		/* Duh, this is ugly and might not work if sysctl_args
-		   is in read-only memory, but do_sysctl does indirectly
-		   a lot of uaccess in both directions and we'd have to
-		   basically copy the whole sysctl.c here, and
-		   glibc's __sysctl uses rw memory for the structure
-		   anyway.  */
-		if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) ||
-		    put_user(oldlen, (size_t __user *)addr))
-			return -EFAULT;
-		oldlenp = (size_t __user *)addr;
-	}
-
-	lock_kernel();
-	error = do_sysctl((int __user *)(unsigned long) tmp.name,
-			  tmp.nlen,
-			  (void __user *)(unsigned long) tmp.oldval,
-			  oldlenp,
-			  (void __user *)(unsigned long) tmp.newval,
-			  tmp.newlen);
-	unlock_kernel();
-	if (oldlenp) {
-		if (!error) {
-			if (get_user(oldlen, (size_t __user *)addr) ||
-			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
-				error = -EFAULT;
-		}
-		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
-			error = -EFAULT;
-	}
-	return error;
-#endif
-}
-
 long sys32_lookup_dcookie(unsigned long cookie_high,
 			  unsigned long cookie_low,
 			  char __user *buf, size_t len)
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/sys_sparc_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/sys_sparc_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -317,10 +317,14 @@ bottomup:
 unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
 {
 	unsigned long align_goal, addr = -ENOMEM;
+	unsigned long (*get_area)(struct file *, unsigned long,
+				  unsigned long, unsigned long, unsigned long);
+
+	get_area = current->mm->get_unmapped_area;
 
 	if (flags & MAP_FIXED) {
 		/* Ok, don't mess with it. */
-		return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+		return get_area(NULL, orig_addr, len, pgoff, flags);
 	}
 	flags &= ~MAP_SHARED;
 
@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struc
 		align_goal = (64UL * 1024);
 
 	do {
-		addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
+		addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
 		if (!(addr & ~PAGE_MASK)) {
 			addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
 			break;
@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struc
 	 * be obtained.
 	 */
 	if (addr & ~PAGE_MASK)
-		addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
+		addr = get_area(NULL, orig_addr, len, pgoff, flags);
 
 	return addr;
 }
@@ -361,6 +365,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area);
 void arch_pick_mmap_layout(struct mm_struct *mm)
 {
 	unsigned long random_factor = 0UL;
+	unsigned long gap;
 
 	if (current->flags & PF_RANDOMIZE) {
 		random_factor = get_random_int();
@@ -375,9 +380,10 @@ void arch_pick_mmap_layout(struct mm_str
 	 * Fall back to the standard layout if the personality
 	 * bit is set, or if the expected stack growth is unlimited:
 	 */
+	gap = rlimit(RLIMIT_STACK);
 	if (!test_thread_flag(TIF_32BIT) ||
 	    (current->personality & ADDR_COMPAT_LAYOUT) ||
-	    current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
+	    gap == RLIM_INFINITY ||
 	    sysctl_legacy_va_layout) {
 		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
 		mm->get_unmapped_area = arch_get_unmapped_area;
@@ -385,9 +391,7 @@ void arch_pick_mmap_layout(struct mm_str
 	} else {
 		/* We know it's 32-bit */
 		unsigned long task_size = STACK_TOP32;
-		unsigned long gap;
 
-		gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
 		if (gap < 128 * 1024 * 1024)
 			gap = 128 * 1024 * 1024;
 		if (gap > (task_size / 6 * 5))
@@ -399,18 +403,6 @@ void arch_pick_mmap_layout(struct mm_str
 	}
 }
 
-SYSCALL_DEFINE1(sparc_brk, unsigned long, brk)
-{
-	/* People could try to be nasty and use ta 0x6d in 32bit programs */
-	if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32)
-		return current->mm->brk;
-
-	if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk)))
-		return current->mm->brk;
-
-	return sys_brk(brk);
-}
-                                                                
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way unix traditionally does this, though.
@@ -568,23 +560,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, add
 		unsigned long, prot, unsigned long, flags, unsigned long, fd,
 		unsigned long, off)
 {
-	struct file * file = NULL;
-	unsigned long retval = -EBADF;
-
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	len = PAGE_ALIGN(len);
-
-	down_write(&current->mm->mmap_sem);
-	retval = do_mmap(file, addr, len, prot, flags, off);
-	up_write(&current->mm->mmap_sem);
+	unsigned long retval = -EINVAL;
 
-	if (file)
-		fput(file);
+	if ((off + PAGE_ALIGN(len)) < off)
+		goto out;
+	if (off & ~PAGE_MASK)
+		goto out;
+	retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 out:
 	return retval;
 }
@@ -614,12 +596,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long
 
 	if (test_thread_flag(TIF_32BIT))
 		goto out;
-	if (unlikely(new_len >= VA_EXCLUDE_START))
-		goto out;
-	if (unlikely(sparc_mmap_check(addr, old_len)))
-		goto out;
-	if (unlikely(sparc_mmap_check(new_addr, new_len)))
-		goto out;
 
 	down_write(&current->mm->mmap_sem);
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls_32.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_32.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@ sys_call_table:
 /*0*/	.long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
 /*5*/	.long sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
-/*15*/	.long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
+/*15*/	.long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek
 /*20*/	.long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
 /*25*/	.long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause
 /*30*/	.long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
@@ -67,7 +67,7 @@ sys_call_table:
 /*235*/	.long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
 /*240*/	.long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 /*245*/	.long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
-/*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+/*250*/	.long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
 /*255*/	.long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
 /*260*/	.long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
 /*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
@@ -82,5 +82,5 @@ sys_call_table:
 /*310*/	.long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
 /*315*/	.long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
+/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls_64.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_64.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,7 @@ sys_call_table32:
 /*0*/	.word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod
-/*15*/	.word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek
+/*15*/	.word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
 /*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
@@ -68,7 +68,7 @@ sys_call_table32:
 	.word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall
 /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
 	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
-/*250*/	.word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
+/*250*/	.word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
 	.word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
 /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
 	.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
@@ -83,7 +83,7 @@ sys_call_table32:
 /*310*/	.word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
 	.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
-	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open
+	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg
 
 #endif /* CONFIG_COMPAT */
 
@@ -96,7 +96,7 @@ sys_call_table:
 /*0*/	.word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod
-/*15*/	.word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek
+/*15*/	.word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
 /*25*/	.word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall
 /*30*/	.word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
@@ -158,4 +158,4 @@ sys_call_table:
 /*310*/	.word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
 	.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
+	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls.h linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls.h
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/systbls.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/systbls.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@
 struct new_utsname;
 
 extern asmlinkage unsigned long sys_getpagesize(void);
-extern asmlinkage unsigned long sparc_brk(unsigned long brk);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
 extern asmlinkage long sys_ipc(unsigned int call, int first,
 			       unsigned long second,
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/time_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/time_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
 #include <linux/platform_device.h>
 
 #include <asm/oplib.h>
+#include <asm/timex.h>
 #include <asm/timer.h>
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -51,7 +52,6 @@ DEFINE_SPINLOCK(rtc_lock);
 EXPORT_SYMBOL(rtc_lock);
 
 static int set_rtc_mmss(unsigned long);
-static int sbus_do_settimeofday(struct timespec *tv);
 
 unsigned long profile_pc(struct pt_regs *regs)
 {
@@ -76,6 +76,8 @@ EXPORT_SYMBOL(profile_pc);
 
 __volatile__ unsigned int *master_l10_counter;
 
+u32 (*do_arch_gettimeoffset)(void);
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -196,38 +198,14 @@ static int __init clock_init(void)
 {
 	return of_register_driver(&clock_driver, &of_platform_bus_type);
 }
-
 /* Must be after subsys_initcall() so that busses are probed.  Must
  * be before device_initcall() because things like the RTC driver
  * need to see the clock registers.
  */
 fs_initcall(clock_init);
 
-static void __init sbus_time_init(void)
-{
-
-	BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
-	btfixup();
-
-	sparc_init_timers(timer_interrupt);
-	
-	/* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
-	local_irq_enable();
-}
-
-void __init time_init(void)
-{
-#ifdef CONFIG_PCI
-	extern void pci_time_init(void);
-	if (pcic_present()) {
-		pci_time_init();
-		return;
-	}
-#endif
-	sbus_time_init();
-}
 
-static inline unsigned long do_gettimeoffset(void)
+u32 sbus_do_gettimeoffset(void)
 {
 	unsigned long val = *master_l10_counter;
 	unsigned long usec = (val >> 10) & 0x1fffff;
@@ -236,86 +214,39 @@ static inline unsigned long do_gettimeof
 	if (val & 0x80000000)
 		usec += 1000000 / HZ;
 
-	return usec;
-}
-
-/* Ok, my cute asm atomicity trick doesn't work anymore.
- * There are just too many variables that need to be protected
- * now (both members of xtime, et al.)
- */
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long seq;
-	unsigned long usec, sec;
-	unsigned long max_ntp_tick = tick_usec - tickadj;
-
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-		usec = do_gettimeoffset();
-
-		/*
-		 * If time_adjust is negative then NTP is slowing the clock
-		 * so make sure not to go into next possible interval.
-		 * Better to lose some accuracy than have time go backwards..
-		 */
-		if (unlikely(time_adjust < 0))
-			usec = min(usec, max_ntp_tick);
-
-		sec = xtime.tv_sec;
-		usec += (xtime.tv_nsec / 1000);
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
+	return usec * 1000;
 }
 
-EXPORT_SYMBOL(do_gettimeofday);
 
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
 {
-	int ret;
-
-	write_seqlock_irq(&xtime_lock);
-	ret = bus_do_settimeofday(tv);
-	write_sequnlock_irq(&xtime_lock);
-	clock_was_set();
-	return ret;
+	if (unlikely(!do_arch_gettimeoffset))
+		return 0;
+	return do_arch_gettimeoffset();
 }
 
-EXPORT_SYMBOL(do_settimeofday);
-
-static int sbus_do_settimeofday(struct timespec *tv)
+static void __init sbus_time_init(void)
 {
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	/*
-	 * This is revolting. We need to set "xtime" correctly. However, the
-	 * value in this location is the value at the most recent update of
-	 * wall time.  Discover what correction gettimeofday() would have
-	 * made, and then undo it!
-	 */
-	nsec -= 1000 * do_gettimeoffset();
+	do_arch_gettimeoffset = sbus_do_gettimeoffset;
 
-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+	btfixup();
 
-	set_normalized_timespec(&xtime, sec, nsec);
-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+	sparc_init_timers(timer_interrupt);
+}
 
-	ntp_clear();
-	return 0;
+void __init time_init(void)
+{
+#ifdef CONFIG_PCI
+	extern void pci_time_init(void);
+	if (pcic_present()) {
+		pci_time_init();
+		return;
+	}
+#endif
+	sbus_time_init();
 }
 
+
 static int set_rtc_mmss(unsigned long secs)
 {
 	struct rtc_device *rtc = rtc_class_open("rtc0");
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/time_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/time_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/time_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -774,26 +774,9 @@ void __devinit setup_sparc64_timer(void)
 static struct clocksource clocksource_tick = {
 	.rating		= 100,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.shift		= 16,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static void __init setup_clockevent_multiplier(unsigned long hz)
-{
-	unsigned long mult, shift = 32;
-
-	while (1) {
-		mult = div_sc(hz, NSEC_PER_SEC, shift);
-		if (mult && (mult >> 32UL) == 0UL)
-			break;
-
-		shift--;
-	}
-
-	sparc64_clockevent.shift = shift;
-	sparc64_clockevent.mult = mult;
-}
-
 static unsigned long tb_ticks_per_usec __read_mostly;
 
 void __delay(unsigned long loops)
@@ -828,9 +811,7 @@ void __init time_init(void)
 		clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT);
 
 	clocksource_tick.name = tick_ops->name;
-	clocksource_tick.mult =
-		clocksource_hz2mult(freq,
-				    clocksource_tick.shift);
+	clocksource_calc_mult_shift(&clocksource_tick, freq, 4);
 	clocksource_tick.read = clocksource_tick_read;
 
 	printk("clocksource: mult[%x] shift[%d]\n",
@@ -839,15 +820,14 @@ void __init time_init(void)
 	clocksource_register(&clocksource_tick);
 
 	sparc64_clockevent.name = tick_ops->name;
-
-	setup_clockevent_multiplier(freq);
+	clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4);
 
 	sparc64_clockevent.max_delta_ns =
 		clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
 	sparc64_clockevent.min_delta_ns =
 		clockevent_delta2ns(0xF, &sparc64_clockevent);
 
-	printk("clockevent: mult[%lx] shift[%d]\n",
+	printk("clockevent: mult[%x] shift[%d]\n",
 	       sparc64_clockevent.mult, sparc64_clockevent.shift);
 
 	setup_sparc64_timer();
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/trampoline_32.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/trampoline_32.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/trampoline_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/trampoline_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
 #include <asm/contregs.h>
 #include <asm/thread_info.h>
 
-	.globl sun4m_cpu_startup, __smp4m_processor_id
+	.globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id
 	.globl sun4d_cpu_startup, __smp4d_processor_id
 
 	__CPUINIT
@@ -106,6 +106,12 @@ __smp4d_processor_id:
 	retl
 	 mov	%g1, %o7
 
+__leon_processor_id:
+	rd     %asr17,%g2
+        srl    %g2,28,%g2
+	retl
+	 mov	%g1, %o7
+
 /* CPUID in bootbus can be found at PA 0xff0140000 */
 #define SUN4D_BOOTBUS_CPUID	0xf0140000
 
@@ -160,3 +166,64 @@ sun4d_cpu_startup:
 	 nop
 
 	b,a	smp_do_cpu_idle
+
+#ifdef CONFIG_SPARC_LEON
+
+	__CPUINIT
+	.align	4
+        .global leon_smp_cpu_startup, smp_penguin_ctable
+
+leon_smp_cpu_startup:
+
+        set smp_penguin_ctable,%g1
+        ld [%g1+4],%g1
+        srl %g1,4,%g1
+        set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */
+	sta %g1, [%g5] ASI_M_MMUREGS
+
+	/* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
+	set	(PSR_PIL | PSR_S | PSR_PS), %g1
+	wr	%g1, 0x0, %psr		! traps off though
+	WRITE_PAUSE
+
+	/* Our %wim is one behind CWP */
+	mov	2, %g1
+	wr	%g1, 0x0, %wim
+	WRITE_PAUSE
+
+	/* Set tbr - we use just one trap table. */
+	set	trapbase, %g1
+	wr	%g1, 0x0, %tbr
+	WRITE_PAUSE
+
+	/* Get our CPU id */
+        rd     %asr17,%g3
+
+	/* Give ourselves a stack and curptr. */
+	set	current_set, %g5
+	srl	%g3, 28, %g4
+	sll	%g4, 2, %g4
+	ld	[%g5 + %g4], %g6
+
+	sethi	%hi(THREAD_SIZE - STACKFRAME_SZ), %sp
+	or	%sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp
+	add	%g6, %sp, %sp
+
+	/* Turn on traps (PSR_ET). */
+	rd	%psr, %g1
+	wr	%g1, PSR_ET, %psr	! traps on
+	WRITE_PAUSE
+
+	/* Init our caches, etc. */
+	set	poke_srmmu, %g5
+	ld	[%g5], %g5
+	call	%g5
+	 nop
+
+	/* Start this processor. */
+	call	leon_callin
+	 nop
+
+	b,a	smp_do_cpu_idle
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/tsb.S linux-libre-2.6.33-gnu1/arch/sparc/kernel/tsb.S
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/tsb.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/tsb.S	2010-02-24 13:52:17.000000000 -0500
@@ -191,10 +191,12 @@ tsb_dtlb_load:
 
 tsb_itlb_load:
 	/* Executable bit must be set.  */
-661:	andcc		%g5, _PAGE_EXEC_4U, %g0
-	.section	.sun4v_1insn_patch, "ax"
+661:	sethi		%hi(_PAGE_EXEC_4U), %g4
+	andcc		%g5, %g4, %g0
+	.section	.sun4v_2insn_patch, "ax"
 	.word		661b
 	andcc		%g5, _PAGE_EXEC_4V, %g0
+	nop
 	.previous
 
 	be,pn		%xcc, tsb_do_fault
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/unaligned_32.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/unaligned_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,7 @@
 #include <asm/uaccess.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-
-/* #define DEBUG_MNA */
+#include <linux/perf_event.h>
 
 enum direction {
 	load,    /* ld, ldd, ldh, ldsh */
@@ -29,12 +28,6 @@ enum direction {
 	invalid,
 };
 
-#ifdef DEBUG_MNA
-static char *dirstrings[] = {
-  "load", "store", "both", "fpload", "fpstore", "invalid"
-};
-#endif
-
 static inline enum direction decode_direction(unsigned int insn)
 {
 	unsigned long tmp = (insn >> 21) & 1;
@@ -255,10 +248,7 @@ asmlinkage void kernel_unaligned_trap(st
 		unsigned long addr = compute_effective_address(regs, insn);
 		int err;
 
-#ifdef DEBUG_MNA
-		printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
-		       regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
-#endif
+		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
 		switch (dir) {
 		case load:
 			err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
@@ -350,6 +340,7 @@ asmlinkage void user_unaligned_trap(stru
 		}
 
 		addr = compute_effective_address(regs, insn);
+		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
 		switch(dir) {
 		case load:
 			err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/unaligned_64.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/unaligned_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/unaligned_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,10 +20,9 @@
 #include <asm/uaccess.h>
 #include <linux/smp.h>
 #include <linux/bitops.h>
+#include <linux/perf_event.h>
 #include <asm/fpumacro.h>
 
-/* #define DEBUG_MNA */
-
 enum direction {
 	load,    /* ld, ldd, ldh, ldsh */
 	store,   /* st, std, sth, stsh */
@@ -33,12 +32,6 @@ enum direction {
 	invalid,
 };
 
-#ifdef DEBUG_MNA
-static char *dirstrings[] = {
-  "load", "store", "both", "fpload", "fpstore", "invalid"
-};
-#endif
-
 static inline enum direction decode_direction(unsigned int insn)
 {
 	unsigned long tmp = (insn >> 21) & 1;
@@ -327,12 +320,7 @@ asmlinkage void kernel_unaligned_trap(st
 
 		addr = compute_effective_address(regs, insn,
 						 ((insn >> 25) & 0x1f));
-#ifdef DEBUG_MNA
-		printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] "
-		       "retpc[%016lx]\n",
-		       regs->tpc, dirstrings[dir], addr, size,
-		       regs->u_regs[UREG_RETPC]);
-#endif
+		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr);
 		switch (asi) {
 		case ASI_NL:
 		case ASI_AIUPL:
@@ -399,6 +387,7 @@ int handle_popc(u32 insn, struct pt_regs
 	int ret, i, rd = ((insn >> 25) & 0x1f);
 	int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
 	                        
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
 	if (insn & 0x2000) {
 		maybe_flush_windows(0, 0, rd, from_kernel);
 		value = sign_extend_imm13(insn);
@@ -445,6 +434,8 @@ int handle_ldf_stq(u32 insn, struct pt_r
 	int asi = decode_asi(insn, regs);
 	int flag = (freg < 32) ? FPRS_DL : FPRS_DU;
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
 	save_and_clear_fpu();
 	current_thread_info()->xfsr[0] &= ~0x1c000;
 	if (freg & 3) {
@@ -566,6 +557,8 @@ void handle_ld_nf(u32 insn, struct pt_re
 	int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
 	unsigned long *reg;
 	                        
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
 	maybe_flush_windows(0, 0, rd, from_kernel);
 	reg = fetch_reg_addr(rd, regs);
 	if (from_kernel || rd < 16) {
@@ -596,6 +589,7 @@ void handle_lddfmna(struct pt_regs *regs
 
 	if (tstate & TSTATE_PRIV)
 		die_if_kernel("lddfmna from kernel", regs);
+	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar);
 	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
@@ -657,6 +651,7 @@ void handle_stdfmna(struct pt_regs *regs
 
 	if (tstate & TSTATE_PRIV)
 		die_if_kernel("stdfmna from kernel", regs);
+	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar);
 	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/kernel/visemul.c linux-libre-2.6.33-gnu1/arch/sparc/kernel/visemul.c
--- linux-libre-2.6.32-gnu1/arch/sparc/kernel/visemul.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/kernel/visemul.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/thread_info.h>
+#include <linux/perf_event.h>
 
 #include <asm/ptrace.h>
 #include <asm/pstate.h>
@@ -801,6 +802,8 @@ int vis_emul(struct pt_regs *regs, unsig
 
 	BUG_ON(regs->tstate & TSTATE_PRIV);
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
 	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/bzero.S linux-libre-2.6.33-gnu1/arch/sparc/lib/bzero.S
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/bzero.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/bzero.S	2010-02-24 13:52:17.000000000 -0500
@@ -6,10 +6,6 @@
 
 	.text
 
-	.globl	__memset
-	.type	__memset, #function
-__memset:		/* %o0=buf, %o1=pat, %o2=len */
-
 	.globl	memset
 	.type	memset, #function
 memset:			/* %o0=buf, %o1=pat, %o2=len */
@@ -83,7 +79,6 @@ __bzero_done:
 	retl
 	 mov		%o3, %o0
 	.size		__bzero, .-__bzero
-	.size		__memset, .-__memset
 	.size		memset, .-memset
 
 #define EX_ST(x,y)		\
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/checksum_32.S linux-libre-2.6.33-gnu1/arch/sparc/lib/checksum_32.S
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/checksum_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/checksum_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -560,7 +560,7 @@ __csum_partial_copy_end:
 	 mov	%i0, %o1
 	mov	%i1, %o0
 5:
-	call	__memcpy
+	call	memcpy
 	 mov	%i2, %o2
 	tst	%o0
 	bne,a	2f
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/ksyms.c linux-libre-2.6.33-gnu1/arch/sparc/lib/ksyms.c
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/ksyms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/ksyms.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,6 @@ EXPORT_SYMBOL(__memscan_generic);
 EXPORT_SYMBOL(memcmp);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(__memset);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(__bzero);
 
@@ -81,7 +80,6 @@ EXPORT_SYMBOL(__csum_partial_copy_sparc_
 
 /* Special internal versions of library functions. */
 EXPORT_SYMBOL(__copy_1page);
-EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memmove);
 EXPORT_SYMBOL(bzero_1page);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/Makefile linux-libre-2.6.33-gnu1/arch/sparc/lib/Makefile
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -44,3 +44,4 @@ obj-y                 += iomap.o
 obj-$(CONFIG_SPARC32) += atomic32.o
 obj-y                 += ksyms.o
 obj-$(CONFIG_SPARC64) += PeeCeeI.o
+obj-y                 += usercopy.o
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/mcount.S linux-libre-2.6.33-gnu1/arch/sparc/lib/mcount.S
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/mcount.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/mcount.S	2010-02-24 13:52:17.000000000 -0500
@@ -64,8 +64,9 @@ mcount:
 2:	 sethi		%hi(softirq_stack), %g3
 	or		%g3, %lo(softirq_stack), %g3
 	ldx		[%g3 + %g1], %g7
+	sub		%g7, STACK_BIAS, %g7
 	cmp		%sp, %g7
-	bleu,pt		%xcc, 2f
+	bleu,pt		%xcc, 3f
 	 sethi		%hi(THREAD_SIZE), %g3
 	add		%g7, %g3, %g7
 	cmp		%sp, %g7
@@ -75,7 +76,7 @@ mcount:
 	 * again, we are already trying to output the stack overflow
 	 * message.
 	 */
-	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
+3:	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
 	 or		%g7, %lo(ovstack), %g7
 	add		%g7, OVSTACKSIZE, %g3
 	sub		%g3, STACK_BIAS + 192, %g3
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/memcpy.S linux-libre-2.6.33-gnu1/arch/sparc/lib/memcpy.S
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/memcpy.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/memcpy.S	2010-02-24 13:52:17.000000000 -0500
@@ -543,9 +543,6 @@ FUNC(memmove)
 	b		3f
 	 add		%o0, 2, %o0
 
-#ifdef __KERNEL__
-FUNC(__memcpy)
-#endif
 FUNC(memcpy)	/* %o0=dst %o1=src %o2=len */
 
 	sub		%o0, %o1, %o4
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/memset.S linux-libre-2.6.33-gnu1/arch/sparc/lib/memset.S
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/memset.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/memset.S	2010-02-24 13:52:17.000000000 -0500
@@ -60,11 +60,10 @@
         .globl  __bzero_begin
 __bzero_begin:
 
-	.globl	__bzero, __memset, 
+	.globl	__bzero
 	.globl	memset
 	.globl	__memset_start, __memset_end
 __memset_start:
-__memset:
 memset:
 	and	%o1, 0xff, %g3
 	sll	%g3, 8, %g2
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/lib/usercopy.c linux-libre-2.6.33-gnu1/arch/sparc/lib/usercopy.c
--- linux-libre-2.6.32-gnu1/arch/sparc/lib/usercopy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/lib/usercopy.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,8 @@
+#include <linux/module.h>
+#include <linux/bug.h>
+
+void copy_from_user_overflow(void)
+{
+	WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/Makefile linux-libre-2.6.33-gnu1/arch/sparc/Makefile
--- linux-libre-2.6.32-gnu1/arch/sparc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@ AS             := $(AS) -32
 LDFLAGS        := -m elf32_sparc
 CHECKFLAGS     += -D__sparc__
 export BITS    := 32
+UTS_MACHINE    := sparc
 
 #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
 KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
@@ -46,6 +47,7 @@ CHECKFLAGS      += -D__sparc__ -D__sparc
 
 LDFLAGS              := -m elf64_sparc
 export BITS          := 64
+UTS_MACHINE          := sparc64
 
 KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow   \
                  -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/math-emu/math_32.c linux-libre-2.6.33-gnu1/arch/sparc/math-emu/math_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/math-emu/math_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/math-emu/math_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/perf_event.h>
 #include <asm/uaccess.h>
 
 #include "sfp-util_32.h"
@@ -163,6 +164,8 @@ int do_mathemu(struct pt_regs *regs, str
 	int retcode = 0;                               /* assume all succeed */
 	unsigned long insn;
 
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
+
 #ifdef DEBUG_MATHEMU
 	printk("In do_mathemu()... pc is %08lx\n", regs->pc);
 	printk("fpqdepth is %ld\n", fpt->thread.fpqdepth);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/math-emu/math_64.c linux-libre-2.6.33-gnu1/arch/sparc/math-emu/math_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/math-emu/math_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/math-emu/math_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/perf_event.h>
 
 #include <asm/fpumacro.h>
 #include <asm/ptrace.h>
@@ -183,6 +184,7 @@ int do_mathemu(struct pt_regs *regs, str
 
 	if (tstate & TSTATE_PRIV)
 		die_if_kernel("unfinished/unimplemented FPop from kernel", regs);
+	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0);
 	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/mm/fault_32.c linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_32.c
--- linux-libre-2.6.32-gnu1/arch/sparc/mm/fault_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/signal.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
+#include <linux/perf_event.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
@@ -203,6 +204,8 @@ asmlinkage void do_sparc_fault(struct pt
         if (in_atomic() || !mm)
                 goto no_context;
 
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+
 	down_read(&mm->mmap_sem);
 
 	/*
@@ -249,10 +252,15 @@ good_area:
 			goto do_sigbus;
 		BUG();
 	}
-	if (fault & VM_FAULT_MAJOR)
+	if (fault & VM_FAULT_MAJOR) {
 		current->maj_flt++;
-	else
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+			      regs, address);
+	} else {
 		current->min_flt++;
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+			      regs, address);
+	}
 	up_read(&mm->mmap_sem);
 	return;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/mm/fault_64.c linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_64.c
--- linux-libre-2.6.32-gnu1/arch/sparc/mm/fault_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/mm/fault_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/perf_event.h>
 #include <linux/interrupt.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
@@ -31,13 +32,12 @@
 #include <asm/sections.h>
 #include <asm/mmu_context.h>
 
-#ifdef CONFIG_KPROBES
-static inline int notify_page_fault(struct pt_regs *regs)
+static inline __kprobes int notify_page_fault(struct pt_regs *regs)
 {
 	int ret = 0;
 
 	/* kprobe_running() needs smp_processor_id() */
-	if (!user_mode(regs)) {
+	if (kprobes_built_in() && !user_mode(regs)) {
 		preempt_disable();
 		if (kprobe_running() && kprobe_fault_handler(regs, 0))
 			ret = 1;
@@ -45,12 +45,6 @@ static inline int notify_page_fault(stru
 	}
 	return ret;
 }
-#else
-static inline int notify_page_fault(struct pt_regs *regs)
-{
-	return 0;
-}
-#endif
 
 static void __kprobes unhandled_fault(unsigned long address,
 				      struct task_struct *tsk,
@@ -73,7 +67,7 @@ static void __kprobes unhandled_fault(un
 	die_if_kernel("Oops", regs);
 }
 
-static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
+static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
 {
 	printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
 	       regs->tpc);
@@ -170,8 +164,9 @@ static unsigned int get_fault_insn(struc
 	return insn;
 }
 
-static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
-			    unsigned int insn, unsigned long address)
+static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
+				      int fault_code, unsigned int insn,
+				      unsigned long address)
 {
 	unsigned char asi = ASI_P;
  
@@ -225,7 +220,7 @@ cannot_handle:
 	unhandled_fault (address, current, regs);
 }
 
-static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
+static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
 {
 	static int times;
 
@@ -237,8 +232,8 @@ static void noinline bogus_32bit_fault_t
 	show_regs(regs);
 }
 
-static void noinline bogus_32bit_fault_address(struct pt_regs *regs,
-					       unsigned long addr)
+static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
+							 unsigned long addr)
 {
 	static int times;
 
@@ -302,6 +297,8 @@ asmlinkage void __kprobes do_sparc64_fau
 	if (in_atomic() || !mm)
 		goto intr_or_no_mm;
 
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+
 	if (!down_read_trylock(&mm->mmap_sem)) {
 		if ((regs->tstate & TSTATE_PRIV) &&
 		    !search_exception_tables(regs->tpc)) {
@@ -406,11 +403,15 @@ good_area:
 			goto do_sigbus;
 		BUG();
 	}
-	if (fault & VM_FAULT_MAJOR)
+	if (fault & VM_FAULT_MAJOR) {
 		current->maj_flt++;
-	else
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+			      regs, address);
+	} else {
 		current->min_flt++;
-
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+			      regs, address);
+	}
 	up_read(&mm->mmap_sem);
 
 	mm_rss = get_mm_rss(mm);
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/mm/srmmu.c linux-libre-2.6.33-gnu1/arch/sparc/mm/srmmu.c
--- linux-libre-2.6.32-gnu1/arch/sparc/mm/srmmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/mm/srmmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -1990,7 +1990,7 @@ void __init poke_leonsparc(void)
 void __init init_leon(void)
 {
 
-	srmmu_name = "Leon";
+	srmmu_name = "LEON";
 
 	BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all,
 			BTFIXUPCALL_NORM);
@@ -2037,8 +2037,6 @@ static void __init get_srmmu_type(void)
 
 	/* First, check for sparc-leon. */
 	if (sparc_cpu_model == sparc_leon) {
-		psr_typ = 0xf;	/* hardcoded ids for older models/simulators */
-		psr_vers = 2;
 		init_leon();
 		return;
 	}
@@ -2301,7 +2299,8 @@ void __init ld_mmu_srmmu(void)
 	BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM);
-	if (sparc_cpu_model != sun4d) {
+	if (sparc_cpu_model != sun4d &&
+	    sparc_cpu_model != sparc_leon) {
 		BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM);
 		BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM);
@@ -2330,6 +2329,8 @@ void __init ld_mmu_srmmu(void)
 #ifdef CONFIG_SMP
 	if (sparc_cpu_model == sun4d)
 		sun4d_init_smp();
+	else if (sparc_cpu_model == sparc_leon)
+		leon_init_smp();
 	else
 		sun4m_init_smp();
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/sparc/mm/sun4c.c linux-libre-2.6.33-gnu1/arch/sparc/mm/sun4c.c
--- linux-libre-2.6.32-gnu1/arch/sparc/mm/sun4c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/sparc/mm/sun4c.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/seq_file.h>
 #include <linux/scatterlist.h>
+#include <linux/bitmap.h>
 
 #include <asm/sections.h>
 #include <asm/page.h>
@@ -1021,20 +1022,12 @@ static char *sun4c_lockarea(char *vaddr,
 	npages = (((unsigned long)vaddr & ~PAGE_MASK) +
 		  size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
 
-	scan = 0;
 	local_irq_save(flags);
-	for (;;) {
-		scan = find_next_zero_bit(sun4c_iobuffer_map,
-					  iobuffer_map_size, scan);
-		if ((base = scan) + npages > iobuffer_map_size) goto abend;
-		for (;;) {
-			if (scan >= base + npages) goto found;
-			if (test_bit(scan, sun4c_iobuffer_map)) break;
-			scan++;
-		}
-	}
+	base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size,
+						0, npages, 0);
+	if (base >= iobuffer_map_size)
+		goto abend;
 
-found:
 	high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
 	high = SUN4C_REAL_PGDIR_ALIGN(high);
 	while (high > sun4c_iobuffer_high) {
diff -druNp linux-libre-2.6.32-gnu1/arch/um/drivers/mconsole_kern.c linux-libre-2.6.33-gnu1/arch/um/drivers/mconsole_kern.c
--- linux-libre-2.6.32-gnu1/arch/um/drivers/mconsole_kern.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/drivers/mconsole_kern.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,6 +6,7 @@
 
 #include <linux/console.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/mm.h>
@@ -124,50 +125,36 @@ void mconsole_log(struct mc_request *req
 void mconsole_proc(struct mc_request *req)
 {
 	struct nameidata nd;
-	struct file_system_type *proc;
-	struct super_block *super;
+	struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
 	struct file *file;
 	int n, err;
 	char *ptr = req->request.data, *buf;
+	mm_segment_t old_fs = get_fs();
 
 	ptr += strlen("proc");
-	while (isspace(*ptr)) ptr++;
+	ptr = skip_spaces(ptr);
 
-	proc = get_fs_type("proc");
-	if (proc == NULL) {
-		mconsole_reply(req, "procfs not registered", 1, 0);
+	err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd);
+	if (err) {
+		mconsole_reply(req, "Failed to look up file", 1, 0);
 		goto out;
 	}
 
-	super = (*proc->get_sb)(proc, 0, NULL, NULL);
-	put_filesystem(proc);
-	if (super == NULL) {
-		mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
+	err = may_open(&nd.path, MAY_READ, FMODE_READ);
+	if (result) {
+		mconsole_reply(req, "Failed to open file", 1, 0);
+		path_put(&nd.path);
 		goto out;
 	}
-	up_write(&super->s_umount);
-
-	nd.path.dentry = super->s_root;
-	nd.path.mnt = NULL;
-	nd.flags = O_RDONLY + 1;
-	nd.last_type = LAST_ROOT;
-
-	/* START: it was experienced that the stability problems are closed
-	 * if commenting out these two calls + the below read cycle. To
-	 * make UML crash again, it was enough to readd either one.*/
-	err = link_path_walk(ptr, &nd);
-	if (err) {
-		mconsole_reply(req, "Failed to look up file", 1, 0);
-		goto out_kill;
-	}
 
 	file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
 			   current_cred());
+	err = PTR_ERR(file);
 	if (IS_ERR(file)) {
 		mconsole_reply(req, "Failed to open file", 1, 0);
-		goto out_kill;
+		path_put(&nd.path);
+		goto out;
 	}
-	/*END*/
 
 	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (buf == NULL) {
@@ -175,10 +162,13 @@ void mconsole_proc(struct mc_request *re
 		goto out_fput;
 	}
 
-	if ((file->f_op != NULL) && (file->f_op->read != NULL)) {
+	if (file->f_op->read) {
 		do {
-			n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
-						&file->f_pos);
+			loff_t pos;
+			set_fs(KERNEL_DS);
+			n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
+			file_pos_write(file, pos);
+			set_fs(old_fs);
 			if (n >= 0) {
 				buf[n] = '\0';
 				mconsole_reply(req, buf, 0, (n > 0));
@@ -196,8 +186,6 @@ void mconsole_proc(struct mc_request *re
 	kfree(buf);
  out_fput:
 	fput(file);
- out_kill:
-	deactivate_super(super);
  out: ;
 }
 #endif
@@ -212,8 +200,7 @@ void mconsole_proc(struct mc_request *re
 	char *ptr = req->request.data;
 
 	ptr += strlen("proc");
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr);
 	snprintf(path, sizeof(path), "/proc/%s", ptr);
 
 	fd = sys_open(path, 0, 0);
@@ -560,8 +547,7 @@ void mconsole_config(struct mc_request *
 	int err;
 
 	ptr += strlen("config");
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr);
 	dev = mconsole_find_dev(ptr);
 	if (dev == NULL) {
 		mconsole_reply(req, "Bad configuration option", 1, 0);
@@ -588,7 +574,7 @@ void mconsole_remove(struct mc_request *
 	int err, start, end, n;
 
 	ptr += strlen("remove");
-	while (isspace(*ptr)) ptr++;
+	ptr = skip_spaces(ptr);
 	dev = mconsole_find_dev(ptr);
 	if (dev == NULL) {
 		mconsole_reply(req, "Bad remove option", 1, 0);
@@ -712,7 +698,7 @@ void mconsole_sysrq(struct mc_request *r
 	char *ptr = req->request.data;
 
 	ptr += strlen("sysrq");
-	while (isspace(*ptr)) ptr++;
+	ptr = skip_spaces(ptr);
 
 	/*
 	 * With 'b', the system will shut down without a chance to reply,
@@ -757,8 +743,7 @@ void mconsole_stack(struct mc_request *r
 	 */
 
 	ptr += strlen("stack");
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr);
 
 	/*
 	 * Should really check for multiple pids or reject bad args here
@@ -833,8 +818,8 @@ static int __init mconsole_init(void)
 
 __initcall(mconsole_init);
 
-static int write_proc_mconsole(struct file *file, const char __user *buffer,
-			       unsigned long count, void *data)
+static ssize_t mconsole_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	char *buf;
 
@@ -855,6 +840,11 @@ static int write_proc_mconsole(struct fi
 	return count;
 }
 
+static const struct file_operations mconsole_proc_fops = {
+	.owner		= THIS_MODULE,
+	.write		= mconsole_proc_write,
+};
+
 static int create_proc_mconsole(void)
 {
 	struct proc_dir_entry *ent;
@@ -862,15 +852,12 @@ static int create_proc_mconsole(void)
 	if (notify_socket == NULL)
 		return 0;
 
-	ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
+	ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops);
 	if (ent == NULL) {
 		printk(KERN_INFO "create_proc_mconsole : create_proc_entry "
 		       "failed\n");
 		return 0;
 	}
-
-	ent->read_proc = NULL;
-	ent->write_proc = write_proc_mconsole;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/um/drivers/mmapper_kern.c linux-libre-2.6.33-gnu1/arch/um/drivers/mmapper_kern.c
--- linux-libre-2.6.32-gnu1/arch/um/drivers/mmapper_kern.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/drivers/mmapper_kern.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
+
 #include <asm/uaccess.h>
 #include "mem_user.h"
 
@@ -78,7 +78,6 @@ out:
 
 static int mmapper_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
@@ -115,18 +114,16 @@ static int __init mmapper_init(void)
 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
 	if (mmapper_size == 0) {
 		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-		goto out;
+		return -ENODEV;
 	}
+	p_buf = __pa(v_buf);
 
 	err = misc_register(&mmapper_dev);
 	if (err) {
 		printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
 		       err);
-		goto out;
+		return err;;
 	}
-
-	p_buf = __pa(v_buf);
-out:
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/um/drivers/random.c linux-libre-2.6.33-gnu1/arch/um/drivers/random.c
--- linux-libre-2.6.32-gnu1/arch/um/drivers/random.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/drivers/random.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,6 @@
  * of the GNU General Public License, incorporated herein by reference.
  */
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
@@ -34,8 +33,6 @@ static DECLARE_WAIT_QUEUE_HEAD(host_read
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
 {
-	cycle_kernel_lock();
-
 	/* enforce read-only access to this chrdev */
 	if ((filp->f_mode & FMODE_READ) == 0)
 		return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/arch/um/drivers/ubd_kern.c linux-libre-2.6.33-gnu1/arch/um/drivers/ubd_kern.c
--- linux-libre-2.6.32-gnu1/arch/um/drivers/ubd_kern.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/drivers/ubd_kern.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
 #include "linux/init.h"
 #include "linux/cdrom.h"
 #include "linux/proc_fs.h"
+#include "linux/seq_file.h"
 #include "linux/ctype.h"
 #include "linux/capability.h"
 #include "linux/mm.h"
@@ -200,23 +201,25 @@ static void make_proc_ide(void)
 	proc_ide = proc_mkdir("ide0", proc_ide_root);
 }
 
-static int proc_ide_read_media(char *page, char **start, off_t off, int count,
-			       int *eof, void *data)
+static int fake_ide_media_proc_show(struct seq_file *m, void *v)
 {
-	int len;
+	seq_puts(m, "disk\n");
+	return 0;
+}
 
-	strcpy(page, "disk\n");
-	len = strlen("disk\n");
-	len -= off;
-	if (len < count){
-		*eof = 1;
-		if (len <= 0) return 0;
-	}
-	else len = count;
-	*start = page + off;
-	return len;
+static int fake_ide_media_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, fake_ide_media_proc_show, NULL);
 }
 
+static const struct file_operations fake_ide_media_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fake_ide_media_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static void make_ide_entries(const char *dev_name)
 {
 	struct proc_dir_entry *dir, *ent;
@@ -227,11 +230,8 @@ static void make_ide_entries(const char
 	dir = proc_mkdir(dev_name, proc_ide);
 	if(!dir) return;
 
-	ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
+	ent = proc_create("media", S_IRUGO, dir, &fake_ide_media_proc_fops);
 	if(!ent) return;
-	ent->data = NULL;
-	ent->read_proc = proc_ide_read_media;
-	ent->write_proc = NULL;
 	snprintf(name, sizeof(name), "ide0/%s", dev_name);
 	proc_symlink(dev_name, proc_ide_root, name);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/um/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/um/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/um/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/um/kernel/exitcode.c linux-libre-2.6.33-gnu1/arch/um/kernel/exitcode.c
--- linux-libre-2.6.32-gnu1/arch/um/kernel/exitcode.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/kernel/exitcode.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,9 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/types.h>
 #include <asm/uaccess.h>
 
@@ -16,30 +18,26 @@
  */
 int uml_exitcode = 0;
 
-static int read_proc_exitcode(char *page, char **start, off_t off,
-			      int count, int *eof, void *data)
+static int exitcode_proc_show(struct seq_file *m, void *v)
 {
-	int len, val;
+	int val;
 
 	/*
 	 * Save uml_exitcode in a local so that we don't need to guarantee
 	 * that sprintf accesses it atomically.
 	 */
 	val = uml_exitcode;
-	len = sprintf(page, "%d\n", val);
-	len -= off;
-	if (len <= off+count)
-		*eof = 1;
-	*start = page + off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	seq_printf(m, "%d\n", val);
+	return 0;
 }
 
-static int write_proc_exitcode(struct file *file, const char __user *buffer,
-			       unsigned long count, void *data)
+static int exitcode_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, exitcode_proc_show, NULL);
+}
+
+static ssize_t exitcode_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	char *end, buf[sizeof("nnnnn\0")];
 	int tmp;
@@ -55,20 +53,25 @@ static int write_proc_exitcode(struct fi
 	return count;
 }
 
+static const struct file_operations exitcode_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= exitcode_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= exitcode_proc_write,
+};
+
 static int make_proc_exitcode(void)
 {
 	struct proc_dir_entry *ent;
 
-	ent = create_proc_entry("exitcode", 0600, NULL);
+	ent = proc_create("exitcode", 0600, NULL, &exitcode_proc_fops);
 	if (ent == NULL) {
 		printk(KERN_WARNING "make_proc_exitcode : Failed to register "
 		       "/proc/exitcode\n");
 		return 0;
 	}
-
-	ent->read_proc = read_proc_exitcode;
-	ent->write_proc = write_proc_exitcode;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/um/kernel/irq.c linux-libre-2.6.33-gnu1/arch/um/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/um/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -53,7 +53,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS)
 		seq_putc(p, '\n');
 
diff -druNp linux-libre-2.6.32-gnu1/arch/um/kernel/process.c linux-libre-2.6.33-gnu1/arch/um/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/um/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,11 +9,13 @@
 #include <linux/hardirq.h>
 #include <linux/gfp.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/personality.h>
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/tick.h>
 #include <linux/threads.h>
 #include <asm/current.h>
@@ -336,16 +338,19 @@ int get_using_sysemu(void)
 	return atomic_read(&using_sysemu);
 }
 
-static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
+static int sysemu_proc_show(struct seq_file *m, void *v)
 {
-	if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size)
-		/* No overflow */
-		*eof = 1;
+	seq_printf(m, "%d\n", get_using_sysemu());
+	return 0;
+}
 
-	return strlen(buf);
+static int sysemu_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sysemu_proc_show, NULL);
 }
 
-static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
+static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
+				 size_t count, loff_t *pos)
 {
 	char tmp[2];
 
@@ -358,13 +363,22 @@ static int proc_write_sysemu(struct file
 	return count;
 }
 
+static const struct file_operations sysemu_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sysemu_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= sysemu_proc_write,
+};
+
 int __init make_proc_sysemu(void)
 {
 	struct proc_dir_entry *ent;
 	if (!sysemu_supported)
 		return 0;
 
-	ent = create_proc_entry("sysemu", 0600, NULL);
+	ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops);
 
 	if (ent == NULL)
 	{
@@ -372,9 +386,6 @@ int __init make_proc_sysemu(void)
 		return 0;
 	}
 
-	ent->read_proc  = proc_read_sysemu;
-	ent->write_proc = proc_write_sysemu;
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/um/kernel/syscall.c linux-libre-2.6.33-gnu1/arch/um/kernel/syscall.c
--- linux-libre-2.6.32-gnu1/arch/um/kernel/syscall.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/kernel/syscall.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@
 #include "linux/mm.h"
 #include "linux/sched.h"
 #include "linux/utsname.h"
+#include "linux/syscalls.h"
 #include "asm/current.h"
 #include "asm/mman.h"
 #include "asm/uaccess.h"
@@ -37,31 +38,6 @@ long sys_vfork(void)
 	return ret;
 }
 
-/* common code for old and new mmaps */
-long sys_mmap2(unsigned long addr, unsigned long len,
-	       unsigned long prot, unsigned long flags,
-	       unsigned long fd, unsigned long pgoff)
-{
-	long error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
- out:
-	return error;
-}
-
 long old_mmap(unsigned long addr, unsigned long len,
 	      unsigned long prot, unsigned long flags,
 	      unsigned long fd, unsigned long offset)
@@ -70,7 +46,7 @@ long old_mmap(unsigned long addr, unsign
 	if (offset & ~PAGE_MASK)
 		goto out;
 
-	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  out:
 	return err;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/um/Makefile linux-libre-2.6.33-gnu1/arch/um/Makefile
--- linux-libre-2.6.32-gnu1/arch/um/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(AR
 
 $(SHARED_HEADERS)/kern_constants.h:
 	$(Q)mkdir -p $(dir $@)
-	$(Q)echo '#include "../../../../include/asm/asm-offsets.h"' >$@
+	$(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@
 
 export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH
diff -druNp linux-libre-2.6.32-gnu1/arch/um/sys-i386/asm/elf.h linux-libre-2.6.33-gnu1/arch/um/sys-i386/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/um/sys-i386/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/sys-i386/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,6 @@ typedef struct user_i387_struct elf_fpre
 	PT_REGS_EAX(regs) = 0; \
 } while (0)
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE 4096
 
 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
diff -druNp linux-libre-2.6.32-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h linux-libre-2.6.33-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h
--- linux-libre-2.6.32-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/sys-i386/shared/sysdep/syscalls.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,3 @@ extern syscall_handler_t *sys_call_table
 #define EXECUTE_SYSCALL(syscall, regs) \
 	((long (*)(struct syscall_args)) \
 	 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
-
-extern long sys_mmap2(unsigned long addr, unsigned long len,
-		      unsigned long prot, unsigned long flags,
-		      unsigned long fd, unsigned long pgoff);
diff -druNp linux-libre-2.6.32-gnu1/arch/um/sys-ppc/asm/elf.h linux-libre-2.6.33-gnu1/arch/um/sys-ppc/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/um/sys-ppc/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/sys-ppc/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,6 @@ extern long elf_aux_hwcap;
 #define ELF_CLASS ELFCLASS32
 #endif
 
-#define USE_ELF_CORE_DUMP
-
 #define R_386_NONE	0
 #define R_386_32	1
 #define R_386_PC32	2
diff -druNp linux-libre-2.6.32-gnu1/arch/um/sys-x86_64/asm/elf.h linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/um/sys-x86_64/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/um/sys-x86_64/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,6 @@ extern int elf_core_copy_fpregs(struct t
         clear_thread_flag(TIF_IA32);
 #endif
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE 4096
 
 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/head_64.S linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/head_64.S
--- linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/head_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/head_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -107,8 +107,7 @@ ENTRY(startup_32)
 	lgdt	gdt(%ebp)
 
 	/* Enable PAE mode */
-	xorl	%eax, %eax
-	orl	$(X86_CR4_PAE), %eax
+	movl	$(X86_CR4_PAE), %eax
 	movl	%eax, %cr4
 
  /*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/Makefile linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,11 +4,12 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
+targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
+cflags-$(CONFIG_X86_32) := -march=i386
 cflags-$(CONFIG_X86_64) := -mcmodel=small
 KBUILD_CFLAGS += $(cflags-y)
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
@@ -48,10 +49,13 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.al
 	$(call if_changed,bzip2)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,lzma)
+$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,lzo)
 
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
 suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
+suffix-$(CONFIG_KERNEL_LZO) 	:= lzo
 
 quiet_cmd_mkpiggy = MKPIGGY $@
       cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/misc.c linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/misc.c
--- linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/misc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/misc.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,6 +162,10 @@ static int lines, cols;
 #include "../../../../lib/decompress_unlzma.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
 static void scroll(void)
 {
 	int i;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/relocs.c linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/relocs.c
--- linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/relocs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/relocs.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,9 @@
 #include <byteswap.h>
 #define USE_BSD
 #include <endian.h>
+#include <regex.h>
+
+static void die(char *fmt, ...);
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 static Elf32_Ehdr ehdr;
@@ -30,25 +33,47 @@ static struct section *secs;
  * the address for which it has been compiled. Don't warn user about
  * absolute relocations present w.r.t these symbols.
  */
-static const char* safe_abs_relocs[] = {
-		"xen_irq_disable_direct_reloc",
-		"xen_save_fl_direct_reloc",
-};
+static const char abs_sym_regex[] =
+	"^(xen_irq_disable_direct_reloc$|"
+	"xen_save_fl_direct_reloc$|"
+	"VDSO|"
+	"__crc_)";
+static regex_t abs_sym_regex_c;
+static int is_abs_reloc(const char *sym_name)
+{
+	return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0);
+}
 
-static int is_safe_abs_reloc(const char* sym_name)
+/*
+ * These symbols are known to be relative, even if the linker marks them
+ * as absolute (typically defined outside any section in the linker script.)
+ */
+static const char rel_sym_regex[] =
+	"^_end$";
+static regex_t rel_sym_regex_c;
+static int is_rel_reloc(const char *sym_name)
 {
-	int i;
+	return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0);
+}
 
-	for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) {
-		if (!strcmp(sym_name, safe_abs_relocs[i]))
-			/* Match found */
-			return 1;
-	}
-	if (strncmp(sym_name, "VDSO", 4) == 0)
-		return 1;
-	if (strncmp(sym_name, "__crc_", 6) == 0)
-		return 1;
-	return 0;
+static void regex_init(void)
+{
+        char errbuf[128];
+        int err;
+	
+        err = regcomp(&abs_sym_regex_c, abs_sym_regex,
+                      REG_EXTENDED|REG_NOSUB);
+        if (err) {
+                regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf);
+                die("%s", errbuf);
+        }
+
+        err = regcomp(&rel_sym_regex_c, rel_sym_regex,
+                      REG_EXTENDED|REG_NOSUB);
+        if (err) {
+                regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf);
+                die("%s", errbuf);
+        }
 }
 
 static void die(char *fmt, ...)
@@ -131,7 +156,7 @@ static const char *rel_type(unsigned typ
 #undef REL_TYPE
 	};
 	const char *name = "unknown type rel type name";
-	if (type < ARRAY_SIZE(type_name)) {
+	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
 		name = type_name[type];
 	}
 	return name;
@@ -448,7 +473,7 @@ static void print_absolute_relocs(void)
 			 * Before warning check if this absolute symbol
 			 * relocation is harmless.
 			 */
-			if (is_safe_abs_reloc(name))
+			if (is_abs_reloc(name) || is_rel_reloc(name))
 				continue;
 
 			if (!printed) {
@@ -501,21 +526,26 @@ static void walk_relocs(void (*visit)(El
 			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
 			r_type = ELF32_R_TYPE(rel->r_info);
 			/* Don't visit relocations to absolute symbols */
-			if (sym->st_shndx == SHN_ABS) {
+			if (sym->st_shndx == SHN_ABS &&
+			    !is_rel_reloc(sym_name(sym_strtab, sym))) {
 				continue;
 			}
-			if (r_type == R_386_NONE || r_type == R_386_PC32) {
+			switch (r_type) {
+			case R_386_NONE:
+			case R_386_PC32:
 				/*
 				 * NONE can be ignored and and PC relative
 				 * relocations don't need to be adjusted.
 				 */
-			}
-			else if (r_type == R_386_32) {
+				break;
+			case R_386_32:
 				/* Visit relocations that need to be adjusted */
 				visit(rel, sym);
-			}
-			else {
-				die("Unsupported relocation type: %d\n", r_type);
+				break;
+			default:
+				die("Unsupported relocation type: %s (%d)\n",
+				    rel_type(r_type), r_type);
+				break;
 			}
 		}
 	}
@@ -571,16 +601,15 @@ static void emit_relocs(int as_text)
 	}
 	else {
 		unsigned char buf[4];
-		buf[0] = buf[1] = buf[2] = buf[3] = 0;
 		/* Print a stop */
-		printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);
+		fwrite("\0\0\0\0", 4, 1, stdout);
 		/* Now print each relocation */
 		for (i = 0; i < reloc_count; i++) {
 			buf[0] = (relocs[i] >>  0) & 0xff;
 			buf[1] = (relocs[i] >>  8) & 0xff;
 			buf[2] = (relocs[i] >> 16) & 0xff;
 			buf[3] = (relocs[i] >> 24) & 0xff;
-			printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);
+			fwrite(buf, 4, 1, stdout);
 		}
 	}
 }
@@ -598,6 +627,8 @@ int main(int argc, char **argv)
 	FILE *fp;
 	int i;
 
+	regex_init();
+
 	show_absolute_syms = 0;
 	show_absolute_relocs = 0;
 	as_text = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/x86/boot/compressed/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/compressed/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
 
 #undef i386
 
+#include <asm/cache.h>
 #include <asm/page_types.h>
 
 #ifdef CONFIG_X86_64
@@ -46,7 +47,7 @@ SECTIONS
 		*(.data.*)
 		_edata = . ;
 	}
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.bss : {
 		_bss = . ;
 		*(.bss)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/header.S linux-libre-2.6.33-gnu1/arch/x86/boot/header.S
--- linux-libre-2.6.32-gnu1/arch/x86/boot/header.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/header.S	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
  */
 
 #include <asm/segment.h>
-#include <linux/utsrelease.h>
+#include <generated/utsrelease.h>
 #include <asm/boot.h>
 #include <asm/e820.h>
 #include <asm/page_types.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/version.c linux-libre-2.6.33-gnu1/arch/x86/boot/version.c
--- linux-libre-2.6.32-gnu1/arch/x86/boot/version.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/version.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,8 +13,8 @@
  */
 
 #include "boot.h"
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
+#include <generated/utsrelease.h>
+#include <generated/compile.h>
 
 const char kernel_version[] =
 	UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/boot/video.c linux-libre-2.6.33-gnu1/arch/x86/boot/video.c
--- linux-libre-2.6.32-gnu1/arch/x86/boot/video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/boot/video.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,12 @@ static void store_cursor_position(void)
 
 	boot_params.screen_info.orig_x = oreg.dl;
 	boot_params.screen_info.orig_y = oreg.dh;
+
+	if (oreg.ch & 0x20)
+		boot_params.screen_info.flags |= VIDEO_FLAGS_NOCURSOR;
+
+	if ((oreg.ch & 0x1f) > (oreg.cl & 0x1f))
+		boot_params.screen_info.flags |= VIDEO_FLAGS_NOCURSOR;
 }
 
 static void store_video_mode(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/crypto/aesni-intel_asm.S linux-libre-2.6.33-gnu1/arch/x86/crypto/aesni-intel_asm.S
--- linux-libre-2.6.32-gnu1/arch/x86/crypto/aesni-intel_asm.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/crypto/aesni-intel_asm.S	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/inst.h>
 
 .text
 
@@ -122,103 +123,72 @@ ENTRY(aesni_set_key)
 	movups 0x10(%rsi), %xmm2	# other user key
 	movaps %xmm2, (%rcx)
 	add $0x10, %rcx
-	# aeskeygenassist $0x1, %xmm2, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+	AESKEYGENASSIST 0x1 %xmm2 %xmm1		# round 1
 	call _key_expansion_256a
-	# aeskeygenassist $0x1, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	AESKEYGENASSIST 0x1 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	AESKEYGENASSIST 0x2 %xmm2 %xmm1		# round 2
 	call _key_expansion_256a
-	# aeskeygenassist $0x2, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	AESKEYGENASSIST 0x2 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	AESKEYGENASSIST 0x4 %xmm2 %xmm1		# round 3
 	call _key_expansion_256a
-	# aeskeygenassist $0x4, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	AESKEYGENASSIST 0x4 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	AESKEYGENASSIST 0x8 %xmm2 %xmm1		# round 4
 	call _key_expansion_256a
-	# aeskeygenassist $0x8, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	AESKEYGENASSIST 0x8 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	AESKEYGENASSIST 0x10 %xmm2 %xmm1	# round 5
 	call _key_expansion_256a
-	# aeskeygenassist $0x10, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	AESKEYGENASSIST 0x10 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	AESKEYGENASSIST 0x20 %xmm2 %xmm1	# round 6
 	call _key_expansion_256a
-	# aeskeygenassist $0x20, %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	AESKEYGENASSIST 0x20 %xmm0 %xmm1
 	call _key_expansion_256b
-	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	AESKEYGENASSIST 0x40 %xmm2 %xmm1	# round 7
 	call _key_expansion_256a
 	jmp .Ldec_key
 .Lenc_key192:
 	movq 0x10(%rsi), %xmm2		# other user key
-	# aeskeygenassist $0x1, %xmm2, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+	AESKEYGENASSIST 0x1 %xmm2 %xmm1		# round 1
 	call _key_expansion_192a
-	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	AESKEYGENASSIST 0x2 %xmm2 %xmm1		# round 2
 	call _key_expansion_192b
-	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	AESKEYGENASSIST 0x4 %xmm2 %xmm1		# round 3
 	call _key_expansion_192a
-	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	AESKEYGENASSIST 0x8 %xmm2 %xmm1		# round 4
 	call _key_expansion_192b
-	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	AESKEYGENASSIST 0x10 %xmm2 %xmm1	# round 5
 	call _key_expansion_192a
-	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	AESKEYGENASSIST 0x20 %xmm2 %xmm1	# round 6
 	call _key_expansion_192b
-	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	AESKEYGENASSIST 0x40 %xmm2 %xmm1	# round 7
 	call _key_expansion_192a
-	# aeskeygenassist $0x80, %xmm2, %xmm1	# round 8
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x80
+	AESKEYGENASSIST 0x80 %xmm2 %xmm1	# round 8
 	call _key_expansion_192b
 	jmp .Ldec_key
 .Lenc_key128:
-	# aeskeygenassist $0x1, %xmm0, %xmm1	# round 1
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	AESKEYGENASSIST 0x1 %xmm0 %xmm1		# round 1
 	call _key_expansion_128
-	# aeskeygenassist $0x2, %xmm0, %xmm1	# round 2
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	AESKEYGENASSIST 0x2 %xmm0 %xmm1		# round 2
 	call _key_expansion_128
-	# aeskeygenassist $0x4, %xmm0, %xmm1	# round 3
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	AESKEYGENASSIST 0x4 %xmm0 %xmm1		# round 3
 	call _key_expansion_128
-	# aeskeygenassist $0x8, %xmm0, %xmm1	# round 4
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	AESKEYGENASSIST 0x8 %xmm0 %xmm1		# round 4
 	call _key_expansion_128
-	# aeskeygenassist $0x10, %xmm0, %xmm1	# round 5
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	AESKEYGENASSIST 0x10 %xmm0 %xmm1	# round 5
 	call _key_expansion_128
-	# aeskeygenassist $0x20, %xmm0, %xmm1	# round 6
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	AESKEYGENASSIST 0x20 %xmm0 %xmm1	# round 6
 	call _key_expansion_128
-	# aeskeygenassist $0x40, %xmm0, %xmm1	# round 7
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x40
+	AESKEYGENASSIST 0x40 %xmm0 %xmm1	# round 7
 	call _key_expansion_128
-	# aeskeygenassist $0x80, %xmm0, %xmm1	# round 8
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x80
+	AESKEYGENASSIST 0x80 %xmm0 %xmm1	# round 8
 	call _key_expansion_128
-	# aeskeygenassist $0x1b, %xmm0, %xmm1	# round 9
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x1b
+	AESKEYGENASSIST 0x1b %xmm0 %xmm1	# round 9
 	call _key_expansion_128
-	# aeskeygenassist $0x36, %xmm0, %xmm1	# round 10
-	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x36
+	AESKEYGENASSIST 0x36 %xmm0 %xmm1	# round 10
 	call _key_expansion_128
 .Ldec_key:
 	sub $0x10, %rcx
@@ -231,8 +201,7 @@ ENTRY(aesni_set_key)
 .align 4
 .Ldec_key_loop:
 	movaps (%rdi), %xmm0
-	# aesimc %xmm0, %xmm1
-	.byte 0x66, 0x0f, 0x38, 0xdb, 0xc8
+	AESIMC %xmm0 %xmm1
 	movaps %xmm1, (%rsi)
 	add $0x10, %rdi
 	sub $0x10, %rsi
@@ -274,51 +243,37 @@ _aesni_enc1:
 	je .Lenc192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x50(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 .align 4
 .Lenc192:
 	movaps -0x40(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x30(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 .align 4
 .Lenc128:
 	movaps -0x20(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps -0x10(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps (TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x10(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x20(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x30(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x40(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x50(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x60(TKEYP), KEY
-	# aesenc KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	AESENC KEY STATE
 	movaps 0x70(TKEYP), KEY
-	# aesenclast KEY, STATE	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
+	AESENCLAST KEY STATE
 	ret
 
 /*
@@ -353,135 +308,79 @@ _aesni_enc4:
 	je .L4enc192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x50(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 #.align 4
 .L4enc192:
 	movaps -0x40(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x30(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 #.align 4
 .L4enc128:
 	movaps -0x20(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps -0x10(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps (TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x10(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x20(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x30(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x40(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x50(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x60(TKEYP), KEY
-	# aesenc KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
-	# aesenc KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
-	# aesenc KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xea
-	# aesenc KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+	AESENC KEY STATE1
+	AESENC KEY STATE2
+	AESENC KEY STATE3
+	AESENC KEY STATE4
 	movaps 0x70(TKEYP), KEY
-	# aesenclast KEY, STATE1	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
-	# aesenclast KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xe2
-	# aesenclast KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xea
-	# aesenclast KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdd, 0xf2
+	AESENCLAST KEY STATE1		# last round
+	AESENCLAST KEY STATE2
+	AESENCLAST KEY STATE3
+	AESENCLAST KEY STATE4
 	ret
 
 /*
@@ -518,51 +417,37 @@ _aesni_dec1:
 	je .Ldec192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x50(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 .align 4
 .Ldec192:
 	movaps -0x40(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x30(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 .align 4
 .Ldec128:
 	movaps -0x20(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps -0x10(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps (TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x10(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x20(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x30(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x40(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x50(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x60(TKEYP), KEY
-	# aesdec KEY, STATE
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	AESDEC KEY STATE
 	movaps 0x70(TKEYP), KEY
-	# aesdeclast KEY, STATE		# last round
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
+	AESDECLAST KEY STATE
 	ret
 
 /*
@@ -597,135 +482,79 @@ _aesni_dec4:
 	je .L4dec192
 	add $0x20, TKEYP
 	movaps -0x60(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x50(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 .align 4
 .L4dec192:
 	movaps -0x40(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x30(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 .align 4
 .L4dec128:
 	movaps -0x20(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps -0x10(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps (TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x10(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x20(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x30(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x40(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x50(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x60(TKEYP), KEY
-	# aesdec KEY, STATE1
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
-	# aesdec KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xe2
-	# aesdec KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xea
-	# aesdec KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+	AESDEC KEY STATE1
+	AESDEC KEY STATE2
+	AESDEC KEY STATE3
+	AESDEC KEY STATE4
 	movaps 0x70(TKEYP), KEY
-	# aesdeclast KEY, STATE1	# last round
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
-	# aesdeclast KEY, STATE2
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xe2
-	# aesdeclast KEY, STATE3
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xea
-	# aesdeclast KEY, STATE4
-	.byte 0x66, 0x0f, 0x38, 0xdf, 0xf2
+	AESDECLAST KEY STATE1		# last round
+	AESDECLAST KEY STATE2
+	AESDECLAST KEY STATE3
+	AESDECLAST KEY STATE4
 	ret
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/crypto/ghash-clmulni-intel_asm.S linux-libre-2.6.33-gnu1/arch/x86/crypto/ghash-clmulni-intel_asm.S
--- linux-libre-2.6.32-gnu1/arch/x86/crypto/ghash-clmulni-intel_asm.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/crypto/ghash-clmulni-intel_asm.S	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,157 @@
+/*
+ * Accelerated GHASH implementation with Intel PCLMULQDQ-NI
+ * instructions. This file contains accelerated part of ghash
+ * implementation. More information about PCLMULQDQ can be found at:
+ *
+ * http://software.intel.com/en-us/articles/carry-less-multiplication-and-its-usage-for-computing-the-gcm-mode/
+ *
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang@intel.com>
+ *	     Vinodh Gopal
+ *	     Erdinc Ozturk
+ *	     Deniz Karakoyunlu
+ *
+ * This 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 <asm/inst.h>
+
+.data
+
+.align 16
+.Lbswap_mask:
+	.octa 0x000102030405060708090a0b0c0d0e0f
+.Lpoly:
+	.octa 0xc2000000000000000000000000000001
+.Ltwo_one:
+	.octa 0x00000001000000000000000000000001
+
+#define DATA	%xmm0
+#define SHASH	%xmm1
+#define T1	%xmm2
+#define T2	%xmm3
+#define T3	%xmm4
+#define BSWAP	%xmm5
+#define IN1	%xmm6
+
+.text
+
+/*
+ * __clmul_gf128mul_ble:	internal ABI
+ * input:
+ *	DATA:			operand1
+ *	SHASH:			operand2, hash_key << 1 mod poly
+ * output:
+ *	DATA:			operand1 * operand2 mod poly
+ * changed:
+ *	T1
+ *	T2
+ *	T3
+ */
+__clmul_gf128mul_ble:
+	movaps DATA, T1
+	pshufd $0b01001110, DATA, T2
+	pshufd $0b01001110, SHASH, T3
+	pxor DATA, T2
+	pxor SHASH, T3
+
+	PCLMULQDQ 0x00 SHASH DATA	# DATA = a0 * b0
+	PCLMULQDQ 0x11 SHASH T1		# T1 = a1 * b1
+	PCLMULQDQ 0x00 T3 T2		# T2 = (a1 + a0) * (b1 + b0)
+	pxor DATA, T2
+	pxor T1, T2			# T2 = a0 * b1 + a1 * b0
+
+	movaps T2, T3
+	pslldq $8, T3
+	psrldq $8, T2
+	pxor T3, DATA
+	pxor T2, T1			# <T1:DATA> is result of
+					# carry-less multiplication
+
+	# first phase of the reduction
+	movaps DATA, T3
+	psllq $1, T3
+	pxor DATA, T3
+	psllq $5, T3
+	pxor DATA, T3
+	psllq $57, T3
+	movaps T3, T2
+	pslldq $8, T2
+	psrldq $8, T3
+	pxor T2, DATA
+	pxor T3, T1
+
+	# second phase of the reduction
+	movaps DATA, T2
+	psrlq $5, T2
+	pxor DATA, T2
+	psrlq $1, T2
+	pxor DATA, T2
+	psrlq $1, T2
+	pxor T2, T1
+	pxor T1, DATA
+	ret
+
+/* void clmul_ghash_mul(char *dst, const be128 *shash) */
+ENTRY(clmul_ghash_mul)
+	movups (%rdi), DATA
+	movups (%rsi), SHASH
+	movaps .Lbswap_mask, BSWAP
+	PSHUFB_XMM BSWAP DATA
+	call __clmul_gf128mul_ble
+	PSHUFB_XMM BSWAP DATA
+	movups DATA, (%rdi)
+	ret
+
+/*
+ * void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
+ *			   const be128 *shash);
+ */
+ENTRY(clmul_ghash_update)
+	cmp $16, %rdx
+	jb .Lupdate_just_ret	# check length
+	movaps .Lbswap_mask, BSWAP
+	movups (%rdi), DATA
+	movups (%rcx), SHASH
+	PSHUFB_XMM BSWAP DATA
+.align 4
+.Lupdate_loop:
+	movups (%rsi), IN1
+	PSHUFB_XMM BSWAP IN1
+	pxor IN1, DATA
+	call __clmul_gf128mul_ble
+	sub $16, %rdx
+	add $16, %rsi
+	cmp $16, %rdx
+	jge .Lupdate_loop
+	PSHUFB_XMM BSWAP DATA
+	movups DATA, (%rdi)
+.Lupdate_just_ret:
+	ret
+
+/*
+ * void clmul_ghash_setkey(be128 *shash, const u8 *key);
+ *
+ * Calculate hash_key << 1 mod poly
+ */
+ENTRY(clmul_ghash_setkey)
+	movaps .Lbswap_mask, BSWAP
+	movups (%rsi), %xmm0
+	PSHUFB_XMM BSWAP %xmm0
+	movaps %xmm0, %xmm1
+	psllq $1, %xmm0
+	psrlq $63, %xmm1
+	movaps %xmm1, %xmm2
+	pslldq $8, %xmm1
+	psrldq $8, %xmm2
+	por %xmm1, %xmm0
+	# reduction
+	pshufd $0b00100100, %xmm2, %xmm1
+	pcmpeqd .Ltwo_one, %xmm1
+	pand .Lpoly, %xmm1
+	pxor %xmm1, %xmm0
+	movups %xmm0, (%rdi)
+	ret
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/crypto/ghash-clmulni-intel_glue.c linux-libre-2.6.33-gnu1/arch/x86/crypto/ghash-clmulni-intel_glue.c
--- linux-libre-2.6.32-gnu1/arch/x86/crypto/ghash-clmulni-intel_glue.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/crypto/ghash-clmulni-intel_glue.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,333 @@
+/*
+ * Accelerated GHASH implementation with Intel PCLMULQDQ-NI
+ * instructions. This file contains glue code.
+ *
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang@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/init.h>
+#include <linux/kernel.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <crypto/cryptd.h>
+#include <crypto/gf128mul.h>
+#include <crypto/internal/hash.h>
+#include <asm/i387.h>
+
+#define GHASH_BLOCK_SIZE	16
+#define GHASH_DIGEST_SIZE	16
+
+void clmul_ghash_mul(char *dst, const be128 *shash);
+
+void clmul_ghash_update(char *dst, const char *src, unsigned int srclen,
+			const be128 *shash);
+
+void clmul_ghash_setkey(be128 *shash, const u8 *key);
+
+struct ghash_async_ctx {
+	struct cryptd_ahash *cryptd_tfm;
+};
+
+struct ghash_ctx {
+	be128 shash;
+};
+
+struct ghash_desc_ctx {
+	u8 buffer[GHASH_BLOCK_SIZE];
+	u32 bytes;
+};
+
+static int ghash_init(struct shash_desc *desc)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static int ghash_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
+
+	if (keylen != GHASH_BLOCK_SIZE) {
+		crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
+	clmul_ghash_setkey(&ctx->shash, key);
+
+	return 0;
+}
+
+static int ghash_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *dst = dctx->buffer;
+
+	kernel_fpu_begin();
+	if (dctx->bytes) {
+		int n = min(srclen, dctx->bytes);
+		u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		dctx->bytes -= n;
+		srclen -= n;
+
+		while (n--)
+			*pos++ ^= *src++;
+
+		if (!dctx->bytes)
+			clmul_ghash_mul(dst, &ctx->shash);
+	}
+
+	clmul_ghash_update(dst, src, srclen, &ctx->shash);
+	kernel_fpu_end();
+
+	if (srclen & 0xf) {
+		src += srclen - (srclen & 0xf);
+		srclen &= 0xf;
+		dctx->bytes = GHASH_BLOCK_SIZE - srclen;
+		while (srclen--)
+			*dst++ ^= *src++;
+	}
+
+	return 0;
+}
+
+static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
+{
+	u8 *dst = dctx->buffer;
+
+	if (dctx->bytes) {
+		u8 *tmp = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		while (dctx->bytes--)
+			*tmp++ ^= 0;
+
+		kernel_fpu_begin();
+		clmul_ghash_mul(dst, &ctx->shash);
+		kernel_fpu_end();
+	}
+
+	dctx->bytes = 0;
+}
+
+static int ghash_final(struct shash_desc *desc, u8 *dst)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *buf = dctx->buffer;
+
+	ghash_flush(ctx, dctx);
+	memcpy(dst, buf, GHASH_BLOCK_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg ghash_alg = {
+	.digestsize	= GHASH_DIGEST_SIZE,
+	.init		= ghash_init,
+	.update		= ghash_update,
+	.final		= ghash_final,
+	.setkey		= ghash_setkey,
+	.descsize	= sizeof(struct ghash_desc_ctx),
+	.base		= {
+		.cra_name		= "__ghash",
+		.cra_driver_name	= "__ghash-pclmulqdqni",
+		.cra_priority		= 0,
+		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		= GHASH_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct ghash_ctx),
+		.cra_module		= THIS_MODULE,
+		.cra_list		= LIST_HEAD_INIT(ghash_alg.base.cra_list),
+	},
+};
+
+static int ghash_async_init(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+	if (!irq_fpu_usable()) {
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_init(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+		desc->tfm = child;
+		desc->flags = req->base.flags;
+		return crypto_shash_init(desc);
+	}
+}
+
+static int ghash_async_update(struct ahash_request *req)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+	if (!irq_fpu_usable()) {
+		struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+		struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+		struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_update(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		return shash_ahash_update(req, desc);
+	}
+}
+
+static int ghash_async_final(struct ahash_request *req)
+{
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+
+	if (!irq_fpu_usable()) {
+		struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+		struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+		struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_final(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		return crypto_shash_final(desc, req->result);
+	}
+}
+
+static int ghash_async_digest(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct ahash_request *cryptd_req = ahash_request_ctx(req);
+	struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
+
+	if (!irq_fpu_usable()) {
+		memcpy(cryptd_req, req, sizeof(*req));
+		ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
+		return crypto_ahash_digest(cryptd_req);
+	} else {
+		struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
+		struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
+
+		desc->tfm = child;
+		desc->flags = req->base.flags;
+		return shash_ahash_digest(req, desc);
+	}
+}
+
+static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
+			      unsigned int keylen)
+{
+	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct crypto_ahash *child = &ctx->cryptd_tfm->base;
+	int err;
+
+	crypto_ahash_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_ahash_set_flags(child, crypto_ahash_get_flags(tfm)
+			       & CRYPTO_TFM_REQ_MASK);
+	err = crypto_ahash_setkey(child, key, keylen);
+	crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child)
+			       & CRYPTO_TFM_RES_MASK);
+
+	return 0;
+}
+
+static int ghash_async_init_tfm(struct crypto_tfm *tfm)
+{
+	struct cryptd_ahash *cryptd_tfm;
+	struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	cryptd_tfm = cryptd_alloc_ahash("__ghash-pclmulqdqni", 0, 0);
+	if (IS_ERR(cryptd_tfm))
+		return PTR_ERR(cryptd_tfm);
+	ctx->cryptd_tfm = cryptd_tfm;
+	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+				 sizeof(struct ahash_request) +
+				 crypto_ahash_reqsize(&cryptd_tfm->base));
+
+	return 0;
+}
+
+static void ghash_async_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct ghash_async_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	cryptd_free_ahash(ctx->cryptd_tfm);
+}
+
+static struct ahash_alg ghash_async_alg = {
+	.init		= ghash_async_init,
+	.update		= ghash_async_update,
+	.final		= ghash_async_final,
+	.setkey		= ghash_async_setkey,
+	.digest		= ghash_async_digest,
+	.halg = {
+		.digestsize	= GHASH_DIGEST_SIZE,
+		.base = {
+			.cra_name		= "ghash",
+			.cra_driver_name	= "ghash-clmulni",
+			.cra_priority		= 400,
+			.cra_flags		= CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+			.cra_blocksize		= GHASH_BLOCK_SIZE,
+			.cra_type		= &crypto_ahash_type,
+			.cra_module		= THIS_MODULE,
+			.cra_list		= LIST_HEAD_INIT(ghash_async_alg.halg.base.cra_list),
+			.cra_init		= ghash_async_init_tfm,
+			.cra_exit		= ghash_async_exit_tfm,
+		},
+	},
+};
+
+static int __init ghash_pclmulqdqni_mod_init(void)
+{
+	int err;
+
+	if (!cpu_has_pclmulqdq) {
+		printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
+		       " detected.\n");
+		return -ENODEV;
+	}
+
+	err = crypto_register_shash(&ghash_alg);
+	if (err)
+		goto err_out;
+	err = crypto_register_ahash(&ghash_async_alg);
+	if (err)
+		goto err_shash;
+
+	return 0;
+
+err_shash:
+	crypto_unregister_shash(&ghash_alg);
+err_out:
+	return err;
+}
+
+static void __exit ghash_pclmulqdqni_mod_exit(void)
+{
+	crypto_unregister_ahash(&ghash_async_alg);
+	crypto_unregister_shash(&ghash_alg);
+}
+
+module_init(ghash_pclmulqdqni_mod_init);
+module_exit(ghash_pclmulqdqni_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GHASH Message Digest Algorithm, "
+		   "acclerated by PCLMULQDQ-NI");
+MODULE_ALIAS("ghash");
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/crypto/Makefile linux-libre-2.6.33-gnu1/arch/x86/crypto/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/crypto/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/crypto/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@ obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x
 obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
 obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
 obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
+obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
 
@@ -24,3 +25,5 @@ twofish-x86_64-y := twofish-x86_64-asm_6
 salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
 
 aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
+
+ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/ia32/ia32_aout.c linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32_aout.c
--- linux-libre-2.6.32-gnu1/arch/x86/ia32/ia32_aout.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32_aout.c	2010-02-24 13:52:17.000000000 -0500
@@ -308,14 +308,15 @@ static int load_aout_binary(struct linux
 	if (retval)
 		return retval;
 
-	regs->cs = __USER32_CS;
-	regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
-		regs->r13 = regs->r14 = regs->r15 = 0;
-
 	/* OK, This is the point of no return */
 	set_personality(PER_LINUX);
 	set_thread_flag(TIF_IA32);
-	clear_thread_flag(TIF_ABI_PENDING);
+
+	setup_new_exec(bprm);
+
+	regs->cs = __USER32_CS;
+	regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
+		regs->r13 = regs->r14 = regs->r15 = 0;
 
 	current->mm->end_code = ex.a_text +
 		(current->mm->start_code = N_TXTADDR(ex));
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/ia32/ia32entry.S linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32entry.S
--- linux-libre-2.6.32-gnu1/arch/x86/ia32/ia32entry.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/ia32/ia32entry.S	2010-02-24 13:52:17.000000000 -0500
@@ -653,7 +653,7 @@ ia32_sys_call_table:
 	.quad compat_sys_writev
 	.quad sys_getsid
 	.quad sys_fdatasync
-	.quad sys32_sysctl	/* sysctl */
+	.quad compat_sys_sysctl	/* sysctl */
 	.quad sys_mlock		/* 150 */
 	.quad sys_munlock
 	.quad sys_mlockall
@@ -696,7 +696,7 @@ ia32_sys_call_table:
 	.quad quiet_ni_syscall		/* streams2 */
 	.quad stub32_vfork            /* 190 */
 	.quad compat_sys_getrlimit
-	.quad sys32_mmap2
+	.quad sys_mmap_pgoff
 	.quad sys32_truncate64
 	.quad sys32_ftruncate64
 	.quad sys32_stat64		/* 195 */
@@ -841,4 +841,5 @@ ia32_sys_call_table:
 	.quad compat_sys_pwritev
 	.quad compat_sys_rt_tgsigqueueinfo	/* 335 */
 	.quad sys_perf_event_open
+	.quad compat_sys_recvmmsg
 ia32_syscall_end:
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/ia32/sys_ia32.c linux-libre-2.6.33-gnu1/arch/x86/ia32/sys_ia32.c
--- linux-libre-2.6.32-gnu1/arch/x86/ia32/sys_ia32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/ia32/sys_ia32.c	2010-02-24 13:52:17.000000000 -0500
@@ -155,9 +155,6 @@ struct mmap_arg_struct {
 asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
 {
 	struct mmap_arg_struct a;
-	struct file *file = NULL;
-	unsigned long retval;
-	struct mm_struct *mm ;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
 		return -EFAULT;
@@ -165,22 +162,8 @@ asmlinkage long sys32_mmap(struct mmap_a
 	if (a.offset & ~PAGE_MASK)
 		return -EINVAL;
 
-	if (!(a.flags & MAP_ANONYMOUS)) {
-		file = fget(a.fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	mm = current->mm;
-	down_write(&mm->mmap_sem);
-	retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags,
+	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
 			       a.offset>>PAGE_SHIFT);
-	if (file)
-		fput(file);
-
-	up_write(&mm->mmap_sem);
-
-	return retval;
 }
 
 asmlinkage long sys32_mprotect(unsigned long start, size_t len,
@@ -434,62 +417,6 @@ asmlinkage long sys32_rt_sigqueueinfo(in
 	return ret;
 }
 
-#ifdef CONFIG_SYSCTL_SYSCALL
-struct sysctl_ia32 {
-	unsigned int	name;
-	int		nlen;
-	unsigned int	oldval;
-	unsigned int	oldlenp;
-	unsigned int	newval;
-	unsigned int	newlen;
-	unsigned int	__unused[4];
-};
-
-
-asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *args32)
-{
-	struct sysctl_ia32 a32;
-	mm_segment_t old_fs = get_fs();
-	void __user *oldvalp, *newvalp;
-	size_t oldlen;
-	int __user *namep;
-	long ret;
-
-	if (copy_from_user(&a32, args32, sizeof(a32)))
-		return -EFAULT;
-
-	/*
-	 * We need to pre-validate these because we have to disable
-	 * address checking before calling do_sysctl() because of
-	 * OLDLEN but we can't run the risk of the user specifying bad
-	 * addresses here.  Well, since we're dealing with 32 bit
-	 * addresses, we KNOW that access_ok() will always succeed, so
-	 * this is an expensive NOP, but so what...
-	 */
-	namep = compat_ptr(a32.name);
-	oldvalp = compat_ptr(a32.oldval);
-	newvalp =  compat_ptr(a32.newval);
-
-	if ((oldvalp && get_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
-	    || !access_ok(VERIFY_WRITE, namep, 0)
-	    || !access_ok(VERIFY_WRITE, oldvalp, 0)
-	    || !access_ok(VERIFY_WRITE, newvalp, 0))
-		return -EFAULT;
-
-	set_fs(KERNEL_DS);
-	lock_kernel();
-	ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen,
-			newvalp, (size_t) a32.newlen);
-	unlock_kernel();
-	set_fs(old_fs);
-
-	if (oldvalp && put_user(oldlen, (int __user *)compat_ptr(a32.oldlenp)))
-		return -EFAULT;
-
-	return ret;
-}
-#endif
-
 /* warning: next two assume little endian */
 asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count,
 			    u32 poslo, u32 poshi)
@@ -539,30 +466,6 @@ asmlinkage long sys32_sendfile(int out_f
 	return ret;
 }
 
-asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-			    unsigned long prot, unsigned long flags,
-			    unsigned long fd, unsigned long pgoff)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long error;
-	struct file *file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			return -EBADF;
-	}
-
-	down_write(&mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&mm->mmap_sem);
-
-	if (file)
-		fput(file);
-	return error;
-}
-
 asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
 {
 	char *arch = "x86_64";
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/acpi.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/acpi.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/acpi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/acpi.h	2010-02-24 13:52:17.000000000 -0500
@@ -118,7 +118,7 @@ extern void acpi_restore_state_mem(void)
 extern unsigned long acpi_wakeup_address;
 
 /* early initialization routine */
-extern void acpi_reserve_bootmem(void);
+extern void acpi_reserve_wakeup_memory(void);
 
 /*
  * Check if the CPU can handle C2 and deeper
@@ -142,6 +142,32 @@ static inline unsigned int acpi_processo
 		return max_cstate;
 }
 
+static inline bool arch_has_acpi_pdc(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	return (c->x86_vendor == X86_VENDOR_INTEL ||
+		c->x86_vendor == X86_VENDOR_CENTAUR);
+}
+
+static inline void arch_acpi_set_pdc_bits(u32 *buf)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	buf[2] |= ACPI_PDC_C_CAPABILITY_SMP;
+
+	if (cpu_has(c, X86_FEATURE_EST))
+		buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
+
+	if (cpu_has(c, X86_FEATURE_ACPI))
+		buf[2] |= ACPI_PDC_T_FFH;
+
+	/*
+	 * If mwait/monitor is unsupported, C2/C3_FFH will be disabled
+	 */
+	if (!cpu_has(c, X86_FEATURE_MWAIT))
+		buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
+}
+
 #else /* !CONFIG_ACPI */
 
 #define acpi_lapic 0
@@ -158,6 +184,7 @@ struct bootnode;
 
 #ifdef CONFIG_ACPI_NUMA
 extern int acpi_numa;
+extern int acpi_get_nodes(struct bootnode *physnodes);
 extern int acpi_scan_nodes(unsigned long start, unsigned long end);
 #define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
 extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/alternative-asm.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/alternative-asm.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/alternative-asm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/alternative-asm.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,17 +1,13 @@
 #ifdef __ASSEMBLY__
 
-#ifdef CONFIG_X86_32
-# define X86_ALIGN .long
-#else
-# define X86_ALIGN .quad
-#endif
+#include <asm/asm.h>
 
 #ifdef CONFIG_SMP
 	.macro LOCK_PREFIX
 1:	lock
 	.section .smp_locks,"a"
-	.align 4
-	X86_ALIGN 1b
+	_ASM_ALIGN
+	_ASM_PTR 1b
 	.previous
 	.endm
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/alternative.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/alternative.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/alternative.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/alternative.h	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,7 @@ static inline void alternatives_smp_swit
       "	 .byte " __stringify(feature) "\n"	/* feature bit     */	\
       "	 .byte 662b-661b\n"			/* sourcelen       */	\
       "	 .byte 664f-663f\n"			/* replacementlen  */	\
+      "	 .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */	\
       ".previous\n"							\
       ".section .altinstr_replacement, \"ax\"\n"			\
       "663:\n\t" newinstr "\n664:\n"		/* replacement     */	\
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
@@ -23,19 +23,13 @@
 #include <linux/irqreturn.h>
 
 #ifdef CONFIG_AMD_IOMMU
-extern int amd_iommu_init(void);
-extern int amd_iommu_init_dma_ops(void);
-extern int amd_iommu_init_passthrough(void);
+
 extern void amd_iommu_detect(void);
-extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
-extern void amd_iommu_flush_all_domains(void);
-extern void amd_iommu_flush_all_devices(void);
-extern void amd_iommu_shutdown(void);
-extern void amd_iommu_apply_erratum_63(u16 devid);
+
 #else
-static inline int amd_iommu_init(void) { return -ENODEV; }
+
 static inline void amd_iommu_detect(void) { }
-static inline void amd_iommu_shutdown(void) { }
+
 #endif
 
 #endif /* _ASM_X86_AMD_IOMMU_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu_proto.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_proto.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu_proto.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_proto.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel <joerg.roedel@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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_X86_AMD_IOMMU_PROTO_H
+#define _ASM_X86_AMD_IOMMU_PROTO_H
+
+struct amd_iommu;
+
+extern int amd_iommu_init_dma_ops(void);
+extern int amd_iommu_init_passthrough(void);
+extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
+extern void amd_iommu_flush_all_domains(void);
+extern void amd_iommu_flush_all_devices(void);
+extern void amd_iommu_apply_erratum_63(u16 devid);
+extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
+extern int amd_iommu_init_devices(void);
+extern void amd_iommu_uninit_devices(void);
+extern void amd_iommu_init_notifier(void);
+extern void amd_iommu_init_api(void);
+#ifndef CONFIG_AMD_IOMMU_STATS
+
+static inline void amd_iommu_stats_init(void) { }
+
+#endif /* !CONFIG_AMD_IOMMU_STATS */
+
+#endif /* _ASM_X86_AMD_IOMMU_PROTO_H  */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu_types.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_types.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/amd_iommu_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/amd_iommu_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
@@ -25,6 +25,11 @@
 #include <linux/spinlock.h>
 
 /*
+ * Maximum number of IOMMUs supported
+ */
+#define MAX_IOMMUS	32
+
+/*
  * some size calculation constants
  */
 #define DEV_TABLE_ENTRY_SIZE		32
@@ -206,6 +211,9 @@ extern bool amd_iommu_dump;
 			printk(KERN_INFO "AMD-Vi: " format, ## arg);	\
 	} while(0);
 
+/* global flag if IOMMUs cache non-present entries */
+extern bool amd_iommu_np_cache;
+
 /*
  * Make iterating over all IOMMUs easier
  */
@@ -226,6 +234,8 @@ extern bool amd_iommu_dump;
  * independent of their use.
  */
 struct protection_domain {
+	struct list_head list;  /* for list of all protection domains */
+	struct list_head dev_list; /* List of all devices in this domain */
 	spinlock_t lock;	/* mostly used to lock the page table*/
 	u16 id;			/* the domain id written to the device table */
 	int mode;		/* paging mode (0-6 levels) */
@@ -233,7 +243,20 @@ struct protection_domain {
 	unsigned long flags;	/* flags to find out type of domain */
 	bool updated;		/* complete domain flush required */
 	unsigned dev_cnt;	/* devices assigned to this domain */
+	unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
 	void *priv;		/* private data */
+
+};
+
+/*
+ * This struct contains device specific data for the IOMMU
+ */
+struct iommu_dev_data {
+	struct list_head list;		  /* For domain->dev_list */
+	struct device *dev;		  /* Device this data belong to */
+	struct device *alias;		  /* The Alias Device */
+	struct protection_domain *domain; /* Domain the device is bound to */
+	atomic_t bind;			  /* Domain attach reverent count */
 };
 
 /*
@@ -291,6 +314,9 @@ struct dma_ops_domain {
 struct amd_iommu {
 	struct list_head list;
 
+	/* Index within the IOMMU array */
+	int index;
+
 	/* locks the accesses to the hardware */
 	spinlock_t lock;
 
@@ -357,6 +383,21 @@ struct amd_iommu {
 extern struct list_head amd_iommu_list;
 
 /*
+ * Array with pointers to each IOMMU struct
+ * The indices are referenced in the protection domains
+ */
+extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
+
+/* Number of IOMMUs present in the system */
+extern int amd_iommus_present;
+
+/*
+ * Declarations for the global list of all protection domains
+ */
+extern spinlock_t amd_iommu_pd_lock;
+extern struct list_head amd_iommu_pd_list;
+
+/*
  * Structure defining one entry in the device table
  */
 struct dev_table_entry {
@@ -416,15 +457,9 @@ extern unsigned amd_iommu_aperture_order
 /* largest PCI device id we expect translation requests for */
 extern u16 amd_iommu_last_bdf;
 
-/* data structures for protection domain handling */
-extern struct protection_domain **amd_iommu_pd_table;
-
 /* allocation bitmap for domain ids */
 extern unsigned long *amd_iommu_pd_alloc_bitmap;
 
-/* will be 1 if device isolation is enabled */
-extern bool amd_iommu_isolate;
-
 /*
  * If true, the addresses will be flushed on unmap time, not when
  * they are reused
@@ -462,11 +497,6 @@ struct __iommu_counter {
 #define ADD_STATS_COUNTER(name, x)
 #define SUB_STATS_COUNTER(name, x)
 
-static inline void amd_iommu_stats_init(void) { }
-
 #endif /* CONFIG_AMD_IOMMU_STATS */
 
-/* some function prototypes */
-extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
-
 #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/a.out-core.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/a.out-core.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/a.out-core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/a.out-core.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 
 #include <linux/user.h>
 #include <linux/elfcore.h>
+#include <asm/debugreg.h>
 
 /*
  * fill in the user structure for an a.out core dump
@@ -32,14 +33,7 @@ static inline void aout_dump_thread(stru
 			>> PAGE_SHIFT;
 	dump->u_dsize -= dump->u_tsize;
 	dump->u_ssize = 0;
-	dump->u_debugreg[0] = current->thread.debugreg0;
-	dump->u_debugreg[1] = current->thread.debugreg1;
-	dump->u_debugreg[2] = current->thread.debugreg2;
-	dump->u_debugreg[3] = current->thread.debugreg3;
-	dump->u_debugreg[4] = 0;
-	dump->u_debugreg[5] = 0;
-	dump->u_debugreg[6] = current->thread.debugreg6;
-	dump->u_debugreg[7] = current->thread.debugreg7;
+	aout_dump_debugregs(dump);
 
 	if (dump->start_stack < TASK_SIZE)
 		dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack))
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/apicdef.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/apicdef.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/apicdef.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/apicdef.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,12 @@
 #define IO_APIC_DEFAULT_PHYS_BASE	0xfec00000
 #define	APIC_DEFAULT_PHYS_BASE		0xfee00000
 
+/*
+ * This is the IO-APIC register space as specified
+ * by Intel docs:
+ */
+#define IO_APIC_SLOT_SIZE		1024
+
 #define	APIC_ID		0x20
 
 #define	APIC_LVR	0x30
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/apic.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/apic.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/apic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/apic.h	2010-02-24 13:52:17.000000000 -0500
@@ -297,20 +297,20 @@ struct apic {
 	int disable_esr;
 
 	int dest_logical;
-	unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
+	unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
 	unsigned long (*check_apicid_present)(int apicid);
 
 	void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
 	void (*init_apic_ldr)(void);
 
-	physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
+	void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
 
 	void (*setup_apic_routing)(void);
 	int (*multi_timer_check)(int apic, int irq);
 	int (*apicid_to_node)(int logical_apicid);
 	int (*cpu_to_logical_apicid)(int cpu);
 	int (*cpu_present_to_apicid)(int mps_cpu);
-	physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
+	void (*apicid_to_cpu_present)(int phys_apicid, physid_mask_t *retmap);
 	void (*setup_portio_remap)(void);
 	int (*check_phys_apicid_present)(int phys_apicid);
 	void (*enable_apic_mode)(void);
@@ -488,6 +488,8 @@ static inline unsigned int read_apic_id(
 
 extern void default_setup_apic_routing(void);
 
+extern struct apic apic_noop;
+
 #ifdef CONFIG_X86_32
 
 extern struct apic apic_default;
@@ -532,9 +534,9 @@ default_cpu_mask_to_apicid_and(const str
 	return (unsigned int)(mask1 & mask2 & mask3);
 }
 
-static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
+static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)
 {
-	return physid_isset(apicid, bitmap);
+	return physid_isset(apicid, *map);
 }
 
 static inline unsigned long default_check_apicid_present(int bit)
@@ -542,9 +544,9 @@ static inline unsigned long default_chec
 	return physid_isset(bit, phys_cpu_present_map);
 }
 
-static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map)
+static inline void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
 {
-	return phys_map;
+	*retmap = *phys_map;
 }
 
 /* Mapping from cpu number to logical apicid */
@@ -583,11 +585,6 @@ extern int default_cpu_present_to_apicid
 extern int default_check_phys_apicid_present(int phys_apicid);
 #endif
 
-static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
-{
-	return physid_mask_of_physid(phys_apicid);
-}
-
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_32
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/apicnum.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/apicnum.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/apicnum.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/apicnum.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_APICNUM_H
-#define _ASM_X86_APICNUM_H
-
-/* define MAX_IO_APICS */
-#ifdef CONFIG_X86_32
-# define MAX_IO_APICS 64
-#else
-# define MAX_IO_APICS 128
-# define MAX_LOCAL_APIC 32768
-#endif
-
-#endif /* _ASM_X86_APICNUM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/bug.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/bug.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/bug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/bug.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,14 +22,14 @@ do {								\
 		     ".popsection"				\
 		     : : "i" (__FILE__), "i" (__LINE__),	\
 		     "i" (sizeof(struct bug_entry)));		\
-	for (;;) ;						\
+	unreachable();						\
 } while (0)
 
 #else
 #define BUG()							\
 do {								\
 	asm volatile("ud2");					\
-	for (;;) ;						\
+	unreachable();						\
 } while (0)
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@ static inline void flush_cache_range(str
 				     unsigned long start, unsigned long end) { }
 static inline void flush_cache_page(struct vm_area_struct *vma,
 				    unsigned long vmaddr, unsigned long pfn) { }
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 static inline void flush_dcache_page(struct page *page) { }
 static inline void flush_dcache_mmap_lock(struct address_space *mapping) { }
 static inline void flush_dcache_mmap_unlock(struct address_space *mapping) { }
@@ -176,6 +177,7 @@ void clflush_cache_range(void *addr, uns
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 extern const int rodata_test_data;
+extern int kernel_set_to_readonly;
 void set_kernel_text_rw(void);
 void set_kernel_text_ro(void);
 #else
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cache.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cache.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cache.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cache.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,12 +9,13 @@
 
 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
 
+#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
+#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
+
 #ifdef CONFIG_X86_VSMP
-/* vSMP Internode cacheline shift */
-#define INTERNODE_CACHE_SHIFT (12)
 #ifdef CONFIG_SMP
 #define __cacheline_aligned_in_smp					\
-	__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))	\
+	__attribute__((__aligned__(INTERNODE_CACHE_BYTES)))		\
 	__page_aligned_data
 #endif
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/calgary.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/calgary.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/calgary.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/calgary.h	2010-02-24 13:52:17.000000000 -0500
@@ -62,10 +62,8 @@ struct cal_chipset_ops {
 extern int use_calgary;
 
 #ifdef CONFIG_CALGARY_IOMMU
-extern int calgary_iommu_init(void);
 extern void detect_calgary(void);
 #else
-static inline int calgary_iommu_init(void) { return 1; }
 static inline void detect_calgary(void) { return; }
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cmpxchg_32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cmpxchg_32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cmpxchg_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cmpxchg_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,14 +8,50 @@
  *       you need to test for the feature in boot_cpu_data.
  */
 
-#define xchg(ptr, v)							\
-	((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), sizeof(*(ptr))))
+extern void __xchg_wrong_size(void);
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ *	  but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
 
 struct __xchg_dummy {
 	unsigned long a[100];
 };
 #define __xg(x) ((struct __xchg_dummy *)(x))
 
+#define __xchg(x, ptr, size)						\
+({									\
+	__typeof(*(ptr)) __x = (x);					\
+	switch (size) {							\
+	case 1:								\
+		asm volatile("xchgb %b0,%1"				\
+			     : "=q" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	case 2:								\
+		asm volatile("xchgw %w0,%1"				\
+			     : "=r" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	case 4:								\
+		asm volatile("xchgl %0,%1"				\
+			     : "=r" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	default:							\
+		__xchg_wrong_size();					\
+	}								\
+	__x;								\
+})
+
+#define xchg(ptr, v)							\
+	__xchg((v), (ptr), sizeof(*ptr))
+
 /*
  * The semantics of XCHGCMP8B are a bit strange, this is why
  * there is a loop and the loading of %%eax and %%edx has to
@@ -71,57 +107,63 @@ static inline void __set_64bit_var(unsig
 		       (unsigned int)((value) >> 32))			\
 	 : __set_64bit(ptr, ll_low((value)), ll_high((value))))
 
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- *	  but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
-				   int size)
-{
-	switch (size) {
-	case 1:
-		asm volatile("xchgb %b0,%1"
-			     : "=q" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	case 2:
-		asm volatile("xchgw %w0,%1"
-			     : "=r" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	case 4:
-		asm volatile("xchgl %0,%1"
-			     : "=r" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	}
-	return x;
-}
+extern void __cmpxchg_wrong_size(void);
 
 /*
  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  * store NEW in MEM.  Return the initial value in MEM.  Success is
  * indicated by comparing RETURN with OLD.
  */
+#define __raw_cmpxchg(ptr, old, new, size, lock)			\
+({									\
+	__typeof__(*(ptr)) __ret;					\
+	__typeof__(*(ptr)) __old = (old);				\
+	__typeof__(*(ptr)) __new = (new);				\
+	switch (size) {							\
+	case 1:								\
+		asm volatile(lock "cmpxchgb %b1,%2"			\
+			     : "=a"(__ret)				\
+			     : "q"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	case 2:								\
+		asm volatile(lock "cmpxchgw %w1,%2"			\
+			     : "=a"(__ret)				\
+			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	case 4:								\
+		asm volatile(lock "cmpxchgl %1,%2"			\
+			     : "=a"(__ret)				\
+			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	default:							\
+		__cmpxchg_wrong_size();					\
+	}								\
+	__ret;								\
+})
+
+#define __cmpxchg(ptr, old, new, size)					\
+	__raw_cmpxchg((ptr), (old), (new), (size), LOCK_PREFIX)
+
+#define __sync_cmpxchg(ptr, old, new, size)				\
+	__raw_cmpxchg((ptr), (old), (new), (size), "lock; ")
+
+#define __cmpxchg_local(ptr, old, new, size)				\
+	__raw_cmpxchg((ptr), (old), (new), (size), "")
 
 #ifdef CONFIG_X86_CMPXCHG
 #define __HAVE_ARCH_CMPXCHG 1
-#define cmpxchg(ptr, o, n)						\
-	((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o),	\
-				       (unsigned long)(n),		\
-				       sizeof(*(ptr))))
-#define sync_cmpxchg(ptr, o, n)						\
-	((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o),	\
-					    (unsigned long)(n),		\
-					    sizeof(*(ptr))))
-#define cmpxchg_local(ptr, o, n)					\
-	((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o),	\
-					     (unsigned long)(n),	\
-					     sizeof(*(ptr))))
+
+#define cmpxchg(ptr, old, new)						\
+	__cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define sync_cmpxchg(ptr, old, new)					\
+	__sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define cmpxchg_local(ptr, old, new)					\
+	__cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
@@ -133,94 +175,6 @@ static inline unsigned long __xchg(unsig
 					       (unsigned long long)(n)))
 #endif
 
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-				      unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile(LOCK_PREFIX "cmpxchgl %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
-
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
-					   unsigned long old,
-					   unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile("lock; cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile("lock; cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile("lock; cmpxchgl %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
-
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
-					    unsigned long old,
-					    unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile("cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile("cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile("cmpxchgl %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
-
 static inline unsigned long long __cmpxchg64(volatile void *ptr,
 					     unsigned long long old,
 					     unsigned long long new)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cmpxchg_64.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cmpxchg_64.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cmpxchg_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cmpxchg_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,9 +3,6 @@
 
 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
 
-#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), \
-						 (ptr), sizeof(*(ptr))))
-
 #define __xg(x) ((volatile long *)(x))
 
 static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
@@ -15,167 +12,118 @@ static inline void set_64bit(volatile un
 
 #define _set_64bit set_64bit
 
+extern void __xchg_wrong_size(void);
+extern void __cmpxchg_wrong_size(void);
+
 /*
  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  * Note 2: xchg has side effect, so that attribute volatile is necessary,
  *	  but generally the primitive is invalid, *ptr is output argument. --ANK
  */
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
-				   int size)
-{
-	switch (size) {
-	case 1:
-		asm volatile("xchgb %b0,%1"
-			     : "=q" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	case 2:
-		asm volatile("xchgw %w0,%1"
-			     : "=r" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	case 4:
-		asm volatile("xchgl %k0,%1"
-			     : "=r" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	case 8:
-		asm volatile("xchgq %0,%1"
-			     : "=r" (x)
-			     : "m" (*__xg(ptr)), "0" (x)
-			     : "memory");
-		break;
-	}
-	return x;
-}
+#define __xchg(x, ptr, size)						\
+({									\
+	__typeof(*(ptr)) __x = (x);					\
+	switch (size) {							\
+	case 1:								\
+		asm volatile("xchgb %b0,%1"				\
+			     : "=q" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	case 2:								\
+		asm volatile("xchgw %w0,%1"				\
+			     : "=r" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	case 4:								\
+		asm volatile("xchgl %k0,%1"				\
+			     : "=r" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	case 8:								\
+		asm volatile("xchgq %0,%1"				\
+			     : "=r" (__x)				\
+			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "memory");				\
+		break;							\
+	default:							\
+		__xchg_wrong_size();					\
+	}								\
+	__x;								\
+})
+
+#define xchg(ptr, v)							\
+	__xchg((v), (ptr), sizeof(*ptr))
+
+#define __HAVE_ARCH_CMPXCHG 1
 
 /*
  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  * store NEW in MEM.  Return the initial value in MEM.  Success is
  * indicated by comparing RETURN with OLD.
  */
+#define __raw_cmpxchg(ptr, old, new, size, lock)			\
+({									\
+	__typeof__(*(ptr)) __ret;					\
+	__typeof__(*(ptr)) __old = (old);				\
+	__typeof__(*(ptr)) __new = (new);				\
+	switch (size) {							\
+	case 1:								\
+		asm volatile(lock "cmpxchgb %b1,%2"			\
+			     : "=a"(__ret)				\
+			     : "q"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	case 2:								\
+		asm volatile(lock "cmpxchgw %w1,%2"			\
+			     : "=a"(__ret)				\
+			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	case 4:								\
+		asm volatile(lock "cmpxchgl %k1,%2"			\
+			     : "=a"(__ret)				\
+			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	case 8:								\
+		asm volatile(lock "cmpxchgq %1,%2"			\
+			     : "=a"(__ret)				\
+			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+			     : "memory");				\
+		break;							\
+	default:							\
+		__cmpxchg_wrong_size();					\
+	}								\
+	__ret;								\
+})
 
-#define __HAVE_ARCH_CMPXCHG 1
+#define __cmpxchg(ptr, old, new, size)					\
+	__raw_cmpxchg((ptr), (old), (new), (size), LOCK_PREFIX)
 
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-				      unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile(LOCK_PREFIX "cmpxchgl %k1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 8:
-		asm volatile(LOCK_PREFIX "cmpxchgq %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
+#define __sync_cmpxchg(ptr, old, new, size)				\
+	__raw_cmpxchg((ptr), (old), (new), (size), "lock; ")
 
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
-					   unsigned long old,
-					   unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile("lock; cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile("lock; cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile("lock; cmpxchgl %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
+#define __cmpxchg_local(ptr, old, new, size)				\
+	__raw_cmpxchg((ptr), (old), (new), (size), "")
 
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
-					    unsigned long old,
-					    unsigned long new, int size)
-{
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		asm volatile("cmpxchgb %b1,%2"
-			     : "=a"(prev)
-			     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 2:
-		asm volatile("cmpxchgw %w1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 4:
-		asm volatile("cmpxchgl %k1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	case 8:
-		asm volatile("cmpxchgq %1,%2"
-			     : "=a"(prev)
-			     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-			     : "memory");
-		return prev;
-	}
-	return old;
-}
+#define cmpxchg(ptr, old, new)						\
+	__cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define sync_cmpxchg(ptr, old, new)					\
+	__sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+
+#define cmpxchg_local(ptr, old, new)					\
+	__cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
 
-#define cmpxchg(ptr, o, n)						\
-	((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o),	\
-				       (unsigned long)(n), sizeof(*(ptr))))
 #define cmpxchg64(ptr, o, n)						\
 ({									\
 	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
 	cmpxchg((ptr), (o), (n));					\
 })
-#define cmpxchg_local(ptr, o, n)					\
-	((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o),	\
-					     (unsigned long)(n),	\
-					     sizeof(*(ptr))))
-#define sync_cmpxchg(ptr, o, n)						\
-	((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o),	\
-					    (unsigned long)(n),		\
-					    sizeof(*(ptr))))
+
 #define cmpxchg64_local(ptr, o, n)					\
 ({									\
 	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cpu_debug.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpu_debug.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cpu_debug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpu_debug.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,127 +0,0 @@
-#ifndef _ASM_X86_CPU_DEBUG_H
-#define _ASM_X86_CPU_DEBUG_H
-
-/*
- * CPU x86 architecture debug
- *
- * Copyright(C) 2009 Jaswinder Singh Rajput
- */
-
-/* Register flags */
-enum cpu_debug_bit {
-/* Model Specific Registers (MSRs)					*/
-	CPU_MC_BIT,				/* Machine Check	*/
-	CPU_MONITOR_BIT,			/* Monitor		*/
-	CPU_TIME_BIT,				/* Time			*/
-	CPU_PMC_BIT,				/* Performance Monitor	*/
-	CPU_PLATFORM_BIT,			/* Platform		*/
-	CPU_APIC_BIT,				/* APIC			*/
-	CPU_POWERON_BIT,			/* Power-on		*/
-	CPU_CONTROL_BIT,			/* Control		*/
-	CPU_FEATURES_BIT,			/* Features control	*/
-	CPU_LBRANCH_BIT,			/* Last Branch		*/
-	CPU_BIOS_BIT,				/* BIOS			*/
-	CPU_FREQ_BIT,				/* Frequency		*/
-	CPU_MTTR_BIT,				/* MTRR			*/
-	CPU_PERF_BIT,				/* Performance		*/
-	CPU_CACHE_BIT,				/* Cache		*/
-	CPU_SYSENTER_BIT,			/* Sysenter		*/
-	CPU_THERM_BIT,				/* Thermal		*/
-	CPU_MISC_BIT,				/* Miscellaneous	*/
-	CPU_DEBUG_BIT,				/* Debug		*/
-	CPU_PAT_BIT,				/* PAT			*/
-	CPU_VMX_BIT,				/* VMX			*/
-	CPU_CALL_BIT,				/* System Call		*/
-	CPU_BASE_BIT,				/* BASE Address		*/
-	CPU_VER_BIT,				/* Version ID		*/
-	CPU_CONF_BIT,				/* Configuration	*/
-	CPU_SMM_BIT,				/* System mgmt mode	*/
-	CPU_SVM_BIT,				/*Secure Virtual Machine*/
-	CPU_OSVM_BIT,				/* OS-Visible Workaround*/
-/* Standard Registers							*/
-	CPU_TSS_BIT,				/* Task Stack Segment	*/
-	CPU_CR_BIT,				/* Control Registers	*/
-	CPU_DT_BIT,				/* Descriptor Table	*/
-/* End of Registers flags						*/
-	CPU_REG_ALL_BIT,			/* Select all Registers	*/
-};
-
-#define	CPU_REG_ALL		(~0)		/* Select all Registers	*/
-
-#define	CPU_MC			(1 << CPU_MC_BIT)
-#define	CPU_MONITOR		(1 << CPU_MONITOR_BIT)
-#define	CPU_TIME		(1 << CPU_TIME_BIT)
-#define	CPU_PMC			(1 << CPU_PMC_BIT)
-#define	CPU_PLATFORM		(1 << CPU_PLATFORM_BIT)
-#define	CPU_APIC		(1 << CPU_APIC_BIT)
-#define	CPU_POWERON		(1 << CPU_POWERON_BIT)
-#define	CPU_CONTROL		(1 << CPU_CONTROL_BIT)
-#define	CPU_FEATURES		(1 << CPU_FEATURES_BIT)
-#define	CPU_LBRANCH		(1 << CPU_LBRANCH_BIT)
-#define	CPU_BIOS		(1 << CPU_BIOS_BIT)
-#define	CPU_FREQ		(1 << CPU_FREQ_BIT)
-#define	CPU_MTRR		(1 << CPU_MTTR_BIT)
-#define	CPU_PERF		(1 << CPU_PERF_BIT)
-#define	CPU_CACHE		(1 << CPU_CACHE_BIT)
-#define	CPU_SYSENTER		(1 << CPU_SYSENTER_BIT)
-#define	CPU_THERM		(1 << CPU_THERM_BIT)
-#define	CPU_MISC		(1 << CPU_MISC_BIT)
-#define	CPU_DEBUG		(1 << CPU_DEBUG_BIT)
-#define	CPU_PAT			(1 << CPU_PAT_BIT)
-#define	CPU_VMX			(1 << CPU_VMX_BIT)
-#define	CPU_CALL		(1 << CPU_CALL_BIT)
-#define	CPU_BASE		(1 << CPU_BASE_BIT)
-#define	CPU_VER			(1 << CPU_VER_BIT)
-#define	CPU_CONF		(1 << CPU_CONF_BIT)
-#define	CPU_SMM			(1 << CPU_SMM_BIT)
-#define	CPU_SVM			(1 << CPU_SVM_BIT)
-#define	CPU_OSVM		(1 << CPU_OSVM_BIT)
-#define	CPU_TSS			(1 << CPU_TSS_BIT)
-#define	CPU_CR			(1 << CPU_CR_BIT)
-#define	CPU_DT			(1 << CPU_DT_BIT)
-
-/* Register file flags */
-enum cpu_file_bit {
-	CPU_INDEX_BIT,				/* index		*/
-	CPU_VALUE_BIT,				/* value		*/
-};
-
-#define	CPU_FILE_VALUE		(1 << CPU_VALUE_BIT)
-
-#define MAX_CPU_FILES		512
-
-struct cpu_private {
-	unsigned		cpu;
-	unsigned		type;
-	unsigned		reg;
-	unsigned		file;
-};
-
-struct cpu_debug_base {
-	char			*name;		/* Register name	*/
-	unsigned		flag;		/* Register flag	*/
-	unsigned		write;		/* Register write flag	*/
-};
-
-/*
- * Currently it looks similar to cpu_debug_base but once we add more files
- * cpu_file_base will go in different direction
- */
-struct cpu_file_base {
-	char			*name;		/* Register file name	*/
-	unsigned		flag;		/* Register file flag	*/
-	unsigned		write;		/* Register write flag	*/
-};
-
-struct cpu_cpuX_base {
-	struct dentry		*dentry;	/* Register dentry	*/
-	int			init;		/* Register index file	*/
-};
-
-struct cpu_debug_range {
-	unsigned		min;		/* Register range min	*/
-	unsigned		max;		/* Register range max	*/
-	unsigned		flag;		/* Supported flags	*/
-};
-
-#endif /* _ASM_X86_CPU_DEBUG_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/cpufeature.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpufeature.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/cpufeature.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/cpufeature.h	2010-02-24 13:52:17.000000000 -0500
@@ -153,6 +153,7 @@
 #define X86_FEATURE_SSE5	(6*32+11) /* SSE-5 */
 #define X86_FEATURE_SKINIT	(6*32+12) /* SKINIT/STGI instructions */
 #define X86_FEATURE_WDT		(6*32+13) /* Watchdog timer */
+#define X86_FEATURE_NODEID_MSR	(6*32+19) /* NodeId MSR */
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
@@ -248,6 +249,7 @@ extern const char * const x86_power_flag
 #define cpu_has_x2apic		boot_cpu_has(X86_FEATURE_X2APIC)
 #define cpu_has_xsave		boot_cpu_has(X86_FEATURE_XSAVE)
 #define cpu_has_hypervisor	boot_cpu_has(X86_FEATURE_HYPERVISOR)
+#define cpu_has_pclmulqdq	boot_cpu_has(X86_FEATURE_PCLMULQDQ)
 
 #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
 # define cpu_has_invlpg		1
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/debugreg.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/debugreg.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/debugreg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/debugreg.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #define DR_TRAP1	(0x2)		/* db1 */
 #define DR_TRAP2	(0x4)		/* db2 */
 #define DR_TRAP3	(0x8)		/* db3 */
+#define DR_TRAP_BITS	(DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)
 
 #define DR_STEP		(0x4000)	/* single-step */
 #define DR_SWITCH	(0x8000)	/* task switch */
@@ -49,6 +50,8 @@
 
 #define DR_LOCAL_ENABLE_SHIFT 0    /* Extra shift to the local enable bit */
 #define DR_GLOBAL_ENABLE_SHIFT 1   /* Extra shift to the global enable bit */
+#define DR_LOCAL_ENABLE (0x1)      /* Local enable for reg 0 */
+#define DR_GLOBAL_ENABLE (0x2)     /* Global enable for reg 0 */
 #define DR_ENABLE_SIZE 2           /* 2 enable bits per register */
 
 #define DR_LOCAL_ENABLE_MASK (0x55)  /* Set  local bits for all 4 regs */
@@ -67,4 +70,34 @@
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
+/*
+ * HW breakpoint additions
+ */
+#ifdef __KERNEL__
+
+DECLARE_PER_CPU(unsigned long, cpu_dr7);
+
+static inline void hw_breakpoint_disable(void)
+{
+	/* Zero the control register for HW Breakpoint */
+	set_debugreg(0UL, 7);
+
+	/* Zero-out the individual HW breakpoint address registers */
+	set_debugreg(0UL, 0);
+	set_debugreg(0UL, 1);
+	set_debugreg(0UL, 2);
+	set_debugreg(0UL, 3);
+}
+
+static inline int hw_breakpoint_active(void)
+{
+	return __get_cpu_var(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
+}
+
+extern void aout_dump_debugregs(struct user *dump);
+
+extern void hw_breakpoint_restore(void);
+
+#endif	/* __KERNEL__ */
+
 #endif /* _ASM_X86_DEBUGREG_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/desc_defs.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/desc_defs.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/desc_defs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/desc_defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,9 +12,9 @@
 #include <linux/types.h>
 
 /*
- * FIXME: Acessing the desc_struct through its fields is more elegant,
+ * FIXME: Accessing the desc_struct through its fields is more elegant,
  * and should be the one valid thing to do. However, a lot of open code
- * still touches the a and b acessors, and doing this allow us to do it
+ * still touches the a and b accessors, and doing this allow us to do it
  * incrementally. We keep the signature as a struct, rather than an union,
  * so we can get rid of it transparently in the future -- glommer
  */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/device.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/device.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/device.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/device.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@ struct dev_archdata {
 #ifdef CONFIG_X86_64
 struct dma_map_ops *dma_ops;
 #endif
-#ifdef CONFIG_DMAR
+#if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
 	void *iommu; /* hook for IOMMU specific extension */
 #endif
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/dma-mapping.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/dma-mapping.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/dma-mapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/dma-mapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,8 @@
 # define ISA_DMA_BIT_MASK DMA_BIT_MASK(32)
 #endif
 
-extern dma_addr_t bad_dma_address;
+#define DMA_ERROR_CODE	0
+
 extern int iommu_merge;
 extern struct device x86_dma_fallback_dev;
 extern int panic_on_overflow;
@@ -48,7 +49,7 @@ static inline int dma_mapping_error(stru
 	if (ops->mapping_error)
 		return ops->mapping_error(dev, dma_addr);
 
-	return (dma_addr == bad_dma_address);
+	return (dma_addr == DMA_ERROR_CODE);
 }
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
@@ -66,7 +67,7 @@ static inline bool dma_capable(struct de
 	if (!dev->dma_mask)
 		return 0;
 
-	return addr + size <= *dev->dma_mask;
+	return addr + size - 1 <= *dev->dma_mask;
 }
 
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/e820.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/e820.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/e820.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/e820.h	2010-02-24 13:52:17.000000000 -0500
@@ -61,6 +61,12 @@ struct e820map {
 	struct e820entry map[E820_X_MAX];
 };
 
+#define ISA_START_ADDRESS	0xa0000
+#define ISA_END_ADDRESS		0x100000
+
+#define BIOS_BEGIN		0x000a0000
+#define BIOS_END		0x00100000
+
 #ifdef __KERNEL__
 /* see comment in arch/x86/kernel/e820.c */
 extern struct e820map e820;
@@ -126,15 +132,18 @@ extern void e820_reserve_resources(void)
 extern void e820_reserve_resources_late(void);
 extern void setup_memory_map(void);
 extern char *default_machine_specific_memory_setup(void);
-#endif /* __KERNEL__ */
-#endif /* __ASSEMBLY__ */
 
-#define ISA_START_ADDRESS	0xa0000
-#define ISA_END_ADDRESS		0x100000
-#define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
+/*
+ * Returns true iff the specified range [s,e) is completely contained inside
+ * the ISA region.
+ */
+static inline bool is_ISA_range(u64 s, u64 e)
+{
+	return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS;
+}
 
-#define BIOS_BEGIN		0x000a0000
-#define BIOS_END		0x00100000
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
 
 #ifdef __KERNEL__
 #include <linux/ioport.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -157,19 +157,6 @@ do {						\
 
 #define compat_elf_check_arch(x)	elf_check_arch_ia32(x)
 
-static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
-{
-	loadsegment(fs, 0);
-	loadsegment(ds, __USER32_DS);
-	loadsegment(es, __USER32_DS);
-	load_gs_index(0);
-	regs->ip = ip;
-	regs->sp = sp;
-	regs->flags = X86_EFLAGS_IF;
-	regs->cs = __USER32_CS;
-	regs->ss = __USER32_DS;
-}
-
 static inline void elf_common_init(struct thread_struct *t,
 				   struct pt_regs *regs, const u16 ds)
 {
@@ -183,28 +170,16 @@ static inline void elf_common_init(struc
 }
 
 #define ELF_PLAT_INIT(_r, load_addr)			\
-do {							\
-	elf_common_init(&current->thread, _r, 0);	\
-	clear_thread_flag(TIF_IA32);			\
-} while (0)
+	elf_common_init(&current->thread, _r, 0)
 
 #define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
 	elf_common_init(&current->thread, regs, __USER_DS)
 
-#define	compat_start_thread(regs, ip, sp)		\
-do {							\
-	start_ia32_thread(regs, ip, sp);		\
-	set_fs(USER_DS);				\
-} while (0)
+void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
+#define compat_start_thread start_thread_ia32
 
-#define COMPAT_SET_PERSONALITY(ex)			\
-do {							\
-	if (test_thread_flag(TIF_IA32))			\
-		clear_thread_flag(TIF_ABI_PENDING);	\
-	else						\
-		set_thread_flag(TIF_ABI_PENDING);	\
-	current->personality |= force_personality32;	\
-} while (0)
+void set_personality_ia32(void);
+#define COMPAT_SET_PERSONALITY(ex) set_personality_ia32()
 
 #define COMPAT_ELF_PLATFORM			("i686")
 
@@ -255,7 +230,6 @@ extern int force_personality32;
 #endif /* !CONFIG_X86_32 */
 
 #define CORE_DUMP_USE_REGSET
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/entry_arch.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/entry_arch.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/entry_arch.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/entry_arch.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@ BUILD_INTERRUPT3(invalidate_interrupt7,I
 		 smp_invalidate_interrupt)
 #endif
 
-BUILD_INTERRUPT(generic_interrupt, GENERIC_INTERRUPT_VECTOR)
+BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
 
 /*
  * every pentium local APIC has two 'local interrupts', with a
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/gart.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/gart.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/gart.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/gart.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,8 +35,7 @@ extern int gart_iommu_aperture_allowed;
 extern int gart_iommu_aperture_disabled;
 
 extern void early_gart_iommu_check(void);
-extern void gart_iommu_init(void);
-extern void gart_iommu_shutdown(void);
+extern int gart_iommu_init(void);
 extern void __init gart_parse_options(char *);
 extern void gart_iommu_hole_init(void);
 
@@ -48,12 +47,6 @@ extern void gart_iommu_hole_init(void);
 static inline void early_gart_iommu_check(void)
 {
 }
-static inline void gart_iommu_init(void)
-{
-}
-static inline void gart_iommu_shutdown(void)
-{
-}
 static inline void gart_parse_options(char *options)
 {
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/geode.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/geode.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/geode.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/geode.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,160 +12,7 @@
 
 #include <asm/processor.h>
 #include <linux/io.h>
-
-/* Generic southbridge functions */
-
-#define GEODE_DEV_PMS 0
-#define GEODE_DEV_ACPI 1
-#define GEODE_DEV_GPIO 2
-#define GEODE_DEV_MFGPT 3
-
-extern int geode_get_dev_base(unsigned int dev);
-
-/* Useful macros */
-#define geode_pms_base()	geode_get_dev_base(GEODE_DEV_PMS)
-#define geode_acpi_base()	geode_get_dev_base(GEODE_DEV_ACPI)
-#define geode_gpio_base()	geode_get_dev_base(GEODE_DEV_GPIO)
-#define geode_mfgpt_base()	geode_get_dev_base(GEODE_DEV_MFGPT)
-
-/* MSRS */
-
-#define MSR_GLIU_P2D_RO0	0x10000029
-
-#define MSR_LX_GLD_MSR_CONFIG	0x48002001
-#define MSR_LX_MSR_PADSEL	0x48002011	/* NOT 0x48000011; the data
-						 * sheet has the wrong value */
-#define MSR_GLCP_SYS_RSTPLL	0x4C000014
-#define MSR_GLCP_DOTPLL		0x4C000015
-
-#define MSR_LBAR_SMB		0x5140000B
-#define MSR_LBAR_GPIO		0x5140000C
-#define MSR_LBAR_MFGPT		0x5140000D
-#define MSR_LBAR_ACPI		0x5140000E
-#define MSR_LBAR_PMS		0x5140000F
-
-#define MSR_DIVIL_SOFT_RESET	0x51400017
-
-#define MSR_PIC_YSEL_LOW	0x51400020
-#define MSR_PIC_YSEL_HIGH	0x51400021
-#define MSR_PIC_ZSEL_LOW	0x51400022
-#define MSR_PIC_ZSEL_HIGH	0x51400023
-#define MSR_PIC_IRQM_LPC	0x51400025
-
-#define MSR_MFGPT_IRQ		0x51400028
-#define MSR_MFGPT_NR		0x51400029
-#define MSR_MFGPT_SETUP		0x5140002B
-
-#define MSR_LX_SPARE_MSR	0x80000011	/* DC-specific */
-
-#define MSR_GX_GLD_MSR_CONFIG	0xC0002001
-#define MSR_GX_MSR_PADSEL	0xC0002011
-
-/* Resource Sizes */
-
-#define LBAR_GPIO_SIZE		0xFF
-#define LBAR_MFGPT_SIZE		0x40
-#define LBAR_ACPI_SIZE		0x40
-#define LBAR_PMS_SIZE		0x80
-
-/* ACPI registers (PMS block) */
-
-/*
- * PM1_EN is only valid when VSA is enabled for 16 bit reads.
- * When VSA is not enabled, *always* read both PM1_STS and PM1_EN
- * with a 32 bit read at offset 0x0
- */
-
-#define PM1_STS			0x00
-#define PM1_EN			0x02
-#define PM1_CNT			0x08
-#define PM2_CNT			0x0C
-#define PM_TMR			0x10
-#define PM_GPE0_STS		0x18
-#define PM_GPE0_EN		0x1C
-
-/* PMC registers (PMS block) */
-
-#define PM_SSD			0x00
-#define PM_SCXA			0x04
-#define PM_SCYA			0x08
-#define PM_OUT_SLPCTL		0x0C
-#define PM_SCLK			0x10
-#define PM_SED			0x1
-#define PM_SCXD			0x18
-#define PM_SCYD			0x1C
-#define PM_IN_SLPCTL		0x20
-#define PM_WKD			0x30
-#define PM_WKXD			0x34
-#define PM_RD			0x38
-#define PM_WKXA			0x3C
-#define PM_FSD			0x40
-#define PM_TSD			0x44
-#define PM_PSD			0x48
-#define PM_NWKD			0x4C
-#define PM_AWKD			0x50
-#define PM_SSC			0x54
-
-/* VSA2 magic values */
-
-#define VSA_VRC_INDEX		0xAC1C
-#define VSA_VRC_DATA		0xAC1E
-#define VSA_VR_UNLOCK		0xFC53	/* unlock virtual register */
-#define VSA_VR_SIGNATURE	0x0003
-#define VSA_VR_MEM_SIZE		0x0200
-#define AMD_VSA_SIG		0x4132	/* signature is ascii 'VSA2' */
-#define GSW_VSA_SIG		0x534d  /* General Software signature */
-/* GPIO */
-
-#define GPIO_OUTPUT_VAL		0x00
-#define GPIO_OUTPUT_ENABLE	0x04
-#define GPIO_OUTPUT_OPEN_DRAIN	0x08
-#define GPIO_OUTPUT_INVERT	0x0C
-#define GPIO_OUTPUT_AUX1	0x10
-#define GPIO_OUTPUT_AUX2	0x14
-#define GPIO_PULL_UP		0x18
-#define GPIO_PULL_DOWN		0x1C
-#define GPIO_INPUT_ENABLE	0x20
-#define GPIO_INPUT_INVERT	0x24
-#define GPIO_INPUT_FILTER	0x28
-#define GPIO_INPUT_EVENT_COUNT	0x2C
-#define GPIO_READ_BACK		0x30
-#define GPIO_INPUT_AUX1		0x34
-#define GPIO_EVENTS_ENABLE	0x38
-#define GPIO_LOCK_ENABLE	0x3C
-#define GPIO_POSITIVE_EDGE_EN	0x40
-#define GPIO_NEGATIVE_EDGE_EN	0x44
-#define GPIO_POSITIVE_EDGE_STS	0x48
-#define GPIO_NEGATIVE_EDGE_STS	0x4C
-
-#define GPIO_MAP_X		0xE0
-#define GPIO_MAP_Y		0xE4
-#define GPIO_MAP_Z		0xE8
-#define GPIO_MAP_W		0xEC
-
-static inline u32 geode_gpio(unsigned int nr)
-{
-	BUG_ON(nr > 28);
-	return 1 << nr;
-}
-
-extern void geode_gpio_set(u32, unsigned int);
-extern void geode_gpio_clear(u32, unsigned int);
-extern int geode_gpio_isset(u32, unsigned int);
-extern void geode_gpio_setup_event(unsigned int, int, int);
-extern void geode_gpio_set_irq(unsigned int, unsigned int);
-
-static inline void geode_gpio_event_irq(unsigned int gpio, int pair)
-{
-	geode_gpio_setup_event(gpio, pair, 0);
-}
-
-static inline void geode_gpio_event_pme(unsigned int gpio, int pair)
-{
-	geode_gpio_setup_event(gpio, pair, 1);
-}
-
-/* Specific geode tests */
+#include <linux/cs5535.h>
 
 static inline int is_geode_gx(void)
 {
@@ -186,68 +33,4 @@ static inline int is_geode(void)
 	return (is_geode_gx() || is_geode_lx());
 }
 
-#ifdef CONFIG_MGEODE_LX
-extern int geode_has_vsa2(void);
-#else
-static inline int geode_has_vsa2(void)
-{
-	return 0;
-}
-#endif
-
-/* MFGPTs */
-
-#define MFGPT_MAX_TIMERS	8
-#define MFGPT_TIMER_ANY		(-1)
-
-#define MFGPT_DOMAIN_WORKING	1
-#define MFGPT_DOMAIN_STANDBY	2
-#define MFGPT_DOMAIN_ANY	(MFGPT_DOMAIN_WORKING | MFGPT_DOMAIN_STANDBY)
-
-#define MFGPT_CMP1		0
-#define MFGPT_CMP2		1
-
-#define MFGPT_EVENT_IRQ		0
-#define MFGPT_EVENT_NMI		1
-#define MFGPT_EVENT_RESET	3
-
-#define MFGPT_REG_CMP1		0
-#define MFGPT_REG_CMP2		2
-#define MFGPT_REG_COUNTER	4
-#define MFGPT_REG_SETUP		6
-
-#define MFGPT_SETUP_CNTEN	(1 << 15)
-#define MFGPT_SETUP_CMP2	(1 << 14)
-#define MFGPT_SETUP_CMP1	(1 << 13)
-#define MFGPT_SETUP_SETUP	(1 << 12)
-#define MFGPT_SETUP_STOPEN	(1 << 11)
-#define MFGPT_SETUP_EXTEN	(1 << 10)
-#define MFGPT_SETUP_REVEN	(1 << 5)
-#define MFGPT_SETUP_CLKSEL	(1 << 4)
-
-static inline void geode_mfgpt_write(int timer, u16 reg, u16 value)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
-	outw(value, base + reg + (timer * 8));
-}
-
-static inline u16 geode_mfgpt_read(int timer, u16 reg)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
-	return inw(base + reg + (timer * 8));
-}
-
-extern int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable);
-extern int geode_mfgpt_set_irq(int timer, int cmp, int *irq, int enable);
-extern int geode_mfgpt_alloc_timer(int timer, int domain);
-
-#define geode_mfgpt_setup_irq(t, c, i) geode_mfgpt_set_irq((t), (c), (i), 1)
-#define geode_mfgpt_release_irq(t, c, i) geode_mfgpt_set_irq((t), (c), (i), 0)
-
-#ifdef CONFIG_GEODE_MFGPT_TIMER
-extern int __init mfgpt_timer_setup(void);
-#else
-static inline int mfgpt_timer_setup(void) { return 0; }
-#endif
-
 #endif /* _ASM_X86_GEODE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/hardirq.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/hardirq.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/hardirq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/hardirq.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@ typedef struct {
 	unsigned int apic_timer_irqs;	/* arch dependent */
 	unsigned int irq_spurious_count;
 #endif
-	unsigned int generic_irqs;	/* arch dependent */
+	unsigned int x86_platform_ipis;	/* arch dependent */
 	unsigned int apic_perf_irqs;
 	unsigned int apic_pending_irqs;
 #ifdef CONFIG_SMP
@@ -20,11 +20,11 @@ typedef struct {
 	unsigned int irq_call_count;
 	unsigned int irq_tlb_count;
 #endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
 	unsigned int irq_thermal_count;
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
 	unsigned int irq_threshold_count;
-# endif
 #endif
 } ____cacheline_aligned irq_cpustat_t;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/hpet.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/hpet.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/hpet.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/hpet.h	2010-02-24 13:52:17.000000000 -0500
@@ -65,11 +65,13 @@
 /* hpet memory map physical address */
 extern unsigned long hpet_address;
 extern unsigned long force_hpet_address;
+extern u8 hpet_blockid;
 extern int hpet_force_user;
+extern u8 hpet_msi_disable;
 extern int is_hpet_enabled(void);
 extern int hpet_enable(void);
 extern void hpet_disable(void);
-extern unsigned long hpet_readl(unsigned long a);
+extern unsigned int hpet_readl(unsigned int a);
 extern void force_hpet_resume(void);
 
 extern void hpet_msi_unmask(unsigned int irq);
@@ -78,9 +80,9 @@ extern void hpet_msi_write(unsigned int
 extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
 
 #ifdef CONFIG_PCI_MSI
-extern int arch_setup_hpet_msi(unsigned int irq);
+extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id);
 #else
-static inline int arch_setup_hpet_msi(unsigned int irq)
+static inline int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
 	return -EINVAL;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/hw_breakpoint.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_breakpoint.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/hw_breakpoint.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_breakpoint.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,73 @@
+#ifndef	_I386_HW_BREAKPOINT_H
+#define	_I386_HW_BREAKPOINT_H
+
+#ifdef	__KERNEL__
+#define	__ARCH_HW_BREAKPOINT_H
+
+/*
+ * The name should probably be something dealt in
+ * a higher level. While dealing with the user
+ * (display/resolving)
+ */
+struct arch_hw_breakpoint {
+	char		*name; /* Contains name of the symbol to set bkpt */
+	unsigned long	address;
+	u8		len;
+	u8		type;
+};
+
+#include <linux/kdebug.h>
+#include <linux/percpu.h>
+#include <linux/list.h>
+
+/* Available HW breakpoint length encodings */
+#define X86_BREAKPOINT_LEN_1		0x40
+#define X86_BREAKPOINT_LEN_2		0x44
+#define X86_BREAKPOINT_LEN_4		0x4c
+#define X86_BREAKPOINT_LEN_EXECUTE	0x40
+
+#ifdef CONFIG_X86_64
+#define X86_BREAKPOINT_LEN_8		0x48
+#endif
+
+/* Available HW breakpoint type encodings */
+
+/* trigger on instruction execute */
+#define X86_BREAKPOINT_EXECUTE	0x80
+/* trigger on memory write */
+#define X86_BREAKPOINT_WRITE	0x81
+/* trigger on memory read or write */
+#define X86_BREAKPOINT_RW	0x83
+
+/* Total number of available HW breakpoint registers */
+#define HBP_NUM 4
+
+struct perf_event;
+struct pmu;
+
+extern int arch_check_va_in_userspace(unsigned long va, u8 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+					 struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+					   unsigned long val, void *data);
+
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
+
+extern void
+arch_fill_perf_breakpoint(struct perf_event *bp);
+
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type);
+int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type);
+
+extern int arch_bp_generic_fields(int x86_len, int x86_type,
+				  int *gen_len, int *gen_type);
+
+extern struct pmu perf_ops_bp;
+
+#endif	/* __KERNEL__ */
+#endif	/* _I386_HW_BREAKPOINT_H */
+
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/hw_irq.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_irq.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/hw_irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/hw_irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 
 /* Interrupt handlers registered during init_IRQ */
 extern void apic_timer_interrupt(void);
-extern void generic_interrupt(void);
+extern void x86_platform_ipi(void);
 extern void error_interrupt(void);
 extern void perf_pending_interrupt(void);
 
@@ -79,14 +79,33 @@ static inline void set_io_apic_irq_attr(
 					int ioapic, int ioapic_pin,
 					int trigger, int polarity)
 {
-	irq_attr->ioapic     = ioapic;
-	irq_attr->ioapic_pin = ioapic_pin;
-	irq_attr->trigger    = trigger;
-	irq_attr->polarity   = polarity;
+	irq_attr->ioapic	= ioapic;
+	irq_attr->ioapic_pin	= ioapic_pin;
+	irq_attr->trigger	= trigger;
+	irq_attr->polarity	= polarity;
 }
 
-extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin,
-					struct io_apic_irq_attr *irq_attr);
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * Most irqs are mapped 1:1 with pins.
+ */
+struct irq_cfg {
+	struct irq_pin_list	*irq_2_pin;
+	cpumask_var_t		domain;
+	cpumask_var_t		old_domain;
+	u8			vector;
+	u8			move_in_progress : 1;
+};
+
+extern struct irq_cfg *irq_cfg(unsigned int);
+extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
+extern void send_cleanup_vector(struct irq_cfg *);
+
+struct irq_desc;
+extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
+				      unsigned int *dest_id);
+extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
 extern void setup_ioapic_dest(void);
 
 extern void enable_IO_APIC(void);
@@ -101,7 +120,7 @@ extern void eisa_set_level_irq(unsigned
 /* SMP */
 extern void smp_apic_timer_interrupt(struct pt_regs *);
 extern void smp_spurious_interrupt(struct pt_regs *);
-extern void smp_generic_interrupt(struct pt_regs *);
+extern void smp_x86_platform_ipi(struct pt_regs *);
 extern void smp_error_interrupt(struct pt_regs *);
 #ifdef CONFIG_X86_IO_APIC
 extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/i387.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/i387.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/i387.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/i387.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,8 @@
 #ifndef _ASM_X86_I387_H
 #define _ASM_X86_I387_H
 
+#ifndef __ASSEMBLY__
+
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
@@ -411,4 +413,9 @@ static inline unsigned short get_fpu_mxc
 	}
 }
 
+#endif /* __ASSEMBLY__ */
+
+#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
+#define PSHUFB_XMM5_XMM6 .byte 0x66, 0x0f, 0x38, 0x00, 0xf5
+
 #endif /* _ASM_X86_I387_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/inat.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/inat.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/inat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/inat.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,220 @@
+#ifndef _ASM_X86_INAT_H
+#define _ASM_X86_INAT_H
+/*
+ * x86 instruction attributes
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <asm/inat_types.h>
+
+/*
+ * Internal bits. Don't use bitmasks directly, because these bits are
+ * unstable. You should use checking functions.
+ */
+
+#define INAT_OPCODE_TABLE_SIZE 256
+#define INAT_GROUP_TABLE_SIZE 8
+
+/* Legacy last prefixes */
+#define INAT_PFX_OPNDSZ	1	/* 0x66 */ /* LPFX1 */
+#define INAT_PFX_REPE	2	/* 0xF3 */ /* LPFX2 */
+#define INAT_PFX_REPNE	3	/* 0xF2 */ /* LPFX3 */
+/* Other Legacy prefixes */
+#define INAT_PFX_LOCK	4	/* 0xF0 */
+#define INAT_PFX_CS	5	/* 0x2E */
+#define INAT_PFX_DS	6	/* 0x3E */
+#define INAT_PFX_ES	7	/* 0x26 */
+#define INAT_PFX_FS	8	/* 0x64 */
+#define INAT_PFX_GS	9	/* 0x65 */
+#define INAT_PFX_SS	10	/* 0x36 */
+#define INAT_PFX_ADDRSZ	11	/* 0x67 */
+/* x86-64 REX prefix */
+#define INAT_PFX_REX	12	/* 0x4X */
+/* AVX VEX prefixes */
+#define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
+#define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
+
+#define INAT_LSTPFX_MAX	3
+#define INAT_LGCPFX_MAX	11
+
+/* Immediate size */
+#define INAT_IMM_BYTE		1
+#define INAT_IMM_WORD		2
+#define INAT_IMM_DWORD		3
+#define INAT_IMM_QWORD		4
+#define INAT_IMM_PTR		5
+#define INAT_IMM_VWORD32	6
+#define INAT_IMM_VWORD		7
+
+/* Legacy prefix */
+#define INAT_PFX_OFFS	0
+#define INAT_PFX_BITS	4
+#define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
+#define INAT_PFX_MASK	(INAT_PFX_MAX << INAT_PFX_OFFS)
+/* Escape opcodes */
+#define INAT_ESC_OFFS	(INAT_PFX_OFFS + INAT_PFX_BITS)
+#define INAT_ESC_BITS	2
+#define INAT_ESC_MAX	((1 << INAT_ESC_BITS) - 1)
+#define INAT_ESC_MASK	(INAT_ESC_MAX << INAT_ESC_OFFS)
+/* Group opcodes (1-16) */
+#define INAT_GRP_OFFS	(INAT_ESC_OFFS + INAT_ESC_BITS)
+#define INAT_GRP_BITS	5
+#define INAT_GRP_MAX	((1 << INAT_GRP_BITS) - 1)
+#define INAT_GRP_MASK	(INAT_GRP_MAX << INAT_GRP_OFFS)
+/* Immediates */
+#define INAT_IMM_OFFS	(INAT_GRP_OFFS + INAT_GRP_BITS)
+#define INAT_IMM_BITS	3
+#define INAT_IMM_MASK	(((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
+/* Flags */
+#define INAT_FLAG_OFFS	(INAT_IMM_OFFS + INAT_IMM_BITS)
+#define INAT_MODRM	(1 << (INAT_FLAG_OFFS))
+#define INAT_FORCE64	(1 << (INAT_FLAG_OFFS + 1))
+#define INAT_SCNDIMM	(1 << (INAT_FLAG_OFFS + 2))
+#define INAT_MOFFSET	(1 << (INAT_FLAG_OFFS + 3))
+#define INAT_VARIANT	(1 << (INAT_FLAG_OFFS + 4))
+#define INAT_VEXOK	(1 << (INAT_FLAG_OFFS + 5))
+#define INAT_VEXONLY	(1 << (INAT_FLAG_OFFS + 6))
+/* Attribute making macros for attribute tables */
+#define INAT_MAKE_PREFIX(pfx)	(pfx << INAT_PFX_OFFS)
+#define INAT_MAKE_ESCAPE(esc)	(esc << INAT_ESC_OFFS)
+#define INAT_MAKE_GROUP(grp)	((grp << INAT_GRP_OFFS) | INAT_MODRM)
+#define INAT_MAKE_IMM(imm)	(imm << INAT_IMM_OFFS)
+
+/* Attribute search APIs */
+extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
+extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
+					     insn_byte_t last_pfx,
+					     insn_attr_t esc_attr);
+extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
+					    insn_byte_t last_pfx,
+					    insn_attr_t esc_attr);
+extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
+					  insn_byte_t vex_m,
+					  insn_byte_t vex_pp);
+
+/* Attribute checking functions */
+static inline int inat_is_legacy_prefix(insn_attr_t attr)
+{
+	attr &= INAT_PFX_MASK;
+	return attr && attr <= INAT_LGCPFX_MAX;
+}
+
+static inline int inat_is_address_size_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
+}
+
+static inline int inat_is_operand_size_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
+}
+
+static inline int inat_is_rex_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
+}
+
+static inline int inat_last_prefix_id(insn_attr_t attr)
+{
+	if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
+		return 0;
+	else
+		return attr & INAT_PFX_MASK;
+}
+
+static inline int inat_is_vex_prefix(insn_attr_t attr)
+{
+	attr &= INAT_PFX_MASK;
+	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
+}
+
+static inline int inat_is_vex3_prefix(insn_attr_t attr)
+{
+	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
+}
+
+static inline int inat_is_escape(insn_attr_t attr)
+{
+	return attr & INAT_ESC_MASK;
+}
+
+static inline int inat_escape_id(insn_attr_t attr)
+{
+	return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
+}
+
+static inline int inat_is_group(insn_attr_t attr)
+{
+	return attr & INAT_GRP_MASK;
+}
+
+static inline int inat_group_id(insn_attr_t attr)
+{
+	return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
+}
+
+static inline int inat_group_common_attribute(insn_attr_t attr)
+{
+	return attr & ~INAT_GRP_MASK;
+}
+
+static inline int inat_has_immediate(insn_attr_t attr)
+{
+	return attr & INAT_IMM_MASK;
+}
+
+static inline int inat_immediate_size(insn_attr_t attr)
+{
+	return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
+}
+
+static inline int inat_has_modrm(insn_attr_t attr)
+{
+	return attr & INAT_MODRM;
+}
+
+static inline int inat_is_force64(insn_attr_t attr)
+{
+	return attr & INAT_FORCE64;
+}
+
+static inline int inat_has_second_immediate(insn_attr_t attr)
+{
+	return attr & INAT_SCNDIMM;
+}
+
+static inline int inat_has_moffset(insn_attr_t attr)
+{
+	return attr & INAT_MOFFSET;
+}
+
+static inline int inat_has_variant(insn_attr_t attr)
+{
+	return attr & INAT_VARIANT;
+}
+
+static inline int inat_accept_vex(insn_attr_t attr)
+{
+	return attr & INAT_VEXOK;
+}
+
+static inline int inat_must_vex(insn_attr_t attr)
+{
+	return attr & INAT_VEXONLY;
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/inat_types.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/inat_types.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/inat_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/inat_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+#ifndef _ASM_X86_INAT_TYPES_H
+#define _ASM_X86_INAT_TYPES_H
+/*
+ * x86 instruction attributes
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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.
+ *
+ */
+
+/* Instruction attributes */
+typedef unsigned int insn_attr_t;
+typedef unsigned char insn_byte_t;
+typedef signed int insn_value_t;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/insn.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/insn.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/insn.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/insn.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,184 @@
+#ifndef _ASM_X86_INSN_H
+#define _ASM_X86_INSN_H
+/*
+ * x86 instruction analysis
+ *
+ * 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) IBM Corporation, 2009
+ */
+
+/* insn_attr_t is defined in inat.h */
+#include <asm/inat.h>
+
+struct insn_field {
+	union {
+		insn_value_t value;
+		insn_byte_t bytes[4];
+	};
+	/* !0 if we've run insn_get_xxx() for this field */
+	unsigned char got;
+	unsigned char nbytes;
+};
+
+struct insn {
+	struct insn_field prefixes;	/*
+					 * Prefixes
+					 * prefixes.bytes[3]: last prefix
+					 */
+	struct insn_field rex_prefix;	/* REX prefix */
+	struct insn_field vex_prefix;	/* VEX prefix */
+	struct insn_field opcode;	/*
+					 * opcode.bytes[0]: opcode1
+					 * opcode.bytes[1]: opcode2
+					 * opcode.bytes[2]: opcode3
+					 */
+	struct insn_field modrm;
+	struct insn_field sib;
+	struct insn_field displacement;
+	union {
+		struct insn_field immediate;
+		struct insn_field moffset1;	/* for 64bit MOV */
+		struct insn_field immediate1;	/* for 64bit imm or off16/32 */
+	};
+	union {
+		struct insn_field moffset2;	/* for 64bit MOV */
+		struct insn_field immediate2;	/* for 64bit imm or seg16 */
+	};
+
+	insn_attr_t attr;
+	unsigned char opnd_bytes;
+	unsigned char addr_bytes;
+	unsigned char length;
+	unsigned char x86_64;
+
+	const insn_byte_t *kaddr;	/* kernel address of insn to analyze */
+	const insn_byte_t *next_byte;
+};
+
+#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
+#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
+#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
+
+#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
+#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
+#define X86_SIB_BASE(sib) ((sib) & 0x07)
+
+#define X86_REX_W(rex) ((rex) & 8)
+#define X86_REX_R(rex) ((rex) & 4)
+#define X86_REX_X(rex) ((rex) & 2)
+#define X86_REX_B(rex) ((rex) & 1)
+
+/* VEX bit flags  */
+#define X86_VEX_W(vex)	((vex) & 0x80)	/* VEX3 Byte2 */
+#define X86_VEX_R(vex)	((vex) & 0x80)	/* VEX2/3 Byte1 */
+#define X86_VEX_X(vex)	((vex) & 0x40)	/* VEX3 Byte1 */
+#define X86_VEX_B(vex)	((vex) & 0x20)	/* VEX3 Byte1 */
+#define X86_VEX_L(vex)	((vex) & 0x04)	/* VEX3 Byte2, VEX2 Byte1 */
+/* VEX bit fields */
+#define X86_VEX3_M(vex)	((vex) & 0x1f)		/* VEX3 Byte1 */
+#define X86_VEX2_M	1			/* VEX2.M always 1 */
+#define X86_VEX_V(vex)	(((vex) & 0x78) >> 3)	/* VEX3 Byte2, VEX2 Byte1 */
+#define X86_VEX_P(vex)	((vex) & 0x03)		/* VEX3 Byte2, VEX2 Byte1 */
+#define X86_VEX_M_MAX	0x1f			/* VEX3.M Maximum value */
+
+/* The last prefix is needed for two-byte and three-byte opcodes */
+static inline insn_byte_t insn_last_prefix(struct insn *insn)
+{
+	return insn->prefixes.bytes[3];
+}
+
+extern void insn_init(struct insn *insn, const void *kaddr, int x86_64);
+extern void insn_get_prefixes(struct insn *insn);
+extern void insn_get_opcode(struct insn *insn);
+extern void insn_get_modrm(struct insn *insn);
+extern void insn_get_sib(struct insn *insn);
+extern void insn_get_displacement(struct insn *insn);
+extern void insn_get_immediate(struct insn *insn);
+extern void insn_get_length(struct insn *insn);
+
+/* Attribute will be determined after getting ModRM (for opcode groups) */
+static inline void insn_get_attribute(struct insn *insn)
+{
+	insn_get_modrm(insn);
+}
+
+/* Instruction uses RIP-relative addressing */
+extern int insn_rip_relative(struct insn *insn);
+
+/* Init insn for kernel text */
+static inline void kernel_insn_init(struct insn *insn, const void *kaddr)
+{
+#ifdef CONFIG_X86_64
+	insn_init(insn, kaddr, 1);
+#else /* CONFIG_X86_32 */
+	insn_init(insn, kaddr, 0);
+#endif
+}
+
+static inline int insn_is_avx(struct insn *insn)
+{
+	if (!insn->prefixes.got)
+		insn_get_prefixes(insn);
+	return (insn->vex_prefix.value != 0);
+}
+
+static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
+{
+	if (insn->vex_prefix.nbytes == 2)	/* 2 bytes VEX */
+		return X86_VEX2_M;
+	else
+		return X86_VEX3_M(insn->vex_prefix.bytes[1]);
+}
+
+static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
+{
+	if (insn->vex_prefix.nbytes == 2)	/* 2 bytes VEX */
+		return X86_VEX_P(insn->vex_prefix.bytes[1]);
+	else
+		return X86_VEX_P(insn->vex_prefix.bytes[2]);
+}
+
+/* Offset of each field from kaddr */
+static inline int insn_offset_rex_prefix(struct insn *insn)
+{
+	return insn->prefixes.nbytes;
+}
+static inline int insn_offset_vex_prefix(struct insn *insn)
+{
+	return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
+}
+static inline int insn_offset_opcode(struct insn *insn)
+{
+	return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
+}
+static inline int insn_offset_modrm(struct insn *insn)
+{
+	return insn_offset_opcode(insn) + insn->opcode.nbytes;
+}
+static inline int insn_offset_sib(struct insn *insn)
+{
+	return insn_offset_modrm(insn) + insn->modrm.nbytes;
+}
+static inline int insn_offset_displacement(struct insn *insn)
+{
+	return insn_offset_sib(insn) + insn->sib.nbytes;
+}
+static inline int insn_offset_immediate(struct insn *insn)
+{
+	return insn_offset_displacement(insn) + insn->displacement.nbytes;
+}
+
+#endif /* _ASM_X86_INSN_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/inst.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/inst.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/inst.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/inst.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,150 @@
+/*
+ * Generate .byte code for some instructions not supported by old
+ * binutils.
+ */
+#ifndef X86_ASM_INST_H
+#define X86_ASM_INST_H
+
+#ifdef __ASSEMBLY__
+
+	.macro XMM_NUM opd xmm
+	.ifc \xmm,%xmm0
+	\opd = 0
+	.endif
+	.ifc \xmm,%xmm1
+	\opd = 1
+	.endif
+	.ifc \xmm,%xmm2
+	\opd = 2
+	.endif
+	.ifc \xmm,%xmm3
+	\opd = 3
+	.endif
+	.ifc \xmm,%xmm4
+	\opd = 4
+	.endif
+	.ifc \xmm,%xmm5
+	\opd = 5
+	.endif
+	.ifc \xmm,%xmm6
+	\opd = 6
+	.endif
+	.ifc \xmm,%xmm7
+	\opd = 7
+	.endif
+	.ifc \xmm,%xmm8
+	\opd = 8
+	.endif
+	.ifc \xmm,%xmm9
+	\opd = 9
+	.endif
+	.ifc \xmm,%xmm10
+	\opd = 10
+	.endif
+	.ifc \xmm,%xmm11
+	\opd = 11
+	.endif
+	.ifc \xmm,%xmm12
+	\opd = 12
+	.endif
+	.ifc \xmm,%xmm13
+	\opd = 13
+	.endif
+	.ifc \xmm,%xmm14
+	\opd = 14
+	.endif
+	.ifc \xmm,%xmm15
+	\opd = 15
+	.endif
+	.endm
+
+	.macro PFX_OPD_SIZE
+	.byte 0x66
+	.endm
+
+	.macro PFX_REX opd1 opd2
+	.if (\opd1 | \opd2) & 8
+	.byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1)
+	.endif
+	.endm
+
+	.macro MODRM mod opd1 opd2
+	.byte \mod | (\opd1 & 7) | ((\opd2 & 7) << 3)
+	.endm
+
+	.macro PSHUFB_XMM xmm1 xmm2
+	XMM_NUM pshufb_opd1 \xmm1
+	XMM_NUM pshufb_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX pshufb_opd1 pshufb_opd2
+	.byte 0x0f, 0x38, 0x00
+	MODRM 0xc0 pshufb_opd1 pshufb_opd2
+	.endm
+
+	.macro PCLMULQDQ imm8 xmm1 xmm2
+	XMM_NUM clmul_opd1 \xmm1
+	XMM_NUM clmul_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX clmul_opd1 clmul_opd2
+	.byte 0x0f, 0x3a, 0x44
+	MODRM 0xc0 clmul_opd1 clmul_opd2
+	.byte \imm8
+	.endm
+
+	.macro AESKEYGENASSIST rcon xmm1 xmm2
+	XMM_NUM aeskeygen_opd1 \xmm1
+	XMM_NUM aeskeygen_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aeskeygen_opd1 aeskeygen_opd2
+	.byte 0x0f, 0x3a, 0xdf
+	MODRM 0xc0 aeskeygen_opd1 aeskeygen_opd2
+	.byte \rcon
+	.endm
+
+	.macro AESIMC xmm1 xmm2
+	XMM_NUM aesimc_opd1 \xmm1
+	XMM_NUM aesimc_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesimc_opd1 aesimc_opd2
+	.byte 0x0f, 0x38, 0xdb
+	MODRM 0xc0 aesimc_opd1 aesimc_opd2
+	.endm
+
+	.macro AESENC xmm1 xmm2
+	XMM_NUM aesenc_opd1 \xmm1
+	XMM_NUM aesenc_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesenc_opd1 aesenc_opd2
+	.byte 0x0f, 0x38, 0xdc
+	MODRM 0xc0 aesenc_opd1 aesenc_opd2
+	.endm
+
+	.macro AESENCLAST xmm1 xmm2
+	XMM_NUM aesenclast_opd1 \xmm1
+	XMM_NUM aesenclast_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesenclast_opd1 aesenclast_opd2
+	.byte 0x0f, 0x38, 0xdd
+	MODRM 0xc0 aesenclast_opd1 aesenclast_opd2
+	.endm
+
+	.macro AESDEC xmm1 xmm2
+	XMM_NUM aesdec_opd1 \xmm1
+	XMM_NUM aesdec_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesdec_opd1 aesdec_opd2
+	.byte 0x0f, 0x38, 0xde
+	MODRM 0xc0 aesdec_opd1 aesdec_opd2
+	.endm
+
+	.macro AESDECLAST xmm1 xmm2
+	XMM_NUM aesdeclast_opd1 \xmm1
+	XMM_NUM aesdeclast_opd2 \xmm2
+	PFX_OPD_SIZE
+	PFX_REX aesdeclast_opd1 aesdeclast_opd2
+	.byte 0x0f, 0x38, 0xdf
+	MODRM 0xc0 aesdeclast_opd1 aesdeclast_opd2
+	.endm
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/iommu.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/iommu.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/iommu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/iommu.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,6 @@
 #ifndef _ASM_X86_IOMMU_H
 #define _ASM_X86_IOMMU_H
 
-extern void pci_iommu_shutdown(void);
-extern void no_iommu_init(void);
 extern struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/irq.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,9 +34,10 @@ static inline int irq_canonicalize(int i
 #ifdef CONFIG_HOTPLUG_CPU
 #include <linux/cpumask.h>
 extern void fixup_irqs(void);
+extern void irq_force_complete_move(int);
 #endif
 
-extern void (*generic_interrupt_extension)(void);
+extern void (*x86_platform_ipi_callback)(void);
 extern void native_init_IRQ(void);
 extern bool handle_irq(unsigned irq, struct pt_regs *regs);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/irq_vectors.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq_vectors.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/irq_vectors.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/irq_vectors.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,14 +106,14 @@
 /*
  * Generic system vector for platform specific use
  */
-#define GENERIC_INTERRUPT_VECTOR	0xed
+#define X86_PLATFORM_IPI_VECTOR		0xed
 
 /*
  * Performance monitoring pending work vector:
  */
 #define LOCAL_PENDING_VECTOR		0xec
 
-#define UV_BAU_MESSAGE			0xec
+#define UV_BAU_MESSAGE			0xea
 
 /*
  * Self IPI vector for machine checks
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/k8.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/k8.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/k8.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/k8.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,13 +4,16 @@
 #include <linux/pci.h>
 
 extern struct pci_device_id k8_nb_ids[];
+struct bootnode;
 
 extern int early_is_k8_nb(u32 value);
 extern struct pci_dev **k8_northbridges;
 extern int num_k8_northbridges;
 extern int cache_k8_northbridges(void);
 extern void k8_flush_garts(void);
-extern int k8_scan_nodes(unsigned long start, unsigned long end);
+extern int k8_get_nodes(struct bootnode *nodes);
+extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
+extern int k8_scan_nodes(void);
 
 #ifdef CONFIG_K8_NB
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/Kbuild linux-libre-2.6.33-gnu1/arch/x86/include/asm/Kbuild
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/Kbuild	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/Kbuild	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@ header-y += ptrace-abi.h
 header-y += sigcontext32.h
 header-y += ucontext.h
 header-y += processor-flags.h
+header-y += hw_breakpoint.h
 
 unifdef-y += e820.h
 unifdef-y += ist.h
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm_emulate.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_emulate.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm_emulate.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_emulate.h	2010-02-24 13:52:17.000000000 -0500
@@ -129,7 +129,7 @@ struct decode_cache {
 	u8 seg_override;
 	unsigned int d;
 	unsigned long regs[NR_VCPU_REGS];
-	unsigned long eip;
+	unsigned long eip, eip_orig;
 	/* modrm */
 	u8 modrm;
 	u8 modrm_mod;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,8 @@
 #define __KVM_HAVE_MSIX
 #define __KVM_HAVE_MCE
 #define __KVM_HAVE_PIT_STATE2
+#define __KVM_HAVE_XEN_HVM
+#define __KVM_HAVE_VCPU_EVENTS
 
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
@@ -79,6 +81,7 @@ struct kvm_ioapic_state {
 #define KVM_IRQCHIP_PIC_MASTER   0
 #define KVM_IRQCHIP_PIC_SLAVE    1
 #define KVM_IRQCHIP_IOAPIC       2
+#define KVM_NR_IRQCHIPS          3
 
 /* for KVM_GET_REGS and KVM_SET_REGS */
 struct kvm_regs {
@@ -250,4 +253,35 @@ struct kvm_reinject_control {
 	__u8 pit_reinject;
 	__u8 reserved[31];
 };
+
+/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_VALID_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_VALID_SIPI_VECTOR	0x00000002
+
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 has_error_code;
+		__u8 pad;
+		__u32 error_code;
+	} exception;
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 soft;
+		__u8 pad;
+	} interrupt;
+	struct {
+		__u8 injected;
+		__u8 pending;
+		__u8 masked;
+		__u8 pad;
+	} nmi;
+	__u32 sipi_vector;
+	__u32 flags;
+	__u32 reserved[10];
+};
+
 #endif /* _ASM_X86_KVM_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm_host.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_host.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/kvm_host.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/kvm_host.h	2010-02-24 13:52:17.000000000 -0500
@@ -354,7 +354,6 @@ struct kvm_vcpu_arch {
 	unsigned int time_offset;
 	struct page *time_page;
 
-	bool singlestep; /* guest is single stepped by KVM */
 	bool nmi_pending;
 	bool nmi_injected;
 
@@ -371,6 +370,10 @@ struct kvm_vcpu_arch {
 	u64 mcg_status;
 	u64 mcg_ctl;
 	u64 *mce_banks;
+
+	/* used for guest single stepping over the given code position */
+	u16 singlestep_cs;
+	unsigned long singlestep_rip;
 };
 
 struct kvm_mem_alias {
@@ -397,7 +400,6 @@ struct kvm_arch{
 	struct kvm_pic *vpic;
 	struct kvm_ioapic *vioapic;
 	struct kvm_pit *vpit;
-	struct hlist_head irq_ack_notifier_list;
 	int vapics_in_nmi_mode;
 
 	unsigned int tss_addr;
@@ -410,8 +412,10 @@ struct kvm_arch{
 	gpa_t ept_identity_map_addr;
 
 	unsigned long irq_sources_bitmap;
-	unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
 	u64 vm_init_tsc;
+	s64 kvmclock_offset;
+
+	struct kvm_xen_hvm_config xen_hvm_config;
 };
 
 struct kvm_vm_stat {
@@ -461,7 +465,7 @@ struct descriptor_table {
 struct kvm_x86_ops {
 	int (*cpu_has_kvm_support)(void);          /* __init */
 	int (*disabled_by_bios)(void);             /* __init */
-	void (*hardware_enable)(void *dummy);      /* __init */
+	int (*hardware_enable)(void *dummy);
 	void (*hardware_disable)(void *dummy);
 	void (*check_processor_compatibility)(void *rtn);
 	int (*hardware_setup)(void);               /* __init */
@@ -477,8 +481,8 @@ struct kvm_x86_ops {
 	void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
 	void (*vcpu_put)(struct kvm_vcpu *vcpu);
 
-	int (*set_guest_debug)(struct kvm_vcpu *vcpu,
-			       struct kvm_guest_debug *dbg);
+	void (*set_guest_debug)(struct kvm_vcpu *vcpu,
+				struct kvm_guest_debug *dbg);
 	int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
 	int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
 	u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -506,8 +510,8 @@ struct kvm_x86_ops {
 
 	void (*tlb_flush)(struct kvm_vcpu *vcpu);
 
-	void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
-	int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
+	void (*run)(struct kvm_vcpu *vcpu);
+	int (*handle_exit)(struct kvm_vcpu *vcpu);
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
 	void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
 	u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
@@ -519,6 +523,8 @@ struct kvm_x86_ops {
 				bool has_error_code, u32 error_code);
 	int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
 	int (*nmi_allowed)(struct kvm_vcpu *vcpu);
+	bool (*get_nmi_mask)(struct kvm_vcpu *vcpu);
+	void (*set_nmi_mask)(struct kvm_vcpu *vcpu, bool masked);
 	void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
 	void (*enable_irq_window)(struct kvm_vcpu *vcpu);
 	void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
@@ -568,7 +574,7 @@ enum emulation_result {
 #define EMULTYPE_NO_DECODE	    (1 << 0)
 #define EMULTYPE_TRAP_UD	    (1 << 1)
 #define EMULTYPE_SKIP		    (1 << 2)
-int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
+int emulate_instruction(struct kvm_vcpu *vcpu,
 			unsigned long cr2, u16 error_code, int emulation_type);
 void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
 void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
@@ -585,9 +591,9 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u
 
 struct x86_emulate_ctxt;
 
-int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in,
 		     int size, unsigned port);
-int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
 			   int size, unsigned long count, int down,
 			    gva_t address, int rep, unsigned port);
 void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
@@ -616,6 +622,9 @@ void kvm_get_cs_db_l_bits(struct kvm_vcp
 int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
 
+unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu);
+void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
+
 void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
@@ -802,4 +811,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcp
 int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 
+void kvm_define_shared_msr(unsigned index, u32 msr);
+void kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/mce.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/mce.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/mce.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/mce.h	2010-02-24 13:52:17.000000000 -0500
@@ -108,8 +108,11 @@ struct mce_log {
 #define K8_MCE_THRESHOLD_BANK_5    (MCE_THRESHOLD_BASE + 5 * 9)
 #define K8_MCE_THRESHOLD_DRAM_ECC  (MCE_THRESHOLD_BANK_4 + 0)
 
+
 #ifdef __KERNEL__
 
+extern struct atomic_notifier_head x86_mce_decoder_chain;
+
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <asm/atomic.h>
@@ -118,9 +121,11 @@ extern int mce_disabled;
 extern int mce_p5_enabled;
 
 #ifdef CONFIG_X86_MCE
-void mcheck_init(struct cpuinfo_x86 *c);
+int mcheck_init(void);
+void mcheck_cpu_init(struct cpuinfo_x86 *c);
 #else
-static inline void mcheck_init(struct cpuinfo_x86 *c) {}
+static inline int mcheck_init(void) { return 0; }
+static inline void mcheck_cpu_init(struct cpuinfo_x86 *c) {}
 #endif
 
 #ifdef CONFIG_X86_ANCIENT_MCE
@@ -214,5 +219,11 @@ void intel_init_thermal(struct cpuinfo_x
 
 void mce_log_therm_throt_event(__u64 status);
 
+#ifdef CONFIG_X86_THERMAL_VECTOR
+extern void mcheck_intel_therm_init(void);
+#else
+static inline void mcheck_intel_therm_init(void) { }
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/mmzone_32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/mmzone_32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/mmzone_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/mmzone_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ static inline void resume_map_numa_kva(p
 /*
  * generic node memory support, the following assumptions apply:
  *
- * 1) memory comes in 64Mb contigious chunks which are either present or not
+ * 1) memory comes in 64Mb contiguous chunks which are either present or not
  * 2) we will not have more than 64Gb in total
  *
  * for now assume that 64Gb is max amount of RAM for whole system
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/mpspec.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/mpspec.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/mpspec.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/mpspec.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,12 +71,7 @@ static inline void early_get_smp_config(
 
 static inline void find_smp_config(void)
 {
-	x86_init.mpparse.find_smp_config(1);
-}
-
-static inline void early_find_smp_config(void)
-{
-	x86_init.mpparse.find_smp_config(0);
+	x86_init.mpparse.find_smp_config();
 }
 
 #ifdef CONFIG_X86_MPPARSE
@@ -89,7 +84,7 @@ extern void default_mpc_oem_bus_info(str
 # else
 #  define default_mpc_oem_bus_info NULL
 # endif
-extern void default_find_smp_config(unsigned int reserve);
+extern void default_find_smp_config(void);
 extern void default_get_smp_config(unsigned int early);
 #else
 static inline void early_reserve_e820_mpc_new(void) { }
@@ -97,7 +92,7 @@ static inline void early_reserve_e820_mp
 #define default_mpc_apic_id NULL
 #define default_smp_read_mpc_oem NULL
 #define default_mpc_oem_bus_info NULL
-#define default_find_smp_config x86_init_uint_noop
+#define default_find_smp_config x86_init_noop
 #define default_get_smp_config x86_init_uint_noop
 #endif
 
@@ -163,14 +158,16 @@ typedef struct physid_mask physid_mask_t
 #define physids_shift_left(d, s, n)				\
 	bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS)
 
-#define physids_coerce(map)			((map).mask[0])
+static inline unsigned long physids_coerce(physid_mask_t *map)
+{
+	return map->mask[0];
+}
 
-#define physids_promote(physids)					\
-	({								\
-		physid_mask_t __physid_mask = PHYSID_MASK_NONE;		\
-		__physid_mask.mask[0] = physids;			\
-		__physid_mask;						\
-	})
+static inline void physids_promote(unsigned long physids, physid_mask_t *map)
+{
+	physids_clear(*map);
+	map->mask[0] = physids;
+}
 
 /* Note: will create very large stack frames if physid_mask_t is big */
 #define physid_mask_of_physid(physid)					\
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/msr.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/msr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,18 @@ struct msr {
 	};
 };
 
+struct msr_info {
+	u32 msr_no;
+	struct msr reg;
+	struct msr *msrs;
+	int err;
+};
+
+struct msr_regs_info {
+	u32 *regs;
+	int err;
+};
+
 static inline unsigned long long native_read_tscp(unsigned int *aux)
 {
 	unsigned long low, high;
@@ -240,15 +252,18 @@ do {
 #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),		\
 					     (u32)((val) >> 32))
 
-#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2))
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
 
-#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
+
+struct msr *msrs_alloc(void);
+void msrs_free(struct msr *msrs);
 
 #ifdef CONFIG_SMP
 int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
 int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
-void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
-void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
 int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
 int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
 int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
@@ -264,12 +279,12 @@ static inline int wrmsr_on_cpu(unsigned
 	wrmsr(msr_no, l, h);
 	return 0;
 }
-static inline void rdmsr_on_cpus(const cpumask_t *m, u32 msr_no,
+static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
 				struct msr *msrs)
 {
        rdmsr_on_cpu(0, msr_no, &(msrs[0].l), &(msrs[0].h));
 }
-static inline void wrmsr_on_cpus(const cpumask_t *m, u32 msr_no,
+static inline void wrmsr_on_cpus(const struct cpumask *m, u32 msr_no,
 				struct msr *msrs)
 {
        wrmsr_on_cpu(0, msr_no, msrs[0].l, msrs[0].h);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/msr-index.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr-index.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/msr-index.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/msr-index.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #define MSR_FS_BASE		0xc0000100 /* 64bit FS base */
 #define MSR_GS_BASE		0xc0000101 /* 64bit GS base */
 #define MSR_KERNEL_GS_BASE	0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX		0xc0000103 /* Auxiliary TSC */
 
 /* EFER bits: */
 #define _EFER_SCE		0  /* SYSCALL/SYSRET */
@@ -123,6 +124,7 @@
 #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
 #define FAM10H_MMIO_CONF_BASE_MASK	0xfffffff
 #define FAM10H_MMIO_CONF_BASE_SHIFT	20
+#define MSR_FAM10H_NODE_ID		0xc001100c
 
 /* K8 MSRs */
 #define MSR_K8_TOP_MEM1			0xc001001a
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/olpc.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/olpc.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/olpc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/olpc.h	2010-02-24 13:52:17.000000000 -0500
@@ -120,7 +120,7 @@ extern int olpc_ec_mask_unset(uint8_t bi
 
 /* GPIO assignments */
 
-#define OLPC_GPIO_MIC_AC	geode_gpio(1)
+#define OLPC_GPIO_MIC_AC	1
 #define OLPC_GPIO_DCON_IRQ	geode_gpio(7)
 #define OLPC_GPIO_THRM_ALRM	geode_gpio(10)
 #define OLPC_GPIO_SMB_CLK	geode_gpio(14)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/page_types.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/page_types.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/page_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/page_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,8 @@ extern unsigned long max_pfn_mapped;
 extern unsigned long init_memory_mapping(unsigned long start,
 					 unsigned long end);
 
-extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8);
 extern void free_initmem(void);
 
 #endif	/* !__ASSEMBLY__ */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/paravirt.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/paravirt.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt.h	2010-02-24 13:52:17.000000000 -0500
@@ -731,34 +731,34 @@ static inline void __set_fixmap(unsigned
 
 #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
 
-static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
+static inline int arch_spin_is_locked(struct arch_spinlock *lock)
 {
 	return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock);
 }
 
-static inline int __raw_spin_is_contended(struct raw_spinlock *lock)
+static inline int arch_spin_is_contended(struct arch_spinlock *lock)
 {
 	return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock);
 }
-#define __raw_spin_is_contended	__raw_spin_is_contended
+#define arch_spin_is_contended	arch_spin_is_contended
 
-static __always_inline void __raw_spin_lock(struct raw_spinlock *lock)
+static __always_inline void arch_spin_lock(struct arch_spinlock *lock)
 {
 	PVOP_VCALL1(pv_lock_ops.spin_lock, lock);
 }
 
-static __always_inline void __raw_spin_lock_flags(struct raw_spinlock *lock,
+static __always_inline void arch_spin_lock_flags(struct arch_spinlock *lock,
 						  unsigned long flags)
 {
 	PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags);
 }
 
-static __always_inline int __raw_spin_trylock(struct raw_spinlock *lock)
+static __always_inline int arch_spin_trylock(struct arch_spinlock *lock)
 {
 	return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock);
 }
 
-static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
+static __always_inline void arch_spin_unlock(struct arch_spinlock *lock)
 {
 	PVOP_VCALL1(pv_lock_ops.spin_unlock, lock);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/paravirt_types.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt_types.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/paravirt_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/paravirt_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -318,14 +318,14 @@ struct pv_mmu_ops {
 			   phys_addr_t phys, pgprot_t flags);
 };
 
-struct raw_spinlock;
+struct arch_spinlock;
 struct pv_lock_ops {
-	int (*spin_is_locked)(struct raw_spinlock *lock);
-	int (*spin_is_contended)(struct raw_spinlock *lock);
-	void (*spin_lock)(struct raw_spinlock *lock);
-	void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
-	int (*spin_trylock)(struct raw_spinlock *lock);
-	void (*spin_unlock)(struct raw_spinlock *lock);
+	int (*spin_is_locked)(struct arch_spinlock *lock);
+	int (*spin_is_contended)(struct arch_spinlock *lock);
+	void (*spin_lock)(struct arch_spinlock *lock);
+	void (*spin_lock_flags)(struct arch_spinlock *lock, unsigned long flags);
+	int (*spin_trylock)(struct arch_spinlock *lock);
+	void (*spin_unlock)(struct arch_spinlock *lock);
 };
 
 /* This contains all the paravirt structures: we get a convenient
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/pci_x86.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_x86.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/pci_x86.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/pci_x86.h	2010-02-24 13:52:17.000000000 -0500
@@ -118,11 +118,27 @@ extern int __init pcibios_init(void);
 
 /* pci-mmconfig.c */
 
+/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
+#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
+
+struct pci_mmcfg_region {
+	struct list_head list;
+	struct resource res;
+	u64 address;
+	char __iomem *virt;
+	u16 segment;
+	u8 start_bus;
+	u8 end_bus;
+	char name[PCI_MMCFG_RESOURCE_NAME_LEN];
+};
+
 extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
+extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
 
-extern struct acpi_mcfg_allocation *pci_mmcfg_config;
-extern int pci_mmcfg_config_num;
+extern struct list_head pci_mmcfg_list;
+
+#define PCI_MMCFG_BUS_OFFSET(bus)      ((bus) << 20)
 
 /*
  * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/percpu.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/percpu.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/percpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/percpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -74,31 +74,31 @@ extern void __bad_percpu_size(void);
 
 #define percpu_to_op(op, var, val)			\
 do {							\
-	typedef typeof(var) T__;			\
+	typedef typeof(var) pto_T__;			\
 	if (0) {					\
-		T__ tmp__;				\
-		tmp__ = (val);				\
+		pto_T__ pto_tmp__;			\
+		pto_tmp__ = (val);			\
 	}						\
 	switch (sizeof(var)) {				\
 	case 1:						\
 		asm(op "b %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "qi" ((T__)(val)));		\
+		    : "qi" ((pto_T__)(val)));		\
 		break;					\
 	case 2:						\
 		asm(op "w %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "ri" ((T__)(val)));		\
+		    : "ri" ((pto_T__)(val)));		\
 		break;					\
 	case 4:						\
 		asm(op "l %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "ri" ((T__)(val)));		\
+		    : "ri" ((pto_T__)(val)));		\
 		break;					\
 	case 8:						\
 		asm(op "q %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "re" ((T__)(val)));		\
+		    : "re" ((pto_T__)(val)));		\
 		break;					\
 	default: __bad_percpu_size();			\
 	}						\
@@ -106,31 +106,31 @@ do {							\
 
 #define percpu_from_op(op, var, constraint)		\
 ({							\
-	typeof(var) ret__;				\
+	typeof(var) pfo_ret__;				\
 	switch (sizeof(var)) {				\
 	case 1:						\
 		asm(op "b "__percpu_arg(1)",%0"		\
-		    : "=q" (ret__)			\
+		    : "=q" (pfo_ret__)			\
 		    : constraint);			\
 		break;					\
 	case 2:						\
 		asm(op "w "__percpu_arg(1)",%0"		\
-		    : "=r" (ret__)			\
+		    : "=r" (pfo_ret__)			\
 		    : constraint);			\
 		break;					\
 	case 4:						\
 		asm(op "l "__percpu_arg(1)",%0"		\
-		    : "=r" (ret__)			\
+		    : "=r" (pfo_ret__)			\
 		    : constraint);			\
 		break;					\
 	case 8:						\
 		asm(op "q "__percpu_arg(1)",%0"		\
-		    : "=r" (ret__)			\
+		    : "=r" (pfo_ret__)			\
 		    : constraint);			\
 		break;					\
 	default: __bad_percpu_size();			\
 	}						\
-	ret__;						\
+	pfo_ret__;					\
 })
 
 /*
@@ -153,6 +153,84 @@ do {							\
 #define percpu_or(var, val)	percpu_to_op("or", per_cpu__##var, val)
 #define percpu_xor(var, val)	percpu_to_op("xor", per_cpu__##var, val)
 
+#define __this_cpu_read_1(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define __this_cpu_read_2(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define __this_cpu_read_4(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+
+#define __this_cpu_write_1(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define __this_cpu_write_2(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define __this_cpu_write_4(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define __this_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
+#define __this_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
+#define __this_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
+#define __this_cpu_or_1(pcp, val)	percpu_to_op("or", (pcp), val)
+#define __this_cpu_or_2(pcp, val)	percpu_to_op("or", (pcp), val)
+#define __this_cpu_or_4(pcp, val)	percpu_to_op("or", (pcp), val)
+#define __this_cpu_xor_1(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define __this_cpu_xor_2(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define __this_cpu_xor_4(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+#define this_cpu_read_1(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define this_cpu_read_2(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define this_cpu_read_4(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define this_cpu_write_1(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define this_cpu_write_2(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define this_cpu_write_4(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define this_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
+#define this_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
+#define this_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
+#define this_cpu_or_1(pcp, val)		percpu_to_op("or", (pcp), val)
+#define this_cpu_or_2(pcp, val)		percpu_to_op("or", (pcp), val)
+#define this_cpu_or_4(pcp, val)		percpu_to_op("or", (pcp), val)
+#define this_cpu_xor_1(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define this_cpu_xor_2(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define this_cpu_xor_4(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+#define irqsafe_cpu_add_1(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_add_2(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_add_4(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_and_1(pcp, val)	percpu_to_op("and", (pcp), val)
+#define irqsafe_cpu_and_2(pcp, val)	percpu_to_op("and", (pcp), val)
+#define irqsafe_cpu_and_4(pcp, val)	percpu_to_op("and", (pcp), val)
+#define irqsafe_cpu_or_1(pcp, val)	percpu_to_op("or", (pcp), val)
+#define irqsafe_cpu_or_2(pcp, val)	percpu_to_op("or", (pcp), val)
+#define irqsafe_cpu_or_4(pcp, val)	percpu_to_op("or", (pcp), val)
+#define irqsafe_cpu_xor_1(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define irqsafe_cpu_xor_2(pcp, val)	percpu_to_op("xor", (pcp), val)
+#define irqsafe_cpu_xor_4(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+/*
+ * Per cpu atomic 64 bit operations are only available under 64 bit.
+ * 32 bit must fall back to generic operations.
+ */
+#ifdef CONFIG_X86_64
+#define __this_cpu_read_8(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define __this_cpu_write_8(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define __this_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define __this_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
+#define __this_cpu_or_8(pcp, val)	percpu_to_op("or", (pcp), val)
+#define __this_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+#define this_cpu_read_8(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
+#define this_cpu_write_8(pcp, val)	percpu_to_op("mov", (pcp), val)
+#define this_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define this_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
+#define this_cpu_or_8(pcp, val)		percpu_to_op("or", (pcp), val)
+#define this_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+#define irqsafe_cpu_add_8(pcp, val)	percpu_to_op("add", (pcp), val)
+#define irqsafe_cpu_and_8(pcp, val)	percpu_to_op("and", (pcp), val)
+#define irqsafe_cpu_or_8(pcp, val)	percpu_to_op("or", (pcp), val)
+#define irqsafe_cpu_xor_8(pcp, val)	percpu_to_op("xor", (pcp), val)
+
+#endif
+
 /* This is not atomic against other CPUs -- CPU preemption needs to be off */
 #define x86_test_and_clear_bit_percpu(bit, var)				\
 ({									\
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/perf_event.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/perf_event.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/perf_event.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/perf_event.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
 
 #define ARCH_PERFMON_EVENTSEL0_ENABLE			  (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_ANY			  (1 << 21)
 #define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
 #define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
 #define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
@@ -28,9 +29,20 @@
  */
 #define ARCH_PERFMON_EVENT_MASK				    0xffff
 
+/*
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ *  - inv
+ *  - edge
+ *  - cnt-mask
+ *  The other filters are supported by fixed counters.
+ *  The any-thread option is supported starting with v3.
+ */
+#define ARCH_PERFMON_EVENT_FILTER_MASK			0xff840000
+
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL		      0x3c
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK		(0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 		 0
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX			 0
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
 		(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/pgtable.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/pgtable.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/pgtable.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/x86_init.h>
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
@@ -270,9 +272,9 @@ static inline int is_new_memtype_allowed
 					 unsigned long new_flags)
 {
 	/*
-	 * PAT type is always WB for ISA. So no need to check.
+	 * PAT type is always WB for untracked ranges, so no need to check.
 	 */
-	if (is_ISA_range(paddr, paddr + size - 1))
+	if (x86_platform.is_untracked_pat_range(paddr, paddr + size))
 		return 1;
 
 	/*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/processor.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/processor.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/processor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/processor.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@ struct mm_struct;
 #include <linux/math64.h>
 #include <linux/init.h>
 
+#define HBP_NUM 4
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
@@ -180,7 +181,7 @@ static inline void native_cpuid(unsigned
 				unsigned int *ecx, unsigned int *edx)
 {
 	/* ecx is often an input as well as an output. */
-	asm("cpuid"
+	asm volatile("cpuid"
 	    : "=a" (*eax),
 	      "=b" (*ebx),
 	      "=c" (*ecx),
@@ -422,6 +423,8 @@ extern unsigned int xstate_size;
 extern void free_thread_xstate(struct task_struct *);
 extern struct kmem_cache *task_xstate_cachep;
 
+struct perf_event;
+
 struct thread_struct {
 	/* Cached TLS descriptors: */
 	struct desc_struct	tls_array[GDT_ENTRY_TLS_ENTRIES];
@@ -443,13 +446,12 @@ struct thread_struct {
 	unsigned long		fs;
 #endif
 	unsigned long		gs;
-	/* Hardware debugging registers: */
-	unsigned long		debugreg0;
-	unsigned long		debugreg1;
-	unsigned long		debugreg2;
-	unsigned long		debugreg3;
-	unsigned long		debugreg6;
-	unsigned long		debugreg7;
+	/* Save middle states of ptrace breakpoints */
+	struct perf_event	*ptrace_bps[HBP_NUM];
+	/* Debug status used for traps, single steps, etc... */
+	unsigned long           debugreg6;
+	/* Keep track of the exact dr7 value set by the user */
+	unsigned long           ptrace_dr7;
 	/* Fault info: */
 	unsigned long		cr2;
 	unsigned long		trap_no;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/proto.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/proto.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/proto.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/proto.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,18 +5,19 @@
 
 /* misc architecture specific prototypes */
 
-extern void early_idt_handler(void);
+void early_idt_handler(void);
 
-extern void system_call(void);
-extern void syscall_init(void);
+void system_call(void);
+void syscall_init(void);
 
-extern void ia32_syscall(void);
-extern void ia32_cstar_target(void);
-extern void ia32_sysenter_target(void);
+void ia32_syscall(void);
+void ia32_cstar_target(void);
+void ia32_sysenter_target(void);
 
-extern void syscall32_cpu_init(void);
+void syscall32_cpu_init(void);
 
-extern void check_efer(void);
+void x86_configure_nx(void);
+void x86_report_nx(void);
 
 extern int reboot_force;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/ptrace.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/ptrace.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/ptrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/ptrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,7 @@
 
 #ifdef __KERNEL__
 #include <asm/segment.h>
+#include <asm/page_types.h>
 #endif
 
 #ifndef __ASSEMBLY__
@@ -216,6 +217,67 @@ static inline unsigned long user_stack_p
 	return regs->sp;
 }
 
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:	pt_regs from which register value is gotten.
+ * @offset:	offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @addr:	address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+					   unsigned long addr)
+{
+	return ((addr & ~(THREAD_SIZE - 1))  ==
+		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @n:		stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+						      unsigned int n)
+{
+	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+	addr += n;
+	if (regs_within_kernel_stack(regs, (unsigned long)addr))
+		return *addr;
+	else
+		return 0;
+}
+
+/* Get Nth argument at function call */
+extern unsigned long regs_get_argument_nth(struct pt_regs *regs,
+					   unsigned int n);
+
 /*
  * These are defined as per linux/ptrace.h, which see.
  */
@@ -230,6 +292,8 @@ extern void user_enable_block_step(struc
 #define arch_has_block_step()	(boot_cpu_data.x86 >= 6)
 #endif
 
+#define ARCH_HAS_USER_SINGLE_STEP_INFO
+
 struct user_desc;
 extern int do_get_thread_area(struct task_struct *p, int idx,
 			      struct user_desc __user *info);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/sections.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/sections.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/sections.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/sections.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,13 @@
 #define _ASM_X86_SECTIONS_H
 
 #include <asm-generic/sections.h>
+#include <asm/uaccess.h>
 
 extern char __brk_base[], __brk_limit[];
+extern struct exception_table_entry __stop___ex_table[];
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+extern char __end_rodata_hpage_align[];
+#endif
 
 #endif	/* _ASM_X86_SECTIONS_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/sigcontext.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/sigcontext.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/sigcontext.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/sigcontext.h	2010-02-24 13:52:17.000000000 -0500
@@ -124,7 +124,7 @@ struct sigcontext {
 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the defintion of
+	 * of extended memory layout. See comments at the definition of
 	 * (struct _fpx_sw_bytes)
 	 */
 	void __user *fpstate;		/* zero when no FPU/extended context */
@@ -219,7 +219,7 @@ struct sigcontext {
 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
-	 * of extended memory layout. See comments at the defintion of
+	 * of extended memory layout. See comments at the definition of
 	 * (struct _fpx_sw_bytes)
 	 */
 	void __user *fpstate;		/* zero when no FPU/extended context */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/spinlock.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/spinlock.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/spinlock.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/spinlock.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@
 #if (NR_CPUS < 256)
 #define TICKET_SHIFT 8
 
-static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
 {
 	short inc = 0x0100;
 
@@ -77,7 +77,7 @@ static __always_inline void __ticket_spi
 		: "memory", "cc");
 }
 
-static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
 {
 	int tmp, new;
 
@@ -96,7 +96,7 @@ static __always_inline int __ticket_spin
 	return tmp;
 }
 
-static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
 {
 	asm volatile(UNLOCK_LOCK_PREFIX "incb %0"
 		     : "+m" (lock->slock)
@@ -106,7 +106,7 @@ static __always_inline void __ticket_spi
 #else
 #define TICKET_SHIFT 16
 
-static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
 {
 	int inc = 0x00010000;
 	int tmp;
@@ -127,7 +127,7 @@ static __always_inline void __ticket_spi
 		     : "memory", "cc");
 }
 
-static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
 {
 	int tmp;
 	int new;
@@ -149,7 +149,7 @@ static __always_inline int __ticket_spin
 	return tmp;
 }
 
-static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
 {
 	asm volatile(UNLOCK_LOCK_PREFIX "incw %0"
 		     : "+m" (lock->slock)
@@ -158,14 +158,14 @@ static __always_inline void __ticket_spi
 }
 #endif
 
-static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(arch_spinlock_t *lock)
 {
 	int tmp = ACCESS_ONCE(lock->slock);
 
 	return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1));
 }
 
-static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(arch_spinlock_t *lock)
 {
 	int tmp = ACCESS_ONCE(lock->slock);
 
@@ -174,43 +174,43 @@ static inline int __ticket_spin_is_conte
 
 #ifndef CONFIG_PARAVIRT_SPINLOCKS
 
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
 {
 	return __ticket_spin_is_locked(lock);
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
 {
 	return __ticket_spin_is_contended(lock);
 }
-#define __raw_spin_is_contended	__raw_spin_is_contended
+#define arch_spin_is_contended	arch_spin_is_contended
 
-static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	__ticket_spin_lock(lock);
 }
 
-static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	return __ticket_spin_trylock(lock);
 }
 
-static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	__ticket_spin_unlock(lock);
 }
 
-static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
+static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock,
 						  unsigned long flags)
 {
-	__raw_spin_lock(lock);
+	arch_spin_lock(lock);
 }
 
 #endif	/* CONFIG_PARAVIRT_SPINLOCKS */
 
-static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
 {
-	while (__raw_spin_is_locked(lock))
+	while (arch_spin_is_locked(lock))
 		cpu_relax();
 }
 
@@ -232,7 +232,7 @@ static inline void __raw_spin_unlock_wai
  * read_can_lock - would read_trylock() succeed?
  * @lock: the rwlock in question.
  */
-static inline int __raw_read_can_lock(raw_rwlock_t *lock)
+static inline int arch_read_can_lock(arch_rwlock_t *lock)
 {
 	return (int)(lock)->lock > 0;
 }
@@ -241,12 +241,12 @@ static inline int __raw_read_can_lock(ra
  * write_can_lock - would write_trylock() succeed?
  * @lock: the rwlock in question.
  */
-static inline int __raw_write_can_lock(raw_rwlock_t *lock)
+static inline int arch_write_can_lock(arch_rwlock_t *lock)
 {
 	return (lock)->lock == RW_LOCK_BIAS;
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
 		     "jns 1f\n"
@@ -255,7 +255,7 @@ static inline void __raw_read_lock(raw_r
 		     ::LOCK_PTR_REG (rw) : "memory");
 }
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
 		     "jz 1f\n"
@@ -264,7 +264,7 @@ static inline void __raw_write_lock(raw_
 		     ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
 }
 
-static inline int __raw_read_trylock(raw_rwlock_t *lock)
+static inline int arch_read_trylock(arch_rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t *)lock;
 
@@ -274,7 +274,7 @@ static inline int __raw_read_trylock(raw
 	return 0;
 }
 
-static inline int __raw_write_trylock(raw_rwlock_t *lock)
+static inline int arch_write_trylock(arch_rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t *)lock;
 
@@ -284,23 +284,23 @@ static inline int __raw_write_trylock(ra
 	return 0;
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	asm volatile(LOCK_PREFIX "addl %1, %0"
 		     : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
 }
 
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define _raw_spin_relax(lock)	cpu_relax()
-#define _raw_read_relax(lock)	cpu_relax()
-#define _raw_write_relax(lock)	cpu_relax()
+#define arch_spin_relax(lock)	cpu_relax()
+#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) { }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/spinlock_types.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/spinlock_types.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/spinlock_types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/spinlock_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,16 +5,16 @@
 # error "please don't include this file directly"
 #endif
 
-typedef struct raw_spinlock {
+typedef struct arch_spinlock {
 	unsigned int slock;
-} raw_spinlock_t;
+} arch_spinlock_t;
 
-#define __RAW_SPIN_LOCK_UNLOCKED	{ 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
 
 typedef struct {
 	unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
 
-#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
+#define __ARCH_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
 
 #endif /* _ASM_X86_SPINLOCK_TYPES_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/stacktrace.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/stacktrace.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/stacktrace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/stacktrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,29 @@ extern int kstack_depth_to_print;
 
 int x86_is_stack_id(int id, char *name);
 
+struct thread_info;
+struct stacktrace_ops;
+
+typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
+				      unsigned long *stack,
+				      unsigned long bp,
+				      const struct stacktrace_ops *ops,
+				      void *data,
+				      unsigned long *end,
+				      int *graph);
+
+extern unsigned long
+print_context_stack(struct thread_info *tinfo,
+		    unsigned long *stack, unsigned long bp,
+		    const struct stacktrace_ops *ops, void *data,
+		    unsigned long *end, int *graph);
+
+extern unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+		       unsigned long *stack, unsigned long bp,
+		       const struct stacktrace_ops *ops, void *data,
+		       unsigned long *end, int *graph);
+
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
@@ -14,6 +37,7 @@ struct stacktrace_ops {
 	void (*address)(void *data, unsigned long address, int reliable);
 	/* On negative return stop dumping */
 	int (*stack)(void *data, char *name);
+	walk_stack_t	walk_stack;
 };
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/string_32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/string_32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/string_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/string_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -177,10 +177,15 @@ static inline void *__memcpy3d(void *to,
  */
 
 #ifndef CONFIG_KMEMCHECK
+
+#if (__GNUC__ >= 4)
+#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
+#else
 #define memcpy(t, f, n)				\
 	(__builtin_constant_p((n))		\
 	 ? __constant_memcpy((t), (f), (n))	\
 	 : __memcpy((t), (f), (n)))
+#endif
 #else
 /*
  * kmemcheck becomes very happy if we use the REP instructions unconditionally,
@@ -316,11 +321,15 @@ void *__constant_c_and_count_memset(void
 	 : __memset_generic((s), (c), (count)))
 
 #define __HAVE_ARCH_MEMSET
+#if (__GNUC__ >= 4)
+#define memset(s, c, count) __builtin_memset(s, c, count)
+#else
 #define memset(s, c, count)						\
 	(__builtin_constant_p(c)					\
 	 ? __constant_c_x_memset((s), (0x01010101UL * (unsigned char)(c)), \
 				 (count))				\
 	 : __memset((s), (c), (count)))
+#endif
 
 /*
  * find the first occurrence of byte 'c', or 1 past the area if none
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/svm.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/svm.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/svm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/svm.h	2010-02-24 13:52:17.000000000 -0500
@@ -57,7 +57,8 @@ struct __attribute__ ((__packed__)) vmcb
 	u16 intercept_dr_write;
 	u32 intercept_exceptions;
 	u64 intercept;
-	u8 reserved_1[44];
+	u8 reserved_1[42];
+	u16 pause_filter_count;
 	u64 iopm_base_pa;
 	u64 msrpm_base_pa;
 	u64 tsc_offset;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/swiotlb.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/swiotlb.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/swiotlb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/swiotlb.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,15 +3,16 @@
 
 #include <linux/swiotlb.h>
 
-/* SWIOTLB interface */
-
-extern int swiotlb_force;
-
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
-extern void pci_swiotlb_init(void);
+extern int __init pci_swiotlb_detect(void);
+extern void __init pci_swiotlb_init(void);
 #else
 #define swiotlb 0
+static inline int pci_swiotlb_detect(void)
+{
+	return 0;
+}
 static inline void pci_swiotlb_init(void)
 {
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/syscalls.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscalls.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/syscalls.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/syscalls.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,16 +18,24 @@
 /* Common in X86_32 and X86_64 */
 /* kernel/ioport.c */
 asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
+long sys_iopl(unsigned int, struct pt_regs *);
 
 /* kernel/process.c */
 int sys_fork(struct pt_regs *);
 int sys_vfork(struct pt_regs *);
+long sys_execve(char __user *, char __user * __user *,
+		char __user * __user *, struct pt_regs *);
+long sys_clone(unsigned long, unsigned long, void __user *,
+	       void __user *, struct pt_regs *);
 
 /* kernel/ldt.c */
 asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
 
 /* kernel/signal.c */
 long sys_rt_sigreturn(struct pt_regs *);
+long sys_sigaltstack(const stack_t __user *, stack_t __user *,
+		     struct pt_regs *);
+
 
 /* kernel/tls.c */
 asmlinkage int sys_set_thread_area(struct user_desc __user *);
@@ -35,18 +43,11 @@ asmlinkage int sys_get_thread_area(struc
 
 /* X86_32 only */
 #ifdef CONFIG_X86_32
-/* kernel/ioport.c */
-long sys_iopl(struct pt_regs *);
-
-/* kernel/process_32.c */
-int sys_clone(struct pt_regs *);
-int sys_execve(struct pt_regs *);
 
 /* kernel/signal.c */
 asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
 asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
 			     struct old_sigaction __user *);
-int sys_sigaltstack(struct pt_regs *);
 unsigned long sys_sigreturn(struct pt_regs *);
 
 /* kernel/sys_i386_32.c */
@@ -55,8 +56,6 @@ struct sel_arg_struct;
 struct oldold_utsname;
 struct old_utsname;
 
-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
-			  unsigned long, unsigned long, unsigned long);
 asmlinkage int old_mmap(struct mmap_arg_struct __user *);
 asmlinkage int old_select(struct sel_arg_struct __user *);
 asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
@@ -64,28 +63,15 @@ asmlinkage int sys_uname(struct old_utsn
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
 
 /* kernel/vm86_32.c */
-int sys_vm86old(struct pt_regs *);
-int sys_vm86(struct pt_regs *);
+int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
+int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
 
 #else /* CONFIG_X86_32 */
 
 /* X86_64 only */
-/* kernel/ioport.c */
-asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
-
 /* kernel/process_64.c */
-asmlinkage long sys_clone(unsigned long, unsigned long,
-			  void __user *, void __user *,
-			  struct pt_regs *);
-asmlinkage long sys_execve(char __user *, char __user * __user *,
-			   char __user * __user *,
-			   struct pt_regs *);
 long sys_arch_prctl(int, unsigned long);
 
-/* kernel/signal.c */
-asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
-				struct pt_regs *);
-
 /* kernel/sys_x86_64.c */
 struct new_utsname;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/sys_ia32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/sys_ia32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/sys_ia32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/sys_ia32.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,6 @@ struct mmap_arg_struct;
 asmlinkage long sys32_mmap(struct mmap_arg_struct __user *);
 asmlinkage long sys32_mprotect(unsigned long, size_t, unsigned long);
 
-asmlinkage long sys32_pipe(int __user *);
 struct sigaction32;
 struct old_sigaction32;
 asmlinkage long sys32_rt_sigaction(int, struct sigaction32 __user *,
@@ -51,20 +50,12 @@ asmlinkage long sys32_sched_rr_get_inter
 asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *, compat_size_t);
 asmlinkage long sys32_rt_sigqueueinfo(int, int, compat_siginfo_t __user *);
 
-#ifdef CONFIG_SYSCTL_SYSCALL
-struct sysctl_ia32;
-asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *);
-#endif
-
 asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32);
 asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32);
 
 asmlinkage long sys32_personality(unsigned long);
 asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
 
-asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long,
-			    unsigned long, unsigned long, unsigned long);
-
 struct oldold_utsname;
 struct old_utsname;
 asmlinkage long sys32_olduname(struct oldold_utsname __user *);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/system.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/system.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/system.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/system.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,9 +11,9 @@
 #include <linux/irqflags.h>
 
 /* entries in ARCH_DLINFO: */
-#ifdef CONFIG_IA32_EMULATION
+#if defined(CONFIG_IA32_EMULATION) || !defined(CONFIG_X86_64)
 # define AT_VECTOR_SIZE_ARCH 2
-#else
+#else /* else it's non-compat x86-64 */
 # define AT_VECTOR_SIZE_ARCH 1
 #endif
 
@@ -23,6 +23,7 @@ struct task_struct *__switch_to(struct t
 struct tss_struct;
 void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 		      struct tss_struct *tss);
+extern void show_regs_common(void);
 
 #ifdef CONFIG_X86_32
 
@@ -128,8 +129,6 @@ do {									\
 	     "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */	  \
 	     "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */	  \
 	     "call __switch_to\n\t"					  \
-	     ".globl thread_return\n"					  \
-	     "thread_return:\n\t"					  \
 	     "movq "__percpu_arg([current_task])",%%rsi\n\t"		  \
 	     __switch_canary						  \
 	     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
@@ -157,19 +156,22 @@ extern void native_load_gs_index(unsigne
  * Load a segment. Fall back on loading the zero
  * segment if something goes wrong..
  */
-#define loadsegment(seg, value)			\
-	asm volatile("\n"			\
-		     "1:\t"			\
-		     "movl %k0,%%" #seg "\n"	\
-		     "2:\n"			\
-		     ".section .fixup,\"ax\"\n"	\
-		     "3:\t"			\
-		     "movl %k1, %%" #seg "\n\t"	\
-		     "jmp 2b\n"			\
-		     ".previous\n"		\
-		     _ASM_EXTABLE(1b,3b)	\
-		     : :"r" (value), "r" (0) : "memory")
-
+#define loadsegment(seg, value)						\
+do {									\
+	unsigned short __val = (value);					\
+									\
+	asm volatile("						\n"	\
+		     "1:	movl %k0,%%" #seg "		\n"	\
+									\
+		     ".section .fixup,\"ax\"			\n"	\
+		     "2:	xorl %k0,%k0			\n"	\
+		     "		jmp 1b				\n"	\
+		     ".previous					\n"	\
+									\
+		     _ASM_EXTABLE(1b, 2b)				\
+									\
+		     : "+r" (__val) : : "memory");			\
+} while (0)
 
 /*
  * Save a segment register away
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/thread_info.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/thread_info.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/thread_info.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/thread_info.h	2010-02-24 13:52:17.000000000 -0500
@@ -83,10 +83,10 @@ struct thread_info {
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
+#define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* 32bit process */
 #define TIF_FORK		18	/* ret_from_fork */
-#define TIF_ABI_PENDING		19
 #define TIF_MEMDIE		20
 #define TIF_DEBUG		21	/* uses debug registers */
 #define TIF_IO_BITMAP		22	/* uses I/O bitmap */
@@ -107,10 +107,10 @@ struct thread_info {
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
+#define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_FORK		(1 << TIF_FORK)
-#define _TIF_ABI_PENDING	(1 << TIF_ABI_PENDING)
 #define _TIF_DEBUG		(1 << TIF_DEBUG)
 #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
@@ -142,13 +142,14 @@ struct thread_info {
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK						\
-	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
+	(_TIF_SIGPENDING | _TIF_MCE_NOTIFY | _TIF_NOTIFY_RESUME |	\
+	 _TIF_USER_RETURN_NOTIFY)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW							\
 	(_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_NOTSC)
 
-#define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW
+#define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
 
 #define PREEMPT_ACTIVE		0x10000000
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/topology.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/topology.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/topology.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/topology.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,11 +35,16 @@
 # endif
 #endif
 
-/* Node not present */
-#define NUMA_NO_NODE	(-1)
+/*
+ * to preserve the visibility of NUMA_NO_NODE definition,
+ * moved to there from here.  May be used independent of
+ * CONFIG_NUMA.
+ */
+#include <linux/numa.h>
 
 #ifdef CONFIG_NUMA
 #include <linux/cpumask.h>
+
 #include <asm/mpspec.h>
 
 #ifdef CONFIG_X86_32
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/trampoline.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/trampoline.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/trampoline.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/trampoline.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,6 @@ extern unsigned long initial_code;
 extern unsigned long initial_gs;
 
 #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
-#define TRAMPOLINE_BASE 0x6000
 
 extern unsigned long setup_trampoline(void);
 extern void __init reserve_trampoline_memory(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess_32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -187,9 +187,33 @@ __copy_from_user_inatomic_nocache(void *
 
 unsigned long __must_check copy_to_user(void __user *to,
 					const void *from, unsigned long n);
-unsigned long __must_check copy_from_user(void *to,
+unsigned long __must_check _copy_from_user(void *to,
 					  const void __user *from,
 					  unsigned long n);
+
+
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+	__compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+	__compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
+static inline unsigned long __must_check copy_from_user(void *to,
+					  const void __user *from,
+					  unsigned long n)
+{
+	int sz = __compiletime_object_size(to);
+
+	if (likely(sz == -1 || sz >= n))
+		n = _copy_from_user(to, from, n);
+	else
+		copy_from_user_overflow();
+
+	return n;
+}
+
 long __must_check strncpy_from_user(char *dst, const char __user *src,
 				    long count);
 long __must_check __strncpy_from_user(char *dst,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess_64.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_64.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,12 +19,36 @@ __must_check unsigned long
 copy_user_generic(void *to, const void *from, unsigned len);
 
 __must_check unsigned long
-copy_to_user(void __user *to, const void *from, unsigned len);
+_copy_to_user(void __user *to, const void *from, unsigned len);
 __must_check unsigned long
-copy_from_user(void *to, const void __user *from, unsigned len);
+_copy_from_user(void *to, const void __user *from, unsigned len);
 __must_check unsigned long
 copy_in_user(void __user *to, const void __user *from, unsigned len);
 
+static inline unsigned long __must_check copy_from_user(void *to,
+					  const void __user *from,
+					  unsigned long n)
+{
+	int sz = __compiletime_object_size(to);
+
+	might_fault();
+	if (likely(sz == -1 || sz >= n))
+		n = _copy_from_user(to, from, n);
+#ifdef CONFIG_DEBUG_VM
+	else
+		WARN(1, "Buffer overflow detected!\n");
+#endif
+	return n;
+}
+
+static __always_inline __must_check
+int copy_to_user(void __user *dst, const void *src, unsigned size)
+{
+	might_fault();
+
+	return _copy_to_user(dst, src, size);
+}
+
 static __always_inline __must_check
 int __copy_from_user(void *dst, const void __user *src, unsigned size)
 {
@@ -176,8 +200,11 @@ __must_check long strlen_user(const char
 __must_check unsigned long clear_user(void __user *mem, unsigned long len);
 __must_check unsigned long __clear_user(void __user *mem, unsigned long len);
 
-__must_check long __copy_from_user_inatomic(void *dst, const void __user *src,
-					    unsigned size);
+static __must_check __always_inline int
+__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
+{
+	return copy_user_generic(dst, (__force const void *)src, size);
+}
 
 static __must_check __always_inline int
 __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uaccess.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uaccess.h	2010-02-24 13:52:17.000000000 -0500
@@ -570,7 +570,6 @@ extern struct movsl_mask {
 #ifdef CONFIG_X86_32
 # include "uaccess_32.h"
 #else
-# define ARCH_HAS_SEARCH_EXTABLE
 # include "uaccess_64.h"
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/unistd_32.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_32.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/unistd_32.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_32.h	2010-02-24 13:52:17.000000000 -0500
@@ -342,10 +342,11 @@
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
 #define __NR_perf_event_open	336
+#define __NR_recvmmsg		337
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 337
+#define NR_syscalls 338
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/unistd_64.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_64.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/unistd_64.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/unistd_64.h	2010-02-24 13:52:17.000000000 -0500
@@ -661,6 +661,8 @@ __SYSCALL(__NR_pwritev, sys_pwritev)
 __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
 #define __NR_perf_event_open			298
 __SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+#define __NR_recvmmsg				299
+__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/bios.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/bios.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/bios.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/bios.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,15 +76,6 @@ union partition_info_u {
 	};
 };
 
-union uv_watchlist_u {
-	u64	val;
-	struct {
-		u64	blade	: 16,
-			size	: 32,
-			filler	: 16;
-	};
-};
-
 enum uv_memprotect {
 	UV_MEMPROT_RESTRICT_ACCESS,
 	UV_MEMPROT_ALLOW_AMO,
@@ -100,7 +91,7 @@ extern s64 uv_bios_call_reentrant(enum u
 
 extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
 extern s64 uv_bios_freq_base(u64, u64 *);
-extern int uv_bios_mq_watchlist_alloc(int, unsigned long, unsigned int,
+extern int uv_bios_mq_watchlist_alloc(unsigned long, unsigned int,
 					unsigned long *);
 extern int uv_bios_mq_watchlist_free(int, int);
 extern s64 uv_bios_change_memprotect(u64, u64, enum uv_memprotect);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_bau.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_bau.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_bau.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_bau.h	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,7 @@
 #define DESC_STATUS_SOURCE_TIMEOUT	3
 
 /*
- * source side threshholds at which message retries print a warning
+ * source side thresholds at which message retries print a warning
  */
 #define SOURCE_TIMEOUT_LIMIT		20
 #define DESTINATION_TIMEOUT_LIMIT	20
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_hub.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_hub.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_hub.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_hub.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,20 +31,20 @@
  *		  contiguous (although various IO spaces may punch holes in
  *		  it)..
  *
- * 	N	- Number of bits in the node portion of a socket physical
- * 		  address.
+ *	N	- Number of bits in the node portion of a socket physical
+ *		  address.
  *
- * 	NASID   - network ID of a router, Mbrick or Cbrick. Nasid values of
- * 	 	  routers always have low bit of 1, C/MBricks have low bit
- * 		  equal to 0. Most addressing macros that target UV hub chips
- * 		  right shift the NASID by 1 to exclude the always-zero bit.
- * 		  NASIDs contain up to 15 bits.
+ *	NASID   - network ID of a router, Mbrick or Cbrick. Nasid values of
+ *		  routers always have low bit of 1, C/MBricks have low bit
+ *		  equal to 0. Most addressing macros that target UV hub chips
+ *		  right shift the NASID by 1 to exclude the always-zero bit.
+ *		  NASIDs contain up to 15 bits.
  *
  *	GNODE   - NASID right shifted by 1 bit. Most mmrs contain gnodes instead
  *		  of nasids.
  *
- * 	PNODE   - the low N bits of the GNODE. The PNODE is the most useful variant
- * 		  of the nasid for socket usage.
+ *	PNODE   - the low N bits of the GNODE. The PNODE is the most useful variant
+ *		  of the nasid for socket usage.
  *
  *
  *  NumaLink Global Physical Address Format:
@@ -71,12 +71,12 @@
  *
  *
  * APICID format
- * 	NOTE!!!!!! This is the current format of the APICID. However, code
- * 	should assume that this will change in the future. Use functions
- * 	in this file for all APICID bit manipulations and conversion.
+ *	NOTE!!!!!! This is the current format of the APICID. However, code
+ *	should assume that this will change in the future. Use functions
+ *	in this file for all APICID bit manipulations and conversion.
  *
- * 		1111110000000000
- * 		5432109876543210
+ *		1111110000000000
+ *		5432109876543210
  *		pppppppppplc0cch
  *		sssssssssss
  *
@@ -89,9 +89,9 @@
  *	Note: Processor only supports 12 bits in the APICID register. The ACPI
  *	      tables hold all 16 bits. Software needs to be aware of this.
  *
- * 	      Unless otherwise specified, all references to APICID refer to
- * 	      the FULL value contained in ACPI tables, not the subset in the
- * 	      processor APICID register.
+ *	      Unless otherwise specified, all references to APICID refer to
+ *	      the FULL value contained in ACPI tables, not the subset in the
+ *	      processor APICID register.
  */
 
 
@@ -151,16 +151,16 @@ struct uv_hub_info_s {
 };
 
 DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
-#define uv_hub_info 		(&__get_cpu_var(__uv_hub_info))
+#define uv_hub_info		(&__get_cpu_var(__uv_hub_info))
 #define uv_cpu_hub_info(cpu)	(&per_cpu(__uv_hub_info, cpu))
 
 /*
  * Local & Global MMR space macros.
- * 	Note: macros are intended to be used ONLY by inline functions
- * 	in this file - not by other kernel code.
- * 		n -  NASID (full 15-bit global nasid)
- * 		g -  GNODE (full 15-bit global nasid, right shifted 1)
- * 		p -  PNODE (local part of nsids, right shifted 1)
+ *	Note: macros are intended to be used ONLY by inline functions
+ *	in this file - not by other kernel code.
+ *		n -  NASID (full 15-bit global nasid)
+ *		g -  GNODE (full 15-bit global nasid, right shifted 1)
+ *		p -  PNODE (local part of nsids, right shifted 1)
  */
 #define UV_NASID_TO_PNODE(n)		(((n) >> 1) & uv_hub_info->pnode_mask)
 #define UV_PNODE_TO_GNODE(p)		((p) |uv_hub_info->gnode_extra)
@@ -172,6 +172,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __
 #define UV_LOCAL_MMR_SIZE		(64UL * 1024 * 1024)
 #define UV_GLOBAL_MMR32_SIZE		(64UL * 1024 * 1024)
 
+#define UV_GLOBAL_GRU_MMR_BASE		0x4000000
+
 #define UV_GLOBAL_MMR32_PNODE_SHIFT	15
 #define UV_GLOBAL_MMR64_PNODE_SHIFT	26
 
@@ -213,8 +215,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __
 /*
  * Macros for converting between kernel virtual addresses, socket local physical
  * addresses, and UV global physical addresses.
- * 	Note: use the standard __pa() & __va() macros for converting
- * 	      between socket virtual and socket physical addresses.
+ *	Note: use the standard __pa() & __va() macros for converting
+ *	      between socket virtual and socket physical addresses.
  */
 
 /* socket phys RAM --> UV global physical address */
@@ -232,6 +234,26 @@ static inline unsigned long uv_gpa(void
 	return uv_soc_phys_ram_to_gpa(__pa(v));
 }
 
+/* Top two bits indicate the requested address is in MMR space.  */
+static inline int
+uv_gpa_in_mmr_space(unsigned long gpa)
+{
+	return (gpa >> 62) == 0x3UL;
+}
+
+/* UV global physical address --> socket phys RAM */
+static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
+{
+	unsigned long paddr = gpa & uv_hub_info->gpa_mask;
+	unsigned long remap_base = uv_hub_info->lowmem_remap_base;
+	unsigned long remap_top =  uv_hub_info->lowmem_remap_top;
+
+	if (paddr >= remap_base && paddr < remap_base + remap_top)
+		paddr -= remap_base;
+	return paddr;
+}
+
+
 /* gnode -> pnode */
 static inline unsigned long uv_gpa_to_gnode(unsigned long gpa)
 {
@@ -265,21 +287,18 @@ static inline int uv_apicid_to_pnode(int
  * Access global MMRs using the low memory MMR32 space. This region supports
  * faster MMR access but not all MMRs are accessible in this space.
  */
-static inline unsigned long *uv_global_mmr32_address(int pnode,
-				unsigned long offset)
+static inline unsigned long *uv_global_mmr32_address(int pnode, unsigned long offset)
 {
 	return __va(UV_GLOBAL_MMR32_BASE |
 		       UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset);
 }
 
-static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
-				 unsigned long val)
+static inline void uv_write_global_mmr32(int pnode, unsigned long offset, unsigned long val)
 {
 	writeq(val, uv_global_mmr32_address(pnode, offset));
 }
 
-static inline unsigned long uv_read_global_mmr32(int pnode,
-						 unsigned long offset)
+static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset)
 {
 	return readq(uv_global_mmr32_address(pnode, offset));
 }
@@ -288,26 +307,42 @@ static inline unsigned long uv_read_glob
  * Access Global MMR space using the MMR space located at the top of physical
  * memory.
  */
-static inline unsigned long *uv_global_mmr64_address(int pnode,
-				unsigned long offset)
+static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset)
 {
 	return __va(UV_GLOBAL_MMR64_BASE |
 		    UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
 }
 
-static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
-				unsigned long val)
+static inline void uv_write_global_mmr64(int pnode, unsigned long offset, unsigned long val)
 {
 	writeq(val, uv_global_mmr64_address(pnode, offset));
 }
 
-static inline unsigned long uv_read_global_mmr64(int pnode,
-						 unsigned long offset)
+static inline unsigned long uv_read_global_mmr64(int pnode, unsigned long offset)
 {
 	return readq(uv_global_mmr64_address(pnode, offset));
 }
 
 /*
+ * Global MMR space addresses when referenced by the GRU. (GRU does
+ * NOT use socket addressing).
+ */
+static inline unsigned long uv_global_gru_mmr_address(int pnode, unsigned long offset)
+{
+	return UV_GLOBAL_GRU_MMR_BASE | offset | (pnode << uv_hub_info->m_val);
+}
+
+static inline void uv_write_global_mmr8(int pnode, unsigned long offset, unsigned char val)
+{
+	writeb(val, uv_global_mmr64_address(pnode, offset));
+}
+
+static inline unsigned char uv_read_global_mmr8(int pnode, unsigned long offset)
+{
+	return readb(uv_global_mmr64_address(pnode, offset));
+}
+
+/*
  * Access hub local MMRs. Faster than using global space but only local MMRs
  * are accessible.
  */
@@ -426,14 +461,28 @@ static inline void uv_set_scir_bits(unsi
 	}
 }
 
+static inline unsigned long uv_scir_offset(int apicid)
+{
+	return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f);
+}
+
 static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
 {
 	if (uv_cpu_hub_info(cpu)->scir.state != value) {
+		uv_write_global_mmr8(uv_cpu_to_pnode(cpu),
+				uv_cpu_hub_info(cpu)->scir.offset, value);
 		uv_cpu_hub_info(cpu)->scir.state = value;
-		uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
 	}
 }
 
+static unsigned long uv_hub_ipi_value(int apicid, int vector, int mode)
+{
+	return (1UL << UVH_IPI_INT_SEND_SHFT) |
+			((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
+			(mode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
+			(vector << UVH_IPI_INT_VECTOR_SHFT);
+}
+
 static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
 {
 	unsigned long val;
@@ -442,12 +491,21 @@ static inline void uv_hub_send_ipi(int p
 	if (vector == NMI_VECTOR)
 		dmode = dest_NMI;
 
-	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
-			((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
-			(dmode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
-			(vector << UVH_IPI_INT_VECTOR_SHFT);
+	val = uv_hub_ipi_value(apicid, vector, dmode);
 	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
 }
 
+/*
+ * Get the minimum revision number of the hub chips within the partition.
+ *     1 - initial rev 1.0 silicon
+ *     2 - rev 2.0 production silicon
+ */
+static inline int uv_get_min_hub_revision_id(void)
+{
+	extern int uv_min_hub_revision_id;
+
+	return uv_min_hub_revision_id;
+}
+
 #endif /* CONFIG_X86_64 */
 #endif /* _ASM_X86_UV_UV_HUB_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_irq.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_irq.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/uv/uv_irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/uv/uv_irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,12 +25,14 @@ struct uv_IO_APIC_route_entry {
 		dest		: 32;
 };
 
-extern struct irq_chip uv_irq_chip;
-
-extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
-extern void arch_disable_uv_irq(int, unsigned long);
+enum {
+	UV_AFFINITY_ALL,
+	UV_AFFINITY_NODE,
+	UV_AFFINITY_CPU
+};
 
-extern int uv_setup_irq(char *, int, int, unsigned long);
-extern void uv_teardown_irq(unsigned int, int, unsigned long);
+extern int uv_irq_2_mmr_info(int, unsigned long *, int *);
+extern int uv_setup_irq(char *, int, int, unsigned long, int);
+extern void uv_teardown_irq(unsigned int);
 
 #endif /* _ASM_X86_UV_UV_IRQ_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/vmx.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/vmx.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/vmx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/vmx.h	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,7 @@
 #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
 #define SECONDARY_EXEC_WBINVD_EXITING		0x00000040
 #define SECONDARY_EXEC_UNRESTRICTED_GUEST	0x00000080
+#define SECONDARY_EXEC_PAUSE_LOOP_EXITING	0x00000400
 
 
 #define PIN_BASED_EXT_INTR_MASK                 0x00000001
@@ -144,6 +145,8 @@ enum vmcs_field {
 	VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
 	TPR_THRESHOLD                   = 0x0000401c,
 	SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
+	PLE_GAP                         = 0x00004020,
+	PLE_WINDOW                      = 0x00004022,
 	VM_INSTRUCTION_ERROR            = 0x00004400,
 	VM_EXIT_REASON                  = 0x00004402,
 	VM_EXIT_INTR_INFO               = 0x00004404,
@@ -248,6 +251,7 @@ enum vmcs_field {
 #define EXIT_REASON_MSR_READ            31
 #define EXIT_REASON_MSR_WRITE           32
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
+#define EXIT_REASON_PAUSE_INSTRUCTION   40
 #define EXIT_REASON_MCE_DURING_VMENTRY	 41
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
 #define EXIT_REASON_APIC_ACCESS         44
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/x86_init.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/x86_init.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/x86_init.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/x86_init.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,7 @@ struct x86_init_mpparse {
 	void (*smp_read_mpc_oem)(struct mpc_table *mpc);
 	void (*mpc_oem_pci_bus)(struct mpc_bus *m);
 	void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
-	void (*find_smp_config)(unsigned int reserve);
+	void (*find_smp_config)(void);
 	void (*get_smp_config)(unsigned int early);
 };
 
@@ -91,6 +91,14 @@ struct x86_init_timers {
 };
 
 /**
+ * struct x86_init_iommu - platform specific iommu setup
+ * @iommu_init:			platform specific iommu setup
+ */
+struct x86_init_iommu {
+	int (*iommu_init)(void);
+};
+
+/**
  * struct x86_init_ops - functions for platform specific setup
  *
  */
@@ -101,6 +109,7 @@ struct x86_init_ops {
 	struct x86_init_oem		oem;
 	struct x86_init_paging		paging;
 	struct x86_init_timers		timers;
+	struct x86_init_iommu		iommu;
 };
 
 /**
@@ -116,11 +125,14 @@ struct x86_cpuinit_ops {
  * @calibrate_tsc:		calibrate TSC
  * @get_wallclock:		get time from HW clock like RTC etc.
  * @set_wallclock:		set time back to HW clock
+ * @is_untracked_pat_range	exclude from PAT logic
  */
 struct x86_platform_ops {
 	unsigned long (*calibrate_tsc)(void);
 	unsigned long (*get_wallclock)(void);
 	int (*set_wallclock)(unsigned long nowtime);
+	void (*iommu_shutdown)(void);
+	bool (*is_untracked_pat_range)(u64 start, u64 end);
 };
 
 extern struct x86_init_ops x86_init;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/include/asm/xen/hypervisor.h linux-libre-2.6.33-gnu1/arch/x86/include/asm/xen/hypervisor.h
--- linux-libre-2.6.32-gnu1/arch/x86/include/asm/xen/hypervisor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/include/asm/xen/hypervisor.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,31 +37,4 @@
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
 
-enum xen_domain_type {
-	XEN_NATIVE,		/* running on bare hardware    */
-	XEN_PV_DOMAIN,		/* running in a PV domain      */
-	XEN_HVM_DOMAIN,		/* running in a Xen hvm domain */
-};
-
-#ifdef CONFIG_XEN
-extern enum xen_domain_type xen_domain_type;
-#else
-#define xen_domain_type		XEN_NATIVE
-#endif
-
-#define xen_domain()		(xen_domain_type != XEN_NATIVE)
-#define xen_pv_domain()		(xen_domain() &&			\
-				 xen_domain_type == XEN_PV_DOMAIN)
-#define xen_hvm_domain()	(xen_domain() &&			\
-				 xen_domain_type == XEN_HVM_DOMAIN)
-
-#ifdef CONFIG_XEN_DOM0
-#include <xen/interface/xen.h>
-
-#define xen_initial_domain()	(xen_pv_domain() && \
-				 xen_start_info->flags & SIF_INITDOMAIN)
-#else  /* !CONFIG_XEN_DOM0 */
-#define xen_initial_domain()	(0)
-#endif	/* CONFIG_XEN_DOM0 */
-
 #endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/Kconfig linux-libre-2.6.33-gnu1/arch/x86/Kconfig
--- linux-libre-2.6.32-gnu1/arch/x86/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,12 @@ config X86
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
+	select HAVE_KERNEL_LZO
+	select HAVE_HW_BREAKPOINT
+	select PERF_EVENTS
+	select ANON_INODES
 	select HAVE_ARCH_KMEMCHECK
+	select HAVE_USER_RETURN_NOTIFIER
 
 config OUTPUT_FORMAT
 	string
@@ -984,12 +989,6 @@ config X86_CPUID
 	  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
 	  /dev/cpu/31/cpuid.
 
-config X86_CPU_DEBUG
-	tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
-	---help---
-	  If you select this option, this will provide various x86 CPUs
-	  information through debugfs.
-
 choice
 	prompt "High Memory Support"
 	default HIGHMEM4G if !X86_NUMAQ
@@ -1242,6 +1241,11 @@ config ARCH_MEMORY_PROBE
 	def_bool X86_64
 	depends on MEMORY_HOTPLUG
 
+config ILLEGAL_POINTER_VALUE
+       hex
+       default 0 if X86_32
+       default 0xdead000000000000 if X86_64
+
 source "mm/Kconfig"
 
 config HIGHPTE
@@ -1330,7 +1334,9 @@ config MATH_EMULATION
 	  kernel, it won't hurt.
 
 config MTRR
-	bool "MTRR (Memory Type Range Register) support"
+	bool
+	default y
+	prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
 	---help---
 	  On Intel P6 family processors (Pentium Pro, Pentium II and later)
 	  the Memory Type Range Registers (MTRRs) may be used to control
@@ -1396,7 +1402,8 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAU
 
 config X86_PAT
 	bool
-	prompt "x86 PAT support"
+	default y
+	prompt "x86 PAT support" if EMBEDDED
 	depends on MTRR
 	---help---
 	  Use PAT attributes to setup page level cache control.
@@ -1602,7 +1609,7 @@ config COMPAT_VDSO
 	depends on X86_32 || IA32_EMULATION
 	---help---
 	  Map the 32-bit VDSO to the predictable old-style address too.
-	---help---
+
 	  Say N here if you are running a sufficiently recent glibc
 	  version (2.3.3 or later), to remove the high-mapped
 	  VDSO mapping and to exclusively use the randomized VDSO.
@@ -2007,18 +2014,9 @@ config SCx200HR_TIMER
 	  processor goes idle (as is done by the scheduler).  The
 	  other workaround is idle=poll boot option.
 
-config GEODE_MFGPT_TIMER
-	def_bool y
-	prompt "Geode Multi-Function General Purpose Timer (MFGPT) events"
-	depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
-	---help---
-	  This driver provides a clock event source based on the MFGPT
-	  timer(s) in the CS5535 and CS5536 companion chip for the geode.
-	  MFGPTs have a better resolution and max interval than the
-	  generic PIT, and are suitable for use as high-res timers.
-
 config OLPC
 	bool "One Laptop Per Child support"
+	select GPIOLIB
 	default n
 	---help---
 	  Add support for detecting the unique features of the OLPC
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/Kconfig.cpu linux-libre-2.6.33-gnu1/arch/x86/Kconfig.cpu
--- linux-libre-2.6.32-gnu1/arch/x86/Kconfig.cpu	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/Kconfig.cpu	2010-02-24 13:52:17.000000000 -0500
@@ -301,15 +301,11 @@ config X86_CPU
 
 #
 # Define implied options from the CPU selection here
-config X86_L1_CACHE_BYTES
-	int
-	default "128" if MPSC
-	default "64" if GENERIC_CPU || MK8 || MCORE2 || MATOM || X86_32
-
-config X86_INTERNODE_CACHE_BYTES
+config X86_INTERNODE_CACHE_SHIFT
 	int
-	default "4096" if X86_VSMP
-	default X86_L1_CACHE_BYTES if !X86_VSMP
+	default "12" if X86_VSMP
+	default "7" if NUMA
+	default X86_L1_CACHE_SHIFT
 
 config X86_CMPXCHG
 	def_bool X86_64 || (X86_32 && !M386)
@@ -317,9 +313,9 @@ config X86_CMPXCHG
 config X86_L1_CACHE_SHIFT
 	int
 	default "7" if MPENTIUM4 || MPSC
+	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
 	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
 
 config X86_XADD
 	def_bool y
@@ -400,13 +396,13 @@ config X86_TSC
 
 config X86_CMPXCHG64
 	def_bool y
-	depends on !M386 && !M486
+	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
 
 # this should be set for all -march=.. options where the compiler
 # generates cmov.
 config X86_CMOV
 	def_bool y
-	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM)
+	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
 
 config X86_MINIMUM_CPU_FAMILY
 	int
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/Kconfig.debug linux-libre-2.6.33-gnu1/arch/x86/Kconfig.debug
--- linux-libre-2.6.32-gnu1/arch/x86/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -186,6 +186,15 @@ config X86_DS_SELFTEST
 config HAVE_MMIOTRACE_SUPPORT
 	def_bool y
 
+config X86_DECODER_SELFTEST
+	bool "x86 instruction decoder selftest"
+	depends on DEBUG_KERNEL && KPROBES
+	---help---
+	 Perform x86 instruction decoder selftests at build time.
+	 This option is useful for checking the sanity of x86 instruction
+	 decoder code.
+	 If unsure, say "N".
+
 #
 # IO delay types:
 #
@@ -287,4 +296,18 @@ config OPTIMIZE_INLINING
 
 	  If unsure, say N.
 
+config DEBUG_STRICT_USER_COPY_CHECKS
+	bool "Strict copy size checks"
+	depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+	---help---
+	  Enabling this option turns a certain set of sanity checks for user
+	  copy operations into compile time failures.
+
+	  The copy_from_user() etc checks are there to help test if there
+	  are sufficient security checks on the length argument of
+	  the copy operation, by having gcc prove that the argument is
+	  within bounds.
+
+	  If unsure, or if you run an older (pre 4.4) gcc, say N.
+
 endmenu
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/boot.c linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/boot.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/boot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/boot.c	2010-02-24 13:52:17.000000000 -0500
@@ -624,6 +624,7 @@ static int __init acpi_parse_hpet(struct
 	}
 
 	hpet_address = hpet_tbl->address.address;
+	hpet_blockid = hpet_tbl->sequence;
 
 	/*
 	 * Some broken BIOSes advertise HPET at 0x0. We really do not
@@ -1122,7 +1123,7 @@ static int __init acpi_parse_madt_ioapic
 	if (!acpi_sci_override_gsi)
 		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
 
-	/* Fill in identity legacy mapings where no override */
+	/* Fill in identity legacy mappings where no override */
 	mp_config_acpi_legacy_irqs();
 
 	count =
@@ -1184,9 +1185,6 @@ static void __init acpi_process_madt(voi
 		if (!error) {
 			acpi_lapic = 1;
 
-#ifdef CONFIG_X86_BIGSMP
-			generic_bigsmp_probe();
-#endif
 			/*
 			 * Parse MADT IO-APIC entries
 			 */
@@ -1196,8 +1194,6 @@ static void __init acpi_process_madt(voi
 				acpi_ioapic = 1;
 
 				smp_found_config = 1;
-				if (apic->setup_apic_routing)
-					apic->setup_apic_routing();
 			}
 		}
 		if (error == -EINVAL) {
@@ -1348,14 +1344,6 @@ static struct dmi_system_id __initdata a
 	 },
 	{
 	 .callback = force_acpi_ht,
-	 .ident = "ASUS P2B-DS",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-		     DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
 	 .ident = "ASUS CUR-DLS",
 	 .matches = {
 		     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
@@ -1528,16 +1516,10 @@ static struct dmi_system_id __initdata a
  *	if acpi_blacklisted() acpi_disabled = 1;
  *	acpi_irq_model=...
  *	...
- *
- * return value: (currently ignored)
- *	0: success
- *	!0: failure
  */
 
-int __init acpi_boot_table_init(void)
+void __init acpi_boot_table_init(void)
 {
-	int error;
-
 	dmi_check_system(acpi_dmi_table);
 
 	/*
@@ -1545,15 +1527,14 @@ int __init acpi_boot_table_init(void)
 	 * One exception: acpi=ht continues far enough to enumerate LAPICs
 	 */
 	if (acpi_disabled && !acpi_ht)
-		return 1;
+		return; 
 
 	/*
 	 * Initialize the ACPI boot-time table parser.
 	 */
-	error = acpi_table_init();
-	if (error) {
+	if (acpi_table_init()) {
 		disable_acpi();
-		return error;
+		return;
 	}
 
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
@@ -1561,18 +1542,15 @@ int __init acpi_boot_table_init(void)
 	/*
 	 * blacklist may disable ACPI entirely
 	 */
-	error = acpi_blacklisted();
-	if (error) {
+	if (acpi_blacklisted()) {
 		if (acpi_force) {
 			printk(KERN_WARNING PREFIX "acpi=force override\n");
 		} else {
 			printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
 			disable_acpi();
-			return error;
+			return;
 		}
 	}
-
-	return 0;
 }
 
 int __init early_acpi_boot_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/cstate.c linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/cstate.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/cstate.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/cstate.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(
 	 * P4, Core and beyond CPUs
 	 */
 	if (c->x86_vendor == X86_VENDOR_INTEL &&
-	    (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14)))
+	    (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f)))
 			flags->bm_control = 0;
 }
 EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/Makefile linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@ obj-$(CONFIG_ACPI)		+= boot.o
 obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup_rm.o wakeup_$(BITS).o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y				+= cstate.o processor.o
+obj-y				+= cstate.o
 endif
 
 $(obj)/wakeup_rm.o:    $(obj)/realmode/wakeup.bin
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/processor.c linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/processor.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/processor.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/processor.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2005 Intel Corporation
- * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- * 	- Added _PDC for platforms with Intel CPUs
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-
-#include <acpi/processor.h>
-#include <asm/acpi.h>
-
-static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
-{
-	struct acpi_object_list *obj_list;
-	union acpi_object *obj;
-	u32 *buf;
-
-	/* allocate and initialize pdc. It will be used later. */
-	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
-	if (!obj_list) {
-		printk(KERN_ERR "Memory allocation error\n");
-		return;
-	}
-
-	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-	if (!obj) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj_list);
-		return;
-	}
-
-	buf = kmalloc(12, GFP_KERNEL);
-	if (!buf) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj);
-		kfree(obj_list);
-		return;
-	}
-
-	buf[0] = ACPI_PDC_REVISION_ID;
-	buf[1] = 1;
-	buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
-
-	/*
-	 * The default of PDC_SMP_T_SWCOORD bit is set for intel x86 cpu so
-	 * that OSPM is capable of native ACPI throttling software
-	 * coordination using BIOS supplied _TSD info.
-	 */
-	buf[2] |= ACPI_PDC_SMP_T_SWCOORD;
-	if (cpu_has(c, X86_FEATURE_EST))
-		buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP;
-
-	if (cpu_has(c, X86_FEATURE_ACPI))
-		buf[2] |= ACPI_PDC_T_FFH;
-
-	/*
-	 * If mwait/monitor is unsupported, C2/C3_FFH will be disabled
-	 */
-	if (!cpu_has(c, X86_FEATURE_MWAIT))
-		buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
-
-	obj->type = ACPI_TYPE_BUFFER;
-	obj->buffer.length = 12;
-	obj->buffer.pointer = (u8 *) buf;
-	obj_list->count = 1;
-	obj_list->pointer = obj;
-	pr->pdc = obj_list;
-
-	return;
-}
-
-
-/* Initialize _PDC data based on the CPU vendor */
-void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
-{
-	struct cpuinfo_x86 *c = &cpu_data(pr->id);
-
-	pr->pdc = NULL;
-	if (c->x86_vendor == X86_VENDOR_INTEL ||
-	    c->x86_vendor == X86_VENDOR_CENTAUR)
-		init_intel_pdc(pr, c);
-
-	return;
-}
-
-EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
-
-void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr)
-{
-	if (pr->pdc) {
-		kfree(pr->pdc->pointer->buffer.pointer);
-		kfree(pr->pdc->pointer);
-		kfree(pr->pdc);
-		pr->pdc = NULL;
-	}
-}
-
-EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/sleep.c linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/sleep.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/acpi/sleep.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/acpi/sleep.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,12 +78,9 @@ int acpi_save_state_mem(void)
 #ifndef CONFIG_64BIT
 	store_gdt((struct desc_ptr *)&header->pmode_gdt);
 
-	header->pmode_efer_low = nx_enabled;
-	if (header->pmode_efer_low & 1) {
-		/* This is strange, why not save efer, always? */
-		rdmsr(MSR_EFER, header->pmode_efer_low,
-			header->pmode_efer_high);
-	}
+	if (rdmsr_safe(MSR_EFER, &header->pmode_efer_low,
+		       &header->pmode_efer_high))
+		header->pmode_efer_low = header->pmode_efer_high = 0;
 #endif /* !CONFIG_64BIT */
 
 	header->pmode_cr0 = read_cr0();
@@ -119,29 +116,32 @@ void acpi_restore_state_mem(void)
 
 
 /**
- * acpi_reserve_bootmem - do _very_ early ACPI initialisation
+ * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation
  *
  * We allocate a page from the first 1MB of memory for the wakeup
  * routine for when we come back from a sleep state. The
  * runtime allocator allows specification of <16MB pages, but not
  * <1MB pages.
  */
-void __init acpi_reserve_bootmem(void)
+void __init acpi_reserve_wakeup_memory(void)
 {
+	unsigned long mem;
+
 	if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) {
 		printk(KERN_ERR
 		       "ACPI: Wakeup code way too big, S3 disabled.\n");
 		return;
 	}
 
-	acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE);
+	mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE);
 
-	if (!acpi_realmode) {
+	if (mem == -1L) {
 		printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
 		return;
 	}
-
-	acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
+	acpi_realmode = (unsigned long) phys_to_virt(mem);
+	acpi_wakeup_address = mem;
+	reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP");
 }
 
 
@@ -162,6 +162,8 @@ static int __init acpi_sleep_setup(char
 #endif
 		if (strncmp(str, "old_ordering", 12) == 0)
 			acpi_old_suspend_ordering();
+		if (strncmp(str, "sci_force_enable", 16) == 0)
+			acpi_set_sci_en_on_resume();
 		str = strchr(str, ',');
 		if (str != NULL)
 			str += strspn(str, ", \t");
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/amd_iommu.c linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/amd_iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
@@ -19,7 +19,7 @@
 
 #include <linux/pci.h>
 #include <linux/gfp.h>
-#include <linux/bitops.h>
+#include <linux/bitmap.h>
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
@@ -28,6 +28,7 @@
 #include <asm/proto.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
@@ -56,20 +57,152 @@ struct iommu_cmd {
 	u32 data[4];
 };
 
-static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
-			     struct unity_map_entry *e);
-static struct dma_ops_domain *find_protection_domain(u16 devid);
-static u64 *alloc_pte(struct protection_domain *domain,
-		      unsigned long address, int end_lvl,
-		      u64 **pte_page, gfp_t gfp);
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
-				      unsigned long start_page,
-				      unsigned int pages);
 static void reset_iommu_command_buffer(struct amd_iommu *iommu);
-static u64 *fetch_pte(struct protection_domain *domain,
-		      unsigned long address, int map_size);
 static void update_domain(struct protection_domain *domain);
 
+/****************************************************************************
+ *
+ * Helper functions
+ *
+ ****************************************************************************/
+
+static inline u16 get_device_id(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return calc_devid(pdev->bus->number, pdev->devfn);
+}
+
+static struct iommu_dev_data *get_dev_data(struct device *dev)
+{
+	return dev->archdata.iommu;
+}
+
+/*
+ * In this function the list of preallocated protection domains is traversed to
+ * find the domain for a specific device
+ */
+static struct dma_ops_domain *find_protection_domain(u16 devid)
+{
+	struct dma_ops_domain *entry, *ret = NULL;
+	unsigned long flags;
+	u16 alias = amd_iommu_alias_table[devid];
+
+	if (list_empty(&iommu_pd_list))
+		return NULL;
+
+	spin_lock_irqsave(&iommu_pd_list_lock, flags);
+
+	list_for_each_entry(entry, &iommu_pd_list, list) {
+		if (entry->target_dev == devid ||
+		    entry->target_dev == alias) {
+			ret = entry;
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
+	return ret;
+}
+
+/*
+ * This function checks if the driver got a valid device from the caller to
+ * avoid dereferencing invalid pointers.
+ */
+static bool check_device(struct device *dev)
+{
+	u16 devid;
+
+	if (!dev || !dev->dma_mask)
+		return false;
+
+	/* No device or no PCI device */
+	if (!dev || dev->bus != &pci_bus_type)
+		return false;
+
+	devid = get_device_id(dev);
+
+	/* Out of our scope? */
+	if (devid > amd_iommu_last_bdf)
+		return false;
+
+	if (amd_iommu_rlookup_table[devid] == NULL)
+		return false;
+
+	return true;
+}
+
+static int iommu_init_device(struct device *dev)
+{
+	struct iommu_dev_data *dev_data;
+	struct pci_dev *pdev;
+	u16 devid, alias;
+
+	if (dev->archdata.iommu)
+		return 0;
+
+	dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+	if (!dev_data)
+		return -ENOMEM;
+
+	dev_data->dev = dev;
+
+	devid = get_device_id(dev);
+	alias = amd_iommu_alias_table[devid];
+	pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
+	if (pdev)
+		dev_data->alias = &pdev->dev;
+
+	atomic_set(&dev_data->bind, 0);
+
+	dev->archdata.iommu = dev_data;
+
+
+	return 0;
+}
+
+static void iommu_uninit_device(struct device *dev)
+{
+	kfree(dev->archdata.iommu);
+}
+
+void __init amd_iommu_uninit_devices(void)
+{
+	struct pci_dev *pdev = NULL;
+
+	for_each_pci_dev(pdev) {
+
+		if (!check_device(&pdev->dev))
+			continue;
+
+		iommu_uninit_device(&pdev->dev);
+	}
+}
+
+int __init amd_iommu_init_devices(void)
+{
+	struct pci_dev *pdev = NULL;
+	int ret = 0;
+
+	for_each_pci_dev(pdev) {
+
+		if (!check_device(&pdev->dev))
+			continue;
+
+		ret = iommu_init_device(&pdev->dev);
+		if (ret)
+			goto out_free;
+	}
+
+	return 0;
+
+out_free:
+
+	amd_iommu_uninit_devices();
+
+	return ret;
+}
 #ifdef CONFIG_AMD_IOMMU_STATS
 
 /*
@@ -90,7 +223,6 @@ DECLARE_STATS_COUNTER(alloced_io_mem);
 DECLARE_STATS_COUNTER(total_map_requests);
 
 static struct dentry *stats_dir;
-static struct dentry *de_isolate;
 static struct dentry *de_fflush;
 
 static void amd_iommu_stats_add(struct __iommu_counter *cnt)
@@ -108,9 +240,6 @@ static void amd_iommu_stats_init(void)
 	if (stats_dir == NULL)
 		return;
 
-	de_isolate = debugfs_create_bool("isolation", 0444, stats_dir,
-					 (u32 *)&amd_iommu_isolate);
-
 	de_fflush  = debugfs_create_bool("fullflush", 0444, stats_dir,
 					 (u32 *)&amd_iommu_unmap_flush);
 
@@ -130,12 +259,6 @@ static void amd_iommu_stats_init(void)
 
 #endif
 
-/* returns !0 if the IOMMU is caching non-present entries in its TLB */
-static int iommu_has_npcache(struct amd_iommu *iommu)
-{
-	return iommu->cap & (1UL << IOMMU_CAP_NPCACHE);
-}
-
 /****************************************************************************
  *
  * Interrupt handling functions
@@ -199,6 +322,7 @@ static void iommu_print_event(struct amd
 		break;
 	case EVENT_TYPE_ILL_CMD:
 		printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+		iommu->reset_in_progress = true;
 		reset_iommu_command_buffer(iommu);
 		dump_command(address);
 		break;
@@ -321,11 +445,8 @@ static void __iommu_wait_for_completion(
 	status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
 	writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
 
-	if (unlikely(i == EXIT_LOOP_COUNT)) {
-		spin_unlock(&iommu->lock);
-		reset_iommu_command_buffer(iommu);
-		spin_lock(&iommu->lock);
-	}
+	if (unlikely(i == EXIT_LOOP_COUNT))
+		iommu->reset_in_progress = true;
 }
 
 /*
@@ -372,26 +493,46 @@ static int iommu_completion_wait(struct
 out:
 	spin_unlock_irqrestore(&iommu->lock, flags);
 
+	if (iommu->reset_in_progress)
+		reset_iommu_command_buffer(iommu);
+
 	return 0;
 }
 
+static void iommu_flush_complete(struct protection_domain *domain)
+{
+	int i;
+
+	for (i = 0; i < amd_iommus_present; ++i) {
+		if (!domain->dev_iommu[i])
+			continue;
+
+		/*
+		 * Devices of this domain are behind this IOMMU
+		 * We need to wait for completion of all commands.
+		 */
+		iommu_completion_wait(amd_iommus[i]);
+	}
+}
+
 /*
  * Command send function for invalidating a device table entry
  */
-static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
+static int iommu_flush_device(struct device *dev)
 {
+	struct amd_iommu *iommu;
 	struct iommu_cmd cmd;
-	int ret;
+	u16 devid;
 
-	BUG_ON(iommu == NULL);
+	devid = get_device_id(dev);
+	iommu = amd_iommu_rlookup_table[devid];
 
+	/* Build command */
 	memset(&cmd, 0, sizeof(cmd));
 	CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
 	cmd.data[0] = devid;
 
-	ret = iommu_queue_command(iommu, &cmd);
-
-	return ret;
+	return iommu_queue_command(iommu, &cmd);
 }
 
 static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
@@ -430,11 +571,11 @@ static int iommu_queue_inv_iommu_pages(s
  * It invalidates a single PTE if the range to flush is within a single
  * page. Otherwise it flushes the whole TLB of the IOMMU.
  */
-static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
-		u64 address, size_t size)
+static void __iommu_flush_pages(struct protection_domain *domain,
+				u64 address, size_t size, int pde)
 {
-	int s = 0;
-	unsigned pages = iommu_num_pages(address, size, PAGE_SIZE);
+	int s = 0, i;
+	unsigned long pages = iommu_num_pages(address, size, PAGE_SIZE);
 
 	address &= PAGE_MASK;
 
@@ -447,142 +588,212 @@ static int iommu_flush_pages(struct amd_
 		s = 1;
 	}
 
-	iommu_queue_inv_iommu_pages(iommu, address, domid, 0, s);
 
-	return 0;
+	for (i = 0; i < amd_iommus_present; ++i) {
+		if (!domain->dev_iommu[i])
+			continue;
+
+		/*
+		 * Devices of this domain are behind this IOMMU
+		 * We need a TLB flush
+		 */
+		iommu_queue_inv_iommu_pages(amd_iommus[i], address,
+					    domain->id, pde, s);
+	}
+
+	return;
 }
 
-/* Flush the whole IO/TLB for a given protection domain */
-static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_pages(struct protection_domain *domain,
+			     u64 address, size_t size)
 {
-	u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
-	INC_STATS_COUNTER(domain_flush_single);
+	__iommu_flush_pages(domain, address, size, 0);
+}
 
-	iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);
+/* Flush the whole IO/TLB for a given protection domain */
+static void iommu_flush_tlb(struct protection_domain *domain)
+{
+	__iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
 }
 
 /* Flush the whole IO/TLB for a given protection domain - including PDE */
-static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_tlb_pde(struct protection_domain *domain)
 {
-       u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
-       INC_STATS_COUNTER(domain_flush_single);
-
-       iommu_queue_inv_iommu_pages(iommu, address, domid, 1, 1);
+	__iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
 }
 
+
 /*
- * This function flushes one domain on one IOMMU
+ * This function flushes the DTEs for all devices in domain
  */
-static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_domain_devices(struct protection_domain *domain)
 {
-	struct iommu_cmd cmd;
+	struct iommu_dev_data *dev_data;
 	unsigned long flags;
 
-	__iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
-				      domid, 1, 1);
+	spin_lock_irqsave(&domain->lock, flags);
 
-	spin_lock_irqsave(&iommu->lock, flags);
-	__iommu_queue_command(iommu, &cmd);
-	__iommu_completion_wait(iommu);
-	__iommu_wait_for_completion(iommu);
-	spin_unlock_irqrestore(&iommu->lock, flags);
+	list_for_each_entry(dev_data, &domain->dev_list, list)
+		iommu_flush_device(dev_data->dev);
+
+	spin_unlock_irqrestore(&domain->lock, flags);
 }
 
-static void flush_all_domains_on_iommu(struct amd_iommu *iommu)
+static void iommu_flush_all_domain_devices(void)
 {
-	int i;
+	struct protection_domain *domain;
+	unsigned long flags;
 
-	for (i = 1; i < MAX_DOMAIN_ID; ++i) {
-		if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
-			continue;
-		flush_domain_on_iommu(iommu, i);
+	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+
+	list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+		iommu_flush_domain_devices(domain);
+		iommu_flush_complete(domain);
 	}
 
+	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+void amd_iommu_flush_all_devices(void)
+{
+	iommu_flush_all_domain_devices();
 }
 
 /*
- * This function is used to flush the IO/TLB for a given protection domain
- * on every IOMMU in the system
+ * This function uses heavy locking and may disable irqs for some time. But
+ * this is no issue because it is only called during resume.
  */
-static void iommu_flush_domain(u16 domid)
+void amd_iommu_flush_all_domains(void)
 {
-	struct amd_iommu *iommu;
+	struct protection_domain *domain;
+	unsigned long flags;
 
-	INC_STATS_COUNTER(domain_flush_all);
+	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
 
-	for_each_iommu(iommu)
-		flush_domain_on_iommu(iommu, domid);
+	list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+		spin_lock(&domain->lock);
+		iommu_flush_tlb_pde(domain);
+		iommu_flush_complete(domain);
+		spin_unlock(&domain->lock);
+	}
+
+	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
 }
 
-void amd_iommu_flush_all_domains(void)
+static void reset_iommu_command_buffer(struct amd_iommu *iommu)
 {
-	struct amd_iommu *iommu;
+	pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
 
-	for_each_iommu(iommu)
-		flush_all_domains_on_iommu(iommu);
+	if (iommu->reset_in_progress)
+		panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+
+	amd_iommu_reset_cmd_buffer(iommu);
+	amd_iommu_flush_all_devices();
+	amd_iommu_flush_all_domains();
+
+	iommu->reset_in_progress = false;
 }
 
-static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
+/****************************************************************************
+ *
+ * The functions below are used the create the page table mappings for
+ * unity mapped regions.
+ *
+ ****************************************************************************/
+
+/*
+ * This function is used to add another level to an IO page table. Adding
+ * another level increases the size of the address space by 9 bits to a size up
+ * to 64 bits.
+ */
+static bool increase_address_space(struct protection_domain *domain,
+				   gfp_t gfp)
 {
-	int i;
+	u64 *pte;
 
-	for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-		if (iommu != amd_iommu_rlookup_table[i])
-			continue;
+	if (domain->mode == PAGE_MODE_6_LEVEL)
+		/* address space already 64 bit large */
+		return false;
 
-		iommu_queue_inv_dev_entry(iommu, i);
-		iommu_completion_wait(iommu);
-	}
+	pte = (void *)get_zeroed_page(gfp);
+	if (!pte)
+		return false;
+
+	*pte             = PM_LEVEL_PDE(domain->mode,
+					virt_to_phys(domain->pt_root));
+	domain->pt_root  = pte;
+	domain->mode    += 1;
+	domain->updated  = true;
+
+	return true;
 }
 
-static void flush_devices_by_domain(struct protection_domain *domain)
+static u64 *alloc_pte(struct protection_domain *domain,
+		      unsigned long address,
+		      int end_lvl,
+		      u64 **pte_page,
+		      gfp_t gfp)
 {
-	struct amd_iommu *iommu;
-	int i;
+	u64 *pte, *page;
+	int level;
 
-	for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-		if ((domain == NULL && amd_iommu_pd_table[i] == NULL) ||
-		    (amd_iommu_pd_table[i] != domain))
-			continue;
+	while (address > PM_LEVEL_SIZE(domain->mode))
+		increase_address_space(domain, gfp);
 
-		iommu = amd_iommu_rlookup_table[i];
-		if (!iommu)
-			continue;
+	level =  domain->mode - 1;
+	pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
 
-		iommu_queue_inv_dev_entry(iommu, i);
-		iommu_completion_wait(iommu);
+	while (level > end_lvl) {
+		if (!IOMMU_PTE_PRESENT(*pte)) {
+			page = (u64 *)get_zeroed_page(gfp);
+			if (!page)
+				return NULL;
+			*pte = PM_LEVEL_PDE(level, virt_to_phys(page));
+		}
+
+		level -= 1;
+
+		pte = IOMMU_PTE_PAGE(*pte);
+
+		if (pte_page && level == end_lvl)
+			*pte_page = pte;
+
+		pte = &pte[PM_LEVEL_INDEX(level, address)];
 	}
+
+	return pte;
 }
 
-static void reset_iommu_command_buffer(struct amd_iommu *iommu)
+/*
+ * This function checks if there is a PTE for a given dma address. If
+ * there is one, it returns the pointer to it.
+ */
+static u64 *fetch_pte(struct protection_domain *domain,
+		      unsigned long address, int map_size)
 {
-	pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
+	int level;
+	u64 *pte;
 
-	if (iommu->reset_in_progress)
-		panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+	level =  domain->mode - 1;
+	pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
 
-	iommu->reset_in_progress = true;
+	while (level > map_size) {
+		if (!IOMMU_PTE_PRESENT(*pte))
+			return NULL;
 
-	amd_iommu_reset_cmd_buffer(iommu);
-	flush_all_devices_for_iommu(iommu);
-	flush_all_domains_on_iommu(iommu);
+		level -= 1;
 
-	iommu->reset_in_progress = false;
-}
+		pte = IOMMU_PTE_PAGE(*pte);
+		pte = &pte[PM_LEVEL_INDEX(level, address)];
 
-void amd_iommu_flush_all_devices(void)
-{
-	flush_devices_by_domain(NULL);
-}
+		if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
+			pte = NULL;
+			break;
+		}
+	}
 
-/****************************************************************************
- *
- * The functions below are used the create the page table mappings for
- * unity mapped regions.
- *
- ****************************************************************************/
+	return pte;
+}
 
 /*
  * Generic mapping functions. It maps a physical address into a DMA
@@ -654,28 +865,6 @@ static int iommu_for_unity_map(struct am
 }
 
 /*
- * Init the unity mappings for a specific IOMMU in the system
- *
- * Basically iterates over all unity mapping entries and applies them to
- * the default domain DMA of that IOMMU if necessary.
- */
-static int iommu_init_unity_mappings(struct amd_iommu *iommu)
-{
-	struct unity_map_entry *entry;
-	int ret;
-
-	list_for_each_entry(entry, &amd_iommu_unity_map, list) {
-		if (!iommu_for_unity_map(iommu, entry))
-			continue;
-		ret = dma_ops_unity_map(iommu->default_dom, entry);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-/*
  * This function actually applies the mapping to the page table of the
  * dma_ops domain.
  */
@@ -704,6 +893,28 @@ static int dma_ops_unity_map(struct dma_
 }
 
 /*
+ * Init the unity mappings for a specific IOMMU in the system
+ *
+ * Basically iterates over all unity mapping entries and applies them to
+ * the default domain DMA of that IOMMU if necessary.
+ */
+static int iommu_init_unity_mappings(struct amd_iommu *iommu)
+{
+	struct unity_map_entry *entry;
+	int ret;
+
+	list_for_each_entry(entry, &amd_iommu_unity_map, list) {
+		if (!iommu_for_unity_map(iommu, entry))
+			continue;
+		ret = dma_ops_unity_map(iommu->default_dom, entry);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
  * Inits the unity mappings required for a specific device
  */
 static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
@@ -740,34 +951,23 @@ static int init_unity_mappings_for_devic
  */
 
 /*
- * This function checks if there is a PTE for a given dma address. If
- * there is one, it returns the pointer to it.
+ * Used to reserve address ranges in the aperture (e.g. for exclusion
+ * ranges.
  */
-static u64 *fetch_pte(struct protection_domain *domain,
-		      unsigned long address, int map_size)
+static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
+				      unsigned long start_page,
+				      unsigned int pages)
 {
-	int level;
-	u64 *pte;
-
-	level =  domain->mode - 1;
-	pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
-	while (level > map_size) {
-		if (!IOMMU_PTE_PRESENT(*pte))
-			return NULL;
-
-		level -= 1;
+	unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
 
-		pte = IOMMU_PTE_PAGE(*pte);
-		pte = &pte[PM_LEVEL_INDEX(level, address)];
+	if (start_page + pages > last_page)
+		pages = last_page - start_page;
 
-		if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
-			pte = NULL;
-			break;
-		}
+	for (i = start_page; i < start_page + pages; ++i) {
+		int index = i / APERTURE_RANGE_PAGES;
+		int page  = i % APERTURE_RANGE_PAGES;
+		__set_bit(page, dom->aperture[index]->bitmap);
 	}
-
-	return pte;
 }
 
 /*
@@ -775,12 +975,12 @@ static u64 *fetch_pte(struct protection_
  * aperture in case of dma_ops domain allocation or address allocation
  * failure.
  */
-static int alloc_new_range(struct amd_iommu *iommu,
-			   struct dma_ops_domain *dma_dom,
+static int alloc_new_range(struct dma_ops_domain *dma_dom,
 			   bool populate, gfp_t gfp)
 {
 	int index = dma_dom->aperture_size >> APERTURE_RANGE_SHIFT;
-	int i;
+	struct amd_iommu *iommu;
+	unsigned long i;
 
 #ifdef CONFIG_IOMMU_STRESS
 	populate = false;
@@ -819,14 +1019,17 @@ static int alloc_new_range(struct amd_io
 	dma_dom->aperture_size += APERTURE_RANGE_SIZE;
 
 	/* Intialize the exclusion range if necessary */
-	if (iommu->exclusion_start &&
-	    iommu->exclusion_start >= dma_dom->aperture[index]->offset &&
-	    iommu->exclusion_start < dma_dom->aperture_size) {
-		unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
-		int pages = iommu_num_pages(iommu->exclusion_start,
-					    iommu->exclusion_length,
-					    PAGE_SIZE);
-		dma_ops_reserve_addresses(dma_dom, startpage, pages);
+	for_each_iommu(iommu) {
+		if (iommu->exclusion_start &&
+		    iommu->exclusion_start >= dma_dom->aperture[index]->offset
+		    && iommu->exclusion_start < dma_dom->aperture_size) {
+			unsigned long startpage;
+			int pages = iommu_num_pages(iommu->exclusion_start,
+						    iommu->exclusion_length,
+						    PAGE_SIZE);
+			startpage = iommu->exclusion_start >> PAGE_SHIFT;
+			dma_ops_reserve_addresses(dma_dom, startpage, pages);
+		}
 	}
 
 	/*
@@ -928,7 +1131,7 @@ static unsigned long dma_ops_alloc_addre
 	}
 
 	if (unlikely(address == -1))
-		address = bad_dma_address;
+		address = DMA_ERROR_CODE;
 
 	WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size);
 
@@ -959,7 +1162,7 @@ static void dma_ops_free_addresses(struc
 
 	address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT;
 
-	iommu_area_free(range->bitmap, address, pages);
+	bitmap_clear(range->bitmap, address, pages);
 
 }
 
@@ -973,6 +1176,31 @@ static void dma_ops_free_addresses(struc
  *
  ****************************************************************************/
 
+/*
+ * This function adds a protection domain to the global protection domain list
+ */
+static void add_domain_to_list(struct protection_domain *domain)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+	list_add(&domain->list, &amd_iommu_pd_list);
+	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+/*
+ * This function removes a protection domain to the global
+ * protection domain list
+ */
+static void del_domain_from_list(struct protection_domain *domain)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+	list_del(&domain->list);
+	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
 static u16 domain_id_alloc(void)
 {
 	unsigned long flags;
@@ -1000,26 +1228,6 @@ static void domain_id_free(int id)
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
 
-/*
- * Used to reserve address ranges in the aperture (e.g. for exclusion
- * ranges.
- */
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
-				      unsigned long start_page,
-				      unsigned int pages)
-{
-	unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
-
-	if (start_page + pages > last_page)
-		pages = last_page - start_page;
-
-	for (i = start_page; i < start_page + pages; ++i) {
-		int index = i / APERTURE_RANGE_PAGES;
-		int page  = i % APERTURE_RANGE_PAGES;
-		__set_bit(page, dom->aperture[index]->bitmap);
-	}
-}
-
 static void free_pagetable(struct protection_domain *domain)
 {
 	int i, j;
@@ -1061,6 +1269,8 @@ static void dma_ops_domain_free(struct d
 	if (!dom)
 		return;
 
+	del_domain_from_list(&dom->domain);
+
 	free_pagetable(&dom->domain);
 
 	for (i = 0; i < APERTURE_MAX_RANGES; ++i) {
@@ -1078,7 +1288,7 @@ static void dma_ops_domain_free(struct d
  * It also intializes the page table and the address allocator data
  * structures required for the dma_ops interface
  */
-static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
+static struct dma_ops_domain *dma_ops_domain_alloc(void)
 {
 	struct dma_ops_domain *dma_dom;
 
@@ -1091,6 +1301,7 @@ static struct dma_ops_domain *dma_ops_do
 	dma_dom->domain.id = domain_id_alloc();
 	if (dma_dom->domain.id == 0)
 		goto free_dma_dom;
+	INIT_LIST_HEAD(&dma_dom->domain.dev_list);
 	dma_dom->domain.mode = PAGE_MODE_2_LEVEL;
 	dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
 	dma_dom->domain.flags = PD_DMA_OPS_MASK;
@@ -1101,7 +1312,9 @@ static struct dma_ops_domain *dma_ops_do
 	dma_dom->need_flush = false;
 	dma_dom->target_dev = 0xffff;
 
-	if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL))
+	add_domain_to_list(&dma_dom->domain);
+
+	if (alloc_new_range(dma_dom, true, GFP_KERNEL))
 		goto free_dma_dom;
 
 	/*
@@ -1129,22 +1342,6 @@ static bool dma_ops_domain(struct protec
 	return domain->flags & PD_DMA_OPS_MASK;
 }
 
-/*
- * Find out the protection domain structure for a given PCI device. This
- * will give us the pointer to the page table root for example.
- */
-static struct protection_domain *domain_for_device(u16 devid)
-{
-	struct protection_domain *dom;
-	unsigned long flags;
-
-	read_lock_irqsave(&amd_iommu_devtable_lock, flags);
-	dom = amd_iommu_pd_table[devid];
-	read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
-
-	return dom;
-}
-
 static void set_dte_entry(u16 devid, struct protection_domain *domain)
 {
 	u64 pte_root = virt_to_phys(domain->pt_root);
@@ -1156,42 +1353,123 @@ static void set_dte_entry(u16 devid, str
 	amd_iommu_dev_table[devid].data[2] = domain->id;
 	amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
 	amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
+}
 
-	amd_iommu_pd_table[devid] = domain;
+static void clear_dte_entry(u16 devid)
+{
+	/* remove entry from the device table seen by the hardware */
+	amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
+	amd_iommu_dev_table[devid].data[1] = 0;
+	amd_iommu_dev_table[devid].data[2] = 0;
+
+	amd_iommu_apply_erratum_63(devid);
+}
+
+static void do_attach(struct device *dev, struct protection_domain *domain)
+{
+	struct iommu_dev_data *dev_data;
+	struct amd_iommu *iommu;
+	u16 devid;
+
+	devid    = get_device_id(dev);
+	iommu    = amd_iommu_rlookup_table[devid];
+	dev_data = get_dev_data(dev);
+
+	/* Update data structures */
+	dev_data->domain = domain;
+	list_add(&dev_data->list, &domain->dev_list);
+	set_dte_entry(devid, domain);
+
+	/* Do reference counting */
+	domain->dev_iommu[iommu->index] += 1;
+	domain->dev_cnt                 += 1;
+
+	/* Flush the DTE entry */
+	iommu_flush_device(dev);
+}
+
+static void do_detach(struct device *dev)
+{
+	struct iommu_dev_data *dev_data;
+	struct amd_iommu *iommu;
+	u16 devid;
+
+	devid    = get_device_id(dev);
+	iommu    = amd_iommu_rlookup_table[devid];
+	dev_data = get_dev_data(dev);
+
+	/* decrease reference counters */
+	dev_data->domain->dev_iommu[iommu->index] -= 1;
+	dev_data->domain->dev_cnt                 -= 1;
+
+	/* Update data structures */
+	dev_data->domain = NULL;
+	list_del(&dev_data->list);
+	clear_dte_entry(devid);
+
+	/* Flush the DTE entry */
+	iommu_flush_device(dev);
 }
 
 /*
  * If a device is not yet associated with a domain, this function does
  * assigns it visible for the hardware
  */
-static void __attach_device(struct amd_iommu *iommu,
-			    struct protection_domain *domain,
-			    u16 devid)
+static int __attach_device(struct device *dev,
+			   struct protection_domain *domain)
 {
+	struct iommu_dev_data *dev_data, *alias_data;
+
+	dev_data   = get_dev_data(dev);
+	alias_data = get_dev_data(dev_data->alias);
+
+	if (!alias_data)
+		return -EINVAL;
+
 	/* lock domain */
 	spin_lock(&domain->lock);
 
-	/* update DTE entry */
-	set_dte_entry(devid, domain);
+	/* Some sanity checks */
+	if (alias_data->domain != NULL &&
+	    alias_data->domain != domain)
+		return -EBUSY;
 
-	domain->dev_cnt += 1;
+	if (dev_data->domain != NULL &&
+	    dev_data->domain != domain)
+		return -EBUSY;
+
+	/* Do real assignment */
+	if (dev_data->alias != dev) {
+		alias_data = get_dev_data(dev_data->alias);
+		if (alias_data->domain == NULL)
+			do_attach(dev_data->alias, domain);
+
+		atomic_inc(&alias_data->bind);
+	}
+
+	if (dev_data->domain == NULL)
+		do_attach(dev, domain);
+
+	atomic_inc(&dev_data->bind);
 
 	/* ready */
 	spin_unlock(&domain->lock);
+
+	return 0;
 }
 
 /*
  * If a device is not yet associated with a domain, this function does
  * assigns it visible for the hardware
  */
-static void attach_device(struct amd_iommu *iommu,
-			  struct protection_domain *domain,
-			  u16 devid)
+static int attach_device(struct device *dev,
+			 struct protection_domain *domain)
 {
 	unsigned long flags;
+	int ret;
 
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-	__attach_device(iommu, domain, devid);
+	ret = __attach_device(dev, domain);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 
 	/*
@@ -1199,98 +1477,130 @@ static void attach_device(struct amd_iom
 	 * left the caches in the IOMMU dirty. So we have to flush
 	 * here to evict all dirty stuff.
 	 */
-	iommu_queue_inv_dev_entry(iommu, devid);
-	iommu_flush_tlb_pde(iommu, domain->id);
+	iommu_flush_tlb_pde(domain);
+
+	return ret;
 }
 
 /*
  * Removes a device from a protection domain (unlocked)
  */
-static void __detach_device(struct protection_domain *domain, u16 devid)
+static void __detach_device(struct device *dev)
 {
+	struct iommu_dev_data *dev_data = get_dev_data(dev);
+	struct iommu_dev_data *alias_data;
+	struct protection_domain *domain;
+	unsigned long flags;
 
-	/* lock domain */
-	spin_lock(&domain->lock);
+	BUG_ON(!dev_data->domain);
 
-	/* remove domain from the lookup table */
-	amd_iommu_pd_table[devid] = NULL;
+	domain = dev_data->domain;
 
-	/* remove entry from the device table seen by the hardware */
-	amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
-	amd_iommu_dev_table[devid].data[1] = 0;
-	amd_iommu_dev_table[devid].data[2] = 0;
+	spin_lock_irqsave(&domain->lock, flags);
 
-	amd_iommu_apply_erratum_63(devid);
+	if (dev_data->alias != dev) {
+		alias_data = get_dev_data(dev_data->alias);
+		if (atomic_dec_and_test(&alias_data->bind))
+			do_detach(dev_data->alias);
+	}
 
-	/* decrease reference counter */
-	domain->dev_cnt -= 1;
+	if (atomic_dec_and_test(&dev_data->bind))
+		do_detach(dev);
 
-	/* ready */
-	spin_unlock(&domain->lock);
+	spin_unlock_irqrestore(&domain->lock, flags);
 
 	/*
 	 * If we run in passthrough mode the device must be assigned to the
-	 * passthrough domain if it is detached from any other domain
+	 * passthrough domain if it is detached from any other domain.
+	 * Make sure we can deassign from the pt_domain itself.
 	 */
-	if (iommu_pass_through) {
-		struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
-		__attach_device(iommu, pt_domain, devid);
-	}
+	if (iommu_pass_through &&
+	    (dev_data->domain == NULL && domain != pt_domain))
+		__attach_device(dev, pt_domain);
 }
 
 /*
  * Removes a device from a protection domain (with devtable_lock held)
  */
-static void detach_device(struct protection_domain *domain, u16 devid)
+static void detach_device(struct device *dev)
 {
 	unsigned long flags;
 
 	/* lock device table */
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-	__detach_device(domain, devid);
+	__detach_device(dev);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
 
+/*
+ * Find out the protection domain structure for a given PCI device. This
+ * will give us the pointer to the page table root for example.
+ */
+static struct protection_domain *domain_for_device(struct device *dev)
+{
+	struct protection_domain *dom;
+	struct iommu_dev_data *dev_data, *alias_data;
+	unsigned long flags;
+	u16 devid, alias;
+
+	devid      = get_device_id(dev);
+	alias      = amd_iommu_alias_table[devid];
+	dev_data   = get_dev_data(dev);
+	alias_data = get_dev_data(dev_data->alias);
+	if (!alias_data)
+		return NULL;
+
+	read_lock_irqsave(&amd_iommu_devtable_lock, flags);
+	dom = dev_data->domain;
+	if (dom == NULL &&
+	    alias_data->domain != NULL) {
+		__attach_device(dev, alias_data->domain);
+		dom = alias_data->domain;
+	}
+
+	read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+	return dom;
+}
+
 static int device_change_notifier(struct notifier_block *nb,
 				  unsigned long action, void *data)
 {
 	struct device *dev = data;
-	struct pci_dev *pdev = to_pci_dev(dev);
-	u16 devid = calc_devid(pdev->bus->number, pdev->devfn);
+	u16 devid;
 	struct protection_domain *domain;
 	struct dma_ops_domain *dma_domain;
 	struct amd_iommu *iommu;
 	unsigned long flags;
 
-	if (devid > amd_iommu_last_bdf)
-		goto out;
-
-	devid = amd_iommu_alias_table[devid];
-
-	iommu = amd_iommu_rlookup_table[devid];
-	if (iommu == NULL)
-		goto out;
-
-	domain = domain_for_device(devid);
+	if (!check_device(dev))
+		return 0;
 
-	if (domain && !dma_ops_domain(domain))
-		WARN_ONCE(1, "AMD IOMMU WARNING: device %s already bound "
-			  "to a non-dma-ops domain\n", dev_name(dev));
+	devid  = get_device_id(dev);
+	iommu  = amd_iommu_rlookup_table[devid];
 
 	switch (action) {
 	case BUS_NOTIFY_UNBOUND_DRIVER:
+
+		domain = domain_for_device(dev);
+
 		if (!domain)
 			goto out;
 		if (iommu_pass_through)
 			break;
-		detach_device(domain, devid);
+		detach_device(dev);
 		break;
 	case BUS_NOTIFY_ADD_DEVICE:
+
+		iommu_init_device(dev);
+
+		domain = domain_for_device(dev);
+
 		/* allocate a protection domain if a device is added */
 		dma_domain = find_protection_domain(devid);
 		if (dma_domain)
 			goto out;
-		dma_domain = dma_ops_domain_alloc(iommu);
+		dma_domain = dma_ops_domain_alloc();
 		if (!dma_domain)
 			goto out;
 		dma_domain->target_dev = devid;
@@ -1300,11 +1610,15 @@ static int device_change_notifier(struct
 		spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
 
 		break;
+	case BUS_NOTIFY_DEL_DEVICE:
+
+		iommu_uninit_device(dev);
+
 	default:
 		goto out;
 	}
 
-	iommu_queue_inv_dev_entry(iommu, devid);
+	iommu_flush_device(dev);
 	iommu_completion_wait(iommu);
 
 out:
@@ -1315,6 +1629,11 @@ static struct notifier_block device_nb =
 	.notifier_call = device_change_notifier,
 };
 
+void amd_iommu_init_notifier(void)
+{
+	bus_register_notifier(&pci_bus_type, &device_nb);
+}
+
 /*****************************************************************************
  *
  * The next functions belong to the dma_ops mapping/unmapping code.
@@ -1322,106 +1641,46 @@ static struct notifier_block device_nb =
  *****************************************************************************/
 
 /*
- * This function checks if the driver got a valid device from the caller to
- * avoid dereferencing invalid pointers.
- */
-static bool check_device(struct device *dev)
-{
-	if (!dev || !dev->dma_mask)
-		return false;
-
-	return true;
-}
-
-/*
- * In this function the list of preallocated protection domains is traversed to
- * find the domain for a specific device
- */
-static struct dma_ops_domain *find_protection_domain(u16 devid)
-{
-	struct dma_ops_domain *entry, *ret = NULL;
-	unsigned long flags;
-
-	if (list_empty(&iommu_pd_list))
-		return NULL;
-
-	spin_lock_irqsave(&iommu_pd_list_lock, flags);
-
-	list_for_each_entry(entry, &iommu_pd_list, list) {
-		if (entry->target_dev == devid) {
-			ret = entry;
-			break;
-		}
-	}
-
-	spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
-
-	return ret;
-}
-
-/*
  * In the dma_ops path we only have the struct device. This function
  * finds the corresponding IOMMU, the protection domain and the
  * requestor id for a given device.
  * If the device is not yet associated with a domain this is also done
  * in this function.
  */
-static int get_device_resources(struct device *dev,
-				struct amd_iommu **iommu,
-				struct protection_domain **domain,
-				u16 *bdf)
+static struct protection_domain *get_domain(struct device *dev)
 {
+	struct protection_domain *domain;
 	struct dma_ops_domain *dma_dom;
-	struct pci_dev *pcidev;
-	u16 _bdf;
-
-	*iommu = NULL;
-	*domain = NULL;
-	*bdf = 0xffff;
-
-	if (dev->bus != &pci_bus_type)
-		return 0;
-
-	pcidev = to_pci_dev(dev);
-	_bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
+	u16 devid = get_device_id(dev);
 
-	/* device not translated by any IOMMU in the system? */
-	if (_bdf > amd_iommu_last_bdf)
-		return 0;
+	if (!check_device(dev))
+		return ERR_PTR(-EINVAL);
 
-	*bdf = amd_iommu_alias_table[_bdf];
+	domain = domain_for_device(dev);
+	if (domain != NULL && !dma_ops_domain(domain))
+		return ERR_PTR(-EBUSY);
 
-	*iommu = amd_iommu_rlookup_table[*bdf];
-	if (*iommu == NULL)
-		return 0;
-	*domain = domain_for_device(*bdf);
-	if (*domain == NULL) {
-		dma_dom = find_protection_domain(*bdf);
-		if (!dma_dom)
-			dma_dom = (*iommu)->default_dom;
-		*domain = &dma_dom->domain;
-		attach_device(*iommu, *domain, *bdf);
-		DUMP_printk("Using protection domain %d for device %s\n",
-			    (*domain)->id, dev_name(dev));
-	}
+	if (domain != NULL)
+		return domain;
 
-	if (domain_for_device(_bdf) == NULL)
-		attach_device(*iommu, *domain, _bdf);
+	/* Device not bount yet - bind it */
+	dma_dom = find_protection_domain(devid);
+	if (!dma_dom)
+		dma_dom = amd_iommu_rlookup_table[devid]->default_dom;
+	attach_device(dev, &dma_dom->domain);
+	DUMP_printk("Using protection domain %d for device %s\n",
+		    dma_dom->domain.id, dev_name(dev));
 
-	return 1;
+	return &dma_dom->domain;
 }
 
 static void update_device_table(struct protection_domain *domain)
 {
-	unsigned long flags;
-	int i;
+	struct iommu_dev_data *dev_data;
 
-	for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-		if (amd_iommu_pd_table[i] != domain)
-			continue;
-		write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-		set_dte_entry(i, domain);
-		write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+	list_for_each_entry(dev_data, &domain->dev_list, list) {
+		u16 devid = get_device_id(dev_data->dev);
+		set_dte_entry(devid, domain);
 	}
 }
 
@@ -1431,76 +1690,13 @@ static void update_domain(struct protect
 		return;
 
 	update_device_table(domain);
-	flush_devices_by_domain(domain);
-	iommu_flush_domain(domain->id);
+	iommu_flush_domain_devices(domain);
+	iommu_flush_tlb_pde(domain);
 
 	domain->updated = false;
 }
 
 /*
- * This function is used to add another level to an IO page table. Adding
- * another level increases the size of the address space by 9 bits to a size up
- * to 64 bits.
- */
-static bool increase_address_space(struct protection_domain *domain,
-				   gfp_t gfp)
-{
-	u64 *pte;
-
-	if (domain->mode == PAGE_MODE_6_LEVEL)
-		/* address space already 64 bit large */
-		return false;
-
-	pte = (void *)get_zeroed_page(gfp);
-	if (!pte)
-		return false;
-
-	*pte             = PM_LEVEL_PDE(domain->mode,
-					virt_to_phys(domain->pt_root));
-	domain->pt_root  = pte;
-	domain->mode    += 1;
-	domain->updated  = true;
-
-	return true;
-}
-
-static u64 *alloc_pte(struct protection_domain *domain,
-		      unsigned long address,
-		      int end_lvl,
-		      u64 **pte_page,
-		      gfp_t gfp)
-{
-	u64 *pte, *page;
-	int level;
-
-	while (address > PM_LEVEL_SIZE(domain->mode))
-		increase_address_space(domain, gfp);
-
-	level =  domain->mode - 1;
-	pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
-	while (level > end_lvl) {
-		if (!IOMMU_PTE_PRESENT(*pte)) {
-			page = (u64 *)get_zeroed_page(gfp);
-			if (!page)
-				return NULL;
-			*pte = PM_LEVEL_PDE(level, virt_to_phys(page));
-		}
-
-		level -= 1;
-
-		pte = IOMMU_PTE_PAGE(*pte);
-
-		if (pte_page && level == end_lvl)
-			*pte_page = pte;
-
-		pte = &pte[PM_LEVEL_INDEX(level, address)];
-	}
-
-	return pte;
-}
-
-/*
  * This function fetches the PTE for a given address in the aperture
  */
 static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
@@ -1530,8 +1726,7 @@ static u64* dma_ops_get_pte(struct dma_o
  * This is the generic map function. It maps one 4kb page at paddr to
  * the given address in the DMA address space for the domain.
  */
-static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
-				     struct dma_ops_domain *dom,
+static dma_addr_t dma_ops_domain_map(struct dma_ops_domain *dom,
 				     unsigned long address,
 				     phys_addr_t paddr,
 				     int direction)
@@ -1544,7 +1739,7 @@ static dma_addr_t dma_ops_domain_map(str
 
 	pte  = dma_ops_get_pte(dom, address);
 	if (!pte)
-		return bad_dma_address;
+		return DMA_ERROR_CODE;
 
 	__pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC;
 
@@ -1565,8 +1760,7 @@ static dma_addr_t dma_ops_domain_map(str
 /*
  * The generic unmapping function for on page in the DMA address space.
  */
-static void dma_ops_domain_unmap(struct amd_iommu *iommu,
-				 struct dma_ops_domain *dom,
+static void dma_ops_domain_unmap(struct dma_ops_domain *dom,
 				 unsigned long address)
 {
 	struct aperture_range *aperture;
@@ -1597,7 +1791,6 @@ static void dma_ops_domain_unmap(struct
  * Must be called with the domain lock held.
  */
 static dma_addr_t __map_single(struct device *dev,
-			       struct amd_iommu *iommu,
 			       struct dma_ops_domain *dma_dom,
 			       phys_addr_t paddr,
 			       size_t size,
@@ -1625,7 +1818,7 @@ static dma_addr_t __map_single(struct de
 retry:
 	address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask,
 					  dma_mask);
-	if (unlikely(address == bad_dma_address)) {
+	if (unlikely(address == DMA_ERROR_CODE)) {
 		/*
 		 * setting next_address here will let the address
 		 * allocator only scan the new allocated range in the
@@ -1633,11 +1826,11 @@ retry:
 		 */
 		dma_dom->next_address = dma_dom->aperture_size;
 
-		if (alloc_new_range(iommu, dma_dom, false, GFP_ATOMIC))
+		if (alloc_new_range(dma_dom, false, GFP_ATOMIC))
 			goto out;
 
 		/*
-		 * aperture was sucessfully enlarged by 128 MB, try
+		 * aperture was successfully enlarged by 128 MB, try
 		 * allocation again
 		 */
 		goto retry;
@@ -1645,8 +1838,8 @@ retry:
 
 	start = address;
 	for (i = 0; i < pages; ++i) {
-		ret = dma_ops_domain_map(iommu, dma_dom, start, paddr, dir);
-		if (ret == bad_dma_address)
+		ret = dma_ops_domain_map(dma_dom, start, paddr, dir);
+		if (ret == DMA_ERROR_CODE)
 			goto out_unmap;
 
 		paddr += PAGE_SIZE;
@@ -1657,10 +1850,10 @@ retry:
 	ADD_STATS_COUNTER(alloced_io_mem, size);
 
 	if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) {
-		iommu_flush_tlb(iommu, dma_dom->domain.id);
+		iommu_flush_tlb(&dma_dom->domain);
 		dma_dom->need_flush = false;
-	} else if (unlikely(iommu_has_npcache(iommu)))
-		iommu_flush_pages(iommu, dma_dom->domain.id, address, size);
+	} else if (unlikely(amd_iommu_np_cache))
+		iommu_flush_pages(&dma_dom->domain, address, size);
 
 out:
 	return address;
@@ -1669,20 +1862,19 @@ out_unmap:
 
 	for (--i; i >= 0; --i) {
 		start -= PAGE_SIZE;
-		dma_ops_domain_unmap(iommu, dma_dom, start);
+		dma_ops_domain_unmap(dma_dom, start);
 	}
 
 	dma_ops_free_addresses(dma_dom, address, pages);
 
-	return bad_dma_address;
+	return DMA_ERROR_CODE;
 }
 
 /*
  * Does the reverse of the __map_single function. Must be called with
  * the domain lock held too
  */
-static void __unmap_single(struct amd_iommu *iommu,
-			   struct dma_ops_domain *dma_dom,
+static void __unmap_single(struct dma_ops_domain *dma_dom,
 			   dma_addr_t dma_addr,
 			   size_t size,
 			   int dir)
@@ -1690,7 +1882,7 @@ static void __unmap_single(struct amd_io
 	dma_addr_t i, start;
 	unsigned int pages;
 
-	if ((dma_addr == bad_dma_address) ||
+	if ((dma_addr == DMA_ERROR_CODE) ||
 	    (dma_addr + size > dma_dom->aperture_size))
 		return;
 
@@ -1699,7 +1891,7 @@ static void __unmap_single(struct amd_io
 	start = dma_addr;
 
 	for (i = 0; i < pages; ++i) {
-		dma_ops_domain_unmap(iommu, dma_dom, start);
+		dma_ops_domain_unmap(dma_dom, start);
 		start += PAGE_SIZE;
 	}
 
@@ -1708,7 +1900,7 @@ static void __unmap_single(struct amd_io
 	dma_ops_free_addresses(dma_dom, dma_addr, pages);
 
 	if (amd_iommu_unmap_flush || dma_dom->need_flush) {
-		iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size);
+		iommu_flush_pages(&dma_dom->domain, dma_addr, size);
 		dma_dom->need_flush = false;
 	}
 }
@@ -1722,36 +1914,29 @@ static dma_addr_t map_page(struct device
 			   struct dma_attrs *attrs)
 {
 	unsigned long flags;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
-	u16 devid;
 	dma_addr_t addr;
 	u64 dma_mask;
 	phys_addr_t paddr = page_to_phys(page) + offset;
 
 	INC_STATS_COUNTER(cnt_map_single);
 
-	if (!check_device(dev))
-		return bad_dma_address;
-
-	dma_mask = *dev->dma_mask;
-
-	get_device_resources(dev, &iommu, &domain, &devid);
-
-	if (iommu == NULL || domain == NULL)
-		/* device not handled by any AMD IOMMU */
+	domain = get_domain(dev);
+	if (PTR_ERR(domain) == -EINVAL)
 		return (dma_addr_t)paddr;
+	else if (IS_ERR(domain))
+		return DMA_ERROR_CODE;
 
-	if (!dma_ops_domain(domain))
-		return bad_dma_address;
+	dma_mask = *dev->dma_mask;
 
 	spin_lock_irqsave(&domain->lock, flags);
-	addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false,
+
+	addr = __map_single(dev, domain->priv, paddr, size, dir, false,
 			    dma_mask);
-	if (addr == bad_dma_address)
+	if (addr == DMA_ERROR_CODE)
 		goto out;
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 out:
 	spin_unlock_irqrestore(&domain->lock, flags);
@@ -1766,25 +1951,19 @@ static void unmap_page(struct device *de
 		       enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	unsigned long flags;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
-	u16 devid;
 
 	INC_STATS_COUNTER(cnt_unmap_single);
 
-	if (!check_device(dev) ||
-	    !get_device_resources(dev, &iommu, &domain, &devid))
-		/* device not handled by any AMD IOMMU */
-		return;
-
-	if (!dma_ops_domain(domain))
+	domain = get_domain(dev);
+	if (IS_ERR(domain))
 		return;
 
 	spin_lock_irqsave(&domain->lock, flags);
 
-	__unmap_single(iommu, domain->priv, dma_addr, size, dir);
+	__unmap_single(domain->priv, dma_addr, size, dir);
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -1816,9 +1995,7 @@ static int map_sg(struct device *dev, st
 		  struct dma_attrs *attrs)
 {
 	unsigned long flags;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
-	u16 devid;
 	int i;
 	struct scatterlist *s;
 	phys_addr_t paddr;
@@ -1827,25 +2004,20 @@ static int map_sg(struct device *dev, st
 
 	INC_STATS_COUNTER(cnt_map_sg);
 
-	if (!check_device(dev))
+	domain = get_domain(dev);
+	if (PTR_ERR(domain) == -EINVAL)
+		return map_sg_no_iommu(dev, sglist, nelems, dir);
+	else if (IS_ERR(domain))
 		return 0;
 
 	dma_mask = *dev->dma_mask;
 
-	get_device_resources(dev, &iommu, &domain, &devid);
-
-	if (!iommu || !domain)
-		return map_sg_no_iommu(dev, sglist, nelems, dir);
-
-	if (!dma_ops_domain(domain))
-		return 0;
-
 	spin_lock_irqsave(&domain->lock, flags);
 
 	for_each_sg(sglist, s, nelems, i) {
 		paddr = sg_phys(s);
 
-		s->dma_address = __map_single(dev, iommu, domain->priv,
+		s->dma_address = __map_single(dev, domain->priv,
 					      paddr, s->length, dir, false,
 					      dma_mask);
 
@@ -1856,7 +2028,7 @@ static int map_sg(struct device *dev, st
 			goto unmap;
 	}
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 out:
 	spin_unlock_irqrestore(&domain->lock, flags);
@@ -1865,7 +2037,7 @@ out:
 unmap:
 	for_each_sg(sglist, s, mapped_elems, i) {
 		if (s->dma_address)
-			__unmap_single(iommu, domain->priv, s->dma_address,
+			__unmap_single(domain->priv, s->dma_address,
 				       s->dma_length, dir);
 		s->dma_address = s->dma_length = 0;
 	}
@@ -1884,30 +2056,25 @@ static void unmap_sg(struct device *dev,
 		     struct dma_attrs *attrs)
 {
 	unsigned long flags;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
 	struct scatterlist *s;
-	u16 devid;
 	int i;
 
 	INC_STATS_COUNTER(cnt_unmap_sg);
 
-	if (!check_device(dev) ||
-	    !get_device_resources(dev, &iommu, &domain, &devid))
-		return;
-
-	if (!dma_ops_domain(domain))
+	domain = get_domain(dev);
+	if (IS_ERR(domain))
 		return;
 
 	spin_lock_irqsave(&domain->lock, flags);
 
 	for_each_sg(sglist, s, nelems, i) {
-		__unmap_single(iommu, domain->priv, s->dma_address,
+		__unmap_single(domain->priv, s->dma_address,
 			       s->dma_length, dir);
 		s->dma_address = s->dma_length = 0;
 	}
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -1920,49 +2087,44 @@ static void *alloc_coherent(struct devic
 {
 	unsigned long flags;
 	void *virt_addr;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
-	u16 devid;
 	phys_addr_t paddr;
 	u64 dma_mask = dev->coherent_dma_mask;
 
 	INC_STATS_COUNTER(cnt_alloc_coherent);
 
-	if (!check_device(dev))
+	domain = get_domain(dev);
+	if (PTR_ERR(domain) == -EINVAL) {
+		virt_addr = (void *)__get_free_pages(flag, get_order(size));
+		*dma_addr = __pa(virt_addr);
+		return virt_addr;
+	} else if (IS_ERR(domain))
 		return NULL;
 
-	if (!get_device_resources(dev, &iommu, &domain, &devid))
-		flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+	dma_mask  = dev->coherent_dma_mask;
+	flag     &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+	flag     |= __GFP_ZERO;
 
-	flag |= __GFP_ZERO;
 	virt_addr = (void *)__get_free_pages(flag, get_order(size));
 	if (!virt_addr)
 		return NULL;
 
 	paddr = virt_to_phys(virt_addr);
 
-	if (!iommu || !domain) {
-		*dma_addr = (dma_addr_t)paddr;
-		return virt_addr;
-	}
-
-	if (!dma_ops_domain(domain))
-		goto out_free;
-
 	if (!dma_mask)
 		dma_mask = *dev->dma_mask;
 
 	spin_lock_irqsave(&domain->lock, flags);
 
-	*dma_addr = __map_single(dev, iommu, domain->priv, paddr,
+	*dma_addr = __map_single(dev, domain->priv, paddr,
 				 size, DMA_BIDIRECTIONAL, true, dma_mask);
 
-	if (*dma_addr == bad_dma_address) {
+	if (*dma_addr == DMA_ERROR_CODE) {
 		spin_unlock_irqrestore(&domain->lock, flags);
 		goto out_free;
 	}
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -1982,28 +2144,19 @@ static void free_coherent(struct device
 			  void *virt_addr, dma_addr_t dma_addr)
 {
 	unsigned long flags;
-	struct amd_iommu *iommu;
 	struct protection_domain *domain;
-	u16 devid;
 
 	INC_STATS_COUNTER(cnt_free_coherent);
 
-	if (!check_device(dev))
-		return;
-
-	get_device_resources(dev, &iommu, &domain, &devid);
-
-	if (!iommu || !domain)
-		goto free_mem;
-
-	if (!dma_ops_domain(domain))
+	domain = get_domain(dev);
+	if (IS_ERR(domain))
 		goto free_mem;
 
 	spin_lock_irqsave(&domain->lock, flags);
 
-	__unmap_single(iommu, domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
+	__unmap_single(domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
 
-	iommu_completion_wait(iommu);
+	iommu_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -2017,22 +2170,7 @@ free_mem:
  */
 static int amd_iommu_dma_supported(struct device *dev, u64 mask)
 {
-	u16 bdf;
-	struct pci_dev *pcidev;
-
-	/* No device or no PCI device */
-	if (!dev || dev->bus != &pci_bus_type)
-		return 0;
-
-	pcidev = to_pci_dev(dev);
-
-	bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
-
-	/* Out of our scope? */
-	if (bdf > amd_iommu_last_bdf)
-		return 0;
-
-	return 1;
+	return check_device(dev);
 }
 
 /*
@@ -2046,25 +2184,28 @@ static void prealloc_protection_domains(
 {
 	struct pci_dev *dev = NULL;
 	struct dma_ops_domain *dma_dom;
-	struct amd_iommu *iommu;
 	u16 devid;
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		devid = calc_devid(dev->bus->number, dev->devfn);
-		if (devid > amd_iommu_last_bdf)
-			continue;
-		devid = amd_iommu_alias_table[devid];
-		if (domain_for_device(devid))
+
+		/* Do we handle this device? */
+		if (!check_device(&dev->dev))
 			continue;
-		iommu = amd_iommu_rlookup_table[devid];
-		if (!iommu)
+
+		/* Is there already any domain for it? */
+		if (domain_for_device(&dev->dev))
 			continue;
-		dma_dom = dma_ops_domain_alloc(iommu);
+
+		devid = get_device_id(&dev->dev);
+
+		dma_dom = dma_ops_domain_alloc();
 		if (!dma_dom)
 			continue;
 		init_unity_mappings_for_device(dma_dom, devid);
 		dma_dom->target_dev = devid;
 
+		attach_device(&dev->dev, &dma_dom->domain);
+
 		list_add_tail(&dma_dom->list, &iommu_pd_list);
 	}
 }
@@ -2082,6 +2223,12 @@ static struct dma_map_ops amd_iommu_dma_
 /*
  * The function which clues the AMD IOMMU driver into dma_ops.
  */
+
+void __init amd_iommu_init_api(void)
+{
+	register_iommu(&amd_iommu_ops);
+}
+
 int __init amd_iommu_init_dma_ops(void)
 {
 	struct amd_iommu *iommu;
@@ -2093,7 +2240,7 @@ int __init amd_iommu_init_dma_ops(void)
 	 * protection domain will be assigned to the default one.
 	 */
 	for_each_iommu(iommu) {
-		iommu->default_dom = dma_ops_domain_alloc(iommu);
+		iommu->default_dom = dma_ops_domain_alloc();
 		if (iommu->default_dom == NULL)
 			return -ENOMEM;
 		iommu->default_dom->domain.flags |= PD_DEFAULT_MASK;
@@ -2103,15 +2250,12 @@ int __init amd_iommu_init_dma_ops(void)
 	}
 
 	/*
-	 * If device isolation is enabled, pre-allocate the protection
-	 * domains for each device.
+	 * Pre-allocate the protection domains for each device.
 	 */
-	if (amd_iommu_isolate)
-		prealloc_protection_domains();
+	prealloc_protection_domains();
 
 	iommu_detected = 1;
-	force_iommu = 1;
-	bad_dma_address = 0;
+	swiotlb = 0;
 #ifdef CONFIG_GART_IOMMU
 	gart_iommu_aperture_disabled = 1;
 	gart_iommu_aperture = 0;
@@ -2120,10 +2264,6 @@ int __init amd_iommu_init_dma_ops(void)
 	/* Make the driver finally visible to the drivers */
 	dma_ops = &amd_iommu_dma_ops;
 
-	register_iommu(&amd_iommu_ops);
-
-	bus_register_notifier(&pci_bus_type, &device_nb);
-
 	amd_iommu_stats_init();
 
 	return 0;
@@ -2150,14 +2290,17 @@ free_domains:
 
 static void cleanup_domain(struct protection_domain *domain)
 {
+	struct iommu_dev_data *dev_data, *next;
 	unsigned long flags;
-	u16 devid;
 
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
 
-	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
-		if (amd_iommu_pd_table[devid] == domain)
-			__detach_device(domain, devid);
+	list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
+		struct device *dev = dev_data->dev;
+
+		do_detach(dev);
+		atomic_set(&dev_data->bind, 0);
+	}
 
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
@@ -2167,6 +2310,8 @@ static void protection_domain_free(struc
 	if (!domain)
 		return;
 
+	del_domain_from_list(domain);
+
 	if (domain->id)
 		domain_id_free(domain->id);
 
@@ -2185,6 +2330,9 @@ static struct protection_domain *protect
 	domain->id = domain_id_alloc();
 	if (!domain->id)
 		goto out_err;
+	INIT_LIST_HEAD(&domain->dev_list);
+
+	add_domain_to_list(domain);
 
 	return domain;
 
@@ -2241,26 +2389,23 @@ static void amd_iommu_domain_destroy(str
 static void amd_iommu_detach_device(struct iommu_domain *dom,
 				    struct device *dev)
 {
-	struct protection_domain *domain = dom->priv;
+	struct iommu_dev_data *dev_data = dev->archdata.iommu;
 	struct amd_iommu *iommu;
-	struct pci_dev *pdev;
 	u16 devid;
 
-	if (dev->bus != &pci_bus_type)
+	if (!check_device(dev))
 		return;
 
-	pdev = to_pci_dev(dev);
-
-	devid = calc_devid(pdev->bus->number, pdev->devfn);
+	devid = get_device_id(dev);
 
-	if (devid > 0)
-		detach_device(domain, devid);
+	if (dev_data->domain != NULL)
+		detach_device(dev);
 
 	iommu = amd_iommu_rlookup_table[devid];
 	if (!iommu)
 		return;
 
-	iommu_queue_inv_dev_entry(iommu, devid);
+	iommu_flush_device(dev);
 	iommu_completion_wait(iommu);
 }
 
@@ -2268,35 +2413,30 @@ static int amd_iommu_attach_device(struc
 				   struct device *dev)
 {
 	struct protection_domain *domain = dom->priv;
-	struct protection_domain *old_domain;
+	struct iommu_dev_data *dev_data;
 	struct amd_iommu *iommu;
-	struct pci_dev *pdev;
+	int ret;
 	u16 devid;
 
-	if (dev->bus != &pci_bus_type)
+	if (!check_device(dev))
 		return -EINVAL;
 
-	pdev = to_pci_dev(dev);
-
-	devid = calc_devid(pdev->bus->number, pdev->devfn);
+	dev_data = dev->archdata.iommu;
 
-	if (devid >= amd_iommu_last_bdf ||
-			devid != amd_iommu_alias_table[devid])
-		return -EINVAL;
+	devid = get_device_id(dev);
 
 	iommu = amd_iommu_rlookup_table[devid];
 	if (!iommu)
 		return -EINVAL;
 
-	old_domain = domain_for_device(devid);
-	if (old_domain)
-		detach_device(old_domain, devid);
+	if (dev_data->domain)
+		detach_device(dev);
 
-	attach_device(iommu, domain, devid);
+	ret = attach_device(dev, domain);
 
 	iommu_completion_wait(iommu);
 
-	return 0;
+	return ret;
 }
 
 static int amd_iommu_map_range(struct iommu_domain *dom,
@@ -2342,7 +2482,7 @@ static void amd_iommu_unmap_range(struct
 		iova  += PAGE_SIZE;
 	}
 
-	iommu_flush_domain(domain->id);
+	iommu_flush_tlb_pde(domain);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
@@ -2393,10 +2533,11 @@ static struct iommu_ops amd_iommu_ops =
 
 int __init amd_iommu_init_passthrough(void)
 {
+	struct amd_iommu *iommu;
 	struct pci_dev *dev = NULL;
-	u16 devid, devid2;
+	u16 devid;
 
-	/* allocate passthroug domain */
+	/* allocate passthrough domain */
 	pt_domain = protection_domain_alloc();
 	if (!pt_domain)
 		return -ENOMEM;
@@ -2404,20 +2545,17 @@ int __init amd_iommu_init_passthrough(vo
 	pt_domain->mode |= PAGE_MODE_NONE;
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		struct amd_iommu *iommu;
 
-		devid = calc_devid(dev->bus->number, dev->devfn);
-		if (devid > amd_iommu_last_bdf)
+		if (!check_device(&dev->dev))
 			continue;
 
-		devid2 = amd_iommu_alias_table[devid];
+		devid = get_device_id(&dev->dev);
 
-		iommu = amd_iommu_rlookup_table[devid2];
+		iommu = amd_iommu_rlookup_table[devid];
 		if (!iommu)
 			continue;
 
-		__attach_device(iommu, pt_domain, devid);
-		__attach_device(iommu, pt_domain, devid2);
+		attach_device(&dev->dev, pt_domain);
 	}
 
 	pr_info("AMD-Vi: Initialized for Passthrough Mode\n");
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/amd_iommu_init.c linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu_init.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/amd_iommu_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/amd_iommu_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
@@ -25,10 +25,12 @@
 #include <linux/interrupt.h>
 #include <linux/msi.h>
 #include <asm/pci-direct.h>
+#include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/x86_init.h>
 
 /*
  * definitions for the ACPI scanning code
@@ -123,18 +125,29 @@ u16 amd_iommu_last_bdf;			/* largest PCI
 					   to handle */
 LIST_HEAD(amd_iommu_unity_map);		/* a list of required unity mappings
 					   we find in ACPI */
-#ifdef CONFIG_IOMMU_STRESS
-bool amd_iommu_isolate = false;
-#else
-bool amd_iommu_isolate = true;		/* if true, device isolation is
-					   enabled */
-#endif
-
 bool amd_iommu_unmap_flush;		/* if true, flush on every unmap */
 
 LIST_HEAD(amd_iommu_list);		/* list of all AMD IOMMUs in the
 					   system */
 
+/* Array to assign indices to IOMMUs*/
+struct amd_iommu *amd_iommus[MAX_IOMMUS];
+int amd_iommus_present;
+
+/* IOMMUs have a non-present cache? */
+bool amd_iommu_np_cache __read_mostly;
+
+/*
+ * Set to true if ACPI table parsing and hardware intialization went properly
+ */
+static bool amd_iommu_initialized;
+
+/*
+ * List of protection domains - used during resume
+ */
+LIST_HEAD(amd_iommu_pd_list);
+spinlock_t amd_iommu_pd_lock;
+
 /*
  * Pointer to the device table which is shared by all AMD IOMMUs
  * it is indexed by the PCI device id or the HT unit id and contains
@@ -157,12 +170,6 @@ u16 *amd_iommu_alias_table;
 struct amd_iommu **amd_iommu_rlookup_table;
 
 /*
- * The pd table (protection domain table) is used to find the protection domain
- * data structure a device belongs to. Indexed with the PCI device id too.
- */
-struct protection_domain **amd_iommu_pd_table;
-
-/*
  * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
  * to know which ones are already in use.
  */
@@ -838,7 +845,18 @@ static void __init free_iommu_all(void)
 static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 {
 	spin_lock_init(&iommu->lock);
+
+	/* Add IOMMU to internal data structures */
 	list_add_tail(&iommu->list, &amd_iommu_list);
+	iommu->index             = amd_iommus_present++;
+
+	if (unlikely(iommu->index >= MAX_IOMMUS)) {
+		WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n");
+		return -ENOSYS;
+	}
+
+	/* Index is fine - add IOMMU to the array */
+	amd_iommus[iommu->index] = iommu;
 
 	/*
 	 * Copy data from ACPI table entry to the iommu struct
@@ -868,6 +886,9 @@ static int __init init_iommu_one(struct
 	init_iommu_from_acpi(iommu, h);
 	init_iommu_devices(iommu);
 
+	if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
+		amd_iommu_np_cache = true;
+
 	return pci_enable_device(iommu->dev);
 }
 
@@ -913,6 +934,8 @@ static int __init init_iommu_all(struct
 	}
 	WARN_ON(p != end);
 
+	amd_iommu_initialized = true;
+
 	return 0;
 }
 
@@ -925,7 +948,7 @@ static int __init init_iommu_all(struct
  *
  ****************************************************************************/
 
-static int __init iommu_setup_msi(struct amd_iommu *iommu)
+static int iommu_setup_msi(struct amd_iommu *iommu)
 {
 	int r;
 
@@ -1176,19 +1199,10 @@ static struct sys_device device_amd_iomm
  * functions. Finally it prints some information about AMD IOMMUs and
  * the driver state and enables the hardware.
  */
-int __init amd_iommu_init(void)
+static int __init amd_iommu_init(void)
 {
 	int i, ret = 0;
 
-
-	if (no_iommu) {
-		printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
-		return 0;
-	}
-
-	if (!amd_iommu_detected)
-		return -ENODEV;
-
 	/*
 	 * First parse ACPI tables to find the largest Bus/Dev/Func
 	 * we need to handle. Upon this information the shared data
@@ -1225,15 +1239,6 @@ int __init amd_iommu_init(void)
 	if (amd_iommu_rlookup_table == NULL)
 		goto free;
 
-	/*
-	 * Protection Domain table - maps devices to protection domains
-	 * This table has the same size as the rlookup_table
-	 */
-	amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-				     get_order(rlookup_table_size));
-	if (amd_iommu_pd_table == NULL)
-		goto free;
-
 	amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
 					    GFP_KERNEL | __GFP_ZERO,
 					    get_order(MAX_DOMAIN_ID/8));
@@ -1255,6 +1260,8 @@ int __init amd_iommu_init(void)
 	 */
 	amd_iommu_pd_alloc_bitmap[0] = 1;
 
+	spin_lock_init(&amd_iommu_pd_lock);
+
 	/*
 	 * now the data structures are allocated and basically initialized
 	 * start the real acpi table scan
@@ -1263,6 +1270,9 @@ int __init amd_iommu_init(void)
 	if (acpi_table_parse("IVRS", init_iommu_all) != 0)
 		goto free;
 
+	if (!amd_iommu_initialized)
+		goto free;
+
 	if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
 		goto free;
 
@@ -1274,39 +1284,43 @@ int __init amd_iommu_init(void)
 	if (ret)
 		goto free;
 
+	ret = amd_iommu_init_devices();
+	if (ret)
+		goto free;
+
 	if (iommu_pass_through)
 		ret = amd_iommu_init_passthrough();
 	else
 		ret = amd_iommu_init_dma_ops();
+
 	if (ret)
 		goto free;
 
+	amd_iommu_init_api();
+
+	amd_iommu_init_notifier();
+
 	enable_iommus();
 
 	if (iommu_pass_through)
 		goto out;
 
-	printk(KERN_INFO "AMD-Vi: device isolation ");
-	if (amd_iommu_isolate)
-		printk("enabled\n");
-	else
-		printk("disabled\n");
-
 	if (amd_iommu_unmap_flush)
 		printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
 	else
 		printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
 
+	x86_platform.iommu_shutdown = disable_iommus;
 out:
 	return ret;
 
 free:
+
+	amd_iommu_uninit_devices();
+
 	free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
 		   get_order(MAX_DOMAIN_ID/8));
 
-	free_pages((unsigned long)amd_iommu_pd_table,
-		   get_order(rlookup_table_size));
-
 	free_pages((unsigned long)amd_iommu_rlookup_table,
 		   get_order(rlookup_table_size));
 
@@ -1323,11 +1337,6 @@ free:
 	goto out;
 }
 
-void amd_iommu_shutdown(void)
-{
-	disable_iommus();
-}
-
 /****************************************************************************
  *
  * Early detect code. This code runs at IOMMU detection time in the DMA
@@ -1342,16 +1351,16 @@ static int __init early_amd_iommu_detect
 
 void __init amd_iommu_detect(void)
 {
-	if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture))
+	if (no_iommu || (iommu_detected && !gart_iommu_aperture))
 		return;
 
 	if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
 		iommu_detected = 1;
 		amd_iommu_detected = 1;
-#ifdef CONFIG_GART_IOMMU
-		gart_iommu_aperture_disabled = 1;
-		gart_iommu_aperture = 0;
-#endif
+		x86_init.iommu.iommu_init = amd_iommu_init;
+
+		/* Make sure ACS will be enabled */
+		pci_request_acs();
 	}
 }
 
@@ -1372,10 +1381,6 @@ static int __init parse_amd_iommu_dump(c
 static int __init parse_amd_iommu_options(char *str)
 {
 	for (; *str; ++str) {
-		if (strncmp(str, "isolate", 7) == 0)
-			amd_iommu_isolate = true;
-		if (strncmp(str, "share", 5) == 0)
-			amd_iommu_isolate = false;
 		if (strncmp(str, "fullflush", 9) == 0)
 			amd_iommu_unmap_flush = true;
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/aperture_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/aperture_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/aperture_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/aperture_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,8 +28,10 @@
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
 #include <asm/k8.h>
+#include <asm/x86_init.h>
 
 int gart_iommu_aperture;
+EXPORT_SYMBOL_GPL(gart_iommu_aperture);
 int gart_iommu_aperture_disabled __initdata;
 int gart_iommu_aperture_allowed __initdata;
 
@@ -279,7 +281,8 @@ void __init early_gart_iommu_check(void)
 	 * or BIOS forget to put that in reserved.
 	 * try to update e820 to make that region as reserved.
 	 */
-	int i, fix, slot;
+	u32 agp_aper_base = 0, agp_aper_order = 0;
+	int i, fix, slot, valid_agp = 0;
 	u32 ctl;
 	u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
 	u64 aper_base = 0, last_aper_base = 0;
@@ -289,6 +292,8 @@ void __init early_gart_iommu_check(void)
 		return;
 
 	/* This is mostly duplicate of iommu_hole_init */
+	agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
+
 	fix = 0;
 	for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 		int bus;
@@ -341,10 +346,10 @@ void __init early_gart_iommu_check(void)
 		}
 	}
 
-	if (!fix)
+	if (valid_agp)
 		return;
 
-	/* different nodes have different setting, disable them all at first*/
+	/* disable them all at first */
 	for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 		int bus;
 		int dev_base, dev_limit;
@@ -400,6 +405,7 @@ void __init gart_iommu_hole_init(void)
 
 			iommu_detected = 1;
 			gart_iommu_aperture = 1;
+			x86_init.iommu.iommu_init = gart_iommu_init;
 
 			aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
 			aper_size = (32 * 1024 * 1024) << aper_order;
@@ -456,8 +462,6 @@ out:
 
 	if (aper_alloc) {
 		/* Got the aperture from the AGP bridge */
-	} else if (swiotlb && !valid_agp) {
-		/* Do nothing */
 	} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
 		   force_iommu ||
 		   valid_agp ||
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,12 +61,6 @@ unsigned int boot_cpu_physical_apicid =
 
 /*
  * The highest APIC ID seen during enumeration.
- *
- * On AMD, this determines the messaging protocol we can use: if all APIC IDs
- * are in the 0 ... 7 range, then we can use logical addressing which
- * has some performance advantages (better broadcasting).
- *
- * If there's an APIC ID above 8, we use physical addressing.
  */
 unsigned int max_physical_apicid;
 
@@ -241,28 +235,13 @@ static int modern_apic(void)
 }
 
 /*
- * bare function to substitute write operation
- * and it's _that_ fast :)
- */
-static void native_apic_write_dummy(u32 reg, u32 v)
-{
-	WARN_ON_ONCE((cpu_has_apic || !disable_apic));
-}
-
-static u32 native_apic_read_dummy(u32 reg)
-{
-	WARN_ON_ONCE((cpu_has_apic && !disable_apic));
-	return 0;
-}
-
-/*
- * right after this call apic->write/read doesn't do anything
- * note that there is no restore operation it works one way
+ * right after this call apic become NOOP driven
+ * so apic->write/read doesn't do anything
  */
 void apic_disable(void)
 {
-	apic->read = native_apic_read_dummy;
-	apic->write = native_apic_write_dummy;
+	pr_info("APIC: switched to apic NOOP\n");
+	apic = &apic_noop;
 }
 
 void native_apic_wait_icr_idle(void)
@@ -459,7 +438,7 @@ static void lapic_timer_setup(enum clock
 		v = apic_read(APIC_LVTT);
 		v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
 		apic_write(APIC_LVTT, v);
-		apic_write(APIC_TMICT, 0xffffffff);
+		apic_write(APIC_TMICT, 0);
 		break;
 	case CLOCK_EVT_MODE_RESUME:
 		/* Nothing to do here */
@@ -662,7 +641,7 @@ static int __init calibrate_APIC_clock(v
 	calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
 
 	apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
-	apic_printk(APIC_VERBOSE, "..... mult: %ld\n", lapic_clockevent.mult);
+	apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
 	apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
 		    calibration_result);
 
@@ -1356,7 +1335,7 @@ void enable_x2apic(void)
 
 	rdmsr(MSR_IA32_APICBASE, msr, msr2);
 	if (!(msr & X2APIC_ENABLE)) {
-		pr_info("Enabling x2apic\n");
+		printk_once(KERN_INFO "Enabling x2apic\n");
 		wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
 	}
 }
@@ -1392,14 +1371,11 @@ void __init enable_IR_x2apic(void)
 	unsigned long flags;
 	struct IO_APIC_route_entry **ioapic_entries = NULL;
 	int ret, x2apic_enabled = 0;
-	int dmar_table_init_ret = 0;
+	int dmar_table_init_ret;
 
-#ifdef CONFIG_INTR_REMAP
 	dmar_table_init_ret = dmar_table_init();
-	if (dmar_table_init_ret)
-		pr_debug("dmar_table_init() failed with %d:\n",
-				dmar_table_init_ret);
-#endif
+	if (dmar_table_init_ret && !x2apic_supported())
+		return;
 
 	ioapic_entries = alloc_ioapic_entries();
 	if (!ioapic_entries) {
@@ -1665,9 +1641,7 @@ int __init APIC_init_uniprocessor(void)
 #endif
 
 	enable_IR_x2apic();
-#ifdef CONFIG_X86_64
 	default_setup_apic_routing();
-#endif
 
 	verify_local_APIC();
 	connect_bsp_APIC();
@@ -1915,18 +1889,6 @@ void __cpuinit generic_processor_info(in
 	if (apicid > max_physical_apicid)
 		max_physical_apicid = apicid;
 
-#ifdef CONFIG_X86_32
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_INTEL:
-		if (num_processors > 8)
-			def_to_bigsmp = 1;
-		break;
-	case X86_VENDOR_AMD:
-		if (max_physical_apicid >= 8)
-			def_to_bigsmp = 1;
-	}
-#endif
-
 #if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
 	early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
 	early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic_flat_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_flat_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic_flat_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_flat_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -240,6 +240,11 @@ static int physflat_acpi_madt_oem_check(
 		printk(KERN_DEBUG "system APIC only can use physical flat");
 		return 1;
 	}
+
+	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "EXA", 3)) {
+		printk(KERN_DEBUG "IBM Summit detected, will use apic physical");
+		return 1;
+	}
 #endif
 
 	return 0;
@@ -306,10 +311,7 @@ physflat_cpu_mask_to_apicid_and(const st
 		if (cpumask_test_cpu(cpu, cpu_online_mask))
 			break;
 	}
-	if (cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-
-	return BAD_APICID;
+	return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 struct apic apic_physflat =  {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic_noop.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_noop.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/apic_noop.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/apic_noop.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,200 @@
+/*
+ * NOOP APIC driver.
+ *
+ * Does almost nothing and should be substituted by a real apic driver via
+ * probe routine.
+ *
+ * Though in case if apic is disabled (for some reason) we try
+ * to not uglify the caller's code and allow to call (some) apic routines
+ * like self-ipi, etc...
+ */
+
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apicdef.h>
+#include <asm/apic.h>
+#include <asm/setup.h>
+
+#include <linux/smp.h>
+#include <asm/ipi.h>
+
+#include <linux/interrupt.h>
+#include <asm/acpi.h>
+#include <asm/e820.h>
+
+static void noop_init_apic_ldr(void) { }
+static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
+static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { }
+static void noop_send_IPI_allbutself(int vector) { }
+static void noop_send_IPI_all(int vector) { }
+static void noop_send_IPI_self(int vector) { }
+static void noop_apic_wait_icr_idle(void) { }
+static void noop_apic_icr_write(u32 low, u32 id) { }
+
+static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
+{
+	return -1;
+}
+
+static u32 noop_safe_apic_wait_icr_idle(void)
+{
+	return 0;
+}
+
+static u64 noop_apic_icr_read(void)
+{
+	return 0;
+}
+
+static int noop_cpu_to_logical_apicid(int cpu)
+{
+	return 0;
+}
+
+static int noop_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return 0;
+}
+
+static unsigned int noop_get_apic_id(unsigned long x)
+{
+	return 0;
+}
+
+static int noop_probe(void)
+{
+	/*
+	 * NOOP apic should not ever be
+	 * enabled via probe routine
+	 */
+	return 0;
+}
+
+static int noop_apic_id_registered(void)
+{
+	/*
+	 * if we would be really "pedantic"
+	 * we should pass read_apic_id() here
+	 * but since NOOP suppose APIC ID = 0
+	 * lets save a few cycles
+	 */
+	return physid_isset(0, phys_cpu_present_map);
+}
+
+static const struct cpumask *noop_target_cpus(void)
+{
+	/* only BSP here */
+	return cpumask_of(0);
+}
+
+static unsigned long noop_check_apicid_used(physid_mask_t *map, int apicid)
+{
+	return physid_isset(apicid, *map);
+}
+
+static unsigned long noop_check_apicid_present(int bit)
+{
+	return physid_isset(bit, phys_cpu_present_map);
+}
+
+static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	if (cpu != 0)
+		pr_warning("APIC: Vector allocated for non-BSP cpu\n");
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+int noop_apicid_to_node(int logical_apicid)
+{
+	/* we're always on node 0 */
+	return 0;
+}
+
+static u32 noop_apic_read(u32 reg)
+{
+	WARN_ON_ONCE((cpu_has_apic && !disable_apic));
+	return 0;
+}
+
+static void noop_apic_write(u32 reg, u32 v)
+{
+	WARN_ON_ONCE(cpu_has_apic && !disable_apic);
+}
+
+struct apic apic_noop = {
+	.name				= "noop",
+	.probe				= noop_probe,
+	.acpi_madt_oem_check		= NULL,
+
+	.apic_id_registered		= noop_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	/* logical delivery broadcast to all CPUs: */
+	.irq_dest_mode			= 1,
+
+	.target_cpus			= noop_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= noop_check_apicid_used,
+	.check_apicid_present		= noop_check_apicid_present,
+
+	.vector_allocation_domain	= noop_vector_allocation_domain,
+	.init_apic_ldr			= noop_init_apic_ldr,
+
+	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= noop_apicid_to_node,
+
+	.cpu_to_logical_apicid		= noop_cpu_to_logical_apicid,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= physid_set_mask_of_physid,
+
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+
+	.phys_pkg_id			= noop_phys_pkg_id,
+
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= noop_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0x0F << 24,
+
+	.cpu_mask_to_apicid		= default_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= noop_send_IPI_mask,
+	.send_IPI_mask_allbutself	= noop_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= noop_send_IPI_allbutself,
+	.send_IPI_all			= noop_send_IPI_all,
+	.send_IPI_self			= noop_send_IPI_self,
+
+	.wakeup_secondary_cpu		= noop_wakeup_secondary_cpu,
+
+	/* should be safe */
+	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW,
+	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+	.wait_for_init_deassert		= NULL,
+
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= NULL,
+
+	.read				= noop_apic_read,
+	.write				= noop_apic_write,
+	.icr_read			= noop_apic_icr_read,
+	.icr_write			= noop_apic_icr_write,
+	.wait_icr_idle			= noop_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= noop_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/bigsmp_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/bigsmp_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/bigsmp_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/bigsmp_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,7 @@ static const struct cpumask *bigsmp_targ
 #endif
 }
 
-static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid)
 {
 	return 0;
 }
@@ -93,11 +93,6 @@ static int bigsmp_cpu_present_to_apicid(
 	return BAD_APICID;
 }
 
-static physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
-{
-	return physid_mask_of_physid(phys_apicid);
-}
-
 /* Mapping from cpu number to logical apicid */
 static inline int bigsmp_cpu_to_logical_apicid(int cpu)
 {
@@ -106,10 +101,10 @@ static inline int bigsmp_cpu_to_logical_
 	return cpu_physical_id(cpu);
 }
 
-static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
+static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
 {
 	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0xFFL);
+	physids_promote(0xFFL, retmap);
 }
 
 static int bigsmp_check_phys_apicid_present(int phys_apicid)
@@ -136,10 +131,7 @@ static unsigned int bigsmp_cpu_mask_to_a
 		if (cpumask_test_cpu(cpu, cpu_online_mask))
 			break;
 	}
-	if (cpu < nr_cpu_ids)
-		return bigsmp_cpu_to_logical_apicid(cpu);
-
-	return BAD_APICID;
+	return bigsmp_cpu_to_logical_apicid(cpu);
 }
 
 static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
@@ -230,7 +222,7 @@ struct apic apic_bigsmp = {
 	.apicid_to_node			= bigsmp_apicid_to_node,
 	.cpu_to_logical_apicid		= bigsmp_cpu_to_logical_apicid,
 	.cpu_present_to_apicid		= bigsmp_cpu_present_to_apicid,
-	.apicid_to_cpu_present		= bigsmp_apicid_to_cpu_present,
+	.apicid_to_cpu_present		= physid_set_mask_of_physid,
 	.setup_portio_remap		= NULL,
 	.check_phys_apicid_present	= bigsmp_check_phys_apicid_present,
 	.enable_apic_mode		= NULL,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/es7000_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/es7000_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/es7000_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/es7000_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,9 @@
  *
  * http://www.unisys.com
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/notifier.h>
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
@@ -223,9 +226,9 @@ static int parse_unisys_oem(char *oemptr
 			mip_addr = val;
 			mip = (struct mip_reg *)val;
 			mip_reg = __va(mip);
-			pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
+			pr_debug("host_reg = 0x%lx\n",
 				 (unsigned long)host_reg);
-			pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
+			pr_debug("mip_reg = 0x%lx\n",
 				 (unsigned long)mip_reg);
 			success++;
 			break;
@@ -401,7 +404,7 @@ static void es7000_enable_apic_mode(void
 	if (!es7000_plat)
 		return;
 
-	printk(KERN_INFO "ES7000: Enabling APIC mode.\n");
+	pr_info("Enabling APIC mode.\n");
 	memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
 	es7000_mip_reg.off_0x00 = MIP_SW_APIC;
 	es7000_mip_reg.off_0x38 = MIP_VALID;
@@ -466,11 +469,11 @@ static const struct cpumask *es7000_targ
 	return cpumask_of(smp_processor_id());
 }
 
-static unsigned long
-es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
 {
 	return 0;
 }
+
 static unsigned long es7000_check_apicid_present(int bit)
 {
 	return physid_isset(bit, phys_cpu_present_map);
@@ -514,8 +517,7 @@ static void es7000_setup_apic_routing(vo
 {
 	int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
 
-	printk(KERN_INFO
-	  "Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
+	pr_info("Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
 		(apic_version[apic] == 0x14) ?
 			"Physical Cluster" : "Logical Cluster",
 		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
@@ -539,14 +541,10 @@ static int es7000_cpu_present_to_apicid(
 
 static int cpu_id;
 
-static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
+static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
 {
-	physid_mask_t mask;
-
-	mask = physid_mask_of_physid(cpu_id);
+	physid_set_mask_of_physid(cpu_id, retmap);
 	++cpu_id;
-
-	return mask;
 }
 
 /* Mapping from cpu number to logical apicid */
@@ -561,10 +559,10 @@ static int es7000_cpu_to_logical_apicid(
 #endif
 }
 
-static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
+static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
 {
 	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0xff);
+	physids_promote(0xFFL, retmap);
 }
 
 static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/io_apic.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/io_apic.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/io_apic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/io_apic.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,8 +60,6 @@
 #include <asm/irq_remapping.h>
 #include <asm/hpet.h>
 #include <asm/hw_irq.h>
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/uv_irq.h>
 
 #include <asm/apic.h>
 
@@ -140,20 +138,6 @@ static struct irq_pin_list *get_one_free
 	return pin;
 }
 
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * Most irqs are mapped 1:1 with pins.
- */
-struct irq_cfg {
-	struct irq_pin_list *irq_2_pin;
-	cpumask_var_t domain;
-	cpumask_var_t old_domain;
-	unsigned move_cleanup_count;
-	u8 vector;
-	u8 move_in_progress : 1;
-};
-
 /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
 #ifdef CONFIG_SPARSE_IRQ
 static struct irq_cfg irq_cfgx[] = {
@@ -209,7 +193,7 @@ int __init arch_early_irq_init(void)
 }
 
 #ifdef CONFIG_SPARSE_IRQ
-static struct irq_cfg *irq_cfg(unsigned int irq)
+struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	struct irq_cfg *cfg = NULL;
 	struct irq_desc *desc;
@@ -361,7 +345,7 @@ void arch_free_chip_data(struct irq_desc
 /* end for move_irq_desc */
 
 #else
-static struct irq_cfg *irq_cfg(unsigned int irq)
+struct irq_cfg *irq_cfg(unsigned int irq)
 {
 	return irq < nr_irqs ? irq_cfgx + irq : NULL;
 }
@@ -555,23 +539,41 @@ static void __init replace_pin_at_irq_no
 	add_pin_to_irq_node(cfg, node, newapic, newpin);
 }
 
+static void __io_apic_modify_irq(struct irq_pin_list *entry,
+				 int mask_and, int mask_or,
+				 void (*final)(struct irq_pin_list *entry))
+{
+	unsigned int reg, pin;
+
+	pin = entry->pin;
+	reg = io_apic_read(entry->apic, 0x10 + pin * 2);
+	reg &= mask_and;
+	reg |= mask_or;
+	io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
+	if (final)
+		final(entry);
+}
+
 static void io_apic_modify_irq(struct irq_cfg *cfg,
 			       int mask_and, int mask_or,
 			       void (*final)(struct irq_pin_list *entry))
 {
-	int pin;
 	struct irq_pin_list *entry;
 
-	for_each_irq_pin(entry, cfg->irq_2_pin) {
-		unsigned int reg;
-		pin = entry->pin;
-		reg = io_apic_read(entry->apic, 0x10 + pin * 2);
-		reg &= mask_and;
-		reg |= mask_or;
-		io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
-		if (final)
-			final(entry);
-	}
+	for_each_irq_pin(entry, cfg->irq_2_pin)
+		__io_apic_modify_irq(entry, mask_and, mask_or, final);
+}
+
+static void __mask_and_edge_IO_APIC_irq(struct irq_pin_list *entry)
+{
+	__io_apic_modify_irq(entry, ~IO_APIC_REDIR_LEVEL_TRIGGER,
+			     IO_APIC_REDIR_MASKED, NULL);
+}
+
+static void __unmask_and_level_IO_APIC_irq(struct irq_pin_list *entry)
+{
+	__io_apic_modify_irq(entry, ~IO_APIC_REDIR_MASKED,
+			     IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
 }
 
 static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
@@ -595,18 +597,6 @@ static void __mask_IO_APIC_irq(struct ir
 	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
 }
 
-static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_LEVEL_TRIGGER,
-			IO_APIC_REDIR_MASKED, NULL);
-}
-
-static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED,
-			IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
-}
-
 static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
 {
 	struct irq_cfg *cfg = desc->chip_data;
@@ -1177,7 +1167,7 @@ __assign_irq_vector(int irq, struct irq_
 	int cpu, err;
 	cpumask_var_t tmp_mask;
 
-	if ((cfg->move_in_progress) || cfg->move_cleanup_count)
+	if (cfg->move_in_progress)
 		return -EBUSY;
 
 	if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC))
@@ -1237,8 +1227,7 @@ next:
 	return err;
 }
 
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
 {
 	int err;
 	unsigned long flags;
@@ -1599,9 +1588,6 @@ __apicdebuginit(void) print_IO_APIC(void
 	struct irq_desc *desc;
 	unsigned int irq;
 
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
 	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
 	for (i = 0; i < nr_ioapics; i++)
 		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
@@ -1708,9 +1694,6 @@ __apicdebuginit(void) print_APIC_field(i
 {
 	int i;
 
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
 	printk(KERN_DEBUG);
 
 	for (i = 0; i < 8; i++)
@@ -1724,9 +1707,6 @@ __apicdebuginit(void) print_local_APIC(v
 	unsigned int i, v, ver, maxlvt;
 	u64 icr;
 
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
 	printk(KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
 		smp_processor_id(), hard_smp_processor_id());
 	v = apic_read(APIC_ID);
@@ -1824,13 +1804,19 @@ __apicdebuginit(void) print_local_APIC(v
 	printk("\n");
 }
 
-__apicdebuginit(void) print_all_local_APICs(void)
+__apicdebuginit(void) print_local_APICs(int maxcpu)
 {
 	int cpu;
 
+	if (!maxcpu)
+		return;
+
 	preempt_disable();
-	for_each_online_cpu(cpu)
+	for_each_online_cpu(cpu) {
+		if (cpu >= maxcpu)
+			break;
 		smp_call_function_single(cpu, print_local_APIC, NULL, 1);
+	}
 	preempt_enable();
 }
 
@@ -1839,7 +1825,7 @@ __apicdebuginit(void) print_PIC(void)
 	unsigned int v;
 	unsigned long flags;
 
-	if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
+	if (!nr_legacy_irqs)
 		return;
 
 	printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1866,21 +1852,41 @@ __apicdebuginit(void) print_PIC(void)
 	printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
 }
 
-__apicdebuginit(int) print_all_ICs(void)
+static int __initdata show_lapic = 1;
+static __init int setup_show_lapic(char *arg)
 {
+	int num = -1;
+
+	if (strcmp(arg, "all") == 0) {
+		show_lapic = CONFIG_NR_CPUS;
+	} else {
+		get_option(&arg, &num);
+		if (num >= 0)
+			show_lapic = num;
+	}
+
+	return 1;
+}
+__setup("show_lapic=", setup_show_lapic);
+
+__apicdebuginit(int) print_ICs(void)
+{
+	if (apic_verbosity == APIC_QUIET)
+		return 0;
+
 	print_PIC();
 
 	/* don't print out if apic is not there */
 	if (!cpu_has_apic && !apic_from_smp_config())
 		return 0;
 
-	print_all_local_APICs();
+	print_local_APICs(show_lapic);
 	print_IO_APIC();
 
 	return 0;
 }
 
-fs_initcall(print_all_ICs);
+fs_initcall(print_ICs);
 
 
 /* Where if anywhere is the i8259 connect in external int mode */
@@ -2031,7 +2037,7 @@ void __init setup_ioapic_ids_from_mpc(vo
 	 * This is broken; anything with a real cpu count has to
 	 * circumvent this idiocy regardless.
 	 */
-	phys_id_present_map = apic->ioapic_phys_id_map(phys_cpu_present_map);
+	apic->ioapic_phys_id_map(&phys_cpu_present_map, &phys_id_present_map);
 
 	/*
 	 * Set the IOAPIC ID to the value stored in the MPC table.
@@ -2058,7 +2064,7 @@ void __init setup_ioapic_ids_from_mpc(vo
 		 * system must have a unique ID or we get lots of nice
 		 * 'stuck on smp_invalidate_needed IPI wait' messages.
 		 */
-		if (apic->check_apicid_used(phys_id_present_map,
+		if (apic->check_apicid_used(&phys_id_present_map,
 					mp_ioapics[apic_id].apicid)) {
 			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
 				apic_id, mp_ioapics[apic_id].apicid);
@@ -2073,7 +2079,7 @@ void __init setup_ioapic_ids_from_mpc(vo
 			mp_ioapics[apic_id].apicid = i;
 		} else {
 			physid_mask_t tmp;
-			tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid);
+			apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid, &tmp);
 			apic_printk(APIC_VERBOSE, "Setting %d in the "
 					"phys_id_present_map\n",
 					mp_ioapics[apic_id].apicid);
@@ -2228,20 +2234,16 @@ static int ioapic_retrigger_irq(unsigned
  */
 
 #ifdef CONFIG_SMP
-static void send_cleanup_vector(struct irq_cfg *cfg)
+void send_cleanup_vector(struct irq_cfg *cfg)
 {
 	cpumask_var_t cleanup_mask;
 
 	if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
 		unsigned int i;
-		cfg->move_cleanup_count = 0;
-		for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
-			cfg->move_cleanup_count++;
 		for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
 			apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
 	} else {
 		cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
-		cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
 		apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
 		free_cpumask_var(cleanup_mask);
 	}
@@ -2272,31 +2274,30 @@ static void __target_IO_APIC_irq(unsigne
 	}
 }
 
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
-
 /*
  * Either sets desc->affinity to a valid value, and returns
- * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
  * leaves desc->affinity untouched.
  */
-static unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+unsigned int
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
+		  unsigned int *dest_id)
 {
 	struct irq_cfg *cfg;
 	unsigned int irq;
 
 	if (!cpumask_intersects(mask, cpu_online_mask))
-		return BAD_APICID;
+		return -1;
 
 	irq = desc->irq;
 	cfg = desc->chip_data;
 	if (assign_irq_vector(irq, cfg, mask))
-		return BAD_APICID;
+		return -1;
 
 	cpumask_copy(desc->affinity, mask);
 
-	return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+	*dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+	return 0;
 }
 
 static int
@@ -2312,12 +2313,11 @@ set_ioapic_affinity_irq_desc(struct irq_
 	cfg = desc->chip_data;
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	dest = set_desc_affinity(desc, mask);
-	if (dest != BAD_APICID) {
+	ret = set_desc_affinity(desc, mask, &dest);
+	if (!ret) {
 		/* Only the high 8 bits are valid. */
 		dest = SET_APIC_LOGICAL_ID(dest);
 		__target_IO_APIC_irq(irq, dest, cfg);
-		ret = 0;
 	}
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -2432,8 +2432,13 @@ asmlinkage void smp_irq_move_cleanup_int
 			continue;
 
 		cfg = irq_cfg(irq);
-		spin_lock(&desc->lock);
-		if (!cfg->move_cleanup_count)
+		raw_spin_lock(&desc->lock);
+
+		/*
+		 * Check if the irq migration is in progress. If so, we
+		 * haven't received the cleanup request yet for this irq.
+		 */
+		if (cfg->move_in_progress)
 			goto unlock;
 
 		if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
@@ -2452,29 +2457,40 @@ asmlinkage void smp_irq_move_cleanup_int
 			goto unlock;
 		}
 		__get_cpu_var(vector_irq)[vector] = -1;
-		cfg->move_cleanup_count--;
 unlock:
-		spin_unlock(&desc->lock);
+		raw_spin_unlock(&desc->lock);
 	}
 
 	irq_exit();
 }
 
-static void irq_complete_move(struct irq_desc **descp)
+static void __irq_complete_move(struct irq_desc **descp, unsigned vector)
 {
 	struct irq_desc *desc = *descp;
 	struct irq_cfg *cfg = desc->chip_data;
-	unsigned vector, me;
+	unsigned me;
 
 	if (likely(!cfg->move_in_progress))
 		return;
 
-	vector = ~get_irq_regs()->orig_ax;
 	me = smp_processor_id();
 
 	if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
 		send_cleanup_vector(cfg);
 }
+
+static void irq_complete_move(struct irq_desc **descp)
+{
+	__irq_complete_move(descp, ~get_irq_regs()->orig_ax);
+}
+
+void irq_force_complete_move(int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = desc->chip_data;
+
+	__irq_complete_move(&desc, cfg->vector);
+}
 #else
 static inline void irq_complete_move(struct irq_desc **descp) {}
 #endif
@@ -2490,6 +2506,59 @@ static void ack_apic_edge(unsigned int i
 
 atomic_t irq_mis_count;
 
+/*
+ * IO-APIC versions below 0x20 don't support EOI register.
+ * For the record, here is the information about various versions:
+ *     0Xh     82489DX
+ *     1Xh     I/OAPIC or I/O(x)APIC which are not PCI 2.2 Compliant
+ *     2Xh     I/O(x)APIC which is PCI 2.2 Compliant
+ *     30h-FFh Reserved
+ *
+ * Some of the Intel ICH Specs (ICH2 to ICH5) documents the io-apic
+ * version as 0x2. This is an error with documentation and these ICH chips
+ * use io-apic's of version 0x20.
+ *
+ * For IO-APIC's with EOI register, we use that to do an explicit EOI.
+ * Otherwise, we simulate the EOI message manually by changing the trigger
+ * mode to edge and then back to level, with RTE being masked during this.
+*/
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+	struct irq_pin_list *entry;
+
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
+		if (mp_ioapics[entry->apic].apicver >= 0x20) {
+			/*
+			 * Intr-remapping uses pin number as the virtual vector
+			 * in the RTE. Actual vector is programmed in
+			 * intr-remapping table entry. Hence for the io-apic
+			 * EOI we use the pin number.
+			 */
+			if (irq_remapped(irq))
+				io_apic_eoi(entry->apic, entry->pin);
+			else
+				io_apic_eoi(entry->apic, cfg->vector);
+		} else {
+			__mask_and_edge_IO_APIC_irq(entry);
+			__unmask_and_level_IO_APIC_irq(entry);
+		}
+	}
+}
+
+static void eoi_ioapic_irq(struct irq_desc *desc)
+{
+	struct irq_cfg *cfg;
+	unsigned long flags;
+	unsigned int irq;
+
+	irq = desc->irq;
+	cfg = desc->chip_data;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__eoi_ioapic_irq(irq, cfg);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
 static void ack_apic_level(unsigned int irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
@@ -2525,6 +2594,19 @@ static void ack_apic_level(unsigned int
 	 * level-triggered interrupt.  We mask the source for the time of the
 	 * operation to prevent an edge-triggered interrupt escaping meanwhile.
 	 * The idea is from Manfred Spraul.  --macro
+	 *
+	 * Also in the case when cpu goes offline, fixup_irqs() will forward
+	 * any unhandled interrupt on the offlined cpu to the new cpu
+	 * destination that is handling the corresponding interrupt. This
+	 * interrupt forwarding is done via IPI's. Hence, in this case also
+	 * level-triggered io-apic interrupt will be seen as an edge
+	 * interrupt in the IRR. And we can't rely on the cpu's EOI
+	 * to be broadcasted to the IO-APIC's which will clear the remoteIRR
+	 * corresponding to the level-triggered interrupt. Hence on IO-APIC's
+	 * supporting EOI register, we do an explicit EOI to clear the
+	 * remote IRR and on IO-APIC's which don't have an EOI register,
+	 * we use the above logic (mask+edge followed by unmask+level) from
+	 * Manfred Spraul to clear the remote IRR.
 	 */
 	cfg = desc->chip_data;
 	i = cfg->vector;
@@ -2536,6 +2618,19 @@ static void ack_apic_level(unsigned int
 	 */
 	ack_APIC_irq();
 
+	/*
+	 * Tail end of clearing remote IRR bit (either by delivering the EOI
+	 * message via io-apic EOI register write or simulating it using
+	 * mask+edge followed by unnask+level logic) manually when the
+	 * level triggered interrupt is seen as the edge triggered interrupt
+	 * at the cpu.
+	 */
+	if (!(v & (1 << (i & 0x1f)))) {
+		atomic_inc(&irq_mis_count);
+
+		eoi_ioapic_irq(desc);
+	}
+
 	/* Now we can move and renable the irq */
 	if (unlikely(do_unmask_irq)) {
 		/* Only migrate the irq if the ack has been received.
@@ -2569,41 +2664,9 @@ static void ack_apic_level(unsigned int
 			move_masked_irq(irq);
 		unmask_IO_APIC_irq_desc(desc);
 	}
-
-	/* Tail end of version 0x11 I/O APIC bug workaround */
-	if (!(v & (1 << (i & 0x1f)))) {
-		atomic_inc(&irq_mis_count);
-		spin_lock(&ioapic_lock);
-		__mask_and_edge_IO_APIC_irq(cfg);
-		__unmask_and_level_IO_APIC_irq(cfg);
-		spin_unlock(&ioapic_lock);
-	}
 }
 
 #ifdef CONFIG_INTR_REMAP
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
-{
-	struct irq_pin_list *entry;
-
-	for_each_irq_pin(entry, cfg->irq_2_pin)
-		io_apic_eoi(entry->apic, entry->pin);
-}
-
-static void
-eoi_ioapic_irq(struct irq_desc *desc)
-{
-	struct irq_cfg *cfg;
-	unsigned long flags;
-	unsigned int irq;
-
-	irq = desc->irq;
-	cfg = desc->chip_data;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	__eoi_ioapic_irq(irq, cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
 static void ir_ack_apic_edge(unsigned int irq)
 {
 	ack_APIC_irq();
@@ -3157,6 +3220,7 @@ unsigned int create_irq_nr(unsigned int
 			continue;
 
 		desc_new = move_irq_desc(desc_new, node);
+		cfg_new = desc_new->chip_data;
 
 		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
 			irq = new;
@@ -3211,7 +3275,8 @@ void destroy_irq(unsigned int irq)
  * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
+			   struct msi_msg *msg, u8 hpet_id)
 {
 	struct irq_cfg *cfg;
 	int err;
@@ -3245,7 +3310,10 @@ static int msi_compose_msg(struct pci_de
 		irte.dest_id = IRTE_DEST(dest);
 
 		/* Set source-id of interrupt request */
-		set_msi_sid(&irte, pdev);
+		if (pdev)
+			set_msi_sid(&irte, pdev);
+		else
+			set_hpet_sid(&irte, hpet_id);
 
 		modify_irte(irq, &irte);
 
@@ -3291,8 +3359,7 @@ static int set_msi_irq_affinity(unsigned
 	struct msi_msg msg;
 	unsigned int dest;
 
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
+	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
 	cfg = desc->chip_data;
@@ -3324,8 +3391,7 @@ ir_set_msi_irq_affinity(unsigned int irq
 	if (get_irte(irq, &irte))
 		return -1;
 
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
+	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
 	irte.vector = cfg->vector;
@@ -3410,7 +3476,7 @@ static int setup_msi_irq(struct pci_dev
 	int ret;
 	struct msi_msg msg;
 
-	ret = msi_compose_msg(dev, irq, &msg);
+	ret = msi_compose_msg(dev, irq, &msg, -1);
 	if (ret < 0)
 		return ret;
 
@@ -3507,8 +3573,7 @@ static int dmar_msi_set_affinity(unsigne
 	struct msi_msg msg;
 	unsigned int dest;
 
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
+	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
 	cfg = desc->chip_data;
@@ -3543,7 +3608,7 @@ int arch_setup_dmar_msi(unsigned int irq
 	int ret;
 	struct msi_msg msg;
 
-	ret = msi_compose_msg(NULL, irq, &msg);
+	ret = msi_compose_msg(NULL, irq, &msg, -1);
 	if (ret < 0)
 		return ret;
 	dmar_msi_write(irq, &msg);
@@ -3563,8 +3628,7 @@ static int hpet_msi_set_affinity(unsigne
 	struct msi_msg msg;
 	unsigned int dest;
 
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
+	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
 	cfg = desc->chip_data;
@@ -3583,6 +3647,19 @@ static int hpet_msi_set_affinity(unsigne
 
 #endif /* CONFIG_SMP */
 
+static struct irq_chip ir_hpet_msi_type = {
+	.name = "IR-HPET_MSI",
+	.unmask = hpet_msi_unmask,
+	.mask = hpet_msi_mask,
+#ifdef CONFIG_INTR_REMAP
+	.ack = ir_ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity = ir_set_msi_irq_affinity,
+#endif
+#endif
+	.retrigger = ioapic_retrigger_irq,
+};
+
 static struct irq_chip hpet_msi_type = {
 	.name = "HPET_MSI",
 	.unmask = hpet_msi_unmask,
@@ -3594,20 +3671,36 @@ static struct irq_chip hpet_msi_type = {
 	.retrigger = ioapic_retrigger_irq,
 };
 
-int arch_setup_hpet_msi(unsigned int irq)
+int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
 	int ret;
 	struct msi_msg msg;
 	struct irq_desc *desc = irq_to_desc(irq);
 
-	ret = msi_compose_msg(NULL, irq, &msg);
+	if (intr_remapping_enabled) {
+		struct intel_iommu *iommu = map_hpet_to_ir(id);
+		int index;
+
+		if (!iommu)
+			return -1;
+
+		index = alloc_irte(iommu, irq, 1);
+		if (index < 0)
+			return -1;
+	}
+
+	ret = msi_compose_msg(NULL, irq, &msg, id);
 	if (ret < 0)
 		return ret;
 
 	hpet_msi_write(irq, &msg);
 	desc->status |= IRQ_MOVE_PCNTXT;
-	set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
-		"edge");
+	if (irq_remapped(irq))
+		set_irq_chip_and_handler_name(irq, &ir_hpet_msi_type,
+					      handle_edge_irq, "edge");
+	else
+		set_irq_chip_and_handler_name(irq, &hpet_msi_type,
+					      handle_edge_irq, "edge");
 
 	return 0;
 }
@@ -3641,8 +3734,7 @@ static int set_ht_irq_affinity(unsigned
 	struct irq_cfg *cfg;
 	unsigned int dest;
 
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
+	if (set_desc_affinity(desc, mask, &dest))
 		return -1;
 
 	cfg = desc->chip_data;
@@ -3708,75 +3800,6 @@ int arch_setup_ht_irq(unsigned int irq,
 }
 #endif /* CONFIG_HT_IRQ */
 
-#ifdef CONFIG_X86_UV
-/*
- * Re-target the irq to the specified CPU and enable the specified MMR located
- * on the specified blade to allow the sending of MSIs to the specified CPU.
- */
-int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
-		       unsigned long mmr_offset)
-{
-	const struct cpumask *eligible_cpu = cpumask_of(cpu);
-	struct irq_cfg *cfg;
-	int mmr_pnode;
-	unsigned long mmr_value;
-	struct uv_IO_APIC_route_entry *entry;
-	unsigned long flags;
-	int err;
-
-	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-	cfg = irq_cfg(irq);
-
-	err = assign_irq_vector(irq, cfg, eligible_cpu);
-	if (err != 0)
-		return err;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
-				      irq_name);
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	mmr_value = 0;
-	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-	entry->vector		= cfg->vector;
-	entry->delivery_mode	= apic->irq_delivery_mode;
-	entry->dest_mode	= apic->irq_dest_mode;
-	entry->polarity		= 0;
-	entry->trigger		= 0;
-	entry->mask		= 0;
-	entry->dest		= apic->cpu_mask_to_apicid(eligible_cpu);
-
-	mmr_pnode = uv_blade_to_pnode(mmr_blade);
-	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
-
-	if (cfg->move_in_progress)
-		send_cleanup_vector(cfg);
-
-	return irq;
-}
-
-/*
- * Disable the specified MMR located on the specified blade so that MSIs are
- * longer allowed to be sent.
- */
-void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
-{
-	unsigned long mmr_value;
-	struct uv_IO_APIC_route_entry *entry;
-	int mmr_pnode;
-
-	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-	mmr_value = 0;
-	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-	entry->mask = 1;
-
-	mmr_pnode = uv_blade_to_pnode(mmr_blade);
-	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
-}
-#endif /* CONFIG_X86_64 */
-
 int __init io_apic_get_redir_entries (int ioapic)
 {
 	union IO_APIC_reg_01	reg_01;
@@ -3944,7 +3967,7 @@ int __init io_apic_get_unique_id(int ioa
 	 */
 
 	if (physids_empty(apic_id_map))
-		apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map);
+		apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map);
 
 	spin_lock_irqsave(&ioapic_lock, flags);
 	reg_00.raw = io_apic_read(ioapic, 0);
@@ -3960,10 +3983,10 @@ int __init io_apic_get_unique_id(int ioa
 	 * Every APIC in a system must have a unique ID or we get lots of nice
 	 * 'stuck on smp_invalidate_needed IPI wait' messages.
 	 */
-	if (apic->check_apicid_used(apic_id_map, apic_id)) {
+	if (apic->check_apicid_used(&apic_id_map, apic_id)) {
 
 		for (i = 0; i < get_physical_broadcast(); i++) {
-			if (!apic->check_apicid_used(apic_id_map, i))
+			if (!apic->check_apicid_used(&apic_id_map, i))
 				break;
 		}
 
@@ -3976,7 +3999,7 @@ int __init io_apic_get_unique_id(int ioa
 		apic_id = i;
 	}
 
-	tmp = apic->apicid_to_cpu_present(apic_id);
+	apic->apicid_to_cpu_present(apic_id, &tmp);
 	physids_or(apic_id_map, apic_id_map, tmp);
 
 	if (reg_00.bits.ID != apic_id) {
@@ -4106,7 +4129,7 @@ static struct resource * __init ioapic_s
 	for (i = 0; i < nr_ioapics; i++) {
 		res[i].name = mem;
 		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		sprintf(mem,  "IOAPIC %u", i);
+		snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
 		mem += IOAPIC_RESOURCE_NAME_SIZE;
 	}
 
@@ -4140,18 +4163,17 @@ void __init ioapic_init_mappings(void)
 #ifdef CONFIG_X86_32
 fake_ioapic_page:
 #endif
-			ioapic_phys = (unsigned long)
-				alloc_bootmem_pages(PAGE_SIZE);
+			ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
 			ioapic_phys = __pa(ioapic_phys);
 		}
 		set_fixmap_nocache(idx, ioapic_phys);
-		apic_printk(APIC_VERBOSE,
-			    "mapped IOAPIC to %08lx (%08lx)\n",
-			    __fix_to_virt(idx), ioapic_phys);
+		apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
+			__fix_to_virt(idx) + (ioapic_phys & ~PAGE_MASK),
+			ioapic_phys);
 		idx++;
 
 		ioapic_res->start = ioapic_phys;
-		ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
+		ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1;
 		ioapic_res++;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/Makefile linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
 # Makefile for local APIC drivers and for the IO-APIC code
 #
 
-obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o probe_$(BITS).o ipi.o nmi.o
+obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o apic_noop.o probe_$(BITS).o ipi.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_SMP)		+= ipi.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/nmi.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/nmi.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/nmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/nmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,8 @@
 int unknown_nmi_panic;
 int nmi_watchdog_enabled;
 
-static cpumask_t backtrace_mask __read_mostly;
+/* For reliability, we're prepared to waste bits here. */
+static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
 
 /* nmi_active:
  * >0: the lapic NMI watchdog is active, but can be disabled
@@ -360,7 +361,7 @@ void stop_apic_nmi_watchdog(void *unused
  */
 
 static DEFINE_PER_CPU(unsigned, last_irq_sum);
-static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(long, alert_counter);
 static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog(void)
@@ -414,7 +415,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
 	}
 
 	/* We can be called before check_nmi_watchdog, hence NULL check. */
-	if (cpumask_test_cpu(cpu, &backtrace_mask)) {
+	if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
 		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */
 
 		spin_lock(&lock);
@@ -422,7 +423,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
 		show_regs(regs);
 		dump_stack();
 		spin_unlock(&lock);
-		cpumask_clear_cpu(cpu, &backtrace_mask);
+		cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
 
 		rc = 1;
 	}
@@ -437,8 +438,8 @@ nmi_watchdog_tick(struct pt_regs *regs,
 		 * Ayiee, looks like this CPU is stuck ...
 		 * wait a few IRQs (5 seconds) before doing the oops ...
 		 */
-		local_inc(&__get_cpu_var(alert_counter));
-		if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz)
+		__this_cpu_inc(per_cpu_var(alert_counter));
+		if (__this_cpu_read(per_cpu_var(alert_counter)) == 5 * nmi_hz)
 			/*
 			 * die_nmi will return ONLY if NOTIFY_STOP happens..
 			 */
@@ -446,7 +447,7 @@ nmi_watchdog_tick(struct pt_regs *regs,
 				regs, panic_on_timeout);
 	} else {
 		__get_cpu_var(last_irq_sum) = sum;
-		local_set(&__get_cpu_var(alert_counter), 0);
+		__this_cpu_write(per_cpu_var(alert_counter), 0);
 	}
 
 	/* see if the nmi watchdog went off */
@@ -558,14 +559,14 @@ void arch_trigger_all_cpu_backtrace(void
 {
 	int i;
 
-	cpumask_copy(&backtrace_mask, cpu_online_mask);
+	cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask);
 
 	printk(KERN_INFO "sending NMI to all CPUs:\n");
 	apic->send_IPI_all(NMI_VECTOR);
 
 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
 	for (i = 0; i < 10 * 1000; i++) {
-		if (cpumask_empty(&backtrace_mask))
+		if (cpumask_empty(to_cpumask(backtrace_mask)))
 			break;
 		mdelay(1);
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/numaq_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/numaq_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/numaq_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/numaq_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -264,11 +264,6 @@ static void __init smp_read_mpc_oem(stru
 static __init void early_check_numaq(void)
 {
 	/*
-	 * Find possible boot-time SMP configuration:
-	 */
-	early_find_smp_config();
-
-	/*
 	 * get boot-time SMP configuration:
 	 */
 	if (smp_found_config)
@@ -334,10 +329,9 @@ static inline const struct cpumask *numa
 	return cpu_all_mask;
 }
 
-static inline unsigned long
-numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
 {
-	return physid_isset(apicid, bitmap);
+	return physid_isset(apicid, *map);
 }
 
 static inline unsigned long numaq_check_apicid_present(int bit)
@@ -371,10 +365,10 @@ static inline int numaq_multi_timer_chec
 	return apic != 0 && irq == 0;
 }
 
-static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
+static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
 {
 	/* We don't have a good way to do this yet - hack */
-	return physids_promote(0xFUL);
+	return physids_promote(0xFUL, retmap);
 }
 
 static inline int numaq_cpu_to_logical_apicid(int cpu)
@@ -402,12 +396,12 @@ static inline int numaq_apicid_to_node(i
 	return logical_apicid >> 4;
 }
 
-static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
+static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
 {
 	int node = numaq_apicid_to_node(logical_apicid);
 	int cpu = __ffs(logical_apicid & 0xf);
 
-	return physid_mask_of_physid(cpu + 4*node);
+	physid_set_mask_of_physid(cpu + 4*node, retmap);
 }
 
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/probe_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/probe_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/probe_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/probe_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,32 @@ static int __init print_ipi_mode(void)
 }
 late_initcall(print_ipi_mode);
 
-void default_setup_apic_routing(void)
+void __init default_setup_apic_routing(void)
+{
+	int version = apic_version[boot_cpu_physical_apicid];
+
+	if (num_possible_cpus() > 8) {
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_INTEL:
+			if (!APIC_XAPIC(version)) {
+				def_to_bigsmp = 0;
+				break;
+			}
+			/* If P4 and above fall through */
+		case X86_VENDOR_AMD:
+			def_to_bigsmp = 1;
+		}
+	}
+
+#ifdef CONFIG_X86_BIGSMP
+	generic_bigsmp_probe();
+#endif
+
+	if (apic->setup_apic_routing)
+		apic->setup_apic_routing();
+}
+
+static void setup_apic_flat_routing(void)
 {
 #ifdef CONFIG_X86_IO_APIC
 	printk(KERN_INFO
@@ -103,12 +128,12 @@ struct apic apic_default = {
 	.init_apic_ldr			= default_init_apic_ldr,
 
 	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
-	.setup_apic_routing		= default_setup_apic_routing,
+	.setup_apic_routing		= setup_apic_flat_routing,
 	.multi_timer_check		= NULL,
 	.apicid_to_node			= default_apicid_to_node,
 	.cpu_to_logical_apicid		= default_cpu_to_logical_apicid,
 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
-	.apicid_to_cpu_present		= default_apicid_to_cpu_present,
+	.apicid_to_cpu_present		= physid_set_mask_of_physid,
 	.setup_portio_remap		= NULL,
 	.check_phys_apicid_present	= default_check_phys_apicid_present,
 	.enable_apic_mode		= NULL,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/probe_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/probe_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/probe_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/probe_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,17 +67,8 @@ void __init default_setup_apic_routing(v
 	}
 #endif
 
-	if (apic == &apic_flat) {
-		switch (boot_cpu_data.x86_vendor) {
-		case X86_VENDOR_INTEL:
-			if (num_processors > 8)
-				apic = &apic_physflat;
-			break;
-		case X86_VENDOR_AMD:
-			if (max_physical_apicid >= 8)
-				apic = &apic_physflat;
-		}
-	}
+	if (apic == &apic_flat && num_possible_cpus() > 8)
+			apic = &apic_physflat;
 
 	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/summit_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/summit_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/summit_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/summit_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -183,7 +183,7 @@ static const struct cpumask *summit_targ
 	return cpumask_of(0);
 }
 
-static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long summit_check_apicid_used(physid_mask_t *map, int apicid)
 {
 	return 0;
 }
@@ -261,15 +261,15 @@ static int summit_cpu_present_to_apicid(
 		return BAD_APICID;
 }
 
-static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
+static void summit_ioapic_phys_id_map(physid_mask_t *phys_id_map, physid_mask_t *retmap)
 {
 	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0x0F);
+	physids_promote(0x0FL, retmap);
 }
 
-static physid_mask_t summit_apicid_to_cpu_present(int apicid)
+static void summit_apicid_to_cpu_present(int apicid, physid_mask_t *retmap)
 {
-	return physid_mask_of_physid(0);
+	physid_set_mask_of_physid(0, retmap);
 }
 
 static int summit_check_phys_apicid_present(int physical_apicid)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_cluster.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_cluster.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_cluster.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_cluster.c	2010-02-24 13:52:17.000000000 -0500
@@ -148,10 +148,7 @@ x2apic_cpu_mask_to_apicid_and(const stru
 			break;
 	}
 
-	if (cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_logical_apicid, cpu);
-
-	return BAD_APICID;
+	return per_cpu(x86_cpu_to_logical_apicid, cpu);
 }
 
 static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_phys.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_phys.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_phys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_phys.c	2010-02-24 13:52:17.000000000 -0500
@@ -146,10 +146,7 @@ x2apic_cpu_mask_to_apicid_and(const stru
 			break;
 	}
 
-	if (cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-
-	return BAD_APICID;
+	return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_phys_get_apic_id(unsigned long x)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,10 +30,24 @@
 #include <asm/apic.h>
 #include <asm/ipi.h>
 #include <asm/smp.h>
+#include <asm/x86_init.h>
 
 DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
+static u64 gru_start_paddr, gru_end_paddr;
+int uv_min_hub_revision_id;
+EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
+
+static inline bool is_GRU_range(u64 start, u64 end)
+{
+	return start >= gru_start_paddr && end <= gru_end_paddr;
+}
+
+static bool uv_is_untracked_pat_range(u64 start, u64 end)
+{
+	return is_ISA_range(start, end) || is_GRU_range(start, end);
+}
 
 static int early_get_nodeid(void)
 {
@@ -43,19 +57,27 @@ static int early_get_nodeid(void)
 	mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_NODE_ID, sizeof(*mmr));
 	node_id.v = *mmr;
 	early_iounmap(mmr, sizeof(*mmr));
+
+	/* Currently, all blades have same revision number */
+	uv_min_hub_revision_id = node_id.s.revision;
+
 	return node_id.s.node_id;
 }
 
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
+	int nodeid;
+
 	if (!strcmp(oem_id, "SGI")) {
+		nodeid = early_get_nodeid();
+		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
 		if (!strcmp(oem_table_id, "UVL"))
 			uv_system_type = UV_LEGACY_APIC;
 		else if (!strcmp(oem_table_id, "UVX"))
 			uv_system_type = UV_X2APIC;
 		else if (!strcmp(oem_table_id, "UVH")) {
 			__get_cpu_var(x2apic_extra_bits) =
-				early_get_nodeid() << (UV_APIC_PNODE_SHIFT - 1);
+				nodeid << (UV_APIC_PNODE_SHIFT - 1);
 			uv_system_type = UV_NON_UNIQUE_APIC;
 			return 1;
 		}
@@ -212,10 +234,7 @@ uv_cpu_mask_to_apicid_and(const struct c
 		if (cpumask_test_cpu(cpu, cpu_online_mask))
 			break;
 	}
-	if (cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-
-	return BAD_APICID;
+	return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_get_apic_id(unsigned long x)
@@ -364,13 +383,13 @@ static __init void get_lowmem_redirect(u
 
 enum map_type {map_wb, map_uc};
 
-static __init void map_high(char *id, unsigned long base, int shift,
-			    int max_pnode, enum map_type map_type)
+static __init void map_high(char *id, unsigned long base, int pshift,
+			int bshift, int max_pnode, enum map_type map_type)
 {
 	unsigned long bytes, paddr;
 
-	paddr = base << shift;
-	bytes = (1UL << shift) * (max_pnode + 1);
+	paddr = base << pshift;
+	bytes = (1UL << bshift) * (max_pnode + 1);
 	printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
 						paddr + bytes);
 	if (map_type == map_uc)
@@ -385,8 +404,12 @@ static __init void map_gru_high(int max_
 	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, max_pnode, map_wb);
+	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);
+
+	}
 }
 
 static __init void map_mmr_high(int max_pnode)
@@ -396,7 +419,7 @@ static __init void map_mmr_high(int max_
 
 	mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR);
 	if (mmr.s.enable)
-		map_high("MMR", mmr.s.base, shift, max_pnode, map_uc);
+		map_high("MMR", mmr.s.base, shift, shift, max_pnode, map_uc);
 }
 
 static __init void map_mmioh_high(int max_pnode)
@@ -406,7 +429,14 @@ static __init void map_mmioh_high(int ma
 
 	mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
 	if (mmioh.s.enable)
-		map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc);
+		map_high("MMIOH", mmioh.s.base, shift, mmioh.s.m_io,
+			max_pnode, map_uc);
+}
+
+static __init void map_low_mmrs(void)
+{
+	init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
+	init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);
 }
 
 static __init void uv_rtc_init(void)
@@ -550,6 +580,8 @@ void __init uv_system_init(void)
 	unsigned long mmr_base, present, paddr;
 	unsigned short pnode_mask;
 
+	map_low_mmrs();
+
 	m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
 	m_val = m_n_config.s.m_skt;
 	n_val = m_n_config.s.n_skt;
@@ -607,8 +639,10 @@ void __init uv_system_init(void)
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
+		int apicid = per_cpu(x86_cpu_to_apicid, cpu);
+
 		nid = cpu_to_node(cpu);
-		pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
+		pnode = uv_apicid_to_pnode(apicid);
 		blade = boot_pnode_to_blade(pnode);
 		lcpu = uv_blade_info[blade].nr_possible_cpus;
 		uv_blade_info[blade].nr_possible_cpus++;
@@ -629,15 +663,13 @@ void __init uv_system_init(void)
 		uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
 		uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
-		uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
+		uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
 		max_pnode = max(pnode, max_pnode);
 
-		printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, "
-			"lcpu %d, blade %d\n",
-			cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid,
-			lcpu, blade);
+		printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
+			cpu, apicid, pnode, nid, lcpu, blade);
 	}
 
 	/* Add blade/pnode info for nodes without cpus */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/apm_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/apm_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/apm_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/apm_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,6 @@
 #include <linux/module.h>
 
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/timer.h>
@@ -403,6 +402,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *user_list;
 static DEFINE_SPINLOCK(user_list_lock);
+static DEFINE_MUTEX(apm_mutex);
 
 /*
  * Set up a segment that references the real mode segment 0x40
@@ -1531,7 +1531,7 @@ static long do_ioctl(struct file *filp,
 		return -EPERM;
 	switch (cmd) {
 	case APM_IOC_STANDBY:
-		lock_kernel();
+		mutex_lock(&apm_mutex);
 		if (as->standbys_read > 0) {
 			as->standbys_read--;
 			as->standbys_pending--;
@@ -1540,10 +1540,10 @@ static long do_ioctl(struct file *filp,
 			queue_event(APM_USER_STANDBY, as);
 		if (standbys_pending <= 0)
 			standby();
-		unlock_kernel();
+		mutex_unlock(&apm_mutex);
 		break;
 	case APM_IOC_SUSPEND:
-		lock_kernel();
+		mutex_lock(&apm_mutex);
 		if (as->suspends_read > 0) {
 			as->suspends_read--;
 			as->suspends_pending--;
@@ -1552,13 +1552,14 @@ static long do_ioctl(struct file *filp,
 			queue_event(APM_USER_SUSPEND, as);
 		if (suspends_pending <= 0) {
 			ret = suspend(1);
+			mutex_unlock(&apm_mutex);
 		} else {
 			as->suspend_wait = 1;
+			mutex_unlock(&apm_mutex);
 			wait_event_interruptible(apm_suspend_waitqueue,
 					as->suspend_wait == 0);
 			ret = as->suspend_result;
 		}
-		unlock_kernel();
 		return ret;
 	default:
 		return -ENOTTY;
@@ -1608,12 +1609,10 @@ static int do_open(struct inode *inode,
 {
 	struct apm_user *as;
 
-	lock_kernel();
 	as = kmalloc(sizeof(*as), GFP_KERNEL);
 	if (as == NULL) {
 		printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
 		       sizeof(*as));
-		       unlock_kernel();
 		return -ENOMEM;
 	}
 	as->magic = APM_BIOS_MAGIC;
@@ -1635,7 +1634,6 @@ static int do_open(struct inode *inode,
 	user_list = as;
 	spin_unlock(&user_list_lock);
 	filp->private_data = as;
-	unlock_kernel();
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/bios_uv.c linux-libre-2.6.33-gnu1/arch/x86/kernel/bios_uv.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/bios_uv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/bios_uv.c	2010-02-24 13:52:17.000000000 -0500
@@ -101,21 +101,17 @@ s64 uv_bios_get_sn_info(int fc, int *uvt
 }
 
 int
-uv_bios_mq_watchlist_alloc(int blade, unsigned long addr, unsigned int mq_size,
+uv_bios_mq_watchlist_alloc(unsigned long addr, unsigned int mq_size,
 			   unsigned long *intr_mmr_offset)
 {
-	union uv_watchlist_u size_blade;
 	u64 watchlist;
 	s64 ret;
 
-	size_blade.size = mq_size;
-	size_blade.blade = blade;
-
 	/*
 	 * bios returns watchlist number or negative error number.
 	 */
 	ret = (int)uv_bios_call_irqsave(UV_BIOS_WATCHLIST_ALLOC, addr,
-			size_blade.val, (u64)intr_mmr_offset,
+			mq_size, (u64)intr_mmr_offset,
 			(u64)&watchlist, 0);
 	if (ret < BIOS_STATUS_SUCCESS)
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,7 @@ void __cpuinit detect_extended_topology(
 	unsigned int eax, ebx, ecx, edx, sub_index;
 	unsigned int ht_mask_width, core_plus_mask_width;
 	unsigned int core_select_mask, core_level_siblings;
+	static bool printed;
 
 	if (c->cpuid_level < 0xb)
 		return;
@@ -127,12 +128,14 @@ void __cpuinit detect_extended_topology(
 
 	c->x86_max_cores = (core_level_siblings / smp_num_siblings);
 
-
-	printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-	       c->phys_proc_id);
-	if (c->x86_max_cores > 1)
-		printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
-		       c->cpu_core_id);
+	if (!printed) {
+		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
+		       c->phys_proc_id);
+		if (c->x86_max_cores > 1)
+			printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
+			       c->cpu_core_id);
+		printed = 1;
+	}
 	return;
 #endif
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/amd.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/amd.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/amd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/amd.c	2010-02-24 13:52:17.000000000 -0500
@@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int api
 
 /*
  * Fixup core topology information for AMD multi-node processors.
- * Assumption 1: Number of cores in each internal node is the same.
- * Assumption 2: Mixed systems with both single-node and dual-node
- *               processors are not supported.
+ * Assumption: Number of cores in each internal node is the same.
  */
 #ifdef CONFIG_X86_HT
 static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_PCI
-	u32 t, cpn;
-	u8 n, n_id;
+	unsigned long long value;
+	u32 nodes, cores_per_node;
 	int cpu = smp_processor_id();
 
+	if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
+		return;
+
 	/* fixup topology information only once for a core */
 	if (cpu_has(c, X86_FEATURE_AMD_DCM))
 		return;
 
-	/* check for multi-node processor on boot cpu */
-	t = read_pci_config(0, 24, 3, 0xe8);
-	if (!(t & (1 << 29)))
+	rdmsrl(MSR_FAM10H_NODE_ID, value);
+
+	nodes = ((value >> 3) & 7) + 1;
+	if (nodes == 1)
 		return;
 
 	set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+	cores_per_node = c->x86_max_cores / nodes;
 
-	/* cores per node: each internal node has half the number of cores */
-	cpn = c->x86_max_cores >> 1;
-
-	/* even-numbered NB_id of this dual-node processor */
-	n = c->phys_proc_id << 1;
-
-	/*
-	 * determine internal node id and assign cores fifty-fifty to
-	 * each node of the dual-node processor
-	 */
-	t = read_pci_config(0, 24 + n, 3, 0xe8);
-	n = (t>>30) & 0x3;
-	if (n == 0) {
-		if (c->cpu_core_id < cpn)
-			n_id = 0;
-		else
-			n_id = 1;
-	} else {
-		if (c->cpu_core_id < cpn)
-			n_id = 1;
-		else
-			n_id = 0;
-	}
-
-	/* compute entire NodeID, use llc_shared_map to store sibling info */
-	per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
+	/* store NodeID, use llc_shared_map to store sibling info */
+	per_cpu(cpu_llc_id, cpu) = value & 7;
 
-	/* fixup core id to be in range from 0 to cpn */
-	c->cpu_core_id = c->cpu_core_id % cpn;
-#endif
+	/* fixup core id to be in range from 0 to (cores_per_node - 1) */
+	c->cpu_core_id = c->cpu_core_id % cores_per_node;
 }
 #endif
 
@@ -375,8 +352,6 @@ static void __cpuinit srat_detect_node(s
 			node = nearby_node(apicid);
 	}
 	numa_set_node(cpu, node);
-
-	printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
 #endif
 }
 
@@ -535,7 +510,7 @@ static void __cpuinit init_amd(struct cp
 		}
 	}
 
-	display_cacheinfo(c);
+	cpu_detect_cache_sizes(c);
 
 	/* Multi core CPU? */
 	if (c->extended_cpuid_level >= 0x80000008) {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/centaur.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/centaur.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/centaur.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/centaur.c	2010-02-24 13:52:17.000000000 -0500
@@ -294,7 +294,7 @@ static void __cpuinit init_c3(struct cpu
 		set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 	}
 
-	display_cacheinfo(c);
+	cpu_detect_cache_sizes(c);
 }
 
 enum {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/common.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/common.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ void __init setup_cpu_local_masks(void)
 static void __cpuinit default_init(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_64
-	display_cacheinfo(c);
+	cpu_detect_cache_sizes(c);
 #else
 	/* Not much we can do here... */
 	/* Check if at least it has cpuid */
@@ -383,7 +383,7 @@ static void __cpuinit get_model_name(str
 	}
 }
 
-void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
+void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
 {
 	unsigned int n, dummy, ebx, ecx, edx, l2size;
 
@@ -391,8 +391,6 @@ void __cpuinit display_cacheinfo(struct
 
 	if (n >= 0x80000005) {
 		cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
-		printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
-				edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
 		c->x86_cache_size = (ecx>>24) + (edx>>24);
 #ifdef CONFIG_X86_64
 		/* On K8 L1 TLB is inclusive, so don't count it */
@@ -422,9 +420,6 @@ void __cpuinit display_cacheinfo(struct
 #endif
 
 	c->x86_cache_size = l2size;
-
-	printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
-			l2size, ecx & 0xFF);
 }
 
 void __cpuinit detect_ht(struct cpuinfo_x86 *c)
@@ -432,6 +427,7 @@ void __cpuinit detect_ht(struct cpuinfo_
 #ifdef CONFIG_X86_HT
 	u32 eax, ebx, ecx, edx;
 	int index_msb, core_bits;
+	static bool printed;
 
 	if (!cpu_has(c, X86_FEATURE_HT))
 		return;
@@ -447,7 +443,7 @@ void __cpuinit detect_ht(struct cpuinfo_
 	smp_num_siblings = (ebx & 0xff0000) >> 16;
 
 	if (smp_num_siblings == 1) {
-		printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
+		printk_once(KERN_INFO "CPU0: Hyper-Threading is disabled\n");
 		goto out;
 	}
 
@@ -474,11 +470,12 @@ void __cpuinit detect_ht(struct cpuinfo_
 				       ((1 << core_bits) - 1);
 
 out:
-	if ((c->x86_max_cores * smp_num_siblings) > 1) {
+	if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) {
 		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
 		       c->phys_proc_id);
 		printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
 		       c->cpu_core_id);
+		printed = 1;
 	}
 #endif
 }
@@ -659,24 +656,31 @@ void __init early_cpu_init(void)
 	const struct cpu_dev *const *cdev;
 	int count = 0;
 
+#ifdef PROCESSOR_SELECT
 	printk(KERN_INFO "KERNEL supported cpus:\n");
+#endif
+
 	for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
 		const struct cpu_dev *cpudev = *cdev;
-		unsigned int j;
 
 		if (count >= X86_VENDOR_NUM)
 			break;
 		cpu_devs[count] = cpudev;
 		count++;
 
-		for (j = 0; j < 2; j++) {
-			if (!cpudev->c_ident[j])
-				continue;
-			printk(KERN_INFO "  %s %s\n", cpudev->c_vendor,
-				cpudev->c_ident[j]);
+#ifdef PROCESSOR_SELECT
+		{
+			unsigned int j;
+
+			for (j = 0; j < 2; j++) {
+				if (!cpudev->c_ident[j])
+					continue;
+				printk(KERN_INFO "  %s %s\n", cpudev->c_vendor,
+					cpudev->c_ident[j]);
+			}
 		}
+#endif
 	}
-
 	early_identify_cpu(&boot_cpu_data);
 }
 
@@ -837,10 +841,8 @@ static void __cpuinit identify_cpu(struc
 			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
 	}
 
-#ifdef CONFIG_X86_MCE
 	/* Init Machine Check Exception if available. */
-	mcheck_init(c);
-#endif
+	mcheck_cpu_init(c);
 
 	select_idle_routine(c);
 
@@ -1093,7 +1095,7 @@ static void clear_all_debug_regs(void)
 
 void __cpuinit cpu_init(void)
 {
-	struct orig_ist *orig_ist;
+	struct orig_ist *oist;
 	struct task_struct *me;
 	struct tss_struct *t;
 	unsigned long v;
@@ -1102,7 +1104,7 @@ void __cpuinit cpu_init(void)
 
 	cpu = stack_smp_processor_id();
 	t = &per_cpu(init_tss, cpu);
-	orig_ist = &per_cpu(orig_ist, cpu);
+	oist = &per_cpu(orig_ist, cpu);
 
 #ifdef CONFIG_NUMA
 	if (cpu != 0 && percpu_read(node_number) == 0 &&
@@ -1115,7 +1117,7 @@ void __cpuinit cpu_init(void)
 	if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
 		panic("CPU#%d already initialized!\n", cpu);
 
-	printk(KERN_INFO "Initializing CPU#%d\n", cpu);
+	pr_debug("Initializing CPU#%d\n", cpu);
 
 	clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
@@ -1136,19 +1138,19 @@ void __cpuinit cpu_init(void)
 	wrmsrl(MSR_KERNEL_GS_BASE, 0);
 	barrier();
 
-	check_efer();
+	x86_configure_nx();
 	if (cpu != 0)
 		enable_x2apic();
 
 	/*
 	 * set up and load the per-CPU TSS
 	 */
-	if (!orig_ist->ist[0]) {
+	if (!oist->ist[0]) {
 		char *estacks = per_cpu(exception_stacks, cpu);
 
 		for (v = 0; v < N_EXCEPTION_STACKS; v++) {
 			estacks += exception_stack_sizes[v];
-			orig_ist->ist[v] = t->x86_tss.ist[v] =
+			oist->ist[v] = t->x86_tss.ist[v] =
 					(unsigned long)estacks;
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpu_debug.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpu_debug.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpu_debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpu_debug.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,688 +0,0 @@
-/*
- * CPU x86 architecture debug code
- *
- * Copyright(C) 2009 Jaswinder Singh Rajput
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/kprobes.h>
-#include <linux/uaccess.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/percpu.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-
-#include <asm/cpu_debug.h>
-#include <asm/paravirt.h>
-#include <asm/system.h>
-#include <asm/traps.h>
-#include <asm/apic.h>
-#include <asm/desc.h>
-
-static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpu_arr);
-static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], priv_arr);
-static DEFINE_PER_CPU(int, cpu_priv_count);
-
-static DEFINE_MUTEX(cpu_debug_lock);
-
-static struct dentry *cpu_debugfs_dir;
-
-static struct cpu_debug_base cpu_base[] = {
-	{ "mc",		CPU_MC,		0	},
-	{ "monitor",	CPU_MONITOR,	0	},
-	{ "time",	CPU_TIME,	0	},
-	{ "pmc",	CPU_PMC,	1	},
-	{ "platform",	CPU_PLATFORM,	0	},
-	{ "apic",	CPU_APIC,	0	},
-	{ "poweron",	CPU_POWERON,	0	},
-	{ "control",	CPU_CONTROL,	0	},
-	{ "features",	CPU_FEATURES,	0	},
-	{ "lastbranch",	CPU_LBRANCH,	0	},
-	{ "bios",	CPU_BIOS,	0	},
-	{ "freq",	CPU_FREQ,	0	},
-	{ "mtrr",	CPU_MTRR,	0	},
-	{ "perf",	CPU_PERF,	0	},
-	{ "cache",	CPU_CACHE,	0	},
-	{ "sysenter",	CPU_SYSENTER,	0	},
-	{ "therm",	CPU_THERM,	0	},
-	{ "misc",	CPU_MISC,	0	},
-	{ "debug",	CPU_DEBUG,	0	},
-	{ "pat",	CPU_PAT,	0	},
-	{ "vmx",	CPU_VMX,	0	},
-	{ "call",	CPU_CALL,	0	},
-	{ "base",	CPU_BASE,	0	},
-	{ "ver",	CPU_VER,	0	},
-	{ "conf",	CPU_CONF,	0	},
-	{ "smm",	CPU_SMM,	0	},
-	{ "svm",	CPU_SVM,	0	},
-	{ "osvm",	CPU_OSVM,	0	},
-	{ "tss",	CPU_TSS,	0	},
-	{ "cr",		CPU_CR,		0	},
-	{ "dt",		CPU_DT,		0	},
-	{ "registers",	CPU_REG_ALL,	0	},
-};
-
-static struct cpu_file_base cpu_file[] = {
-	{ "index",	CPU_REG_ALL,	0	},
-	{ "value",	CPU_REG_ALL,	1	},
-};
-
-/* CPU Registers Range */
-static struct cpu_debug_range cpu_reg_range[] = {
-	{ 0x00000000, 0x00000001, CPU_MC,	},
-	{ 0x00000006, 0x00000007, CPU_MONITOR,	},
-	{ 0x00000010, 0x00000010, CPU_TIME,	},
-	{ 0x00000011, 0x00000013, CPU_PMC,	},
-	{ 0x00000017, 0x00000017, CPU_PLATFORM,	},
-	{ 0x0000001B, 0x0000001B, CPU_APIC,	},
-	{ 0x0000002A, 0x0000002B, CPU_POWERON,	},
-	{ 0x0000002C, 0x0000002C, CPU_FREQ,	},
-	{ 0x0000003A, 0x0000003A, CPU_CONTROL,	},
-	{ 0x00000040, 0x00000047, CPU_LBRANCH,	},
-	{ 0x00000060, 0x00000067, CPU_LBRANCH,	},
-	{ 0x00000079, 0x00000079, CPU_BIOS,	},
-	{ 0x00000088, 0x0000008A, CPU_CACHE,	},
-	{ 0x0000008B, 0x0000008B, CPU_BIOS,	},
-	{ 0x0000009B, 0x0000009B, CPU_MONITOR,	},
-	{ 0x000000C1, 0x000000C4, CPU_PMC,	},
-	{ 0x000000CD, 0x000000CD, CPU_FREQ,	},
-	{ 0x000000E7, 0x000000E8, CPU_PERF,	},
-	{ 0x000000FE, 0x000000FE, CPU_MTRR,	},
-
-	{ 0x00000116, 0x0000011E, CPU_CACHE,	},
-	{ 0x00000174, 0x00000176, CPU_SYSENTER,	},
-	{ 0x00000179, 0x0000017B, CPU_MC,	},
-	{ 0x00000186, 0x00000189, CPU_PMC,	},
-	{ 0x00000198, 0x00000199, CPU_PERF,	},
-	{ 0x0000019A, 0x0000019A, CPU_TIME,	},
-	{ 0x0000019B, 0x0000019D, CPU_THERM,	},
-	{ 0x000001A0, 0x000001A0, CPU_MISC,	},
-	{ 0x000001C9, 0x000001C9, CPU_LBRANCH,	},
-	{ 0x000001D7, 0x000001D8, CPU_LBRANCH,	},
-	{ 0x000001D9, 0x000001D9, CPU_DEBUG,	},
-	{ 0x000001DA, 0x000001E0, CPU_LBRANCH,	},
-
-	{ 0x00000200, 0x0000020F, CPU_MTRR,	},
-	{ 0x00000250, 0x00000250, CPU_MTRR,	},
-	{ 0x00000258, 0x00000259, CPU_MTRR,	},
-	{ 0x00000268, 0x0000026F, CPU_MTRR,	},
-	{ 0x00000277, 0x00000277, CPU_PAT,	},
-	{ 0x000002FF, 0x000002FF, CPU_MTRR,	},
-
-	{ 0x00000300, 0x00000311, CPU_PMC,	},
-	{ 0x00000345, 0x00000345, CPU_PMC,	},
-	{ 0x00000360, 0x00000371, CPU_PMC,	},
-	{ 0x0000038D, 0x00000390, CPU_PMC,	},
-	{ 0x000003A0, 0x000003BE, CPU_PMC,	},
-	{ 0x000003C0, 0x000003CD, CPU_PMC,	},
-	{ 0x000003E0, 0x000003E1, CPU_PMC,	},
-	{ 0x000003F0, 0x000003F2, CPU_PMC,	},
-
-	{ 0x00000400, 0x00000417, CPU_MC,	},
-	{ 0x00000480, 0x0000048B, CPU_VMX,	},
-
-	{ 0x00000600, 0x00000600, CPU_DEBUG,	},
-	{ 0x00000680, 0x0000068F, CPU_LBRANCH,	},
-	{ 0x000006C0, 0x000006CF, CPU_LBRANCH,	},
-
-	{ 0x000107CC, 0x000107D3, CPU_PMC,	},
-
-	{ 0xC0000080, 0xC0000080, CPU_FEATURES,	},
-	{ 0xC0000081, 0xC0000084, CPU_CALL,	},
-	{ 0xC0000100, 0xC0000102, CPU_BASE,	},
-	{ 0xC0000103, 0xC0000103, CPU_TIME,	},
-
-	{ 0xC0010000, 0xC0010007, CPU_PMC,	},
-	{ 0xC0010010, 0xC0010010, CPU_CONF,	},
-	{ 0xC0010015, 0xC0010015, CPU_CONF,	},
-	{ 0xC0010016, 0xC001001A, CPU_MTRR,	},
-	{ 0xC001001D, 0xC001001D, CPU_MTRR,	},
-	{ 0xC001001F, 0xC001001F, CPU_CONF,	},
-	{ 0xC0010030, 0xC0010035, CPU_BIOS,	},
-	{ 0xC0010044, 0xC0010048, CPU_MC,	},
-	{ 0xC0010050, 0xC0010056, CPU_SMM,	},
-	{ 0xC0010058, 0xC0010058, CPU_CONF,	},
-	{ 0xC0010060, 0xC0010060, CPU_CACHE,	},
-	{ 0xC0010061, 0xC0010068, CPU_SMM,	},
-	{ 0xC0010069, 0xC001006B, CPU_SMM,	},
-	{ 0xC0010070, 0xC0010071, CPU_SMM,	},
-	{ 0xC0010111, 0xC0010113, CPU_SMM,	},
-	{ 0xC0010114, 0xC0010118, CPU_SVM,	},
-	{ 0xC0010140, 0xC0010141, CPU_OSVM,	},
-	{ 0xC0011022, 0xC0011023, CPU_CONF,	},
-};
-
-static int is_typeflag_valid(unsigned cpu, unsigned flag)
-{
-	int i;
-
-	/* Standard Registers should be always valid */
-	if (flag >= CPU_TSS)
-		return 1;
-
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (cpu_reg_range[i].flag == flag)
-			return 1;
-	}
-
-	/* Invalid */
-	return 0;
-}
-
-static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
-			      int index, unsigned flag)
-{
-	if (cpu_reg_range[index].flag == flag) {
-		*min = cpu_reg_range[index].min;
-		*max = cpu_reg_range[index].max;
-	} else
-		*max = 0;
-
-	return *max;
-}
-
-/* This function can also be called with seq = NULL for printk */
-static void print_cpu_data(struct seq_file *seq, unsigned type,
-			   u32 low, u32 high)
-{
-	struct cpu_private *priv;
-	u64 val = high;
-
-	if (seq) {
-		priv = seq->private;
-		if (priv->file) {
-			val = (val << 32) | low;
-			seq_printf(seq, "0x%llx\n", val);
-		} else
-			seq_printf(seq, " %08x: %08x_%08x\n",
-				   type, high, low);
-	} else
-		printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low);
-}
-
-/* This function can also be called with seq = NULL for printk */
-static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
-{
-	unsigned msr, msr_min, msr_max;
-	struct cpu_private *priv;
-	u32 low, high;
-	int i;
-
-	if (seq) {
-		priv = seq->private;
-		if (priv->file) {
-			if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg,
-					       &low, &high))
-				print_cpu_data(seq, priv->reg, low, high);
-			return;
-		}
-	}
-
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
-			continue;
-
-		for (msr = msr_min; msr <= msr_max; msr++) {
-			if (rdmsr_safe_on_cpu(cpu, msr, &low, &high))
-				continue;
-			print_cpu_data(seq, msr, low, high);
-		}
-	}
-}
-
-static void print_tss(void *arg)
-{
-	struct pt_regs *regs = task_pt_regs(current);
-	struct seq_file *seq = arg;
-	unsigned int seg;
-
-	seq_printf(seq, " RAX\t: %016lx\n", regs->ax);
-	seq_printf(seq, " RBX\t: %016lx\n", regs->bx);
-	seq_printf(seq, " RCX\t: %016lx\n", regs->cx);
-	seq_printf(seq, " RDX\t: %016lx\n", regs->dx);
-
-	seq_printf(seq, " RSI\t: %016lx\n", regs->si);
-	seq_printf(seq, " RDI\t: %016lx\n", regs->di);
-	seq_printf(seq, " RBP\t: %016lx\n", regs->bp);
-	seq_printf(seq, " ESP\t: %016lx\n", regs->sp);
-
-#ifdef CONFIG_X86_64
-	seq_printf(seq, " R08\t: %016lx\n", regs->r8);
-	seq_printf(seq, " R09\t: %016lx\n", regs->r9);
-	seq_printf(seq, " R10\t: %016lx\n", regs->r10);
-	seq_printf(seq, " R11\t: %016lx\n", regs->r11);
-	seq_printf(seq, " R12\t: %016lx\n", regs->r12);
-	seq_printf(seq, " R13\t: %016lx\n", regs->r13);
-	seq_printf(seq, " R14\t: %016lx\n", regs->r14);
-	seq_printf(seq, " R15\t: %016lx\n", regs->r15);
-#endif
-
-	asm("movl %%cs,%0" : "=r" (seg));
-	seq_printf(seq, " CS\t:             %04x\n", seg);
-	asm("movl %%ds,%0" : "=r" (seg));
-	seq_printf(seq, " DS\t:             %04x\n", seg);
-	seq_printf(seq, " SS\t:             %04lx\n", regs->ss & 0xffff);
-	asm("movl %%es,%0" : "=r" (seg));
-	seq_printf(seq, " ES\t:             %04x\n", seg);
-	asm("movl %%fs,%0" : "=r" (seg));
-	seq_printf(seq, " FS\t:             %04x\n", seg);
-	asm("movl %%gs,%0" : "=r" (seg));
-	seq_printf(seq, " GS\t:             %04x\n", seg);
-
-	seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags);
-
-	seq_printf(seq, " EIP\t: %016lx\n", regs->ip);
-}
-
-static void print_cr(void *arg)
-{
-	struct seq_file *seq = arg;
-
-	seq_printf(seq, " cr0\t: %016lx\n", read_cr0());
-	seq_printf(seq, " cr2\t: %016lx\n", read_cr2());
-	seq_printf(seq, " cr3\t: %016lx\n", read_cr3());
-	seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe());
-#ifdef CONFIG_X86_64
-	seq_printf(seq, " cr8\t: %016lx\n", read_cr8());
-#endif
-}
-
-static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt)
-{
-	seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size));
-}
-
-static void print_dt(void *seq)
-{
-	struct desc_ptr dt;
-	unsigned long ldt;
-
-	/* IDT */
-	store_idt((struct desc_ptr *)&dt);
-	print_desc_ptr("IDT", seq, dt);
-
-	/* GDT */
-	store_gdt((struct desc_ptr *)&dt);
-	print_desc_ptr("GDT", seq, dt);
-
-	/* LDT */
-	store_ldt(ldt);
-	seq_printf(seq, " LDT\t: %016lx\n", ldt);
-
-	/* TR */
-	store_tr(ldt);
-	seq_printf(seq, " TR\t: %016lx\n", ldt);
-}
-
-static void print_dr(void *arg)
-{
-	struct seq_file *seq = arg;
-	unsigned long dr;
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		/* Ignore db4, db5 */
-		if ((i == 4) || (i == 5))
-			continue;
-		get_debugreg(dr, i);
-		seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
-	}
-
-	seq_printf(seq, "\n MSR\t:\n");
-}
-
-static void print_apic(void *arg)
-{
-	struct seq_file *seq = arg;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-	seq_printf(seq, " LAPIC\t:\n");
-	seq_printf(seq, " ID\t\t: %08x\n",  apic_read(APIC_ID) >> 24);
-	seq_printf(seq, " LVR\t\t: %08x\n",  apic_read(APIC_LVR));
-	seq_printf(seq, " TASKPRI\t: %08x\n",  apic_read(APIC_TASKPRI));
-	seq_printf(seq, " ARBPRI\t\t: %08x\n",  apic_read(APIC_ARBPRI));
-	seq_printf(seq, " PROCPRI\t: %08x\n",  apic_read(APIC_PROCPRI));
-	seq_printf(seq, " LDR\t\t: %08x\n",  apic_read(APIC_LDR));
-	seq_printf(seq, " DFR\t\t: %08x\n",  apic_read(APIC_DFR));
-	seq_printf(seq, " SPIV\t\t: %08x\n",  apic_read(APIC_SPIV));
-	seq_printf(seq, " ISR\t\t: %08x\n",  apic_read(APIC_ISR));
-	seq_printf(seq, " ESR\t\t: %08x\n",  apic_read(APIC_ESR));
-	seq_printf(seq, " ICR\t\t: %08x\n",  apic_read(APIC_ICR));
-	seq_printf(seq, " ICR2\t\t: %08x\n",  apic_read(APIC_ICR2));
-	seq_printf(seq, " LVTT\t\t: %08x\n",  apic_read(APIC_LVTT));
-	seq_printf(seq, " LVTTHMR\t: %08x\n",  apic_read(APIC_LVTTHMR));
-	seq_printf(seq, " LVTPC\t\t: %08x\n",  apic_read(APIC_LVTPC));
-	seq_printf(seq, " LVT0\t\t: %08x\n",  apic_read(APIC_LVT0));
-	seq_printf(seq, " LVT1\t\t: %08x\n",  apic_read(APIC_LVT1));
-	seq_printf(seq, " LVTERR\t\t: %08x\n",  apic_read(APIC_LVTERR));
-	seq_printf(seq, " TMICT\t\t: %08x\n",  apic_read(APIC_TMICT));
-	seq_printf(seq, " TMCCT\t\t: %08x\n",  apic_read(APIC_TMCCT));
-	seq_printf(seq, " TDCR\t\t: %08x\n",  apic_read(APIC_TDCR));
-	if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
-		unsigned int i, v, maxeilvt;
-
-		v = apic_read(APIC_EFEAT);
-		maxeilvt = (v >> 16) & 0xff;
-		seq_printf(seq, " EFEAT\t\t: %08x\n", v);
-		seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
-
-		for (i = 0; i < maxeilvt; i++) {
-			v = apic_read(APIC_EILVTn(i));
-			seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
-		}
-	}
-#endif /* CONFIG_X86_LOCAL_APIC */
-	seq_printf(seq, "\n MSR\t:\n");
-}
-
-static int cpu_seq_show(struct seq_file *seq, void *v)
-{
-	struct cpu_private *priv = seq->private;
-
-	if (priv == NULL)
-		return -EINVAL;
-
-	switch (cpu_base[priv->type].flag) {
-	case CPU_TSS:
-		smp_call_function_single(priv->cpu, print_tss, seq, 1);
-		break;
-	case CPU_CR:
-		smp_call_function_single(priv->cpu, print_cr, seq, 1);
-		break;
-	case CPU_DT:
-		smp_call_function_single(priv->cpu, print_dt, seq, 1);
-		break;
-	case CPU_DEBUG:
-		if (priv->file == CPU_INDEX_BIT)
-			smp_call_function_single(priv->cpu, print_dr, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
-		break;
-	case CPU_APIC:
-		if (priv->file == CPU_INDEX_BIT)
-			smp_call_function_single(priv->cpu, print_apic, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
-		break;
-
-	default:
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
-		break;
-	}
-	seq_printf(seq, "\n");
-
-	return 0;
-}
-
-static void *cpu_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	if (*pos == 0) /* One time is enough ;-) */
-		return seq;
-
-	return NULL;
-}
-
-static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	(*pos)++;
-
-	return cpu_seq_start(seq, pos);
-}
-
-static void cpu_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static const struct seq_operations cpu_seq_ops = {
-	.start		= cpu_seq_start,
-	.next		= cpu_seq_next,
-	.stop		= cpu_seq_stop,
-	.show		= cpu_seq_show,
-};
-
-static int cpu_seq_open(struct inode *inode, struct file *file)
-{
-	struct cpu_private *priv = inode->i_private;
-	struct seq_file *seq;
-	int err;
-
-	err = seq_open(file, &cpu_seq_ops);
-	if (!err) {
-		seq = file->private_data;
-		seq->private = priv;
-	}
-
-	return err;
-}
-
-static int write_msr(struct cpu_private *priv, u64 val)
-{
-	u32 low, high;
-
-	high = (val >> 32) & 0xffffffff;
-	low = val & 0xffffffff;
-
-	if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high))
-		return 0;
-
-	return -EPERM;
-}
-
-static int write_cpu_register(struct cpu_private *priv, const char *buf)
-{
-	int ret = -EPERM;
-	u64 val;
-
-	ret = strict_strtoull(buf, 0, &val);
-	if (ret < 0)
-		return ret;
-
-	/* Supporting only MSRs */
-	if (priv->type < CPU_TSS_BIT)
-		return write_msr(priv, val);
-
-	return ret;
-}
-
-static ssize_t cpu_write(struct file *file, const char __user *ubuf,
-			     size_t count, loff_t *off)
-{
-	struct seq_file *seq = file->private_data;
-	struct cpu_private *priv = seq->private;
-	char buf[19];
-
-	if ((priv == NULL) || (count >= sizeof(buf)))
-		return -EINVAL;
-
-	if (copy_from_user(&buf, ubuf, count))
-		return -EFAULT;
-
-	buf[count] = 0;
-
-	if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write))
-		if (!write_cpu_register(priv, buf))
-			return count;
-
-	return -EACCES;
-}
-
-static const struct file_operations cpu_fops = {
-	.owner		= THIS_MODULE,
-	.open		= cpu_seq_open,
-	.read		= seq_read,
-	.write		= cpu_write,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
-};
-
-static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
-			   unsigned file, struct dentry *dentry)
-{
-	struct cpu_private *priv = NULL;
-
-	/* Already intialized */
-	if (file == CPU_INDEX_BIT)
-		if (per_cpu(cpu_arr[type].init, cpu))
-			return 0;
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (priv == NULL)
-		return -ENOMEM;
-
-	priv->cpu = cpu;
-	priv->type = type;
-	priv->reg = reg;
-	priv->file = file;
-	mutex_lock(&cpu_debug_lock);
-	per_cpu(priv_arr[type], cpu) = priv;
-	per_cpu(cpu_priv_count, cpu)++;
-	mutex_unlock(&cpu_debug_lock);
-
-	if (file)
-		debugfs_create_file(cpu_file[file].name, S_IRUGO,
-				    dentry, (void *)priv, &cpu_fops);
-	else {
-		debugfs_create_file(cpu_base[type].name, S_IRUGO,
-				    per_cpu(cpu_arr[type].dentry, cpu),
-				    (void *)priv, &cpu_fops);
-		mutex_lock(&cpu_debug_lock);
-		per_cpu(cpu_arr[type].init, cpu) = 1;
-		mutex_unlock(&cpu_debug_lock);
-	}
-
-	return 0;
-}
-
-static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
-			     struct dentry *dentry)
-{
-	unsigned file;
-	int err = 0;
-
-	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
-		err = cpu_create_file(cpu, type, reg, file, dentry);
-		if (err)
-			return err;
-	}
-
-	return err;
-}
-
-static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
-{
-	struct dentry *cpu_dentry = NULL;
-	unsigned reg, reg_min, reg_max;
-	int i, err = 0;
-	char reg_dir[12];
-	u32 low, high;
-
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &reg_min, &reg_max, i,
-				   cpu_base[type].flag))
-			continue;
-
-		for (reg = reg_min; reg <= reg_max; reg++) {
-			if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
-				continue;
-
-			sprintf(reg_dir, "0x%x", reg);
-			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
-			err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
-			if (err)
-				return err;
-		}
-	}
-
-	return err;
-}
-
-static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
-{
-	struct dentry *cpu_dentry = NULL;
-	unsigned type;
-	int err = 0;
-
-	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
-		if (!is_typeflag_valid(cpu, cpu_base[type].flag))
-			continue;
-		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
-		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
-
-		if (type < CPU_TSS_BIT)
-			err = cpu_init_msr(cpu, type, cpu_dentry);
-		else
-			err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
-					      cpu_dentry);
-		if (err)
-			return err;
-	}
-
-	return err;
-}
-
-static int cpu_init_cpu(void)
-{
-	struct dentry *cpu_dentry = NULL;
-	struct cpuinfo_x86 *cpui;
-	char cpu_dir[12];
-	unsigned cpu;
-	int err = 0;
-
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
-		cpui = &cpu_data(cpu);
-		if (!cpu_has(cpui, X86_FEATURE_MSR))
-			continue;
-
-		sprintf(cpu_dir, "cpu%d", cpu);
-		cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir);
-		err = cpu_init_allreg(cpu, cpu_dentry);
-
-		pr_info("cpu%d(%d) debug files %d\n",
-			cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu));
-		if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) {
-			pr_err("Register files count %d exceeds limit %d\n",
-				per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
-			per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES;
-			err = -ENFILE;
-		}
-		if (err)
-			return err;
-	}
-
-	return err;
-}
-
-static int __init cpu_debug_init(void)
-{
-	cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir);
-
-	return cpu_init_cpu();
-}
-
-static void __exit cpu_debug_exit(void)
-{
-	int i, cpu;
-
-	if (cpu_debugfs_dir)
-		debugfs_remove_recursive(cpu_debugfs_dir);
-
-	for (cpu = 0; cpu <  nr_cpu_ids; cpu++)
-		for (i = 0; i < per_cpu(cpu_priv_count, cpu); i++)
-			kfree(per_cpu(priv_arr[i], cpu));
-}
-
-module_init(cpu_debug_init);
-module_exit(cpu_debug_exit);
-
-MODULE_AUTHOR("Jaswinder Singh Rajput");
-MODULE_DESCRIPTION("CPU Debug module");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,9 +68,9 @@ struct acpi_cpufreq_data {
 	unsigned int cpu_feature;
 };
 
-static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
+static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
 
-static DEFINE_PER_CPU(struct aperfmperf, old_perf);
+static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
 
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
@@ -190,9 +190,11 @@ static void do_drv_write(void *_cmd)
 
 static void drv_read(struct drv_cmd *cmd)
 {
+	int err;
 	cmd->val = 0;
 
-	smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
+	err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1);
+	WARN_ON_ONCE(err);	/* smp_call_function_any() was buggy? */
 }
 
 static void drv_write(struct drv_cmd *cmd)
@@ -214,14 +216,14 @@ static u32 get_cur_val(const struct cpum
 	if (unlikely(cpumask_empty(mask)))
 		return 0;
 
-	switch (per_cpu(drv_data, cpumask_first(mask))->cpu_feature) {
+	switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
 	case SYSTEM_INTEL_MSR_CAPABLE:
 		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
 		cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
 		break;
 	case SYSTEM_IO_CAPABLE:
 		cmd.type = SYSTEM_IO_CAPABLE;
-		perf = per_cpu(drv_data, cpumask_first(mask))->acpi_data;
+		perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
 		cmd.addr.io.port = perf->control_register.address;
 		cmd.addr.io.bit_width = perf->control_register.bit_width;
 		break;
@@ -268,8 +270,8 @@ static unsigned int get_measured_perf(st
 	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
 		return 0;
 
-	ratio = calc_aperfmperf_ratio(&per_cpu(old_perf, cpu), &perf);
-	per_cpu(old_perf, cpu) = perf;
+	ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
+	per_cpu(acfreq_old_perf, cpu) = perf;
 
 	retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
 
@@ -278,7 +280,7 @@ static unsigned int get_measured_perf(st
 
 static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
 {
-	struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu);
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
 	unsigned int freq;
 	unsigned int cached_freq;
 
@@ -322,7 +324,7 @@ static unsigned int check_freqs(const st
 static int acpi_cpufreq_target(struct cpufreq_policy *policy,
 			       unsigned int target_freq, unsigned int relation)
 {
-	struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
 	struct acpi_processor_performance *perf;
 	struct cpufreq_freqs freqs;
 	struct drv_cmd cmd;
@@ -416,7 +418,7 @@ out:
 
 static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
 {
-	struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
 
 	dprintk("acpi_cpufreq_verify\n");
 
@@ -574,7 +576,7 @@ static int acpi_cpufreq_cpu_init(struct
 		return -ENOMEM;
 
 	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
-	per_cpu(drv_data, cpu) = data;
+	per_cpu(acfreq_data, cpu) = data;
 
 	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
 		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
@@ -725,20 +727,20 @@ err_unreg:
 	acpi_processor_unregister_performance(perf, cpu);
 err_free:
 	kfree(data);
-	per_cpu(drv_data, cpu) = NULL;
+	per_cpu(acfreq_data, cpu) = NULL;
 
 	return result;
 }
 
 static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
-	struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
 
 	dprintk("acpi_cpufreq_cpu_exit\n");
 
 	if (data) {
 		cpufreq_frequency_table_put_attr(policy->cpu);
-		per_cpu(drv_data, policy->cpu) = NULL;
+		per_cpu(acfreq_data, policy->cpu) = NULL;
 		acpi_processor_unregister_performance(data->acpi_data,
 						      policy->cpu);
 		kfree(data);
@@ -749,7 +751,7 @@ static int acpi_cpufreq_cpu_exit(struct
 
 static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
 {
-	struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
 
 	dprintk("acpi_cpufreq_resume\n");
 
@@ -764,14 +766,15 @@ static struct freq_attr *acpi_cpufreq_at
 };
 
 static struct cpufreq_driver acpi_cpufreq_driver = {
-	.verify = acpi_cpufreq_verify,
-	.target = acpi_cpufreq_target,
-	.init = acpi_cpufreq_cpu_init,
-	.exit = acpi_cpufreq_cpu_exit,
-	.resume = acpi_cpufreq_resume,
-	.name = "acpi-cpufreq",
-	.owner = THIS_MODULE,
-	.attr = acpi_cpufreq_attr,
+	.verify		= acpi_cpufreq_verify,
+	.target		= acpi_cpufreq_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
+	.name		= "acpi-cpufreq",
+	.owner		= THIS_MODULE,
+	.attr		= acpi_cpufreq_attr,
 };
 
 static int __init acpi_cpufreq_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c	2010-02-24 13:52:17.000000000 -0500
@@ -885,7 +885,7 @@ static int __init longhaul_cpu_init(stru
 
 	/* Find ACPI data for processor */
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
-				ACPI_UINT32_MAX, &longhaul_walk_callback,
+				ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
 				NULL, (void *)&pr);
 
 	/* Check ACPI support for C3 state */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ static int powernow_k6_cpu_init(struct c
 	}
 
 	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cpuinfo.transition_latency = 200000;
 	policy->cur = busfreq * max_multiplier;
 
 	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	2010-02-24 13:52:17.000000000 -0500
@@ -714,14 +714,17 @@ static struct freq_attr *powernow_table_
 };
 
 static struct cpufreq_driver powernow_driver = {
-	.verify	= powernow_verify,
-	.target	= powernow_target,
-	.get	= powernow_get,
-	.init	= powernow_cpu_init,
-	.exit	= powernow_cpu_exit,
-	.name	= "powernow-k7",
-	.owner	= THIS_MODULE,
-	.attr	= powernow_table_attr,
+	.verify		= powernow_verify,
+	.target		= powernow_target,
+	.get		= powernow_get,
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	.bios_limit	= acpi_processor_get_bios_limit,
+#endif
+	.init		= powernow_cpu_init,
+	.exit		= powernow_cpu_exit,
+	.name		= "powernow-k7",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_table_attr,
 };
 
 static int __init powernow_init(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2010-02-24 13:52:17.000000000 -0500
@@ -1118,7 +1118,7 @@ static int transition_frequency_pstate(s
 static int powernowk8_target(struct cpufreq_policy *pol,
 		unsigned targfreq, unsigned relation)
 {
-	cpumask_t oldmask;
+	cpumask_var_t oldmask;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	u32 checkfid;
 	u32 checkvid;
@@ -1131,9 +1131,13 @@ static int powernowk8_target(struct cpuf
 	checkfid = data->currfid;
 	checkvid = data->currvid;
 
-	/* only run on specific CPU from here on */
-	oldmask = current->cpus_allowed;
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu));
+	/* only run on specific CPU from here on. */
+	/* This is poor form: use a workqueue or smp_call_function_single */
+	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
+		return -ENOMEM;
+
+	cpumask_copy(oldmask, tsk_cpus_allowed(current));
+	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
 		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
@@ -1193,7 +1197,8 @@ static int powernowk8_target(struct cpuf
 	ret = 0;
 
 err_out:
-	set_cpus_allowed_ptr(current, &oldmask);
+	set_cpus_allowed_ptr(current, oldmask);
+	free_cpumask_var(oldmask);
 	return ret;
 }
 
@@ -1351,6 +1356,7 @@ static int __devexit powernowk8_cpu_exit
 
 	kfree(data->powernow_table);
 	kfree(data);
+	per_cpu(powernow_data, pol->cpu) = NULL;
 
 	return 0;
 }
@@ -1370,7 +1376,7 @@ static unsigned int powernowk8_get(unsig
 	int err;
 
 	if (!data)
-		return -EINVAL;
+		return 0;
 
 	smp_call_function_single(cpu, query_values_on_cpu, &err, true);
 	if (err)
@@ -1393,14 +1399,15 @@ static struct freq_attr *powernow_k8_att
 };
 
 static struct cpufreq_driver cpufreq_amd64_driver = {
-	.verify = powernowk8_verify,
-	.target = powernowk8_target,
-	.init = powernowk8_cpu_init,
-	.exit = __devexit_p(powernowk8_cpu_exit),
-	.get = powernowk8_get,
-	.name = "powernow-k8",
-	.owner = THIS_MODULE,
-	.attr = powernow_k8_attr,
+	.verify		= powernowk8_verify,
+	.target		= powernowk8_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= powernowk8_cpu_init,
+	.exit		= __devexit_p(powernowk8_cpu_exit),
+	.get		= powernowk8_get,
+	.name		= "powernow-k8",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_k8_attr,
 };
 
 /* driver entry point for init */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset
 
 /* speedstep_processor
  */
-static unsigned int speedstep_processor;
+static enum speedstep_processor speedstep_processor;
 
 static u32 pmbase;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@ static int relaxed_check;
  *                   GET PROCESSOR CORE SPEED IN KHZ                 *
  *********************************************************************/
 
-static unsigned int pentium3_get_frequency(unsigned int processor)
+static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
 {
 	/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
 	struct {
@@ -227,7 +227,7 @@ static unsigned int pentium4_get_frequen
 
 
 /* Warning: may get called from smp_call_function_single. */
-unsigned int speedstep_get_frequency(unsigned int processor)
+unsigned int speedstep_get_frequency(enum speedstep_processor processor)
 {
 	switch (processor) {
 	case SPEEDSTEP_CPU_PCORE:
@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(speedstep_detect_proce
  *                     DETECT SPEEDSTEP SPEEDS                       *
  *********************************************************************/
 
-unsigned int speedstep_get_freqs(unsigned int processor,
+unsigned int speedstep_get_freqs(enum speedstep_processor processor,
 				  unsigned int *low_speed,
 				  unsigned int *high_speed,
 				  unsigned int *transition_latency,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,18 +11,18 @@
 
 
 /* processors */
-
-#define SPEEDSTEP_CPU_PIII_C_EARLY	0x00000001  /* Coppermine core */
-#define SPEEDSTEP_CPU_PIII_C		0x00000002  /* Coppermine core */
-#define SPEEDSTEP_CPU_PIII_T		0x00000003  /* Tualatin core */
-#define SPEEDSTEP_CPU_P4M		0x00000004  /* P4-M  */
-
+enum speedstep_processor {
+	SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_C	   = 0x00000002,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_T	   = 0x00000003,  /* Tualatin core */
+	SPEEDSTEP_CPU_P4M	   = 0x00000004,  /* P4-M  */
 /* the following processors are not speedstep-capable and are not auto-detected
  * in speedstep_detect_processor(). However, their speed can be detected using
  * the speedstep_get_frequency() call. */
-#define SPEEDSTEP_CPU_PM		0xFFFFFF03  /* Pentium M  */
-#define SPEEDSTEP_CPU_P4D		0xFFFFFF04  /* desktop P4  */
-#define SPEEDSTEP_CPU_PCORE		0xFFFFFF05  /* Core */
+	SPEEDSTEP_CPU_PM	   = 0xFFFFFF03,  /* Pentium M  */
+	SPEEDSTEP_CPU_P4D	   = 0xFFFFFF04,  /* desktop P4  */
+	SPEEDSTEP_CPU_PCORE	   = 0xFFFFFF05,  /* Core */
+};
 
 /* speedstep states -- only two of them */
 
@@ -31,10 +31,10 @@
 
 
 /* detect a speedstep-capable processor */
-extern unsigned int speedstep_detect_processor (void);
+extern enum speedstep_processor speedstep_detect_processor(void);
 
 /* detect the current speed (in khz) of the processor */
-extern unsigned int speedstep_get_frequency(unsigned int processor);
+extern unsigned int speedstep_get_frequency(enum speedstep_processor processor);
 
 
 /* detect the low and high speeds of the processor. The callback
@@ -42,7 +42,7 @@ extern unsigned int speedstep_get_freque
  * SPEEDSTEP_LOW; the second argument is zero so that no
  * cpufreq_notify_transition calls are initiated.
  */
-extern unsigned int speedstep_get_freqs(unsigned int processor,
+extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,
 	unsigned int *low_speed,
 	unsigned int *high_speed,
 	unsigned int *transition_latency,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,7 @@ static int smi_cmd;
 static unsigned int smi_sig;
 
 /* info about the processor */
-static unsigned int speedstep_processor;
+static enum speedstep_processor speedstep_processor;
 
 /*
  * There are only two frequency states for each processor. Values
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpu.h linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpu.h
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cpu.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cpu.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,6 @@ struct cpu_dev {
 extern const struct cpu_dev *const __x86_cpu_dev_start[],
 			    *const __x86_cpu_dev_end[];
 
-extern void display_cacheinfo(struct cpuinfo_x86 *c);
+extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cyrix.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cyrix.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/cyrix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/cyrix.c	2010-02-24 13:52:17.000000000 -0500
@@ -373,7 +373,7 @@ static void __cpuinit init_nsc(struct cp
 	/* Handle the GX (Formally known as the GX2) */
 
 	if (c->x86 == 5 && c->x86_model == 5)
-		display_cacheinfo(c);
+		cpu_detect_cache_sizes(c);
 	else
 		init_cyrix(c);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/intel.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/intel.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,6 @@ static void __cpuinit early_init_intel(s
 	if (c->x86_power & (1 << 8)) {
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-		set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
 		sched_clock_stable = 1;
 	}
 
@@ -263,11 +262,13 @@ static void __cpuinit srat_detect_node(s
 	/* Don't do the funky fallback heuristics the AMD version employs
 	   for now. */
 	node = apicid_to_node[apicid];
-	if (node == NUMA_NO_NODE || !node_online(node))
+	if (node == NUMA_NO_NODE)
 		node = first_node(node_online_map);
+	else if (!node_online(node)) {
+		/* reuse the value from init_cpu_to_node() */
+		node = cpu_to_node(cpu);
+	}
 	numa_set_node(cpu, node);
-
-	printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
 #endif
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2010-02-24 13:52:17.000000000 -0500
@@ -94,7 +94,7 @@ static const struct _cache_table __cpuin
 	{ 0xd1, LVL_3,    1024 },	/* 4-way set assoc, 64 byte line size */
 	{ 0xd2, LVL_3,    2048 },	/* 4-way set assoc, 64 byte line size */
 	{ 0xd6, LVL_3,    1024 },	/* 8-way set assoc, 64 byte line size */
-	{ 0xd7, LVL_3,    2038 },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd7, LVL_3,    2048 },	/* 8-way set assoc, 64 byte line size */
 	{ 0xd8, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
 	{ 0xdc, LVL_3,    2048 },	/* 12-way set assoc, 64 byte line size */
 	{ 0xdd, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
@@ -102,6 +102,9 @@ static const struct _cache_table __cpuin
 	{ 0xe2, LVL_3,    2048 },	/* 16-way set assoc, 64 byte line size */
 	{ 0xe3, LVL_3,    4096 },	/* 16-way set assoc, 64 byte line size */
 	{ 0xe4, LVL_3,    8192 },	/* 16-way set assoc, 64 byte line size */
+	{ 0xea, LVL_3,    12288 },	/* 24-way set assoc, 64 byte line size */
+	{ 0xeb, LVL_3,    18432 },	/* 24-way set assoc, 64 byte line size */
+	{ 0xec, LVL_3,    24576 },	/* 24-way set assoc, 64 byte line size */
 	{ 0x00, 0, 0}
 };
 
@@ -488,22 +491,6 @@ unsigned int __cpuinit init_intel_cachei
 #endif
 	}
 
-	if (trace)
-		printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
-	else if (l1i)
-		printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
-
-	if (l1d)
-		printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
-	else
-		printk(KERN_CONT "\n");
-
-	if (l2)
-		printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
-
-	if (l3)
-		printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
-
 	c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
 
 	return l2;
@@ -512,26 +499,27 @@ unsigned int __cpuinit init_intel_cachei
 #ifdef CONFIG_SYSFS
 
 /* pointer to _cpuid4_info array (for each cache leaf) */
-static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
-#define CPUID4_INFO_IDX(x, y)	(&((per_cpu(cpuid4_info, x))[y]))
+static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
+#define CPUID4_INFO_IDX(x, y)	(&((per_cpu(ici_cpuid4_info, x))[y]))
 
 #ifdef CONFIG_SMP
 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 {
 	struct _cpuid4_info	*this_leaf, *sibling_leaf;
 	unsigned long num_threads_sharing;
-	int index_msb, i;
+	int index_msb, i, sibling;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
-		struct cpuinfo_x86 *d;
-		for_each_online_cpu(i) {
-			if (!per_cpu(cpuid4_info, i))
+		for_each_cpu(i, c->llc_shared_map) {
+			if (!per_cpu(ici_cpuid4_info, i))
 				continue;
-			d = &cpu_data(i);
 			this_leaf = CPUID4_INFO_IDX(i, index);
-			cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
-				     d->llc_shared_map);
+			for_each_cpu(sibling, c->llc_shared_map) {
+				if (!cpu_online(sibling))
+					continue;
+				set_bit(sibling, this_leaf->shared_cpu_map);
+			}
 		}
 		return;
 	}
@@ -548,7 +536,7 @@ static void __cpuinit cache_shared_cpu_m
 			    c->apicid >> index_msb) {
 				cpumask_set_cpu(i,
 					to_cpumask(this_leaf->shared_cpu_map));
-				if (i != cpu && per_cpu(cpuid4_info, i))  {
+				if (i != cpu && per_cpu(ici_cpuid4_info, i))  {
 					sibling_leaf =
 						CPUID4_INFO_IDX(i, index);
 					cpumask_set_cpu(cpu, to_cpumask(
@@ -587,8 +575,8 @@ static void __cpuinit free_cache_attribu
 	for (i = 0; i < num_cache_leaves; i++)
 		cache_remove_shared_cpu_map(cpu, i);
 
-	kfree(per_cpu(cpuid4_info, cpu));
-	per_cpu(cpuid4_info, cpu) = NULL;
+	kfree(per_cpu(ici_cpuid4_info, cpu));
+	per_cpu(ici_cpuid4_info, cpu) = NULL;
 }
 
 static int
@@ -627,15 +615,15 @@ static int __cpuinit detect_cache_attrib
 	if (num_cache_leaves == 0)
 		return -ENOENT;
 
-	per_cpu(cpuid4_info, cpu) = kzalloc(
+	per_cpu(ici_cpuid4_info, cpu) = kzalloc(
 	    sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
-	if (per_cpu(cpuid4_info, cpu) == NULL)
+	if (per_cpu(ici_cpuid4_info, cpu) == NULL)
 		return -ENOMEM;
 
 	smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
 	if (retval) {
-		kfree(per_cpu(cpuid4_info, cpu));
-		per_cpu(cpuid4_info, cpu) = NULL;
+		kfree(per_cpu(ici_cpuid4_info, cpu));
+		per_cpu(ici_cpuid4_info, cpu) = NULL;
 	}
 
 	return retval;
@@ -647,7 +635,7 @@ static int __cpuinit detect_cache_attrib
 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
 
 /* pointer to kobject for cpuX/cache */
-static DEFINE_PER_CPU(struct kobject *, cache_kobject);
+static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
 
 struct _index_kobject {
 	struct kobject kobj;
@@ -656,8 +644,8 @@ struct _index_kobject {
 };
 
 /* pointer to array of kobjects for cpuX/cache/indexY */
-static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
-#define INDEX_KOBJECT_PTR(x, y)		(&((per_cpu(index_kobject, x))[y]))
+static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject);
+#define INDEX_KOBJECT_PTR(x, y)		(&((per_cpu(ici_index_kobject, x))[y]))
 
 #define show_one_plus(file_name, object, val)				\
 static ssize_t show_##file_name						\
@@ -876,10 +864,10 @@ static struct kobj_type ktype_percpu_ent
 
 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
 {
-	kfree(per_cpu(cache_kobject, cpu));
-	kfree(per_cpu(index_kobject, cpu));
-	per_cpu(cache_kobject, cpu) = NULL;
-	per_cpu(index_kobject, cpu) = NULL;
+	kfree(per_cpu(ici_cache_kobject, cpu));
+	kfree(per_cpu(ici_index_kobject, cpu));
+	per_cpu(ici_cache_kobject, cpu) = NULL;
+	per_cpu(ici_index_kobject, cpu) = NULL;
 	free_cache_attributes(cpu);
 }
 
@@ -895,14 +883,14 @@ static int __cpuinit cpuid4_cache_sysfs_
 		return err;
 
 	/* Allocate all required memory */
-	per_cpu(cache_kobject, cpu) =
+	per_cpu(ici_cache_kobject, cpu) =
 		kzalloc(sizeof(struct kobject), GFP_KERNEL);
-	if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
+	if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL))
 		goto err_out;
 
-	per_cpu(index_kobject, cpu) = kzalloc(
+	per_cpu(ici_index_kobject, cpu) = kzalloc(
 	    sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
-	if (unlikely(per_cpu(index_kobject, cpu) == NULL))
+	if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL))
 		goto err_out;
 
 	return 0;
@@ -926,7 +914,7 @@ static int __cpuinit cache_add_dev(struc
 	if (unlikely(retval < 0))
 		return retval;
 
-	retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
+	retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
 				      &ktype_percpu_entry,
 				      &sys_dev->kobj, "%s", "cache");
 	if (retval < 0) {
@@ -940,12 +928,12 @@ static int __cpuinit cache_add_dev(struc
 		this_object->index = i;
 		retval = kobject_init_and_add(&(this_object->kobj),
 					      &ktype_cache,
-					      per_cpu(cache_kobject, cpu),
+					      per_cpu(ici_cache_kobject, cpu),
 					      "index%1lu", i);
 		if (unlikely(retval)) {
 			for (j = 0; j < i; j++)
 				kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
-			kobject_put(per_cpu(cache_kobject, cpu));
+			kobject_put(per_cpu(ici_cache_kobject, cpu));
 			cpuid4_cache_sysfs_exit(cpu);
 			return retval;
 		}
@@ -953,7 +941,7 @@ static int __cpuinit cache_add_dev(struc
 	}
 	cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
 
-	kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
+	kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD);
 	return 0;
 }
 
@@ -962,7 +950,7 @@ static void __cpuinit cache_remove_dev(s
 	unsigned int cpu = sys_dev->id;
 	unsigned long i;
 
-	if (per_cpu(cpuid4_info, cpu) == NULL)
+	if (per_cpu(ici_cpuid4_info, cpu) == NULL)
 		return;
 	if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
 		return;
@@ -970,7 +958,7 @@ static void __cpuinit cache_remove_dev(s
 
 	for (i = 0; i < num_cache_leaves; i++)
 		kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
-	kobject_put(per_cpu(cache_kobject, cpu));
+	kobject_put(per_cpu(ici_cache_kobject, cpu));
 	cpuid4_cache_sysfs_exit(cpu);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/Makefile linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
 # Don't trace early stages of a secondary CPU boot
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_common.o = -pg
+CFLAGS_REMOVE_perf_event.o = -pg
 endif
 
 # Make sure load_percpu_segment has no stackprotector
@@ -18,8 +19,6 @@ obj-y			+= vmware.o hypervisor.o sched.o
 obj-$(CONFIG_X86_32)	+= bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
 
-obj-$(CONFIG_X86_CPU_DEBUG)		+= cpu_debug.o
-
 obj-$(CONFIG_CPU_SUP_INTEL)		+= intel.o
 obj-$(CONFIG_CPU_SUP_AMD)		+= amd.o
 obj-$(CONFIG_CPU_SUP_CYRIX_32)		+= cyrix.o
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/mce.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,9 @@
 
 #include "mce-internal.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/mce.h>
+
 int mce_disabled __read_mostly;
 
 #define MISC_MCELOG_MINOR	227
@@ -85,18 +88,26 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait)
 static DEFINE_PER_CPU(struct mce, mces_seen);
 static int			cpu_missing;
 
-static void default_decode_mce(struct mce *m)
+/*
+ * CPU/chipset specific EDAC code can register a notifier call here to print
+ * MCE errors in a human-readable form.
+ */
+ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
+EXPORT_SYMBOL_GPL(x86_mce_decoder_chain);
+
+static int default_decode_mce(struct notifier_block *nb, unsigned long val,
+			       void *data)
 {
 	pr_emerg("No human readable MCE decoding support on this CPU type.\n");
 	pr_emerg("Run the message through 'mcelog --ascii' to decode.\n");
+
+	return NOTIFY_STOP;
 }
 
-/*
- * CPU/chipset specific EDAC code can register a callback here to print
- * MCE errors in a human-readable form:
- */
-void (*x86_mce_decode_callback)(struct mce *m) = default_decode_mce;
-EXPORT_SYMBOL(x86_mce_decode_callback);
+static struct notifier_block mce_dec_nb = {
+	.notifier_call = default_decode_mce,
+	.priority      = -1,
+};
 
 /* MCA banks polled by the period polling timer for corrected events */
 DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
@@ -141,6 +152,9 @@ void mce_log(struct mce *mce)
 {
 	unsigned next, entry;
 
+	/* Emit the trace record: */
+	trace_mce_record(mce);
+
 	mce->finished = 0;
 	wmb();
 	for (;;) {
@@ -204,9 +218,9 @@ static void print_mce(struct mce *m)
 
 	/*
 	 * Print out human-readable details about the MCE error,
-	 * (if the CPU has an implementation for that):
+	 * (if the CPU has an implementation for that)
 	 */
-	x86_mce_decode_callback(m);
+	atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
 }
 
 static void print_mce_head(void)
@@ -1122,7 +1136,7 @@ static int check_interval = 5 * 60; /* 5
 static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */
 static DEFINE_PER_CPU(struct timer_list, mce_timer);
 
-static void mcheck_timer(unsigned long data)
+static void mce_start_timer(unsigned long data)
 {
 	struct timer_list *t = &per_cpu(mce_timer, data);
 	int *n;
@@ -1187,7 +1201,7 @@ int mce_notify_irq(void)
 }
 EXPORT_SYMBOL_GPL(mce_notify_irq);
 
-static int mce_banks_init(void)
+static int __cpuinit __mcheck_cpu_mce_banks_init(void)
 {
 	int i;
 
@@ -1206,7 +1220,7 @@ static int mce_banks_init(void)
 /*
  * Initialize Machine Checks for a CPU.
  */
-static int __cpuinit mce_cap_init(void)
+static int __cpuinit __mcheck_cpu_cap_init(void)
 {
 	unsigned b;
 	u64 cap;
@@ -1228,7 +1242,7 @@ static int __cpuinit mce_cap_init(void)
 	WARN_ON(banks != 0 && b != banks);
 	banks = b;
 	if (!mce_banks) {
-		int err = mce_banks_init();
+		int err = __mcheck_cpu_mce_banks_init();
 
 		if (err)
 			return err;
@@ -1244,7 +1258,7 @@ static int __cpuinit mce_cap_init(void)
 	return 0;
 }
 
-static void mce_init(void)
+static void __mcheck_cpu_init_generic(void)
 {
 	mce_banks_t all_banks;
 	u64 cap;
@@ -1273,7 +1287,7 @@ static void mce_init(void)
 }
 
 /* Add per CPU specific workarounds here */
-static int __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
+static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
 {
 	if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
 		pr_info("MCE: unknown CPU type - not enabling MCE support.\n");
@@ -1341,7 +1355,7 @@ static int __cpuinit mce_cpu_quirks(stru
 	return 0;
 }
 
-static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c)
+static void __cpuinit __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
 {
 	if (c->x86 != 5)
 		return;
@@ -1355,7 +1369,7 @@ static void __cpuinit mce_ancient_init(s
 	}
 }
 
-static void mce_cpu_features(struct cpuinfo_x86 *c)
+static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
 {
 	switch (c->x86_vendor) {
 	case X86_VENDOR_INTEL:
@@ -1369,18 +1383,19 @@ static void mce_cpu_features(struct cpui
 	}
 }
 
-static void mce_init_timer(void)
+static void __mcheck_cpu_init_timer(void)
 {
 	struct timer_list *t = &__get_cpu_var(mce_timer);
 	int *n = &__get_cpu_var(mce_next_interval);
 
+	setup_timer(t, mce_start_timer, smp_processor_id());
+
 	if (mce_ignore_ce)
 		return;
 
 	*n = check_interval * HZ;
 	if (!*n)
 		return;
-	setup_timer(t, mcheck_timer, smp_processor_id());
 	t->expires = round_jiffies(jiffies + *n);
 	add_timer_on(t, smp_processor_id());
 }
@@ -1400,27 +1415,28 @@ 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_init(struct cpuinfo_x86 *c)
+void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c)
 {
 	if (mce_disabled)
 		return;
 
-	mce_ancient_init(c);
+	__mcheck_cpu_ancient_init(c);
 
 	if (!mce_available(c))
 		return;
 
-	if (mce_cap_init() < 0 || mce_cpu_quirks(c) < 0) {
+	if (__mcheck_cpu_cap_init() < 0 || __mcheck_cpu_apply_quirks(c) < 0) {
 		mce_disabled = 1;
 		return;
 	}
 
 	machine_check_vector = do_machine_check;
 
-	mce_init();
-	mce_cpu_features(c);
-	mce_init_timer();
+	__mcheck_cpu_init_generic();
+	__mcheck_cpu_init_vendor(c);
+	__mcheck_cpu_init_timer();
 	INIT_WORK(&__get_cpu_var(mce_work), mce_process_work);
+
 }
 
 /*
@@ -1640,6 +1656,15 @@ static int __init mcheck_enable(char *st
 }
 __setup("mce", mcheck_enable);
 
+int __init mcheck_init(void)
+{
+	atomic_notifier_chain_register(&x86_mce_decoder_chain, &mce_dec_nb);
+
+	mcheck_intel_therm_init();
+
+	return 0;
+}
+
 /*
  * Sysfs support
  */
@@ -1648,7 +1673,7 @@ __setup("mce", mcheck_enable);
  * Disable machine checks on suspend and shutdown. We can't really handle
  * them later.
  */
-static int mce_disable(void)
+static int mce_disable_error_reporting(void)
 {
 	int i;
 
@@ -1663,12 +1688,12 @@ static int mce_disable(void)
 
 static int mce_suspend(struct sys_device *dev, pm_message_t state)
 {
-	return mce_disable();
+	return mce_disable_error_reporting();
 }
 
 static int mce_shutdown(struct sys_device *dev)
 {
-	return mce_disable();
+	return mce_disable_error_reporting();
 }
 
 /*
@@ -1678,8 +1703,8 @@ static int mce_shutdown(struct sys_devic
  */
 static int mce_resume(struct sys_device *dev)
 {
-	mce_init();
-	mce_cpu_features(&current_cpu_data);
+	__mcheck_cpu_init_generic();
+	__mcheck_cpu_init_vendor(&current_cpu_data);
 
 	return 0;
 }
@@ -1689,8 +1714,8 @@ static void mce_cpu_restart(void *data)
 	del_timer_sync(&__get_cpu_var(mce_timer));
 	if (!mce_available(&current_cpu_data))
 		return;
-	mce_init();
-	mce_init_timer();
+	__mcheck_cpu_init_generic();
+	__mcheck_cpu_init_timer();
 }
 
 /* Reinit MCEs after user configuration changes */
@@ -1716,7 +1741,7 @@ static void mce_enable_ce(void *all)
 	cmci_reenable();
 	cmci_recheck();
 	if (all)
-		mce_init_timer();
+		__mcheck_cpu_init_timer();
 }
 
 static struct sysdev_class mce_sysclass = {
@@ -1904,7 +1929,7 @@ error2:
 		sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr);
 error:
 	while (--i >= 0)
-		sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr);
+		sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
 
 	sysdev_unregister(&per_cpu(mce_dev, cpu));
 
@@ -1929,13 +1954,14 @@ static __cpuinit void mce_remove_device(
 }
 
 /* Make sure there are no machine checks on offlined CPUs. */
-static void mce_disable_cpu(void *h)
+static void __cpuinit mce_disable_cpu(void *h)
 {
 	unsigned long action = *(unsigned long *)h;
 	int i;
 
 	if (!mce_available(&current_cpu_data))
 		return;
+
 	if (!(action & CPU_TASKS_FROZEN))
 		cmci_clear();
 	for (i = 0; i < banks; i++) {
@@ -1946,7 +1972,7 @@ static void mce_disable_cpu(void *h)
 	}
 }
 
-static void mce_reenable_cpu(void *h)
+static void __cpuinit mce_reenable_cpu(void *h)
 {
 	unsigned long action = *(unsigned long *)h;
 	int i;
@@ -1991,9 +2017,11 @@ mce_cpu_callback(struct notifier_block *
 		break;
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
-		t->expires = round_jiffies(jiffies +
+		if (!mce_ignore_ce && check_interval) {
+			t->expires = round_jiffies(jiffies +
 					   __get_cpu_var(mce_next_interval));
-		add_timer_on(t, cpu);
+			add_timer_on(t, cpu);
+		}
 		smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
 		break;
 	case CPU_POST_DEAD:
@@ -2025,7 +2053,7 @@ static __init void mce_init_banks(void)
 	}
 }
 
-static __init int mce_init_device(void)
+static __init int mcheck_init_device(void)
 {
 	int err;
 	int i = 0;
@@ -2053,7 +2081,7 @@ static __init int mce_init_device(void)
 	return err;
 }
 
-device_initcall(mce_init_device);
+device_initcall(mcheck_init_device);
 
 /*
  * Old style boot options parsing. Only for compatibility.
@@ -2101,7 +2129,7 @@ static int fake_panic_set(void *data, u6
 DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
 			fake_panic_set, "%llu\n");
 
-static int __init mce_debugfs_init(void)
+static int __init mcheck_debugfs_init(void)
 {
 	struct dentry *dmce, *ffake_panic;
 
@@ -2115,5 +2143,5 @@ static int __init mce_debugfs_init(void)
 
 	return 0;
 }
-late_initcall(mce_debugfs_init);
+late_initcall(mcheck_debugfs_init);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/mce-inject.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ static void raise_exception(struct mce *
 	m->finished = 0;
 }
 
-static cpumask_t mce_inject_cpumask;
+static cpumask_var_t mce_inject_cpumask;
 
 static int mce_raise_notify(struct notifier_block *self,
 			    unsigned long val, void *data)
@@ -82,9 +82,9 @@ static int mce_raise_notify(struct notif
 	struct die_args *args = (struct die_args *)data;
 	int cpu = smp_processor_id();
 	struct mce *m = &__get_cpu_var(injectm);
-	if (val != DIE_NMI_IPI || !cpu_isset(cpu, mce_inject_cpumask))
+	if (val != DIE_NMI_IPI || !cpumask_test_cpu(cpu, mce_inject_cpumask))
 		return NOTIFY_DONE;
-	cpu_clear(cpu, mce_inject_cpumask);
+	cpumask_clear_cpu(cpu, mce_inject_cpumask);
 	if (m->inject_flags & MCJ_EXCEPTION)
 		raise_exception(m, args->regs);
 	else if (m->status)
@@ -148,22 +148,22 @@ static void raise_mce(struct mce *m)
 		unsigned long start;
 		int cpu;
 		get_online_cpus();
-		mce_inject_cpumask = cpu_online_map;
-		cpu_clear(get_cpu(), mce_inject_cpumask);
+		cpumask_copy(mce_inject_cpumask, cpu_online_mask);
+		cpumask_clear_cpu(get_cpu(), mce_inject_cpumask);
 		for_each_online_cpu(cpu) {
 			struct mce *mcpu = &per_cpu(injectm, cpu);
 			if (!mcpu->finished ||
 			    MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)
-				cpu_clear(cpu, mce_inject_cpumask);
+				cpumask_clear_cpu(cpu, mce_inject_cpumask);
 		}
-		if (!cpus_empty(mce_inject_cpumask))
-			apic->send_IPI_mask(&mce_inject_cpumask, NMI_VECTOR);
+		if (!cpumask_empty(mce_inject_cpumask))
+			apic->send_IPI_mask(mce_inject_cpumask, NMI_VECTOR);
 		start = jiffies;
-		while (!cpus_empty(mce_inject_cpumask)) {
+		while (!cpumask_empty(mce_inject_cpumask)) {
 			if (!time_before(jiffies, start + 2*HZ)) {
 				printk(KERN_ERR
 				"Timeout waiting for mce inject NMI %lx\n",
-					*cpus_addr(mce_inject_cpumask));
+					*cpumask_bits(mce_inject_cpumask));
 				break;
 			}
 			cpu_relax();
@@ -210,6 +210,8 @@ static ssize_t mce_write(struct file *fi
 
 static int inject_init(void)
 {
+	if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
+		return -ENOMEM;
 	printk(KERN_INFO "Machine check injector initialized\n");
 	mce_chrdev_ops.write = mce_write;
 	register_die_notifier(&mce_raise_nb);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,8 @@ static DEFINE_PER_CPU(struct thermal_sta
 
 static atomic_t therm_throt_en	= ATOMIC_INIT(0);
 
+static u32 lvtthmr_init __read_mostly;
+
 #ifdef CONFIG_SYSFS
 #define define_therm_throt_sysdev_one_ro(_name)				\
 	static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
@@ -254,14 +256,34 @@ asmlinkage void smp_thermal_interrupt(st
 	ack_APIC_irq();
 }
 
+/* Thermal monitoring depends on APIC, ACPI and clock modulation */
+static int intel_thermal_supported(struct cpuinfo_x86 *c)
+{
+	if (!cpu_has_apic)
+		return 0;
+	if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
+		return 0;
+	return 1;
+}
+
+void __init mcheck_intel_therm_init(void)
+{
+	/*
+	 * This function is only called on boot CPU. Save the init thermal
+	 * LVT value on BSP and use that value to restore APs' thermal LVT
+	 * entry BIOS programmed later
+	 */
+	if (intel_thermal_supported(&boot_cpu_data))
+		lvtthmr_init = apic_read(APIC_LVTTHMR);
+}
+
 void intel_init_thermal(struct cpuinfo_x86 *c)
 {
 	unsigned int cpu = smp_processor_id();
 	int tm2 = 0;
 	u32 l, h;
 
-	/* Thermal monitoring depends on ACPI and clock modulation*/
-	if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
+	if (!intel_thermal_supported(c))
 		return;
 
 	/*
@@ -270,7 +292,20 @@ void intel_init_thermal(struct cpuinfo_x
 	 * since it might be delivered via SMI already:
 	 */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-	h = apic_read(APIC_LVTTHMR);
+
+	/*
+	 * The initial value of thermal LVT entries on all APs always reads
+	 * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
+	 * sequence to them and LVT registers are reset to 0s except for
+	 * the mask bits which are set to 1s when APs receive INIT IPI.
+	 * Always restore the value that BIOS has programmed on AP based on
+	 * BSP's info we saved since BIOS is always setting the same value
+	 * for all threads/cores
+	 */
+	apic_write(APIC_LVTTHMR, lvtthmr_init);
+
+	h = lvtthmr_init;
+
 	if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
 		printk(KERN_DEBUG
 		       "CPU%d: Thermal monitoring handled by SMI\n", cpu);
@@ -312,8 +347,8 @@ void intel_init_thermal(struct cpuinfo_x
 	l = apic_read(APIC_LVTTHMR);
 	apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
 
-	printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
-	       cpu, tm2 ? "TM2" : "TM1");
+	printk_once(KERN_INFO "CPU0: Thermal monitoring enabled (%s)\n",
+		       tm2 ? "TM2" : "TM1");
 
 	/* enable thermal throttle processing */
 	atomic_set(&therm_throt_en, 1);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2010-02-24 13:52:17.000000000 -0500
@@ -170,6 +170,41 @@ static int __init cmp_range(const void *
 	return start1 - start2;
 }
 
+static int __init clean_sort_range(struct res_range *range, int az)
+{
+	int i, j, k = az - 1, nr_range = 0;
+
+	for (i = 0; i < k; i++) {
+		if (range[i].end)
+			continue;
+		for (j = k; j > i; j--) {
+			if (range[j].end) {
+				k = j;
+				break;
+			}
+		}
+		if (j == i)
+			break;
+		range[i].start = range[k].start;
+		range[i].end   = range[k].end;
+		range[k].start = 0;
+		range[k].end   = 0;
+		k--;
+	}
+	/* count it */
+	for (i = 0; i < az; i++) {
+		if (!range[i].end) {
+			nr_range = i;
+			break;
+		}
+	}
+
+	/* sort them */
+	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+
+	return nr_range;
+}
+
 #define BIOS_BUG_MSG KERN_WARNING \
 	"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
 
@@ -223,22 +258,18 @@ x86_get_mtrr_mem_range(struct res_range
 		subtract_range(range, extra_remove_base,
 				 extra_remove_base + extra_remove_size  - 1);
 
-	/* get new range num */
-	nr_range = 0;
-	for (i = 0; i < RANGE_NUM; i++) {
-		if (!range[i].end)
-			continue;
-		nr_range++;
-	}
 	if  (debug_print) {
 		printk(KERN_DEBUG "After UC checking\n");
-		for (i = 0; i < nr_range; i++)
+		for (i = 0; i < RANGE_NUM; i++) {
+			if (!range[i].end)
+				continue;
 			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
 				 range[i].start, range[i].end + 1);
+		}
 	}
 
 	/* sort the ranges */
-	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+	nr_range = clean_sort_range(range, RANGE_NUM);
 	if  (debug_print) {
 		printk(KERN_DEBUG "After sorting\n");
 		for (i = 0; i < nr_range; i++)
@@ -689,8 +720,6 @@ static int __init mtrr_need_cleanup(void
 			continue;
 		if (!size)
 			type = MTRR_NUM_TYPES;
-		if (type == MTRR_TYPE_WRPROT)
-			type = MTRR_TYPE_UNCACHABLE;
 		num[type]++;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mtrr/if.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/if.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
 #include <linux/proc_fs.h>
 #include <linux/module.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/init.h>
 
 #define LINE_SIZE 80
@@ -133,8 +134,7 @@ mtrr_write(struct file *file, const char
 		return -EINVAL;
 
 	base = simple_strtoull(line + 5, &ptr, 0);
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr);
 
 	if (strncmp(ptr, "size=", 5))
 		return -EINVAL;
@@ -142,14 +142,11 @@ mtrr_write(struct file *file, const char
 	size = simple_strtoull(ptr + 5, &ptr, 0);
 	if ((base & 0xfff) || (size & 0xfff))
 		return -EINVAL;
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr);
 
 	if (strncmp(ptr, "type=", 5))
 		return -EINVAL;
-	ptr += 5;
-	while (isspace(*ptr))
-		ptr++;
+	ptr = skip_spaces(ptr + 5);
 
 	for (i = 0; i < MTRR_NUM_TYPES; ++i) {
 		if (strcmp(ptr, mtrr_strings[i]))
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2010-02-24 13:52:17.000000000 -0500
@@ -712,7 +712,7 @@ static void probe_nmi_watchdog(void)
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
 		if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 &&
-		    boot_cpu_data.x86 != 16)
+		    boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17)
 			return;
 		wd_ops = &k7_wd_ops;
 		break;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/perf_event.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/perf_event.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/perf_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,6 +77,18 @@ struct cpu_hw_events {
 	struct debug_store	*ds;
 };
 
+struct event_constraint {
+	unsigned long	idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	int		code;
+};
+
+#define EVENT_CONSTRAINT(c, m) { .code = (c), .idxmsk[0] = (m) }
+#define EVENT_CONSTRAINT_END  { .code = 0, .idxmsk[0] = 0 }
+
+#define for_each_event_constraint(e, c) \
+	for ((e) = (c); (e)->idxmsk[0]; (e)++)
+
+
 /*
  * struct x86_pmu - generic x86 pmu
  */
@@ -102,6 +114,8 @@ struct x86_pmu {
 	u64		intel_ctrl;
 	void		(*enable_bts)(u64 config);
 	void		(*disable_bts)(void);
+	int		(*get_event_idx)(struct cpu_hw_events *cpuc,
+					 struct hw_perf_event *hwc);
 };
 
 static struct x86_pmu x86_pmu __read_mostly;
@@ -110,6 +124,8 @@ static DEFINE_PER_CPU(struct cpu_hw_even
 	.enabled = 1,
 };
 
+static const struct event_constraint *event_constraints;
+
 /*
  * Not sure about some of these
  */
@@ -155,6 +171,16 @@ static u64 p6_pmu_raw_event(u64 hw_event
 	return hw_event & P6_EVNTSEL_MASK;
 }
 
+static const struct event_constraint intel_p6_event_constraints[] =
+{
+	EVENT_CONSTRAINT(0xc1, 0x1),	/* FLOPS */
+	EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
+	EVENT_CONSTRAINT(0x11, 0x1),	/* FP_ASSIST */
+	EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
+	EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
+	EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
+	EVENT_CONSTRAINT_END
+};
 
 /*
  * Intel PerfMon v3. Used on Core2 and later.
@@ -170,6 +196,35 @@ static const u64 intel_perfmon_event_map
   [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
 };
 
+static const struct event_constraint intel_core_event_constraints[] =
+{
+	EVENT_CONSTRAINT(0x10, 0x1),	/* FP_COMP_OPS_EXE */
+	EVENT_CONSTRAINT(0x11, 0x2),	/* FP_ASSIST */
+	EVENT_CONSTRAINT(0x12, 0x2),	/* MUL */
+	EVENT_CONSTRAINT(0x13, 0x2),	/* DIV */
+	EVENT_CONSTRAINT(0x14, 0x1),	/* CYCLES_DIV_BUSY */
+	EVENT_CONSTRAINT(0x18, 0x1),	/* IDLE_DURING_DIV */
+	EVENT_CONSTRAINT(0x19, 0x2),	/* DELAYED_BYPASS */
+	EVENT_CONSTRAINT(0xa1, 0x1),	/* RS_UOPS_DISPATCH_CYCLES */
+	EVENT_CONSTRAINT(0xcb, 0x1),	/* MEM_LOAD_RETIRED */
+	EVENT_CONSTRAINT_END
+};
+
+static const struct event_constraint intel_nehalem_event_constraints[] =
+{
+	EVENT_CONSTRAINT(0x40, 0x3),	/* L1D_CACHE_LD */
+	EVENT_CONSTRAINT(0x41, 0x3),	/* L1D_CACHE_ST */
+	EVENT_CONSTRAINT(0x42, 0x3),	/* L1D_CACHE_LOCK */
+	EVENT_CONSTRAINT(0x43, 0x3),	/* L1D_ALL_REF */
+	EVENT_CONSTRAINT(0x4e, 0x3),	/* L1D_PREFETCH */
+	EVENT_CONSTRAINT(0x4c, 0x3),	/* LOAD_HIT_PRE */
+	EVENT_CONSTRAINT(0x51, 0x3),	/* L1D */
+	EVENT_CONSTRAINT(0x52, 0x3),	/* L1D_CACHE_PREFETCH_LOCK_FB_HIT */
+	EVENT_CONSTRAINT(0x53, 0x3),	/* L1D_CACHE_LOCK_FB_HIT */
+	EVENT_CONSTRAINT(0xc5, 0x3),	/* CACHE_LOCK_CYCLES */
+	EVENT_CONSTRAINT_END
+};
+
 static u64 intel_pmu_event_map(int hw_event)
 {
 	return intel_perfmon_event_map[hw_event];
@@ -190,7 +245,7 @@ static u64 __read_mostly hw_cache_event_
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX];
 
-static const u64 nehalem_hw_cache_event_ids
+static __initconst u64 nehalem_hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -281,7 +336,7 @@ static const u64 nehalem_hw_cache_event_
  },
 };
 
-static const u64 core2_hw_cache_event_ids
+static __initconst u64 core2_hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -372,7 +427,7 @@ static const u64 core2_hw_cache_event_id
  },
 };
 
-static const u64 atom_hw_cache_event_ids
+static __initconst u64 atom_hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -469,7 +524,7 @@ static u64 intel_pmu_raw_event(u64 hw_ev
 #define CORE_EVNTSEL_UNIT_MASK		0x0000FF00ULL
 #define CORE_EVNTSEL_EDGE_MASK		0x00040000ULL
 #define CORE_EVNTSEL_INV_MASK		0x00800000ULL
-#define CORE_EVNTSEL_REG_MASK	0xFF000000ULL
+#define CORE_EVNTSEL_REG_MASK		0xFF000000ULL
 
 #define CORE_EVNTSEL_MASK		\
 	(CORE_EVNTSEL_EVENT_MASK |	\
@@ -481,7 +536,7 @@ static u64 intel_pmu_raw_event(u64 hw_ev
 	return hw_event & CORE_EVNTSEL_MASK;
 }
 
-static const u64 amd_hw_cache_event_ids
+static __initconst u64 amd_hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -932,6 +987,8 @@ static int __hw_perf_event_init(struct p
 	 */
 	hwc->config = ARCH_PERFMON_EVENTSEL_INT;
 
+	hwc->idx = -1;
+
 	/*
 	 * Count user and OS events unless requested not to.
 	 */
@@ -1229,7 +1286,7 @@ x86_perf_event_set_period(struct perf_ev
 		return 0;
 
 	/*
-	 * If we are way outside a reasoable range then just skip forward:
+	 * If we are way outside a reasonable range then just skip forward:
 	 */
 	if (unlikely(left <= -period)) {
 		left = period;
@@ -1286,6 +1343,13 @@ intel_pmu_enable_fixed(struct hw_perf_ev
 		bits |= 0x2;
 	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
 		bits |= 0x1;
+
+	/*
+	 * ANY bit is supported in v3 and up
+	 */
+	if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
+		bits |= 0x4;
+
 	bits <<= (idx * 4);
 	mask = 0xfULL << (idx * 4);
 
@@ -1334,8 +1398,7 @@ static void amd_pmu_enable_event(struct
 		x86_pmu_enable_event(hwc, idx);
 }
 
-static int
-fixed_mode_idx(struct perf_event *event, struct hw_perf_event *hwc)
+static int fixed_mode_idx(struct hw_perf_event *hwc)
 {
 	unsigned int hw_event;
 
@@ -1349,6 +1412,12 @@ fixed_mode_idx(struct perf_event *event,
 	if (!x86_pmu.num_events_fixed)
 		return -1;
 
+	/*
+	 * fixed counters do not take all possible filters
+	 */
+	if (hwc->config & ARCH_PERFMON_EVENT_FILTER_MASK)
+		return -1;
+
 	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
 		return X86_PMC_IDX_FIXED_INSTRUCTIONS;
 	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
@@ -1360,22 +1429,57 @@ fixed_mode_idx(struct perf_event *event,
 }
 
 /*
- * Find a PMC slot for the freshly enabled / scheduled in event:
+ * generic counter allocator: get next free counter
  */
-static int x86_pmu_enable(struct perf_event *event)
+static int
+gen_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
 {
-	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-	struct hw_perf_event *hwc = &event->hw;
 	int idx;
 
-	idx = fixed_mode_idx(event, hwc);
+	idx = find_first_zero_bit(cpuc->used_mask, x86_pmu.num_events);
+	return idx == x86_pmu.num_events ? -1 : idx;
+}
+
+/*
+ * intel-specific counter allocator: check event constraints
+ */
+static int
+intel_get_event_idx(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
+{
+	const struct event_constraint *event_constraint;
+	int i, code;
+
+	if (!event_constraints)
+		goto skip;
+
+	code = hwc->config & CORE_EVNTSEL_EVENT_MASK;
+
+	for_each_event_constraint(event_constraint, event_constraints) {
+		if (code == event_constraint->code) {
+			for_each_bit(i, event_constraint->idxmsk, X86_PMC_IDX_MAX) {
+				if (!test_and_set_bit(i, cpuc->used_mask))
+					return i;
+			}
+			return -1;
+		}
+	}
+skip:
+	return gen_get_event_idx(cpuc, hwc);
+}
+
+static int
+x86_schedule_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
+{
+	int idx;
+
+	idx = fixed_mode_idx(hwc);
 	if (idx == X86_PMC_IDX_FIXED_BTS) {
 		/* BTS is already occupied. */
 		if (test_and_set_bit(idx, cpuc->used_mask))
 			return -EAGAIN;
 
 		hwc->config_base	= 0;
-		hwc->event_base	= 0;
+		hwc->event_base		= 0;
 		hwc->idx		= idx;
 	} else if (idx >= 0) {
 		/*
@@ -1396,20 +1500,35 @@ static int x86_pmu_enable(struct perf_ev
 	} else {
 		idx = hwc->idx;
 		/* Try to get the previous generic event again */
-		if (test_and_set_bit(idx, cpuc->used_mask)) {
+		if (idx == -1 || test_and_set_bit(idx, cpuc->used_mask)) {
 try_generic:
-			idx = find_first_zero_bit(cpuc->used_mask,
-						  x86_pmu.num_events);
-			if (idx == x86_pmu.num_events)
+			idx = x86_pmu.get_event_idx(cpuc, hwc);
+			if (idx == -1)
 				return -EAGAIN;
 
 			set_bit(idx, cpuc->used_mask);
 			hwc->idx = idx;
 		}
-		hwc->config_base  = x86_pmu.eventsel;
-		hwc->event_base = x86_pmu.perfctr;
+		hwc->config_base = x86_pmu.eventsel;
+		hwc->event_base  = x86_pmu.perfctr;
 	}
 
+	return idx;
+}
+
+/*
+ * Find a PMC slot for the freshly enabled / scheduled in event:
+ */
+static int x86_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	idx = x86_schedule_event(cpuc, hwc);
+	if (idx < 0)
+		return idx;
+
 	perf_events_lapic_init();
 
 	x86_pmu.disable(hwc, idx);
@@ -1520,6 +1639,7 @@ static void intel_pmu_drain_bts_buffer(s
 
 	data.period	= event->hw.last_period;
 	data.addr	= 0;
+	data.raw	= NULL;
 	regs.ip		= 0;
 
 	/*
@@ -1637,6 +1757,7 @@ static int p6_pmu_handle_irq(struct pt_r
 	u64 val;
 
 	data.addr = 0;
+	data.raw = NULL;
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
@@ -1682,6 +1803,7 @@ static int intel_pmu_handle_irq(struct p
 	u64 ack, status;
 
 	data.addr = 0;
+	data.raw = NULL;
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
@@ -1745,6 +1867,7 @@ static int amd_pmu_handle_irq(struct pt_
 	u64 val;
 
 	data.addr = 0;
+	data.raw = NULL;
 
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
@@ -1852,7 +1975,7 @@ static __read_mostly struct notifier_blo
 	.priority		= 1
 };
 
-static struct x86_pmu p6_pmu = {
+static __initconst struct x86_pmu p6_pmu = {
 	.name			= "p6",
 	.handle_irq		= p6_pmu_handle_irq,
 	.disable_all		= p6_pmu_disable_all,
@@ -1877,9 +2000,10 @@ static struct x86_pmu p6_pmu = {
 	 */
 	.event_bits		= 32,
 	.event_mask		= (1ULL << 32) - 1,
+	.get_event_idx		= intel_get_event_idx,
 };
 
-static struct x86_pmu intel_pmu = {
+static __initconst struct x86_pmu intel_pmu = {
 	.name			= "Intel",
 	.handle_irq		= intel_pmu_handle_irq,
 	.disable_all		= intel_pmu_disable_all,
@@ -1900,9 +2024,10 @@ static struct x86_pmu intel_pmu = {
 	.max_period		= (1ULL << 31) - 1,
 	.enable_bts		= intel_pmu_enable_bts,
 	.disable_bts		= intel_pmu_disable_bts,
+	.get_event_idx		= intel_get_event_idx,
 };
 
-static struct x86_pmu amd_pmu = {
+static __initconst struct x86_pmu amd_pmu = {
 	.name			= "AMD",
 	.handle_irq		= amd_pmu_handle_irq,
 	.disable_all		= amd_pmu_disable_all,
@@ -1920,9 +2045,10 @@ static struct x86_pmu amd_pmu = {
 	.apic			= 1,
 	/* use highest bit to detect overflow */
 	.max_period		= (1ULL << 47) - 1,
+	.get_event_idx		= gen_get_event_idx,
 };
 
-static int p6_pmu_init(void)
+static __init int p6_pmu_init(void)
 {
 	switch (boot_cpu_data.x86_model) {
 	case 1:
@@ -1932,10 +2058,12 @@ static int p6_pmu_init(void)
 	case 7:
 	case 8:
 	case 11: /* Pentium III */
+		event_constraints = intel_p6_event_constraints;
 		break;
 	case 9:
 	case 13:
 		/* Pentium M */
+		event_constraints = intel_p6_event_constraints;
 		break;
 	default:
 		pr_cont("unsupported p6 CPU model %d ",
@@ -1945,16 +2073,10 @@ static int p6_pmu_init(void)
 
 	x86_pmu = p6_pmu;
 
-	if (!cpu_has_apic) {
-		pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
-		pr_info("no hardware sampling interrupt available.\n");
-		x86_pmu.apic = 0;
-	}
-
 	return 0;
 }
 
-static int intel_pmu_init(void)
+static __init int intel_pmu_init(void)
 {
 	union cpuid10_edx edx;
 	union cpuid10_eax eax;
@@ -2007,12 +2129,14 @@ static int intel_pmu_init(void)
 		       sizeof(hw_cache_event_ids));
 
 		pr_cont("Core2 events, ");
+		event_constraints = intel_core_event_constraints;
 		break;
 	default:
 	case 26:
 		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 
+		event_constraints = intel_nehalem_event_constraints;
 		pr_cont("Nehalem/Corei7 events, ");
 		break;
 	case 28:
@@ -2025,7 +2149,7 @@ static int intel_pmu_init(void)
 	return 0;
 }
 
-static int amd_pmu_init(void)
+static __init int amd_pmu_init(void)
 {
 	/* Performance-monitoring supported from K7 and later: */
 	if (boot_cpu_data.x86 < 6)
@@ -2040,6 +2164,16 @@ static int amd_pmu_init(void)
 	return 0;
 }
 
+static void __init pmu_check_apic(void)
+{
+	if (cpu_has_apic)
+		return;
+
+	x86_pmu.apic = 0;
+	pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+	pr_info("no hardware sampling interrupt available.\n");
+}
+
 void __init init_hw_perf_events(void)
 {
 	int err;
@@ -2061,6 +2195,8 @@ void __init init_hw_perf_events(void)
 		return;
 	}
 
+	pmu_check_apic();
+
 	pr_cont("%s PMU driver.\n", x86_pmu.name);
 
 	if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
@@ -2105,11 +2241,47 @@ static const struct pmu pmu = {
 	.unthrottle	= x86_pmu_unthrottle,
 };
 
+static int
+validate_event(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct hw_perf_event fake_event = event->hw;
+
+	if (event->pmu && event->pmu != &pmu)
+		return 0;
+
+	return x86_schedule_event(cpuc, &fake_event) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+	struct perf_event *sibling, *leader = event->group_leader;
+	struct cpu_hw_events fake_pmu;
+
+	memset(&fake_pmu, 0, sizeof(fake_pmu));
+
+	if (!validate_event(&fake_pmu, leader))
+		return -ENOSPC;
+
+	list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+		if (!validate_event(&fake_pmu, sibling))
+			return -ENOSPC;
+	}
+
+	if (!validate_event(&fake_pmu, event))
+		return -ENOSPC;
+
+	return 0;
+}
+
 const struct pmu *hw_perf_event_init(struct perf_event *event)
 {
 	int err;
 
 	err = __hw_perf_event_init(event);
+	if (!err) {
+		if (event->group_leader != event)
+			err = validate_group(event);
+	}
 	if (err) {
 		if (event->destroy)
 			event->destroy(event);
@@ -2132,7 +2304,7 @@ void callchain_store(struct perf_callcha
 
 static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
 static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
-static DEFINE_PER_CPU(int, in_nmi_frame);
+static DEFINE_PER_CPU(int, in_ignored_frame);
 
 
 static void
@@ -2148,8 +2320,9 @@ static void backtrace_warning(void *data
 
 static int backtrace_stack(void *data, char *name)
 {
-	per_cpu(in_nmi_frame, smp_processor_id()) =
-			x86_is_stack_id(NMI_STACK, name);
+	per_cpu(in_ignored_frame, smp_processor_id()) =
+			x86_is_stack_id(NMI_STACK, name) ||
+			x86_is_stack_id(DEBUG_STACK, name);
 
 	return 0;
 }
@@ -2158,7 +2331,7 @@ static void backtrace_address(void *data
 {
 	struct perf_callchain_entry *entry = data;
 
-	if (per_cpu(in_nmi_frame, smp_processor_id()))
+	if (per_cpu(in_ignored_frame, smp_processor_id()))
 		return;
 
 	if (reliable)
@@ -2170,6 +2343,7 @@ static const struct stacktrace_ops backt
 	.warning_symbol		= backtrace_warning_symbol,
 	.stack			= backtrace_stack,
 	.address		= backtrace_address,
+	.walk_stack		= print_context_stack_bp,
 };
 
 #include "../dumpstack.h"
@@ -2180,7 +2354,7 @@ perf_callchain_kernel(struct pt_regs *re
 	callchain_store(entry, PERF_CONTEXT_KERNEL);
 	callchain_store(entry, regs->ip);
 
-	dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
+	dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/transmeta.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/transmeta.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpu/transmeta.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpu/transmeta.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,7 @@ static void __cpuinit init_transmeta(str
 
 	early_init_transmeta(c);
 
-	display_cacheinfo(c);
+	cpu_detect_cache_sizes(c);
 
 	/* Print CMS and CPU revision */
 	max = cpuid_eax(0x80860000);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/cpuid.c linux-libre-2.6.33-gnu1/arch/x86/kernel/cpuid.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/cpuid.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/cpuid.c	2010-02-24 13:52:17.000000000 -0500
@@ -116,21 +116,16 @@ static int cpuid_open(struct inode *inod
 {
 	unsigned int cpu;
 	struct cpuinfo_x86 *c;
-	int ret = 0;
-
-	lock_kernel();
 
 	cpu = iminor(file->f_path.dentry->d_inode);
-	if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
-		ret = -ENXIO;	/* No such CPU */
-		goto out;
-	}
+	if (cpu >= nr_cpu_ids || !cpu_online(cpu))
+		return -ENXIO;	/* No such CPU */
+
 	c = &cpu_data(cpu);
 	if (c->cpuid_level < 0)
-		ret = -EIO;	/* CPUID not supported */
-out:
-	unlock_kernel();
-	return ret;
+		return -EIO;	/* CPUID not supported */
+
+	return 0;
 }
 
 /*
@@ -192,7 +187,8 @@ static int __init cpuid_init(void)
 	int i, err = 0;
 	i = 0;
 
-	if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+	if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
+			      "cpu/cpuid", &cpuid_fops)) {
 		printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
 		       CPUID_MAJOR);
 		err = -EBUSY;
@@ -221,7 +217,7 @@ out_class:
 	}
 	class_destroy(cpuid_class);
 out_chrdev:
-	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+	__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
 out:
 	return err;
 }
@@ -233,7 +229,7 @@ static void __exit cpuid_exit(void)
 	for_each_online_cpu(cpu)
 		cpuid_device_destroy(cpu);
 	class_destroy(cpuid_class);
-	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+	__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
 	unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/crash.c linux-libre-2.6.33-gnu1/arch/x86/kernel/crash.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/crash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/crash.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,8 +27,7 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/iommu.h>
-
+#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -106,7 +105,7 @@ void native_machine_crash_shutdown(struc
 #endif
 
 #ifdef CONFIG_X86_64
-	pci_iommu_shutdown();
+	x86_platform.iommu_shutdown();
 #endif
 
 	crash_save_cpu(regs, safe_smp_processor_id());
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/ds.c linux-libre-2.6.33-gnu1/arch/x86/kernel/ds.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/ds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/ds.c	2010-02-24 13:52:17.000000000 -0500
@@ -265,13 +265,13 @@ struct ds_context {
 	int			cpu;
 };
 
-static DEFINE_PER_CPU(struct ds_context *, cpu_context);
+static DEFINE_PER_CPU(struct ds_context *, cpu_ds_context);
 
 
 static struct ds_context *ds_get_context(struct task_struct *task, int cpu)
 {
 	struct ds_context **p_context =
-		(task ? &task->thread.ds_ctx : &per_cpu(cpu_context, cpu));
+		(task ? &task->thread.ds_ctx : &per_cpu(cpu_ds_context, cpu));
 	struct ds_context *context = NULL;
 	struct ds_context *new_context = NULL;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,9 +10,9 @@
 #include <linux/module.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
+#include <linux/sysfs.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
-#include <linux/sysfs.h>
 
 #include <asm/stacktrace.h>
 
@@ -35,6 +35,7 @@ void dump_trace(struct task_struct *task
 
 	if (!stack) {
 		unsigned long dummy;
+
 		stack = &dummy;
 		if (task && task != current)
 			stack = (unsigned long *)task->thread.sp;
@@ -57,8 +58,7 @@ void dump_trace(struct task_struct *task
 
 		context = (struct thread_info *)
 			((unsigned long)stack & (~(THREAD_SIZE - 1)));
-		bp = print_context_stack(context, stack, bp, ops,
-					 data, NULL, &graph);
+		bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
 
 		stack = (unsigned long *)context->previous_esp;
 		if (!stack)
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(dump_trace);
 
 void
 show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
-		unsigned long *sp, unsigned long bp, char *log_lvl)
+		   unsigned long *sp, unsigned long bp, char *log_lvl)
 {
 	unsigned long *stack;
 	int i;
@@ -156,4 +156,3 @@ int is_valid_bugaddr(unsigned long ip)
 
 	return ud2 == 0x0b0f;
 }
-
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,26 +10,28 @@
 #include <linux/module.h>
 #include <linux/ptrace.h>
 #include <linux/kexec.h>
+#include <linux/sysfs.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
-#include <linux/sysfs.h>
 
 #include <asm/stacktrace.h>
 
 #include "dumpstack.h"
 
+#define N_EXCEPTION_STACKS_END \
+		(N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2)
 
 static char x86_stack_ids[][8] = {
-		[DEBUG_STACK - 1] = "#DB",
-		[NMI_STACK - 1] = "NMI",
-		[DOUBLEFAULT_STACK - 1] = "#DF",
-		[STACKFAULT_STACK - 1] = "#SS",
-		[MCE_STACK - 1] = "#MC",
+		[ DEBUG_STACK-1			]	= "#DB",
+		[ NMI_STACK-1			]	= "NMI",
+		[ DOUBLEFAULT_STACK-1		]	= "#DF",
+		[ STACKFAULT_STACK-1		]	= "#SS",
+		[ MCE_STACK-1			]	= "#MC",
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
-		[N_EXCEPTION_STACKS ...
-			N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
+		[ N_EXCEPTION_STACKS ...
+		  N_EXCEPTION_STACKS_END	]	= "#DB[?]"
 #endif
-	};
+};
 
 int x86_is_stack_id(int id, char *name)
 {
@@ -37,7 +39,7 @@ int x86_is_stack_id(int id, char *name)
 }
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
-					unsigned *usedp, char **idp)
+					 unsigned *usedp, char **idp)
 {
 	unsigned k;
 
@@ -101,6 +103,35 @@ static unsigned long *in_exception_stack
 	return NULL;
 }
 
+static inline int
+in_irq_stack(unsigned long *stack, unsigned long *irq_stack,
+	     unsigned long *irq_stack_end)
+{
+	return (stack >= irq_stack && stack < irq_stack_end);
+}
+
+/*
+ * We are returning from the irq stack and go to the previous one.
+ * If the previous stack is also in the irq stack, then bp in the first
+ * frame of the irq stack points to the previous, interrupted one.
+ * Otherwise we have another level of indirection: We first save
+ * the bp of the previous stack, then we switch the stack to the irq one
+ * and save a new bp that links to the previous one.
+ * (See save_args())
+ */
+static inline unsigned long
+fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
+		  unsigned long *irq_stack, unsigned long *irq_stack_end)
+{
+#ifdef CONFIG_FRAME_POINTER
+	struct stack_frame *frame = (struct stack_frame *)bp;
+
+	if (!in_irq_stack(stack, irq_stack, irq_stack_end))
+		return (unsigned long)frame->next_frame;
+#endif
+	return bp;
+}
+
 /*
  * x86-64 can have up to three kernel stacks:
  * process stack
@@ -157,8 +188,8 @@ void dump_trace(struct task_struct *task
 			if (ops->stack(data, id) < 0)
 				break;
 
-			bp = print_context_stack(tinfo, stack, bp, ops,
-						 data, estack_end, &graph);
+			bp = ops->walk_stack(tinfo, stack, bp, ops,
+					     data, estack_end, &graph);
 			ops->stack(data, "<EOE>");
 			/*
 			 * We link to the next stack via the
@@ -173,7 +204,7 @@ void dump_trace(struct task_struct *task
 			irq_stack = irq_stack_end -
 				(IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);
 
-			if (stack >= irq_stack && stack < irq_stack_end) {
+			if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
 				if (ops->stack(data, "IRQ") < 0)
 					break;
 				bp = print_context_stack(tinfo, stack, bp,
@@ -184,6 +215,8 @@ void dump_trace(struct task_struct *task
 				 * pointer (index -1 to end) in the IRQ stack:
 				 */
 				stack = (unsigned long *) (irq_stack_end[-1]);
+				bp = fixup_bp_irq_link(bp, stack, irq_stack,
+						       irq_stack_end);
 				irq_stack_end = NULL;
 				ops->stack(data, "EOI");
 				continue;
@@ -202,21 +235,24 @@ EXPORT_SYMBOL(dump_trace);
 
 void
 show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
-		unsigned long *sp, unsigned long bp, char *log_lvl)
+		   unsigned long *sp, unsigned long bp, char *log_lvl)
 {
+	unsigned long *irq_stack_end;
+	unsigned long *irq_stack;
 	unsigned long *stack;
+	int cpu;
 	int i;
-	const int cpu = smp_processor_id();
-	unsigned long *irq_stack_end =
-		(unsigned long *)(per_cpu(irq_stack_ptr, cpu));
-	unsigned long *irq_stack =
-		(unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE);
+
+	preempt_disable();
+	cpu = smp_processor_id();
+
+	irq_stack_end	= (unsigned long *)(per_cpu(irq_stack_ptr, cpu));
+	irq_stack	= (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE);
 
 	/*
-	 * debugging aid: "show_stack(NULL, NULL);" prints the
-	 * back trace for this cpu.
+	 * Debugging aid: "show_stack(NULL, NULL);" prints the
+	 * back trace for this cpu:
 	 */
-
 	if (sp == NULL) {
 		if (task)
 			sp = (unsigned long *)task->thread.sp;
@@ -240,6 +276,8 @@ show_stack_log_lvl(struct task_struct *t
 		printk(" %016lx", *stack++);
 		touch_nmi_watchdog();
 	}
+	preempt_enable();
+
 	printk("\n");
 	show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 }
@@ -303,4 +341,3 @@ int is_valid_bugaddr(unsigned long ip)
 
 	return ud2 == 0x0b0f;
 }
-
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack.c linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,6 +109,32 @@ print_context_stack(struct thread_info *
 	}
 	return bp;
 }
+EXPORT_SYMBOL_GPL(print_context_stack);
+
+unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+		       unsigned long *stack, unsigned long bp,
+		       const struct stacktrace_ops *ops, void *data,
+		       unsigned long *end, int *graph)
+{
+	struct stack_frame *frame = (struct stack_frame *)bp;
+	unsigned long *ret_addr = &frame->return_address;
+
+	while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
+		unsigned long addr = *ret_addr;
+
+		if (!__kernel_text_address(addr))
+			break;
+
+		ops->address(data, addr, 1);
+		frame = frame->next_frame;
+		ret_addr = &frame->return_address;
+		print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
+	}
+
+	return (unsigned long)frame;
+}
+EXPORT_SYMBOL_GPL(print_context_stack_bp);
 
 
 static void
@@ -141,10 +167,11 @@ static void print_trace_address(void *da
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-	.warning = print_trace_warning,
-	.warning_symbol = print_trace_warning_symbol,
-	.stack = print_trace_stack,
-	.address = print_trace_address,
+	.warning		= print_trace_warning,
+	.warning_symbol		= print_trace_warning_symbol,
+	.stack			= print_trace_stack,
+	.address		= print_trace_address,
+	.walk_stack		= print_context_stack,
 };
 
 void
@@ -188,7 +215,7 @@ void dump_stack(void)
 }
 EXPORT_SYMBOL(dump_stack);
 
-static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
+static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 static int die_owner = -1;
 static unsigned int die_nest_count;
 
@@ -207,11 +234,11 @@ unsigned __kprobes long oops_begin(void)
 	/* racy, but better than risking deadlock. */
 	raw_local_irq_save(flags);
 	cpu = smp_processor_id();
-	if (!__raw_spin_trylock(&die_lock)) {
+	if (!arch_spin_trylock(&die_lock)) {
 		if (cpu == die_owner)
 			/* nested oops. should stop eventually */;
 		else
-			__raw_spin_lock(&die_lock);
+			arch_spin_lock(&die_lock);
 	}
 	die_nest_count++;
 	die_owner = cpu;
@@ -231,7 +258,7 @@ void __kprobes oops_end(unsigned long fl
 	die_nest_count--;
 	if (!die_nest_count)
 		/* Nest count reaches zero, release the lock. */
-		__raw_spin_unlock(&die_lock);
+		arch_spin_unlock(&die_lock);
 	raw_local_irq_restore(flags);
 	oops_exit();
 
@@ -268,11 +295,12 @@ int __kprobes __die(const char *str, str
 
 	show_registers(regs);
 #ifdef CONFIG_X86_32
-	sp = (unsigned long) (&regs->sp);
-	savesegment(ss, ss);
-	if (user_mode(regs)) {
+	if (user_mode_vm(regs)) {
 		sp = regs->sp;
 		ss = regs->ss & 0xffff;
+	} else {
+		sp = kernel_stack_pointer(regs);
+		savesegment(ss, ss);
 	}
 	printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
 	print_symbol("%s", regs->ip);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack.h linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.h
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/dumpstack.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/dumpstack.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,12 +14,6 @@
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
-extern unsigned long
-print_context_stack(struct thread_info *tinfo,
-		unsigned long *stack, unsigned long bp,
-		const struct stacktrace_ops *ops, void *data,
-		unsigned long *end, int *graph);
-
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 		unsigned long *stack, unsigned long bp, char *log_lvl);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/e820.c linux-libre-2.6.33-gnu1/arch/x86/kernel/e820.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/e820.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/e820.c	2010-02-24 13:52:17.000000000 -0500
@@ -724,7 +724,7 @@ core_initcall(e820_mark_nvs_memory);
 /*
  * Early reserved memory areas.
  */
-#define MAX_EARLY_RES 20
+#define MAX_EARLY_RES 32
 
 struct early_res {
 	u64 start, end;
@@ -732,7 +732,16 @@ struct early_res {
 	char overlap_ok;
 };
 static struct early_res early_res[MAX_EARLY_RES] __initdata = {
-	{ 0, PAGE_SIZE, "BIOS data page" },	/* BIOS data page */
+	{ 0, PAGE_SIZE, "BIOS data page", 1 },	/* BIOS data page */
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_TRAMPOLINE)
+	/*
+	 * But first pinch a few for the stack/trampoline stuff
+	 * FIXME: Don't need the extra page at 4K, but need to fix
+	 * trampoline before removing it. (see the GDT stuff)
+	 */
+	{ PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE", 1 },
+#endif
+
 	{}
 };
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/entry_32.S linux-libre-2.6.33-gnu1/arch/x86/kernel/entry_32.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/entry_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/entry_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -334,6 +334,10 @@ ENTRY(ret_from_fork)
 END(ret_from_fork)
 
 /*
+ * Interrupt exit functions should be protected against kprobes
+ */
+	.pushsection .kprobes.text, "ax"
+/*
  * Return to user mode is not as complex as all this looks,
  * but we want the default path for a system call return to
  * go as quickly as possible which is why some of this is
@@ -383,6 +387,10 @@ need_resched:
 END(resume_kernel)
 #endif
 	CFI_ENDPROC
+/*
+ * End of kprobes section
+ */
+	.popsection
 
 /* SYSENTER_RETURN points to after the "sysenter" instruction in
    the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
@@ -513,6 +521,10 @@ sysexit_audit:
 	PTGS_TO_GS_EX
 ENDPROC(ia32_sysenter_target)
 
+/*
+ * syscall stub including irq exit should be protected against kprobes
+ */
+	.pushsection .kprobes.text, "ax"
 	# system call handler stub
 ENTRY(system_call)
 	RING0_INT_FRAME			# can't unwind into user space anyway
@@ -705,26 +717,69 @@ syscall_badsys:
 	jmp resume_userspace
 END(syscall_badsys)
 	CFI_ENDPROC
+/*
+ * End of kprobes section
+ */
+	.popsection
 
 /*
  * System calls that need a pt_regs pointer.
  */
-#define PTREGSCALL(name) \
+#define PTREGSCALL0(name) \
 	ALIGN; \
 ptregs_##name: \
 	leal 4(%esp),%eax; \
 	jmp sys_##name;
 
-PTREGSCALL(iopl)
-PTREGSCALL(fork)
-PTREGSCALL(clone)
-PTREGSCALL(vfork)
-PTREGSCALL(execve)
-PTREGSCALL(sigaltstack)
-PTREGSCALL(sigreturn)
-PTREGSCALL(rt_sigreturn)
-PTREGSCALL(vm86)
-PTREGSCALL(vm86old)
+#define PTREGSCALL1(name) \
+	ALIGN; \
+ptregs_##name: \
+	leal 4(%esp),%edx; \
+	movl (PT_EBX+4)(%esp),%eax; \
+	jmp sys_##name;
+
+#define PTREGSCALL2(name) \
+	ALIGN; \
+ptregs_##name: \
+	leal 4(%esp),%ecx; \
+	movl (PT_ECX+4)(%esp),%edx; \
+	movl (PT_EBX+4)(%esp),%eax; \
+	jmp sys_##name;
+
+#define PTREGSCALL3(name) \
+	ALIGN; \
+ptregs_##name: \
+	leal 4(%esp),%eax; \
+	pushl %eax; \
+	movl PT_EDX(%eax),%ecx; \
+	movl PT_ECX(%eax),%edx; \
+	movl PT_EBX(%eax),%eax; \
+	call sys_##name; \
+	addl $4,%esp; \
+	ret
+
+PTREGSCALL1(iopl)
+PTREGSCALL0(fork)
+PTREGSCALL0(vfork)
+PTREGSCALL3(execve)
+PTREGSCALL2(sigaltstack)
+PTREGSCALL0(sigreturn)
+PTREGSCALL0(rt_sigreturn)
+PTREGSCALL2(vm86)
+PTREGSCALL1(vm86old)
+
+/* Clone is an oddball.  The 4th arg is in %edi */
+	ALIGN;
+ptregs_clone:
+	leal 4(%esp),%eax
+	pushl %eax
+	pushl PT_EDI(%eax)
+	movl PT_EDX(%eax),%ecx
+	movl PT_ECX(%eax),%edx
+	movl PT_EBX(%eax),%eax
+	call sys_clone
+	addl $8,%esp
+	ret
 
 .macro FIXUP_ESPFIX_STACK
 /*
@@ -814,6 +869,10 @@ common_interrupt:
 ENDPROC(common_interrupt)
 	CFI_ENDPROC
 
+/*
+ *  Irq entries should be protected against kprobes
+ */
+	.pushsection .kprobes.text, "ax"
 #define BUILD_INTERRUPT3(name, nr, fn)	\
 ENTRY(name)				\
 	RING0_INT_FRAME;		\
@@ -980,16 +1039,16 @@ ENTRY(spurious_interrupt_bug)
 	jmp error_code
 	CFI_ENDPROC
 END(spurious_interrupt_bug)
+/*
+ * End of kprobes section
+ */
+	.popsection
 
 ENTRY(kernel_thread_helper)
 	pushl $0		# fake return address for unwinder
 	CFI_STARTPROC
-	movl %edx,%eax
-	push %edx
-	CFI_ADJUST_CFA_OFFSET 4
-	call *%ebx
-	push %eax
-	CFI_ADJUST_CFA_OFFSET 4
+	movl %edi,%eax
+	call *%esi
 	call do_exit
 	ud2			# padding for call trace
 	CFI_ENDPROC
@@ -1185,17 +1244,14 @@ END(ftrace_graph_caller)
 
 .globl return_to_handler
 return_to_handler:
-	pushl $0
 	pushl %eax
-	pushl %ecx
 	pushl %edx
 	movl %ebp, %eax
 	call ftrace_return_to_handler
-	movl %eax, 0xc(%esp)
+	movl %eax, %ecx
 	popl %edx
-	popl %ecx
 	popl %eax
-	ret
+	jmp *%ecx
 #endif
 
 .section .rodata,"a"
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/entry_64.S linux-libre-2.6.33-gnu1/arch/x86/kernel/entry_64.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/entry_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/entry_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -155,11 +155,11 @@ GLOBAL(return_to_handler)
 
 	call ftrace_return_to_handler
 
-	movq %rax, 16(%rsp)
+	movq %rax, %rdi
 	movq 8(%rsp), %rdx
 	movq (%rsp), %rax
-	addq $16, %rsp
-	retq
+	addq $24, %rsp
+	jmp *%rdi
 #endif
 
 
@@ -803,6 +803,10 @@ END(interrupt)
 	call \func
 	.endm
 
+/*
+ * Interrupt entry/exit should be protected against kprobes
+ */
+	.pushsection .kprobes.text, "ax"
 	/*
 	 * The interrupt stubs push (~vector+0x80) onto the stack and
 	 * then jump to common_interrupt.
@@ -941,6 +945,10 @@ ENTRY(retint_kernel)
 
 	CFI_ENDPROC
 END(common_interrupt)
+/*
+ * End of kprobes section
+ */
+       .popsection
 
 /*
  * APIC interrupts.
@@ -969,8 +977,8 @@ apicinterrupt UV_BAU_MESSAGE \
 #endif
 apicinterrupt LOCAL_TIMER_VECTOR \
 	apic_timer_interrupt smp_apic_timer_interrupt
-apicinterrupt GENERIC_INTERRUPT_VECTOR \
-	generic_interrupt smp_generic_interrupt
+apicinterrupt X86_PLATFORM_IPI_VECTOR \
+	x86_platform_ipi smp_x86_platform_ipi
 
 #ifdef CONFIG_SMP
 apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \
@@ -1068,10 +1076,10 @@ ENTRY(\sym)
 	TRACE_IRQS_OFF
 	movq %rsp,%rdi		/* pt_regs pointer */
 	xorl %esi,%esi		/* no error code */
-	PER_CPU(init_tss, %rbp)
-	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
+	PER_CPU(init_tss, %r12)
+	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
 	call \do_sym
-	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
+	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
 	jmp paranoid_exit	/* %ebx: no swapgs flag */
 	CFI_ENDPROC
 END(\sym)
@@ -1158,63 +1166,20 @@ bad_gs:
 	jmp  2b
 	.previous
 
-/*
- * Create a kernel thread.
- *
- * C extern interface:
- *	extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- *
- * asm input arguments:
- *	rdi: fn, rsi: arg, rdx: flags
- */
-ENTRY(kernel_thread)
-	CFI_STARTPROC
-	FAKE_STACK_FRAME $child_rip
-	SAVE_ALL
-
-	# rdi: flags, rsi: usp, rdx: will be &pt_regs
-	movq %rdx,%rdi
-	orq  kernel_thread_flags(%rip),%rdi
-	movq $-1, %rsi
-	movq %rsp, %rdx
-
-	xorl %r8d,%r8d
-	xorl %r9d,%r9d
-
-	# clone now
-	call do_fork
-	movq %rax,RAX(%rsp)
-	xorl %edi,%edi
-
-	/*
-	 * It isn't worth to check for reschedule here,
-	 * so internally to the x86_64 port you can rely on kernel_thread()
-	 * not to reschedule the child before returning, this avoids the need
-	 * of hacks for example to fork off the per-CPU idle tasks.
-	 * [Hopefully no generic code relies on the reschedule -AK]
-	 */
-	RESTORE_ALL
-	UNFAKE_STACK_FRAME
-	ret
-	CFI_ENDPROC
-END(kernel_thread)
-
-ENTRY(child_rip)
+ENTRY(kernel_thread_helper)
 	pushq $0		# fake return address
 	CFI_STARTPROC
 	/*
 	 * Here we are in the child and the registers are set as they were
 	 * at kernel_thread() invocation in the parent.
 	 */
-	movq %rdi, %rax
-	movq %rsi, %rdi
-	call *%rax
+	call *%rsi
 	# exit
 	mov %eax, %edi
 	call do_exit
 	ud2			# padding for call trace
 	CFI_ENDPROC
-END(child_rip)
+END(kernel_thread_helper)
 
 /*
  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
@@ -1491,12 +1456,17 @@ error_kernelspace:
 	leaq irq_return(%rip),%rcx
 	cmpq %rcx,RIP+8(%rsp)
 	je error_swapgs
-	movl %ecx,%ecx	/* zero extend */
-	cmpq %rcx,RIP+8(%rsp)
-	je error_swapgs
+	movl %ecx,%eax	/* zero extend */
+	cmpq %rax,RIP+8(%rsp)
+	je bstep_iret
 	cmpq $gs_change,RIP+8(%rsp)
 	je error_swapgs
 	jmp error_sti
+
+bstep_iret:
+	/* Fix truncated RIP */
+	movq %rcx,RIP+8(%rsp)
+	jmp error_swapgs
 END(error_entry)
 
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/ftrace.c linux-libre-2.6.33-gnu1/arch/x86/kernel/ftrace.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/ftrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/ftrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,8 @@
  * the dangers of modifying code on the run.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/spinlock.h>
 #include <linux/hardirq.h>
 #include <linux/uaccess.h>
@@ -187,9 +189,26 @@ static void wait_for_nmi(void)
 	nmi_wait_count++;
 }
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
 static int
 do_ftrace_mod_code(unsigned long ip, void *new_code)
 {
+	/*
+	 * On x86_64, kernel text mappings are mapped read-only with
+	 * CONFIG_DEBUG_RODATA. So we use the kernel identity mapping instead
+	 * of the kernel text mapping to modify the kernel text.
+	 *
+	 * For 32bit kernels, these mappings are same and we can use
+	 * kernel identity mapping to modify code.
+	 */
+	if (within(ip, (unsigned long)_text, (unsigned long)_etext))
+		ip = (unsigned long)__va(__pa(ip));
+
 	mod_code_ip = (void *)ip;
 	mod_code_newcode = new_code;
 
@@ -336,15 +355,15 @@ int __init ftrace_dyn_arch_init(void *da
 
 	switch (faulted) {
 	case 0:
-		pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n");
+		pr_info("converting mcount calls to 0f 1f 44 00 00\n");
 		memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE);
 		break;
 	case 1:
-		pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n");
+		pr_info("converting mcount calls to 66 66 66 66 90\n");
 		memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE);
 		break;
 	case 2:
-		pr_info("ftrace: converting mcount calls to jmp . + 5\n");
+		pr_info("converting mcount calls to jmp . + 5\n");
 		memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE);
 		break;
 	}
@@ -468,82 +487,10 @@ void prepare_ftrace_return(unsigned long
 
 #ifdef CONFIG_FTRACE_SYSCALLS
 
-extern unsigned long __start_syscalls_metadata[];
-extern unsigned long __stop_syscalls_metadata[];
 extern unsigned long *sys_call_table;
 
-static struct syscall_metadata **syscalls_metadata;
-
-static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
-{
-	struct syscall_metadata *start;
-	struct syscall_metadata *stop;
-	char str[KSYM_SYMBOL_LEN];
-
-
-	start = (struct syscall_metadata *)__start_syscalls_metadata;
-	stop = (struct syscall_metadata *)__stop_syscalls_metadata;
-	kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
-
-	for ( ; start < stop; start++) {
-		if (start->name && !strcmp(start->name, str))
-			return start;
-	}
-	return NULL;
-}
-
-struct syscall_metadata *syscall_nr_to_meta(int nr)
-{
-	if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
-		return NULL;
-
-	return syscalls_metadata[nr];
-}
-
-int syscall_name_to_nr(char *name)
-{
-	int i;
-
-	if (!syscalls_metadata)
-		return -1;
-
-	for (i = 0; i < NR_syscalls; i++) {
-		if (syscalls_metadata[i]) {
-			if (!strcmp(syscalls_metadata[i]->name, name))
-				return i;
-		}
-	}
-	return -1;
-}
-
-void set_syscall_enter_id(int num, int id)
-{
-	syscalls_metadata[num]->enter_id = id;
-}
-
-void set_syscall_exit_id(int num, int id)
-{
-	syscalls_metadata[num]->exit_id = id;
-}
-
-static int __init arch_init_ftrace_syscalls(void)
+unsigned long __init arch_syscall_addr(int nr)
 {
-	int i;
-	struct syscall_metadata *meta;
-	unsigned long **psys_syscall_table = &sys_call_table;
-
-	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
-					NR_syscalls, GFP_KERNEL);
-	if (!syscalls_metadata) {
-		WARN_ON(1);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < NR_syscalls; i++) {
-		meta = find_syscall_meta(psys_syscall_table[i]);
-		syscalls_metadata[i] = meta;
-	}
-	return 0;
+	return (unsigned long)(&sys_call_table)[nr];
 }
-arch_initcall(arch_init_ftrace_syscalls);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/geode_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/geode_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/geode_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/geode_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-/*
- * AMD Geode southbridge support code
- * Copyright (C) 2006, Advanced Micro Devices, Inc.
- * Copyright (C) 2007, Andres Salomon <dilinger@debian.org>
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <asm/msr.h>
-#include <asm/geode.h>
-
-static struct {
-	char *name;
-	u32 msr;
-	int size;
-	u32 base;
-} lbars[] = {
-	{ "geode-pms",   MSR_LBAR_PMS, LBAR_PMS_SIZE, 0 },
-	{ "geode-acpi",  MSR_LBAR_ACPI, LBAR_ACPI_SIZE, 0 },
-	{ "geode-gpio",  MSR_LBAR_GPIO, LBAR_GPIO_SIZE, 0 },
-	{ "geode-mfgpt", MSR_LBAR_MFGPT, LBAR_MFGPT_SIZE, 0 }
-};
-
-static void __init init_lbars(void)
-{
-	u32 lo, hi;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(lbars); i++) {
-		rdmsr(lbars[i].msr, lo, hi);
-		if (hi & 0x01)
-			lbars[i].base = lo & 0x0000ffff;
-
-		if (lbars[i].base == 0)
-			printk(KERN_ERR "geode:  Couldn't initialize '%s'\n",
-					lbars[i].name);
-	}
-}
-
-int geode_get_dev_base(unsigned int dev)
-{
-	BUG_ON(dev >= ARRAY_SIZE(lbars));
-	return lbars[dev].base;
-}
-EXPORT_SYMBOL_GPL(geode_get_dev_base);
-
-/* === GPIO API === */
-
-void geode_gpio_set(u32 gpio, unsigned int reg)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
-
-	if (!base)
-		return;
-
-	/* low bank register */
-	if (gpio & 0xFFFF)
-		outl(gpio & 0xFFFF, base + reg);
-	/* high bank register */
-	gpio >>= 16;
-	if (gpio)
-		outl(gpio, base + 0x80 + reg);
-}
-EXPORT_SYMBOL_GPL(geode_gpio_set);
-
-void geode_gpio_clear(u32 gpio, unsigned int reg)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
-
-	if (!base)
-		return;
-
-	/* low bank register */
-	if (gpio & 0xFFFF)
-		outl((gpio & 0xFFFF) << 16, base + reg);
-	/* high bank register */
-	gpio &= (0xFFFF << 16);
-	if (gpio)
-		outl(gpio, base + 0x80 + reg);
-}
-EXPORT_SYMBOL_GPL(geode_gpio_clear);
-
-int geode_gpio_isset(u32 gpio, unsigned int reg)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
-	u32 val;
-
-	if (!base)
-		return 0;
-
-	/* low bank register */
-	if (gpio & 0xFFFF) {
-		val = inl(base + reg) & (gpio & 0xFFFF);
-		if ((gpio & 0xFFFF) == val)
-			return 1;
-	}
-	/* high bank register */
-	gpio >>= 16;
-	if (gpio) {
-		val = inl(base + 0x80 + reg) & gpio;
-		if (gpio == val)
-			return 1;
-	}
-	return 0;
-}
-EXPORT_SYMBOL_GPL(geode_gpio_isset);
-
-void geode_gpio_set_irq(unsigned int group, unsigned int irq)
-{
-	u32 lo, hi;
-
-	if (group > 7 || irq > 15)
-		return;
-
-	rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
-
-	lo &= ~(0xF << (group * 4));
-	lo |= (irq & 0xF) << (group * 4);
-
-	wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
-}
-EXPORT_SYMBOL_GPL(geode_gpio_set_irq);
-
-void geode_gpio_setup_event(unsigned int gpio, int pair, int pme)
-{
-	u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
-	u32 offset, shift, val;
-
-	if (gpio >= 24)
-		offset = GPIO_MAP_W;
-	else if (gpio >= 16)
-		offset = GPIO_MAP_Z;
-	else if (gpio >= 8)
-		offset = GPIO_MAP_Y;
-	else
-		offset = GPIO_MAP_X;
-
-	shift = (gpio % 8) * 4;
-
-	val = inl(base + offset);
-
-	/* Clear whatever was there before */
-	val &= ~(0xF << shift);
-
-	/* And set the new value */
-
-	val |= ((pair & 7) << shift);
-
-	/* Set the PME bit if this is a PME event */
-
-	if (pme)
-		val |= (1 << (shift + 3));
-
-	outl(val, base + offset);
-}
-EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
-
-int geode_has_vsa2(void)
-{
-	static int has_vsa2 = -1;
-
-	if (has_vsa2 == -1) {
-		u16 val;
-
-		/*
-		 * The VSA has virtual registers that we can query for a
-		 * signature.
-		 */
-		outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
-		outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
-
-		val = inw(VSA_VRC_DATA);
-		has_vsa2 = (val == AMD_VSA_SIG || val == GSW_VSA_SIG);
-	}
-
-	return has_vsa2;
-}
-EXPORT_SYMBOL_GPL(geode_has_vsa2);
-
-static int __init geode_southbridge_init(void)
-{
-	if (!is_geode())
-		return -ENODEV;
-
-	init_lbars();
-	(void) mfgpt_timer_setup();
-	return 0;
-}
-
-postcore_initcall(geode_southbridge_init);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/head32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/head32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/head32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/head32.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,8 +29,6 @@ static void __init i386_default_early_se
 
 void __init i386_start_kernel(void)
 {
-	reserve_trampoline_memory();
-
 	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/head_32.S linux-libre-2.6.33-gnu1/arch/x86/kernel/head_32.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/head_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/head_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,8 @@
 #include <asm/asm-offsets.h>
 #include <asm/setup.h>
 #include <asm/processor-flags.h>
+#include <asm/msr-index.h>
+#include <asm/cpufeature.h>
 #include <asm/percpu.h>
 
 /* Physical address */
@@ -297,25 +299,27 @@ ENTRY(startup_32_smp)
 	orl %edx,%eax
 	movl %eax,%cr4
 
-	btl $5, %eax		# check if PAE is enabled
-	jnc 6f
+	testb $X86_CR4_PAE, %al		# check if PAE is enabled
+	jz 6f
 
 	/* Check if extended functions are implemented */
 	movl $0x80000000, %eax
 	cpuid
-	cmpl $0x80000000, %eax
-	jbe 6f
+	/* Value must be in the range 0x80000001 to 0x8000ffff */
+	subl $0x80000001, %eax
+	cmpl $(0x8000ffff-0x80000001), %eax
+	ja 6f
 	mov $0x80000001, %eax
 	cpuid
 	/* Execute Disable bit supported? */
-	btl $20, %edx
+	btl $(X86_FEATURE_NX & 31), %edx
 	jnc 6f
 
 	/* Setup EFER (Extended Feature Enable Register) */
-	movl $0xc0000080, %ecx
+	movl $MSR_EFER, %ecx
 	rdmsr
 
-	btsl $11, %eax
+	btsl $_EFER_NX, %eax
 	/* Make changes effective */
 	wrmsr
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/head64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/head64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/head64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/head64.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,8 +98,6 @@ void __init x86_64_start_reservations(ch
 {
 	copy_bootdata(__va(real_mode_data));
 
-	reserve_trampoline_memory();
-
 	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/head_64.S linux-libre-2.6.33-gnu1/arch/x86/kernel/head_64.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/head_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/head_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -212,8 +212,8 @@ ENTRY(secondary_startup_64)
 	 */
 	lgdt	early_gdt_descr(%rip)
 
-	/* set up data segments. actually 0 would do too */
-	movl $__KERNEL_DS,%eax
+	/* set up data segments */
+	xorl %eax,%eax
 	movl %eax,%ds
 	movl %eax,%ss
 	movl %eax,%es
@@ -262,11 +262,11 @@ ENTRY(secondary_startup_64)
 	.quad	x86_64_start_kernel
 	ENTRY(initial_gs)
 	.quad	INIT_PER_CPU_VAR(irq_stack_union)
-	__FINITDATA
 
 	ENTRY(stack_start)
 	.quad  init_thread_union+THREAD_SIZE-8
 	.word  0
+	__FINITDATA
 
 bad_address:
 	jmp bad_address
@@ -340,6 +340,7 @@ ENTRY(name)
 	i = i + 1 ;					\
 	.endr
 
+	.data
 	/*
 	 * This default setting generates an ident mapping at address 0x100000
 	 * and a mapping for the kernel that precisely maps virtual address
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/hpet.c linux-libre-2.6.33-gnu1/arch/x86/kernel/hpet.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/hpet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/hpet.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,9 @@
  * HPET address is set in acpi/boot.c, when an ACPI entry exists
  */
 unsigned long				hpet_address;
+u8					hpet_blockid; /* OS timer block num */
+u8					hpet_msi_disable;
+
 #ifdef CONFIG_PCI_MSI
 static unsigned long			hpet_num_timers;
 #endif
@@ -47,12 +50,12 @@ struct hpet_dev {
 	char				name[10];
 };
 
-unsigned long hpet_readl(unsigned long a)
+inline unsigned int hpet_readl(unsigned int a)
 {
 	return readl(hpet_virt_address + a);
 }
 
-static inline void hpet_writel(unsigned long d, unsigned long a)
+static inline void hpet_writel(unsigned int d, unsigned int a)
 {
 	writel(d, hpet_virt_address + a);
 }
@@ -167,7 +170,7 @@ do {								\
 
 static void hpet_reserve_msi_timers(struct hpet_data *hd);
 
-static void hpet_reserve_platform_timers(unsigned long id)
+static void hpet_reserve_platform_timers(unsigned int id)
 {
 	struct hpet __iomem *hpet = hpet_virt_address;
 	struct hpet_timer __iomem *timer = &hpet->hpet_timers[2];
@@ -205,7 +208,7 @@ static void hpet_reserve_platform_timers
 
 }
 #else
-static void hpet_reserve_platform_timers(unsigned long id) { }
+static void hpet_reserve_platform_timers(unsigned int id) { }
 #endif
 
 /*
@@ -246,7 +249,7 @@ static void hpet_reset_counter(void)
 
 static void hpet_start_counter(void)
 {
-	unsigned long cfg = hpet_readl(HPET_CFG);
+	unsigned int cfg = hpet_readl(HPET_CFG);
 	cfg |= HPET_CFG_ENABLE;
 	hpet_writel(cfg, HPET_CFG);
 }
@@ -271,7 +274,7 @@ static void hpet_resume_counter(void)
 
 static void hpet_enable_legacy_int(void)
 {
-	unsigned long cfg = hpet_readl(HPET_CFG);
+	unsigned int cfg = hpet_readl(HPET_CFG);
 
 	cfg |= HPET_CFG_LEGACY;
 	hpet_writel(cfg, HPET_CFG);
@@ -314,7 +317,7 @@ static int hpet_setup_msi_irq(unsigned i
 static void hpet_set_mode(enum clock_event_mode mode,
 			  struct clock_event_device *evt, int timer)
 {
-	unsigned long cfg, cmp, now;
+	unsigned int cfg, cmp, now;
 	uint64_t delta;
 
 	switch (mode) {
@@ -323,7 +326,7 @@ static void hpet_set_mode(enum clock_eve
 		delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
 		delta >>= evt->shift;
 		now = hpet_readl(HPET_COUNTER);
-		cmp = now + (unsigned long) delta;
+		cmp = now + (unsigned int) delta;
 		cfg = hpet_readl(HPET_Tn_CFG(timer));
 		/* Make sure we use edge triggered interrupts */
 		cfg &= ~HPET_TN_LEVEL;
@@ -339,7 +342,7 @@ static void hpet_set_mode(enum clock_eve
 		 * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
 		 * Publication # 24674)
 		 */
-		hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
+		hpet_writel((unsigned int) delta, HPET_Tn_CMP(timer));
 		hpet_start_counter();
 		hpet_print_config();
 		break;
@@ -383,13 +386,24 @@ static int hpet_next_event(unsigned long
 	hpet_writel(cnt, HPET_Tn_CMP(timer));
 
 	/*
-	 * We need to read back the CMP register to make sure that
-	 * what we wrote hit the chip before we compare it to the
-	 * counter.
+	 * We need to read back the CMP register on certain HPET
+	 * implementations (ATI chipsets) which seem to delay the
+	 * transfer of the compare register into the internal compare
+	 * logic. With small deltas this might actually be too late as
+	 * the counter could already be higher than the compare value
+	 * at that point and we would wait for the next hpet interrupt
+	 * forever. We found out that reading the CMP register back
+	 * forces the transfer so we can rely on the comparison with
+	 * the counter register below. If the read back from the
+	 * compare register does not match the value we programmed
+	 * then we might have a real hardware problem. We can not do
+	 * much about it here, but at least alert the user/admin with
+	 * a prominent warning.
 	 */
-	WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt);
+	WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+		  KERN_WARNING "hpet: compare register read back failed.\n");
 
-	return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
+	return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
@@ -415,7 +429,7 @@ static struct hpet_dev	*hpet_devs;
 void hpet_msi_unmask(unsigned int irq)
 {
 	struct hpet_dev *hdev = get_irq_data(irq);
-	unsigned long cfg;
+	unsigned int cfg;
 
 	/* unmask it */
 	cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
@@ -425,7 +439,7 @@ void hpet_msi_unmask(unsigned int irq)
 
 void hpet_msi_mask(unsigned int irq)
 {
-	unsigned long cfg;
+	unsigned int cfg;
 	struct hpet_dev *hdev = get_irq_data(irq);
 
 	/* mask it */
@@ -467,7 +481,7 @@ static int hpet_msi_next_event(unsigned
 
 static int hpet_setup_msi_irq(unsigned int irq)
 {
-	if (arch_setup_hpet_msi(irq)) {
+	if (arch_setup_hpet_msi(irq, hpet_blockid)) {
 		destroy_irq(irq);
 		return -EINVAL;
 	}
@@ -584,6 +598,11 @@ static void hpet_msi_capability_lookup(u
 	unsigned int num_timers_used = 0;
 	int i;
 
+	if (hpet_msi_disable)
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_ARAT))
+		return;
 	id = hpet_readl(HPET_ID);
 
 	num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
@@ -598,7 +617,7 @@ static void hpet_msi_capability_lookup(u
 
 	for (i = start_timer; i < num_timers - RESERVE_TIMERS; i++) {
 		struct hpet_dev *hdev = &hpet_devs[num_timers_used];
-		unsigned long cfg = hpet_readl(HPET_Tn_CFG(i));
+		unsigned int cfg = hpet_readl(HPET_Tn_CFG(i));
 
 		/* Only consider HPET timer with MSI support */
 		if (!(cfg & HPET_TN_FSB_CAP))
@@ -813,7 +832,7 @@ static int hpet_clocksource_register(voi
  */
 int __init hpet_enable(void)
 {
-	unsigned long id;
+	unsigned int id;
 	int i;
 
 	if (!is_hpet_capable())
@@ -872,10 +891,8 @@ int __init hpet_enable(void)
 
 	if (id & HPET_ID_LEGSUP) {
 		hpet_legacy_clockevent_register();
-		hpet_msi_capability_lookup(2);
 		return 1;
 	}
-	hpet_msi_capability_lookup(0);
 	return 0;
 
 out_nohpet:
@@ -908,9 +925,20 @@ static __init int hpet_late_init(void)
 	if (!hpet_virt_address)
 		return -ENODEV;
 
+	if (hpet_readl(HPET_ID) & HPET_ID_LEGSUP)
+		hpet_msi_capability_lookup(2);
+	else
+		hpet_msi_capability_lookup(0);
+
 	hpet_reserve_platform_timers(hpet_readl(HPET_ID));
 	hpet_print_config();
 
+	if (hpet_msi_disable)
+		return 0;
+
+	if (boot_cpu_has(X86_FEATURE_ARAT))
+		return 0;
+
 	for_each_online_cpu(cpu) {
 		hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
 	}
@@ -925,7 +953,7 @@ fs_initcall(hpet_late_init);
 void hpet_disable(void)
 {
 	if (is_hpet_capable()) {
-		unsigned long cfg = hpet_readl(HPET_CFG);
+		unsigned int cfg = hpet_readl(HPET_CFG);
 
 		if (hpet_legacy_int_enabled) {
 			cfg &= ~HPET_CFG_LEGACY;
@@ -965,8 +993,8 @@ static int hpet_prev_update_sec;
 static struct rtc_time hpet_alarm_time;
 static unsigned long hpet_pie_count;
 static u32 hpet_t1_cmp;
-static unsigned long hpet_default_delta;
-static unsigned long hpet_pie_delta;
+static u32 hpet_default_delta;
+static u32 hpet_pie_delta;
 static unsigned long hpet_pie_limit;
 
 static rtc_irq_handler irq_handler;
@@ -1017,7 +1045,8 @@ EXPORT_SYMBOL_GPL(hpet_unregister_irq_ha
  */
 int hpet_rtc_timer_init(void)
 {
-	unsigned long cfg, cnt, delta, flags;
+	unsigned int cfg, cnt, delta;
+	unsigned long flags;
 
 	if (!is_hpet_enabled())
 		return 0;
@@ -1027,7 +1056,7 @@ int hpet_rtc_timer_init(void)
 
 		clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
 		clc >>= hpet_clockevent.shift + DEFAULT_RTC_SHIFT;
-		hpet_default_delta = (unsigned long) clc;
+		hpet_default_delta = clc;
 	}
 
 	if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit)
@@ -1113,7 +1142,7 @@ int hpet_set_periodic_freq(unsigned long
 		clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
 		do_div(clc, freq);
 		clc >>= hpet_clockevent.shift;
-		hpet_pie_delta = (unsigned long) clc;
+		hpet_pie_delta = clc;
 	}
 	return 1;
 }
@@ -1127,7 +1156,7 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq);
 
 static void hpet_rtc_timer_reinit(void)
 {
-	unsigned long cfg, delta;
+	unsigned int cfg, delta;
 	int lost_ints = -1;
 
 	if (unlikely(!hpet_rtc_flags)) {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/hw_breakpoint.c linux-libre-2.6.33-gnu1/arch/x86/kernel/hw_breakpoint.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/hw_breakpoint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/hw_breakpoint.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,538 @@
+/*
+ * 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) 2007 Alan Stern
+ * Copyright (C) 2009 IBM Corporation
+ * Copyright (C) 2009 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ * Authors: Alan Stern <stern@rowland.harvard.edu>
+ *          K.Prasad <prasad@linux.vnet.ibm.com>
+ *          Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/irqflags.h>
+#include <linux/notifier.h>
+#include <linux/kallsyms.h>
+#include <linux/kprobes.h>
+#include <linux/percpu.h>
+#include <linux/kdebug.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/hw_breakpoint.h>
+#include <asm/processor.h>
+#include <asm/debugreg.h>
+
+/* Per cpu debug control register value */
+DEFINE_PER_CPU(unsigned long, cpu_dr7);
+EXPORT_PER_CPU_SYMBOL(cpu_dr7);
+
+/* Per cpu debug address registers values */
+static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for each cpus
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
+
+
+static inline unsigned long
+__encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+	unsigned long bp_info;
+
+	bp_info = (len | type) & 0xf;
+	bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
+	bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
+
+	return bp_info;
+}
+
+/*
+ * Encode the length, type, Exact, and Enable bits for a particular breakpoint
+ * as stored in debug register 7.
+ */
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+	return __encode_dr7(drnum, len, type) | DR_GLOBAL_SLOWDOWN;
+}
+
+/*
+ * Decode the length and type bits for a particular breakpoint as
+ * stored in debug register 7.  Return the "enabled" status.
+ */
+int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type)
+{
+	int bp_info = dr7 >> (DR_CONTROL_SHIFT + bpnum * DR_CONTROL_SIZE);
+
+	*len = (bp_info & 0xc) | 0x40;
+	*type = (bp_info & 0x3) | 0x80;
+
+	return (dr7 >> (bpnum * DR_ENABLE_SIZE)) & 0x3;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint. Eventually we enable it in the debug control register.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	unsigned long *dr7;
+	int i;
+
+	for (i = 0; i < HBP_NUM; i++) {
+		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+		if (!*slot) {
+			*slot = bp;
+			break;
+		}
+	}
+
+	if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
+		return -EBUSY;
+
+	set_debugreg(info->address, i);
+	__get_cpu_var(cpu_debugreg[i]) = info->address;
+
+	dr7 = &__get_cpu_var(cpu_dr7);
+	*dr7 |= encode_dr7(i, info->len, info->type);
+
+	set_debugreg(*dr7, 7);
+
+	return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	unsigned long *dr7;
+	int i;
+
+	for (i = 0; i < HBP_NUM; i++) {
+		struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
+
+		if (*slot == bp) {
+			*slot = NULL;
+			break;
+		}
+	}
+
+	if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
+		return;
+
+	dr7 = &__get_cpu_var(cpu_dr7);
+	*dr7 &= ~__encode_dr7(i, info->len, info->type);
+
+	set_debugreg(*dr7, 7);
+}
+
+static int get_hbp_len(u8 hbp_len)
+{
+	unsigned int len_in_bytes = 0;
+
+	switch (hbp_len) {
+	case X86_BREAKPOINT_LEN_1:
+		len_in_bytes = 1;
+		break;
+	case X86_BREAKPOINT_LEN_2:
+		len_in_bytes = 2;
+		break;
+	case X86_BREAKPOINT_LEN_4:
+		len_in_bytes = 4;
+		break;
+#ifdef CONFIG_X86_64
+	case X86_BREAKPOINT_LEN_8:
+		len_in_bytes = 8;
+		break;
+#endif
+	}
+	return len_in_bytes;
+}
+
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u8 hbp_len)
+{
+	unsigned int len;
+
+	len = get_hbp_len(hbp_len);
+
+	return (va <= TASK_SIZE - len);
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+{
+	unsigned int len;
+
+	len = get_hbp_len(hbp_len);
+
+	return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+int arch_bp_generic_fields(int x86_len, int x86_type,
+			   int *gen_len, int *gen_type)
+{
+	/* Len */
+	switch (x86_len) {
+	case X86_BREAKPOINT_LEN_1:
+		*gen_len = HW_BREAKPOINT_LEN_1;
+		break;
+	case X86_BREAKPOINT_LEN_2:
+		*gen_len = HW_BREAKPOINT_LEN_2;
+		break;
+	case X86_BREAKPOINT_LEN_4:
+		*gen_len = HW_BREAKPOINT_LEN_4;
+		break;
+#ifdef CONFIG_X86_64
+	case X86_BREAKPOINT_LEN_8:
+		*gen_len = HW_BREAKPOINT_LEN_8;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	/* Type */
+	switch (x86_type) {
+	case X86_BREAKPOINT_EXECUTE:
+		*gen_type = HW_BREAKPOINT_X;
+		break;
+	case X86_BREAKPOINT_WRITE:
+		*gen_type = HW_BREAKPOINT_W;
+		break;
+	case X86_BREAKPOINT_RW:
+		*gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static int arch_build_bp_info(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+	info->address = bp->attr.bp_addr;
+
+	/* Len */
+	switch (bp->attr.bp_len) {
+	case HW_BREAKPOINT_LEN_1:
+		info->len = X86_BREAKPOINT_LEN_1;
+		break;
+	case HW_BREAKPOINT_LEN_2:
+		info->len = X86_BREAKPOINT_LEN_2;
+		break;
+	case HW_BREAKPOINT_LEN_4:
+		info->len = X86_BREAKPOINT_LEN_4;
+		break;
+#ifdef CONFIG_X86_64
+	case HW_BREAKPOINT_LEN_8:
+		info->len = X86_BREAKPOINT_LEN_8;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	/* Type */
+	switch (bp->attr.bp_type) {
+	case HW_BREAKPOINT_W:
+		info->type = X86_BREAKPOINT_WRITE;
+		break;
+	case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
+		info->type = X86_BREAKPOINT_RW;
+		break;
+	case HW_BREAKPOINT_X:
+		info->type = X86_BREAKPOINT_EXECUTE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+				  struct task_struct *tsk)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	unsigned int align;
+	int ret;
+
+
+	ret = arch_build_bp_info(bp);
+	if (ret)
+		return ret;
+
+	ret = -EINVAL;
+
+	if (info->type == X86_BREAKPOINT_EXECUTE)
+		/*
+		 * Ptrace-refactoring code
+		 * For now, we'll allow instruction breakpoint only for user-space
+		 * addresses
+		 */
+		if ((!arch_check_va_in_userspace(info->address, info->len)) &&
+			info->len != X86_BREAKPOINT_EXECUTE)
+			return ret;
+
+	switch (info->len) {
+	case X86_BREAKPOINT_LEN_1:
+		align = 0;
+		break;
+	case X86_BREAKPOINT_LEN_2:
+		align = 1;
+		break;
+	case X86_BREAKPOINT_LEN_4:
+		align = 3;
+		break;
+#ifdef CONFIG_X86_64
+	case X86_BREAKPOINT_LEN_8:
+		align = 7;
+		break;
+#endif
+	default:
+		return ret;
+	}
+
+	/*
+	 * For kernel-addresses, either the address or symbol name can be
+	 * specified.
+	 */
+	if (info->name)
+		info->address = (unsigned long)
+				kallsyms_lookup_name(info->name);
+	/*
+	 * Check that the low-order bits of the address are appropriate
+	 * for the alignment implied by len.
+	 */
+	if (info->address & align)
+		return -EINVAL;
+
+	/* Check that the virtual address is in the proper range */
+	if (tsk) {
+		if (!arch_check_va_in_userspace(info->address, info->len))
+			return -EFAULT;
+	} else {
+		if (!arch_check_va_in_kernelspace(info->address, info->len))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * Dump the debug register contents to the user.
+ * We can't dump our per cpu values because it
+ * may contain cpu wide breakpoint, something that
+ * doesn't belong to the current task.
+ *
+ * TODO: include non-ptrace user breakpoints (perf)
+ */
+void aout_dump_debugregs(struct user *dump)
+{
+	int i;
+	int dr7 = 0;
+	struct perf_event *bp;
+	struct arch_hw_breakpoint *info;
+	struct thread_struct *thread = &current->thread;
+
+	for (i = 0; i < HBP_NUM; i++) {
+		bp = thread->ptrace_bps[i];
+
+		if (bp && !bp->attr.disabled) {
+			dump->u_debugreg[i] = bp->attr.bp_addr;
+			info = counter_arch_bp(bp);
+			dr7 |= encode_dr7(i, info->len, info->type);
+		} else {
+			dump->u_debugreg[i] = 0;
+		}
+	}
+
+	dump->u_debugreg[4] = 0;
+	dump->u_debugreg[5] = 0;
+	dump->u_debugreg[6] = current->thread.debugreg6;
+
+	dump->u_debugreg[7] = dr7;
+}
+EXPORT_SYMBOL_GPL(aout_dump_debugregs);
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+	int i;
+	struct thread_struct *t = &tsk->thread;
+
+	for (i = 0; i < HBP_NUM; i++) {
+		unregister_hw_breakpoint(t->ptrace_bps[i]);
+		t->ptrace_bps[i] = NULL;
+	}
+}
+
+void hw_breakpoint_restore(void)
+{
+	set_debugreg(__get_cpu_var(cpu_debugreg[0]), 0);
+	set_debugreg(__get_cpu_var(cpu_debugreg[1]), 1);
+	set_debugreg(__get_cpu_var(cpu_debugreg[2]), 2);
+	set_debugreg(__get_cpu_var(cpu_debugreg[3]), 3);
+	set_debugreg(current->thread.debugreg6, 6);
+	set_debugreg(__get_cpu_var(cpu_dr7), 7);
+}
+EXPORT_SYMBOL_GPL(hw_breakpoint_restore);
+
+/*
+ * Handle debug exception notifications.
+ *
+ * Return value is either NOTIFY_STOP or NOTIFY_DONE as explained below.
+ *
+ * NOTIFY_DONE returned if one of the following conditions is true.
+ * i) When the causative address is from user-space and the exception
+ * is a valid one, i.e. not triggered as a result of lazy debug register
+ * switching
+ * ii) When there are more bits than trap<n> set in DR6 register (such
+ * as BD, BS or BT) indicating that more than one debug condition is
+ * met and requires some more action in do_debug().
+ *
+ * NOTIFY_STOP returned for all other cases
+ *
+ */
+static int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+	int i, cpu, rc = NOTIFY_STOP;
+	struct perf_event *bp;
+	unsigned long dr7, dr6;
+	unsigned long *dr6_p;
+
+	/* The DR6 value is pointed by args->err */
+	dr6_p = (unsigned long *)ERR_PTR(args->err);
+	dr6 = *dr6_p;
+
+	/* Do an early return if no trap bits are set in DR6 */
+	if ((dr6 & DR_TRAP_BITS) == 0)
+		return NOTIFY_DONE;
+
+	get_debugreg(dr7, 7);
+	/* Disable breakpoints during exception handling */
+	set_debugreg(0UL, 7);
+	/*
+	 * Assert that local interrupts are disabled
+	 * Reset the DRn bits in the virtualized register value.
+	 * The ptrace trigger routine will add in whatever is needed.
+	 */
+	current->thread.debugreg6 &= ~DR_TRAP_BITS;
+	cpu = get_cpu();
+
+	/* Handle all the breakpoints that were triggered */
+	for (i = 0; i < HBP_NUM; ++i) {
+		if (likely(!(dr6 & (DR_TRAP0 << i))))
+			continue;
+
+		/*
+		 * The counter may be concurrently released but that can only
+		 * occur from a call_rcu() path. We can then safely fetch
+		 * the breakpoint, use its callback, touch its counter
+		 * while we are in an rcu_read_lock() path.
+		 */
+		rcu_read_lock();
+
+		bp = per_cpu(bp_per_reg[i], cpu);
+		if (bp)
+			rc = NOTIFY_DONE;
+		/*
+		 * Reset the 'i'th TRAP bit in dr6 to denote completion of
+		 * exception handling
+		 */
+		(*dr6_p) &= ~(DR_TRAP0 << i);
+		/*
+		 * bp can be NULL due to lazy debug register switching
+		 * or due to concurrent perf counter removing.
+		 */
+		if (!bp) {
+			rcu_read_unlock();
+			break;
+		}
+
+		perf_bp_event(bp, args->regs);
+
+		rcu_read_unlock();
+	}
+	if (dr6 & (~DR_TRAP_BITS))
+		rc = NOTIFY_DONE;
+
+	set_debugreg(dr7, 7);
+	put_cpu();
+
+	return rc;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(
+		struct notifier_block *unused, unsigned long val, void *data)
+{
+	if (val != DIE_DEBUG)
+		return NOTIFY_DONE;
+
+	return hw_breakpoint_handler(data);
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+	/* TODO */
+}
+
+void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
+{
+	/* TODO */
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/ioport.c linux-libre-2.6.33-gnu1/arch/x86/kernel/ioport.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/ioport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/ioport.c	2010-02-24 13:52:17.000000000 -0500
@@ -103,9 +103,10 @@ asmlinkage long sys_ioperm(unsigned long
  * on system-call entry - see also fork() and the signal handling
  * code.
  */
-static int do_iopl(unsigned int level, struct pt_regs *regs)
+long sys_iopl(unsigned int level, struct pt_regs *regs)
 {
 	unsigned int old = (regs->flags >> 12) & 3;
+	struct thread_struct *t = &current->thread;
 
 	if (level > 3)
 		return -EINVAL;
@@ -115,29 +116,8 @@ static int do_iopl(unsigned int level, s
 			return -EPERM;
 	}
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-
-	return 0;
-}
-
-#ifdef CONFIG_X86_32
-long sys_iopl(struct pt_regs *regs)
-{
-	unsigned int level = regs->bx;
-	struct thread_struct *t = &current->thread;
-	int rc;
-
-	rc = do_iopl(level, regs);
-	if (rc < 0)
-		goto out;
-
 	t->iopl = level << 12;
 	set_iopl_mask(t->iopl);
-out:
-	return rc;
-}
-#else
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
-{
-	return do_iopl(level, regs);
+
+	return 0;
 }
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/irq_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/irq_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/irq_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/irq_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,48 +211,3 @@ bool handle_irq(unsigned irq, struct pt_
 
 	return true;
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
-void fixup_irqs(void)
-{
-	unsigned int irq;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(irq, desc) {
-		const struct cpumask *affinity;
-
-		if (!desc)
-			continue;
-		if (irq == 2)
-			continue;
-
-		affinity = desc->affinity;
-		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
-			printk("Breaking affinity for irq %i\n", irq);
-			affinity = cpu_all_mask;
-		}
-		if (desc->chip->set_affinity)
-			desc->chip->set_affinity(irq, affinity);
-		else if (desc->action)
-			printk_once("Cannot set affinity for irq %i\n", irq);
-	}
-
-#if 0
-	barrier();
-	/* Ingo Molnar says: "after the IO-APIC masks have been redirected
-	   [note the nop - the interrupt-enable boundary on x86 is two
-	   instructions from sti] - to flush out pending hardirqs and
-	   IPIs. After this point nothing is supposed to reach this CPU." */
-	__asm__ __volatile__("sti; nop; cli");
-	barrier();
-#else
-	/* That doesn't seem sufficient.  Give it 1ms. */
-	local_irq_enable();
-	mdelay(1);
-	local_irq_disable();
-#endif
-}
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/irq_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/irq_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/irq_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/irq_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,64 +62,6 @@ bool handle_irq(unsigned irq, struct pt_
 	return true;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
-/* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
-void fixup_irqs(void)
-{
-	unsigned int irq;
-	static int warned;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(irq, desc) {
-		int break_affinity = 0;
-		int set_affinity = 1;
-		const struct cpumask *affinity;
-
-		if (!desc)
-			continue;
-		if (irq == 2)
-			continue;
-
-		/* interrupt's are disabled at this point */
-		spin_lock(&desc->lock);
-
-		affinity = desc->affinity;
-		if (!irq_has_action(irq) ||
-		    cpumask_equal(affinity, cpu_online_mask)) {
-			spin_unlock(&desc->lock);
-			continue;
-		}
-
-		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
-			break_affinity = 1;
-			affinity = cpu_all_mask;
-		}
-
-		if (desc->chip->mask)
-			desc->chip->mask(irq);
-
-		if (desc->chip->set_affinity)
-			desc->chip->set_affinity(irq, affinity);
-		else if (!(warned++))
-			set_affinity = 0;
-
-		if (desc->chip->unmask)
-			desc->chip->unmask(irq);
-
-		spin_unlock(&desc->lock);
-
-		if (break_affinity && set_affinity)
-			printk("Broke affinity for irq %i\n", irq);
-		else if (!set_affinity)
-			printk("Cannot set affinity for irq %i\n", irq);
-	}
-
-	/* That doesn't seem sufficient.  Give it 1ms. */
-	local_irq_enable();
-	mdelay(1);
-	local_irq_disable();
-}
-#endif
 
 extern void call_softirq(void);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/irq.c linux-libre-2.6.33-gnu1/arch/x86/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
 atomic_t irq_err_count;
 
 /* Function pointer for generic interrupt vector handling */
-void (*generic_interrupt_extension)(void) = NULL;
+void (*x86_platform_ipi_callback)(void) = NULL;
 
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
@@ -72,10 +72,10 @@ static int show_other_interrupts(struct
 		seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
 	seq_printf(p, "  Performance pending work\n");
 #endif
-	if (generic_interrupt_extension) {
+	if (x86_platform_ipi_callback) {
 		seq_printf(p, "%*s: ", prec, "PLT");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_stats(j)->generic_irqs);
+			seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis);
 		seq_printf(p, "  Platform interrupts\n");
 	}
 #ifdef CONFIG_SMP
@@ -92,17 +92,17 @@ static int show_other_interrupts(struct
 		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
 	seq_printf(p, "  TLB shootdowns\n");
 #endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
 	seq_printf(p, "%*s: ", prec, "TRM");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
 	seq_printf(p, "  Thermal event interrupts\n");
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
 	seq_printf(p, "%*s: ", prec, "THR");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
 	seq_printf(p, "  Threshold APIC interrupts\n");
-# endif
 #endif
 #ifdef CONFIG_X86_MCE
 	seq_printf(p, "%*s: ", prec, "MCE");
@@ -149,7 +149,7 @@ int show_interrupts(struct seq_file *p,
 	if (!desc)
 		return 0;
 
-	spin_lock_irqsave(&desc->lock, flags);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	for_each_online_cpu(j)
 		any_count |= kstat_irqs_cpu(i, j);
 	action = desc->action;
@@ -170,7 +170,7 @@ int show_interrupts(struct seq_file *p,
 
 	seq_putc(p, '\n');
 out:
-	spin_unlock_irqrestore(&desc->lock, flags);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return 0;
 }
 
@@ -187,18 +187,18 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 	sum += irq_stats(cpu)->apic_perf_irqs;
 	sum += irq_stats(cpu)->apic_pending_irqs;
 #endif
-	if (generic_interrupt_extension)
-		sum += irq_stats(cpu)->generic_irqs;
+	if (x86_platform_ipi_callback)
+		sum += irq_stats(cpu)->x86_platform_ipis;
 #ifdef CONFIG_SMP
 	sum += irq_stats(cpu)->irq_resched_count;
 	sum += irq_stats(cpu)->irq_call_count;
 	sum += irq_stats(cpu)->irq_tlb_count;
 #endif
-#ifdef CONFIG_X86_MCE
+#ifdef CONFIG_X86_THERMAL_VECTOR
 	sum += irq_stats(cpu)->irq_thermal_count;
-# ifdef CONFIG_X86_MCE_THRESHOLD
+#endif
+#ifdef CONFIG_X86_MCE_THRESHOLD
 	sum += irq_stats(cpu)->irq_threshold_count;
-# endif
 #endif
 #ifdef CONFIG_X86_MCE
 	sum += per_cpu(mce_exception_count, cpu);
@@ -251,9 +251,9 @@ unsigned int __irq_entry do_IRQ(struct p
 }
 
 /*
- * Handler for GENERIC_INTERRUPT_VECTOR.
+ * Handler for X86_PLATFORM_IPI_VECTOR.
  */
-void smp_generic_interrupt(struct pt_regs *regs)
+void smp_x86_platform_ipi(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
@@ -263,10 +263,10 @@ void smp_generic_interrupt(struct pt_reg
 
 	irq_enter();
 
-	inc_irq_stat(generic_irqs);
+	inc_irq_stat(x86_platform_ipis);
 
-	if (generic_interrupt_extension)
-		generic_interrupt_extension();
+	if (x86_platform_ipi_callback)
+		x86_platform_ipi_callback();
 
 	irq_exit();
 
@@ -274,3 +274,93 @@ void smp_generic_interrupt(struct pt_reg
 }
 
 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
+
+#ifdef CONFIG_HOTPLUG_CPU
+/* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
+void fixup_irqs(void)
+{
+	unsigned int irq, vector;
+	static int warned;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(irq, desc) {
+		int break_affinity = 0;
+		int set_affinity = 1;
+		const struct cpumask *affinity;
+
+		if (!desc)
+			continue;
+		if (irq == 2)
+			continue;
+
+		/* interrupt's are disabled at this point */
+		raw_spin_lock(&desc->lock);
+
+		affinity = desc->affinity;
+		if (!irq_has_action(irq) ||
+		    cpumask_equal(affinity, cpu_online_mask)) {
+			raw_spin_unlock(&desc->lock);
+			continue;
+		}
+
+		/*
+		 * Complete the irq move. This cpu is going down and for
+		 * non intr-remapping case, we can't wait till this interrupt
+		 * arrives at this cpu before completing the irq move.
+		 */
+		irq_force_complete_move(irq);
+
+		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+			break_affinity = 1;
+			affinity = cpu_all_mask;
+		}
+
+		if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->mask)
+			desc->chip->mask(irq);
+
+		if (desc->chip->set_affinity)
+			desc->chip->set_affinity(irq, affinity);
+		else if (!(warned++))
+			set_affinity = 0;
+
+		if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask)
+			desc->chip->unmask(irq);
+
+		raw_spin_unlock(&desc->lock);
+
+		if (break_affinity && set_affinity)
+			printk("Broke affinity for irq %i\n", irq);
+		else if (!set_affinity)
+			printk("Cannot set affinity for irq %i\n", irq);
+	}
+
+	/*
+	 * We can remove mdelay() and then send spuriuous interrupts to
+	 * new cpu targets for all the irqs that were handled previously by
+	 * this cpu. While it works, I have seen spurious interrupt messages
+	 * (nothing wrong but still...).
+	 *
+	 * So for now, retain mdelay(1) and check the IRR and then send those
+	 * interrupts to new targets as this cpu is already offlined...
+	 */
+	mdelay(1);
+
+	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
+		unsigned int irr;
+
+		if (__get_cpu_var(vector_irq)[vector] < 0)
+			continue;
+
+		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
+		if (irr  & (1 << (vector % 32))) {
+			irq = __get_cpu_var(vector_irq)[vector];
+
+			desc = irq_to_desc(irq);
+			raw_spin_lock(&desc->lock);
+			if (desc->chip->retrigger)
+				desc->chip->retrigger(irq);
+			raw_spin_unlock(&desc->lock);
+		}
+	}
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/irqinit.c linux-libre-2.6.33-gnu1/arch/x86/kernel/irqinit.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/irqinit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/irqinit.c	2010-02-24 13:52:17.000000000 -0500
@@ -200,8 +200,8 @@ static void __init apic_intr_init(void)
 	/* self generated IPI for local APIC timer */
 	alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
 
-	/* generic IPI for platform specific use */
-	alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt);
+	/* IPI for X86 platform specific use */
+	alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi);
 
 	/* IPI vectors for APIC spurious and error interrupts */
 	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/kgdb.c linux-libre-2.6.33-gnu1/arch/x86/kernel/kgdb.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/kgdb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/kgdb.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,9 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/nmi.h>
+#include <linux/hw_breakpoint.h>
 
+#include <asm/debugreg.h>
 #include <asm/apicdef.h>
 #include <asm/system.h>
 
@@ -85,10 +87,15 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[GDB_DS]	= regs->ds;
 	gdb_regs[GDB_ES]	= regs->es;
 	gdb_regs[GDB_CS]	= regs->cs;
-	gdb_regs[GDB_SS]	= __KERNEL_DS;
 	gdb_regs[GDB_FS]	= 0xFFFF;
 	gdb_regs[GDB_GS]	= 0xFFFF;
-	gdb_regs[GDB_SP]	= (int)&regs->sp;
+	if (user_mode_vm(regs)) {
+		gdb_regs[GDB_SS] = regs->ss;
+		gdb_regs[GDB_SP] = regs->sp;
+	} else {
+		gdb_regs[GDB_SS] = __KERNEL_DS;
+		gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
+	}
 #else
 	gdb_regs[GDB_R8]	= regs->r8;
 	gdb_regs[GDB_R9]	= regs->r9;
@@ -101,7 +108,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs32[GDB_PS]	= regs->flags;
 	gdb_regs32[GDB_CS]	= regs->cs;
 	gdb_regs32[GDB_SS]	= regs->ss;
-	gdb_regs[GDB_SP]	= regs->sp;
+	gdb_regs[GDB_SP]	= kernel_stack_pointer(regs);
 #endif
 }
 
@@ -198,41 +205,81 @@ void gdb_regs_to_pt_regs(unsigned long *
 
 static struct hw_breakpoint {
 	unsigned		enabled;
-	unsigned		type;
-	unsigned		len;
 	unsigned long		addr;
+	int			len;
+	int			type;
+	struct perf_event	**pev;
 } breakinfo[4];
 
 static void kgdb_correct_hw_break(void)
 {
-	unsigned long dr7;
-	int correctit = 0;
-	int breakbit;
 	int breakno;
 
-	get_debugreg(dr7, 7);
 	for (breakno = 0; breakno < 4; breakno++) {
-		breakbit = 2 << (breakno << 1);
-		if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
-			correctit = 1;
-			dr7 |= breakbit;
-			dr7 &= ~(0xf0000 << (breakno << 2));
-			dr7 |= ((breakinfo[breakno].len << 2) |
-				 breakinfo[breakno].type) <<
-			       ((breakno << 2) + 16);
-			if (breakno >= 0 && breakno <= 3)
-				set_debugreg(breakinfo[breakno].addr, breakno);
+		struct perf_event *bp;
+		struct arch_hw_breakpoint *info;
+		int val;
+		int cpu = raw_smp_processor_id();
+		if (!breakinfo[breakno].enabled)
+			continue;
+		bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu);
+		info = counter_arch_bp(bp);
+		if (bp->attr.disabled != 1)
+			continue;
+		bp->attr.bp_addr = breakinfo[breakno].addr;
+		bp->attr.bp_len = breakinfo[breakno].len;
+		bp->attr.bp_type = breakinfo[breakno].type;
+		info->address = breakinfo[breakno].addr;
+		info->len = breakinfo[breakno].len;
+		info->type = breakinfo[breakno].type;
+		val = arch_install_hw_breakpoint(bp);
+		if (!val)
+			bp->attr.disabled = 0;
+	}
+	hw_breakpoint_restore();
+}
 
-		} else {
-			if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
-				correctit = 1;
-				dr7 &= ~breakbit;
-				dr7 &= ~(0xf0000 << (breakno << 2));
-			}
-		}
+static int hw_break_reserve_slot(int breakno)
+{
+	int cpu;
+	int cnt = 0;
+	struct perf_event **pevent;
+
+	for_each_online_cpu(cpu) {
+		cnt++;
+		pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu);
+		if (dbg_reserve_bp_slot(*pevent))
+			goto fail;
 	}
-	if (correctit)
-		set_debugreg(dr7, 7);
+
+	return 0;
+
+fail:
+	for_each_online_cpu(cpu) {
+		cnt--;
+		if (!cnt)
+			break;
+		pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu);
+		dbg_release_bp_slot(*pevent);
+	}
+	return -1;
+}
+
+static int hw_break_release_slot(int breakno)
+{
+	struct perf_event **pevent;
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu);
+		if (dbg_release_bp_slot(*pevent))
+			/*
+			 * The debugger is responisble for handing the retry on
+			 * remove failure.
+			 */
+			return -1;
+	}
+	return 0;
 }
 
 static int
@@ -246,6 +293,10 @@ kgdb_remove_hw_break(unsigned long addr,
 	if (i == 4)
 		return -1;
 
+	if (hw_break_release_slot(i)) {
+		printk(KERN_ERR "Cannot remove hw breakpoint at %lx\n", addr);
+		return -1;
+	}
 	breakinfo[i].enabled = 0;
 
 	return 0;
@@ -254,15 +305,23 @@ kgdb_remove_hw_break(unsigned long addr,
 static void kgdb_remove_all_hw_break(void)
 {
 	int i;
+	int cpu = raw_smp_processor_id();
+	struct perf_event *bp;
 
-	for (i = 0; i < 4; i++)
-		memset(&breakinfo[i], 0, sizeof(struct hw_breakpoint));
+	for (i = 0; i < 4; i++) {
+		if (!breakinfo[i].enabled)
+			continue;
+		bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
+		if (bp->attr.disabled == 1)
+			continue;
+		arch_uninstall_hw_breakpoint(bp);
+		bp->attr.disabled = 1;
+	}
 }
 
 static int
 kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
 {
-	unsigned type;
 	int i;
 
 	for (i = 0; i < 4; i++)
@@ -273,27 +332,42 @@ kgdb_set_hw_break(unsigned long addr, in
 
 	switch (bptype) {
 	case BP_HARDWARE_BREAKPOINT:
-		type = 0;
-		len  = 1;
+		len = 1;
+		breakinfo[i].type = X86_BREAKPOINT_EXECUTE;
 		break;
 	case BP_WRITE_WATCHPOINT:
-		type = 1;
+		breakinfo[i].type = X86_BREAKPOINT_WRITE;
 		break;
 	case BP_ACCESS_WATCHPOINT:
-		type = 3;
+		breakinfo[i].type = X86_BREAKPOINT_RW;
 		break;
 	default:
 		return -1;
 	}
-
-	if (len == 1 || len == 2 || len == 4)
-		breakinfo[i].len  = len - 1;
-	else
+	switch (len) {
+	case 1:
+		breakinfo[i].len = X86_BREAKPOINT_LEN_1;
+		break;
+	case 2:
+		breakinfo[i].len = X86_BREAKPOINT_LEN_2;
+		break;
+	case 4:
+		breakinfo[i].len = X86_BREAKPOINT_LEN_4;
+		break;
+#ifdef CONFIG_X86_64
+	case 8:
+		breakinfo[i].len = X86_BREAKPOINT_LEN_8;
+		break;
+#endif
+	default:
 		return -1;
-
-	breakinfo[i].enabled = 1;
+	}
 	breakinfo[i].addr = addr;
-	breakinfo[i].type = type;
+	if (hw_break_reserve_slot(i)) {
+		breakinfo[i].addr = 0;
+		return -1;
+	}
+	breakinfo[i].enabled = 1;
 
 	return 0;
 }
@@ -308,8 +382,21 @@ kgdb_set_hw_break(unsigned long addr, in
  */
 void kgdb_disable_hw_debug(struct pt_regs *regs)
 {
+	int i;
+	int cpu = raw_smp_processor_id();
+	struct perf_event *bp;
+
 	/* Disable hardware debugging while we are in kgdb: */
 	set_debugreg(0UL, 7);
+	for (i = 0; i < 4; i++) {
+		if (!breakinfo[i].enabled)
+			continue;
+		bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
+		if (bp->attr.disabled == 1)
+			continue;
+		arch_uninstall_hw_breakpoint(bp);
+		bp->attr.disabled = 1;
+	}
 }
 
 /**
@@ -373,7 +460,6 @@ int kgdb_arch_handle_exception(int e_vec
 			       struct pt_regs *linux_regs)
 {
 	unsigned long addr;
-	unsigned long dr6;
 	char *ptr;
 	int newPC;
 
@@ -395,25 +481,10 @@ int kgdb_arch_handle_exception(int e_vec
 		/* set the trace bit if we're stepping */
 		if (remcomInBuffer[0] == 's') {
 			linux_regs->flags |= X86_EFLAGS_TF;
-			kgdb_single_step = 1;
 			atomic_set(&kgdb_cpu_doing_single_step,
 				   raw_smp_processor_id());
 		}
 
-		get_debugreg(dr6, 6);
-		if (!(dr6 & 0x4000)) {
-			int breakno;
-
-			for (breakno = 0; breakno < 4; breakno++) {
-				if (dr6 & (1 << breakno) &&
-				    breakinfo[breakno].type == 0) {
-					/* Set restore flag: */
-					linux_regs->flags |= X86_EFLAGS_RF;
-					break;
-				}
-			}
-		}
-		set_debugreg(0UL, 6);
 		kgdb_correct_hw_break();
 
 		return 0;
@@ -434,6 +505,11 @@ single_step_cont(struct pt_regs *regs, s
 			"resuming...\n");
 	kgdb_arch_handle_exception(args->trapnr, args->signr,
 				   args->err, "c", "", regs);
+	/*
+	 * Reset the BS bit in dr6 (pointed by args->err) to
+	 * denote completion of processing
+	 */
+	(*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
 
 	return NOTIFY_STOP;
 }
@@ -476,8 +552,7 @@ static int __kgdb_notify(struct die_args
 		break;
 
 	case DIE_DEBUG:
-		if (atomic_read(&kgdb_cpu_doing_single_step) ==
-		    raw_smp_processor_id()) {
+		if (atomic_read(&kgdb_cpu_doing_single_step) != -1) {
 			if (user_mode(regs))
 				return single_step_cont(regs, args);
 			break;
@@ -530,7 +605,42 @@ static struct notifier_block kgdb_notifi
  */
 int kgdb_arch_init(void)
 {
-	return register_die_notifier(&kgdb_notifier);
+	int i, cpu;
+	int ret;
+	struct perf_event_attr attr;
+	struct perf_event **pevent;
+
+	ret = register_die_notifier(&kgdb_notifier);
+	if (ret != 0)
+		return ret;
+	/*
+	 * Pre-allocate the hw breakpoint structions in the non-atomic
+	 * portion of kgdb because this operation requires mutexs to
+	 * complete.
+	 */
+	attr.bp_addr = (unsigned long)kgdb_arch_init;
+	attr.type = PERF_TYPE_BREAKPOINT;
+	attr.bp_len = HW_BREAKPOINT_LEN_1;
+	attr.bp_type = HW_BREAKPOINT_W;
+	attr.disabled = 1;
+	for (i = 0; i < 4; i++) {
+		breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL);
+		if (IS_ERR(breakinfo[i].pev)) {
+			printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n");
+			breakinfo[i].pev = NULL;
+			kgdb_arch_exit();
+			return -1;
+		}
+		for_each_online_cpu(cpu) {
+			pevent = per_cpu_ptr(breakinfo[i].pev, cpu);
+			pevent[0]->hw.sample_period = 1;
+			if (pevent[0]->destroy != NULL) {
+				pevent[0]->destroy = NULL;
+				release_bp_slot(*pevent);
+			}
+		}
+	}
+	return ret;
 }
 
 /**
@@ -541,6 +651,13 @@ int kgdb_arch_init(void)
  */
 void kgdb_arch_exit(void)
 {
+	int i;
+	for (i = 0; i < 4; i++) {
+		if (breakinfo[i].pev) {
+			unregister_wide_hw_breakpoint(breakinfo[i].pev);
+			breakinfo[i].pev = NULL;
+		}
+	}
 	unregister_die_notifier(&kgdb_notifier);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/kprobes.c linux-libre-2.6.33-gnu1/arch/x86/kernel/kprobes.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/kprobes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/kprobes.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,31 +48,22 @@
 #include <linux/preempt.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/kallsyms.h>
 
 #include <asm/cacheflush.h>
 #include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/alternative.h>
+#include <asm/insn.h>
+#include <asm/debugreg.h>
 
 void jprobe_return_end(void);
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
-#ifdef CONFIG_X86_64
-#define stack_addr(regs) ((unsigned long *)regs->sp)
-#else
-/*
- * "&regs->sp" looks wrong, but it's correct for x86_32.  x86_32 CPUs
- * don't save the ss and esp registers if the CPU is already in kernel
- * mode when it traps.  So for kprobes, regs->sp and regs->ss are not
- * the [nonexistent] saved stack pointer and ss register, but rather
- * the top 8 bytes of the pre-int3 stack.  So &regs->sp happens to
- * point to the top of the pre-int3 stack.
- */
-#define stack_addr(regs) ((unsigned long *)&regs->sp)
-#endif
+#define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
 
 #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
 	(((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) |   \
@@ -106,50 +97,6 @@ static const u32 twobyte_is_boostable[25
 	/*      -----------------------------------------------         */
 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
 };
-static const u32 onebyte_has_modrm[256 / 32] = {
-	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
-	/*      -----------------------------------------------         */
-	W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 00 */
-	W(0x10, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 10 */
-	W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 20 */
-	W(0x30, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 30 */
-	W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
-	W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */
-	W(0x60, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0) | /* 60 */
-	W(0x70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 70 */
-	W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
-	W(0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 90 */
-	W(0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* a0 */
-	W(0xb0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* b0 */
-	W(0xc0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* c0 */
-	W(0xd0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
-	W(0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* e0 */
-	W(0xf0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1)   /* f0 */
-	/*      -----------------------------------------------         */
-	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
-};
-static const u32 twobyte_has_modrm[256 / 32] = {
-	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
-	/*      -----------------------------------------------         */
-	W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1) | /* 0f */
-	W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0) , /* 1f */
-	W(0x20, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 2f */
-	W(0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 3f */
-	W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 4f */
-	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 5f */
-	W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 6f */
-	W(0x70, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1) , /* 7f */
-	W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 8f */
-	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 9f */
-	W(0xa0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) | /* af */
-	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) , /* bf */
-	W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* cf */
-	W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* df */
-	W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* ef */
-	W(0xf0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)   /* ff */
-	/*      -----------------------------------------------         */
-	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
-};
 #undef W
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = {
@@ -244,6 +191,75 @@ retry:
 	}
 }
 
+/* Recover the probed instruction at addr for further analysis. */
+static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
+{
+	struct kprobe *kp;
+	kp = get_kprobe((void *)addr);
+	if (!kp)
+		return -EINVAL;
+
+	/*
+	 *  Basically, kp->ainsn.insn has an original instruction.
+	 *  However, RIP-relative instruction can not do single-stepping
+	 *  at different place, fix_riprel() tweaks the displacement of
+	 *  that instruction. In that case, we can't recover the instruction
+	 *  from the kp->ainsn.insn.
+	 *
+	 *  On the other hand, kp->opcode has a copy of the first byte of
+	 *  the probed instruction, which is overwritten by int3. And
+	 *  the instruction at kp->addr is not modified by kprobes except
+	 *  for the first byte, we can recover the original instruction
+	 *  from it and kp->opcode.
+	 */
+	memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+	buf[0] = kp->opcode;
+	return 0;
+}
+
+/* Dummy buffers for kallsyms_lookup */
+static char __dummy_buf[KSYM_NAME_LEN];
+
+/* Check if paddr is at an instruction boundary */
+static int __kprobes can_probe(unsigned long paddr)
+{
+	int ret;
+	unsigned long addr, offset = 0;
+	struct insn insn;
+	kprobe_opcode_t buf[MAX_INSN_SIZE];
+
+	if (!kallsyms_lookup(paddr, NULL, &offset, NULL, __dummy_buf))
+		return 0;
+
+	/* Decode instructions */
+	addr = paddr - offset;
+	while (addr < paddr) {
+		kernel_insn_init(&insn, (void *)addr);
+		insn_get_opcode(&insn);
+
+		/*
+		 * Check if the instruction has been modified by another
+		 * kprobe, in which case we replace the breakpoint by the
+		 * original instruction in our buffer.
+		 */
+		if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+			ret = recover_probed_instruction(buf, addr);
+			if (ret)
+				/*
+				 * Another debugging subsystem might insert
+				 * this breakpoint. In that case, we can't
+				 * recover it.
+				 */
+				return 0;
+			kernel_insn_init(&insn, buf);
+		}
+		insn_get_length(&insn);
+		addr += insn.length;
+	}
+
+	return (addr == paddr);
+}
+
 /*
  * Returns non-zero if opcode modifies the interrupt flag.
  */
@@ -277,68 +293,30 @@ static int __kprobes is_IF_modifier(kpro
 static void __kprobes fix_riprel(struct kprobe *p)
 {
 #ifdef CONFIG_X86_64
-	u8 *insn = p->ainsn.insn;
-	s64 disp;
-	int need_modrm;
-
-	/* Skip legacy instruction prefixes.  */
-	while (1) {
-		switch (*insn) {
-		case 0x66:
-		case 0x67:
-		case 0x2e:
-		case 0x3e:
-		case 0x26:
-		case 0x64:
-		case 0x65:
-		case 0x36:
-		case 0xf0:
-		case 0xf3:
-		case 0xf2:
-			++insn;
-			continue;
-		}
-		break;
-	}
-
-	/* Skip REX instruction prefix.  */
-	if (is_REX_prefix(insn))
-		++insn;
-
-	if (*insn == 0x0f) {
-		/* Two-byte opcode.  */
-		++insn;
-		need_modrm = test_bit(*insn,
-				      (unsigned long *)twobyte_has_modrm);
-	} else
-		/* One-byte opcode.  */
-		need_modrm = test_bit(*insn,
-				      (unsigned long *)onebyte_has_modrm);
+	struct insn insn;
+	kernel_insn_init(&insn, p->ainsn.insn);
 
-	if (need_modrm) {
-		u8 modrm = *++insn;
-		if ((modrm & 0xc7) == 0x05) {
-			/* %rip+disp32 addressing mode */
-			/* Displacement follows ModRM byte.  */
-			++insn;
-			/*
-			 * The copied instruction uses the %rip-relative
-			 * addressing mode.  Adjust the displacement for the
-			 * difference between the original location of this
-			 * instruction and the location of the copy that will
-			 * actually be run.  The tricky bit here is making sure
-			 * that the sign extension happens correctly in this
-			 * calculation, since we need a signed 32-bit result to
-			 * be sign-extended to 64 bits when it's added to the
-			 * %rip value and yield the same 64-bit result that the
-			 * sign-extension of the original signed 32-bit
-			 * displacement would have given.
-			 */
-			disp = (u8 *) p->addr + *((s32 *) insn) -
-			       (u8 *) p->ainsn.insn;
-			BUG_ON((s64) (s32) disp != disp); /* Sanity check.  */
-			*(s32 *)insn = (s32) disp;
-		}
+	if (insn_rip_relative(&insn)) {
+		s64 newdisp;
+		u8 *disp;
+		insn_get_displacement(&insn);
+		/*
+		 * The copied instruction uses the %rip-relative addressing
+		 * mode.  Adjust the displacement for the difference between
+		 * the original location of this instruction and the location
+		 * of the copy that will actually be run.  The tricky bit here
+		 * is making sure that the sign extension happens correctly in
+		 * this calculation, since we need a signed 32-bit result to
+		 * be sign-extended to 64 bits when it's added to the %rip
+		 * value and yield the same 64-bit result that the sign-
+		 * extension of the original signed 32-bit displacement would
+		 * have given.
+		 */
+		newdisp = (u8 *) p->addr + (s64) insn.displacement.value -
+			  (u8 *) p->ainsn.insn;
+		BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check.  */
+		disp = (u8 *) p->ainsn.insn + insn_offset_displacement(&insn);
+		*(s32 *) disp = (s32) newdisp;
 	}
 #endif
 }
@@ -359,6 +337,8 @@ static void __kprobes arch_copy_kprobe(s
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
+	if (!can_probe((unsigned long)p->addr))
+		return -EILSEQ;
 	/* insn: must be on special executable page on x86. */
 	p->ainsn.insn = get_insn_slot();
 	if (!p->ainsn.insn)
@@ -472,17 +452,6 @@ static int __kprobes reenter_kprobe(stru
 {
 	switch (kcb->kprobe_status) {
 	case KPROBE_HIT_SSDONE:
-#ifdef CONFIG_X86_64
-		/* TODO: Provide re-entrancy from post_kprobes_handler() and
-		 * avoid exception stack corruption while single-stepping on
-		 * the instruction of the new probe.
-		 */
-		arch_disarm_kprobe(p);
-		regs->ip = (unsigned long)p->addr;
-		reset_current_kprobe();
-		preempt_enable_no_resched();
-		break;
-#endif
 	case KPROBE_HIT_ACTIVE:
 		save_previous_kprobe(kcb);
 		set_current_kprobe(p, regs, kcb);
@@ -491,18 +460,16 @@ static int __kprobes reenter_kprobe(stru
 		kcb->kprobe_status = KPROBE_REENTER;
 		break;
 	case KPROBE_HIT_SS:
-		if (p == kprobe_running()) {
-			regs->flags &= ~X86_EFLAGS_TF;
-			regs->flags |= kcb->kprobe_saved_flags;
-			return 0;
-		} else {
-			/* A probe has been hit in the codepath leading up
-			 * to, or just after, single-stepping of a probed
-			 * instruction. This entire codepath should strictly
-			 * reside in .kprobes.text section. Raise a warning
-			 * to highlight this peculiar case.
-			 */
-		}
+		/* A probe has been hit in the codepath leading up to, or just
+		 * after, single-stepping of a probed instruction. This entire
+		 * codepath should strictly reside in .kprobes.text section.
+		 * Raise a BUG or we'll continue in an endless reentering loop
+		 * and eventually a stack overflow.
+		 */
+		printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n",
+		       p->addr);
+		dump_kprobe(p);
+		BUG();
 	default:
 		/* impossible cases */
 		WARN_ON(1);
@@ -514,7 +481,7 @@ static int __kprobes reenter_kprobe(stru
 
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
- * remain disabled thorough out this function.
+ * remain disabled throughout this function.
  */
 static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
@@ -851,7 +818,7 @@ no_change:
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.
+ * remain disabled throughout this function.
  */
 static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
@@ -967,8 +934,14 @@ int __kprobes kprobe_exceptions_notify(s
 			ret = NOTIFY_STOP;
 		break;
 	case DIE_DEBUG:
-		if (post_kprobe_handler(args->regs))
+		if (post_kprobe_handler(args->regs)) {
+			/*
+			 * Reset the BS bit in dr6 (pointed by args->err) to
+			 * denote completion of processing
+			 */
+			(*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
 			ret = NOTIFY_STOP;
+		}
 		break;
 	case DIE_GPF:
 		/*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/machine_kexec_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/machine_kexec_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@
 #include <asm/desc.h>
 #include <asm/system.h>
 #include <asm/cacheflush.h>
+#include <asm/debugreg.h>
 
 static void set_idt(void *newidt, __u16 limit)
 {
@@ -157,8 +158,7 @@ int machine_kexec_prepare(struct kimage
 {
 	int error;
 
-	if (nx_enabled)
-		set_pages_x(image->control_code_page, 1);
+	set_pages_x(image->control_code_page, 1);
 	error = machine_kexec_alloc_page_tables(image);
 	if (error)
 		return error;
@@ -172,8 +172,7 @@ int machine_kexec_prepare(struct kimage
  */
 void machine_kexec_cleanup(struct kimage *image)
 {
-	if (nx_enabled)
-		set_pages_nx(image->control_code_page, 1);
+	set_pages_nx(image->control_code_page, 1);
 	machine_kexec_free_page_tables(image);
 }
 
@@ -202,6 +201,7 @@ void machine_kexec(struct kimage *image)
 
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
+	hw_breakpoint_disable();
 
 	if (image->preserve_context) {
 #ifdef CONFIG_X86_IO_APIC
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/machine_kexec_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/machine_kexec_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/machine_kexec_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
+#include <asm/debugreg.h>
 
 static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
 				unsigned long addr)
@@ -282,6 +283,7 @@ void machine_kexec(struct kimage *image)
 
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
+	hw_breakpoint_disable();
 
 	if (image->preserve_context) {
 #ifdef CONFIG_X86_IO_APIC
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/Makefile linux-libre-2.6.33-gnu1/arch/x86/kernel/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x86
 obj-$(CONFIG_X86_64)	+= syscall_64.o vsyscall_64.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
-obj-y			+= alternative.o i8253.o pci-nommu.o
+obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
 obj-y			+= tsc.o io_delay.o rtc.o
 
 obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
@@ -89,7 +89,6 @@ obj-$(CONFIG_EARLY_PRINTK)	+= early_prin
 obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
 
 obj-$(CONFIG_K8_NB)		+= k8.o
-obj-$(CONFIG_MGEODE_LX)		+= geode_32.o mfgpt_32.o
 obj-$(CONFIG_DEBUG_RODATA_TEST)	+= test_rodata.o
 obj-$(CONFIG_DEBUG_NX_TEST)	+= test_nx.o
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/mfgpt_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/mfgpt_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/mfgpt_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/mfgpt_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,410 +0,0 @@
-/*
- * Driver/API for AMD Geode Multi-Function General Purpose Timers (MFGPT)
- *
- * Copyright (C) 2006, Advanced Micro Devices, Inc.
- * Copyright (C) 2007, Andres Salomon <dilinger@debian.org>
- *
- * 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.
- *
- * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
- */
-
-/*
- * We are using the 32.768kHz input clock - it's the only one that has the
- * ranges we find desirable.  The following table lists the suitable
- * divisors and the associated Hz, minimum interval and the maximum interval:
- *
- *  Divisor   Hz      Min Delta (s)  Max Delta (s)
- *   1        32768   .00048828125      2.000
- *   2        16384   .0009765625       4.000
- *   4         8192   .001953125        8.000
- *   8         4096   .00390625        16.000
- *   16        2048   .0078125         32.000
- *   32        1024   .015625          64.000
- *   64         512   .03125          128.000
- *  128         256   .0625           256.000
- *  256         128   .125            512.000
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <asm/geode.h>
-
-#define MFGPT_DEFAULT_IRQ	7
-
-static struct mfgpt_timer_t {
-	unsigned int avail:1;
-} mfgpt_timers[MFGPT_MAX_TIMERS];
-
-/* Selected from the table above */
-
-#define MFGPT_DIVISOR 16
-#define MFGPT_SCALE  4     /* divisor = 2^(scale) */
-#define MFGPT_HZ  (32768 / MFGPT_DIVISOR)
-#define MFGPT_PERIODIC (MFGPT_HZ / HZ)
-
-/* Allow for disabling of MFGPTs */
-static int disable;
-static int __init mfgpt_disable(char *s)
-{
-	disable = 1;
-	return 1;
-}
-__setup("nomfgpt", mfgpt_disable);
-
-/* Reset the MFGPT timers. This is required by some broken BIOSes which already
- * do the same and leave the system in an unstable state. TinyBIOS 0.98 is
- * affected at least (0.99 is OK with MFGPT workaround left to off).
- */
-static int __init mfgpt_fix(char *s)
-{
-	u32 val, dummy;
-
-	/* The following udocumented bit resets the MFGPT timers */
-	val = 0xFF; dummy = 0;
-	wrmsr(MSR_MFGPT_SETUP, val, dummy);
-	return 1;
-}
-__setup("mfgptfix", mfgpt_fix);
-
-/*
- * Check whether any MFGPTs are available for the kernel to use.  In most
- * cases, firmware that uses AMD's VSA code will claim all timers during
- * bootup; we certainly don't want to take them if they're already in use.
- * In other cases (such as with VSAless OpenFirmware), the system firmware
- * leaves timers available for us to use.
- */
-
-
-static int timers = -1;
-
-static void geode_mfgpt_detect(void)
-{
-	int i;
-	u16 val;
-
-	timers = 0;
-
-	if (disable) {
-		printk(KERN_INFO "geode-mfgpt:  MFGPT support is disabled\n");
-		goto done;
-	}
-
-	if (!geode_get_dev_base(GEODE_DEV_MFGPT)) {
-		printk(KERN_INFO "geode-mfgpt:  MFGPT LBAR is not set up\n");
-		goto done;
-	}
-
-	for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
-		val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
-		if (!(val & MFGPT_SETUP_SETUP)) {
-			mfgpt_timers[i].avail = 1;
-			timers++;
-		}
-	}
-
-done:
-	printk(KERN_INFO "geode-mfgpt:  %d MFGPT timers available.\n", timers);
-}
-
-int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable)
-{
-	u32 msr, mask, value, dummy;
-	int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
-
-	if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
-		return -EIO;
-
-	/*
-	 * The register maps for these are described in sections 6.17.1.x of
-	 * the AMD Geode CS5536 Companion Device Data Book.
-	 */
-	switch (event) {
-	case MFGPT_EVENT_RESET:
-		/*
-		 * XXX: According to the docs, we cannot reset timers above
-		 * 6; that is, resets for 7 and 8 will be ignored.  Is this
-		 * a problem?   -dilinger
-		 */
-		msr = MSR_MFGPT_NR;
-		mask = 1 << (timer + 24);
-		break;
-
-	case MFGPT_EVENT_NMI:
-		msr = MSR_MFGPT_NR;
-		mask = 1 << (timer + shift);
-		break;
-
-	case MFGPT_EVENT_IRQ:
-		msr = MSR_MFGPT_IRQ;
-		mask = 1 << (timer + shift);
-		break;
-
-	default:
-		return -EIO;
-	}
-
-	rdmsr(msr, value, dummy);
-
-	if (enable)
-		value |= mask;
-	else
-		value &= ~mask;
-
-	wrmsr(msr, value, dummy);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(geode_mfgpt_toggle_event);
-
-int geode_mfgpt_set_irq(int timer, int cmp, int *irq, int enable)
-{
-	u32 zsel, lpc, dummy;
-	int shift;
-
-	if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
-		return -EIO;
-
-	/*
-	 * Unfortunately, MFGPTs come in pairs sharing their IRQ lines. If VSA
-	 * is using the same CMP of the timer's Siamese twin, the IRQ is set to
-	 * 2, and we mustn't use nor change it.
-	 * XXX: Likewise, 2 Linux drivers might clash if the 2nd overwrites the
-	 * IRQ of the 1st. This can only happen if forcing an IRQ, calling this
-	 * with *irq==0 is safe. Currently there _are_ no 2 drivers.
-	 */
-	rdmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
-	shift = ((cmp == MFGPT_CMP1 ? 0 : 4) + timer % 4) * 4;
-	if (((zsel >> shift) & 0xF) == 2)
-		return -EIO;
-
-	/* Choose IRQ: if none supplied, keep IRQ already set or use default */
-	if (!*irq)
-		*irq = (zsel >> shift) & 0xF;
-	if (!*irq)
-		*irq = MFGPT_DEFAULT_IRQ;
-
-	/* Can't use IRQ if it's 0 (=disabled), 2, or routed to LPC */
-	if (*irq < 1 || *irq == 2 || *irq > 15)
-		return -EIO;
-	rdmsr(MSR_PIC_IRQM_LPC, lpc, dummy);
-	if (lpc & (1 << *irq))
-		return -EIO;
-
-	/* All chosen and checked - go for it */
-	if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
-		return -EIO;
-	if (enable) {
-		zsel = (zsel & ~(0xF << shift)) | (*irq << shift);
-		wrmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
-	}
-
-	return 0;
-}
-
-static int mfgpt_get(int timer)
-{
-	mfgpt_timers[timer].avail = 0;
-	printk(KERN_INFO "geode-mfgpt:  Registered timer %d\n", timer);
-	return timer;
-}
-
-int geode_mfgpt_alloc_timer(int timer, int domain)
-{
-	int i;
-
-	if (timers == -1) {
-		/* timers haven't been detected yet */
-		geode_mfgpt_detect();
-	}
-
-	if (!timers)
-		return -1;
-
-	if (timer >= MFGPT_MAX_TIMERS)
-		return -1;
-
-	if (timer < 0) {
-		/* Try to find an available timer */
-		for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
-			if (mfgpt_timers[i].avail)
-				return mfgpt_get(i);
-
-			if (i == 5 && domain == MFGPT_DOMAIN_WORKING)
-				break;
-		}
-	} else {
-		/* If they requested a specific timer, try to honor that */
-		if (mfgpt_timers[timer].avail)
-			return mfgpt_get(timer);
-	}
-
-	/* No timers available - too bad */
-	return -1;
-}
-EXPORT_SYMBOL_GPL(geode_mfgpt_alloc_timer);
-
-
-#ifdef CONFIG_GEODE_MFGPT_TIMER
-
-/*
- * The MFPGT timers on the CS5536 provide us with suitable timers to use
- * as clock event sources - not as good as a HPET or APIC, but certainly
- * better than the PIT.  This isn't a general purpose MFGPT driver, but
- * a simplified one designed specifically to act as a clock event source.
- * For full details about the MFGPT, please consult the CS5536 data sheet.
- */
-
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-
-static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
-static u16 mfgpt_event_clock;
-
-static int irq;
-static int __init mfgpt_setup(char *str)
-{
-	get_option(&str, &irq);
-	return 1;
-}
-__setup("mfgpt_irq=", mfgpt_setup);
-
-static void mfgpt_disable_timer(u16 clock)
-{
-	/* avoid races by clearing CMP1 and CMP2 unconditionally */
-	geode_mfgpt_write(clock, MFGPT_REG_SETUP, (u16) ~MFGPT_SETUP_CNTEN |
-			MFGPT_SETUP_CMP1 | MFGPT_SETUP_CMP2);
-}
-
-static int mfgpt_next_event(unsigned long, struct clock_event_device *);
-static void mfgpt_set_mode(enum clock_event_mode, struct clock_event_device *);
-
-static struct clock_event_device mfgpt_clockevent = {
-	.name = "mfgpt-timer",
-	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = mfgpt_set_mode,
-	.set_next_event = mfgpt_next_event,
-	.rating = 250,
-	.cpumask = cpu_all_mask,
-	.shift = 32
-};
-
-static void mfgpt_start_timer(u16 delta)
-{
-	geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_CMP2, (u16) delta);
-	geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
-
-	geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
-			  MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
-}
-
-static void mfgpt_set_mode(enum clock_event_mode mode,
-			   struct clock_event_device *evt)
-{
-	mfgpt_disable_timer(mfgpt_event_clock);
-
-	if (mode == CLOCK_EVT_MODE_PERIODIC)
-		mfgpt_start_timer(MFGPT_PERIODIC);
-
-	mfgpt_tick_mode = mode;
-}
-
-static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
-{
-	mfgpt_start_timer(delta);
-	return 0;
-}
-
-static irqreturn_t mfgpt_tick(int irq, void *dev_id)
-{
-	u16 val = geode_mfgpt_read(mfgpt_event_clock, MFGPT_REG_SETUP);
-
-	/* See if the interrupt was for us */
-	if (!(val & (MFGPT_SETUP_SETUP  | MFGPT_SETUP_CMP2 | MFGPT_SETUP_CMP1)))
-		return IRQ_NONE;
-
-	/* Turn off the clock (and clear the event) */
-	mfgpt_disable_timer(mfgpt_event_clock);
-
-	if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
-		return IRQ_HANDLED;
-
-	/* Clear the counter */
-	geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
-
-	/* Restart the clock in periodic mode */
-
-	if (mfgpt_tick_mode == CLOCK_EVT_MODE_PERIODIC) {
-		geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
-				  MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
-	}
-
-	mfgpt_clockevent.event_handler(&mfgpt_clockevent);
-	return IRQ_HANDLED;
-}
-
-static struct irqaction mfgptirq  = {
-	.handler = mfgpt_tick,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
-	.name = "mfgpt-timer"
-};
-
-int __init mfgpt_timer_setup(void)
-{
-	int timer, ret;
-	u16 val;
-
-	timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
-	if (timer < 0) {
-		printk(KERN_ERR
-		       "mfgpt-timer:  Could not allocate a MFPGT timer\n");
-		return -ENODEV;
-	}
-
-	mfgpt_event_clock = timer;
-
-	/* Set up the IRQ on the MFGPT side */
-	if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, &irq)) {
-		printk(KERN_ERR "mfgpt-timer:  Could not set up IRQ %d\n", irq);
-		return -EIO;
-	}
-
-	/* And register it with the kernel */
-	ret = setup_irq(irq, &mfgptirq);
-
-	if (ret) {
-		printk(KERN_ERR
-		       "mfgpt-timer:  Unable to set up the interrupt.\n");
-		goto err;
-	}
-
-	/* Set the clock scale and enable the event mode for CMP2 */
-	val = MFGPT_SCALE | (3 << 8);
-
-	geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
-
-	/* Set up the clock event */
-	mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC,
-				       mfgpt_clockevent.shift);
-	mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF,
-			&mfgpt_clockevent);
-	mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE,
-			&mfgpt_clockevent);
-
-	printk(KERN_INFO
-	       "mfgpt-timer:  Registering MFGPT timer %d as a clock event, using IRQ %d\n",
-	       timer, irq);
-	clockevents_register_device(&mfgpt_clockevent);
-
-	return 0;
-
-err:
-	geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, &irq);
-	printk(KERN_ERR
-	       "mfgpt-timer:  Unable to set up the MFGPT clock source\n");
-	return -EIO;
-}
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_amd.c linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_amd.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_amd.c	2013-05-03 13:54:53.000000000 -0400
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_amd.c	2013-05-03 12:02:41.000000000 -0400
@@ -13,6 +13,9 @@
  *  Licensed under the terms of the GNU General Public
  *  License version 2. See file COPYING for details.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/firmware.h>
 #include <linux/pci_ids.h>
 #include <linux/uaccess.h>
@@ -76,12 +79,12 @@ static int collect_cpu_info_amd(int cpu,
 
 	memset(csig, 0, sizeof(*csig));
 	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
-		printk(KERN_WARNING "microcode: CPU%d: AMD CPU family 0x%x not "
-		       "supported\n", cpu, c->x86);
+		pr_warning("microcode: CPU%d: AMD CPU family 0x%x not "
+			   "supported\n", cpu, c->x86);
 		return -1;
 	}
 	rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
-	printk(KERN_INFO "microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev);
+	pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev);
 	return 0;
 }
 
@@ -103,23 +106,16 @@ static int get_matching_microcode(int cp
 		i++;
 	}
 
-	if (!equiv_cpu_id) {
-		printk(KERN_WARNING "microcode: CPU%d: cpu revision "
-		       "not listed in equivalent cpu table\n", cpu);
+	if (!equiv_cpu_id)
 		return 0;
-	}
 
-	if (mc_header->processor_rev_id != equiv_cpu_id) {
-		printk(KERN_ERR	"microcode: CPU%d: patch mismatch "
-		       "(processor_rev_id: %x, equiv_cpu_id: %x)\n",
-		       cpu, mc_header->processor_rev_id, equiv_cpu_id);
+	if (mc_header->processor_rev_id != equiv_cpu_id)
 		return 0;
-	}
 
 	/* ucode might be chipset specific -- currently we don't support this */
 	if (mc_header->nb_dev_id || mc_header->sb_dev_id) {
-		printk(KERN_ERR "microcode: CPU%d: loading of chipset "
-		       "specific code not yet supported\n", cpu);
+		pr_err("CPU%d: loading of chipset specific code not yet supported\n",
+		       cpu);
 		return 0;
 	}
 
@@ -148,14 +144,12 @@ static int apply_microcode_amd(int cpu)
 
 	/* check current patch id and patch's id for match */
 	if (rev != mc_amd->hdr.patch_id) {
-		printk(KERN_ERR "microcode: CPU%d: update failed "
-		       "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id);
+		pr_err("CPU%d: update failed (for patch_level=0x%x)\n",
+		       cpu, mc_amd->hdr.patch_id);
 		return -1;
 	}
 
-	printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n",
-	       cpu, rev);
-
+	pr_info("CPU%d: updated (new patch_level=0x%x)\n", cpu, rev);
 	uci->cpu_sig.rev = rev;
 
 	return 0;
@@ -178,18 +172,14 @@ get_next_ucode(const u8 *buf, unsigned i
 		return NULL;
 
 	if (section_hdr[0] != UCODE_UCODE_TYPE) {
-		printk(KERN_ERR "microcode: error: invalid type field in "
-		       "container file section header\n");
+		pr_err("error: invalid type field in container file section header\n");
 		return NULL;
 	}
 
 	total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
 
-	printk(KERN_DEBUG "microcode: size %u, total_size %u\n",
-	       size, total_size);
-
 	if (total_size > size || total_size > UCODE_MAX_SIZE) {
-		printk(KERN_ERR "microcode: error: size mismatch\n");
+		pr_err("error: size mismatch\n");
 		return NULL;
 	}
 
@@ -218,15 +208,13 @@ static int install_equiv_cpu_table(const
 	size = buf_pos[2];
 
 	if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {
-		printk(KERN_ERR "microcode: error: invalid type field in "
-		       "container file section header\n");
+		pr_err("error: invalid type field in container file section header\n");
 		return 0;
 	}
 
 	equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
 	if (!equiv_cpu_table) {
-		printk(KERN_ERR "microcode: failed to allocate "
-		       "equivalent CPU table\n");
+		pr_err("failed to allocate equivalent CPU table\n");
 		return 0;
 	}
 
@@ -259,8 +247,7 @@ generic_load_microcode(int cpu, const u8
 
 	offset = install_equiv_cpu_table(ucode_ptr);
 	if (!offset) {
-		printk(KERN_ERR "microcode: failed to create "
-		       "equivalent cpu table\n");
+		pr_err("failed to create equivalent cpu table\n");
 		return UCODE_ERROR;
 	}
 
@@ -291,8 +278,7 @@ generic_load_microcode(int cpu, const u8
 		if (!leftover) {
 			vfree(uci->mc);
 			uci->mc = new_mc;
-			pr_debug("microcode: CPU%d found a matching microcode "
-				 "update with version 0x%x (current=0x%x)\n",
+			pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
 				 cpu, new_rev, uci->cpu_sig.rev);
 		} else {
 			vfree(new_mc);
@@ -318,7 +304,7 @@ static enum ucode_state request_microcod
 	}
 
 	if (*(u32 *)firmware->data != UCODE_MAGIC) {
-		printk(KERN_ERR "microcode: invalid UCODE_MAGIC (0x%08x)\n",
+		pr_err("invalid UCODE_MAGIC (0x%08x)\n",
 		       *(u32 *)firmware->data);
 		return UCODE_ERROR;
 	}
@@ -333,8 +319,7 @@ static enum ucode_state request_microcod
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
-	printk(KERN_INFO "microcode: AMD microcode update via "
-	       "/dev/cpu/microcode not supported\n");
+	pr_info("AMD microcode update via /dev/cpu/microcode not supported\n");
 	return UCODE_ERROR;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_core.c linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_core.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,10 +70,12 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/platform_device.h>
 #include <linux/miscdevice.h>
 #include <linux/capability.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -201,7 +203,6 @@ static int do_microcode_update(const voi
 
 static int microcode_open(struct inode *unused1, struct file *unused2)
 {
-	cycle_kernel_lock();
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }
 
@@ -211,7 +212,7 @@ static ssize_t microcode_write(struct fi
 	ssize_t ret = -EINVAL;
 
 	if ((len >> PAGE_SHIFT) > totalram_pages) {
-		pr_err("microcode: too much data (max %ld pages)\n", totalram_pages);
+		pr_err("too much data (max %ld pages)\n", totalram_pages);
 		return ret;
 	}
 
@@ -246,7 +247,7 @@ static int __init microcode_dev_init(voi
 
 	error = misc_register(&microcode_dev);
 	if (error) {
-		pr_err("microcode: can't misc_register on minor=%d\n", MICROCODE_MINOR);
+		pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
 		return error;
 	}
 
@@ -361,7 +362,7 @@ static enum ucode_state microcode_resume
 	if (!uci->mc)
 		return UCODE_NFOUND;
 
-	pr_debug("microcode: CPU%d updated upon resume\n", cpu);
+	pr_debug("CPU%d updated upon resume\n", cpu);
 	apply_microcode_on_target(cpu);
 
 	return UCODE_OK;
@@ -381,7 +382,7 @@ static enum ucode_state microcode_init_c
 	ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev);
 
 	if (ustate == UCODE_OK) {
-		pr_debug("microcode: CPU%d updated upon init\n", cpu);
+		pr_debug("CPU%d updated upon init\n", cpu);
 		apply_microcode_on_target(cpu);
 	}
 
@@ -408,7 +409,7 @@ static int mc_sysdev_add(struct sys_devi
 	if (!cpu_online(cpu))
 		return 0;
 
-	pr_debug("microcode: CPU%d added\n", cpu);
+	pr_debug("CPU%d added\n", cpu);
 
 	err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
 	if (err)
@@ -427,7 +428,7 @@ static int mc_sysdev_remove(struct sys_d
 	if (!cpu_online(cpu))
 		return 0;
 
-	pr_debug("microcode: CPU%d removed\n", cpu);
+	pr_debug("CPU%d removed\n", cpu);
 	microcode_fini_cpu(cpu);
 	sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
 	return 0;
@@ -475,15 +476,15 @@ mc_cpu_callback(struct notifier_block *n
 		microcode_update_cpu(cpu);
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
-		pr_debug("microcode: CPU%d added\n", cpu);
+		pr_debug("CPU%d added\n", cpu);
 		if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
-			pr_err("microcode: Failed to create group for CPU%d\n", cpu);
+			pr_err("Failed to create group for CPU%d\n", cpu);
 		break;
 	case CPU_DOWN_PREPARE:
 	case CPU_DOWN_PREPARE_FROZEN:
 		/* Suspend is in progress, only remove the interface */
 		sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
-		pr_debug("microcode: CPU%d removed\n", cpu);
+		pr_debug("CPU%d removed\n", cpu);
 		break;
 	case CPU_DEAD:
 	case CPU_UP_CANCELED_FROZEN:
@@ -509,7 +510,7 @@ static int __init microcode_init(void)
 		microcode_ops = init_amd_microcode();
 
 	if (!microcode_ops) {
-		pr_err("microcode: no support for this CPU vendor\n");
+		pr_err("no support for this CPU vendor\n");
 		return -ENODEV;
 	}
 
@@ -540,8 +541,7 @@ static int __init microcode_init(void)
 	register_hotcpu_notifier(&mc_cpu_notifier);
 
 	pr_info("Microcode Update Driver: v" MICROCODE_VERSION
-	       " <tigran@aivazian.fsnet.co.uk>,"
-	       " Peter Oruba\n");
+		" <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n");
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_intel.c linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_intel.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 13:54:55.000000000 -0400
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 12:02:43.000000000 -0400
@@ -70,6 +70,9 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/firmware.h>
 #include <linux/uaccess.h>
 #include <linux/kernel.h>
@@ -146,8 +149,7 @@ static int collect_cpu_info(int cpu_num,
 
 	if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
 	    cpu_has(c, X86_FEATURE_IA64)) {
-		printk(KERN_ERR "microcode: CPU%d not a capable Intel "
-			"processor\n", cpu_num);
+		pr_err("CPU%d not a capable Intel processor\n", cpu_num);
 		return -1;
 	}
 
@@ -165,8 +167,8 @@ static int collect_cpu_info(int cpu_num,
 	/* get the current revision from MSR 0x8B */
 	rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
 
-	printk(KERN_INFO "microcode: CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
-			cpu_num, csig->sig, csig->pf, csig->rev);
+	pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
+		cpu_num, csig->sig, csig->pf, csig->rev);
 
 	return 0;
 }
@@ -194,28 +196,24 @@ static int microcode_sanity_check(void *
 	data_size = get_datasize(mc_header);
 
 	if (data_size + MC_HEADER_SIZE > total_size) {
-		printk(KERN_ERR "microcode: error! "
-				"Bad data size in microcode data file\n");
+		pr_err("error! Bad data size in microcode data file\n");
 		return -EINVAL;
 	}
 
 	if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
-		printk(KERN_ERR "microcode: error! "
-				"Unknown microcode update format\n");
+		pr_err("error! Unknown microcode update format\n");
 		return -EINVAL;
 	}
 	ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
 	if (ext_table_size) {
 		if ((ext_table_size < EXT_HEADER_SIZE)
 		 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
-			printk(KERN_ERR "microcode: error! "
-				"Small exttable size in microcode data file\n");
+			pr_err("error! Small exttable size in microcode data file\n");
 			return -EINVAL;
 		}
 		ext_header = mc + MC_HEADER_SIZE + data_size;
 		if (ext_table_size != exttable_size(ext_header)) {
-			printk(KERN_ERR "microcode: error! "
-				"Bad exttable size in microcode data file\n");
+			pr_err("error! Bad exttable size in microcode data file\n");
 			return -EFAULT;
 		}
 		ext_sigcount = ext_header->count;
@@ -230,8 +228,7 @@ static int microcode_sanity_check(void *
 		while (i--)
 			ext_table_sum += ext_tablep[i];
 		if (ext_table_sum) {
-			printk(KERN_WARNING "microcode: aborting, "
-				"bad extended signature table checksum\n");
+			pr_warning("aborting, bad extended signature table checksum\n");
 			return -EINVAL;
 		}
 	}
@@ -242,7 +239,7 @@ static int microcode_sanity_check(void *
 	while (i--)
 		orig_sum += ((int *)mc)[i];
 	if (orig_sum) {
-		printk(KERN_ERR "microcode: aborting, bad checksum\n");
+		pr_err("aborting, bad checksum\n");
 		return -EINVAL;
 	}
 	if (!ext_table_size)
@@ -255,7 +252,7 @@ static int microcode_sanity_check(void *
 			- (mc_header->sig + mc_header->pf + mc_header->cksum)
 			+ (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
 		if (sum) {
-			printk(KERN_ERR "microcode: aborting, bad checksum\n");
+			pr_err("aborting, bad checksum\n");
 			return -EINVAL;
 		}
 	}
@@ -327,13 +324,11 @@ static int apply_microcode(int cpu)
 	rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
 
 	if (val[1] != mc_intel->hdr.rev) {
-		printk(KERN_ERR "microcode: CPU%d update "
-				"to revision 0x%x failed\n",
-			cpu_num, mc_intel->hdr.rev);
+		pr_err("CPU%d update to revision 0x%x failed\n",
+		       cpu_num, mc_intel->hdr.rev);
 		return -1;
 	}
-	printk(KERN_INFO "microcode: CPU%d updated to revision "
-			 "0x%x, date = %04x-%02x-%02x \n",
+	pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x \n",
 		cpu_num, val[1],
 		mc_intel->hdr.date & 0xffff,
 		mc_intel->hdr.date >> 24,
@@ -362,8 +357,7 @@ static enum ucode_state generic_load_mic
 
 		mc_size = get_totalsize(&mc_header);
 		if (!mc_size || mc_size > leftover) {
-			printk(KERN_ERR "microcode: error!"
-					"Bad data in microcode data file\n");
+			pr_err("error! Bad data in microcode data file\n");
 			break;
 		}
 
@@ -405,9 +399,8 @@ static enum ucode_state generic_load_mic
 		vfree(uci->mc);
 	uci->mc = (struct microcode_intel *)new_mc;
 
-	pr_debug("microcode: CPU%d found a matching microcode update with"
-		 " version 0x%x (current=0x%x)\n",
-			cpu, new_rev, uci->cpu_sig.rev);
+	pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
+		 cpu, new_rev, uci->cpu_sig.rev);
 out:
 	return state;
 }
@@ -429,7 +422,7 @@ static enum ucode_state request_microcod
 		c->x86, c->x86_model, c->x86_mask);
 
 	if (reject_firmware(&firmware, name, device)) {
-		pr_debug("microcode: data file %s load failed\n", name);
+		pr_debug("data file %s load failed\n", name);
 		return UCODE_NFOUND;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/mpparse.c linux-libre-2.6.33-gnu1/arch/x86/kernel/mpparse.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/mpparse.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/mpparse.c	2010-02-24 13:52:17.000000000 -0500
@@ -359,13 +359,6 @@ static int __init smp_read_mpc(struct mp
 		x86_init.mpparse.mpc_record(1);
 	}
 
-#ifdef CONFIG_X86_BIGSMP
-	generic_bigsmp_probe();
-#endif
-
-	if (apic->setup_apic_routing)
-		apic->setup_apic_routing();
-
 	if (!num_processors)
 		printk(KERN_ERR "MPTABLE: no processors registered!\n");
 	return num_processors;
@@ -667,36 +660,18 @@ void __init default_get_smp_config(unsig
 	 */
 }
 
-static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
+static void __init smp_reserve_memory(struct mpf_intel *mpf)
 {
 	unsigned long size = get_mpc_size(mpf->physptr);
-#ifdef CONFIG_X86_32
-	/*
-	 * We cannot access to MPC table to compute table size yet,
-	 * as only few megabytes from the bottom is mapped now.
-	 * PC-9800's MPC table places on the very last of physical
-	 * memory; so that simply reserving PAGE_SIZE from mpf->physptr
-	 * yields BUG() in reserve_bootmem.
-	 * also need to make sure physptr is below than max_low_pfn
-	 * we don't need reserve the area above max_low_pfn
-	 */
-	unsigned long end = max_low_pfn * PAGE_SIZE;
 
-	if (mpf->physptr < end) {
-		if (mpf->physptr + size > end)
-			size = end - mpf->physptr;
-		reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
-	}
-#else
-	reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
-#endif
+	reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc");
 }
 
-static int __init smp_scan_config(unsigned long base, unsigned long length,
-				  unsigned reserve)
+static int __init smp_scan_config(unsigned long base, unsigned long length)
 {
 	unsigned int *bp = phys_to_virt(base);
 	struct mpf_intel *mpf;
+	unsigned long mem;
 
 	apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n",
 			bp, length);
@@ -717,12 +692,10 @@ static int __init smp_scan_config(unsign
 			printk(KERN_INFO "found SMP MP-table at [%p] %llx\n",
 			       mpf, (u64)virt_to_phys(mpf));
 
-			if (!reserve)
-				return 1;
-			reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
-						BOOTMEM_DEFAULT);
+			mem = virt_to_phys(mpf);
+			reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf");
 			if (mpf->physptr)
-				smp_reserve_bootmem(mpf);
+				smp_reserve_memory(mpf);
 
 			return 1;
 		}
@@ -732,7 +705,7 @@ static int __init smp_scan_config(unsign
 	return 0;
 }
 
-void __init default_find_smp_config(unsigned int reserve)
+void __init default_find_smp_config(void)
 {
 	unsigned int address;
 
@@ -744,9 +717,9 @@ void __init default_find_smp_config(unsi
 	 * 2) Scan the top 1K of base RAM
 	 * 3) Scan the 64K of bios
 	 */
-	if (smp_scan_config(0x0, 0x400, reserve) ||
-	    smp_scan_config(639 * 0x400, 0x400, reserve) ||
-	    smp_scan_config(0xF0000, 0x10000, reserve))
+	if (smp_scan_config(0x0, 0x400) ||
+	    smp_scan_config(639 * 0x400, 0x400) ||
+	    smp_scan_config(0xF0000, 0x10000))
 		return;
 	/*
 	 * If it is an SMP machine we should know now, unless the
@@ -767,7 +740,7 @@ void __init default_find_smp_config(unsi
 
 	address = get_bios_ebda();
 	if (address)
-		smp_scan_config(address, 0x400, reserve);
+		smp_scan_config(address, 0x400);
 }
 
 #ifdef CONFIG_X86_IO_APIC
@@ -965,9 +938,6 @@ void __init early_reserve_e820_mpc_new(v
 {
 	if (enable_update_mptable && alloc_mptable) {
 		u64 startt = 0;
-#ifdef CONFIG_X86_TRAMPOLINE
-		startt = TRAMPOLINE_BASE;
-#endif
 		mpc_new_phys = early_reserve_e820(startt, mpc_new_length, 4);
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/msr.c linux-libre-2.6.33-gnu1/arch/x86/kernel/msr.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/msr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/msr.c	2010-02-24 13:52:17.000000000 -0500
@@ -172,23 +172,18 @@ static long msr_ioctl(struct file *file,
 
 static int msr_open(struct inode *inode, struct file *file)
 {
-	unsigned int cpu = iminor(file->f_path.dentry->d_inode);
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
-	int ret = 0;
+	unsigned int cpu;
+	struct cpuinfo_x86 *c;
 
-	lock_kernel();
 	cpu = iminor(file->f_path.dentry->d_inode);
+	if (cpu >= nr_cpu_ids || !cpu_online(cpu))
+		return -ENXIO;	/* No such CPU */
 
-	if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
-		ret = -ENXIO;	/* No such CPU */
-		goto out;
-	}
 	c = &cpu_data(cpu);
 	if (!cpu_has(c, X86_FEATURE_MSR))
-		ret = -EIO;	/* MSR not supported */
-out:
-	unlock_kernel();
-	return ret;
+		return -EIO;	/* MSR not supported */
+
+	return 0;
 }
 
 /*
@@ -251,7 +246,7 @@ static int __init msr_init(void)
 	int i, err = 0;
 	i = 0;
 
-	if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+	if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
 		printk(KERN_ERR "msr: unable to get major %d for msr\n",
 		       MSR_MAJOR);
 		err = -EBUSY;
@@ -279,7 +274,7 @@ out_class:
 		msr_device_destroy(i);
 	class_destroy(msr_class);
 out_chrdev:
-	unregister_chrdev(MSR_MAJOR, "cpu/msr");
+	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
 out:
 	return err;
 }
@@ -290,7 +285,7 @@ static void __exit msr_exit(void)
 	for_each_online_cpu(cpu)
 		msr_device_destroy(cpu);
 	class_destroy(msr_class);
-	unregister_chrdev(MSR_MAJOR, "cpu/msr");
+	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
 	unregister_hotcpu_notifier(&msr_class_cpu_notifier);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/olpc.c linux-libre-2.6.33-gnu1/arch/x86/kernel/olpc.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/olpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/olpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,7 @@ static int __init olpc_init(void)
 	unsigned char *romsig;
 
 	/* The ioremap check is dangerous; limit what we run it on */
-	if (!is_geode() || geode_has_vsa2())
+	if (!is_geode() || cs5535_has_vsa2())
 		return 0;
 
 	spin_lock_init(&ec_lock);
@@ -244,7 +244,7 @@ static int __init olpc_init(void)
 			(unsigned char *) &olpc_platform_info.ecver, 1);
 
 	/* check to see if the VSA exists */
-	if (geode_has_vsa2())
+	if (cs5535_has_vsa2())
 		olpc_platform_info.flags |= OLPC_F_VSA;
 
 	printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/paravirt-spinlocks.c linux-libre-2.6.33-gnu1/arch/x86/kernel/paravirt-spinlocks.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/paravirt-spinlocks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/paravirt-spinlocks.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,9 +8,9 @@
 #include <asm/paravirt.h>
 
 static inline void
-default_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+default_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 {
-	__raw_spin_lock(lock);
+	arch_spin_lock(lock);
 }
 
 struct pv_lock_ops pv_lock_ops = {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-calgary_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-calgary_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-calgary_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-calgary_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 #include <linux/string.h>
 #include <linux/crash_dump.h>
 #include <linux/dma-mapping.h>
-#include <linux/bitops.h>
+#include <linux/bitmap.h>
 #include <linux/pci_ids.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -46,6 +46,7 @@
 #include <asm/dma.h>
 #include <asm/rio.h>
 #include <asm/bios_ebda.h>
+#include <asm/x86_init.h>
 
 #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
 int use_calgary __read_mostly = 1;
@@ -211,7 +212,7 @@ static void iommu_range_reserve(struct i
 
 	spin_lock_irqsave(&tbl->it_lock, flags);
 
-	iommu_area_reserve(tbl->it_map, index, npages);
+	bitmap_set(tbl->it_map, index, npages);
 
 	spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
@@ -244,7 +245,7 @@ static unsigned long iommu_range_alloc(s
 			if (panic_on_overflow)
 				panic("Calgary: fix the allocator.\n");
 			else
-				return bad_dma_address;
+				return DMA_ERROR_CODE;
 		}
 	}
 
@@ -260,12 +261,15 @@ static dma_addr_t iommu_alloc(struct dev
 			      void *vaddr, unsigned int npages, int direction)
 {
 	unsigned long entry;
-	dma_addr_t ret = bad_dma_address;
+	dma_addr_t ret;
 
 	entry = iommu_range_alloc(dev, tbl, npages);
 
-	if (unlikely(entry == bad_dma_address))
-		goto error;
+	if (unlikely(entry == DMA_ERROR_CODE)) {
+		printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
+		       "iommu %p\n", npages, tbl);
+		return DMA_ERROR_CODE;
+	}
 
 	/* set the return dma address */
 	ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
@@ -273,13 +277,7 @@ static dma_addr_t iommu_alloc(struct dev
 	/* put the TCEs in the HW table */
 	tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
 		  direction);
-
 	return ret;
-
-error:
-	printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
-	       "iommu %p\n", npages, tbl);
-	return bad_dma_address;
 }
 
 static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -290,8 +288,8 @@ static void iommu_free(struct iommu_tabl
 	unsigned long flags;
 
 	/* were we called with bad_dma_address? */
-	badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
-	if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
+	badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
+	if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
 		WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
 		       "address 0x%Lx\n", dma_addr);
 		return;
@@ -305,7 +303,7 @@ static void iommu_free(struct iommu_tabl
 
 	spin_lock_irqsave(&tbl->it_lock, flags);
 
-	iommu_area_free(tbl->it_map, entry, npages);
+	bitmap_clear(tbl->it_map, entry, npages);
 
 	spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
@@ -318,13 +316,15 @@ static inline struct iommu_table *find_i
 
 	pdev = to_pci_dev(dev);
 
+	/* search up the device tree for an iommu */
 	pbus = pdev->bus;
-
-	/* is the device behind a bridge? Look for the root bus */
-	while (pbus->parent)
+	do {
+		tbl = pci_iommu(pbus);
+		if (tbl && tbl->it_busno == pbus->number)
+			break;
+		tbl = NULL;
 		pbus = pbus->parent;
-
-	tbl = pci_iommu(pbus);
+	} while (pbus);
 
 	BUG_ON(tbl && (tbl->it_busno != pbus->number));
 
@@ -373,7 +373,7 @@ static int calgary_map_sg(struct device
 		npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
 
 		entry = iommu_range_alloc(dev, tbl, npages);
-		if (entry == bad_dma_address) {
+		if (entry == DMA_ERROR_CODE) {
 			/* makes sure unmap knows to stop */
 			s->dma_length = 0;
 			goto error;
@@ -391,7 +391,7 @@ static int calgary_map_sg(struct device
 error:
 	calgary_unmap_sg(dev, sg, nelems, dir, NULL);
 	for_each_sg(sg, s, nelems, i) {
-		sg->dma_address = bad_dma_address;
+		sg->dma_address = DMA_ERROR_CODE;
 		sg->dma_length = 0;
 	}
 	return 0;
@@ -446,7 +446,7 @@ static void* calgary_alloc_coherent(stru
 
 	/* set up tces to cover the allocated range */
 	mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL);
-	if (mapping == bad_dma_address)
+	if (mapping == DMA_ERROR_CODE)
 		goto free;
 	*dma_handle = mapping;
 	return ret;
@@ -727,7 +727,7 @@ static void __init calgary_reserve_regio
 	struct iommu_table *tbl = pci_iommu(dev->bus);
 
 	/* reserve EMERGENCY_PAGES from bad_dma_address and up */
-	iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
+	iommu_range_reserve(tbl, DMA_ERROR_CODE, EMERGENCY_PAGES);
 
 	/* avoid the BIOS/VGA first 640KB-1MB region */
 	/* for CalIOC2 - avoid the entire first MB */
@@ -1344,6 +1344,23 @@ static void __init get_tce_space_from_ta
 	return;
 }
 
+static int __init calgary_iommu_init(void)
+{
+	int ret;
+
+	/* ok, we're trying to use Calgary - let's roll */
+	printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
+
+	ret = calgary_init();
+	if (ret) {
+		printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
+		       "falling back to no_iommu\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 void __init detect_calgary(void)
 {
 	int bus;
@@ -1357,7 +1374,7 @@ void __init detect_calgary(void)
 	 * if the user specified iommu=off or iommu=soft or we found
 	 * another HW IOMMU already, bail out.
 	 */
-	if (swiotlb || no_iommu || iommu_detected)
+	if (no_iommu || iommu_detected)
 		return;
 
 	if (!use_calgary)
@@ -1442,9 +1459,7 @@ void __init detect_calgary(void)
 		printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n",
 		       specified_table_size);
 
-		/* swiotlb for devices that aren't behind the Calgary. */
-		if (max_pfn > MAX_DMA32_PFN)
-			swiotlb = 1;
+		x86_init.iommu.iommu_init = calgary_iommu_init;
 	}
 	return;
 
@@ -1457,35 +1472,6 @@ cleanup:
 	}
 }
 
-int __init calgary_iommu_init(void)
-{
-	int ret;
-
-	if (no_iommu || (swiotlb && !calgary_detected))
-		return -ENODEV;
-
-	if (!calgary_detected)
-		return -ENODEV;
-
-	/* ok, we're trying to use Calgary - let's roll */
-	printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
-
-	ret = calgary_init();
-	if (ret) {
-		printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
-		       "falling back to no_iommu\n", ret);
-		return ret;
-	}
-
-	force_iommu = 1;
-	bad_dma_address = 0x0;
-	/* dma_ops is set to swiotlb or nommu */
-	if (!dma_ops)
-		dma_ops = &nommu_dma_ops;
-
-	return 0;
-}
-
 static int __init calgary_parse_options(char *p)
 {
 	unsigned int bridge;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-dma.c linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-dma.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,10 +11,11 @@
 #include <asm/gart.h>
 #include <asm/calgary.h>
 #include <asm/amd_iommu.h>
+#include <asm/x86_init.h>
 
 static int forbid_dac __read_mostly;
 
-struct dma_map_ops *dma_ops;
+struct dma_map_ops *dma_ops = &nommu_dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
 static int iommu_sac_force __read_mostly;
@@ -42,9 +43,6 @@ int iommu_detected __read_mostly = 0;
  */
 int iommu_pass_through __read_mostly;
 
-dma_addr_t bad_dma_address __read_mostly = 0;
-EXPORT_SYMBOL(bad_dma_address);
-
 /* Dummy device used for NULL arguments (normally ISA). */
 struct device x86_dma_fallback_dev = {
 	.init_name = "fallback device",
@@ -126,19 +124,18 @@ void __init pci_iommu_alloc(void)
 	/* free the range so iommu could get some range less than 4G */
 	dma32_free_bootmem();
 #endif
+	if (pci_swiotlb_detect())
+		goto out;
 
-	/*
-	 * The order of these functions is important for
-	 * fall-back/fail-over reasons
-	 */
 	gart_iommu_hole_init();
 
 	detect_calgary();
 
 	detect_intel_iommu();
 
+	/* needs to be called after gart_iommu_hole_init */
 	amd_iommu_detect();
-
+out:
 	pci_swiotlb_init();
 }
 
@@ -214,7 +211,7 @@ static __init int iommu_setup(char *p)
 		if (!strncmp(p, "allowdac", 8))
 			forbid_dac = 0;
 		if (!strncmp(p, "nodac", 5))
-			forbid_dac = -1;
+			forbid_dac = 1;
 		if (!strncmp(p, "usedac", 6)) {
 			forbid_dac = -1;
 			return 1;
@@ -289,25 +286,17 @@ static int __init pci_iommu_init(void)
 #ifdef CONFIG_PCI
 	dma_debug_add_bus(&pci_bus_type);
 #endif
+	x86_init.iommu.iommu_init();
 
-	calgary_iommu_init();
-
-	intel_iommu_init();
-
-	amd_iommu_init();
-
-	gart_iommu_init();
+	if (swiotlb) {
+		printk(KERN_INFO "PCI-DMA: "
+		       "Using software bounce buffering for IO (SWIOTLB)\n");
+		swiotlb_print_info();
+	} else
+		swiotlb_free();
 
-	no_iommu_init();
 	return 0;
 }
-
-void pci_iommu_shutdown(void)
-{
-	gart_iommu_shutdown();
-
-	amd_iommu_shutdown();
-}
 /* Must execute after PCI subsystem */
 rootfs_initcall(pci_iommu_init);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-gart_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-gart_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-gart_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-gart_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #include <linux/module.h>
 #include <linux/topology.h>
 #include <linux/interrupt.h>
-#include <linux/bitops.h>
+#include <linux/bitmap.h>
 #include <linux/kdebug.h>
 #include <linux/scatterlist.h>
 #include <linux/iommu-helper.h>
@@ -39,6 +39,7 @@
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
 #include <asm/k8.h>
+#include <asm/x86_init.h>
 
 static unsigned long iommu_bus_base;	/* GART remapping area (physical) */
 static unsigned long iommu_size;	/* size of remapping area bytes */
@@ -46,6 +47,8 @@ static unsigned long iommu_pages;	/* ..
 
 static u32 *iommu_gatt_base;		/* Remapping table */
 
+static dma_addr_t bad_dma_addr;
+
 /*
  * If this is disabled the IOMMU will use an optimized flushing strategy
  * of only flushing when an mapping is reused. With it true the GART is
@@ -92,7 +95,7 @@ static unsigned long alloc_iommu(struct
 
 	base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
 			   PAGE_SIZE) >> PAGE_SHIFT;
-	boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+	boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
 			      PAGE_SIZE) >> PAGE_SHIFT;
 
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);
@@ -123,7 +126,7 @@ static void free_iommu(unsigned long off
 	unsigned long flags;
 
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);
-	iommu_area_free(iommu_gart_bitmap, offset, size);
+	bitmap_clear(iommu_gart_bitmap, offset, size);
 	if (offset >= next_bit)
 		next_bit = offset + size;
 	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
@@ -216,7 +219,7 @@ static dma_addr_t dma_map_area(struct de
 		if (panic_on_overflow)
 			panic("dma_map_area overflow %lu bytes\n", size);
 		iommu_full(dev, size, dir);
-		return bad_dma_address;
+		return bad_dma_addr;
 	}
 
 	for (i = 0; i < npages; i++) {
@@ -294,7 +297,7 @@ static int dma_map_sg_nonforce(struct de
 	int i;
 
 #ifdef CONFIG_IOMMU_DEBUG
-	printk(KERN_DEBUG "dma_map_sg overflow\n");
+	pr_debug("dma_map_sg overflow\n");
 #endif
 
 	for_each_sg(sg, s, nents, i) {
@@ -302,7 +305,7 @@ static int dma_map_sg_nonforce(struct de
 
 		if (nonforced_iommu(dev, addr, s->length)) {
 			addr = dma_map_area(dev, addr, s->length, dir, 0);
-			if (addr == bad_dma_address) {
+			if (addr == bad_dma_addr) {
 				if (i > 0)
 					gart_unmap_sg(dev, sg, i, dir, NULL);
 				nents = 0;
@@ -389,12 +392,14 @@ static int gart_map_sg(struct device *de
 	if (!dev)
 		dev = &x86_dma_fallback_dev;
 
-	out = 0;
-	start = 0;
-	start_sg = sgmap = sg;
-	seg_size = 0;
-	max_seg_size = dma_get_max_seg_size(dev);
-	ps = NULL; /* shut up gcc */
+	out		= 0;
+	start		= 0;
+	start_sg	= sg;
+	sgmap		= sg;
+	seg_size	= 0;
+	max_seg_size	= dma_get_max_seg_size(dev);
+	ps		= NULL; /* shut up gcc */
+
 	for_each_sg(sg, s, nents, i) {
 		dma_addr_t addr = sg_phys(s);
 
@@ -417,11 +422,12 @@ static int gart_map_sg(struct device *de
 						 sgmap, pages, need) < 0)
 					goto error;
 				out++;
-				seg_size = 0;
-				sgmap = sg_next(sgmap);
-				pages = 0;
-				start = i;
-				start_sg = s;
+
+				seg_size	= 0;
+				sgmap		= sg_next(sgmap);
+				pages		= 0;
+				start		= i;
+				start_sg	= s;
 			}
 		}
 
@@ -455,7 +461,7 @@ error:
 
 	iommu_full(dev, pages << PAGE_SHIFT, dir);
 	for_each_sg(sg, s, nents, i)
-		s->dma_address = bad_dma_address;
+		s->dma_address = bad_dma_addr;
 	return 0;
 }
 
@@ -479,7 +485,7 @@ gart_alloc_coherent(struct device *dev,
 				     DMA_BIDIRECTIONAL, align_mask);
 
 		flush_gart();
-		if (paddr != bad_dma_address) {
+		if (paddr != bad_dma_addr) {
 			*dma_addr = paddr;
 			return page_address(page);
 		}
@@ -499,6 +505,11 @@ gart_free_coherent(struct device *dev, s
 	free_pages((unsigned long)vaddr, get_order(size));
 }
 
+static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return (dma_addr == bad_dma_addr);
+}
+
 static int no_agp;
 
 static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
@@ -515,7 +526,7 @@ static __init unsigned long check_iommu_
 	iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
 
 	if (iommu_size < 64*1024*1024) {
-		printk(KERN_WARNING
+		pr_warning(
 			"PCI-DMA: Warning: Small IOMMU %luMB."
 			" Consider increasing the AGP aperture in BIOS\n",
 				iommu_size >> 20);
@@ -570,28 +581,32 @@ void set_up_gart_resume(u32 aper_order,
 	aperture_alloc = aper_alloc;
 }
 
-static int gart_resume(struct sys_device *dev)
+static void gart_fixup_northbridges(struct sys_device *dev)
 {
-	printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n");
+	int i;
 
-	if (fix_up_north_bridges) {
-		int i;
+	if (!fix_up_north_bridges)
+		return;
 
-		printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n");
+	pr_info("PCI-DMA: Restoring GART aperture settings\n");
 
-		for (i = 0; i < num_k8_northbridges; i++) {
-			struct pci_dev *dev = k8_northbridges[i];
+	for (i = 0; i < num_k8_northbridges; i++) {
+		struct pci_dev *dev = k8_northbridges[i];
 
-			/*
-			 * Don't enable translations just yet.  That is the next
-			 * step.  Restore the pre-suspend aperture settings.
-			 */
-			pci_write_config_dword(dev, AMD64_GARTAPERTURECTL,
-						aperture_order << 1);
-			pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE,
-						aperture_alloc >> 25);
-		}
+		/*
+		 * Don't enable translations just yet.  That is the next
+		 * step.  Restore the pre-suspend aperture settings.
+		 */
+		pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, aperture_order << 1);
+		pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
 	}
+}
+
+static int gart_resume(struct sys_device *dev)
+{
+	pr_info("PCI-DMA: Resuming GART IOMMU\n");
+
+	gart_fixup_northbridges(dev);
 
 	enable_gart_translations();
 
@@ -604,15 +619,14 @@ static int gart_suspend(struct sys_devic
 }
 
 static struct sysdev_class gart_sysdev_class = {
-	.name = "gart",
-	.suspend = gart_suspend,
-	.resume = gart_resume,
+	.name		= "gart",
+	.suspend	= gart_suspend,
+	.resume		= gart_resume,
 
 };
 
 static struct sys_device device_gart = {
-	.id	= 0,
-	.cls	= &gart_sysdev_class,
+	.cls		= &gart_sysdev_class,
 };
 
 /*
@@ -627,7 +641,8 @@ static __init int init_k8_gatt(struct ag
 	void *gatt;
 	int i, error;
 
-	printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
+	pr_info("PCI-DMA: Disabling AGP.\n");
+
 	aper_size = aper_base = info->aper_size = 0;
 	dev = NULL;
 	for (i = 0; i < num_k8_northbridges; i++) {
@@ -645,6 +660,7 @@ static __init int init_k8_gatt(struct ag
 	}
 	if (!aper_base)
 		goto nommu;
+
 	info->aper_base = aper_base;
 	info->aper_size = aper_size >> 20;
 
@@ -667,14 +683,14 @@ static __init int init_k8_gatt(struct ag
 
 	flush_gart();
 
-	printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
+	pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
 	       aper_base, aper_size>>10);
 
 	return 0;
 
  nommu:
 	/* Should not happen anymore */
-	printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
+	pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
 	       "falling back to iommu=soft.\n");
 	return -1;
 }
@@ -686,14 +702,16 @@ static struct dma_map_ops gart_dma_ops =
 	.unmap_page			= gart_unmap_page,
 	.alloc_coherent			= gart_alloc_coherent,
 	.free_coherent			= gart_free_coherent,
+	.mapping_error			= gart_mapping_error,
 };
 
-void gart_iommu_shutdown(void)
+static void gart_iommu_shutdown(void)
 {
 	struct pci_dev *dev;
 	int i;
 
-	if (no_agp && (dma_ops != &gart_dma_ops))
+	/* don't shutdown it if there is AGP installed */
+	if (!no_agp)
 		return;
 
 	for (i = 0; i < num_k8_northbridges; i++) {
@@ -708,7 +726,7 @@ void gart_iommu_shutdown(void)
 	}
 }
 
-void __init gart_iommu_init(void)
+int __init gart_iommu_init(void)
 {
 	struct agp_kern_info info;
 	unsigned long iommu_start;
@@ -718,7 +736,7 @@ void __init gart_iommu_init(void)
 	long i;
 
 	if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
-		return;
+		return 0;
 
 #ifndef CONFIG_AGP_AMD64
 	no_agp = 1;
@@ -730,35 +748,28 @@ void __init gart_iommu_init(void)
 		(agp_copy_info(agp_bridge, &info) < 0);
 #endif
 
-	if (swiotlb)
-		return;
-
-	/* Did we detect a different HW IOMMU? */
-	if (iommu_detected && !gart_iommu_aperture)
-		return;
-
 	if (no_iommu ||
 	    (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
 	    !gart_iommu_aperture ||
 	    (no_agp && init_k8_gatt(&info) < 0)) {
 		if (max_pfn > MAX_DMA32_PFN) {
-			printk(KERN_WARNING "More than 4GB of memory "
-			       "but GART IOMMU not available.\n");
-			printk(KERN_WARNING "falling back to iommu=soft.\n");
+			pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
+			pr_warning("falling back to iommu=soft.\n");
 		}
-		return;
+		return 0;
 	}
 
 	/* need to map that range */
-	aper_size = info.aper_size << 20;
-	aper_base = info.aper_base;
-	end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+	aper_size	= info.aper_size << 20;
+	aper_base	= info.aper_base;
+	end_pfn		= (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+
 	if (end_pfn > max_low_pfn_mapped) {
 		start_pfn = (aper_base>>PAGE_SHIFT);
 		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
 	}
 
-	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
+	pr_info("PCI-DMA: using GART IOMMU.\n");
 	iommu_size = check_iommu_size(info.aper_base, aper_size);
 	iommu_pages = iommu_size >> PAGE_SHIFT;
 
@@ -773,8 +784,7 @@ void __init gart_iommu_init(void)
 
 		ret = dma_debug_resize_entries(iommu_pages);
 		if (ret)
-			printk(KERN_DEBUG
-			       "PCI-DMA: Cannot trace all the entries\n");
+			pr_debug("PCI-DMA: Cannot trace all the entries\n");
 	}
 #endif
 
@@ -782,17 +792,16 @@ void __init gart_iommu_init(void)
 	 * Out of IOMMU space handling.
 	 * Reserve some invalid pages at the beginning of the GART.
 	 */
-	iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
+	bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
 
-	agp_memory_reserved = iommu_size;
-	printk(KERN_INFO
-	       "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
+	pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
 	       iommu_size >> 20);
 
-	iommu_start = aper_size - iommu_size;
-	iommu_bus_base = info.aper_base + iommu_start;
-	bad_dma_address = iommu_bus_base;
-	iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
+	agp_memory_reserved	= iommu_size;
+	iommu_start		= aper_size - iommu_size;
+	iommu_bus_base		= info.aper_base + iommu_start;
+	bad_dma_addr		= iommu_bus_base;
+	iommu_gatt_base		= agp_gatt_table + (iommu_start>>PAGE_SHIFT);
 
 	/*
 	 * Unmap the IOMMU part of the GART. The alias of the page is
@@ -814,7 +823,7 @@ void __init gart_iommu_init(void)
 	 * the pages as Not-Present:
 	 */
 	wbinvd();
-	
+
 	/*
 	 * Now all caches are flushed and we can safely enable
 	 * GART hardware.  Doing it early leaves the possibility
@@ -838,6 +847,10 @@ void __init gart_iommu_init(void)
 
 	flush_gart();
 	dma_ops = &gart_dma_ops;
+	x86_platform.iommu_shutdown = gart_iommu_shutdown;
+	swiotlb = 0;
+
+	return 0;
 }
 
 void __init gart_parse_options(char *p)
@@ -856,7 +869,7 @@ void __init gart_parse_options(char *p)
 #endif
 	if (isdigit(*p) && get_option(&p, &arg))
 		iommu_size = arg;
-	if (!strncmp(p, "fullflush", 8))
+	if (!strncmp(p, "fullflush", 9))
 		iommu_fullflush = 1;
 	if (!strncmp(p, "nofullflush", 11))
 		iommu_fullflush = 0;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-nommu.c linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-nommu.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-nommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-nommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,7 @@ static dma_addr_t nommu_map_page(struct
 	dma_addr_t bus = page_to_phys(page) + offset;
 	WARN_ON(size == 0);
 	if (!check_addr("map_single", dev, bus, size))
-		return bad_dma_address;
+		return DMA_ERROR_CODE;
 	flush_write_buffers();
 	return bus;
 }
@@ -103,12 +103,3 @@ struct dma_map_ops nommu_dma_ops = {
 	.sync_sg_for_device	= nommu_sync_sg_for_device,
 	.is_phys		= 1,
 };
-
-void __init no_iommu_init(void)
-{
-	if (dma_ops)
-		return;
-
-	force_iommu = 0; /* no HW IOMMU */
-	dma_ops = &nommu_dma_ops;
-}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-swiotlb.c linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-swiotlb.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/pci-swiotlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/pci-swiotlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,18 +42,31 @@ static struct dma_map_ops swiotlb_dma_op
 	.dma_supported = NULL,
 };
 
-void __init pci_swiotlb_init(void)
+/*
+ * pci_swiotlb_detect - set swiotlb to 1 if necessary
+ *
+ * This returns non-zero if we are forced to use swiotlb (by the boot
+ * option).
+ */
+int __init pci_swiotlb_detect(void)
 {
+	int use_swiotlb = swiotlb | swiotlb_force;
+
 	/* don't initialize swiotlb if iommu=off (no_iommu=1) */
 #ifdef CONFIG_X86_64
-	if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN))
+	if (!no_iommu && max_pfn > MAX_DMA32_PFN)
 		swiotlb = 1;
 #endif
 	if (swiotlb_force)
 		swiotlb = 1;
+
+	return use_swiotlb;
+}
+
+void __init pci_swiotlb_init(void)
+{
 	if (swiotlb) {
-		printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
-		swiotlb_init();
+		swiotlb_init(0);
 		dma_ops = &swiotlb_dma_ops;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/process_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/process_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/process_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/process_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@
 #include <linux/vmalloc.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
-#include <linux/utsname.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
@@ -35,7 +34,6 @@
 #include <linux/tick.h>
 #include <linux/percpu.h>
 #include <linux/prctl.h>
-#include <linux/dmi.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
@@ -58,6 +56,7 @@
 #include <asm/idle.h>
 #include <asm/syscalls.h>
 #include <asm/ds.h>
+#include <asm/debugreg.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
@@ -127,39 +126,29 @@ void __show_regs(struct pt_regs *regs, i
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned long sp;
 	unsigned short ss, gs;
-	const char *board;
 
 	if (user_mode_vm(regs)) {
 		sp = regs->sp;
 		ss = regs->ss & 0xffff;
 		gs = get_user_gs(regs);
 	} else {
-		sp = (unsigned long) (&regs->sp);
+		sp = kernel_stack_pointer(regs);
 		savesegment(ss, ss);
 		savesegment(gs, gs);
 	}
 
-	printk("\n");
-
-	board = dmi_get_system_info(DMI_PRODUCT_NAME);
-	if (!board)
-		board = "";
-	printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",
-			task_pid_nr(current), current->comm,
-			print_tainted(), init_utsname()->release,
-			(int)strcspn(init_utsname()->version, " "),
-			init_utsname()->version, board);
+	show_regs_common();
 
-	printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+	printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
 			(u16)regs->cs, regs->ip, regs->flags,
 			smp_processor_id());
 	print_symbol("EIP is at %s\n", regs->ip);
 
-	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+	printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 		regs->ax, regs->bx, regs->cx, regs->dx);
-	printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+	printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
 		regs->si, regs->di, regs->bp, sp);
-	printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+	printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
 	       (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss);
 
 	if (!all)
@@ -169,61 +158,28 @@ void __show_regs(struct pt_regs *regs, i
 	cr2 = read_cr2();
 	cr3 = read_cr3();
 	cr4 = read_cr4_safe();
-	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
+	printk(KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
 			cr0, cr2, cr3, cr4);
 
 	get_debugreg(d0, 0);
 	get_debugreg(d1, 1);
 	get_debugreg(d2, 2);
 	get_debugreg(d3, 3);
-	printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+	printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
 			d0, d1, d2, d3);
 
 	get_debugreg(d6, 6);
 	get_debugreg(d7, 7);
-	printk("DR6: %08lx DR7: %08lx\n",
+	printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n",
 			d6, d7);
 }
 
 void show_regs(struct pt_regs *regs)
 {
-	__show_regs(regs, 1);
+	show_registers(regs);
 	show_trace(NULL, regs, &regs->sp, regs->bp);
 }
 
-/*
- * This gets run with %bx containing the
- * function to call, and %dx containing
- * the "args".
- */
-extern void kernel_thread_helper(void);
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-
-	regs.bx = (unsigned long) fn;
-	regs.dx = (unsigned long) arg;
-
-	regs.ds = __USER_DS;
-	regs.es = __USER_DS;
-	regs.fs = __KERNEL_PERCPU;
-	regs.gs = __KERNEL_STACK_CANARY;
-	regs.orig_ax = -1;
-	regs.ip = (unsigned long) kernel_thread_helper;
-	regs.cs = __KERNEL_CS | get_kernel_rpl();
-	regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
-
-	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 void release_thread(struct task_struct *dead_task)
 {
 	BUG_ON(dead_task->mm);
@@ -259,7 +215,12 @@ int copy_thread(unsigned long clone_flag
 
 	task_user_gs(p) = get_user_gs(regs);
 
+	p->thread.io_bitmap_ptr = NULL;
 	tsk = current;
+	err = -ENOMEM;
+
+	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
 	if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
 		p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
 						IO_BITMAP_BYTES, GFP_KERNEL);
@@ -430,46 +391,6 @@ __switch_to(struct task_struct *prev_p,
 	return prev_p;
 }
 
-int sys_clone(struct pt_regs *regs)
-{
-	unsigned long clone_flags;
-	unsigned long newsp;
-	int __user *parent_tidptr, *child_tidptr;
-
-	clone_flags = regs->bx;
-	newsp = regs->cx;
-	parent_tidptr = (int __user *)regs->dx;
-	child_tidptr = (int __user *)regs->di;
-	if (!newsp)
-		newsp = regs->sp;
-	return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
-}
-
-/*
- * sys_execve() executes a new program.
- */
-int sys_execve(struct pt_regs *regs)
-{
-	int error;
-	char *filename;
-
-	filename = getname((char __user *) regs->bx);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	error = do_execve(filename,
-			(char __user * __user *) regs->cx,
-			(char __user * __user *) regs->dx,
-			regs);
-	if (error == 0) {
-		/* Make sure we don't return using sysenter.. */
-		set_thread_flag(TIF_IRET);
-	}
-	putname(filename);
-out:
-	return error;
-}
-
 #define top_esp                (THREAD_SIZE - sizeof(unsigned long))
 #define top_ebp                (THREAD_SIZE - 2*sizeof(unsigned long))
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/process_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/process_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/process_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/process_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
-#include <linux/utsname.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
@@ -38,7 +37,6 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/ftrace.h>
-#include <linux/dmi.h>
 
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -52,14 +50,13 @@
 #include <asm/idle.h>
 #include <asm/syscalls.h>
 #include <asm/ds.h>
+#include <asm/debugreg.h>
 
 asmlinkage extern void ret_from_fork(void);
 
 DEFINE_PER_CPU(unsigned long, old_rsp);
 static DEFINE_PER_CPU(unsigned char, is_idle);
 
-unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
-
 static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 
 void idle_notifier_register(struct notifier_block *n)
@@ -162,31 +159,21 @@ void __show_regs(struct pt_regs *regs, i
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned int fsindex, gsindex;
 	unsigned int ds, cs, es;
-	const char *board;
 
-	printk("\n");
-	print_modules();
-	board = dmi_get_system_info(DMI_PRODUCT_NAME);
-	if (!board)
-		board = "";
-	printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
-		current->pid, current->comm, print_tainted(),
-		init_utsname()->release,
-		(int)strcspn(init_utsname()->version, " "),
-		init_utsname()->version, board);
-	printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
+	show_regs_common();
+	printk(KERN_DEFAULT "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
 	printk_address(regs->ip, 1);
-	printk(KERN_INFO "RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss,
+	printk(KERN_DEFAULT "RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss,
 			regs->sp, regs->flags);
-	printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
+	printk(KERN_DEFAULT "RAX: %016lx RBX: %016lx RCX: %016lx\n",
 	       regs->ax, regs->bx, regs->cx);
-	printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
+	printk(KERN_DEFAULT "RDX: %016lx RSI: %016lx RDI: %016lx\n",
 	       regs->dx, regs->si, regs->di);
-	printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
+	printk(KERN_DEFAULT "RBP: %016lx R08: %016lx R09: %016lx\n",
 	       regs->bp, regs->r8, regs->r9);
-	printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
+	printk(KERN_DEFAULT "R10: %016lx R11: %016lx R12: %016lx\n",
 	       regs->r10, regs->r11, regs->r12);
-	printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
+	printk(KERN_DEFAULT "R13: %016lx R14: %016lx R15: %016lx\n",
 	       regs->r13, regs->r14, regs->r15);
 
 	asm("movl %%ds,%0" : "=r" (ds));
@@ -207,27 +194,26 @@ void __show_regs(struct pt_regs *regs, i
 	cr3 = read_cr3();
 	cr4 = read_cr4();
 
-	printk(KERN_INFO "FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
+	printk(KERN_DEFAULT "FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
 	       fs, fsindex, gs, gsindex, shadowgs);
-	printk(KERN_INFO "CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
+	printk(KERN_DEFAULT "CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
 			es, cr0);
-	printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
+	printk(KERN_DEFAULT "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
 			cr4);
 
 	get_debugreg(d0, 0);
 	get_debugreg(d1, 1);
 	get_debugreg(d2, 2);
-	printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
+	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);
-	printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
+	printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 }
 
 void show_regs(struct pt_regs *regs)
 {
-	printk(KERN_INFO "CPU %d:", smp_processor_id());
-	__show_regs(regs, 1);
+	show_registers(regs);
 	show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
 }
 
@@ -285,8 +271,9 @@ int copy_thread(unsigned long clone_flag
 	*childregs = *regs;
 
 	childregs->ax = 0;
-	childregs->sp = sp;
-	if (sp == ~0UL)
+	if (user_mode(regs))
+		childregs->sp = sp;
+	else
 		childregs->sp = (unsigned long)childregs;
 
 	p->thread.sp = (unsigned long) childregs;
@@ -297,12 +284,16 @@ int copy_thread(unsigned long clone_flag
 
 	p->thread.fs = me->thread.fs;
 	p->thread.gs = me->thread.gs;
+	p->thread.io_bitmap_ptr = NULL;
 
 	savesegment(gs, p->thread.gsindex);
 	savesegment(fs, p->thread.fsindex);
 	savesegment(es, p->thread.es);
 	savesegment(ds, p->thread.ds);
 
+	err = -ENOMEM;
+	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
 	if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
 		p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
 		if (!p->thread.io_bitmap_ptr) {
@@ -341,29 +332,46 @@ out:
 		kfree(p->thread.io_bitmap_ptr);
 		p->thread.io_bitmap_max = 0;
 	}
+
 	return err;
 }
 
-void
-start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+static void
+start_thread_common(struct pt_regs *regs, unsigned long new_ip,
+		    unsigned long new_sp,
+		    unsigned int _cs, unsigned int _ss, unsigned int _ds)
 {
 	loadsegment(fs, 0);
-	loadsegment(es, 0);
-	loadsegment(ds, 0);
+	loadsegment(es, _ds);
+	loadsegment(ds, _ds);
 	load_gs_index(0);
 	regs->ip		= new_ip;
 	regs->sp		= new_sp;
 	percpu_write(old_rsp, new_sp);
-	regs->cs		= __USER_CS;
-	regs->ss		= __USER_DS;
-	regs->flags		= 0x200;
+	regs->cs		= _cs;
+	regs->ss		= _ss;
+	regs->flags		= X86_EFLAGS_IF;
 	set_fs(USER_DS);
 	/*
 	 * Free the old FP and other extended state
 	 */
 	free_thread_xstate(current);
 }
-EXPORT_SYMBOL_GPL(start_thread);
+
+void
+start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+{
+	start_thread_common(regs, new_ip, new_sp,
+			    __USER_CS, __USER_DS, 0);
+}
+
+#ifdef CONFIG_IA32_EMULATION
+void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
+{
+	start_thread_common(regs, new_ip, new_sp,
+			    __USER32_CS, __USER32_DS, __USER32_DS);
+}
+#endif
 
 /*
  *	switch_to(x,y) should switch tasks from x to y.
@@ -495,26 +503,8 @@ __switch_to(struct task_struct *prev_p,
 	 */
 	if (preload_fpu)
 		__math_state_restore();
-	return prev_p;
-}
-
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage
-long sys_execve(char __user *name, char __user * __user *argv,
-		char __user * __user *envp, struct pt_regs *regs)
-{
-	long error;
-	char *filename;
 
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename, argv, envp, regs);
-	putname(filename);
-	return error;
+	return prev_p;
 }
 
 void set_personality_64bit(void)
@@ -531,13 +521,16 @@ void set_personality_64bit(void)
 	current->personality &= ~READ_IMPLIES_EXEC;
 }
 
-asmlinkage long
-sys_clone(unsigned long clone_flags, unsigned long newsp,
-	  void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+void set_personality_ia32(void)
 {
-	if (!newsp)
-		newsp = regs->sp;
-	return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+	/* inherit personality from parent */
+
+	/* Make sure to be in 32bit mode */
+	set_thread_flag(TIF_IA32);
+	current->personality |= force_personality32;
+
+	/* Prepare the first "return" to user space */
+	current_thread_info()->status |= TS_COMPAT;
 }
 
 unsigned long get_wchan(struct task_struct *p)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/process.c linux-libre-2.6.33-gnu1/arch/x86/kernel/process.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/process.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/process.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,11 @@
 #include <linux/pm.h>
 #include <linux/clockchips.h>
 #include <linux/random.h>
+#include <linux/user-return-notifier.h>
+#include <linux/dmi.h>
+#include <linux/utsname.h>
 #include <trace/events/power.h>
+#include <linux/hw_breakpoint.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/syscalls.h>
@@ -17,6 +21,7 @@
 #include <asm/uaccess.h>
 #include <asm/i387.h>
 #include <asm/ds.h>
+#include <asm/debugreg.h>
 
 unsigned long idle_halt;
 EXPORT_SYMBOL(idle_halt);
@@ -87,30 +92,30 @@ void exit_thread(void)
 	}
 }
 
-void flush_thread(void)
+void show_regs_common(void)
 {
-	struct task_struct *tsk = current;
+	const char *board, *product;
 
-#ifdef CONFIG_X86_64
-	if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
-		clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
-		if (test_tsk_thread_flag(tsk, TIF_IA32)) {
-			clear_tsk_thread_flag(tsk, TIF_IA32);
-		} else {
-			set_tsk_thread_flag(tsk, TIF_IA32);
-			current_thread_info()->status |= TS_COMPAT;
-		}
-	}
-#endif
+	board = dmi_get_system_info(DMI_BOARD_NAME);
+	if (!board)
+		board = "";
+	product = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!product)
+		product = "";
 
-	clear_tsk_thread_flag(tsk, TIF_DEBUG);
+	printk(KERN_CONT "\n");
+	printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
+		current->pid, current->comm, print_tainted(),
+		init_utsname()->release,
+		(int)strcspn(init_utsname()->version, " "),
+		init_utsname()->version, board, product);
+}
 
-	tsk->thread.debugreg0 = 0;
-	tsk->thread.debugreg1 = 0;
-	tsk->thread.debugreg2 = 0;
-	tsk->thread.debugreg3 = 0;
-	tsk->thread.debugreg6 = 0;
-	tsk->thread.debugreg7 = 0;
+void flush_thread(void)
+{
+	struct task_struct *tsk = current;
+
+	flush_ptrace_hw_breakpoint(tsk);
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
 	/*
 	 * Forget coprocessor state..
@@ -192,16 +197,6 @@ void __switch_to_xtra(struct task_struct
 	else if (next->debugctlmsr != prev->debugctlmsr)
 		update_debugctlmsr(next->debugctlmsr);
 
-	if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
-		set_debugreg(next->debugreg0, 0);
-		set_debugreg(next->debugreg1, 1);
-		set_debugreg(next->debugreg2, 2);
-		set_debugreg(next->debugreg3, 3);
-		/* no 4 and 5 */
-		set_debugreg(next->debugreg6, 6);
-		set_debugreg(next->debugreg7, 7);
-	}
-
 	if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
 	    test_tsk_thread_flag(next_p, TIF_NOTSC)) {
 		/* prev and next are different */
@@ -224,6 +219,7 @@ void __switch_to_xtra(struct task_struct
 		 */
 		memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
 	}
+	propagate_user_return_notify(prev_p, next_p);
 }
 
 int sys_fork(struct pt_regs *regs)
@@ -247,6 +243,78 @@ int sys_vfork(struct pt_regs *regs)
 		       NULL, NULL);
 }
 
+long
+sys_clone(unsigned long clone_flags, unsigned long newsp,
+	  void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+{
+	if (!newsp)
+		newsp = regs->sp;
+	return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+}
+
+/*
+ * This gets run with %si containing the
+ * function to call, and %di containing
+ * the "args".
+ */
+extern void kernel_thread_helper(void);
+
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+
+	regs.si = (unsigned long) fn;
+	regs.di = (unsigned long) arg;
+
+#ifdef CONFIG_X86_32
+	regs.ds = __USER_DS;
+	regs.es = __USER_DS;
+	regs.fs = __KERNEL_PERCPU;
+	regs.gs = __KERNEL_STACK_CANARY;
+#else
+	regs.ss = __KERNEL_DS;
+#endif
+
+	regs.orig_ax = -1;
+	regs.ip = (unsigned long) kernel_thread_helper;
+	regs.cs = __KERNEL_CS | get_kernel_rpl();
+	regs.flags = X86_EFLAGS_IF | 0x2;
+
+	/* Ok, create the new process.. */
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+EXPORT_SYMBOL(kernel_thread);
+
+/*
+ * sys_execve() executes a new program.
+ */
+long sys_execve(char __user *name, char __user * __user *argv,
+		char __user * __user *envp, struct pt_regs *regs)
+{
+	long error;
+	char *filename;
+
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		return error;
+	error = do_execve(filename, argv, envp, regs);
+
+#ifdef CONFIG_X86_32
+	if (error == 0) {
+		/* Make sure we don't return using sysenter.. */
+                set_thread_flag(TIF_IRET);
+        }
+#endif
+
+	putname(filename);
+	return error;
+}
 
 /*
  * Idle related variables and functions
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/ptrace.c linux-libre-2.6.33-gnu1/arch/x86/kernel/ptrace.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/ptrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/ptrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,8 @@
 #include <linux/seccomp.h>
 #include <linux/signal.h>
 #include <linux/workqueue.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -34,6 +36,7 @@
 #include <asm/prctl.h>
 #include <asm/proto.h>
 #include <asm/ds.h>
+#include <asm/hw_breakpoint.h>
 
 #include "tls.h"
 
@@ -49,6 +52,118 @@ enum x86_regset {
 	REGSET_IOPERM32,
 };
 
+struct pt_regs_offset {
+	const char *name;
+	int offset;
+};
+
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+#ifdef CONFIG_X86_64
+	REG_OFFSET_NAME(r15),
+	REG_OFFSET_NAME(r14),
+	REG_OFFSET_NAME(r13),
+	REG_OFFSET_NAME(r12),
+	REG_OFFSET_NAME(r11),
+	REG_OFFSET_NAME(r10),
+	REG_OFFSET_NAME(r9),
+	REG_OFFSET_NAME(r8),
+#endif
+	REG_OFFSET_NAME(bx),
+	REG_OFFSET_NAME(cx),
+	REG_OFFSET_NAME(dx),
+	REG_OFFSET_NAME(si),
+	REG_OFFSET_NAME(di),
+	REG_OFFSET_NAME(bp),
+	REG_OFFSET_NAME(ax),
+#ifdef CONFIG_X86_32
+	REG_OFFSET_NAME(ds),
+	REG_OFFSET_NAME(es),
+	REG_OFFSET_NAME(fs),
+	REG_OFFSET_NAME(gs),
+#endif
+	REG_OFFSET_NAME(orig_ax),
+	REG_OFFSET_NAME(ip),
+	REG_OFFSET_NAME(cs),
+	REG_OFFSET_NAME(flags),
+	REG_OFFSET_NAME(sp),
+	REG_OFFSET_NAME(ss),
+	REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:	the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->offset;
+	return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:	the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (roff->offset == offset)
+			return roff->name;
+	return NULL;
+}
+
+static const int arg_offs_table[] = {
+#ifdef CONFIG_X86_32
+	[0] = offsetof(struct pt_regs, ax),
+	[1] = offsetof(struct pt_regs, dx),
+	[2] = offsetof(struct pt_regs, cx)
+#else /* CONFIG_X86_64 */
+	[0] = offsetof(struct pt_regs, di),
+	[1] = offsetof(struct pt_regs, si),
+	[2] = offsetof(struct pt_regs, dx),
+	[3] = offsetof(struct pt_regs, cx),
+	[4] = offsetof(struct pt_regs, r8),
+	[5] = offsetof(struct pt_regs, r9)
+#endif
+};
+
+/**
+ * regs_get_argument_nth() - get Nth argument at function call
+ * @regs:	pt_regs which contains registers at function entry.
+ * @n:		argument number.
+ *
+ * regs_get_argument_nth() returns @n th argument of a function call.
+ * Since usually the kernel stack will be changed right after function entry,
+ * you must use this at function entry. If the @n th entry is NOT in the
+ * kernel stack or pt_regs, this returns 0.
+ */
+unsigned long regs_get_argument_nth(struct pt_regs *regs, unsigned int n)
+{
+	if (n < ARRAY_SIZE(arg_offs_table))
+		return *(unsigned long *)((char *)regs + arg_offs_table[n]);
+	else {
+		/*
+		 * The typical case: arg n is on the stack.
+		 * (Note: stack[0] = return address, so skip it)
+		 */
+		n -= ARRAY_SIZE(arg_offs_table);
+		return regs_get_kernel_stack_nth(regs, 1 + n);
+	}
+}
+
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
@@ -137,11 +252,6 @@ static int set_segment_reg(struct task_s
 	return 0;
 }
 
-static unsigned long debugreg_addr_limit(struct task_struct *task)
-{
-	return TASK_SIZE - 3;
-}
-
 #else  /* CONFIG_X86_64 */
 
 #define FLAG_MASK		(FLAG_MASK_32 | X86_EFLAGS_NT)
@@ -266,15 +376,6 @@ static int set_segment_reg(struct task_s
 	return 0;
 }
 
-static unsigned long debugreg_addr_limit(struct task_struct *task)
-{
-#ifdef CONFIG_IA32_EMULATION
-	if (test_tsk_thread_flag(task, TIF_IA32))
-		return IA32_PAGE_OFFSET - 3;
-#endif
-	return TASK_SIZE_MAX - 7;
-}
-
 #endif	/* CONFIG_X86_32 */
 
 static unsigned long get_flags(struct task_struct *task)
@@ -408,14 +509,14 @@ static int genregs_get(struct task_struc
 {
 	if (kbuf) {
 		unsigned long *k = kbuf;
-		while (count > 0) {
+		while (count >= sizeof(*k)) {
 			*k++ = getreg(target, pos);
 			count -= sizeof(*k);
 			pos += sizeof(*k);
 		}
 	} else {
 		unsigned long __user *u = ubuf;
-		while (count > 0) {
+		while (count >= sizeof(*u)) {
 			if (__put_user(getreg(target, pos), u++))
 				return -EFAULT;
 			count -= sizeof(*u);
@@ -434,14 +535,14 @@ static int genregs_set(struct task_struc
 	int ret = 0;
 	if (kbuf) {
 		const unsigned long *k = kbuf;
-		while (count > 0 && !ret) {
+		while (count >= sizeof(*k) && !ret) {
 			ret = putreg(target, pos, *k++);
 			count -= sizeof(*k);
 			pos += sizeof(*k);
 		}
 	} else {
 		const unsigned long  __user *u = ubuf;
-		while (count > 0 && !ret) {
+		while (count >= sizeof(*u) && !ret) {
 			unsigned long word;
 			ret = __get_user(word, u++);
 			if (ret)
@@ -454,99 +555,240 @@ static int genregs_set(struct task_struc
 	return ret;
 }
 
+static void ptrace_triggered(struct perf_event *bp, int nmi,
+			     struct perf_sample_data *data,
+			     struct pt_regs *regs)
+{
+	int i;
+	struct thread_struct *thread = &(current->thread);
+
+	/*
+	 * Store in the virtual DR6 register the fact that the breakpoint
+	 * was hit so the thread's debugger will see it.
+	 */
+	for (i = 0; i < HBP_NUM; i++) {
+		if (thread->ptrace_bps[i] == bp)
+			break;
+	}
+
+	thread->debugreg6 |= (DR_TRAP0 << i);
+}
+
 /*
- * This function is trivial and will be inlined by the compiler.
- * Having it separates the implementation details of debug
- * registers from the interface details of ptrace.
+ * Walk through every ptrace breakpoints for this thread and
+ * build the dr7 value on top of their attributes.
+ *
  */
-static unsigned long ptrace_get_debugreg(struct task_struct *child, int n)
+static unsigned long ptrace_get_dr7(struct perf_event *bp[])
 {
-	switch (n) {
-	case 0:		return child->thread.debugreg0;
-	case 1:		return child->thread.debugreg1;
-	case 2:		return child->thread.debugreg2;
-	case 3:		return child->thread.debugreg3;
-	case 6:		return child->thread.debugreg6;
-	case 7:		return child->thread.debugreg7;
+	int i;
+	int dr7 = 0;
+	struct arch_hw_breakpoint *info;
+
+	for (i = 0; i < HBP_NUM; i++) {
+		if (bp[i] && !bp[i]->attr.disabled) {
+			info = counter_arch_bp(bp[i]);
+			dr7 |= encode_dr7(i, info->len, info->type);
+		}
 	}
-	return 0;
+
+	return dr7;
 }
 
-static int ptrace_set_debugreg(struct task_struct *child,
-			       int n, unsigned long data)
+static int
+ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
+			 struct task_struct *tsk, int disabled)
 {
-	int i;
+	int err;
+	int gen_len, gen_type;
+	struct perf_event_attr attr;
 
-	if (unlikely(n == 4 || n == 5))
-		return -EIO;
+	/*
+	 * We shoud 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;
 
-	if (n < 4 && unlikely(data >= debugreg_addr_limit(child)))
-		return -EIO;
+	err = arch_bp_generic_fields(len, type, &gen_len, &gen_type);
+	if (err)
+		return err;
 
-	switch (n) {
-	case 0:		child->thread.debugreg0 = data; break;
-	case 1:		child->thread.debugreg1 = data; break;
-	case 2:		child->thread.debugreg2 = data; break;
-	case 3:		child->thread.debugreg3 = data; break;
+	attr = bp->attr;
+	attr.bp_len = gen_len;
+	attr.bp_type = gen_type;
+	attr.disabled = disabled;
 
-	case 6:
-		if ((data & ~0xffffffffUL) != 0)
-			return -EIO;
-		child->thread.debugreg6 = data;
-		break;
+	return modify_user_hw_breakpoint(bp, &attr);
+}
 
-	case 7:
+/*
+ * Handle ptrace writes to debug register 7.
+ */
+static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
+{
+	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;
+
+	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.
+	 */
+	for (i = 0; i < HBP_NUM; i++) {
+		enabled = decode_dr7(data, i, &len, &type);
+		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;
+
+				rc = ptrace_modify_breakpoint(bp, len, type,
+							      tsk, 1);
+				if (rc)
+					break;
+			}
+			continue;
+		}
+
+		rc = ptrace_modify_breakpoint(bp, len, type, tsk, 0);
+		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;
+		}
+		goto restore;
+	}
+	return ((orig_ret < 0) ? orig_ret : rc);
+}
+
+/*
+ * Handle PTRACE_PEEKUSR calls for the debug register area.
+ */
+static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
+{
+	struct thread_struct *thread = &(tsk->thread);
+	unsigned long val = 0;
+
+	if (n < HBP_NUM) {
+		struct perf_event *bp;
+		bp = thread->ptrace_bps[n];
+		if (!bp)
+			return 0;
+		val = bp->hw.info.address;
+	} else if (n == 6) {
+		val = thread->debugreg6;
+	 } else if (n == 7) {
+		val = thread->ptrace_dr7;
+	}
+	return val;
+}
+
+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;
+
+	if (!t->ptrace_bps[nr]) {
+		hw_breakpoint_init(&attr);
 		/*
-		 * Sanity-check data. Take one half-byte at once with
-		 * check = (val >> (16 + 4*i)) & 0xf. It contains the
-		 * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
-		 * 2 and 3 are LENi. Given a list of invalid values,
-		 * we do mask |= 1 << invalid_value, so that
-		 * (mask >> check) & 1 is a correct test for invalid
-		 * values.
-		 *
-		 * R/Wi contains the type of the breakpoint /
-		 * watchpoint, LENi contains the length of the watched
-		 * data in the watchpoint case.
-		 *
-		 * The invalid values are:
-		 * - LENi == 0x10 (undefined), so mask |= 0x0f00.	[32-bit]
-		 * - R/Wi == 0x10 (break on I/O reads or writes), so
-		 *   mask |= 0x4444.
-		 * - R/Wi == 0x00 && LENi != 0x00, so we have mask |=
-		 *   0x1110.
-		 *
-		 * Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54.
-		 *
-		 * See the Intel Manual "System Programming Guide",
-		 * 15.2.4
-		 *
-		 * Note that LENi == 0x10 is defined on x86_64 in long
-		 * mode (i.e. even for 32-bit userspace software, but
-		 * 64-bit kernel), so the x86_64 mask value is 0x5454.
-		 * See the AMD manual no. 24593 (AMD64 System Programming)
+		 * Put stub len and type to register (reserve) an inactive but
+		 * correct bp
 		 */
-#ifdef CONFIG_X86_32
-#define	DR7_MASK	0x5f54
-#else
-#define	DR7_MASK	0x5554
-#endif
-		data &= ~DR_CONTROL_RESERVED;
-		for (i = 0; i < 4; i++)
-			if ((DR7_MASK >> ((data >> (16 + 4*i)) & 0xf)) & 1)
-				return -EIO;
-		child->thread.debugreg7 = data;
-		if (data)
-			set_tsk_thread_flag(child, TIF_DEBUG);
-		else
-			clear_tsk_thread_flag(child, TIF_DEBUG);
-		break;
+		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, tsk);
+
+		/*
+		 * 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.
+		 * -EINVAL may be what we want for in-kernel breakpoints users,
+		 * but -EIO looks better for ptrace, since we refuse a register
+		 * writing for the user. And anyway this is the previous
+		 * behaviour.
+		 */
+		if (IS_ERR(bp))
+			return PTR_ERR(bp);
+
+		t->ptrace_bps[nr] = bp;
+	} else {
+		int err;
+
+		bp = t->ptrace_bps[nr];
+
+		attr = bp->attr;
+		attr.bp_addr = addr;
+		err = modify_user_hw_breakpoint(bp, &attr);
+		if (err)
+			return err;
 	}
 
+
 	return 0;
 }
 
 /*
+ * Handle PTRACE_POKEUSR calls for the debug register area.
+ */
+int ptrace_set_debugreg(struct task_struct *tsk, int n, unsigned long val)
+{
+	struct thread_struct *thread = &(tsk->thread);
+	int rc = 0;
+
+	/* There are no DR4 or DR5 registers */
+	if (n == 4 || n == 5)
+		return -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) {
+		rc = ptrace_write_dr7(tsk, val);
+		if (!rc)
+			thread->ptrace_dr7 = val;
+	}
+
+ret_path:
+	return rc;
+}
+
+/*
  * These access the current or another (stopped) task's io permission
  * bitmap for debugging or core dump.
  */
@@ -1219,14 +1461,14 @@ static int genregs32_get(struct task_str
 {
 	if (kbuf) {
 		compat_ulong_t *k = kbuf;
-		while (count > 0) {
+		while (count >= sizeof(*k)) {
 			getreg32(target, pos, k++);
 			count -= sizeof(*k);
 			pos += sizeof(*k);
 		}
 	} else {
 		compat_ulong_t __user *u = ubuf;
-		while (count > 0) {
+		while (count >= sizeof(*u)) {
 			compat_ulong_t word;
 			getreg32(target, pos, &word);
 			if (__put_user(word, u++))
@@ -1247,14 +1489,14 @@ static int genregs32_set(struct task_str
 	int ret = 0;
 	if (kbuf) {
 		const compat_ulong_t *k = kbuf;
-		while (count > 0 && !ret) {
+		while (count >= sizeof(*k) && !ret) {
 			ret = putreg32(target, pos, *k++);
 			count -= sizeof(*k);
 			pos += sizeof(*k);
 		}
 	} else {
 		const compat_ulong_t __user *u = ubuf;
-		while (count > 0 && !ret) {
+		while (count >= sizeof(*u) && !ret) {
 			compat_ulong_t word;
 			ret = __get_user(word, u++);
 			if (ret)
@@ -1437,21 +1679,33 @@ const struct user_regset_view *task_user
 #endif
 }
 
-void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
-					 int error_code, int si_code)
+static void fill_sigtrap_info(struct task_struct *tsk,
+				struct pt_regs *regs,
+				int error_code, int si_code,
+				struct siginfo *info)
 {
-	struct siginfo info;
-
 	tsk->thread.trap_no = 1;
 	tsk->thread.error_code = error_code;
 
-	memset(&info, 0, sizeof(info));
-	info.si_signo = SIGTRAP;
-	info.si_code = si_code;
+	memset(info, 0, sizeof(*info));
+	info->si_signo = SIGTRAP;
+	info->si_code = si_code;
+	info->si_addr = user_mode_vm(regs) ? (void __user *)regs->ip : NULL;
+}
 
-	/* User-mode ip? */
-	info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
+void user_single_step_siginfo(struct task_struct *tsk,
+				struct pt_regs *regs,
+				struct siginfo *info)
+{
+	fill_sigtrap_info(tsk, regs, 0, TRAP_BRKPT, info);
+}
+
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+					 int error_code, int si_code)
+{
+	struct siginfo info;
 
+	fill_sigtrap_info(tsk, regs, error_code, si_code, &info);
 	/* Send us the fake SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
 }
@@ -1516,29 +1770,22 @@ asmregparm long syscall_trace_enter(stru
 
 asmregparm void syscall_trace_leave(struct pt_regs *regs)
 {
+	bool step;
+
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_exit(regs, regs->ax);
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE))
-		tracehook_report_syscall_exit(regs, 0);
-
 	/*
 	 * If TIF_SYSCALL_EMU is set, we only get here because of
 	 * TIF_SINGLESTEP (i.e. this is PTRACE_SYSEMU_SINGLESTEP).
 	 * We already reported this syscall instruction in
-	 * syscall_trace_enter(), so don't do any more now.
-	 */
-	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
-		return;
-
-	/*
-	 * If we are single-stepping, synthesize a trap to follow the
-	 * system call instruction.
+	 * syscall_trace_enter().
 	 */
-	if (test_thread_flag(TIF_SINGLESTEP) &&
-	    tracehook_consider_fatal_signal(current, SIGTRAP))
-		send_sigtrap(current, regs, 0, TRAP_BRKPT);
+	step = unlikely(test_thread_flag(TIF_SINGLESTEP)) &&
+			!test_thread_flag(TIF_SYSCALL_EMU);
+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(regs, step);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/quirks.c linux-libre-2.6.33-gnu1/arch/x86/kernel/quirks.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/quirks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/quirks.c	2010-02-24 13:52:17.000000000 -0500
@@ -491,6 +491,19 @@ void force_hpet_resume(void)
 		break;
 	}
 }
+
+/*
+ * HPET MSI on some boards (ATI SB700/SB800) has side effect on
+ * floppy DMA. Disable HPET MSI on such platforms.
+ */
+static void force_disable_hpet_msi(struct pci_dev *unused)
+{
+	hpet_msi_disable = 1;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+			 force_disable_hpet_msi);
+
 #endif
 
 #if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
@@ -499,6 +512,7 @@ static void __init quirk_amd_nb_node(str
 {
 	struct pci_dev *nb_ht;
 	unsigned int devfn;
+	u32 node;
 	u32 val;
 
 	devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0);
@@ -507,7 +521,13 @@ static void __init quirk_amd_nb_node(str
 		return;
 
 	pci_read_config_dword(nb_ht, 0x60, &val);
-	set_dev_node(&dev->dev, val & 7);
+	node = val & 7;
+	/*
+	 * Some hardware may return an invalid node ID,
+	 * so check it first:
+	 */
+	if (node_online(node))
+		set_dev_node(&dev->dev, node);
 	pci_dev_put(nb_ht);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/reboot.c linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/reboot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 # include <linux/ctype.h>
 # include <linux/mc146818rtc.h>
 #else
-# include <asm/iommu.h>
+# include <asm/x86_init.h>
 #endif
 
 /*
@@ -203,6 +203,15 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
 		},
 	},
+	{	/* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G*/
+		.callback = set_bios_reboot,
+		.ident = "Dell OptiPlex 760",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"),
+			DMI_MATCH(DMI_BOARD_NAME, "0G919G"),
+		},
+	},
 	{	/* Handle problems with rebooting on Dell 2400's */
 		.callback = set_bios_reboot,
 		.ident = "Dell PowerEdge 2400",
@@ -259,6 +268,14 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
 		},
 	},
+	{       /* Handle problems with rebooting on ASUS P4S800 */
+		.callback = set_bios_reboot,
+		.ident = "ASUS P4S800",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
+		},
+	},
 	{ }
 };
 
@@ -622,7 +639,7 @@ void native_machine_shutdown(void)
 #endif
 
 #ifdef CONFIG_X86_64
-	pci_iommu_shutdown();
+	x86_platform.iommu_shutdown();
 #endif
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/reboot_fixups_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot_fixups_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/reboot_fixups_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/reboot_fixups_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
 #include <linux/interrupt.h>
 #include <asm/reboot_fixups.h>
 #include <asm/msr.h>
-#include <asm/geode.h>
+#include <linux/cs5535.h>
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
@@ -80,6 +80,7 @@ void mach_reboot_fixups(void)
 			continue;
 
 		cur->reboot_fixup(dev);
+		pci_dev_put(dev);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/setup.c linux-libre-2.6.33-gnu1/arch/x86/kernel/setup.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,6 +73,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/apic.h>
+#include <asm/trampoline.h>
 #include <asm/e820.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
@@ -106,9 +107,11 @@
 #include <asm/percpu.h>
 #include <asm/topology.h>
 #include <asm/apicdef.h>
+#include <asm/k8.h>
 #ifdef CONFIG_X86_64
 #include <asm/numa_64.h>
 #endif
+#include <asm/mce.h>
 
 /*
  * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -247,7 +250,7 @@ EXPORT_SYMBOL(edd);
  *              from boot_params into a safe place.
  *
  */
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
 {
      memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer,
 	    sizeof(edd.mbr_signature));
@@ -256,7 +259,7 @@ static inline void copy_edd(void)
      edd.edd_info_nr = boot_params.eddbuf_entries;
 }
 #else
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
 {
 }
 #endif
@@ -486,42 +489,11 @@ static void __init reserve_early_setup_d
 
 #ifdef CONFIG_KEXEC
 
-/**
- * Reserve @size bytes of crashkernel memory at any suitable offset.
- *
- * @size: Size of the crashkernel memory to reserve.
- * Returns the base address on success, and -1ULL on failure.
- */
-static
-unsigned long long __init find_and_reserve_crashkernel(unsigned long long size)
-{
-	const unsigned long long alignment = 16<<20; 	/* 16M */
-	unsigned long long start = 0LL;
-
-	while (1) {
-		int ret;
-
-		start = find_e820_area(start, ULONG_MAX, size, alignment);
-		if (start == -1ULL)
-			return start;
-
-		/* try to reserve it */
-		ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE);
-		if (ret >= 0)
-			return start;
-
-		start += alignment;
-	}
-}
-
 static inline unsigned long long get_total_mem(void)
 {
 	unsigned long long total;
 
-	total = max_low_pfn - min_low_pfn;
-#ifdef CONFIG_HIGHMEM
-	total += highend_pfn - highstart_pfn;
-#endif
+	total = max_pfn - min_low_pfn;
 
 	return total << PAGE_SHIFT;
 }
@@ -541,21 +513,25 @@ static void __init reserve_crashkernel(v
 
 	/* 0 means: find the address automatically */
 	if (crash_base <= 0) {
-		crash_base = find_and_reserve_crashkernel(crash_size);
+		const unsigned long long alignment = 16<<20;	/* 16M */
+
+		crash_base = find_e820_area(alignment, ULONG_MAX, crash_size,
+				 alignment);
 		if (crash_base == -1ULL) {
-			pr_info("crashkernel reservation failed. "
-				"No suitable area found.\n");
+			pr_info("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
-		ret = reserve_bootmem_generic(crash_base, crash_size,
-					BOOTMEM_EXCLUSIVE);
-		if (ret < 0) {
-			pr_info("crashkernel reservation failed - "
-				"memory is in use\n");
+		unsigned long long start;
+
+		start = find_e820_area(crash_base, ULONG_MAX, crash_size,
+				 1<<20);
+		if (start != crash_base) {
+			pr_info("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
+	reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL");
 
 	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
 			"for crashkernel (System RAM: %ldMB)\n",
@@ -666,19 +642,27 @@ static struct dmi_system_id __initdata b
 			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
 		},
 	},
-	{
 	/*
-	 * AMI BIOS with low memory corruption was found on Intel DG45ID board.
-	 * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
+	 * AMI BIOS with low memory corruption was found on Intel DG45ID and
+	 * DG45FC boards.
+	 * It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
 	 * match only DMI_BOARD_NAME and see if there is more bad products
 	 * with this vendor.
 	 */
+	{
 		.callback = dmi_low_memory_corruption,
 		.ident = "AMI BIOS",
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
 		},
 	},
+	{
+		.callback = dmi_low_memory_corruption,
+		.ident = "AMI BIOS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
+		},
+	},
 #endif
 	{}
 };
@@ -698,6 +682,9 @@ static struct dmi_system_id __initdata b
 
 void __init setup_arch(char **cmdline_p)
 {
+	int acpi = 0;
+	int k8 = 0;
+
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
@@ -790,21 +777,18 @@ void __init setup_arch(char **cmdline_p)
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = command_line;
 
-#ifdef CONFIG_X86_64
 	/*
-	 * Must call this twice: Once just to detect whether hardware doesn't
-	 * support NX (so that the early EHCI debug console setup can safely
-	 * call set_fixmap(), and then again after parsing early parameters to
-	 * honor the respective command line option.
+	 * x86_configure_nx() is called before parse_early_param() to detect
+	 * whether hardware doesn't support NX (so that the early EHCI debug
+	 * console setup can safely call set_fixmap()). It may then be called
+	 * again from within noexec_setup() during parsing early parameters
+	 * to honor the respective command line option.
 	 */
-	check_efer();
-#endif
+	x86_configure_nx();
 
 	parse_early_param();
 
-#ifdef CONFIG_X86_64
-	check_efer();
-#endif
+	x86_report_nx();
 
 	/* Must be before kernel pagetables are setup */
 	vmi_activate();
@@ -900,6 +884,20 @@ void __init setup_arch(char **cmdline_p)
 
 	reserve_brk();
 
+	/*
+	 * Find and reserve possible boot-time SMP configuration:
+	 */
+	find_smp_config();
+
+	reserve_trampoline_memory();
+
+#ifdef CONFIG_ACPI_SLEEP
+	/*
+	 * Reserve low memory region for sleep support.
+	 * even before init_memory_mapping
+	 */
+	acpi_reserve_wakeup_memory();
+#endif
 	init_gbpages();
 
 	/* max_pfn_mapped is updated here */
@@ -926,6 +924,8 @@ void __init setup_arch(char **cmdline_p)
 
 	reserve_initrd();
 
+	reserve_crashkernel();
+
 	vsmp_init();
 
 	io_delay_init();
@@ -941,23 +941,15 @@ void __init setup_arch(char **cmdline_p)
 	/*
 	 * Parse SRAT to discover nodes.
 	 */
-	acpi_numa_init();
+	acpi = acpi_numa_init();
 #endif
 
-	initmem_init(0, max_pfn);
-
-#ifdef CONFIG_ACPI_SLEEP
-	/*
-	 * Reserve low memory region for sleep support.
-	 */
-	acpi_reserve_bootmem();
+#ifdef CONFIG_K8_NUMA
+	if (!acpi)
+		k8 = !k8_numa_init(0, max_pfn);
 #endif
-	/*
-	 * Find and reserve possible boot-time SMP configuration:
-	 */
-	find_smp_config();
 
-	reserve_crashkernel();
+	initmem_init(0, max_pfn, acpi, k8);
 
 #ifdef CONFIG_X86_64
 	/*
@@ -1031,6 +1023,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
 	x86_init.oem.banner();
+
+	mcheck_init();
 }
 
 #ifdef CONFIG_X86_32
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/setup_percpu.c linux-libre-2.6.33-gnu1/arch/x86/kernel/setup_percpu.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/setup_percpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/setup_percpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -20,9 +22,9 @@
 #include <asm/stackprotector.h>
 
 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
-# define DBG(x...) printk(KERN_DEBUG x)
+# define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__)
 #else
-# define DBG(x...)
+# define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0)
 #endif
 
 DEFINE_PER_CPU(int, cpu_number);
@@ -116,8 +118,8 @@ static void * __init pcpu_alloc_bootmem(
 	} else {
 		ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node),
 						   size, align, goal);
-		pr_debug("per cpu data for cpu%d %lu bytes on node%d at "
-			 "%016lx\n", cpu, size, node, __pa(ptr));
+		pr_debug("per cpu data for cpu%d %lu bytes on node%d at %016lx\n",
+			 cpu, size, node, __pa(ptr));
 	}
 	return ptr;
 #else
@@ -198,8 +200,7 @@ void __init setup_per_cpu_areas(void)
 					    pcpu_cpu_distance,
 					    pcpu_fc_alloc, pcpu_fc_free);
 		if (rc < 0)
-			pr_warning("PERCPU: %s allocator failed (%d), "
-				   "falling back to page size\n",
+			pr_warning("%s allocator failed (%d), falling back to page size\n",
 				   pcpu_fc_names[pcpu_chosen_fc], rc);
 	}
 	if (rc < 0)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/signal.c linux-libre-2.6.33-gnu1/arch/x86/kernel/signal.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/signal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/signal.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/stddef.h>
 #include <linux/personality.h>
 #include <linux/uaccess.h>
+#include <linux/user-return-notifier.h>
 
 #include <asm/processor.h>
 #include <asm/ucontext.h>
@@ -544,22 +545,12 @@ sys_sigaction(int sig, const struct old_
 }
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_X86_32
-int sys_sigaltstack(struct pt_regs *regs)
-{
-	const stack_t __user *uss = (const stack_t __user *)regs->bx;
-	stack_t __user *uoss = (stack_t __user *)regs->cx;
-
-	return do_sigaltstack(uss, uoss, regs->sp);
-}
-#else /* !CONFIG_X86_32 */
-asmlinkage long
+long
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 		struct pt_regs *regs)
 {
 	return do_sigaltstack(uss, uoss, regs->sp);
 }
-#endif /* CONFIG_X86_32 */
 
 /*
  * Do a signal return; undo the signal stack.
@@ -799,15 +790,6 @@ static void do_signal(struct pt_regs *re
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		/*
-		 * Re-enable any watchpoints before delivering the
-		 * signal to user space. The processor register will
-		 * have been cleared if the watchpoint triggered
-		 * inside the kernel.
-		 */
-		if (current->thread.debugreg7)
-			set_debugreg(current->thread.debugreg7, 7);
-
 		/* Whee! Actually deliver the signal.  */
 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
 			/*
@@ -872,6 +854,8 @@ do_notify_resume(struct pt_regs *regs, v
 		if (current->replacement_session_keyring)
 			key_replace_session_keyring();
 	}
+	if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
+		fire_user_return_notifiers();
 
 #ifdef CONFIG_X86_32
 	clear_thread_flag(TIF_IRET);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/smpboot.c linux-libre-2.6.33-gnu1/arch/x86/kernel/smpboot.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/smpboot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/smpboot.c	2010-02-24 13:52:17.000000000 -0500
@@ -671,6 +671,26 @@ static void __cpuinit do_fork_idle(struc
 	complete(&c_idle->done);
 }
 
+/* reduce the number of lines printed when booting a large cpu count system */
+static void __cpuinit announce_cpu(int cpu, int apicid)
+{
+	static int current_node = -1;
+	int node = cpu_to_node(cpu);
+
+	if (system_state == SYSTEM_BOOTING) {
+		if (node != current_node) {
+			if (current_node > (-1))
+				pr_cont(" Ok.\n");
+			current_node = node;
+			pr_info("Booting Node %3d, Processors ", node);
+		}
+		pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " Ok.\n" : "");
+		return;
+	} else
+		pr_info("Booting Node %d Processor %d APIC 0x%x\n",
+			node, cpu, apicid);
+}
+
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -687,7 +707,7 @@ static int __cpuinit do_boot_cpu(int api
 		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
 	};
 
-	INIT_WORK(&c_idle.work, do_fork_idle);
+	INIT_WORK_ON_STACK(&c_idle.work, do_fork_idle);
 
 	alternatives_smp_switch(1);
 
@@ -713,6 +733,7 @@ static int __cpuinit do_boot_cpu(int api
 
 	if (IS_ERR(c_idle.idle)) {
 		printk("failed fork for CPU %d\n", cpu);
+		destroy_work_on_stack(&c_idle.work);
 		return PTR_ERR(c_idle.idle);
 	}
 
@@ -736,9 +757,8 @@ do_rest:
 	/* start_ip had better be page-aligned! */
 	start_ip = setup_trampoline();
 
-	/* So we see what's up   */
-	printk(KERN_INFO "Booting processor %d APIC 0x%x ip 0x%lx\n",
-			  cpu, apicid, start_ip);
+	/* So we see what's up */
+	announce_cpu(cpu, apicid);
 
 	/*
 	 * This grunge runs the startup process for
@@ -787,21 +807,17 @@ do_rest:
 			udelay(100);
 		}
 
-		if (cpumask_test_cpu(cpu, cpu_callin_mask)) {
-			/* number CPUs logically, starting from 1 (BSP is 0) */
-			pr_debug("OK.\n");
-			printk(KERN_INFO "CPU%d: ", cpu);
-			print_cpu_info(&cpu_data(cpu));
-			pr_debug("CPU has booted.\n");
-		} else {
+		if (cpumask_test_cpu(cpu, cpu_callin_mask))
+			pr_debug("CPU%d: has booted.\n", cpu);
+		else {
 			boot_error = 1;
 			if (*((volatile unsigned char *)trampoline_base)
 					== 0xA5)
 				/* trampoline started but...? */
-				printk(KERN_ERR "Stuck ??\n");
+				pr_err("CPU%d: Stuck ??\n", cpu);
 			else
 				/* trampoline code not run */
-				printk(KERN_ERR "Not responding.\n");
+				pr_err("CPU%d: Not responding.\n", cpu);
 			if (apic->inquire_remote_apic)
 				apic->inquire_remote_apic(apicid);
 		}
@@ -831,6 +847,7 @@ do_rest:
 		smpboot_restore_warm_reset_vector();
 	}
 
+	destroy_work_on_stack(&c_idle.work);
 	return boot_error;
 }
 
@@ -1066,9 +1083,7 @@ void __init native_smp_prepare_cpus(unsi
 	set_cpu_sibling_map(0);
 
 	enable_IR_x2apic();
-#ifdef CONFIG_X86_64
 	default_setup_apic_routing();
-#endif
 
 	if (smp_sanity_check(max_cpus) < 0) {
 		printk(KERN_INFO "SMP disabled\n");
@@ -1250,16 +1265,7 @@ static void __ref remove_cpu_from_maps(i
 void cpu_disable_common(void)
 {
 	int cpu = smp_processor_id();
-	/*
-	 * HACK:
-	 * Allow any queued timer interrupts to get serviced
-	 * This is only a temporary solution until we cleanup
-	 * fixup_irqs as we do for IA64.
-	 */
-	local_irq_enable();
-	mdelay(1);
 
-	local_irq_disable();
 	remove_siblinginfo(cpu);
 
 	/* It's now safe to remove this processor from the online map */
@@ -1300,14 +1306,16 @@ void native_cpu_die(unsigned int cpu)
 	for (i = 0; i < 10; i++) {
 		/* They ack this in play_dead by setting CPU_DEAD */
 		if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
-			printk(KERN_INFO "CPU %d is now offline\n", cpu);
+			if (system_state == SYSTEM_RUNNING)
+				pr_info("CPU %u is now offline\n", cpu);
+
 			if (1 == num_online_cpus())
 				alternatives_smp_switch(0);
 			return;
 		}
 		msleep(100);
 	}
-	printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+	pr_err("CPU %u didn't die...\n", cpu);
 }
 
 void play_dead_common(void)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/stacktrace.c linux-libre-2.6.33-gnu1/arch/x86/kernel/stacktrace.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/stacktrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/stacktrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,17 +53,19 @@ save_stack_address_nosched(void *data, u
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-	.warning = save_stack_warning,
-	.warning_symbol = save_stack_warning_symbol,
-	.stack = save_stack_stack,
-	.address = save_stack_address,
+	.warning	= save_stack_warning,
+	.warning_symbol	= save_stack_warning_symbol,
+	.stack		= save_stack_stack,
+	.address	= save_stack_address,
+	.walk_stack	= print_context_stack,
 };
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-	.warning = save_stack_warning,
-	.warning_symbol = save_stack_warning_symbol,
-	.stack = save_stack_stack,
-	.address = save_stack_address_nosched,
+	.warning	= save_stack_warning,
+	.warning_symbol	= save_stack_warning_symbol,
+	.stack		= save_stack_stack,
+	.address	= save_stack_address_nosched,
+	.walk_stack	= print_context_stack,
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/syscall_table_32.S linux-libre-2.6.33-gnu1/arch/x86/kernel/syscall_table_32.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/syscall_table_32.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/syscall_table_32.S	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,7 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall	/* reserved for streams2 */
 	.long ptregs_vfork	/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap2
+	.long sys_mmap_pgoff
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
@@ -336,3 +336,4 @@ ENTRY(sys_call_table)
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
 	.long sys_perf_event_open
+	.long sys_recvmmsg
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/sys_i386_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_i386_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/sys_i386_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_i386_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,31 +24,6 @@
 
 #include <asm/syscalls.h>
 
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-			  unsigned long prot, unsigned long flags,
-			  unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file *file = NULL;
-	struct mm_struct *mm = current->mm;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/i386 didn't use to be able to handle more than
@@ -77,7 +52,7 @@ asmlinkage int old_mmap(struct mmap_arg_
 	if (a.offset & ~PAGE_MASK)
 		goto out;
 
-	err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
+	err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
 			a.fd, a.offset >> PAGE_SHIFT);
 out:
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/sys_x86_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_x86_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/sys_x86_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/sys_x86_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,26 +23,11 @@ SYSCALL_DEFINE6(mmap, unsigned long, add
 		unsigned long, fd, unsigned long, off)
 {
 	long error;
-	struct file *file;
-
 	error = -EINVAL;
 	if (off & ~PAGE_MASK)
 		goto out;
 
-	error = -EBADF;
-	file = NULL;
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
+	error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 out:
 	return error;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/tlb_uv.c linux-libre-2.6.33-gnu1/arch/x86/kernel/tlb_uv.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/tlb_uv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/tlb_uv.c	2010-02-24 13:52:17.000000000 -0500
@@ -817,10 +817,8 @@ static int __init uv_init_blade(int blad
 	 */
 	apicid = blade_to_first_apicid(blade);
 	pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG);
-	if ((pa & 0xff) != UV_BAU_MESSAGE) {
-		uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
+	uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
 				      ((apicid << 32) | UV_BAU_MESSAGE));
-	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/trampoline.c linux-libre-2.6.33-gnu1/arch/x86/kernel/trampoline.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/trampoline.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/trampoline.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,21 +12,19 @@
 #endif
 
 /* ready for x86_64 and x86 */
-unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
+unsigned char *__trampinitdata trampoline_base;
 
 void __init reserve_trampoline_memory(void)
 {
-#ifdef CONFIG_X86_32
-	/*
-	 * But first pinch a few for the stack/trampoline stuff
-	 * FIXME: Don't need the extra page at 4K, but need to fix
-	 * trampoline before removing it. (see the GDT stuff)
-	 */
-	reserve_early(PAGE_SIZE, PAGE_SIZE + PAGE_SIZE, "EX TRAMPOLINE");
-#endif
+	unsigned long mem;
+
 	/* Has to be in very low memory so we can execute real-mode AP code. */
-	reserve_early(TRAMPOLINE_BASE, TRAMPOLINE_BASE + TRAMPOLINE_SIZE,
-			"TRAMPOLINE");
+	mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE);
+	if (mem == -1L)
+		panic("Cannot allocate trampoline\n");
+
+	trampoline_base = __va(mem);
+	reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE");
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/traps.c linux-libre-2.6.33-gnu1/arch/x86/kernel/traps.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/traps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/traps.c	2010-02-24 13:52:17.000000000 -0500
@@ -529,77 +529,56 @@ asmlinkage __kprobes struct pt_regs *syn
 dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 {
 	struct task_struct *tsk = current;
-	unsigned long condition;
+	unsigned long dr6;
 	int si_code;
 
-	get_debugreg(condition, 6);
+	get_debugreg(dr6, 6);
 
 	/* Catch kmemcheck conditions first of all! */
-	if (condition & DR_STEP && kmemcheck_trap(regs))
+	if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
 		return;
 
+	/* DR6 may or may not be cleared by the CPU */
+	set_debugreg(0, 6);
 	/*
 	 * The processor cleared BTF, so don't mark that we need it set.
 	 */
 	clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
 	tsk->thread.debugctlmsr = 0;
 
-	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-						SIGTRAP) == NOTIFY_STOP)
+	/* Store the virtualized DR6 value */
+	tsk->thread.debugreg6 = dr6;
+
+	if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
+							SIGTRAP) == NOTIFY_STOP)
 		return;
 
 	/* It's safe to allow irq's after DR6 has been saved */
 	preempt_conditional_sti(regs);
 
-	/* Mask out spurious debug traps due to lazy DR7 setting */
-	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
-		if (!tsk->thread.debugreg7)
-			goto clear_dr7;
+	if (regs->flags & X86_VM_MASK) {
+		handle_vm86_trap((struct kernel_vm86_regs *) regs,
+				error_code, 1);
+		return;
 	}
 
-#ifdef CONFIG_X86_32
-	if (regs->flags & X86_VM_MASK)
-		goto debug_vm86;
-#endif
-
-	/* Save debug status register where ptrace can see it */
-	tsk->thread.debugreg6 = condition;
-
 	/*
-	 * Single-stepping through TF: make sure we ignore any events in
-	 * kernel space (but re-enable TF when returning to user mode).
+	 * Single-stepping through system calls: ignore any exceptions in
+	 * kernel space, but re-enable TF when returning to user mode.
+	 *
+	 * We already checked v86 mode above, so we can check for kernel mode
+	 * by just checking the CPL of CS.
 	 */
-	if (condition & DR_STEP) {
-		if (!user_mode(regs))
-			goto clear_TF_reenable;
+	if ((dr6 & DR_STEP) && !user_mode(regs)) {
+		tsk->thread.debugreg6 &= ~DR_STEP;
+		set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+		regs->flags &= ~X86_EFLAGS_TF;
 	}
-
-	si_code = get_si_code(condition);
-	/* Ok, finally something we can handle */
-	send_sigtrap(tsk, regs, error_code, si_code);
-
-	/*
-	 * Disable additional traps. They'll be re-enabled when
-	 * the signal is delivered.
-	 */
-clear_dr7:
-	set_debugreg(0, 7);
+	si_code = get_si_code(tsk->thread.debugreg6);
+	if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
+		send_sigtrap(tsk, regs, error_code, si_code);
 	preempt_conditional_cli(regs);
-	return;
-
-#ifdef CONFIG_X86_32
-debug_vm86:
-	/* reenable preemption: handle_vm86_trap() might sleep */
-	dec_preempt_count();
-	handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
-	conditional_cli(regs);
-	return;
-#endif
 
-clear_TF_reenable:
-	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
-	regs->flags &= ~X86_EFLAGS_TF;
-	preempt_conditional_cli(regs);
 	return;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/tsc.c linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/tsc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc.c	2010-02-24 13:52:17.000000000 -0500
@@ -763,6 +763,7 @@ void mark_tsc_unstable(char *reason)
 {
 	if (!tsc_unstable) {
 		tsc_unstable = 1;
+		sched_clock_stable = 0;
 		printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
 		/* Change only the rating, when not registered */
 		if (clocksource_tsc.mult)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/tsc_sync.c linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc_sync.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/tsc_sync.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/tsc_sync.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,7 @@ static __cpuinitdata atomic_t stop_count
  * we want to have the fastest, inlined, non-debug version
  * of a critical section, to be able to prove TSC time-warps:
  */
-static __cpuinitdata raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED;
+static __cpuinitdata arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 
 static __cpuinitdata cycles_t last_tsc;
 static __cpuinitdata cycles_t max_warp;
@@ -62,13 +62,13 @@ static __cpuinit void check_tsc_warp(voi
 		 * previous TSC that was measured (possibly on
 		 * another CPU) and update the previous TSC timestamp.
 		 */
-		__raw_spin_lock(&sync_lock);
+		arch_spin_lock(&sync_lock);
 		prev = last_tsc;
 		rdtsc_barrier();
 		now = get_cycles();
 		rdtsc_barrier();
 		last_tsc = now;
-		__raw_spin_unlock(&sync_lock);
+		arch_spin_unlock(&sync_lock);
 
 		/*
 		 * Be nice every now and then (and also check whether
@@ -87,10 +87,10 @@ static __cpuinit void check_tsc_warp(voi
 		 * we saw a time-warp of the TSC going backwards:
 		 */
 		if (unlikely(prev > now)) {
-			__raw_spin_lock(&sync_lock);
+			arch_spin_lock(&sync_lock);
 			max_warp = max(max_warp, prev - now);
 			nr_warps++;
-			__raw_spin_unlock(&sync_lock);
+			arch_spin_unlock(&sync_lock);
 		}
 	}
 	WARN(!(now-start),
@@ -114,13 +114,12 @@ void __cpuinit check_tsc_sync_source(int
 		return;
 
 	if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
-		printk_once(KERN_INFO "Skipping synchronization checks as TSC is reliable.\n");
+		if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING)
+			pr_info(
+			"Skipped synchronization checks as TSC is reliable.\n");
 		return;
 	}
 
-	pr_info("checking TSC synchronization [CPU#%d -> CPU#%d]:",
-		smp_processor_id(), cpu);
-
 	/*
 	 * Reset it - in case this is a second bootup:
 	 */
@@ -142,12 +141,14 @@ void __cpuinit check_tsc_sync_source(int
 		cpu_relax();
 
 	if (nr_warps) {
-		printk("\n");
+		pr_warning("TSC synchronization [CPU#%d -> CPU#%d]:\n",
+			smp_processor_id(), cpu);
 		pr_warning("Measured %Ld cycles TSC warp between CPUs, "
 			   "turning off TSC clock.\n", max_warp);
 		mark_tsc_unstable("check_tsc_sync_source failed");
 	} else {
-		printk(" passed.\n");
+		pr_debug("TSC synchronization [CPU#%d -> CPU#%d]: passed\n",
+			smp_processor_id(), cpu);
 	}
 
 	/*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/uv_irq.c linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_irq.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/uv_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,10 +9,25 @@
  */
 
 #include <linux/module.h>
+#include <linux/rbtree.h>
 #include <linux/irq.h>
 
 #include <asm/apic.h>
 #include <asm/uv/uv_irq.h>
+#include <asm/uv/uv_hub.h>
+
+/* MMR offset and pnode of hub sourcing interrupts for a given irq */
+struct uv_irq_2_mmr_pnode{
+	struct rb_node		list;
+	unsigned long		offset;
+	int			pnode;
+	int			irq;
+};
+
+static spinlock_t		uv_irq_lock;
+static struct rb_root		uv_irq_root;
+
+static int uv_set_irq_affinity(unsigned int, const struct cpumask *);
 
 static void uv_noop(unsigned int irq)
 {
@@ -39,25 +54,213 @@ struct irq_chip uv_irq_chip = {
 	.unmask		= uv_noop,
 	.eoi		= uv_ack_apic,
 	.end		= uv_noop,
+	.set_affinity	= uv_set_irq_affinity,
 };
 
 /*
+ * Add offset and pnode information of the hub sourcing interrupts to the
+ * rb tree for a specific irq.
+ */
+static int uv_set_irq_2_mmr_info(int irq, unsigned long offset, unsigned blade)
+{
+	struct rb_node **link = &uv_irq_root.rb_node;
+	struct rb_node *parent = NULL;
+	struct uv_irq_2_mmr_pnode *n;
+	struct uv_irq_2_mmr_pnode *e;
+	unsigned long irqflags;
+
+	n = kmalloc_node(sizeof(struct uv_irq_2_mmr_pnode), GFP_KERNEL,
+				uv_blade_to_memory_nid(blade));
+	if (!n)
+		return -ENOMEM;
+
+	n->irq = irq;
+	n->offset = offset;
+	n->pnode = uv_blade_to_pnode(blade);
+	spin_lock_irqsave(&uv_irq_lock, irqflags);
+	/* Find the right place in the rbtree: */
+	while (*link) {
+		parent = *link;
+		e = rb_entry(parent, struct uv_irq_2_mmr_pnode, list);
+
+		if (unlikely(irq == e->irq)) {
+			/* irq entry exists */
+			e->pnode = uv_blade_to_pnode(blade);
+			e->offset = offset;
+			spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+			kfree(n);
+			return 0;
+		}
+
+		if (irq < e->irq)
+			link = &(*link)->rb_left;
+		else
+			link = &(*link)->rb_right;
+	}
+
+	/* Insert the node into the rbtree. */
+	rb_link_node(&n->list, parent, link);
+	rb_insert_color(&n->list, &uv_irq_root);
+
+	spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+	return 0;
+}
+
+/* Retrieve offset and pnode information from the rb tree for a specific irq */
+int uv_irq_2_mmr_info(int irq, unsigned long *offset, int *pnode)
+{
+	struct uv_irq_2_mmr_pnode *e;
+	struct rb_node *n;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&uv_irq_lock, irqflags);
+	n = uv_irq_root.rb_node;
+	while (n) {
+		e = rb_entry(n, struct uv_irq_2_mmr_pnode, list);
+
+		if (e->irq == irq) {
+			*offset = e->offset;
+			*pnode = e->pnode;
+			spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+			return 0;
+		}
+
+		if (irq < e->irq)
+			n = n->rb_left;
+		else
+			n = n->rb_right;
+	}
+	spin_unlock_irqrestore(&uv_irq_lock, irqflags);
+	return -1;
+}
+
+/*
+ * Re-target the irq to the specified CPU and enable the specified MMR located
+ * on the specified blade to allow the sending of MSIs to the specified CPU.
+ */
+static int
+arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
+		       unsigned long mmr_offset, int restrict)
+{
+	const struct cpumask *eligible_cpu = cpumask_of(cpu);
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg;
+	int mmr_pnode;
+	unsigned long mmr_value;
+	struct uv_IO_APIC_route_entry *entry;
+	int err;
+
+	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
+			sizeof(unsigned long));
+
+	cfg = irq_cfg(irq);
+
+	err = assign_irq_vector(irq, cfg, eligible_cpu);
+	if (err != 0)
+		return err;
+
+	if (restrict == UV_AFFINITY_CPU)
+		desc->status |= IRQ_NO_BALANCING;
+	else
+		desc->status |= IRQ_MOVE_PCNTXT;
+
+	set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
+				      irq_name);
+
+	mmr_value = 0;
+	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+	entry->vector		= cfg->vector;
+	entry->delivery_mode	= apic->irq_delivery_mode;
+	entry->dest_mode	= apic->irq_dest_mode;
+	entry->polarity		= 0;
+	entry->trigger		= 0;
+	entry->mask		= 0;
+	entry->dest		= apic->cpu_mask_to_apicid(eligible_cpu);
+
+	mmr_pnode = uv_blade_to_pnode(mmr_blade);
+	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+	if (cfg->move_in_progress)
+		send_cleanup_vector(cfg);
+
+	return irq;
+}
+
+/*
+ * Disable the specified MMR located on the specified blade so that MSIs are
+ * longer allowed to be sent.
+ */
+static void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset)
+{
+	unsigned long mmr_value;
+	struct uv_IO_APIC_route_entry *entry;
+
+	BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) !=
+			sizeof(unsigned long));
+
+	mmr_value = 0;
+	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+	entry->mask = 1;
+
+	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+}
+
+static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg = desc->chip_data;
+	unsigned int dest;
+	unsigned long mmr_value;
+	struct uv_IO_APIC_route_entry *entry;
+	unsigned long mmr_offset;
+	unsigned mmr_pnode;
+
+	if (set_desc_affinity(desc, mask, &dest))
+		return -1;
+
+	mmr_value = 0;
+	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+
+	entry->vector		= cfg->vector;
+	entry->delivery_mode	= apic->irq_delivery_mode;
+	entry->dest_mode	= apic->irq_dest_mode;
+	entry->polarity		= 0;
+	entry->trigger		= 0;
+	entry->mask		= 0;
+	entry->dest		= dest;
+
+	/* Get previously stored MMR and pnode of hub sourcing interrupts */
+	if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode))
+		return -1;
+
+	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+	if (cfg->move_in_progress)
+		send_cleanup_vector(cfg);
+
+	return 0;
+}
+
+/*
  * Set up a mapping of an available irq and vector, and enable the specified
  * MMR that defines the MSI that is to be sent to the specified CPU when an
  * interrupt is raised.
  */
 int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
-		 unsigned long mmr_offset)
+		 unsigned long mmr_offset, int restrict)
 {
-	int irq;
-	int ret;
+	int irq, ret;
+
+	irq = create_irq_nr(NR_IRQS_LEGACY, uv_blade_to_memory_nid(mmr_blade));
 
-	irq = create_irq();
 	if (irq <= 0)
 		return -EBUSY;
 
-	ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
-	if (ret != irq)
+	ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset,
+		restrict);
+	if (ret == irq)
+		uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade);
+	else
 		destroy_irq(irq);
 
 	return ret;
@@ -71,9 +274,28 @@ EXPORT_SYMBOL_GPL(uv_setup_irq);
  *
  * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
  */
-void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
+void uv_teardown_irq(unsigned int irq)
 {
-	arch_disable_uv_irq(mmr_blade, mmr_offset);
+	struct uv_irq_2_mmr_pnode *e;
+	struct rb_node *n;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&uv_irq_lock, irqflags);
+	n = uv_irq_root.rb_node;
+	while (n) {
+		e = rb_entry(n, struct uv_irq_2_mmr_pnode, list);
+		if (e->irq == irq) {
+			arch_disable_uv_irq(e->pnode, e->offset);
+			rb_erase(n, &uv_irq_root);
+			kfree(e);
+			break;
+		}
+		if (irq < e->irq)
+			n = n->rb_left;
+		else
+			n = n->rb_right;
+	}
+	spin_unlock_irqrestore(&uv_irq_lock, irqflags);
 	destroy_irq(irq);
 }
 EXPORT_SYMBOL_GPL(uv_teardown_irq);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/uv_time.c linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_time.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/uv_time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/uv_time.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,7 @@ struct uv_rtc_timer_head {
  */
 static struct uv_rtc_timer_head		**blade_info __read_mostly;
 
-static int				uv_rtc_enable;
+static int				uv_rtc_evt_enable;
 
 /*
  * Hardware interface routines
@@ -90,7 +90,7 @@ static void uv_rtc_send_IPI(int cpu)
 	pnode = uv_apicid_to_pnode(apicid);
 	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
 	      (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-	      (GENERIC_INTERRUPT_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
+	      (X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
 
 	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
 }
@@ -115,7 +115,7 @@ static int uv_setup_intr(int cpu, u64 ex
 	uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
 		UVH_EVENT_OCCURRED0_RTC1_MASK);
 
-	val = (GENERIC_INTERRUPT_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
+	val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
 		((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
 
 	/* Set configuration */
@@ -123,7 +123,10 @@ static int uv_setup_intr(int cpu, u64 ex
 	/* Initialize comparator value */
 	uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires);
 
-	return (expires < uv_read_rtc(NULL) && !uv_intr_pending(pnode));
+	if (uv_read_rtc(NULL) <= expires)
+		return 0;
+
+	return !uv_intr_pending(pnode);
 }
 
 /*
@@ -223,6 +226,7 @@ static int uv_rtc_set_timer(int cpu, u64
 
 	next_cpu = head->next_cpu;
 	*t = expires;
+
 	/* Will this one be next to go off? */
 	if (next_cpu < 0 || bcpu == next_cpu ||
 			expires < head->cpu[next_cpu].expires) {
@@ -231,7 +235,7 @@ static int uv_rtc_set_timer(int cpu, u64
 			*t = ULLONG_MAX;
 			uv_rtc_find_next_timer(head, pnode);
 			spin_unlock_irqrestore(&head->lock, flags);
-			return 1;
+			return -ETIME;
 		}
 	}
 
@@ -244,7 +248,7 @@ static int uv_rtc_set_timer(int cpu, u64
  *
  * Returns 1 if this timer was pending.
  */
-static int uv_rtc_unset_timer(int cpu)
+static int uv_rtc_unset_timer(int cpu, int force)
 {
 	int pnode = uv_cpu_to_pnode(cpu);
 	int bid = uv_cpu_to_blade_id(cpu);
@@ -256,14 +260,15 @@ static int uv_rtc_unset_timer(int cpu)
 
 	spin_lock_irqsave(&head->lock, flags);
 
-	if (head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t)
+	if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force)
 		rc = 1;
 
-	*t = ULLONG_MAX;
-
-	/* Was the hardware setup for this timer? */
-	if (head->next_cpu == bcpu)
-		uv_rtc_find_next_timer(head, pnode);
+	if (rc) {
+		*t = ULLONG_MAX;
+		/* Was the hardware setup for this timer? */
+		if (head->next_cpu == bcpu)
+			uv_rtc_find_next_timer(head, pnode);
+	}
 
 	spin_unlock_irqrestore(&head->lock, flags);
 
@@ -277,10 +282,21 @@ static int uv_rtc_unset_timer(int cpu)
 
 /*
  * Read the RTC.
+ *
+ * Starting with HUB rev 2.0, the UV RTC register is replicated across all
+ * cachelines of it's own page.  This allows faster simultaneous reads
+ * from a given socket.
  */
 static cycle_t uv_read_rtc(struct clocksource *cs)
 {
-	return (cycle_t)uv_read_local_mmr(UVH_RTC);
+	unsigned long offset;
+
+	if (uv_get_min_hub_revision_id() == 1)
+		offset = 0;
+	else
+		offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;
+
+	return (cycle_t)uv_read_local_mmr(UVH_RTC | offset);
 }
 
 /*
@@ -310,32 +326,32 @@ static void uv_rtc_timer_setup(enum cloc
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		uv_rtc_unset_timer(ced_cpu);
+		uv_rtc_unset_timer(ced_cpu, 1);
 		break;
 	}
 }
 
 static void uv_rtc_interrupt(void)
 {
-	struct clock_event_device *ced = &__get_cpu_var(cpu_ced);
 	int cpu = smp_processor_id();
+	struct clock_event_device *ced = &per_cpu(cpu_ced, cpu);
 
 	if (!ced || !ced->event_handler)
 		return;
 
-	if (uv_rtc_unset_timer(cpu) != 1)
+	if (uv_rtc_unset_timer(cpu, 0) != 1)
 		return;
 
 	ced->event_handler(ced);
 }
 
-static int __init uv_enable_rtc(char *str)
+static int __init uv_enable_evt_rtc(char *str)
 {
-	uv_rtc_enable = 1;
+	uv_rtc_evt_enable = 1;
 
 	return 1;
 }
-__setup("uvrtc", uv_enable_rtc);
+__setup("uvrtcevt", uv_enable_evt_rtc);
 
 static __init void uv_rtc_register_clockevents(struct work_struct *dummy)
 {
@@ -350,27 +366,32 @@ static __init int uv_rtc_setup_clock(voi
 {
 	int rc;
 
-	if (!uv_rtc_enable || !is_uv_system() || generic_interrupt_extension)
+	if (!is_uv_system())
 		return -ENODEV;
 
-	generic_interrupt_extension = uv_rtc_interrupt;
-
 	clocksource_uv.mult = clocksource_hz2mult(sn_rtc_cycles_per_second,
 				clocksource_uv.shift);
 
+	/* If single blade, prefer tsc */
+	if (uv_num_possible_blades() == 1)
+		clocksource_uv.rating = 250;
+
 	rc = clocksource_register(&clocksource_uv);
-	if (rc) {
-		generic_interrupt_extension = NULL;
+	if (rc)
+		printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
+	else
+		printk(KERN_INFO "UV RTC clocksource registered freq %lu MHz\n",
+			sn_rtc_cycles_per_second/(unsigned long)1E6);
+
+	if (rc || !uv_rtc_evt_enable || x86_platform_ipi_callback)
 		return rc;
-	}
 
 	/* Setup and register clockevents */
 	rc = uv_rtc_allocate_timers();
-	if (rc) {
-		clocksource_unregister(&clocksource_uv);
-		generic_interrupt_extension = NULL;
-		return rc;
-	}
+	if (rc)
+		goto error;
+
+	x86_platform_ipi_callback = uv_rtc_interrupt;
 
 	clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second,
 				NSEC_PER_SEC, clock_event_device_uv.shift);
@@ -383,11 +404,19 @@ static __init int uv_rtc_setup_clock(voi
 
 	rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
 	if (rc) {
-		clocksource_unregister(&clocksource_uv);
-		generic_interrupt_extension = NULL;
+		x86_platform_ipi_callback = NULL;
 		uv_rtc_deallocate_timers();
+		goto error;
 	}
 
+	printk(KERN_INFO "UV RTC clockevents registered\n");
+
+	return 0;
+
+error:
+	clocksource_unregister(&clocksource_uv);
+	printk(KERN_INFO "UV RTC clockevents failed rc %d\n", rc);
+
 	return rc;
 }
 arch_initcall(uv_rtc_setup_clock);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/visws_quirks.c linux-libre-2.6.33-gnu1/arch/x86/kernel/visws_quirks.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/visws_quirks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/visws_quirks.c	2010-02-24 13:52:17.000000000 -0500
@@ -183,7 +183,7 @@ static void __init MP_processor_info(str
 		return;
 	}
 
-	apic_cpus = apic->apicid_to_cpu_present(m->apicid);
+	apic->apicid_to_cpu_present(m->apicid, &apic_cpus);
 	physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
 	/*
 	 * Validate version
@@ -197,7 +197,7 @@ static void __init MP_processor_info(str
 	apic_version[m->apicid] = ver;
 }
 
-static void __init visws_find_smp_config(unsigned int reserve)
+static void __init visws_find_smp_config(void)
 {
 	struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
 	unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
@@ -486,7 +486,7 @@ static void end_cobalt_irq(unsigned int
 }
 
 static struct irq_chip cobalt_irq_type = {
-	.typename =	"Cobalt-APIC",
+	.name =		"Cobalt-APIC",
 	.startup =	startup_cobalt_irq,
 	.shutdown =	disable_cobalt_irq,
 	.enable =	enable_cobalt_irq,
@@ -523,7 +523,7 @@ static void end_piix4_master_irq(unsigne
 }
 
 static struct irq_chip piix4_master_irq_type = {
-	.typename =	"PIIX4-master",
+	.name =		"PIIX4-master",
 	.startup =	startup_piix4_master_irq,
 	.ack =		ack_cobalt_irq,
 	.end =		end_piix4_master_irq,
@@ -531,7 +531,7 @@ static struct irq_chip piix4_master_irq_
 
 
 static struct irq_chip piix4_virtual_irq_type = {
-	.typename =	"PIIX4-virtual",
+	.name =		"PIIX4-virtual",
 	.shutdown =	disable_8259A_irq,
 	.enable =	enable_8259A_irq,
 	.disable =	disable_8259A_irq,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/vm86_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/vm86_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/vm86_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/vm86_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -197,9 +197,8 @@ out:
 static int do_vm86_irq_handling(int subfunction, int irqnumber);
 static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
 
-int sys_vm86old(struct pt_regs *regs)
+int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs)
 {
-	struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx;
 	struct kernel_vm86_struct info; /* declare this _on top_,
 					 * this avoids wasting of stack space.
 					 * This remains on the stack until we
@@ -227,7 +226,7 @@ out:
 }
 
 
-int sys_vm86(struct pt_regs *regs)
+int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs)
 {
 	struct kernel_vm86_struct info; /* declare this _on top_,
 					 * this avoids wasting of stack space.
@@ -239,12 +238,12 @@ int sys_vm86(struct pt_regs *regs)
 	struct vm86plus_struct __user *v86;
 
 	tsk = current;
-	switch (regs->bx) {
+	switch (cmd) {
 	case VM86_REQUEST_IRQ:
 	case VM86_FREE_IRQ:
 	case VM86_GET_IRQ_BITS:
 	case VM86_GET_AND_RESET_IRQ:
-		ret = do_vm86_irq_handling(regs->bx, (int)regs->cx);
+		ret = do_vm86_irq_handling(cmd, (int)arg);
 		goto out;
 	case VM86_PLUS_INSTALL_CHECK:
 		/*
@@ -261,7 +260,7 @@ int sys_vm86(struct pt_regs *regs)
 	ret = -EPERM;
 	if (tsk->thread.saved_sp0)
 		goto out;
-	v86 = (struct vm86plus_struct __user *)regs->cx;
+	v86 = (struct vm86plus_struct __user *)arg;
 	tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
 				       offsetof(struct kernel_vm86_struct, regs32) -
 				       sizeof(info.regs));
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/vmiclock_32.c linux-libre-2.6.33-gnu1/arch/x86/kernel/vmiclock_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/vmiclock_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/vmiclock_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -226,7 +226,7 @@ static void __devinit vmi_time_init_cloc
 	evt->min_delta_ns = clockevent_delta2ns(1, evt);
 	evt->cpumask = cpumask_of(cpu);
 
-	printk(KERN_WARNING "vmi: registering clock event %s. mult=%lu shift=%u\n",
+	printk(KERN_WARNING "vmi: registering clock event %s. mult=%u shift=%u\n",
 	       evt->name, evt->mult, evt->shift);
 	clockevents_register_device(evt);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/vmlinux.lds.S linux-libre-2.6.33-gnu1/arch/x86/kernel/vmlinux.lds.S
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/vmlinux.lds.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/vmlinux.lds.S	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,32 @@ ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
 #endif
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+/*
+ * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA
+ * we retain large page mappings for boundaries spanning kernel text, rodata
+ * and data sections.
+ *
+ * However, kernel identity mappings will have different RWX permissions
+ * to the pages mapping to text and to the pages padding (which are freed) the
+ * text section. Hence kernel identity mappings will be broken to smaller
+ * pages. For 64-bit, kernel text and kernel identity mappings are different,
+ * so we can enable protection checks that come with CONFIG_DEBUG_RODATA,
+ * as well as retain 2MB large page mappings for kernel text.
+ */
+#define X64_ALIGN_DEBUG_RODATA_BEGIN	. = ALIGN(HPAGE_SIZE);
+
+#define X64_ALIGN_DEBUG_RODATA_END				\
+		. = ALIGN(HPAGE_SIZE);				\
+		__end_rodata_hpage_align = .;
+
+#else
+
+#define X64_ALIGN_DEBUG_RODATA_BEGIN
+#define X64_ALIGN_DEBUG_RODATA_END
+
+#endif
+
 PHDRS {
 	text PT_LOAD FLAGS(5);          /* R_E */
 	data PT_LOAD FLAGS(7);          /* RWE */
@@ -90,7 +116,9 @@ SECTIONS
 
 	EXCEPTION_TABLE(16) :text = 0x9090
 
+	X64_ALIGN_DEBUG_RODATA_BEGIN
 	RO_DATA(PAGE_SIZE)
+	X64_ALIGN_DEBUG_RODATA_END
 
 	/* Data */
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -107,13 +135,13 @@ SECTIONS
 
 		PAGE_ALIGNED_DATA(PAGE_SIZE)
 
-		CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
+		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 
 		DATA_DATA
 		CONSTRUCTORS
 
 		/* rarely changed data like cpu maps */
-		READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
+		READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
 
 		/* End of data section */
 		_edata = .;
@@ -137,12 +165,12 @@ SECTIONS
 		*(.vsyscall_0)
 	} :user
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
 		*(.vsyscall_fn)
 	}
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
 		*(.vsyscall_gtod_data)
 	}
@@ -166,7 +194,7 @@ SECTIONS
 	}
 	vgetcpu_mode = VVIRT(.vgetcpu_mode);
 
-	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+	. = ALIGN(L1_CACHE_BYTES);
 	.jiffies : AT(VLOAD(.jiffies)) {
 		*(.jiffies)
 	}
@@ -291,9 +319,7 @@ SECTIONS
 		__brk_limit = .;
 	}
 
-	.end : AT(ADDR(.end) - LOAD_OFFSET) {
-		_end = .;
-	}
+	_end = .;
 
         STABS_DEBUG
         DWARF_DEBUG
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/vsyscall_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/vsyscall_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/vsyscall_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/vsyscall_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,7 +73,8 @@ void update_vsyscall_tz(void)
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
+		     u32 mult)
 {
 	unsigned long flags;
 
@@ -82,7 +83,7 @@ void update_vsyscall(struct timespec *wa
 	vsyscall_gtod_data.clock.vread = clock->vread;
 	vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
 	vsyscall_gtod_data.clock.mask = clock->mask;
-	vsyscall_gtod_data.clock.mult = clock->mult;
+	vsyscall_gtod_data.clock.mult = mult;
 	vsyscall_gtod_data.clock.shift = clock->shift;
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
@@ -237,7 +238,7 @@ static ctl_table kernel_table2[] = {
 };
 
 static ctl_table kernel_root_table2[] = {
-	{ .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
+	{ .procname = "kernel", .mode = 0555,
 	  .child = kernel_table2 },
 	{}
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/x8664_ksyms_64.c linux-libre-2.6.33-gnu1/arch/x86/kernel/x8664_ksyms_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,6 @@
 EXPORT_SYMBOL(mcount);
 #endif
 
-EXPORT_SYMBOL(kernel_thread);
-
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
 EXPORT_SYMBOL(__get_user_4);
@@ -30,9 +28,8 @@ EXPORT_SYMBOL(__put_user_8);
 
 EXPORT_SYMBOL(copy_user_generic);
 EXPORT_SYMBOL(__copy_user_nocache);
-EXPORT_SYMBOL(copy_from_user);
-EXPORT_SYMBOL(copy_to_user);
-EXPORT_SYMBOL(__copy_from_user_inatomic);
+EXPORT_SYMBOL(_copy_from_user);
+EXPORT_SYMBOL(_copy_to_user);
 
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
@@ -57,4 +54,6 @@ EXPORT_SYMBOL(__memcpy);
 
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(init_level4_pgt);
-EXPORT_SYMBOL(load_gs_index);
+#ifndef CONFIG_PARAVIRT
+EXPORT_SYMBOL(native_load_gs_index);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kernel/x86_init.c linux-libre-2.6.33-gnu1/arch/x86/kernel/x86_init.c
--- linux-libre-2.6.32-gnu1/arch/x86/kernel/x86_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kernel/x86_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,11 +13,15 @@
 #include <asm/e820.h>
 #include <asm/time.h>
 #include <asm/irq.h>
+#include <asm/pat.h>
 #include <asm/tsc.h>
+#include <asm/iommu.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 void __init x86_init_pgd_noop(pgd_t *unused) { }
+int __init iommu_init_noop(void) { return 0; }
+void iommu_shutdown_noop(void) { }
 
 /*
  * The platform setup functions are preset with the default functions
@@ -62,6 +66,10 @@ struct x86_init_ops x86_init __initdata
 		.tsc_pre_init		= x86_init_noop,
 		.timer_init		= hpet_time_init,
 	},
+
+	.iommu = {
+		.iommu_init		= iommu_init_noop,
+	},
 };
 
 struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
@@ -72,4 +80,6 @@ struct x86_platform_ops x86_platform = {
 	.calibrate_tsc			= native_calibrate_tsc,
 	.get_wallclock			= mach_get_cmos_time,
 	.set_wallclock			= mach_set_rtc_mmss,
+	.iommu_shutdown			= iommu_shutdown_noop,
+	.is_untracked_pat_range		= is_ISA_range,
 };
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/emulate.c linux-libre-2.6.33-gnu1/arch/x86/kvm/emulate.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/emulate.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/emulate.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,6 +75,8 @@
 #define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
 #define GroupMask   0xff        /* Group number stored in bits 0:7 */
+/* Misc flags */
+#define No64	    (1<<28)
 /* Source 2 operand type */
 #define Src2None    (0<<29)
 #define Src2CL      (1<<29)
@@ -92,19 +94,23 @@ static u32 opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x08 - 0x0F */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+	ImplicitOps | Stack | No64, 0,
 	/* 0x10 - 0x17 */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x18 - 0x1F */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
 	/* 0x20 - 0x27 */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -133,7 +139,8 @@ static u32 opcode_table[256] = {
 	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
 	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
 	/* 0x60 - 0x67 */
-	0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
+	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
+	0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
 	0, 0, 0, 0,
 	/* 0x68 - 0x6F */
 	SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
@@ -158,7 +165,7 @@ static u32 opcode_table[256] = {
 	/* 0x90 - 0x97 */
 	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
 	/* 0x98 - 0x9F */
-	0, 0, SrcImm | Src2Imm16, 0,
+	0, 0, SrcImm | Src2Imm16 | No64, 0,
 	ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
 	/* 0xA0 - 0xA7 */
 	ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
@@ -185,7 +192,7 @@ static u32 opcode_table[256] = {
 	ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
 	/* 0xC8 - 0xCF */
 	0, 0, 0, ImplicitOps | Stack,
-	ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps,
+	ImplicitOps, SrcImmByte, ImplicitOps | No64, ImplicitOps,
 	/* 0xD0 - 0xD7 */
 	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
 	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
@@ -198,7 +205,7 @@ static u32 opcode_table[256] = {
 	ByteOp | SrcImmUByte, SrcImmUByte,
 	/* 0xE8 - 0xEF */
 	SrcImm | Stack, SrcImm | ImplicitOps,
-	SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps,
+	SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps,
 	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
 	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
 	/* 0xF0 - 0xF7 */
@@ -244,11 +251,13 @@ static u32 twobyte_table[256] = {
 	/* 0x90 - 0x9F */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0xA0 - 0xA7 */
-	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
+	ImplicitOps | Stack, ImplicitOps | Stack,
+	0, DstMem | SrcReg | ModRM | BitOp,
 	DstMem | SrcReg | Src2ImmByte | ModRM,
 	DstMem | SrcReg | Src2CL | ModRM, 0, 0,
 	/* 0xA8 - 0xAF */
-	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
+	ImplicitOps | Stack, ImplicitOps | Stack,
+	0, DstMem | SrcReg | ModRM | BitOp,
 	DstMem | SrcReg | Src2ImmByte | ModRM,
 	DstMem | SrcReg | Src2CL | ModRM,
 	ModRM, 0,
@@ -613,6 +622,9 @@ static int do_insn_fetch(struct x86_emul
 {
 	int rc = 0;
 
+	/* x86 instructions are limited to 15 bytes. */
+	if (eip + size - ctxt->decode.eip_orig > 15)
+		return X86EMUL_UNHANDLEABLE;
 	eip += ctxt->cs_base;
 	while (size--) {
 		rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
@@ -871,7 +883,7 @@ x86_decode_insn(struct x86_emulate_ctxt
 	/* Shadow copy of register state. Committed on successful emulation. */
 
 	memset(c, 0, sizeof(struct decode_cache));
-	c->eip = kvm_rip_read(ctxt->vcpu);
+	c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu);
 	ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
 	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
 
@@ -962,6 +974,11 @@ done_prefixes:
 		}
 	}
 
+	if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
+		kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");;
+		return -1;
+	}
+
 	if (c->d & Group) {
 		group = c->d & GroupMask;
 		c->modrm = insn_fetch(u8, 1, c->eip);
@@ -1186,6 +1203,69 @@ static int emulate_pop(struct x86_emulat
 	return rc;
 }
 
+static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct kvm_segment segment;
+
+	kvm_x86_ops->get_segment(ctxt->vcpu, &segment, seg);
+
+	c->src.val = segment.selector;
+	emulate_push(ctxt);
+}
+
+static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
+			     struct x86_emulate_ops *ops, int seg)
+{
+	struct decode_cache *c = &ctxt->decode;
+	unsigned long selector;
+	int rc;
+
+	rc = emulate_pop(ctxt, ops, &selector, c->op_bytes);
+	if (rc != 0)
+		return rc;
+
+	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
+	return rc;
+}
+
+static void emulate_pusha(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	unsigned long old_esp = c->regs[VCPU_REGS_RSP];
+	int reg = VCPU_REGS_RAX;
+
+	while (reg <= VCPU_REGS_RDI) {
+		(reg == VCPU_REGS_RSP) ?
+		(c->src.val = old_esp) : (c->src.val = c->regs[reg]);
+
+		emulate_push(ctxt);
+		++reg;
+	}
+}
+
+static int emulate_popa(struct x86_emulate_ctxt *ctxt,
+			struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc = 0;
+	int reg = VCPU_REGS_RDI;
+
+	while (reg >= VCPU_REGS_RAX) {
+		if (reg == VCPU_REGS_RSP) {
+			register_address_increment(c, &c->regs[VCPU_REGS_RSP],
+							c->op_bytes);
+			--reg;
+		}
+
+		rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes);
+		if (rc != 0)
+			break;
+		--reg;
+	}
+	return rc;
+}
+
 static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
 				struct x86_emulate_ops *ops)
 {
@@ -1707,18 +1787,45 @@ special_insn:
 	      add:		/* add */
 		emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0x06:		/* push es */
+		emulate_push_sreg(ctxt, VCPU_SREG_ES);
+		break;
+	case 0x07:		/* pop es */
+		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0x08 ... 0x0d:
 	      or:		/* or */
 		emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0x0e:		/* push cs */
+		emulate_push_sreg(ctxt, VCPU_SREG_CS);
+		break;
 	case 0x10 ... 0x15:
 	      adc:		/* adc */
 		emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0x16:		/* push ss */
+		emulate_push_sreg(ctxt, VCPU_SREG_SS);
+		break;
+	case 0x17:		/* pop ss */
+		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0x18 ... 0x1d:
 	      sbb:		/* sbb */
 		emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0x1e:		/* push ds */
+		emulate_push_sreg(ctxt, VCPU_SREG_DS);
+		break;
+	case 0x1f:		/* pop ds */
+		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0x20 ... 0x25:
 	      and:		/* and */
 		emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
@@ -1750,6 +1857,14 @@ special_insn:
 		if (rc != 0)
 			goto done;
 		break;
+	case 0x60:	/* pusha */
+		emulate_pusha(ctxt);
+		break;
+	case 0x61:	/* popa */
+		rc = emulate_popa(ctxt, ops);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0x63:		/* movsxd */
 		if (ctxt->mode != X86EMUL_MODE_PROT64)
 			goto cannot_emulate;
@@ -1761,7 +1876,7 @@ special_insn:
 		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
-		 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
+		 if (kvm_emulate_pio_string(ctxt->vcpu,
 				1,
 				(c->d & ByteOp) ? 1 : c->op_bytes,
 				c->rep_prefix ?
@@ -1777,7 +1892,7 @@ special_insn:
 		return 0;
 	case 0x6e:		/* outsb */
 	case 0x6f:		/* outsw/outsd */
-		if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
+		if (kvm_emulate_pio_string(ctxt->vcpu,
 				0,
 				(c->d & ByteOp) ? 1 : c->op_bytes,
 				c->rep_prefix ?
@@ -2070,7 +2185,7 @@ special_insn:
 	case 0xef: /* out (e/r)ax,dx */
 		port = c->regs[VCPU_REGS_RDX];
 		io_dir_in = 0;
-	do_io:	if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in,
+	do_io:	if (kvm_emulate_pio(ctxt->vcpu, io_dir_in,
 				   (c->d & ByteOp) ? 1 : c->op_bytes,
 				   port) != 0) {
 			c->eip = saved_eip;
@@ -2297,6 +2412,14 @@ twobyte_insn:
 			jmp_rel(c, c->src.val);
 		c->dst.type = OP_NONE;
 		break;
+	case 0xa0:	  /* push fs */
+		emulate_push_sreg(ctxt, VCPU_SREG_FS);
+		break;
+	case 0xa1:	 /* pop fs */
+		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0xa3:
 	      bt:		/* bt */
 		c->dst.type = OP_NONE;
@@ -2308,6 +2431,14 @@ twobyte_insn:
 	case 0xa5: /* shld cl, r, r/m */
 		emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
 		break;
+	case 0xa8:	/* push gs */
+		emulate_push_sreg(ctxt, VCPU_SREG_GS);
+		break;
+	case 0xa9:	/* pop gs */
+		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
+		if (rc != 0)
+			goto done;
+		break;
 	case 0xab:
 	      bts:		/* bts */
 		/* only subword offset */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/i8254.c linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/i8254.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/i8254.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,8 @@
  *   Based on QEMU and Xen.
  */
 
+#define pr_fmt(fmt) "pit: " fmt
+
 #include <linux/kvm_host.h>
 
 #include "irq.h"
@@ -262,7 +264,7 @@ void __kvm_migrate_pit_timer(struct kvm_
 
 static void destroy_pit_timer(struct kvm_timer *pt)
 {
-	pr_debug("pit: execute del timer!\n");
+	pr_debug("execute del timer!\n");
 	hrtimer_cancel(&pt->timer);
 }
 
@@ -284,7 +286,7 @@ static void create_pit_timer(struct kvm_
 
 	interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
 
-	pr_debug("pit: create pit timer, interval is %llu nsec\n", interval);
+	pr_debug("create pit timer, interval is %llu nsec\n", interval);
 
 	/* TODO The new value only affected after the retriggered */
 	hrtimer_cancel(&pt->timer);
@@ -309,7 +311,7 @@ static void pit_load_count(struct kvm *k
 
 	WARN_ON(!mutex_is_locked(&ps->lock));
 
-	pr_debug("pit: load_count val is %d, channel is %d\n", val, channel);
+	pr_debug("load_count val is %d, channel is %d\n", val, channel);
 
 	/*
 	 * The largest possible initial count is 0; this is equivalent
@@ -395,8 +397,8 @@ static int pit_ioport_write(struct kvm_i
 	mutex_lock(&pit_state->lock);
 
 	if (val != 0)
-		pr_debug("pit: write addr is 0x%x, len is %d, val is 0x%x\n",
-			  (unsigned int)addr, len, val);
+		pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n",
+			 (unsigned int)addr, len, val);
 
 	if (addr == 3) {
 		channel = val >> 6;
@@ -465,6 +467,9 @@ static int pit_ioport_read(struct kvm_io
 		return -EOPNOTSUPP;
 
 	addr &= KVM_PIT_CHANNEL_MASK;
+	if (addr == 3)
+		return 0;
+
 	s = &pit_state->channels[addr];
 
 	mutex_lock(&pit_state->lock);
@@ -688,10 +693,8 @@ static void __inject_pit_timer_intr(stru
 	struct kvm_vcpu *vcpu;
 	int i;
 
-	mutex_lock(&kvm->irq_lock);
 	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
 	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
-	mutex_unlock(&kvm->irq_lock);
 
 	/*
 	 * Provides NMI watchdog support via Virtual Wire mode.
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/i8259.c linux-libre-2.6.33-gnu1/arch/x86/kvm/i8259.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/i8259.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/i8259.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,15 @@ static void pic_clear_isr(struct kvm_kpi
 	s->isr_ack |= (1 << irq);
 	if (s != &s->pics_state->pics[0])
 		irq += 8;
+	/*
+	 * We are dropping lock while calling ack notifiers since ack
+	 * notifier callbacks for assigned devices call into PIC recursively.
+	 * Other interrupt may be delivered to PIC while lock is dropped but
+	 * it should be safe since PIC state is already updated at this stage.
+	 */
+	spin_unlock(&s->pics_state->lock);
 	kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
+	spin_lock(&s->pics_state->lock);
 }
 
 void kvm_pic_clear_isr_ack(struct kvm *kvm)
@@ -176,16 +184,18 @@ int kvm_pic_set_irq(void *opaque, int ir
 static inline void pic_intack(struct kvm_kpic_state *s, int irq)
 {
 	s->isr |= 1 << irq;
-	if (s->auto_eoi) {
-		if (s->rotate_on_auto_eoi)
-			s->priority_add = (irq + 1) & 7;
-		pic_clear_isr(s, irq);
-	}
 	/*
 	 * We don't clear a level sensitive interrupt here
 	 */
 	if (!(s->elcr & (1 << irq)))
 		s->irr &= ~(1 << irq);
+
+	if (s->auto_eoi) {
+		if (s->rotate_on_auto_eoi)
+			s->priority_add = (irq + 1) & 7;
+		pic_clear_isr(s, irq);
+	}
+
 }
 
 int kvm_pic_read_irq(struct kvm *kvm)
@@ -225,22 +235,11 @@ int kvm_pic_read_irq(struct kvm *kvm)
 
 void kvm_pic_reset(struct kvm_kpic_state *s)
 {
-	int irq, irqbase, n;
+	int irq;
 	struct kvm *kvm = s->pics_state->irq_request_opaque;
 	struct kvm_vcpu *vcpu0 = kvm->bsp_vcpu;
+	u8 irr = s->irr, isr = s->imr;
 
-	if (s == &s->pics_state->pics[0])
-		irqbase = 0;
-	else
-		irqbase = 8;
-
-	for (irq = 0; irq < PIC_NUM_PINS/2; irq++) {
-		if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
-			if (s->irr & (1 << irq) || s->isr & (1 << irq)) {
-				n = irq + irqbase;
-				kvm_notify_acked_irq(kvm, SELECT_PIC(n), n);
-			}
-	}
 	s->last_irr = 0;
 	s->irr = 0;
 	s->imr = 0;
@@ -256,6 +255,13 @@ void kvm_pic_reset(struct kvm_kpic_state
 	s->rotate_on_auto_eoi = 0;
 	s->special_fully_nested_mode = 0;
 	s->init4 = 0;
+
+	for (irq = 0; irq < PIC_NUM_PINS/2; irq++) {
+		if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
+			if (irr & (1 << irq) || isr & (1 << irq)) {
+				pic_clear_isr(s, irq);
+			}
+	}
 }
 
 static void pic_ioport_write(void *opaque, u32 addr, u32 val)
@@ -298,9 +304,9 @@ static void pic_ioport_write(void *opaqu
 				priority = get_priority(s, s->isr);
 				if (priority != 8) {
 					irq = (priority + s->priority_add) & 7;
-					pic_clear_isr(s, irq);
 					if (cmd == 5)
 						s->priority_add = (irq + 1) & 7;
+					pic_clear_isr(s, irq);
 					pic_update_irq(s->pics_state);
 				}
 				break;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/irq.h linux-libre-2.6.33-gnu1/arch/x86/kvm/irq.h
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/irq.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/irq.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,7 @@ struct kvm_pic {
 	int output;		/* intr from master PIC */
 	struct kvm_io_device dev;
 	void (*ack_notifier)(void *opaque, int irq);
+	unsigned long irq_states[16];
 };
 
 struct kvm_pic *kvm_create_pic(struct kvm *kvm);
@@ -85,7 +86,11 @@ static inline struct kvm_pic *pic_irqchi
 
 static inline int irqchip_in_kernel(struct kvm *kvm)
 {
-	return pic_irqchip(kvm) != NULL;
+	int ret;
+
+	ret = (pic_irqchip(kvm) != NULL);
+	smp_rmb();
+	return ret;
 }
 
 void kvm_pic_reset(struct kvm_kpic_state *s);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/Kconfig linux-libre-2.6.33-gnu1/arch/x86/kvm/Kconfig
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@ config KVM
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
+	select USER_RETURN_NOTIFIER
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
 	  virtualization extensions.  You will need a fairly recent
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/lapic.c linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/lapic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/lapic.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,6 @@
 #include <asm/current.h>
 #include <asm/apicdef.h>
 #include <asm/atomic.h>
-#include <asm/apicdef.h>
 #include "kvm_cache_regs.h"
 #include "irq.h"
 #include "trace.h"
@@ -374,6 +373,12 @@ static int __apic_accept_irq(struct kvm_
 		if (unlikely(!apic_enabled(apic)))
 			break;
 
+		if (trig_mode) {
+			apic_debug("level trig mode for vector %d", vector);
+			apic_set_vector(vector, apic->regs + APIC_TMR);
+		} else
+			apic_clear_vector(vector, apic->regs + APIC_TMR);
+
 		result = !apic_test_and_set_irr(vector, apic);
 		trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
 					  trig_mode, vector, !result);
@@ -384,11 +389,6 @@ static int __apic_accept_irq(struct kvm_
 			break;
 		}
 
-		if (trig_mode) {
-			apic_debug("level trig mode for vector %d", vector);
-			apic_set_vector(vector, apic->regs + APIC_TMR);
-		} else
-			apic_clear_vector(vector, apic->regs + APIC_TMR);
 		kvm_vcpu_kick(vcpu);
 		break;
 
@@ -471,11 +471,8 @@ static void apic_set_eoi(struct kvm_lapi
 		trigger_mode = IOAPIC_LEVEL_TRIG;
 	else
 		trigger_mode = IOAPIC_EDGE_TRIG;
-	if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) {
-		mutex_lock(&apic->vcpu->kvm->irq_lock);
+	if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI))
 		kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
-		mutex_unlock(&apic->vcpu->kvm->irq_lock);
-	}
 }
 
 static void apic_send_ipi(struct kvm_lapic *apic)
@@ -504,9 +501,7 @@ static void apic_send_ipi(struct kvm_lap
 		   irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
 		   irq.vector);
 
-	mutex_lock(&apic->vcpu->kvm->irq_lock);
 	kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq);
-	mutex_unlock(&apic->vcpu->kvm->irq_lock);
 }
 
 static u32 apic_get_tmcct(struct kvm_lapic *apic)
@@ -1156,6 +1151,7 @@ void kvm_apic_post_state_restore(struct
 	hrtimer_cancel(&apic->lapic_timer.timer);
 	update_divide_count(apic);
 	start_apic_timer(apic);
+	apic->irr_pending = true;
 }
 
 void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/Makefile linux-libre-2.6.33-gnu1/arch/x86/kvm/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,8 @@ 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)
+				coalesced_mmio.o irq_comm.o eventfd.o \
+				assigned-dev.o)
 kvm-$(CONFIG_IOMMU_API)	+= $(addprefix ../../../virt/kvm/, iommu.o)
 
 kvm-y			+= x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/mmu.c linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -477,7 +477,7 @@ static int host_mapping_level(struct kvm
 
 	addr = gfn_to_hva(kvm, gfn);
 	if (kvm_is_error_hva(addr))
-		return page_size;
+		return PT_PAGE_TABLE_LEVEL;
 
 	down_read(&current->mm->mmap_sem);
 	vma = find_vma(current->mm, addr);
@@ -515,11 +515,9 @@ static int mapping_level(struct kvm_vcpu
 	if (host_level == PT_PAGE_TABLE_LEVEL)
 		return host_level;
 
-	for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) {
-
+	for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
 		if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
 			break;
-	}
 
 	return level - 1;
 }
@@ -2789,7 +2787,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *
 	if (r)
 		goto out;
 
-	er = emulate_instruction(vcpu, vcpu->run, cr2, error_code, 0);
+	er = emulate_instruction(vcpu, cr2, error_code, 0);
 
 	switch (er) {
 	case EMULATE_DONE:
@@ -2800,6 +2798,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *
 	case EMULATE_FAIL:
 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+		vcpu->run->internal.ndata = 0;
 		return 0;
 	default:
 		BUG();
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/paging_tmpl.h linux-libre-2.6.33-gnu1/arch/x86/kvm/paging_tmpl.h
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/paging_tmpl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/paging_tmpl.h	2010-02-24 13:52:17.000000000 -0500
@@ -150,7 +150,9 @@ walk:
 		walker->table_gfn[walker->level - 1] = table_gfn;
 		walker->pte_gpa[walker->level - 1] = pte_gpa;
 
-		kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
+		if (kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)))
+			goto not_present;
+
 		trace_kvm_mmu_paging_element(pte, walker->level);
 
 		if (!is_present_gpte(pte))
@@ -455,8 +457,6 @@ out_unlock:
 static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 {
 	struct kvm_shadow_walk_iterator iterator;
-	pt_element_t gpte;
-	gpa_t pte_gpa = -1;
 	int level;
 	u64 *sptep;
 	int need_flush = 0;
@@ -467,14 +467,9 @@ static void FNAME(invlpg)(struct kvm_vcp
 		level = iterator.level;
 		sptep = iterator.sptep;
 
-		/* FIXME: properly handle invlpg on large guest pages */
 		if (level == PT_PAGE_TABLE_LEVEL  ||
 		    ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) ||
 		    ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) {
-			struct kvm_mmu_page *sp = page_header(__pa(sptep));
-
-			pte_gpa = (sp->gfn << PAGE_SHIFT);
-			pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
 
 			if (is_shadow_present_pte(*sptep)) {
 				rmap_remove(vcpu->kvm, sptep);
@@ -493,18 +488,6 @@ static void FNAME(invlpg)(struct kvm_vcp
 	if (need_flush)
 		kvm_flush_remote_tlbs(vcpu->kvm);
 	spin_unlock(&vcpu->kvm->mmu_lock);
-
-	if (pte_gpa == -1)
-		return;
-	if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
-				  sizeof(pt_element_t)))
-		return;
-	if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) {
-		if (mmu_topup_memory_caches(vcpu))
-			return;
-		kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
-				  sizeof(pt_element_t), 0);
-	}
 }
 
 static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/svm.c linux-libre-2.6.33-gnu1/arch/x86/kvm/svm.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/svm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/svm.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@ MODULE_LICENSE("GPL");
 #define SVM_FEATURE_NPT  (1 << 0)
 #define SVM_FEATURE_LBRV (1 << 1)
 #define SVM_FEATURE_SVML (1 << 2)
+#define SVM_FEATURE_PAUSE_FILTER (1 << 10)
 
 #define NESTED_EXIT_HOST	0	/* Exit handled on host level */
 #define NESTED_EXIT_DONE	1	/* Exit caused nested vmexit  */
@@ -53,15 +54,6 @@ MODULE_LICENSE("GPL");
 
 #define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
 
-/* Turn on to get debugging output*/
-/* #define NESTED_DEBUG */
-
-#ifdef NESTED_DEBUG
-#define nsvm_printk(fmt, args...) printk(KERN_INFO fmt, ## args)
-#else
-#define nsvm_printk(fmt, args...) do {} while(0)
-#endif
-
 static const u32 host_save_user_msrs[] = {
 #ifdef CONFIG_X86_64
 	MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
@@ -85,6 +77,9 @@ struct nested_state {
 	/* gpa pointers to the real vectors */
 	u64 vmcb_msrpm;
 
+	/* A VMEXIT is required but not yet emulated */
+	bool exit_required;
+
 	/* cache for intercepts of the guest */
 	u16 intercept_cr_read;
 	u16 intercept_cr_write;
@@ -112,6 +107,8 @@ struct vcpu_svm {
 	u32 *msrpm;
 
 	struct nested_state nested;
+
+	bool nmi_singlestep;
 };
 
 /* enable NPT for AMD64 and X86 with PAE */
@@ -286,7 +283,7 @@ static void skip_emulated_instruction(st
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	if (!svm->next_rip) {
-		if (emulate_instruction(vcpu, vcpu->run, 0, 0, EMULTYPE_SKIP) !=
+		if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) !=
 				EMULATE_DONE)
 			printk(KERN_DEBUG "%s: NOP\n", __func__);
 		return;
@@ -316,75 +313,79 @@ static void svm_hardware_disable(void *g
 	cpu_svm_disable();
 }
 
-static void svm_hardware_enable(void *garbage)
+static int svm_hardware_enable(void *garbage)
 {
 
-	struct svm_cpu_data *svm_data;
+	struct svm_cpu_data *sd;
 	uint64_t efer;
 	struct descriptor_table gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
+	rdmsrl(MSR_EFER, efer);
+	if (efer & EFER_SVME)
+		return -EBUSY;
+
 	if (!has_svm()) {
-		printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me);
-		return;
+		printk(KERN_ERR "svm_hardware_enable: err EOPNOTSUPP on %d\n",
+		       me);
+		return -EINVAL;
 	}
-	svm_data = per_cpu(svm_data, me);
+	sd = per_cpu(svm_data, me);
 
-	if (!svm_data) {
-		printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n",
+	if (!sd) {
+		printk(KERN_ERR "svm_hardware_enable: svm_data is NULL on %d\n",
 		       me);
-		return;
+		return -EINVAL;
 	}
 
-	svm_data->asid_generation = 1;
-	svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
-	svm_data->next_asid = svm_data->max_asid + 1;
+	sd->asid_generation = 1;
+	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
+	sd->next_asid = sd->max_asid + 1;
 
 	kvm_get_gdt(&gdt_descr);
 	gdt = (struct desc_struct *)gdt_descr.base;
-	svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
+	sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
-	rdmsrl(MSR_EFER, efer);
 	wrmsrl(MSR_EFER, efer | EFER_SVME);
 
-	wrmsrl(MSR_VM_HSAVE_PA,
-	       page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
+	wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT);
+
+	return 0;
 }
 
 static void svm_cpu_uninit(int cpu)
 {
-	struct svm_cpu_data *svm_data
-		= per_cpu(svm_data, raw_smp_processor_id());
+	struct svm_cpu_data *sd = per_cpu(svm_data, raw_smp_processor_id());
 
-	if (!svm_data)
+	if (!sd)
 		return;
 
 	per_cpu(svm_data, raw_smp_processor_id()) = NULL;
-	__free_page(svm_data->save_area);
-	kfree(svm_data);
+	__free_page(sd->save_area);
+	kfree(sd);
 }
 
 static int svm_cpu_init(int cpu)
 {
-	struct svm_cpu_data *svm_data;
+	struct svm_cpu_data *sd;
 	int r;
 
-	svm_data = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
-	if (!svm_data)
+	sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
+	if (!sd)
 		return -ENOMEM;
-	svm_data->cpu = cpu;
-	svm_data->save_area = alloc_page(GFP_KERNEL);
+	sd->cpu = cpu;
+	sd->save_area = alloc_page(GFP_KERNEL);
 	r = -ENOMEM;
-	if (!svm_data->save_area)
+	if (!sd->save_area)
 		goto err_1;
 
-	per_cpu(svm_data, cpu) = svm_data;
+	per_cpu(svm_data, cpu) = sd;
 
 	return 0;
 
 err_1:
-	kfree(svm_data);
+	kfree(sd);
 	return r;
 
 }
@@ -476,7 +477,7 @@ static __init int svm_hardware_setup(voi
 		kvm_enable_efer_bits(EFER_SVME);
 	}
 
-	for_each_online_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		r = svm_cpu_init(cpu);
 		if (r)
 			goto err;
@@ -510,7 +511,7 @@ static __exit void svm_hardware_unsetup(
 {
 	int cpu;
 
-	for_each_online_cpu(cpu)
+	for_each_possible_cpu(cpu)
 		svm_cpu_uninit(cpu);
 
 	__free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER);
@@ -625,11 +626,12 @@ static void init_vmcb(struct vcpu_svm *s
 	save->rip = 0x0000fff0;
 	svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip;
 
-	/*
-	 * cr0 val on cpu init should be 0x60000010, we enable cpu
-	 * cache by default. the orderly way is to enable cache in bios.
+	/* This is the guest-visible cr0 value.
+	 * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0.
 	 */
-	save->cr0 = 0x00000010 | X86_CR0_PG | X86_CR0_WP;
+	svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
+	kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0);
+
 	save->cr4 = X86_CR4_PAE;
 	/* rdx = ?? */
 
@@ -644,8 +646,6 @@ static void init_vmcb(struct vcpu_svm *s
 		control->intercept_cr_write &= ~(INTERCEPT_CR0_MASK|
 						 INTERCEPT_CR3_MASK);
 		save->g_pat = 0x0007040600070406ULL;
-		/* enable caching because the QEMU Bios doesn't enable it */
-		save->cr0 = X86_CR0_ET;
 		save->cr3 = 0;
 		save->cr4 = 0;
 	}
@@ -654,6 +654,11 @@ static void init_vmcb(struct vcpu_svm *s
 	svm->nested.vmcb = 0;
 	svm->vcpu.arch.hflags = 0;
 
+	if (svm_has(SVM_FEATURE_PAUSE_FILTER)) {
+		control->pause_filter_count = 3000;
+		control->intercept |= (1ULL << INTERCEPT_PAUSE);
+	}
+
 	enable_gif(svm);
 }
 
@@ -758,14 +763,13 @@ static void svm_vcpu_load(struct kvm_vcp
 	int i;
 
 	if (unlikely(cpu != vcpu->cpu)) {
-		u64 tsc_this, delta;
+		u64 delta;
 
 		/*
 		 * Make sure that the guest sees a monotonically
 		 * increasing TSC.
 		 */
-		rdtscll(tsc_this);
-		delta = vcpu->arch.host_tsc - tsc_this;
+		delta = vcpu->arch.host_tsc - native_read_tsc();
 		svm->vmcb->control.tsc_offset += delta;
 		if (is_nested(svm))
 			svm->nested.hsave->control.tsc_offset += delta;
@@ -787,7 +791,7 @@ static void svm_vcpu_put(struct kvm_vcpu
 	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
 		wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
 
-	rdtscll(vcpu->arch.host_tsc);
+	vcpu->arch.host_tsc = native_read_tsc();
 }
 
 static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu)
@@ -1045,7 +1049,7 @@ static void update_db_intercept(struct k
 	svm->vmcb->control.intercept_exceptions &=
 		~((1 << DB_VECTOR) | (1 << BP_VECTOR));
 
-	if (vcpu->arch.singlestep)
+	if (svm->nmi_singlestep)
 		svm->vmcb->control.intercept_exceptions |= (1 << DB_VECTOR);
 
 	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
@@ -1060,26 +1064,16 @@ static void update_db_intercept(struct k
 		vcpu->guest_debug = 0;
 }
 
-static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
+static void svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
 {
-	int old_debug = vcpu->guest_debug;
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	vcpu->guest_debug = dbg->control;
-
-	update_db_intercept(vcpu);
-
 	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
 		svm->vmcb->save.dr7 = dbg->arch.debugreg[7];
 	else
 		svm->vmcb->save.dr7 = vcpu->arch.dr7;
 
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		svm->vmcb->save.rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
-	else if (old_debug & KVM_GUESTDBG_SINGLESTEP)
-		svm->vmcb->save.rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
-
-	return 0;
+	update_db_intercept(vcpu);
 }
 
 static void load_host_msrs(struct kvm_vcpu *vcpu)
@@ -1096,16 +1090,16 @@ static void save_host_msrs(struct kvm_vc
 #endif
 }
 
-static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data)
+static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
 {
-	if (svm_data->next_asid > svm_data->max_asid) {
-		++svm_data->asid_generation;
-		svm_data->next_asid = 1;
+	if (sd->next_asid > sd->max_asid) {
+		++sd->asid_generation;
+		sd->next_asid = 1;
 		svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
 	}
 
-	svm->asid_generation = svm_data->asid_generation;
-	svm->vmcb->control.asid = svm_data->next_asid++;
+	svm->asid_generation = sd->asid_generation;
+	svm->vmcb->control.asid = sd->next_asid++;
 }
 
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
@@ -1180,7 +1174,7 @@ static void svm_set_dr(struct kvm_vcpu *
 	}
 }
 
-static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int pf_interception(struct vcpu_svm *svm)
 {
 	u64 fault_address;
 	u32 error_code;
@@ -1194,17 +1188,19 @@ static int pf_interception(struct vcpu_s
 	return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
 }
 
-static int db_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int db_interception(struct vcpu_svm *svm)
 {
+	struct kvm_run *kvm_run = svm->vcpu.run;
+
 	if (!(svm->vcpu.guest_debug &
 	      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) &&
-		!svm->vcpu.arch.singlestep) {
+		!svm->nmi_singlestep) {
 		kvm_queue_exception(&svm->vcpu, DB_VECTOR);
 		return 1;
 	}
 
-	if (svm->vcpu.arch.singlestep) {
-		svm->vcpu.arch.singlestep = false;
+	if (svm->nmi_singlestep) {
+		svm->nmi_singlestep = false;
 		if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
 			svm->vmcb->save.rflags &=
 				~(X86_EFLAGS_TF | X86_EFLAGS_RF);
@@ -1223,25 +1219,27 @@ static int db_interception(struct vcpu_s
 	return 1;
 }
 
-static int bp_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int bp_interception(struct vcpu_svm *svm)
 {
+	struct kvm_run *kvm_run = svm->vcpu.run;
+
 	kvm_run->exit_reason = KVM_EXIT_DEBUG;
 	kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip;
 	kvm_run->debug.arch.exception = BP_VECTOR;
 	return 0;
 }
 
-static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int ud_interception(struct vcpu_svm *svm)
 {
 	int er;
 
-	er = emulate_instruction(&svm->vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD);
+	er = emulate_instruction(&svm->vcpu, 0, 0, EMULTYPE_TRAP_UD);
 	if (er != EMULATE_DONE)
 		kvm_queue_exception(&svm->vcpu, UD_VECTOR);
 	return 1;
 }
 
-static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int nm_interception(struct vcpu_svm *svm)
 {
 	svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
 	if (!(svm->vcpu.arch.cr0 & X86_CR0_TS))
@@ -1251,7 +1249,7 @@ static int nm_interception(struct vcpu_s
 	return 1;
 }
 
-static int mc_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int mc_interception(struct vcpu_svm *svm)
 {
 	/*
 	 * On an #MC intercept the MCE handler is not called automatically in
@@ -1264,8 +1262,10 @@ static int mc_interception(struct vcpu_s
 	return 1;
 }
 
-static int shutdown_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int shutdown_interception(struct vcpu_svm *svm)
 {
+	struct kvm_run *kvm_run = svm->vcpu.run;
+
 	/*
 	 * VMCB is undefined after a SHUTDOWN intercept
 	 * so reinitialize it.
@@ -1277,7 +1277,7 @@ static int shutdown_interception(struct
 	return 0;
 }
 
-static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int io_interception(struct vcpu_svm *svm)
 {
 	u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */
 	int size, in, string;
@@ -1291,7 +1291,7 @@ static int io_interception(struct vcpu_s
 
 	if (string) {
 		if (emulate_instruction(&svm->vcpu,
-					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
+					0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
@@ -1301,33 +1301,33 @@ static int io_interception(struct vcpu_s
 	size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
 
 	skip_emulated_instruction(&svm->vcpu);
-	return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
+	return kvm_emulate_pio(&svm->vcpu, in, size, port);
 }
 
-static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int nmi_interception(struct vcpu_svm *svm)
 {
 	return 1;
 }
 
-static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int intr_interception(struct vcpu_svm *svm)
 {
 	++svm->vcpu.stat.irq_exits;
 	return 1;
 }
 
-static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int nop_on_interception(struct vcpu_svm *svm)
 {
 	return 1;
 }
 
-static int halt_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int halt_interception(struct vcpu_svm *svm)
 {
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 1;
 	skip_emulated_instruction(&svm->vcpu);
 	return kvm_emulate_halt(&svm->vcpu);
 }
 
-static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int vmmcall_interception(struct vcpu_svm *svm)
 {
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
@@ -1378,8 +1378,15 @@ static inline int nested_svm_intr(struct
 
 	svm->vmcb->control.exit_code = SVM_EXIT_INTR;
 
-	if (nested_svm_exit_handled(svm)) {
-		nsvm_printk("VMexit -> INTR\n");
+	if (svm->nested.intercept & 1ULL) {
+		/*
+		 * The #vmexit can't be emulated here directly because this
+		 * code path runs with irqs and preemtion disabled. A
+		 * #vmexit emulation might sleep. Only signal request for
+		 * the #vmexit here.
+		 */
+		svm->nested.exit_required = true;
+		trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
 		return 1;
 	}
 
@@ -1390,10 +1397,7 @@ static void *nested_svm_map(struct vcpu_
 {
 	struct page *page;
 
-	down_read(&current->mm->mmap_sem);
 	page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
-	up_read(&current->mm->mmap_sem);
-
 	if (is_error_page(page))
 		goto error;
 
@@ -1532,14 +1536,12 @@ static int nested_svm_exit_handled(struc
 	}
 	default: {
 		u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
-		nsvm_printk("exit code: 0x%x\n", exit_code);
 		if (svm->nested.intercept & exit_bits)
 			vmexit = NESTED_EXIT_DONE;
 	}
 	}
 
 	if (vmexit == NESTED_EXIT_DONE) {
-		nsvm_printk("#VMEXIT reason=%04x\n", exit_code);
 		nested_svm_vmexit(svm);
 	}
 
@@ -1584,6 +1586,12 @@ static int nested_svm_vmexit(struct vcpu
 	struct vmcb *hsave = svm->nested.hsave;
 	struct vmcb *vmcb = svm->vmcb;
 
+	trace_kvm_nested_vmexit_inject(vmcb->control.exit_code,
+				       vmcb->control.exit_info_1,
+				       vmcb->control.exit_info_2,
+				       vmcb->control.exit_int_info,
+				       vmcb->control.exit_int_info_err);
+
 	nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0);
 	if (!nested_vmcb)
 		return 1;
@@ -1617,6 +1625,22 @@ static int nested_svm_vmexit(struct vcpu
 	nested_vmcb->control.exit_info_2       = vmcb->control.exit_info_2;
 	nested_vmcb->control.exit_int_info     = vmcb->control.exit_int_info;
 	nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err;
+
+	/*
+	 * If we emulate a VMRUN/#VMEXIT in the same host #vmexit cycle we have
+	 * to make sure that we do not lose injected events. So check event_inj
+	 * here and copy it to exit_int_info if it is valid.
+	 * Exit_int_info and event_inj can't be both valid because the case
+	 * below only happens on a VMRUN instruction intercept which has
+	 * no valid exit_int_info set.
+	 */
+	if (vmcb->control.event_inj & SVM_EVTINJ_VALID) {
+		struct vmcb_control_area *nc = &nested_vmcb->control;
+
+		nc->exit_int_info     = vmcb->control.event_inj;
+		nc->exit_int_info_err = vmcb->control.event_inj_err;
+	}
+
 	nested_vmcb->control.tlb_ctl           = 0;
 	nested_vmcb->control.event_inj         = 0;
 	nested_vmcb->control.event_inj_err     = 0;
@@ -1628,10 +1652,6 @@ static int nested_svm_vmexit(struct vcpu
 	/* Restore the original control entries */
 	copy_vmcb_control_area(vmcb, hsave);
 
-	/* Kill any pending exceptions */
-	if (svm->vcpu.arch.exception.pending == true)
-		nsvm_printk("WARNING: Pending Exception\n");
-
 	kvm_clear_exception_queue(&svm->vcpu);
 	kvm_clear_interrupt_queue(&svm->vcpu);
 
@@ -1702,6 +1722,12 @@ static bool nested_svm_vmrun(struct vcpu
 	/* nested_vmcb is our indicator if nested SVM is activated */
 	svm->nested.vmcb = svm->vmcb->save.rax;
 
+	trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb,
+			       nested_vmcb->save.rip,
+			       nested_vmcb->control.int_ctl,
+			       nested_vmcb->control.event_inj,
+			       nested_vmcb->control.nested_ctl);
+
 	/* Clear internal status */
 	kvm_clear_exception_queue(&svm->vcpu);
 	kvm_clear_interrupt_queue(&svm->vcpu);
@@ -1789,28 +1815,15 @@ static bool nested_svm_vmrun(struct vcpu
 	svm->nested.intercept            = nested_vmcb->control.intercept;
 
 	force_new_asid(&svm->vcpu);
-	svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info;
-	svm->vmcb->control.exit_int_info_err = nested_vmcb->control.exit_int_info_err;
 	svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | V_INTR_MASKING_MASK;
-	if (nested_vmcb->control.int_ctl & V_IRQ_MASK) {
-		nsvm_printk("nSVM Injecting Interrupt: 0x%x\n",
-				nested_vmcb->control.int_ctl);
-	}
 	if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK)
 		svm->vcpu.arch.hflags |= HF_VINTR_MASK;
 	else
 		svm->vcpu.arch.hflags &= ~HF_VINTR_MASK;
 
-	nsvm_printk("nSVM exit_int_info: 0x%x | int_state: 0x%x\n",
-			nested_vmcb->control.exit_int_info,
-			nested_vmcb->control.int_state);
-
 	svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
 	svm->vmcb->control.int_state = nested_vmcb->control.int_state;
 	svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
-	if (nested_vmcb->control.event_inj & SVM_EVTINJ_VALID)
-		nsvm_printk("Injecting Event: 0x%x\n",
-				nested_vmcb->control.event_inj);
 	svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
 	svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
 
@@ -1837,7 +1850,7 @@ static void nested_svm_vmloadsave(struct
 	to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip;
 }
 
-static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int vmload_interception(struct vcpu_svm *svm)
 {
 	struct vmcb *nested_vmcb;
 
@@ -1857,7 +1870,7 @@ static int vmload_interception(struct vc
 	return 1;
 }
 
-static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int vmsave_interception(struct vcpu_svm *svm)
 {
 	struct vmcb *nested_vmcb;
 
@@ -1877,10 +1890,8 @@ static int vmsave_interception(struct vc
 	return 1;
 }
 
-static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int vmrun_interception(struct vcpu_svm *svm)
 {
-	nsvm_printk("VMrun\n");
-
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
@@ -1907,7 +1918,7 @@ failed:
 	return 1;
 }
 
-static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int stgi_interception(struct vcpu_svm *svm)
 {
 	if (nested_svm_check_permissions(svm))
 		return 1;
@@ -1920,7 +1931,7 @@ static int stgi_interception(struct vcpu
 	return 1;
 }
 
-static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int clgi_interception(struct vcpu_svm *svm)
 {
 	if (nested_svm_check_permissions(svm))
 		return 1;
@@ -1937,10 +1948,12 @@ static int clgi_interception(struct vcpu
 	return 1;
 }
 
-static int invlpga_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int invlpga_interception(struct vcpu_svm *svm)
 {
 	struct kvm_vcpu *vcpu = &svm->vcpu;
-	nsvm_printk("INVLPGA\n");
+
+	trace_kvm_invlpga(svm->vmcb->save.rip, vcpu->arch.regs[VCPU_REGS_RCX],
+			  vcpu->arch.regs[VCPU_REGS_RAX]);
 
 	/* Let's treat INVLPGA the same as INVLPG (can be optimized!) */
 	kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]);
@@ -1950,15 +1963,21 @@ static int invlpga_interception(struct v
 	return 1;
 }
 
-static int invalid_op_interception(struct vcpu_svm *svm,
-				   struct kvm_run *kvm_run)
+static int skinit_interception(struct vcpu_svm *svm)
 {
+	trace_kvm_skinit(svm->vmcb->save.rip, svm->vcpu.arch.regs[VCPU_REGS_RAX]);
+
 	kvm_queue_exception(&svm->vcpu, UD_VECTOR);
 	return 1;
 }
 
-static int task_switch_interception(struct vcpu_svm *svm,
-				    struct kvm_run *kvm_run)
+static int invalid_op_interception(struct vcpu_svm *svm)
+{
+	kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+	return 1;
+}
+
+static int task_switch_interception(struct vcpu_svm *svm)
 {
 	u16 tss_selector;
 	int reason;
@@ -2008,14 +2027,14 @@ static int task_switch_interception(stru
 	return kvm_task_switch(&svm->vcpu, tss_selector, reason);
 }
 
-static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int cpuid_interception(struct vcpu_svm *svm)
 {
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
 	kvm_emulate_cpuid(&svm->vcpu);
 	return 1;
 }
 
-static int iret_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int iret_interception(struct vcpu_svm *svm)
 {
 	++svm->vcpu.stat.nmi_window_exits;
 	svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
@@ -2023,26 +2042,27 @@ static int iret_interception(struct vcpu
 	return 1;
 }
 
-static int invlpg_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int invlpg_interception(struct vcpu_svm *svm)
 {
-	if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0, 0) != EMULATE_DONE)
+	if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE)
 		pr_unimpl(&svm->vcpu, "%s: failed\n", __func__);
 	return 1;
 }
 
-static int emulate_on_interception(struct vcpu_svm *svm,
-				   struct kvm_run *kvm_run)
+static int emulate_on_interception(struct vcpu_svm *svm)
 {
-	if (emulate_instruction(&svm->vcpu, NULL, 0, 0, 0) != EMULATE_DONE)
+	if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE)
 		pr_unimpl(&svm->vcpu, "%s: failed\n", __func__);
 	return 1;
 }
 
-static int cr8_write_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int cr8_write_interception(struct vcpu_svm *svm)
 {
+	struct kvm_run *kvm_run = svm->vcpu.run;
+
 	u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
 	/* instruction emulation calls kvm_set_cr8() */
-	emulate_instruction(&svm->vcpu, NULL, 0, 0, 0);
+	emulate_instruction(&svm->vcpu, 0, 0, 0);
 	if (irqchip_in_kernel(svm->vcpu.kvm)) {
 		svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
 		return 1;
@@ -2128,7 +2148,7 @@ static int svm_get_msr(struct kvm_vcpu *
 	return 0;
 }
 
-static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int rdmsr_interception(struct vcpu_svm *svm)
 {
 	u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
 	u64 data;
@@ -2221,7 +2241,7 @@ static int svm_set_msr(struct kvm_vcpu *
 	return 0;
 }
 
-static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int wrmsr_interception(struct vcpu_svm *svm)
 {
 	u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
 	u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
@@ -2237,17 +2257,18 @@ static int wrmsr_interception(struct vcp
 	return 1;
 }
 
-static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+static int msr_interception(struct vcpu_svm *svm)
 {
 	if (svm->vmcb->control.exit_info_1)
-		return wrmsr_interception(svm, kvm_run);
+		return wrmsr_interception(svm);
 	else
-		return rdmsr_interception(svm, kvm_run);
+		return rdmsr_interception(svm);
 }
 
-static int interrupt_window_interception(struct vcpu_svm *svm,
-				   struct kvm_run *kvm_run)
+static int interrupt_window_interception(struct vcpu_svm *svm)
 {
+	struct kvm_run *kvm_run = svm->vcpu.run;
+
 	svm_clear_vintr(svm);
 	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
 	/*
@@ -2265,8 +2286,13 @@ static int interrupt_window_interception
 	return 1;
 }
 
-static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
-				      struct kvm_run *kvm_run) = {
+static int pause_interception(struct vcpu_svm *svm)
+{
+	kvm_vcpu_on_spin(&(svm->vcpu));
+	return 1;
+}
+
+static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
 	[SVM_EXIT_READ_CR0]           		= emulate_on_interception,
 	[SVM_EXIT_READ_CR3]           		= emulate_on_interception,
 	[SVM_EXIT_READ_CR4]           		= emulate_on_interception,
@@ -2301,6 +2327,7 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_CPUID]			= cpuid_interception,
 	[SVM_EXIT_IRET]                         = iret_interception,
 	[SVM_EXIT_INVD]                         = emulate_on_interception,
+	[SVM_EXIT_PAUSE]			= pause_interception,
 	[SVM_EXIT_HLT]				= halt_interception,
 	[SVM_EXIT_INVLPG]			= invlpg_interception,
 	[SVM_EXIT_INVLPGA]			= invlpga_interception,
@@ -2314,26 +2341,36 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_VMSAVE]			= vmsave_interception,
 	[SVM_EXIT_STGI]				= stgi_interception,
 	[SVM_EXIT_CLGI]				= clgi_interception,
-	[SVM_EXIT_SKINIT]			= invalid_op_interception,
+	[SVM_EXIT_SKINIT]			= skinit_interception,
 	[SVM_EXIT_WBINVD]                       = emulate_on_interception,
 	[SVM_EXIT_MONITOR]			= invalid_op_interception,
 	[SVM_EXIT_MWAIT]			= invalid_op_interception,
 	[SVM_EXIT_NPF]				= pf_interception,
 };
 
-static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+static int handle_exit(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
+	struct kvm_run *kvm_run = vcpu->run;
 	u32 exit_code = svm->vmcb->control.exit_code;
 
 	trace_kvm_exit(exit_code, svm->vmcb->save.rip);
 
+	if (unlikely(svm->nested.exit_required)) {
+		nested_svm_vmexit(svm);
+		svm->nested.exit_required = false;
+
+		return 1;
+	}
+
 	if (is_nested(svm)) {
 		int vmexit;
 
-		nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
-			    exit_code, svm->vmcb->control.exit_info_1,
-			    svm->vmcb->control.exit_info_2, svm->vmcb->save.rip);
+		trace_kvm_nested_vmexit(svm->vmcb->save.rip, exit_code,
+					svm->vmcb->control.exit_info_1,
+					svm->vmcb->control.exit_info_2,
+					svm->vmcb->control.exit_int_info,
+					svm->vmcb->control.exit_int_info_err);
 
 		vmexit = nested_svm_exit_special(svm);
 
@@ -2383,15 +2420,15 @@ static int handle_exit(struct kvm_run *k
 		return 0;
 	}
 
-	return svm_exit_handlers[exit_code](svm, kvm_run);
+	return svm_exit_handlers[exit_code](svm);
 }
 
 static void reload_tss(struct kvm_vcpu *vcpu)
 {
 	int cpu = raw_smp_processor_id();
 
-	struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
-	svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
+	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
+	sd->tss_desc->type = 9; /* available 32/64-bit TSS */
 	load_TR_desc();
 }
 
@@ -2399,12 +2436,12 @@ static void pre_svm_run(struct vcpu_svm
 {
 	int cpu = raw_smp_processor_id();
 
-	struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
+	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
 
 	svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
 	/* FIXME: handle wraparound of asid_generation */
-	if (svm->asid_generation != svm_data->asid_generation)
-		new_asid(svm, svm_data);
+	if (svm->asid_generation != sd->asid_generation)
+		new_asid(svm, sd);
 }
 
 static void svm_inject_nmi(struct kvm_vcpu *vcpu)
@@ -2460,20 +2497,47 @@ static int svm_nmi_allowed(struct kvm_vc
 		!(svm->vcpu.arch.hflags & HF_NMI_MASK);
 }
 
+static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	return !!(svm->vcpu.arch.hflags & HF_NMI_MASK);
+}
+
+static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	if (masked) {
+		svm->vcpu.arch.hflags |= HF_NMI_MASK;
+		svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+	} else {
+		svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
+		svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+	}
+}
+
 static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct vmcb *vmcb = svm->vmcb;
-	return (vmcb->save.rflags & X86_EFLAGS_IF) &&
-		!(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-		gif_set(svm) &&
-		!(is_nested(svm) && (svm->vcpu.arch.hflags & HF_VINTR_MASK));
+	int ret;
+
+	if (!gif_set(svm) ||
+	     (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK))
+		return 0;
+
+	ret = !!(vmcb->save.rflags & X86_EFLAGS_IF);
+
+	if (is_nested(svm))
+		return ret && !(svm->vcpu.arch.hflags & HF_VINTR_MASK);
+
+	return ret;
 }
 
 static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
-	nsvm_printk("Trying to open IRQ window\n");
 
 	nested_svm_intr(svm);
 
@@ -2498,7 +2562,7 @@ static void enable_nmi_window(struct kvm
 	/* Something prevents NMI from been injected. Single step over
 	   possible problem (IRET or exception injection or interrupt
 	   shadow) */
-	vcpu->arch.singlestep = true;
+	svm->nmi_singlestep = true;
 	svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 	update_db_intercept(vcpu);
 }
@@ -2588,13 +2652,20 @@ static void svm_complete_interrupts(stru
 #define R "e"
 #endif
 
-static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	u16 fs_selector;
 	u16 gs_selector;
 	u16 ldt_selector;
 
+	/*
+	 * A vmexit emulation is required before the vcpu can be executed
+	 * again.
+	 */
+	if (unlikely(svm->nested.exit_required))
+		return;
+
 	svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
 	svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
 	svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP];
@@ -2893,6 +2964,8 @@ static struct kvm_x86_ops svm_x86_ops =
 	.queue_exception = svm_queue_exception,
 	.interrupt_allowed = svm_interrupt_allowed,
 	.nmi_allowed = svm_nmi_allowed,
+	.get_nmi_mask = svm_get_nmi_mask,
+	.set_nmi_mask = svm_set_nmi_mask,
 	.enable_nmi_window = enable_nmi_window,
 	.enable_irq_window = enable_irq_window,
 	.update_cr8_intercept = update_cr8_intercept,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/trace.h linux-libre-2.6.33-gnu1/arch/x86/kvm/trace.h
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/trace.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/trace.h	2010-02-24 13:52:17.000000000 -0500
@@ -349,6 +349,171 @@ TRACE_EVENT(kvm_apic_accept_irq,
 		  __entry->coalesced ? " (coalesced)" : "")
 );
 
+/*
+ * Tracepoint for nested VMRUN
+ */
+TRACE_EVENT(kvm_nested_vmrun,
+	    TP_PROTO(__u64 rip, __u64 vmcb, __u64 nested_rip, __u32 int_ctl,
+		     __u32 event_inj, bool npt),
+	    TP_ARGS(rip, vmcb, nested_rip, int_ctl, event_inj, npt),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		rip		)
+		__field(	__u64,		vmcb		)
+		__field(	__u64,		nested_rip	)
+		__field(	__u32,		int_ctl		)
+		__field(	__u32,		event_inj	)
+		__field(	bool,		npt		)
+	),
+
+	TP_fast_assign(
+		__entry->rip		= rip;
+		__entry->vmcb		= vmcb;
+		__entry->nested_rip	= nested_rip;
+		__entry->int_ctl	= int_ctl;
+		__entry->event_inj	= event_inj;
+		__entry->npt		= npt;
+	),
+
+	TP_printk("rip: 0x%016llx vmcb: 0x%016llx nrip: 0x%016llx int_ctl: 0x%08x "
+		  "event_inj: 0x%08x npt: %s\n",
+		__entry->rip, __entry->vmcb, __entry->nested_rip,
+		__entry->int_ctl, __entry->event_inj,
+		__entry->npt ? "on" : "off")
+);
+
+/*
+ * Tracepoint for #VMEXIT while nested
+ */
+TRACE_EVENT(kvm_nested_vmexit,
+	    TP_PROTO(__u64 rip, __u32 exit_code,
+		     __u64 exit_info1, __u64 exit_info2,
+		     __u32 exit_int_info, __u32 exit_int_info_err),
+	    TP_ARGS(rip, exit_code, exit_info1, exit_info2,
+		    exit_int_info, exit_int_info_err),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		rip			)
+		__field(	__u32,		exit_code		)
+		__field(	__u64,		exit_info1		)
+		__field(	__u64,		exit_info2		)
+		__field(	__u32,		exit_int_info		)
+		__field(	__u32,		exit_int_info_err	)
+	),
+
+	TP_fast_assign(
+		__entry->rip			= rip;
+		__entry->exit_code		= exit_code;
+		__entry->exit_info1		= exit_info1;
+		__entry->exit_info2		= exit_info2;
+		__entry->exit_int_info		= exit_int_info;
+		__entry->exit_int_info_err	= exit_int_info_err;
+	),
+	TP_printk("rip: 0x%016llx reason: %s ext_inf1: 0x%016llx "
+		  "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n",
+		  __entry->rip,
+		  ftrace_print_symbols_seq(p, __entry->exit_code,
+					   kvm_x86_ops->exit_reasons_str),
+		  __entry->exit_info1, __entry->exit_info2,
+		  __entry->exit_int_info, __entry->exit_int_info_err)
+);
+
+/*
+ * Tracepoint for #VMEXIT reinjected to the guest
+ */
+TRACE_EVENT(kvm_nested_vmexit_inject,
+	    TP_PROTO(__u32 exit_code,
+		     __u64 exit_info1, __u64 exit_info2,
+		     __u32 exit_int_info, __u32 exit_int_info_err),
+	    TP_ARGS(exit_code, exit_info1, exit_info2,
+		    exit_int_info, exit_int_info_err),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		exit_code		)
+		__field(	__u64,		exit_info1		)
+		__field(	__u64,		exit_info2		)
+		__field(	__u32,		exit_int_info		)
+		__field(	__u32,		exit_int_info_err	)
+	),
+
+	TP_fast_assign(
+		__entry->exit_code		= exit_code;
+		__entry->exit_info1		= exit_info1;
+		__entry->exit_info2		= exit_info2;
+		__entry->exit_int_info		= exit_int_info;
+		__entry->exit_int_info_err	= exit_int_info_err;
+	),
+
+	TP_printk("reason: %s ext_inf1: 0x%016llx "
+		  "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n",
+		  ftrace_print_symbols_seq(p, __entry->exit_code,
+					   kvm_x86_ops->exit_reasons_str),
+		__entry->exit_info1, __entry->exit_info2,
+		__entry->exit_int_info, __entry->exit_int_info_err)
+);
+
+/*
+ * Tracepoint for nested #vmexit because of interrupt pending
+ */
+TRACE_EVENT(kvm_nested_intr_vmexit,
+	    TP_PROTO(__u64 rip),
+	    TP_ARGS(rip),
+
+	TP_STRUCT__entry(
+		__field(	__u64,	rip	)
+	),
+
+	TP_fast_assign(
+		__entry->rip	=	rip
+	),
+
+	TP_printk("rip: 0x%016llx\n", __entry->rip)
+);
+
+/*
+ * Tracepoint for nested #vmexit because of interrupt pending
+ */
+TRACE_EVENT(kvm_invlpga,
+	    TP_PROTO(__u64 rip, int asid, u64 address),
+	    TP_ARGS(rip, asid, address),
+
+	TP_STRUCT__entry(
+		__field(	__u64,	rip	)
+		__field(	int,	asid	)
+		__field(	__u64,	address	)
+	),
+
+	TP_fast_assign(
+		__entry->rip		=	rip;
+		__entry->asid		=	asid;
+		__entry->address	=	address;
+	),
+
+	TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx\n",
+		  __entry->rip, __entry->asid, __entry->address)
+);
+
+/*
+ * Tracepoint for nested #vmexit because of interrupt pending
+ */
+TRACE_EVENT(kvm_skinit,
+	    TP_PROTO(__u64 rip, __u32 slb),
+	    TP_ARGS(rip, slb),
+
+	TP_STRUCT__entry(
+		__field(	__u64,	rip	)
+		__field(	__u32,	slb	)
+	),
+
+	TP_fast_assign(
+		__entry->rip		=	rip;
+		__entry->slb		=	slb;
+	),
+
+	TP_printk("rip: 0x%016llx slb: 0x%08x\n",
+		  __entry->rip, __entry->slb)
+);
+
 #endif /* _TRACE_KVM_H */
 
 /* This part must be outside protection */
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/vmx.c linux-libre-2.6.33-gnu1/arch/x86/kvm/vmx.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/vmx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/vmx.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,12 +61,37 @@ module_param_named(unrestricted_guest,
 static int __read_mostly emulate_invalid_guest_state = 0;
 module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 
+/*
+ * These 2 parameters are used to config the controls for Pause-Loop Exiting:
+ * ple_gap:    upper bound on the amount of time between two successive
+ *             executions of PAUSE in a loop. Also indicate if ple enabled.
+ *             According to test, this time is usually small than 41 cycles.
+ * ple_window: upper bound on the amount of time a guest is allowed to execute
+ *             in a PAUSE loop. Tests indicate that most spinlocks are held for
+ *             less than 2^12 cycles
+ * Time is measured based on a counter that runs at the same rate as the TSC,
+ * refer SDM volume 3b section 21.6.13 & 22.1.3.
+ */
+#define KVM_VMX_DEFAULT_PLE_GAP    41
+#define KVM_VMX_DEFAULT_PLE_WINDOW 4096
+static int ple_gap = KVM_VMX_DEFAULT_PLE_GAP;
+module_param(ple_gap, int, S_IRUGO);
+
+static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
+module_param(ple_window, int, S_IRUGO);
+
 struct vmcs {
 	u32 revision_id;
 	u32 abort;
 	char data[0];
 };
 
+struct shared_msr_entry {
+	unsigned index;
+	u64 data;
+	u64 mask;
+};
+
 struct vcpu_vmx {
 	struct kvm_vcpu       vcpu;
 	struct list_head      local_vcpus_link;
@@ -74,13 +99,12 @@ struct vcpu_vmx {
 	int                   launched;
 	u8                    fail;
 	u32                   idt_vectoring_info;
-	struct kvm_msr_entry *guest_msrs;
-	struct kvm_msr_entry *host_msrs;
+	struct shared_msr_entry *guest_msrs;
 	int                   nmsrs;
 	int                   save_nmsrs;
-	int                   msr_offset_efer;
 #ifdef CONFIG_X86_64
-	int                   msr_offset_kernel_gs_base;
+	u64 		      msr_host_kernel_gs_base;
+	u64 		      msr_guest_kernel_gs_base;
 #endif
 	struct vmcs          *vmcs;
 	struct {
@@ -88,7 +112,6 @@ struct vcpu_vmx {
 		u16           fs_sel, gs_sel, ldt_sel;
 		int           gs_ldt_reload_needed;
 		int           fs_reload_needed;
-		int           guest_efer_loaded;
 	} host_state;
 	struct {
 		int vm86_active;
@@ -107,7 +130,6 @@ struct vcpu_vmx {
 	} rmode;
 	int vpid;
 	bool emulation_required;
-	enum emulation_result invalid_state_emulation_result;
 
 	/* Support for vnmi-less CPUs */
 	int soft_vnmi_blocked;
@@ -176,6 +198,8 @@ static struct kvm_vmx_segment_field {
 	VMX_SEGMENT_FIELD(LDTR),
 };
 
+static u64 host_efer;
+
 static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
 
 /*
@@ -184,28 +208,12 @@ static void ept_save_pdptrs(struct kvm_v
  */
 static const u32 vmx_msr_index[] = {
 #ifdef CONFIG_X86_64
-	MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
+	MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
 #endif
 	MSR_EFER, MSR_K6_STAR,
 };
 #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
 
-static void load_msrs(struct kvm_msr_entry *e, int n)
-{
-	int i;
-
-	for (i = 0; i < n; ++i)
-		wrmsrl(e[i].index, e[i].data);
-}
-
-static void save_msrs(struct kvm_msr_entry *e, int n)
-{
-	int i;
-
-	for (i = 0; i < n; ++i)
-		rdmsrl(e[i].index, e[i].data);
-}
-
 static inline int is_page_fault(u32 intr_info)
 {
 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
@@ -320,6 +328,12 @@ static inline int cpu_has_vmx_unrestrict
 		SECONDARY_EXEC_UNRESTRICTED_GUEST;
 }
 
+static inline int cpu_has_vmx_ple(void)
+{
+	return vmcs_config.cpu_based_2nd_exec_ctrl &
+		SECONDARY_EXEC_PAUSE_LOOP_EXITING;
+}
+
 static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
 {
 	return flexpriority_enabled &&
@@ -348,7 +362,7 @@ static int __find_msr_index(struct vcpu_
 	int i;
 
 	for (i = 0; i < vmx->nmsrs; ++i)
-		if (vmx->guest_msrs[i].index == msr)
+		if (vmx_msr_index[vmx->guest_msrs[i].index] == msr)
 			return i;
 	return -1;
 }
@@ -379,7 +393,7 @@ static inline void __invept(int ext, u64
 			: : "a" (&operand), "c" (ext) : "cc", "memory");
 }
 
-static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
+static struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
 {
 	int i;
 
@@ -570,17 +584,12 @@ static void reload_tss(void)
 	load_TR_desc();
 }
 
-static void load_transition_efer(struct vcpu_vmx *vmx)
+static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
 {
-	int efer_offset = vmx->msr_offset_efer;
-	u64 host_efer;
 	u64 guest_efer;
 	u64 ignore_bits;
 
-	if (efer_offset < 0)
-		return;
-	host_efer = vmx->host_msrs[efer_offset].data;
-	guest_efer = vmx->guest_msrs[efer_offset].data;
+	guest_efer = vmx->vcpu.arch.shadow_efer;
 
 	/*
 	 * NX is emulated; LMA and LME handled by hardware; SCE meaninless
@@ -593,27 +602,17 @@ static void load_transition_efer(struct
 	if (guest_efer & EFER_LMA)
 		ignore_bits &= ~(u64)EFER_SCE;
 #endif
-	if ((guest_efer & ~ignore_bits) == (host_efer & ~ignore_bits))
-		return;
-
-	vmx->host_state.guest_efer_loaded = 1;
 	guest_efer &= ~ignore_bits;
 	guest_efer |= host_efer & ignore_bits;
-	wrmsrl(MSR_EFER, guest_efer);
-	vmx->vcpu.stat.efer_reload++;
-}
-
-static void reload_host_efer(struct vcpu_vmx *vmx)
-{
-	if (vmx->host_state.guest_efer_loaded) {
-		vmx->host_state.guest_efer_loaded = 0;
-		load_msrs(vmx->host_msrs + vmx->msr_offset_efer, 1);
-	}
+	vmx->guest_msrs[efer_offset].data = guest_efer;
+	vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
+	return true;
 }
 
 static void vmx_save_host_state(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	int i;
 
 	if (vmx->host_state.loaded)
 		return;
@@ -650,13 +649,15 @@ static void vmx_save_host_state(struct k
 #endif
 
 #ifdef CONFIG_X86_64
-	if (is_long_mode(&vmx->vcpu))
-		save_msrs(vmx->host_msrs +
-			  vmx->msr_offset_kernel_gs_base, 1);
-
+	if (is_long_mode(&vmx->vcpu)) {
+		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+		wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+	}
 #endif
-	load_msrs(vmx->guest_msrs, vmx->save_nmsrs);
-	load_transition_efer(vmx);
+	for (i = 0; i < vmx->save_nmsrs; ++i)
+		kvm_set_shared_msr(vmx->guest_msrs[i].index,
+				   vmx->guest_msrs[i].data,
+				   vmx->guest_msrs[i].mask);
 }
 
 static void __vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -684,9 +685,12 @@ static void __vmx_load_host_state(struct
 		local_irq_restore(flags);
 	}
 	reload_tss();
-	save_msrs(vmx->guest_msrs, vmx->save_nmsrs);
-	load_msrs(vmx->host_msrs, vmx->save_nmsrs);
-	reload_host_efer(vmx);
+#ifdef CONFIG_X86_64
+	if (is_long_mode(&vmx->vcpu)) {
+		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+		wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+	}
+#endif
 }
 
 static void vmx_load_host_state(struct vcpu_vmx *vmx)
@@ -877,19 +881,14 @@ static void vmx_queue_exception(struct k
 /*
  * Swap MSR entry in host/guest MSR entry array.
  */
-#ifdef CONFIG_X86_64
 static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
 {
-	struct kvm_msr_entry tmp;
+	struct shared_msr_entry tmp;
 
 	tmp = vmx->guest_msrs[to];
 	vmx->guest_msrs[to] = vmx->guest_msrs[from];
 	vmx->guest_msrs[from] = tmp;
-	tmp = vmx->host_msrs[to];
-	vmx->host_msrs[to] = vmx->host_msrs[from];
-	vmx->host_msrs[from] = tmp;
 }
-#endif
 
 /*
  * Set up the vmcs to automatically save and restore system
@@ -898,15 +897,13 @@ static void move_msr_up(struct vcpu_vmx
  */
 static void setup_msrs(struct vcpu_vmx *vmx)
 {
-	int save_nmsrs;
+	int save_nmsrs, index;
 	unsigned long *msr_bitmap;
 
 	vmx_load_host_state(vmx);
 	save_nmsrs = 0;
 #ifdef CONFIG_X86_64
 	if (is_long_mode(&vmx->vcpu)) {
-		int index;
-
 		index = __find_msr_index(vmx, MSR_SYSCALL_MASK);
 		if (index >= 0)
 			move_msr_up(vmx, index, save_nmsrs++);
@@ -916,9 +913,6 @@ static void setup_msrs(struct vcpu_vmx *
 		index = __find_msr_index(vmx, MSR_CSTAR);
 		if (index >= 0)
 			move_msr_up(vmx, index, save_nmsrs++);
-		index = __find_msr_index(vmx, MSR_KERNEL_GS_BASE);
-		if (index >= 0)
-			move_msr_up(vmx, index, save_nmsrs++);
 		/*
 		 * MSR_K6_STAR is only needed on long mode guests, and only
 		 * if efer.sce is enabled.
@@ -928,13 +922,11 @@ static void setup_msrs(struct vcpu_vmx *
 			move_msr_up(vmx, index, save_nmsrs++);
 	}
 #endif
-	vmx->save_nmsrs = save_nmsrs;
+	index = __find_msr_index(vmx, MSR_EFER);
+	if (index >= 0 && update_transition_efer(vmx, index))
+		move_msr_up(vmx, index, save_nmsrs++);
 
-#ifdef CONFIG_X86_64
-	vmx->msr_offset_kernel_gs_base =
-		__find_msr_index(vmx, MSR_KERNEL_GS_BASE);
-#endif
-	vmx->msr_offset_efer = __find_msr_index(vmx, MSR_EFER);
+	vmx->save_nmsrs = save_nmsrs;
 
 	if (cpu_has_vmx_msr_bitmap()) {
 		if (is_long_mode(&vmx->vcpu))
@@ -976,7 +968,7 @@ static void guest_write_tsc(u64 guest_ts
 static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
 {
 	u64 data;
-	struct kvm_msr_entry *msr;
+	struct shared_msr_entry *msr;
 
 	if (!pdata) {
 		printk(KERN_ERR "BUG: get_msr called with NULL pdata\n");
@@ -991,9 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu *
 	case MSR_GS_BASE:
 		data = vmcs_readl(GUEST_GS_BASE);
 		break;
+	case MSR_KERNEL_GS_BASE:
+		vmx_load_host_state(to_vmx(vcpu));
+		data = to_vmx(vcpu)->msr_guest_kernel_gs_base;
+		break;
+#endif
 	case MSR_EFER:
 		return kvm_get_msr_common(vcpu, msr_index, pdata);
-#endif
 	case MSR_IA32_TSC:
 		data = guest_read_tsc();
 		break;
@@ -1007,6 +1003,7 @@ static int vmx_get_msr(struct kvm_vcpu *
 		data = vmcs_readl(GUEST_SYSENTER_ESP);
 		break;
 	default:
+		vmx_load_host_state(to_vmx(vcpu));
 		msr = find_msr_entry(to_vmx(vcpu), msr_index);
 		if (msr) {
 			vmx_load_host_state(to_vmx(vcpu));
@@ -1028,7 +1025,7 @@ static int vmx_get_msr(struct kvm_vcpu *
 static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	struct kvm_msr_entry *msr;
+	struct shared_msr_entry *msr;
 	u64 host_tsc;
 	int ret = 0;
 
@@ -1044,6 +1041,10 @@ static int vmx_set_msr(struct kvm_vcpu *
 	case MSR_GS_BASE:
 		vmcs_writel(GUEST_GS_BASE, data);
 		break;
+	case MSR_KERNEL_GS_BASE:
+		vmx_load_host_state(vmx);
+		vmx->msr_guest_kernel_gs_base = data;
+		break;
 #endif
 	case MSR_IA32_SYSENTER_CS:
 		vmcs_write32(GUEST_SYSENTER_CS, data);
@@ -1097,30 +1098,14 @@ static void vmx_cache_reg(struct kvm_vcp
 	}
 }
 
-static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
+static void set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
 {
-	int old_debug = vcpu->guest_debug;
-	unsigned long flags;
-
-	vcpu->guest_debug = dbg->control;
-	if (!(vcpu->guest_debug & KVM_GUESTDBG_ENABLE))
-		vcpu->guest_debug = 0;
-
 	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
 		vmcs_writel(GUEST_DR7, dbg->arch.debugreg[7]);
 	else
 		vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
 
-	flags = vmcs_readl(GUEST_RFLAGS);
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
-	else if (old_debug & KVM_GUESTDBG_SINGLESTEP)
-		flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
-	vmcs_writel(GUEST_RFLAGS, flags);
-
 	update_exception_bitmap(vcpu);
-
-	return 0;
 }
 
 static __init int cpu_has_kvm_support(void)
@@ -1139,12 +1124,15 @@ static __init int vmx_disabled_by_bios(v
 	/* locked but not enabled */
 }
 
-static void hardware_enable(void *garbage)
+static int hardware_enable(void *garbage)
 {
 	int cpu = raw_smp_processor_id();
 	u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
 	u64 old;
 
+	if (read_cr4() & X86_CR4_VMXE)
+		return -EBUSY;
+
 	INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu));
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
 	if ((old & (FEATURE_CONTROL_LOCKED |
@@ -1159,6 +1147,10 @@ static void hardware_enable(void *garbag
 	asm volatile (ASM_VMX_VMXON_RAX
 		      : : "a"(&phys_addr), "m"(phys_addr)
 		      : "memory", "cc");
+
+	ept_sync_global();
+
+	return 0;
 }
 
 static void vmclear_local_vcpus(void)
@@ -1250,7 +1242,8 @@ static __init int setup_vmcs_config(stru
 			SECONDARY_EXEC_WBINVD_EXITING |
 			SECONDARY_EXEC_ENABLE_VPID |
 			SECONDARY_EXEC_ENABLE_EPT |
-			SECONDARY_EXEC_UNRESTRICTED_GUEST;
+			SECONDARY_EXEC_UNRESTRICTED_GUEST |
+			SECONDARY_EXEC_PAUSE_LOOP_EXITING;
 		if (adjust_vmx_controls(min2, opt2,
 					MSR_IA32_VMX_PROCBASED_CTLS2,
 					&_cpu_based_2nd_exec_control) < 0)
@@ -1344,15 +1337,17 @@ static void free_kvm_area(void)
 {
 	int cpu;
 
-	for_each_online_cpu(cpu)
+	for_each_possible_cpu(cpu) {
 		free_vmcs(per_cpu(vmxarea, cpu));
+		per_cpu(vmxarea, cpu) = NULL;
+	}
 }
 
 static __init int alloc_kvm_area(void)
 {
 	int cpu;
 
-	for_each_online_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		struct vmcs *vmcs;
 
 		vmcs = alloc_vmcs_cpu(cpu);
@@ -1394,6 +1389,9 @@ static __init int hardware_setup(void)
 	if (enable_ept && !cpu_has_vmx_ept_2m_page())
 		kvm_disable_largepages();
 
+	if (!cpu_has_vmx_ple())
+		ple_gap = 0;
+
 	return alloc_kvm_area();
 }
 
@@ -1536,8 +1534,16 @@ continue_rmode:
 static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
+	struct shared_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
+
+	if (!msr)
+		return;
 
+	/*
+	 * Force kernel_gs_base reloading before EFER changes, as control
+	 * of this msr depends on is_long_mode().
+	 */
+	vmx_load_host_state(to_vmx(vcpu));
 	vcpu->arch.shadow_efer = efer;
 	if (!msr)
 		return;
@@ -1727,6 +1733,7 @@ static void vmx_set_cr3(struct kvm_vcpu
 		vmcs_write64(EPT_POINTER, eptp);
 		guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
 			vcpu->kvm->arch.ept_identity_map_addr;
+		ept_load_pdptrs(vcpu);
 	}
 
 	vmx_flush_tlb(vcpu);
@@ -2302,13 +2309,22 @@ static int vmx_vcpu_setup(struct vcpu_vm
 				~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
 		if (vmx->vpid == 0)
 			exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
-		if (!enable_ept)
+		if (!enable_ept) {
 			exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+			enable_unrestricted_guest = 0;
+		}
 		if (!enable_unrestricted_guest)
 			exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
+		if (!ple_gap)
+			exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
 		vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
 	}
 
+	if (ple_gap) {
+		vmcs_write32(PLE_GAP, ple_gap);
+		vmcs_write32(PLE_WINDOW, ple_window);
+	}
+
 	vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, !!bypass_guest_pf);
 	vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, !!bypass_guest_pf);
 	vmcs_write32(CR3_TARGET_COUNT, 0);           /* 22.2.1 */
@@ -2376,10 +2392,9 @@ static int vmx_vcpu_setup(struct vcpu_vm
 		if (wrmsr_safe(index, data_low, data_high) < 0)
 			continue;
 		data = data_low | ((u64)data_high << 32);
-		vmx->host_msrs[j].index = index;
-		vmx->host_msrs[j].reserved = 0;
-		vmx->host_msrs[j].data = data;
-		vmx->guest_msrs[j] = vmx->host_msrs[j];
+		vmx->guest_msrs[j].index = i;
+		vmx->guest_msrs[j].data = 0;
+		vmx->guest_msrs[j].mask = -1ull;
 		++vmx->nmsrs;
 	}
 
@@ -2510,7 +2525,7 @@ static int vmx_vcpu_reset(struct kvm_vcp
 	if (vmx->vpid != 0)
 		vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
 
-	vmx->vcpu.arch.cr0 = 0x60000010;
+	vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
 	vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */
 	vmx_set_cr4(&vmx->vcpu, 0);
 	vmx_set_efer(&vmx->vcpu, 0);
@@ -2627,6 +2642,34 @@ static int vmx_nmi_allowed(struct kvm_vc
 				GUEST_INTR_STATE_NMI));
 }
 
+static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
+{
+	if (!cpu_has_virtual_nmis())
+		return to_vmx(vcpu)->soft_vnmi_blocked;
+	else
+		return !!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+			  GUEST_INTR_STATE_NMI);
+}
+
+static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+	if (!cpu_has_virtual_nmis()) {
+		if (vmx->soft_vnmi_blocked != masked) {
+			vmx->soft_vnmi_blocked = masked;
+			vmx->vnmi_blocked_time = 0;
+		}
+	} else {
+		if (masked)
+			vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
+				      GUEST_INTR_STATE_NMI);
+		else
+			vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+					GUEST_INTR_STATE_NMI);
+	}
+}
+
 static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
 {
 	return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
@@ -2659,7 +2702,7 @@ static int handle_rmode_exception(struct
 	 * Cause the #SS fault with 0 error code in VM86 mode.
 	 */
 	if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
-		if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
+		if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE)
 			return 1;
 	/*
 	 * Forward all other exceptions that are valid in real mode.
@@ -2710,15 +2753,16 @@ static void kvm_machine_check(void)
 #endif
 }
 
-static int handle_machine_check(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_machine_check(struct kvm_vcpu *vcpu)
 {
 	/* already handled by vcpu_run */
 	return 1;
 }
 
-static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_exception(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	struct kvm_run *kvm_run = vcpu->run;
 	u32 intr_info, ex_no, error_code;
 	unsigned long cr2, rip, dr6;
 	u32 vect_info;
@@ -2728,12 +2772,17 @@ static int handle_exception(struct kvm_v
 	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
 
 	if (is_machine_check(intr_info))
-		return handle_machine_check(vcpu, kvm_run);
+		return handle_machine_check(vcpu);
 
 	if ((vect_info & VECTORING_INFO_VALID_MASK) &&
-						!is_page_fault(intr_info))
-		printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
-		       "intr info 0x%x\n", __func__, vect_info, intr_info);
+	    !is_page_fault(intr_info)) {
+		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_SIMUL_EX;
+		vcpu->run->internal.ndata = 2;
+		vcpu->run->internal.data[0] = vect_info;
+		vcpu->run->internal.data[1] = intr_info;
+		return 0;
+	}
 
 	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR)
 		return 1;  /* already handled by vmx_vcpu_run() */
@@ -2744,7 +2793,7 @@ static int handle_exception(struct kvm_v
 	}
 
 	if (is_invalid_opcode(intr_info)) {
-		er = emulate_instruction(vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD);
+		er = emulate_instruction(vcpu, 0, 0, EMULTYPE_TRAP_UD);
 		if (er != EMULATE_DONE)
 			kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
@@ -2803,20 +2852,19 @@ static int handle_exception(struct kvm_v
 	return 0;
 }
 
-static int handle_external_interrupt(struct kvm_vcpu *vcpu,
-				     struct kvm_run *kvm_run)
+static int handle_external_interrupt(struct kvm_vcpu *vcpu)
 {
 	++vcpu->stat.irq_exits;
 	return 1;
 }
 
-static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_triple_fault(struct kvm_vcpu *vcpu)
 {
-	kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
+	vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
 	return 0;
 }
 
-static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_io(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification;
 	int size, in, string;
@@ -2827,8 +2875,7 @@ static int handle_io(struct kvm_vcpu *vc
 	string = (exit_qualification & 16) != 0;
 
 	if (string) {
-		if (emulate_instruction(vcpu,
-					kvm_run, 0, 0, 0) == EMULATE_DO_MMIO)
+		if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO)
 			return 0;
 		return 1;
 	}
@@ -2838,7 +2885,7 @@ static int handle_io(struct kvm_vcpu *vc
 	port = exit_qualification >> 16;
 
 	skip_emulated_instruction(vcpu);
-	return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
+	return kvm_emulate_pio(vcpu, in, size, port);
 }
 
 static void
@@ -2852,7 +2899,7 @@ vmx_patch_hypercall(struct kvm_vcpu *vcp
 	hypercall[2] = 0xc1;
 }
 
-static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_cr(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification, val;
 	int cr;
@@ -2887,7 +2934,7 @@ static int handle_cr(struct kvm_vcpu *vc
 					return 1;
 				if (cr8_prev <= cr8)
 					return 1;
-				kvm_run->exit_reason = KVM_EXIT_SET_TPR;
+				vcpu->run->exit_reason = KVM_EXIT_SET_TPR;
 				return 0;
 			}
 		};
@@ -2922,13 +2969,13 @@ static int handle_cr(struct kvm_vcpu *vc
 	default:
 		break;
 	}
-	kvm_run->exit_reason = 0;
+	vcpu->run->exit_reason = 0;
 	pr_unimpl(vcpu, "unhandled control register: op %d cr %d\n",
 	       (int)(exit_qualification >> 4) & 3, cr);
 	return 0;
 }
 
-static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_dr(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification;
 	unsigned long val;
@@ -2944,13 +2991,13 @@ static int handle_dr(struct kvm_vcpu *vc
 		 * guest debugging itself.
 		 */
 		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
-			kvm_run->debug.arch.dr6 = vcpu->arch.dr6;
-			kvm_run->debug.arch.dr7 = dr;
-			kvm_run->debug.arch.pc =
+			vcpu->run->debug.arch.dr6 = vcpu->arch.dr6;
+			vcpu->run->debug.arch.dr7 = dr;
+			vcpu->run->debug.arch.pc =
 				vmcs_readl(GUEST_CS_BASE) +
 				vmcs_readl(GUEST_RIP);
-			kvm_run->debug.arch.exception = DB_VECTOR;
-			kvm_run->exit_reason = KVM_EXIT_DEBUG;
+			vcpu->run->debug.arch.exception = DB_VECTOR;
+			vcpu->run->exit_reason = KVM_EXIT_DEBUG;
 			return 0;
 		} else {
 			vcpu->arch.dr7 &= ~DR7_GD;
@@ -3016,13 +3063,13 @@ static int handle_dr(struct kvm_vcpu *vc
 	return 1;
 }
 
-static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_cpuid(struct kvm_vcpu *vcpu)
 {
 	kvm_emulate_cpuid(vcpu);
 	return 1;
 }
 
-static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_rdmsr(struct kvm_vcpu *vcpu)
 {
 	u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
 	u64 data;
@@ -3041,7 +3088,7 @@ static int handle_rdmsr(struct kvm_vcpu
 	return 1;
 }
 
-static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_wrmsr(struct kvm_vcpu *vcpu)
 {
 	u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
 	u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
@@ -3058,14 +3105,12 @@ static int handle_wrmsr(struct kvm_vcpu
 	return 1;
 }
 
-static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu,
-				      struct kvm_run *kvm_run)
+static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu)
 {
 	return 1;
 }
 
-static int handle_interrupt_window(struct kvm_vcpu *vcpu,
-				   struct kvm_run *kvm_run)
+static int handle_interrupt_window(struct kvm_vcpu *vcpu)
 {
 	u32 cpu_based_vm_exec_control;
 
@@ -3081,34 +3126,34 @@ static int handle_interrupt_window(struc
 	 * possible
 	 */
 	if (!irqchip_in_kernel(vcpu->kvm) &&
-	    kvm_run->request_interrupt_window &&
+	    vcpu->run->request_interrupt_window &&
 	    !kvm_cpu_has_interrupt(vcpu)) {
-		kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
+		vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
 		return 0;
 	}
 	return 1;
 }
 
-static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_halt(struct kvm_vcpu *vcpu)
 {
 	skip_emulated_instruction(vcpu);
 	return kvm_emulate_halt(vcpu);
 }
 
-static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_vmcall(struct kvm_vcpu *vcpu)
 {
 	skip_emulated_instruction(vcpu);
 	kvm_emulate_hypercall(vcpu);
 	return 1;
 }
 
-static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_vmx_insn(struct kvm_vcpu *vcpu)
 {
 	kvm_queue_exception(vcpu, UD_VECTOR);
 	return 1;
 }
 
-static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_invlpg(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 
@@ -3117,14 +3162,14 @@ static int handle_invlpg(struct kvm_vcpu
 	return 1;
 }
 
-static int handle_wbinvd(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_wbinvd(struct kvm_vcpu *vcpu)
 {
 	skip_emulated_instruction(vcpu);
 	/* TODO: Add support for VT-d/pass-through device */
 	return 1;
 }
 
-static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_apic_access(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification;
 	enum emulation_result er;
@@ -3133,7 +3178,7 @@ static int handle_apic_access(struct kvm
 	exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 	offset = exit_qualification & 0xffful;
 
-	er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+	er = emulate_instruction(vcpu, 0, 0, 0);
 
 	if (er !=  EMULATE_DONE) {
 		printk(KERN_ERR
@@ -3144,7 +3189,7 @@ static int handle_apic_access(struct kvm
 	return 1;
 }
 
-static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_task_switch(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	unsigned long exit_qualification;
@@ -3198,7 +3243,7 @@ static int handle_task_switch(struct kvm
 	return 1;
 }
 
-static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_ept_violation(struct kvm_vcpu *vcpu)
 {
 	unsigned long exit_qualification;
 	gpa_t gpa;
@@ -3219,8 +3264,8 @@ static int handle_ept_violation(struct k
 			vmcs_readl(GUEST_LINEAR_ADDRESS));
 		printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
 			(long unsigned int)exit_qualification);
-		kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
-		kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION;
+		vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
+		vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION;
 		return 0;
 	}
 
@@ -3290,7 +3335,7 @@ static void ept_misconfig_inspect_spte(s
 	}
 }
 
-static int handle_ept_misconfig(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
 {
 	u64 sptes[4];
 	int nr_sptes, i;
@@ -3306,13 +3351,13 @@ static int handle_ept_misconfig(struct k
 	for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i)
 		ept_misconfig_inspect_spte(vcpu, sptes[i-1], i);
 
-	kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
-	kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
+	vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
+	vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
 
 	return 0;
 }
 
-static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int handle_nmi_window(struct kvm_vcpu *vcpu)
 {
 	u32 cpu_based_vm_exec_control;
 
@@ -3325,36 +3370,50 @@ static int handle_nmi_window(struct kvm_
 	return 1;
 }
 
-static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
-				struct kvm_run *kvm_run)
+static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	enum emulation_result err = EMULATE_DONE;
-
-	local_irq_enable();
-	preempt_enable();
+	int ret = 1;
 
 	while (!guest_state_valid(vcpu)) {
-		err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+		err = emulate_instruction(vcpu, 0, 0, 0);
 
-		if (err == EMULATE_DO_MMIO)
-			break;
+		if (err == EMULATE_DO_MMIO) {
+			ret = 0;
+			goto out;
+		}
 
 		if (err != EMULATE_DONE) {
 			kvm_report_emulation_failure(vcpu, "emulation failure");
-			break;
+			vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+			vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+			vcpu->run->internal.ndata = 0;
+			ret = 0;
+			goto out;
 		}
 
 		if (signal_pending(current))
-			break;
+			goto out;
 		if (need_resched())
 			schedule();
 	}
 
-	preempt_disable();
-	local_irq_disable();
+	vmx->emulation_required = 0;
+out:
+	return ret;
+}
 
-	vmx->invalid_state_emulation_result = err;
+/*
+ * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE
+ * exiting, so only get here on cpu with PAUSE-Loop-Exiting.
+ */
+static int handle_pause(struct kvm_vcpu *vcpu)
+{
+	skip_emulated_instruction(vcpu);
+	kvm_vcpu_on_spin(vcpu);
+
+	return 1;
 }
 
 /*
@@ -3362,8 +3421,7 @@ static void handle_invalid_guest_state(s
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
  * to be done to userspace and return 0.
  */
-static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
-				      struct kvm_run *kvm_run) = {
+static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[EXIT_REASON_EXCEPTION_NMI]           = handle_exception,
 	[EXIT_REASON_EXTERNAL_INTERRUPT]      = handle_external_interrupt,
 	[EXIT_REASON_TRIPLE_FAULT]            = handle_triple_fault,
@@ -3394,6 +3452,7 @@ static int (*kvm_vmx_exit_handlers[])(st
 	[EXIT_REASON_MCE_DURING_VMENTRY]      = handle_machine_check,
 	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
 	[EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig,
+	[EXIT_REASON_PAUSE_INSTRUCTION]       = handle_pause,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -3403,7 +3462,7 @@ static const int kvm_vmx_max_exit_handle
  * The guest has exited.  See if we can fix it or if we need userspace
  * assistance.
  */
-static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+static int vmx_handle_exit(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u32 exit_reason = vmx->exit_reason;
@@ -3411,13 +3470,9 @@ static int vmx_handle_exit(struct kvm_ru
 
 	trace_kvm_exit(exit_reason, kvm_rip_read(vcpu));
 
-	/* If we need to emulate an MMIO from handle_invalid_guest_state
-	 * we just return 0 */
-	if (vmx->emulation_required && emulate_invalid_guest_state) {
-		if (guest_state_valid(vcpu))
-			vmx->emulation_required = 0;
-		return vmx->invalid_state_emulation_result != EMULATE_DO_MMIO;
-	}
+	/* If guest state is invalid, start emulating */
+	if (vmx->emulation_required && emulate_invalid_guest_state)
+		return handle_invalid_guest_state(vcpu);
 
 	/* Access CR3 don't cause VMExit in paging mode, so we need
 	 * to sync with guest real CR3. */
@@ -3425,8 +3480,8 @@ static int vmx_handle_exit(struct kvm_ru
 		vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
 
 	if (unlikely(vmx->fail)) {
-		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
-		kvm_run->fail_entry.hardware_entry_failure_reason
+		vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+		vcpu->run->fail_entry.hardware_entry_failure_reason
 			= vmcs_read32(VM_INSTRUCTION_ERROR);
 		return 0;
 	}
@@ -3459,10 +3514,10 @@ static int vmx_handle_exit(struct kvm_ru
 
 	if (exit_reason < kvm_vmx_max_exit_handlers
 	    && kvm_vmx_exit_handlers[exit_reason])
-		return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run);
+		return kvm_vmx_exit_handlers[exit_reason](vcpu);
 	else {
-		kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
-		kvm_run->hw.hardware_exit_reason = exit_reason;
+		vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
+		vcpu->run->hw.hardware_exit_reason = exit_reason;
 	}
 	return 0;
 }
@@ -3600,23 +3655,18 @@ static void fixup_rmode_irq(struct vcpu_
 #define Q "l"
 #endif
 
-static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
-	if (enable_ept && is_paging(vcpu)) {
-		vmcs_writel(GUEST_CR3, vcpu->arch.cr3);
-		ept_load_pdptrs(vcpu);
-	}
 	/* Record the guest's net vcpu time for enforced NMI injections. */
 	if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
 		vmx->entry_time = ktime_get();
 
-	/* Handle invalid guest state instead of entering VMX */
-	if (vmx->emulation_required && emulate_invalid_guest_state) {
-		handle_invalid_guest_state(vcpu, kvm_run);
+	/* Don't enter VMX if guest state is invalid, let the exit handler
+	   start emulation until we arrive back to a valid state */
+	if (vmx->emulation_required && emulate_invalid_guest_state)
 		return;
-	}
 
 	if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
 		vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
@@ -3775,7 +3825,6 @@ static void vmx_free_vcpu(struct kvm_vcp
 		__clear_bit(vmx->vpid, vmx_vpid_bitmap);
 	spin_unlock(&vmx_vpid_lock);
 	vmx_free_vmcs(vcpu);
-	kfree(vmx->host_msrs);
 	kfree(vmx->guest_msrs);
 	kvm_vcpu_uninit(vcpu);
 	kmem_cache_free(kvm_vcpu_cache, vmx);
@@ -3802,10 +3851,6 @@ static struct kvm_vcpu *vmx_create_vcpu(
 		goto uninit_vcpu;
 	}
 
-	vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!vmx->host_msrs)
-		goto free_guest_msrs;
-
 	vmx->vmcs = alloc_vmcs();
 	if (!vmx->vmcs)
 		goto free_msrs;
@@ -3836,8 +3881,6 @@ static struct kvm_vcpu *vmx_create_vcpu(
 free_vmcs:
 	free_vmcs(vmx->vmcs);
 free_msrs:
-	kfree(vmx->host_msrs);
-free_guest_msrs:
 	kfree(vmx->guest_msrs);
 uninit_vcpu:
 	kvm_vcpu_uninit(&vmx->vcpu);
@@ -3973,6 +4016,8 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.queue_exception = vmx_queue_exception,
 	.interrupt_allowed = vmx_interrupt_allowed,
 	.nmi_allowed = vmx_nmi_allowed,
+	.get_nmi_mask = vmx_get_nmi_mask,
+	.set_nmi_mask = vmx_set_nmi_mask,
 	.enable_nmi_window = enable_nmi_window,
 	.enable_irq_window = enable_irq_window,
 	.update_cr8_intercept = update_cr8_intercept,
@@ -3987,7 +4032,12 @@ static struct kvm_x86_ops vmx_x86_ops =
 
 static int __init vmx_init(void)
 {
-	int r;
+	int r, i;
+
+	rdmsrl_safe(MSR_EFER, &host_efer);
+
+	for (i = 0; i < NR_VMX_MSR; ++i)
+		kvm_define_shared_msr(i, vmx_msr_index[i]);
 
 	vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
 	if (!vmx_io_bitmap_a)
@@ -4049,8 +4099,6 @@ static int __init vmx_init(void)
 	if (bypass_guest_pf)
 		kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull);
 
-	ept_sync_global();
-
 	return 0;
 
 out3:
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/kvm/x86.c linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.c
--- linux-libre-2.6.32-gnu1/arch/x86/kvm/x86.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/kvm/x86.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,11 +37,13 @@
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
 #include <linux/cpufreq.h>
+#include <linux/user-return-notifier.h>
 #include <trace/events/kvm.h>
 #undef TRACE_INCLUDE_FILE
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
+#include <asm/debugreg.h>
 #include <asm/uaccess.h>
 #include <asm/msr.h>
 #include <asm/desc.h>
@@ -87,6 +89,25 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops);
 int ignore_msrs = 0;
 module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
 
+#define KVM_NR_SHARED_MSRS 16
+
+struct kvm_shared_msrs_global {
+	int nr;
+	struct kvm_shared_msr {
+		u32 msr;
+		u64 value;
+	} msrs[KVM_NR_SHARED_MSRS];
+};
+
+struct kvm_shared_msrs {
+	struct user_return_notifier urn;
+	bool registered;
+	u64 current_value[KVM_NR_SHARED_MSRS];
+};
+
+static struct kvm_shared_msrs_global __read_mostly shared_msrs_global;
+static DEFINE_PER_CPU(struct kvm_shared_msrs, shared_msrs);
+
 struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "pf_fixed", VCPU_STAT(pf_fixed) },
 	{ "pf_guest", VCPU_STAT(pf_guest) },
@@ -123,6 +144,72 @@ struct kvm_stats_debugfs_item debugfs_en
 	{ NULL }
 };
 
+static void kvm_on_user_return(struct user_return_notifier *urn)
+{
+	unsigned slot;
+	struct kvm_shared_msr *global;
+	struct kvm_shared_msrs *locals
+		= container_of(urn, struct kvm_shared_msrs, urn);
+
+	for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
+		global = &shared_msrs_global.msrs[slot];
+		if (global->value != locals->current_value[slot]) {
+			wrmsrl(global->msr, global->value);
+			locals->current_value[slot] = global->value;
+		}
+	}
+	locals->registered = false;
+	user_return_notifier_unregister(urn);
+}
+
+void kvm_define_shared_msr(unsigned slot, u32 msr)
+{
+	int cpu;
+	u64 value;
+
+	if (slot >= shared_msrs_global.nr)
+		shared_msrs_global.nr = slot + 1;
+	shared_msrs_global.msrs[slot].msr = msr;
+	rdmsrl_safe(msr, &value);
+	shared_msrs_global.msrs[slot].value = value;
+	for_each_online_cpu(cpu)
+		per_cpu(shared_msrs, cpu).current_value[slot] = value;
+}
+EXPORT_SYMBOL_GPL(kvm_define_shared_msr);
+
+static void kvm_shared_msr_cpu_online(void)
+{
+	unsigned i;
+	struct kvm_shared_msrs *locals = &__get_cpu_var(shared_msrs);
+
+	for (i = 0; i < shared_msrs_global.nr; ++i)
+		locals->current_value[i] = shared_msrs_global.msrs[i].value;
+}
+
+void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
+{
+	struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
+
+	if (((value ^ smsr->current_value[slot]) & mask) == 0)
+		return;
+	smsr->current_value[slot] = value;
+	wrmsrl(shared_msrs_global.msrs[slot].msr, value);
+	if (!smsr->registered) {
+		smsr->urn.on_user_return = kvm_on_user_return;
+		user_return_notifier_register(&smsr->urn);
+		smsr->registered = true;
+	}
+}
+EXPORT_SYMBOL_GPL(kvm_set_shared_msr);
+
+static void drop_user_return_notifiers(void *ignore)
+{
+	struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
+
+	if (smsr->registered)
+		kvm_on_user_return(&smsr->urn);
+}
+
 unsigned long segment_base(u16 selector)
 {
 	struct descriptor_table gdt;
@@ -484,16 +571,19 @@ static inline u32 bit(int bitno)
  * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
  *
  * This list is modified at module load time to reflect the
- * capabilities of the host cpu.
+ * capabilities of the host cpu. This capabilities test skips MSRs that are
+ * kvm-specific. Those are put in the beginning of the list.
  */
+
+#define KVM_SAVE_MSRS_BEGIN	2
 static u32 msrs_to_save[] = {
+	MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
 	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
 	MSR_K6_STAR,
 #ifdef CONFIG_X86_64
 	MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
-	MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
-	MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
+	MSR_IA32_TSC, MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
 };
 
 static unsigned num_msrs_to_save;
@@ -580,7 +670,7 @@ static void kvm_write_wall_clock(struct
 {
 	static int version;
 	struct pvclock_wall_clock wc;
-	struct timespec now, sys, boot;
+	struct timespec boot;
 
 	if (!wall_clock)
 		return;
@@ -595,9 +685,7 @@ static void kvm_write_wall_clock(struct
 	 * wall clock specified here.  guest system time equals host
 	 * system time for us, thus we must fill in host boot time here.
 	 */
-	now = current_kernel_time();
-	ktime_get_ts(&sys);
-	boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys));
+	getboottime(&boot);
 
 	wc.sec = boot.tv_sec;
 	wc.nsec = boot.tv_nsec;
@@ -672,12 +760,14 @@ static void kvm_write_guest_time(struct
 	local_irq_save(flags);
 	kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp);
 	ktime_get_ts(&ts);
+	monotonic_to_bootbased(&ts);
 	local_irq_restore(flags);
 
 	/* With all the info we got, fill in the values */
 
 	vcpu->hv_clock.system_time = ts.tv_nsec +
-				     (NSEC_PER_SEC * (u64)ts.tv_sec);
+				     (NSEC_PER_SEC * (u64)ts.tv_sec) + v->kvm->arch.kvmclock_offset;
+
 	/*
 	 * The interface expects us to write an even number signaling that the
 	 * update is finished. Since the guest won't see the intermediate
@@ -835,6 +925,38 @@ static int set_msr_mce(struct kvm_vcpu *
 	return 0;
 }
 
+static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
+{
+	struct kvm *kvm = vcpu->kvm;
+	int lm = is_long_mode(vcpu);
+	u8 *blob_addr = lm ? (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_64
+		: (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_32;
+	u8 blob_size = lm ? kvm->arch.xen_hvm_config.blob_size_64
+		: kvm->arch.xen_hvm_config.blob_size_32;
+	u32 page_num = data & ~PAGE_MASK;
+	u64 page_addr = data & PAGE_MASK;
+	u8 *page;
+	int r;
+
+	r = -E2BIG;
+	if (page_num >= blob_size)
+		goto out;
+	r = -ENOMEM;
+	page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!page)
+		goto out;
+	r = -EFAULT;
+	if (copy_from_user(page, blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE))
+		goto out_free;
+	if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE))
+		goto out_free;
+	r = 0;
+out_free:
+	kfree(page);
+out:
+	return r;
+}
+
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 {
 	switch (msr) {
@@ -950,6 +1072,8 @@ int kvm_set_msr_common(struct kvm_vcpu *
 			"0x%x data 0x%llx\n", msr, data);
 		break;
 	default:
+		if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
+			return xen_hvm_config(vcpu, data);
 		if (!ignore_msrs) {
 			pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n",
 				msr, data);
@@ -1224,6 +1348,9 @@ int kvm_dev_ioctl_check_extension(long e
 	case KVM_CAP_PIT2:
 	case KVM_CAP_PIT_STATE2:
 	case KVM_CAP_SET_IDENTITY_MAP_ADDR:
+	case KVM_CAP_XEN_HVM:
+	case KVM_CAP_ADJUST_CLOCK:
+	case KVM_CAP_VCPU_EVENTS:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -1238,8 +1365,8 @@ int kvm_dev_ioctl_check_extension(long e
 	case KVM_CAP_NR_MEMSLOTS:
 		r = KVM_MEMORY_SLOTS;
 		break;
-	case KVM_CAP_PV_MMU:
-		r = !tdp_enabled;
+	case KVM_CAP_PV_MMU:	/* obsolete */
+		r = 0;
 		break;
 	case KVM_CAP_IOMMU:
 		r = iommu_found();
@@ -1326,6 +1453,12 @@ out:
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	kvm_x86_ops->vcpu_load(vcpu, cpu);
+	if (unlikely(per_cpu(cpu_tsc_khz, cpu) == 0)) {
+		unsigned long khz = cpufreq_quick_get(cpu);
+		if (!khz)
+			khz = tsc_khz;
+		per_cpu(cpu_tsc_khz, cpu) = khz;
+	}
 	kvm_request_guest_time_update(vcpu);
 }
 
@@ -1759,6 +1892,65 @@ static int kvm_vcpu_ioctl_x86_set_mce(st
 	return 0;
 }
 
+static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
+					       struct kvm_vcpu_events *events)
+{
+	vcpu_load(vcpu);
+
+	events->exception.injected = vcpu->arch.exception.pending;
+	events->exception.nr = vcpu->arch.exception.nr;
+	events->exception.has_error_code = vcpu->arch.exception.has_error_code;
+	events->exception.error_code = vcpu->arch.exception.error_code;
+
+	events->interrupt.injected = vcpu->arch.interrupt.pending;
+	events->interrupt.nr = vcpu->arch.interrupt.nr;
+	events->interrupt.soft = vcpu->arch.interrupt.soft;
+
+	events->nmi.injected = vcpu->arch.nmi_injected;
+	events->nmi.pending = vcpu->arch.nmi_pending;
+	events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu);
+
+	events->sipi_vector = vcpu->arch.sipi_vector;
+
+	events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
+			 | KVM_VCPUEVENT_VALID_SIPI_VECTOR);
+
+	vcpu_put(vcpu);
+}
+
+static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
+					      struct kvm_vcpu_events *events)
+{
+	if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING
+			      | KVM_VCPUEVENT_VALID_SIPI_VECTOR))
+		return -EINVAL;
+
+	vcpu_load(vcpu);
+
+	vcpu->arch.exception.pending = events->exception.injected;
+	vcpu->arch.exception.nr = events->exception.nr;
+	vcpu->arch.exception.has_error_code = events->exception.has_error_code;
+	vcpu->arch.exception.error_code = events->exception.error_code;
+
+	vcpu->arch.interrupt.pending = events->interrupt.injected;
+	vcpu->arch.interrupt.nr = events->interrupt.nr;
+	vcpu->arch.interrupt.soft = events->interrupt.soft;
+	if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm))
+		kvm_pic_clear_isr_ack(vcpu->kvm);
+
+	vcpu->arch.nmi_injected = events->nmi.injected;
+	if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING)
+		vcpu->arch.nmi_pending = events->nmi.pending;
+	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
+
+	if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
+		vcpu->arch.sipi_vector = events->sipi_vector;
+
+	vcpu_put(vcpu);
+
+	return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -1769,6 +1961,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 
 	switch (ioctl) {
 	case KVM_GET_LAPIC: {
+		r = -EINVAL;
+		if (!vcpu->arch.apic)
+			goto out;
 		lapic = kzalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
 
 		r = -ENOMEM;
@@ -1784,6 +1979,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		break;
 	}
 	case KVM_SET_LAPIC: {
+		r = -EINVAL;
+		if (!vcpu->arch.apic)
+			goto out;
 		lapic = kmalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
 		r = -ENOMEM;
 		if (!lapic)
@@ -1910,6 +2108,27 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
 		break;
 	}
+	case KVM_GET_VCPU_EVENTS: {
+		struct kvm_vcpu_events events;
+
+		kvm_vcpu_ioctl_x86_get_vcpu_events(vcpu, &events);
+
+		r = -EFAULT;
+		if (copy_to_user(argp, &events, sizeof(struct kvm_vcpu_events)))
+			break;
+		r = 0;
+		break;
+	}
+	case KVM_SET_VCPU_EVENTS: {
+		struct kvm_vcpu_events events;
+
+		r = -EFAULT;
+		if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events)))
+			break;
+
+		r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events);
+		break;
+	}
 	default:
 		r = -EINVAL;
 	}
@@ -2038,9 +2257,7 @@ static int kvm_vm_ioctl_get_irqchip(stru
 			sizeof(struct kvm_pic_state));
 		break;
 	case KVM_IRQCHIP_IOAPIC:
-		memcpy(&chip->chip.ioapic,
-			ioapic_irqchip(kvm),
-			sizeof(struct kvm_ioapic_state));
+		r = kvm_get_ioapic(kvm, &chip->chip.ioapic);
 		break;
 	default:
 		r = -EINVAL;
@@ -2070,11 +2287,7 @@ static int kvm_vm_ioctl_set_irqchip(stru
 		spin_unlock(&pic_irqchip(kvm)->lock);
 		break;
 	case KVM_IRQCHIP_IOAPIC:
-		mutex_lock(&kvm->irq_lock);
-		memcpy(ioapic_irqchip(kvm),
-			&chip->chip.ioapic,
-			sizeof(struct kvm_ioapic_state));
-		mutex_unlock(&kvm->irq_lock);
+		r = kvm_set_ioapic(kvm, &chip->chip.ioapic);
 		break;
 	default:
 		r = -EINVAL;
@@ -2182,7 +2395,7 @@ long kvm_arch_vm_ioctl(struct file *filp
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
-	int r = -EINVAL;
+	int r = -ENOTTY;
 	/*
 	 * This union makes it completely explicit to gcc-3.x
 	 * that these two variables' stack usage should be
@@ -2244,25 +2457,39 @@ long kvm_arch_vm_ioctl(struct file *filp
 		if (r)
 			goto out;
 		break;
-	case KVM_CREATE_IRQCHIP:
+	case KVM_CREATE_IRQCHIP: {
+		struct kvm_pic *vpic;
+
+		mutex_lock(&kvm->lock);
+		r = -EEXIST;
+		if (kvm->arch.vpic)
+			goto create_irqchip_unlock;
 		r = -ENOMEM;
-		kvm->arch.vpic = kvm_create_pic(kvm);
-		if (kvm->arch.vpic) {
+		vpic = kvm_create_pic(kvm);
+		if (vpic) {
 			r = kvm_ioapic_init(kvm);
 			if (r) {
-				kfree(kvm->arch.vpic);
-				kvm->arch.vpic = NULL;
-				goto out;
+				kfree(vpic);
+				goto create_irqchip_unlock;
 			}
 		} else
-			goto out;
+			goto create_irqchip_unlock;
+		smp_wmb();
+		kvm->arch.vpic = vpic;
+		smp_wmb();
 		r = kvm_setup_default_irq_routing(kvm);
 		if (r) {
+			mutex_lock(&kvm->irq_lock);
 			kfree(kvm->arch.vpic);
 			kfree(kvm->arch.vioapic);
-			goto out;
+			kvm->arch.vpic = NULL;
+			kvm->arch.vioapic = NULL;
+			mutex_unlock(&kvm->irq_lock);
 		}
+	create_irqchip_unlock:
+		mutex_unlock(&kvm->lock);
 		break;
+	}
 	case KVM_CREATE_PIT:
 		u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
 		goto create_pit;
@@ -2292,10 +2519,8 @@ long kvm_arch_vm_ioctl(struct file *filp
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
 			__s32 status;
-			mutex_lock(&kvm->irq_lock);
 			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 					irq_event.irq, irq_event.level);
-			mutex_unlock(&kvm->irq_lock);
 			if (ioctl == KVM_IRQ_LINE_STATUS) {
 				irq_event.status = status;
 				if (copy_to_user(argp, &irq_event,
@@ -2421,6 +2646,55 @@ long kvm_arch_vm_ioctl(struct file *filp
 		r = 0;
 		break;
 	}
+	case KVM_XEN_HVM_CONFIG: {
+		r = -EFAULT;
+		if (copy_from_user(&kvm->arch.xen_hvm_config, argp,
+				   sizeof(struct kvm_xen_hvm_config)))
+			goto out;
+		r = -EINVAL;
+		if (kvm->arch.xen_hvm_config.flags)
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_CLOCK: {
+		struct timespec now;
+		struct kvm_clock_data user_ns;
+		u64 now_ns;
+		s64 delta;
+
+		r = -EFAULT;
+		if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
+			goto out;
+
+		r = -EINVAL;
+		if (user_ns.flags)
+			goto out;
+
+		r = 0;
+		ktime_get_ts(&now);
+		now_ns = timespec_to_ns(&now);
+		delta = user_ns.clock - now_ns;
+		kvm->arch.kvmclock_offset = delta;
+		break;
+	}
+	case KVM_GET_CLOCK: {
+		struct timespec now;
+		struct kvm_clock_data user_ns;
+		u64 now_ns;
+
+		ktime_get_ts(&now);
+		now_ns = timespec_to_ns(&now);
+		user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
+		user_ns.flags = 0;
+
+		r = -EFAULT;
+		if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
+			goto out;
+		r = 0;
+		break;
+	}
+
 	default:
 		;
 	}
@@ -2433,7 +2707,8 @@ static void kvm_init_msr_list(void)
 	u32 dummy[2];
 	unsigned i, j;
 
-	for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
+	/* skip the first msrs in the list. KVM-specific */
+	for (i = j = KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) {
 		if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
 			continue;
 		if (j < i)
@@ -2757,13 +3032,13 @@ static void cache_all_regs(struct kvm_vc
 }
 
 int emulate_instruction(struct kvm_vcpu *vcpu,
-			struct kvm_run *run,
 			unsigned long cr2,
 			u16 error_code,
 			int emulation_type)
 {
 	int r, shadow_mask;
 	struct decode_cache *c;
+	struct kvm_run *run = vcpu->run;
 
 	kvm_clear_exception_queue(vcpu);
 	vcpu->arch.mmio_fault_cr2 = cr2;
@@ -2783,7 +3058,7 @@ int emulate_instruction(struct kvm_vcpu
 		kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 
 		vcpu->arch.emulate_ctxt.vcpu = vcpu;
-		vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
+		vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu);
 		vcpu->arch.emulate_ctxt.mode =
 			(vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
 			? X86EMUL_MODE_REAL : cs_l
@@ -2861,7 +3136,7 @@ int emulate_instruction(struct kvm_vcpu
 		return EMULATE_DO_MMIO;
 	}
 
-	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+	kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
 
 	if (vcpu->mmio_is_write) {
 		vcpu->mmio_needed = 0;
@@ -2969,8 +3244,7 @@ static int pio_string_write(struct kvm_v
 	return r;
 }
 
-int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
-		  int size, unsigned port)
+int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port)
 {
 	unsigned long val;
 
@@ -2999,7 +3273,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_pio);
 
-int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
 		  int size, unsigned long count, int down,
 		  gva_t address, int rep, unsigned port)
 {
@@ -3072,9 +3346,6 @@ static void bounce_off(void *info)
 	/* nothing */
 }
 
-static unsigned int  ref_freq;
-static unsigned long tsc_khz_ref;
-
 static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 				     void *data)
 {
@@ -3083,14 +3354,11 @@ static int kvmclock_cpufreq_notifier(str
 	struct kvm_vcpu *vcpu;
 	int i, send_ipi = 0;
 
-	if (!ref_freq)
-		ref_freq = freq->old;
-
 	if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
 		return 0;
 	if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
 		return 0;
-	per_cpu(cpu_tsc_khz, freq->cpu) = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new);
+	per_cpu(cpu_tsc_khz, freq->cpu) = freq->new;
 
 	spin_lock(&kvm_lock);
 	list_for_each_entry(kvm, &vm_list, vm_list) {
@@ -3127,9 +3395,28 @@ static struct notifier_block kvmclock_cp
         .notifier_call  = kvmclock_cpufreq_notifier
 };
 
+static void kvm_timer_init(void)
+{
+	int cpu;
+
+	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+		cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
+					  CPUFREQ_TRANSITION_NOTIFIER);
+		for_each_online_cpu(cpu) {
+			unsigned long khz = cpufreq_get(cpu);
+			if (!khz)
+				khz = tsc_khz;
+			per_cpu(cpu_tsc_khz, cpu) = khz;
+		}
+	} else {
+		for_each_possible_cpu(cpu)
+			per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
+	}
+}
+
 int kvm_arch_init(void *opaque)
 {
-	int r, cpu;
+	int r;
 	struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
 
 	if (kvm_x86_ops) {
@@ -3161,13 +3448,7 @@ int kvm_arch_init(void *opaque)
 	kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
 			PT_DIRTY_MASK, PT64_NX_MASK, 0);
 
-	for_each_possible_cpu(cpu)
-		per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
-	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
-		tsc_khz_ref = tsc_khz;
-		cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
-					  CPUFREQ_TRANSITION_NOTIFIER);
-	}
+	kvm_timer_init();
 
 	return 0;
 
@@ -3295,7 +3576,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu
 		   unsigned long *rflags)
 {
 	kvm_lmsw(vcpu, msw);
-	*rflags = kvm_x86_ops->get_rflags(vcpu);
+	*rflags = kvm_get_rflags(vcpu);
 }
 
 unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
@@ -3333,7 +3614,7 @@ void realmode_set_cr(struct kvm_vcpu *vc
 	switch (cr) {
 	case 0:
 		kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
-		*rflags = kvm_x86_ops->get_rflags(vcpu);
+		*rflags = kvm_get_rflags(vcpu);
 		break;
 	case 2:
 		vcpu->arch.cr2 = val;
@@ -3453,18 +3734,18 @@ EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
  *
  * No need to exit to userspace if we already have an interrupt queued.
  */
-static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
-					  struct kvm_run *kvm_run)
+static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
 {
 	return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) &&
-		kvm_run->request_interrupt_window &&
+		vcpu->run->request_interrupt_window &&
 		kvm_arch_interrupt_allowed(vcpu));
 }
 
-static void post_kvm_run_save(struct kvm_vcpu *vcpu,
-			      struct kvm_run *kvm_run)
+static void post_kvm_run_save(struct kvm_vcpu *vcpu)
 {
-	kvm_run->if_flag = (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF) != 0;
+	struct kvm_run *kvm_run = vcpu->run;
+
+	kvm_run->if_flag = (kvm_get_rflags(vcpu) & X86_EFLAGS_IF) != 0;
 	kvm_run->cr8 = kvm_get_cr8(vcpu);
 	kvm_run->apic_base = kvm_get_apic_base(vcpu);
 	if (irqchip_in_kernel(vcpu->kvm))
@@ -3525,7 +3806,7 @@ static void update_cr8_intercept(struct
 	kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
 }
 
-static void inject_pending_event(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static void inject_pending_event(struct kvm_vcpu *vcpu)
 {
 	/* try to reinject previous events if any */
 	if (vcpu->arch.exception.pending) {
@@ -3561,11 +3842,11 @@ static void inject_pending_event(struct
 	}
 }
 
-static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 {
 	int r;
 	bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
-		kvm_run->request_interrupt_window;
+		vcpu->run->request_interrupt_window;
 
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
@@ -3586,12 +3867,12 @@ static int vcpu_enter_guest(struct kvm_v
 			kvm_x86_ops->tlb_flush(vcpu);
 		if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
 				       &vcpu->requests)) {
-			kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
+			vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS;
 			r = 0;
 			goto out;
 		}
 		if (test_and_clear_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests)) {
-			kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
+			vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
 			r = 0;
 			goto out;
 		}
@@ -3615,7 +3896,7 @@ static int vcpu_enter_guest(struct kvm_v
 		goto out;
 	}
 
-	inject_pending_event(vcpu, kvm_run);
+	inject_pending_event(vcpu);
 
 	/* enable NMI/IRQ window open exits if needed */
 	if (vcpu->arch.nmi_pending)
@@ -3641,16 +3922,17 @@ static int vcpu_enter_guest(struct kvm_v
 	}
 
 	trace_kvm_entry(vcpu->vcpu_id);
-	kvm_x86_ops->run(vcpu, kvm_run);
+	kvm_x86_ops->run(vcpu);
 
-	if (unlikely(vcpu->arch.switch_db_regs || test_thread_flag(TIF_DEBUG))) {
-		set_debugreg(current->thread.debugreg0, 0);
-		set_debugreg(current->thread.debugreg1, 1);
-		set_debugreg(current->thread.debugreg2, 2);
-		set_debugreg(current->thread.debugreg3, 3);
-		set_debugreg(current->thread.debugreg6, 6);
-		set_debugreg(current->thread.debugreg7, 7);
-	}
+	/*
+	 * If the guest has used debug registers, at least dr7
+	 * will be disabled while returning to the host.
+	 * If we don't have active breakpoints in the host, we don't
+	 * care about the messed up debug address registers. But if
+	 * we have some of them active, restore the old state.
+	 */
+	if (hw_breakpoint_active())
+		hw_breakpoint_restore();
 
 	set_bit(KVM_REQ_KICK, &vcpu->requests);
 	local_irq_enable();
@@ -3682,13 +3964,13 @@ static int vcpu_enter_guest(struct kvm_v
 
 	kvm_lapic_sync_from_vapic(vcpu);
 
-	r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
+	r = kvm_x86_ops->handle_exit(vcpu);
 out:
 	return r;
 }
 
 
-static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int __vcpu_run(struct kvm_vcpu *vcpu)
 {
 	int r;
 
@@ -3708,7 +3990,7 @@ static int __vcpu_run(struct kvm_vcpu *v
 	r = 1;
 	while (r > 0) {
 		if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
-			r = vcpu_enter_guest(vcpu, kvm_run);
+			r = vcpu_enter_guest(vcpu);
 		else {
 			up_read(&vcpu->kvm->slots_lock);
 			kvm_vcpu_block(vcpu);
@@ -3736,14 +4018,14 @@ static int __vcpu_run(struct kvm_vcpu *v
 		if (kvm_cpu_has_pending_timer(vcpu))
 			kvm_inject_pending_timer_irqs(vcpu);
 
-		if (dm_request_for_irq_injection(vcpu, kvm_run)) {
+		if (dm_request_for_irq_injection(vcpu)) {
 			r = -EINTR;
-			kvm_run->exit_reason = KVM_EXIT_INTR;
+			vcpu->run->exit_reason = KVM_EXIT_INTR;
 			++vcpu->stat.request_irq_exits;
 		}
 		if (signal_pending(current)) {
 			r = -EINTR;
-			kvm_run->exit_reason = KVM_EXIT_INTR;
+			vcpu->run->exit_reason = KVM_EXIT_INTR;
 			++vcpu->stat.signal_exits;
 		}
 		if (need_resched()) {
@@ -3754,7 +4036,7 @@ static int __vcpu_run(struct kvm_vcpu *v
 	}
 
 	up_read(&vcpu->kvm->slots_lock);
-	post_kvm_run_save(vcpu, kvm_run);
+	post_kvm_run_save(vcpu);
 
 	vapic_exit(vcpu);
 
@@ -3787,15 +4069,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 		if (r)
 			goto out;
 	}
-#if CONFIG_HAS_IOMEM
 	if (vcpu->mmio_needed) {
 		memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
 		vcpu->mmio_read_completed = 1;
 		vcpu->mmio_needed = 0;
 
 		down_read(&vcpu->kvm->slots_lock);
-		r = emulate_instruction(vcpu, kvm_run,
-					vcpu->arch.mmio_fault_cr2, 0,
+		r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0,
 					EMULTYPE_NO_DECODE);
 		up_read(&vcpu->kvm->slots_lock);
 		if (r == EMULATE_DO_MMIO) {
@@ -3806,12 +4086,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
 			goto out;
 		}
 	}
-#endif
 	if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL)
 		kvm_register_write(vcpu, VCPU_REGS_RAX,
 				     kvm_run->hypercall.ret);
 
-	r = __vcpu_run(vcpu, kvm_run);
+	r = __vcpu_run(vcpu);
 
 out:
 	if (vcpu->sigset_active)
@@ -3845,13 +4124,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 #endif
 
 	regs->rip = kvm_rip_read(vcpu);
-	regs->rflags = kvm_x86_ops->get_rflags(vcpu);
-
-	/*
-	 * Don't leak debug flags in case they were set for guest debugging
-	 */
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
+	regs->rflags = kvm_get_rflags(vcpu);
 
 	vcpu_put(vcpu);
 
@@ -3879,12 +4152,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	kvm_register_write(vcpu, VCPU_REGS_R13, regs->r13);
 	kvm_register_write(vcpu, VCPU_REGS_R14, regs->r14);
 	kvm_register_write(vcpu, VCPU_REGS_R15, regs->r15);
-
 #endif
 
 	kvm_rip_write(vcpu, regs->rip);
-	kvm_x86_ops->set_rflags(vcpu, regs->rflags);
-
+	kvm_set_rflags(vcpu, regs->rflags);
 
 	vcpu->arch.exception.pending = false;
 
@@ -4103,7 +4374,7 @@ static int is_vm86_segment(struct kvm_vc
 {
 	return (seg != VCPU_SREG_LDTR) &&
 		(seg != VCPU_SREG_TR) &&
-		(kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_VM);
+		(kvm_get_rflags(vcpu) & X86_EFLAGS_VM);
 }
 
 int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
@@ -4131,7 +4402,7 @@ static void save_state_to_tss32(struct k
 {
 	tss->cr3 = vcpu->arch.cr3;
 	tss->eip = kvm_rip_read(vcpu);
-	tss->eflags = kvm_x86_ops->get_rflags(vcpu);
+	tss->eflags = kvm_get_rflags(vcpu);
 	tss->eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	tss->ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
 	tss->edx = kvm_register_read(vcpu, VCPU_REGS_RDX);
@@ -4155,7 +4426,7 @@ static int load_state_from_tss32(struct
 	kvm_set_cr3(vcpu, tss->cr3);
 
 	kvm_rip_write(vcpu, tss->eip);
-	kvm_x86_ops->set_rflags(vcpu, tss->eflags | 2);
+	kvm_set_rflags(vcpu, tss->eflags | 2);
 
 	kvm_register_write(vcpu, VCPU_REGS_RAX, tss->eax);
 	kvm_register_write(vcpu, VCPU_REGS_RCX, tss->ecx);
@@ -4193,7 +4464,7 @@ static void save_state_to_tss16(struct k
 				struct tss_segment_16 *tss)
 {
 	tss->ip = kvm_rip_read(vcpu);
-	tss->flag = kvm_x86_ops->get_rflags(vcpu);
+	tss->flag = kvm_get_rflags(vcpu);
 	tss->ax = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	tss->cx = kvm_register_read(vcpu, VCPU_REGS_RCX);
 	tss->dx = kvm_register_read(vcpu, VCPU_REGS_RDX);
@@ -4208,14 +4479,13 @@ static void save_state_to_tss16(struct k
 	tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS);
 	tss->ds = get_segment_selector(vcpu, VCPU_SREG_DS);
 	tss->ldt = get_segment_selector(vcpu, VCPU_SREG_LDTR);
-	tss->prev_task_link = get_segment_selector(vcpu, VCPU_SREG_TR);
 }
 
 static int load_state_from_tss16(struct kvm_vcpu *vcpu,
 				 struct tss_segment_16 *tss)
 {
 	kvm_rip_write(vcpu, tss->ip);
-	kvm_x86_ops->set_rflags(vcpu, tss->flag | 2);
+	kvm_set_rflags(vcpu, tss->flag | 2);
 	kvm_register_write(vcpu, VCPU_REGS_RAX, tss->ax);
 	kvm_register_write(vcpu, VCPU_REGS_RCX, tss->cx);
 	kvm_register_write(vcpu, VCPU_REGS_RDX, tss->dx);
@@ -4361,8 +4631,8 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 	}
 
 	if (reason == TASK_SWITCH_IRET) {
-		u32 eflags = kvm_x86_ops->get_rflags(vcpu);
-		kvm_x86_ops->set_rflags(vcpu, eflags & ~X86_EFLAGS_NT);
+		u32 eflags = kvm_get_rflags(vcpu);
+		kvm_set_rflags(vcpu, eflags & ~X86_EFLAGS_NT);
 	}
 
 	/* set back link to prev task only if NT bit is set in eflags
@@ -4370,11 +4640,6 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 	if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
 		old_tss_sel = 0xffff;
 
-	/* set back link to prev task only if NT bit is set in eflags
-	   note that old_tss_sel is not used afetr this point */
-	if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
-		old_tss_sel = 0xffff;
-
 	if (nseg_desc.type & 8)
 		ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_sel,
 					 old_tss_base, &nseg_desc);
@@ -4383,8 +4648,8 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 					 old_tss_base, &nseg_desc);
 
 	if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) {
-		u32 eflags = kvm_x86_ops->get_rflags(vcpu);
-		kvm_x86_ops->set_rflags(vcpu, eflags | X86_EFLAGS_NT);
+		u32 eflags = kvm_get_rflags(vcpu);
+		kvm_set_rflags(vcpu, eflags | X86_EFLAGS_NT);
 	}
 
 	if (reason != TASK_SWITCH_IRET) {
@@ -4436,8 +4701,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 
 	mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
 	kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
-	if (!is_long_mode(vcpu) && is_pae(vcpu))
+	if (!is_long_mode(vcpu) && is_pae(vcpu)) {
 		load_pdptrs(vcpu, vcpu->arch.cr3);
+		mmu_reset_needed = 1;
+	}
 
 	if (mmu_reset_needed)
 		kvm_mmu_reset_context(vcpu);
@@ -4478,12 +4745,32 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 					struct kvm_guest_debug *dbg)
 {
+	unsigned long rflags;
 	int i, r;
 
 	vcpu_load(vcpu);
 
-	if ((dbg->control & (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP)) ==
-	    (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP)) {
+	if (dbg->control & (KVM_GUESTDBG_INJECT_DB | KVM_GUESTDBG_INJECT_BP)) {
+		r = -EBUSY;
+		if (vcpu->arch.exception.pending)
+			goto unlock_out;
+		if (dbg->control & KVM_GUESTDBG_INJECT_DB)
+			kvm_queue_exception(vcpu, DB_VECTOR);
+		else
+			kvm_queue_exception(vcpu, BP_VECTOR);
+	}
+
+	/*
+	 * Read rflags as long as potentially injected trace flags are still
+	 * filtered out.
+	 */
+	rflags = kvm_get_rflags(vcpu);
+
+	vcpu->guest_debug = dbg->control;
+	if (!(vcpu->guest_debug & KVM_GUESTDBG_ENABLE))
+		vcpu->guest_debug = 0;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
 		for (i = 0; i < KVM_NR_DB_REGS; ++i)
 			vcpu->arch.eff_db[i] = dbg->arch.debugreg[i];
 		vcpu->arch.switch_db_regs =
@@ -4494,13 +4781,23 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
 		vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK);
 	}
 
-	r = kvm_x86_ops->set_guest_debug(vcpu, dbg);
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+		vcpu->arch.singlestep_cs =
+			get_segment_selector(vcpu, VCPU_SREG_CS);
+		vcpu->arch.singlestep_rip = kvm_rip_read(vcpu);
+	}
 
-	if (dbg->control & KVM_GUESTDBG_INJECT_DB)
-		kvm_queue_exception(vcpu, DB_VECTOR);
-	else if (dbg->control & KVM_GUESTDBG_INJECT_BP)
-		kvm_queue_exception(vcpu, BP_VECTOR);
+	/*
+	 * Trigger an rflags update that will inject or remove the trace
+	 * flags.
+	 */
+	kvm_set_rflags(vcpu, rflags);
 
+	kvm_x86_ops->set_guest_debug(vcpu, dbg);
+
+	r = 0;
+
+unlock_out:
 	vcpu_put(vcpu);
 
 	return r;
@@ -4701,14 +4998,26 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu
 	return kvm_x86_ops->vcpu_reset(vcpu);
 }
 
-void kvm_arch_hardware_enable(void *garbage)
+int kvm_arch_hardware_enable(void *garbage)
 {
-	kvm_x86_ops->hardware_enable(garbage);
+	/*
+	 * Since this may be called from a hotplug notifcation,
+	 * we can't get the CPU frequency directly.
+	 */
+	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+		int cpu = raw_smp_processor_id();
+		per_cpu(cpu_tsc_khz, cpu) = 0;
+	}
+
+	kvm_shared_msr_cpu_online();
+
+	return kvm_x86_ops->hardware_enable(garbage);
 }
 
 void kvm_arch_hardware_disable(void *garbage)
 {
 	kvm_x86_ops->hardware_disable(garbage);
+	drop_user_return_notifiers(garbage);
 }
 
 int kvm_arch_hardware_setup(void)
@@ -4762,12 +5071,13 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 				       GFP_KERNEL);
 	if (!vcpu->arch.mce_banks) {
 		r = -ENOMEM;
-		goto fail_mmu_destroy;
+		goto fail_free_lapic;
 	}
 	vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS;
 
 	return 0;
-
+fail_free_lapic:
+	kvm_free_lapic(vcpu);
 fail_mmu_destroy:
 	kvm_mmu_destroy(vcpu);
 fail_free_pio_data:
@@ -4778,6 +5088,7 @@ fail:
 
 void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
+	kfree(vcpu->arch.mce_banks);
 	kvm_free_lapic(vcpu);
 	down_read(&vcpu->kvm->slots_lock);
 	kvm_mmu_destroy(vcpu);
@@ -4946,8 +5257,36 @@ int kvm_arch_interrupt_allowed(struct kv
 	return kvm_x86_ops->interrupt_allowed(vcpu);
 }
 
+unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu)
+{
+	unsigned long rflags;
+
+	rflags = kvm_x86_ops->get_rflags(vcpu);
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		rflags &= ~(unsigned long)(X86_EFLAGS_TF | X86_EFLAGS_RF);
+	return rflags;
+}
+EXPORT_SYMBOL_GPL(kvm_get_rflags);
+
+void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
+{
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP &&
+	    vcpu->arch.singlestep_cs ==
+			get_segment_selector(vcpu, VCPU_SREG_CS) &&
+	    vcpu->arch.singlestep_rip == kvm_rip_read(vcpu))
+		rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
+	kvm_x86_ops->set_rflags(vcpu, rflags);
+}
+EXPORT_SYMBOL_GPL(kvm_set_rflags);
+
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_cr);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmrun);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit_inject);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/copy_user_64.S linux-libre-2.6.33-gnu1/arch/x86/lib/copy_user_64.S
--- linux-libre-2.6.32-gnu1/arch/x86/lib/copy_user_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/copy_user_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,7 @@
 	.endm
 
 /* Standard copy_to_user with segment limit checking */
-ENTRY(copy_to_user)
+ENTRY(_copy_to_user)
 	CFI_STARTPROC
 	GET_THREAD_INFO(%rax)
 	movq %rdi,%rcx
@@ -75,10 +75,10 @@ ENTRY(copy_to_user)
 	jae bad_to_user
 	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
 	CFI_ENDPROC
-ENDPROC(copy_to_user)
+ENDPROC(_copy_to_user)
 
 /* Standard copy_from_user with segment limit checking */
-ENTRY(copy_from_user)
+ENTRY(_copy_from_user)
 	CFI_STARTPROC
 	GET_THREAD_INFO(%rax)
 	movq %rsi,%rcx
@@ -88,7 +88,7 @@ ENTRY(copy_from_user)
 	jae bad_from_user
 	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
 	CFI_ENDPROC
-ENDPROC(copy_from_user)
+ENDPROC(_copy_from_user)
 
 ENTRY(copy_user_generic)
 	CFI_STARTPROC
@@ -96,12 +96,6 @@ ENTRY(copy_user_generic)
 	CFI_ENDPROC
 ENDPROC(copy_user_generic)
 
-ENTRY(__copy_from_user_inatomic)
-	CFI_STARTPROC
-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
-	CFI_ENDPROC
-ENDPROC(__copy_from_user_inatomic)
-
 	.section .fixup,"ax"
 	/* must zero dest */
 ENTRY(bad_from_user)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/.gitignore linux-libre-2.6.33-gnu1/arch/x86/lib/.gitignore
--- linux-libre-2.6.32-gnu1/arch/x86/lib/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/.gitignore	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+inat-tables.c
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/inat.c linux-libre-2.6.33-gnu1/arch/x86/lib/inat.c
--- linux-libre-2.6.32-gnu1/arch/x86/lib/inat.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/inat.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,90 @@
+/*
+ * x86 instruction attribute tables
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <asm/insn.h>
+
+/* Attribute tables are generated from opcode map */
+#include "inat-tables.c"
+
+/* Attribute search APIs */
+insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
+{
+	return inat_primary_table[opcode];
+}
+
+insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
+				      insn_attr_t esc_attr)
+{
+	const insn_attr_t *table;
+	insn_attr_t lpfx_attr;
+	int n, m = 0;
+
+	n = inat_escape_id(esc_attr);
+	if (last_pfx) {
+		lpfx_attr = inat_get_opcode_attribute(last_pfx);
+		m = inat_last_prefix_id(lpfx_attr);
+	}
+	table = inat_escape_tables[n][0];
+	if (!table)
+		return 0;
+	if (inat_has_variant(table[opcode]) && m) {
+		table = inat_escape_tables[n][m];
+		if (!table)
+			return 0;
+	}
+	return table[opcode];
+}
+
+insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
+				     insn_attr_t grp_attr)
+{
+	const insn_attr_t *table;
+	insn_attr_t lpfx_attr;
+	int n, m = 0;
+
+	n = inat_group_id(grp_attr);
+	if (last_pfx) {
+		lpfx_attr = inat_get_opcode_attribute(last_pfx);
+		m = inat_last_prefix_id(lpfx_attr);
+	}
+	table = inat_group_tables[n][0];
+	if (!table)
+		return inat_group_common_attribute(grp_attr);
+	if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
+		table = inat_group_tables[n][m];
+		if (!table)
+			return inat_group_common_attribute(grp_attr);
+	}
+	return table[X86_MODRM_REG(modrm)] |
+	       inat_group_common_attribute(grp_attr);
+}
+
+insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
+				   insn_byte_t vex_p)
+{
+	const insn_attr_t *table;
+	if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
+		return 0;
+	table = inat_avx_tables[vex_m][vex_p];
+	if (!table)
+		return 0;
+	return table[opcode];
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/insn.c linux-libre-2.6.33-gnu1/arch/x86/lib/insn.c
--- linux-libre-2.6.32-gnu1/arch/x86/lib/insn.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/insn.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,516 @@
+/*
+ * x86 instruction analysis
+ *
+ * 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) IBM Corporation, 2002, 2004, 2009
+ */
+
+#include <linux/string.h>
+#include <asm/inat.h>
+#include <asm/insn.h>
+
+#define get_next(t, insn)	\
+	({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
+
+#define peek_next(t, insn)	\
+	({t r; r = *(t*)insn->next_byte; r; })
+
+#define peek_nbyte_next(t, insn, n)	\
+	({t r; r = *(t*)((insn)->next_byte + n); r; })
+
+/**
+ * insn_init() - initialize struct insn
+ * @insn:	&struct insn to be initialized
+ * @kaddr:	address (in kernel memory) of instruction (or copy thereof)
+ * @x86_64:	!0 for 64-bit kernel or 64-bit app
+ */
+void insn_init(struct insn *insn, const void *kaddr, int x86_64)
+{
+	memset(insn, 0, sizeof(*insn));
+	insn->kaddr = kaddr;
+	insn->next_byte = kaddr;
+	insn->x86_64 = x86_64 ? 1 : 0;
+	insn->opnd_bytes = 4;
+	if (x86_64)
+		insn->addr_bytes = 8;
+	else
+		insn->addr_bytes = 4;
+}
+
+/**
+ * insn_get_prefixes - scan x86 instruction prefix bytes
+ * @insn:	&struct insn containing instruction
+ *
+ * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
+ * to point to the (first) opcode.  No effect if @insn->prefixes.got
+ * is already set.
+ */
+void insn_get_prefixes(struct insn *insn)
+{
+	struct insn_field *prefixes = &insn->prefixes;
+	insn_attr_t attr;
+	insn_byte_t b, lb;
+	int i, nb;
+
+	if (prefixes->got)
+		return;
+
+	nb = 0;
+	lb = 0;
+	b = peek_next(insn_byte_t, insn);
+	attr = inat_get_opcode_attribute(b);
+	while (inat_is_legacy_prefix(attr)) {
+		/* Skip if same prefix */
+		for (i = 0; i < nb; i++)
+			if (prefixes->bytes[i] == b)
+				goto found;
+		if (nb == 4)
+			/* Invalid instruction */
+			break;
+		prefixes->bytes[nb++] = b;
+		if (inat_is_address_size_prefix(attr)) {
+			/* address size switches 2/4 or 4/8 */
+			if (insn->x86_64)
+				insn->addr_bytes ^= 12;
+			else
+				insn->addr_bytes ^= 6;
+		} else if (inat_is_operand_size_prefix(attr)) {
+			/* oprand size switches 2/4 */
+			insn->opnd_bytes ^= 6;
+		}
+found:
+		prefixes->nbytes++;
+		insn->next_byte++;
+		lb = b;
+		b = peek_next(insn_byte_t, insn);
+		attr = inat_get_opcode_attribute(b);
+	}
+	/* Set the last prefix */
+	if (lb && lb != insn->prefixes.bytes[3]) {
+		if (unlikely(insn->prefixes.bytes[3])) {
+			/* Swap the last prefix */
+			b = insn->prefixes.bytes[3];
+			for (i = 0; i < nb; i++)
+				if (prefixes->bytes[i] == lb)
+					prefixes->bytes[i] = b;
+		}
+		insn->prefixes.bytes[3] = lb;
+	}
+
+	/* Decode REX prefix */
+	if (insn->x86_64) {
+		b = peek_next(insn_byte_t, insn);
+		attr = inat_get_opcode_attribute(b);
+		if (inat_is_rex_prefix(attr)) {
+			insn->rex_prefix.value = b;
+			insn->rex_prefix.nbytes = 1;
+			insn->next_byte++;
+			if (X86_REX_W(b))
+				/* REX.W overrides opnd_size */
+				insn->opnd_bytes = 8;
+		}
+	}
+	insn->rex_prefix.got = 1;
+
+	/* Decode VEX prefix */
+	b = peek_next(insn_byte_t, insn);
+	attr = inat_get_opcode_attribute(b);
+	if (inat_is_vex_prefix(attr)) {
+		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
+		if (!insn->x86_64) {
+			/*
+			 * In 32-bits mode, if the [7:6] bits (mod bits of
+			 * ModRM) on the second byte are not 11b, it is
+			 * LDS or LES.
+			 */
+			if (X86_MODRM_MOD(b2) != 3)
+				goto vex_end;
+		}
+		insn->vex_prefix.bytes[0] = b;
+		insn->vex_prefix.bytes[1] = b2;
+		if (inat_is_vex3_prefix(attr)) {
+			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+			insn->vex_prefix.bytes[2] = b2;
+			insn->vex_prefix.nbytes = 3;
+			insn->next_byte += 3;
+			if (insn->x86_64 && X86_VEX_W(b2))
+				/* VEX.W overrides opnd_size */
+				insn->opnd_bytes = 8;
+		} else {
+			insn->vex_prefix.nbytes = 2;
+			insn->next_byte += 2;
+		}
+	}
+vex_end:
+	insn->vex_prefix.got = 1;
+
+	prefixes->got = 1;
+	return;
+}
+
+/**
+ * insn_get_opcode - collect opcode(s)
+ * @insn:	&struct insn containing instruction
+ *
+ * Populates @insn->opcode, updates @insn->next_byte to point past the
+ * opcode byte(s), and set @insn->attr (except for groups).
+ * If necessary, first collects any preceding (prefix) bytes.
+ * Sets @insn->opcode.value = opcode1.  No effect if @insn->opcode.got
+ * is already 1.
+ */
+void insn_get_opcode(struct insn *insn)
+{
+	struct insn_field *opcode = &insn->opcode;
+	insn_byte_t op, pfx;
+	if (opcode->got)
+		return;
+	if (!insn->prefixes.got)
+		insn_get_prefixes(insn);
+
+	/* Get first opcode */
+	op = get_next(insn_byte_t, insn);
+	opcode->bytes[0] = op;
+	opcode->nbytes = 1;
+
+	/* Check if there is VEX prefix or not */
+	if (insn_is_avx(insn)) {
+		insn_byte_t m, p;
+		m = insn_vex_m_bits(insn);
+		p = insn_vex_p_bits(insn);
+		insn->attr = inat_get_avx_attribute(op, m, p);
+		if (!inat_accept_vex(insn->attr))
+			insn->attr = 0;	/* This instruction is bad */
+		goto end;	/* VEX has only 1 byte for opcode */
+	}
+
+	insn->attr = inat_get_opcode_attribute(op);
+	while (inat_is_escape(insn->attr)) {
+		/* Get escaped opcode */
+		op = get_next(insn_byte_t, insn);
+		opcode->bytes[opcode->nbytes++] = op;
+		pfx = insn_last_prefix(insn);
+		insn->attr = inat_get_escape_attribute(op, pfx, insn->attr);
+	}
+	if (inat_must_vex(insn->attr))
+		insn->attr = 0;	/* This instruction is bad */
+end:
+	opcode->got = 1;
+}
+
+/**
+ * insn_get_modrm - collect ModRM byte, if any
+ * @insn:	&struct insn containing instruction
+ *
+ * Populates @insn->modrm and updates @insn->next_byte to point past the
+ * ModRM byte, if any.  If necessary, first collects the preceding bytes
+ * (prefixes and opcode(s)).  No effect if @insn->modrm.got is already 1.
+ */
+void insn_get_modrm(struct insn *insn)
+{
+	struct insn_field *modrm = &insn->modrm;
+	insn_byte_t pfx, mod;
+	if (modrm->got)
+		return;
+	if (!insn->opcode.got)
+		insn_get_opcode(insn);
+
+	if (inat_has_modrm(insn->attr)) {
+		mod = get_next(insn_byte_t, insn);
+		modrm->value = mod;
+		modrm->nbytes = 1;
+		if (inat_is_group(insn->attr)) {
+			pfx = insn_last_prefix(insn);
+			insn->attr = inat_get_group_attribute(mod, pfx,
+							      insn->attr);
+		}
+	}
+
+	if (insn->x86_64 && inat_is_force64(insn->attr))
+		insn->opnd_bytes = 8;
+	modrm->got = 1;
+}
+
+
+/**
+ * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
+ * @insn:	&struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * ModRM byte.  No effect if @insn->x86_64 is 0.
+ */
+int insn_rip_relative(struct insn *insn)
+{
+	struct insn_field *modrm = &insn->modrm;
+
+	if (!insn->x86_64)
+		return 0;
+	if (!modrm->got)
+		insn_get_modrm(insn);
+	/*
+	 * For rip-relative instructions, the mod field (top 2 bits)
+	 * is zero and the r/m field (bottom 3 bits) is 0x5.
+	 */
+	return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
+}
+
+/**
+ * insn_get_sib() - Get the SIB byte of instruction
+ * @insn:	&struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * ModRM byte.
+ */
+void insn_get_sib(struct insn *insn)
+{
+	insn_byte_t modrm;
+
+	if (insn->sib.got)
+		return;
+	if (!insn->modrm.got)
+		insn_get_modrm(insn);
+	if (insn->modrm.nbytes) {
+		modrm = (insn_byte_t)insn->modrm.value;
+		if (insn->addr_bytes != 2 &&
+		    X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
+			insn->sib.value = get_next(insn_byte_t, insn);
+			insn->sib.nbytes = 1;
+		}
+	}
+	insn->sib.got = 1;
+}
+
+
+/**
+ * insn_get_displacement() - Get the displacement of instruction
+ * @insn:	&struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * SIB byte.
+ * Displacement value is sign-expanded.
+ */
+void insn_get_displacement(struct insn *insn)
+{
+	insn_byte_t mod, rm, base;
+
+	if (insn->displacement.got)
+		return;
+	if (!insn->sib.got)
+		insn_get_sib(insn);
+	if (insn->modrm.nbytes) {
+		/*
+		 * Interpreting the modrm byte:
+		 * mod = 00 - no displacement fields (exceptions below)
+		 * mod = 01 - 1-byte displacement field
+		 * mod = 10 - displacement field is 4 bytes, or 2 bytes if
+		 * 	address size = 2 (0x67 prefix in 32-bit mode)
+		 * mod = 11 - no memory operand
+		 *
+		 * If address size = 2...
+		 * mod = 00, r/m = 110 - displacement field is 2 bytes
+		 *
+		 * If address size != 2...
+		 * mod != 11, r/m = 100 - SIB byte exists
+		 * mod = 00, SIB base = 101 - displacement field is 4 bytes
+		 * mod = 00, r/m = 101 - rip-relative addressing, displacement
+		 * 	field is 4 bytes
+		 */
+		mod = X86_MODRM_MOD(insn->modrm.value);
+		rm = X86_MODRM_RM(insn->modrm.value);
+		base = X86_SIB_BASE(insn->sib.value);
+		if (mod == 3)
+			goto out;
+		if (mod == 1) {
+			insn->displacement.value = get_next(char, insn);
+			insn->displacement.nbytes = 1;
+		} else if (insn->addr_bytes == 2) {
+			if ((mod == 0 && rm == 6) || mod == 2) {
+				insn->displacement.value =
+					 get_next(short, insn);
+				insn->displacement.nbytes = 2;
+			}
+		} else {
+			if ((mod == 0 && rm == 5) || mod == 2 ||
+			    (mod == 0 && base == 5)) {
+				insn->displacement.value = get_next(int, insn);
+				insn->displacement.nbytes = 4;
+			}
+		}
+	}
+out:
+	insn->displacement.got = 1;
+}
+
+/* Decode moffset16/32/64 */
+static void __get_moffset(struct insn *insn)
+{
+	switch (insn->addr_bytes) {
+	case 2:
+		insn->moffset1.value = get_next(short, insn);
+		insn->moffset1.nbytes = 2;
+		break;
+	case 4:
+		insn->moffset1.value = get_next(int, insn);
+		insn->moffset1.nbytes = 4;
+		break;
+	case 8:
+		insn->moffset1.value = get_next(int, insn);
+		insn->moffset1.nbytes = 4;
+		insn->moffset2.value = get_next(int, insn);
+		insn->moffset2.nbytes = 4;
+		break;
+	}
+	insn->moffset1.got = insn->moffset2.got = 1;
+}
+
+/* Decode imm v32(Iz) */
+static void __get_immv32(struct insn *insn)
+{
+	switch (insn->opnd_bytes) {
+	case 2:
+		insn->immediate.value = get_next(short, insn);
+		insn->immediate.nbytes = 2;
+		break;
+	case 4:
+	case 8:
+		insn->immediate.value = get_next(int, insn);
+		insn->immediate.nbytes = 4;
+		break;
+	}
+}
+
+/* Decode imm v64(Iv/Ov) */
+static void __get_immv(struct insn *insn)
+{
+	switch (insn->opnd_bytes) {
+	case 2:
+		insn->immediate1.value = get_next(short, insn);
+		insn->immediate1.nbytes = 2;
+		break;
+	case 4:
+		insn->immediate1.value = get_next(int, insn);
+		insn->immediate1.nbytes = 4;
+		break;
+	case 8:
+		insn->immediate1.value = get_next(int, insn);
+		insn->immediate1.nbytes = 4;
+		insn->immediate2.value = get_next(int, insn);
+		insn->immediate2.nbytes = 4;
+		break;
+	}
+	insn->immediate1.got = insn->immediate2.got = 1;
+}
+
+/* Decode ptr16:16/32(Ap) */
+static void __get_immptr(struct insn *insn)
+{
+	switch (insn->opnd_bytes) {
+	case 2:
+		insn->immediate1.value = get_next(short, insn);
+		insn->immediate1.nbytes = 2;
+		break;
+	case 4:
+		insn->immediate1.value = get_next(int, insn);
+		insn->immediate1.nbytes = 4;
+		break;
+	case 8:
+		/* ptr16:64 is not exist (no segment) */
+		return;
+	}
+	insn->immediate2.value = get_next(unsigned short, insn);
+	insn->immediate2.nbytes = 2;
+	insn->immediate1.got = insn->immediate2.got = 1;
+}
+
+/**
+ * insn_get_immediate() - Get the immediates of instruction
+ * @insn:	&struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * displacement bytes.
+ * Basically, most of immediates are sign-expanded. Unsigned-value can be
+ * get by bit masking with ((1 << (nbytes * 8)) - 1)
+ */
+void insn_get_immediate(struct insn *insn)
+{
+	if (insn->immediate.got)
+		return;
+	if (!insn->displacement.got)
+		insn_get_displacement(insn);
+
+	if (inat_has_moffset(insn->attr)) {
+		__get_moffset(insn);
+		goto done;
+	}
+
+	if (!inat_has_immediate(insn->attr))
+		/* no immediates */
+		goto done;
+
+	switch (inat_immediate_size(insn->attr)) {
+	case INAT_IMM_BYTE:
+		insn->immediate.value = get_next(char, insn);
+		insn->immediate.nbytes = 1;
+		break;
+	case INAT_IMM_WORD:
+		insn->immediate.value = get_next(short, insn);
+		insn->immediate.nbytes = 2;
+		break;
+	case INAT_IMM_DWORD:
+		insn->immediate.value = get_next(int, insn);
+		insn->immediate.nbytes = 4;
+		break;
+	case INAT_IMM_QWORD:
+		insn->immediate1.value = get_next(int, insn);
+		insn->immediate1.nbytes = 4;
+		insn->immediate2.value = get_next(int, insn);
+		insn->immediate2.nbytes = 4;
+		break;
+	case INAT_IMM_PTR:
+		__get_immptr(insn);
+		break;
+	case INAT_IMM_VWORD32:
+		__get_immv32(insn);
+		break;
+	case INAT_IMM_VWORD:
+		__get_immv(insn);
+		break;
+	default:
+		break;
+	}
+	if (inat_has_second_immediate(insn->attr)) {
+		insn->immediate2.value = get_next(char, insn);
+		insn->immediate2.nbytes = 1;
+	}
+done:
+	insn->immediate.got = 1;
+}
+
+/**
+ * insn_get_length() - Get the length of instruction
+ * @insn:	&struct insn containing instruction
+ *
+ * If necessary, first collects the instruction up to and including the
+ * immediates bytes.
+ */
+void insn_get_length(struct insn *insn)
+{
+	if (insn->length)
+		return;
+	if (!insn->immediate.got)
+		insn_get_immediate(insn);
+	insn->length = (unsigned char)((unsigned long)insn->next_byte
+				     - (unsigned long)insn->kaddr);
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/Makefile linux-libre-2.6.33-gnu1/arch/x86/lib/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/lib/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,14 +2,27 @@
 # Makefile for x86 specific library files.
 #
 
-obj-$(CONFIG_SMP) := msr.o
+inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
+inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
+quiet_cmd_inat_tables = GEN     $@
+      cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@
+
+$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
+	$(call cmd,inat_tables)
+
+$(obj)/inat.o: $(obj)/inat-tables.c
+
+clean-files := inat-tables.c
+
+obj-$(CONFIG_SMP) += msr-smp.o
 
 lib-y := delay.o
 lib-y += thunk_$(BITS).o
 lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
+lib-$(CONFIG_KPROBES) += insn.o inat.o
 
-obj-y += msr-reg.o msr-reg-export.o
+obj-y += msr.o msr-reg.o msr-reg-export.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/msr.c linux-libre-2.6.33-gnu1/arch/x86/lib/msr.c
--- linux-libre-2.6.32-gnu1/arch/x86/lib/msr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/msr.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,226 +1,23 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
-#include <linux/smp.h>
 #include <asm/msr.h>
 
-struct msr_info {
-	u32 msr_no;
-	struct msr reg;
-	struct msr *msrs;
-	int off;
-	int err;
-};
-
-static void __rdmsr_on_cpu(void *info)
-{
-	struct msr_info *rv = info;
-	struct msr *reg;
-	int this_cpu = raw_smp_processor_id();
-
-	if (rv->msrs)
-		reg = &rv->msrs[this_cpu - rv->off];
-	else
-		reg = &rv->reg;
-
-	rdmsr(rv->msr_no, reg->l, reg->h);
-}
-
-static void __wrmsr_on_cpu(void *info)
-{
-	struct msr_info *rv = info;
-	struct msr *reg;
-	int this_cpu = raw_smp_processor_id();
-
-	if (rv->msrs)
-		reg = &rv->msrs[this_cpu - rv->off];
-	else
-		reg = &rv->reg;
-
-	wrmsr(rv->msr_no, reg->l, reg->h);
-}
-
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-	int err;
-	struct msr_info rv;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.msr_no = msr_no;
-	err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
-	*l = rv.reg.l;
-	*h = rv.reg.h;
-
-	return err;
-}
-EXPORT_SYMBOL(rdmsr_on_cpu);
-
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-	int err;
-	struct msr_info rv;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.msr_no = msr_no;
-	rv.reg.l = l;
-	rv.reg.h = h;
-	err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
-
-	return err;
-}
-EXPORT_SYMBOL(wrmsr_on_cpu);
-
-/* rdmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
-{
-	struct msr_info rv;
-	int this_cpu;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.off    = cpumask_first(mask);
-	rv.msrs	  = msrs;
-	rv.msr_no = msr_no;
-
-	this_cpu = get_cpu();
-
-	if (cpumask_test_cpu(this_cpu, mask))
-		__rdmsr_on_cpu(&rv);
-
-	smp_call_function_many(mask, __rdmsr_on_cpu, &rv, 1);
-	put_cpu();
-}
-EXPORT_SYMBOL(rdmsr_on_cpus);
-
-/*
- * wrmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs)
-{
-	struct msr_info rv;
-	int this_cpu;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.off    = cpumask_first(mask);
-	rv.msrs   = msrs;
-	rv.msr_no = msr_no;
-
-	this_cpu = get_cpu();
-
-	if (cpumask_test_cpu(this_cpu, mask))
-		__wrmsr_on_cpu(&rv);
-
-	smp_call_function_many(mask, __wrmsr_on_cpu, &rv, 1);
-	put_cpu();
-}
-EXPORT_SYMBOL(wrmsr_on_cpus);
-
-/* These "safe" variants are slower and should be used when the target MSR
-   may not actually exist. */
-static void __rdmsr_safe_on_cpu(void *info)
-{
-	struct msr_info *rv = info;
-
-	rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
-}
-
-static void __wrmsr_safe_on_cpu(void *info)
-{
-	struct msr_info *rv = info;
-
-	rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
-}
-
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-	int err;
-	struct msr_info rv;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.msr_no = msr_no;
-	err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
-	*l = rv.reg.l;
-	*h = rv.reg.h;
-
-	return err ? err : rv.err;
-}
-EXPORT_SYMBOL(rdmsr_safe_on_cpu);
-
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-	int err;
-	struct msr_info rv;
-
-	memset(&rv, 0, sizeof(rv));
-
-	rv.msr_no = msr_no;
-	rv.reg.l = l;
-	rv.reg.h = h;
-	err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
-
-	return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_on_cpu);
-
-/*
- * These variants are significantly slower, but allows control over
- * the entire 32-bit GPR set.
- */
-struct msr_regs_info {
-	u32 *regs;
-	int err;
-};
-
-static void __rdmsr_safe_regs_on_cpu(void *info)
-{
-	struct msr_regs_info *rv = info;
-
-	rv->err = rdmsr_safe_regs(rv->regs);
-}
-
-static void __wrmsr_safe_regs_on_cpu(void *info)
-{
-	struct msr_regs_info *rv = info;
-
-	rv->err = wrmsr_safe_regs(rv->regs);
-}
-
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+struct msr *msrs_alloc(void)
 {
-	int err;
-	struct msr_regs_info rv;
+	struct msr *msrs = NULL;
 
-	rv.regs   = regs;
-	rv.err    = -EIO;
-	err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+	msrs = alloc_percpu(struct msr);
+	if (!msrs) {
+		pr_warning("%s: error allocating msrs\n", __func__);
+		return NULL;
+	}
 
-	return err ? err : rv.err;
+	return msrs;
 }
-EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+EXPORT_SYMBOL(msrs_alloc);
 
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+void msrs_free(struct msr *msrs)
 {
-	int err;
-	struct msr_regs_info rv;
-
-	rv.regs = regs;
-	rv.err  = -EIO;
-	err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
-
-	return err ? err : rv.err;
+	free_percpu(msrs);
 }
-EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
+EXPORT_SYMBOL(msrs_free);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/msr-smp.c linux-libre-2.6.33-gnu1/arch/x86/lib/msr-smp.c
--- linux-libre-2.6.32-gnu1/arch/x86/lib/msr-smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/msr-smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,204 @@
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/smp.h>
+#include <asm/msr.h>
+
+static void __rdmsr_on_cpu(void *info)
+{
+	struct msr_info *rv = info;
+	struct msr *reg;
+	int this_cpu = raw_smp_processor_id();
+
+	if (rv->msrs)
+		reg = per_cpu_ptr(rv->msrs, this_cpu);
+	else
+		reg = &rv->reg;
+
+	rdmsr(rv->msr_no, reg->l, reg->h);
+}
+
+static void __wrmsr_on_cpu(void *info)
+{
+	struct msr_info *rv = info;
+	struct msr *reg;
+	int this_cpu = raw_smp_processor_id();
+
+	if (rv->msrs)
+		reg = per_cpu_ptr(rv->msrs, this_cpu);
+	else
+		reg = &rv->reg;
+
+	wrmsr(rv->msr_no, reg->l, reg->h);
+}
+
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+	int err;
+	struct msr_info rv;
+
+	memset(&rv, 0, sizeof(rv));
+
+	rv.msr_no = msr_no;
+	err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
+	*l = rv.reg.l;
+	*h = rv.reg.h;
+
+	return err;
+}
+EXPORT_SYMBOL(rdmsr_on_cpu);
+
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+	int err;
+	struct msr_info rv;
+
+	memset(&rv, 0, sizeof(rv));
+
+	rv.msr_no = msr_no;
+	rv.reg.l = l;
+	rv.reg.h = h;
+	err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
+
+	return err;
+}
+EXPORT_SYMBOL(wrmsr_on_cpu);
+
+static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
+			    struct msr *msrs,
+			    void (*msr_func) (void *info))
+{
+	struct msr_info rv;
+	int this_cpu;
+
+	memset(&rv, 0, sizeof(rv));
+
+	rv.msrs	  = msrs;
+	rv.msr_no = msr_no;
+
+	this_cpu = get_cpu();
+
+	if (cpumask_test_cpu(this_cpu, mask))
+		msr_func(&rv);
+
+	smp_call_function_many(mask, msr_func, &rv, 1);
+	put_cpu();
+}
+
+/* rdmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+	__rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
+}
+EXPORT_SYMBOL(rdmsr_on_cpus);
+
+/*
+ * wrmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+	__rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
+}
+EXPORT_SYMBOL(wrmsr_on_cpus);
+
+/* These "safe" variants are slower and should be used when the target MSR
+   may not actually exist. */
+static void __rdmsr_safe_on_cpu(void *info)
+{
+	struct msr_info *rv = info;
+
+	rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
+}
+
+static void __wrmsr_safe_on_cpu(void *info)
+{
+	struct msr_info *rv = info;
+
+	rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
+}
+
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+	int err;
+	struct msr_info rv;
+
+	memset(&rv, 0, sizeof(rv));
+
+	rv.msr_no = msr_no;
+	err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
+	*l = rv.reg.l;
+	*h = rv.reg.h;
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+	int err;
+	struct msr_info rv;
+
+	memset(&rv, 0, sizeof(rv));
+
+	rv.msr_no = msr_no;
+	rv.reg.l = l;
+	rv.reg.h = h;
+	err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_on_cpu);
+
+/*
+ * These variants are significantly slower, but allows control over
+ * the entire 32-bit GPR set.
+ */
+static void __rdmsr_safe_regs_on_cpu(void *info)
+{
+	struct msr_regs_info *rv = info;
+
+	rv->err = rdmsr_safe_regs(rv->regs);
+}
+
+static void __wrmsr_safe_regs_on_cpu(void *info)
+{
+	struct msr_regs_info *rv = info;
+
+	rv->err = wrmsr_safe_regs(rv->regs);
+}
+
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+	int err;
+	struct msr_regs_info rv;
+
+	rv.regs   = regs;
+	rv.err    = -EIO;
+	err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+	int err;
+	struct msr_regs_info rv;
+
+	rv.regs = regs;
+	rv.err  = -EIO;
+	err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/usercopy_32.c linux-libre-2.6.33-gnu1/arch/x86/lib/usercopy_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/lib/usercopy_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/usercopy_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -874,7 +874,7 @@ EXPORT_SYMBOL(copy_to_user);
  * data to the requested size using zero bytes.
  */
 unsigned long
-copy_from_user(void *to, const void __user *from, unsigned long n)
+_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	if (access_ok(VERIFY_READ, from, n))
 		n = __copy_from_user(to, from, n);
@@ -882,4 +882,10 @@ copy_from_user(void *to, const void __us
 		memset(to, 0, n);
 	return n;
 }
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(_copy_from_user);
+
+void copy_from_user_overflow(void)
+{
+	WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/lib/x86-opcode-map.txt linux-libre-2.6.33-gnu1/arch/x86/lib/x86-opcode-map.txt
--- linux-libre-2.6.32-gnu1/arch/x86/lib/x86-opcode-map.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/lib/x86-opcode-map.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,893 @@
+# x86 Opcode Maps
+#
+#<Opcode maps>
+# Table: table-name
+# Referrer: escaped-name
+# AVXcode: avx-code
+# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
+# (or)
+# opcode: escape # escaped-name
+# EndTable
+#
+#<group maps>
+# GrpTable: GrpXXX
+# reg:  mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
+# EndTable
+#
+# AVX Superscripts
+#  (VEX): this opcode can accept VEX prefix.
+#  (oVEX): this opcode requires VEX prefix.
+#  (o128): this opcode only supports 128bit VEX.
+#  (o256): this opcode only supports 256bit VEX.
+#
+
+Table: one byte opcode
+Referrer:
+AVXcode:
+# 0x00 - 0x0f
+00: ADD Eb,Gb
+01: ADD Ev,Gv
+02: ADD Gb,Eb
+03: ADD Gv,Ev
+04: ADD AL,Ib
+05: ADD rAX,Iz
+06: PUSH ES (i64)
+07: POP ES (i64)
+08: OR Eb,Gb
+09: OR Ev,Gv
+0a: OR Gb,Eb
+0b: OR Gv,Ev
+0c: OR AL,Ib
+0d: OR rAX,Iz
+0e: PUSH CS (i64)
+0f: escape # 2-byte escape
+# 0x10 - 0x1f
+10: ADC Eb,Gb
+11: ADC Ev,Gv
+12: ADC Gb,Eb
+13: ADC Gv,Ev
+14: ADC AL,Ib
+15: ADC rAX,Iz
+16: PUSH SS (i64)
+17: POP SS (i64)
+18: SBB Eb,Gb
+19: SBB Ev,Gv
+1a: SBB Gb,Eb
+1b: SBB Gv,Ev
+1c: SBB AL,Ib
+1d: SBB rAX,Iz
+1e: PUSH DS (i64)
+1f: POP DS (i64)
+# 0x20 - 0x2f
+20: AND Eb,Gb
+21: AND Ev,Gv
+22: AND Gb,Eb
+23: AND Gv,Ev
+24: AND AL,Ib
+25: AND rAx,Iz
+26: SEG=ES (Prefix)
+27: DAA (i64)
+28: SUB Eb,Gb
+29: SUB Ev,Gv
+2a: SUB Gb,Eb
+2b: SUB Gv,Ev
+2c: SUB AL,Ib
+2d: SUB rAX,Iz
+2e: SEG=CS (Prefix)
+2f: DAS (i64)
+# 0x30 - 0x3f
+30: XOR Eb,Gb
+31: XOR Ev,Gv
+32: XOR Gb,Eb
+33: XOR Gv,Ev
+34: XOR AL,Ib
+35: XOR rAX,Iz
+36: SEG=SS (Prefix)
+37: AAA (i64)
+38: CMP Eb,Gb
+39: CMP Ev,Gv
+3a: CMP Gb,Eb
+3b: CMP Gv,Ev
+3c: CMP AL,Ib
+3d: CMP rAX,Iz
+3e: SEG=DS (Prefix)
+3f: AAS (i64)
+# 0x40 - 0x4f
+40: INC eAX (i64) | REX (o64)
+41: INC eCX (i64) | REX.B (o64)
+42: INC eDX (i64) | REX.X (o64)
+43: INC eBX (i64) | REX.XB (o64)
+44: INC eSP (i64) | REX.R (o64)
+45: INC eBP (i64) | REX.RB (o64)
+46: INC eSI (i64) | REX.RX (o64)
+47: INC eDI (i64) | REX.RXB (o64)
+48: DEC eAX (i64) | REX.W (o64)
+49: DEC eCX (i64) | REX.WB (o64)
+4a: DEC eDX (i64) | REX.WX (o64)
+4b: DEC eBX (i64) | REX.WXB (o64)
+4c: DEC eSP (i64) | REX.WR (o64)
+4d: DEC eBP (i64) | REX.WRB (o64)
+4e: DEC eSI (i64) | REX.WRX (o64)
+4f: DEC eDI (i64) | REX.WRXB (o64)
+# 0x50 - 0x5f
+50: PUSH rAX/r8 (d64)
+51: PUSH rCX/r9 (d64)
+52: PUSH rDX/r10 (d64)
+53: PUSH rBX/r11 (d64)
+54: PUSH rSP/r12 (d64)
+55: PUSH rBP/r13 (d64)
+56: PUSH rSI/r14 (d64)
+57: PUSH rDI/r15 (d64)
+58: POP rAX/r8 (d64)
+59: POP rCX/r9 (d64)
+5a: POP rDX/r10 (d64)
+5b: POP rBX/r11 (d64)
+5c: POP rSP/r12 (d64)
+5d: POP rBP/r13 (d64)
+5e: POP rSI/r14 (d64)
+5f: POP rDI/r15 (d64)
+# 0x60 - 0x6f
+60: PUSHA/PUSHAD (i64)
+61: POPA/POPAD (i64)
+62: BOUND Gv,Ma (i64)
+63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
+64: SEG=FS (Prefix)
+65: SEG=GS (Prefix)
+66: Operand-Size (Prefix)
+67: Address-Size (Prefix)
+68: PUSH Iz (d64)
+69: IMUL Gv,Ev,Iz
+6a: PUSH Ib (d64)
+6b: IMUL Gv,Ev,Ib
+6c: INS/INSB Yb,DX
+6d: INS/INSW/INSD Yz,DX
+6e: OUTS/OUTSB DX,Xb
+6f: OUTS/OUTSW/OUTSD DX,Xz
+# 0x70 - 0x7f
+70: JO Jb
+71: JNO Jb
+72: JB/JNAE/JC Jb
+73: JNB/JAE/JNC Jb
+74: JZ/JE Jb
+75: JNZ/JNE Jb
+76: JBE/JNA Jb
+77: JNBE/JA Jb
+78: JS Jb
+79: JNS Jb
+7a: JP/JPE Jb
+7b: JNP/JPO Jb
+7c: JL/JNGE Jb
+7d: JNL/JGE Jb
+7e: JLE/JNG Jb
+7f: JNLE/JG Jb
+# 0x80 - 0x8f
+80: Grp1 Eb,Ib (1A)
+81: Grp1 Ev,Iz (1A)
+82: Grp1 Eb,Ib (1A),(i64)
+83: Grp1 Ev,Ib (1A)
+84: TEST Eb,Gb
+85: TEST Ev,Gv
+86: XCHG Eb,Gb
+87: XCHG Ev,Gv
+88: MOV Eb,Gb
+89: MOV Ev,Gv
+8a: MOV Gb,Eb
+8b: MOV Gv,Ev
+8c: MOV Ev,Sw
+8d: LEA Gv,M
+8e: MOV Sw,Ew
+8f: Grp1A (1A) | POP Ev (d64)
+# 0x90 - 0x9f
+90: NOP | PAUSE (F3) | XCHG r8,rAX
+91: XCHG rCX/r9,rAX
+92: XCHG rDX/r10,rAX
+93: XCHG rBX/r11,rAX
+94: XCHG rSP/r12,rAX
+95: XCHG rBP/r13,rAX
+96: XCHG rSI/r14,rAX
+97: XCHG rDI/r15,rAX
+98: CBW/CWDE/CDQE
+99: CWD/CDQ/CQO
+9a: CALLF Ap (i64)
+9b: FWAIT/WAIT
+9c: PUSHF/D/Q Fv (d64)
+9d: POPF/D/Q Fv (d64)
+9e: SAHF
+9f: LAHF
+# 0xa0 - 0xaf
+a0: MOV AL,Ob
+a1: MOV rAX,Ov
+a2: MOV Ob,AL
+a3: MOV Ov,rAX
+a4: MOVS/B Xb,Yb
+a5: MOVS/W/D/Q Xv,Yv
+a6: CMPS/B Xb,Yb
+a7: CMPS/W/D Xv,Yv
+a8: TEST AL,Ib
+a9: TEST rAX,Iz
+aa: STOS/B Yb,AL
+ab: STOS/W/D/Q Yv,rAX
+ac: LODS/B AL,Xb
+ad: LODS/W/D/Q rAX,Xv
+ae: SCAS/B AL,Yb
+af: SCAS/W/D/Q rAX,Xv
+# 0xb0 - 0xbf
+b0: MOV AL/R8L,Ib
+b1: MOV CL/R9L,Ib
+b2: MOV DL/R10L,Ib
+b3: MOV BL/R11L,Ib
+b4: MOV AH/R12L,Ib
+b5: MOV CH/R13L,Ib
+b6: MOV DH/R14L,Ib
+b7: MOV BH/R15L,Ib
+b8: MOV rAX/r8,Iv
+b9: MOV rCX/r9,Iv
+ba: MOV rDX/r10,Iv
+bb: MOV rBX/r11,Iv
+bc: MOV rSP/r12,Iv
+bd: MOV rBP/r13,Iv
+be: MOV rSI/r14,Iv
+bf: MOV rDI/r15,Iv
+# 0xc0 - 0xcf
+c0: Grp2 Eb,Ib (1A)
+c1: Grp2 Ev,Ib (1A)
+c2: RETN Iw (f64)
+c3: RETN
+c4: LES Gz,Mp (i64) | 3bytes-VEX (Prefix)
+c5: LDS Gz,Mp (i64) | 2bytes-VEX (Prefix)
+c6: Grp11 Eb,Ib (1A)
+c7: Grp11 Ev,Iz (1A)
+c8: ENTER Iw,Ib
+c9: LEAVE (d64)
+ca: RETF Iw
+cb: RETF
+cc: INT3
+cd: INT Ib
+ce: INTO (i64)
+cf: IRET/D/Q
+# 0xd0 - 0xdf
+d0: Grp2 Eb,1 (1A)
+d1: Grp2 Ev,1 (1A)
+d2: Grp2 Eb,CL (1A)
+d3: Grp2 Ev,CL (1A)
+d4: AAM Ib (i64)
+d5: AAD Ib (i64)
+d6:
+d7: XLAT/XLATB
+d8: ESC
+d9: ESC
+da: ESC
+db: ESC
+dc: ESC
+dd: ESC
+de: ESC
+df: ESC
+# 0xe0 - 0xef
+e0: LOOPNE/LOOPNZ Jb (f64)
+e1: LOOPE/LOOPZ Jb (f64)
+e2: LOOP Jb (f64)
+e3: JrCXZ Jb (f64)
+e4: IN AL,Ib
+e5: IN eAX,Ib
+e6: OUT Ib,AL
+e7: OUT Ib,eAX
+e8: CALL Jz (f64)
+e9: JMP-near Jz (f64)
+ea: JMP-far Ap (i64)
+eb: JMP-short Jb (f64)
+ec: IN AL,DX
+ed: IN eAX,DX
+ee: OUT DX,AL
+ef: OUT DX,eAX
+# 0xf0 - 0xff
+f0: LOCK (Prefix)
+f1:
+f2: REPNE (Prefix)
+f3: REP/REPE (Prefix)
+f4: HLT
+f5: CMC
+f6: Grp3_1 Eb (1A)
+f7: Grp3_2 Ev (1A)
+f8: CLC
+f9: STC
+fa: CLI
+fb: STI
+fc: CLD
+fd: STD
+fe: Grp4 (1A)
+ff: Grp5 (1A)
+EndTable
+
+Table: 2-byte opcode (0x0f)
+Referrer: 2-byte escape
+AVXcode: 1
+# 0x0f 0x00-0x0f
+00: Grp6 (1A)
+01: Grp7 (1A)
+02: LAR Gv,Ew
+03: LSL Gv,Ew
+04:
+05: SYSCALL (o64)
+06: CLTS
+07: SYSRET (o64)
+08: INVD
+09: WBINVD
+0a:
+0b: UD2 (1B)
+0c:
+0d: NOP Ev | GrpP
+0e: FEMMS
+# 3DNow! uses the last imm byte as opcode extension.
+0f: 3DNow! Pq,Qq,Ib
+# 0x0f 0x10-0x1f
+10: movups Vps,Wps (VEX) | movss Vss,Wss (F3),(VEX),(o128) | movupd Vpd,Wpd (66),(VEX) | movsd Vsd,Wsd (F2),(VEX),(o128)
+11: movups Wps,Vps (VEX) | movss Wss,Vss (F3),(VEX),(o128) | movupd Wpd,Vpd (66),(VEX) | movsd Wsd,Vsd (F2),(VEX),(o128)
+12: movlps Vq,Mq (VEX),(o128) | movlpd Vq,Mq (66),(VEX),(o128) | movhlps Vq,Uq (VEX),(o128) | movddup Vq,Wq (F2),(VEX) | movsldup Vq,Wq (F3),(VEX)
+13: mpvlps Mq,Vq (VEX),(o128) | movlpd Mq,Vq (66),(VEX),(o128)
+14: unpcklps Vps,Wq (VEX) | unpcklpd Vpd,Wq (66),(VEX)
+15: unpckhps Vps,Wq (VEX) | unpckhpd Vpd,Wq (66),(VEX)
+16: movhps Vq,Mq (VEX),(o128) | movhpd Vq,Mq (66),(VEX),(o128) | movlsps Vq,Uq (VEX),(o128) | movshdup Vq,Wq (F3),(VEX)
+17: movhps Mq,Vq (VEX),(o128) | movhpd Mq,Vq (66),(VEX),(o128)
+18: Grp16 (1A)
+19:
+1a:
+1b:
+1c:
+1d:
+1e:
+1f: NOP Ev
+# 0x0f 0x20-0x2f
+20: MOV Rd,Cd
+21: MOV Rd,Dd
+22: MOV Cd,Rd
+23: MOV Dd,Rd
+24:
+25:
+26:
+27:
+28: movaps Vps,Wps (VEX) | movapd Vpd,Wpd (66),(VEX)
+29: movaps Wps,Vps (VEX) | movapd Wpd,Vpd (66),(VEX)
+2a: cvtpi2ps Vps,Qpi | cvtsi2ss Vss,Ed/q (F3),(VEX),(o128) | cvtpi2pd Vpd,Qpi (66) | cvtsi2sd Vsd,Ed/q (F2),(VEX),(o128)
+2b: movntps Mps,Vps (VEX) | movntpd Mpd,Vpd (66),(VEX)
+2c: cvttps2pi Ppi,Wps | cvttss2si  Gd/q,Wss (F3),(VEX),(o128) | cvttpd2pi Ppi,Wpd (66) | cvttsd2si Gd/q,Wsd (F2),(VEX),(o128)
+2d: cvtps2pi Ppi,Wps | cvtss2si Gd/q,Wss (F3),(VEX),(o128) | cvtpd2pi Qpi,Wpd (66) | cvtsd2si Gd/q,Wsd (F2),(VEX),(o128)
+2e: ucomiss Vss,Wss (VEX),(o128) | ucomisd  Vsd,Wsd (66),(VEX),(o128)
+2f: comiss Vss,Wss (VEX),(o128) | comisd  Vsd,Wsd (66),(VEX),(o128)
+# 0x0f 0x30-0x3f
+30: WRMSR
+31: RDTSC
+32: RDMSR
+33: RDPMC
+34: SYSENTER
+35: SYSEXIT
+36:
+37: GETSEC
+38: escape # 3-byte escape 1
+39:
+3a: escape # 3-byte escape 2
+3b:
+3c:
+3d:
+3e:
+3f:
+# 0x0f 0x40-0x4f
+40: CMOVO Gv,Ev
+41: CMOVNO Gv,Ev
+42: CMOVB/C/NAE Gv,Ev
+43: CMOVAE/NB/NC Gv,Ev
+44: CMOVE/Z Gv,Ev
+45: CMOVNE/NZ Gv,Ev
+46: CMOVBE/NA Gv,Ev
+47: CMOVA/NBE Gv,Ev
+48: CMOVS Gv,Ev
+49: CMOVNS Gv,Ev
+4a: CMOVP/PE Gv,Ev
+4b: CMOVNP/PO Gv,Ev
+4c: CMOVL/NGE Gv,Ev
+4d: CMOVNL/GE Gv,Ev
+4e: CMOVLE/NG Gv,Ev
+4f: CMOVNLE/G Gv,Ev
+# 0x0f 0x50-0x5f
+50: movmskps Gd/q,Ups (VEX) | movmskpd Gd/q,Upd (66),(VEX)
+51: sqrtps Vps,Wps (VEX) | sqrtss Vss,Wss (F3),(VEX),(o128) | sqrtpd Vpd,Wpd (66),(VEX) | sqrtsd Vsd,Wsd (F2),(VEX),(o128)
+52: rsqrtps Vps,Wps (VEX) | rsqrtss Vss,Wss (F3),(VEX),(o128)
+53: rcpps Vps,Wps (VEX) | rcpss Vss,Wss (F3),(VEX),(o128)
+54: andps Vps,Wps (VEX) | andpd Vpd,Wpd (66),(VEX)
+55: andnps Vps,Wps (VEX) | andnpd Vpd,Wpd (66),(VEX)
+56: orps Vps,Wps (VEX) | orpd Vpd,Wpd (66),(VEX)
+57: xorps Vps,Wps (VEX) | xorpd Vpd,Wpd (66),(VEX)
+58: addps Vps,Wps (VEX) | addss Vss,Wss (F3),(VEX),(o128) | addpd Vpd,Wpd (66),(VEX) | addsd Vsd,Wsd (F2),(VEX),(o128)
+59: mulps Vps,Wps (VEX) | mulss Vss,Wss (F3),(VEX),(o128) | mulpd Vpd,Wpd (66),(VEX) | mulsd Vsd,Wsd (F2),(VEX),(o128)
+5a: cvtps2pd Vpd,Wps (VEX) | cvtss2sd Vsd,Wss (F3),(VEX),(o128) | cvtpd2ps Vps,Wpd (66),(VEX) | cvtsd2ss Vsd,Wsd (F2),(VEX),(o128)
+5b: cvtdq2ps Vps,Wdq (VEX) | cvtps2dq Vdq,Wps (66),(VEX) | cvttps2dq Vdq,Wps (F3),(VEX)
+5c: subps Vps,Wps (VEX) | subss Vss,Wss (F3),(VEX),(o128) | subpd Vpd,Wpd (66),(VEX) | subsd Vsd,Wsd (F2),(VEX),(o128)
+5d: minps Vps,Wps (VEX) | minss Vss,Wss (F3),(VEX),(o128) | minpd Vpd,Wpd (66),(VEX) | minsd Vsd,Wsd (F2),(VEX),(o128)
+5e: divps Vps,Wps (VEX) | divss Vss,Wss (F3),(VEX),(o128) | divpd Vpd,Wpd (66),(VEX) | divsd Vsd,Wsd (F2),(VEX),(o128)
+5f: maxps Vps,Wps (VEX) | maxss Vss,Wss (F3),(VEX),(o128) | maxpd Vpd,Wpd (66),(VEX) | maxsd Vsd,Wsd (F2),(VEX),(o128)
+# 0x0f 0x60-0x6f
+60: punpcklbw Pq,Qd | punpcklbw Vdq,Wdq (66),(VEX),(o128)
+61: punpcklwd Pq,Qd | punpcklwd Vdq,Wdq (66),(VEX),(o128)
+62: punpckldq Pq,Qd | punpckldq Vdq,Wdq (66),(VEX),(o128)
+63: packsswb Pq,Qq | packsswb Vdq,Wdq (66),(VEX),(o128)
+64: pcmpgtb Pq,Qq | pcmpgtb Vdq,Wdq (66),(VEX),(o128)
+65: pcmpgtw Pq,Qq | pcmpgtw Vdq,Wdq (66),(VEX),(o128)
+66: pcmpgtd Pq,Qq | pcmpgtd Vdq,Wdq (66),(VEX),(o128)
+67: packuswb Pq,Qq | packuswb Vdq,Wdq (66),(VEX),(o128)
+68: punpckhbw Pq,Qd | punpckhbw Vdq,Wdq (66),(VEX),(o128)
+69: punpckhwd Pq,Qd | punpckhwd Vdq,Wdq (66),(VEX),(o128)
+6a: punpckhdq Pq,Qd | punpckhdq Vdq,Wdq (66),(VEX),(o128)
+6b: packssdw Pq,Qd | packssdw Vdq,Wdq (66),(VEX),(o128)
+6c: punpcklqdq Vdq,Wdq (66),(VEX),(o128)
+6d: punpckhqdq Vdq,Wdq (66),(VEX),(o128)
+6e: movd/q/ Pd,Ed/q | movd/q Vdq,Ed/q (66),(VEX),(o128)
+6f: movq Pq,Qq | movdqa Vdq,Wdq (66),(VEX) | movdqu Vdq,Wdq (F3),(VEX)
+# 0x0f 0x70-0x7f
+70: pshufw Pq,Qq,Ib | pshufd Vdq,Wdq,Ib (66),(VEX),(o128) | pshufhw Vdq,Wdq,Ib (F3),(VEX),(o128) | pshuflw VdqWdq,Ib (F2),(VEX),(o128)
+71: Grp12 (1A)
+72: Grp13 (1A)
+73: Grp14 (1A)
+74: pcmpeqb Pq,Qq | pcmpeqb Vdq,Wdq (66),(VEX),(o128)
+75: pcmpeqw Pq,Qq | pcmpeqw Vdq,Wdq (66),(VEX),(o128)
+76: pcmpeqd Pq,Qq | pcmpeqd Vdq,Wdq (66),(VEX),(o128)
+77: emms/vzeroupper/vzeroall (VEX)
+78: VMREAD Ed/q,Gd/q
+79: VMWRITE Gd/q,Ed/q
+7a:
+7b:
+7c: haddps Vps,Wps (F2),(VEX) | haddpd Vpd,Wpd (66),(VEX)
+7d: hsubps Vps,Wps (F2),(VEX) | hsubpd Vpd,Wpd (66),(VEX)
+7e: movd/q Ed/q,Pd | movd/q Ed/q,Vdq (66),(VEX),(o128) | movq Vq,Wq (F3),(VEX),(o128)
+7f: movq Qq,Pq | movdqa Wdq,Vdq (66),(VEX) | movdqu Wdq,Vdq (F3),(VEX)
+# 0x0f 0x80-0x8f
+80: JO Jz (f64)
+81: JNO Jz (f64)
+82: JB/JNAE/JC Jz (f64)
+83: JNB/JAE/JNC Jz (f64)
+84: JZ/JE Jz (f64)
+85: JNZ/JNE Jz (f64)
+86: JBE/JNA Jz (f64)
+87: JNBE/JA Jz (f64)
+88: JS Jz (f64)
+89: JNS Jz (f64)
+8a: JP/JPE Jz (f64)
+8b: JNP/JPO Jz (f64)
+8c: JL/JNGE Jz (f64)
+8d: JNL/JGE Jz (f64)
+8e: JLE/JNG Jz (f64)
+8f: JNLE/JG Jz (f64)
+# 0x0f 0x90-0x9f
+90: SETO Eb
+91: SETNO Eb
+92: SETB/C/NAE Eb
+93: SETAE/NB/NC Eb
+94: SETE/Z Eb
+95: SETNE/NZ Eb
+96: SETBE/NA Eb
+97: SETA/NBE Eb
+98: SETS Eb
+99: SETNS Eb
+9a: SETP/PE Eb
+9b: SETNP/PO Eb
+9c: SETL/NGE Eb
+9d: SETNL/GE Eb
+9e: SETLE/NG Eb
+9f: SETNLE/G Eb
+# 0x0f 0xa0-0xaf
+a0: PUSH FS (d64)
+a1: POP FS (d64)
+a2: CPUID
+a3: BT Ev,Gv
+a4: SHLD Ev,Gv,Ib
+a5: SHLD Ev,Gv,CL
+a6: GrpPDLK
+a7: GrpRNG
+a8: PUSH GS (d64)
+a9: POP GS (d64)
+aa: RSM
+ab: BTS Ev,Gv
+ac: SHRD Ev,Gv,Ib
+ad: SHRD Ev,Gv,CL
+ae: Grp15 (1A),(1C)
+af: IMUL Gv,Ev
+# 0x0f 0xb0-0xbf
+b0: CMPXCHG Eb,Gb
+b1: CMPXCHG Ev,Gv
+b2: LSS Gv,Mp
+b3: BTR Ev,Gv
+b4: LFS Gv,Mp
+b5: LGS Gv,Mp
+b6: MOVZX Gv,Eb
+b7: MOVZX Gv,Ew
+b8: JMPE | POPCNT Gv,Ev (F3)
+b9: Grp10 (1A)
+ba: Grp8 Ev,Ib (1A)
+bb: BTC Ev,Gv
+bc: BSF Gv,Ev
+bd: BSR Gv,Ev
+be: MOVSX Gv,Eb
+bf: MOVSX Gv,Ew
+# 0x0f 0xc0-0xcf
+c0: XADD Eb,Gb
+c1: XADD Ev,Gv
+c2: cmpps Vps,Wps,Ib (VEX) | cmpss Vss,Wss,Ib (F3),(VEX),(o128) | cmppd Vpd,Wpd,Ib (66),(VEX) | cmpsd Vsd,Wsd,Ib (F2),(VEX)
+c3: movnti Md/q,Gd/q
+c4: pinsrw Pq,Rd/q/Mw,Ib | pinsrw Vdq,Rd/q/Mw,Ib (66),(VEX),(o128)
+c5: pextrw Gd,Nq,Ib | pextrw Gd,Udq,Ib (66),(VEX),(o128)
+c6: shufps Vps,Wps,Ib (VEX) | shufpd Vpd,Wpd,Ib (66),(VEX)
+c7: Grp9 (1A)
+c8: BSWAP RAX/EAX/R8/R8D
+c9: BSWAP RCX/ECX/R9/R9D
+ca: BSWAP RDX/EDX/R10/R10D
+cb: BSWAP RBX/EBX/R11/R11D
+cc: BSWAP RSP/ESP/R12/R12D
+cd: BSWAP RBP/EBP/R13/R13D
+ce: BSWAP RSI/ESI/R14/R14D
+cf: BSWAP RDI/EDI/R15/R15D
+# 0x0f 0xd0-0xdf
+d0: addsubps Vps,Wps (F2),(VEX) | addsubpd Vpd,Wpd (66),(VEX)
+d1: psrlw Pq,Qq | psrlw Vdq,Wdq (66),(VEX),(o128)
+d2: psrld Pq,Qq | psrld Vdq,Wdq (66),(VEX),(o128)
+d3: psrlq Pq,Qq | psrlq Vdq,Wdq (66),(VEX),(o128)
+d4: paddq Pq,Qq | paddq Vdq,Wdq (66),(VEX),(o128)
+d5: pmullw Pq,Qq | pmullw Vdq,Wdq (66),(VEX),(o128)
+d6: movq Wq,Vq (66),(VEX),(o128) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2)
+d7: pmovmskb Gd,Nq | pmovmskb Gd,Udq (66),(VEX),(o128)
+d8: psubusb Pq,Qq | psubusb Vdq,Wdq (66),(VEX),(o128)
+d9: psubusw Pq,Qq | psubusw Vdq,Wdq (66),(VEX),(o128)
+da: pminub Pq,Qq | pminub Vdq,Wdq (66),(VEX),(o128)
+db: pand Pq,Qq | pand Vdq,Wdq (66),(VEX),(o128)
+dc: paddusb Pq,Qq | paddusb Vdq,Wdq (66),(VEX),(o128)
+dd: paddusw Pq,Qq | paddusw Vdq,Wdq (66),(VEX),(o128)
+de: pmaxub Pq,Qq | pmaxub Vdq,Wdq (66),(VEX),(o128)
+df: pandn Pq,Qq | pandn Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0xe0-0xef
+e0: pavgb Pq,Qq | pavgb Vdq,Wdq (66),(VEX),(o128)
+e1: psraw Pq,Qq | psraw Vdq,Wdq (66),(VEX),(o128)
+e2: psrad Pq,Qq | psrad Vdq,Wdq (66),(VEX),(o128)
+e3: pavgw Pq,Qq | pavgw Vdq,Wdq (66),(VEX),(o128)
+e4: pmulhuw Pq,Qq | pmulhuw Vdq,Wdq (66),(VEX),(o128)
+e5: pmulhw Pq,Qq | pmulhw Vdq,Wdq (66),(VEX),(o128)
+e6: cvtpd2dq Vdq,Wpd (F2),(VEX) | cvttpd2dq Vdq,Wpd (66),(VEX) | cvtdq2pd Vpd,Wdq (F3),(VEX)
+e7: movntq Mq,Pq | movntdq Mdq,Vdq (66),(VEX)
+e8: psubsb Pq,Qq | psubsb Vdq,Wdq (66),(VEX),(o128)
+e9: psubsw Pq,Qq | psubsw Vdq,Wdq (66),(VEX),(o128)
+ea: pminsw Pq,Qq | pminsw Vdq,Wdq (66),(VEX),(o128)
+eb: por Pq,Qq | por Vdq,Wdq (66),(VEX),(o128)
+ec: paddsb Pq,Qq | paddsb Vdq,Wdq (66),(VEX),(o128)
+ed: paddsw Pq,Qq | paddsw Vdq,Wdq (66),(VEX),(o128)
+ee: pmaxsw Pq,Qq | pmaxsw Vdq,Wdq (66),(VEX),(o128)
+ef: pxor Pq,Qq | pxor Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0xf0-0xff
+f0: lddqu Vdq,Mdq (F2),(VEX)
+f1: psllw Pq,Qq | psllw Vdq,Wdq (66),(VEX),(o128)
+f2: pslld Pq,Qq | pslld Vdq,Wdq (66),(VEX),(o128)
+f3: psllq Pq,Qq | psllq Vdq,Wdq (66),(VEX),(o128)
+f4: pmuludq Pq,Qq | pmuludq Vdq,Wdq (66),(VEX),(o128)
+f5: pmaddwd Pq,Qq | pmaddwd Vdq,Wdq (66),(VEX),(o128)
+f6: psadbw Pq,Qq | psadbw Vdq,Wdq (66),(VEX),(o128)
+f7: maskmovq Pq,Nq | maskmovdqu Vdq,Udq (66),(VEX),(o128)
+f8: psubb Pq,Qq | psubb Vdq,Wdq (66),(VEX),(o128)
+f9: psubw Pq,Qq | psubw Vdq,Wdq (66),(VEX),(o128)
+fa: psubd Pq,Qq | psubd Vdq,Wdq (66),(VEX),(o128)
+fb: psubq Pq,Qq | psubq Vdq,Wdq (66),(VEX),(o128)
+fc: paddb Pq,Qq | paddb Vdq,Wdq (66),(VEX),(o128)
+fd: paddw Pq,Qq | paddw Vdq,Wdq (66),(VEX),(o128)
+fe: paddd Pq,Qq | paddd Vdq,Wdq (66),(VEX),(o128)
+ff:
+EndTable
+
+Table: 3-byte opcode 1 (0x0f 0x38)
+Referrer: 3-byte escape 1
+AVXcode: 2
+# 0x0f 0x38 0x00-0x0f
+00: pshufb Pq,Qq | pshufb Vdq,Wdq (66),(VEX),(o128)
+01: phaddw Pq,Qq | phaddw Vdq,Wdq (66),(VEX),(o128)
+02: phaddd Pq,Qq | phaddd Vdq,Wdq (66),(VEX),(o128)
+03: phaddsw Pq,Qq | phaddsw Vdq,Wdq (66),(VEX),(o128)
+04: pmaddubsw Pq,Qq | pmaddubsw Vdq,Wdq (66),(VEX),(o128)
+05: phsubw Pq,Qq | phsubw Vdq,Wdq (66),(VEX),(o128)
+06: phsubd Pq,Qq | phsubd Vdq,Wdq (66),(VEX),(o128)
+07: phsubsw Pq,Qq | phsubsw Vdq,Wdq (66),(VEX),(o128)
+08: psignb Pq,Qq | psignb Vdq,Wdq (66),(VEX),(o128)
+09: psignw Pq,Qq | psignw Vdq,Wdq (66),(VEX),(o128)
+0a: psignd Pq,Qq | psignd Vdq,Wdq (66),(VEX),(o128)
+0b: pmulhrsw Pq,Qq | pmulhrsw Vdq,Wdq (66),(VEX),(o128)
+0c: Vpermilps /r (66),(oVEX)
+0d: Vpermilpd /r (66),(oVEX)
+0e: vtestps /r (66),(oVEX)
+0f: vtestpd /r (66),(oVEX)
+# 0x0f 0x38 0x10-0x1f
+10: pblendvb Vdq,Wdq (66)
+11:
+12:
+13:
+14: blendvps Vdq,Wdq (66)
+15: blendvpd Vdq,Wdq (66)
+16:
+17: ptest Vdq,Wdq (66),(VEX)
+18: vbroadcastss /r (66),(oVEX)
+19: vbroadcastsd /r (66),(oVEX),(o256)
+1a: vbroadcastf128 /r (66),(oVEX),(o256)
+1b:
+1c: pabsb Pq,Qq | pabsb Vdq,Wdq (66),(VEX),(o128)
+1d: pabsw Pq,Qq | pabsw Vdq,Wdq (66),(VEX),(o128)
+1e: pabsd Pq,Qq | pabsd Vdq,Wdq (66),(VEX),(o128)
+1f:
+# 0x0f 0x38 0x20-0x2f
+20: pmovsxbw Vdq,Udq/Mq (66),(VEX),(o128)
+21: pmovsxbd Vdq,Udq/Md (66),(VEX),(o128)
+22: pmovsxbq Vdq,Udq/Mw (66),(VEX),(o128)
+23: pmovsxwd Vdq,Udq/Mq (66),(VEX),(o128)
+24: pmovsxwq Vdq,Udq/Md (66),(VEX),(o128)
+25: pmovsxdq Vdq,Udq/Mq (66),(VEX),(o128)
+26:
+27:
+28: pmuldq Vdq,Wdq (66),(VEX),(o128)
+29: pcmpeqq Vdq,Wdq (66),(VEX),(o128)
+2a: movntdqa Vdq,Mdq (66),(VEX),(o128)
+2b: packusdw Vdq,Wdq (66),(VEX),(o128)
+2c: vmaskmovps(ld) /r (66),(oVEX)
+2d: vmaskmovpd(ld) /r (66),(oVEX)
+2e: vmaskmovps(st) /r (66),(oVEX)
+2f: vmaskmovpd(st) /r (66),(oVEX)
+# 0x0f 0x38 0x30-0x3f
+30: pmovzxbw Vdq,Udq/Mq (66),(VEX),(o128)
+31: pmovzxbd Vdq,Udq/Md (66),(VEX),(o128)
+32: pmovzxbq Vdq,Udq/Mw (66),(VEX),(o128)
+33: pmovzxwd Vdq,Udq/Mq (66),(VEX),(o128)
+34: pmovzxwq Vdq,Udq/Md (66),(VEX),(o128)
+35: pmovzxdq Vdq,Udq/Mq (66),(VEX),(o128)
+36:
+37: pcmpgtq Vdq,Wdq (66),(VEX),(o128)
+38: pminsb Vdq,Wdq (66),(VEX),(o128)
+39: pminsd Vdq,Wdq (66),(VEX),(o128)
+3a: pminuw Vdq,Wdq (66),(VEX),(o128)
+3b: pminud Vdq,Wdq (66),(VEX),(o128)
+3c: pmaxsb Vdq,Wdq (66),(VEX),(o128)
+3d: pmaxsd Vdq,Wdq (66),(VEX),(o128)
+3e: pmaxuw Vdq,Wdq (66),(VEX),(o128)
+3f: pmaxud Vdq,Wdq (66),(VEX),(o128)
+# 0x0f 0x38 0x40-0x8f
+40: pmulld Vdq,Wdq (66),(VEX),(o128)
+41: phminposuw Vdq,Wdq (66),(VEX),(o128)
+80: INVEPT Gd/q,Mdq (66)
+81: INVPID Gd/q,Mdq (66)
+# 0x0f 0x38 0x90-0xbf (FMA)
+96: vfmaddsub132pd/ps /r (66),(VEX)
+97: vfmsubadd132pd/ps /r (66),(VEX)
+98: vfmadd132pd/ps /r (66),(VEX)
+99: vfmadd132sd/ss /r (66),(VEX),(o128)
+9a: vfmsub132pd/ps /r (66),(VEX)
+9b: vfmsub132sd/ss /r (66),(VEX),(o128)
+9c: vfnmadd132pd/ps /r (66),(VEX)
+9d: vfnmadd132sd/ss /r (66),(VEX),(o128)
+9e: vfnmsub132pd/ps /r (66),(VEX)
+9f: vfnmsub132sd/ss /r (66),(VEX),(o128)
+a6: vfmaddsub213pd/ps /r (66),(VEX)
+a7: vfmsubadd213pd/ps /r (66),(VEX)
+a8: vfmadd213pd/ps /r (66),(VEX)
+a9: vfmadd213sd/ss /r (66),(VEX),(o128)
+aa: vfmsub213pd/ps /r (66),(VEX)
+ab: vfmsub213sd/ss /r (66),(VEX),(o128)
+ac: vfnmadd213pd/ps /r (66),(VEX)
+ad: vfnmadd213sd/ss /r (66),(VEX),(o128)
+ae: vfnmsub213pd/ps /r (66),(VEX)
+af: vfnmsub213sd/ss /r (66),(VEX),(o128)
+b6: vfmaddsub231pd/ps /r (66),(VEX)
+b7: vfmsubadd231pd/ps /r (66),(VEX)
+b8: vfmadd231pd/ps /r (66),(VEX)
+b9: vfmadd231sd/ss /r (66),(VEX),(o128)
+ba: vfmsub231pd/ps /r (66),(VEX)
+bb: vfmsub231sd/ss /r (66),(VEX),(o128)
+bc: vfnmadd231pd/ps /r (66),(VEX)
+bd: vfnmadd231sd/ss /r (66),(VEX),(o128)
+be: vfnmsub231pd/ps /r (66),(VEX)
+bf: vfnmsub231sd/ss /r (66),(VEX),(o128)
+# 0x0f 0x38 0xc0-0xff
+db: aesimc Vdq,Wdq (66),(VEX),(o128)
+dc: aesenc Vdq,Wdq (66),(VEX),(o128)
+dd: aesenclast Vdq,Wdq (66),(VEX),(o128)
+de: aesdec Vdq,Wdq (66),(VEX),(o128)
+df: aesdeclast Vdq,Wdq (66),(VEX),(o128)
+f0: MOVBE Gv,Mv | CRC32 Gd,Eb (F2)
+f1: MOVBE Mv,Gv | CRC32 Gd,Ev (F2)
+EndTable
+
+Table: 3-byte opcode 2 (0x0f 0x3a)
+Referrer: 3-byte escape 2
+AVXcode: 3
+# 0x0f 0x3a 0x00-0xff
+04: vpermilps /r,Ib (66),(oVEX)
+05: vpermilpd /r,Ib (66),(oVEX)
+06: vperm2f128 /r,Ib (66),(oVEX),(o256)
+08: roundps Vdq,Wdq,Ib (66),(VEX)
+09: roundpd Vdq,Wdq,Ib (66),(VEX)
+0a: roundss Vss,Wss,Ib (66),(VEX),(o128)
+0b: roundsd Vsd,Wsd,Ib (66),(VEX),(o128)
+0c: blendps Vdq,Wdq,Ib (66),(VEX)
+0d: blendpd Vdq,Wdq,Ib (66),(VEX)
+0e: pblendw Vdq,Wdq,Ib (66),(VEX),(o128)
+0f: palignr Pq,Qq,Ib | palignr Vdq,Wdq,Ib (66),(VEX),(o128)
+14: pextrb Rd/Mb,Vdq,Ib (66),(VEX),(o128)
+15: pextrw Rd/Mw,Vdq,Ib (66),(VEX),(o128)
+16: pextrd/pextrq Ed/q,Vdq,Ib (66),(VEX),(o128)
+17: extractps Ed,Vdq,Ib (66),(VEX),(o128)
+18: vinsertf128 /r,Ib (66),(oVEX),(o256)
+19: vextractf128 /r,Ib (66),(oVEX),(o256)
+20: pinsrb Vdq,Rd/q/Mb,Ib (66),(VEX),(o128)
+21: insertps Vdq,Udq/Md,Ib (66),(VEX),(o128)
+22: pinsrd/pinsrq Vdq,Ed/q,Ib (66),(VEX),(o128)
+40: dpps Vdq,Wdq,Ib (66),(VEX)
+41: dppd Vdq,Wdq,Ib (66),(VEX),(o128)
+42: mpsadbw Vdq,Wdq,Ib (66),(VEX),(o128)
+44: pclmulq Vdq,Wdq,Ib (66),(VEX),(o128)
+4a: vblendvps /r,Ib (66),(oVEX)
+4b: vblendvpd /r,Ib (66),(oVEX)
+4c: vpblendvb /r,Ib (66),(oVEX),(o128)
+60: pcmpestrm Vdq,Wdq,Ib (66),(VEX),(o128)
+61: pcmpestri Vdq,Wdq,Ib (66),(VEX),(o128)
+62: pcmpistrm Vdq,Wdq,Ib (66),(VEX),(o128)
+63: pcmpistri Vdq,Wdq,Ib (66),(VEX),(o128)
+df: aeskeygenassist Vdq,Wdq,Ib (66),(VEX),(o128)
+EndTable
+
+GrpTable: Grp1
+0: ADD
+1: OR
+2: ADC
+3: SBB
+4: AND
+5: SUB
+6: XOR
+7: CMP
+EndTable
+
+GrpTable: Grp1A
+0: POP
+EndTable
+
+GrpTable: Grp2
+0: ROL
+1: ROR
+2: RCL
+3: RCR
+4: SHL/SAL
+5: SHR
+6:
+7: SAR
+EndTable
+
+GrpTable: Grp3_1
+0: TEST Eb,Ib
+1:
+2: NOT Eb
+3: NEG Eb
+4: MUL AL,Eb
+5: IMUL AL,Eb
+6: DIV AL,Eb
+7: IDIV AL,Eb
+EndTable
+
+GrpTable: Grp3_2
+0: TEST Ev,Iz
+1:
+2: NOT Ev
+3: NEG Ev
+4: MUL rAX,Ev
+5: IMUL rAX,Ev
+6: DIV rAX,Ev
+7: IDIV rAX,Ev
+EndTable
+
+GrpTable: Grp4
+0: INC Eb
+1: DEC Eb
+EndTable
+
+GrpTable: Grp5
+0: INC Ev
+1: DEC Ev
+2: CALLN Ev (f64)
+3: CALLF Ep
+4: JMPN Ev (f64)
+5: JMPF Ep
+6: PUSH Ev (d64)
+7:
+EndTable
+
+GrpTable: Grp6
+0: SLDT Rv/Mw
+1: STR Rv/Mw
+2: LLDT Ew
+3: LTR Ew
+4: VERR Ew
+5: VERW Ew
+EndTable
+
+GrpTable: Grp7
+0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
+1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001)
+2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B)
+3: LIDT Ms
+4: SMSW Mw/Rv
+5:
+6: LMSW Ew
+7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
+EndTable
+
+GrpTable: Grp8
+4: BT
+5: BTS
+6: BTR
+7: BTC
+EndTable
+
+GrpTable: Grp9
+1: CMPXCHG8B/16B Mq/Mdq
+6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3)
+7: VMPTRST Mq
+EndTable
+
+GrpTable: Grp10
+EndTable
+
+GrpTable: Grp11
+0: MOV
+EndTable
+
+GrpTable: Grp12
+2: psrlw Nq,Ib (11B) | psrlw Udq,Ib (66),(11B),(VEX),(o128)
+4: psraw Nq,Ib (11B) | psraw Udq,Ib (66),(11B),(VEX),(o128)
+6: psllw Nq,Ib (11B) | psllw Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp13
+2: psrld Nq,Ib (11B) | psrld Udq,Ib (66),(11B),(VEX),(o128)
+4: psrad Nq,Ib (11B) | psrad Udq,Ib (66),(11B),(VEX),(o128)
+6: pslld Nq,Ib (11B) | pslld Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp14
+2: psrlq Nq,Ib (11B) | psrlq Udq,Ib (66),(11B),(VEX),(o128)
+3: psrldq Udq,Ib (66),(11B),(VEX),(o128)
+6: psllq Nq,Ib (11B) | psllq Udq,Ib (66),(11B),(VEX),(o128)
+7: pslldq Udq,Ib (66),(11B),(VEX),(o128)
+EndTable
+
+GrpTable: Grp15
+0: fxsave
+1: fxstor
+2: ldmxcsr (VEX)
+3: stmxcsr (VEX)
+4: XSAVE
+5: XRSTOR | lfence (11B)
+6: mfence (11B)
+7: clflush | sfence (11B)
+EndTable
+
+GrpTable: Grp16
+0: prefetch NTA
+1: prefetch T0
+2: prefetch T1
+3: prefetch T2
+EndTable
+
+# AMD's Prefetch Group
+GrpTable: GrpP
+0: PREFETCH
+1: PREFETCHW
+EndTable
+
+GrpTable: GrpPDLK
+0: MONTMUL
+1: XSHA1
+2: XSHA2
+EndTable
+
+GrpTable: GrpRNG
+0: xstore-rng
+1: xcrypt-ecb
+2: xcrypt-cbc
+4: xcrypt-cfb
+5: xcrypt-ofb
+EndTable
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/Makefile linux-libre-2.6.33-gnu1/arch/x86/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -155,6 +155,9 @@ all: bzImage
 KBUILD_IMAGE := $(boot)/bzImage
 
 bzImage: vmlinux
+ifeq ($(CONFIG_X86_DECODER_SELFTEST),y)
+	$(Q)$(MAKE) $(build)=arch/x86/tools posttest
+endif
 	$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
 	$(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
 	$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/Makefile_32.cpu linux-libre-2.6.33-gnu1/arch/x86/Makefile_32.cpu
--- linux-libre-2.6.32-gnu1/arch/x86/Makefile_32.cpu	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/Makefile_32.cpu	2010-02-24 13:52:17.000000000 -0500
@@ -41,11 +41,18 @@ cflags-$(CONFIG_X86_ELAN)	+= -march=i486
 
 # Geode GX1 support
 cflags-$(CONFIG_MGEODEGX1)	+= -march=pentium-mmx
-
+cflags-$(CONFIG_MGEODE_LX)	+= $(call cc-option,-march=geode,-march=pentium-mmx)
 # add at the end to overwrite eventual tuning options from earlier
 # cpu entries
 cflags-$(CONFIG_X86_GENERIC) 	+= $(call tune,generic,$(call tune,i686))
 
+# Work around the pentium-mmx code generator madness of gcc4.4.x which
+# does stack alignment by generating horrible code _before_ the mcount
+# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
+# tracer assumptions. For i686, generic, core2 this is set by the
+# compiler anyway
+cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args)
+
 # Bug fix for binutils: this option is required in order to keep
 # binutils from generating NOPL instructions against our will.
 ifneq ($(CONFIG_X86_P6_NOP),y)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/extable.c linux-libre-2.6.33-gnu1/arch/x86/mm/extable.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/extable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/extable.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,34 +35,3 @@ int fixup_exception(struct pt_regs *regs
 
 	return 0;
 }
-
-#ifdef CONFIG_X86_64
-/*
- * Need to defined our own search_extable on X86_64 to work around
- * a B stepping K8 bug.
- */
-const struct exception_table_entry *
-search_extable(const struct exception_table_entry *first,
-	       const struct exception_table_entry *last,
-	       unsigned long value)
-{
-	/* B stepping K8 bug */
-	if ((value >> 32) == 0)
-		value |= 0xffffffffUL << 32;
-
-	while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
-
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff == 0)
-			return mid;
-		else if (diff < 0)
-			first = mid+1;
-		else
-			last = mid-1;
-	}
-	return NULL;
-}
-#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/fault.c linux-libre-2.6.33-gnu1/arch/x86/mm/fault.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/fault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/fault.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,8 @@ enum x86_pf_error_code {
  * Returns 0 if mmiotrace is disabled, or if the fault is not
  * handled by mmiotrace:
  */
-static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
+static inline int __kprobes
+kmmio_fault(struct pt_regs *regs, unsigned long addr)
 {
 	if (unlikely(is_kmmio_active()))
 		if (kmmio_handler(regs, addr) == 1)
@@ -46,7 +47,7 @@ static inline int kmmio_fault(struct pt_
 	return 0;
 }
 
-static inline int notify_page_fault(struct pt_regs *regs)
+static inline int __kprobes notify_page_fault(struct pt_regs *regs)
 {
 	int ret = 0;
 
@@ -240,7 +241,7 @@ void vmalloc_sync_all(void)
  *
  *   Handle a fault on the vmalloc or module mapping area
  */
-static noinline int vmalloc_fault(unsigned long address)
+static noinline __kprobes int vmalloc_fault(unsigned long address)
 {
 	unsigned long pgd_paddr;
 	pmd_t *pmd_k;
@@ -357,7 +358,7 @@ void vmalloc_sync_all(void)
  *
  * This assumes no large pages in there.
  */
-static noinline int vmalloc_fault(unsigned long address)
+static noinline __kprobes int vmalloc_fault(unsigned long address)
 {
 	pgd_t *pgd, *pgd_ref;
 	pud_t *pud, *pud_ref;
@@ -658,7 +659,7 @@ no_context(struct pt_regs *regs, unsigne
 	show_fault_oops(regs, error_code, address);
 
 	stackend = end_of_stack(tsk);
-	if (*stackend != STACK_END_MAGIC)
+	if (tsk != &init_task && *stackend != STACK_END_MAGIC)
 		printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
 
 	tsk->thread.cr2		= address;
@@ -860,7 +861,7 @@ static int spurious_fault_check(unsigned
  * There are no security implications to leaving a stale TLB when
  * increasing the permissions on a page.
  */
-static noinline int
+static noinline __kprobes int
 spurious_fault(unsigned long error_code, unsigned long address)
 {
 	pgd_t *pgd;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/gup.c linux-libre-2.6.33-gnu1/arch/x86/mm/gup.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/gup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/gup.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@ static inline pte_t gup_get_pte(pte_t *p
 #else
 	/*
 	 * With get_user_pages_fast, we walk down the pagetables without taking
-	 * any locks.  For this we would like to load the pointers atoimcally,
+	 * any locks.  For this we would like to load the pointers atomically,
 	 * but that is not possible (without expensive cmpxchg8b) on PAE.  What
 	 * we do have is the guarantee that a pte will only either go from not
 	 * present to present, or present to not present or both -- it will not
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/init_32.c linux-libre-2.6.33-gnu1/arch/x86/mm/init_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/init_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/init_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -412,7 +412,7 @@ static void __init permanent_kmaps_init(
 	pkmap_page_table = pte;
 }
 
-static void __init add_one_highpage_init(struct page *page, int pfn)
+static void __init add_one_highpage_init(struct page *page)
 {
 	ClearPageReserved(page);
 	init_page_count(page);
@@ -445,7 +445,7 @@ static int __init add_highpages_work_fn(
 		if (!pfn_valid(node_pfn))
 			continue;
 		page = pfn_to_page(node_pfn);
-		add_one_highpage_init(page, node_pfn);
+		add_one_highpage_init(page);
 	}
 
 	return 0;
@@ -703,8 +703,8 @@ void __init find_low_pfn_range(void)
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-void __init initmem_init(unsigned long start_pfn,
-				  unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 #ifdef CONFIG_HIGHMEM
 	highstart_pfn = highend_pfn = max_pfn;
@@ -892,8 +892,7 @@ void __init mem_init(void)
 		reservedpages << (PAGE_SHIFT-10),
 		datasize >> 10,
 		initsize >> 10,
-		(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
-	       );
+		totalhigh_pages << (PAGE_SHIFT-10));
 
 	printk(KERN_INFO "virtual kernel memory layout:\n"
 		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
@@ -997,7 +996,7 @@ static noinline int do_test_wp_bit(void)
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
-static int kernel_set_to_readonly;
+int kernel_set_to_readonly __read_mostly;
 
 void set_kernel_text_rw(void)
 {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/init_64.c linux-libre-2.6.33-gnu1/arch/x86/mm/init_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/init_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/init_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,7 @@
 #include <asm/numa.h>
 #include <asm/cacheflush.h>
 #include <asm/init.h>
+#include <linux/bootmem.h>
 
 static unsigned long dma_reserve __initdata;
 
@@ -568,7 +569,8 @@ kernel_physical_mapping_init(unsigned lo
 }
 
 #ifndef CONFIG_NUMA
-void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 	unsigned long bootmap_size, bootmap;
 
@@ -615,6 +617,21 @@ void __init paging_init(void)
  */
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
+ * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need
+ * updating.
+ */
+static void  update_end_of_memory_vars(u64 start, u64 size)
+{
+	unsigned long end_pfn = PFN_UP(start + size);
+
+	if (end_pfn > max_pfn) {
+		max_pfn = end_pfn;
+		max_low_pfn = end_pfn;
+		high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
+	}
+}
+
+/*
  * Memory is added always to NORMAL zone. This means you will never get
  * additional DMA/DMA32 memory.
  */
@@ -633,6 +650,9 @@ int arch_add_memory(int nid, u64 start,
 	ret = __add_pages(nid, zone, start_pfn, nr_pages);
 	WARN_ON_ONCE(ret);
 
+	/* update max_pfn, max_low_pfn and high_memory */
+	update_end_of_memory_vars(start, size);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(arch_add_memory);
@@ -694,12 +714,12 @@ void __init mem_init(void)
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
-static int kernel_set_to_readonly;
+int kernel_set_to_readonly;
 
 void set_kernel_text_rw(void)
 {
-	unsigned long start = PFN_ALIGN(_stext);
-	unsigned long end = PFN_ALIGN(__start_rodata);
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long end = PFN_ALIGN(__stop___ex_table);
 
 	if (!kernel_set_to_readonly)
 		return;
@@ -707,13 +727,18 @@ void set_kernel_text_rw(void)
 	pr_debug("Set kernel text: %lx - %lx for read write\n",
 		 start, end);
 
+	/*
+	 * Make the kernel identity mapping for text RW. Kernel text
+	 * mapping will always be RO. Refer to the comment in
+	 * static_protections() in pageattr.c
+	 */
 	set_memory_rw(start, (end - start) >> PAGE_SHIFT);
 }
 
 void set_kernel_text_ro(void)
 {
-	unsigned long start = PFN_ALIGN(_stext);
-	unsigned long end = PFN_ALIGN(__start_rodata);
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long end = PFN_ALIGN(__stop___ex_table);
 
 	if (!kernel_set_to_readonly)
 		return;
@@ -721,14 +746,21 @@ void set_kernel_text_ro(void)
 	pr_debug("Set kernel text: %lx - %lx for read only\n",
 		 start, end);
 
+	/*
+	 * Set the kernel identity mapping for text RO.
+	 */
 	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 }
 
 void mark_rodata_ro(void)
 {
-	unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
+	unsigned long start = PFN_ALIGN(_text);
 	unsigned long rodata_start =
 		((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
+	unsigned long end = (unsigned long) &__end_rodata_hpage_align;
+	unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table);
+	unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata);
+	unsigned long data_start = (unsigned long) &_sdata;
 
 	printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
 	       (end - start) >> 10);
@@ -751,6 +783,14 @@ void mark_rodata_ro(void)
 	printk(KERN_INFO "Testing CPA: again\n");
 	set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
+
+	free_init_pages("unused kernel memory",
+			(unsigned long) page_address(virt_to_page(text_end)),
+			(unsigned long)
+				 page_address(virt_to_page(rodata_start)));
+	free_init_pages("unused kernel memory",
+			(unsigned long) page_address(virt_to_page(rodata_end)),
+			(unsigned long) page_address(virt_to_page(data_start)));
 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/init.c linux-libre-2.6.33-gnu1/arch/x86/mm/init.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/init.c	2010-02-24 13:52:17.000000000 -0500
@@ -146,10 +146,6 @@ unsigned long __init_refok init_memory_m
 	use_gbpages = direct_gbpages;
 #endif
 
-	set_nx();
-	if (nx_enabled)
-		printk(KERN_INFO "NX (Execute Disable) protection: active\n");
-
 	/* Enable PSE if available */
 	if (cpu_has_pse)
 		set_in_cr4(X86_CR4_PSE);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/ioremap.c linux-libre-2.6.33-gnu1/arch/x86/mm/ioremap.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/ioremap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/ioremap.c	2010-02-24 13:52:17.000000000 -0500
@@ -281,30 +281,6 @@ void __iomem *ioremap_cache(resource_siz
 }
 EXPORT_SYMBOL(ioremap_cache);
 
-static void __iomem *ioremap_default(resource_size_t phys_addr,
-					unsigned long size)
-{
-	unsigned long flags;
-	void __iomem *ret;
-	int err;
-
-	/*
-	 * - WB for WB-able memory and no other conflicting mappings
-	 * - UC_MINUS for non-WB-able memory with no other conflicting mappings
-	 * - Inherit from confliting mappings otherwise
-	 */
-	err = reserve_memtype(phys_addr, phys_addr + size,
-				_PAGE_CACHE_WB, &flags);
-	if (err < 0)
-		return NULL;
-
-	ret = __ioremap_caller(phys_addr, size, flags,
-			       __builtin_return_address(0));
-
-	free_memtype(phys_addr, phys_addr + size);
-	return ret;
-}
-
 void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
 				unsigned long prot_val)
 {
@@ -380,7 +356,7 @@ void *xlate_dev_mem_ptr(unsigned long ph
 	if (page_is_ram(start >> PAGE_SHIFT))
 		return __va(phys);
 
-	addr = (void __force *)ioremap_default(start, PAGE_SIZE);
+	addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
 	if (addr)
 		addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/k8topology_64.c linux-libre-2.6.33-gnu1/arch/x86/mm/k8topology_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/k8topology_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/k8topology_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,9 @@
 #include <asm/apic.h>
 #include <asm/k8.h>
 
+static struct bootnode __initdata nodes[8];
+static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
+
 static __init int find_northbridge(void)
 {
 	int num;
@@ -54,18 +57,6 @@ static __init void early_get_boot_cpu_id
 	 * need to get boot_cpu_id so can use that to create apicid_to_node
 	 * in k8_scan_nodes()
 	 */
-	/*
-	 * Find possible boot-time SMP configuration:
-	 */
-#ifdef CONFIG_X86_MPPARSE
-	early_find_smp_config();
-#endif
-#ifdef CONFIG_ACPI
-	/*
-	 * Read APIC information from ACPI tables.
-	 */
-	early_acpi_boot_init();
-#endif
 #ifdef CONFIG_X86_MPPARSE
 	/*
 	 * get boot-time SMP configuration:
@@ -76,12 +67,26 @@ static __init void early_get_boot_cpu_id
 	early_init_lapic_mapping();
 }
 
-int __init k8_scan_nodes(unsigned long start, unsigned long end)
+int __init k8_get_nodes(struct bootnode *physnodes)
 {
-	unsigned numnodes, cores, bits, apicid_base;
+	int i;
+	int ret = 0;
+
+	for_each_node_mask(i, nodes_parsed) {
+		physnodes[ret].start = nodes[i].start;
+		physnodes[ret].end = nodes[i].end;
+		ret++;
+	}
+	return ret;
+}
+
+int __init k8_numa_init(unsigned long start_pfn, unsigned long end_pfn)
+{
+	unsigned long start = PFN_PHYS(start_pfn);
+	unsigned long end = PFN_PHYS(end_pfn);
+	unsigned numnodes;
 	unsigned long prevbase;
-	struct bootnode nodes[8];
-	int i, j, nb, found = 0;
+	int i, nb, found = 0;
 	u32 nodeid, reg;
 
 	if (!early_pci_allowed())
@@ -91,16 +96,15 @@ int __init k8_scan_nodes(unsigned long s
 	if (nb < 0)
 		return nb;
 
-	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
+	pr_info("Scanning NUMA topology in Northbridge %d\n", nb);
 
 	reg = read_pci_config(0, nb, 0, 0x60);
 	numnodes = ((reg >> 4) & 0xF) + 1;
 	if (numnodes <= 1)
 		return -1;
 
-	printk(KERN_INFO "Number of nodes %d\n", numnodes);
+	pr_info("Number of physical nodes %d\n", numnodes);
 
-	memset(&nodes, 0, sizeof(nodes));
 	prevbase = 0;
 	for (i = 0; i < 8; i++) {
 		unsigned long base, limit;
@@ -111,28 +115,28 @@ int __init k8_scan_nodes(unsigned long s
 		nodeid = limit & 7;
 		if ((base & 3) == 0) {
 			if (i < numnodes)
-				printk("Skipping disabled node %d\n", i);
+				pr_info("Skipping disabled node %d\n", i);
 			continue;
 		}
 		if (nodeid >= numnodes) {
-			printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
-			       base, limit);
+			pr_info("Ignoring excess node %d (%lx:%lx)\n", nodeid,
+				base, limit);
 			continue;
 		}
 
 		if (!limit) {
-			printk(KERN_INFO "Skipping node entry %d (base %lx)\n",
-			       i, base);
+			pr_info("Skipping node entry %d (base %lx)\n",
+				i, base);
 			continue;
 		}
 		if ((base >> 8) & 3 || (limit >> 8) & 3) {
-			printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n",
-			       nodeid, (base>>8)&3, (limit>>8) & 3);
+			pr_err("Node %d using interleaving mode %lx/%lx\n",
+			       nodeid, (base >> 8) & 3, (limit >> 8) & 3);
 			return -1;
 		}
-		if (node_isset(nodeid, node_possible_map)) {
-			printk(KERN_INFO "Node %d already present. Skipping\n",
-			       nodeid);
+		if (node_isset(nodeid, nodes_parsed)) {
+			pr_info("Node %d already present, skipping\n",
+				nodeid);
 			continue;
 		}
 
@@ -141,8 +145,8 @@ int __init k8_scan_nodes(unsigned long s
 		limit |= (1<<24)-1;
 		limit++;
 
-		if (limit > max_pfn << PAGE_SHIFT)
-			limit = max_pfn << PAGE_SHIFT;
+		if (limit > end)
+			limit = end;
 		if (limit <= base)
 			continue;
 
@@ -154,24 +158,24 @@ int __init k8_scan_nodes(unsigned long s
 		if (limit > end)
 			limit = end;
 		if (limit == base) {
-			printk(KERN_ERR "Empty node %d\n", nodeid);
+			pr_err("Empty node %d\n", nodeid);
 			continue;
 		}
 		if (limit < base) {
-			printk(KERN_ERR "Node %d bogus settings %lx-%lx.\n",
+			pr_err("Node %d bogus settings %lx-%lx.\n",
 			       nodeid, base, limit);
 			continue;
 		}
 
 		/* Could sort here, but pun for now. Should not happen anyroads. */
 		if (prevbase > base) {
-			printk(KERN_ERR "Node map not sorted %lx,%lx\n",
+			pr_err("Node map not sorted %lx,%lx\n",
 			       prevbase, base);
 			return -1;
 		}
 
-		printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n",
-		       nodeid, base, limit);
+		pr_info("Node %d MemBase %016lx Limit %016lx\n",
+			nodeid, base, limit);
 
 		found++;
 
@@ -180,18 +184,29 @@ int __init k8_scan_nodes(unsigned long s
 
 		prevbase = base;
 
-		node_set(nodeid, node_possible_map);
+		node_set(nodeid, nodes_parsed);
 	}
 
 	if (!found)
 		return -1;
+	return 0;
+}
 
+int __init k8_scan_nodes(void)
+{
+	unsigned int bits;
+	unsigned int cores;
+	unsigned int apicid_base;
+	int i;
+
+	BUG_ON(nodes_empty(nodes_parsed));
+	node_possible_map = nodes_parsed;
 	memnode_shift = compute_hash_shift(nodes, 8, NULL);
 	if (memnode_shift < 0) {
-		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n");
+		pr_err("No NUMA node hash function found. Contact maintainer\n");
 		return -1;
 	}
-	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift);
+	pr_info("Using node hash shift of %d\n", memnode_shift);
 
 	/* use the coreid bits from early_identify_cpu */
 	bits = boot_cpu_data.x86_coreid_bits;
@@ -200,14 +215,12 @@ int __init k8_scan_nodes(unsigned long s
 	/* need to get boot_cpu_id early for system with apicid lifting */
 	early_get_boot_cpu_id();
 	if (boot_cpu_physical_apicid > 0) {
-		printk(KERN_INFO "BSP APIC ID: %02x\n",
-				 boot_cpu_physical_apicid);
+		pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
 		apicid_base = boot_cpu_physical_apicid;
 	}
 
-	for (i = 0; i < 8; i++) {
-		if (nodes[i].start == nodes[i].end)
-			continue;
+	for_each_node_mask(i, node_possible_map) {
+		int j;
 
 		e820_register_active_regions(i,
 				nodes[i].start >> PAGE_SHIFT,
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/kmemcheck/error.c linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/error.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/kmemcheck/error.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/kmemcheck/error.c	2010-02-24 13:52:17.000000000 -0500
@@ -106,26 +106,25 @@ void kmemcheck_error_recall(void)
 
 	switch (e->type) {
 	case KMEMCHECK_ERROR_INVALID_ACCESS:
-		printk(KERN_ERR  "WARNING: kmemcheck: Caught %d-bit read "
-			"from %s memory (%p)\n",
+		printk(KERN_WARNING "WARNING: kmemcheck: Caught %d-bit read from %s memory (%p)\n",
 			8 * e->size, e->state < ARRAY_SIZE(desc) ?
 				desc[e->state] : "(invalid shadow state)",
 			(void *) e->address);
 
-		printk(KERN_INFO);
+		printk(KERN_WARNING);
 		for (i = 0; i < SHADOW_COPY_SIZE; ++i)
-			printk("%02x", e->memory_copy[i]);
-		printk("\n");
+			printk(KERN_CONT "%02x", e->memory_copy[i]);
+		printk(KERN_CONT "\n");
 
-		printk(KERN_INFO);
+		printk(KERN_WARNING);
 		for (i = 0; i < SHADOW_COPY_SIZE; ++i) {
 			if (e->shadow_copy[i] < ARRAY_SIZE(short_desc))
-				printk(" %c", short_desc[e->shadow_copy[i]]);
+				printk(KERN_CONT " %c", short_desc[e->shadow_copy[i]]);
 			else
-				printk(" ?");
+				printk(KERN_CONT " ?");
 		}
-		printk("\n");
-		printk(KERN_INFO "%*c\n", 2 + 2
+		printk(KERN_CONT "\n");
+		printk(KERN_WARNING "%*c\n", 2 + 2
 			* (int) (e->address & (SHADOW_COPY_SIZE - 1)), '^');
 		break;
 	case KMEMCHECK_ERROR_BUG:
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/kmmio.c linux-libre-2.6.33-gnu1/arch/x86/mm/kmmio.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/kmmio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/kmmio.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,8 @@
  *     2008 Pekka Paalanen <pq@iki.fi>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/list.h>
 #include <linux/rculist.h>
 #include <linux/spinlock.h>
@@ -136,7 +138,7 @@ static int clear_page_presence(struct km
 	pte_t *pte = lookup_address(f->page, &level);
 
 	if (!pte) {
-		pr_err("kmmio: no pte for page 0x%08lx\n", f->page);
+		pr_err("no pte for page 0x%08lx\n", f->page);
 		return -1;
 	}
 
@@ -148,7 +150,7 @@ static int clear_page_presence(struct km
 		clear_pte_presence(pte, clear, &f->old_presence);
 		break;
 	default:
-		pr_err("kmmio: unexpected page level 0x%x.\n", level);
+		pr_err("unexpected page level 0x%x.\n", level);
 		return -1;
 	}
 
@@ -170,13 +172,14 @@ static int clear_page_presence(struct km
 static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 {
 	int ret;
-	WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
+	WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n"));
 	if (f->armed) {
-		pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
-					f->page, f->count, !!f->old_presence);
+		pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n",
+			   f->page, f->count, !!f->old_presence);
 	}
 	ret = clear_page_presence(f, true);
-	WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
+	WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"),
+		  f->page);
 	f->armed = true;
 	return ret;
 }
@@ -203,7 +206,7 @@ static void disarm_kmmio_fault_page(stru
  */
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate
- * and they remain disabled thorough out this function.
+ * and they remain disabled throughout this function.
  */
 int kmmio_handler(struct pt_regs *regs, unsigned long addr)
 {
@@ -240,24 +243,21 @@ int kmmio_handler(struct pt_regs *regs,
 			 * condition needs handling by do_page_fault(), the
 			 * page really not being present is the most common.
 			 */
-			pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n",
-					addr, smp_processor_id());
+			pr_debug("secondary hit for 0x%08lx CPU %d.\n",
+				 addr, smp_processor_id());
 
 			if (!faultpage->old_presence)
-				pr_info("kmmio: unexpected secondary hit for "
-					"address 0x%08lx on CPU %d.\n", addr,
-					smp_processor_id());
+				pr_info("unexpected secondary hit for address 0x%08lx on CPU %d.\n",
+					addr, smp_processor_id());
 		} else {
 			/*
 			 * Prevent overwriting already in-flight context.
 			 * This should not happen, let's hope disarming at
 			 * least prevents a panic.
 			 */
-			pr_emerg("kmmio: recursive probe hit on CPU %d, "
-					"for address 0x%08lx. Ignoring.\n",
-					smp_processor_id(), addr);
-			pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
-						ctx->addr);
+			pr_emerg("recursive probe hit on CPU %d, for address 0x%08lx. Ignoring.\n",
+				 smp_processor_id(), addr);
+			pr_emerg("previous hit was at 0x%08lx.\n", ctx->addr);
 			disarm_kmmio_fault_page(faultpage);
 		}
 		goto no_kmmio_ctx;
@@ -302,7 +302,7 @@ no_kmmio:
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate
- * and they remain disabled thorough out this function.
+ * and they remain disabled throughout this function.
  * This must always get called as the pair to kmmio_handler().
  */
 static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
@@ -316,8 +316,8 @@ static int post_kmmio_handler(unsigned l
 		 * something external causing them (f.e. using a debugger while
 		 * mmio tracing enabled), or erroneous behaviour
 		 */
-		pr_warning("kmmio: unexpected debug trap on CPU %d.\n",
-							smp_processor_id());
+		pr_warning("unexpected debug trap on CPU %d.\n",
+			   smp_processor_id());
 		goto out;
 	}
 
@@ -425,7 +425,7 @@ int register_kmmio_probe(struct kmmio_pr
 	list_add_rcu(&p->list, &kmmio_probes);
 	while (size < size_lim) {
 		if (add_kmmio_fault_page(p->addr + size))
-			pr_err("kmmio: Unable to set page fault.\n");
+			pr_err("Unable to set page fault.\n");
 		size += PAGE_SIZE;
 	}
 out:
@@ -490,7 +490,7 @@ static void remove_kmmio_fault_pages(str
  * 2. remove_kmmio_fault_pages()
  *    Remove the pages from kmmio_page_table.
  * 3. rcu_free_kmmio_fault_pages()
- *    Actally free the kmmio_fault_page structs as with RCU.
+ *    Actually free the kmmio_fault_page structs as with RCU.
  */
 void unregister_kmmio_probe(struct kmmio_probe *p)
 {
@@ -511,7 +511,7 @@ void unregister_kmmio_probe(struct kmmio
 
 	drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC);
 	if (!drelease) {
-		pr_crit("kmmio: leaking kmmio_fault_page objects.\n");
+		pr_crit("leaking kmmio_fault_page objects.\n");
 		return;
 	}
 	drelease->release_list = release_list;
@@ -538,10 +538,17 @@ static int
 kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args)
 {
 	struct die_args *arg = args;
+	unsigned long* dr6_p = (unsigned long *)ERR_PTR(arg->err);
 
-	if (val == DIE_DEBUG && (arg->err & DR_STEP))
-		if (post_kmmio_handler(arg->err, arg->regs) == 1)
+	if (val == DIE_DEBUG && (*dr6_p & DR_STEP))
+		if (post_kmmio_handler(*dr6_p, arg->regs) == 1) {
+			/*
+			 * Reset the BS bit in dr6 (pointed by args->err) to
+			 * denote completion of processing
+			 */
+			*dr6_p &= ~DR_STEP;
 			return NOTIFY_STOP;
+		}
 
 	return NOTIFY_DONE;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/mmio-mod.c linux-libre-2.6.33-gnu1/arch/x86/mm/mmio-mod.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/mmio-mod.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/mmio-mod.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,9 @@
  *
  * Derived from the read-mod example from relay-examples by Tom Zanussi.
  */
+
+#define pr_fmt(fmt) "mmiotrace: " fmt
+
 #define DEBUG 1
 
 #include <linux/module.h>
@@ -36,8 +39,6 @@
 
 #include "pf_in.h"
 
-#define NAME "mmiotrace: "
-
 struct trap_reason {
 	unsigned long addr;
 	unsigned long ip;
@@ -96,17 +97,18 @@ static void print_pte(unsigned long addr
 	pte_t *pte = lookup_address(address, &level);
 
 	if (!pte) {
-		pr_err(NAME "Error in %s: no pte for page 0x%08lx\n",
-							__func__, address);
+		pr_err("Error in %s: no pte for page 0x%08lx\n",
+		       __func__, address);
 		return;
 	}
 
 	if (level == PG_LEVEL_2M) {
-		pr_emerg(NAME "4MB pages are not currently supported: "
-							"0x%08lx\n", address);
+		pr_emerg("4MB pages are not currently supported: 0x%08lx\n",
+			 address);
 		BUG();
 	}
-	pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address,
+	pr_info("pte for 0x%lx: 0x%llx 0x%llx\n",
+		address,
 		(unsigned long long)pte_val(*pte),
 		(unsigned long long)pte_val(*pte) & _PAGE_PRESENT);
 }
@@ -118,22 +120,21 @@ static void print_pte(unsigned long addr
 static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr)
 {
 	const struct trap_reason *my_reason = &get_cpu_var(pf_reason);
-	pr_emerg(NAME "unexpected fault for address: 0x%08lx, "
-					"last fault for address: 0x%08lx\n",
-					addr, my_reason->addr);
+	pr_emerg("unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n",
+		 addr, my_reason->addr);
 	print_pte(addr);
 	print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip);
 	print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip);
 #ifdef __i386__
 	pr_emerg("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-			regs->ax, regs->bx, regs->cx, regs->dx);
+		 regs->ax, regs->bx, regs->cx, regs->dx);
 	pr_emerg("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-			regs->si, regs->di, regs->bp, regs->sp);
+		 regs->si, regs->di, regs->bp, regs->sp);
 #else
 	pr_emerg("rax: %016lx   rcx: %016lx   rdx: %016lx\n",
-					regs->ax, regs->cx, regs->dx);
+		 regs->ax, regs->cx, regs->dx);
 	pr_emerg("rsi: %016lx   rdi: %016lx   rbp: %016lx   rsp: %016lx\n",
-				regs->si, regs->di, regs->bp, regs->sp);
+		 regs->si, regs->di, regs->bp, regs->sp);
 #endif
 	put_cpu_var(pf_reason);
 	BUG();
@@ -213,7 +214,7 @@ static void post(struct kmmio_probe *p,
 	/* this should always return the active_trace count to 0 */
 	my_reason->active_traces--;
 	if (my_reason->active_traces) {
-		pr_emerg(NAME "unexpected post handler");
+		pr_emerg("unexpected post handler");
 		BUG();
 	}
 
@@ -244,7 +245,7 @@ static void ioremap_trace_core(resource_
 	};
 
 	if (!trace) {
-		pr_err(NAME "kmalloc failed in ioremap\n");
+		pr_err("kmalloc failed in ioremap\n");
 		return;
 	}
 
@@ -282,8 +283,8 @@ void mmiotrace_ioremap(resource_size_t o
 	if (!is_enabled()) /* recheck and proper locking in *_core() */
 		return;
 
-	pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n",
-				(unsigned long long)offset, size, addr);
+	pr_debug("ioremap_*(0x%llx, 0x%lx) = %p\n",
+		 (unsigned long long)offset, size, addr);
 	if ((filter_offset) && (offset != filter_offset))
 		return;
 	ioremap_trace_core(offset, size, addr);
@@ -301,7 +302,7 @@ static void iounmap_trace_core(volatile
 	struct remap_trace *tmp;
 	struct remap_trace *found_trace = NULL;
 
-	pr_debug(NAME "Unmapping %p.\n", addr);
+	pr_debug("Unmapping %p.\n", addr);
 
 	spin_lock_irq(&trace_lock);
 	if (!is_enabled())
@@ -363,9 +364,8 @@ static void clear_trace_list(void)
 	 * Caller also ensures is_enabled() cannot change.
 	 */
 	list_for_each_entry(trace, &trace_list, list) {
-		pr_notice(NAME "purging non-iounmapped "
-					"trace @0x%08lx, size 0x%lx.\n",
-					trace->probe.addr, trace->probe.len);
+		pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n",
+			  trace->probe.addr, trace->probe.len);
 		if (!nommiotrace)
 			unregister_kmmio_probe(&trace->probe);
 	}
@@ -387,7 +387,7 @@ static void enter_uniprocessor(void)
 
 	if (downed_cpus == NULL &&
 	    !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
-		pr_notice(NAME "Failed to allocate mask\n");
+		pr_notice("Failed to allocate mask\n");
 		goto out;
 	}
 
@@ -395,20 +395,19 @@ static void enter_uniprocessor(void)
 	cpumask_copy(downed_cpus, cpu_online_mask);
 	cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
 	if (num_online_cpus() > 1)
-		pr_notice(NAME "Disabling non-boot CPUs...\n");
+		pr_notice("Disabling non-boot CPUs...\n");
 	put_online_cpus();
 
 	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_down(cpu);
 		if (!err)
-			pr_info(NAME "CPU%d is down.\n", cpu);
+			pr_info("CPU%d is down.\n", cpu);
 		else
-			pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err);
+			pr_err("Error taking CPU%d down: %d\n", cpu, err);
 	}
 out:
 	if (num_online_cpus() > 1)
-		pr_warning(NAME "multiple CPUs still online, "
-						"may miss events.\n");
+		pr_warning("multiple CPUs still online, may miss events.\n");
 }
 
 /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit,
@@ -420,13 +419,13 @@ static void __ref leave_uniprocessor(voi
 
 	if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
 		return;
-	pr_notice(NAME "Re-enabling CPUs...\n");
+	pr_notice("Re-enabling CPUs...\n");
 	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_up(cpu);
 		if (!err)
-			pr_info(NAME "enabled CPU%d.\n", cpu);
+			pr_info("enabled CPU%d.\n", cpu);
 		else
-			pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err);
+			pr_err("cannot re-enable CPU%d: %d\n", cpu, err);
 	}
 }
 
@@ -434,8 +433,8 @@ static void __ref leave_uniprocessor(voi
 static void enter_uniprocessor(void)
 {
 	if (num_online_cpus() > 1)
-		pr_warning(NAME "multiple CPUs are online, may miss events. "
-			"Suggest booting with maxcpus=1 kernel argument.\n");
+		pr_warning("multiple CPUs are online, may miss events. "
+			   "Suggest booting with maxcpus=1 kernel argument.\n");
 }
 
 static void leave_uniprocessor(void)
@@ -450,13 +449,13 @@ void enable_mmiotrace(void)
 		goto out;
 
 	if (nommiotrace)
-		pr_info(NAME "MMIO tracing disabled.\n");
+		pr_info("MMIO tracing disabled.\n");
 	kmmio_init();
 	enter_uniprocessor();
 	spin_lock_irq(&trace_lock);
 	atomic_inc(&mmiotrace_enabled);
 	spin_unlock_irq(&trace_lock);
-	pr_info(NAME "enabled.\n");
+	pr_info("enabled.\n");
 out:
 	mutex_unlock(&mmiotrace_mutex);
 }
@@ -475,7 +474,7 @@ void disable_mmiotrace(void)
 	clear_trace_list(); /* guarantees: no more kmmio callbacks */
 	leave_uniprocessor();
 	kmmio_cleanup();
-	pr_info(NAME "disabled.\n");
+	pr_info("disabled.\n");
 out:
 	mutex_unlock(&mmiotrace_mutex);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/numa_32.c linux-libre-2.6.33-gnu1/arch/x86/mm/numa_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/numa_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/numa_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -347,8 +347,8 @@ static void init_remap_allocator(int nid
 		(ulong) node_remap_end_vaddr[nid]);
 }
 
-void __init initmem_init(unsigned long start_pfn,
-				  unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+				int acpi, int k8)
 {
 	int nid;
 	long kva_target_pfn;
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/numa_64.c linux-libre-2.6.33-gnu1/arch/x86/mm/numa_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/numa_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/numa_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -239,8 +239,14 @@ setup_node_bootmem(int nodeid, unsigned
 	bootmap = early_node_mem(nodeid, bootmap_start, end,
 				 bootmap_pages<<PAGE_SHIFT, PAGE_SIZE);
 	if (bootmap == NULL)  {
-		if (nodedata_phys < start || nodedata_phys >= end)
-			free_bootmem(nodedata_phys, pgdat_size);
+		if (nodedata_phys < start || nodedata_phys >= end) {
+			/*
+			 * only need to free it if it is from other node
+			 * bootmem
+			 */
+			if (nid != nodeid)
+				free_bootmem(nodedata_phys, pgdat_size);
+		}
 		node_data[nodeid] = NULL;
 		return;
 	}
@@ -306,8 +312,71 @@ void __init numa_init_array(void)
 
 #ifdef CONFIG_NUMA_EMU
 /* Numa emulation */
+static struct bootnode nodes[MAX_NUMNODES] __initdata;
+static struct bootnode physnodes[MAX_NUMNODES] __initdata;
 static char *cmdline __initdata;
 
+static int __init setup_physnodes(unsigned long start, unsigned long end,
+					int acpi, int k8)
+{
+	int nr_nodes = 0;
+	int ret = 0;
+	int i;
+
+#ifdef CONFIG_ACPI_NUMA
+	if (acpi)
+		nr_nodes = acpi_get_nodes(physnodes);
+#endif
+#ifdef CONFIG_K8_NUMA
+	if (k8)
+		nr_nodes = k8_get_nodes(physnodes);
+#endif
+	/*
+	 * Basic sanity checking on the physical node map: there may be errors
+	 * if the SRAT or K8 incorrectly reported the topology or the mem=
+	 * kernel parameter is used.
+	 */
+	for (i = 0; i < nr_nodes; i++) {
+		if (physnodes[i].start == physnodes[i].end)
+			continue;
+		if (physnodes[i].start > end) {
+			physnodes[i].end = physnodes[i].start;
+			continue;
+		}
+		if (physnodes[i].end < start) {
+			physnodes[i].start = physnodes[i].end;
+			continue;
+		}
+		if (physnodes[i].start < start)
+			physnodes[i].start = start;
+		if (physnodes[i].end > end)
+			physnodes[i].end = end;
+	}
+
+	/*
+	 * Remove all nodes that have no memory or were truncated because of the
+	 * limited address range.
+	 */
+	for (i = 0; i < nr_nodes; i++) {
+		if (physnodes[i].start == physnodes[i].end)
+			continue;
+		physnodes[ret].start = physnodes[i].start;
+		physnodes[ret].end = physnodes[i].end;
+		ret++;
+	}
+
+	/*
+	 * If no physical topology was detected, a single node is faked to cover
+	 * the entire address space.
+	 */
+	if (!ret) {
+		physnodes[ret].start = start;
+		physnodes[ret].end = end;
+		ret = 1;
+	}
+	return ret;
+}
+
 /*
  * Setups up nid to range from addr to addr + size.  If the end
  * boundary is greater than max_addr, then max_addr is used instead.
@@ -315,11 +384,9 @@ static char *cmdline __initdata;
  * allocation past addr and -1 otherwise.  addr is adjusted to be at
  * the end of the node.
  */
-static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr,
-				   u64 size, u64 max_addr)
+static int __init setup_node_range(int nid, u64 *addr, u64 size, u64 max_addr)
 {
 	int ret = 0;
-
 	nodes[nid].start = *addr;
 	*addr += size;
 	if (*addr >= max_addr) {
@@ -335,12 +402,111 @@ static int __init setup_node_range(int n
 }
 
 /*
+ * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
+ * to max_addr.  The return value is the number of nodes allocated.
+ */
+static int __init split_nodes_interleave(u64 addr, u64 max_addr,
+						int nr_phys_nodes, int nr_nodes)
+{
+	nodemask_t physnode_mask = NODE_MASK_NONE;
+	u64 size;
+	int big;
+	int ret = 0;
+	int i;
+
+	if (nr_nodes <= 0)
+		return -1;
+	if (nr_nodes > MAX_NUMNODES) {
+		pr_info("numa=fake=%d too large, reducing to %d\n",
+			nr_nodes, MAX_NUMNODES);
+		nr_nodes = MAX_NUMNODES;
+	}
+
+	size = (max_addr - addr - e820_hole_size(addr, max_addr)) / nr_nodes;
+	/*
+	 * Calculate the number of big nodes that can be allocated as a result
+	 * of consolidating the remainder.
+	 */
+	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) & nr_nodes) /
+		FAKE_NODE_MIN_SIZE;
+
+	size &= FAKE_NODE_MIN_HASH_MASK;
+	if (!size) {
+		pr_err("Not enough memory for each node.  "
+			"NUMA emulation disabled.\n");
+		return -1;
+	}
+
+	for (i = 0; i < nr_phys_nodes; i++)
+		if (physnodes[i].start != physnodes[i].end)
+			node_set(i, physnode_mask);
+
+	/*
+	 * Continue to fill physical nodes with fake nodes until there is no
+	 * memory left on any of them.
+	 */
+	while (nodes_weight(physnode_mask)) {
+		for_each_node_mask(i, physnode_mask) {
+			u64 end = physnodes[i].start + size;
+			u64 dma32_end = PFN_PHYS(MAX_DMA32_PFN);
+
+			if (ret < big)
+				end += FAKE_NODE_MIN_SIZE;
+
+			/*
+			 * Continue to add memory to this fake node if its
+			 * non-reserved memory is less than the per-node size.
+			 */
+			while (end - physnodes[i].start -
+				e820_hole_size(physnodes[i].start, end) < size) {
+				end += FAKE_NODE_MIN_SIZE;
+				if (end > physnodes[i].end) {
+					end = physnodes[i].end;
+					break;
+				}
+			}
+
+			/*
+			 * If there won't be at least FAKE_NODE_MIN_SIZE of
+			 * non-reserved memory in ZONE_DMA32 for the next node,
+			 * this one must extend to the boundary.
+			 */
+			if (end < dma32_end && dma32_end - end -
+			    e820_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+				end = dma32_end;
+
+			/*
+			 * If there won't be enough non-reserved memory for the
+			 * next node, this one must extend to the end of the
+			 * physical node.
+			 */
+			if (physnodes[i].end - end -
+			    e820_hole_size(end, physnodes[i].end) < size)
+				end = physnodes[i].end;
+
+			/*
+			 * Avoid allocating more nodes than requested, which can
+			 * happen as a result of rounding down each node's size
+			 * to FAKE_NODE_MIN_SIZE.
+			 */
+			if (nodes_weight(physnode_mask) + ret >= nr_nodes)
+				end = physnodes[i].end;
+
+			if (setup_node_range(ret++, &physnodes[i].start,
+						end - physnodes[i].start,
+						physnodes[i].end) < 0)
+				node_clear(i, physnode_mask);
+		}
+	}
+	return ret;
+}
+
+/*
  * Splits num_nodes nodes up equally starting at node_start.  The return value
  * is the number of nodes split up and addr is adjusted to be at the end of the
  * last node allocated.
  */
-static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr,
-				      u64 max_addr, int node_start,
+static int __init split_nodes_equally(u64 *addr, u64 max_addr, int node_start,
 				      int num_nodes)
 {
 	unsigned int big;
@@ -388,7 +554,7 @@ static int __init split_nodes_equally(st
 					break;
 				}
 			}
-		if (setup_node_range(i, nodes, addr, end - *addr, max_addr) < 0)
+		if (setup_node_range(i, addr, end - *addr, max_addr) < 0)
 			break;
 	}
 	return i - node_start + 1;
@@ -399,12 +565,12 @@ static int __init split_nodes_equally(st
  * always assigned to a final node and can be asymmetric.  Returns the number of
  * nodes split.
  */
-static int __init split_nodes_by_size(struct bootnode *nodes, u64 *addr,
-				      u64 max_addr, int node_start, u64 size)
+static int __init split_nodes_by_size(u64 *addr, u64 max_addr, int node_start,
+				      u64 size)
 {
 	int i = node_start;
 	size = (size << 20) & FAKE_NODE_MIN_HASH_MASK;
-	while (!setup_node_range(i++, nodes, addr, size, max_addr))
+	while (!setup_node_range(i++, addr, size, max_addr))
 		;
 	return i - node_start;
 }
@@ -413,15 +579,15 @@ static int __init split_nodes_by_size(st
  * Sets up the system RAM area from start_pfn to last_pfn according to the
  * numa=fake command-line option.
  */
-static struct bootnode nodes[MAX_NUMNODES] __initdata;
-
-static int __init numa_emulation(unsigned long start_pfn, unsigned long last_pfn)
+static int __init numa_emulation(unsigned long start_pfn,
+			unsigned long last_pfn, int acpi, int k8)
 {
 	u64 size, addr = start_pfn << PAGE_SHIFT;
 	u64 max_addr = last_pfn << PAGE_SHIFT;
 	int num_nodes = 0, num = 0, coeff_flag, coeff = -1, i;
+	int num_phys_nodes;
 
-	memset(&nodes, 0, sizeof(nodes));
+	num_phys_nodes = setup_physnodes(addr, max_addr, acpi, k8);
 	/*
 	 * If the numa=fake command-line is just a single number N, split the
 	 * system RAM into N fake nodes.
@@ -429,7 +595,8 @@ static int __init numa_emulation(unsigne
 	if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) {
 		long n = simple_strtol(cmdline, NULL, 0);
 
-		num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, n);
+		num_nodes = split_nodes_interleave(addr, max_addr,
+							num_phys_nodes, n);
 		if (num_nodes < 0)
 			return num_nodes;
 		goto out;
@@ -456,8 +623,8 @@ static int __init numa_emulation(unsigne
 			size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK;
 			if (size)
 				for (i = 0; i < coeff; i++, num_nodes++)
-					if (setup_node_range(num_nodes, nodes,
-						&addr, size, max_addr) < 0)
+					if (setup_node_range(num_nodes, &addr,
+						size, max_addr) < 0)
 						goto done;
 			if (!*cmdline)
 				break;
@@ -473,7 +640,7 @@ done:
 	if (addr < max_addr) {
 		if (coeff_flag && coeff < 0) {
 			/* Split remaining nodes into num-sized chunks */
-			num_nodes += split_nodes_by_size(nodes, &addr, max_addr,
+			num_nodes += split_nodes_by_size(&addr, max_addr,
 							 num_nodes, num);
 			goto out;
 		}
@@ -482,7 +649,7 @@ done:
 			/* Split remaining nodes into coeff chunks */
 			if (coeff <= 0)
 				break;
-			num_nodes += split_nodes_equally(nodes, &addr, max_addr,
+			num_nodes += split_nodes_equally(&addr, max_addr,
 							 num_nodes, coeff);
 			break;
 		case ',':
@@ -490,8 +657,8 @@ done:
 			break;
 		default:
 			/* Give one final node */
-			setup_node_range(num_nodes, nodes, &addr,
-					 max_addr - addr, max_addr);
+			setup_node_range(num_nodes, &addr, max_addr - addr,
+					 max_addr);
 			num_nodes++;
 		}
 	}
@@ -505,14 +672,10 @@ out:
 	}
 
 	/*
-	 * We need to vacate all active ranges that may have been registered by
-	 * SRAT and set acpi_numa to -1 so that srat_disabled() always returns
-	 * true.  NUMA emulation has succeeded so we will not scan ACPI nodes.
+	 * We need to vacate all active ranges that may have been registered for
+	 * the e820 memory map.
 	 */
 	remove_all_active_ranges();
-#ifdef CONFIG_ACPI_NUMA
-	acpi_numa = -1;
-#endif
 	for_each_node_mask(i, node_possible_map) {
 		e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
 						nodes[i].end >> PAGE_SHIFT);
@@ -524,7 +687,8 @@ out:
 }
 #endif /* CONFIG_NUMA_EMU */
 
-void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,
+				int acpi, int k8)
 {
 	int i;
 
@@ -532,23 +696,22 @@ void __init initmem_init(unsigned long s
 	nodes_clear(node_online_map);
 
 #ifdef CONFIG_NUMA_EMU
-	if (cmdline && !numa_emulation(start_pfn, last_pfn))
+	if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, k8))
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
 #endif
 
 #ifdef CONFIG_ACPI_NUMA
-	if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
-					  last_pfn << PAGE_SHIFT))
+	if (!numa_off && acpi && !acpi_scan_nodes(start_pfn << PAGE_SHIFT,
+						  last_pfn << PAGE_SHIFT))
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
 #endif
 
 #ifdef CONFIG_K8_NUMA
-	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT,
-					last_pfn<<PAGE_SHIFT))
+	if (!numa_off && k8 && !k8_scan_nodes())
 		return;
 	nodes_clear(node_possible_map);
 	nodes_clear(node_online_map);
@@ -601,6 +764,25 @@ static __init int numa_setup(char *opt)
 early_param("numa", numa_setup);
 
 #ifdef CONFIG_NUMA
+
+static __init int find_near_online_node(int node)
+{
+	int n, val;
+	int min_val = INT_MAX;
+	int best_node = -1;
+
+	for_each_online_node(n) {
+		val = node_distance(node, n);
+
+		if (val < min_val) {
+			min_val = val;
+			best_node = n;
+		}
+	}
+
+	return best_node;
+}
+
 /*
  * Setup early cpu_to_node.
  *
@@ -632,7 +814,7 @@ void __init init_cpu_to_node(void)
 		if (node == NUMA_NO_NODE)
 			continue;
 		if (!node_online(node))
-			continue;
+			node = find_near_online_node(node);
 		numa_set_node(cpu, node);
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/pageattr.c linux-libre-2.6.33-gnu1/arch/x86/mm/pageattr.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/pageattr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/pageattr.c	2010-02-24 13:52:17.000000000 -0500
@@ -279,6 +279,22 @@ static inline pgprot_t static_protection
 		   __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
 		pgprot_val(forbidden) |= _PAGE_RW;
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+	/*
+	 * Once the kernel maps the text as RO (kernel_set_to_readonly is set),
+	 * kernel text mappings for the large page aligned text, rodata sections
+	 * will be always read-only. For the kernel identity mappings covering
+	 * the holes caused by this alignment can be anything that user asks.
+	 *
+	 * This will preserve the large page mappings for kernel text/data
+	 * at no extra cost.
+	 */
+	if (kernel_set_to_readonly &&
+	    within(address, (unsigned long)_text,
+		   (unsigned long)__end_rodata_hpage_align))
+		pgprot_val(forbidden) |= _PAGE_RW;
+#endif
+
 	prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
 
 	return prot;
@@ -1069,12 +1085,18 @@ EXPORT_SYMBOL(set_memory_array_wb);
 
 int set_memory_x(unsigned long addr, int numpages)
 {
+	if (!(__supported_pte_mask & _PAGE_NX))
+		return 0;
+
 	return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_NX), 0);
 }
 EXPORT_SYMBOL(set_memory_x);
 
 int set_memory_nx(unsigned long addr, int numpages)
 {
+	if (!(__supported_pte_mask & _PAGE_NX))
+		return 0;
+
 	return change_page_attr_set(&addr, numpages, __pgprot(_PAGE_NX), 0);
 }
 EXPORT_SYMBOL(set_memory_nx);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/pat.c linux-libre-2.6.33-gnu1/arch/x86/mm/pat.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/pat.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/pat.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
+#include <asm/x86_init.h>
 #include <asm/pgtable.h>
 #include <asm/fcntl.h>
 #include <asm/e820.h>
@@ -355,9 +356,6 @@ static int free_ram_pages_type(u64 start
  * - _PAGE_CACHE_UC_MINUS
  * - _PAGE_CACHE_UC
  *
- * req_type will have a special case value '-1', when requester want to inherit
- * the memory type from mtrr (if WB), existing PAT, defaulting to UC_MINUS.
- *
  * If new_type is NULL, function will return an error if it cannot reserve the
  * region with req_type. If new_type is non-NULL, function will return
  * available type in new_type in case of no error. In case of any error
@@ -377,9 +375,7 @@ int reserve_memtype(u64 start, u64 end,
 	if (!pat_enabled) {
 		/* This is identical to page table setting without PAT */
 		if (new_type) {
-			if (req_type == -1)
-				*new_type = _PAGE_CACHE_WB;
-			else if (req_type == _PAGE_CACHE_WC)
+			if (req_type == _PAGE_CACHE_WC)
 				*new_type = _PAGE_CACHE_UC_MINUS;
 			else
 				*new_type = req_type & _PAGE_CACHE_MASK;
@@ -388,7 +384,7 @@ int reserve_memtype(u64 start, u64 end,
 	}
 
 	/* Low ISA region is always mapped WB in page table. No need to track */
-	if (is_ISA_range(start, end - 1)) {
+	if (x86_platform.is_untracked_pat_range(start, end)) {
 		if (new_type)
 			*new_type = _PAGE_CACHE_WB;
 		return 0;
@@ -499,7 +495,7 @@ int free_memtype(u64 start, u64 end)
 		return 0;
 
 	/* Low ISA region is always mapped WB. No need to track */
-	if (is_ISA_range(start, end - 1))
+	if (x86_platform.is_untracked_pat_range(start, end))
 		return 0;
 
 	is_range_ram = pat_pagerange_is_ram(start, end);
@@ -582,7 +578,7 @@ static unsigned long lookup_memtype(u64
 	int rettype = _PAGE_CACHE_WB;
 	struct memtype *entry;
 
-	if (is_ISA_range(paddr, paddr + PAGE_SIZE - 1))
+	if (x86_platform.is_untracked_pat_range(paddr, paddr + PAGE_SIZE))
 		return rettype;
 
 	if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {
@@ -708,9 +704,8 @@ int phys_mem_access_prot_allowed(struct
 	if (!range_is_allowed(pfn, size))
 		return 0;
 
-	if (file->f_flags & O_SYNC) {
+	if (file->f_flags & O_DSYNC)
 		flags = _PAGE_CACHE_UC_MINUS;
-	}
 
 #ifdef CONFIG_X86_32
 	/*
@@ -1018,8 +1013,10 @@ static const struct file_operations memt
 
 static int __init pat_memtype_list_init(void)
 {
-	debugfs_create_file("pat_memtype_list", S_IRUSR, arch_debugfs_dir,
-				NULL, &memtype_fops);
+	if (pat_enabled) {
+		debugfs_create_file("pat_memtype_list", S_IRUSR,
+				    arch_debugfs_dir, NULL, &memtype_fops);
+	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/setup_nx.c linux-libre-2.6.33-gnu1/arch/x86/mm/setup_nx.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/setup_nx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/setup_nx.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,10 +3,8 @@
 #include <linux/init.h>
 
 #include <asm/pgtable.h>
+#include <asm/proto.h>
 
-int nx_enabled;
-
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 static int disable_nx __cpuinitdata;
 
 /*
@@ -22,48 +20,41 @@ static int __init noexec_setup(char *str
 	if (!str)
 		return -EINVAL;
 	if (!strncmp(str, "on", 2)) {
-		__supported_pte_mask |= _PAGE_NX;
 		disable_nx = 0;
 	} else if (!strncmp(str, "off", 3)) {
 		disable_nx = 1;
-		__supported_pte_mask &= ~_PAGE_NX;
 	}
+	x86_configure_nx();
 	return 0;
 }
 early_param("noexec", noexec_setup);
-#endif
 
-#ifdef CONFIG_X86_PAE
-void __init set_nx(void)
+void __cpuinit x86_configure_nx(void)
 {
-	unsigned int v[4], l, h;
-
-	if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
-		cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
+	if (cpu_has_nx && !disable_nx)
+		__supported_pte_mask |= _PAGE_NX;
+	else
+		__supported_pte_mask &= ~_PAGE_NX;
+}
 
-		if ((v[3] & (1 << 20)) && !disable_nx) {
-			rdmsr(MSR_EFER, l, h);
-			l |= EFER_NX;
-			wrmsr(MSR_EFER, l, h);
-			nx_enabled = 1;
-			__supported_pte_mask |= _PAGE_NX;
+void __init x86_report_nx(void)
+{
+	if (!cpu_has_nx) {
+		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+		       "missing in CPU or disabled in BIOS!\n");
+	} else {
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+		if (disable_nx) {
+			printk(KERN_INFO "NX (Execute Disable) protection: "
+			       "disabled by kernel command line option\n");
+		} else {
+			printk(KERN_INFO "NX (Execute Disable) protection: "
+			       "active\n");
 		}
-	}
-}
 #else
-void set_nx(void)
-{
-}
+		/* 32bit non-PAE kernel, NX cannot be used */
+		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
+		       "cannot be enabled: non-PAE kernel!\n");
 #endif
-
-#ifdef CONFIG_X86_64
-void __cpuinit check_efer(void)
-{
-	unsigned long efer;
-
-	rdmsrl(MSR_EFER, efer);
-	if (!(efer & EFER_NX) || disable_nx)
-		__supported_pte_mask &= ~_PAGE_NX;
+	}
 }
-#endif
-
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/srat_32.c linux-libre-2.6.33-gnu1/arch/x86/mm/srat_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/srat_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/srat_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -267,6 +267,8 @@ int __init get_memcfg_from_srat(void)
 		e820_register_active_regions(chunk->nid, chunk->start_pfn,
 					     min(chunk->end_pfn, max_pfn));
 	}
+	/* for out of order entries in SRAT */
+	sort_node_map();
 
 	for_each_online_node(nid) {
 		unsigned long start = node_start_pfn[nid];
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/srat_64.c linux-libre-2.6.33-gnu1/arch/x86/mm/srat_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/srat_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/srat_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -136,7 +136,7 @@ acpi_numa_x2apic_affinity_init(struct ac
 	apicid_to_node[apic_id] = node;
 	node_set(node, cpu_nodes_parsed);
 	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
 	       pxm, apic_id, node);
 }
 
@@ -170,7 +170,7 @@ acpi_numa_processor_affinity_init(struct
 	apicid_to_node[apic_id] = node;
 	node_set(node, cpu_nodes_parsed);
 	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
 	       pxm, apic_id, node);
 }
 
@@ -229,9 +229,11 @@ update_nodes_add(int node, unsigned long
 			printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
 	}
 
-	if (changed)
+	if (changed) {
+		node_set(node, cpu_nodes_parsed);
 		printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n",
 				 nd->start, nd->end);
+	}
 }
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
@@ -290,8 +292,6 @@ acpi_numa_memory_affinity_init(struct ac
 
 	printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm,
 	       start, end);
-	e820_register_active_regions(node, start >> PAGE_SHIFT,
-				     end >> PAGE_SHIFT);
 
 	if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) {
 		update_nodes_add(node, start, end);
@@ -319,7 +319,7 @@ static int __init nodes_cover_memory(con
 		unsigned long s = nodes[i].start >> PAGE_SHIFT;
 		unsigned long e = nodes[i].end >> PAGE_SHIFT;
 		pxmram += e - s;
-		pxmram -= absent_pages_in_range(s, e);
+		pxmram -= __absent_pages_in_range(i, s, e);
 		if ((long)pxmram < 0)
 			pxmram = 0;
 	}
@@ -338,6 +338,19 @@ static int __init nodes_cover_memory(con
 
 void __init acpi_numa_arch_fixup(void) {}
 
+int __init acpi_get_nodes(struct bootnode *physnodes)
+{
+	int i;
+	int ret = 0;
+
+	for_each_node_mask(i, nodes_parsed) {
+		physnodes[ret].start = nodes[i].start;
+		physnodes[ret].end = nodes[i].end;
+		ret++;
+	}
+	return ret;
+}
+
 /* Use the information discovered above to actually set up the nodes. */
 int __init acpi_scan_nodes(unsigned long start, unsigned long end)
 {
@@ -350,11 +363,6 @@ int __init acpi_scan_nodes(unsigned long
 	for (i = 0; i < MAX_NUMNODES; i++)
 		cutoff_node(i, start, end);
 
-	if (!nodes_cover_memory(nodes)) {
-		bad_srat();
-		return -1;
-	}
-
 	memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks,
 					   memblk_nodeid);
 	if (memnode_shift < 0) {
@@ -364,6 +372,16 @@ int __init acpi_scan_nodes(unsigned long
 		return -1;
 	}
 
+	for_each_node_mask(i, nodes_parsed)
+		e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
+						nodes[i].end >> PAGE_SHIFT);
+	/* for out of order entries in SRAT */
+	sort_node_map();
+	if (!nodes_cover_memory(nodes)) {
+		bad_srat();
+		return -1;
+	}
+
 	/* Account for nodes with cpus and no memory */
 	nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed);
 
@@ -454,7 +472,6 @@ void __init acpi_fake_nodes(const struct
 	for (i = 0; i < num_nodes; i++)
 		if (fake_nodes[i].start != fake_nodes[i].end)
 			node_set(i, nodes_parsed);
-	WARN_ON(!nodes_cover_memory(fake_nodes));
 }
 
 static int null_slit_node_compare(int a, int b)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/testmmiotrace.c linux-libre-2.6.33-gnu1/arch/x86/mm/testmmiotrace.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/testmmiotrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/testmmiotrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,12 +1,13 @@
 /*
  * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/mmiotrace.h>
 
-#define MODULE_NAME "testmmiotrace"
-
 static unsigned long mmio_address;
 module_param(mmio_address, ulong, 0);
 MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
@@ -30,7 +31,7 @@ static unsigned v32(unsigned i)
 static void do_write_test(void __iomem *p)
 {
 	unsigned int i;
-	pr_info(MODULE_NAME ": write test.\n");
+	pr_info("write test.\n");
 	mmiotrace_printk("Write test.\n");
 
 	for (i = 0; i < 256; i++)
@@ -47,7 +48,7 @@ static void do_read_test(void __iomem *p
 {
 	unsigned int i;
 	unsigned errs[3] = { 0 };
-	pr_info(MODULE_NAME ": read test.\n");
+	pr_info("read test.\n");
 	mmiotrace_printk("Read test.\n");
 
 	for (i = 0; i < 256; i++)
@@ -68,7 +69,7 @@ static void do_read_test(void __iomem *p
 
 static void do_read_far_test(void __iomem *p)
 {
-	pr_info(MODULE_NAME ": read far test.\n");
+	pr_info("read far test.\n");
 	mmiotrace_printk("Read far test.\n");
 
 	ioread32(p + read_far);
@@ -78,7 +79,7 @@ static void do_test(unsigned long size)
 {
 	void __iomem *p = ioremap_nocache(mmio_address, size);
 	if (!p) {
-		pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
+		pr_err("could not ioremap, aborting.\n");
 		return;
 	}
 	mmiotrace_printk("ioremap returned %p.\n", p);
@@ -94,24 +95,22 @@ static int __init init(void)
 	unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
 
 	if (mmio_address == 0) {
-		pr_err(MODULE_NAME ": you have to use the module argument "
-							"mmio_address.\n");
-		pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS"
-				" YOU REALLY KNOW WHAT YOU ARE DOING!\n");
+		pr_err("you have to use the module argument mmio_address.\n");
+		pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
 		return -ENXIO;
 	}
 
-	pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
-		"address space, and writing 16 kB of rubbish in there.\n",
-		 size >> 10, mmio_address);
+	pr_warning("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
+		   "and writing 16 kB of rubbish in there.\n",
+		   size >> 10, mmio_address);
 	do_test(size);
-	pr_info(MODULE_NAME ": All done.\n");
+	pr_info("All done.\n");
 	return 0;
 }
 
 static void __exit cleanup(void)
 {
-	pr_debug(MODULE_NAME ": unloaded.\n");
+	pr_debug("unloaded.\n");
 }
 
 module_init(init);
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/mm/tlb.c linux-libre-2.6.33-gnu1/arch/x86/mm/tlb.c
--- linux-libre-2.6.32-gnu1/arch/x86/mm/tlb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/mm/tlb.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@
 
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
+#include <asm/cache.h>
 #include <asm/apic.h>
 #include <asm/uv/uv.h>
 
@@ -43,7 +44,7 @@ union smp_flush_state {
 		spinlock_t tlbstate_lock;
 		DECLARE_BITMAP(flush_cpumask, NR_CPUS);
 	};
-	char pad[CONFIG_X86_INTERNODE_CACHE_BYTES];
+	char pad[INTERNODE_CACHE_BYTES];
 } ____cacheline_internodealigned_in_smp;
 
 /* State is put into the per CPU data section, but padded
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/oprofile/backtrace.c linux-libre-2.6.33-gnu1/arch/x86/oprofile/backtrace.c
--- linux-libre-2.6.32-gnu1/arch/x86/oprofile/backtrace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/oprofile/backtrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,10 +41,11 @@ static void backtrace_address(void *data
 }
 
 static struct stacktrace_ops backtrace_ops = {
-	.warning = backtrace_warning,
-	.warning_symbol = backtrace_warning_symbol,
-	.stack = backtrace_stack,
-	.address = backtrace_address,
+	.warning	= backtrace_warning,
+	.warning_symbol	= backtrace_warning_symbol,
+	.stack		= backtrace_stack,
+	.address	= backtrace_address,
+	.walk_stack	= print_context_stack,
 };
 
 struct frame_head {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/oprofile/nmi_int.c linux-libre-2.6.33-gnu1/arch/x86/oprofile/nmi_int.c
--- linux-libre-2.6.32-gnu1/arch/x86/oprofile/nmi_int.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/oprofile/nmi_int.c	2010-02-24 13:52:17.000000000 -0500
@@ -222,7 +222,7 @@ static void nmi_cpu_switch(void *dummy)
 
 	/* move to next set */
 	si += model->num_counters;
-	if ((si > model->num_virt_counters) || (counter_config[si].count == 0))
+	if ((si >= model->num_virt_counters) || (counter_config[si].count == 0))
 		per_cpu(switch_index, cpu) = 0;
 	else
 		per_cpu(switch_index, cpu) = si;
@@ -598,6 +598,7 @@ static int __init ppro_init(char **cpu_t
 	case 15: case 23:
 		*cpu_type = "i386/core_2";
 		break;
+	case 0x2e:
 	case 26:
 		spec = &op_arch_perfmon_spec;
 		*cpu_type = "i386/core_i7";
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/acpi.c linux-libre-2.6.33-gnu1/arch/x86/pci/acpi.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,7 @@
 #include <asm/pci_x86.h>
 
 struct pci_root_info {
+	struct acpi_device *bridge;
 	char *name;
 	unsigned int res_num;
 	struct resource *res;
@@ -58,6 +59,30 @@ bus_has_transparent_bridge(struct pci_bu
 	return false;
 }
 
+static void
+align_resource(struct acpi_device *bridge, struct resource *res)
+{
+	int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
+
+	/*
+	 * Host bridge windows are not BARs, but the decoders on the PCI side
+	 * that claim this address space have starting alignment and length
+	 * constraints, so fix any obvious BIOS goofs.
+	 */
+	if (!IS_ALIGNED(res->start, align)) {
+		dev_printk(KERN_DEBUG, &bridge->dev,
+			   "host bridge window %pR invalid; "
+			   "aligning start to %d-byte boundary\n", res, align);
+		res->start &= ~(align - 1);
+	}
+	if (!IS_ALIGNED(res->end + 1, align)) {
+		dev_printk(KERN_DEBUG, &bridge->dev,
+			   "host bridge window %pR invalid; "
+			   "aligning end to %d-byte boundary\n", res, align);
+		res->end = ALIGN(res->end, align) - 1;
+	}
+}
+
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
@@ -91,11 +116,12 @@ setup_resource(struct acpi_resource *acp
 	start = addr.minimum + addr.translation_offset;
 	end = start + addr.address_length - 1;
 	if (info->res_num >= max_root_bus_resources) {
-		printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
-			"from %s for %s due to _CRS returning more than "
-			"%d resource descriptors\n", (unsigned long) start,
-			(unsigned long) end, root->name, info->name,
-			max_root_bus_resources);
+		if (pci_probe & PCI_USE__CRS)
+			printk(KERN_WARNING "PCI: Failed to allocate "
+			       "0x%lx-0x%lx from %s for %s due to _CRS "
+			       "returning more than %d resource descriptors\n",
+			       (unsigned long) start, (unsigned long) end,
+			       root->name, info->name, max_root_bus_resources);
 		return AE_OK;
 	}
 
@@ -105,14 +131,28 @@ setup_resource(struct acpi_resource *acp
 	res->start = start;
 	res->end = end;
 	res->child = NULL;
+	align_resource(info->bridge, res);
+
+	if (!(pci_probe & PCI_USE__CRS)) {
+		dev_printk(KERN_DEBUG, &info->bridge->dev,
+			   "host bridge window %pR (ignored)\n", res);
+		return AE_OK;
+	}
 
 	if (insert_resource(root, res)) {
-		printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
-			"from %s for %s\n", (unsigned long) res->start,
-			(unsigned long) res->end, root->name, info->name);
+		dev_err(&info->bridge->dev,
+			"can't allocate host bridge window %pR\n", res);
 	} else {
 		info->bus->resource[info->res_num] = res;
 		info->res_num++;
+		if (addr.translation_offset)
+			dev_info(&info->bridge->dev, "host bridge window %pR "
+				 "(PCI address [%#llx-%#llx])\n",
+				 res, res->start - addr.translation_offset,
+				 res->end - addr.translation_offset);
+		else
+			dev_info(&info->bridge->dev,
+				 "host bridge window %pR\n", res);
 	}
 	return AE_OK;
 }
@@ -124,6 +164,12 @@ get_current_resources(struct acpi_device
 	struct pci_root_info info;
 	size_t size;
 
+	if (!(pci_probe & PCI_USE__CRS))
+		dev_info(&device->dev,
+			 "ignoring host bridge windows from ACPI; "
+			 "boot with \"pci=use_crs\" to use them\n");
+
+	info.bridge = device;
 	info.bus = bus;
 	info.res_num = 0;
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
@@ -163,8 +209,9 @@ struct pci_bus * __devinit pci_acpi_scan
 #endif
 
 	if (domain && !pci_domains_supported) {
-		printk(KERN_WARNING "PCI: Multiple domains not supported "
-		       "(dom %d, bus %d)\n", domain, busnum);
+		printk(KERN_WARNING "pci_bus %04x:%02x: "
+		       "ignored (multiple domains not supported)\n",
+		       domain, busnum);
 		return NULL;
 	}
 
@@ -188,7 +235,8 @@ struct pci_bus * __devinit pci_acpi_scan
 	 */
 	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
 	if (!sd) {
-		printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
+		printk(KERN_WARNING "pci_bus %04x:%02x: "
+		       "ignored (out of memory)\n", domain, busnum);
 		return NULL;
 	}
 
@@ -209,9 +257,7 @@ struct pci_bus * __devinit pci_acpi_scan
 	} else {
 		bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
 		if (bus) {
-			if (pci_probe & PCI_USE__CRS)
-				get_current_resources(device, busnum, domain,
-							bus);
+			get_current_resources(device, busnum, domain, bus);
 			bus->subordinate = pci_scan_child_bus(bus);
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/amd_bus.c linux-libre-2.6.33-gnu1/arch/x86/pci/amd_bus.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/amd_bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/amd_bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,10 +6,10 @@
 
 #ifdef CONFIG_X86_64
 #include <asm/pci-direct.h>
-#include <asm/mpspec.h>
-#include <linux/cpumask.h>
 #endif
 
+#include "bus_numa.h"
+
 /*
  * This discovers the pcibus <-> node mapping on AMD K8.
  * also get peer root bus resource for io,mmio
@@ -17,67 +17,6 @@
 
 #ifdef CONFIG_X86_64
 
-/*
- * sub bus (transparent) will use entres from 3 to store extra from root,
- * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
- */
-#define RES_NUM 16
-struct pci_root_info {
-	char name[12];
-	unsigned int res_num;
-	struct resource res[RES_NUM];
-	int bus_min;
-	int bus_max;
-	int node;
-	int link;
-};
-
-/* 4 at this time, it may become to 32 */
-#define PCI_ROOT_NR 4
-static int pci_root_num;
-static struct pci_root_info pci_root_info[PCI_ROOT_NR];
-
-void x86_pci_root_bus_res_quirks(struct pci_bus *b)
-{
-	int i;
-	int j;
-	struct pci_root_info *info;
-
-	/* don't go for it if _CRS is used already */
-	if (b->resource[0] != &ioport_resource ||
-	    b->resource[1] != &iomem_resource)
-		return;
-
-	/* if only one root bus, don't need to anything */
-	if (pci_root_num < 2)
-		return;
-
-	for (i = 0; i < pci_root_num; i++) {
-		if (pci_root_info[i].bus_min == b->number)
-			break;
-	}
-
-	if (i == pci_root_num)
-		return;
-
-	printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
-			b->number);
-
-	info = &pci_root_info[i];
-	for (j = 0; j < info->res_num; j++) {
-		struct resource *res;
-		struct resource *root;
-
-		res = &info->res[j];
-		b->resource[j] = res;
-		if (res->flags & IORESOURCE_IO)
-			root = &ioport_resource;
-		else
-			root = &iomem_resource;
-		insert_resource(root, res);
-	}
-}
-
 #define RANGE_NUM 16
 
 struct res_range {
@@ -130,52 +69,6 @@ static void __init update_range(struct r
 	}
 }
 
-static void __init update_res(struct pci_root_info *info, size_t start,
-			      size_t end, unsigned long flags, int merge)
-{
-	int i;
-	struct resource *res;
-
-	if (!merge)
-		goto addit;
-
-	/* try to merge it with old one */
-	for (i = 0; i < info->res_num; i++) {
-		size_t final_start, final_end;
-		size_t common_start, common_end;
-
-		res = &info->res[i];
-		if (res->flags != flags)
-			continue;
-
-		common_start = max((size_t)res->start, start);
-		common_end = min((size_t)res->end, end);
-		if (common_start > common_end + 1)
-			continue;
-
-		final_start = min((size_t)res->start, start);
-		final_end = max((size_t)res->end, end);
-
-		res->start = final_start;
-		res->end = final_end;
-		return;
-	}
-
-addit:
-
-	/* need to add that */
-	if (info->res_num >= RES_NUM)
-		return;
-
-	res = &info->res[info->res_num];
-	res->name = info->name;
-	res->flags = flags;
-	res->start = start;
-	res->end = end;
-	res->child = NULL;
-	info->res_num++;
-}
-
 struct pci_hostbridge_probe {
 	u32 bus;
 	u32 slot;
@@ -230,7 +123,6 @@ static int __init early_fill_mp_bus_info
 	int j;
 	unsigned bus;
 	unsigned slot;
-	int found;
 	int node;
 	int link;
 	int def_node;
@@ -247,7 +139,7 @@ static int __init early_fill_mp_bus_info
 	if (!early_pci_allowed())
 		return -1;
 
-	found = 0;
+	found_all_numa_early = 0;
 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 		u32 id;
 		u16 device;
@@ -261,12 +153,12 @@ static int __init early_fill_mp_bus_info
 		device = (id>>16) & 0xffff;
 		if (pci_probes[i].vendor == vendor &&
 		    pci_probes[i].device == device) {
-			found = 1;
+			found_all_numa_early = 1;
 			break;
 		}
 	}
 
-	if (!found)
+	if (!found_all_numa_early)
 		return 0;
 
 	pci_root_num = 0;
@@ -488,7 +380,7 @@ static int __init early_fill_mp_bus_info
 		info = &pci_root_info[i];
 		res_num = info->res_num;
 		busnum = info->bus_min;
-		printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
+		printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
 		       info->bus_min, info->bus_max, info->node, info->link);
 		for (j = 0; j < res_num; j++) {
 			res = &info->res[j];
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/bus_numa.c linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/bus_numa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include "bus_numa.h"
+
+int pci_root_num;
+struct pci_root_info pci_root_info[PCI_ROOT_NR];
+int found_all_numa_early;
+
+void x86_pci_root_bus_res_quirks(struct pci_bus *b)
+{
+	int i;
+	int j;
+	struct pci_root_info *info;
+
+	/* don't go for it if _CRS is used already */
+	if (b->resource[0] != &ioport_resource ||
+	    b->resource[1] != &iomem_resource)
+		return;
+
+	if (!pci_root_num)
+		return;
+
+	/* for amd, if only one root bus, don't need to do anything */
+	if (pci_root_num < 2 && found_all_numa_early)
+		return;
+
+	for (i = 0; i < pci_root_num; i++) {
+		if (pci_root_info[i].bus_min == b->number)
+			break;
+	}
+
+	if (i == pci_root_num)
+		return;
+
+	printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
+			b->number);
+
+	info = &pci_root_info[i];
+	for (j = 0; j < info->res_num; j++) {
+		struct resource *res;
+		struct resource *root;
+
+		res = &info->res[j];
+		b->resource[j] = res;
+		if (res->flags & IORESOURCE_IO)
+			root = &ioport_resource;
+		else
+			root = &iomem_resource;
+		insert_resource(root, res);
+	}
+}
+
+void __devinit update_res(struct pci_root_info *info, size_t start,
+			      size_t end, unsigned long flags, int merge)
+{
+	int i;
+	struct resource *res;
+
+	if (start > end)
+		return;
+
+	if (!merge)
+		goto addit;
+
+	/* try to merge it with old one */
+	for (i = 0; i < info->res_num; i++) {
+		size_t final_start, final_end;
+		size_t common_start, common_end;
+
+		res = &info->res[i];
+		if (res->flags != flags)
+			continue;
+
+		common_start = max((size_t)res->start, start);
+		common_end = min((size_t)res->end, end);
+		if (common_start > common_end + 1)
+			continue;
+
+		final_start = min((size_t)res->start, start);
+		final_end = max((size_t)res->end, end);
+
+		res->start = final_start;
+		res->end = final_end;
+		return;
+	}
+
+addit:
+
+	/* need to add that */
+	if (info->res_num >= RES_NUM)
+		return;
+
+	res = &info->res[info->res_num];
+	res->name = info->name;
+	res->flags = flags;
+	res->start = start;
+	res->end = end;
+	res->child = NULL;
+	info->res_num++;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/bus_numa.h linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.h
--- linux-libre-2.6.32-gnu1/arch/x86/pci/bus_numa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/bus_numa.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,27 @@
+#ifdef CONFIG_X86_64
+
+/*
+ * sub bus (transparent) will use entres from 3 to store extra from
+ * root, so need to make sure we have enough slot there, Should we
+ * increase PCI_BUS_NUM_RESOURCES?
+ */
+#define RES_NUM 16
+struct pci_root_info {
+	char name[12];
+	unsigned int res_num;
+	struct resource res[RES_NUM];
+	int bus_min;
+	int bus_max;
+	int node;
+	int link;
+};
+
+/* 4 at this time, it may become to 32 */
+#define PCI_ROOT_NR 4
+extern int pci_root_num;
+extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
+extern int found_all_numa_early;
+
+extern void update_res(struct pci_root_info *info, size_t start,
+			      size_t end, unsigned long flags, int merge);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/common.c linux-libre-2.6.33-gnu1/arch/x86/pci/common.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -410,8 +410,6 @@ struct pci_bus * __devinit pcibios_scan_
 	return bus;
 }
 
-extern u8 pci_cache_line_size;
-
 int __init pcibios_init(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
@@ -422,15 +420,19 @@ int __init pcibios_init(void)
 	}
 
 	/*
-	 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8
-	 * and P4. It's also good for 386/486s (which actually have 16)
+	 * Set PCI cacheline size to that of the CPU if the CPU has reported it.
+	 * (For older CPUs that don't support cpuid, we se it to 32 bytes
+	 * It's also good for 386/486s (which actually have 16)
 	 * as quite a few PCI devices do not support smaller values.
 	 */
-	pci_cache_line_size = 32 >> 2;
-	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
-		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
-	else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
-		pci_cache_line_size = 128 >> 2;	/* P4 */
+	if (c->x86_clflush_size > 0) {
+		pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
+		printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
+			pci_dfl_cache_line_size << 2);
+	} else {
+ 		pci_dfl_cache_line_size = 32 >> 2;
+		printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
+	}
 
 	pcibios_resource_survey();
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/early.c linux-libre-2.6.33-gnu1/arch/x86/pci/early.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/early.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/early.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,8 +12,6 @@ u32 read_pci_config(u8 bus, u8 slot, u8
 	u32 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inl(0xcfc);
-	if (v != 0xffffffff)
-		pr_debug("%x reading 4 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
@@ -22,7 +20,6 @@ u8 read_pci_config_byte(u8 bus, u8 slot,
 	u8 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inb(0xcfc + (offset&3));
-	pr_debug("%x reading 1 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
@@ -31,28 +28,24 @@ u16 read_pci_config_16(u8 bus, u8 slot,
 	u16 v;
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	v = inw(0xcfc + (offset&2));
-	pr_debug("%x reading 2 from %x: %x\n", slot, offset, v);
 	return v;
 }
 
 void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
 				    u32 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outl(val, 0xcfc);
 }
 
 void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outb(val, 0xcfc + (offset&3));
 }
 
 void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
 {
-	pr_debug("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
 	outw(val, 0xcfc + (offset&2));
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/i386.c linux-libre-2.6.33-gnu1/arch/x86/pci/i386.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/i386.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/i386.c	2010-02-24 13:52:17.000000000 -0500
@@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_
 					continue;
 				if (!r->start ||
 				    pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
+					dev_info(&dev->dev,
+						 "can't reserve window %pR\n",
+						 r);
 					/*
 					 * Something is wrong with the region.
 					 * Invalidate the resource to prevent
@@ -144,16 +146,29 @@ static void __init pcibios_allocate_bus_
 	}
 }
 
+struct pci_check_idx_range {
+	int start;
+	int end;
+};
+
 static void __init pcibios_allocate_resources(int pass)
 {
 	struct pci_dev *dev = NULL;
-	int idx, disabled;
+	int idx, disabled, i;
 	u16 command;
 	struct resource *r;
 
+	struct pci_check_idx_range idx_range[] = {
+		{ PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
+#ifdef CONFIG_PCI_IOV
+		{ PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
+#endif
+	};
+
 	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+		for (i = 0; i < ARRAY_SIZE(idx_range); i++)
+		for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
 			r = &dev->resource[idx];
 			if (r->parent)		/* Already allocated */
 				continue;
@@ -164,12 +179,12 @@ static void __init pcibios_allocate_reso
 			else
 				disabled = !(command & PCI_COMMAND_MEMORY);
 			if (pass == disabled) {
-				dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n",
-					(unsigned long long) r->start,
-					(unsigned long long) r->end,
-					r->flags, disabled, pass);
+				dev_dbg(&dev->dev,
+					"BAR %d: reserving %pr (d=%d, p=%d)\n",
+					idx, r, disabled, pass);
 				if (pci_claim_resource(dev, idx) < 0) {
-					dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
+					dev_info(&dev->dev,
+						 "can't reserve %pR\n", r);
 					/* We'll assign a new address later */
 					r->end -= r->start;
 					r->start = 0;
@@ -182,7 +197,7 @@ static void __init pcibios_allocate_reso
 				/* Turn the ROM off, leave the resource region,
 				 * but keep it unregistered. */
 				u32 reg;
-				dev_dbg(&dev->dev, "disabling ROM\n");
+				dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
 				r->flags &= ~IORESOURCE_ROM_ENABLE;
 				pci_read_config_dword(dev,
 						dev->rom_base_reg, &reg);
@@ -282,6 +297,15 @@ int pci_mmap_page_range(struct pci_dev *
 		return -EINVAL;
 
 	prot = pgprot_val(vma->vm_page_prot);
+
+	/*
+ 	 * Return error if pat is not enabled and write_combine is requested.
+ 	 * Caller can followup with UC MINUS request and add a WC mtrr if there
+ 	 * is a free mtrr slot.
+ 	 */
+	if (!pat_enabled && write_combine)
+		return -EINVAL;
+
 	if (pat_enabled && write_combine)
 		prot |= _PAGE_CACHE_WC;
 	else if (pat_enabled || boot_cpu_data.x86 > 3)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/Makefile linux-libre-2.6.33-gnu1/arch/x86/pci/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/pci/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,3 +15,8 @@ obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
 
 obj-y				+= common.o early.o
 obj-y				+= amd_bus.o
+obj-$(CONFIG_X86_64)		+= bus_numa.o
+
+ifeq ($(CONFIG_PCI_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig_32.c linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig_32.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig_32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig_32.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,18 +27,10 @@ static int mmcfg_last_accessed_cpu;
  */
 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
 {
-	struct acpi_mcfg_allocation *cfg;
-	int cfg_num;
-
-	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
-		cfg = &pci_mmcfg_config[cfg_num];
-		if (cfg->pci_segment == seg &&
-		    (cfg->start_bus_number <= bus) &&
-		    (cfg->end_bus_number >= bus))
-			return cfg->address;
-	}
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
 
-	/* Fall back to type 0 */
+	if (cfg)
+		return cfg->address;
 	return 0;
 }
 
@@ -47,7 +39,7 @@ static u32 get_base_addr(unsigned int se
  */
 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
-	u32 dev_base = base | (bus << 20) | (devfn << 12);
+	u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
 	int cpu = smp_processor_id();
 	if (dev_base != mmcfg_last_accessed_device ||
 	    cpu != mmcfg_last_accessed_cpu) {
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig_64.c linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig_64.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig_64.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig_64.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,38 +12,15 @@
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
-/* Static virtual mapping of the MMCONFIG aperture */
-struct mmcfg_virt {
-	struct acpi_mcfg_allocation *cfg;
-	char __iomem *virt;
-};
-static struct mmcfg_virt *pci_mmcfg_virt;
-
-static char __iomem *get_virt(unsigned int seg, unsigned bus)
-{
-	struct acpi_mcfg_allocation *cfg;
-	int cfg_num;
-
-	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
-		cfg = pci_mmcfg_virt[cfg_num].cfg;
-		if (cfg->pci_segment == seg &&
-		    (cfg->start_bus_number <= bus) &&
-		    (cfg->end_bus_number >= bus))
-			return pci_mmcfg_virt[cfg_num].virt;
-	}
-
-	/* Fall back to type 0 */
-	return NULL;
-}
+#define PREFIX "PCI: "
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-	char __iomem *addr;
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
 
-	addr = get_virt(seg, bus);
-	if (!addr)
-		return NULL;
- 	return addr + ((bus << 20) | (devfn << 12));
+	if (cfg && cfg->virt)
+		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+	return NULL;
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
@@ -109,42 +86,30 @@ static struct pci_raw_ops pci_mmcfg = {
 	.write =	pci_mmcfg_write,
 };
 
-static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
+static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
 {
 	void __iomem *addr;
 	u64 start, size;
+	int num_buses;
 
-	start = cfg->start_bus_number;
-	start <<= 20;
-	start += cfg->address;
-	size = cfg->end_bus_number + 1 - cfg->start_bus_number;
-	size <<= 20;
+	start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
+	num_buses = cfg->end_bus - cfg->start_bus + 1;
+	size = PCI_MMCFG_BUS_OFFSET(num_buses);
 	addr = ioremap_nocache(start, size);
-	if (addr) {
-		printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
-		       start, start + size - 1);
-		addr -= cfg->start_bus_number << 20;
-	}
+	if (addr)
+		addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
 	return addr;
 }
 
 int __init pci_mmcfg_arch_init(void)
 {
-	int i;
-	pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
-				 pci_mmcfg_config_num, GFP_KERNEL);
-	if (pci_mmcfg_virt == NULL) {
-		printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
-		return 0;
-	}
+	struct pci_mmcfg_region *cfg;
 
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
-		pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
-		if (!pci_mmcfg_virt[i].virt) {
-			printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
-					"segment %d\n",
-				pci_mmcfg_config[i].pci_segment);
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		cfg->virt = mcfg_ioremap(cfg);
+		if (!cfg->virt) {
+			printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
+			       &cfg->res);
 			pci_mmcfg_arch_free();
 			return 0;
 		}
@@ -155,19 +120,12 @@ int __init pci_mmcfg_arch_init(void)
 
 void __init pci_mmcfg_arch_free(void)
 {
-	int i;
-
-	if (pci_mmcfg_virt == NULL)
-		return;
+	struct pci_mmcfg_region *cfg;
 
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		if (pci_mmcfg_virt[i].virt) {
-			iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20));
-			pci_mmcfg_virt[i].virt = NULL;
-			pci_mmcfg_virt[i].cfg = NULL;
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->virt) {
+			iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+			cfg->virt = NULL;
 		}
 	}
-
-	kfree(pci_mmcfg_virt);
-	pci_mmcfg_virt = NULL;
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig-shared.c linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig-shared.c
--- linux-libre-2.6.32-gnu1/arch/x86/pci/mmconfig-shared.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/pci/mmconfig-shared.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,48 +15,98 @@
 #include <linux/acpi.h>
 #include <linux/sfi_acpi.h>
 #include <linux/bitmap.h>
-#include <linux/sort.h>
+#include <linux/dmi.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
 
 #define PREFIX "PCI: "
 
-/* aperture is up to 256MB but BIOS may reserve less */
-#define MMCONFIG_APER_MIN	(2 * 1024*1024)
-#define MMCONFIG_APER_MAX	(256 * 1024*1024)
-
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static int __initdata pci_mmcfg_resources_inserted;
 
-static __init int extend_mmcfg(int num)
+LIST_HEAD(pci_mmcfg_list);
+
+static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
 {
-	struct acpi_mcfg_allocation *new;
-	int new_num = pci_mmcfg_config_num + num;
+	if (cfg->res.parent)
+		release_resource(&cfg->res);
+	list_del(&cfg->list);
+	kfree(cfg);
+}
 
-	new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL);
-	if (!new)
-		return -1;
+static __init void free_all_mmcfg(void)
+{
+	struct pci_mmcfg_region *cfg, *tmp;
 
-	if (pci_mmcfg_config) {
-		memcpy(new, pci_mmcfg_config,
-			 sizeof(pci_mmcfg_config[0]) * new_num);
-		kfree(pci_mmcfg_config);
+	pci_mmcfg_arch_free();
+	list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
+		pci_mmconfig_remove(cfg);
+}
+
+static __init void list_add_sorted(struct pci_mmcfg_region *new)
+{
+	struct pci_mmcfg_region *cfg;
+
+	/* keep list sorted by segment and starting bus number */
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->segment > new->segment ||
+		    (cfg->segment == new->segment &&
+		     cfg->start_bus >= new->start_bus)) {
+			list_add_tail(&new->list, &cfg->list);
+			return;
+		}
 	}
-	pci_mmcfg_config = new;
+	list_add_tail(&new->list, &pci_mmcfg_list);
+}
 
-	return 0;
+static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+							int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+	int num_buses;
+	struct resource *res;
+
+	if (addr == 0)
+		return NULL;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	new->address = addr;
+	new->segment = segment;
+	new->start_bus = start;
+	new->end_bus = end;
+
+	list_add_sorted(new);
+
+	num_buses = end - start + 1;
+	res = &new->res;
+	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
+	res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+	res->name = new->name;
+
+	printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at "
+	       "%pR (base %#lx)\n", segment, start, end, &new->res,
+	       (unsigned long) addr);
+
+	return new;
 }
 
-static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end)
+struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
 {
-	int i = pci_mmcfg_config_num;
+	struct pci_mmcfg_region *cfg;
 
-	pci_mmcfg_config_num++;
-	pci_mmcfg_config[i].address = addr;
-	pci_mmcfg_config[i].pci_segment = segment;
-	pci_mmcfg_config[i].start_bus_number = start;
-	pci_mmcfg_config[i].end_bus_number = end;
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == segment &&
+		    cfg->start_bus <= bus && bus <= cfg->end_bus)
+			return cfg;
+
+	return NULL;
 }
 
 static const char __init *pci_mmcfg_e7520(void)
@@ -68,11 +118,9 @@ static const char __init *pci_mmcfg_e752
 	if (win == 0x0000 || win == 0xf000)
 		return NULL;
 
-	if (extend_mmcfg(1) == -1)
+	if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
 		return NULL;
 
-	fill_one_mmcfg(win << 16, 0, 0, 255);
-
 	return "Intel Corporation E7520 Memory Controller Hub";
 }
 
@@ -114,11 +162,9 @@ static const char __init *pci_mmcfg_inte
 	if ((pciexbar & mask) >= 0xf0000000U)
 		return NULL;
 
-	if (extend_mmcfg(1) == -1)
+	if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
 		return NULL;
 
-	fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
-
 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
 }
 
@@ -127,7 +173,7 @@ static const char __init *pci_mmcfg_amd_
 	u32 low, high, address;
 	u64 base, msr;
 	int i;
-	unsigned segnbits = 0, busnbits;
+	unsigned segnbits = 0, busnbits, end_bus;
 
 	if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
 		return NULL;
@@ -161,11 +207,13 @@ static const char __init *pci_mmcfg_amd_
 		busnbits = 8;
 	}
 
-	if (extend_mmcfg(1 << segnbits) == -1)
-		return NULL;
-
+	end_bus = (1 << busnbits) - 1;
 	for (i = 0; i < (1 << segnbits); i++)
-		fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1);
+		if (pci_mmconfig_add(i, 0, end_bus,
+				     base + (1<<28) * i) == NULL) {
+			free_all_mmcfg();
+			return NULL;
+		}
 
 	return "AMD Family 10h NB";
 }
@@ -190,7 +238,7 @@ static const char __init *pci_mmcfg_nvid
 	/*
 	 * do check if amd fam10h already took over
 	 */
-	if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked)
+	if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
 		return NULL;
 
 	mcp55_checked = true;
@@ -213,16 +261,14 @@ static const char __init *pci_mmcfg_nvid
 		if (!(extcfg & extcfg_enable_mask))
 			continue;
 
-		if (extend_mmcfg(1) == -1)
-			continue;
-
 		size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
 		base = extcfg & extcfg_base_mask[size_index];
 		/* base could > 4G */
 		base <<= extcfg_base_lshift;
 		start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
 		end = start + extcfg_sizebus[size_index] - 1;
-		fill_one_mmcfg(base, 0, start, end);
+		if (pci_mmconfig_add(0, start, end, base) == NULL)
+			continue;
 		mcp55_mmconf_found++;
 	}
 
@@ -253,45 +299,27 @@ static struct pci_mmcfg_hostbridge_probe
 	  0x0369, pci_mmcfg_nvidia_mcp55 },
 };
 
-static int __init cmp_mmcfg(const void *x1, const void *x2)
-{
-	const typeof(pci_mmcfg_config[0]) *m1 = x1;
-	const typeof(pci_mmcfg_config[0]) *m2 = x2;
-	int start1, start2;
-
-	start1 = m1->start_bus_number;
-	start2 = m2->start_bus_number;
-
-	return start1 - start2;
-}
-
 static void __init pci_mmcfg_check_end_bus_number(void)
 {
-	int i;
-	typeof(pci_mmcfg_config[0]) *cfg, *cfgx;
-
-	/* sort them at first */
-	sort(pci_mmcfg_config, pci_mmcfg_config_num,
-		 sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL);
+	struct pci_mmcfg_region *cfg, *cfgx;
 
 	/* last one*/
-	if (pci_mmcfg_config_num > 0) {
-		i = pci_mmcfg_config_num - 1;
-		cfg = &pci_mmcfg_config[i];
-		if (cfg->end_bus_number < cfg->start_bus_number)
-			cfg->end_bus_number = 255;
-	}
+	cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list);
+	if (cfg)
+		if (cfg->end_bus < cfg->start_bus)
+			cfg->end_bus = 255;
 
-	/* don't overlap please */
-	for (i = 0; i < pci_mmcfg_config_num - 1; i++) {
-		cfg = &pci_mmcfg_config[i];
-		cfgx = &pci_mmcfg_config[i+1];
+	if (list_is_singular(&pci_mmcfg_list))
+		return;
 
-		if (cfg->end_bus_number < cfg->start_bus_number)
-			cfg->end_bus_number = 255;
+	/* don't overlap please */
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+		if (cfg->end_bus < cfg->start_bus)
+			cfg->end_bus = 255;
 
-		if (cfg->end_bus_number >= cfgx->start_bus_number)
-			cfg->end_bus_number = cfgx->start_bus_number - 1;
+		cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
+		if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus)
+			cfg->end_bus = cfgx->start_bus - 1;
 	}
 }
 
@@ -306,8 +334,7 @@ static int __init pci_mmcfg_check_hostbr
 	if (!raw_pci_ops)
 		return 0;
 
-	pci_mmcfg_config_num = 0;
-	pci_mmcfg_config = NULL;
+	free_all_mmcfg();
 
 	for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
 		bus =  pci_mmcfg_probes[i].bus;
@@ -322,45 +349,22 @@ static int __init pci_mmcfg_check_hostbr
 			name = pci_mmcfg_probes[i].probe();
 
 		if (name)
-			printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n",
+			printk(KERN_INFO PREFIX "%s with MMCONFIG support\n",
 			       name);
 	}
 
 	/* some end_bus_number is crazy, fix it */
 	pci_mmcfg_check_end_bus_number();
 
-	return pci_mmcfg_config_num != 0;
+	return !list_empty(&pci_mmcfg_list);
 }
 
 static void __init pci_mmcfg_insert_resources(void)
 {
-#define PCI_MMCFG_RESOURCE_NAME_LEN 24
-	int i;
-	struct resource *res;
-	char *names;
-	unsigned num_buses;
-
-	res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
-			pci_mmcfg_config_num, GFP_KERNEL);
-	if (!res) {
-		printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
-		return;
-	}
+	struct pci_mmcfg_region *cfg;
 
-	names = (void *)&res[pci_mmcfg_config_num];
-	for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
-		struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
-		num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
-		res->name = names;
-		snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN,
-			 "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment,
-			 cfg->start_bus_number, cfg->end_bus_number);
-		res->start = cfg->address + (cfg->start_bus_number << 20);
-		res->end = res->start + (num_buses << 20) - 1;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		insert_resource(&iomem_resource, res);
-		names += PCI_MMCFG_RESOURCE_NAME_LEN;
-	}
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		insert_resource(&iomem_resource, &cfg->res);
 
 	/* Mark that the resources have been inserted. */
 	pci_mmcfg_resources_inserted = 1;
@@ -437,11 +441,12 @@ static int __init is_acpi_reserved(u64 s
 typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
 static int __init is_mmconf_reserved(check_reserved_t is_reserved,
-		u64 addr, u64 size, int i,
-		typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
+				    struct pci_mmcfg_region *cfg, int with_e820)
 {
+	u64 addr = cfg->res.start;
+	u64 size = resource_size(&cfg->res);
 	u64 old_size = size;
-	int valid = 0;
+	int valid = 0, num_buses;
 
 	while (!is_reserved(addr, addr + size, E820_RESERVED)) {
 		size >>= 1;
@@ -450,19 +455,25 @@ static int __init is_mmconf_reserved(che
 	}
 
 	if (size >= (16UL<<20) || size == old_size) {
-		printk(KERN_NOTICE
-		       "PCI: MCFG area at %Lx reserved in %s\n",
-			addr, with_e820?"E820":"ACPI motherboard resources");
+		printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
+		       &cfg->res,
+		       with_e820 ? "E820" : "ACPI motherboard resources");
 		valid = 1;
 
 		if (old_size != size) {
-			/* update end_bus_number */
-			cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1);
-			printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx "
-			       "segment %hu buses %u - %u\n",
-			       i, (unsigned long)cfg->address, cfg->pci_segment,
-			       (unsigned int)cfg->start_bus_number,
-			       (unsigned int)cfg->end_bus_number);
+			/* update end_bus */
+			cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
+			num_buses = cfg->end_bus - cfg->start_bus + 1;
+			cfg->res.end = cfg->res.start +
+			    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+			snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+				 "PCI MMCONFIG %04x [bus %02x-%02x]",
+				 cfg->segment, cfg->start_bus, cfg->end_bus);
+			printk(KERN_INFO PREFIX
+			       "MMCONFIG for %04x [bus%02x-%02x] "
+			       "at %pR (base %#lx) (size reduced!)\n",
+			       cfg->segment, cfg->start_bus, cfg->end_bus,
+			       &cfg->res, (unsigned long) cfg->address);
 		}
 	}
 
@@ -471,45 +482,26 @@ static int __init is_mmconf_reserved(che
 
 static void __init pci_mmcfg_reject_broken(int early)
 {
-	typeof(pci_mmcfg_config[0]) *cfg;
-	int i;
-
-	if ((pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
-		return;
+	struct pci_mmcfg_region *cfg;
 
-	for (i = 0; i < pci_mmcfg_config_num; i++) {
+	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
 		int valid = 0;
-		u64 addr, size;
-
-		cfg = &pci_mmcfg_config[i];
-		addr = cfg->start_bus_number;
-		addr <<= 20;
-		addr += cfg->address;
-		size = cfg->end_bus_number + 1 - cfg->start_bus_number;
-		size <<= 20;
-		printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
-		       "segment %hu buses %u - %u\n",
-		       i, (unsigned long)cfg->address, cfg->pci_segment,
-		       (unsigned int)cfg->start_bus_number,
-		       (unsigned int)cfg->end_bus_number);
 
 		if (!early && !acpi_disabled)
-			valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0);
+			valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0);
 
 		if (valid)
 			continue;
 
 		if (!early)
-			printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
-			       " reserved in ACPI motherboard resources\n",
-			       cfg->address);
+			printk(KERN_ERR FW_BUG PREFIX
+			       "MMCONFIG at %pR not reserved in "
+			       "ACPI motherboard resources\n", &cfg->res);
 
 		/* Don't try to do this check unless configuration
 		   type 1 is available. how about type 2 ?*/
 		if (raw_pci_ops)
-			valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1);
+			valid = is_mmconf_reserved(e820_all_mapped, cfg, 1);
 
 		if (!valid)
 			goto reject;
@@ -518,34 +510,41 @@ static void __init pci_mmcfg_reject_brok
 	return;
 
 reject:
-	printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
-	pci_mmcfg_arch_free();
-	kfree(pci_mmcfg_config);
-	pci_mmcfg_config = NULL;
-	pci_mmcfg_config_num = 0;
+	printk(KERN_INFO PREFIX "not using MMCONFIG\n");
+	free_all_mmcfg();
 }
 
 static int __initdata known_bridge;
 
-static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
+static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
+					struct acpi_mcfg_allocation *cfg)
+{
+	int year;
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-struct acpi_mcfg_allocation *pci_mmcfg_config;
-int pci_mmcfg_config_num;
+	if (cfg->address < 0xFFFFFFFF)
+		return 0;
 
-static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
-{
 	if (!strcmp(mcfg->header.oem_id, "SGI"))
-		acpi_mcfg_64bit_base_addr = TRUE;
+		return 0;
 
-	return 0;
+	if (mcfg->header.revision >= 1) {
+		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
+		    year >= 2010)
+			return 0;
+	}
+
+	printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
+	       "is above 4GB, ignored\n", cfg->pci_segment,
+	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
+	return -EINVAL;
 }
 
 static int __init pci_parse_mcfg(struct acpi_table_header *header)
 {
 	struct acpi_table_mcfg *mcfg;
+	struct acpi_mcfg_allocation *cfg_table, *cfg;
 	unsigned long i;
-	int config_size;
+	int entries;
 
 	if (!header)
 		return -EINVAL;
@@ -553,38 +552,33 @@ static int __init pci_parse_mcfg(struct
 	mcfg = (struct acpi_table_mcfg *)header;
 
 	/* how many config structures do we have */
-	pci_mmcfg_config_num = 0;
+	free_all_mmcfg();
+	entries = 0;
 	i = header->length - sizeof(struct acpi_table_mcfg);
 	while (i >= sizeof(struct acpi_mcfg_allocation)) {
-		++pci_mmcfg_config_num;
+		entries++;
 		i -= sizeof(struct acpi_mcfg_allocation);
 	};
-	if (pci_mmcfg_config_num == 0) {
+	if (entries == 0) {
 		printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
 		return -ENODEV;
 	}
 
-	config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
-	pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
-	if (!pci_mmcfg_config) {
-		printk(KERN_WARNING PREFIX
-		       "No memory for MCFG config tables\n");
-		return -ENOMEM;
-	}
-
-	memcpy(pci_mmcfg_config, &mcfg[1], config_size);
-
-	acpi_mcfg_oem_check(mcfg);
-
-	for (i = 0; i < pci_mmcfg_config_num; ++i) {
-		if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
-		    !acpi_mcfg_64bit_base_addr) {
-			printk(KERN_ERR PREFIX
-			       "MMCONFIG not in low 4GB of memory\n");
-			kfree(pci_mmcfg_config);
-			pci_mmcfg_config_num = 0;
+	cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
+	for (i = 0; i < entries; i++) {
+		cfg = &cfg_table[i];
+		if (acpi_mcfg_check_entry(mcfg, cfg)) {
+			free_all_mmcfg();
 			return -ENODEV;
 		}
+
+		if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
+				   cfg->end_bus_number, cfg->address) == NULL) {
+			printk(KERN_WARNING PREFIX
+			       "no memory for MCFG entries\n");
+			free_all_mmcfg();
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -614,9 +608,7 @@ static void __init __pci_mmcfg_init(int
 
 	pci_mmcfg_reject_broken(early);
 
-	if ((pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
+	if (list_empty(&pci_mmcfg_list))
 		return;
 
 	if (pci_mmcfg_arch_init())
@@ -648,9 +640,7 @@ static int __init pci_mmcfg_late_insert_
 	 */
 	if ((pci_mmcfg_resources_inserted == 1) ||
 	    (pci_probe & PCI_PROBE_MMCONF) == 0 ||
-	    (pci_mmcfg_config_num == 0) ||
-	    (pci_mmcfg_config == NULL) ||
-	    (pci_mmcfg_config[0].address == 0))
+	    list_empty(&pci_mmcfg_list))
 		return 1;
 
 	/*
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/power/cpu.c linux-libre-2.6.33-gnu1/arch/x86/power/cpu.c
--- linux-libre-2.6.32-gnu1/arch/x86/power/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/power/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <asm/mce.h>
 #include <asm/xcr.h>
 #include <asm/suspend.h>
+#include <asm/debugreg.h>
 
 #ifdef CONFIG_X86_32
 static struct saved_context saved_context;
@@ -142,31 +143,6 @@ static void fix_processor_context(void)
 #endif
 	load_TR_desc();				/* This does ltr */
 	load_LDT(&current->active_mm->context);	/* This does lldt */
-
-	/*
-	 * Now maybe reload the debug registers
-	 */
-	if (current->thread.debugreg7) {
-#ifdef CONFIG_X86_32
-		set_debugreg(current->thread.debugreg0, 0);
-		set_debugreg(current->thread.debugreg1, 1);
-		set_debugreg(current->thread.debugreg2, 2);
-		set_debugreg(current->thread.debugreg3, 3);
-		/* no 4 and 5 */
-		set_debugreg(current->thread.debugreg6, 6);
-		set_debugreg(current->thread.debugreg7, 7);
-#else
-		/* CONFIG_X86_64 */
-		loaddebug(&current->thread, 0);
-		loaddebug(&current->thread, 1);
-		loaddebug(&current->thread, 2);
-		loaddebug(&current->thread, 3);
-		/* no 4 and 5 */
-		loaddebug(&current->thread, 6);
-		loaddebug(&current->thread, 7);
-#endif
-	}
-
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/tools/chkobjdump.awk linux-libre-2.6.33-gnu1/arch/x86/tools/chkobjdump.awk
--- linux-libre-2.6.32-gnu1/arch/x86/tools/chkobjdump.awk	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/tools/chkobjdump.awk	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+# GNU objdump version checker
+#
+# Usage:
+# objdump -v | awk -f chkobjdump.awk
+BEGIN {
+	# objdump version 2.19 or later is OK for the test.
+	od_ver = 2;
+	od_sver = 19;
+}
+
+/^GNU objdump/ {
+	verstr = ""
+	for (i = 3; i <= NF; i++)
+		if (match($(i), "^[0-9]")) {
+			verstr = $(i);
+			break;
+		}
+	if (verstr == "") {
+		printf("Warning: Failed to find objdump version number.\n");
+		exit 0;
+	}
+	split(verstr, ver, ".");
+	if (ver[1] > od_ver ||
+	    (ver[1] == od_ver && ver[2] >= od_sver)) {
+		exit 1;
+	} else {
+		printf("Warning: objdump version %s is older than %d.%d\n",
+		       verstr, od_ver, od_sver);
+		print("Warning: Skipping posttest.");
+		# Logic is inverted, because we just skip test without error.
+		exit 0;
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/tools/distill.awk linux-libre-2.6.33-gnu1/arch/x86/tools/distill.awk
--- linux-libre-2.6.32-gnu1/arch/x86/tools/distill.awk	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/tools/distill.awk	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,47 @@
+#!/bin/awk -f
+# Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
+# Distills the disassembly as follows:
+# - Removes all lines except the disassembled instructions.
+# - For instructions that exceed 1 line (7 bytes), crams all the hex bytes
+# into a single line.
+# - Remove bad(or prefix only) instructions
+
+BEGIN {
+	prev_addr = ""
+	prev_hex = ""
+	prev_mnemonic = ""
+	bad_expr = "(\\(bad\\)|^rex|^.byte|^rep(z|nz)$|^lock$|^es$|^cs$|^ss$|^ds$|^fs$|^gs$|^data(16|32)$|^addr(16|32|64))"
+	fwait_expr = "^9b "
+	fwait_str="9b\tfwait"
+}
+
+/^ *[0-9a-f]+ <[^>]*>:/ {
+	# Symbol entry
+	printf("%s%s\n", $2, $1)
+}
+
+/^ *[0-9a-f]+:/ {
+	if (split($0, field, "\t") < 3) {
+		# This is a continuation of the same insn.
+		prev_hex = prev_hex field[2]
+	} else {
+		# Skip bad instructions
+		if (match(prev_mnemonic, bad_expr))
+			prev_addr = ""
+		# Split fwait from other f* instructions
+		if (match(prev_hex, fwait_expr) && prev_mnemonic != "fwait") {
+			printf "%s\t%s\n", prev_addr, fwait_str
+			sub(fwait_expr, "", prev_hex)
+		}
+		if (prev_addr != "")
+			printf "%s\t%s\t%s\n", prev_addr, prev_hex, prev_mnemonic
+		prev_addr = field[1]
+		prev_hex = field[2]
+		prev_mnemonic = field[3]
+	}
+}
+
+END {
+	if (prev_addr != "")
+		printf "%s\t%s\t%s\n", prev_addr, prev_hex, prev_mnemonic
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/tools/gen-insn-attr-x86.awk linux-libre-2.6.33-gnu1/arch/x86/tools/gen-insn-attr-x86.awk
--- linux-libre-2.6.32-gnu1/arch/x86/tools/gen-insn-attr-x86.awk	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/tools/gen-insn-attr-x86.awk	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,378 @@
+#!/bin/awk -f
+# gen-insn-attr-x86.awk: Instruction attribute table generator
+# Written by Masami Hiramatsu <mhiramat@redhat.com>
+#
+# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
+
+# Awk implementation sanity check
+function check_awk_implement() {
+	if (sprintf("%x", 0) != "0")
+		return "Your awk has a printf-format problem."
+	return ""
+}
+
+# Clear working vars
+function clear_vars() {
+	delete table
+	delete lptable2
+	delete lptable1
+	delete lptable3
+	eid = -1 # escape id
+	gid = -1 # group id
+	aid = -1 # AVX id
+	tname = ""
+}
+
+BEGIN {
+	# Implementation error checking
+	awkchecked = check_awk_implement()
+	if (awkchecked != "") {
+		print "Error: " awkchecked > "/dev/stderr"
+		print "Please try to use gawk." > "/dev/stderr"
+		exit 1
+	}
+
+	# Setup generating tables
+	print "/* x86 opcode map generated from x86-opcode-map.txt */"
+	print "/* Do not change this code. */\n"
+	ggid = 1
+	geid = 1
+	gaid = 0
+	delete etable
+	delete gtable
+	delete atable
+
+	opnd_expr = "^[A-Za-z/]"
+	ext_expr = "^\\("
+	sep_expr = "^\\|$"
+	group_expr = "^Grp[0-9A-Za-z]+"
+
+	imm_expr = "^[IJAO][a-z]"
+	imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
+	imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
+	imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
+	imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)"
+	imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)"
+	imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)"
+	imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
+	imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)"
+	imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)"
+	imm_flag["Ob"] = "INAT_MOFFSET"
+	imm_flag["Ov"] = "INAT_MOFFSET"
+
+	modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
+	force64_expr = "\\([df]64\\)"
+	rex_expr = "^REX(\\.[XRWB]+)*"
+	fpu_expr = "^ESC" # TODO
+
+	lprefix1_expr = "\\(66\\)"
+	lprefix2_expr = "\\(F3\\)"
+	lprefix3_expr = "\\(F2\\)"
+	max_lprefix = 4
+
+	vexok_expr = "\\(VEX\\)"
+	vexonly_expr = "\\(oVEX\\)"
+
+	prefix_expr = "\\(Prefix\\)"
+	prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
+	prefix_num["REPNE"] = "INAT_PFX_REPNE"
+	prefix_num["REP/REPE"] = "INAT_PFX_REPE"
+	prefix_num["LOCK"] = "INAT_PFX_LOCK"
+	prefix_num["SEG=CS"] = "INAT_PFX_CS"
+	prefix_num["SEG=DS"] = "INAT_PFX_DS"
+	prefix_num["SEG=ES"] = "INAT_PFX_ES"
+	prefix_num["SEG=FS"] = "INAT_PFX_FS"
+	prefix_num["SEG=GS"] = "INAT_PFX_GS"
+	prefix_num["SEG=SS"] = "INAT_PFX_SS"
+	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
+	prefix_num["2bytes-VEX"] = "INAT_PFX_VEX2"
+	prefix_num["3bytes-VEX"] = "INAT_PFX_VEX3"
+
+	clear_vars()
+}
+
+function semantic_error(msg) {
+	print "Semantic error at " NR ": " msg > "/dev/stderr"
+	exit 1
+}
+
+function debug(msg) {
+	print "DEBUG: " msg
+}
+
+function array_size(arr,   i,c) {
+	c = 0
+	for (i in arr)
+		c++
+	return c
+}
+
+/^Table:/ {
+	print "/* " $0 " */"
+	if (tname != "")
+		semantic_error("Hit Table: before EndTable:.");
+}
+
+/^Referrer:/ {
+	if (NF != 1) {
+		# escape opcode table
+		ref = ""
+		for (i = 2; i <= NF; i++)
+			ref = ref $i
+		eid = escape[ref]
+		tname = sprintf("inat_escape_table_%d", eid)
+	}
+}
+
+/^AVXcode:/ {
+	if (NF != 1) {
+		# AVX/escape opcode table
+		aid = $2
+		if (gaid <= aid)
+			gaid = aid + 1
+		if (tname == "")	# AVX only opcode table
+			tname = sprintf("inat_avx_table_%d", $2)
+	}
+	if (aid == -1 && eid == -1)	# primary opcode table
+		tname = "inat_primary_table"
+}
+
+/^GrpTable:/ {
+	print "/* " $0 " */"
+	if (!($2 in group))
+		semantic_error("No group: " $2 )
+	gid = group[$2]
+	tname = "inat_group_table_" gid
+}
+
+function print_table(tbl,name,fmt,n)
+{
+	print "const insn_attr_t " name " = {"
+	for (i = 0; i < n; i++) {
+		id = sprintf(fmt, i)
+		if (tbl[id])
+			print "	[" id "] = " tbl[id] ","
+	}
+	print "};"
+}
+
+/^EndTable/ {
+	if (gid != -1) {
+		# print group tables
+		if (array_size(table) != 0) {
+			print_table(table, tname "[INAT_GROUP_TABLE_SIZE]",
+				    "0x%x", 8)
+			gtable[gid,0] = tname
+		}
+		if (array_size(lptable1) != 0) {
+			print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]",
+				    "0x%x", 8)
+			gtable[gid,1] = tname "_1"
+		}
+		if (array_size(lptable2) != 0) {
+			print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]",
+				    "0x%x", 8)
+			gtable[gid,2] = tname "_2"
+		}
+		if (array_size(lptable3) != 0) {
+			print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]",
+				    "0x%x", 8)
+			gtable[gid,3] = tname "_3"
+		}
+	} else {
+		# print primary/escaped tables
+		if (array_size(table) != 0) {
+			print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]",
+				    "0x%02x", 256)
+			etable[eid,0] = tname
+			if (aid >= 0)
+				atable[aid,0] = tname
+		}
+		if (array_size(lptable1) != 0) {
+			print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]",
+				    "0x%02x", 256)
+			etable[eid,1] = tname "_1"
+			if (aid >= 0)
+				atable[aid,1] = tname "_1"
+		}
+		if (array_size(lptable2) != 0) {
+			print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]",
+				    "0x%02x", 256)
+			etable[eid,2] = tname "_2"
+			if (aid >= 0)
+				atable[aid,2] = tname "_2"
+		}
+		if (array_size(lptable3) != 0) {
+			print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]",
+				    "0x%02x", 256)
+			etable[eid,3] = tname "_3"
+			if (aid >= 0)
+				atable[aid,3] = tname "_3"
+		}
+	}
+	print ""
+	clear_vars()
+}
+
+function add_flags(old,new) {
+	if (old && new)
+		return old " | " new
+	else if (old)
+		return old
+	else
+		return new
+}
+
+# convert operands to flags.
+function convert_operands(count,opnd,       i,j,imm,mod)
+{
+	imm = null
+	mod = null
+	for (j = 1; j <= count; j++) {
+		i = opnd[j]
+		if (match(i, imm_expr) == 1) {
+			if (!imm_flag[i])
+				semantic_error("Unknown imm opnd: " i)
+			if (imm) {
+				if (i != "Ib")
+					semantic_error("Second IMM error")
+				imm = add_flags(imm, "INAT_SCNDIMM")
+			} else
+				imm = imm_flag[i]
+		} else if (match(i, modrm_expr))
+			mod = "INAT_MODRM"
+	}
+	return add_flags(imm, mod)
+}
+
+/^[0-9a-f]+\:/ {
+	if (NR == 1)
+		next
+	# get index
+	idx = "0x" substr($1, 1, index($1,":") - 1)
+	if (idx in table)
+		semantic_error("Redefine " idx " in " tname)
+
+	# check if escaped opcode
+	if ("escape" == $2) {
+		if ($3 != "#")
+			semantic_error("No escaped name")
+		ref = ""
+		for (i = 4; i <= NF; i++)
+			ref = ref $i
+		if (ref in escape)
+			semantic_error("Redefine escape (" ref ")")
+		escape[ref] = geid
+		geid++
+		table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")"
+		next
+	}
+
+	variant = null
+	# converts
+	i = 2
+	while (i <= NF) {
+		opcode = $(i++)
+		delete opnds
+		ext = null
+		flags = null
+		opnd = null
+		# parse one opcode
+		if (match($i, opnd_expr)) {
+			opnd = $i
+			count = split($(i++), opnds, ",")
+			flags = convert_operands(count, opnds)
+		}
+		if (match($i, ext_expr))
+			ext = $(i++)
+		if (match($i, sep_expr))
+			i++
+		else if (i < NF)
+			semantic_error($i " is not a separator")
+
+		# check if group opcode
+		if (match(opcode, group_expr)) {
+			if (!(opcode in group)) {
+				group[opcode] = ggid
+				ggid++
+			}
+			flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")")
+		}
+		# check force(or default) 64bit
+		if (match(ext, force64_expr))
+			flags = add_flags(flags, "INAT_FORCE64")
+
+		# check REX prefix
+		if (match(opcode, rex_expr))
+			flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
+
+		# check coprocessor escape : TODO
+		if (match(opcode, fpu_expr))
+			flags = add_flags(flags, "INAT_MODRM")
+
+		# check VEX only code
+		if (match(ext, vexonly_expr))
+			flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
+
+		# check VEX only code
+		if (match(ext, vexok_expr))
+			flags = add_flags(flags, "INAT_VEXOK")
+
+		# check prefixes
+		if (match(ext, prefix_expr)) {
+			if (!prefix_num[opcode])
+				semantic_error("Unknown prefix: " opcode)
+			flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")")
+		}
+		if (length(flags) == 0)
+			continue
+		# check if last prefix
+		if (match(ext, lprefix1_expr)) {
+			lptable1[idx] = add_flags(lptable1[idx],flags)
+			variant = "INAT_VARIANT"
+		} else if (match(ext, lprefix2_expr)) {
+			lptable2[idx] = add_flags(lptable2[idx],flags)
+			variant = "INAT_VARIANT"
+		} else if (match(ext, lprefix3_expr)) {
+			lptable3[idx] = add_flags(lptable3[idx],flags)
+			variant = "INAT_VARIANT"
+		} else {
+			table[idx] = add_flags(table[idx],flags)
+		}
+	}
+	if (variant)
+		table[idx] = add_flags(table[idx],variant)
+}
+
+END {
+	if (awkchecked != "")
+		exit 1
+	# print escape opcode map's array
+	print "/* Escape opcode map array */"
+	print "const insn_attr_t const *inat_escape_tables[INAT_ESC_MAX + 1]" \
+	      "[INAT_LSTPFX_MAX + 1] = {"
+	for (i = 0; i < geid; i++)
+		for (j = 0; j < max_lprefix; j++)
+			if (etable[i,j])
+				print "	["i"]["j"] = "etable[i,j]","
+	print "};\n"
+	# print group opcode map's array
+	print "/* Group opcode map array */"
+	print "const insn_attr_t const *inat_group_tables[INAT_GRP_MAX + 1]"\
+	      "[INAT_LSTPFX_MAX + 1] = {"
+	for (i = 0; i < ggid; i++)
+		for (j = 0; j < max_lprefix; j++)
+			if (gtable[i,j])
+				print "	["i"]["j"] = "gtable[i,j]","
+	print "};\n"
+	# print AVX opcode map's array
+	print "/* AVX opcode map array */"
+	print "const insn_attr_t const *inat_avx_tables[X86_VEX_M_MAX + 1]"\
+	      "[INAT_LSTPFX_MAX + 1] = {"
+	for (i = 0; i < gaid; i++)
+		for (j = 0; j < max_lprefix; j++)
+			if (atable[i,j])
+				print "	["i"]["j"] = "atable[i,j]","
+	print "};"
+}
+
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/tools/Makefile linux-libre-2.6.33-gnu1/arch/x86/tools/Makefile
--- linux-libre-2.6.32-gnu1/arch/x86/tools/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/tools/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,31 @@
+PHONY += posttest
+
+ifeq ($(KBUILD_VERBOSE),1)
+  posttest_verbose = -v
+else
+  posttest_verbose =
+endif
+
+ifeq ($(CONFIG_64BIT),y)
+  posttest_64bit = -y
+else
+  posttest_64bit = -n
+endif
+
+distill_awk = $(srctree)/arch/x86/tools/distill.awk
+chkobjdump = $(srctree)/arch/x86/tools/chkobjdump.awk
+
+quiet_cmd_posttest = TEST    $@
+      cmd_posttest = ($(OBJDUMP) -v | $(AWK) -f $(chkobjdump)) || $(OBJDUMP) -d -j .text $(objtree)/vmlinux | $(AWK) -f $(distill_awk) | $(obj)/test_get_len $(posttest_64bit) $(posttest_verbose)
+
+posttest: $(obj)/test_get_len vmlinux
+	$(call cmd,posttest)
+
+hostprogs-y	:= test_get_len
+
+# -I needed for generated C source and C source which in the kernel tree.
+HOSTCFLAGS_test_get_len.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/
+
+# Dependencies are also needed.
+$(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c
+
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/tools/test_get_len.c linux-libre-2.6.33-gnu1/arch/x86/tools/test_get_len.c
--- linux-libre-2.6.32-gnu1/arch/x86/tools/test_get_len.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/tools/test_get_len.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,173 @@
+/*
+ * 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) IBM Corporation, 2009
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#define unlikely(cond) (cond)
+
+#include <asm/insn.h>
+#include <inat.c>
+#include <insn.c>
+
+/*
+ * Test of instruction analysis in general and insn_get_length() in
+ * particular.  See if insn_get_length() and the disassembler agree
+ * on the length of each instruction in an elf disassembly.
+ *
+ * Usage: objdump -d a.out | awk -f distill.awk | ./test_get_len
+ */
+
+const char *prog;
+static int verbose;
+static int x86_64;
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: objdump -d a.out | awk -f distill.awk |"
+		" %s [-y|-n] [-v] \n", prog);
+	fprintf(stderr, "\t-y	64bit mode\n");
+	fprintf(stderr, "\t-n	32bit mode\n");
+	fprintf(stderr, "\t-v	verbose mode\n");
+	exit(1);
+}
+
+static void malformed_line(const char *line, int line_nr)
+{
+	fprintf(stderr, "%s: malformed line %d:\n%s", prog, line_nr, line);
+	exit(3);
+}
+
+static void dump_field(FILE *fp, const char *name, const char *indent,
+		       struct insn_field *field)
+{
+	fprintf(fp, "%s.%s = {\n", indent, name);
+	fprintf(fp, "%s\t.value = %d, bytes[] = {%x, %x, %x, %x},\n",
+		indent, field->value, field->bytes[0], field->bytes[1],
+		field->bytes[2], field->bytes[3]);
+	fprintf(fp, "%s\t.got = %d, .nbytes = %d},\n", indent,
+		field->got, field->nbytes);
+}
+
+static void dump_insn(FILE *fp, struct insn *insn)
+{
+	fprintf(fp, "Instruction = { \n");
+	dump_field(fp, "prefixes", "\t",	&insn->prefixes);
+	dump_field(fp, "rex_prefix", "\t",	&insn->rex_prefix);
+	dump_field(fp, "vex_prefix", "\t",	&insn->vex_prefix);
+	dump_field(fp, "opcode", "\t",		&insn->opcode);
+	dump_field(fp, "modrm", "\t",		&insn->modrm);
+	dump_field(fp, "sib", "\t",		&insn->sib);
+	dump_field(fp, "displacement", "\t",	&insn->displacement);
+	dump_field(fp, "immediate1", "\t",	&insn->immediate1);
+	dump_field(fp, "immediate2", "\t",	&insn->immediate2);
+	fprintf(fp, "\t.attr = %x, .opnd_bytes = %d, .addr_bytes = %d,\n",
+		insn->attr, insn->opnd_bytes, insn->addr_bytes);
+	fprintf(fp, "\t.length = %d, .x86_64 = %d, .kaddr = %p}\n",
+		insn->length, insn->x86_64, insn->kaddr);
+}
+
+static void parse_args(int argc, char **argv)
+{
+	int c;
+	prog = argv[0];
+	while ((c = getopt(argc, argv, "ynv")) != -1) {
+		switch (c) {
+		case 'y':
+			x86_64 = 1;
+			break;
+		case 'n':
+			x86_64 = 0;
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		default:
+			usage();
+		}
+	}
+}
+
+#define BUFSIZE 256
+
+int main(int argc, char **argv)
+{
+	char line[BUFSIZE], sym[BUFSIZE] = "<unknown>";
+	unsigned char insn_buf[16];
+	struct insn insn;
+	int insns = 0;
+	int warnings = 0;
+
+	parse_args(argc, argv);
+
+	while (fgets(line, BUFSIZE, stdin)) {
+		char copy[BUFSIZE], *s, *tab1, *tab2;
+		int nb = 0;
+		unsigned int b;
+
+		if (line[0] == '<') {
+			/* Symbol line */
+			strcpy(sym, line);
+			continue;
+		}
+
+		insns++;
+		memset(insn_buf, 0, 16);
+		strcpy(copy, line);
+		tab1 = strchr(copy, '\t');
+		if (!tab1)
+			malformed_line(line, insns);
+		s = tab1 + 1;
+		s += strspn(s, " ");
+		tab2 = strchr(s, '\t');
+		if (!tab2)
+			malformed_line(line, insns);
+		*tab2 = '\0';	/* Characters beyond tab2 aren't examined */
+		while (s < tab2) {
+			if (sscanf(s, "%x", &b) == 1) {
+				insn_buf[nb++] = (unsigned char) b;
+				s += 3;
+			} else
+				break;
+		}
+		/* Decode an instruction */
+		insn_init(&insn, insn_buf, x86_64);
+		insn_get_length(&insn);
+		if (insn.length != nb) {
+			warnings++;
+			fprintf(stderr, "Warning: %s found difference at %s\n",
+				prog, sym);
+			fprintf(stderr, "Warning: %s", line);
+			fprintf(stderr, "Warning: objdump says %d bytes, but "
+				"insn_get_length() says %d\n", nb,
+				insn.length);
+			if (verbose)
+				dump_insn(stderr, &insn);
+		}
+	}
+	if (warnings)
+		fprintf(stderr, "Warning: decoded and checked %d"
+			" instructions with %d warnings\n", insns, warnings);
+	else
+		fprintf(stderr, "Succeed: decoded and checked %d"
+			" instructions\n", insns);
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/vdso/vdso32-setup.c linux-libre-2.6.33-gnu1/arch/x86/vdso/vdso32-setup.c
--- linux-libre-2.6.32-gnu1/arch/x86/vdso/vdso32-setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/vdso/vdso32-setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -393,7 +393,6 @@ static ctl_table abi_table2[] = {
 
 static ctl_table abi_root_table2[] = {
 	{
-		.ctl_name = CTL_ABI,
 		.procname = "abi",
 		.mode = 0555,
 		.child = abi_table2
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/enlighten.c linux-libre-2.6.33-gnu1/arch/x86/xen/enlighten.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/enlighten.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/enlighten.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,9 @@
 #include <linux/page-flags.h>
 #include <linux/highmem.h>
 #include <linux/console.h>
+#include <linux/pci.h>
 
+#include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>
 #include <xen/interface/physdev.h>
@@ -138,24 +140,23 @@ static void xen_vcpu_setup(int cpu)
  */
 void xen_vcpu_restore(void)
 {
-	if (have_vcpu_info_placement) {
-		int cpu;
+	int cpu;
 
-		for_each_online_cpu(cpu) {
-			bool other_cpu = (cpu != smp_processor_id());
+	for_each_online_cpu(cpu) {
+		bool other_cpu = (cpu != smp_processor_id());
 
-			if (other_cpu &&
-			    HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
-				BUG();
+		if (other_cpu &&
+		    HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
+			BUG();
 
-			xen_vcpu_setup(cpu);
+		xen_setup_runstate_info(cpu);
 
-			if (other_cpu &&
-			    HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
-				BUG();
-		}
+		if (have_vcpu_info_placement)
+			xen_vcpu_setup(cpu);
 
-		BUG_ON(!have_vcpu_info_placement);
+		if (other_cpu &&
+		    HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
+			BUG();
 	}
 }
 
@@ -1093,10 +1094,8 @@ asmlinkage void __init xen_start_kernel(
 
 	__supported_pte_mask |= _PAGE_IOMAP;
 
-#ifdef CONFIG_X86_64
 	/* Work out if we support NX */
-	check_efer();
-#endif
+	x86_configure_nx();
 
 	xen_setup_features();
 
@@ -1152,9 +1151,13 @@ asmlinkage void __init xen_start_kernel(
 
 	/* keep using Xen gdt for now; no urgent need to change it */
 
+#ifdef CONFIG_X86_32
 	pv_info.kernel_rpl = 1;
 	if (xen_feature(XENFEAT_supervisor_mode_kernel))
 		pv_info.kernel_rpl = 0;
+#else
+	pv_info.kernel_rpl = 0;
+#endif
 
 	/* set the limit of our address space */
 	xen_reserve_top();
@@ -1178,10 +1181,16 @@ asmlinkage void __init xen_start_kernel(
 		add_preferred_console("xenboot", 0, NULL);
 		add_preferred_console("tty", 0, NULL);
 		add_preferred_console("hvc", 0, NULL);
+	} else {
+		/* Make sure ACS will be enabled */
+		pci_request_acs();
 	}
+		
 
 	xen_raw_console_write("about to get started...\n");
 
+	xen_setup_runstate_info(0);
+
 	/* Start the world */
 #ifdef CONFIG_X86_32
 	i386_start_kernel();
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/mmu.c linux-libre-2.6.33-gnu1/arch/x86/xen/mmu.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/mmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/mmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,7 +185,7 @@ static inline unsigned p2m_index(unsigne
 }
 
 /* Build the parallel p2m_top_mfn structures */
-static void __init xen_build_mfn_list_list(void)
+void xen_build_mfn_list_list(void)
 {
 	unsigned pfn, idx;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/smp.c linux-libre-2.6.33-gnu1/arch/x86/xen/smp.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/smp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/smp.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,10 +35,10 @@
 
 cpumask_var_t xen_cpu_initialized_map;
 
-static DEFINE_PER_CPU(int, resched_irq);
-static DEFINE_PER_CPU(int, callfunc_irq);
-static DEFINE_PER_CPU(int, callfuncsingle_irq);
-static DEFINE_PER_CPU(int, debug_irq) = -1;
+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_debug_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);
@@ -73,7 +73,7 @@ static __cpuinit void cpu_bringup(void)
 
 	xen_setup_cpu_clockevents();
 
-	cpu_set(cpu, cpu_online_map);
+	set_cpu_online(cpu, true);
 	percpu_write(cpu_state, CPU_ONLINE);
 	wmb();
 
@@ -103,7 +103,7 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(resched_irq, cpu) = rc;
+	per_cpu(xen_resched_irq, cpu) = rc;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
@@ -114,7 +114,7 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(callfunc_irq, cpu) = rc;
+	per_cpu(xen_callfunc_irq, cpu) = rc;
 
 	debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
 	rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt,
@@ -122,7 +122,7 @@ static int xen_smp_intr_init(unsigned in
 				     debug_name, NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(debug_irq, cpu) = rc;
+	per_cpu(xen_debug_irq, cpu) = rc;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
@@ -133,19 +133,20 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(callfuncsingle_irq, cpu) = rc;
+	per_cpu(xen_callfuncsingle_irq, cpu) = rc;
 
 	return 0;
 
  fail:
-	if (per_cpu(resched_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-	if (per_cpu(callfunc_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-	if (per_cpu(debug_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(debug_irq, cpu), NULL);
-	if (per_cpu(callfuncsingle_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(callfuncsingle_irq, cpu), NULL);
+	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);
 
 	return rc;
 }
@@ -295,6 +296,7 @@ static int __cpuinit xen_cpu_up(unsigned
 		(unsigned long)task_stack_page(idle) -
 		KERNEL_STACK_OFFSET + THREAD_SIZE;
 #endif
+	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
 	xen_init_lock_cpu(cpu);
 
@@ -348,10 +350,10 @@ static void xen_cpu_die(unsigned int cpu
 		current->state = TASK_UNINTERRUPTIBLE;
 		schedule_timeout(HZ/10);
 	}
-	unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(debug_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(callfuncsingle_irq, cpu), NULL);
+	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);
 	xen_uninit_lock_cpu(cpu);
 	xen_teardown_timer(cpu);
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/spinlock.c linux-libre-2.6.33-gnu1/arch/x86/xen/spinlock.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/spinlock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/spinlock.c	2010-02-24 13:52:17.000000000 -0500
@@ -120,14 +120,14 @@ struct xen_spinlock {
 	unsigned short spinners;	/* count of waiting cpus */
 };
 
-static int xen_spin_is_locked(struct raw_spinlock *lock)
+static int xen_spin_is_locked(struct arch_spinlock *lock)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 
 	return xl->lock != 0;
 }
 
-static int xen_spin_is_contended(struct raw_spinlock *lock)
+static int xen_spin_is_contended(struct arch_spinlock *lock)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 
@@ -136,7 +136,7 @@ static int xen_spin_is_contended(struct
 	return xl->spinners != 0;
 }
 
-static int xen_spin_trylock(struct raw_spinlock *lock)
+static int xen_spin_trylock(struct arch_spinlock *lock)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 	u8 old = 1;
@@ -181,7 +181,7 @@ static inline void unspinning_lock(struc
 	__get_cpu_var(lock_spinners) = prev;
 }
 
-static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enable)
+static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enable)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 	struct xen_spinlock *prev;
@@ -254,7 +254,7 @@ out:
 	return ret;
 }
 
-static inline void __xen_spin_lock(struct raw_spinlock *lock, bool irq_enable)
+static inline void __xen_spin_lock(struct arch_spinlock *lock, bool irq_enable)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 	unsigned timeout;
@@ -291,12 +291,12 @@ static inline void __xen_spin_lock(struc
 	spin_time_accum_total(start_spin);
 }
 
-static void xen_spin_lock(struct raw_spinlock *lock)
+static void xen_spin_lock(struct arch_spinlock *lock)
 {
 	__xen_spin_lock(lock, false);
 }
 
-static void xen_spin_lock_flags(struct raw_spinlock *lock, unsigned long flags)
+static void xen_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags)
 {
 	__xen_spin_lock(lock, !raw_irqs_disabled_flags(flags));
 }
@@ -317,7 +317,7 @@ static noinline void xen_spin_unlock_slo
 	}
 }
 
-static void xen_spin_unlock(struct raw_spinlock *lock)
+static void xen_spin_unlock(struct arch_spinlock *lock)
 {
 	struct xen_spinlock *xl = (struct xen_spinlock *)lock;
 
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/suspend.c linux-libre-2.6.33-gnu1/arch/x86/xen/suspend.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/suspend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/suspend.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,5 @@
 #include <linux/types.h>
+#include <linux/clockchips.h>
 
 #include <xen/interface/xen.h>
 #include <xen/grant_table.h>
@@ -27,6 +28,8 @@ void xen_pre_suspend(void)
 
 void xen_post_suspend(int suspend_cancelled)
 {
+	xen_build_mfn_list_list();
+
 	xen_setup_shared_info();
 
 	if (suspend_cancelled) {
@@ -44,7 +47,19 @@ void xen_post_suspend(int suspend_cancel
 
 }
 
+static void xen_vcpu_notify_restore(void *data)
+{
+	unsigned long reason = (unsigned long)data;
+
+	/* Boot processor notified via generic timekeeping_resume() */
+	if ( smp_processor_id() == 0)
+		return;
+
+	clockevents_notify(reason, NULL);
+}
+
 void xen_arch_resume(void)
 {
-	/* nothing */
+	smp_call_function(xen_vcpu_notify_restore,
+			       (void *)CLOCK_EVT_NOTIFY_RESUME, 1);
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/time.c linux-libre-2.6.33-gnu1/arch/x86/xen/time.c
--- linux-libre-2.6.32-gnu1/arch/x86/xen/time.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/time.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,14 +31,14 @@
 #define NS_PER_TICK	(1000000000LL / HZ)
 
 /* runstate info updated by Xen */
-static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
+static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
 
 /* snapshots of runstate info */
-static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate_snapshot);
+static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot);
 
 /* unused ns of stolen and blocked time */
-static DEFINE_PER_CPU(u64, residual_stolen);
-static DEFINE_PER_CPU(u64, residual_blocked);
+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)
@@ -79,7 +79,7 @@ static void get_runstate_snapshot(struct
 
 	BUG_ON(preemptible());
 
-	state = &__get_cpu_var(runstate);
+	state = &__get_cpu_var(xen_runstate);
 
 	/*
 	 * The runstate info is always updated by the hypervisor on
@@ -97,14 +97,14 @@ static void get_runstate_snapshot(struct
 /* return true when a vcpu could run but has no real cpu to run on */
 bool xen_vcpu_stolen(int vcpu)
 {
-	return per_cpu(runstate, vcpu).state == RUNSTATE_runnable;
+	return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable;
 }
 
-static void setup_runstate_info(int cpu)
+void xen_setup_runstate_info(int cpu)
 {
 	struct vcpu_register_runstate_memory_area area;
 
-	area.addr.v = &per_cpu(runstate, cpu);
+	area.addr.v = &per_cpu(xen_runstate, cpu);
 
 	if (HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area,
 			       cpu, &area))
@@ -122,7 +122,7 @@ static void do_stolen_accounting(void)
 
 	WARN_ON(state.state != RUNSTATE_running);
 
-	snap = &__get_cpu_var(runstate_snapshot);
+	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];
@@ -133,24 +133,24 @@ static void do_stolen_accounting(void)
 
 	/* Add the appropriate number of ticks of stolen time,
 	   including any left-overs from last time. */
-	stolen = runnable + offline + __get_cpu_var(residual_stolen);
+	stolen = runnable + offline + __get_cpu_var(xen_residual_stolen);
 
 	if (stolen < 0)
 		stolen = 0;
 
 	ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen);
-	__get_cpu_var(residual_stolen) = stolen;
+	__get_cpu_var(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 += __get_cpu_var(residual_blocked);
+	blocked += __get_cpu_var(xen_residual_blocked);
 
 	if (blocked < 0)
 		blocked = 0;
 
 	ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
-	__get_cpu_var(residual_blocked) = blocked;
+	__get_cpu_var(xen_residual_blocked) = blocked;
 	account_idle_ticks(ticks);
 }
 
@@ -434,7 +434,7 @@ void xen_setup_timer(int cpu)
 		name = "<timer kasprintf failed>";
 
 	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
-				      IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				      IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER,
 				      name, NULL);
 
 	evt = &per_cpu(xen_clock_events, cpu);
@@ -442,8 +442,6 @@ void xen_setup_timer(int cpu)
 
 	evt->cpumask = cpumask_of(cpu);
 	evt->irq = irq;
-
-	setup_runstate_info(cpu);
 }
 
 void xen_teardown_timer(int cpu)
@@ -494,6 +492,7 @@ __init void xen_time_init(void)
 
 	setup_force_cpu_cap(X86_FEATURE_TSC);
 
+	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
 	xen_setup_cpu_clockevents();
 }
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/xen-asm_64.S linux-libre-2.6.33-gnu1/arch/x86/xen/xen-asm_64.S
--- linux-libre-2.6.32-gnu1/arch/x86/xen/xen-asm_64.S	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/xen-asm_64.S	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ ENTRY(xen_sysret32)
 	pushq $__USER32_CS
 	pushq %rcx
 
-	pushq $VGCF_in_syscall
+	pushq $0
 1:	jmp hypercall_iret
 ENDPATCH(xen_sysret32)
 RELOC(xen_sysret32, 1b+1)
@@ -151,7 +151,7 @@ ENTRY(xen_syscall32_target)
 ENTRY(xen_sysenter_target)
 	lea 16(%rsp), %rsp	/* strip %rcx, %r11 */
 	mov $-ENOSYS, %rax
-	pushq $VGCF_in_syscall
+	pushq $0
 	jmp hypercall_iret
 ENDPROC(xen_syscall32_target)
 ENDPROC(xen_sysenter_target)
diff -druNp linux-libre-2.6.32-gnu1/arch/x86/xen/xen-ops.h linux-libre-2.6.33-gnu1/arch/x86/xen/xen-ops.h
--- linux-libre-2.6.32-gnu1/arch/x86/xen/xen-ops.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/x86/xen/xen-ops.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,7 @@ extern struct shared_info *HYPERVISOR_sh
 
 void xen_setup_mfn_list_list(void);
 void xen_setup_shared_info(void);
+void xen_build_mfn_list_list(void);
 void xen_setup_machphys_mapping(void);
 pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
 void xen_ident_map_ISA(void);
@@ -41,6 +42,7 @@ void __init xen_build_dynamic_phys_to_ma
 
 void xen_init_irq_ops(void);
 void xen_setup_timer(int cpu);
+void xen_setup_runstate_info(int cpu);
 void xen_teardown_timer(int cpu);
 cycle_t xen_clocksource_read(void);
 void xen_setup_cpu_clockevents(void);
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/asm-offsets.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/asm-offsets.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/asm-offsets.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/asm-offsets.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/cacheflush.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/cacheflush.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/cacheflush.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/cacheflush.h	2010-02-24 13:52:17.000000000 -0500
@@ -101,6 +101,7 @@ static inline void __invalidate_icache_p
 #define flush_cache_vmap(start,end)	flush_cache_all()
 #define flush_cache_vunmap(start,end)	flush_cache_all()
 
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page*);
 extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
 extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long);
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/elf.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/elf.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/elf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/elf.h	2010-02-24 13:52:17.000000000 -0500
@@ -123,7 +123,6 @@ extern void xtensa_elf_core_copy_regs (x
 #define ELF_CLASS	ELFCLASS32
 #define ELF_ARCH	EM_XTENSA
 
-#define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/socket.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/socket.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/socket.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/socket.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,4 +71,6 @@
 #define SO_PROTOCOL		38
 #define SO_DOMAIN		39
 
+#define SO_RXQ_OVFL             40
+
 #endif	/* _XTENSA_SOCKET_H */
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/syscall.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/syscall.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/syscall.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/syscall.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,9 +12,6 @@ struct pt_regs;
 struct sigaction;
 asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*);
 asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*);
-asmlinkage long xtensa_pipe(int __user *);
-asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long,
-    			     unsigned long, unsigned long, unsigned long);
 asmlinkage long xtensa_ptrace(long, long, long, long);
 asmlinkage long xtensa_sigreturn(struct pt_regs*);
 asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/unistd.h linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/unistd.h
--- linux-libre-2.6.32-gnu1/arch/xtensa/include/asm/unistd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/include/asm/unistd.h	2010-02-24 13:52:17.000000000 -0500
@@ -94,7 +94,7 @@ __SYSCALL( 35, sys_readlink, 3)
 #define __NR_mknod 				 36
 __SYSCALL( 36, sys_mknod, 3)
 #define __NR_pipe 				 37
-__SYSCALL( 37, xtensa_pipe, 1)
+__SYSCALL( 37, sys_pipe, 1)
 #define __NR_unlink 				 38
 __SYSCALL( 38, sys_unlink, 1)
 #define __NR_rmdir 				 39
@@ -189,7 +189,7 @@ __SYSCALL( 79, sys_fremovexattr, 2)
 /* File Map / Shared Memory Operations */
 
 #define __NR_mmap2 				 80
-__SYSCALL( 80, xtensa_mmap2, 6)
+__SYSCALL( 80, sys_mmap_pgoff, 6)
 #define __NR_munmap 				 81
 __SYSCALL( 81, sys_munmap, 2)
 #define __NR_mprotect 				 82
@@ -681,8 +681,10 @@ __SYSCALL(304, sys_signalfd, 3)
 __SYSCALL(305, sys_ni_syscall, 0)
 #define __NR_eventfd				306
 __SYSCALL(306, sys_eventfd, 1)
+#define __NR_recvmmsg				307
+__SYSCALL(307, sys_recvmmsg, 5)
 
-#define __NR_syscall_count			307
+#define __NR_syscall_count			308
 
 /*
  * sysxtensa syscall handler
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/kernel/irq.c linux-libre-2.6.33-gnu1/arch/xtensa/kernel/irq.c
--- linux-libre-2.6.32-gnu1/arch/xtensa/kernel/irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/kernel/irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,7 +90,7 @@ int show_interrupts(struct seq_file *p,
 	}
 
 	if (i < NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action)
 			goto skip;
@@ -109,7 +109,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_putc(p, '\n');
 skip:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "NMI: ");
 		for_each_online_cpu(j)
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/kernel/syscall.c linux-libre-2.6.33-gnu1/arch/xtensa/kernel/syscall.c
--- linux-libre-2.6.32-gnu1/arch/xtensa/kernel/syscall.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/kernel/syscall.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,49 +39,6 @@ syscall_t sys_call_table[__NR_syscall_co
 #include <asm/unistd.h>
 };
 
-/*
- * xtensa_pipe() is the normal C calling standard for creating a pipe. It's not
- * the way unix traditional does this, though.
- */
-
-asmlinkage long xtensa_pipe(int __user *userfds)
-{
-	int fd[2];
-	int error;
-
-	error = do_pipe_flags(fd, 0);
-	if (!error) {
-		if (copy_to_user(userfds, fd, 2 * sizeof(int)))
-			error = -EFAULT;
-	}
-	return error;
-}
-
-
-asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len,
-   			     unsigned long prot, unsigned long flags,
-			     unsigned long fd, unsigned long pgoff)
-{
-	int error = -EBADF;
-	struct file * file = NULL;
-
-	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	if (!(flags & MAP_ANONYMOUS)) {
-		file = fget(fd);
-		if (!file)
-			goto out;
-	}
-
-	down_write(&current->mm->mmap_sem);
-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-	up_write(&current->mm->mmap_sem);
-
-	if (file)
-		fput(file);
-out:
-	return error;
-}
-
 asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
 {
 	unsigned long ret;
diff -druNp linux-libre-2.6.32-gnu1/arch/xtensa/platforms/iss/console.c linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/console.c
--- linux-libre-2.6.32-gnu1/arch/xtensa/platforms/iss/console.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/arch/xtensa/platforms/iss/console.c	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,7 @@ static const struct file_operations rs_p
 	.release	= single_release,
 };
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
 	.write = rs_write,
diff -druNp linux-libre-2.6.32-gnu1/block/as-iosched.c linux-libre-2.6.33-gnu1/block/as-iosched.c
--- linux-libre-2.6.32-gnu1/block/as-iosched.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/as-iosched.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1520 +0,0 @@
-/*
- *  Anticipatory & deadline i/o scheduler.
- *
- *  Copyright (C) 2002 Jens Axboe <axboe@kernel.dk>
- *                     Nick Piggin <nickpiggin@yahoo.com.au>
- *
- */
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/blkdev.h>
-#include <linux/elevator.h>
-#include <linux/bio.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/compiler.h>
-#include <linux/rbtree.h>
-#include <linux/interrupt.h>
-
-/*
- * See Documentation/block/as-iosched.txt
- */
-
-/*
- * max time before a read is submitted.
- */
-#define default_read_expire (HZ / 8)
-
-/*
- * ditto for writes, these limits are not hard, even
- * if the disk is capable of satisfying them.
- */
-#define default_write_expire (HZ / 4)
-
-/*
- * read_batch_expire describes how long we will allow a stream of reads to
- * persist before looking to see whether it is time to switch over to writes.
- */
-#define default_read_batch_expire (HZ / 2)
-
-/*
- * write_batch_expire describes how long we want a stream of writes to run for.
- * This is not a hard limit, but a target we set for the auto-tuning thingy.
- * See, the problem is: we can send a lot of writes to disk cache / TCQ in
- * a short amount of time...
- */
-#define default_write_batch_expire (HZ / 8)
-
-/*
- * max time we may wait to anticipate a read (default around 6ms)
- */
-#define default_antic_expire ((HZ / 150) ? HZ / 150 : 1)
-
-/*
- * Keep track of up to 20ms thinktimes. We can go as big as we like here,
- * however huge values tend to interfere and not decay fast enough. A program
- * might be in a non-io phase of operation. Waiting on user input for example,
- * or doing a lengthy computation. A small penalty can be justified there, and
- * will still catch out those processes that constantly have large thinktimes.
- */
-#define MAX_THINKTIME (HZ/50UL)
-
-/* Bits in as_io_context.state */
-enum as_io_states {
-	AS_TASK_RUNNING=0,	/* Process has not exited */
-	AS_TASK_IOSTARTED,	/* Process has started some IO */
-	AS_TASK_IORUNNING,	/* Process has completed some IO */
-};
-
-enum anticipation_status {
-	ANTIC_OFF=0,		/* Not anticipating (normal operation)	*/
-	ANTIC_WAIT_REQ,		/* The last read has not yet completed  */
-	ANTIC_WAIT_NEXT,	/* Currently anticipating a request vs
-				   last read (which has completed) */
-	ANTIC_FINISHED,		/* Anticipating but have found a candidate
-				 * or timed out */
-};
-
-struct as_data {
-	/*
-	 * run time data
-	 */
-
-	struct request_queue *q;	/* the "owner" queue */
-
-	/*
-	 * requests (as_rq s) are present on both sort_list and fifo_list
-	 */
-	struct rb_root sort_list[2];
-	struct list_head fifo_list[2];
-
-	struct request *next_rq[2];	/* next in sort order */
-	sector_t last_sector[2];	/* last SYNC & ASYNC sectors */
-
-	unsigned long exit_prob;	/* probability a task will exit while
-					   being waited on */
-	unsigned long exit_no_coop;	/* probablility an exited task will
-					   not be part of a later cooperating
-					   request */
-	unsigned long new_ttime_total; 	/* mean thinktime on new proc */
-	unsigned long new_ttime_mean;
-	u64 new_seek_total;		/* mean seek on new proc */
-	sector_t new_seek_mean;
-
-	unsigned long current_batch_expires;
-	unsigned long last_check_fifo[2];
-	int changed_batch;		/* 1: waiting for old batch to end */
-	int new_batch;			/* 1: waiting on first read complete */
-	int batch_data_dir;		/* current batch SYNC / ASYNC */
-	int write_batch_count;		/* max # of reqs in a write batch */
-	int current_write_count;	/* how many requests left this batch */
-	int write_batch_idled;		/* has the write batch gone idle? */
-
-	enum anticipation_status antic_status;
-	unsigned long antic_start;	/* jiffies: when it started */
-	struct timer_list antic_timer;	/* anticipatory scheduling timer */
-	struct work_struct antic_work;	/* Deferred unplugging */
-	struct io_context *io_context;	/* Identify the expected process */
-	int ioc_finished; /* IO associated with io_context is finished */
-	int nr_dispatched;
-
-	/*
-	 * settings that change how the i/o scheduler behaves
-	 */
-	unsigned long fifo_expire[2];
-	unsigned long batch_expire[2];
-	unsigned long antic_expire;
-};
-
-/*
- * per-request data.
- */
-enum arq_state {
-	AS_RQ_NEW=0,		/* New - not referenced and not on any lists */
-	AS_RQ_QUEUED,		/* In the request queue. It belongs to the
-				   scheduler */
-	AS_RQ_DISPATCHED,	/* On the dispatch list. It belongs to the
-				   driver now */
-	AS_RQ_PRESCHED,		/* Debug poisoning for requests being used */
-	AS_RQ_REMOVED,
-	AS_RQ_MERGED,
-	AS_RQ_POSTSCHED,	/* when they shouldn't be */
-};
-
-#define RQ_IOC(rq)	((struct io_context *) (rq)->elevator_private)
-#define RQ_STATE(rq)	((enum arq_state)(rq)->elevator_private2)
-#define RQ_SET_STATE(rq, state)	((rq)->elevator_private2 = (void *) state)
-
-static DEFINE_PER_CPU(unsigned long, as_ioc_count);
-static struct completion *ioc_gone;
-static DEFINE_SPINLOCK(ioc_gone_lock);
-
-static void as_move_to_dispatch(struct as_data *ad, struct request *rq);
-static void as_antic_stop(struct as_data *ad);
-
-/*
- * IO Context helper functions
- */
-
-/* Called to deallocate the as_io_context */
-static void free_as_io_context(struct as_io_context *aic)
-{
-	kfree(aic);
-	elv_ioc_count_dec(as_ioc_count);
-	if (ioc_gone) {
-		/*
-		 * AS scheduler is exiting, grab exit lock and check
-		 * the pending io context count. If it hits zero,
-		 * complete ioc_gone and set it back to NULL.
-		 */
-		spin_lock(&ioc_gone_lock);
-		if (ioc_gone && !elv_ioc_count_read(as_ioc_count)) {
-			complete(ioc_gone);
-			ioc_gone = NULL;
-		}
-		spin_unlock(&ioc_gone_lock);
-	}
-}
-
-static void as_trim(struct io_context *ioc)
-{
-	spin_lock_irq(&ioc->lock);
-	if (ioc->aic)
-		free_as_io_context(ioc->aic);
-	ioc->aic = NULL;
-	spin_unlock_irq(&ioc->lock);
-}
-
-/* Called when the task exits */
-static void exit_as_io_context(struct as_io_context *aic)
-{
-	WARN_ON(!test_bit(AS_TASK_RUNNING, &aic->state));
-	clear_bit(AS_TASK_RUNNING, &aic->state);
-}
-
-static struct as_io_context *alloc_as_io_context(void)
-{
-	struct as_io_context *ret;
-
-	ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
-	if (ret) {
-		ret->dtor = free_as_io_context;
-		ret->exit = exit_as_io_context;
-		ret->state = 1 << AS_TASK_RUNNING;
-		atomic_set(&ret->nr_queued, 0);
-		atomic_set(&ret->nr_dispatched, 0);
-		spin_lock_init(&ret->lock);
-		ret->ttime_total = 0;
-		ret->ttime_samples = 0;
-		ret->ttime_mean = 0;
-		ret->seek_total = 0;
-		ret->seek_samples = 0;
-		ret->seek_mean = 0;
-		elv_ioc_count_inc(as_ioc_count);
-	}
-
-	return ret;
-}
-
-/*
- * If the current task has no AS IO context then create one and initialise it.
- * Then take a ref on the task's io context and return it.
- */
-static struct io_context *as_get_io_context(int node)
-{
-	struct io_context *ioc = get_io_context(GFP_ATOMIC, node);
-	if (ioc && !ioc->aic) {
-		ioc->aic = alloc_as_io_context();
-		if (!ioc->aic) {
-			put_io_context(ioc);
-			ioc = NULL;
-		}
-	}
-	return ioc;
-}
-
-static void as_put_io_context(struct request *rq)
-{
-	struct as_io_context *aic;
-
-	if (unlikely(!RQ_IOC(rq)))
-		return;
-
-	aic = RQ_IOC(rq)->aic;
-
-	if (rq_is_sync(rq) && aic) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&aic->lock, flags);
-		set_bit(AS_TASK_IORUNNING, &aic->state);
-		aic->last_end_request = jiffies;
-		spin_unlock_irqrestore(&aic->lock, flags);
-	}
-
-	put_io_context(RQ_IOC(rq));
-}
-
-/*
- * rb tree support functions
- */
-#define RQ_RB_ROOT(ad, rq)	(&(ad)->sort_list[rq_is_sync((rq))])
-
-static void as_add_rq_rb(struct as_data *ad, struct request *rq)
-{
-	struct request *alias;
-
-	while ((unlikely(alias = elv_rb_add(RQ_RB_ROOT(ad, rq), rq)))) {
-		as_move_to_dispatch(ad, alias);
-		as_antic_stop(ad);
-	}
-}
-
-static inline void as_del_rq_rb(struct as_data *ad, struct request *rq)
-{
-	elv_rb_del(RQ_RB_ROOT(ad, rq), rq);
-}
-
-/*
- * IO Scheduler proper
- */
-
-#define MAXBACK (1024 * 1024)	/*
-				 * Maximum distance the disk will go backward
-				 * for a request.
-				 */
-
-#define BACK_PENALTY	2
-
-/*
- * as_choose_req selects the preferred one of two requests of the same data_dir
- * ignoring time - eg. timeouts, which is the job of as_dispatch_request
- */
-static struct request *
-as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2)
-{
-	int data_dir;
-	sector_t last, s1, s2, d1, d2;
-	int r1_wrap=0, r2_wrap=0;	/* requests are behind the disk head */
-	const sector_t maxback = MAXBACK;
-
-	if (rq1 == NULL || rq1 == rq2)
-		return rq2;
-	if (rq2 == NULL)
-		return rq1;
-
-	data_dir = rq_is_sync(rq1);
-
-	last = ad->last_sector[data_dir];
-	s1 = blk_rq_pos(rq1);
-	s2 = blk_rq_pos(rq2);
-
-	BUG_ON(data_dir != rq_is_sync(rq2));
-
-	/*
-	 * Strict one way elevator _except_ in the case where we allow
-	 * short backward seeks which are biased as twice the cost of a
-	 * similar forward seek.
-	 */
-	if (s1 >= last)
-		d1 = s1 - last;
-	else if (s1+maxback >= last)
-		d1 = (last - s1)*BACK_PENALTY;
-	else {
-		r1_wrap = 1;
-		d1 = 0; /* shut up, gcc */
-	}
-
-	if (s2 >= last)
-		d2 = s2 - last;
-	else if (s2+maxback >= last)
-		d2 = (last - s2)*BACK_PENALTY;
-	else {
-		r2_wrap = 1;
-		d2 = 0;
-	}
-
-	/* Found required data */
-	if (!r1_wrap && r2_wrap)
-		return rq1;
-	else if (!r2_wrap && r1_wrap)
-		return rq2;
-	else if (r1_wrap && r2_wrap) {
-		/* both behind the head */
-		if (s1 <= s2)
-			return rq1;
-		else
-			return rq2;
-	}
-
-	/* Both requests in front of the head */
-	if (d1 < d2)
-		return rq1;
-	else if (d2 < d1)
-		return rq2;
-	else {
-		if (s1 >= s2)
-			return rq1;
-		else
-			return rq2;
-	}
-}
-
-/*
- * as_find_next_rq finds the next request after @prev in elevator order.
- * this with as_choose_req form the basis for how the scheduler chooses
- * what request to process next. Anticipation works on top of this.
- */
-static struct request *
-as_find_next_rq(struct as_data *ad, struct request *last)
-{
-	struct rb_node *rbnext = rb_next(&last->rb_node);
-	struct rb_node *rbprev = rb_prev(&last->rb_node);
-	struct request *next = NULL, *prev = NULL;
-
-	BUG_ON(RB_EMPTY_NODE(&last->rb_node));
-
-	if (rbprev)
-		prev = rb_entry_rq(rbprev);
-
-	if (rbnext)
-		next = rb_entry_rq(rbnext);
-	else {
-		const int data_dir = rq_is_sync(last);
-
-		rbnext = rb_first(&ad->sort_list[data_dir]);
-		if (rbnext && rbnext != &last->rb_node)
-			next = rb_entry_rq(rbnext);
-	}
-
-	return as_choose_req(ad, next, prev);
-}
-
-/*
- * anticipatory scheduling functions follow
- */
-
-/*
- * as_antic_expired tells us when we have anticipated too long.
- * The funny "absolute difference" math on the elapsed time is to handle
- * jiffy wraps, and disks which have been idle for 0x80000000 jiffies.
- */
-static int as_antic_expired(struct as_data *ad)
-{
-	long delta_jif;
-
-	delta_jif = jiffies - ad->antic_start;
-	if (unlikely(delta_jif < 0))
-		delta_jif = -delta_jif;
-	if (delta_jif < ad->antic_expire)
-		return 0;
-
-	return 1;
-}
-
-/*
- * as_antic_waitnext starts anticipating that a nice request will soon be
- * submitted. See also as_antic_waitreq
- */
-static void as_antic_waitnext(struct as_data *ad)
-{
-	unsigned long timeout;
-
-	BUG_ON(ad->antic_status != ANTIC_OFF
-			&& ad->antic_status != ANTIC_WAIT_REQ);
-
-	timeout = ad->antic_start + ad->antic_expire;
-
-	mod_timer(&ad->antic_timer, timeout);
-
-	ad->antic_status = ANTIC_WAIT_NEXT;
-}
-
-/*
- * as_antic_waitreq starts anticipating. We don't start timing the anticipation
- * until the request that we're anticipating on has finished. This means we
- * are timing from when the candidate process wakes up hopefully.
- */
-static void as_antic_waitreq(struct as_data *ad)
-{
-	BUG_ON(ad->antic_status == ANTIC_FINISHED);
-	if (ad->antic_status == ANTIC_OFF) {
-		if (!ad->io_context || ad->ioc_finished)
-			as_antic_waitnext(ad);
-		else
-			ad->antic_status = ANTIC_WAIT_REQ;
-	}
-}
-
-/*
- * This is called directly by the functions in this file to stop anticipation.
- * We kill the timer and schedule a call to the request_fn asap.
- */
-static void as_antic_stop(struct as_data *ad)
-{
-	int status = ad->antic_status;
-
-	if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
-		if (status == ANTIC_WAIT_NEXT)
-			del_timer(&ad->antic_timer);
-		ad->antic_status = ANTIC_FINISHED;
-		/* see as_work_handler */
-		kblockd_schedule_work(ad->q, &ad->antic_work);
-	}
-}
-
-/*
- * as_antic_timeout is the timer function set by as_antic_waitnext.
- */
-static void as_antic_timeout(unsigned long data)
-{
-	struct request_queue *q = (struct request_queue *)data;
-	struct as_data *ad = q->elevator->elevator_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	if (ad->antic_status == ANTIC_WAIT_REQ
-			|| ad->antic_status == ANTIC_WAIT_NEXT) {
-		struct as_io_context *aic;
-		spin_lock(&ad->io_context->lock);
-		aic = ad->io_context->aic;
-
-		ad->antic_status = ANTIC_FINISHED;
-		kblockd_schedule_work(q, &ad->antic_work);
-
-		if (aic->ttime_samples == 0) {
-			/* process anticipated on has exited or timed out*/
-			ad->exit_prob = (7*ad->exit_prob + 256)/8;
-		}
-		if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
-			/* process not "saved" by a cooperating request */
-			ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8;
-		}
-		spin_unlock(&ad->io_context->lock);
-	}
-	spin_unlock_irqrestore(q->queue_lock, flags);
-}
-
-static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic,
-				unsigned long ttime)
-{
-	/* fixed point: 1.0 == 1<<8 */
-	if (aic->ttime_samples == 0) {
-		ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
-		ad->new_ttime_mean = ad->new_ttime_total / 256;
-
-		ad->exit_prob = (7*ad->exit_prob)/8;
-	}
-	aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
-	aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
-	aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
-}
-
-static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic,
-				sector_t sdist)
-{
-	u64 total;
-
-	if (aic->seek_samples == 0) {
-		ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
-		ad->new_seek_mean = ad->new_seek_total / 256;
-	}
-
-	/*
-	 * Don't allow the seek distance to get too large from the
-	 * odd fragment, pagein, etc
-	 */
-	if (aic->seek_samples <= 60) /* second&third seek */
-		sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
-	else
-		sdist = min(sdist, (aic->seek_mean * 4)	+ 2*1024*64);
-
-	aic->seek_samples = (7*aic->seek_samples + 256) / 8;
-	aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
-	total = aic->seek_total + (aic->seek_samples/2);
-	do_div(total, aic->seek_samples);
-	aic->seek_mean = (sector_t)total;
-}
-
-/*
- * as_update_iohist keeps a decaying histogram of IO thinktimes, and
- * updates @aic->ttime_mean based on that. It is called when a new
- * request is queued.
- */
-static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
-				struct request *rq)
-{
-	int data_dir = rq_is_sync(rq);
-	unsigned long thinktime = 0;
-	sector_t seek_dist;
-
-	if (aic == NULL)
-		return;
-
-	if (data_dir == BLK_RW_SYNC) {
-		unsigned long in_flight = atomic_read(&aic->nr_queued)
-					+ atomic_read(&aic->nr_dispatched);
-		spin_lock(&aic->lock);
-		if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
-			test_bit(AS_TASK_IOSTARTED, &aic->state)) {
-			/* Calculate read -> read thinktime */
-			if (test_bit(AS_TASK_IORUNNING, &aic->state)
-							&& in_flight == 0) {
-				thinktime = jiffies - aic->last_end_request;
-				thinktime = min(thinktime, MAX_THINKTIME-1);
-			}
-			as_update_thinktime(ad, aic, thinktime);
-
-			/* Calculate read -> read seek distance */
-			if (aic->last_request_pos < blk_rq_pos(rq))
-				seek_dist = blk_rq_pos(rq) -
-					    aic->last_request_pos;
-			else
-				seek_dist = aic->last_request_pos -
-					    blk_rq_pos(rq);
-			as_update_seekdist(ad, aic, seek_dist);
-		}
-		aic->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
-		set_bit(AS_TASK_IOSTARTED, &aic->state);
-		spin_unlock(&aic->lock);
-	}
-}
-
-/*
- * as_close_req decides if one request is considered "close" to the
- * previous one issued.
- */
-static int as_close_req(struct as_data *ad, struct as_io_context *aic,
-			struct request *rq)
-{
-	unsigned long delay;	/* jiffies */
-	sector_t last = ad->last_sector[ad->batch_data_dir];
-	sector_t next = blk_rq_pos(rq);
-	sector_t delta; /* acceptable close offset (in sectors) */
-	sector_t s;
-
-	if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
-		delay = 0;
-	else
-		delay = jiffies - ad->antic_start;
-
-	if (delay == 0)
-		delta = 8192;
-	else if (delay <= (20 * HZ / 1000) && delay <= ad->antic_expire)
-		delta = 8192 << delay;
-	else
-		return 1;
-
-	if ((last <= next + (delta>>1)) && (next <= last + delta))
-		return 1;
-
-	if (last < next)
-		s = next - last;
-	else
-		s = last - next;
-
-	if (aic->seek_samples == 0) {
-		/*
-		 * Process has just started IO. Use past statistics to
-		 * gauge success possibility
-		 */
-		if (ad->new_seek_mean > s) {
-			/* this request is better than what we're expecting */
-			return 1;
-		}
-
-	} else {
-		if (aic->seek_mean > s) {
-			/* this request is better than what we're expecting */
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * as_can_break_anticipation returns true if we have been anticipating this
- * request.
- *
- * It also returns true if the process against which we are anticipating
- * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to
- * dispatch it ASAP, because we know that application will not be submitting
- * any new reads.
- *
- * If the task which has submitted the request has exited, break anticipation.
- *
- * If this task has queued some other IO, do not enter enticipation.
- */
-static int as_can_break_anticipation(struct as_data *ad, struct request *rq)
-{
-	struct io_context *ioc;
-	struct as_io_context *aic;
-
-	ioc = ad->io_context;
-	BUG_ON(!ioc);
-	spin_lock(&ioc->lock);
-
-	if (rq && ioc == RQ_IOC(rq)) {
-		/* request from same process */
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-
-	if (ad->ioc_finished && as_antic_expired(ad)) {
-		/*
-		 * In this situation status should really be FINISHED,
-		 * however the timer hasn't had the chance to run yet.
-		 */
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-
-	aic = ioc->aic;
-	if (!aic) {
-		spin_unlock(&ioc->lock);
-		return 0;
-	}
-
-	if (atomic_read(&aic->nr_queued) > 0) {
-		/* process has more requests queued */
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-
-	if (atomic_read(&aic->nr_dispatched) > 0) {
-		/* process has more requests dispatched */
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-
-	if (rq && rq_is_sync(rq) && as_close_req(ad, aic, rq)) {
-		/*
-		 * Found a close request that is not one of ours.
-		 *
-		 * This makes close requests from another process update
-		 * our IO history. Is generally useful when there are
-		 * two or more cooperating processes working in the same
-		 * area.
-		 */
-		if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
-			if (aic->ttime_samples == 0)
-				ad->exit_prob = (7*ad->exit_prob + 256)/8;
-
-			ad->exit_no_coop = (7*ad->exit_no_coop)/8;
-		}
-
-		as_update_iohist(ad, aic, rq);
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-
-	if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
-		/* process anticipated on has exited */
-		if (aic->ttime_samples == 0)
-			ad->exit_prob = (7*ad->exit_prob + 256)/8;
-
-		if (ad->exit_no_coop > 128) {
-			spin_unlock(&ioc->lock);
-			return 1;
-		}
-	}
-
-	if (aic->ttime_samples == 0) {
-		if (ad->new_ttime_mean > ad->antic_expire) {
-			spin_unlock(&ioc->lock);
-			return 1;
-		}
-		if (ad->exit_prob * ad->exit_no_coop > 128*256) {
-			spin_unlock(&ioc->lock);
-			return 1;
-		}
-	} else if (aic->ttime_mean > ad->antic_expire) {
-		/* the process thinks too much between requests */
-		spin_unlock(&ioc->lock);
-		return 1;
-	}
-	spin_unlock(&ioc->lock);
-	return 0;
-}
-
-/*
- * as_can_anticipate indicates whether we should either run rq
- * or keep anticipating a better request.
- */
-static int as_can_anticipate(struct as_data *ad, struct request *rq)
-{
-#if 0 /* disable for now, we need to check tag level as well */
-	/*
-	 * SSD device without seek penalty, disable idling
-	 */
-	if (blk_queue_nonrot(ad->q)) axman
-		return 0;
-#endif
-
-	if (!ad->io_context)
-		/*
-		 * Last request submitted was a write
-		 */
-		return 0;
-
-	if (ad->antic_status == ANTIC_FINISHED)
-		/*
-		 * Don't restart if we have just finished. Run the next request
-		 */
-		return 0;
-
-	if (as_can_break_anticipation(ad, rq))
-		/*
-		 * This request is a good candidate. Don't keep anticipating,
-		 * run it.
-		 */
-		return 0;
-
-	/*
-	 * OK from here, we haven't finished, and don't have a decent request!
-	 * Status is either ANTIC_OFF so start waiting,
-	 * ANTIC_WAIT_REQ so continue waiting for request to finish
-	 * or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
-	 */
-
-	return 1;
-}
-
-/*
- * as_update_rq must be called whenever a request (rq) is added to
- * the sort_list. This function keeps caches up to date, and checks if the
- * request might be one we are "anticipating"
- */
-static void as_update_rq(struct as_data *ad, struct request *rq)
-{
-	const int data_dir = rq_is_sync(rq);
-
-	/* keep the next_rq cache up to date */
-	ad->next_rq[data_dir] = as_choose_req(ad, rq, ad->next_rq[data_dir]);
-
-	/*
-	 * have we been anticipating this request?
-	 * or does it come from the same process as the one we are anticipating
-	 * for?
-	 */
-	if (ad->antic_status == ANTIC_WAIT_REQ
-			|| ad->antic_status == ANTIC_WAIT_NEXT) {
-		if (as_can_break_anticipation(ad, rq))
-			as_antic_stop(ad);
-	}
-}
-
-/*
- * Gathers timings and resizes the write batch automatically
- */
-static void update_write_batch(struct as_data *ad)
-{
-	unsigned long batch = ad->batch_expire[BLK_RW_ASYNC];
-	long write_time;
-
-	write_time = (jiffies - ad->current_batch_expires) + batch;
-	if (write_time < 0)
-		write_time = 0;
-
-	if (write_time > batch && !ad->write_batch_idled) {
-		if (write_time > batch * 3)
-			ad->write_batch_count /= 2;
-		else
-			ad->write_batch_count--;
-	} else if (write_time < batch && ad->current_write_count == 0) {
-		if (batch > write_time * 3)
-			ad->write_batch_count *= 2;
-		else
-			ad->write_batch_count++;
-	}
-
-	if (ad->write_batch_count < 1)
-		ad->write_batch_count = 1;
-}
-
-/*
- * as_completed_request is to be called when a request has completed and
- * returned something to the requesting process, be it an error or data.
- */
-static void as_completed_request(struct request_queue *q, struct request *rq)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-
-	WARN_ON(!list_empty(&rq->queuelist));
-
-	if (RQ_STATE(rq) != AS_RQ_REMOVED) {
-		WARN(1, "rq->state %d\n", RQ_STATE(rq));
-		goto out;
-	}
-
-	if (ad->changed_batch && ad->nr_dispatched == 1) {
-		ad->current_batch_expires = jiffies +
-					ad->batch_expire[ad->batch_data_dir];
-		kblockd_schedule_work(q, &ad->antic_work);
-		ad->changed_batch = 0;
-
-		if (ad->batch_data_dir == BLK_RW_SYNC)
-			ad->new_batch = 1;
-	}
-	WARN_ON(ad->nr_dispatched == 0);
-	ad->nr_dispatched--;
-
-	/*
-	 * Start counting the batch from when a request of that direction is
-	 * actually serviced. This should help devices with big TCQ windows
-	 * and writeback caches
-	 */
-	if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) {
-		update_write_batch(ad);
-		ad->current_batch_expires = jiffies +
-				ad->batch_expire[BLK_RW_SYNC];
-		ad->new_batch = 0;
-	}
-
-	if (ad->io_context == RQ_IOC(rq) && ad->io_context) {
-		ad->antic_start = jiffies;
-		ad->ioc_finished = 1;
-		if (ad->antic_status == ANTIC_WAIT_REQ) {
-			/*
-			 * We were waiting on this request, now anticipate
-			 * the next one
-			 */
-			as_antic_waitnext(ad);
-		}
-	}
-
-	as_put_io_context(rq);
-out:
-	RQ_SET_STATE(rq, AS_RQ_POSTSCHED);
-}
-
-/*
- * as_remove_queued_request removes a request from the pre dispatch queue
- * without updating refcounts. It is expected the caller will drop the
- * reference unless it replaces the request at somepart of the elevator
- * (ie. the dispatch queue)
- */
-static void as_remove_queued_request(struct request_queue *q,
-				     struct request *rq)
-{
-	const int data_dir = rq_is_sync(rq);
-	struct as_data *ad = q->elevator->elevator_data;
-	struct io_context *ioc;
-
-	WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED);
-
-	ioc = RQ_IOC(rq);
-	if (ioc && ioc->aic) {
-		BUG_ON(!atomic_read(&ioc->aic->nr_queued));
-		atomic_dec(&ioc->aic->nr_queued);
-	}
-
-	/*
-	 * Update the "next_rq" cache if we are about to remove its
-	 * entry
-	 */
-	if (ad->next_rq[data_dir] == rq)
-		ad->next_rq[data_dir] = as_find_next_rq(ad, rq);
-
-	rq_fifo_clear(rq);
-	as_del_rq_rb(ad, rq);
-}
-
-/*
- * as_fifo_expired returns 0 if there are no expired requests on the fifo,
- * 1 otherwise.  It is ratelimited so that we only perform the check once per
- * `fifo_expire' interval.  Otherwise a large number of expired requests
- * would create a hopeless seekstorm.
- *
- * See as_antic_expired comment.
- */
-static int as_fifo_expired(struct as_data *ad, int adir)
-{
-	struct request *rq;
-	long delta_jif;
-
-	delta_jif = jiffies - ad->last_check_fifo[adir];
-	if (unlikely(delta_jif < 0))
-		delta_jif = -delta_jif;
-	if (delta_jif < ad->fifo_expire[adir])
-		return 0;
-
-	ad->last_check_fifo[adir] = jiffies;
-
-	if (list_empty(&ad->fifo_list[adir]))
-		return 0;
-
-	rq = rq_entry_fifo(ad->fifo_list[adir].next);
-
-	return time_after(jiffies, rq_fifo_time(rq));
-}
-
-/*
- * as_batch_expired returns true if the current batch has expired. A batch
- * is a set of reads or a set of writes.
- */
-static inline int as_batch_expired(struct as_data *ad)
-{
-	if (ad->changed_batch || ad->new_batch)
-		return 0;
-
-	if (ad->batch_data_dir == BLK_RW_SYNC)
-		/* TODO! add a check so a complete fifo gets written? */
-		return time_after(jiffies, ad->current_batch_expires);
-
-	return time_after(jiffies, ad->current_batch_expires)
-		|| ad->current_write_count == 0;
-}
-
-/*
- * move an entry to dispatch queue
- */
-static void as_move_to_dispatch(struct as_data *ad, struct request *rq)
-{
-	const int data_dir = rq_is_sync(rq);
-
-	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
-
-	as_antic_stop(ad);
-	ad->antic_status = ANTIC_OFF;
-
-	/*
-	 * This has to be set in order to be correctly updated by
-	 * as_find_next_rq
-	 */
-	ad->last_sector[data_dir] = blk_rq_pos(rq) + blk_rq_sectors(rq);
-
-	if (data_dir == BLK_RW_SYNC) {
-		struct io_context *ioc = RQ_IOC(rq);
-		/* In case we have to anticipate after this */
-		copy_io_context(&ad->io_context, &ioc);
-	} else {
-		if (ad->io_context) {
-			put_io_context(ad->io_context);
-			ad->io_context = NULL;
-		}
-
-		if (ad->current_write_count != 0)
-			ad->current_write_count--;
-	}
-	ad->ioc_finished = 0;
-
-	ad->next_rq[data_dir] = as_find_next_rq(ad, rq);
-
-	/*
-	 * take it off the sort and fifo list, add to dispatch queue
-	 */
-	as_remove_queued_request(ad->q, rq);
-	WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED);
-
-	elv_dispatch_sort(ad->q, rq);
-
-	RQ_SET_STATE(rq, AS_RQ_DISPATCHED);
-	if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
-		atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched);
-	ad->nr_dispatched++;
-}
-
-/*
- * as_dispatch_request selects the best request according to
- * read/write expire, batch expire, etc, and moves it to the dispatch
- * queue. Returns 1 if a request was found, 0 otherwise.
- */
-static int as_dispatch_request(struct request_queue *q, int force)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-	const int reads = !list_empty(&ad->fifo_list[BLK_RW_SYNC]);
-	const int writes = !list_empty(&ad->fifo_list[BLK_RW_ASYNC]);
-	struct request *rq;
-
-	if (unlikely(force)) {
-		/*
-		 * Forced dispatch, accounting is useless.  Reset
-		 * accounting states and dump fifo_lists.  Note that
-		 * batch_data_dir is reset to BLK_RW_SYNC to avoid
-		 * screwing write batch accounting as write batch
-		 * accounting occurs on W->R transition.
-		 */
-		int dispatched = 0;
-
-		ad->batch_data_dir = BLK_RW_SYNC;
-		ad->changed_batch = 0;
-		ad->new_batch = 0;
-
-		while (ad->next_rq[BLK_RW_SYNC]) {
-			as_move_to_dispatch(ad, ad->next_rq[BLK_RW_SYNC]);
-			dispatched++;
-		}
-		ad->last_check_fifo[BLK_RW_SYNC] = jiffies;
-
-		while (ad->next_rq[BLK_RW_ASYNC]) {
-			as_move_to_dispatch(ad, ad->next_rq[BLK_RW_ASYNC]);
-			dispatched++;
-		}
-		ad->last_check_fifo[BLK_RW_ASYNC] = jiffies;
-
-		return dispatched;
-	}
-
-	/* Signal that the write batch was uncontended, so we can't time it */
-	if (ad->batch_data_dir == BLK_RW_ASYNC && !reads) {
-		if (ad->current_write_count == 0 || !writes)
-			ad->write_batch_idled = 1;
-	}
-
-	if (!(reads || writes)
-		|| ad->antic_status == ANTIC_WAIT_REQ
-		|| ad->antic_status == ANTIC_WAIT_NEXT
-		|| ad->changed_batch)
-		return 0;
-
-	if (!(reads && writes && as_batch_expired(ad))) {
-		/*
-		 * batch is still running or no reads or no writes
-		 */
-		rq = ad->next_rq[ad->batch_data_dir];
-
-		if (ad->batch_data_dir == BLK_RW_SYNC && ad->antic_expire) {
-			if (as_fifo_expired(ad, BLK_RW_SYNC))
-				goto fifo_expired;
-
-			if (as_can_anticipate(ad, rq)) {
-				as_antic_waitreq(ad);
-				return 0;
-			}
-		}
-
-		if (rq) {
-			/* we have a "next request" */
-			if (reads && !writes)
-				ad->current_batch_expires =
-					jiffies + ad->batch_expire[BLK_RW_SYNC];
-			goto dispatch_request;
-		}
-	}
-
-	/*
-	 * at this point we are not running a batch. select the appropriate
-	 * data direction (read / write)
-	 */
-
-	if (reads) {
-		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[BLK_RW_SYNC]));
-
-		if (writes && ad->batch_data_dir == BLK_RW_SYNC)
-			/*
-			 * Last batch was a read, switch to writes
-			 */
-			goto dispatch_writes;
-
-		if (ad->batch_data_dir == BLK_RW_ASYNC) {
-			WARN_ON(ad->new_batch);
-			ad->changed_batch = 1;
-		}
-		ad->batch_data_dir = BLK_RW_SYNC;
-		rq = rq_entry_fifo(ad->fifo_list[BLK_RW_SYNC].next);
-		ad->last_check_fifo[ad->batch_data_dir] = jiffies;
-		goto dispatch_request;
-	}
-
-	/*
-	 * the last batch was a read
-	 */
-
-	if (writes) {
-dispatch_writes:
-		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[BLK_RW_ASYNC]));
-
-		if (ad->batch_data_dir == BLK_RW_SYNC) {
-			ad->changed_batch = 1;
-
-			/*
-			 * new_batch might be 1 when the queue runs out of
-			 * reads. A subsequent submission of a write might
-			 * cause a change of batch before the read is finished.
-			 */
-			ad->new_batch = 0;
-		}
-		ad->batch_data_dir = BLK_RW_ASYNC;
-		ad->current_write_count = ad->write_batch_count;
-		ad->write_batch_idled = 0;
-		rq = rq_entry_fifo(ad->fifo_list[BLK_RW_ASYNC].next);
-		ad->last_check_fifo[BLK_RW_ASYNC] = jiffies;
-		goto dispatch_request;
-	}
-
-	BUG();
-	return 0;
-
-dispatch_request:
-	/*
-	 * If a request has expired, service it.
-	 */
-
-	if (as_fifo_expired(ad, ad->batch_data_dir)) {
-fifo_expired:
-		rq = rq_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
-	}
-
-	if (ad->changed_batch) {
-		WARN_ON(ad->new_batch);
-
-		if (ad->nr_dispatched)
-			return 0;
-
-		if (ad->batch_data_dir == BLK_RW_ASYNC)
-			ad->current_batch_expires = jiffies +
-					ad->batch_expire[BLK_RW_ASYNC];
-		else
-			ad->new_batch = 1;
-
-		ad->changed_batch = 0;
-	}
-
-	/*
-	 * rq is the selected appropriate request.
-	 */
-	as_move_to_dispatch(ad, rq);
-
-	return 1;
-}
-
-/*
- * add rq to rbtree and fifo
- */
-static void as_add_request(struct request_queue *q, struct request *rq)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-	int data_dir;
-
-	RQ_SET_STATE(rq, AS_RQ_NEW);
-
-	data_dir = rq_is_sync(rq);
-
-	rq->elevator_private = as_get_io_context(q->node);
-
-	if (RQ_IOC(rq)) {
-		as_update_iohist(ad, RQ_IOC(rq)->aic, rq);
-		atomic_inc(&RQ_IOC(rq)->aic->nr_queued);
-	}
-
-	as_add_rq_rb(ad, rq);
-
-	/*
-	 * set expire time and add to fifo list
-	 */
-	rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]);
-	list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]);
-
-	as_update_rq(ad, rq); /* keep state machine up to date */
-	RQ_SET_STATE(rq, AS_RQ_QUEUED);
-}
-
-static void as_activate_request(struct request_queue *q, struct request *rq)
-{
-	WARN_ON(RQ_STATE(rq) != AS_RQ_DISPATCHED);
-	RQ_SET_STATE(rq, AS_RQ_REMOVED);
-	if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
-		atomic_dec(&RQ_IOC(rq)->aic->nr_dispatched);
-}
-
-static void as_deactivate_request(struct request_queue *q, struct request *rq)
-{
-	WARN_ON(RQ_STATE(rq) != AS_RQ_REMOVED);
-	RQ_SET_STATE(rq, AS_RQ_DISPATCHED);
-	if (RQ_IOC(rq) && RQ_IOC(rq)->aic)
-		atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched);
-}
-
-/*
- * as_queue_empty tells us if there are requests left in the device. It may
- * not be the case that a driver can get the next request even if the queue
- * is not empty - it is used in the block layer to check for plugging and
- * merging opportunities
- */
-static int as_queue_empty(struct request_queue *q)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-
-	return list_empty(&ad->fifo_list[BLK_RW_ASYNC])
-		&& list_empty(&ad->fifo_list[BLK_RW_SYNC]);
-}
-
-static int
-as_merge(struct request_queue *q, struct request **req, struct bio *bio)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-	sector_t rb_key = bio->bi_sector + bio_sectors(bio);
-	struct request *__rq;
-
-	/*
-	 * check for front merge
-	 */
-	__rq = elv_rb_find(&ad->sort_list[bio_data_dir(bio)], rb_key);
-	if (__rq && elv_rq_merge_ok(__rq, bio)) {
-		*req = __rq;
-		return ELEVATOR_FRONT_MERGE;
-	}
-
-	return ELEVATOR_NO_MERGE;
-}
-
-static void as_merged_request(struct request_queue *q, struct request *req,
-			      int type)
-{
-	struct as_data *ad = q->elevator->elevator_data;
-
-	/*
-	 * if the merge was a front merge, we need to reposition request
-	 */
-	if (type == ELEVATOR_FRONT_MERGE) {
-		as_del_rq_rb(ad, req);
-		as_add_rq_rb(ad, req);
-		/*
-		 * Note! At this stage of this and the next function, our next
-		 * request may not be optimal - eg the request may have "grown"
-		 * behind the disk head. We currently don't bother adjusting.
-		 */
-	}
-}
-
-static void as_merged_requests(struct request_queue *q, struct request *req,
-			 	struct request *next)
-{
-	/*
-	 * if next expires before rq, assign its expire time to arq
-	 * and move into next position (next will be deleted) in fifo
-	 */
-	if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) {
-		if (time_before(rq_fifo_time(next), rq_fifo_time(req))) {
-			list_move(&req->queuelist, &next->queuelist);
-			rq_set_fifo_time(req, rq_fifo_time(next));
-		}
-	}
-
-	/*
-	 * kill knowledge of next, this one is a goner
-	 */
-	as_remove_queued_request(q, next);
-	as_put_io_context(next);
-
-	RQ_SET_STATE(next, AS_RQ_MERGED);
-}
-
-/*
- * This is executed in a "deferred" process context, by kblockd. It calls the
- * driver's request_fn so the driver can submit that request.
- *
- * IMPORTANT! This guy will reenter the elevator, so set up all queue global
- * state before calling, and don't rely on any state over calls.
- *
- * FIXME! dispatch queue is not a queue at all!
- */
-static void as_work_handler(struct work_struct *work)
-{
-	struct as_data *ad = container_of(work, struct as_data, antic_work);
-
-	blk_run_queue(ad->q);
-}
-
-static int as_may_queue(struct request_queue *q, int rw)
-{
-	int ret = ELV_MQUEUE_MAY;
-	struct as_data *ad = q->elevator->elevator_data;
-	struct io_context *ioc;
-	if (ad->antic_status == ANTIC_WAIT_REQ ||
-			ad->antic_status == ANTIC_WAIT_NEXT) {
-		ioc = as_get_io_context(q->node);
-		if (ad->io_context == ioc)
-			ret = ELV_MQUEUE_MUST;
-		put_io_context(ioc);
-	}
-
-	return ret;
-}
-
-static void as_exit_queue(struct elevator_queue *e)
-{
-	struct as_data *ad = e->elevator_data;
-
-	del_timer_sync(&ad->antic_timer);
-	cancel_work_sync(&ad->antic_work);
-
-	BUG_ON(!list_empty(&ad->fifo_list[BLK_RW_SYNC]));
-	BUG_ON(!list_empty(&ad->fifo_list[BLK_RW_ASYNC]));
-
-	put_io_context(ad->io_context);
-	kfree(ad);
-}
-
-/*
- * initialize elevator private data (as_data).
- */
-static void *as_init_queue(struct request_queue *q)
-{
-	struct as_data *ad;
-
-	ad = kmalloc_node(sizeof(*ad), GFP_KERNEL | __GFP_ZERO, q->node);
-	if (!ad)
-		return NULL;
-
-	ad->q = q; /* Identify what queue the data belongs to */
-
-	/* anticipatory scheduling helpers */
-	ad->antic_timer.function = as_antic_timeout;
-	ad->antic_timer.data = (unsigned long)q;
-	init_timer(&ad->antic_timer);
-	INIT_WORK(&ad->antic_work, as_work_handler);
-
-	INIT_LIST_HEAD(&ad->fifo_list[BLK_RW_SYNC]);
-	INIT_LIST_HEAD(&ad->fifo_list[BLK_RW_ASYNC]);
-	ad->sort_list[BLK_RW_SYNC] = RB_ROOT;
-	ad->sort_list[BLK_RW_ASYNC] = RB_ROOT;
-	ad->fifo_expire[BLK_RW_SYNC] = default_read_expire;
-	ad->fifo_expire[BLK_RW_ASYNC] = default_write_expire;
-	ad->antic_expire = default_antic_expire;
-	ad->batch_expire[BLK_RW_SYNC] = default_read_batch_expire;
-	ad->batch_expire[BLK_RW_ASYNC] = default_write_batch_expire;
-
-	ad->current_batch_expires = jiffies + ad->batch_expire[BLK_RW_SYNC];
-	ad->write_batch_count = ad->batch_expire[BLK_RW_ASYNC] / 10;
-	if (ad->write_batch_count < 2)
-		ad->write_batch_count = 2;
-
-	return ad;
-}
-
-/*
- * sysfs parts below
- */
-
-static ssize_t
-as_var_show(unsigned int var, char *page)
-{
-	return sprintf(page, "%d\n", var);
-}
-
-static ssize_t
-as_var_store(unsigned long *var, const char *page, size_t count)
-{
-	char *p = (char *) page;
-
-	*var = simple_strtoul(p, &p, 10);
-	return count;
-}
-
-static ssize_t est_time_show(struct elevator_queue *e, char *page)
-{
-	struct as_data *ad = e->elevator_data;
-	int pos = 0;
-
-	pos += sprintf(page+pos, "%lu %% exit probability\n",
-				100*ad->exit_prob/256);
-	pos += sprintf(page+pos, "%lu %% probability of exiting without a "
-				"cooperating process submitting IO\n",
-				100*ad->exit_no_coop/256);
-	pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
-	pos += sprintf(page+pos, "%llu sectors new seek distance\n",
-				(unsigned long long)ad->new_seek_mean);
-
-	return pos;
-}
-
-#define SHOW_FUNCTION(__FUNC, __VAR)				\
-static ssize_t __FUNC(struct elevator_queue *e, char *page)	\
-{								\
-	struct as_data *ad = e->elevator_data;			\
-	return as_var_show(jiffies_to_msecs((__VAR)), (page));	\
-}
-SHOW_FUNCTION(as_read_expire_show, ad->fifo_expire[BLK_RW_SYNC]);
-SHOW_FUNCTION(as_write_expire_show, ad->fifo_expire[BLK_RW_ASYNC]);
-SHOW_FUNCTION(as_antic_expire_show, ad->antic_expire);
-SHOW_FUNCTION(as_read_batch_expire_show, ad->batch_expire[BLK_RW_SYNC]);
-SHOW_FUNCTION(as_write_batch_expire_show, ad->batch_expire[BLK_RW_ASYNC]);
-#undef SHOW_FUNCTION
-
-#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX)				\
-static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)	\
-{									\
-	struct as_data *ad = e->elevator_data;				\
-	int ret = as_var_store(__PTR, (page), count);			\
-	if (*(__PTR) < (MIN))						\
-		*(__PTR) = (MIN);					\
-	else if (*(__PTR) > (MAX))					\
-		*(__PTR) = (MAX);					\
-	*(__PTR) = msecs_to_jiffies(*(__PTR));				\
-	return ret;							\
-}
-STORE_FUNCTION(as_read_expire_store, &ad->fifo_expire[BLK_RW_SYNC], 0, INT_MAX);
-STORE_FUNCTION(as_write_expire_store,
-			&ad->fifo_expire[BLK_RW_ASYNC], 0, INT_MAX);
-STORE_FUNCTION(as_antic_expire_store, &ad->antic_expire, 0, INT_MAX);
-STORE_FUNCTION(as_read_batch_expire_store,
-			&ad->batch_expire[BLK_RW_SYNC], 0, INT_MAX);
-STORE_FUNCTION(as_write_batch_expire_store,
-			&ad->batch_expire[BLK_RW_ASYNC], 0, INT_MAX);
-#undef STORE_FUNCTION
-
-#define AS_ATTR(name) \
-	__ATTR(name, S_IRUGO|S_IWUSR, as_##name##_show, as_##name##_store)
-
-static struct elv_fs_entry as_attrs[] = {
-	__ATTR_RO(est_time),
-	AS_ATTR(read_expire),
-	AS_ATTR(write_expire),
-	AS_ATTR(antic_expire),
-	AS_ATTR(read_batch_expire),
-	AS_ATTR(write_batch_expire),
-	__ATTR_NULL
-};
-
-static struct elevator_type iosched_as = {
-	.ops = {
-		.elevator_merge_fn = 		as_merge,
-		.elevator_merged_fn =		as_merged_request,
-		.elevator_merge_req_fn =	as_merged_requests,
-		.elevator_dispatch_fn =		as_dispatch_request,
-		.elevator_add_req_fn =		as_add_request,
-		.elevator_activate_req_fn =	as_activate_request,
-		.elevator_deactivate_req_fn = 	as_deactivate_request,
-		.elevator_queue_empty_fn =	as_queue_empty,
-		.elevator_completed_req_fn =	as_completed_request,
-		.elevator_former_req_fn =	elv_rb_former_request,
-		.elevator_latter_req_fn =	elv_rb_latter_request,
-		.elevator_may_queue_fn =	as_may_queue,
-		.elevator_init_fn =		as_init_queue,
-		.elevator_exit_fn =		as_exit_queue,
-		.trim =				as_trim,
-	},
-
-	.elevator_attrs = as_attrs,
-	.elevator_name = "anticipatory",
-	.elevator_owner = THIS_MODULE,
-};
-
-static int __init as_init(void)
-{
-	elv_register(&iosched_as);
-
-	return 0;
-}
-
-static void __exit as_exit(void)
-{
-	DECLARE_COMPLETION_ONSTACK(all_gone);
-	elv_unregister(&iosched_as);
-	ioc_gone = &all_gone;
-	/* ioc_gone's update must be visible before reading ioc_count */
-	smp_wmb();
-	if (elv_ioc_count_read(as_ioc_count))
-		wait_for_completion(&all_gone);
-	synchronize_rcu();
-}
-
-module_init(as_init);
-module_exit(as_exit);
-
-MODULE_AUTHOR("Nick Piggin");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("anticipatory IO scheduler");
diff -druNp linux-libre-2.6.32-gnu1/block/blk-barrier.c linux-libre-2.6.33-gnu1/block/blk-barrier.c
--- linux-libre-2.6.32-gnu1/block/blk-barrier.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-barrier.c	2010-02-24 13:52:17.000000000 -0500
@@ -402,7 +402,7 @@ int blkdev_issue_discard(struct block_de
 		 * our current implementations need.  If we'll ever need
 		 * more the interface will need revisiting.
 		 */
-		page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		page = alloc_page(gfp_mask | __GFP_ZERO);
 		if (!page)
 			goto out_free_bio;
 		if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
diff -druNp linux-libre-2.6.32-gnu1/block/blk-cgroup.c linux-libre-2.6.33-gnu1/block/blk-cgroup.c
--- linux-libre-2.6.32-gnu1/block/blk-cgroup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-cgroup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,361 @@
+/*
+ * Common Block IO controller cgroup interface
+ *
+ * Based on ideas and code from CFQ, CFS and BFQ:
+ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
+ *
+ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+ *		      Paolo Valente <paolo.valente@unimore.it>
+ *
+ * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
+ * 	              Nauman Rafique <nauman@google.com>
+ */
+#include <linux/ioprio.h>
+#include <linux/seq_file.h>
+#include <linux/kdev_t.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include "blk-cgroup.h"
+
+static DEFINE_SPINLOCK(blkio_list_lock);
+static LIST_HEAD(blkio_list);
+
+struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
+EXPORT_SYMBOL_GPL(blkio_root_cgroup);
+
+bool blkiocg_css_tryget(struct blkio_cgroup *blkcg)
+{
+	if (!css_tryget(&blkcg->css))
+		return false;
+	return true;
+}
+EXPORT_SYMBOL_GPL(blkiocg_css_tryget);
+
+void blkiocg_css_put(struct blkio_cgroup *blkcg)
+{
+	css_put(&blkcg->css);
+}
+EXPORT_SYMBOL_GPL(blkiocg_css_put);
+
+struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
+{
+	return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id),
+			    struct blkio_cgroup, css);
+}
+EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup);
+
+void blkiocg_update_blkio_group_stats(struct blkio_group *blkg,
+			unsigned long time, unsigned long sectors)
+{
+	blkg->time += time;
+	blkg->sectors += sectors;
+}
+EXPORT_SYMBOL_GPL(blkiocg_update_blkio_group_stats);
+
+void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
+			struct blkio_group *blkg, void *key, dev_t dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&blkcg->lock, flags);
+	rcu_assign_pointer(blkg->key, key);
+	blkg->blkcg_id = css_id(&blkcg->css);
+	hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
+	spin_unlock_irqrestore(&blkcg->lock, flags);
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+	/* Need to take css reference ? */
+	cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path));
+#endif
+	blkg->dev = dev;
+}
+EXPORT_SYMBOL_GPL(blkiocg_add_blkio_group);
+
+static void __blkiocg_del_blkio_group(struct blkio_group *blkg)
+{
+	hlist_del_init_rcu(&blkg->blkcg_node);
+	blkg->blkcg_id = 0;
+}
+
+/*
+ * returns 0 if blkio_group was still on cgroup list. Otherwise returns 1
+ * indicating that blk_group was unhashed by the time we got to it.
+ */
+int blkiocg_del_blkio_group(struct blkio_group *blkg)
+{
+	struct blkio_cgroup *blkcg;
+	unsigned long flags;
+	struct cgroup_subsys_state *css;
+	int ret = 1;
+
+	rcu_read_lock();
+	css = css_lookup(&blkio_subsys, blkg->blkcg_id);
+	if (!css)
+		goto out;
+
+	blkcg = container_of(css, struct blkio_cgroup, css);
+	spin_lock_irqsave(&blkcg->lock, flags);
+	if (!hlist_unhashed(&blkg->blkcg_node)) {
+		__blkiocg_del_blkio_group(blkg);
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&blkcg->lock, flags);
+out:
+	rcu_read_unlock();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blkiocg_del_blkio_group);
+
+/* called under rcu_read_lock(). */
+struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key)
+{
+	struct blkio_group *blkg;
+	struct hlist_node *n;
+	void *__key;
+
+	hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) {
+		__key = blkg->key;
+		if (__key == key)
+			return blkg;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(blkiocg_lookup_group);
+
+#define SHOW_FUNCTION(__VAR)						\
+static u64 blkiocg_##__VAR##_read(struct cgroup *cgroup,		\
+				       struct cftype *cftype)		\
+{									\
+	struct blkio_cgroup *blkcg;					\
+									\
+	blkcg = cgroup_to_blkio_cgroup(cgroup);				\
+	return (u64)blkcg->__VAR;					\
+}
+
+SHOW_FUNCTION(weight);
+#undef SHOW_FUNCTION
+
+static int
+blkiocg_weight_write(struct cgroup *cgroup, struct cftype *cftype, u64 val)
+{
+	struct blkio_cgroup *blkcg;
+	struct blkio_group *blkg;
+	struct hlist_node *n;
+	struct blkio_policy_type *blkiop;
+
+	if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX)
+		return -EINVAL;
+
+	blkcg = cgroup_to_blkio_cgroup(cgroup);
+	spin_lock(&blkio_list_lock);
+	spin_lock_irq(&blkcg->lock);
+	blkcg->weight = (unsigned int)val;
+	hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
+		list_for_each_entry(blkiop, &blkio_list, list)
+			blkiop->ops.blkio_update_group_weight_fn(blkg,
+					blkcg->weight);
+	}
+	spin_unlock_irq(&blkcg->lock);
+	spin_unlock(&blkio_list_lock);
+	return 0;
+}
+
+#define SHOW_FUNCTION_PER_GROUP(__VAR)					\
+static int blkiocg_##__VAR##_read(struct cgroup *cgroup,		\
+			struct cftype *cftype, struct seq_file *m)	\
+{									\
+	struct blkio_cgroup *blkcg;					\
+	struct blkio_group *blkg;					\
+	struct hlist_node *n;						\
+									\
+	if (!cgroup_lock_live_group(cgroup))				\
+		return -ENODEV;						\
+									\
+	blkcg = cgroup_to_blkio_cgroup(cgroup);				\
+	rcu_read_lock();						\
+	hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) {\
+		if (blkg->dev)						\
+			seq_printf(m, "%u:%u %lu\n", MAJOR(blkg->dev),	\
+				 MINOR(blkg->dev), blkg->__VAR);	\
+	}								\
+	rcu_read_unlock();						\
+	cgroup_unlock();						\
+	return 0;							\
+}
+
+SHOW_FUNCTION_PER_GROUP(time);
+SHOW_FUNCTION_PER_GROUP(sectors);
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+SHOW_FUNCTION_PER_GROUP(dequeue);
+#endif
+#undef SHOW_FUNCTION_PER_GROUP
+
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+void blkiocg_update_blkio_group_dequeue_stats(struct blkio_group *blkg,
+			unsigned long dequeue)
+{
+	blkg->dequeue += dequeue;
+}
+EXPORT_SYMBOL_GPL(blkiocg_update_blkio_group_dequeue_stats);
+#endif
+
+struct cftype blkio_files[] = {
+	{
+		.name = "weight",
+		.read_u64 = blkiocg_weight_read,
+		.write_u64 = blkiocg_weight_write,
+	},
+	{
+		.name = "time",
+		.read_seq_string = blkiocg_time_read,
+	},
+	{
+		.name = "sectors",
+		.read_seq_string = blkiocg_sectors_read,
+	},
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+       {
+		.name = "dequeue",
+		.read_seq_string = blkiocg_dequeue_read,
+       },
+#endif
+};
+
+static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+{
+	return cgroup_add_files(cgroup, subsys, blkio_files,
+				ARRAY_SIZE(blkio_files));
+}
+
+static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+{
+	struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
+	unsigned long flags;
+	struct blkio_group *blkg;
+	void *key;
+	struct blkio_policy_type *blkiop;
+
+	rcu_read_lock();
+remove_entry:
+	spin_lock_irqsave(&blkcg->lock, flags);
+
+	if (hlist_empty(&blkcg->blkg_list)) {
+		spin_unlock_irqrestore(&blkcg->lock, flags);
+		goto done;
+	}
+
+	blkg = hlist_entry(blkcg->blkg_list.first, struct blkio_group,
+				blkcg_node);
+	key = rcu_dereference(blkg->key);
+	__blkiocg_del_blkio_group(blkg);
+
+	spin_unlock_irqrestore(&blkcg->lock, flags);
+
+	/*
+	 * This blkio_group is being unlinked as associated cgroup is going
+	 * away. Let all the IO controlling policies know about this event.
+	 *
+	 * Currently this is static call to one io controlling policy. Once
+	 * we have more policies in place, we need some dynamic registration
+	 * of callback function.
+	 */
+	spin_lock(&blkio_list_lock);
+	list_for_each_entry(blkiop, &blkio_list, list)
+		blkiop->ops.blkio_unlink_group_fn(key, blkg);
+	spin_unlock(&blkio_list_lock);
+	goto remove_entry;
+done:
+	free_css_id(&blkio_subsys, &blkcg->css);
+	rcu_read_unlock();
+	kfree(blkcg);
+}
+
+static struct cgroup_subsys_state *
+blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+{
+	struct blkio_cgroup *blkcg, *parent_blkcg;
+
+	if (!cgroup->parent) {
+		blkcg = &blkio_root_cgroup;
+		goto done;
+	}
+
+	/* Currently we do not support hierarchy deeper than two level (0,1) */
+	parent_blkcg = cgroup_to_blkio_cgroup(cgroup->parent);
+	if (css_depth(&parent_blkcg->css) > 0)
+		return ERR_PTR(-EINVAL);
+
+	blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
+	if (!blkcg)
+		return ERR_PTR(-ENOMEM);
+
+	blkcg->weight = BLKIO_WEIGHT_DEFAULT;
+done:
+	spin_lock_init(&blkcg->lock);
+	INIT_HLIST_HEAD(&blkcg->blkg_list);
+
+	return &blkcg->css;
+}
+
+/*
+ * We cannot support shared io contexts, as we have no mean to support
+ * two tasks with the same ioc in two different groups without major rework
+ * of the main cic data structures.  For now we allow a task to change
+ * its cgroup only if it's the only owner of its ioc.
+ */
+static int blkiocg_can_attach(struct cgroup_subsys *subsys,
+				struct cgroup *cgroup, struct task_struct *tsk,
+				bool threadgroup)
+{
+	struct io_context *ioc;
+	int ret = 0;
+
+	/* task_lock() is needed to avoid races with exit_io_context() */
+	task_lock(tsk);
+	ioc = tsk->io_context;
+	if (ioc && atomic_read(&ioc->nr_tasks) > 1)
+		ret = -EINVAL;
+	task_unlock(tsk);
+
+	return ret;
+}
+
+static void blkiocg_attach(struct cgroup_subsys *subsys, struct cgroup *cgroup,
+				struct cgroup *prev, struct task_struct *tsk,
+				bool threadgroup)
+{
+	struct io_context *ioc;
+
+	task_lock(tsk);
+	ioc = tsk->io_context;
+	if (ioc)
+		ioc->cgroup_changed = 1;
+	task_unlock(tsk);
+}
+
+struct cgroup_subsys blkio_subsys = {
+	.name = "blkio",
+	.create = blkiocg_create,
+	.can_attach = blkiocg_can_attach,
+	.attach = blkiocg_attach,
+	.destroy = blkiocg_destroy,
+	.populate = blkiocg_populate,
+	.subsys_id = blkio_subsys_id,
+	.use_id = 1,
+};
+
+void blkio_policy_register(struct blkio_policy_type *blkiop)
+{
+	spin_lock(&blkio_list_lock);
+	list_add_tail(&blkiop->list, &blkio_list);
+	spin_unlock(&blkio_list_lock);
+}
+EXPORT_SYMBOL_GPL(blkio_policy_register);
+
+void blkio_policy_unregister(struct blkio_policy_type *blkiop)
+{
+	spin_lock(&blkio_list_lock);
+	list_del_init(&blkiop->list);
+	spin_unlock(&blkio_list_lock);
+}
+EXPORT_SYMBOL_GPL(blkio_policy_unregister);
diff -druNp linux-libre-2.6.32-gnu1/block/blk-cgroup.h linux-libre-2.6.33-gnu1/block/blk-cgroup.h
--- linux-libre-2.6.32-gnu1/block/blk-cgroup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-cgroup.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,127 @@
+#ifndef _BLK_CGROUP_H
+#define _BLK_CGROUP_H
+/*
+ * Common Block IO controller cgroup interface
+ *
+ * Based on ideas and code from CFQ, CFS and BFQ:
+ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
+ *
+ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+ *		      Paolo Valente <paolo.valente@unimore.it>
+ *
+ * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
+ * 	              Nauman Rafique <nauman@google.com>
+ */
+
+#include <linux/cgroup.h>
+
+#ifdef CONFIG_BLK_CGROUP
+
+struct blkio_cgroup {
+	struct cgroup_subsys_state css;
+	unsigned int weight;
+	spinlock_t lock;
+	struct hlist_head blkg_list;
+};
+
+struct blkio_group {
+	/* An rcu protected unique identifier for the group */
+	void *key;
+	struct hlist_node blkcg_node;
+	unsigned short blkcg_id;
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+	/* Store cgroup path */
+	char path[128];
+	/* How many times this group has been removed from service tree */
+	unsigned long dequeue;
+#endif
+	/* The device MKDEV(major, minor), this group has been created for */
+	dev_t   dev;
+
+	/* total disk time and nr sectors dispatched by this group */
+	unsigned long time;
+	unsigned long sectors;
+};
+
+extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg);
+extern void blkiocg_css_put(struct blkio_cgroup *blkcg);
+
+typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
+typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
+						unsigned int weight);
+
+struct blkio_policy_ops {
+	blkio_unlink_group_fn *blkio_unlink_group_fn;
+	blkio_update_group_weight_fn *blkio_update_group_weight_fn;
+};
+
+struct blkio_policy_type {
+	struct list_head list;
+	struct blkio_policy_ops ops;
+};
+
+/* Blkio controller policy registration */
+extern void blkio_policy_register(struct blkio_policy_type *);
+extern void blkio_policy_unregister(struct blkio_policy_type *);
+
+#else
+
+struct blkio_group {
+};
+
+struct blkio_policy_type {
+};
+
+static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
+static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
+
+#endif
+
+#define BLKIO_WEIGHT_MIN	100
+#define BLKIO_WEIGHT_MAX	1000
+#define BLKIO_WEIGHT_DEFAULT	500
+
+#ifdef CONFIG_DEBUG_BLK_CGROUP
+static inline char *blkg_path(struct blkio_group *blkg)
+{
+	return blkg->path;
+}
+void blkiocg_update_blkio_group_dequeue_stats(struct blkio_group *blkg,
+				unsigned long dequeue);
+#else
+static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
+static inline void blkiocg_update_blkio_group_dequeue_stats(
+			struct blkio_group *blkg, unsigned long dequeue) {}
+#endif
+
+#ifdef CONFIG_BLK_CGROUP
+extern struct blkio_cgroup blkio_root_cgroup;
+extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
+extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
+			struct blkio_group *blkg, void *key, dev_t dev);
+extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
+extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
+						void *key);
+void blkiocg_update_blkio_group_stats(struct blkio_group *blkg,
+			unsigned long time, unsigned long sectors);
+#else
+struct cgroup;
+static inline struct blkio_cgroup *
+cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
+
+static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
+			struct blkio_group *blkg, void *key, dev_t dev)
+{
+}
+
+static inline int
+blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
+
+static inline struct blkio_group *
+blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; }
+static inline void blkiocg_update_blkio_group_stats(struct blkio_group *blkg,
+			unsigned long time, unsigned long sectors)
+{
+}
+#endif
+#endif /* _BLK_CGROUP_H */
diff -druNp linux-libre-2.6.32-gnu1/block/blk-core.c linux-libre-2.6.33-gnu1/block/blk-core.c
--- linux-libre-2.6.32-gnu1/block/blk-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -1147,7 +1147,7 @@ void init_request_from_bio(struct reques
  */
 static inline bool queue_should_plug(struct request_queue *q)
 {
-	return !(blk_queue_nonrot(q) && blk_queue_queuing(q));
+	return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
 }
 
 static int __make_request(struct request_queue *q, struct bio *bio)
@@ -1859,15 +1859,8 @@ void blk_dequeue_request(struct request
 	 * and to it is freed is accounted as io that is in progress at
 	 * the driver side.
 	 */
-	if (blk_account_rq(rq)) {
+	if (blk_account_rq(rq))
 		q->in_flight[rq_is_sync(rq)]++;
-		/*
-		 * Mark this device as supporting hardware queuing, if
-		 * we have more IOs in flight than 4.
-		 */
-		if (!blk_queue_queuing(q) && queue_in_flight(q) > 4)
-			set_bit(QUEUE_FLAG_CQ, &q->queue_flags);
-	}
 }
 
 /**
@@ -2358,6 +2351,25 @@ void blk_rq_bio_prep(struct request_queu
 		rq->rq_disk = bio->bi_bdev->bd_disk;
 }
 
+#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
+/**
+ * rq_flush_dcache_pages - Helper function to flush all pages in a request
+ * @rq: the request to be flushed
+ *
+ * Description:
+ *     Flush all pages in @rq.
+ */
+void rq_flush_dcache_pages(struct request *rq)
+{
+	struct req_iterator iter;
+	struct bio_vec *bvec;
+
+	rq_for_each_segment(bvec, rq, iter)
+		flush_dcache_page(bvec->bv_page);
+}
+EXPORT_SYMBOL_GPL(rq_flush_dcache_pages);
+#endif
+
 /**
  * blk_lld_busy - Check if underlying low-level drivers of a device are busy
  * @q : the queue of the device being checked
diff -druNp linux-libre-2.6.32-gnu1/block/blk-ioc.c linux-libre-2.6.33-gnu1/block/blk-ioc.c
--- linux-libre-2.6.32-gnu1/block/blk-ioc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-ioc.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,6 @@ int put_io_context(struct io_context *io
 
 	if (atomic_long_dec_and_test(&ioc->refcount)) {
 		rcu_read_lock();
-		if (ioc->aic && ioc->aic->dtor)
-			ioc->aic->dtor(ioc->aic);
 		cfq_dtor(ioc);
 		rcu_read_unlock();
 
@@ -66,22 +64,20 @@ static void cfq_exit(struct io_context *
 }
 
 /* Called by the exitting task */
-void exit_io_context(void)
+void exit_io_context(struct task_struct *task)
 {
 	struct io_context *ioc;
 
-	task_lock(current);
-	ioc = current->io_context;
-	current->io_context = NULL;
-	task_unlock(current);
+	task_lock(task);
+	ioc = task->io_context;
+	task->io_context = NULL;
+	task_unlock(task);
 
 	if (atomic_dec_and_test(&ioc->nr_tasks)) {
-		if (ioc->aic && ioc->aic->exit)
-			ioc->aic->exit(ioc->aic);
 		cfq_exit(ioc);
 
-		put_io_context(ioc);
 	}
+	put_io_context(ioc);
 }
 
 struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
@@ -97,7 +93,6 @@ struct io_context *alloc_io_context(gfp_
 		ret->ioprio = 0;
 		ret->last_waited = jiffies; /* doesn't matter... */
 		ret->nr_batch_requests = 0; /* because this is 0 */
-		ret->aic = NULL;
 		INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
 		INIT_HLIST_HEAD(&ret->cic_list);
 		ret->ioc_data = NULL;
diff -druNp linux-libre-2.6.32-gnu1/block/blk-iopoll.c linux-libre-2.6.33-gnu1/block/blk-iopoll.c
--- linux-libre-2.6.32-gnu1/block/blk-iopoll.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-iopoll.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ static DEFINE_PER_CPU(struct list_head,
  * Description:
  *     Add this blk_iopoll structure to the pending poll list and trigger the
  *     raise of the blk iopoll softirq. The driver must already have gotten a
- *     succesful return from blk_iopoll_sched_prep() before calling this.
+ *     successful return from blk_iopoll_sched_prep() before calling this.
  **/
 void blk_iopoll_sched(struct blk_iopoll *iop)
 {
diff -druNp linux-libre-2.6.32-gnu1/block/blk-settings.c linux-libre-2.6.33-gnu1/block/blk-settings.c
--- linux-libre-2.6.32-gnu1/block/blk-settings.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-settings.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>	/* for max_pfn/max_low_pfn */
 #include <linux/gcd.h>
+#include <linux/jiffies.h>
 
 #include "blk.h"
 
@@ -96,7 +97,11 @@ void blk_set_default_limits(struct queue
 	lim->max_segment_size = MAX_SEGMENT_SIZE;
 	lim->max_sectors = BLK_DEF_MAX_SECTORS;
 	lim->max_hw_sectors = INT_MAX;
-	lim->max_discard_sectors = SAFE_MAX_SECTORS;
+	lim->max_discard_sectors = 0;
+	lim->discard_granularity = 0;
+	lim->discard_alignment = 0;
+	lim->discard_misaligned = 0;
+	lim->discard_zeroes_data = -1;
 	lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
 	lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
 	lim->alignment_offset = 0;
@@ -141,7 +146,7 @@ void blk_queue_make_request(struct reque
 	q->nr_batching = BLK_BATCH_REQ;
 
 	q->unplug_thresh = 4;		/* hmm */
-	q->unplug_delay = (3 * HZ) / 1000;	/* 3 milliseconds */
+	q->unplug_delay = msecs_to_jiffies(3);	/* 3 milliseconds */
 	if (q->unplug_delay == 0)
 		q->unplug_delay = 1;
 
@@ -488,20 +493,43 @@ void blk_queue_stack_limits(struct reque
 }
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
+static unsigned int lcm(unsigned int a, unsigned int b)
+{
+	if (a && b)
+		return (a * b) / gcd(a, b);
+	else if (b)
+		return b;
+
+	return a;
+}
+
 /**
  * blk_stack_limits - adjust queue_limits for stacked devices
- * @t:	the stacking driver limits (top)
- * @b:  the underlying queue limits (bottom)
+ * @t:	the stacking driver limits (top device)
+ * @b:  the underlying queue limits (bottom, component device)
  * @offset:  offset to beginning of data within component device
  *
  * Description:
- *    Merges two queue_limit structs.  Returns 0 if alignment didn't
- *    change.  Returns -1 if adding the bottom device caused
- *    misalignment.
+ *    This function is used by stacking drivers like MD and DM to ensure
+ *    that all component devices have compatible block sizes and
+ *    alignments.  The stacking driver must provide a queue_limits
+ *    struct (top) and then iteratively call the stacking function for
+ *    all component (bottom) devices.  The stacking function will
+ *    attempt to combine the values and ensure proper alignment.
+ *
+ *    Returns 0 if the top and bottom queue_limits are compatible.  The
+ *    top device's block sizes and alignment offsets may be adjusted to
+ *    ensure alignment with the bottom device. If no compatible sizes
+ *    and alignments exist, -1 is returned and the resulting top
+ *    queue_limits will have the misaligned flag set to indicate that
+ *    the alignment_offset is undefined.
  */
 int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
 		     sector_t offset)
 {
+	sector_t alignment;
+	unsigned int top, bottom, ret = 0;
+
 	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
 	t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
 	t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
@@ -518,6 +546,26 @@ int blk_stack_limits(struct queue_limits
 	t->max_segment_size = min_not_zero(t->max_segment_size,
 					   b->max_segment_size);
 
+	t->misaligned |= b->misaligned;
+
+	alignment = queue_limit_alignment_offset(b, offset);
+
+	/* Bottom device has different alignment.  Check that it is
+	 * compatible with the current top alignment.
+	 */
+	if (t->alignment_offset != alignment) {
+
+		top = max(t->physical_block_size, t->io_min)
+			+ t->alignment_offset;
+		bottom = max(b->physical_block_size, b->io_min) + alignment;
+
+		/* Verify that top and bottom intervals line up */
+		if (max(top, bottom) & (min(top, bottom) - 1)) {
+			t->misaligned = 1;
+			ret = -1;
+		}
+	}
+
 	t->logical_block_size = max(t->logical_block_size,
 				    b->logical_block_size);
 
@@ -525,41 +573,95 @@ int blk_stack_limits(struct queue_limits
 				     b->physical_block_size);
 
 	t->io_min = max(t->io_min, b->io_min);
+	t->io_opt = lcm(t->io_opt, b->io_opt);
+
 	t->no_cluster |= b->no_cluster;
+	t->discard_zeroes_data &= b->discard_zeroes_data;
 
-	/* Bottom device offset aligned? */
-	if (offset &&
-	    (offset & (b->physical_block_size - 1)) != b->alignment_offset) {
+	/* Physical block size a multiple of the logical block size? */
+	if (t->physical_block_size & (t->logical_block_size - 1)) {
+		t->physical_block_size = t->logical_block_size;
 		t->misaligned = 1;
-		return -1;
+		ret = -1;
 	}
 
-	/* If top has no alignment offset, inherit from bottom */
-	if (!t->alignment_offset)
-		t->alignment_offset =
-			b->alignment_offset & (b->physical_block_size - 1);
+	/* Minimum I/O a multiple of the physical block size? */
+	if (t->io_min & (t->physical_block_size - 1)) {
+		t->io_min = t->physical_block_size;
+		t->misaligned = 1;
+		ret = -1;
+	}
 
-	/* Top device aligned on logical block boundary? */
+	/* Optimal I/O a multiple of the physical block size? */
+	if (t->io_opt & (t->physical_block_size - 1)) {
+		t->io_opt = 0;
+		t->misaligned = 1;
+		ret = -1;
+	}
+
+	/* Find lowest common alignment_offset */
+	t->alignment_offset = lcm(t->alignment_offset, alignment)
+		& (max(t->physical_block_size, t->io_min) - 1);
+
+	/* Verify that new alignment_offset is on a logical block boundary */
 	if (t->alignment_offset & (t->logical_block_size - 1)) {
 		t->misaligned = 1;
-		return -1;
+		ret = -1;
 	}
 
-	/* Find lcm() of optimal I/O size */
-	if (t->io_opt && b->io_opt)
-		t->io_opt = (t->io_opt * b->io_opt) / gcd(t->io_opt, b->io_opt);
-	else if (b->io_opt)
-		t->io_opt = b->io_opt;
+	/* Discard alignment and granularity */
+	if (b->discard_granularity) {
+		unsigned int granularity = b->discard_granularity;
+		offset &= granularity - 1;
 
-	/* Verify that optimal I/O size is a multiple of io_min */
-	if (t->io_min && t->io_opt % t->io_min)
-		return -1;
+		alignment = (granularity + b->discard_alignment - offset)
+			& (granularity - 1);
 
-	return 0;
+		if (t->discard_granularity != 0 &&
+		    t->discard_alignment != alignment) {
+			top = t->discard_granularity + t->discard_alignment;
+			bottom = b->discard_granularity + alignment;
+
+			/* Verify that top and bottom intervals line up */
+			if (max(top, bottom) & (min(top, bottom) - 1))
+				t->discard_misaligned = 1;
+		}
+
+		t->max_discard_sectors = min_not_zero(t->max_discard_sectors,
+						      b->max_discard_sectors);
+		t->discard_granularity = max(t->discard_granularity,
+					     b->discard_granularity);
+		t->discard_alignment = lcm(t->discard_alignment, alignment) &
+			(t->discard_granularity - 1);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(blk_stack_limits);
 
 /**
+ * bdev_stack_limits - adjust queue limits for stacked drivers
+ * @t:	the stacking driver limits (top device)
+ * @bdev:  the component block_device (bottom)
+ * @start:  first data sector within component device
+ *
+ * Description:
+ *    Merges queue limits for a top device and a block_device.  Returns
+ *    0 if alignment didn't change.  Returns -1 if adding the bottom
+ *    device caused misalignment.
+ */
+int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
+		      sector_t start)
+{
+	struct request_queue *bq = bdev_get_queue(bdev);
+
+	start += get_start_sect(bdev);
+
+	return blk_stack_limits(t, &bq->limits, start << 9);
+}
+EXPORT_SYMBOL(bdev_stack_limits);
+
+/**
  * disk_stack_limits - adjust queue limits for stacked drivers
  * @disk:  MD/DM gendisk (top)
  * @bdev:  the underlying block device (bottom)
diff -druNp linux-libre-2.6.32-gnu1/block/blk-sysfs.c linux-libre-2.6.33-gnu1/block/blk-sysfs.c
--- linux-libre-2.6.32-gnu1/block/blk-sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/blk-sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,6 +126,21 @@ static ssize_t queue_io_opt_show(struct
 	return queue_var_show(queue_io_opt(q), page);
 }
 
+static ssize_t queue_discard_granularity_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(q->limits.discard_granularity, page);
+}
+
+static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(q->limits.max_discard_sectors << 9, page);
+}
+
+static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(queue_discard_zeroes_data(q), page);
+}
+
 static ssize_t
 queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
 {
@@ -293,6 +308,21 @@ static struct queue_sysfs_entry queue_io
 	.show = queue_io_opt_show,
 };
 
+static struct queue_sysfs_entry queue_discard_granularity_entry = {
+	.attr = {.name = "discard_granularity", .mode = S_IRUGO },
+	.show = queue_discard_granularity_show,
+};
+
+static struct queue_sysfs_entry queue_discard_max_entry = {
+	.attr = {.name = "discard_max_bytes", .mode = S_IRUGO },
+	.show = queue_discard_max_show,
+};
+
+static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
+	.attr = {.name = "discard_zeroes_data", .mode = S_IRUGO },
+	.show = queue_discard_zeroes_data_show,
+};
+
 static struct queue_sysfs_entry queue_nonrot_entry = {
 	.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
 	.show = queue_nonrot_show,
@@ -328,6 +358,9 @@ static struct attribute *default_attrs[]
 	&queue_physical_block_size_entry.attr,
 	&queue_io_min_entry.attr,
 	&queue_io_opt_entry.attr,
+	&queue_discard_granularity_entry.attr,
+	&queue_discard_max_entry.attr,
+	&queue_discard_zeroes_data_entry.attr,
 	&queue_nonrot_entry.attr,
 	&queue_nomerges_entry.attr,
 	&queue_rq_affinity_entry.attr,
diff -druNp linux-libre-2.6.32-gnu1/block/bsg.c linux-libre-2.6.33-gnu1/block/bsg.c
--- linux-libre-2.6.32-gnu1/block/bsg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/bsg.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/blkdev.h>
 #include <linux/poll.h>
 #include <linux/cdev.h>
+#include <linux/jiffies.h>
 #include <linux/percpu.h>
 #include <linux/uio.h>
 #include <linux/idr.h>
@@ -197,7 +198,7 @@ static int blk_fill_sgv4_hdr_rq(struct r
 	rq->cmd_len = hdr->request_len;
 	rq->cmd_type = REQ_TYPE_BLOCK_PC;
 
-	rq->timeout = (hdr->timeout * HZ) / 1000;
+	rq->timeout = msecs_to_jiffies(hdr->timeout);
 	if (!rq->timeout)
 		rq->timeout = q->sg_timeout;
 	if (!rq->timeout)
diff -druNp linux-libre-2.6.32-gnu1/block/cfq-iosched.c linux-libre-2.6.33-gnu1/block/cfq-iosched.c
--- linux-libre-2.6.32-gnu1/block/cfq-iosched.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/cfq-iosched.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,9 +9,11 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
+#include <linux/jiffies.h>
 #include <linux/rbtree.h>
 #include <linux/ioprio.h>
 #include <linux/blktrace_api.h>
+#include "blk-cgroup.h"
 
 /*
  * tunables
@@ -27,6 +29,8 @@ static const int cfq_slice_sync = HZ / 1
 static int cfq_slice_async = HZ / 25;
 static const int cfq_slice_async_rq = 2;
 static int cfq_slice_idle = HZ / 125;
+static const int cfq_target_latency = HZ * 3/10; /* 300 ms */
+static const int cfq_hist_divisor = 4;
 
 /*
  * offset from end of service tree
@@ -40,6 +44,10 @@ static int cfq_slice_idle = HZ / 125;
 
 #define CFQ_SLICE_SCALE		(5)
 #define CFQ_HW_QUEUE_MIN	(5)
+#define CFQ_SERVICE_SHIFT       12
+
+#define CFQQ_SEEK_THR		8 * 1024
+#define CFQQ_SEEKY(cfqq)	((cfqq)->seek_mean > CFQQ_SEEK_THR)
 
 #define RQ_CIC(rq)		\
 	((struct cfq_io_context *) (rq)->elevator_private)
@@ -57,6 +65,7 @@ static DEFINE_SPINLOCK(ioc_gone_lock);
 #define cfq_class_rt(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
 
 #define sample_valid(samples)	((samples) > 80)
+#define rb_entry_cfqg(node)	rb_entry((node), struct cfq_group, rb_node)
 
 /*
  * Most of our rbtree usage is for sorting with min extraction, so
@@ -67,8 +76,12 @@ static DEFINE_SPINLOCK(ioc_gone_lock);
 struct cfq_rb_root {
 	struct rb_root rb;
 	struct rb_node *left;
+	unsigned count;
+	u64 min_vdisktime;
+	struct rb_node *active;
+	unsigned total_weight;
 };
-#define CFQ_RB_ROOT	(struct cfq_rb_root) { RB_ROOT, NULL, }
+#define CFQ_RB_ROOT	(struct cfq_rb_root) { RB_ROOT, NULL, 0, 0, }
 
 /*
  * Per process-grouping structure
@@ -99,6 +112,11 @@ struct cfq_queue {
 	/* fifo list of requests in sort_list */
 	struct list_head fifo;
 
+	/* time when queue got scheduled in to dispatch first request. */
+	unsigned long dispatch_start;
+	unsigned int allocated_slice;
+	/* time when first request from queue completed and slice started. */
+	unsigned long slice_start;
 	unsigned long slice_end;
 	long slice_resid;
 	unsigned int slice_dispatch;
@@ -112,7 +130,70 @@ struct cfq_queue {
 	unsigned short ioprio, org_ioprio;
 	unsigned short ioprio_class, org_ioprio_class;
 
+	unsigned int seek_samples;
+	u64 seek_total;
+	sector_t seek_mean;
+	sector_t last_request_pos;
+
 	pid_t pid;
+
+	struct cfq_rb_root *service_tree;
+	struct cfq_queue *new_cfqq;
+	struct cfq_group *cfqg;
+	struct cfq_group *orig_cfqg;
+	/* Sectors dispatched in current dispatch round */
+	unsigned long nr_sectors;
+};
+
+/*
+ * First index in the service_trees.
+ * IDLE is handled separately, so it has negative index
+ */
+enum wl_prio_t {
+	BE_WORKLOAD = 0,
+	RT_WORKLOAD = 1,
+	IDLE_WORKLOAD = 2,
+};
+
+/*
+ * Second index in the service_trees.
+ */
+enum wl_type_t {
+	ASYNC_WORKLOAD = 0,
+	SYNC_NOIDLE_WORKLOAD = 1,
+	SYNC_WORKLOAD = 2
+};
+
+/* This is per cgroup per device grouping structure */
+struct cfq_group {
+	/* group service_tree member */
+	struct rb_node rb_node;
+
+	/* group service_tree key */
+	u64 vdisktime;
+	unsigned int weight;
+	bool on_st;
+
+	/* number of cfqq currently on this group */
+	int nr_cfqq;
+
+	/* Per group busy queus average. Useful for workload slice calc. */
+	unsigned int busy_queues_avg[2];
+	/*
+	 * rr lists of queues with requests, onle rr for each priority class.
+	 * Counts are embedded in the cfq_rb_root
+	 */
+	struct cfq_rb_root service_trees[2][3];
+	struct cfq_rb_root service_tree_idle;
+
+	unsigned long saved_workload_slice;
+	enum wl_type_t saved_workload;
+	enum wl_prio_t saved_serving_prio;
+	struct blkio_group blkg;
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+	struct hlist_node cfqd_node;
+	atomic_t ref;
+#endif
 };
 
 /*
@@ -120,11 +201,18 @@ struct cfq_queue {
  */
 struct cfq_data {
 	struct request_queue *queue;
+	/* Root service tree for cfq_groups */
+	struct cfq_rb_root grp_service_tree;
+	struct cfq_group root_group;
 
 	/*
-	 * rr list of queues with requests and the count of them
+	 * The priority currently being served
 	 */
-	struct cfq_rb_root service_tree;
+	enum wl_prio_t serving_prio;
+	enum wl_type_t serving_type;
+	unsigned long workload_expires;
+	struct cfq_group *serving_group;
+	bool noidle_tree_requires_idle;
 
 	/*
 	 * Each priority tree is sorted by next_request position.  These
@@ -143,8 +231,14 @@ struct cfq_data {
 	 */
 	int rq_queued;
 	int hw_tag;
-	int hw_tag_samples;
-	int rq_in_driver_peak;
+	/*
+	 * hw_tag can be
+	 * -1 => indeterminate, (cfq will behave as if NCQ is present, to allow better detection)
+	 *  1 => NCQ is present (hw_tag_est_depth is the estimated max depth)
+	 *  0 => no NCQ
+	 */
+	int hw_tag_est_depth;
+	unsigned int hw_tag_samples;
 
 	/*
 	 * idle window management
@@ -174,6 +268,7 @@ struct cfq_data {
 	unsigned int cfq_slice_async_rq;
 	unsigned int cfq_slice_idle;
 	unsigned int cfq_latency;
+	unsigned int cfq_group_isolation;
 
 	struct list_head cic_list;
 
@@ -182,9 +277,28 @@ struct cfq_data {
 	 */
 	struct cfq_queue oom_cfqq;
 
-	unsigned long last_end_sync_rq;
+	unsigned long last_delayed_sync;
+
+	/* List of cfq groups being managed on this device*/
+	struct hlist_head cfqg_list;
+	struct rcu_head rcu;
 };
 
+static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd);
+
+static struct cfq_rb_root *service_tree_for(struct cfq_group *cfqg,
+					    enum wl_prio_t prio,
+					    enum wl_type_t type)
+{
+	if (!cfqg)
+		return NULL;
+
+	if (prio == IDLE_WORKLOAD)
+		return &cfqg->service_tree_idle;
+
+	return &cfqg->service_trees[prio][type];
+}
+
 enum cfqq_state_flags {
 	CFQ_CFQQ_FLAG_on_rr = 0,	/* on round-robin busy list */
 	CFQ_CFQQ_FLAG_wait_request,	/* waiting for a request */
@@ -195,8 +309,10 @@ enum cfqq_state_flags {
 	CFQ_CFQQ_FLAG_prio_changed,	/* task priority has changed */
 	CFQ_CFQQ_FLAG_slice_new,	/* no requests dispatched in slice */
 	CFQ_CFQQ_FLAG_sync,		/* synchronous queue */
-	CFQ_CFQQ_FLAG_coop,		/* has done a coop jump of the queue */
-	CFQ_CFQQ_FLAG_coop_preempt,	/* coop preempt */
+	CFQ_CFQQ_FLAG_coop,		/* cfqq is shared */
+	CFQ_CFQQ_FLAG_split_coop,	/* shared cfqq will be splitted */
+	CFQ_CFQQ_FLAG_deep,		/* sync cfqq experienced large depth */
+	CFQ_CFQQ_FLAG_wait_busy,	/* Waiting for next request */
 };
 
 #define CFQ_CFQQ_FNS(name)						\
@@ -223,14 +339,78 @@ CFQ_CFQQ_FNS(prio_changed);
 CFQ_CFQQ_FNS(slice_new);
 CFQ_CFQQ_FNS(sync);
 CFQ_CFQQ_FNS(coop);
-CFQ_CFQQ_FNS(coop_preempt);
+CFQ_CFQQ_FNS(split_coop);
+CFQ_CFQQ_FNS(deep);
+CFQ_CFQQ_FNS(wait_busy);
 #undef CFQ_CFQQ_FNS
 
+#ifdef CONFIG_DEBUG_CFQ_IOSCHED
+#define cfq_log_cfqq(cfqd, cfqq, fmt, args...)	\
+	blk_add_trace_msg((cfqd)->queue, "cfq%d%c %s " fmt, (cfqq)->pid, \
+			cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
+			blkg_path(&(cfqq)->cfqg->blkg), ##args);
+
+#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)				\
+	blk_add_trace_msg((cfqd)->queue, "%s " fmt,			\
+				blkg_path(&(cfqg)->blkg), ##args);      \
+
+#else
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...)	\
 	blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args)
+#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)		do {} while (0);
+#endif
 #define cfq_log(cfqd, fmt, args...)	\
 	blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
 
+/* Traverses through cfq group service trees */
+#define for_each_cfqg_st(cfqg, i, j, st) \
+	for (i = 0; i <= IDLE_WORKLOAD; i++) \
+		for (j = 0, st = i < IDLE_WORKLOAD ? &cfqg->service_trees[i][j]\
+			: &cfqg->service_tree_idle; \
+			(i < IDLE_WORKLOAD && j <= SYNC_WORKLOAD) || \
+			(i == IDLE_WORKLOAD && j == 0); \
+			j++, st = i < IDLE_WORKLOAD ? \
+			&cfqg->service_trees[i][j]: NULL) \
+
+
+static inline enum wl_prio_t cfqq_prio(struct cfq_queue *cfqq)
+{
+	if (cfq_class_idle(cfqq))
+		return IDLE_WORKLOAD;
+	if (cfq_class_rt(cfqq))
+		return RT_WORKLOAD;
+	return BE_WORKLOAD;
+}
+
+
+static enum wl_type_t cfqq_type(struct cfq_queue *cfqq)
+{
+	if (!cfq_cfqq_sync(cfqq))
+		return ASYNC_WORKLOAD;
+	if (!cfq_cfqq_idle_window(cfqq))
+		return SYNC_NOIDLE_WORKLOAD;
+	return SYNC_WORKLOAD;
+}
+
+static inline int cfq_group_busy_queues_wl(enum wl_prio_t wl,
+					struct cfq_data *cfqd,
+					struct cfq_group *cfqg)
+{
+	if (wl == IDLE_WORKLOAD)
+		return cfqg->service_tree_idle.count;
+
+	return cfqg->service_trees[wl][ASYNC_WORKLOAD].count
+		+ cfqg->service_trees[wl][SYNC_NOIDLE_WORKLOAD].count
+		+ cfqg->service_trees[wl][SYNC_WORKLOAD].count;
+}
+
+static inline int cfqg_busy_async_queues(struct cfq_data *cfqd,
+					struct cfq_group *cfqg)
+{
+	return cfqg->service_trees[RT_WORKLOAD][ASYNC_WORKLOAD].count
+		+ cfqg->service_trees[BE_WORKLOAD][ASYNC_WORKLOAD].count;
+}
+
 static void cfq_dispatch_insert(struct request_queue *, struct request *);
 static struct cfq_queue *cfq_get_queue(struct cfq_data *, bool,
 				       struct io_context *, gfp_t);
@@ -279,7 +459,7 @@ static int cfq_queue_empty(struct reques
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 
-	return !cfqd->busy_queues;
+	return !cfqd->rq_queued;
 }
 
 /*
@@ -303,10 +483,110 @@ cfq_prio_to_slice(struct cfq_data *cfqd,
 	return cfq_prio_slice(cfqd, cfq_cfqq_sync(cfqq), cfqq->ioprio);
 }
 
+static inline u64 cfq_scale_slice(unsigned long delta, struct cfq_group *cfqg)
+{
+	u64 d = delta << CFQ_SERVICE_SHIFT;
+
+	d = d * BLKIO_WEIGHT_DEFAULT;
+	do_div(d, cfqg->weight);
+	return d;
+}
+
+static inline u64 max_vdisktime(u64 min_vdisktime, u64 vdisktime)
+{
+	s64 delta = (s64)(vdisktime - min_vdisktime);
+	if (delta > 0)
+		min_vdisktime = vdisktime;
+
+	return min_vdisktime;
+}
+
+static inline u64 min_vdisktime(u64 min_vdisktime, u64 vdisktime)
+{
+	s64 delta = (s64)(vdisktime - min_vdisktime);
+	if (delta < 0)
+		min_vdisktime = vdisktime;
+
+	return min_vdisktime;
+}
+
+static void update_min_vdisktime(struct cfq_rb_root *st)
+{
+	u64 vdisktime = st->min_vdisktime;
+	struct cfq_group *cfqg;
+
+	if (st->active) {
+		cfqg = rb_entry_cfqg(st->active);
+		vdisktime = cfqg->vdisktime;
+	}
+
+	if (st->left) {
+		cfqg = rb_entry_cfqg(st->left);
+		vdisktime = min_vdisktime(vdisktime, cfqg->vdisktime);
+	}
+
+	st->min_vdisktime = max_vdisktime(st->min_vdisktime, vdisktime);
+}
+
+/*
+ * get averaged number of queues of RT/BE priority.
+ * average is updated, with a formula that gives more weight to higher numbers,
+ * to quickly follows sudden increases and decrease slowly
+ */
+
+static inline unsigned cfq_group_get_avg_queues(struct cfq_data *cfqd,
+					struct cfq_group *cfqg, bool rt)
+{
+	unsigned min_q, max_q;
+	unsigned mult  = cfq_hist_divisor - 1;
+	unsigned round = cfq_hist_divisor / 2;
+	unsigned busy = cfq_group_busy_queues_wl(rt, cfqd, cfqg);
+
+	min_q = min(cfqg->busy_queues_avg[rt], busy);
+	max_q = max(cfqg->busy_queues_avg[rt], busy);
+	cfqg->busy_queues_avg[rt] = (mult * max_q + min_q + round) /
+		cfq_hist_divisor;
+	return cfqg->busy_queues_avg[rt];
+}
+
+static inline unsigned
+cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg)
+{
+	struct cfq_rb_root *st = &cfqd->grp_service_tree;
+
+	return cfq_target_latency * cfqg->weight / st->total_weight;
+}
+
 static inline void
 cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
-	cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies;
+	unsigned slice = cfq_prio_to_slice(cfqd, cfqq);
+	if (cfqd->cfq_latency) {
+		/*
+		 * interested queues (we consider only the ones with the same
+		 * priority class in the cfq group)
+		 */
+		unsigned iq = cfq_group_get_avg_queues(cfqd, cfqq->cfqg,
+						cfq_class_rt(cfqq));
+		unsigned sync_slice = cfqd->cfq_slice[1];
+		unsigned expect_latency = sync_slice * iq;
+		unsigned group_slice = cfq_group_slice(cfqd, cfqq->cfqg);
+
+		if (expect_latency > group_slice) {
+			unsigned base_low_slice = 2 * cfqd->cfq_slice_idle;
+			/* scale low_slice according to IO priority
+			 * and sync vs async */
+			unsigned low_slice =
+				min(slice, base_low_slice * slice / sync_slice);
+			/* the adapted slice value is scaled to fit all iqs
+			 * into the target latency */
+			slice = max(slice * group_slice / expect_latency,
+				    low_slice);
+		}
+	}
+	cfqq->slice_start = jiffies;
+	cfqq->slice_end = jiffies + slice;
+	cfqq->allocated_slice = slice;
 	cfq_log_cfqq(cfqd, cfqq, "set_slice=%lu", cfqq->slice_end - jiffies);
 }
 
@@ -331,9 +611,9 @@ static inline bool cfq_slice_used(struct
  * behind the head is penalized and only allowed to a certain extent.
  */
 static struct request *
-cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2)
+cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2, sector_t last)
 {
-	sector_t last, s1, s2, d1 = 0, d2 = 0;
+	sector_t s1, s2, d1 = 0, d2 = 0;
 	unsigned long back_max;
 #define CFQ_RQ1_WRAP	0x01 /* request 1 wraps */
 #define CFQ_RQ2_WRAP	0x02 /* request 2 wraps */
@@ -356,8 +636,6 @@ cfq_choose_req(struct cfq_data *cfqd, st
 	s1 = blk_rq_pos(rq1);
 	s2 = blk_rq_pos(rq2);
 
-	last = cfqd->last_position;
-
 	/*
 	 * by definition, 1KiB is 2 sectors
 	 */
@@ -425,6 +703,10 @@ cfq_choose_req(struct cfq_data *cfqd, st
  */
 static struct cfq_queue *cfq_rb_first(struct cfq_rb_root *root)
 {
+	/* Service tree is empty */
+	if (!root->count)
+		return NULL;
+
 	if (!root->left)
 		root->left = rb_first(&root->rb);
 
@@ -434,6 +716,17 @@ static struct cfq_queue *cfq_rb_first(st
 	return NULL;
 }
 
+static struct cfq_group *cfq_rb_first_group(struct cfq_rb_root *root)
+{
+	if (!root->left)
+		root->left = rb_first(&root->rb);
+
+	if (root->left)
+		return rb_entry_cfqg(root->left);
+
+	return NULL;
+}
+
 static void rb_erase_init(struct rb_node *n, struct rb_root *root)
 {
 	rb_erase(n, root);
@@ -445,6 +738,7 @@ static void cfq_rb_erase(struct rb_node
 	if (root->left == n)
 		root->left = NULL;
 	rb_erase_init(n, &root->rb);
+	--root->count;
 }
 
 /*
@@ -471,7 +765,7 @@ cfq_find_next_rq(struct cfq_data *cfqd,
 			next = rb_entry_rq(rbnext);
 	}
 
-	return cfq_choose_req(cfqd, next, prev);
+	return cfq_choose_req(cfqd, next, prev, blk_rq_pos(last));
 }
 
 static unsigned long cfq_slice_offset(struct cfq_data *cfqd,
@@ -480,12 +774,334 @@ static unsigned long cfq_slice_offset(st
 	/*
 	 * just an approximation, should be ok.
 	 */
-	return (cfqd->busy_queues - 1) * (cfq_prio_slice(cfqd, 1, 0) -
+	return (cfqq->cfqg->nr_cfqq - 1) * (cfq_prio_slice(cfqd, 1, 0) -
 		       cfq_prio_slice(cfqd, cfq_cfqq_sync(cfqq), cfqq->ioprio));
 }
 
+static inline s64
+cfqg_key(struct cfq_rb_root *st, struct cfq_group *cfqg)
+{
+	return cfqg->vdisktime - st->min_vdisktime;
+}
+
+static void
+__cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg)
+{
+	struct rb_node **node = &st->rb.rb_node;
+	struct rb_node *parent = NULL;
+	struct cfq_group *__cfqg;
+	s64 key = cfqg_key(st, cfqg);
+	int left = 1;
+
+	while (*node != NULL) {
+		parent = *node;
+		__cfqg = rb_entry_cfqg(parent);
+
+		if (key < cfqg_key(st, __cfqg))
+			node = &parent->rb_left;
+		else {
+			node = &parent->rb_right;
+			left = 0;
+		}
+	}
+
+	if (left)
+		st->left = &cfqg->rb_node;
+
+	rb_link_node(&cfqg->rb_node, parent, node);
+	rb_insert_color(&cfqg->rb_node, &st->rb);
+}
+
+static void
+cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
+{
+	struct cfq_rb_root *st = &cfqd->grp_service_tree;
+	struct cfq_group *__cfqg;
+	struct rb_node *n;
+
+	cfqg->nr_cfqq++;
+	if (cfqg->on_st)
+		return;
+
+	/*
+	 * Currently put the group at the end. Later implement something
+	 * so that groups get lesser vtime based on their weights, so that
+	 * if group does not loose all if it was not continously backlogged.
+	 */
+	n = rb_last(&st->rb);
+	if (n) {
+		__cfqg = rb_entry_cfqg(n);
+		cfqg->vdisktime = __cfqg->vdisktime + CFQ_IDLE_DELAY;
+	} else
+		cfqg->vdisktime = st->min_vdisktime;
+
+	__cfq_group_service_tree_add(st, cfqg);
+	cfqg->on_st = true;
+	st->total_weight += cfqg->weight;
+}
+
+static void
+cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg)
+{
+	struct cfq_rb_root *st = &cfqd->grp_service_tree;
+
+	if (st->active == &cfqg->rb_node)
+		st->active = NULL;
+
+	BUG_ON(cfqg->nr_cfqq < 1);
+	cfqg->nr_cfqq--;
+
+	/* If there are other cfq queues under this group, don't delete it */
+	if (cfqg->nr_cfqq)
+		return;
+
+	cfq_log_cfqg(cfqd, cfqg, "del_from_rr group");
+	cfqg->on_st = false;
+	st->total_weight -= cfqg->weight;
+	if (!RB_EMPTY_NODE(&cfqg->rb_node))
+		cfq_rb_erase(&cfqg->rb_node, st);
+	cfqg->saved_workload_slice = 0;
+	blkiocg_update_blkio_group_dequeue_stats(&cfqg->blkg, 1);
+}
+
+static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq)
+{
+	unsigned int slice_used;
+
+	/*
+	 * Queue got expired before even a single request completed or
+	 * got expired immediately after first request completion.
+	 */
+	if (!cfqq->slice_start || cfqq->slice_start == jiffies) {
+		/*
+		 * Also charge the seek time incurred to the group, otherwise
+		 * if there are mutiple queues in the group, each can dispatch
+		 * a single request on seeky media and cause lots of seek time
+		 * and group will never know it.
+		 */
+		slice_used = max_t(unsigned, (jiffies - cfqq->dispatch_start),
+					1);
+	} else {
+		slice_used = jiffies - cfqq->slice_start;
+		if (slice_used > cfqq->allocated_slice)
+			slice_used = cfqq->allocated_slice;
+	}
+
+	cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u sect=%lu", slice_used,
+				cfqq->nr_sectors);
+	return slice_used;
+}
+
+static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
+				struct cfq_queue *cfqq)
+{
+	struct cfq_rb_root *st = &cfqd->grp_service_tree;
+	unsigned int used_sl, charge_sl;
+	int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg)
+			- cfqg->service_tree_idle.count;
+
+	BUG_ON(nr_sync < 0);
+	used_sl = charge_sl = cfq_cfqq_slice_usage(cfqq);
+
+	if (!cfq_cfqq_sync(cfqq) && !nr_sync)
+		charge_sl = cfqq->allocated_slice;
+
+	/* Can't update vdisktime while group is on service tree */
+	cfq_rb_erase(&cfqg->rb_node, st);
+	cfqg->vdisktime += cfq_scale_slice(charge_sl, cfqg);
+	__cfq_group_service_tree_add(st, cfqg);
+
+	/* This group is being expired. Save the context */
+	if (time_after(cfqd->workload_expires, jiffies)) {
+		cfqg->saved_workload_slice = cfqd->workload_expires
+						- jiffies;
+		cfqg->saved_workload = cfqd->serving_type;
+		cfqg->saved_serving_prio = cfqd->serving_prio;
+	} else
+		cfqg->saved_workload_slice = 0;
+
+	cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime,
+					st->min_vdisktime);
+	blkiocg_update_blkio_group_stats(&cfqg->blkg, used_sl,
+						cfqq->nr_sectors);
+}
+
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+static inline struct cfq_group *cfqg_of_blkg(struct blkio_group *blkg)
+{
+	if (blkg)
+		return container_of(blkg, struct cfq_group, blkg);
+	return NULL;
+}
+
+void
+cfq_update_blkio_group_weight(struct blkio_group *blkg, unsigned int weight)
+{
+	cfqg_of_blkg(blkg)->weight = weight;
+}
+
+static struct cfq_group *
+cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
+{
+	struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
+	struct cfq_group *cfqg = NULL;
+	void *key = cfqd;
+	int i, j;
+	struct cfq_rb_root *st;
+	struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info;
+	unsigned int major, minor;
+
+	/* Do we need to take this reference */
+	if (!blkiocg_css_tryget(blkcg))
+		return NULL;;
+
+	cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
+	if (cfqg || !create)
+		goto done;
+
+	cfqg = kzalloc_node(sizeof(*cfqg), GFP_ATOMIC, cfqd->queue->node);
+	if (!cfqg)
+		goto done;
+
+	cfqg->weight = blkcg->weight;
+	for_each_cfqg_st(cfqg, i, j, st)
+		*st = CFQ_RB_ROOT;
+	RB_CLEAR_NODE(&cfqg->rb_node);
+
+	/*
+	 * Take the initial reference that will be released on destroy
+	 * This can be thought of a joint reference by cgroup and
+	 * elevator which will be dropped by either elevator exit
+	 * or cgroup deletion path depending on who is exiting first.
+	 */
+	atomic_set(&cfqg->ref, 1);
+
+	/* Add group onto cgroup list */
+	sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+	blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
+					MKDEV(major, minor));
+
+	/* Add group on cfqd list */
+	hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
+
+done:
+	blkiocg_css_put(blkcg);
+	return cfqg;
+}
+
 /*
- * The cfqd->service_tree holds all pending cfq_queue's that have
+ * Search for the cfq group current task belongs to. If create = 1, then also
+ * create the cfq group if it does not exist. request_queue lock must be held.
+ */
+static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
+{
+	struct cgroup *cgroup;
+	struct cfq_group *cfqg = NULL;
+
+	rcu_read_lock();
+	cgroup = task_cgroup(current, blkio_subsys_id);
+	cfqg = cfq_find_alloc_cfqg(cfqd, cgroup, create);
+	if (!cfqg && create)
+		cfqg = &cfqd->root_group;
+	rcu_read_unlock();
+	return cfqg;
+}
+
+static void cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg)
+{
+	/* Currently, all async queues are mapped to root group */
+	if (!cfq_cfqq_sync(cfqq))
+		cfqg = &cfqq->cfqd->root_group;
+
+	cfqq->cfqg = cfqg;
+	/* cfqq reference on cfqg */
+	atomic_inc(&cfqq->cfqg->ref);
+}
+
+static void cfq_put_cfqg(struct cfq_group *cfqg)
+{
+	struct cfq_rb_root *st;
+	int i, j;
+
+	BUG_ON(atomic_read(&cfqg->ref) <= 0);
+	if (!atomic_dec_and_test(&cfqg->ref))
+		return;
+	for_each_cfqg_st(cfqg, i, j, st)
+		BUG_ON(!RB_EMPTY_ROOT(&st->rb) || st->active != NULL);
+	kfree(cfqg);
+}
+
+static void cfq_destroy_cfqg(struct cfq_data *cfqd, struct cfq_group *cfqg)
+{
+	/* Something wrong if we are trying to remove same group twice */
+	BUG_ON(hlist_unhashed(&cfqg->cfqd_node));
+
+	hlist_del_init(&cfqg->cfqd_node);
+
+	/*
+	 * Put the reference taken at the time of creation so that when all
+	 * queues are gone, group can be destroyed.
+	 */
+	cfq_put_cfqg(cfqg);
+}
+
+static void cfq_release_cfq_groups(struct cfq_data *cfqd)
+{
+	struct hlist_node *pos, *n;
+	struct cfq_group *cfqg;
+
+	hlist_for_each_entry_safe(cfqg, pos, n, &cfqd->cfqg_list, cfqd_node) {
+		/*
+		 * If cgroup removal path got to blk_group first and removed
+		 * it from cgroup list, then it will take care of destroying
+		 * cfqg also.
+		 */
+		if (!blkiocg_del_blkio_group(&cfqg->blkg))
+			cfq_destroy_cfqg(cfqd, cfqg);
+	}
+}
+
+/*
+ * Blk cgroup controller notification saying that blkio_group object is being
+ * delinked as associated cgroup object is going away. That also means that
+ * no new IO will come in this group. So get rid of this group as soon as
+ * any pending IO in the group is finished.
+ *
+ * This function is called under rcu_read_lock(). key is the rcu protected
+ * pointer. That means "key" is a valid cfq_data pointer as long as we are rcu
+ * read lock.
+ *
+ * "key" was fetched from blkio_group under blkio_cgroup->lock. That means
+ * it should not be NULL as even if elevator was exiting, cgroup deltion
+ * path got to it first.
+ */
+void cfq_unlink_blkio_group(void *key, struct blkio_group *blkg)
+{
+	unsigned long  flags;
+	struct cfq_data *cfqd = key;
+
+	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
+	cfq_destroy_cfqg(cfqd, cfqg_of_blkg(blkg));
+	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
+}
+
+#else /* GROUP_IOSCHED */
+static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
+{
+	return &cfqd->root_group;
+}
+static inline void
+cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg) {
+	cfqq->cfqg = cfqg;
+}
+
+static void cfq_release_cfq_groups(struct cfq_data *cfqd) {}
+static inline void cfq_put_cfqg(struct cfq_group *cfqg) {}
+
+#endif /* GROUP_IOSCHED */
+
+/*
+ * The cfqd->service_trees holds all pending cfq_queue's that have
  * requests waiting to be processed. It is sorted in the order that
  * we will service the queues.
  */
@@ -495,11 +1111,42 @@ static void cfq_service_tree_add(struct
 	struct rb_node **p, *parent;
 	struct cfq_queue *__cfqq;
 	unsigned long rb_key;
+	struct cfq_rb_root *service_tree;
 	int left;
+	int new_cfqq = 1;
+	int group_changed = 0;
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+	if (!cfqd->cfq_group_isolation
+	    && cfqq_type(cfqq) == SYNC_NOIDLE_WORKLOAD
+	    && cfqq->cfqg && cfqq->cfqg != &cfqd->root_group) {
+		/* Move this cfq to root group */
+		cfq_log_cfqq(cfqd, cfqq, "moving to root group");
+		if (!RB_EMPTY_NODE(&cfqq->rb_node))
+			cfq_group_service_tree_del(cfqd, cfqq->cfqg);
+		cfqq->orig_cfqg = cfqq->cfqg;
+		cfqq->cfqg = &cfqd->root_group;
+		atomic_inc(&cfqd->root_group.ref);
+		group_changed = 1;
+	} else if (!cfqd->cfq_group_isolation
+		   && cfqq_type(cfqq) == SYNC_WORKLOAD && cfqq->orig_cfqg) {
+		/* cfqq is sequential now needs to go to its original group */
+		BUG_ON(cfqq->cfqg != &cfqd->root_group);
+		if (!RB_EMPTY_NODE(&cfqq->rb_node))
+			cfq_group_service_tree_del(cfqd, cfqq->cfqg);
+		cfq_put_cfqg(cfqq->cfqg);
+		cfqq->cfqg = cfqq->orig_cfqg;
+		cfqq->orig_cfqg = NULL;
+		group_changed = 1;
+		cfq_log_cfqq(cfqd, cfqq, "moved to origin group");
+	}
+#endif
+
+	service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq),
+						cfqq_type(cfqq));
 	if (cfq_class_idle(cfqq)) {
 		rb_key = CFQ_IDLE_DELAY;
-		parent = rb_last(&cfqd->service_tree.rb);
+		parent = rb_last(&service_tree->rb);
 		if (parent && parent != &cfqq->rb_node) {
 			__cfqq = rb_entry(parent, struct cfq_queue, rb_node);
 			rb_key += __cfqq->rb_key;
@@ -517,23 +1164,27 @@ static void cfq_service_tree_add(struct
 		cfqq->slice_resid = 0;
 	} else {
 		rb_key = -HZ;
-		__cfqq = cfq_rb_first(&cfqd->service_tree);
+		__cfqq = cfq_rb_first(service_tree);
 		rb_key += __cfqq ? __cfqq->rb_key : jiffies;
 	}
 
 	if (!RB_EMPTY_NODE(&cfqq->rb_node)) {
+		new_cfqq = 0;
 		/*
 		 * same position, nothing more to do
 		 */
-		if (rb_key == cfqq->rb_key)
+		if (rb_key == cfqq->rb_key &&
+		    cfqq->service_tree == service_tree)
 			return;
 
-		cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree);
+		cfq_rb_erase(&cfqq->rb_node, cfqq->service_tree);
+		cfqq->service_tree = NULL;
 	}
 
 	left = 1;
 	parent = NULL;
-	p = &cfqd->service_tree.rb.rb_node;
+	cfqq->service_tree = service_tree;
+	p = &service_tree->rb.rb_node;
 	while (*p) {
 		struct rb_node **n;
 
@@ -541,35 +1192,28 @@ static void cfq_service_tree_add(struct
 		__cfqq = rb_entry(parent, struct cfq_queue, rb_node);
 
 		/*
-		 * sort RT queues first, we always want to give
-		 * preference to them. IDLE queues goes to the back.
-		 * after that, sort on the next service time.
+		 * sort by key, that represents service time.
 		 */
-		if (cfq_class_rt(cfqq) > cfq_class_rt(__cfqq))
-			n = &(*p)->rb_left;
-		else if (cfq_class_rt(cfqq) < cfq_class_rt(__cfqq))
-			n = &(*p)->rb_right;
-		else if (cfq_class_idle(cfqq) < cfq_class_idle(__cfqq))
-			n = &(*p)->rb_left;
-		else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq))
-			n = &(*p)->rb_right;
-		else if (time_before(rb_key, __cfqq->rb_key))
+		if (time_before(rb_key, __cfqq->rb_key))
 			n = &(*p)->rb_left;
-		else
+		else {
 			n = &(*p)->rb_right;
-
-		if (n == &(*p)->rb_right)
 			left = 0;
+		}
 
 		p = n;
 	}
 
 	if (left)
-		cfqd->service_tree.left = &cfqq->rb_node;
+		service_tree->left = &cfqq->rb_node;
 
 	cfqq->rb_key = rb_key;
 	rb_link_node(&cfqq->rb_node, parent, p);
-	rb_insert_color(&cfqq->rb_node, &cfqd->service_tree.rb);
+	rb_insert_color(&cfqq->rb_node, &service_tree->rb);
+	service_tree->count++;
+	if ((add_front || !new_cfqq) && !group_changed)
+		return;
+	cfq_group_service_tree_add(cfqd, cfqq->cfqg);
 }
 
 static struct cfq_queue *
@@ -671,13 +1315,16 @@ static void cfq_del_cfqq_rr(struct cfq_d
 	BUG_ON(!cfq_cfqq_on_rr(cfqq));
 	cfq_clear_cfqq_on_rr(cfqq);
 
-	if (!RB_EMPTY_NODE(&cfqq->rb_node))
-		cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree);
+	if (!RB_EMPTY_NODE(&cfqq->rb_node)) {
+		cfq_rb_erase(&cfqq->rb_node, cfqq->service_tree);
+		cfqq->service_tree = NULL;
+	}
 	if (cfqq->p_root) {
 		rb_erase(&cfqq->p_node, cfqq->p_root);
 		cfqq->p_root = NULL;
 	}
 
+	cfq_group_service_tree_del(cfqd, cfqq->cfqg);
 	BUG_ON(!cfqd->busy_queues);
 	cfqd->busy_queues--;
 }
@@ -688,7 +1335,6 @@ static void cfq_del_cfqq_rr(struct cfq_d
 static void cfq_del_rq_rb(struct request *rq)
 {
 	struct cfq_queue *cfqq = RQ_CFQQ(rq);
-	struct cfq_data *cfqd = cfqq->cfqd;
 	const int sync = rq_is_sync(rq);
 
 	BUG_ON(!cfqq->queued[sync]);
@@ -696,8 +1342,17 @@ static void cfq_del_rq_rb(struct request
 
 	elv_rb_del(&cfqq->sort_list, rq);
 
-	if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list))
-		cfq_del_cfqq_rr(cfqd, cfqq);
+	if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) {
+		/*
+		 * Queue will be deleted from service tree when we actually
+		 * expire it later. Right now just remove it from prio tree
+		 * as it is empty.
+		 */
+		if (cfqq->p_root) {
+			rb_erase(&cfqq->p_node, cfqq->p_root);
+			cfqq->p_root = NULL;
+		}
+	}
 }
 
 static void cfq_add_rq_rb(struct request *rq)
@@ -722,7 +1377,7 @@ static void cfq_add_rq_rb(struct request
 	 * check if this request is a better next-serve candidate
 	 */
 	prev = cfqq->next_rq;
-	cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
+	cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq, cfqd->last_position);
 
 	/*
 	 * adjust priority tree position, if ->next_rq changes
@@ -829,6 +1484,7 @@ static void
 cfq_merged_requests(struct request_queue *q, struct request *rq,
 		    struct request *next)
 {
+	struct cfq_queue *cfqq = RQ_CFQQ(rq);
 	/*
 	 * reposition in fifo if next is older than rq
 	 */
@@ -838,6 +1494,8 @@ cfq_merged_requests(struct request_queue
 		rq_set_fifo_time(rq, rq_fifo_time(next));
 	}
 
+	if (cfqq->next_rq == next)
+		cfqq->next_rq = rq;
 	cfq_remove_request(next);
 }
 
@@ -871,8 +1529,12 @@ static void __cfq_set_active_queue(struc
 {
 	if (cfqq) {
 		cfq_log_cfqq(cfqd, cfqq, "set_active");
+		cfqq->slice_start = 0;
+		cfqq->dispatch_start = jiffies;
+		cfqq->allocated_slice = 0;
 		cfqq->slice_end = 0;
 		cfqq->slice_dispatch = 0;
+		cfqq->nr_sectors = 0;
 
 		cfq_clear_cfqq_wait_request(cfqq);
 		cfq_clear_cfqq_must_dispatch(cfqq);
@@ -899,6 +1561,16 @@ __cfq_slice_expired(struct cfq_data *cfq
 		del_timer(&cfqd->idle_slice_timer);
 
 	cfq_clear_cfqq_wait_request(cfqq);
+	cfq_clear_cfqq_wait_busy(cfqq);
+
+	/*
+	 * If this cfqq is shared between multiple processes, check to
+	 * make sure that those processes are still issuing I/Os within
+	 * the mean seek distance.  If not, it may be time to break the
+	 * queues apart again.
+	 */
+	if (cfq_cfqq_coop(cfqq) && CFQQ_SEEKY(cfqq))
+		cfq_mark_cfqq_split_coop(cfqq);
 
 	/*
 	 * store what was left of this slice, if the queue idled/timed out
@@ -908,11 +1580,19 @@ __cfq_slice_expired(struct cfq_data *cfq
 		cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid);
 	}
 
+	cfq_group_served(cfqd, cfqq->cfqg, cfqq);
+
+	if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list))
+		cfq_del_cfqq_rr(cfqd, cfqq);
+
 	cfq_resort_rr_list(cfqd, cfqq);
 
 	if (cfqq == cfqd->active_queue)
 		cfqd->active_queue = NULL;
 
+	if (&cfqq->cfqg->rb_node == cfqd->grp_service_tree.active)
+		cfqd->grp_service_tree.active = NULL;
+
 	if (cfqd->active_cic) {
 		put_io_context(cfqd->active_cic->ioc);
 		cfqd->active_cic = NULL;
@@ -933,10 +1613,39 @@ static inline void cfq_slice_expired(str
  */
 static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
 {
-	if (RB_EMPTY_ROOT(&cfqd->service_tree.rb))
+	struct cfq_rb_root *service_tree =
+		service_tree_for(cfqd->serving_group, cfqd->serving_prio,
+					cfqd->serving_type);
+
+	if (!cfqd->rq_queued)
 		return NULL;
 
-	return cfq_rb_first(&cfqd->service_tree);
+	/* There is nothing to dispatch */
+	if (!service_tree)
+		return NULL;
+	if (RB_EMPTY_ROOT(&service_tree->rb))
+		return NULL;
+	return cfq_rb_first(service_tree);
+}
+
+static struct cfq_queue *cfq_get_next_queue_forced(struct cfq_data *cfqd)
+{
+	struct cfq_group *cfqg;
+	struct cfq_queue *cfqq;
+	int i, j;
+	struct cfq_rb_root *st;
+
+	if (!cfqd->rq_queued)
+		return NULL;
+
+	cfqg = cfq_get_next_cfqg(cfqd);
+	if (!cfqg)
+		return NULL;
+
+	for_each_cfqg_st(cfqg, i, j, st)
+		if ((cfqq = cfq_rb_first(st)) != NULL)
+			return cfqq;
+	return NULL;
 }
 
 /*
@@ -945,14 +1654,8 @@ static struct cfq_queue *cfq_get_next_qu
 static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
 					      struct cfq_queue *cfqq)
 {
-	if (!cfqq) {
+	if (!cfqq)
 		cfqq = cfq_get_next_queue(cfqd);
-		if (cfqq && !cfq_cfqq_coop_preempt(cfqq))
-			cfq_clear_cfqq_coop(cfqq);
-	}
-
-	if (cfqq)
-		cfq_clear_cfqq_coop_preempt(cfqq);
 
 	__cfq_set_active_queue(cfqd, cfqq);
 	return cfqq;
@@ -967,16 +1670,17 @@ static inline sector_t cfq_dist_from_las
 		return cfqd->last_position - blk_rq_pos(rq);
 }
 
-#define CIC_SEEK_THR	8 * 1024
-#define CIC_SEEKY(cic)	((cic)->seek_mean > CIC_SEEK_THR)
-
-static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq)
+static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+			       struct request *rq, bool for_preempt)
 {
-	struct cfq_io_context *cic = cfqd->active_cic;
-	sector_t sdist = cic->seek_mean;
+	sector_t sdist = cfqq->seek_mean;
 
-	if (!sample_valid(cic->seek_samples))
-		sdist = CIC_SEEK_THR;
+	if (!sample_valid(cfqq->seek_samples))
+		sdist = CFQQ_SEEK_THR;
+
+	/* if seek_mean is big, using it as close criteria is meaningless */
+	if (sdist > CFQQ_SEEK_THR && !for_preempt)
+		sdist = CFQQ_SEEK_THR;
 
 	return cfq_dist_from_last(cfqd, rq) <= sdist;
 }
@@ -1005,7 +1709,7 @@ static struct cfq_queue *cfqq_close(stru
 	 * will contain the closest sector.
 	 */
 	__cfqq = rb_entry(parent, struct cfq_queue, p_node);
-	if (cfq_rq_close(cfqd, __cfqq->next_rq))
+	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
 		return __cfqq;
 
 	if (blk_rq_pos(__cfqq->next_rq) < sector)
@@ -1016,7 +1720,7 @@ static struct cfq_queue *cfqq_close(stru
 		return NULL;
 
 	__cfqq = rb_entry(node, struct cfq_queue, p_node);
-	if (cfq_rq_close(cfqd, __cfqq->next_rq))
+	if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
 		return __cfqq;
 
 	return NULL;
@@ -1033,16 +1737,19 @@ static struct cfq_queue *cfqq_close(stru
  * assumption.
  */
 static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
-					      struct cfq_queue *cur_cfqq,
-					      bool probe)
+					      struct cfq_queue *cur_cfqq)
 {
 	struct cfq_queue *cfqq;
 
+	if (!cfq_cfqq_sync(cur_cfqq))
+		return NULL;
+	if (CFQQ_SEEKY(cur_cfqq))
+		return NULL;
+
 	/*
-	 * A valid cfq_io_context is necessary to compare requests against
-	 * the seek_mean of the current cfqq.
+	 * Don't search priority tree if it's the only queue in the group.
 	 */
-	if (!cfqd->active_cic)
+	if (cur_cfqq->cfqg->nr_cfqq == 1)
 		return NULL;
 
 	/*
@@ -1054,14 +1761,55 @@ static struct cfq_queue *cfq_close_coope
 	if (!cfqq)
 		return NULL;
 
-	if (cfq_cfqq_coop(cfqq))
+	/* If new queue belongs to different cfq_group, don't choose it */
+	if (cur_cfqq->cfqg != cfqq->cfqg)
+		return NULL;
+
+	/*
+	 * It only makes sense to merge sync queues.
+	 */
+	if (!cfq_cfqq_sync(cfqq))
+		return NULL;
+	if (CFQQ_SEEKY(cfqq))
+		return NULL;
+
+	/*
+	 * Do not merge queues of different priority classes
+	 */
+	if (cfq_class_rt(cfqq) != cfq_class_rt(cur_cfqq))
 		return NULL;
 
-	if (!probe)
-		cfq_mark_cfqq_coop(cfqq);
 	return cfqq;
 }
 
+/*
+ * Determine whether we should enforce idle window for this queue.
+ */
+
+static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	enum wl_prio_t prio = cfqq_prio(cfqq);
+	struct cfq_rb_root *service_tree = cfqq->service_tree;
+
+	BUG_ON(!service_tree);
+	BUG_ON(!service_tree->count);
+
+	/* We never do for idle class queues. */
+	if (prio == IDLE_WORKLOAD)
+		return false;
+
+	/* We do for queues that were marked with idle window flag. */
+	if (cfq_cfqq_idle_window(cfqq) &&
+	   !(blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag))
+		return true;
+
+	/*
+	 * Otherwise, we do only if they are the last ones
+	 * in their service tree.
+	 */
+	return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
+}
+
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 {
 	struct cfq_queue *cfqq = cfqd->active_queue;
@@ -1082,13 +1830,13 @@ static void cfq_arm_slice_timer(struct c
 	/*
 	 * idle is disabled, either manually or by past process history
 	 */
-	if (!cfqd->cfq_slice_idle || !cfq_cfqq_idle_window(cfqq))
+	if (!cfqd->cfq_slice_idle || !cfq_should_idle(cfqd, cfqq))
 		return;
 
 	/*
-	 * still requests with the driver, don't idle
+	 * still active requests from this queue, don't idle
 	 */
-	if (rq_in_driver(cfqd))
+	if (cfqq->dispatched)
 		return;
 
 	/*
@@ -1109,14 +1857,7 @@ static void cfq_arm_slice_timer(struct c
 
 	cfq_mark_cfqq_wait_request(cfqq);
 
-	/*
-	 * we don't want to idle for seeks, but we do want to allow
-	 * fair distribution of slice time for a process doing back-to-back
-	 * seeks. so allow a little bit of time for him to submit a new rq
-	 */
 	sl = cfqd->cfq_slice_idle;
-	if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
-		sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT));
 
 	mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
 	cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl);
@@ -1139,6 +1880,7 @@ static void cfq_dispatch_insert(struct r
 
 	if (cfq_cfqq_sync(cfqq))
 		cfqd->sync_flight++;
+	cfqq->nr_sectors += blk_rq_sectors(rq);
 }
 
 /*
@@ -1175,6 +1917,186 @@ cfq_prio_to_maxrq(struct cfq_data *cfqd,
 }
 
 /*
+ * Must be called with the queue_lock held.
+ */
+static int cfqq_process_refs(struct cfq_queue *cfqq)
+{
+	int process_refs, io_refs;
+
+	io_refs = cfqq->allocated[READ] + cfqq->allocated[WRITE];
+	process_refs = atomic_read(&cfqq->ref) - io_refs;
+	BUG_ON(process_refs < 0);
+	return process_refs;
+}
+
+static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq)
+{
+	int process_refs, new_process_refs;
+	struct cfq_queue *__cfqq;
+
+	/* Avoid a circular list and skip interim queue merges */
+	while ((__cfqq = new_cfqq->new_cfqq)) {
+		if (__cfqq == cfqq)
+			return;
+		new_cfqq = __cfqq;
+	}
+
+	process_refs = cfqq_process_refs(cfqq);
+	/*
+	 * If the process for the cfqq has gone away, there is no
+	 * sense in merging the queues.
+	 */
+	if (process_refs == 0)
+		return;
+
+	/*
+	 * Merge in the direction of the lesser amount of work.
+	 */
+	new_process_refs = cfqq_process_refs(new_cfqq);
+	if (new_process_refs >= process_refs) {
+		cfqq->new_cfqq = new_cfqq;
+		atomic_add(process_refs, &new_cfqq->ref);
+	} else {
+		new_cfqq->new_cfqq = cfqq;
+		atomic_add(new_process_refs, &cfqq->ref);
+	}
+}
+
+static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd,
+				struct cfq_group *cfqg, enum wl_prio_t prio)
+{
+	struct cfq_queue *queue;
+	int i;
+	bool key_valid = false;
+	unsigned long lowest_key = 0;
+	enum wl_type_t cur_best = SYNC_NOIDLE_WORKLOAD;
+
+	for (i = 0; i <= SYNC_WORKLOAD; ++i) {
+		/* select the one with lowest rb_key */
+		queue = cfq_rb_first(service_tree_for(cfqg, prio, i));
+		if (queue &&
+		    (!key_valid || time_before(queue->rb_key, lowest_key))) {
+			lowest_key = queue->rb_key;
+			cur_best = i;
+			key_valid = true;
+		}
+	}
+
+	return cur_best;
+}
+
+static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
+{
+	unsigned slice;
+	unsigned count;
+	struct cfq_rb_root *st;
+	unsigned group_slice;
+
+	if (!cfqg) {
+		cfqd->serving_prio = IDLE_WORKLOAD;
+		cfqd->workload_expires = jiffies + 1;
+		return;
+	}
+
+	/* Choose next priority. RT > BE > IDLE */
+	if (cfq_group_busy_queues_wl(RT_WORKLOAD, cfqd, cfqg))
+		cfqd->serving_prio = RT_WORKLOAD;
+	else if (cfq_group_busy_queues_wl(BE_WORKLOAD, cfqd, cfqg))
+		cfqd->serving_prio = BE_WORKLOAD;
+	else {
+		cfqd->serving_prio = IDLE_WORKLOAD;
+		cfqd->workload_expires = jiffies + 1;
+		return;
+	}
+
+	/*
+	 * For RT and BE, we have to choose also the type
+	 * (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload
+	 * expiration time
+	 */
+	st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type);
+	count = st->count;
+
+	/*
+	 * check workload expiration, and that we still have other queues ready
+	 */
+	if (count && !time_after(jiffies, cfqd->workload_expires))
+		return;
+
+	/* otherwise select new workload type */
+	cfqd->serving_type =
+		cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio);
+	st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type);
+	count = st->count;
+
+	/*
+	 * the workload slice is computed as a fraction of target latency
+	 * proportional to the number of queues in that workload, over
+	 * all the queues in the same priority class
+	 */
+	group_slice = cfq_group_slice(cfqd, cfqg);
+
+	slice = group_slice * count /
+		max_t(unsigned, cfqg->busy_queues_avg[cfqd->serving_prio],
+		      cfq_group_busy_queues_wl(cfqd->serving_prio, cfqd, cfqg));
+
+	if (cfqd->serving_type == ASYNC_WORKLOAD) {
+		unsigned int tmp;
+
+		/*
+		 * Async queues are currently system wide. Just taking
+		 * proportion of queues with-in same group will lead to higher
+		 * async ratio system wide as generally root group is going
+		 * to have higher weight. A more accurate thing would be to
+		 * calculate system wide asnc/sync ratio.
+		 */
+		tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg);
+		tmp = tmp/cfqd->busy_queues;
+		slice = min_t(unsigned, slice, tmp);
+
+		/* async workload slice is scaled down according to
+		 * the sync/async slice ratio. */
+		slice = slice * cfqd->cfq_slice[0] / cfqd->cfq_slice[1];
+	} else
+		/* sync workload slice is at least 2 * cfq_slice_idle */
+		slice = max(slice, 2 * cfqd->cfq_slice_idle);
+
+	slice = max_t(unsigned, slice, CFQ_MIN_TT);
+	cfqd->workload_expires = jiffies + slice;
+	cfqd->noidle_tree_requires_idle = false;
+}
+
+static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd)
+{
+	struct cfq_rb_root *st = &cfqd->grp_service_tree;
+	struct cfq_group *cfqg;
+
+	if (RB_EMPTY_ROOT(&st->rb))
+		return NULL;
+	cfqg = cfq_rb_first_group(st);
+	st->active = &cfqg->rb_node;
+	update_min_vdisktime(st);
+	return cfqg;
+}
+
+static void cfq_choose_cfqg(struct cfq_data *cfqd)
+{
+	struct cfq_group *cfqg = cfq_get_next_cfqg(cfqd);
+
+	cfqd->serving_group = cfqg;
+
+	/* Restore the workload type data */
+	if (cfqg->saved_workload_slice) {
+		cfqd->workload_expires = jiffies + cfqg->saved_workload_slice;
+		cfqd->serving_type = cfqg->saved_workload;
+		cfqd->serving_prio = cfqg->saved_serving_prio;
+	} else
+		cfqd->workload_expires = jiffies - 1;
+
+	choose_service_tree(cfqd, cfqg);
+}
+
+/*
  * Select a queue for service. If we have a current active queue,
  * check whether to continue servicing it, or retrieve and set a new one.
  */
@@ -1186,13 +2108,37 @@ static struct cfq_queue *cfq_select_queu
 	if (!cfqq)
 		goto new_queue;
 
+	if (!cfqd->rq_queued)
+		return NULL;
+
 	/*
-	 * The active queue has run out of time, expire it and select new.
+	 * We were waiting for group to get backlogged. Expire the queue
 	 */
-	if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
+	if (cfq_cfqq_wait_busy(cfqq) && !RB_EMPTY_ROOT(&cfqq->sort_list))
 		goto expire;
 
 	/*
+	 * The active queue has run out of time, expire it and select new.
+	 */
+	if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) {
+		/*
+		 * If slice had not expired at the completion of last request
+		 * we might not have turned on wait_busy flag. Don't expire
+		 * the queue yet. Allow the group to get backlogged.
+		 *
+		 * The very fact that we have used the slice, that means we
+		 * have been idling all along on this queue and it should be
+		 * ok to wait for this request to complete.
+		 */
+		if (cfqq->cfqg->nr_cfqq == 1 && RB_EMPTY_ROOT(&cfqq->sort_list)
+		    && cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) {
+			cfqq = NULL;
+			goto keep_queue;
+		} else
+			goto expire;
+	}
+
+	/*
 	 * The active queue has requests and isn't expired, allow it to
 	 * dispatch.
 	 */
@@ -1203,11 +2149,14 @@ static struct cfq_queue *cfq_select_queu
 	 * If another queue has a request waiting within our mean seek
 	 * distance, let it run.  The expire code will check for close
 	 * cooperators and put the close queue at the front of the service
-	 * tree.
+	 * tree.  If possible, merge the expiring queue with the new cfqq.
 	 */
-	new_cfqq = cfq_close_cooperator(cfqd, cfqq, 0);
-	if (new_cfqq)
+	new_cfqq = cfq_close_cooperator(cfqd, cfqq);
+	if (new_cfqq) {
+		if (!cfqq->new_cfqq)
+			cfq_setup_merge(cfqq, new_cfqq);
 		goto expire;
+	}
 
 	/*
 	 * No requests pending. If the active queue still has requests in
@@ -1215,7 +2164,7 @@ static struct cfq_queue *cfq_select_queu
 	 * conditions to happen (or time out) before selecting a new queue.
 	 */
 	if (timer_pending(&cfqd->idle_slice_timer) ||
-	    (cfqq->dispatched && cfq_cfqq_idle_window(cfqq))) {
+	    (cfqq->dispatched && cfq_should_idle(cfqd, cfqq))) {
 		cfqq = NULL;
 		goto keep_queue;
 	}
@@ -1223,6 +2172,13 @@ static struct cfq_queue *cfq_select_queu
 expire:
 	cfq_slice_expired(cfqd, 0);
 new_queue:
+	/*
+	 * Current queue expired. Check if we have to switch to a new
+	 * service tree
+	 */
+	if (!new_cfqq)
+		cfq_choose_cfqg(cfqd);
+
 	cfqq = cfq_set_active_queue(cfqd, new_cfqq);
 keep_queue:
 	return cfqq;
@@ -1238,6 +2194,9 @@ static int __cfq_forced_dispatch_cfqq(st
 	}
 
 	BUG_ON(!list_empty(&cfqq->fifo));
+
+	/* By default cfqq is not expired if it is empty. Do it explicitly */
+	__cfq_slice_expired(cfqq->cfqd, cfqq, 0);
 	return dispatched;
 }
 
@@ -1250,11 +2209,10 @@ static int cfq_forced_dispatch(struct cf
 	struct cfq_queue *cfqq;
 	int dispatched = 0;
 
-	while ((cfqq = cfq_rb_first(&cfqd->service_tree)) != NULL)
+	while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
 		dispatched += __cfq_forced_dispatch_cfqq(cfqq);
 
 	cfq_slice_expired(cfqd, 0);
-
 	BUG_ON(cfqd->busy_queues);
 
 	cfq_log(cfqd, "forced_dispatch=%d", dispatched);
@@ -1268,7 +2226,7 @@ static bool cfq_may_dispatch(struct cfq_
 	/*
 	 * Drain async requests before we start sync IO
 	 */
-	if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
+	if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
 		return false;
 
 	/*
@@ -1298,9 +2256,9 @@ static bool cfq_may_dispatch(struct cfq_
 			return false;
 
 		/*
-		 * Sole queue user, allow bigger slice
+		 * Sole queue user, no limit
 		 */
-		max_dispatch *= 4;
+		max_dispatch = -1;
 	}
 
 	/*
@@ -1309,7 +2267,7 @@ static bool cfq_may_dispatch(struct cfq_
 	 * based on the last sync IO we serviced
 	 */
 	if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) {
-		unsigned long last_sync = jiffies - cfqd->last_end_sync_rq;
+		unsigned long last_sync = jiffies - cfqd->last_delayed_sync;
 		unsigned int depth;
 
 		depth = last_sync / cfqd->cfq_slice[1];
@@ -1407,11 +2365,13 @@ static int cfq_dispatch_requests(struct
  * task holds one reference to the queue, dropped when task exits. each rq
  * in-flight on this queue also holds a reference, dropped when rq is freed.
  *
+ * Each cfq queue took a reference on the parent group. Drop it now.
  * queue lock must be held here.
  */
 static void cfq_put_queue(struct cfq_queue *cfqq)
 {
 	struct cfq_data *cfqd = cfqq->cfqd;
+	struct cfq_group *cfqg, *orig_cfqg;
 
 	BUG_ON(atomic_read(&cfqq->ref) <= 0);
 
@@ -1421,14 +2381,19 @@ static void cfq_put_queue(struct cfq_que
 	cfq_log_cfqq(cfqd, cfqq, "put_queue");
 	BUG_ON(rb_first(&cfqq->sort_list));
 	BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
-	BUG_ON(cfq_cfqq_on_rr(cfqq));
+	cfqg = cfqq->cfqg;
+	orig_cfqg = cfqq->orig_cfqg;
 
 	if (unlikely(cfqd->active_queue == cfqq)) {
 		__cfq_slice_expired(cfqd, cfqq, 0);
 		cfq_schedule_dispatch(cfqd);
 	}
 
+	BUG_ON(cfq_cfqq_on_rr(cfqq));
 	kmem_cache_free(cfq_pool, cfqq);
+	cfq_put_cfqg(cfqg);
+	if (orig_cfqg)
+		cfq_put_cfqg(orig_cfqg);
 }
 
 /*
@@ -1518,11 +2483,29 @@ static void cfq_free_io_context(struct i
 
 static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+	struct cfq_queue *__cfqq, *next;
+
 	if (unlikely(cfqq == cfqd->active_queue)) {
 		__cfq_slice_expired(cfqd, cfqq, 0);
 		cfq_schedule_dispatch(cfqd);
 	}
 
+	/*
+	 * If this queue was scheduled to merge with another queue, be
+	 * sure to drop the reference taken on that queue (and others in
+	 * the merge chain).  See cfq_setup_merge and cfq_merge_cfqqs.
+	 */
+	__cfqq = cfqq->new_cfqq;
+	while (__cfqq) {
+		if (__cfqq == cfqq) {
+			WARN(1, "cfqq->new_cfqq loop detected\n");
+			break;
+		}
+		next = __cfqq->new_cfqq;
+		cfq_put_queue(__cfqq);
+		__cfqq = next;
+	}
+
 	cfq_put_queue(cfqq);
 }
 
@@ -1703,14 +2686,51 @@ static void cfq_init_cfqq(struct cfq_dat
 	cfqq->pid = pid;
 }
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic)
+{
+	struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1);
+	struct cfq_data *cfqd = cic->key;
+	unsigned long flags;
+	struct request_queue *q;
+
+	if (unlikely(!cfqd))
+		return;
+
+	q = cfqd->queue;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+
+	if (sync_cfqq) {
+		/*
+		 * Drop reference to sync queue. A new sync queue will be
+		 * assigned in new group upon arrival of a fresh request.
+		 */
+		cfq_log_cfqq(cfqd, sync_cfqq, "changed cgroup");
+		cic_set_cfqq(cic, NULL, 1);
+		cfq_put_queue(sync_cfqq);
+	}
+
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+static void cfq_ioc_set_cgroup(struct io_context *ioc)
+{
+	call_for_each_cic(ioc, changed_cgroup);
+	ioc->cgroup_changed = 0;
+}
+#endif  /* CONFIG_CFQ_GROUP_IOSCHED */
+
 static struct cfq_queue *
 cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync,
 		     struct io_context *ioc, gfp_t gfp_mask)
 {
 	struct cfq_queue *cfqq, *new_cfqq = NULL;
 	struct cfq_io_context *cic;
+	struct cfq_group *cfqg;
 
 retry:
+	cfqg = cfq_get_cfqg(cfqd, 1);
 	cic = cfq_cic_lookup(cfqd, ioc);
 	/* cic always exists here */
 	cfqq = cic_to_cfqq(cic, is_sync);
@@ -1741,6 +2761,7 @@ retry:
 		if (cfqq) {
 			cfq_init_cfqq(cfqd, cfqq, current->pid, is_sync);
 			cfq_init_prio_data(cfqq, ioc);
+			cfq_link_cfqq_cfqg(cfqq, cfqg);
 			cfq_log_cfqq(cfqd, cfqq, "alloced");
 		} else
 			cfqq = &cfqd->oom_cfqq;
@@ -1932,6 +2953,10 @@ out:
 	if (unlikely(ioc->ioprio_changed))
 		cfq_ioc_set_ioprio(ioc);
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+	if (unlikely(ioc->cgroup_changed))
+		cfq_ioc_set_cgroup(ioc);
+#endif
 	return cic;
 err_free:
 	cfq_cic_free(cic);
@@ -1952,33 +2977,33 @@ cfq_update_io_thinktime(struct cfq_data
 }
 
 static void
-cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic,
+cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 		       struct request *rq)
 {
 	sector_t sdist;
 	u64 total;
 
-	if (!cic->last_request_pos)
+	if (!cfqq->last_request_pos)
 		sdist = 0;
-	else if (cic->last_request_pos < blk_rq_pos(rq))
-		sdist = blk_rq_pos(rq) - cic->last_request_pos;
+	else if (cfqq->last_request_pos < blk_rq_pos(rq))
+		sdist = blk_rq_pos(rq) - cfqq->last_request_pos;
 	else
-		sdist = cic->last_request_pos - blk_rq_pos(rq);
+		sdist = cfqq->last_request_pos - blk_rq_pos(rq);
 
 	/*
 	 * Don't allow the seek distance to get too large from the
 	 * odd fragment, pagein, etc
 	 */
-	if (cic->seek_samples <= 60) /* second&third seek */
-		sdist = min(sdist, (cic->seek_mean * 4) + 2*1024*1024);
+	if (cfqq->seek_samples <= 60) /* second&third seek */
+		sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*1024);
 	else
-		sdist = min(sdist, (cic->seek_mean * 4)	+ 2*1024*64);
+		sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*64);
 
-	cic->seek_samples = (7*cic->seek_samples + 256) / 8;
-	cic->seek_total = (7*cic->seek_total + (u64)256*sdist) / 8;
-	total = cic->seek_total + (cic->seek_samples/2);
-	do_div(total, cic->seek_samples);
-	cic->seek_mean = (sector_t)total;
+	cfqq->seek_samples = (7*cfqq->seek_samples + 256) / 8;
+	cfqq->seek_total = (7*cfqq->seek_total + (u64)256*sdist) / 8;
+	total = cfqq->seek_total + (cfqq->seek_samples/2);
+	do_div(total, cfqq->seek_samples);
+	cfqq->seek_mean = (sector_t)total;
 }
 
 /*
@@ -1999,14 +3024,15 @@ cfq_update_idle_window(struct cfq_data *
 
 	enable_idle = old_idle = cfq_cfqq_idle_window(cfqq);
 
+	if (cfqq->queued[0] + cfqq->queued[1] >= 4)
+		cfq_mark_cfqq_deep(cfqq);
+
 	if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
-	    (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic)))
+	    (!cfq_cfqq_deep(cfqq) && sample_valid(cfqq->seek_samples)
+	     && CFQQ_SEEKY(cfqq)))
 		enable_idle = 0;
 	else if (sample_valid(cic->ttime_samples)) {
-		unsigned int slice_idle = cfqd->cfq_slice_idle;
-		if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
-			slice_idle = msecs_to_jiffies(CFQ_MIN_TT);
-		if (cic->ttime_mean > slice_idle)
+		if (cic->ttime_mean > cfqd->cfq_slice_idle)
 			enable_idle = 0;
 		else
 			enable_idle = 1;
@@ -2035,9 +3061,6 @@ cfq_should_preempt(struct cfq_data *cfqd
 	if (!cfqq)
 		return false;
 
-	if (cfq_slice_used(cfqq))
-		return true;
-
 	if (cfq_class_idle(new_cfqq))
 		return false;
 
@@ -2045,12 +3068,31 @@ cfq_should_preempt(struct cfq_data *cfqd
 		return true;
 
 	/*
+	 * Don't allow a non-RT request to preempt an ongoing RT cfqq timeslice.
+	 */
+	if (cfq_class_rt(cfqq) && !cfq_class_rt(new_cfqq))
+		return false;
+
+	/*
 	 * if the new request is sync, but the currently running queue is
 	 * not, let the sync request have priority.
 	 */
 	if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
 		return true;
 
+	if (new_cfqq->cfqg != cfqq->cfqg)
+		return false;
+
+	if (cfq_slice_used(cfqq))
+		return true;
+
+	/* Allow preemption only if we are idling on sync-noidle tree */
+	if (cfqd->serving_type == SYNC_NOIDLE_WORKLOAD &&
+	    cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD &&
+	    new_cfqq->service_tree->count == 2 &&
+	    RB_EMPTY_ROOT(&cfqq->sort_list))
+		return true;
+
 	/*
 	 * So both queues are sync. Let the new request get disk time if
 	 * it's a metadata request and the current queue is doing regular IO.
@@ -2071,16 +3113,8 @@ cfq_should_preempt(struct cfq_data *cfqd
 	 * if this request is as-good as one we would expect from the
 	 * current cfqq, let it preempt
 	 */
-	if (cfq_rq_close(cfqd, rq) && (!cfq_cfqq_coop(new_cfqq) ||
-	    cfqd->busy_queues == 1)) {
-		/*
-		 * Mark new queue coop_preempt, so its coop flag will not be
-		 * cleared when new queue gets scheduled at the very first time
-		 */
-		cfq_mark_cfqq_coop_preempt(new_cfqq);
-		cfq_mark_cfqq_coop(new_cfqq);
+	if (cfq_rq_close(cfqd, cfqq, rq, true))
 		return true;
-	}
 
 	return false;
 }
@@ -2121,10 +3155,10 @@ cfq_rq_enqueued(struct cfq_data *cfqd, s
 		cfqq->meta_pending++;
 
 	cfq_update_io_thinktime(cfqd, cic);
-	cfq_update_io_seektime(cfqd, cic, rq);
+	cfq_update_io_seektime(cfqd, cfqq, rq);
 	cfq_update_idle_window(cfqd, cfqq, cic);
 
-	cic->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
+	cfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
 
 	if (cfqq == cfqd->active_queue) {
 		/*
@@ -2141,9 +3175,10 @@ cfq_rq_enqueued(struct cfq_data *cfqd, s
 			if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE ||
 			    cfqd->busy_queues > 1) {
 				del_timer(&cfqd->idle_slice_timer);
-			__blk_run_queue(cfqd->queue);
-			}
-			cfq_mark_cfqq_must_dispatch(cfqq);
+				cfq_clear_cfqq_wait_request(cfqq);
+				__blk_run_queue(cfqd->queue);
+			} else
+				cfq_mark_cfqq_must_dispatch(cfqq);
 		}
 	} else if (cfq_should_preempt(cfqd, cfqq, rq)) {
 		/*
@@ -2165,10 +3200,9 @@ static void cfq_insert_request(struct re
 	cfq_log_cfqq(cfqd, cfqq, "insert_request");
 	cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc);
 
-	cfq_add_rq_rb(rq);
-
 	rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
 	list_add_tail(&rq->queuelist, &cfqq->fifo);
+	cfq_add_rq_rb(rq);
 
 	cfq_rq_enqueued(cfqd, cfqq, rq);
 }
@@ -2179,23 +3213,64 @@ static void cfq_insert_request(struct re
  */
 static void cfq_update_hw_tag(struct cfq_data *cfqd)
 {
-	if (rq_in_driver(cfqd) > cfqd->rq_in_driver_peak)
-		cfqd->rq_in_driver_peak = rq_in_driver(cfqd);
+	struct cfq_queue *cfqq = cfqd->active_queue;
+
+	if (rq_in_driver(cfqd) > cfqd->hw_tag_est_depth)
+		cfqd->hw_tag_est_depth = rq_in_driver(cfqd);
+
+	if (cfqd->hw_tag == 1)
+		return;
 
 	if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN &&
 	    rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN)
 		return;
 
+	/*
+	 * If active queue hasn't enough requests and can idle, cfq might not
+	 * dispatch sufficient requests to hardware. Don't zero hw_tag in this
+	 * case
+	 */
+	if (cfqq && cfq_cfqq_idle_window(cfqq) &&
+	    cfqq->dispatched + cfqq->queued[0] + cfqq->queued[1] <
+	    CFQ_HW_QUEUE_MIN && rq_in_driver(cfqd) < CFQ_HW_QUEUE_MIN)
+		return;
+
 	if (cfqd->hw_tag_samples++ < 50)
 		return;
 
-	if (cfqd->rq_in_driver_peak >= CFQ_HW_QUEUE_MIN)
+	if (cfqd->hw_tag_est_depth >= CFQ_HW_QUEUE_MIN)
 		cfqd->hw_tag = 1;
 	else
 		cfqd->hw_tag = 0;
+}
 
-	cfqd->hw_tag_samples = 0;
-	cfqd->rq_in_driver_peak = 0;
+static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	struct cfq_io_context *cic = cfqd->active_cic;
+
+	/* If there are other queues in the group, don't wait */
+	if (cfqq->cfqg->nr_cfqq > 1)
+		return false;
+
+	if (cfq_slice_used(cfqq))
+		return true;
+
+	/* if slice left is less than think time, wait busy */
+	if (cic && sample_valid(cic->ttime_samples)
+	    && (cfqq->slice_end - jiffies < cic->ttime_mean))
+		return true;
+
+	/*
+	 * If think times is less than a jiffy than ttime_mean=0 and above
+	 * will not be true. It might happen that slice has not expired yet
+	 * but will expire soon (4-5 ns) during select_queue(). To cover the
+	 * case where think time is less than a jiffy, mark the queue wait
+	 * busy if only 1 jiffy is left in the slice.
+	 */
+	if (cfqq->slice_end - jiffies == 1)
+		return true;
+
+	return false;
 }
 
 static void cfq_completed_request(struct request_queue *q, struct request *rq)
@@ -2206,7 +3281,7 @@ static void cfq_completed_request(struct
 	unsigned long now;
 
 	now = jiffies;
-	cfq_log_cfqq(cfqd, cfqq, "complete");
+	cfq_log_cfqq(cfqd, cfqq, "complete rqnoidle %d", !!rq_noidle(rq));
 
 	cfq_update_hw_tag(cfqd);
 
@@ -2220,7 +3295,8 @@ static void cfq_completed_request(struct
 
 	if (sync) {
 		RQ_CIC(rq)->last_end_request = now;
-		cfqd->last_end_sync_rq = now;
+		if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now))
+			cfqd->last_delayed_sync = now;
 	}
 
 	/*
@@ -2234,18 +3310,39 @@ static void cfq_completed_request(struct
 			cfq_set_prio_slice(cfqd, cfqq);
 			cfq_clear_cfqq_slice_new(cfqq);
 		}
+
 		/*
-		 * If there are no requests waiting in this queue, and
-		 * there are other queues ready to issue requests, AND
-		 * those other queues are issuing requests within our
-		 * mean seek distance, give them a chance to run instead
-		 * of idling.
+		 * Should we wait for next request to come in before we expire
+		 * the queue.
+		 */
+		if (cfq_should_wait_busy(cfqd, cfqq)) {
+			cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
+			cfq_mark_cfqq_wait_busy(cfqq);
+		}
+
+		/*
+		 * Idling is not enabled on:
+		 * - expired queues
+		 * - idle-priority queues
+		 * - async queues
+		 * - queues with still some requests queued
+		 * - when there is a close cooperator
 		 */
 		if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
 			cfq_slice_expired(cfqd, 1);
-		else if (cfqq_empty && !cfq_close_cooperator(cfqd, cfqq, 1) &&
-			 sync && !rq_noidle(rq))
-			cfq_arm_slice_timer(cfqd);
+		else if (sync && cfqq_empty &&
+			 !cfq_close_cooperator(cfqd, cfqq)) {
+			cfqd->noidle_tree_requires_idle |= !rq_noidle(rq);
+			/*
+			 * Idling is enabled for SYNC_WORKLOAD.
+			 * SYNC_NOIDLE_WORKLOAD idles at the end of the tree
+			 * only if we processed at least one !rq_noidle request
+			 */
+			if (cfqd->serving_type == SYNC_WORKLOAD
+			    || cfqd->noidle_tree_requires_idle
+			    || cfqq->cfqg->nr_cfqq == 1)
+				cfq_arm_slice_timer(cfqd);
+		}
 	}
 
 	if (!rq_in_driver(cfqd))
@@ -2269,12 +3366,10 @@ static void cfq_prio_boost(struct cfq_qu
 			cfqq->ioprio = IOPRIO_NORM;
 	} else {
 		/*
-		 * check if we need to unboost the queue
+		 * unboost the queue (if needed)
 		 */
-		if (cfqq->ioprio_class != cfqq->org_ioprio_class)
-			cfqq->ioprio_class = cfqq->org_ioprio_class;
-		if (cfqq->ioprio != cfqq->org_ioprio)
-			cfqq->ioprio = cfqq->org_ioprio;
+		cfqq->ioprio_class = cfqq->org_ioprio_class;
+		cfqq->ioprio = cfqq->org_ioprio;
 	}
 }
 
@@ -2338,6 +3433,35 @@ static void cfq_put_request(struct reque
 	}
 }
 
+static struct cfq_queue *
+cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_context *cic,
+		struct cfq_queue *cfqq)
+{
+	cfq_log_cfqq(cfqd, cfqq, "merging with queue %p", cfqq->new_cfqq);
+	cic_set_cfqq(cic, cfqq->new_cfqq, 1);
+	cfq_mark_cfqq_coop(cfqq->new_cfqq);
+	cfq_put_queue(cfqq);
+	return cic_to_cfqq(cic, 1);
+}
+
+/*
+ * Returns NULL if a new cfqq should be allocated, or the old cfqq if this
+ * was the last process referring to said cfqq.
+ */
+static struct cfq_queue *
+split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq)
+{
+	if (cfqq_process_refs(cfqq) == 1) {
+		cfqq->pid = current->pid;
+		cfq_clear_cfqq_coop(cfqq);
+		cfq_clear_cfqq_split_coop(cfqq);
+		return cfqq;
+	}
+
+	cic_set_cfqq(cic, NULL, 1);
+	cfq_put_queue(cfqq);
+	return NULL;
+}
 /*
  * Allocate cfq data structures associated with this request.
  */
@@ -2360,10 +3484,30 @@ cfq_set_request(struct request_queue *q,
 	if (!cic)
 		goto queue_fail;
 
+new_queue:
 	cfqq = cic_to_cfqq(cic, is_sync);
 	if (!cfqq || cfqq == &cfqd->oom_cfqq) {
 		cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask);
 		cic_set_cfqq(cic, cfqq, is_sync);
+	} else {
+		/*
+		 * If the queue was seeky for too long, break it apart.
+		 */
+		if (cfq_cfqq_coop(cfqq) && cfq_cfqq_split_coop(cfqq)) {
+			cfq_log_cfqq(cfqd, cfqq, "breaking apart cfqq");
+			cfqq = split_cfqq(cic, cfqq);
+			if (!cfqq)
+				goto new_queue;
+		}
+
+		/*
+		 * Check to see if this queue is scheduled to merge with
+		 * another, closely cooperating queue.  The merging of
+		 * queues happens here as it must be done in process context.
+		 * The reference on new_cfqq was taken in merge_cfqqs.
+		 */
+		if (cfqq->new_cfqq)
+			cfqq = cfq_merge_cfqqs(cfqd, cic, cfqq);
 	}
 
 	cfqq->allocated[rw]++;
@@ -2438,6 +3582,11 @@ static void cfq_idle_slice_timer(unsigne
 		 */
 		if (!RB_EMPTY_ROOT(&cfqq->sort_list))
 			goto out_kick;
+
+		/*
+		 * Queue depth flag is reset only when the idle didn't succeed
+		 */
+		cfq_clear_cfqq_deep(cfqq);
 	}
 expire:
 	cfq_slice_expired(cfqd, timed_out);
@@ -2468,6 +3617,11 @@ static void cfq_put_async_queues(struct
 		cfq_put_queue(cfqd->async_idle_cfqq);
 }
 
+static void cfq_cfqd_free(struct rcu_head *head)
+{
+	kfree(container_of(head, struct cfq_data, rcu));
+}
+
 static void cfq_exit_queue(struct elevator_queue *e)
 {
 	struct cfq_data *cfqd = e->elevator_data;
@@ -2489,25 +3643,49 @@ static void cfq_exit_queue(struct elevat
 	}
 
 	cfq_put_async_queues(cfqd);
+	cfq_release_cfq_groups(cfqd);
+	blkiocg_del_blkio_group(&cfqd->root_group.blkg);
 
 	spin_unlock_irq(q->queue_lock);
 
 	cfq_shutdown_timer_wq(cfqd);
 
-	kfree(cfqd);
+	/* Wait for cfqg->blkg->key accessors to exit their grace periods. */
+	call_rcu(&cfqd->rcu, cfq_cfqd_free);
 }
 
 static void *cfq_init_queue(struct request_queue *q)
 {
 	struct cfq_data *cfqd;
-	int i;
+	int i, j;
+	struct cfq_group *cfqg;
+	struct cfq_rb_root *st;
 
 	cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
 	if (!cfqd)
 		return NULL;
 
-	cfqd->service_tree = CFQ_RB_ROOT;
+	/* Init root service tree */
+	cfqd->grp_service_tree = CFQ_RB_ROOT;
+
+	/* Init root group */
+	cfqg = &cfqd->root_group;
+	for_each_cfqg_st(cfqg, i, j, st)
+		*st = CFQ_RB_ROOT;
+	RB_CLEAR_NODE(&cfqg->rb_node);
+
+	/* Give preference to root group over other groups */
+	cfqg->weight = 2*BLKIO_WEIGHT_DEFAULT;
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+	/*
+	 * Take a reference to root group which we never drop. This is just
+	 * to make sure that cfq_put_cfqg() does not try to kfree root group
+	 */
+	atomic_set(&cfqg->ref, 1);
+	blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd,
+					0);
+#endif
 	/*
 	 * Not strictly needed (since RB_ROOT just clears the node and we
 	 * zeroed cfqd on alloc), but better be safe in case someone decides
@@ -2523,6 +3701,7 @@ static void *cfq_init_queue(struct reque
 	 */
 	cfq_init_cfqq(cfqd, &cfqd->oom_cfqq, 1, 0);
 	atomic_inc(&cfqd->oom_cfqq.ref);
+	cfq_link_cfqq_cfqg(&cfqd->oom_cfqq, &cfqd->root_group);
 
 	INIT_LIST_HEAD(&cfqd->cic_list);
 
@@ -2544,8 +3723,14 @@ static void *cfq_init_queue(struct reque
 	cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
 	cfqd->cfq_slice_idle = cfq_slice_idle;
 	cfqd->cfq_latency = 1;
-	cfqd->hw_tag = 1;
-	cfqd->last_end_sync_rq = jiffies;
+	cfqd->cfq_group_isolation = 0;
+	cfqd->hw_tag = -1;
+	/*
+	 * we optimistically start assuming sync ops weren't delayed in last
+	 * second, in order to have larger depth for async operations.
+	 */
+	cfqd->last_delayed_sync = jiffies - HZ;
+	INIT_RCU_HEAD(&cfqd->rcu);
 	return cfqd;
 }
 
@@ -2614,6 +3799,7 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd-
 SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
 SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
 SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
+SHOW_FUNCTION(cfq_group_isolation_show, cfqd->cfq_group_isolation, 0);
 #undef SHOW_FUNCTION
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
@@ -2646,6 +3832,7 @@ STORE_FUNCTION(cfq_slice_async_store, &c
 STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
 		UINT_MAX, 0);
 STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
+STORE_FUNCTION(cfq_group_isolation_store, &cfqd->cfq_group_isolation, 0, 1, 0);
 #undef STORE_FUNCTION
 
 #define CFQ_ATTR(name) \
@@ -2662,6 +3849,7 @@ static struct elv_fs_entry cfq_attrs[] =
 	CFQ_ATTR(slice_async_rq),
 	CFQ_ATTR(slice_idle),
 	CFQ_ATTR(low_latency),
+	CFQ_ATTR(group_isolation),
 	__ATTR_NULL
 };
 
@@ -2691,6 +3879,17 @@ static struct elevator_type iosched_cfq
 	.elevator_owner =	THIS_MODULE,
 };
 
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+static struct blkio_policy_type blkio_policy_cfq = {
+	.ops = {
+		.blkio_unlink_group_fn =	cfq_unlink_blkio_group,
+		.blkio_update_group_weight_fn =	cfq_update_blkio_group_weight,
+	},
+};
+#else
+static struct blkio_policy_type blkio_policy_cfq;
+#endif
+
 static int __init cfq_init(void)
 {
 	/*
@@ -2705,6 +3904,7 @@ static int __init cfq_init(void)
 		return -ENOMEM;
 
 	elv_register(&iosched_cfq);
+	blkio_policy_register(&blkio_policy_cfq);
 
 	return 0;
 }
@@ -2712,6 +3912,7 @@ static int __init cfq_init(void)
 static void __exit cfq_exit(void)
 {
 	DECLARE_COMPLETION_ONSTACK(all_gone);
+	blkio_policy_unregister(&blkio_policy_cfq);
 	elv_unregister(&iosched_cfq);
 	ioc_gone = &all_gone;
 	/* ioc_gone's update must be visible before reading ioc_count */
diff -druNp linux-libre-2.6.32-gnu1/block/compat_ioctl.c linux-libre-2.6.33-gnu1/block/compat_ioctl.c
--- linux-libre-2.6.32-gnu1/block/compat_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/compat_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -747,6 +747,8 @@ long compat_blkdev_ioctl(struct file *fi
 		return compat_put_uint(arg, bdev_io_opt(bdev));
 	case BLKALIGNOFF:
 		return compat_put_int(arg, bdev_alignment_offset(bdev));
+	case BLKDISCARDZEROES:
+		return compat_put_uint(arg, bdev_discard_zeroes_data(bdev));
 	case BLKFLSBUF:
 	case BLKROSET:
 	case BLKDISCARD:
diff -druNp linux-libre-2.6.32-gnu1/block/elevator.c linux-libre-2.6.33-gnu1/block/elevator.c
--- linux-libre-2.6.32-gnu1/block/elevator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/elevator.c	2010-02-24 13:52:17.000000000 -0500
@@ -154,10 +154,7 @@ static struct elevator_type *elevator_ge
 
 		spin_unlock(&elv_list_lock);
 
-		if (!strcmp(name, "anticipatory"))
-			sprintf(elv, "as-iosched");
-		else
-			sprintf(elv, "%s-iosched", name);
+		sprintf(elv, "%s-iosched", name);
 
 		request_module("%s", elv);
 		spin_lock(&elv_list_lock);
@@ -193,10 +190,7 @@ static int __init elevator_setup(char *s
 	 * Be backwards-compatible with previous kernels, so users
 	 * won't get the wrong elevator.
 	 */
-	if (!strcmp(str, "as"))
-		strcpy(chosen_elevator, "anticipatory");
-	else
-		strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
+	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
 	return 1;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/block/genhd.c linux-libre-2.6.33-gnu1/block/genhd.c
--- linux-libre-2.6.32-gnu1/block/genhd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/genhd.c	2010-02-24 13:52:17.000000000 -0500
@@ -861,12 +861,23 @@ static ssize_t disk_alignment_offset_sho
 	return sprintf(buf, "%d\n", queue_alignment_offset(disk->queue));
 }
 
+static ssize_t disk_discard_alignment_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct gendisk *disk = dev_to_disk(dev);
+
+	return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
+}
+
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
 static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
 static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
 static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
 static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
+static DEVICE_ATTR(discard_alignment, S_IRUGO, disk_discard_alignment_show,
+		   NULL);
 static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
 static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
@@ -887,6 +898,7 @@ static struct attribute *disk_attrs[] =
 	&dev_attr_ro.attr,
 	&dev_attr_size.attr,
 	&dev_attr_alignment_offset.attr,
+	&dev_attr_discard_alignment.attr,
 	&dev_attr_capability.attr,
 	&dev_attr_stat.attr,
 	&dev_attr_inflight.attr,
diff -druNp linux-libre-2.6.32-gnu1/block/ioctl.c linux-libre-2.6.33-gnu1/block/ioctl.c
--- linux-libre-2.6.32-gnu1/block/ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -280,6 +280,8 @@ int blkdev_ioctl(struct block_device *bd
 		return put_uint(arg, bdev_io_opt(bdev));
 	case BLKALIGNOFF:
 		return put_int(arg, bdev_alignment_offset(bdev));
+	case BLKDISCARDZEROES:
+		return put_uint(arg, bdev_discard_zeroes_data(bdev));
 	case BLKSECTGET:
 		return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
 	case BLKRASET:
diff -druNp linux-libre-2.6.32-gnu1/block/Kconfig linux-libre-2.6.33-gnu1/block/Kconfig
--- linux-libre-2.6.32-gnu1/block/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -77,6 +77,28 @@ config BLK_DEV_INTEGRITY
 	T10/SCSI Data Integrity Field or the T13/ATA External Path
 	Protection.  If in doubt, say N.
 
+config BLK_CGROUP
+	bool
+	depends on CGROUPS
+	default n
+	---help---
+	Generic block IO controller cgroup interface. This is the common
+	cgroup interface which should be used by various IO controlling
+	policies.
+
+	Currently, CFQ IO scheduler uses it to recognize task groups and
+	control disk bandwidth allocation (proportional time slice allocation)
+	to such task groups.
+
+config DEBUG_BLK_CGROUP
+	bool
+	depends on BLK_CGROUP
+	default n
+	---help---
+	Enable some debugging help. Currently it stores the cgroup path
+	in the blk group which can be used by cfq for tracing various
+	group related activity.
+
 endif # BLOCK
 
 config BLOCK_COMPAT
diff -druNp linux-libre-2.6.32-gnu1/block/Kconfig.iosched linux-libre-2.6.33-gnu1/block/Kconfig.iosched
--- linux-libre-2.6.32-gnu1/block/Kconfig.iosched	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/Kconfig.iosched	2010-02-24 13:52:17.000000000 -0500
@@ -12,24 +12,14 @@ config IOSCHED_NOOP
 	  that do their own scheduling and require only minimal assistance from
 	  the kernel.
 
-config IOSCHED_AS
-	tristate "Anticipatory I/O scheduler"
-	default y
-	---help---
-	  The anticipatory I/O scheduler is generally a good choice for most
-	  environments, but is quite large and complex when compared to the
-	  deadline I/O scheduler, it can also be slower in some cases
-	  especially some database loads.
-
 config IOSCHED_DEADLINE
 	tristate "Deadline I/O scheduler"
 	default y
 	---help---
-	  The deadline I/O scheduler is simple and compact, and is often as
-	  good as the anticipatory I/O scheduler, and in some database
-	  workloads, better. In the case of a single process performing I/O to
-	  a disk at any one time, its behaviour is almost identical to the
-	  anticipatory I/O scheduler and so is a good choice.
+	  The deadline I/O scheduler is simple and compact. It will provide
+	  CSCAN service with FIFO expiration of requests, switching to
+	  a new point in the service tree and doing a batch of IO from there
+	  in case of expiry.
 
 config IOSCHED_CFQ
 	tristate "CFQ I/O scheduler"
@@ -37,9 +27,28 @@ config IOSCHED_CFQ
 	---help---
 	  The CFQ I/O scheduler tries to distribute bandwidth equally
 	  among all processes in the system. It should provide a fair
-	  working environment, suitable for desktop systems.
+	  and low latency working environment, suitable for both desktop
+	  and server systems.
+
 	  This is the default I/O scheduler.
 
+config CFQ_GROUP_IOSCHED
+	bool "CFQ Group Scheduling support"
+	depends on IOSCHED_CFQ && CGROUPS
+	select BLK_CGROUP
+	default n
+	---help---
+	  Enable group IO scheduling in CFQ.
+
+config DEBUG_CFQ_IOSCHED
+	bool "Debug CFQ Scheduling"
+	depends on CFQ_GROUP_IOSCHED
+	select DEBUG_BLK_CGROUP
+	default n
+	---help---
+	  Enable CFQ IO scheduling debugging in CFQ. Currently it makes
+	  blktrace output more verbose.
+
 choice
 	prompt "Default I/O scheduler"
 	default DEFAULT_CFQ
@@ -47,9 +56,6 @@ choice
 	  Select the I/O scheduler which will be used by default for all
 	  block devices.
 
-	config DEFAULT_AS
-		bool "Anticipatory" if IOSCHED_AS=y
-
 	config DEFAULT_DEADLINE
 		bool "Deadline" if IOSCHED_DEADLINE=y
 
@@ -63,7 +69,6 @@ endchoice
 
 config DEFAULT_IOSCHED
 	string
-	default "anticipatory" if DEFAULT_AS
 	default "deadline" if DEFAULT_DEADLINE
 	default "cfq" if DEFAULT_CFQ
 	default "noop" if DEFAULT_NOOP
diff -druNp linux-libre-2.6.32-gnu1/block/Makefile linux-libre-2.6.33-gnu1/block/Makefile
--- linux-libre-2.6.32-gnu1/block/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -8,8 +8,8 @@ obj-$(CONFIG_BLOCK) := elevator.o blk-co
 			blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o
 
 obj-$(CONFIG_BLK_DEV_BSG)	+= bsg.o
+obj-$(CONFIG_BLK_CGROUP)	+= blk-cgroup.o
 obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
-obj-$(CONFIG_IOSCHED_AS)	+= as-iosched.o
 obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
 obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
 
diff -druNp linux-libre-2.6.32-gnu1/block/scsi_ioctl.c linux-libre-2.6.33-gnu1/block/scsi_ioctl.c
--- linux-libre-2.6.32-gnu1/block/scsi_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/block/scsi_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,9 @@
 struct blk_cmd_filter {
 	unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
 	unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
-} blk_default_cmd_filter;
+};
+
+static struct blk_cmd_filter blk_default_cmd_filter;
 
 /* Command group 3 is reserved and should never be used.  */
 const unsigned char scsi_command_size_tbl[8] =
@@ -675,7 +677,7 @@ int scsi_cmd_ioctl(struct request_queue
 }
 EXPORT_SYMBOL(scsi_cmd_ioctl);
 
-int __init blk_scsi_ioctl_init(void)
+static int __init blk_scsi_ioctl_init(void)
 {
 	blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/crypto/ansi_cprng.c linux-libre-2.6.33-gnu1/crypto/ansi_cprng.c
--- linux-libre-2.6.32-gnu1/crypto/ansi_cprng.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/ansi_cprng.c	2010-02-24 13:52:17.000000000 -0500
@@ -85,7 +85,7 @@ static void xor_vectors(unsigned char *i
  * Returns DEFAULT_BLK_SZ bytes of random data per call
  * returns 0 if generation succeded, <0 if something went wrong
  */
-static int _get_more_prng_bytes(struct prng_context *ctx)
+static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
 {
 	int i;
 	unsigned char tmp[DEFAULT_BLK_SZ];
@@ -132,7 +132,7 @@ static int _get_more_prng_bytes(struct p
 			 */
 			if (!memcmp(ctx->rand_data, ctx->last_rand_data,
 					DEFAULT_BLK_SZ)) {
-				if (fips_enabled) {
+				if (cont_test) {
 					panic("cprng %p Failed repetition check!\n",
 						ctx);
 				}
@@ -185,16 +185,14 @@ static int _get_more_prng_bytes(struct p
 }
 
 /* Our exported functions */
-static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
+static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
+				int do_cont_test)
 {
 	unsigned char *ptr = buf;
 	unsigned int byte_count = (unsigned int)nbytes;
 	int err;
 
 
-	if (nbytes < 0)
-		return -EINVAL;
-
 	spin_lock_bh(&ctx->prng_lock);
 
 	err = -EINVAL;
@@ -220,7 +218,7 @@ static int get_prng_bytes(char *buf, siz
 
 remainder:
 	if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
-		if (_get_more_prng_bytes(ctx) < 0) {
+		if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
 			memset(buf, 0, nbytes);
 			err = -EINVAL;
 			goto done;
@@ -247,7 +245,7 @@ empty_rbuf:
 	 */
 	for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
 		if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
-			if (_get_more_prng_bytes(ctx) < 0) {
+			if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
 				memset(buf, 0, nbytes);
 				err = -EINVAL;
 				goto done;
@@ -356,7 +354,7 @@ static int cprng_get_random(struct crypt
 {
 	struct prng_context *prng = crypto_rng_ctx(tfm);
 
-	return get_prng_bytes(rdata, dlen, prng);
+	return get_prng_bytes(rdata, dlen, prng, 0);
 }
 
 /*
@@ -404,19 +402,79 @@ static struct crypto_alg rng_alg = {
 	}
 };
 
+#ifdef CONFIG_CRYPTO_FIPS
+static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
+			    unsigned int dlen)
+{
+	struct prng_context *prng = crypto_rng_ctx(tfm);
+
+	return get_prng_bytes(rdata, dlen, prng, 1);
+}
+
+static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
+{
+	u8 rdata[DEFAULT_BLK_SZ];
+	int rc;
+
+	struct prng_context *prng = crypto_rng_ctx(tfm);
+
+	rc = cprng_reset(tfm, seed, slen);
+
+	if (!rc)
+		goto out;
+
+	/* this primes our continuity test */
+	rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
+	prng->rand_data_valid = DEFAULT_BLK_SZ;
+
+out:
+	return rc;
+}
+
+static struct crypto_alg fips_rng_alg = {
+	.cra_name		= "fips(ansi_cprng)",
+	.cra_driver_name	= "fips_ansi_cprng",
+	.cra_priority		= 300,
+	.cra_flags		= CRYPTO_ALG_TYPE_RNG,
+	.cra_ctxsize		= sizeof(struct prng_context),
+	.cra_type		= &crypto_rng_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(rng_alg.cra_list),
+	.cra_init		= cprng_init,
+	.cra_exit		= cprng_exit,
+	.cra_u			= {
+		.rng = {
+			.rng_make_random	= fips_cprng_get_random,
+			.rng_reset		= fips_cprng_reset,
+			.seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
+		}
+	}
+};
+#endif
 
 /* Module initalization */
 static int __init prng_mod_init(void)
 {
-	if (fips_enabled)
-		rng_alg.cra_priority += 200;
+	int rc = 0;
 
-	return crypto_register_alg(&rng_alg);
+	rc = crypto_register_alg(&rng_alg);
+#ifdef CONFIG_CRYPTO_FIPS
+	if (rc)
+		goto out;
+
+	rc = crypto_register_alg(&fips_rng_alg);
+
+out:
+#endif
+	return rc;
 }
 
 static void __exit prng_mod_fini(void)
 {
 	crypto_unregister_alg(&rng_alg);
+#ifdef CONFIG_CRYPTO_FIPS
+	crypto_unregister_alg(&fips_rng_alg);
+#endif
 	return;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/crypto/async_tx/raid6test.c linux-libre-2.6.33-gnu1/crypto/async_tx/raid6test.c
--- linux-libre-2.6.32-gnu1/crypto/async_tx/raid6test.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/async_tx/raid6test.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,6 +214,13 @@ static int raid6_test(void)
 		err += test(4, &tests);
 	if (NDISKS > 5)
 		err += test(5, &tests);
+	/* the 11 and 12 disk cases are special for ioatdma (p-disabled
+	 * q-continuation without extended descriptor)
+	 */
+	if (NDISKS > 12) {
+		err += test(11, &tests);
+		err += test(12, &tests);
+	}
 	err += test(NDISKS, &tests);
 
 	pr("\n");
diff -druNp linux-libre-2.6.32-gnu1/crypto/cryptd.c linux-libre-2.6.33-gnu1/crypto/cryptd.c
--- linux-libre-2.6.32-gnu1/crypto/cryptd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/cryptd.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,7 +99,7 @@ static int cryptd_enqueue_request(struct
 	struct cryptd_cpu_queue *cpu_queue;
 
 	cpu = get_cpu();
-	cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+	cpu_queue = this_cpu_ptr(queue->cpu_queue);
 	err = crypto_enqueue_request(&cpu_queue->queue, request);
 	queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
 	put_cpu();
@@ -711,6 +711,13 @@ struct crypto_shash *cryptd_ahash_child(
 }
 EXPORT_SYMBOL_GPL(cryptd_ahash_child);
 
+struct shash_desc *cryptd_shash_desc(struct ahash_request *req)
+{
+	struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
+	return &rctx->desc;
+}
+EXPORT_SYMBOL_GPL(cryptd_shash_desc);
+
 void cryptd_free_ahash(struct cryptd_ahash *tfm)
 {
 	crypto_free_ahash(&tfm->base);
diff -druNp linux-libre-2.6.32-gnu1/crypto/digest.c linux-libre-2.6.33-gnu1/crypto/digest.c
--- linux-libre-2.6.32-gnu1/crypto/digest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/digest.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,240 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Digest operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * 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 <crypto/internal/hash.h>
-#include <crypto/scatterwalk.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/hardirq.h>
-#include <linux/highmem.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/scatterlist.h>
-
-#include "internal.h"
-
-static int init(struct hash_desc *desc)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-
-	tfm->__crt_alg->cra_digest.dia_init(tfm);
-	return 0;
-}
-
-static int update2(struct hash_desc *desc,
-		   struct scatterlist *sg, unsigned int nbytes)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
-
-	if (!nbytes)
-		return 0;
-
-	for (;;) {
-		struct page *pg = sg_page(sg);
-		unsigned int offset = sg->offset;
-		unsigned int l = sg->length;
-
-		if (unlikely(l > nbytes))
-			l = nbytes;
-		nbytes -= l;
-
-		do {
-			unsigned int bytes_from_page = min(l, ((unsigned int)
-							   (PAGE_SIZE)) - 
-							   offset);
-			char *src = crypto_kmap(pg, 0);
-			char *p = src + offset;
-
-			if (unlikely(offset & alignmask)) {
-				unsigned int bytes =
-					alignmask + 1 - (offset & alignmask);
-				bytes = min(bytes, bytes_from_page);
-				tfm->__crt_alg->cra_digest.dia_update(tfm, p,
-								      bytes);
-				p += bytes;
-				bytes_from_page -= bytes;
-				l -= bytes;
-			}
-			tfm->__crt_alg->cra_digest.dia_update(tfm, p,
-							      bytes_from_page);
-			crypto_kunmap(src, 0);
-			crypto_yield(desc->flags);
-			offset = 0;
-			pg++;
-			l -= bytes_from_page;
-		} while (l > 0);
-
-		if (!nbytes)
-			break;
-		sg = scatterwalk_sg_next(sg);
-	}
-
-	return 0;
-}
-
-static int update(struct hash_desc *desc,
-		  struct scatterlist *sg, unsigned int nbytes)
-{
-	if (WARN_ON_ONCE(in_irq()))
-		return -EDEADLK;
-	return update2(desc, sg, nbytes);
-}
-
-static int final(struct hash_desc *desc, u8 *out)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
-	unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
-	struct digest_alg *digest = &tfm->__crt_alg->cra_digest;
-
-	if (unlikely((unsigned long)out & alignmask)) {
-		unsigned long align = alignmask + 1;
-		unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
-		u8 *dst = (u8 *)ALIGN(addr, align) +
-			  ALIGN(tfm->__crt_alg->cra_ctxsize, align);
-
-		digest->dia_final(tfm, dst);
-		memcpy(out, dst, digest->dia_digestsize);
-	} else
-		digest->dia_final(tfm, out);
-
-	return 0;
-}
-
-static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
-{
-	crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
-	return -ENOSYS;
-}
-
-static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(hash);
-
-	crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
-	return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
-}
-
-static int digest(struct hash_desc *desc,
-		  struct scatterlist *sg, unsigned int nbytes, u8 *out)
-{
-	if (WARN_ON_ONCE(in_irq()))
-		return -EDEADLK;
-
-	init(desc);
-	update2(desc, sg, nbytes);
-	return final(desc, out);
-}
-
-int crypto_init_digest_ops(struct crypto_tfm *tfm)
-{
-	struct hash_tfm *ops = &tfm->crt_hash;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	if (dalg->dia_digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-	
-	ops->init	= init;
-	ops->update	= update;
-	ops->final	= final;
-	ops->digest	= digest;
-	ops->setkey	= dalg->dia_setkey ? setkey : nosetkey;
-	ops->digestsize	= dalg->dia_digestsize;
-	
-	return 0;
-}
-
-void crypto_exit_digest_ops(struct crypto_tfm *tfm)
-{
-}
-
-static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
-	return -ENOSYS;
-}
-
-static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	struct crypto_tfm    *tfm        = crypto_ahash_tfm(tfm_async);
-	struct digest_alg    *dalg       = &tfm->__crt_alg->cra_digest;
-
-	crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
-	return dalg->dia_setkey(tfm, key, keylen);
-}
-
-static int digest_async_init(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	dalg->dia_init(tfm);
-	return 0;
-}
-
-static int digest_async_update(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	update(&desc, req->src, req->nbytes);
-	return 0;
-}
-
-static int digest_async_final(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	final(&desc, req->result);
-	return 0;
-}
-
-static int digest_async_digest(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm  = req->base.tfm;
-	struct hash_desc  desc = {
-		.tfm   = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return digest(&desc, req->src, req->nbytes, req->result);
-}
-
-int crypto_init_digest_ops_async(struct crypto_tfm *tfm)
-{
-	struct ahash_tfm  *crt  = &tfm->crt_ahash;
-	struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
-
-	if (dalg->dia_digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-
-	crt->init       = digest_async_init;
-	crt->update     = digest_async_update;
-	crt->final      = digest_async_final;
-	crt->digest     = digest_async_digest;
-	crt->setkey     = dalg->dia_setkey ? digest_async_setkey :
-						digest_async_nosetkey;
-	crt->digestsize = dalg->dia_digestsize;
-
-	return 0;
-}
diff -druNp linux-libre-2.6.32-gnu1/crypto/hash.c linux-libre-2.6.33-gnu1/crypto/hash.c
--- linux-libre-2.6.32-gnu1/crypto/hash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/hash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,183 +0,0 @@
-/*
- * Cryptographic Hash operations.
- * 
- * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
- *
- * 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 <crypto/internal/hash.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-
-#include "internal.h"
-
-static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
-					u32 mask)
-{
-	return alg->cra_ctxsize;
-}
-
-static int hash_setkey_unaligned(struct crypto_hash *crt, const u8 *key,
-		                 unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(crt);
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-	unsigned long alignmask = crypto_hash_alignmask(crt);
-	int ret;
-	u8 *buffer, *alignbuffer;
-	unsigned long absize;
-
-	absize = keylen + alignmask;
-	buffer = kmalloc(absize, GFP_ATOMIC);
-	if (!buffer)
-		return -ENOMEM;
-
-	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
-	memcpy(alignbuffer, key, keylen);
-	ret = alg->setkey(crt, alignbuffer, keylen);
-	memset(alignbuffer, 0, keylen);
-	kfree(buffer);
-	return ret;
-}
-
-static int hash_setkey(struct crypto_hash *crt, const u8 *key,
-		       unsigned int keylen)
-{
-	struct crypto_tfm *tfm = crypto_hash_tfm(crt);
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-	unsigned long alignmask = crypto_hash_alignmask(crt);
-
-	if ((unsigned long)key & alignmask)
-		return hash_setkey_unaligned(crt, key, keylen);
-
-	return alg->setkey(crt, key, keylen);
-}
-
-static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
-			unsigned int keylen)
-{
-	struct crypto_tfm  *tfm      = crypto_ahash_tfm(tfm_async);
-	struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm);
-	struct hash_alg    *alg      = &tfm->__crt_alg->cra_hash;
-
-	return alg->setkey(tfm_hash, key, keylen);
-}
-
-static int hash_async_init(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->init(&desc);
-}
-
-static int hash_async_update(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->update(&desc, req->src, req->nbytes);
-}
-
-static int hash_async_final(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->final(&desc, req->result);
-}
-
-static int hash_async_digest(struct ahash_request *req)
-{
-	struct crypto_tfm *tfm = req->base.tfm;
-	struct hash_alg   *alg = &tfm->__crt_alg->cra_hash;
-	struct hash_desc  desc = {
-		.tfm = __crypto_hash_cast(tfm),
-		.flags = req->base.flags,
-	};
-
-	return alg->digest(&desc, req->src, req->nbytes, req->result);
-}
-
-static int crypto_init_hash_ops_async(struct crypto_tfm *tfm)
-{
-	struct ahash_tfm *crt = &tfm->crt_ahash;
-	struct hash_alg  *alg = &tfm->__crt_alg->cra_hash;
-
-	crt->init       = hash_async_init;
-	crt->update     = hash_async_update;
-	crt->final      = hash_async_final;
-	crt->digest     = hash_async_digest;
-	crt->setkey     = hash_async_setkey;
-	crt->digestsize = alg->digestsize;
-
-	return 0;
-}
-
-static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm)
-{
-	struct hash_tfm *crt = &tfm->crt_hash;
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-
-	crt->init       = alg->init;
-	crt->update     = alg->update;
-	crt->final      = alg->final;
-	crt->digest     = alg->digest;
-	crt->setkey     = hash_setkey;
-	crt->digestsize = alg->digestsize;
-
-	return 0;
-}
-
-static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
-{
-	struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
-
-	if (alg->digestsize > PAGE_SIZE / 8)
-		return -EINVAL;
-
-	if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK)
-		return crypto_init_hash_ops_async(tfm);
-	else
-		return crypto_init_hash_ops_sync(tfm);
-}
-
-static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
-	__attribute__ ((unused));
-static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
-{
-	seq_printf(m, "type         : hash\n");
-	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-	seq_printf(m, "digestsize   : %u\n", alg->cra_hash.digestsize);
-}
-
-const struct crypto_type crypto_hash_type = {
-	.ctxsize = crypto_hash_ctxsize,
-	.init = crypto_init_hash_ops,
-#ifdef CONFIG_PROC_FS
-	.show = crypto_hash_show,
-#endif
-};
-EXPORT_SYMBOL_GPL(crypto_hash_type);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic cryptographic hash type");
diff -druNp linux-libre-2.6.32-gnu1/crypto/Kconfig linux-libre-2.6.33-gnu1/crypto/Kconfig
--- linux-libre-2.6.32-gnu1/crypto/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -440,6 +440,15 @@ config CRYPTO_WP512
 	  See also:
 	  <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html>
 
+config CRYPTO_GHASH_CLMUL_NI_INTEL
+	tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
+	depends on (X86 || UML_X86) && 64BIT
+	select CRYPTO_SHASH
+	select CRYPTO_CRYPTD
+	help
+	  GHASH is message digest algorithm for GCM (Galois/Counter Mode).
+	  The implementation is accelerated by CLMUL-NI of Intel.
+
 comment "Ciphers"
 
 config CRYPTO_AES
diff -druNp linux-libre-2.6.32-gnu1/crypto/proc.c linux-libre-2.6.33-gnu1/crypto/proc.c
--- linux-libre-2.6.32-gnu1/crypto/proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,28 +25,22 @@
 #ifdef CONFIG_CRYPTO_FIPS
 static struct ctl_table crypto_sysctl_table[] = {
 	{
-		.ctl_name       = CTL_UNNUMBERED,
 		.procname       = "fips_enabled",
 		.data           = &fips_enabled,
 		.maxlen         = sizeof(int),
 		.mode           = 0444,
-		.proc_handler   = &proc_dointvec
-	},
-	{
-		.ctl_name = 0,
+		.proc_handler   = proc_dointvec
 	},
+	{}
 };
 
 static struct ctl_table crypto_dir_table[] = {
 	{
-		.ctl_name       = CTL_UNNUMBERED,
 		.procname       = "crypto",
 		.mode           = 0555,
 		.child          = crypto_sysctl_table
 	},
-	{
-		.ctl_name = 0,
-	},
+	{}
 };
 
 static struct ctl_table_header *crypto_sysctls;
@@ -115,13 +109,6 @@ static int c_show(struct seq_file *m, vo
 		seq_printf(m, "max keysize  : %u\n",
 					alg->cra_cipher.cia_max_keysize);
 		break;
-		
-	case CRYPTO_ALG_TYPE_DIGEST:
-		seq_printf(m, "type         : digest\n");
-		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-		seq_printf(m, "digestsize   : %u\n",
-		           alg->cra_digest.dia_digestsize);
-		break;
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		seq_printf(m, "type         : compression\n");
 		break;
diff -druNp linux-libre-2.6.32-gnu1/crypto/testmgr.c linux-libre-2.6.33-gnu1/crypto/testmgr.c
--- linux-libre-2.6.32-gnu1/crypto/testmgr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/testmgr.c	2010-02-24 13:52:17.000000000 -0500
@@ -1201,7 +1201,7 @@ static int test_cprng(struct crypto_rng
 		      unsigned int tcount)
 {
 	const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
-	int err, i, j, seedsize;
+	int err = 0, i, j, seedsize;
 	u8 *seed;
 	char result[32];
 
@@ -1943,6 +1943,15 @@ static const struct alg_test_desc alg_te
 			}
 		}
 	}, {
+		.alg = "ghash",
+		.test = alg_test_hash,
+		.suite = {
+			.hash = {
+				.vecs = ghash_tv_template,
+				.count = GHASH_TEST_VECTORS
+			}
+		}
+	}, {
 		.alg = "hmac(md5)",
 		.test = alg_test_hash,
 		.suite = {
diff -druNp linux-libre-2.6.32-gnu1/crypto/testmgr.h linux-libre-2.6.33-gnu1/crypto/testmgr.h
--- linux-libre-2.6.32-gnu1/crypto/testmgr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/crypto/testmgr.h	2010-02-24 13:52:17.000000000 -0500
@@ -1003,6 +1003,21 @@ static struct hash_testvec tgr128_tv_tem
 	},
 };
 
+#define GHASH_TEST_VECTORS 1
+
+static struct hash_testvec ghash_tv_template[] =
+{
+	{
+
+		.key	= "\xdf\xa6\xbf\x4d\xed\x81\xdb\x03\xff\xca\xff\x95\xf8\x30\xf0\x61",
+		.ksize	= 16,
+		.plaintext = "\x95\x2b\x2a\x56\xa5\x60\x04a\xc0\xb3\x2b\x66\x56\xa0\x5b\x40\xb6",
+		.psize	= 16,
+		.digest	= "\xda\x53\xeb\x0a\xd2\xc5\x5b\xb6"
+			  "\x4f\xc4\x80\x2c\xc3\xfe\xda\x60",
+	},
+};
+
 /*
  * HMAC-MD5 test vectors from RFC2202
  * (These need to be fixed to not use strlen).
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/stable/sysfs-driver-qla2xxx linux-libre-2.6.33-gnu1/Documentation/ABI/stable/sysfs-driver-qla2xxx
--- linux-libre-2.6.32-gnu1/Documentation/ABI/stable/sysfs-driver-qla2xxx	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/stable/sysfs-driver-qla2xxx	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,8 @@
+What:		/sys/bus/pci/drivers/qla2xxx/.../devices/*
+Date:		September 2009
+Contact:	QLogic Linux Driver <linux-driver@qlogic.com>
+Description:	qla2xxx-udev.sh currently looks for uevent CHANGE events to
+		signal a firmware-dump has been generated by the driver and is
+		ready for retrieval.
+Users:		qla2xxx-udev.sh.  Proposed changes should be mailed to
+		linux-driver@qlogic.com
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/ima_policy linux-libre-2.6.33-gnu1/Documentation/ABI/testing/ima_policy
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/ima_policy	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/ima_policy	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,7 @@ Description:
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
 				 [obj_user=] [obj_role=] [obj_type=]]
 
-		base: 	func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
+		base: 	func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK]
 			mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
 			fsmagic:= hex value
 			uid:= decimal value
@@ -40,11 +40,11 @@ Description:
 
 			measure func=BPRM_CHECK
 			measure func=FILE_MMAP mask=MAY_EXEC
-			measure func=INODE_PERM mask=MAY_READ uid=0
+			measure func=FILE_CHECK mask=MAY_READ uid=0
 
 		The default policy measures all executables in bprm_check,
 		all files mmapped executable in file_mmap, and all files
-		open for read by root in inode_permission.
+		open for read by root in do_filp_open.
 
 		Examples of LSM specific definitions:
 
@@ -54,8 +54,8 @@ Description:
 
 			dont_measure obj_type=var_log_t
 			dont_measure obj_type=auditd_log_t
-			measure subj_user=system_u func=INODE_PERM mask=MAY_READ
-			measure subj_role=system_r func=INODE_PERM mask=MAY_READ
+			measure subj_user=system_u func=FILE_CHECK mask=MAY_READ
+			measure subj_role=system_r func=FILE_CHECK mask=MAY_READ
 
 		Smack:
-			measure subj_user=_ func=INODE_PERM mask=MAY_READ
+			measure subj_user=_ func=FILE_CHECK mask=MAY_READ
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/procfs-diskstats linux-libre-2.6.33-gnu1/Documentation/ABI/testing/procfs-diskstats
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/procfs-diskstats	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/procfs-diskstats	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@ Description:
 		 1 - major number
 		 2 - minor mumber
 		 3 - device name
-		 4 - reads completed succesfully
+		 4 - reads completed successfully
 		 5 - reads merged
 		 6 - sectors read
 		 7 - time spent reading (ms)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-block linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-block
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-block	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-block	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@ Contact:	Jerome Marchand <jmarchan@redha
 Description:
 		The /sys/block/<disk>/stat files displays the I/O
 		statistics of disk <disk>. They contain 11 fields:
-		 1 - reads completed succesfully
+		 1 - reads completed successfully
 		 2 - reads merged
 		 3 - sectors read
 		 4 - time spent reading (ms)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-bus-usb linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-bus-usb
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-bus-usb	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-bus-usb	2010-02-24 13:52:17.000000000 -0500
@@ -21,25 +21,27 @@ Contact:	Alan Stern <stern@rowland.harva
 Description:
 		Each USB device directory will contain a file named
 		power/level.  This file holds a power-level setting for
-		the device, one of "on", "auto", or "suspend".
+		the device, either "on" or "auto".
 
 		"on" means that the device is not allowed to autosuspend,
 		although normal suspends for system sleep will still
 		be honored.  "auto" means the device will autosuspend
 		and autoresume in the usual manner, according to the
-		capabilities of its driver.  "suspend" means the device
-		is forced into a suspended state and it will not autoresume
-		in response to I/O requests.  However remote-wakeup requests
-		from the device may still be enabled (the remote-wakeup
-		setting is controlled separately by the power/wakeup
-		attribute).
+		capabilities of its driver.
 
 		During normal use, devices should be left in the "auto"
-		level.  The other levels are meant for administrative uses.
+		level.  The "on" level is meant for administrative uses.
 		If you want to suspend a device immediately but leave it
 		free to wake up in response to I/O requests, you should
 		write "0" to power/autosuspend.
 
+		Device not capable of proper suspend and resume should be
+		left in the "on" level.  Although the USB spec requires
+		devices to support suspend/resume, many of them do not.
+		In fact so many don't that by default, the USB core
+		initializes all non-hub devices in the "on" level.  Some
+		drivers may change this setting when they are bound.
+
 What:		/sys/bus/usb/devices/.../power/persist
 Date:		May 2007
 KernelVersion:	2.6.23
@@ -144,3 +146,16 @@ Description:
 
 		Write a 1 to force the device to disconnect
 		(equivalent to unplugging a wired USB device).
+
+What:		/sys/bus/usb/drivers/.../remove_id
+Date:		November 2009
+Contact:	CHENG Renquan <rqcheng@smu.edu.sg>
+Description:
+		Writing a device ID to this file will remove an ID
+		that was dynamically added via the new_id sysfs entry.
+		The format for the device ID is:
+		idVendor idProduct.	After successfully
+		removing an ID, the driver will no longer support the
+		device.  This is useful to ensure auto probing won't
+		match the driver to the device.  For example:
+		# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc	2010-02-24 13:52:17.000000000 -0500
@@ -23,3 +23,16 @@ Description:
                 Since this relates to security (specifically, the
                 lifetime of PTKs and GTKs) it should not be changed
                 from the default.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate
+Date:           August 2009
+KernelVersion:  2.6.32
+Contact:        David Vrabel <david.vrabel@csr.com>
+Description:
+                The maximum PHY rate to use for all connected devices.
+                This is only of limited use for testing and
+                development as the hardware's automatic rate
+                adaptation is better then this simple control.
+
+                Refer to [ECMA-368] section 10.3.1.1 for the value to
+                use.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-devices-memory linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-memory
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-devices-memory	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-memory	2010-02-24 13:52:17.000000000 -0500
@@ -60,6 +60,19 @@ Description:
 Users:		hotplug memory remove tools
 		https://w3.opensource.ibm.com/projects/powerpc-utils/
 
+
+What:		/sys/devices/system/memoryX/nodeY
+Date:		October 2009
+Contact:	Linux Memory Management list <linux-mm@kvack.org>
+Description:
+		When CONFIG_NUMA is enabled, a symbolic link that
+		points to the corresponding NUMA node directory.
+
+		For example, the following symbolic link is created for
+		memory section 9 on node0:
+		/sys/devices/system/memory/memory9/node0 -> ../../node/node0
+
+
 What:		/sys/devices/system/node/nodeX/memoryY
 Date:		September 2008
 Contact:	Gary Hade <garyhade@us.ibm.com>
@@ -70,4 +83,3 @@ Description:
 		memory section directory.  For example, the following symbolic
 		link is created for memory section 9 on node0.
 		/sys/devices/system/node/node0/memory9 -> ../../memory/memory9
-
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-devices-system-cpu linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-system-cpu
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-devices-system-cpu	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-devices-system-cpu	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,35 @@ Description:	CPU topology files that des
 		See Documentation/cputopology.txt for more information.
 
 
+What:		/sys/devices/system/cpu/probe
+		/sys/devices/system/cpu/release
+Date:		November 2009
+Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:	Dynamic addition and removal of CPU's.  This is not hotplug
+		removal, this is meant complete removal/addition of the CPU
+		from the system.
+
+		probe: writes to this file will dynamically add a CPU to the
+		system.  Information written to the file to add CPU's is
+		architecture specific.
+
+		release: writes to this file dynamically remove a CPU from
+		the system.  Information writtento the file to remove CPU's
+		is architecture specific.
+
+What:		/sys/devices/system/cpu/cpu#/node
+Date:		October 2009
+Contact:	Linux memory management mailing list <linux-mm@kvack.org>
+Description:	Discover NUMA node a CPU belongs to
+
+		When CONFIG_NUMA is enabled, a symbolic link that points
+		to the corresponding NUMA node directory.
+
+		For example, the following symlink is created for cpu42
+		in NUMA node 2:
+
+		/sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
+
 
 What:		/sys/devices/system/cpu/cpu#/node
 Date:		October 2009
@@ -136,6 +165,24 @@ Description:	Discover cpuidle policy and
 		See files in Documentation/cpuidle/ for more information.
 
 
+What:		/sys/devices/system/cpu/cpu#/cpufreq/*
+Date:		pre-git history
+Contact:	cpufreq@vger.kernel.org
+Description:	Discover and change clock speed of CPUs
+
+		Clock scaling allows you to change the clock speed of the
+		CPUs on the fly. This is a nice method to save battery
+		power, because the lower the clock speed, the less power
+		the CPU consumes.
+
+		There are many knobs to tweak in this directory.
+
+		See files in Documentation/cpu-freq/ for more information.
+
+		In particular, read Documentation/cpu-freq/user-guide.txt
+		to learn how to control the knobs.
+
+
 What:      /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
 Date:      August 2008
 KernelVersion:	2.6.27
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-kernel-slab linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-kernel-slab
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-kernel-slab	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-kernel-slab	2010-02-24 13:52:17.000000000 -0500
@@ -45,8 +45,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The alloc_fastpath file is read-only and specifies how many
-		objects have been allocated using the fast path.
+		The alloc_fastpath file shows how many objects have been
+		allocated using the fast path.  It can be written to clear the
+		current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/alloc_from_partial
@@ -55,9 +56,10 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The alloc_from_partial file is read-only and specifies how
-		many times a cpu slab has been full and it has been refilled
-		by using a slab from the list of partially used slabs.
+		The alloc_from_partial file shows how many times a cpu slab has
+		been full and it has been refilled by using a slab from the list
+		of partially used slabs.  It can be written to clear the current
+		count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/alloc_refill
@@ -66,9 +68,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The alloc_refill file is read-only and specifies how many
-		times the per-cpu freelist was empty but there were objects
-		available as the result of remote cpu frees.
+		The alloc_refill file shows how many times the per-cpu freelist
+		was empty but there were objects available as the result of
+		remote cpu frees.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/alloc_slab
@@ -77,8 +79,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The alloc_slab file is read-only and specifies how many times
-		a new slab had to be allocated from the page allocator.
+		The alloc_slab file is shows how many times a new slab had to
+		be allocated from the page allocator.  It can be written to
+		clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/alloc_slowpath
@@ -87,9 +90,10 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The alloc_slowpath file is read-only and specifies how many
-		objects have been allocated using the slow path because of a
-		refill or allocation from a partial or new slab.
+		The alloc_slowpath file shows how many objects have been
+		allocated using the slow path because of a refill or
+		allocation from a partial or new slab.  It can be written to
+		clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/cache_dma
@@ -117,10 +121,11 @@ KernelVersion:	2.6.31
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file cpuslab_flush is read-only and specifies how many
-		times a cache's cpu slabs have been flushed as the result of
-		destroying or shrinking a cache, a cpu going offline, or as
-		the result of forcing an allocation from a certain node.
+		The file cpuslab_flush shows how many times a cache's cpu slabs
+		have been flushed as the result of destroying or shrinking a
+		cache, a cpu going offline, or as the result of forcing an
+		allocation from a certain node.  It can be written to clear the
+		current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/ctor
@@ -139,8 +144,8 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file deactivate_empty is read-only and specifies how many
-		times an empty cpu slab was deactivated.
+		The deactivate_empty file shows how many times an empty cpu slab
+		was deactivated.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/deactivate_full
@@ -149,8 +154,8 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file deactivate_full is read-only and specifies how many
-		times a full cpu slab was deactivated.
+		The deactivate_full file shows how many times a full cpu slab
+		was deactivated.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/deactivate_remote_frees
@@ -159,9 +164,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file deactivate_remote_frees is read-only and specifies how
-		many times a cpu slab has been deactivated and contained free
-		objects that were freed remotely.
+		The deactivate_remote_frees file shows how many times a cpu slab
+		has been deactivated and contained free objects that were freed
+		remotely.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/deactivate_to_head
@@ -170,9 +175,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file deactivate_to_head is read-only and specifies how
-		many times a partial cpu slab was deactivated and added to the
-		head of its node's partial list.
+		The deactivate_to_head file shows how many times a partial cpu
+		slab was deactivated and added to the head of its node's partial
+		list.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/deactivate_to_tail
@@ -181,9 +186,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file deactivate_to_tail is read-only and specifies how
-		many times a partial cpu slab was deactivated and added to the
-		tail of its node's partial list.
+		The deactivate_to_tail file shows how many times a partial cpu
+		slab was deactivated and added to the tail of its node's partial
+		list.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/destroy_by_rcu
@@ -201,9 +206,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file free_add_partial is read-only and specifies how many
-		times an object has been freed in a full slab so that it had to
-		added to its node's partial list.
+		The free_add_partial file shows how many times an object has
+		been freed in a full slab so that it had to added to its node's
+		partial list.  It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/free_calls
@@ -222,9 +227,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The free_fastpath file is read-only and specifies how many
-		objects have been freed using the fast path because it was an
-		object from the cpu slab.
+		The free_fastpath file shows how many objects have been freed
+		using the fast path because it was an object from the cpu slab.
+		It can be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/free_frozen
@@ -233,9 +238,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The free_frozen file is read-only and specifies how many
-		objects have been freed to a frozen slab (i.e. a remote cpu
-		slab).
+		The free_frozen file shows how many objects have been freed to
+		a frozen slab (i.e. a remote cpu slab).  It can be written to
+		clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/free_remove_partial
@@ -244,9 +249,10 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file free_remove_partial is read-only and specifies how
-		many times an object has been freed to a now-empty slab so
-		that it had to be removed from its node's partial list.
+		The free_remove_partial file shows how many times an object has
+		been freed to a now-empty slab so that it had to be removed from
+		its node's partial list.  It can be written to clear the current
+		count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/free_slab
@@ -255,8 +261,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The free_slab file is read-only and specifies how many times an
-		empty slab has been freed back to the page allocator.
+		The free_slab file shows how many times an empty slab has been
+		freed back to the page allocator.  It can be written to clear
+		the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/free_slowpath
@@ -265,9 +272,9 @@ KernelVersion:	2.6.25
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The free_slowpath file is read-only and specifies how many
-		objects have been freed using the slow path (i.e. to a full or
-		partial slab).
+		The free_slowpath file shows how many objects have been freed
+		using the slow path (i.e. to a full or partial slab).  It can
+		be written to clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/hwcache_align
@@ -346,10 +353,10 @@ KernelVersion:	2.6.26
 Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
 		Christoph Lameter <cl@linux-foundation.org>
 Description:
-		The file order_fallback is read-only and specifies how many
-		times an allocation of a new slab has not been possible at the
-		cache's order and instead fallen back to its minimum possible
-		order.
+		The order_fallback file shows how many times an allocation of a
+		new slab has not been possible at the cache's order and instead
+		fallen back to its minimum possible order.  It can be written to
+		clear the current count.
 		Available when CONFIG_SLUB_STATS is enabled.
 
 What:		/sys/kernel/slab/cache/partial
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-memory-page-offline linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-memory-page-offline
--- linux-libre-2.6.32-gnu1/Documentation/ABI/testing/sysfs-memory-page-offline	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ABI/testing/sysfs-memory-page-offline	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,44 @@
+What:		/sys/devices/system/memory/soft_offline_page
+Date:		Sep 2009
+KernelVersion:	2.6.33
+Contact:	andi@firstfloor.org
+Description:
+		Soft-offline the memory page containing the physical address
+		written into this file. Input is a hex number specifying the
+		physical address of the page. The kernel will then attempt
+		to soft-offline it, by moving the contents elsewhere or
+		dropping it if possible. The kernel will then be placed
+		on the bad page list and never be reused.
+
+		The offlining is done in kernel specific granuality.
+		Normally it's the base page size of the kernel, but
+		this might change.
+
+		The page must be still accessible, not poisoned. The
+		kernel will never kill anything for this, but rather
+		fail the offline.  Return value is the size of the
+		number, or a error when the offlining failed.  Reading
+		the file is not allowed.
+
+What:		/sys/devices/system/memory/hard_offline_page
+Date:		Sep 2009
+KernelVersion:	2.6.33
+Contact:	andi@firstfloor.org
+Description:
+		Hard-offline the memory page containing the physical
+		address written into this file. Input is a hex number
+		specifying the physical address of the page. The
+		kernel will then attempt to hard-offline the page, by
+		trying to drop the page or killing any owner or
+		triggering IO errors if needed.  Note this may kill
+		any processes owning the page. The kernel will avoid
+		to access this page assuming it's poisoned by the
+		hardware.
+
+		The offlining is done in kernel specific granuality.
+		Normally it's the base page size of the kernel, but
+		this might change.
+
+		Return value is the size of the number, or a error when
+		the offlining failed.
+		Reading the file is not allowed.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/acpi/method-customizing.txt linux-libre-2.6.33-gnu1/Documentation/acpi/method-customizing.txt
--- linux-libre-2.6.32-gnu1/Documentation/acpi/method-customizing.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/acpi/method-customizing.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,66 @@
+Linux ACPI Custom Control Method How To
+=======================================
+
+Written by Zhang Rui <rui.zhang@intel.com>
+
+
+Linux supports customizing ACPI control methods at runtime.
+
+Users can use this to
+1. override an existing method which may not work correctly,
+   or just for debugging purposes.
+2. insert a completely new method in order to create a missing
+   method such as _OFF, _ON, _STA, _INI, etc.
+For these cases, it is far simpler to dynamically install a single
+control method rather than override the entire DSDT, because kernel
+rebuild/reboot is not needed and test result can be got in minutes.
+
+Note: Only ACPI METHOD can be overridden, any other object types like
+      "Device", "OperationRegion", are not recognized.
+Note: The same ACPI control method can be overridden for many times,
+      and it's always the latest one that used by Linux/kernel.
+
+1. override an existing method
+   a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,
+      just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat"
+   b) disassemble the table by running "iasl -d dsdt.dat".
+   c) rewrite the ASL code of the method and save it in a new file,
+   d) package the new file (psr.asl) to an ACPI table format.
+      Here is an example of a customized \_SB._AC._PSR method,
+
+      DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715)
+      {
+	External (ACON)
+
+	Method (\_SB_.AC._PSR, 0, NotSerialized)
+	{
+		Store ("In AC _PSR", Debug)
+		Return (ACON)
+	}
+      }
+      Note that the full pathname of the method in ACPI namespace
+      should be used.
+      And remember to use "External" to declare external objects.
+   e) assemble the file to generate the AML code of the method.
+      e.g. "iasl psr.asl" (psr.aml is generated as a result)
+   f) mount debugfs by "mount -t debugfs none /sys/kernel/debug"
+   g) override the old method via the debugfs by running
+      "cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method"
+
+2. insert a new method
+   This is easier than overriding an existing method.
+   We just need to create the ASL code of the method we want to
+   insert and then follow the step c) ~ g) in section 1.
+
+3. undo your changes
+   The "undo" operation is not supported for a new inserted method
+   right now, i.e. we can not remove a method currently.
+   For an overrided method, in order to undo your changes, please
+   save a copy of the method original ASL code in step c) section 1,
+   and redo step c) ~ g) to override the method with the original one.
+
+
+Note: We can use a kernel with multiple custom ACPI method running,
+      But each individual write to debugfs can implement a SINGLE
+      method override. i.e. if we want to insert/override multiple
+      ACPI methods, we need to redo step c) ~ g) for multiple times.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/OMAP/DSS linux-libre-2.6.33-gnu1/Documentation/arm/OMAP/DSS
--- linux-libre-2.6.32-gnu1/Documentation/arm/OMAP/DSS	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/OMAP/DSS	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,317 @@
+OMAP2/3 Display Subsystem
+-------------------------
+
+This is an almost total rewrite of the OMAP FB driver in drivers/video/omap
+(let's call it DSS1). The main differences between DSS1 and DSS2 are DSI,
+TV-out and multiple display support, but there are lots of small improvements
+also.
+
+The DSS2 driver (omapdss module) is in arch/arm/plat-omap/dss/, and the FB,
+panel and controller drivers are in drivers/video/omap2/. DSS1 and DSS2 live
+currently side by side, you can choose which one to use.
+
+Features
+--------
+
+Working and tested features include:
+
+- MIPI DPI (parallel) output
+- MIPI DSI output in command mode
+- MIPI DBI (RFBI) output
+- SDI output
+- TV output
+- All pieces can be compiled as a module or inside kernel
+- Use DISPC to update any of the outputs
+- Use CPU to update RFBI or DSI output
+- OMAP DISPC planes
+- RGB16, RGB24 packed, RGB24 unpacked
+- YUV2, UYVY
+- Scaling
+- Adjusting DSS FCK to find a good pixel clock
+- Use DSI DPLL to create DSS FCK
+
+Tested boards include:
+- OMAP3 SDP board
+- Beagle board
+- N810
+
+omapdss driver
+--------------
+
+The DSS driver does not itself have any support for Linux framebuffer, V4L or
+such like the current ones, but it has an internal kernel API that upper level
+drivers can use.
+
+The DSS driver models OMAP's overlays, overlay managers and displays in a
+flexible way to enable non-common multi-display configuration. In addition to
+modelling the hardware overlays, omapdss supports virtual overlays and overlay
+managers. These can be used when updating a display with CPU or system DMA.
+
+Panel and controller drivers
+----------------------------
+
+The drivers implement panel or controller specific functionality and are not
+usually visible to users except through omapfb driver.  They register
+themselves to the DSS driver.
+
+omapfb driver
+-------------
+
+The omapfb driver implements arbitrary number of standard linux framebuffers.
+These framebuffers can be routed flexibly to any overlays, thus allowing very
+dynamic display architecture.
+
+The driver exports some omapfb specific ioctls, which are compatible with the
+ioctls in the old driver.
+
+The rest of the non standard features are exported via sysfs. Whether the final
+implementation will use sysfs, or ioctls, is still open.
+
+V4L2 drivers
+------------
+
+V4L2 is being implemented in TI.
+
+From omapdss point of view the V4L2 drivers should be similar to framebuffer
+driver.
+
+Architecture
+--------------------
+
+Some clarification what the different components do:
+
+    - Framebuffer is a memory area inside OMAP's SRAM/SDRAM that contains the
+      pixel data for the image. Framebuffer has width and height and color
+      depth.
+    - Overlay defines where the pixels are read from and where they go on the
+      screen. The overlay may be smaller than framebuffer, thus displaying only
+      part of the framebuffer. The position of the overlay may be changed if
+      the overlay is smaller than the display.
+    - Overlay manager combines the overlays in to one image and feeds them to
+      display.
+    - Display is the actual physical display device.
+
+A framebuffer can be connected to multiple overlays to show the same pixel data
+on all of the overlays. Note that in this case the overlay input sizes must be
+the same, but, in case of video overlays, the output size can be different. Any
+framebuffer can be connected to any overlay.
+
+An overlay can be connected to one overlay manager. Also DISPC overlays can be
+connected only to DISPC overlay managers, and virtual overlays can be only
+connected to virtual overlays.
+
+An overlay manager can be connected to one display. There are certain
+restrictions which kinds of displays an overlay manager can be connected:
+
+    - DISPC TV overlay manager can be only connected to TV display.
+    - Virtual overlay managers can only be connected to DBI or DSI displays.
+    - DISPC LCD overlay manager can be connected to all displays, except TV
+      display.
+
+Sysfs
+-----
+The sysfs interface is mainly used for testing. I don't think sysfs
+interface is the best for this in the final version, but I don't quite know
+what would be the best interfaces for these things.
+
+The sysfs interface is divided to two parts: DSS and FB.
+
+/sys/class/graphics/fb? directory:
+mirror		0=off, 1=on
+rotate		Rotation 0-3 for 0, 90, 180, 270 degrees
+rotate_type	0 = DMA rotation, 1 = VRFB rotation
+overlays	List of overlay numbers to which framebuffer pixels go
+phys_addr	Physical address of the framebuffer
+virt_addr	Virtual address of the framebuffer
+size		Size of the framebuffer
+
+/sys/devices/platform/omapdss/overlay? directory:
+enabled		0=off, 1=on
+input_size	width,height (ie. the framebuffer size)
+manager		Destination overlay manager name
+name
+output_size	width,height
+position	x,y
+screen_width	width
+global_alpha   	global alpha 0-255 0=transparent 255=opaque
+
+/sys/devices/platform/omapdss/manager? directory:
+display				Destination display
+name
+alpha_blending_enabled		0=off, 1=on
+trans_key_enabled		0=off, 1=on
+trans_key_type			gfx-destination, video-source
+trans_key_value			transparency color key (RGB24)
+default_color			default background color (RGB24)
+
+/sys/devices/platform/omapdss/display? directory:
+ctrl_name	Controller name
+mirror		0=off, 1=on
+update_mode	0=off, 1=auto, 2=manual
+enabled		0=off, 1=on
+name
+rotate		Rotation 0-3 for 0, 90, 180, 270 degrees
+timings		Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw)
+		When writing, two special timings are accepted for tv-out:
+		"pal" and "ntsc"
+panel_name
+tear_elim	Tearing elimination 0=off, 1=on
+
+There are also some debugfs files at <debugfs>/omapdss/ which show information
+about clocks and registers.
+
+Examples
+--------
+
+The following definitions have been made for the examples below:
+
+ovl0=/sys/devices/platform/omapdss/overlay0
+ovl1=/sys/devices/platform/omapdss/overlay1
+ovl2=/sys/devices/platform/omapdss/overlay2
+
+mgr0=/sys/devices/platform/omapdss/manager0
+mgr1=/sys/devices/platform/omapdss/manager1
+
+lcd=/sys/devices/platform/omapdss/display0
+dvi=/sys/devices/platform/omapdss/display1
+tv=/sys/devices/platform/omapdss/display2
+
+fb0=/sys/class/graphics/fb0
+fb1=/sys/class/graphics/fb1
+fb2=/sys/class/graphics/fb2
+
+Default setup on OMAP3 SDP
+--------------------------
+
+Here's the default setup on OMAP3 SDP board. All planes go to LCD. DVI
+and TV-out are not in use. The columns from left to right are:
+framebuffers, overlays, overlay managers, displays. Framebuffers are
+handled by omapfb, and the rest by the DSS.
+
+FB0 --- GFX  -\            DVI
+FB1 --- VID1 --+- LCD ---- LCD
+FB2 --- VID2 -/   TV ----- TV
+
+Example: Switch from LCD to DVI
+----------------------
+
+w=`cat $dvi/timings | cut -d "," -f 2 | cut -d "/" -f 1`
+h=`cat $dvi/timings | cut -d "," -f 3 | cut -d "/" -f 1`
+
+echo "0" > $lcd/enabled
+echo "" > $mgr0/display
+fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h
+# at this point you have to switch the dvi/lcd dip-switch from the omap board
+echo "dvi" > $mgr0/display
+echo "1" > $dvi/enabled
+
+After this the configuration looks like:
+
+FB0 --- GFX  -\         -- DVI
+FB1 --- VID1 --+- LCD -/   LCD
+FB2 --- VID2 -/   TV ----- TV
+
+Example: Clone GFX overlay to LCD and TV
+-------------------------------
+
+w=`cat $tv/timings | cut -d "," -f 2 | cut -d "/" -f 1`
+h=`cat $tv/timings | cut -d "," -f 3 | cut -d "/" -f 1`
+
+echo "0" > $ovl0/enabled
+echo "0" > $ovl1/enabled
+
+echo "" > $fb1/overlays
+echo "0,1" > $fb0/overlays
+
+echo "$w,$h" > $ovl1/output_size
+echo "tv" > $ovl1/manager
+
+echo "1" > $ovl0/enabled
+echo "1" > $ovl1/enabled
+
+echo "1" > $tv/enabled
+
+After this the configuration looks like (only relevant parts shown):
+
+FB0 +-- GFX  ---- LCD ---- LCD
+     \- VID1 ---- TV  ---- TV
+
+Misc notes
+----------
+
+OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator.
+
+Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
+of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
+
+Rotation and mirroring currently only supports RGB565 and RGB8888 modes. VRFB
+does not support mirroring.
+
+VRFB rotation requires much more memory than non-rotated framebuffer, so you
+probably need to increase your vram setting before using VRFB rotation. Also,
+many applications may not work with VRFB if they do not pay attention to all
+framebuffer parameters.
+
+Kernel boot arguments
+---------------------
+
+vram=<size>
+	- Amount of total VRAM to preallocate. For example, "10M". omapfb
+	  allocates memory for framebuffers from VRAM.
+
+omapfb.mode=<display>:<mode>[,...]
+	- Default video mode for specified displays. For example,
+	  "dvi:800x400MR-24@60".  See drivers/video/modedb.c.
+	  There are also two special modes: "pal" and "ntsc" that
+	  can be used to tv out.
+
+omapfb.vram=<fbnum>:<size>[@<physaddr>][,...]
+	- VRAM allocated for a framebuffer. Normally omapfb allocates vram
+	  depending on the display size. With this you can manually allocate
+	  more or define the physical address of each framebuffer. For example,
+	  "1:4M" to allocate 4M for fb1.
+
+omapfb.debug=<y|n>
+	- Enable debug printing. You have to have OMAPFB debug support enabled
+	  in kernel config.
+
+omapfb.test=<y|n>
+	- Draw test pattern to framebuffer whenever framebuffer settings change.
+	  You need to have OMAPFB debug support enabled in kernel config.
+
+omapfb.vrfb=<y|n>
+	- Use VRFB rotation for all framebuffers.
+
+omapfb.rotate=<angle>
+	- Default rotation applied to all framebuffers.
+	  0 - 0 degree rotation
+	  1 - 90 degree rotation
+	  2 - 180 degree rotation
+	  3 - 270 degree rotation
+
+omapfb.mirror=<y|n>
+	- Default mirror for all framebuffers. Only works with DMA rotation.
+
+omapdss.def_disp=<display>
+	- Name of default display, to which all overlays will be connected.
+	  Common examples are "lcd" or "tv".
+
+omapdss.debug=<y|n>
+	- Enable debug printing. You have to have DSS debug support enabled in
+	  kernel config.
+
+TODO
+----
+
+DSS locking
+
+Error checking
+- Lots of checks are missing or implemented just as BUG()
+
+System DMA update for DSI
+- Can be used for RGB16 and RGB24P modes. Probably not for RGB24U (how
+  to skip the empty byte?)
+
+OMAP1 support
+- Not sure if needed
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt	2010-02-24 13:52:17.000000000 -0500
@@ -55,4 +55,4 @@ Maintainers
   This board is maintained by Simtec Electronics.
 
 
-(c) 2004 Ben Dooks, Simtec Electronics
+Copyright 2004 Ben Dooks, Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/GPIO.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/GPIO.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/GPIO.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/GPIO.txt	2010-02-24 13:52:17.000000000 -0500
@@ -134,4 +134,4 @@ Authour
 
 
 Ben Dooks, 03 October 2004
-(c) 2004 Ben Dooks, Simtec Electronics
+Copyright 2004 Ben Dooks, Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/Overview.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/Overview.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/Overview.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/Overview.txt	2010-02-24 13:52:17.000000000 -0500
@@ -299,4 +299,4 @@ Port Contributors
 Document Author
 ---------------
 
-Ben Dooks, (c) 2004-2005,2006 Simtec Electronics
+Ben Dooks, Copyright 2004-2006 Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2412.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2412.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2412.txt	2010-02-24 13:52:17.000000000 -0500
@@ -117,4 +117,4 @@ ATA
 Document Author
 ---------------
 
-Ben Dooks, (c) 2006 Simtec Electronics
+Ben Dooks, Copyright 2006 Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2413.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2413.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2413.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/S3C2413.txt	2010-02-24 13:52:17.000000000 -0500
@@ -18,4 +18,4 @@ Camera Interface
 Document Author
 ---------------
 
-Ben Dooks, (c) 2006 Simtec Electronics
+Ben Dooks, Copyright 2006 Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt	2010-02-24 13:52:17.000000000 -0500
@@ -133,5 +133,5 @@ Configuration
 Document Author
 ---------------
 
-Ben Dooks, (c) 2004 Simtec Electronics
+Ben Dooks, Copyright 2004 Simtec Electronics
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/USB-Host.txt linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/USB-Host.txt
--- linux-libre-2.6.32-gnu1/Documentation/arm/Samsung-S3C24XX/USB-Host.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/arm/Samsung-S3C24XX/USB-Host.txt	2010-02-24 13:52:17.000000000 -0500
@@ -90,4 +90,4 @@ Platform Data
 Document Author
 ---------------
 
-Ben Dooks, (c) 2005 Simtec Electronics
+Ben Dooks, Copyright 2005 Simtec Electronics
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blackfin/00-INDEX linux-libre-2.6.33-gnu1/Documentation/blackfin/00-INDEX
--- linux-libre-2.6.32-gnu1/Documentation/blackfin/00-INDEX	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blackfin/00-INDEX	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,6 @@
 00-INDEX
 	- This file
 
-cache-lock.txt
-	- HOWTO for blackfin cache locking.
-
 cachefeatures.txt
 	- Supported cache features.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blackfin/cachefeatures.txt linux-libre-2.6.33-gnu1/Documentation/blackfin/cachefeatures.txt
--- linux-libre-2.6.32-gnu1/Documentation/blackfin/cachefeatures.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blackfin/cachefeatures.txt	2010-02-24 13:52:17.000000000 -0500
@@ -41,16 +41,6 @@
 		icplb_flush();
 		dcplb_flush();
 
-	- Locking the cache.
-
-		cache_grab_lock();
-		cache_lock();
-
-	Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to
-	lock the cache.
-
-	Locking the cache is optional feature.
-
 	- Miscellaneous cache functions.
 
 		flush_cache_all();
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blackfin/cache-lock.txt linux-libre-2.6.33-gnu1/Documentation/blackfin/cache-lock.txt
--- linux-libre-2.6.32-gnu1/Documentation/blackfin/cache-lock.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blackfin/cache-lock.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/*
- * File:         Documentation/blackfin/cache-lock.txt
- * Based on:
- * Author:
- *
- * Created:
- * Description:  This file contains the simple DMA Implementation for Blackfin
- *
- * Rev:          $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $
- *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- */
-
-How to lock your code in cache in uClinux/blackfin
---------------------------------------------------
-
-There are only a few steps required to lock your code into the cache.
-Currently you can lock the code by Way.
-
-Below are the interface provided for locking the cache.
-
-
-1. cache_grab_lock(int Ways);
-
-This function grab the lock for locking your code into the cache specified
-by Ways.
-
-
-2. cache_lock(int Ways);
-
-This function should be called after your critical code has been executed.
-Once the critical code exits, the code is now loaded into the cache. This
-function locks the code into the cache.
-
-
-So, the example sequence will be:
-
-	cache_grab_lock(WAY0_L);	/* Grab the lock */
-
-	critical_code();		/* Execute the code of interest */
-
-	cache_lock(WAY0_L);		/* Lock the cache */
-
-Where WAY0_L signifies WAY0 locking.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blackfin/gptimers-example.c linux-libre-2.6.33-gnu1/Documentation/blackfin/gptimers-example.c
--- linux-libre-2.6.32-gnu1/Documentation/blackfin/gptimers-example.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blackfin/gptimers-example.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,83 @@
+/*
+ * Simple gptimers example
+ *	http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gptimers
+ *
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/gptimers.h>
+#include <asm/portmux.h>
+
+/* ... random driver includes ... */
+
+#define DRIVER_NAME "gptimer_example"
+
+struct gptimer_data {
+	uint32_t period, width;
+};
+static struct gptimer_data data;
+
+/* ... random driver state ... */
+
+static irqreturn_t gptimer_example_irq(int irq, void *dev_id)
+{
+	struct gptimer_data *data = dev_id;
+
+	/* make sure it was our timer which caused the interrupt */
+	if (!get_gptimer_intr(TIMER5_id))
+		return IRQ_NONE;
+
+	/* read the width/period values that were captured for the waveform */
+	data->width = get_gptimer_pwidth(TIMER5_id);
+	data->period = get_gptimer_period(TIMER5_id);
+
+	/* acknowledge the interrupt */
+	clear_gptimer_intr(TIMER5_id);
+
+	/* tell the upper layers we took care of things */
+	return IRQ_HANDLED;
+}
+
+/* ... random driver code ... */
+
+static int __init gptimer_example_init(void)
+{
+	int ret;
+
+	/* grab the peripheral pins */
+	ret = peripheral_request(P_TMR5, DRIVER_NAME);
+	if (ret) {
+		printk(KERN_NOTICE DRIVER_NAME ": peripheral request failed\n");
+		return ret;
+	}
+
+	/* grab the IRQ for the timer */
+	ret = request_irq(IRQ_TIMER5, gptimer_example_irq, IRQF_SHARED, DRIVER_NAME, &data);
+	if (ret) {
+		printk(KERN_NOTICE DRIVER_NAME ": IRQ request failed\n");
+		peripheral_free(P_TMR5);
+		return ret;
+	}
+
+	/* setup the timer and enable it */
+	set_gptimer_config(TIMER5_id, WDTH_CAP | PULSE_HI | PERIOD_CNT | IRQ_ENA);
+	enable_gptimers(TIMER5bit);
+
+	return 0;
+}
+module_init(gptimer_example_init);
+
+static void __exit gptimer_example_exit(void)
+{
+	disable_gptimers(TIMER5bit);
+	free_irq(IRQ_TIMER5, &data);
+	peripheral_free(P_TMR5);
+}
+module_exit(gptimer_example_exit);
+
+MODULE_LICENSE("BSD");
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blackfin/Makefile linux-libre-2.6.33-gnu1/Documentation/blackfin/Makefile
--- linux-libre-2.6.32-gnu1/Documentation/blackfin/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blackfin/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6 @@
+obj-m := gptimers-example.o
+
+all: modules
+
+modules clean:
+	$(MAKE) -C ../.. SUBDIRS=$(PWD) $@
diff -druNp linux-libre-2.6.32-gnu1/Documentation/block/00-INDEX linux-libre-2.6.33-gnu1/Documentation/block/00-INDEX
--- linux-libre-2.6.32-gnu1/Documentation/block/00-INDEX	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/block/00-INDEX	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,5 @@
 00-INDEX
 	- This file
-as-iosched.txt
-	- Anticipatory IO scheduler
 barrier.txt
 	- I/O Barriers
 biodoc.txt
diff -druNp linux-libre-2.6.32-gnu1/Documentation/block/as-iosched.txt linux-libre-2.6.33-gnu1/Documentation/block/as-iosched.txt
--- linux-libre-2.6.32-gnu1/Documentation/block/as-iosched.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/block/as-iosched.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,172 +0,0 @@
-Anticipatory IO scheduler
--------------------------
-Nick Piggin <piggin@cyberone.com.au>    13 Sep 2003
-
-Attention! Database servers, especially those using "TCQ" disks should
-investigate performance with the 'deadline' IO scheduler. Any system with high
-disk performance requirements should do so, in fact.
-
-If you see unusual performance characteristics of your disk systems, or you
-see big performance regressions versus the deadline scheduler, please email
-me. Database users don't bother unless you're willing to test a lot of patches
-from me ;) its a known issue.
-
-Also, users with hardware RAID controllers, doing striping, may find
-highly variable performance results with using the as-iosched. The
-as-iosched anticipatory implementation is based on the notion that a disk
-device has only one physical seeking head.  A striped RAID controller
-actually has a head for each physical device in the logical RAID device.
-
-However, setting the antic_expire (see tunable parameters below) produces
-very similar behavior to the deadline IO scheduler.
-
-Selecting IO schedulers
------------------------
-Refer to Documentation/block/switching-sched.txt for information on
-selecting an io scheduler on a per-device basis.
-
-Anticipatory IO scheduler Policies
-----------------------------------
-The as-iosched implementation implements several layers of policies
-to determine when an IO request is dispatched to the disk controller.
-Here are the policies outlined, in order of application.
-
-1. one-way Elevator algorithm.
-
-The elevator algorithm is similar to that used in deadline scheduler, with
-the addition that it allows limited backward movement of the elevator
-(i.e. seeks backwards).  A seek backwards can occur when choosing between
-two IO requests where one is behind the elevator's current position, and
-the other is in front of the elevator's position. If the seek distance to
-the request in back of the elevator is less than half the seek distance to
-the request in front of the elevator, then the request in back can be chosen.
-Backward seeks are also limited to a maximum of MAXBACK (1024*1024) sectors.
-This favors forward movement of the elevator, while allowing opportunistic
-"short" backward seeks.
-
-2. FIFO expiration times for reads and for writes.
-
-This is again very similar to the deadline IO scheduler.  The expiration
-times for requests on these lists is tunable using the parameters read_expire
-and write_expire discussed below.  When a read or a write expires in this way,
-the IO scheduler will interrupt its current elevator sweep or read anticipation
-to service the expired request.
-
-3. Read and write request batching
-
-A batch is a collection of read requests or a collection of write
-requests.  The as scheduler alternates dispatching read and write batches
-to the driver.  In the case a read batch, the scheduler submits read
-requests to the driver as long as there are read requests to submit, and
-the read batch time limit has not been exceeded (read_batch_expire).
-The read batch time limit begins counting down only when there are
-competing write requests pending.
-
-In the case of a write batch, the scheduler submits write requests to
-the driver as long as there are write requests available, and the
-write batch time limit has not been exceeded (write_batch_expire).
-However, the length of write batches will be gradually shortened
-when read batches frequently exceed their time limit.
-
-When changing between batch types, the scheduler waits for all requests
-from the previous batch to complete before scheduling requests for the
-next batch.
-
-The read and write fifo expiration times described in policy 2 above
-are checked only when in scheduling IO of a batch for the corresponding
-(read/write) type.  So for example, the read FIFO timeout values are
-tested only during read batches.  Likewise, the write FIFO timeout
-values are tested only during write batches.  For this reason,
-it is generally not recommended for the read batch time
-to be longer than the write expiration time, nor for the write batch
-time to exceed the read expiration time (see tunable parameters below).
-
-When the IO scheduler changes from a read to a write batch,
-it begins the elevator from the request that is on the head of the
-write expiration FIFO.  Likewise, when changing from a write batch to
-a read batch, scheduler begins the elevator from the first entry
-on the read expiration FIFO.
-
-4. Read anticipation.
-
-Read anticipation occurs only when scheduling a read batch.
-This implementation of read anticipation allows only one read request
-to be dispatched to the disk controller at a time.  In
-contrast, many write requests may be dispatched to the disk controller
-at a time during a write batch.  It is this characteristic that can make
-the anticipatory scheduler perform anomalously with controllers supporting
-TCQ, or with hardware striped RAID devices. Setting the antic_expire
-queue parameter (see below) to zero disables this behavior, and the 
-anticipatory scheduler behaves essentially like the deadline scheduler.
-
-When read anticipation is enabled (antic_expire is not zero), reads
-are dispatched to the disk controller one at a time.
-At the end of each read request, the IO scheduler examines its next
-candidate read request from its sorted read list.  If that next request
-is from the same process as the request that just completed,
-or if the next request in the queue is "very close" to the
-just completed request, it is dispatched immediately.  Otherwise,
-statistics (average think time, average seek distance) on the process
-that submitted the just completed request are examined.  If it seems
-likely that that process will submit another request soon, and that
-request is likely to be near the just completed request, then the IO
-scheduler will stop dispatching more read requests for up to (antic_expire)
-milliseconds, hoping that process will submit a new request near the one
-that just completed.  If such a request is made, then it is dispatched
-immediately.  If the antic_expire wait time expires, then the IO scheduler
-will dispatch the next read request from the sorted read queue.
-
-To decide whether an anticipatory wait is worthwhile, the scheduler
-maintains statistics for each process that can be used to compute
-mean "think time" (the time between read requests), and mean seek
-distance for that process.  One observation is that these statistics
-are associated with each process, but those statistics are not associated
-with a specific IO device.  So for example, if a process is doing IO
-on several file systems on separate devices, the statistics will be
-a combination of IO behavior from all those devices.
-
-
-Tuning the anticipatory IO scheduler
-------------------------------------
-When using 'as', the anticipatory IO scheduler there are 5 parameters under
-/sys/block/*/queue/iosched/. All are units of milliseconds.
-
-The parameters are:
-* read_expire
-    Controls how long until a read request becomes "expired". It also controls the
-    interval between which expired requests are served, so set to 50, a request
-    might take anywhere < 100ms to be serviced _if_ it is the next on the
-    expired list. Obviously request expiration strategies won't make the disk
-    go faster. The result basically equates to the timeslice a single reader
-    gets in the presence of other IO. 100*((seek time / read_expire) + 1) is
-    very roughly the % streaming read efficiency your disk should get with
-    multiple readers.
-
-* read_batch_expire
-    Controls how much time a batch of reads is given before pending writes are
-    served. A higher value is more efficient. This might be set below read_expire
-    if writes are to be given higher priority than reads, but reads are to be
-    as efficient as possible when there are no writes. Generally though, it
-    should be some multiple of read_expire.
-
-* write_expire, and
-* write_batch_expire are equivalent to the above, for writes.
-
-* antic_expire
-    Controls the maximum amount of time we can anticipate a good read (one
-    with a short seek distance from the most recently completed request) before
-    giving up. Many other factors may cause anticipation to be stopped early,
-    or some processes will not be "anticipated" at all. Should be a bit higher
-    for big seek time devices though not a linear correspondence - most
-    processes have only a few ms thinktime.
-
-In addition to the tunables above there is a read-only file named est_time
-which, when read, will show:
-
-    - The probability of a task exiting without a cooperating task
-      submitting an anticipated IO.
-
-    - The current mean think time.
-
-    - The seek distance used to determine if an incoming IO is better.
-
diff -druNp linux-libre-2.6.32-gnu1/Documentation/block/biodoc.txt linux-libre-2.6.33-gnu1/Documentation/block/biodoc.txt
--- linux-libre-2.6.32-gnu1/Documentation/block/biodoc.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/block/biodoc.txt	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,7 @@ a virtual address mapping (unlike the ea
 do not have a corresponding kernel virtual address space mapping) and
 low-memory pages.
 
-Note: Please refer to Documentation/DMA-mapping.txt for a discussion
+Note: Please refer to Documentation/PCI/PCI-DMA-mapping.txt for a discussion
 on PCI high mem DMA aspects and mapping of scatter gather lists, and support
 for 64 bit PCI.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/conn-states-8.dot linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/conn-states-8.dot
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/conn-states-8.dot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/conn-states-8.dot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,18 @@
+digraph conn_states {
+	StandAllone  -> WFConnection   [ label = "ioctl_set_net()" ]
+	WFConnection -> Unconnected    [ label = "unable to bind()" ]
+	WFConnection -> WFReportParams [ label = "in connect() after accept" ]
+	WFReportParams -> StandAllone  [ label = "checks in receive_param()" ]
+	WFReportParams -> Connected    [ label = "in receive_param()" ]
+	WFReportParams -> WFBitMapS    [ label = "sync_handshake()" ]
+	WFReportParams -> WFBitMapT    [ label = "sync_handshake()" ]
+	WFBitMapS -> SyncSource        [ label = "receive_bitmap()" ]
+	WFBitMapT -> SyncTarget        [ label = "receive_bitmap()" ]
+	SyncSource -> Connected
+	SyncTarget -> Connected
+	SyncSource -> PausedSyncS
+	SyncTarget -> PausedSyncT
+	PausedSyncS -> SyncSource
+	PausedSyncT -> SyncTarget
+	Connected   -> WFConnection    [ label = "* on network error" ]
+}
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/disk-states-8.dot linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/disk-states-8.dot
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/disk-states-8.dot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/disk-states-8.dot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,16 @@
+digraph disk_states {
+	Diskless -> Inconsistent       [ label = "ioctl_set_disk()" ]
+	Diskless -> Consistent         [ label = "ioctl_set_disk()" ]
+	Diskless -> Outdated           [ label = "ioctl_set_disk()" ]
+	Consistent -> Outdated         [ label = "receive_param()" ]
+	Consistent -> UpToDate         [ label = "receive_param()" ]
+	Consistent -> Inconsistent     [ label = "start resync" ]
+	Outdated   -> Inconsistent     [ label = "start resync" ]
+	UpToDate   -> Inconsistent     [ label = "ioctl_replicate" ]
+	Inconsistent -> UpToDate       [ label = "resync completed" ]
+	Consistent -> Failed           [ label = "io completion error" ]
+	Outdated   -> Failed           [ label = "io completion error" ]
+	UpToDate   -> Failed           [ label = "io completion error" ]
+	Inconsistent -> Failed         [ label = "io completion error" ]
+	Failed -> Diskless             [ label = "sending notify to peer" ]
+}
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/DRBD-8.3-data-packets.svg linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/DRBD-8.3-data-packets.svg
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/DRBD-8.3-data-packets.svg	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/DRBD-8.3-data-packets.svg	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,588 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.0"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 21000 29700"
+   id="svg2"
+   style="fill-rule:evenodd">
+  <defs
+     id="defs4" />
+  <g
+     id="Default"
+     style="visibility:visible">
+    <desc
+       id="desc180">Master slide</desc>
+  </g>
+  <path
+     d="M 11999,8601 L 11899,8301 L 12099,8301 L 11999,8601 z"
+     id="path193"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 11999,7801 L 11999,8361"
+     id="path197"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 7999,10401 L 7899,10101 L 8099,10101 L 7999,10401 z"
+     id="path209"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 7999,9601 L 7999,10161"
+     id="path213"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 11999,7801 L 11685,7840 L 11724,7644 L 11999,7801 z"
+     id="path225"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 7999,7001 L 11764,7754"
+     id="path229"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <g
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,-1244.4792,1416.5139)"
+     id="g245"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text247">
+      <tspan
+         x="9139 9368 9579 9808 9986 10075 10252 10481 10659 10837 10909"
+         y="9284"
+         id="tspan249">RSDataReply</tspan>
+    </text>
+  </g>
+  <path
+     d="M 7999,9601 L 8281,9458 L 8311,9655 L 7999,9601 z"
+     id="path259"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 11999,9001 L 8236,9565"
+     id="path263"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <g
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,1620.9382,-1639.4947)"
+     id="g279"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text281">
+      <tspan
+         x="8743 8972 9132 9310 9573 9801 10013 10242 10419 10597 10775 10953 11114"
+         y="7023"
+         id="tspan283">CsumRSRequest</tspan>
+    </text>
+  </g>
+  <text
+     id="text297"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4034 4263 4440 4703 4881 5042 5219 5397 5503 5681 5842 6003 6180 6341 6519 6625 6803 6980 7158 7336 7497 7586 7692"
+       y="5707"
+       id="tspan299">w_make_resync_request()</tspan>
+  </text>
+  <text
+     id="text313"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12305 12483 12644 12821 12893 13054 13232 13410 13638 13816 13905 14083 14311 14489 14667 14845 15023 15184 15272 15378"
+       y="7806"
+       id="tspan315">receive_DataRequest()</tspan>
+  </text>
+  <text
+     id="text329"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12377 12483 12660 12838 13016 13194 13372 13549 13621 13799 13977 14083 14261 14438 14616 14794 14955 15133 15294 15399"
+       y="8606"
+       id="tspan331">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text345"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12191 12420 12597 12775 12953 13131 13309 13486 13664 13825 13986 14164 14426 14604 14710 14871 15049 15154 15332 15510 15616"
+       y="9007"
+       id="tspan347">w_e_end_csum_rs_req()</tspan>
+  </text>
+  <text
+     id="text361"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4444 4550 4728 4889 5066 5138 5299 5477 5655 5883 6095 6324 6501 6590 6768 6997 7175 7352 7424 7585 7691"
+       y="9507"
+       id="tspan363">receive_RSDataReply()</tspan>
+  </text>
+  <text
+     id="text377"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4457 4635 4741 4918 5096 5274 5452 5630 5807 5879 6057 6235 6464 6569 6641 6730 6908 7086 7247 7425 7585 7691"
+       y="10407"
+       id="tspan379">drbd_endio_write_sec()</tspan>
+  </text>
+  <text
+     id="text393"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4647 4825 5003 5180 5358 5536 5714 5820 5997 6158 6319 6497 6658 6836 7013 7085 7263 7424 7585 7691"
+       y="10907"
+       id="tspan395">e_end_resync_block()</tspan>
+  </text>
+  <path
+     d="M 11999,11601 L 11685,11640 L 11724,11444 L 11999,11601 z"
+     id="path405"
+     style="fill:#000080;visibility:visible" />
+  <path
+     d="M 7999,10801 L 11764,11554"
+     id="path409"
+     style="fill:none;stroke:#000080;visibility:visible" />
+  <g
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,2434.7562,-1674.649)"
+     id="g425"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text427">
+      <tspan
+         x="9320 9621 9726 9798 9887 10065 10277 10438"
+         y="10943"
+         id="tspan429">WriteAck</tspan>
+    </text>
+  </g>
+  <text
+     id="text443"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12377 12555 12644 12821 13033 13105 13283 13444 13604 13816 13977 14138 14244"
+       y="11559"
+       id="tspan445">got_BlockAck()</tspan>
+  </text>
+  <text
+     id="text459"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="7999 8304 8541 8778 8990 9201 9413 9650 10001 10120 10357 10594 10806 11043 11280 11398 11703 11940 12152 12364 12601 12812 12931 13049 13261 13498 13710 13947 14065 14302 14540 14658 14777 14870 15107 15225 15437 15649 15886"
+       y="4877"
+       id="tspan461">Checksum based Resync, case not in sync</tspan>
+  </text>
+  <text
+     id="text475"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="6961 7266 7571 7854 8159 8299 8536 8654 8891 9010 9247 9484 9603 9840 9958 10077 10170 10407"
+       y="2806"
+       id="tspan477">DRBD-8.3 data flow</tspan>
+  </text>
+  <text
+     id="text491"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5190 5419 5596 5774 5952 6113 6291 6468 6646 6824 6985 7146 7324 7586 7692"
+       y="7005"
+       id="tspan493">w_e_send_csum()</tspan>
+  </text>
+  <path
+     d="M 11999,17601 L 11899,17301 L 12099,17301 L 11999,17601 z"
+     id="path503"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 11999,16801 L 11999,17361"
+     id="path507"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 11999,16801 L 11685,16840 L 11724,16644 L 11999,16801 z"
+     id="path519"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 7999,16001 L 11764,16754"
+     id="path523"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <g
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,-2539.5806,1529.3491)"
+     id="g539"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text541">
+      <tspan
+         x="9269 9498 9709 9798 9959 10048 10226 10437 10598 10776"
+         y="18265"
+         id="tspan543">RSIsInSync</tspan>
+    </text>
+  </g>
+  <path
+     d="M 7999,18601 L 8281,18458 L 8311,18655 L 7999,18601 z"
+     id="path553"
+     style="fill:#000080;visibility:visible" />
+  <path
+     d="M 11999,18001 L 8236,18565"
+     id="path557"
+     style="fill:none;stroke:#000080;visibility:visible" />
+  <g
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,3461.4027,-1449.3012)"
+     id="g573"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text575">
+      <tspan
+         x="8743 8972 9132 9310 9573 9801 10013 10242 10419 10597 10775 10953 11114"
+         y="16023"
+         id="tspan577">CsumRSRequest</tspan>
+    </text>
+  </g>
+  <text
+     id="text591"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12305 12483 12644 12821 12893 13054 13232 13410 13638 13816 13905 14083 14311 14489 14667 14845 15023 15184 15272 15378"
+       y="16806"
+       id="tspan593">receive_DataRequest()</tspan>
+  </text>
+  <text
+     id="text607"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12377 12483 12660 12838 13016 13194 13372 13549 13621 13799 13977 14083 14261 14438 14616 14794 14955 15133 15294 15399"
+       y="17606"
+       id="tspan609">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text623"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12191 12420 12597 12775 12953 13131 13309 13486 13664 13825 13986 14164 14426 14604 14710 14871 15049 15154 15332 15510 15616"
+       y="18007"
+       id="tspan625">w_e_end_csum_rs_req()</tspan>
+  </text>
+  <text
+     id="text639"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5735 5913 6091 6180 6357 6446 6607 6696 6874 7085 7246 7424 7585 7691"
+       y="18507"
+       id="tspan641">got_IsInSync()</tspan>
+  </text>
+  <text
+     id="text655"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="7999 8304 8541 8778 8990 9201 9413 9650 10001 10120 10357 10594 10806 11043 11280 11398 11703 11940 12152 12364 12601 12812 12931 13049 13261 13498 13710 13947 14065 14159 14396 14514 14726 14937 15175"
+       y="13877"
+       id="tspan657">Checksum based Resync, case in sync</tspan>
+  </text>
+  <path
+     d="M 12000,24601 L 11900,24301 L 12100,24301 L 12000,24601 z"
+     id="path667"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 12000,23801 L 12000,24361"
+     id="path671"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 8000,26401 L 7900,26101 L 8100,26101 L 8000,26401 z"
+     id="path683"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,25601 L 8000,26161"
+     id="path687"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 12000,23801 L 11686,23840 L 11725,23644 L 12000,23801 z"
+     id="path699"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,23001 L 11765,23754"
+     id="path703"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <g
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,-3543.8452,1630.5143)"
+     id="g719"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text721">
+      <tspan
+         x="9464 9710 9921 10150 10328 10505 10577"
+         y="25236"
+         id="tspan723">OVReply</tspan>
+    </text>
+  </g>
+  <path
+     d="M 8000,25601 L 8282,25458 L 8312,25655 L 8000,25601 z"
+     id="path733"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 12000,25001 L 8237,25565"
+     id="path737"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <g
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,4918.2801,-1381.2128)"
+     id="g753"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text755">
+      <tspan
+         x="9142 9388 9599 9828 10006 10183 10361 10539 10700"
+         y="23106"
+         id="tspan757">OVRequest</tspan>
+    </text>
+  </g>
+  <text
+     id="text771"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12306 12484 12645 12822 12894 13055 13233 13411 13656 13868 14097 14274 14452 14630 14808 14969 15058 15163"
+       y="23806"
+       id="tspan773">receive_OVRequest()</tspan>
+  </text>
+  <text
+     id="text787"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12378 12484 12661 12839 13017 13195 13373 13550 13622 13800 13978 14084 14262 14439 14617 14795 14956 15134 15295 15400"
+       y="24606"
+       id="tspan789">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text803"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12192 12421 12598 12776 12954 13132 13310 13487 13665 13843 14004 14182 14288 14465 14643 14749"
+       y="25007"
+       id="tspan805">w_e_end_ov_req()</tspan>
+  </text>
+  <text
+     id="text819"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5101 5207 5385 5546 5723 5795 5956 6134 6312 6557 6769 6998 7175 7353 7425 7586 7692"
+       y="25507"
+       id="tspan821">receive_OVReply()</tspan>
+  </text>
+  <text
+     id="text835"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4492 4670 4776 4953 5131 5309 5487 5665 5842 5914 6092 6270 6376 6554 6731 6909 7087 7248 7426 7587 7692"
+       y="26407"
+       id="tspan837">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text851"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4902 5131 5308 5486 5664 5842 6020 6197 6375 6553 6714 6892 6998 7175 7353 7425 7586 7692"
+       y="26907"
+       id="tspan853">w_e_end_ov_reply()</tspan>
+  </text>
+  <path
+     d="M 12000,27601 L 11686,27640 L 11725,27444 L 12000,27601 z"
+     id="path863"
+     style="fill:#000080;visibility:visible" />
+  <path
+     d="M 8000,26801 L 11765,27554"
+     id="path867"
+     style="fill:none;stroke:#000080;visibility:visible" />
+  <g
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,5704.1907,-1328.312)"
+     id="g883"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <text
+       id="text885">
+      <tspan
+         x="9279 9525 9736 9965 10143 10303 10481 10553"
+         y="26935"
+         id="tspan887">OVResult</tspan>
+    </text>
+  </g>
+  <text
+     id="text901"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12378 12556 12645 12822 13068 13280 13508 13686 13847 14025 14097 14185 14291"
+       y="27559"
+       id="tspan903">got_OVResult()</tspan>
+  </text>
+  <text
+     id="text917"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="8000 8330 8567 8660 8754 8991 9228 9346 9558 9795 9935 10028 10146"
+       y="21877"
+       id="tspan919">Online verify</tspan>
+  </text>
+  <text
+     id="text933"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4641 4870 5047 5310 5488 5649 5826 6004 6182 6343 6521 6626 6804 6982 7160 7338 7499 7587 7693"
+       y="23005"
+       id="tspan935">w_make_ov_request()</tspan>
+  </text>
+  <path
+     d="M 8000,6500 L 7900,6200 L 8100,6200 L 8000,6500 z"
+     id="path945"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,5700 L 8000,6260"
+     id="path949"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 3900,5500 L 3700,5500 L 3700,11000 L 3900,11000"
+     id="path961"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 3900,14500 L 3700,14500 L 3700,18600 L 3900,18600"
+     id="path973"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 3900,22800 L 3700,22800 L 3700,26900 L 3900,26900"
+     id="path985"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <text
+     id="text1001"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4492 4670 4776 4953 5131 5309 5487 5665 5842 5914 6092 6270 6376 6554 6731 6909 7087 7248 7426 7587 7692"
+       y="6506"
+       id="tspan1003">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text1017"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4034 4263 4440 4703 4881 5042 5219 5397 5503 5681 5842 6003 6180 6341 6519 6625 6803 6980 7158 7336 7497 7586 7692"
+       y="14708"
+       id="tspan1019">w_make_resync_request()</tspan>
+  </text>
+  <text
+     id="text1033"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5190 5419 5596 5774 5952 6113 6291 6468 6646 6824 6985 7146 7324 7586 7692"
+       y="16006"
+       id="tspan1035">w_e_send_csum()</tspan>
+  </text>
+  <path
+     d="M 8000,15501 L 7900,15201 L 8100,15201 L 8000,15501 z"
+     id="path1045"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,14701 L 8000,15261"
+     id="path1049"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     id="text1065"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4492 4670 4776 4953 5131 5309 5487 5665 5842 5914 6092 6270 6376 6554 6731 6909 7087 7248 7426 7587 7692"
+       y="15507"
+       id="tspan1067">drbd_endio_read_sec()</tspan>
+  </text>
+  <path
+     d="M 16100,9000 L 16300,9000 L 16300,7500 L 16100,7500"
+     id="path1077"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 16100,18000 L 16300,18000 L 16300,16500 L 16100,16500"
+     id="path1089"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 16100,25000 L 16300,25000 L 16300,23500 L 16100,23500"
+     id="path1101"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <text
+     id="text1117"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="2026 2132 2293 2471 2648 2826 3004 3076 3254 3431 3503 3681 3787"
+       y="5402"
+       id="tspan1119">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1133"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="2027 2133 2294 2472 2649 2827 3005 3077 3255 3432 3504 3682 3788"
+       y="14402"
+       id="tspan1135">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1149"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="2026 2132 2293 2471 2648 2826 3004 3076 3254 3431 3503 3681 3787"
+       y="22602"
+       id="tspan1151">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1165"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="1426 1532 1693 1871 2031 2209 2472 2649 2721 2899 2988 3166 3344 3416 3593 3699"
+       y="11302"
+       id="tspan1167">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1181"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="1526 1632 1793 1971 2131 2309 2572 2749 2821 2999 3088 3266 3444 3516 3693 3799"
+       y="18931"
+       id="tspan1183">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1197"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="1526 1632 1793 1971 2131 2309 2572 2749 2821 2999 3088 3266 3444 3516 3693 3799"
+       y="27231"
+       id="tspan1199">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1213"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16126 16232 16393 16571 16748 16926 17104 17176 17354 17531 17603 17781 17887"
+       y="7402"
+       id="tspan1215">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1229"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16127 16233 16394 16572 16749 16927 17105 17177 17355 17532 17604 17782 17888"
+       y="16331"
+       id="tspan1231">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1245"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16127 16233 16394 16572 16749 16927 17105 17177 17355 17532 17604 17782 17888"
+       y="23302"
+       id="tspan1247">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1261"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16115 16221 16382 16560 16720 16898 17161 17338 17410 17588 17677 17855 18033 18105 18282 18388"
+       y="9302"
+       id="tspan1263">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1277"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16115 16221 16382 16560 16720 16898 17161 17338 17410 17588 17677 17855 18033 18105 18282 18388"
+       y="18331"
+       id="tspan1279">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1293"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16126 16232 16393 16571 16731 16909 17172 17349 17421 17599 17688 17866 18044 18116 18293 18399"
+       y="25302"
+       id="tspan1295">rs_complete_io()</tspan>
+  </text>
+</svg>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/drbd-connection-state-overview.dot linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/drbd-connection-state-overview.dot
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/drbd-connection-state-overview.dot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/drbd-connection-state-overview.dot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,85 @@
+// vim: set sw=2 sts=2 :
+digraph {
+  rankdir=BT
+  bgcolor=white
+
+  node [shape=plaintext]
+  node [fontcolor=black]
+
+  StandAlone     [ style=filled,fillcolor=gray,label=StandAlone ]
+
+  node [fontcolor=lightgray]
+
+  Unconnected    [ label=Unconnected ]
+
+  CommTrouble [ shape=record,
+    label="{communication loss|{Timeout|BrokenPipe|NetworkFailure}}" ]
+
+  node [fontcolor=gray]
+
+  subgraph cluster_try_connect {
+    label="try to connect, handshake"
+    rank=max
+    WFConnection   [ label=WFConnection ]
+    WFReportParams [ label=WFReportParams ]
+  }
+
+  TearDown       [ label=TearDown ]
+
+  Connected      [ label=Connected,style=filled,fillcolor=green,fontcolor=black ]
+
+  node [fontcolor=lightblue]
+
+  StartingSyncS  [ label=StartingSyncS ]
+  StartingSyncT  [ label=StartingSyncT ]
+
+  subgraph cluster_bitmap_exchange {
+    node [fontcolor=red]
+    fontcolor=red
+    label="new application (WRITE?) requests blocked\lwhile bitmap is exchanged"
+
+    WFBitMapT      [ label=WFBitMapT ]
+    WFSyncUUID     [ label=WFSyncUUID ]
+    WFBitMapS      [ label=WFBitMapS ]
+  }
+
+  node [fontcolor=blue]
+
+  cluster_resync [ shape=record,label="{<any>resynchronisation process running\l'concurrent' application requests allowed|{{<T>PausedSyncT\nSyncTarget}|{<S>PausedSyncS\nSyncSource}}}" ]
+
+  node [shape=box,fontcolor=black]
+
+  // drbdadm [label="drbdadm connect"]
+  // handshake [label="drbd_connect()\ndrbd_do_handshake\ndrbd_sync_handshake() etc."]
+  // comm_error [label="communication trouble"]
+
+  //
+  // edges
+  // --------------------------------------
+
+  StandAlone -> Unconnected [ label="drbdadm connect" ]
+  Unconnected -> StandAlone  [ label="drbdadm disconnect\lor serious communication trouble" ]
+  Unconnected -> WFConnection [ label="receiver thread is started" ]
+  WFConnection -> WFReportParams [ headlabel="accept()\land/or                        \lconnect()\l" ]
+
+  WFReportParams -> StandAlone [ label="during handshake\lpeers do not agree\labout something essential" ]
+  WFReportParams -> Connected [ label="data identical\lno sync needed",color=green,fontcolor=green ]
+
+    WFReportParams -> WFBitMapS
+    WFReportParams -> WFBitMapT
+    WFBitMapT -> WFSyncUUID [minlen=0.1,constraint=false]
+
+      WFBitMapS -> cluster_resync:S
+      WFSyncUUID -> cluster_resync:T
+
+  edge [color=green]
+  cluster_resync:any -> Connected [ label="resnyc done",fontcolor=green ]
+
+  edge [color=red]
+  WFReportParams -> CommTrouble
+  Connected -> CommTrouble
+  cluster_resync:any -> CommTrouble
+  edge [color=black]
+  CommTrouble -> Unconnected [label="receiver thread is stopped" ]
+
+}
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/DRBD-data-packets.svg linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/DRBD-data-packets.svg
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/DRBD-data-packets.svg	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/DRBD-data-packets.svg	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.0"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 21000 29700"
+   id="svg2"
+   style="fill-rule:evenodd">
+  <defs
+     id="defs4" />
+  <g
+     id="Default"
+     style="visibility:visible">
+    <desc
+       id="desc176">Master slide</desc>
+  </g>
+  <path
+     d="M 11999,19601 L 11899,19301 L 12099,19301 L 11999,19601 z"
+     id="path189"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 11999,18801 L 11999,19361"
+     id="path193"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 7999,21401 L 7899,21101 L 8099,21101 L 7999,21401 z"
+     id="path205"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 7999,20601 L 7999,21161"
+     id="path209"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 11999,18801 L 11685,18840 L 11724,18644 L 11999,18801 z"
+     id="path221"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 7999,18001 L 11764,18754"
+     id="path225"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     x="-3023.845"
+     y="1106.8124"
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,0,0)"
+     id="text243"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="6115.1553 6344.1553 6555.1553 6784.1553 6962.1553 7051.1553 7228.1553 7457.1553 7635.1553 7813.1553 7885.1553"
+       y="21390.812"
+       id="tspan245">RSDataReply</tspan>
+  </text>
+  <path
+     d="M 7999,20601 L 8281,20458 L 8311,20655 L 7999,20601 z"
+     id="path255"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 11999,20001 L 8236,20565"
+     id="path259"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     x="3502.5356"
+     y="-2184.6621"
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,0,0)"
+     id="text277"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12321.536 12550.536 12761.536 12990.536 13168.536 13257.536 13434.536 13663.536 13841.536 14019.536 14196.536 14374.536 14535.536"
+       y="15854.338"
+       id="tspan279">RSDataRequest</tspan>
+  </text>
+  <text
+     id="text293"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4034 4263 4440 4703 4881 5042 5219 5397 5503 5681 5842 6003 6180 6341 6519 6625 6803 6980 7158 7336 7497 7586 7692"
+       y="17807"
+       id="tspan295">w_make_resync_request()</tspan>
+  </text>
+  <text
+     id="text309"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12305 12483 12644 12821 12893 13054 13232 13410 13638 13816 13905 14083 14311 14489 14667 14845 15023 15184 15272 15378"
+       y="18806"
+       id="tspan311">receive_DataRequest()</tspan>
+  </text>
+  <text
+     id="text325"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12377 12483 12660 12838 13016 13194 13372 13549 13621 13799 13977 14083 14261 14438 14616 14794 14955 15133 15294 15399"
+       y="19606"
+       id="tspan327">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text341"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12191 12420 12597 12775 12953 13131 13309 13486 13664 13770 13931 14109 14287 14375 14553 14731 14837 15015 15192 15298"
+       y="20007"
+       id="tspan343">w_e_end_rsdata_req()</tspan>
+  </text>
+  <text
+     id="text357"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4444 4550 4728 4889 5066 5138 5299 5477 5655 5883 6095 6324 6501 6590 6768 6997 7175 7352 7424 7585 7691"
+       y="20507"
+       id="tspan359">receive_RSDataReply()</tspan>
+  </text>
+  <text
+     id="text373"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4457 4635 4741 4918 5096 5274 5452 5630 5807 5879 6057 6235 6464 6569 6641 6730 6908 7086 7247 7425 7585 7691"
+       y="21407"
+       id="tspan375">drbd_endio_write_sec()</tspan>
+  </text>
+  <text
+     id="text389"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4647 4825 5003 5180 5358 5536 5714 5820 5997 6158 6319 6497 6658 6836 7013 7085 7263 7424 7585 7691"
+       y="21907"
+       id="tspan391">e_end_resync_block()</tspan>
+  </text>
+  <path
+     d="M 11999,22601 L 11685,22640 L 11724,22444 L 11999,22601 z"
+     id="path401"
+     style="fill:#000080;visibility:visible" />
+  <path
+     d="M 7999,21801 L 11764,22554"
+     id="path405"
+     style="fill:none;stroke:#000080;visibility:visible" />
+  <text
+     x="4290.3008"
+     y="-2369.6162"
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,0,0)"
+     id="text423"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="13610.301 13911.301 14016.301 14088.301 14177.301 14355.301 14567.301 14728.301"
+       y="19573.385"
+       id="tspan425">WriteAck</tspan>
+  </text>
+  <text
+     id="text439"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12199 12377 12555 12644 12821 13033 13105 13283 13444 13604 13816 13977 14138 14244"
+       y="22559"
+       id="tspan441">got_BlockAck()</tspan>
+  </text>
+  <text
+     id="text455"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="7999 8304 8541 8753 8964 9201 9413 9531 9769 9862 10099 10310 10522 10734 10852 10971 11208 11348 11585 11822"
+       y="16877"
+       id="tspan457">Resync blocks, 4-32K</tspan>
+  </text>
+  <path
+     d="M 12000,7601 L 11900,7301 L 12100,7301 L 12000,7601 z"
+     id="path467"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 12000,6801 L 12000,7361"
+     id="path471"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 12000,6801 L 11686,6840 L 11725,6644 L 12000,6801 z"
+     id="path483"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,6001 L 11765,6754"
+     id="path487"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     x="-1288.1796"
+     y="1279.7666"
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,0,0)"
+     id="text505"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="8174.8208 8475.8203 8580.8203 8652.8203 8741.8203 8919.8203 9131.8203 9292.8203"
+       y="9516.7666"
+       id="tspan507">WriteAck</tspan>
+  </text>
+  <path
+     d="M 8000,8601 L 8282,8458 L 8312,8655 L 8000,8601 z"
+     id="path517"
+     style="fill:#000080;visibility:visible" />
+  <path
+     d="M 12000,8001 L 8237,8565"
+     id="path521"
+     style="fill:none;stroke:#000080;visibility:visible" />
+  <text
+     x="1065.6655"
+     y="-2097.7664"
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,0,0)"
+     id="text539"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="10682.666 10911.666 11088.666 11177.666"
+       y="4107.2339"
+       id="tspan541">Data</tspan>
+  </text>
+  <text
+     id="text555"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4746 4924 5030 5207 5385 5563 5826 6003 6164 6342 6520 6626 6803 6981 7159 7337 7498 7587 7692"
+       y="5505"
+       id="tspan557">drbd_make_request()</tspan>
+  </text>
+  <text
+     id="text571"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12306 12484 12645 12822 12894 13055 13233 13411 13639 13817 13906 14084 14190"
+       y="6806"
+       id="tspan573">receive_Data()</tspan>
+  </text>
+  <text
+     id="text587"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12378 12484 12661 12839 13017 13195 13373 13550 13622 13800 13978 14207 14312 14384 14473 14651 14829 14990 15168 15328 15434"
+       y="7606"
+       id="tspan589">drbd_endio_write_sec()</tspan>
+  </text>
+  <text
+     id="text603"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12192 12370 12548 12725 12903 13081 13259 13437 13509 13686 13847 14008 14114"
+       y="8007"
+       id="tspan605">e_end_block()</tspan>
+  </text>
+  <text
+     id="text619"
+     style="font-size:318px;font-weight:400;fill:#000080;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5647 5825 6003 6092 6269 6481 6553 6731 6892 7052 7264 7425 7586 7692"
+       y="8606"
+       id="tspan621">got_BlockAck()</tspan>
+  </text>
+  <text
+     id="text635"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="8000 8305 8542 8779 9016 9109 9346 9486 9604 9956 10049 10189 10328 10565 10705 10942 11179 11298 11603 11742 11835 11954 12191 12310 12428 12665 12902 13139 13279 13516 13753"
+       y="4877"
+       id="tspan637">Regular mirrored write, 512-32K</tspan>
+  </text>
+  <text
+     id="text651"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5381 5610 5787 5948 6126 6304 6482 6659 6837 7015 7087 7265 7426 7587 7692"
+       y="6003"
+       id="tspan653">w_send_dblock()</tspan>
+  </text>
+  <path
+     d="M 8000,6800 L 7900,6500 L 8100,6500 L 8000,6800 z"
+     id="path663"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,6000 L 8000,6560"
+     id="path667"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     id="text683"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4602 4780 4886 5063 5241 5419 5597 5775 5952 6024 6202 6380 6609 6714 6786 6875 7053 7231 7409 7515 7587 7692"
+       y="6905"
+       id="tspan685">drbd_endio_write_pri()</tspan>
+  </text>
+  <path
+     d="M 12000,13602 L 11900,13302 L 12100,13302 L 12000,13602 z"
+     id="path695"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 12000,12802 L 12000,13362"
+     id="path699"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <path
+     d="M 12000,12802 L 11686,12841 L 11725,12645 L 12000,12802 z"
+     id="path711"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 8000,12002 L 11765,12755"
+     id="path715"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     x="-2155.5266"
+     y="1201.5964"
+     transform="matrix(0.9895258,-0.1443562,0.1443562,0.9895258,0,0)"
+     id="text733"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="7202.4736 7431.4736 7608.4736 7697.4736 7875.4736 8104.4736 8282.4736 8459.4736 8531.4736"
+       y="15454.597"
+       id="tspan735">DataReply</tspan>
+  </text>
+  <path
+     d="M 8000,14602 L 8282,14459 L 8312,14656 L 8000,14602 z"
+     id="path745"
+     style="fill:#008000;visibility:visible" />
+  <path
+     d="M 12000,14002 L 8237,14566"
+     id="path749"
+     style="fill:none;stroke:#008000;visibility:visible" />
+  <text
+     x="2280.3804"
+     y="-2103.2141"
+     transform="matrix(0.9788674,0.2044961,-0.2044961,0.9788674,0,0)"
+     id="text767"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="11316.381 11545.381 11722.381 11811.381 11989.381 12218.381 12396.381 12573.381 12751.381 12929.381 13090.381"
+       y="9981.7861"
+       id="tspan769">DataRequest</tspan>
+  </text>
+  <text
+     id="text783"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="4746 4924 5030 5207 5385 5563 5826 6003 6164 6342 6520 6626 6803 6981 7159 7337 7498 7587 7692"
+       y="11506"
+       id="tspan785">drbd_make_request()</tspan>
+  </text>
+  <text
+     id="text799"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12306 12484 12645 12822 12894 13055 13233 13411 13639 13817 13906 14084 14312 14490 14668 14846 15024 15185 15273 15379"
+       y="12807"
+       id="tspan801">receive_DataRequest()</tspan>
+  </text>
+  <text
+     id="text815"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12200 12378 12484 12661 12839 13017 13195 13373 13550 13622 13800 13978 14084 14262 14439 14617 14795 14956 15134 15295 15400"
+       y="13607"
+       id="tspan817">drbd_endio_read_sec()</tspan>
+  </text>
+  <text
+     id="text831"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="12192 12421 12598 12776 12954 13132 13310 13487 13665 13843 14021 14110 14288 14465 14571 14749 14927 15033"
+       y="14008"
+       id="tspan833">w_e_end_data_req()</tspan>
+  </text>
+  <g
+     id="g835"
+     style="visibility:visible">
+    <desc
+       id="desc837">Drawing</desc>
+    <text
+       id="text847"
+       style="font-size:318px;font-weight:400;fill:#008000;font-family:Helvetica embedded">
+      <tspan
+         x="4885 4991 5169 5330 5507 5579 5740 5918 6096 6324 6502 6591 6769 6997 7175 7353 7425 7586 7692"
+         y="14607"
+         id="tspan849">receive_DataReply()</tspan>
+    </text>
+  </g>
+  <text
+     id="text863"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="8000 8305 8398 8610 8821 8914 9151 9363 9575 9693 9833 10070 10307 10544 10663 10781 11018 11255 11493 11632 11869 12106"
+       y="10878"
+       id="tspan865">Diskless read, 512-32K</tspan>
+  </text>
+  <text
+     id="text879"
+     style="font-size:318px;font-weight:400;fill:#008000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="5029 5258 5435 5596 5774 5952 6130 6307 6413 6591 6769 6947 7125 7230 7408 7586 7692"
+       y="12004"
+       id="tspan881">w_send_read_req()</tspan>
+  </text>
+  <text
+     id="text895"
+     style="font-size:423px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="6961 7266 7571 7854 8159 8278 8515 8633 8870 9107 9226 9463 9581 9700 9793 10030"
+       y="2806"
+       id="tspan897">DRBD 8 data flow</tspan>
+  </text>
+  <path
+     d="M 3900,5300 L 3700,5300 L 3700,7000 L 3900,7000"
+     id="path907"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 3900,17600 L 3700,17600 L 3700,22000 L 3900,22000"
+     id="path919"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <path
+     d="M 16100,20000 L 16300,20000 L 16300,18500 L 16100,18500"
+     id="path931"
+     style="fill:none;stroke:#000000;visibility:visible" />
+  <text
+     id="text947"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="2126 2304 2376 2554 2731 2909 3087 3159 3337 3515 3587 3764 3870"
+       y="5202"
+       id="tspan949">al_begin_io()</tspan>
+  </text>
+  <text
+     id="text963"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="1632 1810 1882 2060 2220 2398 2661 2839 2910 3088 3177 3355 3533 3605 3783 3888"
+       y="7331"
+       id="tspan965">al_complete_io()</tspan>
+  </text>
+  <text
+     id="text979"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="2126 2232 2393 2571 2748 2926 3104 3176 3354 3531 3603 3781 3887"
+       y="17431"
+       id="tspan981">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text995"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="1626 1732 1893 2071 2231 2409 2672 2849 2921 3099 3188 3366 3544 3616 3793 3899"
+       y="22331"
+       id="tspan997">rs_complete_io()</tspan>
+  </text>
+  <text
+     id="text1011"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16027 16133 16294 16472 16649 16827 17005 17077 17255 17432 17504 17682 17788"
+       y="18402"
+       id="tspan1013">rs_begin_io()</tspan>
+  </text>
+  <text
+     id="text1027"
+     style="font-size:318px;font-weight:400;fill:#000000;visibility:visible;font-family:Helvetica embedded">
+    <tspan
+       x="16115 16221 16382 16560 16720 16898 17161 17338 17410 17588 17677 17855 18033 18105 18282 18388"
+       y="20331"
+       id="tspan1029">rs_complete_io()</tspan>
+  </text>
+</svg>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/node-states-8.dot linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/node-states-8.dot
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/node-states-8.dot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/node-states-8.dot	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,14 @@
+digraph node_states {
+	Secondary -> Primary           [ label = "ioctl_set_state()" ]
+	Primary   -> Secondary 	       [ label = "ioctl_set_state()" ]
+}
+
+digraph peer_states {
+	Secondary -> Primary           [ label = "recv state packet" ]
+	Primary   -> Secondary 	       [ label = "recv state packet" ]
+	Primary   -> Unknown 	       [ label = "connection lost" ]
+	Secondary  -> Unknown  	       [ label = "connection lost" ]
+	Unknown   -> Primary           [ label = "connected" ]
+	Unknown   -> Secondary         [ label = "connected" ]
+}
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/README.txt linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/README.txt
--- linux-libre-2.6.32-gnu1/Documentation/blockdev/drbd/README.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/blockdev/drbd/README.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,16 @@
+Description
+
+  DRBD is a shared-nothing, synchronously replicated block device. It
+  is designed to serve as a building block for high availability
+  clusters and in this context, is a "drop-in" replacement for shared
+  storage. Simplistically, you could see it as a network RAID 1.
+
+  Please visit http://www.drbd.org to find out more.
+
+The here included files are intended to help understand the implementation
+
+DRBD-8.3-data-packets.svg, DRBD-data-packets.svg  
+  relates some functions, and write packets.
+
+conn-states-8.dot, disk-states-8.dot, node-states-8.dot
+  The sub graphs of DRBD's state transitions
diff -druNp linux-libre-2.6.32-gnu1/Documentation/c2port.txt linux-libre-2.6.33-gnu1/Documentation/c2port.txt
--- linux-libre-2.6.32-gnu1/Documentation/c2port.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/c2port.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-			C2 port support
-			---------------
-
-(C) Copyright 2007 Rodolfo Giometti <giometti@enneenne.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.
-
-
-
-Overview
---------
-
-This driver implements the support for Linux of Silicon Labs (Silabs)
-C2 Interface used for in-system programming of micro controllers.
-
-By using this driver you can reprogram the in-system flash without EC2
-or EC3 debug adapter. This solution is also useful in those systems
-where the micro controller is connected via special GPIOs pins.
-
-References
-----------
-
-The C2 Interface main references are at (http://www.silabs.com)
-Silicon Laboratories site], see:
-
-- AN127: FLASH Programming via the C2 Interface at
-http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Small_Form_Factor/en/an127.pdf, and
-
-- C2 Specification at
-http://www.silabs.com/public/documents/tpub_doc/spec/Microcontrollers/en/C2spec.pdf,
-
-however it implements a two wire serial communication protocol (bit
-banging) designed to enable in-system programming, debugging, and
-boundary-scan testing on low pin-count Silicon Labs devices. Currently
-this code supports only flash programming but extensions are easy to
-add.
-
-Using the driver
-----------------
-
-Once the driver is loaded you can use sysfs support to get C2port's
-info or read/write in-system flash.
-
-# ls /sys/class/c2port/c2port0/
-access            flash_block_size  flash_erase       rev_id
-dev_id            flash_blocks_num  flash_size        subsystem/
-flash_access      flash_data        reset             uevent
-
-Initially the C2port access is disabled since you hardware may have
-such lines multiplexed with other devices so, to get access to the
-C2port, you need the command:
-
-# echo 1 > /sys/class/c2port/c2port0/access
-
-after that you should read the device ID and revision ID of the
-connected micro controller:
-
-# cat /sys/class/c2port/c2port0/dev_id
-8
-# cat /sys/class/c2port/c2port0/rev_id
-1
-
-However, for security reasons, the in-system flash access in not
-enabled yet, to do so you need the command:
-
-# echo 1 > /sys/class/c2port/c2port0/flash_access
-
-After that you can read the whole flash:
-
-# cat /sys/class/c2port/c2port0/flash_data > image
-
-erase it:
-
-# echo 1 > /sys/class/c2port/c2port0/flash_erase
-
-and write it:
-
-# cat image > /sys/class/c2port/c2port0/flash_data
-
-after writing you have to reset the device to execute the new code:
-
-# echo 1 > /sys/class/c2port/c2port0/reset
diff -druNp linux-libre-2.6.32-gnu1/Documentation/cgroups/blkio-controller.txt linux-libre-2.6.33-gnu1/Documentation/cgroups/blkio-controller.txt
--- linux-libre-2.6.32-gnu1/Documentation/cgroups/blkio-controller.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/cgroups/blkio-controller.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,135 @@
+				Block IO Controller
+				===================
+Overview
+========
+cgroup subsys "blkio" implements the block io controller. There seems to be
+a need of various kinds of IO control policies (like proportional BW, max BW)
+both at leaf nodes as well as at intermediate nodes in a storage hierarchy.
+Plan is to use the same cgroup based management interface for blkio controller
+and based on user options switch IO policies in the background.
+
+In the first phase, this patchset implements proportional weight time based
+division of disk policy. It is implemented in CFQ. Hence this policy takes
+effect only on leaf nodes when CFQ is being used.
+
+HOWTO
+=====
+You can do a very simple testing of running two dd threads in two different
+cgroups. Here is what you can do.
+
+- Enable group scheduling in CFQ
+	CONFIG_CFQ_GROUP_IOSCHED=y
+
+- Compile and boot into kernel and mount IO controller (blkio).
+
+	mount -t cgroup -o blkio none /cgroup
+
+- Create two cgroups
+	mkdir -p /cgroup/test1/ /cgroup/test2
+
+- Set weights of group test1 and test2
+	echo 1000 > /cgroup/test1/blkio.weight
+	echo 500 > /cgroup/test2/blkio.weight
+
+- Create two same size files (say 512MB each) on same disk (file1, file2) and
+  launch two dd threads in different cgroup to read those files.
+
+	sync
+	echo 3 > /proc/sys/vm/drop_caches
+
+	dd if=/mnt/sdb/zerofile1 of=/dev/null &
+	echo $! > /cgroup/test1/tasks
+	cat /cgroup/test1/tasks
+
+	dd if=/mnt/sdb/zerofile2 of=/dev/null &
+	echo $! > /cgroup/test2/tasks
+	cat /cgroup/test2/tasks
+
+- At macro level, first dd should finish first. To get more precise data, keep
+  on looking at (with the help of script), at blkio.disk_time and
+  blkio.disk_sectors files of both test1 and test2 groups. This will tell how
+  much disk time (in milli seconds), each group got and how many secotors each
+  group dispatched to the disk. We provide fairness in terms of disk time, so
+  ideally io.disk_time of cgroups should be in proportion to the weight.
+
+Various user visible config options
+===================================
+CONFIG_CFQ_GROUP_IOSCHED
+	- Enables group scheduling in CFQ. Currently only 1 level of group
+	  creation is allowed.
+
+CONFIG_DEBUG_CFQ_IOSCHED
+	- Enables some debugging messages in blktrace. Also creates extra
+	  cgroup file blkio.dequeue.
+
+Config options selected automatically
+=====================================
+These config options are not user visible and are selected/deselected
+automatically based on IO scheduler configuration.
+
+CONFIG_BLK_CGROUP
+	- Block IO controller. Selected by CONFIG_CFQ_GROUP_IOSCHED.
+
+CONFIG_DEBUG_BLK_CGROUP
+	- Debug help. Selected by CONFIG_DEBUG_CFQ_IOSCHED.
+
+Details of cgroup files
+=======================
+- blkio.weight
+	- Specifies per cgroup weight.
+
+	  Currently allowed range of weights is from 100 to 1000.
+
+- blkio.time
+	- disk time allocated to cgroup per device in milliseconds. First
+	  two fields specify the major and minor number of the device and
+	  third field specifies the disk time allocated to group in
+	  milliseconds.
+
+- blkio.sectors
+	- number of sectors transferred to/from disk by the group. First
+	  two fields specify the major and minor number of the device and
+	  third field specifies the number of sectors transferred by the
+	  group to/from the device.
+
+- blkio.dequeue
+	- Debugging aid only enabled if CONFIG_DEBUG_CFQ_IOSCHED=y. This
+	  gives the statistics about how many a times a group was dequeued
+	  from service tree of the device. First two fields specify the major
+	  and minor number of the device and third field specifies the number
+	  of times a group was dequeued from a particular device.
+
+CFQ sysfs tunable
+=================
+/sys/block/<disk>/queue/iosched/group_isolation
+
+If group_isolation=1, it provides stronger isolation between groups at the
+expense of throughput. By default group_isolation is 0. In general that
+means that if group_isolation=0, expect fairness for sequential workload
+only. Set group_isolation=1 to see fairness for random IO workload also.
+
+Generally CFQ will put random seeky workload in sync-noidle category. CFQ
+will disable idling on these queues and it does a collective idling on group
+of such queues. Generally these are slow moving queues and if there is a
+sync-noidle service tree in each group, that group gets exclusive access to
+disk for certain period. That means it will bring the throughput down if
+group does not have enough IO to drive deeper queue depths and utilize disk
+capacity to the fullest in the slice allocated to it. But the flip side is
+that even a random reader should get better latencies and overall throughput
+if there are lots of sequential readers/sync-idle workload running in the
+system.
+
+If group_isolation=0, then CFQ automatically moves all the random seeky queues
+in the root group. That means there will be no service differentiation for
+that kind of workload. This leads to better throughput as we do collective
+idling on root sync-noidle tree.
+
+By default one should run with group_isolation=0. If that is not sufficient
+and one wants stronger isolation between groups, then set group_isolation=1
+but this will come at cost of reduced throughput.
+
+What works
+==========
+- Currently only sync IO queues are support. All the buffered writes are
+  still system wide and not per group. Hence we will not see service
+  differentiation between buffered writes between groups.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/Changes linux-libre-2.6.33-gnu1/Documentation/Changes
--- linux-libre-2.6.32-gnu1/Documentation/Changes	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/Changes	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,8 @@ o  oprofile               0.9
 o  udev                   081                     # udevinfo -V
 o  grub                   0.93                    # grub --version
 o  mcelog		  0.6
+o  iptables               1.4.1                   # iptables -V
+
 
 Kernel compilation
 ==================
diff -druNp linux-libre-2.6.32-gnu1/Documentation/cpu-freq/cpu-drivers.txt linux-libre-2.6.33-gnu1/Documentation/cpu-freq/cpu-drivers.txt
--- linux-libre-2.6.32-gnu1/Documentation/cpu-freq/cpu-drivers.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/cpu-freq/cpu-drivers.txt	2010-02-24 13:52:17.000000000 -0500
@@ -92,9 +92,9 @@ policy->cpuinfo.max_freq -	the minimum a
 				(in kHz) which is supported by 
 				this CPU
 policy->cpuinfo.transition_latency   the time it takes on this CPU to
-				switch between two frequencies (if
-				appropriate, else specify
-				CPUFREQ_ETERNAL)
+				switch between two frequencies in
+				nanoseconds (if appropriate, else
+				specify CPUFREQ_ETERNAL)
 
 policy->cur			The current operating frequency of
 				this CPU (if appropriate)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/cpu-freq/governors.txt linux-libre-2.6.33-gnu1/Documentation/cpu-freq/governors.txt
--- linux-libre-2.6.32-gnu1/Documentation/cpu-freq/governors.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/cpu-freq/governors.txt	2010-02-24 13:52:17.000000000 -0500
@@ -145,8 +145,8 @@ show_sampling_rate_max: THIS INTERFACE I
 up_threshold: defines what the average CPU usage between the samplings
 of 'sampling_rate' needs to be for the kernel to make a decision on
 whether it should increase the frequency.  For example when it is set
-to its default value of '80' it means that between the checking
-intervals the CPU needs to be on average more than 80% in use to then
+to its default value of '95' it means that between the checking
+intervals the CPU needs to be on average more than 95% in use to then
 decide that the CPU frequency needs to be increased.  
 
 ignore_nice_load: this parameter takes a value of '0' or '1'. When
diff -druNp linux-libre-2.6.32-gnu1/Documentation/cpu-freq/user-guide.txt linux-libre-2.6.33-gnu1/Documentation/cpu-freq/user-guide.txt
--- linux-libre-2.6.32-gnu1/Documentation/cpu-freq/user-guide.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/cpu-freq/user-guide.txt	2010-02-24 13:52:17.000000000 -0500
@@ -203,6 +203,17 @@ scaling_cur_freq :		Current frequency of
 				the frequency the kernel thinks the CPU runs
 				at.
 
+bios_limit :			If the BIOS tells the OS to limit a CPU to
+				lower frequencies, the user can read out the
+				maximum available frequency from this file.
+				This typically can happen through (often not
+				intended) BIOS settings, restrictions
+				triggered through a service processor or other
+				BIOS/HW based implementations.
+				This does not cover thermal ACPI limitations
+				which can be detected through the generic
+				thermal driver.
+
 If you have selected the "userspace" governor which allows you to
 set the CPU operating frequency to a specific value, you can read out
 the current frequency in
diff -druNp linux-libre-2.6.32-gnu1/Documentation/cpu-hotplug.txt linux-libre-2.6.33-gnu1/Documentation/cpu-hotplug.txt
--- linux-libre-2.6.32-gnu1/Documentation/cpu-hotplug.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/cpu-hotplug.txt	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,12 @@ maxcpus=n    Restrict boot time cpus to
 additional_cpus=n (*)	Use this to limit hotpluggable cpus. This option sets
   			cpu_possible_map = cpu_present_map + additional_cpus
 
+cede_offline={"off","on"}  Use this option to disable/enable putting offlined
+		            processors to an extended H_CEDE state on
+			    supported pseries platforms.
+			    If nothing is specified,
+			    cede_offline is set to "on".
+
 (*) Option valid only for following architectures
 - ia64
 
@@ -309,41 +315,26 @@ A: The following are what is required fo
 
 Q: I need to ensure that a particular cpu is not removed when there is some
    work specific to this cpu is in progress.
-A: First switch the current thread context to preferred cpu
+A: There are two ways.  If your code can be run in interrupt context, use
+   smp_call_function_single(), otherwise use work_on_cpu().  Note that
+   work_on_cpu() is slow, and can fail due to out of memory:
 
 	int my_func_on_cpu(int cpu)
 	{
-		cpumask_t saved_mask, new_mask = CPU_MASK_NONE;
-		int curr_cpu, err = 0;
-
-		saved_mask = current->cpus_allowed;
-		cpu_set(cpu, new_mask);
-		err = set_cpus_allowed(current, new_mask);
-
-		if (err)
-			return err;
-
-		/*
-		 * If we got scheduled out just after the return from
-		 * set_cpus_allowed() before running the work, this ensures
-		 * we stay locked.
-		 */
-		curr_cpu = get_cpu();
-
-		if (curr_cpu != cpu) {
-			err = -EAGAIN;
-			goto ret;
-		} else {
-			/*
-			 * Do work : But cant sleep, since get_cpu() disables preempt
-			 */
-		}
-		ret:
-			put_cpu();
-			set_cpus_allowed(current, saved_mask);
-			return err;
-		}
-
+		int err;
+		get_online_cpus();
+		if (!cpu_online(cpu))
+			err = -EINVAL;
+		else
+#if NEEDS_BLOCKING
+			err = work_on_cpu(cpu, __my_func_on_cpu, NULL);
+#else
+			smp_call_function_single(cpu, __my_func_on_cpu, &err,
+						 true);
+#endif
+		put_online_cpus();
+		return err;
+	}
 
 Q: How do we determine how many CPUs are available for hotplug.
 A: There is no clear spec defined way from ACPI that can give us that
diff -druNp linux-libre-2.6.32-gnu1/Documentation/device-mapper/snapshot.txt linux-libre-2.6.33-gnu1/Documentation/device-mapper/snapshot.txt
--- linux-libre-2.6.32-gnu1/Documentation/device-mapper/snapshot.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/device-mapper/snapshot.txt	2010-02-24 13:52:17.000000000 -0500
@@ -8,13 +8,19 @@ the block device which are also writable
 original content;
 *) To create device "forks", i.e. multiple different versions of the
 same data stream.
+*) To merge a snapshot of a block device back into the snapshot's origin
+device.
 
+In the first two cases, dm copies only the chunks of data that get
+changed and uses a separate copy-on-write (COW) block device for
+storage.
 
-In both cases, dm copies only the chunks of data that get changed and
-uses a separate copy-on-write (COW) block device for storage.
+For snapshot merge the contents of the COW storage are merged back into
+the origin device.
 
 
-There are two dm targets available: snapshot and snapshot-origin.
+There are three dm targets available:
+snapshot, snapshot-origin, and snapshot-merge.
 
 *) snapshot-origin <origin>
 
@@ -40,8 +46,25 @@ The difference is that for transient sna
 saved on disk - they can be kept in memory by the kernel.
 
 
-How this is used by LVM2
-========================
+* snapshot-merge <origin> <COW device> <persistent> <chunksize>
+
+takes the same table arguments as the snapshot target except it only
+works with persistent snapshots.  This target assumes the role of the
+"snapshot-origin" target and must not be loaded if the "snapshot-origin"
+is still present for <origin>.
+
+Creates a merging snapshot that takes control of the changed chunks
+stored in the <COW device> of an existing snapshot, through a handover
+procedure, and merges these chunks back into the <origin>.  Once merging
+has started (in the background) the <origin> may be opened and the merge
+will continue while I/O is flowing to it.  Changes to the <origin> are
+deferred until the merging snapshot's corresponding chunk(s) have been
+merged.  Once merging has started the snapshot device, associated with
+the "snapshot" target, will return -EIO when accessed.
+
+
+How snapshot is used by LVM2
+============================
 When you create the first LVM2 snapshot of a volume, four dm devices are used:
 
 1) a device containing the original mapping table of the source volume;
@@ -72,3 +95,30 @@ brw-------  1 root root 254, 12 29 ago 1
 brw-------  1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
 brw-------  1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
 
+
+How snapshot-merge is used by LVM2
+==================================
+A merging snapshot assumes the role of the "snapshot-origin" while
+merging.  As such the "snapshot-origin" is replaced with
+"snapshot-merge".  The "-real" device is not changed and the "-cow"
+device is renamed to <origin name>-cow to aid LVM2's cleanup of the
+merging snapshot after it completes.  The "snapshot" that hands over its
+COW device to the "snapshot-merge" is deactivated (unless using lvchange
+--refresh); but if it is left active it will simply return I/O errors.
+
+A snapshot will merge into its origin with the following command:
+
+lvconvert --merge volumeGroup/snap
+
+we'll now have this situation:
+
+# dmsetup table|grep volumeGroup
+
+volumeGroup-base-real: 0 2097152 linear 8:19 384
+volumeGroup-base-cow: 0 204800 linear 8:19 2097536
+volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16
+
+# ls -lL /dev/mapper/volumeGroup-*
+brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
+brw-------  1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
+brw-------  1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DMA-mapping.txt linux-libre-2.6.33-gnu1/Documentation/DMA-mapping.txt
--- linux-libre-2.6.32-gnu1/Documentation/DMA-mapping.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DMA-mapping.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,766 +0,0 @@
-			Dynamic DMA mapping
-			===================
-
-		 David S. Miller <davem@redhat.com>
-		 Richard Henderson <rth@cygnus.com>
-		  Jakub Jelinek <jakub@redhat.com>
-
-This document describes the DMA mapping system in terms of the pci_
-API.  For a similar API that works for generic devices, see
-DMA-API.txt.
-
-Most of the 64bit platforms have special hardware that translates bus
-addresses (DMA addresses) into physical addresses.  This is similar to
-how page tables and/or a TLB translates virtual addresses to physical
-addresses on a CPU.  This is needed so that e.g. PCI devices can
-access with a Single Address Cycle (32bit DMA address) any page in the
-64bit physical address space.  Previously in Linux those 64bit
-platforms had to set artificial limits on the maximum RAM size in the
-system, so that the virt_to_bus() static scheme works (the DMA address
-translation tables were simply filled on bootup to map each bus
-address to the physical page __pa(bus_to_virt())).
-
-So that Linux can use the dynamic DMA mapping, it needs some help from the
-drivers, namely it has to take into account that DMA addresses should be
-mapped only for the time they are actually used and unmapped after the DMA
-transfer.
-
-The following API will work of course even on platforms where no such
-hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
-top of the virt_to_bus interface.
-
-First of all, you should make sure
-
-#include <linux/pci.h>
-
-is in your driver. This file will obtain for you the definition of the
-dma_addr_t (which can hold any valid DMA address for the platform)
-type which should be used everywhere you hold a DMA (bus) address
-returned from the DMA mapping functions.
-
-			 What memory is DMA'able?
-
-The first piece of information you must know is what kernel memory can
-be used with the DMA mapping facilities.  There has been an unwritten
-set of rules regarding this, and this text is an attempt to finally
-write them down.
-
-If you acquired your memory via the page allocator
-(i.e. __get_free_page*()) or the generic memory allocators
-(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
-that memory using the addresses returned from those routines.
-
-This means specifically that you may _not_ use the memory/addresses
-returned from vmalloc() for DMA.  It is possible to DMA to the
-_underlying_ memory mapped into a vmalloc() area, but this requires
-walking page tables to get the physical addresses, and then
-translating each of those pages back to a kernel address using
-something like __va().  [ EDIT: Update this when we integrate
-Gerd Knorr's generic code which does this. ]
-
-This rule also means that you may use neither kernel image addresses
-(items in data/text/bss segments), nor module image addresses, nor
-stack addresses for DMA.  These could all be mapped somewhere entirely
-different than the rest of physical memory.  Even if those classes of
-memory could physically work with DMA, you'd need to ensure the I/O
-buffers were cacheline-aligned.  Without that, you'd see cacheline
-sharing problems (data corruption) on CPUs with DMA-incoherent caches.
-(The CPU could write to one word, DMA would write to a different one
-in the same cache line, and one of them could be overwritten.)
-
-Also, this means that you cannot take the return of a kmap()
-call and DMA to/from that.  This is similar to vmalloc().
-
-What about block I/O and networking buffers?  The block I/O and
-networking subsystems make sure that the buffers they use are valid
-for you to DMA from/to.
-
-			DMA addressing limitations
-
-Does your device have any DMA addressing limitations?  For example, is
-your device only capable of driving the low order 24-bits of address
-on the PCI bus for SAC DMA transfers?  If so, you need to inform the
-PCI layer of this fact.
-
-By default, the kernel assumes that your device can address the full
-32-bits in a SAC cycle.  For a 64-bit DAC capable device, this needs
-to be increased.  And for a device with limitations, as discussed in
-the previous paragraph, it needs to be decreased.
-
-pci_alloc_consistent() by default will return 32-bit DMA addresses.
-PCI-X specification requires PCI-X devices to support 64-bit
-addressing (DAC) for all transactions. And at least one platform (SGI
-SN2) requires 64-bit consistent allocations to operate correctly when
-the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(),
-it's good practice to call pci_set_consistent_dma_mask() to set the
-appropriate mask even if your device only supports 32-bit DMA
-(default) and especially if it's a PCI-X device.
-
-For correct operation, you must interrogate the PCI layer in your
-device probe routine to see if the PCI controller on the machine can
-properly support the DMA addressing limitation your device has.  It is
-good style to do this even if your device holds the default setting,
-because this shows that you did think about these issues wrt. your
-device.
-
-The query is performed via a call to pci_set_dma_mask():
-
-	int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-The query for consistent allocations is performed via a call to
-pci_set_consistent_dma_mask():
-
-	int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-Here, pdev is a pointer to the PCI device struct of your device, and
-device_mask is a bit mask describing which bits of a PCI address your
-device supports.  It returns zero if your card can perform DMA
-properly on the machine given the address mask you provided.
-
-If it returns non-zero, your device cannot perform DMA properly on
-this platform, and attempting to do so will result in undefined
-behavior.  You must either use a different mask, or not use DMA.
-
-This means that in the failure case, you have three options:
-
-1) Use another DMA mask, if possible (see below).
-2) Use some non-DMA mode for data transfer, if possible.
-3) Ignore this device and do not initialize it.
-
-It is recommended that your driver print a kernel KERN_WARNING message
-when you end up performing either #2 or #3.  In this manner, if a user
-of your driver reports that performance is bad or that the device is not
-even detected, you can ask them for the kernel messages to find out
-exactly why.
-
-The standard 32-bit addressing PCI device would do something like
-this:
-
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-Another common scenario is a 64-bit capable device.  The approach
-here is to try for 64-bit DAC addressing, but back down to a
-32-bit mask should that fail.  The PCI platform code may fail the
-64-bit mask not because the platform is not capable of 64-bit
-addressing.  Rather, it may fail in this case simply because
-32-bit SAC addressing is done more efficiently than DAC addressing.
-Sparc64 is one platform which behaves in this way.
-
-Here is how you would handle a 64-bit capable device which can drive
-all 64-bits when accessing streaming DMA:
-
-	int using_dac;
-
-	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		using_dac = 0;
-	} else {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-If a card is capable of using 64-bit consistent allocations as well,
-the case would look like this:
-
-	int using_dac, consistent_using_dac;
-
-	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		using_dac = 1;
-	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
-	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		using_dac = 0;
-		consistent_using_dac = 0;
-		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-	} else {
-		printk(KERN_WARNING
-		       "mydev: No suitable DMA available.\n");
-		goto ignore_this_device;
-	}
-
-pci_set_consistent_dma_mask() will always be able to set the same or a
-smaller mask as pci_set_dma_mask(). However for the rare case that a
-device driver only uses consistent allocations, one would have to
-check the return value from pci_set_consistent_dma_mask().
-
-Finally, if your device can only drive the low 24-bits of
-address during PCI bus mastering you might do something like:
-
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
-		printk(KERN_WARNING
-		       "mydev: 24-bit DMA addressing not available.\n");
-		goto ignore_this_device;
-	}
-
-When pci_set_dma_mask() is successful, and returns zero, the PCI layer
-saves away this mask you have provided.  The PCI layer will use this
-information later when you make DMA mappings.
-
-There is a case which we are aware of at this time, which is worth
-mentioning in this documentation.  If your device supports multiple
-functions (for example a sound card provides playback and record
-functions) and the various different functions have _different_
-DMA addressing limitations, you may wish to probe each mask and
-only provide the functionality which the machine can handle.  It
-is important that the last call to pci_set_dma_mask() be for the
-most specific mask.
-
-Here is pseudo-code showing how this might be done:
-
-	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
-	#define RECORD_ADDRESS_BITS	0x00ffffff
-
-	struct my_sound_card *card;
-	struct pci_dev *pdev;
-
-	...
-	if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) {
-		card->playback_enabled = 1;
-	} else {
-		card->playback_enabled = 0;
-		printk(KERN_WARN "%s: Playback disabled due to DMA limitations.\n",
-		       card->name);
-	}
-	if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
-		card->record_enabled = 1;
-	} else {
-		card->record_enabled = 0;
-		printk(KERN_WARN "%s: Record disabled due to DMA limitations.\n",
-		       card->name);
-	}
-
-A sound card was used as an example here because this genre of PCI
-devices seems to be littered with ISA chips given a PCI front end,
-and thus retaining the 16MB DMA addressing limitations of ISA.
-
-			Types of DMA mappings
-
-There are two types of DMA mappings:
-
-- Consistent DMA mappings which are usually mapped at driver
-  initialization, unmapped at the end and for which the hardware should
-  guarantee that the device and the CPU can access the data
-  in parallel and will see updates made by each other without any
-  explicit software flushing.
-
-  Think of "consistent" as "synchronous" or "coherent".
-
-  The current default is to return consistent memory in the low 32
-  bits of the PCI bus space.  However, for future compatibility you
-  should set the consistent mask even if this default is fine for your
-  driver.
-
-  Good examples of what to use consistent mappings for are:
-
-	- Network card DMA ring descriptors.
-	- SCSI adapter mailbox command data structures.
-	- Device firmware microcode executed out of
-	  main memory.
-
-  The invariant these examples all require is that any CPU store
-  to memory is immediately visible to the device, and vice
-  versa.  Consistent mappings guarantee this.
-
-  IMPORTANT: Consistent DMA memory does not preclude the usage of
-             proper memory barriers.  The CPU may reorder stores to
-	     consistent memory just as it may normal memory.  Example:
-	     if it is important for the device to see the first word
-	     of a descriptor updated before the second, you must do
-	     something like:
-
-		desc->word0 = address;
-		wmb();
-		desc->word1 = DESC_VALID;
-
-             in order to get correct behavior on all platforms.
-
-	     Also, on some platforms your driver may need to flush CPU write
-	     buffers in much the same way as it needs to flush write buffers
-	     found in PCI bridges (such as by reading a register's value
-	     after writing it).
-
-- Streaming DMA mappings which are usually mapped for one DMA transfer,
-  unmapped right after it (unless you use pci_dma_sync_* below) and for which
-  hardware can optimize for sequential accesses.
-
-  This of "streaming" as "asynchronous" or "outside the coherency
-  domain".
-
-  Good examples of what to use streaming mappings for are:
-
-	- Networking buffers transmitted/received by a device.
-	- Filesystem buffers written/read by a SCSI device.
-
-  The interfaces for using this type of mapping were designed in
-  such a way that an implementation can make whatever performance
-  optimizations the hardware allows.  To this end, when using
-  such mappings you must be explicit about what you want to happen.
-
-Neither type of DMA mapping has alignment restrictions that come
-from PCI, although some devices may have such restrictions.
-Also, systems with caches that aren't DMA-coherent will work better
-when the underlying buffers don't share cache lines with other data.
-
-
-		 Using Consistent DMA mappings.
-
-To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
-you should do:
-
-	dma_addr_t dma_handle;
-
-	cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
-
-where pdev is a struct pci_dev *. This may be called in interrupt context.
-You should use dma_alloc_coherent (see DMA-API.txt) for buses
-where devices don't have struct pci_dev (like ISA, EISA).
-
-This argument is needed because the DMA translations may be bus
-specific (and often is private to the bus which the device is attached
-to).
-
-Size is the length of the region you want to allocate, in bytes.
-
-This routine will allocate RAM for that region, so it acts similarly to
-__get_free_pages (but takes size instead of a page order).  If your
-driver needs regions sized smaller than a page, you may prefer using
-the pci_pool interface, described below.
-
-The consistent DMA mapping interfaces, for non-NULL pdev, will by
-default return a DMA address which is SAC (Single Address Cycle)
-addressable.  Even if the device indicates (via PCI dma mask) that it
-may address the upper 32-bits and thus perform DAC cycles, consistent
-allocation will only return > 32-bit PCI addresses for DMA if the
-consistent dma mask has been explicitly changed via
-pci_set_consistent_dma_mask().  This is true of the pci_pool interface
-as well.
-
-pci_alloc_consistent returns two values: the virtual address which you
-can use to access it from the CPU and dma_handle which you pass to the
-card.
-
-The cpu return address and the DMA bus master address are both
-guaranteed to be aligned to the smallest PAGE_SIZE order which
-is greater than or equal to the requested size.  This invariant
-exists (for example) to guarantee that if you allocate a chunk
-which is smaller than or equal to 64 kilobytes, the extent of the
-buffer you receive will not cross a 64K boundary.
-
-To unmap and free such a DMA region, you call:
-
-	pci_free_consistent(pdev, size, cpu_addr, dma_handle);
-
-where pdev, size are the same as in the above call and cpu_addr and
-dma_handle are the values pci_alloc_consistent returned to you.
-This function may not be called in interrupt context.
-
-If your driver needs lots of smaller memory regions, you can write
-custom code to subdivide pages returned by pci_alloc_consistent,
-or you can use the pci_pool API to do that.  A pci_pool is like
-a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
-Also, it understands common hardware constraints for alignment,
-like queue heads needing to be aligned on N byte boundaries.
-
-Create a pci_pool like this:
-
-	struct pci_pool *pool;
-
-	pool = pci_pool_create(name, pdev, size, align, alloc);
-
-The "name" is for diagnostics (like a kmem_cache name); pdev and size
-are as above.  The device's hardware alignment requirement for this
-type of data is "align" (which is expressed in bytes, and must be a
-power of two).  If your device has no boundary crossing restrictions,
-pass 0 for alloc; passing 4096 says memory allocated from this pool
-must not cross 4KByte boundaries (but at that time it may be better to
-go for pci_alloc_consistent directly instead).
-
-Allocate memory from a pci pool like this:
-
-	cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
-
-flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
-holding SMP locks), SLAB_ATOMIC otherwise.  Like pci_alloc_consistent,
-this returns two values, cpu_addr and dma_handle.
-
-Free memory that was allocated from a pci_pool like this:
-
-	pci_pool_free(pool, cpu_addr, dma_handle);
-
-where pool is what you passed to pci_pool_alloc, and cpu_addr and
-dma_handle are the values pci_pool_alloc returned. This function
-may be called in interrupt context.
-
-Destroy a pci_pool by calling:
-
-	pci_pool_destroy(pool);
-
-Make sure you've called pci_pool_free for all memory allocated
-from a pool before you destroy the pool. This function may not
-be called in interrupt context.
-
-			DMA Direction
-
-The interfaces described in subsequent portions of this document
-take a DMA direction argument, which is an integer and takes on
-one of the following values:
-
- PCI_DMA_BIDIRECTIONAL
- PCI_DMA_TODEVICE
- PCI_DMA_FROMDEVICE
- PCI_DMA_NONE
-
-One should provide the exact DMA direction if you know it.
-
-PCI_DMA_TODEVICE means "from main memory to the PCI device"
-PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
-It is the direction in which the data moves during the DMA
-transfer.
-
-You are _strongly_ encouraged to specify this as precisely
-as you possibly can.
-
-If you absolutely cannot know the direction of the DMA transfer,
-specify PCI_DMA_BIDIRECTIONAL.  It means that the DMA can go in
-either direction.  The platform guarantees that you may legally
-specify this, and that it will work, but this may be at the
-cost of performance for example.
-
-The value PCI_DMA_NONE is to be used for debugging.  One can
-hold this in a data structure before you come to know the
-precise direction, and this will help catch cases where your
-direction tracking logic has failed to set things up properly.
-
-Another advantage of specifying this value precisely (outside of
-potential platform-specific optimizations of such) is for debugging.
-Some platforms actually have a write permission boolean which DMA
-mappings can be marked with, much like page protections in the user
-program address space.  Such platforms can and do report errors in the
-kernel logs when the PCI controller hardware detects violation of the
-permission setting.
-
-Only streaming mappings specify a direction, consistent mappings
-implicitly have a direction attribute setting of
-PCI_DMA_BIDIRECTIONAL.
-
-The SCSI subsystem tells you the direction to use in the
-'sc_data_direction' member of the SCSI command your driver is
-working on.
-
-For Networking drivers, it's a rather simple affair.  For transmit
-packets, map/unmap them with the PCI_DMA_TODEVICE direction
-specifier.  For receive packets, just the opposite, map/unmap them
-with the PCI_DMA_FROMDEVICE direction specifier.
-
-		  Using Streaming DMA mappings
-
-The streaming DMA mapping routines can be called from interrupt
-context.  There are two versions of each map/unmap, one which will
-map/unmap a single memory region, and one which will map/unmap a
-scatterlist.
-
-To map a single region, you do:
-
-	struct pci_dev *pdev = mydev->pdev;
-	dma_addr_t dma_handle;
-	void *addr = buffer->ptr;
-	size_t size = buffer->len;
-
-	dma_handle = pci_map_single(pdev, addr, size, direction);
-
-and to unmap it:
-
-	pci_unmap_single(pdev, dma_handle, size, direction);
-
-You should call pci_unmap_single when the DMA activity is finished, e.g.
-from the interrupt which told you that the DMA transfer is done.
-
-Using cpu pointers like this for single mappings has a disadvantage,
-you cannot reference HIGHMEM memory in this way.  Thus, there is a
-map/unmap interface pair akin to pci_{map,unmap}_single.  These
-interfaces deal with page/offset pairs instead of cpu pointers.
-Specifically:
-
-	struct pci_dev *pdev = mydev->pdev;
-	dma_addr_t dma_handle;
-	struct page *page = buffer->page;
-	unsigned long offset = buffer->offset;
-	size_t size = buffer->len;
-
-	dma_handle = pci_map_page(pdev, page, offset, size, direction);
-
-	...
-
-	pci_unmap_page(pdev, dma_handle, size, direction);
-
-Here, "offset" means byte offset within the given page.
-
-With scatterlists, you map a region gathered from several regions by:
-
-	int i, count = pci_map_sg(pdev, sglist, nents, direction);
-	struct scatterlist *sg;
-
-	for_each_sg(sglist, sg, count, i) {
-		hw_address[i] = sg_dma_address(sg);
-		hw_len[i] = sg_dma_len(sg);
-	}
-
-where nents is the number of entries in the sglist.
-
-The implementation is free to merge several consecutive sglist entries
-into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
-consecutive sglist entries can be merged into one provided the first one
-ends and the second one starts on a page boundary - in fact this is a huge
-advantage for cards which either cannot do scatter-gather or have very
-limited number of scatter-gather entries) and returns the actual number
-of sg entries it mapped them to. On failure 0 is returned.
-
-Then you should loop count times (note: this can be less than nents times)
-and use sg_dma_address() and sg_dma_len() macros where you previously
-accessed sg->address and sg->length as shown above.
-
-To unmap a scatterlist, just call:
-
-	pci_unmap_sg(pdev, sglist, nents, direction);
-
-Again, make sure DMA activity has already finished.
-
-PLEASE NOTE:  The 'nents' argument to the pci_unmap_sg call must be
-              the _same_ one you passed into the pci_map_sg call,
-	      it should _NOT_ be the 'count' value _returned_ from the
-              pci_map_sg call.
-
-Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
-counterpart, because the bus address space is a shared resource (although
-in some ports the mapping is per each BUS so less devices contend for the
-same bus address space) and you could render the machine unusable by eating
-all bus addresses.
-
-If you need to use the same streaming DMA region multiple times and touch
-the data in between the DMA transfers, the buffer needs to be synced
-properly in order for the cpu and device to see the most uptodate and
-correct copy of the DMA buffer.
-
-So, firstly, just map it with pci_map_{single,sg}, and after each DMA
-transfer call either:
-
-	pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
-
-or:
-
-	pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
-
-as appropriate.
-
-Then, if you wish to let the device get at the DMA area again,
-finish accessing the data with the cpu, and then before actually
-giving the buffer to the hardware call either:
-
-	pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
-
-or:
-
-	pci_dma_sync_sg_for_device(dev, sglist, nents, direction);
-
-as appropriate.
-
-After the last DMA transfer call one of the DMA unmap routines
-pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
-call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
-routines at all.
-
-Here is pseudo code which shows a situation in which you would need
-to use the pci_dma_sync_*() interfaces.
-
-	my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
-	{
-		dma_addr_t mapping;
-
-		mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE);
-
-		cp->rx_buf = buffer;
-		cp->rx_len = len;
-		cp->rx_dma = mapping;
-
-		give_rx_buf_to_card(cp);
-	}
-
-	...
-
-	my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
-	{
-		struct my_card *cp = devid;
-
-		...
-		if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
-			struct my_card_header *hp;
-
-			/* Examine the header to see if we wish
-			 * to accept the data.  But synchronize
-			 * the DMA transfer with the CPU first
-			 * so that we see updated contents.
-			 */
-			pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma,
-						    cp->rx_len,
-						    PCI_DMA_FROMDEVICE);
-
-			/* Now it is safe to examine the buffer. */
-			hp = (struct my_card_header *) cp->rx_buf;
-			if (header_is_ok(hp)) {
-				pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len,
-						 PCI_DMA_FROMDEVICE);
-				pass_to_upper_layers(cp->rx_buf);
-				make_and_setup_new_rx_buf(cp);
-			} else {
-				/* Just sync the buffer and give it back
-				 * to the card.
-				 */
-				pci_dma_sync_single_for_device(cp->pdev,
-							       cp->rx_dma,
-							       cp->rx_len,
-							       PCI_DMA_FROMDEVICE);
-				give_rx_buf_to_card(cp);
-			}
-		}
-	}
-
-Drivers converted fully to this interface should not use virt_to_bus any
-longer, nor should they use bus_to_virt. Some drivers have to be changed a
-little bit, because there is no longer an equivalent to bus_to_virt in the
-dynamic DMA mapping scheme - you have to always store the DMA addresses
-returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
-calls (pci_map_sg stores them in the scatterlist itself if the platform
-supports dynamic DMA mapping in hardware) in your driver structures and/or
-in the card registers.
-
-All PCI drivers should be using these interfaces with no exceptions.
-It is planned to completely remove virt_to_bus() and bus_to_virt() as
-they are entirely deprecated.  Some ports already do not provide these
-as it is impossible to correctly support them.
-
-		Optimizing Unmap State Space Consumption
-
-On many platforms, pci_unmap_{single,page}() is simply a nop.
-Therefore, keeping track of the mapping address and length is a waste
-of space.  Instead of filling your drivers up with ifdefs and the like
-to "work around" this (which would defeat the whole purpose of a
-portable API) the following facilities are provided.
-
-Actually, instead of describing the macros one by one, we'll
-transform some example code.
-
-1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures.
-   Example, before:
-
-	struct ring_state {
-		struct sk_buff *skb;
-		dma_addr_t mapping;
-		__u32 len;
-	};
-
-   after:
-
-	struct ring_state {
-		struct sk_buff *skb;
-		DECLARE_PCI_UNMAP_ADDR(mapping)
-		DECLARE_PCI_UNMAP_LEN(len)
-	};
-
-   NOTE: DO NOT put a semicolon at the end of the DECLARE_*()
-         macro.
-
-2) Use pci_unmap_{addr,len}_set to set these values.
-   Example, before:
-
-	ringp->mapping = FOO;
-	ringp->len = BAR;
-
-   after:
-
-	pci_unmap_addr_set(ringp, mapping, FOO);
-	pci_unmap_len_set(ringp, len, BAR);
-
-3) Use pci_unmap_{addr,len} to access these values.
-   Example, before:
-
-	pci_unmap_single(pdev, ringp->mapping, ringp->len,
-			 PCI_DMA_FROMDEVICE);
-
-   after:
-
-	pci_unmap_single(pdev,
-			 pci_unmap_addr(ringp, mapping),
-			 pci_unmap_len(ringp, len),
-			 PCI_DMA_FROMDEVICE);
-
-It really should be self-explanatory.  We treat the ADDR and LEN
-separately, because it is possible for an implementation to only
-need the address in order to perform the unmap operation.
-
-			Platform Issues
-
-If you are just writing drivers for Linux and do not maintain
-an architecture port for the kernel, you can safely skip down
-to "Closing".
-
-1) Struct scatterlist requirements.
-
-   Struct scatterlist must contain, at a minimum, the following
-   members:
-
-	struct page *page;
-	unsigned int offset;
-	unsigned int length;
-
-   The base address is specified by a "page+offset" pair.
-
-   Previous versions of struct scatterlist contained a "void *address"
-   field that was sometimes used instead of page+offset.  As of Linux
-   2.5., page+offset is always used, and the "address" field has been
-   deleted.
-
-2) More to come...
-
-			Handling Errors
-
-DMA address space is limited on some architectures and an allocation
-failure can be determined by:
-
-- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0
-
-- checking the returned dma_addr_t of pci_map_single and pci_map_page
-  by using pci_dma_mapping_error():
-
-	dma_addr_t dma_handle;
-
-	dma_handle = pci_map_single(pdev, addr, size, direction);
-	if (pci_dma_mapping_error(pdev, dma_handle)) {
-		/*
-		 * reduce current DMA mapping usage,
-		 * delay and try again later or
-		 * reset driver.
-		 */
-	}
-
-			   Closing
-
-This document, and the API itself, would not be in it's current
-form without the feedback and suggestions from numerous individuals.
-We would like to specifically mention, in no particular order, the
-following people:
-
-	Russell King <rmk@arm.linux.org.uk>
-	Leo Dagum <dagum@barrel.engr.sgi.com>
-	Ralf Baechle <ralf@oss.sgi.com>
-	Grant Grundler <grundler@cup.hp.com>
-	Jay Estabrook <Jay.Estabrook@compaq.com>
-	Thomas Sailer <sailer@ife.ee.ethz.ch>
-	Andrea Arcangeli <andrea@suse.de>
-	Jens Axboe <jens.axboe@oracle.com>
-	David Mosberger-Tang <davidm@hpl.hp.com>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/device-drivers.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/device-drivers.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/device-drivers.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/device-drivers.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -293,10 +293,23 @@ X!Idrivers/video/console/fonts.c
 
   <chapter id="input_subsystem">
      <title>Input Subsystem</title>
+     <sect1><title>Input core</title>
 !Iinclude/linux/input.h
 !Edrivers/input/input.c
 !Edrivers/input/ff-core.c
 !Edrivers/input/ff-memless.c
+     </sect1>
+     <sect1><title>Polled input devices</title>
+!Iinclude/linux/input-polldev.h
+!Edrivers/input/input-polldev.c
+     </sect1>
+     <sect1><title>Matrix keyboars/keypads</title>
+!Iinclude/linux/input/matrix_keypad.h
+     </sect1>
+     <sect1><title>Sparse keymap support</title>
+!Iinclude/linux/input/sparse-keymap.h
+!Edrivers/input/sparse-keymap.c
+     </sect1>
   </chapter>
 
   <chapter id="spi">
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/dvbapi.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/dvbapi.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/dvbapi.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/dvbapi.xml	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,14 @@
 <revhistory>
 <!-- Put document revisions here, newest first. -->
 <revision>
+	<revnumber>2.0.2</revnumber>
+	<date>2009-10-25</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>
+		documents FE_SET_FRONTEND_TUNE_MODE and FE_DISHETWORK_SEND_LEGACY_CMD ioctls.
+	</revremark>
+</revision>
+<revision>
 <revnumber>2.0.1</revnumber>
 <date>2009-09-16</date>
 <authorinitials>mcc</authorinitials>
@@ -85,3 +93,8 @@ Added ISDB-T test originally written by
     &sub-examples;
   </chapter>
 <!-- END OF CHAPTERS -->
+  <appendix id="frontend_h">
+    <title>DVB Frontend Header File</title>
+    &sub-frontend-h;
+  </appendix>
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/dvbproperty.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/dvbproperty.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/dvbproperty.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/dvbproperty.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,318 @@
+<section id="FE_GET_PROPERTY">
+<title>FE_GET_PROPERTY/FE_SET_PROPERTY</title>
+
+<section id="isdbt">
+	<title>ISDB-T frontend</title>
+	<para>This section describes shortly what are the possible parameters in the Linux
+		DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
+		demodulator:</para>
+
+	<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
+		needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
+		that some very sophisticated devices won't need certain parameters to
+		tune.</para>
+
+	<para>The information given here should help application writers to know how
+		to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
+
+	<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
+		basically show the dependencies between the needed parameter values,
+		but surely some information is left out. For more detailed information
+		see the following documents:</para>
+
+	<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
+		Television Broadcasting" and</para>
+	<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
+		Television Broadcasting".</para>
+
+	<para>In order to read this document one has to have some knowledge the
+		channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
+		the reader that an ISDB-T channel consists of 13 segments, that it can
+		have up to 3 layer sharing those segments, and things like that.</para>
+
+	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
+
+	<section id="isdbt-parms">
+		<title>Parameters that are common with DVB-T and ATSC</title>
+
+		<section id="isdbt-freq">
+			<title><constant>DTV_FREQUENCY</constant></title>
+
+			<para>Central frequency of the channel.</para>
+
+			<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
+				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
+				the channel which is 6MHz.</para>
+
+			<para>As in ISDB-Tsb the channel consists of only one or three segments the
+				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
+				central frequency of the channel is expected.</para>
+		</section>
+
+		<section id="isdbt-bw">
+			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
+
+			<para>Possible values:</para>
+
+			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
+			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
+
+			<para>Note: Hardware specific values might be given here, but standard
+				applications should not bother to set a value to this field as
+				standard demods are ignoring it anyway.</para>
+
+			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
+				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
+				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
+		</section>
+
+		<section id="isdbt-delivery-sys">
+			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
+
+			<para>Possible values: <constant>SYS_ISDBT</constant></para>
+		</section>
+
+		<section id="isdbt-tx-mode">
+			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
+
+			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
+
+			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
+				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
+
+			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
+				hardware will try to find the correct FFT-size (if capable) and will
+				use TMCC to fill in the missing parameters.</para>
+
+			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
+		</section>
+
+		<section id="isdbt-guard-interval">
+			<title><constant>DTV_GUARD_INTERVAL</constant></title>
+
+			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
+				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
+
+			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
+				try to find the correct guard interval (if capable) and will use TMCC to fill
+				in the missing parameters.</para>
+		</section>
+	</section>
+	<section id="isdbt-new-parms">
+		<title>ISDB-T only parameters</title>
+
+		<section id="isdbt-part-rec">
+			<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
+
+			<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
+				the channel is in partial reception mode or not.</para>
+
+			<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
+				<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
+
+			<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
+				is consisting of one segment and layer or three segments and two layers.</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sound-bcast">
+			<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
+
+			<para>This field represents whether the other DTV_ISDBT_*-parameters are
+				referring to an ISDB-T and an ISDB-Tsb channel. (See also
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-ch-id">
+			<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para>(Note of the author: This might not be the correct description of the
+				<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
+				background needed to program a device)</para>
+
+			<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
+				set of connected ISDB-Tsb channels. In this set of channels every
+				channel can be received independently. The number of connected
+				ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
+				bandwidth available.</para>
+
+			<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
+				broadcaster has several possibilities to put those channels in the
+				air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
+				segments from position 1-8 to 5-13 or anything in between.</para>
+
+			<para>The underlying layer of segments are subchannels: each segment is
+				consisting of several subchannels with a predefined IDs. A sub-channel
+				is used to help the demodulator to synchronize on the channel.</para>
+
+			<para>An ISDB-T channel is always centered over all sub-channels. As for
+				the example above, in ISDB-Tsb it is no longer as simple as that.</para>
+
+			<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
+				sub-channel ID of the segment to be demodulated.</para>
+
+			<para>Possible values: 0 .. 41, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-seg-idx">
+
+			<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
+				demodulated for an ISDB-Tsb channel where several of them are
+				transmitted in the connected manner.</para>
+
+			<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdbt-sb-seg-cnt">
+			<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
+				channels.</para>
+
+			<para>Possible values: 1 .. 13</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdb-hierq-layers">
+			<title>Hierarchical layers</title>
+
+			<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
+				ISDB-T hierarchical layers can be decoded simultaneously. For that
+				reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
+
+			<para>ISDB-T has 3 hierarchical layers which each can use a part of the
+				available segments. The total number of segments over all layers has
+				to 13 in ISDB-T.</para>
+
+			<section id="isdbt-layer-ena">
+				<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
+
+				<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
+					layers in the decoding process. Setting all bits of
+					<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
+					demodulated. This is the default.</para>
+
+				<para>If the channel is in the partial reception mode
+					(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
+					independently of the other 12 segments. In that mode layer A has to
+					have a <constant>SEGMENT_COUNT</constant> of 1.</para>
+
+				<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
+					according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
+					accordingly.</para>
+
+				<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
+
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
+			</section>
+
+			<section id="isdbt-layer-fec">
+				<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
+
+				<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
+			</section>
+
+			<section id="isdbt-layer-mod">
+				<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
+
+				<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
+
+				<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
+					and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
+			</section>
+
+			<section id="isdbt-layer-seg-cnt">
+				<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
+
+				<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
+					<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
+
+				<informaltable id="isdbt-layer_seg-cnt-table">
+					<tgroup cols="6">
+
+						<tbody>
+							<row>
+								<entry>PR</entry>
+								<entry>SB</entry>
+								<entry>Layer A width</entry>
+								<entry>Layer B width</entry>
+								<entry>Layer C width</entry>
+								<entry>total width</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>2</entry>
+								<entry>0</entry>
+								<entry>13</entry>
+							</row>
+						</tbody>
+
+					</tgroup>
+				</informaltable>
+
+			</section>
+
+			<section id="isdbt_layer_t_interl">
+				<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
+
+				<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
+					here are referring to what can be found in the TMCC-structure -
+					independent of the mode.</para>
+			</section>
+		</section>
+	</section>
+</section>
+</section>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/frontend.h.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/frontend.h.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/frontend.h.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/frontend.h.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,415 @@
+<programlisting>
+/*
+ * frontend.h
+ *
+ * Copyright (C) 2000 Marcus Metzler &lt;marcus@convergence.de&gt;
+ *                  Ralph  Metzler &lt;ralph@convergence.de&gt;
+ *                  Holger Waechtler &lt;holger@convergence.de&gt;
+ *                  Andre Draszik &lt;ad@convergence.de&gt;
+ *                  for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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 Lesser 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 _DVBFRONTEND_H_
+#define _DVBFRONTEND_H_
+
+#include &lt;linux/types.h&gt;
+
+typedef enum fe_type {
+        FE_QPSK,
+        FE_QAM,
+        FE_OFDM,
+        FE_ATSC
+} fe_type_t;
+
+
+typedef enum fe_caps {
+        FE_IS_STUPID                    = 0,
+        FE_CAN_INVERSION_AUTO           = 0x1,
+        FE_CAN_FEC_1_2                  = 0x2,
+        FE_CAN_FEC_2_3                  = 0x4,
+        FE_CAN_FEC_3_4                  = 0x8,
+        FE_CAN_FEC_4_5                  = 0x10,
+        FE_CAN_FEC_5_6                  = 0x20,
+        FE_CAN_FEC_6_7                  = 0x40,
+        FE_CAN_FEC_7_8                  = 0x80,
+        FE_CAN_FEC_8_9                  = 0x100,
+        FE_CAN_FEC_AUTO                 = 0x200,
+        FE_CAN_QPSK                     = 0x400,
+        FE_CAN_QAM_16                   = 0x800,
+        FE_CAN_QAM_32                   = 0x1000,
+        FE_CAN_QAM_64                   = 0x2000,
+        FE_CAN_QAM_128                  = 0x4000,
+        FE_CAN_QAM_256                  = 0x8000,
+        FE_CAN_QAM_AUTO                 = 0x10000,
+        FE_CAN_TRANSMISSION_MODE_AUTO   = 0x20000,
+        FE_CAN_BANDWIDTH_AUTO           = 0x40000,
+        FE_CAN_GUARD_INTERVAL_AUTO      = 0x80000,
+        FE_CAN_HIERARCHY_AUTO           = 0x100000,
+        FE_CAN_8VSB                     = 0x200000,
+        FE_CAN_16VSB                    = 0x400000,
+        FE_HAS_EXTENDED_CAPS            = 0x800000,   /* We need more bitspace for newer APIs, indicate this. */
+        FE_CAN_2G_MODULATION            = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
+        FE_NEEDS_BENDING                = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
+        FE_CAN_RECOVER                  = 0x40000000, /* frontend can recover from a cable unplug automatically */
+        FE_CAN_MUTE_TS                  = 0x80000000  /* frontend can stop spurious TS data output */
+} fe_caps_t;
+
+
+struct dvb_frontend_info {
+        char       name[128];
+        fe_type_t  type;
+        __u32      frequency_min;
+        __u32      frequency_max;
+        __u32      frequency_stepsize;
+        __u32      frequency_tolerance;
+        __u32      symbol_rate_min;
+        __u32      symbol_rate_max;
+        __u32      symbol_rate_tolerance;       /* ppm */
+        __u32      notifier_delay;              /* DEPRECATED */
+        fe_caps_t  caps;
+};
+
+
+/**
+ *  Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
+ *  the meaning of this struct...
+ */
+struct dvb_diseqc_master_cmd {
+        __u8 msg [6];   /*  { framing, address, command, data [3] } */
+        __u8 msg_len;   /*  valid values are 3...6  */
+};
+
+
+struct dvb_diseqc_slave_reply {
+        __u8 msg [4];   /*  { framing, data [3] } */
+        __u8 msg_len;   /*  valid values are 0...4, 0 means no msg  */
+        int  timeout;   /*  return from ioctl after timeout ms with */
+};                      /*  errorcode when no message was received  */
+
+
+typedef enum fe_sec_voltage {
+        SEC_VOLTAGE_13,
+        SEC_VOLTAGE_18,
+        SEC_VOLTAGE_OFF
+} fe_sec_voltage_t;
+
+
+typedef enum fe_sec_tone_mode {
+        SEC_TONE_ON,
+        SEC_TONE_OFF
+} fe_sec_tone_mode_t;
+
+
+typedef enum fe_sec_mini_cmd {
+        SEC_MINI_A,
+        SEC_MINI_B
+} fe_sec_mini_cmd_t;
+
+
+typedef enum fe_status {
+        FE_HAS_SIGNAL   = 0x01,   /* found something above the noise level */
+        FE_HAS_CARRIER  = 0x02,   /* found a DVB signal  */
+        FE_HAS_VITERBI  = 0x04,   /* FEC is stable  */
+        FE_HAS_SYNC     = 0x08,   /* found sync bytes  */
+        FE_HAS_LOCK     = 0x10,   /* everything's working... */
+        FE_TIMEDOUT     = 0x20,   /* no lock within the last ~2 seconds */
+        FE_REINIT       = 0x40    /* frontend was reinitialized,  */
+} fe_status_t;                    /* application is recommended to reset */
+                                  /* DiSEqC, tone and parameters */
+
+typedef enum fe_spectral_inversion {
+        INVERSION_OFF,
+        INVERSION_ON,
+        INVERSION_AUTO
+} fe_spectral_inversion_t;
+
+
+typedef enum fe_code_rate {
+        FEC_NONE = 0,
+        FEC_1_2,
+        FEC_2_3,
+        FEC_3_4,
+        FEC_4_5,
+        FEC_5_6,
+        FEC_6_7,
+        FEC_7_8,
+        FEC_8_9,
+        FEC_AUTO,
+        FEC_3_5,
+        FEC_9_10,
+} fe_code_rate_t;
+
+
+typedef enum fe_modulation {
+        QPSK,
+        QAM_16,
+        QAM_32,
+        QAM_64,
+        QAM_128,
+        QAM_256,
+        QAM_AUTO,
+        VSB_8,
+        VSB_16,
+        PSK_8,
+        APSK_16,
+        APSK_32,
+        DQPSK,
+} fe_modulation_t;
+
+typedef enum fe_transmit_mode {
+        TRANSMISSION_MODE_2K,
+        TRANSMISSION_MODE_8K,
+        TRANSMISSION_MODE_AUTO,
+        TRANSMISSION_MODE_4K
+} fe_transmit_mode_t;
+
+typedef enum fe_bandwidth {
+        BANDWIDTH_8_MHZ,
+        BANDWIDTH_7_MHZ,
+        BANDWIDTH_6_MHZ,
+        BANDWIDTH_AUTO
+} fe_bandwidth_t;
+
+
+typedef enum fe_guard_interval {
+        GUARD_INTERVAL_1_32,
+        GUARD_INTERVAL_1_16,
+        GUARD_INTERVAL_1_8,
+        GUARD_INTERVAL_1_4,
+        GUARD_INTERVAL_AUTO
+} fe_guard_interval_t;
+
+
+typedef enum fe_hierarchy {
+        HIERARCHY_NONE,
+        HIERARCHY_1,
+        HIERARCHY_2,
+        HIERARCHY_4,
+        HIERARCHY_AUTO
+} fe_hierarchy_t;
+
+
+struct dvb_qpsk_parameters {
+        __u32           symbol_rate;  /* symbol rate in Symbols per second */
+        fe_code_rate_t  fec_inner;    /* forward error correction (see above) */
+};
+
+struct dvb_qam_parameters {
+        __u32           symbol_rate; /* symbol rate in Symbols per second */
+        fe_code_rate_t  fec_inner;   /* forward error correction (see above) */
+        fe_modulation_t modulation;  /* modulation type (see above) */
+};
+
+struct dvb_vsb_parameters {
+        fe_modulation_t modulation;  /* modulation type (see above) */
+};
+
+struct dvb_ofdm_parameters {
+        fe_bandwidth_t      bandwidth;
+        fe_code_rate_t      code_rate_HP;  /* high priority stream code rate */
+        fe_code_rate_t      code_rate_LP;  /* low priority stream code rate */
+        fe_modulation_t     constellation; /* modulation type (see above) */
+        fe_transmit_mode_t  transmission_mode;
+        fe_guard_interval_t guard_interval;
+        fe_hierarchy_t      hierarchy_information;
+};
+
+
+struct dvb_frontend_parameters {
+        __u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
+                             /* intermediate frequency in kHz for QPSK */
+        fe_spectral_inversion_t inversion;
+        union {
+                struct dvb_qpsk_parameters qpsk;
+                struct dvb_qam_parameters  qam;
+                struct dvb_ofdm_parameters ofdm;
+                struct dvb_vsb_parameters vsb;
+        } u;
+};
+
+
+struct dvb_frontend_event {
+        fe_status_t status;
+        struct dvb_frontend_parameters parameters;
+};
+
+/* S2API Commands */
+#define DTV_UNDEFINED           0
+#define DTV_TUNE                1
+#define DTV_CLEAR               2
+#define DTV_FREQUENCY           3
+#define DTV_MODULATION          4
+#define DTV_BANDWIDTH_HZ        5
+#define DTV_INVERSION           6
+#define DTV_DISEQC_MASTER       7
+#define DTV_SYMBOL_RATE         8
+#define DTV_INNER_FEC           9
+#define DTV_VOLTAGE             10
+#define DTV_TONE                11
+#define DTV_PILOT               12
+#define DTV_ROLLOFF             13
+#define DTV_DISEQC_SLAVE_REPLY  14
+
+/* Basic enumeration set for querying unlimited capabilities */
+#define DTV_FE_CAPABILITY_COUNT 15
+#define DTV_FE_CAPABILITY       16
+#define DTV_DELIVERY_SYSTEM     17
+
+/* ISDB-T and ISDB-Tsb */
+#define DTV_ISDBT_PARTIAL_RECEPTION     18
+#define DTV_ISDBT_SOUND_BROADCASTING    19
+
+#define DTV_ISDBT_SB_SUBCHANNEL_ID      20
+#define DTV_ISDBT_SB_SEGMENT_IDX        21
+#define DTV_ISDBT_SB_SEGMENT_COUNT      22
+
+#define DTV_ISDBT_LAYERA_FEC                    23
+#define DTV_ISDBT_LAYERA_MODULATION             24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT          25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING      26
+
+#define DTV_ISDBT_LAYERB_FEC                    27
+#define DTV_ISDBT_LAYERB_MODULATION             28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT          29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING      30
+
+#define DTV_ISDBT_LAYERC_FEC                    31
+#define DTV_ISDBT_LAYERC_MODULATION             32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT          33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING      34
+
+#define DTV_API_VERSION         35
+
+#define DTV_CODE_RATE_HP        36
+#define DTV_CODE_RATE_LP        37
+#define DTV_GUARD_INTERVAL      38
+#define DTV_TRANSMISSION_MODE   39
+#define DTV_HIERARCHY           40
+
+#define DTV_ISDBT_LAYER_ENABLED 41
+
+#define DTV_ISDBS_TS_ID         42
+
+#define DTV_MAX_COMMAND                         DTV_ISDBS_TS_ID
+
+typedef enum fe_pilot {
+        PILOT_ON,
+        PILOT_OFF,
+        PILOT_AUTO,
+} fe_pilot_t;
+
+typedef enum fe_rolloff {
+        ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
+        ROLLOFF_20,
+        ROLLOFF_25,
+        ROLLOFF_AUTO,
+} fe_rolloff_t;
+
+typedef enum fe_delivery_system {
+        SYS_UNDEFINED,
+        SYS_DVBC_ANNEX_AC,
+        SYS_DVBC_ANNEX_B,
+        SYS_DVBT,
+        SYS_DSS,
+        SYS_DVBS,
+        SYS_DVBS2,
+        SYS_DVBH,
+        SYS_ISDBT,
+        SYS_ISDBS,
+        SYS_ISDBC,
+        SYS_ATSC,
+        SYS_ATSCMH,
+        SYS_DMBTH,
+        SYS_CMMB,
+        SYS_DAB,
+} fe_delivery_system_t;
+
+struct dtv_cmds_h {
+        char    *name;          /* A display name for debugging purposes */
+
+        __u32   cmd;            /* A unique ID */
+
+        /* Flags */
+        __u32   set:1;          /* Either a set or get property */
+        __u32   buffer:1;       /* Does this property use the buffer? */
+        __u32   reserved:30;    /* Align */
+};
+
+struct dtv_property {
+        __u32 cmd;
+        __u32 reserved[3];
+        union {
+                __u32 data;
+                struct {
+                        __u8 data[32];
+                        __u32 len;
+                        __u32 reserved1[3];
+                        void *reserved2;
+                } buffer;
+        } u;
+        int result;
+} __attribute__ ((packed));
+
+/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
+#define DTV_IOCTL_MAX_MSGS 64
+
+struct dtv_properties {
+        __u32 num;
+        struct dtv_property *props;
+};
+
+#define <link linkend="FE_GET_PROPERTY">FE_SET_PROPERTY</link>            _IOW('o', 82, struct dtv_properties)
+#define <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link>            _IOR('o', 83, struct dtv_properties)
+
+
+/**
+ * When set, this flag will disable any zigzagging or other "normal" tuning
+ * behaviour. Additionally, there will be no automatic monitoring of the lock
+ * status, and hence no frontend events will be generated. If a frontend device
+ * is closed, this flag will be automatically turned off when the device is
+ * reopened read-write.
+ */
+#define FE_TUNE_MODE_ONESHOT 0x01
+
+
+#define <link linkend="FE_GET_INFO">FE_GET_INFO</link>                _IOR('o', 61, struct dvb_frontend_info)
+
+#define <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link>   _IO('o', 62)
+#define <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link>  _IOW('o', 63, struct dvb_diseqc_master_cmd)
+#define <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> _IOR('o', 64, struct dvb_diseqc_slave_reply)
+#define <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link>       _IO('o', 65)  /* fe_sec_mini_cmd_t */
+
+#define <link linkend="FE_SET_TONE">FE_SET_TONE</link>                _IO('o', 66)  /* fe_sec_tone_mode_t */
+#define <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link>             _IO('o', 67)  /* fe_sec_voltage_t */
+#define <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link> _IO('o', 68)  /* int */
+
+#define <link linkend="FE_READ_STATUS">FE_READ_STATUS</link>             _IOR('o', 69, fe_status_t)
+#define <link linkend="FE_READ_BER">FE_READ_BER</link>                _IOR('o', 70, __u32)
+#define <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>    _IOR('o', 71, __u16)
+#define <link linkend="FE_READ_SNR">FE_READ_SNR</link>                _IOR('o', 72, __u16)
+#define <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> _IOR('o', 73, __u32)
+
+#define <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link>            _IOW('o', 76, struct dvb_frontend_parameters)
+#define <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link>            _IOR('o', 77, struct dvb_frontend_parameters)
+#define <link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link>  _IO('o', 81) /* unsigned int */
+#define <link linkend="FE_GET_EVENT">FE_GET_EVENT</link>               _IOR('o', 78, struct dvb_frontend_event)
+
+#define <link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link> _IO('o', 80) /* unsigned int */
+
+#endif /*_DVBFRONTEND_H_*/
+</programlisting>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/frontend.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/frontend.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/frontend.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/frontend.xml	2010-02-24 13:52:17.000000000 -0500
@@ -73,7 +73,8 @@ a specific frontend type.</para>
 <section id="frontend_info">
 <title>frontend information</title>
 
-<para>Information about the frontend ca be queried with FE_GET_INFO.</para>
+<para>Information about the frontend ca be queried with
+	<link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
 
 <programlisting>
 	struct dvb_frontend_info {
@@ -338,7 +339,7 @@ modulation mode which can be one of the
 <entry align="char">
 <para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
  for subsequent use. Usually the first thing to do after a successful open is to
- find out the frontend type with FE_GET_INFO.</para>
+ find out the frontend type with <link linkend="FE_GET_INFO">FE_GET_INFO</link>.</para>
 <para>The device can be opened in read-only mode, which only allows monitoring of
  device status and statistics, or read/write mode, which allows any kind of use
  (e.g. performing tuning operations.)
@@ -478,7 +479,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_status">
+<section id="FE_READ_STATUS">
 <title>FE_READ_STATUS</title>
 <para>DESCRIPTION
 </para>
@@ -492,7 +493,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_STATUS,
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_STATUS">FE_READ_STATUS</link>,
  fe_status_t &#x22C6;status);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -511,7 +512,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_STATUS for this command.</para>
+<para>Equals <link linkend="FE_READ_STATUS">FE_READ_STATUS</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -542,7 +543,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_ber">
+<section id="FE_READ_BER">
 <title>FE_READ_BER</title>
 <para>DESCRIPTION
 </para>
@@ -557,7 +558,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_BER,
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_BER">FE_READ_BER</link>,
  uint32_t &#x22C6;ber);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -575,7 +576,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_BER for this command.</para>
+<para>Equals <link linkend="FE_READ_BER">FE_READ_BER</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -619,7 +620,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_snr">
+<section id="FE_READ_SNR">
 <title>FE_READ_SNR</title>
 
 <para>DESCRIPTION
@@ -634,7 +635,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, int16_t
  &#x22C6;snr);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -652,7 +653,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_SNR for this command.</para>
+<para>Equals <link linkend="FE_READ_SNR">FE_READ_SNR</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -697,7 +698,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_signal_strength">
+<section id="FE_READ_SIGNAL_STRENGTH">
 <title>FE_READ_SIGNAL_STRENGTH</title>
 <para>DESCRIPTION
 </para>
@@ -712,7 +713,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl( int fd, int request =
- FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para>
+ <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, int16_t &#x22C6;strength);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -730,7 +731,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_SIGNAL_STRENGTH for this
+<para>Equals <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -775,7 +776,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_read_ub">
+<section id="FE_READ_UNCORRECTED_BLOCKS">
 <title>FE_READ_UNCORRECTED_BLOCKS</title>
 <para>DESCRIPTION
 </para>
@@ -797,7 +798,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl( int fd, int request =
- FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para>
+ <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link>, uint32_t &#x22C6;ublocks);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>PARAMETERS
@@ -814,7 +815,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_READ_UNCORRECTED_BLOCKS for this
+<para>Equals <link linkend="FE_READ_UNCORRECTED_BLOCKS">FE_READ_UNCORRECTED_BLOCKS</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -852,7 +853,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_set_fe">
+<section id="FE_SET_FRONTEND">
 <title>FE_SET_FRONTEND</title>
 <para>DESCRIPTION
 </para>
@@ -861,8 +862,8 @@ modulation mode which can be one of the
 <para>This ioctl call starts a tuning operation using specified parameters. The result
  of this call will be successful if the parameters were valid and the tuning could
  be initiated. The result of the tuning operation in itself, however, will arrive
- asynchronously as an event (see documentation for FE_GET_EVENT and
- FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before
+ asynchronously as an event (see documentation for <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> and
+ FrontendEvent.) If a new <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> operation is initiated before
  the previous one was completed, the previous operation will be aborted in favor
  of the new one. This command requires read/write access to the device.</para>
 </entry>
@@ -872,7 +873,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_FRONTEND,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link>,
  struct dvb_frontend_parameters &#x22C6;p);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -890,7 +891,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_FRONTEND for this command.</para>
+<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -928,7 +929,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_get_fe">
+<section id="FE_GET_FRONTEND">
 <title>FE_GET_FRONTEND</title>
 <para>DESCRIPTION
 </para>
@@ -943,7 +944,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_GET_FRONTEND,
+<para>int ioctl(int fd, int request = <link linkend="FE_GET_FRONTEND">FE_GET_FRONTEND</link>,
  struct dvb_frontend_parameters &#x22C6;p);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -962,7 +963,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_FRONTEND for this command.</para>
+<para>Equals <link linkend="FE_SET_FRONTEND">FE_SET_FRONTEND</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1003,7 +1004,7 @@ modulation mode which can be one of the
 
 </section>
 
-<section id="frontend_get_event">
+<section id="FE_GET_EVENT">
 <title>FE_GET_EVENT</title>
 <para>DESCRIPTION
 </para>
@@ -1024,7 +1025,8 @@ modulation mode which can be one of the
  rather small (room for 8 events), the queue must be serviced regularly to avoid
  overflow. If an overflow happens, the oldest event is discarded from the queue,
  and an error (EOVERFLOW) occurs the next time the queue is read. After
- reporting the error condition in this fashion, subsequent FE_GET_EVENT
+ reporting the error condition in this fashion, subsequent
+ <link linkend="FE_GET_EVENT">FE_GET_EVENT</link>
  calls will return events from the queue as usual.</para>
 </entry>
  </row><row><entry
@@ -1057,7 +1059,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_GET_EVENT for this command.</para>
+<para>Equals <link linkend="FE_GET_EVENT">FE_GET_EVENT</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1115,7 +1117,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_get_info">
+<section id="FE_GET_INFO">
 <title>FE_GET_INFO</title>
 <para>DESCRIPTION
 </para>
@@ -1130,7 +1132,7 @@ modulation mode which can be one of the
 
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para> int ioctl(int fd, int request = FE_GET_INFO, struct
+<para> int ioctl(int fd, int request = <link linkend="FE_GET_INFO">FE_GET_INFO</link>, struct
  dvb_frontend_info &#x22C6;info);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1149,7 +1151,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_GET_INFO for this command.</para>
+<para>Equals <link linkend="FE_GET_INFO">FE_GET_INFO</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1181,7 +1183,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_reset_overload">
+<section id="FE_DISEQC_RESET_OVERLOAD">
 <title>FE_DISEQC_RESET_OVERLOAD</title>
 <para>DESCRIPTION
 </para>
@@ -1199,7 +1201,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_RESET_OVERLOAD);</para>
+ <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link>);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>PARAMETERS
@@ -1216,7 +1218,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_RESET_OVERLOAD for this
+<para>Equals <link linkend="FE_DISEQC_RESET_OVERLOAD">FE_DISEQC_RESET_OVERLOAD</link> for this
  command.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1247,7 +1249,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_send_master_cmd">
+<section id="FE_DISEQC_SEND_MASTER_CMD">
 <title>FE_DISEQC_SEND_MASTER_CMD</title>
 <para>DESCRIPTION
 </para>
@@ -1261,7 +1263,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_SEND_MASTER_CMD, struct
+ <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link>, struct
  dvb_diseqc_master_cmd &#x22C6;cmd);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1280,7 +1282,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_SEND_MASTER_CMD for this
+<para>Equals <link linkend="FE_DISEQC_SEND_MASTER_CMD">FE_DISEQC_SEND_MASTER_CMD</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -1335,7 +1337,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_recv_slave_reply">
+<section id="FE_DISEQC_RECV_SLAVE_REPLY">
 <title>FE_DISEQC_RECV_SLAVE_REPLY</title>
 <para>DESCRIPTION
 </para>
@@ -1350,7 +1352,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_RECV_SLAVE_REPLY, struct
+ <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link>, struct
  dvb_diseqc_slave_reply &#x22C6;reply);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1369,7 +1371,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this
+<para>Equals <link linkend="FE_DISEQC_RECV_SLAVE_REPLY">FE_DISEQC_RECV_SLAVE_REPLY</link> for this
  command.</para>
 </entry>
  </row><row><entry
@@ -1423,7 +1425,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_diseqc_send_burst">
+<section id="FE_DISEQC_SEND_BURST">
 <title>FE_DISEQC_SEND_BURST</title>
 <para>DESCRIPTION
 </para>
@@ -1438,7 +1440,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para>
+ <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link>, fe_sec_mini_cmd_t burst);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -1456,7 +1458,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_DISEQC_SEND_BURST for this command.</para>
+<para>Equals <link linkend="FE_DISEQC_SEND_BURST">FE_DISEQC_SEND_BURST</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1509,7 +1511,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_set_tone">
+<section id="FE_SET_TONE">
 <title>FE_SET_TONE</title>
 <para>DESCRIPTION
 </para>
@@ -1523,7 +1525,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_TONE,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_TONE">FE_SET_TONE</link>,
  fe_sec_tone_mode_t tone);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1541,7 +1543,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_TONE for this command.</para>
+<para>Equals <link linkend="FE_SET_TONE">FE_SET_TONE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1592,7 +1594,7 @@ modulation mode which can be one of the
 </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="fe_set_voltage">
+<section id="FE_SET_VOLTAGE">
 <title>FE_SET_VOLTAGE</title>
 <para>DESCRIPTION
 </para>
@@ -1606,7 +1608,7 @@ modulation mode which can be one of the
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = FE_SET_VOLTAGE,
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link>,
  fe_sec_voltage_t voltage);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -1625,7 +1627,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_VOLTAGE for this command.</para>
+<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1677,7 +1679,7 @@ modulation mode which can be one of the
  </row></tbody></tgroup></informaltable>
 </section>
 
-<section id="frontend_enable_high_lnb_volt">
+<section id="FE_ENABLE_HIGH_LNB_VOLTAGE">
 <title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
 <para>DESCRIPTION
 </para>
@@ -1694,7 +1696,7 @@ modulation mode which can be one of the
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl(int fd, int request =
- FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para>
+ <link linkend="FE_ENABLE_HIGH_LNB_VOLTAGE">FE_ENABLE_HIGH_LNB_VOLTAGE</link>, int high);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -1712,7 +1714,7 @@ modulation mode which can be one of the
 <para>int request</para>
 </entry><entry
  align="char">
-<para>Equals FE_SET_VOLTAGE for this command.</para>
+<para>Equals <link linkend="FE_SET_VOLTAGE">FE_SET_VOLTAGE</link> for this command.</para>
 </entry>
  </row><row><entry
  align="char">
@@ -1762,5 +1764,82 @@ modulation mode which can be one of the
 </entry>
  </row></tbody></tgroup></informaltable>
 </section>
+
+<section id="FE_SET_FRONTEND_TUNE_MODE">
+<title>FE_SET_FRONTEND_TUNE_MODE</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>Allow setting tuner mode flags to the frontend.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>int ioctl(int fd, int request =
+<link linkend="FE_SET_FRONTEND_TUNE_MODE">FE_SET_FRONTEND_TUNE_MODE</link>, unsigned int flags);</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char">
+	<para>unsigned int flags</para>
+</entry>
+<entry align="char">
+<para>
+FE_TUNE_MODE_ONESHOT When set, this flag will disable any zigzagging or other "normal" tuning behaviour. Additionally, there will be no automatic monitoring of the lock status, and hence no frontend events will be generated. If a frontend device is closed, this flag will be automatically turned off when the device is reopened read-write.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char"><para>EINVAL</para></entry>
+<entry align="char"><para>Invalid argument.</para></entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="FE_DISHNETWORK_SEND_LEGACY_CMD">
+	<title>FE_DISHNETWORK_SEND_LEGACY_CMD</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>WARNING: This is a very obscure legacy command, used only at stv0299 driver. Should not be used on newer drivers.</para>
+<para>It provides a non-standard method for selecting Diseqc voltage on the frontend, for Dish Network legacy switches.</para>
+<para>As support for this ioctl were added in 2004, this means that such dishes were already legacy in 2004.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>int ioctl(int fd, int request =
+	<link linkend="FE_DISHNETWORK_SEND_LEGACY_CMD">FE_DISHNETWORK_SEND_LEGACY_CMD</link>, unsigned long cmd);</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+<entry align="char">
+	<para>unsigned long cmd</para>
+</entry>
+<entry align="char">
+<para>
+sends the specified raw cmd to the dish via DISEqC.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+	<para>There are no errors in use for this call</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
 </section>
-&sub-isdbt;
+
+&sub-dvbproperty;
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/isdbt.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/isdbt.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/dvb/isdbt.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/dvb/isdbt.xml	1969-12-31 19:00:00.000000000 -0500
@@ -1,314 +0,0 @@
-<section id="isdbt">
-	<title>ISDB-T frontend</title>
-	<para>This section describes shortly what are the possible parameters in the Linux
-		DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
-		demodulator:</para>
-
-	<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
-		needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
-		that some very sophisticated devices won't need certain parameters to
-		tune.</para>
-
-	<para>The information given here should help application writers to know how
-		to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
-
-	<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
-		basically show the dependencies between the needed parameter values,
-		but surely some information is left out. For more detailed information
-		see the following documents:</para>
-
-	<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
-		Television Broadcasting" and</para>
-	<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
-		Television Broadcasting".</para>
-
-	<para>In order to read this document one has to have some knowledge the
-		channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
-		the reader that an ISDB-T channel consists of 13 segments, that it can
-		have up to 3 layer sharing those segments, and things like that.</para>
-
-	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
-
-	<section id="isdbt-parms">
-		<title>Parameters that are common with DVB-T and ATSC</title>
-
-		<section id="isdbt-freq">
-			<title><constant>DTV_FREQUENCY</constant></title>
-
-			<para>Central frequency of the channel.</para>
-
-			<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
-				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
-				the channel which is 6MHz.</para>
-
-			<para>As in ISDB-Tsb the channel consists of only one or three segments the
-				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
-				central frequency of the channel is expected.</para>
-		</section>
-
-		<section id="isdbt-bw">
-			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
-
-			<para>Possible values:</para>
-
-			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
-			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
-
-			<para>Note: Hardware specific values might be given here, but standard
-				applications should not bother to set a value to this field as
-				standard demods are ignoring it anyway.</para>
-
-			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
-				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
-				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
-		</section>
-
-		<section id="isdbt-delivery-sys">
-			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
-
-			<para>Possible values: <constant>SYS_ISDBT</constant></para>
-		</section>
-
-		<section id="isdbt-tx-mode">
-			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
-
-			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
-				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
-
-			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
-				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
-
-			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
-				hardware will try to find the correct FFT-size (if capable) and will
-				use TMCC to fill in the missing parameters.</para>
-
-			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
-		</section>
-
-		<section id="isdbt-guard-interval">
-			<title><constant>DTV_GUARD_INTERVAL</constant></title>
-
-			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
-				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
-
-			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
-				try to find the correct guard interval (if capable) and will use TMCC to fill
-				in the missing parameters.</para>
-		</section>
-	</section>
-	<section id="isdbt-new-parms">
-		<title>ISDB-T only parameters</title>
-
-		<section id="isdbt-part-rec">
-			<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
-
-			<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
-				the channel is in partial reception mode or not.</para>
-
-			<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
-				<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
-
-			<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
-				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
-				is consisting of one segment and layer or three segments and two layers.</para>
-
-			<para>Possible values: 0, 1, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sound-bcast">
-			<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
-
-			<para>This field represents whether the other DTV_ISDBT_*-parameters are
-				referring to an ISDB-T and an ISDB-Tsb channel. (See also
-				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
-
-			<para>Possible values: 0, 1, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sb-ch-id">
-			<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para>(Note of the author: This might not be the correct description of the
-				<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
-				background needed to program a device)</para>
-
-			<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
-				set of connected ISDB-Tsb channels. In this set of channels every
-				channel can be received independently. The number of connected
-				ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
-				bandwidth available.</para>
-
-			<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
-				broadcaster has several possibilities to put those channels in the
-				air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
-				segments from position 1-8 to 5-13 or anything in between.</para>
-
-			<para>The underlying layer of segments are subchannels: each segment is
-				consisting of several subchannels with a predefined IDs. A sub-channel
-				is used to help the demodulator to synchronize on the channel.</para>
-
-			<para>An ISDB-T channel is always centered over all sub-channels. As for
-				the example above, in ISDB-Tsb it is no longer as simple as that.</para>
-
-			<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
-				sub-channel ID of the segment to be demodulated.</para>
-
-			<para>Possible values: 0 .. 41, -1 (AUTO)</para>
-		</section>
-
-		<section id="isdbt-sb-seg-idx">
-
-			<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
-				demodulated for an ISDB-Tsb channel where several of them are
-				transmitted in the connected manner.</para>
-
-			<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
-
-			<para>Note: This value cannot be determined by an automatic channel search.</para>
-		</section>
-
-		<section id="isdbt-sb-seg-cnt">
-			<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
-
-			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
-
-			<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
-				channels.</para>
-
-			<para>Possible values: 1 .. 13</para>
-
-			<para>Note: This value cannot be determined by an automatic channel search.</para>
-		</section>
-
-		<section id="isdb-hierq-layers">
-			<title>Hierarchical layers</title>
-
-			<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
-				ISDB-T hierarchical layers can be decoded simultaneously. For that
-				reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
-
-			<para>ISDB-T has 3 hierarchical layers which each can use a part of the
-				available segments. The total number of segments over all layers has
-				to 13 in ISDB-T.</para>
-
-			<section id="isdbt-layer-ena">
-				<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
-
-				<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
-					layers in the decoding process. Setting all bits of
-					<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
-					demodulated. This is the default.</para>
-
-				<para>If the channel is in the partial reception mode
-					(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
-					independently of the other 12 segments. In that mode layer A has to
-					have a <constant>SEGMENT_COUNT</constant> of 1.</para>
-
-				<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
-					according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
-					accordingly.</para>
-
-				<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
-
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
-				<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
-			</section>
-
-			<section id="isdbt-layer-fec">
-				<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
-
-				<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
-			</section>
-
-			<section id="isdbt-layer-mod">
-				<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
-
-				<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
-
-				<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
-					and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
-			</section>
-
-			<section id="isdbt-layer-seg-cnt">
-				<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
-
-				<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
-
-				<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
-					<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
-
-				<informaltable id="isdbt-layer_seg-cnt-table">
-					<tgroup cols="6">
-
-						<tbody>
-							<row>
-								<entry>PR</entry>
-								<entry>SB</entry>
-								<entry>Layer A width</entry>
-								<entry>Layer B width</entry>
-								<entry>Layer C width</entry>
-								<entry>total width</entry>
-							</row>
-
-							<row>
-								<entry>0</entry>
-								<entry>0</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>13</entry>
-							</row>
-
-							<row>
-								<entry>1</entry>
-								<entry>0</entry>
-								<entry>1</entry>
-								<entry>1 .. 13</entry>
-								<entry>1 .. 13</entry>
-								<entry>13</entry>
-							</row>
-
-							<row>
-								<entry>0</entry>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>0</entry>
-								<entry>0</entry>
-								<entry>1</entry>
-							</row>
-
-							<row>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>1</entry>
-								<entry>2</entry>
-								<entry>0</entry>
-								<entry>13</entry>
-							</row>
-						</tbody>
-
-					</tgroup>
-				</informaltable>
-
-			</section>
-
-			<section id="isdbt_layer_t_interl">
-				<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
-
-				<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
-
-				<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
-					here are referring to what can be found in the TMCC-structure -
-					independent of the mode.</para>
-			</section>
-		</section>
-	</section>
-</section>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/genericirq.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/genericirq.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/genericirq.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/genericirq.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -417,8 +417,8 @@ desc->chip->end();
       </para>
       <para>
 	To make use of the split implementation, replace the call to
-	__do_IRQ by a call to desc->chip->handle_irq() and associate
-        the appropriate handler function to desc->chip->handle_irq().
+	__do_IRQ by a call to desc->handle_irq() and associate
+        the appropriate handler function to desc->handle_irq().
 	In most cases the generic handler implementations should
 	be sufficient.
      </para>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/kernel-hacking.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/kernel-hacking.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/kernel-hacking.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/kernel-hacking.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -352,7 +352,7 @@ asmlinkage long sys_mycall(int arg)
   </para>
 
   <programlisting>
-if (signal_pending()) 
+if (signal_pending(current))
         return -ERESTARTSYS;
   </programlisting>
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/Makefile linux-libre-2.6.33-gnu1/Documentation/DocBook/Makefile
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
 
 DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
-	    procfs-guide.xml writing_usb_driver.xml networking.xml \
+	    writing_usb_driver.xml networking.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
 	    genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
@@ -32,10 +32,10 @@ PS_METHOD	= $(prefer-db2x)
 
 ###
 # The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
 
 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
-xmldocs: $(BOOKS)
+xmldocs: $(BOOKS) xmldoclinks
 sgmldocs: xmldocs
 
 PS := $(patsubst %.xml, %.ps, $(BOOKS))
@@ -45,15 +45,24 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS)
 pdfdocs: $(PDF)
 
 HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
-htmldocs: media $(HTML)
+htmldocs: $(HTML)
 	$(call build_main_index)
+	$(call build_images)
 
 MAN := $(patsubst %.xml, %.9, $(BOOKS))
 mandocs: $(MAN)
 
-media:
-	mkdir -p $(srctree)/Documentation/DocBook/media/
-	cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
+build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
+	       cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
+
+xmldoclinks:
+ifneq ($(objtree),$(srctree))
+	for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
+		rm -f $(objtree)/Documentation/DocBook/$$dep \
+		&& ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
+		|| exit; \
+	done
+endif
 
 installmandocs: mandocs
 	mkdir -p /usr/local/man/man9/
@@ -65,7 +74,7 @@ KERNELDOC = $(srctree)/scripts/kernel-do
 DOCPROC   = $(objtree)/scripts/basic/docproc
 
 XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
-#XMLTOFLAGS += --skip-validation
+XMLTOFLAGS += --skip-validation
 
 ###
 # DOCPROC is used for two purposes:
@@ -101,17 +110,6 @@ endif
 # Changes in kernel-doc force a rebuild of all documentation
 $(BOOKS): $(KERNELDOC)
 
-###
-# procfs guide uses a .c file as example code.
-# This requires an explicit dependency
-C-procfs-example = procfs_example.xml
-C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
-$(obj)/procfs-guide.xml: $(C-procfs-example2)
-
-# List of programs to build
-##oops, this is a kernel module::hostprogs-y := procfs_example
-obj-m += procfs_example.o
-
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
 
@@ -238,7 +236,7 @@ clean-files := $(DOCBOOKS) \
 	$(patsubst %.xml, %.pdf,  $(DOCBOOKS)) \
 	$(patsubst %.xml, %.html, $(DOCBOOKS)) \
 	$(patsubst %.xml, %.9,    $(DOCBOOKS)) \
-	$(C-procfs-example) $(index)
+	$(index)
 
 clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/media-entities.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/media-entities.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/media-entities.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/media-entities.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 <!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
 <!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
 <!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
+<!ENTITY VIDIOC-ENUM-DV-PRESETS "<link linkend='vidioc-enum-dv-presets'><constant>VIDIOC_ENUM_DV_PRESETS</constant></link>">
 <!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
 <!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
 <!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
@@ -30,6 +31,8 @@
 <!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
 <!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
 <!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
+<!ENTITY VIDIOC-G-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_G_DV_PRESET</constant></link>">
+<!ENTITY VIDIOC-G-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_G_DV_TIMINGS</constant></link>">
 <!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
 <!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
 <!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
@@ -53,6 +56,7 @@
 <!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
 <!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
 <!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
+<!ENTITY VIDIOC-QUERY-DV-PRESET "<link linkend='vidioc-query-dv-preset'><constant>VIDIOC_QUERY_DV_PRESET</constant></link>">
 <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
 <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
 <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
@@ -60,6 +64,8 @@
 <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
 <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
 <!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
+<!ENTITY VIDIOC-S-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_S_DV_PRESET</constant></link>">
+<!ENTITY VIDIOC-S-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_S_DV_TIMINGS</constant></link>">
 <!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
 <!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
 <!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
@@ -118,6 +124,7 @@
 <!-- Structures -->
 <!ENTITY v4l2-audio "struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link>">
 <!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
+<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
 <!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
 <!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
 <!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
@@ -128,6 +135,9 @@
 <!ENTITY v4l2-dbg-chip-ident "struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
 <!ENTITY v4l2-dbg-match "struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
 <!ENTITY v4l2-dbg-register "struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
+<!ENTITY v4l2-dv-enum-preset "struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link>">
+<!ENTITY v4l2-dv-preset "struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link>">
+<!ENTITY v4l2-dv-timings "struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link>">
 <!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
 <!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
 <!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
@@ -243,6 +253,10 @@
 <!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
 <!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
 <!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY sub-enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
+<!ENTITY sub-g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
+<!ENTITY sub-query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
+<!ENTITY sub-g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
 <!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
 <!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
 <!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
@@ -280,7 +294,7 @@
 <!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
 <!ENTITY sub-intro SYSTEM "dvb/intro.xml">
 <!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
-<!ENTITY sub-isdbt SYSTEM "dvb/isdbt.xml">
+<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
 <!ENTITY sub-demux SYSTEM "dvb/demux.xml">
 <!ENTITY sub-video SYSTEM "dvb/video.xml">
 <!ENTITY sub-audio SYSTEM "dvb/audio.xml">
@@ -288,6 +302,7 @@
 <!ENTITY sub-net SYSTEM "dvb/net.xml">
 <!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
 <!ENTITY sub-examples SYSTEM "dvb/examples.xml">
+<!ENTITY sub-frontend-h SYSTEM "dvb/frontend.h.xml">
 <!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
 <!ENTITY sub-media SYSTEM "media.xml">
 <!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
@@ -332,6 +347,10 @@
 <!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
 <!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
 <!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
+<!ENTITY g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
+<!ENTITY query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
+<!ENTITY g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
 <!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
 <!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
 <!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/media-indices.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/media-indices.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/media-indices.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/media-indices.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,7 @@
 <indexentry><primaryie>enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
@@ -46,6 +47,9 @@
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-preset'>v4l2_dv_preset</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dv-timings'>v4l2_dv_timings</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
 <indexentry><primaryie>struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/mtdnand.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/mtdnand.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/mtdnand.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/mtdnand.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -174,7 +174,7 @@
 		</para>
 		<programlisting>
 static struct mtd_info *board_mtd;
-static unsigned long baseaddr;
+static void __iomem *baseaddr;
 		</programlisting>
 		<para>
 			Static example
@@ -182,7 +182,7 @@ static unsigned long baseaddr;
 		<programlisting>
 static struct mtd_info board_mtd;
 static struct nand_chip board_chip;
-static unsigned long baseaddr;
+static void __iomem *baseaddr;
 		</programlisting>
 	</sect1>
 	<sect1 id="Partition_defines">
@@ -283,8 +283,8 @@ int __init board_init (void)
 	}
 
 	/* map physical address */
-	baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
-	if(!baseaddr){
+	baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
+	if (!baseaddr) {
 		printk("Ioremap to access NAND chip failed\n");
 		err = -EIO;
 		goto out_mtd;
@@ -316,7 +316,7 @@ int __init board_init (void)
 	goto out;
 
 out_ior:
-	iounmap((void *)baseaddr);
+	iounmap(baseaddr);
 out_mtd:
 	kfree (board_mtd);
 out:
@@ -341,7 +341,7 @@ static void __exit board_cleanup (void)
 	nand_release (board_mtd);
 
 	/* unmap physical address */
-	iounmap((void *)baseaddr);
+	iounmap(baseaddr);
 	
 	/* Free the MTD device structure */
 	kfree (board_mtd);
@@ -362,7 +362,7 @@ module_exit(board_cleanup);
 	<sect1 id="Multiple_chip_control">
 		<title>Multiple chip control</title>
 		<para>
-			The nand driver can control chip arrays. Therefor the
+			The nand driver can control chip arrays. Therefore the
 			board driver must provide an own select_chip function. This
 			function must (de)select the requested chip.
 			The function pointer in the nand_chip structure must
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/procfs_example.c linux-libre-2.6.33-gnu1/Documentation/DocBook/procfs_example.c
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/procfs_example.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/procfs_example.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,201 +0,0 @@
-/*
- * procfs_example.c: an example proc interface
- *
- * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)
- *
- * This file accompanies the procfs-guide in the Linux kernel
- * source. Its main use is to demonstrate the concepts and
- * functions described in the guide.
- *
- * This software has been developed while working on the LART
- * computing board (http://www.lartmaker.nl), which was sponsored
- * by the Delt University of Technology projects Mobile Multi-media
- * Communications and Ubiquitous Communications.
- *
- * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/jiffies.h>
-#include <asm/uaccess.h>
-
-
-#define MODULE_VERS "1.0"
-#define MODULE_NAME "procfs_example"
-
-#define FOOBAR_LEN 8
-
-struct fb_data_t {
-	char name[FOOBAR_LEN + 1];
-	char value[FOOBAR_LEN + 1];
-};
-
-
-static struct proc_dir_entry *example_dir, *foo_file,
-	*bar_file, *jiffies_file, *symlink;
-
-
-struct fb_data_t foo_data, bar_data;
-
-
-static int proc_read_jiffies(char *page, char **start,
-			     off_t off, int count,
-			     int *eof, void *data)
-{
-	int len;
-
-	len = sprintf(page, "jiffies = %ld\n",
-                      jiffies);
-
-	return len;
-}
-
-
-static int proc_read_foobar(char *page, char **start,
-			    off_t off, int count, 
-			    int *eof, void *data)
-{
-	int len;
-	struct fb_data_t *fb_data = (struct fb_data_t *)data;
-
-	/* DON'T DO THAT - buffer overruns are bad */
-	len = sprintf(page, "%s = '%s'\n", 
-		      fb_data->name, fb_data->value);
-
-	return len;
-}
-
-
-static int proc_write_foobar(struct file *file,
-			     const char *buffer,
-			     unsigned long count, 
-			     void *data)
-{
-	int len;
-	struct fb_data_t *fb_data = (struct fb_data_t *)data;
-
-	if(count > FOOBAR_LEN)
-		len = FOOBAR_LEN;
-	else
-		len = count;
-
-	if(copy_from_user(fb_data->value, buffer, len))
-		return -EFAULT;
-
-	fb_data->value[len] = '\0';
-
-	return len;
-}
-
-
-static int __init init_procfs_example(void)
-{
-	int rv = 0;
-
-	/* create directory */
-	example_dir = proc_mkdir(MODULE_NAME, NULL);
-	if(example_dir == NULL) {
-		rv = -ENOMEM;
-		goto out;
-	}
-	/* create jiffies using convenience function */
-	jiffies_file = create_proc_read_entry("jiffies", 
-					      0444, example_dir, 
-					      proc_read_jiffies,
-					      NULL);
-	if(jiffies_file == NULL) {
-		rv  = -ENOMEM;
-		goto no_jiffies;
-	}
-
-	/* create foo and bar files using same callback
-	 * functions 
-	 */
-	foo_file = create_proc_entry("foo", 0644, example_dir);
-	if(foo_file == NULL) {
-		rv = -ENOMEM;
-		goto no_foo;
-	}
-
-	strcpy(foo_data.name, "foo");
-	strcpy(foo_data.value, "foo");
-	foo_file->data = &foo_data;
-	foo_file->read_proc = proc_read_foobar;
-	foo_file->write_proc = proc_write_foobar;
-		
-	bar_file = create_proc_entry("bar", 0644, example_dir);
-	if(bar_file == NULL) {
-		rv = -ENOMEM;
-		goto no_bar;
-	}
-
-	strcpy(bar_data.name, "bar");
-	strcpy(bar_data.value, "bar");
-	bar_file->data = &bar_data;
-	bar_file->read_proc = proc_read_foobar;
-	bar_file->write_proc = proc_write_foobar;
-		
-	/* create symlink */
-	symlink = proc_symlink("jiffies_too", example_dir, 
-			       "jiffies");
-	if(symlink == NULL) {
-		rv = -ENOMEM;
-		goto no_symlink;
-	}
-
-	/* everything OK */
-	printk(KERN_INFO "%s %s initialised\n",
-	       MODULE_NAME, MODULE_VERS);
-	return 0;
-
-no_symlink:
-	remove_proc_entry("bar", example_dir);
-no_bar:
-	remove_proc_entry("foo", example_dir);
-no_foo:
-	remove_proc_entry("jiffies", example_dir);
-no_jiffies:			      
-	remove_proc_entry(MODULE_NAME, NULL);
-out:
-	return rv;
-}
-
-
-static void __exit cleanup_procfs_example(void)
-{
-	remove_proc_entry("jiffies_too", example_dir);
-	remove_proc_entry("bar", example_dir);
-	remove_proc_entry("foo", example_dir);
-	remove_proc_entry("jiffies", example_dir);
-	remove_proc_entry(MODULE_NAME, NULL);
-
-	printk(KERN_INFO "%s %s removed\n",
-	       MODULE_NAME, MODULE_VERS);
-}
-
-
-module_init(init_procfs_example);
-module_exit(cleanup_procfs_example);
-
-MODULE_AUTHOR("Erik Mouw");
-MODULE_DESCRIPTION("procfs examples");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/procfs-guide.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/procfs-guide.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/procfs-guide.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/procfs-guide.tmpl	1969-12-31 19:00:00.000000000 -0500
@@ -1,626 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-<!ENTITY procfsexample SYSTEM "procfs_example.xml">
-]>
-
-<book id="LKProcfsGuide">
-  <bookinfo>
-    <title>Linux Kernel Procfs Guide</title>
-
-    <authorgroup>
-      <author>
-	<firstname>Erik</firstname>
-	<othername>(J.A.K.)</othername>
-	<surname>Mouw</surname>
-	<affiliation>
-	  <address>
-            <email>mouw@nl.linux.org</email>
-          </address>
-	</affiliation>
-      </author>
-      <othercredit>
-	<contrib>
-	This software and documentation were written while working on the
-	LART computing board
-	(<ulink url="http://www.lartmaker.nl/">http://www.lartmaker.nl/</ulink>),
-	which was sponsored by the Delt University of Technology projects
-	Mobile Multi-media Communications and Ubiquitous Communications.
-	</contrib>
-      </othercredit>
-    </authorgroup>
-
-    <revhistory>
-      <revision>
-	<revnumber>1.0</revnumber>
-	<date>May 30, 2001</date>
-	<revremark>Initial revision posted to linux-kernel</revremark>
-      </revision>
-      <revision>
-	<revnumber>1.1</revnumber>
-	<date>June 3, 2001</date>
-	<revremark>Revised after comments from linux-kernel</revremark>
-      </revision>
-    </revhistory>
-
-    <copyright>
-      <year>2001</year>
-      <holder>Erik Mouw</holder>
-    </copyright>
-
-
-    <legalnotice>
-      <para>
-        This documentation 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.
-      </para>
-      
-      <para>
-        This documentation is distributed in the hope that it will be
-        useful, but WITHOUT ANY WARRANTY; without even the implied
-        warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-        PURPOSE.  See the GNU General Public License for more details.
-      </para>
-      
-      <para>
-        You 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
-      </para>
-      
-      <para>
-        For more details see the file COPYING in the source
-        distribution of Linux.
-      </para>
-    </legalnotice>
-  </bookinfo>
-
-
-
-
-  <toc>
-  </toc>
-
-
-
-
-  <preface id="Preface">
-    <title>Preface</title>
-
-    <para>
-      This guide describes the use of the procfs file system from
-      within the Linux kernel. The idea to write this guide came up on
-      the #kernelnewbies IRC channel (see <ulink
-      url="http://www.kernelnewbies.org/">http://www.kernelnewbies.org/</ulink>),
-      when Jeff Garzik explained the use of procfs and forwarded me a
-      message Alexander Viro wrote to the linux-kernel mailing list. I
-      agreed to write it up nicely, so here it is.
-    </para>
-
-    <para>
-      I'd like to thank Jeff Garzik
-      <email>jgarzik@pobox.com</email> and Alexander Viro
-      <email>viro@parcelfarce.linux.theplanet.co.uk</email> for their input,
-      Tim Waugh <email>twaugh@redhat.com</email> for his <ulink
-      url="http://people.redhat.com/twaugh/docbook/selfdocbook/">Selfdocbook</ulink>,
-      and Marc Joosen <email>marcj@historia.et.tudelft.nl</email> for
-      proofreading.
-    </para>
-
-    <para>
-      Erik
-    </para>
-  </preface>
-
-
-
-
-  <chapter id="intro">
-    <title>Introduction</title>
-
-    <para>
-      The <filename class="directory">/proc</filename> file system
-      (procfs) is a special file system in the linux kernel. It's a
-      virtual file system: it is not associated with a block device
-      but exists only in memory. The files in the procfs are there to
-      allow userland programs access to certain information from the
-      kernel (like process information in <filename
-      class="directory">/proc/[0-9]+/</filename>), but also for debug
-      purposes (like <filename>/proc/ksyms</filename>).
-    </para>
-
-    <para>
-      This guide describes the use of the procfs file system from
-      within the Linux kernel. It starts by introducing all relevant
-      functions to manage the files within the file system. After that
-      it shows how to communicate with userland, and some tips and
-      tricks will be pointed out. Finally a complete example will be
-      shown.
-    </para>
-
-    <para>
-      Note that the files in <filename
-      class="directory">/proc/sys</filename> are sysctl files: they
-      don't belong to procfs and are governed by a completely
-      different API described in the Kernel API book.
-    </para>
-  </chapter>
-
-
-
-
-  <chapter id="managing">
-    <title>Managing procfs entries</title>
-    
-    <para>
-      This chapter describes the functions that various kernel
-      components use to populate the procfs with files, symlinks,
-      device nodes, and directories.
-    </para>
-
-    <para>
-      A minor note before we start: if you want to use any of the
-      procfs functions, be sure to include the correct header file! 
-      This should be one of the first lines in your code:
-    </para>
-
-    <programlisting>
-#include &lt;linux/proc_fs.h&gt;
-    </programlisting>
-
-
-
-
-    <sect1 id="regularfile">
-      <title>Creating a regular file</title>
-      
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>struct proc_dir_entry* <function>create_proc_entry</function></funcdef>
-	  <paramdef>const char* <parameter>name</parameter></paramdef>
-	  <paramdef>mode_t <parameter>mode</parameter></paramdef>
-	  <paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-
-      <para>
-        This function creates a regular file with the name
-        <parameter>name</parameter>, file mode
-        <parameter>mode</parameter> in the directory
-        <parameter>parent</parameter>. To create a file in the root of
-        the procfs, use <constant>NULL</constant> as
-        <parameter>parent</parameter> parameter. When successful, the
-        function will return a pointer to the freshly created
-        <structname>struct proc_dir_entry</structname>; otherwise it
-        will return <constant>NULL</constant>. <xref
-        linkend="userland"/> describes how to do something useful with
-        regular files.
-      </para>
-
-      <para>
-        Note that it is specifically supported that you can pass a
-        path that spans multiple directories. For example
-        <function>create_proc_entry</function>(<parameter>"drivers/via0/info"</parameter>)
-        will create the <filename class="directory">via0</filename>
-        directory if necessary, with standard
-        <constant>0755</constant> permissions.
-      </para>
-
-    <para>
-      If you only want to be able to read the file, the function
-      <function>create_proc_read_entry</function> described in <xref
-      linkend="convenience"/> may be used to create and initialise
-      the procfs entry in one single call.
-    </para>
-    </sect1>
-
-
-
-
-    <sect1 id="Creating_a_symlink">
-      <title>Creating a symlink</title>
-
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>struct proc_dir_entry*
-	  <function>proc_symlink</function></funcdef> <paramdef>const
-	  char* <parameter>name</parameter></paramdef>
-	  <paramdef>struct proc_dir_entry*
-	  <parameter>parent</parameter></paramdef> <paramdef>const
-	  char* <parameter>dest</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-      
-      <para>
-        This creates a symlink in the procfs directory
-        <parameter>parent</parameter> that points from
-        <parameter>name</parameter> to
-        <parameter>dest</parameter>. This translates in userland to
-        <literal>ln -s</literal> <parameter>dest</parameter>
-        <parameter>name</parameter>.
-      </para>
-    </sect1>
-
-    <sect1 id="Creating_a_directory">
-      <title>Creating a directory</title>
-      
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>struct proc_dir_entry* <function>proc_mkdir</function></funcdef>
-	  <paramdef>const char* <parameter>name</parameter></paramdef>
-	  <paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-
-      <para>
-        Create a directory <parameter>name</parameter> in the procfs
-        directory <parameter>parent</parameter>.
-      </para>
-    </sect1>
-
-
-
-
-    <sect1 id="Removing_an_entry">
-      <title>Removing an entry</title>
-      
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>void <function>remove_proc_entry</function></funcdef>
-	  <paramdef>const char* <parameter>name</parameter></paramdef>
-	  <paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-
-      <para>
-        Removes the entry <parameter>name</parameter> in the directory
-        <parameter>parent</parameter> from the procfs. Entries are
-        removed by their <emphasis>name</emphasis>, not by the
-        <structname>struct proc_dir_entry</structname> returned by the
-        various create functions. Note that this function doesn't
-        recursively remove entries.
-      </para>
-
-      <para>
-        Be sure to free the <structfield>data</structfield> entry from
-        the <structname>struct proc_dir_entry</structname> before
-        <function>remove_proc_entry</function> is called (that is: if
-        there was some <structfield>data</structfield> allocated, of
-        course). See <xref linkend="usingdata"/> for more information
-        on using the <structfield>data</structfield> entry.
-      </para>
-    </sect1>
-  </chapter>
-
-
-
-
-  <chapter id="userland">
-    <title>Communicating with userland</title>
-    
-    <para>
-       Instead of reading (or writing) information directly from
-       kernel memory, procfs works with <emphasis>call back
-       functions</emphasis> for files: functions that are called when
-       a specific file is being read or written. Such functions have
-       to be initialised after the procfs file is created by setting
-       the <structfield>read_proc</structfield> and/or
-       <structfield>write_proc</structfield> fields in the
-       <structname>struct proc_dir_entry*</structname> that the
-       function <function>create_proc_entry</function> returned:
-    </para>
-
-    <programlisting>
-struct proc_dir_entry* entry;
-
-entry->read_proc = read_proc_foo;
-entry->write_proc = write_proc_foo;
-    </programlisting>
-
-    <para>
-      If you only want to use a the
-      <structfield>read_proc</structfield>, the function
-      <function>create_proc_read_entry</function> described in <xref
-      linkend="convenience"/> may be used to create and initialise the
-      procfs entry in one single call.
-    </para>
-
-
-
-    <sect1 id="Reading_data">
-      <title>Reading data</title>
-
-      <para>
-        The read function is a call back function that allows userland
-        processes to read data from the kernel. The read function
-        should have the following format:
-      </para>
-
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>int <function>read_func</function></funcdef>
-	  <paramdef>char* <parameter>buffer</parameter></paramdef>
-	  <paramdef>char** <parameter>start</parameter></paramdef>
-	  <paramdef>off_t <parameter>off</parameter></paramdef>
-	  <paramdef>int <parameter>count</parameter></paramdef>
-	  <paramdef>int* <parameter>peof</parameter></paramdef>
-	  <paramdef>void* <parameter>data</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-
-      <para>
-        The read function should write its information into the
-        <parameter>buffer</parameter>, which will be exactly
-        <literal>PAGE_SIZE</literal> bytes long.
-      </para>
-
-      <para>
-        The parameter
-        <parameter>peof</parameter> should be used to signal that the
-        end of the file has been reached by writing
-        <literal>1</literal> to the memory location
-        <parameter>peof</parameter> points to.
-      </para>
-
-      <para>
-        The <parameter>data</parameter>
-        parameter can be used to create a single call back function for
-        several files, see <xref linkend="usingdata"/>.
-      </para>
-
-      <para>
-        The rest of the parameters and the return value are described
-	by a comment in <filename>fs/proc/generic.c</filename> as follows:
-      </para>
-
-      <blockquote>
-        <para>
-	You have three ways to return data:
-       	</para>
-        <orderedlist>
-          <listitem>
-            <para>
-	      Leave <literal>*start = NULL</literal>.  (This is the default.)
-	      Put the data of the requested offset at that
-	      offset within the buffer.  Return the number (<literal>n</literal>)
-	      of bytes there are from the beginning of the
-	      buffer up to the last byte of data.  If the
-	      number of supplied bytes (<literal>= n - offset</literal>) is
-	      greater than zero and you didn't signal eof
-	      and the reader is prepared to take more data
-	      you will be called again with the requested
-	      offset advanced by the number of bytes
-	      absorbed.  This interface is useful for files
-	      no larger than the buffer.
-	    </para>
-	  </listitem>
-	  <listitem>
-            <para>
-	      Set <literal>*start</literal> to an unsigned long value less than
-	      the buffer address but greater than zero.
-	      Put the data of the requested offset at the
-	      beginning of the buffer.  Return the number of
-	      bytes of data placed there.  If this number is
-	      greater than zero and you didn't signal eof
-	      and the reader is prepared to take more data
-	      you will be called again with the requested
-	      offset advanced by <literal>*start</literal>.  This interface is
-	      useful when you have a large file consisting
-	      of a series of blocks which you want to count
-	      and return as wholes.
-	      (Hack by Paul.Russell@rustcorp.com.au)
-	    </para>
-	  </listitem>
-	  <listitem>
-            <para>
-	      Set <literal>*start</literal> to an address within the buffer.
-	      Put the data of the requested offset at <literal>*start</literal>.
-	      Return the number of bytes of data placed there.
-	      If this number is greater than zero and you
-	      didn't signal eof and the reader is prepared to
-	      take more data you will be called again with the
-	      requested offset advanced by the number of bytes
-	      absorbed.
-	    </para>
-	  </listitem>
-	</orderedlist>
-      </blockquote>
-
-      <para>
-        <xref linkend="example"/> shows how to use a read call back
-        function.
-      </para>
-    </sect1>
-
-
-
-
-    <sect1 id="Writing_data">
-      <title>Writing data</title>
-
-      <para>
-        The write call back function allows a userland process to write
-        data to the kernel, so it has some kind of control over the
-        kernel. The write function should have the following format:
-      </para>
-
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>int <function>write_func</function></funcdef>
-	  <paramdef>struct file* <parameter>file</parameter></paramdef>
-	  <paramdef>const char* <parameter>buffer</parameter></paramdef>
-	  <paramdef>unsigned long <parameter>count</parameter></paramdef>
-	  <paramdef>void* <parameter>data</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-
-      <para>
-        The write function should read <parameter>count</parameter>
-        bytes at maximum from the <parameter>buffer</parameter>. Note
-        that the <parameter>buffer</parameter> doesn't live in the
-        kernel's memory space, so it should first be copied to kernel
-        space with <function>copy_from_user</function>. The
-        <parameter>file</parameter> parameter is usually
-        ignored. <xref linkend="usingdata"/> shows how to use the
-        <parameter>data</parameter> parameter.
-      </para>
-
-      <para>
-        Again, <xref linkend="example"/> shows how to use this call back
-        function.
-      </para>
-    </sect1>
-
-
-
-
-    <sect1 id="usingdata">
-      <title>A single call back for many files</title>
-
-      <para>
-         When a large number of almost identical files is used, it's
-         quite inconvenient to use a separate call back function for
-         each file. A better approach is to have a single call back
-         function that distinguishes between the files by using the
-         <structfield>data</structfield> field in <structname>struct
-         proc_dir_entry</structname>. First of all, the
-         <structfield>data</structfield> field has to be initialised:
-      </para>
-
-      <programlisting>
-struct proc_dir_entry* entry;
-struct my_file_data *file_data;
-
-file_data = kmalloc(sizeof(struct my_file_data), GFP_KERNEL);
-entry->data = file_data;
-      </programlisting>
-     
-      <para>
-          The <structfield>data</structfield> field is a <type>void
-          *</type>, so it can be initialised with anything.
-      </para>
-
-      <para>
-        Now that the <structfield>data</structfield> field is set, the
-        <function>read_proc</function> and
-        <function>write_proc</function> can use it to distinguish
-        between files because they get it passed into their
-        <parameter>data</parameter> parameter:
-      </para>
-
-      <programlisting>
-int foo_read_func(char *page, char **start, off_t off,
-                  int count, int *eof, void *data)
-{
-        int len;
-
-        if(data == file_data) {
-                /* special case for this file */
-        } else {
-                /* normal processing */
-        }
-
-        return len;
-}
-      </programlisting>
-
-      <para>
-        Be sure to free the <structfield>data</structfield> data field
-        when removing the procfs entry.
-      </para>
-    </sect1>
-  </chapter>
-
-
-
-
-  <chapter id="tips">
-    <title>Tips and tricks</title>
-
-
-
-
-    <sect1 id="convenience">
-      <title>Convenience functions</title>
-
-      <funcsynopsis>
-	<funcprototype>
-	  <funcdef>struct proc_dir_entry* <function>create_proc_read_entry</function></funcdef>
-	  <paramdef>const char* <parameter>name</parameter></paramdef>
-	  <paramdef>mode_t <parameter>mode</parameter></paramdef>
-	  <paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>
-	  <paramdef>read_proc_t* <parameter>read_proc</parameter></paramdef>
-	  <paramdef>void* <parameter>data</parameter></paramdef>
-	</funcprototype>
-      </funcsynopsis>
-      
-      <para>
-        This function creates a regular file in exactly the same way
-        as <function>create_proc_entry</function> from <xref
-        linkend="regularfile"/> does, but also allows to set the read
-        function <parameter>read_proc</parameter> in one call. This
-        function can set the <parameter>data</parameter> as well, like
-        explained in <xref linkend="usingdata"/>.
-      </para>
-    </sect1>
-
-
-
-    <sect1 id="Modules">
-      <title>Modules</title>
-
-      <para>
-        If procfs is being used from within a module, be sure to set
-        the <structfield>owner</structfield> field in the
-        <structname>struct proc_dir_entry</structname> to
-        <constant>THIS_MODULE</constant>.
-      </para>
-
-      <programlisting>
-struct proc_dir_entry* entry;
-
-entry->owner = THIS_MODULE;
-      </programlisting>
-    </sect1>
-
-
-
-
-    <sect1 id="Mode_and_ownership">
-      <title>Mode and ownership</title>
-
-      <para>
-        Sometimes it is useful to change the mode and/or ownership of
-        a procfs entry. Here is an example that shows how to achieve
-        that:
-      </para>
-
-      <programlisting>
-struct proc_dir_entry* entry;
-
-entry->mode =  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH;
-entry->uid = 0;
-entry->gid = 100;
-      </programlisting>
-
-    </sect1>
-  </chapter>
-
-
-
-
-  <chapter id="example">
-    <title>Example</title>
-
-    <!-- be careful with the example code: it shouldn't be wider than
-    approx. 60 columns, or otherwise it won't fit properly on a page
-    -->
-
-&procfsexample;
-
-  </chapter>
-</book>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/tracepoint.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/tracepoint.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/tracepoint.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/tracepoint.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -86,4 +86,9 @@
 !Iinclude/trace/events/irq.h
   </chapter>
 
+  <chapter id="signal">
+   <title>SIGNAL</title>
+!Iinclude/trace/events/signal.h
+  </chapter>
+
 </book>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/common.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/common.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/common.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/common.xml	2010-02-24 13:52:17.000000000 -0500
@@ -716,6 +716,41 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &am
 }
       </programlisting>
     </example>
+  <section id="dv-timings">
+	<title>Digital Video (DV) Timings</title>
+	<para>
+	The video standards discussed so far has been dealing with Analog TV and the
+corresponding video timings. Today there are many more different hardware interfaces
+such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
+video signals and there is a need to extend the API to select the video timings
+for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
+the limited bits available, a new set of IOCTLs is added to set/get video timings at
+the input and output: </para><itemizedlist>
+	<listitem>
+	<para>DV Presets: Digital Video (DV) presets. These are IDs representing a
+video timing at the input/output. Presets are pre-defined timings implemented
+by the hardware according to video standards. A __u32 data type is used to represent
+a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions
+to support as many different presets as needed.</para>
+	</listitem>
+	<listitem>
+	<para>Custom DV Timings: This will allow applications to define more detailed
+custom video timings for the interface. This includes parameters such as width, height,
+polarities, frontporch, backporch etc.
+	</para>
+	</listitem>
+	</itemizedlist>
+	<para>To enumerate and query the attributes of DV presets supported by a device,
+applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset,
+applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the
+&VIDIOC-S-DV-PRESET; ioctl.</para>
+	<para>To set custom DV timings for the device, applications use the
+&VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the
+&VIDIOC-G-DV-TIMINGS; ioctl.</para>
+	<para>Applications can make use of the <xref linkend="input-capabilities" /> and
+<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
+video timings for the device.</para>
+	</section>
   </section>
 
   &sub-controls;
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/compat.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/compat.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/compat.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/compat.xml	2010-02-24 13:52:17.000000000 -0500
@@ -2291,8 +2291,8 @@ was renamed to <structname id="v4l2-chip
 	<listitem>
 	  <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
 	</listitem>
-       </orderedlist>
-     </section>
+      </orderedlist>
+    </section>
     <section>
       <title>V4L2 in Linux 2.6.32</title>
       <orderedlist>
@@ -2322,8 +2322,16 @@ more information.</para>
 	<listitem>
 	  <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
 	</listitem>
-       </orderedlist>
-     </section>
+      </orderedlist>
+    </section>
+    <section>
+      <title>V4L2 in Linux 2.6.33</title>
+      <orderedlist>
+	<listitem>
+	  <para>Added support for Digital Video timings in order to support HDTV receivers and transmitters.</para>
+	</listitem>
+      </orderedlist>
+    </section>
    </section>
 
    <section id="other">
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/controls.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/controls.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/controls.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/controls.xml	2010-02-24 13:52:17.000000000 -0500
@@ -281,10 +281,28 @@ minimum value disables backlight compens
 <constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
 	  </row>
 	  <row>
+	    <entry><constant>V4L2_CID_ROTATE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Rotates the image by specified angle. Common angles are 90,
+	    270 and 180. Rotating the image to 90 and 270 will reverse the height
+	    and width of the display window. It is necessary to set the new height and
+	    width of the picture using the &VIDIOC-S-FMT; ioctl according to
+	    the rotation angle selected.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BG_COLOR</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Sets the background color on the current output device.
+	    Background color needs to be specified in the RGB24 format. The
+	    supplied 32 bit value is interpreted as bits 0-7 Red color information,
+	    bits 8-15 Green color information, bits 16-23 Blue color
+	    information and bits 24-31 must be zero.</entry>
+	  </row>
+	  <row>
 	    <entry><constant>V4L2_CID_LASTP1</constant></entry>
 	    <entry></entry>
 	    <entry>End of the predefined control IDs (currently
-<constant>V4L2_CID_COLORFX</constant> + 1).</entry>
+<constant>V4L2_CID_BG_COLOR</constant> + 1).</entry>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/pixfmt.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/pixfmt.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/pixfmt.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/pixfmt.xml	2010-02-24 13:52:17.000000000 -0500
@@ -770,6 +770,11 @@ kernel sources in the file <filename>Doc
 	    <entry>'S920'</entry>
 	    <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
 	  </row>
+	  <row id="V4L2-PIX-FMT-STV0680">
+	    <entry><constant>V4L2_PIX_FMT_STV0680</constant></entry>
+	    <entry>'S680'</entry>
+	    <entry>Bayer format of the gspca stv0680 driver.</entry>
+	  </row>
 	  <row id="V4L2-PIX-FMT-WNVA">
 	    <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
 	    <entry>'WNVA'</entry>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/v4l2.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/v4l2.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/v4l2.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/v4l2.xml	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,17 @@ Remote Controller chapter.</contrib>
 	  </address>
 	</affiliation>
       </author>
+
+      <author>
+	<firstname>Muralidharan</firstname>
+	<surname>Karicheri</surname>
+	<contrib>Documented the Digital Video timings API.</contrib>
+	<affiliation>
+	  <address>
+	    <email>m-karicheri2@ti.com</email>
+	  </address>
+	</affiliation>
+      </author>
     </authorgroup>
 
     <copyright>
@@ -89,7 +100,7 @@ Remote Controller chapter.</contrib>
       <year>2008</year>
       <year>2009</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
-Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
+Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
     </copyright>
     <legalnotice>
     <para>Except when explicitly stated as GPL, programming examples within
@@ -103,6 +114,13 @@ structs, ioctls) must be noted in more d
 applications. -->
 
       <revision>
+	<revnumber>2.6.33</revnumber>
+	<date>2009-12-03</date>
+	<authorinitials>mk</authorinitials>
+	<revremark>Added documentation for the Digital Video timings API.</revremark>
+      </revision>
+
+      <revision>
 	<revnumber>2.6.32</revnumber>
 	<date>2009-08-31</date>
 	<authorinitials>mcc</authorinitials>
@@ -355,7 +373,7 @@ and discussions on the V4L mailing list.
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 2.6.32</subtitle>
+ <subtitle>Revision 2.6.33</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -411,6 +429,7 @@ and discussions on the V4L mailing list.
     &sub-encoder-cmd;
     &sub-enumaudio;
     &sub-enumaudioout;
+    &sub-enum-dv-presets;
     &sub-enum-fmt;
     &sub-enum-framesizes;
     &sub-enum-frameintervals;
@@ -421,6 +440,8 @@ and discussions on the V4L mailing list.
     &sub-g-audioout;
     &sub-g-crop;
     &sub-g-ctrl;
+    &sub-g-dv-preset;
+    &sub-g-dv-timings;
     &sub-g-enc-index;
     &sub-g-ext-ctrls;
     &sub-g-fbuf;
@@ -441,6 +462,7 @@ and discussions on the V4L mailing list.
     &sub-querybuf;
     &sub-querycap;
     &sub-queryctrl;
+    &sub-query-dv-preset;
     &sub-querystd;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/videodev2.h.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/videodev2.h.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/videodev2.h.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/videodev2.h.xml	2010-02-24 13:52:17.000000000 -0500
@@ -363,6 +363,7 @@ struct <link linkend="v4l2-pix-format">v
 #define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link>    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
 #define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link>    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
 #define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link>   v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
+#define <link linkend="V4L2-PIX-FMT-STV0680">V4L2_PIX_FMT_STV0680</link>  v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
 
 /*
  *      F O R M A T   E N U M E R A T I O N
@@ -492,7 +493,7 @@ struct <link linkend="v4l2-jpegcompressi
                                  * you do, leave them untouched.
                                  * Inluding less markers will make the
                                  * resulting code smaller, but there will
-                                 * be fewer aplications which can read it.
+                                 * be fewer applications which can read it.
                                  * The presence of the APP and COM marker
                                  * is influenced by APP_len and COM_len
                                  * ONLY, not by this property! */
@@ -565,6 +566,7 @@ struct <link linkend="v4l2-framebuffer">
 #define V4L2_FBUF_CAP_LOCAL_ALPHA       0x0010
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA      0x0020
 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA   0x0040
+#define V4L2_FBUF_CAP_SRC_CHROMAKEY     0x0080
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY          0x0001
 #define V4L2_FBUF_FLAG_OVERLAY          0x0002
@@ -572,6 +574,7 @@ struct <link linkend="v4l2-framebuffer">
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA      0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA     0x0010
 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA  0x0020
+#define V4L2_FBUF_FLAG_SRC_CHROMAKEY    0x0040
 
 struct <link linkend="v4l2-clip">v4l2_clip</link> {
         struct <link linkend="v4l2-rect">v4l2_rect</link>        c;
@@ -731,6 +734,99 @@ struct <link linkend="v4l2-standard">v4l
 };
 
 /*
+ *      V I D E O       T I M I N G S   D V     P R E S E T
+ */
+struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link> {
+        __u32   preset;
+        __u32   reserved[4];
+};
+
+/*
+ *      D V     P R E S E T S   E N U M E R A T I O N
+ */
+struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link> {
+        __u32   index;
+        __u32   preset;
+        __u8    name[32]; /* Name of the preset timing */
+        __u32   width;
+        __u32   height;
+        __u32   reserved[4];
+};
+
+/*
+ *      D V     P R E S E T     V A L U E S
+ */
+#define         V4L2_DV_INVALID         0
+#define         V4L2_DV_480P59_94       1 /* BT.1362 */
+#define         V4L2_DV_576P50          2 /* BT.1362 */
+#define         V4L2_DV_720P24          3 /* SMPTE 296M */
+#define         V4L2_DV_720P25          4 /* SMPTE 296M */
+#define         V4L2_DV_720P30          5 /* SMPTE 296M */
+#define         V4L2_DV_720P50          6 /* SMPTE 296M */
+#define         V4L2_DV_720P59_94       7 /* SMPTE 274M */
+#define         V4L2_DV_720P60          8 /* SMPTE 274M/296M */
+#define         V4L2_DV_1080I29_97      9 /* BT.1120/ SMPTE 274M */
+#define         V4L2_DV_1080I30         10 /* BT.1120/ SMPTE 274M */
+#define         V4L2_DV_1080I25         11 /* BT.1120 */
+#define         V4L2_DV_1080I50         12 /* SMPTE 296M */
+#define         V4L2_DV_1080I60         13 /* SMPTE 296M */
+#define         V4L2_DV_1080P24         14 /* SMPTE 296M */
+#define         V4L2_DV_1080P25         15 /* SMPTE 296M */
+#define         V4L2_DV_1080P30         16 /* SMPTE 296M */
+#define         V4L2_DV_1080P50         17 /* BT.1120 */
+#define         V4L2_DV_1080P60         18 /* BT.1120 */
+
+/*
+ *      D V     B T     T I M I N G S
+ */
+
+/* BT.656/BT.1120 timing data */
+struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> {
+        __u32   width;          /* width in pixels */
+        __u32   height;         /* height in lines */
+        __u32   interlaced;     /* Interlaced or progressive */
+        __u32   polarities;     /* Positive or negative polarity */
+        __u64   pixelclock;     /* Pixel clock in HZ. Ex. 74.25MHz-&gt;74250000 */
+        __u32   hfrontporch;    /* Horizpontal front porch in pixels */
+        __u32   hsync;          /* Horizontal Sync length in pixels */
+        __u32   hbackporch;     /* Horizontal back porch in pixels */
+        __u32   vfrontporch;    /* Vertical front porch in pixels */
+        __u32   vsync;          /* Vertical Sync length in lines */
+        __u32   vbackporch;     /* Vertical back porch in lines */
+        __u32   il_vfrontporch; /* Vertical front porch for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   il_vsync;       /* Vertical sync length for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   il_vbackporch;  /* Vertical back porch for bottom field of
+                                 * interlaced field formats
+                                 */
+        __u32   reserved[16];
+} __attribute__ ((packed));
+
+/* Interlaced or progressive format */
+#define V4L2_DV_PROGRESSIVE     0
+#define V4L2_DV_INTERLACED      1
+
+/* Polarities. If bit is not set, it is assumed to be negative polarity */
+#define V4L2_DV_VSYNC_POS_POL   0x00000001
+#define V4L2_DV_HSYNC_POS_POL   0x00000002
+
+
+/* DV timings */
+struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link> {
+        __u32 type;
+        union {
+                struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link>  bt;
+                __u32   reserved[32];
+        };
+} __attribute__ ((packed));
+
+/* Values for the type field */
+#define V4L2_DV_BT_656_1120     0       /* BT.656/1120 timing type */
+
+/*
  *      V I D E O   I N P U T S
  */
 struct <link linkend="v4l2-input">v4l2_input</link> {
@@ -741,7 +837,8 @@ struct <link linkend="v4l2-input">v4l2_i
         __u32        tuner;             /*  Associated tuner */
         v4l2_std_id  std;
         __u32        status;
-        __u32        reserved[4];
+        __u32        capabilities;
+        __u32        reserved[3];
 };
 
 /*  Values for the 'type' field */
@@ -772,6 +869,11 @@ struct <link linkend="v4l2-input">v4l2_i
 #define V4L2_IN_ST_NO_ACCESS   0x02000000  /* Conditional access denied */
 #define V4L2_IN_ST_VTR         0x04000000  /* VTR time constant */
 
+/* capabilities flags */
+#define V4L2_IN_CAP_PRESETS             0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_IN_CAP_CUSTOM_TIMINGS      0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_IN_CAP_STD                 0x00000004 /* Supports S_STD */
+
 /*
  *      V I D E O   O U T P U T S
  */
@@ -782,13 +884,19 @@ struct <link linkend="v4l2-output">v4l2_
         __u32        audioset;          /*  Associated audios (bitfield) */
         __u32        modulator;         /*  Associated modulator */
         v4l2_std_id  std;
-        __u32        reserved[4];
+        __u32        capabilities;
+        __u32        reserved[3];
 };
 /*  Values for the 'type' field */
 #define V4L2_OUTPUT_TYPE_MODULATOR              1
 #define V4L2_OUTPUT_TYPE_ANALOG                 2
 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY       3
 
+/* capabilities flags */
+#define V4L2_OUT_CAP_PRESETS            0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_OUT_CAP_CUSTOM_TIMINGS     0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_OUT_CAP_STD                0x00000004 /* Supports S_STD */
+
 /*
  *      C O N T R O L S
  */
@@ -914,8 +1022,10 @@ enum <link linkend="v4l2-colorfx">v4l2_c
 #define V4L2_CID_AUTOBRIGHTNESS                 (V4L2_CID_BASE+32)
 #define V4L2_CID_BAND_STOP_FILTER               (V4L2_CID_BASE+33)
 
+#define V4L2_CID_ROTATE                         (V4L2_CID_BASE+34)
+#define V4L2_CID_BG_COLOR                       (V4L2_CID_BASE+35)
 /* last CID + 1 */
-#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+34)
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+36)
 
 /*  MPEG-class control IDs defined by V4L2 */
 #define V4L2_CID_MPEG_BASE                      (V4L2_CTRL_CLASS_MPEG | 0x900)
@@ -1621,6 +1731,13 @@ struct <link linkend="v4l2-dbg-chip-iden
 #endif
 
 #define VIDIOC_S_HW_FREQ_SEEK    _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>)
+#define VIDIOC_ENUM_DV_PRESETS  _IOWR('V', 83, struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link>)
+#define VIDIOC_S_DV_PRESET      _IOWR('V', 84, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_G_DV_PRESET      _IOWR('V', 85, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_QUERY_DV_PRESET  _IOR('V',  86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
+#define VIDIOC_S_DV_TIMINGS     _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
+#define VIDIOC_G_DV_TIMINGS     _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,238 @@
+<refentry id="vidioc-enum-dv-presets">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUM_DV_PRESETS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUM_DV_PRESETS</refname>
+    <refpurpose>Enumerate supported Digital Video presets</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_dv_enum_preset *<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_ENUM_DV_PRESETS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a DV preset, applications initialize the
+<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset;
+and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all DV Presets supported,
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
+different set of DV presets after switching the video input or
+output.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-enum-preset">
+      <title>struct <structname>v4l2_dv_enum_presets</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the DV preset, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>preset</structfield></entry>
+	    <entry>This field identifies one of the DV preset values listed in <xref linkend="v4l2-dv-presets-vals"/>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[24]</entry>
+	    <entry>Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is
+intended for the user.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the active video in pixels for the DV preset.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the active video in lines for the DV preset.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-presets-vals">
+      <title>struct <structname>DV Presets</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>Preset</entry>
+	    <entry>Preset value</entry>
+	    <entry>Description</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_INVALID</entry>
+	    <entry>0</entry>
+	    <entry>Invalid preset value.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_480P59_94</entry>
+	    <entry>1</entry>
+	    <entry>720x480 progressive video at 59.94 fps as per BT.1362.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_576P50</entry>
+	    <entry>2</entry>
+	    <entry>720x576 progressive video at 50 fps as per BT.1362.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P24</entry>
+	    <entry>3</entry>
+	    <entry>1280x720 progressive video at 24 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P25</entry>
+	    <entry>4</entry>
+	    <entry>1280x720 progressive video at 25 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P30</entry>
+	    <entry>5</entry>
+	    <entry>1280x720 progressive video at 30 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P50</entry>
+	    <entry>6</entry>
+	    <entry>1280x720 progressive video at 50 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P59_94</entry>
+	    <entry>7</entry>
+	    <entry>1280x720 progressive video at 59.94 fps as per SMPTE 274M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_720P60</entry>
+	    <entry>8</entry>
+	    <entry>1280x720 progressive video at 60 fps as per SMPTE 274M/296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080I29_97</entry>
+	    <entry>9</entry>
+	    <entry>1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080I30</entry>
+	    <entry>10</entry>
+	    <entry>1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080I25</entry>
+	    <entry>11</entry>
+	    <entry>1920x1080 interlaced video at 25 fps as per BT.1120.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080I50</entry>
+	    <entry>12</entry>
+	    <entry>1920x1080 interlaced video at 50 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080I60</entry>
+	    <entry>13</entry>
+	    <entry>1920x1080 interlaced video at 60 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080P24</entry>
+	    <entry>14</entry>
+	    <entry>1920x1080 progressive video at 24 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080P25</entry>
+	    <entry>15</entry>
+	    <entry>1920x1080 progressive video at 25 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080P30</entry>
+	    <entry>16</entry>
+	    <entry>1920x1080 progressive video at 30 fps as per SMPTE 296M.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080P50</entry>
+	    <entry>17</entry>
+	    <entry>1920x1080 progressive video at 50 fps as per BT.1120.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_1080P60</entry>
+	    <entry>18</entry>
+	    <entry>1920x1080 progressive video at 60 fps as per BT.1120.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-dv-enum-preset; <structfield>index</structfield>
+is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enuminput.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enuminput.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enuminput.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enuminput.xml	2010-02-24 13:52:17.000000000 -0500
@@ -124,7 +124,13 @@ current input.</entry>
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry><structfield>capabilities</structfield></entry>
+	    <entry>This field provides capabilities for the
+input. See <xref linkend="input-capabilities" /> for flags.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[3]</entry>
 	    <entry>Reserved for future extensions. Drivers must set
 the array to zero.</entry>
 	  </row>
@@ -260,6 +266,34 @@ flag is set Macrovision has been detecte
 	  </row>
 	</tbody>
       </tgroup>
+    </table>
+
+    <!-- Capability flags based on video timings RFC by Muralidharan
+Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
+input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
+	-->
+    <table frame="none" pgwide="1" id="input-capabilities">
+      <title>Input capabilities</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_IN_CAP_PRESETS</constant></entry>
+	    <entry>0x00000001</entry>
+	    <entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
+	    <entry>0x00000002</entry>
+	    <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_CAP_STD</constant></entry>
+	    <entry>0x00000004</entry>
+	    <entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
     </table>
   </refsect1>
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enumoutput.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enumoutput.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-enumoutput.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-enumoutput.xml	2010-02-24 13:52:17.000000000 -0500
@@ -114,7 +114,13 @@ details on video standards and how to sw
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry><structfield>capabilities</structfield></entry>
+	    <entry>This field provides capabilities for the
+output. See <xref linkend="output-capabilities" /> for flags.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[3]</entry>
 	    <entry>Reserved for future extensions. Drivers must set
 the array to zero.</entry>
 	  </row>
@@ -145,6 +151,34 @@ CVBS, S-Video, RGB.</entry>
 	  </row>
 	</tbody>
       </tgroup>
+    </table>
+
+    <!-- Capabilities flags based on video timings RFC by Muralidharan
+Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
+input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
+	-->
+    <table frame="none" pgwide="1" id="output-capabilities">
+      <title>Output capabilities</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_OUT_CAP_PRESETS</constant></entry>
+	    <entry>0x00000001</entry>
+	    <entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
+	    <entry>0x00000002</entry>
+	    <entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_OUT_CAP_STD</constant></entry>
+	    <entry>0x00000004</entry>
+	    <entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
     </table>
 
   </refsect1>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,111 @@
+<refentry id="vidioc-g-dv-preset">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_DV_PRESET</refname>
+    <refname>VIDIOC_S_DV_PRESET</refname>
+    <refpurpose>Query or select the DV preset of the current input or output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>&v4l2-dv-preset;
+*<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_G_DV_PRESET, VIDIOC_S_DV_PRESET</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>To query and select the current DV preset, applications
+use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant>
+ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
+Applications must zero the reserved array in &v4l2-dv-preset;.
+<constant>VIDIOC_G_DV_PRESET</constant> returns a dv preset in the field
+<structfield>preset</structfield> of &v4l2-dv-preset;.</para>
+
+    <para><constant>VIDIOC_S_DV_PRESET</constant> accepts a pointer to a &v4l2-dv-preset;
+that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;.
+If the preset is not supported, it returns an &EINVAL; </para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_DV_PRESET</constant>,<constant>VIDIOC_S_DV_PRESET</constant> parameter was unsuitable.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The device is busy and therefore can not change the preset.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-preset">
+      <title>struct <structname>v4l2_dv_preset</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>preset</structfield></entry>
+	    <entry>Preset value to represent the digital video timings</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved[4]</structfield></entry>
+	    <entry>Reserved fields for future use</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,224 @@
+<refentry id="vidioc-g-dv-timings">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_DV_TIMINGS</refname>
+    <refname>VIDIOC_S_DV_TIMINGS</refname>
+    <refpurpose>Get or set custom DV timings for input or output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>&v4l2-dv-timings;
+*<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_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>To set custom DV timings for the input or output, applications use the
+<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current custom timings,
+applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing
+information is filled in using the structure &v4l2-dv-timings;. These ioctls take
+a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported
+or the timing values are not correct, the driver returns &EINVAL;.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_DV_TIMINGS</constant> parameter was unsuitable.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The device is busy and therefore can not change the timings.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+
+    <table pgwide="1" frame="none" id="v4l2-bt-timings">
+      <title>struct <structname>v4l2_bt_timings</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the active video in pixels</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the active video in lines</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>interlaced</structfield></entry>
+	    <entry>Progressive (0) or interlaced (1)</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>polarities</structfield></entry>
+	    <entry>This is a bit mask that defines polarities of sync signals.
+bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_HSYNC_POS_POL) is for horizontal sync polarity. If the bit is set
+(1) it is positive polarity and if is cleared (0), it is negative polarity.</entry>
+	  </row>
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>pixelclock</structfield></entry>
+	    <entry>Pixel clock in Hz. Ex. 74.25MHz->74250000</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>hfrontporch</structfield></entry>
+	    <entry>Horizontal front porch in pixels</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>hsync</structfield></entry>
+	    <entry>Horizontal sync length in pixels</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>hbackporch</structfield></entry>
+	    <entry>Horizontal back porch in pixels</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>vfrontporch</structfield></entry>
+	    <entry>Vertical front porch in lines</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>vsync</structfield></entry>
+	    <entry>Vertical sync length in lines</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>vbackporch</structfield></entry>
+	    <entry>Vertical back porch in lines</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>il_vfrontporch</structfield></entry>
+	    <entry>Vertical front porch in lines for bottom field of interlaced field formats</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>il_vsync</structfield></entry>
+	    <entry>Vertical sync length in lines for bottom field of interlaced field formats</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>il_vbackporch</structfield></entry>
+	    <entry>Vertical back porch in lines for bottom field of interlaced field formats</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-dv-timings">
+      <title>struct <structname>v4l2_dv_timings</structname></title>
+      <tgroup cols="4">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry><structfield></structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-bt-timings;</entry>
+	    <entry><structfield>bt</structfield></entry>
+	    <entry>Timings defined by BT.656/1120 specifications</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[32]</entry>
+	    <entry></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="dv-timing-types">
+      <title>DV Timing types</title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>Timing type</entry>
+	    <entry>value</entry>
+	    <entry>Description</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_BT_656_1120</entry>
+	    <entry>0</entry>
+	    <entry>BT.656/1120 timings</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-fbuf.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-fbuf.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-fbuf.xml	2010-02-24 13:52:17.000000000 -0500
@@ -336,6 +336,13 @@ alpha value. Alpha blending makes no sen
 inverted alpha channel of the framebuffer or VGA signal. Alpha
 blending makes no sense for destructive overlays.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry>
+	    <entry>0x0080</entry>
+	    <entry>The device supports Source Chroma-keying. Framebuffer pixels
+with the chroma-key colors are replaced by video pixels, which is exactly opposite of
+<constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
@@ -411,6 +418,16 @@ images, but with an inverted alpha value
 output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
 actual alpha depth depends on the framebuffer pixel format.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_SRC_CHROMAKEY</constant></entry>
+	    <entry>0x0040</entry>
+	    <entry>Use source chroma-keying. The source chroma-key color is
+determined by the <structfield>chromakey</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+linkend="overlay" /> and <xref linkend="osd" />.
+Both chroma-keying are mutual exclusive to each other, so same
+<structfield>chromakey</structfield> field of &v4l2-window; is being used.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-std.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-std.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-g-std.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-g-std.xml	2010-02-24 13:52:17.000000000 -0500
@@ -86,6 +86,12 @@ standards.</para>
 <constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
 	</listitem>
       </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The device is busy and therefore can not change the standard</para>
+	</listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 </refentry>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,85 @@
+<refentry id="vidioc-query-dv-preset">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERY_DV_PRESET</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERY_DV_PRESET</refname>
+    <refpurpose>Sense the DV preset received by the current
+input</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>&v4l2-dv-preset; *<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_QUERY_DV_PRESET</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The hardware may be able to detect the current DV preset
+automatically, similar to sensing the video standard. To do so, applications
+call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
+&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
+returned in the preset field of &v4l2-dv-preset;. When detection is not
+possible or fails, the value V4L2_DV_INVALID is returned.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported.</para>
+	</listitem>
+    </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The device is busy and therefore can not sense the preset</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-querystd.xml linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-querystd.xml
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/v4l/vidioc-querystd.xml	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/v4l/vidioc-querystd.xml	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,12 @@ current video input or output.</para>
 	  <para>This ioctl is not supported.</para>
 	</listitem>
       </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The device is busy and therefore can not detect the standard</para>
+	</listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 </refentry>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl linux-libre-2.6.33-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl
--- linux-libre-2.6.32-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl	2010-02-24 13:52:17.000000000 -0500
@@ -5318,7 +5318,7 @@ struct _snd_pcm_runtime {
       pages of the given size and map them onto the virtually contiguous
       memory.  The virtual pointer is addressed in runtime-&gt;dma_area.
       The physical address (runtime-&gt;dma_addr) is set to zero,
-      because the buffer is physically non-contigous.
+      because the buffer is physically non-contiguous.
       The physical address table is set up in sgbuf-&gt;table.
       You can get the physical address at a certain offset via
       <function>snd_pcm_sgbuf_get_addr()</function>. 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/dontdiff linux-libre-2.6.33-gnu1/Documentation/dontdiff
--- linux-libre-2.6.32-gnu1/Documentation/dontdiff	2013-05-03 13:55:28.000000000 -0400
+++ linux-libre-2.6.33-gnu1/Documentation/dontdiff	2013-05-03 12:03:02.000000000 -0400
@@ -65,6 +65,7 @@ aicdb.h*
 asm-offsets.h
 asm_offsets.h
 autoconf.h*
+av_permissions.h
 bbootsect
 bin2c
 binkernel.spec
@@ -95,12 +96,15 @@ docproc
 elf2ecoff
 elfconfig.h*
 fixdep
+flask.h
 fore200e_mkfirm
 fore200e_pca_fw.c*
 gconf
 gen-devlist
 gen_crc32table
 gen_init_cpio
+generated
+genheaders
 genksyms
 *_gray256.c
 ihex2fw
diff -druNp linux-libre-2.6.32-gnu1/Documentation/driver-model/driver.txt linux-libre-2.6.33-gnu1/Documentation/driver-model/driver.txt
--- linux-libre-2.6.32-gnu1/Documentation/driver-model/driver.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/driver-model/driver.txt	2010-02-24 13:52:17.000000000 -0500
@@ -226,5 +226,5 @@ struct driver_attribute driver_attr_debu
 This can then be used to add and remove the attribute from the
 driver's directory using:
 
-int driver_create_file(struct device_driver *, struct driver_attribute *);
-void driver_remove_file(struct device_driver *, struct driver_attribute *);
+int driver_create_file(struct device_driver *, const struct driver_attribute *);
+void driver_remove_file(struct device_driver *, const struct driver_attribute *);
diff -druNp linux-libre-2.6.32-gnu1/Documentation/dvb/README.dvb-usb linux-libre-2.6.33-gnu1/Documentation/dvb/README.dvb-usb
--- linux-libre-2.6.32-gnu1/Documentation/dvb/README.dvb-usb	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/dvb/README.dvb-usb	2010-02-24 13:52:17.000000000 -0500
@@ -85,7 +85,7 @@ http://www.linuxtv.org/wiki/index.php/DV
 	     - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
 	       better settled there (added xfer_ops-struct)
 	     - created a common files for frontends (mc/p/mb)
-  2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
+  2004-09-28 - added support for a new device (Unknown, vendor ID is Hyper-Paltek)
   2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
 	       to Amaury Demol for reporting
 	     - changed usb TS transfer method (several urbs, stopping transfer
diff -druNp linux-libre-2.6.32-gnu1/Documentation/edac.txt linux-libre-2.6.33-gnu1/Documentation/edac.txt
--- linux-libre-2.6.32-gnu1/Documentation/edac.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/edac.txt	2010-02-24 13:52:17.000000000 -0500
@@ -80,7 +80,7 @@ is:
 
 	broken_parity_status
 
-as is located in /sys/devices/pci<XXX>/0000:XX:YY.Z directorys for
+as is located in /sys/devices/pci<XXX>/0000:XX:YY.Z directories for
 PCI devices.
 
 FUTURE HARDWARE SCANNING
@@ -288,9 +288,8 @@ Total UE count that had no information a
 
 	'ue_noinfo_count'
 
-	This attribute file displays the number of UEs that
-	have occurred have occurred with  no informations as to which DIMM
-	slot is having errors.
+	This attribute file displays the number of UEs that have occurred
+	with no information as to which DIMM slot is having errors.
 
 
 Total Correctable Errors count attribute file:
diff -druNp linux-libre-2.6.32-gnu1/Documentation/fault-injection/fault-injection.txt linux-libre-2.6.33-gnu1/Documentation/fault-injection/fault-injection.txt
--- linux-libre-2.6.32-gnu1/Documentation/fault-injection/fault-injection.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/fault-injection/fault-injection.txt	2010-02-24 13:52:17.000000000 -0500
@@ -143,8 +143,8 @@ o provide a way to configure fault attri
   failslab, fail_page_alloc, and fail_make_request use this way.
   Helper functions:
 
-	init_fault_attr_entries(entries, attr, name);
-	void cleanup_fault_attr_entries(entries);
+	init_fault_attr_dentries(entries, attr, name);
+	void cleanup_fault_attr_dentries(entries);
 
 - module parameters
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/fb/viafb.txt linux-libre-2.6.33-gnu1/Documentation/fb/viafb.txt
--- linux-libre-2.6.32-gnu1/Documentation/fb/viafb.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/fb/viafb.txt	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@
     VIA UniChrome Family(CLE266, PM800 / CN400 / CN300,
                         P4M800CE / P4M800Pro / CN700 / VN800,
                         CX700 / VX700, K8M890, P4M890,
-                        CN896 / P4M900, VX800)
+                        CN896 / P4M900, VX800, VX855)
 
 [Driver features]
 ------------------------
@@ -154,13 +154,6 @@
         0 : No Dual Edge Panel (default)
         1 : Dual Edge Panel
 
-    viafb_video_dev:
-        This option is used to specify video output devices(CRT, DVI, LCD) for
-        duoview case.
-        For example:
-        To output video on DVI, we should use:
-            modprobe viafb viafb_video_dev=DVI...
-
     viafb_lcd_port:
         This option is used to specify LCD output port,
         available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH" "DFP_LOW".
@@ -181,9 +174,6 @@ Notes:
        and bpp, need to call VIAFB specified ioctl interface VIAFB_SET_DEVICE
        instead of calling common ioctl function FBIOPUT_VSCREENINFO since
        viafb doesn't support multi-head well, or it will cause screen crush.
-    4. VX800 2D accelerator hasn't been supported in this driver yet. When
-       using driver on VX800, the driver will disable the acceleration
-       function as default.
 
 
 [Configure viafb with "fbset" tool]
diff -druNp linux-libre-2.6.32-gnu1/Documentation/feature-removal-schedule.txt linux-libre-2.6.33-gnu1/Documentation/feature-removal-schedule.txt
--- linux-libre-2.6.32-gnu1/Documentation/feature-removal-schedule.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/feature-removal-schedule.txt	2010-02-24 13:52:17.000000000 -0500
@@ -6,6 +6,21 @@ be removed from this file.
 
 ---------------------------
 
+What:	USER_SCHED
+When:	2.6.34
+
+Why:	USER_SCHED was implemented as a proof of concept for group scheduling.
+	The effect of USER_SCHED can already be achieved from userspace with
+	the help of libcgroup. The removal of USER_SCHED will also simplify
+	the scheduler code with the removal of one major ifdef. There are also
+	issues USER_SCHED has with USER_NS. A decision was taken not to fix
+	those and instead remove USER_SCHED. Also new group scheduling
+	features will not be implemented for USER_SCHED.
+
+Who:	Dhaval Giani <dhaval@linux.vnet.ibm.com>
+
+---------------------------
+
 What:	PRISM54
 When:	2.6.34
 
@@ -276,22 +291,6 @@ Who:	Michael Buesch <mb@bu3sch.de>
 
 ---------------------------
 
-What:	usedac i386 kernel parameter
-When:	2.6.27
-Why:	replaced by allowdac and no dac combination
-Who:	Glauber Costa <gcosta@redhat.com>
-
----------------------------
-
-What: print_fn_descriptor_symbol()
-When: October 2009
-Why:  The %pF vsprintf format provides the same functionality in a
-      simpler way.  print_fn_descriptor_symbol() is deprecated but
-      still present to give out-of-tree modules time to change.
-Who:  Bjorn Helgaas <bjorn.helgaas@hp.com>
-
----------------------------
-
 What:	/sys/o2cb symlink
 When:	January 2010
 Why:	/sys/fs/o2cb is the proper location for this information - /sys/o2cb
@@ -302,18 +301,6 @@ Who:	ocfs2-devel@oss.oracle.com
 
 ---------------------------
 
-What:	SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD,
-	SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD
-When: 	June 2009
-Why:    A newer version of the options have been introduced in 2005 that
-	removes the limitions of the old API.  The sctp library has been
-        converted to use these new options at the same time.  Any user
-	space app that directly uses the old options should convert to using
-	the new options.
-Who:	Vlad Yasevich <vladislav.yasevich@hp.com>
-
----------------------------
-
 What:	Ability for non root users to shm_get hugetlb pages based on mlock
 	resource limits
 When:	2.6.31
@@ -404,15 +391,6 @@ Who:	Alex Chiang <achiang@hp.com>
 
 ---------------------------
 
-What:	i2c-voodoo3 driver
-When:	October 2009
-Why:	Superseded by tdfxfb. I2C/DDC support used to live in a separate
-	driver but this caused driver conflicts.
-Who:	Jean Delvare <khali@linux-fr.org>
-	Krzysztof Helt <krzysztof.h1@wp.pl>
-
----------------------------
-
 What:	CONFIG_RFKILL_INPUT
 When:	2.6.33
 Why:	Should be implemented in userspace, policy daemon.
@@ -489,3 +467,78 @@ Why:	With the recent innovations in CPU
 Who:	Alok N Kataria <akataria@vmware.com>
 
 ----------------------------
+
+What:	adt7473 hardware monitoring driver
+When:	February 2010
+Why:	Obsoleted by the adt7475 driver.
+Who:	Jean Delvare <khali@linux-fr.org>
+
+---------------------------
+What:	Support for lcd_switch and display_get in asus-laptop driver
+When:	March 2010
+Why:	These two features use non-standard interfaces. There are the
+	only features that really need multiple path to guess what's
+	the right method name on a specific laptop.
+
+	Removing them will allow to remove a lot of code an significantly
+	clean the drivers.
+
+	This will affect the backlight code which won't be able to know
+	if the backlight is on or off. The platform display file will also be
+	write only (like the one in eeepc-laptop).
+
+	This should'nt affect a lot of user because they usually know
+	when their display is on or off.
+
+Who:	Corentin Chary <corentin.chary@gmail.com>
+
+----------------------------
+
+What:	usbvideo quickcam_messenger driver
+When:	2.6.35
+Files:	drivers/media/video/usbvideo/quickcam_messenger.[ch]
+Why:	obsolete v4l1 driver replaced by gspca_stv06xx
+Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	ov511 v4l1 driver
+When:	2.6.35
+Files:	drivers/media/video/ov511.[ch]
+Why:	obsolete v4l1 driver replaced by gspca_ov519
+Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	w9968cf v4l1 driver
+When:	2.6.35
+Files:	drivers/media/video/w9968cf*.[ch]
+Why:	obsolete v4l1 driver replaced by gspca_ov519
+Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	ovcamchip sensor framework
+When:	2.6.35
+Files:	drivers/media/video/ovcamchip/*
+Why:	Only used by obsoleted v4l1 drivers
+Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	stv680 v4l1 driver
+When:	2.6.35
+Files:	drivers/media/video/stv680.[ch]
+Why:	obsolete v4l1 driver replaced by gspca_stv0680
+Who:	Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:	zc0301 v4l driver
+When:	2.6.35
+Files:	drivers/media/video/zc0301/*
+Why:	Duplicate functionality with the gspca_zc3xx driver, zc0301 only
+	supports 2 USB-ID's (because it only supports a limited set of
+	sensors) wich are also supported by the gspca_zc3xx driver
+	(which supports 53 USB-ID's in total)
+Who:	Hans de Goede <hdegoede@redhat.com>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/00-INDEX linux-libre-2.6.33-gnu1/Documentation/filesystems/00-INDEX
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/00-INDEX	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/00-INDEX	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,5 @@
 00-INDEX
 	- this file (info on some of the filesystems supported by linux).
-Exporting
-	- explanation of how to make filesystems exportable.
 Locking
 	- info on locking rules as they pertain to Linux VFS.
 9p.txt
@@ -36,6 +34,8 @@ dnotify.txt
 	- info about directory notification in Linux.
 ecryptfs.txt
 	- docs on eCryptfs: stacked cryptographic filesystem for Linux.
+exofs.txt
+	- info, usage, mount options, design about EXOFS.
 ext2.txt
 	- info, mount options and specifications for the Ext2 filesystem.
 ext3.txt
@@ -66,12 +66,8 @@ mandatory-locking.txt
 	- info on the Linux implementation of Sys V mandatory file locking.
 ncpfs.txt
 	- info on Novell Netware(tm) filesystem using NCP protocol.
-nfs41-server.txt
-	- info on the Linux server implementation of NFSv4 minor version 1.
-nfs-rdma.txt
-	- how to install and setup the Linux NFS/RDMA client and server software.
-nfsroot.txt
-	- short guide on setting up a diskless box with NFS root filesystem.
+nfs/
+	- nfs-related documentation.
 nilfs2.txt
 	- info and mount options for the NILFS2 filesystem.
 ntfs.txt
@@ -90,8 +86,6 @@ relay.txt
 	- info on relay, for efficient streaming from kernel to user space.
 romfs.txt
 	- description of the ROMFS filesystem.
-rpc-cache.txt
-	- introduction to the caching mechanisms in the sunrpc layer.
 seq_file.txt
 	- how to use the seq_file API
 sharedsubtree.txt
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/exofs.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/exofs.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/exofs.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/exofs.txt	2010-02-24 13:52:17.000000000 -0500
@@ -60,13 +60,13 @@ USAGE
 
    mkfs.exofs --pid=65536 --format /dev/osd0
 
-   The --format is optional if not specified no OSD_FORMAT will be
-   preformed and a clean file system will be created in the specified pid,
+   The --format is optional. If not specified, no OSD_FORMAT will be
+   performed and a clean file system will be created in the specified pid,
    in the available space of the target. (Use --format=size_in_meg to limit
    the total LUN space available)
 
-   If pid already exist it will be deleted and a new one will be created in it's
-   place. Be careful.
+   If pid already exists, it will be deleted and a new one will be created in
+   its place. Be careful.
 
    An exofs lives inside a single OSD partition. You can create multiple exofs
    filesystems on the same device using multiple pids.
@@ -81,7 +81,7 @@ USAGE
 
 7. For reference (See do-exofs example script):
 	do-exofs start - an example of how to perform the above steps.
-	do-exofs stop -  an example of how to unmount the file system.
+	do-exofs stop - an example of how to unmount the file system.
 	do-exofs format - an example of how to format and mkfs a new exofs.
 
 8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
@@ -104,8 +104,8 @@ Where:
     exofs specific options: Options are separated by commas (,)
 		pid=<integer> - The partition number to mount/create as
                                 container of the filesystem.
-                                This option is mandatory
-                to=<integer>  - Timeout in ticks for a single command
+                                This option is mandatory.
+                to=<integer>  - Timeout in ticks for a single command.
                                 default is (60 * HZ) [for debugging only]
 
 ===============================================================================
@@ -116,7 +116,7 @@ DESIGN
   with a special ID (defined in common.h).
   Information included in the file system control block is used to fill the
   in-memory superblock structure at mount time. This object is created before
-  the file system is used by mkexofs.c It contains information such as:
+  the file system is used by mkexofs.c. It contains information such as:
 	- The file system's magic number
 	- The next inode number to be allocated
 
@@ -134,8 +134,8 @@ DESIGN
   attributes. This applies to both regular files and other types (directories,
   device files, symlinks, etc.).
 
-* Credentials are generated per object (inode and superblock) when they is
-  created in memory (read off disk or created). The credential works for all
+* Credentials are generated per object (inode and superblock) when they are
+  created in memory (read from disk or created). The credential works for all
   operations and is used as long as the object remains in memory.
 
 * Async OSD operations are used whenever possible, but the target may execute
@@ -145,7 +145,8 @@ DESIGN
   from executing in reverse order:
 	- The following are handled with the OBJ_CREATED and OBJ_2BCREATED
 	  flags. OBJ_CREATED is set when we know the object exists on the OSD -
-	  in create's callback function, and when we successfully do a read_inode.
+	  in create's callback function, and when we successfully do a
+	  read_inode.
 	  OBJ_2BCREATED is set in the beginning of the create function, so we
 	  know that we should wait.
 		- create/delete: delete should wait until the object is created
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/Exporting linux-libre-2.6.33-gnu1/Documentation/filesystems/Exporting
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/Exporting	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/Exporting	1969-12-31 19:00:00.000000000 -0500
@@ -1,147 +0,0 @@
-
-Making Filesystems Exportable
-=============================
-
-Overview
---------
-
-All filesystem operations require a dentry (or two) as a starting
-point.  Local applications have a reference-counted hold on suitable
-dentries via open file descriptors or cwd/root.  However remote
-applications that access a filesystem via a remote filesystem protocol
-such as NFS may not be able to hold such a reference, and so need a
-different way to refer to a particular dentry.  As the alternative
-form of reference needs to be stable across renames, truncates, and
-server-reboot (among other things, though these tend to be the most
-problematic), there is no simple answer like 'filename'.
-
-The mechanism discussed here allows each filesystem implementation to
-specify how to generate an opaque (outside of the filesystem) byte
-string for any dentry, and how to find an appropriate dentry for any
-given opaque byte string.
-This byte string will be called a "filehandle fragment" as it
-corresponds to part of an NFS filehandle.
-
-A filesystem which supports the mapping between filehandle fragments
-and dentries will be termed "exportable".
-
-
-
-Dcache Issues
--------------
-
-The dcache normally contains a proper prefix of any given filesystem
-tree.  This means that if any filesystem object is in the dcache, then
-all of the ancestors of that filesystem object are also in the dcache.
-As normal access is by filename this prefix is created naturally and
-maintained easily (by each object maintaining a reference count on
-its parent).
-
-However when objects are included into the dcache by interpreting a
-filehandle fragment, there is no automatic creation of a path prefix
-for the object.  This leads to two related but distinct features of
-the dcache that are not needed for normal filesystem access.
-
-1/ The dcache must sometimes contain objects that are not part of the
-   proper prefix. i.e that are not connected to the root.
-2/ The dcache must be prepared for a newly found (via ->lookup) directory
-   to already have a (non-connected) dentry, and must be able to move
-   that dentry into place (based on the parent and name in the
-   ->lookup).   This is particularly needed for directories as
-   it is a dcache invariant that directories only have one dentry.
-
-To implement these features, the dcache has:
-
-a/ A dentry flag DCACHE_DISCONNECTED which is set on
-   any dentry that might not be part of the proper prefix.
-   This is set when anonymous dentries are created, and cleared when a
-   dentry is noticed to be a child of a dentry which is in the proper
-   prefix. 
-
-b/ A per-superblock list "s_anon" of dentries which are the roots of
-   subtrees that are not in the proper prefix.  These dentries, as
-   well as the proper prefix, need to be released at unmount time.  As
-   these dentries will not be hashed, they are linked together on the
-   d_hash list_head.
-
-c/ Helper routines to allocate anonymous dentries, and to help attach
-   loose directory dentries at lookup time. They are:
-    d_alloc_anon(inode) will return a dentry for the given inode.
-      If the inode already has a dentry, one of those is returned.
-      If it doesn't, a new anonymous (IS_ROOT and
-        DCACHE_DISCONNECTED) dentry is allocated and attached.
-      In the case of a directory, care is taken that only one dentry
-      can ever be attached.
-    d_splice_alias(inode, dentry) will make sure that there is a
-      dentry with the same name and parent as the given dentry, and
-      which refers to the given inode.
-      If the inode is a directory and already has a dentry, then that
-      dentry is d_moved over the given dentry.
-      If the passed dentry gets attached, care is taken that this is
-      mutually exclusive to a d_alloc_anon operation.
-      If the passed dentry is used, NULL is returned, else the used
-      dentry is returned.  This corresponds to the calling pattern of
-      ->lookup.
-  
- 
-Filesystem Issues
------------------
-
-For a filesystem to be exportable it must:
- 
-   1/ provide the filehandle fragment routines described below.
-   2/ make sure that d_splice_alias is used rather than d_add
-      when ->lookup finds an inode for a given parent and name.
-      Typically the ->lookup routine will end with a:
-
-		return d_splice_alias(inode, dentry);
-	}
-
-
-
-  A file system implementation declares that instances of the filesystem
-are exportable by setting the s_export_op field in the struct
-super_block.  This field must point to a "struct export_operations"
-struct which has the following members:
-
- encode_fh  (optional)
-    Takes a dentry and creates a filehandle fragment which can later be used
-    to find or create a dentry for the same object.  The default
-    implementation creates a filehandle fragment that encodes a 32bit inode
-    and generation number for the inode encoded, and if necessary the
-    same information for the parent.
-
-  fh_to_dentry (mandatory)
-    Given a filehandle fragment, this should find the implied object and
-    create a dentry for it (possibly with d_alloc_anon).
-
-  fh_to_parent (optional but strongly recommended)
-    Given a filehandle fragment, this should find the parent of the
-    implied object and create a dentry for it (possibly with d_alloc_anon).
-    May fail if the filehandle fragment is too small.
-
-  get_parent (optional but strongly recommended)
-    When given a dentry for a directory, this should return  a dentry for
-    the parent.  Quite possibly the parent dentry will have been allocated
-    by d_alloc_anon.  The default get_parent function just returns an error
-    so any filehandle lookup that requires finding a parent will fail.
-    ->lookup("..") is *not* used as a default as it can leave ".." entries
-    in the dcache which are too messy to work with.
-
-  get_name (optional)
-    When given a parent dentry and a child dentry, this should find a name
-    in the directory identified by the parent dentry, which leads to the
-    object identified by the child dentry.  If no get_name function is
-    supplied, a default implementation is provided which uses vfs_readdir
-    to find potential names, and matches inode numbers to find the correct
-    match.
-
-
-A filehandle fragment consists of an array of 1 or more 4byte words,
-together with a one byte "type".
-The decode_fh routine should not depend on the stated size that is
-passed to it.  This size may be larger than the original filehandle
-generated by encode_fh, in which case it will have been padded with
-nuls.  Rather, the encode_fh routine should choose a "type" which
-indicates the decode_fh how much of the filehandle is valid, and how
-it should be interpreted.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/ext3.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/ext3.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/ext3.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/ext3.txt	2010-02-24 13:52:17.000000000 -0500
@@ -32,8 +32,8 @@ journal_dev=devnum	When the external jou
 			identified through its new major/minor numbers encoded
 			in devnum.
 
-noload			Don't load the journal on mounting. Note that this forces
-			mount of inconsistent filesystem, which can lead to
+norecovery		Don't load the journal on mounting. Note that this forces
+noload			mount of inconsistent filesystem, which can lead to
 			various problems.
 
 data=journal		All data are committed into the journal prior to being
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/ext4.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/ext4.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/ext4.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/ext4.txt	2010-02-24 13:52:17.000000000 -0500
@@ -153,8 +153,8 @@ journal_dev=devnum	When the external jou
 			identified through its new major/minor numbers encoded
 			in devnum.
 
-noload			Don't load the journal on mounting.  Note that
-                     	if the filesystem was not unmounted cleanly,
+norecovery		Don't load the journal on mounting.  Note that
+noload			if the filesystem was not unmounted cleanly,
                      	skipping the journal replay will lead to the
                      	filesystem containing inconsistencies that can
                      	lead to any number of problems.
@@ -196,7 +196,7 @@ nobarrier		This also requires an IO stac
 			also be used to enable or disable barriers, for
 			consistency with other ext4 mount options.
 
-inode_readahead=n	This tuning parameter controls the maximum
+inode_readahead_blks=n	This tuning parameter controls the maximum
 			number of inode table blocks that ext4's inode
 			table readahead algorithm will pre-read into
 			the buffer cache.  The default value is 32 blocks.
@@ -353,6 +353,12 @@ noauto_da_alloc		replacing existing file
 			system crashes before the delayed allocation
 			blocks are forced to disk.
 
+discard		Controls whether ext4 should issue discard/TRIM
+nodiscard(*)		commands to the underlying block device when
+			blocks are freed.  This is useful for SSD devices
+			and sparse/thinly-provisioned LUNs, but it is off
+			by default until sufficient testing has been done.
+
 Data Mode
 =========
 There are 3 different data modes:
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/knfsd-stats.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/knfsd-stats.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/knfsd-stats.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/knfsd-stats.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,159 +0,0 @@
-
-Kernel NFS Server Statistics
-============================
-
-This document describes the format and semantics of the statistics
-which the kernel NFS server makes available to userspace.  These
-statistics are available in several text form pseudo files, each of
-which is described separately below.
-
-In most cases you don't need to know these formats, as the nfsstat(8)
-program from the nfs-utils distribution provides a helpful command-line
-interface for extracting and printing them.
-
-All the files described here are formatted as a sequence of text lines,
-separated by newline '\n' characters.  Lines beginning with a hash
-'#' character are comments intended for humans and should be ignored
-by parsing routines.  All other lines contain a sequence of fields
-separated by whitespace.
-
-/proc/fs/nfsd/pool_stats
-------------------------
-
-This file is available in kernels from 2.6.30 onwards, if the
-/proc/fs/nfsd filesystem is mounted (it almost always should be).
-
-The first line is a comment which describes the fields present in
-all the other lines.  The other lines present the following data as
-a sequence of unsigned decimal numeric fields.  One line is shown
-for each NFS thread pool.
-
-All counters are 64 bits wide and wrap naturally.  There is no way
-to zero these counters, instead applications should do their own
-rate conversion.
-
-pool
-	The id number of the NFS thread pool to which this line applies.
-	This number does not change.
-
-	Thread pool ids are a contiguous set of small integers starting
-	at zero.  The maximum value depends on the thread pool mode, but
-	currently cannot be larger than the number of CPUs in the system.
-	Note that in the default case there will be a single thread pool
-	which contains all the nfsd threads and all the CPUs in the system,
-	and thus this file will have a single line with a pool id of "0".
-
-packets-arrived
-	Counts how many NFS packets have arrived.  More precisely, this
-	is the number of times that the network stack has notified the
-	sunrpc server layer that new data may be available on a transport
-	(e.g. an NFS or UDP socket or an NFS/RDMA endpoint).
-
-	Depending on the NFS workload patterns and various network stack
-	effects (such as Large Receive Offload) which can combine packets
-	on the wire, this may be either more or less than the number
-	of NFS calls received (which statistic is available elsewhere).
-	However this is a more accurate and less workload-dependent measure
-	of how much CPU load is being placed on the sunrpc server layer
-	due to NFS network traffic.
-
-sockets-enqueued
-	Counts how many times an NFS transport is enqueued to wait for
-	an nfsd thread to service it, i.e. no nfsd thread was considered
-	available.
-
-	The circumstance this statistic tracks indicates that there was NFS
-	network-facing work to be done but it couldn't be done immediately,
-	thus introducing a small delay in servicing NFS calls.  The ideal
-	rate of change for this counter is zero; significantly non-zero
-	values may indicate a performance limitation.
-
-	This can happen either because there are too few nfsd threads in the
-	thread pool for the NFS workload (the workload is thread-limited),
-	or because the NFS workload needs more CPU time than is available in
-	the thread pool (the workload is CPU-limited).  In the former case,
-	configuring more nfsd threads will probably improve the performance
-	of the NFS workload.  In the latter case, the sunrpc server layer is
-	already choosing not to wake idle nfsd threads because there are too
-	many nfsd threads which want to run but cannot, so configuring more
-	nfsd threads will make no difference whatsoever.  The overloads-avoided
-	statistic (see below) can be used to distinguish these cases.
-
-threads-woken
-	Counts how many times an idle nfsd thread is woken to try to
-	receive some data from an NFS transport.
-
-	This statistic tracks the circumstance where incoming
-	network-facing NFS work is being handled quickly, which is a good
-	thing.  The ideal rate of change for this counter will be close
-	to but less than the rate of change of the packets-arrived counter.
-
-overloads-avoided
-	Counts how many times the sunrpc server layer chose not to wake an
-	nfsd thread, despite the presence of idle nfsd threads, because
-	too many nfsd threads had been recently woken but could not get
-	enough CPU time to actually run.
-
-	This statistic counts a circumstance where the sunrpc layer
-	heuristically avoids overloading the CPU scheduler with too many
-	runnable nfsd threads.  The ideal rate of change for this counter
-	is zero.  Significant non-zero values indicate that the workload
-	is CPU limited.  Usually this is associated with heavy CPU usage
-	on all the CPUs in the nfsd thread pool.
-
-	If a sustained large overloads-avoided rate is detected on a pool,
-	the top(1) utility should be used to check for the following
-	pattern of CPU usage on all the CPUs associated with the given
-	nfsd thread pool.
-
-	 - %us ~= 0 (as you're *NOT* running applications on your NFS server)
-
-	 - %wa ~= 0
-
-	 - %id ~= 0
-
-	 - %sy + %hi + %si ~= 100
-
-	If this pattern is seen, configuring more nfsd threads will *not*
-	improve the performance of the workload.  If this patten is not
-	seen, then something more subtle is wrong.
-
-threads-timedout
-	Counts how many times an nfsd thread triggered an idle timeout,
-	i.e. was not woken to handle any incoming network packets for
-	some time.
-
-	This statistic counts a circumstance where there are more nfsd
-	threads configured than can be used by the NFS workload.  This is
-	a clue that the number of nfsd threads can be reduced without
-	affecting performance.  Unfortunately, it's only a clue and not
-	a strong indication, for a couple of reasons:
-
-	 - Currently the rate at which the counter is incremented is quite
-	   slow; the idle timeout is 60 minutes.  Unless the NFS workload
-	   remains constant for hours at a time, this counter is unlikely
-	   to be providing information that is still useful.
-
-	 - It is usually a wise policy to provide some slack,
-	   i.e. configure a few more nfsds than are currently needed,
-	   to allow for future spikes in load.
-
-
-Note that incoming packets on NFS transports will be dealt with in
-one of three ways.  An nfsd thread can be woken (threads-woken counts
-this case), or the transport can be enqueued for later attention
-(sockets-enqueued counts this case), or the packet can be temporarily
-deferred because the transport is currently being used by an nfsd
-thread.  This last case is not very interesting and is not explicitly
-counted, but can be inferred from the other counters thus:
-
-packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken )
-
-
-More
-----
-Descriptions of the other statistics file should go here.
-
-
-Greg Banks <gnb@sgi.com>
-26 Mar 2009
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/00-INDEX linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/00-INDEX
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/00-INDEX	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/00-INDEX	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,16 @@
+00-INDEX
+	- this file (nfs-related documentation).
+Exporting
+	- explanation of how to make filesystems exportable.
+knfsd-stats.txt
+	- statistics which the NFS server makes available to user space.
+nfs.txt
+	- nfs client, and DNS resolution for fs_locations.
+nfs41-server.txt
+	- info on the Linux server implementation of NFSv4 minor version 1.
+nfs-rdma.txt
+	- how to install and setup the Linux NFS/RDMA client and server software
+nfsroot.txt
+	- short guide on setting up a diskless box with NFS root filesystem.
+rpc-cache.txt
+	- introduction to the caching mechanisms in the sunrpc layer.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/Exporting linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/Exporting
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/Exporting	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/Exporting	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,147 @@
+
+Making Filesystems Exportable
+=============================
+
+Overview
+--------
+
+All filesystem operations require a dentry (or two) as a starting
+point.  Local applications have a reference-counted hold on suitable
+dentries via open file descriptors or cwd/root.  However remote
+applications that access a filesystem via a remote filesystem protocol
+such as NFS may not be able to hold such a reference, and so need a
+different way to refer to a particular dentry.  As the alternative
+form of reference needs to be stable across renames, truncates, and
+server-reboot (among other things, though these tend to be the most
+problematic), there is no simple answer like 'filename'.
+
+The mechanism discussed here allows each filesystem implementation to
+specify how to generate an opaque (outside of the filesystem) byte
+string for any dentry, and how to find an appropriate dentry for any
+given opaque byte string.
+This byte string will be called a "filehandle fragment" as it
+corresponds to part of an NFS filehandle.
+
+A filesystem which supports the mapping between filehandle fragments
+and dentries will be termed "exportable".
+
+
+
+Dcache Issues
+-------------
+
+The dcache normally contains a proper prefix of any given filesystem
+tree.  This means that if any filesystem object is in the dcache, then
+all of the ancestors of that filesystem object are also in the dcache.
+As normal access is by filename this prefix is created naturally and
+maintained easily (by each object maintaining a reference count on
+its parent).
+
+However when objects are included into the dcache by interpreting a
+filehandle fragment, there is no automatic creation of a path prefix
+for the object.  This leads to two related but distinct features of
+the dcache that are not needed for normal filesystem access.
+
+1/ The dcache must sometimes contain objects that are not part of the
+   proper prefix. i.e that are not connected to the root.
+2/ The dcache must be prepared for a newly found (via ->lookup) directory
+   to already have a (non-connected) dentry, and must be able to move
+   that dentry into place (based on the parent and name in the
+   ->lookup).   This is particularly needed for directories as
+   it is a dcache invariant that directories only have one dentry.
+
+To implement these features, the dcache has:
+
+a/ A dentry flag DCACHE_DISCONNECTED which is set on
+   any dentry that might not be part of the proper prefix.
+   This is set when anonymous dentries are created, and cleared when a
+   dentry is noticed to be a child of a dentry which is in the proper
+   prefix. 
+
+b/ A per-superblock list "s_anon" of dentries which are the roots of
+   subtrees that are not in the proper prefix.  These dentries, as
+   well as the proper prefix, need to be released at unmount time.  As
+   these dentries will not be hashed, they are linked together on the
+   d_hash list_head.
+
+c/ Helper routines to allocate anonymous dentries, and to help attach
+   loose directory dentries at lookup time. They are:
+    d_alloc_anon(inode) will return a dentry for the given inode.
+      If the inode already has a dentry, one of those is returned.
+      If it doesn't, a new anonymous (IS_ROOT and
+        DCACHE_DISCONNECTED) dentry is allocated and attached.
+      In the case of a directory, care is taken that only one dentry
+      can ever be attached.
+    d_splice_alias(inode, dentry) will make sure that there is a
+      dentry with the same name and parent as the given dentry, and
+      which refers to the given inode.
+      If the inode is a directory and already has a dentry, then that
+      dentry is d_moved over the given dentry.
+      If the passed dentry gets attached, care is taken that this is
+      mutually exclusive to a d_alloc_anon operation.
+      If the passed dentry is used, NULL is returned, else the used
+      dentry is returned.  This corresponds to the calling pattern of
+      ->lookup.
+  
+ 
+Filesystem Issues
+-----------------
+
+For a filesystem to be exportable it must:
+ 
+   1/ provide the filehandle fragment routines described below.
+   2/ make sure that d_splice_alias is used rather than d_add
+      when ->lookup finds an inode for a given parent and name.
+      Typically the ->lookup routine will end with a:
+
+		return d_splice_alias(inode, dentry);
+	}
+
+
+
+  A file system implementation declares that instances of the filesystem
+are exportable by setting the s_export_op field in the struct
+super_block.  This field must point to a "struct export_operations"
+struct which has the following members:
+
+ encode_fh  (optional)
+    Takes a dentry and creates a filehandle fragment which can later be used
+    to find or create a dentry for the same object.  The default
+    implementation creates a filehandle fragment that encodes a 32bit inode
+    and generation number for the inode encoded, and if necessary the
+    same information for the parent.
+
+  fh_to_dentry (mandatory)
+    Given a filehandle fragment, this should find the implied object and
+    create a dentry for it (possibly with d_alloc_anon).
+
+  fh_to_parent (optional but strongly recommended)
+    Given a filehandle fragment, this should find the parent of the
+    implied object and create a dentry for it (possibly with d_alloc_anon).
+    May fail if the filehandle fragment is too small.
+
+  get_parent (optional but strongly recommended)
+    When given a dentry for a directory, this should return  a dentry for
+    the parent.  Quite possibly the parent dentry will have been allocated
+    by d_alloc_anon.  The default get_parent function just returns an error
+    so any filehandle lookup that requires finding a parent will fail.
+    ->lookup("..") is *not* used as a default as it can leave ".." entries
+    in the dcache which are too messy to work with.
+
+  get_name (optional)
+    When given a parent dentry and a child dentry, this should find a name
+    in the directory identified by the parent dentry, which leads to the
+    object identified by the child dentry.  If no get_name function is
+    supplied, a default implementation is provided which uses vfs_readdir
+    to find potential names, and matches inode numbers to find the correct
+    match.
+
+
+A filehandle fragment consists of an array of 1 or more 4byte words,
+together with a one byte "type".
+The decode_fh routine should not depend on the stated size that is
+passed to it.  This size may be larger than the original filehandle
+generated by encode_fh, in which case it will have been padded with
+nuls.  Rather, the encode_fh routine should choose a "type" which
+indicates the decode_fh how much of the filehandle is valid, and how
+it should be interpreted.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/knfsd-stats.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/knfsd-stats.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/knfsd-stats.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/knfsd-stats.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,159 @@
+
+Kernel NFS Server Statistics
+============================
+
+This document describes the format and semantics of the statistics
+which the kernel NFS server makes available to userspace.  These
+statistics are available in several text form pseudo files, each of
+which is described separately below.
+
+In most cases you don't need to know these formats, as the nfsstat(8)
+program from the nfs-utils distribution provides a helpful command-line
+interface for extracting and printing them.
+
+All the files described here are formatted as a sequence of text lines,
+separated by newline '\n' characters.  Lines beginning with a hash
+'#' character are comments intended for humans and should be ignored
+by parsing routines.  All other lines contain a sequence of fields
+separated by whitespace.
+
+/proc/fs/nfsd/pool_stats
+------------------------
+
+This file is available in kernels from 2.6.30 onwards, if the
+/proc/fs/nfsd filesystem is mounted (it almost always should be).
+
+The first line is a comment which describes the fields present in
+all the other lines.  The other lines present the following data as
+a sequence of unsigned decimal numeric fields.  One line is shown
+for each NFS thread pool.
+
+All counters are 64 bits wide and wrap naturally.  There is no way
+to zero these counters, instead applications should do their own
+rate conversion.
+
+pool
+	The id number of the NFS thread pool to which this line applies.
+	This number does not change.
+
+	Thread pool ids are a contiguous set of small integers starting
+	at zero.  The maximum value depends on the thread pool mode, but
+	currently cannot be larger than the number of CPUs in the system.
+	Note that in the default case there will be a single thread pool
+	which contains all the nfsd threads and all the CPUs in the system,
+	and thus this file will have a single line with a pool id of "0".
+
+packets-arrived
+	Counts how many NFS packets have arrived.  More precisely, this
+	is the number of times that the network stack has notified the
+	sunrpc server layer that new data may be available on a transport
+	(e.g. an NFS or UDP socket or an NFS/RDMA endpoint).
+
+	Depending on the NFS workload patterns and various network stack
+	effects (such as Large Receive Offload) which can combine packets
+	on the wire, this may be either more or less than the number
+	of NFS calls received (which statistic is available elsewhere).
+	However this is a more accurate and less workload-dependent measure
+	of how much CPU load is being placed on the sunrpc server layer
+	due to NFS network traffic.
+
+sockets-enqueued
+	Counts how many times an NFS transport is enqueued to wait for
+	an nfsd thread to service it, i.e. no nfsd thread was considered
+	available.
+
+	The circumstance this statistic tracks indicates that there was NFS
+	network-facing work to be done but it couldn't be done immediately,
+	thus introducing a small delay in servicing NFS calls.  The ideal
+	rate of change for this counter is zero; significantly non-zero
+	values may indicate a performance limitation.
+
+	This can happen either because there are too few nfsd threads in the
+	thread pool for the NFS workload (the workload is thread-limited),
+	or because the NFS workload needs more CPU time than is available in
+	the thread pool (the workload is CPU-limited).  In the former case,
+	configuring more nfsd threads will probably improve the performance
+	of the NFS workload.  In the latter case, the sunrpc server layer is
+	already choosing not to wake idle nfsd threads because there are too
+	many nfsd threads which want to run but cannot, so configuring more
+	nfsd threads will make no difference whatsoever.  The overloads-avoided
+	statistic (see below) can be used to distinguish these cases.
+
+threads-woken
+	Counts how many times an idle nfsd thread is woken to try to
+	receive some data from an NFS transport.
+
+	This statistic tracks the circumstance where incoming
+	network-facing NFS work is being handled quickly, which is a good
+	thing.  The ideal rate of change for this counter will be close
+	to but less than the rate of change of the packets-arrived counter.
+
+overloads-avoided
+	Counts how many times the sunrpc server layer chose not to wake an
+	nfsd thread, despite the presence of idle nfsd threads, because
+	too many nfsd threads had been recently woken but could not get
+	enough CPU time to actually run.
+
+	This statistic counts a circumstance where the sunrpc layer
+	heuristically avoids overloading the CPU scheduler with too many
+	runnable nfsd threads.  The ideal rate of change for this counter
+	is zero.  Significant non-zero values indicate that the workload
+	is CPU limited.  Usually this is associated with heavy CPU usage
+	on all the CPUs in the nfsd thread pool.
+
+	If a sustained large overloads-avoided rate is detected on a pool,
+	the top(1) utility should be used to check for the following
+	pattern of CPU usage on all the CPUs associated with the given
+	nfsd thread pool.
+
+	 - %us ~= 0 (as you're *NOT* running applications on your NFS server)
+
+	 - %wa ~= 0
+
+	 - %id ~= 0
+
+	 - %sy + %hi + %si ~= 100
+
+	If this pattern is seen, configuring more nfsd threads will *not*
+	improve the performance of the workload.  If this patten is not
+	seen, then something more subtle is wrong.
+
+threads-timedout
+	Counts how many times an nfsd thread triggered an idle timeout,
+	i.e. was not woken to handle any incoming network packets for
+	some time.
+
+	This statistic counts a circumstance where there are more nfsd
+	threads configured than can be used by the NFS workload.  This is
+	a clue that the number of nfsd threads can be reduced without
+	affecting performance.  Unfortunately, it's only a clue and not
+	a strong indication, for a couple of reasons:
+
+	 - Currently the rate at which the counter is incremented is quite
+	   slow; the idle timeout is 60 minutes.  Unless the NFS workload
+	   remains constant for hours at a time, this counter is unlikely
+	   to be providing information that is still useful.
+
+	 - It is usually a wise policy to provide some slack,
+	   i.e. configure a few more nfsds than are currently needed,
+	   to allow for future spikes in load.
+
+
+Note that incoming packets on NFS transports will be dealt with in
+one of three ways.  An nfsd thread can be woken (threads-woken counts
+this case), or the transport can be enqueued for later attention
+(sockets-enqueued counts this case), or the packet can be temporarily
+deferred because the transport is currently being used by an nfsd
+thread.  This last case is not very interesting and is not explicitly
+counted, but can be inferred from the other counters thus:
+
+packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken )
+
+
+More
+----
+Descriptions of the other statistics file should go here.
+
+
+Greg Banks <gnb@sgi.com>
+26 Mar 2009
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs41-server.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs41-server.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs41-server.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs41-server.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,222 @@
+NFSv4.1 Server Implementation
+
+Server support for minorversion 1 can be controlled using the
+/proc/fs/nfsd/versions control file.  The string output returned
+by reading this file will contain either "+4.1" or "-4.1"
+correspondingly.
+
+Currently, server support for minorversion 1 is disabled by default.
+It can be enabled at run time by writing the string "+4.1" to
+the /proc/fs/nfsd/versions control file.  Note that to write this
+control file, the nfsd service must be taken down.  Use your user-mode
+nfs-utils to set this up; see rpc.nfsd(8)
+
+(Warning: older servers will interpret "+4.1" and "-4.1" as "+4" and
+"-4", respectively.  Therefore, code meant to work on both new and old
+kernels must turn 4.1 on or off *before* turning support for version 4
+on or off; rpc.nfsd does this correctly.)
+
+The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
+on the latest NFSv4.1 Internet Draft:
+http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+
+From the many new features in NFSv4.1 the current implementation
+focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
+"exactly once" semantics and better control and throttling of the
+resources allocated for each client.
+
+Other NFSv4.1 features, Parallel NFS operations in particular,
+are still under development out of tree.
+See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design
+for more information.
+
+The current implementation is intended for developers only: while it
+does support ordinary file operations on clients we have tested against
+(including the linux client), it is incomplete in ways which may limit
+features unexpectedly, cause known bugs in rare cases, or cause
+interoperability problems with future clients.  Known issues:
+
+	- gss support is questionable: currently mounts with kerberos
+	  from a linux client are possible, but we aren't really
+	  conformant with the spec (for example, we don't use kerberos
+	  on the backchannel correctly).
+	- no trunking support: no clients currently take advantage of
+	  trunking, but this is a mandatory feature, and its use is
+	  recommended to clients in a number of places.  (E.g. to ensure
+	  timely renewal in case an existing connection's retry timeouts
+	  have gotten too long; see section 8.3 of the draft.)
+	  Therefore, lack of this feature may cause future clients to
+	  fail.
+	- Incomplete backchannel support: incomplete backchannel gss
+	  support and no support for BACKCHANNEL_CTL mean that
+	  callbacks (hence delegations and layouts) may not be
+	  available and clients confused by the incomplete
+	  implementation may fail.
+	- Server reboot recovery is unsupported; if the server reboots,
+	  clients may fail.
+	- We do not support SSV, which provides security for shared
+	  client-server state (thus preventing unauthorized tampering
+	  with locks and opens, for example).  It is mandatory for
+	  servers to support this, though no clients use it yet.
+	- Mandatory operations which we do not support, such as
+	  DESTROY_CLIENTID, FREE_STATEID, SECINFO_NO_NAME, and
+	  TEST_STATEID, are not currently used by clients, but will be
+	  (and the spec recommends their uses in common cases), and
+	  clients should not be expected to know how to recover from the
+	  case where they are not supported.  This will eventually cause
+	  interoperability failures.
+
+In addition, some limitations are inherited from the current NFSv4
+implementation:
+
+	- Incomplete delegation enforcement: if a file is renamed or
+	  unlinked, a client holding a delegation may continue to
+	  indefinitely allow opens of the file under the old name.
+
+The table below, taken from the NFSv4.1 document, lists
+the operations that are mandatory to implement (REQ), optional
+(OPT), and NFSv4.0 operations that are required not to implement (MNI)
+in minor version 1.  The first column indicates the operations that
+are not supported yet by the linux server implementation.
+
+The OPTIONAL features identified and their abbreviations are as follows:
+	pNFS	Parallel NFS
+	FDELG	File Delegations
+	DDELG	Directory Delegations
+
+The following abbreviations indicate the linux server implementation status.
+	I	Implemented NFSv4.1 operations.
+	NS	Not Supported.
+	NS*	unimplemented optional feature.
+	P	pNFS features implemented out of tree.
+	PNS	pNFS features that are not supported yet (out of tree).
+
+Operations
+
+   +----------------------+------------+--------------+----------------+
+   | Operation            | REQ, REC,  | Feature      | Definition     |
+   |                      | OPT, or    | (REQ, REC,   |                |
+   |                      | MNI        | or OPT)      |                |
+   +----------------------+------------+--------------+----------------+
+   | ACCESS               | REQ        |              | Section 18.1   |
+NS | BACKCHANNEL_CTL      | REQ        |              | Section 18.33  |
+NS | BIND_CONN_TO_SESSION | REQ        |              | Section 18.34  |
+   | CLOSE                | REQ        |              | Section 18.2   |
+   | COMMIT               | REQ        |              | Section 18.3   |
+   | CREATE               | REQ        |              | Section 18.4   |
+I  | CREATE_SESSION       | REQ        |              | Section 18.36  |
+NS*| DELEGPURGE           | OPT        | FDELG (REQ)  | Section 18.5   |
+   | DELEGRETURN          | OPT        | FDELG,       | Section 18.6   |
+   |                      |            | DDELG, pNFS  |                |
+   |                      |            | (REQ)        |                |
+NS | DESTROY_CLIENTID     | REQ        |              | Section 18.50  |
+I  | DESTROY_SESSION      | REQ        |              | Section 18.37  |
+I  | EXCHANGE_ID          | REQ        |              | Section 18.35  |
+NS | FREE_STATEID         | REQ        |              | Section 18.38  |
+   | GETATTR              | REQ        |              | Section 18.7   |
+P  | GETDEVICEINFO        | OPT        | pNFS (REQ)   | Section 18.40  |
+P  | GETDEVICELIST        | OPT        | pNFS (OPT)   | Section 18.41  |
+   | GETFH                | REQ        |              | Section 18.8   |
+NS*| GET_DIR_DELEGATION   | OPT        | DDELG (REQ)  | Section 18.39  |
+P  | LAYOUTCOMMIT         | OPT        | pNFS (REQ)   | Section 18.42  |
+P  | LAYOUTGET            | OPT        | pNFS (REQ)   | Section 18.43  |
+P  | LAYOUTRETURN         | OPT        | pNFS (REQ)   | Section 18.44  |
+   | LINK                 | OPT        |              | Section 18.9   |
+   | LOCK                 | REQ        |              | Section 18.10  |
+   | LOCKT                | REQ        |              | Section 18.11  |
+   | LOCKU                | REQ        |              | Section 18.12  |
+   | LOOKUP               | REQ        |              | Section 18.13  |
+   | LOOKUPP              | REQ        |              | Section 18.14  |
+   | NVERIFY              | REQ        |              | Section 18.15  |
+   | OPEN                 | REQ        |              | Section 18.16  |
+NS*| OPENATTR             | OPT        |              | Section 18.17  |
+   | OPEN_CONFIRM         | MNI        |              | N/A            |
+   | OPEN_DOWNGRADE       | REQ        |              | Section 18.18  |
+   | PUTFH                | REQ        |              | Section 18.19  |
+   | PUTPUBFH             | REQ        |              | Section 18.20  |
+   | PUTROOTFH            | REQ        |              | Section 18.21  |
+   | READ                 | REQ        |              | Section 18.22  |
+   | READDIR              | REQ        |              | Section 18.23  |
+   | READLINK             | OPT        |              | Section 18.24  |
+NS | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
+   | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
+   | REMOVE               | REQ        |              | Section 18.25  |
+   | RENAME               | REQ        |              | Section 18.26  |
+   | RENEW                | MNI        |              | N/A            |
+   | RESTOREFH            | REQ        |              | Section 18.27  |
+   | SAVEFH               | REQ        |              | Section 18.28  |
+   | SECINFO              | REQ        |              | Section 18.29  |
+NS | SECINFO_NO_NAME      | REC        | pNFS files   | Section 18.45, |
+   |                      |            | layout (REQ) | Section 13.12  |
+I  | SEQUENCE             | REQ        |              | Section 18.46  |
+   | SETATTR              | REQ        |              | Section 18.30  |
+   | SETCLIENTID          | MNI        |              | N/A            |
+   | SETCLIENTID_CONFIRM  | MNI        |              | N/A            |
+NS | SET_SSV              | REQ        |              | Section 18.47  |
+NS | TEST_STATEID         | REQ        |              | Section 18.48  |
+   | VERIFY               | REQ        |              | Section 18.31  |
+NS*| WANT_DELEGATION      | OPT        | FDELG (OPT)  | Section 18.49  |
+   | WRITE                | REQ        |              | Section 18.32  |
+
+Callback Operations
+
+   +-------------------------+-----------+-------------+---------------+
+   | Operation               | REQ, REC, | Feature     | Definition    |
+   |                         | OPT, or   | (REQ, REC,  |               |
+   |                         | MNI       | or OPT)     |               |
+   +-------------------------+-----------+-------------+---------------+
+   | CB_GETATTR              | OPT       | FDELG (REQ) | Section 20.1  |
+P  | CB_LAYOUTRECALL         | OPT       | pNFS (REQ)  | Section 20.3  |
+NS*| CB_NOTIFY               | OPT       | DDELG (REQ) | Section 20.4  |
+P  | CB_NOTIFY_DEVICEID      | OPT       | pNFS (OPT)  | Section 20.12 |
+NS*| CB_NOTIFY_LOCK          | OPT       |             | Section 20.11 |
+NS*| CB_PUSH_DELEG           | OPT       | FDELG (OPT) | Section 20.5  |
+   | CB_RECALL               | OPT       | FDELG,      | Section 20.2  |
+   |                         |           | DDELG, pNFS |               |
+   |                         |           | (REQ)       |               |
+NS*| CB_RECALL_ANY           | OPT       | FDELG,      | Section 20.6  |
+   |                         |           | DDELG, pNFS |               |
+   |                         |           | (REQ)       |               |
+NS | CB_RECALL_SLOT          | REQ       |             | Section 20.8  |
+NS*| CB_RECALLABLE_OBJ_AVAIL | OPT       | DDELG, pNFS | Section 20.7  |
+   |                         |           | (REQ)       |               |
+I  | CB_SEQUENCE             | OPT       | FDELG,      | Section 20.9  |
+   |                         |           | DDELG, pNFS |               |
+   |                         |           | (REQ)       |               |
+NS*| CB_WANTS_CANCELLED      | OPT       | FDELG,      | Section 20.10 |
+   |                         |           | DDELG, pNFS |               |
+   |                         |           | (REQ)       |               |
+   +-------------------------+-----------+-------------+---------------+
+
+Implementation notes:
+
+DELEGPURGE:
+* mandatory only for servers that support CLAIM_DELEGATE_PREV and/or
+  CLAIM_DELEG_PREV_FH (which allows clients to keep delegations that
+  persist across client reboots).  Thus we need not implement this for
+  now.
+
+EXCHANGE_ID:
+* only SP4_NONE state protection supported
+* implementation ids are ignored
+
+CREATE_SESSION:
+* backchannel attributes are ignored
+* backchannel security parameters are ignored
+
+SEQUENCE:
+* no support for dynamic slot table renegotiation (optional)
+
+nfsv4.1 COMPOUND rules:
+The following cases aren't supported yet:
+* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION,
+  DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID.
+* DESTROY_SESSION MUST be the final operation in the COMPOUND request.
+
+Nonstandard compound limitations:
+* No support for a sessions fore channel RPC compound that requires both a
+  ca_maxrequestsize request and a ca_maxresponsesize reply, so we may
+  fail to live up to the promise we made in CREATE_SESSION fore channel
+  negotiation.
+* No more than one IO operation (read, write, readdir) allowed per
+  compound.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs-rdma.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs-rdma.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs-rdma.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs-rdma.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,271 @@
+################################################################################
+#									       #
+#				NFS/RDMA README				       #
+#									       #
+################################################################################
+
+ Author: NetApp and Open Grid Computing
+ Date: May 29, 2008
+
+Table of Contents
+~~~~~~~~~~~~~~~~~
+ - Overview
+ - Getting Help
+ - Installation
+ - Check RDMA and NFS Setup
+ - NFS/RDMA Setup
+
+Overview
+~~~~~~~~
+
+  This document describes how to install and setup the Linux NFS/RDMA client
+  and server software.
+
+  The NFS/RDMA client was first included in Linux 2.6.24. The NFS/RDMA server
+  was first included in the following release, Linux 2.6.25.
+
+  In our testing, we have obtained excellent performance results (full 10Gbit
+  wire bandwidth at minimal client CPU) under many workloads. The code passes
+  the full Connectathon test suite and operates over both Infiniband and iWARP
+  RDMA adapters.
+
+Getting Help
+~~~~~~~~~~~~
+
+  If you get stuck, you can ask questions on the
+
+                nfs-rdma-devel@lists.sourceforge.net
+
+  mailing list.
+
+Installation
+~~~~~~~~~~~~
+
+  These instructions are a step by step guide to building a machine for
+  use with NFS/RDMA.
+
+  - Install an RDMA device
+
+    Any device supported by the drivers in drivers/infiniband/hw is acceptable.
+
+    Testing has been performed using several Mellanox-based IB cards, the
+    Ammasso AMS1100 iWARP adapter, and the Chelsio cxgb3 iWARP adapter.
+
+  - Install a Linux distribution and tools
+
+    The first kernel release to contain both the NFS/RDMA client and server was
+    Linux 2.6.25  Therefore, a distribution compatible with this and subsequent
+    Linux kernel release should be installed.
+
+    The procedures described in this document have been tested with
+    distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
+
+  - Install nfs-utils-1.1.2 or greater on the client
+
+    An NFS/RDMA mount point can be obtained by using the mount.nfs command in
+    nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
+    version with support for NFS/RDMA mounts, but for various reasons we
+    recommend using nfs-utils-1.1.2 or greater). To see which version of
+    mount.nfs you are using, type:
+
+    $ /sbin/mount.nfs -V
+
+    If the version is less than 1.1.2 or the command does not exist,
+    you should install the latest version of nfs-utils.
+
+    Download the latest package from:
+
+    http://www.kernel.org/pub/linux/utils/nfs
+
+    Uncompress the package and follow the installation instructions.
+
+    If you will not need the idmapper and gssd executables (you do not need
+    these to create an NFS/RDMA enabled mount command), the installation
+    process can be simplified by disabling these features when running
+    configure:
+
+    $ ./configure --disable-gss --disable-nfsv4
+
+    To build nfs-utils you will need the tcp_wrappers package installed. For
+    more information on this see the package's README and INSTALL files.
+
+    After building the nfs-utils package, there will be a mount.nfs binary in
+    the utils/mount directory. This binary can be used to initiate NFS v2, v3,
+    or v4 mounts. To initiate a v4 mount, the binary must be called
+    mount.nfs4.  The standard technique is to create a symlink called
+    mount.nfs4 to mount.nfs.
+
+    This mount.nfs binary should be installed at /sbin/mount.nfs as follows:
+
+    $ sudo cp utils/mount/mount.nfs /sbin/mount.nfs
+
+    In this location, mount.nfs will be invoked automatically for NFS mounts
+    by the system mount command.
+
+    NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed
+    on the NFS client machine. You do not need this specific version of
+    nfs-utils on the server. Furthermore, only the mount.nfs command from
+    nfs-utils-1.1.2 is needed on the client.
+
+  - Install a Linux kernel with NFS/RDMA
+
+    The NFS/RDMA client and server are both included in the mainline Linux
+    kernel version 2.6.25 and later. This and other versions of the 2.6 Linux
+    kernel can be found at:
+
+    ftp://ftp.kernel.org/pub/linux/kernel/v2.6/
+
+    Download the sources and place them in an appropriate location.
+
+  - Configure the RDMA stack
+
+    Make sure your kernel configuration has RDMA support enabled. Under
+    Device Drivers -> InfiniBand support, update the kernel configuration
+    to enable InfiniBand support [NOTE: the option name is misleading. Enabling
+    InfiniBand support is required for all RDMA devices (IB, iWARP, etc.)].
+
+    Enable the appropriate IB HCA support (mlx4, mthca, ehca, ipath, etc.) or
+    iWARP adapter support (amso, cxgb3, etc.).
+
+    If you are using InfiniBand, be sure to enable IP-over-InfiniBand support.
+
+  - Configure the NFS client and server
+
+    Your kernel configuration must also have NFS file system support and/or
+    NFS server support enabled. These and other NFS related configuration
+    options can be found under File Systems -> Network File Systems.
+
+  - Build, install, reboot
+
+    The NFS/RDMA code will be enabled automatically if NFS and RDMA
+    are turned on. The NFS/RDMA client and server are configured via the hidden
+    SUNRPC_XPRT_RDMA config option that depends on SUNRPC and INFINIBAND. The
+    value of SUNRPC_XPRT_RDMA will be:
+
+     - N if either SUNRPC or INFINIBAND are N, in this case the NFS/RDMA client
+       and server will not be built
+     - M if both SUNRPC and INFINIBAND are on (M or Y) and at least one is M,
+       in this case the NFS/RDMA client and server will be built as modules
+     - Y if both SUNRPC and INFINIBAND are Y, in this case the NFS/RDMA client
+       and server will be built into the kernel
+
+    Therefore, if you have followed the steps above and turned no NFS and RDMA,
+    the NFS/RDMA client and server will be built.
+
+    Build a new kernel, install it, boot it.
+
+Check RDMA and NFS Setup
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Before configuring the NFS/RDMA software, it is a good idea to test
+    your new kernel to ensure that the kernel is working correctly.
+    In particular, it is a good idea to verify that the RDMA stack
+    is functioning as expected and standard NFS over TCP/IP and/or UDP/IP
+    is working properly.
+
+  - Check RDMA Setup
+
+    If you built the RDMA components as modules, load them at
+    this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
+    card:
+
+    $ modprobe ib_mthca
+    $ modprobe ib_ipoib
+
+    If you are using InfiniBand, make sure there is a Subnet Manager (SM)
+    running on the network. If your IB switch has an embedded SM, you can
+    use it. Otherwise, you will need to run an SM, such as OpenSM, on one
+    of your end nodes.
+
+    If an SM is running on your network, you should see the following:
+
+    $ cat /sys/class/infiniband/driverX/ports/1/state
+    4: ACTIVE
+
+    where driverX is mthca0, ipath5, ehca3, etc.
+
+    To further test the InfiniBand software stack, use IPoIB (this
+    assumes you have two IB hosts named host1 and host2):
+
+    host1$ ifconfig ib0 a.b.c.x
+    host2$ ifconfig ib0 a.b.c.y
+    host1$ ping a.b.c.y
+    host2$ ping a.b.c.x
+
+    For other device types, follow the appropriate procedures.
+
+  - Check NFS Setup
+
+    For the NFS components enabled above (client and/or server),
+    test their functionality over standard Ethernet using TCP/IP or UDP/IP.
+
+NFS/RDMA Setup
+~~~~~~~~~~~~~~
+
+  We recommend that you use two machines, one to act as the client and
+  one to act as the server.
+
+  One time configuration:
+
+  - On the server system, configure the /etc/exports file and
+    start the NFS/RDMA server.
+
+    Exports entries with the following formats have been tested:
+
+    /vol0   192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
+    /vol0   192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
+
+    The IP address(es) is(are) the client's IPoIB address for an InfiniBand
+    HCA or the cleint's iWARP address(es) for an RNIC.
+
+    NOTE: The "insecure" option must be used because the NFS/RDMA client does
+    not use a reserved port.
+
+ Each time a machine boots:
+
+  - Load and configure the RDMA drivers
+
+    For InfiniBand using a Mellanox adapter:
+
+    $ modprobe ib_mthca
+    $ modprobe ib_ipoib
+    $ ifconfig ib0 a.b.c.d
+
+    NOTE: use unique addresses for the client and server
+
+  - Start the NFS server
+
+    If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
+    kernel config), load the RDMA transport module:
+
+    $ modprobe svcrdma
+
+    Regardless of how the server was built (module or built-in), start the
+    server:
+
+    $ /etc/init.d/nfs start
+
+    or
+
+    $ service nfs start
+
+    Instruct the server to listen on the RDMA transport:
+
+    $ echo rdma 20049 > /proc/fs/nfsd/portlist
+
+  - On the client system
+
+    If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
+    kernel config), load the RDMA client module:
+
+    $ modprobe xprtrdma.ko
+
+    Regardless of how the client was built (module or built-in), use this
+    command to mount the NFS/RDMA server:
+
+    $ mount -o rdma,port=20049 <IPoIB-server-name-or-address>:/<export> /mnt
+
+    To verify that the mount is using RDMA, run "cat /proc/mounts" and check
+    the "proto" field for the given mount.
+
+  Congratulations! You're using NFS/RDMA!
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfsroot.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfsroot.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfsroot.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfsroot.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,270 @@
+Mounting the root filesystem via NFS (nfsroot)
+===============================================
+
+Written 1996 by Gero Kuhlmann <gero@gkminix.han.de>
+Updated 1997 by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+Updated 2006 by Nico Schottelius <nico-kernel-nfsroot@schottelius.org>
+Updated 2006 by Horms <horms@verge.net.au>
+
+
+
+In order to use a diskless system, such as an X-terminal or printer server
+for example, it is necessary for the root filesystem to be present on a
+non-disk device. This may be an initramfs (see Documentation/filesystems/
+ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a
+filesystem mounted via NFS. The following text describes on how to use NFS
+for the root filesystem. For the rest of this text 'client' means the
+diskless system, and 'server' means the NFS server.
+
+
+
+
+1.) Enabling nfsroot capabilities
+    -----------------------------
+
+In order to use nfsroot, NFS client support needs to be selected as
+built-in during configuration. Once this has been selected, the nfsroot
+option will become available, which should also be selected.
+
+In the networking options, kernel level autoconfiguration can be selected,
+along with the types of autoconfiguration to support. Selecting all of
+DHCP, BOOTP and RARP is safe.
+
+
+
+
+2.) Kernel command line
+    -------------------
+
+When the kernel has been loaded by a boot loader (see below) it needs to be
+told what root fs device to use. And in the case of nfsroot, where to find
+both the server and the name of the directory on the server to mount as root.
+This can be established using the following kernel command line parameters:
+
+
+root=/dev/nfs
+
+  This is necessary to enable the pseudo-NFS-device. Note that it's not a
+  real device but just a synonym to tell the kernel to use NFS instead of
+  a real device.
+
+
+nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
+
+  If the `nfsroot' parameter is NOT given on the command line,
+  the default "/tftpboot/%s" will be used.
+
+  <server-ip>	Specifies the IP address of the NFS server.
+		The default address is determined by the `ip' parameter
+		(see below). This parameter allows the use of different
+		servers for IP autoconfiguration and NFS.
+
+  <root-dir>	Name of the directory on the server to mount as root.
+		If there is a "%s" token in the string, it will be
+		replaced by the ASCII-representation of the client's
+		IP address.
+
+  <nfs-options>	Standard NFS options. All options are separated by commas.
+		The following defaults are used:
+			port		= as given by server portmap daemon
+			rsize		= 4096
+			wsize		= 4096
+			timeo		= 7
+			retrans		= 3
+			acregmin	= 3
+			acregmax	= 60
+			acdirmin	= 30
+			acdirmax	= 60
+			flags		= hard, nointr, noposix, cto, ac
+
+
+ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>
+
+  This parameter tells the kernel how to configure IP addresses of devices
+  and also how to set up the IP routing table. It was originally called
+  `nfsaddrs', but now the boot-time IP configuration works independently of
+  NFS, so it was renamed to `ip' and the old name remained as an alias for
+  compatibility reasons.
+
+  If this parameter is missing from the kernel command line, all fields are
+  assumed to be empty, and the defaults mentioned below apply. In general
+  this means that the kernel tries to configure everything using
+  autoconfiguration.
+
+  The <autoconf> parameter can appear alone as the value to the `ip'
+  parameter (without all the ':' characters before).  If the value is
+  "ip=off" or "ip=none", no autoconfiguration will take place, otherwise
+  autoconfiguration will take place.  The most common way to use this
+  is "ip=dhcp".
+
+  <client-ip>	IP address of the client.
+
+  		Default:  Determined using autoconfiguration.
+
+  <server-ip>	IP address of the NFS server. If RARP is used to determine
+		the client address and this parameter is NOT empty only
+		replies from the specified server are accepted.
+
+		Only required for NFS root. That is autoconfiguration
+		will not be triggered if it is missing and NFS root is not
+		in operation.
+
+		Default: Determined using autoconfiguration.
+		         The address of the autoconfiguration server is used.
+
+  <gw-ip>	IP address of a gateway if the server is on a different subnet.
+
+		Default: Determined using autoconfiguration.
+
+  <netmask>	Netmask for local network interface. If unspecified
+		the netmask is derived from the client IP address assuming
+		classful addressing.
+
+		Default:  Determined using autoconfiguration.
+
+  <hostname>	Name of the client. May be supplied by autoconfiguration,
+  		but its absence will not trigger autoconfiguration.
+
+  		Default: Client IP address is used in ASCII notation.
+
+  <device>	Name of network device to use.
+
+		Default: If the host only has one device, it is used.
+			 Otherwise the device is determined using
+			 autoconfiguration. This is done by sending
+			 autoconfiguration requests out of all devices,
+			 and using the device that received the first reply.
+
+  <autoconf>	Method to use for autoconfiguration. In the case of options
+                which specify multiple autoconfiguration protocols,
+		requests are sent using all protocols, and the first one
+		to reply is used.
+
+		Only autoconfiguration protocols that have been compiled
+		into the kernel will be used, regardless of the value of
+		this option.
+
+                  off or none: don't use autoconfiguration
+				(do static IP assignment instead)
+		  on or any:   use any protocol available in the kernel
+			       (default)
+		  dhcp:        use DHCP
+		  bootp:       use BOOTP
+		  rarp:        use RARP
+		  both:        use both BOOTP and RARP but not DHCP
+		               (old option kept for backwards compatibility)
+
+                Default: any
+
+
+
+
+3.) Boot Loader
+    ----------
+
+To get the kernel into memory different approaches can be used.
+They depend on various facilities being available:
+
+
+3.1)  Booting from a floppy using syslinux
+
+	When building kernels, an easy way to create a boot floppy that uses
+	syslinux is to use the zdisk or bzdisk make targets which use zimage
+      	and bzimage images respectively. Both targets accept the
+     	FDARGS parameter which can be used to set the kernel command line.
+
+	e.g.
+	   make bzdisk FDARGS="root=/dev/nfs"
+
+   	Note that the user running this command will need to have
+     	access to the floppy drive device, /dev/fd0
+
+     	For more information on syslinux, including how to create bootdisks
+     	for prebuilt kernels, see http://syslinux.zytor.com/
+
+	N.B: Previously it was possible to write a kernel directly to
+	     a floppy using dd, configure the boot device using rdev, and
+	     boot using the resulting floppy. Linux no longer supports this
+	     method of booting.
+
+3.2) Booting from a cdrom using isolinux
+
+     	When building kernels, an easy way to create a bootable cdrom that
+     	uses isolinux is to use the isoimage target which uses a bzimage
+     	image. Like zdisk and bzdisk, this target accepts the FDARGS
+     	parameter which can be used to set the kernel command line.
+
+	e.g.
+	  make isoimage FDARGS="root=/dev/nfs"
+
+     	The resulting iso image will be arch/<ARCH>/boot/image.iso
+     	This can be written to a cdrom using a variety of tools including
+     	cdrecord.
+
+	e.g.
+	  cdrecord dev=ATAPI:1,0,0 arch/i386/boot/image.iso
+
+     	For more information on isolinux, including how to create bootdisks
+     	for prebuilt kernels, see http://syslinux.zytor.com/
+
+3.2) Using LILO
+	When using LILO all the necessary command line parameters may be
+	specified using the 'append=' directive in the LILO configuration
+	file.
+
+	However, to use the 'root=' directive you also need to create
+	a dummy root device, which may be removed after LILO is run.
+
+	mknod /dev/boot255 c 0 255
+
+	For information on configuring LILO, please refer to its documentation.
+
+3.3) Using GRUB
+	When using GRUB, kernel parameter are simply appended after the kernel
+	specification: kernel <kernel> <parameters>
+
+3.4) Using loadlin
+	loadlin may be used to boot Linux from a DOS command prompt without
+	requiring a local hard disk to mount as root. This has not been
+	thoroughly tested by the authors of this document, but in general
+	it should be possible configure the kernel command line similarly
+	to the configuration of LILO.
+
+	Please refer to the loadlin documentation for further information.
+
+3.5) Using a boot ROM
+	This is probably the most elegant way of booting a diskless client.
+	With a boot ROM the kernel is loaded using the TFTP protocol. The
+	authors of this document are not aware of any no commercial boot
+	ROMs that support booting Linux over the network. However, there
+	are two free implementations of a boot ROM, netboot-nfs and
+	etherboot, both of which are available on sunsite.unc.edu, and both
+	of which contain everything you need to boot a diskless Linux client.
+
+3.6) Using pxelinux
+	Pxelinux may be used to boot linux using the PXE boot loader
+	which is present on many modern network cards.
+
+	When using pxelinux, the kernel image is specified using
+	"kernel <relative-path-below /tftpboot>". The nfsroot parameters
+	are passed to the kernel by adding them to the "append" line.
+	It is common to use serial console in conjunction with pxeliunx,
+	see Documentation/serial-console.txt for more information.
+
+	For more information on isolinux, including how to create bootdisks
+	for prebuilt kernels, see http://syslinux.zytor.com/
+
+
+
+
+4.) Credits
+    -------
+
+  The nfsroot code in the kernel and the RARP support have been written
+  by Gero Kuhlmann <gero@gkminix.han.de>.
+
+  The rest of the IP layer autoconfiguration code has been written
+  by Martin Mares <mj@atrey.karlin.mff.cuni.cz>.
+
+  In order to write the initial version of nfsroot I would like to thank
+  Jens-Uwe Mager <jum@anubis.han.de> for his help.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/nfs.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/nfs.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,98 @@
+
+The NFS client
+==============
+
+The NFS version 2 protocol was first documented in RFC1094 (March 1989).
+Since then two more major releases of NFS have been published, with NFSv3
+being documented in RFC1813 (June 1995), and NFSv4 in RFC3530 (April
+2003).
+
+The Linux NFS client currently supports all the above published versions,
+and work is in progress on adding support for minor version 1 of the NFSv4
+protocol.
+
+The purpose of this document is to provide information on some of the
+upcall interfaces that are used in order to provide the NFS client with
+some of the information that it requires in order to fully comply with
+the NFS spec.
+
+The DNS resolver
+================
+
+NFSv4 allows for one server to refer the NFS client to data that has been
+migrated onto another server by means of the special "fs_locations"
+attribute. See
+	http://tools.ietf.org/html/rfc3530#section-6
+and
+	http://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00
+
+The fs_locations information can take the form of either an ip address and
+a path, or a DNS hostname and a path. The latter requires the NFS client to
+do a DNS lookup in order to mount the new volume, and hence the need for an
+upcall to allow userland to provide this service.
+
+Assuming that the user has the 'rpc_pipefs' filesystem mounted in the usual
+/var/lib/nfs/rpc_pipefs, the upcall consists of the following steps:
+
+   (1) The process checks the dns_resolve cache to see if it contains a
+       valid entry. If so, it returns that entry and exits.
+
+   (2) If no valid entry exists, the helper script '/sbin/nfs_cache_getent'
+       (may be changed using the 'nfs.cache_getent' kernel boot parameter)
+       is run, with two arguments:
+		- the cache name, "dns_resolve"
+		- the hostname to resolve
+
+   (3) After looking up the corresponding ip address, the helper script
+       writes the result into the rpc_pipefs pseudo-file
+       '/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel'
+       in the following (text) format:
+
+		"<ip address> <hostname> <ttl>\n"
+
+       Where <ip address> is in the usual IPv4 (123.456.78.90) or IPv6
+       (ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) format.
+       <hostname> is identical to the second argument of the helper
+       script, and <ttl> is the 'time to live' of this cache entry (in
+       units of seconds).
+
+       Note: If <ip address> is invalid, say the string "0", then a negative
+       entry is created, which will cause the kernel to treat the hostname
+       as having no valid DNS translation.
+
+
+
+
+A basic sample /sbin/nfs_cache_getent
+=====================================
+
+#!/bin/bash
+#
+ttl=600
+#
+cut=/usr/bin/cut
+getent=/usr/bin/getent
+rpc_pipefs=/var/lib/nfs/rpc_pipefs
+#
+die()
+{
+	echo "Usage: $0 cache_name entry_name"
+	exit 1
+}
+
+[ $# -lt 2 ] && die
+cachename="$1"
+cache_path=${rpc_pipefs}/cache/${cachename}/channel
+
+case "${cachename}" in
+	dns_resolve)
+		name="$2"
+		result="$(${getent} hosts ${name} | ${cut} -f1 -d\ )"
+		[ -z "${result}" ] && result="0"
+		;;
+	*)
+		die
+		;;
+esac
+echo "${result} ${name} ${ttl}" >${cache_path}
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/rpc-cache.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/rpc-cache.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs/rpc-cache.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs/rpc-cache.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,202 @@
+	This document gives a brief introduction to the caching
+mechanisms in the sunrpc layer that is used, in particular,
+for NFS authentication.
+
+CACHES
+======
+The caching replaces the old exports table and allows for
+a wide variety of values to be caches.
+
+There are a number of caches that are similar in structure though
+quite possibly very different in content and use.  There is a corpus
+of common code for managing these caches.
+
+Examples of caches that are likely to be needed are:
+  - mapping from IP address to client name
+  - mapping from client name and filesystem to export options
+  - mapping from UID to list of GIDs, to work around NFS's limitation
+    of 16 gids.
+  - mappings between local UID/GID and remote UID/GID for sites that
+    do not have uniform uid assignment
+  - mapping from network identify to public key for crypto authentication.
+
+The common code handles such things as:
+   - general cache lookup with correct locking
+   - supporting 'NEGATIVE' as well as positive entries
+   - allowing an EXPIRED time on cache items, and removing
+     items after they expire, and are no longer in-use.
+   - making requests to user-space to fill in cache entries
+   - allowing user-space to directly set entries in the cache
+   - delaying RPC requests that depend on as-yet incomplete
+     cache entries, and replaying those requests when the cache entry
+     is complete.
+   - clean out old entries as they expire.
+
+Creating a Cache
+----------------
+
+1/ A cache needs a datum to store.  This is in the form of a
+   structure definition that must contain a
+     struct cache_head
+   as an element, usually the first.
+   It will also contain a key and some content.
+   Each cache element is reference counted and contains
+   expiry and update times for use in cache management.
+2/ A cache needs a "cache_detail" structure that
+   describes the cache.  This stores the hash table, some
+   parameters for cache management, and some operations detailing how
+   to work with particular cache items.
+   The operations requires are:
+   	struct cache_head *alloc(void)
+		This simply allocates appropriate memory and returns
+   		a pointer to the cache_detail embedded within the
+		structure
+	void cache_put(struct kref *)
+		This is called when the last reference to an item is
+		dropped.  The pointer passed is to the 'ref' field
+		in the cache_head.  cache_put should release any
+		references create by 'cache_init' and, if CACHE_VALID
+		is set, any references created by cache_update.
+		It should then release the memory allocated by
+   		'alloc'.
+        int match(struct cache_head *orig, struct cache_head *new)
+		test if the keys in the two structures match.  Return
+		1 if they do, 0 if they don't.
+	void init(struct cache_head *orig, struct cache_head *new)
+		Set the 'key' fields in 'new' from 'orig'.  This may
+		include taking references to shared objects.
+	void update(struct cache_head *orig, struct cache_head *new)
+		Set the 'content' fileds in 'new' from 'orig'.
+	int cache_show(struct seq_file *m, struct cache_detail *cd,
+			struct cache_head *h)
+		Optional.  Used to provide a /proc file that lists the
+		contents of a cache.  This should show one item,
+   		usually on just one line.
+	int cache_request(struct cache_detail *cd, struct cache_head *h,
+   		char **bpp, int *blen)
+		Format a request to be send to user-space for an item
+   		to be instantiated.  *bpp is a buffer of size *blen.
+		bpp should be moved forward over the encoded message,
+		and  *blen should be reduced to show how much free
+		space remains.  Return 0 on success or <0 if not
+		enough room or other problem.
+	int cache_parse(struct cache_detail *cd, char *buf, int len)
+		A message from user space has arrived to fill out a
+		cache entry.  It is in 'buf' of length 'len'.
+		cache_parse should parse this, find the item in the
+		cache with sunrpc_cache_lookup, and update the item
+		with sunrpc_cache_update.
+
+
+3/ A cache needs to be registered using cache_register().  This
+   includes it on a list of caches that will be regularly
+   cleaned to discard old data.
+
+Using a cache
+-------------
+
+To find a value in a cache, call sunrpc_cache_lookup passing a pointer
+to the cache_head in a sample item with the 'key' fields filled in.
+This will be passed to ->match to identify the target entry.  If no
+entry is found, a new entry will be create, added to the cache, and
+marked as not containing valid data.
+
+The item returned is typically passed to cache_check which will check
+if the data is valid, and may initiate an up-call to get fresh data.
+cache_check will return -ENOENT in the entry is negative or if an up
+call is needed but not possible, -EAGAIN if an upcall is pending,
+or 0 if the data is valid;
+
+cache_check can be passed a "struct cache_req *".  This structure is
+typically embedded in the actual request and can be used to create a
+deferred copy of the request (struct cache_deferred_req).  This is
+done when the found cache item is not uptodate, but the is reason to
+believe that userspace might provide information soon.  When the cache
+item does become valid, the deferred copy of the request will be
+revisited (->revisit).  It is expected that this method will
+reschedule the request for processing.
+
+The value returned by sunrpc_cache_lookup can also be passed to
+sunrpc_cache_update to set the content for the item.  A second item is
+passed which should hold the content.  If the item found by _lookup
+has valid data, then it is discarded and a new item is created.  This
+saves any user of an item from worrying about content changing while
+it is being inspected.  If the item found by _lookup does not contain
+valid data, then the content is copied across and CACHE_VALID is set.
+
+Populating a cache
+------------------
+
+Each cache has a name, and when the cache is registered, a directory
+with that name is created in /proc/net/rpc
+
+This directory contains a file called 'channel' which is a channel
+for communicating between kernel and user for populating the cache.
+This directory may later contain other files of interacting
+with the cache.
+
+The 'channel' works a bit like a datagram socket. Each 'write' is
+passed as a whole to the cache for parsing and interpretation.
+Each cache can treat the write requests differently, but it is
+expected that a message written will contain:
+  - a key
+  - an expiry time
+  - a content.
+with the intention that an item in the cache with the give key
+should be create or updated to have the given content, and the
+expiry time should be set on that item.
+
+Reading from a channel is a bit more interesting.  When a cache
+lookup fails, or when it succeeds but finds an entry that may soon
+expire, a request is lodged for that cache item to be updated by
+user-space.  These requests appear in the channel file.
+
+Successive reads will return successive requests.
+If there are no more requests to return, read will return EOF, but a
+select or poll for read will block waiting for another request to be
+added.
+
+Thus a user-space helper is likely to:
+  open the channel.
+    select for readable
+    read a request
+    write a response
+  loop.
+
+If it dies and needs to be restarted, any requests that have not been
+answered will still appear in the file and will be read by the new
+instance of the helper.
+
+Each cache should define a "cache_parse" method which takes a message
+written from user-space and processes it.  It should return an error
+(which propagates back to the write syscall) or 0.
+
+Each cache should also define a "cache_request" method which
+takes a cache item and encodes a request into the buffer
+provided.
+
+Note: If a cache has no active readers on the channel, and has had not
+active readers for more than 60 seconds, further requests will not be
+added to the channel but instead all lookups that do not find a valid
+entry will fail.  This is partly for backward compatibility: The
+previous nfs exports table was deemed to be authoritative and a
+failed lookup meant a definite 'no'.
+
+request/response format
+-----------------------
+
+While each cache is free to use it's own format for requests
+and responses over channel, the following is recommended as
+appropriate and support routines are available to help:
+Each request or response record should be printable ASCII
+with precisely one newline character which should be at the end.
+Fields within the record should be separated by spaces, normally one.
+If spaces, newlines, or nul characters are needed in a field they
+much be quoted.  two mechanisms are available:
+1/ If a field begins '\x' then it must contain an even number of
+   hex digits, and pairs of these digits provide the bytes in the
+   field.
+2/ otherwise a \ in the field must be followed by 3 octal digits
+   which give the code for a byte.  Other characters are treated
+   as them selves.  At the very least, space, newline, nul, and
+   '\' must be quoted in this way.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs41-server.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs41-server.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs41-server.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs41-server.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,215 +0,0 @@
-NFSv4.1 Server Implementation
-
-Server support for minorversion 1 can be controlled using the
-/proc/fs/nfsd/versions control file.  The string output returned
-by reading this file will contain either "+4.1" or "-4.1"
-correspondingly.
-
-Currently, server support for minorversion 1 is disabled by default.
-It can be enabled at run time by writing the string "+4.1" to
-the /proc/fs/nfsd/versions control file.  Note that to write this
-control file, the nfsd service must be taken down.  Use your user-mode
-nfs-utils to set this up; see rpc.nfsd(8)
-
-(Warning: older servers will interpret "+4.1" and "-4.1" as "+4" and
-"-4", respectively.  Therefore, code meant to work on both new and old
-kernels must turn 4.1 on or off *before* turning support for version 4
-on or off; rpc.nfsd does this correctly.)
-
-The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
-on the latest NFSv4.1 Internet Draft:
-http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
-
-From the many new features in NFSv4.1 the current implementation
-focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
-"exactly once" semantics and better control and throttling of the
-resources allocated for each client.
-
-Other NFSv4.1 features, Parallel NFS operations in particular,
-are still under development out of tree.
-See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design
-for more information.
-
-The current implementation is intended for developers only: while it
-does support ordinary file operations on clients we have tested against
-(including the linux client), it is incomplete in ways which may limit
-features unexpectedly, cause known bugs in rare cases, or cause
-interoperability problems with future clients.  Known issues:
-
-	- gss support is questionable: currently mounts with kerberos
-	  from a linux client are possible, but we aren't really
-	  conformant with the spec (for example, we don't use kerberos
-	  on the backchannel correctly).
-	- no trunking support: no clients currently take advantage of
-	  trunking, but this is a mandatory failure, and its use is
-	  recommended to clients in a number of places.  (E.g. to ensure
-	  timely renewal in case an existing connection's retry timeouts
-	  have gotten too long; see section 8.3 of the draft.)
-	  Therefore, lack of this feature may cause future clients to
-	  fail.
-	- Incomplete backchannel support: incomplete backchannel gss
-	  support and no support for BACKCHANNEL_CTL mean that
-	  callbacks (hence delegations and layouts) may not be
-	  available and clients confused by the incomplete
-	  implementation may fail.
-	- Server reboot recovery is unsupported; if the server reboots,
-	  clients may fail.
-	- We do not support SSV, which provides security for shared
-	  client-server state (thus preventing unauthorized tampering
-	  with locks and opens, for example).  It is mandatory for
-	  servers to support this, though no clients use it yet.
-	- Mandatory operations which we do not support, such as
-	  DESTROY_CLIENTID, FREE_STATEID, SECINFO_NO_NAME, and
-	  TEST_STATEID, are not currently used by clients, but will be
-	  (and the spec recommends their uses in common cases), and
-	  clients should not be expected to know how to recover from the
-	  case where they are not supported.  This will eventually cause
-	  interoperability failures.
-
-In addition, some limitations are inherited from the current NFSv4
-implementation:
-
-	- Incomplete delegation enforcement: if a file is renamed or
-	  unlinked, a client holding a delegation may continue to
-	  indefinitely allow opens of the file under the old name.
-
-The table below, taken from the NFSv4.1 document, lists
-the operations that are mandatory to implement (REQ), optional
-(OPT), and NFSv4.0 operations that are required not to implement (MNI)
-in minor version 1.  The first column indicates the operations that
-are not supported yet by the linux server implementation.
-
-The OPTIONAL features identified and their abbreviations are as follows:
-	pNFS	Parallel NFS
-	FDELG	File Delegations
-	DDELG	Directory Delegations
-
-The following abbreviations indicate the linux server implementation status.
-	I	Implemented NFSv4.1 operations.
-	NS	Not Supported.
-	NS*	unimplemented optional feature.
-	P	pNFS features implemented out of tree.
-	PNS	pNFS features that are not supported yet (out of tree).
-
-Operations
-
-   +----------------------+------------+--------------+----------------+
-   | Operation            | REQ, REC,  | Feature      | Definition     |
-   |                      | OPT, or    | (REQ, REC,   |                |
-   |                      | MNI        | or OPT)      |                |
-   +----------------------+------------+--------------+----------------+
-   | ACCESS               | REQ        |              | Section 18.1   |
-NS | BACKCHANNEL_CTL      | REQ        |              | Section 18.33  |
-NS | BIND_CONN_TO_SESSION | REQ        |              | Section 18.34  |
-   | CLOSE                | REQ        |              | Section 18.2   |
-   | COMMIT               | REQ        |              | Section 18.3   |
-   | CREATE               | REQ        |              | Section 18.4   |
-I  | CREATE_SESSION       | REQ        |              | Section 18.36  |
-NS*| DELEGPURGE           | OPT        | FDELG (REQ)  | Section 18.5   |
-   | DELEGRETURN          | OPT        | FDELG,       | Section 18.6   |
-   |                      |            | DDELG, pNFS  |                |
-   |                      |            | (REQ)        |                |
-NS | DESTROY_CLIENTID     | REQ        |              | Section 18.50  |
-I  | DESTROY_SESSION      | REQ        |              | Section 18.37  |
-I  | EXCHANGE_ID          | REQ        |              | Section 18.35  |
-NS | FREE_STATEID         | REQ        |              | Section 18.38  |
-   | GETATTR              | REQ        |              | Section 18.7   |
-P  | GETDEVICEINFO        | OPT        | pNFS (REQ)   | Section 18.40  |
-P  | GETDEVICELIST        | OPT        | pNFS (OPT)   | Section 18.41  |
-   | GETFH                | REQ        |              | Section 18.8   |
-NS*| GET_DIR_DELEGATION   | OPT        | DDELG (REQ)  | Section 18.39  |
-P  | LAYOUTCOMMIT         | OPT        | pNFS (REQ)   | Section 18.42  |
-P  | LAYOUTGET            | OPT        | pNFS (REQ)   | Section 18.43  |
-P  | LAYOUTRETURN         | OPT        | pNFS (REQ)   | Section 18.44  |
-   | LINK                 | OPT        |              | Section 18.9   |
-   | LOCK                 | REQ        |              | Section 18.10  |
-   | LOCKT                | REQ        |              | Section 18.11  |
-   | LOCKU                | REQ        |              | Section 18.12  |
-   | LOOKUP               | REQ        |              | Section 18.13  |
-   | LOOKUPP              | REQ        |              | Section 18.14  |
-   | NVERIFY              | REQ        |              | Section 18.15  |
-   | OPEN                 | REQ        |              | Section 18.16  |
-NS*| OPENATTR             | OPT        |              | Section 18.17  |
-   | OPEN_CONFIRM         | MNI        |              | N/A            |
-   | OPEN_DOWNGRADE       | REQ        |              | Section 18.18  |
-   | PUTFH                | REQ        |              | Section 18.19  |
-   | PUTPUBFH             | REQ        |              | Section 18.20  |
-   | PUTROOTFH            | REQ        |              | Section 18.21  |
-   | READ                 | REQ        |              | Section 18.22  |
-   | READDIR              | REQ        |              | Section 18.23  |
-   | READLINK             | OPT        |              | Section 18.24  |
-NS | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
-   | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
-   | REMOVE               | REQ        |              | Section 18.25  |
-   | RENAME               | REQ        |              | Section 18.26  |
-   | RENEW                | MNI        |              | N/A            |
-   | RESTOREFH            | REQ        |              | Section 18.27  |
-   | SAVEFH               | REQ        |              | Section 18.28  |
-   | SECINFO              | REQ        |              | Section 18.29  |
-NS | SECINFO_NO_NAME      | REC        | pNFS files   | Section 18.45, |
-   |                      |            | layout (REQ) | Section 13.12  |
-I  | SEQUENCE             | REQ        |              | Section 18.46  |
-   | SETATTR              | REQ        |              | Section 18.30  |
-   | SETCLIENTID          | MNI        |              | N/A            |
-   | SETCLIENTID_CONFIRM  | MNI        |              | N/A            |
-NS | SET_SSV              | REQ        |              | Section 18.47  |
-NS | TEST_STATEID         | REQ        |              | Section 18.48  |
-   | VERIFY               | REQ        |              | Section 18.31  |
-NS*| WANT_DELEGATION      | OPT        | FDELG (OPT)  | Section 18.49  |
-   | WRITE                | REQ        |              | Section 18.32  |
-
-Callback Operations
-
-   +-------------------------+-----------+-------------+---------------+
-   | Operation               | REQ, REC, | Feature     | Definition    |
-   |                         | OPT, or   | (REQ, REC,  |               |
-   |                         | MNI       | or OPT)     |               |
-   +-------------------------+-----------+-------------+---------------+
-   | CB_GETATTR              | OPT       | FDELG (REQ) | Section 20.1  |
-P  | CB_LAYOUTRECALL         | OPT       | pNFS (REQ)  | Section 20.3  |
-NS*| CB_NOTIFY               | OPT       | DDELG (REQ) | Section 20.4  |
-P  | CB_NOTIFY_DEVICEID      | OPT       | pNFS (OPT)  | Section 20.12 |
-NS*| CB_NOTIFY_LOCK          | OPT       |             | Section 20.11 |
-NS*| CB_PUSH_DELEG           | OPT       | FDELG (OPT) | Section 20.5  |
-   | CB_RECALL               | OPT       | FDELG,      | Section 20.2  |
-   |                         |           | DDELG, pNFS |               |
-   |                         |           | (REQ)       |               |
-NS*| CB_RECALL_ANY           | OPT       | FDELG,      | Section 20.6  |
-   |                         |           | DDELG, pNFS |               |
-   |                         |           | (REQ)       |               |
-NS | CB_RECALL_SLOT          | REQ       |             | Section 20.8  |
-NS*| CB_RECALLABLE_OBJ_AVAIL | OPT       | DDELG, pNFS | Section 20.7  |
-   |                         |           | (REQ)       |               |
-I  | CB_SEQUENCE             | OPT       | FDELG,      | Section 20.9  |
-   |                         |           | DDELG, pNFS |               |
-   |                         |           | (REQ)       |               |
-NS*| CB_WANTS_CANCELLED      | OPT       | FDELG,      | Section 20.10 |
-   |                         |           | DDELG, pNFS |               |
-   |                         |           | (REQ)       |               |
-   +-------------------------+-----------+-------------+---------------+
-
-Implementation notes:
-
-DELEGPURGE:
-* mandatory only for servers that support CLAIM_DELEGATE_PREV and/or
-  CLAIM_DELEG_PREV_FH (which allows clients to keep delegations that
-  persist across client reboots).  Thus we need not implement this for
-  now.
-
-EXCHANGE_ID:
-* only SP4_NONE state protection supported
-* implementation ids are ignored
-
-CREATE_SESSION:
-* backchannel attributes are ignored
-* backchannel security parameters are ignored
-
-SEQUENCE:
-* no support for dynamic slot table renegotiation (optional)
-
-nfsv4.1 COMPOUND rules:
-The following cases aren't supported yet:
-* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION,
-  DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID.
-* DESTROY_SESSION MUST be the final operation in the COMPOUND request.
-
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs-rdma.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs-rdma.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs-rdma.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs-rdma.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,271 +0,0 @@
-################################################################################
-#									       #
-#				NFS/RDMA README				       #
-#									       #
-################################################################################
-
- Author: NetApp and Open Grid Computing
- Date: May 29, 2008
-
-Table of Contents
-~~~~~~~~~~~~~~~~~
- - Overview
- - Getting Help
- - Installation
- - Check RDMA and NFS Setup
- - NFS/RDMA Setup
-
-Overview
-~~~~~~~~
-
-  This document describes how to install and setup the Linux NFS/RDMA client
-  and server software.
-
-  The NFS/RDMA client was first included in Linux 2.6.24. The NFS/RDMA server
-  was first included in the following release, Linux 2.6.25.
-
-  In our testing, we have obtained excellent performance results (full 10Gbit
-  wire bandwidth at minimal client CPU) under many workloads. The code passes
-  the full Connectathon test suite and operates over both Infiniband and iWARP
-  RDMA adapters.
-
-Getting Help
-~~~~~~~~~~~~
-
-  If you get stuck, you can ask questions on the
-
-                nfs-rdma-devel@lists.sourceforge.net
-
-  mailing list.
-
-Installation
-~~~~~~~~~~~~
-
-  These instructions are a step by step guide to building a machine for
-  use with NFS/RDMA.
-
-  - Install an RDMA device
-
-    Any device supported by the drivers in drivers/infiniband/hw is acceptable.
-
-    Testing has been performed using several Mellanox-based IB cards, the
-    Ammasso AMS1100 iWARP adapter, and the Chelsio cxgb3 iWARP adapter.
-
-  - Install a Linux distribution and tools
-
-    The first kernel release to contain both the NFS/RDMA client and server was
-    Linux 2.6.25  Therefore, a distribution compatible with this and subsequent
-    Linux kernel release should be installed.
-
-    The procedures described in this document have been tested with
-    distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
-
-  - Install nfs-utils-1.1.2 or greater on the client
-
-    An NFS/RDMA mount point can be obtained by using the mount.nfs command in
-    nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
-    version with support for NFS/RDMA mounts, but for various reasons we
-    recommend using nfs-utils-1.1.2 or greater). To see which version of
-    mount.nfs you are using, type:
-
-    $ /sbin/mount.nfs -V
-
-    If the version is less than 1.1.2 or the command does not exist,
-    you should install the latest version of nfs-utils.
-
-    Download the latest package from:
-
-    http://www.kernel.org/pub/linux/utils/nfs
-
-    Uncompress the package and follow the installation instructions.
-
-    If you will not need the idmapper and gssd executables (you do not need
-    these to create an NFS/RDMA enabled mount command), the installation
-    process can be simplified by disabling these features when running
-    configure:
-
-    $ ./configure --disable-gss --disable-nfsv4
-
-    To build nfs-utils you will need the tcp_wrappers package installed. For
-    more information on this see the package's README and INSTALL files.
-
-    After building the nfs-utils package, there will be a mount.nfs binary in
-    the utils/mount directory. This binary can be used to initiate NFS v2, v3,
-    or v4 mounts. To initiate a v4 mount, the binary must be called
-    mount.nfs4.  The standard technique is to create a symlink called
-    mount.nfs4 to mount.nfs.
-
-    This mount.nfs binary should be installed at /sbin/mount.nfs as follows:
-
-    $ sudo cp utils/mount/mount.nfs /sbin/mount.nfs
-
-    In this location, mount.nfs will be invoked automatically for NFS mounts
-    by the system mount command.
-
-    NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed
-    on the NFS client machine. You do not need this specific version of
-    nfs-utils on the server. Furthermore, only the mount.nfs command from
-    nfs-utils-1.1.2 is needed on the client.
-
-  - Install a Linux kernel with NFS/RDMA
-
-    The NFS/RDMA client and server are both included in the mainline Linux
-    kernel version 2.6.25 and later. This and other versions of the 2.6 Linux
-    kernel can be found at:
-
-    ftp://ftp.kernel.org/pub/linux/kernel/v2.6/
-
-    Download the sources and place them in an appropriate location.
-
-  - Configure the RDMA stack
-
-    Make sure your kernel configuration has RDMA support enabled. Under
-    Device Drivers -> InfiniBand support, update the kernel configuration
-    to enable InfiniBand support [NOTE: the option name is misleading. Enabling
-    InfiniBand support is required for all RDMA devices (IB, iWARP, etc.)].
-
-    Enable the appropriate IB HCA support (mlx4, mthca, ehca, ipath, etc.) or
-    iWARP adapter support (amso, cxgb3, etc.).
-
-    If you are using InfiniBand, be sure to enable IP-over-InfiniBand support.
-
-  - Configure the NFS client and server
-
-    Your kernel configuration must also have NFS file system support and/or
-    NFS server support enabled. These and other NFS related configuration
-    options can be found under File Systems -> Network File Systems.
-
-  - Build, install, reboot
-
-    The NFS/RDMA code will be enabled automatically if NFS and RDMA
-    are turned on. The NFS/RDMA client and server are configured via the hidden
-    SUNRPC_XPRT_RDMA config option that depends on SUNRPC and INFINIBAND. The
-    value of SUNRPC_XPRT_RDMA will be:
-
-     - N if either SUNRPC or INFINIBAND are N, in this case the NFS/RDMA client
-       and server will not be built
-     - M if both SUNRPC and INFINIBAND are on (M or Y) and at least one is M,
-       in this case the NFS/RDMA client and server will be built as modules
-     - Y if both SUNRPC and INFINIBAND are Y, in this case the NFS/RDMA client
-       and server will be built into the kernel
-
-    Therefore, if you have followed the steps above and turned no NFS and RDMA,
-    the NFS/RDMA client and server will be built.
-
-    Build a new kernel, install it, boot it.
-
-Check RDMA and NFS Setup
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-    Before configuring the NFS/RDMA software, it is a good idea to test
-    your new kernel to ensure that the kernel is working correctly.
-    In particular, it is a good idea to verify that the RDMA stack
-    is functioning as expected and standard NFS over TCP/IP and/or UDP/IP
-    is working properly.
-
-  - Check RDMA Setup
-
-    If you built the RDMA components as modules, load them at
-    this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
-    card:
-
-    $ modprobe ib_mthca
-    $ modprobe ib_ipoib
-
-    If you are using InfiniBand, make sure there is a Subnet Manager (SM)
-    running on the network. If your IB switch has an embedded SM, you can
-    use it. Otherwise, you will need to run an SM, such as OpenSM, on one
-    of your end nodes.
-
-    If an SM is running on your network, you should see the following:
-
-    $ cat /sys/class/infiniband/driverX/ports/1/state
-    4: ACTIVE
-
-    where driverX is mthca0, ipath5, ehca3, etc.
-
-    To further test the InfiniBand software stack, use IPoIB (this
-    assumes you have two IB hosts named host1 and host2):
-
-    host1$ ifconfig ib0 a.b.c.x
-    host2$ ifconfig ib0 a.b.c.y
-    host1$ ping a.b.c.y
-    host2$ ping a.b.c.x
-
-    For other device types, follow the appropriate procedures.
-
-  - Check NFS Setup
-
-    For the NFS components enabled above (client and/or server),
-    test their functionality over standard Ethernet using TCP/IP or UDP/IP.
-
-NFS/RDMA Setup
-~~~~~~~~~~~~~~
-
-  We recommend that you use two machines, one to act as the client and
-  one to act as the server.
-
-  One time configuration:
-
-  - On the server system, configure the /etc/exports file and
-    start the NFS/RDMA server.
-
-    Exports entries with the following formats have been tested:
-
-    /vol0   192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
-    /vol0   192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
-
-    The IP address(es) is(are) the client's IPoIB address for an InfiniBand
-    HCA or the cleint's iWARP address(es) for an RNIC.
-
-    NOTE: The "insecure" option must be used because the NFS/RDMA client does
-    not use a reserved port.
-
- Each time a machine boots:
-
-  - Load and configure the RDMA drivers
-
-    For InfiniBand using a Mellanox adapter:
-
-    $ modprobe ib_mthca
-    $ modprobe ib_ipoib
-    $ ifconfig ib0 a.b.c.d
-
-    NOTE: use unique addresses for the client and server
-
-  - Start the NFS server
-
-    If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
-    kernel config), load the RDMA transport module:
-
-    $ modprobe svcrdma
-
-    Regardless of how the server was built (module or built-in), start the
-    server:
-
-    $ /etc/init.d/nfs start
-
-    or
-
-    $ service nfs start
-
-    Instruct the server to listen on the RDMA transport:
-
-    $ echo rdma 20049 > /proc/fs/nfsd/portlist
-
-  - On the client system
-
-    If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
-    kernel config), load the RDMA client module:
-
-    $ modprobe xprtrdma.ko
-
-    Regardless of how the client was built (module or built-in), use this
-    command to mount the NFS/RDMA server:
-
-    $ mount -o rdma,port=20049 <IPoIB-server-name-or-address>:/<export> /mnt
-
-    To verify that the mount is using RDMA, run "cat /proc/mounts" and check
-    the "proto" field for the given mount.
-
-  Congratulations! You're using NFS/RDMA!
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfsroot.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfsroot.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfsroot.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfsroot.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,270 +0,0 @@
-Mounting the root filesystem via NFS (nfsroot)
-===============================================
-
-Written 1996 by Gero Kuhlmann <gero@gkminix.han.de>
-Updated 1997 by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
-Updated 2006 by Nico Schottelius <nico-kernel-nfsroot@schottelius.org>
-Updated 2006 by Horms <horms@verge.net.au>
-
-
-
-In order to use a diskless system, such as an X-terminal or printer server
-for example, it is necessary for the root filesystem to be present on a
-non-disk device. This may be an initramfs (see Documentation/filesystems/
-ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a
-filesystem mounted via NFS. The following text describes on how to use NFS
-for the root filesystem. For the rest of this text 'client' means the
-diskless system, and 'server' means the NFS server.
-
-
-
-
-1.) Enabling nfsroot capabilities
-    -----------------------------
-
-In order to use nfsroot, NFS client support needs to be selected as
-built-in during configuration. Once this has been selected, the nfsroot
-option will become available, which should also be selected.
-
-In the networking options, kernel level autoconfiguration can be selected,
-along with the types of autoconfiguration to support. Selecting all of
-DHCP, BOOTP and RARP is safe.
-
-
-
-
-2.) Kernel command line
-    -------------------
-
-When the kernel has been loaded by a boot loader (see below) it needs to be
-told what root fs device to use. And in the case of nfsroot, where to find
-both the server and the name of the directory on the server to mount as root.
-This can be established using the following kernel command line parameters:
-
-
-root=/dev/nfs
-
-  This is necessary to enable the pseudo-NFS-device. Note that it's not a
-  real device but just a synonym to tell the kernel to use NFS instead of
-  a real device.
-
-
-nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
-
-  If the `nfsroot' parameter is NOT given on the command line,
-  the default "/tftpboot/%s" will be used.
-
-  <server-ip>	Specifies the IP address of the NFS server.
-		The default address is determined by the `ip' parameter
-		(see below). This parameter allows the use of different
-		servers for IP autoconfiguration and NFS.
-
-  <root-dir>	Name of the directory on the server to mount as root.
-		If there is a "%s" token in the string, it will be
-		replaced by the ASCII-representation of the client's
-		IP address.
-
-  <nfs-options>	Standard NFS options. All options are separated by commas.
-		The following defaults are used:
-			port		= as given by server portmap daemon
-			rsize		= 4096
-			wsize		= 4096
-			timeo		= 7
-			retrans		= 3
-			acregmin	= 3
-			acregmax	= 60
-			acdirmin	= 30
-			acdirmax	= 60
-			flags		= hard, nointr, noposix, cto, ac
-
-
-ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>
-
-  This parameter tells the kernel how to configure IP addresses of devices
-  and also how to set up the IP routing table. It was originally called
-  `nfsaddrs', but now the boot-time IP configuration works independently of
-  NFS, so it was renamed to `ip' and the old name remained as an alias for
-  compatibility reasons.
-
-  If this parameter is missing from the kernel command line, all fields are
-  assumed to be empty, and the defaults mentioned below apply. In general
-  this means that the kernel tries to configure everything using
-  autoconfiguration.
-
-  The <autoconf> parameter can appear alone as the value to the `ip'
-  parameter (without all the ':' characters before).  If the value is
-  "ip=off" or "ip=none", no autoconfiguration will take place, otherwise
-  autoconfiguration will take place.  The most common way to use this
-  is "ip=dhcp".
-
-  <client-ip>	IP address of the client.
-
-  		Default:  Determined using autoconfiguration.
-
-  <server-ip>	IP address of the NFS server. If RARP is used to determine
-		the client address and this parameter is NOT empty only
-		replies from the specified server are accepted.
-
-		Only required for NFS root. That is autoconfiguration
-		will not be triggered if it is missing and NFS root is not
-		in operation.
-
-		Default: Determined using autoconfiguration.
-		         The address of the autoconfiguration server is used.
-
-  <gw-ip>	IP address of a gateway if the server is on a different subnet.
-
-		Default: Determined using autoconfiguration.
-
-  <netmask>	Netmask for local network interface. If unspecified
-		the netmask is derived from the client IP address assuming
-		classful addressing.
-
-		Default:  Determined using autoconfiguration.
-
-  <hostname>	Name of the client. May be supplied by autoconfiguration,
-  		but its absence will not trigger autoconfiguration.
-
-  		Default: Client IP address is used in ASCII notation.
-
-  <device>	Name of network device to use.
-
-		Default: If the host only has one device, it is used.
-			 Otherwise the device is determined using
-			 autoconfiguration. This is done by sending
-			 autoconfiguration requests out of all devices,
-			 and using the device that received the first reply.
-
-  <autoconf>	Method to use for autoconfiguration. In the case of options
-                which specify multiple autoconfiguration protocols,
-		requests are sent using all protocols, and the first one
-		to reply is used.
-
-		Only autoconfiguration protocols that have been compiled
-		into the kernel will be used, regardless of the value of
-		this option.
-
-                  off or none: don't use autoconfiguration
-				(do static IP assignment instead)
-		  on or any:   use any protocol available in the kernel
-			       (default)
-		  dhcp:        use DHCP
-		  bootp:       use BOOTP
-		  rarp:        use RARP
-		  both:        use both BOOTP and RARP but not DHCP
-		               (old option kept for backwards compatibility)
-
-                Default: any
-
-
-
-
-3.) Boot Loader
-    ----------
-
-To get the kernel into memory different approaches can be used.
-They depend on various facilities being available:
-
-
-3.1)  Booting from a floppy using syslinux
-
-	When building kernels, an easy way to create a boot floppy that uses
-	syslinux is to use the zdisk or bzdisk make targets which use zimage
-      	and bzimage images respectively. Both targets accept the
-     	FDARGS parameter which can be used to set the kernel command line.
-
-	e.g.
-	   make bzdisk FDARGS="root=/dev/nfs"
-
-   	Note that the user running this command will need to have
-     	access to the floppy drive device, /dev/fd0
-
-     	For more information on syslinux, including how to create bootdisks
-     	for prebuilt kernels, see http://syslinux.zytor.com/
-
-	N.B: Previously it was possible to write a kernel directly to
-	     a floppy using dd, configure the boot device using rdev, and
-	     boot using the resulting floppy. Linux no longer supports this
-	     method of booting.
-
-3.2) Booting from a cdrom using isolinux
-
-     	When building kernels, an easy way to create a bootable cdrom that
-     	uses isolinux is to use the isoimage target which uses a bzimage
-     	image. Like zdisk and bzdisk, this target accepts the FDARGS
-     	parameter which can be used to set the kernel command line.
-
-	e.g.
-	  make isoimage FDARGS="root=/dev/nfs"
-
-     	The resulting iso image will be arch/<ARCH>/boot/image.iso
-     	This can be written to a cdrom using a variety of tools including
-     	cdrecord.
-
-	e.g.
-	  cdrecord dev=ATAPI:1,0,0 arch/i386/boot/image.iso
-
-     	For more information on isolinux, including how to create bootdisks
-     	for prebuilt kernels, see http://syslinux.zytor.com/
-
-3.2) Using LILO
-	When using LILO all the necessary command line parameters may be
-	specified using the 'append=' directive in the LILO configuration
-	file.
-
-	However, to use the 'root=' directive you also need to create
-	a dummy root device, which may be removed after LILO is run.
-
-	mknod /dev/boot255 c 0 255
-
-	For information on configuring LILO, please refer to its documentation.
-
-3.3) Using GRUB
-	When using GRUB, kernel parameter are simply appended after the kernel
-	specification: kernel <kernel> <parameters>
-
-3.4) Using loadlin
-	loadlin may be used to boot Linux from a DOS command prompt without
-	requiring a local hard disk to mount as root. This has not been
-	thoroughly tested by the authors of this document, but in general
-	it should be possible configure the kernel command line similarly
-	to the configuration of LILO.
-
-	Please refer to the loadlin documentation for further information.
-
-3.5) Using a boot ROM
-	This is probably the most elegant way of booting a diskless client.
-	With a boot ROM the kernel is loaded using the TFTP protocol. The
-	authors of this document are not aware of any no commercial boot
-	ROMs that support booting Linux over the network. However, there
-	are two free implementations of a boot ROM, netboot-nfs and
-	etherboot, both of which are available on sunsite.unc.edu, and both
-	of which contain everything you need to boot a diskless Linux client.
-
-3.6) Using pxelinux
-	Pxelinux may be used to boot linux using the PXE boot loader
-	which is present on many modern network cards.
-
-	When using pxelinux, the kernel image is specified using
-	"kernel <relative-path-below /tftpboot>". The nfsroot parameters
-	are passed to the kernel by adding them to the "append" line.
-	It is common to use serial console in conjunction with pxeliunx,
-	see Documentation/serial-console.txt for more information.
-
-	For more information on isolinux, including how to create bootdisks
-	for prebuilt kernels, see http://syslinux.zytor.com/
-
-
-
-
-4.) Credits
-    -------
-
-  The nfsroot code in the kernel and the RARP support have been written
-  by Gero Kuhlmann <gero@gkminix.han.de>.
-
-  The rest of the IP layer autoconfiguration code has been written
-  by Martin Mares <mj@atrey.karlin.mff.cuni.cz>.
-
-  In order to write the initial version of nfsroot I would like to thank
-  Jens-Uwe Mager <jum@anubis.han.de> for his help.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nfs.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nfs.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,98 +0,0 @@
-
-The NFS client
-==============
-
-The NFS version 2 protocol was first documented in RFC1094 (March 1989).
-Since then two more major releases of NFS have been published, with NFSv3
-being documented in RFC1813 (June 1995), and NFSv4 in RFC3530 (April
-2003).
-
-The Linux NFS client currently supports all the above published versions,
-and work is in progress on adding support for minor version 1 of the NFSv4
-protocol.
-
-The purpose of this document is to provide information on some of the
-upcall interfaces that are used in order to provide the NFS client with
-some of the information that it requires in order to fully comply with
-the NFS spec.
-
-The DNS resolver
-================
-
-NFSv4 allows for one server to refer the NFS client to data that has been
-migrated onto another server by means of the special "fs_locations"
-attribute. See
-	http://tools.ietf.org/html/rfc3530#section-6
-and
-	http://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00
-
-The fs_locations information can take the form of either an ip address and
-a path, or a DNS hostname and a path. The latter requires the NFS client to
-do a DNS lookup in order to mount the new volume, and hence the need for an
-upcall to allow userland to provide this service.
-
-Assuming that the user has the 'rpc_pipefs' filesystem mounted in the usual
-/var/lib/nfs/rpc_pipefs, the upcall consists of the following steps:
-
-   (1) The process checks the dns_resolve cache to see if it contains a
-       valid entry. If so, it returns that entry and exits.
-
-   (2) If no valid entry exists, the helper script '/sbin/nfs_cache_getent'
-       (may be changed using the 'nfs.cache_getent' kernel boot parameter)
-       is run, with two arguments:
-		- the cache name, "dns_resolve"
-		- the hostname to resolve
-
-   (3) After looking up the corresponding ip address, the helper script
-       writes the result into the rpc_pipefs pseudo-file
-       '/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel'
-       in the following (text) format:
-
-		"<ip address> <hostname> <ttl>\n"
-
-       Where <ip address> is in the usual IPv4 (123.456.78.90) or IPv6
-       (ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) format.
-       <hostname> is identical to the second argument of the helper
-       script, and <ttl> is the 'time to live' of this cache entry (in
-       units of seconds).
-
-       Note: If <ip address> is invalid, say the string "0", then a negative
-       entry is created, which will cause the kernel to treat the hostname
-       as having no valid DNS translation.
-
-
-
-
-A basic sample /sbin/nfs_cache_getent
-=====================================
-
-#!/bin/bash
-#
-ttl=600
-#
-cut=/usr/bin/cut
-getent=/usr/bin/getent
-rpc_pipefs=/var/lib/nfs/rpc_pipefs
-#
-die()
-{
-	echo "Usage: $0 cache_name entry_name"
-	exit 1
-}
-
-[ $# -lt 2 ] && die
-cachename="$1"
-cache_path=${rpc_pipefs}/cache/${cachename}/channel
-
-case "${cachename}" in
-	dns_resolve)
-		name="$2"
-		result="$(${getent} hosts ${name} | ${cut} -f1 -d\ )"
-		[ -z "${result}" ] && result="0"
-		;;
-	*)
-		die
-		;;
-esac
-echo "${result} ${name} ${ttl}" >${cache_path}
-
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/nilfs2.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/nilfs2.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/nilfs2.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/nilfs2.txt	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ described in the man pages included in t
 Project web page:    http://www.nilfs.org/en/
 Download page:       http://www.nilfs.org/en/download.html
 Git tree web page:   http://www.nilfs.org/git/
-NILFS mailing lists: http://www.nilfs.org/mailman/listinfo/users
+List info:           http://vger.kernel.org/vger-lists.html#linux-nilfs
 
 Caveats
 =======
@@ -49,8 +49,7 @@ Mount options
 NILFS2 supports the following mount options:
 (*) == default
 
-barrier=on(*)		This enables/disables barriers. barrier=off disables
-			it, barrier=on enables it.
+nobarrier		Disables barriers.
 errors=continue(*)	Keep going on a filesystem error.
 errors=remount-ro	Remount the filesystem read-only on an error.
 errors=panic		Panic and halt the machine if an error occurs.
@@ -71,6 +70,10 @@ order=strict		Apply strict in-order sema
 			blocks.  That means, it is guaranteed that no
 			overtaking of events occurs in the recovered file
 			system after a crash.
+norecovery		Disable recovery of the filesystem on mount.
+			This disables every write access on the device for
+			read-only mounts or snapshots.  This option will fail
+			for r/w mounts on an unclean volume.
 
 NILFS2 usage
 ============
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/porting linux-libre-2.6.33-gnu1/Documentation/filesystems/porting
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/porting	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/porting	2010-02-24 13:52:17.000000000 -0500
@@ -140,7 +140,7 @@ Callers of notify_change() need ->i_mute
 New super_block field "struct export_operations *s_export_op" for
 explicit support for exporting, e.g. via NFS.  The structure is fully
 documented at its declaration in include/linux/fs.h, and in
-Documentation/filesystems/Exporting.
+Documentation/filesystems/nfs/Exporting.
 
 Briefly it allows for the definition of decode_fh and encode_fh operations
 to encode and decode filehandles, and allows the filesystem to use
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/proc.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/proc.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/proc.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/proc.txt	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,7 @@ Table of Contents
   3.3	/proc/<pid>/io - Display the IO accounting fields
   3.4	/proc/<pid>/coredump_filter - Core dump filtering settings
   3.5	/proc/<pid>/mountinfo - Information about mounts
+  3.6	/proc/<pid>/comm  & /proc/<pid>/task/<tid>/comm
 
 
 ------------------------------------------------------------------------------
@@ -176,7 +177,6 @@ read the file /proc/PID/status:
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
-  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -230,7 +230,6 @@ Table 1-2: Contents of the statm files (
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
- Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -1072,7 +1071,8 @@ second).  The meanings of the columns ar
 - irq: servicing interrupts
 - softirq: servicing softirqs
 - steal: involuntary wait
-- guest: running a guest
+- guest: running a normal guest
+- guest_nice: running a niced guest
 
 The "intr" line gives counts of interrupts  serviced since boot time, for each
 of the  possible system interrupts.   The first  column  is the  total of  all
@@ -1088,8 +1088,8 @@ The "processes" line gives the number  o
 includes (but  is not limited  to) those  created by  calls to the  fork() and
 clone() system calls.
 
-The  "procs_running" line gives the  number of processes  currently running on
-CPUs.
+The "procs_running" line gives the total number of threads that are
+running or ready to run (i.e., the total number of runnable threads).
 
 The   "procs_blocked" line gives  the  number of  processes currently blocked,
 waiting for I/O to complete.
@@ -1408,3 +1408,11 @@ For more information on mount propagatio
 
   Documentation/filesystems/sharedsubtree.txt
 
+
+3.6	/proc/<pid>/comm  & /proc/<pid>/task/<tid>/comm
+--------------------------------------------------------
+These files provide a method to access a tasks comm value. It also allows for
+a task to set its own or one of its thread siblings comm value. The comm value
+is limited in size compared to the cmdline value, so writing anything longer
+then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
+comm value.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/rpc-cache.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/rpc-cache.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/rpc-cache.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/rpc-cache.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-	This document gives a brief introduction to the caching
-mechanisms in the sunrpc layer that is used, in particular,
-for NFS authentication.
-
-CACHES
-======
-The caching replaces the old exports table and allows for
-a wide variety of values to be caches.
-
-There are a number of caches that are similar in structure though
-quite possibly very different in content and use.  There is a corpus
-of common code for managing these caches.
-
-Examples of caches that are likely to be needed are:
-  - mapping from IP address to client name
-  - mapping from client name and filesystem to export options
-  - mapping from UID to list of GIDs, to work around NFS's limitation
-    of 16 gids.
-  - mappings between local UID/GID and remote UID/GID for sites that
-    do not have uniform uid assignment
-  - mapping from network identify to public key for crypto authentication.
-
-The common code handles such things as:
-   - general cache lookup with correct locking
-   - supporting 'NEGATIVE' as well as positive entries
-   - allowing an EXPIRED time on cache items, and removing
-     items after they expire, and are no longer in-use.
-   - making requests to user-space to fill in cache entries
-   - allowing user-space to directly set entries in the cache
-   - delaying RPC requests that depend on as-yet incomplete
-     cache entries, and replaying those requests when the cache entry
-     is complete.
-   - clean out old entries as they expire.
-
-Creating a Cache
-----------------
-
-1/ A cache needs a datum to store.  This is in the form of a
-   structure definition that must contain a
-     struct cache_head
-   as an element, usually the first.
-   It will also contain a key and some content.
-   Each cache element is reference counted and contains
-   expiry and update times for use in cache management.
-2/ A cache needs a "cache_detail" structure that
-   describes the cache.  This stores the hash table, some
-   parameters for cache management, and some operations detailing how
-   to work with particular cache items.
-   The operations requires are:
-   	struct cache_head *alloc(void)
-		This simply allocates appropriate memory and returns
-   		a pointer to the cache_detail embedded within the
-		structure
-	void cache_put(struct kref *)
-		This is called when the last reference to an item is
-		dropped.  The pointer passed is to the 'ref' field
-		in the cache_head.  cache_put should release any
-		references create by 'cache_init' and, if CACHE_VALID
-		is set, any references created by cache_update.
-		It should then release the memory allocated by
-   		'alloc'.
-        int match(struct cache_head *orig, struct cache_head *new)
-		test if the keys in the two structures match.  Return
-		1 if they do, 0 if they don't.
-	void init(struct cache_head *orig, struct cache_head *new)
-		Set the 'key' fields in 'new' from 'orig'.  This may
-		include taking references to shared objects.
-	void update(struct cache_head *orig, struct cache_head *new)
-		Set the 'content' fileds in 'new' from 'orig'.
-	int cache_show(struct seq_file *m, struct cache_detail *cd,
-			struct cache_head *h)
-		Optional.  Used to provide a /proc file that lists the
-		contents of a cache.  This should show one item,
-   		usually on just one line.
-	int cache_request(struct cache_detail *cd, struct cache_head *h,
-   		char **bpp, int *blen)
-		Format a request to be send to user-space for an item
-   		to be instantiated.  *bpp is a buffer of size *blen.
-		bpp should be moved forward over the encoded message,
-		and  *blen should be reduced to show how much free
-		space remains.  Return 0 on success or <0 if not
-		enough room or other problem.
-	int cache_parse(struct cache_detail *cd, char *buf, int len)
-		A message from user space has arrived to fill out a
-		cache entry.  It is in 'buf' of length 'len'.
-		cache_parse should parse this, find the item in the
-		cache with sunrpc_cache_lookup, and update the item
-		with sunrpc_cache_update.
-
-
-3/ A cache needs to be registered using cache_register().  This
-   includes it on a list of caches that will be regularly
-   cleaned to discard old data.
-
-Using a cache
--------------
-
-To find a value in a cache, call sunrpc_cache_lookup passing a pointer
-to the cache_head in a sample item with the 'key' fields filled in.
-This will be passed to ->match to identify the target entry.  If no
-entry is found, a new entry will be create, added to the cache, and
-marked as not containing valid data.
-
-The item returned is typically passed to cache_check which will check
-if the data is valid, and may initiate an up-call to get fresh data.
-cache_check will return -ENOENT in the entry is negative or if an up
-call is needed but not possible, -EAGAIN if an upcall is pending,
-or 0 if the data is valid;
-
-cache_check can be passed a "struct cache_req *".  This structure is
-typically embedded in the actual request and can be used to create a
-deferred copy of the request (struct cache_deferred_req).  This is
-done when the found cache item is not uptodate, but the is reason to
-believe that userspace might provide information soon.  When the cache
-item does become valid, the deferred copy of the request will be
-revisited (->revisit).  It is expected that this method will
-reschedule the request for processing.
-
-The value returned by sunrpc_cache_lookup can also be passed to
-sunrpc_cache_update to set the content for the item.  A second item is
-passed which should hold the content.  If the item found by _lookup
-has valid data, then it is discarded and a new item is created.  This
-saves any user of an item from worrying about content changing while
-it is being inspected.  If the item found by _lookup does not contain
-valid data, then the content is copied across and CACHE_VALID is set.
-
-Populating a cache
-------------------
-
-Each cache has a name, and when the cache is registered, a directory
-with that name is created in /proc/net/rpc
-
-This directory contains a file called 'channel' which is a channel
-for communicating between kernel and user for populating the cache.
-This directory may later contain other files of interacting
-with the cache.
-
-The 'channel' works a bit like a datagram socket. Each 'write' is
-passed as a whole to the cache for parsing and interpretation.
-Each cache can treat the write requests differently, but it is
-expected that a message written will contain:
-  - a key
-  - an expiry time
-  - a content.
-with the intention that an item in the cache with the give key
-should be create or updated to have the given content, and the
-expiry time should be set on that item.
-
-Reading from a channel is a bit more interesting.  When a cache
-lookup fails, or when it succeeds but finds an entry that may soon
-expire, a request is lodged for that cache item to be updated by
-user-space.  These requests appear in the channel file.
-
-Successive reads will return successive requests.
-If there are no more requests to return, read will return EOF, but a
-select or poll for read will block waiting for another request to be
-added.
-
-Thus a user-space helper is likely to:
-  open the channel.
-    select for readable
-    read a request
-    write a response
-  loop.
-
-If it dies and needs to be restarted, any requests that have not been
-answered will still appear in the file and will be read by the new
-instance of the helper.
-
-Each cache should define a "cache_parse" method which takes a message
-written from user-space and processes it.  It should return an error
-(which propagates back to the write syscall) or 0.
-
-Each cache should also define a "cache_request" method which
-takes a cache item and encodes a request into the buffer
-provided.
-
-Note: If a cache has no active readers on the channel, and has had not
-active readers for more than 60 seconds, further requests will not be
-added to the channel but instead all lookups that do not find a valid
-entry will fail.  This is partly for backward compatibility: The
-previous nfs exports table was deemed to be authoritative and a
-failed lookup meant a definite 'no'.
-
-request/response format
------------------------
-
-While each cache is free to use it's own format for requests
-and responses over channel, the following is recommended as
-appropriate and support routines are available to help:
-Each request or response record should be printable ASCII
-with precisely one newline character which should be at the end.
-Fields within the record should be separated by spaces, normally one.
-If spaces, newlines, or nul characters are needed in a field they
-much be quoted.  two mechanisms are available:
-1/ If a field begins '\x' then it must contain an even number of
-   hex digits, and pairs of these digits provide the bytes in the
-   field.
-2/ otherwise a \ in the field must be followed by 3 octal digits
-   which give the code for a byte.  Other characters are treated
-   as them selves.  At the very least, space, newline, nul, and
-   '\' must be quoted in this way.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/seq_file.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/seq_file.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/seq_file.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/seq_file.txt	2010-02-24 13:52:17.000000000 -0500
@@ -248,9 +248,7 @@ code, that is done in the initialization
 	{
 	        struct proc_dir_entry *entry;
 
-	        entry = create_proc_entry("sequence", 0, NULL);
-	        if (entry)
-	                entry->proc_fops = &ct_file_ops;
+	        proc_create("sequence", 0, NULL, &ct_file_ops);
 	        return 0;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/sysfs.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/sysfs.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/sysfs.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/sysfs.txt	2010-02-24 13:52:17.000000000 -0500
@@ -91,8 +91,8 @@ struct device_attribute {
 			 const char *buf, size_t count);
 };
 
-int device_create_file(struct device *, struct device_attribute *);
-void device_remove_file(struct device *, struct device_attribute *);
+int device_create_file(struct device *, const struct device_attribute *);
+void device_remove_file(struct device *, const struct device_attribute *);
 
 It also defines this helper for defining device attributes: 
 
@@ -316,8 +316,8 @@ DEVICE_ATTR(_name, _mode, _show, _store)
 
 Creation/Removal:
 
-int device_create_file(struct device *device, struct device_attribute * attr);
-void device_remove_file(struct device * dev, struct device_attribute * attr);
+int device_create_file(struct device *dev, const struct device_attribute * attr);
+void device_remove_file(struct device *dev, const struct device_attribute * attr);
 
 
 - bus drivers (include/linux/device.h)
@@ -358,7 +358,7 @@ DRIVER_ATTR(_name, _mode, _show, _store)
 
 Creation/Removal:
 
-int driver_create_file(struct device_driver *, struct driver_attribute *);
-void driver_remove_file(struct device_driver *, struct driver_attribute *);
+int driver_create_file(struct device_driver *, const struct driver_attribute *);
+void driver_remove_file(struct device_driver *, const struct driver_attribute *);
 
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/filesystems/vfs.txt linux-libre-2.6.33-gnu1/Documentation/filesystems/vfs.txt
--- linux-libre-2.6.32-gnu1/Documentation/filesystems/vfs.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/filesystems/vfs.txt	2010-02-24 13:52:17.000000000 -0500
@@ -472,7 +472,7 @@ __sync_single_inode) to check if ->write
 writing out the whole address_space.
 
 The Writeback tag is used by filemap*wait* and sync_page* functions,
-via wait_on_page_writeback_range, to wait for all writeback to
+via filemap_fdatawait_range, to wait for all writeback to
 complete.  While waiting ->sync_page (if defined) will be called on
 each page that is found to require writeback.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/gpio.txt linux-libre-2.6.33-gnu1/Documentation/gpio.txt
--- linux-libre-2.6.32-gnu1/Documentation/gpio.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/gpio.txt	2010-02-24 13:52:17.000000000 -0500
@@ -380,7 +380,7 @@ rare; use gpiochip_remove() when it is u
 
 Most often a gpio_chip is part of an instance-specific structure with state
 not exposed by the GPIO interfaces, such as addressing, power management,
-and more.  Chips such as codecs will have complex non-GPIO state,
+and more.  Chips such as codecs will have complex non-GPIO state.
 
 Any debugfs dump method should normally ignore signals which haven't been
 requested as GPIOs.  They can use gpiochip_is_requested(), which returns
@@ -531,7 +531,14 @@ and have the following read/write attrib
 		This file exists only if the pin can be configured as an
 		interrupt generating input pin.
 
-GPIO controllers have paths like /sys/class/gpio/chipchip42/ (for the
+	"active_low" ... reads as either 0 (false) or 1 (true).  Write
+		any nonzero value to invert the value attribute both
+		for reading and writing.  Existing and subsequent
+		poll(2) support configuration via the edge attribute
+		for "rising" and "falling" edges will follow this
+		setting.
+
+GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
 controller implementing GPIOs starting at #42) and have the following
 read-only attributes:
 
@@ -566,6 +573,8 @@ requested using gpio_request():
 	int gpio_export_link(struct device *dev, const char *name,
 		unsigned gpio)
 
+	/* change the polarity of a GPIO node in sysfs */
+	int gpio_sysfs_set_active_low(unsigned gpio, int value);
 
 After a kernel driver requests a GPIO, it may only be made available in
 the sysfs interface by gpio_export().  The driver can control whether the
@@ -580,3 +589,9 @@ After the GPIO has been exported, gpio_e
 symlinks from elsewhere in sysfs to the GPIO sysfs node.  Drivers can
 use this to provide the interface under their own device in sysfs with
 a descriptive name.
+
+Drivers can use gpio_sysfs_set_active_low() to hide GPIO line polarity
+differences between boards from user space.  This only affects the
+sysfs interface.  Polarity change can be done both before and after
+gpio_export(), and previously enabled poll(2) support for either
+rising or falling edge will be reconfigured to follow this setting.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/adt7473 linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7473
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/adt7473	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7473	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,8 @@ Supported chips:
 
 Author: Darrick J. Wong
 
+This driver is depreacted, please use the adt7475 driver instead.
+
 Description
 -----------
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/adt7475 linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7475
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/adt7475	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/adt7475	2010-02-24 13:52:17.000000000 -0500
@@ -1,87 +1,117 @@
-This describes the interface for the ADT7475 driver:
-
-(there are 4 fans, numbered fan1 to fan4):
-
-fanX_input		Read the current speed of the fan (in RPMs)
-fanX_min		Read/write the minimum speed of the fan.  Dropping
-			below this sets an alarm.
-
-(there are three PWMs, numbered pwm1 to pwm3):
+Kernel driver adt7475
+=====================
 
-pwmX			Read/write the current duty cycle of the PWM.  Writes
-			only have effect when auto mode is turned off (see
-			below).  Range is 0 - 255.
+Supported chips:
+  * Analog Devices ADT7473
+    Prefix: 'adt7473'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7475
+    Prefix: 'adt7475'
+    Addresses scanned: I2C 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7476
+    Prefix: 'adt7476'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
+  * Analog Devices ADT7490
+    Prefix: 'adt7490'
+    Addresses scanned: I2C 0x2C, 0x2D, 0x2E
+    Datasheet: Publicly available at the On Semiconductors website
 
-pwmX_enable		Fan speed control method:
+Authors:
+	Jordan Crouse
+	Hans de Goede
+	Darrick J. Wong (documentation)
+	Jean Delvare
 
-			0 - No control (fan at full speed)
-			1 - Manual fan speed control (using pwm[1-*])
-			2 - Automatic fan speed control
 
-pwmX_auto_channels_temp	Select which channels affect this PWM
+Description
+-----------
 
-			1 - TEMP1 controls PWM
-			2 - TEMP2 controls PWM
-			4 - TEMP3 controls PWM
-			6 - TEMP2 and TEMP3 control PWM
-			7 - All three inputs control PWM
+This driver implements support for the Analog Devices ADT7473, ADT7475,
+ADT7476 and ADT7490 chip family. The ADT7473 and ADT7475 differ only in
+minor details. The ADT7476 has additional features, including extra voltage
+measurement inputs and VID support. The ADT7490 also has additional
+features, including extra voltage measurement inputs and PECI support. All
+the supported chips will be collectively designed by the name "ADT747x" in
+the rest of this document.
 
-pwmX_freq		Read/write the PWM frequency in Hz. The number
-			should be one of the following:
+The ADT747x uses the 2-wire interface compatible with the SMBus 2.0
+specification. Using an analog to digital converter it measures three (3)
+temperatures and two (2) or more voltages. It has four (4) 16-bit counters
+for measuring fan speed. There are three (3) PWM outputs that can be used
+to control fan speed.
 
-			11 Hz
-			14 Hz
-			22 Hz
-			29 Hz
-			35 Hz
-			44 Hz
-			58 Hz
-			88 Hz
+A sophisticated control system for the PWM outputs is designed into the
+ADT747x that allows fan speed to be adjusted automatically based on any of the
+three temperature sensors. Each PWM output is individually adjustable and
+programmable. Once configured, the ADT747x will adjust the PWM outputs in
+response to the measured temperatures without further host intervention.
+This feature can also be disabled for manual control of the PWM's.
 
-pwmX_auto_point1_pwm	Read/write the minimum PWM duty cycle in automatic mode
+Each of the measured inputs (voltage, temperature, fan speed) has
+corresponding high/low limit values. The ADT747x will signal an ALARM if
+any measured value exceeds either limit.
 
-pwmX_auto_point2_pwm	Read/write the maximum PWM duty cycle in automatic mode
+The ADT747x samples all inputs continuously. The driver will not read
+the registers more often than once every other second. Further,
+configuration data is only read once per minute.
 
-(there are three temperature settings numbered temp1 to temp3):
+Chip Differences Summary
+------------------------
 
-tempX_input		Read the current temperature.  The value is in milli
-			degrees of Celsius.
+ADT7473:
+  * 2 voltage inputs
+  * system acoustics optimizations (not implemented)
 
-tempX_max		Read/write the upper temperature limit - exceeding this
-			will cause an alarm.
+ADT7475:
+  * 2 voltage inputs
 
-tempX_min		Read/write the lower temperature limit - exceeding this
-			will cause an alarm.
+ADT7476:
+  * 5 voltage inputs
+  * VID support
 
-tempX_offset		Read/write the temperature adjustment offset
+ADT7490:
+  * 6 voltage inputs
+  * 1 Imon input (not implemented)
+  * PECI support (not implemented)
+  * 2 GPIO pins (not implemented)
+  * system acoustics optimizations (not implemented)
 
-tempX_crit		Read/write the THERM limit for remote1.
+Special Features
+----------------
 
-tempX_crit_hyst		Set the temperature value below crit where the
-			fans will stay on - this helps drive the temperature
-			low enough so it doesn't stay near the edge and
-			cause THERM to keep tripping.
+The ADT747x has a 10-bit ADC and can therefore measure temperatures
+with a resolution of 0.25 degree Celsius. Temperature readings can be
+configured either for two's complement format or "Offset 64" format,
+wherein 64 is subtracted from the raw value to get the temperature value.
 
-tempX_auto_point1_temp	Read/write the minimum temperature where the fans will
-			turn on in automatic mode.
+The datasheet is very detailed and describes a procedure for determining
+an optimal configuration for the automatic PWM control.
 
-tempX_auto_point2_temp	Read/write the maximum temperature over which the fans
-			will run in automatic mode.  tempX_auto_point1_temp
-			and tempX_auto_point2_temp together define the
-			range of automatic control.
+Fan Speed Control
+-----------------
 
-tempX_alarm		Read a 1 if the max/min alarm is set
-tempX_fault		Read a 1 if either temp1 or temp3 diode has a fault
+The driver exposes two trip points per PWM channel.
 
-(There are two voltage settings, in1 and in2):
+point1: Set the PWM speed at the lower temperature bound
+point2: Set the PWM speed at the higher temperature bound
 
-inX_input		Read the current voltage on VCC.  Value is in
-			millivolts.
+The ADT747x will scale the PWM linearly between the lower and higher PWM
+speed when the temperature is between the two temperature boundaries.
+Temperature boundaries are associated to temperature channels rather than
+PWM outputs, and a given PWM output can be controlled by several temperature
+channels. As a result, the ADT747x may compute more than one PWM value
+for a channel at a given time, in which case the maximum value (fastest
+fan speed) is applied. PWM values range from 0 (off) to 255 (full speed).
 
-inX_min			read/write the minimum voltage limit.
-			Dropping below this causes an alarm.
+Fan speed may be set to maximum when the temperature sensor associated with
+the PWM control exceeds temp#_max.
 
-inX_max			read/write the maximum voltage limit.
-			Exceeding this causes an alarm.
+Notes
+-----
 
-inX_alarm		Read a 1 if the max/min alarm is set.
+The nVidia binary driver presents an ADT7473 chip via an on-card i2c bus.
+Unfortunately, they fail to set the i2c adapter class, so this driver may
+fail to find the chip until the nvidia driver is patched.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/amc6821 linux-libre-2.6.33-gnu1/Documentation/hwmon/amc6821
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/amc6821	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/amc6821	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+Kernel driver amc6821
+=====================
+
+Supported chips:
+	Texas Instruments AMC6821
+	Prefix: 'amc6821'
+	Addresses scanned: 0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, 0x4c, 0x4d, 0x4e
+	Datasheet: http://focus.ti.com/docs/prod/folders/print/amc6821.html
+
+Authors:
+	Tomaz Mertelj <tomaz.mertelj@guest.arnes.si>
+
+
+Description
+-----------
+
+This driver implements support for the Texas Instruments amc6821 chip.
+The chip has one on-chip and one remote temperature sensor and one pwm fan
+regulator.
+The pwm can be controlled either from software or automatically.
+
+The driver provides the following sensor accesses in sysfs:
+
+temp1_input		ro	on-chip temperature
+temp1_min		rw	"
+temp1_max		rw	"
+temp1_crit	 	rw	"
+temp1_min_alarm		ro	"
+temp1_max_alarm		ro	"
+temp1_crit_alarm	ro	"
+
+temp2_input		ro	remote temperature
+temp2_min		rw	"
+temp2_max		rw	"
+temp2_crit	 	rw	"
+temp2_min_alarm		ro	"
+temp2_max_alarm		ro	"
+temp2_crit_alarm	ro	"
+temp2_fault		ro	"
+
+fan1_input	 	ro	tachometer speed
+fan1_min		rw	"
+fan1_max		rw	"
+fan1_fault	 	ro	"
+fan1_div		rw	Fan divisor can be either 2 or 4.
+
+pwm1			rw	pwm1
+pwm1_enable		rw	regulator mode, 1=open loop, 2=fan controlled
+				by remote temperature, 3=fan controlled by
+				combination of the on-chip temperature and
+				remote-sensor temperature,
+pwm1_auto_channels_temp ro	1 if pwm_enable==2, 3 if pwm_enable==3
+pwm1_auto_point1_pwm	ro	Hardwired to 0, shared for both
+				temperature channels.
+pwm1_auto_point2_pwm	rw	This value is shared for both temperature
+				channels.
+pwm1_auto_point3_pwm	rw	Hardwired to 255, shared for both
+				temperature channels.
+
+temp1_auto_point1_temp	ro	Hardwired to temp2_auto_point1_temp
+				which is rw. Below this temperature fan stops.
+temp1_auto_point2_temp	rw	The low-temperature limit of the proportional
+				range. Below this temperature
+				pwm1 = pwm1_auto_point2_pwm. It can go from
+				0 degree C to 124 degree C in steps of
+				4 degree C. Read it out after writing to get
+				the actual value.
+temp1_auto_point3_temp	rw	Above this temperature fan runs at maximum
+				speed. It can go from temp1_auto_point2_temp.
+				It can only have certain discrete values
+				which depend on temp1_auto_point2_temp and
+				pwm1_auto_point2_pwm. Read it out after
+				writing to get the actual value.
+
+temp2_auto_point1_temp	rw	Must be between 0 degree C and 63 degree C and
+				it defines the passive cooling temperature.
+				Below this temperature the fan stops in
+				the closed loop mode.
+temp2_auto_point2_temp	rw	The low-temperature limit of the proportional
+				range. Below this temperature
+				pwm1 = pwm1_auto_point2_pwm. It can go from
+				0 degree C to 124 degree C in steps
+				of 4 degree C.
+
+temp2_auto_point3_temp	rw	Above this temperature fan runs at maximum
+				speed. It can only have certain discrete
+				values which depend on temp2_auto_point2_temp
+				and pwm1_auto_point2_pwm. Read it out after
+				writing to get actual value.
+
+
+Module parameters
+-----------------
+
+If your board has a BIOS that initializes the amc6821 correctly, you should
+load the module with: init=0.
+
+If your board BIOS doesn't initialize the chip, or you want
+different settings, you can set the following parameters:
+init=1,
+pwminv: 0 default pwm output, 1 inverts pwm output.
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/f71882fg linux-libre-2.6.33-gnu1/Documentation/hwmon/f71882fg
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/f71882fg	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/f71882fg	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,10 @@ Supported chips:
     Prefix: 'f71882fg'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Available from the Fintek website
+  * Fintek F71889FG
+    Prefix: 'f71889fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Should become available on the Fintek website soon
   * Fintek F8000
     Prefix: 'f8000'
     Addresses scanned: none, address read from Super I/O config space
@@ -51,6 +55,12 @@ supported. The right one to use depends
 motherboard, so the driver assumes that the BIOS set the method
 properly.
 
+Note that the lowest numbered temperature zone trip point corresponds to
+to the border between the highest and one but highest temperature zones, and
+vica versa. So the temperature zone trip points 1-4 (or 1-2) go from high temp
+to low temp! This is how things are implemented in the IC, and the driver
+mimicks this.
+
 There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC
 voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM
 mode where the actual RPM of the fan (as measured) is controlled and the speed
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/it87 linux-libre-2.6.33-gnu1/Documentation/hwmon/it87
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/it87	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/it87	2010-02-24 13:52:17.000000000 -0500
@@ -86,7 +86,6 @@ The IT8712F and IT8716F additionally fea
 the Vcore voltage of the processor. The early IT8712F have 5 VID pins,
 the IT8716F and late IT8712F have 6. They are shared with other functions
 though, so the functionality may not be available on a given system.
-The driver dumbly assume it is there.
 
 The IT8718F and IT8720F also features VID inputs (up to 8 pins) but the value
 is stored in the Super-I/O configuration space. Due to technical limitations,
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/k10temp linux-libre-2.6.33-gnu1/Documentation/hwmon/k10temp
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/k10temp	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/k10temp	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,65 @@
+Kernel driver k10temp
+=====================
+
+Supported chips:
+* AMD Family 10h processors:
+  Socket F: Quad-Core/Six-Core/Embedded Opteron (but see below)
+  Socket AM2+: Quad-Core Opteron, Phenom (II) X3/X4, Athlon X2 (but see below)
+  Socket AM3: Quad-Core Opteron, Athlon/Phenom II X2/X3/X4, Sempron II
+  Socket S1G3: Athlon II, Sempron, Turion II
+* AMD Family 11h processors:
+  Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra)
+
+  Prefix: 'k10temp'
+  Addresses scanned: PCI space
+  Datasheets:
+  BIOS and Kernel Developer's Guide (BKDG) For AMD Family 10h Processors:
+    http://support.amd.com/us/Processor_TechDocs/31116.pdf
+  BIOS and Kernel Developer's Guide (BKDG) for AMD Family 11h Processors:
+    http://support.amd.com/us/Processor_TechDocs/41256.pdf
+  Revision Guide for AMD Family 10h Processors:
+    http://support.amd.com/us/Processor_TechDocs/41322.pdf
+  Revision Guide for AMD Family 11h Processors:
+    http://support.amd.com/us/Processor_TechDocs/41788.pdf
+  AMD Family 11h Processor Power and Thermal Data Sheet for Notebooks:
+    http://support.amd.com/us/Processor_TechDocs/43373.pdf
+  AMD Family 10h Server and Workstation Processor Power and Thermal Data Sheet:
+    http://support.amd.com/us/Processor_TechDocs/43374.pdf
+  AMD Family 10h Desktop Processor Power and Thermal Data Sheet:
+    http://support.amd.com/us/Processor_TechDocs/43375.pdf
+
+Author: Clemens Ladisch <clemens@ladisch.de>
+
+Description
+-----------
+
+This driver permits reading of the internal temperature sensor of AMD
+Family 10h and 11h processors.
+
+All these processors have a sensor, but on those for Socket F or AM2+,
+the sensor may return inconsistent values (erratum 319).  The driver
+will refuse to load on these revisions unless you specify the "force=1"
+module parameter.
+
+Due to technical reasons, the driver can detect only the mainboard's
+socket type, not the processor's actual capabilities.  Therefore, if you
+are using an AM3 processor on an AM2+ mainboard, you can safely use the
+"force=1" parameter.
+
+There is one temperature measurement value, available as temp1_input in
+sysfs. It is measured in degrees Celsius with a resolution of 1/8th degree.
+Please note that it is defined as a relative value; to quote the AMD manual:
+
+  Tctl is the processor temperature control value, used by the platform to
+  control cooling systems. Tctl is a non-physical temperature on an
+  arbitrary scale measured in degrees. It does _not_ represent an actual
+  physical temperature like die or case temperature. Instead, it specifies
+  the processor temperature relative to the point at which the system must
+  supply the maximum cooling for the processor's specified maximum case
+  temperature and maximum thermal power dissipation.
+
+The maximum value for Tctl is available in the file temp1_max.
+
+If the BIOS has enabled hardware temperature control, the threshold at
+which the processor will throttle itself to avoid damage is available in
+temp1_crit and temp1_crit_hyst.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/lis3lv02d linux-libre-2.6.33-gnu1/Documentation/hwmon/lis3lv02d
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/lis3lv02d	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/lis3lv02d	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,8 @@ Kernel driver lis3lv02d
 
 Supported chips:
 
-  * STMicroelectronics LIS3LV02DL and LIS3LV02DQ
+  * STMicroelectronics LIS3LV02DL, LIS3LV02DQ (12 bits precision)
+  * STMicroelectronics LIS302DL, LIS3L02DQ, LIS331DL (8 bits)
 
 Authors:
         Yan Burman <burman.yan@gmail.com>
@@ -13,32 +14,52 @@ Authors:
 Description
 -----------
 
-This driver provides support for the accelerometer found in various HP
-laptops sporting the feature officially called "HP Mobile Data
-Protection System 3D" or "HP 3D DriveGuard". It detects automatically
-laptops with this sensor. Known models (for now the HP 2133, nc6420,
-nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
-automatically oriented on standard way (eg: you can directly play
-neverball).  The accelerometer data is readable via
-/sys/devices/platform/lis3lv02d.
+This driver provides support for the accelerometer found in various HP laptops
+sporting the feature officially called "HP Mobile Data Protection System 3D" or
+"HP 3D DriveGuard". It detects automatically laptops with this sensor. Known
+models (full list can be found in drivers/hwmon/hp_accel.c) will have their
+axis automatically oriented on standard way (eg: you can directly play
+neverball). The accelerometer data is readable via
+/sys/devices/platform/lis3lv02d. Reported values are scaled
+to mg values (1/1000th of earth gravity).
 
 Sysfs attributes under /sys/devices/platform/lis3lv02d/:
 position - 3D position that the accelerometer reports. Format: "(x,y,z)"
-calibrate - read: values (x, y, z) that are used as the base for input
-		  class device operation.
-            write: forces the base to be recalibrated with the current
-		   position.
-rate - reports the sampling rate of the accelerometer device in HZ
+rate - read reports the sampling rate of the accelerometer device in HZ.
+	write changes sampling rate of the accelerometer device.
+	Only values which are supported by HW are accepted.
+selftest - performs selftest for the chip as specified by chip manufacturer.
 
 This driver also provides an absolute input class device, allowing
-the laptop to act as a pinball machine-esque joystick.
+the laptop to act as a pinball machine-esque joystick. Joystick device can be
+calibrated. Joystick device can be in two different modes.
+By default output values are scaled between -32768 .. 32767. In joystick raw
+mode, joystick and sysfs position entry have the same scale. There can be
+small difference due to input system fuzziness feature.
+Events are also available as input event device.
+
+Selftest is meant only for hardware diagnostic purposes. It is not meant to be
+used during normal operations. Position data is not corrupted during selftest
+but interrupt behaviour is not guaranteed to work reliably. In test mode, the
+sensing element is internally moved little bit. Selftest measures difference
+between normal mode and test mode. Chip specifications tell the acceptance
+limit for each type of the chip. Limits are provided via platform data
+to allow adjustment of the limits without a change to the actual driver.
+Seltest returns either "OK x y z" or "FAIL x y z" where x, y and z are
+measured difference between modes. Axes are not remapped in selftest mode.
+Measurement values are provided to help HW diagnostic applications to make
+final decision.
+
+On HP laptops, if the led infrastructure is activated, support for a led
+indicating disk protection will be provided as /sys/class/leds/hp::hddprotect.
 
 Another feature of the driver is misc device called "freefall" that
 acts similar to /dev/rtc and reacts on free-fall interrupts received
 from the device. It supports blocking operations, poll/select and
 fasync operation modes. You must read 1 bytes from the device.  The
 result is number of free-fall interrupts since the last successful
-read (or 255 if number of interrupts would not fit).
+read (or 255 if number of interrupts would not fit). See the hpfall.c
+file for an example on using the device.
 
 
 Axes orientation
@@ -55,7 +76,7 @@ the accelerometer are converted into a "
  * If the laptop is put upside-down, Z becomes negative
 
 If your laptop model is not recognized (cf "dmesg"), you can send an
-email to the authors to add it to the database.  When reporting a new
+email to the maintainer to add it to the database.  When reporting a new
 laptop, please include the output of "dmidecode" plus the value of
 /sys/devices/platform/lis3lv02d/position in these four cases.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/mc13783-adc linux-libre-2.6.33-gnu1/Documentation/hwmon/mc13783-adc
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/mc13783-adc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/mc13783-adc	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,50 @@
+Kernel driver mc13783-adc
+=========================
+
+Supported chips:
+  * Freescale Atlas MC13783
+    Prefix: 'mc13783_adc'
+    Datasheet: http://www.freescale.com/files/rf_if/doc/data_sheet/MC13783.pdf?fsrch=1
+
+Authors:
+    Sascha Hauer <s.hauer@pengutronix.de>
+    Luotao Fu <l.fu@pengutronix.de>
+
+Description
+-----------
+
+The Freescale MC13783 is a Power Management and Audio Circuit. Among
+other things it contains a 10-bit A/D converter. The converter has 16
+channels which can be used in different modes.
+The A/D converter has a resolution of 2.25mV. Channels 0-4 have
+a dedicated meaning with chip internal scaling applied. Channels 5-7
+can be used as general purpose inputs or alternatively in a dedicated
+mode. Channels 12-15 are occupied by the touchscreen if it's active.
+
+Currently the driver only supports channels 2 and 5-15 with no alternative
+modes for channels 5-7.
+
+See this table for the meaning of the different channels and their chip
+internal scaling:
+
+Channel	Signal						Input Range	Scaling
+-------------------------------------------------------------------------------
+0	Battery Voltage (BATT)				2.50 - 4.65V	-2.40V
+1	Battery Current (BATT - BATTISNS)		-50 - 50 mV	x20
+2	Application Supply (BP)				2.50 - 4.65V	-2.40V
+3	Charger Voltage (CHRGRAW)			0 - 10V /	/5
+							0 - 20V		/10
+4	Charger Current (CHRGISNSP-CHRGISNSN)		-0.25V - 0.25V	x4
+5	General Purpose ADIN5 / Battery Pack Thermistor	0 - 2.30V	No
+6	General Purpose ADIN6 / Backup Voltage (LICELL)	0 - 2.30V /	No /
+							1.50 - 3.50V	-1.20V
+7	General Purpose ADIN7 / UID / Die Temperature	0 - 2.30V /	No /
+							0 - 2.55V /	x0.9 / No
+8	General Purpose ADIN8				0 - 2.30V	No
+9	General Purpose ADIN9				0 - 2.30V	No
+10	General Purpose ADIN10				0 - 2.30V	No
+11	General Purpose ADIN11				0 - 2.30V	No
+12	General Purpose TSX1 / Touchscreen X-plate 1	0 - 2.30V	No
+13	General Purpose TSX2 / Touchscreen X-plate 2	0 - 2.30V	No
+14	General Purpose TSY1 / Touchscreen Y-plate 1	0 - 2.30V	No
+15	General Purpose TSY2 / Touchscreen Y-plate 2	0 - 2.30V	No
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/sysfs-interface linux-libre-2.6.33-gnu1/Documentation/hwmon/sysfs-interface
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/sysfs-interface	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/sysfs-interface	2010-02-24 13:52:17.000000000 -0500
@@ -225,8 +225,6 @@ pwm[1-*]_auto_point[1-*]_temp_hyst
 		to PWM output channels.
 		RW
 
-OR
-
 temp[1-*]_auto_point[1-*]_pwm
 temp[1-*]_auto_point[1-*]_temp
 temp[1-*]_auto_point[1-*]_temp_hyst
@@ -235,6 +233,15 @@ temp[1-*]_auto_point[1-*]_temp_hyst
 		to temperature channels.
 		RW
 
+There is a third case where trip points are associated to both PWM output
+channels and temperature channels: the PWM values are associated to PWM
+output channels while the temperature values are associated to temperature
+channels. In that case, the result is determined by the mapping between
+temperature inputs and PWM outputs. When several temperature inputs are
+mapped to a given PWM output, this leads to several candidate PWM values.
+The actual result is up to the chip, but in general the highest candidate
+value (fastest fan speed) wins.
+
 
 ****************
 * Temperatures *
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/w83627ehf linux-libre-2.6.33-gnu1/Documentation/hwmon/w83627ehf
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/w83627ehf	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/w83627ehf	2010-02-24 13:52:17.000000000 -0500
@@ -81,8 +81,14 @@ pwm[1-4] - this file stores PWM duty cyc
 	   0 (stop) to 255 (full)
 
 pwm[1-4]_enable - this file controls mode of fan/temperature control:
-	* 1 Manual Mode, write to pwm file any value 0-255 (full speed)
-	* 2 Thermal Cruise
+	* 1 Manual mode, write to pwm file any value 0-255 (full speed)
+	* 2 "Thermal Cruise" mode
+	* 3 "Fan Speed Cruise" mode
+	* 4 "Smart Fan III" mode
+
+pwm[1-4]_mode - controls if output is PWM or DC level
+        * 0 DC output (0 - 12v)
+        * 1 PWM output
 
 Thermal Cruise mode
 -------------------
diff -druNp linux-libre-2.6.32-gnu1/Documentation/hwmon/w83627hf linux-libre-2.6.33-gnu1/Documentation/hwmon/w83627hf
--- linux-libre-2.6.32-gnu1/Documentation/hwmon/w83627hf	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/hwmon/w83627hf	2010-02-24 13:52:17.000000000 -0500
@@ -32,8 +32,6 @@ Authors:
 Module Parameters
 -----------------
 
-* force_addr: int
-  Initialize the ISA address of the sensors
 * force_i2c: int
   Initialize the I2C address of the sensors
 * init: int
@@ -70,3 +68,30 @@ doesn't help, you may just ignore the bo
 For further information on this driver see the w83781d driver documentation.
 
 [1] http://www.lm-sensors.org/browser/lm-sensors/trunk/doc/vid
+
+Forcing the address
+-------------------
+
+The driver used to have a module parameter named force_addr, which could
+be used to force the base I/O address of the hardware monitoring block.
+This was meant as a workaround for mainboards with a broken BIOS. This
+module parameter is gone for technical reasons. If you need this feature,
+you can obtain the same result by using the isaset tool (part of
+lm-sensors) before loading the driver:
+
+# Enter the Super I/O config space
+isaset -y -f 0x2e 0x87
+isaset -y -f 0x2e 0x87
+
+# Select the hwmon logical device
+isaset -y 0x2e 0x2f 0x07 0x0b
+
+# Set the base I/O address (to 0x290 in this example)
+isaset -y 0x2e 0x2f 0x60 0x02
+isaset -y 0x2e 0x2f 0x61 0x90
+
+# Exit the Super-I/O config space
+isaset -y -f 0x2e 0xaa
+
+The above sequence assumes a Super-I/O config space at 0x2e/0x2f, but
+0x4e/0x4f is also possible.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/i2c/busses/i2c-voodoo3 linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-voodoo3
--- linux-libre-2.6.32-gnu1/Documentation/i2c/busses/i2c-voodoo3	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/i2c/busses/i2c-voodoo3	1969-12-31 19:00:00.000000000 -0500
@@ -1,62 +0,0 @@
-Kernel driver i2c-voodoo3
-
-Supported adapters:
-  * 3dfx Voodoo3 based cards
-  * Voodoo Banshee based cards
-
-Authors: 
-	Frodo Looijaard <frodol@dds.nl>, 
-	Philip Edelbrock <phil@netroedge.com>, 
-	Ralph Metzler <rjkm@thp.uni-koeln.de>,
-	Mark D. Studebaker <mdsxyz123@yahoo.com>
-
-Main contact: Philip Edelbrock <phil@netroedge.com>
-	
-The code is based upon Ralph's test code (he did the hard stuff ;')
-
-Description
------------
-
-The 3dfx Voodoo3 chip contains two I2C interfaces (aka a I2C 'master' or
-'host'). 
-
-The first interface is used for DDC (Data Display Channel) which is a
-serial channel through the VGA monitor connector to a DDC-compliant
-monitor. This interface is defined by the Video Electronics Standards
-Association (VESA). The standards are available for purchase at
-http://www.vesa.org .
-
-The second interface is a general-purpose I2C bus. The intent by 3dfx was
-to allow manufacturers to add extra chips to the video card such as a
-TV-out chip such as the BT869 or possibly even I2C based temperature
-sensors like the ADM1021 or LM75.
-
-Stability
----------
-
-Seems to be stable on the test machine, but needs more testing on other
-machines. Simultaneous accesses of the DDC and I2C busses may cause errors.
-
-Supported Devices
------------------
-
-Specifically, this driver was written and tested on the '3dfx Voodoo3 AGP
-3000' which has a tv-out feature (s-video or composite).  According to the
-docs and discussions, this code should work for any Voodoo3 based cards as
-well as Voodoo Banshee based cards.  The DDC interface has been tested on a
-Voodoo Banshee card.
-	
-Issues
-------
-
-Probably many, but it seems to work OK on my system. :')
-
-
-External Device Connection
---------------------------
-
-The digital video input jumpers give availability to the I2C bus. 
-Specifically, pins 13 and 25 (bottom row middle, and bottom right-end) are     
-the I2C clock and I2C data lines, respectively. +5V and GND are probably
-also easily available making the addition of extra I2C/SMBus devices easy
-to implement.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/i2c/i2c-stub linux-libre-2.6.33-gnu1/Documentation/i2c/i2c-stub
--- linux-libre-2.6.32-gnu1/Documentation/i2c/i2c-stub	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/i2c/i2c-stub	2010-02-24 13:52:17.000000000 -0500
@@ -2,9 +2,9 @@ MODULE: i2c-stub
 
 DESCRIPTION:
 
-This module is a very simple fake I2C/SMBus driver.  It implements four
-types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and
-(r/w) word data.
+This module is a very simple fake I2C/SMBus driver.  It implements five
+types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, (r/w)
+word data, and (r/w) I2C block data.
 
 You need to provide chip addresses as a module parameter when loading this
 driver, which will then only react to SMBus commands to these addresses.
@@ -21,8 +21,8 @@ EEPROMs, among others.
 
 The typical use-case is like this:
 	1. load this module
-	2. use i2cset (from lm_sensors project) to pre-load some data
-	3. load the target sensors chip driver module
+	2. use i2cset (from the i2c-tools project) to pre-load some data
+	3. load the target chip driver module
 	4. observe its behavior in the kernel log
 
 There's a script named i2c-stub-from-dump in the i2c-tools package which
@@ -33,6 +33,12 @@ PARAMETERS:
 int chip_addr[10]:
 	The SMBus addresses to emulate chips at.
 
+unsigned long functionality:
+	Functionality override, to disable some commands. See I2C_FUNC_*
+	constants in <linux/i2c.h> for the suitable values. For example,
+	value 0x1f0000 would only enable the quick, byte and byte data
+	commands.
+
 CAVEATS:
 
 If your target driver polls some byte or word waiting for it to change, the
diff -druNp linux-libre-2.6.32-gnu1/Documentation/i2c/old-module-parameters linux-libre-2.6.33-gnu1/Documentation/i2c/old-module-parameters
--- linux-libre-2.6.32-gnu1/Documentation/i2c/old-module-parameters	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/i2c/old-module-parameters	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,44 @@
+I2C device driver binding control from user-space
+=================================================
+
+Up to kernel 2.6.32, many i2c drivers used helper macros provided by
+<linux/i2c.h> which created standard module parameters to let the user
+control how the driver would probe i2c buses and attach to devices. These
+parameters were known as "probe" (to let the driver probe for an extra
+address), "force" (to forcibly attach the driver to a given device) and
+"ignore" (to prevent a driver from probing a given address).
+
+With the conversion of the i2c subsystem to the standard device driver
+binding model, it became clear that these per-module parameters were no
+longer needed, and that a centralized implementation was possible. The new,
+sysfs-based interface is described in the documentation file
+"instantiating-devices", section "Method 4: Instantiate from user-space".
+
+Below is a mapping from the old module parameters to the new interface.
+
+Attaching a driver to an I2C device
+-----------------------------------
+
+Old method (module parameters):
+# modprobe <driver> probe=1,0x2d
+# modprobe <driver> force=1,0x2d
+# modprobe <driver> force_<device>=1,0x2d
+
+New method (sysfs interface):
+# echo <device> 0x2d > /sys/bus/i2c/devices/i2c-1/new_device
+
+Preventing a driver from attaching to an I2C device
+---------------------------------------------------
+
+Old method (module parameters):
+# modprobe <driver> ignore=1,0x2f
+
+New method (sysfs interface):
+# echo dummy 0x2f > /sys/bus/i2c/devices/i2c-1/new_device
+# modprobe <driver>
+
+Of course, it is important to instantiate the "dummy" device before loading
+the driver. The dummy device will be handled by i2c-core itself, preventing
+other drivers from binding to it later on. If there is a real device at the
+problematic address, and you want another driver to bind to it, then simply
+pass the name of the device in question instead of "dummy".
diff -druNp linux-libre-2.6.32-gnu1/Documentation/i2c/writing-clients linux-libre-2.6.33-gnu1/Documentation/i2c/writing-clients
--- linux-libre-2.6.32-gnu1/Documentation/i2c/writing-clients	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/i2c/writing-clients	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@ static struct i2c_driver foo_driver = {
 	/* if device autodetection is needed: */
 	.class		= I2C_CLASS_SOMETHING,
 	.detect		= foo_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 
 	.shutdown	= foo_shutdown,	/* optional */
 	.suspend	= foo_suspend,	/* optional */
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ics932s401 linux-libre-2.6.33-gnu1/Documentation/ics932s401
--- linux-libre-2.6.32-gnu1/Documentation/ics932s401	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ics932s401	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-Kernel driver ics932s401
-======================
-
-Supported chips:
-  * IDT ICS932S401
-    Prefix: 'ics932s401'
-    Addresses scanned: I2C 0x69
-    Datasheet: Publically available at the IDT website
-
-Author: Darrick J. Wong
-
-Description
------------
-
-This driver implements support for the IDT ICS932S401 chip family.
-
-This chip has 4 clock outputs--a base clock for the CPU (which is likely
-multiplied to get the real CPU clock), a system clock, a PCI clock, a USB
-clock, and a reference clock.  The driver reports selected and actual
-frequency.  If spread spectrum mode is enabled, the driver also reports by what
-percent the clock signal is being spread, which should be between 0 and -0.5%.
-All frequencies are reported in KHz.
-
-The ICS932S401 monitors all inputs continuously. The driver will not read
-the registers more often than once every other second.
-
-Special Features
-----------------
-
-The clocks could be reprogrammed to increase system speed.  I will not help you
-do this, as you risk damaging your system!
diff -druNp linux-libre-2.6.32-gnu1/Documentation/infiniband/ipoib.txt linux-libre-2.6.33-gnu1/Documentation/infiniband/ipoib.txt
--- linux-libre-2.6.32-gnu1/Documentation/infiniband/ipoib.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/infiniband/ipoib.txt	2010-02-24 13:52:17.000000000 -0500
@@ -36,11 +36,11 @@ Datagram vs Connected modes
   fabric with a 2K MTU, the IPoIB MTU will be 2048 - 4 = 2044 bytes.
 
   In connected mode, the IB RC (Reliable Connected) transport is used.
-  Connected mode is to takes advantage of the connected nature of the
-  IB transport and allows an MTU up to the maximal IP packet size of
-  64K, which reduces the number of IP packets needed for handling
-  large UDP datagrams, TCP segments, etc and increases the performance
-  for large messages.
+  Connected mode takes advantage of the connected nature of the IB
+  transport and allows an MTU up to the maximal IP packet size of 64K,
+  which reduces the number of IP packets needed for handling large UDP
+  datagrams, TCP segments, etc and increases the performance for large
+  messages.
 
   In connected mode, the interface's UD QP is still used for multicast
   and communication with peers that don't support connected mode. In
diff -druNp linux-libre-2.6.32-gnu1/Documentation/input/multi-touch-protocol.txt linux-libre-2.6.33-gnu1/Documentation/input/multi-touch-protocol.txt
--- linux-libre-2.6.32-gnu1/Documentation/input/multi-touch-protocol.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/input/multi-touch-protocol.txt	2010-02-24 13:52:17.000000000 -0500
@@ -27,12 +27,30 @@ set of events/packets.
 
 A set of ABS_MT events with the desired properties is defined. The events
 are divided into categories, to allow for partial implementation.  The
-minimum set consists of ABS_MT_TOUCH_MAJOR, ABS_MT_POSITION_X and
-ABS_MT_POSITION_Y, which allows for multiple fingers to be tracked.  If the
-device supports it, the ABS_MT_WIDTH_MAJOR may be used to provide the size
-of the approaching finger. Anisotropy and direction may be specified with
-ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION.  The
-ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
+minimum set consists of ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which
+allows for multiple fingers to be tracked.  If the device supports it, the
+ABS_MT_TOUCH_MAJOR and ABS_MT_WIDTH_MAJOR may be used to provide the size
+of the contact area and approaching finger, respectively.
+
+The TOUCH and WIDTH parameters have a geometrical interpretation; imagine
+looking through a window at someone gently holding a finger against the
+glass.  You will see two regions, one inner region consisting of the part
+of the finger actually touching the glass, and one outer region formed by
+the perimeter of the finger. The diameter of the inner region is the
+ABS_MT_TOUCH_MAJOR, the diameter of the outer region is
+ABS_MT_WIDTH_MAJOR. Now imagine the person pressing the finger harder
+against the glass. The inner region will increase, and in general, the
+ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than
+unity, is related to the finger pressure. For pressure-based devices,
+ABS_MT_PRESSURE may be used to provide the pressure on the contact area
+instead.
+
+In addition to the MAJOR parameters, the oval shape of the finger can be
+described by adding the MINOR parameters, such that MAJOR and MINOR are the
+major and minor axis of an ellipse. Finally, the orientation of the oval
+shape can be describe with the ORIENTATION parameter.
+
+The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
 finger or a pen or something else.  Devices with more granular information
 may specify general shapes as blobs, i.e., as a sequence of rectangular
 shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices
@@ -42,11 +60,9 @@ report finger tracking from hardware [5]
 Here is what a minimal event sequence for a two-finger touch would look
 like:
 
-   ABS_MT_TOUCH_MAJOR
    ABS_MT_POSITION_X
    ABS_MT_POSITION_Y
    SYN_MT_REPORT
-   ABS_MT_TOUCH_MAJOR
    ABS_MT_POSITION_X
    ABS_MT_POSITION_Y
    SYN_MT_REPORT
@@ -87,6 +103,12 @@ the contact. The ratio ABS_MT_TOUCH_MAJO
 the notion of pressure. The fingers of the hand and the palm all have
 different characteristic widths [1].
 
+ABS_MT_PRESSURE
+
+The pressure, in arbitrary units, on the contact area. May be used instead
+of TOUCH and WIDTH for pressure-based devices or any device with a spatial
+signal intensity distribution.
+
 ABS_MT_ORIENTATION
 
 The orientation of the ellipse. The value should describe a signed quarter
@@ -170,6 +192,16 @@ There are a few devices that support tra
 make use of these native identifiers to reduce bandwidth and cpu usage.
 
 
+Gestures
+--------
+
+In the specific application of creating gesture events, the TOUCH and WIDTH
+parameters can be used to, e.g., approximate finger pressure or distinguish
+between index finger and thumb. With the addition of the MINOR parameters,
+one can also distinguish between a sweeping finger and a pointing finger,
+and with ORIENTATION, one can detect twisting of fingers.
+
+
 Notes
 -----
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/ioctl/ioctl-number.txt linux-libre-2.6.33-gnu1/Documentation/ioctl/ioctl-number.txt
--- linux-libre-2.6.32-gnu1/Documentation/ioctl/ioctl-number.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/ioctl/ioctl-number.txt	2010-02-24 13:52:17.000000000 -0500
@@ -56,10 +56,11 @@ Following this convention is good becaus
 (5) When following the convention, the driver code can use generic
     code to copy the parameters between user and kernel space.
 
-This table lists ioctls visible from user land for Linux/i386.  It contains
-most drivers up to 2.3.14, but I know I am missing some.
+This table lists ioctls visible from user land for Linux/x86.  It contains
+most drivers up to 2.6.31, but I know I am missing some.  There has been
+no attempt to list non-X86 architectures or ioctls from drivers/staging/.
 
-Code	Seq#	Include File		Comments
+Code  Seq#(hex)	Include File		Comments
 ========================================================
 0x00	00-1F	linux/fs.h		conflict!
 0x00	00-1F	scsi/scsi_ioctl.h	conflict!
@@ -69,119 +70,228 @@ Code	Seq#	Include File		Comments
 0x03	all	linux/hdreg.h
 0x04	D2-DC	linux/umsdos_fs.h	Dead since 2.6.11, but don't reuse these.
 0x06	all	linux/lp.h
-0x09	all	linux/md.h
+0x09	all	linux/raid/md_u.h
+0x10	00-0F	drivers/char/s390/vmcp.h
 0x12	all	linux/fs.h
 		linux/blkpg.h
 0x1b	all	InfiniBand Subsystem	<http://www.openib.org/>
 0x20	all	drivers/cdrom/cm206.h
 0x22	all	scsi/sg.h
 '#'	00-3F	IEEE 1394 Subsystem	Block for the entire subsystem
+'$'	00-0F	linux/perf_counter.h, linux/perf_event.h
 '1'	00-1F	<linux/timepps.h>	PPS kit from Ulrich Windl
 					<ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/>
+'2'	01-04	linux/i2o.h
+'3'	00-0F	drivers/s390/char/raw3270.h	conflict!
+'3'	00-1F	linux/suspend_ioctls.h	conflict!
+		and kernel/power/user.c
 '8'	all				SNP8023 advanced NIC card
 					<mailto:mcr@solidum.com>
-'A'	00-1F	linux/apm_bios.h
+'@'	00-0F	linux/radeonfb.h	conflict!
+'@'	00-0F	drivers/video/aty/aty128fb.c	conflict!
+'A'	00-1F	linux/apm_bios.h	conflict!
+'A'	00-0F	linux/agpgart.h		conflict!
+		and drivers/char/agp/compat_ioctl.h
+'A'	00-7F	sound/asound.h		conflict!
+'B'	00-1F	linux/cciss_ioctl.h	conflict!
+'B'	00-0F	include/linux/pmu.h	conflict!
 'B'	C0-FF				advanced bbus
 					<mailto:maassen@uni-freiburg.de>
-'C'	all	linux/soundcard.h
+'C'	all	linux/soundcard.h	conflict!
+'C'	01-2F	linux/capi.h		conflict!
+'C'	F0-FF	drivers/net/wan/cosa.h	conflict!
 'D'	all	arch/s390/include/asm/dasd.h
-'E'	all	linux/input.h
-'F'	all	linux/fb.h
-'H'	all	linux/hiddev.h
-'I'	all	linux/isdn.h
+'D'	40-5F	drivers/scsi/dpt/dtpi_ioctl.h
+'D'	05	drivers/scsi/pmcraid.h
+'E'	all	linux/input.h		conflict!
+'E'	00-0F	xen/evtchn.h		conflict!
+'F'	all	linux/fb.h		conflict!
+'F'	01-02	drivers/scsi/pmcraid.h	conflict!
+'F'	20	drivers/video/fsl-diu-fb.h	conflict!
+'F'	20	drivers/video/intelfb/intelfb.h	conflict!
+'F'	20	linux/ivtvfb.h		conflict!
+'F'	20	linux/matroxfb.h	conflict!
+'F'	20	drivers/video/aty/atyfb_base.c	conflict!
+'F'	00-0F	video/da8xx-fb.h	conflict!
+'F'	80-8F	linux/arcfb.h		conflict!
+'F'	DD	video/sstfb.h		conflict!
+'G'	00-3F	drivers/misc/sgi-gru/grulib.h	conflict!
+'G'	00-0F	linux/gigaset_dev.h	conflict!
+'H'	00-7F	linux/hiddev.h		conflict!
+'H'	00-0F	linux/hidraw.h		conflict!
+'H'	00-0F	sound/asound.h		conflict!
+'H'	20-40	sound/asound_fm.h	conflict!
+'H'	80-8F	sound/sfnt_info.h	conflict!
+'H'	10-8F	sound/emu10k1.h		conflict!
+'H'	10-1F	sound/sb16_csp.h	conflict!
+'H'	10-1F	sound/hda_hwdep.h	conflict!
+'H'	40-4F	sound/hdspm.h		conflict!
+'H'	40-4F	sound/hdsp.h		conflict!
+'H'	90	sound/usb/usx2y/usb_stream.h
+'H'	C0-F0	net/bluetooth/hci.h	conflict!
+'H'	C0-DF	net/bluetooth/hidp/hidp.h	conflict!
+'H'	C0-DF	net/bluetooth/cmtp/cmtp.h	conflict!
+'H'	C0-DF	net/bluetooth/bnep/bnep.h	conflict!
+'I'	all	linux/isdn.h		conflict!
+'I'	00-0F	drivers/isdn/divert/isdn_divert.h	conflict!
+'I'	40-4F	linux/mISDNif.h		conflict!
 'J'	00-1F	drivers/scsi/gdth_ioctl.h
 'K'	all	linux/kd.h
-'L'	00-1F	linux/loop.h
-'L'	20-2F	driver/usb/misc/vstusb.h
+'L'	00-1F	linux/loop.h		conflict!
+'L'	10-1F	drivers/scsi/mpt2sas/mpt2sas_ctl.h	conflict!
+'L'	20-2F	linux/usb/vstusb.h
 'L'	E0-FF	linux/ppdd.h		encrypted disk device driver
 					<http://linux01.gwdg.de/~alatham/ppdd.html>
-'M'	all	linux/soundcard.h
+'M'	all	linux/soundcard.h	conflict!
+'M'	01-16	mtd/mtd-abi.h		conflict!
+		and drivers/mtd/mtdchar.c
+'M'	01-03	drivers/scsi/megaraid/megaraid_sas.h
+'M'	00-0F	drivers/video/fsl-diu-fb.h	conflict!
 'N'	00-1F	drivers/usb/scanner.h
-'O'     00-02   include/mtd/ubi-user.h UBI
-'P'	all	linux/soundcard.h
+'O'     00-06   mtd/ubi-user.h		UBI
+'P'	all	linux/soundcard.h	conflict!
+'P'	60-6F	sound/sscape_ioctl.h	conflict!
+'P'	00-0F	drivers/usb/class/usblp.c	conflict!
 'Q'	all	linux/soundcard.h
-'R'	00-1F	linux/random.h
+'R'	00-1F	linux/random.h		conflict!
+'R'	01	linux/rfkill.h		conflict!
+'R'	01-0F	media/rds.h		conflict!
+'R'	C0-DF	net/bluetooth/rfcomm.h
 'S'	all	linux/cdrom.h		conflict!
 'S'	80-81	scsi/scsi_ioctl.h	conflict!
 'S'	82-FF	scsi/scsi.h		conflict!
+'S'	00-7F	sound/asequencer.h	conflict!
 'T'	all	linux/soundcard.h	conflict!
+'T'	00-AF	sound/asound.h		conflict!
 'T'	all	arch/x86/include/asm/ioctls.h	conflict!
-'U'	00-EF	linux/drivers/usb/usb.h
-'V'	all	linux/vt.h
+'T'	C0-DF	linux/if_tun.h		conflict!
+'U'	all	sound/asound.h		conflict!
+'U'	00-0F	drivers/media/video/uvc/uvcvideo.h	conflict!
+'U'	00-CF	linux/uinput.h		conflict!
+'U'	00-EF	linux/usbdevice_fs.h
+'U'	C0-CF	drivers/bluetooth/hci_uart.h
+'V'	all	linux/vt.h		conflict!
+'V'	all	linux/videodev2.h	conflict!
+'V'	C0	linux/ivtvfb.h		conflict!
+'V'	C0	linux/ivtv.h		conflict!
+'V'	C0	media/davinci/vpfe_capture.h	conflict!
+'V'	C0	media/si4713.h		conflict!
+'V'	C0-CF	drivers/media/video/mxb.h	conflict!
 'W'	00-1F	linux/watchdog.h	conflict!
 'W'	00-1F	linux/wanrouter.h	conflict!
-'X'	all	linux/xfs_fs.h
+'W'	00-3F	sound/asound.h		conflict!
+'X'	all	fs/xfs/xfs_fs.h		conflict!
+		and fs/xfs/linux-2.6/xfs_ioctl32.h
+		and include/linux/falloc.h
+		and linux/fs.h
+'X'	all	fs/ocfs2/ocfs_fs.h	conflict!
+'X'	01	linux/pktcdvd.h		conflict!
 'Y'	all	linux/cyclades.h
-'['	00-07	linux/usb/usbtmc.h	USB Test and Measurement Devices
+'Z'	14-15	drivers/message/fusion/mptctl.h
+'['	00-07	linux/usb/tmc.h		USB Test and Measurement Devices
 					<mailto:gregkh@suse.de>
-'a'	all				ATM on linux
+'a'	all	linux/atm*.h, linux/sonet.h	ATM on linux
 					<http://lrcwww.epfl.ch/linux-atm/magic.html>
-'b'	00-FF				bit3 vme host bridge
+'b'	00-FF				conflict! bit3 vme host bridge
 					<mailto:natalia@nikhefk.nikhef.nl>
+'b'	00-0F	media/bt819.h		conflict!
+'c'	all	linux/cm4000_cs.h	conflict!
 'c'	00-7F	linux/comstats.h	conflict!
 'c'	00-7F	linux/coda.h		conflict!
-'c'	80-9F	arch/s390/include/asm/chsc.h
-'c'	A0-AF   arch/x86/include/asm/msr.h
+'c'	00-1F	linux/chio.h		conflict!
+'c'	80-9F	arch/s390/include/asm/chsc.h	conflict!
+'c'	A0-AF   arch/x86/include/asm/msr.h	conflict!
 'd'	00-FF	linux/char/drm/drm/h	conflict!
+'d'	02-40	pcmcia/ds.h		conflict!
+'d'	10-3F	drivers/media/video/dabusb.h	conflict!
+'d'	C0-CF	drivers/media/video/saa7191.h	conflict!
 'd'	F0-FF	linux/digi1.h
 'e'	all	linux/digi1.h		conflict!
-'e'	00-1F	net/irda/irtty.h	conflict!
-'f'	00-1F	linux/ext2_fs.h
-'h'	00-7F				Charon filesystem
+'e'	00-1F	drivers/net/irda/irtty-sir.h	conflict!
+'f'	00-1F	linux/ext2_fs.h		conflict!
+'f'	00-1F	linux/ext3_fs.h		conflict!
+'f'	00-0F	fs/jfs/jfs_dinode.h	conflict!
+'f'	00-0F	fs/ext4/ext4.h		conflict!
+'f'	00-0F	linux/fs.h		conflict!
+'f'	00-0F	fs/ocfs2/ocfs2_fs.h	conflict!
+'g'	00-0F	linux/usb/gadgetfs.h
+'g'	20-2F	linux/usb/g_printer.h
+'h'	00-7F				conflict! Charon filesystem
 					<mailto:zapman@interlan.net>
-'i'	00-3F	linux/i2o.h
+'h'	00-1F	linux/hpet.h		conflict!
+'i'	00-3F	linux/i2o-dev.h		conflict!
+'i'	0B-1F	linux/ipmi.h		conflict!
+'i'	80-8F	linux/i8k.h
 'j'	00-3F	linux/joystick.h
+'k'	00-0F	linux/spi/spidev.h	conflict!
+'k'	00-05	video/kyro.h		conflict!
 'l'	00-3F	linux/tcfs_fs.h		transparent cryptographic file system
 					<http://mikonos.dia.unisa.it/tcfs>
 'l'	40-7F	linux/udf_fs_i.h	in development:
 					<http://sourceforge.net/projects/linux-udf/>
-'m'	00-09	linux/mmtimer.h
+'m'	00-09	linux/mmtimer.h		conflict!
 'm'	all	linux/mtio.h		conflict!
 'm'	all	linux/soundcard.h	conflict!
 'm'	all	linux/synclink.h	conflict!
+'m'	00-19	drivers/message/fusion/mptctl.h	conflict!
+'m'	00	drivers/scsi/megaraid/megaraid_ioctl.h	conflict!
 'm'	00-1F	net/irda/irmod.h	conflict!
-'n'	00-7F	linux/ncp_fs.h
+'n'	00-7F	linux/ncp_fs.h and fs/ncpfs/ioctl.c
 'n'	80-8F	linux/nilfs2_fs.h	NILFS2
-'n'	E0-FF	video/matrox.h          matroxfb
+'n'	E0-FF	linux/matroxfb.h	matroxfb
 'o'	00-1F	fs/ocfs2/ocfs2_fs.h	OCFS2
-'o'     00-03   include/mtd/ubi-user.h  conflict! (OCFS2 and UBI overlaps)
-'o'     40-41   include/mtd/ubi-user.h  UBI
-'o'     01-A1   include/linux/dvb/*.h DVB
+'o'     00-03   mtd/ubi-user.h		conflict! (OCFS2 and UBI overlaps)
+'o'     40-41   mtd/ubi-user.h		UBI
+'o'     01-A1   linux/dvb/*.h		DVB
 'p'	00-0F	linux/phantom.h		conflict! (OpenHaptics needs this)
+'p'	00-1F	linux/rtc.h		conflict!
 'p'	00-3F	linux/mc146818rtc.h	conflict!
 'p'	40-7F	linux/nvram.h
-'p'	80-9F				user-space parport
+'p'	80-9F	linux/ppdev.h		user-space parport
 					<mailto:tim@cyberelk.net>
-'p'	a1-a4	linux/pps.h		LinuxPPS
+'p'	A1-A4	linux/pps.h		LinuxPPS
 					<mailto:giometti@linux.it>
 'q'	00-1F	linux/serio.h
-'q'	80-FF				Internet PhoneJACK, Internet LineJACK
-					<http://www.quicknet.net>
-'r'	00-1F	linux/msdos_fs.h
+'q'	80-FF	linux/telephony.h	Internet PhoneJACK, Internet LineJACK
+		linux/ixjuser.h		<http://www.quicknet.net>
+'r'	00-1F	linux/msdos_fs.h and fs/fat/dir.c
 's'	all	linux/cdk.h
 't'	00-7F	linux/if_ppp.h
 't'	80-8F	linux/isdn_ppp.h
+'t'	90	linux/toshiba.h
 'u'	00-1F	linux/smb_fs.h
-'v'	00-1F	linux/ext2_fs.h		conflict!
 'v'	all	linux/videodev.h	conflict!
+'v'	00-1F	linux/ext2_fs.h		conflict!
+'v'	00-1F	linux/fs.h		conflict!
+'v'	00-0F	linux/sonypi.h		conflict!
+'v'	C0-CF	drivers/media/video/ov511.h	conflict!
+'v'	C0-DF	media/pwc-ioctl.h	conflict!
+'v'	C0-FF	linux/meye.h		conflict!
+'v'	C0-CF	drivers/media/video/zoran/zoran.h	conflict!
+'v'	D0-DF	drivers/media/video/cpia2/cpia2dev.h	conflict!
 'w'	all				CERN SCI driver
 'y'	00-1F				packet based user level communications
 					<mailto:zapman@interlan.net>
-'z'	00-3F				CAN bus card
+'z'	00-3F				CAN bus card	conflict!
 					<mailto:hdstich@connectu.ulm.circular.de>
-'z'	40-7F				CAN bus card
+'z'	40-7F				CAN bus card	conflict!
 					<mailto:oe@port.de>
+'z'	10-4F	drivers/s390/crypto/zcrypt_api.h	conflict!
 0x80	00-1F	linux/fb.h
 0x81	00-1F	linux/videotext.h
+0x88	00-3F	media/ovcamchip.h
 0x89	00-06	arch/x86/include/asm/sockios.h
 0x89	0B-DF	linux/sockios.h
 0x89	E0-EF	linux/sockios.h		SIOCPROTOPRIVATE range
+0x89	E0-EF	linux/dn.h		PROTOPRIVATE range
 0x89	F0-FF	linux/sockios.h		SIOCDEVPRIVATE range
 0x8B	all	linux/wireless.h
 0x8C	00-3F				WiNRADiO driver
 					<http://www.proximity.com.au/~brian/winradio/>
 0x90	00	drivers/cdrom/sbpcd.h
+0x92	00-0F	drivers/usb/mon/mon_bin.c
 0x93	60-7F	linux/auto_fs.h
+0x94	all	fs/btrfs/ioctl.h
 0x99	00-0F				537-Addinboard driver
 					<mailto:buk@buks.ipn.de>
 0xA0	all	linux/sdp/sdp.h		Industrial Device Project
@@ -192,17 +302,22 @@ Code	Seq#	Include File		Comments
 0xAB	00-1F	linux/nbd.h
 0xAC	00-1F	linux/raw.h
 0xAD	00	Netfilter device	in development:
-					<mailto:rusty@rustcorp.com.au>	
+					<mailto:rusty@rustcorp.com.au>
 0xAE	all	linux/kvm.h		Kernel-based Virtual Machine
 					<mailto:kvm@vger.kernel.org>
 0xB0	all	RATIO devices		in development:
 					<mailto:vgo@ratio.de>
 0xB1	00-1F	PPPoX			<mailto:mostrows@styx.uwaterloo.ca>
+0xC0	00-0F	linux/usb/iowarrior.h
 0xCB	00-1F	CBM serial IEC bus	in development:
 					<mailto:michael.klein@puffin.lb.shuttle.de>
+0xCD	01	linux/reiserfs_fs.h
+0xCF	02	fs/cifs/ioctl.c
+0xDB	00-0F	drivers/char/mwave/mwavepub.h
 0xDD	00-3F	ZFCP device driver	see drivers/s390/scsi/
 					<mailto:aherrman@de.ibm.com>
-0xF3	00-3F	video/sisfb.h		sisfb (in development)
+0xF3	00-3F	drivers/usb/misc/sisusbvga/sisusb.h	sisfb (in development)
 					<mailto:thomas@winischhofer.net>
 0xF4	00-1F	video/mbxfb.h		mbxfb
 					<mailto:raph@8d.com>
+0xFD	all	linux/dm-ioctl.h
diff -druNp linux-libre-2.6.32-gnu1/Documentation/IO-mapping.txt linux-libre-2.6.33-gnu1/Documentation/IO-mapping.txt
--- linux-libre-2.6.32-gnu1/Documentation/IO-mapping.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/IO-mapping.txt	2010-02-24 13:52:17.000000000 -0500
@@ -157,7 +157,7 @@ For such memory, you can do things like
 	 * access only the 640k-1MB area, so anything else
 	 * has to be remapped.
 	 */
-	char * baseptr = ioremap(0xFC000000, 1024*1024);
+	void __iomem *baseptr = ioremap(0xFC000000, 1024*1024);
 
 	/* write a 'A' to the offset 10 of the area */
 	writeb('A',baseptr+10);
diff -druNp linux-libre-2.6.32-gnu1/Documentation/isdn/README.gigaset linux-libre-2.6.33-gnu1/Documentation/isdn/README.gigaset
--- linux-libre-2.6.32-gnu1/Documentation/isdn/README.gigaset	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/isdn/README.gigaset	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,7 @@ GigaSet 307x Device Driver
      ------------
 1.1. Hardware
      --------
-     This release supports the connection of the Gigaset 307x/417x family of
+     This driver supports the connection of the Gigaset 307x/417x family of
      ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB
      connection. The following devices are reported to be compatible:
 
@@ -33,7 +33,7 @@ GigaSet 307x Device Driver
               http://gigaset307x.sourceforge.net/
 
      We had also reports from users of Gigaset M105 who could use the drivers
-     with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.4.)
+     with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.5.)
      If you have another device that works with our driver, please let us know.
 
      Chances of getting an USB device to work are good if the output of
@@ -49,7 +49,7 @@ GigaSet 307x Device Driver
      --------
      The driver works with ISDN4linux and so can be used with any software
      which is able to use ISDN4linux for ISDN connections (voice or data).
-     CAPI4Linux support is planned but not yet available.
+     Experimental Kernel CAPI support is available as a compilation option.
 
      There are some user space tools available at
      http://sourceforge.net/projects/gigaset307x/
@@ -68,22 +68,38 @@ GigaSet 307x Device Driver
      for troubleshooting or to pass module parameters.
 
      The module ser_gigaset provides a serial line discipline N_GIGASET_M101
-     which drives the device through the regular serial line driver. It must
-     be attached to the serial line to which the M101 is connected with the
-     ldattach(8) command (requires util-linux-ng release 2.14 or later), for
-     example:
-	 ldattach GIGASET_M101 /dev/ttyS1
+     which uses the regular serial port driver to access the device, and must
+     therefore be attached to the serial device to which the M101 is connected.
+     The ldattach(8) command (included in util-linux-ng release 2.14 or later)
+     can be used for that purpose, for example:
+	ldattach GIGASET_M101 /dev/ttyS1
      This will open the device file, attach the line discipline to it, and
      then sleep in the background, keeping the device open so that the line
      discipline remains active. To deactivate it, kill the daemon, for example
      with
-	 killall ldattach
+	killall ldattach
      before disconnecting the device. To have this happen automatically at
      system startup/shutdown on an LSB compatible system, create and activate
      an appropriate LSB startup script /etc/init.d/gigaset. (The init name
      'gigaset' is officially assigned to this project by LANANA.)
      Alternatively, just add the 'ldattach' command line to /etc/rc.local.
 
+     The modules accept the following parameters:
+
+	Module	 	Parameter  Meaning
+
+	gigaset	 	debug	   debug level (see section 3.2.)
+
+			startmode  initial operation mode (see section 2.5.):
+	bas_gigaset )		   1=ISDN4linux/CAPI (default), 0=Unimodem
+	ser_gigaset )
+	usb_gigaset )	cidmode    initial Call-ID mode setting (see section
+				   2.5.): 1=on (default), 0=off
+
+     Depending on your distribution you may want to create a separate module
+     configuration file /etc/modprobe.d/gigaset for these, or add them to a
+     custom file like /etc/modprobe.conf.local.
+
 2.2. Device nodes for user space programs
      ------------------------------------
      The device can be accessed from user space (eg. by the user space tools
@@ -93,29 +109,83 @@ GigaSet 307x Device Driver
      - /dev/ttyGU0 for M105 (USB data boxes)
      - /dev/ttyGB0 for the base driver (direct USB connection)
 
-     You can also select a "default device" which is used by the frontends when
+     If you connect more than one device of a type, they will get consecutive
+     device nodes, eg. /dev/ttyGU1 for a second M105.
+
+     You can also set a "default device" for the user space tools to use when
      no device node is given as parameter, by creating a symlink /dev/ttyG to
      one of them, eg.:
 
-        ln -s /dev/ttyGB0 /dev/ttyG
+	ln -s /dev/ttyGB0 /dev/ttyG
+
+     The devices accept the following device specific ioctl calls
+     (defined in gigaset_dev.h):
+
+     ioctl(int fd, GIGASET_REDIR, int *cmd);
+     If cmd==1, the device is set to be controlled exclusively through the
+     character device node; access from the ISDN subsystem is blocked.
+     If cmd==0, the device is set to be used from the ISDN subsystem and does
+     not communicate through the character device node.
+
+     ioctl(int fd, GIGASET_CONFIG, int *cmd);
+     (ser_gigaset and usb_gigaset only)
+     If cmd==1, the device is set to adapter configuration mode where commands
+     are interpreted by the M10x DECT adapter itself instead of being
+     forwarded to the base station. In this mode, the device accepts the
+     commands described in Siemens document "AT-Kommando Alignment M10x Data"
+     for setting the operation mode, associating with a base station and
+     querying parameters like field strengh and signal quality.
+     Note that there is no ioctl command for leaving adapter configuration
+     mode and returning to regular operation. In order to leave adapter
+     configuration mode, write the command ATO to the device.
+
+     ioctl(int fd, GIGASET_BRKCHARS, unsigned char brkchars[6]);
+     (usb_gigaset only)
+     Set the break characters on an M105's internal serial adapter to the six
+     bytes stored in brkchars[]. Unused bytes should be set to zero.
+
+     ioctl(int fd, GIGASET_VERSION, unsigned version[4]);
+     Retrieve version information from the driver. version[0] must be set to
+     one of:
+     - GIGVER_DRIVER: retrieve driver version
+     - GIGVER_COMPAT: retrieve interface compatibility version
+     - GIGVER_FWBASE: retrieve the firmware version of the base
+     Upon return, version[] is filled with the requested version information.
 
 2.3. ISDN4linux
      ----------
      This is the "normal" mode of operation. After loading the module you can
-     set up the ISDN system just as you'd do with any ISDN card.
-     Your distribution should provide some configuration utility.
-     If not, you can use some HOWTOs like
+     set up the ISDN system just as you'd do with any ISDN card supported by
+     the ISDN4Linux subsystem. Most distributions provide some configuration
+     utility. If not, you can use some HOWTOs like
          http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html
-     If this doesn't work, because you have some recent device like SX100 where
+     If this doesn't work, because you have some device like SX100 where
      debug output (see section 3.2.) shows something like this when dialing
          CMD Received: ERROR
          Available Params: 0
          Connection State: 0, Response: -1
          gigaset_process_response: resp_code -1 in ConState 0 !
          Timeout occurred
-     you might need to use unimodem mode:
+     you probably need to use unimodem mode. (see section 2.5.)
 
-2.4. Unimodem mode
+2.4. CAPI
+     ----
+     If the driver is compiled with CAPI support (kernel configuration option
+     GIGASET_CAPI, experimental) it can also be used with CAPI 2.0 kernel and
+     user space applications. For user space access, the module capi.ko must
+     be loaded. The capiinit command (included in the capi4k-utils package)
+     does this for you.
+
+     The CAPI variant of the driver supports legacy ISDN4Linux applications
+     via the capidrv compatibility driver. The kernel module capidrv.ko must
+     be loaded explicitly with the command
+        modprobe capidrv
+     if needed, and cannot be unloaded again without unloading the driver
+     first. (These are limitations of capidrv.)
+
+     The note about unimodem mode in the preceding section applies here, too.
+
+2.5. Unimodem mode
      -------------
      This is needed for some devices [e.g. SX100] as they have problems with
      the "normal" commands.
@@ -126,9 +196,14 @@ GigaSet 307x Device Driver
      You can switch back using
          gigacontr --mode isdn
 
-     You can also load the driver using e.g.
-         modprobe usb_gigaset startmode=0
-     to prevent the driver from starting in "isdn4linux mode".
+     You can also put the driver directly into Unimodem mode when it's loaded,
+     by passing the module parameter startmode=0 to the hardware specific
+     module, e.g.
+	modprobe usb_gigaset startmode=0
+     or by adding a line like
+	options usb_gigaset startmode=0
+     to an appropriate module configuration file, like /etc/modprobe.d/gigaset
+     or /etc/modprobe.conf.local.
 
      In this mode the device works like a modem connected to a serial port
      (the /dev/ttyGU0, ... mentioned above) which understands the commands
@@ -156,11 +231,10 @@ GigaSet 307x Device Driver
 
         options ppp_async flag_time=0
 
-     to /etc/modprobe.conf. If your distribution has some local module
-     configuration file like /etc/modprobe.conf.local,
-     using that should be preferred.
+     to an appropriate module configuration file, like /etc/modprobe.d/gigaset
+     or /etc/modprobe.conf.local.
 
-2.5. Call-ID (CID) mode
+2.6. Call-ID (CID) mode
      ------------------
      Call-IDs are numbers used to tag commands to, and responses from, the
      Gigaset base in order to support the simultaneous handling of multiple
@@ -181,14 +255,15 @@ GigaSet 307x Device Driver
        settings (CID mode).
      - If you have several DECT data devices (M10x) which you want to use
        in turn, select Unimodem mode by passing the parameter "cidmode=0" to
-       the driver ("modprobe usb_gigaset cidmode=0" or modprobe.conf).
+       the appropriate driver module (ser_gigaset or usb_gigaset).
 
      If you want both of these at once, you are out of luck.
 
-     You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
-     setting (ttyGxy is ttyGU0 or ttyGB0).
+     You can also use the tty class parameter "cidmode" of the device to
+     change its CID mode while the driver is loaded, eg.
+        echo 0 > /sys/class/tty/ttyGU0/cidmode
 
-2.6. Unregistered Wireless Devices (M101/M105)
+2.7. Unregistered Wireless Devices (M101/M105)
      -----------------------------------------
      The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
      the M101 and M105 wireless devices to be used as ISDN devices for ISDN
@@ -200,7 +275,7 @@ GigaSet 307x Device Driver
      driver. In that situation, a restricted set of functions is available
      which includes, in particular, those necessary for registering the device
      to a base or for switching it between Fixed Part and Portable Part
-     modes.
+     modes. See the gigacontr(8) manpage for details.
 
 3.   Troubleshooting
      ---------------
@@ -214,9 +289,7 @@ GigaSet 307x Device Driver
 
            options isdn dialtimeout=15
 
-        to /etc/modprobe.conf. If your distribution has some local module
-        configuration file like /etc/modprobe.conf.local,
-        using that should be preferred.
+        to /etc/modprobe.d/gigaset, /etc/modprobe.conf.local or a similar file.
 
      Problem:
         Your isdn script aborts with a message about isdnlog.
@@ -228,7 +301,7 @@ GigaSet 307x Device Driver
         You have two or more DECT data adapters (M101/M105) and only the
         first one you turn on works.
      Solution:
-        Select Unimodem mode for all DECT data adapters. (see section 2.4.)
+        Select Unimodem mode for all DECT data adapters. (see section 2.5.)
 
      Problem:
 	Messages like this:
@@ -236,7 +309,7 @@ GigaSet 307x Device Driver
 	appear in your syslog.
      Solution:
 	Check whether your M10x wireless device is correctly registered to the
-	Gigaset base. (see section 2.6.)
+	Gigaset base. (see section 2.7.)
 
 3.2. Telling the driver to provide more information
      ----------------------------------------------
@@ -256,7 +329,8 @@ GigaSet 307x Device Driver
      The initial value can be set using the debug parameter when loading the
      module "gigaset", e.g. by adding a line
         options gigaset debug=0
-     to /etc/modprobe.conf, ...
+     to your module configuration file, eg. /etc/modprobe.d/gigaset or
+     /etc/modprobe.conf.local.
 
      Generated debugging information can be found
      - as output of the command
diff -druNp linux-libre-2.6.32-gnu1/Documentation/kbuild/kbuild.txt linux-libre-2.6.33-gnu1/Documentation/kbuild/kbuild.txt
--- linux-libre-2.6.32-gnu1/Documentation/kbuild/kbuild.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/kbuild/kbuild.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,17 @@
+Output files
+
+modules.order
+--------------------------------------------------
+This file records the order in which modules appear in Makefiles. This
+is used by modprobe to deterministically resolve aliases that match
+multiple modules.
+
+modules.builtin
+--------------------------------------------------
+This file lists all modules that are built into the kernel. This is used
+by modprobe to not fail when trying to load something builtin.
+
+
 Environment variables
 
 KCPPFLAGS
diff -druNp linux-libre-2.6.32-gnu1/Documentation/kbuild/kconfig.txt linux-libre-2.6.33-gnu1/Documentation/kbuild/kconfig.txt
--- linux-libre-2.6.32-gnu1/Documentation/kbuild/kconfig.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/kbuild/kconfig.txt	2010-02-24 13:52:17.000000000 -0500
@@ -103,10 +103,16 @@ KCONFIG_AUTOCONFIG
 This environment variable can be set to specify the path & name of the
 "auto.conf" file.  Its default value is "include/config/auto.conf".
 
+KCONFIG_TRISTATE
+--------------------------------------------------
+This environment variable can be set to specify the path & name of the
+"tristate.conf" file.  Its default value is "include/config/tristate.conf".
+
 KCONFIG_AUTOHEADER
 --------------------------------------------------
 This environment variable can be set to specify the path & name of the
-"autoconf.h" (header) file.  Its default value is "include/linux/autoconf.h".
+"autoconf.h" (header) file.
+Its default value is "include/generated/autoconf.h".
 
 
 ======================================================================
diff -druNp linux-libre-2.6.32-gnu1/Documentation/kernel-doc-nano-HOWTO.txt linux-libre-2.6.33-gnu1/Documentation/kernel-doc-nano-HOWTO.txt
--- linux-libre-2.6.32-gnu1/Documentation/kernel-doc-nano-HOWTO.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/kernel-doc-nano-HOWTO.txt	2010-02-24 13:52:17.000000000 -0500
@@ -214,11 +214,13 @@ The format of the block comment is like
  * (section header: (section description)? )*
 (*)?*/
 
-The short function description ***cannot be multiline***, but the other
-descriptions can be (and they can contain blank lines).  If you continue
-that initial short description onto a second line, that second line will
-appear further down at the beginning of the description section, which is
-almost certainly not what you had in mind.
+All "description" text can span multiple lines, although the
+function_name & its short description are traditionally on a single line.
+Description text may also contain blank lines (i.e., lines that contain
+only a "*").
+
+"section header:" names must be unique per function (or struct,
+union, typedef, enum).
 
 Avoid putting a spurious blank line after the function name, or else the
 description will be repeated!
diff -druNp linux-libre-2.6.32-gnu1/Documentation/kernel-parameters.txt linux-libre-2.6.33-gnu1/Documentation/kernel-parameters.txt
--- linux-libre-2.6.32-gnu1/Documentation/kernel-parameters.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/kernel-parameters.txt	2010-02-24 13:52:17.000000000 -0500
@@ -85,7 +85,6 @@ parameter is applicable:
 	PPT	Parallel port support is enabled.
 	PS2	Appropriate PS/2 support is enabled.
 	RAM	RAM disk support is enabled.
-	ROOTPLUG The example Root Plug LSM is enabled.
 	S390	S390 architecture is enabled.
 	SCSI	Appropriate SCSI support is enabled.
 			A lot of drivers has their options described inside of
@@ -200,6 +199,10 @@ and is between 256 and 4096 characters.
 			acpi_display_output=video
 			See above.
 
+	acpi_early_pdc_eval	[HW,ACPI] Evaluate processor _PDC methods
+				early. Needed on some platforms to properly
+				initialize the EC.
+
 	acpi_irq_balance [HW,ACPI]
 			ACPI will balance active IRQs
 			default in APIC mode
@@ -241,7 +244,7 @@ and is between 256 and 4096 characters.
 
 	acpi_sleep=	[HW,ACPI] Sleep options
 			Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
-				  old_ordering, s4_nonvs }
+				  old_ordering, s4_nonvs, sci_force_enable }
 			See Documentation/power/video.txt for information on
 			s3_bios and s3_mode.
 			s3_beep is for debugging; it makes the PC's speaker beep
@@ -254,6 +257,9 @@ and is between 256 and 4096 characters.
 			of _PTS is used by default).
 			s4_nonvs prevents the kernel from saving/restoring the
 			ACPI NVS memory during hibernation.
+			sci_force_enable causes the kernel to set SCI_EN directly
+			on resume from S1/S3 (which is against the ACPI spec,
+			but some broken systems don't work without it).
 
 	acpi_use_timer_override [HW,ACPI]
 			Use timer override. For some broken Nvidia NF5 boards
@@ -309,6 +315,11 @@ and is between 256 and 4096 characters.
 	aic79xx=	[HW,SCSI]
 			See Documentation/scsi/aic79xx.txt.
 
+	alignment=	[KNL,ARM]
+			Allow the default userspace alignment fault handler
+			behaviour to be specified.  Bit 0 enables warnings,
+			bit 1 enables fixups, and bit 2 sends a segfault.
+
 	amd_iommu=	[HW,X86-84]
 			Pass parameters to the AMD IOMMU driver in the system.
 			Possible values are:
@@ -345,6 +356,15 @@ and is between 256 and 4096 characters.
 			Change the amount of debugging information output
 			when initialising the APIC and IO-APIC components.
 
+	show_lapic=	[APIC,X86] Advanced Programmable Interrupt Controller
+			Limit apic dumping. The parameter defines the maximal
+			number of local apics being dumped. Also it is possible
+			to set it to "all" by meaning -- no limit here.
+			Format: { 1 (default) | 2 | ... | all }.
+			The parameter valid if only apic=debug or
+			apic=verbose is specified.
+			Example: apic=debug show_lapic=all
+
 	apm=		[APM] Advanced Power Management
 			See header of arch/x86/kernel/apm_32.c.
 
@@ -779,6 +799,13 @@ and is between 256 and 4096 characters.
 			by the set_ftrace_notrace file in the debugfs
 			tracing directory.
 
+	ftrace_graph_filter=[function-list]
+			[FTRACE] Limit the top level callers functions traced
+			by the function graph tracer at boot up.
+			function-list is a comma separated list of functions
+			that can be changed at run time by the
+			set_graph_function file in the debugfs tracing directory.
+
 	gamecon.map[2|3]=
 			[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
 			support via parallel port (up to 5 devices per port)
@@ -1017,7 +1044,7 @@ and is between 256 and 4096 characters.
 			No delay
 
 	ip=		[IP_PNP]
-			See Documentation/filesystems/nfsroot.txt.
+			See Documentation/filesystems/nfs/nfsroot.txt.
 
 	ip2=		[HW] Set IO/IRQ pairs for up to 4 IntelliPort boards
 			See comment before ip2_setup() in
@@ -1538,10 +1565,10 @@ and is between 256 and 4096 characters.
 			going to be removed in 2.6.29.
 
 	nfsaddrs=	[NFS]
-			See Documentation/filesystems/nfsroot.txt.
+			See Documentation/filesystems/nfs/nfsroot.txt.
 
 	nfsroot=	[NFS] nfs root filesystem for disk-less boxes.
-			See Documentation/filesystems/nfsroot.txt.
+			See Documentation/filesystems/nfs/nfsroot.txt.
 
 	nfs.callback_tcpport=
 			[NFS] set the TCP port on which the NFSv4 callback
@@ -1772,6 +1799,11 @@ and is between 256 and 4096 characters.
 			waiting for the ACK, so if this is set too high
 			interrupts *may* be lost!
 
+	omap_mux=	[OMAP] Override bootloader pin multiplexing.
+			Format: <mux_mode0.mode_name=value>...
+			For example, to override I2C bus2:
+			omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100
+
 	opl3=		[HW,OSS]
 			Format: <io>
 
@@ -2032,8 +2064,15 @@ and is between 256 and 4096 characters.
 
 	print-fatal-signals=
 			[KNL] debug: print fatal signals
-			print-fatal-signals=1: print segfault info to
-			the kernel console.
+
+			If enabled, warn about various signal handling
+			related application anomalies: too many signals,
+			too many POSIX.1 timers, fatal signals causing a
+			coredump - etc.
+
+			If you hit the warning due to signal overflow,
+			you might want to try "ulimit -i unlimited".
+
 			default: off.
 
 	printk.time=	Show timing data prefixed to each printk message line
@@ -2164,15 +2203,6 @@ and is between 256 and 4096 characters.
 			Useful for devices that are detected asynchronously
 			(e.g. USB and MMC devices).
 
-	root_plug.vendor_id=
-			[ROOTPLUG] Override the default vendor ID
-
-	root_plug.product_id=
-			[ROOTPLUG] Override the default product ID
-
-	root_plug.debug=
-			[ROOTPLUG] Enable debugging output
-
 	rw		[KNL] Mount root device read-write on boot
 
 	S		[KNL] Run init in single mode
@@ -2182,6 +2212,8 @@ and is between 256 and 4096 characters.
 
 	sbni=		[NET] Granch SBNI12 leased line adapter
 
+	sched_debug	[KNL] Enables verbose scheduler debug messages.
+
 	sc1200wdt=	[HW,WDT] SC1200 WDT (watchdog) driver
 			Format: <io>[,<timeout>[,<isapnp>]]
 
@@ -2590,6 +2622,9 @@ and is between 256 and 4096 characters.
 	uart6850=	[HW,OSS]
 			Format: <io>,<irq>
 
+	uhash_entries=	[KNL,NET]
+			Set number of hash buckets for UDP/UDP-Lite connections
+
 	uhci-hcd.ignore_oc=
 			[USB] Ignore overcurrent events (default N).
 			Some badly-designed motherboards generate lots of
@@ -2645,6 +2680,8 @@ and is between 256 and 4096 characters.
 			to a common usb-storage quirk flag as follows:
 				a = SANE_SENSE (collect more than 18 bytes
 					of sense data);
+				b = BAD_SENSE (don't collect more than 18
+					bytes of sense data);
 				c = FIX_CAPACITY (decrease the reported
 					device capacity by one sector);
 				h = CAPACITY_HEURISTICS (decrease the
@@ -2704,6 +2741,11 @@ and is between 256 and 4096 characters.
 	vmpoff=		[KNL,S390] Perform z/VM CP command after power off.
 			Format: <command>
 
+	vt.cur_default=	[VT] Default cursor shape.
+			Format: 0xCCBBAA, where AA, BB, and CC are the same as
+			the parameters of the <Esc>[?A;B;Cc escape sequence;
+			see VGA-softcursor.txt. Default: 2 = underline.
+
 	vt.default_blu=	[VT]
 			Format: <blue0>,<blue1>,<blue2>,...,<blue15>
 			Change the default blue palette of the console.
@@ -2729,6 +2771,15 @@ and is between 256 and 4096 characters.
 			Default is 1, i.e. UTF-8 mode is enabled for all
 			newly opened terminals.
 
+	vt.global_cursor_default=
+			[VT]
+			Format=<-1|0|1>
+			Set system-wide default for whether a cursor
+			is shown on new VTs. Default is -1,
+			i.e. cursors will be created by default unless
+			overridden by individual drivers. 0 will hide
+			cursors, 1 will display them.
+
 	waveartist=	[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/kvm/api.txt linux-libre-2.6.33-gnu1/Documentation/kvm/api.txt
--- linux-libre-2.6.32-gnu1/Documentation/kvm/api.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/kvm/api.txt	2010-02-24 13:52:17.000000000 -0500
@@ -593,6 +593,123 @@ struct kvm_irqchip {
 	} chip;
 };
 
+4.27 KVM_XEN_HVM_CONFIG
+
+Capability: KVM_CAP_XEN_HVM
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_xen_hvm_config (in)
+Returns: 0 on success, -1 on error
+
+Sets the MSR that the Xen HVM guest uses to initialize its hypercall
+page, and provides the starting address and size of the hypercall
+blobs in userspace.  When the guest writes the MSR, kvm copies one
+page of a blob (32- or 64-bit, depending on the vcpu mode) to guest
+memory.
+
+struct kvm_xen_hvm_config {
+	__u32 flags;
+	__u32 msr;
+	__u64 blob_addr_32;
+	__u64 blob_addr_64;
+	__u8 blob_size_32;
+	__u8 blob_size_64;
+	__u8 pad2[30];
+};
+
+4.27 KVM_GET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (out)
+Returns: 0 on success, -1 on error
+
+Gets the current timestamp of kvmclock as seen by the current guest. In
+conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+	__u64 clock;  /* kvmclock current value */
+	__u32 flags;
+	__u32 pad[9];
+};
+
+4.28 KVM_SET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (in)
+Returns: 0 on success, -1 on error
+
+Sets the current timestamp of kvmclock to the valued specific in its parameter.
+In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+	__u64 clock;  /* kvmclock current value */
+	__u32 flags;
+	__u32 pad[9];
+};
+
+4.29 KVM_GET_VCPU_EVENTS
+
+Capability: KVM_CAP_VCPU_EVENTS
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_vcpu_event (out)
+Returns: 0 on success, -1 on error
+
+Gets currently pending exceptions, interrupts, and NMIs as well as related
+states of the vcpu.
+
+struct kvm_vcpu_events {
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 has_error_code;
+		__u8 pad;
+		__u32 error_code;
+	} exception;
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 soft;
+		__u8 pad;
+	} interrupt;
+	struct {
+		__u8 injected;
+		__u8 pending;
+		__u8 masked;
+		__u8 pad;
+	} nmi;
+	__u32 sipi_vector;
+	__u32 flags;
+};
+
+4.30 KVM_SET_VCPU_EVENTS
+
+Capability: KVM_CAP_VCPU_EVENTS
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_vcpu_event (in)
+Returns: 0 on success, -1 on error
+
+Set pending exceptions, interrupts, and NMIs as well as related states of the
+vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Keep the
+corresponding bits in the flags field cleared to suppress overwriting the
+current in-kernel state. The bits are:
+
+KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel
+KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector
+
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
diff -druNp linux-libre-2.6.32-gnu1/Documentation/laptops/thinkpad-acpi.txt linux-libre-2.6.33-gnu1/Documentation/laptops/thinkpad-acpi.txt
--- linux-libre-2.6.32-gnu1/Documentation/laptops/thinkpad-acpi.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/laptops/thinkpad-acpi.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 		     ThinkPad ACPI Extras Driver
 
-                            Version 0.23
-                          April 10th, 2009
+                            Version 0.24
+                        December 11th,  2009
 
                Borislav Deianov <borislav@users.sf.net>
              Henrique de Moraes Holschuh <hmh@hmh.eng.br>
@@ -460,6 +460,8 @@ event	code	Key		Notes
 				For Lenovo ThinkPads with a new
 				BIOS, it has to be handled either
 				by the ACPI OSI, or by userspace.
+				The driver does the right thing,
+				never mess with this.
 0x1011	0x10	FN+END		Brightness down.  See brightness
 				up for details.
 
@@ -582,46 +584,15 @@ with hotkey_report_mode.
 
 Brightness hotkey notes:
 
-These are the current sane choices for brightness key mapping in
-thinkpad-acpi:
-
-For IBM and Lenovo models *without* ACPI backlight control (the ones on
-which thinkpad-acpi will autoload its backlight interface by default,
-and on which ACPI video does not export a backlight interface):
-
-1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as
-   these older firmware versions unfortunately won't respect the hotkey
-   mask for brightness keys anyway, and always reacts to them.  This
-   usually work fine, unless X.org drivers are doing something to block
-   the BIOS.  In that case, use (3) below.  This is the default mode of
-   operation.
-
-2. Enable the hotkeys, but map them to something else that is NOT
-   KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause
-   userspace to try to change the backlight level, and use that as an
-   on-screen-display hint.
-
-3. IF AND ONLY IF X.org drivers find a way to block the firmware from
-   automatically changing the brightness, enable the hotkeys and map
-   them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to
-   something that calls xbacklight.  thinkpad-acpi will not be able to
-   change brightness in that case either, so you should disable its
-   backlight interface.
-
-For Lenovo models *with* ACPI backlight control:
-
-1. Load up ACPI video and use that.  ACPI video will report ACPI
-   events for brightness change keys.  Do not mess with thinkpad-acpi
-   defaults in this case.  thinkpad-acpi should not have anything to do
-   with backlight events in a scenario where ACPI video is loaded:
-   brightness hotkeys must be disabled, and the backlight interface is
-   to be kept disabled as well.  This is the default mode of operation.
+Don't mess with the brightness hotkeys in a Thinkpad.  If you want
+notifications for OSD, use the sysfs backlight class event support.
 
-2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi,
-   and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN.  Process
-   these keys on userspace somehow (e.g. by calling xbacklight).
-   The driver will do this automatically if it detects that ACPI video
-   has been disabled.
+The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events
+automatically for the cases were userspace has to do something to
+implement brightness changes.  When you override these events, you will
+either fail to handle properly the ThinkPads that require explicit
+action to change backlight brightness, or the ThinkPads that require
+that no action be taken to work properly.
 
 
 Bluetooth
@@ -1121,25 +1092,103 @@ WARNING:
     its level up and down at every change.
 
 
-Volume control -- /proc/acpi/ibm/volume
----------------------------------------
+Volume control (Console Audio control)
+--------------------------------------
 
-This feature allows volume control on ThinkPad models which don't have
-a hardware volume knob. The available commands are:
+procfs: /proc/acpi/ibm/volume
+ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC"
+
+NOTE: by default, the volume control interface operates in read-only
+mode, as it is supposed to be used for on-screen-display purposes.
+The read/write mode can be enabled through the use of the
+"volume_control=1" module parameter.
+
+NOTE: distros are urged to not enable volume_control by default, this
+should be done by the local admin only.  The ThinkPad UI is for the
+console audio control to be done through the volume keys only, and for
+the desktop environment to just provide on-screen-display feedback.
+Software volume control should be done only in the main AC97/HDA
+mixer.
+
+
+About the ThinkPad Console Audio control:
+
+ThinkPads have a built-in amplifier and muting circuit that drives the
+console headphone and speakers.  This circuit is after the main AC97
+or HDA mixer in the audio path, and under exclusive control of the
+firmware.
+
+ThinkPads have three special hotkeys to interact with the console
+audio control: volume up, volume down and mute.
+
+It is worth noting that the normal way the mute function works (on
+ThinkPads that do not have a "mute LED") is:
+
+1. Press mute to mute.  It will *always* mute, you can press it as
+   many times as you want, and the sound will remain mute.
+
+2. Press either volume key to unmute the ThinkPad (it will _not_
+   change the volume, it will just unmute).
+
+This is a very superior design when compared to the cheap software-only
+mute-toggle solution found on normal consumer laptops:  you can be
+absolutely sure the ThinkPad will not make noise if you press the mute
+button, no matter the previous state.
+
+The IBM ThinkPads, and the earlier Lenovo ThinkPads have variable-gain
+amplifiers driving the speakers and headphone output, and the firmware
+also handles volume control for the headphone and speakers on these
+ThinkPads without any help from the operating system (this volume
+control stage exists after the main AC97 or HDA mixer in the audio
+path).
+
+The newer Lenovo models only have firmware mute control, and depend on
+the main HDA mixer to do volume control (which is done by the operating
+system).  In this case, the volume keys are filtered out for unmute
+key press (there are some firmware bugs in this area) and delivered as
+normal key presses to the operating system (thinkpad-acpi is not
+involved).
+
+
+The ThinkPad-ACPI volume control:
+
+The preferred way to interact with the Console Audio control is the
+ALSA interface.
+
+The legacy procfs interface allows one to read the current state,
+and if volume control is enabled, accepts the following commands:
 
 	echo up   >/proc/acpi/ibm/volume
 	echo down >/proc/acpi/ibm/volume
 	echo mute >/proc/acpi/ibm/volume
+	echo unmute >/proc/acpi/ibm/volume
 	echo 'level <level>' >/proc/acpi/ibm/volume
 
-The <level> number range is 0 to 15 although not all of them may be
-distinct. The unmute the volume after the mute command, use either the
-up or down command (the level command will not unmute the volume).
-The current volume level and mute state is shown in the file.
+The <level> number range is 0 to 14 although not all of them may be
+distinct. To unmute the volume after the mute command, use either the
+up or down command (the level command will not unmute the volume), or
+the unmute command.
 
-The ALSA mixer interface to this feature is still missing, but patches
-to add it exist.  That problem should be addressed in the not so
-distant future.
+You can use the volume_capabilities parameter to tell the driver
+whether your thinkpad has volume control or mute-only control:
+volume_capabilities=1 for mixers with mute and volume control,
+volume_capabilities=2 for mixers with only mute control.
+
+If the driver misdetects the capabilities for your ThinkPad model,
+please report this to ibm-acpi-devel@lists.sourceforge.net, so that we
+can update the driver.
+
+There are two strategies for volume control.  To select which one
+should be used, use the volume_mode module parameter: volume_mode=1
+selects EC mode, and volume_mode=3 selects EC mode with NVRAM backing
+(so that volume/mute changes are remembered across shutdown/reboot).
+
+The driver will operate in volume_mode=3 by default. If that does not
+work well on your ThinkPad model, please report this to
+ibm-acpi-devel@lists.sourceforge.net.
+
+The driver supports the standard ALSA module parameters.  If the ALSA
+mixer is disabled, the driver will disable all volume functionality.
 
 
 Fan control and monitoring: fan speed, fan enable/disable
@@ -1405,6 +1454,7 @@ to enable more than one output class, ju
 	0x0008			HKEY event interface, hotkeys
 	0x0010			Fan control
 	0x0020			Backlight brightness
+	0x0040			Audio mixer/volume control
 
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
@@ -1465,3 +1515,9 @@ Sysfs interface changelog:
 		and it is always able to disable hot keys.  Very old
 		thinkpads are properly supported.  hotkey_bios_mask
 		is deprecated and marked for removal.
+
+0x020600:	Marker for backlight change event support.
+
+0x020700:	Support for mute-only mixers.
+		Volume control in read-only mode by default.
+		Marker for ALSA mixer support.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/lguest/lguest.c linux-libre-2.6.33-gnu1/Documentation/lguest/lguest.c
--- linux-libre-2.6.32-gnu1/Documentation/lguest/lguest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/lguest/lguest.c	2010-02-24 13:52:17.000000000 -0500
@@ -304,7 +304,7 @@ static void *map_zeroed_pages(unsigned i
 	addr = mmap(NULL, getpagesize() * num,
 		    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
 	if (addr == MAP_FAILED)
-		err(1, "Mmaping %u pages of /dev/zero", num);
+		err(1, "Mmapping %u pages of /dev/zero", num);
 
 	/*
 	 * One neat mmap feature is that you can close the fd, and it
diff -druNp linux-libre-2.6.32-gnu1/Documentation/lockstat.txt linux-libre-2.6.33-gnu1/Documentation/lockstat.txt
--- linux-libre-2.6.32-gnu1/Documentation/lockstat.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/lockstat.txt	2010-02-24 13:52:17.000000000 -0500
@@ -62,8 +62,20 @@ applicable).
 It also tracks 4 contention points per class. A contention point is a call site
 that had to wait on lock acquisition.
 
+ - CONFIGURATION
+
+Lock statistics are enabled via CONFIG_LOCK_STATS.
+
  - USAGE
 
+Enable collection of statistics:
+
+# echo 1 >/proc/sys/kernel/lock_stat
+
+Disable collection of statistics:
+
+# echo 0 >/proc/sys/kernel/lock_stat
+
 Look at the current lock statistics:
 
 ( line numbers not part of actual output, done for clarity in the explanation
diff -druNp linux-libre-2.6.32-gnu1/Documentation/md.txt linux-libre-2.6.33-gnu1/Documentation/md.txt
--- linux-libre-2.6.32-gnu1/Documentation/md.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/md.txt	2010-02-24 13:52:17.000000000 -0500
@@ -233,9 +233,9 @@ All md devices contain:
 
   resync_start
      The point at which resync should start.  If no resync is needed,
-     this will be a very large number.  At array creation it will
-     default to 0, though starting the array as 'clean' will
-     set it much larger.
+     this will be a very large number (or 'none' since 2.6.30-rc1).  At
+     array creation it will default to 0, though starting the array as
+     'clean' will set it much larger.
 
    new_dev
      This file can be written but not read.  The value written should
@@ -296,6 +296,51 @@ All md devices contain:
      active-idle
          like active, but no writes have been seen for a while (safe_mode_delay).
 
+  bitmap/location
+     This indicates where the write-intent bitmap for the array is
+     stored.
+     It can be one of "none", "file" or "[+-]N".
+     "file" may later be extended to "file:/file/name"
+     "[+-]N" means that many sectors from the start of the metadata.
+       This is replicated on all devices.  For arrays with externally
+       managed metadata, the offset is from the beginning of the
+       device.
+  bitmap/chunksize
+     The size, in bytes, of the chunk which will be represented by a
+     single bit.  For RAID456, it is a portion of an individual
+     device. For RAID10, it is a portion of the array.  For RAID1, it
+     is both (they come to the same thing).
+  bitmap/time_base
+     The time, in seconds, between looking for bits in the bitmap to
+     be cleared. In the current implementation, a bit will be cleared
+     between 2 and 3 times "time_base" after all the covered blocks
+     are known to be in-sync.
+  bitmap/backlog
+     When write-mostly devices are active in a RAID1, write requests
+     to those devices proceed in the background - the filesystem (or
+     other user of the device) does not have to wait for them.
+     'backlog' sets a limit on the number of concurrent background
+     writes.  If there are more than this, new writes will by
+     synchronous.
+  bitmap/metadata
+     This can be either 'internal' or 'external'.
+     'internal' is the default and means the metadata for the bitmap
+     is stored in the first 256 bytes of the allocated space and is
+     managed by the md module.
+     'external' means that bitmap metadata is managed externally to
+     the kernel (i.e. by some userspace program)
+  bitmap/can_clear
+     This is either 'true' or 'false'.  If 'true', then bits in the
+     bitmap will be cleared when the corresponding blocks are thought
+     to be in-sync.  If 'false', bits will never be cleared.
+     This is automatically set to 'false' if a write happens on a
+     degraded array, or if the array becomes degraded during a write.
+     When metadata is managed externally, it should be set to true
+     once the array becomes non-degraded, and this fact has been
+     recorded in the metadata.
+     
+     
+     
 
 As component devices are added to an md array, they appear in the 'md'
 directory as new directories named
@@ -334,8 +379,9 @@ Each directory contains:
 	Writing "writemostly" sets the writemostly flag.
 	Writing "-writemostly" clears the writemostly flag.
 	Writing "blocked" sets the "blocked" flag.
-	Writing "-blocked" clear the "blocked" flag and allows writes
+	Writing "-blocked" clears the "blocked" flag and allows writes
 		to complete.
+	Writing "in_sync" sets the in_sync flag.
 
 	This file responds to select/poll. Any change to 'faulty'
 	or 'blocked' causes an event.
@@ -372,6 +418,24 @@ Each directory contains:
         array.  If a value less than the current component_size is
         written, it will be rejected.
 
+      recovery_start
+
+        When the device is not 'in_sync', this records the number of
+	sectors from the start of the device which are known to be
+	correct.  This is normally zero, but during a recovery
+	operation is will steadily increase, and if the recovery is
+	interrupted, restoring this value can cause recovery to
+	avoid repeating the earlier blocks.  With v1.x metadata, this
+	value is saved and restored automatically.
+
+	This can be set whenever the device is not an active member of
+	the array, either before the array is activated, or before
+	the 'slot' is set.
+
+	Setting this to 'none' is equivalent to setting 'in_sync'.
+	Setting to any other value also clears the 'in_sync' flag.
+	
+
 
 An active md device will also contain and entry for each active device
 in the array.  These are named
diff -druNp linux-libre-2.6.32-gnu1/Documentation/memory-hotplug.txt linux-libre-2.6.33-gnu1/Documentation/memory-hotplug.txt
--- linux-libre-2.6.32-gnu1/Documentation/memory-hotplug.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/memory-hotplug.txt	2010-02-24 13:52:17.000000000 -0500
@@ -160,12 +160,15 @@ Under each section, you can see 4 files.
 NOTE:
   These directories/files appear after physical memory hotplug phase.
 
-If CONFIG_NUMA is enabled the
-/sys/devices/system/memory/memoryXXX memory section
-directories can also be accessed via symbolic links located in
-the /sys/devices/system/node/node* directories.  For example:
+If CONFIG_NUMA is enabled the memoryXXX/ directories can also be accessed
+via symbolic links located in the /sys/devices/system/node/node* directories.
+
+For example:
 /sys/devices/system/node/node0/memory9 -> ../../memory/memory9
 
+A backlink will also be created:
+/sys/devices/system/memory/memory9/node0 -> ../../node/node0
+
 --------------------------------
 4. Physical memory hot-add phase
 --------------------------------
diff -druNp linux-libre-2.6.32-gnu1/Documentation/misc-devices/ad525x_dpot.txt linux-libre-2.6.33-gnu1/Documentation/misc-devices/ad525x_dpot.txt
--- linux-libre-2.6.32-gnu1/Documentation/misc-devices/ad525x_dpot.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/misc-devices/ad525x_dpot.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+---------------------------------
+  AD525x Digital Potentiometers
+---------------------------------
+
+The ad525x_dpot driver exports a simple sysfs interface.  This allows you to
+work with the immediate resistance settings as well as update the saved startup
+settings.  Access to the factory programmed tolerance is also provided, but
+interpretation of this settings is required by the end application according to
+the specific part in use.
+
+---------
+  Files
+---------
+
+Each dpot device will have a set of eeprom, rdac, and tolerance files.  How
+many depends on the actual part you have, as will the range of allowed values.
+
+The eeprom files are used to program the startup value of the device.
+
+The rdac files are used to program the immediate value of the device.
+
+The tolerance files are the read-only factory programmed tolerance settings
+and may vary greatly on a part-by-part basis.  For exact interpretation of
+this field, please consult the datasheet for your part.  This is presented
+as a hex file for easier parsing.
+
+-----------
+  Example
+-----------
+
+Locate the device in your sysfs tree.  This is probably easiest by going into
+the common i2c directory and locating the device by the i2c slave address.
+
+	# ls /sys/bus/i2c/devices/
+	0-0022  0-0027  0-002f
+
+So assuming the device in question is on the first i2c bus and has the slave
+address of 0x2f, we descend (unrelated sysfs entries have been trimmed).
+
+	# ls /sys/bus/i2c/devices/0-002f/
+	eeprom0 rdac0 tolerance0
+
+You can use simple reads/writes to access these files:
+
+	# cd /sys/bus/i2c/devices/0-002f/
+
+	# cat eeprom0
+	0
+	# echo 10 > eeprom0
+	# cat eeprom0
+	10
+
+	# cat rdac0
+	5
+	# echo 3 > rdac0
+	# cat rdac0
+	3
diff -druNp linux-libre-2.6.32-gnu1/Documentation/misc-devices/c2port.txt linux-libre-2.6.33-gnu1/Documentation/misc-devices/c2port.txt
--- linux-libre-2.6.32-gnu1/Documentation/misc-devices/c2port.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/misc-devices/c2port.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,90 @@
+			C2 port support
+			---------------
+
+(C) Copyright 2007 Rodolfo Giometti <giometti@enneenne.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.
+
+
+
+Overview
+--------
+
+This driver implements the support for Linux of Silicon Labs (Silabs)
+C2 Interface used for in-system programming of micro controllers.
+
+By using this driver you can reprogram the in-system flash without EC2
+or EC3 debug adapter. This solution is also useful in those systems
+where the micro controller is connected via special GPIOs pins.
+
+References
+----------
+
+The C2 Interface main references are at (http://www.silabs.com)
+Silicon Laboratories site], see:
+
+- AN127: FLASH Programming via the C2 Interface at
+http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Small_Form_Factor/en/an127.pdf, and
+
+- C2 Specification at
+http://www.silabs.com/public/documents/tpub_doc/spec/Microcontrollers/en/C2spec.pdf,
+
+however it implements a two wire serial communication protocol (bit
+banging) designed to enable in-system programming, debugging, and
+boundary-scan testing on low pin-count Silicon Labs devices. Currently
+this code supports only flash programming but extensions are easy to
+add.
+
+Using the driver
+----------------
+
+Once the driver is loaded you can use sysfs support to get C2port's
+info or read/write in-system flash.
+
+# ls /sys/class/c2port/c2port0/
+access            flash_block_size  flash_erase       rev_id
+dev_id            flash_blocks_num  flash_size        subsystem/
+flash_access      flash_data        reset             uevent
+
+Initially the C2port access is disabled since you hardware may have
+such lines multiplexed with other devices so, to get access to the
+C2port, you need the command:
+
+# echo 1 > /sys/class/c2port/c2port0/access
+
+after that you should read the device ID and revision ID of the
+connected micro controller:
+
+# cat /sys/class/c2port/c2port0/dev_id
+8
+# cat /sys/class/c2port/c2port0/rev_id
+1
+
+However, for security reasons, the in-system flash access in not
+enabled yet, to do so you need the command:
+
+# echo 1 > /sys/class/c2port/c2port0/flash_access
+
+After that you can read the whole flash:
+
+# cat /sys/class/c2port/c2port0/flash_data > image
+
+erase it:
+
+# echo 1 > /sys/class/c2port/c2port0/flash_erase
+
+and write it:
+
+# cat image > /sys/class/c2port/c2port0/flash_data
+
+after writing you have to reset the device to execute the new code:
+
+# echo 1 > /sys/class/c2port/c2port0/reset
diff -druNp linux-libre-2.6.32-gnu1/Documentation/misc-devices/ics932s401 linux-libre-2.6.33-gnu1/Documentation/misc-devices/ics932s401
--- linux-libre-2.6.32-gnu1/Documentation/misc-devices/ics932s401	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/misc-devices/ics932s401	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,31 @@
+Kernel driver ics932s401
+======================
+
+Supported chips:
+  * IDT ICS932S401
+    Prefix: 'ics932s401'
+    Addresses scanned: I2C 0x69
+    Datasheet: Publically available at the IDT website
+
+Author: Darrick J. Wong
+
+Description
+-----------
+
+This driver implements support for the IDT ICS932S401 chip family.
+
+This chip has 4 clock outputs--a base clock for the CPU (which is likely
+multiplied to get the real CPU clock), a system clock, a PCI clock, a USB
+clock, and a reference clock.  The driver reports selected and actual
+frequency.  If spread spectrum mode is enabled, the driver also reports by what
+percent the clock signal is being spread, which should be between 0 and -0.5%.
+All frequencies are reported in KHz.
+
+The ICS932S401 monitors all inputs continuously. The driver will not read
+the registers more often than once every other second.
+
+Special Features
+----------------
+
+The clocks could be reprogrammed to increase system speed.  I will not help you
+do this, as you risk damaging your system!
diff -druNp linux-libre-2.6.32-gnu1/Documentation/networking/3c509.txt linux-libre-2.6.33-gnu1/Documentation/networking/3c509.txt
--- linux-libre-2.6.32-gnu1/Documentation/networking/3c509.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/networking/3c509.txt	2010-02-24 13:52:17.000000000 -0500
@@ -48,11 +48,11 @@ for LILO parameters for doing this:
 This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
 transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
 with other card types when overriding the I/O address. When the driver is
-loaded as a module, only the IRQ and transceiver setting may be overridden.
-For example, setting two cards to 10base2/IRQ10 and AUI/IRQ11 is done by using
-the xcvr and irq module options:
+loaded as a module, only the IRQ may be overridden. For example,
+setting two cards to IRQ10 and IRQ11 is done by using the irq module
+option:
 
-   options 3c509 xcvr=3,1 irq=10,11
+   options 3c509 irq=10,11
 
 
 (2) Full-duplex mode
@@ -77,6 +77,8 @@ operation.
 itself full-duplex capable. This is almost certainly one of two things: a full-
 duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
 another system that's connected directly to the 3c509B via a crossover cable.
+
+Full-duplex mode can be enabled using 'ethtool'.
  
 /////Extremely important caution concerning full-duplex mode/////
 Understand that the 3c509B's hardware's full-duplex support is much more
@@ -113,6 +115,8 @@ This insured that merely upgrading the d
 never automatically enable full-duplex mode in an existing installation;
 it must always be explicitly enabled via one of these code in order to be
 activated.
+
+The transceiver type can be changed using 'ethtool'.
   
 
 (4a) Interpretation of error messages and common problems
diff -druNp linux-libre-2.6.32-gnu1/Documentation/networking/bonding.txt linux-libre-2.6.33-gnu1/Documentation/networking/bonding.txt
--- linux-libre-2.6.32-gnu1/Documentation/networking/bonding.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/networking/bonding.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 
 		Linux Ethernet Bonding Driver HOWTO
 
-		Latest update: 12 November 2007
+		Latest update: 23 September 2009
 
 Initial release : Thomas Davis <tadavis at lbl.gov>
 Corrections, HA extensions : 2000/10/03-15 :
@@ -614,6 +614,46 @@ primary
 
 	The primary option is only valid for active-backup mode.
 
+primary_reselect
+
+	Specifies the reselection policy for the primary slave.  This
+	affects how the primary slave is chosen to become the active slave
+	when failure of the active slave or recovery of the primary slave
+	occurs.  This option is designed to prevent flip-flopping between
+	the primary slave and other slaves.  Possible values are:
+
+	always or 0 (default)
+
+		The primary slave becomes the active slave whenever it
+		comes back up.
+
+	better or 1
+
+		The primary slave becomes the active slave when it comes
+		back up, if the speed and duplex of the primary slave is
+		better than the speed and duplex of the current active
+		slave.
+
+	failure or 2
+
+		The primary slave becomes the active slave only if the
+		current active slave fails and the primary slave is up.
+
+	The primary_reselect setting is ignored in two cases:
+
+		If no slaves are active, the first slave to recover is
+		made the active slave.
+
+		When initially enslaved, the primary slave is always made
+		the active slave.
+
+	Changing the primary_reselect policy via sysfs will cause an
+	immediate selection of the best active slave according to the new
+	policy.  This may or may not result in a change of the active
+	slave, depending upon the circumstances.
+
+	This option was added for bonding version 3.6.0.
+
 updelay
 
 	Specifies the time, in milliseconds, to wait before enabling a
diff -druNp linux-libre-2.6.32-gnu1/Documentation/networking/ip-sysctl.txt linux-libre-2.6.33-gnu1/Documentation/networking/ip-sysctl.txt
--- linux-libre-2.6.32-gnu1/Documentation/networking/ip-sysctl.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/networking/ip-sysctl.txt	2010-02-24 13:52:17.000000000 -0500
@@ -164,6 +164,14 @@ tcp_congestion_control - STRING
 	additional choices may be available based on kernel configuration.
 	Default is set as part of kernel configuration.
 
+tcp_cookie_size - INTEGER
+	Default size of TCP Cookie Transactions (TCPCT) option, that may be
+	overridden on a per socket basis by the TCPCT socket option.
+	Values greater than the maximum (16) are interpreted as the maximum.
+	Values greater than zero and less than the minimum (8) are interpreted
+	as the minimum.  Odd values are interpreted as the next even value.
+	Default: 0 (off).
+
 tcp_dsack - BOOLEAN
 	Allows TCP to send "duplicate" SACKs.
 
@@ -723,6 +731,12 @@ accept_source_route - BOOLEAN
 	default TRUE (router)
 		FALSE (host)
 
+accept_local - BOOLEAN
+	Accept packets with local source addresses. In combination with
+	suitable routing, this can be used to direct packets between two
+	local interfaces over the wire and have them accepted properly.
+	default FALSE
+
 rp_filter - INTEGER
 	0 - No source validation.
 	1 - Strict mode as defined in RFC3704 Strict Reverse Path
@@ -738,8 +752,8 @@ rp_filter - INTEGER
 	to prevent IP spoofing from DDos attacks. If using asymmetric routing
 	or other complicated routing, then loose mode is recommended.
 
-	conf/all/rp_filter must also be set to non-zero to do source validation
-	on the interface
+	The max value from conf/{all,interface}/rp_filter is used
+	when doing source validation on the {interface}.
 
 	Default value is 0. Note that some distributions enable it
 	in startup scripts.
@@ -1060,10 +1074,10 @@ regen_max_retry - INTEGER
 	Default: 5
 
 max_addresses - INTEGER
-	Number of maximum addresses per interface.  0 disables limitation.
-	It is recommended not set too large value (or 0) because it would
-	be too easy way to crash kernel to allow to create too much of
-	autoconfigured addresses.
+	Maximum number of autoconfigured addresses per interface.  Setting
+	to zero disables the limitation.  It is not recommended to set this
+	value too large (or to zero) because it would be an easy way to
+	crash the kernel by allowing too many addresses to be created.
 	Default: 16
 
 disable_ipv6 - BOOLEAN
@@ -1086,6 +1100,24 @@ accept_dad - INTEGER
 	2: Enable DAD, and disable IPv6 operation if MAC-based duplicate
 	   link-local address has been found.
 
+force_tllao - BOOLEAN
+	Enable sending the target link-layer address option even when
+	responding to a unicast neighbor solicitation.
+	Default: FALSE
+
+	Quoting from RFC 2461, section 4.4, Target link-layer address:
+
+	"The option MUST be included for multicast solicitations in order to
+	avoid infinite Neighbor Solicitation "recursion" when the peer node
+	does not have a cache entry to return a Neighbor Advertisements
+	message.  When responding to unicast solicitations, the option can be
+	omitted since the sender of the solicitation has the correct link-
+	layer address; otherwise it would not have be able to send the unicast
+	solicitation in the first place. However, including the link-layer
+	address in this case adds little overhead and eliminates a potential
+	race condition where the sender deletes the cached link-layer address
+	prior to receiving a response to a previous solicitation."
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/nommu-mmap.txt linux-libre-2.6.33-gnu1/Documentation/nommu-mmap.txt
--- linux-libre-2.6.32-gnu1/Documentation/nommu-mmap.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/nommu-mmap.txt	2010-02-24 13:52:17.000000000 -0500
@@ -119,6 +119,32 @@ FURTHER NOTES ON NO-MMU MMAP
      granule but will only discard the excess if appropriately configured as
      this has an effect on fragmentation.
 
+ (*) The memory allocated by a request for an anonymous mapping will normally
+     be cleared by the kernel before being returned in accordance with the
+     Linux man pages (ver 2.22 or later).
+
+     In the MMU case this can be achieved with reasonable performance as
+     regions are backed by virtual pages, with the contents only being mapped
+     to cleared physical pages when a write happens on that specific page
+     (prior to which, the pages are effectively mapped to the global zero page
+     from which reads can take place).  This spreads out the time it takes to
+     initialize the contents of a page - depending on the write-usage of the
+     mapping.
+
+     In the no-MMU case, however, anonymous mappings are backed by physical
+     pages, and the entire map is cleared at allocation time.  This can cause
+     significant delays during a userspace malloc() as the C library does an
+     anonymous mapping and the kernel then does a memset for the entire map.
+
+     However, for memory that isn't required to be precleared - such as that
+     returned by malloc() - mmap() can take a MAP_UNINITIALIZED flag to
+     indicate to the kernel that it shouldn't bother clearing the memory before
+     returning it.  Note that CONFIG_MMAP_ALLOW_UNINITIALIZED must be enabled
+     to permit this, otherwise the flag will be ignored.
+
+     uClibc uses this to speed up malloc(), and the ELF-FDPIC binfmt uses this
+     to allocate the brk and stack region.
+
  (*) A list of all the private copy and anonymous mappings on the system is
      visible through /proc/maps in no-MMU mode.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/oops-tracing.txt linux-libre-2.6.33-gnu1/Documentation/oops-tracing.txt
--- linux-libre-2.6.32-gnu1/Documentation/oops-tracing.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/oops-tracing.txt	2010-02-24 13:52:17.000000000 -0500
@@ -257,6 +257,8 @@ characters, each representing a particul
 
  10: 'W' if a warning has previously been issued by the kernel.
 
+ 11: 'C' if a staging driver has been loaded.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
diff -druNp linux-libre-2.6.32-gnu1/Documentation/PCI/PCI-DMA-mapping.txt linux-libre-2.6.33-gnu1/Documentation/PCI/PCI-DMA-mapping.txt
--- linux-libre-2.6.32-gnu1/Documentation/PCI/PCI-DMA-mapping.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/PCI/PCI-DMA-mapping.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,766 @@
+			Dynamic DMA mapping
+			===================
+
+		 David S. Miller <davem@redhat.com>
+		 Richard Henderson <rth@cygnus.com>
+		  Jakub Jelinek <jakub@redhat.com>
+
+This document describes the DMA mapping system in terms of the pci_
+API.  For a similar API that works for generic devices, see
+DMA-API.txt.
+
+Most of the 64bit platforms have special hardware that translates bus
+addresses (DMA addresses) into physical addresses.  This is similar to
+how page tables and/or a TLB translates virtual addresses to physical
+addresses on a CPU.  This is needed so that e.g. PCI devices can
+access with a Single Address Cycle (32bit DMA address) any page in the
+64bit physical address space.  Previously in Linux those 64bit
+platforms had to set artificial limits on the maximum RAM size in the
+system, so that the virt_to_bus() static scheme works (the DMA address
+translation tables were simply filled on bootup to map each bus
+address to the physical page __pa(bus_to_virt())).
+
+So that Linux can use the dynamic DMA mapping, it needs some help from the
+drivers, namely it has to take into account that DMA addresses should be
+mapped only for the time they are actually used and unmapped after the DMA
+transfer.
+
+The following API will work of course even on platforms where no such
+hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
+top of the virt_to_bus interface.
+
+First of all, you should make sure
+
+#include <linux/pci.h>
+
+is in your driver. This file will obtain for you the definition of the
+dma_addr_t (which can hold any valid DMA address for the platform)
+type which should be used everywhere you hold a DMA (bus) address
+returned from the DMA mapping functions.
+
+			 What memory is DMA'able?
+
+The first piece of information you must know is what kernel memory can
+be used with the DMA mapping facilities.  There has been an unwritten
+set of rules regarding this, and this text is an attempt to finally
+write them down.
+
+If you acquired your memory via the page allocator
+(i.e. __get_free_page*()) or the generic memory allocators
+(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
+that memory using the addresses returned from those routines.
+
+This means specifically that you may _not_ use the memory/addresses
+returned from vmalloc() for DMA.  It is possible to DMA to the
+_underlying_ memory mapped into a vmalloc() area, but this requires
+walking page tables to get the physical addresses, and then
+translating each of those pages back to a kernel address using
+something like __va().  [ EDIT: Update this when we integrate
+Gerd Knorr's generic code which does this. ]
+
+This rule also means that you may use neither kernel image addresses
+(items in data/text/bss segments), nor module image addresses, nor
+stack addresses for DMA.  These could all be mapped somewhere entirely
+different than the rest of physical memory.  Even if those classes of
+memory could physically work with DMA, you'd need to ensure the I/O
+buffers were cacheline-aligned.  Without that, you'd see cacheline
+sharing problems (data corruption) on CPUs with DMA-incoherent caches.
+(The CPU could write to one word, DMA would write to a different one
+in the same cache line, and one of them could be overwritten.)
+
+Also, this means that you cannot take the return of a kmap()
+call and DMA to/from that.  This is similar to vmalloc().
+
+What about block I/O and networking buffers?  The block I/O and
+networking subsystems make sure that the buffers they use are valid
+for you to DMA from/to.
+
+			DMA addressing limitations
+
+Does your device have any DMA addressing limitations?  For example, is
+your device only capable of driving the low order 24-bits of address
+on the PCI bus for SAC DMA transfers?  If so, you need to inform the
+PCI layer of this fact.
+
+By default, the kernel assumes that your device can address the full
+32-bits in a SAC cycle.  For a 64-bit DAC capable device, this needs
+to be increased.  And for a device with limitations, as discussed in
+the previous paragraph, it needs to be decreased.
+
+pci_alloc_consistent() by default will return 32-bit DMA addresses.
+PCI-X specification requires PCI-X devices to support 64-bit
+addressing (DAC) for all transactions. And at least one platform (SGI
+SN2) requires 64-bit consistent allocations to operate correctly when
+the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(),
+it's good practice to call pci_set_consistent_dma_mask() to set the
+appropriate mask even if your device only supports 32-bit DMA
+(default) and especially if it's a PCI-X device.
+
+For correct operation, you must interrogate the PCI layer in your
+device probe routine to see if the PCI controller on the machine can
+properly support the DMA addressing limitation your device has.  It is
+good style to do this even if your device holds the default setting,
+because this shows that you did think about these issues wrt. your
+device.
+
+The query is performed via a call to pci_set_dma_mask():
+
+	int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
+
+The query for consistent allocations is performed via a call to
+pci_set_consistent_dma_mask():
+
+	int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
+
+Here, pdev is a pointer to the PCI device struct of your device, and
+device_mask is a bit mask describing which bits of a PCI address your
+device supports.  It returns zero if your card can perform DMA
+properly on the machine given the address mask you provided.
+
+If it returns non-zero, your device cannot perform DMA properly on
+this platform, and attempting to do so will result in undefined
+behavior.  You must either use a different mask, or not use DMA.
+
+This means that in the failure case, you have three options:
+
+1) Use another DMA mask, if possible (see below).
+2) Use some non-DMA mode for data transfer, if possible.
+3) Ignore this device and do not initialize it.
+
+It is recommended that your driver print a kernel KERN_WARNING message
+when you end up performing either #2 or #3.  In this manner, if a user
+of your driver reports that performance is bad or that the device is not
+even detected, you can ask them for the kernel messages to find out
+exactly why.
+
+The standard 32-bit addressing PCI device would do something like
+this:
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+Another common scenario is a 64-bit capable device.  The approach
+here is to try for 64-bit DAC addressing, but back down to a
+32-bit mask should that fail.  The PCI platform code may fail the
+64-bit mask not because the platform is not capable of 64-bit
+addressing.  Rather, it may fail in this case simply because
+32-bit SAC addressing is done more efficiently than DAC addressing.
+Sparc64 is one platform which behaves in this way.
+
+Here is how you would handle a 64-bit capable device which can drive
+all 64-bits when accessing streaming DMA:
+
+	int using_dac;
+
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		using_dac = 1;
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+		using_dac = 0;
+	} else {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+If a card is capable of using 64-bit consistent allocations as well,
+the case would look like this:
+
+	int using_dac, consistent_using_dac;
+
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		using_dac = 1;
+	   	consistent_using_dac = 1;
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+		using_dac = 0;
+		consistent_using_dac = 0;
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	} else {
+		printk(KERN_WARNING
+		       "mydev: No suitable DMA available.\n");
+		goto ignore_this_device;
+	}
+
+pci_set_consistent_dma_mask() will always be able to set the same or a
+smaller mask as pci_set_dma_mask(). However for the rare case that a
+device driver only uses consistent allocations, one would have to
+check the return value from pci_set_consistent_dma_mask().
+
+Finally, if your device can only drive the low 24-bits of
+address during PCI bus mastering you might do something like:
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
+		printk(KERN_WARNING
+		       "mydev: 24-bit DMA addressing not available.\n");
+		goto ignore_this_device;
+	}
+
+When pci_set_dma_mask() is successful, and returns zero, the PCI layer
+saves away this mask you have provided.  The PCI layer will use this
+information later when you make DMA mappings.
+
+There is a case which we are aware of at this time, which is worth
+mentioning in this documentation.  If your device supports multiple
+functions (for example a sound card provides playback and record
+functions) and the various different functions have _different_
+DMA addressing limitations, you may wish to probe each mask and
+only provide the functionality which the machine can handle.  It
+is important that the last call to pci_set_dma_mask() be for the
+most specific mask.
+
+Here is pseudo-code showing how this might be done:
+
+	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
+	#define RECORD_ADDRESS_BITS	DMA_BIT_MASK(24)
+
+	struct my_sound_card *card;
+	struct pci_dev *pdev;
+
+	...
+	if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) {
+		card->playback_enabled = 1;
+	} else {
+		card->playback_enabled = 0;
+		printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
+		       card->name);
+	}
+	if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
+		card->record_enabled = 1;
+	} else {
+		card->record_enabled = 0;
+		printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
+		       card->name);
+	}
+
+A sound card was used as an example here because this genre of PCI
+devices seems to be littered with ISA chips given a PCI front end,
+and thus retaining the 16MB DMA addressing limitations of ISA.
+
+			Types of DMA mappings
+
+There are two types of DMA mappings:
+
+- Consistent DMA mappings which are usually mapped at driver
+  initialization, unmapped at the end and for which the hardware should
+  guarantee that the device and the CPU can access the data
+  in parallel and will see updates made by each other without any
+  explicit software flushing.
+
+  Think of "consistent" as "synchronous" or "coherent".
+
+  The current default is to return consistent memory in the low 32
+  bits of the PCI bus space.  However, for future compatibility you
+  should set the consistent mask even if this default is fine for your
+  driver.
+
+  Good examples of what to use consistent mappings for are:
+
+	- Network card DMA ring descriptors.
+	- SCSI adapter mailbox command data structures.
+	- Device firmware microcode executed out of
+	  main memory.
+
+  The invariant these examples all require is that any CPU store
+  to memory is immediately visible to the device, and vice
+  versa.  Consistent mappings guarantee this.
+
+  IMPORTANT: Consistent DMA memory does not preclude the usage of
+             proper memory barriers.  The CPU may reorder stores to
+	     consistent memory just as it may normal memory.  Example:
+	     if it is important for the device to see the first word
+	     of a descriptor updated before the second, you must do
+	     something like:
+
+		desc->word0 = address;
+		wmb();
+		desc->word1 = DESC_VALID;
+
+             in order to get correct behavior on all platforms.
+
+	     Also, on some platforms your driver may need to flush CPU write
+	     buffers in much the same way as it needs to flush write buffers
+	     found in PCI bridges (such as by reading a register's value
+	     after writing it).
+
+- Streaming DMA mappings which are usually mapped for one DMA transfer,
+  unmapped right after it (unless you use pci_dma_sync_* below) and for which
+  hardware can optimize for sequential accesses.
+
+  This of "streaming" as "asynchronous" or "outside the coherency
+  domain".
+
+  Good examples of what to use streaming mappings for are:
+
+	- Networking buffers transmitted/received by a device.
+	- Filesystem buffers written/read by a SCSI device.
+
+  The interfaces for using this type of mapping were designed in
+  such a way that an implementation can make whatever performance
+  optimizations the hardware allows.  To this end, when using
+  such mappings you must be explicit about what you want to happen.
+
+Neither type of DMA mapping has alignment restrictions that come
+from PCI, although some devices may have such restrictions.
+Also, systems with caches that aren't DMA-coherent will work better
+when the underlying buffers don't share cache lines with other data.
+
+
+		 Using Consistent DMA mappings.
+
+To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
+you should do:
+
+	dma_addr_t dma_handle;
+
+	cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
+
+where pdev is a struct pci_dev *. This may be called in interrupt context.
+You should use dma_alloc_coherent (see DMA-API.txt) for buses
+where devices don't have struct pci_dev (like ISA, EISA).
+
+This argument is needed because the DMA translations may be bus
+specific (and often is private to the bus which the device is attached
+to).
+
+Size is the length of the region you want to allocate, in bytes.
+
+This routine will allocate RAM for that region, so it acts similarly to
+__get_free_pages (but takes size instead of a page order).  If your
+driver needs regions sized smaller than a page, you may prefer using
+the pci_pool interface, described below.
+
+The consistent DMA mapping interfaces, for non-NULL pdev, will by
+default return a DMA address which is SAC (Single Address Cycle)
+addressable.  Even if the device indicates (via PCI dma mask) that it
+may address the upper 32-bits and thus perform DAC cycles, consistent
+allocation will only return > 32-bit PCI addresses for DMA if the
+consistent dma mask has been explicitly changed via
+pci_set_consistent_dma_mask().  This is true of the pci_pool interface
+as well.
+
+pci_alloc_consistent returns two values: the virtual address which you
+can use to access it from the CPU and dma_handle which you pass to the
+card.
+
+The cpu return address and the DMA bus master address are both
+guaranteed to be aligned to the smallest PAGE_SIZE order which
+is greater than or equal to the requested size.  This invariant
+exists (for example) to guarantee that if you allocate a chunk
+which is smaller than or equal to 64 kilobytes, the extent of the
+buffer you receive will not cross a 64K boundary.
+
+To unmap and free such a DMA region, you call:
+
+	pci_free_consistent(pdev, size, cpu_addr, dma_handle);
+
+where pdev, size are the same as in the above call and cpu_addr and
+dma_handle are the values pci_alloc_consistent returned to you.
+This function may not be called in interrupt context.
+
+If your driver needs lots of smaller memory regions, you can write
+custom code to subdivide pages returned by pci_alloc_consistent,
+or you can use the pci_pool API to do that.  A pci_pool is like
+a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
+Also, it understands common hardware constraints for alignment,
+like queue heads needing to be aligned on N byte boundaries.
+
+Create a pci_pool like this:
+
+	struct pci_pool *pool;
+
+	pool = pci_pool_create(name, pdev, size, align, alloc);
+
+The "name" is for diagnostics (like a kmem_cache name); pdev and size
+are as above.  The device's hardware alignment requirement for this
+type of data is "align" (which is expressed in bytes, and must be a
+power of two).  If your device has no boundary crossing restrictions,
+pass 0 for alloc; passing 4096 says memory allocated from this pool
+must not cross 4KByte boundaries (but at that time it may be better to
+go for pci_alloc_consistent directly instead).
+
+Allocate memory from a pci pool like this:
+
+	cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
+
+flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
+holding SMP locks), SLAB_ATOMIC otherwise.  Like pci_alloc_consistent,
+this returns two values, cpu_addr and dma_handle.
+
+Free memory that was allocated from a pci_pool like this:
+
+	pci_pool_free(pool, cpu_addr, dma_handle);
+
+where pool is what you passed to pci_pool_alloc, and cpu_addr and
+dma_handle are the values pci_pool_alloc returned. This function
+may be called in interrupt context.
+
+Destroy a pci_pool by calling:
+
+	pci_pool_destroy(pool);
+
+Make sure you've called pci_pool_free for all memory allocated
+from a pool before you destroy the pool. This function may not
+be called in interrupt context.
+
+			DMA Direction
+
+The interfaces described in subsequent portions of this document
+take a DMA direction argument, which is an integer and takes on
+one of the following values:
+
+ PCI_DMA_BIDIRECTIONAL
+ PCI_DMA_TODEVICE
+ PCI_DMA_FROMDEVICE
+ PCI_DMA_NONE
+
+One should provide the exact DMA direction if you know it.
+
+PCI_DMA_TODEVICE means "from main memory to the PCI device"
+PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
+It is the direction in which the data moves during the DMA
+transfer.
+
+You are _strongly_ encouraged to specify this as precisely
+as you possibly can.
+
+If you absolutely cannot know the direction of the DMA transfer,
+specify PCI_DMA_BIDIRECTIONAL.  It means that the DMA can go in
+either direction.  The platform guarantees that you may legally
+specify this, and that it will work, but this may be at the
+cost of performance for example.
+
+The value PCI_DMA_NONE is to be used for debugging.  One can
+hold this in a data structure before you come to know the
+precise direction, and this will help catch cases where your
+direction tracking logic has failed to set things up properly.
+
+Another advantage of specifying this value precisely (outside of
+potential platform-specific optimizations of such) is for debugging.
+Some platforms actually have a write permission boolean which DMA
+mappings can be marked with, much like page protections in the user
+program address space.  Such platforms can and do report errors in the
+kernel logs when the PCI controller hardware detects violation of the
+permission setting.
+
+Only streaming mappings specify a direction, consistent mappings
+implicitly have a direction attribute setting of
+PCI_DMA_BIDIRECTIONAL.
+
+The SCSI subsystem tells you the direction to use in the
+'sc_data_direction' member of the SCSI command your driver is
+working on.
+
+For Networking drivers, it's a rather simple affair.  For transmit
+packets, map/unmap them with the PCI_DMA_TODEVICE direction
+specifier.  For receive packets, just the opposite, map/unmap them
+with the PCI_DMA_FROMDEVICE direction specifier.
+
+		  Using Streaming DMA mappings
+
+The streaming DMA mapping routines can be called from interrupt
+context.  There are two versions of each map/unmap, one which will
+map/unmap a single memory region, and one which will map/unmap a
+scatterlist.
+
+To map a single region, you do:
+
+	struct pci_dev *pdev = mydev->pdev;
+	dma_addr_t dma_handle;
+	void *addr = buffer->ptr;
+	size_t size = buffer->len;
+
+	dma_handle = pci_map_single(pdev, addr, size, direction);
+
+and to unmap it:
+
+	pci_unmap_single(pdev, dma_handle, size, direction);
+
+You should call pci_unmap_single when the DMA activity is finished, e.g.
+from the interrupt which told you that the DMA transfer is done.
+
+Using cpu pointers like this for single mappings has a disadvantage,
+you cannot reference HIGHMEM memory in this way.  Thus, there is a
+map/unmap interface pair akin to pci_{map,unmap}_single.  These
+interfaces deal with page/offset pairs instead of cpu pointers.
+Specifically:
+
+	struct pci_dev *pdev = mydev->pdev;
+	dma_addr_t dma_handle;
+	struct page *page = buffer->page;
+	unsigned long offset = buffer->offset;
+	size_t size = buffer->len;
+
+	dma_handle = pci_map_page(pdev, page, offset, size, direction);
+
+	...
+
+	pci_unmap_page(pdev, dma_handle, size, direction);
+
+Here, "offset" means byte offset within the given page.
+
+With scatterlists, you map a region gathered from several regions by:
+
+	int i, count = pci_map_sg(pdev, sglist, nents, direction);
+	struct scatterlist *sg;
+
+	for_each_sg(sglist, sg, count, i) {
+		hw_address[i] = sg_dma_address(sg);
+		hw_len[i] = sg_dma_len(sg);
+	}
+
+where nents is the number of entries in the sglist.
+
+The implementation is free to merge several consecutive sglist entries
+into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
+consecutive sglist entries can be merged into one provided the first one
+ends and the second one starts on a page boundary - in fact this is a huge
+advantage for cards which either cannot do scatter-gather or have very
+limited number of scatter-gather entries) and returns the actual number
+of sg entries it mapped them to. On failure 0 is returned.
+
+Then you should loop count times (note: this can be less than nents times)
+and use sg_dma_address() and sg_dma_len() macros where you previously
+accessed sg->address and sg->length as shown above.
+
+To unmap a scatterlist, just call:
+
+	pci_unmap_sg(pdev, sglist, nents, direction);
+
+Again, make sure DMA activity has already finished.
+
+PLEASE NOTE:  The 'nents' argument to the pci_unmap_sg call must be
+              the _same_ one you passed into the pci_map_sg call,
+	      it should _NOT_ be the 'count' value _returned_ from the
+              pci_map_sg call.
+
+Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
+counterpart, because the bus address space is a shared resource (although
+in some ports the mapping is per each BUS so less devices contend for the
+same bus address space) and you could render the machine unusable by eating
+all bus addresses.
+
+If you need to use the same streaming DMA region multiple times and touch
+the data in between the DMA transfers, the buffer needs to be synced
+properly in order for the cpu and device to see the most uptodate and
+correct copy of the DMA buffer.
+
+So, firstly, just map it with pci_map_{single,sg}, and after each DMA
+transfer call either:
+
+	pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
+
+or:
+
+	pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
+
+as appropriate.
+
+Then, if you wish to let the device get at the DMA area again,
+finish accessing the data with the cpu, and then before actually
+giving the buffer to the hardware call either:
+
+	pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
+
+or:
+
+	pci_dma_sync_sg_for_device(dev, sglist, nents, direction);
+
+as appropriate.
+
+After the last DMA transfer call one of the DMA unmap routines
+pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
+call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
+routines at all.
+
+Here is pseudo code which shows a situation in which you would need
+to use the pci_dma_sync_*() interfaces.
+
+	my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
+	{
+		dma_addr_t mapping;
+
+		mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE);
+
+		cp->rx_buf = buffer;
+		cp->rx_len = len;
+		cp->rx_dma = mapping;
+
+		give_rx_buf_to_card(cp);
+	}
+
+	...
+
+	my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
+	{
+		struct my_card *cp = devid;
+
+		...
+		if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
+			struct my_card_header *hp;
+
+			/* Examine the header to see if we wish
+			 * to accept the data.  But synchronize
+			 * the DMA transfer with the CPU first
+			 * so that we see updated contents.
+			 */
+			pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma,
+						    cp->rx_len,
+						    PCI_DMA_FROMDEVICE);
+
+			/* Now it is safe to examine the buffer. */
+			hp = (struct my_card_header *) cp->rx_buf;
+			if (header_is_ok(hp)) {
+				pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len,
+						 PCI_DMA_FROMDEVICE);
+				pass_to_upper_layers(cp->rx_buf);
+				make_and_setup_new_rx_buf(cp);
+			} else {
+				/* Just sync the buffer and give it back
+				 * to the card.
+				 */
+				pci_dma_sync_single_for_device(cp->pdev,
+							       cp->rx_dma,
+							       cp->rx_len,
+							       PCI_DMA_FROMDEVICE);
+				give_rx_buf_to_card(cp);
+			}
+		}
+	}
+
+Drivers converted fully to this interface should not use virt_to_bus any
+longer, nor should they use bus_to_virt. Some drivers have to be changed a
+little bit, because there is no longer an equivalent to bus_to_virt in the
+dynamic DMA mapping scheme - you have to always store the DMA addresses
+returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
+calls (pci_map_sg stores them in the scatterlist itself if the platform
+supports dynamic DMA mapping in hardware) in your driver structures and/or
+in the card registers.
+
+All PCI drivers should be using these interfaces with no exceptions.
+It is planned to completely remove virt_to_bus() and bus_to_virt() as
+they are entirely deprecated.  Some ports already do not provide these
+as it is impossible to correctly support them.
+
+		Optimizing Unmap State Space Consumption
+
+On many platforms, pci_unmap_{single,page}() is simply a nop.
+Therefore, keeping track of the mapping address and length is a waste
+of space.  Instead of filling your drivers up with ifdefs and the like
+to "work around" this (which would defeat the whole purpose of a
+portable API) the following facilities are provided.
+
+Actually, instead of describing the macros one by one, we'll
+transform some example code.
+
+1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures.
+   Example, before:
+
+	struct ring_state {
+		struct sk_buff *skb;
+		dma_addr_t mapping;
+		__u32 len;
+	};
+
+   after:
+
+	struct ring_state {
+		struct sk_buff *skb;
+		DECLARE_PCI_UNMAP_ADDR(mapping)
+		DECLARE_PCI_UNMAP_LEN(len)
+	};
+
+   NOTE: DO NOT put a semicolon at the end of the DECLARE_*()
+         macro.
+
+2) Use pci_unmap_{addr,len}_set to set these values.
+   Example, before:
+
+	ringp->mapping = FOO;
+	ringp->len = BAR;
+
+   after:
+
+	pci_unmap_addr_set(ringp, mapping, FOO);
+	pci_unmap_len_set(ringp, len, BAR);
+
+3) Use pci_unmap_{addr,len} to access these values.
+   Example, before:
+
+	pci_unmap_single(pdev, ringp->mapping, ringp->len,
+			 PCI_DMA_FROMDEVICE);
+
+   after:
+
+	pci_unmap_single(pdev,
+			 pci_unmap_addr(ringp, mapping),
+			 pci_unmap_len(ringp, len),
+			 PCI_DMA_FROMDEVICE);
+
+It really should be self-explanatory.  We treat the ADDR and LEN
+separately, because it is possible for an implementation to only
+need the address in order to perform the unmap operation.
+
+			Platform Issues
+
+If you are just writing drivers for Linux and do not maintain
+an architecture port for the kernel, you can safely skip down
+to "Closing".
+
+1) Struct scatterlist requirements.
+
+   Struct scatterlist must contain, at a minimum, the following
+   members:
+
+	struct page *page;
+	unsigned int offset;
+	unsigned int length;
+
+   The base address is specified by a "page+offset" pair.
+
+   Previous versions of struct scatterlist contained a "void *address"
+   field that was sometimes used instead of page+offset.  As of Linux
+   2.5., page+offset is always used, and the "address" field has been
+   deleted.
+
+2) More to come...
+
+			Handling Errors
+
+DMA address space is limited on some architectures and an allocation
+failure can be determined by:
+
+- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0
+
+- checking the returned dma_addr_t of pci_map_single and pci_map_page
+  by using pci_dma_mapping_error():
+
+	dma_addr_t dma_handle;
+
+	dma_handle = pci_map_single(pdev, addr, size, direction);
+	if (pci_dma_mapping_error(pdev, dma_handle)) {
+		/*
+		 * reduce current DMA mapping usage,
+		 * delay and try again later or
+		 * reset driver.
+		 */
+	}
+
+			   Closing
+
+This document, and the API itself, would not be in it's current
+form without the feedback and suggestions from numerous individuals.
+We would like to specifically mention, in no particular order, the
+following people:
+
+	Russell King <rmk@arm.linux.org.uk>
+	Leo Dagum <dagum@barrel.engr.sgi.com>
+	Ralf Baechle <ralf@oss.sgi.com>
+	Grant Grundler <grundler@cup.hp.com>
+	Jay Estabrook <Jay.Estabrook@compaq.com>
+	Thomas Sailer <sailer@ife.ee.ethz.ch>
+	Andrea Arcangeli <andrea@suse.de>
+	Jens Axboe <jens.axboe@oracle.com>
+	David Mosberger-Tang <davidm@hpl.hp.com>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/pcmcia/driver-changes.txt linux-libre-2.6.33-gnu1/Documentation/pcmcia/driver-changes.txt
--- linux-libre-2.6.32-gnu1/Documentation/pcmcia/driver-changes.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/pcmcia/driver-changes.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,17 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
+   Instead of the cs_error() callback or the CS_CHECK() macro, please use
+   Linux-style checking of return values, and -- if necessary -- debug
+   messages using "dev_dbg()" or "pr_debug()".
+
+* New CIS tuple access (as of 2.6.33)
+   Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
+   pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
+   only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
+   interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
+   a new helper "pcmcia_get_mac_from_cis()" was added.
+
 * New configuration loop helper (as of 2.6.28)
    By calling pcmcia_loop_config(), a driver can iterate over all available
    configuration options. During a driver's probe() phase, one doesn't need
diff -druNp linux-libre-2.6.32-gnu1/Documentation/power/regulator/consumer.txt linux-libre-2.6.33-gnu1/Documentation/power/regulator/consumer.txt
--- linux-libre-2.6.32-gnu1/Documentation/power/regulator/consumer.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/power/regulator/consumer.txt	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,7 @@ to set the limit to 500mA when supplying
 
 Consumers can control their supply current limit by calling :-
 
-int regulator_set_current_limit(regulator, min_uV, max_uV);
+int regulator_set_current_limit(regulator, min_uA, max_uA);
 
 Where min_uA and max_uA are the minimum and maximum acceptable current limit in
 microamps.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/power/runtime_pm.txt linux-libre-2.6.33-gnu1/Documentation/power/runtime_pm.txt
--- linux-libre-2.6.32-gnu1/Documentation/power/runtime_pm.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/power/runtime_pm.txt	2010-02-24 13:52:17.000000000 -0500
@@ -38,83 +38,85 @@ struct dev_pm_ops {
 	...
 	int (*runtime_suspend)(struct device *dev);
 	int (*runtime_resume)(struct device *dev);
-	void (*runtime_idle)(struct device *dev);
+	int (*runtime_idle)(struct device *dev);
 	...
 };
 
-The ->runtime_suspend() callback is executed by the PM core for the bus type of
-the device being suspended.  The bus type's callback is then _entirely_
-_responsible_ for handling the device as appropriate, which may, but need not
-include executing the device driver's own ->runtime_suspend() callback (from the
+The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are
+executed by the PM core for either the bus type, or device type (if the bus
+type's callback is not defined), or device class (if the bus type's and device
+type's callbacks are not defined) of given device.  The bus type, device type
+and device class callbacks are referred to as subsystem-level callbacks in what
+follows.
+
+The subsystem-level suspend callback is _entirely_ _responsible_ for handling
+the suspend of the device as appropriate, which may, but need not include
+executing the device driver's own ->runtime_suspend() callback (from the
 PM core's point of view it is not necessary to implement a ->runtime_suspend()
-callback in a device driver as long as the bus type's ->runtime_suspend() knows
-what to do to handle the device).
+callback in a device driver as long as the subsystem-level suspend callback
+knows what to do to handle the device).
 
-  * Once the bus type's ->runtime_suspend() callback has completed successfully
+  * Once the subsystem-level suspend callback has completed successfully
     for given device, the PM core regards the device as suspended, which need
     not mean that the device has been put into a low power state.  It is
     supposed to mean, however, that the device will not process data and will
-    not communicate with the CPU(s) and RAM until its bus type's
-    ->runtime_resume() callback is executed for it.  The run-time PM status of
-    a device after successful execution of its bus type's ->runtime_suspend()
-    callback is 'suspended'.
+    not communicate with the CPU(s) and RAM until the subsystem-level resume
+    callback is executed for it.  The run-time PM status of a device after
+    successful execution of the subsystem-level suspend callback is 'suspended'.
 
-  * If the bus type's ->runtime_suspend() callback returns -EBUSY or -EAGAIN,
-    the device's run-time PM status is supposed to be 'active', which means that
-    the device _must_ be fully operational afterwards.
+  * If the subsystem-level suspend callback returns -EBUSY or -EAGAIN,
+    the device's run-time PM status is 'active', which means that the device
+    _must_ be fully operational afterwards.
 
-  * If the bus type's ->runtime_suspend() callback returns an error code
-    different from -EBUSY or -EAGAIN, the PM core regards this as a fatal
-    error and will refuse to run the helper functions described in Section 4
-    for the device, until the status of it is directly set either to 'active'
-    or to 'suspended' (the PM core provides special helper functions for this
-    purpose).
+  * If the subsystem-level suspend callback returns an error code different
+    from -EBUSY or -EAGAIN, the PM core regards this as a fatal error and will
+    refuse to run the helper functions described in Section 4 for the device,
+    until the status of it is directly set either to 'active', or to 'suspended'
+    (the PM core provides special helper functions for this purpose).
 
-In particular, if the driver requires remote wakeup capability for proper
-functioning and device_may_wakeup() returns 'false' for the device, then
-->runtime_suspend() should return -EBUSY.  On the other hand, if
-device_may_wakeup() returns 'true' for the device and the device is put
-into a low power state during the execution of its bus type's
-->runtime_suspend(), it is expected that remote wake-up (i.e. hardware mechanism
-allowing the device to request a change of its power state, such as PCI PME)
-will be enabled for the device.  Generally, remote wake-up should be enabled
-for all input devices put into a low power state at run time.
+In particular, if the driver requires remote wake-up capability (i.e. hardware
+mechanism allowing the device to request a change of its power state, such as
+PCI PME) for proper functioning and device_run_wake() returns 'false' for the
+device, then ->runtime_suspend() should return -EBUSY.  On the other hand, if
+device_run_wake() returns 'true' for the device and the device is put into a low
+power state during the execution of the subsystem-level suspend callback, it is
+expected that remote wake-up will be enabled for the device.  Generally, remote
+wake-up should be enabled for all input devices put into a low power state at
+run time.
 
-The ->runtime_resume() callback is executed by the PM core for the bus type of
-the device being woken up.  The bus type's callback is then _entirely_
-_responsible_ for handling the device as appropriate, which may, but need not
-include executing the device driver's own ->runtime_resume() callback (from the
-PM core's point of view it is not necessary to implement a ->runtime_resume()
-callback in a device driver as long as the bus type's ->runtime_resume() knows
-what to do to handle the device).
+The subsystem-level resume callback is _entirely_ _responsible_ for handling the
+resume of the device as appropriate, which may, but need not include executing
+the device driver's own ->runtime_resume() callback (from the PM core's point of
+view it is not necessary to implement a ->runtime_resume() callback in a device
+driver as long as the subsystem-level resume callback knows what to do to handle
+the device).
 
-  * Once the bus type's ->runtime_resume() callback has completed successfully,
-    the PM core regards the device as fully operational, which means that the
-    device _must_ be able to complete I/O operations as needed.  The run-time
-    PM status of the device is then 'active'.
+  * Once the subsystem-level resume callback has completed successfully, the PM
+    core regards the device as fully operational, which means that the device
+    _must_ be able to complete I/O operations as needed.  The run-time PM status
+    of the device is then 'active'.
 
-  * If the bus type's ->runtime_resume() callback returns an error code, the PM
-    core regards this as a fatal error and will refuse to run the helper
-    functions described in Section 4 for the device, until its status is
-    directly set either to 'active' or to 'suspended' (the PM core provides
-    special helper functions for this purpose).
+  * If the subsystem-level resume callback returns an error code, the PM core
+    regards this as a fatal error and will refuse to run the helper functions
+    described in Section 4 for the device, until its status is directly set
+    either to 'active' or to 'suspended' (the PM core provides special helper
+    functions for this purpose).
 
-The ->runtime_idle() callback is executed by the PM core for the bus type of
-given device whenever the device appears to be idle, which is indicated to the
-PM core by two counters, the device's usage counter and the counter of 'active'
-children of the device.
+The subsystem-level idle callback is executed by the PM core whenever the device
+appears to be idle, which is indicated to the PM core by two counters, the
+device's usage counter and the counter of 'active' children of the device.
 
   * If any of these counters is decreased using a helper function provided by
     the PM core and it turns out to be equal to zero, the other counter is
     checked.  If that counter also is equal to zero, the PM core executes the
-    device bus type's ->runtime_idle() callback (with the device as an
-    argument).
+    subsystem-level idle callback with the device as an argument.
 
-The action performed by a bus type's ->runtime_idle() callback is totally
-dependent on the bus type 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 action performed by a subsystem-level idle callback is totally dependent on
+the subsystem 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.
 
 The helper functions provided by the PM core, described in Section 4, guarantee
 that the following constraints are met with respect to the bus type's run-time
@@ -214,6 +216,9 @@ defined in include/linux/pm.h:
       being executed for that device and it is not practical to wait for the
       suspend to complete; means "start a resume as soon as you've suspended"
 
+  unsigned int run_wake;
+    - set if the device is capable of generating run-time wake-up events
+
   enum rpm_status runtime_status;
     - the run-time PM status of the device; this field's initial value is
       RPM_SUSPENDED, which means that each device is initially regarded by the
@@ -234,41 +239,41 @@ drivers/base/power/runtime.c and include
       removing the device from device hierarchy
 
   int pm_runtime_idle(struct device *dev);
-    - execute ->runtime_idle() for the device's bus type; 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 0 on
+      success or error code on failure, where -EINPROGRESS means that
+      ->runtime_idle() is already being executed
 
   int pm_runtime_suspend(struct device *dev);
-    - execute ->runtime_suspend() for the device's bus type; returns 0 on
+    - execute the subsystem-level suspend callback for the device; returns 0 on
       success, 1 if the device's run-time PM status was already 'suspended', or
       error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
       to suspend the device again in future
 
   int pm_runtime_resume(struct device *dev);
-    - execute ->runtime_resume() for the device's bus type; returns 0 on
+    - execute the subsystem-leve resume callback for the device; returns 0 on
       success, 1 if the device's run-time PM status was already 'active' or
       error code on failure, where -EAGAIN means it may be safe to attempt to
       resume the device again in future, but 'power.runtime_error' should be
       checked additionally
 
   int pm_request_idle(struct device *dev);
-    - submit a request to execute ->runtime_idle() for the device's bus type
-      (the request is represented by a work item in pm_wq); returns 0 on success
-      or error code if the request has not been queued up
+    - submit a request to execute the subsystem-level idle callback for the
+      device (the request is represented by a work item in pm_wq); returns 0 on
+      success or error code if the request has not been queued up
 
   int pm_schedule_suspend(struct device *dev, unsigned int delay);
-    - schedule the execution of ->runtime_suspend() for the device's bus type
-      in future, where 'delay' is the time to wait before queuing up a suspend
-      work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is
-      queued up immediately); returns 0 on success, 1 if the device's PM
+    - schedule the execution of the subsystem-level suspend callback for the
+      device in future, where 'delay' is the time to wait before queuing up a
+      suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work
+      item is queued up immediately); returns 0 on success, 1 if the device's PM
       run-time status was already 'suspended', or error code if the request
       hasn't been scheduled (or queued up if 'delay' is 0); if the execution of
       ->runtime_suspend() is already scheduled and not yet expired, the new
       value of 'delay' will be used as the time to wait
 
   int pm_request_resume(struct device *dev);
-    - submit a request to execute ->runtime_resume() for the device's bus type
-      (the request is represented by a work item in pm_wq); returns 0 on
+    - submit a request to execute the subsystem-level resume callback for the
+      device (the request is represented by a work item in pm_wq); returns 0 on
       success, 1 if the device's run-time PM status was already 'active', or
       error code if the request hasn't been queued up
 
@@ -299,12 +304,12 @@ drivers/base/power/runtime.c and include
       run-time PM callbacks described in Section 2
 
   int pm_runtime_disable(struct device *dev);
-    - prevent the run-time PM helper functions from running the device bus
-      type's run-time PM callbacks, make sure that all of the pending run-time
-      PM operations on the device are either completed or canceled; returns
-      1 if there was a resume request pending and it was necessary to execute
-      ->runtime_resume() for the device's bus type to satisfy that request,
-      otherwise 0 is returned
+    - prevent the run-time PM helper functions from running subsystem-level
+      run-time PM callbacks for the device, make sure that all of the pending
+      run-time PM operations on the device are either completed or canceled;
+      returns 1 if there was a resume request pending and it was necessary to
+      execute the subsystem-level resume callback for the device to satisfy that
+      request, otherwise 0 is returned
 
   void pm_suspend_ignore_children(struct device *dev, bool enable);
     - set/unset the power.ignore_children flag of the device
@@ -374,5 +379,55 @@ pm_runtime_suspend() or pm_runtime_idle(
 they will fail returning -EAGAIN, because the device's usage counter is
 incremented by the core before executing ->probe() and ->remove().  Still, it
 may be desirable to suspend the device as soon as ->probe() or ->remove() has
-finished, so the PM core uses pm_runtime_idle_sync() to invoke the device bus
-type's ->runtime_idle() callback at that time.
+finished, so the PM core uses pm_runtime_idle_sync() to invoke the
+subsystem-level idle callback for the device at that time.
+
+6. Run-time PM and System Sleep
+
+Run-time PM and system sleep (i.e., system suspend and hibernation, also known
+as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of
+ways.  If a device is active when a system sleep starts, everything is
+straightforward.  But what should happen if the device is already suspended?
+
+The device may have different wake-up settings for run-time PM and system sleep.
+For example, remote wake-up may be enabled for run-time suspend but disallowed
+for system sleep (device_may_wakeup(dev) returns 'false').  When this happens,
+the subsystem-level system suspend callback is responsible for changing the
+device's wake-up setting (it may leave that to the device driver's system
+suspend routine).  It may be necessary to resume the device and suspend it again
+in order to do so.  The same is true if the driver uses different power levels
+or other settings for run-time suspend and system sleep.
+
+During system resume, devices generally should be brought back to full power,
+even if they were suspended before the system sleep began.  There are several
+reasons for this, including:
+
+  * The device might need to switch power levels, wake-up settings, etc.
+
+  * Remote wake-up events might have been lost by the firmware.
+
+  * The device's children may need the device to be at full power in order
+    to resume themselves.
+
+  * The driver's idea of the device state may not agree with the device's
+    physical state.  This can happen during resume from hibernation.
+
+  * The device might need to be reset.
+
+  * Even though the device was suspended, if its usage counter was > 0 then most
+    likely it would need a run-time resume in the near future anyway.
+
+  * Always going back to full power is simplest.
+
+If the device was suspended before the sleep began, then its run-time PM status
+will have to be updated to reflect the actual post-system sleep status.  The way
+to do this is:
+
+	pm_runtime_disable(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
+The PM core always increments the run-time usage counter before calling the
+->prepare() callback and decrements it after calling the ->complete() callback.
+Hence disabling run-time PM temporarily like this will not cause any run-time
+suspend callbacks to be lost.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,93 @@
+PPC440SPe DMA/XOR (DMA Controller and XOR Accelerator)
+
+Device nodes needed for operation of the ppc440spe-adma driver
+are specified hereby. These are I2O/DMA, DMA and XOR nodes
+for DMA engines and Memory Queue Module node. The latter is used
+by ADMA driver for configuration of RAID-6 H/W capabilities of
+the PPC440SPe. In addition to the nodes and properties described
+below, the ranges property of PLB node must specify ranges for
+DMA devices.
+
+ i) The I2O node
+
+ Required properties:
+
+ - compatible		: "ibm,i2o-440spe";
+ - reg			: <registers mapping>
+ - dcr-reg		: <DCR registers range>
+
+ Example:
+
+	I2O: i2o@400100000 {
+		compatible = "ibm,i2o-440spe";
+		reg = <0x00000004 0x00100000 0x100>;
+		dcr-reg = <0x060 0x020>;
+	};
+
+
+ ii) The DMA node
+
+ Required properties:
+
+ - compatible		: "ibm,dma-440spe";
+ - cell-index		: 1 cell, hardware index of the DMA engine
+			  (typically 0x0 and 0x1 for DMA0 and DMA1)
+ - reg			: <registers mapping>
+ - dcr-reg		: <DCR registers range>
+ - interrupts		: <interrupt mapping for DMA0/1 interrupts sources:
+			   2 sources: DMAx CS FIFO Needs Service IRQ (on UIC0)
+			   and DMA Error IRQ (on UIC1). The latter is common
+			   for both DMA engines>.
+ - interrupt-parent	: needed for interrupt mapping
+
+ Example:
+
+	DMA0: dma0@400100100 {
+		compatible = "ibm,dma-440spe";
+		cell-index = <0>;
+		reg = <0x00000004 0x00100100 0x100>;
+		dcr-reg = <0x060 0x020>;
+		interrupt-parent = <&DMA0>;
+		interrupts = <0 1>;
+		#interrupt-cells = <1>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		interrupt-map = <
+			0 &UIC0 0x14 4
+			1 &UIC1 0x16 4>;
+	};
+
+
+ iii) XOR Accelerator node
+
+ Required properties:
+
+ - compatible		: "amcc,xor-accelerator";
+ - reg			: <registers mapping>
+ - interrupts		: <interrupt mapping for XOR interrupt source>
+ - interrupt-parent	: for interrupt mapping
+
+ Example:
+
+	xor-accel@400200000 {
+		compatible = "amcc,xor-accelerator";
+		reg = <0x00000004 0x00200000 0x400>;
+		interrupt-parent = <&UIC1>;
+		interrupts = <0x1f 4>;
+	};
+
+
+ iv) Memory Queue Module node
+
+ Required properties:
+
+ - compatible		: "ibm,mq-440spe";
+ - dcr-reg		: <DCR registers range>
+
+ Example:
+
+	MQ0: mq {
+		compatible = "ibm,mq-440spe";
+		dcr-reg = <0x040 0x020>;
+	};
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/board.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/board.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/board.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/board.txt	2010-02-24 13:52:17.000000000 -0500
@@ -20,12 +20,16 @@ Required properities:
 - compatible : should be "fsl,fpga-pixis".
 - reg : should contain the address and the length of the FPPGA register
   set.
+- interrupt-parent: should specify phandle for the interrupt controller.
+- interrupts : should specify event (wakeup) IRQ.
 
 Example (MPC8610HPCD):
 
 	board-control@e8000000 {
 		compatible = "fsl,fpga-pixis";
 		reg = <0xe8000000 32>;
+		interrupt-parent = <&mpic>;
+		interrupts = <8 8>;
 	};
 
 * Freescale BCSR GPIO banks
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,22 @@ fsl,mpc5200-gpt nodes
 ---------------------
 On the mpc5200 and 5200b, GPT0 has a watchdog timer function.  If the board
 design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'fsl,has-wdt'.
+include the empty property 'fsl,has-wdt'.  Note that this does not activate
+the watchdog.  The timer will function as a GPT if the timer api is used, and
+it will function as watchdog if the watchdog device is used.  The watchdog
+mode has priority over the gpt mode, i.e. if the watchdog is activated, any
+gpt api call to this timer will fail with -EBUSY.
+
+If you add the property
+	fsl,wdt-on-boot = <n>;
+GPT0 will be marked as in-use watchdog, i.e. blocking every gpt access to it.
+If n>0, the watchdog is started with a timeout of n seconds.  If n=0, the
+configuration of the watchdog is not touched.  This is useful in two cases:
+- just mark GPT0 as watchdog, blocking gpt accesses, and configure it later;
+- do not touch a configuration assigned by the boot loader which supervises
+  the boot process itself.
+
+The watchdog will respect the CONFIG_WATCHDOG_NOWAYOUT option.
 
 An mpc5200-gpt can be used as a single line GPIO controller.  To do so,
 add the following properties to the gpt node:
@@ -178,3 +193,13 @@ External interrupts:
 	external irq3:	interrupts = <1 3 n>;
 'n' is sense (0: level high, 1: edge rising, 2: edge falling 3: level low)
 
+fsl,mpc5200-mscan nodes
+-----------------------
+In addition to the required compatible-, reg- and interrupt-properites, you can
+also specify which clock source shall be used for the controller:
+
+- fsl,mscan-clock-source- a string describing the clock source. Valid values
+			  are:	"ip" for ip bus clock
+				"ref" for reference clock (XTAL)
+			  "ref" is default in case this property is not
+			  present.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/mpic.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpic.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/fsl/mpic.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/fsl/mpic.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,42 @@
+* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores
+
+The OpenPIC specification does not specify which interrupt source has to
+become which interrupt number. This is up to the software implementation
+of the interrupt controller. The only requirement is that every
+interrupt source has to have an unique interrupt number / vector number.
+To accomplish this the current implementation assigns the number zero to
+the first source, the number one to the second source and so on until
+all interrupt sources have their unique number.
+Usually the assigned vector number equals the interrupt number mentioned
+in the documentation for a given core / CPU. This is however not true
+for the e500 cores (MPC85XX CPUs) where the documentation distinguishes
+between internal and external interrupt sources and starts counting at
+zero for both of them.
+
+So what to write for external interrupt source X or internal interrupt
+source Y into the device tree? Here is an example:
+
+The memory map for the interrupt controller in the MPC8544[0] shows,
+that the first interrupt source starts at 0x5_0000 (PIC Register Address
+Map-Interrupt Source Configuration Registers). This source becomes the
+number zero therefore:
+ External interrupt 0 = interrupt number 0
+ External interrupt 1 = interrupt number 1
+ External interrupt 2 = interrupt number 2
+ ...
+Every interrupt number allocates 0x20 bytes register space. So to get
+its number it is sufficient to shift the lower 16bits to right by five.
+So for the external interrupt 10 we have:
+  0x0140 >> 5 = 10
+
+After the external sources, the internal sources follow. The in core I2C
+controller on the MPC8544 for instance has the internal source number
+27. Oo obtain its interrupt number we take the lower 16bits of its memory
+address (0x5_0560) and shift it right:
+ 0x0560 >> 5 = 43
+
+Therefore the I2C device node for the MPC8544 CPU has to have the
+interrupt number 43 specified in the device tree.
+
+[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual
+    MPC8544ERM Rev. 1 10/2007
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,109 @@
+
+Nintendo GameCube device tree
+=============================
+
+1) The "flipper" node
+
+  This node represents the multi-function "Flipper" chip, which packages
+  many of the devices found in the Nintendo GameCube.
+
+  Required properties:
+
+   - compatible : Should be "nintendo,flipper"
+
+1.a) The Video Interface (VI) node
+
+  Represents the interface between the graphics processor and a external
+  video encoder.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-vi"
+   - reg : should contain the VI registers location and length
+   - interrupts : should contain the VI interrupt
+
+1.b) The Processor Interface (PI) node
+
+  Represents the data and control interface between the main processor
+  and graphics and audio processor.
+
+  Required properties:
+
+  - compatible : should be "nintendo,flipper-pi"
+  - reg : should contain the PI registers location and length
+
+1.b.i) The "Flipper" interrupt controller node
+
+  Represents the interrupt controller within the "Flipper" chip.
+  The node for the "Flipper" interrupt controller must be placed under
+  the PI node.
+
+  Required properties:
+
+  - compatible : should be "nintendo,flipper-pic"
+
+1.c) The Digital Signal Procesor (DSP) node
+
+  Represents the digital signal processor interface, designed to offload
+  audio related tasks.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-dsp"
+   - reg : should contain the DSP registers location and length
+   - interrupts : should contain the DSP interrupt
+
+1.c.i) The Auxiliary RAM (ARAM) node
+
+  Represents the non cpu-addressable ram designed mainly to store audio
+  related information.
+  The ARAM node must be placed under the DSP node.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-aram"
+   - reg : should contain the ARAM start (zero-based) and length
+
+1.d) The Disk Interface (DI) node
+
+  Represents the interface used to communicate with mass storage devices.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-di"
+   - reg : should contain the DI registers location and length
+   - interrupts : should contain the DI interrupt
+
+1.e) The Audio Interface (AI) node
+
+  Represents the interface to the external 16-bit stereo digital-to-analog
+  converter.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-ai"
+   - reg : should contain the AI registers location and length
+   - interrupts : should contain the AI interrupt
+
+1.f) The Serial Interface (SI) node
+
+  Represents the interface to the four single bit serial interfaces.
+  The SI is a proprietary serial interface used normally to control gamepads.
+  It's NOT a RS232-type interface.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-si"
+   - reg : should contain the SI registers location and length
+   - interrupts : should contain the SI interrupt
+
+1.g) The External Interface (EXI) node
+
+  Represents the multi-channel SPI-like interface.
+
+  Required properties:
+
+   - compatible : should be "nintendo,flipper-exi"
+   - reg : should contain the EXI registers location and length
+   - interrupts : should contain the EXI interrupt
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/nintendo/wii.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/nintendo/wii.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/nintendo/wii.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/nintendo/wii.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,184 @@
+
+Nintendo Wii device tree
+========================
+
+0) The root node
+
+  This node represents the Nintendo Wii video game console.
+
+  Required properties:
+
+   - model : Should be "nintendo,wii"
+   - compatible : Should be "nintendo,wii"
+
+1) The "hollywood" node
+
+  This node represents the multi-function "Hollywood" chip, which packages
+  many of the devices found in the Nintendo Wii.
+
+  Required properties:
+
+   - compatible : Should be "nintendo,hollywood"
+
+1.a) The Video Interface (VI) node
+
+  Represents the interface between the graphics processor and a external
+  video encoder.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-vi","nintendo,flipper-vi"
+   - reg : should contain the VI registers location and length
+   - interrupts : should contain the VI interrupt
+
+1.b) The Processor Interface (PI) node
+
+  Represents the data and control interface between the main processor
+  and graphics and audio processor.
+
+  Required properties:
+
+  - compatible : should be "nintendo,hollywood-pi","nintendo,flipper-pi"
+  - reg : should contain the PI registers location and length
+
+1.b.i) The "Flipper" interrupt controller node
+
+  Represents the "Flipper" interrupt controller within the "Hollywood" chip.
+  The node for the "Flipper" interrupt controller must be placed under
+  the PI node.
+
+  Required properties:
+
+  - #interrupt-cells : <1>
+  - compatible : should be "nintendo,flipper-pic"
+  - interrupt-controller
+
+1.c) The Digital Signal Procesor (DSP) node
+
+  Represents the digital signal processor interface, designed to offload
+  audio related tasks.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-dsp","nintendo,flipper-dsp"
+   - reg : should contain the DSP registers location and length
+   - interrupts : should contain the DSP interrupt
+
+1.d) The Serial Interface (SI) node
+
+  Represents the interface to the four single bit serial interfaces.
+  The SI is a proprietary serial interface used normally to control gamepads.
+  It's NOT a RS232-type interface.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-si","nintendo,flipper-si"
+   - reg : should contain the SI registers location and length
+   - interrupts : should contain the SI interrupt
+
+1.e) The Audio Interface (AI) node
+
+  Represents the interface to the external 16-bit stereo digital-to-analog
+  converter.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-ai","nintendo,flipper-ai"
+   - reg : should contain the AI registers location and length
+   - interrupts : should contain the AI interrupt
+
+1.f) The External Interface (EXI) node
+
+  Represents the multi-channel SPI-like interface.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-exi","nintendo,flipper-exi"
+   - reg : should contain the EXI registers location and length
+   - interrupts : should contain the EXI interrupt
+
+1.g) The Open Host Controller Interface (OHCI) nodes
+
+  Represent the USB 1.x Open Host Controller Interfaces.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-usb-ohci","usb-ohci"
+   - reg : should contain the OHCI registers location and length
+   - interrupts : should contain the OHCI interrupt
+
+1.h) The Enhanced Host Controller Interface (EHCI) node
+
+  Represents the USB 2.0 Enhanced Host Controller Interface.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-usb-ehci","usb-ehci"
+   - reg : should contain the EHCI registers location and length
+   - interrupts : should contain the EHCI interrupt
+
+1.i) The Secure Digital Host Controller Interface (SDHCI) nodes
+
+  Represent the Secure Digital Host Controller Interfaces.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-sdhci","sdhci"
+   - reg : should contain the SDHCI registers location and length
+   - interrupts : should contain the SDHCI interrupt
+
+1.j) The Inter-Processsor Communication (IPC) node
+
+  Represent the Inter-Processor Communication interface. This interface
+  enables communications between the Broadway and the Starlet processors.
+
+   - compatible : should be "nintendo,hollywood-ipc"
+   - reg : should contain the IPC registers location and length
+   - interrupts : should contain the IPC interrupt
+
+1.k) The "Hollywood" interrupt controller node
+
+  Represents the "Hollywood" interrupt controller within the
+  "Hollywood" chip.
+
+  Required properties:
+
+  - #interrupt-cells : <1>
+  - compatible : should be "nintendo,hollywood-pic"
+  - reg : should contain the controller registers location and length
+  - interrupt-controller
+  - interrupts : should contain the cascade interrupt of the "flipper" pic
+  - interrupt-parent: should contain the phandle of the "flipper" pic
+
+1.l) The General Purpose I/O (GPIO) controller node
+
+  Represents the dual access 32 GPIO controller interface.
+
+  Required properties:
+
+  - #gpio-cells : <2>
+  - compatible : should be "nintendo,hollywood-gpio"
+  - reg : should contain the IPC registers location and length
+  - gpio-controller
+
+1.m) The control node
+
+  Represents the control interface used to setup several miscellaneous
+  settings of the "Hollywood" chip like boot memory mappings, resets,
+  disk interface mode, etc.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-control"
+   - reg : should contain the control registers location and length
+
+1.n) The Disk Interface (DI) node
+
+  Represents the interface used to communicate with mass storage devices.
+
+  Required properties:
+
+   - compatible : should be "nintendo,hollywood-di"
+   - reg : should contain the DI registers location and length
+   - interrupts : should contain the DI interrupt
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/xilinx.txt linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/xilinx.txt
--- linux-libre-2.6.32-gnu1/Documentation/powerpc/dts-bindings/xilinx.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/powerpc/dts-bindings/xilinx.txt	2010-02-24 13:52:17.000000000 -0500
@@ -292,4 +292,15 @@
        - reg-offset : A value of 3 is required
        - reg-shift : A value of 2 is required
 
+      vii) Xilinx USB Host controller
+
+      The Xilinx USB host controller is EHCI compatible but with a different
+      base address for the EHCI registers, and it is always a big-endian
+      USB Host controller. The hardware can be configured as high speed only,
+      or high speed/full speed hybrid.
+
+      Required properties:
+      - xlnx,support-usb-fs: A value 0 means the core is built as high speed
+                             only. A value 1 means the core also supports
+                             full speed devices.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/RCU/trace.txt linux-libre-2.6.33-gnu1/Documentation/RCU/trace.txt
--- linux-libre-2.6.32-gnu1/Documentation/RCU/trace.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/RCU/trace.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,185 +1,10 @@
 CONFIG_RCU_TRACE debugfs Files and Formats
 
 
-The rcupreempt and rcutree implementations of RCU provide debugfs trace
-output that summarizes counters and state.  This information is useful for
-debugging RCU itself, and can sometimes also help to debug abuses of RCU.
-Note that the rcuclassic implementation of RCU does not provide debugfs
-trace output.
-
-The following sections describe the debugfs files and formats for
-preemptable RCU (rcupreempt) and hierarchical RCU (rcutree).
-
-
-Preemptable RCU debugfs Files and Formats
-
-This implementation of RCU provides three debugfs files under the
-top-level directory RCU: rcu/rcuctrs (which displays the per-CPU
-counters used by preemptable RCU) rcu/rcugp (which displays grace-period
-counters), and rcu/rcustats (which internal counters for debugging RCU).
-
-The output of "cat rcu/rcuctrs" looks as follows:
-
-CPU last cur F M
-  0    5  -5 0 0
-  1   -1   0 0 0
-  2    0   1 0 0
-  3    0   1 0 0
-  4    0   1 0 0
-  5    0   1 0 0
-  6    0   2 0 0
-  7    0  -1 0 0
-  8    0   1 0 0
-ggp = 26226, state = waitzero
-
-The per-CPU fields are as follows:
-
-o	"CPU" gives the CPU number.  Offline CPUs are not displayed.
-
-o	"last" gives the value of the counter that is being decremented
-	for the current grace period phase.  In the example above,
-	the counters sum to 4, indicating that there are still four
-	RCU read-side critical sections still running that started
-	before the last counter flip.
-
-o	"cur" gives the value of the counter that is currently being
-	both incremented (by rcu_read_lock()) and decremented (by
-	rcu_read_unlock()).  In the example above, the counters sum to
-	1, indicating that there is only one RCU read-side critical section
-	still running that started after the last counter flip.
-
-o	"F" indicates whether RCU is waiting for this CPU to acknowledge
-	a counter flip.  In the above example, RCU is not waiting on any,
-	which is consistent with the state being "waitzero" rather than
-	"waitack".
-
-o	"M" indicates whether RCU is waiting for this CPU to execute a
-	memory barrier.  In the above example, RCU is not waiting on any,
-	which is consistent with the state being "waitzero" rather than
-	"waitmb".
-
-o	"ggp" is the global grace-period counter.
-
-o	"state" is the RCU state, which can be one of the following:
-
-	o	"idle": there is no grace period in progress.
-
-	o	"waitack": RCU just incremented the global grace-period
-		counter, which has the effect of reversing the roles of
-		the "last" and "cur" counters above, and is waiting for
-		all the CPUs to acknowledge the flip.  Once the flip has
-		been acknowledged, CPUs will no longer be incrementing
-		what are now the "last" counters, so that their sum will
-		decrease monotonically down to zero.
-
-	o	"waitzero": RCU is waiting for the sum of the "last" counters
-		to decrease to zero.
-
-	o	"waitmb": RCU is waiting for each CPU to execute a memory
-		barrier, which ensures that instructions from a given CPU's
-		last RCU read-side critical section cannot be reordered
-		with instructions following the memory-barrier instruction.
-
-The output of "cat rcu/rcugp" looks as follows:
-
-oldggp=48870  newggp=48873
-
-Note that reading from this file provokes a synchronize_rcu().  The
-"oldggp" value is that of "ggp" from rcu/rcuctrs above, taken before
-executing the synchronize_rcu(), and the "newggp" value is also the
-"ggp" value, but taken after the synchronize_rcu() command returns.
-
-
-The output of "cat rcu/rcugp" looks as follows:
-
-na=1337955 nl=40 wa=1337915 wl=44 da=1337871 dl=0 dr=1337871 di=1337871
-1=50989 e1=6138 i1=49722 ie1=82 g1=49640 a1=315203 ae1=265563 a2=49640
-z1=1401244 ze1=1351605 z2=49639 m1=5661253 me1=5611614 m2=49639
-
-These are counters tracking internal preemptable-RCU events, however,
-some of them may be useful for debugging algorithms using RCU.  In
-particular, the "nl", "wl", and "dl" values track the number of RCU
-callbacks in various states.  The fields are as follows:
-
-o	"na" is the total number of RCU callbacks that have been enqueued
-	since boot.
-
-o	"nl" is the number of RCU callbacks waiting for the previous
-	grace period to end so that they can start waiting on the next
-	grace period.
-
-o	"wa" is the total number of RCU callbacks that have started waiting
-	for a grace period since boot.  "na" should be roughly equal to
-	"nl" plus "wa".
-
-o	"wl" is the number of RCU callbacks currently waiting for their
-	grace period to end.
-
-o	"da" is the total number of RCU callbacks whose grace periods
-	have completed since boot.  "wa" should be roughly equal to
-	"wl" plus "da".
-
-o	"dr" is the total number of RCU callbacks that have been removed
-	from the list of callbacks ready to invoke.  "dr" should be roughly
-	equal to "da".
-
-o	"di" is the total number of RCU callbacks that have been invoked
-	since boot.  "di" should be roughly equal to "da", though some
-	early versions of preemptable RCU had a bug so that only the
-	last CPU's count of invocations was displayed, rather than the
-	sum of all CPU's counts.
-
-o	"1" is the number of calls to rcu_try_flip().  This should be
-	roughly equal to the sum of "e1", "i1", "a1", "z1", and "m1"
-	described below.  In other words, the number of times that
-	the state machine is visited should be equal to the sum of the
-	number of times that each state is visited plus the number of
-	times that the state-machine lock acquisition failed.
-
-o	"e1" is the number of times that rcu_try_flip() was unable to
-	acquire the fliplock.
-
-o	"i1" is the number of calls to rcu_try_flip_idle().
-
-o	"ie1" is the number of times rcu_try_flip_idle() exited early
-	due to the calling CPU having no work for RCU.
-
-o	"g1" is the number of times that rcu_try_flip_idle() decided
-	to start a new grace period.  "i1" should be roughly equal to
-	"ie1" plus "g1".
-
-o	"a1" is the number of calls to rcu_try_flip_waitack().
-
-o	"ae1" is the number of times that rcu_try_flip_waitack() found
-	that at least one CPU had not yet acknowledge the new grace period
-	(AKA "counter flip").
-
-o	"a2" is the number of time rcu_try_flip_waitack() found that
-	all CPUs had acknowledged.  "a1" should be roughly equal to
-	"ae1" plus "a2".  (This particular output was collected on
-	a 128-CPU machine, hence the smaller-than-usual fraction of
-	calls to rcu_try_flip_waitack() finding all CPUs having already
-	acknowledged.)
-
-o	"z1" is the number of calls to rcu_try_flip_waitzero().
-
-o	"ze1" is the number of times that rcu_try_flip_waitzero() found
-	that not all of the old RCU read-side critical sections had
-	completed.
-
-o	"z2" is the number of times that rcu_try_flip_waitzero() finds
-	the sum of the counters equal to zero, in other words, that
-	all of the old RCU read-side critical sections had completed.
-	The value of "z1" should be roughly equal to "ze1" plus
-	"z2".
-
-o	"m1" is the number of calls to rcu_try_flip_waitmb().
-
-o	"me1" is the number of times that rcu_try_flip_waitmb() finds
-	that at least one CPU has not yet executed a memory barrier.
-
-o	"m2" is the number of times that rcu_try_flip_waitmb() finds that
-	all CPUs have executed a memory barrier.
+The rcutree implementation of RCU provides debugfs trace output that
+summarizes counters and state.  This information is useful for debugging
+RCU itself, and can sometimes also help to debug abuses of RCU.
+The following sections describe the debugfs files and formats.
 
 
 Hierarchical RCU debugfs Files and Formats
@@ -210,9 +35,10 @@ rcu_bh:
   6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
   7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
 
-The first section lists the rcu_data structures for rcu, the second for
-rcu_bh.  Each section has one line per CPU, or eight for this 8-CPU system.
-The fields are as follows:
+The first section lists the rcu_data structures for rcu_sched, the second
+for rcu_bh.  Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
+additional section for rcu_preempt.  Each section has one line per CPU,
+or eight for this 8-CPU system.  The fields are as follows:
 
 o	The number at the beginning of each line is the CPU number.
 	CPUs numbers followed by an exclamation mark are offline,
@@ -223,9 +49,9 @@ o	The number at the beginning of each li
 
 o	"c" is the count of grace periods that this CPU believes have
 	completed.  CPUs in dynticks idle mode may lag quite a ways
-	behind, for example, CPU 4 under "rcu" above, which has slept
-	through the past 25 RCU grace periods.	It is not unusual to
-	see CPUs lagging by thousands of grace periods.
+	behind, for example, CPU 4 under "rcu_sched" above, which has
+	slept through the past 25 RCU grace periods.  It is not unusual
+	to see CPUs lagging by thousands of grace periods.
 
 o	"g" is the count of grace periods that this CPU believes have
 	started.  Again, CPUs in dynticks idle mode may lag behind.
@@ -308,8 +134,10 @@ The output of "cat rcu/rcugp" looks as f
 rcu_sched: completed=33062  gpnum=33063
 rcu_bh: completed=464  gpnum=464
 
-Again, this output is for both "rcu" and "rcu_bh".  The fields are
-taken from the rcu_state structure, and are as follows:
+Again, this output is for both "rcu_sched" and "rcu_bh".  Note that
+kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
+"rcu_preempt" line.  The fields are taken from the rcu_state structure,
+and are as follows:
 
 o	"completed" is the number of grace periods that have completed.
 	It is comparable to the "c" field from rcu/rcudata in that a
@@ -324,23 +152,24 @@ o	"gpnum" is the number of grace periods
 	If these two fields are equal (as they are for "rcu_bh" above),
 	then there is no grace period in progress, in other words, RCU
 	is idle.  On the other hand, if the two fields differ (as they
-	do for "rcu" above), then an RCU grace period is in progress.
+	do for "rcu_sched" above), then an RCU grace period is in progress.
 
 
 The output of "cat rcu/rcuhier" looks as follows, with very long lines:
 
-c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
-1/1 0:127 ^0    
-3/3 0:35 ^0    0/0 36:71 ^1    0/0 72:107 ^2    0/0 108:127 ^3    
-3/3f 0:5 ^0    2/3 6:11 ^1    0/0 12:17 ^2    0/0 18:23 ^3    0/0 24:29 ^4    0/0 30:35 ^5    0/0 36:41 ^0    0/0 42:47 ^1    0/0 48:53 ^2    0/0 54:59 ^3    0/0 60:65 ^4    0/0 66:71 ^5    0/0 72:77 ^0    0/0 78:83 ^1    0/0 84:89 ^2    0/0 90:95 ^3    0/0 96:101 ^4    0/0 102:107 ^5    0/0 108:113 ^0    0/0 114:119 ^1    0/0 120:125 ^2    0/0 126:127 ^3    
+c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 oqlen=0
+1/1 .>. 0:127 ^0    
+3/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
+3/3f .>. 0:5 ^0    2/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3    
 rcu_bh:
-c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
-0/1 0:127 ^0    
-0/3 0:35 ^0    0/0 36:71 ^1    0/0 72:107 ^2    0/0 108:127 ^3    
-0/3f 0:5 ^0    0/3 6:11 ^1    0/0 12:17 ^2    0/0 18:23 ^3    0/0 24:29 ^4    0/0 30:35 ^5    0/0 36:41 ^0    0/0 42:47 ^1    0/0 48:53 ^2    0/0 54:59 ^3    0/0 60:65 ^4    0/0 66:71 ^5    0/0 72:77 ^0    0/0 78:83 ^1    0/0 84:89 ^2    0/0 90:95 ^3    0/0 96:101 ^4    0/0 102:107 ^5    0/0 108:113 ^0    0/0 114:119 ^1    0/0 120:125 ^2    0/0 126:127 ^3
+c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 oqlen=0
+0/1 .>. 0:127 ^0    
+0/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
+0/3f .>. 0:5 ^0    0/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3
 
-This is once again split into "rcu" and "rcu_bh" portions.  The fields are
-as follows:
+This is once again split into "rcu_sched" and "rcu_bh" portions,
+and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
+"rcu_preempt" section.  The fields are as follows:
 
 o	"c" is exactly the same as "completed" under rcu/rcugp.
 
@@ -372,6 +201,11 @@ o	"fqlh" is the number of calls to force
 	exited immediately (without even being counted in nfqs above)
 	due to contention on ->fqslock.
 
+o	"oqlen" is the number of callbacks on the "orphan" callback
+	list.  RCU callbacks are placed on this list by CPUs going
+	offline, and are "adopted" either by the CPU helping the outgoing
+	CPU or by the next rcu_barrier*() call, whichever comes first.
+
 o	Each element of the form "1/1 0:127 ^0" represents one struct
 	rcu_node.  Each line represents one level of the hierarchy, from
 	root to leaves.  It is best to think of the rcu_data structures
@@ -379,7 +213,7 @@ o	Each element of the form "1/1 0:127 ^0
 	might be either one, two, or three levels of rcu_node structures,
 	depending on the relationship between CONFIG_RCU_FANOUT and
 	CONFIG_NR_CPUS.
-	
+
 	o	The numbers separated by the "/" are the qsmask followed
 		by the qsmaskinit.  The qsmask will have one bit
 		set for each entity in the next lower level that
@@ -389,10 +223,19 @@ o	Each element of the form "1/1 0:127 ^0
 		The value of qsmaskinit is assigned to that of qsmask
 		at the beginning of each grace period.
 
-		For example, for "rcu", the qsmask of the first entry
-		of the lowest level is 0x14, meaning that we are still
-		waiting for CPUs 2 and 4 to check in for the current
-		grace period.
+		For example, for "rcu_sched", the qsmask of the first
+		entry of the lowest level is 0x14, meaning that we
+		are still waiting for CPUs 2 and 4 to check in for the
+		current grace period.
+
+	o	The characters separated by the ">" indicate the state
+		of the blocked-tasks lists.  A "T" preceding the ">"
+		indicates that at least one task blocked in an RCU
+		read-side critical section blocks the current grace
+		period, while a "." preceding the ">" indicates otherwise.
+		The character following the ">" indicates similarly for
+		the next grace period.  A "T" should appear in this
+		field only for rcu-preempt.
 
 	o	The numbers separated by the ":" are the range of CPUs
 		served by this struct rcu_node.  This can be helpful
@@ -431,8 +274,9 @@ rcu_bh:
   6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
   7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
 
-As always, this is once again split into "rcu" and "rcu_bh" portions.
-The fields are as follows:
+As always, this is once again split into "rcu_sched" and "rcu_bh"
+portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
+"rcu_preempt" section.  The fields are as follows:
 
 o	"np" is the number of times that __rcu_pending() has been invoked
 	for the corresponding flavor of RCU.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/RCU/whatisRCU.txt linux-libre-2.6.33-gnu1/Documentation/RCU/whatisRCU.txt
--- linux-libre-2.6.32-gnu1/Documentation/RCU/whatisRCU.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/RCU/whatisRCU.txt	2010-02-24 13:52:17.000000000 -0500
@@ -830,7 +830,7 @@ sched:	Critical sections	Grace period		B
 SRCU:	Critical sections	Grace period		Barrier
 
 	srcu_read_lock		synchronize_srcu	N/A
-	srcu_read_unlock
+	srcu_read_unlock	synchronize_srcu_expedited
 
 SRCU:	Initialization/cleanup
 	init_srcu_struct
diff -druNp linux-libre-2.6.32-gnu1/Documentation/scsi/ChangeLog.megaraid_sas linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-libre-2.6.32-gnu1/Documentation/scsi/ChangeLog.megaraid_sas	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/scsi/ChangeLog.megaraid_sas	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,65 @@
+1 Release Date    : Tues.  July 28, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.12
+3 Older Version   : 00.00.04.10
+
+1.	Change the AEN sys PD update from scsi_scan to
+	scsi_add_device and scsi_remove_device.
+2.	Takeoff the debug print-out in aen_polling routine.
+
+1 Release Date    : Thur.  July 02, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.10
+3 Older Version   : 00.00.04.08
+
+1.	Add the 3 mins timeout during the controller initialize.
+2.	Add the fix for 64bit sense date errors.
+
+1 Release Date    : Tues. May 05, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.08
+3 Older Version   : 00.00.04.06
+
+1.	Add the fix of pending in FW after deleted the logic drives.
+2.	Add the fix of deallocating memory after get pdlist.
+
+1 Release Date    : Tues. March 26, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.06
+3 Older Version   : 00.00.04.04
+
+1.	Add the fix of the driver cmd empty fix of the driver cmd empty.
+2.	Add the fix of the driver MSM AEN CMD cause the system slow.
+
+1 Release Date    : Tues. March 03, 2009 10:12:45 PST 2009 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Bo Yang
+
+2 Current Version : 00.00.04.04
+3 Older Version   : 00.00.04.01
+
+1.	Add the Tape drive fix to the driver: If the command is for
+	the tape device, set the pthru timeout to the os layer timeout value.
+
+2.	Add Poll_wait mechanism to Gen-2 Linux driv.
+		In the aen handler, driver needs to wakeup poll handler similar to
+		the way it raises SIGIO.
+
+3.	Add new controller new SAS2 support to the driver.
+
+4.	Report the unconfigured PD (system PD) to OS.
+
+5.	Add the IEEE SGL support to the driver
+
+6.	Reasign the Application cmds to SAS2 controller
 
 1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
@@ -185,7 +247,7 @@ ii.	FW enables WCE bit in Mode Sense cmd
 	Disks are exposed with WCE=1. User is advised to enable Write Back
 	mode only when the controller has battery backup. At this time
 	Synhronize cache is not supported by the FW. Driver will short-cycle
-	the cmd and return sucess without sending down to FW.
+	the cmd and return success without sending down to FW.
 
 1 Release Date    : Sun Jan. 14 11:21:32 PDT 2007 -
 		 Sumant Patro <Sumant.Patro@lsil.com>/Bo Yang
diff -druNp linux-libre-2.6.32-gnu1/Documentation/serial/hayes-esp.txt linux-libre-2.6.33-gnu1/Documentation/serial/hayes-esp.txt
--- linux-libre-2.6.32-gnu1/Documentation/serial/hayes-esp.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/serial/hayes-esp.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,154 +0,0 @@
-HAYES ESP DRIVER VERSION 2.1
-
-A big thanks to the people at Hayes, especially Alan Adamson.  Their support
-has enabled me to provide enhancements to the driver.
-
-Please report your experiences with this driver to me (arobinso@nyx.net).  I
-am looking for both positive and negative feedback.
-
-*** IMPORTANT CHANGES FOR 2.1 ***
-Support for PIO mode.  Five situations will cause PIO mode to be used:
-1) A multiport card is detected.  PIO mode will always be used.  (8 port cards
-do not support DMA).
-2) The DMA channel is set to an invalid value (anything other than 1 or 3).
-3) The DMA buffer/channel could not be allocated.  The port will revert to PIO
-mode until it is reopened.
-4) Less than a specified number of bytes need to be transferred to/from the
-FIFOs.  PIO mode will be used for that transfer only.
-5) A port needs to do a DMA transfer and another port is already using the
-DMA channel.  PIO mode will be used for that transfer only.
-
-Since the Hayes ESP seems to conflict with other cards (notably sound cards)
-when using DMA, DMA is turned off by default.  To use DMA, it must be turned
-on explicitly, either with the "dma=" option described below or with
-setserial.  A multiport card can be forced into DMA mode by using setserial;
-however, most multiport cards don't support DMA.
-
-The latest version of setserial allows the enhanced configuration of the ESP
-card to be viewed and modified.
-***
-
-This package contains the files needed to compile a module to support the Hayes
-ESP card.  The drivers are basically a modified version of the serial drivers.
-
-Features:
-
-- Uses the enhanced mode of the ESP card, allowing a wider range of
-  interrupts and features than compatibility mode
-- Uses DMA and 16 bit PIO mode to transfer data to and from the ESP's FIFOs,
-  reducing CPU load
-- Supports primary and secondary ports
-
-
-If the driver is compiled as a module, the IRQs to use can be specified by
-using the irq= option.  The format is:
-
-irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380]
-
-The address in brackets is the base address of the card.  The IRQ of
-nonexistent cards can be set to 0.  If an IRQ of a card that does exist is set
-to 0, the driver will attempt to guess at the correct IRQ.  For example, to set
-the IRQ of the card at address 0x300 to 12, the insmod command would be:
-
-insmod esp irq=0,0,0,0,0,0,12,0
-
-The custom divisor can be set by using the divisor= option.  The format is the
-same as for the irq= option.  Each divisor value is a series of hex digits,
-with each digit representing the divisor to use for a corresponding port.  The
-divisor value is constructed RIGHT TO LEFT.  Specifying a nonzero divisor value
-will automatically set the spd_cust flag.  To calculate the divisor to use for
-a certain baud rate, divide the port's base baud (generally 921600) by the
-desired rate.  For example, to set the divisor of the primary port at 0x300 to
-4 and the divisor of the secondary port at 0x308 to 8, the insmod command would
-be:
-
-insmod esp divisor=0,0,0,0,0,0,0x84,0
-
-The dma= option can be used to set the DMA channel.  The channel can be either
-1 or 3.  Specifying any other value will force the driver to use PIO mode.
-For example, to set the DMA channel to 3, the insmod command would be:
-
-insmod esp dma=3
-
-The rx_trigger= and tx_trigger= options can be used to set the FIFO trigger
-levels.  They specify when the ESP card should send an interrupt.  Larger
-values will decrease the number of interrupts; however, a value too high may
-result in data loss.  Valid values are 1 through 1023, with 768 being the
-default.  For example, to set the receive trigger level to 512 bytes and the
-transmit trigger level to 700 bytes, the insmod command would be:
-
-insmod esp rx_trigger=512 tx_trigger=700
-
-The flow_off= and flow_on= options can be used to set the hardware flow off/
-flow on levels.  The flow on level must be lower than the flow off level, and
-the flow off level should be higher than rx_trigger.  Valid values are 1
-through 1023, with 1016 being the default flow off level and 944 being the
-default flow on level.  For example, to set the flow off level to 1000 bytes
-and the flow on level to 935 bytes, the insmod command would be:
-
-insmod esp flow_off=1000 flow_on=935
-
-The rx_timeout= option can be used to set the receive timeout value.  This
-value indicates how long after receiving the last character that the ESP card
-should wait before signalling an interrupt.  Valid values are 0 though 255,
-with 128 being the default.  A value too high will increase latency, and a
-value too low will cause unnecessary interrupts.  For example, to set the
-receive timeout to 255, the insmod command would be:
-
-insmod esp rx_timeout=255
-
-The pio_threshold= option sets the threshold (in number of characters) for
-using PIO mode instead of DMA mode.  For example, if this value is 32,
-transfers of 32 bytes or less will always use PIO mode.
-
-insmod esp pio_threshold=32
-
-Multiple options can be listed on the insmod command line by separating each
-option with a space.  For example:
-
-insmod esp dma=3 trigger=512
-
-The esp module can be automatically loaded when needed.  To cause this to
-happen, add the following lines to /etc/modprobe.conf (replacing the last line
-with options for your configuration):
-
-alias char-major-57 esp
-alias char-major-58 esp
-options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0
-
-You may also need to run 'depmod -a'.
-
-Devices must be created manually.  To create the devices, note the output from
-the module after it is inserted.  The output will appear in the location where
-kernel messages usually appear (usually /var/adm/messages).  Create two devices
-for each 'tty' mentioned, one with major of 57 and the other with major of 58.
-The minor number should be the same as the tty number reported.  The commands
-would be (replace ? with the tty number):
-
-mknod /dev/ttyP? c 57 ?
-mknod /dev/cup? c 58 ?
-
-For example, if the following line appears:
-
-Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port
-
-...two devices should be created:
-
-mknod /dev/ttyP8 c 57 8
-mknod /dev/cup8 c 58 8
-
-You may need to set the permissions on the devices:
-
-chmod 666 /dev/ttyP*
-chmod 666 /dev/cup*
-
-The ESP module and the serial module should not conflict (they can be used at
-the same time).  After the ESP module has been loaded the ports on the ESP card
-will no longer be accessible by the serial driver.
-
-If I/O errors are experienced when accessing the port, check for IRQ and DMA
-conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
-DMAs currently in use).
-
-Enjoy!
-Andrew J. Robinson <arobinso@nyx.net>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/serial/tty.txt linux-libre-2.6.33-gnu1/Documentation/serial/tty.txt
--- linux-libre-2.6.32-gnu1/Documentation/serial/tty.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/serial/tty.txt	2010-02-24 13:52:17.000000000 -0500
@@ -42,7 +42,8 @@ TTY side interfaces:
 open()		-	Called when the line discipline is attached to
 			the terminal. No other call into the line
 			discipline for this tty will occur until it
-			completes successfully. Can sleep.
+			completes successfully. Returning an error will
+			prevent the ldisc from being attached. Can sleep.
 
 close()		-	This is called on a terminal when the line
 			discipline is being unplugged. At the point of
@@ -52,7 +53,7 @@ close()		-	This is called on a terminal
 hangup()	-	Called when the tty line is hung up.
 			The line discipline should cease I/O to the tty.
 			No further calls into the ldisc code will occur.
-			Can sleep.
+			The return value is ignored. Can sleep.
 
 write()		-	A process is writing data through the line
 			discipline.  Multiple write calls are serialized
@@ -83,6 +84,10 @@ ioctl()		-	Called when an ioctl is hande
 			that might be for the ldisc. Multiple ioctl calls
 			may occur in parallel. May sleep. 
 
+compat_ioctl()	-	Called when a 32 bit ioctl is handed to the tty layer
+			that might be for the ldisc. Multiple ioctl calls
+			may occur in parallel. May sleep.
+
 Driver Side Interfaces:
 
 receive_buf()	-	Hand buffers of bytes from the driver to the ldisc
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt
--- linux-libre-2.6.32-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 14:07:29.000000000 -0400
+++ linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 12:15:05.000000000 -0400
@@ -798,6 +798,9 @@ Prior to version 0.9.0rc4 options had a
     		setup before initializing the codecs.  This option is
 		available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.
 		See HD-Audio.txt for details.
+    beep_mode	- Selects the beep registration mode (0=off, 1=on, 2=
+		dynamic registration via mute switch on/off); the default
+		value is set via CONFIG_SND_HDA_INPUT_BEEP_MODE kconfig.
     
     [Single (global) options]
     single_cmd  - Use single immediate commands to communicate with
@@ -1454,6 +1457,7 @@ Prior to version 0.9.0rc4 options had a
 
     Module for internal PC-Speaker.
 
+    nopcm	- Disable PC-Speaker PCM sound. Only beeps remain.
     nforce_wa	- enable NForce chipset workaround. Expect bad sound.
 
     This module supports system beeps, some kind of PCM playback and
@@ -1631,7 +1635,7 @@ Prior to version 0.9.0rc4 options had a
   Module snd-sscape
   -----------------
 
-    Module for ENSONIQ SoundScape PnP cards.
+    Module for ENSONIQ SoundScape cards.
 
     port	- Port # (PnP setup)
     wss_port	- WSS Port # (PnP setup)
@@ -1639,10 +1643,11 @@ Prior to version 0.9.0rc4 options had a
     mpu_irq	- MPU-401 IRQ # (PnP setup)
     dma		- DMA # (PnP setup)
     dma2	- 2nd DMA # (PnP setup, -1 to disable)
+    joystick	- Enable gameport - 0 = disable (default), 1 = enable
 
-    This module supports multiple cards.  ISA PnP must be enabled.
-    You need sscape_ctl tool in alsa-tools package for loading
-    the microcode.
+    This module supports multiple cards.
+
+    The driver requires the firmware loader support on kernel.
 
   Module snd-sun-amd7930 (on sparc only)
   --------------------------------------
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sound/alsa/ControlNames.txt linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ControlNames.txt
--- linux-libre-2.6.32-gnu1/Documentation/sound/alsa/ControlNames.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sound/alsa/ControlNames.txt	2010-02-24 13:52:17.000000000 -0500
@@ -18,8 +18,9 @@ SOURCE:
   Master
   Master Mono
   Hardware Master
+  Speaker	(internal speaker)
   Headphone
-  PC Speaker
+  Beep		(beep generator)
   Phone
   Phone Input
   Phone Output
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt
--- linux-libre-2.6.32-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2010-02-24 13:52:17.000000000 -0500
@@ -126,6 +126,7 @@ ALC882/883/885/888/889
   mb5		Macbook 5,1
   mbp3		Macbook Pro rev3
   imac24	iMac 24'' with jack detection
+  imac91	iMac 9,1
   w2jc		ASUS W2JC
   3stack-2ch-dig	3-jack with SPDIF I/O (ALC883)
   alc883-6stack-dig	6-jack digital with SPDIF I/O (ALC883)
@@ -391,6 +392,7 @@ STAC92HD83*
   ref		Reference board
   mic-ref	Reference board with power management for ports
   dell-s14	Dell laptop
+  hp		HP laptops with (inverted) mute-LED
   auto		BIOS setup (default)
 
 STAC9872
@@ -401,4 +403,5 @@ STAC9872
 Cirrus Logic CS4206/4207
 ========================
   mbp55		MacBook Pro 5,5
+  imac27	IMac 27 Inch
   auto		BIOS setup (default)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sound/alsa/HD-Audio.txt linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio.txt
--- linux-libre-2.6.32-gnu1/Documentation/sound/alsa/HD-Audio.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sound/alsa/HD-Audio.txt	2010-02-24 13:52:17.000000000 -0500
@@ -624,11 +624,13 @@ hda-verb.  The program gives you an easy
 the widget information and adjusting the amp values, as well as the
 proc-compatible output.
 
-The hda-analyzer is a part of alsa.git repository in
-alsa-project.org:
+The hda-analyzer:
 
 - http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer
 
+is a part of alsa.git repository in alsa-project.org:
+
+- git://git.alsa-project.org/alsa.git
 
 Codecgraph
 ~~~~~~~~~~
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sound/alsa/Procfile.txt linux-libre-2.6.33-gnu1/Documentation/sound/alsa/Procfile.txt
--- linux-libre-2.6.32-gnu1/Documentation/sound/alsa/Procfile.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sound/alsa/Procfile.txt	2010-02-24 13:52:17.000000000 -0500
@@ -95,7 +95,7 @@ card*/pcm*/xrun_debug
 	It takes an integer value, can be changed by writing to this
 	file, such as
 
-		 # cat 5 > /proc/asound/card0/pcm0p/xrun_debug
+		 # echo 5 > /proc/asound/card0/pcm0p/xrun_debug
 
 	The value consists of the following bit flags:
 	  bit 0 = Enable XRUN/jiffies debug messages
diff -druNp linux-libre-2.6.32-gnu1/Documentation/spi/spi-summary linux-libre-2.6.33-gnu1/Documentation/spi/spi-summary
--- linux-libre-2.6.32-gnu1/Documentation/spi/spi-summary	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/spi/spi-summary	2010-02-24 13:52:17.000000000 -0500
@@ -538,7 +538,7 @@ SPI MESSAGE QUEUE
 The bulk of the driver will be managing the I/O queue fed by transfer().
 
 That queue could be purely conceptual.  For example, a driver used only
-for low-frequency sensor acess might be fine using synchronous PIO.
+for low-frequency sensor access might be fine using synchronous PIO.
 
 But the queue will probably be very real, using message->queue, PIO,
 often DMA (especially if the root filesystem is in SPI flash), and
diff -druNp linux-libre-2.6.32-gnu1/Documentation/spinlocks.txt linux-libre-2.6.33-gnu1/Documentation/spinlocks.txt
--- linux-libre-2.6.32-gnu1/Documentation/spinlocks.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/spinlocks.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,73 +1,8 @@
-SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and
-are hence deprecated.
-
-Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
-__SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate for static
-initialization.
-
-Most of the time, you can simply turn:
-
-	static spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
-
-into:
-
-	static DEFINE_SPINLOCK(xxx_lock);
-
-Static structure member variables go from:
-
-	struct foo bar {
-		.lock	=	SPIN_LOCK_UNLOCKED;
-	};
-
-to:
-
-	struct foo bar {
-		.lock	=	__SPIN_LOCK_UNLOCKED(bar.lock);
-	};
-
-Declaration of static rw_locks undergo a similar transformation.
-
-Dynamic initialization, when necessary, may be performed as
-demonstrated below.
-
-   spinlock_t xxx_lock;
-   rwlock_t xxx_rw_lock;
-
-   static int __init xxx_init(void)
-   {
-   	spin_lock_init(&xxx_lock);
-	rwlock_init(&xxx_rw_lock);
-	...
-   }
-
-   module_init(xxx_init);
-
-The following discussion is still valid, however, with the dynamic
-initialization of spinlocks or with DEFINE_SPINLOCK, etc., used
-instead of SPIN_LOCK_UNLOCKED.
-
------------------------
-
-On Fri, 2 Jan 1998, Doug Ledford wrote:
-> 
-> I'm working on making the aic7xxx driver more SMP friendly (as well as
-> importing the latest FreeBSD sequencer code to have 7895 support) and wanted
-> to get some info from you.  The goal here is to make the various routines
-> SMP safe as well as UP safe during interrupts and other manipulating
-> routines.  So far, I've added a spin_lock variable to things like my queue
-> structs.  Now, from what I recall, there are some spin lock functions I can
-> use to lock these spin locks from other use as opposed to a (nasty)
-> save_flags(); cli(); stuff; restore_flags(); construct.  Where do I find
-> these routines and go about making use of them?  Do they only lock on a
-> per-processor basis or can they also lock say an interrupt routine from
-> mucking with a queue if the queue routine was manipulating it when the
-> interrupt occurred, or should I still use a cli(); based construct on that
-> one?
-
-See <asm/spinlock.h>. The basic version is:
+Lesson 1: Spin locks
 
-   spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
+The most basic primitive for locking is spinlock.
 
+static DEFINE_SPINLOCK(xxx_lock);
 
 	unsigned long flags;
 
@@ -75,13 +10,11 @@ See <asm/spinlock.h>. The basic version
 	... critical section here ..
 	spin_unlock_irqrestore(&xxx_lock, flags);
 
-and the above is always safe. It will disable interrupts _locally_, but the
+The above is always safe. It will disable interrupts _locally_, but the
 spinlock itself will guarantee the global lock, so it will guarantee that
 there is only one thread-of-control within the region(s) protected by that
-lock. 
-
-Note that it works well even under UP - the above sequence under UP
-essentially is just the same as doing a
+lock. This works well even under UP. The above sequence under UP
+essentially is just the same as doing
 
 	unsigned long flags;
 
@@ -91,15 +24,13 @@ essentially is just the same as doing a
 
 so the code does _not_ need to worry about UP vs SMP issues: the spinlocks
 work correctly under both (and spinlocks are actually more efficient on
-architectures that allow doing the "save_flags + cli" in one go because I
-don't export that interface normally).
+architectures that allow doing the "save_flags + cli" in one operation).
 
-NOTE NOTE NOTE! The reason the spinlock is so much faster than a global
-interrupt lock under SMP is exactly because it disables interrupts only on
-the local CPU. The spin-lock is safe only when you _also_ use the lock
-itself to do locking across CPU's, which implies that EVERYTHING that
-touches a shared variable has to agree about the spinlock they want to
-use.
+   NOTE! Implications of spin_locks for memory are further described in:
+
+     Documentation/memory-barriers.txt
+       (5) LOCK operations.
+       (6) UNLOCK operations.
 
 The above is usually pretty simple (you usually need and want only one
 spinlock for most things - using more than one spinlock can make things a
@@ -120,20 +51,24 @@ and another sequence that does
 then they are NOT mutually exclusive, and the critical regions can happen
 at the same time on two different CPU's. That's fine per se, but the
 critical regions had better be critical for different things (ie they
-can't stomp on each other). 
+can't stomp on each other).
 
 The above is a problem mainly if you end up mixing code - for example the
 routines in ll_rw_block() tend to use cli/sti to protect the atomicity of
 their actions, and if a driver uses spinlocks instead then you should
-think about issues like the above..
+think about issues like the above.
 
 This is really the only really hard part about spinlocks: once you start
 using spinlocks they tend to expand to areas you might not have noticed
 before, because you have to make sure the spinlocks correctly protect the
 shared data structures _everywhere_ they are used. The spinlocks are most
-easily added to places that are completely independent of other code (ie
-internal driver data structures that nobody else ever touches, for
-example). 
+easily added to places that are completely independent of other code (for
+example, internal driver data structures that nobody else ever touches).
+
+   NOTE! The spin-lock is safe only when you _also_ use the lock itself
+   to do locking across CPU's, which implies that EVERYTHING that
+   touches a shared variable has to agree about the spinlock they want
+   to use.
 
 ----
 
@@ -141,13 +76,17 @@ Lesson 2: reader-writer spinlocks.
 
 If your data accesses have a very natural pattern where you usually tend
 to mostly read from the shared variables, the reader-writer locks
-(rw_lock) versions of the spinlocks are often nicer. They allow multiple
+(rw_lock) versions of the spinlocks are sometimes useful. They allow multiple
 readers to be in the same critical region at once, but if somebody wants
-to change the variables it has to get an exclusive write lock. The
-routines look the same as above:
+to change the variables it has to get an exclusive write lock.
 
-   rwlock_t xxx_lock = RW_LOCK_UNLOCKED;
+   NOTE! reader-writer locks require more atomic memory operations than
+   simple spinlocks.  Unless the reader critical section is long, you
+   are better off just using spinlocks.
+
+The routines look the same as above:
 
+   rwlock_t xxx_lock = RW_LOCK_UNLOCKED;
 
 	unsigned long flags;
 
@@ -159,18 +98,21 @@ routines look the same as above:
 	.. read and write exclusive access to the info ...
 	write_unlock_irqrestore(&xxx_lock, flags);
 
-The above kind of lock is useful for complex data structures like linked
-lists etc, especially when you know that most of the work is to just
-traverse the list searching for entries without changing the list itself,
-for example. Then you can use the read lock for that kind of list
-traversal, which allows many concurrent readers. Anything that _changes_
-the list will have to get the write lock. 
+The above kind of lock may be useful for complex data structures like
+linked lists, especially searching for entries without changing the list
+itself.  The read lock allows many concurrent readers.  Anything that
+_changes_ the list will have to get the write lock.
 
-Note: you cannot "upgrade" a read-lock to a write-lock, so if you at _any_
+   NOTE! RCU is better for list traversal, but requires careful
+   attention to design detail (see Documentation/RCU/listRCU.txt).
+
+Also, you cannot "upgrade" a read-lock to a write-lock, so if you at _any_
 time need to do any changes (even if you don't do it every time), you have
-to get the write-lock at the very beginning. I could fairly easily add a
-primitive to create a "upgradeable" read-lock, but it hasn't been an issue
-yet. Tell me if you'd want one. 
+to get the write-lock at the very beginning.
+
+   NOTE! We are working hard to remove reader-writer spinlocks in most
+   cases, so please don't add a new one without consensus.  (Instead, see
+   Documentation/RCU/rcu.txt for complete information.)
 
 ----
 
@@ -233,4 +175,46 @@ indeed), while write-locks need to prote
 
 		Linus
 
+----
+
+Reference information:
+
+For dynamic initialization, use spin_lock_init() or rwlock_init() as
+appropriate:
+
+   spinlock_t xxx_lock;
+   rwlock_t xxx_rw_lock;
+
+   static int __init xxx_init(void)
+   {
+	spin_lock_init(&xxx_lock);
+	rwlock_init(&xxx_rw_lock);
+	...
+   }
+
+   module_init(xxx_init);
+
+For static initialization, use DEFINE_SPINLOCK() / DEFINE_RWLOCK() or
+__SPIN_LOCK_UNLOCKED() / __RW_LOCK_UNLOCKED() as appropriate.
+
+SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED are deprecated.  These interfere
+with lockdep state tracking.
+
+Most of the time, you can simply turn:
+	static spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
+into:
+	static DEFINE_SPINLOCK(xxx_lock);
+
+Static structure member variables go from:
 
+	struct foo bar {
+		.lock	=	SPIN_LOCK_UNLOCKED;
+	};
+
+to:
+
+	struct foo bar {
+		.lock	=	__SPIN_LOCK_UNLOCKED(bar.lock);
+	};
+
+Declaration of static rw_locks undergo a similar transformation.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/stable_kernel_rules.txt linux-libre-2.6.33-gnu1/Documentation/stable_kernel_rules.txt
--- linux-libre-2.6.32-gnu1/Documentation/stable_kernel_rules.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/stable_kernel_rules.txt	2010-02-24 13:52:17.000000000 -0500
@@ -26,13 +26,33 @@ Procedure for submitting patches to the
 
  - Send the patch, after verifying that it follows the above rules, to
    stable@kernel.org.
+ - To have the patch automatically included in the stable tree, add the
+   the tag
+     Cc: stable@kernel.org
+   in the sign-off area. Once the patch is merged it will be applied to
+   the stable tree without anything else needing to be done by the author
+   or subsystem maintainer.
+ - If the patch requires other patches as prerequisites which can be
+   cherry-picked than this can be specified in the following format in
+   the sign-off area:
+
+     Cc: <stable@kernel.org> # .32.x: a1f84a3: sched: Check for idle
+     Cc: <stable@kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
+     Cc: <stable@kernel.org> # .32.x: fd21073: sched: Fix affinity logic
+     Cc: <stable@kernel.org> # .32.x
+    Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+   The tag sequence has the meaning of:
+     git cherry-pick a1f84a3
+     git cherry-pick 1b9508f
+     git cherry-pick fd21073
+     git cherry-pick <this commit>
+
  - The sender will receive an ACK when the patch has been accepted into the
    queue, or a NAK if the patch is rejected.  This response might take a few
    days, according to the developer's schedules.
  - If accepted, the patch will be added to the -stable queue, for review by
    other developers and by the relevant subsystem maintainer.
- - If the stable@kernel.org address is added to a patch, when it goes into
-   Linus's tree it will automatically be emailed to the stable team.
  - Security patches should not be sent to this alias, but instead to the
    documented security@kernel.org address.
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/SubmitChecklist linux-libre-2.6.33-gnu1/Documentation/SubmitChecklist
--- linux-libre-2.6.32-gnu1/Documentation/SubmitChecklist	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/SubmitChecklist	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@ kernel patches.
 2: Passes allnoconfig, allmodconfig
 
 3: Builds on multiple CPU architectures by using local cross-compile tools
-   or something like PLM at OSDL.
+   or some other build farm.
 
 4: ppc64 is a good architecture for cross-compilation checking because it
    tends to use `unsigned long' for 64-bit quantities.
@@ -88,3 +88,6 @@ kernel patches.
 
 24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the
     source code that explains the logic of what they are doing and why.
+
+25: If any ioctl's are added by the patch, then also update
+    Documentation/ioctl/ioctl-number.txt.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sysctl/ctl_unnumbered.txt linux-libre-2.6.33-gnu1/Documentation/sysctl/ctl_unnumbered.txt
--- linux-libre-2.6.32-gnu1/Documentation/sysctl/ctl_unnumbered.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sysctl/ctl_unnumbered.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-
-Except for a few extremely rare exceptions user space applications do not use
-the binary sysctl interface.  Instead everyone uses /proc/sys/...  with
-readable ascii names.
-
-Recently the kernel has started supporting setting the binary sysctl value to
-CTL_UNNUMBERED so we no longer need to assign a binary sysctl path to allow
-sysctls to show up in /proc/sys.
-
-Assigning binary sysctl numbers is an endless source of conflicts in sysctl.h,
-breaking of the user space ABI (because of those conflicts), and maintenance
-problems.  A complete pass through all of the sysctl users revealed multiple
-instances where the sysctl binary interface was broken and had gone undetected
-for years.
-
-So please do not add new binary sysctl numbers.  They are unneeded and
-problematic.
-
-If you really need a new binary sysctl number please first merge your sysctl
-into the kernel and then as a separate patch allocate a binary sysctl number.
-
-(ebiederm@xmission.com, June 2007)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sysctl/kernel.txt linux-libre-2.6.33-gnu1/Documentation/sysctl/kernel.txt
--- linux-libre-2.6.32-gnu1/Documentation/sysctl/kernel.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sysctl/kernel.txt	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,8 @@ Currently, these files might (depending
 show up in /proc/sys/kernel:
 - acpi_video_flags
 - acct
+- bootloader_type	     [ X86 only ]
+- bootloader_version	     [ X86 only ]
 - callhome		     [ S390 only ]
 - auto_msgmni
 - core_pattern
@@ -93,6 +95,35 @@ valid for 30 seconds.
 
 ==============================================================
 
+bootloader_type:
+
+x86 bootloader identification
+
+This gives the bootloader type number as indicated by the bootloader,
+shifted left by 4, and OR'd with the low four bits of the bootloader
+version.  The reason for this encoding is that this used to match the
+type_of_loader field in the kernel header; the encoding is kept for
+backwards compatibility.  That is, if the full bootloader type number
+is 0x15 and the full version number is 0x234, this file will contain
+the value 340 = 0x154.
+
+See the type_of_loader and ext_loader_type fields in
+Documentation/x86/boot.txt for additional information.
+
+==============================================================
+
+bootloader_version:
+
+x86 bootloader version
+
+The complete bootloader version number.  In the example above, this
+file will contain the value 564 = 0x234.
+
+See the type_of_loader and ext_loader_ver fields in
+Documentation/x86/boot.txt for additional information.
+
+==============================================================
+
 callhome:
 
 Controls the kernel's callhome behavior in case of a kernel panic.
@@ -139,9 +170,9 @@ core_pattern is used to specify a core d
 core_pipe_limit:
 
 This sysctl is only applicable when core_pattern is configured to pipe core
-files to user space helper a (when the first character of core_pattern is a '|',
+files to a user space helper (when the first character of core_pattern is a '|',
 see above).  When collecting cores via a pipe to an application, it is
-occasionally usefull for the collecting application to gather data about the
+occasionally useful for the collecting application to gather data about the
 crashing process from its /proc/pid directory.  In order to do this safely, the
 kernel must wait for the collecting process to exit, so as not to remove the
 crashing processes proc files prematurely.  This in turn creates the possibility
@@ -152,7 +183,7 @@ applications in parallel.  If this value
 processes above that value are noted via the kernel log and their cores are
 skipped.  0 is a special value, indicating that unlimited processes may be
 captured in parallel, but that no waiting will take place (i.e. the collecting
-process is not guaranteed access to /proc/<crahing pid>/).  This value defaults
+process is not guaranteed access to /proc/<crashing pid>/).  This value defaults
 to 0.
 
 ==============================================================
diff -druNp linux-libre-2.6.32-gnu1/Documentation/sysctl/vm.txt linux-libre-2.6.33-gnu1/Documentation/sysctl/vm.txt
--- linux-libre-2.6.32-gnu1/Documentation/sysctl/vm.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/sysctl/vm.txt	2010-02-24 13:52:17.000000000 -0500
@@ -370,7 +370,7 @@ The default is 1 percent.
 mmap_min_addr
 
 This file indicates the amount of address space  which a user process will
-be restricted from mmaping.  Since kernel null dereference bugs could
+be restricted from mmapping.  Since kernel null dereference bugs could
 accidentally operate based on the information in the first couple of pages
 of memory userspace processes should not be allowed to write to them.  By
 default this value is set to 0 and no protections will be enforced by the
diff -druNp linux-libre-2.6.32-gnu1/Documentation/thermal/sysfs-api.txt linux-libre-2.6.33-gnu1/Documentation/thermal/sysfs-api.txt
--- linux-libre-2.6.32-gnu1/Documentation/thermal/sysfs-api.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/thermal/sysfs-api.txt	2010-02-24 13:52:17.000000000 -0500
@@ -206,6 +206,7 @@ passive
 	passive trip point for the zone. Activation is done by polling with
 	an interval of 1 second.
 	Unit: millidegrees Celsius
+	Valid values: 0 (disabled) or greater than 1000
 	RW, Optional
 
 *****************************
diff -druNp linux-libre-2.6.32-gnu1/Documentation/timers/hpet.txt linux-libre-2.6.33-gnu1/Documentation/timers/hpet.txt
--- linux-libre-2.6.32-gnu1/Documentation/timers/hpet.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/timers/hpet.txt	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,7 @@
 The High Precision Event Timer (HPET) hardware follows a specification
 by Intel and Microsoft which can be found at
 
-	http://www.intel.com/technology/architecture/hpetspec.htm
+	http://www.intel.com/hardwaredesign/hpetspec_1.pdf
 
 Each HPET has one fixed-rate counter (at 10+ MHz, hence "High Precision")
 and up to 32 comparators.  Normally three or more comparators are provided,
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/events-kmem.txt linux-libre-2.6.33-gnu1/Documentation/trace/events-kmem.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/events-kmem.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/events-kmem.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 			Subsystem Trace Points: kmem
 
-The tracing system kmem captures events related to object and page allocation
-within the kernel. Broadly speaking there are four major subheadings.
+The kmem tracing system captures events related to object and page allocation
+within the kernel. Broadly speaking there are five major subheadings.
 
   o Slab allocation of small objects of unknown type (kmalloc)
   o Slab allocation of small objects of known type
@@ -9,7 +9,7 @@ within the kernel. Broadly speaking ther
   o Per-CPU Allocator Activity
   o External Fragmentation
 
-This document will describe what each of the tracepoints are and why they
+This document describes what each of the tracepoints is and why they
 might be useful.
 
 1. Slab allocation of small objects of unknown type
@@ -34,7 +34,7 @@ kmem_cache_free		call_site=%lx ptr=%p
 These events are similar in usage to the kmalloc-related events except that
 it is likely easier to pin the event down to a specific cache. At the time
 of writing, no information is available on what slab is being allocated from,
-but the call_site can usually be used to extrapolate that information
+but the call_site can usually be used to extrapolate that information.
 
 3. Page allocation
 ==================
@@ -80,9 +80,9 @@ event indicating whether it is for a per
 When the per-CPU list is too full, a number of pages are freed, each one
 which triggers a mm_page_pcpu_drain event.
 
-The individual nature of the events are so that pages can be tracked
+The individual nature of the events is so that pages can be tracked
 between allocation and freeing. A number of drain or refill pages that occur
-consecutively imply the zone->lock being taken once. Large amounts of PCP
+consecutively imply the zone->lock being taken once. Large amounts of per-CPU
 refills and drains could imply an imbalance between CPUs where too much work
 is being concentrated in one place. It could also indicate that the per-CPU
 lists should be a larger size. Finally, large amounts of refills on one CPU
@@ -102,6 +102,6 @@ is important.
 
 Large numbers of this event implies that memory is fragmenting and
 high-order allocations will start failing at some time in the future. One
-means of reducing the occurange of this event is to increase the size of
+means of reducing the occurrence of this event is to increase the size of
 min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
 pageblock_size is usually the size of the default hugepage size.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/ftrace-design.txt linux-libre-2.6.33-gnu1/Documentation/trace/ftrace-design.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/ftrace-design.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/ftrace-design.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 		function tracer guts
 		====================
+		By Mike Frysinger
 
 Introduction
 ------------
@@ -53,14 +54,14 @@ size of the mcount call that is embedded
 For example, if the function foo() calls bar(), when the bar() function calls
 mcount(), the arguments mcount() will pass to the tracer are:
 	"frompc" - the address bar() will use to return to foo()
-	"selfpc" - the address bar() (with _mcount() size adjustment)
+	"selfpc" - the address bar() (with mcount() size adjustment)
 
 Also keep in mind that this mcount function will be called *a lot*, so
 optimizing for the default case of no tracer will help the smooth running of
 your system when tracing is disabled.  So the start of the mcount function is
-typically the bare min with checking things before returning.  That also means
-the code flow should usually kept linear (i.e. no branching in the nop case).
-This is of course an optimization and not a hard requirement.
+typically the bare minimum with checking things before returning.  That also
+means the code flow should usually be kept linear (i.e. no branching in the nop
+case).  This is of course an optimization and not a hard requirement.
 
 Here is some pseudo code that should help (these functions should actually be
 implemented in assembly):
@@ -131,10 +132,10 @@ some functions to save (hijack) and rest
 
 The mcount function should check the function pointers ftrace_graph_return
 (compare to ftrace_stub) and ftrace_graph_entry (compare to
-ftrace_graph_entry_stub).  If either of those are not set to the relevant stub
+ftrace_graph_entry_stub).  If either of those is not set to the relevant stub
 function, call the arch-specific function ftrace_graph_caller which in turn
 calls the arch-specific function prepare_ftrace_return.  Neither of these
-function names are strictly required, but you should use them anyways to stay
+function names is strictly required, but you should use them anyway to stay
 consistent across the architecture ports -- easier to compare & contrast
 things.
 
@@ -144,7 +145,7 @@ but the first argument should be a point
 located on the stack.  This allows the function to hijack the return address
 temporarily to have it point to the arch-specific function return_to_handler.
 That function will simply call the common ftrace_return_to_handler function and
-that will return the original return address with which, you can return to the
+that will return the original return address with which you can return to the
 original call site.
 
 Here is the updated mcount pseudo code:
@@ -173,14 +174,16 @@ void ftrace_graph_caller(void)
 
 	unsigned long *frompc = &...;
 	unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
-	prepare_ftrace_return(frompc, selfpc);
+	/* passing frame pointer up is optional -- see below */
+	prepare_ftrace_return(frompc, selfpc, frame_pointer);
 
 	/* restore all state needed by the ABI */
 }
 #endif
 
-For information on how to implement prepare_ftrace_return(), simply look at
-the x86 version.  The only architecture-specific piece in it is the setup of
+For information on how to implement prepare_ftrace_return(), simply look at the
+x86 version (the frame pointer passing is optional; see the next section for
+more information).  The only architecture-specific piece in it is the setup of
 the fault recovery table (the asm(...) code).  The rest should be the same
 across architectures.
 
@@ -205,6 +208,23 @@ void return_to_handler(void)
 #endif
 
 
+HAVE_FUNCTION_GRAPH_FP_TEST
+---------------------------
+
+An arch may pass in a unique value (frame pointer) to both the entering and
+exiting of a function.  On exit, the value is compared and if it does not
+match, then it will panic the kernel.  This is largely a sanity check for bad
+code generation with gcc.  If gcc for your port sanely updates the frame
+pointer under different opitmization levels, then ignore this option.
+
+However, adding support for it isn't terribly difficult.  In your assembly code
+that calls prepare_ftrace_return(), pass the frame pointer as the 3rd argument.
+Then in the C version of that function, do what the x86 port does and pass it
+along to ftrace_push_return_trace() instead of a stub value of 0.
+
+Similarly, when you call ftrace_return_to_handler(), pass it the frame pointer.
+
+
 HAVE_FTRACE_NMI_ENTER
 ---------------------
 
@@ -213,10 +233,19 @@ If you can't trace NMI functions, then s
 <details to be filled>
 
 
-HAVE_FTRACE_SYSCALLS
+HAVE_SYSCALL_TRACEPOINTS
 ---------------------
 
-<details to be filled>
+You need very few things to get the syscalls tracing in an arch.
+
+- Have a NR_syscalls variable in <asm/unistd.h> that provides the number
+  of syscalls supported by the arch.
+- Implement arch_syscall_addr() that resolves a syscall address from a
+  syscall number.
+- Support the TIF_SYSCALL_TRACEPOINT thread flags
+- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
+  in the ptrace syscalls tracing path.
+- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
 
 
 HAVE_FTRACE_MCOUNT_RECORD
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/ftrace.txt linux-libre-2.6.33-gnu1/Documentation/trace/ftrace.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/ftrace.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/ftrace.txt	2010-02-24 13:52:17.000000000 -0500
@@ -1625,7 +1625,7 @@ If I am only interested in sys_nanosleep
 
  # echo sys_nanosleep hrtimer_interrupt \
 		> set_ftrace_filter
- # echo ftrace > current_tracer
+ # echo function > current_tracer
  # echo 1 > tracing_enabled
  # usleep 1
  # echo 0 > tracing_enabled
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/kprobetrace.txt linux-libre-2.6.33-gnu1/Documentation/trace/kprobetrace.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/kprobetrace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/kprobetrace.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,149 @@
+                        Kprobe-based Event Tracing
+                        ==========================
+
+                 Documentation is written by Masami Hiramatsu
+
+
+Overview
+--------
+These events are similar to tracepoint based events. Instead of Tracepoint,
+this is based on kprobes (kprobe and kretprobe). So it can probe wherever
+kprobes can probe (this means, all functions body except for __kprobes
+functions). Unlike the Tracepoint based event, this can be added and removed
+dynamically, on the fly.
+
+To enable this feature, build your kernel with CONFIG_KPROBE_TRACING=y.
+
+Similar to the events tracer, this doesn't need to be activated via
+current_tracer. Instead of that, add probe points via
+/sys/kernel/debug/tracing/kprobe_events, and enable it via
+/sys/kernel/debug/tracing/events/kprobes/<EVENT>/enabled.
+
+
+Synopsis of kprobe_events
+-------------------------
+  p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS]	: Set a probe
+  r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS]		: Set a return probe
+
+ GRP		: Group name. If omitted, use "kprobes" for it.
+ EVENT		: Event name. If omitted, the event name is generated
+		  based on SYMBOL+offs or MEMADDR.
+ SYMBOL[+offs]	: Symbol+offset where the probe is inserted.
+ MEMADDR	: Address where the probe is inserted.
+
+ FETCHARGS	: Arguments. Each probe can have up to 128 args.
+  %REG		: Fetch register REG
+  @ADDR		: Fetch memory at ADDR (ADDR should be in kernel)
+  @SYM[+|-offs]	: Fetch memory at SYM +|- offs (SYM should be a data symbol)
+  $stackN	: Fetch Nth entry of stack (N >= 0)
+  $stack	: Fetch stack address.
+  $argN		: Fetch function argument. (N >= 0)(*)
+  $retval	: Fetch return value.(**)
+  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
+  NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
+
+  (*) aN may not correct on asmlinkaged functions and at the middle of
+      function body.
+  (**) only for return probe.
+  (***) this is useful for fetching a field of data structures.
+
+
+Per-Probe Event Filtering
+-------------------------
+ Per-probe event filtering feature allows you to set different filter on each
+probe and gives you what arguments will be shown in trace buffer. If an event
+name is specified right after 'p:' or 'r:' in kprobe_events, it adds an event
+under tracing/events/kprobes/<EVENT>, at the directory you can see 'id',
+'enabled', 'format' and 'filter'.
+
+enabled:
+  You can enable/disable the probe by writing 1 or 0 on it.
+
+format:
+  This shows the format of this probe event.
+
+filter:
+  You can write filtering rules of this event.
+
+id:
+  This shows the id of this probe event.
+
+
+Event Profiling
+---------------
+ You can check the total number of probe hits and probe miss-hits via
+/sys/kernel/debug/tracing/kprobe_profile.
+ The first column is event name, the second is the number of probe hits,
+the third is the number of probe miss-hits.
+
+
+Usage examples
+--------------
+To add a probe as a new event, write a new definition to kprobe_events
+as below.
+
+  echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events
+
+ This sets a kprobe on the top of do_sys_open() function with recording
+1st to 4th arguments as "myprobe" event. As this example shows, users can
+choose more familiar names for each arguments.
+
+  echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events
+
+ This sets a kretprobe on the return point of do_sys_open() function with
+recording return value as "myretprobe" event.
+ You can see the format of these events via
+/sys/kernel/debug/tracing/events/kprobes/<EVENT>/format.
+
+  cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
+name: myprobe
+ID: 75
+format:
+	field:unsigned short common_type;	offset:0;	size:2;
+	field:unsigned char common_flags;	offset:2;	size:1;
+	field:unsigned char common_preempt_count;	offset:3;	size:1;
+	field:int common_pid;	offset:4;	size:4;
+	field:int common_tgid;	offset:8;	size:4;
+
+	field: unsigned long ip;	offset:16;tsize:8;
+	field: int nargs;	offset:24;tsize:4;
+	field: unsigned long dfd;	offset:32;tsize:8;
+	field: unsigned long filename;	offset:40;tsize:8;
+	field: unsigned long flags;	offset:48;tsize:8;
+	field: unsigned long mode;	offset:56;tsize:8;
+
+print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode
+
+
+ You can see that the event has 4 arguments as in the expressions you specified.
+
+  echo > /sys/kernel/debug/tracing/kprobe_events
+
+ This clears all probe points.
+
+ Right after definition, each event is disabled by default. For tracing these
+events, you need to enable it.
+
+  echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
+  echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
+
+ And you can see the traced information via /sys/kernel/debug/tracing/trace.
+
+  cat /sys/kernel/debug/tracing/trace
+# tracer: nop
+#
+#           TASK-PID    CPU#    TIMESTAMP  FUNCTION
+#              | |       |          |         |
+           <...>-1447  [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
+           <...>-1447  [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $retval=fffffffffffffffe
+           <...>-1447  [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
+           <...>-1447  [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
+           <...>-1447  [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
+           <...>-1447  [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
+
+
+ Each line shows when the kernel hits an event, and <- SYMBOL means kernel
+returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
+returns from do_sys_open to sys_open+0x1b).
+
+
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/mmiotrace.txt linux-libre-2.6.33-gnu1/Documentation/trace/mmiotrace.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/mmiotrace.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/mmiotrace.txt	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,8 @@ Check for lost events.
 Usage
 -----
 
-Make sure debugfs is mounted to /sys/kernel/debug. If not, (requires root privileges)
+Make sure debugfs is mounted to /sys/kernel/debug.
+If not (requires root privileges):
 $ mount -t debugfs debugfs /sys/kernel/debug
 
 Check that the driver you are about to trace is not loaded.
@@ -91,7 +92,7 @@ $ dmesg > dmesg.txt
 $ tar zcf pciid-nick-mmiotrace.tar.gz mydump.txt lspci.txt dmesg.txt
 and then send the .tar.gz file. The trace compresses considerably. Replace
 "pciid" and "nick" with the PCI ID or model name of your piece of hardware
-under investigation and your nick name.
+under investigation and your nickname.
 
 
 How Mmiotrace Works
@@ -100,7 +101,7 @@ How Mmiotrace Works
 Access to hardware IO-memory is gained by mapping addresses from PCI bus by
 calling one of the ioremap_*() functions. Mmiotrace is hooked into the
 __ioremap() function and gets called whenever a mapping is created. Mapping is
-an event that is recorded into the trace log. Note, that ISA range mappings
+an event that is recorded into the trace log. Note that ISA range mappings
 are not caught, since the mapping always exists and is returned directly.
 
 MMIO accesses are recorded via page faults. Just before __ioremap() returns,
@@ -122,11 +123,11 @@ Trace Log Format
 ----------------
 
 The raw log is text and easily filtered with e.g. grep and awk. One record is
-one line in the log. A record starts with a keyword, followed by keyword
-dependant arguments. Arguments are separated by a space, or continue until the
+one line in the log. A record starts with a keyword, followed by keyword-
+dependent arguments. Arguments are separated by a space, or continue until the
 end of line. The format for version 20070824 is as follows:
 
-Explanation	Keyword	Space separated arguments
+Explanation	Keyword	Space-separated arguments
 ---------------------------------------------------------------------------
 
 read event	R	width, timestamp, map id, physical, value, PC, PID
@@ -136,7 +137,7 @@ iounmap event	UNMAP	timestamp, map id, P
 marker		MARK	timestamp, text
 version		VERSION	the string "20070824"
 info for reader	LSPCI	one line from lspci -v
-PCI address map	PCIDEV	space separated /proc/bus/pci/devices data
+PCI address map	PCIDEV	space-separated /proc/bus/pci/devices data
 unk. opcode	UNKNOWN	timestamp, map id, physical, data, PC, PID
 
 Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/ring-buffer-design.txt linux-libre-2.6.33-gnu1/Documentation/trace/ring-buffer-design.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/ring-buffer-design.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/ring-buffer-design.txt	2010-02-24 13:52:17.000000000 -0500
@@ -33,9 +33,9 @@ head_page - a pointer to the page that t
 
 tail_page - a pointer to the page that will be written to next
 
-commit_page - a pointer to the page with the last finished non nested write.
+commit_page - a pointer to the page with the last finished non-nested write.
 
-cmpxchg - hardware assisted atomic transaction that performs the following:
+cmpxchg - hardware-assisted atomic transaction that performs the following:
 
    A = B iff previous A == C
 
@@ -52,15 +52,15 @@ The Generic Ring Buffer
 The ring buffer can be used in either an overwrite mode or in
 producer/consumer mode.
 
-Producer/consumer mode is where the producer were to fill up the
+Producer/consumer mode is where if the producer were to fill up the
 buffer before the consumer could free up anything, the producer
 will stop writing to the buffer. This will lose most recent events.
 
-Overwrite mode is where the produce were to fill up the buffer
+Overwrite mode is where if the producer were to fill up the buffer
 before the consumer could free up anything, the producer will
 overwrite the older data. This will lose the oldest events.
 
-No two writers can write at the same time (on the same per cpu buffer),
+No two writers can write at the same time (on the same per-cpu buffer),
 but a writer may interrupt another writer, but it must finish writing
 before the previous writer may continue. This is very important to the
 algorithm. The writers act like a "stack". The way interrupts works
@@ -79,16 +79,16 @@ the interrupt doing a write as well.
 
 Readers can happen at any time. But no two readers may run at the
 same time, nor can a reader preempt/interrupt another reader. A reader
-can not preempt/interrupt a writer, but it may read/consume from the
+cannot preempt/interrupt a writer, but it may read/consume from the
 buffer at the same time as a writer is writing, but the reader must be
 on another processor to do so. A reader may read on its own processor
 and can be preempted by a writer.
 
-A writer can preempt a reader, but a reader can not preempt a writer.
+A writer can preempt a reader, but a reader cannot preempt a writer.
 But a reader can read the buffer at the same time (on another processor)
 as a writer.
 
-The ring buffer is made up of a list of pages held together by a link list.
+The ring buffer is made up of a list of pages held together by a linked list.
 
 At initialization a reader page is allocated for the reader that is not
 part of the ring buffer.
@@ -102,7 +102,7 @@ the head page.
 
 The reader has its own page to use. At start up time, this page is
 allocated but is not attached to the list. When the reader wants
-to read from the buffer, if its page is empty (like it is on start up)
+to read from the buffer, if its page is empty (like it is on start-up),
 it will swap its page with the head_page. The old reader page will
 become part of the ring buffer and the head_page will be removed.
 The page after the inserted page (old reader_page) will become the
@@ -206,7 +206,7 @@ The main pointers:
 
   commit page - the page that last finished a write.
 
-The commit page only is updated by the outer most writer in the
+The commit page only is updated by the outermost writer in the
 writer stack. A writer that preempts another writer will not move the
 commit page.
 
@@ -281,7 +281,7 @@ with the previous write.
 The commit pointer points to the last write location that was
 committed without preempting another write. When a write that
 preempted another write is committed, it only becomes a pending commit
-and will not be a full commit till all writes have been committed.
+and will not be a full commit until all writes have been committed.
 
 The commit page points to the page that has the last full commit.
 The tail page points to the page with the last write (before
@@ -292,7 +292,7 @@ be several pages ahead. If the tail page
 page then no more writes may take place (regardless of the mode
 of the ring buffer: overwrite and produce/consumer).
 
-The order of pages are:
+The order of pages is:
 
  head page
  commit page
@@ -311,7 +311,7 @@ Possible scenario:
 There is a special case that the head page is after either the commit page
 and possibly the tail page. That is when the commit (and tail) page has been
 swapped with the reader page. This is because the head page is always
-part of the ring buffer, but the reader page is not. When ever there
+part of the ring buffer, but the reader page is not. Whenever there
 has been less than a full page that has been committed inside the ring buffer,
 and a reader swaps out a page, it will be swapping out the commit page.
 
@@ -338,7 +338,7 @@ and a reader swaps out a page, it will b
 In this case, the head page will not move when the tail and commit
 move back into the ring buffer.
 
-The reader can not swap a page into the ring buffer if the commit page
+The reader cannot swap a page into the ring buffer if the commit page
 is still on that page. If the read meets the last commit (real commit
 not pending or reserved), then there is nothing more to read.
 The buffer is considered empty until another full commit finishes.
@@ -395,7 +395,7 @@ The main idea behind the lockless algori
 of the head_page pointer with the swapping of pages with the reader.
 State flags are placed inside the pointer to the page. To do this,
 each page must be aligned in memory by 4 bytes. This will allow the 2
-least significant bits of the address to be used as flags. Since
+least significant bits of the address to be used as flags, since
 they will always be zero for the address. To get the address,
 simply mask out the flags.
 
@@ -460,7 +460,7 @@ When the reader tries to swap the page w
 will also use cmpxchg. If the flag bit in the pointer to the
 head page does not have the HEADER flag set, the compare will fail
 and the reader will need to look for the new head page and try again.
-Note, the flag UPDATE and HEADER are never set at the same time.
+Note, the flags UPDATE and HEADER are never set at the same time.
 
 The reader swaps the reader page as follows:
 
@@ -539,7 +539,7 @@ updated to the reader page.
     |  +-----------------------------+   |
     +------------------------------------+
 
-Another important point. The page that the reader page points back to
+Another important point: The page that the reader page points back to
 by its previous pointer (the one that now points to the new head page)
 never points back to the reader page. That is because the reader page is
 not part of the ring buffer. Traversing the ring buffer via the next pointers
@@ -572,7 +572,7 @@ not be able to swap the head page from t
 move the head page, until the writer is finished with the move.
 
 This eliminates any races that the reader can have on the writer. The reader
-must spin, and this is why the reader can not preempt the writer.
+must spin, and this is why the reader cannot preempt the writer.
 
             tail page
                |
@@ -659,9 +659,9 @@ before pushing the head page. If it is,
 tail page wrapped the buffer, and we must drop new writes.
 
 This is not a race condition, because the commit page can only be moved
-by the outter most writer (the writer that was preempted).
+by the outermost writer (the writer that was preempted).
 This means that the commit will not move while a writer is moving the
-tail page. The reader can not swap the reader page if it is also being
+tail page. The reader cannot swap the reader page if it is also being
 used as the commit page. The reader can simply check that the commit
 is off the reader page. Once the commit page leaves the reader page
 it will never go back on it unless a reader does another swap with the
@@ -733,7 +733,7 @@ The write converts the head page pointer
 --->|   |<---|   |<---|   |<---|   |<---
     +---+    +---+    +---+    +---+
 
-But if a nested writer preempts here. It will see that the next
+But if a nested writer preempts here, it will see that the next
 page is a head page, but it is also nested. It will detect that
 it is nested and will save that information. The detection is the
 fact that it sees the UPDATE flag instead of a HEADER or NORMAL
@@ -761,7 +761,7 @@ to NORMAL.
 --->|   |<---|   |<---|   |<---|   |<---
     +---+    +---+    +---+    +---+
 
-After the nested writer finishes, the outer most writer will convert
+After the nested writer finishes, the outermost writer will convert
 the UPDATE pointer to NORMAL.
 
 
@@ -812,7 +812,7 @@ head page.
     +---+    +---+    +---+    +---+
 
 The nested writer moves the tail page forward. But does not set the old
-update page to NORMAL because it is not the outer most writer.
+update page to NORMAL because it is not the outermost writer.
 
                     tail page
                         |
@@ -892,7 +892,7 @@ It will return to the first writer.
 --->|   |<---|   |<---|   |<---|   |<---
     +---+    +---+    +---+    +---+
 
-The first writer can not know atomically test if the tail page moved
+The first writer cannot know atomically if the tail page moved
 while it updates the HEAD page. It will then update the head page to
 what it thinks is the new head page.
 
@@ -923,9 +923,9 @@ if the tail page is either where it use
 --->|   |<---|   |<---|   |<---|   |<---
     +---+    +---+    +---+    +---+
 
-If tail page != A and tail page does not equal B, then it must reset the
-pointer back to NORMAL. The fact that it only needs to worry about
-nested writers, it only needs to check this after setting the HEAD page.
+If tail page != A and tail page != B, then it must reset the pointer
+back to NORMAL. The fact that it only needs to worry about nested
+writers means that it only needs to check this after setting the HEAD page.
 
 
 (first writer)
@@ -939,7 +939,7 @@ nested writers, it only needs to check t
     +---+    +---+    +---+    +---+
 
 Now the writer can update the head page. This is also why the head page must
-remain in UPDATE and only reset by the outer most writer. This prevents
+remain in UPDATE and only reset by the outermost writer. This prevents
 the reader from seeing the incorrect head page.
 
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/trace/tracepoint-analysis.txt linux-libre-2.6.33-gnu1/Documentation/trace/tracepoint-analysis.txt
--- linux-libre-2.6.32-gnu1/Documentation/trace/tracepoint-analysis.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/trace/tracepoint-analysis.txt	2010-02-24 13:52:17.000000000 -0500
@@ -10,8 +10,8 @@ Tracepoints (see Documentation/trace/tra
 creating custom kernel modules to register probe functions using the event
 tracing infrastructure.
 
-Simplistically, tracepoints will represent an important event that when can
-be taken in conjunction with other tracepoints to build a "Big Picture" of
+Simplistically, tracepoints represent important events that can be
+taken in conjunction with other tracepoints to build a "Big Picture" of
 what is going on within the system. There are a large number of methods for
 gathering and interpreting these events. Lacking any current Best Practises,
 this document describes some of the methods that can be used.
@@ -33,12 +33,12 @@ calling
 
 will give a fair indication of the number of events available.
 
-2.2 PCL
+2.2 PCL (Performance Counters for Linux)
 -------
 
-Discovery and enumeration of all counters and events, including tracepoints
+Discovery and enumeration of all counters and events, including tracepoints,
 are available with the perf tool. Getting a list of available events is a
-simple case of
+simple case of:
 
   $ perf list 2>&1 | grep Tracepoint
   ext4:ext4_free_inode                     [Tracepoint event]
@@ -49,19 +49,19 @@ simple case of
   [ .... remaining output snipped .... ]
 
 
-2. Enabling Events
+3. Enabling Events
 ==================
 
-2.1 System-Wide Event Enabling
+3.1 System-Wide Event Enabling
 ------------------------------
 
 See Documentation/trace/events.txt for a proper description on how events
 can be enabled system-wide. A short example of enabling all events related
-to page allocation would look something like
+to page allocation would look something like:
 
   $ for i in `find /sys/kernel/debug/tracing/events -name "enable" | grep mm_`; do echo 1 > $i; done
 
-2.2 System-Wide Event Enabling with SystemTap
+3.2 System-Wide Event Enabling with SystemTap
 ---------------------------------------------
 
 In SystemTap, tracepoints are accessible using the kernel.trace() function
@@ -86,7 +86,7 @@ were allocating the pages.
           print_count()
   }
 
-2.3 System-Wide Event Enabling with PCL
+3.3 System-Wide Event Enabling with PCL
 ---------------------------------------
 
 By specifying the -a switch and analysing sleep, the system-wide events
@@ -107,16 +107,16 @@ for a duration of time can be examined.
 Similarly, one could execute a shell and exit it as desired to get a report
 at that point.
 
-2.4 Local Event Enabling
+3.4 Local Event Enabling
 ------------------------
 
 Documentation/trace/ftrace.txt describes how to enable events on a per-thread
 basis using set_ftrace_pid.
 
-2.5 Local Event Enablement with PCL
+3.5 Local Event Enablement with PCL
 -----------------------------------
 
-Events can be activate and tracked for the duration of a process on a local
+Events can be activated and tracked for the duration of a process on a local
 basis using PCL such as follows.
 
   $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \
@@ -131,18 +131,18 @@ basis using PCL such as follows.
 
     0.973913387  seconds time elapsed
 
-3. Event Filtering
+4. Event Filtering
 ==================
 
 Documentation/trace/ftrace.txt covers in-depth how to filter events in
 ftrace.  Obviously using grep and awk of trace_pipe is an option as well
 as any script reading trace_pipe.
 
-4. Analysing Event Variances with PCL
+5. Analysing Event Variances with PCL
 =====================================
 
 Any workload can exhibit variances between runs and it can be important
-to know what the standard deviation in. By and large, this is left to the
+to know what the standard deviation is. By and large, this is left to the
 performance analyst to do it by hand. In the event that the discrete event
 occurrences are useful to the performance analyst, then perf can be used.
 
@@ -166,7 +166,7 @@ In the event that some higher-level even
 aggregation of discrete events, then a script would need to be developed.
 
 Using --repeat, it is also possible to view how events are fluctuating over
-time on a system wide basis using -a and sleep.
+time on a system-wide basis using -a and sleep.
 
   $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free_direct \
 		-e kmem:mm_pagevec_free \
@@ -180,7 +180,7 @@ time on a system wide basis using -a and
 
     1.002251757  seconds time elapsed   ( +-   0.005% )
 
-5. Higher-Level Analysis with Helper Scripts
+6. Higher-Level Analysis with Helper Scripts
 ============================================
 
 When events are enabled the events that are triggering can be read from
@@ -190,11 +190,11 @@ be gathered on-line as appropriate. Exam
 
   o Reading information from /proc for the PID that triggered the event
   o Deriving a higher-level event from a series of lower-level events.
-  o Calculate latencies between two events
+  o Calculating latencies between two events
 
 Documentation/trace/postprocess/trace-pagealloc-postprocess.pl is an example
 script that can read trace_pipe from STDIN or a copy of a trace. When used
-on-line, it can be interrupted once to generate a report without existing
+on-line, it can be interrupted once to generate a report without exiting
 and twice to exit.
 
 Simplistically, the script just reads STDIN and counts up events but it
@@ -212,12 +212,12 @@ also can do more such as
     processes, the parent process responsible for creating all the helpers
     can be identified
 
-6. Lower-Level Analysis with PCL
+7. Lower-Level Analysis with PCL
 ================================
 
-There may also be a requirement to identify what functions with a program
+There may also be a requirement to identify what functions within a program
 were generating events within the kernel. To begin this sort of analysis, the
-data must be recorded. At the time of writing, this required root
+data must be recorded. At the time of writing, this required root:
 
   $ perf record -c 1 \
 	-e kmem:mm_page_alloc -e kmem:mm_page_free_direct \
@@ -253,11 +253,11 @@ perf report.
   # (For more details, try: perf report --sort comm,dso,symbol)
   #
 
-According to this, the vast majority of events occured triggered on events
-within the VDSO. With simple binaries, this will often be the case so lets
+According to this, the vast majority of events triggered on events
+within the VDSO. With simple binaries, this will often be the case so let's
 take a slightly different example. In the course of writing this, it was
-noticed that X was generating an insane amount of page allocations so lets look
-at it
+noticed that X was generating an insane amount of page allocations so let's look
+at it:
 
   $ perf record -c 1 -f \
 		-e kmem:mm_page_alloc -e kmem:mm_page_free_direct \
@@ -280,8 +280,8 @@ This was interrupted after a few seconds
   # (For more details, try: perf report --sort comm,dso,symbol)
   #
 
-So, almost half of the events are occuring in a library. To get an idea which
-symbol.
+So, almost half of the events are occurring in a library. To get an idea which
+symbol:
 
   $ perf report --sort comm,dso,symbol
   # Samples: 27666
@@ -297,7 +297,7 @@ symbol.
        0.01%     Xorg  /opt/gfx-test/lib/libpixman-1.so.0.13.1  [.] get_fast_path
        0.00%     Xorg  [kernel]                                 [k] ftrace_trace_userstack
 
-To see where within the function pixmanFillsse2 things are going wrong
+To see where within the function pixmanFillsse2 things are going wrong:
 
   $ perf annotate pixmanFillsse2
   [ ... ]
diff -druNp linux-libre-2.6.32-gnu1/Documentation/usb/power-management.txt linux-libre-2.6.33-gnu1/Documentation/usb/power-management.txt
--- linux-libre-2.6.32-gnu1/Documentation/usb/power-management.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/usb/power-management.txt	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
 
 		 Alan Stern <stern@rowland.harvard.edu>
 
-			    October 5, 2007
+			    November 10, 2009
 
 
 
@@ -71,12 +71,10 @@ being accessed through sysfs, then it de
 	Forms of dynamic PM
 	-------------------
 
-Dynamic suspends can occur in two ways: manual and automatic.
-"Manual" means that the user has told the kernel to suspend a device,
-whereas "automatic" means that the kernel has decided all by itself to
-suspend a device.  Automatic suspend is called "autosuspend" for
-short.  In general, a device won't be autosuspended unless it has been
-idle for some minimum period of time, the so-called idle-delay time.
+Dynamic suspends occur when the kernel decides to suspend an idle
+device.  This is called "autosuspend" for short.  In general, a device
+won't be autosuspended unless it has been idle for some minimum period
+of time, the so-called idle-delay time.
 
 Of course, nothing the kernel does on its own initiative should
 prevent the computer or its devices from working properly.  If a
@@ -96,10 +94,11 @@ idle.
 We can categorize power management events in two broad classes:
 external and internal.  External events are those triggered by some
 agent outside the USB stack: system suspend/resume (triggered by
-userspace), manual dynamic suspend/resume (also triggered by
-userspace), and remote wakeup (triggered by the device).  Internal
-events are those triggered within the USB stack: autosuspend and
-autoresume.
+userspace), manual dynamic resume (also triggered by userspace), and
+remote wakeup (triggered by the device).  Internal events are those
+triggered within the USB stack: autosuspend and autoresume.  Note that
+all dynamic suspend events are internal; external agents are not
+allowed to issue dynamic suspends.
 
 
 	The user interface for dynamic PM
@@ -123,9 +122,9 @@ relevant attribute files are: wakeup, le
 
 	power/level
 
-		This file contains one of three words: "on", "auto",
-		or "suspend".  You can write those words to the file
-		to change the device's setting.
+		This file contains one of two words: "on" or "auto".
+		You can write those words to the file to change the
+		device's setting.
 
 		"on" means that the device should be resumed and
 		autosuspend is not allowed.  (Of course, system
@@ -134,10 +133,10 @@ relevant attribute files are: wakeup, le
 		"auto" is the normal state in which the kernel is
 		allowed to autosuspend and autoresume the device.
 
-		"suspend" means that the device should remain
-		suspended, and autoresume is not allowed.  (But remote
-		wakeup may still be allowed, since it is controlled
-		separately by the power/wakeup attribute.)
+		(In kernels up to 2.6.32, you could also specify
+		"suspend", meaning that the device should remain
+		suspended and autoresume was not allowed.  This
+		setting is no longer supported.)
 
 	power/autosuspend
 
@@ -145,9 +144,9 @@ relevant attribute files are: wakeup, le
 		number of seconds the device should remain idle before
 		the kernel will autosuspend it (the idle-delay time).
 		The default is 2.  0 means to autosuspend as soon as
-		the device becomes idle, and -1 means never to
-		autosuspend.  You can write a number to the file to
-		change the autosuspend idle-delay time.
+		the device becomes idle, and negative values mean
+		never to autosuspend.  You can write a number to the
+		file to change the autosuspend idle-delay time.
 
 Writing "-1" to power/autosuspend and writing "on" to power/level do
 essentially the same thing -- they both prevent the device from being
@@ -313,13 +312,14 @@ three of the methods listed above.  In a
 that it supports autosuspend by setting the .supports_autosuspend flag
 in its usb_driver structure.  It is then responsible for informing the
 USB core whenever one of its interfaces becomes busy or idle.  The
-driver does so by calling these five functions:
+driver does so by calling these six functions:
 
 	int  usb_autopm_get_interface(struct usb_interface *intf);
 	void usb_autopm_put_interface(struct usb_interface *intf);
-	int  usb_autopm_set_interface(struct usb_interface *intf);
 	int  usb_autopm_get_interface_async(struct usb_interface *intf);
 	void usb_autopm_put_interface_async(struct usb_interface *intf);
+	void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
+	void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
 
 The functions work by maintaining a counter in the usb_interface
 structure.  When intf->pm_usage_count is > 0 then the interface is
@@ -331,11 +331,13 @@ considered to be idle, and the kernel ma
 associated with the device itself rather than any of its interfaces.
 This field is used only by the USB core.)
 
-The driver owns intf->pm_usage_count; it can modify the value however
-and whenever it likes.  A nice aspect of the non-async usb_autopm_*
-routines is that the changes they make are protected by the usb_device
-structure's PM mutex (udev->pm_mutex); however drivers may change
-pm_usage_count without holding the mutex.  Drivers using the async
+Drivers must not modify intf->pm_usage_count directly; its value
+should be changed only be using the functions listed above.  Drivers
+are responsible for insuring that the overall change to pm_usage_count
+during their lifetime balances out to 0 (it may be necessary for the
+disconnect method to call usb_autopm_put_interface() one or more times
+to fulfill this requirement).  The first two routines use the PM mutex
+in struct usb_device for mutual exclusion; drivers using the async
 routines are responsible for their own synchronization and mutual
 exclusion.
 
@@ -347,11 +349,6 @@ exclusion.
 	attempts an autosuspend if the new value is <= 0 and the
 	device isn't suspended.
 
-	usb_autopm_set_interface() leaves pm_usage_count alone.
-	It attempts an autoresume if the value is > 0 and the device
-	is suspended, and it attempts an autosuspend if the value is
-	<= 0 and the device isn't suspended.
-
 	usb_autopm_get_interface_async() and
 	usb_autopm_put_interface_async() do almost the same things as
 	their non-async counterparts.  The differences are: they do
@@ -360,13 +357,11 @@ exclusion.
 	such as an URB's completion handler, but when they return the
 	device will not generally not yet be in the desired state.
 
-There also are a couple of utility routines drivers can use:
-
-	usb_autopm_enable() sets pm_usage_cnt to 0 and then calls
-	usb_autopm_set_interface(), which will attempt an autosuspend.
-
-	usb_autopm_disable() sets pm_usage_cnt to 1 and then calls
-	usb_autopm_set_interface(), which will attempt an autoresume.
+	usb_autopm_get_interface_no_resume() and
+	usb_autopm_put_interface_no_suspend() merely increment or
+	decrement the pm_usage_count value; they do not attempt to
+	carry out an autoresume or an autosuspend.  Hence they can be
+	called in an atomic context.
 
 The conventional usage pattern is that a driver calls
 usb_autopm_get_interface() in its open routine and
@@ -381,9 +376,9 @@ the device hasn't been idle for long eno
 routine is automatically set up to carry out the operation when the
 autosuspend idle-delay has expired.
 
-Autoresume attempts also can fail.  This will happen if power/level is
-set to "suspend" or if the device doesn't manage to resume properly.
-Unlike autosuspend, there's no delay for an autoresume.
+Autoresume attempts also can fail, although failure would mean that
+the device is no longer present or operating properly.  Unlike
+autosuspend, there's no delay for an autoresume.
 
 
 	Other parts of the driver interface
@@ -400,11 +395,11 @@ though, setting this flag won't cause th
 Normally a driver would set this flag in its probe method, at which
 time the device is guaranteed not to be autosuspended.)
 
-The usb_autopm_* routines have to run in a sleepable process context;
-they must not be called from an interrupt handler or while holding a
-spinlock.  In fact, the entire autosuspend mechanism is not well geared
-toward interrupt-driven operation.  However there is one thing a
-driver can do in an interrupt handler:
+The synchronous usb_autopm_* routines have to run in a sleepable
+process context; they must not be called from an interrupt handler or
+while holding a spinlock.  In fact, the entire autosuspend mechanism
+is not well geared toward interrupt-driven operation.  However there
+is one thing a driver can do in an interrupt handler:
 
 	usb_mark_last_busy(struct usb_device *udev);
 
@@ -423,15 +418,16 @@ an URB had completed too recently.
 
 External suspend calls should never be allowed to fail in this way,
 only autosuspend calls.  The driver can tell them apart by checking
-udev->auto_pm; this flag will be set to 1 for internal PM events
-(autosuspend or autoresume) and 0 for external PM events.
+the PM_EVENT_AUTO bit in the message.event argument to the suspend
+method; this bit will be set for internal PM events (autosuspend) and
+clear for external PM events.
 
 Many of the ingredients in the autosuspend framework are oriented
 towards interfaces: The usb_interface structure contains the
 pm_usage_cnt field, and the usb_autopm_* routines take an interface
 pointer as their argument.  But somewhat confusingly, a few of the
-pieces (usb_mark_last_busy() and udev->auto_pm) use the usb_device
-structure instead.  Drivers need to keep this straight; they can call
+pieces (i.e., usb_mark_last_busy()) use the usb_device structure
+instead.  Drivers need to keep this straight; they can call
 interface_to_usbdev() to find the device structure for a given
 interface.
 
@@ -530,13 +526,3 @@ succeed, it may still remain active and
 resume as soon as the system suspend is complete.  Or the remote
 wakeup may fail and get lost.  Which outcome occurs depends on timing
 and on the hardware and firmware design.
-
-More interestingly, a device might undergo a manual resume or
-autoresume during system suspend.  With current kernels this shouldn't
-happen, because manual resumes must be initiated by userspace and
-autoresumes happen in response to I/O requests, but all user processes
-and I/O should be quiescent during a system suspend -- thanks to the
-freezer.  However there are plans to do away with the freezer, which
-would mean these things would become possible.  If and when this comes
-about, the USB core will carefully arrange matters so that either type
-of resume will block until the entire system has resumed.
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vgaarbiter.txt linux-libre-2.6.33-gnu1/Documentation/vgaarbiter.txt
--- linux-libre-2.6.32-gnu1/Documentation/vgaarbiter.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vgaarbiter.txt	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,7 @@ I.2 libpciaccess
 ----------------
 
 To use the vga arbiter char device it was implemented an API inside the
-libpciaccess library. One fieldd was added to struct pci_device (each device
+libpciaccess library. One field was added to struct pci_device (each device
 on the system):
 
     /* the type of resource decoded by the device */
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.cx23885 linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx23885
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.cx23885	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx23885	2010-02-24 13:52:17.000000000 -0500
@@ -24,3 +24,5 @@
  23 -> Magic-Pro ProHDTV Extreme 2                         [14f1:8657]
  24 -> Hauppauge WinTV-HVR1850                             [0070:8541]
  25 -> Compro VideoMate E800                               [1858:e800]
+ 26 -> Hauppauge WinTV-HVR1290                             [0070:8551]
+ 27 -> Mygica X8558 PRO DMB-TH                             [14f1:8578]
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.cx88 linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx88
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.cx88	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.cx88	2010-02-24 13:52:17.000000000 -0500
@@ -81,3 +81,4 @@
  80 -> Hauppauge WinTV-IR Only                             [0070:9290]
  81 -> Leadtek WinFast DTV1800 Hybrid                      [107d:6654]
  82 -> WinFast DTV2000 H rev. J                            [107d:6f2b]
+ 83 -> Prof 7301 DVB-S/S2                                  [b034:3034]
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.em28xx linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.em28xx
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.em28xx	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.em28xx	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
@@ -69,3 +69,4 @@
  71 -> Silvercrest Webcam 1.3mpix               (em2820/em2840)
  72 -> Gadmei UTV330+                           (em2861)
  73 -> Reddo DVB-C USB TV Box                   (em2870)
+ 74 -> Actionmaster/LinXcel/Digitus VC211A      (em2800)
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.saa7134 linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.saa7134
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/CARDLIST.saa7134	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/CARDLIST.saa7134	2010-02-24 13:52:17.000000000 -0500
@@ -172,3 +172,5 @@
 171 -> Beholder BeholdTV X7                     [5ace:7595]
 172 -> RoverMedia TV Link Pro FM                [19d1:0138]
 173 -> Zolid Hybrid TV Tuner PCI                [1131:2004]
+174 -> Asus Europa Hybrid OEM                   [1043:4847]
+175 -> Leadtek Winfast DTV1000S                 [107d:6655]
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/gspca.txt linux-libre-2.6.33-gnu1/Documentation/video4linux/gspca.txt
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/gspca.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/gspca.txt	2010-02-24 13:52:17.000000000 -0500
@@ -6,11 +6,13 @@ The modules are:
 
 xxxx		vend:prod
 ----
-spca501		0000:0000	MystFromOri Unknow Camera
+spca501		0000:0000	MystFromOri Unknown Camera
+spca508		0130:0130	Clone Digital Webcam 11043
 m5602		0402:5602	ALi Video Camera Controller
 spca501		040a:0002	Kodak DVC-325
 spca500		040a:0300	Kodak EZ200
 zc3xx		041e:041e	Creative WebCam Live!
+ov519		041e:4003	Video Blaster WebCam Go Plus
 spca500		041e:400a	Creative PC-CAM 300
 sunplus		041e:400b	Creative PC-CAM 600
 sunplus		041e:4012	PC-Cam350
@@ -37,6 +39,7 @@ ov519		041e:405f	Creative Live! VISTA VF
 ov519		041e:4060	Creative Live! VISTA VF0350
 ov519		041e:4061	Creative Live! VISTA VF0400
 ov519		041e:4064	Creative Live! VISTA VF0420
+ov519		041e:4067	Creative Live! Cam Video IM (VF0350)
 ov519		041e:4068	Creative Live! VISTA VF0470
 spca561		0458:7004	Genius VideoCAM Express V2
 sunplus		0458:7006	Genius Dsc 1.3 Smart
@@ -68,12 +71,12 @@ zc3xx		046d:08a3	Logitech QC Chat
 zc3xx		046d:08a6	Logitech QCim
 zc3xx		046d:08a7	Logitech QuickCam Image
 zc3xx		046d:08a9	Logitech Notebook Deluxe
-zc3xx		046d:08aa	Labtec Webcam  Notebook
+zc3xx		046d:08aa	Labtec Webcam Notebook
 zc3xx		046d:08ac	Logitech QuickCam Cool
 zc3xx		046d:08ad	Logitech QCCommunicate STX
 zc3xx		046d:08ae	Logitech QuickCam for Notebooks
 zc3xx		046d:08af	Logitech QuickCam Cool
-zc3xx		046d:08b9	Logitech QC IM ???
+zc3xx		046d:08b9	Logitech QuickCam Express
 zc3xx		046d:08d7	Logitech QCam STX
 zc3xx		046d:08d9	Logitech QuickCam IM/Connect
 zc3xx		046d:08d8	Logitech Notebook Deluxe
@@ -82,7 +85,7 @@ zc3xx		046d:08dd	Logitech QuickCam for N
 spca500		046d:0900	Logitech Inc. ClickSmart 310
 spca500		046d:0901	Logitech Inc. ClickSmart 510
 sunplus		046d:0905	Logitech ClickSmart 820
-tv8532		046d:0920	QC Express
+tv8532		046d:0920	Logitech QuickCam Express
 tv8532		046d:0921	Labtec Webcam
 spca561		046d:0928	Logitech QC Express Etch2
 spca561		046d:0929	Labtec Webcam Elch2
@@ -91,7 +94,7 @@ spca561		046d:092b	Labtec Webcam Plus
 spca561		046d:092c	Logitech QC chat Elch2
 spca561		046d:092d	Logitech QC Elch2
 spca561		046d:092e	Logitech QC Elch2
-spca561		046d:092f	Logitech  QuickCam Express Plus
+spca561		046d:092f	Logitech QuickCam Express Plus
 sunplus		046d:0960	Logitech ClickSmart 420
 sunplus		0471:0322	Philips DMVC1300K
 zc3xx		0471:0325	Philips SPC 200 NC
@@ -166,10 +169,14 @@ sunplus		055f:c650	Mustek MDC5500Z
 zc3xx		055f:d003	Mustek WCam300A
 zc3xx		055f:d004	Mustek WCam300 AN
 conex		0572:0041	Creative Notebook cx11646
+ov519		05a9:0511	Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
+ov519		05a9:0518	Creative WebCam
 ov519		05a9:0519	OV519 Microphone
 ov519		05a9:0530	OmniVision
+ov519		05a9:2800	OmniVision SuperCAM
 ov519		05a9:4519	Webcam Classic
 ov519		05a9:8519	OmniVision
+ov519		05a9:a511	D-Link USB Digital Video Camera
 ov519		05a9:a518	D-Link DSB-C310 Webcam
 sunplus		05da:1018	Digital Dream Enigma 1.3
 stk014		05e1:0893	Syntek DV4000
@@ -185,9 +192,8 @@ ov534		06f8:3002	Hercules Blog Webcam
 ov534		06f8:3003	Hercules Dualpix HD Weblog
 sonixj		06f8:3004	Hercules Classic Silver
 sonixj		06f8:3008	Hercules Deluxe Optical Glass
-pac7311		06f8:3009	Hercules Classic Link
+pac7302		06f8:3009	Hercules Classic Link
 spca508		0733:0110	ViewQuest VQ110
-spca508		0130:0130	Clone Digital Webcam 11043
 spca501		0733:0401	Intel Create and Share
 spca501		0733:0402	ViewQuest M318B
 spca505		0733:0430	Intel PC Camera Pro
@@ -198,10 +204,12 @@ sunplus		0733:2221	Mercury Digital Pro 3
 sunplus		0733:3261	Concord 3045 spca536a
 sunplus		0733:3281	Cyberpix S550V
 spca506		0734:043b	3DeMon USB Capture aka
+ov519		0813:0002	Dual Mode USB Camera Plus
 spca500		084d:0003	D-Link DSC-350
 spca500		08ca:0103	Aiptek PocketDV
 sunplus		08ca:0104	Aiptek PocketDVII 1.3
 sunplus		08ca:0106	Aiptek Pocket DV3100+
+mr97310a	08ca:0110	Trust Spyc@m 100
 mr97310a	08ca:0111	Aiptek PenCam VGA+
 sunplus		08ca:2008	Aiptek Mini PenCam 2 M
 sunplus		08ca:2010	Aiptek PocketCam 3M
@@ -222,7 +230,7 @@ pac207		093a:2460	Qtec Webcam 100
 pac207		093a:2461	HP Webcam
 pac207		093a:2463	Philips SPC 220 NC
 pac207		093a:2464	Labtec Webcam 1200
-pac207		093a:2468	PAC207
+pac207		093a:2468	Webcam WB-1400T
 pac207		093a:2470	Genius GF112
 pac207		093a:2471	Genius VideoCam ge111
 pac207		093a:2472	Genius VideoCam ge110
@@ -230,18 +238,19 @@ pac207		093a:2474	Genius iLook 111
 pac207		093a:2476	Genius e-Messenger 112
 pac7311		093a:2600	PAC7311 Typhoon
 pac7311		093a:2601	Philips SPC 610 NC
-pac7311		093a:2603	PAC7312
+pac7311		093a:2603	Philips SPC 500 NC
 pac7311		093a:2608	Trust WB-3300p
 pac7311		093a:260e	Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
 pac7311		093a:260f	SnakeCam
-pac7311		093a:2620	Apollo AC-905
-pac7311		093a:2621	PAC731x
-pac7311		093a:2622	Genius Eye 312
-pac7311		093a:2624	PAC7302
-pac7311		093a:2626	Labtec 2200
-pac7311		093a:2629	Genious iSlim 300
-pac7311		093a:262a	Webcam 300k
-pac7311		093a:262c	Philips SPC 230 NC
+pac7302		093a:2620	Apollo AC-905
+pac7302		093a:2621	PAC731x
+pac7302		093a:2622	Genius Eye 312
+pac7302		093a:2624	PAC7302
+pac7302		093a:2626	Labtec 2200
+pac7302		093a:2628	Genius iLook 300
+pac7302		093a:2629	Genious iSlim 300
+pac7302		093a:262a	Webcam 300k
+pac7302		093a:262c	Philips SPC 230 NC
 jeilinj		0979:0280	Sakar 57379
 zc3xx		0ac8:0302	Z-star Vimicro zc0302
 vc032x		0ac8:0321	Vimicro generic vc0321
@@ -250,12 +259,13 @@ vc032x		0ac8:0328	A4Tech PK-130MG
 zc3xx		0ac8:301b	Z-Star zc301b
 zc3xx		0ac8:303b	Vimicro 0x303b
 zc3xx		0ac8:305b	Z-star Vimicro zc0305b
-zc3xx		0ac8:307b	Ldlc VC302+Ov7620
+zc3xx		0ac8:307b	PC Camera (ZS0211)
 vc032x		0ac8:c001	Sony embedded vimicro
 vc032x		0ac8:c002	Sony embedded vimicro
 vc032x		0ac8:c301	Samsung Q1 Ultra Premium
 spca508		0af9:0010	Hama USB Sightcam 100
 spca508		0af9:0011	Hama USB Sightcam 100
+ov519		0b62:0059	iBOT2 Webcam
 sonixb		0c45:6001	Genius VideoCAM NB
 sonixb		0c45:6005	Microdia Sweex Mini Webcam
 sonixb		0c45:6007	Sonix sn9c101 + Tas5110D
@@ -315,8 +325,10 @@ sn9c20x		0c45:62b3	PC Camera (SN9C202 +
 sn9c20x		0c45:62bb	PC Camera (SN9C202 + OV7660)
 sn9c20x		0c45:62bc	PC Camera (SN9C202 + HV7131R)
 sunplus		0d64:0303	Sunplus FashionCam DXG
+ov519		0e96:c001	TRUST 380 USB2 SPACEC@M
 etoms		102c:6151	Qcam Sangha CIF
 etoms		102c:6251	Qcam xxxxxx VGA
+ov519		1046:9967	W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
 zc3xx		10fd:0128	Typhoon Webshot II USB 300k 0x0128
 spca561		10fd:7e50	FlyCam Usb 100
 zc3xx		10fd:8050	Typhoon Webshot II USB 300k
@@ -329,7 +341,12 @@ spca501		1776:501c	Arowana 300K CMOS Cam
 t613		17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
 vc032x		17ef:4802	Lenovo Vc0323+MI1310_SOC
 pac207		2001:f115	D-Link DSB-C120
+sq905c		2770:9050	sq905c
+sq905c		2770:905c	DualCamera
+sq905		2770:9120	Argus Digital Camera DC1512
+sq905c		2770:913d	sq905c
 spca500		2899:012c	Toptro Industrial
+ov519		8020:ef04	ov519
 spca508		8086:0110	Intel Easy PC Camera
 spca500		8086:0630	Intel Pocket PC Camera
 spca506		99fa:8988	Grandtec V.cap
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/sh_mobile_ceu_camera.txt linux-libre-2.6.33-gnu1/Documentation/video4linux/sh_mobile_ceu_camera.txt
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/sh_mobile_ceu_camera.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/sh_mobile_ceu_camera.txt	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,157 @@
+	Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
+	=======================================================================
+
+Terminology
+-----------
+
+sensor scales: horizontal and vertical scales, configured by the sensor driver
+host scales: -"- host driver
+combined scales: sensor_scale * host_scale
+
+
+Generic scaling / cropping scheme
+---------------------------------
+
+-1--
+|
+-2-- -\
+|      --\
+|         --\
++-5-- -\     -- -3--
+|       ---\
+|           --- -4-- -\
+|                      -\
+|                        - -6--
+|
+|                        - -6'-
+|                      -/
+|           --- -4'- -/
+|       ---/
++-5'- -/
+|            -- -3'-
+|         --/
+|      --/
+-2'- -/
+|
+|
+-1'-
+
+Produced by user requests:
+
+S_CROP(left / top = (5) - (1), width / height = (5') - (5))
+S_FMT(width / height = (6') - (6))
+
+Here:
+
+(1) to (1') - whole max width or height
+(1) to (2)  - sensor cropped left or top
+(2) to (2') - sensor cropped width or height
+(3) to (3') - sensor scale
+(3) to (4)  - CEU cropped left or top
+(4) to (4') - CEU cropped width or height
+(5) to (5') - reverse sensor scale applied to CEU cropped width or height
+(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
+(6) to (6') - CEU scale - user window
+
+
+S_FMT
+-----
+
+Do not touch input rectangle - it is already optimal.
+
+1. Calculate current sensor scales:
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
+current sensor scales onto input window - this is user S_CROP:
+
+	width_u = (5') - (5) = ((4') - (4)) * scale_s
+
+3. Calculate new combined scales from "effective" input window to requested user
+window:
+
+	scale_comb = width_u / ((6') - (6))
+
+4. Calculate sensor output window by applying combined scales to real input
+window:
+
+	width_s_out = ((2') - (2)) / scale_comb
+
+5. Apply iterative sensor S_FMT for sensor output window.
+
+	subdev->video_ops->s_fmt(.width = width_s_out)
+
+6. Retrieve sensor output window (g_fmt)
+
+7. Calculate new sensor scales:
+
+	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
+
+8. Calculate new CEU crop - apply sensor scales to previously calculated
+"effective" crop:
+
+	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
+	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
+
+9. Use CEU cropping to crop to the new window:
+
+	ceu_crop(.width = width_ceu, .left = left_ceu)
+
+10. Use CEU scaling to scale to the requested user window:
+
+	scale_ceu = width_ceu / width
+
+
+S_CROP
+------
+
+If old scale applied to new crop is invalid produce nearest new scale possible
+
+1. Calculate current combined scales.
+
+	scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
+
+2. Apply iterative sensor S_CROP for new input window.
+
+3. If old combined scales applied to new crop produce an impossible user window,
+adjust scales to produce nearest possible window.
+
+	width_u_out = ((5') - (5)) / scale_comb
+
+	if (width_u_out > max)
+		scale_comb = ((5') - (5)) / max;
+	else if (width_u_out < min)
+		scale_comb = ((5') - (5)) / min;
+
+4. Issue G_CROP to retrieve actual input window.
+
+5. Using actual input window and calculated combined scales calculate sensor
+target output window.
+
+	width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
+
+6. Apply iterative S_FMT for new sensor target output window.
+
+7. Issue G_FMT to retrieve the actual sensor output window.
+
+8. Calculate sensor scales.
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
+scales to the requested window.
+
+	width_ceu = ((5') - (5)) / scale_s
+
+10. Use CEU cropping for above calculated window.
+
+11. Calculate CEU scales from sensor scales from results of (10) and user window
+from (3)
+
+	scale_ceu = calc_scale(((5') - (5)), &width_u_out)
+
+12. Apply CEU scales.
+
+--
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/si4713.txt linux-libre-2.6.33-gnu1/Documentation/video4linux/si4713.txt
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/si4713.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/si4713.txt	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ Stereo/Mono and RDS subchannels
 
 The device can also be configured using the available sub channels for
 transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
-Refer to v4l2-spec for proper use of this ioctl.
+Refer to the V4L2 API specification for proper use of this ioctl.
 
 Testing
 =======
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/v4l2-framework.txt linux-libre-2.6.33-gnu1/Documentation/video4linux/v4l2-framework.txt
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/v4l2-framework.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/v4l2-framework.txt	2010-02-24 13:52:17.000000000 -0500
@@ -561,6 +561,8 @@ video_device helper functions
 
 There are a few useful helper functions:
 
+- file/video_device private data
+
 You can set/get driver private data in the video_device struct using:
 
 void *video_get_drvdata(struct video_device *vdev);
@@ -575,8 +577,7 @@ struct video_device *video_devdata(struc
 
 returns the video_device belonging to the file struct.
 
-The final helper function combines video_get_drvdata with
-video_devdata:
+The video_drvdata function combines video_get_drvdata with video_devdata:
 
 void *video_drvdata(struct file *file);
 
@@ -584,6 +585,17 @@ You can go from a video_device struct to
 
 struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
 
+- Device node name
+
+The video_device node kernel name can be retrieved using
+
+const char *video_device_node_name(struct video_device *vdev);
+
+The name is used as a hint by userspace tools such as udev. The function
+should be used where possible instead of accessing the video_device::num and
+video_device::minor fields.
+
+
 video buffer helper functions
 -----------------------------
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/video4linux/zr364xx.txt linux-libre-2.6.33-gnu1/Documentation/video4linux/zr364xx.txt
--- linux-libre-2.6.32-gnu1/Documentation/video4linux/zr364xx.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/video4linux/zr364xx.txt	2010-02-24 13:52:17.000000000 -0500
@@ -66,3 +66,4 @@ Vendor  Product  Distributor     Model
 0x0a17  0x004e   Pentax          Optio 50
 0x041e  0x405d   Creative        DiVi CAM 516
 0x08ca  0x2102   Aiptek          DV T300
+0x06d6  0x003d   Trust           Powerc@m 910Z
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vm/hugetlbpage.txt linux-libre-2.6.33-gnu1/Documentation/vm/hugetlbpage.txt
--- linux-libre-2.6.32-gnu1/Documentation/vm/hugetlbpage.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vm/hugetlbpage.txt	2010-02-24 13:52:17.000000000 -0500
@@ -11,23 +11,21 @@ This optimization is more critical now a
 (several GBs) are more readily available.
 
 Users can use the huge page support in Linux kernel by either using the mmap
-system call or standard SYSv shared memory system calls (shmget, shmat).
+system call or standard SYSV shared memory system calls (shmget, shmat).
 
 First the Linux kernel needs to be built with the CONFIG_HUGETLBFS
 (present under "File systems") and CONFIG_HUGETLB_PAGE (selected
 automatically when CONFIG_HUGETLBFS is selected) configuration
 options.
 
-The kernel built with huge page support should show the number of configured
-huge pages in the system by running the "cat /proc/meminfo" command.
-
-/proc/meminfo also provides information about the total number of hugetlb
-pages configured in the kernel.  It also displays information about the
-number of free hugetlb pages at any time.  It also displays information about
-the configured huge page size - this is needed for generating the proper
-alignment and size of the arguments to the above system calls.
+The /proc/meminfo file provides information about the total number of
+persistent hugetlb pages in the kernel's huge page pool.  It also displays
+information about the number of free, reserved and surplus huge pages and the
+default huge page size.  The huge page size is needed for generating the
+proper alignment and size of the arguments to system calls that map huge page
+regions.
 
-The output of "cat /proc/meminfo" will have lines like:
+The output of "cat /proc/meminfo" will include lines like:
 
 .....
 HugePages_Total: vvv
@@ -53,59 +51,63 @@ HugePages_Surp  is short for "surplus,"
 /proc/filesystems should also show a filesystem of type "hugetlbfs" configured
 in the kernel.
 
-/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
-pages in the kernel.  Super user can dynamically request more (or free some
-pre-configured) huge pages.
-The allocation (or deallocation) of hugetlb pages is possible only if there are
-enough physically contiguous free pages in system (freeing of huge pages is
-possible only if there are enough hugetlb pages free that can be transferred
-back to regular memory pool).
+/proc/sys/vm/nr_hugepages indicates the current number of "persistent" huge
+pages in the kernel's huge page pool.  "Persistent" huge pages will be
+returned to the huge page pool when freed by a task.  A user with root
+privileges can dynamically allocate more or free some persistent huge pages
+by increasing or decreasing the value of 'nr_hugepages'.
 
-Pages that are used as hugetlb pages are reserved inside the kernel and cannot
-be used for other purposes.
+Pages that are used as huge pages are reserved inside the kernel and cannot
+be used for other purposes.  Huge pages cannot be swapped out under
+memory pressure.
 
-Once the kernel with Hugetlb page support is built and running, a user can
-use either the mmap system call or shared memory system calls to start using
-the huge pages.  It is required that the system administrator preallocate
-enough memory for huge page purposes.
+Once a number of huge pages have been pre-allocated to the kernel huge page
+pool, a user with appropriate privilege can use either the mmap system call
+or shared memory system calls to use the huge pages.  See the discussion of
+Using Huge Pages, below.
 
-The administrator can preallocate huge pages on the kernel boot command line by
-specifying the "hugepages=N" parameter, where 'N' = the number of huge pages
-requested.  This is the most reliable method for preallocating huge pages as
-memory has not yet become fragmented.
+The administrator can allocate persistent huge pages on the kernel boot
+command line by specifying the "hugepages=N" parameter, where 'N' = the
+number of huge pages requested.  This is the most reliable method of
+allocating huge pages as memory has not yet become fragmented.
 
-Some platforms support multiple huge page sizes.  To preallocate huge pages
+Some platforms support multiple huge page sizes.  To allocate huge pages
 of a specific size, one must preceed the huge pages boot command parameters
 with a huge page size selection parameter "hugepagesz=<size>".  <size> must
 be specified in bytes with optional scale suffix [kKmMgG].  The default huge
 page size may be selected with the "default_hugepagesz=<size>" boot parameter.
 
-/proc/sys/vm/nr_hugepages indicates the current number of configured [default
-size] hugetlb pages in the kernel.  Super user can dynamically request more
-(or free some pre-configured) huge pages.
-
-Use the following command to dynamically allocate/deallocate default sized
-huge pages:
+When multiple huge page sizes are supported, /proc/sys/vm/nr_hugepages
+indicates the current number of pre-allocated huge pages of the default size.
+Thus, one can use the following command to dynamically allocate/deallocate
+default sized persistent huge pages:
 
 	echo 20 > /proc/sys/vm/nr_hugepages
 
-This command will try to configure 20 default sized huge pages in the system.
+This command will try to adjust the number of default sized huge pages in the
+huge page pool to 20, allocating or freeing huge pages, as required.
+
 On a NUMA platform, the kernel will attempt to distribute the huge page pool
-over the all on-line nodes.  These huge pages, allocated when nr_hugepages
-is increased, are called "persistent huge pages".
+over all the set of allowed nodes specified by the NUMA memory policy of the
+task that modifies nr_hugepages.  The default for the allowed nodes--when the
+task has default memory policy--is all on-line nodes with memory.  Allowed
+nodes with insufficient available, contiguous memory for a huge page will be
+silently skipped when allocating persistent huge pages.  See the discussion
+below of the interaction of task memory policy, cpusets and per node attributes
+with the allocation and freeing of persistent huge pages.
 
 The success or failure of huge page allocation depends on the amount of
-physically contiguous memory that is preset in system at the time of the
+physically contiguous memory that is present in system at the time of the
 allocation attempt.  If the kernel is unable to allocate huge pages from
 some nodes in a NUMA system, it will attempt to make up the difference by
 allocating extra pages on other nodes with sufficient available contiguous
 memory, if any.
 
-System administrators may want to put this command in one of the local rc init
-files.  This will enable the kernel to request huge pages early in the boot
-process when the possibility of getting physical contiguous pages is still
-very high.  Administrators can verify the number of huge pages actually
-allocated by checking the sysctl or meminfo.  To check the per node
+System administrators may want to put this command in one of the local rc
+init files.  This will enable the kernel to allocate huge pages early in
+the boot process when the possibility of getting physical contiguous pages
+is still very high.  Administrators can verify the number of huge pages
+actually allocated by checking the sysctl or meminfo.  To check the per node
 distribution of huge pages in a NUMA system, use:
 
 	cat /sys/devices/system/node/node*/meminfo | fgrep Huge
@@ -113,45 +115,47 @@ distribution of huge pages in a NUMA sys
 /proc/sys/vm/nr_overcommit_hugepages specifies how large the pool of
 huge pages can grow, if more huge pages than /proc/sys/vm/nr_hugepages are
 requested by applications.  Writing any non-zero value into this file
-indicates that the hugetlb subsystem is allowed to try to obtain "surplus"
-huge pages from the buddy allocator, when the normal pool is exhausted. As
-these surplus huge pages go out of use, they are freed back to the buddy
-allocator.
+indicates that the hugetlb subsystem is allowed to try to obtain that
+number of "surplus" huge pages from the kernel's normal page pool, when the
+persistent huge page pool is exhausted. As these surplus huge pages become
+unused, they are freed back to the kernel's normal page pool.
 
-When increasing the huge page pool size via nr_hugepages, any surplus
+When increasing the huge page pool size via nr_hugepages, any existing surplus
 pages will first be promoted to persistent huge pages.  Then, additional
 huge pages will be allocated, if necessary and if possible, to fulfill
-the new huge page pool size.
+the new persistent huge page pool size.
 
-The administrator may shrink the pool of preallocated huge pages for
+The administrator may shrink the pool of persistent huge pages for
 the default huge page size by setting the nr_hugepages sysctl to a
 smaller value.  The kernel will attempt to balance the freeing of huge pages
-across all on-line nodes.  Any free huge pages on the selected nodes will
-be freed back to the buddy allocator.
+across all nodes in the memory policy of the task modifying nr_hugepages.
+Any free huge pages on the selected nodes will be freed back to the kernel's
+normal page pool.
 
-Caveat: Shrinking the pool via nr_hugepages such that it becomes less
-than the number of huge pages in use will convert the balance to surplus
-huge pages even if it would exceed the overcommit value.  As long as
-this condition holds, however, no more surplus huge pages will be
-allowed on the system until one of the two sysctls are increased
-sufficiently, or the surplus huge pages go out of use and are freed.
+Caveat: Shrinking the persistent huge page pool via nr_hugepages such that
+it becomes less than the number of huge pages in use will convert the balance
+of the in-use huge pages to surplus huge pages.  This will occur even if
+the number of surplus pages it would exceed the overcommit value.  As long as
+this condition holds--that is, until nr_hugepages+nr_overcommit_hugepages is
+increased sufficiently, or the surplus huge pages go out of use and are freed--
+no more surplus huge pages will be allowed to be allocated.
 
 With support for multiple huge page pools at run-time available, much of
-the huge page userspace interface has been duplicated in sysfs. The above
-information applies to the default huge page size which will be
-controlled by the /proc interfaces for backwards compatibility. The root
-huge page control directory in sysfs is:
+the huge page userspace interface in /proc/sys/vm has been duplicated in sysfs.
+The /proc interfaces discussed above have been retained for backwards
+compatibility. The root huge page control directory in sysfs is:
 
 	/sys/kernel/mm/hugepages
 
 For each huge page size supported by the running kernel, a subdirectory
-will exist, of the form
+will exist, of the form:
 
 	hugepages-${size}kB
 
 Inside each of these directories, the same set of files will exist:
 
 	nr_hugepages
+	nr_hugepages_mempolicy
 	nr_overcommit_hugepages
 	free_hugepages
 	resv_hugepages
@@ -159,6 +163,102 @@ Inside each of these directories, the sa
 
 which function as described above for the default huge page-sized case.
 
+
+Interaction of Task Memory Policy with Huge Page Allocation/Freeing
+
+Whether huge pages are allocated and freed via the /proc interface or
+the /sysfs interface using the nr_hugepages_mempolicy attribute, the NUMA
+nodes from which huge pages are allocated or freed are controlled by the
+NUMA memory policy of the task that modifies the nr_hugepages_mempolicy
+sysctl or attribute.  When the nr_hugepages attribute is used, mempolicy
+is ignored.
+
+The recommended method to allocate or free huge pages to/from the kernel
+huge page pool, using the nr_hugepages example above, is:
+
+    numactl --interleave <node-list> echo 20 \
+				>/proc/sys/vm/nr_hugepages_mempolicy
+
+or, more succinctly:
+
+    numactl -m <node-list> echo 20 >/proc/sys/vm/nr_hugepages_mempolicy
+
+This will allocate or free abs(20 - nr_hugepages) to or from the nodes
+specified in <node-list>, depending on whether number of persistent huge pages
+is initially less than or greater than 20, respectively.  No huge pages will be
+allocated nor freed on any node not included in the specified <node-list>.
+
+When adjusting the persistent hugepage count via nr_hugepages_mempolicy, any
+memory policy mode--bind, preferred, local or interleave--may be used.  The
+resulting effect on persistent huge page allocation is as follows:
+
+1) Regardless of mempolicy mode [see Documentation/vm/numa_memory_policy.txt],
+   persistent huge pages will be distributed across the node or nodes
+   specified in the mempolicy as if "interleave" had been specified.
+   However, if a node in the policy does not contain sufficient contiguous
+   memory for a huge page, the allocation will not "fallback" to the nearest
+   neighbor node with sufficient contiguous memory.  To do this would cause
+   undesirable imbalance in the distribution of the huge page pool, or
+   possibly, allocation of persistent huge pages on nodes not allowed by
+   the task's memory policy.
+
+2) One or more nodes may be specified with the bind or interleave policy.
+   If more than one node is specified with the preferred policy, only the
+   lowest numeric id will be used.  Local policy will select the node where
+   the task is running at the time the nodes_allowed mask is constructed.
+   For local policy to be deterministic, the task must be bound to a cpu or
+   cpus in a single node.  Otherwise, the task could be migrated to some
+   other node at any time after launch and the resulting node will be
+   indeterminate.  Thus, local policy is not very useful for this purpose.
+   Any of the other mempolicy modes may be used to specify a single node.
+
+3) The nodes allowed mask will be derived from any non-default task mempolicy,
+   whether this policy was set explicitly by the task itself or one of its
+   ancestors, such as numactl.  This means that if the task is invoked from a
+   shell with non-default policy, that policy will be used.  One can specify a
+   node list of "all" with numactl --interleave or --membind [-m] to achieve
+   interleaving over all nodes in the system or cpuset.
+
+4) Any task mempolicy specifed--e.g., using numactl--will be constrained by
+   the resource limits of any cpuset in which the task runs.  Thus, there will
+   be no way for a task with non-default policy running in a cpuset with a
+   subset of the system nodes to allocate huge pages outside the cpuset
+   without first moving to a cpuset that contains all of the desired nodes.
+
+5) Boot-time huge page allocation attempts to distribute the requested number
+   of huge pages over all on-lines nodes with memory.
+
+Per Node Hugepages Attributes
+
+A subset of the contents of the root huge page control directory in sysfs,
+described above, will be replicated under each the system device of each
+NUMA node with memory in:
+
+	/sys/devices/system/node/node[0-9]*/hugepages/
+
+Under this directory, the subdirectory for each supported huge page size
+contains the following attribute files:
+
+	nr_hugepages
+	free_hugepages
+	surplus_hugepages
+
+The free_' and surplus_' attribute files are read-only.  They return the number
+of free and surplus [overcommitted] huge pages, respectively, on the parent
+node.
+
+The nr_hugepages attribute returns the total number of huge pages on the
+specified node.  When this attribute is written, the number of persistent huge
+pages on the parent node will be adjusted to the specified value, if sufficient
+resources exist, regardless of the task's mempolicy or cpuset constraints.
+
+Note that the number of overcommit and reserve pages remain global quantities,
+as we don't know until fault time, when the faulting task's mempolicy is
+applied, from which node the huge page allocation will be attempted.
+
+
+Using Huge Pages
+
 If the user applications are going to request huge pages using mmap system
 call, then it is required that system administrator mount a file system of
 type hugetlbfs:
@@ -206,9 +306,11 @@ map_hugetlb.c.
  * requesting huge pages.
  *
  * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages.  That means the addresses starting with 0x800000... will need
- * to be specified.  Specifying a fixed address is not required on ppc64,
- * i386 or x86_64.
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
  *
  * Note: The default shared memory limit is quite low on many kernels,
  * you may need to increase it via:
@@ -237,14 +339,8 @@ map_hugetlb.c.
 
 #define dprintf(x)  printf(x)
 
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define SHMAT_FLAGS (SHM_RND)
-#else
-#define ADDR (void *)(0x0UL)
+#define ADDR (void *)(0x0UL)	/* let kernel choose address */
 #define SHMAT_FLAGS (0)
-#endif
 
 int main(void)
 {
@@ -302,10 +398,12 @@ int main(void)
  * example, the app is requesting memory of size 256MB that is backed by
  * huge pages.
  *
- * For ia64 architecture, Linux kernel reserves Region number 4 for huge pages.
- * That means the addresses starting with 0x800000... will need to be
- * specified.  Specifying a fixed address is not required on ppc64, i386
- * or x86_64.
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -317,14 +415,8 @@ int main(void)
 #define LENGTH (256UL*1024*1024)
 #define PROTECTION (PROT_READ | PROT_WRITE)
 
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define FLAGS (MAP_SHARED | MAP_FIXED)
-#else
-#define ADDR (void *)(0x0UL)
+#define ADDR (void *)(0x0UL)	/* let kernel choose address */
 #define FLAGS (MAP_SHARED)
-#endif
 
 void check_bytes(char *addr)
 {
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vm/hwpoison.txt linux-libre-2.6.33-gnu1/Documentation/vm/hwpoison.txt
--- linux-libre-2.6.32-gnu1/Documentation/vm/hwpoison.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vm/hwpoison.txt	2010-02-24 13:52:17.000000000 -0500
@@ -92,16 +92,62 @@ PR_MCE_KILL_GET
 
 Testing:
 
-madvise(MADV_POISON, ....)
+madvise(MADV_HWPOISON, ....)
 	(as root)
 	Poison a page in the process for testing
 
 
 hwpoison-inject module through debugfs
-	/sys/debug/hwpoison/corrupt-pfn
 
-Inject hwpoison fault at PFN echoed into this file
+/sys/debug/hwpoison/
+
+corrupt-pfn
+
+Inject hwpoison fault at PFN echoed into this file. This does
+some early filtering to avoid corrupted unintended pages in test suites.
+
+unpoison-pfn
+
+Software-unpoison page at PFN echoed into this file. This
+way a page can be reused again.
+This only works for Linux injected failures, not for real
+memory failures.
+
+Note these injection interfaces are not stable and might change between
+kernel versions
+
+corrupt-filter-dev-major
+corrupt-filter-dev-minor
+
+Only handle memory failures to pages associated with the file system defined
+by block device major/minor.  -1U is the wildcard value.
+This should be only used for testing with artificial injection.
+
+corrupt-filter-memcg
+
+Limit injection to pages owned by memgroup. Specified by inode number
+of the memcg.
+
+Example:
+        mkdir /cgroup/hwpoison
+
+        usemem -m 100 -s 1000 &
+        echo `jobs -p` > /cgroup/hwpoison/tasks
+
+        memcg_ino=$(ls -id /cgroup/hwpoison | cut -f1 -d' ')
+        echo $memcg_ino > /debug/hwpoison/corrupt-filter-memcg
 
+        page-types -p `pidof init`   --hwpoison  # shall do nothing
+        page-types -p `pidof usemem` --hwpoison  # poison its pages
+
+corrupt-filter-flags-mask
+corrupt-filter-flags-value
+
+When specified, only poison pages if ((page_flags & mask) == value).
+This allows stress testing of many kinds of pages. The page_flags
+are the same as in /proc/kpageflags. The flag bits are defined in
+include/linux/kernel-page-flags.h and documented in
+Documentation/vm/pagemap.txt
 
 Architecture specific MCE injector
 
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vm/ksm.txt linux-libre-2.6.33-gnu1/Documentation/vm/ksm.txt
--- linux-libre-2.6.32-gnu1/Documentation/vm/ksm.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vm/ksm.txt	2010-02-24 13:52:17.000000000 -0500
@@ -16,9 +16,9 @@ by sharing the data common between them.
 application which generates many instances of the same data.
 
 KSM only merges anonymous (private) pages, never pagecache (file) pages.
-KSM's merged pages are at present locked into kernel memory for as long
-as they are shared: so cannot be swapped out like the user pages they
-replace (but swapping KSM pages should follow soon in a later release).
+KSM's merged pages were originally locked into kernel memory, but can now
+be swapped out just like other user pages (but sharing is broken when they
+are swapped back in: ksmd must rediscover their identity and merge again).
 
 KSM only operates on those areas of address space which an application
 has advised to be likely candidates for merging, by using the madvise(2)
@@ -44,20 +44,12 @@ includes unmapped gaps (though working o
 and might fail with EAGAIN if not enough memory for internal structures.
 
 Applications should be considerate in their use of MADV_MERGEABLE,
-restricting its use to areas likely to benefit.  KSM's scans may use
-a lot of processing power, and its kernel-resident pages are a limited
-resource.  Some installations will disable KSM for these reasons.
+restricting its use to areas likely to benefit.  KSM's scans may use a lot
+of processing power: some installations will disable KSM for that reason.
 
 The KSM daemon is controlled by sysfs files in /sys/kernel/mm/ksm/,
 readable by all but writable only by root:
 
-max_kernel_pages - set to maximum number of kernel pages that KSM may use
-                   e.g. "echo 100000 > /sys/kernel/mm/ksm/max_kernel_pages"
-                   Value 0 imposes no limit on the kernel pages KSM may use;
-                   but note that any process using MADV_MERGEABLE can cause
-                   KSM to allocate these pages, unswappable until it exits.
-                   Default: quarter of memory (chosen to not pin too much)
-
 pages_to_scan    - how many present pages to scan before ksmd goes to sleep
                    e.g. "echo 100 > /sys/kernel/mm/ksm/pages_to_scan"
                    Default: 100 (chosen for demonstration purposes)
@@ -75,7 +67,7 @@ run              - set 0 to stop ksmd fr
 
 The effectiveness of KSM and MADV_MERGEABLE is shown in /sys/kernel/mm/ksm/:
 
-pages_shared     - how many shared unswappable kernel pages KSM is using
+pages_shared     - how many shared pages are being used
 pages_sharing    - how many more sites are sharing them i.e. how much saved
 pages_unshared   - how many pages unique but repeatedly checked for merging
 pages_volatile   - how many pages changing too fast to be placed in a tree
@@ -87,4 +79,4 @@ pages_volatile embraces several differen
 proportion there would also indicate poor use of madvise MADV_MERGEABLE.
 
 Izik Eidus,
-Hugh Dickins, 24 Sept 2009
+Hugh Dickins, 17 Nov 2009
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vm/page-types.c linux-libre-2.6.33-gnu1/Documentation/vm/page-types.c
--- linux-libre-2.6.32-gnu1/Documentation/vm/page-types.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vm/page-types.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,11 +1,22 @@
 /*
  * page-types: Tool for querying page flags
  *
+ * 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 in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should find a copy of v2 of the GNU General Public License somewhere on
+ * your Linux system; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
  * Copyright (C) 2009 Intel corporation
  *
  * Authors: Wu Fengguang <fengguang.wu@intel.com>
- *
- * Released under the General Public License (GPL).
  */
 
 #define _LARGEFILE64_SOURCE
@@ -100,7 +111,7 @@
 #define BIT(name)		(1ULL << KPF_##name)
 #define BITS_COMPOUND		(BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
 
-static char *page_flag_names[] = {
+static const char *page_flag_names[] = {
 	[KPF_LOCKED]		= "L:locked",
 	[KPF_ERROR]		= "E:error",
 	[KPF_REFERENCED]	= "R:referenced",
@@ -173,7 +184,7 @@ static int		kpageflags_fd;
 static int		opt_hwpoison;
 static int		opt_unpoison;
 
-static char		*hwpoison_debug_fs = "/debug/hwpoison";
+static const char	hwpoison_debug_fs[] = "/debug/hwpoison";
 static int		hwpoison_inject_fd;
 static int		hwpoison_forget_fd;
 
@@ -301,7 +312,7 @@ static char *page_flag_name(uint64_t fla
 		present = (flags >> i) & 1;
 		if (!page_flag_names[i]) {
 			if (present)
-				fatal("unkown flag bit %d\n", i);
+				fatal("unknown flag bit %d\n", i);
 			continue;
 		}
 		buf[j++] = present ? page_flag_names[i][0] : '_';
@@ -560,7 +571,7 @@ static void walk_pfn(unsigned long voffs
 {
 	uint64_t buf[KPAGEFLAGS_BATCH];
 	unsigned long batch;
-	unsigned long pages;
+	long pages;
 	unsigned long i;
 
 	while (count) {
@@ -673,30 +684,35 @@ static void usage(void)
 
 	printf(
 "page-types [options]\n"
-"            -r|--raw                  Raw mode, for kernel developers\n"
-"            -a|--addr    addr-spec    Walk a range of pages\n"
-"            -b|--bits    bits-spec    Walk pages with specified bits\n"
-"            -p|--pid     pid          Walk process address space\n"
+"            -r|--raw                   Raw mode, for kernel developers\n"
+"            -d|--describe flags        Describe flags\n"
+"            -a|--addr    addr-spec     Walk a range of pages\n"
+"            -b|--bits    bits-spec     Walk pages with specified bits\n"
+"            -p|--pid     pid           Walk process address space\n"
 #if 0 /* planned features */
-"            -f|--file    filename     Walk file address space\n"
+"            -f|--file    filename      Walk file address space\n"
 #endif
-"            -l|--list                 Show page details in ranges\n"
-"            -L|--list-each            Show page details one by one\n"
-"            -N|--no-summary           Don't show summay info\n"
-"            -X|--hwpoison             hwpoison pages\n"
-"            -x|--unpoison             unpoison pages\n"
-"            -h|--help                 Show this usage message\n"
+"            -l|--list                  Show page details in ranges\n"
+"            -L|--list-each             Show page details one by one\n"
+"            -N|--no-summary            Don't show summay info\n"
+"            -X|--hwpoison              hwpoison pages\n"
+"            -x|--unpoison              unpoison pages\n"
+"            -h|--help                  Show this usage message\n"
+"flags:\n"
+"            0x10                       bitfield format, e.g.\n"
+"            anon                       bit-name, e.g.\n"
+"            0x10,anon                  comma-separated list, e.g.\n"
 "addr-spec:\n"
-"            N                         one page at offset N (unit: pages)\n"
-"            N+M                       pages range from N to N+M-1\n"
-"            N,M                       pages range from N to M-1\n"
-"            N,                        pages range from N to end\n"
-"            ,M                        pages range from 0 to M-1\n"
+"            N                          one page at offset N (unit: pages)\n"
+"            N+M                        pages range from N to N+M-1\n"
+"            N,M                        pages range from N to M-1\n"
+"            N,                         pages range from N to end\n"
+"            ,M                         pages range from 0 to M-1\n"
 "bits-spec:\n"
-"            bit1,bit2                 (flags & (bit1|bit2)) != 0\n"
-"            bit1,bit2=bit1            (flags & (bit1|bit2)) == bit1\n"
-"            bit1,~bit2                (flags & (bit1|bit2)) == bit1\n"
-"            =bit1,bit2                flags == (bit1|bit2)\n"
+"            bit1,bit2                  (flags & (bit1|bit2)) != 0\n"
+"            bit1,bit2=bit1             (flags & (bit1|bit2)) == bit1\n"
+"            bit1,~bit2                 (flags & (bit1|bit2)) == bit1\n"
+"            =bit1,bit2                 flags == (bit1|bit2)\n"
 "bit-names:\n"
 	);
 
@@ -884,13 +900,23 @@ static void parse_bits_mask(const char *
 	add_bits_filter(mask, bits);
 }
 
+static void describe_flags(const char *optarg)
+{
+	uint64_t flags = parse_flag_names(optarg, 0);
 
-static struct option opts[] = {
+	printf("0x%016llx\t%s\t%s\n",
+		(unsigned long long)flags,
+		page_flag_name(flags),
+		page_flag_longname(flags));
+}
+
+static const struct option opts[] = {
 	{ "raw"       , 0, NULL, 'r' },
 	{ "pid"       , 1, NULL, 'p' },
 	{ "file"      , 1, NULL, 'f' },
 	{ "addr"      , 1, NULL, 'a' },
 	{ "bits"      , 1, NULL, 'b' },
+	{ "describe"  , 1, NULL, 'd' },
 	{ "list"      , 0, NULL, 'l' },
 	{ "list-each" , 0, NULL, 'L' },
 	{ "no-summary", 0, NULL, 'N' },
@@ -907,7 +933,7 @@ int main(int argc, char *argv[])
 	page_size = getpagesize();
 
 	while ((c = getopt_long(argc, argv,
-				"rp:f:a:b:lLNXxh", opts, NULL)) != -1) {
+				"rp:f:a:b:d:lLNXxh", opts, NULL)) != -1) {
 		switch (c) {
 		case 'r':
 			opt_raw = 1;
@@ -924,6 +950,9 @@ int main(int argc, char *argv[])
 		case 'b':
 			parse_bits_mask(optarg);
 			break;
+		case 'd':
+			describe_flags(optarg);
+			exit(0);
 		case 'l':
 			opt_list = 1;
 			break;
diff -druNp linux-libre-2.6.32-gnu1/Documentation/vm/slub.txt linux-libre-2.6.33-gnu1/Documentation/vm/slub.txt
--- linux-libre-2.6.32-gnu1/Documentation/vm/slub.txt	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/Documentation/vm/slub.txt	2010-02-24 13:52:17.000000000 -0500
@@ -245,7 +245,7 @@ been overwritten. Here a string of 8 cha
 has the length of 8 characters. However, a 8 character string needs a
 terminating 0. That zero has overwritten the first byte of the Redzone field.
 After reporting the details of the issue encountered the FIX SLUB message
-tell us that SLUB has restored the Redzone to its proper value and then
+tells us that SLUB has restored the Redzone to its proper value and then
 system operations continue.
 
 Emergency operations:
diff -druNp linux-libre-2.6.32-gnu1/drivers/accessibility/braille/braille_console.c linux-libre-2.6.33-gnu1/drivers/accessibility/braille/braille_console.c
--- linux-libre-2.6.32-gnu1/drivers/accessibility/braille/braille_console.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/accessibility/braille/braille_console.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/autoconf.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acmacros.h linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acmacros.h
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acmacros.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acmacros.h	2010-02-24 13:52:17.000000000 -0500
@@ -341,6 +341,7 @@
 #define ACPI_ERROR_NAMESPACE(s, e)      acpi_ns_report_error (AE_INFO, s, e);
 #define ACPI_ERROR_METHOD(s, n, p, e)   acpi_ns_report_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
 
 #else
 
@@ -349,6 +350,8 @@
 #define ACPI_ERROR_NAMESPACE(s, e)
 #define ACPI_ERROR_METHOD(s, n, p, e)
 #define ACPI_WARN_PREDEFINED(plist)
+#define ACPI_INFO_PREDEFINED(plist)
+
 #endif		/* ACPI_NO_ERROR_MESSAGES */
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acnamesp.h linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acnamesp.h
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acnamesp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acnamesp.h	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type
 		       acpi_handle start_object,
 		       u32 max_depth,
 		       u32 flags,
-		       acpi_walk_callback user_function,
+		       acpi_walk_callback pre_order_visit,
+		       acpi_walk_callback post_order_visit,
 		       void *context, void **return_value);
 
 struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
@@ -272,7 +273,8 @@ acpi_ns_get_attached_data(struct acpi_na
 			  acpi_object_handler handler, void **data);
 
 /*
- * nsrepair - return object repair for predefined methods/objects
+ * nsrepair - General return object repair for all
+ * predefined methods/objects
  */
 acpi_status
 acpi_ns_repair_object(struct acpi_predefined_data *data,
@@ -285,6 +287,21 @@ acpi_ns_repair_package_list(struct acpi_
 			    union acpi_operand_object **obj_desc_ptr);
 
 /*
+ * nsrepair2 - Return object repair for specific
+ * predefined methods/objects
+ */
+acpi_status
+acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+			struct acpi_namespace_node *node,
+			acpi_status validate_status,
+			union acpi_operand_object **return_object_ptr);
+
+void
+acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+			     u8 package_type,
+			     union acpi_operand_object *obj_desc);
+
+/*
  * nssearch - Namespace searching and entry
  */
 acpi_status
@@ -342,9 +359,7 @@ acpi_ns_externalize_name(u32 internal_na
 			 const char *internal_name,
 			 u32 * converted_name_length, char **converted_name);
 
-struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle);
-
-acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node);
+struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle);
 
 void acpi_ns_terminate(void);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acobject.h linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acobject.h
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acobject.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acobject.h	2010-02-24 13:52:17.000000000 -0500
@@ -180,7 +180,11 @@ struct acpi_object_method {
 	u8 sync_level;
 	union acpi_operand_object *mutex;
 	u8 *aml_start;
-	ACPI_INTERNAL_METHOD implementation;
+	union {
+		ACPI_INTERNAL_METHOD implementation;
+		union acpi_operand_object *handler;
+	} extra;
+
 	u32 aml_length;
 	u8 thread_count;
 	acpi_owner_id owner_id;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acutils.h linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acutils.h
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/acutils.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/acutils.h	2010-02-24 13:52:17.000000000 -0500
@@ -386,6 +386,8 @@ u8 acpi_ut_valid_internal_object(void *o
 
 union acpi_operand_object *acpi_ut_create_package_object(u32 count);
 
+union acpi_operand_object *acpi_ut_create_integer_object(u64 value);
+
 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size);
 
 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
@@ -481,6 +483,11 @@ acpi_ut_predefined_warning(const char *m
 			   char *pathname,
 			   u8 node_flags, const char *format, ...);
 
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_info(const char *module_name,
+			u32 line_number,
+			char *pathname, u8 node_flags, const char *format, ...);
+
 /* Values for Base above (16=Hex, 10=Decimal) */
 
 #define ACPI_ANY_BASE        0
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsinit.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsinit.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsinit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsinit.c	2010-02-24 13:52:17.000000000 -0500
@@ -192,7 +192,7 @@ acpi_ds_initialize_objects(u32 table_ind
 	status =
 	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
 				   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
-				   &info, NULL);
+				   NULL, &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsmethod.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmethod.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsmethod.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmethod.c	2010-02-24 13:52:17.000000000 -0500
@@ -414,7 +414,7 @@ acpi_ds_call_control_method(struct acpi_
 	/* Invoke an internal method if necessary */
 
 	if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
-		status = obj_desc->method.implementation(next_walk_state);
+		status = obj_desc->method.extra.implementation(next_walk_state);
 		if (status == AE_OK) {
 			status = AE_CTRL_TERMINATE;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsmthdat.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmthdat.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsmthdat.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsmthdat.c	2010-02-24 13:52:17.000000000 -0500
@@ -409,13 +409,11 @@ acpi_ds_method_data_get_value(u8 type,
 		/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
 
 		if (acpi_gbl_enable_interpreter_slack) {
-			object =
-			    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+			object = acpi_ut_create_integer_object((u64) 0);
 			if (!object) {
 				return_ACPI_STATUS(AE_NO_MEMORY);
 			}
 
-			object->integer.value = 0;
 			node->object = object;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsobject.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsobject.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dsobject.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dsobject.c	2010-02-24 13:52:17.000000000 -0500
@@ -486,7 +486,7 @@ acpi_ds_build_internal_package_obj(struc
 		 *
 		 * Note: technically, this is an error, from ACPI spec: "It is an error
 		 * for NumElements to be less than the number of elements in the
-		 * PackageList". However, we just print an error message and
+		 * PackageList". However, we just print a message and
 		 * no exception is returned. This provides Windows compatibility. Some
 		 * BIOSs will alter the num_elements on the fly, creating this type
 		 * of ill-formed package object.
@@ -510,9 +510,9 @@ acpi_ds_build_internal_package_obj(struc
 			arg = arg->common.next;
 		}
 
-		ACPI_WARNING((AE_INFO,
-			    "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n",
-			    i, element_count));
+		ACPI_INFO((AE_INFO,
+			   "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
+			   i, element_count));
 	} else if (i < element_count) {
 		/*
 		 * Arg list (elements) was exhausted, but we did not reach num_elements count.
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dswload.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswload.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/dswload.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/dswload.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,18 +212,19 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 		case ACPI_TYPE_BUFFER:
 
 			/*
-			 * These types we will allow, but we will change the type. This
-			 * enables some existing code of the form:
+			 * These types we will allow, but we will change the type.
+			 * This enables some existing code of the form:
 			 *
 			 *  Name (DEB, 0)
 			 *  Scope (DEB) { ... }
 			 *
-			 * Note: silently change the type here. On the second pass, we will report
-			 * a warning
+			 * Note: silently change the type here. On the second pass,
+			 * we will report a warning
 			 */
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
-					  path,
+					  "Type override - [%4.4s] had invalid type (%s) "
+					  "for Scope operator, changed to type ANY\n",
+					  acpi_ut_get_node_name(node),
 					  acpi_ut_get_type_name(node->type)));
 
 			node->type = ACPI_TYPE_ANY;
@@ -235,8 +236,10 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 			/* All other types are an error */
 
 			ACPI_ERROR((AE_INFO,
-				    "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
-				    acpi_ut_get_type_name(node->type), path));
+				    "Invalid type (%s) for target of "
+				    "Scope operator [%4.4s] (Cannot override)",
+				    acpi_ut_get_type_name(node->type),
+				    acpi_ut_get_node_name(node)));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
@@ -639,26 +642,42 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 		break;
 
 	case AML_SCOPE_OP:
-		/*
-		 * The Path is an object reference to an existing object.
-		 * Don't enter the name into the namespace, but look it up
-		 * for use later.
-		 */
-		status =
-		    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
-				   object_type, ACPI_IMODE_EXECUTE,
-				   ACPI_NS_SEARCH_PARENT, walk_state, &(node));
-		if (ACPI_FAILURE(status)) {
-#ifdef ACPI_ASL_COMPILER
-			if (status == AE_NOT_FOUND) {
-				status = AE_OK;
-			} else {
-				ACPI_ERROR_NAMESPACE(buffer_ptr, status);
+
+		/* Special case for Scope(\) -> refers to the Root node */
+
+		if (op && (op->named.node == acpi_gbl_root_node)) {
+			node = op->named.node;
+
+			status =
+			    acpi_ds_scope_stack_push(node, object_type,
+						     walk_state);
+			if (ACPI_FAILURE(status)) {
+				return_ACPI_STATUS(status);
 			}
+		} else {
+			/*
+			 * The Path is an object reference to an existing object.
+			 * Don't enter the name into the namespace, but look it up
+			 * for use later.
+			 */
+			status =
+			    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
+					   object_type, ACPI_IMODE_EXECUTE,
+					   ACPI_NS_SEARCH_PARENT, walk_state,
+					   &(node));
+			if (ACPI_FAILURE(status)) {
+#ifdef ACPI_ASL_COMPILER
+				if (status == AE_NOT_FOUND) {
+					status = AE_OK;
+				} else {
+					ACPI_ERROR_NAMESPACE(buffer_ptr,
+							     status);
+				}
 #else
-			ACPI_ERROR_NAMESPACE(buffer_ptr, status);
+				ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 #endif
-			return_ACPI_STATUS(status);
+				return_ACPI_STATUS(status);
+			}
 		}
 
 		/*
@@ -681,15 +700,16 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 		case ACPI_TYPE_BUFFER:
 
 			/*
-			 * These types we will allow, but we will change the type. This
-			 * enables some existing code of the form:
+			 * These types we will allow, but we will change the type.
+			 * This enables some existing code of the form:
 			 *
 			 *  Name (DEB, 0)
 			 *  Scope (DEB) { ... }
 			 */
 			ACPI_WARNING((AE_INFO,
-				      "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
-				      buffer_ptr,
+				      "Type override - [%4.4s] had invalid type (%s) "
+				      "for Scope operator, changed to type ANY\n",
+				      acpi_ut_get_node_name(node),
 				      acpi_ut_get_type_name(node->type)));
 
 			node->type = ACPI_TYPE_ANY;
@@ -701,9 +721,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 			/* All other types are an error */
 
 			ACPI_ERROR((AE_INFO,
-				    "Invalid type (%s) for target of Scope operator [%4.4s]",
+				    "Invalid type (%s) for target of "
+				    "Scope operator [%4.4s] (Cannot override)",
 				    acpi_ut_get_type_name(node->type),
-				    buffer_ptr));
+				    acpi_ut_get_node_name(node)));
 
 			return (AE_AML_OPERAND_TYPE);
 		}
@@ -1031,9 +1052,22 @@ acpi_status acpi_ds_load2_end_op(struct
 			}
 
 			/*
-			 * If we are executing a method, initialize the region
+			 * The op_region is not fully parsed at this time. The only valid
+			 * argument is the space_id. (We must save the address of the
+			 * AML of the address and length operands)
+			 *
+			 * If we have a valid region, initialize it. The namespace is
+			 * unlocked at this point.
+			 *
+			 * Need to unlock interpreter if it is locked (if we are running
+			 * a control method), in order to allow _REG methods to be run
+			 * during acpi_ev_initialize_region.
 			 */
 			if (walk_state->method_node) {
+				/*
+				 * Executing a method: initialize the region and unlock
+				 * the interpreter
+				 */
 				status =
 				    acpi_ex_create_region(op->named.data,
 							  op->named.length,
@@ -1042,21 +1076,17 @@ acpi_status acpi_ds_load2_end_op(struct
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
-			}
 
-			/*
-			 * The op_region is not fully parsed at this time. Only valid
-			 * argument is the space_id. (We must save the address of the
-			 * AML of the address and length operands)
-			 */
+				acpi_ex_exit_interpreter();
+			}
 
-			/*
-			 * If we have a valid region, initialize it
-			 * Namespace is NOT locked at this point.
-			 */
 			status =
 			    acpi_ev_initialize_region
 			    (acpi_ns_get_attached_object(node), FALSE);
+			if (walk_state->method_node) {
+				acpi_ex_enter_interpreter();
+			}
+
 			if (ACPI_FAILURE(status)) {
 				/*
 				 *  If AE_NOT_EXIST is returned, it is not fatal
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evgpeblk.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpeblk.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evgpeblk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evgpeblk.c	2010-02-24 13:52:17.000000000 -0500
@@ -945,8 +945,8 @@ acpi_ev_create_gpe_block(struct acpi_nam
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-					acpi_ev_save_method_info, gpe_block,
-					NULL);
+					acpi_ev_save_method_info, NULL,
+					gpe_block, NULL);
 
 	/* Return the new block */
 
@@ -1022,8 +1022,8 @@ acpi_ev_initialize_gpe_block(struct acpi
 		status =
 		    acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					   ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-					   acpi_ev_match_prw_and_gpe, &gpe_info,
-					   NULL);
+					   acpi_ev_match_prw_and_gpe, NULL,
+					   &gpe_info, NULL);
 	}
 
 	/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evregion.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evregion.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evregion.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evregion.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,10 @@
 ACPI_MODULE_NAME("evregion")
 
 /* Local prototypes */
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+			    acpi_adr_space_type space_id);
+
 static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
 		u32 level, void *context, void **return_value);
@@ -142,6 +146,50 @@ acpi_status acpi_ev_install_region_handl
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_has_default_handler
+ *
+ * PARAMETERS:  Node                - Namespace node for the device
+ *              space_id            - The address space ID
+ *
+ * RETURN:      TRUE if default handler is installed, FALSE otherwise
+ *
+ * DESCRIPTION: Check if the default handler is installed for the requested
+ *              space ID.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_ev_has_default_handler(struct acpi_namespace_node *node,
+			    acpi_adr_space_type space_id)
+{
+	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *handler_obj;
+
+	/* Must have an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (obj_desc) {
+		handler_obj = obj_desc->device.handler;
+
+		/* Walk the linked list of handlers for this object */
+
+		while (handler_obj) {
+			if (handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler_flags &
+				    ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+					return (TRUE);
+				}
+			}
+
+			handler_obj = handler_obj->address_space.next;
+		}
+	}
+
+	return (FALSE);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_initialize_op_regions
  *
  * PARAMETERS:  None
@@ -169,12 +217,18 @@ acpi_status acpi_ev_initialize_op_region
 
 	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 		/*
-		 * TBD: Make sure handler is the DEFAULT handler, otherwise
-		 * _REG will have already been run.
+		 * Make sure the installed handler is the DEFAULT handler. If not the
+		 * default, the _REG methods will have already been run (when the
+		 * handler was installed)
 		 */
-		status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
-						     acpi_gbl_default_address_spaces
-						     [i]);
+		if (acpi_ev_has_default_handler(acpi_gbl_root_node,
+						acpi_gbl_default_address_spaces
+						[i])) {
+			status =
+			    acpi_ev_execute_reg_methods(acpi_gbl_root_node,
+							acpi_gbl_default_address_spaces
+							[i]);
+		}
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
@@ -235,23 +289,20 @@ acpi_ev_execute_reg_method(union acpi_op
 	 *  connection status 1 for connecting the handler, 0 for disconnecting
 	 *  the handler (Passed as a parameter)
 	 */
-	args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	args[0] =
+	    acpi_ut_create_integer_object((u64) region_obj->region.space_id);
 	if (!args[0]) {
 		status = AE_NO_MEMORY;
 		goto cleanup1;
 	}
 
-	args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	args[1] = acpi_ut_create_integer_object((u64) function);
 	if (!args[1]) {
 		status = AE_NO_MEMORY;
 		goto cleanup2;
 	}
 
-	/* Setup the parameter objects */
-
-	args[0]->integer.value = region_obj->region.space_id;
-	args[1]->integer.value = function;
-	args[2] = NULL;
+	args[2] = NULL;		/* Terminate list */
 
 	/* Execute the method, no return value */
 
@@ -667,7 +718,7 @@ acpi_ev_install_handler(acpi_handle obj_
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	if (!node) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -971,8 +1022,8 @@ acpi_ev_install_space_handler(struct acp
 	 */
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
 					ACPI_NS_WALK_UNLOCK,
-					acpi_ev_install_handler, handler_obj,
-					NULL);
+					acpi_ev_install_handler, NULL,
+					handler_obj, NULL);
 
       unlock_and_exit:
 	return_ACPI_STATUS(status);
@@ -1008,7 +1059,7 @@ acpi_ev_execute_reg_methods(struct acpi_
 	 */
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
 					ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
-					&space_id, NULL);
+					NULL, &space_id, NULL);
 
 	return_ACPI_STATUS(status);
 }
@@ -1036,7 +1087,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	if (!node) {
 		return (AE_BAD_PARAMETER);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evrgnini.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evrgnini.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evrgnini.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evrgnini.c	2010-02-24 13:52:17.000000000 -0500
@@ -575,6 +575,21 @@ acpi_ev_initialize_region(union acpi_ope
 				handler_obj = obj_desc->thermal_zone.handler;
 				break;
 
+			case ACPI_TYPE_METHOD:
+				/*
+				 * If we are executing module level code, the original
+				 * Node's object was replaced by this Method object and we
+				 * saved the handler in the method object.
+				 *
+				 * See acpi_ns_exec_module_code
+				 */
+				if (obj_desc->method.
+				    flags & AOPOBJ_MODULE_LEVEL) {
+					handler_obj =
+					    obj_desc->method.extra.handler;
+				}
+				break;
+
 			default:
 				/* Ignore other objects */
 				break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxface.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxface.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxface.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxface.c	2010-02-24 13:52:17.000000000 -0500
@@ -259,7 +259,7 @@ acpi_install_notify_handler(acpi_handle
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(device);
+	node = acpi_ns_validate_handle(device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -425,7 +425,7 @@ acpi_remove_notify_handler(acpi_handle d
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(device);
+	node = acpi_ns_validate_handle(device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxfevnt.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfevnt.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxfevnt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfevnt.c	2010-02-24 13:52:17.000000000 -0500
@@ -610,7 +610,7 @@ acpi_install_gpe_block(acpi_handle gpe_d
 		return (status);
 	}
 
-	node = acpi_ns_map_handle_to_node(gpe_device);
+	node = acpi_ns_validate_handle(gpe_device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -698,7 +698,7 @@ acpi_status acpi_remove_gpe_block(acpi_h
 		return (status);
 	}
 
-	node = acpi_ns_map_handle_to_node(gpe_device);
+	node = acpi_ns_validate_handle(gpe_device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxfregn.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfregn.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/evxfregn.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/evxfregn.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,7 +89,7 @@ acpi_install_address_space_handler(acpi_
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(device);
+	node = acpi_ns_validate_handle(device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -155,7 +155,7 @@ acpi_remove_address_space_handler(acpi_h
 
 	/* Convert and validate the device handle */
 
-	node = acpi_ns_map_handle_to_node(device);
+	node = acpi_ns_validate_handle(device);
 	if (!node ||
 	    ((node->type != ACPI_TYPE_DEVICE) &&
 	     (node->type != ACPI_TYPE_PROCESSOR) &&
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exconfig.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconfig.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exconfig.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconfig.c	2010-02-24 13:52:17.000000000 -0500
@@ -170,14 +170,12 @@ acpi_ex_load_table_op(struct acpi_walk_s
 
 		/* Table not found, return an Integer=0 and AE_OK */
 
-		ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		ddb_handle = acpi_ut_create_integer_object((u64) 0);
 		if (!ddb_handle) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
-		ddb_handle->integer.value = 0;
 		*return_desc = ddb_handle;
-
 		return_ACPI_STATUS(AE_OK);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exconvrt.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconvrt.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exconvrt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exconvrt.c	2010-02-24 13:52:17.000000000 -0500
@@ -167,7 +167,7 @@ acpi_ex_convert_to_integer(union acpi_op
 
 	/* Create a new integer */
 
-	return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	return_desc = acpi_ut_create_integer_object(result);
 	if (!return_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
@@ -177,7 +177,6 @@ acpi_ex_convert_to_integer(union acpi_op
 
 	/* Save the Result */
 
-	return_desc->integer.value = result;
 	acpi_ex_truncate_for32bit_table(return_desc);
 	*result_desc = return_desc;
 	return_ACPI_STATUS(AE_OK);
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exfield.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfield.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exfield.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exfield.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,13 +162,12 @@ acpi_ex_read_data_from_field(struct acpi
 	} else {
 		/* Field will fit within an Integer (normal case) */
 
-		buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		buffer_desc = acpi_ut_create_integer_object((u64) 0);
 		if (!buffer_desc) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
 		length = acpi_gbl_integer_byte_width;
-		buffer_desc->integer.value = 0;
 		buffer = &buffer_desc->integer.value;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exmutex.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmutex.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exmutex.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exmutex.c	2010-02-24 13:52:17.000000000 -0500
@@ -375,6 +375,15 @@ acpi_ex_release_mutex(union acpi_operand
 		return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
 	}
 
+	/* Must have a valid thread ID */
+
+	if (!walk_state->thread) {
+		ACPI_ERROR((AE_INFO,
+			    "Cannot release Mutex [%4.4s], null thread info",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
+		return_ACPI_STATUS(AE_AML_INTERNAL);
+	}
+
 	/*
 	 * The Mutex is owned, but this thread must be the owner.
 	 * Special case for Global Lock, any thread can release
@@ -392,15 +401,6 @@ acpi_ex_release_mutex(union acpi_operand
 		return_ACPI_STATUS(AE_AML_NOT_OWNER);
 	}
 
-	/* Must have a valid thread ID */
-
-	if (!walk_state->thread) {
-		ACPI_ERROR((AE_INFO,
-			    "Cannot release Mutex [%4.4s], null thread info",
-			    acpi_ut_get_node_name(obj_desc->mutex.node)));
-		return_ACPI_STATUS(AE_AML_INTERNAL);
-	}
-
 	/*
 	 * The sync level of the mutex must be equal to the current sync level. In
 	 * other words, the current level means that at least one mutex at that
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exoparg1.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg1.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exoparg1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg1.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,12 +100,12 @@ acpi_status acpi_ex_opcode_0A_0T_1R(stru
 
 		/* Create a return object of type Integer */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc =
+		    acpi_ut_create_integer_object(acpi_os_get_timer());
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-		return_desc->integer.value = acpi_os_get_timer();
 		break;
 
 	default:		/*  Unknown opcode  */
@@ -599,7 +599,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 	switch (walk_state->opcode) {
 	case AML_LNOT_OP:	/* LNot (Operand) */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object((u64) 0);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -702,13 +702,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 
 		/* Allocate a descriptor to hold the type. */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object((u64) type);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-
-		return_desc->integer.value = type;
 		break;
 
 	case AML_SIZE_OF_OP:	/* size_of (source_object) */
@@ -777,13 +775,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		 * Now that we have the size of the object, create a result
 		 * object to hold the value
 		 */
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object(value);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-
-		return_desc->integer.value = value;
 		break;
 
 	case AML_REF_OF_OP:	/* ref_of (source_object) */
@@ -946,24 +942,24 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 					 * NOTE: index into a buffer is NOT a pointer to a
 					 * sub-buffer of the main buffer, it is only a pointer to a
 					 * single element (byte) of the buffer!
+					 *
+					 * Since we are returning the value of the buffer at the
+					 * indexed location, we don't need to add an additional
+					 * reference to the buffer itself.
 					 */
 					return_desc =
-					    acpi_ut_create_internal_object
-					    (ACPI_TYPE_INTEGER);
+					    acpi_ut_create_integer_object((u64)
+									  temp_desc->
+									  buffer.
+									  pointer
+									  [operand
+									   [0]->
+									   reference.
+									   value]);
 					if (!return_desc) {
 						status = AE_NO_MEMORY;
 						goto cleanup;
 					}
-
-					/*
-					 * Since we are returning the value of the buffer at the
-					 * indexed location, we don't need to add an additional
-					 * reference to the buffer itself.
-					 */
-					return_desc->integer.value =
-					    temp_desc->buffer.
-					    pointer[operand[0]->reference.
-						    value];
 					break;
 
 				case ACPI_TYPE_PACKAGE:
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exoparg6.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg6.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/exoparg6.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/exoparg6.c	2010-02-24 13:52:17.000000000 -0500
@@ -253,18 +253,15 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 		}
 
 		/* Create an integer for the return value */
+		/* Default return value is ACPI_INTEGER_MAX if no match found */
 
-		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
 
 		}
 
-		/* Default return value if no match found */
-
-		return_desc->integer.value = ACPI_INTEGER_MAX;
-
 		/*
 		 * Examine each element until a match is found. Both match conditions
 		 * must be satisfied for a match to occur. Within the loop,
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/Makefile linux-libre-2.6.33-gnu1/drivers/acpi/acpica/Makefile
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
 acpi-y += nsaccess.o  nsload.o    nssearch.o  nsxfeval.o \
 	 nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
 	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
-	 nsparse.o   nspredef.o  nsrepair.o
+	 nsparse.o   nspredef.o  nsrepair.o  nsrepair2.o
 
 acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsaccess.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsaccess.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsaccess.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsaccess.c	2010-02-24 13:52:17.000000000 -0500
@@ -165,7 +165,7 @@ acpi_status acpi_ns_root_initialize(void
 
 				obj_desc->method.method_flags =
 				    AML_METHOD_INTERNAL_ONLY;
-				obj_desc->method.implementation =
+				obj_desc->method.extra.implementation =
 				    acpi_ut_osi_implementation;
 #endif
 				break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsdump.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdump.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsdump.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdump.c	2010-02-24 13:52:17.000000000 -0500
@@ -180,7 +180,7 @@ acpi_ns_dump_one_object(acpi_handle obj_
 		return (AE_OK);
 	}
 
-	this_node = acpi_ns_map_handle_to_node(obj_handle);
+	this_node = acpi_ns_validate_handle(obj_handle);
 	if (!this_node) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
 				  obj_handle));
@@ -634,8 +634,8 @@ acpi_ns_dump_objects(acpi_object_type ty
 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
 				     ACPI_NS_WALK_NO_UNLOCK |
 				     ACPI_NS_WALK_TEMP_NODES,
-				     acpi_ns_dump_one_object, (void *)&info,
-				     NULL);
+				     acpi_ns_dump_one_object, NULL,
+				     (void *)&info, NULL);
 }
 #endif				/* ACPI_FUTURE_USAGE */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsdumpdv.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdumpdv.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsdumpdv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsdumpdv.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,7 +131,8 @@ void acpi_ns_dump_root_devices(void)
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-					acpi_ns_dump_one_device, NULL, NULL);
+					acpi_ns_dump_one_device, NULL, NULL,
+					NULL);
 }
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nseval.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nseval.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nseval.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nseval.c	2010-02-24 13:52:17.000000000 -0500
@@ -366,50 +366,88 @@ static void
 acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
 			 struct acpi_evaluate_info *info)
 {
-	union acpi_operand_object *root_obj;
+	union acpi_operand_object *parent_obj;
+	struct acpi_namespace_node *parent_node;
+	acpi_object_type type;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(ns_exec_module_code);
 
+	/*
+	 * Get the parent node. We cheat by using the next_object field
+	 * of the method object descriptor.
+	 */
+	parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
+				    method_obj->method.next_object);
+	type = acpi_ns_get_type(parent_node);
+
+	/*
+	 * Get the region handler and save it in the method object. We may need
+	 * this if an operation region declaration causes a _REG method to be run.
+	 *
+	 * We can't do this in acpi_ps_link_module_code because
+	 * acpi_gbl_root_node->Object is NULL at PASS1.
+	 */
+	if ((type == ACPI_TYPE_DEVICE) && parent_node->object) {
+		method_obj->method.extra.handler =
+		    parent_node->object->device.handler;
+	}
+
+	/* Must clear next_object (acpi_ns_attach_object needs the field) */
+
+	method_obj->method.next_object = NULL;
+
 	/* Initialize the evaluation information block */
 
 	ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
-	info->prefix_node = acpi_gbl_root_node;
+	info->prefix_node = parent_node;
 
 	/*
-	 * Get the currently attached root object. Add a reference, because the
+	 * Get the currently attached parent object. Add a reference, because the
 	 * ref count will be decreased when the method object is installed to
-	 * the root node.
+	 * the parent node.
 	 */
-	root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node);
-	acpi_ut_add_reference(root_obj);
+	parent_obj = acpi_ns_get_attached_object(parent_node);
+	if (parent_obj) {
+		acpi_ut_add_reference(parent_obj);
+	}
 
-	/* Install the method (module-level code) in the root node */
+	/* Install the method (module-level code) in the parent node */
 
-	status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj,
+	status = acpi_ns_attach_object(parent_node, method_obj,
 				       ACPI_TYPE_METHOD);
 	if (ACPI_FAILURE(status)) {
 		goto exit;
 	}
 
-	/* Execute the root node as a control method */
+	/* Execute the parent node as a control method */
 
 	status = acpi_ns_evaluate(info);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n",
 			  method_obj->method.aml_start));
 
+	/* Delete a possible implicit return value (in slack mode) */
+
+	if (info->return_object) {
+		acpi_ut_remove_reference(info->return_object);
+	}
+
 	/* Detach the temporary method object */
 
-	acpi_ns_detach_object(acpi_gbl_root_node);
+	acpi_ns_detach_object(parent_node);
 
-	/* Restore the original root object */
+	/* Restore the original parent object */
 
-	status =
-	    acpi_ns_attach_object(acpi_gbl_root_node, root_obj,
-				  ACPI_TYPE_DEVICE);
+	if (parent_obj) {
+		status = acpi_ns_attach_object(parent_node, parent_obj, type);
+	} else {
+		parent_node->type = (u8)type;
+	}
 
       exit:
-	acpi_ut_remove_reference(root_obj);
+	if (parent_obj) {
+		acpi_ut_remove_reference(parent_obj);
+	}
 	return_VOID;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsinit.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsinit.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsinit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsinit.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ acpi_status acpi_ns_initialize_objects(v
 	/* Walk entire namespace from the supplied root */
 
 	status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
-				     ACPI_UINT32_MAX, acpi_ns_init_one_object,
+				     ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL,
 				     &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
@@ -156,7 +156,8 @@ acpi_status acpi_ns_initialize_devices(v
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, FALSE,
-					acpi_ns_find_ini_methods, &info, NULL);
+					acpi_ns_find_ini_methods, NULL, &info,
+					NULL);
 	if (ACPI_FAILURE(status)) {
 		goto error_exit;
 	}
@@ -189,7 +190,8 @@ acpi_status acpi_ns_initialize_devices(v
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, FALSE,
-					acpi_ns_init_one_device, &info, NULL);
+					acpi_ns_init_one_device, NULL, &info,
+					NULL);
 
 	ACPI_FREE(info.evaluate_info);
 	if (ACPI_FAILURE(status)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsnames.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsnames.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsnames.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsnames.c	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,7 @@ acpi_ns_handle_to_pathname(acpi_handle t
 
 	ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
 
-	node = acpi_ns_map_handle_to_node(target_handle);
+	node = acpi_ns_validate_handle(target_handle);
 	if (!node) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nspredef.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nspredef.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nspredef.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nspredef.c	2010-02-24 13:52:17.000000000 -0500
@@ -216,23 +216,38 @@ acpi_ns_check_predefined_names(struct ac
 	data->pathname = pathname;
 
 	/*
-	 * Check that the type of the return object is what is expected for
-	 * this predefined name
+	 * 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,
 					   predefined->info.expected_btypes,
 					   ACPI_NOT_PACKAGE_ELEMENT);
 	if (ACPI_FAILURE(status)) {
-		goto check_validation_status;
+		goto exit;
 	}
 
-	/* For returned Package objects, check the type of all sub-objects */
-
-	if (return_object->common.type == ACPI_TYPE_PACKAGE) {
+	/*
+	 * For returned Package objects, check the type of all sub-objects.
+	 * Note: Package may have been newly created by call above.
+	 */
+	if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
 		status = acpi_ns_check_package(data, return_object_ptr);
+		if (ACPI_FAILURE(status)) {
+			goto exit;
+		}
 	}
 
-check_validation_status:
+	/*
+	 * The return object was OK, or it was successfully repaired above.
+	 * Now make some additional checks such as verifying that package
+	 * objects are sorted correctly (if required) or buffer objects have
+	 * the correct data width (bytes vs. dwords). These repairs are
+	 * 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);
+
+exit:
 	/*
 	 * If the object validation failed or if we successfully repaired one
 	 * or more objects, mark the parent node to suppress further warning
@@ -421,6 +436,13 @@ acpi_ns_check_package(struct acpi_predef
 			  data->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,
+				     return_object);
+
 	/* Extract package count and elements array */
 
 	elements = return_object->package.elements;
@@ -455,11 +477,11 @@ acpi_ns_check_package(struct acpi_predef
 		if (count < expected_count) {
 			goto package_too_small;
 		} else if (count > expected_count) {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
-					      "Return Package is larger than needed - "
-					      "found %u, expected %u", count,
-					      expected_count));
+			ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+					  "%s: Return Package is larger than needed - "
+					  "found %u, expected %u\n",
+					  data->pathname, count,
+					  expected_count));
 		}
 
 		/* Validate all elements of the returned package */
@@ -601,7 +623,8 @@ acpi_ns_check_package(struct acpi_predef
 		 * there is only one entry). We may be able to repair this by
 		 * wrapping the returned Package with a new outer Package.
 		 */
-		if ((*elements)->common.type != ACPI_TYPE_PACKAGE) {
+		if (*elements
+		    && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
 
 			/* Create the new outer package and populate it */
 
@@ -677,8 +700,13 @@ acpi_ns_check_package_list(struct acpi_p
 	u32 i;
 	u32 j;
 
-	/* Validate each sub-Package in the parent Package */
-
+	/*
+	 * Validate each sub-Package in the parent Package
+	 *
+	 * NOTE: assumes list of sub-packages contains no NULL elements.
+	 * Any NULL elements should have been removed by earlier call
+	 * to acpi_ns_remove_null_elements.
+	 */
 	for (i = 0; i < count; i++) {
 		sub_package = *elements;
 		sub_elements = sub_package->package.elements;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsrepair2.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair2.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsrepair2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,657 @@
+/******************************************************************************
+ *
+ * Module Name: nsrepair2 - Repair for objects returned by specific
+ *                          predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, 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("nsrepair2")
+
+/*
+ * Information structure and handler for ACPI predefined names that can
+ * be repaired on a per-name basis.
+ */
+typedef
+acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
+				    union acpi_operand_object **return_object_ptr);
+
+typedef struct acpi_repair_info {
+	char name[ACPI_NAME_SIZE];
+	acpi_repair_function repair_function;
+
+} acpi_repair_info;
+
+/* Local prototypes */
+
+static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
+								    acpi_namespace_node
+								    *node);
+
+static acpi_status
+acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+			  union acpi_operand_object *return_object,
+			  u32 expected_count,
+			  u32 sort_index,
+			  u8 sort_direction, char *sort_key_name);
+
+static acpi_status
+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
+
+/*
+ * This table contains the names of the predefined methods for which we can
+ * perform more complex repairs.
+ *
+ * As necessary:
+ *
+ * _ALR: Sort the list ascending by ambient_illuminance
+ * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _PSS: Sort the list descending by Power
+ * _TSS: Sort the list descending by Power
+ */
+static const struct acpi_repair_info acpi_ns_repairable_names[] = {
+	{"_ALR", acpi_ns_repair_ALR},
+	{"_FDE", acpi_ns_repair_FDE},
+	{"_GTM", acpi_ns_repair_FDE},	/* _GTM has same repair as _FDE */
+	{"_PSS", acpi_ns_repair_PSS},
+	{"_TSS", acpi_ns_repair_TSS},
+	{{0, 0, 0, 0}, NULL}	/* Table terminator */
+};
+
+#define ACPI_FDE_FIELD_COUNT        5
+#define ACPI_FDE_BYTE_BUFFER_SIZE   5
+#define ACPI_FDE_DWORD_BUFFER_SIZE  (ACPI_FDE_FIELD_COUNT * sizeof (u32))
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_complex_repairs
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              Node                - Namespace node for the method/object
+ *              validate_status     - Original status of earlier validation
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if repair was successful. If name is not
+ *              matched, validate_status is returned.
+ *
+ * DESCRIPTION: Attempt to repair/convert a return object of a type that was
+ *              not expected.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+			struct acpi_namespace_node *node,
+			acpi_status validate_status,
+			union acpi_operand_object **return_object_ptr)
+{
+	const struct acpi_repair_info *predefined;
+	acpi_status status;
+
+	/* Check if this name is in the list of repairable names */
+
+	predefined = acpi_ns_match_repairable_name(node);
+	if (!predefined) {
+		return (validate_status);
+	}
+
+	status = predefined->repair_function(data, return_object_ptr);
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_match_repairable_name
+ *
+ * PARAMETERS:  Node                - Namespace node for the method/object
+ *
+ * RETURN:      Pointer to entry in repair table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the repairable object list.
+ *
+ *****************************************************************************/
+
+static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
+								    acpi_namespace_node
+								    *node)
+{
+	const struct acpi_repair_info *this_name;
+
+	/* Search info table for a repairable predefined method/object name */
+
+	this_name = acpi_ns_repairable_names;
+	while (this_name->repair_function) {
+		if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
+			return (this_name);
+		}
+		this_name++;
+	}
+
+	return (NULL);		/* Not found */
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_ALR
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              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 _ALR object. If necessary, sort the object list
+ *              ascending by the ambient illuminance values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+		   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,
+					   ACPI_SORT_ASCENDING,
+					   "AmbientIlluminance");
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_FDE
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              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 _FDE and _GTM objects. The expected return
+ *              value is a Buffer of 5 DWORDs. This function repairs a common
+ *              problem where the return value is a Buffer of BYTEs, not
+ *              DWORDs.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	union acpi_operand_object *buffer_object;
+	u8 *byte_buffer;
+	u32 *dword_buffer;
+	u32 i;
+
+	ACPI_FUNCTION_NAME(ns_repair_FDE);
+
+	switch (return_object->common.type) {
+	case ACPI_TYPE_BUFFER:
+
+		/* This is the expected type. Length should be (at least) 5 DWORDs */
+
+		if (return_object->buffer.length >= ACPI_FDE_DWORD_BUFFER_SIZE) {
+			return (AE_OK);
+		}
+
+		/* 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,
+					      "Incorrect return buffer length %u, expected %u",
+					      return_object->buffer.length,
+					      ACPI_FDE_DWORD_BUFFER_SIZE));
+
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Create the new (larger) buffer object */
+
+		buffer_object =
+		    acpi_ut_create_buffer_object(ACPI_FDE_DWORD_BUFFER_SIZE);
+		if (!buffer_object) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Expand each byte to a DWORD */
+
+		byte_buffer = return_object->buffer.pointer;
+		dword_buffer =
+		    ACPI_CAST_PTR(u32, buffer_object->buffer.pointer);
+
+		for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) {
+			*dword_buffer = (u32) *byte_buffer;
+			dword_buffer++;
+			byte_buffer++;
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+				  "%s Expanded Byte Buffer to expected DWord Buffer\n",
+				  data->pathname));
+		break;
+
+	default:
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/* Delete the original return object, return the new buffer object */
+
+	acpi_ut_remove_reference(return_object);
+	*return_object_ptr = buffer_object;
+
+	data->flags |= ACPI_OBJECT_REPAIRED;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_TSS
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              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_predefined_data *data,
+		   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, 5, 1,
+					   ACPI_SORT_DESCENDING,
+					   "PowerDissipation");
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_PSS
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              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 _PSS object. If necessary, sort the object list
+ *              by the CPU frequencies. Check that the power dissipation values
+ *              are all proportional to CPU frequency (i.e., sorting by
+ *              frequency should be the same as sorting by power.)
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+		   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 **elements;
+	union acpi_operand_object *obj_desc;
+	u32 previous_value;
+	acpi_status status;
+	u32 i;
+
+	/*
+	 * Entries (sub-packages) in the _PSS Package must be sorted by power
+	 * dissipation, in descending order. If it appears that the list is
+	 * 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,
+					   ACPI_SORT_DESCENDING,
+					   "CpuFrequency");
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/*
+	 * We now know the list is correctly sorted by CPU frequency. Check if
+	 * the power dissipation values are proportional.
+	 */
+	previous_value = ACPI_UINT32_MAX;
+	outer_elements = return_object->package.elements;
+	outer_element_count = return_object->package.count;
+
+	for (i = 0; i < outer_element_count; i++) {
+		elements = (*outer_elements)->package.elements;
+		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,
+					      "SubPackage[%u,%u] - suspicious power dissipation values",
+					      i - 1, i));
+		}
+
+		previous_value = (u32) obj_desc->integer.value;
+		outer_elements++;
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_sorted_list
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              return_object       - Pointer to the top-level returned object
+ *              expected_count      - Minimum length of each sub-package
+ *              sort_index          - Sub-package entry to sort on
+ *              sort_direction      - Ascending or descending
+ *              sort_key_name       - Name of the sort_index field
+ *
+ * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
+ *              has been repaired by sorting the list.
+ *
+ * DESCRIPTION: Check if the package list is valid and sorted correctly by the
+ *              sort_index. If not, then sort the list.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+			  union acpi_operand_object *return_object,
+			  u32 expected_count,
+			  u32 sort_index,
+			  u8 sort_direction, char *sort_key_name)
+{
+	u32 outer_element_count;
+	union acpi_operand_object **outer_elements;
+	union acpi_operand_object **elements;
+	union acpi_operand_object *obj_desc;
+	u32 i;
+	u32 previous_value;
+	acpi_status status;
+
+	ACPI_FUNCTION_NAME(ns_check_sorted_list);
+
+	/* The top-level object must be a package */
+
+	if (return_object->common.type != ACPI_TYPE_PACKAGE) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * NOTE: assumes list of sub-packages contains no NULL elements.
+	 * 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) {
+		return (AE_AML_PACKAGE_LIMIT);
+	}
+
+	previous_value = 0;
+	if (sort_direction == ACPI_SORT_DESCENDING) {
+		previous_value = ACPI_UINT32_MAX;
+	}
+
+	/* Examine each subpackage */
+
+	for (i = 0; i < outer_element_count; i++) {
+
+		/* Each element of the top-level package must also be a package */
+
+		if ((*outer_elements)->common.type != ACPI_TYPE_PACKAGE) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Each sub-package must have the minimum length */
+
+		if ((*outer_elements)->package.count < expected_count) {
+			return (AE_AML_PACKAGE_LIMIT);
+		}
+
+		elements = (*outer_elements)->package.elements;
+		obj_desc = elements[sort_index];
+
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
+			return (AE_AML_OPERAND_TYPE);
+		}
+
+		/*
+		 * The list must be sorted in the specified order. If we detect a
+		 * discrepancy, issue a warning and sort the entire list
+		 */
+		if (((sort_direction == ACPI_SORT_ASCENDING) &&
+		     (obj_desc->integer.value < previous_value)) ||
+		    ((sort_direction == ACPI_SORT_DESCENDING) &&
+		     (obj_desc->integer.value > previous_value))) {
+			status =
+			    acpi_ns_sort_list(return_object->package.elements,
+					      outer_element_count, sort_index,
+					      sort_direction);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+
+			data->flags |= ACPI_OBJECT_REPAIRED;
+
+			ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+					  "%s: Repaired unsorted list - now sorted by %s\n",
+					  data->pathname, sort_key_name));
+			return (AE_OK);
+		}
+
+		previous_value = (u32) obj_desc->integer.value;
+		outer_elements++;
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_null_elements
+ *
+ * PARAMETERS:  Data                - Pointer to validation data structure
+ *              package_type        - An acpi_return_package_types value
+ *              obj_desc            - A Package object
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Remove all NULL package elements from packages that contain
+ *              a variable number of sub-packages.
+ *
+ *****************************************************************************/
+
+void
+acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+			     u8 package_type,
+			     union acpi_operand_object *obj_desc)
+{
+	union acpi_operand_object **source;
+	union acpi_operand_object **dest;
+	u32 count;
+	u32 new_count;
+	u32 i;
+
+	ACPI_FUNCTION_NAME(ns_remove_null_elements);
+
+	/*
+	 * PTYPE1 packages contain no subpackages.
+	 * PTYPE2 packages contain a variable number of sub-packages. We can
+	 * safely remove all NULL elements from the PTYPE2 packages.
+	 */
+	switch (package_type) {
+	case ACPI_PTYPE1_FIXED:
+	case ACPI_PTYPE1_VAR:
+	case ACPI_PTYPE1_OPTION:
+		return;
+
+	case ACPI_PTYPE2:
+	case ACPI_PTYPE2_COUNT:
+	case ACPI_PTYPE2_PKG_COUNT:
+	case ACPI_PTYPE2_FIXED:
+	case ACPI_PTYPE2_MIN:
+	case ACPI_PTYPE2_REV_FIXED:
+		break;
+
+	default:
+		return;
+	}
+
+	count = obj_desc->package.count;
+	new_count = count;
+
+	source = obj_desc->package.elements;
+	dest = source;
+
+	/* Examine all elements of the package object, remove nulls */
+
+	for (i = 0; i < count; i++) {
+		if (!*source) {
+			new_count--;
+		} else {
+			*dest = *source;
+			dest++;
+		}
+		source++;
+	}
+
+	/* Update parent package if any null elements were removed */
+
+	if (new_count < count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+				  "%s: Found and removed %u NULL elements\n",
+				  data->pathname, (count - new_count)));
+
+		/* NULL terminate list and update the package count */
+
+		*dest = NULL;
+		obj_desc->package.count = new_count;
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_sort_list
+ *
+ * PARAMETERS:  Elements            - Package object element list
+ *              Count               - Element count for above
+ *              Index               - Sort by which package element
+ *              sort_direction      - Ascending or Descending sort
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Sort the objects that are in a package element list.
+ *
+ * NOTE: Assumes that all NULL elements have been removed from the package.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_sort_list(union acpi_operand_object **elements,
+		  u32 count, u32 index, u8 sort_direction)
+{
+	union acpi_operand_object *obj_desc1;
+	union acpi_operand_object *obj_desc2;
+	union acpi_operand_object *temp_obj;
+	u32 i;
+	u32 j;
+
+	/* Simple bubble sort */
+
+	for (i = 1; i < count; i++) {
+		for (j = (count - 1); j >= i; j--) {
+			obj_desc1 = elements[j - 1]->package.elements[index];
+			obj_desc2 = elements[j]->package.elements[index];
+
+			if (((sort_direction == ACPI_SORT_ASCENDING) &&
+			     (obj_desc1->integer.value >
+			      obj_desc2->integer.value))
+			    || ((sort_direction == ACPI_SORT_DESCENDING)
+				&& (obj_desc1->integer.value <
+				    obj_desc2->integer.value))) {
+				temp_obj = elements[j - 1];
+				elements[j - 1] = elements[j];
+				elements[j] = temp_obj;
+			}
+		}
+	}
+
+	return (AE_OK);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsrepair.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsrepair.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsrepair.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,13 +44,53 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
-#include "acpredef.h"
+#include "acinterp.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsrepair")
 
 /*******************************************************************************
  *
+ * This module attempts to repair or convert objects returned by the
+ * predefined methods to an object type that is expected, as per the ACPI
+ * specification. The need for this code is dictated by the many machines that
+ * return incorrect types for the standard predefined methods. Performing these
+ * conversions here, in one place, eliminates the need for individual ACPI
+ * device drivers to do the same. Note: Most of these conversions are different
+ * than the internal object conversion routines used for implicit object
+ * conversion.
+ *
+ * The following conversions can be performed as necessary:
+ *
+ * Integer -> String
+ * Integer -> Buffer
+ * String  -> Integer
+ * String  -> Buffer
+ * Buffer  -> Integer
+ * Buffer  -> String
+ * Buffer  -> Package of Integers
+ * Package -> Package of one Package
+ *
+ ******************************************************************************/
+/* Local prototypes */
+static acpi_status
+acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
+			   union acpi_operand_object **return_object);
+
+static acpi_status
+acpi_ns_convert_to_string(union acpi_operand_object *original_object,
+			  union acpi_operand_object **return_object);
+
+static acpi_status
+acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
+			  union acpi_operand_object **return_object);
+
+static acpi_status
+acpi_ns_convert_to_package(union acpi_operand_object *original_object,
+			   union acpi_operand_object **return_object);
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ns_repair_object
  *
  * PARAMETERS:  Data                - Pointer to validation data structure
@@ -67,6 +107,7 @@ ACPI_MODULE_NAME("nsrepair")
  *              not expected.
  *
  ******************************************************************************/
+
 acpi_status
 acpi_ns_repair_object(struct acpi_predefined_data *data,
 		      u32 expected_btypes,
@@ -75,26 +116,206 @@ acpi_ns_repair_object(struct acpi_predef
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
 	union acpi_operand_object *new_object;
-	acpi_size length;
+	acpi_status status;
+
+	ACPI_FUNCTION_NAME(ns_repair_object);
+
+	/*
+	 * At this point, we know that the type of the returned object was not
+	 * one of the expected types for this predefined name. Attempt to
+	 * repair the object by converting it to one of the expected object
+	 * types for this predefined name.
+	 */
+	if (expected_btypes & ACPI_RTYPE_INTEGER) {
+		status = acpi_ns_convert_to_integer(return_object, &new_object);
+		if (ACPI_SUCCESS(status)) {
+			goto object_repaired;
+		}
+	}
+	if (expected_btypes & ACPI_RTYPE_STRING) {
+		status = acpi_ns_convert_to_string(return_object, &new_object);
+		if (ACPI_SUCCESS(status)) {
+			goto object_repaired;
+		}
+	}
+	if (expected_btypes & ACPI_RTYPE_BUFFER) {
+		status = acpi_ns_convert_to_buffer(return_object, &new_object);
+		if (ACPI_SUCCESS(status)) {
+			goto object_repaired;
+		}
+	}
+	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
+		status = acpi_ns_convert_to_package(return_object, &new_object);
+		if (ACPI_SUCCESS(status)) {
+			goto object_repaired;
+		}
+	}
+
+	/* We cannot repair this object */
+
+	return (AE_AML_OPERAND_TYPE);
+
+      object_repaired:
+
+	/* Object was successfully repaired */
+
+	/*
+	 * If the original object is a package element, we need to:
+	 * 1. Set the reference count of the new object to match the
+	 *    reference count of the old object.
+	 * 2. Decrement the reference count of the original object.
+	 */
+	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
+		new_object->common.reference_count =
+		    return_object->common.reference_count;
+
+		if (return_object->common.reference_count > 1) {
+			return_object->common.reference_count--;
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+				  "%s: Converted %s to expected %s at index %u\n",
+				  data->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,
+				  acpi_ut_get_object_type_name(return_object),
+				  acpi_ut_get_object_type_name(new_object)));
+	}
+
+	/* Delete old object, install the new return object */
+
+	acpi_ut_remove_reference(return_object);
+	*return_object_ptr = new_object;
+	data->flags |= ACPI_OBJECT_REPAIRED;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_to_integer
+ *
+ * PARAMETERS:  original_object     - Object to be converted
+ *              return_object       - Where the new converted object is returned
+ *
+ * RETURN:      Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
+			   union acpi_operand_object **return_object)
+{
+	union acpi_operand_object *new_object;
+	acpi_status status;
+	u64 value = 0;
+	u32 i;
+
+	switch (original_object->common.type) {
+	case ACPI_TYPE_STRING:
+
+		/* String-to-Integer conversion */
+
+		status = acpi_ut_strtoul64(original_object->string.pointer,
+					   ACPI_ANY_BASE, &value);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+		break;
 
-	switch (return_object->common.type) {
 	case ACPI_TYPE_BUFFER:
 
-		/* Does the method/object legally return a string? */
+		/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
 
-		if (!(expected_btypes & ACPI_RTYPE_STRING)) {
+		if (original_object->buffer.length > 8) {
 			return (AE_AML_OPERAND_TYPE);
 		}
 
+		/* Extract each buffer byte to create the integer */
+
+		for (i = 0; i < original_object->buffer.length; i++) {
+			value |=
+			    ((u64) original_object->buffer.
+			     pointer[i] << (i * 8));
+		}
+		break;
+
+	default:
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	new_object = acpi_ut_create_integer_object(value);
+	if (!new_object) {
+		return (AE_NO_MEMORY);
+	}
+
+	*return_object = new_object;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_to_string
+ *
+ * PARAMETERS:  original_object     - Object to be converted
+ *              return_object       - Where the new converted object is returned
+ *
+ * RETURN:      Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_convert_to_string(union acpi_operand_object *original_object,
+			  union acpi_operand_object **return_object)
+{
+	union acpi_operand_object *new_object;
+	acpi_size length;
+	acpi_status status;
+
+	switch (original_object->common.type) {
+	case ACPI_TYPE_INTEGER:
 		/*
-		 * Have a Buffer, expected a String, convert. Use a to_string
+		 * Integer-to-String conversion. Commonly, convert
+		 * an integer of value 0 to a NULL string. The last element of
+		 * _BIF and _BIX packages occasionally need this fix.
+		 */
+		if (original_object->integer.value == 0) {
+
+			/* Allocate a new NULL string object */
+
+			new_object = acpi_ut_create_string_object(0);
+			if (!new_object) {
+				return (AE_NO_MEMORY);
+			}
+		} else {
+			status =
+			    acpi_ex_convert_to_string(original_object,
+						      &new_object,
+						      ACPI_IMPLICIT_CONVERT_HEX);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		}
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		/*
+		 * Buffer-to-String conversion. Use a to_string
 		 * conversion, no transform performed on the buffer data. The best
 		 * example of this is the _BIF method, where the string data from
 		 * the battery is often (incorrectly) returned as buffer object(s).
 		 */
 		length = 0;
-		while ((length < return_object->buffer.length) &&
-		       (return_object->buffer.pointer[length])) {
+		while ((length < original_object->buffer.length) &&
+		       (original_object->buffer.pointer[length])) {
 			length++;
 		}
 
@@ -110,44 +331,177 @@ acpi_ns_repair_object(struct acpi_predef
 		 * terminated at Length+1.
 		 */
 		ACPI_MEMCPY(new_object->string.pointer,
-			    return_object->buffer.pointer, length);
+			    original_object->buffer.pointer, length);
+		break;
+
+	default:
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	*return_object = new_object;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_to_buffer
+ *
+ * PARAMETERS:  original_object     - Object to be converted
+ *              return_object       - Where the new converted object is returned
+ *
+ * RETURN:      Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
+			  union acpi_operand_object **return_object)
+{
+	union acpi_operand_object *new_object;
+	acpi_status status;
+	union acpi_operand_object **elements;
+	u32 *dword_buffer;
+	u32 count;
+	u32 i;
 
+	switch (original_object->common.type) {
+	case ACPI_TYPE_INTEGER:
 		/*
-		 * If the original object is a package element, we need to:
-		 * 1. Set the reference count of the new object to match the
-		 *    reference count of the old object.
-		 * 2. Decrement the reference count of the original object.
+		 * Integer-to-Buffer conversion.
+		 * Convert the Integer to a packed-byte buffer. _MAT and other
+		 * objects need this sometimes, if a read has been performed on a
+		 * Field object that is less than or equal to the global integer
+		 * size (32 or 64 bits).
 		 */
-		if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
-			new_object->common.reference_count =
-			    return_object->common.reference_count;
+		status =
+		    acpi_ex_convert_to_buffer(original_object, &new_object);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+		break;
 
-			if (return_object->common.reference_count > 1) {
-				return_object->common.reference_count--;
+	case ACPI_TYPE_STRING:
+
+		/* String-to-Buffer conversion. Simple data copy */
+
+		new_object =
+		    acpi_ut_create_buffer_object(original_object->string.
+						 length);
+		if (!new_object) {
+			return (AE_NO_MEMORY);
+		}
+
+		ACPI_MEMCPY(new_object->buffer.pointer,
+			    original_object->string.pointer,
+			    original_object->string.length);
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+		/*
+		 * This case is often seen for predefined names that must return a
+		 * Buffer object with multiple DWORD integers within. For example,
+		 * _FDE and _GTM. The Package can be converted to a Buffer.
+		 */
+
+		/* All elements of the Package must be integers */
+
+		elements = original_object->package.elements;
+		count = original_object->package.count;
+
+		for (i = 0; i < count; i++) {
+			if ((!*elements) ||
+			    ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
+				return (AE_AML_OPERAND_TYPE);
 			}
+			elements++;
+		}
 
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
-					      "Converted Buffer to expected String at index %u",
-					      package_index));
-		} else {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
-					      "Converted Buffer to expected String"));
+		/* Create the new buffer object to replace the Package */
+
+		new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
+		if (!new_object) {
+			return (AE_NO_MEMORY);
 		}
 
-		/* Delete old object, install the new return object */
+		/* Copy the package elements (integers) to the buffer as DWORDs */
 
-		acpi_ut_remove_reference(return_object);
-		*return_object_ptr = new_object;
-		data->flags |= ACPI_OBJECT_REPAIRED;
-		return (AE_OK);
+		elements = original_object->package.elements;
+		dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
+
+		for (i = 0; i < count; i++) {
+			*dword_buffer = (u32) (*elements)->integer.value;
+			dword_buffer++;
+			elements++;
+		}
+		break;
 
 	default:
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	*return_object = new_object;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_to_package
+ *
+ * PARAMETERS:  original_object     - Object to be converted
+ *              return_object       - Where the new converted object is returned
+ *
+ * RETURN:      Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
+ *              the buffer is converted to a single integer package element.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_convert_to_package(union acpi_operand_object *original_object,
+			   union acpi_operand_object **return_object)
+{
+	union acpi_operand_object *new_object;
+	union acpi_operand_object **elements;
+	u32 length;
+	u8 *buffer;
+
+	switch (original_object->common.type) {
+	case ACPI_TYPE_BUFFER:
+
+		/* Buffer-to-Package conversion */
+
+		length = original_object->buffer.length;
+		new_object = acpi_ut_create_package_object(length);
+		if (!new_object) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Convert each buffer byte to an integer package element */
+
+		elements = new_object->package.elements;
+		buffer = original_object->buffer.pointer;
+
+		while (length--) {
+			*elements =
+			    acpi_ut_create_integer_object((u64) *buffer);
+			if (!*elements) {
+				acpi_ut_remove_reference(new_object);
+				return (AE_NO_MEMORY);
+			}
+			elements++;
+			buffer++;
+		}
 		break;
+
+	default:
+		return (AE_AML_OPERAND_TYPE);
 	}
 
-	return (AE_AML_OPERAND_TYPE);
+	*return_object = new_object;
+	return (AE_OK);
 }
 
 /*******************************************************************************
@@ -180,6 +534,8 @@ acpi_ns_repair_package_list(struct acpi_
 {
 	union acpi_operand_object *pkg_obj_desc;
 
+	ACPI_FUNCTION_NAME(ns_repair_package_list);
+
 	/*
 	 * Create the new outer package and populate it. The new package will
 	 * have a single element, the lone subpackage.
@@ -196,8 +552,9 @@ acpi_ns_repair_package_list(struct acpi_
 	*obj_desc_ptr = pkg_obj_desc;
 	data->flags |= ACPI_OBJECT_REPAIRED;
 
-	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
-			      "Incorrectly formed Package, attempting repair"));
+	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
+			  "%s: Repaired incorrectly formed Package\n",
+			  data->pathname));
 
 	return (AE_OK);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsutils.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsutils.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsutils.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsutils.c	2010-02-24 13:52:17.000000000 -0500
@@ -671,24 +671,25 @@ acpi_ns_externalize_name(u32 internal_na
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_map_handle_to_node
+ * FUNCTION:    acpi_ns_validate_handle
  *
- * PARAMETERS:  Handle          - Handle to be converted to an Node
+ * PARAMETERS:  Handle          - Handle to be validated and typecast to a
+ *                                namespace node.
  *
- * RETURN:      A Name table entry pointer
+ * RETURN:      A pointer to a namespace node
  *
- * DESCRIPTION: Convert a namespace handle to a real Node
+ * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
+ *              cases for the root node.
  *
- * Note: Real integer handles would allow for more verification
+ * NOTE: Real integer handles would allow for more verification
  *       and keep all pointers within this subsystem - however this introduces
- *       more (and perhaps unnecessary) overhead.
- *
- * The current implemenation is basically a placeholder until such time comes
- * that it is needed.
+ *       more overhead and has not been necessary to this point. Drivers
+ *       holding handles are typically notified before a node becomes invalid
+ *       due to a table unload.
  *
  ******************************************************************************/
 
-struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
+struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle)
 {
 
 	ACPI_FUNCTION_ENTRY();
@@ -709,42 +710,6 @@ struct acpi_namespace_node *acpi_ns_map_
 }
 
 /*******************************************************************************
- *
- * FUNCTION:    acpi_ns_convert_entry_to_handle
- *
- * PARAMETERS:  Node          - Node to be converted to a Handle
- *
- * RETURN:      A user handle
- *
- * DESCRIPTION: Convert a real Node to a namespace handle
- *
- ******************************************************************************/
-
-acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node)
-{
-
-	/*
-	 * Simple implementation for now;
-	 */
-	return ((acpi_handle) node);
-
-/* Example future implementation ---------------------
-
-	if (!Node)
-	{
-		return (NULL);
-	}
-
-	if (Node == acpi_gbl_root_node)
-	{
-		return (ACPI_ROOT_OBJECT);
-	}
-
-	return ((acpi_handle) Node);
-------------------------------------------------------*/
-}
-
-/*******************************************************************************
  *
  * FUNCTION:    acpi_ns_terminate
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nswalk.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nswalk.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nswalk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nswalk.c	2010-02-24 13:52:17.000000000 -0500
@@ -165,24 +165,27 @@ struct acpi_namespace_node *acpi_ns_get_
  *              max_depth           - Depth to which search is to reach
  *              Flags               - Whether to unlock the NS before invoking
  *                                    the callback routine
- *              user_function       - Called when an object of "Type" is found
- *              Context             - Passed to user function
- *              return_value        - from the user_function if terminated early.
- *                                    Otherwise, returns NULL.
+ *              pre_order_visit     - Called during tree pre-order visit
+ *                                    when an object of "Type" is found
+ *              post_order_visit    - Called during tree post-order visit
+ *                                    when an object of "Type" is found
+ *              Context             - Passed to user function(s) above
+ *              return_value        - from the user_function if terminated
+ *                                    early. Otherwise, returns NULL.
  * RETURNS:     Status
  *
  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  *              starting (and ending) at the node specified by start_handle.
- *              The user_function is called whenever a node that matches
- *              the type parameter is found.  If the user function returns
+ *              The callback function is called whenever a node that matches
+ *              the type parameter is found. If the callback function returns
  *              a non-zero value, the search is terminated immediately and
  *              this value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
- *              provide multiple services;  the User Function can be tailored
- *              to each task, whether it is a print function, a compare
- *              function, etc.
+ *              provide multiple services; the callback function(s) can be
+ *              tailored to each task, whether it is a print function,
+ *              a compare function, etc.
  *
  ******************************************************************************/
 
@@ -191,7 +194,8 @@ acpi_ns_walk_namespace(acpi_object_type
 		       acpi_handle start_node,
 		       u32 max_depth,
 		       u32 flags,
-		       acpi_walk_callback user_function,
+		       acpi_walk_callback pre_order_visit,
+		       acpi_walk_callback post_order_visit,
 		       void *context, void **return_value)
 {
 	acpi_status status;
@@ -200,6 +204,7 @@ acpi_ns_walk_namespace(acpi_object_type
 	struct acpi_namespace_node *parent_node;
 	acpi_object_type child_type;
 	u32 level;
+	u8 node_previously_visited = FALSE;
 
 	ACPI_FUNCTION_TRACE(ns_walk_namespace);
 
@@ -212,7 +217,7 @@ acpi_ns_walk_namespace(acpi_object_type
 	/* Null child means "get first node" */
 
 	parent_node = start_node;
-	child_node = NULL;
+	child_node = acpi_ns_get_next_node(parent_node, NULL);
 	child_type = ACPI_TYPE_ANY;
 	level = 1;
 
@@ -221,102 +226,129 @@ acpi_ns_walk_namespace(acpi_object_type
 	 * started. When Level is zero, the loop is done because we have
 	 * bubbled up to (and passed) the original parent handle (start_entry)
 	 */
-	while (level > 0) {
+	while (level > 0 && child_node) {
+		status = AE_OK;
 
-		/* Get the next node in this scope.  Null if not found */
+		/* Found next child, get the type if we are not searching for ANY */
 
-		status = AE_OK;
-		child_node = acpi_ns_get_next_node(parent_node, child_node);
-		if (child_node) {
+		if (type != ACPI_TYPE_ANY) {
+			child_type = child_node->type;
+		}
 
-			/* Found next child, get the type if we are not searching for ANY */
+		/*
+		 * Ignore all temporary namespace nodes (created during control
+		 * method execution) unless told otherwise. These temporary nodes
+		 * can cause a race condition because they can be deleted during
+		 * the execution of the user function (if the namespace is
+		 * unlocked before invocation of the user function.) Only the
+		 * debugger namespace dump will examine the temporary nodes.
+		 */
+		if ((child_node->flags & ANOBJ_TEMPORARY) &&
+		    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
+			status = AE_CTRL_DEPTH;
+		}
 
-			if (type != ACPI_TYPE_ANY) {
-				child_type = child_node->type;
-			}
+		/* Type must match requested type */
 
+		else if (child_type == type) {
 			/*
-			 * Ignore all temporary namespace nodes (created during control
-			 * method execution) unless told otherwise. These temporary nodes
-			 * can cause a race condition because they can be deleted during
-			 * the execution of the user function (if the namespace is
-			 * unlocked before invocation of the user function.) Only the
-			 * debugger namespace dump will examine the temporary nodes.
+			 * Found a matching node, invoke the user callback function.
+			 * Unlock the namespace if flag is set.
 			 */
-			if ((child_node->flags & ANOBJ_TEMPORARY) &&
-			    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
-				status = AE_CTRL_DEPTH;
+			if (flags & ACPI_NS_WALK_UNLOCK) {
+				mutex_status =
+				    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE(mutex_status)) {
+					return_ACPI_STATUS(mutex_status);
+				}
 			}
 
-			/* Type must match requested type */
-
-			else if (child_type == type) {
-				/*
-				 * Found a matching node, invoke the user callback function.
-				 * Unlock the namespace if flag is set.
-				 */
-				if (flags & ACPI_NS_WALK_UNLOCK) {
-					mutex_status =
-					    acpi_ut_release_mutex
-					    (ACPI_MTX_NAMESPACE);
-					if (ACPI_FAILURE(mutex_status)) {
-						return_ACPI_STATUS
-						    (mutex_status);
-					}
+			/*
+			 * Invoke the user function, either pre-order or post-order
+			 * or both.
+			 */
+			if (!node_previously_visited) {
+				if (pre_order_visit) {
+					status =
+					    pre_order_visit(child_node, level,
+							    context,
+							    return_value);
 				}
+			} else {
+				if (post_order_visit) {
+					status =
+					    post_order_visit(child_node, level,
+							     context,
+							     return_value);
+				}
+			}
 
-				status =
-				    user_function(child_node, level, context,
-						  return_value);
-
-				if (flags & ACPI_NS_WALK_UNLOCK) {
-					mutex_status =
-					    acpi_ut_acquire_mutex
-					    (ACPI_MTX_NAMESPACE);
-					if (ACPI_FAILURE(mutex_status)) {
-						return_ACPI_STATUS
-						    (mutex_status);
-					}
+			if (flags & ACPI_NS_WALK_UNLOCK) {
+				mutex_status =
+				    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE(mutex_status)) {
+					return_ACPI_STATUS(mutex_status);
 				}
+			}
 
-				switch (status) {
-				case AE_OK:
-				case AE_CTRL_DEPTH:
+			switch (status) {
+			case AE_OK:
+			case AE_CTRL_DEPTH:
 
-					/* Just keep going */
-					break;
+				/* Just keep going */
+				break;
 
-				case AE_CTRL_TERMINATE:
+			case AE_CTRL_TERMINATE:
 
-					/* Exit now, with OK status */
+				/* Exit now, with OK status */
 
-					return_ACPI_STATUS(AE_OK);
+				return_ACPI_STATUS(AE_OK);
 
-				default:
+			default:
 
-					/* All others are valid exceptions */
+				/* All others are valid exceptions */
 
-					return_ACPI_STATUS(status);
-				}
+				return_ACPI_STATUS(status);
 			}
+		}
 
-			/*
-			 * Depth first search: Attempt to go down another level in the
-			 * namespace if we are allowed to.  Don't go any further if we have
-			 * reached the caller specified maximum depth or if the user
-			 * function has specified that the maximum depth has been reached.
-			 */
-			if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
-				if (child_node->child) {
+		/*
+		 * Depth first search: Attempt to go down another level in the
+		 * namespace if we are allowed to.  Don't go any further if we have
+		 * reached the caller specified maximum depth or if the user
+		 * function has specified that the maximum depth has been reached.
+		 */
+		if (!node_previously_visited &&
+		    (level < max_depth) && (status != AE_CTRL_DEPTH)) {
+			if (child_node->child) {
 
-					/* There is at least one child of this node, visit it */
+				/* There is at least one child of this node, visit it */
 
-					level++;
-					parent_node = child_node;
-					child_node = NULL;
-				}
+				level++;
+				parent_node = child_node;
+				child_node =
+				    acpi_ns_get_next_node(parent_node, NULL);
+				continue;
 			}
-		} else {
+		}
+
+		/* No more children, re-visit this node */
+
+		if (!node_previously_visited) {
+			node_previously_visited = TRUE;
+			continue;
+		}
+
+		/* No more children, visit peers */
+
+		child_node = acpi_ns_get_next_node(parent_node, child_node);
+		if (child_node) {
+			node_previously_visited = FALSE;
+		}
+
+		/* No peers, re-visit parent */
+
+		else {
 			/*
 			 * No more children of this node (acpi_ns_get_next_node failed), go
 			 * back upwards in the namespace tree to the node's parent.
@@ -324,6 +356,8 @@ acpi_ns_walk_namespace(acpi_object_type
 			level--;
 			child_node = parent_node;
 			parent_node = acpi_ns_get_parent_node(parent_node);
+
+			node_previously_visited = TRUE;
 		}
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfeval.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfeval.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfeval.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfeval.c	2010-02-24 13:52:17.000000000 -0500
@@ -190,7 +190,7 @@ acpi_evaluate_object(acpi_handle handle,
 
 	/* Convert and validate the device handle */
 
-	info->prefix_node = acpi_ns_map_handle_to_node(handle);
+	info->prefix_node = acpi_ns_validate_handle(handle);
 	if (!info->prefix_node) {
 		status = AE_BAD_PARAMETER;
 		goto cleanup;
@@ -433,8 +433,11 @@ static void acpi_ns_resolve_references(s
  * PARAMETERS:  Type                - acpi_object_type to search for
  *              start_object        - Handle in namespace where search begins
  *              max_depth           - Depth to which search is to reach
- *              user_function       - Called when an object of "Type" is found
- *              Context             - Passed to user function
+ *              pre_order_visit     - Called during tree pre-order visit
+ *                                    when an object of "Type" is found
+ *              post_order_visit    - Called during tree post-order visit
+ *                                    when an object of "Type" is found
+ *              Context             - Passed to user function(s) above
  *              return_value        - Location where return value of
  *                                    user_function is put if terminated early
  *
@@ -443,16 +446,16 @@ static void acpi_ns_resolve_references(s
  *
  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  *              starting (and ending) at the object specified by start_handle.
- *              The user_function is called whenever an object that matches
- *              the type parameter is found.  If the user function returns
+ *              The callback function is called whenever an object that matches
+ *              the type parameter is found. If the callback function returns
  *              a non-zero value, the search is terminated immediately and this
  *              value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
- *              provide multiple services;  the User Function can be tailored
- *              to each task, whether it is a print function, a compare
- *              function, etc.
+ *              provide multiple services; the callback function(s) can be
+ *              tailored to each task, whether it is a print function,
+ *              a compare function, etc.
  *
  ******************************************************************************/
 
@@ -460,7 +463,8 @@ acpi_status
 acpi_walk_namespace(acpi_object_type type,
 		    acpi_handle start_object,
 		    u32 max_depth,
-		    acpi_walk_callback user_function,
+		    acpi_walk_callback pre_order_visit,
+		    acpi_walk_callback post_order_visit,
 		    void *context, void **return_value)
 {
 	acpi_status status;
@@ -469,7 +473,8 @@ acpi_walk_namespace(acpi_object_type typ
 
 	/* Parameter validation */
 
-	if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
+	if ((type > ACPI_TYPE_LOCAL_MAX) ||
+	    (!max_depth) || (!pre_order_visit && !post_order_visit)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -501,8 +506,9 @@ acpi_walk_namespace(acpi_object_type typ
 	}
 
 	status = acpi_ns_walk_namespace(type, start_object, max_depth,
-					ACPI_NS_WALK_UNLOCK, user_function,
-					context, return_value);
+					ACPI_NS_WALK_UNLOCK, pre_order_visit,
+					post_order_visit, context,
+					return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
@@ -546,7 +552,7 @@ acpi_ns_get_device_callback(acpi_handle
 		return (status);
 	}
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
 		return (status);
@@ -681,8 +687,8 @@ acpi_get_devices(const char *HID,
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-					acpi_ns_get_device_callback, &info,
-					return_value);
+					acpi_ns_get_device_callback, NULL,
+					&info, return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS(status);
@@ -723,7 +729,7 @@ acpi_attach_data(acpi_handle obj_handle,
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -769,7 +775,7 @@ acpi_detach_data(acpi_handle obj_handle,
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -816,7 +822,7 @@ acpi_get_data(acpi_handle obj_handle, ac
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(obj_handle);
+	node = acpi_ns_validate_handle(obj_handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfname.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfname.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfname.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfname.c	2010-02-24 13:52:17.000000000 -0500
@@ -93,7 +93,7 @@ acpi_get_handle(acpi_handle parent,
 	/* Convert a parent handle to a prefix node */
 
 	if (parent) {
-		prefix_node = acpi_ns_map_handle_to_node(parent);
+		prefix_node = acpi_ns_validate_handle(parent);
 		if (!prefix_node) {
 			return (AE_BAD_PARAMETER);
 		}
@@ -114,7 +114,7 @@ acpi_get_handle(acpi_handle parent,
 
 		if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) {
 			*ret_handle =
-			    acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
+			    ACPI_CAST_PTR(acpi_handle, acpi_gbl_root_node);
 			return (AE_OK);
 		}
 	} else if (!prefix_node) {
@@ -129,7 +129,7 @@ acpi_get_handle(acpi_handle parent,
 	status =
 	    acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
 	if (ACPI_SUCCESS(status)) {
-		*ret_handle = acpi_ns_convert_entry_to_handle(node);
+		*ret_handle = ACPI_CAST_PTR(acpi_handle, node);
 	}
 
 	return (status);
@@ -186,7 +186,7 @@ acpi_get_name(acpi_handle handle, u32 na
 		return (status);
 	}
 
-	node = acpi_ns_map_handle_to_node(handle);
+	node = acpi_ns_validate_handle(handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -291,7 +291,7 @@ acpi_get_object_info(acpi_handle handle,
 		goto cleanup;
 	}
 
-	node = acpi_ns_map_handle_to_node(handle);
+	node = acpi_ns_validate_handle(handle);
 	if (!node) {
 		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfobj.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfobj.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/nsxfobj.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/nsxfobj.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ acpi_status acpi_get_id(acpi_handle hand
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(handle);
+	node = acpi_ns_validate_handle(handle);
 	if (!node) {
 		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
@@ -132,7 +132,7 @@ acpi_status acpi_get_type(acpi_handle ha
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(handle);
+	node = acpi_ns_validate_handle(handle);
 	if (!node) {
 		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 		return (AE_BAD_PARAMETER);
@@ -182,7 +182,7 @@ acpi_status acpi_get_parent(acpi_handle
 
 	/* Convert and validate the handle */
 
-	node = acpi_ns_map_handle_to_node(handle);
+	node = acpi_ns_validate_handle(handle);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
@@ -191,7 +191,7 @@ acpi_status acpi_get_parent(acpi_handle
 	/* Get the parent entry */
 
 	parent_node = acpi_ns_get_parent_node(node);
-	*ret_handle = acpi_ns_convert_entry_to_handle(parent_node);
+	*ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node);
 
 	/* Return exception if parent is null */
 
@@ -251,7 +251,7 @@ acpi_get_next_object(acpi_object_type ty
 
 		/* Start search at the beginning of the specified scope */
 
-		parent_node = acpi_ns_map_handle_to_node(parent);
+		parent_node = acpi_ns_validate_handle(parent);
 		if (!parent_node) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
@@ -260,7 +260,7 @@ acpi_get_next_object(acpi_object_type ty
 		/* Non-null handle, ignore the parent */
 		/* Convert and validate the handle */
 
-		child_node = acpi_ns_map_handle_to_node(child);
+		child_node = acpi_ns_validate_handle(child);
 		if (!child_node) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
@@ -276,7 +276,7 @@ acpi_get_next_object(acpi_object_type ty
 	}
 
 	if (ret_handle) {
-		*ret_handle = acpi_ns_convert_entry_to_handle(node);
+		*ret_handle = ACPI_CAST_PTR(acpi_handle, node);
 	}
 
       unlock_and_exit:
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psloop.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psloop.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psloop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psloop.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,8 @@ acpi_ps_complete_final_op(struct acpi_wa
 			  union acpi_parse_object *op, acpi_status status);
 
 static void
-acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
+acpi_ps_link_module_code(union acpi_parse_object *parent_op,
+			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
 
 /*******************************************************************************
  *
@@ -479,11 +480,14 @@ acpi_ps_get_arguments(struct acpi_walk_s
 				 */
 				if (walk_state->pass_number ==
 				    ACPI_IMODE_LOAD_PASS1) {
-					acpi_ps_link_module_code(aml_op_start,
-								 walk_state->
+					acpi_ps_link_module_code(op->common.
+								 parent,
+								 aml_op_start,
+								 (u32)
+								 (walk_state->
 								 parser_state.
 								 pkg_end -
-								 aml_op_start,
+								 aml_op_start),
 								 walk_state->
 								 owner_id);
 				}
@@ -598,7 +602,8 @@ acpi_ps_get_arguments(struct acpi_walk_s
  *
  * FUNCTION:    acpi_ps_link_module_code
  *
- * PARAMETERS:  aml_start           - Pointer to the AML
+ * PARAMETERS:  parent_op           - Parent parser op
+ *              aml_start           - Pointer to the AML
  *              aml_length          - Length of executable AML
  *              owner_id            - owner_id of module level code
  *
@@ -611,11 +616,13 @@ acpi_ps_get_arguments(struct acpi_walk_s
  ******************************************************************************/
 
 static void
-acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
+acpi_ps_link_module_code(union acpi_parse_object *parent_op,
+			 u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
 {
 	union acpi_operand_object *prev;
 	union acpi_operand_object *next;
 	union acpi_operand_object *method_obj;
+	struct acpi_namespace_node *parent_node;
 
 	/* Get the tail of the list */
 
@@ -639,11 +646,24 @@ acpi_ps_link_module_code(u8 *aml_start,
 			return;
 		}
 
+		if (parent_op->common.node) {
+			parent_node = parent_op->common.node;
+		} else {
+			parent_node = acpi_gbl_root_node;
+		}
+
 		method_obj->method.aml_start = aml_start;
 		method_obj->method.aml_length = aml_length;
 		method_obj->method.owner_id = owner_id;
 		method_obj->method.flags |= AOPOBJ_MODULE_LEVEL;
 
+		/*
+		 * Save the parent node in next_object. This is cheating, but we
+		 * don't want to expand the method object.
+		 */
+		method_obj->method.next_object =
+		    ACPI_CAST_PTR(union acpi_operand_object, parent_node);
+
 		if (!prev) {
 			acpi_gbl_module_code_list = method_obj;
 		} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psparse.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psparse.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psparse.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psparse.c	2010-02-24 13:52:17.000000000 -0500
@@ -610,17 +610,13 @@ acpi_status acpi_ps_parse_aml(struct acp
 					    implicit_return_obj) {
 						previous_walk_state->
 						    implicit_return_obj =
-						    acpi_ut_create_internal_object
-						    (ACPI_TYPE_INTEGER);
+						    acpi_ut_create_integer_object
+						    ((u64) 0);
 						if (!previous_walk_state->
 						    implicit_return_obj) {
 							return_ACPI_STATUS
 							    (AE_NO_MEMORY);
 						}
-
-						previous_walk_state->
-						    implicit_return_obj->
-						    integer.value = 0;
 					}
 
 					/* Restart the calling control method */
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psxface.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psxface.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/psxface.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/psxface.c	2010-02-24 13:52:17.000000000 -0500
@@ -287,7 +287,8 @@ acpi_status acpi_ps_execute_method(struc
 	/* Invoke an internal method if necessary */
 
 	if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
-		status = info->obj_desc->method.implementation(walk_state);
+		status =
+		    info->obj_desc->method.extra.implementation(walk_state);
 		info->return_object = walk_state->return_desc;
 
 		/* Cleanup states */
@@ -306,14 +307,12 @@ acpi_status acpi_ps_execute_method(struc
 	 */
 	if (acpi_gbl_enable_interpreter_slack) {
 		walk_state->implicit_return_obj =
-		    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+		    acpi_ut_create_integer_object((u64) 0);
 		if (!walk_state->implicit_return_obj) {
 			status = AE_NO_MEMORY;
 			acpi_ds_delete_walk_state(walk_state);
 			goto cleanup;
 		}
-
-		walk_state->implicit_return_obj->integer.value = 0;
 	}
 
 	/* Parse the AML */
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/rsxface.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsxface.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/rsxface.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/rsxface.c	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,7 @@ acpi_rs_validate_parameters(acpi_handle
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	node = acpi_ns_map_handle_to_node(device_handle);
+	node = acpi_ns_validate_handle(device_handle);
 	if (!node) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utcopy.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utcopy.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utcopy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utcopy.c	2010-02-24 13:52:17.000000000 -0500
@@ -323,11 +323,11 @@ acpi_ut_copy_ielement_to_eelement(u8 obj
  * RETURN:      Status
  *
  * DESCRIPTION: This function is called to place a package object in a user
- *              buffer.  A package object by definition contains other objects.
+ *              buffer. A package object by definition contains other objects.
  *
  *              The buffer is assumed to have sufficient space for the object.
- *              The caller must have verified the buffer length needed using the
- *              acpi_ut_get_object_size function before calling this function.
+ *              The caller must have verified the buffer length needed using
+ *              the acpi_ut_get_object_size function before calling this function.
  *
  ******************************************************************************/
 
@@ -382,12 +382,12 @@ acpi_ut_copy_ipackage_to_epackage(union
  * FUNCTION:    acpi_ut_copy_iobject_to_eobject
  *
  * PARAMETERS:  internal_object     - The internal object to be converted
- *              buffer_ptr          - Where the object is returned
+ *              ret_buffer          - Where the object is returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to build an API object to be returned to
- *              the caller.
+ * DESCRIPTION: This function is called to build an API object to be returned
+ *              to the caller.
  *
  ******************************************************************************/
 
@@ -626,7 +626,7 @@ acpi_ut_copy_epackage_to_ipackage(union
  * PARAMETERS:  external_object     - The external object to be converted
  *              internal_object     - Where the internal object is returned
  *
- * RETURN:      Status              - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: Converts an external object to an internal object.
  *
@@ -665,7 +665,7 @@ acpi_ut_copy_eobject_to_iobject(union ac
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Simple copy of one internal object to another.  Reference count
+ * DESCRIPTION: Simple copy of one internal object to another. Reference count
  *              of the destination object is preserved.
  *
  ******************************************************************************/
@@ -897,10 +897,11 @@ acpi_ut_copy_ielement_to_ielement(u8 obj
  *
  * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage
  *
- * PARAMETERS:  *source_obj     - Pointer to the source package object
- *              *dest_obj       - Where the internal object is returned
+ * PARAMETERS:  source_obj      - Pointer to the source package object
+ *              dest_obj        - Where the internal object is returned
+ *              walk_state      - Current Walk state descriptor
  *
- * RETURN:      Status          - the status of the call
+ * RETURN:      Status
  *
  * DESCRIPTION: This function is called to copy an internal package object
  *              into another internal package object.
@@ -953,9 +954,9 @@ acpi_ut_copy_ipackage_to_ipackage(union
  *
  * FUNCTION:    acpi_ut_copy_iobject_to_iobject
  *
- * PARAMETERS:  walk_state          - Current walk state
- *              source_desc         - The internal object to be copied
+ * PARAMETERS:  source_desc         - The internal object to be copied
  *              dest_desc           - Where the copied object is returned
+ *              walk_state          - Current walk state
  *
  * RETURN:      Status
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utmisc.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmisc.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utmisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utmisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -1161,3 +1161,45 @@ acpi_ut_predefined_warning(const char *m
 	ACPI_COMMON_MSG_SUFFIX;
 	va_end(args);
 }
+
+/*******************************************************************************
+ *
+ * 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 args;
+
+	/*
+	 * 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 Info for %s: ", pathname);
+
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	ACPI_COMMON_MSG_SUFFIX;
+	va_end(args);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utobject.c linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utobject.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpica/utobject.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpica/utobject.c	2010-02-24 13:52:17.000000000 -0500
@@ -190,6 +190,35 @@ union acpi_operand_object *acpi_ut_creat
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_create_integer_object
+ *
+ * PARAMETERS:  initial_value       - Initial value for the integer
+ *
+ * RETURN:      Pointer to a new Integer object, null on failure
+ *
+ * DESCRIPTION: Create an initialized integer object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
+{
+	union acpi_operand_object *integer_desc;
+
+	ACPI_FUNCTION_TRACE(ut_create_integer_object);
+
+	/* Create and initialize a new integer object */
+
+	integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
+	if (!integer_desc) {
+		return_PTR(NULL);
+	}
+
+	integer_desc->integer.value = initial_value;
+	return_PTR(integer_desc);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_create_buffer_object
  *
  * PARAMETERS:  buffer_size            - Size of buffer to be created
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpi_memhotplug.c linux-libre-2.6.33-gnu1/drivers/acpi/acpi_memhotplug.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpi_memhotplug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpi_memhotplug.c	2010-02-24 13:52:17.000000000 -0500
@@ -537,7 +537,7 @@ static int __init acpi_memory_device_ini
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     acpi_memory_register_notify_handler,
+				     acpi_memory_register_notify_handler, NULL,
 				     NULL, NULL);
 
 	if (ACPI_FAILURE(status)) {
@@ -561,7 +561,7 @@ static void __exit acpi_memory_device_ex
 	 */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     acpi_memory_deregister_notify_handler,
+				     acpi_memory_deregister_notify_handler, NULL,
 				     NULL, NULL);
 
 	if (ACPI_FAILURE(status))
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/acpi_pad.c linux-libre-2.6.33-gnu1/drivers/acpi/acpi_pad.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/acpi_pad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/acpi_pad.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,7 +100,8 @@ static void round_robin_cpu(unsigned int
 	struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
 	cpumask_var_t tmp;
 	int cpu;
-	unsigned long min_weight = -1, preferred_cpu;
+	unsigned long min_weight = -1;
+	unsigned long uninitialized_var(preferred_cpu);
 
 	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
 		return;
@@ -207,7 +208,7 @@ static int power_saving_thread(void *dat
 		 * the mechanism only works when all CPUs have RT task running,
 		 * as if one CPU hasn't RT task, RT task from other CPUs will
 		 * borrow CPU time from this CPU and cause RT task use > 95%
-		 * CPU time. To make 'avoid staration' work, takes a nap here.
+		 * CPU time. To make 'avoid starvation' work, takes a nap here.
 		 */
 		if (do_sleep)
 			schedule_timeout_killable(HZ * idle_pct / 100);
@@ -221,14 +222,18 @@ static struct task_struct *ps_tsks[NR_CP
 static unsigned int ps_tsk_num;
 static int create_power_saving_task(void)
 {
+	int rc = -ENOMEM;
+
 	ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
 		(void *)(unsigned long)ps_tsk_num,
 		"power_saving/%d", ps_tsk_num);
-	if (ps_tsks[ps_tsk_num]) {
+	rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
+	if (!rc)
 		ps_tsk_num++;
-		return 0;
-	}
-	return -EINVAL;
+	else
+		ps_tsks[ps_tsk_num] = NULL;
+
+	return rc;
 }
 
 static void destroy_power_saving_task(void)
@@ -236,6 +241,7 @@ static void destroy_power_saving_task(vo
 	if (ps_tsk_num > 0) {
 		ps_tsk_num--;
 		kthread_stop(ps_tsks[ps_tsk_num]);
+		ps_tsks[ps_tsk_num] = NULL;
 	}
 }
 
@@ -252,7 +258,7 @@ static void set_power_saving_task_num(un
 	}
 }
 
-static int acpi_pad_idle_cpus(unsigned int num_cpus)
+static void acpi_pad_idle_cpus(unsigned int num_cpus)
 {
 	get_online_cpus();
 
@@ -260,7 +266,6 @@ static int acpi_pad_idle_cpus(unsigned i
 	set_power_saving_task_num(num_cpus);
 
 	put_online_cpus();
-	return 0;
 }
 
 static uint32_t acpi_pad_idle_cpus_num(void)
@@ -368,19 +373,21 @@ static void acpi_pad_remove_sysfs(struct
 static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
 {
 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	acpi_status status;
 	union acpi_object *package;
 	int rev, num, ret = -EINVAL;
 
-	status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
 		return -EINVAL;
+
+	if (!buffer.length || !buffer.pointer)
+		return -EINVAL;
+
 	package = buffer.pointer;
 	if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
 		goto out;
 	rev = package->package.elements[0].integer.value;
 	num = package->package.elements[1].integer.value;
-	if (rev != 1)
+	if (rev != 1 || num < 0)
 		goto out;
 	*num_cpus = num;
 	ret = 0;
@@ -409,7 +416,7 @@ static void acpi_pad_ost(acpi_handle han
 
 static void acpi_pad_handle_notify(acpi_handle handle)
 {
-	int num_cpus, ret;
+	int num_cpus;
 	uint32_t idle_cpus;
 
 	mutex_lock(&isolated_cpus_lock);
@@ -417,12 +424,9 @@ static void acpi_pad_handle_notify(acpi_
 		mutex_unlock(&isolated_cpus_lock);
 		return;
 	}
-	ret = acpi_pad_idle_cpus(num_cpus);
+	acpi_pad_idle_cpus(num_cpus);
 	idle_cpus = acpi_pad_idle_cpus_num();
-	if (!ret)
-		acpi_pad_ost(handle, 0, idle_cpus);
-	else
-		acpi_pad_ost(handle, 1, 0);
+	acpi_pad_ost(handle, 0, idle_cpus);
 	mutex_unlock(&isolated_cpus_lock);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/battery.c linux-libre-2.6.33-gnu1/drivers/acpi/battery.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/battery.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/battery.c	2010-02-24 13:52:17.000000000 -0500
@@ -831,7 +831,7 @@ static void acpi_battery_notify(struct a
 					dev_name(&device->dev), event,
 					acpi_battery_present(battery));
 #ifdef CONFIG_ACPI_SYSFS_POWER
-	/* acpi_batter_update could remove power_supply object */
+	/* acpi_battery_update could remove power_supply object */
 	if (battery->bat.dev)
 		kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/blacklist.c linux-libre-2.6.33-gnu1/drivers/acpi/blacklist.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/blacklist.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/blacklist.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(
 	acpi_osi_setup("!Windows 2006");
 	return 0;
 }
+static int __init dmi_disable_osi_win7(const struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+	acpi_osi_setup("!Windows 2009");
+	return 0;
+}
 
 static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
 	{
@@ -211,6 +217,14 @@ static struct dmi_system_id acpi_osi_dmi
 		     DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"),
 		},
 	},
+	{
+	.callback = dmi_disable_osi_win7,
+	.ident = "ASUS K50IJ",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+		     DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"),
+		},
+	},
 
 	/*
 	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/bus.c linux-libre-2.6.33-gnu1/drivers/acpi/bus.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -344,6 +344,167 @@ bool acpi_bus_can_wakeup(acpi_handle han
 
 EXPORT_SYMBOL(acpi_bus_can_wakeup);
 
+static void acpi_print_osc_error(acpi_handle handle,
+	struct acpi_osc_context *context, char *error)
+{
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER};
+	int i;
+
+	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))
+		printk(KERN_DEBUG "%s\n", error);
+	else {
+		printk(KERN_DEBUG "%s:%s\n", (char *)buffer.pointer, error);
+		kfree(buffer.pointer);
+	}
+	printk(KERN_DEBUG"_OSC request data:");
+	for (i = 0; i < context->cap.length; i += sizeof(u32))
+		printk("%x ", *((u32 *)(context->cap.pointer + i)));
+	printk("\n");
+}
+
+static u8 hex_val(unsigned char c)
+{
+	return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
+}
+
+static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
+{
+	int i;
+	static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
+		24, 26, 28, 30, 32, 34};
+
+	if (strlen(str) != 36)
+		return AE_BAD_PARAMETER;
+	for (i = 0; i < 36; i++) {
+		if (i == 8 || i == 13 || i == 18 || i == 23) {
+			if (str[i] != '-')
+				return AE_BAD_PARAMETER;
+		} else if (!isxdigit(str[i]))
+			return AE_BAD_PARAMETER;
+	}
+	for (i = 0; i < 16; i++) {
+		uuid[i] = hex_val(str[opc_map_to_uuid[i]]) << 4;
+		uuid[i] |= hex_val(str[opc_map_to_uuid[i] + 1]);
+	}
+	return AE_OK;
+}
+
+acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
+{
+	acpi_status status;
+	struct acpi_object_list input;
+	union acpi_object in_params[4];
+	union acpi_object *out_obj;
+	u8 uuid[16];
+	u32 errors;
+	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+
+	if (!context)
+		return AE_ERROR;
+	if (ACPI_FAILURE(acpi_str_to_uuid(context->uuid_str, uuid)))
+		return AE_ERROR;
+	context->ret.length = ACPI_ALLOCATE_BUFFER;
+	context->ret.pointer = NULL;
+
+	/* Setting up input parameters */
+	input.count = 4;
+	input.pointer = in_params;
+	in_params[0].type 		= ACPI_TYPE_BUFFER;
+	in_params[0].buffer.length 	= 16;
+	in_params[0].buffer.pointer	= uuid;
+	in_params[1].type 		= ACPI_TYPE_INTEGER;
+	in_params[1].integer.value 	= context->rev;
+	in_params[2].type 		= ACPI_TYPE_INTEGER;
+	in_params[2].integer.value	= context->cap.length/sizeof(u32);
+	in_params[3].type		= ACPI_TYPE_BUFFER;
+	in_params[3].buffer.length 	= context->cap.length;
+	in_params[3].buffer.pointer 	= context->cap.pointer;
+
+	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	if (!output.length)
+		return AE_NULL_OBJECT;
+
+	out_obj = output.pointer;
+	if (out_obj->type != ACPI_TYPE_BUFFER
+		|| out_obj->buffer.length != context->cap.length) {
+		acpi_print_osc_error(handle, context,
+			"_OSC evaluation returned wrong type");
+		status = AE_TYPE;
+		goto out_kfree;
+	}
+	/* Need to ignore the bit0 in result code */
+	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+	if (errors) {
+		if (errors & OSC_REQUEST_ERROR)
+			acpi_print_osc_error(handle, context,
+				"_OSC request failed");
+		if (errors & OSC_INVALID_UUID_ERROR)
+			acpi_print_osc_error(handle, context,
+				"_OSC invalid UUID");
+		if (errors & OSC_INVALID_REVISION_ERROR)
+			acpi_print_osc_error(handle, context,
+				"_OSC invalid revision");
+		if (errors & OSC_CAPABILITIES_MASK_ERROR) {
+			if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE]
+			    & OSC_QUERY_ENABLE)
+				goto out_success;
+			status = AE_SUPPORT;
+			goto out_kfree;
+		}
+		status = AE_ERROR;
+		goto out_kfree;
+	}
+out_success:
+	context->ret.length = out_obj->buffer.length;
+	context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL);
+	if (!context->ret.pointer) {
+		status =  AE_NO_MEMORY;
+		goto out_kfree;
+	}
+	memcpy(context->ret.pointer, out_obj->buffer.pointer,
+		context->ret.length);
+	status =  AE_OK;
+
+out_kfree:
+	kfree(output.pointer);
+	if (status != AE_OK)
+		context->ret.pointer = NULL;
+	return status;
+}
+EXPORT_SYMBOL(acpi_run_osc);
+
+static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+static void acpi_bus_osc_support(void)
+{
+	u32 capbuf[2];
+	struct acpi_osc_context context = {
+		.uuid_str = sb_uuid_str,
+		.rev = 1,
+		.cap.length = 8,
+		.cap.pointer = capbuf,
+	};
+	acpi_handle handle;
+
+	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+	capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
+#if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\
+			defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
+	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
+#endif
+
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
+#endif
+	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
+		return;
+	if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
+		kfree(context.ret.pointer);
+	/* do we need to check the returned cap? Sounds no */
+}
+
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
@@ -734,12 +895,16 @@ static int __init acpi_bus_init(void)
 	status = acpi_ec_ecdt_probe();
 	/* Ignore result. Not having an ECDT is not fatal. */
 
+	acpi_bus_osc_support();
+
 	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
 	if (ACPI_FAILURE(status)) {
 		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
 		goto error1;
 	}
 
+	acpi_early_processor_set_pdc();
+
 	/*
 	 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
 	 * is necessary to enable it as early as possible.
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/button.c linux-libre-2.6.33-gnu1/drivers/acpi/button.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/button.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/button.c	2010-02-24 13:52:17.000000000 -0500
@@ -282,6 +282,13 @@ static int acpi_lid_send_state(struct ac
 	if (ret == NOTIFY_DONE)
 		ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
 						   device);
+	if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
+		/*
+		 * It is also regarded as success if the notifier_chain
+		 * returns NOTIFY_OK or NOTIFY_DONE.
+		 */
+		ret = 0;
+	}
 	return ret;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/container.c linux-libre-2.6.33-gnu1/drivers/acpi/container.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/container.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/container.c	2010-02-24 13:52:17.000000000 -0500
@@ -258,7 +258,7 @@ static int __init acpi_container_init(vo
 	acpi_walk_namespace(ACPI_TYPE_DEVICE,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    container_walk_namespace_cb, &action, NULL);
+			    container_walk_namespace_cb, NULL, &action, NULL);
 
 	return (0);
 }
@@ -271,7 +271,7 @@ static void __exit acpi_container_exit(v
 	acpi_walk_namespace(ACPI_TYPE_DEVICE,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    container_walk_namespace_cb, &action, NULL);
+			    container_walk_namespace_cb, NULL, &action, NULL);
 
 	acpi_bus_unregister_driver(&acpi_container_driver);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/debug.c linux-libre-2.6.33-gnu1/drivers/acpi/debug.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
+#include <linux/debugfs.h>
 #include <asm/uaccess.h>
 #include <acpi/acpi_drivers.h>
 
@@ -196,6 +197,80 @@ module_param_call(trace_state, param_set
 		  NULL, 0644);
 
 /* --------------------------------------------------------------------------
+				DebugFS Interface
+   -------------------------------------------------------------------------- */
+
+static ssize_t cm_write(struct file *file, const char __user *user_buf,
+			size_t count, loff_t *ppos)
+{
+	static char *buf;
+	static int uncopied_bytes;
+	struct acpi_table_header table;
+	acpi_status status;
+
+	if (!(*ppos)) {
+		/* parse the table header to get the table length */
+		if (count <= sizeof(struct acpi_table_header))
+			return -EINVAL;
+		if (copy_from_user(&table, user_buf,
+			sizeof(struct acpi_table_header)))
+			return -EFAULT;
+		uncopied_bytes = table.length;
+		buf = kzalloc(uncopied_bytes, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
+	}
+
+	if (uncopied_bytes < count) {
+		kfree(buf);
+		return -EINVAL;
+	}
+
+	if (copy_from_user(buf + (*ppos), user_buf, count)) {
+		kfree(buf);
+		return -EFAULT;
+	}
+
+	uncopied_bytes -= count;
+	*ppos += count;
+
+	if (!uncopied_bytes) {
+		status = acpi_install_method(buf);
+		kfree(buf);
+		if (ACPI_FAILURE(status))
+			return -EINVAL;
+		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
+	}
+
+	return count;
+}
+
+static const struct file_operations cm_fops = {
+	.write = cm_write,
+};
+
+static int acpi_debugfs_init(void)
+{
+	struct dentry *acpi_dir, *cm_dentry;
+
+	acpi_dir = debugfs_create_dir("acpi", NULL);
+	if (!acpi_dir)
+		goto err;
+
+	cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
+					acpi_dir, NULL, &cm_fops);
+	if (!cm_dentry)
+		goto err;
+
+	return 0;
+
+err:
+	if (acpi_dir)
+		debugfs_remove(acpi_dir);
+	return -EINVAL;
+}
+
+/* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 #ifdef CONFIG_ACPI_PROCFS
@@ -286,7 +361,7 @@ static const struct file_operations acpi
 };
 #endif
 
-int __init acpi_debug_init(void)
+int __init acpi_procfs_init(void)
 {
 #ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *entry;
@@ -321,3 +396,10 @@ int __init acpi_debug_init(void)
 	return 0;
 #endif
 }
+
+int __init acpi_debug_init(void)
+{
+	acpi_debugfs_init();
+	acpi_procfs_init();
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/dock.c linux-libre-2.6.33-gnu1/drivers/acpi/dock.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/dock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/dock.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (d
 	" before undocking");
 
 static struct atomic_notifier_head dock_notifier_list;
-static char dock_device_name[] = "dock";
 
 static const struct acpi_device_id dock_device_ids[] = {
 	{"LNXDOCK", 0},
@@ -93,40 +92,30 @@ struct dock_dependent_device {
  *                         Dock Dependent device functions                   *
  *****************************************************************************/
 /**
- *  alloc_dock_dependent_device - allocate and init a dependent device
- *  @handle: the acpi_handle of the dependent device
+ * add_dock_dependent_device - associate a device with the dock station
+ * @ds: The dock station
+ * @handle: handle of the dependent device
  *
- *  Allocate memory for a dependent device structure for a device referenced
- *  by the acpi handle
+ * Add the dependent device to the dock's dependent device list.
  */
-static struct dock_dependent_device *
-alloc_dock_dependent_device(acpi_handle handle)
+static int
+add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
 {
 	struct dock_dependent_device *dd;
 
 	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
-	if (dd) {
-		dd->handle = handle;
-		INIT_LIST_HEAD(&dd->list);
-		INIT_LIST_HEAD(&dd->hotplug_list);
-	}
-	return dd;
-}
+	if (!dd)
+		return -ENOMEM;
+
+	dd->handle = handle;
+	INIT_LIST_HEAD(&dd->list);
+	INIT_LIST_HEAD(&dd->hotplug_list);
 
-/**
- * add_dock_dependent_device - associate a device with the dock station
- * @ds: The dock station
- * @dd: The dependent device
- *
- * Add the dependent device to the dock's dependent device list.
- */
-static void
-add_dock_dependent_device(struct dock_station *ds,
-			  struct dock_dependent_device *dd)
-{
 	spin_lock(&ds->dd_lock);
 	list_add_tail(&dd->list, &ds->dependent_devices);
 	spin_unlock(&ds->dd_lock);
+
+	return 0;
 }
 
 /**
@@ -249,6 +238,7 @@ static int is_battery(acpi_handle handle
 static int is_ejectable_bay(acpi_handle handle)
 {
 	acpi_handle phandle;
+
 	if (!is_ejectable(handle))
 		return 0;
 	if (is_battery(handle) || is_ata(handle))
@@ -275,14 +265,13 @@ int is_dock_device(acpi_handle handle)
 
 	if (is_dock(handle))
 		return 1;
-	list_for_each_entry(dock_station, &dock_stations, sibling) {
+
+	list_for_each_entry(dock_station, &dock_stations, sibling)
 		if (find_dock_dependent_device(dock_station, handle))
 			return 1;
-	}
 
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(is_dock_device);
 
 /**
@@ -305,8 +294,6 @@ static int dock_present(struct dock_stat
 	return 0;
 }
 
-
-
 /**
  * dock_create_acpi_device - add new devices to acpi
  * @handle - handle of the device to add
@@ -320,7 +307,7 @@ static int dock_present(struct dock_stat
  */
 static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
 {
-	struct acpi_device *device = NULL;
+	struct acpi_device *device;
 	struct acpi_device *parent_device;
 	acpi_handle parent;
 	int ret;
@@ -337,8 +324,7 @@ static struct acpi_device * dock_create_
 		ret = acpi_bus_add(&device, parent_device, handle,
 			ACPI_BUS_TYPE_DEVICE);
 		if (ret) {
-			pr_debug("error adding bus, %x\n",
-				-ret);
+			pr_debug("error adding bus, %x\n", -ret);
 			return NULL;
 		}
 	}
@@ -364,7 +350,6 @@ static void dock_remove_acpi_device(acpi
 	}
 }
 
-
 /**
  * hotplug_dock_devices - insert or remove devices on the dock station
  * @ds: the dock station
@@ -384,10 +369,9 @@ static void hotplug_dock_devices(struct
 	/*
 	 * First call driver specific hotplug functions
 	 */
-	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
+	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
 		if (dd->ops && dd->ops->handler)
 			dd->ops->handler(dd->handle, event, dd->context);
-	}
 
 	/*
 	 * Now make sure that an acpi_device is created for each
@@ -426,6 +410,7 @@ static void dock_event(struct dock_stati
 	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
 		if (dd->ops && dd->ops->uevent)
 			dd->ops->uevent(dd->handle, event, dd->context);
+
 	if (num != DOCK_EVENT)
 		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 }
@@ -456,8 +441,8 @@ static void eject_dock(struct dock_stati
 	arg.type = ACPI_TYPE_INTEGER;
 	arg.integer.value = 1;
 
-	if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
-					      &arg_list, NULL)))
+	status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL);
+	if (ACPI_FAILURE(status))
 		pr_debug("Failed to evaluate _EJ0!\n");
 }
 
@@ -577,7 +562,6 @@ int register_dock_notifier(struct notifi
 
 	return atomic_notifier_chain_register(&dock_notifier_list, nb);
 }
-
 EXPORT_SYMBOL_GPL(register_dock_notifier);
 
 /**
@@ -591,7 +575,6 @@ void unregister_dock_notifier(struct not
 
 	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
 }
-
 EXPORT_SYMBOL_GPL(unregister_dock_notifier);
 
 /**
@@ -636,7 +619,6 @@ register_hotplug_dock_device(acpi_handle
 
 	return ret;
 }
-
 EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
 
 /**
@@ -657,7 +639,6 @@ void unregister_hotplug_dock_device(acpi
 			dock_del_hotplug_device(dock_station, dd);
 	}
 }
-
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
 
 /**
@@ -772,7 +753,7 @@ struct dock_data {
 
 static void acpi_dock_deferred_cb(void *context)
 {
-	struct dock_data *data = (struct dock_data *)context;
+	struct dock_data *data = context;
 
 	dock_notify(data->handle, data->event, data->ds);
 	kfree(data);
@@ -782,23 +763,22 @@ static int acpi_dock_notifier_call(struc
 	unsigned long event, void *data)
 {
 	struct dock_station *dock_station;
-	acpi_handle handle = (acpi_handle)data;
+	acpi_handle handle = data;
 
 	if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
 	   && event != ACPI_NOTIFY_EJECT_REQUEST)
 		return 0;
 	list_for_each_entry(dock_station, &dock_stations, sibling) {
 		if (dock_station->handle == handle) {
-			struct dock_data *dock_data;
+			struct dock_data *dd;
 
-			dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL);
-			if (!dock_data)
+			dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+			if (!dd)
 				return 0;
-			dock_data->handle = handle;
-			dock_data->event = event;
-			dock_data->ds = dock_station;
-			acpi_os_hotplug_execute(acpi_dock_deferred_cb,
-				dock_data);
+			dd->handle = handle;
+			dd->event = event;
+			dd->ds = dock_station;
+			acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
 			return 0 ;
 		}
 	}
@@ -826,7 +806,6 @@ find_dock_devices(acpi_handle handle, u3
 	acpi_status status;
 	acpi_handle tmp, parent;
 	struct dock_station *ds = context;
-	struct dock_dependent_device *dd;
 
 	status = acpi_bus_get_ejd(handle, &tmp);
 	if (ACPI_FAILURE(status)) {
@@ -840,11 +819,9 @@ find_dock_devices(acpi_handle handle, u3
 			goto fdd_out;
 	}
 
-	if (tmp == ds->handle) {
-		dd = alloc_dock_dependent_device(handle);
-		if (dd)
-			add_dock_dependent_device(ds, dd);
-	}
+	if (tmp == ds->handle)
+		add_dock_dependent_device(ds, handle);
+
 fdd_out:
 	return AE_OK;
 }
@@ -857,8 +834,7 @@ static ssize_t show_docked(struct device
 {
 	struct acpi_device *tmp;
 
-	struct dock_station *dock_station = *((struct dock_station **)
-		dev->platform_data);
+	struct dock_station *dock_station = dev->platform_data;
 
 	if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
 		return snprintf(buf, PAGE_SIZE, "1\n");
@@ -872,8 +848,7 @@ static DEVICE_ATTR(docked, S_IRUGO, show
 static ssize_t show_flags(struct device *dev,
 			  struct device_attribute *attr, char *buf)
 {
-	struct dock_station *dock_station = *((struct dock_station **)
-		dev->platform_data);
+	struct dock_station *dock_station = dev->platform_data;
 	return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
 
 }
@@ -886,8 +861,7 @@ static ssize_t write_undock(struct devic
 			   const char *buf, size_t count)
 {
 	int ret;
-	struct dock_station *dock_station = *((struct dock_station **)
-		dev->platform_data);
+	struct dock_station *dock_station = dev->platform_data;
 
 	if (!count)
 		return -EINVAL;
@@ -905,8 +879,7 @@ static ssize_t show_dock_uid(struct devi
 			     struct device_attribute *attr, char *buf)
 {
 	unsigned long long lbuf;
-	struct dock_station *dock_station = *((struct dock_station **)
-		dev->platform_data);
+	struct dock_station *dock_station = dev->platform_data;
 	acpi_status status = acpi_evaluate_integer(dock_station->handle,
 					"_UID", NULL, &lbuf);
 	if (ACPI_FAILURE(status))
@@ -919,8 +892,7 @@ static DEVICE_ATTR(uid, S_IRUGO, show_do
 static ssize_t show_dock_type(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct dock_station *dock_station = *((struct dock_station **)
-		dev->platform_data);
+	struct dock_station *dock_station = dev->platform_data;
 	char *type;
 
 	if (dock_station->flags & DOCK_IS_DOCK)
@@ -936,6 +908,19 @@ static ssize_t show_dock_type(struct dev
 }
 static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
 
+static struct attribute *dock_attributes[] = {
+	&dev_attr_docked.attr,
+	&dev_attr_flags.attr,
+	&dev_attr_undock.attr,
+	&dev_attr_uid.attr,
+	&dev_attr_type.attr,
+	NULL
+};
+
+static struct attribute_group dock_attribute_group = {
+	.attrs = dock_attributes
+};
+
 /**
  * dock_add - add a new dock station
  * @handle: the dock station handle
@@ -945,39 +930,31 @@ static DEVICE_ATTR(type, S_IRUGO, show_d
  */
 static int dock_add(acpi_handle handle)
 {
-	int ret;
-	struct dock_dependent_device *dd;
-	struct dock_station *dock_station;
-	struct platform_device *dock_device;
+	int ret, id;
+	struct dock_station ds, *dock_station;
+	struct platform_device *dd;
+
+	id = dock_station_count;
+	memset(&ds, 0, sizeof(ds));
+	dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
+	if (IS_ERR(dd))
+		return PTR_ERR(dd);
+
+	dock_station = dd->dev.platform_data;
 
-	/* allocate & initialize the dock_station private data */
-	dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
-	if (!dock_station)
-		return -ENOMEM;
 	dock_station->handle = handle;
+	dock_station->dock_device = dd;
 	dock_station->last_dock_time = jiffies - HZ;
-	INIT_LIST_HEAD(&dock_station->dependent_devices);
-	INIT_LIST_HEAD(&dock_station->hotplug_devices);
-	INIT_LIST_HEAD(&dock_station->sibling);
-	spin_lock_init(&dock_station->dd_lock);
+
 	mutex_init(&dock_station->hp_lock);
+	spin_lock_init(&dock_station->dd_lock);
+	INIT_LIST_HEAD(&dock_station->sibling);
+	INIT_LIST_HEAD(&dock_station->hotplug_devices);
 	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
-
-	/* initialize platform device stuff */
-	dock_station->dock_device =
-		platform_device_register_simple(dock_device_name,
-			dock_station_count, NULL, 0);
-	dock_device = dock_station->dock_device;
-	if (IS_ERR(dock_device)) {
-		kfree(dock_station);
-		dock_station = NULL;
-		return PTR_ERR(dock_device);
-	}
-	platform_device_add_data(dock_device, &dock_station,
-		sizeof(struct dock_station *));
+	INIT_LIST_HEAD(&dock_station->dependent_devices);
 
 	/* we want the dock device to send uevents */
-	dev_set_uevent_suppress(&dock_device->dev, 0);
+	dev_set_uevent_suppress(&dd->dev, 0);
 
 	if (is_dock(handle))
 		dock_station->flags |= DOCK_IS_DOCK;
@@ -986,106 +963,53 @@ static int dock_add(acpi_handle handle)
 	if (is_battery(handle))
 		dock_station->flags |= DOCK_IS_BAT;
 
-	ret = device_create_file(&dock_device->dev, &dev_attr_docked);
-	if (ret) {
-		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
-		platform_device_unregister(dock_device);
-		kfree(dock_station);
-		dock_station = NULL;
-		return ret;
-	}
-	ret = device_create_file(&dock_device->dev, &dev_attr_undock);
-	if (ret) {
-		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
-		device_remove_file(&dock_device->dev, &dev_attr_docked);
-		platform_device_unregister(dock_device);
-		kfree(dock_station);
-		dock_station = NULL;
-		return ret;
-	}
-	ret = device_create_file(&dock_device->dev, &dev_attr_uid);
-	if (ret) {
-		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
-		device_remove_file(&dock_device->dev, &dev_attr_docked);
-		device_remove_file(&dock_device->dev, &dev_attr_undock);
-		platform_device_unregister(dock_device);
-		kfree(dock_station);
-		dock_station = NULL;
-		return ret;
-	}
-	ret = device_create_file(&dock_device->dev, &dev_attr_flags);
-	if (ret) {
-		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
-		device_remove_file(&dock_device->dev, &dev_attr_docked);
-		device_remove_file(&dock_device->dev, &dev_attr_undock);
-		device_remove_file(&dock_device->dev, &dev_attr_uid);
-		platform_device_unregister(dock_device);
-		kfree(dock_station);
-		dock_station = NULL;
-		return ret;
-	}
-	ret = device_create_file(&dock_device->dev, &dev_attr_type);
+	ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
 	if (ret)
-		printk(KERN_ERR"Error %d adding sysfs file\n", ret);
+		goto err_unregister;
 
 	/* Find dependent devices */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX, find_dock_devices, dock_station,
-			    NULL);
+			    ACPI_UINT32_MAX, find_dock_devices, NULL,
+			    dock_station, NULL);
 
 	/* add the dock station as a device dependent on itself */
-	dd = alloc_dock_dependent_device(handle);
-	if (!dd) {
-		kfree(dock_station);
-		dock_station = NULL;
-		ret = -ENOMEM;
-		goto dock_add_err_unregister;
-	}
-	add_dock_dependent_device(dock_station, dd);
+	ret = add_dock_dependent_device(dock_station, handle);
+	if (ret)
+		goto err_rmgroup;
 
 	dock_station_count++;
 	list_add(&dock_station->sibling, &dock_stations);
 	return 0;
 
-dock_add_err_unregister:
-	device_remove_file(&dock_device->dev, &dev_attr_type);
-	device_remove_file(&dock_device->dev, &dev_attr_docked);
-	device_remove_file(&dock_device->dev, &dev_attr_undock);
-	device_remove_file(&dock_device->dev, &dev_attr_uid);
-	device_remove_file(&dock_device->dev, &dev_attr_flags);
-	platform_device_unregister(dock_device);
-	kfree(dock_station);
-	dock_station = NULL;
+err_rmgroup:
+	sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
+err_unregister:
+	platform_device_unregister(dd);
+	printk(KERN_ERR "%s encountered error %d\n", __func__, ret);
 	return ret;
 }
 
 /**
  * dock_remove - free up resources related to the dock station
  */
-static int dock_remove(struct dock_station *dock_station)
+static int dock_remove(struct dock_station *ds)
 {
 	struct dock_dependent_device *dd, *tmp;
-	struct platform_device *dock_device = dock_station->dock_device;
+	struct platform_device *dock_device = ds->dock_device;
 
 	if (!dock_station_count)
 		return 0;
 
 	/* remove dependent devices */
-	list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices,
-				 list)
-	    kfree(dd);
+	list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list)
+		kfree(dd);
+
+	list_del(&ds->sibling);
 
 	/* cleanup sysfs */
-	device_remove_file(&dock_device->dev, &dev_attr_type);
-	device_remove_file(&dock_device->dev, &dev_attr_docked);
-	device_remove_file(&dock_device->dev, &dev_attr_undock);
-	device_remove_file(&dock_device->dev, &dev_attr_uid);
-	device_remove_file(&dock_device->dev, &dev_attr_flags);
+	sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group);
 	platform_device_unregister(dock_device);
 
-	/* free dock station memory */
-	kfree(dock_station);
-	dock_station = NULL;
 	return 0;
 }
 
@@ -1103,11 +1027,10 @@ find_dock(acpi_handle handle, u32 lvl, v
 {
 	acpi_status status = AE_OK;
 
-	if (is_dock(handle)) {
-		if (dock_add(handle) >= 0) {
+	if (is_dock(handle))
+		if (dock_add(handle) >= 0)
 			status = AE_CTRL_TERMINATE;
-		}
-	}
+
 	return status;
 }
 
@@ -1127,11 +1050,11 @@ static int __init dock_init(void)
 
 	/* look for a dock station */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX, find_dock, NULL, NULL);
+			    ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL);
 
 	/* look for bay */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_bay, NULL, NULL);
+			ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL);
 	if (!dock_station_count) {
 		printk(KERN_INFO PREFIX "No dock devices found.\n");
 		return 0;
@@ -1145,8 +1068,7 @@ static int __init dock_init(void)
 
 static void __exit dock_exit(void)
 {
-	struct dock_station *dock_station;
-	struct dock_station *tmp;
+	struct dock_station *tmp, *dock_station;
 
 	unregister_acpi_bus_notifier(&dock_acpi_notifier);
 	list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/ec.c linux-libre-2.6.33-gnu1/drivers/acpi/ec.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/ec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/ec.c	2010-02-24 13:52:17.000000000 -0500
@@ -201,14 +201,13 @@ unlock:
 	spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static void acpi_ec_gpe_query(void *ec_cxt);
+static int acpi_ec_sync_query(struct acpi_ec *ec);
 
-static int ec_check_sci(struct acpi_ec *ec, u8 state)
+static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 {
 	if (state & ACPI_EC_FLAG_SCI) {
 		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-			return acpi_os_execute(OSL_EC_BURST_HANDLER,
-				acpi_ec_gpe_query, ec);
+			return acpi_ec_sync_query(ec);
 	}
 	return 0;
 }
@@ -249,11 +248,6 @@ static int acpi_ec_transaction_unlocked(
 {
 	unsigned long tmp;
 	int ret = 0;
-	pr_debug(PREFIX "transaction start\n");
-	/* disable GPE during transaction if storm is detected */
-	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		acpi_disable_gpe(NULL, ec->gpe);
-	}
 	if (EC_FLAGS_MSI)
 		udelay(ACPI_EC_MSI_UDELAY);
 	/* start transaction */
@@ -265,20 +259,9 @@ static int acpi_ec_transaction_unlocked(
 		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
 	ret = ec_poll(ec);
-	pr_debug(PREFIX "transaction end\n");
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	ec->curr = NULL;
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
-	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		/* check if we received SCI during transaction */
-		ec_check_sci(ec, acpi_ec_read_status(ec));
-		/* it is safe to enable GPE outside of transaction */
-		acpi_enable_gpe(NULL, ec->gpe);
-	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
-		pr_info(PREFIX "GPE storm detected, "
-			"transactions will use polling mode\n");
-		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
-	}
 	return ret;
 }
 
@@ -321,7 +304,26 @@ static int acpi_ec_transaction(struct ac
 		status = -ETIME;
 		goto end;
 	}
+	pr_debug(PREFIX "transaction start\n");
+	/* disable GPE during transaction if storm is detected */
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		acpi_disable_gpe(NULL, ec->gpe);
+	}
+
 	status = acpi_ec_transaction_unlocked(ec, t);
+
+	/* check if we received SCI during transaction */
+	ec_check_sci_sync(ec, acpi_ec_read_status(ec));
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		msleep(1);
+		/* it is safe to enable GPE outside of transaction */
+		acpi_enable_gpe(NULL, ec->gpe);
+	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+		pr_info(PREFIX "GPE storm detected, "
+			"transactions will use polling mode\n");
+		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+	}
+	pr_debug(PREFIX "transaction end\n");
 end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
@@ -443,7 +445,7 @@ int ec_transaction(u8 command,
 
 EXPORT_SYMBOL(ec_transaction);
 
-static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
 {
 	int result;
 	u8 d;
@@ -452,20 +454,16 @@ static int acpi_ec_query(struct acpi_ec
 				.wlen = 0, .rlen = 1};
 	if (!ec || !data)
 		return -EINVAL;
-
 	/*
 	 * Query the EC to find out which _Qxx method we need to evaluate.
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
-
-	result = acpi_ec_transaction(ec, &t);
+	result = acpi_ec_transaction_unlocked(ec, &t);
 	if (result)
 		return result;
-
 	if (!d)
 		return -ENODATA;
-
 	*data = d;
 	return 0;
 }
@@ -509,43 +507,79 @@ void acpi_ec_remove_query_handler(struct
 
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
-static void acpi_ec_gpe_query(void *ec_cxt)
+static void acpi_ec_run(void *cxt)
 {
-	struct acpi_ec *ec = ec_cxt;
-	u8 value = 0;
-	struct acpi_ec_query_handler *handler, copy;
-
-	if (!ec || acpi_ec_query(ec, &value))
+	struct acpi_ec_query_handler *handler = cxt;
+	if (!handler)
 		return;
-	mutex_lock(&ec->lock);
+	pr_debug(PREFIX "start query execution\n");
+	if (handler->func)
+		handler->func(handler->data);
+	else if (handler->handle)
+		acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
+	pr_debug(PREFIX "stop query execution\n");
+	kfree(handler);
+}
+
+static int acpi_ec_sync_query(struct acpi_ec *ec)
+{
+	u8 value = 0;
+	int status;
+	struct acpi_ec_query_handler *handler, *copy;
+	if ((status = acpi_ec_query_unlocked(ec, &value)))
+		return status;
 	list_for_each_entry(handler, &ec->list, node) {
 		if (value == handler->query_bit) {
 			/* have custom handler for this bit */
-			memcpy(&copy, handler, sizeof(copy));
-			mutex_unlock(&ec->lock);
-			if (copy.func) {
-				copy.func(copy.data);
-			} else if (copy.handle) {
-				acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
-			}
-			return;
+			copy = kmalloc(sizeof(*handler), GFP_KERNEL);
+			if (!copy)
+				return -ENOMEM;
+			memcpy(copy, handler, sizeof(*copy));
+			pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
+			return acpi_os_execute((copy->func) ?
+				OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER,
+				acpi_ec_run, copy);
 		}
 	}
+	return 0;
+}
+
+static void acpi_ec_gpe_query(void *ec_cxt)
+{
+	struct acpi_ec *ec = ec_cxt;
+	if (!ec)
+		return;
+	mutex_lock(&ec->lock);
+	acpi_ec_sync_query(ec);
 	mutex_unlock(&ec->lock);
 }
 
+static void acpi_ec_gpe_query(void *ec_cxt);
+
+static int ec_check_sci(struct acpi_ec *ec, u8 state)
+{
+	if (state & ACPI_EC_FLAG_SCI) {
+		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+			pr_debug(PREFIX "push gpe query to the queue\n");
+			return acpi_os_execute(OSL_NOTIFY_HANDLER,
+				acpi_ec_gpe_query, ec);
+		}
+	}
+	return 0;
+}
+
 static u32 acpi_ec_gpe_handler(void *data)
 {
 	struct acpi_ec *ec = data;
-	u8 status;
 
 	pr_debug(PREFIX "~~~> interrupt\n");
-	status = acpi_ec_read_status(ec);
 
-	advance_transaction(ec, status);
-	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+	advance_transaction(ec, acpi_ec_read_status(ec));
+	if (ec_transaction_done(ec) &&
+	    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
 		wake_up(&ec->wait);
-	ec_check_sci(ec, status);
+		ec_check_sci(ec, acpi_ec_read_status(ec));
+	}
 	return ACPI_INTERRUPT_HANDLED;
 }
 
@@ -820,7 +854,7 @@ static int acpi_ec_add(struct acpi_devic
 
 	/* Find and register all query methods */
 	acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
-			    acpi_ec_register_query_methods, ec, NULL);
+			    acpi_ec_register_query_methods, NULL, ec, NULL);
 
 	if (!first_ec)
 		first_ec = ec;
@@ -916,6 +950,7 @@ static int ec_validate_ecdt(const struct
 /* MSI EC needs special treatment, enable it */
 static int ec_flag_msi(const struct dmi_system_id *id)
 {
+	printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n");
 	EC_FLAGS_MSI = 1;
 	EC_FLAGS_VALIDATE_ECDT = 1;
 	return 0;
@@ -928,8 +963,13 @@ static struct dmi_system_id __initdata e
 	DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
 	{
 	ec_flag_msi, "MSI hardware", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
-	DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
+	DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL},
+	{
+	ec_flag_msi, "MSI hardware", {
+	DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL},
+	{
+	ec_flag_msi, "MSI hardware", {
+	DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
 	{
 	ec_validate_ecdt, "ASUS hardware", {
 	DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/fan.c linux-libre-2.6.33-gnu1/drivers/acpi/fan.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/fan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/fan.c	2010-02-24 13:52:17.000000000 -0500
@@ -267,7 +267,7 @@ static int acpi_fan_add(struct acpi_devi
 		goto end;
 	}
 
-	dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id);
+	dev_dbg(&device->dev, "registered as cooling_device%d\n", cdev->id);
 
 	device->driver_data = cdev;
 	result = sysfs_create_link(&device->dev.kobj,
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/glue.c linux-libre-2.6.33-gnu1/drivers/acpi/glue.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/glue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/glue.c	2010-02-24 13:52:17.000000000 -0500
@@ -113,7 +113,7 @@ acpi_handle acpi_get_child(acpi_handle p
 	if (!parent)
 		return NULL;
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
-			    1, do_acpi_find_child, &find, NULL);
+			    1, do_acpi_find_child, NULL, &find, NULL);
 	return find.handle;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/hest.c linux-libre-2.6.33-gnu1/drivers/acpi/hest.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/hest.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/hest.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,135 @@
+#include <linux/acpi.h>
+#include <linux/pci.h>
+
+#define PREFIX "ACPI: "
+
+static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p)
+{
+	return sizeof(*p) +
+		(sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
+}
+
+static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p)
+{
+	return sizeof(*p) +
+		(sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks);
+}
+
+static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p)
+{
+	return sizeof(*p);
+}
+
+static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p)
+{
+	return sizeof(*p);
+}
+
+static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci)
+{
+	return	(0           == pci_domain_nr(pci->bus) &&
+		 p->bus      == pci->bus->number &&
+		 p->device   == PCI_SLOT(pci->devfn) &&
+		 p->function == PCI_FUNC(pci->devfn));
+}
+
+static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first)
+{
+	struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header);
+	unsigned long rc=0;
+	u8 pcie_type = 0;
+	u8 bridge = 0;
+	switch (type) {
+	case ACPI_HEST_TYPE_AER_ROOT_PORT:
+		rc = sizeof(struct acpi_hest_aer_root);
+		pcie_type = PCI_EXP_TYPE_ROOT_PORT;
+		break;
+	case ACPI_HEST_TYPE_AER_ENDPOINT:
+		rc = sizeof(struct acpi_hest_aer);
+		pcie_type = PCI_EXP_TYPE_ENDPOINT;
+		break;
+	case ACPI_HEST_TYPE_AER_BRIDGE:
+		rc = sizeof(struct acpi_hest_aer_bridge);
+		if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+			bridge = 1;
+		break;
+	}
+
+	if (p->flags & ACPI_HEST_GLOBAL) {
+		if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge)
+			*firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+	}
+	else
+		if (hest_match_pci(p, pci))
+			*firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+	return rc;
+}
+
+static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci)
+{
+	struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader;
+	void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */
+	struct acpi_hest_header *hdr = p;
+
+	int i;
+	int firmware_first = 0;
+	static unsigned char printed_unused = 0;
+	static unsigned char printed_reserved = 0;
+
+	for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) {
+		switch (hdr->type) {
+		case ACPI_HEST_TYPE_IA32_CHECK:
+			p += parse_acpi_hest_ia_machine_check(p);
+			break;
+		case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
+			p += parse_acpi_hest_ia_corrected(p);
+			break;
+		case ACPI_HEST_TYPE_IA32_NMI:
+			p += parse_acpi_hest_ia_nmi(p);
+			break;
+		/* These three should never appear */
+		case ACPI_HEST_TYPE_NOT_USED3:
+		case ACPI_HEST_TYPE_NOT_USED4:
+		case ACPI_HEST_TYPE_NOT_USED5:
+			if (!printed_unused) {
+				printk(KERN_DEBUG PREFIX
+				       "HEST Error Source list contains an obsolete type (%d).\n", hdr->type);
+				printed_unused = 1;
+			}
+			break;
+		case ACPI_HEST_TYPE_AER_ROOT_PORT:
+		case ACPI_HEST_TYPE_AER_ENDPOINT:
+		case ACPI_HEST_TYPE_AER_BRIDGE:
+			p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first);
+			break;
+		case ACPI_HEST_TYPE_GENERIC_ERROR:
+			p += parse_acpi_hest_generic(p);
+			break;
+		/* These should never appear either */
+		case ACPI_HEST_TYPE_RESERVED:
+		default:
+			if (!printed_reserved) {
+				printk(KERN_DEBUG PREFIX
+				       "HEST Error Source list contains a reserved type (%d).\n", hdr->type);
+				printed_reserved = 1;
+			}
+			break;
+		}
+	}
+	return firmware_first;
+}
+
+int acpi_hest_firmware_first_pci(struct pci_dev *pci)
+{
+	acpi_status status = AE_NOT_FOUND;
+	struct acpi_table_header *hest = NULL;
+	status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
+
+	if (ACPI_SUCCESS(status)) {
+		if (acpi_hest_firmware_first(hest, pci)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci);
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/internal.h linux-libre-2.6.33-gnu1/drivers/acpi/internal.h
--- linux-libre-2.6.32-gnu1/drivers/acpi/internal.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/internal.h	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,7 @@ int acpi_power_transition(struct acpi_de
 extern int acpi_power_nocheck;
 
 int acpi_wakeup_device_init(void);
+void acpi_early_processor_set_pdc(void);
 
 /* --------------------------------------------------------------------------
                                   Embedded Controller
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/Makefile linux-libre-2.6.33-gnu1/drivers/acpi/Makefile
--- linux-libre-2.6.32-gnu1/drivers/acpi/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@ obj-y				+= acpi.o \
 
 # All the builtin files are in the "acpi." module_param namespace.
 acpi-y				+= osl.o utils.o reboot.o
+acpi-y				+= hest.o
 
 # sleep related files
 acpi-y				+= wakeup.o
@@ -31,6 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
+acpi-y				+= processor_pdc.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
 acpi-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/numa.c linux-libre-2.6.33-gnu1/drivers/acpi/numa.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/numa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/numa.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/acpi.h>
+#include <linux/numa.h>
 #include <acpi/acpi_bus.h>
 
 #define PREFIX "ACPI: "
@@ -40,14 +41,14 @@ static nodemask_t nodes_found_map = NODE
 
 /* maps to convert between proximity domain and logical node ID */
 static int pxm_to_node_map[MAX_PXM_DOMAINS]
-				= { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
+			= { [0 ... MAX_PXM_DOMAINS - 1] = NUMA_NO_NODE };
 static int node_to_pxm_map[MAX_NUMNODES]
-				= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
+			= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
 int pxm_to_node(int pxm)
 {
 	if (pxm < 0)
-		return NID_INVAL;
+		return NUMA_NO_NODE;
 	return pxm_to_node_map[pxm];
 }
 
@@ -68,9 +69,9 @@ int acpi_map_pxm_to_node(int pxm)
 {
 	int node = pxm_to_node_map[pxm];
 
-	if (node < 0){
+	if (node < 0) {
 		if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
-			return NID_INVAL;
+			return NUMA_NO_NODE;
 		node = first_unset_node(nodes_found_map);
 		__acpi_map_pxm_to_node(pxm, node);
 		node_set(node, nodes_found_map);
@@ -79,16 +80,6 @@ int acpi_map_pxm_to_node(int pxm)
 	return node;
 }
 
-#if 0
-void __cpuinit acpi_unmap_pxm_to_node(int node)
-{
-	int pxm = node_to_pxm_map[node];
-	pxm_to_node_map[pxm] = NID_INVAL;
-	node_to_pxm_map[node] = PXM_INVAL;
-	node_clear(node, nodes_found_map);
-}
-#endif  /*  0  */
-
 static void __init
 acpi_table_print_srat_entry(struct acpi_subtable_header *header)
 {
@@ -283,22 +274,24 @@ acpi_table_parse_srat(enum acpi_srat_typ
 
 int __init acpi_numa_init(void)
 {
+	int ret = 0;
+
 	/* SRAT: Static Resource Affinity Table */
 	if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
 				      acpi_parse_x2apic_affinity, NR_CPUS);
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
 				      acpi_parse_processor_affinity, NR_CPUS);
-		acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
-				      acpi_parse_memory_affinity,
-				      NR_NODE_MEMBLKS);
+		ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
+					    acpi_parse_memory_affinity,
+					    NR_NODE_MEMBLKS);
 	}
 
 	/* SLIT: System Locality Information Table */
 	acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
 
 	acpi_numa_arch_fixup();
-	return 0;
+	return ret;
 }
 
 int acpi_get_pxm(acpi_handle h)
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/osl.c linux-libre-2.6.33-gnu1/drivers/acpi/osl.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/osl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/osl.c	2010-02-24 13:52:17.000000000 -0500
@@ -1118,7 +1118,7 @@ __setup("acpi_enforce_resources=", acpi_
 
 /* Check for resource conflicts between ACPI OperationRegions and native
  * drivers */
-int acpi_check_resource_conflict(struct resource *res)
+int acpi_check_resource_conflict(const struct resource *res)
 {
 	struct acpi_res_list *res_list_elem;
 	int ioport;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/pci_link.c linux-libre-2.6.33-gnu1/drivers/acpi/pci_link.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/pci_link.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/pci_link.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@ ACPI_MODULE_NAME("pci_link");
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
-static struct acpi_device_id link_device_ids[] = {
+static const struct acpi_device_id link_device_ids[] = {
 	{"PNP0C0F", 0},
 	{"", 0},
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/pci_root.c linux-libre-2.6.33-gnu1/drivers/acpi/pci_root.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/pci_root.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/pci_root.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,7 @@ static int acpi_pci_root_add(struct acpi
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
-static struct acpi_device_id root_device_ids[] = {
+static const struct acpi_device_id root_device_ids[] = {
 	{"PNP0A03", 0},
 	{"", 0},
 };
@@ -202,72 +202,24 @@ static void acpi_pci_bridge_scan(struct
 		}
 }
 
-static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
-			  0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766";
 
 static acpi_status acpi_pci_run_osc(acpi_handle handle,
 				    const u32 *capbuf, u32 *retval)
 {
+	struct acpi_osc_context context = {
+		.uuid_str = pci_osc_uuid_str,
+		.rev = 1,
+		.cap.length = 12,
+		.cap.pointer = (void *)capbuf,
+	};
 	acpi_status status;
-	struct acpi_object_list input;
-	union acpi_object in_params[4];
-	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-	union acpi_object *out_obj;
-	u32 errors;
 
-	/* Setting up input parameters */
-	input.count = 4;
-	input.pointer = in_params;
-	in_params[0].type 		= ACPI_TYPE_BUFFER;
-	in_params[0].buffer.length 	= 16;
-	in_params[0].buffer.pointer	= OSC_UUID;
-	in_params[1].type 		= ACPI_TYPE_INTEGER;
-	in_params[1].integer.value 	= 1;
-	in_params[2].type 		= ACPI_TYPE_INTEGER;
-	in_params[2].integer.value	= 3;
-	in_params[3].type		= ACPI_TYPE_BUFFER;
-	in_params[3].buffer.length 	= 12;
-	in_params[3].buffer.pointer 	= (u8 *)capbuf;
-
-	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	if (!output.length)
-		return AE_NULL_OBJECT;
-
-	out_obj = output.pointer;
-	if (out_obj->type != ACPI_TYPE_BUFFER) {
-		printk(KERN_DEBUG "_OSC evaluation returned wrong type\n");
-		status = AE_TYPE;
-		goto out_kfree;
-	}
-	/* Need to ignore the bit0 in result code */
-	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
-	if (errors) {
-		if (errors & OSC_REQUEST_ERROR)
-			printk(KERN_DEBUG "_OSC request failed\n");
-		if (errors & OSC_INVALID_UUID_ERROR)
-			printk(KERN_DEBUG "_OSC invalid UUID\n");
-		if (errors & OSC_INVALID_REVISION_ERROR)
-			printk(KERN_DEBUG "_OSC invalid revision\n");
-		if (errors & OSC_CAPABILITIES_MASK_ERROR) {
-			if (capbuf[OSC_QUERY_TYPE] & OSC_QUERY_ENABLE)
-				goto out_success;
-			printk(KERN_DEBUG
-			       "Firmware did not grant requested _OSC control\n");
-			status = AE_SUPPORT;
-			goto out_kfree;
-		}
-		status = AE_ERROR;
-		goto out_kfree;
+	status = acpi_run_osc(handle, &context);
+	if (ACPI_SUCCESS(status)) {
+		*retval = *((u32 *)(context.ret.pointer + 8));
+		kfree(context.ret.pointer);
 	}
-out_success:
-	*retval = *((u32 *)(out_obj->buffer.pointer + 8));
-	status = AE_OK;
-
-out_kfree:
-	kfree(output.pointer);
 	return status;
 }
 
@@ -277,10 +229,10 @@ static acpi_status acpi_pci_query_osc(st
 	u32 support_set, result, capbuf[3];
 
 	/* do _OSC query for all possible controls */
-	support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS);
+	support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
 	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
 	capbuf[OSC_SUPPORT_TYPE] = support_set;
-	capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+	capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
 
 	status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
 	if (ACPI_SUCCESS(status)) {
@@ -427,7 +379,7 @@ acpi_status acpi_pci_osc_control_set(acp
 	if (ACPI_FAILURE(status))
 		return status;
 
-	control_req = (flags & OSC_CONTROL_MASKS);
+	control_req = (flags & OSC_PCI_CONTROL_MASKS);
 	if (!control_req)
 		return AE_TYPE;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/pci_slot.c linux-libre-2.6.33-gnu1/drivers/acpi/pci_slot.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/pci_slot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/pci_slot.c	2010-02-24 13:52:17.000000000 -0500
@@ -219,12 +219,12 @@ walk_p2p_bridge(acpi_handle handle, u32
 
 	dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number);
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, &child_context, NULL);
+				     user_function, NULL, &child_context, NULL);
 	if (ACPI_FAILURE(status))
 		goto out;
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, &child_context, NULL);
+				     walk_p2p_bridge, NULL, &child_context, NULL);
 out:
 	pci_dev_put(dev);
 	return AE_OK;
@@ -277,12 +277,12 @@ walk_root_bridge(acpi_handle handle, acp
 
 	dbg("root bridge walk, pci_bus = %x\n", pci_bus->number);
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     user_function, &context, NULL);
+				     user_function, NULL, &context, NULL);
 	if (ACPI_FAILURE(status))
 		return status;
 
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     walk_p2p_bridge, &context, NULL);
+				     walk_p2p_bridge, NULL, &context, NULL);
 	if (ACPI_FAILURE(status))
 		err("%s: walk_p2p_bridge failure - %d\n", __func__, status);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/power.c linux-libre-2.6.33-gnu1/drivers/acpi/power.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/power.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/power.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,7 @@ static int acpi_power_remove(struct acpi
 static int acpi_power_resume(struct acpi_device *device);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
-static struct acpi_device_id power_device_ids[] = {
+static const struct acpi_device_id power_device_ids[] = {
 	{ACPI_POWER_HID, 0},
 	{"", 0},
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/power_meter.c linux-libre-2.6.33-gnu1/drivers/acpi/power_meter.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/power_meter.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/power_meter.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,7 +64,7 @@ static int can_cap_in_hardware(void)
 	return force_cap_on || cap_in_hardware;
 }
 
-static struct acpi_device_id power_meter_ids[] = {
+static const struct acpi_device_id power_meter_ids[] = {
 	{"ACPI000D", 0},
 	{"", 0},
 };
@@ -534,6 +534,7 @@ static void remove_domain_devices(struct
 
 	kfree(resource->domain_devices);
 	kobject_put(resource->holders_dir);
+	resource->num_domain_devices = 0;
 }
 
 static int read_domain_devices(struct acpi_power_meter_resource *resource)
@@ -740,7 +741,6 @@ skip_unsafe_cap:
 
 	return res;
 error:
-	remove_domain_devices(resource);
 	remove_attrs(resource);
 	return res;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/processor_core.c linux-libre-2.6.33-gnu1/drivers/acpi/processor_core.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/processor_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/processor_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -124,29 +124,6 @@ static const struct file_operations acpi
 
 DEFINE_PER_CPU(struct acpi_processor *, processors);
 struct acpi_processor_errata errata __read_mostly;
-static int set_no_mwait(const struct dmi_system_id *id)
-{
-	printk(KERN_NOTICE PREFIX "%s detected - "
-		"disabling mwait for CPU C-states\n", id->ident);
-	idle_nomwait = 1;
-	return 0;
-}
-
-static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
-	{
-	set_no_mwait, "IFL91 board", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
-	DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
-	DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
-	DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
-	{
-	set_no_mwait, "Extensa 5220", {
-	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
-	DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-	DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
-	DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
-	{},
-};
 
 /* --------------------------------------------------------------------------
                                 Errata Handling
@@ -277,45 +254,6 @@ static int acpi_processor_errata(struct
 }
 
 /* --------------------------------------------------------------------------
-                              Common ACPI processor functions
-   -------------------------------------------------------------------------- */
-
-/*
- * _PDC is required for a BIOS-OS handshake for most of the newer
- * ACPI processor features.
- */
-static int acpi_processor_set_pdc(struct acpi_processor *pr)
-{
-	struct acpi_object_list *pdc_in = pr->pdc;
-	acpi_status status = AE_OK;
-
-
-	if (!pdc_in)
-		return status;
-	if (idle_nomwait) {
-		/*
-		 * If mwait is disabled for CPU C-states, the C2C3_FFH access
-		 * mode will be disabled in the parameter of _PDC object.
-		 * Of course C1_FFH access mode will also be disabled.
-		 */
-		union acpi_object *obj;
-		u32 *buffer = NULL;
-
-		obj = pdc_in->pointer;
-		buffer = (u32 *)(obj->buffer.pointer);
-		buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
-
-	}
-	status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
-
-	if (ACPI_FAILURE(status))
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		    "Could not evaluate _PDC, using legacy perf. control...\n"));
-
-	return status;
-}
-
-/* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
@@ -353,7 +291,7 @@ static int acpi_processor_info_open_fs(s
 			   PDE(inode)->data);
 }
 
-static int acpi_processor_add_fs(struct acpi_device *device)
+static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
 {
 	struct proc_dir_entry *entry = NULL;
 
@@ -722,7 +660,7 @@ static void acpi_processor_notify(struct
 	switch (event) {
 	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
 		saved = pr->performance_platform_limit;
-		acpi_processor_ppc_has_changed(pr);
+		acpi_processor_ppc_has_changed(pr, 1);
 		if (saved == pr->performance_platform_limit)
 			break;
 		acpi_bus_generate_proc_event(device, event,
@@ -758,7 +696,7 @@ static int acpi_cpu_soft_notify(struct n
 	struct acpi_processor *pr = per_cpu(processors, cpu);
 
 	if (action == CPU_ONLINE && pr) {
-		acpi_processor_ppc_has_changed(pr);
+		acpi_processor_ppc_has_changed(pr, 0);
 		acpi_processor_cst_has_changed(pr);
 		acpi_processor_tstate_has_changed(pr);
 	}
@@ -825,12 +763,10 @@ static int __cpuinit acpi_processor_add(
 	}
 
 	/* _PDC call should be done before doing anything else (if reqd.). */
-	arch_acpi_processor_init_pdc(pr);
-	acpi_processor_set_pdc(pr);
-	arch_acpi_processor_cleanup_pdc(pr);
+	acpi_processor_set_pdc(pr->handle);
 
 #ifdef CONFIG_CPU_FREQ
-	acpi_processor_ppc_has_changed(pr);
+	acpi_processor_ppc_has_changed(pr, 0);
 #endif
 	acpi_processor_get_throttling_info(pr);
 	acpi_processor_get_limit_info(pr);
@@ -845,7 +781,7 @@ static int __cpuinit acpi_processor_add(
 		goto err_power_exit;
 	}
 
-	dev_info(&device->dev, "registered as cooling_device%d\n",
+	dev_dbg(&device->dev, "registered as cooling_device%d\n",
 		 pr->cdev->id);
 
 	result = sysfs_create_link(&device->dev.kobj,
@@ -1102,7 +1038,7 @@ void acpi_processor_install_hotplug_noti
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, &action, NULL);
+			    processor_walk_namespace_cb, NULL, &action, NULL);
 #endif
 	register_hotcpu_notifier(&acpi_cpu_notifier);
 }
@@ -1115,7 +1051,7 @@ void acpi_processor_uninstall_hotplug_no
 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
 			    ACPI_ROOT_OBJECT,
 			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, &action, NULL);
+			    processor_walk_namespace_cb, NULL, &action, NULL);
 #endif
 	unregister_hotcpu_notifier(&acpi_cpu_notifier);
 }
@@ -1145,11 +1081,6 @@ static int __init acpi_processor_init(vo
 	if (!acpi_processor_dir)
 		return -ENOMEM;
 #endif
-	/*
-	 * Check whether the system is DMI table. If yes, OSPM
-	 * should not use mwait for CPU-states.
-	 */
-	dmi_check_system(processor_idle_dmi_table);
 	result = cpuidle_register_driver(&acpi_idle_driver);
 	if (result < 0)
 		goto out_proc;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/processor_idle.c linux-libre-2.6.33-gnu1/drivers/acpi/processor_idle.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/processor_idle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/processor_idle.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,6 +110,14 @@ static struct dmi_system_id __cpuinitdat
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
 	 (void *)2},
+	{ set_max_cstate, "Pavilion zv5000", {
+	  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},
+	 (void *)1},
+	{ set_max_cstate, "Asus L8400B", {
+	  DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
+	 (void *)1},
 	{},
 };
 
@@ -164,7 +172,7 @@ static void lapic_timer_check_state(int
 		pr->power.timer_broadcast_on_state = state;
 }
 
-static void lapic_timer_propagate_broadcast(void *arg)
+static void __lapic_timer_propagate_broadcast(void *arg)
 {
 	struct acpi_processor *pr = (struct acpi_processor *) arg;
 	unsigned long reason;
@@ -175,6 +183,12 @@ static void lapic_timer_propagate_broadc
 	clockevents_notify(reason, &pr->id);
 }
 
+static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
+{
+	smp_call_function_single(pr->id, __lapic_timer_propagate_broadcast,
+				 (void *)pr, 1);
+}
+
 /* Power(C) State timer broadcast control */
 static void lapic_timer_state_broadcast(struct acpi_processor *pr,
 				       struct acpi_processor_cx *cx,
@@ -299,6 +313,28 @@ static int acpi_processor_get_power_info
 	pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
 	pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
 
+	/*
+	 * FADT specified C2 latency must be less than or equal to
+	 * 100 microseconds.
+	 */
+	if (acpi_gbl_FADT.C2latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"C2 latency too large [%d]\n", acpi_gbl_FADT.C2latency));
+		/* invalidate C2 */
+		pr->power.states[ACPI_STATE_C2].address = 0;
+	}
+
+	/*
+	 * FADT supplied C3 latency must be less than or equal to
+	 * 1000 microseconds.
+	 */
+	if (acpi_gbl_FADT.C3latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"C3 latency too large [%d]\n", acpi_gbl_FADT.C3latency));
+		/* invalidate C3 */
+		pr->power.states[ACPI_STATE_C3].address = 0;
+	}
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "lvl2[0x%08x] lvl3[0x%08x]\n",
 			  pr->power.states[ACPI_STATE_C2].address,
@@ -488,33 +524,6 @@ static int acpi_processor_get_power_info
 	return status;
 }
 
-static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
-{
-
-	if (!cx->address)
-		return;
-
-	/*
-	 * C2 latency must be less than or equal to 100
-	 * microseconds.
-	 */
-	else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "latency too large [%d]\n", cx->latency));
-		return;
-	}
-
-	/*
-	 * Otherwise we've met all of our C2 requirements.
-	 * Normalize the C2 latency to expidite policy
-	 */
-	cx->valid = 1;
-
-	cx->latency_ticks = cx->latency;
-
-	return;
-}
-
 static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
 					   struct acpi_processor_cx *cx)
 {
@@ -526,16 +535,6 @@ static void acpi_processor_power_verify_
 		return;
 
 	/*
-	 * C3 latency must be less than or equal to 1000
-	 * microseconds.
-	 */
-	else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "latency too large [%d]\n", cx->latency));
-		return;
-	}
-
-	/*
 	 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
 	 * DMA transfers are used by any ISA device to avoid livelock.
 	 * Note that we could disable Type-F DMA (as recommended by
@@ -623,7 +622,10 @@ static int acpi_processor_power_verify(s
 			break;
 
 		case ACPI_STATE_C2:
-			acpi_processor_power_verify_c2(cx);
+			if (!cx->address)
+				break;
+			cx->valid = 1; 
+			cx->latency_ticks = cx->latency; /* Normalize latency */
 			break;
 
 		case ACPI_STATE_C3:
@@ -638,8 +640,7 @@ static int acpi_processor_power_verify(s
 		working++;
 	}
 
-	smp_call_function_single(pr->id, lapic_timer_propagate_broadcast,
-				 pr, 1);
+	lapic_timer_propagate_broadcast(pr);
 
 	return (working);
 }
@@ -879,12 +880,14 @@ static int acpi_idle_enter_simple(struct
 		return(acpi_idle_enter_c1(dev, state));
 
 	local_irq_disable();
-	current_thread_info()->status &= ~TS_POLLING;
-	/*
-	 * TS_POLLING-cleared state must be visible before we test
-	 * NEED_RESCHED:
-	 */
-	smp_mb();
+	if (cx->entry_method != ACPI_CSTATE_FFH) {
+		current_thread_info()->status &= ~TS_POLLING;
+		/*
+		 * TS_POLLING-cleared state must be visible before we test
+		 * NEED_RESCHED:
+		 */
+		smp_mb();
+	}
 
 	if (unlikely(need_resched())) {
 		current_thread_info()->status |= TS_POLLING;
@@ -964,12 +967,14 @@ static int acpi_idle_enter_bm(struct cpu
 	}
 
 	local_irq_disable();
-	current_thread_info()->status &= ~TS_POLLING;
-	/*
-	 * TS_POLLING-cleared state must be visible before we test
-	 * NEED_RESCHED:
-	 */
-	smp_mb();
+	if (cx->entry_method != ACPI_CSTATE_FFH) {
+		current_thread_info()->status &= ~TS_POLLING;
+		/*
+		 * TS_POLLING-cleared state must be visible before we test
+		 * NEED_RESCHED:
+		 */
+		smp_mb();
+	}
 
 	if (unlikely(need_resched())) {
 		current_thread_info()->status |= TS_POLLING;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/processor_pdc.c linux-libre-2.6.33-gnu1/drivers/acpi/processor_pdc.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/processor_pdc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/processor_pdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2005 Intel Corporation
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ *	Alex Chiang <achiang@hp.com>
+ *	- Unified x86/ia64 implementations
+ *	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *	- Added _PDC for platforms with Intel CPUs
+ */
+#include <linux/dmi.h>
+
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
+
+#include "internal.h"
+
+#define PREFIX			"ACPI: "
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME("processor_pdc");
+
+static int set_no_mwait(const struct dmi_system_id *id)
+{
+	printk(KERN_NOTICE PREFIX "%s detected - "
+		"disabling mwait for CPU C-states\n", id->ident);
+	idle_nomwait = 1;
+	return 0;
+}
+
+static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
+	{
+	set_no_mwait, "IFL91 board", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+	DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
+	DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
+	DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
+	{
+	set_no_mwait, "Extensa 5220", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+	DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+	DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+	DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
+	{},
+};
+
+static void acpi_set_pdc_bits(u32 *buf)
+{
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
+
+	/* Enable coordination with firmware's _TSD info */
+	buf[2] = ACPI_PDC_SMP_T_SWCOORD;
+
+	/* Twiddle arch-specific bits needed for _PDC */
+	arch_acpi_set_pdc_bits(buf);
+}
+
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
+{
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
+
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return NULL;
+	}
+
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return NULL;
+	}
+
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return NULL;
+	}
+
+	acpi_set_pdc_bits(buf);
+
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
+
+	return obj_list;
+}
+
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+static int
+acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
+{
+	acpi_status status = AE_OK;
+
+	if (idle_nomwait) {
+		/*
+		 * If mwait is disabled for CPU C-states, the C2C3_FFH access
+		 * mode will be disabled in the parameter of _PDC object.
+		 * Of course C1_FFH access mode will also be disabled.
+		 */
+		union acpi_object *obj;
+		u32 *buffer = NULL;
+
+		obj = pdc_in->pointer;
+		buffer = (u32 *)(obj->buffer.pointer);
+		buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
+
+	}
+	status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
+
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		    "Could not evaluate _PDC, using legacy perf. control.\n"));
+
+	return status;
+}
+
+static int early_pdc_done;
+
+void acpi_processor_set_pdc(acpi_handle handle)
+{
+	struct acpi_object_list *obj_list;
+
+	if (arch_has_acpi_pdc() == false)
+		return;
+
+	if (early_pdc_done)
+		return;
+
+	obj_list = acpi_processor_alloc_pdc();
+	if (!obj_list)
+		return;
+
+	acpi_processor_eval_pdc(handle, obj_list);
+
+	kfree(obj_list->pointer->buffer.pointer);
+	kfree(obj_list->pointer);
+	kfree(obj_list);
+}
+EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
+
+static int early_pdc_optin;
+static int set_early_pdc_optin(const struct dmi_system_id *id)
+{
+	early_pdc_optin = 1;
+	return 0;
+}
+
+static int param_early_pdc_optin(char *s)
+{
+	early_pdc_optin = 1;
+	return 1;
+}
+__setup("acpi_early_pdc_eval", param_early_pdc_optin);
+
+static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
+	{
+	set_early_pdc_optin, "HP Envy", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL},
+	{
+	set_early_pdc_optin, "HP Pavilion dv6", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL},
+	{
+	set_early_pdc_optin, "HP Pavilion dv7", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL},
+	{},
+};
+
+static acpi_status
+early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_processor_set_pdc(handle);
+	return AE_OK;
+}
+
+void __init acpi_early_processor_set_pdc(void)
+{
+	/*
+	 * Check whether the system is DMI table. If yes, OSPM
+	 * should not use mwait for CPU-states.
+	 */
+	dmi_check_system(processor_idle_dmi_table);
+
+	/*
+	 * Allow systems to opt-in to early _PDC evaluation.
+	 */
+	dmi_check_system(early_pdc_optin_table);
+	if (!early_pdc_optin)
+		return;
+
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX,
+			    early_init_pdc, NULL, NULL, NULL);
+
+	early_pdc_done = 1;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/processor_perflib.c linux-libre-2.6.33-gnu1/drivers/acpi/processor_perflib.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/processor_perflib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/processor_perflib.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,21 +152,78 @@ static int acpi_processor_get_platform_l
 	return 0;
 }
 
-int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
+#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE	0x80
+/*
+ * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
+ * @handle: ACPI processor handle
+ * @status: the status code of _PPC evaluation
+ *	0: success. OSPM is now using the performance state specificed.
+ *	1: failure. OSPM has not changed the number of P-states in use
+ */
+static void acpi_processor_ppc_ost(acpi_handle handle, int status)
+{
+	union acpi_object params[2] = {
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+	};
+	struct acpi_object_list arg_list = {2, params};
+	acpi_handle temp;
+
+	params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
+	params[1].integer.value =  status;
+
+	/* when there is no _OST , skip it */
+	if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp)))
+		return;
+
+	acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
+	return;
+}
+
+int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
 {
 	int ret;
 
-	if (ignore_ppc)
+	if (ignore_ppc) {
+		/*
+		 * Only when it is notification event, the _OST object
+		 * will be evaluated. Otherwise it is skipped.
+		 */
+		if (event_flag)
+			acpi_processor_ppc_ost(pr->handle, 1);
 		return 0;
+	}
 
 	ret = acpi_processor_get_platform_limit(pr);
-
+	/*
+	 * Only when it is notification event, the _OST object
+	 * will be evaluated. Otherwise it is skipped.
+	 */
+	if (event_flag) {
+		if (ret < 0)
+			acpi_processor_ppc_ost(pr->handle, 1);
+		else
+			acpi_processor_ppc_ost(pr->handle, 0);
+	}
 	if (ret < 0)
 		return (ret);
 	else
 		return cpufreq_update_policy(pr->id);
 }
 
+int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
+{
+	struct acpi_processor *pr;
+
+	pr = per_cpu(processors, cpu);
+	if (!pr || !pr->performance || !pr->performance->state_count)
+		return -ENODEV;
+	*limit = pr->performance->states[pr->performance_platform_limit].
+		core_frequency * 1000;
+	return 0;
+}
+EXPORT_SYMBOL(acpi_processor_get_bios_limit);
+
 void acpi_processor_ppc_init(void)
 {
 	if (!cpufreq_register_notifier
@@ -356,7 +413,11 @@ static int acpi_processor_get_performanc
 	if (result)
 		goto update_bios;
 
-	return 0;
+	/* We need to call _PPC once when cpufreq starts */
+	if (ignore_ppc != 1)
+		result = acpi_processor_get_platform_limit(pr);
+
+	return result;
 
 	/*
 	 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/processor_thermal.c linux-libre-2.6.33-gnu1/drivers/acpi/processor_thermal.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/processor_thermal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/processor_thermal.c	2010-02-24 13:52:17.000000000 -0500
@@ -443,8 +443,7 @@ struct thermal_cooling_device_ops proces
 #ifdef CONFIG_ACPI_PROCFS
 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
-
+	struct acpi_processor *pr = seq->private;
 
 	if (!pr)
 		goto end;
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/sbs.c linux-libre-2.6.33-gnu1/drivers/acpi/sbs.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/sbs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/sbs.c	2010-02-24 13:52:17.000000000 -0500
@@ -822,7 +822,10 @@ static int acpi_battery_add(struct acpi_
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
+#if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER)
 	struct acpi_battery *battery = &sbs->battery[id];
+#endif
+
 #ifdef CONFIG_ACPI_SYSFS_POWER
 	if (battery->bat.dev) {
 		if (battery->have_sysfs_alarm)
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/sbshc.c linux-libre-2.6.33-gnu1/drivers/acpi/sbshc.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/sbshc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/sbshc.c	2010-02-24 13:52:17.000000000 -0500
@@ -242,7 +242,7 @@ static int smbus_alarm(void *context)
 		case ACPI_SBS_CHARGER:
 		case ACPI_SBS_MANAGER:
 		case ACPI_SBS_BATTERY:
-			acpi_os_execute(OSL_GPE_HANDLER,
+			acpi_os_execute(OSL_NOTIFY_HANDLER,
 					acpi_smbus_callback, hc);
 		default:;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/scan.c linux-libre-2.6.33-gnu1/drivers/acpi/scan.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/scan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/scan.c	2010-02-24 13:52:17.000000000 -0500
@@ -1332,13 +1332,29 @@ static int acpi_bus_scan(acpi_handle han
 	status = acpi_bus_check_add(handle, 0, ops, &device);
 	if (ACPI_SUCCESS(status))
 		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
-				    acpi_bus_check_add, ops, &device);
+				    acpi_bus_check_add, NULL, ops, &device);
 
 	if (child)
 		*child = device;
-	return 0;
+
+	if (device)
+		return 0;
+	else
+		return -ENODEV;
 }
 
+/*
+ * acpi_bus_add and acpi_bus_start
+ *
+ * scan a given ACPI tree and (probably recently hot-plugged)
+ * create and add or starts found devices.
+ *
+ * If no devices were found -ENODEV is returned which does not
+ * mean that this is a real error, there just have been no suitable
+ * ACPI objects in the table trunk from which the kernel could create
+ * a device and add/start an appropriate driver.
+ */
+
 int
 acpi_bus_add(struct acpi_device **child,
 	     struct acpi_device *parent, acpi_handle handle, int type)
@@ -1348,8 +1364,7 @@ acpi_bus_add(struct acpi_device **child,
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 
-	acpi_bus_scan(handle, &ops, child);
-	return 0;
+	return acpi_bus_scan(handle, &ops, child);
 }
 EXPORT_SYMBOL(acpi_bus_add);
 
@@ -1357,11 +1372,13 @@ int acpi_bus_start(struct acpi_device *d
 {
 	struct acpi_bus_ops ops;
 
+	if (!device)
+		return -EINVAL;
+
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_start = 1;
 
-	acpi_bus_scan(device->handle, &ops, NULL);
-	return 0;
+	return acpi_bus_scan(device->handle, &ops, NULL);
 }
 EXPORT_SYMBOL(acpi_bus_start);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/sleep.c linux-libre-2.6.33-gnu1/drivers/acpi/sleep.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/sleep.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/sleep.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,6 +81,23 @@ static int acpi_sleep_prepare(u32 acpi_s
 #ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 /*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states.  Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume.  Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware.  The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
+void __init acpi_set_sci_en_on_resume(void)
+{
+	set_sci_en_on_resume = true;
+}
+
+/*
  * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
  * user to request that behavior by using the 'acpi_old_suspend_ordering'
  * kernel command line option that causes the following variable to be set.
@@ -170,18 +187,6 @@ static void acpi_pm_end(void)
 #endif /* CONFIG_ACPI_SLEEP */
 
 #ifdef CONFIG_SUSPEND
-/*
- * According to the ACPI specification the BIOS should make sure that ACPI is
- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states.  Still,
- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
- * on such systems during resume.  Unfortunately that doesn't help in
- * particularly pathological cases in which SCI_EN has to be set directly on
- * resume, although the specification states very clearly that this flag is
- * owned by the hardware.  The set_sci_en_on_resume variable will be set in such
- * cases.
- */
-static bool set_sci_en_on_resume;
-
 extern void do_suspend_lowlevel(void);
 
 static u32 acpi_suspend_states[] = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/tables.c linux-libre-2.6.33-gnu1/drivers/acpi/tables.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/tables.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/tables.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id,
 	unsigned long table_end;
 	acpi_size tbl_size;
 
-	if (acpi_disabled)
+	if (acpi_disabled && !acpi_ht)
 		return -ENODEV;
 
 	if (!handler)
@@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, ac
 	struct acpi_table_header *table = NULL;
 	acpi_size tbl_size;
 
-	if (acpi_disabled)
+	if (acpi_disabled && !acpi_ht)
 		return -ENODEV;
 
 	if (!handler)
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/thermal.c linux-libre-2.6.33-gnu1/drivers/acpi/thermal.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/thermal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/thermal.c	2010-02-24 13:52:17.000000000 -0500
@@ -1052,6 +1052,13 @@ static int acpi_thermal_trip_seq_show(st
 				   acpi_device_bid(device));
 		}
 		seq_puts(seq, "\n");
+	} else {
+		seq_printf(seq, "passive (forced):");
+		if (tz->thermal_zone->forced_passive)
+			seq_printf(seq, "        %i C\n",
+				   tz->thermal_zone->forced_passive / 1000);
+		else
+			seq_printf(seq, "<not set>\n");
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/video.c linux-libre-2.6.33-gnu1/drivers/acpi/video.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/video.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,6 +78,13 @@ MODULE_LICENSE("GPL");
 static int brightness_switch_enabled = 1;
 module_param(brightness_switch_enabled, bool, 0644);
 
+/*
+ * By default, we don't allow duplicate ACPI video bus devices
+ * under the same VGA controller
+ */
+static int allow_duplicates;
+module_param(allow_duplicates, bool, 0644);
+
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
@@ -999,8 +1006,10 @@ static void acpi_video_device_find_cap(s
 		sprintf(name, "acpi_video%d", count++);
 		device->backlight = backlight_device_register(name,
 			NULL, device, &acpi_backlight_ops);
-		device->backlight->props.max_brightness = device->brightness->count-3;
 		kfree(name);
+		if (IS_ERR(device->backlight))
+			return;
+		device->backlight->props.max_brightness = device->brightness->count-3;
 
 		result = sysfs_create_link(&device->backlight->dev.kobj,
 					   &device->dev->dev.kobj, "device");
@@ -1979,6 +1988,10 @@ acpi_video_switch_brightness(struct acpi
 	unsigned long long level_current, level_next;
 	int result = -EINVAL;
 
+	/* no warning message if acpi_backlight=vendor is used */
+	if (!acpi_video_backlight_support())
+		return 0;
+
 	if (!device->brightness)
 		goto out;
 
@@ -2233,11 +2246,47 @@ static int acpi_video_resume(struct acpi
 	return AE_OK;
 }
 
+static acpi_status
+acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
+			void **return_value)
+{
+	struct acpi_device *device = context;
+	struct acpi_device *sibling;
+	int result;
+
+	if (handle == device->handle)
+		return AE_CTRL_TERMINATE;
+
+	result = acpi_bus_get_device(handle, &sibling);
+	if (result)
+		return AE_OK;
+
+	if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
+			return AE_ALREADY_EXISTS;
+
+	return AE_OK;
+}
+
 static int acpi_video_bus_add(struct acpi_device *device)
 {
 	struct acpi_video_bus *video;
 	struct input_dev *input;
 	int error;
+	acpi_status status;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				device->parent->handle, 1,
+				acpi_video_bus_match, NULL,
+				device, NULL);
+	if (status == AE_ALREADY_EXISTS) {
+		printk(KERN_WARNING FW_BUG
+			"Duplicate ACPI video bus devices for the"
+			" same VGA controller, please try module "
+			"parameter \"video.allow_duplicates=1\""
+			"if the current driver doesn't work.\n");
+		if (!allow_duplicates)
+			return -ENODEV;
+	}
 
 	video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
 	if (!video)
diff -druNp linux-libre-2.6.32-gnu1/drivers/acpi/video_detect.c linux-libre-2.6.33-gnu1/drivers/acpi/video_detect.c
--- linux-libre-2.6.32-gnu1/drivers/acpi/video_detect.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/acpi/video_detect.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@
  * video_detect.c:
  * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
  * There a Linux specific (Spec does not provide a HID for video devices) is
- * assinged
+ * assigned
  *
  * After PCI devices are glued with ACPI devices
  * acpi_get_pci_dev() can be called to identify ACPI graphics
@@ -83,16 +83,16 @@ long acpi_is_video_device(struct acpi_de
 	if (!device)
 		return 0;
 
-	/* Does this device able to support video switching ? */
+	/* Is this device able to support video switching ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
 		video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
 
-	/* Does this device able to retrieve a video ROM ? */
+	/* Is this device able to retrieve a video ROM ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
 		video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
 
-	/* Does this device able to configure which video head to be POSTed ? */
+	/* Is this device able to configure which video head to be POSTed ? */
 	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
 	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
@@ -101,7 +101,7 @@ long acpi_is_video_device(struct acpi_de
 	/* Only check for backlight functionality if one of the above hit. */
 	if (video_caps)
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
-				    ACPI_UINT32_MAX, acpi_backlight_cap_match,
+				    ACPI_UINT32_MAX, acpi_backlight_cap_match, NULL,
 				    &video_caps, NULL);
 
 	return video_caps;
@@ -137,7 +137,7 @@ find_video(acpi_handle handle, u32 lvl,
  *
  * if NULL is passed as argument all ACPI devices are enumerated and
  * all graphics capabilities of physically present devices are
- * summerized and returned. This is cached and done only once.
+ * summarized and returned. This is cached and done only once.
  */
 long acpi_video_get_capabilities(acpi_handle graphics_handle)
 {
@@ -151,7 +151,7 @@ long acpi_video_get_capabilities(acpi_ha
 	if (!graphics_handle) {
 		/* Only do the global walk through all graphics devices once */
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-				    ACPI_UINT32_MAX, find_video,
+				    ACPI_UINT32_MAX, find_video, NULL,
 				    &caps, NULL);
 		/* There might be boot param flags set already... */
 		acpi_video_support |= caps;
@@ -173,7 +173,7 @@ long acpi_video_get_capabilities(acpi_ha
 			return 0;
 		}
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
-				    ACPI_UINT32_MAX, find_video,
+				    ACPI_UINT32_MAX, find_video, NULL,
 				    &caps, NULL);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/ahci.c linux-libre-2.6.33-gnu1/drivers/ata/ahci.c
--- linux-libre-2.6.32-gnu1/drivers/ata/ahci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/ahci.c	2010-02-24 13:52:17.000000000 -0500
@@ -113,6 +113,7 @@ enum {
 	board_ahci_mcp65	= 6,
 	board_ahci_nopmp	= 7,
 	board_ahci_yesncq	= 8,
+	board_ahci_nosntf	= 9,
 
 	/* global controller registers */
 	HOST_CAP		= 0x00, /* host capabilities */
@@ -235,6 +236,7 @@ enum {
 	AHCI_HFLAG_NO_SUSPEND		= (1 << 10), /* don't suspend */
 	AHCI_HFLAG_SRST_TOUT_IS_OFFLINE	= (1 << 11), /* treat SRST timeout as
 							link offline */
+	AHCI_HFLAG_NO_SNTF		= (1 << 12), /* no sntf */
 
 	/* ap->flags bits */
 
@@ -508,7 +510,7 @@ static const struct ata_port_info ahci_p
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
-	/* board_ahci_yesncq */
+	[board_ahci_yesncq] =
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_YES_NCQ),
 		.flags		= AHCI_FLAG_COMMON,
@@ -516,6 +518,14 @@ static const struct ata_port_info ahci_p
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
+	[board_ahci_nosntf] =
+	{
+		AHCI_HFLAGS	(AHCI_HFLAG_NO_SNTF),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -531,7 +541,7 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
 	{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
 	{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
-	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
+	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */
 	{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
 	{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
 	{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
@@ -849,6 +859,12 @@ static void ahci_save_initial_config(str
 		cap &= ~HOST_CAP_PMP;
 	}
 
+	if ((cap & HOST_CAP_SNTF) && (hpriv->flags & AHCI_HFLAG_NO_SNTF)) {
+		dev_printk(KERN_INFO, &pdev->dev,
+			   "controller can't do SNTF, turning off CAP_SNTF\n");
+		cap &= ~HOST_CAP_SNTF;
+	}
+
 	if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
 	    port_map != 1) {
 		dev_printk(KERN_INFO, &pdev->dev,
@@ -2852,6 +2868,21 @@ static bool ahci_broken_suspend(struct p
 			},
 			.driver_data = "F.23",	/* cutoff BIOS version */
 		},
+		/*
+		 * Acer eMachines G725 has the same problem.  BIOS
+		 * V1.03 is known to be broken.  V3.04 is known to
+		 * work.  Inbetween, there are V1.06, V2.06 and V3.03
+		 * that we don't have much idea about.  For now,
+		 * blacklist anything older than V3.04.
+		 */
+		{
+			.ident = "G725",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
+			},
+			.driver_data = "V3.04",	/* cutoff BIOS version */
+		},
 		{ }	/* terminate list */
 	};
 	const struct dmi_system_id *dmi = dmi_first_match(sysids);
@@ -2988,6 +3019,14 @@ static int ahci_init_one(struct pci_dev
 	if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
 		return -ENODEV;
 
+	/* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode.
+	 * At the moment, we can only use the AHCI mode. Let the users know
+	 * that for SAS drives they're out of luck.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_PROMISE)
+		dev_printk(KERN_INFO, &pdev->dev, "PDC42819 "
+			   "can only drive SATA devices with this driver\n");
+
 	/* acquire resources */
 	rc = pcim_enable_device(pdev);
 	if (rc)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/ata_generic.c linux-libre-2.6.33-gnu1/drivers/ata/ata_generic.c
--- linux-libre-2.6.32-gnu1/drivers/ata/ata_generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/ata_generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -168,9 +168,12 @@ static struct pci_device_id ata_generic[
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C561), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), },
+#if !defined(CONFIG_PATA_TOSHIBA) && !defined(CONFIG_PATA_TOSHIBA_MODULE)
 	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2),  },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_3),  },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5),  },
+#endif	
 	/* Must come last. If you add entries adjust this table appropriately */
 	{ PCI_ANY_ID,		PCI_ANY_ID,			   PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
 	{ 0, },
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/ata_piix.c linux-libre-2.6.33-gnu1/drivers/ata/ata_piix.c
--- linux-libre-2.6.32-gnu1/drivers/ata/ata_piix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/ata_piix.c	2010-02-24 13:52:17.000000000 -0500
@@ -329,7 +329,7 @@ static struct ata_port_operations ich_pa
 };
 
 static struct ata_port_operations piix_sata_ops = {
-	.inherits		= &ata_bmdma_port_ops,
+	.inherits		= &ata_bmdma32_port_ops,
 };
 
 static struct ata_port_operations piix_sidpr_sata_ops = {
@@ -599,7 +599,7 @@ static const struct ich_laptop ich_lapto
 	{ 0x27DF, 0x1028, 0x02b0 },	/* ICH7 on unknown Dell */
 	{ 0x27DF, 0x1043, 0x1267 },	/* ICH7 on Asus W5F */
 	{ 0x27DF, 0x103C, 0x30A1 },	/* ICH7 on HP Compaq nc2400 */
-	{ 0x27DF, 0x103C, 0x361a },	/* ICH7 on unkown HP  */
+	{ 0x27DF, 0x103C, 0x361a },	/* ICH7 on unknown HP  */
 	{ 0x27DF, 0x1071, 0xD221 },	/* ICH7 on Hercules EC-900 */
 	{ 0x27DF, 0x152D, 0x0778 },	/* ICH7 on unknown Intel */
 	{ 0x24CA, 0x1025, 0x0061 },	/* ICH4 on ACER Aspire 2023WLMi */
@@ -869,10 +869,10 @@ static void do_pata_set_dmamode(struct a
 				(timings[pio][1] << 8);
 		}
 
-		if (ap->udma_mask) {
+		if (ap->udma_mask)
 			udma_enable &= ~(1 << devid);
-			pci_write_config_word(dev, master_port, master_data);
-		}
+
+		pci_write_config_word(dev, master_port, master_data);
 	}
 	/* Don't scribble on 0x48 if the controller does not support UDMA */
 	if (ap->udma_mask)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/Kconfig linux-libre-2.6.33-gnu1/drivers/ata/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/ata/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,7 @@
 #
 
 menuconfig ATA
-	tristate "Serial ATA (prod) and Parallel ATA (experimental) drivers"
+	tristate "Serial ATA and Parallel ATA drivers"
 	depends on HAS_IOMEM
 	depends on BLOCK
 	depends on !(M32R || M68K) || BROKEN
@@ -40,7 +40,6 @@ config ATA_VERBOSE_ERROR
 config ATA_ACPI
 	bool "ATA ACPI Support"
 	depends on ACPI && PCI
-	select ACPI_DOCK
 	default y
 	help
 	  This option adds support for ATA-related ACPI objects.
@@ -374,8 +373,8 @@ config PATA_HPT366
 	  If unsure, say N.
 
 config PATA_HPT37X
-	tristate "HPT 370/370A/371/372/374/302 PATA support (Experimental)"
-	depends on PCI && EXPERIMENTAL
+	tristate "HPT 370/370A/371/372/374/302 PATA support"
+	depends on PCI
 	help
 	  This option enables support for the majority of the later HPT
 	  PATA controllers via the new ATA layer.
@@ -383,8 +382,8 @@ config PATA_HPT37X
 	  If unsure, say N.
 
 config PATA_HPT3X2N
-	tristate "HPT 372N/302N PATA support (Experimental)"
-	depends on PCI && EXPERIMENTAL
+	tristate "HPT 372N/302N PATA support"
+	depends on PCI
 	help
 	  This option enables support for the N variant HPT PATA
 	  controllers via the new ATA layer
@@ -401,7 +400,7 @@ config PATA_HPT3X3
 	  If unsure, say N.
 
 config PATA_HPT3X3_DMA
-	bool "HPT 343/363 DMA support (Experimental)"
+	bool "HPT 343/363 DMA support"
 	depends on PATA_HPT3X3
 	help
 	  This option enables DMA support for the HPT343/363
@@ -510,8 +509,8 @@ config PATA_NETCELL
 	  If unsure, say N.
 
 config PATA_NINJA32
-	tristate "Ninja32/Delkin Cardbus ATA support (Experimental)"
-	depends on PCI && EXPERIMENTAL
+	tristate "Ninja32/Delkin Cardbus ATA support"
+	depends on PCI
 	help
 	  This option enables support for the Ninja32, Delkin and
 	  possibly other brands of Cardbus ATA adapter
@@ -573,6 +572,14 @@ config PATA_PCMCIA
 
 	  If unsure, say N.
 
+config PATA_PDC2027X
+	tristate "Promise PATA 2027x support"
+	depends on PCI
+	help
+	  This option enables support for Promise PATA pdc20268 to pdc20277 host adapters.
+
+	  If unsure, say N.
+
 config PATA_PDC_OLD
 	tristate "Older Promise PATA controller support"
 	depends on PCI
@@ -643,14 +650,6 @@ config PATA_SERVERWORKS
 
 	  If unsure, say N.
 
-config PATA_PDC2027X
-	tristate "Promise PATA 2027x support"
-	depends on PCI
-	help
-	  This option enables support for Promise PATA pdc20268 to pdc20277 host adapters.
-
-	  If unsure, say N.
-
 config PATA_SIL680
 	tristate "CMD / Silicon Image 680 PATA support"
 	depends on PCI
@@ -667,6 +666,15 @@ config PATA_SIS
 
 	  If unsure, say N.
 
+config PATA_TOSHIBA
+	tristate "Toshiba Piccolo support (Experimental)"
+	depends on PCI && EXPERIMENTAL
+	help
+	  Support for the Toshiba Piccolo controllers. Currently only the
+	  primary channel is supported by this driver.
+
+	  If unsure, say N.
+
 config PATA_VIA
 	tristate "VIA PATA support"
 	depends on PCI
@@ -781,5 +789,15 @@ config PATA_BF54X
 
 	  If unsure, say N.
 
+config PATA_MACIO
+	tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE"
+	depends on PPC_PMAC
+	help
+	  Most IDE capable PowerMacs have IDE busses driven by a variant
+          of this controller which is part of the Apple chipset used on
+          most PowerMac models. Some models have multiple busses using
+          different chipsets, though generally, MacIO is one of them.
+
+
 endif # ATA_SFF
 endif # ATA
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/libata-acpi.c linux-libre-2.6.33-gnu1/drivers/ata/libata-acpi.c
--- linux-libre-2.6.32-gnu1/drivers/ata/libata-acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/libata-acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -807,12 +807,11 @@ static int ata_acpi_exec_tfs(struct ata_
  * EH context.
  *
  * RETURNS:
- * 0 on success, -errno on failure.
+ * 0 on success, -ENOENT if _SDD doesn't exist, -errno on failure.
  */
 static int ata_acpi_push_id(struct ata_device *dev)
 {
 	struct ata_port *ap = dev->link->ap;
-	int err;
 	acpi_status status;
 	struct acpi_object_list input;
 	union acpi_object in_params[1];
@@ -835,12 +834,16 @@ static int ata_acpi_push_id(struct ata_d
 	status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
 	swap_buf_le16(dev->id, ATA_ID_WORDS);
 
-	err = ACPI_FAILURE(status) ? -EIO : 0;
-	if (err < 0)
+	if (status == AE_NOT_FOUND)
+		return -ENOENT;
+
+	if (ACPI_FAILURE(status)) {
 		ata_dev_printk(dev, KERN_WARNING,
 			       "ACPI _SDD failed (AE 0x%x)\n", status);
+		return -EIO;
+	}
 
-	return err;
+	return 0;
 }
 
 /**
@@ -971,7 +974,7 @@ int ata_acpi_on_devcfg(struct ata_device
 	/* do _SDD if SATA */
 	if (acpi_sata) {
 		rc = ata_acpi_push_id(dev);
-		if (rc)
+		if (rc && rc != -ENOENT)
 			goto acpi_err;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/libata-core.c linux-libre-2.6.33-gnu1/drivers/ata/libata-core.c
--- linux-libre-2.6.32-gnu1/drivers/ata/libata-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/libata-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -3790,21 +3790,45 @@ int sata_link_debounce(struct ata_link *
 int sata_link_resume(struct ata_link *link, const unsigned long *params,
 		     unsigned long deadline)
 {
+	int tries = ATA_LINK_RESUME_TRIES;
 	u32 scontrol, serror;
 	int rc;
 
 	if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
 		return rc;
 
-	scontrol = (scontrol & 0x0f0) | 0x300;
+	/*
+	 * Writes to SControl sometimes get ignored under certain
+	 * controllers (ata_piix SIDPR).  Make sure DET actually is
+	 * cleared.
+	 */
+	do {
+		scontrol = (scontrol & 0x0f0) | 0x300;
+		if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
+			return rc;
+		/*
+		 * Some PHYs react badly if SStatus is pounded
+		 * immediately after resuming.  Delay 200ms before
+		 * debouncing.
+		 */
+		msleep(200);
 
-	if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
-		return rc;
+		/* is SControl restored correctly? */
+		if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
+			return rc;
+	} while ((scontrol & 0xf0f) != 0x300 && --tries);
 
-	/* Some PHYs react badly if SStatus is pounded immediately
-	 * after resuming.  Delay 200ms before debouncing.
-	 */
-	msleep(200);
+	if ((scontrol & 0xf0f) != 0x300) {
+		ata_link_printk(link, KERN_ERR,
+				"failed to resume link (SControl %X)\n",
+				scontrol);
+		return 0;
+	}
+
+	if (tries < ATA_LINK_RESUME_TRIES)
+		ata_link_printk(link, KERN_WARNING,
+				"link resume succeeded after %d retries\n",
+				ATA_LINK_RESUME_TRIES - tries);
 
 	if ((rc = sata_link_debounce(link, params, deadline)))
 		return rc;
@@ -6616,6 +6640,13 @@ static int __init ata_init(void)
 {
 	ata_parse_force_param();
 
+	/*
+	 * FIXME: In UP case, there is only one workqueue thread and if you
+	 * have more than one PIO device, latency is bloody awful, with
+	 * occasional multi-second "hiccups" as one PIO device waits for
+	 * another.  It's an ugly wart that users DO occasionally complain
+	 * about; luckily most users have at most one PIO polled device.
+	 */
 	ata_wq = create_workqueue("ata");
 	if (!ata_wq)
 		goto free_force_tbl;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/libata-eh.c linux-libre-2.6.33-gnu1/drivers/ata/libata-eh.c
--- linux-libre-2.6.32-gnu1/drivers/ata/libata-eh.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/libata-eh.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,6 +110,13 @@ static const unsigned long ata_eh_identi
 	ULONG_MAX,
 };
 
+static const unsigned long ata_eh_flush_timeouts[] = {
+	15000,	/* be generous with flush */
+	15000,  /* ditto */
+	30000,	/* and even more generous */
+	ULONG_MAX,
+};
+
 static const unsigned long ata_eh_other_timeouts[] = {
 	 5000,	/* same rationale as identify timeout */
 	10000,	/* ditto */
@@ -147,6 +154,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIME
 	  .timeouts = ata_eh_other_timeouts, },
 	{ .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS),
 	  .timeouts = ata_eh_other_timeouts, },
+	{ .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT),
+	  .timeouts = ata_eh_flush_timeouts },
 };
 #undef CMDS
 
@@ -2019,8 +2028,9 @@ static void ata_eh_link_autopsy(struct a
 			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
 
 		/* determine whether the command is worth retrying */
-		if (!(qc->err_mask & AC_ERR_INVALID) &&
-		    ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV))
+		if (qc->flags & ATA_QCFLAG_IO ||
+		    (!(qc->err_mask & AC_ERR_INVALID) &&
+		     qc->err_mask != AC_ERR_DEV))
 			qc->flags |= ATA_QCFLAG_RETRY;
 
 		/* accumulate error info */
@@ -3112,6 +3122,82 @@ static int atapi_eh_clear_ua(struct ata_
 	return 0;
 }
 
+/**
+ *	ata_eh_maybe_retry_flush - Retry FLUSH if necessary
+ *	@dev: ATA device which may need FLUSH retry
+ *
+ *	If @dev failed FLUSH, it needs to be reported upper layer
+ *	immediately as it means that @dev failed to remap and already
+ *	lost at least a sector and further FLUSH retrials won't make
+ *	any difference to the lost sector.  However, if FLUSH failed
+ *	for other reasons, for example transmission error, FLUSH needs
+ *	to be retried.
+ *
+ *	This function determines whether FLUSH failure retry is
+ *	necessary and performs it if so.
+ *
+ *	RETURNS:
+ *	0 if EH can continue, -errno if EH needs to be repeated.
+ */
+static int ata_eh_maybe_retry_flush(struct ata_device *dev)
+{
+	struct ata_link *link = dev->link;
+	struct ata_port *ap = link->ap;
+	struct ata_queued_cmd *qc;
+	struct ata_taskfile tf;
+	unsigned int err_mask;
+	int rc = 0;
+
+	/* did flush fail for this device? */
+	if (!ata_tag_valid(link->active_tag))
+		return 0;
+
+	qc = __ata_qc_from_tag(ap, link->active_tag);
+	if (qc->dev != dev || (qc->tf.command != ATA_CMD_FLUSH_EXT &&
+			       qc->tf.command != ATA_CMD_FLUSH))
+		return 0;
+
+	/* if the device failed it, it should be reported to upper layers */
+	if (qc->err_mask & AC_ERR_DEV)
+		return 0;
+
+	/* flush failed for some other reason, give it another shot */
+	ata_tf_init(dev, &tf);
+
+	tf.command = qc->tf.command;
+	tf.flags |= ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+
+	ata_dev_printk(dev, KERN_WARNING, "retrying FLUSH 0x%x Emask 0x%x\n",
+		       tf.command, qc->err_mask);
+
+	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
+	if (!err_mask) {
+		/*
+		 * FLUSH is complete but there's no way to
+		 * successfully complete a failed command from EH.
+		 * Making sure retry is allowed at least once and
+		 * retrying it should do the trick - whatever was in
+		 * the cache is already on the platter and this won't
+		 * cause infinite loop.
+		 */
+		qc->scsicmd->allowed = max(qc->scsicmd->allowed, 1);
+	} else {
+		ata_dev_printk(dev, KERN_WARNING, "FLUSH failed Emask 0x%x\n",
+			       err_mask);
+		rc = -EIO;
+
+		/* if device failed it, report it to upper layers */
+		if (err_mask & AC_ERR_DEV) {
+			qc->err_mask |= AC_ERR_DEV;
+			qc->result_tf = tf;
+			if (!(ap->pflags & ATA_PFLAG_FROZEN))
+				rc = 0;
+		}
+	}
+	return rc;
+}
+
 static int ata_link_nr_enabled(struct ata_link *link)
 {
 	struct ata_device *dev;
@@ -3455,6 +3541,15 @@ int ata_eh_recover(struct ata_port *ap,
 			}
 		}
 
+		/* retry flush if necessary */
+		ata_for_each_dev(dev, link, ALL) {
+			if (dev->class != ATA_DEV_ATA)
+				continue;
+			rc = ata_eh_maybe_retry_flush(dev);
+			if (rc)
+				goto dev_fail;
+		}
+
 		/* configure link power saving */
 		if (ehc->i.action & ATA_EH_LPM)
 			ata_for_each_dev(dev, link, ALL)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/libata-scsi.c linux-libre-2.6.33-gnu1/drivers/ata/libata-scsi.c
--- linux-libre-2.6.32-gnu1/drivers/ata/libata-scsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/libata-scsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,7 @@
 #include <linux/hdreg.h>
 #include <linux/uaccess.h>
 #include <linux/suspend.h>
+#include <asm/unaligned.h>
 
 #include "libata.h"
 
@@ -154,8 +155,7 @@ static ssize_t ata_scsi_lpm_put(struct d
 	 */
 	for (i = 1; i < ARRAY_SIZE(link_pm_policy); i++) {
 		const int len = strlen(link_pm_policy[i].name);
-		if (strncmp(link_pm_policy[i].name, buf, len) == 0 &&
-		   buf[len] == '\n') {
+		if (strncmp(link_pm_policy[i].name, buf, len) == 0) {
 			policy = link_pm_policy[i].value;
 			break;
 		}
@@ -1208,6 +1208,7 @@ void ata_scsi_slave_destroy(struct scsi_
  *	ata_scsi_change_queue_depth - SCSI callback for queue depth config
  *	@sdev: SCSI device to configure queue depth for
  *	@queue_depth: new queue depth
+ *	@reason: calling context
  *
  *	This is libata standard hostt->change_queue_depth callback.
  *	SCSI will call into this callback when user tries to set queue
@@ -1219,12 +1220,16 @@ void ata_scsi_slave_destroy(struct scsi_
  *	RETURNS:
  *	Newly configured queue depth.
  */
-int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				int reason)
 {
 	struct ata_port *ap = ata_shost_to_port(sdev->host);
 	struct ata_device *dev;
 	unsigned long flags;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth < 1 || queue_depth == sdev->queue_depth)
 		return sdev->queue_depth;
 
@@ -1964,6 +1969,7 @@ static unsigned int ata_scsiop_inq_00(st
 		0x80,	/* page 0x80, unit serial no page */
 		0x83,	/* page 0x83, device ident page */
 		0x89,	/* page 0x89, ata info page */
+		0xb0,	/* page 0xb0, block limits page */
 		0xb1,	/* page 0xb1, block device characteristics page */
 	};
 
@@ -2085,6 +2091,43 @@ static unsigned int ata_scsiop_inq_89(st
 	return 0;
 }
 
+static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
+{
+	u32 min_io_sectors;
+
+	rbuf[1] = 0xb0;
+	rbuf[3] = 0x3c;		/* required VPD size with unmap support */
+
+	/*
+	 * Optimal transfer length granularity.
+	 *
+	 * This is always one physical block, but for disks with a smaller
+	 * logical than physical sector size we need to figure out what the
+	 * latter is.
+	 */
+	if (ata_id_has_large_logical_sectors(args->id))
+		min_io_sectors = ata_id_logical_per_physical_sectors(args->id);
+	else
+		min_io_sectors = 1;
+	put_unaligned_be16(min_io_sectors, &rbuf[6]);
+
+	/*
+	 * Optimal unmap granularity.
+	 *
+	 * The ATA spec doesn't even know about a granularity or alignment
+	 * for the TRIM command.  We can leave away most of the unmap related
+	 * VPD page entries, but we have specifify a granularity to signal
+	 * that we support some form of unmap - in thise case via WRITE SAME
+	 * with the unmap bit set.
+	 */
+	if (ata_id_has_trim(args->id)) {
+		put_unaligned_be32(65535 * 512 / 8, &rbuf[20]);
+		put_unaligned_be32(1, &rbuf[28]);
+	}
+
+	return 0;
+}
+
 static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
 {
 	int form_factor = ata_id_form_factor(args->id);
@@ -2374,6 +2417,13 @@ static unsigned int ata_scsiop_read_cap(
 		rbuf[13] = log_per_phys;
 		rbuf[14] = (lowest_aligned >> 8) & 0x3f;
 		rbuf[15] = lowest_aligned;
+
+		if (ata_id_has_trim(args->id)) {
+			rbuf[14] |= 0x80; /* TPE */
+
+			if (ata_id_has_zero_after_trim(args->id))
+				rbuf[14] |= 0x40; /* TPRZ */
+		}
 	}
 
 	return 0;
@@ -2825,7 +2875,7 @@ static unsigned int ata_scsi_pass_thru(s
 	 * write indication (used for PIO/DMA setup), result TF is
 	 * copied back and we don't whine too much about its failure.
 	 */
-	tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	if (scmd->sc_data_direction == DMA_TO_DEVICE)
 		tf->flags |= ATA_TFLAG_WRITE;
 
@@ -2896,6 +2946,58 @@ static unsigned int ata_scsi_pass_thru(s
 	return 1;
 }
 
+static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *tf = &qc->tf;
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	struct ata_device *dev = qc->dev;
+	const u8 *cdb = scmd->cmnd;
+	u64 block;
+	u32 n_block;
+	u32 size;
+	void *buf;
+
+	/* we may not issue DMA commands if no DMA mode is set */
+	if (unlikely(!dev->dma_mode))
+		goto invalid_fld;
+
+	if (unlikely(scmd->cmd_len < 16))
+		goto invalid_fld;
+	scsi_16_lba_len(cdb, &block, &n_block);
+
+	/* for now we only support WRITE SAME with the unmap bit set */
+	if (unlikely(!(cdb[1] & 0x8)))
+		goto invalid_fld;
+
+	/*
+	 * WRITE SAME always has a sector sized buffer as payload, this
+	 * should never be a multiple entry S/G list.
+	 */
+	if (!scsi_sg_count(scmd))
+		goto invalid_fld;
+
+	buf = page_address(sg_page(scsi_sglist(scmd)));
+	size = ata_set_lba_range_entries(buf, 512, block, n_block);
+
+	tf->protocol = ATA_PROT_DMA;
+	tf->hob_feature = 0;
+	tf->feature = ATA_DSM_TRIM;
+	tf->hob_nsect = (size / 512) >> 8;
+	tf->nsect = size / 512;
+	tf->command = ATA_CMD_DSM;
+	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
+		     ATA_TFLAG_WRITE;
+
+	ata_qc_set_pc_nbytes(qc);
+
+	return 0;
+
+ invalid_fld:
+	ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
+	/* "Invalid field in cdb" */
+	return 1;
+}
+
 /**
  *	ata_get_xlat_func - check if SCSI to ATA translation is possible
  *	@dev: ATA device
@@ -2920,6 +3022,9 @@ static inline ata_xlat_func_t ata_get_xl
 	case WRITE_16:
 		return ata_scsi_rw_xlat;
 
+	case WRITE_SAME_16:
+		return ata_scsi_write_same_xlat;
+
 	case SYNCHRONIZE_CACHE:
 		if (ata_try_flush_cache(dev))
 			return ata_scsi_flush_xlat;
@@ -3109,6 +3214,9 @@ void ata_scsi_simulate(struct ata_device
 		case 0x89:
 			ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
 			break;
+		case 0xb0:
+			ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b0);
+			break;
 		case 0xb1:
 			ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1);
 			break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/libata-sff.c linux-libre-2.6.33-gnu1/drivers/ata/libata-sff.c
--- linux-libre-2.6.32-gnu1/drivers/ata/libata-sff.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/libata-sff.c	2010-02-24 13:52:17.000000000 -0500
@@ -736,7 +736,7 @@ unsigned int ata_sff_data_xfer(struct at
 
 		/*
 		 * Use io*16_rep() accessors here as well to avoid pointlessly
-		 * swapping bytes to and fro on the big endian machines...
+		 * swapping bytes to and from on the big endian machines...
 		 */
 		if (rw == READ) {
 			ioread16_rep(data_addr, pad, 1);
@@ -776,7 +776,7 @@ unsigned int ata_sff_data_xfer32(struct
 	void __iomem *data_addr = ap->ioaddr.data_addr;
 	unsigned int words = buflen >> 2;
 	int slop = buflen & 3;
-	
+
 	if (!(ap->pflags & ATA_PFLAG_PIO32))
 		return ata_sff_data_xfer(dev, buf, buflen, rw);
 
@@ -795,7 +795,7 @@ unsigned int ata_sff_data_xfer32(struct
 
 		/*
 		 * Use io*_rep() accessors here as well to avoid pointlessly
-		 * swapping bytes to and fro on the big endian machines...
+		 * swapping bytes to and from on the big endian machines...
 		 */
 		if (rw == READ) {
 			if (slop < 3)
@@ -893,6 +893,9 @@ static void ata_pio_sector(struct ata_qu
 				       do_write);
 	}
 
+	if (!do_write)
+		flush_dcache_page(page);
+
 	qc->curbytes += qc->sect_size;
 	qc->cursg_ofs += qc->sect_size;
 
@@ -2275,7 +2278,7 @@ void ata_sff_drain_fifo(struct ata_queue
 	ap = qc->ap;
 	/* Drain up to 64K of data before we give up this recovery method */
 	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
-						&& count < 32768; count++)
+						&& count < 65536; count += 2)
 		ioread16(ap->ioaddr.data_addr);
 
 	/* Can become DEBUG later */
@@ -2384,7 +2387,7 @@ void ata_sff_post_internal_cmd(struct at
 	ap->hsm_task_state = HSM_ST_IDLE;
 
 	if (ap->ioaddr.bmdma_addr)
-		ata_bmdma_stop(qc);
+		ap->ops->bmdma_stop(qc);
 
 	spin_unlock_irqrestore(ap->lock, flags);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/Makefile linux-libre-2.6.33-gnu1/drivers/ata/Makefile
--- linux-libre-2.6.32-gnu1/drivers/ata/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@ obj-$(CONFIG_SATA_MV)		+= sata_mv.o
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
 obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
+obj-$(CONFIG_PATA_MACIO)	+= pata_macio.o
 
 obj-$(CONFIG_PATA_ALI)		+= pata_ali.o
 obj-$(CONFIG_PATA_AMD)		+= pata_amd.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_PATA_RZ1000)	+= pata_rz1000
 obj-$(CONFIG_PATA_SC1200)	+= pata_sc1200.o
 obj-$(CONFIG_PATA_SERVERWORKS)	+= pata_serverworks.o
 obj-$(CONFIG_PATA_SIL680)	+= pata_sil680.o
+obj-$(CONFIG_PATA_TOSHIBA)	+= pata_piccolo.o
 obj-$(CONFIG_PATA_VIA)		+= pata_via.o
 obj-$(CONFIG_PATA_WINBOND)	+= pata_sl82c105.o
 obj-$(CONFIG_PATA_WINBOND_VLB)	+= pata_winbond.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_ali.c linux-libre-2.6.33-gnu1/drivers/ata/pata_ali.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_ali.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_ali.c	2010-02-24 13:52:17.000000000 -0500
@@ -453,7 +453,9 @@ static void ali_init_chipset(struct pci_
 			/* Clear CD-ROM DMA write bit */
 			tmp &= 0x7F;
 		/* Cable and UDMA */
-		pci_write_config_byte(pdev, 0x4B, tmp | 0x09);
+		if (pdev->revision >= 0xc2)
+			tmp |= 0x01;
+		pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
 		/*
 		 * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
 		 * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_bf54x.c linux-libre-2.6.33-gnu1/drivers/ata/pata_bf54x.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_bf54x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_bf54x.c	2010-02-24 13:52:17.000000000 -0500
@@ -1557,6 +1557,25 @@ static unsigned short atapi_io_port[] =
 	P_ATAPI_DMARQ,
 	P_ATAPI_INTRQ,
 	P_ATAPI_IORDY,
+	P_ATAPI_D0A,
+	P_ATAPI_D1A,
+	P_ATAPI_D2A,
+	P_ATAPI_D3A,
+	P_ATAPI_D4A,
+	P_ATAPI_D5A,
+	P_ATAPI_D6A,
+	P_ATAPI_D7A,
+	P_ATAPI_D8A,
+	P_ATAPI_D9A,
+	P_ATAPI_D10A,
+	P_ATAPI_D11A,
+	P_ATAPI_D12A,
+	P_ATAPI_D13A,
+	P_ATAPI_D14A,
+	P_ATAPI_D15A,
+	P_ATAPI_A0A,
+	P_ATAPI_A1A,
+	P_ATAPI_A2A,
 	0
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_cmd64x.c linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd64x.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_cmd64x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_cmd64x.c	2010-02-24 13:52:17.000000000 -0500
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct at
 		regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
 		/* Merge the control bits */
 		regU |= 1 << adev->devno; /* UDMA on */
-		if (adev->dma_mode > 2)	/* 15nS timing */
+		if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
 			regU |= 4 << adev->devno;
 	} else {
 		regU &= ~ (1 << adev->devno);	/* UDMA off */
@@ -294,8 +294,6 @@ static struct ata_port_operations cmd648
 
 static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	u32 class_rev;
-
 	static const struct ata_port_info cmd_info[6] = {
 		{	/* CMD 643 - no UDMA */
 			.flags = ATA_FLAG_SLAVE_POSS,
@@ -345,18 +343,15 @@ static int cmd64x_init_one(struct pci_de
 	if (rc)
 		return rc;
 
-	pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xFF;
-
 	if (id->driver_data == 0)	/* 643 */
 		ata_pci_bmdma_clear_simplex(pdev);
 
 	if (pdev->device == PCI_DEVICE_ID_CMD_646) {
 		/* Does UDMA work ? */
-		if (class_rev > 4)
+		if (pdev->revision > 4)
 			ppi[0] = &cmd_info[2];
 		/* Early rev with other problems ? */
-		else if (class_rev == 1)
+		else if (pdev->revision == 1)
 			ppi[0] = &cmd_info[3];
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5520.c linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5520.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5520.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5520.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,48 +90,12 @@ static void cs5520_set_timings(struct at
 }
 
 /**
- *	cs5520_enable_dma	-	turn on DMA bits
- *
- *	Turn on the DMA bits for this disk. Needed because the BIOS probably
- *	has not done the work for us. Belongs in the core SATA code.
- */
-
-static void cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev)
-{
-	/* Set the DMA enable/disable flag */
-	u8 reg = ioread8(ap->ioaddr.bmdma_addr + 0x02);
-	reg |= 1<<(adev->devno + 5);
-	iowrite8(reg, ap->ioaddr.bmdma_addr + 0x02);
-}
-
-/**
- *	cs5520_set_dmamode	-	program DMA timings
- *	@ap: ATA port
- *	@adev: ATA device
- *
- *	Program the DMA mode timings for the controller according to the pio
- *	clocking table. Note that this device sets the DMA timings to PIO
- *	mode values. This may seem bizarre but the 5520 architecture talks
- *	PIO mode to the disk and DMA mode to the controller so the underlying
- *	transfers are PIO timed.
- */
-
-static void cs5520_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
-	static const int dma_xlate[3] = { XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 };
-	cs5520_set_timings(ap, adev, dma_xlate[adev->dma_mode]);
-	cs5520_enable_dma(ap, adev);
-}
-
-/**
  *	cs5520_set_piomode	-	program PIO timings
  *	@ap: ATA port
  *	@adev: ATA device
  *
  *	Program the PIO mode timings for the controller according to the pio
- *	clocking table. We know pio_mode will equal dma_mode because of the
- *	CS5520 architecture. At least once we turned DMA on and wrote a
- *	mode setter.
+ *	clocking table.
  */
 
 static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -149,7 +113,6 @@ static struct ata_port_operations cs5520
 	.qc_prep		= ata_sff_dumb_qc_prep,
 	.cable_detect		= ata_cable_40wire,
 	.set_piomode		= cs5520_set_piomode,
-	.set_dmamode		= cs5520_set_dmamode,
 };
 
 static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5535.c linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5535.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5535.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5535.c	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@
  *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
  *
  * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and
- * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de
+ * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
  * and Alexander Kiausch <alex.kiausch@t-online.de>
  *
  * This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5536.c linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5536.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_cs5536.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_cs5536.c	2010-02-24 13:52:17.000000000 -0500
@@ -224,7 +224,7 @@ static struct scsi_host_template cs5536_
 };
 
 static struct ata_port_operations cs5536_port_ops = {
-	.inherits		= &ata_bmdma_port_ops,
+	.inherits		= &ata_bmdma32_port_ops,
 	.cable_detect		= cs5536_cable_detect,
 	.set_piomode		= cs5536_set_piomode,
 	.set_dmamode		= cs5536_set_dmamode,
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_efar.c linux-libre-2.6.33-gnu1/drivers/ata/pata_efar.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_efar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_efar.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
  *    pata_efar.c - EFAR PIIX clone controller driver
  *
  *	(C) 2005 Red Hat
+ *	(C) 2009 Bartlomiej Zolnierkiewicz
  *
  *    Some parts based on ata_piix.c by Jeff Garzik and others.
  *
@@ -118,12 +119,12 @@ static void efar_set_piomode (struct ata
 		int shift = 4 * ap->port_no;
 		u8 slave_data;
 
-		idetm_data &= 0xCC0F;
+		idetm_data &= 0xFF0F;
 		idetm_data |= (control << 4);
 
 		/* Slave timing in separate register */
 		pci_read_config_byte(dev, 0x44, &slave_data);
-		slave_data &= 0x0F << shift;
+		slave_data &= ap->port_no ? 0x0F : 0xF0;
 		slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << shift;
 		pci_write_config_byte(dev, 0x44, slave_data);
 	}
@@ -200,7 +201,7 @@ static void efar_set_dmamode (struct ata
 			master_data &= 0xFF4F;  /* Mask out IORDY|TIME1|DMAONLY */
 			master_data |= control << 4;
 			pci_read_config_byte(dev, 0x44, &slave_data);
-			slave_data &= (0x0F + 0xE1 * ap->port_no);
+			slave_data &= ap->port_no ? 0x0F : 0xF0;
 			/* Load the matching timing */
 			slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
 			pci_write_config_byte(dev, 0x44, slave_data);
@@ -251,7 +252,7 @@ static int efar_init_one (struct pci_dev
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= ATA_PIO4,
-		.mwdma_mask	= ATA_MWDMA2,
+		.mwdma_mask	= ATA_MWDMA12_ONLY,
 		.udma_mask 	= ATA_UDMA4,
 		.port_ops	= &efar_ops,
 	};
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt366.c linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt366.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt366.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt366.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt366"
-#define DRV_VERSION	"0.6.2"
+#define DRV_VERSION	"0.6.7"
 
 struct hpt_clock {
 	u8	xfer_mode;
@@ -36,24 +36,22 @@ struct hpt_clock {
 
 /* key for bus clock timings
  * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
+ * 0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 4:7    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ *        cycles = value + 1
+ * 8:11   cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
  *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
+ * 12:15  cmd_low_time. Active time of DIOW_/DIOR_ during task file
  *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
+ * 16:18  udma_cycle_time. Clock cycles for UDMA xfer?
+ * 19:21  pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer.
+ * 22:24  cmd_pre_high_time. Time to initialize 1st PIO cycle for task file
  *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
+ * 28     UDMA enable.
+ * 29     DMA  enable.
+ * 30     PIO_MST enable. If set, the chip is in bus master mode during
+ *        PIO xfer.
  * 31     FIFO enable.
  */
 
@@ -344,7 +342,6 @@ static int hpt36x_init_one(struct pci_de
 	const struct ata_port_info *ppi[] = { &info_hpt366, NULL };
 
 	void *hpriv = NULL;
-	u32 class_rev;
 	u32 reg1;
 	int rc;
 
@@ -352,13 +349,10 @@ static int hpt36x_init_one(struct pci_de
 	if (rc)
 		return rc;
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xFF;
-
 	/* May be a later chip in disguise. Check */
 	/* Newer chips are not in the HPT36x driver. Ignore them */
-	if (class_rev > 2)
-			return -ENODEV;
+	if (dev->revision > 2)
+		return -ENODEV;
 
 	hpt36x_init_chipset(dev);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt37x.c linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt37x.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt37x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt37x.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt37x"
-#define DRV_VERSION	"0.6.12"
+#define DRV_VERSION	"0.6.14"
 
 struct hpt_clock {
 	u8	xfer_speed;
@@ -303,72 +303,79 @@ static unsigned long hpt370a_filter(stru
 }
 
 /**
- *	hpt37x_pre_reset	-	reset the hpt37x bus
- *	@link: ATA link to reset
- *	@deadline: deadline jiffies for the operation
+ *	hpt37x_cable_detect	-	Detect the cable type
+ *	@ap: ATA port to detect on
  *
- *	Perform the initial reset handling for the 370/372 and 374 func 0
+ *	Return the cable type attached to this port
  */
 
-static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
+static int hpt37x_cable_detect(struct ata_port *ap)
 {
-	u8 scr2, ata66;
-	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	static const struct pci_bits hpt37x_enable_bits[] = {
-		{ 0x50, 1, 0x04, 0x04 },
-		{ 0x54, 1, 0x04, 0x04 }
-	};
-	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
-		return -ENOENT;
+	u8 scr2, ata66;
 
 	pci_read_config_byte(pdev, 0x5B, &scr2);
 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
+
+	udelay(10); /* debounce */
+
 	/* Cable register now active */
 	pci_read_config_byte(pdev, 0x5A, &ata66);
 	/* Restore state */
 	pci_write_config_byte(pdev, 0x5B, scr2);
 
 	if (ata66 & (2 >> ap->port_no))
-		ap->cbl = ATA_CBL_PATA40;
+		return ATA_CBL_PATA40;
 	else
-		ap->cbl = ATA_CBL_PATA80;
-
-	/* Reset the state machine */
-	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
-	udelay(100);
-
-	return ata_sff_prereset(link, deadline);
+		return ATA_CBL_PATA80;
 }
 
-static int hpt374_fn1_pre_reset(struct ata_link *link, unsigned long deadline)
+/**
+ *	hpt374_fn1_cable_detect	-	Detect the cable type
+ *	@ap: ATA port to detect on
+ *
+ *	Return the cable type attached to this port
+ */
+
+static int hpt374_fn1_cable_detect(struct ata_port *ap)
 {
-	static const struct pci_bits hpt37x_enable_bits[] = {
-		{ 0x50, 1, 0x04, 0x04 },
-		{ 0x54, 1, 0x04, 0x04 }
-	};
-	u16 mcr3;
-	u8 ata66;
-	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	unsigned int mcrbase = 0x50 + 4 * ap->port_no;
-
-	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
-		return -ENOENT;
+	u16 mcr3;
+	u8 ata66;
 
 	/* Do the extra channel work */
 	pci_read_config_word(pdev, mcrbase + 2, &mcr3);
-	/* Set bit 15 of 0x52 to enable TCBLID as input
-	 */
+	/* Set bit 15 of 0x52 to enable TCBLID as input */
 	pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000);
 	pci_read_config_byte(pdev, 0x5A, &ata66);
 	/* Reset TCBLID/FCBLID to output */
 	pci_write_config_word(pdev, mcrbase + 2, mcr3);
 
 	if (ata66 & (2 >> ap->port_no))
-		ap->cbl = ATA_CBL_PATA40;
+		return ATA_CBL_PATA40;
 	else
-		ap->cbl = ATA_CBL_PATA80;
+		return ATA_CBL_PATA80;
+}
+
+/**
+ *	hpt37x_pre_reset	-	reset the hpt37x bus
+ *	@link: ATA link to reset
+ *	@deadline: deadline jiffies for the operation
+ *
+ *	Perform the initial reset handling for the HPT37x.
+ */
+
+static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	static const struct pci_bits hpt37x_enable_bits[] = {
+		{ 0x50, 1, 0x04, 0x04 },
+		{ 0x54, 1, 0x04, 0x04 }
+	};
+	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
+		return -ENOENT;
 
 	/* Reset the state machine */
 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
@@ -404,9 +411,8 @@ static void hpt370_set_piomode(struct at
 
 	pci_read_config_dword(pdev, addr1, &reg);
 	mode = hpt37x_find_mode(ap, adev->pio_mode);
-	mode &= ~0x8000000;	/* No FIFO in PIO */
-	mode &= ~0x30070000;	/* Leave config bits alone */
-	reg &= 0x30070000;	/* Strip timing bits */
+	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
+	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -423,8 +429,7 @@ static void hpt370_set_dmamode(struct at
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, mode, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -436,11 +441,12 @@ static void hpt370_set_dmamode(struct at
 	fast |= 0x01;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+
 	pci_read_config_dword(pdev, addr1, &reg);
 	mode = hpt37x_find_mode(ap, adev->dma_mode);
-	mode |= 0x8000000;	/* FIFO in MWDMA or UDMA */
-	mode &= ~0xC0000000;	/* Leave config bits alone */
-	reg &= 0xC0000000;	/* Strip timing bits */
+	mode &= mask;
+	reg &= ~mask;
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -508,9 +514,8 @@ static void hpt372_set_piomode(struct at
 	mode = hpt37x_find_mode(ap, adev->pio_mode);
 
 	printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
-	mode &= ~0x80000000;	/* No FIFO in PIO */
-	mode &= ~0x30070000;	/* Leave config bits alone */
-	reg &= 0x30070000;	/* Strip timing bits */
+	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
+	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -527,8 +532,7 @@ static void hpt372_set_dmamode(struct at
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, mode, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -539,12 +543,13 @@ static void hpt372_set_dmamode(struct at
 	fast &= ~0x07;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+
 	pci_read_config_dword(pdev, addr1, &reg);
 	mode = hpt37x_find_mode(ap, adev->dma_mode);
 	printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
-	mode &= ~0xC0000000;	/* Leave config bits alone */
-	mode |= 0x80000000;	/* FIFO in MWDMA or UDMA */
-	reg &= 0xC0000000;	/* Strip timing bits */
+	mode &= mask;
+	reg &= ~mask;
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -584,6 +589,7 @@ static struct ata_port_operations hpt370
 	.bmdma_stop	= hpt370_bmdma_stop,
 
 	.mode_filter	= hpt370_filter,
+	.cable_detect	= hpt37x_cable_detect,
 	.set_piomode	= hpt370_set_piomode,
 	.set_dmamode	= hpt370_set_dmamode,
 	.prereset	= hpt37x_pre_reset,
@@ -608,6 +614,7 @@ static struct ata_port_operations hpt372
 
 	.bmdma_stop	= hpt37x_bmdma_stop,
 
+	.cable_detect	= hpt37x_cable_detect,
 	.set_piomode	= hpt372_set_piomode,
 	.set_dmamode	= hpt372_set_dmamode,
 	.prereset	= hpt37x_pre_reset,
@@ -620,7 +627,8 @@ static struct ata_port_operations hpt372
 
 static struct ata_port_operations hpt374_fn1_port_ops = {
 	.inherits	= &hpt372_port_ops,
-	.prereset	= hpt374_fn1_pre_reset,
+	.cable_detect	= hpt374_fn1_cable_detect,
+	.prereset	= hpt37x_pre_reset,
 };
 
 /**
@@ -791,9 +799,8 @@ static int hpt37x_init_one(struct pci_de
 	static const int MHz[4] = { 33, 40, 50, 66 };
 	void *private_data = NULL;
 	const struct ata_port_info *ppi[] = { NULL, NULL };
-
+	u8 rev = dev->revision;
 	u8 irqmask;
-	u32 class_rev;
 	u8 mcr1;
 	u32 freq;
 	int prefer_dpll = 1;
@@ -808,19 +815,16 @@ static int hpt37x_init_one(struct pci_de
 	if (rc)
 		return rc;
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xFF;
-
 	if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
 		/* May be a later chip in disguise. Check */
 		/* Older chips are in the HPT366 driver. Ignore them */
-		if (class_rev < 3)
+		if (rev < 3)
 			return -ENODEV;
 		/* N series chips have their own driver. Ignore */
-		if (class_rev == 6)
+		if (rev == 6)
 			return -ENODEV;
 
-		switch(class_rev) {
+		switch(rev) {
 			case 3:
 				ppi[0] = &info_hpt370;
 				chip_table = &hpt370;
@@ -836,28 +840,29 @@ static int hpt37x_init_one(struct pci_de
 				chip_table = &hpt372;
 				break;
 			default:
-				printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev);
+				printk(KERN_ERR "pata_hpt37x: Unknown HPT366 "
+				       "subtype, please report (%d).\n", rev);
 				return -ENODEV;
 		}
 	} else {
 		switch(dev->device) {
 			case PCI_DEVICE_ID_TTI_HPT372:
 				/* 372N if rev >= 2*/
-				if (class_rev >= 2)
+				if (rev >= 2)
 					return -ENODEV;
 				ppi[0] = &info_hpt372;
 				chip_table = &hpt372a;
 				break;
 			case PCI_DEVICE_ID_TTI_HPT302:
 				/* 302N if rev > 1 */
-				if (class_rev > 1)
+				if (rev > 1)
 					return -ENODEV;
 				ppi[0] = &info_hpt372;
 				/* Check this */
 				chip_table = &hpt302;
 				break;
 			case PCI_DEVICE_ID_TTI_HPT371:
-				if (class_rev > 1)
+				if (rev > 1)
 					return -ENODEV;
 				ppi[0] = &info_hpt372;
 				chip_table = &hpt371;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt3x2n.c linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x2n.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt3x2n.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x2n.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2003		Red Hat Inc
- * Portions Copyright (C) 2005-2007	MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009	MontaVista Software, Inc.
  *
  *
  * TODO
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt3x2n"
-#define DRV_VERSION	"0.3.4"
+#define DRV_VERSION	"0.3.8"
 
 enum {
 	HPT_PCI_FAST	=	(1 << 31),
@@ -80,14 +80,13 @@ static struct hpt_clock hpt3x2n_clocks[]
 
 	{	XFER_MW_DMA_2,	0x2c829c62	},
 	{	XFER_MW_DMA_1,	0x2c829c66	},
-	{	XFER_MW_DMA_0,	0x2c829d2c	},
+	{	XFER_MW_DMA_0,	0x2c829d2e	},
 
 	{	XFER_PIO_4,	0x0c829c62	},
 	{	XFER_PIO_3,	0x0c829c84	},
 	{	XFER_PIO_2,	0x0c829ca6	},
 	{	XFER_PIO_1,	0x0d029d26	},
 	{	XFER_PIO_0,	0x0d029d5e	},
-	{	0,		0x0d029d5e	}
 };
 
 /**
@@ -128,12 +127,15 @@ static int hpt3x2n_cable_detect(struct a
 
 	pci_read_config_byte(pdev, 0x5B, &scr2);
 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
+
+	udelay(10); /* debounce */
+
 	/* Cable register now active */
 	pci_read_config_byte(pdev, 0x5A, &ata66);
 	/* Restore state */
 	pci_write_config_byte(pdev, 0x5B, scr2);
 
-	if (ata66 & (1 << ap->port_no))
+	if (ata66 & (2 >> ap->port_no))
 		return ATA_CBL_PATA40;
 	else
 		return ATA_CBL_PATA80;
@@ -185,9 +187,8 @@ static void hpt3x2n_set_piomode(struct a
 
 	pci_read_config_dword(pdev, addr1, &reg);
 	mode = hpt3x2n_find_mode(ap, adev->pio_mode);
-	mode &= ~0x8000000;	/* No FIFO in PIO */
-	mode &= ~0x30070000;	/* Leave config bits alone */
-	reg &= 0x30070000;	/* Strip timing bits */
+	mode &= 0xCFC3FFFF;	/* Leave DMA bits alone */
+	reg &= ~0xCFC3FFFF;	/* Strip timing bits */
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -204,8 +205,7 @@ static void hpt3x2n_set_dmamode(struct a
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 addr1, addr2;
-	u32 reg;
-	u32 mode;
+	u32 reg, mode, mask;
 	u8 fast;
 
 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -216,11 +216,12 @@ static void hpt3x2n_set_dmamode(struct a
 	fast &= ~0x07;
 	pci_write_config_byte(pdev, addr2, fast);
 
+	mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
+
 	pci_read_config_dword(pdev, addr1, &reg);
 	mode = hpt3x2n_find_mode(ap, adev->dma_mode);
-	mode |= 0x8000000;	/* FIFO in MWDMA or UDMA */
-	mode &= ~0xC0000000;	/* Leave config bits alone */
-	reg &= 0xC0000000;	/* Strip timing bits */
+	mode &= mask;
+	reg &= ~mask;
 	pci_write_config_dword(pdev, addr1, reg | mode);
 }
 
@@ -263,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct at
 
 static void hpt3x2n_set_clock(struct ata_port *ap, int source)
 {
-	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
+	void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;
 
 	/* Tristate the bus */
 	iowrite8(0x80, bmdma+0x73);
@@ -273,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata
 	iowrite8(source, bmdma+0x7B);
 	iowrite8(0xC0, bmdma+0x79);
 
-	/* Reset state machines */
-	iowrite8(0x37, bmdma+0x70);
-	iowrite8(0x37, bmdma+0x74);
+	/* Reset state machines, avoid enabling the disabled channels */
+	iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
+	iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);
 
 	/* Complete reset */
 	iowrite8(0x00, bmdma+0x79);
@@ -285,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata
 	iowrite8(0x00, bmdma+0x77);
 }
 
-/* Check if our partner interface is busy */
-
-static int hpt3x2n_pair_idle(struct ata_port *ap)
-{
-	struct ata_host *host = ap->host;
-	struct ata_port *pair = host->ports[ap->port_no ^ 1];
-
-	if (pair->hsm_task_state == HSM_ST_IDLE)
-		return 1;
-	return 0;
-}
-
 static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
 {
 	long flags = (long)ap->host->private_data;
+
 	/* See if we should use the DPLL */
 	if (writing)
 		return USE_DPLL;	/* Needed for write */
@@ -308,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_p
 	return 0;
 }
 
+static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct ata_port *alt = ap->host->ports[ap->port_no ^ 1];
+	int rc, flags = (long)ap->host->private_data;
+	int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
+
+	/* First apply the usual rules */
+	rc = ata_std_qc_defer(qc);
+	if (rc != 0)
+		return rc;
+
+	if ((flags & USE_DPLL) != dpll && alt->qc_active)
+		return ATA_DEFER_PORT;
+	return 0;
+}
+
 static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
 {
-	struct ata_taskfile *tf = &qc->tf;
 	struct ata_port *ap = qc->ap;
 	int flags = (long)ap->host->private_data;
+	int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
 
-	if (hpt3x2n_pair_idle(ap)) {
-		int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE));
-		if ((flags & USE_DPLL) != dpll) {
-			if (dpll == 1)
-				hpt3x2n_set_clock(ap, 0x21);
-			else
-				hpt3x2n_set_clock(ap, 0x23);
-		}
+	if ((flags & USE_DPLL) != dpll) {
+		flags &= ~USE_DPLL;
+		flags |= dpll;
+		ap->host->private_data = (void *)(long)flags;
+
+		hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
 	}
 	return ata_sff_qc_issue(qc);
 }
@@ -338,6 +343,8 @@ static struct ata_port_operations hpt3x2
 	.inherits	= &ata_bmdma_port_ops,
 
 	.bmdma_stop	= hpt3x2n_bmdma_stop,
+
+	.qc_defer	= hpt3x2n_qc_defer,
 	.qc_issue	= hpt3x2n_qc_issue,
 
 	.cable_detect	= hpt3x2n_cable_detect,
@@ -447,41 +454,36 @@ static int hpt3x2n_init_one(struct pci_d
 		.port_ops = &hpt3x2n_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
-
+	u8 rev = dev->revision;
 	u8 irqmask;
-	u32 class_rev;
-
 	unsigned int pci_mhz;
 	unsigned int f_low, f_high;
 	int adjust;
 	unsigned long iobase = pci_resource_start(dev, 4);
-	void *hpriv = NULL;
+	void *hpriv = (void *)USE_DPLL;
 	int rc;
 
 	rc = pcim_enable_device(dev);
 	if (rc)
 		return rc;
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xFF;
-
 	switch(dev->device) {
 		case PCI_DEVICE_ID_TTI_HPT366:
-			if (class_rev < 6)
+			if (rev < 6)
 				return -ENODEV;
 			break;
 		case PCI_DEVICE_ID_TTI_HPT371:
-			if (class_rev < 2)
+			if (rev < 2)
 				return -ENODEV;
 			/* 371N if rev > 1 */
 			break;
 		case PCI_DEVICE_ID_TTI_HPT372:
 			/* 372N if rev >= 2*/
-			if (class_rev < 2)
+			if (rev < 2)
 				return -ENODEV;
 			break;
 		case PCI_DEVICE_ID_TTI_HPT302:
-			if (class_rev < 2)
+			if (rev < 2)
 				return -ENODEV;
 			break;
 		case PCI_DEVICE_ID_TTI_HPT372N:
@@ -543,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_d
 	/* Set our private data up. We only need a few flags so we use
 	   it directly */
 	if (pci_mhz > 60) {
-		hpriv = (void *)PCI66;
+		hpriv = (void *)(PCI66 | USE_DPLL);
 		/*
 		 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
 		 * the MISC. register to stretch the UltraDMA Tss timing.
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt3x3.c linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x3.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_hpt3x3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_hpt3x3.c	2010-02-24 13:52:17.000000000 -0500
@@ -255,8 +255,17 @@ 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);
+	int rc;
+
+	rc = ata_pci_device_do_resume(dev);
+	if (rc)
+		return rc;
+
 	hpt3x3_init_chipset(dev);
-	return ata_pci_device_resume(dev);
+
+	ata_host_resume(host);
+	return 0;
 }
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_it8213.c linux-libre-2.6.33-gnu1/drivers/ata/pata_it8213.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_it8213.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_it8213.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,7 @@
 #define DRV_VERSION	"0.0.3"
 
 /**
- *	it8213_pre_reset	-	check for 40/80 pin
+ *	it8213_pre_reset	-	probe begin
  *	@link: link
  *	@deadline: deadline jiffies for the operation
  *
@@ -92,18 +92,17 @@ static void it8213_set_piomode (struct a
 			    { 2, 1 },
 			    { 2, 3 }, };
 
-	if (pio > 2)
-		control |= 1;	/* TIME1 enable */
+	if (pio > 1)
+		control |= 1;	/* TIME */
 	if (ata_pio_need_iordy(adev))	/* PIO 3/4 require IORDY */
-		control |= 2;	/* IORDY enable */
+		control |= 2;	/* IE */
 	/* Bit 2 is set for ATAPI on the IT8213 - reverse of ICH/PIIX */
 	if (adev->class != ATA_DEV_ATA)
-		control |= 4;
+		control |= 4;	/* PPE */
 
 	pci_read_config_word(dev, idetm_port, &idetm_data);
 
-	/* Enable PPE, IE and TIME as appropriate */
-
+	/* Set PPE, IE, and TIME as appropriate */
 	if (adev->devno == 0) {
 		idetm_data &= 0xCCF0;
 		idetm_data |= control;
@@ -112,17 +111,17 @@ static void it8213_set_piomode (struct a
 	} else {
 		u8 slave_data;
 
-		idetm_data &= 0xCC0F;
+		idetm_data &= 0xFF0F;
 		idetm_data |= (control << 4);
 
 		/* Slave timing in separate register */
 		pci_read_config_byte(dev, 0x44, &slave_data);
 		slave_data &= 0xF0;
-		slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << 4;
+		slave_data |= (timings[pio][0] << 2) | timings[pio][1];
 		pci_write_config_byte(dev, 0x44, slave_data);
 	}
 
-	idetm_data |= 0x4000;	/* Ensure SITRE is enabled */
+	idetm_data |= 0x4000;	/* Ensure SITRE is set */
 	pci_write_config_word(dev, idetm_port, idetm_data);
 }
 
@@ -173,10 +172,10 @@ static void it8213_set_dmamode (struct a
 
 		udma_enable |= (1 << devid);
 
-		/* Load the UDMA mode number */
+		/* Load the UDMA cycle time */
 		pci_read_config_word(dev, 0x4A, &udma_timing);
 		udma_timing &= ~(3 << (4 * devid));
-		udma_timing |= (udma & 3) << (4 * devid);
+		udma_timing |= u_speed << (4 * devid);
 		pci_write_config_word(dev, 0x4A, udma_timing);
 
 		/* Load the clock selection */
@@ -211,7 +210,7 @@ static void it8213_set_dmamode (struct a
 			master_data &= 0xFF4F;  /* Mask out IORDY|TIME1|DMAONLY */
 			master_data |= control << 4;
 			pci_read_config_byte(dev, 0x44, &slave_data);
-			slave_data &= (0x0F + 0xE1 * ap->port_no);
+			slave_data &= 0xF0;
 			/* Load the matching timing */
 			slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
 			pci_write_config_byte(dev, 0x44, slave_data);
@@ -263,7 +262,7 @@ static int it8213_init_one (struct pci_d
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= ATA_PIO4,
-		.mwdma_mask	= ATA_MWDMA2,
+		.mwdma_mask	= ATA_MWDMA12_ONLY,
 		.udma_mask 	= ATA_UDMA4, /* FIXME: want UDMA 100? */
 		.port_ops	= &it8213_ops,
 	};
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_it821x.c linux-libre-2.6.33-gnu1/drivers/ata/pata_it821x.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_it821x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_it821x.c	2010-02-24 13:52:17.000000000 -0500
@@ -955,7 +955,7 @@ static int it821x_reinit_one(struct pci_
 static const struct pci_device_id it821x[] = {
 	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
 	{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
-	{ PCI_VDEVICE(RDC, 0x1010), },
+	{ PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), },
 
 	{ },
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_legacy.c linux-libre-2.6.33-gnu1/drivers/ata/pata_legacy.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_legacy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_legacy.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,13 @@
  *		http://www.ryston.cz/petr/vlb/pdc20230b.html
  *		http://www.ryston.cz/petr/vlb/pdc20230c.html
  *		http://www.ryston.cz/petr/vlb/pdc20630.html
+ *	QDI65x0:
+ *		http://www.ryston.cz/petr/vlb/qd6500.html
+ *		http://www.ryston.cz/petr/vlb/qd6580.html
+ *
+ *	QDI65x0 probe code based on drivers/ide/legacy/qd65xx.c
+ *	Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
+ *	Samuel Thibault <samuel.thibault@ens-lyon.org>
  *
  *  Unsupported but docs exist:
  *	Appian/Adaptec AIC25VL01/Cirrus Logic PD7220
@@ -35,7 +42,7 @@
  *  the MPIIX where the tuning is PCI side but the IDE is "ISA side".
  *
  *  Specific support is included for the ht6560a/ht6560b/opti82c611a/
- *  opti82c465mv/promise 20230c/20630/winbond83759A
+ *  opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A
  *
  *  Use the autospeed and pio_mask options with:
  *	Appian ADI/2 aka CLPD7220 or AIC25VL01.
@@ -672,7 +679,7 @@ static void qdi6580dp_set_piomode(struct
 	outb(timing, ld_qdi->timing + 2 * ap->port_no);
 	/* Clear the FIFO */
 	if (adev->class != ATA_DEV_ATA)
-		outb(0x5F, ld_qdi->timing + 3);
+		outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
 }
 
 /**
@@ -707,7 +714,7 @@ static void qdi6580_set_piomode(struct a
 	outb(timing, ld_qdi->timing + 2 * adev->devno);
 	/* Clear the FIFO */
 	if (adev->class != ATA_DEV_ATA)
-		outb(0x5F, ld_qdi->timing + 3);
+		outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
 }
 
 /**
@@ -787,6 +794,7 @@ static struct ata_port_operations qdi658
 static struct ata_port_operations qdi6580dp_port_ops = {
 	.inherits	= &legacy_base_port_ops,
 	.set_piomode	= qdi6580dp_set_piomode,
+	.qc_issue	= qdi_qc_issue,
 	.sff_data_xfer	= vlb32_data_xfer,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_macio.c linux-libre-2.6.33-gnu1/drivers/ata/pata_macio.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_macio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_macio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1427 @@
+/*
+ * Libata based driver for Apple "macio" family of PATA controllers
+ *
+ * Copyright 2008/2009 Benjamin Herrenschmidt, IBM Corp
+ *                     <benh@kernel.crashing.org>
+ *
+ * Some bits and pieces from drivers/ide/ppc/pmac.c
+ *
+ */
+
+#undef DEBUG
+#undef DEBUG_DMA
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/ata.h>
+#include <linux/libata.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/scatterlist.h>
+#include <linux/of.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+
+#include <asm/macio.h>
+#include <asm/io.h>
+#include <asm/dbdma.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/mediabay.h>
+
+#ifdef DEBUG_DMA
+#define dev_dbgdma(dev, format, arg...)		\
+	dev_printk(KERN_DEBUG , dev , format , ## arg)
+#else
+#define dev_dbgdma(dev, format, arg...)		\
+	({ if (0) dev_printk(KERN_DEBUG, dev, format, ##arg); 0; })
+#endif
+
+#define DRV_NAME	"pata_macio"
+#define DRV_VERSION	"0.9"
+
+/* Models of macio ATA controller */
+enum {
+	controller_ohare,	/* OHare based */
+	controller_heathrow,	/* Heathrow/Paddington */
+	controller_kl_ata3,	/* KeyLargo ATA-3 */
+	controller_kl_ata4,	/* KeyLargo ATA-4 */
+	controller_un_ata6,	/* UniNorth2 ATA-6 */
+	controller_k2_ata6,	/* K2 ATA-6 */
+	controller_sh_ata6,	/* Shasta ATA-6 */
+};
+
+static const char* macio_ata_names[] = {
+	"OHare ATA",		/* OHare based */
+	"Heathrow ATA",		/* Heathrow/Paddington */
+	"KeyLargo ATA-3",	/* KeyLargo ATA-3 (MDMA only) */
+	"KeyLargo ATA-4",	/* KeyLargo ATA-4 (UDMA/66) */
+	"UniNorth ATA-6",	/* UniNorth2 ATA-6 (UDMA/100) */
+	"K2 ATA-6",		/* K2 ATA-6 (UDMA/100) */
+	"Shasta ATA-6",		/* Shasta ATA-6 (UDMA/133) */
+};
+
+/*
+ * Extra registers, both 32-bit little-endian
+ */
+#define IDE_TIMING_CONFIG	0x200
+#define IDE_INTERRUPT		0x300
+
+/* Kauai (U2) ATA has different register setup */
+#define IDE_KAUAI_PIO_CONFIG	0x200
+#define IDE_KAUAI_ULTRA_CONFIG	0x210
+#define IDE_KAUAI_POLL_CONFIG	0x220
+
+/*
+ * Timing configuration register definitions
+ */
+
+/* Number of IDE_SYSCLK_NS ticks, argument is in nanoseconds */
+#define SYSCLK_TICKS(t)		(((t) + IDE_SYSCLK_NS - 1) / IDE_SYSCLK_NS)
+#define SYSCLK_TICKS_66(t)	(((t) + IDE_SYSCLK_66_NS - 1) / IDE_SYSCLK_66_NS)
+#define IDE_SYSCLK_NS		30	/* 33Mhz cell */
+#define IDE_SYSCLK_66_NS	15	/* 66Mhz cell */
+
+/* 133Mhz cell, found in shasta.
+ * See comments about 100 Mhz Uninorth 2...
+ * Note that PIO_MASK and MDMA_MASK seem to overlap, that's just
+ * weird and I don't now why .. at this stage
+ */
+#define TR_133_PIOREG_PIO_MASK		0xff000fff
+#define TR_133_PIOREG_MDMA_MASK		0x00fff800
+#define TR_133_UDMAREG_UDMA_MASK	0x0003ffff
+#define TR_133_UDMAREG_UDMA_EN		0x00000001
+
+/* 100Mhz cell, found in Uninorth 2 and K2. It appears as a pci device
+ * (106b/0033) on uninorth or K2 internal PCI bus and it's clock is
+ * controlled like gem or fw. It appears to be an evolution of keylargo
+ * ATA4 with a timing register extended to 2x32bits registers (one
+ * for PIO & MWDMA and one for UDMA, and a similar DBDMA channel.
+ * It has it's own local feature control register as well.
+ *
+ * After scratching my mind over the timing values, at least for PIO
+ * and MDMA, I think I've figured the format of the timing register,
+ * though I use pre-calculated tables for UDMA as usual...
+ */
+#define TR_100_PIO_ADDRSETUP_MASK	0xff000000 /* Size of field unknown */
+#define TR_100_PIO_ADDRSETUP_SHIFT	24
+#define TR_100_MDMA_MASK		0x00fff000
+#define TR_100_MDMA_RECOVERY_MASK	0x00fc0000
+#define TR_100_MDMA_RECOVERY_SHIFT	18
+#define TR_100_MDMA_ACCESS_MASK		0x0003f000
+#define TR_100_MDMA_ACCESS_SHIFT	12
+#define TR_100_PIO_MASK			0xff000fff
+#define TR_100_PIO_RECOVERY_MASK	0x00000fc0
+#define TR_100_PIO_RECOVERY_SHIFT	6
+#define TR_100_PIO_ACCESS_MASK		0x0000003f
+#define TR_100_PIO_ACCESS_SHIFT		0
+
+#define TR_100_UDMAREG_UDMA_MASK	0x0000ffff
+#define TR_100_UDMAREG_UDMA_EN		0x00000001
+
+
+/* 66Mhz cell, found in KeyLargo. Can do ultra mode 0 to 2 on
+ * 40 connector cable and to 4 on 80 connector one.
+ * Clock unit is 15ns (66Mhz)
+ *
+ * 3 Values can be programmed:
+ *  - Write data setup, which appears to match the cycle time. They
+ *    also call it DIOW setup.
+ *  - Ready to pause time (from spec)
+ *  - Address setup. That one is weird. I don't see where exactly
+ *    it fits in UDMA cycles, I got it's name from an obscure piece
+ *    of commented out code in Darwin. They leave it to 0, we do as
+ *    well, despite a comment that would lead to think it has a
+ *    min value of 45ns.
+ * Apple also add 60ns to the write data setup (or cycle time ?) on
+ * reads.
+ */
+#define TR_66_UDMA_MASK			0xfff00000
+#define TR_66_UDMA_EN			0x00100000 /* Enable Ultra mode for DMA */
+#define TR_66_PIO_ADDRSETUP_MASK	0xe0000000 /* Address setup */
+#define TR_66_PIO_ADDRSETUP_SHIFT	29
+#define TR_66_UDMA_RDY2PAUS_MASK	0x1e000000 /* Ready 2 pause time */
+#define TR_66_UDMA_RDY2PAUS_SHIFT	25
+#define TR_66_UDMA_WRDATASETUP_MASK	0x01e00000 /* Write data setup time */
+#define TR_66_UDMA_WRDATASETUP_SHIFT	21
+#define TR_66_MDMA_MASK			0x000ffc00
+#define TR_66_MDMA_RECOVERY_MASK	0x000f8000
+#define TR_66_MDMA_RECOVERY_SHIFT	15
+#define TR_66_MDMA_ACCESS_MASK		0x00007c00
+#define TR_66_MDMA_ACCESS_SHIFT		10
+#define TR_66_PIO_MASK			0xe00003ff
+#define TR_66_PIO_RECOVERY_MASK		0x000003e0
+#define TR_66_PIO_RECOVERY_SHIFT	5
+#define TR_66_PIO_ACCESS_MASK		0x0000001f
+#define TR_66_PIO_ACCESS_SHIFT		0
+
+/* 33Mhz cell, found in OHare, Heathrow (& Paddington) and KeyLargo
+ * Can do pio & mdma modes, clock unit is 30ns (33Mhz)
+ *
+ * The access time and recovery time can be programmed. Some older
+ * Darwin code base limit OHare to 150ns cycle time. I decided to do
+ * the same here fore safety against broken old hardware ;)
+ * The HalfTick bit, when set, adds half a clock (15ns) to the access
+ * time and removes one from recovery. It's not supported on KeyLargo
+ * implementation afaik. The E bit appears to be set for PIO mode 0 and
+ * is used to reach long timings used in this mode.
+ */
+#define TR_33_MDMA_MASK			0x003ff800
+#define TR_33_MDMA_RECOVERY_MASK	0x001f0000
+#define TR_33_MDMA_RECOVERY_SHIFT	16
+#define TR_33_MDMA_ACCESS_MASK		0x0000f800
+#define TR_33_MDMA_ACCESS_SHIFT		11
+#define TR_33_MDMA_HALFTICK		0x00200000
+#define TR_33_PIO_MASK			0x000007ff
+#define TR_33_PIO_E			0x00000400
+#define TR_33_PIO_RECOVERY_MASK		0x000003e0
+#define TR_33_PIO_RECOVERY_SHIFT	5
+#define TR_33_PIO_ACCESS_MASK		0x0000001f
+#define TR_33_PIO_ACCESS_SHIFT		0
+
+/*
+ * Interrupt register definitions. Only present on newer cells
+ * (Keylargo and later afaik) so we don't use it.
+ */
+#define IDE_INTR_DMA			0x80000000
+#define IDE_INTR_DEVICE			0x40000000
+
+/*
+ * FCR Register on Kauai. Not sure what bit 0x4 is  ...
+ */
+#define KAUAI_FCR_UATA_MAGIC		0x00000004
+#define KAUAI_FCR_UATA_RESET_N		0x00000002
+#define KAUAI_FCR_UATA_ENABLE		0x00000001
+
+
+/* Allow up to 256 DBDMA commands per xfer */
+#define MAX_DCMDS		256
+
+/* Don't let a DMA segment go all the way to 64K */
+#define MAX_DBDMA_SEG		0xff00
+
+
+/*
+ * Wait 1s for disk to answer on IDE bus after a hard reset
+ * of the device (via GPIO/FCR).
+ *
+ * Some devices seem to "pollute" the bus even after dropping
+ * the BSY bit (typically some combo drives slave on the UDMA
+ * bus) after a hard reset. Since we hard reset all drives on
+ * KeyLargo ATA66, we have to keep that delay around. I may end
+ * up not hard resetting anymore on these and keep the delay only
+ * for older interfaces instead (we have to reset when coming
+ * from MacOS...) --BenH.
+ */
+#define IDE_WAKEUP_DELAY_MS	1000
+
+struct pata_macio_timing;
+
+struct pata_macio_priv {
+	int				kind;
+	int				aapl_bus_id;
+	int				mediabay : 1;
+	struct device_node		*node;
+	struct macio_dev		*mdev;
+	struct pci_dev			*pdev;
+	struct device			*dev;
+	int				irq;
+	u32				treg[2][2];
+	void __iomem			*tfregs;
+	void __iomem			*kauai_fcr;
+	struct dbdma_cmd *		dma_table_cpu;
+	dma_addr_t			dma_table_dma;
+	struct ata_host			*host;
+	const struct pata_macio_timing	*timings;
+};
+
+/* Previous variants of this driver used to calculate timings
+ * for various variants of the chip and use tables for others.
+ *
+ * Not only was this confusing, but in addition, it isn't clear
+ * whether our calculation code was correct. It didn't entirely
+ * match the darwin code and whatever documentation I could find
+ * on these cells
+ *
+ * I decided to entirely rely on a table instead for this version
+ * of the driver. Also, because I don't really care about derated
+ * modes and really old HW other than making it work, I'm not going
+ * to calculate / snoop timing values for something else than the
+ * standard modes.
+ */
+struct pata_macio_timing {
+	int	mode;
+	u32	reg1;	/* Bits to set in first timing reg */
+	u32	reg2;	/* Bits to set in second timing reg */
+};
+
+static const struct pata_macio_timing pata_macio_ohare_timings[] = {
+	{ XFER_PIO_0,		0x00000526,	0, },
+	{ XFER_PIO_1,		0x00000085,	0, },
+	{ XFER_PIO_2,		0x00000025,	0, },
+	{ XFER_PIO_3,		0x00000025,	0, },
+	{ XFER_PIO_4,		0x00000025,	0, },
+	{ XFER_MW_DMA_0,	0x00074000,	0, },
+	{ XFER_MW_DMA_1,	0x00221000,	0, },
+	{ XFER_MW_DMA_2,	0x00211000,	0, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing pata_macio_heathrow_timings[] = {
+	{ XFER_PIO_0,		0x00000526,	0, },
+	{ XFER_PIO_1,		0x00000085,	0, },
+	{ XFER_PIO_2,		0x00000025,	0, },
+	{ XFER_PIO_3,		0x00000025,	0, },
+	{ XFER_PIO_4,		0x00000025,	0, },
+	{ XFER_MW_DMA_0,	0x00074000,	0, },
+	{ XFER_MW_DMA_1,	0x00221000,	0, },
+	{ XFER_MW_DMA_2,	0x00211000,	0, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing pata_macio_kl33_timings[] = {
+	{ XFER_PIO_0,		0x00000526,	0, },
+	{ XFER_PIO_1,		0x00000085,	0, },
+	{ XFER_PIO_2,		0x00000025,	0, },
+	{ XFER_PIO_3,		0x00000025,	0, },
+	{ XFER_PIO_4,		0x00000025,	0, },
+	{ XFER_MW_DMA_0,	0x00084000,	0, },
+	{ XFER_MW_DMA_1,	0x00021800,	0, },
+	{ XFER_MW_DMA_2,	0x00011800,	0, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing pata_macio_kl66_timings[] = {
+	{ XFER_PIO_0,		0x0000038c,	0, },
+	{ XFER_PIO_1,		0x0000020a,	0, },
+	{ XFER_PIO_2,		0x00000127,	0, },
+	{ XFER_PIO_3,		0x000000c6,	0, },
+	{ XFER_PIO_4,		0x00000065,	0, },
+	{ XFER_MW_DMA_0,	0x00084000,	0, },
+	{ XFER_MW_DMA_1,	0x00029800,	0, },
+	{ XFER_MW_DMA_2,	0x00019400,	0, },
+	{ XFER_UDMA_0,		0x19100000,	0, },
+	{ XFER_UDMA_1,		0x14d00000,	0, },
+	{ XFER_UDMA_2,		0x10900000,	0, },
+	{ XFER_UDMA_3,		0x0c700000,	0, },
+	{ XFER_UDMA_4,		0x0c500000,	0, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing pata_macio_kauai_timings[] = {
+	{ XFER_PIO_0,		0x08000a92,	0, },
+	{ XFER_PIO_1,		0x0800060f,	0, },
+	{ XFER_PIO_2,		0x0800038b,	0, },
+	{ XFER_PIO_3,		0x05000249,	0, },
+	{ XFER_PIO_4,		0x04000148,	0, },
+	{ XFER_MW_DMA_0,	0x00618000,	0, },
+	{ XFER_MW_DMA_1,	0x00209000,	0, },
+	{ XFER_MW_DMA_2,	0x00148000,	0, },
+	{ XFER_UDMA_0,		         0,	0x000070c1, },
+	{ XFER_UDMA_1,		         0,	0x00005d81, },
+	{ XFER_UDMA_2,		         0,	0x00004a61, },
+	{ XFER_UDMA_3,		         0,	0x00003a51, },
+	{ XFER_UDMA_4,		         0,	0x00002a31, },
+	{ XFER_UDMA_5,		         0,	0x00002921, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing pata_macio_shasta_timings[] = {
+	{ XFER_PIO_0,		0x0a000c97,	0, },
+	{ XFER_PIO_1,		0x07000712,	0, },
+	{ XFER_PIO_2,		0x040003cd,	0, },
+	{ XFER_PIO_3,		0x0500028b,	0, },
+	{ XFER_PIO_4,		0x0400010a,	0, },
+	{ XFER_MW_DMA_0,	0x00820800,	0, },
+	{ XFER_MW_DMA_1,	0x0028b000,	0, },
+	{ XFER_MW_DMA_2,	0x001ca000,	0, },
+	{ XFER_UDMA_0,		         0,	0x00035901, },
+	{ XFER_UDMA_1,		         0,	0x000348b1, },
+	{ XFER_UDMA_2,		         0,	0x00033881, },
+	{ XFER_UDMA_3,		         0,	0x00033861, },
+	{ XFER_UDMA_4,		         0,	0x00033841, },
+	{ XFER_UDMA_5,		         0,	0x00033031, },
+	{ XFER_UDMA_6,		         0,	0x00033021, },
+	{ -1, 0, 0 }
+};
+
+static const struct pata_macio_timing *pata_macio_find_timing(
+					    struct pata_macio_priv *priv,
+					    int mode)
+{
+	int i;
+
+	for (i = 0; priv->timings[i].mode > 0; i++) {
+		if (priv->timings[i].mode == mode)
+			return &priv->timings[i];
+	}
+	return NULL;
+}
+
+
+static void pata_macio_apply_timings(struct ata_port *ap, unsigned int device)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+	void __iomem *rbase = ap->ioaddr.cmd_addr;
+
+	if (priv->kind == controller_sh_ata6 ||
+	    priv->kind == controller_un_ata6 ||
+	    priv->kind == controller_k2_ata6) {
+		writel(priv->treg[device][0], rbase + IDE_KAUAI_PIO_CONFIG);
+		writel(priv->treg[device][1], rbase + IDE_KAUAI_ULTRA_CONFIG);
+	} else
+		writel(priv->treg[device][0], rbase + IDE_TIMING_CONFIG);
+}
+
+static void pata_macio_dev_select(struct ata_port *ap, unsigned int device)
+{
+	ata_sff_dev_select(ap, device);
+
+	/* Apply timings */
+	pata_macio_apply_timings(ap, device);
+}
+
+static void pata_macio_set_timings(struct ata_port *ap,
+				   struct ata_device *adev)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+	const struct pata_macio_timing *t;
+
+	dev_dbg(priv->dev, "Set timings: DEV=%d,PIO=0x%x (%s),DMA=0x%x (%s)\n",
+		adev->devno,
+		adev->pio_mode,
+		ata_mode_string(ata_xfer_mode2mask(adev->pio_mode)),
+		adev->dma_mode,
+		ata_mode_string(ata_xfer_mode2mask(adev->dma_mode)));
+
+	/* First clear timings */
+	priv->treg[adev->devno][0] = priv->treg[adev->devno][1] = 0;
+
+	/* Now get the PIO timings */
+	t = pata_macio_find_timing(priv, adev->pio_mode);
+	if (t == NULL) {
+		dev_warn(priv->dev, "Invalid PIO timing requested: 0x%x\n",
+			 adev->pio_mode);
+		t = pata_macio_find_timing(priv, XFER_PIO_0);
+	}
+	BUG_ON(t == NULL);
+
+	/* PIO timings only ever use the first treg */
+	priv->treg[adev->devno][0] |= t->reg1;
+
+	/* Now get DMA timings */
+	t = pata_macio_find_timing(priv, adev->dma_mode);
+	if (t == NULL || (t->reg1 == 0 && t->reg2 == 0)) {
+		dev_dbg(priv->dev, "DMA timing not set yet, using MW_DMA_0\n");
+		t = pata_macio_find_timing(priv, XFER_MW_DMA_0);
+	}
+	BUG_ON(t == NULL);
+
+	/* DMA timings can use both tregs */
+	priv->treg[adev->devno][0] |= t->reg1;
+	priv->treg[adev->devno][1] |= t->reg2;
+
+	dev_dbg(priv->dev, " -> %08x %08x\n",
+		priv->treg[adev->devno][0],
+		priv->treg[adev->devno][1]);
+
+	/* Apply to hardware */
+	pata_macio_apply_timings(ap, adev->devno);
+}
+
+/*
+ * Blast some well known "safe" values to the timing registers at init or
+ * wakeup from sleep time, before we do real calculation
+ */
+static void pata_macio_default_timings(struct pata_macio_priv *priv)
+{
+	unsigned int value, value2 = 0;
+
+	switch(priv->kind) {
+		case controller_sh_ata6:
+			value = 0x0a820c97;
+			value2 = 0x00033031;
+			break;
+		case controller_un_ata6:
+		case controller_k2_ata6:
+			value = 0x08618a92;
+			value2 = 0x00002921;
+			break;
+		case controller_kl_ata4:
+			value = 0x0008438c;
+			break;
+		case controller_kl_ata3:
+			value = 0x00084526;
+			break;
+		case controller_heathrow:
+		case controller_ohare:
+		default:
+			value = 0x00074526;
+			break;
+	}
+	priv->treg[0][0] = priv->treg[1][0] = value;
+	priv->treg[0][1] = priv->treg[1][1] = value2;
+}
+
+static int pata_macio_cable_detect(struct ata_port *ap)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+
+	/* Get cable type from device-tree */
+	if (priv->kind == controller_kl_ata4 ||
+	    priv->kind == controller_un_ata6 ||
+	    priv->kind == controller_k2_ata6 ||
+	    priv->kind == controller_sh_ata6) {
+		const char* cable = of_get_property(priv->node, "cable-type",
+						    NULL);
+		struct device_node *root = of_find_node_by_path("/");
+		const char *model = of_get_property(root, "model", NULL);
+
+		if (cable && !strncmp(cable, "80-", 3)) {
+			/* Some drives fail to detect 80c cable in PowerBook
+			 * These machine use proprietary short IDE cable
+			 * anyway
+			 */
+			if (!strncmp(model, "PowerBook", 9))
+				return ATA_CBL_PATA40_SHORT;
+			else
+				return ATA_CBL_PATA80;
+		}
+	}
+
+	/* G5's seem to have incorrect cable type in device-tree.
+	 * Let's assume they always have a 80 conductor cable, this seem to
+	 * be always the case unless the user mucked around
+	 */
+	if (of_device_is_compatible(priv->node, "K2-UATA") ||
+	    of_device_is_compatible(priv->node, "shasta-ata"))
+		return ATA_CBL_PATA80;
+
+	/* Anything else is 40 connectors */
+	return ATA_CBL_PATA40;
+}
+
+static void pata_macio_qc_prep(struct ata_queued_cmd *qc)
+{
+	unsigned int write = (qc->tf.flags & ATA_TFLAG_WRITE);
+	struct ata_port *ap = qc->ap;
+	struct pata_macio_priv *priv = ap->private_data;
+	struct scatterlist *sg;
+	struct dbdma_cmd *table;
+	unsigned int si, pi;
+
+	dev_dbgdma(priv->dev, "%s: qc %p flags %lx, write %d dev %d\n",
+		   __func__, qc, qc->flags, write, qc->dev->devno);
+
+	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+		return;
+
+	table = (struct dbdma_cmd *) priv->dma_table_cpu;
+
+	pi = 0;
+	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+		u32 addr, sg_len, len;
+
+		/* determine if physical DMA addr spans 64K boundary.
+		 * Note h/w doesn't support 64-bit, so we unconditionally
+		 * truncate dma_addr_t to u32.
+		 */
+		addr = (u32) sg_dma_address(sg);
+		sg_len = sg_dma_len(sg);
+
+		while (sg_len) {
+			/* table overflow should never happen */
+			BUG_ON (pi++ >= MAX_DCMDS);
+
+			len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG;
+			st_le16(&table->command, write ? OUTPUT_MORE: INPUT_MORE);
+			st_le16(&table->req_count, len);
+			st_le32(&table->phy_addr, addr);
+			table->cmd_dep = 0;
+			table->xfer_status = 0;
+			table->res_count = 0;
+			addr += len;
+			sg_len -= len;
+			++table;
+		}
+	}
+
+	/* Should never happen according to Tejun */
+	BUG_ON(!pi);
+
+	/* Convert the last command to an input/output */
+	table--;
+	st_le16(&table->command, write ? OUTPUT_LAST: INPUT_LAST);
+	table++;
+
+	/* Add the stop command to the end of the list */
+	memset(table, 0, sizeof(struct dbdma_cmd));
+	st_le16(&table->command, DBDMA_STOP);
+
+	dev_dbgdma(priv->dev, "%s: %d DMA list entries\n", __func__, pi);
+}
+
+
+static void pata_macio_freeze(struct ata_port *ap)
+{
+	struct dbdma_regs __iomem *dma_regs = ap->ioaddr.bmdma_addr;
+
+	if (dma_regs) {
+		unsigned int timeout = 1000000;
+
+		/* Make sure DMA controller is stopped */
+		writel((RUN|PAUSE|FLUSH|WAKE|DEAD) << 16, &dma_regs->control);
+		while (--timeout && (readl(&dma_regs->status) & RUN))
+			udelay(1);
+	}
+
+	ata_sff_freeze(ap);
+}
+
+
+static void pata_macio_bmdma_setup(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_macio_priv *priv = ap->private_data;
+	struct dbdma_regs __iomem *dma_regs = ap->ioaddr.bmdma_addr;
+	int dev = qc->dev->devno;
+
+	dev_dbgdma(priv->dev, "%s: qc %p\n", __func__, qc);
+
+	/* Make sure DMA commands updates are visible */
+	writel(priv->dma_table_dma, &dma_regs->cmdptr);
+
+	/* On KeyLargo 66Mhz cell, we need to add 60ns to wrDataSetup on
+	 * UDMA reads
+	 */
+	if (priv->kind == controller_kl_ata4 &&
+	    (priv->treg[dev][0] & TR_66_UDMA_EN)) {
+		void __iomem *rbase = ap->ioaddr.cmd_addr;
+		u32 reg = priv->treg[dev][0];
+
+		if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+			reg += 0x00800000;
+		writel(reg, rbase + IDE_TIMING_CONFIG);
+	}
+
+	/* issue r/w command */
+	ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+static void pata_macio_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_macio_priv *priv = ap->private_data;
+	struct dbdma_regs __iomem *dma_regs = ap->ioaddr.bmdma_addr;
+
+	dev_dbgdma(priv->dev, "%s: qc %p\n", __func__, qc);
+
+	writel((RUN << 16) | RUN, &dma_regs->control);
+	/* Make sure it gets to the controller right now */
+	(void)readl(&dma_regs->control);
+}
+
+static void pata_macio_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_macio_priv *priv = ap->private_data;
+	struct dbdma_regs __iomem *dma_regs = ap->ioaddr.bmdma_addr;
+	unsigned int timeout = 1000000;
+
+	dev_dbgdma(priv->dev, "%s: qc %p\n", __func__, qc);
+
+	/* Stop the DMA engine and wait for it to full halt */
+	writel (((RUN|WAKE|DEAD) << 16), &dma_regs->control);
+	while (--timeout && (readl(&dma_regs->status) & RUN))
+		udelay(1);
+}
+
+static u8 pata_macio_bmdma_status(struct ata_port *ap)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+	struct dbdma_regs __iomem *dma_regs = ap->ioaddr.bmdma_addr;
+	u32 dstat, rstat = ATA_DMA_INTR;
+	unsigned long timeout = 0;
+
+	dstat = readl(&dma_regs->status);
+
+	dev_dbgdma(priv->dev, "%s: dstat=%x\n", __func__, dstat);
+
+	/* We have two things to deal with here:
+	 *
+	 * - The dbdma won't stop if the command was started
+	 * but completed with an error without transferring all
+	 * datas. This happens when bad blocks are met during
+	 * a multi-block transfer.
+	 *
+	 * - The dbdma fifo hasn't yet finished flushing to
+	 * to system memory when the disk interrupt occurs.
+	 *
+	 */
+
+	/* First check for errors */
+	if ((dstat & (RUN|DEAD)) != RUN)
+		rstat |= ATA_DMA_ERR;
+
+	/* If ACTIVE is cleared, the STOP command has been hit and
+	 * the transfer is complete. If not, we have to flush the
+	 * channel.
+	 */
+	if ((dstat & ACTIVE) == 0)
+		return rstat;
+
+	dev_dbgdma(priv->dev, "%s: DMA still active, flushing...\n", __func__);
+
+	/* If dbdma didn't execute the STOP command yet, the
+	 * active bit is still set. We consider that we aren't
+	 * sharing interrupts (which is hopefully the case with
+	 * those controllers) and so we just try to flush the
+	 * channel for pending data in the fifo
+	 */
+	udelay(1);
+	writel((FLUSH << 16) | FLUSH, &dma_regs->control);
+	for (;;) {
+		udelay(1);
+		dstat = readl(&dma_regs->status);
+		if ((dstat & FLUSH) == 0)
+			break;
+		if (++timeout > 1000) {
+			dev_warn(priv->dev, "timeout flushing DMA\n");
+			rstat |= ATA_DMA_ERR;
+			break;
+		}
+	}
+	return rstat;
+}
+
+/* port_start is when we allocate the DMA command list */
+static int pata_macio_port_start(struct ata_port *ap)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+
+	if (ap->ioaddr.bmdma_addr == NULL)
+		return 0;
+
+	/* Allocate space for the DBDMA commands.
+	 *
+	 * The +2 is +1 for the stop command and +1 to allow for
+	 * aligning the start address to a multiple of 16 bytes.
+	 */
+	priv->dma_table_cpu =
+		dmam_alloc_coherent(priv->dev,
+				    (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
+				    &priv->dma_table_dma, GFP_KERNEL);
+	if (priv->dma_table_cpu == NULL) {
+		dev_err(priv->dev, "Unable to allocate DMA command list\n");
+		ap->ioaddr.bmdma_addr = NULL;
+	}
+	return 0;
+}
+
+static void pata_macio_irq_clear(struct ata_port *ap)
+{
+	struct pata_macio_priv *priv = ap->private_data;
+
+	/* Nothing to do here */
+
+	dev_dbgdma(priv->dev, "%s\n", __func__);
+}
+
+static void pata_macio_reset_hw(struct pata_macio_priv *priv, int resume)
+{
+	dev_dbg(priv->dev, "Enabling & resetting... \n");
+
+	if (priv->mediabay)
+		return;
+
+	if (priv->kind == controller_ohare && !resume) {
+		/* The code below is having trouble on some ohare machines
+		 * (timing related ?). Until I can put my hand on one of these
+		 * units, I keep the old way
+		 */
+		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, priv->node, 0, 1);
+	} else {
+		int rc;
+
+ 		/* Reset and enable controller */
+		rc = ppc_md.feature_call(PMAC_FTR_IDE_RESET,
+					 priv->node, priv->aapl_bus_id, 1);
+		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE,
+				    priv->node, priv->aapl_bus_id, 1);
+		msleep(10);
+		/* Only bother waiting if there's a reset control */
+		if (rc == 0) {
+			ppc_md.feature_call(PMAC_FTR_IDE_RESET,
+					    priv->node, priv->aapl_bus_id, 0);
+			msleep(IDE_WAKEUP_DELAY_MS);
+		}
+	}
+
+	/* If resuming a PCI device, restore the config space here */
+	if (priv->pdev && resume) {
+		int rc;
+
+		pci_restore_state(priv->pdev);
+		rc = pcim_enable_device(priv->pdev);
+		if (rc)
+			dev_printk(KERN_ERR, &priv->pdev->dev,
+				   "Failed to enable device after resume (%d)\n", rc);
+		else
+			pci_set_master(priv->pdev);
+	}
+
+	/* On Kauai, initialize the FCR. We don't perform a reset, doesn't really
+	 * seem necessary and speeds up the boot process
+	 */
+	if (priv->kauai_fcr)
+		writel(KAUAI_FCR_UATA_MAGIC |
+		       KAUAI_FCR_UATA_RESET_N |
+		       KAUAI_FCR_UATA_ENABLE, priv->kauai_fcr);
+}
+
+/* Hook the standard slave config to fixup some HW related alignment
+ * restrictions
+ */
+static int pata_macio_slave_config(struct scsi_device *sdev)
+{
+	struct ata_port *ap = ata_shost_to_port(sdev->host);
+	struct pata_macio_priv *priv = ap->private_data;
+	struct ata_device *dev;
+	u16 cmd;
+	int rc;
+
+	/* First call original */
+	rc = ata_scsi_slave_config(sdev);
+	if (rc)
+		return rc;
+
+	/* This is lifted from sata_nv */
+	dev = &ap->link.device[sdev->id];
+
+	/* OHare has issues with non cache aligned DMA on some chipsets */
+	if (priv->kind == controller_ohare) {
+		blk_queue_update_dma_alignment(sdev->request_queue, 31);
+		blk_queue_update_dma_pad(sdev->request_queue, 31);
+
+		/* Tell the world about it */
+		ata_dev_printk(dev, KERN_INFO, "OHare alignment limits applied\n");
+		return 0;
+	}
+
+	/* We only have issues with ATAPI */
+	if (dev->class != ATA_DEV_ATAPI)
+		return 0;
+
+	/* Shasta and K2 seem to have "issues" with reads ... */
+	if (priv->kind == controller_sh_ata6 || priv->kind == controller_k2_ata6) {
+		/* Allright these are bad, apply restrictions */
+		blk_queue_update_dma_alignment(sdev->request_queue, 15);
+		blk_queue_update_dma_pad(sdev->request_queue, 15);
+
+		/* We enable MWI and hack cache line size directly here, this
+		 * is specific to this chipset and not normal values, we happen
+		 * to somewhat know what we are doing here (which is basically
+		 * to do the same Apple does and pray they did not get it wrong :-)
+		 */
+		BUG_ON(!priv->pdev);
+		pci_write_config_byte(priv->pdev, PCI_CACHE_LINE_SIZE, 0x08);
+		pci_read_config_word(priv->pdev, PCI_COMMAND, &cmd);
+		pci_write_config_word(priv->pdev, PCI_COMMAND,
+				      cmd | PCI_COMMAND_INVALIDATE);
+
+		/* Tell the world about it */
+		ata_dev_printk(dev, KERN_INFO,
+			       "K2/Shasta alignment limits applied\n");
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int pata_macio_do_suspend(struct pata_macio_priv *priv, pm_message_t mesg)
+{
+	int rc;
+
+	/* First, core libata suspend to do most of the work */
+	rc = ata_host_suspend(priv->host, mesg);
+	if (rc)
+		return rc;
+
+	/* Restore to default timings */
+	pata_macio_default_timings(priv);
+
+	/* Mask interrupt. Not strictly necessary but old driver did
+	 * it and I'd rather not change that here */
+	disable_irq(priv->irq);
+
+	/* The media bay will handle itself just fine */
+	if (priv->mediabay)
+		return 0;
+
+	/* Kauai has bus control FCRs directly here */
+	if (priv->kauai_fcr) {
+		u32 fcr = readl(priv->kauai_fcr);
+		fcr &= ~(KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE);
+		writel(fcr, priv->kauai_fcr);
+	}
+
+	/* For PCI, save state and disable DMA. No need to call
+	 * pci_set_power_state(), the HW doesn't do D states that
+	 * way, the platform code will take care of suspending the
+	 * ASIC properly
+	 */
+	if (priv->pdev) {
+		pci_save_state(priv->pdev);
+		pci_disable_device(priv->pdev);
+	}
+
+	/* Disable the bus on older machines and the cell on kauai */
+	ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, priv->node,
+			    priv->aapl_bus_id, 0);
+
+	return 0;
+}
+
+static int pata_macio_do_resume(struct pata_macio_priv *priv)
+{
+	/* Reset and re-enable the HW */
+	pata_macio_reset_hw(priv, 1);
+
+	/* Sanitize drive timings */
+	pata_macio_apply_timings(priv->host->ports[0], 0);
+
+	/* We want our IRQ back ! */
+	enable_irq(priv->irq);
+
+	/* Let the libata core take it from there */
+	ata_host_resume(priv->host);
+
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
+static struct scsi_host_template pata_macio_sht = {
+	ATA_BASE_SHT(DRV_NAME),
+	.sg_tablesize		= MAX_DCMDS,
+	/* We may not need that strict one */
+	.dma_boundary		= ATA_DMA_BOUNDARY,
+	.slave_configure	= pata_macio_slave_config,
+};
+
+static struct ata_port_operations pata_macio_ops = {
+	.inherits		= &ata_sff_port_ops,
+
+	.freeze			= pata_macio_freeze,
+	.set_piomode		= pata_macio_set_timings,
+	.set_dmamode		= pata_macio_set_timings,
+	.cable_detect		= pata_macio_cable_detect,
+	.sff_dev_select		= pata_macio_dev_select,
+	.qc_prep		= pata_macio_qc_prep,
+	.mode_filter		= ata_bmdma_mode_filter,
+	.bmdma_setup		= pata_macio_bmdma_setup,
+	.bmdma_start		= pata_macio_bmdma_start,
+	.bmdma_stop		= pata_macio_bmdma_stop,
+	.bmdma_status		= pata_macio_bmdma_status,
+	.port_start		= pata_macio_port_start,
+	.sff_irq_clear		= pata_macio_irq_clear,
+};
+
+static void __devinit pata_macio_invariants(struct pata_macio_priv *priv)
+{
+	const int *bidp;
+
+	/* Identify the type of controller */
+	if (of_device_is_compatible(priv->node, "shasta-ata")) {
+		priv->kind = controller_sh_ata6;
+	        priv->timings = pata_macio_shasta_timings;
+	} else if (of_device_is_compatible(priv->node, "kauai-ata")) {
+		priv->kind = controller_un_ata6;
+	        priv->timings = pata_macio_kauai_timings;
+	} else if (of_device_is_compatible(priv->node, "K2-UATA")) {
+		priv->kind = controller_k2_ata6;
+	        priv->timings = pata_macio_kauai_timings;
+	} else if (of_device_is_compatible(priv->node, "keylargo-ata")) {
+		if (strcmp(priv->node->name, "ata-4") == 0) {
+			priv->kind = controller_kl_ata4;
+			priv->timings = pata_macio_kl66_timings;
+		} else {
+			priv->kind = controller_kl_ata3;
+			priv->timings = pata_macio_kl33_timings;
+		}
+	} else if (of_device_is_compatible(priv->node, "heathrow-ata")) {
+		priv->kind = controller_heathrow;
+		priv->timings = pata_macio_heathrow_timings;
+	} else {
+		priv->kind = controller_ohare;
+		priv->timings = pata_macio_ohare_timings;
+	}
+
+	/* XXX FIXME --- setup priv->mediabay here */
+
+	/* Get Apple bus ID (for clock and ASIC control) */
+	bidp = of_get_property(priv->node, "AAPL,bus-id", NULL);
+	priv->aapl_bus_id =  bidp ? *bidp : 0;
+
+	/* Fixup missing Apple bus ID in case of media-bay */
+	if (priv->mediabay && bidp == 0)
+		priv->aapl_bus_id = 1;
+}
+
+static void __devinit pata_macio_setup_ios(struct ata_ioports *ioaddr,
+					   void __iomem * base,
+					   void __iomem * dma)
+{
+	/* cmd_addr is the base of regs for that port */
+	ioaddr->cmd_addr	= base;
+
+	/* taskfile registers */
+	ioaddr->data_addr	= base + (ATA_REG_DATA    << 4);
+	ioaddr->error_addr	= base + (ATA_REG_ERR     << 4);
+	ioaddr->feature_addr	= base + (ATA_REG_FEATURE << 4);
+	ioaddr->nsect_addr	= base + (ATA_REG_NSECT   << 4);
+	ioaddr->lbal_addr	= base + (ATA_REG_LBAL    << 4);
+	ioaddr->lbam_addr	= base + (ATA_REG_LBAM    << 4);
+	ioaddr->lbah_addr	= base + (ATA_REG_LBAH    << 4);
+	ioaddr->device_addr	= base + (ATA_REG_DEVICE  << 4);
+	ioaddr->status_addr	= base + (ATA_REG_STATUS  << 4);
+	ioaddr->command_addr	= base + (ATA_REG_CMD     << 4);
+	ioaddr->altstatus_addr	= base + 0x160;
+	ioaddr->ctl_addr	= base + 0x160;
+	ioaddr->bmdma_addr	= dma;
+}
+
+static void __devinit pmac_macio_calc_timing_masks(struct pata_macio_priv *priv,
+						   struct ata_port_info   *pinfo)
+{
+	int i = 0;
+
+	pinfo->pio_mask		= 0;
+	pinfo->mwdma_mask	= 0;
+	pinfo->udma_mask	= 0;
+
+	while (priv->timings[i].mode > 0) {
+		unsigned int mask = 1U << (priv->timings[i].mode & 0x0f);
+		switch(priv->timings[i].mode & 0xf0) {
+		case 0x00: /* PIO */
+			pinfo->pio_mask |= (mask >> 8);
+			break;
+		case 0x20: /* MWDMA */
+			pinfo->mwdma_mask |= mask;
+			break;
+		case 0x40: /* UDMA */
+			pinfo->udma_mask |= mask;
+			break;
+		}
+		i++;
+	}
+	dev_dbg(priv->dev, "Supported masks: PIO=%lx, MWDMA=%lx, UDMA=%lx\n",
+		pinfo->pio_mask, pinfo->mwdma_mask, pinfo->udma_mask);
+}
+
+static int __devinit pata_macio_common_init(struct pata_macio_priv	*priv,
+					    resource_size_t		tfregs,
+					    resource_size_t		dmaregs,
+					    resource_size_t		fcregs,
+					    unsigned long		irq)
+{
+	struct ata_port_info		pinfo;
+	const struct ata_port_info	*ppi[] = { &pinfo, NULL };
+	void __iomem			*dma_regs = NULL;
+
+	/* Fill up privates with various invariants collected from the
+	 * device-tree
+	 */
+	pata_macio_invariants(priv);
+
+	/* Make sure we have sane initial timings in the cache */
+	pata_macio_default_timings(priv);
+
+	/* Not sure what the real max is but we know it's less than 64K, let's
+	 * use 64K minus 256
+	 */
+	dma_set_max_seg_size(priv->dev, MAX_DBDMA_SEG);
+
+	/* Allocate libata host for 1 port */
+	memset(&pinfo, 0, sizeof(struct ata_port_info));
+	pmac_macio_calc_timing_masks(priv, &pinfo);
+	pinfo.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO |
+				  ATA_FLAG_NO_LEGACY;
+	pinfo.port_ops		= &pata_macio_ops;
+	pinfo.private_data	= priv;
+
+	priv->host = ata_host_alloc_pinfo(priv->dev, ppi, 1);
+	if (priv->host == NULL) {
+		dev_err(priv->dev, "Failed to allocate ATA port structure\n");
+		return -ENOMEM;
+	}
+
+	/* Setup the private data in host too */
+	priv->host->private_data = priv;
+
+	/* Map base registers */
+	priv->tfregs = devm_ioremap(priv->dev, tfregs, 0x100);
+	if (priv->tfregs == NULL) {
+		dev_err(priv->dev, "Failed to map ATA ports\n");
+		return -ENOMEM;
+	}
+	priv->host->iomap = &priv->tfregs;
+
+	/* Map DMA regs */
+	if (dmaregs != 0) {
+		dma_regs = devm_ioremap(priv->dev, dmaregs,
+					sizeof(struct dbdma_regs));
+		if (dma_regs == NULL)
+			dev_warn(priv->dev, "Failed to map ATA DMA registers\n");
+	}
+
+	/* If chip has local feature control, map those regs too */
+	if (fcregs != 0) {
+		priv->kauai_fcr = devm_ioremap(priv->dev, fcregs, 4);
+		if (priv->kauai_fcr == NULL) {
+			dev_err(priv->dev, "Failed to map ATA FCR register\n");
+			return -ENOMEM;
+		}
+	}
+
+	/* Setup port data structure */
+	pata_macio_setup_ios(&priv->host->ports[0]->ioaddr,
+			     priv->tfregs, dma_regs);
+	priv->host->ports[0]->private_data = priv;
+
+	/* hard-reset the controller */
+	pata_macio_reset_hw(priv, 0);
+	pata_macio_apply_timings(priv->host->ports[0], 0);
+
+	/* Enable bus master if necessary */
+	if (priv->pdev && dma_regs)
+		pci_set_master(priv->pdev);
+
+	dev_info(priv->dev, "Activating pata-macio chipset %s, Apple bus ID %d\n",
+		 macio_ata_names[priv->kind], priv->aapl_bus_id);
+
+	/* Start it up */
+	priv->irq = irq;
+	return ata_host_activate(priv->host, irq, ata_sff_interrupt, 0,
+				 &pata_macio_sht);
+}
+
+static int __devinit pata_macio_attach(struct macio_dev *mdev,
+				       const struct of_device_id *match)
+{
+	struct pata_macio_priv	*priv;
+	resource_size_t		tfregs, dmaregs = 0;
+	unsigned long		irq;
+	int			rc;
+
+	/* Check for broken device-trees */
+	if (macio_resource_count(mdev) == 0) {
+		dev_err(&mdev->ofdev.dev,
+			"No addresses for controller\n");
+		return -ENXIO;
+	}
+
+	/* Enable managed resources */
+	macio_enable_devres(mdev);
+
+	/* Allocate and init private data structure */
+	priv = devm_kzalloc(&mdev->ofdev.dev,
+			    sizeof(struct pata_macio_priv), GFP_KERNEL);
+	if (priv == NULL) {
+		dev_err(&mdev->ofdev.dev,
+			"Failed to allocate private memory\n");
+		return -ENOMEM;
+	}
+	priv->node = of_node_get(mdev->ofdev.node);
+	priv->mdev = mdev;
+	priv->dev = &mdev->ofdev.dev;
+
+	/* Request memory resource for taskfile registers */
+	if (macio_request_resource(mdev, 0, "pata-macio")) {
+		dev_err(&mdev->ofdev.dev,
+			"Cannot obtain taskfile resource\n");
+		return -EBUSY;
+	}
+	tfregs = macio_resource_start(mdev, 0);
+
+	/* Request resources for DMA registers if any */
+	if (macio_resource_count(mdev) >= 2) {
+		if (macio_request_resource(mdev, 1, "pata-macio-dma"))
+			dev_err(&mdev->ofdev.dev,
+				"Cannot obtain DMA resource\n");
+		else
+			dmaregs = macio_resource_start(mdev, 1);
+	}
+
+	/*
+	 * Fixup missing IRQ for some old implementations with broken
+	 * device-trees.
+	 *
+	 * This is a bit bogus, it should be fixed in the device-tree itself,
+	 * via the existing macio fixups, based on the type of interrupt
+	 * controller in the machine. However, I have no test HW for this case,
+	 * and this trick works well enough on those old machines...
+	 */
+	if (macio_irq_count(mdev) == 0) {
+		dev_warn(&mdev->ofdev.dev,
+			 "No interrupts for controller, using 13\n");
+		irq = irq_create_mapping(NULL, 13);
+	} else
+		irq = macio_irq(mdev, 0);
+
+	/* Prevvent media bay callbacks until fully registered */
+	lock_media_bay(priv->mdev->media_bay);
+
+	/* Get register addresses and call common initialization */
+	rc = pata_macio_common_init(priv,
+				    tfregs,		/* Taskfile regs */
+				    dmaregs,		/* DBDMA regs */
+				    0,			/* Feature control */
+				    irq);
+	unlock_media_bay(priv->mdev->media_bay);
+
+	return rc;
+}
+
+static int __devexit pata_macio_detach(struct macio_dev *mdev)
+{
+	struct ata_host *host = macio_get_drvdata(mdev);
+	struct pata_macio_priv *priv = host->private_data;
+
+	lock_media_bay(priv->mdev->media_bay);
+
+	/* Make sure the mediabay callback doesn't try to access
+	 * dead stuff
+	 */
+	priv->host->private_data = NULL;
+
+	ata_host_detach(host);
+
+	unlock_media_bay(priv->mdev->media_bay);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int pata_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
+{
+	struct ata_host *host = macio_get_drvdata(mdev);
+
+	return pata_macio_do_suspend(host->private_data, mesg);
+}
+
+static int pata_macio_resume(struct macio_dev *mdev)
+{
+	struct ata_host *host = macio_get_drvdata(mdev);
+
+	return pata_macio_do_resume(host->private_data);
+}
+
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PMAC_MEDIABAY
+static void pata_macio_mb_event(struct macio_dev* mdev, int mb_state)
+{
+	struct ata_host *host = macio_get_drvdata(mdev);
+	struct ata_port *ap;
+	struct ata_eh_info *ehi;
+	struct ata_device *dev;
+	unsigned long flags;
+
+	if (!host || !host->private_data)
+		return;
+	ap = host->ports[0];
+	spin_lock_irqsave(ap->lock, flags);
+	ehi = &ap->link.eh_info;
+	if (mb_state == MB_CD) {
+		ata_ehi_push_desc(ehi, "mediabay plug");
+		ata_ehi_hotplugged(ehi);
+		ata_port_freeze(ap);
+	} else {
+		ata_ehi_push_desc(ehi, "mediabay unplug");
+		ata_for_each_dev(dev, &ap->link, ALL)
+			dev->flags |= ATA_DFLAG_DETACH;
+		ata_port_abort(ap);
+	}
+	spin_unlock_irqrestore(ap->lock, flags);
+
+}
+#endif /* CONFIG_PMAC_MEDIABAY */
+
+
+static int __devinit pata_macio_pci_attach(struct pci_dev *pdev,
+					   const struct pci_device_id *id)
+{
+	struct pata_macio_priv	*priv;
+	struct device_node	*np;
+	resource_size_t		rbase;
+
+	/* We cannot use a MacIO controller without its OF device node */
+	np = pci_device_to_OF_node(pdev);
+	if (np == NULL) {
+		dev_err(&pdev->dev,
+			"Cannot find OF device node for controller\n");
+		return -ENODEV;
+	}
+
+	/* Check that it can be enabled */
+	if (pcim_enable_device(pdev)) {
+		dev_err(&pdev->dev,
+			"Cannot enable controller PCI device\n");
+		return -ENXIO;
+	}
+
+	/* Allocate and init private data structure */
+	priv = devm_kzalloc(&pdev->dev,
+			    sizeof(struct pata_macio_priv), GFP_KERNEL);
+	if (priv == NULL) {
+		dev_err(&pdev->dev,
+			"Failed to allocate private memory\n");
+		return -ENOMEM;
+	}
+	priv->node = of_node_get(np);
+	priv->pdev = pdev;
+	priv->dev = &pdev->dev;
+
+	/* Get MMIO regions */
+	if (pci_request_regions(pdev, "pata-macio")) {
+		dev_err(&pdev->dev,
+			"Cannot obtain PCI resources\n");
+		return -EBUSY;
+	}
+
+	/* Get register addresses and call common initialization */
+	rbase = pci_resource_start(pdev, 0);
+	if (pata_macio_common_init(priv,
+				   rbase + 0x2000,	/* Taskfile regs */
+				   rbase + 0x1000,	/* DBDMA regs */
+				   rbase,		/* Feature control */
+				   pdev->irq))
+		return -ENXIO;
+
+	return 0;
+}
+
+static void __devexit pata_macio_pci_detach(struct pci_dev *pdev)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+
+	ata_host_detach(host);
+}
+
+#ifdef CONFIG_PM
+
+static int pata_macio_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+
+	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);
+
+	return pata_macio_do_resume(host->private_data);
+}
+
+#endif /* CONFIG_PM */
+
+static struct of_device_id pata_macio_match[] =
+{
+	{
+	.name 		= "IDE",
+	},
+	{
+	.name 		= "ATA",
+	},
+	{
+	.type		= "ide",
+	},
+	{
+	.type		= "ata",
+	},
+	{},
+};
+
+static struct macio_driver pata_macio_driver =
+{
+	.name 		= "pata-macio",
+	.match_table	= pata_macio_match,
+	.probe		= pata_macio_attach,
+	.remove		= pata_macio_detach,
+#ifdef CONFIG_PM
+	.suspend	= pata_macio_suspend,
+	.resume		= pata_macio_resume,
+#endif
+#ifdef CONFIG_PMAC_MEDIABAY
+	.mediabay_event	= pata_macio_mb_event,
+#endif
+	.driver = {
+		.owner		= THIS_MODULE,
+	},
+};
+
+static const struct pci_device_id pata_macio_pci_match[] = {
+	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA),	0 },
+	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100),	0 },
+	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100),	0 },
+	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_SH_ATA),	0 },
+	{ PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA),	0 },
+	{},
+};
+
+static struct pci_driver pata_macio_pci_driver = {
+	.name		= "pata-pci-macio",
+	.id_table	= pata_macio_pci_match,
+	.probe		= pata_macio_pci_attach,
+	.remove		= pata_macio_pci_detach,
+#ifdef CONFIG_PM
+	.suspend	= pata_macio_pci_suspend,
+	.resume		= pata_macio_pci_resume,
+#endif
+	.driver = {
+		.owner		= THIS_MODULE,
+	},
+};
+MODULE_DEVICE_TABLE(pci, pata_macio_pci_match);
+
+
+static int __init pata_macio_init(void)
+{
+	int rc;
+
+	if (!machine_is(powermac))
+		return -ENODEV;
+
+	rc = pci_register_driver(&pata_macio_pci_driver);
+	if (rc)
+		return rc;
+	rc = macio_register_driver(&pata_macio_driver);
+	if (rc) {
+		pci_unregister_driver(&pata_macio_pci_driver);
+		return rc;
+	}
+	return 0;
+}
+
+static void __exit pata_macio_exit(void)
+{
+	macio_unregister_driver(&pata_macio_driver);
+	pci_unregister_driver(&pata_macio_pci_driver);
+}
+
+module_init(pata_macio_init);
+module_exit(pata_macio_exit);
+
+MODULE_AUTHOR("Benjamin Herrenschmidt");
+MODULE_DESCRIPTION("Apple MacIO PATA driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_marvell.c linux-libre-2.6.33-gnu1/drivers/ata/pata_marvell.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_marvell.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_marvell.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@ static int marvell_pata_active(struct pc
 }
 
 /**
- *	marvell_pre_reset	-	check for 40/80 pin
+ *	marvell_pre_reset	-	probe begin
  *	@link: link
  *	@deadline: deadline jiffies for the operation
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_ns87415.c linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87415.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_ns87415.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_ns87415.c	2010-02-24 13:52:17.000000000 -0500
@@ -325,6 +325,13 @@ static struct scsi_host_template ns87415
 	ATA_BMDMA_SHT(DRV_NAME),
 };
 
+static void ns87415_fixup(struct pci_dev *pdev)
+{
+	/* Select 512 byte sectors */
+	pci_write_config_byte(pdev, 0x55, 0xEE);
+	/* Select PIO0 8bit clocking */
+	pci_write_config_byte(pdev, 0x54, 0xB7);
+}
 
 /**
  *	ns87415_init_one - Register 87415 ATA PCI device with kernel services
@@ -371,10 +378,8 @@ static int ns87415_init_one (struct pci_
 	if (rc)
 		return rc;
 
-	/* Select 512 byte sectors */
-	pci_write_config_byte(pdev, 0x55, 0xEE);
-	/* Select PIO0 8bit clocking */
-	pci_write_config_byte(pdev, 0x54, 0xB7);
+	ns87415_fixup(pdev);
+
 	return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
 }
 
@@ -384,6 +389,23 @@ static const struct pci_device_id ns8741
 	{ }	/* terminate list */
 };
 
+#ifdef CONFIG_PM
+static int ns87415_reinit_one(struct pci_dev *pdev)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	int rc;
+
+	rc = ata_pci_device_do_resume(pdev);
+	if (rc)
+		return rc;
+
+	ns87415_fixup(pdev);
+
+	ata_host_resume(host);
+	return 0;
+}
+#endif
+
 static struct pci_driver ns87415_pci_driver = {
 	.name			= DRV_NAME,
 	.id_table		= ns87415_pci_tbl,
@@ -391,7 +413,7 @@ static struct pci_driver ns87415_pci_dri
 	.remove			= ata_pci_remove_one,
 #ifdef CONFIG_PM
 	.suspend		= ata_pci_device_suspend,
-	.resume			= ata_pci_device_resume,
+	.resume			= ns87415_reinit_one,
 #endif
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_octeon_cf.c linux-libre-2.6.33-gnu1/drivers/ata/pata_octeon_cf.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_octeon_cf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_octeon_cf.c	2010-02-24 13:52:17.000000000 -0500
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(str
 			return -EINVAL;
 
 		cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
-					   res_cs0->end - res_cs1->start + 1);
+					   resource_size(res_cs1));
 
 		if (!cs1)
 			return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_oldpiix.c linux-libre-2.6.33-gnu1/drivers/ata/pata_oldpiix.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_oldpiix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_oldpiix.c	2010-02-24 13:52:17.000000000 -0500
@@ -239,7 +239,7 @@ static int oldpiix_init_one (struct pci_
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= ATA_PIO4,
-		.mwdma_mask	= ATA_MWDMA2,
+		.mwdma_mask	= ATA_MWDMA12_ONLY,
 		.port_ops	= &oldpiix_pata_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_pcmcia.c linux-libre-2.6.33-gnu1/drivers/ata/pata_pcmcia.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_pcmcia.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
@@ -177,9 +177,6 @@ static struct ata_port_operations pcmcia
 	.drain_fifo	= pcmcia_8bit_drain_fifo,
 };
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 
 struct pcmcia_config_check {
 	unsigned long ctl_base;
@@ -252,7 +249,7 @@ static int pcmcia_init_one(struct pcmcia
 	struct ata_port *ap;
 	struct ata_pcmcia_info *info;
 	struct pcmcia_config_check *stk = NULL;
-	int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
+	int is_kme = 0, ret = -ENOMEM, p;
 	unsigned long io_base, ctl_base;
 	void __iomem *io_addr, *ctl_addr;
 	int n_ports = 1;
@@ -271,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia
 	pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 	pdev->io.IOAddrLines = 3;
 	pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-	pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	pdev->conf.Attributes = CONF_ENABLE_IRQ;
 	pdev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -296,8 +292,13 @@ static int pcmcia_init_one(struct pcmcia
 	}
 	io_base = pdev->io.BasePort1;
 	ctl_base = stk->ctl_base;
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+	ret = pcmcia_request_irq(pdev, &pdev->irq);
+	if (ret)
+		goto failed;
+
+	ret = pcmcia_request_configuration(pdev, &pdev->conf);
+	if (ret)
+		goto failed;
 
 	/* iomap */
 	ret = -ENOMEM;
@@ -351,8 +352,6 @@ static int pcmcia_init_one(struct pcmcia
 	kfree(stk);
 	return 0;
 
-cs_failed:
-	cs_error(pdev, last_fn, last_ret);
 failed:
 	kfree(stk);
 	info->ndev = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_piccolo.c linux-libre-2.6.33-gnu1/drivers/ata/pata_piccolo.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_piccolo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_piccolo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,140 @@
+/*
+ *  pata_piccolo.c - Toshiba Piccolo PATA/SATA controller driver.
+ *
+ *  This is basically an update to ata_generic.c to add Toshiba Piccolo support
+ *  then split out to keep ata_generic "clean".
+ *
+ *  Copyright 2005 Red Hat Inc, all rights reserved.
+ *
+ *  Elements from ide/pci/generic.c
+ *	    Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
+ *	    Portions (C) Copyright 2002  Red Hat Inc <alan@redhat.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ *
+ *  The timing data tables/programming info are courtesy of the NetBSD driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pata_piccolo"
+#define DRV_VERSION "0.0.1"
+
+
+
+static void tosh_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	static const u16 pio[6] = {	/* For reg 0x50 low word & E088 */
+		0x0566, 0x0433, 0x0311, 0x0201, 0x0200, 0x0100
+	};
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	u16 conf;
+	pci_read_config_word(pdev, 0x50, &conf);
+	conf &= 0xE088;
+	conf |= pio[adev->pio_mode - XFER_PIO_0];
+	pci_write_config_word(pdev, 0x50, conf);
+}
+
+static void tosh_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	u32 conf;
+	pci_read_config_dword(pdev, 0x5C, &conf);
+	conf &= 0x78FFE088;	/* Keep the other bits */
+	if (adev->dma_mode >= XFER_UDMA_0) {
+		int udma = adev->dma_mode - XFER_UDMA_0;
+		conf |= 0x80000000;
+		conf |= (udma + 2) << 28;
+		conf |= (2 - udma) * 0x111;	/* spread into three nibbles */
+	} else {
+		static const u32 mwdma[4] = {
+			0x0655, 0x0200, 0x0200, 0x0100
+		};
+		conf |= mwdma[adev->dma_mode - XFER_MW_DMA_0];
+	}
+	pci_write_config_dword(pdev, 0x5C, conf);
+}
+
+
+static struct scsi_host_template tosh_sht = {
+	ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations tosh_port_ops = {
+	.inherits	= &ata_bmdma_port_ops,
+	.cable_detect	= ata_cable_unknown,
+	.set_piomode	= tosh_set_piomode,
+	.set_dmamode	= tosh_set_dmamode
+};
+
+/**
+ *	ata_tosh_init		-	attach generic IDE
+ *	@dev: PCI device found
+ *	@id: match entry
+ *
+ *	Called each time a matching IDE interface is found. We check if the
+ *	interface is one we wish to claim and if so we perform any chip
+ *	specific hacks then let the ATA layer do the heavy lifting.
+ */
+
+static int ata_tosh_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	static const struct ata_port_info info = {
+		.flags = ATA_FLAG_SLAVE_POSS,
+		.pio_mask = ATA_PIO5,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
+		.port_ops = &tosh_port_ops
+	};
+	const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+	/* Just one port for the moment */
+	return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL);
+}
+
+static struct pci_device_id ata_tosh[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2),  },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_3),  },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5),  },
+	{ 0, },
+};
+
+static struct pci_driver ata_tosh_pci_driver = {
+	.name 		= DRV_NAME,
+	.id_table	= ata_tosh,
+	.probe 		= ata_tosh_init_one,
+	.remove		= ata_pci_remove_one,
+#ifdef CONFIG_PM
+	.suspend	= ata_pci_device_suspend,
+	.resume		= ata_pci_device_resume,
+#endif
+};
+
+static int __init ata_tosh_init(void)
+{
+	return pci_register_driver(&ata_tosh_pci_driver);
+}
+
+
+static void __exit ata_tosh_exit(void)
+{
+	pci_unregister_driver(&ata_tosh_pci_driver);
+}
+
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("Low level driver for Toshiba Piccolo ATA");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, ata_tosh);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(ata_tosh_init);
+module_exit(ata_tosh_exit);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_radisys.c linux-libre-2.6.33-gnu1/drivers/ata/pata_radisys.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_radisys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_radisys.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,9 +139,9 @@ static void radisys_set_dmamode (struct
 		pci_read_config_byte(dev, 0x4A, &udma_mode);
 
 		if (adev->xfer_mode == XFER_UDMA_2)
-			udma_mode &= ~ (1 << adev->devno);
+			udma_mode &= ~(2 << (adev->devno * 4));
 		else /* UDMA 4 */
-			udma_mode |= (1 << adev->devno);
+			udma_mode |= (2 << (adev->devno * 4));
 
 		pci_write_config_byte(dev, 0x4A, udma_mode);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_rdc.c linux-libre-2.6.33-gnu1/drivers/ata/pata_rdc.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_rdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_rdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,7 +284,7 @@ static struct ata_port_info rdc_port_inf
 
 	.flags		= ATA_FLAG_SLAVE_POSS,
 	.pio_mask	= ATA_PIO4,
-	.mwdma_mask	= ATA_MWDMA2,
+	.mwdma_mask	= ATA_MWDMA12_ONLY,
 	.udma_mask	= ATA_UDMA5,
 	.port_ops	= &rdc_pata_ops,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_rz1000.c linux-libre-2.6.33-gnu1/drivers/ata/pata_rz1000.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_rz1000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_rz1000.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,11 +105,20 @@ 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);
+	int rc;
+
+	rc = ata_pci_device_do_resume(pdev);
+	if (rc)
+		return rc;
+
 	/* If this fails on resume (which is a "cant happen" case), we
 	   must stop as any progress risks data loss */
 	if (rz1000_fifo_disable(pdev))
 		panic("rz1000 fifo");
-	return ata_pci_device_resume(pdev);
+
+	ata_host_resume(host);
+	return 0;
 }
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_sil680.c linux-libre-2.6.33-gnu1/drivers/ata/pata_sil680.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_sil680.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_sil680.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,13 +212,11 @@ static struct ata_port_operations sil680
 
 static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
 {
-	u32 class_rev	= 0;
 	u8 tmpbyte	= 0;
 
-        pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-        class_rev &= 0xff;
         /* FIXME: double check */
-	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255);
+	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+			      pdev->revision ? 1 : 255);
 
 	pci_write_config_byte(pdev, 0x80, 0x00);
 	pci_write_config_byte(pdev, 0x84, 0x00);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_sis.c linux-libre-2.6.33-gnu1/drivers/ata/pata_sis.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_sis.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_sis.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  *    pata_sis.c - SiS ATA driver
  *
  *	(C) 2005 Red Hat
- *	(C) 2007 Bartlomiej Zolnierkiewicz
+ *	(C) 2007,2009 Bartlomiej Zolnierkiewicz
  *
  *    Based upon linux/drivers/ide/pci/sis5513.c
  * Copyright (C) 1999-2000	Andre Hedrick <andre@linux-ide.org>
@@ -829,6 +829,23 @@ static int sis_init_one (struct pci_dev
 	return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset);
 }
 
+#ifdef CONFIG_PM
+static int sis_reinit_one(struct pci_dev *pdev)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	int rc;
+
+	rc = ata_pci_device_do_resume(pdev);
+	if (rc)
+		return rc;
+
+	sis_fixup(pdev, host->private_data);
+
+	ata_host_resume(host);
+	return 0;
+}
+#endif
+
 static const struct pci_device_id sis_pci_tbl[] = {
 	{ PCI_VDEVICE(SI, 0x5513), },	/* SiS 5513 */
 	{ PCI_VDEVICE(SI, 0x5518), },	/* SiS 5518 */
@@ -844,7 +861,7 @@ static struct pci_driver sis_pci_driver
 	.remove			= ata_pci_remove_one,
 #ifdef CONFIG_PM
 	.suspend		= ata_pci_device_suspend,
-	.resume			= ata_pci_device_resume,
+	.resume			= sis_reinit_one,
 #endif
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/pata_via.c linux-libre-2.6.33-gnu1/drivers/ata/pata_via.c
--- linux-libre-2.6.32-gnu1/drivers/ata/pata_via.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/pata_via.c	2010-02-24 13:52:17.000000000 -0500
@@ -303,14 +303,21 @@ static void via_do_set_mode(struct ata_p
 	}
 
 	/* Set UDMA unless device is not UDMA capable */
-	if (udma_type && t.udma) {
-		u8 cable80_status;
+	if (udma_type) {
+		u8 udma_etc;
 
-		/* Get 80-wire cable detection bit */
-		pci_read_config_byte(pdev, 0x50 + offset, &cable80_status);
-		cable80_status &= 0x10;
+		pci_read_config_byte(pdev, 0x50 + offset, &udma_etc);
 
-		pci_write_config_byte(pdev, 0x50 + offset, ut | cable80_status);
+		/* clear transfer mode bit */
+		udma_etc &= ~0x20;
+
+		if (t.udma) {
+			/* preserve 80-wire cable detection bit */
+			udma_etc &= 0x10;
+			udma_etc |= ut;
+		}
+
+		pci_write_config_byte(pdev, 0x50 + offset, udma_etc);
 	}
 }
 
@@ -337,6 +344,32 @@ static void via_set_dmamode(struct ata_p
 }
 
 /**
+ *	via_mode_filter		-	filter buggy device/mode pairs
+ *	@dev: ATA device
+ *	@mask: Mode bitmask
+ *
+ *	We need to apply some minimal filtering for old controllers and at least
+ *	one breed of Transcend SSD. Return the updated mask.
+ */
+
+static unsigned long via_mode_filter(struct ata_device *dev, unsigned long mask)
+{
+	struct ata_host *host = dev->link->ap->host;
+	const struct via_isa_bridge *config = host->private_data;
+	unsigned char model_num[ATA_ID_PROD_LEN + 1];
+
+	if (config->id == PCI_DEVICE_ID_VIA_82C586_0) {
+		ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+		if (strcmp(model_num, "TS64GSSD25-M") == 0) {
+			ata_dev_printk(dev, KERN_WARNING,
+	"disabling UDMA mode due to reported lockups with this device.\n");
+			mask &= ~ ATA_MASK_UDMA;
+		}
+	}
+	return ata_bmdma_mode_filter(dev, mask);
+}
+
+/**
  *	via_tf_load - send taskfile registers to host controller
  *	@ap: Port to which output is sent
  *	@tf: ATA taskfile register set
@@ -427,6 +460,7 @@ static struct ata_port_operations via_po
 	.prereset	= via_pre_reset,
 	.sff_tf_load	= via_tf_load,
 	.port_start	= via_port_start,
+	.mode_filter	= via_mode_filter,
 };
 
 static struct ata_port_operations via_port_ops_noirq = {
@@ -526,7 +560,7 @@ static int via_init_one(struct pci_dev *
 		.port_ops = &via_port_ops
 	};
 	const struct ata_port_info *ppi[] = { NULL, NULL };
-	struct pci_dev *isa = NULL;
+	struct pci_dev *isa;
 	const struct via_isa_bridge *config;
 	static int printed_version;
 	u8 enable;
@@ -551,15 +585,13 @@ static int via_init_one(struct pci_dev *
 		if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
 			!!(config->flags & VIA_BAD_ID),
 			config->id, NULL))) {
+			u8 rev = isa->revision;
+			pci_dev_put(isa);
 
-			if (isa->revision >= config->rev_min &&
-			    isa->revision <= config->rev_max)
+			if (rev >= config->rev_min && rev <= config->rev_max)
 				break;
-			pci_dev_put(isa);
 		}
 
-	pci_dev_put(isa);
-
 	if (!(config->flags & VIA_NO_ENABLES)) {
 		/* 0x40 low bits indicate enabled channels */
 		pci_read_config_byte(pdev, 0x40 , &enable);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/sata_fsl.c linux-libre-2.6.33-gnu1/drivers/ata/sata_fsl.c
--- linux-libre-2.6.32-gnu1/drivers/ata/sata_fsl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/sata_fsl.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@ enum {
 
 	SATA_FSL_HOST_FLAGS	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-				ATA_FLAG_PMP | ATA_FLAG_NCQ),
+				ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN),
 
 	SATA_FSL_MAX_CMDS	= SATA_FSL_QUEUE_DEPTH,
 	SATA_FSL_CMD_HDR_SIZE	= 16,	/* 4 DWORDS */
@@ -43,9 +43,9 @@ enum {
 	/*
 	 * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
 	 * chained indirect PRDEs upto a max count of 63.
-	 * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will
+	 * We are allocating an array of 63 PRDEs contiguously, but PRDE#15 will
 	 * be setup as an indirect descriptor, pointing to it's next
-	 * (contigious) PRDE. Though chained indirect PRDE arrays are
+	 * (contiguous) PRDE. Though chained indirect PRDE arrays are
 	 * supported,it will be more efficient to use a direct PRDT and
 	 * a single chain/link to indirect PRDE array/PRDT.
 	 */
@@ -132,7 +132,7 @@ enum {
 	INT_ON_SINGL_DEVICE_ERR = (1 << 1),
 	INT_ON_CMD_COMPLETE = 1,
 
-	INT_ON_ERROR = INT_ON_FATAL_ERR |
+	INT_ON_ERROR = INT_ON_FATAL_ERR | INT_ON_SNOTIFY_UPDATE |
 	    INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR,
 
 	/*
@@ -153,7 +153,7 @@ enum {
 	IE_ON_CMD_COMPLETE = 1,
 
 	DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG |
-	    IE_ON_SIGNATURE_UPDATE |
+	    IE_ON_SIGNATURE_UPDATE | IE_ON_SNOTIFY_UPDATE |
 	    IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
 
 	EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
@@ -314,7 +314,7 @@ static unsigned int sata_fsl_fill_sg(str
 	u32 ttl_dwords = 0;
 
 	/*
-	 * NOTE : direct & indirect prdt's are contigiously allocated
+	 * NOTE : direct & indirect prdt's are contiguously allocated
 	 */
 	struct prde *prd = (struct prde *)&((struct command_desc *)
 					    cmd_desc)->prdt;
@@ -992,9 +992,8 @@ static void sata_fsl_error_intr(struct a
 	 */
 
 	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
-	if (unlikely(SError & 0xFFFF0000)) {
+	if (unlikely(SError & 0xFFFF0000))
 		sata_fsl_scr_write(&ap->link, SCR_ERROR, SError);
-	}
 
 	DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
 		hstatus, cereg, ioread32(hcr_base + DE), SError);
@@ -1007,6 +1006,10 @@ static void sata_fsl_error_intr(struct a
 		freeze = 1;
 	}
 
+	/* Handle SDB FIS receive & notify update */
+	if (hstatus & INT_ON_SNOTIFY_UPDATE)
+		sata_async_notification(ap);
+
 	/* Handle PHYRDY change notification */
 	if (hstatus & INT_ON_PHYRDY_CHG) {
 		DPRINTK("SATA FSL: PHYRDY change indication\n");
@@ -1070,9 +1073,9 @@ static void sata_fsl_error_intr(struct a
 	}
 
 	/* record error info */
-	if (qc) {
+	if (qc)
 		qc->err_mask |= err_mask;
-	} else
+	else
 		ehi->err_mask |= err_mask;
 
 	ehi->action |= action;
@@ -1103,7 +1106,6 @@ static void sata_fsl_host_intr(struct at
 	if (unlikely(SError & 0xFFFF0000)) {
 		DPRINTK("serror @host_intr : 0x%x\n", SError);
 		sata_fsl_error_intr(ap);
-
 	}
 
 	if (unlikely(hstatus & INT_ON_ERROR)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/sata_mv.c linux-libre-2.6.33-gnu1/drivers/ata/sata_mv.c
--- linux-libre-2.6.32-gnu1/drivers/ata/sata_mv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/sata_mv.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,7 @@
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
@@ -538,6 +539,7 @@ struct mv_port_signal {
 
 struct mv_host_priv {
 	u32			hp_flags;
+	unsigned int 		board_idx;
 	u32			main_irq_mask;
 	struct mv_port_signal	signal[8];
 	const struct mv_hw_ops	*ops;
@@ -548,6 +550,10 @@ struct mv_host_priv {
 	u32			irq_cause_offset;
 	u32			irq_mask_offset;
 	u32			unmask_all_irqs;
+
+#if defined(CONFIG_HAVE_CLK)
+	struct clk		*clk;
+#endif
 	/*
 	 * These consistent DMA memory pools give us guaranteed
 	 * alignment for hardware-accessed data structures,
@@ -2217,7 +2223,7 @@ static unsigned int mv_qc_issue_fis(stru
 	int err = 0;
 
 	ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis);
-	err = mv_send_fis(ap, fis, sizeof(fis) / sizeof(fis[0]));
+	err = mv_send_fis(ap, fis, ARRAY_SIZE(fis));
 	if (err)
 		return err;
 
@@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port
 	struct mv_port_priv *pp;
 	int edma_was_enabled;
 
-	if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+	if (ap->flags & ATA_FLAG_DISABLED) {
 		mv_unexpected_intr(ap, 0);
 		return;
 	}
@@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct
 	ZERO(0x024);		/* respq outp */
 	ZERO(0x020);		/* respq inp */
 	ZERO(0x02c);		/* test control */
-	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+	writel(0x800, port_mmio + EDMA_IORDY_TMOUT);
 }
 
 #undef ZERO
@@ -3854,7 +3860,6 @@ static int mv_chip_id(struct ata_host *h
 /**
  *      mv_init_host - Perform some early initialization of the host.
  *	@host: ATA host to initialize
- *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
@@ -3862,13 +3867,13 @@ static int mv_chip_id(struct ata_host *h
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct ata_host *host, unsigned int board_idx)
+static int mv_init_host(struct ata_host *host)
 {
 	int rc = 0, n_hc, port, hc;
 	struct mv_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = hpriv->base;
 
-	rc = mv_chip_id(host, board_idx);
+	rc = mv_chip_id(host, hpriv->board_idx);
 	if (rc)
 		goto done;
 
@@ -3905,14 +3910,6 @@ static int mv_init_host(struct ata_host
 		void __iomem *port_mmio = mv_port_base(mmio, port);
 
 		mv_port_init(&ap->ioaddr, port_mmio);
-
-#ifdef CONFIG_PCI
-		if (!IS_SOC(hpriv)) {
-			unsigned int offset = port_mmio - mmio;
-			ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
-			ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
-		}
-#endif
 	}
 
 	for (hc = 0; hc < n_hc; hc++) {
@@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct plat
 		return -ENOMEM;
 	host->private_data = hpriv;
 	hpriv->n_ports = n_ports;
+	hpriv->board_idx = chip_soc;
 
 	host->iomap = NULL;
 	hpriv->base = devm_ioremap(&pdev->dev, res->start,
 				   resource_size(res));
 	hpriv->base -= SATAHC0_REG_BASE;
 
+#if defined(CONFIG_HAVE_CLK)
+	hpriv->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(hpriv->clk))
+		dev_notice(&pdev->dev, "cannot get clkdev\n");
+	else
+		clk_enable(hpriv->clk);
+#endif
+
 	/*
 	 * (Re-)program MBUS remapping windows if we are asked to.
 	 */
@@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct plat
 
 	rc = mv_create_dma_pools(hpriv, &pdev->dev);
 	if (rc)
-		return rc;
+		goto err;
 
 	/* initialize adapter */
-	rc = mv_init_host(host, chip_soc);
+	rc = mv_init_host(host);
 	if (rc)
-		return rc;
+		goto err;
 
 	dev_printk(KERN_INFO, &pdev->dev,
 		   "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH,
@@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct plat
 
 	return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
 				 IRQF_SHARED, &mv6_sht);
+err:
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(hpriv->clk)) {
+		clk_disable(hpriv->clk);
+		clk_put(hpriv->clk);
+	}
+#endif
+
+	return rc;
 }
 
 /*
@@ -4076,14 +4091,66 @@ static int __devexit mv_platform_remove(
 {
 	struct device *dev = &pdev->dev;
 	struct ata_host *host = dev_get_drvdata(dev);
-
+#if defined(CONFIG_HAVE_CLK)
+	struct mv_host_priv *hpriv = host->private_data;
+#endif
 	ata_host_detach(host);
+
+#if defined(CONFIG_HAVE_CLK)
+	if (!IS_ERR(hpriv->clk)) {
+		clk_disable(hpriv->clk);
+		clk_put(hpriv->clk);
+	}
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	if (host)
+		return ata_host_suspend(host, state);
+	else
+		return 0;
+}
+
+static int mv_platform_resume(struct platform_device *pdev)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	int ret;
+
+	if (host) {
+		struct mv_host_priv *hpriv = host->private_data;
+		const struct mv_sata_platform_data *mv_platform_data = \
+			pdev->dev.platform_data;
+		/*
+		 * (Re-)program MBUS remapping windows if we are asked to.
+		 */
+		if (mv_platform_data->dram != NULL)
+			mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
+
+		/* initialize adapter */
+		ret = mv_init_host(host);
+		if (ret) {
+			printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+			return ret;
+		}
+		ata_host_resume(host);
+	}
+
 	return 0;
 }
+#else
+#define mv_platform_suspend NULL
+#define mv_platform_resume NULL
+#endif
 
 static struct platform_driver mv_platform_driver = {
 	.probe			= mv_platform_probe,
 	.remove			= __devexit_p(mv_platform_remove),
+	.suspend		= mv_platform_suspend,
+	.resume			= mv_platform_resume,
 	.driver			= {
 				   .name = DRV_NAME,
 				   .owner = THIS_MODULE,
@@ -4094,6 +4161,9 @@ static struct platform_driver mv_platfor
 #ifdef CONFIG_PCI
 static int mv_pci_init_one(struct pci_dev *pdev,
 			   const struct pci_device_id *ent);
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev);
+#endif
 
 
 static struct pci_driver mv_pci_driver = {
@@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver =
 	.id_table		= mv_pci_tbl,
 	.probe			= mv_pci_init_one,
 	.remove			= ata_pci_remove_one,
+#ifdef CONFIG_PM
+	.suspend		= ata_pci_device_suspend,
+	.resume			= mv_pci_device_resume,
+#endif
+
 };
 
 /* move to PCI layer or libata core? */
@@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_de
 	const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
 	struct ata_host *host;
 	struct mv_host_priv *hpriv;
-	int n_ports, rc;
+	int n_ports, port, rc;
 
 	if (!printed_version++)
 		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_de
 		return -ENOMEM;
 	host->private_data = hpriv;
 	hpriv->n_ports = n_ports;
+	hpriv->board_idx = board_idx;
 
 	/* acquire resources */
 	rc = pcim_enable_device(pdev);
@@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_de
 	if (rc)
 		return rc;
 
+	for (port = 0; port < host->n_ports; port++) {
+		struct ata_port *ap = host->ports[port];
+		void __iomem *port_mmio = mv_port_base(hpriv->base, port);
+		unsigned int offset = port_mmio - hpriv->base;
+
+		ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
+		ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
+	}
+
 	/* initialize adapter */
-	rc = mv_init_host(host, board_idx);
+	rc = mv_init_host(host);
 	if (rc)
 		return rc;
 
@@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_de
 	return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
 				 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
+
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	int rc;
+
+	rc = ata_pci_device_do_resume(pdev);
+	if (rc)
+		return rc;
+
+	/* initialize adapter */
+	rc = mv_init_host(host);
+	if (rc)
+		return rc;
+
+	ata_host_resume(host);
+
+	return 0;
+}
+#endif
 #endif
 
 static int mv_platform_probe(struct platform_device *pdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/sata_nv.c linux-libre-2.6.33-gnu1/drivers/ata/sata_nv.c
--- linux-libre-2.6.32-gnu1/drivers/ata/sata_nv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/sata_nv.c	2010-02-24 13:52:17.000000000 -0500
@@ -1975,7 +1975,7 @@ static int nv_swncq_slave_config(struct
 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 
 	if (strncmp(model_num, "Maxtor", 6) == 0) {
-		ata_scsi_change_queue_depth(sdev, 1);
+		ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT);
 		ata_dev_printk(dev, KERN_NOTICE,
 			"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/sata_promise.c linux-libre-2.6.33-gnu1/drivers/ata/sata_promise.c
--- linux-libre-2.6.32-gnu1/drivers/ata/sata_promise.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/sata_promise.c	2010-02-24 13:52:17.000000000 -0500
@@ -862,7 +862,7 @@ static void pdc_error_intr(struct ata_po
 	if (port_status & PDC_DRIVE_ERR)
 		ac_err_mask |= AC_ERR_DEV;
 	if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR))
-		ac_err_mask |= AC_ERR_HSM;
+		ac_err_mask |= AC_ERR_OTHER;
 	if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR))
 		ac_err_mask |= AC_ERR_ATA_BUS;
 	if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR
diff -druNp linux-libre-2.6.32-gnu1/drivers/ata/sata_sil24.c linux-libre-2.6.33-gnu1/drivers/ata/sata_sil24.c
--- linux-libre-2.6.32-gnu1/drivers/ata/sata_sil24.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ata/sata_sil24.c	2010-02-24 13:52:17.000000000 -0500
@@ -417,6 +417,10 @@ static struct ata_port_operations sil24_
 #endif
 };
 
+static int sata_sil24_msi;    /* Disable MSI */
+module_param_named(msi, sata_sil24_msi, bool, S_IRUGO);
+MODULE_PARM_DESC(msi, "Enable MSI (Default: false)");
+
 /*
  * Use bits 30-31 of port_flags to encode available port numbers.
  * Current maxium is 4.
@@ -1340,6 +1344,11 @@ static int sil24_init_one(struct pci_dev
 
 	sil24_init_controller(host);
 
+	if (sata_sil24_msi && !pci_enable_msi(pdev)) {
+		dev_printk(KERN_INFO, &pdev->dev, "Using MSI\n");
+		pci_intx(pdev, 0);
+	}
+
 	pci_set_master(pdev);
 	return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
 				 &sil24_sht);
diff -druNp linux-libre-2.6.32-gnu1/drivers/atm/ambassador.c linux-libre-2.6.33-gnu1/drivers/atm/ambassador.c
--- linux-libre-2.6.32-gnu1/drivers/atm/ambassador.c	2013-05-03 13:55:18.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/atm/ambassador.c	2013-05-03 12:02:51.000000000 -0400
@@ -2351,6 +2351,7 @@ static void __init amb_check_args (void)
 MODULE_AUTHOR(maintainer_string);
 MODULE_DESCRIPTION(description_string);
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 module_param(debug,   ushort, 0644);
 module_param(cmds,    uint, 0);
 module_param(txs,     uint, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/atm/fore200e.c linux-libre-2.6.33-gnu1/drivers/atm/fore200e.c
--- linux-libre-2.6.32-gnu1/drivers/atm/fore200e.c	2013-05-03 13:55:23.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/atm/fore200e.c	2013-05-03 12:02:56.000000000 -0400
@@ -2902,8 +2902,8 @@ fore200e_proc_read(struct atm_dev *dev,
 	u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
 	u32 oc3_index;
 
-	if ((media_index < 0) || (media_index > 4))
-	    media_index = 5;
+	if (media_index > 4)
+		media_index = 5;
 	
 	switch (fore200e->loop_mode) {
 	    case ATM_LM_NONE:    oc3_index = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/atm/he.c linux-libre-2.6.33-gnu1/drivers/atm/he.c
--- linux-libre-2.6.32-gnu1/drivers/atm/he.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/atm/he.c	2010-02-24 13:52:17.000000000 -0500
@@ -2505,7 +2505,7 @@ he_close(struct atm_vcc *vcc)
 		 * TBRQ, the host issues the close command to the adapter.
 		 */
 
-		while (((tx_inuse = atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) > 0) &&
+		while (((tx_inuse = atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) > 1) &&
 		       (retry < MAX_RETRY)) {
 			msleep(sleep);
 			if (sleep < 250)
@@ -2514,7 +2514,7 @@ he_close(struct atm_vcc *vcc)
 			++retry;
 		}
 
-		if (tx_inuse)
+		if (tx_inuse > 1)
 			hprintk("close tx cid 0x%x tx_inuse = %d\n", cid, tx_inuse);
 
 		/* 2.3.1.1 generic close operations with flush */
@@ -2739,7 +2739,7 @@ he_ioctl(struct atm_dev *atm_dev, unsign
 			spin_lock_irqsave(&he_dev->global_lock, flags);
 			switch (reg.type) {
 				case HE_REGTYPE_PCI:
-					if (reg.addr < 0 || reg.addr >= HE_REGMAP_SIZE) {
+					if (reg.addr >= HE_REGMAP_SIZE) {
 						err = -EINVAL;
 						break;
 					}
diff -druNp linux-libre-2.6.32-gnu1/drivers/atm/iphase.c linux-libre-2.6.33-gnu1/drivers/atm/iphase.c
--- linux-libre-2.6.32-gnu1/drivers/atm/iphase.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/atm/iphase.c	2010-02-24 13:52:17.000000000 -0500
@@ -557,7 +557,7 @@ static int ia_cbr_setup (IADEV *dev, str
           memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
        } /* while */
        // Move this VCI number into this location of the CBR Sched table.
-       memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex,sizeof(TstSchedTbl));
+       memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex, sizeof(*TstSchedTbl));
        dev->CbrRemEntries--;
        toBeAssigned--;
    } /* while */ 
@@ -1132,7 +1132,7 @@ static int rx_pkt(struct atm_dev *dev)
                     IF_ERR(printk(" cause: packet time out\n");)
                 }
                 else {
-                    IF_ERR(printk(" cause: buffer over flow\n");)
+                    IF_ERR(printk(" cause: buffer overflow\n");)
                 }
 		goto out_free_desc;
 	}  
diff -druNp linux-libre-2.6.32-gnu1/drivers/atm/solos-pci.c linux-libre-2.6.33-gnu1/drivers/atm/solos-pci.c
--- linux-libre-2.6.32-gnu1/drivers/atm/solos-pci.c	2013-05-03 13:55:30.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/atm/solos-pci.c	2013-05-03 12:03:04.000000000 -0400
@@ -142,6 +142,7 @@ MODULE_AUTHOR("Traverse Technologies <su
 MODULE_DESCRIPTION("Solos PCI driver");
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
 MODULE_PARM_DESC(atmdebug, "Print ATM data");
 MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
@@ -528,34 +529,37 @@ static int flash_upgrade(struct solos_ca
 	int numblocks = 0;
 	int offset;
 
-	if (chip == 0) {
+	switch (chip) {
+	case 0:
 		fw_name = "/*(DEBLOBBED)*/";
 		blocksize = FPGA_BLOCK;
-	} 
-	
-	if (chip == 1) {
+		break;
+	case 1:
 		fw_name = "/*(DEBLOBBED)*/";
 		blocksize = SOLOS_BLOCK;
-	}
-	
-	if (chip == 2){
+		break;
+	case 2:
 		if (card->fpga_version > LEGACY_BUFFERS){
 			fw_name = "/*(DEBLOBBED)*/";
 			blocksize = FPGA_BLOCK;
 		} else {
-			dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
+			dev_info(&card->dev->dev, "FPGA version doesn't support"
+					" daughter board upgrades\n");
 			return -EPERM;
 		}
-	}
-	
-	if (chip == 3){
+		break;
+	case 3:
 		if (card->fpga_version > LEGACY_BUFFERS){
 			fw_name = "/*(DEBLOBBED)*/";
 			blocksize = SOLOS_BLOCK;
 		} else {
-		dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
-		return -EPERM;
+			dev_info(&card->dev->dev, "FPGA version doesn't support"
+					" daughter board upgrades\n");
+			return -EPERM;
 		}
+		break;
+	default:
+		return -ENODEV;
 	}
 
 	if (reject_firmware(&fw, fw_name, &card->dev->dev))
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/bus.c linux-libre-2.6.33-gnu1/drivers/base/bus.c
--- linux-libre-2.6.32-gnu1/drivers/base/bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -703,9 +703,9 @@ int bus_add_driver(struct device_driver
 	return 0;
 
 out_unregister:
+	kobject_put(&priv->kobj);
 	kfree(drv->p);
 	drv->p = NULL;
-	kobject_put(&priv->kobj);
 out_put_bus:
 	bus_put(bus);
 	return error;
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/class.c linux-libre-2.6.33-gnu1/drivers/base/class.c
--- linux-libre-2.6.32-gnu1/drivers/base/class.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/class.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,8 @@ static void class_release(struct kobject
 	else
 		pr_debug("class '%s' does not have a release() function, "
 			 "be careful\n", class->name);
+
+	kfree(cp);
 }
 
 static struct sysfs_ops class_sysfs_ops = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/core.c linux-libre-2.6.33-gnu1/drivers/base/core.c
--- linux-libre-2.6.32-gnu1/drivers/base/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,14 @@ static inline int device_is_not_partitio
  */
 const char *dev_driver_string(const struct device *dev)
 {
-	return dev->driver ? dev->driver->name :
+	struct device_driver *drv;
+
+	/* dev->driver can change to NULL underneath us because of unbinding,
+	 * so be careful about accessing it.  dev->bus and dev->class should
+	 * never change once they are set, so they don't need special care.
+	 */
+	drv = ACCESS_ONCE(dev->driver);
+	return drv ? drv->name :
 			(dev->bus ? dev->bus->name :
 			(dev->class ? dev->class->name : ""));
 }
@@ -439,7 +446,8 @@ struct kset *devices_kset;
  * @dev: device.
  * @attr: device attribute descriptor.
  */
-int device_create_file(struct device *dev, struct device_attribute *attr)
+int device_create_file(struct device *dev,
+		       const struct device_attribute *attr)
 {
 	int error = 0;
 	if (dev)
@@ -452,7 +460,8 @@ int device_create_file(struct device *de
  * @dev: device.
  * @attr: device attribute descriptor.
  */
-void device_remove_file(struct device *dev, struct device_attribute *attr)
+void device_remove_file(struct device *dev,
+			const struct device_attribute *attr)
 {
 	if (dev)
 		sysfs_remove_file(&dev->kobj, &attr->attr);
@@ -463,7 +472,8 @@ void device_remove_file(struct device *d
  * @dev: device.
  * @attr: device binary attribute descriptor.
  */
-int device_create_bin_file(struct device *dev, struct bin_attribute *attr)
+int device_create_bin_file(struct device *dev,
+			   const struct bin_attribute *attr)
 {
 	int error = -EINVAL;
 	if (dev)
@@ -477,7 +487,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file
  * @dev: device.
  * @attr: device binary attribute descriptor.
  */
-void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
+void device_remove_bin_file(struct device *dev,
+			    const struct bin_attribute *attr)
 {
 	if (dev)
 		sysfs_remove_bin_file(&dev->kobj, attr);
@@ -898,8 +909,10 @@ int device_add(struct device *dev)
 		dev->init_name = NULL;
 	}
 
-	if (!dev_name(dev))
+	if (!dev_name(dev)) {
+		error = -EINVAL;
 		goto name_error;
+	}
 
 	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
 
@@ -987,6 +1000,8 @@ done:
 	device_remove_class_symlinks(dev);
  SymlinkError:
 	if (MAJOR(dev->devt))
+		devtmpfs_delete_node(dev);
+	if (MAJOR(dev->devt))
 		device_remove_sys_dev_entry(dev);
  devtattrError:
 	if (MAJOR(dev->devt))
@@ -1728,8 +1743,5 @@ void device_shutdown(void)
 			dev->driver->shutdown(dev);
 		}
 	}
-	kobject_put(sysfs_dev_char_kobj);
-	kobject_put(sysfs_dev_block_kobj);
-	kobject_put(dev_kobj);
 	async_synchronize_full();
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/cpu.c linux-libre-2.6.33-gnu1/drivers/base/cpu.c
--- linux-libre-2.6.32-gnu1/drivers/base/cpu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/cpu.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@ static ssize_t __ref store_online(struct
 	struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 	ssize_t ret;
 
+	cpu_hotplug_driver_lock();
 	switch (buf[0]) {
 	case '0':
 		ret = cpu_down(cpu->sysdev.id);
@@ -49,6 +50,7 @@ static ssize_t __ref store_online(struct
 	default:
 		ret = -EINVAL;
 	}
+	cpu_hotplug_driver_unlock();
 
 	if (ret >= 0)
 		ret = count;
@@ -72,6 +74,38 @@ void unregister_cpu(struct cpu *cpu)
 	per_cpu(cpu_sys_devices, logical_cpu) = NULL;
 	return;
 }
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+static ssize_t cpu_probe_store(struct class *class, const char *buf,
+			       size_t count)
+{
+	return arch_cpu_probe(buf, count);
+}
+
+static ssize_t cpu_release_store(struct class *class, const char *buf,
+				 size_t count)
+{
+	return arch_cpu_release(buf, count);
+}
+
+static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
+
+int __init cpu_probe_release_init(void)
+{
+	int rc;
+
+	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+			       &class_attr_probe.attr);
+	if (!rc)
+		rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+				       &class_attr_release.attr);
+
+	return rc;
+}
+device_initcall(cpu_probe_release_init);
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
 #else /* ... !CONFIG_HOTPLUG_CPU */
 static inline void register_cpu_control(struct cpu *cpu)
 {
@@ -97,7 +131,7 @@ static ssize_t show_crash_notes(struct s
 	 * boot up and this data does not change there after. Hence this
 	 * operation should be safe. No locking required.
 	 */
-	addr = __pa(per_cpu_ptr(crash_notes, cpunum));
+	addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
 	rc = sprintf(buf, "%Lx\n", addr);
 	return rc;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/dd.c linux-libre-2.6.33-gnu1/drivers/base/dd.c
--- linux-libre-2.6.32-gnu1/drivers/base/dd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/dd.c	2010-02-24 13:52:17.000000000 -0500
@@ -188,7 +188,7 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe)
  * @dev: device to try to bind to the driver
  *
  * This function returns -ENODEV if the device is not registered,
- * 1 if the device is bound sucessfully and 0 otherwise.
+ * 1 if the device is bound successfully and 0 otherwise.
  *
  * This function must be called with @dev->sem held.  When called for a
  * USB interface, @dev->parent->sem must be held as well.
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/devtmpfs.c linux-libre-2.6.33-gnu1/drivers/base/devtmpfs.c
--- linux-libre-2.6.32-gnu1/drivers/base/devtmpfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/devtmpfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,8 @@ static int dev_mount = 1;
 static int dev_mount;
 #endif
 
+static DEFINE_MUTEX(dirlock);
+
 static int __init mount_param(char *str)
 {
 	dev_mount = simple_strtoul(str, NULL, 0);
@@ -74,47 +76,37 @@ static int dev_mkdir(const char *name, m
 	dentry = lookup_create(&nd, 1);
 	if (!IS_ERR(dentry)) {
 		err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
+		if (!err)
+			/* mark as kernel-created inode */
+			dentry->d_inode->i_private = &dev_mnt;
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 	return err;
 }
 
 static int create_path(const char *nodepath)
 {
-	char *path;
-	struct nameidata nd;
-	int err = 0;
-
-	path = kstrdup(nodepath, GFP_KERNEL);
-	if (!path)
-		return -ENOMEM;
-
-	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
-			      path, LOOKUP_PARENT, &nd);
-	if (err == 0) {
-		struct dentry *dentry;
-
-		/* create directory right away */
-		dentry = lookup_create(&nd, 1);
-		if (!IS_ERR(dentry)) {
-			err = vfs_mkdir(nd.path.dentry->d_inode,
-					dentry, 0755);
-			dput(dentry);
-		}
-		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+	int err;
 
-		path_put(&nd.path);
-	} else if (err == -ENOENT) {
+	mutex_lock(&dirlock);
+	err = dev_mkdir(nodepath, 0755);
+	if (err == -ENOENT) {
+		char *path;
 		char *s;
 
 		/* parent directories do not exist, create them */
+		path = kstrdup(nodepath, GFP_KERNEL);
+		if (!path) {
+			err = -ENOMEM;
+			goto out;
+		}
 		s = path;
-		while (1) {
+		for (;;) {
 			s = strchr(s, '/');
 			if (!s)
 				break;
@@ -125,9 +117,10 @@ static int create_path(const char *nodep
 			s[0] = '/';
 			s++;
 		}
+		kfree(path);
 	}
-
-	kfree(path);
+out:
+	mutex_unlock(&dirlock);
 	return err;
 }
 
@@ -156,34 +149,40 @@ int devtmpfs_create_node(struct device *
 		mode |= S_IFCHR;
 
 	curr_cred = override_creds(&init_cred);
+
 	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
 			      nodename, LOOKUP_PARENT, &nd);
 	if (err == -ENOENT) {
-		/* create missing parent directories */
 		create_path(nodename);
 		err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
 				      nodename, LOOKUP_PARENT, &nd);
-		if (err)
-			goto out;
 	}
+	if (err)
+		goto out;
 
 	dentry = lookup_create(&nd, 0);
 	if (!IS_ERR(dentry)) {
-		int umask;
-
-		umask = sys_umask(0000);
 		err = vfs_mknod(nd.path.dentry->d_inode,
 				dentry, mode, dev->devt);
-		sys_umask(umask);
-		/* mark as kernel created inode */
-		if (!err)
+		if (!err) {
+			struct iattr newattrs;
+
+			/* fixup possibly umasked mode */
+			newattrs.ia_mode = mode;
+			newattrs.ia_valid = ATTR_MODE;
+			mutex_lock(&dentry->d_inode->i_mutex);
+			notify_change(dentry, &newattrs);
+			mutex_unlock(&dentry->d_inode->i_mutex);
+
+			/* mark as kernel-created inode */
 			dentry->d_inode->i_private = &dev_mnt;
+		}
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 out:
 	kfree(tmp);
@@ -205,16 +204,21 @@ static int dev_rmdir(const char *name)
 	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
 	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
 	if (!IS_ERR(dentry)) {
-		if (dentry->d_inode)
-			err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
-		else
+		if (dentry->d_inode) {
+			if (dentry->d_inode->i_private == &dev_mnt)
+				err = vfs_rmdir(nd.path.dentry->d_inode,
+						dentry);
+			else
+				err = -EPERM;
+		} else {
 			err = -ENOENT;
+		}
 		dput(dentry);
 	} else {
 		err = PTR_ERR(dentry);
 	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 	path_put(&nd.path);
 	return err;
 }
@@ -228,7 +232,8 @@ static int delete_path(const char *nodep
 	if (!path)
 		return -ENOMEM;
 
-	while (1) {
+	mutex_lock(&dirlock);
+	for (;;) {
 		char *base;
 
 		base = strrchr(path, '/');
@@ -239,6 +244,7 @@ static int delete_path(const char *nodep
 		if (err)
 			break;
 	}
+	mutex_unlock(&dirlock);
 
 	kfree(path);
 	return err;
@@ -322,9 +328,8 @@ out:
  * If configured, or requested by the commandline, devtmpfs will be
  * auto-mounted after the kernel mounted the root filesystem.
  */
-int devtmpfs_mount(const char *mountpoint)
+int devtmpfs_mount(const char *mntdir)
 {
-	struct path path;
 	int err;
 
 	if (!dev_mount)
@@ -333,15 +338,11 @@ int devtmpfs_mount(const char *mountpoin
 	if (!dev_mnt)
 		return 0;
 
-	err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
-	if (err)
-		return err;
-	err = do_add_mount(dev_mnt, &path, 0, NULL);
+	err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
 		printk(KERN_INFO "devtmpfs: mounted\n");
-	path_put(&path);
 	return err;
 }
 
@@ -353,6 +354,7 @@ int __init devtmpfs_init(void)
 {
 	int err;
 	struct vfsmount *mnt;
+	char options[] = "mode=0755";
 
 	err = register_filesystem(&dev_fs_type);
 	if (err) {
@@ -361,7 +363,7 @@ int __init devtmpfs_init(void)
 		return err;
 	}
 
-	mnt = kern_mount(&dev_fs_type);
+	mnt = kern_mount_data(&dev_fs_type, options);
 	if (IS_ERR(mnt)) {
 		err = PTR_ERR(mnt);
 		printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/driver.c linux-libre-2.6.33-gnu1/drivers/base/driver.c
--- linux-libre-2.6.32-gnu1/drivers/base/driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(driver_find_device);
  * @attr: driver attribute descriptor.
  */
 int driver_create_file(struct device_driver *drv,
-		       struct driver_attribute *attr)
+		       const struct driver_attribute *attr)
 {
 	int error;
 	if (drv)
@@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(driver_create_file);
  * @attr: driver attribute descriptor.
  */
 void driver_remove_file(struct device_driver *drv,
-			struct driver_attribute *attr)
+			const struct driver_attribute *attr)
 {
 	if (drv)
 		sysfs_remove_file(&drv->p->kobj, &attr->attr);
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/firmware_class.c linux-libre-2.6.33-gnu1/drivers/base/firmware_class.c
--- linux-libre-2.6.32-gnu1/drivers/base/firmware_class.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/firmware_class.c	2010-02-24 13:52:17.000000000 -0500
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg)
 	}
 	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
 		fw_work->uevent);
-	if (ret < 0)
-		fw_work->cont(NULL, fw_work->context);
-	else {
-		fw_work->cont(fw, fw_work->context);
-		release_firmware(fw);
-	}
+
+	fw_work->cont(fw, fw_work->context);
+
 	module_put(fw_work->module);
 	kfree(fw_work);
 	return ret;
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg)
  *	is non-zero else the firmware copy must be done manually.
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
+ * @gfp: allocation flags
  * @context: will be passed over to @cont, and
  *	@fw may be %NULL if firmware request fails.
  * @cont: function will be called asynchronously when the firmware
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg)
 int
 request_firmware_nowait(
 	struct module *module, int uevent,
-	const char *name, struct device *device, void *context,
+	const char *name, struct device *device, gfp_t gfp, void *context,
 	void (*cont)(const struct firmware *fw, void *context))
 {
 	struct task_struct *task;
 	struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-						GFP_ATOMIC);
+						gfp);
 
 	if (!fw_work)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/memory.c linux-libre-2.6.33-gnu1/drivers/base/memory.c
--- linux-libre-2.6.32-gnu1/drivers/base/memory.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -63,6 +63,20 @@ void unregister_memory_notifier(struct n
 }
 EXPORT_SYMBOL(unregister_memory_notifier);
 
+static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain);
+
+int register_memory_isolate_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&memory_isolate_chain, nb);
+}
+EXPORT_SYMBOL(register_memory_isolate_notifier);
+
+void unregister_memory_isolate_notifier(struct notifier_block *nb)
+{
+	atomic_notifier_chain_unregister(&memory_isolate_chain, nb);
+}
+EXPORT_SYMBOL(unregister_memory_isolate_notifier);
+
 /*
  * register_memory - Setup a sysfs device for a memory block
  */
@@ -157,6 +171,11 @@ int memory_notify(unsigned long val, voi
 	return blocking_notifier_call_chain(&memory_chain, val, v);
 }
 
+int memory_isolate_notify(unsigned long val, void *v)
+{
+	return atomic_notifier_call_chain(&memory_isolate_chain, val, v);
+}
+
 /*
  * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
  * OK to have direct references to sparsemem variables in here.
@@ -292,7 +311,7 @@ static SYSDEV_ATTR(removable, 0444, show
 static ssize_t
 print_block_size(struct class *class, char *buf)
 {
-	return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+	return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
 static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
@@ -341,6 +360,64 @@ static inline int memory_probe_init(void
 }
 #endif
 
+#ifdef CONFIG_MEMORY_FAILURE
+/*
+ * Support for offlining pages of memory
+ */
+
+/* Soft offline a page */
+static ssize_t
+store_soft_offline_page(struct class *class, const char *buf, size_t count)
+{
+	int ret;
+	u64 pfn;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	if (strict_strtoull(buf, 0, &pfn) < 0)
+		return -EINVAL;
+	pfn >>= PAGE_SHIFT;
+	if (!pfn_valid(pfn))
+		return -ENXIO;
+	ret = soft_offline_page(pfn_to_page(pfn), 0);
+	return ret == 0 ? count : ret;
+}
+
+/* Forcibly offline a page, including killing processes. */
+static ssize_t
+store_hard_offline_page(struct class *class, const char *buf, size_t count)
+{
+	int ret;
+	u64 pfn;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	if (strict_strtoull(buf, 0, &pfn) < 0)
+		return -EINVAL;
+	pfn >>= PAGE_SHIFT;
+	ret = __memory_failure(pfn, 0, 0);
+	return ret ? ret : count;
+}
+
+static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
+static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
+
+static __init int memory_fail_init(void)
+{
+	int err;
+
+	err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
+				&class_attr_soft_offline_page.attr);
+	if (!err)
+		err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
+				&class_attr_hard_offline_page.attr);
+	return err;
+}
+#else
+static inline int memory_fail_init(void)
+{
+	return 0;
+}
+#endif
+
 /*
  * Note that phys_device is optional.  It is here to allow for
  * differentiation between which *physical* devices each
@@ -473,6 +550,9 @@ int __init memory_dev_init(void)
 	err = memory_probe_init();
 	if (!ret)
 		ret = err;
+	err = memory_fail_init();
+	if (!ret)
+		ret = err;
 	err = block_size_init();
 	if (!ret)
 		ret = err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/node.c linux-libre-2.6.33-gnu1/drivers/base/node.c
--- linux-libre-2.6.32-gnu1/drivers/base/node.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/node.c	2010-02-24 13:52:17.000000000 -0500
@@ -173,6 +173,47 @@ static ssize_t node_read_distance(struct
 }
 static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
 
+#ifdef CONFIG_HUGETLBFS
+/*
+ * hugetlbfs per node attributes registration interface:
+ * When/if hugetlb[fs] subsystem initializes [sometime after this module],
+ * it will register its per node attributes for all online nodes with
+ * memory.  It will also call register_hugetlbfs_with_node(), below, to
+ * register its attribute registration functions with this node driver.
+ * Once these hooks have been initialized, the node driver will call into
+ * the hugetlb module to [un]register attributes for hot-plugged nodes.
+ */
+static node_registration_func_t __hugetlb_register_node;
+static node_registration_func_t __hugetlb_unregister_node;
+
+static inline bool hugetlb_register_node(struct node *node)
+{
+	if (__hugetlb_register_node &&
+			node_state(node->sysdev.id, N_HIGH_MEMORY)) {
+		__hugetlb_register_node(node);
+		return true;
+	}
+	return false;
+}
+
+static inline void hugetlb_unregister_node(struct node *node)
+{
+	if (__hugetlb_unregister_node)
+		__hugetlb_unregister_node(node);
+}
+
+void register_hugetlbfs_with_node(node_registration_func_t doregister,
+				  node_registration_func_t unregister)
+{
+	__hugetlb_register_node   = doregister;
+	__hugetlb_unregister_node = unregister;
+}
+#else
+static inline void hugetlb_register_node(struct node *node) {}
+
+static inline void hugetlb_unregister_node(struct node *node) {}
+#endif
+
 
 /*
  * register_node - Setup a sysfs device for a node.
@@ -196,6 +237,8 @@ int register_node(struct node *node, int
 		sysdev_create_file(&node->sysdev, &attr_distance);
 
 		scan_unevictable_register_node(node);
+
+		hugetlb_register_node(node);
 	}
 	return error;
 }
@@ -216,6 +259,7 @@ void unregister_node(struct node *node)
 	sysdev_remove_file(&node->sysdev, &attr_distance);
 
 	scan_unevictable_unregister_node(node);
+	hugetlb_unregister_node(node);		/* no-op, if memoryless node */
 
 	sysdev_unregister(&node->sysdev);
 }
@@ -227,26 +271,43 @@ struct node node_devices[MAX_NUMNODES];
  */
 int register_cpu_under_node(unsigned int cpu, unsigned int nid)
 {
-	if (node_online(nid)) {
-		struct sys_device *obj = get_cpu_sysdev(cpu);
-		if (!obj)
-			return 0;
-		return sysfs_create_link(&node_devices[nid].sysdev.kobj,
-					 &obj->kobj,
-					 kobject_name(&obj->kobj));
-	 }
+	int ret;
+	struct sys_device *obj;
 
-	return 0;
+	if (!node_online(nid))
+		return 0;
+
+	obj = get_cpu_sysdev(cpu);
+	if (!obj)
+		return 0;
+
+	ret = sysfs_create_link(&node_devices[nid].sysdev.kobj,
+				&obj->kobj,
+				kobject_name(&obj->kobj));
+	if (ret)
+		return ret;
+
+	return sysfs_create_link(&obj->kobj,
+				 &node_devices[nid].sysdev.kobj,
+				 kobject_name(&node_devices[nid].sysdev.kobj));
 }
 
 int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
 {
-	if (node_online(nid)) {
-		struct sys_device *obj = get_cpu_sysdev(cpu);
-		if (obj)
-			sysfs_remove_link(&node_devices[nid].sysdev.kobj,
-					 kobject_name(&obj->kobj));
-	}
+	struct sys_device *obj;
+
+	if (!node_online(nid))
+		return 0;
+
+	obj = get_cpu_sysdev(cpu);
+	if (!obj)
+		return 0;
+
+	sysfs_remove_link(&node_devices[nid].sysdev.kobj,
+			  kobject_name(&obj->kobj));
+	sysfs_remove_link(&obj->kobj,
+			  kobject_name(&node_devices[nid].sysdev.kobj));
+
 	return 0;
 }
 
@@ -268,6 +329,7 @@ static int get_nid_for_pfn(unsigned long
 /* register memory section under specified node if it spans that node */
 int register_mem_sect_under_node(struct memory_block *mem_blk, int nid)
 {
+	int ret;
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
 
 	if (!mem_blk)
@@ -284,9 +346,15 @@ int register_mem_sect_under_node(struct
 			continue;
 		if (page_nid != nid)
 			continue;
-		return sysfs_create_link_nowarn(&node_devices[nid].sysdev.kobj,
+		ret = sysfs_create_link_nowarn(&node_devices[nid].sysdev.kobj,
 					&mem_blk->sysdev.kobj,
 					kobject_name(&mem_blk->sysdev.kobj));
+		if (ret)
+			return ret;
+
+		return sysfs_create_link_nowarn(&mem_blk->sysdev.kobj,
+				&node_devices[nid].sysdev.kobj,
+				kobject_name(&node_devices[nid].sysdev.kobj));
 	}
 	/* mem section does not span the specified node */
 	return 0;
@@ -295,12 +363,16 @@ int register_mem_sect_under_node(struct
 /* unregister memory section under all nodes that it spans */
 int unregister_mem_sect_under_nodes(struct memory_block *mem_blk)
 {
-	nodemask_t unlinked_nodes;
+	NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
 
-	if (!mem_blk)
+	if (!mem_blk) {
+		NODEMASK_FREE(unlinked_nodes);
 		return -EFAULT;
-	nodes_clear(unlinked_nodes);
+	}
+	if (!unlinked_nodes)
+		return -ENOMEM;
+	nodes_clear(*unlinked_nodes);
 	sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index);
 	sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
 	for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
@@ -311,11 +383,14 @@ int unregister_mem_sect_under_nodes(stru
 			continue;
 		if (!node_online(nid))
 			continue;
-		if (node_test_and_set(nid, unlinked_nodes))
+		if (node_test_and_set(nid, *unlinked_nodes))
 			continue;
 		sysfs_remove_link(&node_devices[nid].sysdev.kobj,
 			 kobject_name(&mem_blk->sysdev.kobj));
+		sysfs_remove_link(&mem_blk->sysdev.kobj,
+			 kobject_name(&node_devices[nid].sysdev.kobj));
 	}
+	NODEMASK_FREE(unlinked_nodes);
 	return 0;
 }
 
@@ -345,9 +420,77 @@ static int link_mem_sections(int nid)
 	}
 	return err;
 }
-#else
+
+#ifdef CONFIG_HUGETLBFS
+/*
+ * Handle per node hstate attribute [un]registration on transistions
+ * to/from memoryless state.
+ */
+static void node_hugetlb_work(struct work_struct *work)
+{
+	struct node *node = container_of(work, struct node, node_work);
+
+	/*
+	 * We only get here when a node transitions to/from memoryless state.
+	 * We can detect which transition occurred by examining whether the
+	 * node has memory now.  hugetlb_register_node() already check this
+	 * so we try to register the attributes.  If that fails, then the
+	 * node has transitioned to memoryless, try to unregister the
+	 * attributes.
+	 */
+	if (!hugetlb_register_node(node))
+		hugetlb_unregister_node(node);
+}
+
+static void init_node_hugetlb_work(int nid)
+{
+	INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work);
+}
+
+static int node_memory_callback(struct notifier_block *self,
+				unsigned long action, void *arg)
+{
+	struct memory_notify *mnb = arg;
+	int nid = mnb->status_change_nid;
+
+	switch (action) {
+	case MEM_ONLINE:
+	case MEM_OFFLINE:
+		/*
+		 * offload per node hstate [un]registration to a work thread
+		 * when transitioning to/from memoryless state.
+		 */
+		if (nid != NUMA_NO_NODE)
+			schedule_work(&node_devices[nid].node_work);
+		break;
+
+	case MEM_GOING_ONLINE:
+	case MEM_GOING_OFFLINE:
+	case MEM_CANCEL_ONLINE:
+	case MEM_CANCEL_OFFLINE:
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+#endif	/* CONFIG_HUGETLBFS */
+#else	/* !CONFIG_MEMORY_HOTPLUG_SPARSE */
+
 static int link_mem_sections(int nid) { return 0; }
-#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
+#endif	/* CONFIG_MEMORY_HOTPLUG_SPARSE */
+
+#if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \
+    !defined(CONFIG_HUGETLBFS)
+static inline int node_memory_callback(struct notifier_block *self,
+				unsigned long action, void *arg)
+{
+	return NOTIFY_OK;
+}
+
+static void init_node_hugetlb_work(int nid) { }
+
+#endif
 
 int register_one_node(int nid)
 {
@@ -371,6 +514,9 @@ int register_one_node(int nid)
 
 		/* link memory sections under this node */
 		error = link_mem_sections(nid);
+
+		/* initialize work queue for memory hot plug */
+		init_node_hugetlb_work(nid);
 	}
 
 	return error;
@@ -460,13 +606,17 @@ static int node_states_init(void)
 	return err;
 }
 
+#define NODE_CALLBACK_PRI	2	/* lower than SLAB */
 static int __init register_node_type(void)
 {
 	int ret;
 
 	ret = sysdev_class_register(&node_class);
-	if (!ret)
+	if (!ret) {
 		ret = node_states_init();
+		hotplug_memory_notifier(node_memory_callback,
+					NODE_CALLBACK_PRI);
+	}
 
 	/*
 	 * Note:  we're not going to unregister the node class if we fail
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/platform.c linux-libre-2.6.33-gnu1/drivers/base/platform.c
--- linux-libre-2.6.32-gnu1/drivers/base/platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -441,6 +441,7 @@ error:
 	platform_device_put(pdev);
 	return ERR_PTR(retval);
 }
+EXPORT_SYMBOL_GPL(platform_device_register_data);
 
 static int platform_drv_probe(struct device *_dev)
 {
@@ -1000,7 +1001,7 @@ static __initdata LIST_HEAD(early_platfo
 int __init early_platform_driver_register(struct early_platform_driver *epdrv,
 					  char *buf)
 {
-	unsigned long index;
+	char *tmp;
 	int n;
 
 	/* Simply add the driver to the end of the global list.
@@ -1019,13 +1020,28 @@ int __init early_platform_driver_registe
 	if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
 		list_move(&epdrv->list, &early_platform_driver_list);
 
-		if (!strcmp(buf, epdrv->pdrv->driver.name))
+		/* Allow passing parameters after device name */
+		if (buf[n] == '\0' || buf[n] == ',')
 			epdrv->requested_id = -1;
-		else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10,
-							 &index) == 0)
-			epdrv->requested_id = index;
-		else
-			epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+		else {
+			epdrv->requested_id = simple_strtoul(&buf[n + 1],
+							     &tmp, 10);
+
+			if (buf[n] != '.' || (tmp == &buf[n + 1])) {
+				epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+				n = 0;
+			} else
+				n += strcspn(&buf[n + 1], ",") + 1;
+		}
+
+		if (buf[n] == ',')
+			n++;
+
+		if (epdrv->bufsize) {
+			memcpy(epdrv->buffer, &buf[n],
+			       min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
+			epdrv->buffer[epdrv->bufsize - 1] = '\0';
+		}
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/power/main.c linux-libre-2.6.33-gnu1/drivers/base/power/main.c
--- linux-libre-2.6.32-gnu1/drivers/base/power/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/power/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,8 +23,8 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/resume-trace.h>
-#include <linux/rwsem.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 
 #include "../base.h"
 #include "power.h"
@@ -161,6 +161,32 @@ void device_pm_move_last(struct device *
 	list_move_tail(&dev->power.entry, &dpm_list);
 }
 
+static ktime_t initcall_debug_start(struct device *dev)
+{
+	ktime_t calltime = ktime_set(0, 0);
+
+	if (initcall_debug) {
+		pr_info("calling  %s+ @ %i\n",
+				dev_name(dev), task_pid_nr(current));
+		calltime = ktime_get();
+	}
+
+	return calltime;
+}
+
+static void initcall_debug_report(struct device *dev, ktime_t calltime,
+				  int error)
+{
+	ktime_t delta, rettime;
+
+	if (initcall_debug) {
+		rettime = ktime_get();
+		delta = ktime_sub(rettime, calltime);
+		pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
+			error, (unsigned long long)ktime_to_ns(delta) >> 10);
+	}
+}
+
 /**
  * pm_op - Execute the PM operation appropriate for given PM event.
  * @dev: Device to handle.
@@ -172,6 +198,9 @@ static int pm_op(struct device *dev,
 		 pm_message_t state)
 {
 	int error = 0;
+	ktime_t calltime;
+
+	calltime = initcall_debug_start(dev);
 
 	switch (state.event) {
 #ifdef CONFIG_SUSPEND
@@ -219,6 +248,9 @@ static int pm_op(struct device *dev,
 	default:
 		error = -EINVAL;
 	}
+
+	initcall_debug_report(dev, calltime, error);
+
 	return error;
 }
 
@@ -236,6 +268,13 @@ static int pm_noirq_op(struct device *de
 			pm_message_t state)
 {
 	int error = 0;
+	ktime_t calltime, delta, rettime;
+
+	if (initcall_debug) {
+		pr_info("calling  %s_i+ @ %i\n",
+				dev_name(dev), task_pid_nr(current));
+		calltime = ktime_get();
+	}
 
 	switch (state.event) {
 #ifdef CONFIG_SUSPEND
@@ -283,6 +322,15 @@ static int pm_noirq_op(struct device *de
 	default:
 		error = -EINVAL;
 	}
+
+	if (initcall_debug) {
+		rettime = ktime_get();
+		delta = ktime_sub(rettime, calltime);
+		printk("initcall %s_i+ returned %d after %Ld usecs\n",
+			dev_name(dev), error,
+			(unsigned long long)ktime_to_ns(delta) >> 10);
+	}
+
 	return error;
 }
 
@@ -324,6 +372,23 @@ static void pm_dev_err(struct device *de
 		kobject_name(&dev->kobj), pm_verb(state.event), info, error);
 }
 
+static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
+{
+	ktime_t calltime;
+	s64 usecs64;
+	int usecs;
+
+	calltime = ktime_get();
+	usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
+	do_div(usecs64, NSEC_PER_USEC);
+	usecs = usecs64;
+	if (usecs == 0)
+		usecs = 1;
+	pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n",
+		info ?: "", info ? " " : "", pm_verb(state.event),
+		usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
+}
+
 /*------------------------- Resume routines -------------------------*/
 
 /**
@@ -341,14 +406,11 @@ static int device_resume_noirq(struct de
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
 
-	if (!dev->bus)
-		goto End;
-
-	if (dev->bus->pm) {
+	if (dev->bus && dev->bus->pm) {
 		pm_dev_dbg(dev, state, "EARLY ");
 		error = pm_noirq_op(dev, dev->bus->pm, state);
 	}
- End:
+
 	TRACE_RESUME(error);
 	return error;
 }
@@ -363,6 +425,7 @@ static int device_resume_noirq(struct de
 void dpm_resume_noirq(pm_message_t state)
 {
 	struct device *dev;
+	ktime_t starttime = ktime_get();
 
 	mutex_lock(&dpm_list_mtx);
 	transition_started = false;
@@ -376,11 +439,32 @@ void dpm_resume_noirq(pm_message_t state
 				pm_dev_err(dev, state, " early", error);
 		}
 	mutex_unlock(&dpm_list_mtx);
+	dpm_show_time(starttime, state, "early");
 	resume_device_irqs();
 }
 EXPORT_SYMBOL_GPL(dpm_resume_noirq);
 
 /**
+ * legacy_resume - Execute a legacy (bus or class) resume callback for device.
+ * @dev: Device to resume.
+ * @cb: Resume callback to execute.
+ */
+static int legacy_resume(struct device *dev, int (*cb)(struct device *dev))
+{
+	int error;
+	ktime_t calltime;
+
+	calltime = initcall_debug_start(dev);
+
+	error = cb(dev);
+	suspend_report_result(cb, error);
+
+	initcall_debug_report(dev, calltime, error);
+
+	return error;
+}
+
+/**
  * device_resume - Execute "resume" callbacks for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
@@ -400,7 +484,7 @@ static int device_resume(struct device *
 			error = pm_op(dev, dev->bus->pm, state);
 		} else if (dev->bus->resume) {
 			pm_dev_dbg(dev, state, "legacy ");
-			error = dev->bus->resume(dev);
+			error = legacy_resume(dev, dev->bus->resume);
 		}
 		if (error)
 			goto End;
@@ -421,7 +505,7 @@ static int device_resume(struct device *
 			error = pm_op(dev, dev->class->pm, state);
 		} else if (dev->class->resume) {
 			pm_dev_dbg(dev, state, "legacy class ");
-			error = dev->class->resume(dev);
+			error = legacy_resume(dev, dev->class->resume);
 		}
 	}
  End:
@@ -441,6 +525,7 @@ static int device_resume(struct device *
 static void dpm_resume(pm_message_t state)
 {
 	struct list_head list;
+	ktime_t starttime = ktime_get();
 
 	INIT_LIST_HEAD(&list);
 	mutex_lock(&dpm_list_mtx);
@@ -469,6 +554,7 @@ static void dpm_resume(pm_message_t stat
 	}
 	list_splice(&list, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
+	dpm_show_time(starttime, state, NULL);
 }
 
 /**
@@ -521,7 +607,7 @@ static void dpm_complete(pm_message_t st
 			mutex_unlock(&dpm_list_mtx);
 
 			device_complete(dev, state);
-			pm_runtime_put_noidle(dev);
+			pm_runtime_put_sync(dev);
 
 			mutex_lock(&dpm_list_mtx);
 		}
@@ -584,10 +670,7 @@ static int device_suspend_noirq(struct d
 {
 	int error = 0;
 
-	if (!dev->bus)
-		return 0;
-
-	if (dev->bus->pm) {
+	if (dev->bus && dev->bus->pm) {
 		pm_dev_dbg(dev, state, "LATE ");
 		error = pm_noirq_op(dev, dev->bus->pm, state);
 	}
@@ -604,6 +687,7 @@ static int device_suspend_noirq(struct d
 int dpm_suspend_noirq(pm_message_t state)
 {
 	struct device *dev;
+	ktime_t starttime = ktime_get();
 	int error = 0;
 
 	suspend_device_irqs();
@@ -619,11 +703,35 @@ int dpm_suspend_noirq(pm_message_t state
 	mutex_unlock(&dpm_list_mtx);
 	if (error)
 		dpm_resume_noirq(resume_event(state));
+	else
+		dpm_show_time(starttime, state, "late");
 	return error;
 }
 EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
 
 /**
+ * legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
+ * @dev: Device to suspend.
+ * @state: PM transition of the system being carried out.
+ * @cb: Suspend callback to execute.
+ */
+static int legacy_suspend(struct device *dev, pm_message_t state,
+			  int (*cb)(struct device *dev, pm_message_t state))
+{
+	int error;
+	ktime_t calltime;
+
+	calltime = initcall_debug_start(dev);
+
+	error = cb(dev, state);
+	suspend_report_result(cb, error);
+
+	initcall_debug_report(dev, calltime, error);
+
+	return error;
+}
+
+/**
  * device_suspend - Execute "suspend" callbacks for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
@@ -640,8 +748,7 @@ static int device_suspend(struct device
 			error = pm_op(dev, dev->class->pm, state);
 		} else if (dev->class->suspend) {
 			pm_dev_dbg(dev, state, "legacy class ");
-			error = dev->class->suspend(dev, state);
-			suspend_report_result(dev->class->suspend, error);
+			error = legacy_suspend(dev, state, dev->class->suspend);
 		}
 		if (error)
 			goto End;
@@ -662,8 +769,7 @@ static int device_suspend(struct device
 			error = pm_op(dev, dev->bus->pm, state);
 		} else if (dev->bus->suspend) {
 			pm_dev_dbg(dev, state, "legacy ");
-			error = dev->bus->suspend(dev, state);
-			suspend_report_result(dev->bus->suspend, error);
+			error = legacy_suspend(dev, state, dev->bus->suspend);
 		}
 	}
  End:
@@ -679,6 +785,7 @@ static int device_suspend(struct device
 static int dpm_suspend(pm_message_t state)
 {
 	struct list_head list;
+	ktime_t starttime = ktime_get();
 	int error = 0;
 
 	INIT_LIST_HEAD(&list);
@@ -704,6 +811,8 @@ static int dpm_suspend(pm_message_t stat
 	}
 	list_splice(&list, dpm_list.prev);
 	mutex_unlock(&dpm_list_mtx);
+	if (!error)
+		dpm_show_time(starttime, state, NULL);
 	return error;
 }
 
@@ -772,7 +881,7 @@ static int dpm_prepare(pm_message_t stat
 		pm_runtime_get_noresume(dev);
 		if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
 			/* Wake-up requested during system sleep transition. */
-			pm_runtime_put_noidle(dev);
+			pm_runtime_put_sync(dev);
 			error = -EBUSY;
 		} else {
 			error = device_prepare(dev, state);
diff -druNp linux-libre-2.6.32-gnu1/drivers/base/power/runtime.c linux-libre-2.6.33-gnu1/drivers/base/power/runtime.c
--- linux-libre-2.6.32-gnu1/drivers/base/power/runtime.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/base/power/runtime.c	2010-02-24 13:52:17.000000000 -0500
@@ -85,6 +85,19 @@ static int __pm_runtime_idle(struct devi
 		dev->bus->pm->runtime_idle(dev);
 
 		spin_lock_irq(&dev->power.lock);
+	} else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) {
+		spin_unlock_irq(&dev->power.lock);
+
+		dev->type->pm->runtime_idle(dev);
+
+		spin_lock_irq(&dev->power.lock);
+	} else if (dev->class && dev->class->pm
+	    && dev->class->pm->runtime_idle) {
+		spin_unlock_irq(&dev->power.lock);
+
+		dev->class->pm->runtime_idle(dev);
+
+		spin_lock_irq(&dev->power.lock);
 	}
 
 	dev->power.idle_notification = false;
@@ -185,6 +198,7 @@ int __pm_runtime_suspend(struct device *
 	}
 
 	dev->power.runtime_status = RPM_SUSPENDING;
+	dev->power.deferred_resume = false;
 
 	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) {
 		spin_unlock_irq(&dev->power.lock);
@@ -193,6 +207,22 @@ int __pm_runtime_suspend(struct device *
 
 		spin_lock_irq(&dev->power.lock);
 		dev->power.runtime_error = retval;
+	} else if (dev->type && dev->type->pm
+	    && dev->type->pm->runtime_suspend) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->type->pm->runtime_suspend(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
+	} else if (dev->class && dev->class->pm
+	    && dev->class->pm->runtime_suspend) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->class->pm->runtime_suspend(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
 	} else {
 		retval = -ENOSYS;
 	}
@@ -200,7 +230,6 @@ int __pm_runtime_suspend(struct device *
 	if (retval) {
 		dev->power.runtime_status = RPM_ACTIVE;
 		pm_runtime_cancel_pending(dev);
-		dev->power.deferred_resume = false;
 
 		if (retval == -EAGAIN || retval == -EBUSY) {
 			notify = true;
@@ -217,7 +246,6 @@ int __pm_runtime_suspend(struct device *
 	wake_up_all(&dev->power.wait_queue);
 
 	if (dev->power.deferred_resume) {
-		dev->power.deferred_resume = false;
 		__pm_runtime_resume(dev, false);
 		retval = -EAGAIN;
 		goto out;
@@ -360,6 +388,22 @@ int __pm_runtime_resume(struct device *d
 
 		spin_lock_irq(&dev->power.lock);
 		dev->power.runtime_error = retval;
+	} else if (dev->type && dev->type->pm
+	    && dev->type->pm->runtime_resume) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->type->pm->runtime_resume(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
+	} else if (dev->class && dev->class->pm
+	    && dev->class->pm->runtime_resume) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->class->pm->runtime_resume(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
 	} else {
 		retval = -ENOSYS;
 	}
@@ -626,6 +670,8 @@ int pm_schedule_suspend(struct device *d
 		goto out;
 
 	dev->power.timer_expires = jiffies + msecs_to_jiffies(delay);
+	if (!dev->power.timer_expires)
+		dev->power.timer_expires = 1;
 	mod_timer(&dev->power.suspend_timer, dev->power.timer_expires);
 
  out:
@@ -659,13 +705,17 @@ static int __pm_request_resume(struct de
 
 	pm_runtime_deactivate_timer(dev);
 
+	if (dev->power.runtime_status == RPM_SUSPENDING) {
+		dev->power.deferred_resume = true;
+		return retval;
+	}
 	if (dev->power.request_pending) {
 		/* If non-resume request is pending, we can overtake it. */
 		dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME;
 		return retval;
-	} else if (retval) {
-		return retval;
 	}
+	if (retval)
+		return retval;
 
 	dev->power.request = RPM_REQ_RESUME;
 	dev->power.request_pending = true;
@@ -696,15 +746,15 @@ EXPORT_SYMBOL_GPL(pm_request_resume);
  * @dev: Device to handle.
  * @sync: If set and the device is suspended, resume it synchronously.
  *
- * Increment the usage count of the device and if it was zero previously,
- * resume it or submit a resume request for it, depending on the value of @sync.
+ * Increment the usage count of the device and resume it or submit a resume
+ * request for it, depending on the value of @sync.
  */
 int __pm_runtime_get(struct device *dev, bool sync)
 {
-	int retval = 1;
+	int retval;
 
-	if (atomic_add_return(1, &dev->power.usage_count) == 1)
-		retval = sync ? pm_runtime_resume(dev) : pm_request_resume(dev);
+	atomic_inc(&dev->power.usage_count);
+	retval = sync ? pm_runtime_resume(dev) : pm_request_resume(dev);
 
 	return retval;
 }
@@ -777,7 +827,7 @@ int __pm_runtime_set_status(struct devic
 	}
 
 	if (parent) {
-		spin_lock(&parent->power.lock);
+		spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING);
 
 		/*
 		 * It is invalid to put an active child under a parent that is
@@ -786,12 +836,10 @@ int __pm_runtime_set_status(struct devic
 		 */
 		if (!parent->power.disable_depth
 		    && !parent->power.ignore_children
-		    && parent->power.runtime_status != RPM_ACTIVE) {
+		    && parent->power.runtime_status != RPM_ACTIVE)
 			error = -EBUSY;
-		} else {
-			if (dev->power.runtime_status == RPM_SUSPENDED)
-				atomic_inc(&parent->power.child_count);
-		}
+		else if (dev->power.runtime_status == RPM_SUSPENDED)
+			atomic_inc(&parent->power.child_count);
 
 		spin_unlock(&parent->power.lock);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/aoe/aoecmd.c linux-libre-2.6.33-gnu1/drivers/block/aoe/aoecmd.c
--- linux-libre-2.6.32-gnu1/drivers/block/aoe/aoecmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/aoe/aoecmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -735,21 +735,6 @@ diskstats(struct gendisk *disk, struct b
 	part_stat_unlock();
 }
 
-/*
- * Ensure we don't create aliases in VI caches
- */
-static inline void
-killalias(struct bio *bio)
-{
-	struct bio_vec *bv;
-	int i;
-
-	if (bio_data_dir(bio) == READ)
-		__bio_for_each_segment(bv, bio, i, 0) {
-			flush_dcache_page(bv->bv_page);
-		}
-}
-
 void
 aoecmd_ata_rsp(struct sk_buff *skb)
 {
@@ -871,7 +856,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 		if (buf->flags & BUFFL_FAIL)
 			bio_endio(buf->bio, -EIO);
 		else {
-			killalias(buf->bio);
+			bio_flush_dcache_pages(buf->bio);
 			bio_endio(buf->bio, 0);
 		}
 		mempool_free(buf, d->bufpool);
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/ataflop.c linux-libre-2.6.33-gnu1/drivers/block/ataflop.c
--- linux-libre-2.6.32-gnu1/drivers/block/ataflop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/ataflop.c	2010-02-24 13:52:17.000000000 -0500
@@ -1478,10 +1478,7 @@ void do_fd_request(struct request_queue
 	stdma_lock(floppy_irq, NULL);
 
 	atari_disable_irq( IRQ_MFP_FDC );
-	local_save_flags(flags);	/* The request function is called with ints
-	local_irq_disable();		 * disabled... so must save the IPL for later */ 
 	redo_fd_request();
-	local_irq_restore(flags);
 	atari_enable_irq( IRQ_MFP_FDC );
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/cciss.c linux-libre-2.6.33-gnu1/drivers/block/cciss.c
--- linux-libre-2.6.32-gnu1/drivers/block/cciss.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/cciss.c	2010-02-24 13:52:17.000000000 -0500
@@ -179,19 +179,17 @@ static int rebuild_lun_table(ctlr_info_t
 static int deregister_disk(ctlr_info_t *h, int drv_index,
 			   int clear_all, int via_ioctl);
 
-static void cciss_read_capacity(int ctlr, int logvol, int withirq,
+static void cciss_read_capacity(int ctlr, int logvol,
 			sector_t *total_size, unsigned int *block_size);
-static void cciss_read_capacity_16(int ctlr, int logvol, int withirq,
+static void cciss_read_capacity_16(int ctlr, int logvol,
 			sector_t *total_size, unsigned int *block_size);
 static void cciss_geometry_inquiry(int ctlr, int logvol,
-			int withirq, sector_t total_size,
+			sector_t total_size,
 			unsigned int block_size, InquiryData_struct *inq_buff,
 				   drive_info_struct *drv);
 static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
 					   __u32);
 static void start_io(ctlr_info_t *h);
-static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size,
-		   __u8 page_code, unsigned char *scsi3addr, int cmd_type);
 static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
 			__u8 page_code, unsigned char scsi3addr[],
 			int cmd_type);
@@ -339,6 +337,9 @@ static int cciss_seq_show(struct seq_fil
 	if (*pos > h->highest_lun)
 		return 0;
 
+	if (drv == NULL) /* it's possible for h->drv[] to have holes. */
+		return 0;
+
 	if (drv->heads == 0)
 		return 0;
 
@@ -424,12 +425,9 @@ cciss_proc_write(struct file *file, cons
 	if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) {
 		struct seq_file *seq = file->private_data;
 		ctlr_info_t *h = seq->private;
-		int rc;
 
-		rc = cciss_engage_scsi(h->ctlr);
-		if (rc != 0)
-			err = -rc;
-		else
+		err = cciss_engage_scsi(h->ctlr);
+		if (err == 0)
 			err = length;
 	} else
 #endif /* CONFIG_CISS_SCSI_TAPE */
@@ -1657,9 +1655,11 @@ static void cciss_softirq_done(struct re
 {
 	CommandList_struct *cmd = rq->completion_data;
 	ctlr_info_t *h = hba[cmd->ctlr];
+	SGDescriptor_struct *curr_sg = cmd->SG;
 	unsigned long flags;
 	u64bit temp64;
 	int i, ddir;
+	int sg_index = 0;
 
 	if (cmd->Request.Type.Direction == XFER_READ)
 		ddir = PCI_DMA_FROMDEVICE;
@@ -1669,9 +1669,22 @@ static void cciss_softirq_done(struct re
 	/* command did not need to be retried */
 	/* unmap the DMA mapping for all the scatter gather elements */
 	for (i = 0; i < cmd->Header.SGList; i++) {
-		temp64.val32.lower = cmd->SG[i].Addr.lower;
-		temp64.val32.upper = cmd->SG[i].Addr.upper;
-		pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
+		if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) {
+			temp64.val32.lower = cmd->SG[i].Addr.lower;
+			temp64.val32.upper = cmd->SG[i].Addr.upper;
+			pci_dma_sync_single_for_cpu(h->pdev, temp64.val,
+						cmd->SG[i].Len, ddir);
+			pci_unmap_single(h->pdev, temp64.val,
+						cmd->SG[i].Len, ddir);
+			/* Point to the next block */
+			curr_sg = h->cmd_sg_list[cmd->cmdindex]->sgchain;
+			sg_index = 0;
+		}
+		temp64.val32.lower = curr_sg[sg_index].Addr.lower;
+		temp64.val32.upper = curr_sg[sg_index].Addr.upper;
+		pci_unmap_page(h->pdev, temp64.val, curr_sg[sg_index].Len,
+				ddir);
+		++sg_index;
 	}
 
 #ifdef CCISS_DEBUG
@@ -1701,7 +1714,7 @@ static inline void log_unit_to_scsi3addr
  * via the inquiry page 0.  Model, vendor, and rev are set to empty strings if
  * they cannot be read.
  */
-static void cciss_get_device_descr(int ctlr, int logvol, int withirq,
+static void cciss_get_device_descr(int ctlr, int logvol,
 				   char *vendor, char *model, char *rev)
 {
 	int rc;
@@ -1717,14 +1730,8 @@ static void cciss_get_device_descr(int c
 		return;
 
 	log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-	if (withirq)
-		rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf,
-			     sizeof(InquiryData_struct), 0,
-				scsi3addr, TYPE_CMD);
-	else
-		rc = sendcmd(CISS_INQUIRY, ctlr, inq_buf,
-			     sizeof(InquiryData_struct), 0,
-				scsi3addr, TYPE_CMD);
+	rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf, sizeof(*inq_buf), 0,
+			scsi3addr, TYPE_CMD);
 	if (rc == IO_OK) {
 		memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN);
 		vendor[VENDOR_LEN] = '\0';
@@ -1743,7 +1750,7 @@ static void cciss_get_device_descr(int c
  * number cannot be had, for whatever reason, 16 bytes of 0xff
  * are returned instead.
  */
-static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
+static void cciss_get_serial_no(int ctlr, int logvol,
 				unsigned char *serial_no, int buflen)
 {
 #define PAGE_83_INQ_BYTES 64
@@ -1759,12 +1766,8 @@ static void cciss_get_serial_no(int ctlr
 		return;
 	memset(serial_no, 0, buflen);
 	log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-	if (withirq)
-		rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf,
-			PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD);
-	else
-		rc = sendcmd(CISS_INQUIRY, ctlr, buf,
-			PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD);
+	rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf,
+		PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD);
 	if (rc == IO_OK)
 		memcpy(serial_no, &buf[8], buflen);
 	kfree(buf);
@@ -1793,10 +1796,10 @@ static int cciss_add_disk(ctlr_info_t *h
 	blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
 
 	/* This is a hardware imposed limit. */
-	blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);
+	blk_queue_max_hw_segments(disk->queue, h->maxsgentries);
 
 	/* This is a limit in the driver and could be eliminated. */
-	blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
+	blk_queue_max_phys_segments(disk->queue, h->maxsgentries);
 
 	blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
 
@@ -1852,18 +1855,16 @@ static void cciss_update_drive_info(int
 
 	/* testing to see if 16-byte CDBs are already being used */
 	if (h->cciss_read == CCISS_READ_16) {
-		cciss_read_capacity_16(h->ctlr, drv_index, 1,
+		cciss_read_capacity_16(h->ctlr, drv_index,
 			&total_size, &block_size);
 
 	} else {
-		cciss_read_capacity(ctlr, drv_index, 1,
-				    &total_size, &block_size);
-
+		cciss_read_capacity(ctlr, drv_index, &total_size, &block_size);
 		/* if read_capacity returns all F's this volume is >2TB */
 		/* in size so we switch to 16-byte CDB's for all */
 		/* read/write ops */
 		if (total_size == 0xFFFFFFFFULL) {
-			cciss_read_capacity_16(ctlr, drv_index, 1,
+			cciss_read_capacity_16(ctlr, drv_index,
 			&total_size, &block_size);
 			h->cciss_read = CCISS_READ_16;
 			h->cciss_write = CCISS_WRITE_16;
@@ -1873,14 +1874,14 @@ static void cciss_update_drive_info(int
 		}
 	}
 
-	cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
+	cciss_geometry_inquiry(ctlr, drv_index, total_size, block_size,
 			       inq_buff, drvinfo);
 	drvinfo->block_size = block_size;
 	drvinfo->nr_blocks = total_size + 1;
 
-	cciss_get_device_descr(ctlr, drv_index, 1, drvinfo->vendor,
+	cciss_get_device_descr(ctlr, drv_index, drvinfo->vendor,
 				drvinfo->model, drvinfo->rev);
-	cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
+	cciss_get_serial_no(ctlr, drv_index, drvinfo->serial_no,
 			sizeof(drvinfo->serial_no));
 	/* Save the lunid in case we deregister the disk, below. */
 	memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
@@ -2531,6 +2532,8 @@ static int check_target_status(ctlr_info
 		case 0: return IO_OK; /* no sense */
 		case 1: return IO_OK; /* recovered error */
 		default:
+			if (check_for_unit_attention(h, c))
+				return IO_NEEDS_RETRY;
 			printk(KERN_WARNING "cciss%d: cmd 0x%02x "
 				"check condition, sense key = 0x%02x\n",
 				h->ctlr, c->Request.CDB[0],
@@ -2672,7 +2675,7 @@ static int sendcmd_withirq(__u8 cmd, int
 }
 
 static void cciss_geometry_inquiry(int ctlr, int logvol,
-				   int withirq, sector_t total_size,
+				   sector_t total_size,
 				   unsigned int block_size,
 				   InquiryData_struct *inq_buff,
 				   drive_info_struct *drv)
@@ -2683,14 +2686,8 @@ static void cciss_geometry_inquiry(int c
 
 	memset(inq_buff, 0, sizeof(InquiryData_struct));
 	log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-	if (withirq)
-		return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
-					      inq_buff, sizeof(*inq_buff),
-					      0xC1, scsi3addr, TYPE_CMD);
-	else
-		return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
-				      sizeof(*inq_buff), 0xC1, scsi3addr,
-				      TYPE_CMD);
+	return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff,
+			sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD);
 	if (return_code == IO_OK) {
 		if (inq_buff->data_byte[8] == 0xFF) {
 			printk(KERN_WARNING
@@ -2723,7 +2720,7 @@ static void cciss_geometry_inquiry(int c
 }
 
 static void
-cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
+cciss_read_capacity(int ctlr, int logvol, sector_t *total_size,
 		    unsigned int *block_size)
 {
 	ReadCapdata_struct *buf;
@@ -2737,14 +2734,8 @@ cciss_read_capacity(int ctlr, int logvol
 	}
 
 	log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-	if (withirq)
-		return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
-				ctlr, buf, sizeof(ReadCapdata_struct),
-					0, scsi3addr, TYPE_CMD);
-	else
-		return_code = sendcmd(CCISS_READ_CAPACITY,
-				ctlr, buf, sizeof(ReadCapdata_struct),
-					0, scsi3addr, TYPE_CMD);
+	return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf,
+		sizeof(ReadCapdata_struct), 0, scsi3addr, TYPE_CMD);
 	if (return_code == IO_OK) {
 		*total_size = be32_to_cpu(*(__be32 *) buf->total_size);
 		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
@@ -2756,8 +2747,8 @@ cciss_read_capacity(int ctlr, int logvol
 	kfree(buf);
 }
 
-static void
-cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, 				unsigned int *block_size)
+static void cciss_read_capacity_16(int ctlr, int logvol,
+	sector_t *total_size, unsigned int *block_size)
 {
 	ReadCapdata_struct_16 *buf;
 	int return_code;
@@ -2770,16 +2761,9 @@ cciss_read_capacity_16(int ctlr, int log
 	}
 
 	log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol);
-	if (withirq) {
-		return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
-			ctlr, buf, sizeof(ReadCapdata_struct_16),
-				0, scsi3addr, TYPE_CMD);
-	}
-	else {
-		return_code = sendcmd(CCISS_READ_CAPACITY_16,
-			ctlr, buf, sizeof(ReadCapdata_struct_16),
-				0, scsi3addr, TYPE_CMD);
-	}
+	return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
+		ctlr, buf, sizeof(ReadCapdata_struct_16),
+			0, scsi3addr, TYPE_CMD);
 	if (return_code == IO_OK) {
 		*total_size = be64_to_cpu(*(__be64 *) buf->total_size);
 		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
@@ -2820,13 +2804,13 @@ static int cciss_revalidate(struct gendi
 		return 1;
 	}
 	if (h->cciss_read == CCISS_READ_10) {
-		cciss_read_capacity(h->ctlr, logvol, 1,
+		cciss_read_capacity(h->ctlr, logvol,
 					&total_size, &block_size);
 	} else {
-		cciss_read_capacity_16(h->ctlr, logvol, 1,
+		cciss_read_capacity_16(h->ctlr, logvol,
 					&total_size, &block_size);
 	}
-	cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size,
+	cciss_geometry_inquiry(h->ctlr, logvol, total_size, block_size,
 			       inq_buff, drv);
 
 	blk_queue_logical_block_size(drv->queue, drv->block_size);
@@ -2837,167 +2821,6 @@ static int cciss_revalidate(struct gendi
 }
 
 /*
- *   Wait polling for a command to complete.
- *   The memory mapped FIFO is polled for the completion.
- *   Used only at init time, interrupts from the HBA are disabled.
- */
-static unsigned long pollcomplete(int ctlr)
-{
-	unsigned long done;
-	int i;
-
-	/* Wait (up to 20 seconds) for a command to complete */
-
-	for (i = 20 * HZ; i > 0; i--) {
-		done = hba[ctlr]->access.command_completed(hba[ctlr]);
-		if (done == FIFO_EMPTY)
-			schedule_timeout_uninterruptible(1);
-		else
-			return done;
-	}
-	/* Invalid address to tell caller we ran out of time */
-	return 1;
-}
-
-/* Send command c to controller h and poll for it to complete.
- * Turns interrupts off on the board.  Used at driver init time
- * and during SCSI error recovery.
- */
-static int sendcmd_core(ctlr_info_t *h, CommandList_struct *c)
-{
-	int i;
-	unsigned long complete;
-	int status = IO_ERROR;
-	u64bit buff_dma_handle;
-
-resend_cmd1:
-
-	/* Disable interrupt on the board. */
-	h->access.set_intr_mask(h, CCISS_INTR_OFF);
-
-	/* Make sure there is room in the command FIFO */
-	/* Actually it should be completely empty at this time */
-	/* unless we are in here doing error handling for the scsi */
-	/* tape side of the driver. */
-	for (i = 200000; i > 0; i--) {
-		/* if fifo isn't full go */
-		if (!(h->access.fifo_full(h)))
-			break;
-		udelay(10);
-		printk(KERN_WARNING "cciss cciss%d: SendCmd FIFO full,"
-		       " waiting!\n", h->ctlr);
-	}
-	h->access.submit_command(h, c); /* Send the cmd */
-	do {
-		complete = pollcomplete(h->ctlr);
-
-#ifdef CCISS_DEBUG
-		printk(KERN_DEBUG "cciss: command completed\n");
-#endif				/* CCISS_DEBUG */
-
-		if (complete == 1) {
-			printk(KERN_WARNING
-			       "cciss cciss%d: SendCmd Timeout out, "
-			       "No command list address returned!\n", h->ctlr);
-			status = IO_ERROR;
-			break;
-		}
-
-		/* Make sure it's the command we're expecting. */
-		if ((complete & ~CISS_ERROR_BIT) != c->busaddr) {
-			printk(KERN_WARNING "cciss%d: Unexpected command "
-				"completion.\n", h->ctlr);
-			continue;
-		}
-
-		/* It is our command.  If no error, we're done. */
-		if (!(complete & CISS_ERROR_BIT)) {
-			status = IO_OK;
-			break;
-		}
-
-		/* There is an error... */
-
-		/* if data overrun or underun on Report command ignore it */
-		if (((c->Request.CDB[0] == CISS_REPORT_LOG) ||
-		     (c->Request.CDB[0] == CISS_REPORT_PHYS) ||
-		     (c->Request.CDB[0] == CISS_INQUIRY)) &&
-			((c->err_info->CommandStatus == CMD_DATA_OVERRUN) ||
-			 (c->err_info->CommandStatus == CMD_DATA_UNDERRUN))) {
-			complete = c->busaddr;
-			status = IO_OK;
-			break;
-		}
-
-		if (c->err_info->CommandStatus == CMD_UNSOLICITED_ABORT) {
-			printk(KERN_WARNING "cciss%d: unsolicited abort %p\n",
-				h->ctlr, c);
-			if (c->retry_count < MAX_CMD_RETRIES) {
-				printk(KERN_WARNING "cciss%d: retrying %p\n",
-				   h->ctlr, c);
-				c->retry_count++;
-				/* erase the old error information */
-				memset(c->err_info, 0, sizeof(c->err_info));
-				goto resend_cmd1;
-			}
-			printk(KERN_WARNING "cciss%d: retried %p too many "
-				"times\n", h->ctlr, c);
-			status = IO_ERROR;
-			break;
-		}
-
-		if (c->err_info->CommandStatus == CMD_UNABORTABLE) {
-			printk(KERN_WARNING "cciss%d: command could not be "
-				"aborted.\n", h->ctlr);
-			status = IO_ERROR;
-			break;
-		}
-
-		if (c->err_info->CommandStatus == CMD_TARGET_STATUS) {
-			status = check_target_status(h, c);
-			break;
-		}
-
-		printk(KERN_WARNING "cciss%d: sendcmd error\n", h->ctlr);
-		printk(KERN_WARNING "cmd = 0x%02x, CommandStatus = 0x%02x\n",
-			c->Request.CDB[0], c->err_info->CommandStatus);
-		status = IO_ERROR;
-		break;
-
-	} while (1);
-
-	/* unlock the data buffer from DMA */
-	buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
-	buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
-	pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val,
-			 c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
-	return status;
-}
-
-/*
- * Send a command to the controller, and wait for it to complete.
- * Used at init time, and during SCSI error recovery.
- */
-static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size,
-	__u8 page_code, unsigned char *scsi3addr, int cmd_type)
-{
-	CommandList_struct *c;
-	int status;
-
-	c = cmd_alloc(hba[ctlr], 1);
-	if (!c) {
-		printk(KERN_WARNING "cciss: unable to get memory");
-		return IO_ERROR;
-	}
-	status = fill_cmd(c, cmd, ctlr, buff, size, page_code,
-		scsi3addr, cmd_type);
-	if (status == IO_OK)
-		status = sendcmd_core(hba[ctlr], c);
-	cmd_free(hba[ctlr], c, 1);
-	return status;
-}
-
-/*
  * Map (physical) PCI mem into (virtual) kernel space
  */
 static void __iomem *remap_pci_mem(ulong base, ulong size)
@@ -3255,9 +3078,13 @@ static void do_cciss_request(struct requ
 	int seg;
 	struct request *creq;
 	u64bit temp64;
-	struct scatterlist tmp_sg[MAXSGENTRIES];
+	struct scatterlist *tmp_sg;
+	SGDescriptor_struct *curr_sg;
 	drive_info_struct *drv;
 	int i, dir;
+	int nseg = 0;
+	int sg_index = 0;
+	int chained = 0;
 
 	/* We call start_io here in case there is a command waiting on the
 	 * queue that has not been sent.
@@ -3270,13 +3097,14 @@ static void do_cciss_request(struct requ
 	if (!creq)
 		goto startio;
 
-	BUG_ON(creq->nr_phys_segments > MAXSGENTRIES);
+	BUG_ON(creq->nr_phys_segments > h->maxsgentries);
 
 	if ((c = cmd_alloc(h, 1)) == NULL)
 		goto full;
 
 	blk_start_request(creq);
 
+	tmp_sg = h->scatter_list[c->cmdindex];
 	spin_unlock_irq(q->queue_lock);
 
 	c->cmd_type = CMD_RWREQ;
@@ -3305,7 +3133,7 @@ static void do_cciss_request(struct requ
 	       (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq));
 #endif				/* CCISS_DEBUG */
 
-	sg_init_table(tmp_sg, MAXSGENTRIES);
+	sg_init_table(tmp_sg, h->maxsgentries);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -3314,25 +3142,70 @@ static void do_cciss_request(struct requ
 	else
 		dir = PCI_DMA_TODEVICE;
 
+	curr_sg = c->SG;
+	sg_index = 0;
+	chained = 0;
+
 	for (i = 0; i < seg; i++) {
-		c->SG[i].Len = tmp_sg[i].length;
+		if (((sg_index+1) == (h->max_cmd_sgentries)) &&
+			!chained && ((seg - i) > 1)) {
+			nseg = seg - i;
+			curr_sg[sg_index].Len = (nseg) *
+					sizeof(SGDescriptor_struct);
+			curr_sg[sg_index].Ext = CCISS_SG_CHAIN;
+
+			/* Point to next chain block. */
+			curr_sg = h->cmd_sg_list[c->cmdindex]->sgchain;
+			sg_index = 0;
+			chained = 1;
+		}
+		curr_sg[sg_index].Len = tmp_sg[i].length;
 		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
-						  tmp_sg[i].offset,
-						  tmp_sg[i].length, dir);
-		c->SG[i].Addr.lower = temp64.val32.lower;
-		c->SG[i].Addr.upper = temp64.val32.upper;
-		c->SG[i].Ext = 0;	// we are not chaining
+						tmp_sg[i].offset,
+						tmp_sg[i].length, dir);
+		curr_sg[sg_index].Addr.lower = temp64.val32.lower;
+		curr_sg[sg_index].Addr.upper = temp64.val32.upper;
+		curr_sg[sg_index].Ext = 0;  /* we are not chaining */
+
+		++sg_index;
 	}
+
+	if (chained) {
+		int len;
+		curr_sg = c->SG;
+		sg_index = h->max_cmd_sgentries - 1;
+		len = curr_sg[sg_index].Len;
+		/* Setup pointer to next chain block.
+		 * Fill out last element in current chain
+		 * block with address of next chain block.
+		 */
+		temp64.val = pci_map_single(h->pdev,
+					h->cmd_sg_list[c->cmdindex]->sgchain,
+					len, dir);
+
+		h->cmd_sg_list[c->cmdindex]->sg_chain_dma = temp64.val;
+		curr_sg[sg_index].Addr.lower = temp64.val32.lower;
+		curr_sg[sg_index].Addr.upper = temp64.val32.upper;
+
+		pci_dma_sync_single_for_device(h->pdev,
+				h->cmd_sg_list[c->cmdindex]->sg_chain_dma,
+				len, dir);
+	}
+
 	/* track how many SG entries we are using */
 	if (seg > h->maxSG)
 		h->maxSG = seg;
 
 #ifdef CCISS_DEBUG
-	printk(KERN_DEBUG "cciss: Submitting %u sectors in %d segments\n",
-	       blk_rq_sectors(creq), seg);
+	printk(KERN_DEBUG "cciss: Submitting %ld sectors in %d segments "
+			"chained[%d]\n",
+			blk_rq_sectors(creq), seg, chained);
 #endif				/* CCISS_DEBUG */
 
-	c->Header.SGList = c->Header.SGTotal = seg;
+	c->Header.SGList = c->Header.SGTotal = seg + chained;
+	if (seg > h->max_cmd_sgentries)
+		c->Header.SGList = h->max_cmd_sgentries;
+
 	if (likely(blk_fs_request(creq))) {
 		if(h->cciss_read == CCISS_READ_10) {
 			c->Request.CDB[1] = 0;
@@ -3513,28 +3386,33 @@ static int add_to_scan_list(struct ctlr_
  * @h:			   Pointer to the controller.
  *
  * Removes the controller from the rescan queue if present. Blocks if
- * the controller is currently conducting a rescan.
+ * the controller is currently conducting a rescan.  The controller
+ * can be in one of three states:
+ * 1. Doesn't need a scan
+ * 2. On the scan list, but not scanning yet (we remove it)
+ * 3. Busy scanning (and not on the list). In this case we want to wait for
+ *    the scan to complete to make sure the scanning thread for this
+ *    controller is completely idle.
  **/
 static void remove_from_scan_list(struct ctlr_info *h)
 {
 	struct ctlr_info *test_h, *tmp_h;
-	int scanning = 0;
 
 	mutex_lock(&scan_mutex);
 	list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
-		if (test_h == h) {
+		if (test_h == h) { /* state 2. */
 			list_del(&h->scan_list);
 			complete_all(&h->scan_wait);
 			mutex_unlock(&scan_mutex);
 			return;
 		}
 	}
-	if (&h->busy_scanning)
-		scanning = 0;
-	mutex_unlock(&scan_mutex);
-
-	if (scanning)
+	if (h->busy_scanning) { /* state 3. */
+		mutex_unlock(&scan_mutex);
 		wait_for_completion(&h->scan_wait);
+	} else { /* state 1, nothing to do. */
+		mutex_unlock(&scan_mutex);
+	}
 }
 
 /**
@@ -3573,13 +3451,11 @@ static int scan_thread(void *data)
 			h->busy_scanning = 1;
 			mutex_unlock(&scan_mutex);
 
-			if (h) {
-				rebuild_lun_table(h, 0, 0);
-				complete_all(&h->scan_wait);
-				mutex_lock(&scan_mutex);
-				h->busy_scanning = 0;
-				mutex_unlock(&scan_mutex);
-			}
+			rebuild_lun_table(h, 0, 0);
+			complete_all(&h->scan_wait);
+			mutex_lock(&scan_mutex);
+			h->busy_scanning = 0;
+			mutex_unlock(&scan_mutex);
 		}
 	}
 
@@ -3605,8 +3481,22 @@ static int check_for_unit_attention(ctlr
 	case REPORT_LUNS_CHANGED:
 		printk(KERN_WARNING "cciss%d: report LUN data "
 			"changed\n", h->ctlr);
-		add_to_scan_list(h);
-		wake_up_process(cciss_scan_thread);
+	/*
+	 * Here, we could call add_to_scan_list and wake up the scan thread,
+	 * except that it's quite likely that we will get more than one
+	 * REPORT_LUNS_CHANGED condition in quick succession, which means
+	 * that those which occur after the first one will likely happen
+	 * *during* the scan_thread's rescan.  And the rescan code is not
+	 * robust enough to restart in the middle, undoing what it has already
+	 * done, and it's not clear that it's even possible to do this, since
+	 * part of what it does is notify the block layer, which starts
+	 * doing it's own i/o to read partition tables and so on, and the
+	 * driver doesn't have visibility to know what might need undoing.
+	 * In any event, if possible, it is horribly complicated to get right
+	 * so we just don't do it for now.
+	 *
+	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
+	 */
 		return 1;
 	break;
 	case POWER_OR_RESET:
@@ -3888,6 +3778,23 @@ static int __devinit cciss_pci_init(ctlr
 	 * leave a little room for ioctl calls.
 	 */
 	c->max_commands = readl(&(c->cfgtable->CmdsOutMax));
+	c->maxsgentries = readl(&(c->cfgtable->MaxSGElements));
+
+	/*
+	 * Limit native command to 32 s/g elements to save dma'able memory.
+	 * Howvever spec says if 0, use 31
+	 */
+
+	c->max_cmd_sgentries = 31;
+	if (c->maxsgentries > 512) {
+		c->max_cmd_sgentries = 32;
+		c->chainsize = c->maxsgentries - c->max_cmd_sgentries + 1;
+		c->maxsgentries -= 1;   /* account for chain pointer */
+	} else {
+		c->maxsgentries = 31;   /* Default to traditional value */
+		c->chainsize = 0;       /* traditional */
+	}
+
 	c->product_name = products[prod_index].product_name;
 	c->access = *(products[prod_index].access);
 	c->nr_cmds = c->max_commands - 4;
@@ -4214,6 +4121,7 @@ static int __devinit cciss_init_one(stru
 {
 	int i;
 	int j = 0;
+	int k = 0;
 	int rc;
 	int dac, return_code;
 	InquiryData_struct *inq_buff;
@@ -4317,6 +4225,53 @@ static int __devinit cciss_init_one(stru
 		printk(KERN_ERR "cciss: out of memory");
 		goto clean4;
 	}
+
+	/* Need space for temp scatter list */
+	hba[i]->scatter_list = kmalloc(hba[i]->max_commands *
+						sizeof(struct scatterlist *),
+						GFP_KERNEL);
+	for (k = 0; k < hba[i]->nr_cmds; k++) {
+		hba[i]->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
+							hba[i]->maxsgentries,
+							GFP_KERNEL);
+		if (hba[i]->scatter_list[k] == NULL) {
+			printk(KERN_ERR "cciss%d: could not allocate "
+				"s/g lists\n", i);
+			goto clean4;
+		}
+	}
+	hba[i]->cmd_sg_list = kmalloc(sizeof(struct Cmd_sg_list *) *
+						hba[i]->nr_cmds,
+						GFP_KERNEL);
+	if (!hba[i]->cmd_sg_list) {
+		printk(KERN_ERR "cciss%d: Cannot get memory for "
+			"s/g chaining.\n", i);
+		goto clean4;
+	}
+	/* Build up chain blocks for each command */
+	if (hba[i]->chainsize > 0) {
+		for (j = 0; j < hba[i]->nr_cmds; j++) {
+			hba[i]->cmd_sg_list[j] =
+					kmalloc(sizeof(struct Cmd_sg_list),
+							GFP_KERNEL);
+			if (!hba[i]->cmd_sg_list[j]) {
+				printk(KERN_ERR "cciss%d: Cannot get memory "
+					"for chain block.\n", i);
+				goto clean4;
+			}
+			/* Need a block of chainsized s/g elements. */
+			hba[i]->cmd_sg_list[j]->sgchain =
+					kmalloc((hba[i]->chainsize *
+						sizeof(SGDescriptor_struct)),
+						GFP_KERNEL);
+			if (!hba[i]->cmd_sg_list[j]->sgchain) {
+				printk(KERN_ERR "cciss%d: Cannot get memory "
+					"for s/g chains\n", i);
+				goto clean4;
+			}
+		}
+	}
+
 	spin_lock_init(&hba[i]->lock);
 
 	/* Initialize the pdev driver private data.
@@ -4362,7 +4317,7 @@ static int __devinit cciss_init_one(stru
 
 	cciss_procinit(i);
 
-	hba[i]->cciss_max_sectors = 2048;
+	hba[i]->cciss_max_sectors = 8192;
 
 	rebuild_lun_table(hba[i], 1, 0);
 	hba[i]->busy_initializing = 0;
@@ -4370,6 +4325,20 @@ static int __devinit cciss_init_one(stru
 
 clean4:
 	kfree(hba[i]->cmd_pool_bits);
+	/* Free up sg elements */
+	for (k = 0; k < hba[i]->nr_cmds; k++)
+		kfree(hba[i]->scatter_list[k]);
+	kfree(hba[i]->scatter_list);
+	/* Only free up extra s/g lists if controller supports them */
+	if (hba[i]->chainsize > 0) {
+		for (j = 0; j < hba[i]->nr_cmds; j++) {
+			if (hba[i]->cmd_sg_list[j]) {
+				kfree(hba[i]->cmd_sg_list[j]->sgchain);
+				kfree(hba[i]->cmd_sg_list[j]);
+			}
+		}
+		kfree(hba[i]->cmd_sg_list);
+	}
 	if (hba[i]->cmd_pool)
 		pci_free_consistent(hba[i]->pdev,
 				    hba[i]->nr_cmds * sizeof(CommandList_struct),
@@ -4400,30 +4369,28 @@ clean_no_release_regions:
 
 static void cciss_shutdown(struct pci_dev *pdev)
 {
-	ctlr_info_t *tmp_ptr;
-	int i;
-	char flush_buf[4];
+	ctlr_info_t *h;
+	char *flush_buf;
 	int return_code;
 
-	tmp_ptr = pci_get_drvdata(pdev);
-	if (tmp_ptr == NULL)
-		return;
-	i = tmp_ptr->ctlr;
-	if (hba[i] == NULL)
+	h = pci_get_drvdata(pdev);
+	flush_buf = kzalloc(4, GFP_KERNEL);
+	if (!flush_buf) {
+		printk(KERN_WARNING
+			"cciss:%d cache not flushed, out of memory.\n",
+			h->ctlr);
 		return;
-
-	/* Turn board interrupts off  and send the flush cache command */
-	/* sendcmd will turn off interrupt, and send the flush...
-	 * To write all data in the battery backed cache to disks */
-	memset(flush_buf, 0, 4);
-	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0,
-		CTLR_LUNID, TYPE_CMD);
-	if (return_code == IO_OK) {
-		printk(KERN_INFO "Completed flushing cache on controller %d\n", i);
-	} else {
-		printk(KERN_WARNING "Error flushing cache on controller %d\n", i);
 	}
-	free_irq(hba[i]->intr[2], hba[i]);
+	/* write all data in the battery backed cache to disk */
+	memset(flush_buf, 0, 4);
+	return_code = sendcmd_withirq(CCISS_CACHE_FLUSH, h->ctlr, flush_buf,
+		4, 0, CTLR_LUNID, TYPE_CMD);
+	kfree(flush_buf);
+	if (return_code != IO_OK)
+		printk(KERN_WARNING "cciss%d: Error flushing cache\n",
+			h->ctlr);
+	h->access.set_intr_mask(h, CCISS_INTR_OFF);
+	free_irq(h->intr[2], h);
 }
 
 static void __devexit cciss_remove_one(struct pci_dev *pdev)
@@ -4485,6 +4452,20 @@ static void __devexit cciss_remove_one(s
 	pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
 			    hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
 	kfree(hba[i]->cmd_pool_bits);
+	/* Free up sg elements */
+	for (j = 0; j < hba[i]->nr_cmds; j++)
+		kfree(hba[i]->scatter_list[j]);
+	kfree(hba[i]->scatter_list);
+	/* Only free up extra s/g lists if controller supports them */
+	if (hba[i]->chainsize > 0) {
+		for (j = 0; j < hba[i]->nr_cmds; j++) {
+			if (hba[i]->cmd_sg_list[j]) {
+				kfree(hba[i]->cmd_sg_list[j]->sgchain);
+				kfree(hba[i]->cmd_sg_list[j]);
+			}
+		}
+		kfree(hba[i]->cmd_sg_list);
+	}
 	/*
 	 * Deliberately omit pci_disable_device(): it does something nasty to
 	 * Smart Array controllers that pci_enable_device does not undo
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/cciss_cmd.h linux-libre-2.6.33-gnu1/drivers/block/cciss_cmd.h
--- linux-libre-2.6.32-gnu1/drivers/block/cciss_cmd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/cciss_cmd.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,9 +5,10 @@
 //###########################################################################
 #define CISS_VERSION "1.00"
 
-//general boundary defintions
+//general boundary definitions
 #define SENSEINFOBYTES          32//note that this value may vary between host implementations
-#define MAXSGENTRIES            31
+#define MAXSGENTRIES            32
+#define CCISS_SG_CHAIN          0x80000000
 #define MAXREPLYQS              256
 
 //Command Status value
@@ -319,6 +320,10 @@ typedef struct _CfgTable_struct {
   BYTE             ServerName[16];
   DWORD            HeartBeat;
   DWORD            SCSI_Prefetch;
+  DWORD            MaxSGElements;
+  DWORD            MaxLogicalUnits;
+  DWORD            MaxPhysicalDrives;
+  DWORD            MaxPhysicalDrivesPerLogicalUnit;
 } CfgTable_struct;
 #pragma pack()	 
 #endif // CCISS_CMD_H
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/cciss.h linux-libre-2.6.33-gnu1/drivers/block/cciss.h
--- linux-libre-2.6.32-gnu1/drivers/block/cciss.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/cciss.h	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,13 @@ typedef struct _drive_info_struct
 	char device_initialized;     /* indicates whether dev is initialized */
 } drive_info_struct;
 
-struct ctlr_info 
+struct Cmd_sg_list {
+	SGDescriptor_struct	*sgchain;
+	dma_addr_t		sg_chain_dma;
+	int			chain_block_size;
+};
+
+struct ctlr_info
 {
 	int	ctlr;
 	char	devname[8];
@@ -75,6 +81,16 @@ struct ctlr_info
 	int	num_luns;
 	int 	highest_lun;
 	int	usage_count;  /* number of opens all all minor devices */
+	/* Need space for temp sg list
+	 * number of scatter/gathers supported
+	 * number of scatter/gathers in chained block
+	 */
+	struct	scatterlist **scatter_list;
+	int	maxsgentries;
+	int	chainsize;
+	int	max_cmd_sgentries;
+	struct Cmd_sg_list **cmd_sg_list;
+
 #	define DOORBELL_INT	0
 #	define PERF_MODE_INT	1
 #	define SIMPLE_MODE_INT	2
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/cciss_scsi.c linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.c
--- linux-libre-2.6.32-gnu1/drivers/block/cciss_scsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/cciss_scsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -755,7 +755,7 @@ complete_scsi_command( CommandList_struc
                         			cp,  
 						ei->ScsiStatus); 
 #endif
-					cmd->result |= (ei->ScsiStatus < 1);
+					cmd->result |= (ei->ScsiStatus << 1);
                 		}
 				else {  /* scsi status is zero??? How??? */
 					
@@ -1547,7 +1547,7 @@ cciss_engage_scsi(int ctlr)
 	if (sa->registered) {
 		printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-		return ENXIO;
+		return -ENXIO;
 	}
 	sa->registered = 1;
 	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/DAC960.c linux-libre-2.6.33-gnu1/drivers/block/DAC960.c
--- linux-libre-2.6.32-gnu1/drivers/block/DAC960.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/DAC960.c	2010-02-24 13:52:17.000000000 -0500
@@ -7101,7 +7101,7 @@ static struct DAC960_privdata DAC960_BA_
 
 static struct DAC960_privdata DAC960_LP_privdata = {
 	.HardwareType =		DAC960_LP_Controller,
-	.FirmwareType 	=	DAC960_LP_Controller,
+	.FirmwareType 	=	DAC960_V2_Controller,
 	.InterruptHandler =	DAC960_LP_InterruptHandler,
 	.MemoryWindowSize =	DAC960_LP_RegisterWindowSize,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_actlog.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_actlog.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_actlog.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_actlog.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1424 @@
+/*
+   drbd_actlog.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2003-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 2003-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2003-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/slab.h>
+#include <linux/drbd.h>
+#include "drbd_int.h"
+#include "drbd_wrappers.h"
+
+/* We maintain a trivial check sum in our on disk activity log.
+ * With that we can ensure correct operation even when the storage
+ * device might do a partial (last) sector write while loosing power.
+ */
+struct __packed al_transaction {
+	u32       magic;
+	u32       tr_number;
+	struct __packed {
+		u32 pos;
+		u32 extent; } updates[1 + AL_EXTENTS_PT];
+	u32       xor_sum;
+};
+
+struct update_odbm_work {
+	struct drbd_work w;
+	unsigned int enr;
+};
+
+struct update_al_work {
+	struct drbd_work w;
+	struct lc_element *al_ext;
+	struct completion event;
+	unsigned int enr;
+	/* if old_enr != LC_FREE, write corresponding bitmap sector, too */
+	unsigned int old_enr;
+};
+
+struct drbd_atodb_wait {
+	atomic_t           count;
+	struct completion  io_done;
+	struct drbd_conf   *mdev;
+	int                error;
+};
+
+
+int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int);
+
+static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
+				 struct drbd_backing_dev *bdev,
+				 struct page *page, sector_t sector,
+				 int rw, int size)
+{
+	struct bio *bio;
+	struct drbd_md_io md_io;
+	int ok;
+
+	md_io.mdev = mdev;
+	init_completion(&md_io.event);
+	md_io.error = 0;
+
+	if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags))
+		rw |= (1 << BIO_RW_BARRIER);
+	rw |= ((1<<BIO_RW_UNPLUG) | (1<<BIO_RW_SYNCIO));
+
+ retry:
+	bio = bio_alloc(GFP_NOIO, 1);
+	bio->bi_bdev = bdev->md_bdev;
+	bio->bi_sector = sector;
+	ok = (bio_add_page(bio, page, size, 0) == size);
+	if (!ok)
+		goto out;
+	bio->bi_private = &md_io;
+	bio->bi_end_io = drbd_md_io_complete;
+	bio->bi_rw = rw;
+
+	if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
+		bio_endio(bio, -EIO);
+	else
+		submit_bio(rw, bio);
+	wait_for_completion(&md_io.event);
+	ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0;
+
+	/* check for unsupported barrier op.
+	 * would rather check on EOPNOTSUPP, but that is not reliable.
+	 * don't try again for ANY return value != 0 */
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER) && !ok)) {
+		/* Try again with no barrier */
+		dev_warn(DEV, "Barriers not supported on meta data device - disabling\n");
+		set_bit(MD_NO_BARRIER, &mdev->flags);
+		rw &= ~(1 << BIO_RW_BARRIER);
+		bio_put(bio);
+		goto retry;
+	}
+ out:
+	bio_put(bio);
+	return ok;
+}
+
+int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
+			 sector_t sector, int rw)
+{
+	int logical_block_size, mask, ok;
+	int offset = 0;
+	struct page *iop = mdev->md_io_page;
+
+	D_ASSERT(mutex_is_locked(&mdev->md_io_mutex));
+
+	BUG_ON(!bdev->md_bdev);
+
+	logical_block_size = bdev_logical_block_size(bdev->md_bdev);
+	if (logical_block_size == 0)
+		logical_block_size = MD_SECTOR_SIZE;
+
+	/* in case logical_block_size != 512 [ s390 only? ] */
+	if (logical_block_size != MD_SECTOR_SIZE) {
+		mask = (logical_block_size / MD_SECTOR_SIZE) - 1;
+		D_ASSERT(mask == 1 || mask == 3 || mask == 7);
+		D_ASSERT(logical_block_size == (mask+1) * MD_SECTOR_SIZE);
+		offset = sector & mask;
+		sector = sector & ~mask;
+		iop = mdev->md_io_tmpp;
+
+		if (rw & WRITE) {
+			/* these are GFP_KERNEL pages, pre-allocated
+			 * on device initialization */
+			void *p = page_address(mdev->md_io_page);
+			void *hp = page_address(mdev->md_io_tmpp);
+
+			ok = _drbd_md_sync_page_io(mdev, bdev, iop, sector,
+					READ, logical_block_size);
+
+			if (unlikely(!ok)) {
+				dev_err(DEV, "drbd_md_sync_page_io(,%llus,"
+				    "READ [logical_block_size!=512]) failed!\n",
+				    (unsigned long long)sector);
+				return 0;
+			}
+
+			memcpy(hp + offset*MD_SECTOR_SIZE, p, MD_SECTOR_SIZE);
+		}
+	}
+
+	if (sector < drbd_md_first_sector(bdev) ||
+	    sector > drbd_md_last_sector(bdev))
+		dev_alert(DEV, "%s [%d]:%s(,%llus,%s) out of range md access!\n",
+		     current->comm, current->pid, __func__,
+		     (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ");
+
+	ok = _drbd_md_sync_page_io(mdev, bdev, iop, sector, rw, logical_block_size);
+	if (unlikely(!ok)) {
+		dev_err(DEV, "drbd_md_sync_page_io(,%llus,%s) failed!\n",
+		    (unsigned long long)sector, (rw & WRITE) ? "WRITE" : "READ");
+		return 0;
+	}
+
+	if (logical_block_size != MD_SECTOR_SIZE && !(rw & WRITE)) {
+		void *p = page_address(mdev->md_io_page);
+		void *hp = page_address(mdev->md_io_tmpp);
+
+		memcpy(p, hp + offset*MD_SECTOR_SIZE, MD_SECTOR_SIZE);
+	}
+
+	return ok;
+}
+
+static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr)
+{
+	struct lc_element *al_ext;
+	struct lc_element *tmp;
+	unsigned long     al_flags = 0;
+
+	spin_lock_irq(&mdev->al_lock);
+	tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT);
+	if (unlikely(tmp != NULL)) {
+		struct bm_extent  *bm_ext = lc_entry(tmp, struct bm_extent, lce);
+		if (test_bit(BME_NO_WRITES, &bm_ext->flags)) {
+			spin_unlock_irq(&mdev->al_lock);
+			return NULL;
+		}
+	}
+	al_ext   = lc_get(mdev->act_log, enr);
+	al_flags = mdev->act_log->flags;
+	spin_unlock_irq(&mdev->al_lock);
+
+	/*
+	if (!al_ext) {
+		if (al_flags & LC_STARVING)
+			dev_warn(DEV, "Have to wait for LRU element (AL too small?)\n");
+		if (al_flags & LC_DIRTY)
+			dev_warn(DEV, "Ongoing AL update (AL device too slow?)\n");
+	}
+	*/
+
+	return al_ext;
+}
+
+void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector)
+{
+	unsigned int enr = (sector >> (AL_EXTENT_SHIFT-9));
+	struct lc_element *al_ext;
+	struct update_al_work al_work;
+
+	D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
+
+	wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)));
+
+	if (al_ext->lc_number != enr) {
+		/* drbd_al_write_transaction(mdev,al_ext,enr);
+		 * recurses into generic_make_request(), which
+		 * disallows recursion, bios being serialized on the
+		 * current->bio_tail list now.
+		 * we have to delegate updates to the activity log
+		 * to the worker thread. */
+		init_completion(&al_work.event);
+		al_work.al_ext = al_ext;
+		al_work.enr = enr;
+		al_work.old_enr = al_ext->lc_number;
+		al_work.w.cb = w_al_write_transaction;
+		drbd_queue_work_front(&mdev->data.work, &al_work.w);
+		wait_for_completion(&al_work.event);
+
+		mdev->al_writ_cnt++;
+
+		spin_lock_irq(&mdev->al_lock);
+		lc_changed(mdev->act_log, al_ext);
+		spin_unlock_irq(&mdev->al_lock);
+		wake_up(&mdev->al_wait);
+	}
+}
+
+void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector)
+{
+	unsigned int enr = (sector >> (AL_EXTENT_SHIFT-9));
+	struct lc_element *extent;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->al_lock, flags);
+
+	extent = lc_find(mdev->act_log, enr);
+
+	if (!extent) {
+		spin_unlock_irqrestore(&mdev->al_lock, flags);
+		dev_err(DEV, "al_complete_io() called on inactive extent %u\n", enr);
+		return;
+	}
+
+	if (lc_put(mdev->act_log, extent) == 0)
+		wake_up(&mdev->al_wait);
+
+	spin_unlock_irqrestore(&mdev->al_lock, flags);
+}
+
+int
+w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct update_al_work *aw = container_of(w, struct update_al_work, w);
+	struct lc_element *updated = aw->al_ext;
+	const unsigned int new_enr = aw->enr;
+	const unsigned int evicted = aw->old_enr;
+	struct al_transaction *buffer;
+	sector_t sector;
+	int i, n, mx;
+	unsigned int extent_nr;
+	u32 xor_sum = 0;
+
+	if (!get_ldev(mdev)) {
+		dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n");
+		complete(&((struct update_al_work *)w)->event);
+		return 1;
+	}
+	/* do we have to do a bitmap write, first?
+	 * TODO reduce maximum latency:
+	 * submit both bios, then wait for both,
+	 * instead of doing two synchronous sector writes. */
+	if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE)
+		drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT);
+
+	mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */
+	buffer = (struct al_transaction *)page_address(mdev->md_io_page);
+
+	buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC);
+	buffer->tr_number = cpu_to_be32(mdev->al_tr_number);
+
+	n = lc_index_of(mdev->act_log, updated);
+
+	buffer->updates[0].pos = cpu_to_be32(n);
+	buffer->updates[0].extent = cpu_to_be32(new_enr);
+
+	xor_sum ^= new_enr;
+
+	mx = min_t(int, AL_EXTENTS_PT,
+		   mdev->act_log->nr_elements - mdev->al_tr_cycle);
+	for (i = 0; i < mx; i++) {
+		unsigned idx = mdev->al_tr_cycle + i;
+		extent_nr = lc_element_by_index(mdev->act_log, idx)->lc_number;
+		buffer->updates[i+1].pos = cpu_to_be32(idx);
+		buffer->updates[i+1].extent = cpu_to_be32(extent_nr);
+		xor_sum ^= extent_nr;
+	}
+	for (; i < AL_EXTENTS_PT; i++) {
+		buffer->updates[i+1].pos = __constant_cpu_to_be32(-1);
+		buffer->updates[i+1].extent = __constant_cpu_to_be32(LC_FREE);
+		xor_sum ^= LC_FREE;
+	}
+	mdev->al_tr_cycle += AL_EXTENTS_PT;
+	if (mdev->al_tr_cycle >= mdev->act_log->nr_elements)
+		mdev->al_tr_cycle = 0;
+
+	buffer->xor_sum = cpu_to_be32(xor_sum);
+
+	sector =  mdev->ldev->md.md_offset
+		+ mdev->ldev->md.al_offset + mdev->al_tr_pos;
+
+	if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE))
+		drbd_chk_io_error(mdev, 1, TRUE);
+
+	if (++mdev->al_tr_pos >
+	    div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT))
+		mdev->al_tr_pos = 0;
+
+	D_ASSERT(mdev->al_tr_pos < MD_AL_MAX_SIZE);
+	mdev->al_tr_number++;
+
+	mutex_unlock(&mdev->md_io_mutex);
+
+	complete(&((struct update_al_work *)w)->event);
+	put_ldev(mdev);
+
+	return 1;
+}
+
+/**
+ * drbd_al_read_tr() - Read a single transaction from the on disk activity log
+ * @mdev:	DRBD device.
+ * @bdev:	Block device to read form.
+ * @b:		pointer to an al_transaction.
+ * @index:	On disk slot of the transaction to read.
+ *
+ * Returns -1 on IO error, 0 on checksum error and 1 upon success.
+ */
+static int drbd_al_read_tr(struct drbd_conf *mdev,
+			   struct drbd_backing_dev *bdev,
+			   struct al_transaction *b,
+			   int index)
+{
+	sector_t sector;
+	int rv, i;
+	u32 xor_sum = 0;
+
+	sector = bdev->md.md_offset + bdev->md.al_offset + index;
+
+	/* Dont process error normally,
+	 * as this is done before disk is attached! */
+	if (!drbd_md_sync_page_io(mdev, bdev, sector, READ))
+		return -1;
+
+	rv = (be32_to_cpu(b->magic) == DRBD_MAGIC);
+
+	for (i = 0; i < AL_EXTENTS_PT + 1; i++)
+		xor_sum ^= be32_to_cpu(b->updates[i].extent);
+	rv &= (xor_sum == be32_to_cpu(b->xor_sum));
+
+	return rv;
+}
+
+/**
+ * drbd_al_read_log() - Restores the activity log from its on disk representation.
+ * @mdev:	DRBD device.
+ * @bdev:	Block device to read form.
+ *
+ * Returns 1 on success, returns 0 when reading the log failed due to IO errors.
+ */
+int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
+{
+	struct al_transaction *buffer;
+	int i;
+	int rv;
+	int mx;
+	int active_extents = 0;
+	int transactions = 0;
+	int found_valid = 0;
+	int from = 0;
+	int to = 0;
+	u32 from_tnr = 0;
+	u32 to_tnr = 0;
+	u32 cnr;
+
+	mx = div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT);
+
+	/* lock out all other meta data io for now,
+	 * and make sure the page is mapped.
+	 */
+	mutex_lock(&mdev->md_io_mutex);
+	buffer = page_address(mdev->md_io_page);
+
+	/* Find the valid transaction in the log */
+	for (i = 0; i <= mx; i++) {
+		rv = drbd_al_read_tr(mdev, bdev, buffer, i);
+		if (rv == 0)
+			continue;
+		if (rv == -1) {
+			mutex_unlock(&mdev->md_io_mutex);
+			return 0;
+		}
+		cnr = be32_to_cpu(buffer->tr_number);
+
+		if (++found_valid == 1) {
+			from = i;
+			to = i;
+			from_tnr = cnr;
+			to_tnr = cnr;
+			continue;
+		}
+		if ((int)cnr - (int)from_tnr < 0) {
+			D_ASSERT(from_tnr - cnr + i - from == mx+1);
+			from = i;
+			from_tnr = cnr;
+		}
+		if ((int)cnr - (int)to_tnr > 0) {
+			D_ASSERT(cnr - to_tnr == i - to);
+			to = i;
+			to_tnr = cnr;
+		}
+	}
+
+	if (!found_valid) {
+		dev_warn(DEV, "No usable activity log found.\n");
+		mutex_unlock(&mdev->md_io_mutex);
+		return 1;
+	}
+
+	/* Read the valid transactions.
+	 * dev_info(DEV, "Reading from %d to %d.\n",from,to); */
+	i = from;
+	while (1) {
+		int j, pos;
+		unsigned int extent_nr;
+		unsigned int trn;
+
+		rv = drbd_al_read_tr(mdev, bdev, buffer, i);
+		ERR_IF(rv == 0) goto cancel;
+		if (rv == -1) {
+			mutex_unlock(&mdev->md_io_mutex);
+			return 0;
+		}
+
+		trn = be32_to_cpu(buffer->tr_number);
+
+		spin_lock_irq(&mdev->al_lock);
+
+		/* This loop runs backwards because in the cyclic
+		   elements there might be an old version of the
+		   updated element (in slot 0). So the element in slot 0
+		   can overwrite old versions. */
+		for (j = AL_EXTENTS_PT; j >= 0; j--) {
+			pos = be32_to_cpu(buffer->updates[j].pos);
+			extent_nr = be32_to_cpu(buffer->updates[j].extent);
+
+			if (extent_nr == LC_FREE)
+				continue;
+
+			lc_set(mdev->act_log, extent_nr, pos);
+			active_extents++;
+		}
+		spin_unlock_irq(&mdev->al_lock);
+
+		transactions++;
+
+cancel:
+		if (i == to)
+			break;
+		i++;
+		if (i > mx)
+			i = 0;
+	}
+
+	mdev->al_tr_number = to_tnr+1;
+	mdev->al_tr_pos = to;
+	if (++mdev->al_tr_pos >
+	    div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT))
+		mdev->al_tr_pos = 0;
+
+	/* ok, we are done with it */
+	mutex_unlock(&mdev->md_io_mutex);
+
+	dev_info(DEV, "Found %d transactions (%d active extents) in activity log.\n",
+	     transactions, active_extents);
+
+	return 1;
+}
+
+static void atodb_endio(struct bio *bio, int error)
+{
+	struct drbd_atodb_wait *wc = bio->bi_private;
+	struct drbd_conf *mdev = wc->mdev;
+	struct page *page;
+	int uptodate = bio_flagged(bio, BIO_UPTODATE);
+
+	/* strange behavior of some lower level drivers...
+	 * fail the request by clearing the uptodate flag,
+	 * but do not return any error?! */
+	if (!error && !uptodate)
+		error = -EIO;
+
+	drbd_chk_io_error(mdev, error, TRUE);
+	if (error && wc->error == 0)
+		wc->error = error;
+
+	if (atomic_dec_and_test(&wc->count))
+		complete(&wc->io_done);
+
+	page = bio->bi_io_vec[0].bv_page;
+	put_page(page);
+	bio_put(bio);
+	mdev->bm_writ_cnt++;
+	put_ldev(mdev);
+}
+
+#define S2W(s)	((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+/* activity log to on disk bitmap -- prepare bio unless that sector
+ * is already covered by previously prepared bios */
+static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
+					struct bio **bios,
+					unsigned int enr,
+					struct drbd_atodb_wait *wc) __must_hold(local)
+{
+	struct bio *bio;
+	struct page *page;
+	sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
+				      + mdev->ldev->md.bm_offset;
+	unsigned int page_offset = PAGE_SIZE;
+	int offset;
+	int i = 0;
+	int err = -ENOMEM;
+
+	/* Check if that enr is already covered by an already created bio.
+	 * Caution, bios[] is not NULL terminated,
+	 * but only initialized to all NULL.
+	 * For completely scattered activity log,
+	 * the last invocation iterates over all bios,
+	 * and finds the last NULL entry.
+	 */
+	while ((bio = bios[i])) {
+		if (bio->bi_sector == on_disk_sector)
+			return 0;
+		i++;
+	}
+	/* bios[i] == NULL, the next not yet used slot */
+
+	/* GFP_KERNEL, we are not in the write-out path */
+	bio = bio_alloc(GFP_KERNEL, 1);
+	if (bio == NULL)
+		return -ENOMEM;
+
+	if (i > 0) {
+		const struct bio_vec *prev_bv = bios[i-1]->bi_io_vec;
+		page_offset = prev_bv->bv_offset + prev_bv->bv_len;
+		page = prev_bv->bv_page;
+	}
+	if (page_offset == PAGE_SIZE) {
+		page = alloc_page(__GFP_HIGHMEM);
+		if (page == NULL)
+			goto out_bio_put;
+		page_offset = 0;
+	} else {
+		get_page(page);
+	}
+
+	offset = S2W(enr);
+	drbd_bm_get_lel(mdev, offset,
+			min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+			kmap(page) + page_offset);
+	kunmap(page);
+
+	bio->bi_private = wc;
+	bio->bi_end_io = atodb_endio;
+	bio->bi_bdev = mdev->ldev->md_bdev;
+	bio->bi_sector = on_disk_sector;
+
+	if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE)
+		goto out_put_page;
+
+	atomic_inc(&wc->count);
+	/* we already know that we may do this...
+	 * get_ldev_if_state(mdev,D_ATTACHING);
+	 * just get the extra reference, so that the local_cnt reflects
+	 * the number of pending IO requests DRBD at its backing device.
+	 */
+	atomic_inc(&mdev->local_cnt);
+
+	bios[i] = bio;
+
+	return 0;
+
+out_put_page:
+	err = -EINVAL;
+	put_page(page);
+out_bio_put:
+	bio_put(bio);
+	return err;
+}
+
+/**
+ * drbd_al_to_on_disk_bm() -  * Writes bitmap parts covered by active AL extents
+ * @mdev:	DRBD device.
+ *
+ * Called when we detach (unconfigure) local storage,
+ * or when we go from R_PRIMARY to R_SECONDARY role.
+ */
+void drbd_al_to_on_disk_bm(struct drbd_conf *mdev)
+{
+	int i, nr_elements;
+	unsigned int enr;
+	struct bio **bios;
+	struct drbd_atodb_wait wc;
+
+	ERR_IF (!get_ldev_if_state(mdev, D_ATTACHING))
+		return; /* sorry, I don't have any act_log etc... */
+
+	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
+
+	nr_elements = mdev->act_log->nr_elements;
+
+	/* GFP_KERNEL, we are not in anyone's write-out path */
+	bios = kzalloc(sizeof(struct bio *) * nr_elements, GFP_KERNEL);
+	if (!bios)
+		goto submit_one_by_one;
+
+	atomic_set(&wc.count, 0);
+	init_completion(&wc.io_done);
+	wc.mdev = mdev;
+	wc.error = 0;
+
+	for (i = 0; i < nr_elements; i++) {
+		enr = lc_element_by_index(mdev->act_log, i)->lc_number;
+		if (enr == LC_FREE)
+			continue;
+		/* next statement also does atomic_inc wc.count and local_cnt */
+		if (atodb_prepare_unless_covered(mdev, bios,
+						enr/AL_EXT_PER_BM_SECT,
+						&wc))
+			goto free_bios_submit_one_by_one;
+	}
+
+	/* unnecessary optimization? */
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
+
+	/* all prepared, submit them */
+	for (i = 0; i < nr_elements; i++) {
+		if (bios[i] == NULL)
+			break;
+		if (FAULT_ACTIVE(mdev, DRBD_FAULT_MD_WR)) {
+			bios[i]->bi_rw = WRITE;
+			bio_endio(bios[i], -EIO);
+		} else {
+			submit_bio(WRITE, bios[i]);
+		}
+	}
+
+	drbd_blk_run_queue(bdev_get_queue(mdev->ldev->md_bdev));
+
+	/* always (try to) flush bitmap to stable storage */
+	drbd_md_flush(mdev);
+
+	/* In case we did not submit a single IO do not wait for
+	 * them to complete. ( Because we would wait forever here. )
+	 *
+	 * In case we had IOs and they are already complete, there
+	 * is not point in waiting anyways.
+	 * Therefore this if () ... */
+	if (atomic_read(&wc.count))
+		wait_for_completion(&wc.io_done);
+
+	put_ldev(mdev);
+
+	kfree(bios);
+	return;
+
+ free_bios_submit_one_by_one:
+	/* free everything by calling the endio callback directly. */
+	for (i = 0; i < nr_elements && bios[i]; i++)
+		bio_endio(bios[i], 0);
+
+	kfree(bios);
+
+ submit_one_by_one:
+	dev_warn(DEV, "Using the slow drbd_al_to_on_disk_bm()\n");
+
+	for (i = 0; i < mdev->act_log->nr_elements; i++) {
+		enr = lc_element_by_index(mdev->act_log, i)->lc_number;
+		if (enr == LC_FREE)
+			continue;
+		/* Really slow: if we have al-extents 16..19 active,
+		 * sector 4 will be written four times! Synchronous! */
+		drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT);
+	}
+
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
+	put_ldev(mdev);
+}
+
+/**
+ * drbd_al_apply_to_bm() - Sets the bitmap to diry(1) where covered ba active AL extents
+ * @mdev:	DRBD device.
+ */
+void drbd_al_apply_to_bm(struct drbd_conf *mdev)
+{
+	unsigned int enr;
+	unsigned long add = 0;
+	char ppb[10];
+	int i;
+
+	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
+
+	for (i = 0; i < mdev->act_log->nr_elements; i++) {
+		enr = lc_element_by_index(mdev->act_log, i)->lc_number;
+		if (enr == LC_FREE)
+			continue;
+		add += drbd_bm_ALe_set_all(mdev, enr);
+	}
+
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
+
+	dev_info(DEV, "Marked additional %s as out-of-sync based on AL.\n",
+	     ppsize(ppb, Bit2KB(add)));
+}
+
+static int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext)
+{
+	int rv;
+
+	spin_lock_irq(&mdev->al_lock);
+	rv = (al_ext->refcnt == 0);
+	if (likely(rv))
+		lc_del(mdev->act_log, al_ext);
+	spin_unlock_irq(&mdev->al_lock);
+
+	return rv;
+}
+
+/**
+ * drbd_al_shrink() - Removes all active extents form the activity log
+ * @mdev:	DRBD device.
+ *
+ * Removes all active extents form the activity log, waiting until
+ * the reference count of each entry dropped to 0 first, of course.
+ *
+ * You need to lock mdev->act_log with lc_try_lock() / lc_unlock()
+ */
+void drbd_al_shrink(struct drbd_conf *mdev)
+{
+	struct lc_element *al_ext;
+	int i;
+
+	D_ASSERT(test_bit(__LC_DIRTY, &mdev->act_log->flags));
+
+	for (i = 0; i < mdev->act_log->nr_elements; i++) {
+		al_ext = lc_element_by_index(mdev->act_log, i);
+		if (al_ext->lc_number == LC_FREE)
+			continue;
+		wait_event(mdev->al_wait, _try_lc_del(mdev, al_ext));
+	}
+
+	wake_up(&mdev->al_wait);
+}
+
+static int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
+
+	if (!get_ldev(mdev)) {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_warn(DEV, "Can not update on disk bitmap, local IO disabled.\n");
+		kfree(udw);
+		return 1;
+	}
+
+	drbd_bm_write_sect(mdev, udw->enr);
+	put_ldev(mdev);
+
+	kfree(udw);
+
+	if (drbd_bm_total_weight(mdev) <= mdev->rs_failed) {
+		switch (mdev->state.conn) {
+		case C_SYNC_SOURCE:  case C_SYNC_TARGET:
+		case C_PAUSED_SYNC_S: case C_PAUSED_SYNC_T:
+			drbd_resync_finished(mdev);
+		default:
+			/* nothing to do */
+			break;
+		}
+	}
+	drbd_bcast_sync_progress(mdev);
+
+	return 1;
+}
+
+
+/* ATTENTION. The AL's extents are 4MB each, while the extents in the
+ * resync LRU-cache are 16MB each.
+ * The caller of this function has to hold an get_ldev() reference.
+ *
+ * TODO will be obsoleted once we have a caching lru of the on disk bitmap
+ */
+static void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector,
+				      int count, int success)
+{
+	struct lc_element *e;
+	struct update_odbm_work *udw;
+
+	unsigned int enr;
+
+	D_ASSERT(atomic_read(&mdev->local_cnt));
+
+	/* I simply assume that a sector/size pair never crosses
+	 * a 16 MB extent border. (Currently this is true...) */
+	enr = BM_SECT_TO_EXT(sector);
+
+	e = lc_get(mdev->resync, enr);
+	if (e) {
+		struct bm_extent *ext = lc_entry(e, struct bm_extent, lce);
+		if (ext->lce.lc_number == enr) {
+			if (success)
+				ext->rs_left -= count;
+			else
+				ext->rs_failed += count;
+			if (ext->rs_left < ext->rs_failed) {
+				dev_err(DEV, "BAD! sector=%llus enr=%u rs_left=%d "
+				    "rs_failed=%d count=%d\n",
+				     (unsigned long long)sector,
+				     ext->lce.lc_number, ext->rs_left,
+				     ext->rs_failed, count);
+				dump_stack();
+
+				lc_put(mdev->resync, &ext->lce);
+				drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+				return;
+			}
+		} else {
+			/* Normally this element should be in the cache,
+			 * since drbd_rs_begin_io() pulled it already in.
+			 *
+			 * But maybe an application write finished, and we set
+			 * something outside the resync lru_cache in sync.
+			 */
+			int rs_left = drbd_bm_e_weight(mdev, enr);
+			if (ext->flags != 0) {
+				dev_warn(DEV, "changing resync lce: %d[%u;%02lx]"
+				     " -> %d[%u;00]\n",
+				     ext->lce.lc_number, ext->rs_left,
+				     ext->flags, enr, rs_left);
+				ext->flags = 0;
+			}
+			if (ext->rs_failed) {
+				dev_warn(DEV, "Kicking resync_lru element enr=%u "
+				     "out with rs_failed=%d\n",
+				     ext->lce.lc_number, ext->rs_failed);
+				set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags);
+			}
+			ext->rs_left = rs_left;
+			ext->rs_failed = success ? 0 : count;
+			lc_changed(mdev->resync, &ext->lce);
+		}
+		lc_put(mdev->resync, &ext->lce);
+		/* no race, we are within the al_lock! */
+
+		if (ext->rs_left == ext->rs_failed) {
+			ext->rs_failed = 0;
+
+			udw = kmalloc(sizeof(*udw), GFP_ATOMIC);
+			if (udw) {
+				udw->enr = ext->lce.lc_number;
+				udw->w.cb = w_update_odbm;
+				drbd_queue_work_front(&mdev->data.work, &udw->w);
+			} else {
+				dev_warn(DEV, "Could not kmalloc an udw\n");
+				set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags);
+			}
+		}
+	} else {
+		dev_err(DEV, "lc_get() failed! locked=%d/%d flags=%lu\n",
+		    mdev->resync_locked,
+		    mdev->resync->nr_elements,
+		    mdev->resync->flags);
+	}
+}
+
+/* clear the bit corresponding to the piece of storage in question:
+ * size byte of data starting from sector.  Only clear a bits of the affected
+ * one ore more _aligned_ BM_BLOCK_SIZE blocks.
+ *
+ * called by worker on C_SYNC_TARGET and receiver on SyncSource.
+ *
+ */
+void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
+		       const char *file, const unsigned int line)
+{
+	/* Is called from worker and receiver context _only_ */
+	unsigned long sbnr, ebnr, lbnr;
+	unsigned long count = 0;
+	sector_t esector, nr_sectors;
+	int wake_up = 0;
+	unsigned long flags;
+
+	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
+		dev_err(DEV, "drbd_set_in_sync: sector=%llus size=%d nonsense!\n",
+				(unsigned long long)sector, size);
+		return;
+	}
+	nr_sectors = drbd_get_capacity(mdev->this_bdev);
+	esector = sector + (size >> 9) - 1;
+
+	ERR_IF(sector >= nr_sectors) return;
+	ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
+
+	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
+
+	/* we clear it (in sync).
+	 * round up start sector, round down end sector.  we make sure we only
+	 * clear full, aligned, BM_BLOCK_SIZE (4K) blocks */
+	if (unlikely(esector < BM_SECT_PER_BIT-1))
+		return;
+	if (unlikely(esector == (nr_sectors-1)))
+		ebnr = lbnr;
+	else
+		ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1));
+	sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1);
+
+	if (sbnr > ebnr)
+		return;
+
+	/*
+	 * ok, (capacity & 7) != 0 sometimes, but who cares...
+	 * we count rs_{total,left} in bits, not sectors.
+	 */
+	spin_lock_irqsave(&mdev->al_lock, flags);
+	count = drbd_bm_clear_bits(mdev, sbnr, ebnr);
+	if (count) {
+		/* we need the lock for drbd_try_clear_on_disk_bm */
+		if (jiffies - mdev->rs_mark_time > HZ*10) {
+			/* should be rolling marks,
+			 * but we estimate only anyways. */
+			if (mdev->rs_mark_left != drbd_bm_total_weight(mdev) &&
+			    mdev->state.conn != C_PAUSED_SYNC_T &&
+			    mdev->state.conn != C_PAUSED_SYNC_S) {
+				mdev->rs_mark_time = jiffies;
+				mdev->rs_mark_left = drbd_bm_total_weight(mdev);
+			}
+		}
+		if (get_ldev(mdev)) {
+			drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE);
+			put_ldev(mdev);
+		}
+		/* just wake_up unconditional now, various lc_chaged(),
+		 * lc_put() in drbd_try_clear_on_disk_bm(). */
+		wake_up = 1;
+	}
+	spin_unlock_irqrestore(&mdev->al_lock, flags);
+	if (wake_up)
+		wake_up(&mdev->al_wait);
+}
+
+/*
+ * this is intended to set one request worth of data out of sync.
+ * affects at least 1 bit,
+ * and at most 1+DRBD_MAX_SEGMENT_SIZE/BM_BLOCK_SIZE bits.
+ *
+ * called by tl_clear and drbd_send_dblock (==drbd_make_request).
+ * so this can be _any_ process.
+ */
+void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size,
+			    const char *file, const unsigned int line)
+{
+	unsigned long sbnr, ebnr, lbnr, flags;
+	sector_t esector, nr_sectors;
+	unsigned int enr, count;
+	struct lc_element *e;
+
+	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
+		dev_err(DEV, "sector: %llus, size: %d\n",
+			(unsigned long long)sector, size);
+		return;
+	}
+
+	if (!get_ldev(mdev))
+		return; /* no disk, no metadata, no bitmap to set bits in */
+
+	nr_sectors = drbd_get_capacity(mdev->this_bdev);
+	esector = sector + (size >> 9) - 1;
+
+	ERR_IF(sector >= nr_sectors)
+		goto out;
+	ERR_IF(esector >= nr_sectors)
+		esector = (nr_sectors-1);
+
+	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
+
+	/* we set it out of sync,
+	 * we do not need to round anything here */
+	sbnr = BM_SECT_TO_BIT(sector);
+	ebnr = BM_SECT_TO_BIT(esector);
+
+	/* ok, (capacity & 7) != 0 sometimes, but who cares...
+	 * we count rs_{total,left} in bits, not sectors.  */
+	spin_lock_irqsave(&mdev->al_lock, flags);
+	count = drbd_bm_set_bits(mdev, sbnr, ebnr);
+
+	enr = BM_SECT_TO_EXT(sector);
+	e = lc_find(mdev->resync, enr);
+	if (e)
+		lc_entry(e, struct bm_extent, lce)->rs_left += count;
+	spin_unlock_irqrestore(&mdev->al_lock, flags);
+
+out:
+	put_ldev(mdev);
+}
+
+static
+struct bm_extent *_bme_get(struct drbd_conf *mdev, unsigned int enr)
+{
+	struct lc_element *e;
+	struct bm_extent *bm_ext;
+	int wakeup = 0;
+	unsigned long rs_flags;
+
+	spin_lock_irq(&mdev->al_lock);
+	if (mdev->resync_locked > mdev->resync->nr_elements/2) {
+		spin_unlock_irq(&mdev->al_lock);
+		return NULL;
+	}
+	e = lc_get(mdev->resync, enr);
+	bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+	if (bm_ext) {
+		if (bm_ext->lce.lc_number != enr) {
+			bm_ext->rs_left = drbd_bm_e_weight(mdev, enr);
+			bm_ext->rs_failed = 0;
+			lc_changed(mdev->resync, &bm_ext->lce);
+			wakeup = 1;
+		}
+		if (bm_ext->lce.refcnt == 1)
+			mdev->resync_locked++;
+		set_bit(BME_NO_WRITES, &bm_ext->flags);
+	}
+	rs_flags = mdev->resync->flags;
+	spin_unlock_irq(&mdev->al_lock);
+	if (wakeup)
+		wake_up(&mdev->al_wait);
+
+	if (!bm_ext) {
+		if (rs_flags & LC_STARVING)
+			dev_warn(DEV, "Have to wait for element"
+			     " (resync LRU too small?)\n");
+		BUG_ON(rs_flags & LC_DIRTY);
+	}
+
+	return bm_ext;
+}
+
+static int _is_in_al(struct drbd_conf *mdev, unsigned int enr)
+{
+	struct lc_element *al_ext;
+	int rv = 0;
+
+	spin_lock_irq(&mdev->al_lock);
+	if (unlikely(enr == mdev->act_log->new_number))
+		rv = 1;
+	else {
+		al_ext = lc_find(mdev->act_log, enr);
+		if (al_ext) {
+			if (al_ext->refcnt)
+				rv = 1;
+		}
+	}
+	spin_unlock_irq(&mdev->al_lock);
+
+	/*
+	if (unlikely(rv)) {
+		dev_info(DEV, "Delaying sync read until app's write is done\n");
+	}
+	*/
+	return rv;
+}
+
+/**
+ * drbd_rs_begin_io() - Gets an extent in the resync LRU cache and sets it to BME_LOCKED
+ * @mdev:	DRBD device.
+ * @sector:	The sector number.
+ *
+ * This functions sleeps on al_wait. Returns 1 on success, 0 if interrupted.
+ */
+int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
+{
+	unsigned int enr = BM_SECT_TO_EXT(sector);
+	struct bm_extent *bm_ext;
+	int i, sig;
+
+	sig = wait_event_interruptible(mdev->al_wait,
+			(bm_ext = _bme_get(mdev, enr)));
+	if (sig)
+		return 0;
+
+	if (test_bit(BME_LOCKED, &bm_ext->flags))
+		return 1;
+
+	for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
+		sig = wait_event_interruptible(mdev->al_wait,
+				!_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i));
+		if (sig) {
+			spin_lock_irq(&mdev->al_lock);
+			if (lc_put(mdev->resync, &bm_ext->lce) == 0) {
+				clear_bit(BME_NO_WRITES, &bm_ext->flags);
+				mdev->resync_locked--;
+				wake_up(&mdev->al_wait);
+			}
+			spin_unlock_irq(&mdev->al_lock);
+			return 0;
+		}
+	}
+
+	set_bit(BME_LOCKED, &bm_ext->flags);
+
+	return 1;
+}
+
+/**
+ * drbd_try_rs_begin_io() - Gets an extent in the resync LRU cache, does not sleep
+ * @mdev:	DRBD device.
+ * @sector:	The sector number.
+ *
+ * Gets an extent in the resync LRU cache, sets it to BME_NO_WRITES, then
+ * tries to set it to BME_LOCKED. Returns 0 upon success, and -EAGAIN
+ * if there is still application IO going on in this area.
+ */
+int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
+{
+	unsigned int enr = BM_SECT_TO_EXT(sector);
+	const unsigned int al_enr = enr*AL_EXT_PER_BM_SECT;
+	struct lc_element *e;
+	struct bm_extent *bm_ext;
+	int i;
+
+	spin_lock_irq(&mdev->al_lock);
+	if (mdev->resync_wenr != LC_FREE && mdev->resync_wenr != enr) {
+		/* in case you have very heavy scattered io, it may
+		 * stall the syncer undefined if we give up the ref count
+		 * when we try again and requeue.
+		 *
+		 * if we don't give up the refcount, but the next time
+		 * we are scheduled this extent has been "synced" by new
+		 * application writes, we'd miss the lc_put on the
+		 * extent we keep the refcount on.
+		 * so we remembered which extent we had to try again, and
+		 * if the next requested one is something else, we do
+		 * the lc_put here...
+		 * we also have to wake_up
+		 */
+		e = lc_find(mdev->resync, mdev->resync_wenr);
+		bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+		if (bm_ext) {
+			D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags));
+			D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags));
+			clear_bit(BME_NO_WRITES, &bm_ext->flags);
+			mdev->resync_wenr = LC_FREE;
+			if (lc_put(mdev->resync, &bm_ext->lce) == 0)
+				mdev->resync_locked--;
+			wake_up(&mdev->al_wait);
+		} else {
+			dev_alert(DEV, "LOGIC BUG\n");
+		}
+	}
+	/* TRY. */
+	e = lc_try_get(mdev->resync, enr);
+	bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+	if (bm_ext) {
+		if (test_bit(BME_LOCKED, &bm_ext->flags))
+			goto proceed;
+		if (!test_and_set_bit(BME_NO_WRITES, &bm_ext->flags)) {
+			mdev->resync_locked++;
+		} else {
+			/* we did set the BME_NO_WRITES,
+			 * but then could not set BME_LOCKED,
+			 * so we tried again.
+			 * drop the extra reference. */
+			bm_ext->lce.refcnt--;
+			D_ASSERT(bm_ext->lce.refcnt > 0);
+		}
+		goto check_al;
+	} else {
+		/* do we rather want to try later? */
+		if (mdev->resync_locked > mdev->resync->nr_elements-3)
+			goto try_again;
+		/* Do or do not. There is no try. -- Yoda */
+		e = lc_get(mdev->resync, enr);
+		bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+		if (!bm_ext) {
+			const unsigned long rs_flags = mdev->resync->flags;
+			if (rs_flags & LC_STARVING)
+				dev_warn(DEV, "Have to wait for element"
+				     " (resync LRU too small?)\n");
+			BUG_ON(rs_flags & LC_DIRTY);
+			goto try_again;
+		}
+		if (bm_ext->lce.lc_number != enr) {
+			bm_ext->rs_left = drbd_bm_e_weight(mdev, enr);
+			bm_ext->rs_failed = 0;
+			lc_changed(mdev->resync, &bm_ext->lce);
+			wake_up(&mdev->al_wait);
+			D_ASSERT(test_bit(BME_LOCKED, &bm_ext->flags) == 0);
+		}
+		set_bit(BME_NO_WRITES, &bm_ext->flags);
+		D_ASSERT(bm_ext->lce.refcnt == 1);
+		mdev->resync_locked++;
+		goto check_al;
+	}
+check_al:
+	for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
+		if (unlikely(al_enr+i == mdev->act_log->new_number))
+			goto try_again;
+		if (lc_is_used(mdev->act_log, al_enr+i))
+			goto try_again;
+	}
+	set_bit(BME_LOCKED, &bm_ext->flags);
+proceed:
+	mdev->resync_wenr = LC_FREE;
+	spin_unlock_irq(&mdev->al_lock);
+	return 0;
+
+try_again:
+	if (bm_ext)
+		mdev->resync_wenr = enr;
+	spin_unlock_irq(&mdev->al_lock);
+	return -EAGAIN;
+}
+
+void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector)
+{
+	unsigned int enr = BM_SECT_TO_EXT(sector);
+	struct lc_element *e;
+	struct bm_extent *bm_ext;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->al_lock, flags);
+	e = lc_find(mdev->resync, enr);
+	bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+	if (!bm_ext) {
+		spin_unlock_irqrestore(&mdev->al_lock, flags);
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "drbd_rs_complete_io() called, but extent not found\n");
+		return;
+	}
+
+	if (bm_ext->lce.refcnt == 0) {
+		spin_unlock_irqrestore(&mdev->al_lock, flags);
+		dev_err(DEV, "drbd_rs_complete_io(,%llu [=%u]) called, "
+		    "but refcnt is 0!?\n",
+		    (unsigned long long)sector, enr);
+		return;
+	}
+
+	if (lc_put(mdev->resync, &bm_ext->lce) == 0) {
+		clear_bit(BME_LOCKED, &bm_ext->flags);
+		clear_bit(BME_NO_WRITES, &bm_ext->flags);
+		mdev->resync_locked--;
+		wake_up(&mdev->al_wait);
+	}
+
+	spin_unlock_irqrestore(&mdev->al_lock, flags);
+}
+
+/**
+ * drbd_rs_cancel_all() - Removes all extents from the resync LRU (even BME_LOCKED)
+ * @mdev:	DRBD device.
+ */
+void drbd_rs_cancel_all(struct drbd_conf *mdev)
+{
+	spin_lock_irq(&mdev->al_lock);
+
+	if (get_ldev_if_state(mdev, D_FAILED)) { /* Makes sure ->resync is there. */
+		lc_reset(mdev->resync);
+		put_ldev(mdev);
+	}
+	mdev->resync_locked = 0;
+	mdev->resync_wenr = LC_FREE;
+	spin_unlock_irq(&mdev->al_lock);
+	wake_up(&mdev->al_wait);
+}
+
+/**
+ * drbd_rs_del_all() - Gracefully remove all extents from the resync LRU
+ * @mdev:	DRBD device.
+ *
+ * Returns 0 upon success, -EAGAIN if at least one reference count was
+ * not zero.
+ */
+int drbd_rs_del_all(struct drbd_conf *mdev)
+{
+	struct lc_element *e;
+	struct bm_extent *bm_ext;
+	int i;
+
+	spin_lock_irq(&mdev->al_lock);
+
+	if (get_ldev_if_state(mdev, D_FAILED)) {
+		/* ok, ->resync is there. */
+		for (i = 0; i < mdev->resync->nr_elements; i++) {
+			e = lc_element_by_index(mdev->resync, i);
+			bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+			if (bm_ext->lce.lc_number == LC_FREE)
+				continue;
+			if (bm_ext->lce.lc_number == mdev->resync_wenr) {
+				dev_info(DEV, "dropping %u in drbd_rs_del_all, apparently"
+				     " got 'synced' by application io\n",
+				     mdev->resync_wenr);
+				D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags));
+				D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags));
+				clear_bit(BME_NO_WRITES, &bm_ext->flags);
+				mdev->resync_wenr = LC_FREE;
+				lc_put(mdev->resync, &bm_ext->lce);
+			}
+			if (bm_ext->lce.refcnt != 0) {
+				dev_info(DEV, "Retrying drbd_rs_del_all() later. "
+				     "refcnt=%d\n", bm_ext->lce.refcnt);
+				put_ldev(mdev);
+				spin_unlock_irq(&mdev->al_lock);
+				return -EAGAIN;
+			}
+			D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags));
+			D_ASSERT(!test_bit(BME_NO_WRITES, &bm_ext->flags));
+			lc_del(mdev->resync, &bm_ext->lce);
+		}
+		D_ASSERT(mdev->resync->used == 0);
+		put_ldev(mdev);
+	}
+	spin_unlock_irq(&mdev->al_lock);
+
+	return 0;
+}
+
+/**
+ * drbd_rs_failed_io() - Record information on a failure to resync the specified blocks
+ * @mdev:	DRBD device.
+ * @sector:	The sector number.
+ * @size:	Size of failed IO operation, in byte.
+ */
+void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size)
+{
+	/* Is called from worker and receiver context _only_ */
+	unsigned long sbnr, ebnr, lbnr;
+	unsigned long count;
+	sector_t esector, nr_sectors;
+	int wake_up = 0;
+
+	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
+		dev_err(DEV, "drbd_rs_failed_io: sector=%llus size=%d nonsense!\n",
+				(unsigned long long)sector, size);
+		return;
+	}
+	nr_sectors = drbd_get_capacity(mdev->this_bdev);
+	esector = sector + (size >> 9) - 1;
+
+	ERR_IF(sector >= nr_sectors) return;
+	ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1);
+
+	lbnr = BM_SECT_TO_BIT(nr_sectors-1);
+
+	/*
+	 * round up start sector, round down end sector.  we make sure we only
+	 * handle full, aligned, BM_BLOCK_SIZE (4K) blocks */
+	if (unlikely(esector < BM_SECT_PER_BIT-1))
+		return;
+	if (unlikely(esector == (nr_sectors-1)))
+		ebnr = lbnr;
+	else
+		ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1));
+	sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1);
+
+	if (sbnr > ebnr)
+		return;
+
+	/*
+	 * ok, (capacity & 7) != 0 sometimes, but who cares...
+	 * we count rs_{total,left} in bits, not sectors.
+	 */
+	spin_lock_irq(&mdev->al_lock);
+	count = drbd_bm_count_bits(mdev, sbnr, ebnr);
+	if (count) {
+		mdev->rs_failed += count;
+
+		if (get_ldev(mdev)) {
+			drbd_try_clear_on_disk_bm(mdev, sector, count, FALSE);
+			put_ldev(mdev);
+		}
+
+		/* just wake_up unconditional now, various lc_chaged(),
+		 * lc_put() in drbd_try_clear_on_disk_bm(). */
+		wake_up = 1;
+	}
+	spin_unlock_irq(&mdev->al_lock);
+	if (wake_up)
+		wake_up(&mdev->al_wait);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_bitmap.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_bitmap.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_bitmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_bitmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1327 @@
+/*
+   drbd_bitmap.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2004-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 2004-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2004-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/bitops.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/drbd.h>
+#include <asm/kmap_types.h>
+#include "drbd_int.h"
+
+/* OPAQUE outside this file!
+ * interface defined in drbd_int.h
+
+ * convention:
+ * function name drbd_bm_... => used elsewhere, "public".
+ * function name      bm_... => internal to implementation, "private".
+
+ * Note that since find_first_bit returns int, at the current granularity of
+ * the bitmap (4KB per byte), this implementation "only" supports up to
+ * 1<<(32+12) == 16 TB...
+ */
+
+/*
+ * NOTE
+ *  Access to the *bm_pages is protected by bm_lock.
+ *  It is safe to read the other members within the lock.
+ *
+ *  drbd_bm_set_bits is called from bio_endio callbacks,
+ *  We may be called with irq already disabled,
+ *  so we need spin_lock_irqsave().
+ *  And we need the kmap_atomic.
+ */
+struct drbd_bitmap {
+	struct page **bm_pages;
+	spinlock_t bm_lock;
+	/* WARNING unsigned long bm_*:
+	 * 32bit number of bit offset is just enough for 512 MB bitmap.
+	 * it will blow up if we make the bitmap bigger...
+	 * not that it makes much sense to have a bitmap that large,
+	 * rather change the granularity to 16k or 64k or something.
+	 * (that implies other problems, however...)
+	 */
+	unsigned long bm_set;       /* nr of set bits; THINK maybe atomic_t? */
+	unsigned long bm_bits;
+	size_t   bm_words;
+	size_t   bm_number_of_pages;
+	sector_t bm_dev_capacity;
+	struct semaphore bm_change; /* serializes resize operations */
+
+	atomic_t bm_async_io;
+	wait_queue_head_t bm_io_wait;
+
+	unsigned long  bm_flags;
+
+	/* debugging aid, in case we are still racy somewhere */
+	char          *bm_why;
+	struct task_struct *bm_task;
+};
+
+/* definition of bits in bm_flags */
+#define BM_LOCKED       0
+#define BM_MD_IO_ERROR  1
+#define BM_P_VMALLOCED  2
+
+static int bm_is_locked(struct drbd_bitmap *b)
+{
+	return test_bit(BM_LOCKED, &b->bm_flags);
+}
+
+#define bm_print_lock_info(m) __bm_print_lock_info(m, __func__)
+static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	if (!__ratelimit(&drbd_ratelimit_state))
+		return;
+	dev_err(DEV, "FIXME %s in %s, bitmap locked for '%s' by %s\n",
+	    current == mdev->receiver.task ? "receiver" :
+	    current == mdev->asender.task  ? "asender"  :
+	    current == mdev->worker.task   ? "worker"   : current->comm,
+	    func, b->bm_why ?: "?",
+	    b->bm_task == mdev->receiver.task ? "receiver" :
+	    b->bm_task == mdev->asender.task  ? "asender"  :
+	    b->bm_task == mdev->worker.task   ? "worker"   : "?");
+}
+
+void drbd_bm_lock(struct drbd_conf *mdev, char *why)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	int trylock_failed;
+
+	if (!b) {
+		dev_err(DEV, "FIXME no bitmap in drbd_bm_lock!?\n");
+		return;
+	}
+
+	trylock_failed = down_trylock(&b->bm_change);
+
+	if (trylock_failed) {
+		dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
+		    current == mdev->receiver.task ? "receiver" :
+		    current == mdev->asender.task  ? "asender"  :
+		    current == mdev->worker.task   ? "worker"   : current->comm,
+		    why, b->bm_why ?: "?",
+		    b->bm_task == mdev->receiver.task ? "receiver" :
+		    b->bm_task == mdev->asender.task  ? "asender"  :
+		    b->bm_task == mdev->worker.task   ? "worker"   : "?");
+		down(&b->bm_change);
+	}
+	if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
+		dev_err(DEV, "FIXME bitmap already locked in bm_lock\n");
+
+	b->bm_why  = why;
+	b->bm_task = current;
+}
+
+void drbd_bm_unlock(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	if (!b) {
+		dev_err(DEV, "FIXME no bitmap in drbd_bm_unlock!?\n");
+		return;
+	}
+
+	if (!__test_and_clear_bit(BM_LOCKED, &mdev->bitmap->bm_flags))
+		dev_err(DEV, "FIXME bitmap not locked in bm_unlock\n");
+
+	b->bm_why  = NULL;
+	b->bm_task = NULL;
+	up(&b->bm_change);
+}
+
+/* word offset to long pointer */
+static unsigned long *__bm_map_paddr(struct drbd_bitmap *b, unsigned long offset, const enum km_type km)
+{
+	struct page *page;
+	unsigned long page_nr;
+
+	/* page_nr = (word*sizeof(long)) >> PAGE_SHIFT; */
+	page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3);
+	BUG_ON(page_nr >= b->bm_number_of_pages);
+	page = b->bm_pages[page_nr];
+
+	return (unsigned long *) kmap_atomic(page, km);
+}
+
+static unsigned long * bm_map_paddr(struct drbd_bitmap *b, unsigned long offset)
+{
+	return __bm_map_paddr(b, offset, KM_IRQ1);
+}
+
+static void __bm_unmap(unsigned long *p_addr, const enum km_type km)
+{
+	kunmap_atomic(p_addr, km);
+};
+
+static void bm_unmap(unsigned long *p_addr)
+{
+	return __bm_unmap(p_addr, KM_IRQ1);
+}
+
+/* long word offset of _bitmap_ sector */
+#define S2W(s)	((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+/* word offset from start of bitmap to word number _in_page_
+ * modulo longs per page
+#define MLPP(X) ((X) % (PAGE_SIZE/sizeof(long))
+ hm, well, Philipp thinks gcc might not optimze the % into & (... - 1)
+ so do it explicitly:
+ */
+#define MLPP(X) ((X) & ((PAGE_SIZE/sizeof(long))-1))
+
+/* Long words per page */
+#define LWPP (PAGE_SIZE/sizeof(long))
+
+/*
+ * actually most functions herein should take a struct drbd_bitmap*, not a
+ * struct drbd_conf*, but for the debug macros I like to have the mdev around
+ * to be able to report device specific.
+ */
+
+static void bm_free_pages(struct page **pages, unsigned long number)
+{
+	unsigned long i;
+	if (!pages)
+		return;
+
+	for (i = 0; i < number; i++) {
+		if (!pages[i]) {
+			printk(KERN_ALERT "drbd: bm_free_pages tried to free "
+					  "a NULL pointer; i=%lu n=%lu\n",
+					  i, number);
+			continue;
+		}
+		__free_page(pages[i]);
+		pages[i] = NULL;
+	}
+}
+
+static void bm_vk_free(void *ptr, int v)
+{
+	if (v)
+		vfree(ptr);
+	else
+		kfree(ptr);
+}
+
+/*
+ * "have" and "want" are NUMBER OF PAGES.
+ */
+static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
+{
+	struct page **old_pages = b->bm_pages;
+	struct page **new_pages, *page;
+	unsigned int i, bytes, vmalloced = 0;
+	unsigned long have = b->bm_number_of_pages;
+
+	BUG_ON(have == 0 && old_pages != NULL);
+	BUG_ON(have != 0 && old_pages == NULL);
+
+	if (have == want)
+		return old_pages;
+
+	/* Trying kmalloc first, falling back to vmalloc.
+	 * GFP_KERNEL is ok, as this is done when a lower level disk is
+	 * "attached" to the drbd.  Context is receiver thread or cqueue
+	 * thread.  As we have no disk yet, we are not in the IO path,
+	 * not even the IO path of the peer. */
+	bytes = sizeof(struct page *)*want;
+	new_pages = kmalloc(bytes, GFP_KERNEL);
+	if (!new_pages) {
+		new_pages = vmalloc(bytes);
+		if (!new_pages)
+			return NULL;
+		vmalloced = 1;
+	}
+
+	memset(new_pages, 0, bytes);
+	if (want >= have) {
+		for (i = 0; i < have; i++)
+			new_pages[i] = old_pages[i];
+		for (; i < want; i++) {
+			page = alloc_page(GFP_HIGHUSER);
+			if (!page) {
+				bm_free_pages(new_pages + have, i - have);
+				bm_vk_free(new_pages, vmalloced);
+				return NULL;
+			}
+			new_pages[i] = page;
+		}
+	} else {
+		for (i = 0; i < want; i++)
+			new_pages[i] = old_pages[i];
+		/* NOT HERE, we are outside the spinlock!
+		bm_free_pages(old_pages + want, have - want);
+		*/
+	}
+
+	if (vmalloced)
+		set_bit(BM_P_VMALLOCED, &b->bm_flags);
+	else
+		clear_bit(BM_P_VMALLOCED, &b->bm_flags);
+
+	return new_pages;
+}
+
+/*
+ * called on driver init only. TODO call when a device is created.
+ * allocates the drbd_bitmap, and stores it in mdev->bitmap.
+ */
+int drbd_bm_init(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	WARN_ON(b != NULL);
+	b = kzalloc(sizeof(struct drbd_bitmap), GFP_KERNEL);
+	if (!b)
+		return -ENOMEM;
+	spin_lock_init(&b->bm_lock);
+	init_MUTEX(&b->bm_change);
+	init_waitqueue_head(&b->bm_io_wait);
+
+	mdev->bitmap = b;
+
+	return 0;
+}
+
+sector_t drbd_bm_capacity(struct drbd_conf *mdev)
+{
+	ERR_IF(!mdev->bitmap) return 0;
+	return mdev->bitmap->bm_dev_capacity;
+}
+
+/* called on driver unload. TODO: call when a device is destroyed.
+ */
+void drbd_bm_cleanup(struct drbd_conf *mdev)
+{
+	ERR_IF (!mdev->bitmap) return;
+	bm_free_pages(mdev->bitmap->bm_pages, mdev->bitmap->bm_number_of_pages);
+	bm_vk_free(mdev->bitmap->bm_pages, test_bit(BM_P_VMALLOCED, &mdev->bitmap->bm_flags));
+	kfree(mdev->bitmap);
+	mdev->bitmap = NULL;
+}
+
+/*
+ * since (b->bm_bits % BITS_PER_LONG) != 0,
+ * this masks out the remaining bits.
+ * Returns the number of bits cleared.
+ */
+static int bm_clear_surplus(struct drbd_bitmap *b)
+{
+	const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1;
+	size_t w = b->bm_bits >> LN2_BPL;
+	int cleared = 0;
+	unsigned long *p_addr, *bm;
+
+	p_addr = bm_map_paddr(b, w);
+	bm = p_addr + MLPP(w);
+	if (w < b->bm_words) {
+		cleared = hweight_long(*bm & ~mask);
+		*bm &= mask;
+		w++; bm++;
+	}
+
+	if (w < b->bm_words) {
+		cleared += hweight_long(*bm);
+		*bm = 0;
+	}
+	bm_unmap(p_addr);
+	return cleared;
+}
+
+static void bm_set_surplus(struct drbd_bitmap *b)
+{
+	const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1;
+	size_t w = b->bm_bits >> LN2_BPL;
+	unsigned long *p_addr, *bm;
+
+	p_addr = bm_map_paddr(b, w);
+	bm = p_addr + MLPP(w);
+	if (w < b->bm_words) {
+		*bm |= ~mask;
+		bm++; w++;
+	}
+
+	if (w < b->bm_words) {
+		*bm = ~(0UL);
+	}
+	bm_unmap(p_addr);
+}
+
+static unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endian)
+{
+	unsigned long *p_addr, *bm, offset = 0;
+	unsigned long bits = 0;
+	unsigned long i, do_now;
+
+	while (offset < b->bm_words) {
+		i = do_now = min_t(size_t, b->bm_words-offset, LWPP);
+		p_addr = __bm_map_paddr(b, offset, KM_USER0);
+		bm = p_addr + MLPP(offset);
+		while (i--) {
+#ifndef __LITTLE_ENDIAN
+			if (swap_endian)
+				*bm = lel_to_cpu(*bm);
+#endif
+			bits += hweight_long(*bm++);
+		}
+		__bm_unmap(p_addr, KM_USER0);
+		offset += do_now;
+		cond_resched();
+	}
+
+	return bits;
+}
+
+static unsigned long bm_count_bits(struct drbd_bitmap *b)
+{
+	return __bm_count_bits(b, 0);
+}
+
+static unsigned long bm_count_bits_swap_endian(struct drbd_bitmap *b)
+{
+	return __bm_count_bits(b, 1);
+}
+
+/* offset and len in long words.*/
+static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len)
+{
+	unsigned long *p_addr, *bm;
+	size_t do_now, end;
+
+#define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512)
+
+	end = offset + len;
+
+	if (end > b->bm_words) {
+		printk(KERN_ALERT "drbd: bm_memset end > bm_words\n");
+		return;
+	}
+
+	while (offset < end) {
+		do_now = min_t(size_t, ALIGN(offset + 1, LWPP), end) - offset;
+		p_addr = bm_map_paddr(b, offset);
+		bm = p_addr + MLPP(offset);
+		if (bm+do_now > p_addr + LWPP) {
+			printk(KERN_ALERT "drbd: BUG BUG BUG! p_addr:%p bm:%p do_now:%d\n",
+			       p_addr, bm, (int)do_now);
+			break; /* breaks to after catch_oob_access_end() only! */
+		}
+		memset(bm, c, do_now * sizeof(long));
+		bm_unmap(p_addr);
+		offset += do_now;
+	}
+}
+
+/*
+ * make sure the bitmap has enough room for the attached storage,
+ * if necessary, resize.
+ * called whenever we may have changed the device size.
+ * returns -ENOMEM if we could not allocate enough memory, 0 on success.
+ * In case this is actually a resize, we copy the old bitmap into the new one.
+ * Otherwise, the bitmap is initialized to all bits set.
+ */
+int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long bits, words, owords, obits, *p_addr, *bm;
+	unsigned long want, have, onpages; /* number of pages */
+	struct page **npages, **opages = NULL;
+	int err = 0, growing;
+	int opages_vmalloced;
+
+	ERR_IF(!b) return -ENOMEM;
+
+	drbd_bm_lock(mdev, "resize");
+
+	dev_info(DEV, "drbd_bm_resize called with capacity == %llu\n",
+			(unsigned long long)capacity);
+
+	if (capacity == b->bm_dev_capacity)
+		goto out;
+
+	opages_vmalloced = test_bit(BM_P_VMALLOCED, &b->bm_flags);
+
+	if (capacity == 0) {
+		spin_lock_irq(&b->bm_lock);
+		opages = b->bm_pages;
+		onpages = b->bm_number_of_pages;
+		owords = b->bm_words;
+		b->bm_pages = NULL;
+		b->bm_number_of_pages =
+		b->bm_set   =
+		b->bm_bits  =
+		b->bm_words =
+		b->bm_dev_capacity = 0;
+		spin_unlock_irq(&b->bm_lock);
+		bm_free_pages(opages, onpages);
+		bm_vk_free(opages, opages_vmalloced);
+		goto out;
+	}
+	bits  = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECT_PER_BIT));
+
+	/* if we would use
+	   words = ALIGN(bits,BITS_PER_LONG) >> LN2_BPL;
+	   a 32bit host could present the wrong number of words
+	   to a 64bit host.
+	*/
+	words = ALIGN(bits, 64) >> LN2_BPL;
+
+	if (get_ldev(mdev)) {
+		D_ASSERT((u64)bits <= (((u64)mdev->ldev->md.md_size_sect-MD_BM_OFFSET) << 12));
+		put_ldev(mdev);
+	}
+
+	/* one extra long to catch off by one errors */
+	want = ALIGN((words+1)*sizeof(long), PAGE_SIZE) >> PAGE_SHIFT;
+	have = b->bm_number_of_pages;
+	if (want == have) {
+		D_ASSERT(b->bm_pages != NULL);
+		npages = b->bm_pages;
+	} else {
+		if (FAULT_ACTIVE(mdev, DRBD_FAULT_BM_ALLOC))
+			npages = NULL;
+		else
+			npages = bm_realloc_pages(b, want);
+	}
+
+	if (!npages) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	spin_lock_irq(&b->bm_lock);
+	opages = b->bm_pages;
+	owords = b->bm_words;
+	obits  = b->bm_bits;
+
+	growing = bits > obits;
+	if (opages)
+		bm_set_surplus(b);
+
+	b->bm_pages = npages;
+	b->bm_number_of_pages = want;
+	b->bm_bits  = bits;
+	b->bm_words = words;
+	b->bm_dev_capacity = capacity;
+
+	if (growing) {
+		bm_memset(b, owords, 0xff, words-owords);
+		b->bm_set += bits - obits;
+	}
+
+	if (want < have) {
+		/* implicit: (opages != NULL) && (opages != npages) */
+		bm_free_pages(opages + want, have - want);
+	}
+
+	p_addr = bm_map_paddr(b, words);
+	bm = p_addr + MLPP(words);
+	*bm = DRBD_MAGIC;
+	bm_unmap(p_addr);
+
+	(void)bm_clear_surplus(b);
+
+	spin_unlock_irq(&b->bm_lock);
+	if (opages != npages)
+		bm_vk_free(opages, opages_vmalloced);
+	if (!growing)
+		b->bm_set = bm_count_bits(b);
+	dev_info(DEV, "resync bitmap: bits=%lu words=%lu\n", bits, words);
+
+ out:
+	drbd_bm_unlock(mdev);
+	return err;
+}
+
+/* inherently racy:
+ * if not protected by other means, return value may be out of date when
+ * leaving this function...
+ * we still need to lock it, since it is important that this returns
+ * bm_set == 0 precisely.
+ *
+ * maybe bm_set should be atomic_t ?
+ */
+static unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long s;
+	unsigned long flags;
+
+	ERR_IF(!b) return 0;
+	ERR_IF(!b->bm_pages) return 0;
+
+	spin_lock_irqsave(&b->bm_lock, flags);
+	s = b->bm_set;
+	spin_unlock_irqrestore(&b->bm_lock, flags);
+
+	return s;
+}
+
+unsigned long drbd_bm_total_weight(struct drbd_conf *mdev)
+{
+	unsigned long s;
+	/* if I don't have a disk, I don't know about out-of-sync status */
+	if (!get_ldev_if_state(mdev, D_NEGOTIATING))
+		return 0;
+	s = _drbd_bm_total_weight(mdev);
+	put_ldev(mdev);
+	return s;
+}
+
+size_t drbd_bm_words(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	ERR_IF(!b) return 0;
+	ERR_IF(!b->bm_pages) return 0;
+
+	return b->bm_words;
+}
+
+unsigned long drbd_bm_bits(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	ERR_IF(!b) return 0;
+
+	return b->bm_bits;
+}
+
+/* merge number words from buffer into the bitmap starting at offset.
+ * buffer[i] is expected to be little endian unsigned long.
+ * bitmap must be locked by drbd_bm_lock.
+ * currently only used from receive_bitmap.
+ */
+void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number,
+			unsigned long *buffer)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr, *bm;
+	unsigned long word, bits;
+	size_t end, do_now;
+
+	end = offset + number;
+
+	ERR_IF(!b) return;
+	ERR_IF(!b->bm_pages) return;
+	if (number == 0)
+		return;
+	WARN_ON(offset >= b->bm_words);
+	WARN_ON(end    >  b->bm_words);
+
+	spin_lock_irq(&b->bm_lock);
+	while (offset < end) {
+		do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset;
+		p_addr = bm_map_paddr(b, offset);
+		bm = p_addr + MLPP(offset);
+		offset += do_now;
+		while (do_now--) {
+			bits = hweight_long(*bm);
+			word = *bm | lel_to_cpu(*buffer++);
+			*bm++ = word;
+			b->bm_set += hweight_long(word) - bits;
+		}
+		bm_unmap(p_addr);
+	}
+	/* with 32bit <-> 64bit cross-platform connect
+	 * this is only correct for current usage,
+	 * where we _know_ that we are 64 bit aligned,
+	 * and know that this function is used in this way, too...
+	 */
+	if (end == b->bm_words)
+		b->bm_set -= bm_clear_surplus(b);
+
+	spin_unlock_irq(&b->bm_lock);
+}
+
+/* copy number words from the bitmap starting at offset into the buffer.
+ * buffer[i] will be little endian unsigned long.
+ */
+void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number,
+		     unsigned long *buffer)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr, *bm;
+	size_t end, do_now;
+
+	end = offset + number;
+
+	ERR_IF(!b) return;
+	ERR_IF(!b->bm_pages) return;
+
+	spin_lock_irq(&b->bm_lock);
+	if ((offset >= b->bm_words) ||
+	    (end    >  b->bm_words) ||
+	    (number <= 0))
+		dev_err(DEV, "offset=%lu number=%lu bm_words=%lu\n",
+			(unsigned long)	offset,
+			(unsigned long)	number,
+			(unsigned long) b->bm_words);
+	else {
+		while (offset < end) {
+			do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset;
+			p_addr = bm_map_paddr(b, offset);
+			bm = p_addr + MLPP(offset);
+			offset += do_now;
+			while (do_now--)
+				*buffer++ = cpu_to_lel(*bm++);
+			bm_unmap(p_addr);
+		}
+	}
+	spin_unlock_irq(&b->bm_lock);
+}
+
+/* set all bits in the bitmap */
+void drbd_bm_set_all(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	ERR_IF(!b) return;
+	ERR_IF(!b->bm_pages) return;
+
+	spin_lock_irq(&b->bm_lock);
+	bm_memset(b, 0, 0xff, b->bm_words);
+	(void)bm_clear_surplus(b);
+	b->bm_set = b->bm_bits;
+	spin_unlock_irq(&b->bm_lock);
+}
+
+/* clear all bits in the bitmap */
+void drbd_bm_clear_all(struct drbd_conf *mdev)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	ERR_IF(!b) return;
+	ERR_IF(!b->bm_pages) return;
+
+	spin_lock_irq(&b->bm_lock);
+	bm_memset(b, 0, 0, b->bm_words);
+	b->bm_set = 0;
+	spin_unlock_irq(&b->bm_lock);
+}
+
+static void bm_async_io_complete(struct bio *bio, int error)
+{
+	struct drbd_bitmap *b = bio->bi_private;
+	int uptodate = bio_flagged(bio, BIO_UPTODATE);
+
+
+	/* strange behavior of some lower level drivers...
+	 * fail the request by clearing the uptodate flag,
+	 * but do not return any error?!
+	 * do we want to WARN() on this? */
+	if (!error && !uptodate)
+		error = -EIO;
+
+	if (error) {
+		/* doh. what now?
+		 * for now, set all bits, and flag MD_IO_ERROR */
+		__set_bit(BM_MD_IO_ERROR, &b->bm_flags);
+	}
+	if (atomic_dec_and_test(&b->bm_async_io))
+		wake_up(&b->bm_io_wait);
+
+	bio_put(bio);
+}
+
+static void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int page_nr, int rw) __must_hold(local)
+{
+	/* we are process context. we always get a bio */
+	struct bio *bio = bio_alloc(GFP_KERNEL, 1);
+	unsigned int len;
+	sector_t on_disk_sector =
+		mdev->ldev->md.md_offset + mdev->ldev->md.bm_offset;
+	on_disk_sector += ((sector_t)page_nr) << (PAGE_SHIFT-9);
+
+	/* this might happen with very small
+	 * flexible external meta data device */
+	len = min_t(unsigned int, PAGE_SIZE,
+		(drbd_md_last_sector(mdev->ldev) - on_disk_sector + 1)<<9);
+
+	bio->bi_bdev = mdev->ldev->md_bdev;
+	bio->bi_sector = on_disk_sector;
+	bio_add_page(bio, b->bm_pages[page_nr], len, 0);
+	bio->bi_private = b;
+	bio->bi_end_io = bm_async_io_complete;
+
+	if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
+		bio->bi_rw |= rw;
+		bio_endio(bio, -EIO);
+	} else {
+		submit_bio(rw, bio);
+	}
+}
+
+# if defined(__LITTLE_ENDIAN)
+	/* nothing to do, on disk == in memory */
+# define bm_cpu_to_lel(x) ((void)0)
+# else
+void bm_cpu_to_lel(struct drbd_bitmap *b)
+{
+	/* need to cpu_to_lel all the pages ...
+	 * this may be optimized by using
+	 * cpu_to_lel(-1) == -1 and cpu_to_lel(0) == 0;
+	 * the following is still not optimal, but better than nothing */
+	unsigned int i;
+	unsigned long *p_addr, *bm;
+	if (b->bm_set == 0) {
+		/* no page at all; avoid swap if all is 0 */
+		i = b->bm_number_of_pages;
+	} else if (b->bm_set == b->bm_bits) {
+		/* only the last page */
+		i = b->bm_number_of_pages - 1;
+	} else {
+		/* all pages */
+		i = 0;
+	}
+	for (; i < b->bm_number_of_pages; i++) {
+		p_addr = kmap_atomic(b->bm_pages[i], KM_USER0);
+		for (bm = p_addr; bm < p_addr + PAGE_SIZE/sizeof(long); bm++)
+			*bm = cpu_to_lel(*bm);
+		kunmap_atomic(p_addr, KM_USER0);
+	}
+}
+# endif
+/* lel_to_cpu == cpu_to_lel */
+# define bm_lel_to_cpu(x) bm_cpu_to_lel(x)
+
+/*
+ * bm_rw: read/write the whole bitmap from/to its on disk location.
+ */
+static int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	/* sector_t sector; */
+	int bm_words, num_pages, i;
+	unsigned long now;
+	char ppb[10];
+	int err = 0;
+
+	WARN_ON(!bm_is_locked(b));
+
+	/* no spinlock here, the drbd_bm_lock should be enough! */
+
+	bm_words  = drbd_bm_words(mdev);
+	num_pages = (bm_words*sizeof(long) + PAGE_SIZE-1) >> PAGE_SHIFT;
+
+	/* on disk bitmap is little endian */
+	if (rw == WRITE)
+		bm_cpu_to_lel(b);
+
+	now = jiffies;
+	atomic_set(&b->bm_async_io, num_pages);
+	__clear_bit(BM_MD_IO_ERROR, &b->bm_flags);
+
+	/* let the layers below us try to merge these bios... */
+	for (i = 0; i < num_pages; i++)
+		bm_page_io_async(mdev, b, i, rw);
+
+	drbd_blk_run_queue(bdev_get_queue(mdev->ldev->md_bdev));
+	wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0);
+
+	if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) {
+		dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
+		drbd_chk_io_error(mdev, 1, TRUE);
+		err = -EIO;
+	}
+
+	now = jiffies;
+	if (rw == WRITE) {
+		/* swap back endianness */
+		bm_lel_to_cpu(b);
+		/* flush bitmap to stable storage */
+		drbd_md_flush(mdev);
+	} else /* rw == READ */ {
+		/* just read, if necessary adjust endianness */
+		b->bm_set = bm_count_bits_swap_endian(b);
+		dev_info(DEV, "recounting of set bits took additional %lu jiffies\n",
+		     jiffies - now);
+	}
+	now = b->bm_set;
+
+	dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n",
+	     ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now);
+
+	return err;
+}
+
+/**
+ * drbd_bm_read() - Read the whole bitmap from its on disk location.
+ * @mdev:	DRBD device.
+ */
+int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local)
+{
+	return bm_rw(mdev, READ);
+}
+
+/**
+ * drbd_bm_write() - Write the whole bitmap to its on disk location.
+ * @mdev:	DRBD device.
+ */
+int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)
+{
+	return bm_rw(mdev, WRITE);
+}
+
+/**
+ * drbd_bm_write_sect: Writes a 512 (MD_SECTOR_SIZE) byte piece of the bitmap
+ * @mdev:	DRBD device.
+ * @enr:	Extent number in the resync lru (happens to be sector offset)
+ *
+ * The BM_EXT_SIZE is on purpose exactly the amount of the bitmap covered
+ * by a single sector write. Therefore enr == sector offset from the
+ * start of the bitmap.
+ */
+int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local)
+{
+	sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
+				      + mdev->ldev->md.bm_offset;
+	int bm_words, num_words, offset;
+	int err = 0;
+
+	mutex_lock(&mdev->md_io_mutex);
+	bm_words  = drbd_bm_words(mdev);
+	offset    = S2W(enr);	/* word offset into bitmap */
+	num_words = min(S2W(1), bm_words - offset);
+	if (num_words < S2W(1))
+		memset(page_address(mdev->md_io_page), 0, MD_SECTOR_SIZE);
+	drbd_bm_get_lel(mdev, offset, num_words,
+			page_address(mdev->md_io_page));
+	if (!drbd_md_sync_page_io(mdev, mdev->ldev, on_disk_sector, WRITE)) {
+		int i;
+		err = -EIO;
+		dev_err(DEV, "IO ERROR writing bitmap sector %lu "
+		    "(meta-disk sector %llus)\n",
+		    enr, (unsigned long long)on_disk_sector);
+		drbd_chk_io_error(mdev, 1, TRUE);
+		for (i = 0; i < AL_EXT_PER_BM_SECT; i++)
+			drbd_bm_ALe_set_all(mdev, enr*AL_EXT_PER_BM_SECT+i);
+	}
+	mdev->bm_writ_cnt++;
+	mutex_unlock(&mdev->md_io_mutex);
+	return err;
+}
+
+/* NOTE
+ * find_first_bit returns int, we return unsigned long.
+ * should not make much difference anyways, but ...
+ *
+ * this returns a bit number, NOT a sector!
+ */
+#define BPP_MASK ((1UL << (PAGE_SHIFT+3)) - 1)
+static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo,
+	const int find_zero_bit, const enum km_type km)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long i = -1UL;
+	unsigned long *p_addr;
+	unsigned long bit_offset; /* bit offset of the mapped page. */
+
+	if (bm_fo > b->bm_bits) {
+		dev_err(DEV, "bm_fo=%lu bm_bits=%lu\n", bm_fo, b->bm_bits);
+	} else {
+		while (bm_fo < b->bm_bits) {
+			unsigned long offset;
+			bit_offset = bm_fo & ~BPP_MASK; /* bit offset of the page */
+			offset = bit_offset >> LN2_BPL;    /* word offset of the page */
+			p_addr = __bm_map_paddr(b, offset, km);
+
+			if (find_zero_bit)
+				i = find_next_zero_bit(p_addr, PAGE_SIZE*8, bm_fo & BPP_MASK);
+			else
+				i = find_next_bit(p_addr, PAGE_SIZE*8, bm_fo & BPP_MASK);
+
+			__bm_unmap(p_addr, km);
+			if (i < PAGE_SIZE*8) {
+				i = bit_offset + i;
+				if (i >= b->bm_bits)
+					break;
+				goto found;
+			}
+			bm_fo = bit_offset + PAGE_SIZE*8;
+		}
+		i = -1UL;
+	}
+ found:
+	return i;
+}
+
+static unsigned long bm_find_next(struct drbd_conf *mdev,
+	unsigned long bm_fo, const int find_zero_bit)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long i = -1UL;
+
+	ERR_IF(!b) return i;
+	ERR_IF(!b->bm_pages) return i;
+
+	spin_lock_irq(&b->bm_lock);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+
+	i = __bm_find_next(mdev, bm_fo, find_zero_bit, KM_IRQ1);
+
+	spin_unlock_irq(&b->bm_lock);
+	return i;
+}
+
+unsigned long drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo)
+{
+	return bm_find_next(mdev, bm_fo, 0);
+}
+
+#if 0
+/* not yet needed for anything. */
+unsigned long drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo)
+{
+	return bm_find_next(mdev, bm_fo, 1);
+}
+#endif
+
+/* does not spin_lock_irqsave.
+ * you must take drbd_bm_lock() first */
+unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo)
+{
+	/* WARN_ON(!bm_is_locked(mdev)); */
+	return __bm_find_next(mdev, bm_fo, 0, KM_USER1);
+}
+
+unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo)
+{
+	/* WARN_ON(!bm_is_locked(mdev)); */
+	return __bm_find_next(mdev, bm_fo, 1, KM_USER1);
+}
+
+/* returns number of bits actually changed.
+ * for val != 0, we change 0 -> 1, return code positive
+ * for val == 0, we change 1 -> 0, return code negative
+ * wants bitnr, not sector.
+ * expected to be called for only a few bits (e - s about BITS_PER_LONG).
+ * Must hold bitmap lock already. */
+int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
+	unsigned long e, int val, const enum km_type km)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr = NULL;
+	unsigned long bitnr;
+	unsigned long last_page_nr = -1UL;
+	int c = 0;
+
+	if (e >= b->bm_bits) {
+		dev_err(DEV, "ASSERT FAILED: bit_s=%lu bit_e=%lu bm_bits=%lu\n",
+				s, e, b->bm_bits);
+		e = b->bm_bits ? b->bm_bits -1 : 0;
+	}
+	for (bitnr = s; bitnr <= e; bitnr++) {
+		unsigned long offset = bitnr>>LN2_BPL;
+		unsigned long page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3);
+		if (page_nr != last_page_nr) {
+			if (p_addr)
+				__bm_unmap(p_addr, km);
+			p_addr = __bm_map_paddr(b, offset, km);
+			last_page_nr = page_nr;
+		}
+		if (val)
+			c += (0 == __test_and_set_bit(bitnr & BPP_MASK, p_addr));
+		else
+			c -= (0 != __test_and_clear_bit(bitnr & BPP_MASK, p_addr));
+	}
+	if (p_addr)
+		__bm_unmap(p_addr, km);
+	b->bm_set += c;
+	return c;
+}
+
+/* returns number of bits actually changed.
+ * for val != 0, we change 0 -> 1, return code positive
+ * for val == 0, we change 1 -> 0, return code negative
+ * wants bitnr, not sector */
+int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
+	const unsigned long e, int val)
+{
+	unsigned long flags;
+	struct drbd_bitmap *b = mdev->bitmap;
+	int c = 0;
+
+	ERR_IF(!b) return 1;
+	ERR_IF(!b->bm_pages) return 0;
+
+	spin_lock_irqsave(&b->bm_lock, flags);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+
+	c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1);
+
+	spin_unlock_irqrestore(&b->bm_lock, flags);
+	return c;
+}
+
+/* returns number of bits changed 0 -> 1 */
+int drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e)
+{
+	return bm_change_bits_to(mdev, s, e, 1);
+}
+
+/* returns number of bits changed 1 -> 0 */
+int drbd_bm_clear_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e)
+{
+	return -bm_change_bits_to(mdev, s, e, 0);
+}
+
+/* sets all bits in full words,
+ * from first_word up to, but not including, last_word */
+static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b,
+		int page_nr, int first_word, int last_word)
+{
+	int i;
+	int bits;
+	unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0);
+	for (i = first_word; i < last_word; i++) {
+		bits = hweight_long(paddr[i]);
+		paddr[i] = ~0UL;
+		b->bm_set += BITS_PER_LONG - bits;
+	}
+	kunmap_atomic(paddr, KM_USER0);
+}
+
+/* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave.
+ * You must first drbd_bm_lock().
+ * Can be called to set the whole bitmap in one go.
+ * Sets bits from s to e _inclusive_. */
+void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e)
+{
+	/* First set_bit from the first bit (s)
+	 * up to the next long boundary (sl),
+	 * then assign full words up to the last long boundary (el),
+	 * then set_bit up to and including the last bit (e).
+	 *
+	 * Do not use memset, because we must account for changes,
+	 * so we need to loop over the words with hweight() anyways.
+	 */
+	unsigned long sl = ALIGN(s,BITS_PER_LONG);
+	unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1);
+	int first_page;
+	int last_page;
+	int page_nr;
+	int first_word;
+	int last_word;
+
+	if (e - s <= 3*BITS_PER_LONG) {
+		/* don't bother; el and sl may even be wrong. */
+		__bm_change_bits_to(mdev, s, e, 1, KM_USER0);
+		return;
+	}
+
+	/* difference is large enough that we can trust sl and el */
+
+	/* bits filling the current long */
+	if (sl)
+		__bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0);
+
+	first_page = sl >> (3 + PAGE_SHIFT);
+	last_page = el >> (3 + PAGE_SHIFT);
+
+	/* MLPP: modulo longs per page */
+	/* LWPP: long words per page */
+	first_word = MLPP(sl >> LN2_BPL);
+	last_word = LWPP;
+
+	/* first and full pages, unless first page == last page */
+	for (page_nr = first_page; page_nr < last_page; page_nr++) {
+		bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word);
+		cond_resched();
+		first_word = 0;
+	}
+
+	/* last page (respectively only page, for first page == last page) */
+	last_word = MLPP(el >> LN2_BPL);
+	bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word);
+
+	/* possibly trailing bits.
+	 * example: (e & 63) == 63, el will be e+1.
+	 * if that even was the very last bit,
+	 * it would trigger an assert in __bm_change_bits_to()
+	 */
+	if (el <= e)
+		__bm_change_bits_to(mdev, el, e, 1, KM_USER0);
+}
+
+/* returns bit state
+ * wants bitnr, NOT sector.
+ * inherently racy... area needs to be locked by means of {al,rs}_lru
+ *  1 ... bit set
+ *  0 ... bit not set
+ * -1 ... first out of bounds access, stop testing for bits!
+ */
+int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr)
+{
+	unsigned long flags;
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr;
+	int i;
+
+	ERR_IF(!b) return 0;
+	ERR_IF(!b->bm_pages) return 0;
+
+	spin_lock_irqsave(&b->bm_lock, flags);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+	if (bitnr < b->bm_bits) {
+		unsigned long offset = bitnr>>LN2_BPL;
+		p_addr = bm_map_paddr(b, offset);
+		i = test_bit(bitnr & BPP_MASK, p_addr) ? 1 : 0;
+		bm_unmap(p_addr);
+	} else if (bitnr == b->bm_bits) {
+		i = -1;
+	} else { /* (bitnr > b->bm_bits) */
+		dev_err(DEV, "bitnr=%lu > bm_bits=%lu\n", bitnr, b->bm_bits);
+		i = 0;
+	}
+
+	spin_unlock_irqrestore(&b->bm_lock, flags);
+	return i;
+}
+
+/* returns number of bits set in the range [s, e] */
+int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e)
+{
+	unsigned long flags;
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr = NULL, page_nr = -1;
+	unsigned long bitnr;
+	int c = 0;
+	size_t w;
+
+	/* If this is called without a bitmap, that is a bug.  But just to be
+	 * robust in case we screwed up elsewhere, in that case pretend there
+	 * was one dirty bit in the requested area, so we won't try to do a
+	 * local read there (no bitmap probably implies no disk) */
+	ERR_IF(!b) return 1;
+	ERR_IF(!b->bm_pages) return 1;
+
+	spin_lock_irqsave(&b->bm_lock, flags);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+	for (bitnr = s; bitnr <= e; bitnr++) {
+		w = bitnr >> LN2_BPL;
+		if (page_nr != w >> (PAGE_SHIFT - LN2_BPL + 3)) {
+			page_nr = w >> (PAGE_SHIFT - LN2_BPL + 3);
+			if (p_addr)
+				bm_unmap(p_addr);
+			p_addr = bm_map_paddr(b, w);
+		}
+		ERR_IF (bitnr >= b->bm_bits) {
+			dev_err(DEV, "bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits);
+		} else {
+			c += (0 != test_bit(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr));
+		}
+	}
+	if (p_addr)
+		bm_unmap(p_addr);
+	spin_unlock_irqrestore(&b->bm_lock, flags);
+	return c;
+}
+
+
+/* inherently racy...
+ * return value may be already out-of-date when this function returns.
+ * but the general usage is that this is only use during a cstate when bits are
+ * only cleared, not set, and typically only care for the case when the return
+ * value is zero, or we already "locked" this "bitmap extent" by other means.
+ *
+ * enr is bm-extent number, since we chose to name one sector (512 bytes)
+ * worth of the bitmap a "bitmap extent".
+ *
+ * TODO
+ * I think since we use it like a reference count, we should use the real
+ * reference count of some bitmap extent element from some lru instead...
+ *
+ */
+int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	int count, s, e;
+	unsigned long flags;
+	unsigned long *p_addr, *bm;
+
+	ERR_IF(!b) return 0;
+	ERR_IF(!b->bm_pages) return 0;
+
+	spin_lock_irqsave(&b->bm_lock, flags);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+
+	s = S2W(enr);
+	e = min((size_t)S2W(enr+1), b->bm_words);
+	count = 0;
+	if (s < b->bm_words) {
+		int n = e-s;
+		p_addr = bm_map_paddr(b, s);
+		bm = p_addr + MLPP(s);
+		while (n--)
+			count += hweight_long(*bm++);
+		bm_unmap(p_addr);
+	} else {
+		dev_err(DEV, "start offset (%d) too large in drbd_bm_e_weight\n", s);
+	}
+	spin_unlock_irqrestore(&b->bm_lock, flags);
+	return count;
+}
+
+/* set all bits covered by the AL-extent al_enr */
+unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr)
+{
+	struct drbd_bitmap *b = mdev->bitmap;
+	unsigned long *p_addr, *bm;
+	unsigned long weight;
+	int count, s, e, i, do_now;
+	ERR_IF(!b) return 0;
+	ERR_IF(!b->bm_pages) return 0;
+
+	spin_lock_irq(&b->bm_lock);
+	if (bm_is_locked(b))
+		bm_print_lock_info(mdev);
+	weight = b->bm_set;
+
+	s = al_enr * BM_WORDS_PER_AL_EXT;
+	e = min_t(size_t, s + BM_WORDS_PER_AL_EXT, b->bm_words);
+	/* assert that s and e are on the same page */
+	D_ASSERT((e-1) >> (PAGE_SHIFT - LN2_BPL + 3)
+	      ==  s    >> (PAGE_SHIFT - LN2_BPL + 3));
+	count = 0;
+	if (s < b->bm_words) {
+		i = do_now = e-s;
+		p_addr = bm_map_paddr(b, s);
+		bm = p_addr + MLPP(s);
+		while (i--) {
+			count += hweight_long(*bm);
+			*bm = -1UL;
+			bm++;
+		}
+		bm_unmap(p_addr);
+		b->bm_set += do_now*BITS_PER_LONG - count;
+		if (e == b->bm_words)
+			b->bm_set -= bm_clear_surplus(b);
+	} else {
+		dev_err(DEV, "start offset (%d) too large in drbd_bm_ALe_set_all\n", s);
+	}
+	weight = b->bm_set - weight;
+	spin_unlock_irq(&b->bm_lock);
+	return weight;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_int.h linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_int.h
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_int.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_int.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2251 @@
+/*
+  drbd_int.h
+
+  This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+  Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+  Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+  Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+  drbd 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.
+
+  drbd is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with drbd; see the file COPYING.  If not, write to
+  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _DRBD_INT_H
+#define _DRBD_INT_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/crypto.h>
+#include <linux/ratelimit.h>
+#include <linux/tcp.h>
+#include <linux/mutex.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
+#include <net/tcp.h>
+#include <linux/lru_cache.h>
+
+#ifdef __CHECKER__
+# define __protected_by(x)       __attribute__((require_context(x,1,999,"rdwr")))
+# define __protected_read_by(x)  __attribute__((require_context(x,1,999,"read")))
+# define __protected_write_by(x) __attribute__((require_context(x,1,999,"write")))
+# define __must_hold(x)       __attribute__((context(x,1,1), require_context(x,1,999,"call")))
+#else
+# define __protected_by(x)
+# define __protected_read_by(x)
+# define __protected_write_by(x)
+# define __must_hold(x)
+#endif
+
+#define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0)
+
+/* module parameter, defined in drbd_main.c */
+extern unsigned int minor_count;
+extern int disable_sendpage;
+extern int allow_oos;
+extern unsigned int cn_idx;
+
+#ifdef CONFIG_DRBD_FAULT_INJECTION
+extern int enable_faults;
+extern int fault_rate;
+extern int fault_devs;
+#endif
+
+extern char usermode_helper[];
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* I don't remember why XCPU ...
+ * This is used to wake the asender,
+ * and to interrupt sending the sending task
+ * on disconnect.
+ */
+#define DRBD_SIG SIGXCPU
+
+/* This is used to stop/restart our threads.
+ * Cannot use SIGTERM nor SIGKILL, since these
+ * are sent out by init on runlevel changes
+ * I choose SIGHUP for now.
+ */
+#define DRBD_SIGKILL SIGHUP
+
+/* All EEs on the free list should have ID_VACANT (== 0)
+ * freshly allocated EEs get !ID_VACANT (== 1)
+ * so if it says "cannot dereference null pointer at adress 0x00000001",
+ * it is most likely one of these :( */
+
+#define ID_IN_SYNC      (4711ULL)
+#define ID_OUT_OF_SYNC  (4712ULL)
+
+#define ID_SYNCER (-1ULL)
+#define ID_VACANT 0
+#define is_syncer_block_id(id) ((id) == ID_SYNCER)
+
+struct drbd_conf;
+
+
+/* to shorten dev_warn(DEV, "msg"); and relatives statements */
+#define DEV (disk_to_dev(mdev->vdisk))
+
+#define D_ASSERT(exp)	if (!(exp)) \
+	 dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__)
+
+#define ERR_IF(exp) if (({				\
+	int _b = (exp) != 0;				\
+	if (_b) dev_err(DEV, "%s: (%s) in %s:%d\n",	\
+		__func__, #exp, __FILE__, __LINE__);	\
+	 _b;						\
+	}))
+
+/* Defines to control fault insertion */
+enum {
+	DRBD_FAULT_MD_WR = 0,	/* meta data write */
+	DRBD_FAULT_MD_RD = 1,	/*           read  */
+	DRBD_FAULT_RS_WR = 2,	/* resync          */
+	DRBD_FAULT_RS_RD = 3,
+	DRBD_FAULT_DT_WR = 4,	/* data            */
+	DRBD_FAULT_DT_RD = 5,
+	DRBD_FAULT_DT_RA = 6,	/* data read ahead */
+	DRBD_FAULT_BM_ALLOC = 7,	/* bitmap allocation */
+	DRBD_FAULT_AL_EE = 8,	/* alloc ee */
+
+	DRBD_FAULT_MAX,
+};
+
+#ifdef CONFIG_DRBD_FAULT_INJECTION
+extern unsigned int
+_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type);
+static inline int
+drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) {
+	return fault_rate &&
+		(enable_faults & (1<<type)) &&
+		_drbd_insert_fault(mdev, type);
+}
+#define FAULT_ACTIVE(_m, _t) (drbd_insert_fault((_m), (_t)))
+
+#else
+#define FAULT_ACTIVE(_m, _t) (0)
+#endif
+
+/* integer division, round _UP_ to the next integer */
+#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0))
+/* usual integer division */
+#define div_floor(A, B) ((A)/(B))
+
+/* drbd_meta-data.c (still in drbd_main.c) */
+/* 4th incarnation of the disk layout. */
+#define DRBD_MD_MAGIC (DRBD_MAGIC+4)
+
+extern struct drbd_conf **minor_table;
+extern struct ratelimit_state drbd_ratelimit_state;
+
+/* on the wire */
+enum drbd_packets {
+	/* receiver (data socket) */
+	P_DATA		      = 0x00,
+	P_DATA_REPLY	      = 0x01, /* Response to P_DATA_REQUEST */
+	P_RS_DATA_REPLY	      = 0x02, /* Response to P_RS_DATA_REQUEST */
+	P_BARRIER	      = 0x03,
+	P_BITMAP	      = 0x04,
+	P_BECOME_SYNC_TARGET  = 0x05,
+	P_BECOME_SYNC_SOURCE  = 0x06,
+	P_UNPLUG_REMOTE	      = 0x07, /* Used at various times to hint the peer */
+	P_DATA_REQUEST	      = 0x08, /* Used to ask for a data block */
+	P_RS_DATA_REQUEST     = 0x09, /* Used to ask for a data block for resync */
+	P_SYNC_PARAM	      = 0x0a,
+	P_PROTOCOL	      = 0x0b,
+	P_UUIDS		      = 0x0c,
+	P_SIZES		      = 0x0d,
+	P_STATE		      = 0x0e,
+	P_SYNC_UUID	      = 0x0f,
+	P_AUTH_CHALLENGE      = 0x10,
+	P_AUTH_RESPONSE	      = 0x11,
+	P_STATE_CHG_REQ	      = 0x12,
+
+	/* asender (meta socket */
+	P_PING		      = 0x13,
+	P_PING_ACK	      = 0x14,
+	P_RECV_ACK	      = 0x15, /* Used in protocol B */
+	P_WRITE_ACK	      = 0x16, /* Used in protocol C */
+	P_RS_WRITE_ACK	      = 0x17, /* Is a P_WRITE_ACK, additionally call set_in_sync(). */
+	P_DISCARD_ACK	      = 0x18, /* Used in proto C, two-primaries conflict detection */
+	P_NEG_ACK	      = 0x19, /* Sent if local disk is unusable */
+	P_NEG_DREPLY	      = 0x1a, /* Local disk is broken... */
+	P_NEG_RS_DREPLY	      = 0x1b, /* Local disk is broken... */
+	P_BARRIER_ACK	      = 0x1c,
+	P_STATE_CHG_REPLY     = 0x1d,
+
+	/* "new" commands, no longer fitting into the ordering scheme above */
+
+	P_OV_REQUEST	      = 0x1e, /* data socket */
+	P_OV_REPLY	      = 0x1f,
+	P_OV_RESULT	      = 0x20, /* meta socket */
+	P_CSUM_RS_REQUEST     = 0x21, /* data socket */
+	P_RS_IS_IN_SYNC	      = 0x22, /* meta socket */
+	P_SYNC_PARAM89	      = 0x23, /* data socket, protocol version 89 replacement for P_SYNC_PARAM */
+	P_COMPRESSED_BITMAP   = 0x24, /* compressed or otherwise encoded bitmap transfer */
+
+	P_MAX_CMD	      = 0x25,
+	P_MAY_IGNORE	      = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */
+	P_MAX_OPT_CMD	      = 0x101,
+
+	/* special command ids for handshake */
+
+	P_HAND_SHAKE_M	      = 0xfff1, /* First Packet on the MetaSock */
+	P_HAND_SHAKE_S	      = 0xfff2, /* First Packet on the Socket */
+
+	P_HAND_SHAKE	      = 0xfffe	/* FIXED for the next century! */
+};
+
+static inline const char *cmdname(enum drbd_packets cmd)
+{
+	/* THINK may need to become several global tables
+	 * when we want to support more than
+	 * one PRO_VERSION */
+	static const char *cmdnames[] = {
+		[P_DATA]	        = "Data",
+		[P_DATA_REPLY]	        = "DataReply",
+		[P_RS_DATA_REPLY]	= "RSDataReply",
+		[P_BARRIER]	        = "Barrier",
+		[P_BITMAP]	        = "ReportBitMap",
+		[P_BECOME_SYNC_TARGET]  = "BecomeSyncTarget",
+		[P_BECOME_SYNC_SOURCE]  = "BecomeSyncSource",
+		[P_UNPLUG_REMOTE]	= "UnplugRemote",
+		[P_DATA_REQUEST]	= "DataRequest",
+		[P_RS_DATA_REQUEST]     = "RSDataRequest",
+		[P_SYNC_PARAM]	        = "SyncParam",
+		[P_SYNC_PARAM89]	= "SyncParam89",
+		[P_PROTOCOL]            = "ReportProtocol",
+		[P_UUIDS]	        = "ReportUUIDs",
+		[P_SIZES]	        = "ReportSizes",
+		[P_STATE]	        = "ReportState",
+		[P_SYNC_UUID]           = "ReportSyncUUID",
+		[P_AUTH_CHALLENGE]      = "AuthChallenge",
+		[P_AUTH_RESPONSE]	= "AuthResponse",
+		[P_PING]		= "Ping",
+		[P_PING_ACK]	        = "PingAck",
+		[P_RECV_ACK]	        = "RecvAck",
+		[P_WRITE_ACK]	        = "WriteAck",
+		[P_RS_WRITE_ACK]	= "RSWriteAck",
+		[P_DISCARD_ACK]	        = "DiscardAck",
+		[P_NEG_ACK]	        = "NegAck",
+		[P_NEG_DREPLY]	        = "NegDReply",
+		[P_NEG_RS_DREPLY]	= "NegRSDReply",
+		[P_BARRIER_ACK]	        = "BarrierAck",
+		[P_STATE_CHG_REQ]       = "StateChgRequest",
+		[P_STATE_CHG_REPLY]     = "StateChgReply",
+		[P_OV_REQUEST]          = "OVRequest",
+		[P_OV_REPLY]            = "OVReply",
+		[P_OV_RESULT]           = "OVResult",
+		[P_MAX_CMD]	        = NULL,
+	};
+
+	if (cmd == P_HAND_SHAKE_M)
+		return "HandShakeM";
+	if (cmd == P_HAND_SHAKE_S)
+		return "HandShakeS";
+	if (cmd == P_HAND_SHAKE)
+		return "HandShake";
+	if (cmd >= P_MAX_CMD)
+		return "Unknown";
+	return cmdnames[cmd];
+}
+
+/* for sending/receiving the bitmap,
+ * possibly in some encoding scheme */
+struct bm_xfer_ctx {
+	/* "const"
+	 * stores total bits and long words
+	 * of the bitmap, so we don't need to
+	 * call the accessor functions over and again. */
+	unsigned long bm_bits;
+	unsigned long bm_words;
+	/* during xfer, current position within the bitmap */
+	unsigned long bit_offset;
+	unsigned long word_offset;
+
+	/* statistics; index: (h->command == P_BITMAP) */
+	unsigned packets[2];
+	unsigned bytes[2];
+};
+
+extern void INFO_bm_xfer_stats(struct drbd_conf *mdev,
+		const char *direction, struct bm_xfer_ctx *c);
+
+static inline void bm_xfer_ctx_bit_to_word_offset(struct bm_xfer_ctx *c)
+{
+	/* word_offset counts "native long words" (32 or 64 bit),
+	 * aligned at 64 bit.
+	 * Encoded packet may end at an unaligned bit offset.
+	 * In case a fallback clear text packet is transmitted in
+	 * between, we adjust this offset back to the last 64bit
+	 * aligned "native long word", which makes coding and decoding
+	 * the plain text bitmap much more convenient.  */
+#if BITS_PER_LONG == 64
+	c->word_offset = c->bit_offset >> 6;
+#elif BITS_PER_LONG == 32
+	c->word_offset = c->bit_offset >> 5;
+	c->word_offset &= ~(1UL);
+#else
+# error "unsupported BITS_PER_LONG"
+#endif
+}
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+/* This is the layout for a packet on the wire.
+ * The byteorder is the network byte order.
+ *     (except block_id and barrier fields.
+ *	these are pointers to local structs
+ *	and have no relevance for the partner,
+ *	which just echoes them as received.)
+ *
+ * NOTE that the payload starts at a long aligned offset,
+ * regardless of 32 or 64 bit arch!
+ */
+struct p_header {
+	u32	  magic;
+	u16	  command;
+	u16	  length;	/* bytes of data after this header */
+	u8	  payload[0];
+} __packed;
+/* 8 bytes. packet FIXED for the next century! */
+
+/*
+ * short commands, packets without payload, plain p_header:
+ *   P_PING
+ *   P_PING_ACK
+ *   P_BECOME_SYNC_TARGET
+ *   P_BECOME_SYNC_SOURCE
+ *   P_UNPLUG_REMOTE
+ */
+
+/*
+ * commands with out-of-struct payload:
+ *   P_BITMAP    (no additional fields)
+ *   P_DATA, P_DATA_REPLY (see p_data)
+ *   P_COMPRESSED_BITMAP (see receive_compressed_bitmap)
+ */
+
+/* these defines must not be changed without changing the protocol version */
+#define DP_HARDBARRIER	      1
+#define DP_RW_SYNC	      2
+#define DP_MAY_SET_IN_SYNC    4
+
+struct p_data {
+	struct p_header head;
+	u64	    sector;    /* 64 bits sector number */
+	u64	    block_id;  /* to identify the request in protocol B&C */
+	u32	    seq_num;
+	u32	    dp_flags;
+} __packed;
+
+/*
+ * commands which share a struct:
+ *  p_block_ack:
+ *   P_RECV_ACK (proto B), P_WRITE_ACK (proto C),
+ *   P_DISCARD_ACK (proto C, two-primaries conflict detection)
+ *  p_block_req:
+ *   P_DATA_REQUEST, P_RS_DATA_REQUEST
+ */
+struct p_block_ack {
+	struct p_header head;
+	u64	    sector;
+	u64	    block_id;
+	u32	    blksize;
+	u32	    seq_num;
+} __packed;
+
+
+struct p_block_req {
+	struct p_header head;
+	u64 sector;
+	u64 block_id;
+	u32 blksize;
+	u32 pad;	/* to multiple of 8 Byte */
+} __packed;
+
+/*
+ * commands with their own struct for additional fields:
+ *   P_HAND_SHAKE
+ *   P_BARRIER
+ *   P_BARRIER_ACK
+ *   P_SYNC_PARAM
+ *   ReportParams
+ */
+
+struct p_handshake {
+	struct p_header head;	/* 8 bytes */
+	u32 protocol_min;
+	u32 feature_flags;
+	u32 protocol_max;
+
+	/* should be more than enough for future enhancements
+	 * for now, feature_flags and the reserverd array shall be zero.
+	 */
+
+	u32 _pad;
+	u64 reserverd[7];
+} __packed;
+/* 80 bytes, FIXED for the next century */
+
+struct p_barrier {
+	struct p_header head;
+	u32 barrier;	/* barrier number _handle_ only */
+	u32 pad;	/* to multiple of 8 Byte */
+} __packed;
+
+struct p_barrier_ack {
+	struct p_header head;
+	u32 barrier;
+	u32 set_size;
+} __packed;
+
+struct p_rs_param {
+	struct p_header head;
+	u32 rate;
+
+	      /* Since protocol version 88 and higher. */
+	char verify_alg[0];
+} __packed;
+
+struct p_rs_param_89 {
+	struct p_header head;
+	u32 rate;
+        /* protocol version 89: */
+	char verify_alg[SHARED_SECRET_MAX];
+	char csums_alg[SHARED_SECRET_MAX];
+} __packed;
+
+struct p_protocol {
+	struct p_header head;
+	u32 protocol;
+	u32 after_sb_0p;
+	u32 after_sb_1p;
+	u32 after_sb_2p;
+	u32 want_lose;
+	u32 two_primaries;
+
+              /* Since protocol version 87 and higher. */
+	char integrity_alg[0];
+
+} __packed;
+
+struct p_uuids {
+	struct p_header head;
+	u64 uuid[UI_EXTENDED_SIZE];
+} __packed;
+
+struct p_rs_uuid {
+	struct p_header head;
+	u64	    uuid;
+} __packed;
+
+struct p_sizes {
+	struct p_header head;
+	u64	    d_size;  /* size of disk */
+	u64	    u_size;  /* user requested size */
+	u64	    c_size;  /* current exported size */
+	u32	    max_segment_size;  /* Maximal size of a BIO */
+	u32	    queue_order_type;
+} __packed;
+
+struct p_state {
+	struct p_header head;
+	u32	    state;
+} __packed;
+
+struct p_req_state {
+	struct p_header head;
+	u32	    mask;
+	u32	    val;
+} __packed;
+
+struct p_req_state_reply {
+	struct p_header head;
+	u32	    retcode;
+} __packed;
+
+struct p_drbd06_param {
+	u64	  size;
+	u32	  state;
+	u32	  blksize;
+	u32	  protocol;
+	u32	  version;
+	u32	  gen_cnt[5];
+	u32	  bit_map_gen[5];
+} __packed;
+
+struct p_discard {
+	struct p_header head;
+	u64	    block_id;
+	u32	    seq_num;
+	u32	    pad;
+} __packed;
+
+/* Valid values for the encoding field.
+ * Bump proto version when changing this. */
+enum drbd_bitmap_code {
+	/* RLE_VLI_Bytes = 0,
+	 * and other bit variants had been defined during
+	 * algorithm evaluation. */
+	RLE_VLI_Bits = 2,
+};
+
+struct p_compressed_bm {
+	struct p_header head;
+	/* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code
+	 * (encoding & 0x80): polarity (set/unset) of first runlength
+	 * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits
+	 * used to pad up to head.length bytes
+	 */
+	u8 encoding;
+
+	u8 code[0];
+} __packed;
+
+/* DCBP: Drbd Compressed Bitmap Packet ... */
+static inline enum drbd_bitmap_code
+DCBP_get_code(struct p_compressed_bm *p)
+{
+	return (enum drbd_bitmap_code)(p->encoding & 0x0f);
+}
+
+static inline void
+DCBP_set_code(struct p_compressed_bm *p, enum drbd_bitmap_code code)
+{
+	BUG_ON(code & ~0xf);
+	p->encoding = (p->encoding & ~0xf) | code;
+}
+
+static inline int
+DCBP_get_start(struct p_compressed_bm *p)
+{
+	return (p->encoding & 0x80) != 0;
+}
+
+static inline void
+DCBP_set_start(struct p_compressed_bm *p, int set)
+{
+	p->encoding = (p->encoding & ~0x80) | (set ? 0x80 : 0);
+}
+
+static inline int
+DCBP_get_pad_bits(struct p_compressed_bm *p)
+{
+	return (p->encoding >> 4) & 0x7;
+}
+
+static inline void
+DCBP_set_pad_bits(struct p_compressed_bm *p, int n)
+{
+	BUG_ON(n & ~0x7);
+	p->encoding = (p->encoding & (~0x7 << 4)) | (n << 4);
+}
+
+/* one bitmap packet, including the p_header,
+ * should fit within one _architecture independend_ page.
+ * so we need to use the fixed size 4KiB page size
+ * most architechtures have used for a long time.
+ */
+#define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header))
+#define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long))
+#define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm))
+#if (PAGE_SIZE < 4096)
+/* drbd_send_bitmap / receive_bitmap would break horribly */
+#error "PAGE_SIZE too small"
+#endif
+
+union p_polymorph {
+        struct p_header          header;
+        struct p_handshake       handshake;
+        struct p_data            data;
+        struct p_block_ack       block_ack;
+        struct p_barrier         barrier;
+        struct p_barrier_ack     barrier_ack;
+        struct p_rs_param_89     rs_param_89;
+        struct p_protocol        protocol;
+        struct p_sizes           sizes;
+        struct p_uuids           uuids;
+        struct p_state           state;
+        struct p_req_state       req_state;
+        struct p_req_state_reply req_state_reply;
+        struct p_block_req       block_req;
+} __packed;
+
+/**********************************************************************/
+enum drbd_thread_state {
+	None,
+	Running,
+	Exiting,
+	Restarting
+};
+
+struct drbd_thread {
+	spinlock_t t_lock;
+	struct task_struct *task;
+	struct completion stop;
+	enum drbd_thread_state t_state;
+	int (*function) (struct drbd_thread *);
+	struct drbd_conf *mdev;
+	int reset_cpu_mask;
+};
+
+static inline enum drbd_thread_state get_t_state(struct drbd_thread *thi)
+{
+	/* THINK testing the t_state seems to be uncritical in all cases
+	 * (but thread_{start,stop}), so we can read it *without* the lock.
+	 *	--lge */
+
+	smp_rmb();
+	return thi->t_state;
+}
+
+
+/*
+ * Having this as the first member of a struct provides sort of "inheritance".
+ * "derived" structs can be "drbd_queue_work()"ed.
+ * The callback should know and cast back to the descendant struct.
+ * drbd_request and drbd_epoch_entry are descendants of drbd_work.
+ */
+struct drbd_work;
+typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel);
+struct drbd_work {
+	struct list_head list;
+	drbd_work_cb cb;
+};
+
+struct drbd_tl_epoch;
+struct drbd_request {
+	struct drbd_work w;
+	struct drbd_conf *mdev;
+
+	/* if local IO is not allowed, will be NULL.
+	 * if local IO _is_ allowed, holds the locally submitted bio clone,
+	 * or, after local IO completion, the ERR_PTR(error).
+	 * see drbd_endio_pri(). */
+	struct bio *private_bio;
+
+	struct hlist_node colision;
+	sector_t sector;
+	unsigned int size;
+	unsigned int epoch; /* barrier_nr */
+
+	/* barrier_nr: used to check on "completion" whether this req was in
+	 * the current epoch, and we therefore have to close it,
+	 * starting a new epoch...
+	 */
+
+	/* up to here, the struct layout is identical to drbd_epoch_entry;
+	 * we might be able to use that to our advantage...  */
+
+	struct list_head tl_requests; /* ring list in the transfer log */
+	struct bio *master_bio;       /* master bio pointer */
+	unsigned long rq_state; /* see comments above _req_mod() */
+	int seq_num;
+	unsigned long start_time;
+};
+
+struct drbd_tl_epoch {
+	struct drbd_work w;
+	struct list_head requests; /* requests before */
+	struct drbd_tl_epoch *next; /* pointer to the next barrier */
+	unsigned int br_number;  /* the barriers identifier. */
+	int n_req;	/* number of requests attached before this barrier */
+};
+
+struct drbd_request;
+
+/* These Tl_epoch_entries may be in one of 6 lists:
+   active_ee .. data packet being written
+   sync_ee   .. syncer block being written
+   done_ee   .. block written, need to send P_WRITE_ACK
+   read_ee   .. [RS]P_DATA_REQUEST being read
+*/
+
+struct drbd_epoch {
+	struct list_head list;
+	unsigned int barrier_nr;
+	atomic_t epoch_size; /* increased on every request added. */
+	atomic_t active;     /* increased on every req. added, and dec on every finished. */
+	unsigned long flags;
+};
+
+/* drbd_epoch flag bits */
+enum {
+	DE_BARRIER_IN_NEXT_EPOCH_ISSUED,
+	DE_BARRIER_IN_NEXT_EPOCH_DONE,
+	DE_CONTAINS_A_BARRIER,
+	DE_HAVE_BARRIER_NUMBER,
+	DE_IS_FINISHING,
+};
+
+enum epoch_event {
+	EV_PUT,
+	EV_GOT_BARRIER_NR,
+	EV_BARRIER_DONE,
+	EV_BECAME_LAST,
+	EV_CLEANUP = 32, /* used as flag */
+};
+
+struct drbd_epoch_entry {
+	struct drbd_work    w;
+	struct drbd_conf *mdev;
+	struct bio *private_bio;
+	struct hlist_node colision;
+	sector_t sector;
+	unsigned int size;
+	struct drbd_epoch *epoch;
+
+	/* up to here, the struct layout is identical to drbd_request;
+	 * we might be able to use that to our advantage...  */
+
+	unsigned int flags;
+	u64    block_id;
+};
+
+struct drbd_wq_barrier {
+	struct drbd_work w;
+	struct completion done;
+};
+
+struct digest_info {
+	int digest_size;
+	void *digest;
+};
+
+/* ee flag bits */
+enum {
+	__EE_CALL_AL_COMPLETE_IO,
+	__EE_CONFLICT_PENDING,
+	__EE_MAY_SET_IN_SYNC,
+	__EE_IS_BARRIER,
+};
+#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
+#define EE_CONFLICT_PENDING    (1<<__EE_CONFLICT_PENDING)
+#define EE_MAY_SET_IN_SYNC     (1<<__EE_MAY_SET_IN_SYNC)
+#define EE_IS_BARRIER          (1<<__EE_IS_BARRIER)
+
+/* global flag bits */
+enum {
+	CREATE_BARRIER,		/* next P_DATA is preceeded by a P_BARRIER */
+	SIGNAL_ASENDER,		/* whether asender wants to be interrupted */
+	SEND_PING,		/* whether asender should send a ping asap */
+
+	STOP_SYNC_TIMER,	/* tell timer to cancel itself */
+	UNPLUG_QUEUED,		/* only relevant with kernel 2.4 */
+	UNPLUG_REMOTE,		/* sending a "UnplugRemote" could help */
+	MD_DIRTY,		/* current uuids and flags not yet on disk */
+	DISCARD_CONCURRENT,	/* Set on one node, cleared on the peer! */
+	USE_DEGR_WFC_T,		/* degr-wfc-timeout instead of wfc-timeout. */
+	CLUSTER_ST_CHANGE,	/* Cluster wide state change going on... */
+	CL_ST_CHG_SUCCESS,
+	CL_ST_CHG_FAIL,
+	CRASHED_PRIMARY,	/* This node was a crashed primary.
+				 * Gets cleared when the state.conn
+				 * goes into C_CONNECTED state. */
+	WRITE_BM_AFTER_RESYNC,	/* A kmalloc() during resync failed */
+	NO_BARRIER_SUPP,	/* underlying block device doesn't implement barriers */
+	CONSIDER_RESYNC,
+
+	MD_NO_BARRIER,		/* meta data device does not support barriers,
+				   so don't even try */
+	SUSPEND_IO,		/* suspend application io */
+	BITMAP_IO,		/* suspend application io;
+				   once no more io in flight, start bitmap io */
+	BITMAP_IO_QUEUED,       /* Started bitmap IO */
+	RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
+	NET_CONGESTED,		/* The data socket is congested */
+
+	CONFIG_PENDING,		/* serialization of (re)configuration requests.
+				 * if set, also prevents the device from dying */
+	DEVICE_DYING,		/* device became unconfigured,
+				 * but worker thread is still handling the cleanup.
+				 * reconfiguring (nl_disk_conf, nl_net_conf) is dissalowed,
+				 * while this is set. */
+	RESIZE_PENDING,		/* Size change detected locally, waiting for the response from
+				 * the peer, if it changed there as well. */
+};
+
+struct drbd_bitmap; /* opaque for drbd_conf */
+
+/* TODO sort members for performance
+ * MAYBE group them further */
+
+/* THINK maybe we actually want to use the default "event/%s" worker threads
+ * or similar in linux 2.6, which uses per cpu data and threads.
+ *
+ * To be general, this might need a spin_lock member.
+ * For now, please use the mdev->req_lock to protect list_head,
+ * see drbd_queue_work below.
+ */
+struct drbd_work_queue {
+	struct list_head q;
+	struct semaphore s; /* producers up it, worker down()s it */
+	spinlock_t q_lock;  /* to protect the list. */
+};
+
+struct drbd_socket {
+	struct drbd_work_queue work;
+	struct mutex mutex;
+	struct socket    *socket;
+	/* this way we get our
+	 * send/receive buffers off the stack */
+	union p_polymorph sbuf;
+	union p_polymorph rbuf;
+};
+
+struct drbd_md {
+	u64 md_offset;		/* sector offset to 'super' block */
+
+	u64 la_size_sect;	/* last agreed size, unit sectors */
+	u64 uuid[UI_SIZE];
+	u64 device_uuid;
+	u32 flags;
+	u32 md_size_sect;
+
+	s32 al_offset;	/* signed relative sector offset to al area */
+	s32 bm_offset;	/* signed relative sector offset to bitmap */
+
+	/* u32 al_nr_extents;	   important for restoring the AL
+	 * is stored into  sync_conf.al_extents, which in turn
+	 * gets applied to act_log->nr_elements
+	 */
+};
+
+/* for sync_conf and other types... */
+#define NL_PACKET(name, number, fields) struct name { fields };
+#define NL_INTEGER(pn,pr,member) int member;
+#define NL_INT64(pn,pr,member) __u64 member;
+#define NL_BIT(pn,pr,member)   unsigned member:1;
+#define NL_STRING(pn,pr,member,len) unsigned char member[len]; int member ## _len;
+#include "linux/drbd_nl.h"
+
+struct drbd_backing_dev {
+	struct block_device *backing_bdev;
+	struct block_device *md_bdev;
+	struct file *lo_file;
+	struct file *md_file;
+	struct drbd_md md;
+	struct disk_conf dc; /* The user provided config... */
+	sector_t known_size; /* last known size of that backing device */
+};
+
+struct drbd_md_io {
+	struct drbd_conf *mdev;
+	struct completion event;
+	int error;
+};
+
+struct bm_io_work {
+	struct drbd_work w;
+	char *why;
+	int (*io_fn)(struct drbd_conf *mdev);
+	void (*done)(struct drbd_conf *mdev, int rv);
+};
+
+enum write_ordering_e {
+	WO_none,
+	WO_drain_io,
+	WO_bdev_flush,
+	WO_bio_barrier
+};
+
+struct drbd_conf {
+	/* things that are stored as / read from meta data on disk */
+	unsigned long flags;
+
+	/* configured by drbdsetup */
+	struct net_conf *net_conf; /* protected by get_net_conf() and put_net_conf() */
+	struct syncer_conf sync_conf;
+	struct drbd_backing_dev *ldev __protected_by(local);
+
+	sector_t p_size;     /* partner's disk size */
+	struct request_queue *rq_queue;
+	struct block_device *this_bdev;
+	struct gendisk	    *vdisk;
+
+	struct drbd_socket data; /* data/barrier/cstate/parameter packets */
+	struct drbd_socket meta; /* ping/ack (metadata) packets */
+	int agreed_pro_version;  /* actually used protocol version */
+	unsigned long last_received; /* in jiffies, either socket */
+	unsigned int ko_count;
+	struct drbd_work  resync_work,
+			  unplug_work,
+			  md_sync_work;
+	struct timer_list resync_timer;
+	struct timer_list md_sync_timer;
+
+	/* Used after attach while negotiating new disk state. */
+	union drbd_state new_state_tmp;
+
+	union drbd_state state;
+	wait_queue_head_t misc_wait;
+	wait_queue_head_t state_wait;  /* upon each state change. */
+	unsigned int send_cnt;
+	unsigned int recv_cnt;
+	unsigned int read_cnt;
+	unsigned int writ_cnt;
+	unsigned int al_writ_cnt;
+	unsigned int bm_writ_cnt;
+	atomic_t ap_bio_cnt;	 /* Requests we need to complete */
+	atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */
+	atomic_t rs_pending_cnt; /* RS request/data packets on the wire */
+	atomic_t unacked_cnt;	 /* Need to send replys for */
+	atomic_t local_cnt;	 /* Waiting for local completion */
+	atomic_t net_cnt;	 /* Users of net_conf */
+	spinlock_t req_lock;
+	struct drbd_tl_epoch *unused_spare_tle; /* for pre-allocation */
+	struct drbd_tl_epoch *newest_tle;
+	struct drbd_tl_epoch *oldest_tle;
+	struct list_head out_of_sequence_requests;
+	struct hlist_head *tl_hash;
+	unsigned int tl_hash_s;
+
+	/* blocks to sync in this run [unit BM_BLOCK_SIZE] */
+	unsigned long rs_total;
+	/* number of sync IOs that failed in this run */
+	unsigned long rs_failed;
+	/* Syncer's start time [unit jiffies] */
+	unsigned long rs_start;
+	/* cumulated time in PausedSyncX state [unit jiffies] */
+	unsigned long rs_paused;
+	/* block not up-to-date at mark [unit BM_BLOCK_SIZE] */
+	unsigned long rs_mark_left;
+	/* marks's time [unit jiffies] */
+	unsigned long rs_mark_time;
+	/* skipped because csum was equeal [unit BM_BLOCK_SIZE] */
+	unsigned long rs_same_csum;
+
+	/* where does the admin want us to start? (sector) */
+	sector_t ov_start_sector;
+	/* where are we now? (sector) */
+	sector_t ov_position;
+	/* Start sector of out of sync range (to merge printk reporting). */
+	sector_t ov_last_oos_start;
+	/* size of out-of-sync range in sectors. */
+	sector_t ov_last_oos_size;
+	unsigned long ov_left; /* in bits */
+	struct crypto_hash *csums_tfm;
+	struct crypto_hash *verify_tfm;
+
+	struct drbd_thread receiver;
+	struct drbd_thread worker;
+	struct drbd_thread asender;
+	struct drbd_bitmap *bitmap;
+	unsigned long bm_resync_fo; /* bit offset for drbd_bm_find_next */
+
+	/* Used to track operations of resync... */
+	struct lru_cache *resync;
+	/* Number of locked elements in resync LRU */
+	unsigned int resync_locked;
+	/* resync extent number waiting for application requests */
+	unsigned int resync_wenr;
+
+	int open_cnt;
+	u64 *p_uuid;
+	struct drbd_epoch *current_epoch;
+	spinlock_t epoch_lock;
+	unsigned int epochs;
+	enum write_ordering_e write_ordering;
+	struct list_head active_ee; /* IO in progress */
+	struct list_head sync_ee;   /* IO in progress */
+	struct list_head done_ee;   /* send ack */
+	struct list_head read_ee;   /* IO in progress */
+	struct list_head net_ee;    /* zero-copy network send in progress */
+	struct hlist_head *ee_hash; /* is proteced by req_lock! */
+	unsigned int ee_hash_s;
+
+	/* this one is protected by ee_lock, single thread */
+	struct drbd_epoch_entry *last_write_w_barrier;
+
+	int next_barrier_nr;
+	struct hlist_head *app_reads_hash; /* is proteced by req_lock */
+	struct list_head resync_reads;
+	atomic_t pp_in_use;
+	wait_queue_head_t ee_wait;
+	struct page *md_io_page;	/* one page buffer for md_io */
+	struct page *md_io_tmpp;	/* for logical_block_size != 512 */
+	struct mutex md_io_mutex;	/* protects the md_io_buffer */
+	spinlock_t al_lock;
+	wait_queue_head_t al_wait;
+	struct lru_cache *act_log;	/* activity log */
+	unsigned int al_tr_number;
+	int al_tr_cycle;
+	int al_tr_pos;   /* position of the next transaction in the journal */
+	struct crypto_hash *cram_hmac_tfm;
+	struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */
+	struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */
+	void *int_dig_out;
+	void *int_dig_in;
+	void *int_dig_vv;
+	wait_queue_head_t seq_wait;
+	atomic_t packet_seq;
+	unsigned int peer_seq;
+	spinlock_t peer_seq_lock;
+	unsigned int minor;
+	unsigned long comm_bm_set; /* communicated number of set bits. */
+	cpumask_var_t cpu_mask;
+	struct bm_io_work bm_io_work;
+	u64 ed_uuid; /* UUID of the exposed data */
+	struct mutex state_mutex;
+	char congestion_reason;  /* Why we where congested... */
+};
+
+static inline struct drbd_conf *minor_to_mdev(unsigned int minor)
+{
+	struct drbd_conf *mdev;
+
+	mdev = minor < minor_count ? minor_table[minor] : NULL;
+
+	return mdev;
+}
+
+static inline unsigned int mdev_to_minor(struct drbd_conf *mdev)
+{
+	return mdev->minor;
+}
+
+/* returns 1 if it was successfull,
+ * returns 0 if there was no data socket.
+ * so wherever you are going to use the data.socket, e.g. do
+ * if (!drbd_get_data_sock(mdev))
+ *	return 0;
+ *	CODE();
+ * drbd_put_data_sock(mdev);
+ */
+static inline int drbd_get_data_sock(struct drbd_conf *mdev)
+{
+	mutex_lock(&mdev->data.mutex);
+	/* drbd_disconnect() could have called drbd_free_sock()
+	 * while we were waiting in down()... */
+	if (unlikely(mdev->data.socket == NULL)) {
+		mutex_unlock(&mdev->data.mutex);
+		return 0;
+	}
+	return 1;
+}
+
+static inline void drbd_put_data_sock(struct drbd_conf *mdev)
+{
+	mutex_unlock(&mdev->data.mutex);
+}
+
+/*
+ * function declarations
+ *************************/
+
+/* drbd_main.c */
+
+enum chg_state_flags {
+	CS_HARD	= 1,
+	CS_VERBOSE = 2,
+	CS_WAIT_COMPLETE = 4,
+	CS_SERIALIZE    = 8,
+	CS_ORDERED      = CS_WAIT_COMPLETE + CS_SERIALIZE,
+};
+
+extern void drbd_init_set_defaults(struct drbd_conf *mdev);
+extern int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
+			union drbd_state mask, union drbd_state val);
+extern void drbd_force_state(struct drbd_conf *, union drbd_state,
+			union drbd_state);
+extern int _drbd_request_state(struct drbd_conf *, union drbd_state,
+			union drbd_state, enum chg_state_flags);
+extern int __drbd_set_state(struct drbd_conf *, union drbd_state,
+			    enum chg_state_flags, struct completion *done);
+extern void print_st_err(struct drbd_conf *, union drbd_state,
+			union drbd_state, int);
+extern int  drbd_thread_start(struct drbd_thread *thi);
+extern void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait);
+#ifdef CONFIG_SMP
+extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev);
+extern void drbd_calc_cpu_mask(struct drbd_conf *mdev);
+#else
+#define drbd_thread_current_set_cpu(A) ({})
+#define drbd_calc_cpu_mask(A) ({})
+#endif
+extern void drbd_free_resources(struct drbd_conf *mdev);
+extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
+		       unsigned int set_size);
+extern void tl_clear(struct drbd_conf *mdev);
+extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *);
+extern void drbd_free_sock(struct drbd_conf *mdev);
+extern int drbd_send(struct drbd_conf *mdev, struct socket *sock,
+			void *buf, size_t size, unsigned msg_flags);
+extern int drbd_send_protocol(struct drbd_conf *mdev);
+extern int drbd_send_uuids(struct drbd_conf *mdev);
+extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev);
+extern int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val);
+extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply);
+extern int _drbd_send_state(struct drbd_conf *mdev);
+extern int drbd_send_state(struct drbd_conf *mdev);
+extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
+			enum drbd_packets cmd, struct p_header *h,
+			size_t size, unsigned msg_flags);
+#define USE_DATA_SOCKET 1
+#define USE_META_SOCKET 0
+extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
+			enum drbd_packets cmd, struct p_header *h,
+			size_t size);
+extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd,
+			char *data, size_t size);
+extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc);
+extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr,
+			u32 set_size);
+extern int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
+			struct drbd_epoch_entry *e);
+extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd,
+			struct p_block_req *rp);
+extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
+			struct p_data *dp);
+extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd,
+			    sector_t sector, int blksize, u64 block_id);
+extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
+			   struct drbd_epoch_entry *e);
+extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req);
+extern int _drbd_send_barrier(struct drbd_conf *mdev,
+			struct drbd_tl_epoch *barrier);
+extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
+			      sector_t sector, int size, u64 block_id);
+extern int drbd_send_drequest_csum(struct drbd_conf *mdev,
+				   sector_t sector,int size,
+				   void *digest, int digest_size,
+				   enum drbd_packets cmd);
+extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size);
+
+extern int drbd_send_bitmap(struct drbd_conf *mdev);
+extern int _drbd_send_bitmap(struct drbd_conf *mdev);
+extern int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode);
+extern void drbd_free_bc(struct drbd_backing_dev *ldev);
+extern void drbd_mdev_cleanup(struct drbd_conf *mdev);
+
+/* drbd_meta-data.c (still in drbd_main.c) */
+extern void drbd_md_sync(struct drbd_conf *mdev);
+extern int  drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev);
+/* maybe define them below as inline? */
+extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local);
+extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local);
+extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local);
+extern void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local);
+extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local);
+extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local);
+extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local);
+extern int drbd_md_test_flag(struct drbd_backing_dev *, int);
+extern void drbd_md_mark_dirty(struct drbd_conf *mdev);
+extern void drbd_queue_bitmap_io(struct drbd_conf *mdev,
+				 int (*io_fn)(struct drbd_conf *),
+				 void (*done)(struct drbd_conf *, int),
+				 char *why);
+extern int drbd_bmio_set_n_write(struct drbd_conf *mdev);
+extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev);
+extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why);
+
+
+/* Meta data layout
+   We reserve a 128MB Block (4k aligned)
+   * either at the end of the backing device
+   * or on a seperate meta data device. */
+
+#define MD_RESERVED_SECT (128LU << 11)  /* 128 MB, unit sectors */
+/* The following numbers are sectors */
+#define MD_AL_OFFSET 8	    /* 8 Sectors after start of meta area */
+#define MD_AL_MAX_SIZE 64   /* = 32 kb LOG  ~ 3776 extents ~ 14 GB Storage */
+/* Allows up to about 3.8TB */
+#define MD_BM_OFFSET (MD_AL_OFFSET + MD_AL_MAX_SIZE)
+
+/* Since the smalles IO unit is usually 512 byte */
+#define MD_SECTOR_SHIFT	 9
+#define MD_SECTOR_SIZE	 (1<<MD_SECTOR_SHIFT)
+
+/* activity log */
+#define AL_EXTENTS_PT ((MD_SECTOR_SIZE-12)/8-1) /* 61 ; Extents per 512B sector */
+#define AL_EXTENT_SHIFT 22		 /* One extent represents 4M Storage */
+#define AL_EXTENT_SIZE (1<<AL_EXTENT_SHIFT)
+
+#if BITS_PER_LONG == 32
+#define LN2_BPL 5
+#define cpu_to_lel(A) cpu_to_le32(A)
+#define lel_to_cpu(A) le32_to_cpu(A)
+#elif BITS_PER_LONG == 64
+#define LN2_BPL 6
+#define cpu_to_lel(A) cpu_to_le64(A)
+#define lel_to_cpu(A) le64_to_cpu(A)
+#else
+#error "LN2 of BITS_PER_LONG unknown!"
+#endif
+
+/* resync bitmap */
+/* 16MB sized 'bitmap extent' to track syncer usage */
+struct bm_extent {
+	int rs_left; /* number of bits set (out of sync) in this extent. */
+	int rs_failed; /* number of failed resync requests in this extent. */
+	unsigned long flags;
+	struct lc_element lce;
+};
+
+#define BME_NO_WRITES  0  /* bm_extent.flags: no more requests on this one! */
+#define BME_LOCKED     1  /* bm_extent.flags: syncer active on this one. */
+
+/* drbd_bitmap.c */
+/*
+ * We need to store one bit for a block.
+ * Example: 1GB disk @ 4096 byte blocks ==> we need 32 KB bitmap.
+ * Bit 0 ==> local node thinks this block is binary identical on both nodes
+ * Bit 1 ==> local node thinks this block needs to be synced.
+ */
+
+#define BM_BLOCK_SHIFT  12			 /* 4k per bit */
+#define BM_BLOCK_SIZE	 (1<<BM_BLOCK_SHIFT)
+/* (9+3) : 512 bytes @ 8 bits; representing 16M storage
+ * per sector of on disk bitmap */
+#define BM_EXT_SHIFT	 (BM_BLOCK_SHIFT + MD_SECTOR_SHIFT + 3)  /* = 24 */
+#define BM_EXT_SIZE	 (1<<BM_EXT_SHIFT)
+
+#if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12)
+#error "HAVE YOU FIXED drbdmeta AS WELL??"
+#endif
+
+/* thus many _storage_ sectors are described by one bit */
+#define BM_SECT_TO_BIT(x)   ((x)>>(BM_BLOCK_SHIFT-9))
+#define BM_BIT_TO_SECT(x)   ((sector_t)(x)<<(BM_BLOCK_SHIFT-9))
+#define BM_SECT_PER_BIT     BM_BIT_TO_SECT(1)
+
+/* bit to represented kilo byte conversion */
+#define Bit2KB(bits) ((bits)<<(BM_BLOCK_SHIFT-10))
+
+/* in which _bitmap_ extent (resp. sector) the bit for a certain
+ * _storage_ sector is located in */
+#define BM_SECT_TO_EXT(x)   ((x)>>(BM_EXT_SHIFT-9))
+
+/* how much _storage_ sectors we have per bitmap sector */
+#define BM_EXT_TO_SECT(x)   ((sector_t)(x) << (BM_EXT_SHIFT-9))
+#define BM_SECT_PER_EXT     BM_EXT_TO_SECT(1)
+
+/* in one sector of the bitmap, we have this many activity_log extents. */
+#define AL_EXT_PER_BM_SECT  (1 << (BM_EXT_SHIFT - AL_EXTENT_SHIFT))
+#define BM_WORDS_PER_AL_EXT (1 << (AL_EXTENT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+
+#define BM_BLOCKS_PER_BM_EXT_B (BM_EXT_SHIFT - BM_BLOCK_SHIFT)
+#define BM_BLOCKS_PER_BM_EXT_MASK  ((1<<BM_BLOCKS_PER_BM_EXT_B) - 1)
+
+/* the extent in "PER_EXTENT" below is an activity log extent
+ * we need that many (long words/bytes) to store the bitmap
+ *		     of one AL_EXTENT_SIZE chunk of storage.
+ * we can store the bitmap for that many AL_EXTENTS within
+ * one sector of the _on_disk_ bitmap:
+ * bit	 0	  bit 37   bit 38	     bit (512*8)-1
+ *	     ...|........|........|.. // ..|........|
+ * sect. 0	 `296	  `304			   ^(512*8*8)-1
+ *
+#define BM_WORDS_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / BITS_PER_LONG )
+#define BM_BYTES_PER_EXT    ( (AL_EXT_SIZE/BM_BLOCK_SIZE) / 8 )  // 128
+#define BM_EXT_PER_SECT	    ( 512 / BM_BYTES_PER_EXTENT )	 //   4
+ */
+
+#define DRBD_MAX_SECTORS_32 (0xffffffffLU)
+#define DRBD_MAX_SECTORS_BM \
+	  ((MD_RESERVED_SECT - MD_BM_OFFSET) * (1LL<<(BM_EXT_SHIFT-9)))
+#if DRBD_MAX_SECTORS_BM < DRBD_MAX_SECTORS_32
+#define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_BM
+#define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_BM
+#elif !defined(CONFIG_LBDAF) && BITS_PER_LONG == 32
+#define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_32
+#define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_32
+#else
+#define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_BM
+/* 16 TB in units of sectors */
+#if BITS_PER_LONG == 32
+/* adjust by one page worth of bitmap,
+ * so we won't wrap around in drbd_bm_find_next_bit.
+ * you should use 64bit OS for that much storage, anyways. */
+#define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0xffff7fff)
+#else
+#define DRBD_MAX_SECTORS_FLEX BM_BIT_TO_SECT(0x1LU << 32)
+#endif
+#endif
+
+/* Sector shift value for the "hash" functions of tl_hash and ee_hash tables.
+ * With a value of 6 all IO in one 32K block make it to the same slot of the
+ * hash table. */
+#define HT_SHIFT 6
+#define DRBD_MAX_SEGMENT_SIZE (1U<<(9+HT_SHIFT))
+
+/* Number of elements in the app_reads_hash */
+#define APP_R_HSIZE 15
+
+extern int  drbd_bm_init(struct drbd_conf *mdev);
+extern int  drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors);
+extern void drbd_bm_cleanup(struct drbd_conf *mdev);
+extern void drbd_bm_set_all(struct drbd_conf *mdev);
+extern void drbd_bm_clear_all(struct drbd_conf *mdev);
+extern int  drbd_bm_set_bits(
+		struct drbd_conf *mdev, unsigned long s, unsigned long e);
+extern int  drbd_bm_clear_bits(
+		struct drbd_conf *mdev, unsigned long s, unsigned long e);
+/* bm_set_bits variant for use while holding drbd_bm_lock */
+extern void _drbd_bm_set_bits(struct drbd_conf *mdev,
+		const unsigned long s, const unsigned long e);
+extern int  drbd_bm_test_bit(struct drbd_conf *mdev, unsigned long bitnr);
+extern int  drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr);
+extern int  drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local);
+extern int  drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);
+extern int  drbd_bm_write(struct drbd_conf *mdev) __must_hold(local);
+extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev,
+		unsigned long al_enr);
+extern size_t	     drbd_bm_words(struct drbd_conf *mdev);
+extern unsigned long drbd_bm_bits(struct drbd_conf *mdev);
+extern sector_t      drbd_bm_capacity(struct drbd_conf *mdev);
+extern unsigned long drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo);
+/* bm_find_next variants for use while you hold drbd_bm_lock() */
+extern unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo);
+extern unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo);
+extern unsigned long drbd_bm_total_weight(struct drbd_conf *mdev);
+extern int drbd_bm_rs_done(struct drbd_conf *mdev);
+/* for receive_bitmap */
+extern void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset,
+		size_t number, unsigned long *buffer);
+/* for _drbd_send_bitmap and drbd_bm_write_sect */
+extern void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset,
+		size_t number, unsigned long *buffer);
+
+extern void drbd_bm_lock(struct drbd_conf *mdev, char *why);
+extern void drbd_bm_unlock(struct drbd_conf *mdev);
+
+extern int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e);
+/* drbd_main.c */
+
+extern struct kmem_cache *drbd_request_cache;
+extern struct kmem_cache *drbd_ee_cache;	/* epoch entries */
+extern struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
+extern struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
+extern mempool_t *drbd_request_mempool;
+extern mempool_t *drbd_ee_mempool;
+
+extern struct page *drbd_pp_pool; /* drbd's page pool */
+extern spinlock_t   drbd_pp_lock;
+extern int	    drbd_pp_vacant;
+extern wait_queue_head_t drbd_pp_wait;
+
+extern rwlock_t global_state_lock;
+
+extern struct drbd_conf *drbd_new_device(unsigned int minor);
+extern void drbd_free_mdev(struct drbd_conf *mdev);
+
+extern int proc_details;
+
+/* drbd_req */
+extern int drbd_make_request_26(struct request_queue *q, struct bio *bio);
+extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req);
+extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec);
+extern int is_valid_ar_handle(struct drbd_request *, sector_t);
+
+
+/* drbd_nl.c */
+extern void drbd_suspend_io(struct drbd_conf *mdev);
+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 *, int);
+enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 };
+extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, int force) __must_hold(local);
+extern void resync_after_online_grow(struct drbd_conf *);
+extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local);
+extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role,
+		int force);
+enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev);
+extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
+
+/* drbd_worker.c */
+extern int drbd_worker(struct drbd_thread *thi);
+extern int drbd_alter_sa(struct drbd_conf *mdev, int na);
+extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side);
+extern void resume_next_sg(struct drbd_conf *mdev);
+extern void suspend_other_sg(struct drbd_conf *mdev);
+extern int drbd_resync_finished(struct drbd_conf *mdev);
+/* maybe rather drbd_main.c ? */
+extern int drbd_md_sync_page_io(struct drbd_conf *mdev,
+		struct drbd_backing_dev *bdev, sector_t sector, int rw);
+extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int);
+
+static inline void ov_oos_print(struct drbd_conf *mdev)
+{
+	if (mdev->ov_last_oos_size) {
+		dev_err(DEV, "Out of sync: start=%llu, size=%lu (sectors)\n",
+		     (unsigned long long)mdev->ov_last_oos_start,
+		     (unsigned long)mdev->ov_last_oos_size);
+	}
+	mdev->ov_last_oos_size=0;
+}
+
+
+extern void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *);
+/* worker callbacks */
+extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int);
+extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_end_data_req(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_end_rsdata_req(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_end_csum_rs_req(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_end_ov_reply(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int);
+extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int);
+extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int);
+extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int);
+extern int w_io_error(struct drbd_conf *, struct drbd_work *, int);
+extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int);
+extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int);
+extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int);
+extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int);
+extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int);
+extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int);
+extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int);
+
+extern void resync_timer_fn(unsigned long data);
+
+/* drbd_receiver.c */
+extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list);
+extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
+					    u64 id,
+					    sector_t sector,
+					    unsigned int data_size,
+					    gfp_t gfp_mask) __must_hold(local);
+extern void drbd_free_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e);
+extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev,
+		struct list_head *head);
+extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev,
+		struct list_head *head);
+extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled);
+extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed);
+extern void drbd_flush_workqueue(struct drbd_conf *mdev);
+
+/* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to
+ * mess with get_fs/set_fs, we know we are KERNEL_DS always. */
+static inline int drbd_setsockopt(struct socket *sock, int level, int optname,
+			char __user *optval, int optlen)
+{
+	int err;
+	if (level == SOL_SOCKET)
+		err = sock_setsockopt(sock, level, optname, optval, optlen);
+	else
+		err = sock->ops->setsockopt(sock, level, optname, optval,
+					    optlen);
+	return err;
+}
+
+static inline void drbd_tcp_cork(struct socket *sock)
+{
+	int __user val = 1;
+	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
+			(char __user *)&val, sizeof(val));
+}
+
+static inline void drbd_tcp_uncork(struct socket *sock)
+{
+	int __user val = 0;
+	(void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK,
+			(char __user *)&val, sizeof(val));
+}
+
+static inline void drbd_tcp_nodelay(struct socket *sock)
+{
+	int __user val = 1;
+	(void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY,
+			(char __user *)&val, sizeof(val));
+}
+
+static inline void drbd_tcp_quickack(struct socket *sock)
+{
+	int __user val = 1;
+	(void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
+			(char __user *)&val, sizeof(val));
+}
+
+void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo);
+
+/* drbd_proc.c */
+extern struct proc_dir_entry *drbd_proc;
+extern const struct file_operations drbd_proc_fops;
+extern const char *drbd_conn_str(enum drbd_conns s);
+extern const char *drbd_role_str(enum drbd_role s);
+
+/* drbd_actlog.c */
+extern void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector);
+extern void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector);
+extern void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector);
+extern int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector);
+extern int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector);
+extern void drbd_rs_cancel_all(struct drbd_conf *mdev);
+extern int drbd_rs_del_all(struct drbd_conf *mdev);
+extern void drbd_rs_failed_io(struct drbd_conf *mdev,
+		sector_t sector, int size);
+extern int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *);
+extern void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector,
+		int size, const char *file, const unsigned int line);
+#define drbd_set_in_sync(mdev, sector, size) \
+	__drbd_set_in_sync(mdev, sector, size, __FILE__, __LINE__)
+extern void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector,
+		int size, const char *file, const unsigned int line);
+#define drbd_set_out_of_sync(mdev, sector, size) \
+	__drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__)
+extern void drbd_al_apply_to_bm(struct drbd_conf *mdev);
+extern void drbd_al_to_on_disk_bm(struct drbd_conf *mdev);
+extern void drbd_al_shrink(struct drbd_conf *mdev);
+
+
+/* drbd_nl.c */
+
+void drbd_nl_cleanup(void);
+int __init drbd_nl_init(void);
+void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state);
+void drbd_bcast_sync_progress(struct drbd_conf *mdev);
+void drbd_bcast_ee(struct drbd_conf *mdev,
+		const char *reason, const int dgs,
+		const char* seen_hash, const char* calc_hash,
+		const struct drbd_epoch_entry* e);
+
+
+/**
+ * DOC: DRBD State macros
+ *
+ * These macros are used to express state changes in easily readable form.
+ *
+ * The NS macros expand to a mask and a value, that can be bit ored onto the
+ * current state as soon as the spinlock (req_lock) was taken.
+ *
+ * The _NS macros are used for state functions that get called with the
+ * spinlock. These macros expand directly to the new state value.
+ *
+ * Besides the basic forms NS() and _NS() additional _?NS[23] are defined
+ * to express state changes that affect more than one aspect of the state.
+ *
+ * E.g. NS2(conn, C_CONNECTED, peer, R_SECONDARY)
+ * Means that the network connection was established and that the peer
+ * is in secondary role.
+ */
+#define role_MASK R_MASK
+#define peer_MASK R_MASK
+#define disk_MASK D_MASK
+#define pdsk_MASK D_MASK
+#define conn_MASK C_MASK
+#define susp_MASK 1
+#define user_isp_MASK 1
+#define aftr_isp_MASK 1
+
+#define NS(T, S) \
+	({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \
+	({ union drbd_state val; val.i = 0; val.T = (S); val; })
+#define NS2(T1, S1, T2, S2) \
+	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
+	  mask.T2 = T2##_MASK; mask; }), \
+	({ union drbd_state val; val.i = 0; val.T1 = (S1); \
+	  val.T2 = (S2); val; })
+#define NS3(T1, S1, T2, S2, T3, S3) \
+	({ union drbd_state mask; mask.i = 0; mask.T1 = T1##_MASK; \
+	  mask.T2 = T2##_MASK; mask.T3 = T3##_MASK; mask; }), \
+	({ union drbd_state val;  val.i = 0; val.T1 = (S1); \
+	  val.T2 = (S2); val.T3 = (S3); val; })
+
+#define _NS(D, T, S) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T = (S); __ns; })
+#define _NS2(D, T1, S1, T2, S2) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	__ns.T2 = (S2); __ns; })
+#define _NS3(D, T1, S1, T2, S2, T3, S3) \
+	D, ({ union drbd_state __ns; __ns.i = D->state.i; __ns.T1 = (S1); \
+	__ns.T2 = (S2); __ns.T3 = (S3); __ns; })
+
+/*
+ * inline helper functions
+ *************************/
+
+static inline void drbd_state_lock(struct drbd_conf *mdev)
+{
+	wait_event(mdev->misc_wait,
+		   !test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags));
+}
+
+static inline void drbd_state_unlock(struct drbd_conf *mdev)
+{
+	clear_bit(CLUSTER_ST_CHANGE, &mdev->flags);
+	wake_up(&mdev->misc_wait);
+}
+
+static inline int _drbd_set_state(struct drbd_conf *mdev,
+				   union drbd_state ns, enum chg_state_flags flags,
+				   struct completion *done)
+{
+	int rv;
+
+	read_lock(&global_state_lock);
+	rv = __drbd_set_state(mdev, ns, flags, done);
+	read_unlock(&global_state_lock);
+
+	return rv;
+}
+
+/**
+ * drbd_request_state() - Reqest a state change
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ *
+ * This is the most graceful way of requesting a state change. It is verbose
+ * quite verbose in case the state change is not possible, and all those
+ * state changes are globally serialized.
+ */
+static inline int drbd_request_state(struct drbd_conf *mdev,
+				     union drbd_state mask,
+				     union drbd_state val)
+{
+	return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED);
+}
+
+#define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
+static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, const char *where)
+{
+	switch (mdev->ldev->dc.on_io_error) {
+	case EP_PASS_ON:
+		if (!forcedetach) {
+			if (printk_ratelimit())
+				dev_err(DEV, "Local IO failed in %s."
+					     "Passing error on...\n", where);
+			break;
+		}
+		/* NOTE fall through to detach case if forcedetach set */
+	case EP_DETACH:
+	case EP_CALL_HELPER:
+		if (mdev->state.disk > D_FAILED) {
+			_drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL);
+			dev_err(DEV, "Local IO failed in %s."
+				     "Detaching...\n", where);
+		}
+		break;
+	}
+}
+
+/**
+ * drbd_chk_io_error: Handle the on_io_error setting, should be called from all io completion handlers
+ * @mdev:	 DRBD device.
+ * @error:	 Error code passed to the IO completion callback
+ * @forcedetach: Force detach. I.e. the error happened while accessing the meta data
+ *
+ * See also drbd_main.c:after_state_ch() if (os.disk > D_FAILED && ns.disk == D_FAILED)
+ */
+#define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__)
+static inline void drbd_chk_io_error_(struct drbd_conf *mdev,
+	int error, int forcedetach, const char *where)
+{
+	if (error) {
+		unsigned long flags;
+		spin_lock_irqsave(&mdev->req_lock, flags);
+		__drbd_chk_io_error_(mdev, forcedetach, where);
+		spin_unlock_irqrestore(&mdev->req_lock, flags);
+	}
+}
+
+
+/**
+ * drbd_md_first_sector() - Returns the first sector number of the meta data area
+ * @bdev:	Meta data block device.
+ *
+ * BTW, for internal meta data, this happens to be the maximum capacity
+ * we could agree upon with our peer node.
+ */
+static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev)
+{
+	switch (bdev->dc.meta_dev_idx) {
+	case DRBD_MD_INDEX_INTERNAL:
+	case DRBD_MD_INDEX_FLEX_INT:
+		return bdev->md.md_offset + bdev->md.bm_offset;
+	case DRBD_MD_INDEX_FLEX_EXT:
+	default:
+		return bdev->md.md_offset;
+	}
+}
+
+/**
+ * drbd_md_last_sector() - Return the last sector number of the meta data area
+ * @bdev:	Meta data block device.
+ */
+static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
+{
+	switch (bdev->dc.meta_dev_idx) {
+	case DRBD_MD_INDEX_INTERNAL:
+	case DRBD_MD_INDEX_FLEX_INT:
+		return bdev->md.md_offset + MD_AL_OFFSET - 1;
+	case DRBD_MD_INDEX_FLEX_EXT:
+	default:
+		return bdev->md.md_offset + bdev->md.md_size_sect;
+	}
+}
+
+/* Returns the number of 512 byte sectors of the device */
+static inline sector_t drbd_get_capacity(struct block_device *bdev)
+{
+	/* return bdev ? get_capacity(bdev->bd_disk) : 0; */
+	return bdev ? bdev->bd_inode->i_size >> 9 : 0;
+}
+
+/**
+ * drbd_get_max_capacity() - Returns the capacity we announce to out peer
+ * @bdev:	Meta data block device.
+ *
+ * returns the capacity we announce to out peer.  we clip ourselves at the
+ * various MAX_SECTORS, because if we don't, current implementation will
+ * oops sooner or later
+ */
+static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
+{
+	sector_t s;
+	switch (bdev->dc.meta_dev_idx) {
+	case DRBD_MD_INDEX_INTERNAL:
+	case DRBD_MD_INDEX_FLEX_INT:
+		s = drbd_get_capacity(bdev->backing_bdev)
+			? min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
+					drbd_md_first_sector(bdev))
+			: 0;
+		break;
+	case DRBD_MD_INDEX_FLEX_EXT:
+		s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX,
+				drbd_get_capacity(bdev->backing_bdev));
+		/* clip at maximum size the meta device can support */
+		s = min_t(sector_t, s,
+			BM_EXT_TO_SECT(bdev->md.md_size_sect
+				     - bdev->md.bm_offset));
+		break;
+	default:
+		s = min_t(sector_t, DRBD_MAX_SECTORS,
+				drbd_get_capacity(bdev->backing_bdev));
+	}
+	return s;
+}
+
+/**
+ * drbd_md_ss__() - Return the sector number of our meta data super block
+ * @mdev:	DRBD device.
+ * @bdev:	Meta data block device.
+ */
+static inline sector_t drbd_md_ss__(struct drbd_conf *mdev,
+				    struct drbd_backing_dev *bdev)
+{
+	switch (bdev->dc.meta_dev_idx) {
+	default: /* external, some index */
+		return MD_RESERVED_SECT * bdev->dc.meta_dev_idx;
+	case DRBD_MD_INDEX_INTERNAL:
+		/* with drbd08, internal meta data is always "flexible" */
+	case DRBD_MD_INDEX_FLEX_INT:
+		/* sizeof(struct md_on_disk_07) == 4k
+		 * position: last 4k aligned block of 4k size */
+		if (!bdev->backing_bdev) {
+			if (__ratelimit(&drbd_ratelimit_state)) {
+				dev_err(DEV, "bdev->backing_bdev==NULL\n");
+				dump_stack();
+			}
+			return 0;
+		}
+		return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL)
+			- MD_AL_OFFSET;
+	case DRBD_MD_INDEX_FLEX_EXT:
+		return 0;
+	}
+}
+
+static inline void
+_drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
+{
+	list_add_tail(&w->list, &q->q);
+	up(&q->s);
+}
+
+static inline void
+drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&q->q_lock, flags);
+	list_add(&w->list, &q->q);
+	up(&q->s); /* within the spinlock,
+		      see comment near end of drbd_worker() */
+	spin_unlock_irqrestore(&q->q_lock, flags);
+}
+
+static inline void
+drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&q->q_lock, flags);
+	list_add_tail(&w->list, &q->q);
+	up(&q->s); /* within the spinlock,
+		      see comment near end of drbd_worker() */
+	spin_unlock_irqrestore(&q->q_lock, flags);
+}
+
+static inline void wake_asender(struct drbd_conf *mdev)
+{
+	if (test_bit(SIGNAL_ASENDER, &mdev->flags))
+		force_sig(DRBD_SIG, mdev->asender.task);
+}
+
+static inline void request_ping(struct drbd_conf *mdev)
+{
+	set_bit(SEND_PING, &mdev->flags);
+	wake_asender(mdev);
+}
+
+static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
+	enum drbd_packets cmd)
+{
+	struct p_header h;
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h));
+}
+
+static inline int drbd_send_ping(struct drbd_conf *mdev)
+{
+	struct p_header h;
+	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING, &h, sizeof(h));
+}
+
+static inline int drbd_send_ping_ack(struct drbd_conf *mdev)
+{
+	struct p_header h;
+	return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h));
+}
+
+static inline void drbd_thread_stop(struct drbd_thread *thi)
+{
+	_drbd_thread_stop(thi, FALSE, TRUE);
+}
+
+static inline void drbd_thread_stop_nowait(struct drbd_thread *thi)
+{
+	_drbd_thread_stop(thi, FALSE, FALSE);
+}
+
+static inline void drbd_thread_restart_nowait(struct drbd_thread *thi)
+{
+	_drbd_thread_stop(thi, TRUE, FALSE);
+}
+
+/* counts how many answer packets packets we expect from our peer,
+ * for either explicit application requests,
+ * or implicit barrier packets as necessary.
+ * increased:
+ *  w_send_barrier
+ *  _req_mod(req, queue_for_net_write or queue_for_net_read);
+ *    it is much easier and equally valid to count what we queue for the
+ *    worker, even before it actually was queued or send.
+ *    (drbd_make_request_common; recovery path on read io-error)
+ * decreased:
+ *  got_BarrierAck (respective tl_clear, tl_clear_barrier)
+ *  _req_mod(req, data_received)
+ *     [from receive_DataReply]
+ *  _req_mod(req, write_acked_by_peer or recv_acked_by_peer or neg_acked)
+ *     [from got_BlockAck (P_WRITE_ACK, P_RECV_ACK)]
+ *     for some reason it is NOT decreased in got_NegAck,
+ *     but in the resulting cleanup code from report_params.
+ *     we should try to remember the reason for that...
+ *  _req_mod(req, send_failed or send_canceled)
+ *  _req_mod(req, connection_lost_while_pending)
+ *     [from tl_clear_barrier]
+ */
+static inline void inc_ap_pending(struct drbd_conf *mdev)
+{
+	atomic_inc(&mdev->ap_pending_cnt);
+}
+
+#define ERR_IF_CNT_IS_NEGATIVE(which)				\
+	if (atomic_read(&mdev->which) < 0)			\
+		dev_err(DEV, "in %s:%d: " #which " = %d < 0 !\n",	\
+		    __func__ , __LINE__ ,			\
+		    atomic_read(&mdev->which))
+
+#define dec_ap_pending(mdev)	do {				\
+	typecheck(struct drbd_conf *, mdev);			\
+	if (atomic_dec_and_test(&mdev->ap_pending_cnt))		\
+		wake_up(&mdev->misc_wait);			\
+	ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt); } while (0)
+
+/* counts how many resync-related answers we still expect from the peer
+ *		     increase			decrease
+ * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY)
+ * C_SYNC_SOURCE sends P_RS_DATA_REPLY   (and expects P_WRITE_ACK whith ID_SYNCER)
+ *					   (or P_NEG_ACK with ID_SYNCER)
+ */
+static inline void inc_rs_pending(struct drbd_conf *mdev)
+{
+	atomic_inc(&mdev->rs_pending_cnt);
+}
+
+#define dec_rs_pending(mdev)	do {				\
+	typecheck(struct drbd_conf *, mdev);			\
+	atomic_dec(&mdev->rs_pending_cnt);			\
+	ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt); } while (0)
+
+/* counts how many answers we still need to send to the peer.
+ * increased on
+ *  receive_Data	unless protocol A;
+ *			we need to send a P_RECV_ACK (proto B)
+ *			or P_WRITE_ACK (proto C)
+ *  receive_RSDataReply (recv_resync_read) we need to send a P_WRITE_ACK
+ *  receive_DataRequest (receive_RSDataRequest) we need to send back P_DATA
+ *  receive_Barrier_*	we need to send a P_BARRIER_ACK
+ */
+static inline void inc_unacked(struct drbd_conf *mdev)
+{
+	atomic_inc(&mdev->unacked_cnt);
+}
+
+#define dec_unacked(mdev)	do {				\
+	typecheck(struct drbd_conf *, mdev);			\
+	atomic_dec(&mdev->unacked_cnt);				\
+	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0)
+
+#define sub_unacked(mdev, n)	do {				\
+	typecheck(struct drbd_conf *, mdev);			\
+	atomic_sub(n, &mdev->unacked_cnt);			\
+	ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0)
+
+
+static inline void put_net_conf(struct drbd_conf *mdev)
+{
+	if (atomic_dec_and_test(&mdev->net_cnt))
+		wake_up(&mdev->misc_wait);
+}
+
+/**
+ * get_net_conf() - Increase ref count on mdev->net_conf; Returns 0 if nothing there
+ * @mdev:	DRBD device.
+ *
+ * You have to call put_net_conf() when finished working with mdev->net_conf.
+ */
+static inline int get_net_conf(struct drbd_conf *mdev)
+{
+	int have_net_conf;
+
+	atomic_inc(&mdev->net_cnt);
+	have_net_conf = mdev->state.conn >= C_UNCONNECTED;
+	if (!have_net_conf)
+		put_net_conf(mdev);
+	return have_net_conf;
+}
+
+/**
+ * get_ldev() - Increase the ref count on mdev->ldev. Returns 0 if there is no ldev
+ * @M:		DRBD device.
+ *
+ * You have to call put_ldev() when finished working with mdev->ldev.
+ */
+#define get_ldev(M) __cond_lock(local, _get_ldev_if_state(M,D_INCONSISTENT))
+#define get_ldev_if_state(M,MINS) __cond_lock(local, _get_ldev_if_state(M,MINS))
+
+static inline void put_ldev(struct drbd_conf *mdev)
+{
+	__release(local);
+	if (atomic_dec_and_test(&mdev->local_cnt))
+		wake_up(&mdev->misc_wait);
+	D_ASSERT(atomic_read(&mdev->local_cnt) >= 0);
+}
+
+#ifndef __CHECKER__
+static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins)
+{
+	int io_allowed;
+
+	atomic_inc(&mdev->local_cnt);
+	io_allowed = (mdev->state.disk >= mins);
+	if (!io_allowed)
+		put_ldev(mdev);
+	return io_allowed;
+}
+#else
+extern int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins);
+#endif
+
+/* you must have an "get_ldev" reference */
+static inline void drbd_get_syncer_progress(struct drbd_conf *mdev,
+		unsigned long *bits_left, unsigned int *per_mil_done)
+{
+	/*
+	 * this is to break it at compile time when we change that
+	 * (we may feel 4TB maximum storage per drbd is not enough)
+	 */
+	typecheck(unsigned long, mdev->rs_total);
+
+	/* note: both rs_total and rs_left are in bits, i.e. in
+	 * units of BM_BLOCK_SIZE.
+	 * for the percentage, we don't care. */
+
+	*bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed;
+	/* >> 10 to prevent overflow,
+	 * +1 to prevent division by zero */
+	if (*bits_left > mdev->rs_total) {
+		/* doh. maybe a logic bug somewhere.
+		 * may also be just a race condition
+		 * between this and a disconnect during sync.
+		 * for now, just prevent in-kernel buffer overflow.
+		 */
+		smp_rmb();
+		dev_warn(DEV, "cs:%s rs_left=%lu > rs_total=%lu (rs_failed %lu)\n",
+				drbd_conn_str(mdev->state.conn),
+				*bits_left, mdev->rs_total, mdev->rs_failed);
+		*per_mil_done = 0;
+	} else {
+		/* make sure the calculation happens in long context */
+		unsigned long tmp = 1000UL -
+				(*bits_left >> 10)*1000UL
+				/ ((mdev->rs_total >> 10) + 1UL);
+		*per_mil_done = tmp;
+	}
+}
+
+
+/* this throttles on-the-fly application requests
+ * according to max_buffers settings;
+ * maybe re-implement using semaphores? */
+static inline int drbd_get_max_buffers(struct drbd_conf *mdev)
+{
+	int mxb = 1000000; /* arbitrary limit on open requests */
+	if (get_net_conf(mdev)) {
+		mxb = mdev->net_conf->max_buffers;
+		put_net_conf(mdev);
+	}
+	return mxb;
+}
+
+static inline int drbd_state_is_stable(union drbd_state s)
+{
+
+	/* DO NOT add a default clause, we want the compiler to warn us
+	 * for any newly introduced state we may have forgotten to add here */
+
+	switch ((enum drbd_conns)s.conn) {
+	/* new io only accepted when there is no connection, ... */
+	case C_STANDALONE:
+	case C_WF_CONNECTION:
+	/* ... or there is a well established connection. */
+	case C_CONNECTED:
+	case C_SYNC_SOURCE:
+	case C_SYNC_TARGET:
+	case C_VERIFY_S:
+	case C_VERIFY_T:
+	case C_PAUSED_SYNC_S:
+	case C_PAUSED_SYNC_T:
+		/* maybe stable, look at the disk state */
+		break;
+
+	/* no new io accepted during tansitional states
+	 * like handshake or teardown */
+	case C_DISCONNECTING:
+	case C_UNCONNECTED:
+	case C_TIMEOUT:
+	case C_BROKEN_PIPE:
+	case C_NETWORK_FAILURE:
+	case C_PROTOCOL_ERROR:
+	case C_TEAR_DOWN:
+	case C_WF_REPORT_PARAMS:
+	case C_STARTING_SYNC_S:
+	case C_STARTING_SYNC_T:
+	case C_WF_BITMAP_S:
+	case C_WF_BITMAP_T:
+	case C_WF_SYNC_UUID:
+	case C_MASK:
+		/* not "stable" */
+		return 0;
+	}
+
+	switch ((enum drbd_disk_state)s.disk) {
+	case D_DISKLESS:
+	case D_INCONSISTENT:
+	case D_OUTDATED:
+	case D_CONSISTENT:
+	case D_UP_TO_DATE:
+		/* disk state is stable as well. */
+		break;
+
+	/* no new io accepted during tansitional states */
+	case D_ATTACHING:
+	case D_FAILED:
+	case D_NEGOTIATING:
+	case D_UNKNOWN:
+	case D_MASK:
+		/* not "stable" */
+		return 0;
+	}
+
+	return 1;
+}
+
+static inline int __inc_ap_bio_cond(struct drbd_conf *mdev)
+{
+	int mxb = drbd_get_max_buffers(mdev);
+
+	if (mdev->state.susp)
+		return 0;
+	if (test_bit(SUSPEND_IO, &mdev->flags))
+		return 0;
+
+	/* to avoid potential deadlock or bitmap corruption,
+	 * in various places, we only allow new application io
+	 * to start during "stable" states. */
+
+	/* no new io accepted when attaching or detaching the disk */
+	if (!drbd_state_is_stable(mdev->state))
+		return 0;
+
+	/* since some older kernels don't have atomic_add_unless,
+	 * and we are within the spinlock anyways, we have this workaround.  */
+	if (atomic_read(&mdev->ap_bio_cnt) > mxb)
+		return 0;
+	if (test_bit(BITMAP_IO, &mdev->flags))
+		return 0;
+	return 1;
+}
+
+/* I'd like to use wait_event_lock_irq,
+ * but I'm not sure when it got introduced,
+ * and not sure when it has 3 or 4 arguments */
+static inline void inc_ap_bio(struct drbd_conf *mdev, int one_or_two)
+{
+	/* compare with after_state_ch,
+	 * os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S */
+	DEFINE_WAIT(wait);
+
+	/* we wait here
+	 *    as long as the device is suspended
+	 *    until the bitmap is no longer on the fly during connection
+	 *    handshake as long as we would exeed the max_buffer limit.
+	 *
+	 * to avoid races with the reconnect code,
+	 * we need to atomic_inc within the spinlock. */
+
+	spin_lock_irq(&mdev->req_lock);
+	while (!__inc_ap_bio_cond(mdev)) {
+		prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE);
+		spin_unlock_irq(&mdev->req_lock);
+		schedule();
+		finish_wait(&mdev->misc_wait, &wait);
+		spin_lock_irq(&mdev->req_lock);
+	}
+	atomic_add(one_or_two, &mdev->ap_bio_cnt);
+	spin_unlock_irq(&mdev->req_lock);
+}
+
+static inline void dec_ap_bio(struct drbd_conf *mdev)
+{
+	int mxb = drbd_get_max_buffers(mdev);
+	int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt);
+
+	D_ASSERT(ap_bio >= 0);
+	/* this currently does wake_up for every dec_ap_bio!
+	 * maybe rather introduce some type of hysteresis?
+	 * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */
+	if (ap_bio < mxb)
+		wake_up(&mdev->misc_wait);
+	if (ap_bio == 0 && test_bit(BITMAP_IO, &mdev->flags)) {
+		if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags))
+			drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w);
+	}
+}
+
+static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val)
+{
+	mdev->ed_uuid = val;
+}
+
+static inline int seq_cmp(u32 a, u32 b)
+{
+	/* we assume wrap around at 32bit.
+	 * for wrap around at 24bit (old atomic_t),
+	 * we'd have to
+	 *  a <<= 8; b <<= 8;
+	 */
+	return (s32)(a) - (s32)(b);
+}
+#define seq_lt(a, b) (seq_cmp((a), (b)) < 0)
+#define seq_gt(a, b) (seq_cmp((a), (b)) > 0)
+#define seq_ge(a, b) (seq_cmp((a), (b)) >= 0)
+#define seq_le(a, b) (seq_cmp((a), (b)) <= 0)
+/* CAUTION: please no side effects in arguments! */
+#define seq_max(a, b) ((u32)(seq_gt((a), (b)) ? (a) : (b)))
+
+static inline void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq)
+{
+	unsigned int m;
+	spin_lock(&mdev->peer_seq_lock);
+	m = seq_max(mdev->peer_seq, new_seq);
+	mdev->peer_seq = m;
+	spin_unlock(&mdev->peer_seq_lock);
+	if (m == new_seq)
+		wake_up(&mdev->seq_wait);
+}
+
+static inline void drbd_update_congested(struct drbd_conf *mdev)
+{
+	struct sock *sk = mdev->data.socket->sk;
+	if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
+		set_bit(NET_CONGESTED, &mdev->flags);
+}
+
+static inline int drbd_queue_order_type(struct drbd_conf *mdev)
+{
+	/* sorry, we currently have no working implementation
+	 * of distributed TCQ stuff */
+#ifndef QUEUE_ORDERED_NONE
+#define QUEUE_ORDERED_NONE 0
+#endif
+	return QUEUE_ORDERED_NONE;
+}
+
+static inline void drbd_blk_run_queue(struct request_queue *q)
+{
+	if (q && q->unplug_fn)
+		q->unplug_fn(q);
+}
+
+static inline void drbd_kick_lo(struct drbd_conf *mdev)
+{
+	if (get_ldev(mdev)) {
+		drbd_blk_run_queue(bdev_get_queue(mdev->ldev->backing_bdev));
+		put_ldev(mdev);
+	}
+}
+
+static inline void drbd_md_flush(struct drbd_conf *mdev)
+{
+	int r;
+
+	if (test_bit(MD_NO_BARRIER, &mdev->flags))
+		return;
+
+	r = blkdev_issue_flush(mdev->ldev->md_bdev, NULL);
+	if (r) {
+		set_bit(MD_NO_BARRIER, &mdev->flags);
+		dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r);
+	}
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_main.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_main.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3699 @@
+/*
+   drbd.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   Thanks to Carter Burden, Bart Grantham and Gennadiy Nerubayev
+   from Logicworks, Inc. for making SDP replication support possible.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+#include <linux/drbd.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <net/sock.h>
+#include <linux/ctype.h>
+#include <linux/smp_lock.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/memcontrol.h>
+#include <linux/mm_inline.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
+
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <linux/vmalloc.h>
+
+#include <linux/drbd_limits.h>
+#include "drbd_int.h"
+#include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */
+
+#include "drbd_vli.h"
+
+struct after_state_chg_work {
+	struct drbd_work w;
+	union drbd_state os;
+	union drbd_state ns;
+	enum chg_state_flags flags;
+	struct completion *done;
+};
+
+int drbdd_init(struct drbd_thread *);
+int drbd_worker(struct drbd_thread *);
+int drbd_asender(struct drbd_thread *);
+
+int drbd_init(void);
+static int drbd_open(struct block_device *bdev, fmode_t mode);
+static int drbd_release(struct gendisk *gd, fmode_t mode);
+static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
+			   union drbd_state ns, enum chg_state_flags flags);
+static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+static void md_sync_timer_fn(unsigned long data);
+static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+
+MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "
+	      "Lars Ellenberg <lars@linbit.com>");
+MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION);
+MODULE_VERSION(REL_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (1-255)");
+MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR);
+
+#include <linux/moduleparam.h>
+/* allow_open_on_secondary */
+MODULE_PARM_DESC(allow_oos, "DONT USE!");
+/* thanks to these macros, if compiled into the kernel (not-module),
+ * this becomes the boot parameter drbd.minor_count */
+module_param(minor_count, uint, 0444);
+module_param(disable_sendpage, bool, 0644);
+module_param(allow_oos, bool, 0);
+module_param(cn_idx, uint, 0444);
+module_param(proc_details, int, 0644);
+
+#ifdef CONFIG_DRBD_FAULT_INJECTION
+int enable_faults;
+int fault_rate;
+static int fault_count;
+int fault_devs;
+/* bitmap of enabled faults */
+module_param(enable_faults, int, 0664);
+/* fault rate % value - applies to all enabled faults */
+module_param(fault_rate, int, 0664);
+/* count of faults inserted */
+module_param(fault_count, int, 0664);
+/* bitmap of devices to insert faults on */
+module_param(fault_devs, int, 0644);
+#endif
+
+/* module parameter, defined */
+unsigned int minor_count = 32;
+int disable_sendpage;
+int allow_oos;
+unsigned int cn_idx = CN_IDX_DRBD;
+int proc_details;       /* Detail level in proc drbd*/
+
+/* Module parameter for setting the user mode helper program
+ * to run. Default is /sbin/drbdadm */
+char usermode_helper[80] = "/sbin/drbdadm";
+
+module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
+
+/* in 2.6.x, our device mapping and config info contains our virtual gendisks
+ * as member "struct gendisk *vdisk;"
+ */
+struct drbd_conf **minor_table;
+
+struct kmem_cache *drbd_request_cache;
+struct kmem_cache *drbd_ee_cache;	/* epoch entries */
+struct kmem_cache *drbd_bm_ext_cache;	/* bitmap extents */
+struct kmem_cache *drbd_al_ext_cache;	/* activity log extents */
+mempool_t *drbd_request_mempool;
+mempool_t *drbd_ee_mempool;
+
+/* I do not use a standard mempool, because:
+   1) I want to hand out the pre-allocated objects first.
+   2) I want to be able to interrupt sleeping allocation with a signal.
+   Note: This is a single linked list, the next pointer is the private
+	 member of struct page.
+ */
+struct page *drbd_pp_pool;
+spinlock_t   drbd_pp_lock;
+int          drbd_pp_vacant;
+wait_queue_head_t drbd_pp_wait;
+
+DEFINE_RATELIMIT_STATE(drbd_ratelimit_state, 5 * HZ, 5);
+
+static const struct block_device_operations drbd_ops = {
+	.owner =   THIS_MODULE,
+	.open =    drbd_open,
+	.release = drbd_release,
+};
+
+#define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
+
+#ifdef __CHECKER__
+/* When checking with sparse, and this is an inline function, sparse will
+   give tons of false positives. When this is a real functions sparse works.
+ */
+int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins)
+{
+	int io_allowed;
+
+	atomic_inc(&mdev->local_cnt);
+	io_allowed = (mdev->state.disk >= mins);
+	if (!io_allowed) {
+		if (atomic_dec_and_test(&mdev->local_cnt))
+			wake_up(&mdev->misc_wait);
+	}
+	return io_allowed;
+}
+
+#endif
+
+/**
+ * DOC: The transfer log
+ *
+ * The transfer log is a single linked list of &struct drbd_tl_epoch objects.
+ * mdev->newest_tle points to the head, mdev->oldest_tle points to the tail
+ * of the list. There is always at least one &struct drbd_tl_epoch object.
+ *
+ * Each &struct drbd_tl_epoch has a circular double linked list of requests
+ * attached.
+ */
+static int tl_init(struct drbd_conf *mdev)
+{
+	struct drbd_tl_epoch *b;
+
+	/* during device minor initialization, we may well use GFP_KERNEL */
+	b = kmalloc(sizeof(struct drbd_tl_epoch), GFP_KERNEL);
+	if (!b)
+		return 0;
+	INIT_LIST_HEAD(&b->requests);
+	INIT_LIST_HEAD(&b->w.list);
+	b->next = NULL;
+	b->br_number = 4711;
+	b->n_req = 0;
+	b->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */
+
+	mdev->oldest_tle = b;
+	mdev->newest_tle = b;
+	INIT_LIST_HEAD(&mdev->out_of_sequence_requests);
+
+	mdev->tl_hash = NULL;
+	mdev->tl_hash_s = 0;
+
+	return 1;
+}
+
+static void tl_cleanup(struct drbd_conf *mdev)
+{
+	D_ASSERT(mdev->oldest_tle == mdev->newest_tle);
+	D_ASSERT(list_empty(&mdev->out_of_sequence_requests));
+	kfree(mdev->oldest_tle);
+	mdev->oldest_tle = NULL;
+	kfree(mdev->unused_spare_tle);
+	mdev->unused_spare_tle = NULL;
+	kfree(mdev->tl_hash);
+	mdev->tl_hash = NULL;
+	mdev->tl_hash_s = 0;
+}
+
+/**
+ * _tl_add_barrier() - Adds a barrier to the transfer log
+ * @mdev:	DRBD device.
+ * @new:	Barrier to be added before the current head of the TL.
+ *
+ * The caller must hold the req_lock.
+ */
+void _tl_add_barrier(struct drbd_conf *mdev, struct drbd_tl_epoch *new)
+{
+	struct drbd_tl_epoch *newest_before;
+
+	INIT_LIST_HEAD(&new->requests);
+	INIT_LIST_HEAD(&new->w.list);
+	new->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */
+	new->next = NULL;
+	new->n_req = 0;
+
+	newest_before = mdev->newest_tle;
+	/* never send a barrier number == 0, because that is special-cased
+	 * when using TCQ for our write ordering code */
+	new->br_number = (newest_before->br_number+1) ?: 1;
+	if (mdev->newest_tle != new) {
+		mdev->newest_tle->next = new;
+		mdev->newest_tle = new;
+	}
+}
+
+/**
+ * tl_release() - Free or recycle the oldest &struct drbd_tl_epoch object of the TL
+ * @mdev:	DRBD device.
+ * @barrier_nr:	Expected identifier of the DRBD write barrier packet.
+ * @set_size:	Expected number of requests before that barrier.
+ *
+ * In case the passed barrier_nr or set_size does not match the oldest
+ * &struct drbd_tl_epoch objects this function will cause a termination
+ * of the connection.
+ */
+void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
+		       unsigned int set_size)
+{
+	struct drbd_tl_epoch *b, *nob; /* next old barrier */
+	struct list_head *le, *tle;
+	struct drbd_request *r;
+
+	spin_lock_irq(&mdev->req_lock);
+
+	b = mdev->oldest_tle;
+
+	/* first some paranoia code */
+	if (b == NULL) {
+		dev_err(DEV, "BAD! BarrierAck #%u received, but no epoch in tl!?\n",
+			barrier_nr);
+		goto bail;
+	}
+	if (b->br_number != barrier_nr) {
+		dev_err(DEV, "BAD! BarrierAck #%u received, expected #%u!\n",
+			barrier_nr, b->br_number);
+		goto bail;
+	}
+	if (b->n_req != set_size) {
+		dev_err(DEV, "BAD! BarrierAck #%u received with n_req=%u, expected n_req=%u!\n",
+			barrier_nr, set_size, b->n_req);
+		goto bail;
+	}
+
+	/* Clean up list of requests processed during current epoch */
+	list_for_each_safe(le, tle, &b->requests) {
+		r = list_entry(le, struct drbd_request, tl_requests);
+		_req_mod(r, barrier_acked);
+	}
+	/* There could be requests on the list waiting for completion
+	   of the write to the local disk. To avoid corruptions of
+	   slab's data structures we have to remove the lists head.
+
+	   Also there could have been a barrier ack out of sequence, overtaking
+	   the write acks - which would be a bug and violating write ordering.
+	   To not deadlock in case we lose connection while such requests are
+	   still pending, we need some way to find them for the
+	   _req_mode(connection_lost_while_pending).
+
+	   These have been list_move'd to the out_of_sequence_requests list in
+	   _req_mod(, barrier_acked) above.
+	   */
+	list_del_init(&b->requests);
+
+	nob = b->next;
+	if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) {
+		_tl_add_barrier(mdev, b);
+		if (nob)
+			mdev->oldest_tle = nob;
+		/* if nob == NULL b was the only barrier, and becomes the new
+		   barrier. Therefore mdev->oldest_tle points already to b */
+	} else {
+		D_ASSERT(nob != NULL);
+		mdev->oldest_tle = nob;
+		kfree(b);
+	}
+
+	spin_unlock_irq(&mdev->req_lock);
+	dec_ap_pending(mdev);
+
+	return;
+
+bail:
+	spin_unlock_irq(&mdev->req_lock);
+	drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+}
+
+
+/**
+ * tl_clear() - Clears all requests and &struct drbd_tl_epoch objects out of the TL
+ * @mdev:	DRBD device.
+ *
+ * This is called after the connection to the peer was lost. The storage covered
+ * by the requests on the transfer gets marked as our of sync. Called from the
+ * receiver thread and the worker thread.
+ */
+void tl_clear(struct drbd_conf *mdev)
+{
+	struct drbd_tl_epoch *b, *tmp;
+	struct list_head *le, *tle;
+	struct drbd_request *r;
+	int new_initial_bnr = net_random();
+
+	spin_lock_irq(&mdev->req_lock);
+
+	b = mdev->oldest_tle;
+	while (b) {
+		list_for_each_safe(le, tle, &b->requests) {
+			r = list_entry(le, struct drbd_request, tl_requests);
+			/* It would be nice to complete outside of spinlock.
+			 * But this is easier for now. */
+			_req_mod(r, connection_lost_while_pending);
+		}
+		tmp = b->next;
+
+		/* there could still be requests on that ring list,
+		 * in case local io is still pending */
+		list_del(&b->requests);
+
+		/* dec_ap_pending corresponding to queue_barrier.
+		 * the newest barrier may not have been queued yet,
+		 * in which case w.cb is still NULL. */
+		if (b->w.cb != NULL)
+			dec_ap_pending(mdev);
+
+		if (b == mdev->newest_tle) {
+			/* recycle, but reinit! */
+			D_ASSERT(tmp == NULL);
+			INIT_LIST_HEAD(&b->requests);
+			INIT_LIST_HEAD(&b->w.list);
+			b->w.cb = NULL;
+			b->br_number = new_initial_bnr;
+			b->n_req = 0;
+
+			mdev->oldest_tle = b;
+			break;
+		}
+		kfree(b);
+		b = tmp;
+	}
+
+	/* we expect this list to be empty. */
+	D_ASSERT(list_empty(&mdev->out_of_sequence_requests));
+
+	/* but just in case, clean it up anyways! */
+	list_for_each_safe(le, tle, &mdev->out_of_sequence_requests) {
+		r = list_entry(le, struct drbd_request, tl_requests);
+		/* It would be nice to complete outside of spinlock.
+		 * But this is easier for now. */
+		_req_mod(r, connection_lost_while_pending);
+	}
+
+	/* ensure bit indicating barrier is required is clear */
+	clear_bit(CREATE_BARRIER, &mdev->flags);
+
+	spin_unlock_irq(&mdev->req_lock);
+}
+
+/**
+ * cl_wide_st_chg() - TRUE if the state change is a cluster wide one
+ * @mdev:	DRBD device.
+ * @os:		old (current) state.
+ * @ns:		new (wanted) state.
+ */
+static int cl_wide_st_chg(struct drbd_conf *mdev,
+			  union drbd_state os, union drbd_state ns)
+{
+	return (os.conn >= C_CONNECTED && ns.conn >= C_CONNECTED &&
+		 ((os.role != R_PRIMARY && ns.role == R_PRIMARY) ||
+		  (os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
+		  (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S) ||
+		  (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))) ||
+		(os.conn >= C_CONNECTED && ns.conn == C_DISCONNECTING) ||
+		(os.conn == C_CONNECTED && ns.conn == C_VERIFY_S);
+}
+
+int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f,
+		      union drbd_state mask, union drbd_state val)
+{
+	unsigned long flags;
+	union drbd_state os, ns;
+	int rv;
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	rv = _drbd_set_state(mdev, ns, f, NULL);
+	ns = mdev->state;
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	return rv;
+}
+
+/**
+ * drbd_force_state() - Impose a change which happens outside our control on our state
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ */
+void drbd_force_state(struct drbd_conf *mdev,
+	union drbd_state mask, union drbd_state val)
+{
+	drbd_change_state(mdev, CS_HARD, mask, val);
+}
+
+static int is_valid_state(struct drbd_conf *mdev, union drbd_state ns);
+static int is_valid_state_transition(struct drbd_conf *,
+				     union drbd_state, union drbd_state);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, int *warn_sync_abort);
+int drbd_send_state_req(struct drbd_conf *,
+			union drbd_state, union drbd_state);
+
+static enum drbd_state_ret_codes _req_st_cond(struct drbd_conf *mdev,
+				    union drbd_state mask, union drbd_state val)
+{
+	union drbd_state os, ns;
+	unsigned long flags;
+	int rv;
+
+	if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags))
+		return SS_CW_SUCCESS;
+
+	if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags))
+		return SS_CW_FAILED_BY_PEER;
+
+	rv = 0;
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	ns = sanitize_state(mdev, os, ns, NULL);
+
+	if (!cl_wide_st_chg(mdev, os, ns))
+		rv = SS_CW_NO_NEED;
+	if (!rv) {
+		rv = is_valid_state(mdev, ns);
+		if (rv == SS_SUCCESS) {
+			rv = is_valid_state_transition(mdev, ns, os);
+			if (rv == SS_SUCCESS)
+				rv = 0; /* cont waiting, otherwise fail. */
+		}
+	}
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	return rv;
+}
+
+/**
+ * drbd_req_state() - Perform an eventually cluster wide state change
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ * @f:		flags
+ *
+ * Should not be called directly, use drbd_request_state() or
+ * _drbd_request_state().
+ */
+static int drbd_req_state(struct drbd_conf *mdev,
+			  union drbd_state mask, union drbd_state val,
+			  enum chg_state_flags f)
+{
+	struct completion done;
+	unsigned long flags;
+	union drbd_state os, ns;
+	int rv;
+
+	init_completion(&done);
+
+	if (f & CS_SERIALIZE)
+		mutex_lock(&mdev->state_mutex);
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	ns = sanitize_state(mdev, os, ns, NULL);
+
+	if (cl_wide_st_chg(mdev, os, ns)) {
+		rv = is_valid_state(mdev, ns);
+		if (rv == SS_SUCCESS)
+			rv = is_valid_state_transition(mdev, ns, os);
+		spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+		if (rv < SS_SUCCESS) {
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+
+		drbd_state_lock(mdev);
+		if (!drbd_send_state_req(mdev, mask, val)) {
+			drbd_state_unlock(mdev);
+			rv = SS_CW_FAILED_BY_PEER;
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+
+		wait_event(mdev->state_wait,
+			(rv = _req_st_cond(mdev, mask, val)));
+
+		if (rv < SS_SUCCESS) {
+			drbd_state_unlock(mdev);
+			if (f & CS_VERBOSE)
+				print_st_err(mdev, os, ns, rv);
+			goto abort;
+		}
+		spin_lock_irqsave(&mdev->req_lock, flags);
+		os = mdev->state;
+		ns.i = (os.i & ~mask.i) | val.i;
+		rv = _drbd_set_state(mdev, ns, f, &done);
+		drbd_state_unlock(mdev);
+	} else {
+		rv = _drbd_set_state(mdev, ns, f, &done);
+	}
+
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	if (f & CS_WAIT_COMPLETE && rv == SS_SUCCESS) {
+		D_ASSERT(current != mdev->worker.task);
+		wait_for_completion(&done);
+	}
+
+abort:
+	if (f & CS_SERIALIZE)
+		mutex_unlock(&mdev->state_mutex);
+
+	return rv;
+}
+
+/**
+ * _drbd_request_state() - Request a state change (with flags)
+ * @mdev:	DRBD device.
+ * @mask:	mask of state bits to change.
+ * @val:	value of new state bits.
+ * @f:		flags
+ *
+ * Cousin of drbd_request_state(), useful with the CS_WAIT_COMPLETE
+ * flag, or when logging of failed state change requests is not desired.
+ */
+int _drbd_request_state(struct drbd_conf *mdev,	union drbd_state mask,
+			union drbd_state val,	enum chg_state_flags f)
+{
+	int rv;
+
+	wait_event(mdev->state_wait,
+		   (rv = drbd_req_state(mdev, mask, val, f)) != SS_IN_TRANSIENT_STATE);
+
+	return rv;
+}
+
+static void print_st(struct drbd_conf *mdev, char *name, union drbd_state ns)
+{
+	dev_err(DEV, " %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c }\n",
+	    name,
+	    drbd_conn_str(ns.conn),
+	    drbd_role_str(ns.role),
+	    drbd_role_str(ns.peer),
+	    drbd_disk_str(ns.disk),
+	    drbd_disk_str(ns.pdsk),
+	    ns.susp ? 's' : 'r',
+	    ns.aftr_isp ? 'a' : '-',
+	    ns.peer_isp ? 'p' : '-',
+	    ns.user_isp ? 'u' : '-'
+	    );
+}
+
+void print_st_err(struct drbd_conf *mdev,
+	union drbd_state os, union drbd_state ns, int err)
+{
+	if (err == SS_IN_TRANSIENT_STATE)
+		return;
+	dev_err(DEV, "State change failed: %s\n", drbd_set_st_err_str(err));
+	print_st(mdev, " state", os);
+	print_st(mdev, "wanted", ns);
+}
+
+
+#define drbd_peer_str drbd_role_str
+#define drbd_pdsk_str drbd_disk_str
+
+#define drbd_susp_str(A)     ((A) ? "1" : "0")
+#define drbd_aftr_isp_str(A) ((A) ? "1" : "0")
+#define drbd_peer_isp_str(A) ((A) ? "1" : "0")
+#define drbd_user_isp_str(A) ((A) ? "1" : "0")
+
+#define PSC(A) \
+	({ if (ns.A != os.A) { \
+		pbp += sprintf(pbp, #A "( %s -> %s ) ", \
+			      drbd_##A##_str(os.A), \
+			      drbd_##A##_str(ns.A)); \
+	} })
+
+/**
+ * is_valid_state() - Returns an SS_ error code if ns is not valid
+ * @mdev:	DRBD device.
+ * @ns:		State to consider.
+ */
+static int is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
+{
+	/* See drbd_state_sw_errors in drbd_strings.c */
+
+	enum drbd_fencing_p fp;
+	int rv = SS_SUCCESS;
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	if (get_net_conf(mdev)) {
+		if (!mdev->net_conf->two_primaries &&
+		    ns.role == R_PRIMARY && ns.peer == R_PRIMARY)
+			rv = SS_TWO_PRIMARIES;
+		put_net_conf(mdev);
+	}
+
+	if (rv <= 0)
+		/* already found a reason to abort */;
+	else if (ns.role == R_SECONDARY && mdev->open_cnt)
+		rv = SS_DEVICE_IN_USE;
+
+	else if (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.disk < D_UP_TO_DATE)
+		rv = SS_NO_UP_TO_DATE_DISK;
+
+	else if (fp >= FP_RESOURCE &&
+		 ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk >= D_UNKNOWN)
+		rv = SS_PRIMARY_NOP;
+
+	else if (ns.role == R_PRIMARY && ns.disk <= D_INCONSISTENT && ns.pdsk <= D_INCONSISTENT)
+		rv = SS_NO_UP_TO_DATE_DISK;
+
+	else if (ns.conn > C_CONNECTED && ns.disk < D_INCONSISTENT)
+		rv = SS_NO_LOCAL_DISK;
+
+	else if (ns.conn > C_CONNECTED && ns.pdsk < D_INCONSISTENT)
+		rv = SS_NO_REMOTE_DISK;
+
+	else if ((ns.conn == C_CONNECTED ||
+		  ns.conn == C_WF_BITMAP_S ||
+		  ns.conn == C_SYNC_SOURCE ||
+		  ns.conn == C_PAUSED_SYNC_S) &&
+		  ns.disk == D_OUTDATED)
+		rv = SS_CONNECTED_OUTDATES;
+
+	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+		 (mdev->sync_conf.verify_alg[0] == 0))
+		rv = SS_NO_VERIFY_ALG;
+
+	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+		  mdev->agreed_pro_version < 88)
+		rv = SS_NOT_SUPPORTED;
+
+	return rv;
+}
+
+/**
+ * is_valid_state_transition() - Returns an SS_ error code if the state transition is not possible
+ * @mdev:	DRBD device.
+ * @ns:		new state.
+ * @os:		old state.
+ */
+static int is_valid_state_transition(struct drbd_conf *mdev,
+				     union drbd_state ns, union drbd_state os)
+{
+	int rv = SS_SUCCESS;
+
+	if ((ns.conn == C_STARTING_SYNC_T || ns.conn == C_STARTING_SYNC_S) &&
+	    os.conn > C_CONNECTED)
+		rv = SS_RESYNC_RUNNING;
+
+	if (ns.conn == C_DISCONNECTING && os.conn == C_STANDALONE)
+		rv = SS_ALREADY_STANDALONE;
+
+	if (ns.disk > D_ATTACHING && os.disk == D_DISKLESS)
+		rv = SS_IS_DISKLESS;
+
+	if (ns.conn == C_WF_CONNECTION && os.conn < C_UNCONNECTED)
+		rv = SS_NO_NET_CONFIG;
+
+	if (ns.disk == D_OUTDATED && os.disk < D_OUTDATED && os.disk != D_ATTACHING)
+		rv = SS_LOWER_THAN_OUTDATED;
+
+	if (ns.conn == C_DISCONNECTING && os.conn == C_UNCONNECTED)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	if (ns.conn == os.conn && ns.conn == C_WF_REPORT_PARAMS)
+		rv = SS_IN_TRANSIENT_STATE;
+
+	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && os.conn < C_CONNECTED)
+		rv = SS_NEED_CONNECTION;
+
+	if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+	    ns.conn != os.conn && os.conn > C_CONNECTED)
+		rv = SS_RESYNC_RUNNING;
+
+	if ((ns.conn == C_STARTING_SYNC_S || ns.conn == C_STARTING_SYNC_T) &&
+	    os.conn < C_CONNECTED)
+		rv = SS_NEED_CONNECTION;
+
+	return rv;
+}
+
+/**
+ * sanitize_state() - Resolves implicitly necessary additional changes to a state transition
+ * @mdev:	DRBD device.
+ * @os:		old state.
+ * @ns:		new state.
+ * @warn_sync_abort:
+ *
+ * When we loose connection, we have to set the state of the peers disk (pdsk)
+ * to D_UNKNOWN. This rule and many more along those lines are in this function.
+ */
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
+				       union drbd_state ns, int *warn_sync_abort)
+{
+	enum drbd_fencing_p fp;
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	/* Disallow Network errors to configure a device's network part */
+	if ((ns.conn >= C_TIMEOUT && ns.conn <= C_TEAR_DOWN) &&
+	    os.conn <= C_DISCONNECTING)
+		ns.conn = os.conn;
+
+	/* After a network error (+C_TEAR_DOWN) only C_UNCONNECTED or C_DISCONNECTING can follow */
+	if (os.conn >= C_TIMEOUT && os.conn <= C_TEAR_DOWN &&
+	    ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING)
+		ns.conn = os.conn;
+
+	/* After C_DISCONNECTING only C_STANDALONE may follow */
+	if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
+		ns.conn = os.conn;
+
+	if (ns.conn < C_CONNECTED) {
+		ns.peer_isp = 0;
+		ns.peer = R_UNKNOWN;
+		if (ns.pdsk > D_UNKNOWN || ns.pdsk < D_INCONSISTENT)
+			ns.pdsk = D_UNKNOWN;
+	}
+
+	/* Clear the aftr_isp when becoming unconfigured */
+	if (ns.conn == C_STANDALONE && ns.disk == D_DISKLESS && ns.role == R_SECONDARY)
+		ns.aftr_isp = 0;
+
+	if (ns.conn <= C_DISCONNECTING && ns.disk == D_DISKLESS)
+		ns.pdsk = D_UNKNOWN;
+
+	/* Abort resync if a disk fails/detaches */
+	if (os.conn > C_CONNECTED && ns.conn > C_CONNECTED &&
+	    (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
+		if (warn_sync_abort)
+			*warn_sync_abort = 1;
+		ns.conn = C_CONNECTED;
+	}
+
+	if (ns.conn >= C_CONNECTED &&
+	    ((ns.disk == D_CONSISTENT || ns.disk == D_OUTDATED) ||
+	     (ns.disk == D_NEGOTIATING && ns.conn == C_WF_BITMAP_T))) {
+		switch (ns.conn) {
+		case C_WF_BITMAP_T:
+		case C_PAUSED_SYNC_T:
+			ns.disk = D_OUTDATED;
+			break;
+		case C_CONNECTED:
+		case C_WF_BITMAP_S:
+		case C_SYNC_SOURCE:
+		case C_PAUSED_SYNC_S:
+			ns.disk = D_UP_TO_DATE;
+			break;
+		case C_SYNC_TARGET:
+			ns.disk = D_INCONSISTENT;
+			dev_warn(DEV, "Implicitly set disk state Inconsistent!\n");
+			break;
+		}
+		if (os.disk == D_OUTDATED && ns.disk == D_UP_TO_DATE)
+			dev_warn(DEV, "Implicitly set disk from Outdated to UpToDate\n");
+	}
+
+	if (ns.conn >= C_CONNECTED &&
+	    (ns.pdsk == D_CONSISTENT || ns.pdsk == D_OUTDATED)) {
+		switch (ns.conn) {
+		case C_CONNECTED:
+		case C_WF_BITMAP_T:
+		case C_PAUSED_SYNC_T:
+		case C_SYNC_TARGET:
+			ns.pdsk = D_UP_TO_DATE;
+			break;
+		case C_WF_BITMAP_S:
+		case C_PAUSED_SYNC_S:
+			ns.pdsk = D_OUTDATED;
+			break;
+		case C_SYNC_SOURCE:
+			ns.pdsk = D_INCONSISTENT;
+			dev_warn(DEV, "Implicitly set pdsk Inconsistent!\n");
+			break;
+		}
+		if (os.pdsk == D_OUTDATED && ns.pdsk == D_UP_TO_DATE)
+			dev_warn(DEV, "Implicitly set pdsk from Outdated to UpToDate\n");
+	}
+
+	/* Connection breaks down before we finished "Negotiating" */
+	if (ns.conn < C_CONNECTED && ns.disk == D_NEGOTIATING &&
+	    get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		if (mdev->ed_uuid == mdev->ldev->md.uuid[UI_CURRENT]) {
+			ns.disk = mdev->new_state_tmp.disk;
+			ns.pdsk = mdev->new_state_tmp.pdsk;
+		} else {
+			dev_alert(DEV, "Connection lost while negotiating, no data!\n");
+			ns.disk = D_DISKLESS;
+			ns.pdsk = D_UNKNOWN;
+		}
+		put_ldev(mdev);
+	}
+
+	if (fp == FP_STONITH &&
+	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
+	    !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
+		ns.susp = 1;
+
+	if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
+		if (ns.conn == C_SYNC_SOURCE)
+			ns.conn = C_PAUSED_SYNC_S;
+		if (ns.conn == C_SYNC_TARGET)
+			ns.conn = C_PAUSED_SYNC_T;
+	} else {
+		if (ns.conn == C_PAUSED_SYNC_S)
+			ns.conn = C_SYNC_SOURCE;
+		if (ns.conn == C_PAUSED_SYNC_T)
+			ns.conn = C_SYNC_TARGET;
+	}
+
+	return ns;
+}
+
+/* helper for __drbd_set_state */
+static void set_ov_position(struct drbd_conf *mdev, enum drbd_conns cs)
+{
+	if (cs == C_VERIFY_T) {
+		/* starting online verify from an arbitrary position
+		 * does not fit well into the existing protocol.
+		 * on C_VERIFY_T, we initialize ov_left and friends
+		 * implicitly in receive_DataRequest once the
+		 * first P_OV_REQUEST is received */
+		mdev->ov_start_sector = ~(sector_t)0;
+	} else {
+		unsigned long bit = BM_SECT_TO_BIT(mdev->ov_start_sector);
+		if (bit >= mdev->rs_total)
+			mdev->ov_start_sector =
+				BM_BIT_TO_SECT(mdev->rs_total - 1);
+		mdev->ov_position = mdev->ov_start_sector;
+	}
+}
+
+/**
+ * __drbd_set_state() - Set a new DRBD state
+ * @mdev:	DRBD device.
+ * @ns:		new state.
+ * @flags:	Flags
+ * @done:	Optional completion, that will get completed after the after_state_ch() finished
+ *
+ * Caller needs to hold req_lock, and global_state_lock. Do not call directly.
+ */
+int __drbd_set_state(struct drbd_conf *mdev,
+		    union drbd_state ns, enum chg_state_flags flags,
+		    struct completion *done)
+{
+	union drbd_state os;
+	int rv = SS_SUCCESS;
+	int warn_sync_abort = 0;
+	struct after_state_chg_work *ascw;
+
+	os = mdev->state;
+
+	ns = sanitize_state(mdev, os, ns, &warn_sync_abort);
+
+	if (ns.i == os.i)
+		return SS_NOTHING_TO_DO;
+
+	if (!(flags & CS_HARD)) {
+		/*  pre-state-change checks ; only look at ns  */
+		/* See drbd_state_sw_errors in drbd_strings.c */
+
+		rv = is_valid_state(mdev, ns);
+		if (rv < SS_SUCCESS) {
+			/* If the old state was illegal as well, then let
+			   this happen...*/
+
+			if (is_valid_state(mdev, os) == rv) {
+				dev_err(DEV, "Considering state change from bad state. "
+				    "Error would be: '%s'\n",
+				    drbd_set_st_err_str(rv));
+				print_st(mdev, "old", os);
+				print_st(mdev, "new", ns);
+				rv = is_valid_state_transition(mdev, ns, os);
+			}
+		} else
+			rv = is_valid_state_transition(mdev, ns, os);
+	}
+
+	if (rv < SS_SUCCESS) {
+		if (flags & CS_VERBOSE)
+			print_st_err(mdev, os, ns, rv);
+		return rv;
+	}
+
+	if (warn_sync_abort)
+		dev_warn(DEV, "Resync aborted.\n");
+
+	{
+		char *pbp, pb[300];
+		pbp = pb;
+		*pbp = 0;
+		PSC(role);
+		PSC(peer);
+		PSC(conn);
+		PSC(disk);
+		PSC(pdsk);
+		PSC(susp);
+		PSC(aftr_isp);
+		PSC(peer_isp);
+		PSC(user_isp);
+		dev_info(DEV, "%s\n", pb);
+	}
+
+	/* solve the race between becoming unconfigured,
+	 * worker doing the cleanup, and
+	 * admin reconfiguring us:
+	 * on (re)configure, first set CONFIG_PENDING,
+	 * then wait for a potentially exiting worker,
+	 * start the worker, and schedule one no_op.
+	 * then proceed with configuration.
+	 */
+	if (ns.disk == D_DISKLESS &&
+	    ns.conn == C_STANDALONE &&
+	    ns.role == R_SECONDARY &&
+	    !test_and_set_bit(CONFIG_PENDING, &mdev->flags))
+		set_bit(DEVICE_DYING, &mdev->flags);
+
+	mdev->state.i = ns.i;
+	wake_up(&mdev->misc_wait);
+	wake_up(&mdev->state_wait);
+
+	/*   post-state-change actions   */
+	if (os.conn >= C_SYNC_SOURCE   && ns.conn <= C_CONNECTED) {
+		set_bit(STOP_SYNC_TIMER, &mdev->flags);
+		mod_timer(&mdev->resync_timer, jiffies);
+	}
+
+	/* aborted verify run. log the last position */
+	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
+	    ns.conn < C_CONNECTED) {
+		mdev->ov_start_sector =
+			BM_BIT_TO_SECT(mdev->rs_total - mdev->ov_left);
+		dev_info(DEV, "Online Verify reached sector %llu\n",
+			(unsigned long long)mdev->ov_start_sector);
+	}
+
+	if ((os.conn == C_PAUSED_SYNC_T || os.conn == C_PAUSED_SYNC_S) &&
+	    (ns.conn == C_SYNC_TARGET  || ns.conn == C_SYNC_SOURCE)) {
+		dev_info(DEV, "Syncer continues.\n");
+		mdev->rs_paused += (long)jiffies-(long)mdev->rs_mark_time;
+		if (ns.conn == C_SYNC_TARGET) {
+			if (!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags))
+				mod_timer(&mdev->resync_timer, jiffies);
+			/* This if (!test_bit) is only needed for the case
+			   that a device that has ceased to used its timer,
+			   i.e. it is already in drbd_resync_finished() gets
+			   paused and resumed. */
+		}
+	}
+
+	if ((os.conn == C_SYNC_TARGET  || os.conn == C_SYNC_SOURCE) &&
+	    (ns.conn == C_PAUSED_SYNC_T || ns.conn == C_PAUSED_SYNC_S)) {
+		dev_info(DEV, "Resync suspended\n");
+		mdev->rs_mark_time = jiffies;
+		if (ns.conn == C_PAUSED_SYNC_T)
+			set_bit(STOP_SYNC_TIMER, &mdev->flags);
+	}
+
+	if (os.conn == C_CONNECTED &&
+	    (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T)) {
+		mdev->ov_position = 0;
+		mdev->rs_total =
+		mdev->rs_mark_left = drbd_bm_bits(mdev);
+		if (mdev->agreed_pro_version >= 90)
+			set_ov_position(mdev, ns.conn);
+		else
+			mdev->ov_start_sector = 0;
+		mdev->ov_left = mdev->rs_total
+			      - BM_SECT_TO_BIT(mdev->ov_position);
+		mdev->rs_start     =
+		mdev->rs_mark_time = jiffies;
+		mdev->ov_last_oos_size = 0;
+		mdev->ov_last_oos_start = 0;
+
+		if (ns.conn == C_VERIFY_S) {
+			dev_info(DEV, "Starting Online Verify from sector %llu\n",
+					(unsigned long long)mdev->ov_position);
+			mod_timer(&mdev->resync_timer, jiffies);
+		}
+	}
+
+	if (get_ldev(mdev)) {
+		u32 mdf = mdev->ldev->md.flags & ~(MDF_CONSISTENT|MDF_PRIMARY_IND|
+						 MDF_CONNECTED_IND|MDF_WAS_UP_TO_DATE|
+						 MDF_PEER_OUT_DATED|MDF_CRASHED_PRIMARY);
+
+		if (test_bit(CRASHED_PRIMARY, &mdev->flags))
+			mdf |= MDF_CRASHED_PRIMARY;
+		if (mdev->state.role == R_PRIMARY ||
+		    (mdev->state.pdsk < D_INCONSISTENT && mdev->state.peer == R_PRIMARY))
+			mdf |= MDF_PRIMARY_IND;
+		if (mdev->state.conn > C_WF_REPORT_PARAMS)
+			mdf |= MDF_CONNECTED_IND;
+		if (mdev->state.disk > D_INCONSISTENT)
+			mdf |= MDF_CONSISTENT;
+		if (mdev->state.disk > D_OUTDATED)
+			mdf |= MDF_WAS_UP_TO_DATE;
+		if (mdev->state.pdsk <= D_OUTDATED && mdev->state.pdsk >= D_INCONSISTENT)
+			mdf |= MDF_PEER_OUT_DATED;
+		if (mdf != mdev->ldev->md.flags) {
+			mdev->ldev->md.flags = mdf;
+			drbd_md_mark_dirty(mdev);
+		}
+		if (os.disk < D_CONSISTENT && ns.disk >= D_CONSISTENT)
+			drbd_set_ed_uuid(mdev, mdev->ldev->md.uuid[UI_CURRENT]);
+		put_ldev(mdev);
+	}
+
+	/* Peer was forced D_UP_TO_DATE & R_PRIMARY, consider to resync */
+	if (os.disk == D_INCONSISTENT && os.pdsk == D_INCONSISTENT &&
+	    os.peer == R_SECONDARY && ns.peer == R_PRIMARY)
+		set_bit(CONSIDER_RESYNC, &mdev->flags);
+
+	/* Receiver should clean up itself */
+	if (os.conn != C_DISCONNECTING && ns.conn == C_DISCONNECTING)
+		drbd_thread_stop_nowait(&mdev->receiver);
+
+	/* Now the receiver finished cleaning up itself, it should die */
+	if (os.conn != C_STANDALONE && ns.conn == C_STANDALONE)
+		drbd_thread_stop_nowait(&mdev->receiver);
+
+	/* Upon network failure, we need to restart the receiver. */
+	if (os.conn > C_TEAR_DOWN &&
+	    ns.conn <= C_TEAR_DOWN && ns.conn >= C_TIMEOUT)
+		drbd_thread_restart_nowait(&mdev->receiver);
+
+	ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
+	if (ascw) {
+		ascw->os = os;
+		ascw->ns = ns;
+		ascw->flags = flags;
+		ascw->w.cb = w_after_state_ch;
+		ascw->done = done;
+		drbd_queue_work(&mdev->data.work, &ascw->w);
+	} else {
+		dev_warn(DEV, "Could not kmalloc an ascw\n");
+	}
+
+	return rv;
+}
+
+static int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct after_state_chg_work *ascw =
+		container_of(w, struct after_state_chg_work, w);
+	after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags);
+	if (ascw->flags & CS_WAIT_COMPLETE) {
+		D_ASSERT(ascw->done != NULL);
+		complete(ascw->done);
+	}
+	kfree(ascw);
+
+	return 1;
+}
+
+static void abw_start_sync(struct drbd_conf *mdev, int rv)
+{
+	if (rv) {
+		dev_err(DEV, "Writing the bitmap failed not starting resync.\n");
+		_drbd_request_state(mdev, NS(conn, C_CONNECTED), CS_VERBOSE);
+		return;
+	}
+
+	switch (mdev->state.conn) {
+	case C_STARTING_SYNC_T:
+		_drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
+		break;
+	case C_STARTING_SYNC_S:
+		drbd_start_resync(mdev, C_SYNC_SOURCE);
+		break;
+	}
+}
+
+/**
+ * after_state_ch() - Perform after state change actions that may sleep
+ * @mdev:	DRBD device.
+ * @os:		old state.
+ * @ns:		new state.
+ * @flags:	Flags
+ */
+static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
+			   union drbd_state ns, enum chg_state_flags flags)
+{
+	enum drbd_fencing_p fp;
+
+	if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
+		clear_bit(CRASHED_PRIMARY, &mdev->flags);
+		if (mdev->p_uuid)
+			mdev->p_uuid[UI_FLAGS] &= ~((u64)2);
+	}
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	/* Inform userspace about the change... */
+	drbd_bcast_state(mdev, ns);
+
+	if (!(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE) &&
+	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
+		drbd_khelper(mdev, "pri-on-incon-degr");
+
+	/* Here we have the actions that are performed after a
+	   state change. This function might sleep */
+
+	if (fp == FP_STONITH && ns.susp) {
+		/* case1: The outdate peer handler is successful:
+		 * case2: The connection was established again: */
+		if ((os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) ||
+		    (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)) {
+			tl_clear(mdev);
+			spin_lock_irq(&mdev->req_lock);
+			_drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
+			spin_unlock_irq(&mdev->req_lock);
+		}
+	}
+	/* Do not change the order of the if above and the two below... */
+	if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) {      /* attach on the peer */
+		drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+	}
+	if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S)
+		drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL, "send_bitmap (WFBitMapS)");
+
+	/* Lost contact to peer's copy of the data */
+	if ((os.pdsk >= D_INCONSISTENT &&
+	     os.pdsk != D_UNKNOWN &&
+	     os.pdsk != D_OUTDATED)
+	&&  (ns.pdsk < D_INCONSISTENT ||
+	     ns.pdsk == D_UNKNOWN ||
+	     ns.pdsk == D_OUTDATED)) {
+		kfree(mdev->p_uuid);
+		mdev->p_uuid = NULL;
+		if (get_ldev(mdev)) {
+			if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
+			    mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
+				drbd_uuid_new_current(mdev);
+				drbd_send_uuids(mdev);
+			}
+			put_ldev(mdev);
+		}
+	}
+
+	if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) {
+		if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0)
+			drbd_uuid_new_current(mdev);
+
+		/* D_DISKLESS Peer becomes secondary */
+		if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
+			drbd_al_to_on_disk_bm(mdev);
+		put_ldev(mdev);
+	}
+
+	/* Last part of the attaching process ... */
+	if (ns.conn >= C_CONNECTED &&
+	    os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) {
+		kfree(mdev->p_uuid); /* We expect to receive up-to-date UUIDs soon. */
+		mdev->p_uuid = NULL; /* ...to not use the old ones in the mean time */
+		drbd_send_sizes(mdev, 0);  /* to start sync... */
+		drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+	}
+
+	/* We want to pause/continue resync, tell peer. */
+	if (ns.conn >= C_CONNECTED &&
+	     ((os.aftr_isp != ns.aftr_isp) ||
+	      (os.user_isp != ns.user_isp)))
+		drbd_send_state(mdev);
+
+	/* In case one of the isp bits got set, suspend other devices. */
+	if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) &&
+	    (ns.aftr_isp || ns.peer_isp || ns.user_isp))
+		suspend_other_sg(mdev);
+
+	/* Make sure the peer gets informed about eventual state
+	   changes (ISP bits) while we were in WFReportParams. */
+	if (os.conn == C_WF_REPORT_PARAMS && ns.conn >= C_CONNECTED)
+		drbd_send_state(mdev);
+
+	/* We are in the progress to start a full sync... */
+	if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
+	    (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S))
+		drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, &abw_start_sync, "set_n_write from StartingSync");
+
+	/* We are invalidating our self... */
+	if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED &&
+	    os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT)
+		drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate");
+
+	if (os.disk > D_FAILED && ns.disk == D_FAILED) {
+		enum drbd_io_error_p eh;
+
+		eh = EP_PASS_ON;
+		if (get_ldev_if_state(mdev, D_FAILED)) {
+			eh = mdev->ldev->dc.on_io_error;
+			put_ldev(mdev);
+		}
+
+		drbd_rs_cancel_all(mdev);
+		/* since get_ldev() only works as long as disk>=D_INCONSISTENT,
+		   and it is D_DISKLESS here, local_cnt can only go down, it can
+		   not increase... It will reach zero */
+		wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
+		mdev->rs_total = 0;
+		mdev->rs_failed = 0;
+		atomic_set(&mdev->rs_pending_cnt, 0);
+
+		spin_lock_irq(&mdev->req_lock);
+		_drbd_set_state(_NS(mdev, disk, D_DISKLESS), CS_HARD, NULL);
+		spin_unlock_irq(&mdev->req_lock);
+
+		if (eh == EP_CALL_HELPER)
+			drbd_khelper(mdev, "local-io-error");
+	}
+
+	if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) {
+
+		if (os.disk == D_FAILED) /* && ns.disk == D_DISKLESS*/ {
+			if (drbd_send_state(mdev))
+				dev_warn(DEV, "Notified peer that my disk is broken.\n");
+			else
+				dev_err(DEV, "Sending state in drbd_io_error() failed\n");
+		}
+
+		wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
+		lc_destroy(mdev->resync);
+		mdev->resync = NULL;
+		lc_destroy(mdev->act_log);
+		mdev->act_log = NULL;
+		__no_warn(local,
+			drbd_free_bc(mdev->ldev);
+			mdev->ldev = NULL;);
+
+		if (mdev->md_io_tmpp)
+			__free_page(mdev->md_io_tmpp);
+	}
+
+	/* Disks got bigger while they were detached */
+	if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
+	    test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) {
+		if (ns.conn == C_CONNECTED)
+			resync_after_online_grow(mdev);
+	}
+
+	/* A resync finished or aborted, wake paused devices... */
+	if ((os.conn > C_CONNECTED && ns.conn <= C_CONNECTED) ||
+	    (os.peer_isp && !ns.peer_isp) ||
+	    (os.user_isp && !ns.user_isp))
+		resume_next_sg(mdev);
+
+	/* Upon network connection, we need to start the receiver */
+	if (os.conn == C_STANDALONE && ns.conn == C_UNCONNECTED)
+		drbd_thread_start(&mdev->receiver);
+
+	/* Terminate worker thread if we are unconfigured - it will be
+	   restarted as needed... */
+	if (ns.disk == D_DISKLESS &&
+	    ns.conn == C_STANDALONE &&
+	    ns.role == R_SECONDARY) {
+		if (os.aftr_isp != ns.aftr_isp)
+			resume_next_sg(mdev);
+		/* set in __drbd_set_state, unless CONFIG_PENDING was set */
+		if (test_bit(DEVICE_DYING, &mdev->flags))
+			drbd_thread_stop_nowait(&mdev->worker);
+	}
+
+	drbd_md_sync(mdev);
+}
+
+
+static int drbd_thread_setup(void *arg)
+{
+	struct drbd_thread *thi = (struct drbd_thread *) arg;
+	struct drbd_conf *mdev = thi->mdev;
+	unsigned long flags;
+	int retval;
+
+restart:
+	retval = thi->function(thi);
+
+	spin_lock_irqsave(&thi->t_lock, flags);
+
+	/* if the receiver has been "Exiting", the last thing it did
+	 * was set the conn state to "StandAlone",
+	 * if now a re-connect request comes in, conn state goes C_UNCONNECTED,
+	 * and receiver thread will be "started".
+	 * drbd_thread_start needs to set "Restarting" in that case.
+	 * t_state check and assignment needs to be within the same spinlock,
+	 * so either thread_start sees Exiting, and can remap to Restarting,
+	 * or thread_start see None, and can proceed as normal.
+	 */
+
+	if (thi->t_state == Restarting) {
+		dev_info(DEV, "Restarting %s\n", current->comm);
+		thi->t_state = Running;
+		spin_unlock_irqrestore(&thi->t_lock, flags);
+		goto restart;
+	}
+
+	thi->task = NULL;
+	thi->t_state = None;
+	smp_mb();
+	complete(&thi->stop);
+	spin_unlock_irqrestore(&thi->t_lock, flags);
+
+	dev_info(DEV, "Terminating %s\n", current->comm);
+
+	/* Release mod reference taken when thread was started */
+	module_put(THIS_MODULE);
+	return retval;
+}
+
+static void drbd_thread_init(struct drbd_conf *mdev, struct drbd_thread *thi,
+		      int (*func) (struct drbd_thread *))
+{
+	spin_lock_init(&thi->t_lock);
+	thi->task    = NULL;
+	thi->t_state = None;
+	thi->function = func;
+	thi->mdev = mdev;
+}
+
+int drbd_thread_start(struct drbd_thread *thi)
+{
+	struct drbd_conf *mdev = thi->mdev;
+	struct task_struct *nt;
+	unsigned long flags;
+
+	const char *me =
+		thi == &mdev->receiver ? "receiver" :
+		thi == &mdev->asender  ? "asender"  :
+		thi == &mdev->worker   ? "worker"   : "NONSENSE";
+
+	/* is used from state engine doing drbd_thread_stop_nowait,
+	 * while holding the req lock irqsave */
+	spin_lock_irqsave(&thi->t_lock, flags);
+
+	switch (thi->t_state) {
+	case None:
+		dev_info(DEV, "Starting %s thread (from %s [%d])\n",
+				me, current->comm, current->pid);
+
+		/* Get ref on module for thread - this is released when thread exits */
+		if (!try_module_get(THIS_MODULE)) {
+			dev_err(DEV, "Failed to get module reference in drbd_thread_start\n");
+			spin_unlock_irqrestore(&thi->t_lock, flags);
+			return FALSE;
+		}
+
+		init_completion(&thi->stop);
+		D_ASSERT(thi->task == NULL);
+		thi->reset_cpu_mask = 1;
+		thi->t_state = Running;
+		spin_unlock_irqrestore(&thi->t_lock, flags);
+		flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
+
+		nt = kthread_create(drbd_thread_setup, (void *) thi,
+				    "drbd%d_%s", mdev_to_minor(mdev), me);
+
+		if (IS_ERR(nt)) {
+			dev_err(DEV, "Couldn't start thread\n");
+
+			module_put(THIS_MODULE);
+			return FALSE;
+		}
+		spin_lock_irqsave(&thi->t_lock, flags);
+		thi->task = nt;
+		thi->t_state = Running;
+		spin_unlock_irqrestore(&thi->t_lock, flags);
+		wake_up_process(nt);
+		break;
+	case Exiting:
+		thi->t_state = Restarting;
+		dev_info(DEV, "Restarting %s thread (from %s [%d])\n",
+				me, current->comm, current->pid);
+		/* fall through */
+	case Running:
+	case Restarting:
+	default:
+		spin_unlock_irqrestore(&thi->t_lock, flags);
+		break;
+	}
+
+	return TRUE;
+}
+
+
+void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
+{
+	unsigned long flags;
+
+	enum drbd_thread_state ns = restart ? Restarting : Exiting;
+
+	/* may be called from state engine, holding the req lock irqsave */
+	spin_lock_irqsave(&thi->t_lock, flags);
+
+	if (thi->t_state == None) {
+		spin_unlock_irqrestore(&thi->t_lock, flags);
+		if (restart)
+			drbd_thread_start(thi);
+		return;
+	}
+
+	if (thi->t_state != ns) {
+		if (thi->task == NULL) {
+			spin_unlock_irqrestore(&thi->t_lock, flags);
+			return;
+		}
+
+		thi->t_state = ns;
+		smp_mb();
+		init_completion(&thi->stop);
+		if (thi->task != current)
+			force_sig(DRBD_SIGKILL, thi->task);
+
+	}
+
+	spin_unlock_irqrestore(&thi->t_lock, flags);
+
+	if (wait)
+		wait_for_completion(&thi->stop);
+}
+
+#ifdef CONFIG_SMP
+/**
+ * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
+ * @mdev:	DRBD device.
+ *
+ * Forces all threads of a device onto the same CPU. This is beneficial for
+ * DRBD's performance. May be overwritten by user's configuration.
+ */
+void drbd_calc_cpu_mask(struct drbd_conf *mdev)
+{
+	int ord, cpu;
+
+	/* user override. */
+	if (cpumask_weight(mdev->cpu_mask))
+		return;
+
+	ord = mdev_to_minor(mdev) % cpumask_weight(cpu_online_mask);
+	for_each_online_cpu(cpu) {
+		if (ord-- == 0) {
+			cpumask_set_cpu(cpu, mdev->cpu_mask);
+			return;
+		}
+	}
+	/* should not be reached */
+	cpumask_setall(mdev->cpu_mask);
+}
+
+/**
+ * drbd_thread_current_set_cpu() - modifies the cpu mask of the _current_ thread
+ * @mdev:	DRBD device.
+ *
+ * call in the "main loop" of _all_ threads, no need for any mutex, current won't die
+ * prematurely.
+ */
+void drbd_thread_current_set_cpu(struct drbd_conf *mdev)
+{
+	struct task_struct *p = current;
+	struct drbd_thread *thi =
+		p == mdev->asender.task  ? &mdev->asender  :
+		p == mdev->receiver.task ? &mdev->receiver :
+		p == mdev->worker.task   ? &mdev->worker   :
+		NULL;
+	ERR_IF(thi == NULL)
+		return;
+	if (!thi->reset_cpu_mask)
+		return;
+	thi->reset_cpu_mask = 0;
+	set_cpus_allowed_ptr(p, mdev->cpu_mask);
+}
+#endif
+
+/* the appropriate socket mutex must be held already */
+int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
+			  enum drbd_packets cmd, struct p_header *h,
+			  size_t size, unsigned msg_flags)
+{
+	int sent, ok;
+
+	ERR_IF(!h) return FALSE;
+	ERR_IF(!size) return FALSE;
+
+	h->magic   = BE_DRBD_MAGIC;
+	h->command = cpu_to_be16(cmd);
+	h->length  = cpu_to_be16(size-sizeof(struct p_header));
+
+	sent = drbd_send(mdev, sock, h, size, msg_flags);
+
+	ok = (sent == size);
+	if (!ok)
+		dev_err(DEV, "short sent %s size=%d sent=%d\n",
+		    cmdname(cmd), (int)size, sent);
+	return ok;
+}
+
+/* don't pass the socket. we may only look at it
+ * when we hold the appropriate socket mutex.
+ */
+int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket,
+		  enum drbd_packets cmd, struct p_header *h, size_t size)
+{
+	int ok = 0;
+	struct socket *sock;
+
+	if (use_data_socket) {
+		mutex_lock(&mdev->data.mutex);
+		sock = mdev->data.socket;
+	} else {
+		mutex_lock(&mdev->meta.mutex);
+		sock = mdev->meta.socket;
+	}
+
+	/* drbd_disconnect() could have called drbd_free_sock()
+	 * while we were waiting in down()... */
+	if (likely(sock != NULL))
+		ok = _drbd_send_cmd(mdev, sock, cmd, h, size, 0);
+
+	if (use_data_socket)
+		mutex_unlock(&mdev->data.mutex);
+	else
+		mutex_unlock(&mdev->meta.mutex);
+	return ok;
+}
+
+int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
+		   size_t size)
+{
+	struct p_header h;
+	int ok;
+
+	h.magic   = BE_DRBD_MAGIC;
+	h.command = cpu_to_be16(cmd);
+	h.length  = cpu_to_be16(size);
+
+	if (!drbd_get_data_sock(mdev))
+		return 0;
+
+	ok = (sizeof(h) ==
+		drbd_send(mdev, mdev->data.socket, &h, sizeof(h), 0));
+	ok = ok && (size ==
+		drbd_send(mdev, mdev->data.socket, data, size, 0));
+
+	drbd_put_data_sock(mdev);
+
+	return ok;
+}
+
+int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
+{
+	struct p_rs_param_89 *p;
+	struct socket *sock;
+	int size, rv;
+	const int apv = mdev->agreed_pro_version;
+
+	size = apv <= 87 ? sizeof(struct p_rs_param)
+		: apv == 88 ? sizeof(struct p_rs_param)
+			+ strlen(mdev->sync_conf.verify_alg) + 1
+		: /* 89 */    sizeof(struct p_rs_param_89);
+
+	/* used from admin command context and receiver/worker context.
+	 * to avoid kmalloc, grab the socket right here,
+	 * then use the pre-allocated sbuf there */
+	mutex_lock(&mdev->data.mutex);
+	sock = mdev->data.socket;
+
+	if (likely(sock != NULL)) {
+		enum drbd_packets cmd = apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM;
+
+		p = &mdev->data.sbuf.rs_param_89;
+
+		/* initialize verify_alg and csums_alg */
+		memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
+
+		p->rate = cpu_to_be32(sc->rate);
+
+		if (apv >= 88)
+			strcpy(p->verify_alg, mdev->sync_conf.verify_alg);
+		if (apv >= 89)
+			strcpy(p->csums_alg, mdev->sync_conf.csums_alg);
+
+		rv = _drbd_send_cmd(mdev, sock, cmd, &p->head, size, 0);
+	} else
+		rv = 0; /* not ok */
+
+	mutex_unlock(&mdev->data.mutex);
+
+	return rv;
+}
+
+int drbd_send_protocol(struct drbd_conf *mdev)
+{
+	struct p_protocol *p;
+	int size, rv;
+
+	size = sizeof(struct p_protocol);
+
+	if (mdev->agreed_pro_version >= 87)
+		size += strlen(mdev->net_conf->integrity_alg) + 1;
+
+	/* we must not recurse into our own queue,
+	 * as that is blocked during handshake */
+	p = kmalloc(size, GFP_NOIO);
+	if (p == NULL)
+		return 0;
+
+	p->protocol      = cpu_to_be32(mdev->net_conf->wire_protocol);
+	p->after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
+	p->after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
+	p->after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
+	p->want_lose     = cpu_to_be32(mdev->net_conf->want_lose);
+	p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
+
+	if (mdev->agreed_pro_version >= 87)
+		strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
+
+	rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_PROTOCOL,
+			   (struct p_header *)p, size);
+	kfree(p);
+	return rv;
+}
+
+int _drbd_send_uuids(struct drbd_conf *mdev, u64 uuid_flags)
+{
+	struct p_uuids p;
+	int i;
+
+	if (!get_ldev_if_state(mdev, D_NEGOTIATING))
+		return 1;
+
+	for (i = UI_CURRENT; i < UI_SIZE; i++)
+		p.uuid[i] = mdev->ldev ? cpu_to_be64(mdev->ldev->md.uuid[i]) : 0;
+
+	mdev->comm_bm_set = drbd_bm_total_weight(mdev);
+	p.uuid[UI_SIZE] = cpu_to_be64(mdev->comm_bm_set);
+	uuid_flags |= mdev->net_conf->want_lose ? 1 : 0;
+	uuid_flags |= test_bit(CRASHED_PRIMARY, &mdev->flags) ? 2 : 0;
+	uuid_flags |= mdev->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
+	p.uuid[UI_FLAGS] = cpu_to_be64(uuid_flags);
+
+	put_ldev(mdev);
+
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_UUIDS,
+			     (struct p_header *)&p, sizeof(p));
+}
+
+int drbd_send_uuids(struct drbd_conf *mdev)
+{
+	return _drbd_send_uuids(mdev, 0);
+}
+
+int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev)
+{
+	return _drbd_send_uuids(mdev, 8);
+}
+
+
+int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val)
+{
+	struct p_rs_uuid p;
+
+	p.uuid = cpu_to_be64(val);
+
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SYNC_UUID,
+			     (struct p_header *)&p, sizeof(p));
+}
+
+int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply)
+{
+	struct p_sizes p;
+	sector_t d_size, u_size;
+	int q_order_type;
+	int ok;
+
+	if (get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		D_ASSERT(mdev->ldev->backing_bdev);
+		d_size = drbd_get_max_capacity(mdev->ldev);
+		u_size = mdev->ldev->dc.disk_size;
+		q_order_type = drbd_queue_order_type(mdev);
+		p.queue_order_type = cpu_to_be32(drbd_queue_order_type(mdev));
+		put_ldev(mdev);
+	} else {
+		d_size = 0;
+		u_size = 0;
+		q_order_type = QUEUE_ORDERED_NONE;
+	}
+
+	p.d_size = cpu_to_be64(d_size);
+	p.u_size = cpu_to_be64(u_size);
+	p.c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev));
+	p.max_segment_size = cpu_to_be32(queue_max_segment_size(mdev->rq_queue));
+	p.queue_order_type = cpu_to_be32(q_order_type);
+
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SIZES,
+			   (struct p_header *)&p, sizeof(p));
+	return ok;
+}
+
+/**
+ * drbd_send_state() - Sends the drbd state to the peer
+ * @mdev:	DRBD device.
+ */
+int drbd_send_state(struct drbd_conf *mdev)
+{
+	struct socket *sock;
+	struct p_state p;
+	int ok = 0;
+
+	/* Grab state lock so we wont send state if we're in the middle
+	 * of a cluster wide state change on another thread */
+	drbd_state_lock(mdev);
+
+	mutex_lock(&mdev->data.mutex);
+
+	p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */
+	sock = mdev->data.socket;
+
+	if (likely(sock != NULL)) {
+		ok = _drbd_send_cmd(mdev, sock, P_STATE,
+				    (struct p_header *)&p, sizeof(p), 0);
+	}
+
+	mutex_unlock(&mdev->data.mutex);
+
+	drbd_state_unlock(mdev);
+	return ok;
+}
+
+int drbd_send_state_req(struct drbd_conf *mdev,
+	union drbd_state mask, union drbd_state val)
+{
+	struct p_req_state p;
+
+	p.mask    = cpu_to_be32(mask.i);
+	p.val     = cpu_to_be32(val.i);
+
+	return drbd_send_cmd(mdev, USE_DATA_SOCKET, P_STATE_CHG_REQ,
+			     (struct p_header *)&p, sizeof(p));
+}
+
+int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode)
+{
+	struct p_req_state_reply p;
+
+	p.retcode    = cpu_to_be32(retcode);
+
+	return drbd_send_cmd(mdev, USE_META_SOCKET, P_STATE_CHG_REPLY,
+			     (struct p_header *)&p, sizeof(p));
+}
+
+int fill_bitmap_rle_bits(struct drbd_conf *mdev,
+	struct p_compressed_bm *p,
+	struct bm_xfer_ctx *c)
+{
+	struct bitstream bs;
+	unsigned long plain_bits;
+	unsigned long tmp;
+	unsigned long rl;
+	unsigned len;
+	unsigned toggle;
+	int bits;
+
+	/* may we use this feature? */
+	if ((mdev->sync_conf.use_rle == 0) ||
+		(mdev->agreed_pro_version < 90))
+			return 0;
+
+	if (c->bit_offset >= c->bm_bits)
+		return 0; /* nothing to do. */
+
+	/* use at most thus many bytes */
+	bitstream_init(&bs, p->code, BM_PACKET_VLI_BYTES_MAX, 0);
+	memset(p->code, 0, BM_PACKET_VLI_BYTES_MAX);
+	/* plain bits covered in this code string */
+	plain_bits = 0;
+
+	/* p->encoding & 0x80 stores whether the first run length is set.
+	 * bit offset is implicit.
+	 * start with toggle == 2 to be able to tell the first iteration */
+	toggle = 2;
+
+	/* see how much plain bits we can stuff into one packet
+	 * using RLE and VLI. */
+	do {
+		tmp = (toggle == 0) ? _drbd_bm_find_next_zero(mdev, c->bit_offset)
+				    : _drbd_bm_find_next(mdev, c->bit_offset);
+		if (tmp == -1UL)
+			tmp = c->bm_bits;
+		rl = tmp - c->bit_offset;
+
+		if (toggle == 2) { /* first iteration */
+			if (rl == 0) {
+				/* the first checked bit was set,
+				 * store start value, */
+				DCBP_set_start(p, 1);
+				/* but skip encoding of zero run length */
+				toggle = !toggle;
+				continue;
+			}
+			DCBP_set_start(p, 0);
+		}
+
+		/* paranoia: catch zero runlength.
+		 * can only happen if bitmap is modified while we scan it. */
+		if (rl == 0) {
+			dev_err(DEV, "unexpected zero runlength while encoding bitmap "
+			    "t:%u bo:%lu\n", toggle, c->bit_offset);
+			return -1;
+		}
+
+		bits = vli_encode_bits(&bs, rl);
+		if (bits == -ENOBUFS) /* buffer full */
+			break;
+		if (bits <= 0) {
+			dev_err(DEV, "error while encoding bitmap: %d\n", bits);
+			return 0;
+		}
+
+		toggle = !toggle;
+		plain_bits += rl;
+		c->bit_offset = tmp;
+	} while (c->bit_offset < c->bm_bits);
+
+	len = bs.cur.b - p->code + !!bs.cur.bit;
+
+	if (plain_bits < (len << 3)) {
+		/* incompressible with this method.
+		 * we need to rewind both word and bit position. */
+		c->bit_offset -= plain_bits;
+		bm_xfer_ctx_bit_to_word_offset(c);
+		c->bit_offset = c->word_offset * BITS_PER_LONG;
+		return 0;
+	}
+
+	/* RLE + VLI was able to compress it just fine.
+	 * update c->word_offset. */
+	bm_xfer_ctx_bit_to_word_offset(c);
+
+	/* store pad_bits */
+	DCBP_set_pad_bits(p, (8 - bs.cur.bit) & 0x7);
+
+	return len;
+}
+
+enum { OK, FAILED, DONE }
+send_bitmap_rle_or_plain(struct drbd_conf *mdev,
+	struct p_header *h, struct bm_xfer_ctx *c)
+{
+	struct p_compressed_bm *p = (void*)h;
+	unsigned long num_words;
+	int len;
+	int ok;
+
+	len = fill_bitmap_rle_bits(mdev, p, c);
+
+	if (len < 0)
+		return FAILED;
+
+	if (len) {
+		DCBP_set_code(p, RLE_VLI_Bits);
+		ok = _drbd_send_cmd(mdev, mdev->data.socket, P_COMPRESSED_BITMAP, h,
+			sizeof(*p) + len, 0);
+
+		c->packets[0]++;
+		c->bytes[0] += sizeof(*p) + len;
+
+		if (c->bit_offset >= c->bm_bits)
+			len = 0; /* DONE */
+	} else {
+		/* was not compressible.
+		 * send a buffer full of plain text bits instead. */
+		num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
+		len = num_words * sizeof(long);
+		if (len)
+			drbd_bm_get_lel(mdev, c->word_offset, num_words, (unsigned long*)h->payload);
+		ok = _drbd_send_cmd(mdev, mdev->data.socket, P_BITMAP,
+				   h, sizeof(struct p_header) + len, 0);
+		c->word_offset += num_words;
+		c->bit_offset = c->word_offset * BITS_PER_LONG;
+
+		c->packets[1]++;
+		c->bytes[1] += sizeof(struct p_header) + len;
+
+		if (c->bit_offset > c->bm_bits)
+			c->bit_offset = c->bm_bits;
+	}
+	ok = ok ? ((len == 0) ? DONE : OK) : FAILED;
+
+	if (ok == DONE)
+		INFO_bm_xfer_stats(mdev, "send", c);
+	return ok;
+}
+
+/* See the comment at receive_bitmap() */
+int _drbd_send_bitmap(struct drbd_conf *mdev)
+{
+	struct bm_xfer_ctx c;
+	struct p_header *p;
+	int ret;
+
+	ERR_IF(!mdev->bitmap) return FALSE;
+
+	/* maybe we should use some per thread scratch page,
+	 * and allocate that during initial device creation? */
+	p = (struct p_header *) __get_free_page(GFP_NOIO);
+	if (!p) {
+		dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
+		return FALSE;
+	}
+
+	if (get_ldev(mdev)) {
+		if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC)) {
+			dev_info(DEV, "Writing the whole bitmap, MDF_FullSync was set.\n");
+			drbd_bm_set_all(mdev);
+			if (drbd_bm_write(mdev)) {
+				/* write_bm did fail! Leave full sync flag set in Meta P_DATA
+				 * but otherwise process as per normal - need to tell other
+				 * side that a full resync is required! */
+				dev_err(DEV, "Failed to write bitmap to disk!\n");
+			} else {
+				drbd_md_clear_flag(mdev, MDF_FULL_SYNC);
+				drbd_md_sync(mdev);
+			}
+		}
+		put_ldev(mdev);
+	}
+
+	c = (struct bm_xfer_ctx) {
+		.bm_bits = drbd_bm_bits(mdev),
+		.bm_words = drbd_bm_words(mdev),
+	};
+
+	do {
+		ret = send_bitmap_rle_or_plain(mdev, p, &c);
+	} while (ret == OK);
+
+	free_page((unsigned long) p);
+	return (ret == DONE);
+}
+
+int drbd_send_bitmap(struct drbd_conf *mdev)
+{
+	int err;
+
+	if (!drbd_get_data_sock(mdev))
+		return -1;
+	err = !_drbd_send_bitmap(mdev);
+	drbd_put_data_sock(mdev);
+	return err;
+}
+
+int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size)
+{
+	int ok;
+	struct p_barrier_ack p;
+
+	p.barrier  = barrier_nr;
+	p.set_size = cpu_to_be32(set_size);
+
+	if (mdev->state.conn < C_CONNECTED)
+		return FALSE;
+	ok = drbd_send_cmd(mdev, USE_META_SOCKET, P_BARRIER_ACK,
+			(struct p_header *)&p, sizeof(p));
+	return ok;
+}
+
+/**
+ * _drbd_send_ack() - Sends an ack packet
+ * @mdev:	DRBD device.
+ * @cmd:	Packet command code.
+ * @sector:	sector, needs to be in big endian byte order
+ * @blksize:	size in byte, needs to be in big endian byte order
+ * @block_id:	Id, big endian byte order
+ */
+static int _drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd,
+			  u64 sector,
+			  u32 blksize,
+			  u64 block_id)
+{
+	int ok;
+	struct p_block_ack p;
+
+	p.sector   = sector;
+	p.block_id = block_id;
+	p.blksize  = blksize;
+	p.seq_num  = cpu_to_be32(atomic_add_return(1, &mdev->packet_seq));
+
+	if (!mdev->meta.socket || mdev->state.conn < C_CONNECTED)
+		return FALSE;
+	ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd,
+				(struct p_header *)&p, sizeof(p));
+	return ok;
+}
+
+int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd,
+		     struct p_data *dp)
+{
+	const int header_size = sizeof(struct p_data)
+			      - sizeof(struct p_header);
+	int data_size  = ((struct p_header *)dp)->length - header_size;
+
+	return _drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size),
+			      dp->block_id);
+}
+
+int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd,
+		     struct p_block_req *rp)
+{
+	return _drbd_send_ack(mdev, cmd, rp->sector, rp->blksize, rp->block_id);
+}
+
+/**
+ * drbd_send_ack() - Sends an ack packet
+ * @mdev:	DRBD device.
+ * @cmd:	Packet command code.
+ * @e:		Epoch entry.
+ */
+int drbd_send_ack(struct drbd_conf *mdev,
+	enum drbd_packets cmd, struct drbd_epoch_entry *e)
+{
+	return _drbd_send_ack(mdev, cmd,
+			      cpu_to_be64(e->sector),
+			      cpu_to_be32(e->size),
+			      e->block_id);
+}
+
+/* This function misuses the block_id field to signal if the blocks
+ * are is sync or not. */
+int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd,
+		     sector_t sector, int blksize, u64 block_id)
+{
+	return _drbd_send_ack(mdev, cmd,
+			      cpu_to_be64(sector),
+			      cpu_to_be32(blksize),
+			      cpu_to_be64(block_id));
+}
+
+int drbd_send_drequest(struct drbd_conf *mdev, int cmd,
+		       sector_t sector, int size, u64 block_id)
+{
+	int ok;
+	struct p_block_req p;
+
+	p.sector   = cpu_to_be64(sector);
+	p.block_id = block_id;
+	p.blksize  = cpu_to_be32(size);
+
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd,
+				(struct p_header *)&p, sizeof(p));
+	return ok;
+}
+
+int drbd_send_drequest_csum(struct drbd_conf *mdev,
+			    sector_t sector, int size,
+			    void *digest, int digest_size,
+			    enum drbd_packets cmd)
+{
+	int ok;
+	struct p_block_req p;
+
+	p.sector   = cpu_to_be64(sector);
+	p.block_id = BE_DRBD_MAGIC + 0xbeef;
+	p.blksize  = cpu_to_be32(size);
+
+	p.head.magic   = BE_DRBD_MAGIC;
+	p.head.command = cpu_to_be16(cmd);
+	p.head.length  = cpu_to_be16(sizeof(p) - sizeof(struct p_header) + digest_size);
+
+	mutex_lock(&mdev->data.mutex);
+
+	ok = (sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, sizeof(p), 0));
+	ok = ok && (digest_size == drbd_send(mdev, mdev->data.socket, digest, digest_size, 0));
+
+	mutex_unlock(&mdev->data.mutex);
+
+	return ok;
+}
+
+int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size)
+{
+	int ok;
+	struct p_block_req p;
+
+	p.sector   = cpu_to_be64(sector);
+	p.block_id = BE_DRBD_MAGIC + 0xbabe;
+	p.blksize  = cpu_to_be32(size);
+
+	ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_OV_REQUEST,
+			   (struct p_header *)&p, sizeof(p));
+	return ok;
+}
+
+/* called on sndtimeo
+ * returns FALSE if we should retry,
+ * TRUE if we think connection is dead
+ */
+static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *sock)
+{
+	int drop_it;
+	/* long elapsed = (long)(jiffies - mdev->last_received); */
+
+	drop_it =   mdev->meta.socket == sock
+		|| !mdev->asender.task
+		|| get_t_state(&mdev->asender) != Running
+		|| mdev->state.conn < C_CONNECTED;
+
+	if (drop_it)
+		return TRUE;
+
+	drop_it = !--mdev->ko_count;
+	if (!drop_it) {
+		dev_err(DEV, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
+		       current->comm, current->pid, mdev->ko_count);
+		request_ping(mdev);
+	}
+
+	return drop_it; /* && (mdev->state == R_PRIMARY) */;
+}
+
+/* The idea of sendpage seems to be to put some kind of reference
+ * to the page into the skb, and to hand it over to the NIC. In
+ * this process get_page() gets called.
+ *
+ * As soon as the page was really sent over the network put_page()
+ * gets called by some part of the network layer. [ NIC driver? ]
+ *
+ * [ get_page() / put_page() increment/decrement the count. If count
+ *   reaches 0 the page will be freed. ]
+ *
+ * This works nicely with pages from FSs.
+ * But this means that in protocol A we might signal IO completion too early!
+ *
+ * In order not to corrupt data during a resync we must make sure
+ * that we do not reuse our own buffer pages (EEs) to early, therefore
+ * we have the net_ee list.
+ *
+ * XFS seems to have problems, still, it submits pages with page_count == 0!
+ * As a workaround, we disable sendpage on pages
+ * with page_count == 0 or PageSlab.
+ */
+static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page,
+		   int offset, size_t size)
+{
+	int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0);
+	kunmap(page);
+	if (sent == size)
+		mdev->send_cnt += size>>9;
+	return sent == size;
+}
+
+static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
+		    int offset, size_t size)
+{
+	mm_segment_t oldfs = get_fs();
+	int sent, ok;
+	int len = size;
+
+	/* e.g. XFS meta- & log-data is in slab pages, which have a
+	 * page_count of 0 and/or have PageSlab() set.
+	 * we cannot use send_page for those, as that does get_page();
+	 * put_page(); and would cause either a VM_BUG directly, or
+	 * __page_cache_release a page that would actually still be referenced
+	 * by someone, leading to some obscure delayed Oops somewhere else. */
+	if (disable_sendpage || (page_count(page) < 1) || PageSlab(page))
+		return _drbd_no_send_page(mdev, page, offset, size);
+
+	drbd_update_congested(mdev);
+	set_fs(KERNEL_DS);
+	do {
+		sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page,
+							offset, len,
+							MSG_NOSIGNAL);
+		if (sent == -EAGAIN) {
+			if (we_should_drop_the_connection(mdev,
+							  mdev->data.socket))
+				break;
+			else
+				continue;
+		}
+		if (sent <= 0) {
+			dev_warn(DEV, "%s: size=%d len=%d sent=%d\n",
+			     __func__, (int)size, len, sent);
+			break;
+		}
+		len    -= sent;
+		offset += sent;
+	} while (len > 0 /* THINK && mdev->cstate >= C_CONNECTED*/);
+	set_fs(oldfs);
+	clear_bit(NET_CONGESTED, &mdev->flags);
+
+	ok = (len == 0);
+	if (likely(ok))
+		mdev->send_cnt += size>>9;
+	return ok;
+}
+
+static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
+{
+	struct bio_vec *bvec;
+	int i;
+	__bio_for_each_segment(bvec, bio, i, 0) {
+		if (!_drbd_no_send_page(mdev, bvec->bv_page,
+				     bvec->bv_offset, bvec->bv_len))
+			return 0;
+	}
+	return 1;
+}
+
+static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
+{
+	struct bio_vec *bvec;
+	int i;
+	__bio_for_each_segment(bvec, bio, i, 0) {
+		if (!_drbd_send_page(mdev, bvec->bv_page,
+				     bvec->bv_offset, bvec->bv_len))
+			return 0;
+	}
+
+	return 1;
+}
+
+/* Used to send write requests
+ * R_PRIMARY -> Peer	(P_DATA)
+ */
+int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
+{
+	int ok = 1;
+	struct p_data p;
+	unsigned int dp_flags = 0;
+	void *dgb;
+	int dgs;
+
+	if (!drbd_get_data_sock(mdev))
+		return 0;
+
+	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
+		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
+
+	p.head.magic   = BE_DRBD_MAGIC;
+	p.head.command = cpu_to_be16(P_DATA);
+	p.head.length  =
+		cpu_to_be16(sizeof(p) - sizeof(struct p_header) + dgs + req->size);
+
+	p.sector   = cpu_to_be64(req->sector);
+	p.block_id = (unsigned long)req;
+	p.seq_num  = cpu_to_be32(req->seq_num =
+				 atomic_add_return(1, &mdev->packet_seq));
+	dp_flags = 0;
+
+	/* NOTE: no need to check if barriers supported here as we would
+	 *       not pass the test in make_request_common in that case
+	 */
+	if (bio_rw_flagged(req->master_bio, BIO_RW_BARRIER)) {
+		dev_err(DEV, "ASSERT FAILED would have set DP_HARDBARRIER\n");
+		/* dp_flags |= DP_HARDBARRIER; */
+	}
+	if (bio_rw_flagged(req->master_bio, BIO_RW_SYNCIO))
+		dp_flags |= DP_RW_SYNC;
+	/* for now handle SYNCIO and UNPLUG
+	 * as if they still were one and the same flag */
+	if (bio_rw_flagged(req->master_bio, BIO_RW_UNPLUG))
+		dp_flags |= DP_RW_SYNC;
+	if (mdev->state.conn >= C_SYNC_SOURCE &&
+	    mdev->state.conn <= C_PAUSED_SYNC_T)
+		dp_flags |= DP_MAY_SET_IN_SYNC;
+
+	p.dp_flags = cpu_to_be32(dp_flags);
+	set_bit(UNPLUG_REMOTE, &mdev->flags);
+	ok = (sizeof(p) ==
+		drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE));
+	if (ok && dgs) {
+		dgb = mdev->int_dig_out;
+		drbd_csum(mdev, mdev->integrity_w_tfm, req->master_bio, dgb);
+		ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
+	}
+	if (ok) {
+		if (mdev->net_conf->wire_protocol == DRBD_PROT_A)
+			ok = _drbd_send_bio(mdev, req->master_bio);
+		else
+			ok = _drbd_send_zc_bio(mdev, req->master_bio);
+	}
+
+	drbd_put_data_sock(mdev);
+	return ok;
+}
+
+/* answer packet, used to send data back for read requests:
+ *  Peer       -> (diskless) R_PRIMARY   (P_DATA_REPLY)
+ *  C_SYNC_SOURCE -> C_SYNC_TARGET         (P_RS_DATA_REPLY)
+ */
+int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
+		    struct drbd_epoch_entry *e)
+{
+	int ok;
+	struct p_data p;
+	void *dgb;
+	int dgs;
+
+	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ?
+		crypto_hash_digestsize(mdev->integrity_w_tfm) : 0;
+
+	p.head.magic   = BE_DRBD_MAGIC;
+	p.head.command = cpu_to_be16(cmd);
+	p.head.length  =
+		cpu_to_be16(sizeof(p) - sizeof(struct p_header) + dgs + e->size);
+
+	p.sector   = cpu_to_be64(e->sector);
+	p.block_id = e->block_id;
+	/* p.seq_num  = 0;    No sequence numbers here.. */
+
+	/* Only called by our kernel thread.
+	 * This one may be interrupted by DRBD_SIG and/or DRBD_SIGKILL
+	 * in response to admin command or module unload.
+	 */
+	if (!drbd_get_data_sock(mdev))
+		return 0;
+
+	ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p,
+					sizeof(p), MSG_MORE);
+	if (ok && dgs) {
+		dgb = mdev->int_dig_out;
+		drbd_csum(mdev, mdev->integrity_w_tfm, e->private_bio, dgb);
+		ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE);
+	}
+	if (ok)
+		ok = _drbd_send_zc_bio(mdev, e->private_bio);
+
+	drbd_put_data_sock(mdev);
+	return ok;
+}
+
+/*
+  drbd_send distinguishes two cases:
+
+  Packets sent via the data socket "sock"
+  and packets sent via the meta data socket "msock"
+
+		    sock                      msock
+  -----------------+-------------------------+------------------------------
+  timeout           conf.timeout / 2          conf.timeout / 2
+  timeout action    send a ping via msock     Abort communication
+					      and close all sockets
+*/
+
+/*
+ * you must have down()ed the appropriate [m]sock_mutex elsewhere!
+ */
+int drbd_send(struct drbd_conf *mdev, struct socket *sock,
+	      void *buf, size_t size, unsigned msg_flags)
+{
+	struct kvec iov;
+	struct msghdr msg;
+	int rv, sent = 0;
+
+	if (!sock)
+		return -1000;
+
+	/* THINK  if (signal_pending) return ... ? */
+
+	iov.iov_base = buf;
+	iov.iov_len  = size;
+
+	msg.msg_name       = NULL;
+	msg.msg_namelen    = 0;
+	msg.msg_control    = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
+
+	if (sock == mdev->data.socket) {
+		mdev->ko_count = mdev->net_conf->ko_count;
+		drbd_update_congested(mdev);
+	}
+	do {
+		/* STRANGE
+		 * tcp_sendmsg does _not_ use its size parameter at all ?
+		 *
+		 * -EAGAIN on timeout, -EINTR on signal.
+		 */
+/* THINK
+ * do we need to block DRBD_SIG if sock == &meta.socket ??
+ * otherwise wake_asender() might interrupt some send_*Ack !
+ */
+		rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
+		if (rv == -EAGAIN) {
+			if (we_should_drop_the_connection(mdev, sock))
+				break;
+			else
+				continue;
+		}
+		D_ASSERT(rv != 0);
+		if (rv == -EINTR) {
+			flush_signals(current);
+			rv = 0;
+		}
+		if (rv < 0)
+			break;
+		sent += rv;
+		iov.iov_base += rv;
+		iov.iov_len  -= rv;
+	} while (sent < size);
+
+	if (sock == mdev->data.socket)
+		clear_bit(NET_CONGESTED, &mdev->flags);
+
+	if (rv <= 0) {
+		if (rv != -EAGAIN) {
+			dev_err(DEV, "%s_sendmsg returned %d\n",
+			    sock == mdev->meta.socket ? "msock" : "sock",
+			    rv);
+			drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE));
+		} else
+			drbd_force_state(mdev, NS(conn, C_TIMEOUT));
+	}
+
+	return sent;
+}
+
+static int drbd_open(struct block_device *bdev, fmode_t mode)
+{
+	struct drbd_conf *mdev = bdev->bd_disk->private_data;
+	unsigned long flags;
+	int rv = 0;
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	/* to have a stable mdev->state.role
+	 * and no race with updating open_cnt */
+
+	if (mdev->state.role != R_PRIMARY) {
+		if (mode & FMODE_WRITE)
+			rv = -EROFS;
+		else if (!allow_oos)
+			rv = -EMEDIUMTYPE;
+	}
+
+	if (!rv)
+		mdev->open_cnt++;
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	return rv;
+}
+
+static int drbd_release(struct gendisk *gd, fmode_t mode)
+{
+	struct drbd_conf *mdev = gd->private_data;
+	mdev->open_cnt--;
+	return 0;
+}
+
+static void drbd_unplug_fn(struct request_queue *q)
+{
+	struct drbd_conf *mdev = q->queuedata;
+
+	/* unplug FIRST */
+	spin_lock_irq(q->queue_lock);
+	blk_remove_plug(q);
+	spin_unlock_irq(q->queue_lock);
+
+	/* only if connected */
+	spin_lock_irq(&mdev->req_lock);
+	if (mdev->state.pdsk >= D_INCONSISTENT && mdev->state.conn >= C_CONNECTED) {
+		D_ASSERT(mdev->state.role == R_PRIMARY);
+		if (test_and_clear_bit(UNPLUG_REMOTE, &mdev->flags)) {
+			/* add to the data.work queue,
+			 * unless already queued.
+			 * XXX this might be a good addition to drbd_queue_work
+			 * anyways, to detect "double queuing" ... */
+			if (list_empty(&mdev->unplug_work.list))
+				drbd_queue_work(&mdev->data.work,
+						&mdev->unplug_work);
+		}
+	}
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (mdev->state.disk >= D_INCONSISTENT)
+		drbd_kick_lo(mdev);
+}
+
+static void drbd_set_defaults(struct drbd_conf *mdev)
+{
+	mdev->sync_conf.after      = DRBD_AFTER_DEF;
+	mdev->sync_conf.rate       = DRBD_RATE_DEF;
+	mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF;
+	mdev->state = (union drbd_state) {
+		{ .role = R_SECONDARY,
+		  .peer = R_UNKNOWN,
+		  .conn = C_STANDALONE,
+		  .disk = D_DISKLESS,
+		  .pdsk = D_UNKNOWN,
+		  .susp = 0
+		} };
+}
+
+void drbd_init_set_defaults(struct drbd_conf *mdev)
+{
+	/* the memset(,0,) did most of this.
+	 * note: only assignments, no allocation in here */
+
+	drbd_set_defaults(mdev);
+
+	/* for now, we do NOT yet support it,
+	 * even though we start some framework
+	 * to eventually support barriers */
+	set_bit(NO_BARRIER_SUPP, &mdev->flags);
+
+	atomic_set(&mdev->ap_bio_cnt, 0);
+	atomic_set(&mdev->ap_pending_cnt, 0);
+	atomic_set(&mdev->rs_pending_cnt, 0);
+	atomic_set(&mdev->unacked_cnt, 0);
+	atomic_set(&mdev->local_cnt, 0);
+	atomic_set(&mdev->net_cnt, 0);
+	atomic_set(&mdev->packet_seq, 0);
+	atomic_set(&mdev->pp_in_use, 0);
+
+	mutex_init(&mdev->md_io_mutex);
+	mutex_init(&mdev->data.mutex);
+	mutex_init(&mdev->meta.mutex);
+	sema_init(&mdev->data.work.s, 0);
+	sema_init(&mdev->meta.work.s, 0);
+	mutex_init(&mdev->state_mutex);
+
+	spin_lock_init(&mdev->data.work.q_lock);
+	spin_lock_init(&mdev->meta.work.q_lock);
+
+	spin_lock_init(&mdev->al_lock);
+	spin_lock_init(&mdev->req_lock);
+	spin_lock_init(&mdev->peer_seq_lock);
+	spin_lock_init(&mdev->epoch_lock);
+
+	INIT_LIST_HEAD(&mdev->active_ee);
+	INIT_LIST_HEAD(&mdev->sync_ee);
+	INIT_LIST_HEAD(&mdev->done_ee);
+	INIT_LIST_HEAD(&mdev->read_ee);
+	INIT_LIST_HEAD(&mdev->net_ee);
+	INIT_LIST_HEAD(&mdev->resync_reads);
+	INIT_LIST_HEAD(&mdev->data.work.q);
+	INIT_LIST_HEAD(&mdev->meta.work.q);
+	INIT_LIST_HEAD(&mdev->resync_work.list);
+	INIT_LIST_HEAD(&mdev->unplug_work.list);
+	INIT_LIST_HEAD(&mdev->md_sync_work.list);
+	INIT_LIST_HEAD(&mdev->bm_io_work.w.list);
+	mdev->resync_work.cb  = w_resync_inactive;
+	mdev->unplug_work.cb  = w_send_write_hint;
+	mdev->md_sync_work.cb = w_md_sync;
+	mdev->bm_io_work.w.cb = w_bitmap_io;
+	init_timer(&mdev->resync_timer);
+	init_timer(&mdev->md_sync_timer);
+	mdev->resync_timer.function = resync_timer_fn;
+	mdev->resync_timer.data = (unsigned long) mdev;
+	mdev->md_sync_timer.function = md_sync_timer_fn;
+	mdev->md_sync_timer.data = (unsigned long) mdev;
+
+	init_waitqueue_head(&mdev->misc_wait);
+	init_waitqueue_head(&mdev->state_wait);
+	init_waitqueue_head(&mdev->ee_wait);
+	init_waitqueue_head(&mdev->al_wait);
+	init_waitqueue_head(&mdev->seq_wait);
+
+	drbd_thread_init(mdev, &mdev->receiver, drbdd_init);
+	drbd_thread_init(mdev, &mdev->worker, drbd_worker);
+	drbd_thread_init(mdev, &mdev->asender, drbd_asender);
+
+	mdev->agreed_pro_version = PRO_VERSION_MAX;
+	mdev->write_ordering = WO_bio_barrier;
+	mdev->resync_wenr = LC_FREE;
+}
+
+void drbd_mdev_cleanup(struct drbd_conf *mdev)
+{
+	if (mdev->receiver.t_state != None)
+		dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
+				mdev->receiver.t_state);
+
+	/* no need to lock it, I'm the only thread alive */
+	if (atomic_read(&mdev->current_epoch->epoch_size) !=  0)
+		dev_err(DEV, "epoch_size:%d\n", atomic_read(&mdev->current_epoch->epoch_size));
+	mdev->al_writ_cnt  =
+	mdev->bm_writ_cnt  =
+	mdev->read_cnt     =
+	mdev->recv_cnt     =
+	mdev->send_cnt     =
+	mdev->writ_cnt     =
+	mdev->p_size       =
+	mdev->rs_start     =
+	mdev->rs_total     =
+	mdev->rs_failed    =
+	mdev->rs_mark_left =
+	mdev->rs_mark_time = 0;
+	D_ASSERT(mdev->net_conf == NULL);
+
+	drbd_set_my_capacity(mdev, 0);
+	if (mdev->bitmap) {
+		/* maybe never allocated. */
+		drbd_bm_resize(mdev, 0);
+		drbd_bm_cleanup(mdev);
+	}
+
+	drbd_free_resources(mdev);
+
+	/*
+	 * currently we drbd_init_ee only on module load, so
+	 * we may do drbd_release_ee only on module unload!
+	 */
+	D_ASSERT(list_empty(&mdev->active_ee));
+	D_ASSERT(list_empty(&mdev->sync_ee));
+	D_ASSERT(list_empty(&mdev->done_ee));
+	D_ASSERT(list_empty(&mdev->read_ee));
+	D_ASSERT(list_empty(&mdev->net_ee));
+	D_ASSERT(list_empty(&mdev->resync_reads));
+	D_ASSERT(list_empty(&mdev->data.work.q));
+	D_ASSERT(list_empty(&mdev->meta.work.q));
+	D_ASSERT(list_empty(&mdev->resync_work.list));
+	D_ASSERT(list_empty(&mdev->unplug_work.list));
+
+}
+
+
+static void drbd_destroy_mempools(void)
+{
+	struct page *page;
+
+	while (drbd_pp_pool) {
+		page = drbd_pp_pool;
+		drbd_pp_pool = (struct page *)page_private(page);
+		__free_page(page);
+		drbd_pp_vacant--;
+	}
+
+	/* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */
+
+	if (drbd_ee_mempool)
+		mempool_destroy(drbd_ee_mempool);
+	if (drbd_request_mempool)
+		mempool_destroy(drbd_request_mempool);
+	if (drbd_ee_cache)
+		kmem_cache_destroy(drbd_ee_cache);
+	if (drbd_request_cache)
+		kmem_cache_destroy(drbd_request_cache);
+	if (drbd_bm_ext_cache)
+		kmem_cache_destroy(drbd_bm_ext_cache);
+	if (drbd_al_ext_cache)
+		kmem_cache_destroy(drbd_al_ext_cache);
+
+	drbd_ee_mempool      = NULL;
+	drbd_request_mempool = NULL;
+	drbd_ee_cache        = NULL;
+	drbd_request_cache   = NULL;
+	drbd_bm_ext_cache    = NULL;
+	drbd_al_ext_cache    = NULL;
+
+	return;
+}
+
+static int drbd_create_mempools(void)
+{
+	struct page *page;
+	const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * minor_count;
+	int i;
+
+	/* prepare our caches and mempools */
+	drbd_request_mempool = NULL;
+	drbd_ee_cache        = NULL;
+	drbd_request_cache   = NULL;
+	drbd_bm_ext_cache    = NULL;
+	drbd_al_ext_cache    = NULL;
+	drbd_pp_pool         = NULL;
+
+	/* caches */
+	drbd_request_cache = kmem_cache_create(
+		"drbd_req", sizeof(struct drbd_request), 0, 0, NULL);
+	if (drbd_request_cache == NULL)
+		goto Enomem;
+
+	drbd_ee_cache = kmem_cache_create(
+		"drbd_ee", sizeof(struct drbd_epoch_entry), 0, 0, NULL);
+	if (drbd_ee_cache == NULL)
+		goto Enomem;
+
+	drbd_bm_ext_cache = kmem_cache_create(
+		"drbd_bm", sizeof(struct bm_extent), 0, 0, NULL);
+	if (drbd_bm_ext_cache == NULL)
+		goto Enomem;
+
+	drbd_al_ext_cache = kmem_cache_create(
+		"drbd_al", sizeof(struct lc_element), 0, 0, NULL);
+	if (drbd_al_ext_cache == NULL)
+		goto Enomem;
+
+	/* mempools */
+	drbd_request_mempool = mempool_create(number,
+		mempool_alloc_slab, mempool_free_slab, drbd_request_cache);
+	if (drbd_request_mempool == NULL)
+		goto Enomem;
+
+	drbd_ee_mempool = mempool_create(number,
+		mempool_alloc_slab, mempool_free_slab, drbd_ee_cache);
+	if (drbd_request_mempool == NULL)
+		goto Enomem;
+
+	/* drbd's page pool */
+	spin_lock_init(&drbd_pp_lock);
+
+	for (i = 0; i < number; i++) {
+		page = alloc_page(GFP_HIGHUSER);
+		if (!page)
+			goto Enomem;
+		set_page_private(page, (unsigned long)drbd_pp_pool);
+		drbd_pp_pool = page;
+	}
+	drbd_pp_vacant = number;
+
+	return 0;
+
+Enomem:
+	drbd_destroy_mempools(); /* in case we allocated some */
+	return -ENOMEM;
+}
+
+static int drbd_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	/* just so we have it.  you never know what interesting things we
+	 * might want to do here some day...
+	 */
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block drbd_notifier = {
+	.notifier_call = drbd_notify_sys,
+};
+
+static void drbd_release_ee_lists(struct drbd_conf *mdev)
+{
+	int rr;
+
+	rr = drbd_release_ee(mdev, &mdev->active_ee);
+	if (rr)
+		dev_err(DEV, "%d EEs in active list found!\n", rr);
+
+	rr = drbd_release_ee(mdev, &mdev->sync_ee);
+	if (rr)
+		dev_err(DEV, "%d EEs in sync list found!\n", rr);
+
+	rr = drbd_release_ee(mdev, &mdev->read_ee);
+	if (rr)
+		dev_err(DEV, "%d EEs in read list found!\n", rr);
+
+	rr = drbd_release_ee(mdev, &mdev->done_ee);
+	if (rr)
+		dev_err(DEV, "%d EEs in done list found!\n", rr);
+
+	rr = drbd_release_ee(mdev, &mdev->net_ee);
+	if (rr)
+		dev_err(DEV, "%d EEs in net list found!\n", rr);
+}
+
+/* caution. no locking.
+ * currently only used from module cleanup code. */
+static void drbd_delete_device(unsigned int minor)
+{
+	struct drbd_conf *mdev = minor_to_mdev(minor);
+
+	if (!mdev)
+		return;
+
+	/* paranoia asserts */
+	if (mdev->open_cnt != 0)
+		dev_err(DEV, "open_cnt = %d in %s:%u", mdev->open_cnt,
+				__FILE__ , __LINE__);
+
+	ERR_IF (!list_empty(&mdev->data.work.q)) {
+		struct list_head *lp;
+		list_for_each(lp, &mdev->data.work.q) {
+			dev_err(DEV, "lp = %p\n", lp);
+		}
+	};
+	/* end paranoia asserts */
+
+	del_gendisk(mdev->vdisk);
+
+	/* cleanup stuff that may have been allocated during
+	 * device (re-)configuration or state changes */
+
+	if (mdev->this_bdev)
+		bdput(mdev->this_bdev);
+
+	drbd_free_resources(mdev);
+
+	drbd_release_ee_lists(mdev);
+
+	/* should be free'd on disconnect? */
+	kfree(mdev->ee_hash);
+	/*
+	mdev->ee_hash_s = 0;
+	mdev->ee_hash = NULL;
+	*/
+
+	lc_destroy(mdev->act_log);
+	lc_destroy(mdev->resync);
+
+	kfree(mdev->p_uuid);
+	/* mdev->p_uuid = NULL; */
+
+	kfree(mdev->int_dig_out);
+	kfree(mdev->int_dig_in);
+	kfree(mdev->int_dig_vv);
+
+	/* cleanup the rest that has been
+	 * allocated from drbd_new_device
+	 * and actually free the mdev itself */
+	drbd_free_mdev(mdev);
+}
+
+static void drbd_cleanup(void)
+{
+	unsigned int i;
+
+	unregister_reboot_notifier(&drbd_notifier);
+
+	drbd_nl_cleanup();
+
+	if (minor_table) {
+		if (drbd_proc)
+			remove_proc_entry("drbd", NULL);
+		i = minor_count;
+		while (i--)
+			drbd_delete_device(i);
+		drbd_destroy_mempools();
+	}
+
+	kfree(minor_table);
+
+	unregister_blkdev(DRBD_MAJOR, "drbd");
+
+	printk(KERN_INFO "drbd: module cleanup done.\n");
+}
+
+/**
+ * drbd_congested() - Callback for pdflush
+ * @congested_data:	User data
+ * @bdi_bits:		Bits pdflush is currently interested in
+ *
+ * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested.
+ */
+static int drbd_congested(void *congested_data, int bdi_bits)
+{
+	struct drbd_conf *mdev = congested_data;
+	struct request_queue *q;
+	char reason = '-';
+	int r = 0;
+
+	if (!__inc_ap_bio_cond(mdev)) {
+		/* DRBD has frozen IO */
+		r = bdi_bits;
+		reason = 'd';
+		goto out;
+	}
+
+	if (get_ldev(mdev)) {
+		q = bdev_get_queue(mdev->ldev->backing_bdev);
+		r = bdi_congested(&q->backing_dev_info, bdi_bits);
+		put_ldev(mdev);
+		if (r)
+			reason = 'b';
+	}
+
+	if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &mdev->flags)) {
+		r |= (1 << BDI_async_congested);
+		reason = reason == 'b' ? 'a' : 'n';
+	}
+
+out:
+	mdev->congestion_reason = reason;
+	return r;
+}
+
+struct drbd_conf *drbd_new_device(unsigned int minor)
+{
+	struct drbd_conf *mdev;
+	struct gendisk *disk;
+	struct request_queue *q;
+
+	/* GFP_KERNEL, we are outside of all write-out paths */
+	mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL);
+	if (!mdev)
+		return NULL;
+	if (!zalloc_cpumask_var(&mdev->cpu_mask, GFP_KERNEL))
+		goto out_no_cpumask;
+
+	mdev->minor = minor;
+
+	drbd_init_set_defaults(mdev);
+
+	q = blk_alloc_queue(GFP_KERNEL);
+	if (!q)
+		goto out_no_q;
+	mdev->rq_queue = q;
+	q->queuedata   = mdev;
+
+	disk = alloc_disk(1);
+	if (!disk)
+		goto out_no_disk;
+	mdev->vdisk = disk;
+
+	set_disk_ro(disk, TRUE);
+
+	disk->queue = q;
+	disk->major = DRBD_MAJOR;
+	disk->first_minor = minor;
+	disk->fops = &drbd_ops;
+	sprintf(disk->disk_name, "drbd%d", minor);
+	disk->private_data = mdev;
+
+	mdev->this_bdev = bdget(MKDEV(DRBD_MAJOR, minor));
+	/* we have no partitions. we contain only ourselves. */
+	mdev->this_bdev->bd_contains = mdev->this_bdev;
+
+	q->backing_dev_info.congested_fn = drbd_congested;
+	q->backing_dev_info.congested_data = mdev;
+
+	blk_queue_make_request(q, drbd_make_request_26);
+	blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE);
+	blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
+	blk_queue_merge_bvec(q, drbd_merge_bvec);
+	q->queue_lock = &mdev->req_lock; /* needed since we use */
+		/* plugging on a queue, that actually has no requests! */
+	q->unplug_fn = drbd_unplug_fn;
+
+	mdev->md_io_page = alloc_page(GFP_KERNEL);
+	if (!mdev->md_io_page)
+		goto out_no_io_page;
+
+	if (drbd_bm_init(mdev))
+		goto out_no_bitmap;
+	/* no need to lock access, we are still initializing this minor device. */
+	if (!tl_init(mdev))
+		goto out_no_tl;
+
+	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL);
+	if (!mdev->app_reads_hash)
+		goto out_no_app_reads;
+
+	mdev->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
+	if (!mdev->current_epoch)
+		goto out_no_epoch;
+
+	INIT_LIST_HEAD(&mdev->current_epoch->list);
+	mdev->epochs = 1;
+
+	return mdev;
+
+/* out_whatever_else:
+	kfree(mdev->current_epoch); */
+out_no_epoch:
+	kfree(mdev->app_reads_hash);
+out_no_app_reads:
+	tl_cleanup(mdev);
+out_no_tl:
+	drbd_bm_cleanup(mdev);
+out_no_bitmap:
+	__free_page(mdev->md_io_page);
+out_no_io_page:
+	put_disk(disk);
+out_no_disk:
+	blk_cleanup_queue(q);
+out_no_q:
+	free_cpumask_var(mdev->cpu_mask);
+out_no_cpumask:
+	kfree(mdev);
+	return NULL;
+}
+
+/* counterpart of drbd_new_device.
+ * last part of drbd_delete_device. */
+void drbd_free_mdev(struct drbd_conf *mdev)
+{
+	kfree(mdev->current_epoch);
+	kfree(mdev->app_reads_hash);
+	tl_cleanup(mdev);
+	if (mdev->bitmap) /* should no longer be there. */
+		drbd_bm_cleanup(mdev);
+	__free_page(mdev->md_io_page);
+	put_disk(mdev->vdisk);
+	blk_cleanup_queue(mdev->rq_queue);
+	free_cpumask_var(mdev->cpu_mask);
+	kfree(mdev);
+}
+
+
+int __init drbd_init(void)
+{
+	int err;
+
+	if (sizeof(struct p_handshake) != 80) {
+		printk(KERN_ERR
+		       "drbd: never change the size or layout "
+		       "of the HandShake packet.\n");
+		return -EINVAL;
+	}
+
+	if (1 > minor_count || minor_count > 255) {
+		printk(KERN_ERR
+			"drbd: invalid minor_count (%d)\n", minor_count);
+#ifdef MODULE
+		return -EINVAL;
+#else
+		minor_count = 8;
+#endif
+	}
+
+	err = drbd_nl_init();
+	if (err)
+		return err;
+
+	err = register_blkdev(DRBD_MAJOR, "drbd");
+	if (err) {
+		printk(KERN_ERR
+		       "drbd: unable to register block device major %d\n",
+		       DRBD_MAJOR);
+		return err;
+	}
+
+	register_reboot_notifier(&drbd_notifier);
+
+	/*
+	 * allocate all necessary structs
+	 */
+	err = -ENOMEM;
+
+	init_waitqueue_head(&drbd_pp_wait);
+
+	drbd_proc = NULL; /* play safe for drbd_cleanup */
+	minor_table = kzalloc(sizeof(struct drbd_conf *)*minor_count,
+				GFP_KERNEL);
+	if (!minor_table)
+		goto Enomem;
+
+	err = drbd_create_mempools();
+	if (err)
+		goto Enomem;
+
+	drbd_proc = proc_create("drbd", S_IFREG | S_IRUGO , NULL, &drbd_proc_fops);
+	if (!drbd_proc)	{
+		printk(KERN_ERR "drbd: unable to register proc file\n");
+		goto Enomem;
+	}
+
+	rwlock_init(&global_state_lock);
+
+	printk(KERN_INFO "drbd: initialized. "
+	       "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
+	       API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
+	printk(KERN_INFO "drbd: %s\n", drbd_buildtag());
+	printk(KERN_INFO "drbd: registered as block device major %d\n",
+		DRBD_MAJOR);
+	printk(KERN_INFO "drbd: minor_table @ 0x%p\n", minor_table);
+
+	return 0; /* Success! */
+
+Enomem:
+	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");
+	return err;
+}
+
+void drbd_free_bc(struct drbd_backing_dev *ldev)
+{
+	if (ldev == NULL)
+		return;
+
+	bd_release(ldev->backing_bdev);
+	bd_release(ldev->md_bdev);
+
+	fput(ldev->lo_file);
+	fput(ldev->md_file);
+
+	kfree(ldev);
+}
+
+void drbd_free_sock(struct drbd_conf *mdev)
+{
+	if (mdev->data.socket) {
+		kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
+		sock_release(mdev->data.socket);
+		mdev->data.socket = NULL;
+	}
+	if (mdev->meta.socket) {
+		kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
+		sock_release(mdev->meta.socket);
+		mdev->meta.socket = NULL;
+	}
+}
+
+
+void drbd_free_resources(struct drbd_conf *mdev)
+{
+	crypto_free_hash(mdev->csums_tfm);
+	mdev->csums_tfm = NULL;
+	crypto_free_hash(mdev->verify_tfm);
+	mdev->verify_tfm = NULL;
+	crypto_free_hash(mdev->cram_hmac_tfm);
+	mdev->cram_hmac_tfm = NULL;
+	crypto_free_hash(mdev->integrity_w_tfm);
+	mdev->integrity_w_tfm = NULL;
+	crypto_free_hash(mdev->integrity_r_tfm);
+	mdev->integrity_r_tfm = NULL;
+
+	drbd_free_sock(mdev);
+
+	__no_warn(local,
+		  drbd_free_bc(mdev->ldev);
+		  mdev->ldev = NULL;);
+}
+
+/* meta data management */
+
+struct meta_data_on_disk {
+	u64 la_size;           /* last agreed size. */
+	u64 uuid[UI_SIZE];   /* UUIDs. */
+	u64 device_uuid;
+	u64 reserved_u64_1;
+	u32 flags;             /* MDF */
+	u32 magic;
+	u32 md_size_sect;
+	u32 al_offset;         /* offset to this block */
+	u32 al_nr_extents;     /* important for restoring the AL */
+	      /* `-- act_log->nr_elements <-- sync_conf.al_extents */
+	u32 bm_offset;         /* offset to the bitmap, from here */
+	u32 bm_bytes_per_bit;  /* BM_BLOCK_SIZE */
+	u32 reserved_u32[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)
+{
+	struct meta_data_on_disk *buffer;
+	sector_t sector;
+	int i;
+
+	if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
+		return;
+	del_timer(&mdev->md_sync_timer);
+
+	/* 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;
+
+	mutex_lock(&mdev->md_io_mutex);
+	buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
+	memset(buffer, 0, 512);
+
+	buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
+	for (i = UI_CURRENT; i < UI_SIZE; i++)
+		buffer->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]);
+	buffer->flags = cpu_to_be32(mdev->ldev->md.flags);
+	buffer->magic = cpu_to_be32(DRBD_MD_MAGIC);
+
+	buffer->md_size_sect  = cpu_to_be32(mdev->ldev->md.md_size_sect);
+	buffer->al_offset     = cpu_to_be32(mdev->ldev->md.al_offset);
+	buffer->al_nr_extents = cpu_to_be32(mdev->act_log->nr_elements);
+	buffer->bm_bytes_per_bit = cpu_to_be32(BM_BLOCK_SIZE);
+	buffer->device_uuid = cpu_to_be64(mdev->ldev->md.device_uuid);
+
+	buffer->bm_offset = cpu_to_be32(mdev->ldev->md.bm_offset);
+
+	D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset);
+	sector = mdev->ldev->md.md_offset;
+
+	if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
+		clear_bit(MD_DIRTY, &mdev->flags);
+	} else {
+		/* this was a try anyways ... */
+		dev_err(DEV, "meta data update failed!\n");
+
+		drbd_chk_io_error(mdev, 1, TRUE);
+	}
+
+	/* Update mdev->ldev->md.la_size_sect,
+	 * since we updated it on metadata. */
+	mdev->ldev->md.la_size_sect = drbd_get_capacity(mdev->this_bdev);
+
+	mutex_unlock(&mdev->md_io_mutex);
+	put_ldev(mdev);
+}
+
+/**
+ * drbd_md_read() - Reads in the meta data super block
+ * @mdev:	DRBD device.
+ * @bdev:	Device from which the meta data should be read in.
+ *
+ * Return 0 (NO_ERROR) on success, and an enum drbd_ret_codes in case
+ * something goes wrong.  Currently only: ERR_IO_MD_DISK, ERR_MD_INVALID.
+ */
+int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
+{
+	struct meta_data_on_disk *buffer;
+	int i, rv = NO_ERROR;
+
+	if (!get_ldev_if_state(mdev, D_ATTACHING))
+		return ERR_IO_MD_DISK;
+
+	mutex_lock(&mdev->md_io_mutex);
+	buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
+
+	if (!drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) {
+		/* NOTE: cant do normal error processing here as this is
+		   called BEFORE disk is attached */
+		dev_err(DEV, "Error while reading metadata.\n");
+		rv = ERR_IO_MD_DISK;
+		goto err;
+	}
+
+	if (be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) {
+		dev_err(DEV, "Error while reading metadata, magic not found.\n");
+		rv = ERR_MD_INVALID;
+		goto err;
+	}
+	if (be32_to_cpu(buffer->al_offset) != bdev->md.al_offset) {
+		dev_err(DEV, "unexpected al_offset: %d (expected %d)\n",
+		    be32_to_cpu(buffer->al_offset), bdev->md.al_offset);
+		rv = ERR_MD_INVALID;
+		goto err;
+	}
+	if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) {
+		dev_err(DEV, "unexpected bm_offset: %d (expected %d)\n",
+		    be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset);
+		rv = ERR_MD_INVALID;
+		goto err;
+	}
+	if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) {
+		dev_err(DEV, "unexpected md_size: %u (expected %u)\n",
+		    be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect);
+		rv = ERR_MD_INVALID;
+		goto err;
+	}
+
+	if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) {
+		dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
+		    be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
+		rv = ERR_MD_INVALID;
+		goto err;
+	}
+
+	bdev->md.la_size_sect = be64_to_cpu(buffer->la_size);
+	for (i = UI_CURRENT; i < UI_SIZE; i++)
+		bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
+	bdev->md.flags = be32_to_cpu(buffer->flags);
+	mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents);
+	bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
+
+	if (mdev->sync_conf.al_extents < 7)
+		mdev->sync_conf.al_extents = 127;
+
+ err:
+	mutex_unlock(&mdev->md_io_mutex);
+	put_ldev(mdev);
+
+	return rv;
+}
+
+/**
+ * drbd_md_mark_dirty() - Mark meta data super block as dirty
+ * @mdev:	DRBD device.
+ *
+ * Call this function if you change anything that should be written to
+ * the meta-data super block. This function sets MD_DIRTY, and starts a
+ * timer that ensures that within five seconds you have to call drbd_md_sync().
+ */
+void drbd_md_mark_dirty(struct drbd_conf *mdev)
+{
+	set_bit(MD_DIRTY, &mdev->flags);
+	mod_timer(&mdev->md_sync_timer, jiffies + 5*HZ);
+}
+
+
+static void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local)
+{
+	int i;
+
+	for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++)
+		mdev->ldev->md.uuid[i+1] = mdev->ldev->md.uuid[i];
+}
+
+void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local)
+{
+	if (idx == UI_CURRENT) {
+		if (mdev->state.role == R_PRIMARY)
+			val |= 1;
+		else
+			val &= ~((u64)1);
+
+		drbd_set_ed_uuid(mdev, val);
+	}
+
+	mdev->ldev->md.uuid[idx] = val;
+	drbd_md_mark_dirty(mdev);
+}
+
+
+void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local)
+{
+	if (mdev->ldev->md.uuid[idx]) {
+		drbd_uuid_move_history(mdev);
+		mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[idx];
+	}
+	_drbd_uuid_set(mdev, idx, val);
+}
+
+/**
+ * drbd_uuid_new_current() - Creates a new current UUID
+ * @mdev:	DRBD device.
+ *
+ * Creates a new current UUID, and rotates the old current UUID into
+ * the bitmap slot. Causes an incremental resync upon next connect.
+ */
+void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local)
+{
+	u64 val;
+
+	dev_info(DEV, "Creating new current UUID\n");
+	D_ASSERT(mdev->ldev->md.uuid[UI_BITMAP] == 0);
+	mdev->ldev->md.uuid[UI_BITMAP] = mdev->ldev->md.uuid[UI_CURRENT];
+
+	get_random_bytes(&val, sizeof(u64));
+	_drbd_uuid_set(mdev, UI_CURRENT, val);
+}
+
+void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local)
+{
+	if (mdev->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
+		return;
+
+	if (val == 0) {
+		drbd_uuid_move_history(mdev);
+		mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[UI_BITMAP];
+		mdev->ldev->md.uuid[UI_BITMAP] = 0;
+	} else {
+		if (mdev->ldev->md.uuid[UI_BITMAP])
+			dev_warn(DEV, "bm UUID already set");
+
+		mdev->ldev->md.uuid[UI_BITMAP] = val;
+		mdev->ldev->md.uuid[UI_BITMAP] &= ~((u64)1);
+
+	}
+	drbd_md_mark_dirty(mdev);
+}
+
+/**
+ * drbd_bmio_set_n_write() - io_fn for drbd_queue_bitmap_io() or drbd_bitmap_io()
+ * @mdev:	DRBD device.
+ *
+ * Sets all bits in the bitmap and writes the whole bitmap to stable storage.
+ */
+int drbd_bmio_set_n_write(struct drbd_conf *mdev)
+{
+	int rv = -EIO;
+
+	if (get_ldev_if_state(mdev, D_ATTACHING)) {
+		drbd_md_set_flag(mdev, MDF_FULL_SYNC);
+		drbd_md_sync(mdev);
+		drbd_bm_set_all(mdev);
+
+		rv = drbd_bm_write(mdev);
+
+		if (!rv) {
+			drbd_md_clear_flag(mdev, MDF_FULL_SYNC);
+			drbd_md_sync(mdev);
+		}
+
+		put_ldev(mdev);
+	}
+
+	return rv;
+}
+
+/**
+ * drbd_bmio_clear_n_write() - io_fn for drbd_queue_bitmap_io() or drbd_bitmap_io()
+ * @mdev:	DRBD device.
+ *
+ * Clears all bits in the bitmap and writes the whole bitmap to stable storage.
+ */
+int drbd_bmio_clear_n_write(struct drbd_conf *mdev)
+{
+	int rv = -EIO;
+
+	if (get_ldev_if_state(mdev, D_ATTACHING)) {
+		drbd_bm_clear_all(mdev);
+		rv = drbd_bm_write(mdev);
+		put_ldev(mdev);
+	}
+
+	return rv;
+}
+
+static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct bm_io_work *work = container_of(w, struct bm_io_work, w);
+	int rv;
+
+	D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
+
+	drbd_bm_lock(mdev, work->why);
+	rv = work->io_fn(mdev);
+	drbd_bm_unlock(mdev);
+
+	clear_bit(BITMAP_IO, &mdev->flags);
+	wake_up(&mdev->misc_wait);
+
+	if (work->done)
+		work->done(mdev, rv);
+
+	clear_bit(BITMAP_IO_QUEUED, &mdev->flags);
+	work->why = NULL;
+
+	return 1;
+}
+
+/**
+ * drbd_queue_bitmap_io() - Queues an IO operation on the whole bitmap
+ * @mdev:	DRBD device.
+ * @io_fn:	IO callback to be called when bitmap IO is possible
+ * @done:	callback to be called after the bitmap IO was performed
+ * @why:	Descriptive text of the reason for doing the IO
+ *
+ * While IO on the bitmap happens we freeze application IO thus we ensure
+ * that drbd_set_out_of_sync() can not be called. This function MAY ONLY be
+ * called from worker context. It MUST NOT be used while a previous such
+ * work is still pending!
+ */
+void drbd_queue_bitmap_io(struct drbd_conf *mdev,
+			  int (*io_fn)(struct drbd_conf *),
+			  void (*done)(struct drbd_conf *, int),
+			  char *why)
+{
+	D_ASSERT(current == mdev->worker.task);
+
+	D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &mdev->flags));
+	D_ASSERT(!test_bit(BITMAP_IO, &mdev->flags));
+	D_ASSERT(list_empty(&mdev->bm_io_work.w.list));
+	if (mdev->bm_io_work.why)
+		dev_err(DEV, "FIXME going to queue '%s' but '%s' still pending?\n",
+			why, mdev->bm_io_work.why);
+
+	mdev->bm_io_work.io_fn = io_fn;
+	mdev->bm_io_work.done = done;
+	mdev->bm_io_work.why = why;
+
+	set_bit(BITMAP_IO, &mdev->flags);
+	if (atomic_read(&mdev->ap_bio_cnt) == 0) {
+		if (list_empty(&mdev->bm_io_work.w.list)) {
+			set_bit(BITMAP_IO_QUEUED, &mdev->flags);
+			drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w);
+		} else
+			dev_err(DEV, "FIXME avoided double queuing bm_io_work\n");
+	}
+}
+
+/**
+ * drbd_bitmap_io() -  Does an IO operation on the whole bitmap
+ * @mdev:	DRBD device.
+ * @io_fn:	IO callback to be called when bitmap IO is possible
+ * @why:	Descriptive text of the reason for doing the IO
+ *
+ * freezes application IO while that the actual IO operations runs. This
+ * functions MAY NOT be called from worker context.
+ */
+int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why)
+{
+	int rv;
+
+	D_ASSERT(current != mdev->worker.task);
+
+	drbd_suspend_io(mdev);
+
+	drbd_bm_lock(mdev, why);
+	rv = io_fn(mdev);
+	drbd_bm_unlock(mdev);
+
+	drbd_resume_io(mdev);
+
+	return rv;
+}
+
+void drbd_md_set_flag(struct drbd_conf *mdev, int flag) __must_hold(local)
+{
+	if ((mdev->ldev->md.flags & flag) != flag) {
+		drbd_md_mark_dirty(mdev);
+		mdev->ldev->md.flags |= flag;
+	}
+}
+
+void drbd_md_clear_flag(struct drbd_conf *mdev, int flag) __must_hold(local)
+{
+	if ((mdev->ldev->md.flags & flag) != 0) {
+		drbd_md_mark_dirty(mdev);
+		mdev->ldev->md.flags &= ~flag;
+	}
+}
+int drbd_md_test_flag(struct drbd_backing_dev *bdev, int flag)
+{
+	return (bdev->md.flags & flag) != 0;
+}
+
+static void md_sync_timer_fn(unsigned long data)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *) data;
+
+	drbd_queue_work_front(&mdev->data.work, &mdev->md_sync_work);
+}
+
+static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	dev_warn(DEV, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
+	drbd_md_sync(mdev);
+
+	return 1;
+}
+
+#ifdef CONFIG_DRBD_FAULT_INJECTION
+/* Fault insertion support including random number generator shamelessly
+ * stolen from kernel/rcutorture.c */
+struct fault_random_state {
+	unsigned long state;
+	unsigned long count;
+};
+
+#define FAULT_RANDOM_MULT 39916801  /* prime */
+#define FAULT_RANDOM_ADD	479001701 /* prime */
+#define FAULT_RANDOM_REFRESH 10000
+
+/*
+ * Crude but fast random-number generator.  Uses a linear congruential
+ * generator, with occasional help from get_random_bytes().
+ */
+static unsigned long
+_drbd_fault_random(struct fault_random_state *rsp)
+{
+	long refresh;
+
+	if (!rsp->count--) {
+		get_random_bytes(&refresh, sizeof(refresh));
+		rsp->state += refresh;
+		rsp->count = FAULT_RANDOM_REFRESH;
+	}
+	rsp->state = rsp->state * FAULT_RANDOM_MULT + FAULT_RANDOM_ADD;
+	return swahw32(rsp->state);
+}
+
+static char *
+_drbd_fault_str(unsigned int type) {
+	static char *_faults[] = {
+		[DRBD_FAULT_MD_WR] = "Meta-data write",
+		[DRBD_FAULT_MD_RD] = "Meta-data read",
+		[DRBD_FAULT_RS_WR] = "Resync write",
+		[DRBD_FAULT_RS_RD] = "Resync read",
+		[DRBD_FAULT_DT_WR] = "Data write",
+		[DRBD_FAULT_DT_RD] = "Data read",
+		[DRBD_FAULT_DT_RA] = "Data read ahead",
+		[DRBD_FAULT_BM_ALLOC] = "BM allocation",
+		[DRBD_FAULT_AL_EE] = "EE allocation"
+	};
+
+	return (type < DRBD_FAULT_MAX) ? _faults[type] : "**Unknown**";
+}
+
+unsigned int
+_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type)
+{
+	static struct fault_random_state rrs = {0, 0};
+
+	unsigned int ret = (
+		(fault_devs == 0 ||
+			((1 << mdev_to_minor(mdev)) & fault_devs) != 0) &&
+		(((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate));
+
+	if (ret) {
+		fault_count++;
+
+		if (printk_ratelimit())
+			dev_warn(DEV, "***Simulating %s failure\n",
+				_drbd_fault_str(type));
+	}
+
+	return ret;
+}
+#endif
+
+const char *drbd_buildtag(void)
+{
+	/* DRBD built from external sources has here a reference to the
+	   git hash of the source code. */
+
+	static char buildtag[38] = "\0uilt-in";
+
+	if (buildtag[0] == 0) {
+#ifdef CONFIG_MODULES
+		if (THIS_MODULE != NULL)
+			sprintf(buildtag, "srcversion: %-24s", THIS_MODULE->srcversion);
+		else
+#endif
+			buildtag[0] = 'b';
+	}
+
+	return buildtag;
+}
+
+module_init(drbd_init)
+module_exit(drbd_cleanup)
+
+EXPORT_SYMBOL(drbd_conn_str);
+EXPORT_SYMBOL(drbd_role_str);
+EXPORT_SYMBOL(drbd_disk_str);
+EXPORT_SYMBOL(drbd_set_st_err_str);
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_nl.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_nl.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_nl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_nl.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2368 @@
+/*
+   drbd_nl.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+#include <linux/drbd.h>
+#include <linux/in.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/connector.h>
+#include <linux/blkpg.h>
+#include <linux/cpumask.h>
+#include "drbd_int.h"
+#include "drbd_wrappers.h"
+#include <asm/unaligned.h>
+#include <linux/drbd_tag_magic.h>
+#include <linux/drbd_limits.h>
+
+static unsigned short *tl_add_blob(unsigned short *, enum drbd_tags, const void *, int);
+static unsigned short *tl_add_str(unsigned short *, enum drbd_tags, const char *);
+static unsigned short *tl_add_int(unsigned short *, enum drbd_tags, const void *);
+
+/* see get_sb_bdev and bd_claim */
+static char *drbd_m_holder = "Hands off! this is DRBD's meta data device.";
+
+/* Generate the tag_list to struct functions */
+#define NL_PACKET(name, number, fields) \
+static int name ## _from_tags(struct drbd_conf *mdev, \
+	unsigned short *tags, struct name *arg) __attribute__ ((unused)); \
+static int name ## _from_tags(struct drbd_conf *mdev, \
+	unsigned short *tags, struct name *arg) \
+{ \
+	int tag; \
+	int dlen; \
+	\
+	while ((tag = get_unaligned(tags++)) != TT_END) {	\
+		dlen = get_unaligned(tags++);			\
+		switch (tag_number(tag)) { \
+		fields \
+		default: \
+			if (tag & T_MANDATORY) { \
+				dev_err(DEV, "Unknown tag: %d\n", tag_number(tag)); \
+				return 0; \
+			} \
+		} \
+		tags = (unsigned short *)((char *)tags + dlen); \
+	} \
+	return 1; \
+}
+#define NL_INTEGER(pn, pr, member) \
+	case pn: /* D_ASSERT( tag_type(tag) == TT_INTEGER ); */ \
+		arg->member = get_unaligned((int *)(tags));	\
+		break;
+#define NL_INT64(pn, pr, member) \
+	case pn: /* D_ASSERT( tag_type(tag) == TT_INT64 ); */ \
+		arg->member = get_unaligned((u64 *)(tags));	\
+		break;
+#define NL_BIT(pn, pr, member) \
+	case pn: /* D_ASSERT( tag_type(tag) == TT_BIT ); */ \
+		arg->member = *(char *)(tags) ? 1 : 0; \
+		break;
+#define NL_STRING(pn, pr, member, len) \
+	case pn: /* D_ASSERT( tag_type(tag) == TT_STRING ); */ \
+		if (dlen > len) { \
+			dev_err(DEV, "arg too long: %s (%u wanted, max len: %u bytes)\n", \
+				#member, dlen, (unsigned int)len); \
+			return 0; \
+		} \
+		 arg->member ## _len = dlen; \
+		 memcpy(arg->member, tags, min_t(size_t, dlen, len)); \
+		 break;
+#include "linux/drbd_nl.h"
+
+/* Generate the struct to tag_list functions */
+#define NL_PACKET(name, number, fields) \
+static unsigned short* \
+name ## _to_tags(struct drbd_conf *mdev, \
+	struct name *arg, unsigned short *tags) __attribute__ ((unused)); \
+static unsigned short* \
+name ## _to_tags(struct drbd_conf *mdev, \
+	struct name *arg, unsigned short *tags) \
+{ \
+	fields \
+	return tags; \
+}
+
+#define NL_INTEGER(pn, pr, member) \
+	put_unaligned(pn | pr | TT_INTEGER, tags++);	\
+	put_unaligned(sizeof(int), tags++);		\
+	put_unaligned(arg->member, (int *)tags);	\
+	tags = (unsigned short *)((char *)tags+sizeof(int));
+#define NL_INT64(pn, pr, member) \
+	put_unaligned(pn | pr | TT_INT64, tags++);	\
+	put_unaligned(sizeof(u64), tags++);		\
+	put_unaligned(arg->member, (u64 *)tags);	\
+	tags = (unsigned short *)((char *)tags+sizeof(u64));
+#define NL_BIT(pn, pr, member) \
+	put_unaligned(pn | pr | TT_BIT, tags++);	\
+	put_unaligned(sizeof(char), tags++);		\
+	*(char *)tags = arg->member; \
+	tags = (unsigned short *)((char *)tags+sizeof(char));
+#define NL_STRING(pn, pr, member, len) \
+	put_unaligned(pn | pr | TT_STRING, tags++);	\
+	put_unaligned(arg->member ## _len, tags++);	\
+	memcpy(tags, arg->member, arg->member ## _len); \
+	tags = (unsigned short *)((char *)tags + arg->member ## _len);
+#include "linux/drbd_nl.h"
+
+void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name);
+void drbd_nl_send_reply(struct cn_msg *, int);
+
+int drbd_khelper(struct drbd_conf *mdev, char *cmd)
+{
+	char *envp[] = { "HOME=/",
+			"TERM=linux",
+			"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+			NULL, /* Will be set to address family */
+			NULL, /* Will be set to address */
+			NULL };
+
+	char mb[12], af[20], ad[60], *afs;
+	char *argv[] = {usermode_helper, cmd, mb, NULL };
+	int ret;
+
+	snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
+
+	if (get_net_conf(mdev)) {
+		switch (((struct sockaddr *)mdev->net_conf->peer_addr)->sa_family) {
+		case AF_INET6:
+			afs = "ipv6";
+			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI6",
+				 &((struct sockaddr_in6 *)mdev->net_conf->peer_addr)->sin6_addr);
+			break;
+		case AF_INET:
+			afs = "ipv4";
+			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
+				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
+			break;
+		default:
+			afs = "ssocks";
+			snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4",
+				 &((struct sockaddr_in *)mdev->net_conf->peer_addr)->sin_addr);
+		}
+		snprintf(af, 20, "DRBD_PEER_AF=%s", afs);
+		envp[3]=af;
+		envp[4]=ad;
+		put_net_conf(mdev);
+	}
+
+	dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
+
+	drbd_bcast_ev_helper(mdev, cmd);
+	ret = call_usermodehelper(usermode_helper, argv, envp, 1);
+	if (ret)
+		dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
+				usermode_helper, cmd, mb,
+				(ret >> 8) & 0xff, ret);
+	else
+		dev_info(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
+				usermode_helper, cmd, mb,
+				(ret >> 8) & 0xff, ret);
+
+	if (ret < 0) /* Ignore any ERRNOs we got. */
+		ret = 0;
+
+	return ret;
+}
+
+enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
+{
+	char *ex_to_string;
+	int r;
+	enum drbd_disk_state nps;
+	enum drbd_fencing_p fp;
+
+	D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
+
+	if (get_ldev_if_state(mdev, D_CONSISTENT)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	} else {
+		dev_warn(DEV, "Not fencing peer, I'm not even Consistent myself.\n");
+		return mdev->state.pdsk;
+	}
+
+	if (fp == FP_STONITH)
+		_drbd_request_state(mdev, NS(susp, 1), CS_WAIT_COMPLETE);
+
+	r = drbd_khelper(mdev, "fence-peer");
+
+	switch ((r>>8) & 0xff) {
+	case 3: /* peer is inconsistent */
+		ex_to_string = "peer is inconsistent or worse";
+		nps = D_INCONSISTENT;
+		break;
+	case 4: /* peer got outdated, or was already outdated */
+		ex_to_string = "peer was fenced";
+		nps = D_OUTDATED;
+		break;
+	case 5: /* peer was down */
+		if (mdev->state.disk == D_UP_TO_DATE) {
+			/* we will(have) create(d) a new UUID anyways... */
+			ex_to_string = "peer is unreachable, assumed to be dead";
+			nps = D_OUTDATED;
+		} else {
+			ex_to_string = "peer unreachable, doing nothing since disk != UpToDate";
+			nps = mdev->state.pdsk;
+		}
+		break;
+	case 6: /* Peer is primary, voluntarily outdate myself.
+		 * This is useful when an unconnected R_SECONDARY is asked to
+		 * become R_PRIMARY, but finds the other peer being active. */
+		ex_to_string = "peer is active";
+		dev_warn(DEV, "Peer is primary, outdating myself.\n");
+		nps = D_UNKNOWN;
+		_drbd_request_state(mdev, NS(disk, D_OUTDATED), CS_WAIT_COMPLETE);
+		break;
+	case 7:
+		if (fp != FP_STONITH)
+			dev_err(DEV, "fence-peer() = 7 && fencing != Stonith !!!\n");
+		ex_to_string = "peer was stonithed";
+		nps = D_OUTDATED;
+		break;
+	default:
+		/* The script is broken ... */
+		nps = D_UNKNOWN;
+		dev_err(DEV, "fence-peer helper broken, returned %d\n", (r>>8)&0xff);
+		return nps;
+	}
+
+	dev_info(DEV, "fence-peer helper returned %d (%s)\n",
+			(r>>8) & 0xff, ex_to_string);
+	return nps;
+}
+
+
+int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
+{
+	const int max_tries = 4;
+	int r = 0;
+	int try = 0;
+	int forced = 0;
+	union drbd_state mask, val;
+	enum drbd_disk_state nps;
+
+	if (new_role == R_PRIMARY)
+		request_ping(mdev); /* Detect a dead peer ASAP */
+
+	mutex_lock(&mdev->state_mutex);
+
+	mask.i = 0; mask.role = R_MASK;
+	val.i  = 0; val.role  = new_role;
+
+	while (try++ < max_tries) {
+		r = _drbd_request_state(mdev, mask, val, CS_WAIT_COMPLETE);
+
+		/* in case we first succeeded to outdate,
+		 * but now suddenly could establish a connection */
+		if (r == SS_CW_FAILED_BY_PEER && mask.pdsk != 0) {
+			val.pdsk = 0;
+			mask.pdsk = 0;
+			continue;
+		}
+
+		if (r == SS_NO_UP_TO_DATE_DISK && force &&
+		    (mdev->state.disk == D_INCONSISTENT ||
+		     mdev->state.disk == D_OUTDATED)) {
+			mask.disk = D_MASK;
+			val.disk  = D_UP_TO_DATE;
+			forced = 1;
+			continue;
+		}
+
+		if (r == SS_NO_UP_TO_DATE_DISK &&
+		    mdev->state.disk == D_CONSISTENT && mask.pdsk == 0) {
+			D_ASSERT(mdev->state.pdsk == D_UNKNOWN);
+			nps = drbd_try_outdate_peer(mdev);
+
+			if (nps == D_OUTDATED || nps == D_INCONSISTENT) {
+				val.disk = D_UP_TO_DATE;
+				mask.disk = D_MASK;
+			}
+
+			val.pdsk = nps;
+			mask.pdsk = D_MASK;
+
+			continue;
+		}
+
+		if (r == SS_NOTHING_TO_DO)
+			goto fail;
+		if (r == SS_PRIMARY_NOP && mask.pdsk == 0) {
+			nps = drbd_try_outdate_peer(mdev);
+
+			if (force && nps > D_OUTDATED) {
+				dev_warn(DEV, "Forced into split brain situation!\n");
+				nps = D_OUTDATED;
+			}
+
+			mask.pdsk = D_MASK;
+			val.pdsk  = nps;
+
+			continue;
+		}
+		if (r == SS_TWO_PRIMARIES) {
+			/* Maybe the peer is detected as dead very soon...
+			   retry at most once more in this case. */
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10);
+			if (try < max_tries)
+				try = max_tries - 1;
+			continue;
+		}
+		if (r < SS_SUCCESS) {
+			r = _drbd_request_state(mdev, mask, val,
+						CS_VERBOSE + CS_WAIT_COMPLETE);
+			if (r < SS_SUCCESS)
+				goto fail;
+		}
+		break;
+	}
+
+	if (r < SS_SUCCESS)
+		goto fail;
+
+	if (forced)
+		dev_warn(DEV, "Forced to consider local data as UpToDate!\n");
+
+	/* Wait until nothing is on the fly :) */
+	wait_event(mdev->misc_wait, atomic_read(&mdev->ap_pending_cnt) == 0);
+
+	if (new_role == R_SECONDARY) {
+		set_disk_ro(mdev->vdisk, TRUE);
+		if (get_ldev(mdev)) {
+			mdev->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
+			put_ldev(mdev);
+		}
+	} else {
+		if (get_net_conf(mdev)) {
+			mdev->net_conf->want_lose = 0;
+			put_net_conf(mdev);
+		}
+		set_disk_ro(mdev->vdisk, FALSE);
+		if (get_ldev(mdev)) {
+			if (((mdev->state.conn < C_CONNECTED ||
+			       mdev->state.pdsk <= D_FAILED)
+			      && mdev->ldev->md.uuid[UI_BITMAP] == 0) || forced)
+				drbd_uuid_new_current(mdev);
+
+			mdev->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
+			put_ldev(mdev);
+		}
+	}
+
+	if ((new_role == R_SECONDARY) && get_ldev(mdev)) {
+		drbd_al_to_on_disk_bm(mdev);
+		put_ldev(mdev);
+	}
+
+	if (mdev->state.conn >= C_WF_REPORT_PARAMS) {
+		/* if this was forced, we should consider sync */
+		if (forced)
+			drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+	}
+
+	drbd_md_sync(mdev);
+
+	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
+ fail:
+	mutex_unlock(&mdev->state_mutex);
+	return r;
+}
+
+
+static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
+{
+	struct primary primary_args;
+
+	memset(&primary_args, 0, sizeof(struct primary));
+	if (!primary_from_tags(mdev, nlp->tag_list, &primary_args)) {
+		reply->ret_code = ERR_MANDATORY_TAG;
+		return 0;
+	}
+
+	reply->ret_code =
+		drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer);
+
+	return 0;
+}
+
+static int drbd_nl_secondary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_set_role(mdev, R_SECONDARY, 0);
+
+	return 0;
+}
+
+/* initializes the md.*_offset members, so we are able to find
+ * the on disk meta data */
+static void drbd_md_set_sector_offsets(struct drbd_conf *mdev,
+				       struct drbd_backing_dev *bdev)
+{
+	sector_t md_size_sect = 0;
+	switch (bdev->dc.meta_dev_idx) {
+	default:
+		/* v07 style fixed size indexed meta data */
+		bdev->md.md_size_sect = MD_RESERVED_SECT;
+		bdev->md.md_offset = drbd_md_ss__(mdev, bdev);
+		bdev->md.al_offset = MD_AL_OFFSET;
+		bdev->md.bm_offset = MD_BM_OFFSET;
+		break;
+	case DRBD_MD_INDEX_FLEX_EXT:
+		/* just occupy the full device; unit: sectors */
+		bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev);
+		bdev->md.md_offset = 0;
+		bdev->md.al_offset = MD_AL_OFFSET;
+		bdev->md.bm_offset = MD_BM_OFFSET;
+		break;
+	case DRBD_MD_INDEX_INTERNAL:
+	case DRBD_MD_INDEX_FLEX_INT:
+		bdev->md.md_offset = drbd_md_ss__(mdev, bdev);
+		/* al size is still fixed */
+		bdev->md.al_offset = -MD_AL_MAX_SIZE;
+		/* we need (slightly less than) ~ this much bitmap sectors: */
+		md_size_sect = drbd_get_capacity(bdev->backing_bdev);
+		md_size_sect = ALIGN(md_size_sect, BM_SECT_PER_EXT);
+		md_size_sect = BM_SECT_TO_EXT(md_size_sect);
+		md_size_sect = ALIGN(md_size_sect, 8);
+
+		/* plus the "drbd meta data super block",
+		 * and the activity log; */
+		md_size_sect += MD_BM_OFFSET;
+
+		bdev->md.md_size_sect = md_size_sect;
+		/* bitmap offset is adjusted by 'super' block size */
+		bdev->md.bm_offset   = -md_size_sect + MD_AL_OFFSET;
+		break;
+	}
+}
+
+char *ppsize(char *buf, unsigned long long size)
+{
+	/* Needs 9 bytes at max. */
+	static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' };
+	int base = 0;
+	while (size >= 10000) {
+		/* shift + round */
+		size = (size >> 10) + !!(size & (1<<9));
+		base++;
+	}
+	sprintf(buf, "%lu %cB", (long)size, units[base]);
+
+	return buf;
+}
+
+/* there is still a theoretical deadlock when called from receiver
+ * on an D_INCONSISTENT R_PRIMARY:
+ *  remote READ does inc_ap_bio, receiver would need to receive answer
+ *  packet from remote to dec_ap_bio again.
+ *  receiver receive_sizes(), comes here,
+ *  waits for ap_bio_cnt == 0. -> deadlock.
+ * but this cannot happen, actually, because:
+ *  R_PRIMARY D_INCONSISTENT, and peer's disk is unreachable
+ *  (not connected, or bad/no disk on peer):
+ *  see drbd_fail_request_early, ap_bio_cnt is zero.
+ *  R_PRIMARY D_INCONSISTENT, and C_SYNC_TARGET:
+ *  peer may not initiate a resize.
+ */
+void drbd_suspend_io(struct drbd_conf *mdev)
+{
+	set_bit(SUSPEND_IO, &mdev->flags);
+	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
+}
+
+void drbd_resume_io(struct drbd_conf *mdev)
+{
+	clear_bit(SUSPEND_IO, &mdev->flags);
+	wake_up(&mdev->misc_wait);
+}
+
+/**
+ * drbd_determine_dev_size() -  Sets the right device size obeying all constraints
+ * @mdev:	DRBD device.
+ *
+ * Returns 0 on success, negative return values indicate errors.
+ * You should call drbd_md_sync() after calling this function.
+ */
+enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, int force) __must_hold(local)
+{
+	sector_t prev_first_sect, prev_size; /* previous meta location */
+	sector_t la_size;
+	sector_t size;
+	char ppb[10];
+
+	int md_moved, la_size_changed;
+	enum determine_dev_size rv = unchanged;
+
+	/* race:
+	 * application request passes inc_ap_bio,
+	 * but then cannot get an AL-reference.
+	 * this function later may wait on ap_bio_cnt == 0. -> deadlock.
+	 *
+	 * to avoid that:
+	 * Suspend IO right here.
+	 * still lock the act_log to not trigger ASSERTs there.
+	 */
+	drbd_suspend_io(mdev);
+
+	/* no wait necessary anymore, actually we could assert that */
+	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
+
+	prev_first_sect = drbd_md_first_sector(mdev->ldev);
+	prev_size = mdev->ldev->md.md_size_sect;
+	la_size = mdev->ldev->md.la_size_sect;
+
+	/* TODO: should only be some assert here, not (re)init... */
+	drbd_md_set_sector_offsets(mdev, mdev->ldev);
+
+	size = drbd_new_dev_size(mdev, mdev->ldev, force);
+
+	if (drbd_get_capacity(mdev->this_bdev) != size ||
+	    drbd_bm_capacity(mdev) != size) {
+		int err;
+		err = drbd_bm_resize(mdev, size);
+		if (unlikely(err)) {
+			/* currently there is only one error: ENOMEM! */
+			size = drbd_bm_capacity(mdev)>>1;
+			if (size == 0) {
+				dev_err(DEV, "OUT OF MEMORY! "
+				    "Could not allocate bitmap!\n");
+			} else {
+				dev_err(DEV, "BM resizing failed. "
+				    "Leaving size unchanged at size = %lu KB\n",
+				    (unsigned long)size);
+			}
+			rv = dev_size_error;
+		}
+		/* racy, see comments above. */
+		drbd_set_my_capacity(mdev, size);
+		mdev->ldev->md.la_size_sect = size;
+		dev_info(DEV, "size = %s (%llu KB)\n", ppsize(ppb, size>>1),
+		     (unsigned long long)size>>1);
+	}
+	if (rv == dev_size_error)
+		goto out;
+
+	la_size_changed = (la_size != 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) {
+		drbd_al_shrink(mdev); /* All extents inactive. */
+		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");
+		rv = drbd_bitmap_io(mdev, &drbd_bm_write, "size changed"); /* does drbd_resume_io() ! */
+		drbd_md_mark_dirty(mdev);
+	}
+
+	if (size > la_size)
+		rv = grew;
+	if (size < la_size)
+		rv = shrunk;
+out:
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
+	drbd_resume_io(mdev);
+
+	return rv;
+}
+
+sector_t
+drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, int assume_peer_has_space)
+{
+	sector_t p_size = mdev->p_size;   /* partner's disk size. */
+	sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */
+	sector_t m_size; /* my size */
+	sector_t u_size = bdev->dc.disk_size; /* size requested by user. */
+	sector_t size = 0;
+
+	m_size = drbd_get_max_capacity(bdev);
+
+	if (mdev->state.conn < C_CONNECTED && assume_peer_has_space) {
+		dev_warn(DEV, "Resize while not connected was forced by the user!\n");
+		p_size = m_size;
+	}
+
+	if (p_size && m_size) {
+		size = min_t(sector_t, p_size, m_size);
+	} else {
+		if (la_size) {
+			size = la_size;
+			if (m_size && m_size < size)
+				size = m_size;
+			if (p_size && p_size < size)
+				size = p_size;
+		} else {
+			if (m_size)
+				size = m_size;
+			if (p_size)
+				size = p_size;
+		}
+	}
+
+	if (size == 0)
+		dev_err(DEV, "Both nodes diskless!\n");
+
+	if (u_size) {
+		if (u_size > size)
+			dev_err(DEV, "Requested disk size is too big (%lu > %lu)\n",
+			    (unsigned long)u_size>>1, (unsigned long)size>>1);
+		else
+			size = u_size;
+	}
+
+	return size;
+}
+
+/**
+ * drbd_check_al_size() - Ensures that the AL is of the right size
+ * @mdev:	DRBD device.
+ *
+ * Returns -EBUSY if current al lru is still used, -ENOMEM when allocation
+ * failed, and 0 on success. You should call drbd_md_sync() after you called
+ * this function.
+ */
+static int drbd_check_al_size(struct drbd_conf *mdev)
+{
+	struct lru_cache *n, *t;
+	struct lc_element *e;
+	unsigned int in_use;
+	int i;
+
+	ERR_IF(mdev->sync_conf.al_extents < 7)
+		mdev->sync_conf.al_extents = 127;
+
+	if (mdev->act_log &&
+	    mdev->act_log->nr_elements == mdev->sync_conf.al_extents)
+		return 0;
+
+	in_use = 0;
+	t = mdev->act_log;
+	n = lc_create("act_log", drbd_al_ext_cache,
+		mdev->sync_conf.al_extents, sizeof(struct lc_element), 0);
+
+	if (n == NULL) {
+		dev_err(DEV, "Cannot allocate act_log lru!\n");
+		return -ENOMEM;
+	}
+	spin_lock_irq(&mdev->al_lock);
+	if (t) {
+		for (i = 0; i < t->nr_elements; i++) {
+			e = lc_element_by_index(t, i);
+			if (e->refcnt)
+				dev_err(DEV, "refcnt(%d)==%d\n",
+				    e->lc_number, e->refcnt);
+			in_use += e->refcnt;
+		}
+	}
+	if (!in_use)
+		mdev->act_log = n;
+	spin_unlock_irq(&mdev->al_lock);
+	if (in_use) {
+		dev_err(DEV, "Activity log still in use!\n");
+		lc_destroy(n);
+		return -EBUSY;
+	} else {
+		if (t)
+			lc_destroy(t);
+	}
+	drbd_md_mark_dirty(mdev); /* we changed mdev->act_log->nr_elemens */
+	return 0;
+}
+
+void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __must_hold(local)
+{
+	struct request_queue * const q = mdev->rq_queue;
+	struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
+	int max_segments = mdev->ldev->dc.max_bio_bvecs;
+
+	if (b->merge_bvec_fn && !mdev->ldev->dc.use_bmbv)
+		max_seg_s = PAGE_SIZE;
+
+	max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s);
+
+	blk_queue_max_sectors(q, max_seg_s >> 9);
+	blk_queue_max_phys_segments(q, max_segments ? max_segments : MAX_PHYS_SEGMENTS);
+	blk_queue_max_hw_segments(q, max_segments ? max_segments : MAX_HW_SEGMENTS);
+	blk_queue_max_segment_size(q, max_seg_s);
+	blk_queue_logical_block_size(q, 512);
+	blk_queue_segment_boundary(q, PAGE_SIZE-1);
+	blk_stack_limits(&q->limits, &b->limits, 0);
+
+	if (b->merge_bvec_fn)
+		dev_warn(DEV, "Backing device's merge_bvec_fn() = %p\n",
+		     b->merge_bvec_fn);
+	dev_info(DEV, "max_segment_size ( = BIO size ) = %u\n", queue_max_segment_size(q));
+
+	if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
+		dev_info(DEV, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
+		     q->backing_dev_info.ra_pages,
+		     b->backing_dev_info.ra_pages);
+		q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
+	}
+}
+
+/* serialize deconfig (worker exiting, doing cleanup)
+ * and reconfig (drbdsetup disk, drbdsetup net)
+ *
+ * wait for a potentially exiting worker, then restart it,
+ * or start a new one.
+ */
+static void drbd_reconfig_start(struct drbd_conf *mdev)
+{
+	wait_event(mdev->state_wait, !test_and_set_bit(CONFIG_PENDING, &mdev->flags));
+	wait_event(mdev->state_wait, !test_bit(DEVICE_DYING, &mdev->flags));
+	drbd_thread_start(&mdev->worker);
+}
+
+/* if still unconfigured, stops worker again.
+ * if configured now, clears CONFIG_PENDING.
+ * wakes potential waiters */
+static void drbd_reconfig_done(struct drbd_conf *mdev)
+{
+	spin_lock_irq(&mdev->req_lock);
+	if (mdev->state.disk == D_DISKLESS &&
+	    mdev->state.conn == C_STANDALONE &&
+	    mdev->state.role == R_SECONDARY) {
+		set_bit(DEVICE_DYING, &mdev->flags);
+		drbd_thread_stop_nowait(&mdev->worker);
+	} else
+		clear_bit(CONFIG_PENDING, &mdev->flags);
+	spin_unlock_irq(&mdev->req_lock);
+	wake_up(&mdev->state_wait);
+}
+
+/* does always return 0;
+ * interesting return code is in reply->ret_code */
+static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
+{
+	enum drbd_ret_codes retcode;
+	enum determine_dev_size dd;
+	sector_t max_possible_sectors;
+	sector_t min_md_device_sectors;
+	struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
+	struct inode *inode, *inode2;
+	struct lru_cache *resync_lru = NULL;
+	union drbd_state ns, os;
+	int rv;
+	int cp_discovered = 0;
+	int logical_block_size;
+
+	drbd_reconfig_start(mdev);
+
+	/* if you want to reconfigure, please tear down first */
+	if (mdev->state.disk > D_DISKLESS) {
+		retcode = ERR_DISK_CONFIGURED;
+		goto fail;
+	}
+
+	/* allocation not in the IO path, cqueue thread context */
+	nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
+	if (!nbc) {
+		retcode = ERR_NOMEM;
+		goto fail;
+	}
+
+	nbc->dc.disk_size     = DRBD_DISK_SIZE_SECT_DEF;
+	nbc->dc.on_io_error   = DRBD_ON_IO_ERROR_DEF;
+	nbc->dc.fencing       = DRBD_FENCING_DEF;
+	nbc->dc.max_bio_bvecs = DRBD_MAX_BIO_BVECS_DEF;
+
+	if (!disk_conf_from_tags(mdev, nlp->tag_list, &nbc->dc)) {
+		retcode = ERR_MANDATORY_TAG;
+		goto fail;
+	}
+
+	if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) {
+		retcode = ERR_MD_IDX_INVALID;
+		goto fail;
+	}
+
+	nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0);
+	if (IS_ERR(nbc->lo_file)) {
+		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
+		    PTR_ERR(nbc->lo_file));
+		nbc->lo_file = NULL;
+		retcode = ERR_OPEN_DISK;
+		goto fail;
+	}
+
+	inode = nbc->lo_file->f_dentry->d_inode;
+
+	if (!S_ISBLK(inode->i_mode)) {
+		retcode = ERR_DISK_NOT_BDEV;
+		goto fail;
+	}
+
+	nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0);
+	if (IS_ERR(nbc->md_file)) {
+		dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
+		    PTR_ERR(nbc->md_file));
+		nbc->md_file = NULL;
+		retcode = ERR_OPEN_MD_DISK;
+		goto fail;
+	}
+
+	inode2 = nbc->md_file->f_dentry->d_inode;
+
+	if (!S_ISBLK(inode2->i_mode)) {
+		retcode = ERR_MD_NOT_BDEV;
+		goto fail;
+	}
+
+	nbc->backing_bdev = inode->i_bdev;
+	if (bd_claim(nbc->backing_bdev, mdev)) {
+		printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n",
+		       nbc->backing_bdev, mdev,
+		       nbc->backing_bdev->bd_holder,
+		       nbc->backing_bdev->bd_contains->bd_holder,
+		       nbc->backing_bdev->bd_holders);
+		retcode = ERR_BDCLAIM_DISK;
+		goto fail;
+	}
+
+	resync_lru = lc_create("resync", drbd_bm_ext_cache,
+			61, sizeof(struct bm_extent),
+			offsetof(struct bm_extent, lce));
+	if (!resync_lru) {
+		retcode = ERR_NOMEM;
+		goto release_bdev_fail;
+	}
+
+	/* meta_dev_idx >= 0: external fixed size,
+	 * possibly multiple drbd sharing one meta device.
+	 * TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is
+	 * not yet used by some other drbd minor!
+	 * (if you use drbd.conf + drbdadm,
+	 * that should check it for you already; but if you don't, or someone
+	 * fooled it, we need to double check here) */
+	nbc->md_bdev = inode2->i_bdev;
+	if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev
+				: (void *) drbd_m_holder)) {
+		retcode = ERR_BDCLAIM_MD_DISK;
+		goto release_bdev_fail;
+	}
+
+	if ((nbc->backing_bdev == nbc->md_bdev) !=
+	    (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
+	     nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
+		retcode = ERR_MD_IDX_INVALID;
+		goto release_bdev2_fail;
+	}
+
+	/* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
+	drbd_md_set_sector_offsets(mdev, nbc);
+
+	if (drbd_get_max_capacity(nbc) < nbc->dc.disk_size) {
+		dev_err(DEV, "max capacity %llu smaller than disk size %llu\n",
+			(unsigned long long) drbd_get_max_capacity(nbc),
+			(unsigned long long) nbc->dc.disk_size);
+		retcode = ERR_DISK_TO_SMALL;
+		goto release_bdev2_fail;
+	}
+
+	if (nbc->dc.meta_dev_idx < 0) {
+		max_possible_sectors = DRBD_MAX_SECTORS_FLEX;
+		/* at least one MB, otherwise it does not make sense */
+		min_md_device_sectors = (2<<10);
+	} else {
+		max_possible_sectors = DRBD_MAX_SECTORS;
+		min_md_device_sectors = MD_RESERVED_SECT * (nbc->dc.meta_dev_idx + 1);
+	}
+
+	if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) {
+		retcode = ERR_MD_DISK_TO_SMALL;
+		dev_warn(DEV, "refusing attach: md-device too small, "
+		     "at least %llu sectors needed for this meta-disk type\n",
+		     (unsigned long long) min_md_device_sectors);
+		goto release_bdev2_fail;
+	}
+
+	/* Make sure the new disk is big enough
+	 * (we may currently be R_PRIMARY with no local disk...) */
+	if (drbd_get_max_capacity(nbc) <
+	    drbd_get_capacity(mdev->this_bdev)) {
+		retcode = ERR_DISK_TO_SMALL;
+		goto release_bdev2_fail;
+	}
+
+	nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
+
+	if (nbc->known_size > max_possible_sectors) {
+		dev_warn(DEV, "==> truncating very big lower level device "
+			"to currently maximum possible %llu sectors <==\n",
+			(unsigned long long) max_possible_sectors);
+		if (nbc->dc.meta_dev_idx >= 0)
+			dev_warn(DEV, "==>> using internal or flexible "
+				      "meta data may help <<==\n");
+	}
+
+	drbd_suspend_io(mdev);
+	/* also wait for the last barrier ack. */
+	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt));
+	/* and for any other previously queued work */
+	drbd_flush_workqueue(mdev);
+
+	retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
+	drbd_resume_io(mdev);
+	if (retcode < SS_SUCCESS)
+		goto release_bdev2_fail;
+
+	if (!get_ldev_if_state(mdev, D_ATTACHING))
+		goto force_diskless;
+
+	drbd_md_set_sector_offsets(mdev, nbc);
+
+	if (!mdev->bitmap) {
+		if (drbd_bm_init(mdev)) {
+			retcode = ERR_NOMEM;
+			goto force_diskless_dec;
+		}
+	}
+
+	retcode = drbd_md_read(mdev, nbc);
+	if (retcode != NO_ERROR)
+		goto force_diskless_dec;
+
+	if (mdev->state.conn < C_CONNECTED &&
+	    mdev->state.role == R_PRIMARY &&
+	    (mdev->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) {
+		dev_err(DEV, "Can only attach to data with current UUID=%016llX\n",
+		    (unsigned long long)mdev->ed_uuid);
+		retcode = ERR_DATA_NOT_CURRENT;
+		goto force_diskless_dec;
+	}
+
+	/* Since we are diskless, fix the activity log first... */
+	if (drbd_check_al_size(mdev)) {
+		retcode = ERR_NOMEM;
+		goto force_diskless_dec;
+	}
+
+	/* Prevent shrinking of consistent devices ! */
+	if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
+	    drbd_new_dev_size(mdev, nbc, 0) < nbc->md.la_size_sect) {
+		dev_warn(DEV, "refusing to truncate a consistent device\n");
+		retcode = ERR_DISK_TO_SMALL;
+		goto force_diskless_dec;
+	}
+
+	if (!drbd_al_read_log(mdev, nbc)) {
+		retcode = ERR_IO_MD_DISK;
+		goto force_diskless_dec;
+	}
+
+	/* allocate a second IO page if logical_block_size != 512 */
+	logical_block_size = bdev_logical_block_size(nbc->md_bdev);
+	if (logical_block_size == 0)
+		logical_block_size = MD_SECTOR_SIZE;
+
+	if (logical_block_size != MD_SECTOR_SIZE) {
+		if (!mdev->md_io_tmpp) {
+			struct page *page = alloc_page(GFP_NOIO);
+			if (!page)
+				goto force_diskless_dec;
+
+			dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
+			     logical_block_size, MD_SECTOR_SIZE);
+			dev_warn(DEV, "Workaround engaged (has performance impact).\n");
+
+			mdev->md_io_tmpp = page;
+		}
+	}
+
+	/* Reset the "barriers don't work" bits here, then force meta data to
+	 * be written, to ensure we determine if barriers are supported. */
+	if (nbc->dc.no_md_flush)
+		set_bit(MD_NO_BARRIER, &mdev->flags);
+	else
+		clear_bit(MD_NO_BARRIER, &mdev->flags);
+
+	/* Point of no return reached.
+	 * Devices and memory are no longer released by error cleanup below.
+	 * now mdev takes over responsibility, and the state engine should
+	 * clean it up somewhere.  */
+	D_ASSERT(mdev->ldev == NULL);
+	mdev->ldev = nbc;
+	mdev->resync = resync_lru;
+	nbc = NULL;
+	resync_lru = NULL;
+
+	mdev->write_ordering = WO_bio_barrier;
+	drbd_bump_write_ordering(mdev, WO_bio_barrier);
+
+	if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY))
+		set_bit(CRASHED_PRIMARY, &mdev->flags);
+	else
+		clear_bit(CRASHED_PRIMARY, &mdev->flags);
+
+	if (drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND)) {
+		set_bit(CRASHED_PRIMARY, &mdev->flags);
+		cp_discovered = 1;
+	}
+
+	mdev->send_cnt = 0;
+	mdev->recv_cnt = 0;
+	mdev->read_cnt = 0;
+	mdev->writ_cnt = 0;
+
+	drbd_setup_queue_param(mdev, DRBD_MAX_SEGMENT_SIZE);
+
+	/* If I am currently not R_PRIMARY,
+	 * but meta data primary indicator is set,
+	 * I just now recover from a hard crash,
+	 * and have been R_PRIMARY before that crash.
+	 *
+	 * Now, if I had no connection before that crash
+	 * (have been degraded R_PRIMARY), chances are that
+	 * I won't find my peer now either.
+	 *
+	 * In that case, and _only_ in that case,
+	 * we use the degr-wfc-timeout instead of the default,
+	 * so we can automatically recover from a crash of a
+	 * degraded but active "cluster" after a certain timeout.
+	 */
+	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
+	if (mdev->state.role != R_PRIMARY &&
+	     drbd_md_test_flag(mdev->ldev, MDF_PRIMARY_IND) &&
+	    !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND))
+		set_bit(USE_DEGR_WFC_T, &mdev->flags);
+
+	dd = drbd_determin_dev_size(mdev, 0);
+	if (dd == dev_size_error) {
+		retcode = ERR_NOMEM_BITMAP;
+		goto force_diskless_dec;
+	} else if (dd == grew)
+		set_bit(RESYNC_AFTER_NEG, &mdev->flags);
+
+	if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC)) {
+		dev_info(DEV, "Assuming that all blocks are out of sync "
+		     "(aka FullSync)\n");
+		if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from attaching")) {
+			retcode = ERR_IO_MD_DISK;
+			goto force_diskless_dec;
+		}
+	} else {
+		if (drbd_bitmap_io(mdev, &drbd_bm_read, "read from attaching") < 0) {
+			retcode = ERR_IO_MD_DISK;
+			goto force_diskless_dec;
+		}
+	}
+
+	if (cp_discovered) {
+		drbd_al_apply_to_bm(mdev);
+		drbd_al_to_on_disk_bm(mdev);
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	os = mdev->state;
+	ns.i = os.i;
+	/* If MDF_CONSISTENT is not set go into inconsistent state,
+	   otherwise investigate MDF_WasUpToDate...
+	   If MDF_WAS_UP_TO_DATE is not set go into D_OUTDATED disk state,
+	   otherwise into D_CONSISTENT state.
+	*/
+	if (drbd_md_test_flag(mdev->ldev, MDF_CONSISTENT)) {
+		if (drbd_md_test_flag(mdev->ldev, MDF_WAS_UP_TO_DATE))
+			ns.disk = D_CONSISTENT;
+		else
+			ns.disk = D_OUTDATED;
+	} else {
+		ns.disk = D_INCONSISTENT;
+	}
+
+	if (drbd_md_test_flag(mdev->ldev, MDF_PEER_OUT_DATED))
+		ns.pdsk = D_OUTDATED;
+
+	if ( ns.disk == D_CONSISTENT &&
+	    (ns.pdsk == D_OUTDATED || mdev->ldev->dc.fencing == FP_DONT_CARE))
+		ns.disk = D_UP_TO_DATE;
+
+	/* All tests on MDF_PRIMARY_IND, MDF_CONNECTED_IND,
+	   MDF_CONSISTENT and MDF_WAS_UP_TO_DATE must happen before
+	   this point, because drbd_request_state() modifies these
+	   flags. */
+
+	/* In case we are C_CONNECTED postpone any decision on the new disk
+	   state after the negotiation phase. */
+	if (mdev->state.conn == C_CONNECTED) {
+		mdev->new_state_tmp.i = ns.i;
+		ns.i = os.i;
+		ns.disk = D_NEGOTIATING;
+	}
+
+	rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
+	ns = mdev->state;
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (rv < SS_SUCCESS)
+		goto force_diskless_dec;
+
+	if (mdev->state.role == R_PRIMARY)
+		mdev->ldev->md.uuid[UI_CURRENT] |=  (u64)1;
+	else
+		mdev->ldev->md.uuid[UI_CURRENT] &= ~(u64)1;
+
+	drbd_md_mark_dirty(mdev);
+	drbd_md_sync(mdev);
+
+	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
+	put_ldev(mdev);
+	reply->ret_code = retcode;
+	drbd_reconfig_done(mdev);
+	return 0;
+
+ force_diskless_dec:
+	put_ldev(mdev);
+ force_diskless:
+	drbd_force_state(mdev, NS(disk, D_DISKLESS));
+	drbd_md_sync(mdev);
+ release_bdev2_fail:
+	if (nbc)
+		bd_release(nbc->md_bdev);
+ release_bdev_fail:
+	if (nbc)
+		bd_release(nbc->backing_bdev);
+ fail:
+	if (nbc) {
+		if (nbc->lo_file)
+			fput(nbc->lo_file);
+		if (nbc->md_file)
+			fput(nbc->md_file);
+		kfree(nbc);
+	}
+	lc_destroy(resync_lru);
+
+	reply->ret_code = retcode;
+	drbd_reconfig_done(mdev);
+	return 0;
+}
+
+static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			  struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS));
+	return 0;
+}
+
+static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			    struct drbd_nl_cfg_reply *reply)
+{
+	int i, ns;
+	enum drbd_ret_codes retcode;
+	struct net_conf *new_conf = NULL;
+	struct crypto_hash *tfm = NULL;
+	struct crypto_hash *integrity_w_tfm = NULL;
+	struct crypto_hash *integrity_r_tfm = NULL;
+	struct hlist_head *new_tl_hash = NULL;
+	struct hlist_head *new_ee_hash = NULL;
+	struct drbd_conf *odev;
+	char hmac_name[CRYPTO_MAX_ALG_NAME];
+	void *int_dig_out = NULL;
+	void *int_dig_in = NULL;
+	void *int_dig_vv = NULL;
+	struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr;
+
+	drbd_reconfig_start(mdev);
+
+	if (mdev->state.conn > C_STANDALONE) {
+		retcode = ERR_NET_CONFIGURED;
+		goto fail;
+	}
+
+	/* allocation not in the IO path, cqueue thread context */
+	new_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL);
+	if (!new_conf) {
+		retcode = ERR_NOMEM;
+		goto fail;
+	}
+
+	memset(new_conf, 0, sizeof(struct net_conf));
+	new_conf->timeout	   = DRBD_TIMEOUT_DEF;
+	new_conf->try_connect_int  = DRBD_CONNECT_INT_DEF;
+	new_conf->ping_int	   = DRBD_PING_INT_DEF;
+	new_conf->max_epoch_size   = DRBD_MAX_EPOCH_SIZE_DEF;
+	new_conf->max_buffers	   = DRBD_MAX_BUFFERS_DEF;
+	new_conf->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF;
+	new_conf->sndbuf_size	   = DRBD_SNDBUF_SIZE_DEF;
+	new_conf->rcvbuf_size	   = DRBD_RCVBUF_SIZE_DEF;
+	new_conf->ko_count	   = DRBD_KO_COUNT_DEF;
+	new_conf->after_sb_0p	   = DRBD_AFTER_SB_0P_DEF;
+	new_conf->after_sb_1p	   = DRBD_AFTER_SB_1P_DEF;
+	new_conf->after_sb_2p	   = DRBD_AFTER_SB_2P_DEF;
+	new_conf->want_lose	   = 0;
+	new_conf->two_primaries    = 0;
+	new_conf->wire_protocol    = DRBD_PROT_C;
+	new_conf->ping_timeo	   = DRBD_PING_TIMEO_DEF;
+	new_conf->rr_conflict	   = DRBD_RR_CONFLICT_DEF;
+
+	if (!net_conf_from_tags(mdev, nlp->tag_list, new_conf)) {
+		retcode = ERR_MANDATORY_TAG;
+		goto fail;
+	}
+
+	if (new_conf->two_primaries
+	    && (new_conf->wire_protocol != DRBD_PROT_C)) {
+		retcode = ERR_NOT_PROTO_C;
+		goto fail;
+	};
+
+	if (mdev->state.role == R_PRIMARY && new_conf->want_lose) {
+		retcode = ERR_DISCARD;
+		goto fail;
+	}
+
+	retcode = NO_ERROR;
+
+	new_my_addr = (struct sockaddr *)&new_conf->my_addr;
+	new_peer_addr = (struct sockaddr *)&new_conf->peer_addr;
+	for (i = 0; i < minor_count; i++) {
+		odev = minor_to_mdev(i);
+		if (!odev || odev == mdev)
+			continue;
+		if (get_net_conf(odev)) {
+			taken_addr = (struct sockaddr *)&odev->net_conf->my_addr;
+			if (new_conf->my_addr_len == odev->net_conf->my_addr_len &&
+			    !memcmp(new_my_addr, taken_addr, new_conf->my_addr_len))
+				retcode = ERR_LOCAL_ADDR;
+
+			taken_addr = (struct sockaddr *)&odev->net_conf->peer_addr;
+			if (new_conf->peer_addr_len == odev->net_conf->peer_addr_len &&
+			    !memcmp(new_peer_addr, taken_addr, new_conf->peer_addr_len))
+				retcode = ERR_PEER_ADDR;
+
+			put_net_conf(odev);
+			if (retcode != NO_ERROR)
+				goto fail;
+		}
+	}
+
+	if (new_conf->cram_hmac_alg[0] != 0) {
+		snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
+			new_conf->cram_hmac_alg);
+		tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC);
+		if (IS_ERR(tfm)) {
+			tfm = NULL;
+			retcode = ERR_AUTH_ALG;
+			goto fail;
+		}
+
+		if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
+			retcode = ERR_AUTH_ALG_ND;
+			goto fail;
+		}
+	}
+
+	if (new_conf->integrity_alg[0]) {
+		integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
+		if (IS_ERR(integrity_w_tfm)) {
+			integrity_w_tfm = NULL;
+			retcode=ERR_INTEGRITY_ALG;
+			goto fail;
+		}
+
+		if (!drbd_crypto_is_hash(crypto_hash_tfm(integrity_w_tfm))) {
+			retcode=ERR_INTEGRITY_ALG_ND;
+			goto fail;
+		}
+
+		integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
+		if (IS_ERR(integrity_r_tfm)) {
+			integrity_r_tfm = NULL;
+			retcode=ERR_INTEGRITY_ALG;
+			goto fail;
+		}
+	}
+
+	ns = new_conf->max_epoch_size/8;
+	if (mdev->tl_hash_s != ns) {
+		new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
+		if (!new_tl_hash) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+	}
+
+	ns = new_conf->max_buffers/8;
+	if (new_conf->two_primaries && (mdev->ee_hash_s != ns)) {
+		new_ee_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL);
+		if (!new_ee_hash) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+	}
+
+	((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
+
+	if (integrity_w_tfm) {
+		i = crypto_hash_digestsize(integrity_w_tfm);
+		int_dig_out = kmalloc(i, GFP_KERNEL);
+		if (!int_dig_out) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+		int_dig_in = kmalloc(i, GFP_KERNEL);
+		if (!int_dig_in) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+		int_dig_vv = kmalloc(i, GFP_KERNEL);
+		if (!int_dig_vv) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+	}
+
+	if (!mdev->bitmap) {
+		if(drbd_bm_init(mdev)) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	if (mdev->net_conf != NULL) {
+		retcode = ERR_NET_CONFIGURED;
+		spin_unlock_irq(&mdev->req_lock);
+		goto fail;
+	}
+	mdev->net_conf = new_conf;
+
+	mdev->send_cnt = 0;
+	mdev->recv_cnt = 0;
+
+	if (new_tl_hash) {
+		kfree(mdev->tl_hash);
+		mdev->tl_hash_s = mdev->net_conf->max_epoch_size/8;
+		mdev->tl_hash = new_tl_hash;
+	}
+
+	if (new_ee_hash) {
+		kfree(mdev->ee_hash);
+		mdev->ee_hash_s = mdev->net_conf->max_buffers/8;
+		mdev->ee_hash = new_ee_hash;
+	}
+
+	crypto_free_hash(mdev->cram_hmac_tfm);
+	mdev->cram_hmac_tfm = tfm;
+
+	crypto_free_hash(mdev->integrity_w_tfm);
+	mdev->integrity_w_tfm = integrity_w_tfm;
+
+	crypto_free_hash(mdev->integrity_r_tfm);
+	mdev->integrity_r_tfm = integrity_r_tfm;
+
+	kfree(mdev->int_dig_out);
+	kfree(mdev->int_dig_in);
+	kfree(mdev->int_dig_vv);
+	mdev->int_dig_out=int_dig_out;
+	mdev->int_dig_in=int_dig_in;
+	mdev->int_dig_vv=int_dig_vv;
+	spin_unlock_irq(&mdev->req_lock);
+
+	retcode = _drbd_request_state(mdev, NS(conn, C_UNCONNECTED), CS_VERBOSE);
+
+	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
+	reply->ret_code = retcode;
+	drbd_reconfig_done(mdev);
+	return 0;
+
+fail:
+	kfree(int_dig_out);
+	kfree(int_dig_in);
+	kfree(int_dig_vv);
+	crypto_free_hash(tfm);
+	crypto_free_hash(integrity_w_tfm);
+	crypto_free_hash(integrity_r_tfm);
+	kfree(new_tl_hash);
+	kfree(new_ee_hash);
+	kfree(new_conf);
+
+	reply->ret_code = retcode;
+	drbd_reconfig_done(mdev);
+	return 0;
+}
+
+static int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
+{
+	int retcode;
+
+	retcode = _drbd_request_state(mdev, NS(conn, C_DISCONNECTING), CS_ORDERED);
+
+	if (retcode == SS_NOTHING_TO_DO)
+		goto done;
+	else if (retcode == SS_ALREADY_STANDALONE)
+		goto done;
+	else if (retcode == SS_PRIMARY_NOP) {
+		/* Our statche checking code wants to see the peer outdated. */
+		retcode = drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
+						      pdsk, D_OUTDATED));
+	} else if (retcode == SS_CW_FAILED_BY_PEER) {
+		/* The peer probably wants to see us outdated. */
+		retcode = _drbd_request_state(mdev, NS2(conn, C_DISCONNECTING,
+							disk, D_OUTDATED),
+					      CS_ORDERED);
+		if (retcode == SS_IS_DISKLESS || retcode == SS_LOWER_THAN_OUTDATED) {
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			retcode = SS_SUCCESS;
+		}
+	}
+
+	if (retcode < SS_SUCCESS)
+		goto fail;
+
+	if (wait_event_interruptible(mdev->state_wait,
+				     mdev->state.conn != C_DISCONNECTING)) {
+		/* Do not test for mdev->state.conn == C_STANDALONE, since
+		   someone else might connect us in the mean time! */
+		retcode = ERR_INTR;
+		goto fail;
+	}
+
+ done:
+	retcode = NO_ERROR;
+ fail:
+	drbd_md_sync(mdev);
+	reply->ret_code = retcode;
+	return 0;
+}
+
+void resync_after_online_grow(struct drbd_conf *mdev)
+{
+	int iass; /* I am sync source */
+
+	dev_info(DEV, "Resync of new storage after online grow\n");
+	if (mdev->state.role != mdev->state.peer)
+		iass = (mdev->state.role == R_PRIMARY);
+	else
+		iass = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+
+	if (iass)
+		drbd_start_resync(mdev, C_SYNC_SOURCE);
+	else
+		_drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE + CS_SERIALIZE);
+}
+
+static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			  struct drbd_nl_cfg_reply *reply)
+{
+	struct resize rs;
+	int retcode = NO_ERROR;
+	int ldsc = 0; /* local disk size changed */
+	enum determine_dev_size dd;
+
+	memset(&rs, 0, sizeof(struct resize));
+	if (!resize_from_tags(mdev, nlp->tag_list, &rs)) {
+		retcode = ERR_MANDATORY_TAG;
+		goto fail;
+	}
+
+	if (mdev->state.conn > C_CONNECTED) {
+		retcode = ERR_RESIZE_RESYNC;
+		goto fail;
+	}
+
+	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;
+	}
+
+	if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) {
+		mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
+		ldsc = 1;
+	}
+
+	mdev->ldev->dc.disk_size = (sector_t)rs.resize_size;
+	dd = drbd_determin_dev_size(mdev, rs.resize_force);
+	drbd_md_sync(mdev);
+	put_ldev(mdev);
+	if (dd == dev_size_error) {
+		retcode = ERR_NOMEM_BITMAP;
+		goto fail;
+	}
+
+	if (mdev->state.conn == C_CONNECTED && (dd != unchanged || ldsc)) {
+		if (dd == grew)
+			set_bit(RESIZE_PENDING, &mdev->flags);
+
+		drbd_send_uuids(mdev);
+		drbd_send_sizes(mdev, 1);
+	}
+
+ fail:
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			       struct drbd_nl_cfg_reply *reply)
+{
+	int retcode = NO_ERROR;
+	int err;
+	int ovr; /* online verify running */
+	int rsr; /* re-sync running */
+	struct crypto_hash *verify_tfm = NULL;
+	struct crypto_hash *csums_tfm = NULL;
+	struct syncer_conf sc;
+	cpumask_var_t new_cpu_mask;
+
+	if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) {
+		retcode = ERR_NOMEM;
+		goto fail;
+	}
+
+	if (nlp->flags & DRBD_NL_SET_DEFAULTS) {
+		memset(&sc, 0, sizeof(struct syncer_conf));
+		sc.rate       = DRBD_RATE_DEF;
+		sc.after      = DRBD_AFTER_DEF;
+		sc.al_extents = DRBD_AL_EXTENTS_DEF;
+	} else
+		memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf));
+
+	if (!syncer_conf_from_tags(mdev, nlp->tag_list, &sc)) {
+		retcode = ERR_MANDATORY_TAG;
+		goto fail;
+	}
+
+	/* re-sync running */
+	rsr = (	mdev->state.conn == C_SYNC_SOURCE ||
+		mdev->state.conn == C_SYNC_TARGET ||
+		mdev->state.conn == C_PAUSED_SYNC_S ||
+		mdev->state.conn == C_PAUSED_SYNC_T );
+
+	if (rsr && strcmp(sc.csums_alg, mdev->sync_conf.csums_alg)) {
+		retcode = ERR_CSUMS_RESYNC_RUNNING;
+		goto fail;
+	}
+
+	if (!rsr && sc.csums_alg[0]) {
+		csums_tfm = crypto_alloc_hash(sc.csums_alg, 0, CRYPTO_ALG_ASYNC);
+		if (IS_ERR(csums_tfm)) {
+			csums_tfm = NULL;
+			retcode = ERR_CSUMS_ALG;
+			goto fail;
+		}
+
+		if (!drbd_crypto_is_hash(crypto_hash_tfm(csums_tfm))) {
+			retcode = ERR_CSUMS_ALG_ND;
+			goto fail;
+		}
+	}
+
+	/* online verify running */
+	ovr = (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T);
+
+	if (ovr) {
+		if (strcmp(sc.verify_alg, mdev->sync_conf.verify_alg)) {
+			retcode = ERR_VERIFY_RUNNING;
+			goto fail;
+		}
+	}
+
+	if (!ovr && sc.verify_alg[0]) {
+		verify_tfm = crypto_alloc_hash(sc.verify_alg, 0, CRYPTO_ALG_ASYNC);
+		if (IS_ERR(verify_tfm)) {
+			verify_tfm = NULL;
+			retcode = ERR_VERIFY_ALG;
+			goto fail;
+		}
+
+		if (!drbd_crypto_is_hash(crypto_hash_tfm(verify_tfm))) {
+			retcode = ERR_VERIFY_ALG_ND;
+			goto fail;
+		}
+	}
+
+	/* silently ignore cpu mask on UP kernel */
+	if (nr_cpu_ids > 1 && sc.cpu_mask[0] != 0) {
+		err = __bitmap_parse(sc.cpu_mask, 32, 0,
+				cpumask_bits(new_cpu_mask), nr_cpu_ids);
+		if (err) {
+			dev_warn(DEV, "__bitmap_parse() failed with %d\n", err);
+			retcode = ERR_CPU_MASK_PARSE;
+			goto fail;
+		}
+	}
+
+	ERR_IF (sc.rate < 1) sc.rate = 1;
+	ERR_IF (sc.al_extents < 7) sc.al_extents = 127; /* arbitrary minimum */
+#define AL_MAX ((MD_AL_MAX_SIZE-1) * AL_EXTENTS_PT)
+	if (sc.al_extents > AL_MAX) {
+		dev_err(DEV, "sc.al_extents > %d\n", AL_MAX);
+		sc.al_extents = AL_MAX;
+	}
+#undef AL_MAX
+
+	/* most sanity checks done, try to assign the new sync-after
+	 * dependency.  need to hold the global lock in there,
+	 * to avoid a race in the dependency loop check. */
+	retcode = drbd_alter_sa(mdev, sc.after);
+	if (retcode != NO_ERROR)
+		goto fail;
+
+	/* ok, assign the rest of it as well.
+	 * lock against receive_SyncParam() */
+	spin_lock(&mdev->peer_seq_lock);
+	mdev->sync_conf = sc;
+
+	if (!rsr) {
+		crypto_free_hash(mdev->csums_tfm);
+		mdev->csums_tfm = csums_tfm;
+		csums_tfm = NULL;
+	}
+
+	if (!ovr) {
+		crypto_free_hash(mdev->verify_tfm);
+		mdev->verify_tfm = verify_tfm;
+		verify_tfm = NULL;
+	}
+	spin_unlock(&mdev->peer_seq_lock);
+
+	if (get_ldev(mdev)) {
+		wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
+		drbd_al_shrink(mdev);
+		err = drbd_check_al_size(mdev);
+		lc_unlock(mdev->act_log);
+		wake_up(&mdev->al_wait);
+
+		put_ldev(mdev);
+		drbd_md_sync(mdev);
+
+		if (err) {
+			retcode = ERR_NOMEM;
+			goto fail;
+		}
+	}
+
+	if (mdev->state.conn >= C_CONNECTED)
+		drbd_send_sync_param(mdev, &sc);
+
+	if (!cpumask_equal(mdev->cpu_mask, new_cpu_mask)) {
+		cpumask_copy(mdev->cpu_mask, new_cpu_mask);
+		drbd_calc_cpu_mask(mdev);
+		mdev->receiver.reset_cpu_mask = 1;
+		mdev->asender.reset_cpu_mask = 1;
+		mdev->worker.reset_cpu_mask = 1;
+	}
+
+	kobject_uevent(&disk_to_dev(mdev->vdisk)->kobj, KOBJ_CHANGE);
+fail:
+	free_cpumask_var(new_cpu_mask);
+	crypto_free_hash(csums_tfm);
+	crypto_free_hash(verify_tfm);
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
+{
+	int retcode;
+
+	retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T), CS_ORDERED);
+
+	if (retcode < SS_SUCCESS && retcode != SS_NEED_CONNECTION)
+		retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T));
+
+	while (retcode == SS_NEED_CONNECTION) {
+		spin_lock_irq(&mdev->req_lock);
+		if (mdev->state.conn < C_CONNECTED)
+			retcode = _drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_VERBOSE, NULL);
+		spin_unlock_irq(&mdev->req_lock);
+
+		if (retcode != SS_NEED_CONNECTION)
+			break;
+
+		retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T));
+	}
+
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+				   struct drbd_nl_cfg_reply *reply)
+{
+
+	reply->ret_code = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S));
+
+	return 0;
+}
+
+static int drbd_nl_pause_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
+{
+	int retcode = NO_ERROR;
+
+	if (drbd_request_state(mdev, NS(user_isp, 1)) == SS_NOTHING_TO_DO)
+		retcode = ERR_PAUSE_IS_SET;
+
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static int drbd_nl_resume_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			       struct drbd_nl_cfg_reply *reply)
+{
+	int retcode = NO_ERROR;
+
+	if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NOTHING_TO_DO)
+		retcode = ERR_PAUSE_IS_CLEAR;
+
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_request_state(mdev, NS(susp, 1));
+
+	return 0;
+}
+
+static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_request_state(mdev, NS(susp, 0));
+	return 0;
+}
+
+static int drbd_nl_outdate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_request_state(mdev, NS(disk, D_OUTDATED));
+	return 0;
+}
+
+static int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
+{
+	unsigned short *tl;
+
+	tl = reply->tag_list;
+
+	if (get_ldev(mdev)) {
+		tl = disk_conf_to_tags(mdev, &mdev->ldev->dc, tl);
+		put_ldev(mdev);
+	}
+
+	if (get_net_conf(mdev)) {
+		tl = net_conf_to_tags(mdev, mdev->net_conf, tl);
+		put_net_conf(mdev);
+	}
+	tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl);
+
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	return (int)((char *)tl - (char *)reply->tag_list);
+}
+
+static int drbd_nl_get_state(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
+{
+	unsigned short *tl = reply->tag_list;
+	union drbd_state s = mdev->state;
+	unsigned long rs_left;
+	unsigned int res;
+
+	tl = get_state_to_tags(mdev, (struct get_state *)&s, tl);
+
+	/* no local ref, no bitmap, no syncer progress. */
+	if (s.conn >= C_SYNC_SOURCE && s.conn <= C_PAUSED_SYNC_T) {
+		if (get_ldev(mdev)) {
+			drbd_get_syncer_progress(mdev, &rs_left, &res);
+			tl = tl_add_int(tl, T_sync_progress, &res);
+			put_ldev(mdev);
+		}
+	}
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	return (int)((char *)tl - (char *)reply->tag_list);
+}
+
+static int drbd_nl_get_uuids(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			     struct drbd_nl_cfg_reply *reply)
+{
+	unsigned short *tl;
+
+	tl = reply->tag_list;
+
+	if (get_ldev(mdev)) {
+		tl = tl_add_blob(tl, T_uuids, mdev->ldev->md.uuid, UI_SIZE*sizeof(u64));
+		tl = tl_add_int(tl, T_uuids_flags, &mdev->ldev->md.flags);
+		put_ldev(mdev);
+	}
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	return (int)((char *)tl - (char *)reply->tag_list);
+}
+
+/**
+ * drbd_nl_get_timeout_flag() - Used by drbdsetup to find out which timeout value to use
+ * @mdev:	DRBD device.
+ * @nlp:	Netlink/connector packet from drbdsetup
+ * @reply:	Reply packet for drbdsetup
+ */
+static int drbd_nl_get_timeout_flag(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+				    struct drbd_nl_cfg_reply *reply)
+{
+	unsigned short *tl;
+	char rv;
+
+	tl = reply->tag_list;
+
+	rv = mdev->state.pdsk == D_OUTDATED        ? UT_PEER_OUTDATED :
+	  test_bit(USE_DEGR_WFC_T, &mdev->flags) ? UT_DEGRADED : UT_DEFAULT;
+
+	tl = tl_add_blob(tl, T_use_degraded, &rv, sizeof(rv));
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	return (int)((char *)tl - (char *)reply->tag_list);
+}
+
+static int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+				    struct drbd_nl_cfg_reply *reply)
+{
+	/* default to resume from last known position, if possible */
+	struct start_ov args =
+		{ .start_sector = mdev->ov_start_sector };
+
+	if (!start_ov_from_tags(mdev, nlp->tag_list, &args)) {
+		reply->ret_code = ERR_MANDATORY_TAG;
+		return 0;
+	}
+	/* w_make_ov_request expects position to be aligned */
+	mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT;
+	reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S));
+	return 0;
+}
+
+
+static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
+			      struct drbd_nl_cfg_reply *reply)
+{
+	int retcode = NO_ERROR;
+	int skip_initial_sync = 0;
+	int err;
+
+	struct new_c_uuid args;
+
+	memset(&args, 0, sizeof(struct new_c_uuid));
+	if (!new_c_uuid_from_tags(mdev, nlp->tag_list, &args)) {
+		reply->ret_code = ERR_MANDATORY_TAG;
+		return 0;
+	}
+
+	mutex_lock(&mdev->state_mutex); /* Protects us against serialized state changes. */
+
+	if (!get_ldev(mdev)) {
+		retcode = ERR_NO_DISK;
+		goto out;
+	}
+
+	/* this is "skip initial sync", assume to be clean */
+	if (mdev->state.conn == C_CONNECTED && mdev->agreed_pro_version >= 90 &&
+	    mdev->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED && args.clear_bm) {
+		dev_info(DEV, "Preparing to skip initial sync\n");
+		skip_initial_sync = 1;
+	} else if (mdev->state.conn != C_STANDALONE) {
+		retcode = ERR_CONNECTED;
+		goto out_dec;
+	}
+
+	drbd_uuid_set(mdev, UI_BITMAP, 0); /* Rotate UI_BITMAP to History 1, etc... */
+	drbd_uuid_new_current(mdev); /* New current, previous to UI_BITMAP */
+
+	if (args.clear_bm) {
+		err = drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write, "clear_n_write from new_c_uuid");
+		if (err) {
+			dev_err(DEV, "Writing bitmap failed with %d\n",err);
+			retcode = ERR_IO_MD_DISK;
+		}
+		if (skip_initial_sync) {
+			drbd_send_uuids_skip_initial_sync(mdev);
+			_drbd_uuid_set(mdev, UI_BITMAP, 0);
+			spin_lock_irq(&mdev->req_lock);
+			_drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
+					CS_VERBOSE, NULL);
+			spin_unlock_irq(&mdev->req_lock);
+		}
+	}
+
+	drbd_md_sync(mdev);
+out_dec:
+	put_ldev(mdev);
+out:
+	mutex_unlock(&mdev->state_mutex);
+
+	reply->ret_code = retcode;
+	return 0;
+}
+
+static struct drbd_conf *ensure_mdev(struct drbd_nl_cfg_req *nlp)
+{
+	struct drbd_conf *mdev;
+
+	if (nlp->drbd_minor >= minor_count)
+		return NULL;
+
+	mdev = minor_to_mdev(nlp->drbd_minor);
+
+	if (!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) {
+		struct gendisk *disk = NULL;
+		mdev = drbd_new_device(nlp->drbd_minor);
+
+		spin_lock_irq(&drbd_pp_lock);
+		if (minor_table[nlp->drbd_minor] == NULL) {
+			minor_table[nlp->drbd_minor] = mdev;
+			disk = mdev->vdisk;
+			mdev = NULL;
+		} /* else: we lost the race */
+		spin_unlock_irq(&drbd_pp_lock);
+
+		if (disk) /* we won the race above */
+			/* in case we ever add a drbd_delete_device(),
+			 * don't forget the del_gendisk! */
+			add_disk(disk);
+		else /* we lost the race above */
+			drbd_free_mdev(mdev);
+
+		mdev = minor_to_mdev(nlp->drbd_minor);
+	}
+
+	return mdev;
+}
+
+struct cn_handler_struct {
+	int (*function)(struct drbd_conf *,
+			 struct drbd_nl_cfg_req *,
+			 struct drbd_nl_cfg_reply *);
+	int reply_body_size;
+};
+
+static struct cn_handler_struct cnd_table[] = {
+	[ P_primary ]		= { &drbd_nl_primary,		0 },
+	[ P_secondary ]		= { &drbd_nl_secondary,		0 },
+	[ P_disk_conf ]		= { &drbd_nl_disk_conf,		0 },
+	[ P_detach ]		= { &drbd_nl_detach,		0 },
+	[ P_net_conf ]		= { &drbd_nl_net_conf,		0 },
+	[ P_disconnect ]	= { &drbd_nl_disconnect,	0 },
+	[ P_resize ]		= { &drbd_nl_resize,		0 },
+	[ P_syncer_conf ]	= { &drbd_nl_syncer_conf,	0 },
+	[ P_invalidate ]	= { &drbd_nl_invalidate,	0 },
+	[ P_invalidate_peer ]	= { &drbd_nl_invalidate_peer,	0 },
+	[ P_pause_sync ]	= { &drbd_nl_pause_sync,	0 },
+	[ P_resume_sync ]	= { &drbd_nl_resume_sync,	0 },
+	[ P_suspend_io ]	= { &drbd_nl_suspend_io,	0 },
+	[ P_resume_io ]		= { &drbd_nl_resume_io,		0 },
+	[ P_outdate ]		= { &drbd_nl_outdate,		0 },
+	[ P_get_config ]	= { &drbd_nl_get_config,
+				    sizeof(struct syncer_conf_tag_len_struct) +
+				    sizeof(struct disk_conf_tag_len_struct) +
+				    sizeof(struct net_conf_tag_len_struct) },
+	[ P_get_state ]		= { &drbd_nl_get_state,
+				    sizeof(struct get_state_tag_len_struct) +
+				    sizeof(struct sync_progress_tag_len_struct)	},
+	[ P_get_uuids ]		= { &drbd_nl_get_uuids,
+				    sizeof(struct get_uuids_tag_len_struct) },
+	[ P_get_timeout_flag ]	= { &drbd_nl_get_timeout_flag,
+				    sizeof(struct get_timeout_flag_tag_len_struct)},
+	[ P_start_ov ]		= { &drbd_nl_start_ov,		0 },
+	[ P_new_c_uuid ]	= { &drbd_nl_new_c_uuid,	0 },
+};
+
+static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms *nsp)
+{
+	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data;
+	struct cn_handler_struct *cm;
+	struct cn_msg *cn_reply;
+	struct drbd_nl_cfg_reply *reply;
+	struct drbd_conf *mdev;
+	int retcode, rr;
+	int reply_size = sizeof(struct cn_msg)
+		+ sizeof(struct drbd_nl_cfg_reply)
+		+ sizeof(short int);
+
+	if (!try_module_get(THIS_MODULE)) {
+		printk(KERN_ERR "drbd: try_module_get() failed!\n");
+		return;
+	}
+
+	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
+		retcode = ERR_PERM;
+		goto fail;
+	}
+
+	mdev = ensure_mdev(nlp);
+	if (!mdev) {
+		retcode = ERR_MINOR_INVALID;
+		goto fail;
+	}
+
+	if (nlp->packet_type >= P_nl_after_last_packet) {
+		retcode = ERR_PACKET_NR;
+		goto fail;
+	}
+
+	cm = cnd_table + nlp->packet_type;
+
+	/* This may happen if packet number is 0: */
+	if (cm->function == NULL) {
+		retcode = ERR_PACKET_NR;
+		goto fail;
+	}
+
+	reply_size += cm->reply_body_size;
+
+	/* allocation not in the IO path, cqueue thread context */
+	cn_reply = kmalloc(reply_size, GFP_KERNEL);
+	if (!cn_reply) {
+		retcode = ERR_NOMEM;
+		goto fail;
+	}
+	reply = (struct drbd_nl_cfg_reply *) cn_reply->data;
+
+	reply->packet_type =
+		cm->reply_body_size ? nlp->packet_type : P_nl_after_last_packet;
+	reply->minor = nlp->drbd_minor;
+	reply->ret_code = NO_ERROR; /* Might by modified by cm->function. */
+	/* reply->tag_list; might be modified by cm->function. */
+
+	rr = cm->function(mdev, nlp, reply);
+
+	cn_reply->id = req->id;
+	cn_reply->seq = req->seq;
+	cn_reply->ack = req->ack  + 1;
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr;
+	cn_reply->flags = 0;
+
+	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
+	if (rr && rr != -ESRCH)
+		printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
+
+	kfree(cn_reply);
+	module_put(THIS_MODULE);
+	return;
+ fail:
+	drbd_nl_send_reply(req, retcode);
+	module_put(THIS_MODULE);
+}
+
+static atomic_t drbd_nl_seq = ATOMIC_INIT(2); /* two. */
+
+static unsigned short *
+__tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data,
+	unsigned short len, int nul_terminated)
+{
+	unsigned short l = tag_descriptions[tag_number(tag)].max_len;
+	len = (len < l) ? len :  l;
+	put_unaligned(tag, tl++);
+	put_unaligned(len, tl++);
+	memcpy(tl, data, len);
+	tl = (unsigned short*)((char*)tl + len);
+	if (nul_terminated)
+		*((char*)tl - 1) = 0;
+	return tl;
+}
+
+static unsigned short *
+tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, int len)
+{
+	return __tl_add_blob(tl, tag, data, len, 0);
+}
+
+static unsigned short *
+tl_add_str(unsigned short *tl, enum drbd_tags tag, const char *str)
+{
+	return __tl_add_blob(tl, tag, str, strlen(str)+1, 0);
+}
+
+static unsigned short *
+tl_add_int(unsigned short *tl, enum drbd_tags tag, const void *val)
+{
+	put_unaligned(tag, tl++);
+	switch(tag_type(tag)) {
+	case TT_INTEGER:
+		put_unaligned(sizeof(int), tl++);
+		put_unaligned(*(int *)val, (int *)tl);
+		tl = (unsigned short*)((char*)tl+sizeof(int));
+		break;
+	case TT_INT64:
+		put_unaligned(sizeof(u64), tl++);
+		put_unaligned(*(u64 *)val, (u64 *)tl);
+		tl = (unsigned short*)((char*)tl+sizeof(u64));
+		break;
+	default:
+		/* someone did something stupid. */
+		;
+	}
+	return tl;
+}
+
+void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state state)
+{
+	char buffer[sizeof(struct cn_msg)+
+		    sizeof(struct drbd_nl_cfg_reply)+
+		    sizeof(struct get_state_tag_len_struct)+
+		    sizeof(short int)];
+	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
+	struct drbd_nl_cfg_reply *reply =
+		(struct drbd_nl_cfg_reply *)cn_reply->data;
+	unsigned short *tl = reply->tag_list;
+
+	/* dev_warn(DEV, "drbd_bcast_state() got called\n"); */
+
+	tl = get_state_to_tags(mdev, (struct get_state *)&state, tl);
+
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	cn_reply->id.idx = CN_IDX_DRBD;
+	cn_reply->id.val = CN_VAL_DRBD;
+
+	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
+	cn_reply->ack = 0; /* not used here. */
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
+		(int)((char *)tl - (char *)reply->tag_list);
+	cn_reply->flags = 0;
+
+	reply->packet_type = P_get_state;
+	reply->minor = mdev_to_minor(mdev);
+	reply->ret_code = NO_ERROR;
+
+	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
+}
+
+void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name)
+{
+	char buffer[sizeof(struct cn_msg)+
+		    sizeof(struct drbd_nl_cfg_reply)+
+		    sizeof(struct call_helper_tag_len_struct)+
+		    sizeof(short int)];
+	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
+	struct drbd_nl_cfg_reply *reply =
+		(struct drbd_nl_cfg_reply *)cn_reply->data;
+	unsigned short *tl = reply->tag_list;
+
+	/* dev_warn(DEV, "drbd_bcast_state() got called\n"); */
+
+	tl = tl_add_str(tl, T_helper, helper_name);
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	cn_reply->id.idx = CN_IDX_DRBD;
+	cn_reply->id.val = CN_VAL_DRBD;
+
+	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
+	cn_reply->ack = 0; /* not used here. */
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
+		(int)((char *)tl - (char *)reply->tag_list);
+	cn_reply->flags = 0;
+
+	reply->packet_type = P_call_helper;
+	reply->minor = mdev_to_minor(mdev);
+	reply->ret_code = NO_ERROR;
+
+	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
+}
+
+void drbd_bcast_ee(struct drbd_conf *mdev,
+		const char *reason, const int dgs,
+		const char* seen_hash, const char* calc_hash,
+		const struct drbd_epoch_entry* e)
+{
+	struct cn_msg *cn_reply;
+	struct drbd_nl_cfg_reply *reply;
+	struct bio_vec *bvec;
+	unsigned short *tl;
+	int i;
+
+	if (!e)
+		return;
+	if (!reason || !reason[0])
+		return;
+
+	/* apparently we have to memcpy twice, first to prepare the data for the
+	 * struct cn_msg, then within cn_netlink_send from the cn_msg to the
+	 * netlink skb. */
+	/* receiver thread context, which is not in the writeout path (of this node),
+	 * but may be in the writeout path of the _other_ node.
+	 * GFP_NOIO to avoid potential "distributed deadlock". */
+	cn_reply = kmalloc(
+		sizeof(struct cn_msg)+
+		sizeof(struct drbd_nl_cfg_reply)+
+		sizeof(struct dump_ee_tag_len_struct)+
+		sizeof(short int),
+		GFP_NOIO);
+
+	if (!cn_reply) {
+		dev_err(DEV, "could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n",
+				(unsigned long long)e->sector, e->size);
+		return;
+	}
+
+	reply = (struct drbd_nl_cfg_reply*)cn_reply->data;
+	tl = reply->tag_list;
+
+	tl = tl_add_str(tl, T_dump_ee_reason, reason);
+	tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs);
+	tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs);
+	tl = tl_add_int(tl, T_ee_sector, &e->sector);
+	tl = tl_add_int(tl, T_ee_block_id, &e->block_id);
+
+	put_unaligned(T_ee_data, tl++);
+	put_unaligned(e->size, tl++);
+
+	__bio_for_each_segment(bvec, e->private_bio, i, 0) {
+		void *d = kmap(bvec->bv_page);
+		memcpy(tl, d + bvec->bv_offset, bvec->bv_len);
+		kunmap(bvec->bv_page);
+		tl=(unsigned short*)((char*)tl + bvec->bv_len);
+	}
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	cn_reply->id.idx = CN_IDX_DRBD;
+	cn_reply->id.val = CN_VAL_DRBD;
+
+	cn_reply->seq = atomic_add_return(1,&drbd_nl_seq);
+	cn_reply->ack = 0; // not used here.
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
+		(int)((char*)tl - (char*)reply->tag_list);
+	cn_reply->flags = 0;
+
+	reply->packet_type = P_dump_ee;
+	reply->minor = mdev_to_minor(mdev);
+	reply->ret_code = NO_ERROR;
+
+	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
+	kfree(cn_reply);
+}
+
+void drbd_bcast_sync_progress(struct drbd_conf *mdev)
+{
+	char buffer[sizeof(struct cn_msg)+
+		    sizeof(struct drbd_nl_cfg_reply)+
+		    sizeof(struct sync_progress_tag_len_struct)+
+		    sizeof(short int)];
+	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
+	struct drbd_nl_cfg_reply *reply =
+		(struct drbd_nl_cfg_reply *)cn_reply->data;
+	unsigned short *tl = reply->tag_list;
+	unsigned long rs_left;
+	unsigned int res;
+
+	/* no local ref, no bitmap, no syncer progress, no broadcast. */
+	if (!get_ldev(mdev))
+		return;
+	drbd_get_syncer_progress(mdev, &rs_left, &res);
+	put_ldev(mdev);
+
+	tl = tl_add_int(tl, T_sync_progress, &res);
+	put_unaligned(TT_END, tl++); /* Close the tag list */
+
+	cn_reply->id.idx = CN_IDX_DRBD;
+	cn_reply->id.val = CN_VAL_DRBD;
+
+	cn_reply->seq = atomic_add_return(1, &drbd_nl_seq);
+	cn_reply->ack = 0; /* not used here. */
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) +
+		(int)((char *)tl - (char *)reply->tag_list);
+	cn_reply->flags = 0;
+
+	reply->packet_type = P_sync_progress;
+	reply->minor = mdev_to_minor(mdev);
+	reply->ret_code = NO_ERROR;
+
+	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
+}
+
+int __init drbd_nl_init(void)
+{
+	static struct cb_id cn_id_drbd;
+	int err, try=10;
+
+	cn_id_drbd.val = CN_VAL_DRBD;
+	do {
+		cn_id_drbd.idx = cn_idx;
+		err = cn_add_callback(&cn_id_drbd, "cn_drbd", &drbd_connector_callback);
+		if (!err)
+			break;
+		cn_idx = (cn_idx + CN_IDX_STEP);
+	} while (try--);
+
+	if (err) {
+		printk(KERN_ERR "drbd: cn_drbd failed to register\n");
+		return err;
+	}
+
+	return 0;
+}
+
+void drbd_nl_cleanup(void)
+{
+	static struct cb_id cn_id_drbd;
+
+	cn_id_drbd.idx = cn_idx;
+	cn_id_drbd.val = CN_VAL_DRBD;
+
+	cn_del_callback(&cn_id_drbd);
+}
+
+void drbd_nl_send_reply(struct cn_msg *req, int ret_code)
+{
+	char buffer[sizeof(struct cn_msg)+sizeof(struct drbd_nl_cfg_reply)];
+	struct cn_msg *cn_reply = (struct cn_msg *) buffer;
+	struct drbd_nl_cfg_reply *reply =
+		(struct drbd_nl_cfg_reply *)cn_reply->data;
+	int rr;
+
+	cn_reply->id = req->id;
+
+	cn_reply->seq = req->seq;
+	cn_reply->ack = req->ack  + 1;
+	cn_reply->len = sizeof(struct drbd_nl_cfg_reply);
+	cn_reply->flags = 0;
+
+	reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor;
+	reply->ret_code = ret_code;
+
+	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_NOIO);
+	if (rr && rr != -ESRCH)
+		printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_proc.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_proc.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_proc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,265 @@
+/*
+   drbd_proc.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/drbd.h>
+#include "drbd_int.h"
+
+static int drbd_proc_open(struct inode *inode, struct file *file);
+
+
+struct proc_dir_entry *drbd_proc;
+const struct file_operations drbd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= drbd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+/*lge
+ * progress bars shamelessly adapted from driver/md/md.c
+ * output looks like
+ *	[=====>..............] 33.5% (23456/123456)
+ *	finish: 2:20:20 speed: 6,345 (6,456) K/sec
+ */
+static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
+{
+	unsigned long db, dt, dbdt, rt, rs_left;
+	unsigned int res;
+	int i, x, y;
+
+	drbd_get_syncer_progress(mdev, &rs_left, &res);
+
+	x = res/50;
+	y = 20-x;
+	seq_printf(seq, "\t[");
+	for (i = 1; i < x; i++)
+		seq_printf(seq, "=");
+	seq_printf(seq, ">");
+	for (i = 0; i < y; i++)
+		seq_printf(seq, ".");
+	seq_printf(seq, "] ");
+
+	seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10);
+	/* if more than 1 GB display in MB */
+	if (mdev->rs_total > 0x100000L)
+		seq_printf(seq, "(%lu/%lu)M\n\t",
+			    (unsigned long) Bit2KB(rs_left >> 10),
+			    (unsigned long) Bit2KB(mdev->rs_total >> 10));
+	else
+		seq_printf(seq, "(%lu/%lu)K\n\t",
+			    (unsigned long) Bit2KB(rs_left),
+			    (unsigned long) Bit2KB(mdev->rs_total));
+
+	/* see drivers/md/md.c
+	 * We do not want to overflow, so the order of operands and
+	 * the * 100 / 100 trick are important. We do a +1 to be
+	 * safe against division by zero. We only estimate anyway.
+	 *
+	 * dt: time from mark until now
+	 * db: blocks written from mark until now
+	 * rt: remaining time
+	 */
+	dt = (jiffies - mdev->rs_mark_time) / HZ;
+
+	if (dt > 20) {
+		/* if we made no update to rs_mark_time for too long,
+		 * we are stalled. show that. */
+		seq_printf(seq, "stalled\n");
+		return;
+	}
+
+	if (!dt)
+		dt++;
+	db = mdev->rs_mark_left - rs_left;
+	rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
+
+	seq_printf(seq, "finish: %lu:%02lu:%02lu",
+		rt / 3600, (rt % 3600) / 60, rt % 60);
+
+	/* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */
+	dbdt = Bit2KB(db/dt);
+	if (dbdt > 1000)
+		seq_printf(seq, " speed: %ld,%03ld",
+			dbdt/1000, dbdt % 1000);
+	else
+		seq_printf(seq, " speed: %ld", dbdt);
+
+	/* mean speed since syncer started
+	 * we do account for PausedSync periods */
+	dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
+	if (dt <= 0)
+		dt = 1;
+	db = mdev->rs_total - rs_left;
+	dbdt = Bit2KB(db/dt);
+	if (dbdt > 1000)
+		seq_printf(seq, " (%ld,%03ld)",
+			dbdt/1000, dbdt % 1000);
+	else
+		seq_printf(seq, " (%ld)", dbdt);
+
+	seq_printf(seq, " K/sec\n");
+}
+
+static void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
+{
+	struct bm_extent *bme = lc_entry(e, struct bm_extent, lce);
+
+	seq_printf(seq, "%5d %s %s\n", bme->rs_left,
+		   bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------",
+		   bme->flags & BME_LOCKED ? "LOCKED" : "------"
+		   );
+}
+
+static int drbd_seq_show(struct seq_file *seq, void *v)
+{
+	int i, hole = 0;
+	const char *sn;
+	struct drbd_conf *mdev;
+
+	static char write_ordering_chars[] = {
+		[WO_none] = 'n',
+		[WO_drain_io] = 'd',
+		[WO_bdev_flush] = 'f',
+		[WO_bio_barrier] = 'b',
+	};
+
+	seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
+		   API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
+
+	/*
+	  cs .. connection state
+	  ro .. node role (local/remote)
+	  ds .. disk state (local/remote)
+	     protocol
+	     various flags
+	  ns .. network send
+	  nr .. network receive
+	  dw .. disk write
+	  dr .. disk read
+	  al .. activity log write count
+	  bm .. bitmap update write count
+	  pe .. pending (waiting for ack or data reply)
+	  ua .. unack'd (still need to send ack or data reply)
+	  ap .. application requests accepted, but not yet completed
+	  ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
+	  wo .. write ordering mode currently in use
+	 oos .. known out-of-sync kB
+	*/
+
+	for (i = 0; i < minor_count; i++) {
+		mdev = minor_to_mdev(i);
+		if (!mdev) {
+			hole = 1;
+			continue;
+		}
+		if (hole) {
+			hole = 0;
+			seq_printf(seq, "\n");
+		}
+
+		sn = drbd_conn_str(mdev->state.conn);
+
+		if (mdev->state.conn == C_STANDALONE &&
+		    mdev->state.disk == D_DISKLESS &&
+		    mdev->state.role == R_SECONDARY) {
+			seq_printf(seq, "%2d: cs:Unconfigured\n", i);
+		} else {
+			seq_printf(seq,
+			   "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c\n"
+			   "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
+			   "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
+			   i, sn,
+			   drbd_role_str(mdev->state.role),
+			   drbd_role_str(mdev->state.peer),
+			   drbd_disk_str(mdev->state.disk),
+			   drbd_disk_str(mdev->state.pdsk),
+			   (mdev->net_conf == NULL ? ' ' :
+			    (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')),
+			   mdev->state.susp ? 's' : 'r',
+			   mdev->state.aftr_isp ? 'a' : '-',
+			   mdev->state.peer_isp ? 'p' : '-',
+			   mdev->state.user_isp ? 'u' : '-',
+			   mdev->congestion_reason ?: '-',
+			   mdev->send_cnt/2,
+			   mdev->recv_cnt/2,
+			   mdev->writ_cnt/2,
+			   mdev->read_cnt/2,
+			   mdev->al_writ_cnt,
+			   mdev->bm_writ_cnt,
+			   atomic_read(&mdev->local_cnt),
+			   atomic_read(&mdev->ap_pending_cnt) +
+			   atomic_read(&mdev->rs_pending_cnt),
+			   atomic_read(&mdev->unacked_cnt),
+			   atomic_read(&mdev->ap_bio_cnt),
+			   mdev->epochs,
+			   write_ordering_chars[mdev->write_ordering]
+			);
+			seq_printf(seq, " oos:%lu\n",
+				   Bit2KB(drbd_bm_total_weight(mdev)));
+		}
+		if (mdev->state.conn == C_SYNC_SOURCE ||
+		    mdev->state.conn == C_SYNC_TARGET)
+			drbd_syncer_progress(mdev, seq);
+
+		if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
+			seq_printf(seq, "\t%3d%%      %lu/%lu\n",
+				   (int)((mdev->rs_total-mdev->ov_left) /
+					 (mdev->rs_total/100+1)),
+				   mdev->rs_total - mdev->ov_left,
+				   mdev->rs_total);
+
+		if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) {
+			lc_seq_printf_stats(seq, mdev->resync);
+			lc_seq_printf_stats(seq, mdev->act_log);
+			put_ldev(mdev);
+		}
+
+		if (proc_details >= 2) {
+			if (mdev->resync) {
+				lc_seq_dump_details(seq, mdev->resync, "rs_left",
+					resync_dump_detail);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int drbd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, drbd_seq_show, PDE(inode)->data);
+}
+
+/* PROC FS stuff end */
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_receiver.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_receiver.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_receiver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_receiver.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,4439 @@
+/*
+   drbd_receiver.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <net/sock.h>
+
+#include <linux/drbd.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/in.h>
+#include <linux/mm.h>
+#include <linux/memcontrol.h>
+#include <linux/mm_inline.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/pkt_sched.h>
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <linux/vmalloc.h>
+#include <linux/random.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/scatterlist.h>
+#include "drbd_int.h"
+#include "drbd_req.h"
+
+#include "drbd_vli.h"
+
+struct flush_work {
+	struct drbd_work w;
+	struct drbd_epoch *epoch;
+};
+
+enum finish_epoch {
+	FE_STILL_LIVE,
+	FE_DESTROYED,
+	FE_RECYCLED,
+};
+
+static int drbd_do_handshake(struct drbd_conf *mdev);
+static int drbd_do_auth(struct drbd_conf *mdev);
+
+static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
+static int e_end_block(struct drbd_conf *, struct drbd_work *, int);
+
+static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch)
+{
+	struct drbd_epoch *prev;
+	spin_lock(&mdev->epoch_lock);
+	prev = list_entry(epoch->list.prev, struct drbd_epoch, list);
+	if (prev == epoch || prev == mdev->current_epoch)
+		prev = NULL;
+	spin_unlock(&mdev->epoch_lock);
+	return prev;
+}
+
+#define GFP_TRY	(__GFP_HIGHMEM | __GFP_NOWARN)
+
+static struct page *drbd_pp_first_page_or_try_alloc(struct drbd_conf *mdev)
+{
+	struct page *page = NULL;
+
+	/* Yes, testing drbd_pp_vacant outside the lock is racy.
+	 * So what. It saves a spin_lock. */
+	if (drbd_pp_vacant > 0) {
+		spin_lock(&drbd_pp_lock);
+		page = drbd_pp_pool;
+		if (page) {
+			drbd_pp_pool = (struct page *)page_private(page);
+			set_page_private(page, 0); /* just to be polite */
+			drbd_pp_vacant--;
+		}
+		spin_unlock(&drbd_pp_lock);
+	}
+	/* GFP_TRY, because we must not cause arbitrary write-out: in a DRBD
+	 * "criss-cross" setup, that might cause write-out on some other DRBD,
+	 * which in turn might block on the other node at this very place.  */
+	if (!page)
+		page = alloc_page(GFP_TRY);
+	if (page)
+		atomic_inc(&mdev->pp_in_use);
+	return page;
+}
+
+/* kick lower level device, if we have more than (arbitrary number)
+ * reference counts on it, which typically are locally submitted io
+ * requests.  don't use unacked_cnt, so we speed up proto A and B, too. */
+static void maybe_kick_lo(struct drbd_conf *mdev)
+{
+	if (atomic_read(&mdev->local_cnt) >= mdev->net_conf->unplug_watermark)
+		drbd_kick_lo(mdev);
+}
+
+static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed)
+{
+	struct drbd_epoch_entry *e;
+	struct list_head *le, *tle;
+
+	/* The EEs are always appended to the end of the list. Since
+	   they are sent in order over the wire, they have to finish
+	   in order. As soon as we see the first not finished we can
+	   stop to examine the list... */
+
+	list_for_each_safe(le, tle, &mdev->net_ee) {
+		e = list_entry(le, struct drbd_epoch_entry, w.list);
+		if (drbd_bio_has_active_page(e->private_bio))
+			break;
+		list_move(le, to_be_freed);
+	}
+}
+
+static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev)
+{
+	LIST_HEAD(reclaimed);
+	struct drbd_epoch_entry *e, *t;
+
+	maybe_kick_lo(mdev);
+	spin_lock_irq(&mdev->req_lock);
+	reclaim_net_ee(mdev, &reclaimed);
+	spin_unlock_irq(&mdev->req_lock);
+
+	list_for_each_entry_safe(e, t, &reclaimed, w.list)
+		drbd_free_ee(mdev, e);
+}
+
+/**
+ * drbd_pp_alloc() - Returns a page, fails only if a signal comes in
+ * @mdev:	DRBD device.
+ * @retry:	whether or not to retry allocation forever (or until signalled)
+ *
+ * Tries to allocate a page, first from our own page pool, then from the
+ * kernel, unless this allocation would exceed the max_buffers setting.
+ * If @retry is non-zero, retry until DRBD frees a page somewhere else.
+ */
+static struct page *drbd_pp_alloc(struct drbd_conf *mdev, int retry)
+{
+	struct page *page = NULL;
+	DEFINE_WAIT(wait);
+
+	if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) {
+		page = drbd_pp_first_page_or_try_alloc(mdev);
+		if (page)
+			return page;
+	}
+
+	for (;;) {
+		prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE);
+
+		drbd_kick_lo_and_reclaim_net(mdev);
+
+		if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) {
+			page = drbd_pp_first_page_or_try_alloc(mdev);
+			if (page)
+				break;
+		}
+
+		if (!retry)
+			break;
+
+		if (signal_pending(current)) {
+			dev_warn(DEV, "drbd_pp_alloc interrupted!\n");
+			break;
+		}
+
+		schedule();
+	}
+	finish_wait(&drbd_pp_wait, &wait);
+
+	return page;
+}
+
+/* Must not be used from irq, as that may deadlock: see drbd_pp_alloc.
+ * Is also used from inside an other spin_lock_irq(&mdev->req_lock) */
+static void drbd_pp_free(struct drbd_conf *mdev, struct page *page)
+{
+	int free_it;
+
+	spin_lock(&drbd_pp_lock);
+	if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) {
+		free_it = 1;
+	} else {
+		set_page_private(page, (unsigned long)drbd_pp_pool);
+		drbd_pp_pool = page;
+		drbd_pp_vacant++;
+		free_it = 0;
+	}
+	spin_unlock(&drbd_pp_lock);
+
+	atomic_dec(&mdev->pp_in_use);
+
+	if (free_it)
+		__free_page(page);
+
+	wake_up(&drbd_pp_wait);
+}
+
+static void drbd_pp_free_bio_pages(struct drbd_conf *mdev, struct bio *bio)
+{
+	struct page *p_to_be_freed = NULL;
+	struct page *page;
+	struct bio_vec *bvec;
+	int i;
+
+	spin_lock(&drbd_pp_lock);
+	__bio_for_each_segment(bvec, bio, i, 0) {
+		if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) {
+			set_page_private(bvec->bv_page, (unsigned long)p_to_be_freed);
+			p_to_be_freed = bvec->bv_page;
+		} else {
+			set_page_private(bvec->bv_page, (unsigned long)drbd_pp_pool);
+			drbd_pp_pool = bvec->bv_page;
+			drbd_pp_vacant++;
+		}
+	}
+	spin_unlock(&drbd_pp_lock);
+	atomic_sub(bio->bi_vcnt, &mdev->pp_in_use);
+
+	while (p_to_be_freed) {
+		page = p_to_be_freed;
+		p_to_be_freed = (struct page *)page_private(page);
+		set_page_private(page, 0); /* just to be polite */
+		put_page(page);
+	}
+
+	wake_up(&drbd_pp_wait);
+}
+
+/*
+You need to hold the req_lock:
+ _drbd_wait_ee_list_empty()
+
+You must not have the req_lock:
+ drbd_free_ee()
+ drbd_alloc_ee()
+ drbd_init_ee()
+ drbd_release_ee()
+ drbd_ee_fix_bhs()
+ drbd_process_done_ee()
+ drbd_clear_done_ee()
+ drbd_wait_ee_list_empty()
+*/
+
+struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
+				     u64 id,
+				     sector_t sector,
+				     unsigned int data_size,
+				     gfp_t gfp_mask) __must_hold(local)
+{
+	struct request_queue *q;
+	struct drbd_epoch_entry *e;
+	struct page *page;
+	struct bio *bio;
+	unsigned int ds;
+
+	if (FAULT_ACTIVE(mdev, DRBD_FAULT_AL_EE))
+		return NULL;
+
+	e = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM);
+	if (!e) {
+		if (!(gfp_mask & __GFP_NOWARN))
+			dev_err(DEV, "alloc_ee: Allocation of an EE failed\n");
+		return NULL;
+	}
+
+	bio = bio_alloc(gfp_mask & ~__GFP_HIGHMEM, div_ceil(data_size, PAGE_SIZE));
+	if (!bio) {
+		if (!(gfp_mask & __GFP_NOWARN))
+			dev_err(DEV, "alloc_ee: Allocation of a bio failed\n");
+		goto fail1;
+	}
+
+	bio->bi_bdev = mdev->ldev->backing_bdev;
+	bio->bi_sector = sector;
+
+	ds = data_size;
+	while (ds) {
+		page = drbd_pp_alloc(mdev, (gfp_mask & __GFP_WAIT));
+		if (!page) {
+			if (!(gfp_mask & __GFP_NOWARN))
+				dev_err(DEV, "alloc_ee: Allocation of a page failed\n");
+			goto fail2;
+		}
+		if (!bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0)) {
+			drbd_pp_free(mdev, page);
+			dev_err(DEV, "alloc_ee: bio_add_page(s=%llu,"
+			    "data_size=%u,ds=%u) failed\n",
+			    (unsigned long long)sector, data_size, ds);
+
+			q = bdev_get_queue(bio->bi_bdev);
+			if (q->merge_bvec_fn) {
+				struct bvec_merge_data bvm = {
+					.bi_bdev = bio->bi_bdev,
+					.bi_sector = bio->bi_sector,
+					.bi_size = bio->bi_size,
+					.bi_rw = bio->bi_rw,
+				};
+				int l = q->merge_bvec_fn(q, &bvm,
+						&bio->bi_io_vec[bio->bi_vcnt]);
+				dev_err(DEV, "merge_bvec_fn() = %d\n", l);
+			}
+
+			/* dump more of the bio. */
+			dev_err(DEV, "bio->bi_max_vecs = %d\n", bio->bi_max_vecs);
+			dev_err(DEV, "bio->bi_vcnt = %d\n", bio->bi_vcnt);
+			dev_err(DEV, "bio->bi_size = %d\n", bio->bi_size);
+			dev_err(DEV, "bio->bi_phys_segments = %d\n", bio->bi_phys_segments);
+
+			goto fail2;
+			break;
+		}
+		ds -= min_t(int, ds, PAGE_SIZE);
+	}
+
+	D_ASSERT(data_size == bio->bi_size);
+
+	bio->bi_private = e;
+	e->mdev = mdev;
+	e->sector = sector;
+	e->size = bio->bi_size;
+
+	e->private_bio = bio;
+	e->block_id = id;
+	INIT_HLIST_NODE(&e->colision);
+	e->epoch = NULL;
+	e->flags = 0;
+
+	return e;
+
+ fail2:
+	drbd_pp_free_bio_pages(mdev, bio);
+	bio_put(bio);
+ fail1:
+	mempool_free(e, drbd_ee_mempool);
+
+	return NULL;
+}
+
+void drbd_free_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
+{
+	struct bio *bio = e->private_bio;
+	drbd_pp_free_bio_pages(mdev, bio);
+	bio_put(bio);
+	D_ASSERT(hlist_unhashed(&e->colision));
+	mempool_free(e, drbd_ee_mempool);
+}
+
+int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list)
+{
+	LIST_HEAD(work_list);
+	struct drbd_epoch_entry *e, *t;
+	int count = 0;
+
+	spin_lock_irq(&mdev->req_lock);
+	list_splice_init(list, &work_list);
+	spin_unlock_irq(&mdev->req_lock);
+
+	list_for_each_entry_safe(e, t, &work_list, w.list) {
+		drbd_free_ee(mdev, e);
+		count++;
+	}
+	return count;
+}
+
+
+/*
+ * This function is called from _asender only_
+ * but see also comments in _req_mod(,barrier_acked)
+ * and receive_Barrier.
+ *
+ * Move entries from net_ee to done_ee, if ready.
+ * Grab done_ee, call all callbacks, free the entries.
+ * The callbacks typically send out ACKs.
+ */
+static int drbd_process_done_ee(struct drbd_conf *mdev)
+{
+	LIST_HEAD(work_list);
+	LIST_HEAD(reclaimed);
+	struct drbd_epoch_entry *e, *t;
+	int ok = (mdev->state.conn >= C_WF_REPORT_PARAMS);
+
+	spin_lock_irq(&mdev->req_lock);
+	reclaim_net_ee(mdev, &reclaimed);
+	list_splice_init(&mdev->done_ee, &work_list);
+	spin_unlock_irq(&mdev->req_lock);
+
+	list_for_each_entry_safe(e, t, &reclaimed, w.list)
+		drbd_free_ee(mdev, e);
+
+	/* possible callbacks here:
+	 * e_end_block, and e_end_resync_block, e_send_discard_ack.
+	 * all ignore the last argument.
+	 */
+	list_for_each_entry_safe(e, t, &work_list, w.list) {
+		/* list_del not necessary, next/prev members not touched */
+		ok = e->w.cb(mdev, &e->w, !ok) && ok;
+		drbd_free_ee(mdev, e);
+	}
+	wake_up(&mdev->ee_wait);
+
+	return ok;
+}
+
+void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
+{
+	DEFINE_WAIT(wait);
+
+	/* avoids spin_lock/unlock
+	 * and calling prepare_to_wait in the fast path */
+	while (!list_empty(head)) {
+		prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE);
+		spin_unlock_irq(&mdev->req_lock);
+		drbd_kick_lo(mdev);
+		schedule();
+		finish_wait(&mdev->ee_wait, &wait);
+		spin_lock_irq(&mdev->req_lock);
+	}
+}
+
+void drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head)
+{
+	spin_lock_irq(&mdev->req_lock);
+	_drbd_wait_ee_list_empty(mdev, head);
+	spin_unlock_irq(&mdev->req_lock);
+}
+
+/* see also kernel_accept; which is only present since 2.6.18.
+ * also we want to log which part of it failed, exactly */
+static int drbd_accept(struct drbd_conf *mdev, const char **what,
+		struct socket *sock, struct socket **newsock)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	*what = "listen";
+	err = sock->ops->listen(sock, 5);
+	if (err < 0)
+		goto out;
+
+	*what = "sock_create_lite";
+	err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
+			       newsock);
+	if (err < 0)
+		goto out;
+
+	*what = "accept";
+	err = sock->ops->accept(sock, *newsock, 0);
+	if (err < 0) {
+		sock_release(*newsock);
+		*newsock = NULL;
+		goto out;
+	}
+	(*newsock)->ops  = sock->ops;
+
+out:
+	return err;
+}
+
+static int drbd_recv_short(struct drbd_conf *mdev, struct socket *sock,
+		    void *buf, size_t size, int flags)
+{
+	mm_segment_t oldfs;
+	struct kvec iov = {
+		.iov_base = buf,
+		.iov_len = size,
+	};
+	struct msghdr msg = {
+		.msg_iovlen = 1,
+		.msg_iov = (struct iovec *)&iov,
+		.msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL)
+	};
+	int rv;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	rv = sock_recvmsg(sock, &msg, size, msg.msg_flags);
+	set_fs(oldfs);
+
+	return rv;
+}
+
+static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size)
+{
+	mm_segment_t oldfs;
+	struct kvec iov = {
+		.iov_base = buf,
+		.iov_len = size,
+	};
+	struct msghdr msg = {
+		.msg_iovlen = 1,
+		.msg_iov = (struct iovec *)&iov,
+		.msg_flags = MSG_WAITALL | MSG_NOSIGNAL
+	};
+	int rv;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	for (;;) {
+		rv = sock_recvmsg(mdev->data.socket, &msg, size, msg.msg_flags);
+		if (rv == size)
+			break;
+
+		/* Note:
+		 * ECONNRESET	other side closed the connection
+		 * ERESTARTSYS	(on  sock) we got a signal
+		 */
+
+		if (rv < 0) {
+			if (rv == -ECONNRESET)
+				dev_info(DEV, "sock was reset by peer\n");
+			else if (rv != -ERESTARTSYS)
+				dev_err(DEV, "sock_recvmsg returned %d\n", rv);
+			break;
+		} else if (rv == 0) {
+			dev_info(DEV, "sock was shut down by peer\n");
+			break;
+		} else	{
+			/* signal came in, or peer/link went down,
+			 * after we read a partial message
+			 */
+			/* D_ASSERT(signal_pending(current)); */
+			break;
+		}
+	};
+
+	set_fs(oldfs);
+
+	if (rv != size)
+		drbd_force_state(mdev, NS(conn, C_BROKEN_PIPE));
+
+	return rv;
+}
+
+static struct socket *drbd_try_connect(struct drbd_conf *mdev)
+{
+	const char *what;
+	struct socket *sock;
+	struct sockaddr_in6 src_in6;
+	int err;
+	int disconnect_on_error = 1;
+
+	if (!get_net_conf(mdev))
+		return NULL;
+
+	what = "sock_create_kern";
+	err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family,
+		SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (err < 0) {
+		sock = NULL;
+		goto out;
+	}
+
+	sock->sk->sk_rcvtimeo =
+	sock->sk->sk_sndtimeo =  mdev->net_conf->try_connect_int*HZ;
+
+       /* explicitly bind to the configured IP as source IP
+	*  for the outgoing connections.
+	*  This is needed for multihomed hosts and to be
+	*  able to use lo: interfaces for drbd.
+	* Make sure to use 0 as port number, so linux selects
+	*  a free one dynamically.
+	*/
+	memcpy(&src_in6, mdev->net_conf->my_addr,
+	       min_t(int, mdev->net_conf->my_addr_len, sizeof(src_in6)));
+	if (((struct sockaddr *)mdev->net_conf->my_addr)->sa_family == AF_INET6)
+		src_in6.sin6_port = 0;
+	else
+		((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */
+
+	what = "bind before connect";
+	err = sock->ops->bind(sock,
+			      (struct sockaddr *) &src_in6,
+			      mdev->net_conf->my_addr_len);
+	if (err < 0)
+		goto out;
+
+	/* connect may fail, peer not yet available.
+	 * stay C_WF_CONNECTION, don't go Disconnecting! */
+	disconnect_on_error = 0;
+	what = "connect";
+	err = sock->ops->connect(sock,
+				 (struct sockaddr *)mdev->net_conf->peer_addr,
+				 mdev->net_conf->peer_addr_len, 0);
+
+out:
+	if (err < 0) {
+		if (sock) {
+			sock_release(sock);
+			sock = NULL;
+		}
+		switch (-err) {
+			/* timeout, busy, signal pending */
+		case ETIMEDOUT: case EAGAIN: case EINPROGRESS:
+		case EINTR: case ERESTARTSYS:
+			/* peer not (yet) available, network problem */
+		case ECONNREFUSED: case ENETUNREACH:
+		case EHOSTDOWN:    case EHOSTUNREACH:
+			disconnect_on_error = 0;
+			break;
+		default:
+			dev_err(DEV, "%s failed, err = %d\n", what, err);
+		}
+		if (disconnect_on_error)
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+	}
+	put_net_conf(mdev);
+	return sock;
+}
+
+static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev)
+{
+	int timeo, err;
+	struct socket *s_estab = NULL, *s_listen;
+	const char *what;
+
+	if (!get_net_conf(mdev))
+		return NULL;
+
+	what = "sock_create_kern";
+	err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family,
+		SOCK_STREAM, IPPROTO_TCP, &s_listen);
+	if (err) {
+		s_listen = NULL;
+		goto out;
+	}
+
+	timeo = mdev->net_conf->try_connect_int * HZ;
+	timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */
+
+	s_listen->sk->sk_reuse    = 1; /* SO_REUSEADDR */
+	s_listen->sk->sk_rcvtimeo = timeo;
+	s_listen->sk->sk_sndtimeo = timeo;
+
+	what = "bind before listen";
+	err = s_listen->ops->bind(s_listen,
+			      (struct sockaddr *) mdev->net_conf->my_addr,
+			      mdev->net_conf->my_addr_len);
+	if (err < 0)
+		goto out;
+
+	err = drbd_accept(mdev, &what, s_listen, &s_estab);
+
+out:
+	if (s_listen)
+		sock_release(s_listen);
+	if (err < 0) {
+		if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) {
+			dev_err(DEV, "%s failed, err = %d\n", what, err);
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+		}
+	}
+	put_net_conf(mdev);
+
+	return s_estab;
+}
+
+static int drbd_send_fp(struct drbd_conf *mdev,
+	struct socket *sock, enum drbd_packets cmd)
+{
+	struct p_header *h = (struct p_header *) &mdev->data.sbuf.header;
+
+	return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0);
+}
+
+static enum drbd_packets drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock)
+{
+	struct p_header *h = (struct p_header *) &mdev->data.sbuf.header;
+	int rr;
+
+	rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0);
+
+	if (rr == sizeof(*h) && h->magic == BE_DRBD_MAGIC)
+		return be16_to_cpu(h->command);
+
+	return 0xffff;
+}
+
+/**
+ * drbd_socket_okay() - Free the socket if its connection is not okay
+ * @mdev:	DRBD device.
+ * @sock:	pointer to the pointer to the socket.
+ */
+static int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock)
+{
+	int rr;
+	char tb[4];
+
+	if (!*sock)
+		return FALSE;
+
+	rr = drbd_recv_short(mdev, *sock, tb, 4, MSG_DONTWAIT | MSG_PEEK);
+
+	if (rr > 0 || rr == -EAGAIN) {
+		return TRUE;
+	} else {
+		sock_release(*sock);
+		*sock = NULL;
+		return FALSE;
+	}
+}
+
+/*
+ * return values:
+ *   1 yes, we have a valid connection
+ *   0 oops, did not work out, please try again
+ *  -1 peer talks different language,
+ *     no point in trying again, please go standalone.
+ *  -2 We do not have a network config...
+ */
+static int drbd_connect(struct drbd_conf *mdev)
+{
+	struct socket *s, *sock, *msock;
+	int try, h, ok;
+
+	D_ASSERT(!mdev->data.socket);
+
+	if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags))
+		dev_err(DEV, "CREATE_BARRIER flag was set in drbd_connect - now cleared!\n");
+
+	if (drbd_request_state(mdev, NS(conn, C_WF_CONNECTION)) < SS_SUCCESS)
+		return -2;
+
+	clear_bit(DISCARD_CONCURRENT, &mdev->flags);
+
+	sock  = NULL;
+	msock = NULL;
+
+	do {
+		for (try = 0;;) {
+			/* 3 tries, this should take less than a second! */
+			s = drbd_try_connect(mdev);
+			if (s || ++try >= 3)
+				break;
+			/* give the other side time to call bind() & listen() */
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 10);
+		}
+
+		if (s) {
+			if (!sock) {
+				drbd_send_fp(mdev, s, P_HAND_SHAKE_S);
+				sock = s;
+				s = NULL;
+			} else if (!msock) {
+				drbd_send_fp(mdev, s, P_HAND_SHAKE_M);
+				msock = s;
+				s = NULL;
+			} else {
+				dev_err(DEV, "Logic error in drbd_connect()\n");
+				goto out_release_sockets;
+			}
+		}
+
+		if (sock && msock) {
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 10);
+			ok = drbd_socket_okay(mdev, &sock);
+			ok = drbd_socket_okay(mdev, &msock) && ok;
+			if (ok)
+				break;
+		}
+
+retry:
+		s = drbd_wait_for_connect(mdev);
+		if (s) {
+			try = drbd_recv_fp(mdev, s);
+			drbd_socket_okay(mdev, &sock);
+			drbd_socket_okay(mdev, &msock);
+			switch (try) {
+			case P_HAND_SHAKE_S:
+				if (sock) {
+					dev_warn(DEV, "initial packet S crossed\n");
+					sock_release(sock);
+				}
+				sock = s;
+				break;
+			case P_HAND_SHAKE_M:
+				if (msock) {
+					dev_warn(DEV, "initial packet M crossed\n");
+					sock_release(msock);
+				}
+				msock = s;
+				set_bit(DISCARD_CONCURRENT, &mdev->flags);
+				break;
+			default:
+				dev_warn(DEV, "Error receiving initial packet\n");
+				sock_release(s);
+				if (random32() & 1)
+					goto retry;
+			}
+		}
+
+		if (mdev->state.conn <= C_DISCONNECTING)
+			goto out_release_sockets;
+		if (signal_pending(current)) {
+			flush_signals(current);
+			smp_rmb();
+			if (get_t_state(&mdev->receiver) == Exiting)
+				goto out_release_sockets;
+		}
+
+		if (sock && msock) {
+			ok = drbd_socket_okay(mdev, &sock);
+			ok = drbd_socket_okay(mdev, &msock) && ok;
+			if (ok)
+				break;
+		}
+	} while (1);
+
+	msock->sk->sk_reuse = 1; /* SO_REUSEADDR */
+	sock->sk->sk_reuse = 1; /* SO_REUSEADDR */
+
+	sock->sk->sk_allocation = GFP_NOIO;
+	msock->sk->sk_allocation = GFP_NOIO;
+
+	sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
+	msock->sk->sk_priority = TC_PRIO_INTERACTIVE;
+
+	if (mdev->net_conf->sndbuf_size) {
+		sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size;
+		sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+	}
+
+	if (mdev->net_conf->rcvbuf_size) {
+		sock->sk->sk_rcvbuf = mdev->net_conf->rcvbuf_size;
+		sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
+	}
+
+	/* NOT YET ...
+	 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
+	 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
+	 * first set it to the P_HAND_SHAKE timeout,
+	 * which we set to 4x the configured ping_timeout. */
+	sock->sk->sk_sndtimeo =
+	sock->sk->sk_rcvtimeo = mdev->net_conf->ping_timeo*4*HZ/10;
+
+	msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
+	msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+
+	/* we don't want delays.
+	 * we use TCP_CORK where apropriate, though */
+	drbd_tcp_nodelay(sock);
+	drbd_tcp_nodelay(msock);
+
+	mdev->data.socket = sock;
+	mdev->meta.socket = msock;
+	mdev->last_received = jiffies;
+
+	D_ASSERT(mdev->asender.task == NULL);
+
+	h = drbd_do_handshake(mdev);
+	if (h <= 0)
+		return h;
+
+	if (mdev->cram_hmac_tfm) {
+		/* drbd_request_state(mdev, NS(conn, WFAuth)); */
+		switch (drbd_do_auth(mdev)) {
+		case -1:
+			dev_err(DEV, "Authentication of peer failed\n");
+			return -1;
+		case 0:
+			dev_err(DEV, "Authentication of peer failed, trying again.\n");
+			return 0;
+		}
+	}
+
+	if (drbd_request_state(mdev, NS(conn, C_WF_REPORT_PARAMS)) < SS_SUCCESS)
+		return 0;
+
+	sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
+	sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
+
+	atomic_set(&mdev->packet_seq, 0);
+	mdev->peer_seq = 0;
+
+	drbd_thread_start(&mdev->asender);
+
+	drbd_send_protocol(mdev);
+	drbd_send_sync_param(mdev, &mdev->sync_conf);
+	drbd_send_sizes(mdev, 0);
+	drbd_send_uuids(mdev);
+	drbd_send_state(mdev);
+	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
+	clear_bit(RESIZE_PENDING, &mdev->flags);
+
+	return 1;
+
+out_release_sockets:
+	if (sock)
+		sock_release(sock);
+	if (msock)
+		sock_release(msock);
+	return -1;
+}
+
+static int drbd_recv_header(struct drbd_conf *mdev, struct p_header *h)
+{
+	int r;
+
+	r = drbd_recv(mdev, h, sizeof(*h));
+
+	if (unlikely(r != sizeof(*h))) {
+		dev_err(DEV, "short read expecting header on sock: r=%d\n", r);
+		return FALSE;
+	};
+	h->command = be16_to_cpu(h->command);
+	h->length  = be16_to_cpu(h->length);
+	if (unlikely(h->magic != BE_DRBD_MAGIC)) {
+		dev_err(DEV, "magic?? on data m: 0x%lx c: %d l: %d\n",
+		    (long)be32_to_cpu(h->magic),
+		    h->command, h->length);
+		return FALSE;
+	}
+	mdev->last_received = jiffies;
+
+	return TRUE;
+}
+
+static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch)
+{
+	int rv;
+
+	if (mdev->write_ordering >= WO_bdev_flush && get_ldev(mdev)) {
+		rv = blkdev_issue_flush(mdev->ldev->backing_bdev, NULL);
+		if (rv) {
+			dev_err(DEV, "local disk flush failed with status %d\n", rv);
+			/* would rather check on EOPNOTSUPP, but that is not reliable.
+			 * don't try again for ANY return value != 0
+			 * if (rv == -EOPNOTSUPP) */
+			drbd_bump_write_ordering(mdev, WO_drain_io);
+		}
+		put_ldev(mdev);
+	}
+
+	return drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE);
+}
+
+static int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct flush_work *fw = (struct flush_work *)w;
+	struct drbd_epoch *epoch = fw->epoch;
+
+	kfree(w);
+
+	if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags))
+		drbd_flush_after_epoch(mdev, epoch);
+
+	drbd_may_finish_epoch(mdev, epoch, EV_PUT |
+			      (mdev->state.conn < C_CONNECTED ? EV_CLEANUP : 0));
+
+	return 1;
+}
+
+/**
+ * drbd_may_finish_epoch() - Applies an epoch_event to the epoch's state, eventually finishes it.
+ * @mdev:	DRBD device.
+ * @epoch:	Epoch object.
+ * @ev:		Epoch event.
+ */
+static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
+					       struct drbd_epoch *epoch,
+					       enum epoch_event ev)
+{
+	int finish, epoch_size;
+	struct drbd_epoch *next_epoch;
+	int schedule_flush = 0;
+	enum finish_epoch rv = FE_STILL_LIVE;
+
+	spin_lock(&mdev->epoch_lock);
+	do {
+		next_epoch = NULL;
+		finish = 0;
+
+		epoch_size = atomic_read(&epoch->epoch_size);
+
+		switch (ev & ~EV_CLEANUP) {
+		case EV_PUT:
+			atomic_dec(&epoch->active);
+			break;
+		case EV_GOT_BARRIER_NR:
+			set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags);
+
+			/* Special case: If we just switched from WO_bio_barrier to
+			   WO_bdev_flush we should not finish the current epoch */
+			if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 &&
+			    mdev->write_ordering != WO_bio_barrier &&
+			    epoch == mdev->current_epoch)
+				clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags);
+			break;
+		case EV_BARRIER_DONE:
+			set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags);
+			break;
+		case EV_BECAME_LAST:
+			/* nothing to do*/
+			break;
+		}
+
+		if (epoch_size != 0 &&
+		    atomic_read(&epoch->active) == 0 &&
+		    test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) &&
+		    epoch->list.prev == &mdev->current_epoch->list &&
+		    !test_bit(DE_IS_FINISHING, &epoch->flags)) {
+			/* Nearly all conditions are met to finish that epoch... */
+			if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) ||
+			    mdev->write_ordering == WO_none ||
+			    (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) ||
+			    ev & EV_CLEANUP) {
+				finish = 1;
+				set_bit(DE_IS_FINISHING, &epoch->flags);
+			} else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) &&
+				 mdev->write_ordering == WO_bio_barrier) {
+				atomic_inc(&epoch->active);
+				schedule_flush = 1;
+			}
+		}
+		if (finish) {
+			if (!(ev & EV_CLEANUP)) {
+				spin_unlock(&mdev->epoch_lock);
+				drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size);
+				spin_lock(&mdev->epoch_lock);
+			}
+			dec_unacked(mdev);
+
+			if (mdev->current_epoch != epoch) {
+				next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list);
+				list_del(&epoch->list);
+				ev = EV_BECAME_LAST | (ev & EV_CLEANUP);
+				mdev->epochs--;
+				kfree(epoch);
+
+				if (rv == FE_STILL_LIVE)
+					rv = FE_DESTROYED;
+			} else {
+				epoch->flags = 0;
+				atomic_set(&epoch->epoch_size, 0);
+				/* atomic_set(&epoch->active, 0); is alrady zero */
+				if (rv == FE_STILL_LIVE)
+					rv = FE_RECYCLED;
+			}
+		}
+
+		if (!next_epoch)
+			break;
+
+		epoch = next_epoch;
+	} while (1);
+
+	spin_unlock(&mdev->epoch_lock);
+
+	if (schedule_flush) {
+		struct flush_work *fw;
+		fw = kmalloc(sizeof(*fw), GFP_ATOMIC);
+		if (fw) {
+			fw->w.cb = w_flush;
+			fw->epoch = epoch;
+			drbd_queue_work(&mdev->data.work, &fw->w);
+		} else {
+			dev_warn(DEV, "Could not kmalloc a flush_work obj\n");
+			set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
+			/* That is not a recursion, only one level */
+			drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE);
+			drbd_may_finish_epoch(mdev, epoch, EV_PUT);
+		}
+	}
+
+	return rv;
+}
+
+/**
+ * drbd_bump_write_ordering() - Fall back to an other write ordering method
+ * @mdev:	DRBD device.
+ * @wo:		Write ordering method to try.
+ */
+void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) __must_hold(local)
+{
+	enum write_ordering_e pwo;
+	static char *write_ordering_str[] = {
+		[WO_none] = "none",
+		[WO_drain_io] = "drain",
+		[WO_bdev_flush] = "flush",
+		[WO_bio_barrier] = "barrier",
+	};
+
+	pwo = mdev->write_ordering;
+	wo = min(pwo, wo);
+	if (wo == WO_bio_barrier && mdev->ldev->dc.no_disk_barrier)
+		wo = WO_bdev_flush;
+	if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush)
+		wo = WO_drain_io;
+	if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain)
+		wo = WO_none;
+	mdev->write_ordering = wo;
+	if (pwo != mdev->write_ordering || wo == WO_bio_barrier)
+		dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]);
+}
+
+/**
+ * w_e_reissue() - Worker callback; Resubmit a bio, without BIO_RW_BARRIER set
+ * @mdev:	DRBD device.
+ * @w:		work object.
+ * @cancel:	The connection will be closed anyways (unused in this callback)
+ */
+int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local)
+{
+	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	struct bio *bio = e->private_bio;
+
+	/* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place,
+	   (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch)
+	   so that we can finish that epoch in drbd_may_finish_epoch().
+	   That is necessary if we already have a long chain of Epochs, before
+	   we realize that BIO_RW_BARRIER is actually not supported */
+
+	/* As long as the -ENOTSUPP on the barrier is reported immediately
+	   that will never trigger. If it is reported late, we will just
+	   print that warning and continue correctly for all future requests
+	   with WO_bdev_flush */
+	if (previous_epoch(mdev, e->epoch))
+		dev_warn(DEV, "Write ordering was not enforced (one time event)\n");
+
+	/* prepare bio for re-submit,
+	 * re-init volatile members */
+	/* we still have a local reference,
+	 * get_ldev was done in receive_Data. */
+	bio->bi_bdev = mdev->ldev->backing_bdev;
+	bio->bi_sector = e->sector;
+	bio->bi_size = e->size;
+	bio->bi_idx = 0;
+
+	bio->bi_flags &= ~(BIO_POOL_MASK - 1);
+	bio->bi_flags |= 1 << BIO_UPTODATE;
+
+	/* don't know whether this is necessary: */
+	bio->bi_phys_segments = 0;
+	bio->bi_next = NULL;
+
+	/* these should be unchanged: */
+	/* bio->bi_end_io = drbd_endio_write_sec; */
+	/* bio->bi_vcnt = whatever; */
+
+	e->w.cb = e_end_block;
+
+	/* This is no longer a barrier request. */
+	bio->bi_rw &= ~(1UL << BIO_RW_BARRIER);
+
+	drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, bio);
+
+	return 1;
+}
+
+static int receive_Barrier(struct drbd_conf *mdev, struct p_header *h)
+{
+	int rv, issue_flush;
+	struct p_barrier *p = (struct p_barrier *)h;
+	struct drbd_epoch *epoch;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+
+	rv = drbd_recv(mdev, h->payload, h->length);
+	ERR_IF(rv != h->length) return FALSE;
+
+	inc_unacked(mdev);
+
+	if (mdev->net_conf->wire_protocol != DRBD_PROT_C)
+		drbd_kick_lo(mdev);
+
+	mdev->current_epoch->barrier_nr = p->barrier;
+	rv = drbd_may_finish_epoch(mdev, mdev->current_epoch, EV_GOT_BARRIER_NR);
+
+	/* P_BARRIER_ACK may imply that the corresponding extent is dropped from
+	 * the activity log, which means it would not be resynced in case the
+	 * R_PRIMARY crashes now.
+	 * Therefore we must send the barrier_ack after the barrier request was
+	 * completed. */
+	switch (mdev->write_ordering) {
+	case WO_bio_barrier:
+	case WO_none:
+		if (rv == FE_RECYCLED)
+			return TRUE;
+		break;
+
+	case WO_bdev_flush:
+	case WO_drain_io:
+		if (rv == FE_STILL_LIVE) {
+			set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
+			drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
+			rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
+		}
+		if (rv == FE_RECYCLED)
+			return TRUE;
+
+		/* The asender will send all the ACKs and barrier ACKs out, since
+		   all EEs moved from the active_ee to the done_ee. We need to
+		   provide a new epoch object for the EEs that come in soon */
+		break;
+	}
+
+	/* receiver context, in the writeout path of the other node.
+	 * avoid potential distributed deadlock */
+	epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
+	if (!epoch) {
+		dev_warn(DEV, "Allocation of an epoch failed, slowing down\n");
+		issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
+		drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
+		if (issue_flush) {
+			rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
+			if (rv == FE_RECYCLED)
+				return TRUE;
+		}
+
+		drbd_wait_ee_list_empty(mdev, &mdev->done_ee);
+
+		return TRUE;
+	}
+
+	epoch->flags = 0;
+	atomic_set(&epoch->epoch_size, 0);
+	atomic_set(&epoch->active, 0);
+
+	spin_lock(&mdev->epoch_lock);
+	if (atomic_read(&mdev->current_epoch->epoch_size)) {
+		list_add(&epoch->list, &mdev->current_epoch->list);
+		mdev->current_epoch = epoch;
+		mdev->epochs++;
+	} else {
+		/* The current_epoch got recycled while we allocated this one... */
+		kfree(epoch);
+	}
+	spin_unlock(&mdev->epoch_lock);
+
+	return TRUE;
+}
+
+/* used from receive_RSDataReply (recv_resync_read)
+ * and from receive_Data */
+static struct drbd_epoch_entry *
+read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __must_hold(local)
+{
+	struct drbd_epoch_entry *e;
+	struct bio_vec *bvec;
+	struct page *page;
+	struct bio *bio;
+	int dgs, ds, i, rr;
+	void *dig_in = mdev->int_dig_in;
+	void *dig_vv = mdev->int_dig_vv;
+
+	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
+		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
+
+	if (dgs) {
+		rr = drbd_recv(mdev, dig_in, dgs);
+		if (rr != dgs) {
+			dev_warn(DEV, "short read receiving data digest: read %d expected %d\n",
+			     rr, dgs);
+			return NULL;
+		}
+	}
+
+	data_size -= dgs;
+
+	ERR_IF(data_size &  0x1ff) return NULL;
+	ERR_IF(data_size >  DRBD_MAX_SEGMENT_SIZE) return NULL;
+
+	/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
+	 * "criss-cross" setup, that might cause write-out on some other DRBD,
+	 * which in turn might block on the other node at this very place.  */
+	e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_NOIO);
+	if (!e)
+		return NULL;
+	bio = e->private_bio;
+	ds = data_size;
+	bio_for_each_segment(bvec, bio, i) {
+		page = bvec->bv_page;
+		rr = drbd_recv(mdev, kmap(page), min_t(int, ds, PAGE_SIZE));
+		kunmap(page);
+		if (rr != min_t(int, ds, PAGE_SIZE)) {
+			drbd_free_ee(mdev, e);
+			dev_warn(DEV, "short read receiving data: read %d expected %d\n",
+			     rr, min_t(int, ds, PAGE_SIZE));
+			return NULL;
+		}
+		ds -= rr;
+	}
+
+	if (dgs) {
+		drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv);
+		if (memcmp(dig_in, dig_vv, dgs)) {
+			dev_err(DEV, "Digest integrity check FAILED.\n");
+			drbd_bcast_ee(mdev, "digest failed",
+					dgs, dig_in, dig_vv, e);
+			drbd_free_ee(mdev, e);
+			return NULL;
+		}
+	}
+	mdev->recv_cnt += data_size>>9;
+	return e;
+}
+
+/* drbd_drain_block() just takes a data block
+ * out of the socket input buffer, and discards it.
+ */
+static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
+{
+	struct page *page;
+	int rr, rv = 1;
+	void *data;
+
+	page = drbd_pp_alloc(mdev, 1);
+
+	data = kmap(page);
+	while (data_size) {
+		rr = drbd_recv(mdev, data, min_t(int, data_size, PAGE_SIZE));
+		if (rr != min_t(int, data_size, PAGE_SIZE)) {
+			rv = 0;
+			dev_warn(DEV, "short read receiving data: read %d expected %d\n",
+			     rr, min_t(int, data_size, PAGE_SIZE));
+			break;
+		}
+		data_size -= rr;
+	}
+	kunmap(page);
+	drbd_pp_free(mdev, page);
+	return rv;
+}
+
+static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
+			   sector_t sector, int data_size)
+{
+	struct bio_vec *bvec;
+	struct bio *bio;
+	int dgs, rr, i, expect;
+	void *dig_in = mdev->int_dig_in;
+	void *dig_vv = mdev->int_dig_vv;
+
+	dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ?
+		crypto_hash_digestsize(mdev->integrity_r_tfm) : 0;
+
+	if (dgs) {
+		rr = drbd_recv(mdev, dig_in, dgs);
+		if (rr != dgs) {
+			dev_warn(DEV, "short read receiving data reply digest: read %d expected %d\n",
+			     rr, dgs);
+			return 0;
+		}
+	}
+
+	data_size -= dgs;
+
+	/* optimistically update recv_cnt.  if receiving fails below,
+	 * we disconnect anyways, and counters will be reset. */
+	mdev->recv_cnt += data_size>>9;
+
+	bio = req->master_bio;
+	D_ASSERT(sector == bio->bi_sector);
+
+	bio_for_each_segment(bvec, bio, i) {
+		expect = min_t(int, data_size, bvec->bv_len);
+		rr = drbd_recv(mdev,
+			     kmap(bvec->bv_page)+bvec->bv_offset,
+			     expect);
+		kunmap(bvec->bv_page);
+		if (rr != expect) {
+			dev_warn(DEV, "short read receiving data reply: "
+			     "read %d expected %d\n",
+			     rr, expect);
+			return 0;
+		}
+		data_size -= rr;
+	}
+
+	if (dgs) {
+		drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv);
+		if (memcmp(dig_in, dig_vv, dgs)) {
+			dev_err(DEV, "Digest integrity check FAILED. Broken NICs?\n");
+			return 0;
+		}
+	}
+
+	D_ASSERT(data_size == 0);
+	return 1;
+}
+
+/* e_end_resync_block() is called via
+ * drbd_process_done_ee() by asender only */
+static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	sector_t sector = e->sector;
+	int ok;
+
+	D_ASSERT(hlist_unhashed(&e->colision));
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		drbd_set_in_sync(mdev, sector, e->size);
+		ok = drbd_send_ack(mdev, P_RS_WRITE_ACK, e);
+	} else {
+		/* Record failure to sync */
+		drbd_rs_failed_io(mdev, sector, e->size);
+
+		ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
+	}
+	dec_unacked(mdev);
+
+	return ok;
+}
+
+static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_size) __releases(local)
+{
+	struct drbd_epoch_entry *e;
+
+	e = read_in_block(mdev, ID_SYNCER, sector, data_size);
+	if (!e) {
+		put_ldev(mdev);
+		return FALSE;
+	}
+
+	dec_rs_pending(mdev);
+
+	e->private_bio->bi_end_io = drbd_endio_write_sec;
+	e->private_bio->bi_rw = WRITE;
+	e->w.cb = e_end_resync_block;
+
+	inc_unacked(mdev);
+	/* corresponding dec_unacked() in e_end_resync_block()
+	 * respective _drbd_clear_done_ee */
+
+	spin_lock_irq(&mdev->req_lock);
+	list_add(&e->w.list, &mdev->sync_ee);
+	spin_unlock_irq(&mdev->req_lock);
+
+	drbd_generic_make_request(mdev, DRBD_FAULT_RS_WR, e->private_bio);
+	/* accounting done in endio */
+
+	maybe_kick_lo(mdev);
+	return TRUE;
+}
+
+static int receive_DataReply(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct drbd_request *req;
+	sector_t sector;
+	unsigned int header_size, data_size;
+	int ok;
+	struct p_data *p = (struct p_data *)h;
+
+	header_size = sizeof(*p) - sizeof(*h);
+	data_size   = h->length  - header_size;
+
+	ERR_IF(data_size == 0) return FALSE;
+
+	if (drbd_recv(mdev, h->payload, header_size) != header_size)
+		return FALSE;
+
+	sector = be64_to_cpu(p->sector);
+
+	spin_lock_irq(&mdev->req_lock);
+	req = _ar_id_to_req(mdev, p->block_id, sector);
+	spin_unlock_irq(&mdev->req_lock);
+	if (unlikely(!req)) {
+		dev_err(DEV, "Got a corrupt block_id/sector pair(1).\n");
+		return FALSE;
+	}
+
+	/* hlist_del(&req->colision) is done in _req_may_be_done, to avoid
+	 * special casing it there for the various failure cases.
+	 * still no race with drbd_fail_pending_reads */
+	ok = recv_dless_read(mdev, req, sector, data_size);
+
+	if (ok)
+		req_mod(req, data_received);
+	/* else: nothing. handled from drbd_disconnect...
+	 * I don't think we may complete this just yet
+	 * in case we are "on-disconnect: freeze" */
+
+	return ok;
+}
+
+static int receive_RSDataReply(struct drbd_conf *mdev, struct p_header *h)
+{
+	sector_t sector;
+	unsigned int header_size, data_size;
+	int ok;
+	struct p_data *p = (struct p_data *)h;
+
+	header_size = sizeof(*p) - sizeof(*h);
+	data_size   = h->length  - header_size;
+
+	ERR_IF(data_size == 0) return FALSE;
+
+	if (drbd_recv(mdev, h->payload, header_size) != header_size)
+		return FALSE;
+
+	sector = be64_to_cpu(p->sector);
+	D_ASSERT(p->block_id == ID_SYNCER);
+
+	if (get_ldev(mdev)) {
+		/* data is submitted to disk within recv_resync_read.
+		 * corresponding put_ldev done below on error,
+		 * or in drbd_endio_write_sec. */
+		ok = recv_resync_read(mdev, sector, data_size);
+	} else {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Can not write resync data to local disk.\n");
+
+		ok = drbd_drain_block(mdev, data_size);
+
+		drbd_send_ack_dp(mdev, P_NEG_ACK, p);
+	}
+
+	return ok;
+}
+
+/* e_end_block() is called via drbd_process_done_ee().
+ * this means this function only runs in the asender thread
+ */
+static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	sector_t sector = e->sector;
+	struct drbd_epoch *epoch;
+	int ok = 1, pcmd;
+
+	if (e->flags & EE_IS_BARRIER) {
+		epoch = previous_epoch(mdev, e->epoch);
+		if (epoch)
+			drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE + (cancel ? EV_CLEANUP : 0));
+	}
+
+	if (mdev->net_conf->wire_protocol == DRBD_PROT_C) {
+		if (likely(drbd_bio_uptodate(e->private_bio))) {
+			pcmd = (mdev->state.conn >= C_SYNC_SOURCE &&
+				mdev->state.conn <= C_PAUSED_SYNC_T &&
+				e->flags & EE_MAY_SET_IN_SYNC) ?
+				P_RS_WRITE_ACK : P_WRITE_ACK;
+			ok &= drbd_send_ack(mdev, pcmd, e);
+			if (pcmd == P_RS_WRITE_ACK)
+				drbd_set_in_sync(mdev, sector, e->size);
+		} else {
+			ok  = drbd_send_ack(mdev, P_NEG_ACK, e);
+			/* we expect it to be marked out of sync anyways...
+			 * maybe assert this?  */
+		}
+		dec_unacked(mdev);
+	}
+	/* we delete from the conflict detection hash _after_ we sent out the
+	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
+	if (mdev->net_conf->two_primaries) {
+		spin_lock_irq(&mdev->req_lock);
+		D_ASSERT(!hlist_unhashed(&e->colision));
+		hlist_del_init(&e->colision);
+		spin_unlock_irq(&mdev->req_lock);
+	} else {
+		D_ASSERT(hlist_unhashed(&e->colision));
+	}
+
+	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
+
+	return ok;
+}
+
+static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused)
+{
+	struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
+	int ok = 1;
+
+	D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
+
+	spin_lock_irq(&mdev->req_lock);
+	D_ASSERT(!hlist_unhashed(&e->colision));
+	hlist_del_init(&e->colision);
+	spin_unlock_irq(&mdev->req_lock);
+
+	dec_unacked(mdev);
+
+	return ok;
+}
+
+/* Called from receive_Data.
+ * Synchronize packets on sock with packets on msock.
+ *
+ * This is here so even when a P_DATA packet traveling via sock overtook an Ack
+ * packet traveling on msock, they are still processed in the order they have
+ * been sent.
+ *
+ * Note: we don't care for Ack packets overtaking P_DATA packets.
+ *
+ * In case packet_seq is larger than mdev->peer_seq number, there are
+ * outstanding packets on the msock. We wait for them to arrive.
+ * In case we are the logically next packet, we update mdev->peer_seq
+ * ourselves. Correctly handles 32bit wrap around.
+ *
+ * Assume we have a 10 GBit connection, that is about 1<<30 byte per second,
+ * about 1<<21 sectors per second. So "worst" case, we have 1<<3 == 8 seconds
+ * for the 24bit wrap (historical atomic_t guarantee on some archs), and we have
+ * 1<<9 == 512 seconds aka ages for the 32bit wrap around...
+ *
+ * returns 0 if we may process the packet,
+ * -ERESTARTSYS if we were interrupted (by disconnect signal). */
+static int drbd_wait_peer_seq(struct drbd_conf *mdev, const u32 packet_seq)
+{
+	DEFINE_WAIT(wait);
+	unsigned int p_seq;
+	long timeout;
+	int ret = 0;
+	spin_lock(&mdev->peer_seq_lock);
+	for (;;) {
+		prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE);
+		if (seq_le(packet_seq, mdev->peer_seq+1))
+			break;
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		p_seq = mdev->peer_seq;
+		spin_unlock(&mdev->peer_seq_lock);
+		timeout = schedule_timeout(30*HZ);
+		spin_lock(&mdev->peer_seq_lock);
+		if (timeout == 0 && p_seq == mdev->peer_seq) {
+			ret = -ETIMEDOUT;
+			dev_err(DEV, "ASSERT FAILED waited 30 seconds for sequence update, forcing reconnect\n");
+			break;
+		}
+	}
+	finish_wait(&mdev->seq_wait, &wait);
+	if (mdev->peer_seq+1 == packet_seq)
+		mdev->peer_seq++;
+	spin_unlock(&mdev->peer_seq_lock);
+	return ret;
+}
+
+/* mirrored write */
+static int receive_Data(struct drbd_conf *mdev, struct p_header *h)
+{
+	sector_t sector;
+	struct drbd_epoch_entry *e;
+	struct p_data *p = (struct p_data *)h;
+	int header_size, data_size;
+	int rw = WRITE;
+	u32 dp_flags;
+
+	header_size = sizeof(*p) - sizeof(*h);
+	data_size   = h->length  - header_size;
+
+	ERR_IF(data_size == 0) return FALSE;
+
+	if (drbd_recv(mdev, h->payload, header_size) != header_size)
+		return FALSE;
+
+	if (!get_ldev(mdev)) {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Can not write mirrored data block "
+			    "to local disk.\n");
+		spin_lock(&mdev->peer_seq_lock);
+		if (mdev->peer_seq+1 == be32_to_cpu(p->seq_num))
+			mdev->peer_seq++;
+		spin_unlock(&mdev->peer_seq_lock);
+
+		drbd_send_ack_dp(mdev, P_NEG_ACK, p);
+		atomic_inc(&mdev->current_epoch->epoch_size);
+		return drbd_drain_block(mdev, data_size);
+	}
+
+	/* get_ldev(mdev) successful.
+	 * Corresponding put_ldev done either below (on various errors),
+	 * or in drbd_endio_write_sec, if we successfully submit the data at
+	 * the end of this function. */
+
+	sector = be64_to_cpu(p->sector);
+	e = read_in_block(mdev, p->block_id, sector, data_size);
+	if (!e) {
+		put_ldev(mdev);
+		return FALSE;
+	}
+
+	e->private_bio->bi_end_io = drbd_endio_write_sec;
+	e->w.cb = e_end_block;
+
+	spin_lock(&mdev->epoch_lock);
+	e->epoch = mdev->current_epoch;
+	atomic_inc(&e->epoch->epoch_size);
+	atomic_inc(&e->epoch->active);
+
+	if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) {
+		struct drbd_epoch *epoch;
+		/* Issue a barrier if we start a new epoch, and the previous epoch
+		   was not a epoch containing a single request which already was
+		   a Barrier. */
+		epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list);
+		if (epoch == e->epoch) {
+			set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
+			rw |= (1<<BIO_RW_BARRIER);
+			e->flags |= EE_IS_BARRIER;
+		} else {
+			if (atomic_read(&epoch->epoch_size) > 1 ||
+			    !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) {
+				set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
+				set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
+				rw |= (1<<BIO_RW_BARRIER);
+				e->flags |= EE_IS_BARRIER;
+			}
+		}
+	}
+	spin_unlock(&mdev->epoch_lock);
+
+	dp_flags = be32_to_cpu(p->dp_flags);
+	if (dp_flags & DP_HARDBARRIER) {
+		dev_err(DEV, "ASSERT FAILED would have submitted barrier request\n");
+		/* rw |= (1<<BIO_RW_BARRIER); */
+	}
+	if (dp_flags & DP_RW_SYNC)
+		rw |= (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG);
+	if (dp_flags & DP_MAY_SET_IN_SYNC)
+		e->flags |= EE_MAY_SET_IN_SYNC;
+
+	/* I'm the receiver, I do hold a net_cnt reference. */
+	if (!mdev->net_conf->two_primaries) {
+		spin_lock_irq(&mdev->req_lock);
+	} else {
+		/* don't get the req_lock yet,
+		 * we may sleep in drbd_wait_peer_seq */
+		const int size = e->size;
+		const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+		DEFINE_WAIT(wait);
+		struct drbd_request *i;
+		struct hlist_node *n;
+		struct hlist_head *slot;
+		int first;
+
+		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		BUG_ON(mdev->ee_hash == NULL);
+		BUG_ON(mdev->tl_hash == NULL);
+
+		/* conflict detection and handling:
+		 * 1. wait on the sequence number,
+		 *    in case this data packet overtook ACK packets.
+		 * 2. check our hash tables for conflicting requests.
+		 *    we only need to walk the tl_hash, since an ee can not
+		 *    have a conflict with an other ee: on the submitting
+		 *    node, the corresponding req had already been conflicting,
+		 *    and a conflicting req is never sent.
+		 *
+		 * Note: for two_primaries, we are protocol C,
+		 * so there cannot be any request that is DONE
+		 * but still on the transfer log.
+		 *
+		 * unconditionally add to the ee_hash.
+		 *
+		 * if no conflicting request is found:
+		 *    submit.
+		 *
+		 * if any conflicting request is found
+		 * that has not yet been acked,
+		 * AND I have the "discard concurrent writes" flag:
+		 *	 queue (via done_ee) the P_DISCARD_ACK; OUT.
+		 *
+		 * if any conflicting request is found:
+		 *	 block the receiver, waiting on misc_wait
+		 *	 until no more conflicting requests are there,
+		 *	 or we get interrupted (disconnect).
+		 *
+		 *	 we do not just write after local io completion of those
+		 *	 requests, but only after req is done completely, i.e.
+		 *	 we wait for the P_DISCARD_ACK to arrive!
+		 *
+		 *	 then proceed normally, i.e. submit.
+		 */
+		if (drbd_wait_peer_seq(mdev, be32_to_cpu(p->seq_num)))
+			goto out_interrupted;
+
+		spin_lock_irq(&mdev->req_lock);
+
+		hlist_add_head(&e->colision, ee_hash_slot(mdev, sector));
+
+#define OVERLAPS overlaps(i->sector, i->size, sector, size)
+		slot = tl_hash_slot(mdev, sector);
+		first = 1;
+		for (;;) {
+			int have_unacked = 0;
+			int have_conflict = 0;
+			prepare_to_wait(&mdev->misc_wait, &wait,
+				TASK_INTERRUPTIBLE);
+			hlist_for_each_entry(i, n, slot, colision) {
+				if (OVERLAPS) {
+					/* only ALERT on first iteration,
+					 * we may be woken up early... */
+					if (first)
+						dev_alert(DEV, "%s[%u] Concurrent local write detected!"
+						      "	new: %llus +%u; pending: %llus +%u\n",
+						      current->comm, current->pid,
+						      (unsigned long long)sector, size,
+						      (unsigned long long)i->sector, i->size);
+					if (i->rq_state & RQ_NET_PENDING)
+						++have_unacked;
+					++have_conflict;
+				}
+			}
+#undef OVERLAPS
+			if (!have_conflict)
+				break;
+
+			/* Discard Ack only for the _first_ iteration */
+			if (first && discard && have_unacked) {
+				dev_alert(DEV, "Concurrent write! [DISCARD BY FLAG] sec=%llus\n",
+				     (unsigned long long)sector);
+				inc_unacked(mdev);
+				e->w.cb = e_send_discard_ack;
+				list_add_tail(&e->w.list, &mdev->done_ee);
+
+				spin_unlock_irq(&mdev->req_lock);
+
+				/* we could probably send that P_DISCARD_ACK ourselves,
+				 * but I don't like the receiver using the msock */
+
+				put_ldev(mdev);
+				wake_asender(mdev);
+				finish_wait(&mdev->misc_wait, &wait);
+				return TRUE;
+			}
+
+			if (signal_pending(current)) {
+				hlist_del_init(&e->colision);
+
+				spin_unlock_irq(&mdev->req_lock);
+
+				finish_wait(&mdev->misc_wait, &wait);
+				goto out_interrupted;
+			}
+
+			spin_unlock_irq(&mdev->req_lock);
+			if (first) {
+				first = 0;
+				dev_alert(DEV, "Concurrent write! [W AFTERWARDS] "
+				     "sec=%llus\n", (unsigned long long)sector);
+			} else if (discard) {
+				/* we had none on the first iteration.
+				 * there must be none now. */
+				D_ASSERT(have_unacked == 0);
+			}
+			schedule();
+			spin_lock_irq(&mdev->req_lock);
+		}
+		finish_wait(&mdev->misc_wait, &wait);
+	}
+
+	list_add(&e->w.list, &mdev->active_ee);
+	spin_unlock_irq(&mdev->req_lock);
+
+	switch (mdev->net_conf->wire_protocol) {
+	case DRBD_PROT_C:
+		inc_unacked(mdev);
+		/* corresponding dec_unacked() in e_end_block()
+		 * respective _drbd_clear_done_ee */
+		break;
+	case DRBD_PROT_B:
+		/* I really don't like it that the receiver thread
+		 * sends on the msock, but anyways */
+		drbd_send_ack(mdev, P_RECV_ACK, e);
+		break;
+	case DRBD_PROT_A:
+		/* nothing to do */
+		break;
+	}
+
+	if (mdev->state.pdsk == D_DISKLESS) {
+		/* In case we have the only disk of the cluster, */
+		drbd_set_out_of_sync(mdev, e->sector, e->size);
+		e->flags |= EE_CALL_AL_COMPLETE_IO;
+		drbd_al_begin_io(mdev, e->sector);
+	}
+
+	e->private_bio->bi_rw = rw;
+	drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, e->private_bio);
+	/* accounting done in endio */
+
+	maybe_kick_lo(mdev);
+	return TRUE;
+
+out_interrupted:
+	/* yes, the epoch_size now is imbalanced.
+	 * but we drop the connection anyways, so we don't have a chance to
+	 * receive a barrier... atomic_inc(&mdev->epoch_size); */
+	put_ldev(mdev);
+	drbd_free_ee(mdev, e);
+	return FALSE;
+}
+
+static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
+{
+	sector_t sector;
+	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
+	struct drbd_epoch_entry *e;
+	struct digest_info *di = NULL;
+	int size, digest_size;
+	unsigned int fault_type;
+	struct p_block_req *p =
+		(struct p_block_req *)h;
+	const int brps = sizeof(*p)-sizeof(*h);
+
+	if (drbd_recv(mdev, h->payload, brps) != brps)
+		return FALSE;
+
+	sector = be64_to_cpu(p->sector);
+	size   = be32_to_cpu(p->blksize);
+
+	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
+		dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
+				(unsigned long long)sector, size);
+		return FALSE;
+	}
+	if (sector + (size>>9) > capacity) {
+		dev_err(DEV, "%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__,
+				(unsigned long long)sector, size);
+		return FALSE;
+	}
+
+	if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Can not satisfy peer's read request, "
+			    "no local data.\n");
+		drbd_send_ack_rp(mdev, h->command == P_DATA_REQUEST ? P_NEG_DREPLY :
+				 P_NEG_RS_DREPLY , p);
+		return TRUE;
+	}
+
+	/* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD
+	 * "criss-cross" setup, that might cause write-out on some other DRBD,
+	 * which in turn might block on the other node at this very place.  */
+	e = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_NOIO);
+	if (!e) {
+		put_ldev(mdev);
+		return FALSE;
+	}
+
+	e->private_bio->bi_rw = READ;
+	e->private_bio->bi_end_io = drbd_endio_read_sec;
+
+	switch (h->command) {
+	case P_DATA_REQUEST:
+		e->w.cb = w_e_end_data_req;
+		fault_type = DRBD_FAULT_DT_RD;
+		break;
+	case P_RS_DATA_REQUEST:
+		e->w.cb = w_e_end_rsdata_req;
+		fault_type = DRBD_FAULT_RS_RD;
+		/* Eventually this should become asynchronously. Currently it
+		 * blocks the whole receiver just to delay the reading of a
+		 * resync data block.
+		 * the drbd_work_queue mechanism is made for this...
+		 */
+		if (!drbd_rs_begin_io(mdev, sector)) {
+			/* we have been interrupted,
+			 * probably connection lost! */
+			D_ASSERT(signal_pending(current));
+			goto out_free_e;
+		}
+		break;
+
+	case P_OV_REPLY:
+	case P_CSUM_RS_REQUEST:
+		fault_type = DRBD_FAULT_RS_RD;
+		digest_size = h->length - brps ;
+		di = kmalloc(sizeof(*di) + digest_size, GFP_NOIO);
+		if (!di)
+			goto out_free_e;
+
+		di->digest_size = digest_size;
+		di->digest = (((char *)di)+sizeof(struct digest_info));
+
+		if (drbd_recv(mdev, di->digest, digest_size) != digest_size)
+			goto out_free_e;
+
+		e->block_id = (u64)(unsigned long)di;
+		if (h->command == P_CSUM_RS_REQUEST) {
+			D_ASSERT(mdev->agreed_pro_version >= 89);
+			e->w.cb = w_e_end_csum_rs_req;
+		} else if (h->command == P_OV_REPLY) {
+			e->w.cb = w_e_end_ov_reply;
+			dec_rs_pending(mdev);
+			break;
+		}
+
+		if (!drbd_rs_begin_io(mdev, sector)) {
+			/* we have been interrupted, probably connection lost! */
+			D_ASSERT(signal_pending(current));
+			goto out_free_e;
+		}
+		break;
+
+	case P_OV_REQUEST:
+		if (mdev->state.conn >= C_CONNECTED &&
+		    mdev->state.conn != C_VERIFY_T)
+			dev_warn(DEV, "ASSERT FAILED: got P_OV_REQUEST while being %s\n",
+				drbd_conn_str(mdev->state.conn));
+		if (mdev->ov_start_sector == ~(sector_t)0 &&
+		    mdev->agreed_pro_version >= 90) {
+			mdev->ov_start_sector = sector;
+			mdev->ov_position = sector;
+			mdev->ov_left = mdev->rs_total - BM_SECT_TO_BIT(sector);
+			dev_info(DEV, "Online Verify start sector: %llu\n",
+					(unsigned long long)sector);
+		}
+		e->w.cb = w_e_end_ov_req;
+		fault_type = DRBD_FAULT_RS_RD;
+		/* Eventually this should become asynchronous. Currently it
+		 * blocks the whole receiver just to delay the reading of a
+		 * resync data block.
+		 * the drbd_work_queue mechanism is made for this...
+		 */
+		if (!drbd_rs_begin_io(mdev, sector)) {
+			/* we have been interrupted,
+			 * probably connection lost! */
+			D_ASSERT(signal_pending(current));
+			goto out_free_e;
+		}
+		break;
+
+
+	default:
+		dev_err(DEV, "unexpected command (%s) in receive_DataRequest\n",
+		    cmdname(h->command));
+		fault_type = DRBD_FAULT_MAX;
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	list_add(&e->w.list, &mdev->read_ee);
+	spin_unlock_irq(&mdev->req_lock);
+
+	inc_unacked(mdev);
+
+	drbd_generic_make_request(mdev, fault_type, e->private_bio);
+	maybe_kick_lo(mdev);
+
+	return TRUE;
+
+out_free_e:
+	kfree(di);
+	put_ldev(mdev);
+	drbd_free_ee(mdev, e);
+	return FALSE;
+}
+
+static int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local)
+{
+	int self, peer, rv = -100;
+	unsigned long ch_self, ch_peer;
+
+	self = mdev->ldev->md.uuid[UI_BITMAP] & 1;
+	peer = mdev->p_uuid[UI_BITMAP] & 1;
+
+	ch_peer = mdev->p_uuid[UI_SIZE];
+	ch_self = mdev->comm_bm_set;
+
+	switch (mdev->net_conf->after_sb_0p) {
+	case ASB_CONSENSUS:
+	case ASB_DISCARD_SECONDARY:
+	case ASB_CALL_HELPER:
+		dev_err(DEV, "Configuration error.\n");
+		break;
+	case ASB_DISCONNECT:
+		break;
+	case ASB_DISCARD_YOUNGER_PRI:
+		if (self == 0 && peer == 1) {
+			rv = -1;
+			break;
+		}
+		if (self == 1 && peer == 0) {
+			rv =  1;
+			break;
+		}
+		/* Else fall through to one of the other strategies... */
+	case ASB_DISCARD_OLDER_PRI:
+		if (self == 0 && peer == 1) {
+			rv = 1;
+			break;
+		}
+		if (self == 1 && peer == 0) {
+			rv = -1;
+			break;
+		}
+		/* Else fall through to one of the other strategies... */
+		dev_warn(DEV, "Discard younger/older primary did not find a decision\n"
+		     "Using discard-least-changes instead\n");
+	case ASB_DISCARD_ZERO_CHG:
+		if (ch_peer == 0 && ch_self == 0) {
+			rv = test_bit(DISCARD_CONCURRENT, &mdev->flags)
+				? -1 : 1;
+			break;
+		} else {
+			if (ch_peer == 0) { rv =  1; break; }
+			if (ch_self == 0) { rv = -1; break; }
+		}
+		if (mdev->net_conf->after_sb_0p == ASB_DISCARD_ZERO_CHG)
+			break;
+	case ASB_DISCARD_LEAST_CHG:
+		if	(ch_self < ch_peer)
+			rv = -1;
+		else if (ch_self > ch_peer)
+			rv =  1;
+		else /* ( ch_self == ch_peer ) */
+		     /* Well, then use something else. */
+			rv = test_bit(DISCARD_CONCURRENT, &mdev->flags)
+				? -1 : 1;
+		break;
+	case ASB_DISCARD_LOCAL:
+		rv = -1;
+		break;
+	case ASB_DISCARD_REMOTE:
+		rv =  1;
+	}
+
+	return rv;
+}
+
+static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local)
+{
+	int self, peer, hg, rv = -100;
+
+	self = mdev->ldev->md.uuid[UI_BITMAP] & 1;
+	peer = mdev->p_uuid[UI_BITMAP] & 1;
+
+	switch (mdev->net_conf->after_sb_1p) {
+	case ASB_DISCARD_YOUNGER_PRI:
+	case ASB_DISCARD_OLDER_PRI:
+	case ASB_DISCARD_LEAST_CHG:
+	case ASB_DISCARD_LOCAL:
+	case ASB_DISCARD_REMOTE:
+		dev_err(DEV, "Configuration error.\n");
+		break;
+	case ASB_DISCONNECT:
+		break;
+	case ASB_CONSENSUS:
+		hg = drbd_asb_recover_0p(mdev);
+		if (hg == -1 && mdev->state.role == R_SECONDARY)
+			rv = hg;
+		if (hg == 1  && mdev->state.role == R_PRIMARY)
+			rv = hg;
+		break;
+	case ASB_VIOLENTLY:
+		rv = drbd_asb_recover_0p(mdev);
+		break;
+	case ASB_DISCARD_SECONDARY:
+		return mdev->state.role == R_PRIMARY ? 1 : -1;
+	case ASB_CALL_HELPER:
+		hg = drbd_asb_recover_0p(mdev);
+		if (hg == -1 && mdev->state.role == R_PRIMARY) {
+			self = drbd_set_role(mdev, R_SECONDARY, 0);
+			 /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
+			  * we might be here in C_WF_REPORT_PARAMS which is transient.
+			  * we do not need to wait for the after state change work either. */
+			self = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY));
+			if (self != SS_SUCCESS) {
+				drbd_khelper(mdev, "pri-lost-after-sb");
+			} else {
+				dev_warn(DEV, "Successfully gave up primary role.\n");
+				rv = hg;
+			}
+		} else
+			rv = hg;
+	}
+
+	return rv;
+}
+
+static int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local)
+{
+	int self, peer, hg, rv = -100;
+
+	self = mdev->ldev->md.uuid[UI_BITMAP] & 1;
+	peer = mdev->p_uuid[UI_BITMAP] & 1;
+
+	switch (mdev->net_conf->after_sb_2p) {
+	case ASB_DISCARD_YOUNGER_PRI:
+	case ASB_DISCARD_OLDER_PRI:
+	case ASB_DISCARD_LEAST_CHG:
+	case ASB_DISCARD_LOCAL:
+	case ASB_DISCARD_REMOTE:
+	case ASB_CONSENSUS:
+	case ASB_DISCARD_SECONDARY:
+		dev_err(DEV, "Configuration error.\n");
+		break;
+	case ASB_VIOLENTLY:
+		rv = drbd_asb_recover_0p(mdev);
+		break;
+	case ASB_DISCONNECT:
+		break;
+	case ASB_CALL_HELPER:
+		hg = drbd_asb_recover_0p(mdev);
+		if (hg == -1) {
+			 /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
+			  * we might be here in C_WF_REPORT_PARAMS which is transient.
+			  * we do not need to wait for the after state change work either. */
+			self = drbd_change_state(mdev, CS_VERBOSE, NS(role, R_SECONDARY));
+			if (self != SS_SUCCESS) {
+				drbd_khelper(mdev, "pri-lost-after-sb");
+			} else {
+				dev_warn(DEV, "Successfully gave up primary role.\n");
+				rv = hg;
+			}
+		} else
+			rv = hg;
+	}
+
+	return rv;
+}
+
+static void drbd_uuid_dump(struct drbd_conf *mdev, char *text, u64 *uuid,
+			   u64 bits, u64 flags)
+{
+	if (!uuid) {
+		dev_info(DEV, "%s uuid info vanished while I was looking!\n", text);
+		return;
+	}
+	dev_info(DEV, "%s %016llX:%016llX:%016llX:%016llX bits:%llu flags:%llX\n",
+	     text,
+	     (unsigned long long)uuid[UI_CURRENT],
+	     (unsigned long long)uuid[UI_BITMAP],
+	     (unsigned long long)uuid[UI_HISTORY_START],
+	     (unsigned long long)uuid[UI_HISTORY_END],
+	     (unsigned long long)bits,
+	     (unsigned long long)flags);
+}
+
+/*
+  100	after split brain try auto recover
+    2	C_SYNC_SOURCE set BitMap
+    1	C_SYNC_SOURCE use BitMap
+    0	no Sync
+   -1	C_SYNC_TARGET use BitMap
+   -2	C_SYNC_TARGET set BitMap
+ -100	after split brain, disconnect
+-1000	unrelated data
+ */
+static int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(local)
+{
+	u64 self, peer;
+	int i, j;
+
+	self = mdev->ldev->md.uuid[UI_CURRENT] & ~((u64)1);
+	peer = mdev->p_uuid[UI_CURRENT] & ~((u64)1);
+
+	*rule_nr = 10;
+	if (self == UUID_JUST_CREATED && peer == UUID_JUST_CREATED)
+		return 0;
+
+	*rule_nr = 20;
+	if ((self == UUID_JUST_CREATED || self == (u64)0) &&
+	     peer != UUID_JUST_CREATED)
+		return -2;
+
+	*rule_nr = 30;
+	if (self != UUID_JUST_CREATED &&
+	    (peer == UUID_JUST_CREATED || peer == (u64)0))
+		return 2;
+
+	if (self == peer) {
+		int rct, dc; /* roles at crash time */
+
+		if (mdev->p_uuid[UI_BITMAP] == (u64)0 && mdev->ldev->md.uuid[UI_BITMAP] != (u64)0) {
+
+			if (mdev->agreed_pro_version < 91)
+				return -1001;
+
+			if ((mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1)) &&
+			    (mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1))) {
+				dev_info(DEV, "was SyncSource, missed the resync finished event, corrected myself:\n");
+				drbd_uuid_set_bm(mdev, 0UL);
+
+				drbd_uuid_dump(mdev, "self", mdev->ldev->md.uuid,
+					       mdev->state.disk >= D_NEGOTIATING ? drbd_bm_total_weight(mdev) : 0, 0);
+				*rule_nr = 34;
+			} else {
+				dev_info(DEV, "was SyncSource (peer failed to write sync_uuid)\n");
+				*rule_nr = 36;
+			}
+
+			return 1;
+		}
+
+		if (mdev->ldev->md.uuid[UI_BITMAP] == (u64)0 && mdev->p_uuid[UI_BITMAP] != (u64)0) {
+
+			if (mdev->agreed_pro_version < 91)
+				return -1001;
+
+			if ((mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1)) == (mdev->p_uuid[UI_BITMAP] & ~((u64)1)) &&
+			    (mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1)) == (mdev->p_uuid[UI_HISTORY_START] & ~((u64)1))) {
+				dev_info(DEV, "was SyncTarget, peer missed the resync finished event, corrected peer:\n");
+
+				mdev->p_uuid[UI_HISTORY_START + 1] = mdev->p_uuid[UI_HISTORY_START];
+				mdev->p_uuid[UI_HISTORY_START] = mdev->p_uuid[UI_BITMAP];
+				mdev->p_uuid[UI_BITMAP] = 0UL;
+
+				drbd_uuid_dump(mdev, "peer", mdev->p_uuid, mdev->p_uuid[UI_SIZE], mdev->p_uuid[UI_FLAGS]);
+				*rule_nr = 35;
+			} else {
+				dev_info(DEV, "was SyncTarget (failed to write sync_uuid)\n");
+				*rule_nr = 37;
+			}
+
+			return -1;
+		}
+
+		/* Common power [off|failure] */
+		rct = (test_bit(CRASHED_PRIMARY, &mdev->flags) ? 1 : 0) +
+			(mdev->p_uuid[UI_FLAGS] & 2);
+		/* lowest bit is set when we were primary,
+		 * next bit (weight 2) is set when peer was primary */
+		*rule_nr = 40;
+
+		switch (rct) {
+		case 0: /* !self_pri && !peer_pri */ return 0;
+		case 1: /*  self_pri && !peer_pri */ return 1;
+		case 2: /* !self_pri &&  peer_pri */ return -1;
+		case 3: /*  self_pri &&  peer_pri */
+			dc = test_bit(DISCARD_CONCURRENT, &mdev->flags);
+			return dc ? -1 : 1;
+		}
+	}
+
+	*rule_nr = 50;
+	peer = mdev->p_uuid[UI_BITMAP] & ~((u64)1);
+	if (self == peer)
+		return -1;
+
+	*rule_nr = 51;
+	peer = mdev->p_uuid[UI_HISTORY_START] & ~((u64)1);
+	if (self == peer) {
+		self = mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1);
+		peer = mdev->p_uuid[UI_HISTORY_START + 1] & ~((u64)1);
+		if (self == peer) {
+			/* The last P_SYNC_UUID did not get though. Undo the last start of
+			   resync as sync source modifications of the peer's UUIDs. */
+
+			if (mdev->agreed_pro_version < 91)
+				return -1001;
+
+			mdev->p_uuid[UI_BITMAP] = mdev->p_uuid[UI_HISTORY_START];
+			mdev->p_uuid[UI_HISTORY_START] = mdev->p_uuid[UI_HISTORY_START + 1];
+			return -1;
+		}
+	}
+
+	*rule_nr = 60;
+	self = mdev->ldev->md.uuid[UI_CURRENT] & ~((u64)1);
+	for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
+		peer = mdev->p_uuid[i] & ~((u64)1);
+		if (self == peer)
+			return -2;
+	}
+
+	*rule_nr = 70;
+	self = mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1);
+	peer = mdev->p_uuid[UI_CURRENT] & ~((u64)1);
+	if (self == peer)
+		return 1;
+
+	*rule_nr = 71;
+	self = mdev->ldev->md.uuid[UI_HISTORY_START] & ~((u64)1);
+	if (self == peer) {
+		self = mdev->ldev->md.uuid[UI_HISTORY_START + 1] & ~((u64)1);
+		peer = mdev->p_uuid[UI_HISTORY_START] & ~((u64)1);
+		if (self == peer) {
+			/* The last P_SYNC_UUID did not get though. Undo the last start of
+			   resync as sync source modifications of our UUIDs. */
+
+			if (mdev->agreed_pro_version < 91)
+				return -1001;
+
+			_drbd_uuid_set(mdev, UI_BITMAP, mdev->ldev->md.uuid[UI_HISTORY_START]);
+			_drbd_uuid_set(mdev, UI_HISTORY_START, mdev->ldev->md.uuid[UI_HISTORY_START + 1]);
+
+			dev_info(DEV, "Undid last start of resync:\n");
+
+			drbd_uuid_dump(mdev, "self", mdev->ldev->md.uuid,
+				       mdev->state.disk >= D_NEGOTIATING ? drbd_bm_total_weight(mdev) : 0, 0);
+
+			return 1;
+		}
+	}
+
+
+	*rule_nr = 80;
+	peer = mdev->p_uuid[UI_CURRENT] & ~((u64)1);
+	for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
+		self = mdev->ldev->md.uuid[i] & ~((u64)1);
+		if (self == peer)
+			return 2;
+	}
+
+	*rule_nr = 90;
+	self = mdev->ldev->md.uuid[UI_BITMAP] & ~((u64)1);
+	peer = mdev->p_uuid[UI_BITMAP] & ~((u64)1);
+	if (self == peer && self != ((u64)0))
+		return 100;
+
+	*rule_nr = 100;
+	for (i = UI_HISTORY_START; i <= UI_HISTORY_END; i++) {
+		self = mdev->ldev->md.uuid[i] & ~((u64)1);
+		for (j = UI_HISTORY_START; j <= UI_HISTORY_END; j++) {
+			peer = mdev->p_uuid[j] & ~((u64)1);
+			if (self == peer)
+				return -100;
+		}
+	}
+
+	return -1000;
+}
+
+/* drbd_sync_handshake() returns the new conn state on success, or
+   CONN_MASK (-1) on failure.
+ */
+static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_role peer_role,
+					   enum drbd_disk_state peer_disk) __must_hold(local)
+{
+	int hg, rule_nr;
+	enum drbd_conns rv = C_MASK;
+	enum drbd_disk_state mydisk;
+
+	mydisk = mdev->state.disk;
+	if (mydisk == D_NEGOTIATING)
+		mydisk = mdev->new_state_tmp.disk;
+
+	dev_info(DEV, "drbd_sync_handshake:\n");
+	drbd_uuid_dump(mdev, "self", mdev->ldev->md.uuid, mdev->comm_bm_set, 0);
+	drbd_uuid_dump(mdev, "peer", mdev->p_uuid,
+		       mdev->p_uuid[UI_SIZE], mdev->p_uuid[UI_FLAGS]);
+
+	hg = drbd_uuid_compare(mdev, &rule_nr);
+
+	dev_info(DEV, "uuid_compare()=%d by rule %d\n", hg, rule_nr);
+
+	if (hg == -1000) {
+		dev_alert(DEV, "Unrelated data, aborting!\n");
+		return C_MASK;
+	}
+	if (hg == -1001) {
+		dev_alert(DEV, "To resolve this both sides have to support at least protocol\n");
+		return C_MASK;
+	}
+
+	if    ((mydisk == D_INCONSISTENT && peer_disk > D_INCONSISTENT) ||
+	    (peer_disk == D_INCONSISTENT && mydisk    > D_INCONSISTENT)) {
+		int f = (hg == -100) || abs(hg) == 2;
+		hg = mydisk > D_INCONSISTENT ? 1 : -1;
+		if (f)
+			hg = hg*2;
+		dev_info(DEV, "Becoming sync %s due to disk states.\n",
+		     hg > 0 ? "source" : "target");
+	}
+
+	if (hg == 100 || (hg == -100 && mdev->net_conf->always_asbp)) {
+		int pcount = (mdev->state.role == R_PRIMARY)
+			   + (peer_role == R_PRIMARY);
+		int forced = (hg == -100);
+
+		switch (pcount) {
+		case 0:
+			hg = drbd_asb_recover_0p(mdev);
+			break;
+		case 1:
+			hg = drbd_asb_recover_1p(mdev);
+			break;
+		case 2:
+			hg = drbd_asb_recover_2p(mdev);
+			break;
+		}
+		if (abs(hg) < 100) {
+			dev_warn(DEV, "Split-Brain detected, %d primaries, "
+			     "automatically solved. Sync from %s node\n",
+			     pcount, (hg < 0) ? "peer" : "this");
+			if (forced) {
+				dev_warn(DEV, "Doing a full sync, since"
+				     " UUIDs where ambiguous.\n");
+				hg = hg*2;
+			}
+		}
+	}
+
+	if (hg == -100) {
+		if (mdev->net_conf->want_lose && !(mdev->p_uuid[UI_FLAGS]&1))
+			hg = -1;
+		if (!mdev->net_conf->want_lose && (mdev->p_uuid[UI_FLAGS]&1))
+			hg = 1;
+
+		if (abs(hg) < 100)
+			dev_warn(DEV, "Split-Brain detected, manually solved. "
+			     "Sync from %s node\n",
+			     (hg < 0) ? "peer" : "this");
+	}
+
+	if (hg == -100) {
+		dev_alert(DEV, "Split-Brain detected, dropping connection!\n");
+		drbd_khelper(mdev, "split-brain");
+		return C_MASK;
+	}
+
+	if (hg > 0 && mydisk <= D_INCONSISTENT) {
+		dev_err(DEV, "I shall become SyncSource, but I am inconsistent!\n");
+		return C_MASK;
+	}
+
+	if (hg < 0 && /* by intention we do not use mydisk here. */
+	    mdev->state.role == R_PRIMARY && mdev->state.disk >= D_CONSISTENT) {
+		switch (mdev->net_conf->rr_conflict) {
+		case ASB_CALL_HELPER:
+			drbd_khelper(mdev, "pri-lost");
+			/* fall through */
+		case ASB_DISCONNECT:
+			dev_err(DEV, "I shall become SyncTarget, but I am primary!\n");
+			return C_MASK;
+		case ASB_VIOLENTLY:
+			dev_warn(DEV, "Becoming SyncTarget, violating the stable-data"
+			     "assumption\n");
+		}
+	}
+
+	if (abs(hg) >= 2) {
+		dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
+		if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
+			return C_MASK;
+	}
+
+	if (hg > 0) { /* become sync source. */
+		rv = C_WF_BITMAP_S;
+	} else if (hg < 0) { /* become sync target */
+		rv = C_WF_BITMAP_T;
+	} else {
+		rv = C_CONNECTED;
+		if (drbd_bm_total_weight(mdev)) {
+			dev_info(DEV, "No resync, but %lu bits in bitmap!\n",
+			     drbd_bm_total_weight(mdev));
+		}
+	}
+
+	return rv;
+}
+
+/* returns 1 if invalid */
+static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self)
+{
+	/* ASB_DISCARD_REMOTE - ASB_DISCARD_LOCAL is valid */
+	if ((peer == ASB_DISCARD_REMOTE && self == ASB_DISCARD_LOCAL) ||
+	    (self == ASB_DISCARD_REMOTE && peer == ASB_DISCARD_LOCAL))
+		return 0;
+
+	/* any other things with ASB_DISCARD_REMOTE or ASB_DISCARD_LOCAL are invalid */
+	if (peer == ASB_DISCARD_REMOTE || peer == ASB_DISCARD_LOCAL ||
+	    self == ASB_DISCARD_REMOTE || self == ASB_DISCARD_LOCAL)
+		return 1;
+
+	/* everything else is valid if they are equal on both sides. */
+	if (peer == self)
+		return 0;
+
+	/* everything es is invalid. */
+	return 1;
+}
+
+static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_protocol *p = (struct p_protocol *)h;
+	int header_size, data_size;
+	int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
+	int p_want_lose, p_two_primaries;
+	char p_integrity_alg[SHARED_SECRET_MAX] = "";
+
+	header_size = sizeof(*p) - sizeof(*h);
+	data_size   = h->length  - header_size;
+
+	if (drbd_recv(mdev, h->payload, header_size) != header_size)
+		return FALSE;
+
+	p_proto		= be32_to_cpu(p->protocol);
+	p_after_sb_0p	= be32_to_cpu(p->after_sb_0p);
+	p_after_sb_1p	= be32_to_cpu(p->after_sb_1p);
+	p_after_sb_2p	= be32_to_cpu(p->after_sb_2p);
+	p_want_lose	= be32_to_cpu(p->want_lose);
+	p_two_primaries = be32_to_cpu(p->two_primaries);
+
+	if (p_proto != mdev->net_conf->wire_protocol) {
+		dev_err(DEV, "incompatible communication protocols\n");
+		goto disconnect;
+	}
+
+	if (cmp_after_sb(p_after_sb_0p, mdev->net_conf->after_sb_0p)) {
+		dev_err(DEV, "incompatible after-sb-0pri settings\n");
+		goto disconnect;
+	}
+
+	if (cmp_after_sb(p_after_sb_1p, mdev->net_conf->after_sb_1p)) {
+		dev_err(DEV, "incompatible after-sb-1pri settings\n");
+		goto disconnect;
+	}
+
+	if (cmp_after_sb(p_after_sb_2p, mdev->net_conf->after_sb_2p)) {
+		dev_err(DEV, "incompatible after-sb-2pri settings\n");
+		goto disconnect;
+	}
+
+	if (p_want_lose && mdev->net_conf->want_lose) {
+		dev_err(DEV, "both sides have the 'want_lose' flag set\n");
+		goto disconnect;
+	}
+
+	if (p_two_primaries != mdev->net_conf->two_primaries) {
+		dev_err(DEV, "incompatible setting of the two-primaries options\n");
+		goto disconnect;
+	}
+
+	if (mdev->agreed_pro_version >= 87) {
+		unsigned char *my_alg = mdev->net_conf->integrity_alg;
+
+		if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size)
+			return FALSE;
+
+		p_integrity_alg[SHARED_SECRET_MAX-1] = 0;
+		if (strcmp(p_integrity_alg, my_alg)) {
+			dev_err(DEV, "incompatible setting of the data-integrity-alg\n");
+			goto disconnect;
+		}
+		dev_info(DEV, "data-integrity-alg: %s\n",
+		     my_alg[0] ? my_alg : (unsigned char *)"<not-used>");
+	}
+
+	return TRUE;
+
+disconnect:
+	drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+	return FALSE;
+}
+
+/* helper function
+ * input: alg name, feature name
+ * return: NULL (alg name was "")
+ *         ERR_PTR(error) if something goes wrong
+ *         or the crypto hash ptr, if it worked out ok. */
+struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev,
+		const char *alg, const char *name)
+{
+	struct crypto_hash *tfm;
+
+	if (!alg[0])
+		return NULL;
+
+	tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm)) {
+		dev_err(DEV, "Can not allocate \"%s\" as %s (reason: %ld)\n",
+			alg, name, PTR_ERR(tfm));
+		return tfm;
+	}
+	if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
+		crypto_free_hash(tfm);
+		dev_err(DEV, "\"%s\" is not a digest (%s)\n", alg, name);
+		return ERR_PTR(-EINVAL);
+	}
+	return tfm;
+}
+
+static int receive_SyncParam(struct drbd_conf *mdev, struct p_header *h)
+{
+	int ok = TRUE;
+	struct p_rs_param_89 *p = (struct p_rs_param_89 *)h;
+	unsigned int header_size, data_size, exp_max_sz;
+	struct crypto_hash *verify_tfm = NULL;
+	struct crypto_hash *csums_tfm = NULL;
+	const int apv = mdev->agreed_pro_version;
+
+	exp_max_sz  = apv <= 87 ? sizeof(struct p_rs_param)
+		    : apv == 88 ? sizeof(struct p_rs_param)
+					+ SHARED_SECRET_MAX
+		    : /* 89 */    sizeof(struct p_rs_param_89);
+
+	if (h->length > exp_max_sz) {
+		dev_err(DEV, "SyncParam packet too long: received %u, expected <= %u bytes\n",
+		    h->length, exp_max_sz);
+		return FALSE;
+	}
+
+	if (apv <= 88) {
+		header_size = sizeof(struct p_rs_param) - sizeof(*h);
+		data_size   = h->length  - header_size;
+	} else /* apv >= 89 */ {
+		header_size = sizeof(struct p_rs_param_89) - sizeof(*h);
+		data_size   = h->length  - header_size;
+		D_ASSERT(data_size == 0);
+	}
+
+	/* initialize verify_alg and csums_alg */
+	memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX);
+
+	if (drbd_recv(mdev, h->payload, header_size) != header_size)
+		return FALSE;
+
+	mdev->sync_conf.rate	  = be32_to_cpu(p->rate);
+
+	if (apv >= 88) {
+		if (apv == 88) {
+			if (data_size > SHARED_SECRET_MAX) {
+				dev_err(DEV, "verify-alg too long, "
+				    "peer wants %u, accepting only %u byte\n",
+						data_size, SHARED_SECRET_MAX);
+				return FALSE;
+			}
+
+			if (drbd_recv(mdev, p->verify_alg, data_size) != data_size)
+				return FALSE;
+
+			/* we expect NUL terminated string */
+			/* but just in case someone tries to be evil */
+			D_ASSERT(p->verify_alg[data_size-1] == 0);
+			p->verify_alg[data_size-1] = 0;
+
+		} else /* apv >= 89 */ {
+			/* we still expect NUL terminated strings */
+			/* but just in case someone tries to be evil */
+			D_ASSERT(p->verify_alg[SHARED_SECRET_MAX-1] == 0);
+			D_ASSERT(p->csums_alg[SHARED_SECRET_MAX-1] == 0);
+			p->verify_alg[SHARED_SECRET_MAX-1] = 0;
+			p->csums_alg[SHARED_SECRET_MAX-1] = 0;
+		}
+
+		if (strcmp(mdev->sync_conf.verify_alg, p->verify_alg)) {
+			if (mdev->state.conn == C_WF_REPORT_PARAMS) {
+				dev_err(DEV, "Different verify-alg settings. me=\"%s\" peer=\"%s\"\n",
+				    mdev->sync_conf.verify_alg, p->verify_alg);
+				goto disconnect;
+			}
+			verify_tfm = drbd_crypto_alloc_digest_safe(mdev,
+					p->verify_alg, "verify-alg");
+			if (IS_ERR(verify_tfm)) {
+				verify_tfm = NULL;
+				goto disconnect;
+			}
+		}
+
+		if (apv >= 89 && strcmp(mdev->sync_conf.csums_alg, p->csums_alg)) {
+			if (mdev->state.conn == C_WF_REPORT_PARAMS) {
+				dev_err(DEV, "Different csums-alg settings. me=\"%s\" peer=\"%s\"\n",
+				    mdev->sync_conf.csums_alg, p->csums_alg);
+				goto disconnect;
+			}
+			csums_tfm = drbd_crypto_alloc_digest_safe(mdev,
+					p->csums_alg, "csums-alg");
+			if (IS_ERR(csums_tfm)) {
+				csums_tfm = NULL;
+				goto disconnect;
+			}
+		}
+
+
+		spin_lock(&mdev->peer_seq_lock);
+		/* lock against drbd_nl_syncer_conf() */
+		if (verify_tfm) {
+			strcpy(mdev->sync_conf.verify_alg, p->verify_alg);
+			mdev->sync_conf.verify_alg_len = strlen(p->verify_alg) + 1;
+			crypto_free_hash(mdev->verify_tfm);
+			mdev->verify_tfm = verify_tfm;
+			dev_info(DEV, "using verify-alg: \"%s\"\n", p->verify_alg);
+		}
+		if (csums_tfm) {
+			strcpy(mdev->sync_conf.csums_alg, p->csums_alg);
+			mdev->sync_conf.csums_alg_len = strlen(p->csums_alg) + 1;
+			crypto_free_hash(mdev->csums_tfm);
+			mdev->csums_tfm = csums_tfm;
+			dev_info(DEV, "using csums-alg: \"%s\"\n", p->csums_alg);
+		}
+		spin_unlock(&mdev->peer_seq_lock);
+	}
+
+	return ok;
+disconnect:
+	/* just for completeness: actually not needed,
+	 * as this is not reached if csums_tfm was ok. */
+	crypto_free_hash(csums_tfm);
+	/* but free the verify_tfm again, if csums_tfm did not work out */
+	crypto_free_hash(verify_tfm);
+	drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+	return FALSE;
+}
+
+static void drbd_setup_order_type(struct drbd_conf *mdev, int peer)
+{
+	/* sorry, we currently have no working implementation
+	 * of distributed TCQ */
+}
+
+/* warn if the arguments differ by more than 12.5% */
+static void warn_if_differ_considerably(struct drbd_conf *mdev,
+	const char *s, sector_t a, sector_t b)
+{
+	sector_t d;
+	if (a == 0 || b == 0)
+		return;
+	d = (a > b) ? (a - b) : (b - a);
+	if (d > (a>>3) || d > (b>>3))
+		dev_warn(DEV, "Considerable difference in %s: %llus vs. %llus\n", s,
+		     (unsigned long long)a, (unsigned long long)b);
+}
+
+static int receive_sizes(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_sizes *p = (struct p_sizes *)h;
+	enum determine_dev_size dd = unchanged;
+	unsigned int max_seg_s;
+	sector_t p_size, p_usize, my_usize;
+	int ldsc = 0; /* local disk size changed */
+	enum drbd_conns nconn;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	p_size = be64_to_cpu(p->d_size);
+	p_usize = be64_to_cpu(p->u_size);
+
+	if (p_size == 0 && mdev->state.disk == D_DISKLESS) {
+		dev_err(DEV, "some backing storage is needed\n");
+		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+		return FALSE;
+	}
+
+	/* just store the peer's disk size for now.
+	 * we still need to figure out whether we accept that. */
+	mdev->p_size = p_size;
+
+#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
+	if (get_ldev(mdev)) {
+		warn_if_differ_considerably(mdev, "lower level device sizes",
+			   p_size, drbd_get_max_capacity(mdev->ldev));
+		warn_if_differ_considerably(mdev, "user requested size",
+					    p_usize, mdev->ldev->dc.disk_size);
+
+		/* if this is the first connect, or an otherwise expected
+		 * param exchange, choose the minimum */
+		if (mdev->state.conn == C_WF_REPORT_PARAMS)
+			p_usize = min_not_zero((sector_t)mdev->ldev->dc.disk_size,
+					     p_usize);
+
+		my_usize = mdev->ldev->dc.disk_size;
+
+		if (mdev->ldev->dc.disk_size != p_usize) {
+			mdev->ldev->dc.disk_size = p_usize;
+			dev_info(DEV, "Peer sets u_size to %lu sectors\n",
+			     (unsigned long)mdev->ldev->dc.disk_size);
+		}
+
+		/* Never shrink a device with usable data during connect.
+		   But allow online shrinking if we are connected. */
+		if (drbd_new_dev_size(mdev, mdev->ldev, 0) <
+		   drbd_get_capacity(mdev->this_bdev) &&
+		   mdev->state.disk >= D_OUTDATED &&
+		   mdev->state.conn < C_CONNECTED) {
+			dev_err(DEV, "The peer's disk size is too small!\n");
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			mdev->ldev->dc.disk_size = my_usize;
+			put_ldev(mdev);
+			return FALSE;
+		}
+		put_ldev(mdev);
+	}
+#undef min_not_zero
+
+	if (get_ldev(mdev)) {
+	  dd = drbd_determin_dev_size(mdev, 0);
+		put_ldev(mdev);
+		if (dd == dev_size_error)
+			return FALSE;
+		drbd_md_sync(mdev);
+	} else {
+		/* I am diskless, need to accept the peer's size. */
+		drbd_set_my_capacity(mdev, p_size);
+	}
+
+	if (mdev->p_uuid && mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) {
+		nconn = drbd_sync_handshake(mdev,
+				mdev->state.peer, mdev->state.pdsk);
+		put_ldev(mdev);
+
+		if (nconn == C_MASK) {
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			return FALSE;
+		}
+
+		if (drbd_request_state(mdev, NS(conn, nconn)) < SS_SUCCESS) {
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			return FALSE;
+		}
+	}
+
+	if (get_ldev(mdev)) {
+		if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) {
+			mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
+			ldsc = 1;
+		}
+
+		max_seg_s = be32_to_cpu(p->max_segment_size);
+		if (max_seg_s != queue_max_segment_size(mdev->rq_queue))
+			drbd_setup_queue_param(mdev, max_seg_s);
+
+		drbd_setup_order_type(mdev, be32_to_cpu(p->queue_order_type));
+		put_ldev(mdev);
+	}
+
+	if (mdev->state.conn > C_WF_REPORT_PARAMS) {
+		if (be64_to_cpu(p->c_size) !=
+		    drbd_get_capacity(mdev->this_bdev) || ldsc) {
+			/* we have different sizes, probably peer
+			 * needs to know my new size... */
+			drbd_send_sizes(mdev, 0);
+		}
+		if (test_and_clear_bit(RESIZE_PENDING, &mdev->flags) ||
+		    (dd == grew && mdev->state.conn == C_CONNECTED)) {
+			if (mdev->state.pdsk >= D_INCONSISTENT &&
+			    mdev->state.disk >= D_INCONSISTENT)
+				resync_after_online_grow(mdev);
+			else
+				set_bit(RESYNC_AFTER_NEG, &mdev->flags);
+		}
+	}
+
+	return TRUE;
+}
+
+static int receive_uuids(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_uuids *p = (struct p_uuids *)h;
+	u64 *p_uuid;
+	int i;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO);
+
+	for (i = UI_CURRENT; i < UI_EXTENDED_SIZE; i++)
+		p_uuid[i] = be64_to_cpu(p->uuid[i]);
+
+	kfree(mdev->p_uuid);
+	mdev->p_uuid = p_uuid;
+
+	if (mdev->state.conn < C_CONNECTED &&
+	    mdev->state.disk < D_INCONSISTENT &&
+	    mdev->state.role == R_PRIMARY &&
+	    (mdev->ed_uuid & ~((u64)1)) != (p_uuid[UI_CURRENT] & ~((u64)1))) {
+		dev_err(DEV, "Can only connect to data with current UUID=%016llX\n",
+		    (unsigned long long)mdev->ed_uuid);
+		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+		return FALSE;
+	}
+
+	if (get_ldev(mdev)) {
+		int skip_initial_sync =
+			mdev->state.conn == C_CONNECTED &&
+			mdev->agreed_pro_version >= 90 &&
+			mdev->ldev->md.uuid[UI_CURRENT] == UUID_JUST_CREATED &&
+			(p_uuid[UI_FLAGS] & 8);
+		if (skip_initial_sync) {
+			dev_info(DEV, "Accepted new current UUID, preparing to skip initial sync\n");
+			drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write,
+					"clear_n_write from receive_uuids");
+			_drbd_uuid_set(mdev, UI_CURRENT, p_uuid[UI_CURRENT]);
+			_drbd_uuid_set(mdev, UI_BITMAP, 0);
+			_drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
+					CS_VERBOSE, NULL);
+			drbd_md_sync(mdev);
+		}
+		put_ldev(mdev);
+	}
+
+	/* Before we test for the disk state, we should wait until an eventually
+	   ongoing cluster wide state change is finished. That is important if
+	   we are primary and are detaching from our disk. We need to see the
+	   new disk state... */
+	wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags));
+	if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT)
+		drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]);
+
+	return TRUE;
+}
+
+/**
+ * convert_state() - Converts the peer's view of the cluster state to our point of view
+ * @ps:		The state as seen by the peer.
+ */
+static union drbd_state convert_state(union drbd_state ps)
+{
+	union drbd_state ms;
+
+	static enum drbd_conns c_tab[] = {
+		[C_CONNECTED] = C_CONNECTED,
+
+		[C_STARTING_SYNC_S] = C_STARTING_SYNC_T,
+		[C_STARTING_SYNC_T] = C_STARTING_SYNC_S,
+		[C_DISCONNECTING] = C_TEAR_DOWN, /* C_NETWORK_FAILURE, */
+		[C_VERIFY_S]       = C_VERIFY_T,
+		[C_MASK]   = C_MASK,
+	};
+
+	ms.i = ps.i;
+
+	ms.conn = c_tab[ps.conn];
+	ms.peer = ps.role;
+	ms.role = ps.peer;
+	ms.pdsk = ps.disk;
+	ms.disk = ps.pdsk;
+	ms.peer_isp = (ps.aftr_isp | ps.user_isp);
+
+	return ms;
+}
+
+static int receive_req_state(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_req_state *p = (struct p_req_state *)h;
+	union drbd_state mask, val;
+	int rv;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	mask.i = be32_to_cpu(p->mask);
+	val.i = be32_to_cpu(p->val);
+
+	if (test_bit(DISCARD_CONCURRENT, &mdev->flags) &&
+	    test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) {
+		drbd_send_sr_reply(mdev, SS_CONCURRENT_ST_CHG);
+		return TRUE;
+	}
+
+	mask = convert_state(mask);
+	val = convert_state(val);
+
+	rv = drbd_change_state(mdev, CS_VERBOSE, mask, val);
+
+	drbd_send_sr_reply(mdev, rv);
+	drbd_md_sync(mdev);
+
+	return TRUE;
+}
+
+static int receive_state(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_state *p = (struct p_state *)h;
+	enum drbd_conns nconn, oconn;
+	union drbd_state ns, peer_state;
+	enum drbd_disk_state real_peer_disk;
+	int rv;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h)))
+		return FALSE;
+
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	peer_state.i = be32_to_cpu(p->state);
+
+	real_peer_disk = peer_state.disk;
+	if (peer_state.disk == D_NEGOTIATING) {
+		real_peer_disk = mdev->p_uuid[UI_FLAGS] & 4 ? D_INCONSISTENT : D_CONSISTENT;
+		dev_info(DEV, "real peer disk state = %s\n", drbd_disk_str(real_peer_disk));
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+ retry:
+	oconn = nconn = mdev->state.conn;
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (nconn == C_WF_REPORT_PARAMS)
+		nconn = C_CONNECTED;
+
+	if (mdev->p_uuid && peer_state.disk >= D_NEGOTIATING &&
+	    get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		int cr; /* consider resync */
+
+		/* if we established a new connection */
+		cr  = (oconn < C_CONNECTED);
+		/* if we had an established connection
+		 * and one of the nodes newly attaches a disk */
+		cr |= (oconn == C_CONNECTED &&
+		       (peer_state.disk == D_NEGOTIATING ||
+			mdev->state.disk == D_NEGOTIATING));
+		/* if we have both been inconsistent, and the peer has been
+		 * forced to be UpToDate with --overwrite-data */
+		cr |= test_bit(CONSIDER_RESYNC, &mdev->flags);
+		/* if we had been plain connected, and the admin requested to
+		 * start a sync by "invalidate" or "invalidate-remote" */
+		cr |= (oconn == C_CONNECTED &&
+				(peer_state.conn >= C_STARTING_SYNC_S &&
+				 peer_state.conn <= C_WF_BITMAP_T));
+
+		if (cr)
+			nconn = drbd_sync_handshake(mdev, peer_state.role, real_peer_disk);
+
+		put_ldev(mdev);
+		if (nconn == C_MASK) {
+			if (mdev->state.disk == D_NEGOTIATING) {
+				drbd_force_state(mdev, NS(disk, D_DISKLESS));
+				nconn = C_CONNECTED;
+			} else if (peer_state.disk == D_NEGOTIATING) {
+				dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
+				peer_state.disk = D_DISKLESS;
+			} else {
+				D_ASSERT(oconn == C_WF_REPORT_PARAMS);
+				drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+				return FALSE;
+			}
+		}
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	if (mdev->state.conn != oconn)
+		goto retry;
+	clear_bit(CONSIDER_RESYNC, &mdev->flags);
+	ns.i = mdev->state.i;
+	ns.conn = nconn;
+	ns.peer = peer_state.role;
+	ns.pdsk = real_peer_disk;
+	ns.peer_isp = (peer_state.aftr_isp | peer_state.user_isp);
+	if ((nconn == C_CONNECTED || nconn == C_WF_BITMAP_S) && ns.disk == D_NEGOTIATING)
+		ns.disk = mdev->new_state_tmp.disk;
+
+	rv = _drbd_set_state(mdev, ns, CS_VERBOSE | CS_HARD, NULL);
+	ns = mdev->state;
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (rv < SS_SUCCESS) {
+		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+		return FALSE;
+	}
+
+	if (oconn > C_WF_REPORT_PARAMS) {
+		if (nconn > C_CONNECTED && peer_state.conn <= C_CONNECTED &&
+		    peer_state.disk != D_NEGOTIATING ) {
+			/* we want resync, peer has not yet decided to sync... */
+			/* Nowadays only used when forcing a node into primary role and
+			   setting its disk to UpToDate with that */
+			drbd_send_uuids(mdev);
+			drbd_send_state(mdev);
+		}
+	}
+
+	mdev->net_conf->want_lose = 0;
+
+	drbd_md_sync(mdev); /* update connected indicator, la_size, ... */
+
+	return TRUE;
+}
+
+static int receive_sync_uuid(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_rs_uuid *p = (struct p_rs_uuid *)h;
+
+	wait_event(mdev->misc_wait,
+		   mdev->state.conn == C_WF_SYNC_UUID ||
+		   mdev->state.conn < C_CONNECTED ||
+		   mdev->state.disk < D_NEGOTIATING);
+
+	/* D_ASSERT( mdev->state.conn == C_WF_SYNC_UUID ); */
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	/* Here the _drbd_uuid_ functions are right, current should
+	   _not_ be rotated into the history */
+	if (get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		_drbd_uuid_set(mdev, UI_CURRENT, be64_to_cpu(p->uuid));
+		_drbd_uuid_set(mdev, UI_BITMAP, 0UL);
+
+		drbd_start_resync(mdev, C_SYNC_TARGET);
+
+		put_ldev(mdev);
+	} else
+		dev_err(DEV, "Ignoring SyncUUID packet!\n");
+
+	return TRUE;
+}
+
+enum receive_bitmap_ret { OK, DONE, FAILED };
+
+static enum receive_bitmap_ret
+receive_bitmap_plain(struct drbd_conf *mdev, struct p_header *h,
+	unsigned long *buffer, struct bm_xfer_ctx *c)
+{
+	unsigned num_words = min_t(size_t, BM_PACKET_WORDS, c->bm_words - c->word_offset);
+	unsigned want = num_words * sizeof(long);
+
+	if (want != h->length) {
+		dev_err(DEV, "%s:want (%u) != h->length (%u)\n", __func__, want, h->length);
+		return FAILED;
+	}
+	if (want == 0)
+		return DONE;
+	if (drbd_recv(mdev, buffer, want) != want)
+		return FAILED;
+
+	drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer);
+
+	c->word_offset += num_words;
+	c->bit_offset = c->word_offset * BITS_PER_LONG;
+	if (c->bit_offset > c->bm_bits)
+		c->bit_offset = c->bm_bits;
+
+	return OK;
+}
+
+static enum receive_bitmap_ret
+recv_bm_rle_bits(struct drbd_conf *mdev,
+		struct p_compressed_bm *p,
+		struct bm_xfer_ctx *c)
+{
+	struct bitstream bs;
+	u64 look_ahead;
+	u64 rl;
+	u64 tmp;
+	unsigned long s = c->bit_offset;
+	unsigned long e;
+	int len = p->head.length - (sizeof(*p) - sizeof(p->head));
+	int toggle = DCBP_get_start(p);
+	int have;
+	int bits;
+
+	bitstream_init(&bs, p->code, len, DCBP_get_pad_bits(p));
+
+	bits = bitstream_get_bits(&bs, &look_ahead, 64);
+	if (bits < 0)
+		return FAILED;
+
+	for (have = bits; have > 0; s += rl, toggle = !toggle) {
+		bits = vli_decode_bits(&rl, look_ahead);
+		if (bits <= 0)
+			return FAILED;
+
+		if (toggle) {
+			e = s + rl -1;
+			if (e >= c->bm_bits) {
+				dev_err(DEV, "bitmap overflow (e:%lu) while decoding bm RLE packet\n", e);
+				return FAILED;
+			}
+			_drbd_bm_set_bits(mdev, s, e);
+		}
+
+		if (have < bits) {
+			dev_err(DEV, "bitmap decoding error: h:%d b:%d la:0x%08llx l:%u/%u\n",
+				have, bits, look_ahead,
+				(unsigned int)(bs.cur.b - p->code),
+				(unsigned int)bs.buf_len);
+			return FAILED;
+		}
+		look_ahead >>= bits;
+		have -= bits;
+
+		bits = bitstream_get_bits(&bs, &tmp, 64 - have);
+		if (bits < 0)
+			return FAILED;
+		look_ahead |= tmp << have;
+		have += bits;
+	}
+
+	c->bit_offset = s;
+	bm_xfer_ctx_bit_to_word_offset(c);
+
+	return (s == c->bm_bits) ? DONE : OK;
+}
+
+static enum receive_bitmap_ret
+decode_bitmap_c(struct drbd_conf *mdev,
+		struct p_compressed_bm *p,
+		struct bm_xfer_ctx *c)
+{
+	if (DCBP_get_code(p) == RLE_VLI_Bits)
+		return recv_bm_rle_bits(mdev, p, c);
+
+	/* other variants had been implemented for evaluation,
+	 * but have been dropped as this one turned out to be "best"
+	 * during all our tests. */
+
+	dev_err(DEV, "receive_bitmap_c: unknown encoding %u\n", p->encoding);
+	drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+	return FAILED;
+}
+
+void INFO_bm_xfer_stats(struct drbd_conf *mdev,
+		const char *direction, struct bm_xfer_ctx *c)
+{
+	/* what would it take to transfer it "plaintext" */
+	unsigned plain = sizeof(struct p_header) *
+		((c->bm_words+BM_PACKET_WORDS-1)/BM_PACKET_WORDS+1)
+		+ c->bm_words * sizeof(long);
+	unsigned total = c->bytes[0] + c->bytes[1];
+	unsigned r;
+
+	/* total can not be zero. but just in case: */
+	if (total == 0)
+		return;
+
+	/* don't report if not compressed */
+	if (total >= plain)
+		return;
+
+	/* total < plain. check for overflow, still */
+	r = (total > UINT_MAX/1000) ? (total / (plain/1000))
+		                    : (1000 * total / plain);
+
+	if (r > 1000)
+		r = 1000;
+
+	r = 1000 - r;
+	dev_info(DEV, "%s bitmap stats [Bytes(packets)]: plain %u(%u), RLE %u(%u), "
+	     "total %u; compression: %u.%u%%\n",
+			direction,
+			c->bytes[1], c->packets[1],
+			c->bytes[0], c->packets[0],
+			total, r/10, r % 10);
+}
+
+/* Since we are processing the bitfield from lower addresses to higher,
+   it does not matter if the process it in 32 bit chunks or 64 bit
+   chunks as long as it is little endian. (Understand it as byte stream,
+   beginning with the lowest byte...) If we would use big endian
+   we would need to process it from the highest address to the lowest,
+   in order to be agnostic to the 32 vs 64 bits issue.
+
+   returns 0 on failure, 1 if we successfully received it. */
+static int receive_bitmap(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct bm_xfer_ctx c;
+	void *buffer;
+	enum receive_bitmap_ret ret;
+	int ok = FALSE;
+
+	wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt));
+
+	drbd_bm_lock(mdev, "receive bitmap");
+
+	/* maybe we should use some per thread scratch page,
+	 * and allocate that during initial device creation? */
+	buffer	 = (unsigned long *) __get_free_page(GFP_NOIO);
+	if (!buffer) {
+		dev_err(DEV, "failed to allocate one page buffer in %s\n", __func__);
+		goto out;
+	}
+
+	c = (struct bm_xfer_ctx) {
+		.bm_bits = drbd_bm_bits(mdev),
+		.bm_words = drbd_bm_words(mdev),
+	};
+
+	do {
+		if (h->command == P_BITMAP) {
+			ret = receive_bitmap_plain(mdev, h, buffer, &c);
+		} else if (h->command == P_COMPRESSED_BITMAP) {
+			/* MAYBE: sanity check that we speak proto >= 90,
+			 * and the feature is enabled! */
+			struct p_compressed_bm *p;
+
+			if (h->length > BM_PACKET_PAYLOAD_BYTES) {
+				dev_err(DEV, "ReportCBitmap packet too large\n");
+				goto out;
+			}
+			/* use the page buff */
+			p = buffer;
+			memcpy(p, h, sizeof(*h));
+			if (drbd_recv(mdev, p->head.payload, h->length) != h->length)
+				goto out;
+			if (p->head.length <= (sizeof(*p) - sizeof(p->head))) {
+				dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", p->head.length);
+				return FAILED;
+			}
+			ret = decode_bitmap_c(mdev, p, &c);
+		} else {
+			dev_warn(DEV, "receive_bitmap: h->command neither ReportBitMap nor ReportCBitMap (is 0x%x)", h->command);
+			goto out;
+		}
+
+		c.packets[h->command == P_BITMAP]++;
+		c.bytes[h->command == P_BITMAP] += sizeof(struct p_header) + h->length;
+
+		if (ret != OK)
+			break;
+
+		if (!drbd_recv_header(mdev, h))
+			goto out;
+	} while (ret == OK);
+	if (ret == FAILED)
+		goto out;
+
+	INFO_bm_xfer_stats(mdev, "receive", &c);
+
+	if (mdev->state.conn == C_WF_BITMAP_T) {
+		ok = !drbd_send_bitmap(mdev);
+		if (!ok)
+			goto out;
+		/* Omit CS_ORDERED with this state transition to avoid deadlocks. */
+		ok = _drbd_request_state(mdev, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE);
+		D_ASSERT(ok == SS_SUCCESS);
+	} else if (mdev->state.conn != C_WF_BITMAP_S) {
+		/* admin may have requested C_DISCONNECTING,
+		 * other threads may have noticed network errors */
+		dev_info(DEV, "unexpected cstate (%s) in receive_bitmap\n",
+		    drbd_conn_str(mdev->state.conn));
+	}
+
+	ok = TRUE;
+ out:
+	drbd_bm_unlock(mdev);
+	if (ok && mdev->state.conn == C_WF_BITMAP_S)
+		drbd_start_resync(mdev, C_SYNC_SOURCE);
+	free_page((unsigned long) buffer);
+	return ok;
+}
+
+static int receive_skip(struct drbd_conf *mdev, struct p_header *h)
+{
+	/* TODO zero copy sink :) */
+	static char sink[128];
+	int size, want, r;
+
+	dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n",
+	     h->command, h->length);
+
+	size = h->length;
+	while (size > 0) {
+		want = min_t(int, size, sizeof(sink));
+		r = drbd_recv(mdev, sink, want);
+		ERR_IF(r <= 0) break;
+		size -= r;
+	}
+	return size == 0;
+}
+
+static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h)
+{
+	if (mdev->state.disk >= D_INCONSISTENT)
+		drbd_kick_lo(mdev);
+
+	/* Make sure we've acked all the TCP data associated
+	 * with the data requests being unplugged */
+	drbd_tcp_quickack(mdev->data.socket);
+
+	return TRUE;
+}
+
+typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, struct p_header *);
+
+static drbd_cmd_handler_f drbd_default_handler[] = {
+	[P_DATA]	    = receive_Data,
+	[P_DATA_REPLY]	    = receive_DataReply,
+	[P_RS_DATA_REPLY]   = receive_RSDataReply,
+	[P_BARRIER]	    = receive_Barrier,
+	[P_BITMAP]	    = receive_bitmap,
+	[P_COMPRESSED_BITMAP]    = receive_bitmap,
+	[P_UNPLUG_REMOTE]   = receive_UnplugRemote,
+	[P_DATA_REQUEST]    = receive_DataRequest,
+	[P_RS_DATA_REQUEST] = receive_DataRequest,
+	[P_SYNC_PARAM]	    = receive_SyncParam,
+	[P_SYNC_PARAM89]	   = receive_SyncParam,
+	[P_PROTOCOL]        = receive_protocol,
+	[P_UUIDS]	    = receive_uuids,
+	[P_SIZES]	    = receive_sizes,
+	[P_STATE]	    = receive_state,
+	[P_STATE_CHG_REQ]   = receive_req_state,
+	[P_SYNC_UUID]       = receive_sync_uuid,
+	[P_OV_REQUEST]      = receive_DataRequest,
+	[P_OV_REPLY]        = receive_DataRequest,
+	[P_CSUM_RS_REQUEST]    = receive_DataRequest,
+	/* anything missing from this table is in
+	 * the asender_tbl, see get_asender_cmd */
+	[P_MAX_CMD]	    = NULL,
+};
+
+static drbd_cmd_handler_f *drbd_cmd_handler = drbd_default_handler;
+static drbd_cmd_handler_f *drbd_opt_cmd_handler;
+
+static void drbdd(struct drbd_conf *mdev)
+{
+	drbd_cmd_handler_f handler;
+	struct p_header *header = &mdev->data.rbuf.header;
+
+	while (get_t_state(&mdev->receiver) == Running) {
+		drbd_thread_current_set_cpu(mdev);
+		if (!drbd_recv_header(mdev, header)) {
+			drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+			break;
+		}
+
+		if (header->command < P_MAX_CMD)
+			handler = drbd_cmd_handler[header->command];
+		else if (P_MAY_IGNORE < header->command
+		     && header->command < P_MAX_OPT_CMD)
+			handler = drbd_opt_cmd_handler[header->command-P_MAY_IGNORE];
+		else if (header->command > P_MAX_OPT_CMD)
+			handler = receive_skip;
+		else
+			handler = NULL;
+
+		if (unlikely(!handler)) {
+			dev_err(DEV, "unknown packet type %d, l: %d!\n",
+			    header->command, header->length);
+			drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+			break;
+		}
+		if (unlikely(!handler(mdev, header))) {
+			dev_err(DEV, "error receiving %s, l: %d!\n",
+			    cmdname(header->command), header->length);
+			drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
+			break;
+		}
+	}
+}
+
+static void drbd_fail_pending_reads(struct drbd_conf *mdev)
+{
+	struct hlist_head *slot;
+	struct hlist_node *pos;
+	struct hlist_node *tmp;
+	struct drbd_request *req;
+	int i;
+
+	/*
+	 * Application READ requests
+	 */
+	spin_lock_irq(&mdev->req_lock);
+	for (i = 0; i < APP_R_HSIZE; i++) {
+		slot = mdev->app_reads_hash+i;
+		hlist_for_each_entry_safe(req, pos, tmp, slot, colision) {
+			/* it may (but should not any longer!)
+			 * be on the work queue; if that assert triggers,
+			 * we need to also grab the
+			 * spin_lock_irq(&mdev->data.work.q_lock);
+			 * and list_del_init here. */
+			D_ASSERT(list_empty(&req->w.list));
+			/* It would be nice to complete outside of spinlock.
+			 * But this is easier for now. */
+			_req_mod(req, connection_lost_while_pending);
+		}
+	}
+	for (i = 0; i < APP_R_HSIZE; i++)
+		if (!hlist_empty(mdev->app_reads_hash+i))
+			dev_warn(DEV, "ASSERT FAILED: app_reads_hash[%d].first: "
+				"%p, should be NULL\n", i, mdev->app_reads_hash[i].first);
+
+	memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *));
+	spin_unlock_irq(&mdev->req_lock);
+}
+
+void drbd_flush_workqueue(struct drbd_conf *mdev)
+{
+	struct drbd_wq_barrier barr;
+
+	barr.w.cb = w_prev_work_done;
+	init_completion(&barr.done);
+	drbd_queue_work(&mdev->data.work, &barr.w);
+	wait_for_completion(&barr.done);
+}
+
+static void drbd_disconnect(struct drbd_conf *mdev)
+{
+	enum drbd_fencing_p fp;
+	union drbd_state os, ns;
+	int rv = SS_UNKNOWN_ERROR;
+	unsigned int i;
+
+	if (mdev->state.conn == C_STANDALONE)
+		return;
+	if (mdev->state.conn >= C_WF_CONNECTION)
+		dev_err(DEV, "ASSERT FAILED cstate = %s, expected < WFConnection\n",
+				drbd_conn_str(mdev->state.conn));
+
+	/* asender does not clean up anything. it must not interfere, either */
+	drbd_thread_stop(&mdev->asender);
+
+	mutex_lock(&mdev->data.mutex);
+	drbd_free_sock(mdev);
+	mutex_unlock(&mdev->data.mutex);
+
+	spin_lock_irq(&mdev->req_lock);
+	_drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
+	_drbd_wait_ee_list_empty(mdev, &mdev->sync_ee);
+	_drbd_wait_ee_list_empty(mdev, &mdev->read_ee);
+	spin_unlock_irq(&mdev->req_lock);
+
+	/* We do not have data structures that would allow us to
+	 * get the rs_pending_cnt down to 0 again.
+	 *  * On C_SYNC_TARGET we do not have any data structures describing
+	 *    the pending RSDataRequest's we have sent.
+	 *  * On C_SYNC_SOURCE there is no data structure that tracks
+	 *    the P_RS_DATA_REPLY blocks that we sent to the SyncTarget.
+	 *  And no, it is not the sum of the reference counts in the
+	 *  resync_LRU. The resync_LRU tracks the whole operation including
+	 *  the disk-IO, while the rs_pending_cnt only tracks the blocks
+	 *  on the fly. */
+	drbd_rs_cancel_all(mdev);
+	mdev->rs_total = 0;
+	mdev->rs_failed = 0;
+	atomic_set(&mdev->rs_pending_cnt, 0);
+	wake_up(&mdev->misc_wait);
+
+	/* make sure syncer is stopped and w_resume_next_sg queued */
+	del_timer_sync(&mdev->resync_timer);
+	set_bit(STOP_SYNC_TIMER, &mdev->flags);
+	resync_timer_fn((unsigned long)mdev);
+
+	/* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier,
+	 * w_make_resync_request etc. which may still be on the worker queue
+	 * to be "canceled" */
+	drbd_flush_workqueue(mdev);
+
+	/* This also does reclaim_net_ee().  If we do this too early, we might
+	 * miss some resync ee and pages.*/
+	drbd_process_done_ee(mdev);
+
+	kfree(mdev->p_uuid);
+	mdev->p_uuid = NULL;
+
+	if (!mdev->state.susp)
+		tl_clear(mdev);
+
+	drbd_fail_pending_reads(mdev);
+
+	dev_info(DEV, "Connection closed\n");
+
+	drbd_md_sync(mdev);
+
+	fp = FP_DONT_CARE;
+	if (get_ldev(mdev)) {
+		fp = mdev->ldev->dc.fencing;
+		put_ldev(mdev);
+	}
+
+	if (mdev->state.role == R_PRIMARY) {
+		if (fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN) {
+			enum drbd_disk_state nps = drbd_try_outdate_peer(mdev);
+			drbd_request_state(mdev, NS(pdsk, nps));
+		}
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	os = mdev->state;
+	if (os.conn >= C_UNCONNECTED) {
+		/* Do not restart in case we are C_DISCONNECTING */
+		ns = os;
+		ns.conn = C_UNCONNECTED;
+		rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
+	}
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (os.conn == C_DISCONNECTING) {
+		struct hlist_head *h;
+		wait_event(mdev->misc_wait, atomic_read(&mdev->net_cnt) == 0);
+
+		/* we must not free the tl_hash
+		 * while application io is still on the fly */
+		wait_event(mdev->misc_wait, atomic_read(&mdev->ap_bio_cnt) == 0);
+
+		spin_lock_irq(&mdev->req_lock);
+		/* paranoia code */
+		for (h = mdev->ee_hash; h < mdev->ee_hash + mdev->ee_hash_s; h++)
+			if (h->first)
+				dev_err(DEV, "ASSERT FAILED ee_hash[%u].first == %p, expected NULL\n",
+						(int)(h - mdev->ee_hash), h->first);
+		kfree(mdev->ee_hash);
+		mdev->ee_hash = NULL;
+		mdev->ee_hash_s = 0;
+
+		/* paranoia code */
+		for (h = mdev->tl_hash; h < mdev->tl_hash + mdev->tl_hash_s; h++)
+			if (h->first)
+				dev_err(DEV, "ASSERT FAILED tl_hash[%u] == %p, expected NULL\n",
+						(int)(h - mdev->tl_hash), h->first);
+		kfree(mdev->tl_hash);
+		mdev->tl_hash = NULL;
+		mdev->tl_hash_s = 0;
+		spin_unlock_irq(&mdev->req_lock);
+
+		crypto_free_hash(mdev->cram_hmac_tfm);
+		mdev->cram_hmac_tfm = NULL;
+
+		kfree(mdev->net_conf);
+		mdev->net_conf = NULL;
+		drbd_request_state(mdev, NS(conn, C_STANDALONE));
+	}
+
+	/* tcp_close and release of sendpage pages can be deferred.  I don't
+	 * want to use SO_LINGER, because apparently it can be deferred for
+	 * more than 20 seconds (longest time I checked).
+	 *
+	 * Actually we don't care for exactly when the network stack does its
+	 * put_page(), but release our reference on these pages right here.
+	 */
+	i = drbd_release_ee(mdev, &mdev->net_ee);
+	if (i)
+		dev_info(DEV, "net_ee not empty, killed %u entries\n", i);
+	i = atomic_read(&mdev->pp_in_use);
+	if (i)
+		dev_info(DEV, "pp_in_use = %u, expected 0\n", i);
+
+	D_ASSERT(list_empty(&mdev->read_ee));
+	D_ASSERT(list_empty(&mdev->active_ee));
+	D_ASSERT(list_empty(&mdev->sync_ee));
+	D_ASSERT(list_empty(&mdev->done_ee));
+
+	/* ok, no more ee's on the fly, it is safe to reset the epoch_size */
+	atomic_set(&mdev->current_epoch->epoch_size, 0);
+	D_ASSERT(list_empty(&mdev->current_epoch->list));
+}
+
+/*
+ * We support PRO_VERSION_MIN to PRO_VERSION_MAX. The protocol version
+ * we can agree on is stored in agreed_pro_version.
+ *
+ * feature flags and the reserved array should be enough room for future
+ * enhancements of the handshake protocol, and possible plugins...
+ *
+ * for now, they are expected to be zero, but ignored.
+ */
+static int drbd_send_handshake(struct drbd_conf *mdev)
+{
+	/* ASSERT current == mdev->receiver ... */
+	struct p_handshake *p = &mdev->data.sbuf.handshake;
+	int ok;
+
+	if (mutex_lock_interruptible(&mdev->data.mutex)) {
+		dev_err(DEV, "interrupted during initial handshake\n");
+		return 0; /* interrupted. not ok. */
+	}
+
+	if (mdev->data.socket == NULL) {
+		mutex_unlock(&mdev->data.mutex);
+		return 0;
+	}
+
+	memset(p, 0, sizeof(*p));
+	p->protocol_min = cpu_to_be32(PRO_VERSION_MIN);
+	p->protocol_max = cpu_to_be32(PRO_VERSION_MAX);
+	ok = _drbd_send_cmd( mdev, mdev->data.socket, P_HAND_SHAKE,
+			     (struct p_header *)p, sizeof(*p), 0 );
+	mutex_unlock(&mdev->data.mutex);
+	return ok;
+}
+
+/*
+ * return values:
+ *   1 yes, we have a valid connection
+ *   0 oops, did not work out, please try again
+ *  -1 peer talks different language,
+ *     no point in trying again, please go standalone.
+ */
+static int drbd_do_handshake(struct drbd_conf *mdev)
+{
+	/* ASSERT current == mdev->receiver ... */
+	struct p_handshake *p = &mdev->data.rbuf.handshake;
+	const int expect = sizeof(struct p_handshake)
+			  -sizeof(struct p_header);
+	int rv;
+
+	rv = drbd_send_handshake(mdev);
+	if (!rv)
+		return 0;
+
+	rv = drbd_recv_header(mdev, &p->head);
+	if (!rv)
+		return 0;
+
+	if (p->head.command != P_HAND_SHAKE) {
+		dev_err(DEV, "expected HandShake packet, received: %s (0x%04x)\n",
+		     cmdname(p->head.command), p->head.command);
+		return -1;
+	}
+
+	if (p->head.length != expect) {
+		dev_err(DEV, "expected HandShake length: %u, received: %u\n",
+		     expect, p->head.length);
+		return -1;
+	}
+
+	rv = drbd_recv(mdev, &p->head.payload, expect);
+
+	if (rv != expect) {
+		dev_err(DEV, "short read receiving handshake packet: l=%u\n", rv);
+		return 0;
+	}
+
+	p->protocol_min = be32_to_cpu(p->protocol_min);
+	p->protocol_max = be32_to_cpu(p->protocol_max);
+	if (p->protocol_max == 0)
+		p->protocol_max = p->protocol_min;
+
+	if (PRO_VERSION_MAX < p->protocol_min ||
+	    PRO_VERSION_MIN > p->protocol_max)
+		goto incompat;
+
+	mdev->agreed_pro_version = min_t(int, PRO_VERSION_MAX, p->protocol_max);
+
+	dev_info(DEV, "Handshake successful: "
+	     "Agreed network protocol version %d\n", mdev->agreed_pro_version);
+
+	return 1;
+
+ incompat:
+	dev_err(DEV, "incompatible DRBD dialects: "
+	    "I support %d-%d, peer supports %d-%d\n",
+	    PRO_VERSION_MIN, PRO_VERSION_MAX,
+	    p->protocol_min, p->protocol_max);
+	return -1;
+}
+
+#if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE)
+static int drbd_do_auth(struct drbd_conf *mdev)
+{
+	dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
+	dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
+	return -1;
+}
+#else
+#define CHALLENGE_LEN 64
+
+/* Return value:
+	1 - auth succeeded,
+	0 - failed, try again (network error),
+	-1 - auth failed, don't try again.
+*/
+
+static int drbd_do_auth(struct drbd_conf *mdev)
+{
+	char my_challenge[CHALLENGE_LEN];  /* 64 Bytes... */
+	struct scatterlist sg;
+	char *response = NULL;
+	char *right_response = NULL;
+	char *peers_ch = NULL;
+	struct p_header p;
+	unsigned int key_len = strlen(mdev->net_conf->shared_secret);
+	unsigned int resp_size;
+	struct hash_desc desc;
+	int rv;
+
+	desc.tfm = mdev->cram_hmac_tfm;
+	desc.flags = 0;
+
+	rv = crypto_hash_setkey(mdev->cram_hmac_tfm,
+				(u8 *)mdev->net_conf->shared_secret, key_len);
+	if (rv) {
+		dev_err(DEV, "crypto_hash_setkey() failed with %d\n", rv);
+		rv = -1;
+		goto fail;
+	}
+
+	get_random_bytes(my_challenge, CHALLENGE_LEN);
+
+	rv = drbd_send_cmd2(mdev, P_AUTH_CHALLENGE, my_challenge, CHALLENGE_LEN);
+	if (!rv)
+		goto fail;
+
+	rv = drbd_recv_header(mdev, &p);
+	if (!rv)
+		goto fail;
+
+	if (p.command != P_AUTH_CHALLENGE) {
+		dev_err(DEV, "expected AuthChallenge packet, received: %s (0x%04x)\n",
+		    cmdname(p.command), p.command);
+		rv = 0;
+		goto fail;
+	}
+
+	if (p.length > CHALLENGE_LEN*2) {
+		dev_err(DEV, "expected AuthChallenge payload too big.\n");
+		rv = -1;
+		goto fail;
+	}
+
+	peers_ch = kmalloc(p.length, GFP_NOIO);
+	if (peers_ch == NULL) {
+		dev_err(DEV, "kmalloc of peers_ch failed\n");
+		rv = -1;
+		goto fail;
+	}
+
+	rv = drbd_recv(mdev, peers_ch, p.length);
+
+	if (rv != p.length) {
+		dev_err(DEV, "short read AuthChallenge: l=%u\n", rv);
+		rv = 0;
+		goto fail;
+	}
+
+	resp_size = crypto_hash_digestsize(mdev->cram_hmac_tfm);
+	response = kmalloc(resp_size, GFP_NOIO);
+	if (response == NULL) {
+		dev_err(DEV, "kmalloc of response failed\n");
+		rv = -1;
+		goto fail;
+	}
+
+	sg_init_table(&sg, 1);
+	sg_set_buf(&sg, peers_ch, p.length);
+
+	rv = crypto_hash_digest(&desc, &sg, sg.length, response);
+	if (rv) {
+		dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
+		rv = -1;
+		goto fail;
+	}
+
+	rv = drbd_send_cmd2(mdev, P_AUTH_RESPONSE, response, resp_size);
+	if (!rv)
+		goto fail;
+
+	rv = drbd_recv_header(mdev, &p);
+	if (!rv)
+		goto fail;
+
+	if (p.command != P_AUTH_RESPONSE) {
+		dev_err(DEV, "expected AuthResponse packet, received: %s (0x%04x)\n",
+		    cmdname(p.command), p.command);
+		rv = 0;
+		goto fail;
+	}
+
+	if (p.length != resp_size) {
+		dev_err(DEV, "expected AuthResponse payload of wrong size\n");
+		rv = 0;
+		goto fail;
+	}
+
+	rv = drbd_recv(mdev, response , resp_size);
+
+	if (rv != resp_size) {
+		dev_err(DEV, "short read receiving AuthResponse: l=%u\n", rv);
+		rv = 0;
+		goto fail;
+	}
+
+	right_response = kmalloc(resp_size, GFP_NOIO);
+	if (right_response == NULL) {
+		dev_err(DEV, "kmalloc of right_response failed\n");
+		rv = -1;
+		goto fail;
+	}
+
+	sg_set_buf(&sg, my_challenge, CHALLENGE_LEN);
+
+	rv = crypto_hash_digest(&desc, &sg, sg.length, right_response);
+	if (rv) {
+		dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
+		rv = -1;
+		goto fail;
+	}
+
+	rv = !memcmp(response, right_response, resp_size);
+
+	if (rv)
+		dev_info(DEV, "Peer authenticated using %d bytes of '%s' HMAC\n",
+		     resp_size, mdev->net_conf->cram_hmac_alg);
+	else
+		rv = -1;
+
+ fail:
+	kfree(peers_ch);
+	kfree(response);
+	kfree(right_response);
+
+	return rv;
+}
+#endif
+
+int drbdd_init(struct drbd_thread *thi)
+{
+	struct drbd_conf *mdev = thi->mdev;
+	unsigned int minor = mdev_to_minor(mdev);
+	int h;
+
+	sprintf(current->comm, "drbd%d_receiver", minor);
+
+	dev_info(DEV, "receiver (re)started\n");
+
+	do {
+		h = drbd_connect(mdev);
+		if (h == 0) {
+			drbd_disconnect(mdev);
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ);
+		}
+		if (h == -1) {
+			dev_warn(DEV, "Discarding network configuration.\n");
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+		}
+	} while (h == 0);
+
+	if (h > 0) {
+		if (get_net_conf(mdev)) {
+			drbdd(mdev);
+			put_net_conf(mdev);
+		}
+	}
+
+	drbd_disconnect(mdev);
+
+	dev_info(DEV, "receiver terminated\n");
+	return 0;
+}
+
+/* ********* acknowledge sender ******** */
+
+static int got_RqSReply(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_req_state_reply *p = (struct p_req_state_reply *)h;
+
+	int retcode = be32_to_cpu(p->retcode);
+
+	if (retcode >= SS_SUCCESS) {
+		set_bit(CL_ST_CHG_SUCCESS, &mdev->flags);
+	} else {
+		set_bit(CL_ST_CHG_FAIL, &mdev->flags);
+		dev_err(DEV, "Requested state change failed by peer: %s (%d)\n",
+		    drbd_set_st_err_str(retcode), retcode);
+	}
+	wake_up(&mdev->state_wait);
+
+	return TRUE;
+}
+
+static int got_Ping(struct drbd_conf *mdev, struct p_header *h)
+{
+	return drbd_send_ping_ack(mdev);
+
+}
+
+static int got_PingAck(struct drbd_conf *mdev, struct p_header *h)
+{
+	/* restore idle timeout */
+	mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+
+	return TRUE;
+}
+
+static int got_IsInSync(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_block_ack *p = (struct p_block_ack *)h;
+	sector_t sector = be64_to_cpu(p->sector);
+	int blksize = be32_to_cpu(p->blksize);
+
+	D_ASSERT(mdev->agreed_pro_version >= 89);
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+
+	drbd_rs_complete_io(mdev, sector);
+	drbd_set_in_sync(mdev, sector, blksize);
+	/* rs_same_csums is supposed to count in units of BM_BLOCK_SIZE */
+	mdev->rs_same_csum += (blksize >> BM_BLOCK_SHIFT);
+	dec_rs_pending(mdev);
+
+	return TRUE;
+}
+
+/* when we receive the ACK for a write request,
+ * verify that we actually know about it */
+static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev,
+	u64 id, sector_t sector)
+{
+	struct hlist_head *slot = tl_hash_slot(mdev, sector);
+	struct hlist_node *n;
+	struct drbd_request *req;
+
+	hlist_for_each_entry(req, n, slot, colision) {
+		if ((unsigned long)req == (unsigned long)id) {
+			if (req->sector != sector) {
+				dev_err(DEV, "_ack_id_to_req: found req %p but it has "
+				    "wrong sector (%llus versus %llus)\n", req,
+				    (unsigned long long)req->sector,
+				    (unsigned long long)sector);
+				break;
+			}
+			return req;
+		}
+	}
+	dev_err(DEV, "_ack_id_to_req: failed to find req %p, sector %llus in list\n",
+		(void *)(unsigned long)id, (unsigned long long)sector);
+	return NULL;
+}
+
+typedef struct drbd_request *(req_validator_fn)
+	(struct drbd_conf *mdev, u64 id, sector_t sector);
+
+static int validate_req_change_req_state(struct drbd_conf *mdev,
+	u64 id, sector_t sector, req_validator_fn validator,
+	const char *func, enum drbd_req_event what)
+{
+	struct drbd_request *req;
+	struct bio_and_error m;
+
+	spin_lock_irq(&mdev->req_lock);
+	req = validator(mdev, id, sector);
+	if (unlikely(!req)) {
+		spin_unlock_irq(&mdev->req_lock);
+		dev_err(DEV, "%s: got a corrupt block_id/sector pair\n", func);
+		return FALSE;
+	}
+	__req_mod(req, what, &m);
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (m.bio)
+		complete_master_bio(mdev, &m);
+	return TRUE;
+}
+
+static int got_BlockAck(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_block_ack *p = (struct p_block_ack *)h;
+	sector_t sector = be64_to_cpu(p->sector);
+	int blksize = be32_to_cpu(p->blksize);
+	enum drbd_req_event what;
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+
+	if (is_syncer_block_id(p->block_id)) {
+		drbd_set_in_sync(mdev, sector, blksize);
+		dec_rs_pending(mdev);
+		return TRUE;
+	}
+	switch (be16_to_cpu(h->command)) {
+	case P_RS_WRITE_ACK:
+		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		what = write_acked_by_peer_and_sis;
+		break;
+	case P_WRITE_ACK:
+		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		what = write_acked_by_peer;
+		break;
+	case P_RECV_ACK:
+		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_B);
+		what = recv_acked_by_peer;
+		break;
+	case P_DISCARD_ACK:
+		D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+		what = conflict_discarded_by_peer;
+		break;
+	default:
+		D_ASSERT(0);
+		return FALSE;
+	}
+
+	return validate_req_change_req_state(mdev, p->block_id, sector,
+		_ack_id_to_req, __func__ , what);
+}
+
+static int got_NegAck(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_block_ack *p = (struct p_block_ack *)h;
+	sector_t sector = be64_to_cpu(p->sector);
+
+	if (__ratelimit(&drbd_ratelimit_state))
+		dev_warn(DEV, "Got NegAck packet. Peer is in troubles?\n");
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+
+	if (is_syncer_block_id(p->block_id)) {
+		int size = be32_to_cpu(p->blksize);
+		dec_rs_pending(mdev);
+		drbd_rs_failed_io(mdev, sector, size);
+		return TRUE;
+	}
+	return validate_req_change_req_state(mdev, p->block_id, sector,
+		_ack_id_to_req, __func__ , neg_acked);
+}
+
+static int got_NegDReply(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_block_ack *p = (struct p_block_ack *)h;
+	sector_t sector = be64_to_cpu(p->sector);
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+	dev_err(DEV, "Got NegDReply; Sector %llus, len %u; Fail original request.\n",
+	    (unsigned long long)sector, be32_to_cpu(p->blksize));
+
+	return validate_req_change_req_state(mdev, p->block_id, sector,
+		_ar_id_to_req, __func__ , neg_acked);
+}
+
+static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header *h)
+{
+	sector_t sector;
+	int size;
+	struct p_block_ack *p = (struct p_block_ack *)h;
+
+	sector = be64_to_cpu(p->sector);
+	size = be32_to_cpu(p->blksize);
+	D_ASSERT(p->block_id == ID_SYNCER);
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+
+	dec_rs_pending(mdev);
+
+	if (get_ldev_if_state(mdev, D_FAILED)) {
+		drbd_rs_complete_io(mdev, sector);
+		drbd_rs_failed_io(mdev, sector, size);
+		put_ldev(mdev);
+	}
+
+	return TRUE;
+}
+
+static int got_BarrierAck(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_barrier_ack *p = (struct p_barrier_ack *)h;
+
+	tl_release(mdev, p->barrier, be32_to_cpu(p->set_size));
+
+	return TRUE;
+}
+
+static int got_OVResult(struct drbd_conf *mdev, struct p_header *h)
+{
+	struct p_block_ack *p = (struct p_block_ack *)h;
+	struct drbd_work *w;
+	sector_t sector;
+	int size;
+
+	sector = be64_to_cpu(p->sector);
+	size = be32_to_cpu(p->blksize);
+
+	update_peer_seq(mdev, be32_to_cpu(p->seq_num));
+
+	if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC)
+		drbd_ov_oos_found(mdev, sector, size);
+	else
+		ov_oos_print(mdev);
+
+	drbd_rs_complete_io(mdev, sector);
+	dec_rs_pending(mdev);
+
+	if (--mdev->ov_left == 0) {
+		w = kmalloc(sizeof(*w), GFP_NOIO);
+		if (w) {
+			w->cb = w_ov_finished;
+			drbd_queue_work_front(&mdev->data.work, w);
+		} else {
+			dev_err(DEV, "kmalloc(w) failed.");
+			ov_oos_print(mdev);
+			drbd_resync_finished(mdev);
+		}
+	}
+	return TRUE;
+}
+
+struct asender_cmd {
+	size_t pkt_size;
+	int (*process)(struct drbd_conf *mdev, struct p_header *h);
+};
+
+static struct asender_cmd *get_asender_cmd(int cmd)
+{
+	static struct asender_cmd asender_tbl[] = {
+		/* anything missing from this table is in
+		 * the drbd_cmd_handler (drbd_default_handler) table,
+		 * see the beginning of drbdd() */
+	[P_PING]	    = { sizeof(struct p_header), got_Ping },
+	[P_PING_ACK]	    = { sizeof(struct p_header), got_PingAck },
+	[P_RECV_ACK]	    = { sizeof(struct p_block_ack), got_BlockAck },
+	[P_WRITE_ACK]	    = { sizeof(struct p_block_ack), got_BlockAck },
+	[P_RS_WRITE_ACK]    = { sizeof(struct p_block_ack), got_BlockAck },
+	[P_DISCARD_ACK]	    = { sizeof(struct p_block_ack), got_BlockAck },
+	[P_NEG_ACK]	    = { sizeof(struct p_block_ack), got_NegAck },
+	[P_NEG_DREPLY]	    = { sizeof(struct p_block_ack), got_NegDReply },
+	[P_NEG_RS_DREPLY]   = { sizeof(struct p_block_ack), got_NegRSDReply},
+	[P_OV_RESULT]	    = { sizeof(struct p_block_ack), got_OVResult },
+	[P_BARRIER_ACK]	    = { sizeof(struct p_barrier_ack), got_BarrierAck },
+	[P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply },
+	[P_RS_IS_IN_SYNC]   = { sizeof(struct p_block_ack), got_IsInSync },
+	[P_MAX_CMD]	    = { 0, NULL },
+	};
+	if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL)
+		return NULL;
+	return &asender_tbl[cmd];
+}
+
+int drbd_asender(struct drbd_thread *thi)
+{
+	struct drbd_conf *mdev = thi->mdev;
+	struct p_header *h = &mdev->meta.rbuf.header;
+	struct asender_cmd *cmd = NULL;
+
+	int rv, len;
+	void *buf    = h;
+	int received = 0;
+	int expect   = sizeof(struct p_header);
+	int empty;
+
+	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
+
+	current->policy = SCHED_RR;  /* Make this a realtime task! */
+	current->rt_priority = 2;    /* more important than all other tasks */
+
+	while (get_t_state(thi) == Running) {
+		drbd_thread_current_set_cpu(mdev);
+		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
+			ERR_IF(!drbd_send_ping(mdev)) goto reconnect;
+			mdev->meta.socket->sk->sk_rcvtimeo =
+				mdev->net_conf->ping_timeo*HZ/10;
+		}
+
+		/* conditionally cork;
+		 * it may hurt latency if we cork without much to send */
+		if (!mdev->net_conf->no_cork &&
+			3 < atomic_read(&mdev->unacked_cnt))
+			drbd_tcp_cork(mdev->meta.socket);
+		while (1) {
+			clear_bit(SIGNAL_ASENDER, &mdev->flags);
+			flush_signals(current);
+			if (!drbd_process_done_ee(mdev)) {
+				dev_err(DEV, "process_done_ee() = NOT_OK\n");
+				goto reconnect;
+			}
+			/* to avoid race with newly queued ACKs */
+			set_bit(SIGNAL_ASENDER, &mdev->flags);
+			spin_lock_irq(&mdev->req_lock);
+			empty = list_empty(&mdev->done_ee);
+			spin_unlock_irq(&mdev->req_lock);
+			/* new ack may have been queued right here,
+			 * but then there is also a signal pending,
+			 * and we start over... */
+			if (empty)
+				break;
+		}
+		/* but unconditionally uncork unless disabled */
+		if (!mdev->net_conf->no_cork)
+			drbd_tcp_uncork(mdev->meta.socket);
+
+		/* short circuit, recv_msg would return EINTR anyways. */
+		if (signal_pending(current))
+			continue;
+
+		rv = drbd_recv_short(mdev, mdev->meta.socket,
+				     buf, expect-received, 0);
+		clear_bit(SIGNAL_ASENDER, &mdev->flags);
+
+		flush_signals(current);
+
+		/* Note:
+		 * -EINTR	 (on meta) we got a signal
+		 * -EAGAIN	 (on meta) rcvtimeo expired
+		 * -ECONNRESET	 other side closed the connection
+		 * -ERESTARTSYS  (on data) we got a signal
+		 * rv <  0	 other than above: unexpected error!
+		 * rv == expected: full header or command
+		 * rv <  expected: "woken" by signal during receive
+		 * rv == 0	 : "connection shut down by peer"
+		 */
+		if (likely(rv > 0)) {
+			received += rv;
+			buf	 += rv;
+		} else if (rv == 0) {
+			dev_err(DEV, "meta connection shut down by peer.\n");
+			goto reconnect;
+		} else if (rv == -EAGAIN) {
+			if (mdev->meta.socket->sk->sk_rcvtimeo ==
+			    mdev->net_conf->ping_timeo*HZ/10) {
+				dev_err(DEV, "PingAck did not arrive in time.\n");
+				goto reconnect;
+			}
+			set_bit(SEND_PING, &mdev->flags);
+			continue;
+		} else if (rv == -EINTR) {
+			continue;
+		} else {
+			dev_err(DEV, "sock_recvmsg returned %d\n", rv);
+			goto reconnect;
+		}
+
+		if (received == expect && cmd == NULL) {
+			if (unlikely(h->magic != BE_DRBD_MAGIC)) {
+				dev_err(DEV, "magic?? on meta m: 0x%lx c: %d l: %d\n",
+				    (long)be32_to_cpu(h->magic),
+				    h->command, h->length);
+				goto reconnect;
+			}
+			cmd = get_asender_cmd(be16_to_cpu(h->command));
+			len = be16_to_cpu(h->length);
+			if (unlikely(cmd == NULL)) {
+				dev_err(DEV, "unknown command?? on meta m: 0x%lx c: %d l: %d\n",
+				    (long)be32_to_cpu(h->magic),
+				    h->command, h->length);
+				goto disconnect;
+			}
+			expect = cmd->pkt_size;
+			ERR_IF(len != expect-sizeof(struct p_header))
+				goto reconnect;
+		}
+		if (received == expect) {
+			D_ASSERT(cmd != NULL);
+			if (!cmd->process(mdev, h))
+				goto reconnect;
+
+			buf	 = h;
+			received = 0;
+			expect	 = sizeof(struct p_header);
+			cmd	 = NULL;
+		}
+	}
+
+	if (0) {
+reconnect:
+		drbd_force_state(mdev, NS(conn, C_NETWORK_FAILURE));
+	}
+	if (0) {
+disconnect:
+		drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+	}
+	clear_bit(SIGNAL_ASENDER, &mdev->flags);
+
+	D_ASSERT(mdev->state.conn < C_CONNECTED);
+	dev_info(DEV, "asender terminated\n");
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_req.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_req.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1125 @@
+/*
+   drbd_req.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+
+#include <linux/slab.h>
+#include <linux/drbd.h>
+#include "drbd_int.h"
+#include "drbd_req.h"
+
+
+/* Update disk stats at start of I/O request */
+static void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req, struct bio *bio)
+{
+	const int rw = bio_data_dir(bio);
+	int cpu;
+	cpu = part_stat_lock();
+	part_stat_inc(cpu, &mdev->vdisk->part0, ios[rw]);
+	part_stat_add(cpu, &mdev->vdisk->part0, sectors[rw], bio_sectors(bio));
+	part_inc_in_flight(&mdev->vdisk->part0, rw);
+	part_stat_unlock();
+}
+
+/* Update disk stats when completing request upwards */
+static void _drbd_end_io_acct(struct drbd_conf *mdev, struct drbd_request *req)
+{
+	int rw = bio_data_dir(req->master_bio);
+	unsigned long duration = jiffies - req->start_time;
+	int cpu;
+	cpu = part_stat_lock();
+	part_stat_add(cpu, &mdev->vdisk->part0, ticks[rw], duration);
+	part_round_stats(cpu, &mdev->vdisk->part0);
+	part_dec_in_flight(&mdev->vdisk->part0, rw);
+	part_stat_unlock();
+}
+
+static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const int rw)
+{
+	const unsigned long s = req->rq_state;
+	/* if it was a write, we may have to set the corresponding
+	 * bit(s) out-of-sync first. If it had a local part, we need to
+	 * release the reference to the activity log. */
+	if (rw == WRITE) {
+		/* remove it from the transfer log.
+		 * well, only if it had been there in the first
+		 * place... if it had not (local only or conflicting
+		 * and never sent), it should still be "empty" as
+		 * initialized in drbd_req_new(), so we can list_del() it
+		 * here unconditionally */
+		list_del(&req->tl_requests);
+		/* Set out-of-sync unless both OK flags are set
+		 * (local only or remote failed).
+		 * Other places where we set out-of-sync:
+		 * READ with local io-error */
+		if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK))
+			drbd_set_out_of_sync(mdev, req->sector, req->size);
+
+		if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS))
+			drbd_set_in_sync(mdev, req->sector, req->size);
+
+		/* one might be tempted to move the drbd_al_complete_io
+		 * to the local io completion callback drbd_endio_pri.
+		 * but, if this was a mirror write, we may only
+		 * drbd_al_complete_io after this is RQ_NET_DONE,
+		 * otherwise the extent could be dropped from the al
+		 * before it has actually been written on the peer.
+		 * if we crash before our peer knows about the request,
+		 * but after the extent has been dropped from the al,
+		 * we would forget to resync the corresponding extent.
+		 */
+		if (s & RQ_LOCAL_MASK) {
+			if (get_ldev_if_state(mdev, D_FAILED)) {
+				drbd_al_complete_io(mdev, req->sector);
+				put_ldev(mdev);
+			} else if (__ratelimit(&drbd_ratelimit_state)) {
+				dev_warn(DEV, "Should have called drbd_al_complete_io(, %llu), "
+				     "but my Disk seems to have failed :(\n",
+				     (unsigned long long) req->sector);
+			}
+		}
+	}
+
+	/* if it was a local io error, we want to notify our
+	 * peer about that, and see if we need to
+	 * detach the disk and stuff.
+	 * to avoid allocating some special work
+	 * struct, reuse the request. */
+
+	/* THINK
+	 * why do we do this not when we detect the error,
+	 * but delay it until it is "done", i.e. possibly
+	 * until the next barrier ack? */
+
+	if (rw == WRITE &&
+	    ((s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) {
+		if (!(req->w.list.next == LIST_POISON1 ||
+		      list_empty(&req->w.list))) {
+			/* DEBUG ASSERT only; if this triggers, we
+			 * probably corrupt the worker list here */
+			dev_err(DEV, "req->w.list.next = %p\n", req->w.list.next);
+			dev_err(DEV, "req->w.list.prev = %p\n", req->w.list.prev);
+		}
+		req->w.cb = w_io_error;
+		drbd_queue_work(&mdev->data.work, &req->w);
+		/* drbd_req_free() is done in w_io_error */
+	} else {
+		drbd_req_free(req);
+	}
+}
+
+static void queue_barrier(struct drbd_conf *mdev)
+{
+	struct drbd_tl_epoch *b;
+
+	/* We are within the req_lock. Once we queued the barrier for sending,
+	 * we set the CREATE_BARRIER bit. It is cleared as soon as a new
+	 * barrier/epoch object is added. This is the only place this bit is
+	 * set. It indicates that the barrier for this epoch is already queued,
+	 * and no new epoch has been created yet. */
+	if (test_bit(CREATE_BARRIER, &mdev->flags))
+		return;
+
+	b = mdev->newest_tle;
+	b->w.cb = w_send_barrier;
+	/* inc_ap_pending done here, so we won't
+	 * get imbalanced on connection loss.
+	 * dec_ap_pending will be done in got_BarrierAck
+	 * or (on connection loss) in tl_clear.  */
+	inc_ap_pending(mdev);
+	drbd_queue_work(&mdev->data.work, &b->w);
+	set_bit(CREATE_BARRIER, &mdev->flags);
+}
+
+static void _about_to_complete_local_write(struct drbd_conf *mdev,
+	struct drbd_request *req)
+{
+	const unsigned long s = req->rq_state;
+	struct drbd_request *i;
+	struct drbd_epoch_entry *e;
+	struct hlist_node *n;
+	struct hlist_head *slot;
+
+	/* before we can signal completion to the upper layers,
+	 * we may need to close the current epoch */
+	if (mdev->state.conn >= C_CONNECTED &&
+	    req->epoch == mdev->newest_tle->br_number)
+		queue_barrier(mdev);
+
+	/* we need to do the conflict detection stuff,
+	 * if we have the ee_hash (two_primaries) and
+	 * this has been on the network */
+	if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) {
+		const sector_t sector = req->sector;
+		const int size = req->size;
+
+		/* ASSERT:
+		 * there must be no conflicting requests, since
+		 * they must have been failed on the spot */
+#define OVERLAPS overlaps(sector, size, i->sector, i->size)
+		slot = tl_hash_slot(mdev, sector);
+		hlist_for_each_entry(i, n, slot, colision) {
+			if (OVERLAPS) {
+				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
+				      "other: %p %llus +%u\n",
+				      req, (unsigned long long)sector, size,
+				      i, (unsigned long long)i->sector, i->size);
+			}
+		}
+
+		/* maybe "wake" those conflicting epoch entries
+		 * that wait for this request to finish.
+		 *
+		 * currently, there can be only _one_ such ee
+		 * (well, or some more, which would be pending
+		 * P_DISCARD_ACK not yet sent by the asender...),
+		 * since we block the receiver thread upon the
+		 * first conflict detection, which will wait on
+		 * misc_wait.  maybe we want to assert that?
+		 *
+		 * anyways, if we found one,
+		 * we just have to do a wake_up.  */
+#undef OVERLAPS
+#define OVERLAPS overlaps(sector, size, e->sector, e->size)
+		slot = ee_hash_slot(mdev, req->sector);
+		hlist_for_each_entry(e, n, slot, colision) {
+			if (OVERLAPS) {
+				wake_up(&mdev->misc_wait);
+				break;
+			}
+		}
+	}
+#undef OVERLAPS
+}
+
+void complete_master_bio(struct drbd_conf *mdev,
+		struct bio_and_error *m)
+{
+	bio_endio(m->bio, m->error);
+	dec_ap_bio(mdev);
+}
+
+/* Helper for __req_mod().
+ * Set m->bio to the master bio, if it is fit to be completed,
+ * or leave it alone (it is initialized to NULL in __req_mod),
+ * if it has already been completed, or cannot be completed yet.
+ * If m->bio is set, the error status to be returned is placed in m->error.
+ */
+void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
+{
+	const unsigned long s = req->rq_state;
+	struct drbd_conf *mdev = req->mdev;
+	/* only WRITES may end up here without a master bio (on barrier ack) */
+	int rw = req->master_bio ? bio_data_dir(req->master_bio) : WRITE;
+
+	/* we must not complete the master bio, while it is
+	 *	still being processed by _drbd_send_zc_bio (drbd_send_dblock)
+	 *	not yet acknowledged by the peer
+	 *	not yet completed by the local io subsystem
+	 * these flags may get cleared in any order by
+	 *	the worker,
+	 *	the receiver,
+	 *	the bio_endio completion callbacks.
+	 */
+	if (s & RQ_NET_QUEUED)
+		return;
+	if (s & RQ_NET_PENDING)
+		return;
+	if (s & RQ_LOCAL_PENDING)
+		return;
+
+	if (req->master_bio) {
+		/* this is data_received (remote read)
+		 * or protocol C P_WRITE_ACK
+		 * or protocol B P_RECV_ACK
+		 * or protocol A "handed_over_to_network" (SendAck)
+		 * or canceled or failed,
+		 * or killed from the transfer log due to connection loss.
+		 */
+
+		/*
+		 * figure out whether to report success or failure.
+		 *
+		 * report success when at least one of the operations succeeded.
+		 * or, to put the other way,
+		 * only report failure, when both operations failed.
+		 *
+		 * what to do about the failures is handled elsewhere.
+		 * what we need to do here is just: complete the master_bio.
+		 *
+		 * local completion error, if any, has been stored as ERR_PTR
+		 * in private_bio within drbd_endio_pri.
+		 */
+		int ok = (s & RQ_LOCAL_OK) || (s & RQ_NET_OK);
+		int error = PTR_ERR(req->private_bio);
+
+		/* remove the request from the conflict detection
+		 * respective block_id verification hash */
+		if (!hlist_unhashed(&req->colision))
+			hlist_del(&req->colision);
+		else
+			D_ASSERT((s & RQ_NET_MASK) == 0);
+
+		/* for writes we need to do some extra housekeeping */
+		if (rw == WRITE)
+			_about_to_complete_local_write(mdev, req);
+
+		/* Update disk stats */
+		_drbd_end_io_acct(mdev, req);
+
+		m->error = ok ? 0 : (error ?: -EIO);
+		m->bio = req->master_bio;
+		req->master_bio = NULL;
+	}
+
+	if ((s & RQ_NET_MASK) == 0 || (s & RQ_NET_DONE)) {
+		/* this is disconnected (local only) operation,
+		 * or protocol C P_WRITE_ACK,
+		 * or protocol A or B P_BARRIER_ACK,
+		 * or killed from the transfer log due to connection loss. */
+		_req_is_done(mdev, req, rw);
+	}
+	/* else: network part and not DONE yet. that is
+	 * protocol A or B, barrier ack still pending... */
+}
+
+/*
+ * checks whether there was an overlapping request
+ * or ee already registered.
+ *
+ * if so, return 1, in which case this request is completed on the spot,
+ * without ever being submitted or send.
+ *
+ * return 0 if it is ok to submit this request.
+ *
+ * NOTE:
+ * paranoia: assume something above us is broken, and issues different write
+ * requests for the same block simultaneously...
+ *
+ * To ensure these won't be reordered differently on both nodes, resulting in
+ * diverging data sets, we discard the later one(s). Not that this is supposed
+ * to happen, but this is the rationale why we also have to check for
+ * conflicting requests with local origin, and why we have to do so regardless
+ * of whether we allowed multiple primaries.
+ *
+ * BTW, in case we only have one primary, the ee_hash is empty anyways, and the
+ * second hlist_for_each_entry becomes a noop. This is even simpler than to
+ * grab a reference on the net_conf, and check for the two_primaries flag...
+ */
+static int _req_conflicts(struct drbd_request *req)
+{
+	struct drbd_conf *mdev = req->mdev;
+	const sector_t sector = req->sector;
+	const int size = req->size;
+	struct drbd_request *i;
+	struct drbd_epoch_entry *e;
+	struct hlist_node *n;
+	struct hlist_head *slot;
+
+	D_ASSERT(hlist_unhashed(&req->colision));
+
+	if (!get_net_conf(mdev))
+		return 0;
+
+	/* BUG_ON */
+	ERR_IF (mdev->tl_hash_s == 0)
+		goto out_no_conflict;
+	BUG_ON(mdev->tl_hash == NULL);
+
+#define OVERLAPS overlaps(i->sector, i->size, sector, size)
+	slot = tl_hash_slot(mdev, sector);
+	hlist_for_each_entry(i, n, slot, colision) {
+		if (OVERLAPS) {
+			dev_alert(DEV, "%s[%u] Concurrent local write detected! "
+			      "[DISCARD L] new: %llus +%u; "
+			      "pending: %llus +%u\n",
+			      current->comm, current->pid,
+			      (unsigned long long)sector, size,
+			      (unsigned long long)i->sector, i->size);
+			goto out_conflict;
+		}
+	}
+
+	if (mdev->ee_hash_s) {
+		/* now, check for overlapping requests with remote origin */
+		BUG_ON(mdev->ee_hash == NULL);
+#undef OVERLAPS
+#define OVERLAPS overlaps(e->sector, e->size, sector, size)
+		slot = ee_hash_slot(mdev, sector);
+		hlist_for_each_entry(e, n, slot, colision) {
+			if (OVERLAPS) {
+				dev_alert(DEV, "%s[%u] Concurrent remote write detected!"
+				      " [DISCARD L] new: %llus +%u; "
+				      "pending: %llus +%u\n",
+				      current->comm, current->pid,
+				      (unsigned long long)sector, size,
+				      (unsigned long long)e->sector, e->size);
+				goto out_conflict;
+			}
+		}
+	}
+#undef OVERLAPS
+
+out_no_conflict:
+	/* this is like it should be, and what we expected.
+	 * our users do behave after all... */
+	put_net_conf(mdev);
+	return 0;
+
+out_conflict:
+	put_net_conf(mdev);
+	return 1;
+}
+
+/* obviously this could be coded as many single functions
+ * instead of one huge switch,
+ * or by putting the code directly in the respective locations
+ * (as it has been before).
+ *
+ * but having it this way
+ *  enforces that it is all in this one place, where it is easier to audit,
+ *  it makes it obvious that whatever "event" "happens" to a request should
+ *  happen "atomically" within the req_lock,
+ *  and it enforces that we have to think in a very structured manner
+ *  about the "events" that may happen to a request during its life time ...
+ */
+void __req_mod(struct drbd_request *req, enum drbd_req_event what,
+		struct bio_and_error *m)
+{
+	struct drbd_conf *mdev = req->mdev;
+	m->bio = NULL;
+
+	switch (what) {
+	default:
+		dev_err(DEV, "LOGIC BUG in %s:%u\n", __FILE__ , __LINE__);
+		break;
+
+	/* does not happen...
+	 * initialization done in drbd_req_new
+	case created:
+		break;
+		*/
+
+	case to_be_send: /* via network */
+		/* reached via drbd_make_request_common
+		 * and from w_read_retry_remote */
+		D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+		req->rq_state |= RQ_NET_PENDING;
+		inc_ap_pending(mdev);
+		break;
+
+	case to_be_submitted: /* locally */
+		/* reached via drbd_make_request_common */
+		D_ASSERT(!(req->rq_state & RQ_LOCAL_MASK));
+		req->rq_state |= RQ_LOCAL_PENDING;
+		break;
+
+	case completed_ok:
+		if (bio_data_dir(req->master_bio) == WRITE)
+			mdev->writ_cnt += req->size>>9;
+		else
+			mdev->read_cnt += req->size>>9;
+
+		req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK);
+		req->rq_state &= ~RQ_LOCAL_PENDING;
+
+		_req_may_be_done(req, m);
+		put_ldev(mdev);
+		break;
+
+	case write_completed_with_error:
+		req->rq_state |= RQ_LOCAL_COMPLETED;
+		req->rq_state &= ~RQ_LOCAL_PENDING;
+
+		dev_alert(DEV, "Local WRITE failed sec=%llus size=%u\n",
+		      (unsigned long long)req->sector, req->size);
+		/* and now: check how to handle local io error. */
+		__drbd_chk_io_error(mdev, FALSE);
+		_req_may_be_done(req, m);
+		put_ldev(mdev);
+		break;
+
+	case read_ahead_completed_with_error:
+		/* it is legal to fail READA */
+		req->rq_state |= RQ_LOCAL_COMPLETED;
+		req->rq_state &= ~RQ_LOCAL_PENDING;
+		_req_may_be_done(req, m);
+		put_ldev(mdev);
+		break;
+
+	case read_completed_with_error:
+		drbd_set_out_of_sync(mdev, req->sector, req->size);
+
+		req->rq_state |= RQ_LOCAL_COMPLETED;
+		req->rq_state &= ~RQ_LOCAL_PENDING;
+
+		dev_alert(DEV, "Local READ failed sec=%llus size=%u\n",
+		      (unsigned long long)req->sector, req->size);
+		/* _req_mod(req,to_be_send); oops, recursion... */
+		D_ASSERT(!(req->rq_state & RQ_NET_MASK));
+		req->rq_state |= RQ_NET_PENDING;
+		inc_ap_pending(mdev);
+
+		__drbd_chk_io_error(mdev, FALSE);
+		put_ldev(mdev);
+		/* NOTE: if we have no connection,
+		 * or know the peer has no good data either,
+		 * then we don't actually need to "queue_for_net_read",
+		 * but we do so anyways, since the drbd_io_error()
+		 * and the potential state change to "Diskless"
+		 * needs to be done from process context */
+
+		/* fall through: _req_mod(req,queue_for_net_read); */
+
+	case queue_for_net_read:
+		/* READ or READA, and
+		 * no local disk,
+		 * or target area marked as invalid,
+		 * or just got an io-error. */
+		/* from drbd_make_request_common
+		 * or from bio_endio during read io-error recovery */
+
+		/* so we can verify the handle in the answer packet
+		 * corresponding hlist_del is in _req_may_be_done() */
+		hlist_add_head(&req->colision, ar_hash_slot(mdev, req->sector));
+
+		set_bit(UNPLUG_REMOTE, &mdev->flags);
+
+		D_ASSERT(req->rq_state & RQ_NET_PENDING);
+		req->rq_state |= RQ_NET_QUEUED;
+		req->w.cb = (req->rq_state & RQ_LOCAL_MASK)
+			? w_read_retry_remote
+			: w_send_read_req;
+		drbd_queue_work(&mdev->data.work, &req->w);
+		break;
+
+	case queue_for_net_write:
+		/* assert something? */
+		/* from drbd_make_request_common only */
+
+		hlist_add_head(&req->colision, tl_hash_slot(mdev, req->sector));
+		/* corresponding hlist_del is in _req_may_be_done() */
+
+		/* NOTE
+		 * In case the req ended up on the transfer log before being
+		 * queued on the worker, it could lead to this request being
+		 * missed during cleanup after connection loss.
+		 * So we have to do both operations here,
+		 * within the same lock that protects the transfer log.
+		 *
+		 * _req_add_to_epoch(req); this has to be after the
+		 * _maybe_start_new_epoch(req); which happened in
+		 * drbd_make_request_common, because we now may set the bit
+		 * again ourselves to close the current epoch.
+		 *
+		 * Add req to the (now) current epoch (barrier). */
+
+		/* otherwise we may lose an unplug, which may cause some remote
+		 * io-scheduler timeout to expire, increasing maximum latency,
+		 * hurting performance. */
+		set_bit(UNPLUG_REMOTE, &mdev->flags);
+
+		/* see drbd_make_request_common,
+		 * just after it grabs the req_lock */
+		D_ASSERT(test_bit(CREATE_BARRIER, &mdev->flags) == 0);
+
+		req->epoch = mdev->newest_tle->br_number;
+		list_add_tail(&req->tl_requests,
+				&mdev->newest_tle->requests);
+
+		/* increment size of current epoch */
+		mdev->newest_tle->n_req++;
+
+		/* queue work item to send data */
+		D_ASSERT(req->rq_state & RQ_NET_PENDING);
+		req->rq_state |= RQ_NET_QUEUED;
+		req->w.cb =  w_send_dblock;
+		drbd_queue_work(&mdev->data.work, &req->w);
+
+		/* close the epoch, in case it outgrew the limit */
+		if (mdev->newest_tle->n_req >= mdev->net_conf->max_epoch_size)
+			queue_barrier(mdev);
+
+		break;
+
+	case send_canceled:
+		/* treat it the same */
+	case send_failed:
+		/* real cleanup will be done from tl_clear.  just update flags
+		 * so it is no longer marked as on the worker queue */
+		req->rq_state &= ~RQ_NET_QUEUED;
+		/* if we did it right, tl_clear should be scheduled only after
+		 * this, so this should not be necessary! */
+		_req_may_be_done(req, m);
+		break;
+
+	case handed_over_to_network:
+		/* assert something? */
+		if (bio_data_dir(req->master_bio) == WRITE &&
+		    mdev->net_conf->wire_protocol == DRBD_PROT_A) {
+			/* this is what is dangerous about protocol A:
+			 * pretend it was successfully written on the peer. */
+			if (req->rq_state & RQ_NET_PENDING) {
+				dec_ap_pending(mdev);
+				req->rq_state &= ~RQ_NET_PENDING;
+				req->rq_state |= RQ_NET_OK;
+			} /* else: neg-ack was faster... */
+			/* it is still not yet RQ_NET_DONE until the
+			 * corresponding epoch barrier got acked as well,
+			 * so we know what to dirty on connection loss */
+		}
+		req->rq_state &= ~RQ_NET_QUEUED;
+		req->rq_state |= RQ_NET_SENT;
+		/* because _drbd_send_zc_bio could sleep, and may want to
+		 * dereference the bio even after the "write_acked_by_peer" and
+		 * "completed_ok" events came in, once we return from
+		 * _drbd_send_zc_bio (drbd_send_dblock), we have to check
+		 * whether it is done already, and end it.  */
+		_req_may_be_done(req, m);
+		break;
+
+	case connection_lost_while_pending:
+		/* transfer log cleanup after connection loss */
+		/* assert something? */
+		if (req->rq_state & RQ_NET_PENDING)
+			dec_ap_pending(mdev);
+		req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING);
+		req->rq_state |= RQ_NET_DONE;
+		/* if it is still queued, we may not complete it here.
+		 * it will be canceled soon. */
+		if (!(req->rq_state & RQ_NET_QUEUED))
+			_req_may_be_done(req, m);
+		break;
+
+	case write_acked_by_peer_and_sis:
+		req->rq_state |= RQ_NET_SIS;
+	case conflict_discarded_by_peer:
+		/* for discarded conflicting writes of multiple primaries,
+		 * there is no need to keep anything in the tl, potential
+		 * node crashes are covered by the activity log. */
+		if (what == conflict_discarded_by_peer)
+			dev_alert(DEV, "Got DiscardAck packet %llus +%u!"
+			      " DRBD is not a random data generator!\n",
+			      (unsigned long long)req->sector, req->size);
+		req->rq_state |= RQ_NET_DONE;
+		/* fall through */
+	case write_acked_by_peer:
+		/* protocol C; successfully written on peer.
+		 * Nothing to do here.
+		 * We want to keep the tl in place for all protocols, to cater
+		 * for volatile write-back caches on lower level devices.
+		 *
+		 * A barrier request is expected to have forced all prior
+		 * requests onto stable storage, so completion of a barrier
+		 * request could set NET_DONE right here, and not wait for the
+		 * P_BARRIER_ACK, but that is an unnecessary optimization. */
+
+		/* this makes it effectively the same as for: */
+	case recv_acked_by_peer:
+		/* protocol B; pretends to be successfully written on peer.
+		 * see also notes above in handed_over_to_network about
+		 * protocol != C */
+		req->rq_state |= RQ_NET_OK;
+		D_ASSERT(req->rq_state & RQ_NET_PENDING);
+		dec_ap_pending(mdev);
+		req->rq_state &= ~RQ_NET_PENDING;
+		_req_may_be_done(req, m);
+		break;
+
+	case neg_acked:
+		/* assert something? */
+		if (req->rq_state & RQ_NET_PENDING)
+			dec_ap_pending(mdev);
+		req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING);
+
+		req->rq_state |= RQ_NET_DONE;
+		_req_may_be_done(req, m);
+		/* else: done by handed_over_to_network */
+		break;
+
+	case barrier_acked:
+		if (req->rq_state & RQ_NET_PENDING) {
+			/* barrier came in before all requests have been acked.
+			 * this is bad, because if the connection is lost now,
+			 * we won't be able to clean them up... */
+			dev_err(DEV, "FIXME (barrier_acked but pending)\n");
+			list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
+		}
+		D_ASSERT(req->rq_state & RQ_NET_SENT);
+		req->rq_state |= RQ_NET_DONE;
+		_req_may_be_done(req, m);
+		break;
+
+	case data_received:
+		D_ASSERT(req->rq_state & RQ_NET_PENDING);
+		dec_ap_pending(mdev);
+		req->rq_state &= ~RQ_NET_PENDING;
+		req->rq_state |= (RQ_NET_OK|RQ_NET_DONE);
+		_req_may_be_done(req, m);
+		break;
+	};
+}
+
+/* we may do a local read if:
+ * - we are consistent (of course),
+ * - or we are generally inconsistent,
+ *   BUT we are still/already IN SYNC for this area.
+ *   since size may be bigger than BM_BLOCK_SIZE,
+ *   we may need to check several bits.
+ */
+static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int size)
+{
+	unsigned long sbnr, ebnr;
+	sector_t esector, nr_sectors;
+
+	if (mdev->state.disk == D_UP_TO_DATE)
+		return 1;
+	if (mdev->state.disk >= D_OUTDATED)
+		return 0;
+	if (mdev->state.disk <  D_INCONSISTENT)
+		return 0;
+	/* state.disk == D_INCONSISTENT   We will have a look at the BitMap */
+	nr_sectors = drbd_get_capacity(mdev->this_bdev);
+	esector = sector + (size >> 9) - 1;
+
+	D_ASSERT(sector  < nr_sectors);
+	D_ASSERT(esector < nr_sectors);
+
+	sbnr = BM_SECT_TO_BIT(sector);
+	ebnr = BM_SECT_TO_BIT(esector);
+
+	return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr);
+}
+
+static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio)
+{
+	const int rw = bio_rw(bio);
+	const int size = bio->bi_size;
+	const sector_t sector = bio->bi_sector;
+	struct drbd_tl_epoch *b = NULL;
+	struct drbd_request *req;
+	int local, remote;
+	int err = -EIO;
+
+	/* allocate outside of all locks; */
+	req = drbd_req_new(mdev, bio);
+	if (!req) {
+		dec_ap_bio(mdev);
+		/* only pass the error to the upper layers.
+		 * if user cannot handle io errors, that's not our business. */
+		dev_err(DEV, "could not kmalloc() req\n");
+		bio_endio(bio, -ENOMEM);
+		return 0;
+	}
+
+	local = get_ldev(mdev);
+	if (!local) {
+		bio_put(req->private_bio); /* or we get a bio leak */
+		req->private_bio = NULL;
+	}
+	if (rw == WRITE) {
+		remote = 1;
+	} else {
+		/* READ || READA */
+		if (local) {
+			if (!drbd_may_do_local_read(mdev, sector, size)) {
+				/* we could kick the syncer to
+				 * sync this extent asap, wait for
+				 * it, then continue locally.
+				 * Or just issue the request remotely.
+				 */
+				local = 0;
+				bio_put(req->private_bio);
+				req->private_bio = NULL;
+				put_ldev(mdev);
+			}
+		}
+		remote = !local && mdev->state.pdsk >= D_UP_TO_DATE;
+	}
+
+	/* If we have a disk, but a READA request is mapped to remote,
+	 * we are R_PRIMARY, D_INCONSISTENT, SyncTarget.
+	 * Just fail that READA request right here.
+	 *
+	 * THINK: maybe fail all READA when not local?
+	 *        or make this configurable...
+	 *        if network is slow, READA won't do any good.
+	 */
+	if (rw == READA && mdev->state.disk >= D_INCONSISTENT && !local) {
+		err = -EWOULDBLOCK;
+		goto fail_and_free_req;
+	}
+
+	/* For WRITES going to the local disk, grab a reference on the target
+	 * extent.  This waits for any resync activity in the corresponding
+	 * resync extent to finish, and, if necessary, pulls in the target
+	 * extent into the activity log, which involves further disk io because
+	 * of transactional on-disk meta data updates. */
+	if (rw == WRITE && local)
+		drbd_al_begin_io(mdev, sector);
+
+	remote = remote && (mdev->state.pdsk == D_UP_TO_DATE ||
+			    (mdev->state.pdsk == D_INCONSISTENT &&
+			     mdev->state.conn >= C_CONNECTED));
+
+	if (!(local || remote)) {
+		dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
+		goto fail_free_complete;
+	}
+
+	/* For WRITE request, we have to make sure that we have an
+	 * unused_spare_tle, in case we need to start a new epoch.
+	 * I try to be smart and avoid to pre-allocate always "just in case",
+	 * but there is a race between testing the bit and pointer outside the
+	 * spinlock, and grabbing the spinlock.
+	 * if we lost that race, we retry.  */
+	if (rw == WRITE && remote &&
+	    mdev->unused_spare_tle == NULL &&
+	    test_bit(CREATE_BARRIER, &mdev->flags)) {
+allocate_barrier:
+		b = kmalloc(sizeof(struct drbd_tl_epoch), GFP_NOIO);
+		if (!b) {
+			dev_err(DEV, "Failed to alloc barrier.\n");
+			err = -ENOMEM;
+			goto fail_free_complete;
+		}
+	}
+
+	/* GOOD, everything prepared, grab the spin_lock */
+	spin_lock_irq(&mdev->req_lock);
+
+	if (remote) {
+		remote = (mdev->state.pdsk == D_UP_TO_DATE ||
+			    (mdev->state.pdsk == D_INCONSISTENT &&
+			     mdev->state.conn >= C_CONNECTED));
+		if (!remote)
+			dev_warn(DEV, "lost connection while grabbing the req_lock!\n");
+		if (!(local || remote)) {
+			dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
+			spin_unlock_irq(&mdev->req_lock);
+			goto fail_free_complete;
+		}
+	}
+
+	if (b && mdev->unused_spare_tle == NULL) {
+		mdev->unused_spare_tle = b;
+		b = NULL;
+	}
+	if (rw == WRITE && remote &&
+	    mdev->unused_spare_tle == NULL &&
+	    test_bit(CREATE_BARRIER, &mdev->flags)) {
+		/* someone closed the current epoch
+		 * while we were grabbing the spinlock */
+		spin_unlock_irq(&mdev->req_lock);
+		goto allocate_barrier;
+	}
+
+
+	/* Update disk stats */
+	_drbd_start_io_acct(mdev, req, bio);
+
+	/* _maybe_start_new_epoch(mdev);
+	 * If we need to generate a write barrier packet, we have to add the
+	 * new epoch (barrier) object, and queue the barrier packet for sending,
+	 * and queue the req's data after it _within the same lock_, otherwise
+	 * we have race conditions were the reorder domains could be mixed up.
+	 *
+	 * Even read requests may start a new epoch and queue the corresponding
+	 * barrier packet.  To get the write ordering right, we only have to
+	 * make sure that, if this is a write request and it triggered a
+	 * barrier packet, this request is queued within the same spinlock. */
+	if (remote && mdev->unused_spare_tle &&
+	    test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) {
+		_tl_add_barrier(mdev, mdev->unused_spare_tle);
+		mdev->unused_spare_tle = NULL;
+	} else {
+		D_ASSERT(!(remote && rw == WRITE &&
+			   test_bit(CREATE_BARRIER, &mdev->flags)));
+	}
+
+	/* NOTE
+	 * Actually, 'local' may be wrong here already, since we may have failed
+	 * to write to the meta data, and may become wrong anytime because of
+	 * local io-error for some other request, which would lead to us
+	 * "detaching" the local disk.
+	 *
+	 * 'remote' may become wrong any time because the network could fail.
+	 *
+	 * This is a harmless race condition, though, since it is handled
+	 * correctly at the appropriate places; so it just defers the failure
+	 * of the respective operation.
+	 */
+
+	/* mark them early for readability.
+	 * this just sets some state flags. */
+	if (remote)
+		_req_mod(req, to_be_send);
+	if (local)
+		_req_mod(req, to_be_submitted);
+
+	/* check this request on the collision detection hash tables.
+	 * if we have a conflict, just complete it here.
+	 * THINK do we want to check reads, too? (I don't think so...) */
+	if (rw == WRITE && _req_conflicts(req)) {
+		/* this is a conflicting request.
+		 * even though it may have been only _partially_
+		 * overlapping with one of the currently pending requests,
+		 * without even submitting or sending it, we will
+		 * pretend that it was successfully served right now.
+		 */
+		if (local) {
+			bio_put(req->private_bio);
+			req->private_bio = NULL;
+			drbd_al_complete_io(mdev, req->sector);
+			put_ldev(mdev);
+			local = 0;
+		}
+		if (remote)
+			dec_ap_pending(mdev);
+		_drbd_end_io_acct(mdev, req);
+		/* THINK: do we want to fail it (-EIO), or pretend success? */
+		bio_endio(req->master_bio, 0);
+		req->master_bio = NULL;
+		dec_ap_bio(mdev);
+		drbd_req_free(req);
+		remote = 0;
+	}
+
+	/* NOTE remote first: to get the concurrent write detection right,
+	 * we must register the request before start of local IO.  */
+	if (remote) {
+		/* either WRITE and C_CONNECTED,
+		 * or READ, and no local disk,
+		 * or READ, but not in sync.
+		 */
+		_req_mod(req, (rw == WRITE)
+				? queue_for_net_write
+				: queue_for_net_read);
+	}
+	spin_unlock_irq(&mdev->req_lock);
+	kfree(b); /* if someone else has beaten us to it... */
+
+	if (local) {
+		req->private_bio->bi_bdev = mdev->ldev->backing_bdev;
+
+		if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR
+				     : rw == READ  ? DRBD_FAULT_DT_RD
+				     :               DRBD_FAULT_DT_RA))
+			bio_endio(req->private_bio, -EIO);
+		else
+			generic_make_request(req->private_bio);
+	}
+
+	/* we need to plug ALWAYS since we possibly need to kick lo_dev.
+	 * we plug after submit, so we won't miss an unplug event */
+	drbd_plug_device(mdev);
+
+	return 0;
+
+fail_free_complete:
+	if (rw == WRITE && local)
+		drbd_al_complete_io(mdev, sector);
+fail_and_free_req:
+	if (local) {
+		bio_put(req->private_bio);
+		req->private_bio = NULL;
+		put_ldev(mdev);
+	}
+	bio_endio(bio, err);
+	drbd_req_free(req);
+	dec_ap_bio(mdev);
+	kfree(b);
+
+	return 0;
+}
+
+/* helper function for drbd_make_request
+ * if we can determine just by the mdev (state) that this request will fail,
+ * return 1
+ * otherwise return 0
+ */
+static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write)
+{
+	/* Unconfigured */
+	if (mdev->state.conn == C_DISCONNECTING &&
+	    mdev->state.disk == D_DISKLESS)
+		return 1;
+
+	if (mdev->state.role != R_PRIMARY &&
+		(!allow_oos || is_write)) {
+		if (__ratelimit(&drbd_ratelimit_state)) {
+			dev_err(DEV, "Process %s[%u] tried to %s; "
+			    "since we are not in Primary state, "
+			    "we cannot allow this\n",
+			    current->comm, current->pid,
+			    is_write ? "WRITE" : "READ");
+		}
+		return 1;
+	}
+
+	/*
+	 * Paranoia: we might have been primary, but sync target, or
+	 * even diskless, then lost the connection.
+	 * This should have been handled (panic? suspend?) somewhere
+	 * else. But maybe it was not, so check again here.
+	 * Caution: as long as we do not have a read/write lock on mdev,
+	 * to serialize state changes, this is racy, since we may lose
+	 * the connection *after* we test for the cstate.
+	 */
+	if (mdev->state.disk < D_UP_TO_DATE && mdev->state.pdsk < D_UP_TO_DATE) {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Sorry, I have no access to good data anymore.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+int drbd_make_request_26(struct request_queue *q, struct bio *bio)
+{
+	unsigned int s_enr, e_enr;
+	struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata;
+
+	if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) {
+		bio_endio(bio, -EPERM);
+		return 0;
+	}
+
+	/* Reject barrier requests if we know the underlying device does
+	 * not support them.
+	 * XXX: Need to get this info from peer as well some how so we
+	 * XXX: reject if EITHER side/data/metadata area does not support them.
+	 *
+	 * because of those XXX, this is not yet enabled,
+	 * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit.
+	 */
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags))) {
+		/* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */
+		bio_endio(bio, -EOPNOTSUPP);
+		return 0;
+	}
+
+	/*
+	 * what we "blindly" assume:
+	 */
+	D_ASSERT(bio->bi_size > 0);
+	D_ASSERT((bio->bi_size & 0x1ff) == 0);
+	D_ASSERT(bio->bi_idx == 0);
+
+	/* to make some things easier, force alignment of requests within the
+	 * granularity of our hash tables */
+	s_enr = bio->bi_sector >> HT_SHIFT;
+	e_enr = (bio->bi_sector+(bio->bi_size>>9)-1) >> HT_SHIFT;
+
+	if (likely(s_enr == e_enr)) {
+		inc_ap_bio(mdev, 1);
+		return drbd_make_request_common(mdev, bio);
+	}
+
+	/* can this bio be split generically?
+	 * Maybe add our own split-arbitrary-bios function. */
+	if (bio->bi_vcnt != 1 || bio->bi_idx != 0 || bio->bi_size > DRBD_MAX_SEGMENT_SIZE) {
+		/* rather error out here than BUG in bio_split */
+		dev_err(DEV, "bio would need to, but cannot, be split: "
+		    "(vcnt=%u,idx=%u,size=%u,sector=%llu)\n",
+		    bio->bi_vcnt, bio->bi_idx, bio->bi_size,
+		    (unsigned long long)bio->bi_sector);
+		bio_endio(bio, -EINVAL);
+	} else {
+		/* This bio crosses some boundary, so we have to split it. */
+		struct bio_pair *bp;
+		/* works for the "do not cross hash slot boundaries" case
+		 * e.g. sector 262269, size 4096
+		 * s_enr = 262269 >> 6 = 4097
+		 * e_enr = (262269+8-1) >> 6 = 4098
+		 * HT_SHIFT = 6
+		 * sps = 64, mask = 63
+		 * first_sectors = 64 - (262269 & 63) = 3
+		 */
+		const sector_t sect = bio->bi_sector;
+		const int sps = 1 << HT_SHIFT; /* sectors per slot */
+		const int mask = sps - 1;
+		const sector_t first_sectors = sps - (sect & mask);
+		bp = bio_split(bio,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+				bio_split_pool,
+#endif
+				first_sectors);
+
+		/* we need to get a "reference count" (ap_bio_cnt)
+		 * to avoid races with the disconnect/reconnect/suspend code.
+		 * In case we need to split the bio here, we need to get two references
+		 * atomically, otherwise we might deadlock when trying to submit the
+		 * second one! */
+		inc_ap_bio(mdev, 2);
+
+		D_ASSERT(e_enr == s_enr + 1);
+
+		drbd_make_request_common(mdev, &bp->bio1);
+		drbd_make_request_common(mdev, &bp->bio2);
+		bio_pair_release(bp);
+	}
+	return 0;
+}
+
+/* This is called by bio_add_page().  With this function we reduce
+ * the number of BIOs that span over multiple DRBD_MAX_SEGMENT_SIZEs
+ * units (was AL_EXTENTs).
+ *
+ * we do the calculation within the lower 32bit of the byte offsets,
+ * since we don't care for actual offset, but only check whether it
+ * would cross "activity log extent" boundaries.
+ *
+ * As long as the BIO is empty we have to allow at least one bvec,
+ * regardless of size and offset.  so the resulting bio may still
+ * cross extent boundaries.  those are dealt with (bio_split) in
+ * drbd_make_request_26.
+ */
+int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec)
+{
+	struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata;
+	unsigned int bio_offset =
+		(unsigned int)bvm->bi_sector << 9; /* 32 bit */
+	unsigned int bio_size = bvm->bi_size;
+	int limit, backing_limit;
+
+	limit = DRBD_MAX_SEGMENT_SIZE
+	      - ((bio_offset & (DRBD_MAX_SEGMENT_SIZE-1)) + bio_size);
+	if (limit < 0)
+		limit = 0;
+	if (bio_size == 0) {
+		if (limit <= bvec->bv_len)
+			limit = bvec->bv_len;
+	} else if (limit && get_ldev(mdev)) {
+		struct request_queue * const b =
+			mdev->ldev->backing_bdev->bd_disk->queue;
+		if (b->merge_bvec_fn && mdev->ldev->dc.use_bmbv) {
+			backing_limit = b->merge_bvec_fn(b, bvm, bvec);
+			limit = min(limit, backing_limit);
+		}
+		put_ldev(mdev);
+	}
+	return limit;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_req.h linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.h
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_req.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_req.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,326 @@
+/*
+   drbd_req.h
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2006-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 2006-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2006-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+
+   DRBD 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.
+
+   DRBD is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DRBD_REQ_H
+#define _DRBD_REQ_H
+
+#include <linux/module.h>
+
+#include <linux/slab.h>
+#include <linux/drbd.h>
+#include "drbd_int.h"
+#include "drbd_wrappers.h"
+
+/* The request callbacks will be called in irq context by the IDE drivers,
+   and in Softirqs/Tasklets/BH context by the SCSI drivers,
+   and by the receiver and worker in kernel-thread context.
+   Try to get the locking right :) */
+
+/*
+ * Objects of type struct drbd_request do only exist on a R_PRIMARY node, and are
+ * associated with IO requests originating from the block layer above us.
+ *
+ * There are quite a few things that may happen to a drbd request
+ * during its lifetime.
+ *
+ *  It will be created.
+ *  It will be marked with the intention to be
+ *    submitted to local disk and/or
+ *    send via the network.
+ *
+ *  It has to be placed on the transfer log and other housekeeping lists,
+ *  In case we have a network connection.
+ *
+ *  It may be identified as a concurrent (write) request
+ *    and be handled accordingly.
+ *
+ *  It may me handed over to the local disk subsystem.
+ *  It may be completed by the local disk subsystem,
+ *    either sucessfully or with io-error.
+ *  In case it is a READ request, and it failed locally,
+ *    it may be retried remotely.
+ *
+ *  It may be queued for sending.
+ *  It may be handed over to the network stack,
+ *    which may fail.
+ *  It may be acknowledged by the "peer" according to the wire_protocol in use.
+ *    this may be a negative ack.
+ *  It may receive a faked ack when the network connection is lost and the
+ *  transfer log is cleaned up.
+ *  Sending may be canceled due to network connection loss.
+ *  When it finally has outlived its time,
+ *    corresponding dirty bits in the resync-bitmap may be cleared or set,
+ *    it will be destroyed,
+ *    and completion will be signalled to the originator,
+ *      with or without "success".
+ */
+
+enum drbd_req_event {
+	created,
+	to_be_send,
+	to_be_submitted,
+
+	/* XXX yes, now I am inconsistent...
+	 * these two are not "events" but "actions"
+	 * oh, well... */
+	queue_for_net_write,
+	queue_for_net_read,
+
+	send_canceled,
+	send_failed,
+	handed_over_to_network,
+	connection_lost_while_pending,
+	recv_acked_by_peer,
+	write_acked_by_peer,
+	write_acked_by_peer_and_sis, /* and set_in_sync */
+	conflict_discarded_by_peer,
+	neg_acked,
+	barrier_acked, /* in protocol A and B */
+	data_received, /* (remote read) */
+
+	read_completed_with_error,
+	read_ahead_completed_with_error,
+	write_completed_with_error,
+	completed_ok,
+	nothing, /* for tracing only */
+};
+
+/* encoding of request states for now.  we don't actually need that many bits.
+ * we don't need to do atomic bit operations either, since most of the time we
+ * need to look at the connection state and/or manipulate some lists at the
+ * same time, so we should hold the request lock anyways.
+ */
+enum drbd_req_state_bits {
+	/* 210
+	 * 000: no local possible
+	 * 001: to be submitted
+	 *    UNUSED, we could map: 011: submitted, completion still pending
+	 * 110: completed ok
+	 * 010: completed with error
+	 */
+	__RQ_LOCAL_PENDING,
+	__RQ_LOCAL_COMPLETED,
+	__RQ_LOCAL_OK,
+
+	/* 76543
+	 * 00000: no network possible
+	 * 00001: to be send
+	 * 00011: to be send, on worker queue
+	 * 00101: sent, expecting recv_ack (B) or write_ack (C)
+	 * 11101: sent,
+	 *        recv_ack (B) or implicit "ack" (A),
+	 *        still waiting for the barrier ack.
+	 *        master_bio may already be completed and invalidated.
+	 * 11100: write_acked (C),
+	 *        data_received (for remote read, any protocol)
+	 *        or finally the barrier ack has arrived (B,A)...
+	 *        request can be freed
+	 * 01100: neg-acked (write, protocol C)
+	 *        or neg-d-acked (read, any protocol)
+	 *        or killed from the transfer log
+	 *        during cleanup after connection loss
+	 *        request can be freed
+	 * 01000: canceled or send failed...
+	 *        request can be freed
+	 */
+
+	/* if "SENT" is not set, yet, this can still fail or be canceled.
+	 * if "SENT" is set already, we still wait for an Ack packet.
+	 * when cleared, the master_bio may be completed.
+	 * in (B,A) the request object may still linger on the transaction log
+	 * until the corresponding barrier ack comes in */
+	__RQ_NET_PENDING,
+
+	/* If it is QUEUED, and it is a WRITE, it is also registered in the
+	 * transfer log. Currently we need this flag to avoid conflicts between
+	 * worker canceling the request and tl_clear_barrier killing it from
+	 * transfer log.  We should restructure the code so this conflict does
+	 * no longer occur. */
+	__RQ_NET_QUEUED,
+
+	/* well, actually only "handed over to the network stack".
+	 *
+	 * TODO can potentially be dropped because of the similar meaning
+	 * of RQ_NET_SENT and ~RQ_NET_QUEUED.
+	 * however it is not exactly the same. before we drop it
+	 * we must ensure that we can tell a request with network part
+	 * from a request without, regardless of what happens to it. */
+	__RQ_NET_SENT,
+
+	/* when set, the request may be freed (if RQ_NET_QUEUED is clear).
+	 * basically this means the corresponding P_BARRIER_ACK was received */
+	__RQ_NET_DONE,
+
+	/* whether or not we know (C) or pretend (B,A) that the write
+	 * was successfully written on the peer.
+	 */
+	__RQ_NET_OK,
+
+	/* peer called drbd_set_in_sync() for this write */
+	__RQ_NET_SIS,
+
+	/* keep this last, its for the RQ_NET_MASK */
+	__RQ_NET_MAX,
+};
+
+#define RQ_LOCAL_PENDING   (1UL << __RQ_LOCAL_PENDING)
+#define RQ_LOCAL_COMPLETED (1UL << __RQ_LOCAL_COMPLETED)
+#define RQ_LOCAL_OK        (1UL << __RQ_LOCAL_OK)
+
+#define RQ_LOCAL_MASK      ((RQ_LOCAL_OK << 1)-1) /* 0x07 */
+
+#define RQ_NET_PENDING     (1UL << __RQ_NET_PENDING)
+#define RQ_NET_QUEUED      (1UL << __RQ_NET_QUEUED)
+#define RQ_NET_SENT        (1UL << __RQ_NET_SENT)
+#define RQ_NET_DONE        (1UL << __RQ_NET_DONE)
+#define RQ_NET_OK          (1UL << __RQ_NET_OK)
+#define RQ_NET_SIS         (1UL << __RQ_NET_SIS)
+
+/* 0x1f8 */
+#define RQ_NET_MASK        (((1UL << __RQ_NET_MAX)-1) & ~RQ_LOCAL_MASK)
+
+/* epoch entries */
+static inline
+struct hlist_head *ee_hash_slot(struct drbd_conf *mdev, sector_t sector)
+{
+	BUG_ON(mdev->ee_hash_s == 0);
+	return mdev->ee_hash +
+		((unsigned int)(sector>>HT_SHIFT) % mdev->ee_hash_s);
+}
+
+/* transfer log (drbd_request objects) */
+static inline
+struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector)
+{
+	BUG_ON(mdev->tl_hash_s == 0);
+	return mdev->tl_hash +
+		((unsigned int)(sector>>HT_SHIFT) % mdev->tl_hash_s);
+}
+
+/* application reads (drbd_request objects) */
+static struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector)
+{
+	return mdev->app_reads_hash
+		+ ((unsigned int)(sector) % APP_R_HSIZE);
+}
+
+/* when we receive the answer for a read request,
+ * verify that we actually know about it */
+static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev,
+	u64 id, sector_t sector)
+{
+	struct hlist_head *slot = ar_hash_slot(mdev, sector);
+	struct hlist_node *n;
+	struct drbd_request *req;
+
+	hlist_for_each_entry(req, n, slot, colision) {
+		if ((unsigned long)req == (unsigned long)id) {
+			D_ASSERT(req->sector == sector);
+			return req;
+		}
+	}
+	return NULL;
+}
+
+static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
+	struct bio *bio_src)
+{
+	struct bio *bio;
+	struct drbd_request *req =
+		mempool_alloc(drbd_request_mempool, GFP_NOIO);
+	if (likely(req)) {
+		bio = bio_clone(bio_src, GFP_NOIO); /* XXX cannot fail?? */
+
+		req->rq_state    = 0;
+		req->mdev        = mdev;
+		req->master_bio  = bio_src;
+		req->private_bio = bio;
+		req->epoch       = 0;
+		req->sector      = bio->bi_sector;
+		req->size        = bio->bi_size;
+		req->start_time  = jiffies;
+		INIT_HLIST_NODE(&req->colision);
+		INIT_LIST_HEAD(&req->tl_requests);
+		INIT_LIST_HEAD(&req->w.list);
+
+		bio->bi_private  = req;
+		bio->bi_end_io   = drbd_endio_pri;
+		bio->bi_next     = NULL;
+	}
+	return req;
+}
+
+static inline void drbd_req_free(struct drbd_request *req)
+{
+	mempool_free(req, drbd_request_mempool);
+}
+
+static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2)
+{
+	return !((s1 + (l1>>9) <= s2) || (s1 >= s2 + (l2>>9)));
+}
+
+/* Short lived temporary struct on the stack.
+ * We could squirrel the error to be returned into
+ * bio->bi_size, or similar. But that would be too ugly. */
+struct bio_and_error {
+	struct bio *bio;
+	int error;
+};
+
+extern void _req_may_be_done(struct drbd_request *req,
+		struct bio_and_error *m);
+extern void __req_mod(struct drbd_request *req, enum drbd_req_event what,
+		struct bio_and_error *m);
+extern void complete_master_bio(struct drbd_conf *mdev,
+		struct bio_and_error *m);
+
+/* use this if you don't want to deal with calling complete_master_bio()
+ * outside the spinlock, e.g. when walking some list on cleanup. */
+static inline void _req_mod(struct drbd_request *req, enum drbd_req_event what)
+{
+	struct drbd_conf *mdev = req->mdev;
+	struct bio_and_error m;
+
+	/* __req_mod possibly frees req, do not touch req after that! */
+	__req_mod(req, what, &m);
+	if (m.bio)
+		complete_master_bio(mdev, &m);
+}
+
+/* completion of master bio is outside of spinlock.
+ * If you need it irqsave, do it your self! */
+static inline void req_mod(struct drbd_request *req,
+		enum drbd_req_event what)
+{
+	struct drbd_conf *mdev = req->mdev;
+	struct bio_and_error m;
+	spin_lock_irq(&mdev->req_lock);
+	__req_mod(req, what, &m);
+	spin_unlock_irq(&mdev->req_lock);
+
+	if (m.bio)
+		complete_master_bio(mdev, &m);
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_strings.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_strings.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_strings.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_strings.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+/*
+  drbd.h
+
+  This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+  Copyright (C) 2003-2008, LINBIT Information Technologies GmbH.
+  Copyright (C) 2003-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+  Copyright (C) 2003-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+  drbd 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.
+
+  drbd is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with drbd; see the file COPYING.  If not, write to
+  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/drbd.h>
+
+static const char *drbd_conn_s_names[] = {
+	[C_STANDALONE]       = "StandAlone",
+	[C_DISCONNECTING]    = "Disconnecting",
+	[C_UNCONNECTED]      = "Unconnected",
+	[C_TIMEOUT]          = "Timeout",
+	[C_BROKEN_PIPE]      = "BrokenPipe",
+	[C_NETWORK_FAILURE]  = "NetworkFailure",
+	[C_PROTOCOL_ERROR]   = "ProtocolError",
+	[C_WF_CONNECTION]    = "WFConnection",
+	[C_WF_REPORT_PARAMS] = "WFReportParams",
+	[C_TEAR_DOWN]        = "TearDown",
+	[C_CONNECTED]        = "Connected",
+	[C_STARTING_SYNC_S]  = "StartingSyncS",
+	[C_STARTING_SYNC_T]  = "StartingSyncT",
+	[C_WF_BITMAP_S]      = "WFBitMapS",
+	[C_WF_BITMAP_T]      = "WFBitMapT",
+	[C_WF_SYNC_UUID]     = "WFSyncUUID",
+	[C_SYNC_SOURCE]      = "SyncSource",
+	[C_SYNC_TARGET]      = "SyncTarget",
+	[C_PAUSED_SYNC_S]    = "PausedSyncS",
+	[C_PAUSED_SYNC_T]    = "PausedSyncT",
+	[C_VERIFY_S]         = "VerifyS",
+	[C_VERIFY_T]         = "VerifyT",
+};
+
+static const char *drbd_role_s_names[] = {
+	[R_PRIMARY]   = "Primary",
+	[R_SECONDARY] = "Secondary",
+	[R_UNKNOWN]   = "Unknown"
+};
+
+static const char *drbd_disk_s_names[] = {
+	[D_DISKLESS]     = "Diskless",
+	[D_ATTACHING]    = "Attaching",
+	[D_FAILED]       = "Failed",
+	[D_NEGOTIATING]  = "Negotiating",
+	[D_INCONSISTENT] = "Inconsistent",
+	[D_OUTDATED]     = "Outdated",
+	[D_UNKNOWN]      = "DUnknown",
+	[D_CONSISTENT]   = "Consistent",
+	[D_UP_TO_DATE]   = "UpToDate",
+};
+
+static const char *drbd_state_sw_errors[] = {
+	[-SS_TWO_PRIMARIES] = "Multiple primaries not allowed by config",
+	[-SS_NO_UP_TO_DATE_DISK] = "Refusing to be Primary without at least one UpToDate disk",
+	[-SS_NO_LOCAL_DISK] = "Can not resync without local disk",
+	[-SS_NO_REMOTE_DISK] = "Can not resync without remote disk",
+	[-SS_CONNECTED_OUTDATES] = "Refusing to be Outdated while Connected",
+	[-SS_PRIMARY_NOP] = "Refusing to be Primary while peer is not outdated",
+	[-SS_RESYNC_RUNNING] = "Can not start OV/resync since it is already active",
+	[-SS_ALREADY_STANDALONE] = "Can not disconnect a StandAlone device",
+	[-SS_CW_FAILED_BY_PEER] = "State change was refused by peer node",
+	[-SS_IS_DISKLESS] = "Device is diskless, the requested operation requires a disk",
+	[-SS_DEVICE_IN_USE] = "Device is held open by someone",
+	[-SS_NO_NET_CONFIG] = "Have no net/connection configuration",
+	[-SS_NO_VERIFY_ALG] = "Need a verify algorithm to start online verify",
+	[-SS_NEED_CONNECTION] = "Need a connection to start verify or resync",
+	[-SS_NOT_SUPPORTED] = "Peer does not support protocol",
+	[-SS_LOWER_THAN_OUTDATED] = "Disk state is lower than outdated",
+	[-SS_IN_TRANSIENT_STATE] = "In transient state, retry after next state change",
+	[-SS_CONCURRENT_ST_CHG] = "Concurrent state changes detected and aborted",
+};
+
+const char *drbd_conn_str(enum drbd_conns s)
+{
+	/* enums are unsigned... */
+	return s > C_PAUSED_SYNC_T ? "TOO_LARGE" : drbd_conn_s_names[s];
+}
+
+const char *drbd_role_str(enum drbd_role s)
+{
+	return s > R_SECONDARY   ? "TOO_LARGE" : drbd_role_s_names[s];
+}
+
+const char *drbd_disk_str(enum drbd_disk_state s)
+{
+	return s > D_UP_TO_DATE    ? "TOO_LARGE" : drbd_disk_s_names[s];
+}
+
+const char *drbd_set_st_err_str(enum drbd_state_ret_codes err)
+{
+	return err <= SS_AFTER_LAST_ERROR ? "TOO_SMALL" :
+	       err > SS_TWO_PRIMARIES ? "TOO_LARGE"
+			: drbd_state_sw_errors[-err];
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_vli.h linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_vli.h
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_vli.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_vli.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,351 @@
+/*
+-*- linux-c -*-
+   drbd_receiver.c
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DRBD_VLI_H
+#define _DRBD_VLI_H
+
+/*
+ * At a granularity of 4KiB storage represented per bit,
+ * and stroage sizes of several TiB,
+ * and possibly small-bandwidth replication,
+ * the bitmap transfer time can take much too long,
+ * if transmitted in plain text.
+ *
+ * We try to reduce the transfered bitmap information
+ * by encoding runlengths of bit polarity.
+ *
+ * We never actually need to encode a "zero" (runlengths are positive).
+ * But then we have to store the value of the first bit.
+ * The first bit of information thus shall encode if the first runlength
+ * gives the number of set or unset bits.
+ *
+ * We assume that large areas are either completely set or unset,
+ * which gives good compression with any runlength method,
+ * even when encoding the runlength as fixed size 32bit/64bit integers.
+ *
+ * Still, there may be areas where the polarity flips every few bits,
+ * and encoding the runlength sequence of those areas with fix size
+ * integers would be much worse than plaintext.
+ *
+ * We want to encode small runlength values with minimum code length,
+ * while still being able to encode a Huge run of all zeros.
+ *
+ * Thus we need a Variable Length Integer encoding, VLI.
+ *
+ * For some cases, we produce more code bits than plaintext input.
+ * We need to send incompressible chunks as plaintext, skip over them
+ * and then see if the next chunk compresses better.
+ *
+ * We don't care too much about "excellent" compression ratio for large
+ * runlengths (all set/all clear): whether we achieve a factor of 100
+ * or 1000 is not that much of an issue.
+ * We do not want to waste too much on short runlengths in the "noisy"
+ * parts of the bitmap, though.
+ *
+ * There are endless variants of VLI, we experimented with:
+ *  * simple byte-based
+ *  * various bit based with different code word length.
+ *
+ * To avoid yet an other configuration parameter (choice of bitmap compression
+ * algorithm) which was difficult to explain and tune, we just chose the one
+ * variant that turned out best in all test cases.
+ * Based on real world usage patterns, with device sizes ranging from a few GiB
+ * to several TiB, file server/mailserver/webserver/mysql/postgress,
+ * mostly idle to really busy, the all time winner (though sometimes only
+ * marginally better) is:
+ */
+
+/*
+ * encoding is "visualised" as
+ * __little endian__ bitstream, least significant bit first (left most)
+ *
+ * this particular encoding is chosen so that the prefix code
+ * starts as unary encoding the level, then modified so that
+ * 10 levels can be described in 8bit, with minimal overhead
+ * for the smaller levels.
+ *
+ * Number of data bits follow fibonacci sequence, with the exception of the
+ * last level (+1 data bit, so it makes 64bit total).  The only worse code when
+ * encoding bit polarity runlength is 1 plain bits => 2 code bits.
+prefix    data bits                                    max val  Nº data bits
+0 x                                                         0x2            1
+10 x                                                        0x4            1
+110 xx                                                      0x8            2
+1110 xxx                                                   0x10            3
+11110 xxx xx                                               0x30            5
+111110 xx xxxxxx                                          0x130            8
+11111100  xxxxxxxx xxxxx                                 0x2130           13
+11111110  xxxxxxxx xxxxxxxx xxxxx                      0x202130           21
+11111101  xxxxxxxx xxxxxxxx xxxxxxxx  xxxxxxxx xx   0x400202130           34
+11111111  xxxxxxxx xxxxxxxx xxxxxxxx  xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 56
+ * maximum encodable value: 0x100000400202130 == 2**56 + some */
+
+/* compression "table":
+ transmitted   x                                0.29
+ as plaintext x                                  ........................
+             x                                   ........................
+            x                                    ........................
+           x    0.59                         0.21........................
+          x      ........................................................
+         x       .. c ...................................................
+        x    0.44.. o ...................................................
+       x .......... d ...................................................
+      x  .......... e ...................................................
+     X.............   ...................................................
+    x.............. b ...................................................
+2.0x............... i ...................................................
+ #X................ t ...................................................
+ #................. s ...........................  plain bits  ..........
+-+-----------------------------------------------------------------------
+ 1             16              32                              64
+*/
+
+/* LEVEL: (total bits, prefix bits, prefix value),
+ * sorted ascending by number of total bits.
+ * The rest of the code table is calculated at compiletime from this. */
+
+/* fibonacci data 1, 1, ... */
+#define VLI_L_1_1() do { \
+	LEVEL( 2, 1, 0x00); \
+	LEVEL( 3, 2, 0x01); \
+	LEVEL( 5, 3, 0x03); \
+	LEVEL( 7, 4, 0x07); \
+	LEVEL(10, 5, 0x0f); \
+	LEVEL(14, 6, 0x1f); \
+	LEVEL(21, 8, 0x3f); \
+	LEVEL(29, 8, 0x7f); \
+	LEVEL(42, 8, 0xbf); \
+	LEVEL(64, 8, 0xff); \
+	} while (0)
+
+/* finds a suitable level to decode the least significant part of in.
+ * returns number of bits consumed.
+ *
+ * BUG() for bad input, as that would mean a buggy code table. */
+static inline int vli_decode_bits(u64 *out, const u64 in)
+{
+	u64 adj = 1;
+
+#define LEVEL(t,b,v)					\
+	do {						\
+		if ((in & ((1 << b) -1)) == v) {	\
+			*out = ((in & ((~0ULL) >> (64-t))) >> b) + adj;	\
+			return t;			\
+		}					\
+		adj += 1ULL << (t - b);			\
+	} while (0)
+
+	VLI_L_1_1();
+
+	/* NOT REACHED, if VLI_LEVELS code table is defined properly */
+	BUG();
+#undef LEVEL
+}
+
+/* return number of code bits needed,
+ * or negative error number */
+static inline int __vli_encode_bits(u64 *out, const u64 in)
+{
+	u64 max = 0;
+	u64 adj = 1;
+
+	if (in == 0)
+		return -EINVAL;
+
+#define LEVEL(t,b,v) do {		\
+		max += 1ULL << (t - b);	\
+		if (in <= max) {	\
+			if (out)	\
+				*out = ((in - adj) << b) | v;	\
+			return t;	\
+		}			\
+		adj = max + 1;		\
+	} while (0)
+
+	VLI_L_1_1();
+
+	return -EOVERFLOW;
+#undef LEVEL
+}
+
+#undef VLI_L_1_1
+
+/* code from here down is independend of actually used bit code */
+
+/*
+ * Code length is determined by some unique (e.g. unary) prefix.
+ * This encodes arbitrary bit length, not whole bytes: we have a bit-stream,
+ * not a byte stream.
+ */
+
+/* for the bitstream, we need a cursor */
+struct bitstream_cursor {
+	/* the current byte */
+	u8 *b;
+	/* the current bit within *b, nomalized: 0..7 */
+	unsigned int bit;
+};
+
+/* initialize cursor to point to first bit of stream */
+static inline void bitstream_cursor_reset(struct bitstream_cursor *cur, void *s)
+{
+	cur->b = s;
+	cur->bit = 0;
+}
+
+/* advance cursor by that many bits; maximum expected input value: 64,
+ * but depending on VLI implementation, it may be more. */
+static inline void bitstream_cursor_advance(struct bitstream_cursor *cur, unsigned int bits)
+{
+	bits += cur->bit;
+	cur->b = cur->b + (bits >> 3);
+	cur->bit = bits & 7;
+}
+
+/* the bitstream itself knows its length */
+struct bitstream {
+	struct bitstream_cursor cur;
+	unsigned char *buf;
+	size_t buf_len;		/* in bytes */
+
+	/* for input stream:
+	 * number of trailing 0 bits for padding
+	 * total number of valid bits in stream: buf_len * 8 - pad_bits */
+	unsigned int pad_bits;
+};
+
+static inline void bitstream_init(struct bitstream *bs, void *s, size_t len, unsigned int pad_bits)
+{
+	bs->buf = s;
+	bs->buf_len = len;
+	bs->pad_bits = pad_bits;
+	bitstream_cursor_reset(&bs->cur, bs->buf);
+}
+
+static inline void bitstream_rewind(struct bitstream *bs)
+{
+	bitstream_cursor_reset(&bs->cur, bs->buf);
+	memset(bs->buf, 0, bs->buf_len);
+}
+
+/* Put (at most 64) least significant bits of val into bitstream, and advance cursor.
+ * Ignores "pad_bits".
+ * Returns zero if bits == 0 (nothing to do).
+ * Returns number of bits used if successful.
+ *
+ * If there is not enough room left in bitstream,
+ * leaves bitstream unchanged and returns -ENOBUFS.
+ */
+static inline int bitstream_put_bits(struct bitstream *bs, u64 val, const unsigned int bits)
+{
+	unsigned char *b = bs->cur.b;
+	unsigned int tmp;
+
+	if (bits == 0)
+		return 0;
+
+	if ((bs->cur.b + ((bs->cur.bit + bits -1) >> 3)) - bs->buf >= bs->buf_len)
+		return -ENOBUFS;
+
+	/* paranoia: strip off hi bits; they should not be set anyways. */
+	if (bits < 64)
+		val &= ~0ULL >> (64 - bits);
+
+	*b++ |= (val & 0xff) << bs->cur.bit;
+
+	for (tmp = 8 - bs->cur.bit; tmp < bits; tmp += 8)
+		*b++ |= (val >> tmp) & 0xff;
+
+	bitstream_cursor_advance(&bs->cur, bits);
+	return bits;
+}
+
+/* Fetch (at most 64) bits from bitstream into *out, and advance cursor.
+ *
+ * If more than 64 bits are requested, returns -EINVAL and leave *out unchanged.
+ *
+ * If there are less than the requested number of valid bits left in the
+ * bitstream, still fetches all available bits.
+ *
+ * Returns number of actually fetched bits.
+ */
+static inline int bitstream_get_bits(struct bitstream *bs, u64 *out, int bits)
+{
+	u64 val;
+	unsigned int n;
+
+	if (bits > 64)
+		return -EINVAL;
+
+	if (bs->cur.b + ((bs->cur.bit + bs->pad_bits + bits -1) >> 3) - bs->buf >= bs->buf_len)
+		bits = ((bs->buf_len - (bs->cur.b - bs->buf)) << 3)
+			- bs->cur.bit - bs->pad_bits;
+
+	if (bits == 0) {
+		*out = 0;
+		return 0;
+	}
+
+	/* get the high bits */
+	val = 0;
+	n = (bs->cur.bit + bits + 7) >> 3;
+	/* n may be at most 9, if cur.bit + bits > 64 */
+	/* which means this copies at most 8 byte */
+	if (n) {
+		memcpy(&val, bs->cur.b+1, n - 1);
+		val = le64_to_cpu(val) << (8 - bs->cur.bit);
+	}
+
+	/* we still need the low bits */
+	val |= bs->cur.b[0] >> bs->cur.bit;
+
+	/* and mask out bits we don't want */
+	val &= ~0ULL >> (64 - bits);
+
+	bitstream_cursor_advance(&bs->cur, bits);
+	*out = val;
+
+	return bits;
+}
+
+/* encodes @in as vli into @bs;
+
+ * return values
+ *  > 0: number of bits successfully stored in bitstream
+ * -ENOBUFS @bs is full
+ * -EINVAL input zero (invalid)
+ * -EOVERFLOW input too large for this vli code (invalid)
+ */
+static inline int vli_encode_bits(struct bitstream *bs, u64 in)
+{
+	u64 code = code;
+	int bits = __vli_encode_bits(&code, in);
+
+	if (bits <= 0)
+		return bits;
+
+	return bitstream_put_bits(bs, code, bits);
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_worker.c linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_worker.c
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_worker.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_worker.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1510 @@
+/*
+   drbd_worker.c
+
+   This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+   Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
+   Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+   drbd 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.
+
+   drbd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+#include <linux/drbd.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+#include <linux/memcontrol.h>
+#include <linux/mm_inline.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/scatterlist.h>
+
+#include "drbd_int.h"
+#include "drbd_req.h"
+
+#define SLEEP_TIME (HZ/10)
+
+static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel);
+
+
+
+/* defined here:
+   drbd_md_io_complete
+   drbd_endio_write_sec
+   drbd_endio_read_sec
+   drbd_endio_pri
+
+ * more endio handlers:
+   atodb_endio in drbd_actlog.c
+   drbd_bm_async_io_complete in drbd_bitmap.c
+
+ * For all these callbacks, note the following:
+ * The callbacks will be called in irq context by the IDE drivers,
+ * and in Softirqs/Tasklets/BH context by the SCSI drivers.
+ * Try to get the locking right :)
+ *
+ */
+
+
+/* About the global_state_lock
+   Each state transition on an device holds a read lock. In case we have
+   to evaluate the sync after dependencies, we grab a write lock, because
+   we need stable states on all devices for that.  */
+rwlock_t global_state_lock;
+
+/* used for synchronous meta data and bitmap IO
+ * submitted by drbd_md_sync_page_io()
+ */
+void drbd_md_io_complete(struct bio *bio, int error)
+{
+	struct drbd_md_io *md_io;
+
+	md_io = (struct drbd_md_io *)bio->bi_private;
+	md_io->error = error;
+
+	complete(&md_io->event);
+}
+
+/* reads on behalf of the partner,
+ * "submitted" by the receiver
+ */
+void drbd_endio_read_sec(struct bio *bio, int error) __releases(local)
+{
+	unsigned long flags = 0;
+	struct drbd_epoch_entry *e = NULL;
+	struct drbd_conf *mdev;
+	int uptodate = bio_flagged(bio, BIO_UPTODATE);
+
+	e = bio->bi_private;
+	mdev = e->mdev;
+
+	if (error)
+		dev_warn(DEV, "read: error=%d s=%llus\n", error,
+				(unsigned long long)e->sector);
+	if (!error && !uptodate) {
+		dev_warn(DEV, "read: setting error to -EIO s=%llus\n",
+				(unsigned long long)e->sector);
+		/* strange behavior of some lower level drivers...
+		 * fail the request by clearing the uptodate flag,
+		 * but do not return any error?! */
+		error = -EIO;
+	}
+
+	D_ASSERT(e->block_id != ID_VACANT);
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	mdev->read_cnt += e->size >> 9;
+	list_del(&e->w.list);
+	if (list_empty(&mdev->read_ee))
+		wake_up(&mdev->ee_wait);
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	drbd_chk_io_error(mdev, error, FALSE);
+	drbd_queue_work(&mdev->data.work, &e->w);
+	put_ldev(mdev);
+}
+
+/* writes on behalf of the partner, or resync writes,
+ * "submitted" by the receiver.
+ */
+void drbd_endio_write_sec(struct bio *bio, int error) __releases(local)
+{
+	unsigned long flags = 0;
+	struct drbd_epoch_entry *e = NULL;
+	struct drbd_conf *mdev;
+	sector_t e_sector;
+	int do_wake;
+	int is_syncer_req;
+	int do_al_complete_io;
+	int uptodate = bio_flagged(bio, BIO_UPTODATE);
+	int is_barrier = bio_rw_flagged(bio, BIO_RW_BARRIER);
+
+	e = bio->bi_private;
+	mdev = e->mdev;
+
+	if (error)
+		dev_warn(DEV, "write: error=%d s=%llus\n", error,
+				(unsigned long long)e->sector);
+	if (!error && !uptodate) {
+		dev_warn(DEV, "write: setting error to -EIO s=%llus\n",
+				(unsigned long long)e->sector);
+		/* strange behavior of some lower level drivers...
+		 * fail the request by clearing the uptodate flag,
+		 * but do not return any error?! */
+		error = -EIO;
+	}
+
+	/* error == -ENOTSUPP would be a better test,
+	 * alas it is not reliable */
+	if (error && is_barrier && e->flags & EE_IS_BARRIER) {
+		drbd_bump_write_ordering(mdev, WO_bdev_flush);
+		spin_lock_irqsave(&mdev->req_lock, flags);
+		list_del(&e->w.list);
+		e->w.cb = w_e_reissue;
+		/* put_ldev actually happens below, once we come here again. */
+		__release(local);
+		spin_unlock_irqrestore(&mdev->req_lock, flags);
+		drbd_queue_work(&mdev->data.work, &e->w);
+		return;
+	}
+
+	D_ASSERT(e->block_id != ID_VACANT);
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	mdev->writ_cnt += e->size >> 9;
+	is_syncer_req = is_syncer_block_id(e->block_id);
+
+	/* after we moved e to done_ee,
+	 * we may no longer access it,
+	 * it may be freed/reused already!
+	 * (as soon as we release the req_lock) */
+	e_sector = e->sector;
+	do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
+
+	list_del(&e->w.list); /* has been on active_ee or sync_ee */
+	list_add_tail(&e->w.list, &mdev->done_ee);
+
+	/* No hlist_del_init(&e->colision) here, we did not send the Ack yet,
+	 * neither did we wake possibly waiting conflicting requests.
+	 * done from "drbd_process_done_ee" within the appropriate w.cb
+	 * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */
+
+	do_wake = is_syncer_req
+		? list_empty(&mdev->sync_ee)
+		: list_empty(&mdev->active_ee);
+
+	if (error)
+		__drbd_chk_io_error(mdev, FALSE);
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	if (is_syncer_req)
+		drbd_rs_complete_io(mdev, e_sector);
+
+	if (do_wake)
+		wake_up(&mdev->ee_wait);
+
+	if (do_al_complete_io)
+		drbd_al_complete_io(mdev, e_sector);
+
+	wake_asender(mdev);
+	put_ldev(mdev);
+
+}
+
+/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
+ */
+void drbd_endio_pri(struct bio *bio, int error)
+{
+	unsigned long flags;
+	struct drbd_request *req = bio->bi_private;
+	struct drbd_conf *mdev = req->mdev;
+	struct bio_and_error m;
+	enum drbd_req_event what;
+	int uptodate = bio_flagged(bio, BIO_UPTODATE);
+
+	if (error)
+		dev_warn(DEV, "p %s: error=%d\n",
+			 bio_data_dir(bio) == WRITE ? "write" : "read", error);
+	if (!error && !uptodate) {
+		dev_warn(DEV, "p %s: setting error to -EIO\n",
+			 bio_data_dir(bio) == WRITE ? "write" : "read");
+		/* strange behavior of some lower level drivers...
+		 * fail the request by clearing the uptodate flag,
+		 * but do not return any error?! */
+		error = -EIO;
+	}
+
+	/* to avoid recursion in __req_mod */
+	if (unlikely(error)) {
+		what = (bio_data_dir(bio) == WRITE)
+			? write_completed_with_error
+			: (bio_rw(bio) == READA)
+			  ? read_completed_with_error
+			  : read_ahead_completed_with_error;
+	} else
+		what = completed_ok;
+
+	bio_put(req->private_bio);
+	req->private_bio = ERR_PTR(error);
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+	__req_mod(req, what, &m);
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	if (m.bio)
+		complete_master_bio(mdev, &m);
+}
+
+int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_request *req = container_of(w, struct drbd_request, w);
+
+	/* NOTE: mdev->ldev can be NULL by the time we get here! */
+	/* D_ASSERT(mdev->ldev->dc.on_io_error != EP_PASS_ON); */
+
+	/* the only way this callback is scheduled is from _req_may_be_done,
+	 * when it is done and had a local write error, see comments there */
+	drbd_req_free(req);
+
+	return TRUE;
+}
+
+int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_request *req = container_of(w, struct drbd_request, w);
+
+	/* We should not detach for read io-error,
+	 * but try to WRITE the P_DATA_REPLY to the failed location,
+	 * to give the disk the chance to relocate that block */
+
+	spin_lock_irq(&mdev->req_lock);
+	if (cancel ||
+	    mdev->state.conn < C_CONNECTED ||
+	    mdev->state.pdsk <= D_INCONSISTENT) {
+		_req_mod(req, send_canceled);
+		spin_unlock_irq(&mdev->req_lock);
+		dev_alert(DEV, "WE ARE LOST. Local IO failure, no peer.\n");
+		return 1;
+	}
+	spin_unlock_irq(&mdev->req_lock);
+
+	return w_send_read_req(mdev, w, 0);
+}
+
+int w_resync_inactive(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	ERR_IF(cancel) return 1;
+	dev_err(DEV, "resync inactive, but callback triggered??\n");
+	return 1; /* Simply ignore this! */
+}
+
+void drbd_csum(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest)
+{
+	struct hash_desc desc;
+	struct scatterlist sg;
+	struct bio_vec *bvec;
+	int i;
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	sg_init_table(&sg, 1);
+	crypto_hash_init(&desc);
+
+	__bio_for_each_segment(bvec, bio, i, 0) {
+		sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+		crypto_hash_update(&desc, &sg, sg.length);
+	}
+	crypto_hash_final(&desc, digest);
+}
+
+static int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	int digest_size;
+	void *digest;
+	int ok;
+
+	D_ASSERT(e->block_id == DRBD_MAGIC + 0xbeef);
+
+	if (unlikely(cancel)) {
+		drbd_free_ee(mdev, e);
+		return 1;
+	}
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		digest_size = crypto_hash_digestsize(mdev->csums_tfm);
+		digest = kmalloc(digest_size, GFP_NOIO);
+		if (digest) {
+			drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest);
+
+			inc_rs_pending(mdev);
+			ok = drbd_send_drequest_csum(mdev,
+						     e->sector,
+						     e->size,
+						     digest,
+						     digest_size,
+						     P_CSUM_RS_REQUEST);
+			kfree(digest);
+		} else {
+			dev_err(DEV, "kmalloc() of digest failed.\n");
+			ok = 0;
+		}
+	} else
+		ok = 1;
+
+	drbd_free_ee(mdev, e);
+
+	if (unlikely(!ok))
+		dev_err(DEV, "drbd_send_drequest(..., csum) failed\n");
+	return ok;
+}
+
+#define GFP_TRY	(__GFP_HIGHMEM | __GFP_NOWARN)
+
+static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size)
+{
+	struct drbd_epoch_entry *e;
+
+	if (!get_ldev(mdev))
+		return 0;
+
+	/* GFP_TRY, because if there is no memory available right now, this may
+	 * be rescheduled for later. It is "only" background resync, after all. */
+	e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY);
+	if (!e) {
+		put_ldev(mdev);
+		return 2;
+	}
+
+	spin_lock_irq(&mdev->req_lock);
+	list_add(&e->w.list, &mdev->read_ee);
+	spin_unlock_irq(&mdev->req_lock);
+
+	e->private_bio->bi_end_io = drbd_endio_read_sec;
+	e->private_bio->bi_rw = READ;
+	e->w.cb = w_e_send_csum;
+
+	mdev->read_cnt += size >> 9;
+	drbd_generic_make_request(mdev, DRBD_FAULT_RS_RD, e->private_bio);
+
+	return 1;
+}
+
+void resync_timer_fn(unsigned long data)
+{
+	unsigned long flags;
+	struct drbd_conf *mdev = (struct drbd_conf *) data;
+	int queue;
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+
+	if (likely(!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags))) {
+		queue = 1;
+		if (mdev->state.conn == C_VERIFY_S)
+			mdev->resync_work.cb = w_make_ov_request;
+		else
+			mdev->resync_work.cb = w_make_resync_request;
+	} else {
+		queue = 0;
+		mdev->resync_work.cb = w_resync_inactive;
+	}
+
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	/* harmless race: list_empty outside data.work.q_lock */
+	if (list_empty(&mdev->resync_work.list) && queue)
+		drbd_queue_work(&mdev->data.work, &mdev->resync_work);
+}
+
+int w_make_resync_request(struct drbd_conf *mdev,
+		struct drbd_work *w, int cancel)
+{
+	unsigned long bit;
+	sector_t sector;
+	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
+	int max_segment_size = queue_max_segment_size(mdev->rq_queue);
+	int number, i, size, pe, mx;
+	int align, queued, sndbuf;
+
+	if (unlikely(cancel))
+		return 1;
+
+	if (unlikely(mdev->state.conn < C_CONNECTED)) {
+		dev_err(DEV, "Confused in w_make_resync_request()! cstate < Connected");
+		return 0;
+	}
+
+	if (mdev->state.conn != C_SYNC_TARGET)
+		dev_err(DEV, "%s in w_make_resync_request\n",
+			drbd_conn_str(mdev->state.conn));
+
+	if (!get_ldev(mdev)) {
+		/* Since we only need to access mdev->rsync a
+		   get_ldev_if_state(mdev,D_FAILED) would be sufficient, but
+		   to continue resync with a broken disk makes no sense at
+		   all */
+		dev_err(DEV, "Disk broke down during resync!\n");
+		mdev->resync_work.cb = w_resync_inactive;
+		return 1;
+	}
+
+	number = SLEEP_TIME * mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
+	pe = atomic_read(&mdev->rs_pending_cnt);
+
+	mutex_lock(&mdev->data.mutex);
+	if (mdev->data.socket)
+		mx = mdev->data.socket->sk->sk_rcvbuf / sizeof(struct p_block_req);
+	else
+		mx = 1;
+	mutex_unlock(&mdev->data.mutex);
+
+	/* For resync rates >160MB/sec, allow more pending RS requests */
+	if (number > mx)
+		mx = number;
+
+	/* Limit the number of pending RS requests to no more than the peer's receive buffer */
+	if ((pe + number) > mx) {
+		number = mx - pe;
+	}
+
+	for (i = 0; i < number; i++) {
+		/* Stop generating RS requests, when half of the send buffer is filled */
+		mutex_lock(&mdev->data.mutex);
+		if (mdev->data.socket) {
+			queued = mdev->data.socket->sk->sk_wmem_queued;
+			sndbuf = mdev->data.socket->sk->sk_sndbuf;
+		} else {
+			queued = 1;
+			sndbuf = 0;
+		}
+		mutex_unlock(&mdev->data.mutex);
+		if (queued > sndbuf / 2)
+			goto requeue;
+
+next_sector:
+		size = BM_BLOCK_SIZE;
+		bit  = drbd_bm_find_next(mdev, mdev->bm_resync_fo);
+
+		if (bit == -1UL) {
+			mdev->bm_resync_fo = drbd_bm_bits(mdev);
+			mdev->resync_work.cb = w_resync_inactive;
+			put_ldev(mdev);
+			return 1;
+		}
+
+		sector = BM_BIT_TO_SECT(bit);
+
+		if (drbd_try_rs_begin_io(mdev, sector)) {
+			mdev->bm_resync_fo = bit;
+			goto requeue;
+		}
+		mdev->bm_resync_fo = bit + 1;
+
+		if (unlikely(drbd_bm_test_bit(mdev, bit) == 0)) {
+			drbd_rs_complete_io(mdev, sector);
+			goto next_sector;
+		}
+
+#if DRBD_MAX_SEGMENT_SIZE > BM_BLOCK_SIZE
+		/* try to find some adjacent bits.
+		 * we stop if we have already the maximum req size.
+		 *
+		 * Additionally always align bigger requests, in order to
+		 * be prepared for all stripe sizes of software RAIDs.
+		 *
+		 * we _do_ care about the agreed-upon q->max_segment_size
+		 * here, as splitting up the requests on the other side is more
+		 * difficult.  the consequence is, that on lvm and md and other
+		 * "indirect" devices, this is dead code, since
+		 * q->max_segment_size will be PAGE_SIZE.
+		 */
+		align = 1;
+		for (;;) {
+			if (size + BM_BLOCK_SIZE > max_segment_size)
+				break;
+
+			/* Be always aligned */
+			if (sector & ((1<<(align+3))-1))
+				break;
+
+			/* do not cross extent boundaries */
+			if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0)
+				break;
+			/* now, is it actually dirty, after all?
+			 * caution, drbd_bm_test_bit is tri-state for some
+			 * obscure reason; ( b == 0 ) would get the out-of-band
+			 * only accidentally right because of the "oddly sized"
+			 * adjustment below */
+			if (drbd_bm_test_bit(mdev, bit+1) != 1)
+				break;
+			bit++;
+			size += BM_BLOCK_SIZE;
+			if ((BM_BLOCK_SIZE << align) <= size)
+				align++;
+			i++;
+		}
+		/* if we merged some,
+		 * reset the offset to start the next drbd_bm_find_next from */
+		if (size > BM_BLOCK_SIZE)
+			mdev->bm_resync_fo = bit + 1;
+#endif
+
+		/* adjust very last sectors, in case we are oddly sized */
+		if (sector + (size>>9) > capacity)
+			size = (capacity-sector)<<9;
+		if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) {
+			switch (read_for_csum(mdev, sector, size)) {
+			case 0: /* Disk failure*/
+				put_ldev(mdev);
+				return 0;
+			case 2: /* Allocation failed */
+				drbd_rs_complete_io(mdev, sector);
+				mdev->bm_resync_fo = BM_SECT_TO_BIT(sector);
+				goto requeue;
+			/* case 1: everything ok */
+			}
+		} else {
+			inc_rs_pending(mdev);
+			if (!drbd_send_drequest(mdev, P_RS_DATA_REQUEST,
+					       sector, size, ID_SYNCER)) {
+				dev_err(DEV, "drbd_send_drequest() failed, aborting...\n");
+				dec_rs_pending(mdev);
+				put_ldev(mdev);
+				return 0;
+			}
+		}
+	}
+
+	if (mdev->bm_resync_fo >= drbd_bm_bits(mdev)) {
+		/* last syncer _request_ was sent,
+		 * but the P_RS_DATA_REPLY not yet received.  sync will end (and
+		 * next sync group will resume), as soon as we receive the last
+		 * resync data block, and the last bit is cleared.
+		 * until then resync "work" is "inactive" ...
+		 */
+		mdev->resync_work.cb = w_resync_inactive;
+		put_ldev(mdev);
+		return 1;
+	}
+
+ requeue:
+	mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME);
+	put_ldev(mdev);
+	return 1;
+}
+
+static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	int number, i, size;
+	sector_t sector;
+	const sector_t capacity = drbd_get_capacity(mdev->this_bdev);
+
+	if (unlikely(cancel))
+		return 1;
+
+	if (unlikely(mdev->state.conn < C_CONNECTED)) {
+		dev_err(DEV, "Confused in w_make_ov_request()! cstate < Connected");
+		return 0;
+	}
+
+	number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
+	if (atomic_read(&mdev->rs_pending_cnt) > number)
+		goto requeue;
+
+	number -= atomic_read(&mdev->rs_pending_cnt);
+
+	sector = mdev->ov_position;
+	for (i = 0; i < number; i++) {
+		if (sector >= capacity) {
+			mdev->resync_work.cb = w_resync_inactive;
+			return 1;
+		}
+
+		size = BM_BLOCK_SIZE;
+
+		if (drbd_try_rs_begin_io(mdev, sector)) {
+			mdev->ov_position = sector;
+			goto requeue;
+		}
+
+		if (sector + (size>>9) > capacity)
+			size = (capacity-sector)<<9;
+
+		inc_rs_pending(mdev);
+		if (!drbd_send_ov_request(mdev, sector, size)) {
+			dec_rs_pending(mdev);
+			return 0;
+		}
+		sector += BM_SECT_PER_BIT;
+	}
+	mdev->ov_position = sector;
+
+ requeue:
+	mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME);
+	return 1;
+}
+
+
+int w_ov_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	kfree(w);
+	ov_oos_print(mdev);
+	drbd_resync_finished(mdev);
+
+	return 1;
+}
+
+static int w_resync_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	kfree(w);
+
+	drbd_resync_finished(mdev);
+
+	return 1;
+}
+
+int drbd_resync_finished(struct drbd_conf *mdev)
+{
+	unsigned long db, dt, dbdt;
+	unsigned long n_oos;
+	union drbd_state os, ns;
+	struct drbd_work *w;
+	char *khelper_cmd = NULL;
+
+	/* Remove all elements from the resync LRU. Since future actions
+	 * might set bits in the (main) bitmap, then the entries in the
+	 * resync LRU would be wrong. */
+	if (drbd_rs_del_all(mdev)) {
+		/* In case this is not possible now, most probably because
+		 * there are P_RS_DATA_REPLY Packets lingering on the worker's
+		 * queue (or even the read operations for those packets
+		 * is not finished by now).   Retry in 100ms. */
+
+		drbd_kick_lo(mdev);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ / 10);
+		w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC);
+		if (w) {
+			w->cb = w_resync_finished;
+			drbd_queue_work(&mdev->data.work, w);
+			return 1;
+		}
+		dev_err(DEV, "Warn failed to drbd_rs_del_all() and to kmalloc(w).\n");
+	}
+
+	dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
+	if (dt <= 0)
+		dt = 1;
+	db = mdev->rs_total;
+	dbdt = Bit2KB(db/dt);
+	mdev->rs_paused /= HZ;
+
+	if (!get_ldev(mdev))
+		goto out;
+
+	spin_lock_irq(&mdev->req_lock);
+	os = mdev->state;
+
+	/* This protects us against multiple calls (that can happen in the presence
+	   of application IO), and against connectivity loss just before we arrive here. */
+	if (os.conn <= C_CONNECTED)
+		goto out_unlock;
+
+	ns = os;
+	ns.conn = C_CONNECTED;
+
+	dev_info(DEV, "%s done (total %lu sec; paused %lu sec; %lu K/sec)\n",
+	     (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) ?
+	     "Online verify " : "Resync",
+	     dt + mdev->rs_paused, mdev->rs_paused, dbdt);
+
+	n_oos = drbd_bm_total_weight(mdev);
+
+	if (os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) {
+		if (n_oos) {
+			dev_alert(DEV, "Online verify found %lu %dk block out of sync!\n",
+			      n_oos, Bit2KB(1));
+			khelper_cmd = "out-of-sync";
+		}
+	} else {
+		D_ASSERT((n_oos - mdev->rs_failed) == 0);
+
+		if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T)
+			khelper_cmd = "after-resync-target";
+
+		if (mdev->csums_tfm && mdev->rs_total) {
+			const unsigned long s = mdev->rs_same_csum;
+			const unsigned long t = mdev->rs_total;
+			const int ratio =
+				(t == 0)     ? 0 :
+			(t < 100000) ? ((s*100)/t) : (s/(t/100));
+			dev_info(DEV, "%u %% had equal check sums, eliminated: %luK; "
+			     "transferred %luK total %luK\n",
+			     ratio,
+			     Bit2KB(mdev->rs_same_csum),
+			     Bit2KB(mdev->rs_total - mdev->rs_same_csum),
+			     Bit2KB(mdev->rs_total));
+		}
+	}
+
+	if (mdev->rs_failed) {
+		dev_info(DEV, "            %lu failed blocks\n", mdev->rs_failed);
+
+		if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T) {
+			ns.disk = D_INCONSISTENT;
+			ns.pdsk = D_UP_TO_DATE;
+		} else {
+			ns.disk = D_UP_TO_DATE;
+			ns.pdsk = D_INCONSISTENT;
+		}
+	} else {
+		ns.disk = D_UP_TO_DATE;
+		ns.pdsk = D_UP_TO_DATE;
+
+		if (os.conn == C_SYNC_TARGET || os.conn == C_PAUSED_SYNC_T) {
+			if (mdev->p_uuid) {
+				int i;
+				for (i = UI_BITMAP ; i <= UI_HISTORY_END ; i++)
+					_drbd_uuid_set(mdev, i, mdev->p_uuid[i]);
+				drbd_uuid_set(mdev, UI_BITMAP, mdev->ldev->md.uuid[UI_CURRENT]);
+				_drbd_uuid_set(mdev, UI_CURRENT, mdev->p_uuid[UI_CURRENT]);
+			} else {
+				dev_err(DEV, "mdev->p_uuid is NULL! BUG\n");
+			}
+		}
+
+		drbd_uuid_set_bm(mdev, 0UL);
+
+		if (mdev->p_uuid) {
+			/* Now the two UUID sets are equal, update what we
+			 * know of the peer. */
+			int i;
+			for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++)
+				mdev->p_uuid[i] = mdev->ldev->md.uuid[i];
+		}
+	}
+
+	_drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
+out_unlock:
+	spin_unlock_irq(&mdev->req_lock);
+	put_ldev(mdev);
+out:
+	mdev->rs_total  = 0;
+	mdev->rs_failed = 0;
+	mdev->rs_paused = 0;
+	mdev->ov_start_sector = 0;
+
+	if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) {
+		dev_warn(DEV, "Writing the whole bitmap, due to failed kmalloc\n");
+		drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished");
+	}
+
+	if (khelper_cmd)
+		drbd_khelper(mdev, khelper_cmd);
+
+	return 1;
+}
+
+/* helper */
+static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
+{
+	if (drbd_bio_has_active_page(e->private_bio)) {
+		/* This might happen if sendpage() has not finished */
+		spin_lock_irq(&mdev->req_lock);
+		list_add_tail(&e->w.list, &mdev->net_ee);
+		spin_unlock_irq(&mdev->req_lock);
+	} else
+		drbd_free_ee(mdev, e);
+}
+
+/**
+ * w_e_end_data_req() - Worker callback, to send a P_DATA_REPLY packet in response to a P_DATA_REQUEST
+ * @mdev:	DRBD device.
+ * @w:		work object.
+ * @cancel:	The connection will be closed anyways
+ */
+int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	int ok;
+
+	if (unlikely(cancel)) {
+		drbd_free_ee(mdev, e);
+		dec_unacked(mdev);
+		return 1;
+	}
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		ok = drbd_send_block(mdev, P_DATA_REPLY, e);
+	} else {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Sending NegDReply. sector=%llus.\n",
+			    (unsigned long long)e->sector);
+
+		ok = drbd_send_ack(mdev, P_NEG_DREPLY, e);
+	}
+
+	dec_unacked(mdev);
+
+	move_to_net_ee_or_free(mdev, e);
+
+	if (unlikely(!ok))
+		dev_err(DEV, "drbd_send_block() failed\n");
+	return ok;
+}
+
+/**
+ * w_e_end_rsdata_req() - Worker callback to send a P_RS_DATA_REPLY packet in response to a P_RS_DATA_REQUESTRS
+ * @mdev:	DRBD device.
+ * @w:		work object.
+ * @cancel:	The connection will be closed anyways
+ */
+int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	int ok;
+
+	if (unlikely(cancel)) {
+		drbd_free_ee(mdev, e);
+		dec_unacked(mdev);
+		return 1;
+	}
+
+	if (get_ldev_if_state(mdev, D_FAILED)) {
+		drbd_rs_complete_io(mdev, e->sector);
+		put_ldev(mdev);
+	}
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		if (likely(mdev->state.pdsk >= D_INCONSISTENT)) {
+			inc_rs_pending(mdev);
+			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e);
+		} else {
+			if (__ratelimit(&drbd_ratelimit_state))
+				dev_err(DEV, "Not sending RSDataReply, "
+				    "partner DISKLESS!\n");
+			ok = 1;
+		}
+	} else {
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Sending NegRSDReply. sector %llus.\n",
+			    (unsigned long long)e->sector);
+
+		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
+
+		/* update resync data with failure */
+		drbd_rs_failed_io(mdev, e->sector, e->size);
+	}
+
+	dec_unacked(mdev);
+
+	move_to_net_ee_or_free(mdev, e);
+
+	if (unlikely(!ok))
+		dev_err(DEV, "drbd_send_block() failed\n");
+	return ok;
+}
+
+int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct digest_info *di;
+	int digest_size;
+	void *digest = NULL;
+	int ok, eq = 0;
+
+	if (unlikely(cancel)) {
+		drbd_free_ee(mdev, e);
+		dec_unacked(mdev);
+		return 1;
+	}
+
+	drbd_rs_complete_io(mdev, e->sector);
+
+	di = (struct digest_info *)(unsigned long)e->block_id;
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		/* quick hack to try to avoid a race against reconfiguration.
+		 * a real fix would be much more involved,
+		 * introducing more locking mechanisms */
+		if (mdev->csums_tfm) {
+			digest_size = crypto_hash_digestsize(mdev->csums_tfm);
+			D_ASSERT(digest_size == di->digest_size);
+			digest = kmalloc(digest_size, GFP_NOIO);
+		}
+		if (digest) {
+			drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest);
+			eq = !memcmp(digest, di->digest, digest_size);
+			kfree(digest);
+		}
+
+		if (eq) {
+			drbd_set_in_sync(mdev, e->sector, e->size);
+			mdev->rs_same_csum++;
+			ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
+		} else {
+			inc_rs_pending(mdev);
+			e->block_id = ID_SYNCER;
+			ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e);
+		}
+	} else {
+		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Sending NegDReply. I guess it gets messy.\n");
+	}
+
+	dec_unacked(mdev);
+
+	kfree(di);
+
+	move_to_net_ee_or_free(mdev, e);
+
+	if (unlikely(!ok))
+		dev_err(DEV, "drbd_send_block/ack() failed\n");
+	return ok;
+}
+
+int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	int digest_size;
+	void *digest;
+	int ok = 1;
+
+	if (unlikely(cancel))
+		goto out;
+
+	if (unlikely(!drbd_bio_uptodate(e->private_bio)))
+		goto out;
+
+	digest_size = crypto_hash_digestsize(mdev->verify_tfm);
+	/* FIXME if this allocation fails, online verify will not terminate! */
+	digest = kmalloc(digest_size, GFP_NOIO);
+	if (digest) {
+		drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest);
+		inc_rs_pending(mdev);
+		ok = drbd_send_drequest_csum(mdev, e->sector, e->size,
+					     digest, digest_size, P_OV_REPLY);
+		if (!ok)
+			dec_rs_pending(mdev);
+		kfree(digest);
+	}
+
+out:
+	drbd_free_ee(mdev, e);
+
+	dec_unacked(mdev);
+
+	return ok;
+}
+
+void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size)
+{
+	if (mdev->ov_last_oos_start + mdev->ov_last_oos_size == sector) {
+		mdev->ov_last_oos_size += size>>9;
+	} else {
+		mdev->ov_last_oos_start = sector;
+		mdev->ov_last_oos_size = size>>9;
+	}
+	drbd_set_out_of_sync(mdev, sector, size);
+	set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags);
+}
+
+int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	struct digest_info *di;
+	int digest_size;
+	void *digest;
+	int ok, eq = 0;
+
+	if (unlikely(cancel)) {
+		drbd_free_ee(mdev, e);
+		dec_unacked(mdev);
+		return 1;
+	}
+
+	/* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all
+	 * the resync lru has been cleaned up already */
+	drbd_rs_complete_io(mdev, e->sector);
+
+	di = (struct digest_info *)(unsigned long)e->block_id;
+
+	if (likely(drbd_bio_uptodate(e->private_bio))) {
+		digest_size = crypto_hash_digestsize(mdev->verify_tfm);
+		digest = kmalloc(digest_size, GFP_NOIO);
+		if (digest) {
+			drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest);
+
+			D_ASSERT(digest_size == di->digest_size);
+			eq = !memcmp(digest, di->digest, digest_size);
+			kfree(digest);
+		}
+	} else {
+		ok = drbd_send_ack(mdev, P_NEG_RS_DREPLY, e);
+		if (__ratelimit(&drbd_ratelimit_state))
+			dev_err(DEV, "Sending NegDReply. I guess it gets messy.\n");
+	}
+
+	dec_unacked(mdev);
+
+	kfree(di);
+
+	if (!eq)
+		drbd_ov_oos_found(mdev, e->sector, e->size);
+	else
+		ov_oos_print(mdev);
+
+	ok = drbd_send_ack_ex(mdev, P_OV_RESULT, e->sector, e->size,
+			      eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
+
+	drbd_free_ee(mdev, e);
+
+	if (--mdev->ov_left == 0) {
+		ov_oos_print(mdev);
+		drbd_resync_finished(mdev);
+	}
+
+	return ok;
+}
+
+int w_prev_work_done(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w);
+	complete(&b->done);
+	return 1;
+}
+
+int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_tl_epoch *b = container_of(w, struct drbd_tl_epoch, w);
+	struct p_barrier *p = &mdev->data.sbuf.barrier;
+	int ok = 1;
+
+	/* really avoid racing with tl_clear.  w.cb may have been referenced
+	 * just before it was reassigned and re-queued, so double check that.
+	 * actually, this race was harmless, since we only try to send the
+	 * barrier packet here, and otherwise do nothing with the object.
+	 * but compare with the head of w_clear_epoch */
+	spin_lock_irq(&mdev->req_lock);
+	if (w->cb != w_send_barrier || mdev->state.conn < C_CONNECTED)
+		cancel = 1;
+	spin_unlock_irq(&mdev->req_lock);
+	if (cancel)
+		return 1;
+
+	if (!drbd_get_data_sock(mdev))
+		return 0;
+	p->barrier = b->br_number;
+	/* inc_ap_pending was done where this was queued.
+	 * dec_ap_pending will be done in got_BarrierAck
+	 * or (on connection loss) in w_clear_epoch.  */
+	ok = _drbd_send_cmd(mdev, mdev->data.socket, P_BARRIER,
+				(struct p_header *)p, sizeof(*p), 0);
+	drbd_put_data_sock(mdev);
+
+	return ok;
+}
+
+int w_send_write_hint(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	if (cancel)
+		return 1;
+	return drbd_send_short_cmd(mdev, P_UNPLUG_REMOTE);
+}
+
+/**
+ * w_send_dblock() - Worker callback to send a P_DATA packet in order to mirror a write request
+ * @mdev:	DRBD device.
+ * @w:		work object.
+ * @cancel:	The connection will be closed anyways
+ */
+int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	int ok;
+
+	if (unlikely(cancel)) {
+		req_mod(req, send_canceled);
+		return 1;
+	}
+
+	ok = drbd_send_dblock(mdev, req);
+	req_mod(req, ok ? handed_over_to_network : send_failed);
+
+	return ok;
+}
+
+/**
+ * w_send_read_req() - Worker callback to send a read request (P_DATA_REQUEST) packet
+ * @mdev:	DRBD device.
+ * @w:		work object.
+ * @cancel:	The connection will be closed anyways
+ */
+int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+	struct drbd_request *req = container_of(w, struct drbd_request, w);
+	int ok;
+
+	if (unlikely(cancel)) {
+		req_mod(req, send_canceled);
+		return 1;
+	}
+
+	ok = drbd_send_drequest(mdev, P_DATA_REQUEST, req->sector, req->size,
+				(unsigned long)req);
+
+	if (!ok) {
+		/* ?? we set C_TIMEOUT or C_BROKEN_PIPE in drbd_send();
+		 * so this is probably redundant */
+		if (mdev->state.conn >= C_CONNECTED)
+			drbd_force_state(mdev, NS(conn, C_NETWORK_FAILURE));
+	}
+	req_mod(req, ok ? handed_over_to_network : send_failed);
+
+	return ok;
+}
+
+static int _drbd_may_sync_now(struct drbd_conf *mdev)
+{
+	struct drbd_conf *odev = mdev;
+
+	while (1) {
+		if (odev->sync_conf.after == -1)
+			return 1;
+		odev = minor_to_mdev(odev->sync_conf.after);
+		ERR_IF(!odev) return 1;
+		if ((odev->state.conn >= C_SYNC_SOURCE &&
+		     odev->state.conn <= C_PAUSED_SYNC_T) ||
+		    odev->state.aftr_isp || odev->state.peer_isp ||
+		    odev->state.user_isp)
+			return 0;
+	}
+}
+
+/**
+ * _drbd_pause_after() - Pause resync on all devices that may not resync now
+ * @mdev:	DRBD device.
+ *
+ * Called from process context only (admin command and after_state_ch).
+ */
+static int _drbd_pause_after(struct drbd_conf *mdev)
+{
+	struct drbd_conf *odev;
+	int i, rv = 0;
+
+	for (i = 0; i < minor_count; i++) {
+		odev = minor_to_mdev(i);
+		if (!odev)
+			continue;
+		if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
+			continue;
+		if (!_drbd_may_sync_now(odev))
+			rv |= (__drbd_set_state(_NS(odev, aftr_isp, 1), CS_HARD, NULL)
+			       != SS_NOTHING_TO_DO);
+	}
+
+	return rv;
+}
+
+/**
+ * _drbd_resume_next() - Resume resync on all devices that may resync now
+ * @mdev:	DRBD device.
+ *
+ * Called from process context only (admin command and worker).
+ */
+static int _drbd_resume_next(struct drbd_conf *mdev)
+{
+	struct drbd_conf *odev;
+	int i, rv = 0;
+
+	for (i = 0; i < minor_count; i++) {
+		odev = minor_to_mdev(i);
+		if (!odev)
+			continue;
+		if (odev->state.conn == C_STANDALONE && odev->state.disk == D_DISKLESS)
+			continue;
+		if (odev->state.aftr_isp) {
+			if (_drbd_may_sync_now(odev))
+				rv |= (__drbd_set_state(_NS(odev, aftr_isp, 0),
+							CS_HARD, NULL)
+				       != SS_NOTHING_TO_DO) ;
+		}
+	}
+	return rv;
+}
+
+void resume_next_sg(struct drbd_conf *mdev)
+{
+	write_lock_irq(&global_state_lock);
+	_drbd_resume_next(mdev);
+	write_unlock_irq(&global_state_lock);
+}
+
+void suspend_other_sg(struct drbd_conf *mdev)
+{
+	write_lock_irq(&global_state_lock);
+	_drbd_pause_after(mdev);
+	write_unlock_irq(&global_state_lock);
+}
+
+static int sync_after_error(struct drbd_conf *mdev, int o_minor)
+{
+	struct drbd_conf *odev;
+
+	if (o_minor == -1)
+		return NO_ERROR;
+	if (o_minor < -1 || minor_to_mdev(o_minor) == NULL)
+		return ERR_SYNC_AFTER;
+
+	/* check for loops */
+	odev = minor_to_mdev(o_minor);
+	while (1) {
+		if (odev == mdev)
+			return ERR_SYNC_AFTER_CYCLE;
+
+		/* dependency chain ends here, no cycles. */
+		if (odev->sync_conf.after == -1)
+			return NO_ERROR;
+
+		/* follow the dependency chain */
+		odev = minor_to_mdev(odev->sync_conf.after);
+	}
+}
+
+int drbd_alter_sa(struct drbd_conf *mdev, int na)
+{
+	int changes;
+	int retcode;
+
+	write_lock_irq(&global_state_lock);
+	retcode = sync_after_error(mdev, na);
+	if (retcode == NO_ERROR) {
+		mdev->sync_conf.after = na;
+		do {
+			changes  = _drbd_pause_after(mdev);
+			changes |= _drbd_resume_next(mdev);
+		} while (changes);
+	}
+	write_unlock_irq(&global_state_lock);
+	return retcode;
+}
+
+/**
+ * drbd_start_resync() - Start the resync process
+ * @mdev:	DRBD device.
+ * @side:	Either C_SYNC_SOURCE or C_SYNC_TARGET
+ *
+ * This function might bring you directly into one of the
+ * C_PAUSED_SYNC_* states.
+ */
+void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
+{
+	union drbd_state ns;
+	int r;
+
+	if (mdev->state.conn >= C_SYNC_SOURCE) {
+		dev_err(DEV, "Resync already running!\n");
+		return;
+	}
+
+	/* In case a previous resync run was aborted by an IO error/detach on the peer. */
+	drbd_rs_cancel_all(mdev);
+
+	if (side == C_SYNC_TARGET) {
+		/* Since application IO was locked out during C_WF_BITMAP_T and
+		   C_WF_SYNC_UUID we are still unmodified. Before going to C_SYNC_TARGET
+		   we check that we might make the data inconsistent. */
+		r = drbd_khelper(mdev, "before-resync-target");
+		r = (r >> 8) & 0xff;
+		if (r > 0) {
+			dev_info(DEV, "before-resync-target handler returned %d, "
+			     "dropping connection.\n", r);
+			drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
+			return;
+		}
+	}
+
+	drbd_state_lock(mdev);
+
+	if (!get_ldev_if_state(mdev, D_NEGOTIATING)) {
+		drbd_state_unlock(mdev);
+		return;
+	}
+
+	if (side == C_SYNC_TARGET) {
+		mdev->bm_resync_fo = 0;
+	} else /* side == C_SYNC_SOURCE */ {
+		u64 uuid;
+
+		get_random_bytes(&uuid, sizeof(u64));
+		drbd_uuid_set(mdev, UI_BITMAP, uuid);
+		drbd_send_sync_uuid(mdev, uuid);
+
+		D_ASSERT(mdev->state.disk == D_UP_TO_DATE);
+	}
+
+	write_lock_irq(&global_state_lock);
+	ns = mdev->state;
+
+	ns.aftr_isp = !_drbd_may_sync_now(mdev);
+
+	ns.conn = side;
+
+	if (side == C_SYNC_TARGET)
+		ns.disk = D_INCONSISTENT;
+	else /* side == C_SYNC_SOURCE */
+		ns.pdsk = D_INCONSISTENT;
+
+	r = __drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
+	ns = mdev->state;
+
+	if (ns.conn < C_CONNECTED)
+		r = SS_UNKNOWN_ERROR;
+
+	if (r == SS_SUCCESS) {
+		mdev->rs_total     =
+		mdev->rs_mark_left = drbd_bm_total_weight(mdev);
+		mdev->rs_failed    = 0;
+		mdev->rs_paused    = 0;
+		mdev->rs_start     =
+		mdev->rs_mark_time = jiffies;
+		mdev->rs_same_csum = 0;
+		_drbd_pause_after(mdev);
+	}
+	write_unlock_irq(&global_state_lock);
+	drbd_state_unlock(mdev);
+	put_ldev(mdev);
+
+	if (r == SS_SUCCESS) {
+		dev_info(DEV, "Began resync as %s (will sync %lu KB [%lu bits set]).\n",
+		     drbd_conn_str(ns.conn),
+		     (unsigned long) mdev->rs_total << (BM_BLOCK_SHIFT-10),
+		     (unsigned long) mdev->rs_total);
+
+		if (mdev->rs_total == 0) {
+			/* Peer still reachable? Beware of failing before-resync-target handlers! */
+			request_ping(mdev);
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */
+			drbd_resync_finished(mdev);
+			return;
+		}
+
+		/* ns.conn may already be != mdev->state.conn,
+		 * we may have been paused in between, or become paused until
+		 * the timer triggers.
+		 * No matter, that is handled in resync_timer_fn() */
+		if (ns.conn == C_SYNC_TARGET)
+			mod_timer(&mdev->resync_timer, jiffies);
+
+		drbd_md_sync(mdev);
+	}
+}
+
+int drbd_worker(struct drbd_thread *thi)
+{
+	struct drbd_conf *mdev = thi->mdev;
+	struct drbd_work *w = NULL;
+	LIST_HEAD(work_list);
+	int intr = 0, i;
+
+	sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev));
+
+	while (get_t_state(thi) == Running) {
+		drbd_thread_current_set_cpu(mdev);
+
+		if (down_trylock(&mdev->data.work.s)) {
+			mutex_lock(&mdev->data.mutex);
+			if (mdev->data.socket && !mdev->net_conf->no_cork)
+				drbd_tcp_uncork(mdev->data.socket);
+			mutex_unlock(&mdev->data.mutex);
+
+			intr = down_interruptible(&mdev->data.work.s);
+
+			mutex_lock(&mdev->data.mutex);
+			if (mdev->data.socket  && !mdev->net_conf->no_cork)
+				drbd_tcp_cork(mdev->data.socket);
+			mutex_unlock(&mdev->data.mutex);
+		}
+
+		if (intr) {
+			D_ASSERT(intr == -EINTR);
+			flush_signals(current);
+			ERR_IF (get_t_state(thi) == Running)
+				continue;
+			break;
+		}
+
+		if (get_t_state(thi) != Running)
+			break;
+		/* With this break, we have done a down() but not consumed
+		   the entry from the list. The cleanup code takes care of
+		   this...   */
+
+		w = NULL;
+		spin_lock_irq(&mdev->data.work.q_lock);
+		ERR_IF(list_empty(&mdev->data.work.q)) {
+			/* something terribly wrong in our logic.
+			 * we were able to down() the semaphore,
+			 * but the list is empty... doh.
+			 *
+			 * what is the best thing to do now?
+			 * try again from scratch, restarting the receiver,
+			 * asender, whatnot? could break even more ugly,
+			 * e.g. when we are primary, but no good local data.
+			 *
+			 * I'll try to get away just starting over this loop.
+			 */
+			spin_unlock_irq(&mdev->data.work.q_lock);
+			continue;
+		}
+		w = list_entry(mdev->data.work.q.next, struct drbd_work, list);
+		list_del_init(&w->list);
+		spin_unlock_irq(&mdev->data.work.q_lock);
+
+		if (!w->cb(mdev, w, mdev->state.conn < C_CONNECTED)) {
+			/* dev_warn(DEV, "worker: a callback failed! \n"); */
+			if (mdev->state.conn >= C_CONNECTED)
+				drbd_force_state(mdev,
+						NS(conn, C_NETWORK_FAILURE));
+		}
+	}
+	D_ASSERT(test_bit(DEVICE_DYING, &mdev->flags));
+	D_ASSERT(test_bit(CONFIG_PENDING, &mdev->flags));
+
+	spin_lock_irq(&mdev->data.work.q_lock);
+	i = 0;
+	while (!list_empty(&mdev->data.work.q)) {
+		list_splice_init(&mdev->data.work.q, &work_list);
+		spin_unlock_irq(&mdev->data.work.q_lock);
+
+		while (!list_empty(&work_list)) {
+			w = list_entry(work_list.next, struct drbd_work, list);
+			list_del_init(&w->list);
+			w->cb(mdev, w, 1);
+			i++; /* dead debugging code */
+		}
+
+		spin_lock_irq(&mdev->data.work.q_lock);
+	}
+	sema_init(&mdev->data.work.s, 0);
+	/* DANGEROUS race: if someone did queue his work within the spinlock,
+	 * but up() ed outside the spinlock, we could get an up() on the
+	 * semaphore without corresponding list entry.
+	 * So don't do that.
+	 */
+	spin_unlock_irq(&mdev->data.work.q_lock);
+
+	D_ASSERT(mdev->state.disk == D_DISKLESS && mdev->state.conn == C_STANDALONE);
+	/* _drbd_set_state only uses stop_nowait.
+	 * wait here for the Exiting receiver. */
+	drbd_thread_stop(&mdev->receiver);
+	drbd_mdev_cleanup(mdev);
+
+	dev_info(DEV, "worker terminated\n");
+
+	clear_bit(DEVICE_DYING, &mdev->flags);
+	clear_bit(CONFIG_PENDING, &mdev->flags);
+	wake_up(&mdev->state_wait);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_wrappers.h linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_wrappers.h
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/drbd_wrappers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/drbd_wrappers.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,91 @@
+#ifndef _DRBD_WRAPPERS_H
+#define _DRBD_WRAPPERS_H
+
+#include <linux/ctype.h>
+#include <linux/mm.h>
+
+/* see get_sb_bdev and bd_claim */
+extern char *drbd_sec_holder;
+
+/* sets the number of 512 byte sectors of our virtual device */
+static inline void drbd_set_my_capacity(struct drbd_conf *mdev,
+					sector_t size)
+{
+	/* set_capacity(mdev->this_bdev->bd_disk, size); */
+	set_capacity(mdev->vdisk, size);
+	mdev->this_bdev->bd_inode->i_size = (loff_t)size << 9;
+}
+
+#define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE)
+
+static inline int drbd_bio_has_active_page(struct bio *bio)
+{
+	struct bio_vec *bvec;
+	int i;
+
+	__bio_for_each_segment(bvec, bio, i, 0) {
+		if (page_count(bvec->bv_page) > 1)
+			return 1;
+	}
+
+	return 0;
+}
+
+/* bi_end_io handlers */
+extern void drbd_md_io_complete(struct bio *bio, int error);
+extern void drbd_endio_read_sec(struct bio *bio, int error);
+extern void drbd_endio_write_sec(struct bio *bio, int error);
+extern void drbd_endio_pri(struct bio *bio, int error);
+
+/*
+ * used to submit our private bio
+ */
+static inline void drbd_generic_make_request(struct drbd_conf *mdev,
+					     int fault_type, struct bio *bio)
+{
+	__release(local);
+	if (!bio->bi_bdev) {
+		printk(KERN_ERR "drbd%d: drbd_generic_make_request: "
+				"bio->bi_bdev == NULL\n",
+		       mdev_to_minor(mdev));
+		dump_stack();
+		bio_endio(bio, -ENODEV);
+		return;
+	}
+
+	if (FAULT_ACTIVE(mdev, fault_type))
+		bio_endio(bio, -EIO);
+	else
+		generic_make_request(bio);
+}
+
+static inline void drbd_plug_device(struct drbd_conf *mdev)
+{
+	struct request_queue *q;
+	q = bdev_get_queue(mdev->this_bdev);
+
+	spin_lock_irq(q->queue_lock);
+
+/* XXX the check on !blk_queue_plugged is redundant,
+ * implicitly checked in blk_plug_device */
+
+	if (!blk_queue_plugged(q)) {
+		blk_plug_device(q);
+		del_timer(&q->unplug_timer);
+		/* unplugging should not happen automatically... */
+	}
+	spin_unlock_irq(q->queue_lock);
+}
+
+static inline int drbd_crypto_is_hash(struct crypto_tfm *tfm)
+{
+        return (crypto_tfm_alg_type(tfm) & CRYPTO_ALG_TYPE_HASH_MASK)
+                == CRYPTO_ALG_TYPE_HASH;
+}
+
+#ifndef __CHECKER__
+# undef __cond_lock
+# define __cond_lock(x,c) (c)
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/Kconfig linux-libre-2.6.33-gnu1/drivers/block/drbd/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,71 @@
+#
+# DRBD device driver configuration
+#
+
+comment "DRBD disabled because PROC_FS, INET or CONNECTOR not selected"
+	depends on PROC_FS='n' || INET='n' || CONNECTOR='n'
+
+config BLK_DEV_DRBD
+	tristate "DRBD Distributed Replicated Block Device support"
+	depends on PROC_FS && INET && CONNECTOR
+	select LRU_CACHE
+	default n
+	help
+
+	  NOTE: In order to authenticate connections you have to select
+	  CRYPTO_HMAC and a hash function as well.
+
+	  DRBD is a shared-nothing, synchronously replicated block device. It
+	  is designed to serve as a building block for high availability
+	  clusters and in this context, is a "drop-in" replacement for shared
+	  storage. Simplistically, you could see it as a network RAID 1.
+
+	  Each minor device has a role, which can be 'primary' or 'secondary'.
+	  On the node with the primary device the application is supposed to
+	  run and to access the device (/dev/drbdX). Every write is sent to
+	  the local 'lower level block device' and, across the network, to the
+	  node with the device in 'secondary' state.  The secondary device
+	  simply writes the data to its lower level block device.
+
+	  DRBD can also be used in dual-Primary mode (device writable on both
+	  nodes), which means it can exhibit shared disk semantics in a
+	  shared-nothing cluster.  Needless to say, on top of dual-Primary
+	  DRBD utilizing a cluster file system is necessary to maintain for
+	  cache coherency.
+
+	  For automatic failover you need a cluster manager (e.g. heartbeat).
+	  See also: http://www.drbd.org/, http://www.linux-ha.org
+
+	  If unsure, say N.
+
+config DRBD_FAULT_INJECTION
+	bool "DRBD fault injection"
+	depends on BLK_DEV_DRBD
+	help
+
+	  Say Y here if you want to simulate IO errors, in order to test DRBD's
+	  behavior.
+
+	  The actual simulation of IO errors is done by writing 3 values to
+	  /sys/module/drbd/parameters/
+
+	  enable_faults: bitmask of...
+	  1	meta data write
+	  2               read
+	  4	resync data write
+	  8	            read
+	  16	data write
+	  32	data read
+	  64	read ahead
+	  128	kmalloc of bitmap
+	  256	allocation of EE (epoch_entries)
+
+	  fault_devs: bitmask of minor numbers
+	  fault_rate: frequency in percent
+
+	  Example: Simulate data write errors on /dev/drbd0 with a probability of 5%.
+		echo 16 > /sys/module/drbd/parameters/enable_faults
+		echo 1 > /sys/module/drbd/parameters/fault_devs
+		echo 5 > /sys/module/drbd/parameters/fault_rate
+
+	  If unsure, say N.
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/drbd/Makefile linux-libre-2.6.33-gnu1/drivers/block/drbd/Makefile
--- linux-libre-2.6.32-gnu1/drivers/block/drbd/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/drbd/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+drbd-y := drbd_bitmap.o drbd_proc.o
+drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
+drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
+
+obj-$(CONFIG_BLK_DEV_DRBD)     += drbd.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/floppy.c linux-libre-2.6.33-gnu1/drivers/block/floppy.c
--- linux-libre-2.6.32-gnu1/drivers/block/floppy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/floppy.c	2010-02-24 13:52:17.000000000 -0500
@@ -3497,6 +3497,9 @@ static int fd_ioctl(struct block_device
 	    ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)))
 		return -EPERM;
 
+	if (WARN_ON(size < 0 || size > sizeof(inparam)))
+		return -EINVAL;
+
 	/* copyin */
 	CLEARSTRUCT(&inparam);
 	if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -4162,7 +4165,7 @@ static int floppy_resume(struct device *
 	return 0;
 }
 
-static struct dev_pm_ops floppy_pm_ops = {
+static const struct dev_pm_ops floppy_pm_ops = {
 	.resume = floppy_resume,
 	.restore = floppy_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/Kconfig linux-libre-2.6.33-gnu1/drivers/block/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/block/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -271,6 +271,8 @@ config BLK_DEV_CRYPTOLOOP
 	  instead, which can be configured to be on-disk compatible with the
 	  cryptoloop device.
 
+source "drivers/block/drbd/Kconfig"
+
 config BLK_DEV_NBD
 	tristate "Network block device support"
 	depends on NET
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/Makefile linux-libre-2.6.33-gnu1/drivers/block/Makefile
--- linux-libre-2.6.32-gnu1/drivers/block/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -36,5 +36,6 @@ obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 obj-$(CONFIG_BLK_DEV_HD)	+= hd.o
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
+obj-$(CONFIG_BLK_DEV_DRBD)     += drbd/
 
 swim_mod-objs	:= swim.o swim_asm.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/mg_disk.c linux-libre-2.6.33-gnu1/drivers/block/mg_disk.c
--- linux-libre-2.6.32-gnu1/drivers/block/mg_disk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/mg_disk.c	2010-02-24 13:52:17.000000000 -0500
@@ -860,7 +860,7 @@ static int mg_probe(struct platform_devi
 		err = -EINVAL;
 		goto probe_err_2;
 	}
-	host->dev_base = ioremap(rsc->start , rsc->end + 1);
+	host->dev_base = ioremap(rsc->start, resource_size(rsc));
 	if (!host->dev_base) {
 		printk(KERN_ERR "%s:%d ioremap fail\n",
 				__func__, __LINE__);
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/pktcdvd.c linux-libre-2.6.33-gnu1/drivers/block/pktcdvd.c
--- linux-libre-2.6.32-gnu1/drivers/block/pktcdvd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/pktcdvd.c	2010-02-24 13:52:17.000000000 -0500
@@ -322,7 +322,7 @@ static void pkt_sysfs_dev_remove(struct
 	pkt_kobj_remove(pd->kobj_stat);
 	pkt_kobj_remove(pd->kobj_wqueue);
 	if (class_pktcdvd)
-		device_destroy(class_pktcdvd, pd->pkt_dev);
+		device_unregister(pd->dev);
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/ps3vram.c linux-libre-2.6.33-gnu1/drivers/block/ps3vram.c
--- linux-libre-2.6.32-gnu1/drivers/block/ps3vram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/ps3vram.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,7 +123,15 @@ static int ps3vram_notifier_wait(struct
 {
 	struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
 	u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
-	unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+	unsigned long timeout;
+
+	for (timeout = 20; timeout; timeout--) {
+		if (!notify[3])
+			return 0;
+		udelay(10);
+	}
+
+	timeout = jiffies + msecs_to_jiffies(timeout_ms);
 
 	do {
 		if (!notify[3])
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/swim3.c linux-libre-2.6.33-gnu1/drivers/block/swim3.c
--- linux-libre-2.6.32-gnu1/drivers/block/swim3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/swim3.c	2010-02-24 13:52:17.000000000 -0500
@@ -200,7 +200,7 @@ struct floppy_state {
 	int	ejected;
 	wait_queue_head_t wait;
 	int	wanted;
-	struct device_node*	media_bay; /* NULL when not in bay */
+	struct macio_dev *mdev;
 	char	dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
 };
 
@@ -303,14 +303,13 @@ static int swim3_readbit(struct floppy_s
 static void do_fd_request(struct request_queue * q)
 {
 	int i;
-	for(i=0;i<floppy_count;i++)
-	{
-#ifdef CONFIG_PMAC_MEDIABAY
-		if (floppy_states[i].media_bay &&
-			check_media_bay(floppy_states[i].media_bay, MB_FD))
+
+	for(i=0; i<floppy_count; i++) {
+		struct floppy_state *fs = &floppy_states[i];
+		if (fs->mdev->media_bay &&
+		    check_media_bay(fs->mdev->media_bay) != MB_FD)
 			continue;
-#endif /* CONFIG_PMAC_MEDIABAY */
-		start_request(&floppy_states[i]);
+		start_request(fs);
 	}
 }
 
@@ -849,10 +848,9 @@ static int floppy_ioctl(struct block_dev
 	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-#ifdef CONFIG_PMAC_MEDIABAY
-	if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
+	if (fs->mdev->media_bay &&
+	    check_media_bay(fs->mdev->media_bay) != MB_FD)
 		return -ENXIO;
-#endif
 
 	switch (cmd) {
 	case FDEJECT:
@@ -876,10 +874,9 @@ static int floppy_open(struct block_devi
 	int n, err = 0;
 
 	if (fs->ref_count == 0) {
-#ifdef CONFIG_PMAC_MEDIABAY
-		if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
+		if (fs->mdev->media_bay &&
+		    check_media_bay(fs->mdev->media_bay) != MB_FD)
 			return -ENXIO;
-#endif
 		out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
 		out_8(&sw->control_bic, 0xff);
 		out_8(&sw->mode, 0x95);
@@ -963,10 +960,9 @@ static int floppy_revalidate(struct gend
 	struct swim3 __iomem *sw;
 	int ret, n;
 
-#ifdef CONFIG_PMAC_MEDIABAY
-	if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
+	if (fs->mdev->media_bay &&
+	    check_media_bay(fs->mdev->media_bay) != MB_FD)
 		return -ENXIO;
-#endif
 
 	sw = fs->swim3;
 	grab_drive(fs, revalidating, 0);
@@ -1009,7 +1005,6 @@ static const struct block_device_operati
 static int swim3_add_device(struct macio_dev *mdev, int index)
 {
 	struct device_node *swim = mdev->ofdev.node;
-	struct device_node *mediabay;
 	struct floppy_state *fs = &floppy_states[index];
 	int rc = -EBUSY;
 
@@ -1036,9 +1031,7 @@ static int swim3_add_device(struct macio
 	}
 	dev_set_drvdata(&mdev->ofdev.dev, fs);
 
-	mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ?
-		swim->parent : NULL;
-	if (mediabay == NULL)
+	if (mdev->media_bay == NULL)
 		pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
 	
 	memset(fs, 0, sizeof(*fs));
@@ -1068,7 +1061,7 @@ static int swim3_add_device(struct macio
 	fs->secpercyl = 36;
 	fs->secpertrack = 18;
 	fs->total_secs = 2880;
-	fs->media_bay = mediabay;
+	fs->mdev = mdev;
 	init_waitqueue_head(&fs->wait);
 
 	fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
@@ -1093,7 +1086,7 @@ static int swim3_add_device(struct macio
 	init_timer(&fs->timeout);
 
 	printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
-		mediabay ? "in media bay" : "");
+		mdev->media_bay ? "in media bay" : "");
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/xd.c linux-libre-2.6.33-gnu1/drivers/block/xd.c
--- linux-libre-2.6.32-gnu1/drivers/block/xd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/xd.c	2010-02-24 13:52:17.000000000 -0500
@@ -169,13 +169,6 @@ static int __init xd_init(void)
 
 	init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
 
-	if (!xd_dma_buffer)
-		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
-	if (!xd_dma_buffer) {
-		printk(KERN_ERR "xd: Out of memory.\n");
-		return -ENOMEM;
-	}
-
 	err = -EBUSY;
 	if (register_blkdev(XT_DISK_MAJOR, "xd"))
 		goto out1;
@@ -202,6 +195,19 @@ static int __init xd_init(void)
 			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
 	}
 
+	/*
+	 * With the drive detected, xd_maxsectors should now be known.
+	 * If xd_maxsectors is 0, nothing was detected and we fall through
+	 * to return -ENODEV
+	 */
+	if (!xd_dma_buffer && xd_maxsectors) {
+		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
+		if (!xd_dma_buffer) {
+			printk(KERN_ERR "xd: Out of memory.\n");
+			goto out3;
+		}
+	}
+
 	err = -ENODEV;
 	if (!xd_drives)
 		goto out3;
@@ -249,15 +255,17 @@ out4:
 	for (i = 0; i < xd_drives; i++)
 		put_disk(xd_gendisk[i]);
 out3:
-	release_region(xd_iobase,4);
+	if (xd_maxsectors)
+		release_region(xd_iobase,4);
+
+	if (xd_dma_buffer)
+		xd_dma_mem_free((unsigned long)xd_dma_buffer,
+				xd_maxsectors * 0x200);
 out2:
 	blk_cleanup_queue(xd_queue);
 out1a:
 	unregister_blkdev(XT_DISK_MAJOR, "xd");
 out1:
-	if (xd_dma_buffer)
-		xd_dma_mem_free((unsigned long)xd_dma_buffer,
-				xd_maxsectors * 0x200);
 	return err;
 Enomem:
 	err = -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/block/xen-blkfront.c linux-libre-2.6.33-gnu1/drivers/block/xen-blkfront.c
--- linux-libre-2.6.32-gnu1/drivers/block/xen-blkfront.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/block/xen-blkfront.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/grant_table.h>
 #include <xen/events.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/ath3k.c linux-libre-2.6.33-gnu1/drivers/bluetooth/ath3k.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/ath3k.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/ath3k.c	2013-05-03 12:11:52.000000000 -0400
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications 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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/usb.h>
+#include <net/bluetooth/bluetooth.h>
+
+#define VERSION "1.0"
+
+
+static struct usb_device_id ath3k_table[] = {
+	/* Atheros AR3011 */
+	{ USB_DEVICE(0x0CF3, 0x3000) },
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, ath3k_table);
+
+#define USB_REQ_DFU_DNLOAD	1
+#define BULK_SIZE		4096
+
+struct ath3k_data {
+	struct usb_device *udev;
+	u8 *fw_data;
+	u32 fw_size;
+	u32 fw_sent;
+};
+
+static int ath3k_load_firmware(struct ath3k_data *data,
+				unsigned char *firmware,
+				int count)
+{
+	u8 *send_buf;
+	int err, pipe, len, size, sent = 0;
+
+	BT_DBG("ath3k %p udev %p", data, data->udev);
+
+	pipe = usb_sndctrlpipe(data->udev, 0);
+
+	if ((usb_control_msg(data->udev, pipe,
+				USB_REQ_DFU_DNLOAD,
+				USB_TYPE_VENDOR, 0, 0,
+				firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
+		BT_ERR("Can't change to loading configuration err");
+		return -EBUSY;
+	}
+	sent += 20;
+	count -= 20;
+
+	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+	if (!send_buf) {
+		BT_ERR("Can't allocate memory chunk for firmware");
+		return -ENOMEM;
+	}
+
+	while (count) {
+		size = min_t(uint, count, BULK_SIZE);
+		pipe = usb_sndbulkpipe(data->udev, 0x02);
+		memcpy(send_buf, firmware + sent, size);
+
+		err = usb_bulk_msg(data->udev, pipe, send_buf, size,
+					&len, 3000);
+
+		if (err || (len != size)) {
+			BT_ERR("Error in firmware loading err = %d,"
+				"len = %d, size = %d", err, len, size);
+			goto error;
+		}
+
+		sent  += size;
+		count -= size;
+	}
+
+	kfree(send_buf);
+	return 0;
+
+error:
+	kfree(send_buf);
+	return err;
+}
+
+static int ath3k_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	const struct firmware *firmware;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct ath3k_data *data;
+	int size;
+
+	BT_DBG("intf %p id %p", intf, id);
+
+	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+		return -ENODEV;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->udev = udev;
+
+	if (reject_firmware(&firmware, "/*(DEBLOBBED)*/", &udev->dev) < 0) {
+		kfree(data);
+		return -EIO;
+	}
+
+	size = max_t(uint, firmware->size, 4096);
+	data->fw_data = kmalloc(size, GFP_KERNEL);
+	if (!data->fw_data) {
+		release_firmware(firmware);
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	memcpy(data->fw_data, firmware->data, firmware->size);
+	data->fw_size = firmware->size;
+	data->fw_sent = 0;
+	release_firmware(firmware);
+
+	usb_set_intfdata(intf, data);
+	if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
+		usb_set_intfdata(intf, NULL);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void ath3k_disconnect(struct usb_interface *intf)
+{
+	struct ath3k_data *data = usb_get_intfdata(intf);
+
+	BT_DBG("ath3k_disconnect intf %p", intf);
+
+	kfree(data->fw_data);
+	kfree(data);
+}
+
+static struct usb_driver ath3k_driver = {
+	.name		= "ath3k",
+	.probe		= ath3k_probe,
+	.disconnect	= ath3k_disconnect,
+	.id_table	= ath3k_table,
+};
+
+static int __init ath3k_init(void)
+{
+	BT_INFO("Atheros AR30xx firmware driver ver %s", VERSION);
+	return usb_register(&ath3k_driver);
+}
+
+static void __exit ath3k_exit(void)
+{
+	usb_deregister(&ath3k_driver);
+}
+
+module_init(ath3k_init);
+module_exit(ath3k_exit);
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Atheros AR30xx firmware driver");
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/bluecard_cs.c linux-libre-2.6.33-gnu1/drivers/bluetooth/bluecard_cs.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/bluecard_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/bluecard_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -503,7 +503,9 @@ static irqreturn_t bluecard_interrupt(in
 	unsigned int iobase;
 	unsigned char reg;
 
-	BUG_ON(!info->hdev);
+	if (!info || !info->hdev)
+		/* our irq handler is shared */
+		return IRQ_NONE;
 
 	if (!test_bit(CARD_READY, &(info->hw_state)))
 		return IRQ_HANDLED;
@@ -867,11 +869,9 @@ static int bluecard_probe(struct pcmcia_
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
 	link->irq.Handler = bluecard_interrupt;
-	link->irq.Instance = info;
 
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -905,22 +905,16 @@ static int bluecard_config(struct pcmcia
 			break;
 	}
 
-	if (i != 0) {
-		cs_error(link, RequestIO, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != 0) {
-		cs_error(link, RequestIRQ, i);
+	if (i != 0)
 		link->irq.AssignedIRQ = 0;
-	}
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != 0) {
-		cs_error(link, RequestConfiguration, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	if (bluecard_open(info) != 0)
 		goto failed;
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/bt3c_cs.c linux-libre-2.6.33-gnu1/drivers/bluetooth/bt3c_cs.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 14:04:23.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 12:11:57.000000000 -0400
@@ -345,7 +345,9 @@ static irqreturn_t bt3c_interrupt(int ir
 	int iir;
 	irqreturn_t r = IRQ_NONE;
 
-	BUG_ON(!info->hdev);
+	if (!info || !info->hdev)
+		/* our irq handler is shared */
+		return IRQ_NONE;
 
 	iobase = info->p_dev->io.BasePort1;
 
@@ -659,11 +661,9 @@ static int bt3c_probe(struct pcmcia_devi
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
 	link->irq.Handler = bt3c_interrupt;
-	link->irq.Instance = info;
 
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -740,21 +740,16 @@ static int bt3c_config(struct pcmcia_dev
 		goto found_port;
 
 	BT_ERR("No usable port range found");
-	cs_error(link, RequestIO, -ENODEV);
 	goto failed;
 
 found_port:
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != 0) {
-		cs_error(link, RequestIRQ, i);
+	if (i != 0)
 		link->irq.AssignedIRQ = 0;
-	}
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != 0) {
-		cs_error(link, RequestConfiguration, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	if (bt3c_open(info) != 0)
 		goto failed;
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_debugfs.c linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,6 @@ struct btmrvl_debugfs_data {
 	struct dentry *root_dir, *config_dir, *status_dir;
 
 	/* config */
-	struct dentry *drvdbg;
 	struct dentry *psmode;
 	struct dentry *pscmd;
 	struct dentry *hsmode;
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_drv.h linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_drv.h
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_drv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -131,6 +131,7 @@ void btmrvl_check_evtpkt(struct btmrvl_p
 int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
 
 int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
+int btmrvl_enable_ps(struct btmrvl_private *priv);
 int btmrvl_prepare_command(struct btmrvl_private *priv);
 
 #ifdef CONFIG_DEBUG_FS
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_main.c linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_main.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,6 +189,38 @@ int btmrvl_send_module_cfg_cmd(struct bt
 }
 EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
 
+int btmrvl_enable_ps(struct btmrvl_private *priv)
+{
+	struct sk_buff *skb;
+	struct btmrvl_cmd *cmd;
+
+	skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+	if (skb == NULL) {
+		BT_ERR("No free skb");
+		return -ENOMEM;
+	}
+
+	cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+	cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
+					BT_CMD_AUTO_SLEEP_MODE));
+	cmd->length = 1;
+
+	if (priv->btmrvl_dev.psmode)
+		cmd->data[0] = BT_PS_ENABLE;
+	else
+		cmd->data[0] = BT_PS_DISABLE;
+
+	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+	skb->dev = (void *) priv->btmrvl_dev.hcidev;
+	skb_queue_head(&priv->adapter->tx_queue, skb);
+
+	BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
+
 static int btmrvl_enable_hs(struct btmrvl_private *priv)
 {
 	struct sk_buff *skb;
@@ -258,28 +290,7 @@ int btmrvl_prepare_command(struct btmrvl
 
 	if (priv->btmrvl_dev.pscmd) {
 		priv->btmrvl_dev.pscmd = 0;
-
-		skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
-		if (skb == NULL) {
-			BT_ERR("No free skb");
-			return -ENOMEM;
-		}
-
-		cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
-		cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_AUTO_SLEEP_MODE));
-		cmd->length = 1;
-
-		if (priv->btmrvl_dev.psmode)
-			cmd->data[0] = BT_PS_ENABLE;
-		else
-			cmd->data[0] = BT_PS_DISABLE;
-
-		bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
-
-		skb->dev = (void *) priv->btmrvl_dev.hcidev;
-		skb_queue_head(&priv->adapter->tx_queue, skb);
-
-		BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
+		btmrvl_enable_ps(priv);
 	}
 
 	if (priv->btmrvl_dev.hscmd) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_sdio.c linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_sdio.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btmrvl_sdio.c	2013-05-03 14:04:25.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btmrvl_sdio.c	2013-05-03 12:12:00.000000000 -0400
@@ -534,7 +534,7 @@ static int btmrvl_sdio_card_to_host(stru
 		break;
 
 	default:
-		BT_ERR("Unknow packet type:%d", type);
+		BT_ERR("Unknown packet type:%d", type);
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
 						blksz * buf_block_len);
 
@@ -807,6 +807,7 @@ static int btmrvl_sdio_host_to_card(stru
 
 exit:
 	sdio_release_host(card->func);
+	kfree(tmpbuf);
 
 	return ret;
 }
@@ -929,6 +930,8 @@ static int btmrvl_sdio_probe(struct sdio
 	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
 
 	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
+	priv->btmrvl_dev.psmode = 1;
+	btmrvl_enable_ps(priv);
 
 	return 0;
 
@@ -1000,3 +1003,4 @@ MODULE_AUTHOR("Marvell International Ltd
 MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL v2");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btuart_cs.c linux-libre-2.6.33-gnu1/drivers/bluetooth/btuart_cs.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btuart_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btuart_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -295,7 +295,9 @@ static irqreturn_t btuart_interrupt(int
 	int iir, lsr;
 	irqreturn_t r = IRQ_NONE;
 
-	BUG_ON(!info->hdev);
+	if (!info || !info->hdev)
+		/* our irq handler is shared */
+		return IRQ_NONE;
 
 	iobase = info->p_dev->io.BasePort1;
 
@@ -588,11 +590,9 @@ static int btuart_probe(struct pcmcia_de
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
 	link->irq.Handler = btuart_interrupt;
-	link->irq.Instance = info;
 
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -669,21 +669,16 @@ static int btuart_config(struct pcmcia_d
 		goto found_port;
 
 	BT_ERR("No usable port range found");
-	cs_error(link, RequestIO, -ENODEV);
 	goto failed;
 
 found_port:
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != 0) {
-		cs_error(link, RequestIRQ, i);
+	if (i != 0)
 		link->irq.AssignedIRQ = 0;
-	}
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != 0) {
-		cs_error(link, RequestConfiguration, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	if (btuart_open(info) != 0)
 		goto failed;
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/btusb.c linux-libre-2.6.33-gnu1/drivers/bluetooth/btusb.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/btusb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/btusb.c	2010-02-24 13:52:17.000000000 -0500
@@ -307,6 +307,7 @@ static void btusb_bulk_complete(struct u
 		return;
 
 	usb_anchor_urb(urb, &data->bulk_anchor);
+	usb_mark_last_busy(data->udev);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
 	if (err < 0) {
@@ -1066,7 +1067,7 @@ static int btusb_suspend(struct usb_inte
 		return 0;
 
 	spin_lock_irq(&data->txlock);
-	if (!(interface_to_usbdev(intf)->auto_pm && data->tx_in_flight)) {
+	if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
 		set_bit(BTUSB_SUSPENDING, &data->flags);
 		spin_unlock_irq(&data->txlock);
 	} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/dtl1_cs.c linux-libre-2.6.33-gnu1/drivers/bluetooth/dtl1_cs.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/dtl1_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/dtl1_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -299,7 +299,9 @@ static irqreturn_t dtl1_interrupt(int ir
 	int iir, lsr;
 	irqreturn_t r = IRQ_NONE;
 
-	BUG_ON(!info->hdev);
+	if (!info || !info->hdev)
+		/* our irq handler is shared */
+		return IRQ_NONE;
 
 	iobase = info->p_dev->io.BasePort1;
 
@@ -573,11 +575,9 @@ static int dtl1_probe(struct pcmcia_devi
 
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
 	link->irq.Handler = dtl1_interrupt;
-	link->irq.Instance = info;
 
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
@@ -622,16 +622,12 @@ static int dtl1_config(struct pcmcia_dev
 		goto failed;
 
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != 0) {
-		cs_error(link, RequestIRQ, i);
+	if (i != 0)
 		link->irq.AssignedIRQ = 0;
-	}
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != 0) {
-		cs_error(link, RequestConfiguration, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	if (dtl1_open(info) != 0)
 		goto failed;
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/hci_ldisc.c linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_ldisc.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/hci_ldisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_ldisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,7 @@ static int hci_uart_send_frame(struct sk
 	struct hci_uart *hu;
 
 	if (!hdev) {
-		BT_ERR("Frame for uknown device (hdev=NULL)");
+		BT_ERR("Frame for unknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/hci_vhci.c linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_vhci.c
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/hci_vhci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/hci_vhci.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,8 +41,6 @@
 
 #define VERSION "1.3"
 
-static int minor = MISC_DYNAMIC_MINOR;
-
 struct vhci_data {
 	struct hci_dev *hdev;
 
@@ -218,12 +216,6 @@ static unsigned int vhci_poll(struct fil
 	return POLLOUT | POLLWRNORM;
 }
 
-static int vhci_ioctl(struct inode *inode, struct file *file,
-					unsigned int cmd, unsigned long arg)
-{
-	return -EINVAL;
-}
-
 static int vhci_open(struct inode *inode, struct file *file)
 {
 	struct vhci_data *data;
@@ -284,10 +276,10 @@ static int vhci_release(struct inode *in
 }
 
 static const struct file_operations vhci_fops = {
+	.owner		= THIS_MODULE,
 	.read		= vhci_read,
 	.write		= vhci_write,
 	.poll		= vhci_poll,
-	.ioctl		= vhci_ioctl,
 	.open		= vhci_open,
 	.release	= vhci_release,
 };
@@ -302,18 +294,12 @@ static int __init vhci_init(void)
 {
 	BT_INFO("Virtual HCI driver ver %s", VERSION);
 
-	if (misc_register(&vhci_miscdev) < 0) {
-		BT_ERR("Can't register misc device with minor %d", minor);
-		return -EIO;
-	}
-
-	return 0;
+	return misc_register(&vhci_miscdev);
 }
 
 static void __exit vhci_exit(void)
 {
-	if (misc_deregister(&vhci_miscdev) < 0)
-		BT_ERR("Can't unregister misc device with minor %d", minor);
+	misc_deregister(&vhci_miscdev);
 }
 
 module_init(vhci_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/Kconfig linux-libre-2.6.33-gnu1/drivers/bluetooth/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -195,5 +195,16 @@ config BT_MRVL_SDIO
 	  Say Y here to compile support for Marvell BT-over-SDIO driver
 	  into the kernel or say M to compile it as module.
 
-endmenu
+config BT_ATH3K
+	tristate "Atheros firmware download driver"
+	depends on BT_HCIBTUSB
+	select FW_LOADER
+	help
+	  Bluetooth firmware download driver.
+	  This driver loads the firmware into the Atheros Bluetooth
+	  chipset.
+
+	  Say Y here to compile support for "Atheros firmware download driver"
+	  into the kernel or say M to compile it as module (ath3k).
 
+endmenu
diff -druNp linux-libre-2.6.32-gnu1/drivers/bluetooth/Makefile linux-libre-2.6.33-gnu1/drivers/bluetooth/Makefile
--- linux-libre-2.6.32-gnu1/drivers/bluetooth/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/bluetooth/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@ obj-$(CONFIG_BT_HCIBTUART)	+= btuart_cs.
 obj-$(CONFIG_BT_HCIBTUSB)	+= btusb.o
 obj-$(CONFIG_BT_HCIBTSDIO)	+= btsdio.o
 
+obj-$(CONFIG_BT_ATH3K)		+= ath3k.o
 obj-$(CONFIG_BT_MRVL)		+= btmrvl.o
 obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/cdrom/cdrom.c linux-libre-2.6.33-gnu1/drivers/cdrom/cdrom.c
--- linux-libre-2.6.32-gnu1/drivers/cdrom/cdrom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cdrom/cdrom.c	2010-02-24 13:52:17.000000000 -0500
@@ -3557,67 +3557,65 @@ static ctl_table cdrom_table[] = {
 		.data		= &cdrom_sysctl_settings.info, 
 		.maxlen		= CDROM_STR_SIZE,
 		.mode		= 0444,
-		.proc_handler	= &cdrom_sysctl_info,
+		.proc_handler	= cdrom_sysctl_info,
 	},
 	{
 		.procname	= "autoclose",
 		.data		= &cdrom_sysctl_settings.autoclose,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cdrom_sysctl_handler,
+		.proc_handler	= cdrom_sysctl_handler,
 	},
 	{
 		.procname	= "autoeject",
 		.data		= &cdrom_sysctl_settings.autoeject,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cdrom_sysctl_handler,
+		.proc_handler	= cdrom_sysctl_handler,
 	},
 	{
 		.procname	= "debug",
 		.data		= &cdrom_sysctl_settings.debug,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cdrom_sysctl_handler,
+		.proc_handler	= cdrom_sysctl_handler,
 	},
 	{
 		.procname	= "lock",
 		.data		= &cdrom_sysctl_settings.lock,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cdrom_sysctl_handler,
+		.proc_handler	= cdrom_sysctl_handler,
 	},
 	{
 		.procname	= "check_media",
 		.data		= &cdrom_sysctl_settings.check,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &cdrom_sysctl_handler
+		.proc_handler	= cdrom_sysctl_handler
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table cdrom_cdrom_table[] = {
 	{
-		.ctl_name	= DEV_CDROM,
 		.procname	= "cdrom",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= cdrom_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 /* Make sure that /proc/sys/dev is there */
 static ctl_table cdrom_root_table[] = {
 	{
-		.ctl_name	= CTL_DEV,
 		.procname	= "dev",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= cdrom_cdrom_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 static struct ctl_table_header *cdrom_sysctl_header;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/cdrom/gdrom.c linux-libre-2.6.33-gnu1/drivers/cdrom/gdrom.c
--- linux-libre-2.6.32-gnu1/drivers/cdrom/gdrom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cdrom/gdrom.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,7 @@ static void gdrom_spicommand(void *spi_s
 		gdrom_getsense(NULL);
 		return;
 	}
-	outsw(PHYSADDR(GDROM_DATA_REG), cmd, 6);
+	outsw(GDROM_DATA_REG, cmd, 6);
 }
 
 
@@ -298,7 +298,7 @@ static int gdrom_readtoc_cmd(struct gdro
 		err = -EINVAL;
 		goto cleanup_readtoc;
 	}
-	insw(PHYSADDR(GDROM_DATA_REG), toc, tocsize/2);
+	insw(GDROM_DATA_REG, toc, tocsize/2);
 	if (gd.status & 0x01)
 		err = -EINVAL;
 
@@ -449,7 +449,7 @@ static int gdrom_getsense(short *bufstri
 		GDROM_DEFAULT_TIMEOUT);
 	if (gd.pending)
 		goto cleanup_sense;
-	insw(PHYSADDR(GDROM_DATA_REG), &sense, sense_command->buflen/2);
+	insw(GDROM_DATA_REG, &sense, sense_command->buflen/2);
 	if (sense[1] & 40) {
 		printk(KERN_INFO "GDROM: Drive not ready - command aborted\n");
 		goto cleanup_sense;
@@ -586,7 +586,7 @@ static void gdrom_readdisk_dma(struct wo
 		spin_unlock(&gdrom_lock);
 		block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET;
 		block_cnt = blk_rq_sectors(req)/GD_TO_BLK;
-		ctrl_outl(PHYSADDR(req->buffer), GDROM_DMA_STARTADDR_REG);
+		ctrl_outl(virt_to_phys(req->buffer), GDROM_DMA_STARTADDR_REG);
 		ctrl_outl(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG);
 		ctrl_outl(1, GDROM_DMA_DIRECTION_REG);
 		ctrl_outl(1, GDROM_DMA_ENABLE_REG);
@@ -615,7 +615,7 @@ static void gdrom_readdisk_dma(struct wo
 			cpu_relax();
 		gd.pending = 1;
 		gd.transfer = 1;
-		outsw(PHYSADDR(GDROM_DATA_REG), &read_command->cmd, 6);
+		outsw(GDROM_DATA_REG, &read_command->cmd, 6);
 		timeout = jiffies + HZ / 2;
 		/* Wait for any pending DMA to finish */
 		while (ctrl_inb(GDROM_DMA_STATUS_REG) &&
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/amd64-agp.c linux-libre-2.6.33-gnu1/drivers/char/agp/amd64-agp.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/amd64-agp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/amd64-agp.c	2010-02-24 13:52:17.000000000 -0500
@@ -728,6 +728,7 @@ int __init agp_amd64_init(void)
 
 	if (agp_off)
 		return -EINVAL;
+
 	err = pci_register_driver(&agp_amd64_pci_driver);
 	if (err < 0)
 		return err;
@@ -764,19 +765,28 @@ int __init agp_amd64_init(void)
 	return err;
 }
 
+static int __init agp_amd64_mod_init(void)
+{
+#ifndef MODULE
+	if (gart_iommu_aperture)
+		return agp_bridges_found ? 0 : -ENODEV;
+#endif
+	return agp_amd64_init();
+}
+
 static void __exit agp_amd64_cleanup(void)
 {
+#ifndef MODULE
+	if (gart_iommu_aperture)
+		return;
+#endif
 	if (aperture_resource)
 		release_resource(aperture_resource);
 	pci_unregister_driver(&agp_amd64_pci_driver);
 }
 
-/* On AMD64 the PCI driver needs to initialize this driver early
-   for the IOMMU, so it has to be called via a backdoor. */
-#ifndef CONFIG_GART_IOMMU
-module_init(agp_amd64_init);
+module_init(agp_amd64_mod_init);
 module_exit(agp_amd64_cleanup);
-#endif
 
 MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen");
 module_param(agp_try_unsupported, bool, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/backend.c linux-libre-2.6.33-gnu1/drivers/char/agp/backend.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/backend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/backend.c	2010-02-24 13:52:17.000000000 -0500
@@ -285,18 +285,22 @@ int agp_add_bridge(struct agp_bridge_dat
 {
 	int error;
 
-	if (agp_off)
-		return -ENODEV;
+	if (agp_off) {
+		error = -ENODEV;
+		goto err_put_bridge;
+	}
 
 	if (!bridge->dev) {
 		printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
-		return -EINVAL;
+		error = -EINVAL;
+		goto err_put_bridge;
 	}
 
 	/* Grab reference on the chipset driver. */
 	if (!try_module_get(bridge->driver->owner)) {
 		dev_info(&bridge->dev->dev, "can't lock chipset driver\n");
-		return -EINVAL;
+		error = -EINVAL;
+		goto err_put_bridge;
 	}
 
 	error = agp_backend_initialize(bridge);
@@ -326,6 +330,7 @@ frontend_err:
 	agp_backend_cleanup(bridge);
 err_out:
 	module_put(bridge->driver->owner);
+err_put_bridge:
 	agp_put_bridge(bridge);
 	return error;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/frontend.c linux-libre-2.6.33-gnu1/drivers/char/agp/frontend.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/frontend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/frontend.c	2010-02-24 13:52:17.000000000 -0500
@@ -676,25 +676,25 @@ static int agp_open(struct inode *inode,
 	int minor = iminor(inode);
 	struct agp_file_private *priv;
 	struct agp_client *client;
-	int rc = -ENXIO;
-
-	lock_kernel();
-	mutex_lock(&(agp_fe.agp_mutex));
 
 	if (minor != AGPGART_MINOR)
-		goto err_out;
+		return -ENXIO;
+
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
-	if (priv == NULL)
-		goto err_out_nomem;
+	if (priv == NULL) {
+		mutex_unlock(&(agp_fe.agp_mutex));
+		return -ENOMEM;
+	}
 
 	set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
 	priv->my_pid = current->pid;
 
-	if (capable(CAP_SYS_RAWIO)) {
+	if (capable(CAP_SYS_RAWIO))
 		/* Root priv, can be controller */
 		set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);
-	}
+
 	client = agp_find_client_by_pid(current->pid);
 
 	if (client != NULL) {
@@ -704,16 +704,10 @@ static int agp_open(struct inode *inode,
 	file->private_data = (void *) priv;
 	agp_insert_file_private(priv);
 	DBG("private=%p, client=%p", priv, client);
-	mutex_unlock(&(agp_fe.agp_mutex));
-	unlock_kernel();
-	return 0;
 
-err_out_nomem:
-	rc = -ENOMEM;
-err_out:
 	mutex_unlock(&(agp_fe.agp_mutex));
-	unlock_kernel();
-	return rc;
+
+	return 0;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/hp-agp.c linux-libre-2.6.33-gnu1/drivers/char/agp/hp-agp.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/hp-agp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/hp-agp.c	2010-02-24 13:52:17.000000000 -0500
@@ -488,9 +488,8 @@ zx1_gart_probe (acpi_handle obj, u32 dep
 	handle = obj;
 	do {
 		status = acpi_get_object_info(handle, &info);
-		if (ACPI_SUCCESS(status)) {
+		if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) {
 			/* TBD check _CID also */
-			info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0';
 			match = (strcmp(info->hardware_id.string, "HWP0001") == 0);
 			kfree(info);
 			if (match) {
@@ -509,6 +508,9 @@ zx1_gart_probe (acpi_handle obj, u32 dep
 		handle = parent;
 	} while (ACPI_SUCCESS(status));
 
+	if (ACPI_FAILURE(status))
+		return AE_OK;	/* found no enclosing IOC */
+
 	if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
 		return AE_OK;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/intel-agp.c linux-libre-2.6.33-gnu1/drivers/char/agp/intel-agp.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/intel-agp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/intel-agp.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,10 +36,10 @@
 #define PCI_DEVICE_ID_INTEL_82965GME_IG     0x2A12
 #define PCI_DEVICE_ID_INTEL_82945GME_HB     0x27AC
 #define PCI_DEVICE_ID_INTEL_82945GME_IG     0x27AE
-#define PCI_DEVICE_ID_INTEL_IGDGM_HB        0xA010
-#define PCI_DEVICE_ID_INTEL_IGDGM_IG        0xA011
-#define PCI_DEVICE_ID_INTEL_IGDG_HB         0xA000
-#define PCI_DEVICE_ID_INTEL_IGDG_IG         0xA001
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB        0xA010
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG        0xA011
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_HB         0xA000
+#define PCI_DEVICE_ID_INTEL_PINEVIEW_IG         0xA001
 #define PCI_DEVICE_ID_INTEL_G33_HB          0x29C0
 #define PCI_DEVICE_ID_INTEL_G33_IG          0x29C2
 #define PCI_DEVICE_ID_INTEL_Q35_HB          0x29B0
@@ -50,20 +50,20 @@
 #define PCI_DEVICE_ID_INTEL_B43_IG          0x2E42
 #define PCI_DEVICE_ID_INTEL_GM45_HB         0x2A40
 #define PCI_DEVICE_ID_INTEL_GM45_IG         0x2A42
-#define PCI_DEVICE_ID_INTEL_IGD_E_HB        0x2E00
-#define PCI_DEVICE_ID_INTEL_IGD_E_IG        0x2E02
+#define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB        0x2E00
+#define PCI_DEVICE_ID_INTEL_EAGLELAKE_IG        0x2E02
 #define PCI_DEVICE_ID_INTEL_Q45_HB          0x2E10
 #define PCI_DEVICE_ID_INTEL_Q45_IG          0x2E12
 #define PCI_DEVICE_ID_INTEL_G45_HB          0x2E20
 #define PCI_DEVICE_ID_INTEL_G45_IG          0x2E22
 #define PCI_DEVICE_ID_INTEL_G41_HB          0x2E30
 #define PCI_DEVICE_ID_INTEL_G41_IG          0x2E32
-#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB	    0x0040
-#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG	    0x0042
-#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB	    0x0044
-#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB	    0x0062
-#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB    0x006a
-#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG	    0x0046
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB	    0x0040
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG	    0x0042
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB	    0x0044
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB	    0x0062
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB    0x006a
+#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG	    0x0046
 
 /* cover 915 and 945 variants */
 #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@@ -83,22 +83,22 @@
 #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
-#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+#define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
-#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
+#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
-		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB)
 
 extern int agp_memory_reserved;
 
@@ -178,6 +178,7 @@ static struct _intel_private {
 	 * popup and for the GTT.
 	 */
 	int gtt_entries;			/* i830+ */
+	int gtt_total_size;
 	union {
 		void __iomem *i9xx_flush_page;
 		void *i8xx_flush_page;
@@ -653,7 +654,7 @@ static void intel_i830_init_gtt_entries(
 			size = 512;
 		}
 		size += 4; /* add in BIOS popup space */
-	} else if (IS_G33 && !IS_IGD) {
+	} else if (IS_G33 && !IS_PINEVIEW) {
 	/* G33's GTT size defined in gmch_ctrl */
 		switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
 		case G33_PGETBL_SIZE_1M:
@@ -669,7 +670,7 @@ static void intel_i830_init_gtt_entries(
 			size = 512;
 		}
 		size += 4;
-	} else if (IS_G4X || IS_IGD) {
+	} else if (IS_G4X || IS_PINEVIEW) {
 		/* On 4 series hardware, GTT stolen is separate from graphics
 		 * stolen, ignore it in stolen gtt entries counting.  However,
 		 * 4KB of the stolen memory doesn't get mapped to the GTT.
@@ -1153,7 +1154,7 @@ static int intel_i915_configure(void)
 	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 	if (agp_bridge->driver->needs_scratch_page) {
-		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+		for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) {
 			writel(agp_bridge->scratch_page, intel_private.gtt+i);
 		}
 		readl(intel_private.gtt+i-1);	/* PCI Posting. */
@@ -1308,6 +1309,8 @@ static int intel_i915_create_gatt_table(
 	if (!intel_private.gtt)
 		return -ENOMEM;
 
+	intel_private.gtt_total_size = gtt_map_size / 4;
+
 	temp &= 0xfff80000;
 
 	intel_private.registers = ioremap(temp, 128 * 4096);
@@ -1352,15 +1355,15 @@ static void intel_i965_get_gtt_range(int
 {
 	switch (agp_bridge->dev->device) {
 	case PCI_DEVICE_ID_INTEL_GM45_HB:
-	case PCI_DEVICE_ID_INTEL_IGD_E_HB:
+	case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
 	case PCI_DEVICE_ID_INTEL_Q45_HB:
 	case PCI_DEVICE_ID_INTEL_G45_HB:
 	case PCI_DEVICE_ID_INTEL_G41_HB:
 	case PCI_DEVICE_ID_INTEL_B43_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
-	case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
+	case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
 		*gtt_offset = *gtt_size = MB(2);
 		break;
 	default:
@@ -1395,6 +1398,8 @@ static int intel_i965_create_gatt_table(
 	if (!intel_private.gtt)
 		return -ENOMEM;
 
+	intel_private.gtt_total_size = gtt_size / 4;
+
 	intel_private.registers = ioremap(temp, 128 * 4096);
 	if (!intel_private.registers) {
 		iounmap(intel_private.gtt);
@@ -2340,14 +2345,14 @@ static const struct intel_driver_descrip
 		NULL, &intel_g33_driver },
 	{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
 		NULL, &intel_g33_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview",
 		NULL, &intel_g33_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+	{ PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview",
 		NULL, &intel_g33_driver },
 	{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
-	    "Mobile Intel® GM45 Express", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
-	    "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
+	    "GM45", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, 0,
+	    "Eaglelake", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
 	    "Q45/Q43", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0,
@@ -2356,14 +2361,14 @@ static const struct intel_driver_descrip
 	    "B43", NULL, &intel_i965_driver },
 	{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
 	    "G41", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0,
-	    "IGDNG/D", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/M", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/MA", NULL, &intel_i965_driver },
-	{ PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
-	    "IGDNG/MC2", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0,
+	    "Ironlake/D", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/M", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/MA", NULL, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+	    "Ironlake/MC2", NULL, &intel_i965_driver },
 	{ 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2455,10 +2460,14 @@ static int __devinit agp_intel_probe(str
 				&bridge->mode);
 	}
 
-	if (bridge->driver->mask_memory == intel_i965_mask_memory)
+	if (bridge->driver->mask_memory == intel_i965_mask_memory) {
 		if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
 			dev_err(&intel_private.pcidev->dev,
 				"set gfx device dma mask 36bit failed!\n");
+		else
+			pci_set_consistent_dma_mask(intel_private.pcidev,
+						    DMA_BIT_MASK(36));
+	}
 
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
@@ -2545,8 +2554,8 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
+	ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
+	ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
 	ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
 	ID(PCI_DEVICE_ID_INTEL_82G35_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
@@ -2557,15 +2566,15 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_Q35_HB),
 	ID(PCI_DEVICE_ID_INTEL_Q33_HB),
 	ID(PCI_DEVICE_ID_INTEL_GM45_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
+	ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
 	ID(PCI_DEVICE_ID_INTEL_Q45_HB),
 	ID(PCI_DEVICE_ID_INTEL_G45_HB),
 	ID(PCI_DEVICE_ID_INTEL_G41_HB),
 	ID(PCI_DEVICE_ID_INTEL_B43_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
-	ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
+	ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
 	{ }
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/Kconfig linux-libre-2.6.33-gnu1/drivers/char/agp/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/char/agp/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -56,9 +56,8 @@ config AGP_AMD
 	  X on AMD Irongate, 761, and 762 chipsets.
 
 config AGP_AMD64
-	tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
+	tristate "AMD Opteron/Athlon64 on-CPU GART support"
 	depends on AGP && X86
-	default y if GART_IOMMU
 	help
 	  This option gives you AGP support for the GLX component of
 	  X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/agp/uninorth-agp.c linux-libre-2.6.33-gnu1/drivers/char/agp/uninorth-agp.c
--- linux-libre-2.6.32-gnu1/drivers/char/agp/uninorth-agp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/agp/uninorth-agp.c	2010-02-24 13:52:17.000000000 -0500
@@ -144,16 +144,13 @@ static int uninorth_configure(void)
 	return 0;
 }
 
-static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
-				int type)
+static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
-	int i, j, num_entries;
+	int i, num_entries;
 	void *temp;
+	u32 *gp;
 	int mask_type;
 
-	temp = agp_bridge->current_size;
-	num_entries = A_SIZE_32(temp)->num_entries;
-
 	if (type != mem->type)
 		return -EINVAL;
 
@@ -163,49 +160,12 @@ static int uninorth_insert_memory(struct
 		return -EINVAL;
 	}
 
-	if ((pg_start + mem->page_count) > num_entries)
-		return -EINVAL;
-
-	j = pg_start;
-
-	while (j < (pg_start + mem->page_count)) {
-		if (agp_bridge->gatt_table[j])
-			return -EBUSY;
-		j++;
-	}
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		agp_bridge->gatt_table[j] =
-			cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) | 0x1UL);
-		flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])),
-				   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
-	}
-	(void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
-	mb();
-
-	uninorth_tlbflush(mem);
-	return 0;
-}
-
-static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
-{
-	int i, num_entries;
-	void *temp;
-	u32 *gp;
-	int mask_type;
+	if (mem->page_count == 0)
+		return 0;
 
 	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_32(temp)->num_entries;
 
-	if (type != mem->type)
-		return -EINVAL;
-
-	mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
-	if (mask_type != 0) {
-		/* We know nothing of memory types */
-		return -EINVAL;
-	}
-
 	if ((pg_start + mem->page_count) > num_entries)
 		return -EINVAL;
 
@@ -213,14 +173,18 @@ static int u3_insert_memory(struct agp_m
 	for (i = 0; i < mem->page_count; ++i) {
 		if (gp[i]) {
 			dev_info(&agp_bridge->dev->dev,
-				 "u3_insert_memory: entry 0x%x occupied (%x)\n",
+				 "uninorth_insert_memory: entry 0x%x occupied (%x)\n",
 				 i, gp[i]);
 			return -EBUSY;
 		}
 	}
 
 	for (i = 0; i < mem->page_count; i++) {
-		gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL;
+		if (is_u3)
+			gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL;
+		else
+			gp[i] =	cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) |
+					    0x1UL);
 		flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])),
 				   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
 	}
@@ -230,14 +194,23 @@ static int u3_insert_memory(struct agp_m
 	return 0;
 }
 
-int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
+int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	size_t i;
 	u32 *gp;
+	int mask_type;
 
-	if (type != 0 || mem->type != 0)
+	if (type != mem->type)
+		return -EINVAL;
+
+	mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
+	if (mask_type != 0) {
 		/* We know nothing of memory types */
 		return -EINVAL;
+	}
+
+	if (mem->page_count == 0)
+		return 0;
 
 	gp = (u32 *) &agp_bridge->gatt_table[pg_start];
 	for (i = 0; i < mem->page_count; ++i)
@@ -536,7 +509,7 @@ const struct agp_bridge_driver uninorth_
 	.create_gatt_table	= uninorth_create_gatt_table,
 	.free_gatt_table	= uninorth_free_gatt_table,
 	.insert_memory		= uninorth_insert_memory,
-	.remove_memory		= agp_generic_remove_memory,
+	.remove_memory		= uninorth_remove_memory,
 	.alloc_by_type		= agp_generic_alloc_by_type,
 	.free_by_type		= agp_generic_free_by_type,
 	.agp_alloc_page		= agp_generic_alloc_page,
@@ -562,8 +535,8 @@ const struct agp_bridge_driver u3_agp_dr
 	.agp_enable		= uninorth_agp_enable,
 	.create_gatt_table	= uninorth_create_gatt_table,
 	.free_gatt_table	= uninorth_free_gatt_table,
-	.insert_memory		= u3_insert_memory,
-	.remove_memory		= u3_remove_memory,
+	.insert_memory		= uninorth_insert_memory,
+	.remove_memory		= uninorth_remove_memory,
 	.alloc_by_type		= agp_generic_alloc_by_type,
 	.free_by_type		= agp_generic_free_by_type,
 	.agp_alloc_page		= agp_generic_alloc_page,
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/bfin_jtag_comm.c linux-libre-2.6.33-gnu1/drivers/char/bfin_jtag_comm.c
--- linux-libre-2.6.32-gnu1/drivers/char/bfin_jtag_comm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/bfin_jtag_comm.c	2010-02-24 13:52:17.000000000 -0500
@@ -226,7 +226,7 @@ bfin_jc_wait_until_sent(struct tty_struc
 	}
 }
 
-static struct tty_operations bfin_jc_ops = {
+static const struct tty_operations bfin_jc_ops = {
 	.open            = bfin_jc_open,
 	.close           = bfin_jc_close,
 	.write           = bfin_jc_write,
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/cs5535_gpio.c linux-libre-2.6.33-gnu1/drivers/char/cs5535_gpio.c
--- linux-libre-2.6.32-gnu1/drivers/char/cs5535_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/cs5535_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,7 @@
 #include <linux/cdev.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
+
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -158,7 +158,6 @@ static int cs5535_gpio_open(struct inode
 {
 	u32 m = iminor(inode);
 
-	cycle_kernel_lock();
 	/* the mask says which pins are usable by this driver */
 	if ((mask & (1 << m)) == 0)
 		return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/efirtc.c linux-libre-2.6.33-gnu1/drivers/char/efirtc.c
--- linux-libre-2.6.32-gnu1/drivers/char/efirtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/efirtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,8 +27,6 @@
  * 	- Add module support
  */
 
-
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
@@ -174,13 +172,12 @@ static long efi_rtc_ioctl(struct file *f
 			return -EINVAL;
 
 		case RTC_RD_TIME:
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.get_time(&eft, &cap);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
+
 			if (status != EFI_SUCCESS) {
 				/* should never happen */
 				printk(KERN_ERR "efitime: can't read time\n");
@@ -202,13 +199,11 @@ static long efi_rtc_ioctl(struct file *f
 
 			convert_to_efi_time(&wtime, &eft);
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.set_time(&eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			return status == EFI_SUCCESS ? 0 : -EINVAL;
 
@@ -224,7 +219,6 @@ static long efi_rtc_ioctl(struct file *f
 
 			convert_to_efi_time(&wtime, &eft);
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 			/*
 			 * XXX Fixme:
@@ -235,19 +229,16 @@ static long efi_rtc_ioctl(struct file *f
 			status = efi.set_wakeup_time((efi_bool_t)enabled, &eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			return status == EFI_SUCCESS ? 0 : -EINVAL;
 
 		case RTC_WKALM_RD:
 
-			lock_kernel();
 			spin_lock_irqsave(&efi_rtc_lock, flags);
 
 			status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft);
 
 			spin_unlock_irqrestore(&efi_rtc_lock,flags);
-			unlock_kernel();
 
 			if (status != EFI_SUCCESS) return -EINVAL;
 
@@ -277,7 +268,6 @@ static int efi_rtc_open(struct inode *in
 	 * We do accept multiple open files at the same time as we
 	 * synchronize on the per call operation.
 	 */
-	cycle_kernel_lock();
 	return 0;
 }
 
@@ -295,6 +285,7 @@ static const struct file_operations efi_
 	.unlocked_ioctl	= efi_rtc_ioctl,
 	.open		= efi_rtc_open,
 	.release	= efi_rtc_close,
+	.llseek		= no_llseek,
 };
 
 static struct miscdevice efi_rtc_dev= {
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/epca.c linux-libre-2.6.33-gnu1/drivers/char/epca.c
--- linux-libre-2.6.32-gnu1/drivers/char/epca.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/epca.c	2010-02-24 13:52:17.000000000 -0500
@@ -935,7 +935,7 @@ static int info_open(struct tty_struct *
 	return 0;
 }
 
-static struct tty_operations info_ops = {
+static const struct tty_operations info_ops = {
 	.open = info_open,
 	.ioctl = info_ioctl,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/esp.c linux-libre-2.6.33-gnu1/drivers/char/esp.c
--- linux-libre-2.6.32-gnu1/drivers/char/esp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/esp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2533 +0,0 @@
-/*
- *  esp.c - driver for Hayes ESP serial cards
- *
- *  --- Notices from serial.c, upon which this driver is based ---
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
- *  much more extensible to support other serial cards based on the
- *  16450/16550A UART's.  Added support for the AST FourPort and the
- *  Accent Async board.
- *
- *  set_serial_info fixed to set the flags, custom divisor, and uart
- * 	type fields.  Fix suggested by Michael K. Johnson 12/12/92.
- *
- *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- *  rs_set_termios fixed to look also for changes of the input
- *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anhäupl 05/17/96.
- *
- * --- End of notices from serial.c ---
- *
- * Support for the ESP serial card by Andrew J. Robinson
- *     <arobinso@nyx.net> (Card detection routine taken from a patch
- *     by Dennis J. Boylan).  Patches to allow use with 2.1.x contributed
- *     by Chris Faylor.
- *
- * Most recent changes: (Andrew J. Robinson)
- *   Support for PIO mode.  This allows the driver to work properly with
- *     multiport cards.
- *
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> -
- * several cleanups, use module_init/module_exit, etc
- *
- * This module exports the following rs232 io functions:
- *
- *	int espserial_init(void);
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/hayesesp.h>
-
-#define NR_PORTS 64	/* maximum number of ports */
-#define NR_PRIMARY 8	/* maximum number of primary ports */
-#define REGION_SIZE 8   /* size of io region to request */
-
-/* The following variables can be set by giving module options */
-static int irq[NR_PRIMARY];	/* IRQ for each base port */
-static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */
-static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */
-static unsigned int rx_trigger = ESP_RX_TRIGGER;
-static unsigned int tx_trigger = ESP_TX_TRIGGER;
-static unsigned int flow_off = ESP_FLOW_OFF;
-static unsigned int flow_on = ESP_FLOW_ON;
-static unsigned int rx_timeout = ESP_RX_TMOUT;
-static unsigned int pio_threshold = ESP_PIO_THRESHOLD;
-
-MODULE_LICENSE("GPL");
-
-module_param_array(irq, int, NULL, 0);
-module_param_array(divisor, uint, NULL, 0);
-module_param(dma, uint, 0);
-module_param(rx_trigger, uint, 0);
-module_param(tx_trigger, uint, 0);
-module_param(flow_off, uint, 0);
-module_param(flow_on, uint, 0);
-module_param(rx_timeout, uint, 0);
-module_param(pio_threshold, uint, 0);
-
-/* END */
-
-static char *dma_buffer;
-static int dma_bytes;
-static struct esp_pio_buffer *free_pio_buf;
-
-#define DMA_BUFFER_SZ 1024
-
-#define WAKEUP_CHARS 1024
-
-static char serial_name[] __initdata = "ESP serial driver";
-static char serial_version[] __initdata = "2.2";
-
-static struct tty_driver *esp_driver;
-
-/*
- * Serial driver configuration section.  Here are the various options:
- *
- * SERIAL_PARANOIA_CHECK
- * 		Check the magic number for the esp_structure where
- * 		ever possible.
- */
-
-#undef SERIAL_PARANOIA_CHECK
-#define SERIAL_DO_RESTART
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
-				tty->name, info->port.flags, \
-				serial_driver.refcount, \
-				info->port.count, tty->count, s)
-#else
-#define DBG_CNT(s)
-#endif
-
-static struct esp_struct *ports;
-
-static void change_speed(struct esp_struct *info);
-static void rs_wait_until_sent(struct tty_struct *, int);
-
-/*
- * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE
- * times the normal 1.8432 Mhz clock of most serial boards).
- */
-#define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE))
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-static inline int serial_paranoia_check(struct esp_struct *info,
-					char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char badmagic[] = KERN_WARNING
-		"Warning: bad magic number for serial struct (%s) in %s\n";
-	static const char badinfo[] = KERN_WARNING
-		"Warning: null esp_struct for (%s) in %s\n";
-
-	if (!info) {
-		printk(badinfo, name, routine);
-		return 1;
-	}
-	if (info->magic != ESP_MAGIC) {
-		printk(badmagic, name, routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static inline unsigned int serial_in(struct esp_struct *info, int offset)
-{
-	return inb(info->io_port + offset);
-}
-
-static inline void serial_out(struct esp_struct *info, int offset,
-			      unsigned char value)
-{
-	outb(value, info->io_port+offset);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_stop"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->IER & UART_IER_THRI) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_start"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt().  They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-static DEFINE_SPINLOCK(pio_lock);
-
-static inline struct esp_pio_buffer *get_pio_buffer(void)
-{
-	struct esp_pio_buffer *buf;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pio_lock, flags);
-	if (free_pio_buf) {
-		buf = free_pio_buf;
-		free_pio_buf = buf->next;
-	} else {
-		buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC);
-	}
-	spin_unlock_irqrestore(&pio_lock, flags);
-	return buf;
-}
-
-static inline void release_pio_buffer(struct esp_pio_buffer *buf)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&pio_lock, flags);
-	buf->next = free_pio_buf;
-	free_pio_buf = buf;
-	spin_unlock_irqrestore(&pio_lock, flags);
-}
-
-static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
-{
-	struct tty_struct *tty = info->port.tty;
-	int i;
-	struct esp_pio_buffer *pio_buf;
-	struct esp_pio_buffer *err_buf;
-	unsigned char status_mask;
-
-	pio_buf = get_pio_buffer();
-
-	if (!pio_buf)
-		return;
-
-	err_buf = get_pio_buffer();
-
-	if (!err_buf) {
-		release_pio_buffer(pio_buf);
-		return;
-	}
-
-	status_mask = (info->read_status_mask >> 2) & 0x07;
-
-	for (i = 0; i < num_bytes - 1; i += 2) {
-		*((unsigned short *)(pio_buf->data + i)) =
-			inw(info->io_port + UART_ESI_RX);
-		err_buf->data[i] = serial_in(info, UART_ESI_RWS);
-		err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
-		err_buf->data[i] &= status_mask;
-	}
-
-	if (num_bytes & 0x0001) {
-		pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX);
-		err_buf->data[num_bytes - 1] =
-			(serial_in(info, UART_ESI_RWS) >> 3) & status_mask;
-	}
-
-	/* make sure everything is still ok since interrupts were enabled */
-	tty = info->port.tty;
-
-	if (!tty) {
-		release_pio_buffer(pio_buf);
-		release_pio_buffer(err_buf);
-		info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-		return;
-	}
-
-	status_mask = (info->ignore_status_mask >> 2) & 0x07;
-
-	for (i = 0; i < num_bytes; i++) {
-		if (!(err_buf->data[i] & status_mask)) {
-			int flag = 0;
-
-			if (err_buf->data[i] & 0x04) {
-				flag = TTY_BREAK;
-				if (info->port.flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (err_buf->data[i] & 0x02)
-				flag = TTY_FRAME;
-			else if (err_buf->data[i] & 0x01)
-				flag = TTY_PARITY;
-			tty_insert_flip_char(tty, pio_buf->data[i], flag);
-		}
-	}
-
-	tty_schedule_flip(tty);
-
-	info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-	release_pio_buffer(pio_buf);
-	release_pio_buffer(err_buf);
-}
-
-static void program_isa_dma(int dma, int dir, unsigned long addr, int len)
-{
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-	set_dma_mode(dma, dir);
-	set_dma_addr(dma, addr);
-	set_dma_count(dma, len);
-	enable_dma(dma);
-	release_dma_lock(flags);
-}
-
-static void receive_chars_dma(struct esp_struct *info, int num_bytes)
-{
-	info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
-	dma_bytes = num_bytes;
-	info->stat_flags |= ESP_STAT_DMA_RX;
-
-	program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer),
-								dma_bytes);
-	serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
-}
-
-static inline void receive_chars_dma_done(struct esp_struct *info,
-					    int status)
-{
-	struct tty_struct *tty = info->port.tty;
-	int num_bytes;
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-
-	info->stat_flags &= ~ESP_STAT_DMA_RX;
-	num_bytes = dma_bytes - get_dma_residue(dma);
-	release_dma_lock(flags);
-
-	info->icount.rx += num_bytes;
-
-	if (num_bytes > 0) {
-		tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
-
-		status &= (0x1c & info->read_status_mask);
-
-		/* Is the status significant or do we throw the last byte ? */
-		if (!(status & info->ignore_status_mask)) {
-			int statflag = 0;
-
-			if (status & 0x10) {
-				statflag = TTY_BREAK;
-				(info->icount.brk)++;
-				if (info->port.flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (status & 0x08) {
-				statflag = TTY_FRAME;
-				info->icount.frame++;
-			} else if (status & 0x04) {
-				statflag = TTY_PARITY;
-				info->icount.parity++;
-			}
-			tty_insert_flip_char(tty, dma_buffer[num_bytes - 1],
-								statflag);
-		}
-		tty_schedule_flip(tty);
-	}
-
-	if (dma_bytes != num_bytes) {
-		num_bytes = dma_bytes - num_bytes;
-		dma_bytes = 0;
-		receive_chars_dma(info, num_bytes);
-	} else
-		dma_bytes = 0;
-}
-
-/* Caller must hold info->lock */
-
-static inline void transmit_chars_pio(struct esp_struct *info,
-					int space_avail)
-{
-	int i;
-	struct esp_pio_buffer *pio_buf;
-
-	pio_buf = get_pio_buffer();
-
-	if (!pio_buf)
-		return;
-
-	while (space_avail && info->xmit_cnt) {
-		if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) {
-			memcpy(pio_buf->data,
-			       &(info->xmit_buf[info->xmit_tail]),
-			       space_avail);
-		} else {
-			i = ESP_XMIT_SIZE - info->xmit_tail;
-			memcpy(pio_buf->data,
-			       &(info->xmit_buf[info->xmit_tail]), i);
-			memcpy(&(pio_buf->data[i]), info->xmit_buf,
-			       space_avail - i);
-		}
-
-		info->xmit_cnt -= space_avail;
-		info->xmit_tail = (info->xmit_tail + space_avail) &
-			(ESP_XMIT_SIZE - 1);
-
-		for (i = 0; i < space_avail - 1; i += 2) {
-			outw(*((unsigned short *)(pio_buf->data + i)),
-			     info->io_port + UART_ESI_TX);
-		}
-
-		if (space_avail & 0x0001)
-			serial_out(info, UART_ESI_TX,
-				   pio_buf->data[space_avail - 1]);
-
-		if (info->xmit_cnt) {
-			serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-			serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-			space_avail = serial_in(info, UART_ESI_STAT1) << 8;
-			space_avail |= serial_in(info, UART_ESI_STAT2);
-
-			if (space_avail > info->xmit_cnt)
-				space_avail = info->xmit_cnt;
-		}
-	}
-
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if (info->port.tty)
-			tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
-		printk("THRE...");
-#endif
-
-		if (info->xmit_cnt <= 0) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1,
-				   ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		}
-	}
-
-	release_pio_buffer(pio_buf);
-}
-
-/* Caller must hold info->lock */
-static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
-{
-	dma_bytes = num_bytes;
-
-	if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
-		memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
-		       dma_bytes);
-	} else {
-		int i = ESP_XMIT_SIZE - info->xmit_tail;
-		memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
-			i);
-		memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i);
-	}
-
-	info->xmit_cnt -= dma_bytes;
-	info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
-
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if (info->port.tty)
-			tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
-		printk("THRE...");
-#endif
-
-		if (info->xmit_cnt <= 0) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		}
-	}
-
-	info->stat_flags |= ESP_STAT_DMA_TX;
-
-	program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer),
-								dma_bytes);
-	serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-}
-
-static inline void transmit_chars_dma_done(struct esp_struct *info)
-{
-	int num_bytes;
-	unsigned long flags;
-
-	flags = claim_dma_lock();
-	disable_dma(dma);
-	clear_dma_ff(dma);
-
-	num_bytes = dma_bytes - get_dma_residue(dma);
-	info->icount.tx += dma_bytes;
-	release_dma_lock(flags);
-
-	if (dma_bytes != num_bytes) {
-		dma_bytes -= num_bytes;
-		memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes);
-
-		program_isa_dma(dma, DMA_MODE_WRITE,
-				isa_virt_to_bus(dma_buffer), dma_bytes);
-
-		serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-	} else {
-		dma_bytes = 0;
-		info->stat_flags &= ~ESP_STAT_DMA_TX;
-	}
-}
-
-static void check_modem_status(struct esp_struct *info)
-{
-	int	status;
-
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT2);
-
-	if (status & UART_MSR_ANY_DELTA) {
-		/* update input line counters */
-		if (status & UART_MSR_TERI)
-			info->icount.rng++;
-		if (status & UART_MSR_DDSR)
-			info->icount.dsr++;
-		if (status & UART_MSR_DDCD)
-			info->icount.dcd++;
-		if (status & UART_MSR_DCTS)
-			info->icount.cts++;
-		wake_up_interruptible(&info->port.delta_msr_wait);
-	}
-
-	if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
-		printk("ttys%d CD now %s...", info->line,
-		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif
-		if (status & UART_MSR_DCD)
-			wake_up_interruptible(&info->port.open_wait);
-		else {
-#ifdef SERIAL_DEBUG_OPEN
-			printk("scheduling hangup...");
-#endif
-			tty_hangup(info->port.tty);
-		}
-	}
-}
-
-/*
- * This is the serial driver's interrupt routine
- */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
-{
-	struct esp_struct *info;
-	unsigned err_status;
-	unsigned int scratch;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("rs_interrupt_single(%d)...", irq);
-#endif
-	info = (struct esp_struct *)dev_id;
-	err_status = 0;
-	scratch = serial_in(info, UART_ESI_SID);
-
-	spin_lock(&info->lock);
-
-	if (!info->port.tty) {
-		spin_unlock(&info->lock);
-		return IRQ_NONE;
-	}
-
-	if (scratch & 0x04) { /* error */
-		serial_out(info, UART_ESI_CMD1, ESI_GET_ERR_STAT);
-		err_status = serial_in(info, UART_ESI_STAT1);
-		serial_in(info, UART_ESI_STAT2);
-
-		if (err_status & 0x01)
-			info->stat_flags |= ESP_STAT_RX_TIMEOUT;
-
-		if (err_status & 0x20) /* UART status */
-			check_modem_status(info);
-
-		if (err_status & 0x80) /* Start break */
-			wake_up_interruptible(&info->break_wait);
-	}
-
-	if ((scratch & 0x88) || /* DMA completed or timed out */
-	    (err_status & 0x1c) /* receive error */) {
-		if (info->stat_flags & ESP_STAT_DMA_RX)
-			receive_chars_dma_done(info, err_status);
-		else if (info->stat_flags & ESP_STAT_DMA_TX)
-			transmit_chars_dma_done(info);
-	}
-
-	if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
-	    ((scratch & 0x01) || (info->stat_flags & ESP_STAT_RX_TIMEOUT)) &&
-	    (info->IER & UART_IER_RDI)) {
-		int num_bytes;
-
-		serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-		serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
-		num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
-		num_bytes |= serial_in(info, UART_ESI_STAT2);
-
-		num_bytes = tty_buffer_request_room(info->port.tty, num_bytes);
-
-		if (num_bytes) {
-			if (dma_bytes ||
-			    (info->stat_flags & ESP_STAT_USE_PIO) ||
-			    (num_bytes <= info->config.pio_threshold))
-				receive_chars_pio(info, num_bytes);
-			else
-				receive_chars_dma(info, num_bytes);
-		}
-	}
-
-	if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
-	    (scratch & 0x02) && (info->IER & UART_IER_THRI)) {
-		if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
-			info->IER &= ~UART_IER_THRI;
-			serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-			serial_out(info, UART_ESI_CMD2, info->IER);
-		} else {
-			int num_bytes;
-
-			serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-			serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-			num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
-			num_bytes |= serial_in(info, UART_ESI_STAT2);
-
-			if (num_bytes > info->xmit_cnt)
-				num_bytes = info->xmit_cnt;
-
-			if (num_bytes) {
-				if (dma_bytes ||
-				    (info->stat_flags & ESP_STAT_USE_PIO) ||
-				    (num_bytes <= info->config.pio_threshold))
-					transmit_chars_pio(info, num_bytes);
-				else
-					transmit_chars_dma(info, num_bytes);
-			}
-		}
-	}
-
-	info->last_active = jiffies;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-	spin_unlock(&info->lock);
-	return IRQ_HANDLED;
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver:  routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port.  Useful stuff like that.
- *
- * Caller should hold lock
- * ---------------------------------------------------------------
- */
-
-static void esp_basic_init(struct esp_struct *info)
-{
-	/* put ESPC in enhanced mode */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_MODE);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0x01);
-	else
-		serial_out(info, UART_ESI_CMD2, 0x31);
-
-	/* disable interrupts for now */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	/* set interrupt and DMA channel */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_IRQ);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0x01);
-	else
-		serial_out(info, UART_ESI_CMD2, (dma << 4) | 0x01);
-
-	serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
-
-	if (info->line % 8)	/* secondary port */
-		serial_out(info, UART_ESI_CMD2, 0x0d);	/* shared */
-	else if (info->irq == 9)
-		serial_out(info, UART_ESI_CMD2, 0x02);
-	else
-		serial_out(info, UART_ESI_CMD2, info->irq);
-
-	/* set error status mask (check this) */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_ERR_MASK);
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		serial_out(info, UART_ESI_CMD2, 0xa1);
-	else
-		serial_out(info, UART_ESI_CMD2, 0xbd);
-
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	/* set DMA timeout */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_DMA_TMOUT);
-	serial_out(info, UART_ESI_CMD2, 0xff);
-
-	/* set FIFO trigger levels */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_trigger >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_trigger);
-	serial_out(info, UART_ESI_CMD2, info->config.tx_trigger >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.tx_trigger);
-
-	/* Set clock scaling and wait states */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_PRESCALAR);
-	serial_out(info, UART_ESI_CMD2, 0x04 | ESPC_SCALE);
-
-	/* set reinterrupt pacing */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_REINTR);
-	serial_out(info, UART_ESI_CMD2, 0xff);
-}
-
-static int startup(struct esp_struct *info)
-{
-	unsigned long flags;
-	int	retval = 0;
-	unsigned int num_chars;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->port.flags & ASYNC_INITIALIZED)
-		goto out;
-
-	if (!info->xmit_buf) {
-		info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_ATOMIC);
-		retval = -ENOMEM;
-		if (!info->xmit_buf)
-			goto out;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "starting up ttys%d (irq %d)...",
-						info->line, info->irq);
-#endif
-
-	/* Flush the RX buffer.  Using the ESI flush command may cause */
-	/* wild interrupts, so read all the data instead. */
-
-	serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
-	num_chars = serial_in(info, UART_ESI_STAT1) << 8;
-	num_chars |= serial_in(info, UART_ESI_STAT2);
-
-	while (num_chars > 1) {
-		inw(info->io_port + UART_ESI_RX);
-		num_chars -= 2;
-	}
-
-	if (num_chars)
-		serial_in(info, UART_ESI_RX);
-
-	/* set receive character timeout */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
-
-	/* clear all flags except the "never DMA" flag */
-	info->stat_flags &= ESP_STAT_NEVER_DMA;
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		info->stat_flags |= ESP_STAT_USE_PIO;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Allocate the IRQ
-	 */
-
-	retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED,
-			     "esp serial", info);
-
-	if (retval) {
-		if (capable(CAP_SYS_ADMIN)) {
-			if (info->port.tty)
-				set_bit(TTY_IO_ERROR,
-					&info->port.tty->flags);
-			retval = 0;
-		}
-		goto out_unlocked;
-	}
-
-	if (!(info->stat_flags & ESP_STAT_USE_PIO) && !dma_buffer) {
-		dma_buffer = (char *)__get_dma_pages(
-			GFP_KERNEL, get_order(DMA_BUFFER_SZ));
-
-		/* use PIO mode if DMA buf/chan cannot be allocated */
-		if (!dma_buffer)
-			info->stat_flags |= ESP_STAT_USE_PIO;
-		else if (request_dma(dma, "esp serial")) {
-			free_pages((unsigned long)dma_buffer,
-				   get_order(DMA_BUFFER_SZ));
-			dma_buffer = NULL;
-			info->stat_flags |= ESP_STAT_USE_PIO;
-		}
-
-	}
-
-	info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	/*
-	 * Finally, enable interrupts
-	 */
-	/* info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; */
-	info->IER = UART_IER_RLSI | UART_IER_RDI | UART_IER_DMA_TMOUT |
-			UART_IER_DMA_TC;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-
-	if (info->port.tty)
-		clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-	if (info->port.tty) {
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			info->port.tty->alt_speed = 57600;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			info->port.tty->alt_speed = 115200;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-			info->port.tty->alt_speed = 230400;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-			info->port.tty->alt_speed = 460800;
-	}
-
-	/*
-	 * set the speed of the serial port
-	 */
-	change_speed(info);
-	info->port.flags |= ASYNC_INITIALIZED;
-	return 0;
-
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-out_unlocked:
-	return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct esp_struct *info)
-{
-	unsigned long	flags, f;
-
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		return;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d (irq %d)....", info->line,
-	       info->irq);
-#endif
-
-	spin_lock_irqsave(&info->lock, flags);
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-	 * here so the queue might never be waken up
-	 */
-	wake_up_interruptible(&info->port.delta_msr_wait);
-	wake_up_interruptible(&info->break_wait);
-
-	/* stop a DMA transfer on the port being closed */
-	/* DMA lock is higher priority always */
-	if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) {
-		f = claim_dma_lock();
-		disable_dma(dma);
-		clear_dma_ff(dma);
-		release_dma_lock(f);
-
-		dma_bytes = 0;
-	}
-
-	/*
-	 * Free the IRQ
-	 */
-	free_irq(info->irq, info);
-
-	if (dma_buffer) {
-		struct esp_struct *current_port = ports;
-
-		while (current_port) {
-			if ((current_port != info) &&
-			    (current_port->port.flags & ASYNC_INITIALIZED))
-				break;
-
-			current_port = current_port->next_port;
-		}
-
-		if (!current_port) {
-			free_dma(dma);
-			free_pages((unsigned long)dma_buffer,
-				   get_order(DMA_BUFFER_SZ));
-			dma_buffer = NULL;
-		}
-	}
-
-	if (info->xmit_buf) {
-		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = NULL;
-	}
-
-	info->IER = 0;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-
-	if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-
-	info->MCR &= ~UART_MCR_OUT2;
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	if (info->port.tty)
-		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
-
-	info->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct esp_struct *info)
-{
-	unsigned short port;
-	int	quot = 0;
-	unsigned cflag, cval;
-	int	baud, bits;
-	unsigned char flow1 = 0, flow2 = 0;
-	unsigned long flags;
-
-	if (!info->port.tty || !info->port.tty->termios)
-		return;
-	cflag = info->port.tty->termios->c_cflag;
-	port = info->io_port;
-
-	/* byte size and parity */
-	switch (cflag & CSIZE) {
-	case CS5: cval = 0x00; bits = 7; break;
-	case CS6: cval = 0x01; bits = 8; break;
-	case CS7: cval = 0x02; bits = 9; break;
-	case CS8: cval = 0x03; bits = 10; break;
-	default:  cval = 0x00; bits = 7; break;
-	}
-	if (cflag & CSTOPB) {
-		cval |= 0x04;
-		bits++;
-	}
-	if (cflag & PARENB) {
-		cval |= UART_LCR_PARITY;
-		bits++;
-	}
-	if (!(cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-	if (cflag & CMSPAR)
-		cval |= UART_LCR_SPAR;
-#endif
-	baud = tty_get_baud_rate(info->port.tty);
-	if (baud == 38400 &&
-		((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-		quot = info->custom_divisor;
-	else {
-		if (baud == 134) /* Special case since 134 is really 134.5 */
-			quot = (2*BASE_BAUD / 269);
-		else if (baud)
-			quot = BASE_BAUD / baud;
-	}
-	/* If the quotient is ever zero, default to 9600 bps */
-	if (!quot)
-		quot = BASE_BAUD / 9600;
-
-	if (baud) {
-		/* Actual rate */
-		baud = BASE_BAUD/quot;
-		tty_encode_baud_rate(info->port.tty, baud, baud);
-	}
-	info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
-
-	/* CTS flow control flag and modem status interrupts */
-	/* info->IER &= ~UART_IER_MSI; */
-	if (cflag & CRTSCTS) {
-		info->port.flags |= ASYNC_CTS_FLOW;
-		/* info->IER |= UART_IER_MSI; */
-		flow1 = 0x04;
-		flow2 = 0x10;
-	} else
-		info->port.flags &= ~ASYNC_CTS_FLOW;
-	if (cflag & CLOCAL)
-		info->port.flags &= ~ASYNC_CHECK_CD;
-	else
-		info->port.flags |= ASYNC_CHECK_CD;
-
-	/*
-	 * Set up parity check flag
-	 */
-	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-	if (I_INPCK(info->port.tty))
-		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
-		info->read_status_mask |= UART_LSR_BI;
-
-	info->ignore_status_mask = 0;
-#if 0
-	/* This should be safe, but for some broken bits of hardware... */
-	if (I_IGNPAR(info->port.tty)) {
-		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-		info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
-	}
-#endif
-	if (I_IGNBRK(info->port.tty)) {
-		info->ignore_status_mask |= UART_LSR_BI;
-		info->read_status_mask |= UART_LSR_BI;
-		/*
-		 * If we're ignore parity and break indicators, ignore
-		 * overruns too.  (For real raw support).
-		 */
-		if (I_IGNPAR(info->port.tty)) {
-			info->ignore_status_mask |= UART_LSR_OE | \
-				UART_LSR_PE | UART_LSR_FE;
-			info->read_status_mask |= UART_LSR_OE | \
-				UART_LSR_PE | UART_LSR_FE;
-		}
-	}
-
-	if (I_IXOFF(info->port.tty))
-		flow1 |= 0x81;
-
-	spin_lock_irqsave(&info->lock, flags);
-	/* set baud */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_BAUD);
-	serial_out(info, UART_ESI_CMD2, quot >> 8);
-	serial_out(info, UART_ESI_CMD2, quot & 0xff);
-
-	/* set data bits, parity, etc. */
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_LCR);
-	serial_out(info, UART_ESI_CMD2, cval);
-
-	/* Enable flow control */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CNTL);
-	serial_out(info, UART_ESI_CMD2, flow1);
-	serial_out(info, UART_ESI_CMD2, flow2);
-
-	/* set flow control characters (XON/XOFF only) */
-	if (I_IXOFF(info->port.tty)) {
-		serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS);
-		serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty));
-		serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty));
-		serial_out(info, UART_ESI_CMD2, 0x10);
-		serial_out(info, UART_ESI_CMD2, 0x21);
-		switch (cflag & CSIZE) {
-		case CS5:
-			serial_out(info, UART_ESI_CMD2, 0x1f);
-			break;
-		case CS6:
-			serial_out(info, UART_ESI_CMD2, 0x3f);
-			break;
-		case CS7:
-		case CS8:
-			serial_out(info, UART_ESI_CMD2, 0x7f);
-			break;
-		default:
-			serial_out(info, UART_ESI_CMD2, 0xff);
-			break;
-		}
-	}
-
-	/* Set high/low water */
-	serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_off >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_off);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_on >> 8);
-	serial_out(info, UART_ESI_CMD2, info->config.flow_on);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-	int ret = 0;
-
-	if (serial_paranoia_check(info, tty->name, "rs_put_char"))
-		return 0;
-
-	if (!info->xmit_buf)
-		return 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->xmit_cnt < ESP_XMIT_SIZE - 1) {
-		info->xmit_buf[info->xmit_head++] = ch;
-		info->xmit_head &= ESP_XMIT_SIZE-1;
-		info->xmit_cnt++;
-		ret = 1;
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf)
-		goto out;
-
-	if (!(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_write(struct tty_struct *tty,
-		    const unsigned char *buf, int count)
-{
-	int	c, t, ret = 0;
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write"))
-		return 0;
-
-	if (!info->xmit_buf)
-		return 0;
-
-	while (1) {
-		/* Thanks to R. Wolff for suggesting how to do this with */
-		/* interrupts enabled */
-
-		c = count;
-		t = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-
-		if (t < c)
-			c = t;
-
-		t = ESP_XMIT_SIZE - info->xmit_head;
-
-		if (t < c)
-			c = t;
-
-		if (c <= 0)
-			break;
-
-		memcpy(info->xmit_buf + info->xmit_head, buf, c);
-
-		info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1);
-		info->xmit_cnt += c;
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-	}
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	int	ret;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write_room"))
-		return 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	ret = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
-		return 0;
-	return info->xmit_cnt;
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
-		return;
-	spin_lock_irqsave(&info->lock, flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-	tty_wakeup(tty);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk("throttle %s: %d....\n", tty_name(tty, buf),
-						tty_chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_throttle"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->IER &= ~UART_IER_RDI;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, 0x00);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_unthrottle(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf),
-	       tty_chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->IER |= UART_IER_RDI;
-	serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-	serial_out(info, UART_ESI_CMD2, info->IER);
-	serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-	serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct esp_struct *info,
-			   struct serial_struct __user *retinfo)
-{
-	struct serial_struct tmp;
-
-	lock_kernel();
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = PORT_16550A;
-	tmp.line = info->line;
-	tmp.port = info->io_port;
-	tmp.irq = info->irq;
-	tmp.flags = info->port.flags;
-	tmp.xmit_fifo_size = 1024;
-	tmp.baud_base = BASE_BAUD;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
-	tmp.custom_divisor = info->custom_divisor;
-	tmp.hub6 = 0;
-	unlock_kernel();
-	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int get_esp_config(struct esp_struct *info,
-			  struct hayes_esp_config __user *retinfo)
-{
-	struct hayes_esp_config tmp;
-
-	if (!retinfo)
-		return -EFAULT;
-
-	memset(&tmp, 0, sizeof(tmp));
-	lock_kernel();
-	tmp.rx_timeout = info->config.rx_timeout;
-	tmp.rx_trigger = info->config.rx_trigger;
-	tmp.tx_trigger = info->config.tx_trigger;
-	tmp.flow_off = info->config.flow_off;
-	tmp.flow_on = info->config.flow_on;
-	tmp.pio_threshold = info->config.pio_threshold;
-	tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma);
-	unlock_kernel();
-
-	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
-}
-
-static int set_serial_info(struct esp_struct *info,
-			   struct serial_struct __user *new_info)
-{
-	struct serial_struct new_serial;
-	struct esp_struct old_info;
-	unsigned int change_irq;
-	int retval = 0;
-	struct esp_struct *current_async;
-
-	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
-		return -EFAULT;
-	old_info = *info;
-
-	if ((new_serial.type != PORT_16550A) ||
-	    (new_serial.hub6) ||
-	    (info->io_port != new_serial.port) ||
-	    (new_serial.baud_base != BASE_BAUD) ||
-	    (new_serial.irq > 15) ||
-	    (new_serial.irq < 2) ||
-	    (new_serial.irq == 6) ||
-	    (new_serial.irq == 8) ||
-	    (new_serial.irq == 13))
-		return -EINVAL;
-
-	change_irq = new_serial.irq != info->irq;
-
-	if (change_irq && (info->line % 8))
-		return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (change_irq ||
-		    (new_serial.close_delay != info->close_delay) ||
-		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-		     (info->port.flags & ~ASYNC_USR_MASK)))
-			return -EPERM;
-		info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
-			       (new_serial.flags & ASYNC_USR_MASK));
-		info->custom_divisor = new_serial.custom_divisor;
-	} else {
-		if (new_serial.irq == 2)
-			new_serial.irq = 9;
-
-		if (change_irq) {
-			current_async = ports;
-
-			while (current_async) {
-				if ((current_async->line >= info->line) &&
-				    (current_async->line < (info->line + 8))) {
-					if (current_async == info) {
-						if (current_async->port.count > 1)
-							return -EBUSY;
-					} else if (current_async->port.count)
-						return -EBUSY;
-				}
-
-				current_async = current_async->next_port;
-			}
-		}
-
-		/*
-		 * OK, past this point, all the error checking has been done.
-		 * At this point, we start making changes.....
-		 */
-
-		info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
-			       (new_serial.flags & ASYNC_FLAGS));
-		info->custom_divisor = new_serial.custom_divisor;
-		info->close_delay = new_serial.close_delay * HZ/100;
-		info->closing_wait = new_serial.closing_wait * HZ/100;
-
-		if (change_irq) {
-			/*
-			 * We need to shutdown the serial port at the old
-			 * port/irq combination.
-			 */
-			shutdown(info);
-
-			current_async = ports;
-
-			while (current_async) {
-				if ((current_async->line >= info->line) &&
-				    (current_async->line < (info->line + 8)))
-					current_async->irq = new_serial.irq;
-
-				current_async = current_async->next_port;
-			}
-
-			serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
-			if (info->irq == 9)
-				serial_out(info, UART_ESI_CMD2, 0x02);
-			else
-				serial_out(info, UART_ESI_CMD2, info->irq);
-		}
-	}
-
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		if (((old_info.port.flags & ASYNC_SPD_MASK) !=
-		     (info->port.flags & ASYNC_SPD_MASK)) ||
-		    (old_info.custom_divisor != info->custom_divisor)) {
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-				info->port.tty->alt_speed = 57600;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-				info->port.tty->alt_speed = 115200;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-				info->port.tty->alt_speed = 230400;
-			if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-				info->port.tty->alt_speed = 460800;
-			change_speed(info);
-		}
-	} else
-		retval = startup(info);
-
-	return retval;
-}
-
-static int set_esp_config(struct esp_struct *info,
-			  struct hayes_esp_config __user *new_info)
-{
-	struct hayes_esp_config new_config;
-	unsigned int change_dma;
-	int retval = 0;
-	struct esp_struct *current_async;
-	unsigned long flags;
-
-	/* Perhaps a non-sysadmin user should be able to do some of these */
-	/* operations.  I haven't decided yet. */
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (copy_from_user(&new_config, new_info, sizeof(new_config)))
-		return -EFAULT;
-
-	if ((new_config.flow_on >= new_config.flow_off) ||
-	    (new_config.rx_trigger < 1) ||
-	    (new_config.tx_trigger < 1) ||
-	    (new_config.flow_off < 1) ||
-	    (new_config.flow_on < 1) ||
-	    (new_config.rx_trigger > 1023) ||
-	    (new_config.tx_trigger > 1023) ||
-	    (new_config.flow_off > 1023) ||
-	    (new_config.flow_on > 1023) ||
-	    (new_config.pio_threshold < 0) ||
-	    (new_config.pio_threshold > 1024))
-		return -EINVAL;
-
-	if ((new_config.dma_channel != 1) && (new_config.dma_channel != 3))
-		new_config.dma_channel = 0;
-
-	if (info->stat_flags & ESP_STAT_NEVER_DMA)
-		change_dma = new_config.dma_channel;
-	else
-		change_dma = (new_config.dma_channel != dma);
-
-	if (change_dma) {
-		if (new_config.dma_channel) {
-			/* PIO mode to DMA mode transition OR */
-			/* change current DMA channel */
-			current_async = ports;
-
-			while (current_async) {
-				if (current_async == info) {
-					if (current_async->port.count > 1)
-						return -EBUSY;
-				} else if (current_async->port.count)
-					return -EBUSY;
-
-				current_async = current_async->next_port;
-			}
-
-			shutdown(info);
-			dma = new_config.dma_channel;
-			info->stat_flags &= ~ESP_STAT_NEVER_DMA;
-
-			/* all ports must use the same DMA channel */
-
-			spin_lock_irqsave(&info->lock, flags);
-			current_async = ports;
-
-			while (current_async) {
-				esp_basic_init(current_async);
-				current_async = current_async->next_port;
-			}
-			spin_unlock_irqrestore(&info->lock, flags);
-		} else {
-			/* DMA mode to PIO mode only */
-			if (info->port.count > 1)
-				return -EBUSY;
-
-			shutdown(info);
-			spin_lock_irqsave(&info->lock, flags);
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-			esp_basic_init(info);
-			spin_unlock_irqrestore(&info->lock, flags);
-		}
-	}
-
-	info->config.pio_threshold = new_config.pio_threshold;
-
-	if ((new_config.flow_off != info->config.flow_off) ||
-	    (new_config.flow_on != info->config.flow_on)) {
-		info->config.flow_off = new_config.flow_off;
-		info->config.flow_on = new_config.flow_on;
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_off >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_off);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_on >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.flow_on);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if ((new_config.rx_trigger != info->config.rx_trigger) ||
-	    (new_config.tx_trigger != info->config.tx_trigger)) {
-		info->config.rx_trigger = new_config.rx_trigger;
-		info->config.tx_trigger = new_config.tx_trigger;
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
-		serial_out(info, UART_ESI_CMD2,
-			   new_config.rx_trigger >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.rx_trigger);
-		serial_out(info, UART_ESI_CMD2,
-			   new_config.tx_trigger >> 8);
-		serial_out(info, UART_ESI_CMD2, new_config.tx_trigger);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (new_config.rx_timeout != info->config.rx_timeout) {
-		info->config.rx_timeout = new_config.rx_timeout;
-		spin_lock_irqsave(&info->lock, flags);
-
-		if (info->IER & UART_IER_RDI) {
-			serial_out(info, UART_ESI_CMD1,
-				   ESI_SET_RX_TIMEOUT);
-			serial_out(info, UART_ESI_CMD2,
-				   new_config.rx_timeout);
-		}
-
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		retval = startup(info);
-
-	return retval;
-}
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space.
- */
-static int get_lsr_info(struct esp_struct *info, unsigned int __user *value)
-{
-	unsigned char status;
-	unsigned int result;
-	unsigned long flags;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT1);
-	spin_unlock_irqrestore(&info->lock, flags);
-	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
-	return put_user(result, value);
-}
-
-
-static int esp_tiocmget(struct tty_struct *tty, struct file *file)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned char control, status;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, __func__))
-		return -ENODEV;
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	control = info->MCR;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	status = serial_in(info, UART_ESI_STAT2);
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	return    ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
-		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
-		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
-		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
-		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
-		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
-}
-
-static int esp_tiocmset(struct tty_struct *tty, struct file *file,
-			unsigned int set, unsigned int clear)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, __func__))
-		return -ENODEV;
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (set & TIOCM_RTS)
-		info->MCR |= UART_MCR_RTS;
-	if (set & TIOCM_DTR)
-		info->MCR |= UART_MCR_DTR;
-
-	if (clear & TIOCM_RTS)
-		info->MCR &= ~UART_MCR_RTS;
-	if (clear & TIOCM_DTR)
-		info->MCR &= ~UART_MCR_DTR;
-
-	serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-	serial_out(info, UART_ESI_CMD2, UART_MCR);
-	serial_out(info, UART_ESI_CMD2, info->MCR);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return 0;
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-static int esp_break(struct tty_struct *tty, int break_state)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "esp_break"))
-		return -EINVAL;
-
-	if (break_state == -1) {
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
-		serial_out(info, UART_ESI_CMD2, 0x01);
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		/* FIXME - new style wait needed here */
-		interruptible_sleep_on(&info->break_wait);
-	} else {
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
-		serial_out(info, UART_ESI_CMD2, 0x00);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-	return 0;
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file *file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct esp_struct *info = tty->driver_data;
-	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct __user *p_cuser;	/* user space */
-	void __user *argp = (void __user *)arg;
-	unsigned long flags;
-	int ret;
-
-	if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
-	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT) &&
-	    (cmd != TIOCGHAYESESP) && (cmd != TIOCSHAYESESP)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-
-	switch (cmd) {
-	case TIOCGSERIAL:
-		return get_serial_info(info, argp);
-	case TIOCSSERIAL:
-		lock_kernel();
-		ret = set_serial_info(info, argp);
-		unlock_kernel();
-		return ret;
-	case TIOCSERGWILD:
-		return put_user(0L, (unsigned long __user *)argp);
-	case TIOCSERGETLSR: /* Get line status register */
-		return get_lsr_info(info, argp);
-	case TIOCSERSWILD:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		return 0;
-	/*
-	 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-	 * - mask passed in arg for lines of interest
-	 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-	 * Caller should use TIOCGICOUNT to see which one it was
-	 */
-	case TIOCMIWAIT:
-		spin_lock_irqsave(&info->lock, flags);
-		cprev = info->icount;	/* note the counters on entry */
-		spin_unlock_irqrestore(&info->lock, flags);
-		while (1) {
-			/* FIXME: convert to new style wakeup */
-			interruptible_sleep_on(&info->port.delta_msr_wait);
-			/* see if a signal did it */
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			spin_lock_irqsave(&info->lock, flags);
-			cnow = info->icount;	/* atomic copy */
-			spin_unlock_irqrestore(&info->lock, flags);
-			if (cnow.rng == cprev.rng &&
-			    cnow.dsr == cprev.dsr &&
-			    cnow.dcd == cprev.dcd &&
-			    cnow.cts == cprev.cts)
-				return -EIO; /* no change => error */
-			if (((arg & TIOCM_RNG) &&
-			     (cnow.rng != cprev.rng)) ||
-			     ((arg & TIOCM_DSR) &&
-			      (cnow.dsr != cprev.dsr)) ||
-			     ((arg & TIOCM_CD) &&
-			      (cnow.dcd != cprev.dcd)) ||
-			     ((arg & TIOCM_CTS) &&
-			      (cnow.cts != cprev.cts))) {
-				return 0;
-			}
-			cprev = cnow;
-		}
-		/* NOTREACHED */
-	/*
-	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-	 * Return: write counters to the user passed counter struct
-	 * NB: both 1->0 and 0->1 transitions are counted except for
-	 *     RI where only 0->1 is counted.
-	 */
-	case TIOCGICOUNT:
-		spin_lock_irqsave(&info->lock, flags);
-		cnow = info->icount;
-		spin_unlock_irqrestore(&info->lock, flags);
-		p_cuser = argp;
-		if (put_user(cnow.cts, &p_cuser->cts) ||
-		    put_user(cnow.dsr, &p_cuser->dsr) ||
-		    put_user(cnow.rng, &p_cuser->rng) ||
-		    put_user(cnow.dcd, &p_cuser->dcd))
-			return -EFAULT;
-			return 0;
-	case TIOCGHAYESESP:
-		return get_esp_config(info, argp);
-	case TIOCSHAYESESP:
-		lock_kernel();
-		ret = set_esp_config(info, argp);
-		unlock_kernel();
-		return ret;
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	change_speed(info);
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-		!(tty->termios->c_cflag & CBAUD)) {
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-		serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-		serial_out(info, UART_ESI_CMD2, UART_MCR);
-		serial_out(info, UART_ESI_CMD2, info->MCR);
-	}
-
-	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-		(tty->termios->c_cflag & CBAUD)) {
-		info->MCR |= (UART_MCR_DTR | UART_MCR_RTS);
-		serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-		serial_out(info, UART_ESI_CMD2, UART_MCR);
-		serial_out(info, UART_ESI_CMD2, info->MCR);
-	}
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/* Handle turning of CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		rs_start(tty);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- *
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file *filp)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (tty_hung_up_p(filp)) {
-		DBG_CNT("before DEC-hung");
-		goto out;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
-						info->line, info->port.count);
-#endif
-	if (tty->count == 1 && info->port.count != 1) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  Info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count);
-		info->port.count = 1;
-	}
-	if (--info->port.count < 0) {
-		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->port.count);
-		info->port.count = 0;
-	}
-	if (info->port.count) {
-		DBG_CNT("before DEC-2");
-		goto out;
-	}
-	info->port.flags |= ASYNC_CLOSING;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	/* info->IER &= ~UART_IER_RLSI; */
-	info->IER &= ~UART_IER_RDI;
-	info->read_status_mask &= ~UART_LSR_DR;
-	if (info->port.flags & ASYNC_INITIALIZED) {
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
-		serial_out(info, UART_ESI_CMD2, info->IER);
-
-		/* disable receive timeout */
-		serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
-		serial_out(info, UART_ESI_CMD2, 0x00);
-
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		rs_wait_until_sent(tty, info->timeout);
-	}
-	shutdown(info);
-	rs_flush_buffer(tty);
-	tty_ldisc_flush(tty);
-	tty->closing = 0;
-	info->port.tty = NULL;
-
-	if (info->port.blocked_open) {
-		if (info->close_delay)
-			msleep_interruptible(jiffies_to_msecs(info->close_delay));
-		wake_up_interruptible(&info->port.open_wait);
-	}
-	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&info->port.close_wait);
-	return;
-
-out:
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct esp_struct *info = tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
-		return;
-
-	orig_jiffies = jiffies;
-	char_time = ((info->timeout - HZ / 50) / 1024) / 5;
-
-	if (!char_time)
-		char_time = 1;
-
-	spin_lock_irqsave(&info->lock, flags);
-	serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-
-	while ((serial_in(info, UART_ESI_STAT1) != 0x03) ||
-		(serial_in(info, UART_ESI_STAT2) != 0xff)) {
-
-		spin_unlock_irqrestore(&info->lock, flags);
-		msleep_interruptible(jiffies_to_msecs(char_time));
-
-		if (signal_pending(current))
-			return;
-
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			return;
-
-		spin_lock_irqsave(&info->lock, flags);
-		serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
-		serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	set_current_state(TASK_RUNNING);
-}
-
-/*
- * esp_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void esp_hangup(struct tty_struct *tty)
-{
-	struct esp_struct *info = tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "esp_hangup"))
-		return;
-
-	rs_flush_buffer(tty);
-	shutdown(info);
-	info->port.count = 0;
-	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->port.tty = NULL;
-	wake_up_interruptible(&info->port.open_wait);
-}
-
-static int esp_carrier_raised(struct tty_port *port)
-{
-	struct esp_struct *info = container_of(port, struct esp_struct, port);
-	serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
-	if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
-		return 1;
-	return 0;
-}
-
-/*
- * ------------------------------------------------------------
- * esp_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file *filp,
-			   struct esp_struct *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int		retval;
-	int		do_clocal = 0;
-	unsigned long	flags;
-	int		cd;
-	struct tty_port *port = &info->port;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (port->flags & ASYNC_CLOSING)) {
-		if (port->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&port->close_wait);
-#ifdef SERIAL_DO_RESTART
-		if (port->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		port->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (tty->termios->c_cflag & CLOCAL)
-		do_clocal = 1;
-
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, port->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&port->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
-	       info->line, port->count);
-#endif
-	spin_lock_irqsave(&info->lock, flags);
-	if (!tty_hung_up_p(filp))
-		port->count--;
-	port->blocked_open++;
-	while (1) {
-		if ((tty->termios->c_cflag & CBAUD)) {
-			unsigned int scratch;
-
-			serial_out(info, UART_ESI_CMD1, ESI_READ_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			scratch = serial_in(info, UART_ESI_STAT1);
-			serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			serial_out(info, UART_ESI_CMD2,
-				scratch | UART_MCR_DTR | UART_MCR_RTS);
-		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(port->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (port->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-
-		cd = tty_port_carrier_raised(port);
-
-		if (!(port->flags & ASYNC_CLOSING) &&
-		    (do_clocal))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, port->count);
-#endif
-		spin_unlock_irqrestore(&info->lock, flags);
-		schedule();
-		spin_lock_irqsave(&info->lock, flags);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&port->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		port->count++;
-	port->blocked_open--;
-	spin_unlock_irqrestore(&info->lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, port->count);
-#endif
-	if (retval)
-		return retval;
-	port->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int esp_open(struct tty_struct *tty, struct file *filp)
-{
-	struct esp_struct	*info;
-	int 			retval, line;
-	unsigned long		flags;
-
-	line = tty->index;
-	if ((line < 0) || (line >= NR_PORTS))
-		return -ENODEV;
-
-	/* find the port in the chain */
-
-	info = ports;
-
-	while (info && (info->line != line))
-		info = info->next_port;
-
-	if (!info) {
-		serial_paranoia_check(info, tty->name, "esp_open");
-		return -ENODEV;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count);
-#endif
-	spin_lock_irqsave(&info->lock, flags);
-	info->port.count++;
-	tty->driver_data = info;
-	info->port.tty = tty;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		return retval;
-	}
-#ifdef SERIAL_DEBUG_OPEN
-	printk(KERN_DEBUG "esp_open %s successful...", tty->name);
-#endif
-	return 0;
-}
-
-/*
- * ---------------------------------------------------------------------
- * espserial_init() and friends
- *
- * espserial_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-
-static void __init show_serial_version(void)
-{
-	printk(KERN_INFO "%s version %s (DMA %u)\n",
-		serial_name, serial_version, dma);
-}
-
-/*
- * This routine is called by espserial_init() to initialize a specific serial
- * port.
- */
-static int autoconfig(struct esp_struct *info)
-{
-	int port_detected = 0;
-	unsigned long flags;
-
-	if (!request_region(info->io_port, REGION_SIZE, "esp serial"))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-	/*
-	 * Check for ESP card
-	 */
-
-	if (serial_in(info, UART_ESI_BASE) == 0xf3) {
-		serial_out(info, UART_ESI_CMD1, 0x00);
-		serial_out(info, UART_ESI_CMD1, 0x01);
-
-		if ((serial_in(info, UART_ESI_STAT2) & 0x70) == 0x20) {
-			port_detected = 1;
-
-			if (!(info->irq)) {
-				serial_out(info, UART_ESI_CMD1, 0x02);
-
-				if (serial_in(info, UART_ESI_STAT1) & 0x01)
-					info->irq = 3;
-				else
-					info->irq = 4;
-			}
-
-
-			/* put card in enhanced mode */
-			/* this prevents access through */
-			/* the "old" IO ports */
-			esp_basic_init(info);
-
-			/* clear out MCR */
-			serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
-			serial_out(info, UART_ESI_CMD2, UART_MCR);
-			serial_out(info, UART_ESI_CMD2, 0x00);
-		}
-	}
-	if (!port_detected)
-		release_region(info->io_port, REGION_SIZE);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-	return (port_detected);
-}
-
-static const struct tty_operations esp_ops = {
-	.open = esp_open,
-	.close = rs_close,
-	.write = rs_write,
-	.put_char = rs_put_char,
-	.flush_chars = rs_flush_chars,
-	.write_room = rs_write_room,
-	.chars_in_buffer = rs_chars_in_buffer,
-	.flush_buffer = rs_flush_buffer,
-	.ioctl = rs_ioctl,
-	.throttle = rs_throttle,
-	.unthrottle = rs_unthrottle,
-	.set_termios = rs_set_termios,
-	.stop = rs_stop,
-	.start = rs_start,
-	.hangup = esp_hangup,
-	.break_ctl = esp_break,
-	.wait_until_sent = rs_wait_until_sent,
-	.tiocmget = esp_tiocmget,
-	.tiocmset = esp_tiocmset,
-};
-
-static const struct tty_port_operations esp_port_ops = {
-	.esp_carrier_raised,
-};
-
-/*
- * The serial driver boot-time initialization code!
- */
-static int __init espserial_init(void)
-{
-	int i, offset;
-	struct esp_struct *info;
-	struct esp_struct *last_primary = NULL;
-	int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 };
-
-	esp_driver = alloc_tty_driver(NR_PORTS);
-	if (!esp_driver)
-		return -ENOMEM;
-
-	for (i = 0; i < NR_PRIMARY; i++) {
-		if (irq[i] != 0) {
-			if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) ||
-			    (irq[i] == 8) || (irq[i] == 13))
-				irq[i] = 0;
-			else if (irq[i] == 2)
-				irq[i] = 9;
-		}
-	}
-
-	if ((dma != 1) && (dma != 3))
-		dma = 0;
-
-	if ((rx_trigger < 1) || (rx_trigger > 1023))
-		rx_trigger = 768;
-
-	if ((tx_trigger < 1) || (tx_trigger > 1023))
-		tx_trigger = 768;
-
-	if ((flow_off < 1) || (flow_off > 1023))
-		flow_off = 1016;
-
-	if ((flow_on < 1) || (flow_on > 1023))
-		flow_on = 944;
-
-	if ((rx_timeout < 0) || (rx_timeout > 255))
-		rx_timeout = 128;
-
-	if (flow_on >= flow_off)
-		flow_on = flow_off - 1;
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-
-	esp_driver->owner = THIS_MODULE;
-	esp_driver->name = "ttyP";
-	esp_driver->major = ESP_IN_MAJOR;
-	esp_driver->minor_start = 0;
-	esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	esp_driver->subtype = SERIAL_TYPE_NORMAL;
-	esp_driver->init_termios = tty_std_termios;
-	esp_driver->init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	esp_driver->init_termios.c_ispeed = 9600;
-	esp_driver->init_termios.c_ospeed = 9600;
-	esp_driver->flags = TTY_DRIVER_REAL_RAW;
-	tty_set_operations(esp_driver, &esp_ops);
-	if (tty_register_driver(esp_driver)) {
-		printk(KERN_ERR "Couldn't register esp serial driver");
-		put_tty_driver(esp_driver);
-		return 1;
-	}
-
-	info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
-
-	if (!info) {
-		printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
-		tty_unregister_driver(esp_driver);
-		put_tty_driver(esp_driver);
-		return 1;
-	}
-
-	spin_lock_init(&info->lock);
-	/* rx_trigger, tx_trigger are needed by autoconfig */
-	info->config.rx_trigger = rx_trigger;
-	info->config.tx_trigger = tx_trigger;
-
-	i = 0;
-	offset = 0;
-
-	do {
-		tty_port_init(&info->port);
-		info->port.ops = &esp_port_ops;
-		info->io_port = esp[i] + offset;
-		info->irq = irq[i];
-		info->line = (i * 8) + (offset / 8);
-
-		if (!autoconfig(info)) {
-			i++;
-			offset = 0;
-			continue;
-		}
-
-		info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf;
-		info->port.flags = STD_COM_FLAGS;
-		if (info->custom_divisor)
-			info->port.flags |= ASYNC_SPD_CUST;
-		info->magic = ESP_MAGIC;
-		info->close_delay = 5*HZ/10;
-		info->closing_wait = 30*HZ;
-		info->config.rx_timeout = rx_timeout;
-		info->config.flow_on = flow_on;
-		info->config.flow_off = flow_off;
-		info->config.pio_threshold = pio_threshold;
-		info->next_port = ports;
-		init_waitqueue_head(&info->break_wait);
-		ports = info;
-		printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
-			info->line, info->io_port, info->irq);
-
-		if (info->line % 8) {
-			printk("secondary port\n");
-			/* 8 port cards can't do DMA */
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-
-			if (last_primary)
-				last_primary->stat_flags |= ESP_STAT_NEVER_DMA;
-		} else {
-			printk("primary port\n");
-			last_primary = info;
-			irq[i] = info->irq;
-		}
-
-		if (!dma)
-			info->stat_flags |= ESP_STAT_NEVER_DMA;
-
-		info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
-		if (!info) {
-			printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
-			/* allow use of the already detected ports */
-			return 0;
-		}
-
-		spin_lock_init(&info->lock);
-		/* rx_trigger, tx_trigger are needed by autoconfig */
-		info->config.rx_trigger = rx_trigger;
-		info->config.tx_trigger = tx_trigger;
-
-		if (offset == 56) {
-			i++;
-			offset = 0;
-		} else {
-			offset += 8;
-		}
-	} while (i < NR_PRIMARY);
-
-	/* free the last port memory allocation */
-	kfree(info);
-
-	return 0;
-}
-
-static void __exit espserial_exit(void)
-{
-	int e1;
-	struct esp_struct *temp_async;
-	struct esp_pio_buffer *pio_buf;
-
-	e1 = tty_unregister_driver(esp_driver);
-	if (e1)
-		printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1);
-	put_tty_driver(esp_driver);
-
-	while (ports) {
-		if (ports->io_port)
-			release_region(ports->io_port, REGION_SIZE);
-		temp_async = ports->next_port;
-		kfree(ports);
-		ports = temp_async;
-	}
-
-	if (dma_buffer)
-		free_pages((unsigned long)dma_buffer,
-			get_order(DMA_BUFFER_SZ));
-
-	while (free_pio_buf) {
-		pio_buf = free_pio_buf->next;
-		kfree(free_pio_buf);
-		free_pio_buf = pio_buf;
-	}
-}
-
-module_init(espserial_init);
-module_exit(espserial_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/generic_nvram.c linux-libre-2.6.33-gnu1/drivers/char/generic_nvram.c
--- linux-libre-2.6.32-gnu1/drivers/char/generic_nvram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/generic_nvram.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,6 @@
 #include <linux/miscdevice.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 #ifdef CONFIG_PPC_PMAC
@@ -32,7 +31,6 @@ static ssize_t nvram_len;
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-	lock_kernel();
 	switch (origin) {
 	case 1:
 		offset += file->f_pos;
@@ -41,12 +39,11 @@ static loff_t nvram_llseek(struct file *
 		offset += nvram_len;
 		break;
 	}
-	if (offset < 0) {
-		unlock_kernel();
+	if (offset < 0)
 		return -EINVAL;
-	}
+
 	file->f_pos = offset;
-	unlock_kernel();
+
 	return file->f_pos;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hpet.c linux-libre-2.6.33-gnu1/drivers/char/hpet.c
--- linux-libre-2.6.32-gnu1/drivers/char/hpet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hpet.c	2010-02-24 13:52:17.000000000 -0500
@@ -675,36 +675,33 @@ static int hpet_is_known(struct hpet_dat
 
 static ctl_table hpet_table[] = {
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "max-user-freq",
 	 .data = &hpet_max_freq,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = &proc_dointvec,
+	 .proc_handler = proc_dointvec,
 	 },
-	{.ctl_name = 0}
+	{}
 };
 
 static ctl_table hpet_root[] = {
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "hpet",
 	 .maxlen = 0,
 	 .mode = 0555,
 	 .child = hpet_table,
 	 },
-	{.ctl_name = 0}
+	{}
 };
 
 static ctl_table dev_root[] = {
 	{
-	 .ctl_name = CTL_DEV,
 	 .procname = "dev",
 	 .maxlen = 0,
 	 .mode = 0555,
 	 .child = hpet_root,
 	 },
-	{.ctl_name = 0}
+	{}
 };
 
 static struct ctl_table_header *sysctl_header;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hvc_console.c linux-libre-2.6.33-gnu1/drivers/char/hvc_console.c
--- linux-libre-2.6.32-gnu1/drivers/char/hvc_console.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hvc_console.c	2010-02-24 13:52:17.000000000 -0500
@@ -832,6 +832,7 @@ int hvc_remove(struct hvc_struct *hp)
 		tty_hangup(tty);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hvc_remove);
 
 /* Driver initialization: called as soon as someone uses hvc_alloc(). */
 static int hvc_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hvc_iucv.c linux-libre-2.6.33-gnu1/drivers/char/hvc_iucv.c
--- linux-libre-2.6.32-gnu1/drivers/char/hvc_iucv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hvc_iucv.c	2010-02-24 13:52:17.000000000 -0500
@@ -931,7 +931,7 @@ static struct hv_ops hvc_iucv_ops = {
 };
 
 /* Suspend / resume device operations */
-static struct dev_pm_ops hvc_iucv_pm_ops = {
+static const struct dev_pm_ops hvc_iucv_pm_ops = {
 	.freeze	  = hvc_iucv_pm_freeze,
 	.thaw	  = hvc_iucv_pm_restore_thaw,
 	.restore  = hvc_iucv_pm_restore_thaw,
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hvc_xen.c linux-libre-2.6.33-gnu1/drivers/char/hvc_xen.c
--- linux-libre-2.6.32-gnu1/drivers/char/hvc_xen.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hvc_xen.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,8 @@
 #include <linux/types.h>
 
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/page.h>
 #include <xen/events.h>
 #include <xen/interface/io/console.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hw_random/core.c linux-libre-2.6.33-gnu1/drivers/char/hw_random/core.c
--- linux-libre-2.6.32-gnu1/drivers/char/hw_random/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hw_random/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,9 @@
 static struct hwrng *current_rng;
 static LIST_HEAD(rng_list);
 static DEFINE_MUTEX(rng_mutex);
-
+static int data_avail;
+static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
+	__cacheline_aligned;
 
 static inline int hwrng_init(struct hwrng *rng)
 {
@@ -67,19 +69,6 @@ static inline void hwrng_cleanup(struct
 		rng->cleanup(rng);
 }
 
-static inline int hwrng_data_present(struct hwrng *rng, int wait)
-{
-	if (!rng->data_present)
-		return 1;
-	return rng->data_present(rng, wait);
-}
-
-static inline int hwrng_data_read(struct hwrng *rng, u32 *data)
-{
-	return rng->data_read(rng, data);
-}
-
-
 static int rng_dev_open(struct inode *inode, struct file *filp)
 {
 	/* enforce read-only access to this chrdev */
@@ -87,60 +76,93 @@ static int rng_dev_open(struct inode *in
 		return -EINVAL;
 	if (filp->f_mode & FMODE_WRITE)
 		return -EINVAL;
-	cycle_kernel_lock();
+	return 0;
+}
+
+static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
+			int wait) {
+	int present;
+
+	if (rng->read)
+		return rng->read(rng, (void *)buffer, size, wait);
+
+	if (rng->data_present)
+		present = rng->data_present(rng, wait);
+	else
+		present = 1;
+
+	if (present)
+		return rng->data_read(rng, (u32 *)buffer);
+
 	return 0;
 }
 
 static ssize_t rng_dev_read(struct file *filp, char __user *buf,
 			    size_t size, loff_t *offp)
 {
-	u32 data;
 	ssize_t ret = 0;
 	int err = 0;
-	int bytes_read;
+	int bytes_read, len;
 
 	while (size) {
-		err = -ERESTARTSYS;
-		if (mutex_lock_interruptible(&rng_mutex))
+		if (mutex_lock_interruptible(&rng_mutex)) {
+			err = -ERESTARTSYS;
 			goto out;
+		}
+
 		if (!current_rng) {
-			mutex_unlock(&rng_mutex);
 			err = -ENODEV;
-			goto out;
+			goto out_unlock;
 		}
 
-		bytes_read = 0;
-		if (hwrng_data_present(current_rng,
-				       !(filp->f_flags & O_NONBLOCK)))
-			bytes_read = hwrng_data_read(current_rng, &data);
-		mutex_unlock(&rng_mutex);
-
-		err = -EAGAIN;
-		if (!bytes_read && (filp->f_flags & O_NONBLOCK))
-			goto out;
-		if (bytes_read < 0) {
-			err = bytes_read;
-			goto out;
+		if (!data_avail) {
+			bytes_read = rng_get_data(current_rng, rng_buffer,
+				sizeof(rng_buffer),
+				!(filp->f_flags & O_NONBLOCK));
+			if (bytes_read < 0) {
+				err = bytes_read;
+				goto out_unlock;
+			}
+			data_avail = bytes_read;
 		}
 
-		err = -EFAULT;
-		while (bytes_read && size) {
-			if (put_user((u8)data, buf++))
-				goto out;
-			size--;
-			ret++;
-			bytes_read--;
-			data >>= 8;
+		if (!data_avail) {
+			if (filp->f_flags & O_NONBLOCK) {
+				err = -EAGAIN;
+				goto out_unlock;
+			}
+		} else {
+			len = data_avail;
+			if (len > size)
+				len = size;
+
+			data_avail -= len;
+
+			if (copy_to_user(buf + ret, rng_buffer + data_avail,
+								len)) {
+				err = -EFAULT;
+				goto out_unlock;
+			}
+
+			size -= len;
+			ret += len;
 		}
 
+		mutex_unlock(&rng_mutex);
+
 		if (need_resched())
 			schedule_timeout_interruptible(1);
-		err = -ERESTARTSYS;
-		if (signal_pending(current))
+
+		if (signal_pending(current)) {
+			err = -ERESTARTSYS;
 			goto out;
+		}
 	}
 out:
 	return ret ? : err;
+out_unlock:
+	mutex_unlock(&rng_mutex);
+	goto out;
 }
 
 
@@ -280,7 +302,7 @@ int hwrng_register(struct hwrng *rng)
 	struct hwrng *old_rng, *tmp;
 
 	if (rng->name == NULL ||
-	    rng->data_read == NULL)
+	    (rng->data_read == NULL && rng->read == NULL))
 		goto out;
 
 	mutex_lock(&rng_mutex);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/hw_random/virtio-rng.c linux-libre-2.6.33-gnu1/drivers/char/hw_random/virtio-rng.c
--- linux-libre-2.6.32-gnu1/drivers/char/hw_random/virtio-rng.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/hw_random/virtio-rng.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
  *  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/err.h>
 #include <linux/hw_random.h>
 #include <linux/scatterlist.h>
@@ -23,78 +24,64 @@
 #include <linux/virtio.h>
 #include <linux/virtio_rng.h>
 
-/* The host will fill any buffer we give it with sweet, sweet randomness.  We
- * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a
- * time. */
-#define RANDOM_DATA_SIZE 64
-
 static struct virtqueue *vq;
-static u32 *random_data;
-static unsigned int data_left;
+static unsigned int data_avail;
 static DECLARE_COMPLETION(have_data);
+static bool busy;
 
 static void random_recv_done(struct virtqueue *vq)
 {
-	unsigned int len;
-
 	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
-	if (!vq->vq_ops->get_buf(vq, &len))
+	if (!vq->vq_ops->get_buf(vq, &data_avail))
 		return;
 
-	data_left += len;
 	complete(&have_data);
 }
 
-static void register_buffer(void)
+/* The host will fill any buffer we give it with sweet, sweet randomness. */
+static void register_buffer(u8 *buf, size_t size)
 {
 	struct scatterlist sg;
 
-	sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left);
+	sg_init_one(&sg, buf, size);
+
 	/* There should always be room for one buffer. */
-	if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0)
+	if (vq->vq_ops->add_buf(vq, &sg, 0, 1, buf) < 0)
 		BUG();
+
 	vq->vq_ops->kick(vq);
 }
 
-/* At least we don't udelay() in a loop like some other drivers. */
-static int virtio_data_present(struct hwrng *rng, int wait)
+static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
 {
-	if (data_left >= sizeof(u32))
-		return 1;
 
-again:
+	if (!busy) {
+		busy = true;
+		init_completion(&have_data);
+		register_buffer(buf, size);
+	}
+
 	if (!wait)
 		return 0;
 
 	wait_for_completion(&have_data);
 
-	/* Not enough?  Re-register. */
-	if (unlikely(data_left < sizeof(u32))) {
-		register_buffer();
-		goto again;
-	}
+	busy = false;
 
-	return 1;
+	return data_avail;
 }
 
-/* virtio_data_present() must have succeeded before this is called. */
-static int virtio_data_read(struct hwrng *rng, u32 *data)
+static void virtio_cleanup(struct hwrng *rng)
 {
-	BUG_ON(data_left < sizeof(u32));
-	data_left -= sizeof(u32);
-	*data = random_data[data_left / 4];
-
-	if (data_left < sizeof(u32)) {
-		init_completion(&have_data);
-		register_buffer();
-	}
-	return sizeof(*data);
+	if (busy)
+		wait_for_completion(&have_data);
 }
 
+
 static struct hwrng virtio_hwrng = {
-	.name = "virtio",
-	.data_present = virtio_data_present,
-	.data_read = virtio_data_read,
+	.name		= "virtio",
+	.cleanup	= virtio_cleanup,
+	.read		= virtio_read,
 };
 
 static int virtrng_probe(struct virtio_device *vdev)
@@ -112,7 +99,6 @@ static int virtrng_probe(struct virtio_d
 		return err;
 	}
 
-	register_buffer();
 	return 0;
 }
 
@@ -128,7 +114,7 @@ static struct virtio_device_id id_table[
 	{ 0 },
 };
 
-static struct virtio_driver virtio_rng = {
+static struct virtio_driver virtio_rng_driver = {
 	.driver.name =	KBUILD_MODNAME,
 	.driver.owner =	THIS_MODULE,
 	.id_table =	id_table,
@@ -138,22 +124,12 @@ static struct virtio_driver virtio_rng =
 
 static int __init init(void)
 {
-	int err;
-
-	random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL);
-	if (!random_data)
-		return -ENOMEM;
-
-	err = register_virtio_driver(&virtio_rng);
-	if (err)
-		kfree(random_data);
-	return err;
+	return register_virtio_driver(&virtio_rng_driver);
 }
 
 static void __exit fini(void)
 {
-	kfree(random_data);
-	unregister_virtio_driver(&virtio_rng);
+	unregister_virtio_driver(&virtio_rng_driver);
 }
 module_init(init);
 module_exit(fini);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_kcs_sm.c linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_kcs_sm.c
--- linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_kcs_sm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_kcs_sm.c	2010-02-24 13:52:17.000000000 -0500
@@ -370,7 +370,7 @@ static enum si_sm_result kcs_event(struc
 			return SI_SM_IDLE;
 
 	case KCS_START_OP:
-		if (state != KCS_IDLE) {
+		if (state != KCS_IDLE_STATE) {
 			start_error_recovery(kcs,
 					     "State machine not idle at start");
 			break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_poweroff.c linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_poweroff.c
--- linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_poweroff.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_poweroff.c	2010-02-24 13:52:17.000000000 -0500
@@ -660,26 +660,23 @@ static struct ipmi_smi_watcher smi_watch
 #include <linux/sysctl.h>
 
 static ctl_table ipmi_table[] = {
-	{ .ctl_name	= DEV_IPMI_POWEROFF_POWERCYCLE,
-	  .procname	= "poweroff_powercycle",
+	{ .procname	= "poweroff_powercycle",
 	  .data		= &poweroff_powercycle,
 	  .maxlen	= sizeof(poweroff_powercycle),
 	  .mode		= 0644,
-	  .proc_handler	= &proc_dointvec },
+	  .proc_handler	= proc_dointvec },
 	{ }
 };
 
 static ctl_table ipmi_dir_table[] = {
-	{ .ctl_name	= DEV_IPMI,
-	  .procname	= "ipmi",
+	{ .procname	= "ipmi",
 	  .mode		= 0555,
 	  .child	= ipmi_table },
 	{ }
 };
 
 static ctl_table ipmi_root_table[] = {
-	{ .ctl_name	= CTL_DEV,
-	  .procname	= "dev",
+	{ .procname	= "dev",
 	  .mode		= 0555,
 	  .child	= ipmi_dir_table },
 	{ }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_si_intf.c linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_si_intf.c
--- linux-libre-2.6.32-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,6 +64,7 @@
 #include <linux/dmi.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/pnp.h>
 
 #ifdef CONFIG_PPC_OF
 #include <linux/of_device.h>
@@ -1919,7 +1920,7 @@ struct SPMITable {
 	s8      spmi_id[1]; /* A '\0' terminated array starts here. */
 };
 
-static __devinit int try_init_acpi(struct SPMITable *spmi)
+static __devinit int try_init_spmi(struct SPMITable *spmi)
 {
 	struct smi_info  *info;
 	u8 		 addr_space;
@@ -1940,7 +1941,7 @@ static __devinit int try_init_acpi(struc
 		return -ENOMEM;
 	}
 
-	info->addr_source = "ACPI";
+	info->addr_source = "SPMI";
 
 	/* Figure out the interface type. */
 	switch (spmi->InterfaceType) {
@@ -2002,7 +2003,7 @@ static __devinit int try_init_acpi(struc
 	return 0;
 }
 
-static __devinit void acpi_find_bmc(void)
+static __devinit void spmi_find_bmc(void)
 {
 	acpi_status      status;
 	struct SPMITable *spmi;
@@ -2020,9 +2021,106 @@ static __devinit void acpi_find_bmc(void
 		if (status != AE_OK)
 			return;
 
-		try_init_acpi(spmi);
+		try_init_spmi(spmi);
+	}
+}
+
+static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
+				    const struct pnp_device_id *dev_id)
+{
+	struct acpi_device *acpi_dev;
+	struct smi_info *info;
+	acpi_handle handle;
+	acpi_status status;
+	unsigned long long tmp;
+
+	acpi_dev = pnp_acpi_device(dev);
+	if (!acpi_dev)
+		return -ENODEV;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->addr_source = "ACPI";
+
+	handle = acpi_dev->handle;
+
+	/* _IFT tells us the interface type: KCS, BT, etc */
+	status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
+	if (ACPI_FAILURE(status))
+		goto err_free;
+
+	switch (tmp) {
+	case 1:
+		info->si_type = SI_KCS;
+		break;
+	case 2:
+		info->si_type = SI_SMIC;
+		break;
+	case 3:
+		info->si_type = SI_BT;
+		break;
+	default:
+		dev_info(&dev->dev, "unknown interface type %lld\n", tmp);
+		goto err_free;
+	}
+
+	if (pnp_port_valid(dev, 0)) {
+		info->io_setup = port_setup;
+		info->io.addr_type = IPMI_IO_ADDR_SPACE;
+		info->io.addr_data = pnp_port_start(dev, 0);
+	} else if (pnp_mem_valid(dev, 0)) {
+		info->io_setup = mem_setup;
+		info->io.addr_type = IPMI_MEM_ADDR_SPACE;
+		info->io.addr_data = pnp_mem_start(dev, 0);
+	} else {
+		dev_err(&dev->dev, "no I/O or memory address\n");
+		goto err_free;
+	}
+
+	info->io.regspacing = DEFAULT_REGSPACING;
+	info->io.regsize = DEFAULT_REGSPACING;
+	info->io.regshift = 0;
+
+	/* If _GPE exists, use it; otherwise use standard interrupts */
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
+	if (ACPI_SUCCESS(status)) {
+		info->irq = tmp;
+		info->irq_setup = acpi_gpe_irq_setup;
+	} else if (pnp_irq_valid(dev, 0)) {
+		info->irq = pnp_irq(dev, 0);
+		info->irq_setup = std_irq_setup;
 	}
+
+	info->dev = &acpi_dev->dev;
+	pnp_set_drvdata(dev, info);
+
+	return try_smi_init(info);
+
+err_free:
+	kfree(info);
+	return -EINVAL;
 }
+
+static void __devexit ipmi_pnp_remove(struct pnp_dev *dev)
+{
+	struct smi_info *info = pnp_get_drvdata(dev);
+
+	cleanup_one_si(info);
+}
+
+static const struct pnp_device_id pnp_dev_table[] = {
+	{"IPI0001", 0},
+	{"", 0},
+};
+
+static struct pnp_driver ipmi_pnp_driver = {
+	.name		= DEVICE_NAME,
+	.probe		= ipmi_pnp_probe,
+	.remove		= __devexit_p(ipmi_pnp_remove),
+	.id_table	= pnp_dev_table,
+};
 #endif
 
 #ifdef CONFIG_DMI
@@ -2202,7 +2300,6 @@ static int __devinit ipmi_pci_probe(stru
 	int rv;
 	int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK;
 	struct smi_info *info;
-	int first_reg_offset = 0;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
@@ -2241,9 +2338,6 @@ static int __devinit ipmi_pci_probe(stru
 	info->addr_source_cleanup = ipmi_pci_cleanup;
 	info->addr_source_data = pdev;
 
-	if (pdev->subsystem_vendor == PCI_HP_VENDOR_ID)
-		first_reg_offset = 1;
-
 	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
 		info->io_setup = port_setup;
 		info->io.addr_type = IPMI_IO_ADDR_SPACE;
@@ -3108,7 +3202,10 @@ static __devinit int init_ipmi_si(void)
 #endif
 
 #ifdef CONFIG_ACPI
-	acpi_find_bmc();
+	spmi_find_bmc();
+#endif
+#ifdef CONFIG_ACPI
+	pnp_register_driver(&ipmi_pnp_driver);
 #endif
 
 #ifdef CONFIG_PCI
@@ -3233,6 +3330,9 @@ static __exit void cleanup_ipmi_si(void)
 #ifdef CONFIG_PCI
 	pci_unregister_driver(&ipmi_pci_driver);
 #endif
+#ifdef CONFIG_ACPI
+	pnp_unregister_driver(&ipmi_pnp_driver);
+#endif
 
 #ifdef CONFIG_PPC_OF
 	of_unregister_platform_driver(&ipmi_of_platform_driver);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/isicom.c linux-libre-2.6.33-gnu1/drivers/char/isicom.c
--- linux-libre-2.6.32-gnu1/drivers/char/isicom.c	2013-05-03 13:55:39.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/char/isicom.c	2013-05-03 12:03:13.000000000 -0400
@@ -793,35 +793,30 @@ static inline void isicom_setup_board(st
 {
 	int channel;
 	struct isi_port *port;
-	unsigned long flags;
 
-	spin_lock_irqsave(&bp->card_lock, flags);
-	if (bp->status & BOARD_ACTIVE) {
-		spin_unlock_irqrestore(&bp->card_lock, flags);
-		return;
+	bp->count++;
+	if (!(bp->status & BOARD_INIT)) {
+		port = bp->ports;
+		for (channel = 0; channel < bp->port_count; channel++, port++)
+			drop_dtr_rts(port);
 	}
-	port = bp->ports;
-	bp->status |= BOARD_ACTIVE;
-	for (channel = 0; channel < bp->port_count; channel++, port++)
-		drop_dtr_rts(port);
-	spin_unlock_irqrestore(&bp->card_lock, flags);
+	bp->status |= BOARD_ACTIVE | BOARD_INIT;
 }
 
-static int isicom_setup_port(struct tty_struct *tty)
+/* Activate and thus setup board are protected from races against shutdown
+   by the tty_port mutex */
+
+static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
 {
-	struct isi_port *port = tty->driver_data;
+	struct isi_port *port = container_of(tport, struct isi_port, port);
 	struct isi_board *card = port->card;
 	unsigned long flags;
 
-	if (port->port.flags & ASYNC_INITIALIZED)
-		return 0;
-	if (tty_port_alloc_xmit_buf(&port->port) < 0)
+	if (tty_port_alloc_xmit_buf(tport) < 0)
 		return -ENOMEM;
 
 	spin_lock_irqsave(&card->card_lock, flags);
-	clear_bit(TTY_IO_ERROR, &tty->flags);
-	if (port->port.count == 1)
-		card->count++;
+	isicom_setup_board(card);
 
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 
@@ -832,9 +827,7 @@ static int isicom_setup_port(struct tty_
 		outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
 		InterruptTheCard(card->base);
 	}
-
 	isicom_config_port(tty);
-	port->port.flags |= ASYNC_INITIALIZED;
 	spin_unlock_irqrestore(&card->card_lock, flags);
 
 	return 0;
@@ -871,85 +864,37 @@ static struct tty_port *isicom_find_port
 
 	return &port->port;
 }
-	
+
 static int isicom_open(struct tty_struct *tty, struct file *filp)
 {
 	struct isi_port *port;
 	struct isi_board *card;
 	struct tty_port *tport;
-	int error = 0;
 
 	tport = isicom_find_port(tty);
 	if (tport == NULL)
 		return -ENODEV;
 	port = container_of(tport, struct isi_port, port);
 	card = &isi_card[BOARD(tty->index)];
-	isicom_setup_board(card);
 
-	/* FIXME: locking on port.count etc */
-	port->port.count++;
-	tty->driver_data = port;
-	tty_port_tty_set(&port->port, tty);
-	/* FIXME: Locking on Initialized flag */
-	if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
-		error = isicom_setup_port(tty);
-	if (error == 0)
-		error = tty_port_block_til_ready(&port->port, tty, filp);
-	return error;
+	return tty_port_open(tport, tty, filp);
 }
 
 /* close et all */
 
-static inline void isicom_shutdown_board(struct isi_board *bp)
-{
-	if (bp->status & BOARD_ACTIVE)
-		bp->status &= ~BOARD_ACTIVE;
-}
-
 /* card->lock HAS to be held */
 static void isicom_shutdown_port(struct isi_port *port)
 {
 	struct isi_board *card = port->card;
-	struct tty_struct *tty;
-
-	tty = tty_port_tty_get(&port->port);
-
-	if (!(port->port.flags & ASYNC_INITIALIZED)) {
-		tty_kref_put(tty);
-		return;
-	}
-
-	tty_port_free_xmit_buf(&port->port);
-	port->port.flags &= ~ASYNC_INITIALIZED;
-	/* 3rd October 2000 : Vinayak P Risbud */
-	tty_port_tty_set(&port->port, NULL);
-
-	/*Fix done by Anil .S on 30-04-2001
-	remote login through isi port has dtr toggle problem
-	due to which the carrier drops before the password prompt
-	appears on the remote end. Now we drop the dtr only if the
-	HUPCL(Hangup on close) flag is set for the tty*/
-
-	if (C_HUPCL(tty))
-		/* drop dtr on this port */
-		drop_dtr(port);
-
-	/* any other port uninits  */
-	if (tty)
-		set_bit(TTY_IO_ERROR, &tty->flags);
 
 	if (--card->count < 0) {
 		pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
 			card->base, card->count);
 		card->count = 0;
 	}
-
-	/* last port was closed, shutdown that boad too */
-	if (C_HUPCL(tty)) {
-		if (!card->count)
-			isicom_shutdown_board(card);
-	}
-	tty_kref_put(tty);
+	/* last port was closed, shutdown that board too */
+	if (!card->count)
+		card->status &= BOARD_ACTIVE;
 }
 
 static void isicom_flush_buffer(struct tty_struct *tty)
@@ -968,7 +913,7 @@ static void isicom_flush_buffer(struct t
 	tty_wakeup(tty);
 }
 
-static void isicom_close_port(struct tty_port *port)
+static void isicom_shutdown(struct tty_port *port)
 {
 	struct isi_port *ip = container_of(port, struct isi_port, port);
 	struct isi_board *card = ip->card;
@@ -977,12 +922,11 @@ static void isicom_close_port(struct tty
 	/* indicate to the card that no more data can be received
 	   on this port */
 	spin_lock_irqsave(&card->card_lock, flags);
-	if (port->flags & ASYNC_INITIALIZED) {
-		card->port_status &= ~(1 << ip->channel);
-		outw(card->port_status, card->base + 0x02);
-	}
+	card->port_status &= ~(1 << ip->channel);
+	outw(card->port_status, card->base + 0x02);
 	isicom_shutdown_port(ip);
 	spin_unlock_irqrestore(&card->card_lock, flags);
+	tty_port_free_xmit_buf(port);
 }
 
 static void isicom_close(struct tty_struct *tty, struct file *filp)
@@ -991,12 +935,7 @@ static void isicom_close(struct tty_stru
 	struct tty_port *port = &ip->port;
 	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
 		return;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-	isicom_close_port(port);
-	isicom_flush_buffer(tty);
-	tty_port_close_end(port, tty);
+	tty_port_close(port, tty, filp);
 }
 
 /* write et all */
@@ -1326,15 +1265,9 @@ static void isicom_start(struct tty_stru
 static void isicom_hangup(struct tty_struct *tty)
 {
 	struct isi_port *port = tty->driver_data;
-	unsigned long flags;
 
 	if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
 		return;
-
-	spin_lock_irqsave(&port->card->card_lock, flags);
-	isicom_shutdown_port(port);
-	spin_unlock_irqrestore(&port->card->card_lock, flags);
-
 	tty_port_hangup(&port->port);
 }
 
@@ -1367,6 +1300,8 @@ static const struct tty_operations isico
 static const struct tty_port_operations isicom_port_ops = {
 	.carrier_raised		= isicom_carrier_raised,
 	.dtr_rts		= isicom_dtr_rts,
+	.activate		= isicom_activate,
+	.shutdown		= isicom_shutdown,
 };
 
 static int __devinit reset_card(struct pci_dev *pdev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/istallion.c linux-libre-2.6.33-gnu1/drivers/char/istallion.c
--- linux-libre-2.6.32-gnu1/drivers/char/istallion.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/istallion.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,7 +213,6 @@ static int		stli_shared;
  *	with the slave. Most of them need to be updated atomically, so always
  *	use the bit setting operations (unless protected by cli/sti).
  */
-#define	ST_INITIALIZING	1
 #define	ST_OPENING	2
 #define	ST_CLOSING	3
 #define	ST_CMDING	4
@@ -621,7 +620,7 @@ static int	stli_brdinit(struct stlibrd *
 static int	stli_startbrd(struct stlibrd *brdp);
 static ssize_t	stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
 static ssize_t	stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
-static int	stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long	stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 static void	stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
 static void	stli_poll(unsigned long arg);
 static int	stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
@@ -704,7 +703,7 @@ static const struct file_operations	stli
 	.owner		= THIS_MODULE,
 	.read		= stli_memread,
 	.write		= stli_memwrite,
-	.ioctl		= stli_memioctl,
+	.unlocked_ioctl	= stli_memioctl,
 };
 
 /*****************************************************************************/
@@ -783,13 +782,32 @@ static int stli_parsebrd(struct stlconf
 
 /*****************************************************************************/
 
+/*
+ *	On the first open of the device setup the port hardware, and
+ *	initialize the per port data structure. Since initializing the port
+ *	requires several commands to the board we will need to wait for any
+ *	other open that is already initializing the port.
+ *
+ *	Locking: protected by the port mutex.
+ */
+
+static int stli_activate(struct tty_port *port, struct tty_struct *tty)
+{
+	struct stliport *portp = container_of(port, struct stliport, port);
+	struct stlibrd *brdp = stli_brds[portp->brdnr];
+	int rc;
+
+	if ((rc = stli_initopen(tty, brdp, portp)) >= 0)
+		clear_bit(TTY_IO_ERROR, &tty->flags);
+	wake_up_interruptible(&portp->raw_wait);
+	return rc;
+}
+
 static int stli_open(struct tty_struct *tty, struct file *filp)
 {
 	struct stlibrd *brdp;
 	struct stliport *portp;
-	struct tty_port *port;
 	unsigned int minordev, brdnr, portnr;
-	int rc;
 
 	minordev = tty->index;
 	brdnr = MINOR2BRD(minordev);
@@ -809,95 +827,56 @@ static int stli_open(struct tty_struct *
 		return -ENODEV;
 	if (portp->devnr < 1)
 		return -ENODEV;
-	port = &portp->port;
-
-/*
- *	On the first open of the device setup the port hardware, and
- *	initialize the per port data structure. Since initializing the port
- *	requires several commands to the board we will need to wait for any
- *	other open that is already initializing the port.
- *
- *	Review - locking
- */
-	tty_port_tty_set(port, tty);
-	tty->driver_data = portp;
-	port->count++;
-
-	wait_event_interruptible(portp->raw_wait,
-			!test_bit(ST_INITIALIZING, &portp->state));
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-
-	if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
-		set_bit(ST_INITIALIZING, &portp->state);
-		if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
-			/* Locking */
-			port->flags |= ASYNC_INITIALIZED;
-			clear_bit(TTY_IO_ERROR, &tty->flags);
-		}
-		clear_bit(ST_INITIALIZING, &portp->state);
-		wake_up_interruptible(&portp->raw_wait);
-		if (rc < 0)
-			return rc;
-	}
-	return tty_port_block_til_ready(&portp->port, tty, filp);
+	return tty_port_open(&portp->port, tty, filp);
 }
 
+
 /*****************************************************************************/
 
-static void stli_close(struct tty_struct *tty, struct file *filp)
+static void stli_shutdown(struct tty_port *port)
 {
 	struct stlibrd *brdp;
-	struct stliport *portp;
-	struct tty_port *port;
+	unsigned long ftype;
 	unsigned long flags;
+	struct stliport *portp = container_of(port, struct stliport, port);
 
-	portp = tty->driver_data;
-	if (portp == NULL)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
-	port = &portp->port;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
+	brdp = stli_brds[portp->brdnr];
+	if (brdp == NULL)
 		return;
 
-/*
- *	May want to wait for data to drain before closing. The BUSY flag
- *	keeps track of whether we are still transmitting or not. It is
- *	updated by messages from the slave - indicating when all chars
- *	really have drained.
- */
- 	spin_lock_irqsave(&stli_lock, flags);
-	if (tty == stli_txcooktty)
-		stli_flushchars(tty);
-	spin_unlock_irqrestore(&stli_lock, flags);
-
-	/* We end up doing this twice for the moment. This needs looking at
-	   eventually. Note we still use portp->closing_wait as a result */
-	if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, portp->closing_wait);
+	/*
+	 *	May want to wait for data to drain before closing. The BUSY
+	 *	flag keeps track of whether we are still transmitting or not.
+	 *	It is updated by messages from the slave - indicating when all
+	 *	chars really have drained.
+	 */
 
-	/* FIXME: port locking here needs attending to */
-	port->flags &= ~ASYNC_INITIALIZED;
+	if (!test_bit(ST_CLOSING, &portp->state))
+		stli_rawclose(brdp, portp, 0, 0);
 
-	brdp = stli_brds[portp->brdnr];
-	stli_rawclose(brdp, portp, 0, 0);
-	if (tty->termios->c_cflag & HUPCL) {
-		stli_mkasysigs(&portp->asig, 0, 0);
-		if (test_bit(ST_CMDING, &portp->state))
-			set_bit(ST_DOSIGS, &portp->state);
-		else
-			stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
-				sizeof(asysigs_t), 0);
-	}
+ 	spin_lock_irqsave(&stli_lock, flags);
 	clear_bit(ST_TXBUSY, &portp->state);
 	clear_bit(ST_RXSTOP, &portp->state);
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	tty_ldisc_flush(tty);
-	set_bit(ST_DOFLUSHRX, &portp->state);
-	stli_flushbuffer(tty);
+	spin_unlock_irqrestore(&stli_lock, flags);
 
-	tty_port_close_end(port, tty);
-	tty_port_tty_set(port, NULL);
+	ftype = FLUSHTX | FLUSHRX;
+	stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
+}
+
+static void stli_close(struct tty_struct *tty, struct file *filp)
+{
+	struct stliport *portp = tty->driver_data;
+	unsigned long flags;
+	if (portp == NULL)
+		return;
+ 	spin_lock_irqsave(&stli_lock, flags);
+	/*	Flush any internal buffering out first */
+	if (tty == stli_txcooktty)
+		stli_flushchars(tty);
+	spin_unlock_irqrestore(&stli_lock, flags);
+	tty_port_close(&portp->port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -1724,6 +1703,7 @@ static void stli_start(struct tty_struct
 
 /*****************************************************************************/
 
+
 /*
  *	Hangup this port. This is pretty much like closing the port, only
  *	a little more brutal. No waiting for data to drain. Shutdown the
@@ -1733,47 +1713,8 @@ static void stli_start(struct tty_struct
 
 static void stli_hangup(struct tty_struct *tty)
 {
-	struct stliport *portp;
-	struct stlibrd *brdp;
-	struct tty_port *port;
-	unsigned long flags;
-
-	portp = tty->driver_data;
-	if (portp == NULL)
-		return;
-	if (portp->brdnr >= stli_nrbrds)
-		return;
-	brdp = stli_brds[portp->brdnr];
-	if (brdp == NULL)
-		return;
-	port = &portp->port;
-
-	spin_lock_irqsave(&port->lock, flags);
-	port->flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	if (!test_bit(ST_CLOSING, &portp->state))
-		stli_rawclose(brdp, portp, 0, 0);
-
-	spin_lock_irqsave(&stli_lock, flags);
-	if (tty->termios->c_cflag & HUPCL) {
-		stli_mkasysigs(&portp->asig, 0, 0);
-		if (test_bit(ST_CMDING, &portp->state)) {
-			set_bit(ST_DOSIGS, &portp->state);
-			set_bit(ST_DOFLUSHTX, &portp->state);
-			set_bit(ST_DOFLUSHRX, &portp->state);
-		} else {
-			stli_sendcmd(brdp, portp, A_SETSIGNALSF,
-				&portp->asig, sizeof(asysigs_t), 0);
-		}
-	}
-
-	clear_bit(ST_TXBUSY, &portp->state);
-	clear_bit(ST_RXSTOP, &portp->state);
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	spin_unlock_irqrestore(&stli_lock, flags);
-
-	tty_port_hangup(port);
+	struct stliport *portp = tty->driver_data;
+	tty_port_hangup(&portp->port);
 }
 
 /*****************************************************************************/
@@ -4311,7 +4252,7 @@ static int stli_getbrdstruct(struct stli
  *	reset it, and start/stop it.
  */
 
-static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	struct stlibrd *brdp;
 	int brdnr, rc, done;
@@ -4356,7 +4297,7 @@ static int stli_memioctl(struct inode *i
  *	Now handle the board specific ioctls. These all depend on the
  *	minor number of the device they were called from.
  */
-	brdnr = iminor(ip);
+	brdnr = iminor(fp->f_dentry->d_inode);
 	if (brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	brdp = stli_brds[brdnr];
@@ -4420,6 +4361,8 @@ static const struct tty_operations stli_
 static const struct tty_port_operations stli_port_ops = {
 	.carrier_raised = stli_carrier_raised,
 	.dtr_rts = stli_dtr_rts,
+	.activate = stli_activate,
+	.shutdown = stli_shutdown,
 };
 
 /*****************************************************************************/
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/Kconfig linux-libre-2.6.33-gnu1/drivers/char/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/char/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,19 +201,6 @@ config DIGIEPCA
 	  To compile this driver as a module, choose M here: the
 	  module will be called epca.
 
-config ESPSERIAL
-	tristate "Hayes ESP serial port support"
-	depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN
-	help
-	  This is a driver which supports Hayes ESP serial ports.  Both single
-	  port cards and multiport cards are supported.  Make sure to read
-	  <file:Documentation/hayes-esp.txt>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called esp.
-
-	  If unsure, say N.
-
 config MOXA_INTELLIO
 	tristate "Moxa Intellio support"
 	depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
@@ -515,7 +502,7 @@ config BRIQ_PANEL
 
 config BFIN_OTP
 	tristate "Blackfin On-Chip OTP Memory Support"
-	depends on BLACKFIN && (BF52x || BF54x)
+	depends on BLACKFIN && (BF51x || BF52x || BF54x)
 	default y
 	help
 	  If you say Y here, you will get support for a character device
@@ -682,7 +669,7 @@ config VIRTIO_CONSOLE
 
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
-	depends on PPC_PSERIES
+	depends on PPC_PSERIES && HVC_CONSOLE
 	help
 	  Partitionable IBM Power5 ppc64 machines allow hosting of
 	  firmware virtual consoles from one Linux partition by
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/keyboard.c linux-libre-2.6.33-gnu1/drivers/char/keyboard.c
--- linux-libre-2.6.32-gnu1/drivers/char/keyboard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/keyboard.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,8 +46,6 @@
 
 extern void ctrl_alt_del(void);
 
-#define to_handle_h(n) container_of(n, struct input_handle, h_node)
-
 /*
  * Exported functions/variables
  */
@@ -132,6 +130,7 @@ int shift_state = 0;
  */
 
 static struct input_handler kbd_handler;
+static DEFINE_SPINLOCK(kbd_event_lock);
 static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];	/* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];		/* shift state counters.. */
 static int dead_key_next;
@@ -190,78 +189,89 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_no
  *  etc.). So this means that scancodes for the extra function keys won't
  *  be valid for the first event device, but will be for the second.
  */
+
+struct getset_keycode_data {
+	unsigned int scancode;
+	unsigned int keycode;
+	int error;
+};
+
+static int getkeycode_helper(struct input_handle *handle, void *data)
+{
+	struct getset_keycode_data *d = data;
+
+	d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode);
+
+	return d->error == 0; /* stop as soon as we successfully get one */
+}
+
 int getkeycode(unsigned int scancode)
 {
-	struct input_handle *handle;
-	int keycode;
-	int error = -ENODEV;
+	struct getset_keycode_data d = { scancode, 0, -ENODEV };
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		error = input_get_keycode(handle->dev, scancode, &keycode);
-		if (!error)
-			return keycode;
-	}
+	input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
 
-	return error;
+	return d.error ?: d.keycode;
+}
+
+static int setkeycode_helper(struct input_handle *handle, void *data)
+{
+	struct getset_keycode_data *d = data;
+
+	d->error = input_set_keycode(handle->dev, d->scancode, d->keycode);
+
+	return d->error == 0; /* stop as soon as we successfully set one */
 }
 
 int setkeycode(unsigned int scancode, unsigned int keycode)
 {
-	struct input_handle *handle;
-	int error = -ENODEV;
+	struct getset_keycode_data d = { scancode, keycode, -ENODEV };
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		error = input_set_keycode(handle->dev, scancode, keycode);
-		if (!error)
-			break;
-	}
+	input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
 
-	return error;
+	return d.error;
 }
 
 /*
- * Making beeps and bells.
+ * Making beeps and bells. Note that we prefer beeps to bells, but when
+ * shutting the sound off we do both.
  */
-static void kd_nosound(unsigned long ignored)
+
+static int kd_sound_helper(struct input_handle *handle, void *data)
 {
-	struct input_handle *handle;
+	unsigned int *hz = data;
+	struct input_dev *dev = handle->dev;
 
-	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
-		if (test_bit(EV_SND, handle->dev->evbit)) {
-			if (test_bit(SND_TONE, handle->dev->sndbit))
-				input_inject_event(handle, EV_SND, SND_TONE, 0);
-			if (test_bit(SND_BELL, handle->dev->sndbit))
-				input_inject_event(handle, EV_SND, SND_BELL, 0);
+	if (test_bit(EV_SND, dev->evbit)) {
+		if (test_bit(SND_TONE, dev->sndbit)) {
+			input_inject_event(handle, EV_SND, SND_TONE, *hz);
+			if (*hz)
+				return 0;
 		}
+		if (test_bit(SND_BELL, dev->sndbit))
+			input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
 	}
+
+	return 0;
+}
+
+static void kd_nosound(unsigned long ignored)
+{
+	static unsigned int zero;
+
+	input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
 }
 
 static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
 
 void kd_mksound(unsigned int hz, unsigned int ticks)
 {
-	struct list_head *node;
+	del_timer_sync(&kd_mksound_timer);
 
-	del_timer(&kd_mksound_timer);
+	input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
 
-	if (hz) {
-		list_for_each_prev(node, &kbd_handler.h_list) {
-			struct input_handle *handle = to_handle_h(node);
-			if (test_bit(EV_SND, handle->dev->evbit)) {
-				if (test_bit(SND_TONE, handle->dev->sndbit)) {
-					input_inject_event(handle, EV_SND, SND_TONE, hz);
-					break;
-				}
-				if (test_bit(SND_BELL, handle->dev->sndbit)) {
-					input_inject_event(handle, EV_SND, SND_BELL, 1);
-					break;
-				}
-			}
-		}
-		if (ticks)
-			mod_timer(&kd_mksound_timer, jiffies + ticks);
-	} else
-		kd_nosound(0);
+	if (hz && ticks)
+		mod_timer(&kd_mksound_timer, jiffies + ticks);
 }
 EXPORT_SYMBOL(kd_mksound);
 
@@ -269,27 +279,34 @@ EXPORT_SYMBOL(kd_mksound);
  * Setting the keyboard rate.
  */
 
-int kbd_rate(struct kbd_repeat *rep)
+static int kbd_rate_helper(struct input_handle *handle, void *data)
 {
-	struct list_head *node;
-	unsigned int d = 0;
-	unsigned int p = 0;
+	struct input_dev *dev = handle->dev;
+	struct kbd_repeat *rep = data;
 
-	list_for_each(node, &kbd_handler.h_list) {
-		struct input_handle *handle = to_handle_h(node);
-		struct input_dev *dev = handle->dev;
+	if (test_bit(EV_REP, dev->evbit)) {
 
-		if (test_bit(EV_REP, dev->evbit)) {
-			if (rep->delay > 0)
-				input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
-			if (rep->period > 0)
-				input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
-			d = dev->rep[REP_DELAY];
-			p = dev->rep[REP_PERIOD];
-		}
+		if (rep[0].delay > 0)
+			input_inject_event(handle,
+					   EV_REP, REP_DELAY, rep[0].delay);
+		if (rep[0].period > 0)
+			input_inject_event(handle,
+					   EV_REP, REP_PERIOD, rep[0].period);
+
+		rep[1].delay = dev->rep[REP_DELAY];
+		rep[1].period = dev->rep[REP_PERIOD];
 	}
-	rep->delay  = d;
-	rep->period = p;
+
+	return 0;
+}
+
+int kbd_rate(struct kbd_repeat *rep)
+{
+	struct kbd_repeat data[2] = { *rep };
+
+	input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
+	*rep = data[1];	/* Copy currently used settings */
+
 	return 0;
 }
 
@@ -997,36 +1014,36 @@ static inline unsigned char getleds(void
 	return leds;
 }
 
+static int kbd_update_leds_helper(struct input_handle *handle, void *data)
+{
+	unsigned char leds = *(unsigned char *)data;
+
+	if (test_bit(EV_LED, handle->dev->evbit)) {
+		input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+		input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
+		input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+		input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
+	}
+
+	return 0;
+}
+
 /*
- * This routine is the bottom half of the keyboard interrupt
- * routine, and runs with all interrupts enabled. It does
- * console changing, led setting and copy_to_cooked, which can
- * take a reasonably long time.
- *
- * Aside from timing (which isn't really that important for
- * keyboard interrupts as they happen often), using the software
- * interrupt routines for this thing allows us to easily mask
- * this when we don't want any of the above to happen.
- * This allows for easy and efficient race-condition prevention
- * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
+ * This is the tasklet that updates LED state on all keyboards
+ * attached to the box. The reason we use tasklet is that we
+ * need to handle the scenario when keyboard handler is not
+ * registered yet but we already getting updates form VT to
+ * update led state.
  */
-
 static void kbd_bh(unsigned long dummy)
 {
-	struct list_head *node;
 	unsigned char leds = getleds();
 
 	if (leds != ledstate) {
-		list_for_each(node, &kbd_handler.h_list) {
-			struct input_handle *handle = to_handle_h(node);
-			input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-			input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
-			input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-			input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
-		}
+		input_handler_for_each_handle(&kbd_handler, &leds,
+					      kbd_update_leds_helper);
+		ledstate = leds;
 	}
-
-	ledstate = leds;
 }
 
 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
@@ -1136,7 +1153,7 @@ static int emulate_raw(struct vc_data *v
 static void kbd_rawcode(unsigned char data)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
-	kbd = kbd_table + fg_console;
+	kbd = kbd_table + vc->vc_num;
 	if (kbd->kbdmode == VC_RAW)
 		put_queue(vc, data);
 }
@@ -1157,7 +1174,7 @@ static void kbd_keycode(unsigned int key
 		tty->driver_data = vc;
 	}
 
-	kbd = kbd_table + fg_console;
+	kbd = kbd_table + vc->vc_num;
 
 	if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
 		sysrq_alt = down ? keycode : 0;
@@ -1296,10 +1313,16 @@ static void kbd_keycode(unsigned int key
 static void kbd_event(struct input_handle *handle, unsigned int event_type,
 		      unsigned int event_code, int value)
 {
+	/* We are called with interrupts disabled, just take the lock */
+	spin_lock(&kbd_event_lock);
+
 	if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
 		kbd_rawcode(value);
 	if (event_type == EV_KEY)
 		kbd_keycode(event_code, value, HW_RAW(handle->dev));
+
+	spin_unlock(&kbd_event_lock);
+
 	tasklet_schedule(&keyboard_tasklet);
 	do_poke_blanked_console = 1;
 	schedule_console_callback();
@@ -1363,15 +1386,11 @@ static void kbd_disconnect(struct input_
  */
 static void kbd_start(struct input_handle *handle)
 {
-	unsigned char leds = ledstate;
-
 	tasklet_disable(&keyboard_tasklet);
-	if (leds != 0xff) {
-		input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-		input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
-		input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-		input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
-	}
+
+	if (ledstate != 0xff)
+		kbd_update_leds_helper(handle, &ledstate);
+
 	tasklet_enable(&keyboard_tasklet);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/lp.c linux-libre-2.6.33-gnu1/drivers/char/lp.c
--- linux-libre-2.6.32-gnu1/drivers/char/lp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/lp.c	2010-02-24 13:52:17.000000000 -0500
@@ -127,6 +127,7 @@
 #include <linux/wait.h>
 #include <linux/jiffies.h>
 #include <linux/smp_lock.h>
+#include <linux/compat.h>
 
 #include <linux/parport.h>
 #undef LP_STATS
@@ -571,13 +572,11 @@ static int lp_release(struct inode * ino
 	return 0;
 }
 
-static int lp_ioctl(struct inode *inode, struct file *file,
-		    unsigned int cmd, unsigned long arg)
+static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
+	unsigned long arg, void __user *argp)
 {
-	unsigned int minor = iminor(inode);
 	int status;
 	int retval = 0;
-	void __user *argp = (void __user *)arg;
 
 #ifdef LP_DEBUG
 	printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
@@ -587,9 +586,6 @@ static int lp_ioctl(struct inode *inode,
 	if ((LP_F(minor) & LP_EXIST) == 0)
 		return -ENODEV;
 	switch ( cmd ) {
-		struct timeval par_timeout;
-		long to_jiffies;
-
 		case LPTIME:
 			LP_TIME(minor) = arg * HZ/100;
 			break;
@@ -652,34 +648,101 @@ static int lp_ioctl(struct inode *inode,
 				return -EFAULT;
 			break;
 
-		case LPSETTIMEOUT:
-			if (copy_from_user (&par_timeout, argp,
-					    sizeof (struct timeval))) {
-				return -EFAULT;
-			}
-			/* Convert to jiffies, place in lp_table */
-			if ((par_timeout.tv_sec < 0) ||
-			    (par_timeout.tv_usec < 0)) {
-				return -EINVAL;
-			}
-			to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
-			to_jiffies += par_timeout.tv_sec * (long) HZ;
-			if (to_jiffies <= 0) {
-				return -EINVAL;
-			}
-			lp_table[minor].timeout = to_jiffies;
-			break;
-
 		default:
 			retval = -EINVAL;
 	}
 	return retval;
 }
 
+static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout)
+{
+	long to_jiffies;
+
+	/* Convert to jiffies, place in lp_table */
+	if ((par_timeout->tv_sec < 0) ||
+	    (par_timeout->tv_usec < 0)) {
+		return -EINVAL;
+	}
+	to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ);
+	to_jiffies += par_timeout->tv_sec * (long) HZ;
+	if (to_jiffies <= 0) {
+		return -EINVAL;
+	}
+	lp_table[minor].timeout = to_jiffies;
+	return 0;
+}
+
+static long lp_ioctl(struct file *file, unsigned int cmd,
+			unsigned long arg)
+{
+	unsigned int minor;
+	struct timeval par_timeout;
+	int ret;
+
+	minor = iminor(file->f_path.dentry->d_inode);
+	lock_kernel();
+	switch (cmd) {
+	case LPSETTIMEOUT:
+		if (copy_from_user(&par_timeout, (void __user *)arg,
+					sizeof (struct timeval))) {
+			ret = -EFAULT;
+			break;
+		}
+		ret = lp_set_timeout(minor, &par_timeout);
+		break;
+	default:
+		ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg);
+		break;
+	}
+	unlock_kernel();
+
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long lp_compat_ioctl(struct file *file, unsigned int cmd,
+			unsigned long arg)
+{
+	unsigned int minor;
+	struct timeval par_timeout;
+	struct compat_timeval __user *tc;
+	int ret;
+
+	minor = iminor(file->f_path.dentry->d_inode);
+	lock_kernel();
+	switch (cmd) {
+	case LPSETTIMEOUT:
+		tc = compat_ptr(arg);
+		if (get_user(par_timeout.tv_sec, &tc->tv_sec) ||
+		    get_user(par_timeout.tv_usec, &tc->tv_usec)) {
+			ret = -EFAULT;
+			break;
+		}
+		ret = lp_set_timeout(minor, &par_timeout);
+		break;
+#ifdef LP_STATS
+	case LPGETSTATS:
+		/* FIXME: add an implementation if you set LP_STATS */
+		ret = -EINVAL;
+		break;
+#endif
+	default:
+		ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg));
+		break;
+	}
+	unlock_kernel();
+
+	return ret;
+}
+#endif
+
 static const struct file_operations lp_fops = {
 	.owner		= THIS_MODULE,
 	.write		= lp_write,
-	.ioctl		= lp_ioctl,
+	.unlocked_ioctl	= lp_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= lp_compat_ioctl,
+#endif
 	.open		= lp_open,
 	.release	= lp_release,
 #ifdef CONFIG_PARPORT_1284
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/Makefile linux-libre-2.6.33-gnu1/drivers/char/Makefile
--- linux-libre-2.6.32-gnu1/drivers/char/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,6 @@ obj-$(CONFIG_CONSOLE_TRANSLATIONS) += co
 obj-$(CONFIG_HW_CONSOLE)	+= vt.o defkeymap.o
 obj-$(CONFIG_AUDIT)		+= tty_audit.o
 obj-$(CONFIG_MAGIC_SYSRQ)	+= sysrq.o
-obj-$(CONFIG_ESPSERIAL)		+= esp.o
 obj-$(CONFIG_MVME147_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_MVME162_SCC)	+= generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC)	+= generic_serial.o vme_scc.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/mem.c linux-libre-2.6.33-gnu1/drivers/char/mem.c
--- linux-libre-2.6.32-gnu1/drivers/char/mem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/mem.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,7 @@
  *
  *  Added devfs support. 
  *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
- *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
+ *  Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
  */
 
 #include <linux/mm.h>
@@ -26,7 +26,6 @@
 #include <linux/bootmem.h>
 #include <linux/splice.h>
 #include <linux/pfn.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -35,6 +34,16 @@
 # include <linux/efi.h>
 #endif
 
+static inline unsigned long size_inside_page(unsigned long start,
+					     unsigned long size)
+{
+	unsigned long sz;
+
+	sz = PAGE_SIZE - (start & (PAGE_SIZE - 1));
+
+	return min(sz, size);
+}
+
 /*
  * Architectures vary in how they handle caching for addresses
  * outside of main memory.
@@ -44,7 +53,7 @@ static inline int uncached_access(struct
 {
 #if defined(CONFIG_IA64)
 	/*
-	 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
+	 * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases.
 	 */
 	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
 #elif defined(CONFIG_MIPS)
@@ -57,9 +66,9 @@ static inline int uncached_access(struct
 #else
 	/*
 	 * Accessing memory above the top the kernel knows about or through a file pointer
-	 * that was marked O_SYNC will be done non-cached.
+	 * that was marked O_DSYNC will be done non-cached.
 	 */
-	if (file->f_flags & O_SYNC)
+	if (file->f_flags & O_DSYNC)
 		return 1;
 	return addr >= __pa(high_memory);
 #endif
@@ -127,9 +136,7 @@ static ssize_t read_mem(struct file * fi
 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
 	/* we don't have page 0 mapped on sparc and m68k.. */
 	if (p < PAGE_SIZE) {
-		sz = PAGE_SIZE - p;
-		if (sz > count) 
-			sz = count; 
+		sz = size_inside_page(p, count);
 		if (sz > 0) {
 			if (clear_user(buf, sz))
 				return -EFAULT;
@@ -142,15 +149,9 @@ static ssize_t read_mem(struct file * fi
 #endif
 
 	while (count > 0) {
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-p & (PAGE_SIZE - 1))
-			sz = -p & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
+		unsigned long remaining;
 
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(p, count);
 
 		if (!range_is_allowed(p >> PAGE_SHIFT, count))
 			return -EPERM;
@@ -164,12 +165,10 @@ static ssize_t read_mem(struct file * fi
 		if (!ptr)
 			return -EFAULT;
 
-		if (copy_to_user(buf, ptr, sz)) {
-			unxlate_dev_mem_ptr(p, ptr);
-			return -EFAULT;
-		}
-
+		remaining = copy_to_user(buf, ptr, sz);
 		unxlate_dev_mem_ptr(p, ptr);
+		if (remaining)
+			return -EFAULT;
 
 		buf += sz;
 		p += sz;
@@ -197,9 +196,7 @@ static ssize_t write_mem(struct file * f
 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
 	/* we don't have page 0 mapped on sparc and m68k.. */
 	if (p < PAGE_SIZE) {
-		unsigned long sz = PAGE_SIZE - p;
-		if (sz > count)
-			sz = count;
+		sz = size_inside_page(p, count);
 		/* Hmm. Do something? */
 		buf += sz;
 		p += sz;
@@ -209,15 +206,7 @@ static ssize_t write_mem(struct file * f
 #endif
 
 	while (count > 0) {
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-p & (PAGE_SIZE - 1))
-			sz = -p & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
-
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(p, count);
 
 		if (!range_is_allowed(p >> PAGE_SHIFT, sz))
 			return -EPERM;
@@ -235,16 +224,14 @@ static ssize_t write_mem(struct file * f
 		}
 
 		copied = copy_from_user(ptr, buf, sz);
+		unxlate_dev_mem_ptr(p, ptr);
 		if (copied) {
 			written += sz - copied;
-			unxlate_dev_mem_ptr(p, ptr);
 			if (written)
 				break;
 			return -EFAULT;
 		}
 
-		unxlate_dev_mem_ptr(p, ptr);
-
 		buf += sz;
 		p += sz;
 		count -= sz;
@@ -408,6 +395,7 @@ static ssize_t read_kmem(struct file *fi
 	unsigned long p = *ppos;
 	ssize_t low_count, read, sz;
 	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
+	int err = 0;
 
 	read = 0;
 	if (p < (unsigned long) high_memory) {
@@ -418,27 +406,18 @@ static ssize_t read_kmem(struct file *fi
 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
 		/* we don't have page 0 mapped on sparc and m68k.. */
 		if (p < PAGE_SIZE && low_count > 0) {
-			size_t tmp = PAGE_SIZE - p;
-			if (tmp > low_count) tmp = low_count;
-			if (clear_user(buf, tmp))
+			sz = size_inside_page(p, low_count);
+			if (clear_user(buf, sz))
 				return -EFAULT;
-			buf += tmp;
-			p += tmp;
-			read += tmp;
-			low_count -= tmp;
-			count -= tmp;
+			buf += sz;
+			p += sz;
+			read += sz;
+			low_count -= sz;
+			count -= sz;
 		}
 #endif
 		while (low_count > 0) {
-			/*
-			 * Handle first page in case it's not aligned
-			 */
-			if (-p & (PAGE_SIZE - 1))
-				sz = -p & (PAGE_SIZE - 1);
-			else
-				sz = PAGE_SIZE;
-
-			sz = min_t(unsigned long, sz, low_count);
+			sz = size_inside_page(p, low_count);
 
 			/*
 			 * On ia64 if a page has been mapped somewhere as
@@ -462,31 +441,32 @@ static ssize_t read_kmem(struct file *fi
 		if (!kbuf)
 			return -ENOMEM;
 		while (count > 0) {
-			int len = count;
-
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
-			len = vread(kbuf, (char *)p, len);
-			if (!len)
+			sz = size_inside_page(p, count);
+			if (!is_vmalloc_or_module_addr((void *)p)) {
+				err = -ENXIO;
 				break;
-			if (copy_to_user(buf, kbuf, len)) {
-				free_page((unsigned long)kbuf);
-				return -EFAULT;
 			}
-			count -= len;
-			buf += len;
-			read += len;
-			p += len;
+			sz = vread(kbuf, (char *)p, sz);
+			if (!sz)
+				break;
+			if (copy_to_user(buf, kbuf, sz)) {
+				err = -EFAULT;
+				break;
+			}
+			count -= sz;
+			buf += sz;
+			read += sz;
+			p += sz;
 		}
 		free_page((unsigned long)kbuf);
 	}
- 	*ppos = p;
- 	return read;
+	*ppos = p;
+	return read ? read : err;
 }
 
 
 static inline ssize_t
-do_write_kmem(void *p, unsigned long realp, const char __user * buf,
+do_write_kmem(unsigned long p, const char __user *buf,
 	      size_t count, loff_t *ppos)
 {
 	ssize_t written, sz;
@@ -495,14 +475,11 @@ do_write_kmem(void *p, unsigned long rea
 	written = 0;
 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
 	/* we don't have page 0 mapped on sparc and m68k.. */
-	if (realp < PAGE_SIZE) {
-		unsigned long sz = PAGE_SIZE - realp;
-		if (sz > count)
-			sz = count;
+	if (p < PAGE_SIZE) {
+		sz = size_inside_page(p, count);
 		/* Hmm. Do something? */
 		buf += sz;
 		p += sz;
-		realp += sz;
 		count -= sz;
 		written += sz;
 	}
@@ -510,22 +487,15 @@ do_write_kmem(void *p, unsigned long rea
 
 	while (count > 0) {
 		char *ptr;
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-realp & (PAGE_SIZE - 1))
-			sz = -realp & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
 
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(p, count);
 
 		/*
 		 * On ia64 if a page has been mapped somewhere as
 		 * uncached, then it must also be accessed uncached
 		 * by the kernel or data corruption may occur
 		 */
-		ptr = xlate_dev_kmem_ptr(p);
+		ptr = xlate_dev_kmem_ptr((char *)p);
 
 		copied = copy_from_user(ptr, buf, sz);
 		if (copied) {
@@ -536,7 +506,6 @@ do_write_kmem(void *p, unsigned long rea
 		}
 		buf += sz;
 		p += sz;
-		realp += sz;
 		count -= sz;
 		written += sz;
 	}
@@ -555,19 +524,15 @@ static ssize_t write_kmem(struct file *
 	unsigned long p = *ppos;
 	ssize_t wrote = 0;
 	ssize_t virtr = 0;
-	ssize_t written;
 	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+	int err = 0;
 
 	if (p < (unsigned long) high_memory) {
-
-		wrote = count;
-		if (count > (unsigned long) high_memory - p)
-			wrote = (unsigned long) high_memory - p;
-
-		written = do_write_kmem((void*)p, p, buf, wrote, ppos);
-		if (written != wrote)
-			return written;
-		wrote = written;
+		unsigned long to_write = min_t(unsigned long, count,
+					       (unsigned long)high_memory - p);
+		wrote = do_write_kmem(p, buf, to_write, ppos);
+		if (wrote != to_write)
+			return wrote;
 		p += wrote;
 		buf += wrote;
 		count -= wrote;
@@ -578,30 +543,29 @@ static ssize_t write_kmem(struct file *
 		if (!kbuf)
 			return wrote ? wrote : -ENOMEM;
 		while (count > 0) {
-			int len = count;
+			unsigned long sz = size_inside_page(p, count);
+			unsigned long n;
 
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
-			if (len) {
-				written = copy_from_user(kbuf, buf, len);
-				if (written) {
-					if (wrote + virtr)
-						break;
-					free_page((unsigned long)kbuf);
-					return -EFAULT;
-				}
+			if (!is_vmalloc_or_module_addr((void *)p)) {
+				err = -ENXIO;
+				break;
 			}
-			len = vwrite(kbuf, (char *)p, len);
-			count -= len;
-			buf += len;
-			virtr += len;
-			p += len;
+			n = copy_from_user(kbuf, buf, sz);
+			if (n) {
+				err = -EFAULT;
+				break;
+			}
+			vwrite(kbuf, (char *)p, sz);
+			count -= sz;
+			buf += sz;
+			virtr += sz;
+			p += sz;
 		}
 		free_page((unsigned long)kbuf);
 	}
 
- 	*ppos = p;
- 	return virtr + wrote;
+	*ppos = p;
+	return virtr + wrote ? : err;
 }
 #endif
 
@@ -892,29 +856,23 @@ static int memory_open(struct inode *ino
 {
 	int minor;
 	const struct memdev *dev;
-	int ret = -ENXIO;
-
-	lock_kernel();
 
 	minor = iminor(inode);
 	if (minor >= ARRAY_SIZE(devlist))
-		goto out;
+		return -ENXIO;
 
 	dev = &devlist[minor];
 	if (!dev->fops)
-		goto out;
+		return -ENXIO;
 
 	filp->f_op = dev->fops;
 	if (dev->dev_info)
 		filp->f_mapping->backing_dev_info = dev->dev_info;
 
 	if (dev->fops->open)
-		ret = dev->fops->open(inode, filp);
-	else
-		ret = 0;
-out:
-	unlock_kernel();
-	return ret;
+		return dev->fops->open(inode, filp);
+
+	return 0;
 }
 
 static const struct file_operations memory_fops = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/misc.c linux-libre-2.6.33-gnu1/drivers/char/misc.c
--- linux-libre-2.6.32-gnu1/drivers/char/misc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/misc.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,6 @@
 #include <linux/device.h>
 #include <linux/tty.h>
 #include <linux/kmod.h>
-#include <linux/smp_lock.h>
 
 /*
  * Head entry for the doubly linked miscdevice list
@@ -61,9 +60,7 @@ static DEFINE_MUTEX(misc_mtx);
  * Assigned numbers, used for dynamic minors
  */
 #define DYNAMIC_MINORS 64 /* like dynamic majors */
-static unsigned char misc_minors[DYNAMIC_MINORS / 8];
-
-extern int pmu_device_init(void);
+static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS);
 
 #ifdef CONFIG_PROC_FS
 static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -118,8 +115,7 @@ static int misc_open(struct inode * inod
 	struct miscdevice *c;
 	int err = -ENODEV;
 	const struct file_operations *old_fops, *new_fops = NULL;
-	
-	lock_kernel();
+
 	mutex_lock(&misc_mtx);
 	
 	list_for_each_entry(c, &misc_list, list) {
@@ -157,7 +153,6 @@ static int misc_open(struct inode * inod
 	fops_put(old_fops);
 fail:
 	mutex_unlock(&misc_mtx);
-	unlock_kernel();
 	return err;
 }
 
@@ -201,24 +196,23 @@ int misc_register(struct miscdevice * mi
 	}
 
 	if (misc->minor == MISC_DYNAMIC_MINOR) {
-		int i = DYNAMIC_MINORS;
-		while (--i >= 0)
-			if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
-				break;
-		if (i<0) {
+		int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
+		if (i >= DYNAMIC_MINORS) {
 			mutex_unlock(&misc_mtx);
 			return -EBUSY;
 		}
-		misc->minor = i;
+		misc->minor = DYNAMIC_MINORS - i - 1;
+		set_bit(i, misc_minors);
 	}
 
-	if (misc->minor < DYNAMIC_MINORS)
-		misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
 	dev = MKDEV(MISC_MAJOR, misc->minor);
 
 	misc->this_device = device_create(misc_class, misc->parent, dev,
 					  misc, "%s", misc->name);
 	if (IS_ERR(misc->this_device)) {
+		int i = DYNAMIC_MINORS - misc->minor - 1;
+		if (i < DYNAMIC_MINORS && i >= 0)
+			clear_bit(i, misc_minors);
 		err = PTR_ERR(misc->this_device);
 		goto out;
 	}
@@ -245,7 +239,7 @@ int misc_register(struct miscdevice * mi
 
 int misc_deregister(struct miscdevice *misc)
 {
-	int i = misc->minor;
+	int i = DYNAMIC_MINORS - misc->minor - 1;
 
 	if (list_empty(&misc->list))
 		return -EINVAL;
@@ -253,9 +247,8 @@ int misc_deregister(struct miscdevice *m
 	mutex_lock(&misc_mtx);
 	list_del(&misc->list);
 	device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
-	if (i < DYNAMIC_MINORS && i>0) {
-		misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
-	}
+	if (i < DYNAMIC_MINORS && i >= 0)
+		clear_bit(i, misc_minors);
 	mutex_unlock(&misc_mtx);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/moxa.c linux-libre-2.6.33-gnu1/drivers/char/moxa.c
--- linux-libre-2.6.32-gnu1/drivers/char/moxa.c	2013-05-03 13:55:42.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/char/moxa.c	2013-05-03 12:03:16.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
@@ -139,7 +138,7 @@ struct moxa_port {
 	int cflag;
 	unsigned long statusflags;
 
-	u8 DCDState;
+	u8 DCDState;		/* Protected by the port lock */
 	u8 lineCtrl;
 	u8 lowChkFlag;
 };
@@ -151,10 +150,9 @@ struct mon_str {
 };
 
 /* statusflags */
-#define TXSTOPPED	0x1
-#define LOWWAIT 	0x2
-#define EMPTYWAIT	0x4
-#define THROTTLE	0x8
+#define TXSTOPPED	1
+#define LOWWAIT 	2
+#define EMPTYWAIT	3
 
 #define SERIAL_DO_RESTART
 
@@ -165,6 +163,7 @@ static struct mon_str moxaLog;
 static unsigned int moxaFuncTout = HZ / 2;
 static unsigned int moxaLowWaterChk;
 static DEFINE_MUTEX(moxa_openlock);
+static DEFINE_SPINLOCK(moxa_lock);
 /* Variables for insmod */
 #ifdef MODULE
 static unsigned long baseaddr[MAX_BOARDS];
@@ -194,8 +193,6 @@ static int moxa_write(struct tty_struct
 static int moxa_write_room(struct tty_struct *);
 static void moxa_flush_buffer(struct tty_struct *);
 static int moxa_chars_in_buffer(struct tty_struct *);
-static void moxa_throttle(struct tty_struct *);
-static void moxa_unthrottle(struct tty_struct *);
 static void moxa_set_termios(struct tty_struct *, struct ktermios *);
 static void moxa_stop(struct tty_struct *);
 static void moxa_start(struct tty_struct *);
@@ -205,9 +202,9 @@ static int moxa_tiocmset(struct tty_stru
 			 unsigned int set, unsigned int clear);
 static void moxa_poll(unsigned long);
 static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
-static void moxa_setup_empty_event(struct tty_struct *);
-static void moxa_shut_down(struct tty_struct *);
+static void moxa_shutdown(struct tty_port *);
 static int moxa_carrier_raised(struct tty_port *);
+static void moxa_dtr_rts(struct tty_port *, int);
 /*
  * moxa board interface functions:
  */
@@ -234,6 +231,8 @@ static void MoxaSetFifo(struct moxa_port
  * I/O functions
  */
 
+static DEFINE_SPINLOCK(moxafunc_lock);
+
 static void moxa_wait_finish(void __iomem *ofsAddr)
 {
 	unsigned long end = jiffies + moxaFuncTout;
@@ -247,9 +246,25 @@ static void moxa_wait_finish(void __iome
 
 static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
 {
+        unsigned long flags;
+        spin_lock_irqsave(&moxafunc_lock, flags);
+	writew(arg, ofsAddr + FuncArg);
+	writew(cmd, ofsAddr + FuncCode);
+	moxa_wait_finish(ofsAddr);
+	spin_unlock_irqrestore(&moxafunc_lock, flags);
+}
+
+static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
+{
+        unsigned long flags;
+        u16 ret;
+        spin_lock_irqsave(&moxafunc_lock, flags);
 	writew(arg, ofsAddr + FuncArg);
 	writew(cmd, ofsAddr + FuncCode);
 	moxa_wait_finish(ofsAddr);
+	ret = readw(ofsAddr + FuncArg);
+	spin_unlock_irqrestore(&moxafunc_lock, flags);
+	return ret;
 }
 
 static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -299,22 +314,20 @@ static int moxa_ioctl(struct tty_struct
 		struct moxa_port *p;
 		unsigned int i, j;
 
-		mutex_lock(&moxa_openlock);
 		for (i = 0; i < MAX_BOARDS; i++) {
 			p = moxa_boards[i].ports;
 			for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
 				memset(&tmp, 0, sizeof(tmp));
+				spin_lock_bh(&moxa_lock);
 				if (moxa_boards[i].ready) {
 					tmp.inq = MoxaPortRxQueue(p);
 					tmp.outq = MoxaPortTxQueue(p);
 				}
-				if (copy_to_user(argm, &tmp, sizeof(tmp))) {
-					mutex_unlock(&moxa_openlock);
+				spin_unlock_bh(&moxa_lock);
+				if (copy_to_user(argm, &tmp, sizeof(tmp)))
 					return -EFAULT;
-				}
 			}
 		}
-		mutex_unlock(&moxa_openlock);
 		break;
 	} case MOXA_GET_OQUEUE:
 		status = MoxaPortTxQueue(ch);
@@ -330,16 +343,20 @@ static int moxa_ioctl(struct tty_struct
 		struct moxa_port *p;
 		unsigned int i, j;
 
-		mutex_lock(&moxa_openlock);
 		for (i = 0; i < MAX_BOARDS; i++) {
 			p = moxa_boards[i].ports;
 			for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
 				struct tty_struct *ttyp;
 				memset(&tmp, 0, sizeof(tmp));
-				if (!moxa_boards[i].ready)
+				spin_lock_bh(&moxa_lock);
+				if (!moxa_boards[i].ready) {
+				        spin_unlock_bh(&moxa_lock);
 					goto copy;
+                                }
 
 				status = MoxaPortLineStatus(p);
+				spin_unlock_bh(&moxa_lock);
+
 				if (status & 1)
 					tmp.cts = 1;
 				if (status & 2)
@@ -354,24 +371,21 @@ static int moxa_ioctl(struct tty_struct
 					tmp.cflag = ttyp->termios->c_cflag;
 				tty_kref_put(tty);
 copy:
-				if (copy_to_user(argm, &tmp, sizeof(tmp))) {
-					mutex_unlock(&moxa_openlock);
+				if (copy_to_user(argm, &tmp, sizeof(tmp)))
 					return -EFAULT;
-				}
 			}
 		}
-		mutex_unlock(&moxa_openlock);
 		break;
 	}
 	case TIOCGSERIAL:
-		mutex_lock(&moxa_openlock);
+	        mutex_lock(&ch->port.mutex);
 		ret = moxa_get_serial_info(ch, argp);
-		mutex_unlock(&moxa_openlock);
+		mutex_unlock(&ch->port.mutex);
 		break;
 	case TIOCSSERIAL:
-		mutex_lock(&moxa_openlock);
+	        mutex_lock(&ch->port.mutex);
 		ret = moxa_set_serial_info(ch, argp);
-		mutex_unlock(&moxa_openlock);
+		mutex_unlock(&ch->port.mutex);
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -396,8 +410,6 @@ static const struct tty_operations moxa_
 	.flush_buffer = moxa_flush_buffer,
 	.chars_in_buffer = moxa_chars_in_buffer,
 	.ioctl = moxa_ioctl,
-	.throttle = moxa_throttle,
-	.unthrottle = moxa_unthrottle,
 	.set_termios = moxa_set_termios,
 	.stop = moxa_stop,
 	.start = moxa_start,
@@ -409,11 +421,12 @@ static const struct tty_operations moxa_
 
 static const struct tty_port_operations moxa_port_ops = {
 	.carrier_raised = moxa_carrier_raised,
+	.dtr_rts = moxa_dtr_rts,
+	.shutdown = moxa_shutdown,
 };
 
 static struct tty_driver *moxaDriver;
 static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
-static DEFINE_SPINLOCK(moxa_lock);
 
 /*
  * HW init
@@ -1112,14 +1125,12 @@ static void __exit moxa_exit(void)
 module_init(moxa_init);
 module_exit(moxa_exit);
 
-static void moxa_close_port(struct tty_struct *tty)
+static void moxa_shutdown(struct tty_port *port)
 {
-	struct moxa_port *ch = tty->driver_data;
-	moxa_shut_down(tty);
+	struct moxa_port *ch = container_of(port, struct moxa_port, port);
+        MoxaPortDisable(ch);
 	MoxaPortFlushData(ch, 2);
-	ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	tty->driver_data = NULL;
-	tty_port_tty_set(&ch->port, NULL);
+	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
 }
 
 static int moxa_carrier_raised(struct tty_port *port)
@@ -1127,45 +1138,19 @@ static int moxa_carrier_raised(struct tt
 	struct moxa_port *ch = container_of(port, struct moxa_port, port);
 	int dcd;
 
-	spin_lock_bh(&moxa_lock);
+	spin_lock_irq(&port->lock);
 	dcd = ch->DCDState;
-	spin_unlock_bh(&moxa_lock);
+	spin_unlock_irq(&port->lock);
 	return dcd;
 }
 
-static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
-			    struct moxa_port *ch)
+static void moxa_dtr_rts(struct tty_port *port, int onoff)
 {
-	struct tty_port *port = &ch->port;
-	DEFINE_WAIT(wait);
-	int retval = 0;
-	u8 dcd;
-
-	while (1) {
-		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp)) {
-#ifdef SERIAL_DO_RESTART
-			retval = -ERESTARTSYS;
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		dcd = tty_port_carrier_raised(port);
-		if (dcd)
-			break;
-
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-		schedule();
-	}
-	finish_wait(&port->open_wait, &wait);
-
-	return retval;
+	struct moxa_port *ch = container_of(port, struct moxa_port, port);
+	MoxaPortLineCtrl(ch, onoff, onoff);
 }
 
+
 static int moxa_open(struct tty_struct *tty, struct file *filp)
 {
 	struct moxa_board_conf *brd;
@@ -1194,6 +1179,7 @@ static int moxa_open(struct tty_struct *
 	ch->port.count++;
 	tty->driver_data = ch;
 	tty_port_tty_set(&ch->port, tty);
+	mutex_lock(&ch->port.mutex);
 	if (!(ch->port.flags & ASYNC_INITIALIZED)) {
 		ch->statusflags = 0;
 		moxa_set_tty_param(tty, tty->termios);
@@ -1202,58 +1188,20 @@ static int moxa_open(struct tty_struct *
 		MoxaSetFifo(ch, ch->type == PORT_16550A);
 		ch->port.flags |= ASYNC_INITIALIZED;
 	}
+	mutex_unlock(&ch->port.mutex);
 	mutex_unlock(&moxa_openlock);
 
-	retval = 0;
-	if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
-		retval = moxa_block_till_ready(tty, filp, ch);
-	mutex_lock(&moxa_openlock);
-	if (retval) {
-		if (ch->port.count) /* 0 means already hung up... */
-			if (--ch->port.count == 0)
-				moxa_close_port(tty);
-	} else
-		ch->port.flags |= ASYNC_NORMAL_ACTIVE;
-	mutex_unlock(&moxa_openlock);
-
+	retval = tty_port_block_til_ready(&ch->port, tty, filp);
+	if (retval == 0)
+	        set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
 	return retval;
 }
 
 static void moxa_close(struct tty_struct *tty, struct file *filp)
 {
-	struct moxa_port *ch;
-	int port;
-
-	port = tty->index;
-	if (port == MAX_PORTS || tty_hung_up_p(filp))
-		return;
-
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (ch == NULL)
-		goto unlock;
-	if (tty->count == 1 && ch->port.count != 1) {
-		printk(KERN_WARNING "moxa_close: bad serial port count; "
-			"tty->count is 1, ch->port.count is %d\n", ch->port.count);
-		ch->port.count = 1;
-	}
-	if (--ch->port.count < 0) {
-		printk(KERN_WARNING "moxa_close: bad serial port count, "
-			"device=%s\n", tty->name);
-		ch->port.count = 0;
-	}
-	if (ch->port.count)
-		goto unlock;
-
+	struct moxa_port *ch = tty->driver_data;
 	ch->cflag = tty->termios->c_cflag;
-	if (ch->port.flags & ASYNC_INITIALIZED) {
-		moxa_setup_empty_event(tty);
-		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
-	}
-
-	moxa_close_port(tty);
-unlock:
-	mutex_unlock(&moxa_openlock);
+	tty_port_close(&ch->port, tty, filp);
 }
 
 static int moxa_write(struct tty_struct *tty,
@@ -1269,7 +1217,7 @@ static int moxa_write(struct tty_struct
 	len = MoxaPortWriteData(tty, buf, count);
 	spin_unlock_bh(&moxa_lock);
 
-	ch->statusflags |= LOWWAIT;
+	set_bit(LOWWAIT, &ch->statusflags);
 	return len;
 }
 
@@ -1300,40 +1248,21 @@ static int moxa_chars_in_buffer(struct t
 	struct moxa_port *ch = tty->driver_data;
 	int chars;
 
-	/*
-	 * Sigh...I have to check if driver_data is NULL here, because
-	 * if an open() fails, the TTY subsystem eventually calls
-	 * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
-	 * routine.  And since the open() failed, we return 0 here.  TDJ
-	 */
-	if (ch == NULL)
-		return 0;
-	lock_kernel();
 	chars = MoxaPortTxQueue(ch);
-	if (chars) {
+	if (chars)
 		/*
 		 * Make it possible to wakeup anything waiting for output
 		 * in tty_ioctl.c, etc.
 		 */
-		if (!(ch->statusflags & EMPTYWAIT))
-			moxa_setup_empty_event(tty);
-	}
-	unlock_kernel();
+        	set_bit(EMPTYWAIT, &ch->statusflags);
 	return chars;
 }
 
 static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
 {
-	struct moxa_port *ch;
+	struct moxa_port *ch = tty->driver_data;
 	int flag = 0, dtr, rts;
 
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (!ch) {
-		mutex_unlock(&moxa_openlock);
-		return -EINVAL;
-	}
-
 	MoxaPortGetLineOut(ch, &dtr, &rts);
 	if (dtr)
 		flag |= TIOCM_DTR;
@@ -1346,7 +1275,6 @@ static int moxa_tiocmget(struct tty_stru
 		flag |= TIOCM_DSR;
 	if (dtr & 4)
 		flag |= TIOCM_CD;
-	mutex_unlock(&moxa_openlock);
 	return flag;
 }
 
@@ -1379,20 +1307,6 @@ static int moxa_tiocmset(struct tty_stru
 	return 0;
 }
 
-static void moxa_throttle(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	ch->statusflags |= THROTTLE;
-}
-
-static void moxa_unthrottle(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	ch->statusflags &= ~THROTTLE;
-}
-
 static void moxa_set_termios(struct tty_struct *tty,
 		struct ktermios *old_termios)
 {
@@ -1412,7 +1326,7 @@ static void moxa_stop(struct tty_struct
 	if (ch == NULL)
 		return;
 	MoxaPortTxDisable(ch);
-	ch->statusflags |= TXSTOPPED;
+	set_bit(TXSTOPPED, &ch->statusflags);
 }
 
 
@@ -1427,38 +1341,32 @@ static void moxa_start(struct tty_struct
 		return;
 
 	MoxaPortTxEnable(ch);
-	ch->statusflags &= ~TXSTOPPED;
+	clear_bit(TXSTOPPED, &ch->statusflags);
 }
 
 static void moxa_hangup(struct tty_struct *tty)
 {
-	struct moxa_port *ch;
-
-	mutex_lock(&moxa_openlock);
-	ch = tty->driver_data;
-	if (ch == NULL) {
-		mutex_unlock(&moxa_openlock);
-		return;
-	}
-	ch->port.count = 0;
-	moxa_close_port(tty);
-	mutex_unlock(&moxa_openlock);
-
-	wake_up_interruptible(&ch->port.open_wait);
+	struct moxa_port *ch = tty->driver_data;
+	tty_port_hangup(&ch->port);
 }
 
 static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
 {
 	struct tty_struct *tty;
+	unsigned long flags;
 	dcd = !!dcd;
 
+	spin_lock_irqsave(&p->port.lock, flags);
 	if (dcd != p->DCDState) {
+        	p->DCDState = dcd;
+        	spin_unlock_irqrestore(&p->port.lock, flags);
 		tty = tty_port_tty_get(&p->port);
 		if (tty && C_CLOCAL(tty) && !dcd)
 			tty_hangup(tty);
 		tty_kref_put(tty);
 	}
-	p->DCDState = dcd;
+	else
+		spin_unlock_irqrestore(&p->port.lock, flags);
 }
 
 static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
@@ -1470,24 +1378,24 @@ static int moxa_poll_port(struct moxa_po
 	u16 intr;
 
 	if (tty) {
-		if ((p->statusflags & EMPTYWAIT) &&
+		if (test_bit(EMPTYWAIT, &p->statusflags) &&
 				MoxaPortTxQueue(p) == 0) {
-			p->statusflags &= ~EMPTYWAIT;
+			clear_bit(EMPTYWAIT, &p->statusflags);
 			tty_wakeup(tty);
 		}
-		if ((p->statusflags & LOWWAIT) && !tty->stopped &&
+		if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
 				MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
-			p->statusflags &= ~LOWWAIT;
+			clear_bit(LOWWAIT, &p->statusflags);
 			tty_wakeup(tty);
 		}
 
-		if (inited && !(p->statusflags & THROTTLE) &&
+		if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
 				MoxaPortRxQueue(p) > 0) { /* RX */
 			MoxaPortReadData(p);
 			tty_schedule_flip(tty);
 		}
 	} else {
-		p->statusflags &= ~EMPTYWAIT;
+		clear_bit(EMPTYWAIT, &p->statusflags);
 		MoxaPortFlushData(p, 0); /* flush RX */
 	}
 
@@ -1588,35 +1496,6 @@ static void moxa_set_tty_param(struct tt
 	tty_encode_baud_rate(tty, baud, baud);
 }
 
-static void moxa_setup_empty_event(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	spin_lock_bh(&moxa_lock);
-	ch->statusflags |= EMPTYWAIT;
-	spin_unlock_bh(&moxa_lock);
-}
-
-static void moxa_shut_down(struct tty_struct *tty)
-{
-	struct moxa_port *ch = tty->driver_data;
-
-	if (!(ch->port.flags & ASYNC_INITIALIZED))
-		return;
-
-	MoxaPortDisable(ch);
-
-	/*
-	 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
-	 */
-	if (C_HUPCL(tty))
-		MoxaPortLineCtrl(ch, 0, 0);
-
-	spin_lock_bh(&moxa_lock);
-	ch->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_bh(&moxa_lock);
-}
-
 /*****************************************************************************
  *	Driver level functions: 					     *
  *****************************************************************************/
@@ -1918,10 +1797,12 @@ static int MoxaPortSetTermio(struct moxa
 	baud = MoxaPortSetBaud(port, baud);
 
 	if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
+	        spin_lock_irq(&moxafunc_lock);
 		writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
 		writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
 		writeb(FC_SetXonXoff, ofsAddr + FuncCode);
 		moxa_wait_finish(ofsAddr);
+		spin_unlock_irq(&moxafunc_lock);
 
 	}
 	return baud;
@@ -1974,18 +1855,14 @@ static int MoxaPortLineStatus(struct mox
 	int val;
 
 	ofsAddr = port->tableAddr;
-	if (MOXA_IS_320(port->board)) {
-		moxafunc(ofsAddr, FC_LineStatus, 0);
-		val = readw(ofsAddr + FuncArg);
-	} else {
+	if (MOXA_IS_320(port->board))
+		val = moxafuncret(ofsAddr, FC_LineStatus, 0);
+	else
 		val = readw(ofsAddr + FlagStat) >> 4;
-	}
 	val &= 0x0B;
 	if (val & 8)
 		val |= 4;
-	spin_lock_bh(&moxa_lock);
 	moxa_new_dcdstate(port, val & 8);
-	spin_unlock_bh(&moxa_lock);
 	val &= 7;
 	return val;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/mspec.c linux-libre-2.6.33-gnu1/drivers/char/mspec.c
--- linux-libre-2.6.32-gnu1/drivers/char/mspec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/mspec.c	2010-02-24 13:52:17.000000000 -0500
@@ -248,7 +248,7 @@ static const struct vm_operations_struct
 /*
  * mspec_mmap
  *
- * Called when mmaping the device.  Initializes the vma with a fault handler
+ * Called when mmapping the device.  Initializes the vma with a fault handler
  * and private data structure necessary to allocate, track, and free the
  * underlying pages.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/mxser.c linux-libre-2.6.33-gnu1/drivers/char/mxser.c
--- linux-libre-2.6.32-gnu1/drivers/char/mxser.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/mxser.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
@@ -856,9 +855,9 @@ static void mxser_check_modem_status(str
 	}
 }
 
-static int mxser_startup(struct tty_struct *tty)
+static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
 {
-	struct mxser_port *info = tty->driver_data;
+	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long page;
 	unsigned long flags;
 
@@ -868,22 +867,13 @@ static int mxser_startup(struct tty_stru
 
 	spin_lock_irqsave(&info->slock, flags);
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		free_page(page);
-		spin_unlock_irqrestore(&info->slock, flags);
-		return 0;
-	}
-
 	if (!info->ioaddr || !info->type) {
 		set_bit(TTY_IO_ERROR, &tty->flags);
 		free_page(page);
 		spin_unlock_irqrestore(&info->slock, flags);
 		return 0;
 	}
-	if (info->port.xmit_buf)
-		free_page(page);
-	else
-		info->port.xmit_buf = (unsigned char *) page;
+	info->port.xmit_buf = (unsigned char *) page;
 
 	/*
 	 * Clear the FIFO buffers and disable them
@@ -951,24 +941,19 @@ static int mxser_startup(struct tty_stru
 	 * and set the speed of the serial port
 	 */
 	mxser_change_speed(tty, NULL);
-	info->port.flags |= ASYNC_INITIALIZED;
 	spin_unlock_irqrestore(&info->slock, flags);
 
 	return 0;
 }
 
 /*
- * This routine will shutdown a serial port; interrupts maybe disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
+ * This routine will shutdown a serial port
  */
-static void mxser_shutdown(struct tty_struct *tty)
+static void mxser_shutdown_port(struct tty_port *port)
 {
-	struct mxser_port *info = tty->driver_data;
+	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long flags;
 
-	if (!(info->port.flags & ASYNC_INITIALIZED))
-		return;
-
 	spin_lock_irqsave(&info->slock, flags);
 
 	/*
@@ -978,7 +963,7 @@ static void mxser_shutdown(struct tty_st
 	wake_up_interruptible(&info->port.delta_msr_wait);
 
 	/*
-	 * Free the IRQ, if necessary
+	 * Free the xmit buffer, if necessary
 	 */
 	if (info->port.xmit_buf) {
 		free_page((unsigned long) info->port.xmit_buf);
@@ -988,10 +973,6 @@ static void mxser_shutdown(struct tty_st
 	info->IER = 0;
 	outb(0x00, info->ioaddr + UART_IER);
 
-	if (tty->termios->c_cflag & HUPCL)
-		info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
-	outb(info->MCR, info->ioaddr + UART_MCR);
-
 	/* clear Rx/Tx FIFO's */
 	if (info->board->chip_flag)
 		outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT |
@@ -1004,9 +985,6 @@ static void mxser_shutdown(struct tty_st
 	/* read data port to reset things */
 	(void) inb(info->ioaddr + UART_RX);
 
-	set_bit(TTY_IO_ERROR, &tty->flags);
-
-	info->port.flags &= ~ASYNC_INITIALIZED;
 
 	if (info->board->chip_flag)
 		SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
@@ -1023,8 +1001,7 @@ static void mxser_shutdown(struct tty_st
 static int mxser_open(struct tty_struct *tty, struct file *filp)
 {
 	struct mxser_port *info;
-	unsigned long flags;
-	int retval, line;
+	int line;
 
 	line = tty->index;
 	if (line == MXSER_PORTS)
@@ -1035,23 +1012,7 @@ static int mxser_open(struct tty_struct
 	if (!info->ioaddr)
 		return -ENODEV;
 
-	tty->driver_data = info;
-	tty_port_tty_set(&info->port, tty);
-	/*
-	 * Start up serial port
-	 */
-	spin_lock_irqsave(&info->port.lock, flags);
-	info->port.count++;
-	spin_unlock_irqrestore(&info->port.lock, flags);
-	retval = mxser_startup(tty);
-	if (retval)
-		return retval;
-
-	retval = tty_port_block_til_ready(&info->port, tty, filp);
-	if (retval)
-		return retval;
-
-	return 0;
+	return tty_port_open(&info->port, tty, filp);
 }
 
 static void mxser_flush_buffer(struct tty_struct *tty)
@@ -1075,19 +1036,11 @@ static void mxser_flush_buffer(struct tt
 }
 
 
-static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
+static void mxser_close_port(struct tty_port *port)
 {
 	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long timeout;
 	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 *
-	 * FIXME: Can this go ?
-	 */
-	if (port->flags & ASYNC_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
 	 * interrupt driver to stop checking the data ready bit in the
@@ -1097,22 +1050,18 @@ static void mxser_close_port(struct tty_
 	if (info->board->chip_flag)
 		info->IER &= ~MOXA_MUST_RECV_ISR;
 
-	if (port->flags & ASYNC_INITIALIZED) {
-		outb(info->IER, info->ioaddr + UART_IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		timeout = jiffies + HZ;
-		while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
-			schedule_timeout_interruptible(5);
-			if (time_after(jiffies, timeout))
-				break;
-		}
+	outb(info->IER, info->ioaddr + UART_IER);
+	/*
+	 * Before we drop DTR, make sure the UART transmitter
+	 * has completely drained; this is especially
+	 * important if there is a transmit FIFO!
+	 */
+	timeout = jiffies + HZ;
+	while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
+		schedule_timeout_interruptible(5);
+		if (time_after(jiffies, timeout))
+			break;
 	}
-	mxser_shutdown(tty);
-
 }
 
 /*
@@ -1130,8 +1079,12 @@ static void mxser_close(struct tty_struc
 		return;
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
-	mxser_close_port(tty, port);
+	mutex_lock(&port->mutex);
+	mxser_close_port(port);
 	mxser_flush_buffer(tty);
+	mxser_shutdown_port(port);
+	clear_bit(ASYNCB_INITIALIZED, &port->flags);
+	mutex_unlock(&port->mutex);
 	/* Right now the tty_port set is done outside of the close_end helper
 	   as we don't yet have everyone using refcounts */	
 	tty_port_close_end(port, tty);
@@ -1275,6 +1228,7 @@ static int mxser_set_serial_info(struct
 		struct serial_struct __user *new_info)
 {
 	struct mxser_port *info = tty->driver_data;
+	struct tty_port *port = &info->port;
 	struct serial_struct new_serial;
 	speed_t baud;
 	unsigned long sl_flags;
@@ -1290,7 +1244,7 @@ static int mxser_set_serial_info(struct
 			new_serial.port != info->ioaddr)
 		return -EINVAL;
 
-	flags = info->port.flags & ASYNC_SPD_MASK;
+	flags = port->flags & ASYNC_SPD_MASK;
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
@@ -1304,16 +1258,17 @@ static int mxser_set_serial_info(struct
 		 * OK, past this point, all the error checking has been done.
 		 * At this point, we start making changes.....
 		 */
-		info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
+		port->flags = ((port->flags & ~ASYNC_FLAGS) |
 				(new_serial.flags & ASYNC_FLAGS));
-		info->port.close_delay = new_serial.close_delay * HZ / 100;
-		info->port.closing_wait = new_serial.closing_wait * HZ / 100;
-		tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
-								? 1 : 0;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
+		port->close_delay = new_serial.close_delay * HZ / 100;
+		port->closing_wait = new_serial.closing_wait * HZ / 100;
+		tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
 				(new_serial.baud_base != info->baud_base ||
 				new_serial.custom_divisor !=
 				info->custom_divisor)) {
+			if (new_serial.custom_divisor == 0)
+				return -EINVAL;
 			baud = new_serial.baud_base / new_serial.custom_divisor;
 			tty_encode_baud_rate(tty, baud, baud);
 		}
@@ -1323,15 +1278,17 @@ static int mxser_set_serial_info(struct
 
 	process_txrx_fifo(info);
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
+	if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+		if (flags != (port->flags & ASYNC_SPD_MASK)) {
 			spin_lock_irqsave(&info->slock, sl_flags);
 			mxser_change_speed(tty, NULL);
 			spin_unlock_irqrestore(&info->slock, sl_flags);
 		}
-	} else
-		retval = mxser_startup(tty);
-
+	} else {
+		retval = mxser_activate(port, tty);
+		if (retval == 0)
+			set_bit(ASYNCB_INITIALIZED, &port->flags);
+	}
 	return retval;
 }
 
@@ -1520,7 +1477,8 @@ static int __init mxser_read_register(in
 
 static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
 {
-	struct mxser_port *port;
+	struct mxser_port *ip;
+	struct tty_port *port;
 	struct tty_struct *tty;
 	int result, status;
 	unsigned int i, j;
@@ -1536,38 +1494,39 @@ static int mxser_ioctl_special(unsigned
 
 	case MOXA_CHKPORTENABLE:
 		result = 0;
-		lock_kernel();
 		for (i = 0; i < MXSER_BOARDS; i++)
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
 				if (mxser_boards[i].ports[j].ioaddr)
 					result |= (1 << i);
-		unlock_kernel();
 		return put_user(result, (unsigned long __user *)argp);
 	case MOXA_GETDATACOUNT:
-		lock_kernel();
+		/* The receive side is locked by port->slock but it isn't
+		   clear that an exact snapshot is worth copying here */
 		if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
 			ret = -EFAULT;
-		unlock_kernel();
 		return ret;
 	case MOXA_GETMSTATUS: {
 		struct mxser_mstatus ms, __user *msu = argp;
-		lock_kernel();
 		for (i = 0; i < MXSER_BOARDS; i++)
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
-				port = &mxser_boards[i].ports[j];
+				ip = &mxser_boards[i].ports[j];
+				port = &ip->port;
 				memset(&ms, 0, sizeof(ms));
 
-				if (!port->ioaddr)
+				mutex_lock(&port->mutex);
+				if (!ip->ioaddr)
 					goto copy;
 				
-				tty = tty_port_tty_get(&port->port);
+				tty = tty_port_tty_get(port);
 
 				if (!tty || !tty->termios)
-					ms.cflag = port->normal_termios.c_cflag;
+					ms.cflag = ip->normal_termios.c_cflag;
 				else
 					ms.cflag = tty->termios->c_cflag;
 				tty_kref_put(tty);
-				status = inb(port->ioaddr + UART_MSR);
+				spin_lock_irq(&ip->slock);
+				status = inb(ip->ioaddr + UART_MSR);
+				spin_unlock_irq(&ip->slock);
 				if (status & UART_MSR_DCD)
 					ms.dcd = 1;
 				if (status & UART_MSR_DSR)
@@ -1575,13 +1534,11 @@ static int mxser_ioctl_special(unsigned
 				if (status & UART_MSR_CTS)
 					ms.cts = 1;
 			copy:
-				if (copy_to_user(msu, &ms, sizeof(ms))) {
-					unlock_kernel();
+				mutex_unlock(&port->mutex);
+				if (copy_to_user(msu, &ms, sizeof(ms)))
 					return -EFAULT;
-				}
 				msu++;
 			}
-		unlock_kernel();
 		return 0;
 	}
 	case MOXA_ASPP_MON_EXT: {
@@ -1593,41 +1550,48 @@ static int mxser_ioctl_special(unsigned
 		if (!me)
 			return -ENOMEM;
 
-		lock_kernel();
 		for (i = 0, p = 0; i < MXSER_BOARDS; i++) {
 			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) {
 				if (p >= ARRAY_SIZE(me->rx_cnt)) {
 					i = MXSER_BOARDS;
 					break;
 				}
-				port = &mxser_boards[i].ports[j];
-				if (!port->ioaddr)
+				ip = &mxser_boards[i].ports[j];
+				port = &ip->port;
+
+				mutex_lock(&port->mutex);
+				if (!ip->ioaddr) {
+					mutex_unlock(&port->mutex);
 					continue;
+				}
 
-				status = mxser_get_msr(port->ioaddr, 0, p);
+				spin_lock_irq(&ip->slock);
+				status = mxser_get_msr(ip->ioaddr, 0, p);
 
 				if (status & UART_MSR_TERI)
-					port->icount.rng++;
+					ip->icount.rng++;
 				if (status & UART_MSR_DDSR)
-					port->icount.dsr++;
+					ip->icount.dsr++;
 				if (status & UART_MSR_DDCD)
-					port->icount.dcd++;
+					ip->icount.dcd++;
 				if (status & UART_MSR_DCTS)
-					port->icount.cts++;
+					ip->icount.cts++;
 
-				port->mon_data.modem_status = status;
-				me->rx_cnt[p] = port->mon_data.rxcnt;
-				me->tx_cnt[p] = port->mon_data.txcnt;
-				me->up_rxcnt[p] = port->mon_data.up_rxcnt;
-				me->up_txcnt[p] = port->mon_data.up_txcnt;
+				ip->mon_data.modem_status = status;
+				me->rx_cnt[p] = ip->mon_data.rxcnt;
+				me->tx_cnt[p] = ip->mon_data.txcnt;
+				me->up_rxcnt[p] = ip->mon_data.up_rxcnt;
+				me->up_txcnt[p] = ip->mon_data.up_txcnt;
 				me->modem_status[p] =
-					port->mon_data.modem_status;
-				tty = tty_port_tty_get(&port->port);
+					ip->mon_data.modem_status;
+				spin_unlock_irq(&ip->slock);
+
+				tty = tty_port_tty_get(&ip->port);
 
 				if (!tty || !tty->termios) {
-					cflag = port->normal_termios.c_cflag;
-					iflag = port->normal_termios.c_iflag;
-					me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
+					cflag = ip->normal_termios.c_cflag;
+					iflag = ip->normal_termios.c_iflag;
+					me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios);
 				} else {
 					cflag = tty->termios->c_cflag;
 					iflag = tty->termios->c_iflag;
@@ -1646,16 +1610,15 @@ static int mxser_ioctl_special(unsigned
 				if (iflag & (IXON | IXOFF))
 					me->flowctrl[p] |= 0x0C;
 
-				if (port->type == PORT_16550A)
+				if (ip->type == PORT_16550A)
 					me->fifo[p] = 1;
 
-				opmode = inb(port->opmode_ioaddr) >>
-						((p % 4) * 2);
+				opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2);
 				opmode &= OP_MODE_MASK;
 				me->iftype[p] = opmode;
+				mutex_unlock(&port->mutex);
 			}
 		}
-		unlock_kernel();
 		if (copy_to_user(argp, me, sizeof(*me)))
 			ret = -EFAULT;
 		kfree(me);
@@ -1692,6 +1655,7 @@ static int mxser_ioctl(struct tty_struct
 		unsigned int cmd, unsigned long arg)
 {
 	struct mxser_port *info = tty->driver_data;
+	struct tty_port *port = &info->port;
 	struct async_icount cnow;
 	unsigned long flags;
 	void __user *argp = (void __user *)arg;
@@ -1716,20 +1680,20 @@ static int mxser_ioctl(struct tty_struct
 					opmode != RS422_MODE &&
 					opmode != RS485_4WIRE_MODE)
 				return -EFAULT;
-			lock_kernel();
 			mask = ModeMask[p];
 			shiftbit = p * 2;
+			spin_lock_irq(&info->slock);
 			val = inb(info->opmode_ioaddr);
 			val &= mask;
 			val |= (opmode << shiftbit);
 			outb(val, info->opmode_ioaddr);
-			unlock_kernel();
+			spin_unlock_irq(&info->slock);
 		} else {
-			lock_kernel();
 			shiftbit = p * 2;
+			spin_lock_irq(&info->slock);
 			opmode = inb(info->opmode_ioaddr) >> shiftbit;
+			spin_unlock_irq(&info->slock);
 			opmode &= OP_MODE_MASK;
-			unlock_kernel();
 			if (put_user(opmode, (int __user *)argp))
 				return -EFAULT;
 		}
@@ -1742,14 +1706,14 @@ static int mxser_ioctl(struct tty_struct
 
 	switch (cmd) {
 	case TIOCGSERIAL:
-		lock_kernel();
+		mutex_lock(&port->mutex);
 		retval = mxser_get_serial_info(tty, argp);
-		unlock_kernel();
+		mutex_unlock(&port->mutex);
 		return retval;
 	case TIOCSSERIAL:
-		lock_kernel();
+		mutex_lock(&port->mutex);
 		retval = mxser_set_serial_info(tty, argp);
-		unlock_kernel();
+		mutex_unlock(&port->mutex);
 		return retval;
 	case TIOCSERGETLSR:	/* Get line status register */
 		return  mxser_get_lsr_info(info, argp);
@@ -1795,31 +1759,33 @@ static int mxser_ioctl(struct tty_struct
 	case MOXA_HighSpeedOn:
 		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
 	case MOXA_SDS_RSTICOUNTER:
-		lock_kernel();
+		spin_lock_irq(&info->slock);
 		info->mon_data.rxcnt = 0;
 		info->mon_data.txcnt = 0;
-		unlock_kernel();
+		spin_unlock_irq(&info->slock);
 		return 0;
 
 	case MOXA_ASPP_OQUEUE:{
 		int len, lsr;
 
-		lock_kernel();
 		len = mxser_chars_in_buffer(tty);
+		spin_lock(&info->slock);
 		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
+		spin_unlock_irq(&info->slock);
 		len += (lsr ? 0 : 1);
-		unlock_kernel();
 
 		return put_user(len, (int __user *)argp);
 	}
 	case MOXA_ASPP_MON: {
 		int mcr, status;
 
-		lock_kernel();
+		spin_lock(&info->slock);
 		status = mxser_get_msr(info->ioaddr, 1, tty->index);
 		mxser_check_modem_status(tty, info, status);
 
 		mcr = inb(info->ioaddr + UART_MCR);
+		spin_unlock(&info->slock);
+
 		if (mcr & MOXA_MUST_MCR_XON_FLAG)
 			info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
 		else
@@ -1834,7 +1800,7 @@ static int mxser_ioctl(struct tty_struct
 			info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
 		else
 			info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
-		unlock_kernel();
+
 		if (copy_to_user(argp, &info->mon_data,
 				sizeof(struct mxser_mon)))
 			return -EFAULT;
@@ -1993,6 +1959,7 @@ static void mxser_wait_until_sent(struct
 {
 	struct mxser_port *info = tty->driver_data;
 	unsigned long orig_jiffies, char_time;
+	unsigned long flags;
 	int lsr;
 
 	if (info->type == PORT_UNKNOWN)
@@ -2032,19 +1999,21 @@ static void mxser_wait_until_sent(struct
 		timeout, char_time);
 	printk("jiff=%lu...", jiffies);
 #endif
-	lock_kernel();
+	spin_lock_irqsave(&info->slock, flags);
 	while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
 #endif
+		spin_unlock_irqrestore(&info->slock, flags);
 		schedule_timeout_interruptible(char_time);
+		spin_lock_irqsave(&info->slock, flags);
 		if (signal_pending(current))
 			break;
 		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
+	spin_unlock_irqrestore(&info->slock, flags);
 	set_current_state(TASK_RUNNING);
-	unlock_kernel();
 
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
@@ -2059,7 +2028,6 @@ static void mxser_hangup(struct tty_stru
 	struct mxser_port *info = tty->driver_data;
 
 	mxser_flush_buffer(tty);
-	mxser_shutdown(tty);
 	tty_port_hangup(&info->port);
 }
 
@@ -2363,6 +2331,8 @@ static const struct tty_operations mxser
 struct tty_port_operations mxser_port_ops = {
 	.carrier_raised = mxser_carrier_raised,
 	.dtr_rts = mxser_dtr_rts,
+	.activate = mxser_activate,
+	.shutdown = mxser_shutdown_port,
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/nozomi.c linux-libre-2.6.33-gnu1/drivers/char/nozomi.c
--- linux-libre-2.6.32-gnu1/drivers/char/nozomi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/nozomi.c	2010-02-24 13:52:17.000000000 -0500
@@ -358,7 +358,7 @@ struct port {
 	u8 update_flow_control;
 	struct ctrl_ul ctrl_ul;
 	struct ctrl_dl ctrl_dl;
-	struct kfifo *fifo_ul;
+	struct kfifo fifo_ul;
 	void __iomem *dl_addr[2];
 	u32 dl_size[2];
 	u8 toggle_dl;
@@ -685,8 +685,6 @@ static int nozomi_read_config_table(stru
 		dump_table(dc);
 
 		for (i = PORT_MDM; i < MAX_PORT; i++) {
-			dc->port[i].fifo_ul =
-			    kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
 			memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
 			memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
 		}
@@ -798,7 +796,7 @@ static int send_data(enum port_type inde
 	struct tty_struct *tty = tty_port_tty_get(&port->port);
 
 	/* Get data from tty and place in buf for now */
-	size = __kfifo_get(port->fifo_ul, dc->send_buf,
+	size = kfifo_out(&port->fifo_ul, dc->send_buf,
 			   ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
 
 	if (size == 0) {
@@ -988,11 +986,11 @@ static int receive_flow_control(struct n
 
 	} else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) {
 
-		if (__kfifo_len(dc->port[port].fifo_ul)) {
+		if (kfifo_len(&dc->port[port].fifo_ul)) {
 			DBG1("Enable interrupt (0x%04X) on port: %d",
 				enable_ier, port);
 			DBG1("Data in buffer [%d], enable transmit! ",
-				__kfifo_len(dc->port[port].fifo_ul));
+				kfifo_len(&dc->port[port].fifo_ul));
 			enable_transmit_ul(port, dc);
 		} else {
 			DBG1("No data in buffer...");
@@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(st
 		goto err_free_sbuf;
 	}
 
+	for (i = PORT_MDM; i < MAX_PORT; i++) {
+		if (kfifo_alloc(&dc->port[i].fifo_ul,
+		      FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
+			dev_err(&pdev->dev,
+					"Could not allocate kfifo buffer\n");
+			ret = -ENOMEM;
+			goto err_free_kfifo;
+		}
+	}
+
 	spin_lock_init(&dc->spin_mutex);
 
 	nozomi_setup_private_data(dc);
@@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(st
 			NOZOMI_NAME, dc);
 	if (unlikely(ret)) {
 		dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq);
-		goto err_free_sbuf;
+		goto err_free_kfifo;
 	}
 
 	DBG1("base_addr: %p", dc->base_addr);
@@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(st
 	dc->state = NOZOMI_STATE_ENABLED;
 
 	for (i = 0; i < MAX_PORT; i++) {
+		struct device *tty_dev;
+
 		mutex_init(&dc->port[i].tty_sem);
 		tty_port_init(&dc->port[i].port);
-		tty_register_device(ntty_driver, dc->index_start + i,
+		tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
 							&pdev->dev);
+
+		if (IS_ERR(tty_dev)) {
+			ret = PTR_ERR(tty_dev);
+			dev_err(&pdev->dev, "Could not allocate tty?\n");
+			goto err_free_tty;
+		}
 	}
+
 	return 0;
 
+err_free_tty:
+	for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
+		tty_unregister_device(ntty_driver, i);
+err_free_kfifo:
+	for (i = 0; i < MAX_PORT; i++)
+		kfifo_free(&dc->port[i].fifo_ul);
 err_free_sbuf:
 	kfree(dc->send_buf);
 	iounmap(dc->base_addr);
@@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(s
 	free_irq(pdev->irq, dc);
 
 	for (i = 0; i < MAX_PORT; i++)
-		if (dc->port[i].fifo_ul)
-			kfifo_free(dc->port[i].fifo_ul);
+		kfifo_free(&dc->port[i].fifo_ul);
 
 	kfree(dc->send_buf);
 
@@ -1629,10 +1651,10 @@ static void ntty_close(struct tty_struct
 
 	dc->open_ttys--;
 	port->count--;
-	tty_port_tty_set(port, NULL);
 
 	if (port->count == 0) {
 		DBG1("close: %d", nport->token_dl);
+		tty_port_tty_set(port, NULL);
 		spin_lock_irqsave(&dc->spin_mutex, flags);
 		dc->last_ier &= ~(nport->token_dl);
 		writew(dc->last_ier, dc->reg_ier);
@@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct
 		goto exit;
 	}
 
-	rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count);
+	rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
 
 	/* notify card */
 	if (unlikely(dc == NULL)) {
@@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_st
 	if (!port->port.count)
 		goto exit;
 
-	room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
+	room = port->fifo_ul.size - kfifo_len(&port->fifo_ul);
 
 exit:
 	mutex_unlock(&port->tty_sem);
@@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct t
 		goto exit_in_buffer;
 	}
 
-	rval = __kfifo_len(port->fifo_ul);
+	rval = kfifo_len(&port->fifo_ul);
 
 exit_in_buffer:
 	return rval;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/n_r3964.c linux-libre-2.6.33-gnu1/drivers/char/n_r3964.c
--- linux-libre-2.6.32-gnu1/drivers/char/n_r3964.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/n_r3964.c	2010-02-24 13:52:17.000000000 -0500
@@ -602,7 +602,7 @@ static void receive_char(struct r3964_in
 		}
 		break;
 	case R3964_WAIT_FOR_RX_REPEAT:
-		/* FALLTROUGH */
+		/* FALLTHROUGH */
 	case R3964_IDLE:
 		if (c == STX) {
 			/* Prevent rx_queue from overflow: */
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/nvram.c linux-libre-2.6.33-gnu1/drivers/char/nvram.c
--- linux-libre-2.6.32-gnu1/drivers/char/nvram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/nvram.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,6 @@
 #define NVRAM_VERSION	"1.3"
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/nvram.h>
 
 #define PC		1
@@ -111,6 +110,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 
@@ -214,7 +214,6 @@ void nvram_set_checksum(void)
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-	lock_kernel();
 	switch (origin) {
 	case 0:
 		/* nothing to do */
@@ -226,7 +225,7 @@ static loff_t nvram_llseek(struct file *
 		offset += NVRAM_BYTES;
 		break;
 	}
-	unlock_kernel();
+
 	return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
 }
 
@@ -265,10 +264,16 @@ static ssize_t nvram_write(struct file *
 	unsigned char contents[NVRAM_BYTES];
 	unsigned i = *ppos;
 	unsigned char *tmp;
-	int len;
 
-	len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count;
-	if (copy_from_user(contents, buf, len))
+	if (i >= NVRAM_BYTES)
+		return 0;	/* Past EOF */
+
+	if (count > NVRAM_BYTES - i)
+		count = NVRAM_BYTES - i;
+	if (count > NVRAM_BYTES)
+		return -EFAULT;	/* Can't happen, but prove it to gcc */
+
+	if (copy_from_user(contents, buf, count))
 		return -EFAULT;
 
 	spin_lock_irq(&rtc_lock);
@@ -276,7 +281,7 @@ static ssize_t nvram_write(struct file *
 	if (!__nvram_check_checksum())
 		goto checksum_err;
 
-	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
+	for (tmp = contents; count--; ++i, ++tmp)
 		__nvram_write_byte(*tmp, i);
 
 	__nvram_set_checksum();
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/nwflash.c linux-libre-2.6.33-gnu1/drivers/char/nwflash.c
--- linux-libre-2.6.32-gnu1/drivers/char/nwflash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/nwflash.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 #include <asm/hardware/dec21285.h>
 #include <asm/io.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pc8736x_gpio.c linux-libre-2.6.33-gnu1/drivers/char/pc8736x_gpio.c
--- linux-libre-2.6.32-gnu1/drivers/char/pc8736x_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pc8736x_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,6 @@
 #include <linux/mutex.h>
 #include <linux/nsc_gpio.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 #define DEVNAME "pc8736x_gpio"
@@ -223,7 +222,6 @@ static int pc8736x_gpio_open(struct inod
 	unsigned m = iminor(inode);
 	file->private_data = &pc8736x_gpio_ops;
 
-	cycle_kernel_lock();
 	dev_dbg(&pdev->dev, "open %d\n", m);
 
 	if (m >= PC8736X_GPIO_CT)
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/cm4000_cs.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4000_cs.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/cm4000_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4000_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,8 +23,6 @@
   * All rights reserved. Licensed under dual BSD/GPL license.
   */
 
-/* #define PCMCIA_DEBUG 6 */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -47,18 +45,17 @@
 
 /* #define ATR_CSUM */
 
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)	(&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { 				\
-	if (pc_debug >= (n))						\
-		dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, 	\
-			   __func__ , ## args);			\
+#define reader_to_dev(x)	(&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4000_DEBUG set */
+/* #define CM4000_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do { 		\
+		dev_dbg(reader_to_dev(rdr), "%s:" x, 	\
+			   __func__ , ## args);		\
 	} while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
+
 static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
 
 #define	T_1SEC		(HZ)
@@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14]
 /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
 };
 
-#ifndef PCMCIA_DEBUG
+#ifndef CM4000_DEBUG
 #define	xoutb	outb
 #define	xinb	inb
 #else
 static inline void xoutb(unsigned char val, unsigned short port)
 {
-	if (pc_debug >= 7)
-		printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+	pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
 	outb(val, port);
 }
 static inline unsigned char xinb(unsigned short port)
@@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigne
 	unsigned char val;
 
 	val = inb(port);
-	if (pc_debug >= 7)
-		printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+	pr_debug("%.2x=inb(%.4x)\n", val, port);
 
 	return val;
 }
@@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_de
 	for (i = 0; i < 4; i++) {
 		xoutb(i, REG_BUF_ADDR(iobase));
 		xoutb(dev->pts[i], REG_BUF_DATA(iobase));	/* buf data */
-#ifdef PCMCIA_DEBUG
-		if (pc_debug >= 5)
-			printk("0x%.2x ", dev->pts[i]);
+#ifdef CM4000_DEBUG
+		pr_debug("0x%.2x ", dev->pts[i]);
 	}
-	if (pc_debug >= 5)
-		printk("\n");
+	pr_debug("\n");
 #else
 	}
 #endif
@@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_de
 		pts_reply[i] = inb(REG_BUF_DATA(iobase));
 	}
 
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
 	DEBUGP(2, dev, "PTSreply: ");
 	for (i = 0; i < num_bytes_read; i++) {
-		if (pc_debug >= 5)
-			printk("0x%.2x ", pts_reply[i]);
+		pr_debug("0x%.2x ", pts_reply[i]);
 	}
-	printk("\n");
-#endif	/* PCMCIA_DEBUG */
+	pr_debug("\n");
+#endif	/* CM4000_DEBUG */
 
 	DEBUGP(5, dev, "Clear Tactive in Flags1\n");
 	xoutb(0x20, REG_FLAGS1(iobase));
@@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4
 
 	DEBUGP(5, dev, "Delete timer\n");
 	del_timer_sync(&dev->timer);
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
 	dev->monitor_running = 0;
 #endif
 
@@ -898,7 +890,7 @@ static void monitor_card(unsigned long p
 				DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
 				       "be zero) failed\n", dev->atr_csum);
 			}
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
 			else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
 				DEBUGP(4, dev, "ATR length error\n");
 			} else {
@@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp,
 	int size;
 	int rc;
 	void __user *argp = (void __user *)arg;
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
 	char *ioctl_names[CM_IOC_MAXNR + 1] = {
 		[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
 		[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
@@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp,
 		[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
 		[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
 	};
-#endif
 	DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
 	       iminor(inode), ioctl_names[_IOC_NR(cmd)]);
+#endif
 
 	lock_kernel();
 	rc = -ENODEV;
@@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp,
 		}
 	case CM_IOCARDOFF:
 
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
 		DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
 		if (dev->flags0 & 0x01) {
 			DEBUGP(4, dev, "    Card inserted\n");
@@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp,
 
 		}
 		break;
-#ifdef PCMCIA_DEBUG
-	case CM_IOSDBGLVL:	/* set debug log level */
-		{
-			int old_pc_debug = 0;
-
-			old_pc_debug = pc_debug;
-			if (copy_from_user(&pc_debug, argp, sizeof(int)))
-				rc = -EFAULT;
-			else if (old_pc_debug != pc_debug)
-				DEBUGP(0, dev, "Changed debug log level "
-				       "to %i\n", pc_debug);
-		}
+#ifdef CM4000_DEBUG
+	case CM_IOSDBGLVL:
+		rc = -ENOTTY;
 		break;
 #endif
 	default:
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/cm4040_cs.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4040_cs.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/cm4040_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/cm4040_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,6 @@
  * All rights reserved, Dual BSD/GPL Licensed.
  */
 
-/* #define PCMCIA_DEBUG 6 */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -41,18 +39,16 @@
 #include "cm4040_cs.h"
 
 
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)	(&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { 				\
-	if (pc_debug >= (n)) 						\
-		dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, 	\
-			   __func__ , ##args); 			\
+#define reader_to_dev(x)	(&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4040_DEBUG set */
+/* #define CM4040_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do { 		\
+		dev_dbg(reader_to_dev(rdr), "%s:" x, 	\
+			   __func__ , ## args);		\
 	} while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
 
 static char *version =
 "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
@@ -90,14 +86,13 @@ struct reader_dev {
 
 static struct pcmcia_device *dev_table[CM_MAX_DEV];
 
-#ifndef PCMCIA_DEBUG
+#ifndef CM4040_DEBUG
 #define	xoutb	outb
 #define	xinb	inb
 #else
 static inline void xoutb(unsigned char val, unsigned short port)
 {
-	if (pc_debug >= 7)
-		printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+	pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
 	outb(val, port);
 }
 
@@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigne
 	unsigned char val;
 
 	val = inb(port);
-	if (pc_debug >= 7)
-		printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+	pr_debug("%.2x=inb(%.4x)\n", val, port);
 	return val;
 }
 #endif
@@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *
 			return -EIO;
 		}
 	  	dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
-		if (pc_debug >= 6)
-			printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+		pr_debug("%lu:%2x ", i, dev->r_buf[i]);
 	}
-	printk("\n");
+	pr_debug("\n");
 #else
 	}
 #endif
 
 	bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
 
-	DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
+	DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read);
 
 	min_bytes_to_read = min(count, bytes_to_read + 5);
 	min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
 
-	DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
+	DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read);
 
 	for (i = 0; i < (min_bytes_to_read-5); i++) {
 		rc = wait_for_bulk_in_ready(dev);
@@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *
 			return -EIO;
 		}
 		dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
-		if (pc_debug >= 6)
-			printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+		pr_debug("%lu:%2x ", i, dev->r_buf[i]);
 	}
-	printk("\n");
+	pr_debug("\n");
 #else
 	}
 #endif
@@ -547,7 +539,7 @@ static int cm4040_config_check(struct pc
 	p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
 
 	rc = pcmcia_request_io(p_dev, &p_dev->io);
-	dev_printk(KERN_INFO, &handle_to_dev(p_dev),
+	dev_printk(KERN_INFO, &p_dev->dev,
 		   "pcmcia_request_io returned 0x%x\n", rc);
 	return rc;
 }
@@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_d
 
 	fail_rc = pcmcia_request_configuration(link, &link->conf);
 	if (fail_rc != 0) {
-		dev_printk(KERN_INFO, &handle_to_dev(link),
+		dev_printk(KERN_INFO, &link->dev,
 			   "pcmcia_request_configuration failed 0x%x\n",
 			   fail_rc);
 		goto cs_release;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/hardware.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/hardware.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/hardware.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/hardware.c	2010-02-24 13:52:17.000000000 -0500
@@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_
 
 irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
 {
-	struct ipw_hardware *hw = dev_id;
+	struct ipw_dev *ipw = dev_id;
 
-	if (hw->hw_version == HW_VERSION_1)
-		return ipwireless_handle_v1_interrupt(irq, hw);
+	if (ipw->hardware->hw_version == HW_VERSION_1)
+		return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
 	else
-		return ipwireless_handle_v2_v3_interrupt(irq, hw);
+		return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
 }
 
 static void flush_packets_to_hw(struct ipw_hardware *hw)
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/main.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/main.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,10 +65,7 @@ static void signalled_reboot_work(struct
 	struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
 			work_reboot);
 	struct pcmcia_device *link = ipw->link;
-	int ret = pcmcia_reset_card(link->socket);
-
-	if (ret != 0)
-		cs_error(link, ResetCard, ret);
+	pcmcia_reset_card(link->socket);
 }
 
 static void signalled_reboot_callback(void *callback_data)
@@ -79,208 +76,127 @@ static void signalled_reboot_callback(vo
 	schedule_work(&ipw->work_reboot);
 }
 
-static int config_ipwireless(struct ipw_dev *ipw)
+static int ipwireless_probe(struct pcmcia_device *p_dev,
+			    cistpl_cftable_entry_t *cfg,
+			    cistpl_cftable_entry_t *dflt,
+			    unsigned int vcc,
+			    void *priv_data)
 {
-	struct pcmcia_device *link = ipw->link;
-	int ret;
-	tuple_t tuple;
-	unsigned short buf[64];
-	cisparse_t parse;
-	unsigned short cor_value;
+	struct ipw_dev *ipw = priv_data;
+	struct resource *io_resource;
 	memreq_t memreq_attr_memory;
 	memreq_t memreq_common_memory;
+	int ret;
 
-	ipw->is_v2_card = 0;
-
-	tuple.Attributes = 0;
-	tuple.TupleData = (cisdata_t *) buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
-	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
-	ret = pcmcia_get_first_tuple(link, &tuple);
-
-	while (ret == 0) {
-		ret = pcmcia_get_tuple_data(link, &tuple);
-
-		if (ret != 0) {
-			cs_error(link, GetTupleData, ret);
-			goto exit0;
-		}
-		ret = pcmcia_get_next_tuple(link, &tuple);
-	}
-
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-	ret = pcmcia_get_first_tuple(link, &tuple);
-
-	if (ret != 0) {
-		cs_error(link, GetFirstTuple, ret);
-		goto exit0;
-	}
-
-	ret = pcmcia_get_tuple_data(link, &tuple);
-
-	if (ret != 0) {
-		cs_error(link, GetTupleData, ret);
-		goto exit0;
-	}
-
-	ret = pcmcia_parse_tuple(&tuple, &parse);
-
-	if (ret != 0) {
-		cs_error(link, ParseTuple, ret);
-		goto exit0;
-	}
-
-	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-	link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-	link->io.IOAddrLines = 16;
-
-	link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+	p_dev->io.IOAddrLines = 16;
 
 	/* 0x40 causes it to generate level mode interrupts. */
 	/* 0x04 enables IREQ pin. */
-	cor_value = parse.cftable_entry.index | 0x44;
-	link->conf.ConfigIndex = cor_value;
-
-	/* IRQ and I/O settings */
-	tuple.DesiredTuple = CISTPL_CONFIG;
+	p_dev->conf.ConfigIndex = cfg->index | 0x44;
+	ret = pcmcia_request_io(p_dev, &p_dev->io);
+	if (ret)
+		return ret;
 
-	ret = pcmcia_get_first_tuple(link, &tuple);
+	io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
+				IPWIRELESS_PCCARD_NAME);
 
-	if (ret != 0) {
-		cs_error(link, GetFirstTuple, ret);
-		goto exit0;
-	}
+	if (cfg->mem.nwin == 0)
+		return 0;
 
-	ret = pcmcia_get_tuple_data(link, &tuple);
+	ipw->request_common_memory.Attributes =
+		WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
+	ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
+	ipw->request_common_memory.Size = cfg->mem.win[0].len;
+	if (ipw->request_common_memory.Size < 0x1000)
+		ipw->request_common_memory.Size = 0x1000;
+	ipw->request_common_memory.AccessSpeed = 0;
 
-	if (ret != 0) {
-		cs_error(link, GetTupleData, ret);
-		goto exit0;
-	}
+	ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
+				&ipw->handle_common_memory);
 
-	ret = pcmcia_parse_tuple(&tuple, &parse);
+	if (ret != 0)
+		goto exit1;
 
-	if (ret != 0) {
-		cs_error(link, GetTupleData, ret);
-		goto exit0;
-	}
-	link->conf.Attributes = CONF_ENABLE_IRQ;
-	link->conf.ConfigBase = parse.config.base;
-	link->conf.Present = parse.config.rmask[0];
-	link->conf.IntType = INT_MEMORY_AND_IO;
+	memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
+	memreq_common_memory.Page = 0;
 
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.Handler = ipwireless_interrupt;
-	link->irq.Instance = ipw->hardware;
+	ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
+				&memreq_common_memory);
 
-	ret = pcmcia_request_io(link, &link->io);
+	if (ret != 0)
+		goto exit2;
 
-	if (ret != 0) {
-		cs_error(link, RequestIO, ret);
-		goto exit0;
-	}
+	ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
 
-	request_region(link->io.BasePort1, link->io.NumPorts1,
+	ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+				ipw->request_common_memory.Size);
+	request_mem_region(ipw->request_common_memory.Base,
+			ipw->request_common_memory.Size,
 			IPWIRELESS_PCCARD_NAME);
 
-	/* memory settings */
-
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-	ret = pcmcia_get_first_tuple(link, &tuple);
-
-	if (ret != 0) {
-		cs_error(link, GetFirstTuple, ret);
-		goto exit1;
-	}
-
-	ret = pcmcia_get_tuple_data(link, &tuple);
-
-	if (ret != 0) {
-		cs_error(link, GetTupleData, ret);
-		goto exit1;
-	}
-
-	ret = pcmcia_parse_tuple(&tuple, &parse);
-
-	if (ret != 0) {
-		cs_error(link, ParseTuple, ret);
-		goto exit1;
-	}
+	ipw->request_attr_memory.Attributes =
+		WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
+	ipw->request_attr_memory.Base = 0;
+	ipw->request_attr_memory.Size = 0;	/* this used to be 0x1000 */
+	ipw->request_attr_memory.AccessSpeed = 0;
 
-	if (parse.cftable_entry.mem.nwin > 0) {
-		ipw->request_common_memory.Attributes =
-			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
-		ipw->request_common_memory.Base =
-			parse.cftable_entry.mem.win[0].host_addr;
-		ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
-		if (ipw->request_common_memory.Size < 0x1000)
-			ipw->request_common_memory.Size = 0x1000;
-		ipw->request_common_memory.AccessSpeed = 0;
+	ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
+				&ipw->handle_attr_memory);
 
-		ret = pcmcia_request_window(&link, &ipw->request_common_memory,
-				&ipw->handle_common_memory);
+	if (ret != 0)
+		goto exit2;
 
-		if (ret != 0) {
-			cs_error(link, RequestWindow, ret);
-			goto exit1;
-		}
+	memreq_attr_memory.CardOffset = 0;
+	memreq_attr_memory.Page = 0;
 
-		memreq_common_memory.CardOffset =
-			parse.cftable_entry.mem.win[0].card_addr;
-		memreq_common_memory.Page = 0;
+	ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
+				&memreq_attr_memory);
 
-		ret = pcmcia_map_mem_page(ipw->handle_common_memory,
-				&memreq_common_memory);
+	if (ret != 0)
+		goto exit3;
 
-		if (ret != 0) {
-			cs_error(link, MapMemPage, ret);
-			goto exit1;
-		}
+	ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
+				ipw->request_attr_memory.Size);
+	request_mem_region(ipw->request_attr_memory.Base,
+			ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
 
-		ipw->is_v2_card =
-			parse.cftable_entry.mem.win[0].len == 0x100;
+	return 0;
 
-		ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+exit3:
+	pcmcia_release_window(p_dev, ipw->handle_attr_memory);
+exit2:
+	if (ipw->common_memory) {
+		release_mem_region(ipw->request_common_memory.Base,
 				ipw->request_common_memory.Size);
-		request_mem_region(ipw->request_common_memory.Base,
-				ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
-
-		ipw->request_attr_memory.Attributes =
-			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
-		ipw->request_attr_memory.Base = 0;
-		ipw->request_attr_memory.Size = 0;	/* this used to be 0x1000 */
-		ipw->request_attr_memory.AccessSpeed = 0;
-
-		ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
-				&ipw->handle_attr_memory);
+		iounmap(ipw->common_memory);
+		pcmcia_release_window(p_dev, ipw->handle_common_memory);
+	} else
+		pcmcia_release_window(p_dev, ipw->handle_common_memory);
+exit1:
+	release_resource(io_resource);
+	pcmcia_disable_device(p_dev);
+	return -1;
+}
 
-		if (ret != 0) {
-			cs_error(link, RequestWindow, ret);
-			goto exit2;
-		}
+static int config_ipwireless(struct ipw_dev *ipw)
+{
+	struct pcmcia_device *link = ipw->link;
+	int ret = 0;
 
-		memreq_attr_memory.CardOffset = 0;
-		memreq_attr_memory.Page = 0;
+	ipw->is_v2_card = 0;
 
-		ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
-				&memreq_attr_memory);
+	ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
+	if (ret != 0)
+		return ret;
 
-		if (ret != 0) {
-			cs_error(link, MapMemPage, ret);
-			goto exit2;
-		}
+	link->conf.Attributes = CONF_ENABLE_IRQ;
+	link->conf.IntType = INT_MEMORY_AND_IO;
 
-		ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
-				ipw->request_attr_memory.Size);
-		request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
-				IPWIRELESS_PCCARD_NAME);
-	}
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+	link->irq.Handler = ipwireless_interrupt;
 
 	INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
 
@@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_
 
 	ret = pcmcia_request_irq(link, &link->irq);
 
-	if (ret != 0) {
-		cs_error(link, RequestIRQ, ret);
-		goto exit3;
-	}
+	if (ret != 0)
+		goto exit;
 
 	printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
 			ipw->is_v2_card ? "V2/V3" : "V1");
@@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_
 
 	ipw->network = ipwireless_network_create(ipw->hardware);
 	if (!ipw->network)
-		goto exit3;
+		goto exit;
 
 	ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
 			ipw->nodes);
 	if (!ipw->tty)
-		goto exit3;
+		goto exit;
 
 	ipwireless_init_hardware_v2_v3(ipw->hardware);
 
@@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_
 	 */
 	ret = pcmcia_request_configuration(link, &link->conf);
 
-	if (ret != 0) {
-		cs_error(link, RequestConfiguration, ret);
-		goto exit4;
-	}
+	if (ret != 0)
+		goto exit;
 
 	link->dev_node = &ipw->nodes[0];
 
 	return 0;
 
-exit4:
-	pcmcia_disable_device(link);
-exit3:
+exit:
 	if (ipw->attr_memory) {
 		release_mem_region(ipw->request_attr_memory.Base,
 				ipw->request_attr_memory.Size);
 		iounmap(ipw->attr_memory);
-		pcmcia_release_window(ipw->handle_attr_memory);
-		pcmcia_disable_device(link);
+		pcmcia_release_window(link, ipw->handle_attr_memory);
 	}
-exit2:
 	if (ipw->common_memory) {
 		release_mem_region(ipw->request_common_memory.Base,
 				ipw->request_common_memory.Size);
 		iounmap(ipw->common_memory);
-		pcmcia_release_window(ipw->handle_common_memory);
+		pcmcia_release_window(link, ipw->handle_common_memory);
 	}
-exit1:
 	pcmcia_disable_device(link);
-exit0:
 	return -1;
 }
 
@@ -378,9 +284,9 @@ static void release_ipwireless(struct ip
 		iounmap(ipw->attr_memory);
 	}
 	if (ipw->common_memory)
-		pcmcia_release_window(ipw->handle_common_memory);
+		pcmcia_release_window(ipw->link, ipw->handle_common_memory);
 	if (ipw->attr_memory)
-		pcmcia_release_window(ipw->handle_attr_memory);
+		pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
 
 	/* Break the link with Card Services */
 	pcmcia_disable_device(ipw->link);
@@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmc
 
 	ipw->link = link;
 	link->priv = ipw;
-	link->irq.Instance = ipw;
 
 	/* Link this device into our device list. */
 	link->dev_node = &ipw->nodes[0];
@@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmc
 	ret = config_ipwireless(ipw);
 
 	if (ret != 0) {
-		cs_error(link, RegisterClient, ret);
 		ipwireless_detach(link);
 		return ret;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/tty.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/tty.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/ipwireless/tty.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/ipwireless/tty.c	2010-02-24 13:52:17.000000000 -0500
@@ -603,7 +603,7 @@ void ipwireless_tty_free(struct ipw_tty
 	}
 }
 
-static struct tty_operations tty_ops = {
+static const struct tty_operations tty_ops = {
 	.open = ipw_open,
 	.close = ipw_close,
 	.hangup = ipw_hangup,
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pcmcia/synclink_cs.c linux-libre-2.6.33-gnu1/drivers/char/pcmcia/synclink_cs.c
--- linux-libre-2.6.32-gnu1/drivers/char/pcmcia/synclink_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pcmcia/synclink_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_de
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1   = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
 
     link->conf.Attributes = 0;
@@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_de
 /* Card has been inserted.
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+			  cistpl_cftable_entry_t *cfg,
+			  cistpl_cftable_entry_t *dflt,
+			  unsigned int vcc,
+			  void *priv_data)
+{
+	if (cfg->io.nwin > 0) {
+		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+		if (!(cfg->io.flags & CISTPL_IO_8BIT))
+			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+		if (!(cfg->io.flags & CISTPL_IO_16BIT))
+			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+		p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+		p_dev->io.BasePort1 = cfg->io.win[0].base;
+		p_dev->io.NumPorts1 = cfg->io.win[0].len;
+		return pcmcia_request_io(p_dev, &p_dev->io);
+	}
+	return -ENODEV;
+}
 
 static int mgslpc_config(struct pcmcia_device *link)
 {
     MGSLPC_INFO *info = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int last_fn, last_ret;
-    u_char buf[64];
-    cistpl_cftable_entry_t dflt = { 0 };
-    cistpl_cftable_entry_t *cfg;
+    int ret;
 
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_config(0x%p)\n", link);
 
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-
-    /* get CIS configuration entry */
-
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
-    cfg = &(parse.cftable_entry);
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
-    if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-    if (cfg->index == 0)
-	    goto cs_failed;
-
-    link->conf.ConfigIndex = cfg->index;
-    link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-    /* IO window settings */
-    link->io.NumPorts1 = 0;
-    if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-	    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-	    if (!(io->flags & CISTPL_IO_8BIT))
-		    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-	    if (!(io->flags & CISTPL_IO_16BIT))
-		    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-	    link->io.BasePort1 = io->win[0].base;
-	    link->io.NumPorts1 = io->win[0].len;
-	    CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-    }
+    ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+    if (ret != 0)
+	    goto failed;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 8;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Attributes |= IRQ_HANDLE_PRESENT;
     link->irq.Handler     = mgslpc_isr;
-    link->irq.Instance    = info;
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     info->io_base = link->io.BasePort1;
     info->irq_level = link->irq.AssignedIRQ;
@@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_d
     printk("\n");
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
+failed:
     mgslpc_release((u_long)link);
     return -ENODEV;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/pty.c linux-libre-2.6.33-gnu1/drivers/char/pty.c
--- linux-libre-2.6.32-gnu1/drivers/char/pty.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/pty.c	2010-02-24 13:52:17.000000000 -0500
@@ -431,30 +431,25 @@ static struct cdev ptmx_cdev;
 
 static struct ctl_table pty_table[] = {
 	{
-		.ctl_name	= PTY_MAX,
 		.procname	= "max",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.data		= &pty_limit,
-		.proc_handler	= &proc_dointvec_minmax,
-		.strategy	= &sysctl_intvec,
+		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= &pty_limit_min,
 		.extra2		= &pty_limit_max,
 	}, {
-		.ctl_name	= PTY_NR,
 		.procname	= "nr",
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
 		.data		= &pty_count,
-		.proc_handler	= &proc_dointvec,
-	}, {
-		.ctl_name	= 0
-	}
+		.proc_handler	= proc_dointvec,
+	}, 
+	{}
 };
 
 static struct ctl_table pty_kern_table[] = {
 	{
-		.ctl_name	= KERN_PTY,
 		.procname	= "pty",
 		.mode		= 0555,
 		.child		= pty_table,
@@ -464,7 +459,6 @@ static struct ctl_table pty_kern_table[]
 
 static struct ctl_table pty_root_table[] = {
 	{
-		.ctl_name	= CTL_KERN,
 		.procname	= "kernel",
 		.mode		= 0555,
 		.child		= pty_kern_table,
@@ -665,7 +659,7 @@ static int __ptmx_open(struct inode *ino
 	if (!retval)
 		return 0;
 out1:
-	tty_release_dev(filp);
+	tty_release(inode, filp);
 	return retval;
 out:
 	devpts_kill_index(inode, index);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/random.c linux-libre-2.6.33-gnu1/drivers/char/random.c
--- linux-libre-2.6.32-gnu1/drivers/char/random.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/random.c	2010-02-24 13:52:17.000000000 -0500
@@ -1051,12 +1051,6 @@ random_read(struct file *file, char __us
 				/* like a named pipe */
 	}
 
-	/*
-	 * If we gave the user some bytes, update the access time.
-	 */
-	if (count)
-		file_accessed(file);
-
 	return (count ? count : retval);
 }
 
@@ -1107,7 +1101,6 @@ static ssize_t random_write(struct file
 			    size_t count, loff_t *ppos)
 {
 	size_t ret;
-	struct inode *inode = file->f_path.dentry->d_inode;
 
 	ret = write_pool(&blocking_pool, buffer, count);
 	if (ret)
@@ -1116,8 +1109,6 @@ static ssize_t random_write(struct file
 	if (ret)
 		return ret;
 
-	inode->i_mtime = current_fs_time(inode->i_sb);
-	mark_inode_dirty(inode);
 	return (ssize_t)count;
 }
 
@@ -1245,112 +1236,68 @@ static int proc_do_uuid(ctl_table *table
 	if (uuid[8] == 0)
 		generate_random_uuid(uuid);
 
-	sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
-		"%02x%02x%02x%02x%02x%02x",
-		uuid[0],  uuid[1],  uuid[2],  uuid[3],
-		uuid[4],  uuid[5],  uuid[6],  uuid[7],
-		uuid[8],  uuid[9],  uuid[10], uuid[11],
-		uuid[12], uuid[13], uuid[14], uuid[15]);
+	sprintf(buf, "%pU", uuid);
+
 	fake_table.data = buf;
 	fake_table.maxlen = sizeof(buf);
 
 	return proc_dostring(&fake_table, write, buffer, lenp, ppos);
 }
 
-static int uuid_strategy(ctl_table *table,
-			 void __user *oldval, size_t __user *oldlenp,
-			 void __user *newval, size_t newlen)
-{
-	unsigned char tmp_uuid[16], *uuid;
-	unsigned int len;
-
-	if (!oldval || !oldlenp)
-		return 1;
-
-	uuid = table->data;
-	if (!uuid) {
-		uuid = tmp_uuid;
-		uuid[8] = 0;
-	}
-	if (uuid[8] == 0)
-		generate_random_uuid(uuid);
-
-	if (get_user(len, oldlenp))
-		return -EFAULT;
-	if (len) {
-		if (len > 16)
-			len = 16;
-		if (copy_to_user(oldval, uuid, len) ||
-		    put_user(len, oldlenp))
-			return -EFAULT;
-	}
-	return 1;
-}
-
 static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
 ctl_table random_table[] = {
 	{
-		.ctl_name 	= RANDOM_POOLSIZE,
 		.procname	= "poolsize",
 		.data		= &sysctl_poolsize,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= RANDOM_ENTROPY_COUNT,
 		.procname	= "entropy_avail",
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 		.data		= &input_pool.entropy_count,
 	},
 	{
-		.ctl_name	= RANDOM_READ_THRESH,
 		.procname	= "read_wakeup_threshold",
 		.data		= &random_read_wakeup_thresh,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_minmax,
-		.strategy	= &sysctl_intvec,
+		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= &min_read_thresh,
 		.extra2		= &max_read_thresh,
 	},
 	{
-		.ctl_name	= RANDOM_WRITE_THRESH,
 		.procname	= "write_wakeup_threshold",
 		.data		= &random_write_wakeup_thresh,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_minmax,
-		.strategy	= &sysctl_intvec,
+		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= &min_write_thresh,
 		.extra2		= &max_write_thresh,
 	},
 	{
-		.ctl_name	= RANDOM_BOOT_ID,
 		.procname	= "boot_id",
 		.data		= &sysctl_bootid,
 		.maxlen		= 16,
 		.mode		= 0444,
-		.proc_handler	= &proc_do_uuid,
-		.strategy	= &uuid_strategy,
+		.proc_handler	= proc_do_uuid,
 	},
 	{
-		.ctl_name	= RANDOM_UUID,
 		.procname	= "uuid",
 		.maxlen		= 16,
 		.mode		= 0444,
-		.proc_handler	= &proc_do_uuid,
-		.strategy	= &uuid_strategy,
+		.proc_handler	= proc_do_uuid,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 #endif 	/* CONFIG_SYSCTL */
 
 /********************************************************************
  *
- * Random funtions for networking
+ * Random functions for networking
  *
  ********************************************************************/
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/rio/route.h linux-libre-2.6.33-gnu1/drivers/char/rio/route.h
--- linux-libre-2.6.32-gnu1/drivers/char/rio/route.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/rio/route.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,7 @@
 typedef struct COST_ROUTE COST_ROUTE;
 struct COST_ROUTE {
 	unsigned char cost;	/* Cost down this link */
-	unsigned char route[NODE_BYTES];	/* Nodes thorough this route */
+	unsigned char route[NODE_BYTES];	/* Nodes through this route */
 };
 
 typedef struct ROUTE_STR ROUTE_STR;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/riscom8.c linux-libre-2.6.33-gnu1/drivers/char/riscom8.c
--- linux-libre-2.6.32-gnu1/drivers/char/riscom8.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/riscom8.c	2010-02-24 13:52:17.000000000 -0500
@@ -793,26 +793,21 @@ static void rc_change_speed(struct tty_s
 }
 
 /* Must be called with interrupts enabled */
-static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
-						struct riscom_port *port)
+static int rc_activate_port(struct tty_port *port, struct tty_struct *tty)
 {
+	struct riscom_port *rp = container_of(port, struct riscom_port, port);
+	struct riscom_board *bp = port_Board(rp);
 	unsigned long flags;
 
-	if (port->port.flags & ASYNC_INITIALIZED)
-		return 0;
-
-	if (tty_port_alloc_xmit_buf(&port->port) < 0)
+	if (tty_port_alloc_xmit_buf(port) < 0)
 		return -ENOMEM;
 
 	spin_lock_irqsave(&riscom_lock, flags);
 
 	clear_bit(TTY_IO_ERROR, &tty->flags);
-	if (port->port.count == 1)
-		bp->count++;
-	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	rc_change_speed(tty, bp, port);
-	port->port.flags |= ASYNC_INITIALIZED;
-
+	bp->count++;
+	rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0;
+	rc_change_speed(tty, bp, rp);
 	spin_unlock_irqrestore(&riscom_lock, flags);
 	return 0;
 }
@@ -821,9 +816,6 @@ static int rc_setup_port(struct tty_stru
 static void rc_shutdown_port(struct tty_struct *tty,
 			struct riscom_board *bp, struct riscom_port *port)
 {
-	if (!(port->port.flags & ASYNC_INITIALIZED))
-		return;
-
 #ifdef RC_REPORT_OVERRUN
 	printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
 	       board_No(bp), port_No(port), port->overrun);
@@ -840,11 +832,6 @@ static void rc_shutdown_port(struct tty_
 	}
 #endif
 	tty_port_free_xmit_buf(&port->port);
-	if (C_HUPCL(tty)) {
-		/* Drop DTR */
-		bp->DTR |= (1u << port_No(port));
-		rc_out(bp, RC_DTR, bp->DTR);
-	}
 
 	/* Select port */
 	rc_out(bp, CD180_CAR, port_No(port));
@@ -856,7 +843,6 @@ static void rc_shutdown_port(struct tty_
 	rc_out(bp, CD180_IER, port->IER);
 
 	set_bit(TTY_IO_ERROR, &tty->flags);
-	port->port.flags &= ~ASYNC_INITIALIZED;
 
 	if (--bp->count < 0)  {
 		printk(KERN_INFO "rc%d: rc_shutdown_port: "
@@ -889,6 +875,20 @@ static int carrier_raised(struct tty_por
 	return CD;
 }
 
+static void dtr_rts(struct tty_port *port, int onoff)
+{
+	struct riscom_port *p = container_of(port, struct riscom_port, port);
+	struct riscom_board *bp = port_Board(p);
+	unsigned long flags;
+
+	spin_lock_irqsave(&riscom_lock, flags);
+	bp->DTR &= ~(1u << port_No(p));
+	if (onoff == 0)
+		bp->DTR |= (1u << port_No(p));
+	rc_out(bp, RC_DTR, bp->DTR);
+	spin_unlock_irqrestore(&riscom_lock, flags);
+}
+
 static int rc_open(struct tty_struct *tty, struct file *filp)
 {
 	int board;
@@ -909,14 +909,7 @@ static int rc_open(struct tty_struct *tt
 	if (error)
 		return error;
 
-	port->port.count++;
-	tty->driver_data = port;
-	tty_port_tty_set(&port->port, tty);
-
-	error = rc_setup_port(tty, bp, port);
-	if (error == 0)
-		error = tty_port_block_til_ready(&port->port, tty, filp);
-	return error;
+	return tty_port_open(&port->port, tty, filp);
 }
 
 static void rc_flush_buffer(struct tty_struct *tty)
@@ -950,24 +943,23 @@ static void rc_close_port(struct tty_por
 
 	spin_lock_irqsave(&riscom_lock, flags);
 	rp->IER &= ~IER_RXD;
-	if (port->flags & ASYNC_INITIALIZED) {
-		rp->IER &= ~IER_TXRDY;
-		rp->IER |= IER_TXEMPTY;
-		rc_out(bp, CD180_CAR, port_No(rp));
-		rc_out(bp, CD180_IER, rp->IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		timeout = jiffies + HZ;
-		while (rp->IER & IER_TXEMPTY) {
-			spin_unlock_irqrestore(&riscom_lock, flags);
-			msleep_interruptible(jiffies_to_msecs(rp->timeout));
-			spin_lock_irqsave(&riscom_lock, flags);
-			if (time_after(jiffies, timeout))
-				break;
-		}
+
+	rp->IER &= ~IER_TXRDY;
+	rp->IER |= IER_TXEMPTY;
+	rc_out(bp, CD180_CAR, port_No(rp));
+	rc_out(bp, CD180_IER, rp->IER);
+	/*
+	 * Before we drop DTR, make sure the UART transmitter
+	 * has completely drained; this is especially
+	 * important if there is a transmit FIFO!
+	 */
+	timeout = jiffies + HZ;
+	while (rp->IER & IER_TXEMPTY) {
+		spin_unlock_irqrestore(&riscom_lock, flags);
+		msleep_interruptible(jiffies_to_msecs(rp->timeout));
+		spin_lock_irqsave(&riscom_lock, flags);
+		if (time_after(jiffies, timeout))
+			break;
 	}
 	rc_shutdown_port(port->tty, bp, rp);
 	spin_unlock_irqrestore(&riscom_lock, flags);
@@ -1354,7 +1346,6 @@ static void rc_hangup(struct tty_struct
 	if (rc_paranoia_check(port, tty->name, "rc_hangup"))
 		return;
 
-	rc_shutdown_port(tty, port_Board(port), port);
 	tty_port_hangup(&port->port);
 }
 
@@ -1401,7 +1392,9 @@ static const struct tty_operations risco
 
 static const struct tty_port_operations riscom_port_ops = {
 	.carrier_raised = carrier_raised,
+	.dtr_rts = dtr_rts,
 	.shutdown = rc_close_port,
+	.activate = rc_activate_port,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/rtc.c linux-libre-2.6.33-gnu1/drivers/char/rtc.c
--- linux-libre-2.6.32-gnu1/drivers/char/rtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/rtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -282,34 +282,31 @@ static irqreturn_t rtc_interrupt(int irq
  */
 static ctl_table rtc_table[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "max-user-freq",
 		.data		= &rtc_max_user_freq,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table rtc_root[] = {
 	{
-		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "rtc",
 		.mode		= 0555,
 		.child		= rtc_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table dev_root[] = {
 	{
-		.ctl_name	= CTL_DEV,
 		.procname	= "dev",
 		.mode		= 0555,
 		.child		= rtc_root,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static struct ctl_table_header *sysctl_header;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/scx200_gpio.c linux-libre-2.6.33-gnu1/drivers/char/scx200_gpio.c
--- linux-libre-2.6.32-gnu1/drivers/char/scx200_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/scx200_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -52,7 +51,6 @@ static int scx200_gpio_open(struct inode
 	unsigned m = iminor(inode);
 	file->private_data = &scx200_gpio_ops;
 
-	cycle_kernel_lock();
 	if (m >= MAX_PINS)
 		return -EINVAL;
 	return nonseekable_open(inode, file);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/sonypi.c linux-libre-2.6.33-gnu1/drivers/char/sonypi.c
--- linux-libre-2.6.32-gnu1/drivers/char/sonypi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/sonypi.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,6 @@
 #include <linux/err.h>
 #include <linux/kfifo.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -487,7 +486,7 @@ static struct sonypi_device {
 	int camera_power;
 	int bluetooth_power;
 	struct mutex lock;
-	struct kfifo *fifo;
+	struct kfifo fifo;
 	spinlock_t fifo_lock;
 	wait_queue_head_t fifo_proc_list;
 	struct fasync_struct *fifo_async;
@@ -496,7 +495,7 @@ static struct sonypi_device {
 	struct input_dev *input_jog_dev;
 	struct input_dev *input_key_dev;
 	struct work_struct input_work;
-	struct kfifo *input_fifo;
+	struct kfifo input_fifo;
 	spinlock_t input_fifo_lock;
 } sonypi_device;
 
@@ -777,8 +776,9 @@ static void input_keyrelease(struct work
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+			 sizeof(kp), &sonypi_device.input_fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -827,8 +827,9 @@ static void sonypi_report_input_event(u8
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put(sonypi_device.input_fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_in_locked(&sonypi_device.input_fifo,
+			(unsigned char *)&kp, sizeof(kp),
+			&sonypi_device.input_fifo_lock);
 		schedule_work(&sonypi_device.input_work);
 	}
 }
@@ -880,7 +881,8 @@ found:
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_device.fifo_lock);
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -902,14 +904,13 @@ static int sonypi_misc_release(struct in
 
 static int sonypi_misc_open(struct inode *inode, struct file *file)
 {
-	lock_kernel();
 	mutex_lock(&sonypi_device.lock);
 	/* Flush input queue on first open */
 	if (!sonypi_device.open_count)
-		kfifo_reset(sonypi_device.fifo);
+		kfifo_reset(&sonypi_device.fifo);
 	sonypi_device.open_count++;
 	mutex_unlock(&sonypi_device.lock);
-	unlock_kernel();
+
 	return 0;
 }
 
@@ -919,17 +920,18 @@ static ssize_t sonypi_misc_read(struct f
 	ssize_t ret;
 	unsigned char c;
 
-	if ((kfifo_len(sonypi_device.fifo) == 0) &&
+	if ((kfifo_len(&sonypi_device.fifo) == 0) &&
 	    (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
-				       kfifo_len(sonypi_device.fifo) != 0);
+				       kfifo_len(&sonypi_device.fifo) != 0);
 	if (ret)
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
+				 &sonypi_device.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -946,15 +948,15 @@ static ssize_t sonypi_misc_read(struct f
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &sonypi_device.fifo_proc_list, wait);
-	if (kfifo_len(sonypi_device.fifo))
+	if (kfifo_len(&sonypi_device.fifo))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
 
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
+static long sonypi_misc_ioctl(struct file *fp,
 			     unsigned int cmd, unsigned long arg)
 {
-	int ret = 0;
+	long ret = 0;
 	void __user *argp = (void __user *)arg;
 	u8 val8;
 	u16 val16;
@@ -1070,7 +1072,8 @@ static const struct file_operations sony
 	.open		= sonypi_misc_open,
 	.release	= sonypi_misc_release,
 	.fasync		= sonypi_misc_fasync,
-	.ioctl		= sonypi_misc_ioctl,
+	.unlocked_ioctl	= sonypi_misc_ioctl,
+	.llseek		= no_llseek,
 };
 
 static struct miscdevice sonypi_misc_device = {
@@ -1313,11 +1316,10 @@ static int __devinit sonypi_probe(struct
 			"http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
 
 	spin_lock_init(&sonypi_device.fifo_lock);
-	sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-					 &sonypi_device.fifo_lock);
-	if (IS_ERR(sonypi_device.fifo)) {
+	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
+	if (error) {
 		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-		return PTR_ERR(sonypi_device.fifo);
+		return error;
 	}
 
 	init_waitqueue_head(&sonypi_device.fifo_proc_list);
@@ -1393,12 +1395,10 @@ static int __devinit sonypi_probe(struct
 		}
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
-		sonypi_device.input_fifo =
-			kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-				    &sonypi_device.input_fifo_lock);
-		if (IS_ERR(sonypi_device.input_fifo)) {
+		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
+				GFP_KERNEL);
+		if (error) {
 			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-			error = PTR_ERR(sonypi_device.input_fifo);
 			goto err_inpdev_unregister;
 		}
 
@@ -1423,7 +1423,7 @@ static int __devinit sonypi_probe(struct
 		pci_disable_device(pcidev);
  err_put_pcidev:
 	pci_dev_put(pcidev);
-	kfifo_free(sonypi_device.fifo);
+	kfifo_free(&sonypi_device.fifo);
 
 	return error;
 }
@@ -1438,7 +1438,7 @@ static int __devexit sonypi_remove(struc
 	if (useinput) {
 		input_unregister_device(sonypi_device.input_key_dev);
 		input_unregister_device(sonypi_device.input_jog_dev);
-		kfifo_free(sonypi_device.input_fifo);
+		kfifo_free(&sonypi_device.input_fifo);
 	}
 
 	misc_deregister(&sonypi_misc_device);
@@ -1451,7 +1451,7 @@ static int __devexit sonypi_remove(struc
 		pci_dev_put(sonypi_device.dev);
 	}
 
-	kfifo_free(sonypi_device.fifo);
+	kfifo_free(&sonypi_device.fifo);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/stallion.c linux-libre-2.6.33-gnu1/drivers/char/stallion.c
--- linux-libre-2.6.32-gnu1/drivers/char/stallion.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/stallion.c	2010-02-24 13:52:17.000000000 -0500
@@ -407,7 +407,7 @@ static unsigned int	stl_baudrates[] = {
  *	Declare all those functions in this driver!
  */
 
-static int	stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long	stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 static int	stl_brdinit(struct stlbrd *brdp);
 static int	stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
 static int	stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
@@ -607,7 +607,7 @@ static unsigned int	sc26198_baudtable[]
  */
 static const struct file_operations	stl_fsiomem = {
 	.owner		= THIS_MODULE,
-	.ioctl		= stl_memioctl,
+	.unlocked_ioctl	= stl_memioctl,
 };
 
 static struct class *stallion_class;
@@ -702,6 +702,24 @@ static struct stlbrd *stl_allocbrd(void)
 
 /*****************************************************************************/
 
+static int stl_activate(struct tty_port *port, struct tty_struct *tty)
+{
+	struct stlport *portp = container_of(port, struct stlport, port);
+	if (!portp->tx.buf) {
+		portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
+		if (!portp->tx.buf)
+			return -ENOMEM;
+		portp->tx.head = portp->tx.buf;
+		portp->tx.tail = portp->tx.buf;
+	}
+	stl_setport(portp, tty->termios);
+	portp->sigs = stl_getsignals(portp);
+	stl_setsignals(portp, 1, 1);
+	stl_enablerxtx(portp, 1, 1);
+	stl_startrxtx(portp, 1, 0);
+	return 0;
+}
+
 static int stl_open(struct tty_struct *tty, struct file *filp)
 {
 	struct stlport	*portp;
@@ -737,32 +755,8 @@ static int stl_open(struct tty_struct *t
 	if (portp == NULL)
 		return -ENODEV;
 	port = &portp->port;
+	return tty_port_open(&portp->port, tty, filp);
 
-/*
- *	On the first open of the device setup the port hardware, and
- *	initialize the per port data structure.
- */
-	tty_port_tty_set(port, tty);
-	tty->driver_data = portp;
-	port->count++;
-
-	if ((port->flags & ASYNC_INITIALIZED) == 0) {
-		if (!portp->tx.buf) {
-			portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
-			if (!portp->tx.buf)
-				return -ENOMEM;
-			portp->tx.head = portp->tx.buf;
-			portp->tx.tail = portp->tx.buf;
-		}
-		stl_setport(portp, tty->termios);
-		portp->sigs = stl_getsignals(portp);
-		stl_setsignals(portp, 1, 1);
-		stl_enablerxtx(portp, 1, 1);
-		stl_startrxtx(portp, 1, 0);
-		clear_bit(TTY_IO_ERROR, &tty->flags);
-		port->flags |= ASYNC_INITIALIZED;
-	}
-	return tty_port_block_til_ready(port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -826,38 +820,12 @@ static void stl_waituntilsent(struct tty
 
 /*****************************************************************************/
 
-static void stl_close(struct tty_struct *tty, struct file *filp)
+static void stl_shutdown(struct tty_port *port)
 {
-	struct stlport	*portp;
-	struct tty_port *port;
-	unsigned long	flags;
-
-	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
-
-	portp = tty->driver_data;
-	BUG_ON(portp == NULL);
-
-	port = &portp->port;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-/*
- *	May want to wait for any data to drain before closing. The BUSY
- *	flag keeps track of whether we are still sending or not - it is
- *	very accurate for the cd1400, not quite so for the sc26198.
- *	(The sc26198 has no "end-of-data" interrupt only empty FIFO)
- */
-	stl_waituntilsent(tty, (HZ / 2));
-
-	spin_lock_irqsave(&port->lock, flags);
-	portp->port.flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
+	struct stlport *portp = container_of(port, struct stlport, port);
 	stl_disableintrs(portp);
-	if (tty->termios->c_cflag & HUPCL)
-		stl_setsignals(portp, 0, 0);
 	stl_enablerxtx(portp, 0, 0);
-	stl_flushbuffer(tty);
+	stl_flush(portp);
 	portp->istate = 0;
 	if (portp->tx.buf != NULL) {
 		kfree(portp->tx.buf);
@@ -865,9 +833,16 @@ static void stl_close(struct tty_struct
 		portp->tx.head = NULL;
 		portp->tx.tail = NULL;
 	}
+}
 
-	tty_port_close_end(port, tty);
-	tty_port_tty_set(port, NULL);
+static void stl_close(struct tty_struct *tty, struct file *filp)
+{
+	struct stlport*portp;
+	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
+
+	portp = tty->driver_data;
+	BUG_ON(portp == NULL);
+	tty_port_close(&portp->port, tty, filp);
 }
 
 /*****************************************************************************/
@@ -1314,35 +1289,12 @@ static void stl_stop(struct tty_struct *
 
 static void stl_hangup(struct tty_struct *tty)
 {
-	struct stlport	*portp;
-	struct tty_port *port;
-	unsigned long flags;
-
+	struct stlport	*portp = tty->driver_data;
 	pr_debug("stl_hangup(tty=%p)\n", tty);
 
-	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	port = &portp->port;
-
-	spin_lock_irqsave(&port->lock, flags);
-	port->flags &= ~ASYNC_INITIALIZED;
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	stl_disableintrs(portp);
-	if (tty->termios->c_cflag & HUPCL)
-		stl_setsignals(portp, 0, 0);
-	stl_enablerxtx(portp, 0, 0);
-	stl_flushbuffer(tty);
-	portp->istate = 0;
-	set_bit(TTY_IO_ERROR, &tty->flags);
-	if (portp->tx.buf != NULL) {
-		kfree(portp->tx.buf);
-		portp->tx.buf = NULL;
-		portp->tx.head = NULL;
-		portp->tx.tail = NULL;
-	}
-	tty_port_hangup(port);
+	tty_port_hangup(&portp->port);
 }
 
 /*****************************************************************************/
@@ -2486,18 +2438,19 @@ static int stl_getbrdstruct(struct stlbr
  *	collection.
  */
 
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	int	brdnr, rc;
 	void __user *argp = (void __user *)arg;
 
-	pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg);
+	pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg);
 
-	brdnr = iminor(ip);
+	brdnr = iminor(fp->f_dentry->d_inode);
 	if (brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	rc = 0;
 
+	lock_kernel();
 	switch (cmd) {
 	case COM_GETPORTSTATS:
 		rc = stl_getportstats(NULL, NULL, argp);
@@ -2518,7 +2471,7 @@ static int stl_memioctl(struct inode *ip
 		rc = -ENOIOCTLCMD;
 		break;
 	}
-
+	unlock_kernel();
 	return rc;
 }
 
@@ -2549,6 +2502,8 @@ static const struct tty_operations stl_o
 static const struct tty_port_operations stl_port_ops = {
 	.carrier_raised = stl_carrier_raised,
 	.dtr_rts = stl_dtr_rts,
+	.activate = stl_activate,
+	.shutdown = stl_shutdown,
 };
 
 /*****************************************************************************/
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/sysrq.c linux-libre-2.6.33-gnu1/drivers/char/sysrq.c
--- linux-libre-2.6.32-gnu1/drivers/char/sysrq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/sysrq.c	2010-02-24 13:52:17.000000000 -0500
@@ -339,7 +339,7 @@ static struct sysrq_key_op sysrq_term_op
 
 static void moom_callback(struct work_struct *ignored)
 {
-	out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0);
+	out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL);
 }
 
 static DECLARE_WORK(moom_work, moom_callback);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tb0219.c linux-libre-2.6.33-gnu1/drivers/char/tb0219.c
--- linux-libre-2.6.32-gnu1/drivers/char/tb0219.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tb0219.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 
 #include <asm/io.h>
 #include <asm/reboot.h>
@@ -38,7 +37,7 @@ MODULE_PARM_DESC(major, "Major device nu
 
 static void (*old_machine_restart)(char *command);
 static void __iomem *tb0219_base;
-static spinlock_t tb0219_lock;
+static DEFINE_SPINLOCK(tb0219_lock);
 
 #define tb0219_read(offset)		readw(tb0219_base + (offset))
 #define tb0219_write(offset, value)	writew((value), tb0219_base + (offset))
@@ -237,7 +236,6 @@ static int tanbac_tb0219_open(struct ino
 {
 	unsigned int minor;
 
-	cycle_kernel_lock();
 	minor = iminor(inode);
 	switch (minor) {
 	case 0:
@@ -306,8 +304,6 @@ static int __devinit tb0219_probe(struct
 		return retval;
 	}
 
-	spin_lock_init(&tb0219_lock);
-
 	old_machine_restart = _machine_restart;
 	_machine_restart = tb0219_restart;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/toshiba.c linux-libre-2.6.33-gnu1/drivers/char/toshiba.c
--- linux-libre-2.6.32-gnu1/drivers/char/toshiba.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/toshiba.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,7 +68,7 @@
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-
+#include <linux/smp_lock.h>
 #include <linux/toshiba.h>
 
 #define TOSH_MINOR_DEV 181
@@ -88,13 +88,13 @@ static int tosh_date;
 static int tosh_sci;
 static int tosh_fan;
 
-static int tosh_ioctl(struct inode *, struct file *, unsigned int,
+static long tosh_ioctl(struct file *, unsigned int,
 	unsigned long);
 
 
 static const struct file_operations tosh_fops = {
 	.owner		= THIS_MODULE,
-	.ioctl		= tosh_ioctl,
+	.unlocked_ioctl	= tosh_ioctl,
 };
 
 static struct miscdevice tosh_device = {
@@ -252,8 +252,7 @@ int tosh_smm(SMMRegisters *regs)
 EXPORT_SYMBOL(tosh_smm);
 
 
-static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-	unsigned long arg)
+static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	SMMRegisters regs;
 	SMMRegisters __user *argp = (SMMRegisters __user *)arg;
@@ -275,13 +274,16 @@ static int tosh_ioctl(struct inode *ip,
 				return -EINVAL;
 
 			/* do we need to emulate the fan ? */
+			lock_kernel();
 			if (tosh_fan==1) {
 				if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) {
 					err = tosh_emulate_fan(&regs);
+					unlock_kernel();
 					break;
 				}
 			}
 			err = tosh_smm(&regs);
+			unlock_kernel();
 			break;
 		default:
 			return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm.c linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm.c
--- linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 
 enum tpm_const {
 	TPM_MINOR = 224,	/* officially assigned */
-	TPM_BUFSIZE = 2048,
+	TPM_BUFSIZE = 4096,
 	TPM_NUM_DEVICES = 256,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm_infineon.c linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_infineon.c
--- linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm_infineon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_infineon.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,12 +39,12 @@
 struct tpm_inf_dev {
 	int iotype;
 
-	void __iomem *mem_base;		/* MMIO ioremap'd addr */
-	unsigned long map_base;		/* phys MMIO base */
-	unsigned long map_size;		/* MMIO region size */
-	unsigned int index_off;		/* index register offset */
+	void __iomem *mem_base;	/* MMIO ioremap'd addr */
+	unsigned long map_base;	/* phys MMIO base */
+	unsigned long map_size;	/* MMIO region size */
+	unsigned int index_off;	/* index register offset */
 
-	unsigned int data_regs;		/* Data registers */
+	unsigned int data_regs;	/* Data registers */
 	unsigned int data_size;
 
 	unsigned int config_port;	/* IO Port config index reg */
@@ -406,14 +406,14 @@ static const struct tpm_vendor_specific
 	.miscdev = {.fops = &inf_ops,},
 };
 
-static const struct pnp_device_id tpm_pnp_tbl[] = {
+static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
 	/* Infineon TPMs */
 	{"IFX0101", 0},
 	{"IFX0102", 0},
 	{"", 0}
 };
 
-MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
 
 static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
 				       const struct pnp_device_id *dev_id)
@@ -430,7 +430,7 @@ static int __devinit tpm_inf_pnp_probe(s
 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
 	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
 
-	    	tpm_dev.iotype = TPM_INF_IO_PORT;
+		tpm_dev.iotype = TPM_INF_IO_PORT;
 
 		tpm_dev.config_port = pnp_port_start(dev, 0);
 		tpm_dev.config_size = pnp_port_len(dev, 0);
@@ -459,9 +459,9 @@ static int __devinit tpm_inf_pnp_probe(s
 			goto err_last;
 		}
 	} else if (pnp_mem_valid(dev, 0) &&
-	           !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
+		   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
 
-	    	tpm_dev.iotype = TPM_INF_IO_MEM;
+		tpm_dev.iotype = TPM_INF_IO_MEM;
 
 		tpm_dev.map_base = pnp_mem_start(dev, 0);
 		tpm_dev.map_size = pnp_mem_len(dev, 0);
@@ -563,11 +563,11 @@ static int __devinit tpm_inf_pnp_probe(s
 			 "product id 0x%02x%02x"
 			 "%s\n",
 			 tpm_dev.iotype == TPM_INF_IO_PORT ?
-				tpm_dev.config_port :
-				tpm_dev.map_base + tpm_dev.index_off,
+			 tpm_dev.config_port :
+			 tpm_dev.map_base + tpm_dev.index_off,
 			 tpm_dev.iotype == TPM_INF_IO_PORT ?
-				tpm_dev.data_regs :
-				tpm_dev.map_base + tpm_dev.data_regs,
+			 tpm_dev.data_regs :
+			 tpm_dev.map_base + tpm_dev.data_regs,
 			 version[0], version[1],
 			 vendorid[0], vendorid[1],
 			 productid[0], productid[1], chipname);
@@ -607,20 +607,55 @@ static __devexit void tpm_inf_pnp_remove
 			iounmap(tpm_dev.mem_base);
 			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
 		}
+		tpm_dev_vendor_release(chip);
 		tpm_remove_hardware(chip->dev);
 	}
 }
 
+static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
+{
+	struct tpm_chip *chip = pnp_get_drvdata(dev);
+	int rc;
+	if (chip) {
+		u8 savestate[] = {
+			0, 193,	/* TPM_TAG_RQU_COMMAND */
+			0, 0, 0, 10,	/* blob length (in bytes) */
+			0, 0, 0, 152	/* TPM_ORD_SaveState */
+		};
+		dev_info(&dev->dev, "saving TPM state\n");
+		rc = tpm_inf_send(chip, savestate, sizeof(savestate));
+		if (rc < 0) {
+			dev_err(&dev->dev, "error while saving TPM state\n");
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static int tpm_inf_pnp_resume(struct pnp_dev *dev)
+{
+	/* Re-configure TPM after suspending */
+	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+	tpm_config_out(IOLIMH, TPM_INF_ADDR);
+	tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
+	tpm_config_out(IOLIML, TPM_INF_ADDR);
+	tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
+	/* activate register */
+	tpm_config_out(TPM_DAR, TPM_INF_ADDR);
+	tpm_config_out(0x01, TPM_INF_DATA);
+	tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+	/* disable RESET, LP and IRQC */
+	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
+	return tpm_pm_resume(&dev->dev);
+}
+
 static struct pnp_driver tpm_inf_pnp_driver = {
 	.name = "tpm_inf_pnp",
-	.driver = {
-		.owner = THIS_MODULE,
-		.suspend = tpm_pm_suspend,
-		.resume = tpm_pm_resume,
-	},
-	.id_table = tpm_pnp_tbl,
+	.id_table = tpm_inf_pnp_tbl,
 	.probe = tpm_inf_pnp_probe,
-	.remove = __devexit_p(tpm_inf_pnp_remove),
+	.suspend = tpm_inf_pnp_suspend,
+	.resume = tpm_inf_pnp_resume,
+	.remove = __devexit_p(tpm_inf_pnp_remove)
 };
 
 static int __init init_inf(void)
@@ -638,5 +673,5 @@ module_exit(cleanup_inf);
 
 MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>");
 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.9");
+MODULE_VERSION("1.9.2");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm_tis.c linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_tis.c
--- linux-libre-2.6.32-gnu1/drivers/char/tpm/tpm_tis.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tpm/tpm_tis.c	2010-02-24 13:52:17.000000000 -0500
@@ -257,6 +257,10 @@ out:
 	return size;
 }
 
+static int itpm;
+module_param(itpm, bool, 0444);
+MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
+
 /*
  * If interrupts are used (signaled by an irq set in the vendor structure)
  * tpm.c can skip polling for the data to be available as the interrupt is
@@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip
 		wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 			      &chip->vendor.int_queue);
 		status = tpm_tis_status(chip);
-		if ((status & TPM_STS_DATA_EXPECT) == 0) {
+		if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
 			rc = -EIO;
 			goto out_err;
 		}
@@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *d
 		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
+	if (itpm)
+		dev_info(dev, "Intel iTPM workaround enabled\n");
+
+
 	/* Figure out the capabilities */
 	intfcaps =
 	    ioread32(chip->vendor.iobase +
@@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[
 	{"", 0},		/* User Specified */
 	{"", 0}			/* Terminator */
 };
+MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
 
 static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tty_io.c linux-libre-2.6.33-gnu1/drivers/char/tty_io.c
--- linux-libre-2.6.32-gnu1/drivers/char/tty_io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tty_io.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,7 +142,6 @@ ssize_t redirected_tty_write(struct file
 							size_t, loff_t *);
 static unsigned int tty_poll(struct file *, poll_table *);
 static int tty_open(struct inode *, struct file *);
-static int tty_release(struct inode *, struct file *);
 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 #ifdef CONFIG_COMPAT
 static long tty_compat_ioctl(struct file *file, unsigned int cmd,
@@ -506,8 +505,6 @@ static void do_tty_hangup(struct work_st
 	if (!tty)
 		return;
 
-	/* inuse_filps is protected by the single kernel lock */
-	lock_kernel();
 
 	spin_lock(&redirect_lock);
 	if (redirect && redirect->private_data == tty) {
@@ -516,7 +513,10 @@ static void do_tty_hangup(struct work_st
 	}
 	spin_unlock(&redirect_lock);
 
+	/* inuse_filps is protected by the single kernel lock */
+	lock_kernel();
 	check_tty_count(tty, "do_tty_hangup");
+
 	file_list_lock();
 	/* This breaks for file handles being sent over AF_UNIX sockets ? */
 	list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
@@ -708,6 +708,8 @@ void disassociate_ctty(int on_exit)
 	struct tty_struct *tty;
 	struct pid *tty_pgrp = NULL;
 
+	if (!current->signal->leader)
+		return;
 
 	tty = get_current_tty();
 	if (tty) {
@@ -773,8 +775,7 @@ void no_tty(void)
 {
 	struct task_struct *tsk = current;
 	lock_kernel();
-	if (tsk->signal->leader)
-		disassociate_ctty(0);
+	disassociate_ctty(0);
 	unlock_kernel();
 	proc_clear_tty(tsk);
 }
@@ -1017,14 +1018,16 @@ out:
 
 void tty_write_message(struct tty_struct *tty, char *msg)
 {
-	lock_kernel();
 	if (tty) {
 		mutex_lock(&tty->atomic_write_lock);
-		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
+		lock_kernel();
+		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
+			unlock_kernel();
 			tty->ops->write(tty, msg, strlen(msg));
+		} else
+			unlock_kernel();
 		tty_write_unlock(tty);
 	}
-	unlock_kernel();
 	return;
 }
 
@@ -1202,14 +1205,21 @@ static int tty_driver_install_tty(struct
 						struct tty_struct *tty)
 {
 	int idx = tty->index;
+	int ret;
 
-	if (driver->ops->install)
-		return driver->ops->install(driver, tty);
+	if (driver->ops->install) {
+		lock_kernel();
+		ret = driver->ops->install(driver, tty);
+		unlock_kernel();
+		return ret;
+	}
 
 	if (tty_init_termios(tty) == 0) {
+		lock_kernel();
 		tty_driver_kref_get(driver);
 		tty->count++;
 		driver->ttys[idx] = tty;
+		unlock_kernel();
 		return 0;
 	}
 	return -ENOMEM;
@@ -1302,10 +1312,14 @@ struct tty_struct *tty_init_dev(struct t
 	struct tty_struct *tty;
 	int retval;
 
+	lock_kernel();
 	/* Check if pty master is being opened multiple times */
 	if (driver->subtype == PTY_TYPE_MASTER &&
-		(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
+		(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
+		unlock_kernel();
 		return ERR_PTR(-EIO);
+	}
+	unlock_kernel();
 
 	/*
 	 * First time open is complex, especially for PTY devices.
@@ -1335,7 +1349,6 @@ struct tty_struct *tty_init_dev(struct t
 	 * If we fail here just call release_tty to clean up.  No need
 	 * to decrement the use counts, as release_tty doesn't care.
 	 */
-
 	retval = tty_ldisc_setup(tty, tty->link);
 	if (retval)
 		goto release_mem_out;
@@ -1350,7 +1363,9 @@ release_mem_out:
 	if (printk_ratelimit())
 		printk(KERN_INFO "tty_init_dev: ldisc open failed, "
 				 "clearing slot %d\n", idx);
+	lock_kernel();
 	release_tty(tty, idx);
+	unlock_kernel();
 	return ERR_PTR(retval);
 }
 
@@ -1464,7 +1479,17 @@ static void release_tty(struct tty_struc
 	tty_kref_put(tty);
 }
 
-/*
+/**
+ *	tty_release		-	vfs callback for close
+ *	@inode: inode of tty
+ *	@filp: file pointer for handle to tty
+ *
+ *	Called the last time each file handle is closed that references
+ *	this tty. There may however be several such references.
+ *
+ *	Locking:
+ *		Takes bkl. See tty_release_dev
+ *
  * Even releasing the tty structures is a tricky business.. We have
  * to be very careful that the structures are all released at the
  * same time, as interrupts might otherwise get the wrong pointers.
@@ -1472,20 +1497,20 @@ static void release_tty(struct tty_struc
  * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
  * lead to double frees or releasing memory still in use.
  */
-void tty_release_dev(struct file *filp)
+
+int tty_release(struct inode *inode, struct file *filp)
 {
 	struct tty_struct *tty, *o_tty;
 	int	pty_master, tty_closing, o_tty_closing, do_sleep;
 	int	devpts;
 	int	idx;
 	char	buf[64];
-	struct 	inode *inode;
 
-	inode = filp->f_path.dentry->d_inode;
 	tty = (struct tty_struct *)filp->private_data;
 	if (tty_paranoia_check(tty, inode, "tty_release_dev"))
-		return;
+		return 0;
 
+	lock_kernel();
 	check_tty_count(tty, "tty_release_dev");
 
 	tty_fasync(-1, filp, 0);
@@ -1500,19 +1525,22 @@ void tty_release_dev(struct file *filp)
 	if (idx < 0 || idx >= tty->driver->num) {
 		printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
 				  "free (%s)\n", tty->name);
-		return;
+		unlock_kernel();
+		return 0;
 	}
 	if (!devpts) {
 		if (tty != tty->driver->ttys[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
 			       "for (%s)\n", idx, tty->name);
-			return;
+			return 0;
 		}
 		if (tty->termios != tty->driver->termios[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
 			       "for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0;
 		}
 	}
 #endif
@@ -1526,26 +1554,30 @@ void tty_release_dev(struct file *filp)
 	if (tty->driver->other &&
 	     !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
 		if (o_tty != tty->driver->other->ttys[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
 					  "not o_tty for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0 ;
 		}
 		if (o_tty->termios != tty->driver->other->termios[idx]) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
 					  "not o_termios for (%s)\n",
 			       idx, tty->name);
-			return;
+			return 0;
 		}
 		if (o_tty->link != tty) {
+			unlock_kernel();
 			printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
-			return;
+			return 0;
 		}
 	}
 #endif
 	if (tty->ops->close)
 		tty->ops->close(tty, filp);
 
+	unlock_kernel();
 	/*
 	 * Sanity check: if tty->count is going to zero, there shouldn't be
 	 * any waiters on tty->read_wait or tty->write_wait.  We test the
@@ -1568,6 +1600,7 @@ void tty_release_dev(struct file *filp)
 		   opens on /dev/tty */
 
 		mutex_lock(&tty_mutex);
+		lock_kernel();
 		tty_closing = tty->count <= 1;
 		o_tty_closing = o_tty &&
 			(o_tty->count <= (pty_master ? 1 : 0));
@@ -1598,6 +1631,7 @@ void tty_release_dev(struct file *filp)
 
 		printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
 				    "active!\n", tty_name(tty, buf));
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		schedule();
 	}
@@ -1661,8 +1695,10 @@ void tty_release_dev(struct file *filp)
 	mutex_unlock(&tty_mutex);
 
 	/* check whether both sides are closing ... */
-	if (!tty_closing || (o_tty && !o_tty_closing))
-		return;
+	if (!tty_closing || (o_tty && !o_tty_closing)) {
+		unlock_kernel();
+		return 0;
+	}
 
 #ifdef TTY_DEBUG_HANGUP
 	printk(KERN_DEBUG "freeing tty structure...");
@@ -1680,10 +1716,12 @@ void tty_release_dev(struct file *filp)
 	/* Make this pty number available for reallocation */
 	if (devpts)
 		devpts_kill_index(inode, idx);
+	unlock_kernel();
+	return 0;
 }
 
 /**
- *	__tty_open		-	open a tty device
+ *	tty_open		-	open a tty device
  *	@inode: inode of device file
  *	@filp: file pointer to tty
  *
@@ -1703,7 +1741,7 @@ void tty_release_dev(struct file *filp)
  *		 ->siglock protects ->signal/->sighand
  */
 
-static int __tty_open(struct inode *inode, struct file *filp)
+static int tty_open(struct inode *inode, struct file *filp)
 {
 	struct tty_struct *tty = NULL;
 	int noctty, retval;
@@ -1720,10 +1758,12 @@ retry_open:
 	retval = 0;
 
 	mutex_lock(&tty_mutex);
+	lock_kernel();
 
 	if (device == MKDEV(TTYAUX_MAJOR, 0)) {
 		tty = get_current_tty();
 		if (!tty) {
+			unlock_kernel();
 			mutex_unlock(&tty_mutex);
 			return -ENXIO;
 		}
@@ -1755,12 +1795,14 @@ retry_open:
 				goto got_driver;
 			}
 		}
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		return -ENODEV;
 	}
 
 	driver = get_tty_driver(device, &index);
 	if (!driver) {
+		unlock_kernel();
 		mutex_unlock(&tty_mutex);
 		return -ENODEV;
 	}
@@ -1770,6 +1812,7 @@ got_driver:
 		tty = tty_driver_lookup_tty(driver, inode, index);
 
 		if (IS_ERR(tty)) {
+			unlock_kernel();
 			mutex_unlock(&tty_mutex);
 			return PTR_ERR(tty);
 		}
@@ -1784,8 +1827,10 @@ got_driver:
 
 	mutex_unlock(&tty_mutex);
 	tty_driver_kref_put(driver);
-	if (IS_ERR(tty))
+	if (IS_ERR(tty)) {
+		unlock_kernel();
 		return PTR_ERR(tty);
+	}
 
 	filp->private_data = tty;
 	file_move(filp, &tty->tty_files);
@@ -1813,11 +1858,15 @@ got_driver:
 		printk(KERN_DEBUG "error %d in opening %s...", retval,
 		       tty->name);
 #endif
-		tty_release_dev(filp);
-		if (retval != -ERESTARTSYS)
+		tty_release(inode, filp);
+		if (retval != -ERESTARTSYS) {
+			unlock_kernel();
 			return retval;
-		if (signal_pending(current))
+		}
+		if (signal_pending(current)) {
+			unlock_kernel();
 			return retval;
+		}
 		schedule();
 		/*
 		 * Need to reset f_op in case a hangup happened.
@@ -1826,8 +1875,11 @@ got_driver:
 			filp->f_op = &tty_fops;
 		goto retry_open;
 	}
+	unlock_kernel();
+
 
 	mutex_lock(&tty_mutex);
+	lock_kernel();
 	spin_lock_irq(&current->sighand->siglock);
 	if (!noctty &&
 	    current->signal->leader &&
@@ -1835,45 +1887,14 @@ got_driver:
 	    tty->session == NULL)
 		__proc_set_tty(current, tty);
 	spin_unlock_irq(&current->sighand->siglock);
+	unlock_kernel();
 	mutex_unlock(&tty_mutex);
 	return 0;
 }
 
-/* BKL pushdown: scary code avoidance wrapper */
-static int tty_open(struct inode *inode, struct file *filp)
-{
-	int ret;
-
-	lock_kernel();
-	ret = __tty_open(inode, filp);
-	unlock_kernel();
-	return ret;
-}
-
-
 
 
 /**
- *	tty_release		-	vfs callback for close
- *	@inode: inode of tty
- *	@filp: file pointer for handle to tty
- *
- *	Called the last time each file handle is closed that references
- *	this tty. There may however be several such references.
- *
- *	Locking:
- *		Takes bkl. See tty_release_dev
- */
-
-static int tty_release(struct inode *inode, struct file *filp)
-{
-	lock_kernel();
-	tty_release_dev(filp);
-	unlock_kernel();
-	return 0;
-}
-
-/**
  *	tty_poll	-	check tty status
  *	@filp: file being polled
  *	@wait: poll wait structures to update
@@ -1930,8 +1951,10 @@ static int tty_fasync(int fd, struct fil
 			pid = task_pid(current);
 			type = PIDTYPE_PID;
 		}
+		get_pid(pid);
 		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 		retval = __f_setown(filp, pid, type, 0);
+		put_pid(pid);
 		if (retval)
 			goto out;
 	} else {
@@ -2317,9 +2340,7 @@ static int tiocsetd(struct tty_struct *t
 	if (get_user(ldisc, p))
 		return -EFAULT;
 
-	lock_kernel();
 	ret = tty_set_ldisc(tty, ldisc);
-	unlock_kernel();
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tty_ioctl.c linux-libre-2.6.33-gnu1/drivers/char/tty_ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/char/tty_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tty_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -315,7 +315,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rat
  *	For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
  *	we need to carefully set the bits when the user does not get the
  *	desired speed. We allow small margins and preserve as much of possible
- *	of the input intent to keep compatiblity.
+ *	of the input intent to keep compatibility.
  *
  *	Locking: Caller should hold termios lock. This is already held
  *	when calling this function from the driver termios handler.
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tty_ldisc.c linux-libre-2.6.33-gnu1/drivers/char/tty_ldisc.c
--- linux-libre-2.6.32-gnu1/drivers/char/tty_ldisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tty_ldisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,8 @@
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 
+#include <linux/smp_lock.h>	/* For the moment */
+
 #include <linux/kmod.h>
 #include <linux/nsproxy.h>
 
@@ -443,8 +445,14 @@ static void tty_set_termios_ldisc(struct
 static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
 {
 	WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
-	if (ld->ops->open)
-		return ld->ops->open(tty);
+	if (ld->ops->open) {
+		int ret;
+                /* BKL here locks verus a hangup event */
+		lock_kernel();
+		ret = ld->ops->open(tty);
+		unlock_kernel();
+		return ret;
+	}
 	return 0;
 }
 
@@ -545,6 +553,7 @@ int tty_set_ldisc(struct tty_struct *tty
 	if (IS_ERR(new_ldisc))
 		return PTR_ERR(new_ldisc);
 
+	lock_kernel();
 	/*
 	 *	We need to look at the tty locking here for pty/tty pairs
 	 *	when both sides try to change in parallel.
@@ -558,10 +567,12 @@ int tty_set_ldisc(struct tty_struct *tty
 	 */
 
 	if (tty->ldisc->ops->num == ldisc) {
+		unlock_kernel();
 		tty_ldisc_put(new_ldisc);
 		return 0;
 	}
 
+	unlock_kernel();
 	/*
 	 *	Problem: What do we do if this blocks ?
 	 *	We could deadlock here
@@ -582,6 +593,9 @@ int tty_set_ldisc(struct tty_struct *tty
 			test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
 		mutex_lock(&tty->ldisc_mutex);
 	}
+
+	lock_kernel();
+
 	set_bit(TTY_LDISC_CHANGING, &tty->flags);
 
 	/*
@@ -592,6 +606,8 @@ int tty_set_ldisc(struct tty_struct *tty
 	tty->receive_room = 0;
 
 	o_ldisc = tty->ldisc;
+
+	unlock_kernel();
 	/*
 	 *	Make sure we don't change while someone holds a
 	 *	reference to the line discipline. The TTY_LDISC bit
@@ -617,12 +633,14 @@ int tty_set_ldisc(struct tty_struct *tty
 	flush_scheduled_work();
 
 	mutex_lock(&tty->ldisc_mutex);
+	lock_kernel();
 	if (test_bit(TTY_HUPPED, &tty->flags)) {
 		/* We were raced by the hangup method. It will have stomped
 		   the ldisc data and closed the ldisc down */
 		clear_bit(TTY_LDISC_CHANGING, &tty->flags);
 		mutex_unlock(&tty->ldisc_mutex);
 		tty_ldisc_put(new_ldisc);
+		unlock_kernel();
 		return -EIO;
 	}
 
@@ -664,6 +682,7 @@ int tty_set_ldisc(struct tty_struct *tty
 	if (o_work)
 		schedule_delayed_work(&o_tty->buf.work, 1);
 	mutex_unlock(&tty->ldisc_mutex);
+	unlock_kernel();
 	return retval;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/tty_port.c linux-libre-2.6.33-gnu1/drivers/char/tty_port.c
--- linux-libre-2.6.32-gnu1/drivers/char/tty_port.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/tty_port.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,19 +25,21 @@ void tty_port_init(struct tty_port *port
 	init_waitqueue_head(&port->close_wait);
 	init_waitqueue_head(&port->delta_msr_wait);
 	mutex_init(&port->mutex);
+	mutex_init(&port->buf_mutex);
 	spin_lock_init(&port->lock);
 	port->close_delay = (50 * HZ) / 100;
 	port->closing_wait = (3000 * HZ) / 100;
+	kref_init(&port->kref);
 }
 EXPORT_SYMBOL(tty_port_init);
 
 int tty_port_alloc_xmit_buf(struct tty_port *port)
 {
 	/* We may sleep in get_zeroed_page() */
-	mutex_lock(&port->mutex);
+	mutex_lock(&port->buf_mutex);
 	if (port->xmit_buf == NULL)
 		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
-	mutex_unlock(&port->mutex);
+	mutex_unlock(&port->buf_mutex);
 	if (port->xmit_buf == NULL)
 		return -ENOMEM;
 	return 0;
@@ -46,15 +48,32 @@ EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
 
 void tty_port_free_xmit_buf(struct tty_port *port)
 {
-	mutex_lock(&port->mutex);
+	mutex_lock(&port->buf_mutex);
 	if (port->xmit_buf != NULL) {
 		free_page((unsigned long)port->xmit_buf);
 		port->xmit_buf = NULL;
 	}
-	mutex_unlock(&port->mutex);
+	mutex_unlock(&port->buf_mutex);
 }
 EXPORT_SYMBOL(tty_port_free_xmit_buf);
 
+static void tty_port_destructor(struct kref *kref)
+{
+	struct tty_port *port = container_of(kref, struct tty_port, kref);
+	if (port->xmit_buf)
+		free_page((unsigned long)port->xmit_buf);
+	if (port->ops->destruct)
+		port->ops->destruct(port);
+	else
+		kfree(port);
+}
+
+void tty_port_put(struct tty_port *port)
+{
+	if (port)
+		kref_put(&port->kref, tty_port_destructor);
+}
+EXPORT_SYMBOL(tty_port_put);
 
 /**
  *	tty_port_tty_get	-	get a tty reference
@@ -99,10 +118,11 @@ EXPORT_SYMBOL(tty_port_tty_set);
 
 static void tty_port_shutdown(struct tty_port *port)
 {
+	mutex_lock(&port->mutex);
 	if (port->ops->shutdown &&
 		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
 			port->ops->shutdown(port);
-
+	mutex_unlock(&port->mutex);
 }
 
 /**
@@ -120,8 +140,10 @@ void tty_port_hangup(struct tty_port *po
 	spin_lock_irqsave(&port->lock, flags);
 	port->count = 0;
 	port->flags &= ~ASYNC_NORMAL_ACTIVE;
-	if (port->tty)
+	if (port->tty) {
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
 		tty_kref_put(port->tty);
+	}
 	port->tty = NULL;
 	spin_unlock_irqrestore(&port->lock, flags);
 	wake_up_interruptible(&port->open_wait);
@@ -198,7 +220,7 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts);
  *	management of these lines. Note that the dtr/rts raise is done each
  *	iteration as a hangup may have previously dropped them while we wait.
  */
- 
+
 int tty_port_block_til_ready(struct tty_port *port,
 				struct tty_struct *tty, struct file *filp)
 {
@@ -253,7 +275,8 @@ int tty_port_block_til_ready(struct tty_
 			tty_port_raise_dtr_rts(port);
 
 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
-		/* Check for a hangup or uninitialised port. Return accordingly */
+		/* Check for a hangup or uninitialised port.
+							Return accordingly */
 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
 			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
@@ -285,11 +308,11 @@ int tty_port_block_til_ready(struct tty_
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 	spin_unlock_irqrestore(&port->lock, flags);
 	return retval;
-	
 }
 EXPORT_SYMBOL(tty_port_block_til_ready);
 
-int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
+int tty_port_close_start(struct tty_port *port,
+				struct tty_struct *tty, struct file *filp)
 {
 	unsigned long flags;
 
@@ -299,7 +322,7 @@ int tty_port_close_start(struct tty_port
 		return 0;
 	}
 
-	if( tty->count == 1 && port->count != 1) {
+	if (tty->count == 1 && port->count != 1) {
 		printk(KERN_WARNING
 		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
 								port->count);
@@ -331,12 +354,20 @@ int tty_port_close_start(struct tty_port
 		long timeout;
 
 		if (bps > 1200)
-			timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
-								HZ / 10);
+			timeout = max_t(long,
+				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
 		else
 			timeout = 2 * HZ;
 		schedule_timeout_interruptible(timeout);
 	}
+	/* Flush the ldisc buffering */
+	tty_ldisc_flush(tty);
+
+	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
+	   hang up the line */
+	if (tty->termios->c_cflag & HUPCL)
+		tty_port_lower_dtr_rts(port);
+
 	/* Don't call port->drop for the last reference. Callers will want
 	   to drop the last active reference in ->shutdown() or the tty
 	   shutdown path */
@@ -348,11 +379,6 @@ void tty_port_close_end(struct tty_port
 {
 	unsigned long flags;
 
-	tty_ldisc_flush(tty);
-
-	if (tty->termios->c_cflag & HUPCL)
-		tty_port_lower_dtr_rts(port);
-
 	spin_lock_irqsave(&port->lock, flags);
 	tty->closing = 0;
 
@@ -377,7 +403,42 @@ void tty_port_close(struct tty_port *por
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
 	tty_port_shutdown(port);
+	set_bit(TTY_IO_ERROR, &tty->flags);
 	tty_port_close_end(port, tty);
 	tty_port_tty_set(port, NULL);
 }
 EXPORT_SYMBOL(tty_port_close);
+
+int tty_port_open(struct tty_port *port, struct tty_struct *tty,
+							struct file *filp)
+{
+	spin_lock_irq(&port->lock);
+	if (!tty_hung_up_p(filp))
+		++port->count;
+	spin_unlock_irq(&port->lock);
+	tty_port_tty_set(port, tty);
+
+	/*
+	 * Do the device-specific open only if the hardware isn't
+	 * already initialized. Serialize open and shutdown using the
+	 * port mutex.
+	 */
+
+	mutex_lock(&port->mutex);
+
+	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+		clear_bit(TTY_IO_ERROR, &tty->flags);
+		if (port->ops->activate) {
+			int retval = port->ops->activate(port, tty);
+			if (retval) {
+				mutex_unlock(&port->mutex);
+				return retval;
+			}
+		}
+		set_bit(ASYNCB_INITIALIZED, &port->flags);
+	}
+	mutex_unlock(&port->mutex);
+	return tty_port_block_til_ready(port, tty, filp);
+}
+
+EXPORT_SYMBOL(tty_port_open);
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/uv_mmtimer.c linux-libre-2.6.33-gnu1/drivers/char/uv_mmtimer.c
--- linux-libre-2.6.32-gnu1/drivers/char/uv_mmtimer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/uv_mmtimer.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,13 +89,17 @@ static long uv_mmtimer_ioctl(struct file
 	switch (cmd) {
 	case MMTIMER_GETOFFSET:	/* offset of the counter */
 		/*
-		 * UV RTC register is on its own page
+		 * Starting with HUB rev 2.0, the UV RTC register is
+		 * replicated across all cachelines of it's own page.
+		 * This allows faster simultaneous reads from a given socket.
+		 *
+		 * The offset returned is in 64 bit units.
 		 */
-		if (PAGE_SIZE <= (1 << 16))
-			ret = ((UV_LOCAL_MMR_BASE | UVH_RTC) & (PAGE_SIZE-1))
-				/ 8;
+		if (uv_get_min_hub_revision_id() == 1)
+			ret = 0;
 		else
-			ret = -ENOSYS;
+			ret = ((uv_blade_processor_id() * L1_CACHE_BYTES) %
+					PAGE_SIZE) / 8;
 		break;
 
 	case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */
@@ -115,8 +119,8 @@ static long uv_mmtimer_ioctl(struct file
 		ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK);
 		break;
 
-	case MMTIMER_MMAPAVAIL: /* can we mmap the clock into userspace? */
-		ret = (PAGE_SIZE <= (1 << 16)) ? 1 : 0;
+	case MMTIMER_MMAPAVAIL:
+		ret = 1;
 		break;
 
 	case MMTIMER_GETCOUNTER:
diff -druNp linux-libre-2.6.32-gnu1/drivers/char/vt.c linux-libre-2.6.33-gnu1/drivers/char/vt.c
--- linux-libre-2.6.32-gnu1/drivers/char/vt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/char/vt.c	2010-02-24 13:52:17.000000000 -0500
@@ -161,6 +161,11 @@ static void set_palette(struct vc_data *
 static int printable;		/* Is console ready for printing? */
 int default_utf8 = true;
 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
+int global_cursor_default = -1;
+module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
+
+static int cur_default = CUR_DEFAULT;
+module_param(cur_default, int, S_IRUGO | S_IWUSR);
 
 /*
  * ignore_poke: don't unblank the screen when things are typed.  This is
@@ -182,12 +187,10 @@ static DECLARE_WORK(console_work, consol
  * fg_console is the current virtual console,
  * last_console is the last used one,
  * want_console is the console we want to switch to,
- * kmsg_redirect is the console for kernel messages,
  */
 int fg_console;
 int last_console;
 int want_console = -1;
-int kmsg_redirect;
 
 /*
  * For each existing display, we have a pointer to console currently visible
@@ -775,6 +778,12 @@ int vc_allocate(unsigned int currcons)	/
 		vc_cons[currcons].d = NULL;
 		return -ENOMEM;
 	    }
+
+	    /* If no drivers have overridden us and the user didn't pass a
+	       boot option, default to displaying the cursor */
+	    if (global_cursor_default == -1)
+		    global_cursor_default = 1;
+
 	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
 	    vcs_make_sysfs(currcons);
 	    atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
@@ -1616,7 +1625,7 @@ static void reset_terminal(struct vc_dat
 	vc->vc_decscnm		= 0;
 	vc->vc_decom		= 0;
 	vc->vc_decawm		= 1;
-	vc->vc_deccm		= 1;
+	vc->vc_deccm		= global_cursor_default;
 	vc->vc_decim		= 0;
 
 	set_kbd(vc, decarm);
@@ -1630,7 +1639,7 @@ static void reset_terminal(struct vc_dat
 	/* do not do set_leds here because this causes an endless tasklet loop
 	   when the keyboard hasn't been initialized yet */
 
-	vc->vc_cursor_type = CUR_DEFAULT;
+	vc->vc_cursor_type = cur_default;
 	vc->vc_complement_mask = vc->vc_s_complement_mask;
 
 	default_attr(vc);
@@ -1832,7 +1841,7 @@ static void do_con_trol(struct tty_struc
 				if (vc->vc_par[0])
 					vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
 				else
-					vc->vc_cursor_type = CUR_DEFAULT;
+					vc->vc_cursor_type = cur_default;
 				return;
 			}
 			break;
@@ -2426,6 +2435,37 @@ struct tty_driver *console_driver;
 
 #ifdef CONFIG_VT_CONSOLE
 
+/**
+ * vt_kmsg_redirect() - Sets/gets the kernel message console
+ * @new:	The new virtual terminal number or -1 if the console should stay
+ * 		unchanged
+ *
+ * By default, the kernel messages are always printed on the current virtual
+ * console. However, the user may modify that default with the
+ * TIOCL_SETKMSGREDIRECT ioctl call.
+ *
+ * This function sets the kernel message console to be @new. It returns the old
+ * virtual console number. The virtual terminal number 0 (both as parameter and
+ * return value) means no redirection (i.e. always printed on the currently
+ * active console).
+ *
+ * The parameter -1 means that only the current console is returned, but the
+ * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
+ * case to make the code more understandable.
+ *
+ * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
+ * the parameter and always returns 0.
+ */
+int vt_kmsg_redirect(int new)
+{
+	static int kmsg_con;
+
+	if (new != -1)
+		return xchg(&kmsg_con, new);
+	else
+		return kmsg_con;
+}
+
 /*
  *	Console on virtual terminal
  *
@@ -2440,6 +2480,7 @@ static void vt_console_print(struct cons
 	const ushort *start;
 	ushort cnt = 0;
 	ushort myx;
+	int kmsg_console;
 
 	/* console busy or not yet initialized */
 	if (!printable)
@@ -2447,8 +2488,9 @@ static void vt_console_print(struct cons
 	if (!spin_trylock(&printing_lock))
 		return;
 
-	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
-		vc = vc_cons[kmsg_redirect - 1].d;
+	kmsg_console = vt_get_kmsg_redirect();
+	if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
+		vc = vc_cons[kmsg_console - 1].d;
 
 	/* read `x' only after setting currcons properly (otherwise
 	   the `x' macro will read the x of the foreground console). */
@@ -2605,7 +2647,7 @@ int tioclinux(struct tty_struct *tty, un
 			ret = set_vesa_blanking(p);
 			break;
 		case TIOCL_GETKMSGREDIRECT:
-			data = kmsg_redirect;
+			data = vt_get_kmsg_redirect();
 			ret = __put_user(data, p);
 			break;
 		case TIOCL_SETKMSGREDIRECT:
@@ -2615,7 +2657,7 @@ int tioclinux(struct tty_struct *tty, un
 				if (get_user(data, p+1))
 					ret = -EFAULT;
 				else
-					kmsg_redirect = data;
+					vt_kmsg_redirect(data);
 			}
 			break;
 		case TIOCL_GETFGCONSOLE:
@@ -4078,6 +4120,7 @@ EXPORT_SYMBOL(fg_console);
 EXPORT_SYMBOL(console_blank_hook);
 EXPORT_SYMBOL(console_blanked);
 EXPORT_SYMBOL(vc_cons);
+EXPORT_SYMBOL(global_cursor_default);
 #ifndef VT_SINGLE_DRIVER
 EXPORT_SYMBOL(take_over_console);
 EXPORT_SYMBOL(give_up_console);
diff -druNp linux-libre-2.6.32-gnu1/drivers/clocksource/cs5535-clockevt.c linux-libre-2.6.33-gnu1/drivers/clocksource/cs5535-clockevt.c
--- linux-libre-2.6.32-gnu1/drivers/clocksource/cs5535-clockevt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/clocksource/cs5535-clockevt.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,197 @@
+/*
+ * Clock event driver for the CS5535/CS5536
+ *
+ * Copyright (C) 2006, Advanced Micro Devices, Inc.
+ * Copyright (C) 2007  Andres Salomon <dilinger@debian.org>
+ * Copyright (C) 2009  Andres Salomon <dilinger@collabora.co.uk>
+ *
+ * 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.
+ *
+ * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/cs5535.h>
+#include <linux/clockchips.h>
+
+#define DRV_NAME "cs5535-clockevt"
+
+static int timer_irq;
+module_param_named(irq, timer_irq, int, 0644);
+MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks.");
+
+/*
+ * We are using the 32.768kHz input clock - it's the only one that has the
+ * ranges we find desirable.  The following table lists the suitable
+ * divisors and the associated Hz, minimum interval and the maximum interval:
+ *
+ *  Divisor   Hz      Min Delta (s)  Max Delta (s)
+ *   1        32768   .00048828125      2.000
+ *   2        16384   .0009765625       4.000
+ *   4         8192   .001953125        8.000
+ *   8         4096   .00390625        16.000
+ *   16        2048   .0078125         32.000
+ *   32        1024   .015625          64.000
+ *   64         512   .03125          128.000
+ *  128         256   .0625           256.000
+ *  256         128   .125            512.000
+ */
+
+static unsigned int cs5535_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
+static struct cs5535_mfgpt_timer *cs5535_event_clock;
+
+/* Selected from the table above */
+
+#define MFGPT_DIVISOR 16
+#define MFGPT_SCALE  4     /* divisor = 2^(scale) */
+#define MFGPT_HZ  (32768 / MFGPT_DIVISOR)
+#define MFGPT_PERIODIC (MFGPT_HZ / HZ)
+
+/*
+ * The MFPGT timers on the CS5536 provide us with suitable timers to use
+ * as clock event sources - not as good as a HPET or APIC, but certainly
+ * better than the PIT.  This isn't a general purpose MFGPT driver, but
+ * a simplified one designed specifically to act as a clock event source.
+ * For full details about the MFGPT, please consult the CS5536 data sheet.
+ */
+
+static void disable_timer(struct cs5535_mfgpt_timer *timer)
+{
+	/* avoid races by clearing CMP1 and CMP2 unconditionally */
+	cs5535_mfgpt_write(timer, MFGPT_REG_SETUP,
+			(uint16_t) ~MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP1 |
+				MFGPT_SETUP_CMP2);
+}
+
+static void start_timer(struct cs5535_mfgpt_timer *timer, uint16_t delta)
+{
+	cs5535_mfgpt_write(timer, MFGPT_REG_CMP2, delta);
+	cs5535_mfgpt_write(timer, MFGPT_REG_COUNTER, 0);
+
+	cs5535_mfgpt_write(timer, MFGPT_REG_SETUP,
+			MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
+}
+
+static void mfgpt_set_mode(enum clock_event_mode mode,
+		struct clock_event_device *evt)
+{
+	disable_timer(cs5535_event_clock);
+
+	if (mode == CLOCK_EVT_MODE_PERIODIC)
+		start_timer(cs5535_event_clock, MFGPT_PERIODIC);
+
+	cs5535_tick_mode = mode;
+}
+
+static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+	start_timer(cs5535_event_clock, delta);
+	return 0;
+}
+
+static struct clock_event_device cs5535_clockevent = {
+	.name = DRV_NAME,
+	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode = mfgpt_set_mode,
+	.set_next_event = mfgpt_next_event,
+	.rating = 250,
+	.cpumask = cpu_all_mask,
+	.shift = 32
+};
+
+static irqreturn_t mfgpt_tick(int irq, void *dev_id)
+{
+	uint16_t val = cs5535_mfgpt_read(cs5535_event_clock, MFGPT_REG_SETUP);
+
+	/* See if the interrupt was for us */
+	if (!(val & (MFGPT_SETUP_SETUP | MFGPT_SETUP_CMP2 | MFGPT_SETUP_CMP1)))
+		return IRQ_NONE;
+
+	/* Turn off the clock (and clear the event) */
+	disable_timer(cs5535_event_clock);
+
+	if (cs5535_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
+		return IRQ_HANDLED;
+
+	/* Clear the counter */
+	cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_COUNTER, 0);
+
+	/* Restart the clock in periodic mode */
+
+	if (cs5535_tick_mode == CLOCK_EVT_MODE_PERIODIC)
+		cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP,
+				MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
+
+	cs5535_clockevent.event_handler(&cs5535_clockevent);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mfgptirq  = {
+	.handler = mfgpt_tick,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+	.name = DRV_NAME,
+};
+
+static int __init cs5535_mfgpt_init(void)
+{
+	struct cs5535_mfgpt_timer *timer;
+	int ret;
+	uint16_t val;
+
+	timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
+	if (!timer) {
+		printk(KERN_ERR DRV_NAME ": Could not allocate MFPGT timer\n");
+		return -ENODEV;
+	}
+	cs5535_event_clock = timer;
+
+	/* Set up the IRQ on the MFGPT side */
+	if (cs5535_mfgpt_setup_irq(timer, MFGPT_CMP2, &timer_irq)) {
+		printk(KERN_ERR DRV_NAME ": Could not set up IRQ %d\n",
+				timer_irq);
+		return -EIO;
+	}
+
+	/* And register it with the kernel */
+	ret = setup_irq(timer_irq, &mfgptirq);
+	if (ret) {
+		printk(KERN_ERR DRV_NAME ": Unable to set up the interrupt.\n");
+		goto err;
+	}
+
+	/* Set the clock scale and enable the event mode for CMP2 */
+	val = MFGPT_SCALE | (3 << 8);
+
+	cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP, val);
+
+	/* Set up the clock event */
+	cs5535_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC,
+			cs5535_clockevent.shift);
+	cs5535_clockevent.min_delta_ns = clockevent_delta2ns(0xF,
+			&cs5535_clockevent);
+	cs5535_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE,
+			&cs5535_clockevent);
+
+	printk(KERN_INFO DRV_NAME
+		": Registering MFGPT timer as a clock event, using IRQ %d\n",
+		timer_irq);
+	clockevents_register_device(&cs5535_clockevent);
+
+	return 0;
+
+err:
+	cs5535_mfgpt_release_irq(cs5535_event_clock, MFGPT_CMP2, &timer_irq);
+	printk(KERN_ERR DRV_NAME ": Unable to set up the MFGPT clock source\n");
+	return -EIO;
+}
+
+module_init(cs5535_mfgpt_init);
+
+MODULE_AUTHOR("Andres Salomon <dilinger@collabora.co.uk>");
+MODULE_DESCRIPTION("CS5535/CS5536 MFGPT clock event driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/clocksource/Kconfig linux-libre-2.6.33-gnu1/drivers/clocksource/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/clocksource/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/clocksource/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,9 @@
+config CS5535_CLOCK_EVENT_SRC
+	tristate "CS5535/CS5536 high-res timer (MFGPT) events"
+	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
+	help
+	  This driver provides a clock event source based on the MFGPT
+	  timer(s) in the CS5535 and CS5536 companion chips.
+	  MFGPTs have a better resolution and max interval than the
+	  generic PIT, and are suitable for use as high-res timers.
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/clocksource/Makefile linux-libre-2.6.33-gnu1/drivers/clocksource/Makefile
--- linux-libre-2.6.32-gnu1/drivers/clocksource/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/clocksource/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC)	+= tcb_cl
 obj-$(CONFIG_X86_CYCLONE_TIMER)	+= cyclone.o
 obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
+obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC)	+= cs5535-clockevt.o
 obj-$(CONFIG_SH_TIMER_CMT)	+= sh_cmt.o
 obj-$(CONFIG_SH_TIMER_MTU2)	+= sh_mtu2.o
 obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/connector/connector.c linux-libre-2.6.33-gnu1/drivers/connector/connector.c
--- linux-libre-2.6.32-gnu1/drivers/connector/connector.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/connector/connector.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,17 +36,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
 
-static u32 cn_idx = CN_IDX_CONNECTOR;
-static u32 cn_val = CN_VAL_CONNECTOR;
-
-module_param(cn_idx, uint, 0);
-module_param(cn_val, uint, 0);
-MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
-MODULE_PARM_DESC(cn_val, "Connector's main device val.");
-
-static DEFINE_MUTEX(notify_lock);
-static LIST_HEAD(notify_list);
-
 static struct cn_dev cdev;
 
 static int cn_already_initialized;
@@ -210,54 +199,6 @@ static void cn_rx_skb(struct sk_buff *__
 }
 
 /*
- * Notification routing.
- *
- * Gets id and checks if there are notification request for it's idx
- * and val.  If there are such requests notify the listeners with the
- * given notify event.
- *
- */
-static void cn_notify(struct cb_id *id, u32 notify_event)
-{
-	struct cn_ctl_entry *ent;
-
-	mutex_lock(&notify_lock);
-	list_for_each_entry(ent, &notify_list, notify_entry) {
-		int i;
-		struct cn_notify_req *req;
-		struct cn_ctl_msg *ctl = ent->msg;
-		int idx_found, val_found;
-
-		idx_found = val_found = 0;
-
-		req = (struct cn_notify_req *)ctl->data;
-		for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
-			if (id->idx >= req->first &&
-					id->idx < req->first + req->range) {
-				idx_found = 1;
-				break;
-			}
-		}
-
-		for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
-			if (id->val >= req->first &&
-					id->val < req->first + req->range) {
-				val_found = 1;
-				break;
-			}
-		}
-
-		if (idx_found && val_found) {
-			struct cn_msg m = { .ack = notify_event, };
-
-			memcpy(&m.id, id, sizeof(m.id));
-			cn_netlink_send(&m, ctl->group, GFP_KERNEL);
-		}
-	}
-	mutex_unlock(&notify_lock);
-}
-
-/*
  * Callback add routing - adds callback with given ID and name.
  * If there is registered callback with the same ID it will not be added.
  *
@@ -276,8 +217,6 @@ int cn_add_callback(struct cb_id *id, ch
 	if (err)
 		return err;
 
-	cn_notify(id, 0);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cn_add_callback);
@@ -295,111 +234,9 @@ void cn_del_callback(struct cb_id *id)
 	struct cn_dev *dev = &cdev;
 
 	cn_queue_del_callback(dev->cbdev, id);
-	cn_notify(id, 1);
 }
 EXPORT_SYMBOL_GPL(cn_del_callback);
 
-/*
- * Checks two connector's control messages to be the same.
- * Returns 1 if they are the same or if the first one is corrupted.
- */
-static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
-{
-	int i;
-	struct cn_notify_req *req1, *req2;
-
-	if (m1->idx_notify_num != m2->idx_notify_num)
-		return 0;
-
-	if (m1->val_notify_num != m2->val_notify_num)
-		return 0;
-
-	if (m1->len != m2->len)
-		return 0;
-
-	if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) !=
-	    m1->len)
-		return 1;
-
-	req1 = (struct cn_notify_req *)m1->data;
-	req2 = (struct cn_notify_req *)m2->data;
-
-	for (i = 0; i < m1->idx_notify_num; ++i) {
-		if (req1->first != req2->first || req1->range != req2->range)
-			return 0;
-		req1++;
-		req2++;
-	}
-
-	for (i = 0; i < m1->val_notify_num; ++i) {
-		if (req1->first != req2->first || req1->range != req2->range)
-			return 0;
-		req1++;
-		req2++;
-	}
-
-	return 1;
-}
-
-/*
- * Main connector device's callback.
- *
- * Used for notification of a request's processing.
- */
-static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
-{
-	struct cn_ctl_msg *ctl;
-	struct cn_ctl_entry *ent;
-	u32 size;
-
-	if (msg->len < sizeof(*ctl))
-		return;
-
-	ctl = (struct cn_ctl_msg *)msg->data;
-
-	size = (sizeof(*ctl) + ((ctl->idx_notify_num +
-				 ctl->val_notify_num) *
-				sizeof(struct cn_notify_req)));
-
-	if (msg->len != size)
-		return;
-
-	if (ctl->len + sizeof(*ctl) != msg->len)
-		return;
-
-	/*
-	 * Remove notification.
-	 */
-	if (ctl->group == 0) {
-		struct cn_ctl_entry *n;
-
-		mutex_lock(&notify_lock);
-		list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
-			if (cn_ctl_msg_equals(ent->msg, ctl)) {
-				list_del(&ent->notify_entry);
-				kfree(ent);
-			}
-		}
-		mutex_unlock(&notify_lock);
-
-		return;
-	}
-
-	size += sizeof(*ent);
-
-	ent = kzalloc(size, GFP_KERNEL);
-	if (!ent)
-		return;
-
-	ent->msg = (struct cn_ctl_msg *)(ent + 1);
-
-	memcpy(ent->msg, ctl, size - sizeof(*ent));
-
-	mutex_lock(&notify_lock);
-	list_add(&ent->notify_entry, &notify_list);
-	mutex_unlock(&notify_lock);
-}
-
 static int cn_proc_show(struct seq_file *m, void *v)
 {
 	struct cn_queue_dev *dev = cdev.cbdev;
@@ -437,11 +274,8 @@ static const struct file_operations cn_f
 static int __devinit cn_init(void)
 {
 	struct cn_dev *dev = &cdev;
-	int err;
 
 	dev->input = cn_rx_skb;
-	dev->id.idx = cn_idx;
-	dev->id.val = cn_val;
 
 	dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
 					 CN_NETLINK_USERS + 0xf,
@@ -457,14 +291,6 @@ static int __devinit cn_init(void)
 
 	cn_already_initialized = 1;
 
-	err = cn_add_callback(&dev->id, "connector", &cn_callback);
-	if (err) {
-		cn_already_initialized = 0;
-		cn_queue_free_dev(dev->cbdev);
-		netlink_kernel_release(dev->nls);
-		return -EINVAL;
-	}
-
 	proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);
 
 	return 0;
@@ -478,7 +304,6 @@ static void __devexit cn_fini(void)
 
 	proc_net_remove(&init_net, "connector");
 
-	cn_del_callback(&dev->id);
 	cn_queue_free_dev(dev->cbdev);
 	netlink_kernel_release(dev->nls);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq.c linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq.c
--- linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,14 +64,14 @@ static DEFINE_SPINLOCK(cpufreq_driver_lo
  * - Lock should not be held across
  *     __cpufreq_governor(data, CPUFREQ_GOV_STOP);
  */
-static DEFINE_PER_CPU(int, policy_cpu);
+static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
 static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
 
 #define lock_policy_rwsem(mode, cpu)					\
 int lock_policy_rwsem_##mode						\
 (int cpu)								\
 {									\
-	int policy_cpu = per_cpu(policy_cpu, cpu);			\
+	int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);		\
 	BUG_ON(policy_cpu == -1);					\
 	down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));		\
 	if (unlikely(!cpu_online(cpu))) {				\
@@ -90,7 +90,7 @@ EXPORT_SYMBOL_GPL(lock_policy_rwsem_writ
 
 void unlock_policy_rwsem_read(int cpu)
 {
-	int policy_cpu = per_cpu(policy_cpu, cpu);
+	int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
 	BUG_ON(policy_cpu == -1);
 	up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
 }
@@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(unlock_policy_rwsem_re
 
 void unlock_policy_rwsem_write(int cpu)
 {
-	int policy_cpu = per_cpu(policy_cpu, cpu);
+	int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
 	BUG_ON(policy_cpu == -1);
 	up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
 }
@@ -647,6 +647,21 @@ static ssize_t show_scaling_setspeed(str
 	return policy->governor->show_setspeed(policy, buf);
 }
 
+/**
+ * show_scaling_driver - show the current cpufreq HW/BIOS limitation
+ */
+static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
+{
+	unsigned int limit;
+	int ret;
+	if (cpufreq_driver->bios_limit) {
+		ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
+		if (!ret)
+			return sprintf(buf, "%u\n", limit);
+	}
+	return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
+}
+
 #define define_one_ro(_name) \
 static struct freq_attr _name = \
 __ATTR(_name, 0444, show_##_name, NULL)
@@ -666,6 +681,7 @@ define_one_ro(cpuinfo_transition_latency
 define_one_ro(scaling_available_governors);
 define_one_ro(scaling_driver);
 define_one_ro(scaling_cur_freq);
+define_one_ro(bios_limit);
 define_one_ro(related_cpus);
 define_one_ro(affected_cpus);
 define_one_rw(scaling_min_freq);
@@ -767,8 +783,9 @@ static struct kobj_type ktype_cpufreq =
  *   0:        Success
  *   Positive: When we have a managed CPU and the sysfs got symlinked
  */
-int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
-		struct sys_device *sys_dev)
+static int cpufreq_add_dev_policy(unsigned int cpu,
+				  struct cpufreq_policy *policy,
+				  struct sys_device *sys_dev)
 {
 	int ret = 0;
 #ifdef CONFIG_SMP
@@ -801,7 +818,7 @@ int cpufreq_add_dev_policy(unsigned int
 
 			/* Set proper policy_cpu */
 			unlock_policy_rwsem_write(cpu);
-			per_cpu(policy_cpu, cpu) = managed_policy->cpu;
+			per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
 
 			if (lock_policy_rwsem_write(cpu) < 0) {
 				/* Should not go through policy unlock path */
@@ -842,7 +859,8 @@ int cpufreq_add_dev_policy(unsigned int
 
 
 /* symlink affected CPUs */
-int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
+static int cpufreq_add_dev_symlink(unsigned int cpu,
+				   struct cpufreq_policy *policy)
 {
 	unsigned int j;
 	int ret = 0;
@@ -869,8 +887,9 @@ int cpufreq_add_dev_symlink(unsigned int
 	return ret;
 }
 
-int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
-		struct sys_device *sys_dev)
+static int cpufreq_add_dev_interface(unsigned int cpu,
+				     struct cpufreq_policy *policy,
+				     struct sys_device *sys_dev)
 {
 	struct cpufreq_policy new_policy;
 	struct freq_attr **drv_attr;
@@ -902,13 +921,18 @@ int cpufreq_add_dev_interface(unsigned i
 		if (ret)
 			goto err_out_kobj_put;
 	}
+	if (cpufreq_driver->bios_limit) {
+		ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
+		if (ret)
+			goto err_out_kobj_put;
+	}
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
 	for_each_cpu(j, policy->cpus) {
 	if (!cpu_online(j))
 		continue;
 		per_cpu(cpufreq_cpu_data, j) = policy;
-		per_cpu(policy_cpu, j) = policy->cpu;
+		per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
 	}
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
@@ -996,7 +1020,7 @@ static int cpufreq_add_dev(struct sys_de
 	cpumask_copy(policy->cpus, cpumask_of(cpu));
 
 	/* Initially set CPU itself as the policy_cpu */
-	per_cpu(policy_cpu, cpu) = cpu;
+	per_cpu(cpufreq_policy_cpu, cpu) = cpu;
 	ret = (lock_policy_rwsem_write(cpu) < 0);
 	WARN_ON(ret);
 
@@ -1978,7 +2002,7 @@ static int __init cpufreq_core_init(void
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		per_cpu(policy_cpu, cpu) = -1;
+		per_cpu(cpufreq_policy_cpu, cpu) = -1;
 		init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq_conservative.c linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_conservative.c
--- linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq_conservative.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_conservative.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,20 +164,22 @@ static struct notifier_block dbs_cpufreq
 };
 
 /************************** sysfs interface ************************/
-static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_max(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	printk_once(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
 		    "sysfs file is deprecated - used by: %s\n", current->comm);
 	return sprintf(buf, "%u\n", -1U);
 }
 
-static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_min(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
 #define define_one_ro(_name)		\
-static struct freq_attr _name =		\
+static struct global_attr _name =	\
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -186,7 +188,7 @@ define_one_ro(sampling_rate_min);
 /* cpufreq_conservative Governor Tunables */
 #define show_one(file_name, object)					\
 static ssize_t show_##file_name						\
-(struct cpufreq_policy *unused, char *buf)				\
+(struct kobject *kobj, struct attribute *attr, char *buf)		\
 {									\
 	return sprintf(buf, "%u\n", dbs_tuners_ins.object);		\
 }
@@ -197,8 +199,40 @@ show_one(down_threshold, down_threshold)
 show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
-static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+/*** delete after deprecation time ***/
+#define DEPRECATION_MSG(file_name)					\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");
+
+#define show_one_old(file_name)						\
+static ssize_t show_##file_name##_old					\
+(struct cpufreq_policy *unused, char *buf)				\
+{									\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");		\
+	return show_##file_name(NULL, NULL, buf);			\
+}
+show_one_old(sampling_rate);
+show_one_old(sampling_down_factor);
+show_one_old(up_threshold);
+show_one_old(down_threshold);
+show_one_old(ignore_nice_load);
+show_one_old(freq_step);
+show_one_old(sampling_rate_min);
+show_one_old(sampling_rate_max);
+
+#define define_one_ro_old(object, _name)	\
+static struct freq_attr object =		\
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
+define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+
+/*** delete after deprecation time ***/
+
+static ssize_t store_sampling_down_factor(struct kobject *a,
+					  struct attribute *b,
+					  const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -214,8 +248,8 @@ static ssize_t store_sampling_down_facto
 	return count;
 }
 
-static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
+				   const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -231,8 +265,8 @@ static ssize_t store_sampling_rate(struc
 	return count;
 }
 
-static ssize_t store_up_threshold(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
+				  const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -251,8 +285,8 @@ static ssize_t store_up_threshold(struct
 	return count;
 }
 
-static ssize_t store_down_threshold(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_down_threshold(struct kobject *a, struct attribute *b,
+				    const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -272,8 +306,8 @@ static ssize_t store_down_threshold(stru
 	return count;
 }
 
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
+				      const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -308,8 +342,8 @@ static ssize_t store_ignore_nice_load(st
 	return count;
 }
 
-static ssize_t store_freq_step(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
+static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
+			       const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -331,7 +365,7 @@ static ssize_t store_freq_step(struct cp
 }
 
 #define define_one_rw(_name) \
-static struct freq_attr _name = \
+static struct global_attr _name = \
 __ATTR(_name, 0644, show_##_name, store_##_name)
 
 define_one_rw(sampling_rate);
@@ -358,6 +392,53 @@ static struct attribute_group dbs_attr_g
 	.name = "conservative",
 };
 
+/*** delete after deprecation time ***/
+
+#define write_one_old(file_name)					\
+static ssize_t store_##file_name##_old					\
+(struct cpufreq_policy *unused, const char *buf, size_t count)		\
+{									\
+	printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs "	\
+		"interface is deprecated - " #file_name "\n");	\
+	return store_##file_name(NULL, NULL, buf, count);		\
+}
+write_one_old(sampling_rate);
+write_one_old(sampling_down_factor);
+write_one_old(up_threshold);
+write_one_old(down_threshold);
+write_one_old(ignore_nice_load);
+write_one_old(freq_step);
+
+#define define_one_rw_old(object, _name)	\
+static struct freq_attr object =		\
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+define_one_rw_old(sampling_rate_old, sampling_rate);
+define_one_rw_old(sampling_down_factor_old, sampling_down_factor);
+define_one_rw_old(up_threshold_old, up_threshold);
+define_one_rw_old(down_threshold_old, down_threshold);
+define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
+define_one_rw_old(freq_step_old, freq_step);
+
+static struct attribute *dbs_attributes_old[] = {
+	&sampling_rate_max_old.attr,
+	&sampling_rate_min_old.attr,
+	&sampling_rate_old.attr,
+	&sampling_down_factor_old.attr,
+	&up_threshold_old.attr,
+	&down_threshold_old.attr,
+	&ignore_nice_load_old.attr,
+	&freq_step_old.attr,
+	NULL
+};
+
+static struct attribute_group dbs_attr_group_old = {
+	.attrs = dbs_attributes_old,
+	.name = "conservative",
+};
+
+/*** delete after deprecation time ***/
+
 /************************** sysfs end ************************/
 
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
@@ -530,7 +611,7 @@ static int cpufreq_governor_dbs(struct c
 
 		mutex_lock(&dbs_mutex);
 
-		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old);
 		if (rc) {
 			mutex_unlock(&dbs_mutex);
 			return rc;
@@ -564,6 +645,13 @@ static int cpufreq_governor_dbs(struct c
 			if (latency == 0)
 				latency = 1;
 
+			rc = sysfs_create_group(cpufreq_global_kobject,
+						&dbs_attr_group);
+			if (rc) {
+				mutex_unlock(&dbs_mutex);
+				return rc;
+			}
+
 			/*
 			 * conservative does not implement micro like ondemand
 			 * governor, thus we are bound to jiffes/HZ
@@ -591,7 +679,7 @@ static int cpufreq_governor_dbs(struct c
 		dbs_timer_exit(this_dbs_info);
 
 		mutex_lock(&dbs_mutex);
-		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+		sysfs_remove_group(&policy->kobj, &dbs_attr_group_old);
 		dbs_enable--;
 		mutex_destroy(&this_dbs_info->timer_mutex);
 
@@ -605,6 +693,9 @@ static int cpufreq_governor_dbs(struct c
 					CPUFREQ_TRANSITION_NOTIFIER);
 
 		mutex_unlock(&dbs_mutex);
+		if (!dbs_enable)
+			sysfs_remove_group(cpufreq_global_kobject,
+					   &dbs_attr_group);
 
 		break;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq_ondemand.c linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_ondemand.c
--- linux-libre-2.6.32-gnu1/drivers/cpufreq/cpufreq_ondemand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpufreq/cpufreq_ondemand.c	2010-02-24 13:52:17.000000000 -0500
@@ -554,6 +554,9 @@ static void dbs_check_cpu(struct cpu_dbs
 				(dbs_tuners_ins.up_threshold -
 				 dbs_tuners_ins.down_differential);
 
+		if (freq_next < policy->min)
+			freq_next = policy->min;
+
 		if (!dbs_tuners_ins.powersave_bias) {
 			__cpufreq_driver_target(policy, freq_next,
 					CPUFREQ_RELATION_L);
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpufreq/freq_table.c linux-libre-2.6.33-gnu1/drivers/cpufreq/freq_table.c
--- linux-libre-2.6.32-gnu1/drivers/cpufreq/freq_table.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpufreq/freq_table.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,7 +174,7 @@ int cpufreq_frequency_table_target(struc
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 
-static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table);
+static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
 /**
  * show_available_freqs - show available frequencies for the specified CPU
  */
@@ -185,10 +185,10 @@ static ssize_t show_available_freqs(stru
 	ssize_t count = 0;
 	struct cpufreq_frequency_table *table;
 
-	if (!per_cpu(show_table, cpu))
+	if (!per_cpu(cpufreq_show_table, cpu))
 		return -ENODEV;
 
-	table = per_cpu(show_table, cpu);
+	table = per_cpu(cpufreq_show_table, cpu);
 
 	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
@@ -217,20 +217,20 @@ void cpufreq_frequency_table_get_attr(st
 				      unsigned int cpu)
 {
 	dprintk("setting show_table for cpu %u to %p\n", cpu, table);
-	per_cpu(show_table, cpu) = table;
+	per_cpu(cpufreq_show_table, cpu) = table;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu)
 {
 	dprintk("clearing show_table for cpu %u\n", cpu);
-	per_cpu(show_table, cpu) = NULL;
+	per_cpu(cpufreq_show_table, cpu) = NULL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
 struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
 {
-	return per_cpu(show_table, cpu);
+	return per_cpu(cpufreq_show_table, cpu);
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpuidle/governor.c linux-libre-2.6.33-gnu1/drivers/cpuidle/governor.c
--- linux-libre-2.6.32-gnu1/drivers/cpuidle/governor.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpuidle/governor.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,7 @@ struct cpuidle_governor *cpuidle_curr_go
  * __cpuidle_find_governor - finds a governor of the specified name
  * @str: the name
  *
- * Must be called with cpuidle_lock aquired.
+ * Must be called with cpuidle_lock acquired.
  */
 static struct cpuidle_governor * __cpuidle_find_governor(const char *str)
 {
@@ -39,7 +39,7 @@ static struct cpuidle_governor * __cpuid
  * @gov: the new target governor
  *
  * NOTE: "gov" can be NULL to specify disabled
- * Must be called with cpuidle_lock aquired.
+ * Must be called with cpuidle_lock acquired.
  */
 int cpuidle_switch_governor(struct cpuidle_governor *gov)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpuidle/governors/ladder.c linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/ladder.c
--- linux-libre-2.6.32-gnu1/drivers/cpuidle/governors/ladder.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/ladder.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,9 +69,6 @@ static int ladder_select_state(struct cp
 	int last_residency, last_idx = ldev->last_state_idx;
 	int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
 
-	if (unlikely(!ldev))
-		return 0;
-
 	/* Special case when user has set very strict latency requirement */
 	if (unlikely(latency_req == 0)) {
 		ladder_do_selection(ldev, last_idx, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/cpuidle/governors/menu.c linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/menu.c
--- linux-libre-2.6.32-gnu1/drivers/cpuidle/governors/menu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/cpuidle/governors/menu.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/hrtimer.h>
 #include <linux/tick.h>
 #include <linux/sched.h>
+#include <linux/math64.h>
 
 #define BUCKETS 12
 #define RESOLUTION 1024
@@ -169,6 +170,12 @@ static DEFINE_PER_CPU(struct menu_device
 
 static void menu_update(struct cpuidle_device *dev);
 
+/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
+static u64 div_round64(u64 dividend, u32 divisor)
+{
+	return div_u64(dividend + (divisor / 2), divisor);
+}
+
 /**
  * menu_select - selects the next idle state to enter
  * @dev: the CPU
@@ -209,9 +216,8 @@ static int menu_select(struct cpuidle_de
 		data->correction_factor[data->bucket] = RESOLUTION * DECAY;
 
 	/* Make sure to round up for half microseconds */
-	data->predicted_us = DIV_ROUND_CLOSEST(
-		data->expected_us * data->correction_factor[data->bucket],
-		RESOLUTION * DECAY);
+	data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket],
+					 RESOLUTION * DECAY);
 
 	/*
 	 * We want to default to C1 (hlt), not to busy polling
diff -druNp linux-libre-2.6.32-gnu1/drivers/crypto/hifn_795x.c linux-libre-2.6.33-gnu1/drivers/crypto/hifn_795x.c
--- linux-libre-2.6.32-gnu1/drivers/crypto/hifn_795x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/crypto/hifn_795x.c	2010-02-24 13:52:17.000000000 -0500
@@ -863,7 +863,7 @@ static int hifn_init_pubrng(struct hifn_
 		dev->dmareg |= HIFN_DMAIER_PUBDONE;
 		hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg);
 
-		dprintk("Chip %s: Public key engine has been sucessfully "
+		dprintk("Chip %s: Public key engine has been successfully "
 				"initialised.\n", dev->name);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/crypto/padlock-aes.c linux-libre-2.6.33-gnu1/drivers/crypto/padlock-aes.c
--- linux-libre-2.6.32-gnu1/drivers/crypto/padlock-aes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/crypto/padlock-aes.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,7 +64,7 @@ struct aes_ctx {
 	u32 *D;
 };
 
-static DEFINE_PER_CPU(struct cword *, last_cword);
+static DEFINE_PER_CPU(struct cword *, paes_last_cword);
 
 /* Tells whether the ACE is capable to generate
    the extended key for a given key_len. */
@@ -152,9 +152,9 @@ static int aes_set_key(struct crypto_tfm
 
 ok:
 	for_each_online_cpu(cpu)
-		if (&ctx->cword.encrypt == per_cpu(last_cword, cpu) ||
-		    &ctx->cword.decrypt == per_cpu(last_cword, cpu))
-			per_cpu(last_cword, cpu) = NULL;
+		if (&ctx->cword.encrypt == per_cpu(paes_last_cword, cpu) ||
+		    &ctx->cword.decrypt == per_cpu(paes_last_cword, cpu))
+			per_cpu(paes_last_cword, cpu) = NULL;
 
 	return 0;
 }
@@ -166,7 +166,7 @@ static inline void padlock_reset_key(str
 {
 	int cpu = raw_smp_processor_id();
 
-	if (cword != per_cpu(last_cword, cpu))
+	if (cword != per_cpu(paes_last_cword, cpu))
 #ifndef CONFIG_X86_64
 		asm volatile ("pushfl; popfl");
 #else
@@ -176,7 +176,7 @@ static inline void padlock_reset_key(str
 
 static inline void padlock_store_cword(struct cword *cword)
 {
-	per_cpu(last_cword, raw_smp_processor_id()) = cword;
+	per_cpu(paes_last_cword, raw_smp_processor_id()) = cword;
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/crypto/padlock-sha.c linux-libre-2.6.33-gnu1/drivers/crypto/padlock-sha.c
--- linux-libre-2.6.32-gnu1/drivers/crypto/padlock-sha.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/crypto/padlock-sha.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,6 +57,23 @@ static int padlock_sha_update(struct sha
 	return crypto_shash_update(&dctx->fallback, data, length);
 }
 
+static int padlock_sha_export(struct shash_desc *desc, void *out)
+{
+	struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
+
+	return crypto_shash_export(&dctx->fallback, out);
+}
+
+static int padlock_sha_import(struct shash_desc *desc, const void *in)
+{
+	struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
+	struct padlock_sha_ctx *ctx = crypto_shash_ctx(desc->tfm);
+
+	dctx->fallback.tfm = ctx->fallback;
+	dctx->fallback.flags = desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
+	return crypto_shash_import(&dctx->fallback, in);
+}
+
 static inline void padlock_output_block(uint32_t *src,
 		 	uint32_t *dst, size_t count)
 {
@@ -235,7 +252,10 @@ static struct shash_alg sha1_alg = {
 	.update 	=	padlock_sha_update,
 	.finup  	=	padlock_sha1_finup,
 	.final  	=	padlock_sha1_final,
+	.export		=	padlock_sha_export,
+	.import		=	padlock_sha_import,
 	.descsize	=	sizeof(struct padlock_sha_desc),
+	.statesize	=	sizeof(struct sha1_state),
 	.base		=	{
 		.cra_name		=	"sha1",
 		.cra_driver_name	=	"sha1-padlock",
@@ -256,7 +276,10 @@ static struct shash_alg sha256_alg = {
 	.update 	=	padlock_sha_update,
 	.finup  	=	padlock_sha256_finup,
 	.final  	=	padlock_sha256_final,
+	.export		=	padlock_sha_export,
+	.import		=	padlock_sha_import,
 	.descsize	=	sizeof(struct padlock_sha_desc),
+	.statesize	=	sizeof(struct sha256_state),
 	.base		=	{
 		.cra_name		=	"sha256",
 		.cra_driver_name	=	"sha256-padlock",
diff -druNp linux-libre-2.6.32-gnu1/drivers/dio/dio-driver.c linux-libre-2.6.33-gnu1/drivers/dio/dio-driver.c
--- linux-libre-2.6.32-gnu1/drivers/dio/dio-driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dio/dio-driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,5 +140,4 @@ postcore_initcall(dio_driver_init);
 EXPORT_SYMBOL(dio_match_device);
 EXPORT_SYMBOL(dio_register_driver);
 EXPORT_SYMBOL(dio_unregister_driver);
-EXPORT_SYMBOL(dio_dev_driver);
 EXPORT_SYMBOL(dio_bus_type);
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/at_hdmac.c linux-libre-2.6.33-gnu1/drivers/dma/at_hdmac.c
--- linux-libre-2.6.32-gnu1/drivers/dma/at_hdmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/at_hdmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,7 +99,7 @@ static struct at_desc *atc_alloc_descrip
 }
 
 /**
- * atc_desc_get - get a unsused descriptor from free_list
+ * atc_desc_get - get an unused descriptor from free_list
  * @atchan: channel we want a new descriptor for
  */
 static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
@@ -815,7 +815,7 @@ atc_is_tx_complete(struct dma_chan *chan
 	dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n",
 			cookie, done ? *done : 0, used ? *used : 0);
 
-	spin_lock_bh(atchan->lock);
+	spin_lock_bh(&atchan->lock);
 
 	last_complete = atchan->completed_cookie;
 	last_used = chan->cookie;
@@ -830,7 +830,7 @@ atc_is_tx_complete(struct dma_chan *chan
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
 	}
 
-	spin_unlock_bh(atchan->lock);
+	spin_unlock_bh(&atchan->lock);
 
 	if (done)
 		*done = last_complete;
@@ -1188,7 +1188,7 @@ static int at_dma_resume_noirq(struct de
 	return 0;
 }
 
-static struct dev_pm_ops at_dma_dev_pm_ops = {
+static const struct dev_pm_ops at_dma_dev_pm_ops = {
 	.suspend_noirq = at_dma_suspend_noirq,
 	.resume_noirq = at_dma_resume_noirq,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/coh901318.c linux-libre-2.6.33-gnu1/drivers/dma/coh901318.c
--- linux-libre-2.6.32-gnu1/drivers/dma/coh901318.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/coh901318.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1323 @@
+/*
+ * driver/dma/coh901318.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * DMA driver for COH 901 318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/slab.h> /* kmalloc() */
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/irqreturn.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <mach/coh901318.h>
+
+#include "coh901318_lli.h"
+
+#define COHC_2_DEV(cohc) (&cohc->chan.dev->device)
+
+#ifdef VERBOSE_DEBUG
+#define COH_DBG(x) ({ if (1) x; 0; })
+#else
+#define COH_DBG(x) ({ if (0) x; 0; })
+#endif
+
+struct coh901318_desc {
+	struct dma_async_tx_descriptor desc;
+	struct list_head node;
+	struct scatterlist *sg;
+	unsigned int sg_len;
+	struct coh901318_lli *data;
+	enum dma_data_direction dir;
+	int pending_irqs;
+	unsigned long flags;
+};
+
+struct coh901318_base {
+	struct device *dev;
+	void __iomem *virtbase;
+	struct coh901318_pool pool;
+	struct powersave pm;
+	struct dma_device dma_slave;
+	struct dma_device dma_memcpy;
+	struct coh901318_chan *chans;
+	struct coh901318_platform *platform;
+};
+
+struct coh901318_chan {
+	spinlock_t lock;
+	int allocated;
+	int completed;
+	int id;
+	int stopped;
+
+	struct work_struct free_work;
+	struct dma_chan chan;
+
+	struct tasklet_struct tasklet;
+
+	struct list_head active;
+	struct list_head queue;
+	struct list_head free;
+
+	unsigned long nbr_active_done;
+	unsigned long busy;
+	int pending_irqs;
+
+	struct coh901318_base *base;
+};
+
+static void coh901318_list_print(struct coh901318_chan *cohc,
+				 struct coh901318_lli *lli)
+{
+	struct coh901318_lli *l;
+	dma_addr_t addr =  virt_to_phys(lli);
+	int i = 0;
+
+	while (addr) {
+		l = phys_to_virt(addr);
+		dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x"
+			 ", dst 0x%x, link 0x%x link_virt 0x%p\n",
+			 i, l, l->control, l->src_addr, l->dst_addr,
+			 l->link_addr, phys_to_virt(l->link_addr));
+		i++;
+		addr = l->link_addr;
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define COH901318_DEBUGFS_ASSIGN(x, y) (x = y)
+
+static struct coh901318_base *debugfs_dma_base;
+static struct dentry *dma_dentry;
+
+static int coh901318_debugfs_open(struct inode *inode, struct file *file)
+{
+
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static int coh901318_debugfs_read(struct file *file, char __user *buf,
+				  size_t count, loff_t *f_pos)
+{
+	u64 started_channels = debugfs_dma_base->pm.started_channels;
+	int pool_count = debugfs_dma_base->pool.debugfs_pool_counter;
+	int i;
+	int ret = 0;
+	char *dev_buf;
+	char *tmp;
+	int dev_size;
+
+	dev_buf = kmalloc(4*1024, GFP_KERNEL);
+	if (dev_buf == NULL)
+		goto err_kmalloc;
+	tmp = dev_buf;
+
+	tmp += sprintf(tmp, "DMA -- enable dma channels\n");
+
+	for (i = 0; i < debugfs_dma_base->platform->max_channels; i++)
+		if (started_channels & (1 << i))
+			tmp += sprintf(tmp, "channel %d\n", i);
+
+	tmp += sprintf(tmp, "Pool alloc nbr %d\n", pool_count);
+	dev_size = tmp  - dev_buf;
+
+	/* No more to read if offset != 0 */
+	if (*f_pos > dev_size)
+		goto out;
+
+	if (count > dev_size - *f_pos)
+		count = dev_size - *f_pos;
+
+	if (copy_to_user(buf, dev_buf + *f_pos, count))
+		ret = -EINVAL;
+	ret = count;
+	*f_pos += count;
+
+ out:
+	kfree(dev_buf);
+	return ret;
+
+ err_kmalloc:
+	return 0;
+}
+
+static const struct file_operations coh901318_debugfs_status_operations = {
+	.owner		= THIS_MODULE,
+	.open		= coh901318_debugfs_open,
+	.read		= coh901318_debugfs_read,
+};
+
+
+static int __init init_coh901318_debugfs(void)
+{
+
+	dma_dentry = debugfs_create_dir("dma", NULL);
+
+	(void) debugfs_create_file("status",
+				   S_IFREG | S_IRUGO,
+				   dma_dentry, NULL,
+				   &coh901318_debugfs_status_operations);
+	return 0;
+}
+
+static void __exit exit_coh901318_debugfs(void)
+{
+	debugfs_remove_recursive(dma_dentry);
+}
+
+module_init(init_coh901318_debugfs);
+module_exit(exit_coh901318_debugfs);
+#else
+
+#define COH901318_DEBUGFS_ASSIGN(x, y)
+
+#endif /* CONFIG_DEBUG_FS */
+
+static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct coh901318_chan, chan);
+}
+
+static inline dma_addr_t
+cohc_dev_addr(struct coh901318_chan *cohc)
+{
+	return cohc->base->platform->chan_conf[cohc->id].dev_addr;
+}
+
+static inline const struct coh901318_params *
+cohc_chan_param(struct coh901318_chan *cohc)
+{
+	return &cohc->base->platform->chan_conf[cohc->id].param;
+}
+
+static inline const struct coh_dma_channel *
+cohc_chan_conf(struct coh901318_chan *cohc)
+{
+	return &cohc->base->platform->chan_conf[cohc->id];
+}
+
+static void enable_powersave(struct coh901318_chan *cohc)
+{
+	unsigned long flags;
+	struct powersave *pm = &cohc->base->pm;
+
+	spin_lock_irqsave(&pm->lock, flags);
+
+	pm->started_channels &= ~(1ULL << cohc->id);
+
+	if (!pm->started_channels) {
+		/* DMA no longer intends to access memory */
+		cohc->base->platform->access_memory_state(cohc->base->dev,
+							  false);
+	}
+
+	spin_unlock_irqrestore(&pm->lock, flags);
+}
+static void disable_powersave(struct coh901318_chan *cohc)
+{
+	unsigned long flags;
+	struct powersave *pm = &cohc->base->pm;
+
+	spin_lock_irqsave(&pm->lock, flags);
+
+	if (!pm->started_channels) {
+		/* DMA intends to access memory */
+		cohc->base->platform->access_memory_state(cohc->base->dev,
+							  true);
+	}
+
+	pm->started_channels |= (1ULL << cohc->id);
+
+	spin_unlock_irqrestore(&pm->lock, flags);
+}
+
+static inline int coh901318_set_ctrl(struct coh901318_chan *cohc, u32 control)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	writel(control,
+	       virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING * channel);
+	return 0;
+}
+
+static inline int coh901318_set_conf(struct coh901318_chan *cohc, u32 conf)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	writel(conf,
+	       virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING*channel);
+	return 0;
+}
+
+
+static int coh901318_start(struct coh901318_chan *cohc)
+{
+	u32 val;
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	disable_powersave(cohc);
+
+	val = readl(virtbase + COH901318_CX_CFG +
+		    COH901318_CX_CFG_SPACING * channel);
+
+	/* Enable channel */
+	val |= COH901318_CX_CFG_CH_ENABLE;
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+
+	return 0;
+}
+
+static int coh901318_prep_linked_list(struct coh901318_chan *cohc,
+				      struct coh901318_lli *data)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	BUG_ON(readl(virtbase + COH901318_CX_STAT +
+		     COH901318_CX_STAT_SPACING*channel) &
+	       COH901318_CX_STAT_ACTIVE);
+
+	writel(data->src_addr,
+	       virtbase + COH901318_CX_SRC_ADDR +
+	       COH901318_CX_SRC_ADDR_SPACING * channel);
+
+	writel(data->dst_addr, virtbase +
+	       COH901318_CX_DST_ADDR +
+	       COH901318_CX_DST_ADDR_SPACING * channel);
+
+	writel(data->link_addr, virtbase + COH901318_CX_LNK_ADDR +
+	       COH901318_CX_LNK_ADDR_SPACING * channel);
+
+	writel(data->control, virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING * channel);
+
+	return 0;
+}
+static dma_cookie_t
+coh901318_assign_cookie(struct coh901318_chan *cohc,
+			struct coh901318_desc *cohd)
+{
+	dma_cookie_t cookie = cohc->chan.cookie;
+
+	if (++cookie < 0)
+		cookie = 1;
+
+	cohc->chan.cookie = cookie;
+	cohd->desc.cookie = cookie;
+
+	return cookie;
+}
+
+static struct coh901318_desc *
+coh901318_desc_get(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *desc;
+
+	if (list_empty(&cohc->free)) {
+		/* alloc new desc because we're out of used ones
+		 * TODO: alloc a pile of descs instead of just one,
+		 * avoid many small allocations.
+		 */
+		desc = kmalloc(sizeof(struct coh901318_desc), GFP_NOWAIT);
+		if (desc == NULL)
+			goto out;
+		INIT_LIST_HEAD(&desc->node);
+	} else {
+		/* Reuse an old desc. */
+		desc = list_first_entry(&cohc->free,
+					struct coh901318_desc,
+					node);
+		list_del(&desc->node);
+	}
+
+ out:
+	return desc;
+}
+
+static void
+coh901318_desc_free(struct coh901318_chan *cohc, struct coh901318_desc *cohd)
+{
+	list_add_tail(&cohd->node, &cohc->free);
+}
+
+/* call with irq lock held */
+static void
+coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc)
+{
+	list_add_tail(&desc->node, &cohc->active);
+
+	BUG_ON(cohc->pending_irqs != 0);
+
+	cohc->pending_irqs = desc->pending_irqs;
+}
+
+static struct coh901318_desc *
+coh901318_first_active_get(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *d;
+
+	if (list_empty(&cohc->active))
+		return NULL;
+
+	d = list_first_entry(&cohc->active,
+			     struct coh901318_desc,
+			     node);
+	return d;
+}
+
+static void
+coh901318_desc_remove(struct coh901318_desc *cohd)
+{
+	list_del(&cohd->node);
+}
+
+static void
+coh901318_desc_queue(struct coh901318_chan *cohc, struct coh901318_desc *desc)
+{
+	list_add_tail(&desc->node, &cohc->queue);
+}
+
+static struct coh901318_desc *
+coh901318_first_queued(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *d;
+
+	if (list_empty(&cohc->queue))
+		return NULL;
+
+	d = list_first_entry(&cohc->queue,
+			     struct coh901318_desc,
+			     node);
+	return d;
+}
+
+/*
+ * DMA start/stop controls
+ */
+u32 coh901318_get_bytes_left(struct dma_chan *chan)
+{
+	unsigned long flags;
+	u32 ret;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Read transfer count value */
+	ret = readl(cohc->base->virtbase +
+		    COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING *
+		    cohc->id) & COH901318_CX_CTRL_TC_VALUE_MASK;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(coh901318_get_bytes_left);
+
+
+/* Stops a transfer without losing data. Enables power save.
+   Use this function in conjunction with coh901318_continue(..)
+*/
+void coh901318_stop(struct dma_chan *chan)
+{
+	u32 val;
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Disable channel in HW */
+	val = readl(virtbase + COH901318_CX_CFG +
+		    COH901318_CX_CFG_SPACING * channel);
+
+	/* Stopping infinit transfer */
+	if ((val & COH901318_CX_CTRL_TC_ENABLE) == 0 &&
+	    (val & COH901318_CX_CFG_CH_ENABLE))
+		cohc->stopped = 1;
+
+
+	val &= ~COH901318_CX_CFG_CH_ENABLE;
+	/* Enable twice, HW bug work around */
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+
+	/* Spin-wait for it to actually go inactive */
+	while (readl(virtbase + COH901318_CX_STAT+COH901318_CX_STAT_SPACING *
+		     channel) & COH901318_CX_STAT_ACTIVE)
+		cpu_relax();
+
+	/* Check if we stopped an active job */
+	if ((readl(virtbase + COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING *
+		   channel) & COH901318_CX_CTRL_TC_VALUE_MASK) > 0)
+		cohc->stopped = 1;
+
+	enable_powersave(cohc);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+EXPORT_SYMBOL(coh901318_stop);
+
+/* Continues a transfer that has been stopped via 300_dma_stop(..).
+   Power save is handled.
+*/
+void coh901318_continue(struct dma_chan *chan)
+{
+	u32 val;
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	disable_powersave(cohc);
+
+	if (cohc->stopped) {
+		/* Enable channel in HW */
+		val = readl(cohc->base->virtbase + COH901318_CX_CFG +
+			    COH901318_CX_CFG_SPACING * channel);
+
+		val |= COH901318_CX_CFG_CH_ENABLE;
+
+		writel(val, cohc->base->virtbase + COH901318_CX_CFG +
+		       COH901318_CX_CFG_SPACING*channel);
+
+		cohc->stopped = 0;
+	}
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+EXPORT_SYMBOL(coh901318_continue);
+
+bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
+{
+	unsigned int ch_nr = (unsigned int) chan_id;
+
+	if (ch_nr == to_coh901318_chan(chan)->id)
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(coh901318_filter_id);
+
+/*
+ * DMA channel allocation
+ */
+static int coh901318_config(struct coh901318_chan *cohc,
+			    struct coh901318_params *param)
+{
+	unsigned long flags;
+	const struct coh901318_params *p;
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	if (param)
+		p = param;
+	else
+		p = &cohc->base->platform->chan_conf[channel].param;
+
+	/* Clear any pending BE or TC interrupt */
+	if (channel < 32) {
+		writel(1 << channel, virtbase + COH901318_BE_INT_CLEAR1);
+		writel(1 << channel, virtbase + COH901318_TC_INT_CLEAR1);
+	} else {
+		writel(1 << (channel - 32), virtbase +
+		       COH901318_BE_INT_CLEAR2);
+		writel(1 << (channel - 32), virtbase +
+		       COH901318_TC_INT_CLEAR2);
+	}
+
+	coh901318_set_conf(cohc, p->config);
+	coh901318_set_ctrl(cohc, p->ctrl_lli_last);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return 0;
+}
+
+/* must lock when calling this function
+ * start queued jobs, if any
+ * TODO: start all queued jobs in one go
+ *
+ * Returns descriptor if queued job is started otherwise NULL.
+ * If the queue is empty NULL is returned.
+ */
+static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *cohd_que;
+
+	/* start queued jobs, if any
+	 * TODO: transmit all queued jobs in one go
+	 */
+	cohd_que = coh901318_first_queued(cohc);
+
+	if (cohd_que != NULL) {
+		/* Remove from queue */
+		coh901318_desc_remove(cohd_que);
+		/* initiate DMA job */
+		cohc->busy = 1;
+
+		coh901318_desc_submit(cohc, cohd_que);
+
+		coh901318_prep_linked_list(cohc, cohd_que->data);
+
+		/* start dma job */
+		coh901318_start(cohc);
+
+	}
+
+	return cohd_que;
+}
+
+static void dma_tasklet(unsigned long data)
+{
+	struct coh901318_chan *cohc = (struct coh901318_chan *) data;
+	struct coh901318_desc *cohd_fin;
+	unsigned long flags;
+	dma_async_tx_callback callback;
+	void *callback_param;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* get first active entry from list */
+	cohd_fin = coh901318_first_active_get(cohc);
+
+	BUG_ON(cohd_fin->pending_irqs == 0);
+
+	if (cohd_fin == NULL)
+		goto err;
+
+	cohd_fin->pending_irqs--;
+	cohc->completed = cohd_fin->desc.cookie;
+
+	if (cohc->nbr_active_done == 0)
+		return;
+
+	if (!cohd_fin->pending_irqs) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
+	}
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d"
+		 " nbr_active_done %ld\n", __func__,
+		 cohc->id, cohc->pending_irqs, cohc->nbr_active_done);
+
+	/* callback to client */
+	callback = cohd_fin->desc.callback;
+	callback_param = cohd_fin->desc.callback_param;
+
+	if (!cohd_fin->pending_irqs) {
+		coh901318_desc_remove(cohd_fin);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd_fin);
+	}
+
+	if (cohc->nbr_active_done)
+		cohc->nbr_active_done--;
+
+	if (cohc->nbr_active_done) {
+		if (cohc_chan_conf(cohc)->priority_high)
+			tasklet_hi_schedule(&cohc->tasklet);
+		else
+			tasklet_schedule(&cohc->tasklet);
+	}
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	if (callback)
+		callback(callback_param);
+
+	return;
+
+ err:
+	spin_unlock_irqrestore(&cohc->lock, flags);
+	dev_err(COHC_2_DEV(cohc), "[%s] No active dma desc\n", __func__);
+}
+
+
+/* called from interrupt context */
+static void dma_tc_handle(struct coh901318_chan *cohc)
+{
+	BUG_ON(!cohc->allocated && (list_empty(&cohc->active) ||
+				    list_empty(&cohc->queue)));
+
+	if (!cohc->allocated)
+		return;
+
+	BUG_ON(cohc->pending_irqs == 0);
+
+	cohc->pending_irqs--;
+	cohc->nbr_active_done++;
+
+	if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL)
+		cohc->busy = 0;
+
+	BUG_ON(list_empty(&cohc->active));
+
+	if (cohc_chan_conf(cohc)->priority_high)
+		tasklet_hi_schedule(&cohc->tasklet);
+	else
+		tasklet_schedule(&cohc->tasklet);
+}
+
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	u32 status1;
+	u32 status2;
+	int i;
+	int ch;
+	struct coh901318_base *base  = dev_id;
+	struct coh901318_chan *cohc;
+	void __iomem *virtbase = base->virtbase;
+
+	status1 = readl(virtbase + COH901318_INT_STATUS1);
+	status2 = readl(virtbase + COH901318_INT_STATUS2);
+
+	if (unlikely(status1 == 0 && status2 == 0)) {
+		dev_warn(base->dev, "spurious DMA IRQ from no channel!\n");
+		return IRQ_HANDLED;
+	}
+
+	/* TODO: consider handle IRQ in tasklet here to
+	 *       minimize interrupt latency */
+
+	/* Check the first 32 DMA channels for IRQ */
+	while (status1) {
+		/* Find first bit set, return as a number. */
+		i = ffs(status1) - 1;
+		ch = i;
+
+		cohc = &base->chans[ch];
+		spin_lock(&cohc->lock);
+
+		/* Mask off this bit */
+		status1 &= ~(1 << i);
+		/* Check the individual channel bits */
+		if (test_bit(i, virtbase + COH901318_BE_INT_STATUS1)) {
+			dev_crit(COHC_2_DEV(cohc),
+				 "DMA bus error on channel %d!\n", ch);
+			BUG_ON(1);
+			/* Clear BE interrupt */
+			__set_bit(i, virtbase + COH901318_BE_INT_CLEAR1);
+		} else {
+			/* Caused by TC, really? */
+			if (unlikely(!test_bit(i, virtbase +
+					       COH901318_TC_INT_STATUS1))) {
+				dev_warn(COHC_2_DEV(cohc),
+					 "ignoring interrupt not caused by terminal count on channel %d\n", ch);
+				/* Clear TC interrupt */
+				BUG_ON(1);
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR1);
+			} else {
+				/* Enable powersave if transfer has finished */
+				if (!(readl(virtbase + COH901318_CX_STAT +
+					    COH901318_CX_STAT_SPACING*ch) &
+				      COH901318_CX_STAT_ENABLED)) {
+					enable_powersave(cohc);
+				}
+
+				/* Must clear TC interrupt before calling
+				 * dma_tc_handle
+				 * in case tc_handle initate a new dma job
+				 */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR1);
+
+				dma_tc_handle(cohc);
+			}
+		}
+		spin_unlock(&cohc->lock);
+	}
+
+	/* Check the remaining 32 DMA channels for IRQ */
+	while (status2) {
+		/* Find first bit set, return as a number. */
+		i = ffs(status2) - 1;
+		ch = i + 32;
+		cohc = &base->chans[ch];
+		spin_lock(&cohc->lock);
+
+		/* Mask off this bit */
+		status2 &= ~(1 << i);
+		/* Check the individual channel bits */
+		if (test_bit(i, virtbase + COH901318_BE_INT_STATUS2)) {
+			dev_crit(COHC_2_DEV(cohc),
+				 "DMA bus error on channel %d!\n", ch);
+			/* Clear BE interrupt */
+			BUG_ON(1);
+			__set_bit(i, virtbase + COH901318_BE_INT_CLEAR2);
+		} else {
+			/* Caused by TC, really? */
+			if (unlikely(!test_bit(i, virtbase +
+					       COH901318_TC_INT_STATUS2))) {
+				dev_warn(COHC_2_DEV(cohc),
+					 "ignoring interrupt not caused by terminal count on channel %d\n", ch);
+				/* Clear TC interrupt */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR2);
+				BUG_ON(1);
+			} else {
+				/* Enable powersave if transfer has finished */
+				if (!(readl(virtbase + COH901318_CX_STAT +
+					    COH901318_CX_STAT_SPACING*ch) &
+				      COH901318_CX_STAT_ENABLED)) {
+					enable_powersave(cohc);
+				}
+				/* Must clear TC interrupt before calling
+				 * dma_tc_handle
+				 * in case tc_handle initate a new dma job
+				 */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR2);
+
+				dma_tc_handle(cohc);
+			}
+		}
+		spin_unlock(&cohc->lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int coh901318_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct coh901318_chan	*cohc = to_coh901318_chan(chan);
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n",
+		 __func__, cohc->id);
+
+	if (chan->client_count > 1)
+		return -EBUSY;
+
+	coh901318_config(cohc, NULL);
+
+	cohc->allocated = 1;
+	cohc->completed = chan->cookie = 1;
+
+	return 1;
+}
+
+static void
+coh901318_free_chan_resources(struct dma_chan *chan)
+{
+	struct coh901318_chan	*cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Disable HW */
+	writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING*channel);
+	writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING*channel);
+
+	cohc->allocated = 0;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	chan->device->device_terminate_all(chan);
+}
+
+
+static dma_cookie_t
+coh901318_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct coh901318_desc *cohd = container_of(tx, struct coh901318_desc,
+						   desc);
+	struct coh901318_chan *cohc = to_coh901318_chan(tx->chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	tx->cookie = coh901318_assign_cookie(cohc, cohd);
+
+	coh901318_desc_queue(cohc, cohd);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return tx->cookie;
+}
+
+static struct dma_async_tx_descriptor *
+coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		      size_t size, unsigned long flags)
+{
+	struct coh901318_lli *data;
+	struct coh901318_desc *cohd;
+	unsigned long flg;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int lli_len;
+	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
+
+	spin_lock_irqsave(&cohc->lock, flg);
+
+	dev_vdbg(COHC_2_DEV(cohc),
+		 "[%s] channel %d src 0x%x dest 0x%x size %d\n",
+		 __func__, cohc->id, src, dest, size);
+
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Trigger interrupt after last lli */
+		ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE;
+
+	lli_len = size >> MAX_DMA_PACKET_SIZE_SHIFT;
+	if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size)
+		lli_len++;
+
+	data = coh901318_lli_alloc(&cohc->base->pool, lli_len);
+
+	if (data == NULL)
+		goto err;
+
+	cohd = coh901318_desc_get(cohc);
+	cohd->sg = NULL;
+	cohd->sg_len = 0;
+	cohd->data = data;
+
+	cohd->pending_irqs =
+		coh901318_lli_fill_memcpy(
+				&cohc->base->pool, data, src, size, dest,
+				cohc_chan_param(cohc)->ctrl_lli_chained,
+				ctrl_last);
+	cohd->flags = flags;
+
+	COH_DBG(coh901318_list_print(cohc, data));
+
+	dma_async_tx_descriptor_init(&cohd->desc, chan);
+
+	cohd->desc.tx_submit = coh901318_tx_submit;
+
+	spin_unlock_irqrestore(&cohc->lock, flg);
+
+	return &cohd->desc;
+ err:
+	spin_unlock_irqrestore(&cohc->lock, flg);
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+			unsigned int sg_len, enum dma_data_direction direction,
+			unsigned long flags)
+{
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	struct coh901318_lli *data;
+	struct coh901318_desc *cohd;
+	struct scatterlist *sg;
+	int len = 0;
+	int size;
+	int i;
+	u32 ctrl_chained = cohc_chan_param(cohc)->ctrl_lli_chained;
+	u32 ctrl = cohc_chan_param(cohc)->ctrl_lli;
+	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
+	unsigned long flg;
+
+	if (!sgl)
+		goto out;
+	if (sgl->length == 0)
+		goto out;
+
+	spin_lock_irqsave(&cohc->lock, flg);
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] sg_len %d dir %d\n",
+		 __func__, sg_len, direction);
+
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Trigger interrupt after last lli */
+		ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE;
+
+	cohd = coh901318_desc_get(cohc);
+	cohd->sg = NULL;
+	cohd->sg_len = 0;
+	cohd->dir = direction;
+
+	if (direction == DMA_TO_DEVICE) {
+		u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE |
+			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE;
+
+		ctrl_chained |= tx_flags;
+		ctrl_last |= tx_flags;
+		ctrl |= tx_flags;
+	} else if (direction == DMA_FROM_DEVICE) {
+		u32 rx_flags = COH901318_CX_CTRL_PRDD_DEST |
+			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE;
+
+		ctrl_chained |= rx_flags;
+		ctrl_last |= rx_flags;
+		ctrl |= rx_flags;
+	} else
+		goto err_direction;
+
+	dma_async_tx_descriptor_init(&cohd->desc, chan);
+
+	cohd->desc.tx_submit = coh901318_tx_submit;
+
+
+	/* The dma only supports transmitting packages up to
+	 * MAX_DMA_PACKET_SIZE. Calculate to total number of
+	 * dma elemts required to send the entire sg list
+	 */
+	for_each_sg(sgl, sg, sg_len, i) {
+		unsigned int factor;
+		size = sg_dma_len(sg);
+
+		if (size <= MAX_DMA_PACKET_SIZE) {
+			len++;
+			continue;
+		}
+
+		factor = size >> MAX_DMA_PACKET_SIZE_SHIFT;
+		if ((factor << MAX_DMA_PACKET_SIZE_SHIFT) < size)
+			factor++;
+
+		len += factor;
+	}
+
+	data = coh901318_lli_alloc(&cohc->base->pool, len);
+
+	if (data == NULL)
+		goto err_dma_alloc;
+
+	/* initiate allocated data list */
+	cohd->pending_irqs =
+		coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
+				      cohc_dev_addr(cohc),
+				      ctrl_chained,
+				      ctrl,
+				      ctrl_last,
+				      direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
+	cohd->data = data;
+
+	cohd->flags = flags;
+
+	COH_DBG(coh901318_list_print(cohc, data));
+
+	spin_unlock_irqrestore(&cohc->lock, flg);
+
+	return &cohd->desc;
+ err_dma_alloc:
+ err_direction:
+	coh901318_desc_remove(cohd);
+	coh901318_desc_free(cohc, cohd);
+	spin_unlock_irqrestore(&cohc->lock, flg);
+ out:
+	return NULL;
+}
+
+static enum dma_status
+coh901318_is_tx_complete(struct dma_chan *chan,
+			 dma_cookie_t cookie, dma_cookie_t *done,
+			 dma_cookie_t *used)
+{
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+	int ret;
+
+	last_complete = cohc->completed;
+	last_used = chan->cookie;
+
+	ret = dma_async_is_complete(cookie, last_complete, last_used);
+
+	if (done)
+		*done = last_complete;
+	if (used)
+		*used = last_used;
+
+	return ret;
+}
+
+static void
+coh901318_issue_pending(struct dma_chan *chan)
+{
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Busy means that pending jobs are already being processed */
+	if (!cohc->busy)
+		coh901318_queue_start(cohc);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+
+static void
+coh901318_terminate_all(struct dma_chan *chan)
+{
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	struct coh901318_desc *cohd;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	coh901318_stop(chan);
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Clear any pending BE or TC interrupt */
+	if (cohc->id < 32) {
+		writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
+		writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
+	} else {
+		writel(1 << (cohc->id - 32), virtbase +
+		       COH901318_BE_INT_CLEAR2);
+		writel(1 << (cohc->id - 32), virtbase +
+		       COH901318_TC_INT_CLEAR2);
+	}
+
+	enable_powersave(cohc);
+
+	while ((cohd = coh901318_first_active_get(cohc))) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd->data);
+
+		coh901318_desc_remove(cohd);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd);
+	}
+
+	while ((cohd = coh901318_first_queued(cohc))) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd->data);
+
+		coh901318_desc_remove(cohd);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd);
+	}
+
+
+	cohc->nbr_active_done = 0;
+	cohc->busy = 0;
+	cohc->pending_irqs = 0;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
+			 struct coh901318_base *base)
+{
+	int chans_i;
+	int i = 0;
+	struct coh901318_chan *cohc;
+
+	INIT_LIST_HEAD(&dma->channels);
+
+	for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) {
+		for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) {
+			cohc = &base->chans[i];
+
+			cohc->base = base;
+			cohc->chan.device = dma;
+			cohc->id = i;
+
+			/* TODO: do we really need this lock if only one
+			 * client is connected to each channel?
+			 */
+
+			spin_lock_init(&cohc->lock);
+
+			cohc->pending_irqs = 0;
+			cohc->nbr_active_done = 0;
+			cohc->busy = 0;
+			INIT_LIST_HEAD(&cohc->free);
+			INIT_LIST_HEAD(&cohc->active);
+			INIT_LIST_HEAD(&cohc->queue);
+
+			tasklet_init(&cohc->tasklet, dma_tasklet,
+				     (unsigned long) cohc);
+
+			list_add_tail(&cohc->chan.device_node,
+				      &dma->channels);
+		}
+	}
+}
+
+static int __init coh901318_probe(struct platform_device *pdev)
+{
+	int err = 0;
+	struct coh901318_platform *pdata;
+	struct coh901318_base *base;
+	int irq;
+	struct resource *io;
+
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!io)
+		goto err_get_resource;
+
+	/* Map DMA controller registers to virtual memory */
+	if (request_mem_region(io->start,
+			       resource_size(io),
+			       pdev->dev.driver->name) == NULL) {
+		err = -EBUSY;
+		goto err_request_mem;
+	}
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		goto err_no_platformdata;
+
+	base = kmalloc(ALIGN(sizeof(struct coh901318_base), 4) +
+		       pdata->max_channels *
+		       sizeof(struct coh901318_chan),
+		       GFP_KERNEL);
+	if (!base)
+		goto err_alloc_coh_dma_channels;
+
+	base->chans = ((void *)base) + ALIGN(sizeof(struct coh901318_base), 4);
+
+	base->virtbase = ioremap(io->start, resource_size(io));
+	if (!base->virtbase) {
+		err = -ENOMEM;
+		goto err_no_ioremap;
+	}
+
+	base->dev = &pdev->dev;
+	base->platform = pdata;
+	spin_lock_init(&base->pm.lock);
+	base->pm.started_channels = 0;
+
+	COH901318_DEBUGFS_ASSIGN(debugfs_dma_base, base);
+
+	platform_set_drvdata(pdev, base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto err_no_irq;
+
+	err = request_irq(irq, dma_irq_handler, IRQF_DISABLED,
+			  "coh901318", base);
+	if (err) {
+		dev_crit(&pdev->dev,
+			 "Cannot allocate IRQ for DMA controller!\n");
+		goto err_request_irq;
+	}
+
+	err = coh901318_pool_create(&base->pool, &pdev->dev,
+				    sizeof(struct coh901318_lli),
+				    32);
+	if (err)
+		goto err_pool_create;
+
+	/* init channels for device transfers */
+	coh901318_base_init(&base->dma_slave,  base->platform->chans_slave,
+			    base);
+
+	dma_cap_zero(base->dma_slave.cap_mask);
+	dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask);
+
+	base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources;
+	base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources;
+	base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
+	base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete;
+	base->dma_slave.device_issue_pending = coh901318_issue_pending;
+	base->dma_slave.device_terminate_all = coh901318_terminate_all;
+	base->dma_slave.dev = &pdev->dev;
+
+	err = dma_async_device_register(&base->dma_slave);
+
+	if (err)
+		goto err_register_slave;
+
+	/* init channels for memcpy */
+	coh901318_base_init(&base->dma_memcpy, base->platform->chans_memcpy,
+			    base);
+
+	dma_cap_zero(base->dma_memcpy.cap_mask);
+	dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
+
+	base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources;
+	base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources;
+	base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
+	base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete;
+	base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
+	base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
+	base->dma_memcpy.dev = &pdev->dev;
+	err = dma_async_device_register(&base->dma_memcpy);
+
+	if (err)
+		goto err_register_memcpy;
+
+	dev_dbg(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
+		(u32) base->virtbase);
+
+	return err;
+
+ err_register_memcpy:
+	dma_async_device_unregister(&base->dma_slave);
+ err_register_slave:
+	coh901318_pool_destroy(&base->pool);
+ err_pool_create:
+	free_irq(platform_get_irq(pdev, 0), base);
+ err_request_irq:
+ err_no_irq:
+	iounmap(base->virtbase);
+ err_no_ioremap:
+	kfree(base);
+ err_alloc_coh_dma_channels:
+ err_no_platformdata:
+	release_mem_region(pdev->resource->start,
+			   resource_size(pdev->resource));
+ err_request_mem:
+ err_get_resource:
+	return err;
+}
+
+static int __exit coh901318_remove(struct platform_device *pdev)
+{
+	struct coh901318_base *base = platform_get_drvdata(pdev);
+
+	dma_async_device_unregister(&base->dma_memcpy);
+	dma_async_device_unregister(&base->dma_slave);
+	coh901318_pool_destroy(&base->pool);
+	free_irq(platform_get_irq(pdev, 0), base);
+	iounmap(base->virtbase);
+	kfree(base);
+	release_mem_region(pdev->resource->start,
+			   resource_size(pdev->resource));
+	return 0;
+}
+
+
+static struct platform_driver coh901318_driver = {
+	.remove = __exit_p(coh901318_remove),
+	.driver = {
+		.name	= "coh901318",
+	},
+};
+
+int __init coh901318_init(void)
+{
+	return platform_driver_probe(&coh901318_driver, coh901318_probe);
+}
+subsys_initcall(coh901318_init);
+
+void __exit coh901318_exit(void)
+{
+	platform_driver_unregister(&coh901318_driver);
+}
+module_exit(coh901318_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Per Friden");
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/coh901318_lli.c linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.c
--- linux-libre-2.6.32-gnu1/drivers/dma/coh901318_lli.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,318 @@
+/*
+ * driver/dma/coh901318_lli.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Support functions for handling lli for dma
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/dmapool.h>
+#include <linux/memory.h>
+#include <mach/coh901318.h>
+
+#include "coh901318_lli.h"
+
+#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
+#define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0)
+#define DEBUGFS_POOL_COUNTER_ADD(pool, add) (pool->debugfs_pool_counter += add)
+#else
+#define DEBUGFS_POOL_COUNTER_RESET(pool)
+#define DEBUGFS_POOL_COUNTER_ADD(pool, add)
+#endif
+
+static struct coh901318_lli *
+coh901318_lli_next(struct coh901318_lli *data)
+{
+	if (data == NULL || data->link_addr == 0)
+		return NULL;
+
+	return (struct coh901318_lli *) data->virt_link_addr;
+}
+
+int coh901318_pool_create(struct coh901318_pool *pool,
+			  struct device *dev,
+			  size_t size, size_t align)
+{
+	spin_lock_init(&pool->lock);
+	pool->dev = dev;
+	pool->dmapool = dma_pool_create("lli_pool", dev, size, align, 0);
+
+	DEBUGFS_POOL_COUNTER_RESET(pool);
+	return 0;
+}
+
+int coh901318_pool_destroy(struct coh901318_pool *pool)
+{
+
+	dma_pool_destroy(pool->dmapool);
+	return 0;
+}
+
+struct coh901318_lli *
+coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
+{
+	int i;
+	struct coh901318_lli *head;
+	struct coh901318_lli *lli;
+	struct coh901318_lli *lli_prev;
+	dma_addr_t phy;
+
+	if (len == 0)
+		goto err;
+
+	spin_lock(&pool->lock);
+
+	head = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy);
+
+	if (head == NULL)
+		goto err;
+
+	DEBUGFS_POOL_COUNTER_ADD(pool, 1);
+
+	lli = head;
+	lli->phy_this = phy;
+
+	for (i = 1; i < len; i++) {
+		lli_prev = lli;
+
+		lli = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy);
+
+		if (lli == NULL)
+			goto err_clean_up;
+
+		DEBUGFS_POOL_COUNTER_ADD(pool, 1);
+		lli->phy_this = phy;
+
+		lli_prev->link_addr = phy;
+		lli_prev->virt_link_addr = lli;
+	}
+
+	lli->link_addr = 0x00000000U;
+
+	spin_unlock(&pool->lock);
+
+	return head;
+
+ err:
+	spin_unlock(&pool->lock);
+	return NULL;
+
+ err_clean_up:
+	lli_prev->link_addr = 0x00000000U;
+	spin_unlock(&pool->lock);
+	coh901318_lli_free(pool, &head);
+	return NULL;
+}
+
+void coh901318_lli_free(struct coh901318_pool *pool,
+			struct coh901318_lli **lli)
+{
+	struct coh901318_lli *l;
+	struct coh901318_lli *next;
+
+	if (lli == NULL)
+		return;
+
+	l = *lli;
+
+	if (l == NULL)
+		return;
+
+	spin_lock(&pool->lock);
+
+	while (l->link_addr) {
+		next = l->virt_link_addr;
+		dma_pool_free(pool->dmapool, l, l->phy_this);
+		DEBUGFS_POOL_COUNTER_ADD(pool, -1);
+		l = next;
+	}
+	dma_pool_free(pool->dmapool, l, l->phy_this);
+	DEBUGFS_POOL_COUNTER_ADD(pool, -1);
+
+	spin_unlock(&pool->lock);
+	*lli = NULL;
+}
+
+int
+coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t source, unsigned int size,
+			  dma_addr_t destination, u32 ctrl_chained,
+			  u32 ctrl_eom)
+{
+	int s = size;
+	dma_addr_t src = source;
+	dma_addr_t dst = destination;
+
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	while (lli->link_addr) {
+		lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
+		lli->src_addr = src;
+		lli->dst_addr = dst;
+
+		s -= MAX_DMA_PACKET_SIZE;
+		lli = coh901318_lli_next(lli);
+
+		src += MAX_DMA_PACKET_SIZE;
+		dst += MAX_DMA_PACKET_SIZE;
+	}
+
+	lli->control = ctrl_eom | s;
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	/* One irq per single transfer */
+	return 1;
+}
+
+int
+coh901318_lli_fill_single(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t buf, unsigned int size,
+			  dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_eom,
+			  enum dma_data_direction dir)
+{
+	int s = size;
+	dma_addr_t src;
+	dma_addr_t dst;
+
+
+	if (dir == DMA_TO_DEVICE) {
+		src = buf;
+		dst = dev_addr;
+
+	} else if (dir == DMA_FROM_DEVICE) {
+
+		src = dev_addr;
+		dst = buf;
+	} else {
+		return -EINVAL;
+	}
+
+	while (lli->link_addr) {
+		size_t block_size = MAX_DMA_PACKET_SIZE;
+		lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
+
+		/* If we are on the next-to-final block and there will
+		 * be less than half a DMA packet left for the last
+		 * block, then we want to make this block a little
+		 * smaller to balance the sizes. This is meant to
+		 * avoid too small transfers if the buffer size is
+		 * (MAX_DMA_PACKET_SIZE*N + 1) */
+		if (s < (MAX_DMA_PACKET_SIZE + MAX_DMA_PACKET_SIZE/2))
+			block_size = MAX_DMA_PACKET_SIZE/2;
+
+		s -= block_size;
+		lli->src_addr = src;
+		lli->dst_addr = dst;
+
+		lli = coh901318_lli_next(lli);
+
+		if (dir == DMA_TO_DEVICE)
+			src += block_size;
+		else if (dir == DMA_FROM_DEVICE)
+			dst += block_size;
+	}
+
+	lli->control = ctrl_eom | s;
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	/* One irq per single transfer */
+	return 1;
+}
+
+int
+coh901318_lli_fill_sg(struct coh901318_pool *pool,
+		      struct coh901318_lli *lli,
+		      struct scatterlist *sgl, unsigned int nents,
+		      dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl,
+		      u32 ctrl_last,
+		      enum dma_data_direction dir, u32 ctrl_irq_mask)
+{
+	int i;
+	struct scatterlist *sg;
+	u32 ctrl_sg;
+	dma_addr_t src = 0;
+	dma_addr_t dst = 0;
+	int nbr_of_irq = 0;
+	u32 bytes_to_transfer;
+	u32 elem_size;
+
+	if (lli == NULL)
+		goto err;
+
+	spin_lock(&pool->lock);
+
+	if (dir == DMA_TO_DEVICE)
+		dst = dev_addr;
+	else if (dir == DMA_FROM_DEVICE)
+		src = dev_addr;
+	else
+		goto err;
+
+	for_each_sg(sgl, sg, nents, i) {
+		if (sg_is_chain(sg)) {
+			/* sg continues to the next sg-element don't
+			 * send ctrl_finish until the last
+			 * sg-element in the chain
+			 */
+			ctrl_sg = ctrl_chained;
+		} else if (i == nents - 1)
+			ctrl_sg = ctrl_last;
+		else
+			ctrl_sg = ctrl ? ctrl : ctrl_last;
+
+
+		if ((ctrl_sg & ctrl_irq_mask))
+			nbr_of_irq++;
+
+		if (dir == DMA_TO_DEVICE)
+			/* increment source address */
+			src = sg_dma_address(sg);
+		else
+			/* increment destination address */
+			dst =  sg_dma_address(sg);
+
+		bytes_to_transfer = sg_dma_len(sg);
+
+		while (bytes_to_transfer) {
+			u32 val;
+
+			if (bytes_to_transfer > MAX_DMA_PACKET_SIZE) {
+				elem_size = MAX_DMA_PACKET_SIZE;
+				val = ctrl_chained;
+			} else {
+				elem_size = bytes_to_transfer;
+				val = ctrl_sg;
+			}
+
+			lli->control = val | elem_size;
+			lli->src_addr = src;
+			lli->dst_addr = dst;
+
+			if (dir == DMA_FROM_DEVICE)
+				dst += elem_size;
+			else
+				src += elem_size;
+
+			BUG_ON(lli->link_addr & 3);
+
+			bytes_to_transfer -= elem_size;
+			lli = coh901318_lli_next(lli);
+		}
+
+	}
+	spin_unlock(&pool->lock);
+
+	/* There can be many IRQs per sg transfer */
+	return nbr_of_irq;
+ err:
+	spin_unlock(&pool->lock);
+	return -EINVAL;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/coh901318_lli.h linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.h
--- linux-libre-2.6.32-gnu1/drivers/dma/coh901318_lli.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/coh901318_lli.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,124 @@
+/*
+ * driver/dma/coh901318_lli.h
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Support functions for handling lli for coh901318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef COH901318_LLI_H
+#define COH901318_LLI_H
+
+#include <mach/coh901318.h>
+
+struct device;
+
+struct coh901318_pool {
+	spinlock_t lock;
+	struct dma_pool *dmapool;
+	struct device *dev;
+
+#ifdef CONFIG_DEBUG_FS
+	int debugfs_pool_counter;
+#endif
+};
+
+struct device;
+/**
+ * coh901318_pool_create() - Creates an dma pool for lli:s
+ * @pool: pool handle
+ * @dev: dma device
+ * @lli_nbr: number of lli:s in the pool
+ * @algin: adress alignemtn of lli:s
+ * returns 0 on success otherwise none zero
+ */
+int coh901318_pool_create(struct coh901318_pool *pool,
+			  struct device *dev,
+			  size_t lli_nbr, size_t align);
+
+/**
+ * coh901318_pool_destroy() - Destroys the dma pool
+ * @pool: pool handle
+ * returns 0 on success otherwise none zero
+ */
+int coh901318_pool_destroy(struct coh901318_pool *pool);
+
+/**
+ * coh901318_lli_alloc() - Allocates a linked list
+ *
+ * @pool: pool handle
+ * @len: length to list
+ * return: none NULL if success otherwise NULL
+ */
+struct coh901318_lli *
+coh901318_lli_alloc(struct coh901318_pool *pool,
+		    unsigned int len);
+
+/**
+ * coh901318_lli_free() - Returns the linked list items to the pool
+ * @pool: pool handle
+ * @lli: reference to lli pointer to be freed
+ */
+void coh901318_lli_free(struct coh901318_pool *pool,
+			struct coh901318_lli **lli);
+
+/**
+ * coh901318_lli_fill_memcpy() - Prepares the lli:s for dma memcpy
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @src: src address
+ * @size: transfer size
+ * @dst: destination address
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl_last: ctrl for the last lli
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t src, unsigned int size,
+			  dma_addr_t dst, u32 ctrl_chained, u32 ctrl_last);
+
+/**
+ * coh901318_lli_fill_single() - Prepares the lli:s for dma single transfer
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @buf: transfer buffer
+ * @size: transfer size
+ * @dev_addr: address of periphal
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl_last: ctrl for the last lli
+ * @dir: direction of transfer (to or from device)
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_single(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t buf, unsigned int size,
+			  dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_last,
+			  enum dma_data_direction dir);
+
+/**
+ * coh901318_lli_fill_single() - Prepares the lli:s for dma scatter list transfer
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @sg: scatter gather list
+ * @nents: number of entries in sg
+ * @dev_addr: address of periphal
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl: ctrl of middle lli
+ * @ctrl_last: ctrl for the last lli
+ * @dir: direction of transfer (to or from device)
+ * @ctrl_irq_mask: ctrl mask for CPU interrupt
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_sg(struct coh901318_pool *pool,
+		      struct coh901318_lli *lli,
+		      struct scatterlist *sg, unsigned int nents,
+		      dma_addr_t dev_addr, u32 ctrl_chained,
+		      u32 ctrl, u32 ctrl_last,
+		      enum dma_data_direction dir, u32 ctrl_irq_mask);
+
+#endif /* COH901318_LLI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/dmaengine.c linux-libre-2.6.33-gnu1/drivers/dma/dmaengine.c
--- linux-libre-2.6.32-gnu1/drivers/dma/dmaengine.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/dmaengine.c	2010-02-24 13:52:17.000000000 -0500
@@ -326,14 +326,7 @@ arch_initcall(dma_channel_table_init);
  */
 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
 {
-	struct dma_chan *chan;
-	int cpu;
-
-	cpu = get_cpu();
-	chan = per_cpu_ptr(channel_table[tx_type], cpu)->chan;
-	put_cpu();
-
-	return chan;
+	return this_cpu_read(channel_table[tx_type]->chan);
 }
 EXPORT_SYMBOL(dma_find_channel);
 
@@ -833,6 +826,7 @@ void dma_async_device_unregister(struct
 		chan->dev->chan = NULL;
 		mutex_unlock(&dma_list_mutex);
 		device_unregister(&chan->dev->device);
+		free_percpu(chan->local);
 	}
 }
 EXPORT_SYMBOL(dma_async_device_unregister);
@@ -857,7 +851,6 @@ dma_async_memcpy_buf_to_buf(struct dma_c
 	struct dma_async_tx_descriptor *tx;
 	dma_addr_t dma_dest, dma_src;
 	dma_cookie_t cookie;
-	int cpu;
 	unsigned long flags;
 
 	dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE);
@@ -876,10 +869,10 @@ dma_async_memcpy_buf_to_buf(struct dma_c
 	tx->callback = NULL;
 	cookie = tx->tx_submit(tx);
 
-	cpu = get_cpu();
-	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
-	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
-	put_cpu();
+	preempt_disable();
+	__this_cpu_add(chan->local->bytes_transferred, len);
+	__this_cpu_inc(chan->local->memcpy_count);
+	preempt_enable();
 
 	return cookie;
 }
@@ -906,7 +899,6 @@ dma_async_memcpy_buf_to_pg(struct dma_ch
 	struct dma_async_tx_descriptor *tx;
 	dma_addr_t dma_dest, dma_src;
 	dma_cookie_t cookie;
-	int cpu;
 	unsigned long flags;
 
 	dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE);
@@ -923,10 +915,10 @@ dma_async_memcpy_buf_to_pg(struct dma_ch
 	tx->callback = NULL;
 	cookie = tx->tx_submit(tx);
 
-	cpu = get_cpu();
-	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
-	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
-	put_cpu();
+	preempt_disable();
+	__this_cpu_add(chan->local->bytes_transferred, len);
+	__this_cpu_inc(chan->local->memcpy_count);
+	preempt_enable();
 
 	return cookie;
 }
@@ -955,7 +947,6 @@ dma_async_memcpy_pg_to_pg(struct dma_cha
 	struct dma_async_tx_descriptor *tx;
 	dma_addr_t dma_dest, dma_src;
 	dma_cookie_t cookie;
-	int cpu;
 	unsigned long flags;
 
 	dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE);
@@ -973,10 +964,10 @@ dma_async_memcpy_pg_to_pg(struct dma_cha
 	tx->callback = NULL;
 	cookie = tx->tx_submit(tx);
 
-	cpu = get_cpu();
-	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
-	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
-	put_cpu();
+	preempt_disable();
+	__this_cpu_add(chan->local->bytes_transferred, len);
+	__this_cpu_inc(chan->local->memcpy_count);
+	preempt_enable();
 
 	return cookie;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/dmatest.c linux-libre-2.6.33-gnu1/drivers/dma/dmatest.c
--- linux-libre-2.6.32-gnu1/drivers/dma/dmatest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/dmatest.c	2010-02-24 13:52:17.000000000 -0500
@@ -298,10 +298,6 @@ static int dmatest_func(void *data)
 
 		total_tests++;
 
-		len = dmatest_random() % test_buf_size + 1;
-		src_off = dmatest_random() % (test_buf_size - len + 1);
-		dst_off = dmatest_random() % (test_buf_size - len + 1);
-
 		/* honor alignment restrictions */
 		if (thread->type == DMA_MEMCPY)
 			align = dev->copy_align;
@@ -310,7 +306,19 @@ static int dmatest_func(void *data)
 		else if (thread->type == DMA_PQ)
 			align = dev->pq_align;
 
+		if (1 << align > test_buf_size) {
+			pr_err("%u-byte buffer too small for %d-byte alignment\n",
+			       test_buf_size, 1 << align);
+			break;
+		}
+
+		len = dmatest_random() % test_buf_size + 1;
 		len = (len >> align) << align;
+		if (!len)
+			len = 1 << align;
+		src_off = dmatest_random() % (test_buf_size - len + 1);
+		dst_off = dmatest_random() % (test_buf_size - len + 1);
+
 		src_off = (src_off >> align) << align;
 		dst_off = (dst_off >> align) << align;
 
@@ -459,7 +467,7 @@ err_srcs:
 
 	if (iterations > 0)
 		while (!kthread_should_stop()) {
-			DECLARE_WAIT_QUEUE_HEAD(wait_dmatest_exit);
+			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
 			interruptible_sleep_on(&wait_dmatest_exit);
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/dw_dmac.c linux-libre-2.6.33-gnu1/drivers/dma/dw_dmac.c
--- linux-libre-2.6.32-gnu1/drivers/dma/dw_dmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/dw_dmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1270,8 +1270,6 @@ static int __init dw_probe(struct platfo
 		goto err_kfree;
 	}
 
-	memset(dw, 0, sizeof *dw);
-
 	dw->regs = ioremap(io->start, DW_REGLEN);
 	if (!dw->regs) {
 		err = -ENOMEM;
@@ -1427,7 +1425,7 @@ static int dw_resume_noirq(struct device
 	return 0;
 }
 
-static struct dev_pm_ops dw_dev_pm_ops = {
+static const struct dev_pm_ops dw_dev_pm_ops = {
 	.suspend_noirq = dw_suspend_noirq,
 	.resume_noirq = dw_resume_noirq,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma.c linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.c
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -1032,7 +1032,7 @@ int __devinit ioat_probe(struct ioatdma_
 	dma->dev = &pdev->dev;
 
 	if (!dma->chancnt) {
-		dev_err(dev, "zero channels detected\n");
+		dev_err(dev, "channel enumeration error\n");
 		goto err_setup_interrupts;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma.h linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,6 +60,7 @@
  * @dca: direct cache access context
  * @intr_quirk: interrupt setup quirk (for ioat_v1 devices)
  * @enumerate_channels: hw version specific channel enumeration
+ * @reset_hw: hw version specific channel (re)initialization
  * @cleanup_tasklet: select between the v2 and v3 cleanup routines
  * @timer_fn: select between the v2 and v3 timer watchdog routines
  * @self_test: hardware version specific self test for each supported op type
@@ -78,6 +79,7 @@ struct ioatdma_device {
 	struct dca_provider *dca;
 	void (*intr_quirk)(struct ioatdma_device *device);
 	int (*enumerate_channels)(struct ioatdma_device *device);
+	int (*reset_hw)(struct ioat_chan_common *chan);
 	void (*cleanup_tasklet)(unsigned long data);
 	void (*timer_fn)(unsigned long data);
 	int (*self_test)(struct ioatdma_device *device);
@@ -264,6 +266,22 @@ static inline void ioat_suspend(struct i
 	writeb(IOAT_CHANCMD_SUSPEND, chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
 }
 
+static inline void ioat_reset(struct ioat_chan_common *chan)
+{
+	u8 ver = chan->device->version;
+
+	writeb(IOAT_CHANCMD_RESET, chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
+}
+
+static inline bool ioat_reset_pending(struct ioat_chan_common *chan)
+{
+	u8 ver = chan->device->version;
+	u8 cmd;
+
+	cmd = readb(chan->reg_base + IOAT_CHANCMD_OFFSET(ver));
+	return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET;
+}
+
 static inline void ioat_set_chainaddr(struct ioat_dma_chan *ioat, u64 addr)
 {
 	struct ioat_chan_common *chan = &ioat->base;
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v2.c linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.c
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.c	2010-02-24 13:52:17.000000000 -0500
@@ -239,20 +239,50 @@ void __ioat2_restart_chan(struct ioat2_d
 		__ioat2_start_null_desc(ioat);
 }
 
-static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
+int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
 {
-	struct ioat_chan_common *chan = &ioat->base;
-	unsigned long phys_complete;
+	unsigned long end = jiffies + tmo;
+	int err = 0;
 	u32 status;
 
 	status = ioat_chansts(chan);
 	if (is_ioat_active(status) || is_ioat_idle(status))
 		ioat_suspend(chan);
 	while (is_ioat_active(status) || is_ioat_idle(status)) {
+		if (tmo && time_after(jiffies, end)) {
+			err = -ETIMEDOUT;
+			break;
+		}
 		status = ioat_chansts(chan);
 		cpu_relax();
 	}
 
+	return err;
+}
+
+int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo)
+{
+	unsigned long end = jiffies + tmo;
+	int err = 0;
+
+	ioat_reset(chan);
+	while (ioat_reset_pending(chan)) {
+		if (end && time_after(jiffies, end)) {
+			err = -ETIMEDOUT;
+			break;
+		}
+		cpu_relax();
+	}
+
+	return err;
+}
+
+static void ioat2_restart_channel(struct ioat2_dma_chan *ioat)
+{
+	struct ioat_chan_common *chan = &ioat->base;
+	unsigned long phys_complete;
+
+	ioat2_quiesce(chan, 0);
 	if (ioat_cleanup_preamble(chan, &phys_complete))
 		__cleanup(ioat, phys_complete);
 
@@ -318,6 +348,19 @@ void ioat2_timer_event(unsigned long dat
 	spin_unlock_bh(&chan->cleanup_lock);
 }
 
+static int ioat2_reset_hw(struct ioat_chan_common *chan)
+{
+	/* throw away whatever the channel was doing and get it initialized */
+	u32 chanerr;
+
+	ioat2_quiesce(chan, msecs_to_jiffies(100));
+
+	chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+	writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
+
+	return ioat2_reset_sync(chan, msecs_to_jiffies(200));
+}
+
 /**
  * ioat2_enumerate_channels - find and initialize the device's channels
  * @device: the device to be enumerated
@@ -360,6 +403,10 @@ int ioat2_enumerate_channels(struct ioat
 				  (unsigned long) ioat);
 		ioat->xfercap_log = xfercap_log;
 		spin_lock_init(&ioat->ring_lock);
+		if (device->reset_hw(&ioat->base)) {
+			i = 0;
+			break;
+		}
 	}
 	dma->chancnt = i;
 	return i;
@@ -467,7 +514,6 @@ int ioat2_alloc_chan_resources(struct dm
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
 	struct ioat_chan_common *chan = &ioat->base;
 	struct ioat_ring_ent **ring;
-	u32 chanerr;
 	int order;
 
 	/* have we already been set up? */
@@ -477,12 +523,6 @@ int ioat2_alloc_chan_resources(struct dm
 	/* Setup register to interrupt and write completion status on error */
 	writew(IOAT_CHANCTRL_RUN, chan->reg_base + IOAT_CHANCTRL_OFFSET);
 
-	chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
-	if (chanerr) {
-		dev_err(to_dev(chan), "CHANERR = %x, clearing\n", chanerr);
-		writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
-	}
-
 	/* allocate a completion writeback area */
 	/* doing 2 32bit writes to mmio since 1 64b write doesn't work */
 	chan->completion = pci_pool_alloc(chan->device->completion_pool,
@@ -746,13 +786,7 @@ void ioat2_free_chan_resources(struct dm
 	tasklet_disable(&chan->cleanup_task);
 	del_timer_sync(&chan->timer);
 	device->cleanup_tasklet((unsigned long) ioat);
-
-	/* Delay 100ms after reset to allow internal DMA logic to quiesce
-	 * before removing DMA descriptor resources.
-	 */
-	writeb(IOAT_CHANCMD_RESET,
-	       chan->reg_base + IOAT_CHANCMD_OFFSET(chan->device->version));
-	mdelay(100);
+	device->reset_hw(chan);
 
 	spin_lock_bh(&ioat->ring_lock);
 	descs = ioat2_ring_space(ioat);
@@ -839,6 +873,7 @@ int __devinit ioat2_dma_probe(struct ioa
 	int err;
 
 	device->enumerate_channels = ioat2_enumerate_channels;
+	device->reset_hw = ioat2_reset_hw;
 	device->cleanup_tasklet = ioat2_cleanup_tasklet;
 	device->timer_fn = ioat2_timer_event;
 	device->self_test = ioat_dma_self_test;
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v2.h linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v2.h	2010-02-24 13:52:17.000000000 -0500
@@ -185,6 +185,8 @@ bool reshape_ring(struct ioat2_dma_chan
 void __ioat2_issue_pending(struct ioat2_dma_chan *ioat);
 void ioat2_cleanup_tasklet(unsigned long data);
 void ioat2_timer_event(unsigned long data);
+int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo);
+int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo);
 extern struct kobj_type ioat2_ktype;
 extern struct kmem_cache *ioat2_cache;
 #endif /* IOATDMA_V2_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v3.c linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v3.c
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/dma_v3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/dma_v3.c	2010-02-24 13:52:17.000000000 -0500
@@ -650,9 +650,11 @@ __ioat3_prep_pq_lock(struct dma_chan *c,
 
 	num_descs = ioat2_xferlen_to_descs(ioat, len);
 	/* we need 2x the number of descriptors to cover greater than 3
-	 * sources
+	 * sources (we need 1 extra source in the q-only continuation
+	 * case and 3 extra sources in the p+q continuation case.
 	 */
-	if (src_cnt > 3 || flags & DMA_PREP_CONTINUE) {
+	if (src_cnt + dmaf_p_disabled_continue(flags) > 3 ||
+	    (dmaf_continue(flags) && !dmaf_p_disabled_continue(flags))) {
 		with_ext = 1;
 		num_descs *= 2;
 	} else
@@ -1128,6 +1130,45 @@ static int __devinit ioat3_dma_self_test
 	return 0;
 }
 
+static int ioat3_reset_hw(struct ioat_chan_common *chan)
+{
+	/* throw away whatever the channel was doing and get it
+	 * initialized, with ioat3 specific workarounds
+	 */
+	struct ioatdma_device *device = chan->device;
+	struct pci_dev *pdev = device->pdev;
+	u32 chanerr;
+	u16 dev_id;
+	int err;
+
+	ioat2_quiesce(chan, msecs_to_jiffies(100));
+
+	chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+	writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
+
+	/* -= IOAT ver.3 workarounds =- */
+	/* Write CHANERRMSK_INT with 3E07h to mask out the errors
+	 * that can cause stability issues for IOAT ver.3, and clear any
+	 * pending errors
+	 */
+	pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07);
+	err = pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr);
+	if (err) {
+		dev_err(&pdev->dev, "channel error register unreachable\n");
+		return err;
+	}
+	pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr);
+
+	/* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit
+	 * (workaround for spurious config parity error after restart)
+	 */
+	pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id);
+	if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0)
+		pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10);
+
+	return ioat2_reset_sync(chan, msecs_to_jiffies(200));
+}
+
 int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
 {
 	struct pci_dev *pdev = device->pdev;
@@ -1137,10 +1178,10 @@ int __devinit ioat3_dma_probe(struct ioa
 	struct ioat_chan_common *chan;
 	bool is_raid_device = false;
 	int err;
-	u16 dev_id;
 	u32 cap;
 
 	device->enumerate_channels = ioat2_enumerate_channels;
+	device->reset_hw = ioat3_reset_hw;
 	device->self_test = ioat3_dma_self_test;
 	dma = &device->common;
 	dma->device_prep_dma_memcpy = ioat2_dma_prep_memcpy_lock;
@@ -1216,19 +1257,6 @@ int __devinit ioat3_dma_probe(struct ioa
 	dma->device_prep_dma_xor_val = NULL;
 	#endif
 
-	/* -= IOAT ver.3 workarounds =- */
-	/* Write CHANERRMSK_INT with 3E07h to mask out the errors
-	 * that can cause stability issues for IOAT ver.3
-	 */
-	pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07);
-
-	/* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit
-	 * (workaround for spurious config parity error after restart)
-	 */
-	pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id);
-	if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0)
-		pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10);
-
 	err = ioat_probe(device);
 	if (err)
 		return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ioat/registers.h linux-libre-2.6.33-gnu1/drivers/dma/ioat/registers.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ioat/registers.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ioat/registers.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
 
 #define IOAT_PCI_DEVICE_ID_OFFSET		0x02
 #define IOAT_PCI_DMAUNCERRSTS_OFFSET		0x148
+#define IOAT_PCI_CHANERR_INT_OFFSET		0x180
 #define IOAT_PCI_CHANERRMASK_INT_OFFSET		0x184
 
 /* MMIO Device Registers */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/iop-adma.c linux-libre-2.6.33-gnu1/drivers/dma/iop-adma.c
--- linux-libre-2.6.32-gnu1/drivers/dma/iop-adma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/iop-adma.c	2010-02-24 13:52:17.000000000 -0500
@@ -1470,7 +1470,7 @@ static int __devinit iop_adma_probe(stru
 		return -ENODEV;
 
 	if (!devm_request_mem_region(&pdev->dev, res->start,
-				res->end - res->start, pdev->name))
+				resource_size(res), pdev->name))
 		return -EBUSY;
 
 	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
@@ -1542,7 +1542,7 @@ static int __devinit iop_adma_probe(stru
 	iop_chan->device = adev;
 
 	iop_chan->mmr_base = devm_ioremap(&pdev->dev, res->start,
-					res->end - res->start);
+					resource_size(res));
 	if (!iop_chan->mmr_base) {
 		ret = -ENOMEM;
 		goto err_free_iop_chan;
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ipu/ipu_idmac.c linux-libre-2.6.33-gnu1/drivers/dma/ipu/ipu_idmac.c
--- linux-libre-2.6.32-gnu1/drivers/dma/ipu/ipu_idmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ipu/ipu_idmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -761,12 +761,10 @@ static void ipu_select_buffer(enum ipu_c
  * @buffer_n:	buffer number to update.
  *		0 or 1 are the only valid values.
  * @phyaddr:	buffer physical address.
- * @return:	Returns 0 on success or negative error code on failure. This
- *              function will fail if the buffer is set to ready.
  */
 /* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(struct idmac_channel *ichan,
-				     int buffer_n, dma_addr_t phyaddr)
+static void ipu_update_channel_buffer(struct idmac_channel *ichan,
+				      int buffer_n, dma_addr_t phyaddr)
 {
 	enum ipu_channel channel = ichan->dma_chan.chan_id;
 	uint32_t reg;
@@ -806,8 +804,6 @@ static int ipu_update_channel_buffer(str
 	}
 
 	spin_unlock_irqrestore(&ipu_data.lock, flags);
-
-	return 0;
 }
 
 /* Called under spin_lock_irqsave(&ichan->lock) */
@@ -816,7 +812,6 @@ static int ipu_submit_buffer(struct idma
 {
 	unsigned int chan_id = ichan->dma_chan.chan_id;
 	struct device *dev = &ichan->dma_chan.dev->device;
-	int ret;
 
 	if (async_tx_test_ack(&desc->txd))
 		return -EINTR;
@@ -827,14 +822,7 @@ static int ipu_submit_buffer(struct idma
 	 * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
 	 * doing it again shouldn't hurt either.
 	 */
-	ret = ipu_update_channel_buffer(ichan, buf_idx,
-					sg_dma_address(sg));
-
-	if (ret < 0) {
-		dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n",
-			sg, chan_id, buf_idx);
-		return ret;
-	}
+	ipu_update_channel_buffer(ichan, buf_idx, sg_dma_address(sg));
 
 	ipu_select_buffer(chan_id, buf_idx);
 	dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
@@ -1379,10 +1367,11 @@ static irqreturn_t idmac_interrupt(int i
 
 	if (likely(sgnew) &&
 	    ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
-		callback = desc->txd.callback;
-		callback_param = desc->txd.callback_param;
+		callback = descnew->txd.callback;
+		callback_param = descnew->txd.callback_param;
 		spin_unlock(&ichan->lock);
-		callback(callback_param);
+		if (callback)
+			callback(callback_param);
 		spin_lock(&ichan->lock);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/Kconfig linux-libre-2.6.33-gnu1/drivers/dma/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/dma/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@ config DW_DMAC
 
 config AT_HDMAC
 	tristate "Atmel AHB DMA support"
-	depends on ARCH_AT91SAM9RL
+	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
 	select DMA_ENGINE
 	help
 	  Support the Atmel AHB DMA controller.  This can be integrated in
@@ -111,6 +111,24 @@ config SH_DMAE
 	help
 	  Enable support for the Renesas SuperH DMA controllers.
 
+config COH901318
+	bool "ST-Ericsson COH901318 DMA support"
+	select DMA_ENGINE
+	depends on ARCH_U300
+	help
+	  Enable support for ST-Ericsson COH 901 318 DMA.
+
+config AMCC_PPC440SPE_ADMA
+	tristate "AMCC PPC440SPe ADMA support"
+	depends on 440SPe || 440SP
+	select DMA_ENGINE
+	select ARCH_HAS_ASYNC_TX_FIND_CHANNEL
+	help
+	  Enable support for the AMCC PPC440SPe RAID engines.
+
+config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
+	bool
+
 config DMA_ENGINE
 	bool
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/Makefile linux-libre-2.6.33-gnu1/drivers/dma/Makefile
--- linux-libre-2.6.32-gnu1/drivers/dma/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -10,3 +10,5 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 obj-$(CONFIG_SH_DMAE) += shdma.o
+obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
+obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/adma.c linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.c
--- linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/adma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5027 @@
+/*
+ * Copyright (C) 2006-2009 DENX Software Engineering.
+ *
+ * Author: Yuri Tikhonov <yur@emcraft.com>
+ *
+ * Further porting to arch/powerpc by
+ * 	Anatolij Gustschin <agust@denx.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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This driver supports the asynchrounous DMA copy and RAID engines available
+ * on the AMCC PPC440SPe Processors.
+ * Based on the Intel Xscale(R) family of I/O Processors (IOP 32x, 33x, 134x)
+ * ADMA driver written by D.Williams.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/async_tx.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+#include "adma.h"
+
+enum ppc_adma_init_code {
+	PPC_ADMA_INIT_OK = 0,
+	PPC_ADMA_INIT_MEMRES,
+	PPC_ADMA_INIT_MEMREG,
+	PPC_ADMA_INIT_ALLOC,
+	PPC_ADMA_INIT_COHERENT,
+	PPC_ADMA_INIT_CHANNEL,
+	PPC_ADMA_INIT_IRQ1,
+	PPC_ADMA_INIT_IRQ2,
+	PPC_ADMA_INIT_REGISTER
+};
+
+static char *ppc_adma_errors[] = {
+	[PPC_ADMA_INIT_OK] = "ok",
+	[PPC_ADMA_INIT_MEMRES] = "failed to get memory resource",
+	[PPC_ADMA_INIT_MEMREG] = "failed to request memory region",
+	[PPC_ADMA_INIT_ALLOC] = "failed to allocate memory for adev "
+				"structure",
+	[PPC_ADMA_INIT_COHERENT] = "failed to allocate coherent memory for "
+				   "hardware descriptors",
+	[PPC_ADMA_INIT_CHANNEL] = "failed to allocate memory for channel",
+	[PPC_ADMA_INIT_IRQ1] = "failed to request first irq",
+	[PPC_ADMA_INIT_IRQ2] = "failed to request second irq",
+	[PPC_ADMA_INIT_REGISTER] = "failed to register dma async device",
+};
+
+static enum ppc_adma_init_code
+ppc440spe_adma_devices[PPC440SPE_ADMA_ENGINES_NUM];
+
+struct ppc_dma_chan_ref {
+	struct dma_chan *chan;
+	struct list_head node;
+};
+
+/* The list of channels exported by ppc440spe ADMA */
+struct list_head
+ppc440spe_adma_chan_list = LIST_HEAD_INIT(ppc440spe_adma_chan_list);
+
+/* This flag is set when want to refetch the xor chain in the interrupt
+ * handler
+ */
+static u32 do_xor_refetch;
+
+/* Pointer to DMA0, DMA1 CP/CS FIFO */
+static void *ppc440spe_dma_fifo_buf;
+
+/* Pointers to last submitted to DMA0, DMA1 CDBs */
+static struct ppc440spe_adma_desc_slot *chan_last_sub[3];
+static struct ppc440spe_adma_desc_slot *chan_first_cdb[3];
+
+/* Pointer to last linked and submitted xor CB */
+static struct ppc440spe_adma_desc_slot *xor_last_linked;
+static struct ppc440spe_adma_desc_slot *xor_last_submit;
+
+/* This array is used in data-check operations for storing a pattern */
+static char ppc440spe_qword[16];
+
+static atomic_t ppc440spe_adma_err_irq_ref;
+static dcr_host_t ppc440spe_mq_dcr_host;
+static unsigned int ppc440spe_mq_dcr_len;
+
+/* Since RXOR operations use the common register (MQ0_CF2H) for setting-up
+ * the block size in transactions, then we do not allow to activate more than
+ * only one RXOR transactions simultaneously. So use this var to store
+ * the information about is RXOR currently active (PPC440SPE_RXOR_RUN bit is
+ * set) or not (PPC440SPE_RXOR_RUN is clear).
+ */
+static unsigned long ppc440spe_rxor_state;
+
+/* These are used in enable & check routines
+ */
+static u32 ppc440spe_r6_enabled;
+static struct ppc440spe_adma_chan *ppc440spe_r6_tchan;
+static struct completion ppc440spe_r6_test_comp;
+
+static int ppc440spe_adma_dma2rxor_prep_src(
+		struct ppc440spe_adma_desc_slot *desc,
+		struct ppc440spe_rxor *cursor, int index,
+		int src_cnt, u32 addr);
+static void ppc440spe_adma_dma2rxor_set_src(
+		struct ppc440spe_adma_desc_slot *desc,
+		int index, dma_addr_t addr);
+static void ppc440spe_adma_dma2rxor_set_mult(
+		struct ppc440spe_adma_desc_slot *desc,
+		int index, u8 mult);
+
+#ifdef ADMA_LL_DEBUG
+#define ADMA_LL_DBG(x) ({ if (1) x; 0; })
+#else
+#define ADMA_LL_DBG(x) ({ if (0) x; 0; })
+#endif
+
+static void print_cb(struct ppc440spe_adma_chan *chan, void *block)
+{
+	struct dma_cdb *cdb;
+	struct xor_cb *cb;
+	int i;
+
+	switch (chan->device->id) {
+	case 0:
+	case 1:
+		cdb = block;
+
+		pr_debug("CDB at %p [%d]:\n"
+			"\t attr 0x%02x opc 0x%02x cnt 0x%08x\n"
+			"\t sg1u 0x%08x sg1l 0x%08x\n"
+			"\t sg2u 0x%08x sg2l 0x%08x\n"
+			"\t sg3u 0x%08x sg3l 0x%08x\n",
+			cdb, chan->device->id,
+			cdb->attr, cdb->opc, le32_to_cpu(cdb->cnt),
+			le32_to_cpu(cdb->sg1u), le32_to_cpu(cdb->sg1l),
+			le32_to_cpu(cdb->sg2u), le32_to_cpu(cdb->sg2l),
+			le32_to_cpu(cdb->sg3u), le32_to_cpu(cdb->sg3l)
+		);
+		break;
+	case 2:
+		cb = block;
+
+		pr_debug("CB at %p [%d]:\n"
+			"\t cbc 0x%08x cbbc 0x%08x cbs 0x%08x\n"
+			"\t cbtah 0x%08x cbtal 0x%08x\n"
+			"\t cblah 0x%08x cblal 0x%08x\n",
+			cb, chan->device->id,
+			cb->cbc, cb->cbbc, cb->cbs,
+			cb->cbtah, cb->cbtal,
+			cb->cblah, cb->cblal);
+		for (i = 0; i < 16; i++) {
+			if (i && !cb->ops[i].h && !cb->ops[i].l)
+				continue;
+			pr_debug("\t ops[%2d]: h 0x%08x l 0x%08x\n",
+				i, cb->ops[i].h, cb->ops[i].l);
+		}
+		break;
+	}
+}
+
+static void print_cb_list(struct ppc440spe_adma_chan *chan,
+			  struct ppc440spe_adma_desc_slot *iter)
+{
+	for (; iter; iter = iter->hw_next)
+		print_cb(chan, iter->hw_desc);
+}
+
+static void prep_dma_xor_dbg(int id, dma_addr_t dst, dma_addr_t *src,
+			     unsigned int src_cnt)
+{
+	int i;
+
+	pr_debug("\n%s(%d):\nsrc: ", __func__, id);
+	for (i = 0; i < src_cnt; i++)
+		pr_debug("\t0x%016llx ", src[i]);
+	pr_debug("dst:\n\t0x%016llx\n", dst);
+}
+
+static void prep_dma_pq_dbg(int id, dma_addr_t *dst, dma_addr_t *src,
+			    unsigned int src_cnt)
+{
+	int i;
+
+	pr_debug("\n%s(%d):\nsrc: ", __func__, id);
+	for (i = 0; i < src_cnt; i++)
+		pr_debug("\t0x%016llx ", src[i]);
+	pr_debug("dst: ");
+	for (i = 0; i < 2; i++)
+		pr_debug("\t0x%016llx ", dst[i]);
+}
+
+static void prep_dma_pqzero_sum_dbg(int id, dma_addr_t *src,
+				    unsigned int src_cnt,
+				    const unsigned char *scf)
+{
+	int i;
+
+	pr_debug("\n%s(%d):\nsrc(coef): ", __func__, id);
+	if (scf) {
+		for (i = 0; i < src_cnt; i++)
+			pr_debug("\t0x%016llx(0x%02x) ", src[i], scf[i]);
+	} else {
+		for (i = 0; i < src_cnt; i++)
+			pr_debug("\t0x%016llx(no) ", src[i]);
+	}
+
+	pr_debug("dst: ");
+	for (i = 0; i < 2; i++)
+		pr_debug("\t0x%016llx ", src[src_cnt + i]);
+}
+
+/******************************************************************************
+ * Command (Descriptor) Blocks low-level routines
+ ******************************************************************************/
+/**
+ * ppc440spe_desc_init_interrupt - initialize the descriptor for INTERRUPT
+ * pseudo operation
+ */
+static void ppc440spe_desc_init_interrupt(struct ppc440spe_adma_desc_slot *desc,
+					  struct ppc440spe_adma_chan *chan)
+{
+	struct xor_cb *p;
+
+	switch (chan->device->id) {
+	case PPC440SPE_XOR_ID:
+		p = desc->hw_desc;
+		memset(desc->hw_desc, 0, sizeof(struct xor_cb));
+		/* NOP with Command Block Complete Enable */
+		p->cbc = XOR_CBCR_CBCE_BIT;
+		break;
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		memset(desc->hw_desc, 0, sizeof(struct dma_cdb));
+		/* NOP with interrupt */
+		set_bit(PPC440SPE_DESC_INT, &desc->flags);
+		break;
+	default:
+		printk(KERN_ERR "Unsupported id %d in %s\n", chan->device->id,
+				__func__);
+		break;
+	}
+}
+
+/**
+ * ppc440spe_desc_init_null_xor - initialize the descriptor for NULL XOR
+ * pseudo operation
+ */
+static void ppc440spe_desc_init_null_xor(struct ppc440spe_adma_desc_slot *desc)
+{
+	memset(desc->hw_desc, 0, sizeof(struct xor_cb));
+	desc->hw_next = NULL;
+	desc->src_cnt = 0;
+	desc->dst_cnt = 1;
+}
+
+/**
+ * ppc440spe_desc_init_xor - initialize the descriptor for XOR operation
+ */
+static void ppc440spe_desc_init_xor(struct ppc440spe_adma_desc_slot *desc,
+					 int src_cnt, unsigned long flags)
+{
+	struct xor_cb *hw_desc = desc->hw_desc;
+
+	memset(desc->hw_desc, 0, sizeof(struct xor_cb));
+	desc->hw_next = NULL;
+	desc->src_cnt = src_cnt;
+	desc->dst_cnt = 1;
+
+	hw_desc->cbc = XOR_CBCR_TGT_BIT | src_cnt;
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Enable interrupt on completion */
+		hw_desc->cbc |= XOR_CBCR_CBCE_BIT;
+}
+
+/**
+ * ppc440spe_desc_init_dma2pq - initialize the descriptor for PQ
+ * operation in DMA2 controller
+ */
+static void ppc440spe_desc_init_dma2pq(struct ppc440spe_adma_desc_slot *desc,
+		int dst_cnt, int src_cnt, unsigned long flags)
+{
+	struct xor_cb *hw_desc = desc->hw_desc;
+
+	memset(desc->hw_desc, 0, sizeof(struct xor_cb));
+	desc->hw_next = NULL;
+	desc->src_cnt = src_cnt;
+	desc->dst_cnt = dst_cnt;
+	memset(desc->reverse_flags, 0, sizeof(desc->reverse_flags));
+	desc->descs_per_op = 0;
+
+	hw_desc->cbc = XOR_CBCR_TGT_BIT;
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Enable interrupt on completion */
+		hw_desc->cbc |= XOR_CBCR_CBCE_BIT;
+}
+
+#define DMA_CTRL_FLAGS_LAST	DMA_PREP_FENCE
+#define DMA_PREP_ZERO_P		(DMA_CTRL_FLAGS_LAST << 1)
+#define DMA_PREP_ZERO_Q		(DMA_PREP_ZERO_P << 1)
+
+/**
+ * ppc440spe_desc_init_dma01pq - initialize the descriptors for PQ operation
+ * with DMA0/1
+ */
+static void ppc440spe_desc_init_dma01pq(struct ppc440spe_adma_desc_slot *desc,
+				int dst_cnt, int src_cnt, unsigned long flags,
+				unsigned long op)
+{
+	struct dma_cdb *hw_desc;
+	struct ppc440spe_adma_desc_slot *iter;
+	u8 dopc;
+
+	/* Common initialization of a PQ descriptors chain */
+	set_bits(op, &desc->flags);
+	desc->src_cnt = src_cnt;
+	desc->dst_cnt = dst_cnt;
+
+	/* WXOR MULTICAST if both P and Q are being computed
+	 * MV_SG1_SG2 if Q only
+	 */
+	dopc = (desc->dst_cnt == DMA_DEST_MAX_NUM) ?
+		DMA_CDB_OPC_MULTICAST : DMA_CDB_OPC_MV_SG1_SG2;
+
+	list_for_each_entry(iter, &desc->group_list, chain_node) {
+		hw_desc = iter->hw_desc;
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+
+		if (likely(!list_is_last(&iter->chain_node,
+				&desc->group_list))) {
+			/* set 'next' pointer */
+			iter->hw_next = list_entry(iter->chain_node.next,
+				struct ppc440spe_adma_desc_slot, chain_node);
+			clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+		} else {
+			/* this is the last descriptor.
+			 * this slot will be pasted from ADMA level
+			 * each time it wants to configure parameters
+			 * of the transaction (src, dst, ...)
+			 */
+			iter->hw_next = NULL;
+			if (flags & DMA_PREP_INTERRUPT)
+				set_bit(PPC440SPE_DESC_INT, &iter->flags);
+			else
+				clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+		}
+	}
+
+	/* Set OPS depending on WXOR/RXOR type of operation */
+	if (!test_bit(PPC440SPE_DESC_RXOR, &desc->flags)) {
+		/* This is a WXOR only chain:
+		 * - first descriptors are for zeroing destinations
+		 *   if PPC440SPE_ZERO_P/Q set;
+		 * - descriptors remained are for GF-XOR operations.
+		 */
+		iter = list_first_entry(&desc->group_list,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+
+		if (test_bit(PPC440SPE_ZERO_P, &desc->flags)) {
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+			iter = list_first_entry(&iter->chain_node,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		}
+
+		if (test_bit(PPC440SPE_ZERO_Q, &desc->flags)) {
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+			iter = list_first_entry(&iter->chain_node,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		}
+
+		list_for_each_entry_from(iter, &desc->group_list, chain_node) {
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = dopc;
+		}
+	} else {
+		/* This is either RXOR-only or mixed RXOR/WXOR */
+
+		/* The first 1 or 2 slots in chain are always RXOR,
+		 * if need to calculate P & Q, then there are two
+		 * RXOR slots; if only P or only Q, then there is one
+		 */
+		iter = list_first_entry(&desc->group_list,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+
+		if (desc->dst_cnt == DMA_DEST_MAX_NUM) {
+			iter = list_first_entry(&iter->chain_node,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+		}
+
+		/* The remaining descs (if any) are WXORs */
+		if (test_bit(PPC440SPE_DESC_WXOR, &desc->flags)) {
+			iter = list_first_entry(&iter->chain_node,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			list_for_each_entry_from(iter, &desc->group_list,
+						chain_node) {
+				hw_desc = iter->hw_desc;
+				hw_desc->opc = dopc;
+			}
+		}
+	}
+}
+
+/**
+ * ppc440spe_desc_init_dma01pqzero_sum - initialize the descriptor
+ * for PQ_ZERO_SUM operation
+ */
+static void ppc440spe_desc_init_dma01pqzero_sum(
+				struct ppc440spe_adma_desc_slot *desc,
+				int dst_cnt, int src_cnt)
+{
+	struct dma_cdb *hw_desc;
+	struct ppc440spe_adma_desc_slot *iter;
+	int i = 0;
+	u8 dopc = (dst_cnt == 2) ? DMA_CDB_OPC_MULTICAST :
+				   DMA_CDB_OPC_MV_SG1_SG2;
+	/*
+	 * Initialize starting from 2nd or 3rd descriptor dependent
+	 * on dst_cnt. First one or two slots are for cloning P
+	 * and/or Q to chan->pdest and/or chan->qdest as we have
+	 * to preserve original P/Q.
+	 */
+	iter = list_first_entry(&desc->group_list,
+				struct ppc440spe_adma_desc_slot, chain_node);
+	iter = list_entry(iter->chain_node.next,
+			  struct ppc440spe_adma_desc_slot, chain_node);
+
+	if (dst_cnt > 1) {
+		iter = list_entry(iter->chain_node.next,
+				  struct ppc440spe_adma_desc_slot, chain_node);
+	}
+	/* initialize each source descriptor in chain */
+	list_for_each_entry_from(iter, &desc->group_list, chain_node) {
+		hw_desc = iter->hw_desc;
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		iter->src_cnt = 0;
+		iter->dst_cnt = 0;
+
+		/* This is a ZERO_SUM operation:
+		 * - <src_cnt> descriptors starting from 2nd or 3rd
+		 *   descriptor are for GF-XOR operations;
+		 * - remaining <dst_cnt> descriptors are for checking the result
+		 */
+		if (i++ < src_cnt)
+			/* MV_SG1_SG2 if only Q is being verified
+			 * MULTICAST if both P and Q are being verified
+			 */
+			hw_desc->opc = dopc;
+		else
+			/* DMA_CDB_OPC_DCHECK128 operation */
+			hw_desc->opc = DMA_CDB_OPC_DCHECK128;
+
+		if (likely(!list_is_last(&iter->chain_node,
+					 &desc->group_list))) {
+			/* set 'next' pointer */
+			iter->hw_next = list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+		} else {
+			/* this is the last descriptor.
+			 * this slot will be pasted from ADMA level
+			 * each time it wants to configure parameters
+			 * of the transaction (src, dst, ...)
+			 */
+			iter->hw_next = NULL;
+			/* always enable interrupt generation since we get
+			 * the status of pqzero from the handler
+			 */
+			set_bit(PPC440SPE_DESC_INT, &iter->flags);
+		}
+	}
+	desc->src_cnt = src_cnt;
+	desc->dst_cnt = dst_cnt;
+}
+
+/**
+ * ppc440spe_desc_init_memcpy - initialize the descriptor for MEMCPY operation
+ */
+static void ppc440spe_desc_init_memcpy(struct ppc440spe_adma_desc_slot *desc,
+					unsigned long flags)
+{
+	struct dma_cdb *hw_desc = desc->hw_desc;
+
+	memset(desc->hw_desc, 0, sizeof(struct dma_cdb));
+	desc->hw_next = NULL;
+	desc->src_cnt = 1;
+	desc->dst_cnt = 1;
+
+	if (flags & DMA_PREP_INTERRUPT)
+		set_bit(PPC440SPE_DESC_INT, &desc->flags);
+	else
+		clear_bit(PPC440SPE_DESC_INT, &desc->flags);
+
+	hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+}
+
+/**
+ * ppc440spe_desc_init_memset - initialize the descriptor for MEMSET operation
+ */
+static void ppc440spe_desc_init_memset(struct ppc440spe_adma_desc_slot *desc,
+					int value, unsigned long flags)
+{
+	struct dma_cdb *hw_desc = desc->hw_desc;
+
+	memset(desc->hw_desc, 0, sizeof(struct dma_cdb));
+	desc->hw_next = NULL;
+	desc->src_cnt = 1;
+	desc->dst_cnt = 1;
+
+	if (flags & DMA_PREP_INTERRUPT)
+		set_bit(PPC440SPE_DESC_INT, &desc->flags);
+	else
+		clear_bit(PPC440SPE_DESC_INT, &desc->flags);
+
+	hw_desc->sg1u = hw_desc->sg1l = cpu_to_le32((u32)value);
+	hw_desc->sg3u = hw_desc->sg3l = cpu_to_le32((u32)value);
+	hw_desc->opc = DMA_CDB_OPC_DFILL128;
+}
+
+/**
+ * ppc440spe_desc_set_src_addr - set source address into the descriptor
+ */
+static void ppc440spe_desc_set_src_addr(struct ppc440spe_adma_desc_slot *desc,
+					struct ppc440spe_adma_chan *chan,
+					int src_idx, dma_addr_t addrh,
+					dma_addr_t addrl)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+	phys_addr_t addr64, tmplow, tmphi;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		if (!addrh) {
+			addr64 = addrl;
+			tmphi = (addr64 >> 32);
+			tmplow = (addr64 & 0xFFFFFFFF);
+		} else {
+			tmphi = addrh;
+			tmplow = addrl;
+		}
+		dma_hw_desc = desc->hw_desc;
+		dma_hw_desc->sg1l = cpu_to_le32((u32)tmplow);
+		dma_hw_desc->sg1u |= cpu_to_le32((u32)tmphi);
+		break;
+	case PPC440SPE_XOR_ID:
+		xor_hw_desc = desc->hw_desc;
+		xor_hw_desc->ops[src_idx].l = addrl;
+		xor_hw_desc->ops[src_idx].h |= addrh;
+		break;
+	}
+}
+
+/**
+ * ppc440spe_desc_set_src_mult - set source address mult into the descriptor
+ */
+static void ppc440spe_desc_set_src_mult(struct ppc440spe_adma_desc_slot *desc,
+			struct ppc440spe_adma_chan *chan, u32 mult_index,
+			int sg_index, unsigned char mult_value)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+	u32 *psgu;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+
+		switch (sg_index) {
+		/* for RXOR operations set multiplier
+		 * into source cued address
+		 */
+		case DMA_CDB_SG_SRC:
+			psgu = &dma_hw_desc->sg1u;
+			break;
+		/* for WXOR operations set multiplier
+		 * into destination cued address(es)
+		 */
+		case DMA_CDB_SG_DST1:
+			psgu = &dma_hw_desc->sg2u;
+			break;
+		case DMA_CDB_SG_DST2:
+			psgu = &dma_hw_desc->sg3u;
+			break;
+		default:
+			BUG();
+		}
+
+		*psgu |= cpu_to_le32(mult_value << mult_index);
+		break;
+	case PPC440SPE_XOR_ID:
+		xor_hw_desc = desc->hw_desc;
+		break;
+	default:
+		BUG();
+	}
+}
+
+/**
+ * ppc440spe_desc_set_dest_addr - set destination address into the descriptor
+ */
+static void ppc440spe_desc_set_dest_addr(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan,
+				dma_addr_t addrh, dma_addr_t addrl,
+				u32 dst_idx)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+	phys_addr_t addr64, tmphi, tmplow;
+	u32 *psgu, *psgl;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		if (!addrh) {
+			addr64 = addrl;
+			tmphi = (addr64 >> 32);
+			tmplow = (addr64 & 0xFFFFFFFF);
+		} else {
+			tmphi = addrh;
+			tmplow = addrl;
+		}
+		dma_hw_desc = desc->hw_desc;
+
+		psgu = dst_idx ? &dma_hw_desc->sg3u : &dma_hw_desc->sg2u;
+		psgl = dst_idx ? &dma_hw_desc->sg3l : &dma_hw_desc->sg2l;
+
+		*psgl = cpu_to_le32((u32)tmplow);
+		*psgu |= cpu_to_le32((u32)tmphi);
+		break;
+	case PPC440SPE_XOR_ID:
+		xor_hw_desc = desc->hw_desc;
+		xor_hw_desc->cbtal = addrl;
+		xor_hw_desc->cbtah |= addrh;
+		break;
+	}
+}
+
+/**
+ * ppc440spe_desc_set_byte_count - set number of data bytes involved
+ * into the operation
+ */
+static void ppc440spe_desc_set_byte_count(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan,
+				u32 byte_count)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+		dma_hw_desc->cnt = cpu_to_le32(byte_count);
+		break;
+	case PPC440SPE_XOR_ID:
+		xor_hw_desc = desc->hw_desc;
+		xor_hw_desc->cbbc = byte_count;
+		break;
+	}
+}
+
+/**
+ * ppc440spe_desc_set_rxor_block_size - set RXOR block size
+ */
+static inline void ppc440spe_desc_set_rxor_block_size(u32 byte_count)
+{
+	/* assume that byte_count is aligned on the 512-boundary;
+	 * thus write it directly to the register (bits 23:31 are
+	 * reserved there).
+	 */
+	dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CF2H, byte_count);
+}
+
+/**
+ * ppc440spe_desc_set_dcheck - set CHECK pattern
+ */
+static void ppc440spe_desc_set_dcheck(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan, u8 *qword)
+{
+	struct dma_cdb *dma_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+		iowrite32(qword[0], &dma_hw_desc->sg3l);
+		iowrite32(qword[4], &dma_hw_desc->sg3u);
+		iowrite32(qword[8], &dma_hw_desc->sg2l);
+		iowrite32(qword[12], &dma_hw_desc->sg2u);
+		break;
+	default:
+		BUG();
+	}
+}
+
+/**
+ * ppc440spe_xor_set_link - set link address in xor CB
+ */
+static void ppc440spe_xor_set_link(struct ppc440spe_adma_desc_slot *prev_desc,
+				struct ppc440spe_adma_desc_slot *next_desc)
+{
+	struct xor_cb *xor_hw_desc = prev_desc->hw_desc;
+
+	if (unlikely(!next_desc || !(next_desc->phys))) {
+		printk(KERN_ERR "%s: next_desc=0x%p; next_desc->phys=0x%llx\n",
+			__func__, next_desc,
+			next_desc ? next_desc->phys : 0);
+		BUG();
+	}
+
+	xor_hw_desc->cbs = 0;
+	xor_hw_desc->cblal = next_desc->phys;
+	xor_hw_desc->cblah = 0;
+	xor_hw_desc->cbc |= XOR_CBCR_LNK_BIT;
+}
+
+/**
+ * ppc440spe_desc_set_link - set the address of descriptor following this
+ * descriptor in chain
+ */
+static void ppc440spe_desc_set_link(struct ppc440spe_adma_chan *chan,
+				struct ppc440spe_adma_desc_slot *prev_desc,
+				struct ppc440spe_adma_desc_slot *next_desc)
+{
+	unsigned long flags;
+	struct ppc440spe_adma_desc_slot *tail = next_desc;
+
+	if (unlikely(!prev_desc || !next_desc ||
+		(prev_desc->hw_next && prev_desc->hw_next != next_desc))) {
+		/* If previous next is overwritten something is wrong.
+		 * though we may refetch from append to initiate list
+		 * processing; in this case - it's ok.
+		 */
+		printk(KERN_ERR "%s: prev_desc=0x%p; next_desc=0x%p; "
+			"prev->hw_next=0x%p\n", __func__, prev_desc,
+			next_desc, prev_desc ? prev_desc->hw_next : 0);
+		BUG();
+	}
+
+	local_irq_save(flags);
+
+	/* do s/w chaining both for DMA and XOR descriptors */
+	prev_desc->hw_next = next_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		break;
+	case PPC440SPE_XOR_ID:
+		/* bind descriptor to the chain */
+		while (tail->hw_next)
+			tail = tail->hw_next;
+		xor_last_linked = tail;
+
+		if (prev_desc == xor_last_submit)
+			/* do not link to the last submitted CB */
+			break;
+		ppc440spe_xor_set_link(prev_desc, next_desc);
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+/**
+ * ppc440spe_desc_get_src_addr - extract the source address from the descriptor
+ */
+static u32 ppc440spe_desc_get_src_addr(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan, int src_idx)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+		/* May have 0, 1, 2, or 3 sources */
+		switch (dma_hw_desc->opc) {
+		case DMA_CDB_OPC_NO_OP:
+		case DMA_CDB_OPC_DFILL128:
+			return 0;
+		case DMA_CDB_OPC_DCHECK128:
+			if (unlikely(src_idx)) {
+				printk(KERN_ERR "%s: try to get %d source for"
+				    " DCHECK128\n", __func__, src_idx);
+				BUG();
+			}
+			return le32_to_cpu(dma_hw_desc->sg1l);
+		case DMA_CDB_OPC_MULTICAST:
+		case DMA_CDB_OPC_MV_SG1_SG2:
+			if (unlikely(src_idx > 2)) {
+				printk(KERN_ERR "%s: try to get %d source from"
+				    " DMA descr\n", __func__, src_idx);
+				BUG();
+			}
+			if (src_idx) {
+				if (le32_to_cpu(dma_hw_desc->sg1u) &
+				    DMA_CUED_XOR_WIN_MSK) {
+					u8 region;
+
+					if (src_idx == 1)
+						return le32_to_cpu(
+						    dma_hw_desc->sg1l) +
+							desc->unmap_len;
+
+					region = (le32_to_cpu(
+					    dma_hw_desc->sg1u)) >>
+						DMA_CUED_REGION_OFF;
+
+					region &= DMA_CUED_REGION_MSK;
+					switch (region) {
+					case DMA_RXOR123:
+						return le32_to_cpu(
+						    dma_hw_desc->sg1l) +
+							(desc->unmap_len << 1);
+					case DMA_RXOR124:
+						return le32_to_cpu(
+						    dma_hw_desc->sg1l) +
+							(desc->unmap_len * 3);
+					case DMA_RXOR125:
+						return le32_to_cpu(
+						    dma_hw_desc->sg1l) +
+							(desc->unmap_len << 2);
+					default:
+						printk(KERN_ERR
+						    "%s: try to"
+						    " get src3 for region %02x"
+						    "PPC440SPE_DESC_RXOR12?\n",
+						    __func__, region);
+						BUG();
+					}
+				} else {
+					printk(KERN_ERR
+						"%s: try to get %d"
+						" source for non-cued descr\n",
+						__func__, src_idx);
+					BUG();
+				}
+			}
+			return le32_to_cpu(dma_hw_desc->sg1l);
+		default:
+			printk(KERN_ERR "%s: unknown OPC 0x%02x\n",
+				__func__, dma_hw_desc->opc);
+			BUG();
+		}
+		return le32_to_cpu(dma_hw_desc->sg1l);
+	case PPC440SPE_XOR_ID:
+		/* May have up to 16 sources */
+		xor_hw_desc = desc->hw_desc;
+		return xor_hw_desc->ops[src_idx].l;
+	}
+	return 0;
+}
+
+/**
+ * ppc440spe_desc_get_dest_addr - extract the destination address from the
+ * descriptor
+ */
+static u32 ppc440spe_desc_get_dest_addr(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan, int idx)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+
+		if (likely(!idx))
+			return le32_to_cpu(dma_hw_desc->sg2l);
+		return le32_to_cpu(dma_hw_desc->sg3l);
+	case PPC440SPE_XOR_ID:
+		xor_hw_desc = desc->hw_desc;
+		return xor_hw_desc->cbtal;
+	}
+	return 0;
+}
+
+/**
+ * ppc440spe_desc_get_src_num - extract the number of source addresses from
+ * the descriptor
+ */
+static u32 ppc440spe_desc_get_src_num(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan)
+{
+	struct dma_cdb *dma_hw_desc;
+	struct xor_cb *xor_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_hw_desc = desc->hw_desc;
+
+		switch (dma_hw_desc->opc) {
+		case DMA_CDB_OPC_NO_OP:
+		case DMA_CDB_OPC_DFILL128:
+			return 0;
+		case DMA_CDB_OPC_DCHECK128:
+			return 1;
+		case DMA_CDB_OPC_MV_SG1_SG2:
+		case DMA_CDB_OPC_MULTICAST:
+			/*
+			 * Only for RXOR operations we have more than
+			 * one source
+			 */
+			if (le32_to_cpu(dma_hw_desc->sg1u) &
+			    DMA_CUED_XOR_WIN_MSK) {
+				/* RXOR op, there are 2 or 3 sources */
+				if (((le32_to_cpu(dma_hw_desc->sg1u) >>
+				    DMA_CUED_REGION_OFF) &
+				      DMA_CUED_REGION_MSK) == DMA_RXOR12) {
+					/* RXOR 1-2 */
+					return 2;
+				} else {
+					/* RXOR 1-2-3/1-2-4/1-2-5 */
+					return 3;
+				}
+			}
+			return 1;
+		default:
+			printk(KERN_ERR "%s: unknown OPC 0x%02x\n",
+				__func__, dma_hw_desc->opc);
+			BUG();
+		}
+	case PPC440SPE_XOR_ID:
+		/* up to 16 sources */
+		xor_hw_desc = desc->hw_desc;
+		return xor_hw_desc->cbc & XOR_CDCR_OAC_MSK;
+	default:
+		BUG();
+	}
+	return 0;
+}
+
+/**
+ * ppc440spe_desc_get_dst_num - get the number of destination addresses in
+ * this descriptor
+ */
+static u32 ppc440spe_desc_get_dst_num(struct ppc440spe_adma_desc_slot *desc,
+				struct ppc440spe_adma_chan *chan)
+{
+	struct dma_cdb *dma_hw_desc;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* May be 1 or 2 destinations */
+		dma_hw_desc = desc->hw_desc;
+		switch (dma_hw_desc->opc) {
+		case DMA_CDB_OPC_NO_OP:
+		case DMA_CDB_OPC_DCHECK128:
+			return 0;
+		case DMA_CDB_OPC_MV_SG1_SG2:
+		case DMA_CDB_OPC_DFILL128:
+			return 1;
+		case DMA_CDB_OPC_MULTICAST:
+			if (desc->dst_cnt == 2)
+				return 2;
+			else
+				return 1;
+		default:
+			printk(KERN_ERR "%s: unknown OPC 0x%02x\n",
+				__func__, dma_hw_desc->opc);
+			BUG();
+		}
+	case PPC440SPE_XOR_ID:
+		/* Always only 1 destination */
+		return 1;
+	default:
+		BUG();
+	}
+	return 0;
+}
+
+/**
+ * ppc440spe_desc_get_link - get the address of the descriptor that
+ * follows this one
+ */
+static inline u32 ppc440spe_desc_get_link(struct ppc440spe_adma_desc_slot *desc,
+					struct ppc440spe_adma_chan *chan)
+{
+	if (!desc->hw_next)
+		return 0;
+
+	return desc->hw_next->phys;
+}
+
+/**
+ * ppc440spe_desc_is_aligned - check alignment
+ */
+static inline int ppc440spe_desc_is_aligned(
+	struct ppc440spe_adma_desc_slot *desc, int num_slots)
+{
+	return (desc->idx & (num_slots - 1)) ? 0 : 1;
+}
+
+/**
+ * ppc440spe_chan_xor_slot_count - get the number of slots necessary for
+ * XOR operation
+ */
+static int ppc440spe_chan_xor_slot_count(size_t len, int src_cnt,
+			int *slots_per_op)
+{
+	int slot_cnt;
+
+	/* each XOR descriptor provides up to 16 source operands */
+	slot_cnt = *slots_per_op = (src_cnt + XOR_MAX_OPS - 1)/XOR_MAX_OPS;
+
+	if (likely(len <= PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT))
+		return slot_cnt;
+
+	printk(KERN_ERR "%s: len %d > max %d !!\n",
+		__func__, len, PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT);
+	BUG();
+	return slot_cnt;
+}
+
+/**
+ * ppc440spe_dma2_pq_slot_count - get the number of slots necessary for
+ * DMA2 PQ operation
+ */
+static int ppc440spe_dma2_pq_slot_count(dma_addr_t *srcs,
+		int src_cnt, size_t len)
+{
+	signed long long order = 0;
+	int state = 0;
+	int addr_count = 0;
+	int i;
+	for (i = 1; i < src_cnt; i++) {
+		dma_addr_t cur_addr = srcs[i];
+		dma_addr_t old_addr = srcs[i-1];
+		switch (state) {
+		case 0:
+			if (cur_addr == old_addr + len) {
+				/* direct RXOR */
+				order = 1;
+				state = 1;
+				if (i == src_cnt-1)
+					addr_count++;
+			} else if (old_addr == cur_addr + len) {
+				/* reverse RXOR */
+				order = -1;
+				state = 1;
+				if (i == src_cnt-1)
+					addr_count++;
+			} else {
+				state = 3;
+			}
+			break;
+		case 1:
+			if (i == src_cnt-2 || (order == -1
+				&& cur_addr != old_addr - len)) {
+				order = 0;
+				state = 0;
+				addr_count++;
+			} else if (cur_addr == old_addr + len*order) {
+				state = 2;
+				if (i == src_cnt-1)
+					addr_count++;
+			} else if (cur_addr == old_addr + 2*len) {
+				state = 2;
+				if (i == src_cnt-1)
+					addr_count++;
+			} else if (cur_addr == old_addr + 3*len) {
+				state = 2;
+				if (i == src_cnt-1)
+					addr_count++;
+			} else {
+				order = 0;
+				state = 0;
+				addr_count++;
+			}
+			break;
+		case 2:
+			order = 0;
+			state = 0;
+			addr_count++;
+				break;
+		}
+		if (state == 3)
+			break;
+	}
+	if (src_cnt <= 1 || (state != 1 && state != 2)) {
+		pr_err("%s: src_cnt=%d, state=%d, addr_count=%d, order=%lld\n",
+			__func__, src_cnt, state, addr_count, order);
+		for (i = 0; i < src_cnt; i++)
+			pr_err("\t[%d] 0x%llx \n", i, srcs[i]);
+		BUG();
+	}
+
+	return (addr_count + XOR_MAX_OPS - 1) / XOR_MAX_OPS;
+}
+
+
+/******************************************************************************
+ * ADMA channel low-level routines
+ ******************************************************************************/
+
+static u32
+ppc440spe_chan_get_current_descriptor(struct ppc440spe_adma_chan *chan);
+static void ppc440spe_chan_append(struct ppc440spe_adma_chan *chan);
+
+/**
+ * ppc440spe_adma_device_clear_eot_status - interrupt ack to XOR or DMA engine
+ */
+static void ppc440spe_adma_device_clear_eot_status(
+					struct ppc440spe_adma_chan *chan)
+{
+	struct dma_regs *dma_reg;
+	struct xor_regs *xor_reg;
+	u8 *p = chan->device->dma_desc_pool_virt;
+	struct dma_cdb *cdb;
+	u32 rv, i;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* read FIFO to ack */
+		dma_reg = chan->device->dma_reg;
+		while ((rv = ioread32(&dma_reg->csfpl))) {
+			i = rv & DMA_CDB_ADDR_MSK;
+			cdb = (struct dma_cdb *)&p[i -
+			    (u32)chan->device->dma_desc_pool];
+
+			/* Clear opcode to ack. This is necessary for
+			 * ZeroSum operations only
+			 */
+			cdb->opc = 0;
+
+			if (test_bit(PPC440SPE_RXOR_RUN,
+			    &ppc440spe_rxor_state)) {
+				/* probably this is a completed RXOR op,
+				 * get pointer to CDB using the fact that
+				 * physical and virtual addresses of CDB
+				 * in pools have the same offsets
+				 */
+				if (le32_to_cpu(cdb->sg1u) &
+				    DMA_CUED_XOR_BASE) {
+					/* this is a RXOR */
+					clear_bit(PPC440SPE_RXOR_RUN,
+						  &ppc440spe_rxor_state);
+				}
+			}
+
+			if (rv & DMA_CDB_STATUS_MSK) {
+				/* ZeroSum check failed
+				 */
+				struct ppc440spe_adma_desc_slot *iter;
+				dma_addr_t phys = rv & ~DMA_CDB_MSK;
+
+				/*
+				 * Update the status of corresponding
+				 * descriptor.
+				 */
+				list_for_each_entry(iter, &chan->chain,
+				    chain_node) {
+					if (iter->phys == phys)
+						break;
+				}
+				/*
+				 * if cannot find the corresponding
+				 * slot it's a bug
+				 */
+				BUG_ON(&iter->chain_node == &chan->chain);
+
+				if (iter->xor_check_result) {
+					if (test_bit(PPC440SPE_DESC_PCHECK,
+						     &iter->flags)) {
+						*iter->xor_check_result |=
+							SUM_CHECK_P_RESULT;
+					} else
+					if (test_bit(PPC440SPE_DESC_QCHECK,
+						     &iter->flags)) {
+						*iter->xor_check_result |=
+							SUM_CHECK_Q_RESULT;
+					} else
+						BUG();
+				}
+			}
+		}
+
+		rv = ioread32(&dma_reg->dsts);
+		if (rv) {
+			pr_err("DMA%d err status: 0x%x\n",
+			       chan->device->id, rv);
+			/* write back to clear */
+			iowrite32(rv, &dma_reg->dsts);
+		}
+		break;
+	case PPC440SPE_XOR_ID:
+		/* reset status bits to ack */
+		xor_reg = chan->device->xor_reg;
+		rv = ioread32be(&xor_reg->sr);
+		iowrite32be(rv, &xor_reg->sr);
+
+		if (rv & (XOR_IE_ICBIE_BIT|XOR_IE_ICIE_BIT|XOR_IE_RPTIE_BIT)) {
+			if (rv & XOR_IE_RPTIE_BIT) {
+				/* Read PLB Timeout Error.
+				 * Try to resubmit the CB
+				 */
+				u32 val = ioread32be(&xor_reg->ccbalr);
+
+				iowrite32be(val, &xor_reg->cblalr);
+
+				val = ioread32be(&xor_reg->crsr);
+				iowrite32be(val | XOR_CRSR_XAE_BIT,
+					    &xor_reg->crsr);
+			} else
+				pr_err("XOR ERR 0x%x status\n", rv);
+			break;
+		}
+
+		/*  if the XORcore is idle, but there are unprocessed CBs
+		 * then refetch the s/w chain here
+		 */
+		if (!(ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT) &&
+		    do_xor_refetch)
+			ppc440spe_chan_append(chan);
+		break;
+	}
+}
+
+/**
+ * ppc440spe_chan_is_busy - get the channel status
+ */
+static int ppc440spe_chan_is_busy(struct ppc440spe_adma_chan *chan)
+{
+	struct dma_regs *dma_reg;
+	struct xor_regs *xor_reg;
+	int busy = 0;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_reg = chan->device->dma_reg;
+		/*  if command FIFO's head and tail pointers are equal and
+		 * status tail is the same as command, then channel is free
+		 */
+		if (ioread16(&dma_reg->cpfhp) != ioread16(&dma_reg->cpftp) ||
+		    ioread16(&dma_reg->cpftp) != ioread16(&dma_reg->csftp))
+			busy = 1;
+		break;
+	case PPC440SPE_XOR_ID:
+		/* use the special status bit for the XORcore
+		 */
+		xor_reg = chan->device->xor_reg;
+		busy = (ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT) ? 1 : 0;
+		break;
+	}
+
+	return busy;
+}
+
+/**
+ * ppc440spe_chan_set_first_xor_descriptor -  init XORcore chain
+ */
+static void ppc440spe_chan_set_first_xor_descriptor(
+				struct ppc440spe_adma_chan *chan,
+				struct ppc440spe_adma_desc_slot *next_desc)
+{
+	struct xor_regs *xor_reg = chan->device->xor_reg;
+
+	if (ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT)
+		printk(KERN_INFO "%s: Warn: XORcore is running "
+			"when try to set the first CDB!\n",
+			__func__);
+
+	xor_last_submit = xor_last_linked = next_desc;
+
+	iowrite32be(XOR_CRSR_64BA_BIT, &xor_reg->crsr);
+
+	iowrite32be(next_desc->phys, &xor_reg->cblalr);
+	iowrite32be(0, &xor_reg->cblahr);
+	iowrite32be(ioread32be(&xor_reg->cbcr) | XOR_CBCR_LNK_BIT,
+		    &xor_reg->cbcr);
+
+	chan->hw_chain_inited = 1;
+}
+
+/**
+ * ppc440spe_dma_put_desc - put DMA0,1 descriptor to FIFO.
+ * called with irqs disabled
+ */
+static void ppc440spe_dma_put_desc(struct ppc440spe_adma_chan *chan,
+		struct ppc440spe_adma_desc_slot *desc)
+{
+	u32 pcdb;
+	struct dma_regs *dma_reg = chan->device->dma_reg;
+
+	pcdb = desc->phys;
+	if (!test_bit(PPC440SPE_DESC_INT, &desc->flags))
+		pcdb |= DMA_CDB_NO_INT;
+
+	chan_last_sub[chan->device->id] = desc;
+
+	ADMA_LL_DBG(print_cb(chan, desc->hw_desc));
+
+	iowrite32(pcdb, &dma_reg->cpfpl);
+}
+
+/**
+ * ppc440spe_chan_append - update the h/w chain in the channel
+ */
+static void ppc440spe_chan_append(struct ppc440spe_adma_chan *chan)
+{
+	struct xor_regs *xor_reg;
+	struct ppc440spe_adma_desc_slot *iter;
+	struct xor_cb *xcb;
+	u32 cur_desc;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		cur_desc = ppc440spe_chan_get_current_descriptor(chan);
+
+		if (likely(cur_desc)) {
+			iter = chan_last_sub[chan->device->id];
+			BUG_ON(!iter);
+		} else {
+			/* first peer */
+			iter = chan_first_cdb[chan->device->id];
+			BUG_ON(!iter);
+			ppc440spe_dma_put_desc(chan, iter);
+			chan->hw_chain_inited = 1;
+		}
+
+		/* is there something new to append */
+		if (!iter->hw_next)
+			break;
+
+		/* flush descriptors from the s/w queue to fifo */
+		list_for_each_entry_continue(iter, &chan->chain, chain_node) {
+			ppc440spe_dma_put_desc(chan, iter);
+			if (!iter->hw_next)
+				break;
+		}
+		break;
+	case PPC440SPE_XOR_ID:
+		/* update h/w links and refetch */
+		if (!xor_last_submit->hw_next)
+			break;
+
+		xor_reg = chan->device->xor_reg;
+		/* the last linked CDB has to generate an interrupt
+		 * that we'd be able to append the next lists to h/w
+		 * regardless of the XOR engine state at the moment of
+		 * appending of these next lists
+		 */
+		xcb = xor_last_linked->hw_desc;
+		xcb->cbc |= XOR_CBCR_CBCE_BIT;
+
+		if (!(ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT)) {
+			/* XORcore is idle. Refetch now */
+			do_xor_refetch = 0;
+			ppc440spe_xor_set_link(xor_last_submit,
+				xor_last_submit->hw_next);
+
+			ADMA_LL_DBG(print_cb_list(chan,
+				xor_last_submit->hw_next));
+
+			xor_last_submit = xor_last_linked;
+			iowrite32be(ioread32be(&xor_reg->crsr) |
+				    XOR_CRSR_RCBE_BIT | XOR_CRSR_64BA_BIT,
+				    &xor_reg->crsr);
+		} else {
+			/* XORcore is running. Refetch later in the handler */
+			do_xor_refetch = 1;
+		}
+
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+/**
+ * ppc440spe_chan_get_current_descriptor - get the currently executed descriptor
+ */
+static u32
+ppc440spe_chan_get_current_descriptor(struct ppc440spe_adma_chan *chan)
+{
+	struct dma_regs *dma_reg;
+	struct xor_regs *xor_reg;
+
+	if (unlikely(!chan->hw_chain_inited))
+		/* h/w descriptor chain is not initialized yet */
+		return 0;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		dma_reg = chan->device->dma_reg;
+		return ioread32(&dma_reg->acpl) & (~DMA_CDB_MSK);
+	case PPC440SPE_XOR_ID:
+		xor_reg = chan->device->xor_reg;
+		return ioread32be(&xor_reg->ccbalr);
+	}
+	return 0;
+}
+
+/**
+ * ppc440spe_chan_run - enable the channel
+ */
+static void ppc440spe_chan_run(struct ppc440spe_adma_chan *chan)
+{
+	struct xor_regs *xor_reg;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* DMAs are always enabled, do nothing */
+		break;
+	case PPC440SPE_XOR_ID:
+		/* drain write buffer */
+		xor_reg = chan->device->xor_reg;
+
+		/* fetch descriptor pointed to in <link> */
+		iowrite32be(XOR_CRSR_64BA_BIT | XOR_CRSR_XAE_BIT,
+			    &xor_reg->crsr);
+		break;
+	}
+}
+
+/******************************************************************************
+ * ADMA device level
+ ******************************************************************************/
+
+static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan);
+static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan);
+
+static dma_cookie_t
+ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx);
+
+static void ppc440spe_adma_set_dest(struct ppc440spe_adma_desc_slot *tx,
+				    dma_addr_t addr, int index);
+static void
+ppc440spe_adma_memcpy_xor_set_src(struct ppc440spe_adma_desc_slot *tx,
+				  dma_addr_t addr, int index);
+
+static void
+ppc440spe_adma_pq_set_dest(struct ppc440spe_adma_desc_slot *tx,
+			   dma_addr_t *paddr, unsigned long flags);
+static void
+ppc440spe_adma_pq_set_src(struct ppc440spe_adma_desc_slot *tx,
+			  dma_addr_t addr, int index);
+static void
+ppc440spe_adma_pq_set_src_mult(struct ppc440spe_adma_desc_slot *tx,
+			       unsigned char mult, int index, int dst_pos);
+static void
+ppc440spe_adma_pqzero_sum_set_dest(struct ppc440spe_adma_desc_slot *tx,
+				   dma_addr_t paddr, dma_addr_t qaddr);
+
+static struct page *ppc440spe_rxor_srcs[32];
+
+/**
+ * ppc440spe_can_rxor - check if the operands may be processed with RXOR
+ */
+static int ppc440spe_can_rxor(struct page **srcs, int src_cnt, size_t len)
+{
+	int i, order = 0, state = 0;
+	int idx = 0;
+
+	if (unlikely(!(src_cnt > 1)))
+		return 0;
+
+	BUG_ON(src_cnt > ARRAY_SIZE(ppc440spe_rxor_srcs));
+
+	/* Skip holes in the source list before checking */
+	for (i = 0; i < src_cnt; i++) {
+		if (!srcs[i])
+			continue;
+		ppc440spe_rxor_srcs[idx++] = srcs[i];
+	}
+	src_cnt = idx;
+
+	for (i = 1; i < src_cnt; i++) {
+		char *cur_addr = page_address(ppc440spe_rxor_srcs[i]);
+		char *old_addr = page_address(ppc440spe_rxor_srcs[i - 1]);
+
+		switch (state) {
+		case 0:
+			if (cur_addr == old_addr + len) {
+				/* direct RXOR */
+				order = 1;
+				state = 1;
+			} else if (old_addr == cur_addr + len) {
+				/* reverse RXOR */
+				order = -1;
+				state = 1;
+			} else
+				goto out;
+			break;
+		case 1:
+			if ((i == src_cnt - 2) ||
+			    (order == -1 && cur_addr != old_addr - len)) {
+				order = 0;
+				state = 0;
+			} else if ((cur_addr == old_addr + len * order) ||
+				   (cur_addr == old_addr + 2 * len) ||
+				   (cur_addr == old_addr + 3 * len)) {
+				state = 2;
+			} else {
+				order = 0;
+				state = 0;
+			}
+			break;
+		case 2:
+			order = 0;
+			state = 0;
+			break;
+		}
+	}
+
+out:
+	if (state == 1 || state == 2)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * ppc440spe_adma_device_estimate - estimate the efficiency of processing
+ *	the operation given on this channel. It's assumed that 'chan' is
+ *	capable to process 'cap' type of operation.
+ * @chan: channel to use
+ * @cap: type of transaction
+ * @dst_lst: array of destination pointers
+ * @dst_cnt: number of destination operands
+ * @src_lst: array of source pointers
+ * @src_cnt: number of source operands
+ * @src_sz: size of each source operand
+ */
+static int ppc440spe_adma_estimate(struct dma_chan *chan,
+	enum dma_transaction_type cap, struct page **dst_lst, int dst_cnt,
+	struct page **src_lst, int src_cnt, size_t src_sz)
+{
+	int ef = 1;
+
+	if (cap == DMA_PQ || cap == DMA_PQ_VAL) {
+		/* If RAID-6 capabilities were not activated don't try
+		 * to use them
+		 */
+		if (unlikely(!ppc440spe_r6_enabled))
+			return -1;
+	}
+	/*  In the current implementation of ppc440spe ADMA driver it
+	 * makes sense to pick out only pq case, because it may be
+	 * processed:
+	 * (1) either using Biskup method on DMA2;
+	 * (2) or on DMA0/1.
+	 *  Thus we give a favour to (1) if the sources are suitable;
+	 * else let it be processed on one of the DMA0/1 engines.
+	 *  In the sum_product case where destination is also the
+	 * source process it on DMA0/1 only.
+	 */
+	if (cap == DMA_PQ && chan->chan_id == PPC440SPE_XOR_ID) {
+
+		if (dst_cnt == 1 && src_cnt == 2 && dst_lst[0] == src_lst[1])
+			ef = 0; /* sum_product case, process on DMA0/1 */
+		else if (ppc440spe_can_rxor(src_lst, src_cnt, src_sz))
+			ef = 3; /* override (DMA0/1 + idle) */
+		else
+			ef = 0; /* can't process on DMA2 if !rxor */
+	}
+
+	/* channel idleness increases the priority */
+	if (likely(ef) &&
+	    !ppc440spe_chan_is_busy(to_ppc440spe_adma_chan(chan)))
+		ef++;
+
+	return ef;
+}
+
+struct dma_chan *
+ppc440spe_async_tx_find_best_channel(enum dma_transaction_type cap,
+	struct page **dst_lst, int dst_cnt, struct page **src_lst,
+	int src_cnt, size_t src_sz)
+{
+	struct dma_chan *best_chan = NULL;
+	struct ppc_dma_chan_ref *ref;
+	int best_rank = -1;
+
+	if (unlikely(!src_sz))
+		return NULL;
+	if (src_sz > PAGE_SIZE) {
+		/*
+		 * should a user of the api ever pass > PAGE_SIZE requests
+		 * we sort out cases where temporary page-sized buffers
+		 * are used.
+		 */
+		switch (cap) {
+		case DMA_PQ:
+			if (src_cnt == 1 && dst_lst[1] == src_lst[0])
+				return NULL;
+			if (src_cnt == 2 && dst_lst[1] == src_lst[1])
+				return NULL;
+			break;
+		case DMA_PQ_VAL:
+		case DMA_XOR_VAL:
+			return NULL;
+		default:
+			break;
+		}
+	}
+
+	list_for_each_entry(ref, &ppc440spe_adma_chan_list, node) {
+		if (dma_has_cap(cap, ref->chan->device->cap_mask)) {
+			int rank;
+
+			rank = ppc440spe_adma_estimate(ref->chan, cap, dst_lst,
+					dst_cnt, src_lst, src_cnt, src_sz);
+			if (rank > best_rank) {
+				best_rank = rank;
+				best_chan = ref->chan;
+			}
+		}
+	}
+
+	return best_chan;
+}
+EXPORT_SYMBOL_GPL(ppc440spe_async_tx_find_best_channel);
+
+/**
+ * ppc440spe_get_group_entry - get group entry with index idx
+ * @tdesc: is the last allocated slot in the group.
+ */
+static struct ppc440spe_adma_desc_slot *
+ppc440spe_get_group_entry(struct ppc440spe_adma_desc_slot *tdesc, u32 entry_idx)
+{
+	struct ppc440spe_adma_desc_slot *iter = tdesc->group_head;
+	int i = 0;
+
+	if (entry_idx < 0 || entry_idx >= (tdesc->src_cnt + tdesc->dst_cnt)) {
+		printk("%s: entry_idx %d, src_cnt %d, dst_cnt %d\n",
+			__func__, entry_idx, tdesc->src_cnt, tdesc->dst_cnt);
+		BUG();
+	}
+
+	list_for_each_entry(iter, &tdesc->group_list, chain_node) {
+		if (i++ == entry_idx)
+			break;
+	}
+	return iter;
+}
+
+/**
+ * ppc440spe_adma_free_slots - flags descriptor slots for reuse
+ * @slot: Slot to free
+ * Caller must hold &ppc440spe_chan->lock while calling this function
+ */
+static void ppc440spe_adma_free_slots(struct ppc440spe_adma_desc_slot *slot,
+				      struct ppc440spe_adma_chan *chan)
+{
+	int stride = slot->slots_per_op;
+
+	while (stride--) {
+		slot->slots_per_op = 0;
+		slot = list_entry(slot->slot_node.next,
+				struct ppc440spe_adma_desc_slot,
+				slot_node);
+	}
+}
+
+static void ppc440spe_adma_unmap(struct ppc440spe_adma_chan *chan,
+				 struct ppc440spe_adma_desc_slot *desc)
+{
+	u32 src_cnt, dst_cnt;
+	dma_addr_t addr;
+
+	/*
+	 * get the number of sources & destination
+	 * included in this descriptor and unmap
+	 * them all
+	 */
+	src_cnt = ppc440spe_desc_get_src_num(desc, chan);
+	dst_cnt = ppc440spe_desc_get_dst_num(desc, chan);
+
+	/* unmap destinations */
+	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+		while (dst_cnt--) {
+			addr = ppc440spe_desc_get_dest_addr(
+				desc, chan, dst_cnt);
+			dma_unmap_page(chan->device->dev,
+					addr, desc->unmap_len,
+					DMA_FROM_DEVICE);
+		}
+	}
+
+	/* unmap sources */
+	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+		while (src_cnt--) {
+			addr = ppc440spe_desc_get_src_addr(
+				desc, chan, src_cnt);
+			dma_unmap_page(chan->device->dev,
+					addr, desc->unmap_len,
+					DMA_TO_DEVICE);
+		}
+	}
+}
+
+/**
+ * ppc440spe_adma_run_tx_complete_actions - call functions to be called
+ * upon completion
+ */
+static dma_cookie_t ppc440spe_adma_run_tx_complete_actions(
+		struct ppc440spe_adma_desc_slot *desc,
+		struct ppc440spe_adma_chan *chan,
+		dma_cookie_t cookie)
+{
+	int i;
+
+	BUG_ON(desc->async_tx.cookie < 0);
+	if (desc->async_tx.cookie > 0) {
+		cookie = desc->async_tx.cookie;
+		desc->async_tx.cookie = 0;
+
+		/* call the callback (must not sleep or submit new
+		 * operations to this channel)
+		 */
+		if (desc->async_tx.callback)
+			desc->async_tx.callback(
+				desc->async_tx.callback_param);
+
+		/* unmap dma addresses
+		 * (unmap_single vs unmap_page?)
+		 *
+		 * actually, ppc's dma_unmap_page() functions are empty, so
+		 * the following code is just for the sake of completeness
+		 */
+		if (chan && chan->needs_unmap && desc->group_head &&
+		     desc->unmap_len) {
+			struct ppc440spe_adma_desc_slot *unmap =
+							desc->group_head;
+			/* assume 1 slot per op always */
+			u32 slot_count = unmap->slot_cnt;
+
+			/* Run through the group list and unmap addresses */
+			for (i = 0; i < slot_count; i++) {
+				BUG_ON(!unmap);
+				ppc440spe_adma_unmap(chan, unmap);
+				unmap = unmap->hw_next;
+			}
+		}
+	}
+
+	/* run dependent operations */
+	dma_run_dependencies(&desc->async_tx);
+
+	return cookie;
+}
+
+/**
+ * ppc440spe_adma_clean_slot - clean up CDB slot (if ack is set)
+ */
+static int ppc440spe_adma_clean_slot(struct ppc440spe_adma_desc_slot *desc,
+		struct ppc440spe_adma_chan *chan)
+{
+	/* the client is allowed to attach dependent operations
+	 * until 'ack' is set
+	 */
+	if (!async_tx_test_ack(&desc->async_tx))
+		return 0;
+
+	/* leave the last descriptor in the chain
+	 * so we can append to it
+	 */
+	if (list_is_last(&desc->chain_node, &chan->chain) ||
+	    desc->phys == ppc440spe_chan_get_current_descriptor(chan))
+		return 1;
+
+	if (chan->device->id != PPC440SPE_XOR_ID) {
+		/* our DMA interrupt handler clears opc field of
+		 * each processed descriptor. For all types of
+		 * operations except for ZeroSum we do not actually
+		 * need ack from the interrupt handler. ZeroSum is a
+		 * special case since the result of this operation
+		 * is available from the handler only, so if we see
+		 * such type of descriptor (which is unprocessed yet)
+		 * then leave it in chain.
+		 */
+		struct dma_cdb *cdb = desc->hw_desc;
+		if (cdb->opc == DMA_CDB_OPC_DCHECK128)
+			return 1;
+	}
+
+	dev_dbg(chan->device->common.dev, "\tfree slot %llx: %d stride: %d\n",
+		desc->phys, desc->idx, desc->slots_per_op);
+
+	list_del(&desc->chain_node);
+	ppc440spe_adma_free_slots(desc, chan);
+	return 0;
+}
+
+/**
+ * __ppc440spe_adma_slot_cleanup - this is the common clean-up routine
+ *	which runs through the channel CDBs list until reach the descriptor
+ *	currently processed. When routine determines that all CDBs of group
+ *	are completed then corresponding callbacks (if any) are called and slots
+ *	are freed.
+ */
+static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
+{
+	struct ppc440spe_adma_desc_slot *iter, *_iter, *group_start = NULL;
+	dma_cookie_t cookie = 0;
+	u32 current_desc = ppc440spe_chan_get_current_descriptor(chan);
+	int busy = ppc440spe_chan_is_busy(chan);
+	int seen_current = 0, slot_cnt = 0, slots_per_op = 0;
+
+	dev_dbg(chan->device->common.dev, "ppc440spe adma%d: %s\n",
+		chan->device->id, __func__);
+
+	if (!current_desc) {
+		/*  There were no transactions yet, so
+		 * nothing to clean
+		 */
+		return;
+	}
+
+	/* free completed slots from the chain starting with
+	 * the oldest descriptor
+	 */
+	list_for_each_entry_safe(iter, _iter, &chan->chain,
+					chain_node) {
+		dev_dbg(chan->device->common.dev, "\tcookie: %d slot: %d "
+		    "busy: %d this_desc: %#llx next_desc: %#x "
+		    "cur: %#x ack: %d\n",
+		    iter->async_tx.cookie, iter->idx, busy, iter->phys,
+		    ppc440spe_desc_get_link(iter, chan), current_desc,
+		    async_tx_test_ack(&iter->async_tx));
+		prefetch(_iter);
+		prefetch(&_iter->async_tx);
+
+		/* do not advance past the current descriptor loaded into the
+		 * hardware channel,subsequent descriptors are either in process
+		 * or have not been submitted
+		 */
+		if (seen_current)
+			break;
+
+		/* stop the search if we reach the current descriptor and the
+		 * channel is busy, or if it appears that the current descriptor
+		 * needs to be re-read (i.e. has been appended to)
+		 */
+		if (iter->phys == current_desc) {
+			BUG_ON(seen_current++);
+			if (busy || ppc440spe_desc_get_link(iter, chan)) {
+				/* not all descriptors of the group have
+				 * been completed; exit.
+				 */
+				break;
+			}
+		}
+
+		/* detect the start of a group transaction */
+		if (!slot_cnt && !slots_per_op) {
+			slot_cnt = iter->slot_cnt;
+			slots_per_op = iter->slots_per_op;
+			if (slot_cnt <= slots_per_op) {
+				slot_cnt = 0;
+				slots_per_op = 0;
+			}
+		}
+
+		if (slot_cnt) {
+			if (!group_start)
+				group_start = iter;
+			slot_cnt -= slots_per_op;
+		}
+
+		/* all the members of a group are complete */
+		if (slots_per_op != 0 && slot_cnt == 0) {
+			struct ppc440spe_adma_desc_slot *grp_iter, *_grp_iter;
+			int end_of_chain = 0;
+
+			/* clean up the group */
+			slot_cnt = group_start->slot_cnt;
+			grp_iter = group_start;
+			list_for_each_entry_safe_from(grp_iter, _grp_iter,
+				&chan->chain, chain_node) {
+
+				cookie = ppc440spe_adma_run_tx_complete_actions(
+					grp_iter, chan, cookie);
+
+				slot_cnt -= slots_per_op;
+				end_of_chain = ppc440spe_adma_clean_slot(
+				    grp_iter, chan);
+				if (end_of_chain && slot_cnt) {
+					/* Should wait for ZeroSum completion */
+					if (cookie > 0)
+						chan->completed_cookie = cookie;
+					return;
+				}
+
+				if (slot_cnt == 0 || end_of_chain)
+					break;
+			}
+
+			/* the group should be complete at this point */
+			BUG_ON(slot_cnt);
+
+			slots_per_op = 0;
+			group_start = NULL;
+			if (end_of_chain)
+				break;
+			else
+				continue;
+		} else if (slots_per_op) /* wait for group completion */
+			continue;
+
+		cookie = ppc440spe_adma_run_tx_complete_actions(iter, chan,
+		    cookie);
+
+		if (ppc440spe_adma_clean_slot(iter, chan))
+			break;
+	}
+
+	BUG_ON(!seen_current);
+
+	if (cookie > 0) {
+		chan->completed_cookie = cookie;
+		pr_debug("\tcompleted cookie %d\n", cookie);
+	}
+
+}
+
+/**
+ * ppc440spe_adma_tasklet - clean up watch-dog initiator
+ */
+static void ppc440spe_adma_tasklet(unsigned long data)
+{
+	struct ppc440spe_adma_chan *chan = (struct ppc440spe_adma_chan *) data;
+
+	spin_lock_nested(&chan->lock, SINGLE_DEPTH_NESTING);
+	__ppc440spe_adma_slot_cleanup(chan);
+	spin_unlock(&chan->lock);
+}
+
+/**
+ * ppc440spe_adma_slot_cleanup - clean up scheduled initiator
+ */
+static void ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan)
+{
+	spin_lock_bh(&chan->lock);
+	__ppc440spe_adma_slot_cleanup(chan);
+	spin_unlock_bh(&chan->lock);
+}
+
+/**
+ * ppc440spe_adma_alloc_slots - allocate free slots (if any)
+ */
+static struct ppc440spe_adma_desc_slot *ppc440spe_adma_alloc_slots(
+		struct ppc440spe_adma_chan *chan, int num_slots,
+		int slots_per_op)
+{
+	struct ppc440spe_adma_desc_slot *iter = NULL, *_iter;
+	struct ppc440spe_adma_desc_slot *alloc_start = NULL;
+	struct list_head chain = LIST_HEAD_INIT(chain);
+	int slots_found, retry = 0;
+
+
+	BUG_ON(!num_slots || !slots_per_op);
+	/* start search from the last allocated descrtiptor
+	 * if a contiguous allocation can not be found start searching
+	 * from the beginning of the list
+	 */
+retry:
+	slots_found = 0;
+	if (retry == 0)
+		iter = chan->last_used;
+	else
+		iter = list_entry(&chan->all_slots,
+				  struct ppc440spe_adma_desc_slot,
+				  slot_node);
+	list_for_each_entry_safe_continue(iter, _iter, &chan->all_slots,
+	    slot_node) {
+		prefetch(_iter);
+		prefetch(&_iter->async_tx);
+		if (iter->slots_per_op) {
+			slots_found = 0;
+			continue;
+		}
+
+		/* start the allocation if the slot is correctly aligned */
+		if (!slots_found++)
+			alloc_start = iter;
+
+		if (slots_found == num_slots) {
+			struct ppc440spe_adma_desc_slot *alloc_tail = NULL;
+			struct ppc440spe_adma_desc_slot *last_used = NULL;
+
+			iter = alloc_start;
+			while (num_slots) {
+				int i;
+				/* pre-ack all but the last descriptor */
+				if (num_slots != slots_per_op)
+					async_tx_ack(&iter->async_tx);
+
+				list_add_tail(&iter->chain_node, &chain);
+				alloc_tail = iter;
+				iter->async_tx.cookie = 0;
+				iter->hw_next = NULL;
+				iter->flags = 0;
+				iter->slot_cnt = num_slots;
+				iter->xor_check_result = NULL;
+				for (i = 0; i < slots_per_op; i++) {
+					iter->slots_per_op = slots_per_op - i;
+					last_used = iter;
+					iter = list_entry(iter->slot_node.next,
+						struct ppc440spe_adma_desc_slot,
+						slot_node);
+				}
+				num_slots -= slots_per_op;
+			}
+			alloc_tail->group_head = alloc_start;
+			alloc_tail->async_tx.cookie = -EBUSY;
+			list_splice(&chain, &alloc_tail->group_list);
+			chan->last_used = last_used;
+			return alloc_tail;
+		}
+	}
+	if (!retry++)
+		goto retry;
+
+	/* try to free some slots if the allocation fails */
+	tasklet_schedule(&chan->irq_tasklet);
+	return NULL;
+}
+
+/**
+ * ppc440spe_adma_alloc_chan_resources -  allocate pools for CDB slots
+ */
+static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+	struct ppc440spe_adma_desc_slot *slot = NULL;
+	char *hw_desc;
+	int i, db_sz;
+	int init;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+	init = ppc440spe_chan->slots_allocated ? 0 : 1;
+	chan->chan_id = ppc440spe_chan->device->id;
+
+	/* Allocate descriptor slots */
+	i = ppc440spe_chan->slots_allocated;
+	if (ppc440spe_chan->device->id != PPC440SPE_XOR_ID)
+		db_sz = sizeof(struct dma_cdb);
+	else
+		db_sz = sizeof(struct xor_cb);
+
+	for (; i < (ppc440spe_chan->device->pool_size / db_sz); i++) {
+		slot = kzalloc(sizeof(struct ppc440spe_adma_desc_slot),
+			       GFP_KERNEL);
+		if (!slot) {
+			printk(KERN_INFO "SPE ADMA Channel only initialized"
+				" %d descriptor slots", i--);
+			break;
+		}
+
+		hw_desc = (char *) ppc440spe_chan->device->dma_desc_pool_virt;
+		slot->hw_desc = (void *) &hw_desc[i * db_sz];
+		dma_async_tx_descriptor_init(&slot->async_tx, chan);
+		slot->async_tx.tx_submit = ppc440spe_adma_tx_submit;
+		INIT_LIST_HEAD(&slot->chain_node);
+		INIT_LIST_HEAD(&slot->slot_node);
+		INIT_LIST_HEAD(&slot->group_list);
+		slot->phys = ppc440spe_chan->device->dma_desc_pool + i * db_sz;
+		slot->idx = i;
+
+		spin_lock_bh(&ppc440spe_chan->lock);
+		ppc440spe_chan->slots_allocated++;
+		list_add_tail(&slot->slot_node, &ppc440spe_chan->all_slots);
+		spin_unlock_bh(&ppc440spe_chan->lock);
+	}
+
+	if (i && !ppc440spe_chan->last_used) {
+		ppc440spe_chan->last_used =
+			list_entry(ppc440spe_chan->all_slots.next,
+				struct ppc440spe_adma_desc_slot,
+				slot_node);
+	}
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: allocated %d descriptor slots\n",
+		ppc440spe_chan->device->id, i);
+
+	/* initialize the channel and the chain with a null operation */
+	if (init) {
+		switch (ppc440spe_chan->device->id) {
+		case PPC440SPE_DMA0_ID:
+		case PPC440SPE_DMA1_ID:
+			ppc440spe_chan->hw_chain_inited = 0;
+			/* Use WXOR for self-testing */
+			if (!ppc440spe_r6_tchan)
+				ppc440spe_r6_tchan = ppc440spe_chan;
+			break;
+		case PPC440SPE_XOR_ID:
+			ppc440spe_chan_start_null_xor(ppc440spe_chan);
+			break;
+		default:
+			BUG();
+		}
+		ppc440spe_chan->needs_unmap = 1;
+	}
+
+	return (i > 0) ? i : -ENOMEM;
+}
+
+/**
+ * ppc440spe_desc_assign_cookie - assign a cookie
+ */
+static dma_cookie_t ppc440spe_desc_assign_cookie(
+		struct ppc440spe_adma_chan *chan,
+		struct ppc440spe_adma_desc_slot *desc)
+{
+	dma_cookie_t cookie = chan->common.cookie;
+
+	cookie++;
+	if (cookie < 0)
+		cookie = 1;
+	chan->common.cookie = desc->async_tx.cookie = cookie;
+	return cookie;
+}
+
+/**
+ * ppc440spe_rxor_set_region_data -
+ */
+static void ppc440spe_rxor_set_region(struct ppc440spe_adma_desc_slot *desc,
+	u8 xor_arg_no, u32 mask)
+{
+	struct xor_cb *xcb = desc->hw_desc;
+
+	xcb->ops[xor_arg_no].h |= mask;
+}
+
+/**
+ * ppc440spe_rxor_set_src -
+ */
+static void ppc440spe_rxor_set_src(struct ppc440spe_adma_desc_slot *desc,
+	u8 xor_arg_no, dma_addr_t addr)
+{
+	struct xor_cb *xcb = desc->hw_desc;
+
+	xcb->ops[xor_arg_no].h |= DMA_CUED_XOR_BASE;
+	xcb->ops[xor_arg_no].l = addr;
+}
+
+/**
+ * ppc440spe_rxor_set_mult -
+ */
+static void ppc440spe_rxor_set_mult(struct ppc440spe_adma_desc_slot *desc,
+	u8 xor_arg_no, u8 idx, u8 mult)
+{
+	struct xor_cb *xcb = desc->hw_desc;
+
+	xcb->ops[xor_arg_no].h |= mult << (DMA_CUED_MULT1_OFF + idx * 8);
+}
+
+/**
+ * ppc440spe_adma_check_threshold - append CDBs to h/w chain if threshold
+ *	has been achieved
+ */
+static void ppc440spe_adma_check_threshold(struct ppc440spe_adma_chan *chan)
+{
+	dev_dbg(chan->device->common.dev, "ppc440spe adma%d: pending: %d\n",
+		chan->device->id, chan->pending);
+
+	if (chan->pending >= PPC440SPE_ADMA_THRESHOLD) {
+		chan->pending = 0;
+		ppc440spe_chan_append(chan);
+	}
+}
+
+/**
+ * ppc440spe_adma_tx_submit - submit new descriptor group to the channel
+ *	(it's not necessary that descriptors will be submitted to the h/w
+ *	chains too right now)
+ */
+static dma_cookie_t ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct ppc440spe_adma_desc_slot *sw_desc;
+	struct ppc440spe_adma_chan *chan = to_ppc440spe_adma_chan(tx->chan);
+	struct ppc440spe_adma_desc_slot *group_start, *old_chain_tail;
+	int slot_cnt;
+	int slots_per_op;
+	dma_cookie_t cookie;
+
+	sw_desc = tx_to_ppc440spe_adma_slot(tx);
+
+	group_start = sw_desc->group_head;
+	slot_cnt = group_start->slot_cnt;
+	slots_per_op = group_start->slots_per_op;
+
+	spin_lock_bh(&chan->lock);
+
+	cookie = ppc440spe_desc_assign_cookie(chan, sw_desc);
+
+	if (unlikely(list_empty(&chan->chain))) {
+		/* first peer */
+		list_splice_init(&sw_desc->group_list, &chan->chain);
+		chan_first_cdb[chan->device->id] = group_start;
+	} else {
+		/* isn't first peer, bind CDBs to chain */
+		old_chain_tail = list_entry(chan->chain.prev,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		list_splice_init(&sw_desc->group_list,
+		    &old_chain_tail->chain_node);
+		/* fix up the hardware chain */
+		ppc440spe_desc_set_link(chan, old_chain_tail, group_start);
+	}
+
+	/* increment the pending count by the number of operations */
+	chan->pending += slot_cnt / slots_per_op;
+	ppc440spe_adma_check_threshold(chan);
+	spin_unlock_bh(&chan->lock);
+
+	dev_dbg(chan->device->common.dev,
+		"ppc440spe adma%d: %s cookie: %d slot: %d tx %p\n",
+		chan->device->id, __func__,
+		sw_desc->async_tx.cookie, sw_desc->idx, sw_desc);
+
+	return cookie;
+}
+
+/**
+ * ppc440spe_adma_prep_dma_interrupt - prepare CDB for a pseudo DMA operation
+ */
+static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_interrupt(
+		struct dma_chan *chan, 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);
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: %s\n", ppc440spe_chan->device->id,
+		__func__);
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	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_interrupt(group_start, ppc440spe_chan);
+		group_start->unmap_len = 0;
+		sw_desc->async_tx.flags = flags;
+	}
+	spin_unlock_bh(&ppc440spe_chan->lock);
+
+	return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+/**
+ * ppc440spe_adma_prep_dma_memcpy - prepare CDB for a MEMCPY operation
+ */
+static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memcpy(
+		struct dma_chan *chan, dma_addr_t dma_dest,
+		dma_addr_t dma_src, 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(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT));
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: %s len: %u int_en %d\n",
+		ppc440spe_chan->device->id, __func__, 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_memcpy(group_start, flags);
+		ppc440spe_adma_set_dest(group_start, dma_dest, 0);
+		ppc440spe_adma_memcpy_xor_set_src(group_start, dma_src, 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_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(unlikely(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(
+		struct dma_chan *chan, dma_addr_t dma_dest,
+		dma_addr_t *dma_src, u32 src_cnt, 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);
+
+	ADMA_LL_DBG(prep_dma_xor_dbg(ppc440spe_chan->device->id,
+				     dma_dest, dma_src, src_cnt));
+	if (unlikely(!len))
+		return NULL;
+	BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT));
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n",
+		ppc440spe_chan->device->id, __func__, src_cnt, len,
+		flags & DMA_PREP_INTERRUPT ? 1 : 0);
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	slot_cnt = ppc440spe_chan_xor_slot_count(len, src_cnt, &slots_per_op);
+	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_xor(group_start, src_cnt, flags);
+		ppc440spe_adma_set_dest(group_start, dma_dest, 0);
+		while (src_cnt--)
+			ppc440spe_adma_memcpy_xor_set_src(group_start,
+				dma_src[src_cnt], src_cnt);
+		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;
+}
+
+static inline void
+ppc440spe_desc_set_xor_src_cnt(struct ppc440spe_adma_desc_slot *desc,
+				int src_cnt);
+static void ppc440spe_init_rxor_cursor(struct ppc440spe_rxor *cursor);
+
+/**
+ * ppc440spe_adma_init_dma2rxor_slot -
+ */
+static void ppc440spe_adma_init_dma2rxor_slot(
+		struct ppc440spe_adma_desc_slot *desc,
+		dma_addr_t *src, int src_cnt)
+{
+	int i;
+
+	/* initialize CDB */
+	for (i = 0; i < src_cnt; i++) {
+		ppc440spe_adma_dma2rxor_prep_src(desc, &desc->rxor_cursor, i,
+						 desc->src_cnt, (u32)src[i]);
+	}
+}
+
+/**
+ * ppc440spe_dma01_prep_mult -
+ * for Q operation where destination is also the source
+ */
+static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_mult(
+		struct ppc440spe_adma_chan *ppc440spe_chan,
+		dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt,
+		const unsigned char *scf, size_t len, unsigned long flags)
+{
+	struct ppc440spe_adma_desc_slot *sw_desc = NULL;
+	unsigned long op = 0;
+	int slot_cnt;
+
+	set_bit(PPC440SPE_DESC_WXOR, &op);
+	slot_cnt = 2;
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+
+	/* use WXOR, each descriptor occupies one slot */
+	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1);
+	if (sw_desc) {
+		struct ppc440spe_adma_chan *chan;
+		struct ppc440spe_adma_desc_slot *iter;
+		struct dma_cdb *hw_desc;
+
+		chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+		set_bits(op, &sw_desc->flags);
+		sw_desc->src_cnt = src_cnt;
+		sw_desc->dst_cnt = dst_cnt;
+		/* First descriptor, zero data in the destination and copy it
+		 * to q page using MULTICAST transfer.
+		 */
+		iter = list_first_entry(&sw_desc->group_list,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		/* set 'next' pointer */
+		iter->hw_next = list_entry(iter->chain_node.next,
+					   struct ppc440spe_adma_desc_slot,
+					   chain_node);
+		clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MULTICAST;
+
+		ppc440spe_desc_set_dest_addr(iter, chan,
+					     DMA_CUED_XOR_BASE, dst[0], 0);
+		ppc440spe_desc_set_dest_addr(iter, chan, 0, dst[1], 1);
+		ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB,
+					    src[0]);
+		ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len);
+		iter->unmap_len = len;
+
+		/*
+		 * Second descriptor, multiply data from the q page
+		 * and store the result in real destination.
+		 */
+		iter = list_first_entry(&iter->chain_node,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		iter->hw_next = NULL;
+		if (flags & DMA_PREP_INTERRUPT)
+			set_bit(PPC440SPE_DESC_INT, &iter->flags);
+		else
+			clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+		ppc440spe_desc_set_src_addr(iter, chan, 0,
+					    DMA_CUED_XOR_HB, dst[1]);
+		ppc440spe_desc_set_dest_addr(iter, chan,
+					     DMA_CUED_XOR_BASE, dst[0], 0);
+
+		ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF,
+					    DMA_CDB_SG_DST1, scf[0]);
+		ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len);
+		iter->unmap_len = len;
+		sw_desc->async_tx.flags = flags;
+	}
+
+	spin_unlock_bh(&ppc440spe_chan->lock);
+
+	return sw_desc;
+}
+
+/**
+ * ppc440spe_dma01_prep_sum_product -
+ * Dx = A*(P+Pxy) + B*(Q+Qxy) operation where destination is also
+ * the source.
+ */
+static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_sum_product(
+		struct ppc440spe_adma_chan *ppc440spe_chan,
+		dma_addr_t *dst, dma_addr_t *src, int src_cnt,
+		const unsigned char *scf, size_t len, unsigned long flags)
+{
+	struct ppc440spe_adma_desc_slot *sw_desc = NULL;
+	unsigned long op = 0;
+	int slot_cnt;
+
+	set_bit(PPC440SPE_DESC_WXOR, &op);
+	slot_cnt = 3;
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+
+	/* WXOR, each descriptor occupies one slot */
+	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1);
+	if (sw_desc) {
+		struct ppc440spe_adma_chan *chan;
+		struct ppc440spe_adma_desc_slot *iter;
+		struct dma_cdb *hw_desc;
+
+		chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+		set_bits(op, &sw_desc->flags);
+		sw_desc->src_cnt = src_cnt;
+		sw_desc->dst_cnt = 1;
+		/* 1st descriptor, src[1] data to q page and zero destination */
+		iter = list_first_entry(&sw_desc->group_list,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		iter->hw_next = list_entry(iter->chain_node.next,
+					   struct ppc440spe_adma_desc_slot,
+					   chain_node);
+		clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MULTICAST;
+
+		ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE,
+					     *dst, 0);
+		ppc440spe_desc_set_dest_addr(iter, chan, 0,
+					     ppc440spe_chan->qdest, 1);
+		ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB,
+					    src[1]);
+		ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len);
+		iter->unmap_len = len;
+
+		/* 2nd descriptor, multiply src[1] data and store the
+		 * result in destination */
+		iter = list_first_entry(&iter->chain_node,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		/* set 'next' pointer */
+		iter->hw_next = list_entry(iter->chain_node.next,
+					   struct ppc440spe_adma_desc_slot,
+					   chain_node);
+		if (flags & DMA_PREP_INTERRUPT)
+			set_bit(PPC440SPE_DESC_INT, &iter->flags);
+		else
+			clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+		ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB,
+					    ppc440spe_chan->qdest);
+		ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE,
+					     *dst, 0);
+		ppc440spe_desc_set_src_mult(iter, chan,	DMA_CUED_MULT1_OFF,
+					    DMA_CDB_SG_DST1, scf[1]);
+		ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len);
+		iter->unmap_len = len;
+
+		/*
+		 * 3rd descriptor, multiply src[0] data and xor it
+		 * with destination
+		 */
+		iter = list_first_entry(&iter->chain_node,
+					struct ppc440spe_adma_desc_slot,
+					chain_node);
+		memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+		iter->hw_next = NULL;
+		if (flags & DMA_PREP_INTERRUPT)
+			set_bit(PPC440SPE_DESC_INT, &iter->flags);
+		else
+			clear_bit(PPC440SPE_DESC_INT, &iter->flags);
+
+		hw_desc = iter->hw_desc;
+		hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+		ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB,
+					    src[0]);
+		ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE,
+					     *dst, 0);
+		ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF,
+					    DMA_CDB_SG_DST1, scf[0]);
+		ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len);
+		iter->unmap_len = len;
+		sw_desc->async_tx.flags = flags;
+	}
+
+	spin_unlock_bh(&ppc440spe_chan->lock);
+
+	return sw_desc;
+}
+
+static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_pq(
+		struct ppc440spe_adma_chan *ppc440spe_chan,
+		dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt,
+		const unsigned char *scf, size_t len, unsigned long flags)
+{
+	int slot_cnt;
+	struct ppc440spe_adma_desc_slot *sw_desc = NULL, *iter;
+	unsigned long op = 0;
+	unsigned char mult = 1;
+
+	pr_debug("%s: dst_cnt %d, src_cnt %d, len %d\n",
+		 __func__, dst_cnt, src_cnt, len);
+	/*  select operations WXOR/RXOR depending on the
+	 * source addresses of operators and the number
+	 * of destinations (RXOR support only Q-parity calculations)
+	 */
+	set_bit(PPC440SPE_DESC_WXOR, &op);
+	if (!test_and_set_bit(PPC440SPE_RXOR_RUN, &ppc440spe_rxor_state)) {
+		/* no active RXOR;
+		 * do RXOR if:
+		 * - there are more than 1 source,
+		 * - len is aligned on 512-byte boundary,
+		 * - source addresses fit to one of 4 possible regions.
+		 */
+		if (src_cnt > 1 &&
+		    !(len & MQ0_CF2H_RXOR_BS_MASK) &&
+		    (src[0] + len) == src[1]) {
+			/* may do RXOR R1 R2 */
+			set_bit(PPC440SPE_DESC_RXOR, &op);
+			if (src_cnt != 2) {
+				/* may try to enhance region of RXOR */
+				if ((src[1] + len) == src[2]) {
+					/* do RXOR R1 R2 R3 */
+					set_bit(PPC440SPE_DESC_RXOR123,
+						&op);
+				} else if ((src[1] + len * 2) == src[2]) {
+					/* do RXOR R1 R2 R4 */
+					set_bit(PPC440SPE_DESC_RXOR124, &op);
+				} else if ((src[1] + len * 3) == src[2]) {
+					/* do RXOR R1 R2 R5 */
+					set_bit(PPC440SPE_DESC_RXOR125,
+						&op);
+				} else {
+					/* do RXOR R1 R2 */
+					set_bit(PPC440SPE_DESC_RXOR12,
+						&op);
+				}
+			} else {
+				/* do RXOR R1 R2 */
+				set_bit(PPC440SPE_DESC_RXOR12, &op);
+			}
+		}
+
+		if (!test_bit(PPC440SPE_DESC_RXOR, &op)) {
+			/* can not do this operation with RXOR */
+			clear_bit(PPC440SPE_RXOR_RUN,
+				&ppc440spe_rxor_state);
+		} else {
+			/* can do; set block size right now */
+			ppc440spe_desc_set_rxor_block_size(len);
+		}
+	}
+
+	/* Number of necessary slots depends on operation type selected */
+	if (!test_bit(PPC440SPE_DESC_RXOR, &op)) {
+		/*  This is a WXOR only chain. Need descriptors for each
+		 * source to GF-XOR them with WXOR, and need descriptors
+		 * for each destination to zero them with WXOR
+		 */
+		slot_cnt = src_cnt;
+
+		if (flags & DMA_PREP_ZERO_P) {
+			slot_cnt++;
+			set_bit(PPC440SPE_ZERO_P, &op);
+		}
+		if (flags & DMA_PREP_ZERO_Q) {
+			slot_cnt++;
+			set_bit(PPC440SPE_ZERO_Q, &op);
+		}
+	} else {
+		/*  Need 1/2 descriptor for RXOR operation, and
+		 * need (src_cnt - (2 or 3)) for WXOR of sources
+		 * remained (if any)
+		 */
+		slot_cnt = dst_cnt;
+
+		if (flags & DMA_PREP_ZERO_P)
+			set_bit(PPC440SPE_ZERO_P, &op);
+		if (flags & DMA_PREP_ZERO_Q)
+			set_bit(PPC440SPE_ZERO_Q, &op);
+
+		if (test_bit(PPC440SPE_DESC_RXOR12, &op))
+			slot_cnt += src_cnt - 2;
+		else
+			slot_cnt += src_cnt - 3;
+
+		/*  Thus we have either RXOR only chain or
+		 * mixed RXOR/WXOR
+		 */
+		if (slot_cnt == dst_cnt)
+			/* RXOR only chain */
+			clear_bit(PPC440SPE_DESC_WXOR, &op);
+	}
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	/* for both RXOR/WXOR each descriptor occupies one slot */
+	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1);
+	if (sw_desc) {
+		ppc440spe_desc_init_dma01pq(sw_desc, dst_cnt, src_cnt,
+				flags, op);
+
+		/* setup dst/src/mult */
+		pr_debug("%s: set dst descriptor 0, 1: 0x%016llx, 0x%016llx\n",
+			 __func__, dst[0], dst[1]);
+		ppc440spe_adma_pq_set_dest(sw_desc, dst, flags);
+		while (src_cnt--) {
+			ppc440spe_adma_pq_set_src(sw_desc, src[src_cnt],
+						  src_cnt);
+
+			/* NOTE: "Multi = 0 is equivalent to = 1" as it
+			 * stated in 440SPSPe_RAID6_Addendum_UM_1_17.pdf
+			 * doesn't work for RXOR with DMA0/1! Instead, multi=0
+			 * leads to zeroing source data after RXOR.
+			 * So, for P case set-up mult=1 explicitly.
+			 */
+			if (!(flags & DMA_PREP_PQ_DISABLE_Q))
+				mult = scf[src_cnt];
+			ppc440spe_adma_pq_set_src_mult(sw_desc,
+				mult, src_cnt,  dst_cnt - 1);
+		}
+
+		/* Setup byte count foreach slot just allocated */
+		sw_desc->async_tx.flags = flags;
+		list_for_each_entry(iter, &sw_desc->group_list,
+				chain_node) {
+			ppc440spe_desc_set_byte_count(iter,
+				ppc440spe_chan, len);
+			iter->unmap_len = len;
+		}
+	}
+	spin_unlock_bh(&ppc440spe_chan->lock);
+
+	return sw_desc;
+}
+
+static struct ppc440spe_adma_desc_slot *ppc440spe_dma2_prep_pq(
+		struct ppc440spe_adma_chan *ppc440spe_chan,
+		dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt,
+		const unsigned char *scf, size_t len, unsigned long flags)
+{
+	int slot_cnt, descs_per_op;
+	struct ppc440spe_adma_desc_slot *sw_desc = NULL, *iter;
+	unsigned long op = 0;
+	unsigned char mult = 1;
+
+	BUG_ON(!dst_cnt);
+	/*pr_debug("%s: dst_cnt %d, src_cnt %d, len %d\n",
+		 __func__, dst_cnt, src_cnt, len);*/
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	descs_per_op = ppc440spe_dma2_pq_slot_count(src, src_cnt, len);
+	if (descs_per_op < 0) {
+		spin_unlock_bh(&ppc440spe_chan->lock);
+		return NULL;
+	}
+
+	/* depending on number of sources we have 1 or 2 RXOR chains */
+	slot_cnt = descs_per_op * dst_cnt;
+
+	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1);
+	if (sw_desc) {
+		op = slot_cnt;
+		sw_desc->async_tx.flags = flags;
+		list_for_each_entry(iter, &sw_desc->group_list, chain_node) {
+			ppc440spe_desc_init_dma2pq(iter, dst_cnt, src_cnt,
+				--op ? 0 : flags);
+			ppc440spe_desc_set_byte_count(iter, ppc440spe_chan,
+				len);
+			iter->unmap_len = len;
+
+			ppc440spe_init_rxor_cursor(&(iter->rxor_cursor));
+			iter->rxor_cursor.len = len;
+			iter->descs_per_op = descs_per_op;
+		}
+		op = 0;
+		list_for_each_entry(iter, &sw_desc->group_list, chain_node) {
+			op++;
+			if (op % descs_per_op == 0)
+				ppc440spe_adma_init_dma2rxor_slot(iter, src,
+								  src_cnt);
+			if (likely(!list_is_last(&iter->chain_node,
+						 &sw_desc->group_list))) {
+				/* set 'next' pointer */
+				iter->hw_next =
+					list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+				ppc440spe_xor_set_link(iter, iter->hw_next);
+			} else {
+				/* this is the last descriptor. */
+				iter->hw_next = NULL;
+			}
+		}
+
+		/* fixup head descriptor */
+		sw_desc->dst_cnt = dst_cnt;
+		if (flags & DMA_PREP_ZERO_P)
+			set_bit(PPC440SPE_ZERO_P, &sw_desc->flags);
+		if (flags & DMA_PREP_ZERO_Q)
+			set_bit(PPC440SPE_ZERO_Q, &sw_desc->flags);
+
+		/* setup dst/src/mult */
+		ppc440spe_adma_pq_set_dest(sw_desc, dst, flags);
+
+		while (src_cnt--) {
+			/* handle descriptors (if dst_cnt == 2) inside
+			 * the ppc440spe_adma_pq_set_srcxxx() functions
+			 */
+			ppc440spe_adma_pq_set_src(sw_desc, src[src_cnt],
+						  src_cnt);
+			if (!(flags & DMA_PREP_PQ_DISABLE_Q))
+				mult = scf[src_cnt];
+			ppc440spe_adma_pq_set_src_mult(sw_desc,
+					mult, src_cnt, dst_cnt - 1);
+		}
+	}
+	spin_unlock_bh(&ppc440spe_chan->lock);
+	ppc440spe_desc_set_rxor_block_size(len);
+	return sw_desc;
+}
+
+/**
+ * ppc440spe_adma_prep_dma_pq - prepare CDB (group) for a GF-XOR operation
+ */
+static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pq(
+		struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
+		unsigned int src_cnt, const unsigned char *scf,
+		size_t len, unsigned long flags)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+	struct ppc440spe_adma_desc_slot *sw_desc = NULL;
+	int dst_cnt = 0;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+
+	ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id,
+				    dst, src, src_cnt));
+	BUG_ON(!len);
+	BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT));
+	BUG_ON(!src_cnt);
+
+	if (src_cnt == 1 && dst[1] == src[0]) {
+		dma_addr_t dest[2];
+
+		/* dst[1] is real destination (Q) */
+		dest[0] = dst[1];
+		/* this is the page to multicast source data to */
+		dest[1] = ppc440spe_chan->qdest;
+		sw_desc = ppc440spe_dma01_prep_mult(ppc440spe_chan,
+				dest, 2, src, src_cnt, scf, len, flags);
+		return sw_desc ? &sw_desc->async_tx : NULL;
+	}
+
+	if (src_cnt == 2 && dst[1] == src[1]) {
+		sw_desc = ppc440spe_dma01_prep_sum_product(ppc440spe_chan,
+					&dst[1], src, 2, scf, len, flags);
+		return sw_desc ? &sw_desc->async_tx : NULL;
+	}
+
+	if (!(flags & DMA_PREP_PQ_DISABLE_P)) {
+		BUG_ON(!dst[0]);
+		dst_cnt++;
+		flags |= DMA_PREP_ZERO_P;
+	}
+
+	if (!(flags & DMA_PREP_PQ_DISABLE_Q)) {
+		BUG_ON(!dst[1]);
+		dst_cnt++;
+		flags |= DMA_PREP_ZERO_Q;
+	}
+
+	BUG_ON(!dst_cnt);
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n",
+		ppc440spe_chan->device->id, __func__, src_cnt, len,
+		flags & DMA_PREP_INTERRUPT ? 1 : 0);
+
+	switch (ppc440spe_chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		sw_desc = ppc440spe_dma01_prep_pq(ppc440spe_chan,
+				dst, dst_cnt, src, src_cnt, scf,
+				len, flags);
+		break;
+
+	case PPC440SPE_XOR_ID:
+		sw_desc = ppc440spe_dma2_prep_pq(ppc440spe_chan,
+				dst, dst_cnt, src, src_cnt, scf,
+				len, flags);
+		break;
+	}
+
+	return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+/**
+ * ppc440spe_adma_prep_dma_pqzero_sum - prepare CDB group for
+ * a PQ_ZERO_SUM operation
+ */
+static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pqzero_sum(
+		struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
+		unsigned int src_cnt, const unsigned char *scf, size_t len,
+		enum sum_check_flags *pqres, unsigned long flags)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+	struct ppc440spe_adma_desc_slot *sw_desc, *iter;
+	dma_addr_t pdest, qdest;
+	int slot_cnt, slots_per_op, idst, dst_cnt;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+
+	if (flags & DMA_PREP_PQ_DISABLE_P)
+		pdest = 0;
+	else
+		pdest = pq[0];
+
+	if (flags & DMA_PREP_PQ_DISABLE_Q)
+		qdest = 0;
+	else
+		qdest = pq[1];
+
+	ADMA_LL_DBG(prep_dma_pqzero_sum_dbg(ppc440spe_chan->device->id,
+					    src, src_cnt, scf));
+
+	/* Always use WXOR for P/Q calculations (two destinations).
+	 * Need 1 or 2 extra slots to verify results are zero.
+	 */
+	idst = dst_cnt = (pdest && qdest) ? 2 : 1;
+
+	/* One additional slot per destination to clone P/Q
+	 * before calculation (we have to preserve destinations).
+	 */
+	slot_cnt = src_cnt + dst_cnt * 2;
+	slots_per_op = 1;
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt,
+					     slots_per_op);
+	if (sw_desc) {
+		ppc440spe_desc_init_dma01pqzero_sum(sw_desc, dst_cnt, src_cnt);
+
+		/* Setup byte count for each slot just allocated */
+		sw_desc->async_tx.flags = flags;
+		list_for_each_entry(iter, &sw_desc->group_list, chain_node) {
+			ppc440spe_desc_set_byte_count(iter, ppc440spe_chan,
+						      len);
+			iter->unmap_len = len;
+		}
+
+		if (pdest) {
+			struct dma_cdb *hw_desc;
+			struct ppc440spe_adma_chan *chan;
+
+			iter = sw_desc->group_head;
+			chan = to_ppc440spe_adma_chan(iter->async_tx.chan);
+			memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+			iter->hw_next = list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+			iter->src_cnt = 0;
+			iter->dst_cnt = 0;
+			ppc440spe_desc_set_dest_addr(iter, chan, 0,
+						     ppc440spe_chan->pdest, 0);
+			ppc440spe_desc_set_src_addr(iter, chan, 0, 0, pdest);
+			ppc440spe_desc_set_byte_count(iter, ppc440spe_chan,
+						      len);
+			iter->unmap_len = 0;
+			/* override pdest to preserve original P */
+			pdest = ppc440spe_chan->pdest;
+		}
+		if (qdest) {
+			struct dma_cdb *hw_desc;
+			struct ppc440spe_adma_chan *chan;
+
+			iter = list_first_entry(&sw_desc->group_list,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			chan = to_ppc440spe_adma_chan(iter->async_tx.chan);
+
+			if (pdest) {
+				iter = list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			}
+
+			memset(iter->hw_desc, 0, sizeof(struct dma_cdb));
+			iter->hw_next = list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			hw_desc = iter->hw_desc;
+			hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2;
+			iter->src_cnt = 0;
+			iter->dst_cnt = 0;
+			ppc440spe_desc_set_dest_addr(iter, chan, 0,
+						     ppc440spe_chan->qdest, 0);
+			ppc440spe_desc_set_src_addr(iter, chan, 0, 0, qdest);
+			ppc440spe_desc_set_byte_count(iter, ppc440spe_chan,
+						      len);
+			iter->unmap_len = 0;
+			/* override qdest to preserve original Q */
+			qdest = ppc440spe_chan->qdest;
+		}
+
+		/* Setup destinations for P/Q ops */
+		ppc440spe_adma_pqzero_sum_set_dest(sw_desc, pdest, qdest);
+
+		/* Setup zero QWORDs into DCHECK CDBs */
+		idst = dst_cnt;
+		list_for_each_entry_reverse(iter, &sw_desc->group_list,
+					    chain_node) {
+			/*
+			 * The last CDB corresponds to Q-parity check,
+			 * the one before last CDB corresponds
+			 * P-parity check
+			 */
+			if (idst == DMA_DEST_MAX_NUM) {
+				if (idst == dst_cnt) {
+					set_bit(PPC440SPE_DESC_QCHECK,
+						&iter->flags);
+				} else {
+					set_bit(PPC440SPE_DESC_PCHECK,
+						&iter->flags);
+				}
+			} else {
+				if (qdest) {
+					set_bit(PPC440SPE_DESC_QCHECK,
+						&iter->flags);
+				} else {
+					set_bit(PPC440SPE_DESC_PCHECK,
+						&iter->flags);
+				}
+			}
+			iter->xor_check_result = pqres;
+
+			/*
+			 * set it to zero, if check fail then result will
+			 * be updated
+			 */
+			*iter->xor_check_result = 0;
+			ppc440spe_desc_set_dcheck(iter, ppc440spe_chan,
+				ppc440spe_qword);
+
+			if (!(--dst_cnt))
+				break;
+		}
+
+		/* Setup sources and mults for P/Q ops */
+		list_for_each_entry_continue_reverse(iter, &sw_desc->group_list,
+						     chain_node) {
+			struct ppc440spe_adma_chan *chan;
+			u32 mult_dst;
+
+			chan = to_ppc440spe_adma_chan(iter->async_tx.chan);
+			ppc440spe_desc_set_src_addr(iter, chan, 0,
+						    DMA_CUED_XOR_HB,
+						    src[src_cnt - 1]);
+			if (qdest) {
+				mult_dst = (dst_cnt - 1) ? DMA_CDB_SG_DST2 :
+							   DMA_CDB_SG_DST1;
+				ppc440spe_desc_set_src_mult(iter, chan,
+							    DMA_CUED_MULT1_OFF,
+							    mult_dst,
+							    scf[src_cnt - 1]);
+			}
+			if (!(--src_cnt))
+				break;
+		}
+	}
+	spin_unlock_bh(&ppc440spe_chan->lock);
+	return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+/**
+ * ppc440spe_adma_prep_dma_xor_zero_sum - prepare CDB group for
+ * XOR ZERO_SUM operation
+ */
+static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor_zero_sum(
+		struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt,
+		size_t len, enum sum_check_flags *result, unsigned long flags)
+{
+	struct dma_async_tx_descriptor *tx;
+	dma_addr_t pq[2];
+
+	/* validate P, disable Q */
+	pq[0] = src[0];
+	pq[1] = 0;
+	flags |= DMA_PREP_PQ_DISABLE_Q;
+
+	tx = ppc440spe_adma_prep_dma_pqzero_sum(chan, pq, &src[1],
+						src_cnt - 1, 0, len,
+						result, flags);
+	return tx;
+}
+
+/**
+ * ppc440spe_adma_set_dest - set destination address into descriptor
+ */
+static void ppc440spe_adma_set_dest(struct ppc440spe_adma_desc_slot *sw_desc,
+		dma_addr_t addr, int index)
+{
+	struct ppc440spe_adma_chan *chan;
+
+	BUG_ON(index >= sw_desc->dst_cnt);
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* to do: support transfers lengths >
+		 * PPC440SPE_ADMA_DMA/XOR_MAX_BYTE_COUNT
+		 */
+		ppc440spe_desc_set_dest_addr(sw_desc->group_head,
+			chan, 0, addr, index);
+		break;
+	case PPC440SPE_XOR_ID:
+		sw_desc = ppc440spe_get_group_entry(sw_desc, index);
+		ppc440spe_desc_set_dest_addr(sw_desc,
+			chan, 0, addr, index);
+		break;
+	}
+}
+
+static void ppc440spe_adma_pq_zero_op(struct ppc440spe_adma_desc_slot *iter,
+		struct ppc440spe_adma_chan *chan, dma_addr_t addr)
+{
+	/*  To clear destinations update the descriptor
+	 * (P or Q depending on index) as follows:
+	 * addr is destination (0 corresponds to SG2):
+	 */
+	ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE, addr, 0);
+
+	/* ... and the addr is source: */
+	ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, addr);
+
+	/* addr is always SG2 then the mult is always DST1 */
+	ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF,
+				    DMA_CDB_SG_DST1, 1);
+}
+
+/**
+ * ppc440spe_adma_pq_set_dest - set destination address into descriptor
+ * for the PQXOR operation
+ */
+static void ppc440spe_adma_pq_set_dest(struct ppc440spe_adma_desc_slot *sw_desc,
+		dma_addr_t *addrs, unsigned long flags)
+{
+	struct ppc440spe_adma_desc_slot *iter;
+	struct ppc440spe_adma_chan *chan;
+	dma_addr_t paddr, qaddr;
+	dma_addr_t addr = 0, ppath, qpath;
+	int index = 0, i;
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+
+	if (flags & DMA_PREP_PQ_DISABLE_P)
+		paddr = 0;
+	else
+		paddr = addrs[0];
+
+	if (flags & DMA_PREP_PQ_DISABLE_Q)
+		qaddr = 0;
+	else
+		qaddr = addrs[1];
+
+	if (!paddr || !qaddr)
+		addr = paddr ? paddr : qaddr;
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* walk through the WXOR source list and set P/Q-destinations
+		 * for each slot:
+		 */
+		if (!test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) {
+			/* This is WXOR-only chain; may have 1/2 zero descs */
+			if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags))
+				index++;
+			if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags))
+				index++;
+
+			iter = ppc440spe_get_group_entry(sw_desc, index);
+			if (addr) {
+				/* one destination */
+				list_for_each_entry_from(iter,
+					&sw_desc->group_list, chain_node)
+					ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, addr, 0);
+			} else {
+				/* two destinations */
+				list_for_each_entry_from(iter,
+					&sw_desc->group_list, chain_node) {
+					ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, paddr, 0);
+					ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, qaddr, 1);
+				}
+			}
+
+			if (index) {
+				/*  To clear destinations update the descriptor
+				 * (1st,2nd, or both depending on flags)
+				 */
+				index = 0;
+				if (test_bit(PPC440SPE_ZERO_P,
+						&sw_desc->flags)) {
+					iter = ppc440spe_get_group_entry(
+							sw_desc, index++);
+					ppc440spe_adma_pq_zero_op(iter, chan,
+							paddr);
+				}
+
+				if (test_bit(PPC440SPE_ZERO_Q,
+						&sw_desc->flags)) {
+					iter = ppc440spe_get_group_entry(
+							sw_desc, index++);
+					ppc440spe_adma_pq_zero_op(iter, chan,
+							qaddr);
+				}
+
+				return;
+			}
+		} else {
+			/* This is RXOR-only or RXOR/WXOR mixed chain */
+
+			/* If we want to include destination into calculations,
+			 * then make dest addresses cued with mult=1 (XOR).
+			 */
+			ppath = test_bit(PPC440SPE_ZERO_P, &sw_desc->flags) ?
+					DMA_CUED_XOR_HB :
+					DMA_CUED_XOR_BASE |
+						(1 << DMA_CUED_MULT1_OFF);
+			qpath = test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags) ?
+					DMA_CUED_XOR_HB :
+					DMA_CUED_XOR_BASE |
+						(1 << DMA_CUED_MULT1_OFF);
+
+			/* Setup destination(s) in RXOR slot(s) */
+			iter = ppc440spe_get_group_entry(sw_desc, index++);
+			ppc440spe_desc_set_dest_addr(iter, chan,
+						paddr ? ppath : qpath,
+						paddr ? paddr : qaddr, 0);
+			if (!addr) {
+				/* two destinations */
+				iter = ppc440spe_get_group_entry(sw_desc,
+								 index++);
+				ppc440spe_desc_set_dest_addr(iter, chan,
+						qpath, qaddr, 0);
+			}
+
+			if (test_bit(PPC440SPE_DESC_WXOR, &sw_desc->flags)) {
+				/* Setup destination(s) in remaining WXOR
+				 * slots
+				 */
+				iter = ppc440spe_get_group_entry(sw_desc,
+								 index);
+				if (addr) {
+					/* one destination */
+					list_for_each_entry_from(iter,
+					    &sw_desc->group_list,
+					    chain_node)
+						ppc440spe_desc_set_dest_addr(
+							iter, chan,
+							DMA_CUED_XOR_BASE,
+							addr, 0);
+
+				} else {
+					/* two destinations */
+					list_for_each_entry_from(iter,
+					    &sw_desc->group_list,
+					    chain_node) {
+						ppc440spe_desc_set_dest_addr(
+							iter, chan,
+							DMA_CUED_XOR_BASE,
+							paddr, 0);
+						ppc440spe_desc_set_dest_addr(
+							iter, chan,
+							DMA_CUED_XOR_BASE,
+							qaddr, 1);
+					}
+				}
+			}
+
+		}
+		break;
+
+	case PPC440SPE_XOR_ID:
+		/* DMA2 descriptors have only 1 destination, so there are
+		 * two chains - one for each dest.
+		 * If we want to include destination into calculations,
+		 * then make dest addresses cued with mult=1 (XOR).
+		 */
+		ppath = test_bit(PPC440SPE_ZERO_P, &sw_desc->flags) ?
+				DMA_CUED_XOR_HB :
+				DMA_CUED_XOR_BASE |
+					(1 << DMA_CUED_MULT1_OFF);
+
+		qpath = test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags) ?
+				DMA_CUED_XOR_HB :
+				DMA_CUED_XOR_BASE |
+					(1 << DMA_CUED_MULT1_OFF);
+
+		iter = ppc440spe_get_group_entry(sw_desc, 0);
+		for (i = 0; i < sw_desc->descs_per_op; i++) {
+			ppc440spe_desc_set_dest_addr(iter, chan,
+				paddr ? ppath : qpath,
+				paddr ? paddr : qaddr, 0);
+			iter = list_entry(iter->chain_node.next,
+					  struct ppc440spe_adma_desc_slot,
+					  chain_node);
+		}
+
+		if (!addr) {
+			/* Two destinations; setup Q here */
+			iter = ppc440spe_get_group_entry(sw_desc,
+				sw_desc->descs_per_op);
+			for (i = 0; i < sw_desc->descs_per_op; i++) {
+				ppc440spe_desc_set_dest_addr(iter,
+					chan, qpath, qaddr, 0);
+				iter = list_entry(iter->chain_node.next,
+						struct ppc440spe_adma_desc_slot,
+						chain_node);
+			}
+		}
+
+		break;
+	}
+}
+
+/**
+ * ppc440spe_adma_pq_zero_sum_set_dest - set destination address into descriptor
+ * for the PQ_ZERO_SUM operation
+ */
+static void ppc440spe_adma_pqzero_sum_set_dest(
+		struct ppc440spe_adma_desc_slot *sw_desc,
+		dma_addr_t paddr, dma_addr_t qaddr)
+{
+	struct ppc440spe_adma_desc_slot *iter, *end;
+	struct ppc440spe_adma_chan *chan;
+	dma_addr_t addr = 0;
+	int idx;
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+
+	/* walk through the WXOR source list and set P/Q-destinations
+	 * for each slot
+	 */
+	idx = (paddr && qaddr) ? 2 : 1;
+	/* set end */
+	list_for_each_entry_reverse(end, &sw_desc->group_list,
+				    chain_node) {
+		if (!(--idx))
+			break;
+	}
+	/* set start */
+	idx = (paddr && qaddr) ? 2 : 1;
+	iter = ppc440spe_get_group_entry(sw_desc, idx);
+
+	if (paddr && qaddr) {
+		/* two destinations */
+		list_for_each_entry_from(iter, &sw_desc->group_list,
+					 chain_node) {
+			if (unlikely(iter == end))
+				break;
+			ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, paddr, 0);
+			ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, qaddr, 1);
+		}
+	} else {
+		/* one destination */
+		addr = paddr ? paddr : qaddr;
+		list_for_each_entry_from(iter, &sw_desc->group_list,
+					 chain_node) {
+			if (unlikely(iter == end))
+				break;
+			ppc440spe_desc_set_dest_addr(iter, chan,
+						DMA_CUED_XOR_BASE, addr, 0);
+		}
+	}
+
+	/*  The remaining descriptors are DATACHECK. These have no need in
+	 * destination. Actually, these destinations are used there
+	 * as sources for check operation. So, set addr as source.
+	 */
+	ppc440spe_desc_set_src_addr(end, chan, 0, 0, addr ? addr : paddr);
+
+	if (!addr) {
+		end = list_entry(end->chain_node.next,
+				 struct ppc440spe_adma_desc_slot, chain_node);
+		ppc440spe_desc_set_src_addr(end, chan, 0, 0, qaddr);
+	}
+}
+
+/**
+ * ppc440spe_desc_set_xor_src_cnt - set source count into descriptor
+ */
+static inline void ppc440spe_desc_set_xor_src_cnt(
+			struct ppc440spe_adma_desc_slot *desc,
+			int src_cnt)
+{
+	struct xor_cb *hw_desc = desc->hw_desc;
+
+	hw_desc->cbc &= ~XOR_CDCR_OAC_MSK;
+	hw_desc->cbc |= src_cnt;
+}
+
+/**
+ * ppc440spe_adma_pq_set_src - set source address into descriptor
+ */
+static void ppc440spe_adma_pq_set_src(struct ppc440spe_adma_desc_slot *sw_desc,
+		dma_addr_t addr, int index)
+{
+	struct ppc440spe_adma_chan *chan;
+	dma_addr_t haddr = 0;
+	struct ppc440spe_adma_desc_slot *iter = NULL;
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		/* DMA0,1 may do: WXOR, RXOR, RXOR+WXORs chain
+		 */
+		if (test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) {
+			/* RXOR-only or RXOR/WXOR operation */
+			int iskip = test_bit(PPC440SPE_DESC_RXOR12,
+				&sw_desc->flags) ?  2 : 3;
+
+			if (index == 0) {
+				/* 1st slot (RXOR) */
+				/* setup sources region (R1-2-3, R1-2-4,
+				 * or R1-2-5)
+				 */
+				if (test_bit(PPC440SPE_DESC_RXOR12,
+						&sw_desc->flags))
+					haddr = DMA_RXOR12 <<
+						DMA_CUED_REGION_OFF;
+				else if (test_bit(PPC440SPE_DESC_RXOR123,
+				    &sw_desc->flags))
+					haddr = DMA_RXOR123 <<
+						DMA_CUED_REGION_OFF;
+				else if (test_bit(PPC440SPE_DESC_RXOR124,
+				    &sw_desc->flags))
+					haddr = DMA_RXOR124 <<
+						DMA_CUED_REGION_OFF;
+				else if (test_bit(PPC440SPE_DESC_RXOR125,
+				    &sw_desc->flags))
+					haddr = DMA_RXOR125 <<
+						DMA_CUED_REGION_OFF;
+				else
+					BUG();
+				haddr |= DMA_CUED_XOR_BASE;
+				iter = ppc440spe_get_group_entry(sw_desc, 0);
+			} else if (index < iskip) {
+				/* 1st slot (RXOR)
+				 * shall actually set source address only once
+				 * instead of first <iskip>
+				 */
+				iter = NULL;
+			} else {
+				/* 2nd/3d and next slots (WXOR);
+				 * skip first slot with RXOR
+				 */
+				haddr = DMA_CUED_XOR_HB;
+				iter = ppc440spe_get_group_entry(sw_desc,
+				    index - iskip + sw_desc->dst_cnt);
+			}
+		} else {
+			int znum = 0;
+
+			/* WXOR-only operation; skip first slots with
+			 * zeroing destinations
+			 */
+			if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags))
+				znum++;
+			if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags))
+				znum++;
+
+			haddr = DMA_CUED_XOR_HB;
+			iter = ppc440spe_get_group_entry(sw_desc,
+					index + znum);
+		}
+
+		if (likely(iter)) {
+			ppc440spe_desc_set_src_addr(iter, chan, 0, haddr, addr);
+
+			if (!index &&
+			    test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags) &&
+			    sw_desc->dst_cnt == 2) {
+				/* if we have two destinations for RXOR, then
+				 * setup source in the second descr too
+				 */
+				iter = ppc440spe_get_group_entry(sw_desc, 1);
+				ppc440spe_desc_set_src_addr(iter, chan, 0,
+					haddr, addr);
+			}
+		}
+		break;
+
+	case PPC440SPE_XOR_ID:
+		/* DMA2 may do Biskup */
+		iter = sw_desc->group_head;
+		if (iter->dst_cnt == 2) {
+			/* both P & Q calculations required; set P src here */
+			ppc440spe_adma_dma2rxor_set_src(iter, index, addr);
+
+			/* this is for Q */
+			iter = ppc440spe_get_group_entry(sw_desc,
+				sw_desc->descs_per_op);
+		}
+		ppc440spe_adma_dma2rxor_set_src(iter, index, addr);
+		break;
+	}
+}
+
+/**
+ * ppc440spe_adma_memcpy_xor_set_src - set source address into descriptor
+ */
+static void ppc440spe_adma_memcpy_xor_set_src(
+		struct ppc440spe_adma_desc_slot *sw_desc,
+		dma_addr_t addr, int index)
+{
+	struct ppc440spe_adma_chan *chan;
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+	sw_desc = sw_desc->group_head;
+
+	if (likely(sw_desc))
+		ppc440spe_desc_set_src_addr(sw_desc, chan, index, 0, addr);
+}
+
+/**
+ * ppc440spe_adma_dma2rxor_inc_addr  -
+ */
+static void ppc440spe_adma_dma2rxor_inc_addr(
+		struct ppc440spe_adma_desc_slot *desc,
+		struct ppc440spe_rxor *cursor, int index, int src_cnt)
+{
+	cursor->addr_count++;
+	if (index == src_cnt - 1) {
+		ppc440spe_desc_set_xor_src_cnt(desc, cursor->addr_count);
+	} else if (cursor->addr_count == XOR_MAX_OPS) {
+		ppc440spe_desc_set_xor_src_cnt(desc, cursor->addr_count);
+		cursor->addr_count = 0;
+		cursor->desc_count++;
+	}
+}
+
+/**
+ * ppc440spe_adma_dma2rxor_prep_src - setup RXOR types in DMA2 CDB
+ */
+static int ppc440spe_adma_dma2rxor_prep_src(
+		struct ppc440spe_adma_desc_slot *hdesc,
+		struct ppc440spe_rxor *cursor, int index,
+		int src_cnt, u32 addr)
+{
+	int rval = 0;
+	u32 sign;
+	struct ppc440spe_adma_desc_slot *desc = hdesc;
+	int i;
+
+	for (i = 0; i < cursor->desc_count; i++) {
+		desc = list_entry(hdesc->chain_node.next,
+				  struct ppc440spe_adma_desc_slot,
+				  chain_node);
+	}
+
+	switch (cursor->state) {
+	case 0:
+		if (addr == cursor->addrl + cursor->len) {
+			/* direct RXOR */
+			cursor->state = 1;
+			cursor->xor_count++;
+			if (index == src_cnt-1) {
+				ppc440spe_rxor_set_region(desc,
+					cursor->addr_count,
+					DMA_RXOR12 << DMA_CUED_REGION_OFF);
+				ppc440spe_adma_dma2rxor_inc_addr(
+					desc, cursor, index, src_cnt);
+			}
+		} else if (cursor->addrl == addr + cursor->len) {
+			/* reverse RXOR */
+			cursor->state = 1;
+			cursor->xor_count++;
+			set_bit(cursor->addr_count, &desc->reverse_flags[0]);
+			if (index == src_cnt-1) {
+				ppc440spe_rxor_set_region(desc,
+					cursor->addr_count,
+					DMA_RXOR12 << DMA_CUED_REGION_OFF);
+				ppc440spe_adma_dma2rxor_inc_addr(
+					desc, cursor, index, src_cnt);
+			}
+		} else {
+			printk(KERN_ERR "Cannot build "
+				"DMA2 RXOR command block.\n");
+			BUG();
+		}
+		break;
+	case 1:
+		sign = test_bit(cursor->addr_count,
+				desc->reverse_flags)
+			? -1 : 1;
+		if (index == src_cnt-2 || (sign == -1
+			&& addr != cursor->addrl - 2*cursor->len)) {
+			cursor->state = 0;
+			cursor->xor_count = 1;
+			cursor->addrl = addr;
+			ppc440spe_rxor_set_region(desc,
+				cursor->addr_count,
+				DMA_RXOR12 << DMA_CUED_REGION_OFF);
+			ppc440spe_adma_dma2rxor_inc_addr(
+				desc, cursor, index, src_cnt);
+		} else if (addr == cursor->addrl + 2*sign*cursor->len) {
+			cursor->state = 2;
+			cursor->xor_count = 0;
+			ppc440spe_rxor_set_region(desc,
+				cursor->addr_count,
+				DMA_RXOR123 << DMA_CUED_REGION_OFF);
+			if (index == src_cnt-1) {
+				ppc440spe_adma_dma2rxor_inc_addr(
+					desc, cursor, index, src_cnt);
+			}
+		} else if (addr == cursor->addrl + 3*cursor->len) {
+			cursor->state = 2;
+			cursor->xor_count = 0;
+			ppc440spe_rxor_set_region(desc,
+				cursor->addr_count,
+				DMA_RXOR124 << DMA_CUED_REGION_OFF);
+			if (index == src_cnt-1) {
+				ppc440spe_adma_dma2rxor_inc_addr(
+					desc, cursor, index, src_cnt);
+			}
+		} else if (addr == cursor->addrl + 4*cursor->len) {
+			cursor->state = 2;
+			cursor->xor_count = 0;
+			ppc440spe_rxor_set_region(desc,
+				cursor->addr_count,
+				DMA_RXOR125 << DMA_CUED_REGION_OFF);
+			if (index == src_cnt-1) {
+				ppc440spe_adma_dma2rxor_inc_addr(
+					desc, cursor, index, src_cnt);
+			}
+		} else {
+			cursor->state = 0;
+			cursor->xor_count = 1;
+			cursor->addrl = addr;
+			ppc440spe_rxor_set_region(desc,
+				cursor->addr_count,
+				DMA_RXOR12 << DMA_CUED_REGION_OFF);
+			ppc440spe_adma_dma2rxor_inc_addr(
+				desc, cursor, index, src_cnt);
+		}
+		break;
+	case 2:
+		cursor->state = 0;
+		cursor->addrl = addr;
+		cursor->xor_count++;
+		if (index) {
+			ppc440spe_adma_dma2rxor_inc_addr(
+				desc, cursor, index, src_cnt);
+		}
+		break;
+	}
+
+	return rval;
+}
+
+/**
+ * ppc440spe_adma_dma2rxor_set_src - set RXOR source address; it's assumed that
+ *	ppc440spe_adma_dma2rxor_prep_src() has already done prior this call
+ */
+static void ppc440spe_adma_dma2rxor_set_src(
+		struct ppc440spe_adma_desc_slot *desc,
+		int index, dma_addr_t addr)
+{
+	struct xor_cb *xcb = desc->hw_desc;
+	int k = 0, op = 0, lop = 0;
+
+	/* get the RXOR operand which corresponds to index addr */
+	while (op <= index) {
+		lop = op;
+		if (k == XOR_MAX_OPS) {
+			k = 0;
+			desc = list_entry(desc->chain_node.next,
+				struct ppc440spe_adma_desc_slot, chain_node);
+			xcb = desc->hw_desc;
+
+		}
+		if ((xcb->ops[k++].h & (DMA_RXOR12 << DMA_CUED_REGION_OFF)) ==
+		    (DMA_RXOR12 << DMA_CUED_REGION_OFF))
+			op += 2;
+		else
+			op += 3;
+	}
+
+	BUG_ON(k < 1);
+
+	if (test_bit(k-1, desc->reverse_flags)) {
+		/* reverse operand order; put last op in RXOR group */
+		if (index == op - 1)
+			ppc440spe_rxor_set_src(desc, k - 1, addr);
+	} else {
+		/* direct operand order; put first op in RXOR group */
+		if (index == lop)
+			ppc440spe_rxor_set_src(desc, k - 1, addr);
+	}
+}
+
+/**
+ * ppc440spe_adma_dma2rxor_set_mult - set RXOR multipliers; it's assumed that
+ *	ppc440spe_adma_dma2rxor_prep_src() has already done prior this call
+ */
+static void ppc440spe_adma_dma2rxor_set_mult(
+		struct ppc440spe_adma_desc_slot *desc,
+		int index, u8 mult)
+{
+	struct xor_cb *xcb = desc->hw_desc;
+	int k = 0, op = 0, lop = 0;
+
+	/* get the RXOR operand which corresponds to index mult */
+	while (op <= index) {
+		lop = op;
+		if (k == XOR_MAX_OPS) {
+			k = 0;
+			desc = list_entry(desc->chain_node.next,
+					  struct ppc440spe_adma_desc_slot,
+					  chain_node);
+			xcb = desc->hw_desc;
+
+		}
+		if ((xcb->ops[k++].h & (DMA_RXOR12 << DMA_CUED_REGION_OFF)) ==
+		    (DMA_RXOR12 << DMA_CUED_REGION_OFF))
+			op += 2;
+		else
+			op += 3;
+	}
+
+	BUG_ON(k < 1);
+	if (test_bit(k-1, desc->reverse_flags)) {
+		/* reverse order */
+		ppc440spe_rxor_set_mult(desc, k - 1, op - index - 1, mult);
+	} else {
+		/* direct order */
+		ppc440spe_rxor_set_mult(desc, k - 1, index - lop, mult);
+	}
+}
+
+/**
+ * ppc440spe_init_rxor_cursor -
+ */
+static void ppc440spe_init_rxor_cursor(struct ppc440spe_rxor *cursor)
+{
+	memset(cursor, 0, sizeof(struct ppc440spe_rxor));
+	cursor->state = 2;
+}
+
+/**
+ * ppc440spe_adma_pq_set_src_mult - set multiplication coefficient into
+ * descriptor for the PQXOR operation
+ */
+static void ppc440spe_adma_pq_set_src_mult(
+		struct ppc440spe_adma_desc_slot *sw_desc,
+		unsigned char mult, int index, int dst_pos)
+{
+	struct ppc440spe_adma_chan *chan;
+	u32 mult_idx, mult_dst;
+	struct ppc440spe_adma_desc_slot *iter = NULL, *iter1 = NULL;
+
+	chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan);
+
+	switch (chan->device->id) {
+	case PPC440SPE_DMA0_ID:
+	case PPC440SPE_DMA1_ID:
+		if (test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) {
+			int region = test_bit(PPC440SPE_DESC_RXOR12,
+					&sw_desc->flags) ? 2 : 3;
+
+			if (index < region) {
+				/* RXOR multipliers */
+				iter = ppc440spe_get_group_entry(sw_desc,
+					sw_desc->dst_cnt - 1);
+				if (sw_desc->dst_cnt == 2)
+					iter1 = ppc440spe_get_group_entry(
+							sw_desc, 0);
+
+				mult_idx = DMA_CUED_MULT1_OFF + (index << 3);
+				mult_dst = DMA_CDB_SG_SRC;
+			} else {
+				/* WXOR multiplier */
+				iter = ppc440spe_get_group_entry(sw_desc,
+							index - region +
+							sw_desc->dst_cnt);
+				mult_idx = DMA_CUED_MULT1_OFF;
+				mult_dst = dst_pos ? DMA_CDB_SG_DST2 :
+						     DMA_CDB_SG_DST1;
+			}
+		} else {
+			int znum = 0;
+
+			/* WXOR-only;
+			 * skip first slots with destinations (if ZERO_DST has
+			 * place)
+			 */
+			if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags))
+				znum++;
+			if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags))
+				znum++;
+
+			iter = ppc440spe_get_group_entry(sw_desc, index + znum);
+			mult_idx = DMA_CUED_MULT1_OFF;
+			mult_dst = dst_pos ? DMA_CDB_SG_DST2 : DMA_CDB_SG_DST1;
+		}
+
+		if (likely(iter)) {
+			ppc440spe_desc_set_src_mult(iter, chan,
+				mult_idx, mult_dst, mult);
+
+			if (unlikely(iter1)) {
+				/* if we have two destinations for RXOR, then
+				 * we've just set Q mult. Set-up P now.
+				 */
+				ppc440spe_desc_set_src_mult(iter1, chan,
+					mult_idx, mult_dst, 1);
+			}
+
+		}
+		break;
+
+	case PPC440SPE_XOR_ID:
+		iter = sw_desc->group_head;
+		if (sw_desc->dst_cnt == 2) {
+			/* both P & Q calculations required; set P mult here */
+			ppc440spe_adma_dma2rxor_set_mult(iter, index, 1);
+
+			/* and then set Q mult */
+			iter = ppc440spe_get_group_entry(sw_desc,
+			       sw_desc->descs_per_op);
+		}
+		ppc440spe_adma_dma2rxor_set_mult(iter, index, mult);
+		break;
+	}
+}
+
+/**
+ * ppc440spe_adma_free_chan_resources - free the resources allocated
+ */
+static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+	struct ppc440spe_adma_desc_slot *iter, *_iter;
+	int in_use_descs = 0;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
+
+	spin_lock_bh(&ppc440spe_chan->lock);
+	list_for_each_entry_safe(iter, _iter, &ppc440spe_chan->chain,
+					chain_node) {
+		in_use_descs++;
+		list_del(&iter->chain_node);
+	}
+	list_for_each_entry_safe_reverse(iter, _iter,
+			&ppc440spe_chan->all_slots, slot_node) {
+		list_del(&iter->slot_node);
+		kfree(iter);
+		ppc440spe_chan->slots_allocated--;
+	}
+	ppc440spe_chan->last_used = NULL;
+
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d %s slots_allocated %d\n",
+		ppc440spe_chan->device->id,
+		__func__, ppc440spe_chan->slots_allocated);
+	spin_unlock_bh(&ppc440spe_chan->lock);
+
+	/* one is ok since we left it on there on purpose */
+	if (in_use_descs > 1)
+		printk(KERN_ERR "SPE: Freeing %d in use descriptors!\n",
+			in_use_descs - 1);
+}
+
+/**
+ * ppc440spe_adma_is_complete - poll the status of an ADMA transaction
+ * @chan: ADMA channel handle
+ * @cookie: ADMA transaction identifier
+ */
+static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan,
+	dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+	enum dma_status ret;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+	last_used = chan->cookie;
+	last_complete = ppc440spe_chan->completed_cookie;
+
+	if (done)
+		*done = last_complete;
+	if (used)
+		*used = last_used;
+
+	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	if (ret == DMA_SUCCESS)
+		return ret;
+
+	ppc440spe_adma_slot_cleanup(ppc440spe_chan);
+
+	last_used = chan->cookie;
+	last_complete = ppc440spe_chan->completed_cookie;
+
+	if (done)
+		*done = last_complete;
+	if (used)
+		*used = last_used;
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/**
+ * ppc440spe_adma_eot_handler - end of transfer interrupt handler
+ */
+static irqreturn_t ppc440spe_adma_eot_handler(int irq, void *data)
+{
+	struct ppc440spe_adma_chan *chan = data;
+
+	dev_dbg(chan->device->common.dev,
+		"ppc440spe adma%d: %s\n", chan->device->id, __func__);
+
+	tasklet_schedule(&chan->irq_tasklet);
+	ppc440spe_adma_device_clear_eot_status(chan);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ppc440spe_adma_err_handler - DMA error interrupt handler;
+ *	do the same things as a eot handler
+ */
+static irqreturn_t ppc440spe_adma_err_handler(int irq, void *data)
+{
+	struct ppc440spe_adma_chan *chan = data;
+
+	dev_dbg(chan->device->common.dev,
+		"ppc440spe adma%d: %s\n", chan->device->id, __func__);
+
+	tasklet_schedule(&chan->irq_tasklet);
+	ppc440spe_adma_device_clear_eot_status(chan);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ppc440spe_test_callback - called when test operation has been done
+ */
+static void ppc440spe_test_callback(void *unused)
+{
+	complete(&ppc440spe_r6_test_comp);
+}
+
+/**
+ * ppc440spe_adma_issue_pending - flush all pending descriptors to h/w
+ */
+static void ppc440spe_adma_issue_pending(struct dma_chan *chan)
+{
+	struct ppc440spe_adma_chan *ppc440spe_chan;
+
+	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+	dev_dbg(ppc440spe_chan->device->common.dev,
+		"ppc440spe adma%d: %s %d \n", ppc440spe_chan->device->id,
+		__func__, ppc440spe_chan->pending);
+
+	if (ppc440spe_chan->pending) {
+		ppc440spe_chan->pending = 0;
+		ppc440spe_chan_append(ppc440spe_chan);
+	}
+}
+
+/**
+ * ppc440spe_chan_start_null_xor - initiate the first XOR operation (DMA engines
+ *	use FIFOs (as opposite to chains used in XOR) so this is a XOR
+ *	specific operation)
+ */
+static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan)
+{
+	struct ppc440spe_adma_desc_slot *sw_desc, *group_start;
+	dma_cookie_t cookie;
+	int slot_cnt, slots_per_op;
+
+	dev_dbg(chan->device->common.dev,
+		"ppc440spe adma%d: %s\n", chan->device->id, __func__);
+
+	spin_lock_bh(&chan->lock);
+	slot_cnt = ppc440spe_chan_xor_slot_count(0, 2, &slots_per_op);
+	sw_desc = ppc440spe_adma_alloc_slots(chan, slot_cnt, slots_per_op);
+	if (sw_desc) {
+		group_start = sw_desc->group_head;
+		list_splice_init(&sw_desc->group_list, &chan->chain);
+		async_tx_ack(&sw_desc->async_tx);
+		ppc440spe_desc_init_null_xor(group_start);
+
+		cookie = chan->common.cookie;
+		cookie++;
+		if (cookie <= 1)
+			cookie = 2;
+
+		/* initialize the completed cookie to be less than
+		 * the most recently used cookie
+		 */
+		chan->completed_cookie = cookie - 1;
+		chan->common.cookie = sw_desc->async_tx.cookie = cookie;
+
+		/* channel should not be busy */
+		BUG_ON(ppc440spe_chan_is_busy(chan));
+
+		/* set the descriptor address */
+		ppc440spe_chan_set_first_xor_descriptor(chan, sw_desc);
+
+		/* run the descriptor */
+		ppc440spe_chan_run(chan);
+	} else
+		printk(KERN_ERR "ppc440spe adma%d"
+			" failed to allocate null descriptor\n",
+			chan->device->id);
+	spin_unlock_bh(&chan->lock);
+}
+
+/**
+ * ppc440spe_test_raid6 - test are RAID-6 capabilities enabled successfully.
+ *	For this we just perform one WXOR operation with the same source
+ *	and destination addresses, the GF-multiplier is 1; so if RAID-6
+ *	capabilities are enabled then we'll get src/dst filled with zero.
+ */
+static int ppc440spe_test_raid6(struct ppc440spe_adma_chan *chan)
+{
+	struct ppc440spe_adma_desc_slot *sw_desc, *iter;
+	struct page *pg;
+	char *a;
+	dma_addr_t dma_addr, addrs[2];
+	unsigned long op = 0;
+	int rval = 0;
+
+	set_bit(PPC440SPE_DESC_WXOR, &op);
+
+	pg = alloc_page(GFP_KERNEL);
+	if (!pg)
+		return -ENOMEM;
+
+	spin_lock_bh(&chan->lock);
+	sw_desc = ppc440spe_adma_alloc_slots(chan, 1, 1);
+	if (sw_desc) {
+		/* 1 src, 1 dsr, int_ena, WXOR */
+		ppc440spe_desc_init_dma01pq(sw_desc, 1, 1, 1, op);
+		list_for_each_entry(iter, &sw_desc->group_list, chain_node) {
+			ppc440spe_desc_set_byte_count(iter, chan, PAGE_SIZE);
+			iter->unmap_len = PAGE_SIZE;
+		}
+	} else {
+		rval = -EFAULT;
+		spin_unlock_bh(&chan->lock);
+		goto exit;
+	}
+	spin_unlock_bh(&chan->lock);
+
+	/* Fill the test page with ones */
+	memset(page_address(pg), 0xFF, PAGE_SIZE);
+	dma_addr = dma_map_page(chan->device->dev, pg, 0,
+				PAGE_SIZE, DMA_BIDIRECTIONAL);
+
+	/* Setup addresses */
+	ppc440spe_adma_pq_set_src(sw_desc, dma_addr, 0);
+	ppc440spe_adma_pq_set_src_mult(sw_desc, 1, 0, 0);
+	addrs[0] = dma_addr;
+	addrs[1] = 0;
+	ppc440spe_adma_pq_set_dest(sw_desc, addrs, DMA_PREP_PQ_DISABLE_Q);
+
+	async_tx_ack(&sw_desc->async_tx);
+	sw_desc->async_tx.callback = ppc440spe_test_callback;
+	sw_desc->async_tx.callback_param = NULL;
+
+	init_completion(&ppc440spe_r6_test_comp);
+
+	ppc440spe_adma_tx_submit(&sw_desc->async_tx);
+	ppc440spe_adma_issue_pending(&chan->common);
+
+	wait_for_completion(&ppc440spe_r6_test_comp);
+
+	/* Now check if the test page is zeroed */
+	a = page_address(pg);
+	if ((*(u32 *)a) == 0 && memcmp(a, a+4, PAGE_SIZE-4) == 0) {
+		/* page is zero - RAID-6 enabled */
+		rval = 0;
+	} else {
+		/* RAID-6 was not enabled */
+		rval = -EINVAL;
+	}
+exit:
+	__free_page(pg);
+	return rval;
+}
+
+static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev)
+{
+	switch (adev->id) {
+	case PPC440SPE_DMA0_ID:
+	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);
+		break;
+	case PPC440SPE_XOR_ID:
+		dma_cap_set(DMA_XOR, adev->common.cap_mask);
+		dma_cap_set(DMA_PQ, adev->common.cap_mask);
+		dma_cap_set(DMA_INTERRUPT, adev->common.cap_mask);
+		adev->common.cap_mask = adev->common.cap_mask;
+		break;
+	}
+
+	/* Set base routines */
+	adev->common.device_alloc_chan_resources =
+				ppc440spe_adma_alloc_chan_resources;
+	adev->common.device_free_chan_resources =
+				ppc440spe_adma_free_chan_resources;
+	adev->common.device_is_tx_complete = ppc440spe_adma_is_complete;
+	adev->common.device_issue_pending = ppc440spe_adma_issue_pending;
+
+	/* Set prep routines based on capability */
+	if (dma_has_cap(DMA_MEMCPY, adev->common.cap_mask)) {
+		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 =
+			ppc440spe_adma_prep_dma_xor;
+	}
+	if (dma_has_cap(DMA_PQ, adev->common.cap_mask)) {
+		switch (adev->id) {
+		case PPC440SPE_DMA0_ID:
+			dma_set_maxpq(&adev->common,
+				DMA0_FIFO_SIZE / sizeof(struct dma_cdb), 0);
+			break;
+		case PPC440SPE_DMA1_ID:
+			dma_set_maxpq(&adev->common,
+				DMA1_FIFO_SIZE / sizeof(struct dma_cdb), 0);
+			break;
+		case PPC440SPE_XOR_ID:
+			adev->common.max_pq = XOR_MAX_OPS * 3;
+			break;
+		}
+		adev->common.device_prep_dma_pq =
+			ppc440spe_adma_prep_dma_pq;
+	}
+	if (dma_has_cap(DMA_PQ_VAL, adev->common.cap_mask)) {
+		switch (adev->id) {
+		case PPC440SPE_DMA0_ID:
+			adev->common.max_pq = DMA0_FIFO_SIZE /
+						sizeof(struct dma_cdb);
+			break;
+		case PPC440SPE_DMA1_ID:
+			adev->common.max_pq = DMA1_FIFO_SIZE /
+						sizeof(struct dma_cdb);
+			break;
+		}
+		adev->common.device_prep_dma_pq_val =
+			ppc440spe_adma_prep_dma_pqzero_sum;
+	}
+	if (dma_has_cap(DMA_XOR_VAL, adev->common.cap_mask)) {
+		switch (adev->id) {
+		case PPC440SPE_DMA0_ID:
+			adev->common.max_xor = DMA0_FIFO_SIZE /
+						sizeof(struct dma_cdb);
+			break;
+		case PPC440SPE_DMA1_ID:
+			adev->common.max_xor = DMA1_FIFO_SIZE /
+						sizeof(struct dma_cdb);
+			break;
+		}
+		adev->common.device_prep_dma_xor_val =
+			ppc440spe_adma_prep_dma_xor_zero_sum;
+	}
+	if (dma_has_cap(DMA_INTERRUPT, adev->common.cap_mask)) {
+		adev->common.device_prep_dma_interrupt =
+			ppc440spe_adma_prep_dma_interrupt;
+	}
+	pr_info("%s: AMCC(R) PPC440SP(E) ADMA Engine: "
+	  "( %s%s%s%s%s%s%s)\n",
+	  dev_name(adev->dev),
+	  dma_has_cap(DMA_PQ, adev->common.cap_mask) ? "pq " : "",
+	  dma_has_cap(DMA_PQ_VAL, adev->common.cap_mask) ? "pq_val " : "",
+	  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 " : "");
+}
+
+static int ppc440spe_adma_setup_irqs(struct ppc440spe_adma_device *adev,
+				     struct ppc440spe_adma_chan *chan,
+				     int *initcode)
+{
+	struct device_node *np;
+	int ret;
+
+	np = container_of(adev->dev, struct of_device, dev)->node;
+	if (adev->id != PPC440SPE_XOR_ID) {
+		adev->err_irq = irq_of_parse_and_map(np, 1);
+		if (adev->err_irq == NO_IRQ) {
+			dev_warn(adev->dev, "no err irq resource?\n");
+			*initcode = PPC_ADMA_INIT_IRQ2;
+			adev->err_irq = -ENXIO;
+		} else
+			atomic_inc(&ppc440spe_adma_err_irq_ref);
+	} else {
+		adev->err_irq = -ENXIO;
+	}
+
+	adev->irq = irq_of_parse_and_map(np, 0);
+	if (adev->irq == NO_IRQ) {
+		dev_err(adev->dev, "no irq resource\n");
+		*initcode = PPC_ADMA_INIT_IRQ1;
+		ret = -ENXIO;
+		goto err_irq_map;
+	}
+	dev_dbg(adev->dev, "irq %d, err irq %d\n",
+		adev->irq, adev->err_irq);
+
+	ret = request_irq(adev->irq, ppc440spe_adma_eot_handler,
+			  0, dev_driver_string(adev->dev), chan);
+	if (ret) {
+		dev_err(adev->dev, "can't request irq %d\n",
+			adev->irq);
+		*initcode = PPC_ADMA_INIT_IRQ1;
+		ret = -EIO;
+		goto err_req1;
+	}
+
+	/* only DMA engines have a separate error IRQ
+	 * so it's Ok if err_irq < 0 in XOR engine case.
+	 */
+	if (adev->err_irq > 0) {
+		/* both DMA engines share common error IRQ */
+		ret = request_irq(adev->err_irq,
+				  ppc440spe_adma_err_handler,
+				  IRQF_SHARED,
+				  dev_driver_string(adev->dev),
+				  chan);
+		if (ret) {
+			dev_err(adev->dev, "can't request irq %d\n",
+				adev->err_irq);
+			*initcode = PPC_ADMA_INIT_IRQ2;
+			ret = -EIO;
+			goto err_req2;
+		}
+	}
+
+	if (adev->id == PPC440SPE_XOR_ID) {
+		/* enable XOR engine interrupts */
+		iowrite32be(XOR_IE_CBCIE_BIT | XOR_IE_ICBIE_BIT |
+			    XOR_IE_ICIE_BIT | XOR_IE_RPTIE_BIT,
+			    &adev->xor_reg->ier);
+	} else {
+		u32 mask, enable;
+
+		np = of_find_compatible_node(NULL, NULL, "ibm,i2o-440spe");
+		if (!np) {
+			pr_err("%s: can't find I2O device tree node\n",
+				__func__);
+			ret = -ENODEV;
+			goto err_req2;
+		}
+		adev->i2o_reg = of_iomap(np, 0);
+		if (!adev->i2o_reg) {
+			pr_err("%s: failed to map I2O registers\n", __func__);
+			of_node_put(np);
+			ret = -EINVAL;
+			goto err_req2;
+		}
+		of_node_put(np);
+		/* Unmask 'CS FIFO Attention' interrupts and
+		 * enable generating interrupts on errors
+		 */
+		enable = (adev->id == PPC440SPE_DMA0_ID) ?
+			 ~(I2O_IOPIM_P0SNE | I2O_IOPIM_P0EM) :
+			 ~(I2O_IOPIM_P1SNE | I2O_IOPIM_P1EM);
+		mask = ioread32(&adev->i2o_reg->iopim) & enable;
+		iowrite32(mask, &adev->i2o_reg->iopim);
+	}
+	return 0;
+
+err_req2:
+	free_irq(adev->irq, chan);
+err_req1:
+	irq_dispose_mapping(adev->irq);
+err_irq_map:
+	if (adev->err_irq > 0) {
+		if (atomic_dec_and_test(&ppc440spe_adma_err_irq_ref))
+			irq_dispose_mapping(adev->err_irq);
+	}
+	return ret;
+}
+
+static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev,
+					struct ppc440spe_adma_chan *chan)
+{
+	u32 mask, disable;
+
+	if (adev->id == PPC440SPE_XOR_ID) {
+		/* disable XOR engine interrupts */
+		mask = ioread32be(&adev->xor_reg->ier);
+		mask &= ~(XOR_IE_CBCIE_BIT | XOR_IE_ICBIE_BIT |
+			  XOR_IE_ICIE_BIT | XOR_IE_RPTIE_BIT);
+		iowrite32be(mask, &adev->xor_reg->ier);
+	} else {
+		/* disable DMAx engine interrupts */
+		disable = (adev->id == PPC440SPE_DMA0_ID) ?
+			  (I2O_IOPIM_P0SNE | I2O_IOPIM_P0EM) :
+			  (I2O_IOPIM_P1SNE | I2O_IOPIM_P1EM);
+		mask = ioread32(&adev->i2o_reg->iopim) | disable;
+		iowrite32(mask, &adev->i2o_reg->iopim);
+	}
+	free_irq(adev->irq, chan);
+	irq_dispose_mapping(adev->irq);
+	if (adev->err_irq > 0) {
+		free_irq(adev->err_irq, chan);
+		if (atomic_dec_and_test(&ppc440spe_adma_err_irq_ref)) {
+			irq_dispose_mapping(adev->err_irq);
+			iounmap(adev->i2o_reg);
+		}
+	}
+}
+
+/**
+ * ppc440spe_adma_probe - probe the asynch device
+ */
+static int __devinit ppc440spe_adma_probe(struct of_device *ofdev,
+					  const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct resource res;
+	struct ppc440spe_adma_device *adev;
+	struct ppc440spe_adma_chan *chan;
+	struct ppc_dma_chan_ref *ref, *_ref;
+	int ret = 0, initcode = PPC_ADMA_INIT_OK;
+	const u32 *idx;
+	int len;
+	void *regs;
+	u32 id, pool_size;
+
+	if (of_device_is_compatible(np, "amcc,xor-accelerator")) {
+		id = PPC440SPE_XOR_ID;
+		/* As far as the XOR engine is concerned, it does not
+		 * use FIFOs but uses linked list. So there is no dependency
+		 * between pool size to allocate and the engine configuration.
+		 */
+		pool_size = PAGE_SIZE << 1;
+	} else {
+		/* it is DMA0 or DMA1 */
+		idx = of_get_property(np, "cell-index", &len);
+		if (!idx || (len != sizeof(u32))) {
+			dev_err(&ofdev->dev, "Device node %s has missing "
+				"or invalid cell-index property\n",
+				np->full_name);
+			return -EINVAL;
+		}
+		id = *idx;
+		/* DMA0,1 engines use FIFO to maintain CDBs, so we
+		 * should allocate the pool accordingly to size of this
+		 * FIFO. Thus, the pool size depends on the FIFO depth:
+		 * how much CDBs pointers the FIFO may contain then so
+		 * much CDBs we should provide in the pool.
+		 * That is
+		 *   CDB size = 32B;
+		 *   CDBs number = (DMA0_FIFO_SIZE >> 3);
+		 *   Pool size = CDBs number * CDB size =
+		 *      = (DMA0_FIFO_SIZE >> 3) << 5 = DMA0_FIFO_SIZE << 2.
+		 */
+		pool_size = (id == PPC440SPE_DMA0_ID) ?
+			    DMA0_FIFO_SIZE : DMA1_FIFO_SIZE;
+		pool_size <<= 2;
+	}
+
+	if (of_address_to_resource(np, 0, &res)) {
+		dev_err(&ofdev->dev, "failed to get memory resource\n");
+		initcode = PPC_ADMA_INIT_MEMRES;
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (!request_mem_region(res.start, resource_size(&res),
+				dev_driver_string(&ofdev->dev))) {
+		dev_err(&ofdev->dev, "failed to request memory region "
+			"(0x%016llx-0x%016llx)\n",
+			(u64)res.start, (u64)res.end);
+		initcode = PPC_ADMA_INIT_MEMREG;
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* create a device */
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev) {
+		dev_err(&ofdev->dev, "failed to allocate device\n");
+		initcode = PPC_ADMA_INIT_ALLOC;
+		ret = -ENOMEM;
+		goto err_adev_alloc;
+	}
+
+	adev->id = id;
+	adev->pool_size = pool_size;
+	/* allocate coherent memory for hardware descriptors */
+	adev->dma_desc_pool_virt = dma_alloc_coherent(&ofdev->dev,
+					adev->pool_size, &adev->dma_desc_pool,
+					GFP_KERNEL);
+	if (adev->dma_desc_pool_virt == NULL) {
+		dev_err(&ofdev->dev, "failed to allocate %d bytes of coherent "
+			"memory for hardware descriptors\n",
+			adev->pool_size);
+		initcode = PPC_ADMA_INIT_COHERENT;
+		ret = -ENOMEM;
+		goto err_dma_alloc;
+	}
+	dev_dbg(&ofdev->dev, "allocted descriptor pool virt 0x%p phys 0x%llx\n",
+		adev->dma_desc_pool_virt, (u64)adev->dma_desc_pool);
+
+	regs = ioremap(res.start, resource_size(&res));
+	if (!regs) {
+		dev_err(&ofdev->dev, "failed to ioremap regs!\n");
+		goto err_regs_alloc;
+	}
+
+	if (adev->id == PPC440SPE_XOR_ID) {
+		adev->xor_reg = regs;
+		/* Reset XOR */
+		iowrite32be(XOR_CRSR_XASR_BIT, &adev->xor_reg->crsr);
+		iowrite32be(XOR_CRSR_64BA_BIT, &adev->xor_reg->crrr);
+	} else {
+		size_t fifo_size = (adev->id == PPC440SPE_DMA0_ID) ?
+				   DMA0_FIFO_SIZE : DMA1_FIFO_SIZE;
+		adev->dma_reg = regs;
+		/* DMAx_FIFO_SIZE is defined in bytes,
+		 * <fsiz> - is defined in number of CDB pointers (8byte).
+		 * DMA FIFO Length = CSlength + CPlength, where
+		 * CSlength = CPlength = (fsiz + 1) * 8.
+		 */
+		iowrite32(DMA_FIFO_ENABLE | ((fifo_size >> 3) - 2),
+			  &adev->dma_reg->fsiz);
+		/* Configure DMA engine */
+		iowrite32(DMA_CFG_DXEPR_HP | DMA_CFG_DFMPP_HP | DMA_CFG_FALGN,
+			  &adev->dma_reg->cfg);
+		/* Clear Status */
+		iowrite32(~0, &adev->dma_reg->dsts);
+	}
+
+	adev->dev = &ofdev->dev;
+	adev->common.dev = &ofdev->dev;
+	INIT_LIST_HEAD(&adev->common.channels);
+	dev_set_drvdata(&ofdev->dev, adev);
+
+	/* create a channel */
+	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+	if (!chan) {
+		dev_err(&ofdev->dev, "can't allocate channel structure\n");
+		initcode = PPC_ADMA_INIT_CHANNEL;
+		ret = -ENOMEM;
+		goto err_chan_alloc;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->chain);
+	INIT_LIST_HEAD(&chan->all_slots);
+	chan->device = adev;
+	chan->common.device = &adev->common;
+	list_add_tail(&chan->common.device_node, &adev->common.channels);
+	tasklet_init(&chan->irq_tasklet, ppc440spe_adma_tasklet,
+		     (unsigned long)chan);
+
+	/* allocate and map helper pages for async validation or
+	 * async_mult/async_sum_product operations on DMA0/1.
+	 */
+	if (adev->id != PPC440SPE_XOR_ID) {
+		chan->pdest_page = alloc_page(GFP_KERNEL);
+		chan->qdest_page = alloc_page(GFP_KERNEL);
+		if (!chan->pdest_page ||
+		    !chan->qdest_page) {
+			if (chan->pdest_page)
+				__free_page(chan->pdest_page);
+			if (chan->qdest_page)
+				__free_page(chan->qdest_page);
+			ret = -ENOMEM;
+			goto err_page_alloc;
+		}
+		chan->pdest = dma_map_page(&ofdev->dev, chan->pdest_page, 0,
+					   PAGE_SIZE, DMA_BIDIRECTIONAL);
+		chan->qdest = dma_map_page(&ofdev->dev, chan->qdest_page, 0,
+					   PAGE_SIZE, DMA_BIDIRECTIONAL);
+	}
+
+	ref = kmalloc(sizeof(*ref), GFP_KERNEL);
+	if (ref) {
+		ref->chan = &chan->common;
+		INIT_LIST_HEAD(&ref->node);
+		list_add_tail(&ref->node, &ppc440spe_adma_chan_list);
+	} else {
+		dev_err(&ofdev->dev, "failed to allocate channel reference!\n");
+		ret = -ENOMEM;
+		goto err_ref_alloc;
+	}
+
+	ret = ppc440spe_adma_setup_irqs(adev, chan, &initcode);
+	if (ret)
+		goto err_irq;
+
+	ppc440spe_adma_init_capabilities(adev);
+
+	ret = dma_async_device_register(&adev->common);
+	if (ret) {
+		initcode = PPC_ADMA_INIT_REGISTER;
+		dev_err(&ofdev->dev, "failed to register dma device\n");
+		goto err_dev_reg;
+	}
+
+	goto out;
+
+err_dev_reg:
+	ppc440spe_adma_release_irqs(adev, chan);
+err_irq:
+	list_for_each_entry_safe(ref, _ref, &ppc440spe_adma_chan_list, node) {
+		if (chan == to_ppc440spe_adma_chan(ref->chan)) {
+			list_del(&ref->node);
+			kfree(ref);
+		}
+	}
+err_ref_alloc:
+	if (adev->id != PPC440SPE_XOR_ID) {
+		dma_unmap_page(&ofdev->dev, chan->pdest,
+			       PAGE_SIZE, DMA_BIDIRECTIONAL);
+		dma_unmap_page(&ofdev->dev, chan->qdest,
+			       PAGE_SIZE, DMA_BIDIRECTIONAL);
+		__free_page(chan->pdest_page);
+		__free_page(chan->qdest_page);
+	}
+err_page_alloc:
+	kfree(chan);
+err_chan_alloc:
+	if (adev->id == PPC440SPE_XOR_ID)
+		iounmap(adev->xor_reg);
+	else
+		iounmap(adev->dma_reg);
+err_regs_alloc:
+	dma_free_coherent(adev->dev, adev->pool_size,
+			  adev->dma_desc_pool_virt,
+			  adev->dma_desc_pool);
+err_dma_alloc:
+	kfree(adev);
+err_adev_alloc:
+	release_mem_region(res.start, resource_size(&res));
+out:
+	if (id < PPC440SPE_ADMA_ENGINES_NUM)
+		ppc440spe_adma_devices[id] = initcode;
+
+	return ret;
+}
+
+/**
+ * ppc440spe_adma_remove - remove the asynch device
+ */
+static int __devexit ppc440spe_adma_remove(struct of_device *ofdev)
+{
+	struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev);
+	struct device_node *np = ofdev->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;
+
+	dma_async_device_unregister(&adev->common);
+
+	list_for_each_entry_safe(chan, _chan, &adev->common.channels,
+				 device_node) {
+		ppc440spe_chan = to_ppc440spe_adma_chan(chan);
+		ppc440spe_adma_release_irqs(adev, ppc440spe_chan);
+		tasklet_kill(&ppc440spe_chan->irq_tasklet);
+		if (adev->id != PPC440SPE_XOR_ID) {
+			dma_unmap_page(&ofdev->dev, ppc440spe_chan->pdest,
+					PAGE_SIZE, DMA_BIDIRECTIONAL);
+			dma_unmap_page(&ofdev->dev, ppc440spe_chan->qdest,
+					PAGE_SIZE, DMA_BIDIRECTIONAL);
+			__free_page(ppc440spe_chan->pdest_page);
+			__free_page(ppc440spe_chan->qdest_page);
+		}
+		list_for_each_entry_safe(ref, _ref, &ppc440spe_adma_chan_list,
+					 node) {
+			if (ppc440spe_chan ==
+			    to_ppc440spe_adma_chan(ref->chan)) {
+				list_del(&ref->node);
+				kfree(ref);
+			}
+		}
+		list_del(&chan->device_node);
+		kfree(ppc440spe_chan);
+	}
+
+	dma_free_coherent(adev->dev, adev->pool_size,
+			  adev->dma_desc_pool_virt, adev->dma_desc_pool);
+	if (adev->id == PPC440SPE_XOR_ID)
+		iounmap(adev->xor_reg);
+	else
+		iounmap(adev->dma_reg);
+	of_address_to_resource(np, 0, &res);
+	release_mem_region(res.start, resource_size(&res));
+	kfree(adev);
+	return 0;
+}
+
+/*
+ * /sys driver interface to enable h/w RAID-6 capabilities
+ * Files created in e.g. /sys/devices/plb.0/400100100.dma0/driver/
+ * directory are "devices", "enable" and "poly".
+ * "devices" shows available engines.
+ * "enable" is used to enable RAID-6 capabilities or to check
+ * whether these has been activated.
+ * "poly" allows setting/checking used polynomial (for PPC440SPe only).
+ */
+
+static ssize_t show_ppc440spe_devices(struct device_driver *dev, char *buf)
+{
+	ssize_t size = 0;
+	int i;
+
+	for (i = 0; i < PPC440SPE_ADMA_ENGINES_NUM; i++) {
+		if (ppc440spe_adma_devices[i] == -1)
+			continue;
+		size += snprintf(buf + size, PAGE_SIZE - size,
+				 "PPC440SP(E)-ADMA.%d: %s\n", i,
+				 ppc_adma_errors[ppc440spe_adma_devices[i]]);
+	}
+	return size;
+}
+
+static ssize_t show_ppc440spe_r6enable(struct device_driver *dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE,
+			"PPC440SP(e) RAID-6 capabilities are %sABLED.\n",
+			ppc440spe_r6_enabled ? "EN" : "DIS");
+}
+
+static ssize_t store_ppc440spe_r6enable(struct device_driver *dev,
+					const char *buf, size_t count)
+{
+	unsigned long val;
+
+	if (!count || count > 11)
+		return -EINVAL;
+
+	if (!ppc440spe_r6_tchan)
+		return -EFAULT;
+
+	/* Write a key */
+	sscanf(buf, "%lx", &val);
+	dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_XORBA, val);
+	isync();
+
+	/* Verify whether it really works now */
+	if (ppc440spe_test_raid6(ppc440spe_r6_tchan) == 0) {
+		pr_info("PPC440SP(e) RAID-6 has been activated "
+			"successfully\n");
+		ppc440spe_r6_enabled = 1;
+	} else {
+		pr_info("PPC440SP(e) RAID-6 hasn't been activated!"
+			" Error key ?\n");
+		ppc440spe_r6_enabled = 0;
+	}
+	return count;
+}
+
+static ssize_t show_ppc440spe_r6poly(struct device_driver *dev, char *buf)
+{
+	ssize_t size = 0;
+	u32 reg;
+
+#ifdef CONFIG_440SP
+	/* 440SP has fixed polynomial */
+	reg = 0x4d;
+#else
+	reg = dcr_read(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL);
+	reg >>= MQ0_CFBHL_POLY;
+	reg &= 0xFF;
+#endif
+
+	size = snprintf(buf, PAGE_SIZE, "PPC440SP(e) RAID-6 driver "
+			"uses 0x1%02x polynomial.\n", reg);
+	return size;
+}
+
+static ssize_t store_ppc440spe_r6poly(struct device_driver *dev,
+				      const char *buf, size_t count)
+{
+	unsigned long reg, val;
+
+#ifdef CONFIG_440SP
+	/* 440SP uses default 0x14D polynomial only */
+	return -EINVAL;
+#endif
+
+	if (!count || count > 6)
+		return -EINVAL;
+
+	/* e.g., 0x14D or 0x11D */
+	sscanf(buf, "%lx", &val);
+
+	if (val & ~0x1FF)
+		return -EINVAL;
+
+	val &= 0xFF;
+	reg = dcr_read(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL);
+	reg &= ~(0xFF << MQ0_CFBHL_POLY);
+	reg |= val << MQ0_CFBHL_POLY;
+	dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL, reg);
+
+	return count;
+}
+
+static DRIVER_ATTR(devices, S_IRUGO, show_ppc440spe_devices, NULL);
+static DRIVER_ATTR(enable, S_IRUGO | S_IWUSR, show_ppc440spe_r6enable,
+		   store_ppc440spe_r6enable);
+static DRIVER_ATTR(poly, S_IRUGO | S_IWUSR, show_ppc440spe_r6poly,
+		   store_ppc440spe_r6poly);
+
+/*
+ * Common initialisation for RAID engines; allocate memory for
+ * DMAx FIFOs, perform configuration common for all DMA engines.
+ * Further DMA engine specific configuration is done at probe time.
+ */
+static int ppc440spe_configure_raid_devices(void)
+{
+	struct device_node *np;
+	struct resource i2o_res;
+	struct i2o_regs __iomem *i2o_reg;
+	dcr_host_t i2o_dcr_host;
+	unsigned int dcr_base, dcr_len;
+	int i, ret;
+
+	np = of_find_compatible_node(NULL, NULL, "ibm,i2o-440spe");
+	if (!np) {
+		pr_err("%s: can't find I2O device tree node\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	if (of_address_to_resource(np, 0, &i2o_res)) {
+		of_node_put(np);
+		return -EINVAL;
+	}
+
+	i2o_reg = of_iomap(np, 0);
+	if (!i2o_reg) {
+		pr_err("%s: failed to map I2O registers\n", __func__);
+		of_node_put(np);
+		return -EINVAL;
+	}
+
+	/* Get I2O DCRs base */
+	dcr_base = dcr_resource_start(np, 0);
+	dcr_len = dcr_resource_len(np, 0);
+	if (!dcr_base && !dcr_len) {
+		pr_err("%s: can't get DCR registers base/len!\n",
+			np->full_name);
+		of_node_put(np);
+		iounmap(i2o_reg);
+		return -ENODEV;
+	}
+
+	i2o_dcr_host = dcr_map(np, dcr_base, dcr_len);
+	if (!DCR_MAP_OK(i2o_dcr_host)) {
+		pr_err("%s: failed to map DCRs!\n", np->full_name);
+		of_node_put(np);
+		iounmap(i2o_reg);
+		return -ENODEV;
+	}
+	of_node_put(np);
+
+	/* Provide memory regions for DMA's FIFOs: I2O, DMA0 and DMA1 share
+	 * the base address of FIFO memory space.
+	 * Actually we need twice more physical memory than programmed in the
+	 * <fsiz> register (because there are two FIFOs for each DMA: CP and CS)
+	 */
+	ppc440spe_dma_fifo_buf = kmalloc((DMA0_FIFO_SIZE + DMA1_FIFO_SIZE) << 1,
+					 GFP_KERNEL);
+	if (!ppc440spe_dma_fifo_buf) {
+		pr_err("%s: DMA FIFO buffer allocation failed.\n", __func__);
+		iounmap(i2o_reg);
+		dcr_unmap(i2o_dcr_host, dcr_len);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Configure h/w
+	 */
+	/* Reset I2O/DMA */
+	mtdcri(SDR0, DCRN_SDR0_SRST, DCRN_SDR0_SRST_I2ODMA);
+	mtdcri(SDR0, DCRN_SDR0_SRST, 0);
+
+	/* Setup the base address of mmaped registers */
+	dcr_write(i2o_dcr_host, DCRN_I2O0_IBAH, (u32)(i2o_res.start >> 32));
+	dcr_write(i2o_dcr_host, DCRN_I2O0_IBAL, (u32)(i2o_res.start) |
+						I2O_REG_ENABLE);
+	dcr_unmap(i2o_dcr_host, dcr_len);
+
+	/* Setup FIFO memory space base address */
+	iowrite32(0, &i2o_reg->ifbah);
+	iowrite32(((u32)__pa(ppc440spe_dma_fifo_buf)), &i2o_reg->ifbal);
+
+	/* set zero FIFO size for I2O, so the whole
+	 * ppc440spe_dma_fifo_buf is used by DMAs.
+	 * DMAx_FIFOs will be configured while probe.
+	 */
+	iowrite32(0, &i2o_reg->ifsiz);
+	iounmap(i2o_reg);
+
+	/* To prepare WXOR/RXOR functionality we need access to
+	 * Memory Queue Module DCRs (finally it will be enabled
+	 * via /sys interface of the ppc440spe ADMA driver).
+	 */
+	np = of_find_compatible_node(NULL, NULL, "ibm,mq-440spe");
+	if (!np) {
+		pr_err("%s: can't find MQ device tree node\n",
+			__func__);
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	/* Get MQ DCRs base */
+	dcr_base = dcr_resource_start(np, 0);
+	dcr_len = dcr_resource_len(np, 0);
+	if (!dcr_base && !dcr_len) {
+		pr_err("%s: can't get DCR registers base/len!\n",
+			np->full_name);
+		ret = -ENODEV;
+		goto out_mq;
+	}
+
+	ppc440spe_mq_dcr_host = dcr_map(np, dcr_base, dcr_len);
+	if (!DCR_MAP_OK(ppc440spe_mq_dcr_host)) {
+		pr_err("%s: failed to map DCRs!\n", np->full_name);
+		ret = -ENODEV;
+		goto out_mq;
+	}
+	of_node_put(np);
+	ppc440spe_mq_dcr_len = dcr_len;
+
+	/* Set HB alias */
+	dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_BAUH, DMA_CUED_XOR_HB);
+
+	/* Set:
+	 * - LL transaction passing limit to 1;
+	 * - Memory controller cycle limit to 1;
+	 * - Galois Polynomial to 0x14d (default)
+	 */
+	dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL,
+		  (1 << MQ0_CFBHL_TPLM) | (1 << MQ0_CFBHL_HBCL) |
+		  (PPC440SPE_DEFAULT_POLY << MQ0_CFBHL_POLY));
+
+	atomic_set(&ppc440spe_adma_err_irq_ref, 0);
+	for (i = 0; i < PPC440SPE_ADMA_ENGINES_NUM; i++)
+		ppc440spe_adma_devices[i] = -1;
+
+	return 0;
+
+out_mq:
+	of_node_put(np);
+out_free:
+	kfree(ppc440spe_dma_fifo_buf);
+	return ret;
+}
+
+static struct of_device_id __devinitdata ppc440spe_adma_of_match[] = {
+	{ .compatible	= "ibm,dma-440spe", },
+	{ .compatible	= "amcc,xor-accelerator", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match);
+
+static struct of_platform_driver ppc440spe_adma_driver = {
+	.match_table = ppc440spe_adma_of_match,
+	.probe = ppc440spe_adma_probe,
+	.remove = __devexit_p(ppc440spe_adma_remove),
+	.driver = {
+		.name = "PPC440SP(E)-ADMA",
+		.owner = THIS_MODULE,
+	},
+};
+
+static __init int ppc440spe_adma_init(void)
+{
+	int ret;
+
+	ret = ppc440spe_configure_raid_devices();
+	if (ret)
+		return ret;
+
+	ret = of_register_platform_driver(&ppc440spe_adma_driver);
+	if (ret) {
+		pr_err("%s: failed to register platform driver\n",
+			__func__);
+		goto out_reg;
+	}
+
+	/* Initialization status */
+	ret = driver_create_file(&ppc440spe_adma_driver.driver,
+				 &driver_attr_devices);
+	if (ret)
+		goto out_dev;
+
+	/* RAID-6 h/w enable entry */
+	ret = driver_create_file(&ppc440spe_adma_driver.driver,
+				 &driver_attr_enable);
+	if (ret)
+		goto out_en;
+
+	/* GF polynomial to use */
+	ret = driver_create_file(&ppc440spe_adma_driver.driver,
+				 &driver_attr_poly);
+	if (!ret)
+		return ret;
+
+	driver_remove_file(&ppc440spe_adma_driver.driver,
+			   &driver_attr_enable);
+out_en:
+	driver_remove_file(&ppc440spe_adma_driver.driver,
+			   &driver_attr_devices);
+out_dev:
+	/* User will not be able to enable h/w RAID-6 */
+	pr_err("%s: failed to create RAID-6 driver interface\n",
+		__func__);
+	of_unregister_platform_driver(&ppc440spe_adma_driver);
+out_reg:
+	dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len);
+	kfree(ppc440spe_dma_fifo_buf);
+	return ret;
+}
+
+static void __exit ppc440spe_adma_exit(void)
+{
+	driver_remove_file(&ppc440spe_adma_driver.driver,
+			   &driver_attr_poly);
+	driver_remove_file(&ppc440spe_adma_driver.driver,
+			   &driver_attr_enable);
+	driver_remove_file(&ppc440spe_adma_driver.driver,
+			   &driver_attr_devices);
+	of_unregister_platform_driver(&ppc440spe_adma_driver);
+	dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len);
+	kfree(ppc440spe_dma_fifo_buf);
+}
+
+arch_initcall(ppc440spe_adma_init);
+module_exit(ppc440spe_adma_exit);
+
+MODULE_AUTHOR("Yuri Tikhonov <yur@emcraft.com>");
+MODULE_DESCRIPTION("PPC440SPE ADMA Engine Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/adma.h linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/adma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/adma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,195 @@
+/*
+ * 2006-2009 (C) DENX Software Engineering.
+ *
+ * Author: Yuri Tikhonov <yur@emcraft.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 _PPC440SPE_ADMA_H
+#define _PPC440SPE_ADMA_H
+
+#include <linux/types.h>
+#include "dma.h"
+#include "xor.h"
+
+#define to_ppc440spe_adma_chan(chan) \
+		container_of(chan, struct ppc440spe_adma_chan, common)
+#define to_ppc440spe_adma_device(dev) \
+		container_of(dev, struct ppc440spe_adma_device, common)
+#define tx_to_ppc440spe_adma_slot(tx) \
+		container_of(tx, struct ppc440spe_adma_desc_slot, async_tx)
+
+/* Default polynomial (for 440SP is only available) */
+#define PPC440SPE_DEFAULT_POLY	0x4d
+
+#define PPC440SPE_ADMA_ENGINES_NUM	(XOR_ENGINES_NUM + DMA_ENGINES_NUM)
+
+#define PPC440SPE_ADMA_WATCHDOG_MSEC	3
+#define PPC440SPE_ADMA_THRESHOLD	1
+
+#define PPC440SPE_DMA0_ID	0
+#define PPC440SPE_DMA1_ID	1
+#define PPC440SPE_XOR_ID	2
+
+#define PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT	0xFFFFFFUL
+/* this is the XOR_CBBCR width */
+#define PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT	(1 << 31)
+#define PPC440SPE_ADMA_ZERO_SUM_MAX_BYTE_COUNT PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT
+
+#define PPC440SPE_RXOR_RUN	0
+
+#define MQ0_CF2H_RXOR_BS_MASK	0x1FF
+
+#undef ADMA_LL_DEBUG
+
+/**
+ * struct ppc440spe_adma_device - internal representation of an ADMA device
+ * @dev: device
+ * @dma_reg: base for DMAx register access
+ * @xor_reg: base for XOR register access
+ * @i2o_reg: base for I2O register access
+ * @id: HW ADMA Device selector
+ * @dma_desc_pool_virt: base of DMA descriptor region (CPU address)
+ * @dma_desc_pool: base of DMA descriptor region (DMA address)
+ * @pool_size: size of the pool
+ * @irq: DMAx or XOR irq number
+ * @err_irq: DMAx error irq number
+ * @common: embedded struct dma_device
+ */
+struct ppc440spe_adma_device {
+	struct device *dev;
+	struct dma_regs __iomem *dma_reg;
+	struct xor_regs __iomem *xor_reg;
+	struct i2o_regs __iomem *i2o_reg;
+	int id;
+	void *dma_desc_pool_virt;
+	dma_addr_t dma_desc_pool;
+	size_t pool_size;
+	int irq;
+	int err_irq;
+	struct dma_device common;
+};
+
+/**
+ * struct ppc440spe_adma_chan - internal representation of an ADMA channel
+ * @lock: serializes enqueue/dequeue operations to the slot pool
+ * @device: parent device
+ * @chain: device chain view of the descriptors
+ * @common: common dmaengine channel object members
+ * @all_slots: complete domain of slots usable by the channel
+ * @pending: allows batching of hardware operations
+ * @completed_cookie: identifier for the most recently completed operation
+ * @slots_allocated: records the actual size of the descriptor slot pool
+ * @hw_chain_inited: h/w descriptor chain initialization flag
+ * @irq_tasklet: bottom half where ppc440spe_adma_slot_cleanup runs
+ * @needs_unmap: if buffers should not be unmapped upon final processing
+ * @pdest_page: P destination page for async validate operation
+ * @qdest_page: Q destination page for async validate operation
+ * @pdest: P dma addr for async validate operation
+ * @qdest: Q dma addr for async validate operation
+ */
+struct ppc440spe_adma_chan {
+	spinlock_t lock;
+	struct ppc440spe_adma_device *device;
+	struct list_head chain;
+	struct dma_chan common;
+	struct list_head all_slots;
+	struct ppc440spe_adma_desc_slot *last_used;
+	int pending;
+	dma_cookie_t completed_cookie;
+	int slots_allocated;
+	int hw_chain_inited;
+	struct tasklet_struct irq_tasklet;
+	u8 needs_unmap;
+	struct page *pdest_page;
+	struct page *qdest_page;
+	dma_addr_t pdest;
+	dma_addr_t qdest;
+};
+
+struct ppc440spe_rxor {
+	u32 addrl;
+	u32 addrh;
+	int len;
+	int xor_count;
+	int addr_count;
+	int desc_count;
+	int state;
+};
+
+/**
+ * struct ppc440spe_adma_desc_slot - PPC440SPE-ADMA software descriptor
+ * @phys: hardware address of the hardware descriptor chain
+ * @group_head: first operation in a transaction
+ * @hw_next: pointer to the next descriptor in chain
+ * @async_tx: support for the async_tx api
+ * @slot_node: node on the iop_adma_chan.all_slots list
+ * @chain_node: node on the op_adma_chan.chain list
+ * @group_list: list of slots that make up a multi-descriptor transaction
+ *              for example transfer lengths larger than the supported hw max
+ * @unmap_len: transaction bytecount
+ * @hw_desc: virtual address of the hardware descriptor chain
+ * @stride: currently chained or not
+ * @idx: pool index
+ * @slot_cnt: total slots used in an transaction (group of operations)
+ * @src_cnt: number of sources set in this descriptor
+ * @dst_cnt: number of destinations set in the descriptor
+ * @slots_per_op: number of slots per operation
+ * @descs_per_op: number of slot per P/Q operation see comment
+ *                for ppc440spe_prep_dma_pqxor function
+ * @flags: desc state/type
+ * @reverse_flags: 1 if a corresponding rxor address uses reversed address order
+ * @xor_check_result: result of zero sum
+ * @crc32_result: result crc calculation
+ */
+struct ppc440spe_adma_desc_slot {
+	dma_addr_t phys;
+	struct ppc440spe_adma_desc_slot *group_head;
+	struct ppc440spe_adma_desc_slot *hw_next;
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head slot_node;
+	struct list_head chain_node; /* node in channel ops list */
+	struct list_head group_list; /* list */
+	unsigned int unmap_len;
+	void *hw_desc;
+	u16 stride;
+	u16 idx;
+	u16 slot_cnt;
+	u8 src_cnt;
+	u8 dst_cnt;
+	u8 slots_per_op;
+	u8 descs_per_op;
+	unsigned long flags;
+	unsigned long reverse_flags[8];
+
+#define PPC440SPE_DESC_INT	0	/* generate interrupt on complete */
+#define PPC440SPE_ZERO_P	1	/* clear P destionaion */
+#define PPC440SPE_ZERO_Q	2	/* clear Q destination */
+#define PPC440SPE_COHERENT	3	/* src/dst are coherent */
+
+#define PPC440SPE_DESC_WXOR	4	/* WXORs are in chain */
+#define PPC440SPE_DESC_RXOR	5	/* RXOR is in chain */
+
+#define PPC440SPE_DESC_RXOR123	8	/* CDB for RXOR123 operation */
+#define PPC440SPE_DESC_RXOR124	9	/* CDB for RXOR124 operation */
+#define PPC440SPE_DESC_RXOR125	10	/* CDB for RXOR125 operation */
+#define PPC440SPE_DESC_RXOR12	11	/* CDB for RXOR12 operation */
+#define PPC440SPE_DESC_RXOR_REV	12	/* CDB has srcs in reversed order */
+
+#define PPC440SPE_DESC_PCHECK	13
+#define PPC440SPE_DESC_QCHECK	14
+
+#define PPC440SPE_DESC_RXOR_MSK	0x3
+
+	struct ppc440spe_rxor rxor_cursor;
+
+	union {
+		u32 *xor_check_result;
+		u32 *crc32_result;
+	};
+};
+
+#endif /* _PPC440SPE_ADMA_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/dma.h linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/dma.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,223 @@
+/*
+ * 440SPe's DMA engines support header file
+ *
+ * 2006-2009 (C) DENX Software Engineering.
+ *
+ * Author: Yuri Tikhonov <yur@emcraft.com>
+ *
+ * This file is licensed under the term of  the GNU General Public License
+ * version 2. The program licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef	_PPC440SPE_DMA_H
+#define _PPC440SPE_DMA_H
+
+#include <linux/types.h>
+
+/* Number of elements in the array with statical CDBs */
+#define	MAX_STAT_DMA_CDBS	16
+/* Number of DMA engines available on the contoller */
+#define DMA_ENGINES_NUM		2
+
+/* Maximum h/w supported number of destinations */
+#define DMA_DEST_MAX_NUM	2
+
+/* FIFO's params */
+#define DMA0_FIFO_SIZE		0x1000
+#define DMA1_FIFO_SIZE		0x1000
+#define DMA_FIFO_ENABLE		(1<<12)
+
+/* DMA Configuration Register. Data Transfer Engine PLB Priority: */
+#define DMA_CFG_DXEPR_LP	(0<<26)
+#define DMA_CFG_DXEPR_HP	(3<<26)
+#define DMA_CFG_DXEPR_HHP	(2<<26)
+#define DMA_CFG_DXEPR_HHHP	(1<<26)
+
+/* DMA Configuration Register. DMA FIFO Manager PLB Priority: */
+#define DMA_CFG_DFMPP_LP	(0<<23)
+#define DMA_CFG_DFMPP_HP	(3<<23)
+#define DMA_CFG_DFMPP_HHP	(2<<23)
+#define DMA_CFG_DFMPP_HHHP	(1<<23)
+
+/* DMA Configuration Register. Force 64-byte Alignment */
+#define DMA_CFG_FALGN		(1 << 19)
+
+/*UIC0:*/
+#define D0CPF_INT		(1<<12)
+#define D0CSF_INT		(1<<11)
+#define D1CPF_INT		(1<<10)
+#define D1CSF_INT		(1<<9)
+/*UIC1:*/
+#define DMAE_INT		(1<<9)
+
+/* I2O IOP Interrupt Mask Register */
+#define I2O_IOPIM_P0SNE		(1<<3)
+#define I2O_IOPIM_P0EM		(1<<5)
+#define I2O_IOPIM_P1SNE		(1<<6)
+#define I2O_IOPIM_P1EM		(1<<8)
+
+/* DMA CDB fields */
+#define DMA_CDB_MSK		(0xF)
+#define DMA_CDB_64B_ADDR	(1<<2)
+#define DMA_CDB_NO_INT		(1<<3)
+#define DMA_CDB_STATUS_MSK	(0x3)
+#define DMA_CDB_ADDR_MSK	(0xFFFFFFF0)
+
+/* DMA CDB OpCodes */
+#define DMA_CDB_OPC_NO_OP	(0x00)
+#define DMA_CDB_OPC_MV_SG1_SG2	(0x01)
+#define DMA_CDB_OPC_MULTICAST	(0x05)
+#define DMA_CDB_OPC_DFILL128	(0x24)
+#define DMA_CDB_OPC_DCHECK128	(0x23)
+
+#define DMA_CUED_XOR_BASE	(0x10000000)
+#define DMA_CUED_XOR_HB		(0x00000008)
+
+#ifdef CONFIG_440SP
+#define DMA_CUED_MULT1_OFF	0
+#define DMA_CUED_MULT2_OFF	8
+#define DMA_CUED_MULT3_OFF	16
+#define DMA_CUED_REGION_OFF	24
+#define DMA_CUED_XOR_WIN_MSK	(0xFC000000)
+#else
+#define DMA_CUED_MULT1_OFF	2
+#define DMA_CUED_MULT2_OFF	10
+#define DMA_CUED_MULT3_OFF	18
+#define DMA_CUED_REGION_OFF	26
+#define DMA_CUED_XOR_WIN_MSK	(0xF0000000)
+#endif
+
+#define DMA_CUED_REGION_MSK	0x3
+#define DMA_RXOR123		0x0
+#define DMA_RXOR124		0x1
+#define DMA_RXOR125		0x2
+#define DMA_RXOR12		0x3
+
+/* S/G addresses */
+#define DMA_CDB_SG_SRC		1
+#define DMA_CDB_SG_DST1		2
+#define DMA_CDB_SG_DST2		3
+
+/*
+ * DMAx engines Command Descriptor Block Type
+ */
+struct dma_cdb {
+	/*
+	 * Basic CDB structure (Table 20-17, p.499, 440spe_um_1_22.pdf)
+	 */
+	u8	pad0[2];        /* reserved */
+	u8	attr;		/* attributes */
+	u8	opc;		/* opcode */
+	u32	sg1u;		/* upper SG1 address */
+	u32	sg1l;		/* lower SG1 address */
+	u32	cnt;		/* SG count, 3B used */
+	u32	sg2u;		/* upper SG2 address */
+	u32	sg2l;		/* lower SG2 address */
+	u32	sg3u;		/* upper SG3 address */
+	u32	sg3l;		/* lower SG3 address */
+};
+
+/*
+ * DMAx hardware registers (p.515 in 440SPe UM 1.22)
+ */
+struct dma_regs {
+	u32	cpfpl;
+	u32	cpfph;
+	u32	csfpl;
+	u32	csfph;
+	u32	dsts;
+	u32	cfg;
+	u8	pad0[0x8];
+	u16	cpfhp;
+	u16	cpftp;
+	u16	csfhp;
+	u16	csftp;
+	u8	pad1[0x8];
+	u32	acpl;
+	u32	acph;
+	u32	s1bpl;
+	u32	s1bph;
+	u32	s2bpl;
+	u32	s2bph;
+	u32	s3bpl;
+	u32	s3bph;
+	u8	pad2[0x10];
+	u32	earl;
+	u32	earh;
+	u8	pad3[0x8];
+	u32	seat;
+	u32	sead;
+	u32	op;
+	u32	fsiz;
+};
+
+/*
+ * I2O hardware registers (p.528 in 440SPe UM 1.22)
+ */
+struct i2o_regs {
+	u32	ists;
+	u32	iseat;
+	u32	isead;
+	u8	pad0[0x14];
+	u32	idbel;
+	u8	pad1[0xc];
+	u32	ihis;
+	u32	ihim;
+	u8	pad2[0x8];
+	u32	ihiq;
+	u32	ihoq;
+	u8	pad3[0x8];
+	u32	iopis;
+	u32	iopim;
+	u32	iopiq;
+	u8	iopoq;
+	u8	pad4[3];
+	u16	iiflh;
+	u16	iiflt;
+	u16	iiplh;
+	u16	iiplt;
+	u16	ioflh;
+	u16	ioflt;
+	u16	ioplh;
+	u16	ioplt;
+	u32	iidc;
+	u32	ictl;
+	u32	ifcpp;
+	u8	pad5[0x4];
+	u16	mfac0;
+	u16	mfac1;
+	u16	mfac2;
+	u16	mfac3;
+	u16	mfac4;
+	u16	mfac5;
+	u16	mfac6;
+	u16	mfac7;
+	u16	ifcfh;
+	u16	ifcht;
+	u8	pad6[0x4];
+	u32	iifmc;
+	u32	iodb;
+	u32	iodbc;
+	u32	ifbal;
+	u32	ifbah;
+	u32	ifsiz;
+	u32	ispd0;
+	u32	ispd1;
+	u32	ispd2;
+	u32	ispd3;
+	u32	ihipl;
+	u32	ihiph;
+	u32	ihopl;
+	u32	ihoph;
+	u32	iiipl;
+	u32	iiiph;
+	u32	iiopl;
+	u32	iioph;
+	u32	ifcpl;
+	u32	ifcph;
+	u8	pad7[0x8];
+	u32	iopt;
+};
+
+#endif /* _PPC440SPE_DMA_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/Makefile linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/Makefile
--- linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1 @@
+obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += adma.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/xor.h linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/xor.h
--- linux-libre-2.6.32-gnu1/drivers/dma/ppc4xx/xor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/ppc4xx/xor.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,110 @@
+/*
+ * 440SPe's XOR engines support header file
+ *
+ * 2006-2009 (C) DENX Software Engineering.
+ *
+ * Author: Yuri Tikhonov <yur@emcraft.com>
+ *
+ * This file is licensed under the term of  the GNU General Public License
+ * version 2. The program licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef _PPC440SPE_XOR_H
+#define _PPC440SPE_XOR_H
+
+#include <linux/types.h>
+
+/* Number of XOR engines available on the contoller */
+#define XOR_ENGINES_NUM		1
+
+/* Number of operands supported in the h/w */
+#define XOR_MAX_OPS		16
+
+/*
+ * XOR Command Block Control Register bits
+ */
+#define XOR_CBCR_LNK_BIT        (1<<31) /* link present */
+#define XOR_CBCR_TGT_BIT        (1<<30) /* target present */
+#define XOR_CBCR_CBCE_BIT       (1<<29) /* command block compete enable */
+#define XOR_CBCR_RNZE_BIT       (1<<28) /* result not zero enable */
+#define XOR_CBCR_XNOR_BIT       (1<<15) /* XOR/XNOR */
+#define XOR_CDCR_OAC_MSK        (0x7F)  /* operand address count */
+
+/*
+ * XORCore Status Register bits
+ */
+#define XOR_SR_XCP_BIT		(1<<31)	/* core processing */
+#define XOR_SR_ICB_BIT		(1<<17)	/* invalid CB */
+#define XOR_SR_IC_BIT		(1<<16)	/* invalid command */
+#define XOR_SR_IPE_BIT		(1<<15)	/* internal parity error */
+#define XOR_SR_RNZ_BIT		(1<<2)	/* result not Zero */
+#define XOR_SR_CBC_BIT		(1<<1)	/* CB complete */
+#define XOR_SR_CBLC_BIT		(1<<0)	/* CB list complete */
+
+/*
+ * XORCore Control Set and Reset Register bits
+ */
+#define XOR_CRSR_XASR_BIT	(1<<31)	/* soft reset */
+#define XOR_CRSR_XAE_BIT	(1<<30)	/* enable */
+#define XOR_CRSR_RCBE_BIT	(1<<29)	/* refetch CB enable */
+#define XOR_CRSR_PAUS_BIT	(1<<28)	/* pause */
+#define XOR_CRSR_64BA_BIT	(1<<27) /* 64/32 CB format */
+#define XOR_CRSR_CLP_BIT	(1<<25)	/* continue list processing */
+
+/*
+ * XORCore Interrupt Enable Register
+ */
+#define XOR_IE_ICBIE_BIT	(1<<17)	/* Invalid Command Block IRQ Enable */
+#define XOR_IE_ICIE_BIT		(1<<16)	/* Invalid Command IRQ Enable */
+#define XOR_IE_RPTIE_BIT	(1<<14)	/* Read PLB Timeout Error IRQ Enable */
+#define XOR_IE_CBCIE_BIT	(1<<1)	/* CB complete interrupt enable */
+#define XOR_IE_CBLCI_BIT	(1<<0)	/* CB list complete interrupt enable */
+
+/*
+ * XOR Accelerator engine Command Block Type
+ */
+struct xor_cb {
+	/*
+	 * Basic 64-bit format XOR CB (Table 19-1, p.463, 440spe_um_1_22.pdf)
+	 */
+	u32	cbc;		/* control */
+	u32	cbbc;		/* byte count */
+	u32	cbs;		/* status */
+	u8	pad0[4];	/* reserved */
+	u32	cbtah;		/* target address high */
+	u32	cbtal;		/* target address low */
+	u32	cblah;		/* link address high */
+	u32	cblal;		/* link address low */
+	struct {
+		u32 h;
+		u32 l;
+	} __attribute__ ((packed)) ops[16];
+} __attribute__ ((packed));
+
+/*
+ * XOR hardware registers Table 19-3, UM 1.22
+ */
+struct xor_regs {
+	u32	op_ar[16][2];	/* operand address[0]-high,[1]-low registers */
+	u8	pad0[352];	/* reserved */
+	u32	cbcr;		/* CB control register */
+	u32	cbbcr;		/* CB byte count register */
+	u32	cbsr;		/* CB status register */
+	u8	pad1[4];	/* reserved */
+	u32	cbtahr;		/* operand target address high register */
+	u32	cbtalr;		/* operand target address low register */
+	u32	cblahr;		/* CB link address high register */
+	u32	cblalr;		/* CB link address low register */
+	u32	crsr;		/* control set register */
+	u32	crrr;		/* control reset register */
+	u32	ccbahr;		/* current CB address high register */
+	u32	ccbalr;		/* current CB address low register */
+	u32	plbr;		/* PLB configuration register */
+	u32	ier;		/* interrupt enable register */
+	u32	pecr;		/* parity error count register */
+	u32	sr;		/* status register */
+	u32	revidr;		/* revision ID register */
+};
+
+#endif /* _PPC440SPE_XOR_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/shdma.c linux-libre-2.6.33-gnu1/drivers/dma/shdma.c
--- linux-libre-2.6.32-gnu1/drivers/dma/shdma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/shdma.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,16 +23,19 @@
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/dmapool.h>
 #include <linux/platform_device.h>
 #include <cpu/dma.h>
 #include <asm/dma-sh.h>
 #include "shdma.h"
 
 /* DMA descriptor control */
-#define DESC_LAST	(-1)
-#define DESC_COMP	(1)
-#define DESC_NCOMP	(0)
+enum sh_dmae_desc_status {
+	DESC_IDLE,
+	DESC_PREPARED,
+	DESC_SUBMITTED,
+	DESC_COMPLETED,	/* completed, have to call callback */
+	DESC_WAITING,	/* callback called, waiting for ack / re-submit */
+};
 
 #define NR_DESCS_PER_CHANNEL 32
 /*
@@ -45,6 +48,8 @@
  */
 #define RS_DEFAULT  (RS_DUAL)
 
+static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
+
 #define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id])
 static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
 {
@@ -80,17 +85,17 @@ static int sh_dmae_rst(int id)
 	unsigned short dmaor;
 
 	sh_dmae_ctl_stop(id);
-	dmaor = (dmaor_read_reg(id)|DMAOR_INIT);
+	dmaor = dmaor_read_reg(id) | DMAOR_INIT;
 
 	dmaor_write_reg(id, dmaor);
-	if ((dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF))) {
+	if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) {
 		pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int dmae_is_idle(struct sh_dmae_chan *sh_chan)
+static int dmae_is_busy(struct sh_dmae_chan *sh_chan)
 {
 	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
 	if (chcr & CHCR_DE) {
@@ -106,19 +111,18 @@ static inline unsigned int calc_xmit_shi
 	return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT];
 }
 
-static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs hw)
+static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
 {
-	sh_dmae_writel(sh_chan, hw.sar, SAR);
-	sh_dmae_writel(sh_chan, hw.dar, DAR);
-	sh_dmae_writel(sh_chan,
-		(hw.tcr >> calc_xmit_shift(sh_chan)), TCR);
+	sh_dmae_writel(sh_chan, hw->sar, SAR);
+	sh_dmae_writel(sh_chan, hw->dar, DAR);
+	sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR);
 }
 
 static void dmae_start(struct sh_dmae_chan *sh_chan)
 {
 	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
 
-	chcr |= (CHCR_DE|CHCR_IE);
+	chcr |= CHCR_DE | CHCR_IE;
 	sh_dmae_writel(sh_chan, chcr, CHCR);
 }
 
@@ -132,7 +136,7 @@ static void dmae_halt(struct sh_dmae_cha
 
 static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
 {
-	int ret = dmae_is_idle(sh_chan);
+	int ret = dmae_is_busy(sh_chan);
 	/* When DMA was working, can not set data to CHCR */
 	if (ret)
 		return ret;
@@ -149,7 +153,7 @@ static int dmae_set_dmars(struct sh_dmae
 {
 	u32 addr;
 	int shift = 0;
-	int ret = dmae_is_idle(sh_chan);
+	int ret = dmae_is_busy(sh_chan);
 	if (ret)
 		return ret;
 
@@ -185,8 +189,9 @@ static int dmae_set_dmars(struct sh_dmae
 
 static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
 {
-	struct sh_desc *desc = tx_to_sh_desc(tx);
+	struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c;
 	struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan);
+	dma_async_tx_callback callback = tx->callback;
 	dma_cookie_t cookie;
 
 	spin_lock_bh(&sh_chan->desc_lock);
@@ -196,45 +201,53 @@ static dma_cookie_t sh_dmae_tx_submit(st
 	if (cookie < 0)
 		cookie = 1;
 
-	/* If desc only in the case of 1 */
-	if (desc->async_tx.cookie != -EBUSY)
-		desc->async_tx.cookie = cookie;
-	sh_chan->common.cookie = desc->async_tx.cookie;
+	sh_chan->common.cookie = cookie;
+	tx->cookie = cookie;
 
-	list_splice_init(&desc->tx_list, sh_chan->ld_queue.prev);
+	/* Mark all chunks of this descriptor as submitted, move to the queue */
+	list_for_each_entry_safe(chunk, c, desc->node.prev, node) {
+		/*
+		 * All chunks are on the global ld_free, so, we have to find
+		 * the end of the chain ourselves
+		 */
+		if (chunk != desc && (chunk->mark == DESC_IDLE ||
+				      chunk->async_tx.cookie > 0 ||
+				      chunk->async_tx.cookie == -EBUSY ||
+				      &chunk->node == &sh_chan->ld_free))
+			break;
+		chunk->mark = DESC_SUBMITTED;
+		/* Callback goes to the last chunk */
+		chunk->async_tx.callback = NULL;
+		chunk->cookie = cookie;
+		list_move_tail(&chunk->node, &sh_chan->ld_queue);
+		last = chunk;
+	}
+
+	last->async_tx.callback = callback;
+	last->async_tx.callback_param = tx->callback_param;
+
+	dev_dbg(sh_chan->dev, "submit #%d@%p on %d: %x[%d] -> %x\n",
+		tx->cookie, &last->async_tx, sh_chan->id,
+		desc->hw.sar, desc->hw.tcr, desc->hw.dar);
 
 	spin_unlock_bh(&sh_chan->desc_lock);
 
 	return cookie;
 }
 
+/* Called with desc_lock held */
 static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
 {
-	struct sh_desc *desc, *_desc, *ret = NULL;
+	struct sh_desc *desc;
 
-	spin_lock_bh(&sh_chan->desc_lock);
-	list_for_each_entry_safe(desc, _desc, &sh_chan->ld_free, node) {
-		if (async_tx_test_ack(&desc->async_tx)) {
+	list_for_each_entry(desc, &sh_chan->ld_free, node)
+		if (desc->mark != DESC_PREPARED) {
+			BUG_ON(desc->mark != DESC_IDLE);
 			list_del(&desc->node);
-			ret = desc;
-			break;
+			return desc;
 		}
-	}
-	spin_unlock_bh(&sh_chan->desc_lock);
 
-	return ret;
-}
-
-static void sh_dmae_put_desc(struct sh_dmae_chan *sh_chan, struct sh_desc *desc)
-{
-	if (desc) {
-		spin_lock_bh(&sh_chan->desc_lock);
-
-		list_splice_init(&desc->tx_list, &sh_chan->ld_free);
-		list_add(&desc->node, &sh_chan->ld_free);
-
-		spin_unlock_bh(&sh_chan->desc_lock);
-	}
+	return NULL;
 }
 
 static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
@@ -253,11 +266,10 @@ static int sh_dmae_alloc_chan_resources(
 		dma_async_tx_descriptor_init(&desc->async_tx,
 					&sh_chan->common);
 		desc->async_tx.tx_submit = sh_dmae_tx_submit;
-		desc->async_tx.flags = DMA_CTRL_ACK;
-		INIT_LIST_HEAD(&desc->tx_list);
-		sh_dmae_put_desc(sh_chan, desc);
+		desc->mark = DESC_IDLE;
 
 		spin_lock_bh(&sh_chan->desc_lock);
+		list_add(&desc->node, &sh_chan->ld_free);
 		sh_chan->descs_allocated++;
 	}
 	spin_unlock_bh(&sh_chan->desc_lock);
@@ -274,7 +286,10 @@ static void sh_dmae_free_chan_resources(
 	struct sh_desc *desc, *_desc;
 	LIST_HEAD(list);
 
-	BUG_ON(!list_empty(&sh_chan->ld_queue));
+	/* Prepared and not submitted descriptors can still be on the queue */
+	if (!list_empty(&sh_chan->ld_queue))
+		sh_dmae_chan_ld_cleanup(sh_chan, true);
+
 	spin_lock_bh(&sh_chan->desc_lock);
 
 	list_splice_init(&sh_chan->ld_free, &list);
@@ -293,6 +308,8 @@ static struct dma_async_tx_descriptor *s
 	struct sh_dmae_chan *sh_chan;
 	struct sh_desc *first = NULL, *prev = NULL, *new;
 	size_t copy_size;
+	LIST_HEAD(tx_list);
+	int chunks = (len + SH_DMA_TCR_MAX) / (SH_DMA_TCR_MAX + 1);
 
 	if (!chan)
 		return NULL;
@@ -302,108 +319,189 @@ static struct dma_async_tx_descriptor *s
 
 	sh_chan = to_sh_chan(chan);
 
+	/* Have to lock the whole loop to protect against concurrent release */
+	spin_lock_bh(&sh_chan->desc_lock);
+
+	/*
+	 * Chaining:
+	 * first descriptor is what user is dealing with in all API calls, its
+	 *	cookie is at first set to -EBUSY, at tx-submit to a positive
+	 *	number
+	 * if more than one chunk is needed further chunks have cookie = -EINVAL
+	 * the last chunk, if not equal to the first, has cookie = -ENOSPC
+	 * all chunks are linked onto the tx_list head with their .node heads
+	 *	only during this function, then they are immediately spliced
+	 *	back onto the free list in form of a chain
+	 */
 	do {
-		/* Allocate the link descriptor from DMA pool */
+		/* Allocate the link descriptor from the free list */
 		new = sh_dmae_get_desc(sh_chan);
 		if (!new) {
 			dev_err(sh_chan->dev,
-					"No free memory for link descriptor\n");
-			goto err_get_desc;
+				"No free memory for link descriptor\n");
+			list_for_each_entry(new, &tx_list, node)
+				new->mark = DESC_IDLE;
+			list_splice(&tx_list, &sh_chan->ld_free);
+			spin_unlock_bh(&sh_chan->desc_lock);
+			return NULL;
 		}
 
-		copy_size = min(len, (size_t)SH_DMA_TCR_MAX);
+		copy_size = min(len, (size_t)SH_DMA_TCR_MAX + 1);
 
 		new->hw.sar = dma_src;
 		new->hw.dar = dma_dest;
 		new->hw.tcr = copy_size;
-		if (!first)
+		if (!first) {
+			/* First desc */
+			new->async_tx.cookie = -EBUSY;
 			first = new;
+		} else {
+			/* Other desc - invisible to the user */
+			new->async_tx.cookie = -EINVAL;
+		}
 
-		new->mark = DESC_NCOMP;
-		async_tx_ack(&new->async_tx);
+		dev_dbg(sh_chan->dev,
+			"chaining %u of %u with %p, dst %x, cookie %d\n",
+			copy_size, len, &new->async_tx, dma_dest,
+			new->async_tx.cookie);
+
+		new->mark = DESC_PREPARED;
+		new->async_tx.flags = flags;
+		new->chunks = chunks--;
 
 		prev = new;
 		len -= copy_size;
 		dma_src += copy_size;
 		dma_dest += copy_size;
 		/* Insert the link descriptor to the LD ring */
-		list_add_tail(&new->node, &first->tx_list);
+		list_add_tail(&new->node, &tx_list);
 	} while (len);
 
-	new->async_tx.flags = flags; /* client is in control of this ack */
-	new->async_tx.cookie = -EBUSY; /* Last desc */
+	if (new != first)
+		new->async_tx.cookie = -ENOSPC;
 
-	return &first->async_tx;
+	/* Put them back on the free list, so, they don't get lost */
+	list_splice_tail(&tx_list, &sh_chan->ld_free);
 
-err_get_desc:
-	sh_dmae_put_desc(sh_chan, first);
-	return NULL;
+	spin_unlock_bh(&sh_chan->desc_lock);
 
+	return &first->async_tx;
 }
 
-/*
- * sh_chan_ld_cleanup - Clean up link descriptors
- *
- * This function clean up the ld_queue of DMA channel.
- */
-static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan)
+static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
 {
 	struct sh_desc *desc, *_desc;
+	/* Is the "exposed" head of a chain acked? */
+	bool head_acked = false;
+	dma_cookie_t cookie = 0;
+	dma_async_tx_callback callback = NULL;
+	void *param = NULL;
 
 	spin_lock_bh(&sh_chan->desc_lock);
 	list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) {
-		dma_async_tx_callback callback;
-		void *callback_param;
+		struct dma_async_tx_descriptor *tx = &desc->async_tx;
 
-		/* non send data */
-		if (desc->mark == DESC_NCOMP)
+		BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie);
+		BUG_ON(desc->mark != DESC_SUBMITTED &&
+		       desc->mark != DESC_COMPLETED &&
+		       desc->mark != DESC_WAITING);
+
+		/*
+		 * queue is ordered, and we use this loop to (1) clean up all
+		 * completed descriptors, and to (2) update descriptor flags of
+		 * any chunks in a (partially) completed chain
+		 */
+		if (!all && desc->mark == DESC_SUBMITTED &&
+		    desc->cookie != cookie)
 			break;
 
-		/* send data sesc */
-		callback = desc->async_tx.callback;
-		callback_param = desc->async_tx.callback_param;
+		if (tx->cookie > 0)
+			cookie = tx->cookie;
 
-		/* Remove from ld_queue list */
-		list_splice_init(&desc->tx_list, &sh_chan->ld_free);
+		if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
+			BUG_ON(sh_chan->completed_cookie != desc->cookie - 1);
+			sh_chan->completed_cookie = desc->cookie;
+		}
 
-		dev_dbg(sh_chan->dev, "link descriptor %p will be recycle.\n",
-				desc);
+		/* Call callback on the last chunk */
+		if (desc->mark == DESC_COMPLETED && tx->callback) {
+			desc->mark = DESC_WAITING;
+			callback = tx->callback;
+			param = tx->callback_param;
+			dev_dbg(sh_chan->dev, "descriptor #%d@%p on %d callback\n",
+				tx->cookie, tx, sh_chan->id);
+			BUG_ON(desc->chunks != 1);
+			break;
+		}
 
-		list_move(&desc->node, &sh_chan->ld_free);
-		/* Run the link descriptor callback function */
-		if (callback) {
-			spin_unlock_bh(&sh_chan->desc_lock);
-			dev_dbg(sh_chan->dev, "link descriptor %p callback\n",
-					desc);
-			callback(callback_param);
-			spin_lock_bh(&sh_chan->desc_lock);
+		if (tx->cookie > 0 || tx->cookie == -EBUSY) {
+			if (desc->mark == DESC_COMPLETED) {
+				BUG_ON(tx->cookie < 0);
+				desc->mark = DESC_WAITING;
+			}
+			head_acked = async_tx_test_ack(tx);
+		} else {
+			switch (desc->mark) {
+			case DESC_COMPLETED:
+				desc->mark = DESC_WAITING;
+				/* Fall through */
+			case DESC_WAITING:
+				if (head_acked)
+					async_tx_ack(&desc->async_tx);
+			}
+		}
+
+		dev_dbg(sh_chan->dev, "descriptor %p #%d completed.\n",
+			tx, tx->cookie);
+
+		if (((desc->mark == DESC_COMPLETED ||
+		      desc->mark == DESC_WAITING) &&
+		     async_tx_test_ack(&desc->async_tx)) || all) {
+			/* Remove from ld_queue list */
+			desc->mark = DESC_IDLE;
+			list_move(&desc->node, &sh_chan->ld_free);
 		}
 	}
 	spin_unlock_bh(&sh_chan->desc_lock);
+
+	if (callback)
+		callback(param);
+
+	return callback;
+}
+
+/*
+ * sh_chan_ld_cleanup - Clean up link descriptors
+ *
+ * This function cleans up the ld_queue of DMA channel.
+ */
+static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
+{
+	while (__ld_cleanup(sh_chan, all))
+		;
 }
 
 static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
 {
-	struct list_head *ld_node;
-	struct sh_dmae_regs hw;
+	struct sh_desc *sd;
 
+	spin_lock_bh(&sh_chan->desc_lock);
 	/* DMA work check */
-	if (dmae_is_idle(sh_chan))
+	if (dmae_is_busy(sh_chan)) {
+		spin_unlock_bh(&sh_chan->desc_lock);
 		return;
+	}
 
 	/* Find the first un-transfer desciptor */
-	for (ld_node = sh_chan->ld_queue.next;
-		(ld_node != &sh_chan->ld_queue)
-			&& (to_sh_desc(ld_node)->mark == DESC_COMP);
-		ld_node = ld_node->next)
-		cpu_relax();
+	list_for_each_entry(sd, &sh_chan->ld_queue, node)
+		if (sd->mark == DESC_SUBMITTED) {
+			/* Get the ld start address from ld_queue */
+			dmae_set_reg(sh_chan, &sd->hw);
+			dmae_start(sh_chan);
+			break;
+		}
 
-	if (ld_node != &sh_chan->ld_queue) {
-		/* Get the ld start address from ld_queue */
-		hw = to_sh_desc(ld_node)->hw;
-		dmae_set_reg(sh_chan, hw);
-		dmae_start(sh_chan);
-	}
+	spin_unlock_bh(&sh_chan->desc_lock);
 }
 
 static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan)
@@ -421,12 +519,11 @@ static enum dma_status sh_dmae_is_comple
 	dma_cookie_t last_used;
 	dma_cookie_t last_complete;
 
-	sh_dmae_chan_ld_cleanup(sh_chan);
+	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
 	last_used = chan->cookie;
 	last_complete = sh_chan->completed_cookie;
-	if (last_complete == -EBUSY)
-		last_complete = last_used;
+	BUG_ON(last_complete < 0);
 
 	if (done)
 		*done = last_complete;
@@ -481,11 +578,13 @@ static irqreturn_t sh_dmae_err(int irq,
 		err = sh_dmae_rst(0);
 		if (err)
 			return err;
+#ifdef SH_DMAC_BASE1
 		if (shdev->pdata.mode & SHDMA_DMAOR1) {
 			err = sh_dmae_rst(1);
 			if (err)
 				return err;
 		}
+#endif
 		disable_irq(irq);
 		return IRQ_HANDLED;
 	}
@@ -495,34 +594,25 @@ static irqreturn_t sh_dmae_err(int irq,
 static void dmae_do_tasklet(unsigned long data)
 {
 	struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data;
-	struct sh_desc *desc, *_desc, *cur_desc = NULL;
+	struct sh_desc *desc;
 	u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
-	list_for_each_entry_safe(desc, _desc,
-					&sh_chan->ld_queue, node) {
-		if ((desc->hw.sar + desc->hw.tcr) == sar_buf) {
-			cur_desc = desc;
-			break;
-		}
-	}
 
-	if (cur_desc) {
-		switch (cur_desc->async_tx.cookie) {
-		case 0: /* other desc data */
-			break;
-		case -EBUSY: /* last desc */
-		sh_chan->completed_cookie =
-				cur_desc->async_tx.cookie;
-			break;
-		default: /* first desc ( 0 < )*/
-			sh_chan->completed_cookie =
-				cur_desc->async_tx.cookie - 1;
+	spin_lock(&sh_chan->desc_lock);
+	list_for_each_entry(desc, &sh_chan->ld_queue, node) {
+		if ((desc->hw.sar + desc->hw.tcr) == sar_buf &&
+		    desc->mark == DESC_SUBMITTED) {
+			dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n",
+				desc->async_tx.cookie, &desc->async_tx,
+				desc->hw.dar);
+			desc->mark = DESC_COMPLETED;
 			break;
 		}
-		cur_desc->mark = DESC_COMP;
 	}
+	spin_unlock(&sh_chan->desc_lock);
+
 	/* Next desc */
 	sh_chan_xfer_ld_queue(sh_chan);
-	sh_dmae_chan_ld_cleanup(sh_chan);
+	sh_dmae_chan_ld_cleanup(sh_chan, false);
 }
 
 static unsigned int get_dmae_irq(unsigned int id)
@@ -543,8 +633,8 @@ static int __devinit sh_dmae_chan_probe(
 	/* alloc channel */
 	new_sh_chan = kzalloc(sizeof(struct sh_dmae_chan), GFP_KERNEL);
 	if (!new_sh_chan) {
-		dev_err(shdev->common.dev, "No free memory for allocating "
-				"dma channels!\n");
+		dev_err(shdev->common.dev,
+			"No free memory for allocating dma channels!\n");
 		return -ENOMEM;
 	}
 
@@ -586,8 +676,8 @@ static int __devinit sh_dmae_chan_probe(
 			"sh-dmae%d", new_sh_chan->id);
 
 	/* set up channel irq */
-	err = request_irq(irq, &sh_dmae_interrupt,
-		irqflags, new_sh_chan->dev_id, new_sh_chan);
+	err = request_irq(irq, &sh_dmae_interrupt, irqflags,
+			  new_sh_chan->dev_id, new_sh_chan);
 	if (err) {
 		dev_err(shdev->common.dev, "DMA channel %d request_irq error "
 			"with return %d\n", id, err);
@@ -676,6 +766,8 @@ static int __init sh_dmae_probe(struct p
 	shdev->common.device_is_tx_complete = sh_dmae_is_complete;
 	shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending;
 	shdev->common.dev = &pdev->dev;
+	/* Default transfer size of 32 bytes requires 32-byte alignment */
+	shdev->common.copy_align = 5;
 
 #if defined(CONFIG_CPU_SH4)
 	/* Non Mix IRQ mode SH7722/SH7730 etc... */
@@ -688,8 +780,8 @@ static int __init sh_dmae_probe(struct p
 	}
 
 	for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) {
-		err = request_irq(eirq[ecnt], sh_dmae_err,
-			irqflags, "DMAC Address Error", shdev);
+		err = request_irq(eirq[ecnt], sh_dmae_err, irqflags,
+				  "DMAC Address Error", shdev);
 		if (err) {
 			dev_err(&pdev->dev, "DMA device request_irq"
 				"error (irq %d) with return %d\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/shdma.h linux-libre-2.6.33-gnu1/drivers/dma/shdma.h
--- linux-libre-2.6.32-gnu1/drivers/dma/shdma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/shdma.h	2010-02-24 13:52:17.000000000 -0500
@@ -13,9 +13,9 @@
 #ifndef __DMA_SHDMA_H
 #define __DMA_SHDMA_H
 
-#include <linux/device.h>
-#include <linux/dmapool.h>
 #include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
 
 #define SH_DMA_TCR_MAX 0x00FFFFFF	/* 16MB */
 
@@ -26,24 +26,27 @@ struct sh_dmae_regs {
 };
 
 struct sh_desc {
-	struct list_head tx_list;
 	struct sh_dmae_regs hw;
 	struct list_head node;
 	struct dma_async_tx_descriptor async_tx;
+	dma_cookie_t cookie;
+	int chunks;
 	int mark;
 };
 
+struct device;
+
 struct sh_dmae_chan {
 	dma_cookie_t completed_cookie;	/* The maximum cookie completed */
-	spinlock_t desc_lock;			/* Descriptor operation lock */
-	struct list_head ld_queue;		/* Link descriptors queue */
-	struct list_head ld_free;		/* Link descriptors free */
-	struct dma_chan common;			/* DMA common channel */
-	struct device *dev;				/* Channel device */
+	spinlock_t desc_lock;		/* Descriptor operation lock */
+	struct list_head ld_queue;	/* Link descriptors queue */
+	struct list_head ld_free;	/* Link descriptors free */
+	struct dma_chan common;		/* DMA common channel */
+	struct device *dev;		/* Channel device */
 	struct tasklet_struct tasklet;	/* Tasklet */
-	int descs_allocated;			/* desc count */
+	int descs_allocated;		/* desc count */
 	int id;				/* Raw id of this channel */
-	char dev_id[16];	/* unique name per DMAC of channel */
+	char dev_id[16];		/* unique name per DMAC of channel */
 
 	/* Set chcr */
 	int (*set_chcr)(struct sh_dmae_chan *sh_chan, u32 regs);
diff -druNp linux-libre-2.6.32-gnu1/drivers/dma/txx9dmac.c linux-libre-2.6.33-gnu1/drivers/dma/txx9dmac.c
--- linux-libre-2.6.32-gnu1/drivers/dma/txx9dmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/dma/txx9dmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1313,7 +1313,7 @@ static int txx9dmac_resume_noirq(struct
 
 }
 
-static struct dev_pm_ops txx9dmac_dev_pm_ops = {
+static const struct dev_pm_ops txx9dmac_dev_pm_ops = {
 	.suspend_noirq = txx9dmac_suspend_noirq,
 	.resume_noirq = txx9dmac_resume_noirq,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/amd64_edac.c linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.c
--- linux-libre-2.6.32-gnu1/drivers/edac/amd64_edac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,32 +13,56 @@ module_param(report_gart_errors, int, 06
 static int ecc_enable_override;
 module_param(ecc_enable_override, int, 0644);
 
+static struct msr *msrs;
+
 /* Lookup table for all possible MC control instances */
 struct amd64_pvt;
 static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
 static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
 
 /*
- * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
- * for DDR2 DRAM mapping.
+ * Address to DRAM bank mapping: see F2x80 for K8 and F2x[1,0]80 for Fam10 and
+ * later.
  */
-u32 revf_quad_ddr2_shift[] = {
-	0,	/* 0000b NULL DIMM (128mb) */
-	28,	/* 0001b 256mb */
-	29,	/* 0010b 512mb */
-	29,	/* 0011b 512mb */
-	29,	/* 0100b 512mb */
-	30,	/* 0101b 1gb */
-	30,	/* 0110b 1gb */
-	31,	/* 0111b 2gb */
-	31,	/* 1000b 2gb */
-	32,	/* 1001b 4gb */
-	32,	/* 1010b 4gb */
-	33,	/* 1011b 8gb */
-	0,	/* 1100b future */
-	0,	/* 1101b future */
-	0,	/* 1110b future */
-	0	/* 1111b future */
+static int ddr2_dbam_revCG[] = {
+			   [0]		= 32,
+			   [1]		= 64,
+			   [2]		= 128,
+			   [3]		= 256,
+			   [4]		= 512,
+			   [5]		= 1024,
+			   [6]		= 2048,
+};
+
+static int ddr2_dbam_revD[] = {
+			   [0]		= 32,
+			   [1]		= 64,
+			   [2 ... 3]	= 128,
+			   [4]		= 256,
+			   [5]		= 512,
+			   [6]		= 256,
+			   [7]		= 512,
+			   [8 ... 9]	= 1024,
+			   [10]		= 2048,
+};
+
+static int ddr2_dbam[] = { [0]		= 128,
+			   [1]		= 256,
+			   [2 ... 4]	= 512,
+			   [5 ... 6]	= 1024,
+			   [7 ... 8]	= 2048,
+			   [9 ... 10]	= 4096,
+			   [11]		= 8192,
+};
+
+static int ddr3_dbam[] = { [0]		= -1,
+			   [1]		= 256,
+			   [2]		= 512,
+			   [3 ... 4]	= -1,
+			   [5 ... 6]	= 1024,
+			   [7 ... 8]	= 2048,
+			   [9 ... 10]	= 4096,
+			   [11]	= 8192,
 };
 
 /*
@@ -164,18 +188,16 @@ static int amd64_get_scrub_rate(struct m
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 	u32 scrubval = 0;
-	int status = -1, i, ret = 0;
+	int status = -1, i;
 
-	ret = pci_read_config_dword(pvt->misc_f3_ctl, K8_SCRCTRL, &scrubval);
-	if (ret)
-		debugf0("Reading K8_SCRCTRL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_SCRCTRL, &scrubval);
 
 	scrubval = scrubval & 0x001F;
 
 	edac_printk(KERN_DEBUG, EDAC_MC,
 		    "pci-read, sdram scrub control value: %d \n", scrubval);
 
-	for (i = 0; ARRAY_SIZE(scrubrates); i++) {
+	for (i = 0; i < ARRAY_SIZE(scrubrates); i++) {
 		if (scrubrates[i].scrubval == scrubval) {
 			*bw = scrubrates[i].bandwidth;
 			status = 0;
@@ -189,7 +211,7 @@ static int amd64_get_scrub_rate(struct m
 /* Map from a CSROW entry to the mask entry that operates on it */
 static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
 {
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F)
 		return csrow;
 	else
 		return csrow >> 1;
@@ -437,7 +459,7 @@ int amd64_get_dram_hole_info(struct mem_
 	u64 base;
 
 	/* only revE and later have the DRAM Hole Address Register */
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_E) {
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_E) {
 		debugf1("  revision %d for node %d does not support DHAR\n",
 			pvt->ext_model, pvt->mc_node_id);
 		return 1;
@@ -743,21 +765,6 @@ static void find_csrow_limits(struct mem
 	*input_addr_max = base | mask | pvt->dcs_mask_notused;
 }
 
-/*
- * Extract error address from MCA NB Address Low (section 3.6.4.5) and MCA NB
- * Address High (section 3.6.4.6) register values and return the result. Address
- * is located in the info structure (nbeah and nbeal), the encoding is device
- * specific.
- */
-static u64 extract_error_address(struct mem_ctl_info *mci,
-				 struct err_regs *info)
-{
-	struct amd64_pvt *pvt = mci->pvt_info;
-
-	return pvt->ops->get_error_address(mci, info);
-}
-
-
 /* Map the Error address to a PAGE and PAGE OFFSET. */
 static inline void error_address_to_page_and_offset(u64 error_address,
 						    u32 *page, u32 *offset)
@@ -787,7 +794,7 @@ static int sys_addr_to_csrow(struct mem_
 	return csrow;
 }
 
-static int get_channel_from_ecc_syndrome(unsigned short syndrome);
+static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
 
 static void amd64_cpu_display_info(struct amd64_pvt *pvt)
 {
@@ -797,7 +804,7 @@ static void amd64_cpu_display_info(struc
 		edac_printk(KERN_DEBUG, EDAC_MC, "F10h CPU detected\n");
 	else if (boot_cpu_data.x86 == 0xf)
 		edac_printk(KERN_DEBUG, EDAC_MC, "%s detected\n",
-			(pvt->ext_model >= OPTERON_CPU_REV_F) ?
+			(pvt->ext_model >= K8_REV_F) ?
 			"Rev F or later" : "Rev E or earlier");
 	else
 		/* we'll hardly ever ever get here */
@@ -813,7 +820,7 @@ static enum edac_type amd64_determine_ed
 	int bit;
 	enum dev_type edac_cap = EDAC_FLAG_NONE;
 
-	bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F)
+	bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F)
 		? 19
 		: 17;
 
@@ -824,111 +831,86 @@ static enum edac_type amd64_determine_ed
 }
 
 
-static void f10_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt,
-					 int ganged);
+static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt);
+
+static void amd64_dump_dramcfg_low(u32 dclr, int chan)
+{
+	debugf1("F2x%d90 (DRAM Cfg Low): 0x%08x\n", chan, dclr);
+
+	debugf1("  DIMM type: %sbuffered; all DIMMs support ECC: %s\n",
+		(dclr & BIT(16)) ?  "un" : "",
+		(dclr & BIT(19)) ? "yes" : "no");
+
+	debugf1("  PAR/ERR parity: %s\n",
+		(dclr & BIT(8)) ?  "enabled" : "disabled");
+
+	debugf1("  DCT 128bit mode width: %s\n",
+		(dclr & BIT(11)) ?  "128b" : "64b");
+
+	debugf1("  x4 logical DIMMs present: L0: %s L1: %s L2: %s L3: %s\n",
+		(dclr & BIT(12)) ?  "yes" : "no",
+		(dclr & BIT(13)) ?  "yes" : "no",
+		(dclr & BIT(14)) ?  "yes" : "no",
+		(dclr & BIT(15)) ?  "yes" : "no");
+}
 
 /* Display and decode various NB registers for debug purposes. */
 static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
 {
 	int ganged;
 
-	debugf1("  nbcap:0x%8.08x DctDualCap=%s DualNode=%s 8-Node=%s\n",
-		pvt->nbcap,
-		(pvt->nbcap & K8_NBCAP_DCT_DUAL) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_DUAL_NODE) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_8_NODE) ? "True" : "False");
-	debugf1("    ECC Capable=%s   ChipKill Capable=%s\n",
-		(pvt->nbcap & K8_NBCAP_SECDED) ? "True" : "False",
-		(pvt->nbcap & K8_NBCAP_CHIPKILL) ? "True" : "False");
-	debugf1("  DramCfg0-low=0x%08x DIMM-ECC=%s Parity=%s Width=%s\n",
-		pvt->dclr0,
-		(pvt->dclr0 & BIT(19)) ?  "Enabled" : "Disabled",
-		(pvt->dclr0 & BIT(8)) ?  "Enabled" : "Disabled",
-		(pvt->dclr0 & BIT(11)) ?  "128b" : "64b");
-	debugf1("    DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s  DIMM Type=%s\n",
-		(pvt->dclr0 & BIT(12)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(13)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(14)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(15)) ?  "Y" : "N",
-		(pvt->dclr0 & BIT(16)) ?  "UN-Buffered" : "Buffered");
+	debugf1("F3xE8 (NB Cap): 0x%08x\n", pvt->nbcap);
 
+	debugf1("  NB two channel DRAM capable: %s\n",
+		(pvt->nbcap & K8_NBCAP_DCT_DUAL) ? "yes" : "no");
 
-	debugf1("  online-spare: 0x%8.08x\n", pvt->online_spare);
+	debugf1("  ECC capable: %s, ChipKill ECC capable: %s\n",
+		(pvt->nbcap & K8_NBCAP_SECDED) ? "yes" : "no",
+		(pvt->nbcap & K8_NBCAP_CHIPKILL) ? "yes" : "no");
 
-	if (boot_cpu_data.x86 == 0xf) {
-		debugf1("  dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
-			pvt->dhar, dhar_base(pvt->dhar),
-			k8_dhar_offset(pvt->dhar));
-		debugf1("      DramHoleValid=%s\n",
-			(pvt->dhar & DHAR_VALID) ?  "True" : "False");
+	amd64_dump_dramcfg_low(pvt->dclr0, 0);
 
-		debugf1("  dbam-dkt: 0x%8.08x\n", pvt->dbam0);
+	debugf1("F3xB0 (Online Spare): 0x%08x\n", pvt->online_spare);
 
-		/* everything below this point is Fam10h and above */
-		return;
+	debugf1("F1xF0 (DRAM Hole Address): 0x%08x, base: 0x%08x, "
+			"offset: 0x%08x\n",
+			pvt->dhar,
+			dhar_base(pvt->dhar),
+			(boot_cpu_data.x86 == 0xf) ? k8_dhar_offset(pvt->dhar)
+						   : f10_dhar_offset(pvt->dhar));
 
-	} else {
-		debugf1("  dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
-			pvt->dhar, dhar_base(pvt->dhar),
-			f10_dhar_offset(pvt->dhar));
-		debugf1("    DramMemHoistValid=%s DramHoleValid=%s\n",
-			(pvt->dhar & F10_DRAM_MEM_HOIST_VALID) ?
-			"True" : "False",
-			(pvt->dhar & DHAR_VALID) ?
-			"True" : "False");
-	}
+	debugf1("  DramHoleValid: %s\n",
+		(pvt->dhar & DHAR_VALID) ? "yes" : "no");
 
-	/* Only if NOT ganged does dcl1 have valid info */
-	if (!dct_ganging_enabled(pvt)) {
-		debugf1("  DramCfg1-low=0x%08x DIMM-ECC=%s Parity=%s "
-			"Width=%s\n", pvt->dclr1,
-			(pvt->dclr1 & BIT(19)) ?  "Enabled" : "Disabled",
-			(pvt->dclr1 & BIT(8)) ?  "Enabled" : "Disabled",
-			(pvt->dclr1 & BIT(11)) ?  "128b" : "64b");
-		debugf1("    DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s  "
-			"DIMM Type=%s\n",
-			(pvt->dclr1 & BIT(12)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(13)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(14)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(15)) ?  "Y" : "N",
-			(pvt->dclr1 & BIT(16)) ?  "UN-Buffered" : "Buffered");
+	/* everything below this point is Fam10h and above */
+	if (boot_cpu_data.x86 == 0xf) {
+		amd64_debug_display_dimm_sizes(0, pvt);
+		return;
 	}
 
+	/* Only if NOT ganged does dclr1 have valid info */
+	if (!dct_ganging_enabled(pvt))
+		amd64_dump_dramcfg_low(pvt->dclr1, 1);
+
 	/*
 	 * Determine if ganged and then dump memory sizes for first controller,
 	 * and if NOT ganged dump info for 2nd controller.
 	 */
 	ganged = dct_ganging_enabled(pvt);
 
-	f10_debug_display_dimm_sizes(0, pvt, ganged);
+	amd64_debug_display_dimm_sizes(0, pvt);
 
 	if (!ganged)
-		f10_debug_display_dimm_sizes(1, pvt, ganged);
+		amd64_debug_display_dimm_sizes(1, pvt);
 }
 
 /* Read in both of DBAM registers */
 static void amd64_read_dbam_reg(struct amd64_pvt *pvt)
 {
-	int err = 0;
-	unsigned int reg;
-
-	reg = DBAM0;
-	err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam0);
-	if (err)
-		goto err_reg;
-
-	if (boot_cpu_data.x86 >= 0x10) {
-		reg = DBAM1;
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam1);
-
-		if (err)
-			goto err_reg;
-	}
-
-	return;
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, DBAM0, &pvt->dbam0);
 
-err_reg:
-	debugf0("Error reading F2x%03x.\n", reg);
+	if (boot_cpu_data.x86 >= 0x10)
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, DBAM1, &pvt->dbam1);
 }
 
 /*
@@ -963,7 +945,7 @@ err_reg:
 static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
 {
 
-	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F) {
 		pvt->dcsb_base		= REV_E_DCSB_BASE_BITS;
 		pvt->dcsm_mask		= REV_E_DCSM_MASK_BITS;
 		pvt->dcs_mask_notused	= REV_E_DCS_NOTUSED_BITS;
@@ -991,28 +973,21 @@ static void amd64_set_dct_base_and_mask(
  */
 static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
 {
-	int cs, reg, err = 0;
+	int cs, reg;
 
 	amd64_set_dct_base_and_mask(pvt);
 
 	for (cs = 0; cs < pvt->cs_count; cs++) {
 		reg = K8_DCSB0 + (cs * 4);
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-						&pvt->dcsb0[cs]);
-		if (unlikely(err))
-			debugf0("Reading K8_DCSB0[%d] failed\n", cs);
-		else
+		if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg, &pvt->dcsb0[cs]))
 			debugf0("  DCSB0[%d]=0x%08x reg: F2x%x\n",
 				cs, pvt->dcsb0[cs], reg);
 
 		/* If DCT are NOT ganged, then read in DCT1's base */
 		if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) {
 			reg = F10_DCSB1 + (cs * 4);
-			err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-							&pvt->dcsb1[cs]);
-			if (unlikely(err))
-				debugf0("Reading F10_DCSB1[%d] failed\n", cs);
-			else
+			if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg,
+						&pvt->dcsb1[cs]))
 				debugf0("  DCSB1[%d]=0x%08x reg: F2x%x\n",
 					cs, pvt->dcsb1[cs], reg);
 		} else {
@@ -1022,26 +997,20 @@ static void amd64_read_dct_base_mask(str
 
 	for (cs = 0; cs < pvt->num_dcsm; cs++) {
 		reg = K8_DCSM0 + (cs * 4);
-		err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-					&pvt->dcsm0[cs]);
-		if (unlikely(err))
-			debugf0("Reading K8_DCSM0 failed\n");
-		else
+		if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg, &pvt->dcsm0[cs]))
 			debugf0("    DCSM0[%d]=0x%08x reg: F2x%x\n",
 				cs, pvt->dcsm0[cs], reg);
 
 		/* If DCT are NOT ganged, then read in DCT1's mask */
 		if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) {
 			reg = F10_DCSM1 + (cs * 4);
-			err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
-					&pvt->dcsm1[cs]);
-			if (unlikely(err))
-				debugf0("Reading F10_DCSM1[%d] failed\n", cs);
-			else
+			if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, reg,
+						&pvt->dcsm1[cs]))
 				debugf0("    DCSM1[%d]=0x%08x reg: F2x%x\n",
 					cs, pvt->dcsm1[cs], reg);
-		} else
+		} else {
 			pvt->dcsm1[cs] = 0;
+		}
 	}
 }
 
@@ -1049,18 +1018,16 @@ static enum mem_type amd64_determine_mem
 {
 	enum mem_type type;
 
-	if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= OPTERON_CPU_REV_F) {
-		/* Rev F and later */
-		type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2;
+	if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= K8_REV_F) {
+		if (pvt->dchr0 & DDR3_MODE)
+			type = (pvt->dclr0 & BIT(16)) ?	MEM_DDR3 : MEM_RDDR3;
+		else
+			type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2;
 	} else {
-		/* Rev E and earlier */
 		type = (pvt->dclr0 & BIT(18)) ? MEM_DDR : MEM_RDDR;
 	}
 
-	debugf1("  Memory type is: %s\n",
-		(type == MEM_DDR2) ? "MEM_DDR2" :
-		(type == MEM_RDDR2) ? "MEM_RDDR2" :
-		(type == MEM_DDR) ? "MEM_DDR" : "MEM_RDDR");
+	debugf1("  Memory type is: %s\n", edac_mem_types[type]);
 
 	return type;
 }
@@ -1078,11 +1045,11 @@ static int k8_early_channel_count(struct
 {
 	int flag, err = 0;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
+	err = amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
 	if (err)
 		return err;
 
-	if ((boot_cpu_data.x86_model >> 4) >= OPTERON_CPU_REV_F) {
+	if ((boot_cpu_data.x86_model >> 4) >= K8_REV_F) {
 		/* RevF (NPT) and later */
 		flag = pvt->dclr0 & F10_WIDTH_128;
 	} else {
@@ -1114,22 +1081,15 @@ static void k8_read_dram_base_limit(stru
 {
 	u32 low;
 	u32 off = dram << 3;	/* 8 bytes between DRAM entries */
-	int err;
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl,
-				    K8_DRAM_BASE_LOW + off, &low);
-	if (err)
-		debugf0("Reading K8_DRAM_BASE_LOW failed\n");
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DRAM_BASE_LOW + off, &low);
 
 	/* Extract parts into separate data entries */
 	pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
 	pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
 	pvt->dram_rw_en[dram] = (low & 0x3);
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl,
-				    K8_DRAM_LIMIT_LOW + off, &low);
-	if (err)
-		debugf0("Reading K8_DRAM_LIMIT_LOW failed\n");
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DRAM_LIMIT_LOW + off, &low);
 
 	/*
 	 * Extract parts into separate data entries. Limit is the HIGHEST memory
@@ -1142,7 +1102,7 @@ static void k8_read_dram_base_limit(stru
 
 static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 					struct err_regs *info,
-					u64 SystemAddress)
+					u64 sys_addr)
 {
 	struct mem_ctl_info *src_mci;
 	unsigned short syndrome;
@@ -1155,7 +1115,7 @@ static void k8_map_sysaddr_to_csrow(stru
 
 	/* CHIPKILL enabled */
 	if (info->nbcfg & K8_NBCFG_CHIPKILL) {
-		channel = get_channel_from_ecc_syndrome(syndrome);
+		channel = get_channel_from_ecc_syndrome(mci, syndrome);
 		if (channel < 0) {
 			/*
 			 * Syndrome didn't map, so we don't know which of the
@@ -1177,64 +1137,46 @@ static void k8_map_sysaddr_to_csrow(stru
 		 * was obtained from email communication with someone at AMD.
 		 * (Wish the email was placed in this comment - norsk)
 		 */
-		channel = ((SystemAddress & BIT(3)) != 0);
+		channel = ((sys_addr & BIT(3)) != 0);
 	}
 
 	/*
 	 * Find out which node the error address belongs to. This may be
 	 * different from the node that detected the error.
 	 */
-	src_mci = find_mc_by_sys_addr(mci, SystemAddress);
+	src_mci = find_mc_by_sys_addr(mci, sys_addr);
 	if (!src_mci) {
 		amd64_mc_printk(mci, KERN_ERR,
 			     "failed to map error address 0x%lx to a node\n",
-			     (unsigned long)SystemAddress);
+			     (unsigned long)sys_addr);
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
 		return;
 	}
 
-	/* Now map the SystemAddress to a CSROW */
-	csrow = sys_addr_to_csrow(src_mci, SystemAddress);
+	/* Now map the sys_addr to a CSROW */
+	csrow = sys_addr_to_csrow(src_mci, sys_addr);
 	if (csrow < 0) {
 		edac_mc_handle_ce_no_info(src_mci, EDAC_MOD_STR);
 	} else {
-		error_address_to_page_and_offset(SystemAddress, &page, &offset);
+		error_address_to_page_and_offset(sys_addr, &page, &offset);
 
 		edac_mc_handle_ce(src_mci, page, offset, syndrome, csrow,
 				  channel, EDAC_MOD_STR);
 	}
 }
 
-/*
- * determrine the number of PAGES in for this DIMM's size based on its DRAM
- * Address Mapping.
- *
- * First step is to calc the number of bits to shift a value of 1 left to
- * indicate show many pages. Start with the DBAM value as the starting bits,
- * then proceed to adjust those shift bits, based on CPU rev and the table.
- * See BKDG on the DBAM
- */
-static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
+static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
 {
-	int nr_pages;
-
-	if (pvt->ext_model >= OPTERON_CPU_REV_F) {
-		nr_pages = 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
-	} else {
-		/*
-		 * RevE and less section; this line is tricky. It collapses the
-		 * table used by RevD and later to one that matches revisions CG
-		 * and earlier.
-		 */
-		dram_map -= (pvt->ext_model >= OPTERON_CPU_REV_D) ?
-				(dram_map > 8 ? 4 : (dram_map > 5 ?
-				3 : (dram_map > 2 ? 1 : 0))) : 0;
+	int *dbam_map;
 
-		/* 25 shift is 32MiB minimum DIMM size in RevE and prior */
-		nr_pages = 1 << (dram_map + 25 - PAGE_SHIFT);
-	}
+	if (pvt->ext_model >= K8_REV_F)
+		dbam_map = ddr2_dbam;
+	else if (pvt->ext_model >= K8_REV_D)
+		dbam_map = ddr2_dbam_revD;
+	else
+		dbam_map = ddr2_dbam_revCG;
 
-	return nr_pages;
+	return dbam_map[cs_mode];
 }
 
 /*
@@ -1248,34 +1190,24 @@ static int k8_dbam_map_to_pages(struct a
 static int f10_early_channel_count(struct amd64_pvt *pvt)
 {
 	int dbams[] = { DBAM0, DBAM1 };
-	int err = 0, channels = 0;
-	int i, j;
+	int i, j, channels = 0;
 	u32 dbam;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
-	if (err)
-		goto err_reg;
-
 	/* If we are in 128 bit mode, then we are using 2 channels */
 	if (pvt->dclr0 & F10_WIDTH_128) {
-		debugf0("Data WIDTH is 128 bits - 2 channels\n");
 		channels = 2;
 		return channels;
 	}
 
 	/*
-	 * Need to check if in UN-ganged mode: In such, there are 2 channels,
-	 * but they are NOT in 128 bit mode and thus the above 'dcl0' status bit
-	 * will be OFF.
+	 * Need to check if in unganged mode: In such, there are 2 channels,
+	 * but they are not in 128 bit mode and thus the above 'dclr0' status
+	 * bit will be OFF.
 	 *
 	 * Need to check DCT0[0] and DCT1[0] to see if only one of them has
 	 * their CSEnable bit on. If so, then SINGLE DIMM case.
 	 */
-	debugf0("Data WIDTH is NOT 128 bits - need more decoding\n");
+	debugf0("Data width is not 128 bits - need more decoding\n");
 
 	/*
 	 * Check DRAM Bank Address Mapping values for each DIMM to see if there
@@ -1283,8 +1215,7 @@ static int f10_early_channel_count(struc
 	 * both controllers since DIMMs can be placed in either one.
 	 */
 	for (i = 0; i < ARRAY_SIZE(dbams); i++) {
-		err = pci_read_config_dword(pvt->dram_f2_ctl, dbams[i], &dbam);
-		if (err)
+		if (amd64_read_pci_cfg(pvt->dram_f2_ctl, dbams[i], &dbam))
 			goto err_reg;
 
 		for (j = 0; j < 4; j++) {
@@ -1295,6 +1226,9 @@ static int f10_early_channel_count(struc
 		}
 	}
 
+	if (channels > 2)
+		channels = 2;
+
 	debugf0("MCT channel count: %d\n", channels);
 
 	return channels;
@@ -1304,9 +1238,16 @@ err_reg:
 
 }
 
-static int f10_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
+static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
 {
-	return 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
+	int *dbam_map;
+
+	if (pvt->dchr0 & DDR3_MODE || pvt->dchr1 & DDR3_MODE)
+		dbam_map = ddr3_dbam;
+	else
+		dbam_map = ddr2_dbam;
+
+	return dbam_map[cs_mode];
 }
 
 /* Enable extended configuration access via 0xCF8 feature */
@@ -1314,7 +1255,7 @@ static void amd64_setup(struct amd64_pvt
 {
 	u32 reg;
 
-	pci_read_config_dword(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
 
 	pvt->flags.cf8_extcfg = !!(reg & F10_NB_CFG_LOW_ENABLE_EXT_CFG);
 	reg |= F10_NB_CFG_LOW_ENABLE_EXT_CFG;
@@ -1326,7 +1267,7 @@ static void amd64_teardown(struct amd64_
 {
 	u32 reg;
 
-	pci_read_config_dword(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, F10_NB_CFG_HIGH, &reg);
 
 	reg &= ~F10_NB_CFG_LOW_ENABLE_EXT_CFG;
 	if (pvt->flags.cf8_extcfg)
@@ -1355,10 +1296,10 @@ static void f10_read_dram_base_limit(str
 	high_offset = F10_DRAM_BASE_HIGH + (dram << 3);
 
 	/* read the 'raw' DRAM BASE Address register */
-	pci_read_config_dword(pvt->addr_f1_ctl, low_offset, &low_base);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, low_offset, &low_base);
 
 	/* Read from the ECS data register */
-	pci_read_config_dword(pvt->addr_f1_ctl, high_offset, &high_base);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, high_offset, &high_base);
 
 	/* Extract parts into separate data entries */
 	pvt->dram_rw_en[dram] = (low_base & 0x3);
@@ -1375,13 +1316,10 @@ static void f10_read_dram_base_limit(str
 	high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
 
 	/* read the 'raw' LIMIT registers */
-	pci_read_config_dword(pvt->addr_f1_ctl, low_offset, &low_limit);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, low_offset, &low_limit);
 
 	/* Read from the ECS data register for the HIGH portion */
-	pci_read_config_dword(pvt->addr_f1_ctl, high_offset, &high_limit);
-
-	debugf0("  HW Regs: BASE=0x%08x-%08x      LIMIT=  0x%08x-%08x\n",
-		high_base, low_base, high_limit, low_limit);
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, high_offset, &high_limit);
 
 	pvt->dram_DstNode[dram] = (low_limit & 0x7);
 	pvt->dram_IntlvSel[dram] = (low_limit >> 8) & 0x7;
@@ -1397,32 +1335,35 @@ static void f10_read_dram_base_limit(str
 
 static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
 {
-	int err = 0;
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCTL_SEL_LOW,
-				    &pvt->dram_ctl_select_low);
-	if (err) {
-		debugf0("Reading F10_DCTL_SEL_LOW failed\n");
-	} else {
-		debugf0("DRAM_DCTL_SEL_LOW=0x%x  DctSelBaseAddr=0x%x\n",
-			pvt->dram_ctl_select_low, dct_sel_baseaddr(pvt));
+	if (!amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCTL_SEL_LOW,
+				&pvt->dram_ctl_select_low)) {
+		debugf0("F2x110 (DCTL Sel. Low): 0x%08x, "
+			"High range addresses at: 0x%x\n",
+			pvt->dram_ctl_select_low,
+			dct_sel_baseaddr(pvt));
 
-		debugf0("  DRAM DCTs are=%s DRAM Is=%s DRAM-Ctl-"
-				"sel-hi-range=%s\n",
-			(dct_ganging_enabled(pvt) ? "GANGED" : "NOT GANGED"),
-			(dct_dram_enabled(pvt) ? "Enabled"   : "Disabled"),
-			(dct_high_range_enabled(pvt) ? "Enabled" : "Disabled"));
+		debugf0("  DCT mode: %s, All DCTs on: %s\n",
+			(dct_ganging_enabled(pvt) ? "ganged" : "unganged"),
+			(dct_dram_enabled(pvt) ? "yes"   : "no"));
 
-		debugf0("  DctDatIntLv=%s MemCleared=%s DctSelIntLvAddr=0x%x\n",
-			(dct_data_intlv_enabled(pvt) ? "Enabled" : "Disabled"),
-			(dct_memory_cleared(pvt) ? "True " : "False "),
+		if (!dct_ganging_enabled(pvt))
+			debugf0("  Address range split per DCT: %s\n",
+				(dct_high_range_enabled(pvt) ? "yes" : "no"));
+
+		debugf0("  DCT data interleave for ECC: %s, "
+			"DRAM cleared since last warm reset: %s\n",
+			(dct_data_intlv_enabled(pvt) ? "enabled" : "disabled"),
+			(dct_memory_cleared(pvt) ? "yes" : "no"));
+
+		debugf0("  DCT channel interleave: %s, "
+			"DCT interleave bits selector: 0x%x\n",
+			(dct_interleave_enabled(pvt) ? "enabled" : "disabled"),
 			dct_sel_interleave_addr(pvt));
 	}
 
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCTL_SEL_HIGH,
-				    &pvt->dram_ctl_select_high);
-	if (err)
-		debugf0("Reading F10_DCTL_SEL_HIGH failed\n");
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCTL_SEL_HIGH,
+			   &pvt->dram_ctl_select_high);
 }
 
 /*
@@ -1706,10 +1647,11 @@ static int f10_translate_sysaddr_to_cs(s
 }
 
 /*
- * This the F10h reference code from AMD to map a @sys_addr to NodeID,
- * CSROW, Channel.
+ * For reference see "2.8.5 Routing DRAM Requests" in F10 BKDG. This code maps
+ * a @sys_addr to NodeID, DCT (channel) and chip select (CSROW).
  *
- * The @sys_addr is usually an error address received from the hardware.
+ * The @sys_addr is usually an error address received from the hardware
+ * (MCX_ADDR).
  */
 static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 				     struct err_regs *info,
@@ -1722,133 +1664,80 @@ static void f10_map_sysaddr_to_csrow(str
 
 	csrow = f10_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan);
 
-	if (csrow >= 0) {
-		error_address_to_page_and_offset(sys_addr, &page, &offset);
-
-		syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
-		syndrome |= LOW_SYNDROME(info->nbsh);
-
-		/*
-		 * Is CHIPKILL on? If so, then we can attempt to use the
-		 * syndrome to isolate which channel the error was on.
-		 */
-		if (pvt->nbcfg & K8_NBCFG_CHIPKILL)
-			chan = get_channel_from_ecc_syndrome(syndrome);
-
-		if (chan >= 0) {
-			edac_mc_handle_ce(mci, page, offset, syndrome,
-					csrow, chan, EDAC_MOD_STR);
-		} else {
-			/*
-			 * Channel unknown, report all channels on this
-			 * CSROW as failed.
-			 */
-			for (chan = 0; chan < mci->csrows[csrow].nr_channels;
-								chan++) {
-					edac_mc_handle_ce(mci, page, offset,
-							syndrome,
-							csrow, chan,
-							EDAC_MOD_STR);
-			}
-		}
-
-	} else {
+	if (csrow < 0) {
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR);
+		return;
 	}
-}
 
-/*
- * Input (@index) is the DBAM DIMM value (1 of 4) used as an index into a shift
- * table (revf_quad_ddr2_shift) which starts at 128MB DIMM size. Index of 0
- * indicates an empty DIMM slot, as reported by Hardware on empty slots.
- *
- * Normalize to 128MB by subracting 27 bit shift.
- */
-static int map_dbam_to_csrow_size(int index)
-{
-	int mega_bytes = 0;
+	error_address_to_page_and_offset(sys_addr, &page, &offset);
 
-	if (index > 0 && index <= DBAM_MAX_VALUE)
-		mega_bytes = ((128 << (revf_quad_ddr2_shift[index]-27)));
+	syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+	syndrome |= LOW_SYNDROME(info->nbsh);
 
-	return mega_bytes;
+	/*
+	 * We need the syndromes for channel detection only when we're
+	 * ganged. Otherwise @chan should already contain the channel at
+	 * this point.
+	 */
+	if (dct_ganging_enabled(pvt) && pvt->nbcfg & K8_NBCFG_CHIPKILL)
+		chan = get_channel_from_ecc_syndrome(mci, syndrome);
+
+	if (chan >= 0)
+		edac_mc_handle_ce(mci, page, offset, syndrome, csrow, chan,
+				  EDAC_MOD_STR);
+	else
+		/*
+		 * Channel unknown, report all channels on this CSROW as failed.
+		 */
+		for (chan = 0; chan < mci->csrows[csrow].nr_channels; chan++)
+			edac_mc_handle_ce(mci, page, offset, syndrome,
+					  csrow, chan, EDAC_MOD_STR);
 }
 
 /*
- * debug routine to display the memory sizes of a DIMM (ganged or not) and it
+ * debug routine to display the memory sizes of all logical DIMMs and its
  * CSROWs as well
  */
-static void f10_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt,
-					 int ganged)
+static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)
 {
-	int dimm, size0, size1;
+	int dimm, size0, size1, factor = 0;
 	u32 dbam;
 	u32 *dcsb;
 
-	debugf1("  dbam%d: 0x%8.08x  CSROW is %s\n", ctrl,
-			ctrl ? pvt->dbam1 : pvt->dbam0,
-			ganged ? "GANGED - dbam1 not used" : "NON-GANGED");
+	if (boot_cpu_data.x86 == 0xf) {
+		if (pvt->dclr0 & F10_WIDTH_128)
+			factor = 1;
+
+		/* K8 families < revF not supported yet */
+	       if (pvt->ext_model < K8_REV_F)
+			return;
+	       else
+		       WARN_ON(ctrl != 0);
+	}
+
+	debugf1("F2x%d80 (DRAM Bank Address Mapping): 0x%08x\n",
+		ctrl, ctrl ? pvt->dbam1 : pvt->dbam0);
 
 	dbam = ctrl ? pvt->dbam1 : pvt->dbam0;
 	dcsb = ctrl ? pvt->dcsb1 : pvt->dcsb0;
 
+	edac_printk(KERN_DEBUG, EDAC_MC, "DCT%d chip selects:\n", ctrl);
+
 	/* Dump memory sizes for DIMM and its CSROWs */
 	for (dimm = 0; dimm < 4; dimm++) {
 
 		size0 = 0;
 		if (dcsb[dimm*2] & K8_DCSB_CS_ENABLE)
-			size0 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
+			size0 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
 
 		size1 = 0;
 		if (dcsb[dimm*2 + 1] & K8_DCSB_CS_ENABLE)
-			size1 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
-
-		debugf1("     CTRL-%d DIMM-%d=%5dMB   CSROW-%d=%5dMB "
-				"CSROW-%d=%5dMB\n",
-				ctrl,
-				dimm,
-				size0 + size1,
-				dimm * 2,
-				size0,
-				dimm * 2 + 1,
-				size1);
-	}
-}
-
-/*
- * Very early hardware probe on pci_probe thread to determine if this module
- * supports the hardware.
- *
- * Return:
- *      0 for OK
- *      1 for error
- */
-static int f10_probe_valid_hardware(struct amd64_pvt *pvt)
-{
-	int ret = 0;
-
-	/*
-	 * If we are on a DDR3 machine, we don't know yet if
-	 * we support that properly at this time
-	 */
-	if ((pvt->dchr0 & F10_DCHR_Ddr3Mode) ||
-	    (pvt->dchr1 & F10_DCHR_Ddr3Mode)) {
-
-		amd64_printk(KERN_WARNING,
-			"%s() This machine is running with DDR3 memory. "
-			"This is not currently supported. "
-			"DCHR0=0x%x DCHR1=0x%x\n",
-			__func__, pvt->dchr0, pvt->dchr1);
-
-		amd64_printk(KERN_WARNING,
-			"   Contact '%s' module MAINTAINER to help add"
-			" support.\n",
-			EDAC_MOD_STR);
-
-		ret = 1;
+			size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));
 
+		edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n",
+			    dimm * 2,     size0 << factor,
+			    dimm * 2 + 1, size1 << factor);
 	}
-	return ret;
 }
 
 /*
@@ -1868,11 +1757,11 @@ static struct amd64_family_type amd64_fa
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_K8_NB_MISC,
 		.ops = {
-			.early_channel_count = k8_early_channel_count,
-			.get_error_address = k8_get_error_address,
-			.read_dram_base_limit = k8_read_dram_base_limit,
-			.map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = k8_dbam_map_to_pages,
+			.early_channel_count	= k8_early_channel_count,
+			.get_error_address	= k8_get_error_address,
+			.read_dram_base_limit	= k8_read_dram_base_limit,
+			.map_sysaddr_to_csrow	= k8_map_sysaddr_to_csrow,
+			.dbam_to_cs		= k8_dbam_to_chip_select,
 		}
 	},
 	[F10_CPUS] = {
@@ -1880,13 +1769,12 @@ static struct amd64_family_type amd64_fa
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_10H_NB_MAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_10H_NB_MISC,
 		.ops = {
-			.probe_valid_hardware = f10_probe_valid_hardware,
-			.early_channel_count = f10_early_channel_count,
-			.get_error_address = f10_get_error_address,
-			.read_dram_base_limit = f10_read_dram_base_limit,
-			.read_dram_ctl_register = f10_read_dram_ctl_register,
-			.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = f10_dbam_map_to_pages,
+			.early_channel_count	= f10_early_channel_count,
+			.get_error_address	= f10_get_error_address,
+			.read_dram_base_limit	= f10_read_dram_base_limit,
+			.read_dram_ctl_register	= f10_read_dram_ctl_register,
+			.map_sysaddr_to_csrow	= f10_map_sysaddr_to_csrow,
+			.dbam_to_cs		= f10_dbam_to_chip_select,
 		}
 	},
 	[F11_CPUS] = {
@@ -1894,13 +1782,12 @@ static struct amd64_family_type amd64_fa
 		.addr_f1_ctl = PCI_DEVICE_ID_AMD_11H_NB_MAP,
 		.misc_f3_ctl = PCI_DEVICE_ID_AMD_11H_NB_MISC,
 		.ops = {
-			.probe_valid_hardware = f10_probe_valid_hardware,
-			.early_channel_count = f10_early_channel_count,
-			.get_error_address = f10_get_error_address,
-			.read_dram_base_limit = f10_read_dram_base_limit,
-			.read_dram_ctl_register = f10_read_dram_ctl_register,
-			.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
-			.dbam_map_to_pages = f10_dbam_map_to_pages,
+			.early_channel_count	= f10_early_channel_count,
+			.get_error_address	= f10_get_error_address,
+			.read_dram_base_limit	= f10_read_dram_base_limit,
+			.read_dram_ctl_register	= f10_read_dram_ctl_register,
+			.map_sysaddr_to_csrow	= f10_map_sysaddr_to_csrow,
+			.dbam_to_cs		= f10_dbam_to_chip_select,
 		}
 	},
 };
@@ -1923,142 +1810,170 @@ static struct pci_dev *pci_get_related_f
 }
 
 /*
- * syndrome mapping table for ECC ChipKill devices
- *
- * The comment in each row is the token (nibble) number that is in error.
- * The least significant nibble of the syndrome is the mask for the bits
- * that are in error (need to be toggled) for the particular nibble.
- *
- * Each row contains 16 entries.
- * The first entry (0th) is the channel number for that row of syndromes.
- * The remaining 15 entries are the syndromes for the respective Error
- * bit mask index.
- *
- * 1st index entry is 0x0001 mask, indicating that the rightmost bit is the
- * bit in error.
- * The 2nd index entry is 0x0010 that the second bit is damaged.
- * The 3rd index entry is 0x0011 indicating that the rightmost 2 bits
- * are damaged.
- * Thus so on until index 15, 0x1111, whose entry has the syndrome
- * indicating that all 4 bits are damaged.
- *
- * A search is performed on this table looking for a given syndrome.
- *
- * See the AMD documentation for ECC syndromes. This ECC table is valid
- * across all the versions of the AMD64 processors.
- *
- * A fast lookup is to use the LAST four bits of the 16-bit syndrome as a
- * COLUMN index, then search all ROWS of that column, looking for a match
- * with the input syndrome. The ROW value will be the token number.
+ * These are tables of eigenvectors (one per line) which can be used for the
+ * construction of the syndrome tables. The modified syndrome search algorithm
+ * uses those to find the symbol in error and thus the DIMM.
  *
- * The 0'th entry on that row, can be returned as the CHANNEL (0 or 1) of this
- * error.
+ * Algorithm courtesy of Ross LaFetra from AMD.
  */
-#define NUMBER_ECC_ROWS  36
-static const unsigned short ecc_chipkill_syndromes[NUMBER_ECC_ROWS][16] = {
-	/* Channel 0 syndromes */
-	{/*0*/  0, 0xe821, 0x7c32, 0x9413, 0xbb44, 0x5365, 0xc776, 0x2f57,
-	   0xdd88, 0x35a9, 0xa1ba, 0x499b, 0x66cc, 0x8eed, 0x1afe, 0xf2df },
-	{/*1*/  0, 0x5d31, 0xa612, 0xfb23, 0x9584, 0xc8b5, 0x3396, 0x6ea7,
-	   0xeac8, 0xb7f9, 0x4cda, 0x11eb, 0x7f4c, 0x227d, 0xd95e, 0x846f },
-	{/*2*/  0, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-	   0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f },
-	{/*3*/  0, 0x2021, 0x3032, 0x1013, 0x4044, 0x6065, 0x7076, 0x5057,
-	   0x8088, 0xa0a9, 0xb0ba, 0x909b, 0xc0cc, 0xe0ed, 0xf0fe, 0xd0df },
-	{/*4*/  0, 0x5041, 0xa082, 0xf0c3, 0x9054, 0xc015, 0x30d6, 0x6097,
-	   0xe0a8, 0xb0e9, 0x402a, 0x106b, 0x70fc, 0x20bd, 0xd07e, 0x803f },
-	{/*5*/  0, 0xbe21, 0xd732, 0x6913, 0x2144, 0x9f65, 0xf676, 0x4857,
-	   0x3288, 0x8ca9, 0xe5ba, 0x5b9b, 0x13cc, 0xaded, 0xc4fe, 0x7adf },
-	{/*6*/  0, 0x4951, 0x8ea2, 0xc7f3, 0x5394, 0x1ac5, 0xdd36, 0x9467,
-	   0xa1e8, 0xe8b9, 0x2f4a, 0x661b, 0xf27c, 0xbb2d, 0x7cde, 0x358f },
-	{/*7*/  0, 0x74e1, 0x9872, 0xec93, 0xd6b4, 0xa255, 0x4ec6, 0x3a27,
-	   0x6bd8, 0x1f39, 0xf3aa, 0x874b, 0xbd6c, 0xc98d, 0x251e, 0x51ff },
-	{/*8*/  0, 0x15c1, 0x2a42, 0x3f83, 0xcef4, 0xdb35, 0xe4b6, 0xf177,
-	   0x4758, 0x5299, 0x6d1a, 0x78db, 0x89ac, 0x9c6d, 0xa3ee, 0xb62f },
-	{/*9*/  0, 0x3d01, 0x1602, 0x2b03, 0x8504, 0xb805, 0x9306, 0xae07,
-	   0xca08, 0xf709, 0xdc0a, 0xe10b, 0x4f0c, 0x720d, 0x590e, 0x640f },
-	{/*a*/  0, 0x9801, 0xec02, 0x7403, 0x6b04, 0xf305, 0x8706, 0x1f07,
-	   0xbd08, 0x2509, 0x510a, 0xc90b, 0xd60c, 0x4e0d, 0x3a0e, 0xa20f },
-	{/*b*/  0, 0xd131, 0x6212, 0xb323, 0x3884, 0xe9b5, 0x5a96, 0x8ba7,
-	   0x1cc8, 0xcdf9, 0x7eda, 0xafeb, 0x244c, 0xf57d, 0x465e, 0x976f },
-	{/*c*/  0, 0xe1d1, 0x7262, 0x93b3, 0xb834, 0x59e5, 0xca56, 0x2b87,
-	   0xdc18, 0x3dc9, 0xae7a, 0x4fab, 0x542c, 0x85fd, 0x164e, 0xf79f },
-	{/*d*/  0, 0x6051, 0xb0a2, 0xd0f3, 0x1094, 0x70c5, 0xa036, 0xc067,
-	   0x20e8, 0x40b9, 0x904a, 0x601b, 0x307c, 0x502d, 0x80de, 0xe08f },
-	{/*e*/  0, 0xa4c1, 0xf842, 0x5c83, 0xe6f4, 0x4235, 0x1eb6, 0xba77,
-	   0x7b58, 0xdf99, 0x831a, 0x27db, 0x9dac, 0x396d, 0x65ee, 0xc12f },
-	{/*f*/  0, 0x11c1, 0x2242, 0x3383, 0xc8f4, 0xd935, 0xeab6, 0xfb77,
-	   0x4c58, 0x5d99, 0x6e1a, 0x7fdb, 0x84ac, 0x956d, 0xa6ee, 0xb72f },
-
-	/* Channel 1 syndromes */
-	{/*10*/ 1, 0x45d1, 0x8a62, 0xcfb3, 0x5e34, 0x1be5, 0xd456, 0x9187,
-	   0xa718, 0xe2c9, 0x2d7a, 0x68ab, 0xf92c, 0xbcfd, 0x734e, 0x369f },
-	{/*11*/ 1, 0x63e1, 0xb172, 0xd293, 0x14b4, 0x7755, 0xa5c6, 0xc627,
-	   0x28d8, 0x4b39, 0x99aa, 0xfa4b, 0x3c6c, 0x5f8d, 0x8d1e, 0xeeff },
-	{/*12*/ 1, 0xb741, 0xd982, 0x6ec3, 0x2254, 0x9515, 0xfbd6, 0x4c97,
-	   0x33a8, 0x84e9, 0xea2a, 0x5d6b, 0x11fc, 0xa6bd, 0xc87e, 0x7f3f },
-	{/*13*/ 1, 0xdd41, 0x6682, 0xbbc3, 0x3554, 0xe815, 0x53d6, 0xce97,
-	   0x1aa8, 0xc7e9, 0x7c2a, 0xa1fb, 0x2ffc, 0xf2bd, 0x497e, 0x943f },
-	{/*14*/ 1, 0x2bd1, 0x3d62, 0x16b3, 0x4f34, 0x64e5, 0x7256, 0x5987,
-	   0x8518, 0xaec9, 0xb87a, 0x93ab, 0xca2c, 0xe1fd, 0xf74e, 0xdc9f },
-	{/*15*/ 1, 0x83c1, 0xc142, 0x4283, 0xa4f4, 0x2735, 0x65b6, 0xe677,
-	   0xf858, 0x7b99, 0x391a, 0xbadb, 0x5cac, 0xdf6d, 0x9dee, 0x1e2f },
-	{/*16*/ 1, 0x8fd1, 0xc562, 0x4ab3, 0xa934, 0x26e5, 0x6c56, 0xe387,
-	   0xfe18, 0x71c9, 0x3b7a, 0xb4ab, 0x572c, 0xd8fd, 0x924e, 0x1d9f },
-	{/*17*/ 1, 0x4791, 0x89e2, 0xce73, 0x5264, 0x15f5, 0xdb86, 0x9c17,
-	   0xa3b8, 0xe429, 0x2a5a, 0x6dcb, 0xf1dc, 0xb64d, 0x783e, 0x3faf },
-	{/*18*/ 1, 0x5781, 0xa9c2, 0xfe43, 0x92a4, 0xc525, 0x3b66, 0x6ce7,
-	   0xe3f8, 0xb479, 0x4a3a, 0x1dbb, 0x715c, 0x26dd, 0xd89e, 0x8f1f },
-	{/*19*/ 1, 0xbf41, 0xd582, 0x6ac3, 0x2954, 0x9615, 0xfcd6, 0x4397,
-	   0x3ea8, 0x81e9, 0xeb2a, 0x546b, 0x17fc, 0xa8bd, 0xc27e, 0x7d3f },
-	{/*1a*/ 1, 0x9891, 0xe1e2, 0x7273, 0x6464, 0xf7f5, 0x8586, 0x1617,
-	   0xb8b8, 0x2b29, 0x595a, 0xcacb, 0xdcdc, 0x4f4d, 0x3d3e, 0xaeaf },
-	{/*1b*/ 1, 0xcce1, 0x4472, 0x8893, 0xfdb4, 0x3f55, 0xb9c6, 0x7527,
-	   0x56d8, 0x9a39, 0x12aa, 0xde4b, 0xab6c, 0x678d, 0xef1e, 0x23ff },
-	{/*1c*/ 1, 0xa761, 0xf9b2, 0x5ed3, 0xe214, 0x4575, 0x1ba6, 0xbcc7,
-	   0x7328, 0xd449, 0x8a9a, 0x2dfb, 0x913c, 0x365d, 0x688e, 0xcfef },
-	{/*1d*/ 1, 0xff61, 0x55b2, 0xaad3, 0x7914, 0x8675, 0x2ca6, 0xd3c7,
-	   0x9e28, 0x6149, 0xcb9a, 0x34fb, 0xe73c, 0x185d, 0xb28e, 0x4def },
-	{/*1e*/ 1, 0x5451, 0xa8a2, 0xfcf3, 0x9694, 0xc2c5, 0x3e36, 0x6a67,
-	   0xebe8, 0xbfb9, 0x434a, 0x171b, 0x7d7c, 0x292d, 0xd5de, 0x818f },
-	{/*1f*/ 1, 0x6fc1, 0xb542, 0xda83, 0x19f4, 0x7635, 0xacb6, 0xc377,
-	   0x2e58, 0x4199, 0x9b1a, 0xf4db, 0x37ac, 0x586d, 0x82ee, 0xed2f },
+static u16 x4_vectors[] = {
+	0x2f57, 0x1afe, 0x66cc, 0xdd88,
+	0x11eb, 0x3396, 0x7f4c, 0xeac8,
+	0x0001, 0x0002, 0x0004, 0x0008,
+	0x1013, 0x3032, 0x4044, 0x8088,
+	0x106b, 0x30d6, 0x70fc, 0xe0a8,
+	0x4857, 0xc4fe, 0x13cc, 0x3288,
+	0x1ac5, 0x2f4a, 0x5394, 0xa1e8,
+	0x1f39, 0x251e, 0xbd6c, 0x6bd8,
+	0x15c1, 0x2a42, 0x89ac, 0x4758,
+	0x2b03, 0x1602, 0x4f0c, 0xca08,
+	0x1f07, 0x3a0e, 0x6b04, 0xbd08,
+	0x8ba7, 0x465e, 0x244c, 0x1cc8,
+	0x2b87, 0x164e, 0x642c, 0xdc18,
+	0x40b9, 0x80de, 0x1094, 0x20e8,
+	0x27db, 0x1eb6, 0x9dac, 0x7b58,
+	0x11c1, 0x2242, 0x84ac, 0x4c58,
+	0x1be5, 0x2d7a, 0x5e34, 0xa718,
+	0x4b39, 0x8d1e, 0x14b4, 0x28d8,
+	0x4c97, 0xc87e, 0x11fc, 0x33a8,
+	0x8e97, 0x497e, 0x2ffc, 0x1aa8,
+	0x16b3, 0x3d62, 0x4f34, 0x8518,
+	0x1e2f, 0x391a, 0x5cac, 0xf858,
+	0x1d9f, 0x3b7a, 0x572c, 0xfe18,
+	0x15f5, 0x2a5a, 0x5264, 0xa3b8,
+	0x1dbb, 0x3b66, 0x715c, 0xe3f8,
+	0x4397, 0xc27e, 0x17fc, 0x3ea8,
+	0x1617, 0x3d3e, 0x6464, 0xb8b8,
+	0x23ff, 0x12aa, 0xab6c, 0x56d8,
+	0x2dfb, 0x1ba6, 0x913c, 0x7328,
+	0x185d, 0x2ca6, 0x7914, 0x9e28,
+	0x171b, 0x3e36, 0x7d7c, 0xebe8,
+	0x4199, 0x82ee, 0x19f4, 0x2e58,
+	0x4807, 0xc40e, 0x130c, 0x3208,
+	0x1905, 0x2e0a, 0x5804, 0xac08,
+	0x213f, 0x132a, 0xadfc, 0x5ba8,
+	0x19a9, 0x2efe, 0xb5cc, 0x6f88,
+};
 
-	/* ECC bits are also in the set of tokens and they too can go bad
-	 * first 2 cover channel 0, while the second 2 cover channel 1
-	 */
-	{/*20*/ 0, 0xbe01, 0xd702, 0x6903, 0x2104, 0x9f05, 0xf606, 0x4807,
-	   0x3208, 0x8c09, 0xe50a, 0x5b0b, 0x130c, 0xad0d, 0xc40e, 0x7a0f },
-	{/*21*/ 0, 0x4101, 0x8202, 0xc303, 0x5804, 0x1905, 0xda06, 0x9b07,
-	   0xac08, 0xed09, 0x2e0a, 0x6f0b, 0x640c, 0xb50d, 0x760e, 0x370f },
-	{/*22*/ 1, 0xc441, 0x4882, 0x8cc3, 0xf654, 0x3215, 0xbed6, 0x7a97,
-	   0x5ba8, 0x9fe9, 0x132a, 0xd76b, 0xadfc, 0x69bd, 0xe57e, 0x213f },
-	{/*23*/ 1, 0x7621, 0x9b32, 0xed13, 0xda44, 0xac65, 0x4176, 0x3757,
-	   0x6f88, 0x19a9, 0xf4ba, 0x829b, 0xb5cc, 0xc3ed, 0x2efe, 0x58df }
+static u16 x8_vectors[] = {
+	0x0145, 0x028a, 0x2374, 0x43c8, 0xa1f0, 0x0520, 0x0a40, 0x1480,
+	0x0211, 0x0422, 0x0844, 0x1088, 0x01b0, 0x44e0, 0x23c0, 0xed80,
+	0x1011, 0x0116, 0x022c, 0x0458, 0x08b0, 0x8c60, 0x2740, 0x4e80,
+	0x0411, 0x0822, 0x1044, 0x0158, 0x02b0, 0x2360, 0x46c0, 0xab80,
+	0x0811, 0x1022, 0x012c, 0x0258, 0x04b0, 0x4660, 0x8cc0, 0x2780,
+	0x2071, 0x40e2, 0xa0c4, 0x0108, 0x0210, 0x0420, 0x0840, 0x1080,
+	0x4071, 0x80e2, 0x0104, 0x0208, 0x0410, 0x0820, 0x1040, 0x2080,
+	0x8071, 0x0102, 0x0204, 0x0408, 0x0810, 0x1020, 0x2040, 0x4080,
+	0x019d, 0x03d6, 0x136c, 0x2198, 0x50b0, 0xb2e0, 0x0740, 0x0e80,
+	0x0189, 0x03ea, 0x072c, 0x0e58, 0x1cb0, 0x56e0, 0x37c0, 0xf580,
+	0x01fd, 0x0376, 0x06ec, 0x0bb8, 0x1110, 0x2220, 0x4440, 0x8880,
+	0x0163, 0x02c6, 0x1104, 0x0758, 0x0eb0, 0x2be0, 0x6140, 0xc280,
+	0x02fd, 0x01c6, 0x0b5c, 0x1108, 0x07b0, 0x25a0, 0x8840, 0x6180,
+	0x0801, 0x012e, 0x025c, 0x04b8, 0x1370, 0x26e0, 0x57c0, 0xb580,
+	0x0401, 0x0802, 0x015c, 0x02b8, 0x22b0, 0x13e0, 0x7140, 0xe280,
+	0x0201, 0x0402, 0x0804, 0x01b8, 0x11b0, 0x31a0, 0x8040, 0x7180,
+	0x0101, 0x0202, 0x0404, 0x0808, 0x1010, 0x2020, 0x4040, 0x8080,
+	0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+	0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
 };
 
-/*
- * Given the syndrome argument, scan each of the channel tables for a syndrome
- * match. Depending on which table it is found, return the channel number.
- */
-static int get_channel_from_ecc_syndrome(unsigned short syndrome)
+static int decode_syndrome(u16 syndrome, u16 *vectors, int num_vecs,
+				 int v_dim)
 {
-	int row;
-	int column;
+	unsigned int i, err_sym;
 
-	/* Determine column to scan */
-	column = syndrome & 0xF;
+	for (err_sym = 0; err_sym < num_vecs / v_dim; err_sym++) {
+		u16 s = syndrome;
+		int v_idx =  err_sym * v_dim;
+		int v_end = (err_sym + 1) * v_dim;
 
-	/* Scan all rows, looking for syndrome, or end of table */
-	for (row = 0; row < NUMBER_ECC_ROWS; row++) {
-		if (ecc_chipkill_syndromes[row][column] == syndrome)
-			return ecc_chipkill_syndromes[row][0];
+		/* walk over all 16 bits of the syndrome */
+		for (i = 1; i < (1U << 16); i <<= 1) {
+
+			/* if bit is set in that eigenvector... */
+			if (v_idx < v_end && vectors[v_idx] & i) {
+				u16 ev_comp = vectors[v_idx++];
+
+				/* ... and bit set in the modified syndrome, */
+				if (s & i) {
+					/* remove it. */
+					s ^= ev_comp;
+
+					if (!s)
+						return err_sym;
+				}
+
+			} else if (s & i)
+				/* can't get to zero, move to next symbol */
+				break;
+		}
 	}
 
 	debugf0("syndrome(%x) not found\n", syndrome);
 	return -1;
 }
 
+static int map_err_sym_to_channel(int err_sym, int sym_size)
+{
+	if (sym_size == 4)
+		switch (err_sym) {
+		case 0x20:
+		case 0x21:
+			return 0;
+			break;
+		case 0x22:
+		case 0x23:
+			return 1;
+			break;
+		default:
+			return err_sym >> 4;
+			break;
+		}
+	/* x8 symbols */
+	else
+		switch (err_sym) {
+		/* imaginary bits not in a DIMM */
+		case 0x10:
+			WARN(1, KERN_ERR "Invalid error symbol: 0x%x\n",
+					  err_sym);
+			return -1;
+			break;
+
+		case 0x11:
+			return 0;
+			break;
+		case 0x12:
+			return 1;
+			break;
+		default:
+			return err_sym >> 3;
+			break;
+		}
+	return -1;
+}
+
+static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome)
+{
+	struct amd64_pvt *pvt = mci->pvt_info;
+	u32 value = 0;
+	int err_sym = 0;
+
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value);
+
+	/* F3x180[EccSymbolSize]=1, x8 symbols */
+	if (boot_cpu_data.x86 == 0x10 &&
+	    boot_cpu_data.x86_model > 7 &&
+	    value & BIT(25)) {
+		err_sym = decode_syndrome(syndrome, x8_vectors,
+					  ARRAY_SIZE(x8_vectors), 8);
+		return map_err_sym_to_channel(err_sym, 8);
+	} else {
+		err_sym = decode_syndrome(syndrome, x4_vectors,
+					  ARRAY_SIZE(x4_vectors), 4);
+		return map_err_sym_to_channel(err_sym, 4);
+	}
+}
+
 /*
  * Check for valid error in the NB Status High register. If so, proceed to read
  * NB Status Low, NB Address Low and NB Address High registers and store data
@@ -2073,40 +1988,24 @@ static int amd64_get_error_info_regs(str
 {
 	struct amd64_pvt *pvt;
 	struct pci_dev *misc_f3_ctl;
-	int err = 0;
 
 	pvt = mci->pvt_info;
 	misc_f3_ctl = pvt->misc_f3_ctl;
 
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBSH, &regs->nbsh);
-	if (err)
-		goto err_reg;
+	if (amd64_read_pci_cfg(misc_f3_ctl, K8_NBSH, &regs->nbsh))
+		return 0;
 
 	if (!(regs->nbsh & K8_NBSH_VALID_BIT))
 		return 0;
 
 	/* valid error, read remaining error information registers */
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBSL, &regs->nbsl);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBEAL, &regs->nbeal);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBEAH, &regs->nbeah);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(misc_f3_ctl, K8_NBCFG, &regs->nbcfg);
-	if (err)
-		goto err_reg;
+	if (amd64_read_pci_cfg(misc_f3_ctl, K8_NBSL, &regs->nbsl) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBEAL, &regs->nbeal) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBEAH, &regs->nbeah) ||
+	    amd64_read_pci_cfg(misc_f3_ctl, K8_NBCFG, &regs->nbcfg))
+		return 0;
 
 	return 1;
-
-err_reg:
-	debugf0("Reading error info register failed\n");
-	return 0;
 }
 
 /*
@@ -2184,7 +2083,7 @@ static void amd64_handle_ce(struct mem_c
 			    struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	u64 SystemAddress;
+	u64 sys_addr;
 
 	/* Ensure that the Error Address is VALID */
 	if ((info->nbsh & K8_NBSH_VALID_ERROR_ADDR) == 0) {
@@ -2194,22 +2093,23 @@ static void amd64_handle_ce(struct mem_c
 		return;
 	}
 
-	SystemAddress = extract_error_address(mci, info);
+	sys_addr = pvt->ops->get_error_address(mci, info);
 
 	amd64_mc_printk(mci, KERN_ERR,
-		"CE ERROR_ADDRESS= 0x%llx\n", SystemAddress);
+		"CE ERROR_ADDRESS= 0x%llx\n", sys_addr);
 
-	pvt->ops->map_sysaddr_to_csrow(mci, info, SystemAddress);
+	pvt->ops->map_sysaddr_to_csrow(mci, info, sys_addr);
 }
 
 /* Handle any Un-correctable Errors (UEs) */
 static void amd64_handle_ue(struct mem_ctl_info *mci,
 			    struct err_regs *info)
 {
+	struct amd64_pvt *pvt = mci->pvt_info;
+	struct mem_ctl_info *log_mci, *src_mci = NULL;
 	int csrow;
-	u64 SystemAddress;
+	u64 sys_addr;
 	u32 page, offset;
-	struct mem_ctl_info *log_mci, *src_mci = NULL;
 
 	log_mci = mci;
 
@@ -2220,31 +2120,31 @@ static void amd64_handle_ue(struct mem_c
 		return;
 	}
 
-	SystemAddress = extract_error_address(mci, info);
+	sys_addr = pvt->ops->get_error_address(mci, info);
 
 	/*
 	 * Find out which node the error address belongs to. This may be
 	 * different from the node that detected the error.
 	 */
-	src_mci = find_mc_by_sys_addr(mci, SystemAddress);
+	src_mci = find_mc_by_sys_addr(mci, sys_addr);
 	if (!src_mci) {
 		amd64_mc_printk(mci, KERN_CRIT,
 			"ERROR ADDRESS (0x%lx) value NOT mapped to a MC\n",
-			(unsigned long)SystemAddress);
+			(unsigned long)sys_addr);
 		edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR);
 		return;
 	}
 
 	log_mci = src_mci;
 
-	csrow = sys_addr_to_csrow(log_mci, SystemAddress);
+	csrow = sys_addr_to_csrow(log_mci, sys_addr);
 	if (csrow < 0) {
 		amd64_mc_printk(mci, KERN_CRIT,
 			"ERROR_ADDRESS (0x%lx) value NOT mapped to 'csrow'\n",
-			(unsigned long)SystemAddress);
+			(unsigned long)sys_addr);
 		edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR);
 	} else {
-		error_address_to_page_and_offset(SystemAddress, &page, &offset);
+		error_address_to_page_and_offset(sys_addr, &page, &offset);
 		edac_mc_handle_ue(log_mci, page, offset, csrow, EDAC_MOD_STR);
 	}
 }
@@ -2384,30 +2284,26 @@ static void amd64_free_mc_sibling_device
 static void amd64_read_mc_registers(struct amd64_pvt *pvt)
 {
 	u64 msr_val;
-	int dram, err = 0;
+	int dram;
 
 	/*
 	 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since
 	 * those are Read-As-Zero
 	 */
-	rdmsrl(MSR_K8_TOP_MEM1, msr_val);
-	pvt->top_mem = msr_val >> 23;
-	debugf0("  TOP_MEM=0x%08llx\n", pvt->top_mem);
+	rdmsrl(MSR_K8_TOP_MEM1, pvt->top_mem);
+	debugf0("  TOP_MEM:  0x%016llx\n", pvt->top_mem);
 
 	/* check first whether TOP_MEM2 is enabled */
 	rdmsrl(MSR_K8_SYSCFG, msr_val);
 	if (msr_val & (1U << 21)) {
-		rdmsrl(MSR_K8_TOP_MEM2, msr_val);
-		pvt->top_mem2 = msr_val >> 23;
-		debugf0("  TOP_MEM2=0x%08llx\n", pvt->top_mem2);
+		rdmsrl(MSR_K8_TOP_MEM2, pvt->top_mem2);
+		debugf0("  TOP_MEM2: 0x%016llx\n", pvt->top_mem2);
 	} else
 		debugf0("  TOP_MEM2 disabled.\n");
 
 	amd64_cpu_display_info(pvt);
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCAP, &pvt->nbcap);
-	if (err)
-		goto err_reg;
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCAP, &pvt->nbcap);
 
 	if (pvt->ops->read_dram_ctl_register)
 		pvt->ops->read_dram_ctl_register(pvt);
@@ -2425,13 +2321,12 @@ static void amd64_read_mc_registers(stru
 		 * debug output block away.
 		 */
 		if (pvt->dram_rw_en[dram] != 0) {
-			debugf1("  DRAM_BASE[%d]: 0x%8.08x-%8.08x "
-				"DRAM_LIMIT:  0x%8.08x-%8.08x\n",
+			debugf1("  DRAM-BASE[%d]: 0x%016llx "
+				"DRAM-LIMIT:  0x%016llx\n",
 				dram,
-				(u32)(pvt->dram_base[dram] >> 32),
-				(u32)(pvt->dram_base[dram] & 0xFFFFFFFF),
-				(u32)(pvt->dram_limit[dram] >> 32),
-				(u32)(pvt->dram_limit[dram] & 0xFFFFFFFF));
+				pvt->dram_base[dram],
+				pvt->dram_limit[dram]);
+
 			debugf1("        IntlvEn=%s %s %s "
 				"IntlvSel=%d DstNode=%d\n",
 				pvt->dram_IntlvEn[dram] ?
@@ -2445,44 +2340,20 @@ static void amd64_read_mc_registers(stru
 
 	amd64_read_dct_base_mask(pvt);
 
-	err = pci_read_config_dword(pvt->addr_f1_ctl, K8_DHAR, &pvt->dhar);
-	if (err)
-		goto err_reg;
-
+	amd64_read_pci_cfg(pvt->addr_f1_ctl, K8_DHAR, &pvt->dhar);
 	amd64_read_dbam_reg(pvt);
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl,
-				F10_ONLINE_SPARE, &pvt->online_spare);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
-	if (err)
-		goto err_reg;
-
-	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
-	if (err)
-		goto err_reg;
+	amd64_read_pci_cfg(pvt->misc_f3_ctl,
+			   F10_ONLINE_SPARE, &pvt->online_spare);
 
-	if (!dct_ganging_enabled(pvt)) {
-		err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_1,
-						&pvt->dclr1);
-		if (err)
-			goto err_reg;
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
+	amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
 
-		err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCHR_1,
-						&pvt->dchr1);
-		if (err)
-			goto err_reg;
+	if (!dct_ganging_enabled(pvt) && boot_cpu_data.x86 >= 0x10) {
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
+		amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1);
 	}
-
 	amd64_dump_misc_regs(pvt);
-
-	return;
-
-err_reg:
-	debugf0("Reading an MC register failed\n");
-
 }
 
 /*
@@ -2521,7 +2392,7 @@ err_reg:
  */
 static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
 {
-	u32 dram_map, nr_pages;
+	u32 cs_mode, nr_pages;
 
 	/*
 	 * The math on this doesn't look right on the surface because x/2*4 can
@@ -2530,9 +2401,9 @@ static u32 amd64_csrow_nr_pages(int csro
 	 * number of bits to shift the DBAM register to extract the proper CSROW
 	 * field.
 	 */
-	dram_map = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
+	cs_mode = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
 
-	nr_pages = pvt->ops->dbam_map_to_pages(pvt, dram_map);
+	nr_pages = pvt->ops->dbam_to_cs(pvt, cs_mode) << (20 - PAGE_SHIFT);
 
 	/*
 	 * If dual channel then double the memory size of single channel.
@@ -2540,7 +2411,7 @@ static u32 amd64_csrow_nr_pages(int csro
 	 */
 	nr_pages <<= (pvt->channel_count - 1);
 
-	debugf0("  (csrow=%d) DBAM map index= %d\n", csrow_nr, dram_map);
+	debugf0("  (csrow=%d) DBAM map index= %d\n", csrow_nr, cs_mode);
 	debugf0("    nr_pages= %u  channel-count = %d\n",
 		nr_pages, pvt->channel_count);
 
@@ -2556,13 +2427,11 @@ static int amd64_init_csrows(struct mem_
 	struct csrow_info *csrow;
 	struct amd64_pvt *pvt;
 	u64 input_addr_min, input_addr_max, sys_addr;
-	int i, err = 0, empty = 1;
+	int i, empty = 1;
 
 	pvt = mci->pvt_info;
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &pvt->nbcfg);
-	if (err)
-		debugf0("Reading K8_NBCFG failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &pvt->nbcfg);
 
 	debugf0("NBCFG= 0x%x  CHIPKILL= %s DRAM ECC= %s\n", pvt->nbcfg,
 		(pvt->nbcfg & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
@@ -2618,6 +2487,90 @@ static int amd64_init_csrows(struct mem_
 	return empty;
 }
 
+/* get all cores on this DCT */
+static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		if (amd_get_nb_id(cpu) == nid)
+			cpumask_set_cpu(cpu, mask);
+}
+
+/* check MCG_CTL on all the cpus on this node */
+static bool amd64_nb_mce_bank_enabled_on_node(int nid)
+{
+	cpumask_var_t mask;
+	int cpu, nbe;
+	bool ret = false;
+
+	if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
+		amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+			     __func__);
+		return false;
+	}
+
+	get_cpus_on_this_dct_cpumask(mask, nid);
+
+	rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, mask) {
+		struct msr *reg = per_cpu_ptr(msrs, cpu);
+		nbe = reg->l & K8_MSR_MCGCTL_NBE;
+
+		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+			cpu, reg->q,
+			(nbe ? "enabled" : "disabled"));
+
+		if (!nbe)
+			goto out;
+	}
+	ret = true;
+
+out:
+	free_cpumask_var(mask);
+	return ret;
+}
+
+static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
+{
+	cpumask_var_t cmask;
+	int cpu;
+
+	if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
+		amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
+			     __func__);
+		return false;
+	}
+
+	get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
+
+	rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, cmask) {
+
+		struct msr *reg = per_cpu_ptr(msrs, cpu);
+
+		if (on) {
+			if (reg->l & K8_MSR_MCGCTL_NBE)
+				pvt->flags.ecc_report = 1;
+
+			reg->l |= K8_MSR_MCGCTL_NBE;
+		} else {
+			/*
+			 * Turn off ECC reporting only when it was off before
+			 */
+			if (!pvt->flags.ecc_report)
+				reg->l &= ~K8_MSR_MCGCTL_NBE;
+		}
+	}
+	wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
+
+	free_cpumask_var(cmask);
+
+	return 0;
+}
+
 /*
  * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
  * enable it.
@@ -2625,24 +2578,16 @@ static int amd64_init_csrows(struct mem_
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!ecc_enable_override)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
 	amd64_printk(KERN_WARNING,
 		"'ecc_enable_override' parameter is active, "
 		"Enabling AMD ECC hardware now: CAUTION\n");
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 
 	/* turn on UECCn and CECCEn bits */
 	pvt->old_nbctl = value & mask;
@@ -2651,20 +2596,11 @@ static void amd64_enable_ecc_error_repor
 	value |= mask;
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	for_each_cpu(cpu, cpumask) {
-		if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
-			set_bit(idx, &pvt->old_mcgctl);
-
-		msrs[idx].l |= K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
+	if (amd64_toggle_ecc_err_reporting(pvt, ON))
+		amd64_printk(KERN_WARNING, "Error enabling ECC reporting over "
+					   "MCGCTL!\n");
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-	if (err)
-		debugf0("Reading K8_NBCFG failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 	debugf0("NBCFG(1)= 0x%x  CHIPKILL= %s ECC_ENABLE= %s\n", value,
 		(value & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
@@ -2679,9 +2615,7 @@ static void amd64_enable_ecc_error_repor
 		value |= K8_NBCFG_ECC_ENABLE;
 		pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
 
-		err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-		if (err)
-			debugf0("Reading K8_NBCFG failed\n");
+		amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 		if (!(value & K8_NBCFG_ECC_ENABLE)) {
 			amd64_printk(KERN_WARNING,
@@ -2701,86 +2635,21 @@ static void amd64_enable_ecc_error_repor
 
 static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 {
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!pvt->nbctl_mcgctl_saved)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 	value &= ~mask;
 	value |= pvt->old_nbctl;
 
 	/* restore the NB Enable MCGCTL bit */
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	for_each_cpu(cpu, cpumask) {
-		msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
-		msrs[idx].l |=
-			test_bit(idx, &pvt->old_mcgctl) << K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-}
-
-/* get all cores on this DCT */
-static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
-{
-	int cpu;
-
-	for_each_online_cpu(cpu)
-		if (amd_get_nb_id(cpu) == nid)
-			cpumask_set_cpu(cpu, mask);
-}
-
-/* check MCG_CTL on all the cpus on this node */
-static bool amd64_nb_mce_bank_enabled_on_node(int nid)
-{
-	cpumask_t mask;
-	struct msr *msrs;
-	int cpu, nbe, idx = 0;
-	bool ret = false;
-
-	cpumask_clear(&mask);
-
-	get_cpus_on_this_dct_cpumask(&mask, nid);
-
-	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
-	if (!msrs) {
-		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
-			      __func__);
-		 return false;
-	}
-
-	rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
-
-	for_each_cpu(cpu, &mask) {
-		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
-
-		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
-			cpu, msrs[idx].q,
-			(nbe ? "enabled" : "disabled"));
-
-		if (!nbe)
-			goto out;
-
-		idx++;
-	}
-	ret = true;
-
-out:
-	kfree(msrs);
-	return ret;
+	if (amd64_toggle_ecc_err_reporting(pvt, OFF))
+		amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
+					   "MCGCTL!\n");
 }
 
 /*
@@ -2789,25 +2658,23 @@ out:
  * the memory system completely. A command line option allows to force-enable
  * hardware ECC later in amd64_enable_ecc_error_reporting().
  */
-static const char *ecc_warning =
-	"WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n"
-	" Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n"
-	" Also, use of the override can cause unknown side effects.\n";
+static const char *ecc_msg =
+	"ECC disabled in the BIOS or no ECC capability, module will not load.\n"
+	" Either enable ECC checking or force module loading by setting "
+	"'ecc_enable_override'.\n"
+	" (Note that use of the override may cause unknown side effects.)\n";
 
 static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 {
 	u32 value;
-	int err = 0;
 	u8 ecc_enabled = 0;
 	bool nb_mce_en = false;
 
-	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
-	if (err)
-		debugf0("Reading K8_NBCTL failed\n");
+	amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
 
 	ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
 	if (!ecc_enabled)
-		amd64_printk(KERN_WARNING, "This node reports that Memory ECC "
+		amd64_printk(KERN_NOTICE, "This node reports that Memory ECC "
 			     "is currently disabled, set F3x%x[22] (%s).\n",
 			     K8_NBCFG, pci_name(pvt->misc_f3_ctl));
 	else
@@ -2815,18 +2682,17 @@ static int amd64_check_ecc_enabled(struc
 
 	nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id);
 	if (!nb_mce_en)
-		amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR "
+		amd64_printk(KERN_NOTICE, "NB MCE bank disabled, set MSR "
 			     "0x%08x[4] on node %d to enable.\n",
 			     MSR_IA32_MCG_CTL, pvt->mc_node_id);
 
 	if (!ecc_enabled || !nb_mce_en) {
 		if (!ecc_enable_override) {
-			amd64_printk(KERN_WARNING, "%s", ecc_warning);
+			amd64_printk(KERN_NOTICE, "%s", ecc_msg);
 			return -ENODEV;
 		}
-	} else
-		/* CLEAR the override, since BIOS controlled it */
 		ecc_enable_override = 0;
+	}
 
 	return 0;
 }
@@ -2909,7 +2775,6 @@ static int amd64_probe_one_instance(stru
 	pvt->ext_model		= boot_cpu_data.x86_model >> 4;
 	pvt->mc_type_index	= mc_type_index;
 	pvt->ops		= family_ops(mc_type_index);
-	pvt->old_mcgctl		= 0;
 
 	/*
 	 * We have the dram_f2_ctl device as an argument, now go reserve its
@@ -2959,17 +2824,10 @@ static int amd64_init_2nd_stage(struct a
 {
 	int node_id = pvt->mc_node_id;
 	struct mem_ctl_info *mci;
-	int ret, err = 0;
+	int ret = -ENODEV;
 
 	amd64_read_mc_registers(pvt);
 
-	ret = -ENODEV;
-	if (pvt->ops->probe_valid_hardware) {
-		err = pvt->ops->probe_valid_hardware(pvt);
-		if (err)
-			goto err_exit;
-	}
-
 	/*
 	 * We need to determine how many memory channels there are. Then use
 	 * that information for calculating the size of the dynamic instance
@@ -3071,16 +2929,15 @@ static void __devexit amd64_remove_one_i
 
 	amd64_free_mc_sibling_devices(pvt);
 
-	kfree(pvt);
-	mci->pvt_info = NULL;
-
-	mci_lookup[pvt->mc_node_id] = NULL;
-
 	/* unregister from EDAC MCE */
 	amd_report_gart_errors(false);
 	amd_unregister_ecc_decoder(amd64_decode_bus_error);
 
 	/* Free the EDAC CORE resources */
+	mci->pvt_info = NULL;
+	mci_lookup[pvt->mc_node_id] = NULL;
+
+	kfree(pvt);
 	edac_mc_free(mci);
 }
 
@@ -3157,23 +3014,29 @@ static void amd64_setup_pci_device(void)
 static int __init amd64_edac_init(void)
 {
 	int nb, err = -ENODEV;
+	bool load_ok = false;
 
 	edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n");
 
 	opstate_init();
 
 	if (cache_k8_northbridges() < 0)
-		return err;
+		goto err_ret;
+
+	msrs = msrs_alloc();
+	if (!msrs)
+		goto err_ret;
 
 	err = pci_register_driver(&amd64_pci_driver);
 	if (err)
-		return err;
+		goto err_pci;
 
 	/*
 	 * At this point, the array 'pvt_lookup[]' contains pointers to alloc'd
 	 * amd64_pvt structs. These will be used in the 2nd stage init function
 	 * to finish initialization of the MC instances.
 	 */
+	err = -ENODEV;
 	for (nb = 0; nb < num_k8_northbridges; nb++) {
 		if (!pvt_lookup[nb])
 			continue;
@@ -3181,16 +3044,21 @@ static int __init amd64_edac_init(void)
 		err = amd64_init_2nd_stage(pvt_lookup[nb]);
 		if (err)
 			goto err_2nd_stage;
-	}
 
-	amd64_setup_pci_device();
+		load_ok = true;
+	}
 
-	return 0;
+	if (load_ok) {
+		amd64_setup_pci_device();
+		return 0;
+	}
 
 err_2nd_stage:
-	debugf0("2nd stage failed\n");
 	pci_unregister_driver(&amd64_pci_driver);
-
+err_pci:
+	msrs_free(msrs);
+	msrs = NULL;
+err_ret:
 	return err;
 }
 
@@ -3200,6 +3068,9 @@ static void __exit amd64_edac_exit(void)
 		edac_pci_release_generic_ctl(amd64_ctl_pci);
 
 	pci_unregister_driver(&amd64_pci_driver);
+
+	msrs_free(msrs);
+	msrs = NULL;
 }
 
 module_init(amd64_edac_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/amd64_edac.h linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.h
--- linux-libre-2.6.32-gnu1/drivers/edac/amd64_edac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/amd64_edac.h	2010-02-24 13:52:17.000000000 -0500
@@ -129,24 +129,22 @@
  *         sections 3.5.4 and 3.5.5 for more information.
  */
 
-#define EDAC_AMD64_VERSION		" Ver: 3.2.0 " __DATE__
+#define EDAC_AMD64_VERSION		" Ver: 3.3.0 " __DATE__
 #define EDAC_MOD_STR			"amd64_edac"
 
 #define EDAC_MAX_NUMNODES		8
 
 /* Extended Model from CPUID, for CPU Revision numbers */
-#define OPTERON_CPU_LE_REV_C		0
-#define OPTERON_CPU_REV_D		1
-#define OPTERON_CPU_REV_E		2
-
-/* NPT processors have the following Extended Models */
-#define OPTERON_CPU_REV_F		4
-#define OPTERON_CPU_REV_FA		5
+#define K8_REV_D			1
+#define K8_REV_E			2
+#define K8_REV_F			4
 
 /* Hardware limit on ChipSelect rows per MC and processors per system */
 #define MAX_CS_COUNT			8
 #define DRAM_REG_COUNT			8
 
+#define ON true
+#define OFF false
 
 /*
  * PCI-defined configuration space registers
@@ -241,7 +239,7 @@
 #define F10_DCHR_1			0x194
 
 #define F10_DCHR_FOUR_RANK_DIMM		BIT(18)
-#define F10_DCHR_Ddr3Mode		BIT(8)
+#define DDR3_MODE			BIT(8)
 #define F10_DCHR_MblMode		BIT(6)
 
 
@@ -382,14 +380,9 @@ enum {
 #define K8_NBCAP_CORES			(BIT(12)|BIT(13))
 #define K8_NBCAP_CHIPKILL		BIT(4)
 #define K8_NBCAP_SECDED			BIT(3)
-#define K8_NBCAP_8_NODE			BIT(2)
-#define K8_NBCAP_DUAL_NODE		BIT(1)
 #define K8_NBCAP_DCT_DUAL		BIT(0)
 
-/*
- * MSR Regs
- */
-#define K8_MSR_MCGCTL			0x017b
+/* MSRs */
 #define K8_MSR_MCGCTL_NBE		BIT(4)
 
 #define K8_MSR_MC4CTL			0x0410
@@ -487,7 +480,6 @@ struct amd64_pvt {
 	/* Save old hw registers' values before we modified them */
 	u32 nbctl_mcgctl_saved;		/* When true, following 2 are valid */
 	u32 old_nbctl;
-	unsigned long old_mcgctl;	/* per core on this node */
 
 	/* MC Type Index value: socket F vs Family 10h */
 	u32 mc_type_index;
@@ -495,6 +487,7 @@ struct amd64_pvt {
 	/* misc settings */
 	struct flags {
 		unsigned long cf8_extcfg:1;
+		unsigned long ecc_report:1;
 	} flags;
 };
 
@@ -504,7 +497,6 @@ struct scrubrate {
 };
 
 extern struct scrubrate scrubrates[23];
-extern u32 revf_quad_ddr2_shift[16];
 extern const char *tt_msgs[4];
 extern const char *ll_msgs[4];
 extern const char *rrrr_msgs[16];
@@ -534,17 +526,15 @@ extern struct mcidev_sysfs_attribute amd
  * functions and per device encoding/decoding logic.
  */
 struct low_ops {
-	int (*probe_valid_hardware)(struct amd64_pvt *pvt);
-	int (*early_channel_count)(struct amd64_pvt *pvt);
+	int (*early_channel_count)	(struct amd64_pvt *pvt);
 
-	u64 (*get_error_address)(struct mem_ctl_info *mci,
-			struct err_regs *info);
-	void (*read_dram_base_limit)(struct amd64_pvt *pvt, int dram);
-	void (*read_dram_ctl_register)(struct amd64_pvt *pvt);
-	void (*map_sysaddr_to_csrow)(struct mem_ctl_info *mci,
-					struct err_regs *info,
-					u64 SystemAddr);
-	int (*dbam_map_to_pages)(struct amd64_pvt *pvt, int dram_map);
+	u64 (*get_error_address)	(struct mem_ctl_info *mci,
+					 struct err_regs *info);
+	void (*read_dram_base_limit)	(struct amd64_pvt *pvt, int dram);
+	void (*read_dram_ctl_register)	(struct amd64_pvt *pvt);
+	void (*map_sysaddr_to_csrow)	(struct mem_ctl_info *mci,
+					 struct err_regs *info, u64 SystemAddr);
+	int (*dbam_to_cs)		(struct amd64_pvt *pvt, int cs_mode);
 };
 
 struct amd64_family_type {
@@ -566,6 +556,22 @@ static inline struct low_ops *family_ops
 	return &amd64_family_types[index].ops;
 }
 
+static inline int amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
+					   u32 *val, const char *func)
+{
+	int err = 0;
+
+	err = pci_read_config_dword(pdev, offset, val);
+	if (err)
+		amd64_printk(KERN_WARNING, "%s: error reading F%dx%x.\n",
+			     func, PCI_FUNC(pdev->devfn), offset);
+
+	return err;
+}
+
+#define amd64_read_pci_cfg(pdev, offset, val)	\
+	amd64_read_pci_cfg_dword(pdev, offset, val, __func__)
+
 /*
  * For future CPU versions, verify the following as new 'slow' rates appear and
  * modify the necessary skip values for the supported CPU.
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/edac_core.h linux-libre-2.6.33-gnu1/drivers/edac/edac_core.h
--- linux-libre-2.6.32-gnu1/drivers/edac/edac_core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/edac_core.h	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,7 @@
 
 #ifdef CONFIG_EDAC_DEBUG
 extern int edac_debug_level;
+extern const char *edac_mem_types[];
 
 #ifndef CONFIG_EDAC_DEBUG_VERBOSE
 #define edac_debug_printk(level, fmt, arg...)                           \
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/edac_mc.c linux-libre-2.6.33-gnu1/drivers/edac/edac_mc.c
--- linux-libre-2.6.32-gnu1/drivers/edac/edac_mc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/edac_mc.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,6 +76,30 @@ static void edac_mc_dump_mci(struct mem_
 	debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
 }
 
+/*
+ * keep those in sync with the enum mem_type
+ */
+const char *edac_mem_types[] = {
+	"Empty csrow",
+	"Reserved csrow type",
+	"Unknown csrow type",
+	"Fast page mode RAM",
+	"Extended data out RAM",
+	"Burst Extended data out RAM",
+	"Single data rate SDRAM",
+	"Registered single data rate SDRAM",
+	"Double data rate SDRAM",
+	"Registered Double data rate SDRAM",
+	"Rambus DRAM",
+	"Unbuffered DDR2 RAM",
+	"Fully buffered DDR2",
+	"Registered DDR2 RAM",
+	"Rambus XDR",
+	"Unbuffered DDR3 RAM",
+	"Registered DDR3 RAM",
+};
+EXPORT_SYMBOL_GPL(edac_mem_types);
+
 #endif				/* CONFIG_EDAC_DEBUG */
 
 /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/edac_mce_amd.c linux-libre-2.6.33-gnu1/drivers/edac/edac_mce_amd.c
--- linux-libre-2.6.32-gnu1/drivers/edac/edac_mce_amd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/edac_mce_amd.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,6 @@
 
 static bool report_gart_errors;
 static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
-static void (*orig_mce_callback)(struct mce *m);
 
 void amd_report_gart_errors(bool v)
 {
@@ -300,6 +299,12 @@ void amd_decode_nb_mce(int node_id, stru
 	if (!handle_errors)
 		return;
 
+	/*
+	 * GART TLB error reporting is disabled by default. Bail out early.
+	 */
+	if (TLB_ERROR(ec) && !report_gart_errors)
+		return;
+
 	pr_emerg(" Northbridge Error, node %d", node_id);
 
 	/*
@@ -307,14 +312,13 @@ void amd_decode_nb_mce(int node_id, stru
 	 * value encoding has changed so interpret those differently
 	 */
 	if ((boot_cpu_data.x86 == 0x10) &&
-	    (boot_cpu_data.x86_model > 8)) {
+	    (boot_cpu_data.x86_model > 7)) {
 		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
 			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
 	} else {
-		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
+		pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1));
 	}
 
-
 	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
 
 	if (BUS_ERROR(ec) && nb_bus_decoder)
@@ -334,21 +338,6 @@ static void amd_decode_fr_mce(u64 mc5_st
 static inline void amd_decode_err_code(unsigned int ec)
 {
 	if (TLB_ERROR(ec)) {
-		/*
-		 * GART errors are intended to help graphics driver developers
-		 * to detect bad GART PTEs. It is recommended by AMD to disable
-		 * GART table walk error reporting by default[1] (currently
-		 * being disabled in mce_cpu_quirks()) and according to the
-		 * comment in mce_cpu_quirks(), such GART errors can be
-		 * incorrectly triggered. We may see these errors anyway and
-		 * unless requested by the user, they won't be reported.
-		 *
-		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
-		 *     AMD NPT family 0Fh processors
-		 */
-		if (!report_gart_errors)
-			return;
-
 		pr_emerg(" Transaction: %s, Cache Level %s\n",
 			 TT_MSG(ec), LL_MSG(ec));
 	} else if (MEM_ERROR(ec)) {
@@ -363,8 +352,10 @@ static inline void amd_decode_err_code(u
 		pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
 }
 
-static void amd_decode_mce(struct mce *m)
+static int amd_decode_mce(struct notifier_block *nb, unsigned long val,
+			   void *data)
 {
+	struct mce *m = (struct mce *)data;
 	struct err_regs regs;
 	int node, ecc;
 
@@ -420,20 +411,22 @@ static void amd_decode_mce(struct mce *m
 	}
 
 	amd_decode_err_code(m->status & 0xffff);
+
+	return NOTIFY_STOP;
 }
 
+static struct notifier_block amd_mce_dec_nb = {
+	.notifier_call	= amd_decode_mce,
+};
+
 static int __init mce_amd_init(void)
 {
 	/*
 	 * We can decode MCEs for Opteron and later CPUs:
 	 */
 	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
-	    (boot_cpu_data.x86 >= 0xf)) {
-		/* safe the default decode mce callback */
-		orig_mce_callback = x86_mce_decode_callback;
-
-		x86_mce_decode_callback = amd_decode_mce;
-	}
+	    (boot_cpu_data.x86 >= 0xf))
+		atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
 
 	return 0;
 }
@@ -442,7 +435,7 @@ early_initcall(mce_amd_init);
 #ifdef MODULE
 static void __exit mce_amd_exit(void)
 {
-	x86_mce_decode_callback = orig_mce_callback;
+	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
 }
 
 MODULE_DESCRIPTION("AMD MCE decoder");
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/edac_pci_sysfs.c linux-libre-2.6.33-gnu1/drivers/edac/edac_pci_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/edac/edac_pci_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/edac_pci_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -534,8 +534,6 @@ static void edac_pci_dev_parity_clear(st
 {
 	u8 header_type;
 
-	debugf0("%s()\n", __func__);
-
 	get_pci_parity_status(dev, 0);
 
 	/* read the device TYPE, looking for bridges */
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/i5000_edac.c linux-libre-2.6.33-gnu1/drivers/edac/i5000_edac.c
--- linux-libre-2.6.32-gnu1/drivers/edac/i5000_edac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/i5000_edac.c	2010-02-24 13:52:17.000000000 -0500
@@ -577,7 +577,13 @@ static void i5000_process_nonfatal_error
 		debugf0("\tUncorrected bits= 0x%x\n", ue_errors);
 
 		branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd);
-		channel = branch;
+
+		/*
+		 * According with i5000 datasheet, bit 28 has no significance
+		 * for errors M4Err-M12Err and M17Err-M21Err, on FERR_NF_FBD
+		 */
+		channel = branch & 2;
+
 		bank = NREC_BANK(info->nrecmema);
 		rank = NREC_RANK(info->nrecmema);
 		rdwr = NREC_RDWR(info->nrecmema);
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/i5100_edac.c linux-libre-2.6.33-gnu1/drivers/edac/i5100_edac.c
--- linux-libre-2.6.32-gnu1/drivers/edac/i5100_edac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/i5100_edac.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,11 @@
  * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
  *      http://download.intel.com/design/chipsets/datashts/318378.pdf
  *
+ * The intel 5100 has two independent channels. EDAC core currently
+ * can not reflect this configuration so instead the chip-select
+ * rows for each respective channel are layed out one after another,
+ * the first half belonging to channel 0, the second half belonging
+ * to channel 1.
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -25,6 +30,8 @@
 
 /* device 16, func 1 */
 #define I5100_MC		0x40	/* Memory Control Register */
+#define 	I5100_MC_SCRBEN_MASK	(1 << 7)
+#define 	I5100_MC_SCRBDONE_MASK	(1 << 4)
 #define I5100_MS		0x44	/* Memory Status Register */
 #define I5100_SPDDATA		0x48	/* Serial Presence Detect Status Reg */
 #define I5100_SPDCMD		0x4c	/* Serial Presence Detect Command Reg */
@@ -72,11 +79,21 @@
 
 /* bit field accessors */
 
+static inline u32 i5100_mc_scrben(u32 mc)
+{
+	return mc >> 7 & 1;
+}
+
 static inline u32 i5100_mc_errdeten(u32 mc)
 {
 	return mc >> 5 & 1;
 }
 
+static inline u32 i5100_mc_scrbdone(u32 mc)
+{
+	return mc >> 4 & 1;
+}
+
 static inline u16 i5100_spddata_rdo(u16 a)
 {
 	return a >> 15 & 1;
@@ -265,42 +282,43 @@ static inline u32 i5100_recmemb_ras(u32
 }
 
 /* some generic limits */
-#define I5100_MAX_RANKS_PER_CTLR	6
-#define I5100_MAX_CTLRS			2
+#define I5100_MAX_RANKS_PER_CHAN	6
+#define I5100_CHANNELS			    2
 #define I5100_MAX_RANKS_PER_DIMM	4
 #define I5100_DIMM_ADDR_LINES		(6 - 3)	/* 64 bits / 8 bits per byte */
-#define I5100_MAX_DIMM_SLOTS_PER_CTLR	4
+#define I5100_MAX_DIMM_SLOTS_PER_CHAN	4
 #define I5100_MAX_RANK_INTERLEAVE	4
 #define I5100_MAX_DMIRS			5
+#define I5100_SCRUB_REFRESH_RATE	(5 * 60 * HZ)
 
 struct i5100_priv {
 	/* ranks on each dimm -- 0 maps to not present -- obtained via SPD */
-	int dimm_numrank[I5100_MAX_CTLRS][I5100_MAX_DIMM_SLOTS_PER_CTLR];
+	int dimm_numrank[I5100_CHANNELS][I5100_MAX_DIMM_SLOTS_PER_CHAN];
 
 	/*
 	 * mainboard chip select map -- maps i5100 chip selects to
 	 * DIMM slot chip selects.  In the case of only 4 ranks per
-	 * controller, the mapping is fairly obvious but not unique.
-	 * we map -1 -> NC and assume both controllers use the same
+	 * channel, the mapping is fairly obvious but not unique.
+	 * we map -1 -> NC and assume both channels use the same
 	 * map...
 	 *
 	 */
-	int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CTLR][I5100_MAX_RANKS_PER_DIMM];
+	int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CHAN][I5100_MAX_RANKS_PER_DIMM];
 
 	/* memory interleave range */
 	struct {
 		u64	 limit;
 		unsigned way[2];
-	} mir[I5100_MAX_CTLRS];
+	} mir[I5100_CHANNELS];
 
 	/* adjusted memory interleave range register */
-	unsigned amir[I5100_MAX_CTLRS];
+	unsigned amir[I5100_CHANNELS];
 
 	/* dimm interleave range */
 	struct {
 		unsigned rank[I5100_MAX_RANK_INTERLEAVE];
 		u64	 limit;
-	} dmir[I5100_MAX_CTLRS][I5100_MAX_DMIRS];
+	} dmir[I5100_CHANNELS][I5100_MAX_DMIRS];
 
 	/* memory technology registers... */
 	struct {
@@ -310,30 +328,33 @@ struct i5100_priv {
 		unsigned numbank;	/* 2 or 3 lines */
 		unsigned numrow;	/* 13 .. 16 lines */
 		unsigned numcol;	/* 11 .. 12 lines */
-	} mtr[I5100_MAX_CTLRS][I5100_MAX_RANKS_PER_CTLR];
+	} mtr[I5100_CHANNELS][I5100_MAX_RANKS_PER_CHAN];
 
 	u64 tolm;		/* top of low memory in bytes */
-	unsigned ranksperctlr;	/* number of ranks per controller */
+	unsigned ranksperchan;	/* number of ranks per channel */
 
 	struct pci_dev *mc;	/* device 16 func 1 */
 	struct pci_dev *ch0mm;	/* device 21 func 0 */
 	struct pci_dev *ch1mm;	/* device 22 func 0 */
+
+	struct delayed_work i5100_scrubbing;
+	int scrub_enable;
 };
 
-/* map a rank/ctlr to a slot number on the mainboard */
+/* map a rank/chan to a slot number on the mainboard */
 static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
-			      int ctlr, int rank)
+			      int chan, int rank)
 {
 	const struct i5100_priv *priv = mci->pvt_info;
 	int i;
 
-	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
+	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
 		int j;
-		const int numrank = priv->dimm_numrank[ctlr][i];
+		const int numrank = priv->dimm_numrank[chan][i];
 
 		for (j = 0; j < numrank; j++)
 			if (priv->dimm_csmap[i][j] == rank)
-				return i * 2 + ctlr;
+				return i * 2 + chan;
 	}
 
 	return -1;
@@ -374,32 +395,32 @@ static const char *i5100_err_msg(unsigne
 	return "none";
 }
 
-/* convert csrow index into a rank (per controller -- 0..5) */
+/* convert csrow index into a rank (per channel -- 0..5) */
 static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
 {
 	const struct i5100_priv *priv = mci->pvt_info;
 
-	return csrow % priv->ranksperctlr;
+	return csrow % priv->ranksperchan;
 }
 
-/* convert csrow index into a controller (0..1) */
-static int i5100_csrow_to_cntlr(const struct mem_ctl_info *mci, int csrow)
+/* convert csrow index into a channel (0..1) */
+static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
 {
 	const struct i5100_priv *priv = mci->pvt_info;
 
-	return csrow / priv->ranksperctlr;
+	return csrow / priv->ranksperchan;
 }
 
 static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci,
-				    int ctlr, int rank)
+				    int chan, int rank)
 {
 	const struct i5100_priv *priv = mci->pvt_info;
 
-	return ctlr * priv->ranksperctlr + rank;
+	return chan * priv->ranksperchan + rank;
 }
 
 static void i5100_handle_ce(struct mem_ctl_info *mci,
-			    int ctlr,
+			    int chan,
 			    unsigned bank,
 			    unsigned rank,
 			    unsigned long syndrome,
@@ -407,12 +428,12 @@ static void i5100_handle_ce(struct mem_c
 			    unsigned ras,
 			    const char *msg)
 {
-	const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
+	const int csrow = i5100_rank_to_csrow(mci, chan, rank);
 
 	printk(KERN_ERR
-		"CE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
+		"CE chan %d, bank %u, rank %u, syndrome 0x%lx, "
 		"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
-		ctlr, bank, rank, syndrome, cas, ras,
+		chan, bank, rank, syndrome, cas, ras,
 		csrow, mci->csrows[csrow].channels[0].label, msg);
 
 	mci->ce_count++;
@@ -421,7 +442,7 @@ static void i5100_handle_ce(struct mem_c
 }
 
 static void i5100_handle_ue(struct mem_ctl_info *mci,
-			    int ctlr,
+			    int chan,
 			    unsigned bank,
 			    unsigned rank,
 			    unsigned long syndrome,
@@ -429,23 +450,23 @@ static void i5100_handle_ue(struct mem_c
 			    unsigned ras,
 			    const char *msg)
 {
-	const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
+	const int csrow = i5100_rank_to_csrow(mci, chan, rank);
 
 	printk(KERN_ERR
-		"UE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
+		"UE chan %d, bank %u, rank %u, syndrome 0x%lx, "
 		"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
-		ctlr, bank, rank, syndrome, cas, ras,
+		chan, bank, rank, syndrome, cas, ras,
 		csrow, mci->csrows[csrow].channels[0].label, msg);
 
 	mci->ue_count++;
 	mci->csrows[csrow].ue_count++;
 }
 
-static void i5100_read_log(struct mem_ctl_info *mci, int ctlr,
+static void i5100_read_log(struct mem_ctl_info *mci, int chan,
 			   u32 ferr, u32 nerr)
 {
 	struct i5100_priv *priv = mci->pvt_info;
-	struct pci_dev *pdev = (ctlr) ? priv->ch1mm : priv->ch0mm;
+	struct pci_dev *pdev = (chan) ? priv->ch1mm : priv->ch0mm;
 	u32 dw;
 	u32 dw2;
 	unsigned syndrome = 0;
@@ -484,7 +505,7 @@ static void i5100_read_log(struct mem_ct
 		else
 			msg = i5100_err_msg(nerr);
 
-		i5100_handle_ce(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
+		i5100_handle_ce(mci, chan, bank, rank, syndrome, cas, ras, msg);
 	}
 
 	if (i5100_validlog_nrecmemvalid(dw)) {
@@ -506,7 +527,7 @@ static void i5100_read_log(struct mem_ct
 		else
 			msg = i5100_err_msg(nerr);
 
-		i5100_handle_ue(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
+		i5100_handle_ue(mci, chan, bank, rank, syndrome, cas, ras, msg);
 	}
 
 	pci_write_config_dword(pdev, I5100_VALIDLOG, dw);
@@ -534,6 +555,80 @@ static void i5100_check_error(struct mem
 	}
 }
 
+/* The i5100 chipset will scrub the entire memory once, then
+ * set a done bit. Continuous scrubbing is achieved by enqueing
+ * delayed work to a workqueue, checking every few minutes if
+ * the scrubbing has completed and if so reinitiating it.
+ */
+
+static void i5100_refresh_scrubbing(struct work_struct *work)
+{
+	struct delayed_work *i5100_scrubbing = container_of(work,
+							    struct delayed_work,
+							    work);
+	struct i5100_priv *priv = container_of(i5100_scrubbing,
+					       struct i5100_priv,
+					       i5100_scrubbing);
+	u32 dw;
+
+	pci_read_config_dword(priv->mc, I5100_MC, &dw);
+
+	if (priv->scrub_enable) {
+
+		pci_read_config_dword(priv->mc, I5100_MC, &dw);
+
+		if (i5100_mc_scrbdone(dw)) {
+			dw |= I5100_MC_SCRBEN_MASK;
+			pci_write_config_dword(priv->mc, I5100_MC, dw);
+			pci_read_config_dword(priv->mc, I5100_MC, &dw);
+		}
+
+		schedule_delayed_work(&(priv->i5100_scrubbing),
+				      I5100_SCRUB_REFRESH_RATE);
+	}
+}
+/*
+ * The bandwidth is based on experimentation, feel free to refine it.
+ */
+static int i5100_set_scrub_rate(struct mem_ctl_info *mci,
+				       u32 *bandwidth)
+{
+	struct i5100_priv *priv = mci->pvt_info;
+	u32 dw;
+
+	pci_read_config_dword(priv->mc, I5100_MC, &dw);
+	if (*bandwidth) {
+		priv->scrub_enable = 1;
+		dw |= I5100_MC_SCRBEN_MASK;
+		schedule_delayed_work(&(priv->i5100_scrubbing),
+				      I5100_SCRUB_REFRESH_RATE);
+	} else {
+		priv->scrub_enable = 0;
+		dw &= ~I5100_MC_SCRBEN_MASK;
+		cancel_delayed_work(&(priv->i5100_scrubbing));
+	}
+	pci_write_config_dword(priv->mc, I5100_MC, dw);
+
+	pci_read_config_dword(priv->mc, I5100_MC, &dw);
+
+	*bandwidth = 5900000 * i5100_mc_scrben(dw);
+
+	return 0;
+}
+
+static int i5100_get_scrub_rate(struct mem_ctl_info *mci,
+				u32 *bandwidth)
+{
+	struct i5100_priv *priv = mci->pvt_info;
+	u32 dw;
+
+	pci_read_config_dword(priv->mc, I5100_MC, &dw);
+
+	*bandwidth = 5900000 * i5100_mc_scrben(dw);
+
+	return 0;
+}
+
 static struct pci_dev *pci_get_device_func(unsigned vendor,
 					   unsigned device,
 					   unsigned func)
@@ -557,19 +652,19 @@ static unsigned long __devinit i5100_npa
 					    int csrow)
 {
 	struct i5100_priv *priv = mci->pvt_info;
-	const unsigned ctlr_rank = i5100_csrow_to_rank(mci, csrow);
-	const unsigned ctlr = i5100_csrow_to_cntlr(mci, csrow);
+	const unsigned chan_rank = i5100_csrow_to_rank(mci, csrow);
+	const unsigned chan = i5100_csrow_to_chan(mci, csrow);
 	unsigned addr_lines;
 
 	/* dimm present? */
-	if (!priv->mtr[ctlr][ctlr_rank].present)
+	if (!priv->mtr[chan][chan_rank].present)
 		return 0ULL;
 
 	addr_lines =
 		I5100_DIMM_ADDR_LINES +
-		priv->mtr[ctlr][ctlr_rank].numcol +
-		priv->mtr[ctlr][ctlr_rank].numrow +
-		priv->mtr[ctlr][ctlr_rank].numbank;
+		priv->mtr[chan][chan_rank].numcol +
+		priv->mtr[chan][chan_rank].numrow +
+		priv->mtr[chan][chan_rank].numbank;
 
 	return (unsigned long)
 		((unsigned long long) (1ULL << addr_lines) / PAGE_SIZE);
@@ -581,11 +676,11 @@ static void __devinit i5100_init_mtr(str
 	struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm };
 	int i;
 
-	for (i = 0; i < I5100_MAX_CTLRS; i++) {
+	for (i = 0; i < I5100_CHANNELS; i++) {
 		int j;
 		struct pci_dev *pdev = mms[i];
 
-		for (j = 0; j < I5100_MAX_RANKS_PER_CTLR; j++) {
+		for (j = 0; j < I5100_MAX_RANKS_PER_CHAN; j++) {
 			const unsigned addr =
 				(j < 4) ? I5100_MTR_0 + j * 2 :
 					  I5100_MTR_4 + (j - 4) * 2;
@@ -644,7 +739,6 @@ static int i5100_read_spd_byte(const str
  * fill dimm chip select map
  *
  * FIXME:
- *   o only valid for 4 ranks per controller
  *   o not the only way to may chip selects to dimm slots
  *   o investigate if there is some way to obtain this map from the bios
  */
@@ -653,9 +747,7 @@ static void __devinit i5100_init_dimm_cs
 	struct i5100_priv *priv = mci->pvt_info;
 	int i;
 
-	WARN_ON(priv->ranksperctlr != 4);
-
-	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
+	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
 		int j;
 
 		for (j = 0; j < I5100_MAX_RANKS_PER_DIMM; j++)
@@ -663,12 +755,21 @@ static void __devinit i5100_init_dimm_cs
 	}
 
 	/* only 2 chip selects per slot... */
-	priv->dimm_csmap[0][0] = 0;
-	priv->dimm_csmap[0][1] = 3;
-	priv->dimm_csmap[1][0] = 1;
-	priv->dimm_csmap[1][1] = 2;
-	priv->dimm_csmap[2][0] = 2;
-	priv->dimm_csmap[3][0] = 3;
+	if (priv->ranksperchan == 4) {
+		priv->dimm_csmap[0][0] = 0;
+		priv->dimm_csmap[0][1] = 3;
+		priv->dimm_csmap[1][0] = 1;
+		priv->dimm_csmap[1][1] = 2;
+		priv->dimm_csmap[2][0] = 2;
+		priv->dimm_csmap[3][0] = 3;
+	} else {
+		priv->dimm_csmap[0][0] = 0;
+		priv->dimm_csmap[0][1] = 1;
+		priv->dimm_csmap[1][0] = 2;
+		priv->dimm_csmap[1][1] = 3;
+		priv->dimm_csmap[2][0] = 4;
+		priv->dimm_csmap[2][1] = 5;
+	}
 }
 
 static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
@@ -677,10 +778,10 @@ static void __devinit i5100_init_dimm_la
 	struct i5100_priv *priv = mci->pvt_info;
 	int i;
 
-	for (i = 0; i < I5100_MAX_CTLRS; i++) {
+	for (i = 0; i < I5100_CHANNELS; i++) {
 		int j;
 
-		for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CTLR; j++) {
+		for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CHAN; j++) {
 			u8 rank;
 
 			if (i5100_read_spd_byte(mci, i, j, 5, &rank) < 0)
@@ -720,7 +821,7 @@ static void __devinit i5100_init_interle
 	pci_read_config_word(pdev, I5100_AMIR_1, &w);
 	priv->amir[1] = w;
 
-	for (i = 0; i < I5100_MAX_CTLRS; i++) {
+	for (i = 0; i < I5100_CHANNELS; i++) {
 		int j;
 
 		for (j = 0; j < 5; j++) {
@@ -747,7 +848,7 @@ static void __devinit i5100_init_csrows(
 
 	for (i = 0; i < mci->nr_csrows; i++) {
 		const unsigned long npages = i5100_npages(mci, i);
-		const unsigned cntlr = i5100_csrow_to_cntlr(mci, i);
+		const unsigned chan = i5100_csrow_to_chan(mci, i);
 		const unsigned rank = i5100_csrow_to_rank(mci, i);
 
 		if (!npages)
@@ -765,7 +866,7 @@ static void __devinit i5100_init_csrows(
 		mci->csrows[i].grain = 32;
 		mci->csrows[i].csrow_idx = i;
 		mci->csrows[i].dtype =
-			(priv->mtr[cntlr][rank].width == 4) ? DEV_X4 : DEV_X8;
+			(priv->mtr[chan][rank].width == 4) ? DEV_X4 : DEV_X8;
 		mci->csrows[i].ue_count = 0;
 		mci->csrows[i].ce_count = 0;
 		mci->csrows[i].mtype = MEM_RDDR2;
@@ -777,7 +878,7 @@ static void __devinit i5100_init_csrows(
 		mci->csrows[i].channels[0].csrow = mci->csrows + i;
 		snprintf(mci->csrows[i].channels[0].label,
 			 sizeof(mci->csrows[i].channels[0].label),
-			 "DIMM%u", i5100_rank_to_slot(mci, cntlr, rank));
+			 "DIMM%u", i5100_rank_to_slot(mci, chan, rank));
 
 		total_pages += npages;
 	}
@@ -815,13 +916,6 @@ static int __devinit i5100_init_one(stru
 	pci_read_config_dword(pdev, I5100_MS, &dw);
 	ranksperch = !!(dw & (1 << 8)) * 2 + 4;
 
-	if (ranksperch != 4) {
-		/* FIXME: get 6 ranks / controller to work - need hw... */
-		printk(KERN_INFO "i5100_edac: unsupported configuration.\n");
-		ret = -ENODEV;
-		goto bail_pdev;
-	}
-
 	/* enable error reporting... */
 	pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw);
 	dw &= ~I5100_FERR_NF_MEM_ANY_MASK;
@@ -864,11 +958,21 @@ static int __devinit i5100_init_one(stru
 	mci->dev = &pdev->dev;
 
 	priv = mci->pvt_info;
-	priv->ranksperctlr = ranksperch;
+	priv->ranksperchan = ranksperch;
 	priv->mc = pdev;
 	priv->ch0mm = ch0mm;
 	priv->ch1mm = ch1mm;
 
+	INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing);
+
+	/* If scrubbing was already enabled by the bios, start maintaining it */
+	pci_read_config_dword(pdev, I5100_MC, &dw);
+	if (i5100_mc_scrben(dw)) {
+		priv->scrub_enable = 1;
+		schedule_delayed_work(&(priv->i5100_scrubbing),
+				      I5100_SCRUB_REFRESH_RATE);
+	}
+
 	i5100_init_dimm_layout(pdev, mci);
 	i5100_init_interleaving(pdev, mci);
 
@@ -882,6 +986,8 @@ static int __devinit i5100_init_one(stru
 	mci->ctl_page_to_phys = NULL;
 
 	mci->edac_check = i5100_check_error;
+	mci->set_sdram_scrub_rate = i5100_set_scrub_rate;
+	mci->get_sdram_scrub_rate = i5100_get_scrub_rate;
 
 	i5100_init_csrows(mci);
 
@@ -897,12 +1003,14 @@ static int __devinit i5100_init_one(stru
 
 	if (edac_mc_add_mc(mci)) {
 		ret = -ENODEV;
-		goto bail_mc;
+		goto bail_scrub;
 	}
 
 	return ret;
 
-bail_mc:
+bail_scrub:
+	priv->scrub_enable = 0;
+	cancel_delayed_work_sync(&(priv->i5100_scrubbing));
 	edac_mc_free(mci);
 
 bail_disable_ch1:
@@ -935,6 +1043,10 @@ static void __devexit i5100_remove_one(s
 		return;
 
 	priv = mci->pvt_info;
+
+	priv->scrub_enable = 0;
+	cancel_delayed_work_sync(&(priv->i5100_scrubbing));
+
 	pci_disable_device(pdev);
 	pci_disable_device(priv->ch0mm);
 	pci_disable_device(priv->ch1mm);
diff -druNp linux-libre-2.6.32-gnu1/drivers/edac/mpc85xx_edac.c linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.c
--- linux-libre-2.6.32-gnu1/drivers/edac/mpc85xx_edac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/edac/mpc85xx_edac.c	2010-02-24 13:52:17.000000000 -0500
@@ -804,8 +804,8 @@ static void __devinit mpc85xx_init_csrow
 		end   <<= (24 - PAGE_SHIFT);
 		end    |= (1 << (24 - PAGE_SHIFT)) - 1;
 
-		csrow->first_page = start >> PAGE_SHIFT;
-		csrow->last_page = end >> PAGE_SHIFT;
+		csrow->first_page = start;
+		csrow->last_page = end;
 		csrow->nr_pages = end + 1 - start;
 		csrow->grain = 8;
 		csrow->mtype = mtype;
@@ -892,10 +892,6 @@ static int __devinit mpc85xx_mc_err_prob
 
 	mpc85xx_init_csrows(mci);
 
-#ifdef CONFIG_EDAC_DEBUG
-	edac_mc_register_mcidev_debug((struct attribute **)debug_attr);
-#endif
-
 	/* store the original error disable bits */
 	orig_ddr_err_disable =
 	    in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/core-card.c linux-libre-2.6.33-gnu1/drivers/firewire/core-card.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/core-card.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/core-card.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,15 +38,14 @@
 
 #include "core.h"
 
-int fw_compute_block_crc(u32 *block)
+int fw_compute_block_crc(__be32 *block)
 {
-	__be32 be32_block[256];
-	int i, length;
+	int length;
+	u16 crc;
 
-	length = (*block >> 16) & 0xff;
-	for (i = 0; i < length; i++)
-		be32_block[i] = cpu_to_be32(block[i + 1]);
-	*block |= crc_itu_t(0, (u8 *) be32_block, length * 4);
+	length = (be32_to_cpu(block[0]) >> 16) & 0xff;
+	crc = crc_itu_t(0, (u8 *)&block[1], length * 4);
+	*block |= cpu_to_be32(crc);
 
 	return length;
 }
@@ -57,6 +56,10 @@ static LIST_HEAD(card_list);
 static LIST_HEAD(descriptor_list);
 static int descriptor_count;
 
+static __be32 tmp_config_rom[256];
+/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
+static size_t config_rom_length = 1 + 4 + 1 + 1;
+
 #define BIB_CRC(v)		((v) <<  0)
 #define BIB_CRC_LENGTH(v)	((v) << 16)
 #define BIB_INFO_LENGTH(v)	((v) << 24)
@@ -72,11 +75,10 @@ static int descriptor_count;
 #define BIB_CMC			((1) << 30)
 #define BIB_IMC			((1) << 31)
 
-static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
+static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
 {
 	struct fw_descriptor *desc;
-	static u32 config_rom[256];
-	int i, j, length;
+	int i, j, k, length;
 
 	/*
 	 * Initialize contents of config rom buffer.  On the OHCI
@@ -87,40 +89,39 @@ static u32 *generate_config_rom(struct f
 	 * the version stored in the OHCI registers.
 	 */
 
-	memset(config_rom, 0, sizeof(config_rom));
-	config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0);
-	config_rom[1] = 0x31333934;
-
-	config_rom[2] =
+	config_rom[0] = cpu_to_be32(
+		BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
+	config_rom[1] = cpu_to_be32(0x31333934);
+	config_rom[2] = cpu_to_be32(
 		BIB_LINK_SPEED(card->link_speed) |
 		BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
 		BIB_MAX_ROM(2) |
 		BIB_MAX_RECEIVE(card->max_receive) |
-		BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC;
-	config_rom[3] = card->guid >> 32;
-	config_rom[4] = card->guid;
+		BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC);
+	config_rom[3] = cpu_to_be32(card->guid >> 32);
+	config_rom[4] = cpu_to_be32(card->guid);
 
 	/* Generate root directory. */
-	i = 5;
-	config_rom[i++] = 0;
-	config_rom[i++] = 0x0c0083c0; /* node capabilities */
-	j = i + descriptor_count;
+	config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */
+	i = 7;
+	j = 7 + descriptor_count;
 
 	/* Generate root directory entries for descriptors. */
 	list_for_each_entry (desc, &descriptor_list, link) {
 		if (desc->immediate > 0)
-			config_rom[i++] = desc->immediate;
-		config_rom[i] = desc->key | (j - i);
+			config_rom[i++] = cpu_to_be32(desc->immediate);
+		config_rom[i] = cpu_to_be32(desc->key | (j - i));
 		i++;
 		j += desc->length;
 	}
 
 	/* Update root directory length. */
-	config_rom[5] = (i - 5 - 1) << 16;
+	config_rom[5] = cpu_to_be32((i - 5 - 1) << 16);
 
 	/* End of root directory, now copy in descriptors. */
 	list_for_each_entry (desc, &descriptor_list, link) {
-		memcpy(&config_rom[i], desc->data, desc->length * 4);
+		for (k = 0; k < desc->length; k++)
+			config_rom[i + k] = cpu_to_be32(desc->data[k]);
 		i += desc->length;
 	}
 
@@ -131,26 +132,30 @@ static u32 *generate_config_rom(struct f
 	for (i = 0; i < j; i += length + 1)
 		length = fw_compute_block_crc(config_rom + i);
 
-	*config_rom_length = j;
-
-	return config_rom;
+	WARN_ON(j != config_rom_length);
 }
 
 static void update_config_roms(void)
 {
 	struct fw_card *card;
-	u32 *config_rom;
-	size_t length;
 
 	list_for_each_entry (card, &card_list, link) {
-		config_rom = generate_config_rom(card, &length);
-		card->driver->set_config_rom(card, config_rom, length);
+		generate_config_rom(card, tmp_config_rom);
+		card->driver->set_config_rom(card, tmp_config_rom,
+					     config_rom_length);
 	}
 }
 
+static size_t required_space(struct fw_descriptor *desc)
+{
+	/* descriptor + entry into root dir + optional immediate entry */
+	return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
+}
+
 int fw_core_add_descriptor(struct fw_descriptor *desc)
 {
 	size_t i;
+	int ret;
 
 	/*
 	 * Check descriptor is valid; the length of all blocks in the
@@ -166,15 +171,21 @@ int fw_core_add_descriptor(struct fw_des
 
 	mutex_lock(&card_mutex);
 
-	list_add_tail(&desc->link, &descriptor_list);
-	descriptor_count++;
-	if (desc->immediate > 0)
+	if (config_rom_length + required_space(desc) > 256) {
+		ret = -EBUSY;
+	} else {
+		list_add_tail(&desc->link, &descriptor_list);
+		config_rom_length += required_space(desc);
 		descriptor_count++;
-	update_config_roms();
+		if (desc->immediate > 0)
+			descriptor_count++;
+		update_config_roms();
+		ret = 0;
+	}
 
 	mutex_unlock(&card_mutex);
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(fw_core_add_descriptor);
 
@@ -183,6 +194,7 @@ void fw_core_remove_descriptor(struct fw
 	mutex_lock(&card_mutex);
 
 	list_del(&desc->link);
+	config_rom_length -= required_space(desc);
 	descriptor_count--;
 	if (desc->immediate > 0)
 		descriptor_count--;
@@ -211,11 +223,8 @@ static const char gap_count_table[] = {
 
 void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
 {
-	int scheduled;
-
 	fw_card_get(card);
-	scheduled = schedule_delayed_work(&card->work, delay);
-	if (!scheduled)
+	if (!schedule_delayed_work(&card->work, delay))
 		fw_card_put(card);
 }
 
@@ -435,8 +444,6 @@ EXPORT_SYMBOL(fw_card_initialize);
 int fw_card_add(struct fw_card *card,
 		u32 max_receive, u32 link_speed, u64 guid)
 {
-	u32 *config_rom;
-	size_t length;
 	int ret;
 
 	card->max_receive = max_receive;
@@ -445,8 +452,8 @@ int fw_card_add(struct fw_card *card,
 
 	mutex_lock(&card_mutex);
 
-	config_rom = generate_config_rom(card, &length);
-	ret = card->driver->enable(card, config_rom, length);
+	generate_config_rom(card, tmp_config_rom);
+	ret = card->driver->enable(card, tmp_config_rom, config_rom_length);
 	if (ret == 0)
 		list_add_tail(&card->link, &card_list);
 
@@ -465,7 +472,8 @@ EXPORT_SYMBOL(fw_card_add);
  * shutdown still need to be provided by the card driver.
  */
 
-static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static int dummy_enable(struct fw_card *card,
+			const __be32 *config_rom, size_t length)
 {
 	BUG();
 	return -1;
@@ -478,7 +486,7 @@ static int dummy_update_phy_reg(struct f
 }
 
 static int dummy_set_config_rom(struct fw_card *card,
-				u32 *config_rom, size_t length)
+				const __be32 *config_rom, size_t length)
 {
 	/*
 	 * We take the card out of card_list before setting the dummy
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/core-cdev.c linux-libre-2.6.33-gnu1/drivers/firewire/core-cdev.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/core-cdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/core-cdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
 #include <linux/preempt.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/string.h>
 #include <linux/time.h>
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
@@ -130,9 +131,22 @@ struct iso_resource {
 	struct iso_resource_event *e_alloc, *e_dealloc;
 };
 
-static void schedule_iso_resource(struct iso_resource *);
 static void release_iso_resource(struct client *, struct client_resource *);
 
+static void schedule_iso_resource(struct iso_resource *r, unsigned long delay)
+{
+	client_get(r->client);
+	if (!schedule_delayed_work(&r->work, delay))
+		client_put(r->client);
+}
+
+static void schedule_if_iso_resource(struct client_resource *resource)
+{
+	if (resource->release == release_iso_resource)
+		schedule_iso_resource(container_of(resource,
+					struct iso_resource, resource), 0);
+}
+
 /*
  * dequeue_event() just kfree()'s the event, so the event has to be
  * the first field in a struct XYZ_event.
@@ -166,7 +180,7 @@ struct iso_interrupt_event {
 
 struct iso_resource_event {
 	struct event event;
-	struct fw_cdev_event_iso_resource resource;
+	struct fw_cdev_event_iso_resource iso_resource;
 };
 
 static inline void __user *u64_to_uptr(__u64 value)
@@ -314,11 +328,8 @@ static void for_each_client(struct fw_de
 
 static int schedule_reallocations(int id, void *p, void *data)
 {
-	struct client_resource *r = p;
+	schedule_if_iso_resource(p);
 
-	if (r->release == release_iso_resource)
-		schedule_iso_resource(container_of(r,
-					struct iso_resource, resource));
 	return 0;
 }
 
@@ -414,9 +425,7 @@ static int add_client_resource(struct cl
 				  &resource->handle);
 	if (ret >= 0) {
 		client_get(client);
-		if (resource->release == release_iso_resource)
-			schedule_iso_resource(container_of(resource,
-						struct iso_resource, resource));
+		schedule_if_iso_resource(resource);
 	}
 	spin_unlock_irqrestore(&client->lock, flags);
 
@@ -428,26 +437,26 @@ static int add_client_resource(struct cl
 
 static int release_client_resource(struct client *client, u32 handle,
 				   client_resource_release_fn_t release,
-				   struct client_resource **resource)
+				   struct client_resource **return_resource)
 {
-	struct client_resource *r;
+	struct client_resource *resource;
 
 	spin_lock_irq(&client->lock);
 	if (client->in_shutdown)
-		r = NULL;
+		resource = NULL;
 	else
-		r = idr_find(&client->resource_idr, handle);
-	if (r && r->release == release)
+		resource = idr_find(&client->resource_idr, handle);
+	if (resource && resource->release == release)
 		idr_remove(&client->resource_idr, handle);
 	spin_unlock_irq(&client->lock);
 
-	if (!(r && r->release == release))
+	if (!(resource && resource->release == release))
 		return -EINVAL;
 
-	if (resource)
-		*resource = r;
+	if (return_resource)
+		*return_resource = resource;
 	else
-		r->release(client, r);
+		resource->release(client, resource);
 
 	client_put(client);
 
@@ -587,14 +596,22 @@ static int ioctl_send_request(struct cli
 			    client->device->max_speed);
 }
 
+static inline bool is_fcp_request(struct fw_request *request)
+{
+	return request == NULL;
+}
+
 static void release_request(struct client *client,
 			    struct client_resource *resource)
 {
 	struct inbound_transaction_resource *r = container_of(resource,
 			struct inbound_transaction_resource, resource);
 
-	fw_send_response(client->device->card, r->request,
-			 RCODE_CONFLICT_ERROR);
+	if (is_fcp_request(r->request))
+		kfree(r->data);
+	else
+		fw_send_response(client->device->card, r->request,
+				 RCODE_CONFLICT_ERROR);
 	kfree(r);
 }
 
@@ -607,6 +624,7 @@ static void handle_request(struct fw_car
 	struct address_handler_resource *handler = callback_data;
 	struct inbound_transaction_resource *r;
 	struct inbound_transaction_event *e;
+	void *fcp_frame = NULL;
 	int ret;
 
 	r = kmalloc(sizeof(*r), GFP_ATOMIC);
@@ -618,6 +636,18 @@ static void handle_request(struct fw_car
 	r->data    = payload;
 	r->length  = length;
 
+	if (is_fcp_request(request)) {
+		/*
+		 * FIXME: Let core-transaction.c manage a
+		 * single reference-counted copy?
+		 */
+		fcp_frame = kmemdup(payload, length, GFP_ATOMIC);
+		if (fcp_frame == NULL)
+			goto failed;
+
+		r->data = fcp_frame;
+	}
+
 	r->resource.release = release_request;
 	ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
 	if (ret < 0)
@@ -631,13 +661,16 @@ static void handle_request(struct fw_car
 	e->request.closure = handler->closure;
 
 	queue_event(handler->client, &e->event,
-		    &e->request, sizeof(e->request), payload, length);
+		    &e->request, sizeof(e->request), r->data, length);
 	return;
 
  failed:
 	kfree(r);
 	kfree(e);
-	fw_send_response(card, request, RCODE_CONFLICT_ERROR);
+	kfree(fcp_frame);
+
+	if (!is_fcp_request(request))
+		fw_send_response(card, request, RCODE_CONFLICT_ERROR);
 }
 
 static void release_address_handler(struct client *client,
@@ -699,6 +732,7 @@ static int ioctl_send_response(struct cl
 	struct fw_cdev_send_response *request = buffer;
 	struct client_resource *resource;
 	struct inbound_transaction_resource *r;
+	int ret = 0;
 
 	if (release_client_resource(client, request->handle,
 				    release_request, &resource) < 0)
@@ -706,15 +740,21 @@ static int ioctl_send_response(struct cl
 
 	r = container_of(resource, struct inbound_transaction_resource,
 			 resource);
+	if (is_fcp_request(r->request))
+		goto out;
+
 	if (request->length < r->length)
 		r->length = request->length;
-	if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
-		return -EFAULT;
-
+	if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) {
+		ret = -EFAULT;
+		kfree(r->request);
+		goto out;
+	}
 	fw_send_response(client->device->card, r->request, request->rcode);
+ out:
 	kfree(r);
 
-	return 0;
+	return ret;
 }
 
 static int ioctl_initiate_bus_reset(struct client *client, void *buffer)
@@ -1028,8 +1068,7 @@ static void iso_resource_work(struct wor
 	/* Allow 1000ms grace period for other reallocations. */
 	if (todo == ISO_RES_ALLOC &&
 	    time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
-		if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
-			client_get(client);
+		schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3));
 		skip = true;
 	} else {
 		/* We could be called twice within the same generation. */
@@ -1097,12 +1136,12 @@ static void iso_resource_work(struct wor
 		e = r->e_dealloc;
 		r->e_dealloc = NULL;
 	}
-	e->resource.handle	= r->resource.handle;
-	e->resource.channel	= channel;
-	e->resource.bandwidth	= bandwidth;
+	e->iso_resource.handle    = r->resource.handle;
+	e->iso_resource.channel   = channel;
+	e->iso_resource.bandwidth = bandwidth;
 
 	queue_event(client, &e->event,
-		    &e->resource, sizeof(e->resource), NULL, 0);
+		    &e->iso_resource, sizeof(e->iso_resource), NULL, 0);
 
 	if (free) {
 		cancel_delayed_work(&r->work);
@@ -1114,13 +1153,6 @@ static void iso_resource_work(struct wor
 	client_put(client);
 }
 
-static void schedule_iso_resource(struct iso_resource *r)
-{
-	client_get(r->client);
-	if (!schedule_delayed_work(&r->work, 0))
-		client_put(r->client);
-}
-
 static void release_iso_resource(struct client *client,
 				 struct client_resource *resource)
 {
@@ -1129,7 +1161,7 @@ static void release_iso_resource(struct
 
 	spin_lock_irq(&client->lock);
 	r->todo = ISO_RES_DEALLOC;
-	schedule_iso_resource(r);
+	schedule_iso_resource(r, 0);
 	spin_unlock_irq(&client->lock);
 }
 
@@ -1162,10 +1194,10 @@ static int init_iso_resource(struct clie
 	r->e_alloc	= e1;
 	r->e_dealloc	= e2;
 
-	e1->resource.closure	= request->closure;
-	e1->resource.type	= FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
-	e2->resource.closure	= request->closure;
-	e2->resource.type	= FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
+	e1->iso_resource.closure = request->closure;
+	e1->iso_resource.type    = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
+	e2->iso_resource.closure = request->closure;
+	e2->iso_resource.type    = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
 
 	if (todo == ISO_RES_ALLOC) {
 		r->resource.release = release_iso_resource;
@@ -1175,7 +1207,7 @@ static int init_iso_resource(struct clie
 	} else {
 		r->resource.release = NULL;
 		r->resource.handle = -1;
-		schedule_iso_resource(r);
+		schedule_iso_resource(r, 0);
 	}
 	request->handle = r->resource.handle;
 
@@ -1295,7 +1327,23 @@ static int (* const ioctl_handlers[])(st
 static int dispatch_ioctl(struct client *client,
 			  unsigned int cmd, void __user *arg)
 {
-	char buffer[256];
+	char buffer[sizeof(union {
+		struct fw_cdev_get_info			_00;
+		struct fw_cdev_send_request		_01;
+		struct fw_cdev_allocate			_02;
+		struct fw_cdev_deallocate		_03;
+		struct fw_cdev_send_response		_04;
+		struct fw_cdev_initiate_bus_reset	_05;
+		struct fw_cdev_add_descriptor		_06;
+		struct fw_cdev_remove_descriptor	_07;
+		struct fw_cdev_create_iso_context	_08;
+		struct fw_cdev_queue_iso		_09;
+		struct fw_cdev_start_iso		_0a;
+		struct fw_cdev_stop_iso			_0b;
+		struct fw_cdev_get_cycle_timer		_0c;
+		struct fw_cdev_allocate_iso_resource	_0d;
+		struct fw_cdev_send_stream_packet	_13;
+	})];
 	int ret;
 
 	if (_IOC_TYPE(cmd) != '#' ||
@@ -1390,10 +1438,10 @@ static int fw_device_op_mmap(struct file
 
 static int shutdown_resource(int id, void *p, void *data)
 {
-	struct client_resource *r = p;
+	struct client_resource *resource = p;
 	struct client *client = data;
 
-	r->release(client, r);
+	resource->release(client, resource);
 	client_put(client);
 
 	return 0;
@@ -1402,7 +1450,7 @@ static int shutdown_resource(int id, voi
 static int fw_device_op_release(struct inode *inode, struct file *file)
 {
 	struct client *client = file->private_data;
-	struct event *e, *next_e;
+	struct event *event, *next_event;
 
 	mutex_lock(&client->device->client_list_mutex);
 	list_del(&client->link);
@@ -1423,8 +1471,8 @@ static int fw_device_op_release(struct i
 	idr_remove_all(&client->resource_idr);
 	idr_destroy(&client->resource_idr);
 
-	list_for_each_entry_safe(e, next_e, &client->event_list, link)
-		kfree(e);
+	list_for_each_entry_safe(event, next_event, &client->event_list, link)
+		kfree(event);
 
 	client_put(client);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/core.h linux-libre-2.6.33-gnu1/drivers/firewire/core.h
--- linux-libre-2.6.32-gnu1/drivers/firewire/core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/core.h	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,8 @@ struct fw_card_driver {
 	 * enable the PHY or set the link_on bit and initiate a bus
 	 * reset.
 	 */
-	int (*enable)(struct fw_card *card, u32 *config_rom, size_t length);
+	int (*enable)(struct fw_card *card,
+		      const __be32 *config_rom, size_t length);
 
 	int (*update_phy_reg)(struct fw_card *card, int address,
 			      int clear_bits, int set_bits);
@@ -48,10 +49,10 @@ struct fw_card_driver {
 	/*
 	 * Update the config rom for an enabled card.  This function
 	 * should change the config rom that is presented on the bus
-	 * an initiate a bus reset.
+	 * and initiate a bus reset.
 	 */
 	int (*set_config_rom)(struct fw_card *card,
-			      u32 *config_rom, size_t length);
+			      const __be32 *config_rom, size_t length);
 
 	void (*send_request)(struct fw_card *card, struct fw_packet *packet);
 	void (*send_response)(struct fw_card *card, struct fw_packet *packet);
@@ -93,7 +94,7 @@ int fw_card_add(struct fw_card *card,
 		u32 max_receive, u32 link_speed, u64 guid);
 void fw_core_remove_card(struct fw_card *card);
 int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
-int fw_compute_block_crc(u32 *block);
+int fw_compute_block_crc(__be32 *block);
 void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
 
 static inline struct fw_card *fw_card_get(struct fw_card *card)
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/core-topology.c linux-libre-2.6.33-gnu1/drivers/firewire/core-topology.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/core-topology.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/core-topology.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,9 +28,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/string.h>
 
 #include <asm/atomic.h>
+#include <asm/byteorder.h>
 #include <asm/system.h>
 
 #include "core.h"
@@ -183,7 +183,7 @@ static inline struct fw_node *fw_node(st
  * This function builds the tree representation of the topology given
  * by the self IDs from the latest bus reset.  During the construction
  * of the tree, the function checks that the self IDs are valid and
- * internally consistent.  On succcess this function returns the
+ * internally consistent.  On success this function returns the
  * fw_node corresponding to the local card otherwise NULL.
  */
 static struct fw_node *build_tree(struct fw_card *card,
@@ -510,13 +510,16 @@ static void update_tree(struct fw_card *
 static void update_topology_map(struct fw_card *card,
 				u32 *self_ids, int self_id_count)
 {
-	int node_count;
+	int node_count = (card->root_node->node_id & 0x3f) + 1;
+	__be32 *map = card->topology_map;
+
+	*map++ = cpu_to_be32((self_id_count + 2) << 16);
+	*map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1);
+	*map++ = cpu_to_be32((node_count << 16) | self_id_count);
+
+	while (self_id_count--)
+		*map++ = cpu_to_be32p(self_ids++);
 
-	card->topology_map[1]++;
-	node_count = (card->root_node->node_id & 0x3f) + 1;
-	card->topology_map[2] = (node_count << 16) | self_id_count;
-	card->topology_map[0] = (self_id_count + 2) << 16;
-	memcpy(&card->topology_map[3], self_ids, self_id_count * 4);
 	fw_compute_block_crc(card->topology_map);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/core-transaction.c linux-libre-2.6.33-gnu1/drivers/firewire/core-transaction.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/core-transaction.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/core-transaction.c	2010-02-24 13:52:17.000000000 -0500
@@ -218,12 +218,15 @@ static void fw_fill_request(struct fw_pa
 		packet->header_length = 16;
 		packet->payload_length = 0;
 		break;
+
+	default:
+		WARN(1, KERN_ERR "wrong tcode %d", tcode);
 	}
  common:
 	packet->speed = speed;
 	packet->generation = generation;
 	packet->ack = 0;
-	packet->payload_bus = 0;
+	packet->payload_mapped = false;
 }
 
 /**
@@ -429,14 +432,20 @@ static struct fw_address_handler *lookup
 	return NULL;
 }
 
+static bool is_enclosing_handler(struct fw_address_handler *handler,
+				 unsigned long long offset, size_t length)
+{
+	return handler->offset <= offset &&
+		offset + length <= handler->offset + handler->length;
+}
+
 static struct fw_address_handler *lookup_enclosing_address_handler(
 	struct list_head *list, unsigned long long offset, size_t length)
 {
 	struct fw_address_handler *handler;
 
 	list_for_each_entry(handler, list, link) {
-		if (handler->offset <= offset &&
-		    offset + length <= handler->offset + handler->length)
+		if (is_enclosing_handler(handler, offset, length))
 			return handler;
 	}
 
@@ -462,6 +471,12 @@ const struct fw_address_region fw_unit_s
 	{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
 #endif  /*  0  */
 
+static bool is_in_fcp_region(u64 offset, size_t length)
+{
+	return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
+		offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
+}
+
 /**
  * fw_core_add_address_handler - register for incoming requests
  * @handler: callback
@@ -474,8 +489,11 @@ const struct fw_address_region fw_unit_s
  * give the details of the particular request.
  *
  * Return value:  0 on success, non-zero otherwise.
+ *
  * The start offset of the handler's address region is determined by
  * fw_core_add_address_handler() and is returned in handler->offset.
+ *
+ * Address allocations are exclusive, except for the FCP registers.
  */
 int fw_core_add_address_handler(struct fw_address_handler *handler,
 				const struct fw_address_region *region)
@@ -495,10 +513,12 @@ int fw_core_add_address_handler(struct f
 
 	handler->offset = region->start;
 	while (handler->offset + handler->length <= region->end) {
-		other =
-		    lookup_overlapping_address_handler(&address_handler_list,
-						       handler->offset,
-						       handler->length);
+		if (is_in_fcp_region(handler->offset, handler->length))
+			other = NULL;
+		else
+			other = lookup_overlapping_address_handler
+					(&address_handler_list,
+					 handler->offset, handler->length);
 		if (other != NULL) {
 			handler->offset += other->length;
 		} else {
@@ -595,11 +615,10 @@ void fw_fill_response(struct fw_packet *
 		break;
 
 	default:
-		BUG();
-		return;
+		WARN(1, KERN_ERR "wrong tcode %d", tcode);
 	}
 
-	response->payload_bus = 0;
+	response->payload_mapped = false;
 }
 EXPORT_SYMBOL(fw_fill_response);
 
@@ -666,6 +685,9 @@ static struct fw_request *allocate_reque
 void fw_send_response(struct fw_card *card,
 		      struct fw_request *request, int rcode)
 {
+	if (WARN_ONCE(!request, "invalid for FCP address handlers"))
+		return;
+
 	/* unified transaction or broadcast transaction: don't respond */
 	if (request->ack != ACK_PENDING ||
 	    HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
@@ -684,26 +706,15 @@ void fw_send_response(struct fw_card *ca
 }
 EXPORT_SYMBOL(fw_send_response);
 
-void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
+static void handle_exclusive_region_request(struct fw_card *card,
+					    struct fw_packet *p,
+					    struct fw_request *request,
+					    unsigned long long offset)
 {
 	struct fw_address_handler *handler;
-	struct fw_request *request;
-	unsigned long long offset;
 	unsigned long flags;
 	int tcode, destination, source;
 
-	if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
-		return;
-
-	request = allocate_request(p);
-	if (request == NULL) {
-		/* FIXME: send statically allocated busy packet. */
-		return;
-	}
-
-	offset      =
-		((unsigned long long)
-		 HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2];
 	tcode       = HEADER_GET_TCODE(p->header[0]);
 	destination = HEADER_GET_DESTINATION(p->header[0]);
 	source      = HEADER_GET_SOURCE(p->header[1]);
@@ -730,6 +741,73 @@ void fw_core_handle_request(struct fw_ca
 					  request->data, request->length,
 					  handler->callback_data);
 }
+
+static void handle_fcp_region_request(struct fw_card *card,
+				      struct fw_packet *p,
+				      struct fw_request *request,
+				      unsigned long long offset)
+{
+	struct fw_address_handler *handler;
+	unsigned long flags;
+	int tcode, destination, source;
+
+	if ((offset != (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
+	     offset != (CSR_REGISTER_BASE | CSR_FCP_RESPONSE)) ||
+	    request->length > 0x200) {
+		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+
+		return;
+	}
+
+	tcode       = HEADER_GET_TCODE(p->header[0]);
+	destination = HEADER_GET_DESTINATION(p->header[0]);
+	source      = HEADER_GET_SOURCE(p->header[1]);
+
+	if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
+	    tcode != TCODE_WRITE_BLOCK_REQUEST) {
+		fw_send_response(card, request, RCODE_TYPE_ERROR);
+
+		return;
+	}
+
+	spin_lock_irqsave(&address_handler_lock, flags);
+	list_for_each_entry(handler, &address_handler_list, link) {
+		if (is_enclosing_handler(handler, offset, request->length))
+			handler->address_callback(card, NULL, tcode,
+						  destination, source,
+						  p->generation, p->speed,
+						  offset, request->data,
+						  request->length,
+						  handler->callback_data);
+	}
+	spin_unlock_irqrestore(&address_handler_lock, flags);
+
+	fw_send_response(card, request, RCODE_COMPLETE);
+}
+
+void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
+{
+	struct fw_request *request;
+	unsigned long long offset;
+
+	if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
+		return;
+
+	request = allocate_request(p);
+	if (request == NULL) {
+		/* FIXME: send statically allocated busy packet. */
+		return;
+	}
+
+	offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) |
+		p->header[2];
+
+	if (!is_in_fcp_region(offset, request->length))
+		handle_exclusive_region_request(card, p, request, offset);
+	else
+		handle_fcp_region_request(card, p, request, offset);
+
+}
 EXPORT_SYMBOL(fw_core_handle_request);
 
 void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
@@ -810,8 +888,7 @@ static void handle_topology_map(struct f
 		int speed, unsigned long long offset,
 		void *payload, size_t length, void *callback_data)
 {
-	int i, start, end;
-	__be32 *map;
+	int start;
 
 	if (!TCODE_IS_READ_REQUEST(tcode)) {
 		fw_send_response(card, request, RCODE_TYPE_ERROR);
@@ -824,11 +901,7 @@ static void handle_topology_map(struct f
 	}
 
 	start = (offset - topology_map_region.start) / 4;
-	end = start + length / 4;
-	map = payload;
-
-	for (i = 0; i < length / 4; i++)
-		map[i] = cpu_to_be32(card->topology_map[start + i]);
+	memcpy(payload, &card->topology_map[start], length);
 
 	fw_send_response(card, request, RCODE_COMPLETE);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/Kconfig linux-libre-2.6.33-gnu1/drivers/firewire/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/firewire/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,10 @@
+menu "IEEE 1394 (FireWire) support"
+	depends on PCI || BROKEN
+	# firewire-core does not depend on PCI but is
+	# not useful without PCI controller driver
+
 comment "You can enable one or both FireWire driver stacks."
-comment "See the help texts for more information."
+comment "The newer stack is recommended."
 
 config FIREWIRE
 	tristate "FireWire driver stack"
@@ -15,16 +20,6 @@ config FIREWIRE
 	  To compile this driver as a module, say M here: the module will be
 	  called firewire-core.
 
-	  This module functionally replaces ieee1394, raw1394, and video1394.
-	  To access it from application programs, you generally need at least
-	  libraw1394 v2.  IIDC/DCAM applications need libdc1394 v2.
-	  No libraries are required to access storage devices through the
-	  firewire-sbp2 driver.
-
-	  NOTE:
-	  FireWire audio devices currently require the old drivers (ieee1394,
-	  ohci1394, raw1394).
-
 config FIREWIRE_OHCI
 	tristate "OHCI-1394 controllers"
 	depends on PCI && FIREWIRE
@@ -34,22 +29,7 @@ config FIREWIRE_OHCI
 	  is the only chipset in use, so say Y here.
 
 	  To compile this driver as a module, say M here:  The module will be
-	  called firewire-ohci.  It replaces ohci1394 of the classic IEEE 1394
-	  stack.
-
-	  NOTE:
-	  If you want to install firewire-ohci and ohci1394 together, you
-	  should configure them only as modules and blacklist the driver(s)
-	  which you don't want to have auto-loaded.  Add either
-
-	      blacklist firewire-ohci
-	  or
-	      blacklist ohci1394
-	      blacklist video1394
-	      blacklist dv1394
-
-	  to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
-	  depending on your distribution.
+	  called firewire-ohci.
 
 config FIREWIRE_OHCI_DEBUG
 	bool
@@ -66,8 +46,7 @@ config FIREWIRE_SBP2
 	  like scanners.
 
 	  To compile this driver as a module, say M here:  The module will be
-	  called firewire-sbp2.  It replaces sbp2 of the classic IEEE 1394
-	  stack.
+	  called firewire-sbp2.
 
 	  You should also enable support for disks, CD-ROMs, etc. in the SCSI
 	  configuration section.
@@ -83,5 +62,8 @@ config FIREWIRE_NET
 	  NOTE, this driver is not stable yet!
 
 	  To compile this driver as a module, say M here:  The module will be
-	  called firewire-net.  It replaces eth1394 of the classic IEEE 1394
-	  stack.
+	  called firewire-net.
+
+source "drivers/ieee1394/Kconfig"
+
+endmenu
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/net.c linux-libre-2.6.33-gnu1/drivers/firewire/net.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/net.c	2010-02-24 13:52:17.000000000 -0500
@@ -893,20 +893,31 @@ static void fwnet_receive_broadcast(stru
 
 static struct kmem_cache *fwnet_packet_task_cache;
 
+static void fwnet_free_ptask(struct fwnet_packet_task *ptask)
+{
+	dev_kfree_skb_any(ptask->skb);
+	kmem_cache_free(fwnet_packet_task_cache, ptask);
+}
+
 static int fwnet_send_packet(struct fwnet_packet_task *ptask);
 
 static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
 {
-	struct fwnet_device *dev;
+	struct fwnet_device *dev = ptask->dev;
 	unsigned long flags;
-
-	dev = ptask->dev;
+	bool free;
 
 	spin_lock_irqsave(&dev->lock, flags);
-	list_del(&ptask->pt_link);
-	spin_unlock_irqrestore(&dev->lock, flags);
 
-	ptask->outstanding_pkts--; /* FIXME access inside lock */
+	ptask->outstanding_pkts--;
+
+	/* Check whether we or the networking TX soft-IRQ is last user. */
+	free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link));
+
+	if (ptask->outstanding_pkts == 0)
+		list_del(&ptask->pt_link);
+
+	spin_unlock_irqrestore(&dev->lock, flags);
 
 	if (ptask->outstanding_pkts > 0) {
 		u16 dg_size;
@@ -951,10 +962,10 @@ static void fwnet_transmit_packet_done(s
 			ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE;
 		}
 		fwnet_send_packet(ptask);
-	} else {
-		dev_kfree_skb_any(ptask->skb);
-		kmem_cache_free(fwnet_packet_task_cache, ptask);
 	}
+
+	if (free)
+		fwnet_free_ptask(ptask);
 }
 
 static void fwnet_write_complete(struct fw_card *card, int rcode,
@@ -977,6 +988,7 @@ static int fwnet_send_packet(struct fwne
 	unsigned tx_len;
 	struct rfc2734_header *bufhdr;
 	unsigned long flags;
+	bool free;
 
 	dev = ptask->dev;
 	tx_len = ptask->max_payload;
@@ -1022,12 +1034,16 @@ static int fwnet_send_packet(struct fwne
 				generation, SCODE_100, 0ULL, ptask->skb->data,
 				tx_len + 8, fwnet_write_complete, ptask);
 
-		/* FIXME race? */
 		spin_lock_irqsave(&dev->lock, flags);
-		list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
+
+		/* If the AT tasklet already ran, we may be last user. */
+		free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+		if (!free)
+			list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
+
 		spin_unlock_irqrestore(&dev->lock, flags);
 
-		return 0;
+		goto out;
 	}
 
 	fw_send_request(dev->card, &ptask->transaction,
@@ -1035,12 +1051,19 @@ static int fwnet_send_packet(struct fwne
 			ptask->generation, ptask->speed, ptask->fifo_addr,
 			ptask->skb->data, tx_len, fwnet_write_complete, ptask);
 
-	/* FIXME race? */
 	spin_lock_irqsave(&dev->lock, flags);
-	list_add_tail(&ptask->pt_link, &dev->sent_list);
+
+	/* If the AT tasklet already ran, we may be last user. */
+	free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+	if (!free)
+		list_add_tail(&ptask->pt_link, &dev->sent_list);
+
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	dev->netdev->trans_start = jiffies;
+ out:
+	if (free)
+		fwnet_free_ptask(ptask);
 
 	return 0;
 }
@@ -1298,6 +1321,8 @@ static netdev_tx_t fwnet_tx(struct sk_bu
 	spin_unlock_irqrestore(&dev->lock, flags);
 
 	ptask->max_payload = max_payload;
+	INIT_LIST_HEAD(&ptask->pt_link);
+
 	fwnet_send_packet(ptask);
 
 	return NETDEV_TX_OK;
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/ohci.c linux-libre-2.6.33-gnu1/drivers/firewire/ohci.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/ohci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/ohci.c	2010-02-24 13:52:17.000000000 -0500
@@ -205,7 +205,7 @@ struct fw_ohci {
 	dma_addr_t config_rom_bus;
 	__be32 *next_config_rom;
 	dma_addr_t next_config_rom_bus;
-	u32 next_header;
+	__be32 next_header;
 
 	struct ar_context ar_request_ctx;
 	struct ar_context ar_response_ctx;
@@ -997,7 +997,8 @@ static int at_context_queue_packet(struc
 			packet->ack = RCODE_SEND_ERROR;
 			return -1;
 		}
-		packet->payload_bus = payload_bus;
+		packet->payload_bus	= payload_bus;
+		packet->payload_mapped	= true;
 
 		d[2].req_count    = cpu_to_le16(packet->payload_length);
 		d[2].data_address = cpu_to_le32(payload_bus);
@@ -1025,7 +1026,7 @@ static int at_context_queue_packet(struc
 	 */
 	if (ohci->generation != packet->generation ||
 	    reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
-		if (packet->payload_length > 0)
+		if (packet->payload_mapped)
 			dma_unmap_single(ohci->card.device, payload_bus,
 					 packet->payload_length, DMA_TO_DEVICE);
 		packet->ack = RCODE_GENERATION;
@@ -1061,7 +1062,7 @@ static int handle_at_packet(struct conte
 		/* This packet was cancelled, just continue. */
 		return 1;
 
-	if (packet->payload_bus)
+	if (packet->payload_mapped)
 		dma_unmap_single(ohci->card.device, packet->payload_bus,
 				 packet->payload_length, DMA_TO_DEVICE);
 
@@ -1357,8 +1358,9 @@ static void bus_reset_tasklet(unsigned l
 		 */
 		reg_write(ohci, OHCI1394_BusOptions,
 			  be32_to_cpu(ohci->config_rom[2]));
-		ohci->config_rom[0] = cpu_to_be32(ohci->next_header);
-		reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
+		ohci->config_rom[0] = ohci->next_header;
+		reg_write(ohci, OHCI1394_ConfigROMhdr,
+			  be32_to_cpu(ohci->next_header));
 	}
 
 #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
@@ -1477,7 +1479,17 @@ static int software_reset(struct fw_ohci
 	return -EBUSY;
 }
 
-static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length)
+{
+	size_t size = length * 4;
+
+	memcpy(dest, src, size);
+	if (size < CONFIG_ROM_SIZE)
+		memset(&dest[length], 0, CONFIG_ROM_SIZE - size);
+}
+
+static int ohci_enable(struct fw_card *card,
+		       const __be32 *config_rom, size_t length)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
 	struct pci_dev *dev = to_pci_dev(card->device);
@@ -1579,8 +1591,7 @@ static int ohci_enable(struct fw_card *c
 		if (ohci->next_config_rom == NULL)
 			return -ENOMEM;
 
-		memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
-		fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4);
+		copy_config_rom(ohci->next_config_rom, config_rom, length);
 	} else {
 		/*
 		 * In the suspend case, config_rom is NULL, which
@@ -1590,7 +1601,7 @@ static int ohci_enable(struct fw_card *c
 		ohci->next_config_rom_bus = ohci->config_rom_bus;
 	}
 
-	ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]);
+	ohci->next_header = ohci->next_config_rom[0];
 	ohci->next_config_rom[0] = 0;
 	reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
 	reg_write(ohci, OHCI1394_BusOptions,
@@ -1624,7 +1635,7 @@ static int ohci_enable(struct fw_card *c
 }
 
 static int ohci_set_config_rom(struct fw_card *card,
-			       u32 *config_rom, size_t length)
+			       const __be32 *config_rom, size_t length)
 {
 	struct fw_ohci *ohci;
 	unsigned long flags;
@@ -1673,9 +1684,7 @@ static int ohci_set_config_rom(struct fw
 		ohci->next_config_rom = next_config_rom;
 		ohci->next_config_rom_bus = next_config_rom_bus;
 
-		memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE);
-		fw_memcpy_to_be32(ohci->next_config_rom, config_rom,
-				  length * 4);
+		copy_config_rom(ohci->next_config_rom, config_rom, length);
 
 		ohci->next_header = config_rom[0];
 		ohci->next_config_rom[0] = 0;
@@ -1729,7 +1738,7 @@ static int ohci_cancel_packet(struct fw_
 	if (packet->ack != 0)
 		goto out;
 
-	if (packet->payload_bus)
+	if (packet->payload_mapped)
 		dma_unmap_single(ohci->card.device, packet->payload_bus,
 				 packet->payload_length, DMA_TO_DEVICE);
 
@@ -2092,11 +2101,6 @@ static int ohci_queue_iso_transmit(struc
 	u32 payload_index, payload_end_index, next_page_index;
 	int page, end_page, i, length, offset;
 
-	/*
-	 * FIXME: Cycle lost behavior should be configurable: lose
-	 * packet, retransmit or terminate..
-	 */
-
 	p = packet;
 	payload_index = payload;
 
@@ -2126,6 +2130,14 @@ static int ohci_queue_iso_transmit(struc
 	if (!p->skip) {
 		d[0].control   = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE);
 		d[0].req_count = cpu_to_le16(8);
+		/*
+		 * Link the skip address to this descriptor itself.  This causes
+		 * a context to skip a cycle whenever lost cycles or FIFO
+		 * overruns occur, without dropping the data.  The application
+		 * should then decide whether this is an error condition or not.
+		 * FIXME:  Make the context's cycle-lost behaviour configurable?
+		 */
+		d[0].branch_address = cpu_to_le32(d_bus | z);
 
 		header = (__le32 *) &d[1];
 		header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) |
@@ -2209,8 +2221,14 @@ static int ohci_queue_iso_receive_dualbu
 	page     = payload >> PAGE_SHIFT;
 	offset   = payload & ~PAGE_MASK;
 	rest     = p->payload_length;
+	/*
+	 * The controllers I've tested have not worked correctly when
+	 * second_req_count is zero.  Rather than do something we know won't
+	 * work, return an error
+	 */
+	if (rest == 0)
+		return -EINVAL;
 
-	/* FIXME: make packet-per-buffer/dual-buffer a context option */
 	while (rest > 0) {
 		d = context_get_descriptors(&ctx->context,
 					    z + header_z, &d_bus);
@@ -2262,7 +2280,7 @@ static int ohci_queue_iso_receive_packet
 					unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
-	struct descriptor *d = NULL, *pd = NULL;
+	struct descriptor *d, *pd;
 	struct fw_iso_packet *p = packet;
 	dma_addr_t d_bus, page_bus;
 	u32 z, header_z, rest;
@@ -2300,8 +2318,9 @@ static int ohci_queue_iso_receive_packet
 		d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
 
 		rest = payload_per_buffer;
+		pd = d;
 		for (j = 1; j < z; j++) {
-			pd = d + j;
+			pd++;
 			pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
 						  DESCRIPTOR_INPUT_MORE);
 
@@ -2404,6 +2423,7 @@ static void ohci_pmac_off(struct pci_dev
 
 #define PCI_VENDOR_ID_AGERE		PCI_VENDOR_ID_ATT
 #define PCI_DEVICE_ID_AGERE_FW643	0x5901
+#define PCI_DEVICE_ID_TI_TSB43AB23	0x8024
 
 static int __devinit pci_probe(struct pci_dev *dev,
 			       const struct pci_device_id *ent)
@@ -2453,7 +2473,10 @@ static int __devinit pci_probe(struct pc
 	}
 
 	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
+#if 0
+	/* FIXME: make it a context option or remove dual-buffer mode */
 	ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
+#endif
 
 	/* dual-buffer mode is broken if more than one IR context is active */
 	if (dev->vendor == PCI_VENDOR_ID_AGERE &&
@@ -2469,7 +2492,8 @@ static int __devinit pci_probe(struct pc
 #if !defined(CONFIG_X86_32)
 	/* dual-buffer mode is broken with descriptor addresses above 2G */
 	if (dev->vendor == PCI_VENDOR_ID_TI &&
-	    dev->device == PCI_DEVICE_ID_TI_TSB43AB22)
+	    (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 ||
+	     dev->device == PCI_DEVICE_ID_TI_TSB43AB23))
 		ohci->use_dualbuffer = false;
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/firewire/sbp2.c linux-libre-2.6.33-gnu1/drivers/firewire/sbp2.c
--- linux-libre-2.6.32-gnu1/drivers/firewire/sbp2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firewire/sbp2.c	2010-02-24 13:52:17.000000000 -0500
@@ -820,20 +820,25 @@ static void sbp2_release_target(struct k
 	fw_device_put(device);
 }
 
-static struct workqueue_struct *sbp2_wq;
+static void sbp2_target_get(struct sbp2_target *tgt)
+{
+	kref_get(&tgt->kref);
+}
 
 static void sbp2_target_put(struct sbp2_target *tgt)
 {
 	kref_put(&tgt->kref, sbp2_release_target);
 }
 
+static struct workqueue_struct *sbp2_wq;
+
 /*
  * Always get the target's kref when scheduling work on one its units.
  * Each workqueue job is responsible to call sbp2_target_put() upon return.
  */
 static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
 {
-	kref_get(&lu->tgt->kref);
+	sbp2_target_get(lu->tgt);
 	if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
 		sbp2_target_put(lu->tgt);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/firmware/dell_rbu.c linux-libre-2.6.33-gnu1/drivers/firmware/dell_rbu.c
--- linux-libre-2.6.32-gnu1/drivers/firmware/dell_rbu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firmware/dell_rbu.c	2010-02-24 13:52:17.000000000 -0500
@@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct
 {
 	rbu_data.entry_created = 0;
 
-	if (!fw || !fw->size)
+	if (!fw)
 		return;
 
+	if (!fw->size)
+		goto out;
+
 	spin_lock(&rbu_data.lock);
 	if (!strcmp(image_type, "mono")) {
 		if (!img_update_realloc(fw->size))
@@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct
 	} else
 		pr_debug("invalid image type specified.\n");
 	spin_unlock(&rbu_data.lock);
+ out:
+	release_firmware(fw);
 }
 
 static ssize_t read_rbu_image_type(struct kobject *kobj,
@@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(stru
 			spin_unlock(&rbu_data.lock);
 			req_firm_rc = request_firmware_nowait(THIS_MODULE,
 				FW_ACTION_NOHOTPLUG, "dell_rbu",
-				&rbu_device->dev, &context,
+				&rbu_device->dev, GFP_KERNEL, &context,
 				callbackfn_rbu);
 			if (req_firm_rc) {
 				printk(KERN_ERR
diff -druNp linux-libre-2.6.32-gnu1/drivers/firmware/dmi_scan.c linux-libre-2.6.33-gnu1/drivers/firmware/dmi_scan.c
--- linux-libre-2.6.32-gnu1/drivers/firmware/dmi_scan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firmware/dmi_scan.c	2010-02-24 13:52:17.000000000 -0500
@@ -169,10 +169,7 @@ static void __init dmi_save_uuid(const s
 	if (!s)
 		return;
 
-	sprintf(s,
-		"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
-		d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
-		d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+	sprintf(s, "%pUB", d);
 
         dmi_ident[slot] = s;
 }
@@ -429,7 +426,7 @@ static bool dmi_matches(const struct dmi
 	for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
 		int s = dmi->matches[i].slot;
 		if (s == DMI_NONE)
-			continue;
+			break;
 		if (dmi_ident[s]
 		    && strstr(dmi_ident[s], dmi->matches[i].substr))
 			continue;
@@ -440,6 +437,15 @@ static bool dmi_matches(const struct dmi
 }
 
 /**
+ *	dmi_is_end_of_table - check for end-of-table marker
+ *	@dmi: pointer to the dmi_system_id structure to check
+ */
+static bool dmi_is_end_of_table(const struct dmi_system_id *dmi)
+{
+	return dmi->matches[0].slot == DMI_NONE;
+}
+
+/**
  *	dmi_check_system - check system DMI data
  *	@list: array of dmi_system_id structures to match against
  *		All non-null elements of the list must match
@@ -457,7 +463,7 @@ int dmi_check_system(const struct dmi_sy
 	int count = 0;
 	const struct dmi_system_id *d;
 
-	for (d = list; d->ident; d++)
+	for (d = list; !dmi_is_end_of_table(d); d++)
 		if (dmi_matches(d)) {
 			count++;
 			if (d->callback && d->callback(d))
@@ -484,7 +490,7 @@ const struct dmi_system_id *dmi_first_ma
 {
 	const struct dmi_system_id *d;
 
-	for (d = list; d->ident; d++)
+	for (d = list; !dmi_is_end_of_table(d); d++)
 		if (dmi_matches(d))
 			return d;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/firmware/Kconfig linux-libre-2.6.33-gnu1/drivers/firmware/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/firmware/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/firmware/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -7,7 +7,7 @@ menu "Firmware Drivers"
 
 config EDD
 	tristate "BIOS Enhanced Disk Drive calls determine boot disk"
-	depends on !IA64
+	depends on X86
 	help
 	  Say Y or M here if you want to enable BIOS Enhanced Disk Drive
 	  Services real mode BIOS calls to determine which disk
@@ -28,7 +28,7 @@ config EDD_OFF
 
 config FIRMWARE_MEMMAP
     bool "Add firmware-provided memory map to sysfs" if EMBEDDED
-    default (X86_64 || X86_32)
+    default X86
     help
       Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap.
       That memory map is used for example by kexec to set up parameter area
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/adp5520-gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/adp5520-gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/adp5520-gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/adp5520-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,9 +34,9 @@ static int adp5520_gpio_get_value(struct
 	 */
 
 	if (test_bit(off, &dev->output))
-		adp5520_read(dev->master, GPIO_OUT, &reg_val);
+		adp5520_read(dev->master, ADP5520_GPIO_OUT, &reg_val);
 	else
-		adp5520_read(dev->master, GPIO_IN, &reg_val);
+		adp5520_read(dev->master, ADP5520_GPIO_IN, &reg_val);
 
 	return !!(reg_val & dev->lut[off]);
 }
@@ -48,9 +48,9 @@ static void adp5520_gpio_set_value(struc
 	dev = container_of(chip, struct adp5520_gpio, gpio_chip);
 
 	if (val)
-		adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
+		adp5520_set_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]);
 	else
-		adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
+		adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]);
 }
 
 static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
@@ -60,7 +60,8 @@ static int adp5520_gpio_direction_input(
 
 	clear_bit(off, &dev->output);
 
-	return adp5520_clr_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
+	return adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_2,
+				dev->lut[off]);
 }
 
 static int adp5520_gpio_direction_output(struct gpio_chip *chip,
@@ -73,18 +74,21 @@ static int adp5520_gpio_direction_output
 	set_bit(off, &dev->output);
 
 	if (val)
-		ret |= adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
+		ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_OUT,
+					dev->lut[off]);
 	else
-		ret |= adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
+		ret |= adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT,
+					dev->lut[off]);
 
-	ret |= adp5520_set_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
+	ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_2,
+					dev->lut[off]);
 
 	return ret;
 }
 
 static int __devinit adp5520_gpio_probe(struct platform_device *pdev)
 {
-	struct adp5520_gpio_platfrom_data *pdata = pdev->dev.platform_data;
+	struct adp5520_gpio_platform_data *pdata = pdev->dev.platform_data;
 	struct adp5520_gpio *dev;
 	struct gpio_chip *gc;
 	int ret, i, gpios;
@@ -129,20 +133,20 @@ static int __devinit adp5520_gpio_probe(
 	gc->label = pdev->name;
 	gc->owner = THIS_MODULE;
 
-	ret = adp5520_clr_bits(dev->master, GPIO_CFG_1,
+	ret = adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_1,
 		pdata->gpio_en_mask);
 
-	if (pdata->gpio_en_mask & GPIO_C3)
-		ctl_mask |= C3_MODE;
+	if (pdata->gpio_en_mask & ADP5520_GPIO_C3)
+		ctl_mask |= ADP5520_C3_MODE;
 
-	if (pdata->gpio_en_mask & GPIO_R3)
-		ctl_mask |= R3_MODE;
+	if (pdata->gpio_en_mask & ADP5520_GPIO_R3)
+		ctl_mask |= ADP5520_R3_MODE;
 
 	if (ctl_mask)
-		ret = adp5520_set_bits(dev->master, LED_CONTROL,
+		ret = adp5520_set_bits(dev->master, ADP5520_LED_CONTROL,
 			ctl_mask);
 
-	ret |= adp5520_set_bits(dev->master, GPIO_PULLUP,
+	ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP,
 		pdata->gpio_pullup_mask);
 
 	if (ret) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/adp5588-gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/adp5588-gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/adp5588-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/adp5588-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,266 @@
+/*
+ * GPIO Chip driver for Analog Devices
+ * ADP5588 I/O Expander and QWERTY Keypad Controller
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/adp5588.h>
+
+#define DRV_NAME		"adp5588-gpio"
+#define MAXGPIO			18
+#define ADP_BANK(offs)		((offs) >> 3)
+#define ADP_BIT(offs)		(1u << ((offs) & 0x7))
+
+struct adp5588_gpio {
+	struct i2c_client *client;
+	struct gpio_chip gpio_chip;
+	struct mutex lock;	/* protect cached dir, dat_out */
+	unsigned gpio_start;
+	uint8_t dat_out[3];
+	uint8_t dir[3];
+};
+
+static int adp5588_gpio_read(struct i2c_client *client, u8 reg)
+{
+	int ret = i2c_smbus_read_byte_data(client, reg);
+
+	if (ret < 0)
+		dev_err(&client->dev, "Read Error\n");
+
+	return ret;
+}
+
+static int adp5588_gpio_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret = i2c_smbus_write_byte_data(client, reg, val);
+
+	if (ret < 0)
+		dev_err(&client->dev, "Write Error\n");
+
+	return ret;
+}
+
+static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
+{
+	struct adp5588_gpio *dev =
+	    container_of(chip, struct adp5588_gpio, gpio_chip);
+
+	return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off))
+		  & ADP_BIT(off));
+}
+
+static void adp5588_gpio_set_value(struct gpio_chip *chip,
+				   unsigned off, int val)
+{
+	unsigned bank, bit;
+	struct adp5588_gpio *dev =
+	    container_of(chip, struct adp5588_gpio, gpio_chip);
+
+	bank = ADP_BANK(off);
+	bit = ADP_BIT(off);
+
+	mutex_lock(&dev->lock);
+	if (val)
+		dev->dat_out[bank] |= bit;
+	else
+		dev->dat_out[bank] &= ~bit;
+
+	adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank,
+			   dev->dat_out[bank]);
+	mutex_unlock(&dev->lock);
+}
+
+static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
+{
+	int ret;
+	unsigned bank;
+	struct adp5588_gpio *dev =
+	    container_of(chip, struct adp5588_gpio, gpio_chip);
+
+	bank = ADP_BANK(off);
+
+	mutex_lock(&dev->lock);
+	dev->dir[bank] &= ~ADP_BIT(off);
+	ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+static int adp5588_gpio_direction_output(struct gpio_chip *chip,
+					 unsigned off, int val)
+{
+	int ret;
+	unsigned bank, bit;
+	struct adp5588_gpio *dev =
+	    container_of(chip, struct adp5588_gpio, gpio_chip);
+
+	bank = ADP_BANK(off);
+	bit = ADP_BIT(off);
+
+	mutex_lock(&dev->lock);
+	dev->dir[bank] |= bit;
+
+	if (val)
+		dev->dat_out[bank] |= bit;
+	else
+		dev->dat_out[bank] &= ~bit;
+
+	ret = adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank,
+				 dev->dat_out[bank]);
+	ret |= adp5588_gpio_write(dev->client, GPIO_DIR1 + bank,
+				 dev->dir[bank]);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+static int __devinit adp5588_gpio_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
+	struct adp5588_gpio *dev;
+	struct gpio_chip *gc;
+	int ret, i, revid;
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "missing platform data\n");
+		return -ENODEV;
+	}
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
+		return -EIO;
+	}
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&client->dev, "failed to alloc memory\n");
+		return -ENOMEM;
+	}
+
+	dev->client = client;
+
+	gc = &dev->gpio_chip;
+	gc->direction_input = adp5588_gpio_direction_input;
+	gc->direction_output = adp5588_gpio_direction_output;
+	gc->get = adp5588_gpio_get_value;
+	gc->set = adp5588_gpio_set_value;
+	gc->can_sleep = 1;
+
+	gc->base = pdata->gpio_start;
+	gc->ngpio = MAXGPIO;
+	gc->label = client->name;
+	gc->owner = THIS_MODULE;
+
+	mutex_init(&dev->lock);
+
+
+	ret = adp5588_gpio_read(dev->client, DEV_ID);
+	if (ret < 0)
+		goto err;
+
+	revid = ret & ADP5588_DEVICE_ID_MASK;
+
+	for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) {
+		dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i);
+		dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i);
+		ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0);
+		ret |= adp5588_gpio_write(client, GPIO_PULL1 + i,
+				(pdata->pullup_dis_mask >> (8 * i)) & 0xFF);
+
+		if (ret)
+			goto err;
+	}
+
+	ret = gpiochip_add(&dev->gpio_chip);
+	if (ret)
+		goto err;
+
+	dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n",
+			gc->base, gc->base + gc->ngpio - 1,
+			client->name, revid);
+
+	if (pdata->setup) {
+		ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context);
+		if (ret < 0)
+			dev_warn(&client->dev, "setup failed, %d\n", ret);
+	}
+
+	i2c_set_clientdata(client, dev);
+	return 0;
+
+err:
+	kfree(dev);
+	return ret;
+}
+
+static int __devexit adp5588_gpio_remove(struct i2c_client *client)
+{
+	struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
+	struct adp5588_gpio *dev = i2c_get_clientdata(client);
+	int ret;
+
+	if (pdata->teardown) {
+		ret = pdata->teardown(client,
+				      dev->gpio_chip.base, dev->gpio_chip.ngpio,
+				      pdata->context);
+		if (ret < 0) {
+			dev_err(&client->dev, "teardown failed %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = gpiochip_remove(&dev->gpio_chip);
+	if (ret) {
+		dev_err(&client->dev, "gpiochip_remove failed %d\n", ret);
+		return ret;
+	}
+
+	kfree(dev);
+	return 0;
+}
+
+static const struct i2c_device_id adp5588_gpio_id[] = {
+	{DRV_NAME, 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, adp5588_gpio_id);
+
+static struct i2c_driver adp5588_gpio_driver = {
+	.driver = {
+		   .name = DRV_NAME,
+		   },
+	.probe = adp5588_gpio_probe,
+	.remove = __devexit_p(adp5588_gpio_remove),
+	.id_table = adp5588_gpio_id,
+};
+
+static int __init adp5588_gpio_init(void)
+{
+	return i2c_add_driver(&adp5588_gpio_driver);
+}
+
+module_init(adp5588_gpio_init);
+
+static void __exit adp5588_gpio_exit(void)
+{
+	i2c_del_driver(&adp5588_gpio_driver);
+}
+
+module_exit(adp5588_gpio_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("GPIO ADP5588 Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/cs5535-gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/cs5535-gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/cs5535-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/cs5535-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,355 @@
+/*
+ * AMD CS5535/CS5536 GPIO driver
+ * Copyright (C) 2006  Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009  Andres Salomon <dilinger@collabora.co.uk>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/cs5535.h>
+
+#define DRV_NAME "cs5535-gpio"
+#define GPIO_BAR 1
+
+/*
+ * Some GPIO pins
+ *  31-29,23 : reserved (always mask out)
+ *  28       : Power Button
+ *  26       : PME#
+ *  22-16    : LPC
+ *  14,15    : SMBus
+ *  9,8      : UART1
+ *  7        : PCI INTB
+ *  3,4      : UART2/DDC
+ *  2        : IDE_IRQ0
+ *  1        : AC_BEEP
+ *  0        : PCI INTA
+ *
+ * If a mask was not specified, allow all except
+ * reserved and Power Button
+ */
+#define GPIO_DEFAULT_MASK 0x0F7FFFFF
+
+static ulong mask = GPIO_DEFAULT_MASK;
+module_param_named(mask, mask, ulong, 0444);
+MODULE_PARM_DESC(mask, "GPIO channel mask.");
+
+static struct cs5535_gpio_chip {
+	struct gpio_chip chip;
+	resource_size_t base;
+
+	struct pci_dev *pdev;
+	spinlock_t lock;
+} cs5535_gpio_chip;
+
+/*
+ * The CS5535/CS5536 GPIOs support a number of extra features not defined
+ * by the gpio_chip API, so these are exported.  For a full list of the
+ * registers, see include/linux/cs5535.h.
+ */
+
+static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
+		unsigned int reg)
+{
+	if (offset < 16)
+		/* low bank register */
+		outl(1 << offset, chip->base + reg);
+	else
+		/* high bank register */
+		outl(1 << (offset - 16), chip->base + 0x80 + reg);
+}
+
+void cs5535_gpio_set(unsigned offset, unsigned int reg)
+{
+	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->lock, flags);
+	__cs5535_gpio_set(chip, offset, reg);
+	spin_unlock_irqrestore(&chip->lock, flags);
+}
+EXPORT_SYMBOL_GPL(cs5535_gpio_set);
+
+static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
+		unsigned int reg)
+{
+	if (offset < 16)
+		/* low bank register */
+		outl(1 << (offset + 16), chip->base + reg);
+	else
+		/* high bank register */
+		outl(1 << offset, chip->base + 0x80 + reg);
+}
+
+void cs5535_gpio_clear(unsigned offset, unsigned int reg)
+{
+	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->lock, flags);
+	__cs5535_gpio_clear(chip, offset, reg);
+	spin_unlock_irqrestore(&chip->lock, flags);
+}
+EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
+
+int cs5535_gpio_isset(unsigned offset, unsigned int reg)
+{
+	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
+	unsigned long flags;
+	long val;
+
+	spin_lock_irqsave(&chip->lock, flags);
+	if (offset < 16)
+		/* low bank register */
+		val = inl(chip->base + reg);
+	else {
+		/* high bank register */
+		val = inl(chip->base + 0x80 + reg);
+		offset -= 16;
+	}
+	spin_unlock_irqrestore(&chip->lock, flags);
+
+	return (val & (1 << offset)) ? 1 : 0;
+}
+EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
+
+/*
+ * Generic gpio_chip API support.
+ */
+
+static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
+{
+	struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->lock, flags);
+
+	/* check if this pin is available */
+	if ((mask & (1 << offset)) == 0) {
+		dev_info(&chip->pdev->dev,
+			"pin %u is not available (check mask)\n", offset);
+		spin_unlock_irqrestore(&chip->lock, flags);
+		return -EINVAL;
+	}
+
+	/* disable output aux 1 & 2 on this pin */
+	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
+	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
+
+	/* disable input aux 1 on this pin */
+	__cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
+
+	spin_unlock_irqrestore(&chip->lock, flags);
+
+	return 0;
+}
+
+static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
+}
+
+static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+	if (val)
+		cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
+	else
+		cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
+}
+
+static int chip_direction_input(struct gpio_chip *c, unsigned offset)
+{
+	struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->lock, flags);
+	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
+	return 0;
+}
+
+static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
+{
+	struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->lock, flags);
+
+	__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
+	if (val)
+		__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
+	else
+		__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
+
+	spin_unlock_irqrestore(&chip->lock, flags);
+
+	return 0;
+}
+
+static char *cs5535_gpio_names[] = {
+	"GPIO0", "GPIO1", "GPIO2", "GPIO3",
+	"GPIO4", "GPIO5", "GPIO6", "GPIO7",
+	"GPIO8", "GPIO9", "GPIO10", "GPIO11",
+	"GPIO12", "GPIO13", "GPIO14", "GPIO15",
+	"GPIO16", "GPIO17", "GPIO18", "GPIO19",
+	"GPIO20", "GPIO21", "GPIO22", NULL,
+	"GPIO24", "GPIO25", "GPIO26", "GPIO27",
+	"GPIO28", NULL, NULL, NULL,
+};
+
+static struct cs5535_gpio_chip cs5535_gpio_chip = {
+	.chip = {
+		.owner = THIS_MODULE,
+		.label = DRV_NAME,
+
+		.base = 0,
+		.ngpio = 32,
+		.names = cs5535_gpio_names,
+		.request = chip_gpio_request,
+
+		.get = chip_gpio_get,
+		.set = chip_gpio_set,
+
+		.direction_input = chip_direction_input,
+		.direction_output = chip_direction_output,
+	},
+};
+
+static int __init cs5535_gpio_probe(struct pci_dev *pdev,
+		const struct pci_device_id *pci_id)
+{
+	int err;
+	ulong mask_orig = mask;
+
+	/* There are two ways to get the GPIO base address; one is by
+	 * fetching it from MSR_LBAR_GPIO, the other is by reading the
+	 * PCI BAR info.  The latter method is easier (especially across
+	 * different architectures), so we'll stick with that for now.  If
+	 * it turns out to be unreliable in the face of crappy BIOSes, we
+	 * can always go back to using MSRs.. */
+
+	err = pci_enable_device_io(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "can't enable device IO\n");
+		goto done;
+	}
+
+	err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
+		goto done;
+	}
+
+	/* set up the driver-specific struct */
+	cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
+	cs5535_gpio_chip.pdev = pdev;
+	spin_lock_init(&cs5535_gpio_chip.lock);
+
+	dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
+			(unsigned long long) cs5535_gpio_chip.base);
+
+	/* mask out reserved pins */
+	mask &= 0x1F7FFFFF;
+
+	/* do not allow pin 28, Power Button, as there's special handling
+	 * in the PMC needed. (note 12, p. 48) */
+	mask &= ~(1 << 28);
+
+	if (mask_orig != mask)
+		dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
+				mask_orig, mask);
+
+	/* finally, register with the generic GPIO API */
+	err = gpiochip_add(&cs5535_gpio_chip.chip);
+	if (err)
+		goto release_region;
+
+	dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
+	return 0;
+
+release_region:
+	pci_release_region(pdev, GPIO_BAR);
+done:
+	return err;
+}
+
+static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
+{
+	int err;
+
+	err = gpiochip_remove(&cs5535_gpio_chip.chip);
+	if (err) {
+		/* uhh? */
+		dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
+	}
+	pci_release_region(pdev, GPIO_BAR);
+}
+
+static struct pci_device_id cs5535_gpio_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
+
+/*
+ * We can't use the standard PCI driver registration stuff here, since
+ * that allows only one driver to bind to each PCI device (and we want
+ * multiple drivers to be able to bind to the device).  Instead, manually
+ * scan for the PCI device, request a single region, and keep track of the
+ * devices that we're using.
+ */
+
+static int __init cs5535_gpio_scan_pci(void)
+{
+	struct pci_dev *pdev;
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
+		pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
+				cs5535_gpio_pci_tbl[i].device, NULL);
+		if (pdev) {
+			err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
+			if (err)
+				pci_dev_put(pdev);
+
+			/* we only support a single CS5535/6 southbridge */
+			break;
+		}
+	}
+
+	return err;
+}
+
+static void __exit cs5535_gpio_free_pci(void)
+{
+	cs5535_gpio_remove(cs5535_gpio_chip.pdev);
+	pci_dev_put(cs5535_gpio_chip.pdev);
+}
+
+static int __init cs5535_gpio_init(void)
+{
+	return cs5535_gpio_scan_pci();
+}
+
+static void __exit cs5535_gpio_exit(void)
+{
+	cs5535_gpio_free_pci();
+}
+
+module_init(cs5535_gpio_init);
+module_exit(cs5535_gpio_exit);
+
+MODULE_AUTHOR("Andres Salomon <dilinger@collabora.co.uk>");
+MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/gpiolib.c linux-libre-2.6.33-gnu1/drivers/gpio/gpiolib.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/gpiolib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/gpiolib.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,6 +53,7 @@ struct gpio_desc {
 #define FLAG_SYSFS	4	/* exported via /sys/class/gpio/control */
 #define FLAG_TRIG_FALL	5	/* trigger on falling edge */
 #define FLAG_TRIG_RISE	6	/* trigger on rising edge */
+#define FLAG_ACTIVE_LOW	7	/* sysfs value has active low */
 
 #define PDESC_ID_SHIFT	16	/* add new flags before this one */
 
@@ -210,6 +211,11 @@ static DEFINE_MUTEX(sysfs_lock);
  *      * configures behavior of poll(2) on /value
  *      * available only if pin can generate IRQs on input
  *      * is read/write as "none", "falling", "rising", or "both"
+ *   /active_low
+ *      * configures polarity of /value
+ *      * is read/write as zero/nonzero
+ *      * also affects existing and subsequent "falling" and "rising"
+ *        /edge configuration
  */
 
 static ssize_t gpio_direction_show(struct device *dev,
@@ -255,7 +261,7 @@ static ssize_t gpio_direction_store(stru
 	return status ? : size;
 }
 
-static const DEVICE_ATTR(direction, 0644,
+static /* const */ DEVICE_ATTR(direction, 0644,
 		gpio_direction_show, gpio_direction_store);
 
 static ssize_t gpio_value_show(struct device *dev,
@@ -267,10 +273,17 @@ static ssize_t gpio_value_show(struct de
 
 	mutex_lock(&sysfs_lock);
 
-	if (!test_bit(FLAG_EXPORT, &desc->flags))
+	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
 		status = -EIO;
-	else
-		status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio));
+	} else {
+		int value;
+
+		value = !!gpio_get_value_cansleep(gpio);
+		if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+			value = !value;
+
+		status = sprintf(buf, "%d\n", value);
+	}
 
 	mutex_unlock(&sysfs_lock);
 	return status;
@@ -294,6 +307,8 @@ static ssize_t gpio_value_store(struct d
 
 		status = strict_strtol(buf, 0, &value);
 		if (status == 0) {
+			if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+				value = !value;
 			gpio_set_value_cansleep(gpio, value != 0);
 			status = size;
 		}
@@ -303,7 +318,7 @@ static ssize_t gpio_value_store(struct d
 	return status;
 }
 
-static /*const*/ DEVICE_ATTR(value, 0644,
+static const DEVICE_ATTR(value, 0644,
 		gpio_value_show, gpio_value_store);
 
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
@@ -352,9 +367,11 @@ static int gpio_setup_irq(struct gpio_de
 
 	irq_flags = IRQF_SHARED;
 	if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
-		irq_flags |= IRQF_TRIGGER_FALLING;
+		irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
+			IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
 	if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
-		irq_flags |= IRQF_TRIGGER_RISING;
+		irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
+			IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
 
 	if (!pdesc) {
 		pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
@@ -475,9 +492,79 @@ found:
 
 static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
 
+static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
+				int value)
+{
+	int			status = 0;
+
+	if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
+		return 0;
+
+	if (value)
+		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+	else
+		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
+
+	/* reconfigure poll(2) support if enabled on one edge only */
+	if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^
+				!!test_bit(FLAG_TRIG_FALL, &desc->flags))) {
+		unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK;
+
+		gpio_setup_irq(desc, dev, 0);
+		status = gpio_setup_irq(desc, dev, trigger_flags);
+	}
+
+	return status;
+}
+
+static ssize_t gpio_active_low_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	const struct gpio_desc	*desc = dev_get_drvdata(dev);
+	ssize_t			status;
+
+	mutex_lock(&sysfs_lock);
+
+	if (!test_bit(FLAG_EXPORT, &desc->flags))
+		status = -EIO;
+	else
+		status = sprintf(buf, "%d\n",
+				!!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
+
+	mutex_unlock(&sysfs_lock);
+
+	return status;
+}
+
+static ssize_t gpio_active_low_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct gpio_desc	*desc = dev_get_drvdata(dev);
+	ssize_t			status;
+
+	mutex_lock(&sysfs_lock);
+
+	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
+		status = -EIO;
+	} else {
+		long		value;
+
+		status = strict_strtol(buf, 0, &value);
+		if (status == 0)
+			status = sysfs_set_active_low(desc, dev, value != 0);
+	}
+
+	mutex_unlock(&sysfs_lock);
+
+	return status ? : size;
+}
+
+static const DEVICE_ATTR(active_low, 0644,
+		gpio_active_low_show, gpio_active_low_store);
+
 static const struct attribute *gpio_attrs[] = {
-	&dev_attr_direction.attr,
 	&dev_attr_value.attr,
+	&dev_attr_active_low.attr,
 	NULL,
 };
 
@@ -662,12 +749,12 @@ int gpio_export(unsigned gpio, bool dire
 		dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
 				desc, ioname ? ioname : "gpio%d", gpio);
 		if (!IS_ERR(dev)) {
-			if (direction_may_change)
-				status = sysfs_create_group(&dev->kobj,
+			status = sysfs_create_group(&dev->kobj,
 						&gpio_attr_group);
-			else
+
+			if (!status && direction_may_change)
 				status = device_create_file(dev,
-						&dev_attr_value);
+						&dev_attr_direction);
 
 			if (!status && gpio_to_irq(gpio) >= 0
 					&& (direction_may_change
@@ -744,6 +831,53 @@ done:
 }
 EXPORT_SYMBOL_GPL(gpio_export_link);
 
+
+/**
+ * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value
+ * @gpio: gpio to change
+ * @value: non-zero to use active low, i.e. inverted values
+ *
+ * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute.
+ * The GPIO does not have to be exported yet.  If poll(2) support has
+ * been enabled for either rising or falling edge, it will be
+ * reconfigured to follow the new polarity.
+ *
+ * Returns zero on success, else an error.
+ */
+int gpio_sysfs_set_active_low(unsigned gpio, int value)
+{
+	struct gpio_desc	*desc;
+	struct device		*dev = NULL;
+	int			status = -EINVAL;
+
+	if (!gpio_is_valid(gpio))
+		goto done;
+
+	mutex_lock(&sysfs_lock);
+
+	desc = &gpio_desc[gpio];
+
+	if (test_bit(FLAG_EXPORT, &desc->flags)) {
+		dev = class_find_device(&gpio_class, NULL, desc, match_export);
+		if (dev == NULL) {
+			status = -ENODEV;
+			goto unlock;
+		}
+	}
+
+	status = sysfs_set_active_low(desc, dev, value);
+
+unlock:
+	mutex_unlock(&sysfs_lock);
+
+done:
+	if (status)
+		pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(gpio_sysfs_set_active_low);
+
 /**
  * gpio_unexport - reverse effect of gpio_export()
  * @gpio: gpio to make unavailable
@@ -1094,6 +1228,7 @@ void gpio_free(unsigned gpio)
 		}
 		desc_set_label(desc, NULL);
 		module_put(desc->chip->owner);
+		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
 		clear_bit(FLAG_REQUESTED, &desc->flags);
 	} else
 		WARN_ON(extra_checks);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/Kconfig linux-libre-2.6.33-gnu1/drivers/gpio/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/gpio/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -172,8 +172,27 @@ config GPIO_ADP5520
 	  To compile this driver as a module, choose M here: the module will
 	  be called adp5520-gpio.
 
+config GPIO_ADP5588
+	tristate "ADP5588 I2C GPIO expander"
+	depends on I2C
+	help
+	  This option enables support for 18 GPIOs found
+	  on Analog Devices ADP5588 GPIO Expanders.
+	  To compile this driver as a module, choose M here: the module will be
+	  called adp5588-gpio.
+
 comment "PCI GPIO expanders:"
 
+config GPIO_CS5535
+	tristate "AMD CS5535/CS5536 GPIO support"
+	depends on PCI && !CS5535_GPIO
+	help
+	  The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that
+	  can be used for quite a number of things.  The CS5535/6 is found on
+	  AMD Geode and Lemote Yeeloong devices.
+
+	  If unsure, say N.
+
 config GPIO_BT8XX
 	tristate "BT8XX GPIO abuser"
 	depends on PCI && VIDEO_BT848=n
@@ -196,6 +215,12 @@ config GPIO_LANGWELL
 	help
 	  Say Y here to support Intel Moorestown platform GPIO.
 
+config GPIO_TIMBERDALE
+	bool "Support for timberdale GPIO IP"
+	depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM
+	---help---
+	Add support for the GPIO IP in the timberdale FPGA.
+
 comment "SPI GPIO expanders:"
 
 config GPIO_MAX7301
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/langwell_gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/langwell_gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/langwell_gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/langwell_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,7 +123,7 @@ static int lnw_irq_type(unsigned irq, un
 	void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]);
 	void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]);
 
-	if (gpio < 0 || gpio > lnw->chip.ngpio)
+	if (gpio >= lnw->chip.ngpio)
 		return -EINVAL;
 	spin_lock_irqsave(&lnw->lock, flags);
 	if (type & IRQ_TYPE_EDGE_RISING)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/Makefile linux-libre-2.6.33-gnu1/drivers/gpio/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpio/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)	+= -DDEBUG
 obj-$(CONFIG_GPIOLIB)		+= gpiolib.o
 
 obj-$(CONFIG_GPIO_ADP5520)	+= adp5520-gpio.o
+obj-$(CONFIG_GPIO_ADP5588)	+= adp5588-gpio.o
 obj-$(CONFIG_GPIO_LANGWELL)	+= langwell_gpio.o
 obj-$(CONFIG_GPIO_MAX7301)	+= max7301.o
 obj-$(CONFIG_GPIO_MAX732X)	+= max732x.o
@@ -13,9 +14,11 @@ obj-$(CONFIG_GPIO_MCP23S08)	+= mcp23s08.
 obj-$(CONFIG_GPIO_PCA953X)	+= pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)	+= pcf857x.o
 obj-$(CONFIG_GPIO_PL061)	+= pl061.o
+obj-$(CONFIG_GPIO_TIMBERDALE)	+= timbgpio.o
 obj-$(CONFIG_GPIO_TWL4030)	+= twl4030-gpio.o
 obj-$(CONFIG_GPIO_UCB1400)	+= ucb1400_gpio.o
 obj-$(CONFIG_GPIO_XILINX)	+= xilinx_gpio.o
+obj-$(CONFIG_GPIO_CS5535)	+= cs5535-gpio.o
 obj-$(CONFIG_GPIO_BT8XX)	+= bt8xxgpio.o
 obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o
 obj-$(CONFIG_GPIO_WM831X)	+= wm831x-gpio.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/timbgpio.c linux-libre-2.6.33-gnu1/drivers/gpio/timbgpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/timbgpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/timbgpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,342 @@
+/*
+ * timbgpio.c timberdale FPGA GPIO driver
+ * Copyright (c) 2009 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ */
+
+/* Supports:
+ * Timberdale FPGA GPIO
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/timb_gpio.h>
+#include <linux/interrupt.h>
+
+#define DRIVER_NAME "timb-gpio"
+
+#define TGPIOVAL	0x00
+#define TGPIODIR	0x04
+#define TGPIO_IER	0x08
+#define TGPIO_ISR	0x0c
+#define TGPIO_IPR	0x10
+#define TGPIO_ICR	0x14
+#define TGPIO_FLR	0x18
+#define TGPIO_LVR	0x1c
+
+struct timbgpio {
+	void __iomem		*membase;
+	spinlock_t		lock; /* mutual exclusion */
+	struct gpio_chip	gpio;
+	int			irq_base;
+};
+
+static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
+	unsigned offset, bool enabled)
+{
+	struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
+	u32 reg;
+
+	spin_lock(&tgpio->lock);
+	reg = ioread32(tgpio->membase + offset);
+
+	if (enabled)
+		reg |= (1 << index);
+	else
+		reg &= ~(1 << index);
+
+	iowrite32(reg, tgpio->membase + offset);
+	spin_unlock(&tgpio->lock);
+
+	return 0;
+}
+
+static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
+{
+	return timbgpio_update_bit(gpio, nr, TGPIODIR, true);
+}
+
+static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
+{
+	struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
+	u32 value;
+
+	value = ioread32(tgpio->membase + TGPIOVAL);
+	return (value & (1 << nr)) ? 1 : 0;
+}
+
+static int timbgpio_gpio_direction_output(struct gpio_chip *gpio,
+						unsigned nr, int val)
+{
+	return timbgpio_update_bit(gpio, nr, TGPIODIR, false);
+}
+
+static void timbgpio_gpio_set(struct gpio_chip *gpio,
+				unsigned nr, int val)
+{
+	timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0);
+}
+
+static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
+{
+	struct timbgpio *tgpio = container_of(gpio, struct timbgpio, gpio);
+
+	if (tgpio->irq_base <= 0)
+		return -EINVAL;
+
+	return tgpio->irq_base + offset;
+}
+
+/*
+ * GPIO IRQ
+ */
+static void timbgpio_irq_disable(unsigned irq)
+{
+	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	int offset = irq - tgpio->irq_base;
+
+	timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 0);
+}
+
+static void timbgpio_irq_enable(unsigned irq)
+{
+	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	int offset = irq - tgpio->irq_base;
+
+	timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 1);
+}
+
+static int timbgpio_irq_type(unsigned irq, unsigned trigger)
+{
+	struct timbgpio *tgpio = get_irq_chip_data(irq);
+	int offset = irq - tgpio->irq_base;
+	unsigned long flags;
+	u32 lvr, flr;
+
+	if (offset < 0 || offset > tgpio->gpio.ngpio)
+		return -EINVAL;
+
+	spin_lock_irqsave(&tgpio->lock, flags);
+
+	lvr = ioread32(tgpio->membase + TGPIO_LVR);
+	flr = ioread32(tgpio->membase + TGPIO_FLR);
+
+	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+		flr &= ~(1 << offset);
+		if (trigger & IRQ_TYPE_LEVEL_HIGH)
+			lvr |= 1 << offset;
+		else
+			lvr &= ~(1 << offset);
+	}
+
+	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+		return -EINVAL;
+	else {
+		flr |= 1 << offset;
+		/* opposite compared to the datasheet, but it mirrors the
+		 * reality
+		 */
+		if (trigger & IRQ_TYPE_EDGE_FALLING)
+			lvr |= 1 << offset;
+		else
+			lvr &= ~(1 << offset);
+	}
+
+	iowrite32(lvr, tgpio->membase + TGPIO_LVR);
+	iowrite32(flr, tgpio->membase + TGPIO_FLR);
+	iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
+	spin_unlock_irqrestore(&tgpio->lock, flags);
+
+	return 0;
+}
+
+static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct timbgpio *tgpio = get_irq_data(irq);
+	unsigned long ipr;
+	int offset;
+
+	desc->chip->ack(irq);
+	ipr = ioread32(tgpio->membase + TGPIO_IPR);
+	iowrite32(ipr, tgpio->membase + TGPIO_ICR);
+
+	for_each_bit(offset, &ipr, tgpio->gpio.ngpio)
+		generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
+}
+
+static struct irq_chip timbgpio_irqchip = {
+	.name		= "GPIO",
+	.enable		= timbgpio_irq_enable,
+	.disable	= timbgpio_irq_disable,
+	.set_type	= timbgpio_irq_type,
+};
+
+static int __devinit timbgpio_probe(struct platform_device *pdev)
+{
+	int err, i;
+	struct gpio_chip *gc;
+	struct timbgpio *tgpio;
+	struct resource *iomem;
+	struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
+	int irq = platform_get_irq(pdev, 0);
+
+	if (!pdata || pdata->nr_pins > 32) {
+		err = -EINVAL;
+		goto err_mem;
+	}
+
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		err = -EINVAL;
+		goto err_mem;
+	}
+
+	tgpio = kzalloc(sizeof(*tgpio), GFP_KERNEL);
+	if (!tgpio) {
+		err = -EINVAL;
+		goto err_mem;
+	}
+	tgpio->irq_base = pdata->irq_base;
+
+	spin_lock_init(&tgpio->lock);
+
+	if (!request_mem_region(iomem->start, resource_size(iomem),
+		DRIVER_NAME)) {
+		err = -EBUSY;
+		goto err_request;
+	}
+
+	tgpio->membase = ioremap(iomem->start, resource_size(iomem));
+	if (!tgpio->membase) {
+		err = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	gc = &tgpio->gpio;
+
+	gc->label = dev_name(&pdev->dev);
+	gc->owner = THIS_MODULE;
+	gc->dev = &pdev->dev;
+	gc->direction_input = timbgpio_gpio_direction_input;
+	gc->get = timbgpio_gpio_get;
+	gc->direction_output = timbgpio_gpio_direction_output;
+	gc->set = timbgpio_gpio_set;
+	gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL;
+	gc->dbg_show = NULL;
+	gc->base = pdata->gpio_base;
+	gc->ngpio = pdata->nr_pins;
+	gc->can_sleep = 0;
+
+	err = gpiochip_add(gc);
+	if (err)
+		goto err_chipadd;
+
+	platform_set_drvdata(pdev, tgpio);
+
+	/* make sure to disable interrupts */
+	iowrite32(0x0, tgpio->membase + TGPIO_IER);
+
+	if (irq < 0 || tgpio->irq_base <= 0)
+		return 0;
+
+	for (i = 0; i < pdata->nr_pins; i++) {
+		set_irq_chip_and_handler_name(tgpio->irq_base + i,
+			&timbgpio_irqchip, handle_simple_irq, "mux");
+		set_irq_chip_data(tgpio->irq_base + i, tgpio);
+#ifdef CONFIG_ARM
+		set_irq_flags(tgpio->irq_base + i, IRQF_VALID | IRQF_PROBE);
+#endif
+	}
+
+	set_irq_data(irq, tgpio);
+	set_irq_chained_handler(irq, timbgpio_irq);
+
+	return 0;
+
+err_chipadd:
+	iounmap(tgpio->membase);
+err_ioremap:
+	release_mem_region(iomem->start, resource_size(iomem));
+err_request:
+	kfree(tgpio);
+err_mem:
+	printk(KERN_ERR DRIVER_NAME": Failed to register GPIOs: %d\n", err);
+
+	return err;
+}
+
+static int __devexit timbgpio_remove(struct platform_device *pdev)
+{
+	int err;
+	struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
+	struct timbgpio *tgpio = platform_get_drvdata(pdev);
+	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int irq = platform_get_irq(pdev, 0);
+
+	if (irq >= 0 && tgpio->irq_base > 0) {
+		int i;
+		for (i = 0; i < pdata->nr_pins; i++) {
+			set_irq_chip(tgpio->irq_base + i, NULL);
+			set_irq_chip_data(tgpio->irq_base + i, NULL);
+		}
+
+		set_irq_handler(irq, NULL);
+		set_irq_data(irq, NULL);
+	}
+
+	err = gpiochip_remove(&tgpio->gpio);
+	if (err)
+		printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n");
+
+	iounmap(tgpio->membase);
+	release_mem_region(iomem->start, resource_size(iomem));
+	kfree(tgpio);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver timbgpio_platform_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= timbgpio_probe,
+	.remove		= timbgpio_remove,
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int __init timbgpio_init(void)
+{
+	return platform_driver_register(&timbgpio_platform_driver);
+}
+
+static void __exit timbgpio_exit(void)
+{
+	platform_driver_unregister(&timbgpio_platform_driver);
+}
+
+module_init(timbgpio_init);
+module_exit(timbgpio_exit);
+
+MODULE_DESCRIPTION("Timberdale GPIO driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Mocean Laboratories");
+MODULE_ALIAS("platform:"DRIVER_NAME);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/twl4030-gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/twl4030-gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/twl4030-gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/twl4030-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
@@ -80,7 +80,7 @@ static unsigned int gpio_usage_count;
  */
 static inline int gpio_twl4030_write(u8 address, u8 data)
 {
-	return twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
+	return twl_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
 }
 
 /*----------------------------------------------------------------------*/
@@ -117,7 +117,7 @@ static inline int gpio_twl4030_read(u8 a
 	u8 data;
 	int ret = 0;
 
-	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
+	ret = twl_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
 	return (ret < 0) ? ret : data;
 }
 
@@ -142,7 +142,7 @@ static void twl4030_led_set_value(int le
 		cached_leden &= ~mask;
 	else
 		cached_leden |= mask;
-	status = twl4030_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
+	status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
 			TWL4030_LED_LEDEN);
 	mutex_unlock(&gpio_lock);
 }
@@ -223,23 +223,23 @@ static int twl_request(struct gpio_chip
 		}
 
 		/* initialize PWM to always-drive */
-		status = twl4030_i2c_write_u8(module, 0x7f,
+		status = twl_i2c_write_u8(module, 0x7f,
 				TWL4030_PWMx_PWMxOFF);
 		if (status < 0)
 			goto done;
-		status = twl4030_i2c_write_u8(module, 0x7f,
+		status = twl_i2c_write_u8(module, 0x7f,
 				TWL4030_PWMx_PWMxON);
 		if (status < 0)
 			goto done;
 
 		/* init LED to not-driven (high) */
 		module = TWL4030_MODULE_LED;
-		status = twl4030_i2c_read_u8(module, &cached_leden,
+		status = twl_i2c_read_u8(module, &cached_leden,
 				TWL4030_LED_LEDEN);
 		if (status < 0)
 			goto done;
 		cached_leden &= ~ledclr_mask;
-		status = twl4030_i2c_write_u8(module, cached_leden,
+		status = twl_i2c_write_u8(module, cached_leden,
 				TWL4030_LED_LEDEN);
 		if (status < 0)
 			goto done;
@@ -370,7 +370,7 @@ static int __devinit gpio_twl4030_pulls(
 		message[i] = bit_mask;
 	}
 
-	return twl4030_i2c_write(TWL4030_MODULE_GPIO, message,
+	return twl_i2c_write(TWL4030_MODULE_GPIO, message,
 				REG_GPIOPUPDCTR1, 5);
 }
 
@@ -387,7 +387,7 @@ static int __devinit gpio_twl4030_deboun
 	debounce >>= 8;
 	message[3] = (debounce & 0x03);
 
-	return twl4030_i2c_write(TWL4030_MODULE_GPIO, message,
+	return twl_i2c_write(TWL4030_MODULE_GPIO, message,
 				REG_GPIO_DEBEN1, 3);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpio/wm831x-gpio.c linux-libre-2.6.33-gnu1/drivers/gpio/wm831x-gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpio/wm831x-gpio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpio/wm831x-gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,8 +22,7 @@
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 #include <linux/mfd/wm831x/gpio.h>
-
-#define WM831X_GPIO_MAX 16
+#include <linux/mfd/wm831x/irq.h>
 
 struct wm831x_gpio {
 	struct wm831x *wm831x;
@@ -80,6 +79,17 @@ static void wm831x_gpio_set(struct gpio_
 			value << offset);
 }
 
+static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+
+	if (!wm831x->irq_base)
+		return -EINVAL;
+
+	return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset;
+}
+
 #ifdef CONFIG_DEBUG_FS
 static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
@@ -175,6 +185,7 @@ static struct gpio_chip template_chip =
 	.get			= wm831x_gpio_get,
 	.direction_output	= wm831x_gpio_direction_out,
 	.set			= wm831x_gpio_set,
+	.to_irq			= wm831x_gpio_to_irq,
 	.dbg_show		= wm831x_gpio_dbg_show,
 	.can_sleep		= 1,
 };
@@ -192,7 +203,7 @@ static int __devinit wm831x_gpio_probe(s
 
 	wm831x_gpio->wm831x = wm831x;
 	wm831x_gpio->gpio_chip = template_chip;
-	wm831x_gpio->gpio_chip.ngpio = WM831X_GPIO_MAX;
+	wm831x_gpio->gpio_chip.ngpio = wm831x->num_gpio;
 	wm831x_gpio->gpio_chip.dev = &pdev->dev;
 	if (pdata && pdata->gpio_base)
 		wm831x_gpio->gpio_chip.base = pdata->gpio_base;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ati_pcigart.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ati_pcigart.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ati_pcigart.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ati_pcigart.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,7 @@ static int drm_ati_alloc_pcigart_table(s
 				       struct drm_ati_pcigart_info *gart_info)
 {
 	gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
-						PAGE_SIZE,
-						gart_info->table_mask);
+						PAGE_SIZE);
 	if (gart_info->table_handle == NULL)
 		return -ENOMEM;
 
@@ -112,6 +111,13 @@ int drm_ati_pcigart_init(struct drm_devi
 	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
 		DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
 
+		if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) {
+			DRM_ERROR("fail to set dma mask to 0x%Lx\n",
+				  (unsigned long long)gart_info->table_mask);
+			ret = 1;
+			goto done;
+		}
+
 		ret = drm_ati_alloc_pcigart_table(dev, gart_info);
 		if (ret) {
 			DRM_ERROR("cannot allocate PCI GART page!\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_bufs.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_bufs.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_bufs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_bufs.c	2010-02-24 13:52:17.000000000 -0500
@@ -326,7 +326,7 @@ static int drm_addmap_core(struct drm_de
 		 * As we're limiting the address to 2^32-1 (or less),
 		 * casting it down to 32 bits is no problem, but we
 		 * need to point to a 64bit variable first. */
-		dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
+		dmah = drm_pci_alloc(dev, map->size, map->size);
 		if (!dmah) {
 			kfree(map);
 			return -ENOMEM;
@@ -885,7 +885,7 @@ int drm_addbufs_pci(struct drm_device *
 
 	while (entry->buf_count < count) {
 
-		dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful);
+		dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000);
 
 		if (!dmah) {
 			/* Set count correctly so we free the proper amount. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_crtc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_crtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -125,6 +125,15 @@ 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[] = {
+	{ DRM_MODE_DIRTY_OFF,      "Off"      },
+	{ DRM_MODE_DIRTY_ON,       "On"       },
+	{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
+};
+
+DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
+		 drm_dirty_info_enum_list)
+
 struct drm_conn_prop_enum_list {
 	int type;
 	char *name;
@@ -149,6 +158,7 @@ static struct drm_conn_prop_enum_list dr
 	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
 	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
 	{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
+	{ DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -247,7 +257,8 @@ static void drm_mode_object_put(struct d
 	mutex_unlock(&dev->mode_config.idr_mutex);
 }
 
-void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
+struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+		uint32_t id, uint32_t type)
 {
 	struct drm_mode_object *obj = NULL;
 
@@ -272,7 +283,7 @@ EXPORT_SYMBOL(drm_mode_object_find);
  * functions & device file and adds it to the master fd list.
  *
  * RETURNS:
- * Zero on success, error code on falure.
+ * Zero on success, error code on failure.
  */
 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
 			 const struct drm_framebuffer_funcs *funcs)
@@ -802,6 +813,36 @@ int drm_mode_create_dithering_property(s
 EXPORT_SYMBOL(drm_mode_create_dithering_property);
 
 /**
+ * drm_mode_create_dirty_property - create dirty property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ */
+int drm_mode_create_dirty_info_property(struct drm_device *dev)
+{
+	struct drm_property *dirty_info;
+	int i;
+
+	if (dev->mode_config.dirty_info_property)
+		return 0;
+
+	dirty_info =
+		drm_property_create(dev, DRM_MODE_PROP_ENUM |
+				    DRM_MODE_PROP_IMMUTABLE,
+				    "dirty",
+				    ARRAY_SIZE(drm_dirty_info_enum_list));
+	for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
+		drm_property_add_enum(dirty_info, i,
+				      drm_dirty_info_enum_list[i].type,
+				      drm_dirty_info_enum_list[i].name);
+	dev->mode_config.dirty_info_property = dirty_info;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
+
+/**
  * drm_mode_config_init - initialize DRM mode_configuration structure
  * @dev: DRM device
  *
@@ -1753,6 +1794,71 @@ out:
 	return ret;
 }
 
+int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv)
+{
+	struct drm_clip_rect __user *clips_ptr;
+	struct drm_clip_rect *clips = NULL;
+	struct drm_mode_fb_dirty_cmd *r = data;
+	struct drm_mode_object *obj;
+	struct drm_framebuffer *fb;
+	unsigned flags;
+	int num_clips;
+	int ret = 0;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
+	if (!obj) {
+		DRM_ERROR("invalid framebuffer id\n");
+		ret = -EINVAL;
+		goto out_err1;
+	}
+	fb = obj_to_fb(obj);
+
+	num_clips = r->num_clips;
+	clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
+
+	if (!num_clips != !clips_ptr) {
+		ret = -EINVAL;
+		goto out_err1;
+	}
+
+	flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
+
+	/* If userspace annotates copy, clips must come in pairs */
+	if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
+		ret = -EINVAL;
+		goto out_err1;
+	}
+
+	if (num_clips && clips_ptr) {
+		clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+		if (!clips) {
+			ret = -ENOMEM;
+			goto out_err1;
+		}
+
+		ret = copy_from_user(clips, clips_ptr,
+				     num_clips * sizeof(*clips));
+		if (ret)
+			goto out_err2;
+	}
+
+	if (fb->funcs->dirty) {
+		ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips);
+	} else {
+		ret = -ENOSYS;
+		goto out_err2;
+	}
+
+out_err2:
+	kfree(clips);
+out_err1:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+
 /**
  * drm_fb_release - remove and free the FBs on this file
  * @filp: file * from the ioctl
@@ -2328,7 +2434,7 @@ int drm_mode_connector_property_set_ioct
 	} else if (connector->funcs->set_property)
 		ret = connector->funcs->set_property(connector, property, out_resp->value);
 
-	/* store the property value if succesful */
+	/* store the property value if successful */
 	if (!ret)
 		drm_connector_property_set_value(connector, property, out_resp->value);
 out:
@@ -2477,4 +2583,73 @@ int drm_mode_gamma_get_ioctl(struct drm_
 out:
 	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
+}
+
+int drm_mode_page_flip_ioctl(struct drm_device *dev,
+			     void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_crtc_page_flip *page_flip = data;
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+	struct drm_pending_vblank_event *e = NULL;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
+	    page_flip->reserved != 0)
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj)
+		goto out;
+	crtc = obj_to_crtc(obj);
+
+	if (crtc->funcs->page_flip == NULL)
+		goto out;
+
+	obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB);
+	if (!obj)
+		goto out;
+	fb = obj_to_fb(obj);
+
+	if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+		ret = -ENOMEM;
+		spin_lock_irqsave(&dev->event_lock, flags);
+		if (file_priv->event_space < sizeof e->event) {
+			spin_unlock_irqrestore(&dev->event_lock, flags);
+			goto out;
+		}
+		file_priv->event_space -= sizeof e->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+
+		e = kzalloc(sizeof *e, GFP_KERNEL);
+		if (e == NULL) {
+			spin_lock_irqsave(&dev->event_lock, flags);
+			file_priv->event_space += sizeof e->event;
+			spin_unlock_irqrestore(&dev->event_lock, flags);
+			goto out;
+		}
+
+		e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
+		e->event.base.length = sizeof e->event;
+		e->event.user_data = page_flip->user_data;
+		e->base.event = &e->event.base;
+		e->base.file_priv = file_priv;
+		e->base.destroy =
+			(void (*) (struct drm_pending_event *)) kfree;
+	}
+
+	ret = crtc->funcs->page_flip(crtc, fb, e);
+	if (ret) {
+		spin_lock_irqsave(&dev->event_lock, flags);
+		file_priv->event_space += sizeof e->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(e);
+	}
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_crtc_helper.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc_helper.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,7 +109,7 @@ int drm_helper_probe_single_connector_mo
 
 	count = (*connector_funcs->get_modes)(connector);
 	if (!count) {
-		count = drm_add_modes_noedid(connector, 800, 600);
+		count = drm_add_modes_noedid(connector, 1024, 768);
 		if (!count)
 			return 0;
 	}
@@ -216,7 +216,7 @@ bool drm_helper_crtc_in_use(struct drm_c
 EXPORT_SYMBOL(drm_helper_crtc_in_use);
 
 /**
- * drm_disable_unused_functions - disable unused objects
+ * drm_helper_disable_unused_functions - disable unused objects
  * @dev: DRM device
  *
  * LOCKING:
@@ -702,7 +702,7 @@ bool drm_crtc_helper_set_mode(struct drm
 		if (encoder->crtc != crtc)
 			continue;
 
-		DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder),
+		DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder),
 			 mode->name, mode->base.id);
 		encoder_funcs = encoder->helper_private;
 		encoder_funcs->mode_set(encoder, mode, adjusted_mode);
@@ -1020,6 +1020,9 @@ bool drm_helper_initial_config(struct dr
 {
 	int count = 0;
 
+	/* disable all the possible outputs/crtcs before entering KMS mode */
+	drm_helper_disable_unused_functions(dev);
+
 	drm_fb_helper_parse_command_line(dev);
 
 	count = drm_helper_probe_connector_modes(dev,
@@ -1029,7 +1032,8 @@ bool drm_helper_initial_config(struct dr
 	/*
 	 * we shouldn't end up with no modes here.
 	 */
-	WARN(!count, "No connectors reported connected with modes\n");
+	if (count == 0)
+		printk(KERN_INFO "No connectors reported connected with modes\n");
 
 	drm_setup_crtcs(dev);
 
@@ -1159,6 +1163,9 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_st
 int drm_helper_resume_force_mode(struct drm_device *dev)
 {
 	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	struct drm_encoder_helper_funcs *encoder_funcs;
+	struct drm_crtc_helper_funcs *crtc_funcs;
 	int ret;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -1171,6 +1178,25 @@ int drm_helper_resume_force_mode(struct
 
 		if (ret == false)
 			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
+
+		/* Turn off outputs that were already powered off */
+		if (drm_helper_choose_crtc_dpms(crtc)) {
+			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+
+				if(encoder->crtc != crtc)
+					continue;
+
+				encoder_funcs = encoder->helper_private;
+				if (encoder_funcs->dpms)
+					(*encoder_funcs->dpms) (encoder,
+								drm_helper_choose_encoder_dpms(encoder));
+
+				crtc_funcs = crtc->helper_private;
+				if (crtc_funcs->dpms)
+					(*crtc_funcs->dpms) (crtc,
+							     drm_helper_choose_crtc_dpms(crtc));
+			}
+		}
 	}
 	/* disable the unused connectors while restoring the modesetting */
 	drm_helper_disable_unused_functions(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_dp_i2c_helper.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,209 @@
+/*
+ * Copyright © 2009 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, 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/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+#include "drm_dp_helper.h"
+#include "drmP.h"
+
+/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
+static int
+i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
+			    uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+	
+	ret = (*algo_data->aux_ch)(adapter, mode,
+				   write_byte, read_byte);
+	return ret;
+}
+
+/*
+ * I2C over AUX CH
+ */
+
+/*
+ * Send the address. If the I2C link is running, this 'restarts'
+ * the connection with the new address, this is used for doing
+ * a write followed by a read (as needed for DDC)
+ */
+static int
+i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int mode = MODE_I2C_START;
+	int ret;
+
+	if (reading)
+		mode |= MODE_I2C_READ;
+	else
+		mode |= MODE_I2C_WRITE;
+	algo_data->address = address;
+	algo_data->running = true;
+	ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+	return ret;
+}
+
+/*
+ * Stop the I2C transaction. This closes out the link, sending
+ * a bare address packet with the MOT bit turned off
+ */
+static void
+i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int mode = MODE_I2C_STOP;
+
+	if (reading)
+		mode |= MODE_I2C_READ;
+	else
+		mode |= MODE_I2C_WRITE;
+	if (algo_data->running) {
+		(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+		algo_data->running = false;
+	}
+}
+
+/*
+ * Write a single byte to the current I2C address, the
+ * the I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+
+	if (!algo_data->running)
+		return -EIO;
+
+	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
+	return ret;
+}
+
+/*
+ * Read a single byte from the current I2C address, the
+ * I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	int ret;
+
+	if (!algo_data->running)
+		return -EIO;
+
+	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
+	return ret;
+}
+
+static int
+i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
+		     struct i2c_msg *msgs,
+		     int num)
+{
+	int ret = 0;
+	bool reading = false;
+	int m;
+	int b;
+
+	for (m = 0; m < num; m++) {
+		u16 len = msgs[m].len;
+		u8 *buf = msgs[m].buf;
+		reading = (msgs[m].flags & I2C_M_RD) != 0;
+		ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
+		if (ret < 0)
+			break;
+		if (reading) {
+			for (b = 0; b < len; b++) {
+				ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
+				if (ret < 0)
+					break;
+			}
+		} else {
+			for (b = 0; b < len; b++) {
+				ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
+				if (ret < 0)
+					break;
+			}
+		}
+		if (ret < 0)
+			break;
+	}
+	if (ret >= 0)
+		ret = num;
+	i2c_algo_dp_aux_stop(adapter, reading);
+	DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
+	return ret;
+}
+
+static u32
+i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+	       I2C_FUNC_10BIT_ADDR;
+}
+
+static const struct i2c_algorithm i2c_dp_aux_algo = {
+	.master_xfer	= i2c_algo_dp_aux_xfer,
+	.functionality	= i2c_algo_dp_aux_functionality,
+};
+
+static void
+i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
+{
+	(void) i2c_algo_dp_aux_address(adapter, 0, false);
+	(void) i2c_algo_dp_aux_stop(adapter, false);
+					   
+}
+
+static int
+i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
+{
+	adapter->algo = &i2c_dp_aux_algo;
+	adapter->retries = 3;
+	i2c_dp_aux_reset_bus(adapter);
+	return 0;
+}
+
+int
+i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
+{
+	int error;
+	
+	error = i2c_dp_aux_prepare_bus(adapter);
+	if (error)
+		return error;
+	error = i2c_add_adapter(adapter);
+	return error;
+}
+EXPORT_SYMBOL(i2c_dp_aux_add_bus);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,6 +145,8 @@ static struct drm_ioctl_desc drm_ioctls[
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW)
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
@@ -366,6 +368,29 @@ module_init(drm_core_init);
 module_exit(drm_core_exit);
 
 /**
+ * Copy and IOCTL return string to user space
+ */
+static int drm_copy_field(char *buf, size_t *buf_len, const char *value)
+{
+	int len;
+
+	/* don't overflow userbuf */
+	len = strlen(value);
+	if (len > *buf_len)
+		len = *buf_len;
+
+	/* let userspace know exact length of driver value (which could be
+	 * larger than the userspace-supplied buffer) */
+	*buf_len = strlen(value);
+
+	/* finally, try filling in the userbuf */
+	if (len && buf)
+		if (copy_to_user(buf, value, len))
+			return -EFAULT;
+	return 0;
+}
+
+/**
  * Get version information
  *
  * \param inode device inode.
@@ -380,16 +405,21 @@ static int drm_version(struct drm_device
 		       struct drm_file *file_priv)
 {
 	struct drm_version *version = data;
-	int len;
+	int err;
 
 	version->version_major = dev->driver->major;
 	version->version_minor = dev->driver->minor;
 	version->version_patchlevel = dev->driver->patchlevel;
-	DRM_COPY(version->name, dev->driver->name);
-	DRM_COPY(version->date, dev->driver->date);
-	DRM_COPY(version->desc, dev->driver->desc);
+	err = drm_copy_field(version->name, &version->name_len,
+			dev->driver->name);
+	if (!err)
+		err = drm_copy_field(version->date, &version->date_len,
+				dev->driver->date);
+	if (!err)
+		err = drm_copy_field(version->desc, &version->desc_len,
+				dev->driver->desc);
 
-	return 0;
+	return err;
 }
 
 /**
@@ -404,11 +434,11 @@ static int drm_version(struct drm_device
  * Looks up the ioctl function in the ::ioctls table, checking for root
  * previleges if so required, and dispatches to the respective function.
  */
-int drm_ioctl(struct inode *inode, struct file *filp,
+long drm_ioctl(struct file *filp,
 	      unsigned int cmd, unsigned long arg)
 {
 	struct drm_file *file_priv = filp->private_data;
-	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_device *dev;
 	struct drm_ioctl_desc *ioctl;
 	drm_ioctl_t *func;
 	unsigned int nr = DRM_IOCTL_NR(cmd);
@@ -416,6 +446,7 @@ int drm_ioctl(struct inode *inode, struc
 	char stack_kdata[128];
 	char *kdata = NULL;
 
+	dev = file_priv->minor->dev;
 	atomic_inc(&dev->ioctl_count);
 	atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
 	++file_priv->ioctl_count;
@@ -471,7 +502,13 @@ int drm_ioctl(struct inode *inode, struc
 				goto err_i1;
 			}
 		}
-		retcode = func(dev, kdata, file_priv);
+		if (ioctl->flags & DRM_UNLOCKED)
+			retcode = func(dev, kdata, file_priv);
+		else {
+			lock_kernel();
+			retcode = func(dev, kdata, file_priv);
+			unlock_kernel();
+		}
 
 		if (cmd & IOC_OUT) {
 			if (copy_to_user((void __user *)arg, kdata,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_edid.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_edid.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_edid.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_edid.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,18 +123,20 @@ static const u8 edid_header[] = {
  */
 static bool edid_is_valid(struct edid *edid)
 {
-	int i;
+	int i, score = 0;
 	u8 csum = 0;
 	u8 *raw_edid = (u8 *)edid;
 
-	if (memcmp(edid->header, edid_header, sizeof(edid_header)))
-		goto bad;
-	if (edid->version != 1) {
-		DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
+	for (i = 0; i < sizeof(edid_header); i++)
+		if (raw_edid[i] == edid_header[i])
+			score++;
+
+	if (score == 8) ;
+	else if (score >= 6) {
+		DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
+		memcpy(raw_edid, edid_header, sizeof(edid_header));
+	} else
 		goto bad;
-	}
-	if (edid->revision > 4)
-		DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
 
 	for (i = 0; i < EDID_LENGTH; i++)
 		csum += raw_edid[i];
@@ -143,6 +145,14 @@ static bool edid_is_valid(struct edid *e
 		goto bad;
 	}
 
+	if (edid->version != 1) {
+		DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
+		goto bad;
+	}
+
+	if (edid->revision > 4)
+		DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
+
 	return 1;
 
 bad:
@@ -481,16 +491,17 @@ static struct drm_display_mode drm_dmt_m
 		   3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
 };
+static const int drm_num_dmt_modes =
+	sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 
 static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
 			int hsize, int vsize, int fresh)
 {
-	int i, count;
+	int i;
 	struct drm_display_mode *ptr, *mode;
 
-	count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 	mode = NULL;
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < drm_num_dmt_modes; i++) {
 		ptr = &drm_dmt_modes[i];
 		if (hsize == ptr->hdisplay &&
 			vsize == ptr->vdisplay &&
@@ -587,6 +598,50 @@ struct drm_display_mode *drm_mode_std(st
 	return mode;
 }
 
+/*
+ * EDID is delightfully ambiguous about how interlaced modes are to be
+ * encoded.  Our internal representation is of frame height, but some
+ * HDTV detailed timings are encoded as field height.
+ *
+ * The format list here is from CEA, in frame size.  Technically we
+ * should be checking refresh rate too.  Whatever.
+ */
+static void
+drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
+			    struct detailed_pixel_timing *pt)
+{
+	int i;
+	static const struct {
+		int w, h;
+	} cea_interlaced[] = {
+		{ 1920, 1080 },
+		{  720,  480 },
+		{ 1440,  480 },
+		{ 2880,  480 },
+		{  720,  576 },
+		{ 1440,  576 },
+		{ 2880,  576 },
+	};
+	static const int n_sizes =
+		sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
+
+	if (!(pt->misc & DRM_EDID_PT_INTERLACED))
+		return;
+
+	for (i = 0; i < n_sizes; i++) {
+		if ((mode->hdisplay == cea_interlaced[i].w) &&
+		    (mode->vdisplay == cea_interlaced[i].h / 2)) {
+			mode->vdisplay *= 2;
+			mode->vsync_start *= 2;
+			mode->vsync_end *= 2;
+			mode->vtotal *= 2;
+			mode->vtotal |= 1;
+		}
+	}
+
+	mode->flags |= DRM_MODE_FLAG_INTERLACE;
+}
+
 /**
  * drm_mode_detailed - create a new mode from an EDID detailed timing section
  * @dev: DRM device (needed to create new mode)
@@ -622,8 +677,7 @@ static struct drm_display_mode *drm_mode
 		return NULL;
 	}
 	if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
-		printk(KERN_WARNING "integrated sync not supported\n");
-		return NULL;
+		printk(KERN_WARNING "composite sync not supported\n");
 	}
 
 	/* it is incorrect if hsync/vsync width is zero */
@@ -670,8 +724,7 @@ static struct drm_display_mode *drm_mode
 
 	drm_mode_set_name(mode);
 
-	if (pt->misc & DRM_EDID_PT_INTERLACED)
-		mode->flags |= DRM_MODE_FLAG_INTERLACE;
+	drm_mode_do_interlace_quirk(mode, pt);
 
 	if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
 		pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
@@ -834,8 +887,169 @@ static int add_standard_modes(struct drm
 	return modes;
 }
 
+/*
+ * XXX fix this for:
+ * - GTF secondary curve formula
+ * - EDID 1.4 range offsets
+ * - CVT extended bits
+ */
+static bool
+mode_in_range(struct drm_display_mode *mode, struct detailed_timing *timing)
+{
+	struct detailed_data_monitor_range *range;
+	int hsync, vrefresh;
+
+	range = &timing->data.other_data.data.range;
+
+	hsync = drm_mode_hsync(mode);
+	vrefresh = drm_mode_vrefresh(mode);
+
+	if (hsync < range->min_hfreq_khz || hsync > range->max_hfreq_khz)
+		return false;
+
+	if (vrefresh < range->min_vfreq || vrefresh > range->max_vfreq)
+		return false;
+
+	if (range->pixel_clock_mhz && range->pixel_clock_mhz != 0xff) {
+		/* be forgiving since it's in units of 10MHz */
+		int max_clock = range->pixel_clock_mhz * 10 + 9;
+		max_clock *= 1000;
+		if (mode->clock > max_clock)
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will
+ * need to account for them.
+ */
+static int drm_gtf_modes_for_range(struct drm_connector *connector,
+				   struct detailed_timing *timing)
+{
+	int i, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	for (i = 0; i < drm_num_dmt_modes; i++) {
+		if (mode_in_range(drm_dmt_modes + i, timing)) {
+			newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+	}
+
+	return modes;
+}
+
+static int drm_cvt_modes(struct drm_connector *connector,
+			 struct detailed_timing *timing)
+{
+	int i, j, modes = 0;
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+	struct cvt_timing *cvt;
+	const int rates[] = { 60, 85, 75, 60, 50 };
+	const u8 empty[3] = { 0, 0, 0 };
+
+	for (i = 0; i < 4; i++) {
+		int uninitialized_var(width), height;
+		cvt = &(timing->data.other_data.data.cvt[i]);
+
+		if (!memcmp(cvt->code, empty, 3))
+			continue;
+
+		height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2;
+		switch (cvt->code[1] & 0x0c) {
+		case 0x00:
+			width = height * 4 / 3;
+			break;
+		case 0x04:
+			width = height * 16 / 9;
+			break;
+		case 0x08:
+			width = height * 16 / 10;
+			break;
+		case 0x0c:
+			width = height * 15 / 9;
+			break;
+		}
+
+		for (j = 1; j < 5; j++) {
+			if (cvt->code[2] & (1 << j)) {
+				newmode = drm_cvt_mode(dev, width, height,
+						       rates[j], j == 0,
+						       false, false);
+				if (newmode) {
+					drm_mode_probed_add(connector, newmode);
+					modes++;
+				}
+			}
+		}
+	}
+
+	return modes;
+}
+
+static int add_detailed_modes(struct drm_connector *connector,
+			      struct detailed_timing *timing,
+			      struct edid *edid, u32 quirks, int preferred)
+{
+	int i, modes = 0;
+	struct detailed_non_pixel *data = &timing->data.other_data;
+	int timing_level = standard_timing_level(edid);
+	int gtf = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
+	struct drm_display_mode *newmode;
+	struct drm_device *dev = connector->dev;
+
+	if (timing->pixel_clock) {
+		newmode = drm_mode_detailed(dev, edid, timing, quirks);
+		if (!newmode)
+			return 0;
+
+		if (preferred)
+			newmode->type |= DRM_MODE_TYPE_PREFERRED;
+
+		drm_mode_probed_add(connector, newmode);
+		return 1;
+	}
+
+	/* other timing types */
+	switch (data->type) {
+	case EDID_DETAIL_MONITOR_RANGE:
+		if (gtf)
+			modes += drm_gtf_modes_for_range(connector, timing);
+		break;
+	case EDID_DETAIL_STD_MODES:
+		/* Six modes per detailed section */
+		for (i = 0; i < 6; i++) {
+			struct std_timing *std;
+			struct drm_display_mode *newmode;
+
+			std = &data->data.timings[i];
+			newmode = drm_mode_std(dev, std, edid->revision,
+					       timing_level);
+			if (newmode) {
+				drm_mode_probed_add(connector, newmode);
+				modes++;
+			}
+		}
+		break;
+	case EDID_DETAIL_CVT_3BYTE:
+		modes += drm_cvt_modes(connector, timing);
+		break;
+	default:
+		break;
+	}
+
+	return modes;
+}
+
 /**
- * add_detailed_modes - get detailed mode info from EDID data
+ * add_detailed_info - get detailed mode info from EDID data
  * @connector: attached connector
  * @edid: EDID block to scan
  * @quirks: quirks to apply
@@ -846,67 +1060,24 @@ static int add_standard_modes(struct drm
 static int add_detailed_info(struct drm_connector *connector,
 			     struct edid *edid, u32 quirks)
 {
-	struct drm_device *dev = connector->dev;
-	int i, j, modes = 0;
-	int timing_level;
-
-	timing_level = standard_timing_level(edid);
+	int i, modes = 0;
 
 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
 		struct detailed_timing *timing = &edid->detailed_timings[i];
-		struct detailed_non_pixel *data = &timing->data.other_data;
-		struct drm_display_mode *newmode;
-
-		/* X server check is version 1.1 or higher */
-		if (edid->version == 1 && edid->revision >= 1 &&
-		    !timing->pixel_clock) {
-			/* Other timing or info */
-			switch (data->type) {
-			case EDID_DETAIL_MONITOR_SERIAL:
-				break;
-			case EDID_DETAIL_MONITOR_STRING:
-				break;
-			case EDID_DETAIL_MONITOR_RANGE:
-				/* Get monitor range data */
-				break;
-			case EDID_DETAIL_MONITOR_NAME:
-				break;
-			case EDID_DETAIL_MONITOR_CPDATA:
-				break;
-			case EDID_DETAIL_STD_MODES:
-				for (j = 0; j < 6; i++) {
-					struct std_timing *std;
-					struct drm_display_mode *newmode;
-
-					std = &data->data.timings[j];
-					newmode = drm_mode_std(dev, std,
-							       edid->revision,
-							       timing_level);
-					if (newmode) {
-						drm_mode_probed_add(connector, newmode);
-						modes++;
-					}
-				}
-				break;
-			default:
-				break;
-			}
-		} else {
-			newmode = drm_mode_detailed(dev, edid, timing, quirks);
-			if (!newmode)
-				continue;
+		int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
 
-			/* First detailed mode is preferred */
-			if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING))
-				newmode->type |= DRM_MODE_TYPE_PREFERRED;
-			drm_mode_probed_add(connector, newmode);
+		/* In 1.0, only timings are allowed */
+		if (!timing->pixel_clock && edid->version == 1 &&
+			edid->revision == 0)
+			continue;
 
-			modes++;
-		}
+		modes += add_detailed_modes(connector, timing, edid, quirks,
+					    preferred);
 	}
 
 	return modes;
 }
+
 /**
  * add_detailed_mode_eedid - get detailed mode info from addtional timing
  * 			EDID block
@@ -920,12 +1091,9 @@ static int add_detailed_info(struct drm_
 static int add_detailed_info_eedid(struct drm_connector *connector,
 			     struct edid *edid, u32 quirks)
 {
-	struct drm_device *dev = connector->dev;
-	int i, j, modes = 0;
+	int i, modes = 0;
 	char *edid_ext = NULL;
 	struct detailed_timing *timing;
-	struct detailed_non_pixel *data;
-	struct drm_display_mode *newmode;
 	int edid_ext_num;
 	int start_offset, end_offset;
 	int timing_level;
@@ -976,51 +1144,7 @@ static int add_detailed_info_eedid(struc
 	for (i = start_offset; i < end_offset;
 			i += sizeof(struct detailed_timing)) {
 		timing = (struct detailed_timing *)(edid_ext + i);
-		data = &timing->data.other_data;
-		/* Detailed mode timing */
-		if (timing->pixel_clock) {
-			newmode = drm_mode_detailed(dev, edid, timing, quirks);
-			if (!newmode)
-				continue;
-
-			drm_mode_probed_add(connector, newmode);
-
-			modes++;
-			continue;
-		}
-
-		/* Other timing or info */
-		switch (data->type) {
-		case EDID_DETAIL_MONITOR_SERIAL:
-			break;
-		case EDID_DETAIL_MONITOR_STRING:
-			break;
-		case EDID_DETAIL_MONITOR_RANGE:
-			/* Get monitor range data */
-			break;
-		case EDID_DETAIL_MONITOR_NAME:
-			break;
-		case EDID_DETAIL_MONITOR_CPDATA:
-			break;
-		case EDID_DETAIL_STD_MODES:
-			/* Five modes per detailed section */
-			for (j = 0; j < 5; i++) {
-				struct std_timing *std;
-				struct drm_display_mode *newmode;
-
-				std = &data->data.timings[j];
-				newmode = drm_mode_std(dev, std,
-						       edid->revision,
-						       timing_level);
-				if (newmode) {
-					drm_mode_probed_add(connector, newmode);
-					modes++;
-				}
-			}
-			break;
-		default:
-			break;
-		}
+		modes += add_detailed_modes(connector, timing, edid, quirks, 0);
 	}
 
 	return modes;
@@ -1066,19 +1190,19 @@ static int drm_ddc_read_edid(struct drm_
 			     struct i2c_adapter *adapter,
 			     char *buf, int len)
 {
-	int ret;
+	int i;
 
-	ret = drm_do_probe_ddc_edid(adapter, buf, len);
-	if (ret != 0) {
-		goto end;
-	}
-	if (!edid_is_valid((struct edid *)buf)) {
-		dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
-			 drm_get_connector_name(connector));
-		ret = -1;
+	for (i = 0; i < 4; i++) {
+		if (drm_do_probe_ddc_edid(adapter, buf, len))
+			return -1;
+		if (edid_is_valid((struct edid *)buf))
+			return 0;
 	}
-end:
-	return ret;
+
+	/* repeated checksum failures; warn, but carry on */
+	dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+		 drm_get_connector_name(connector));
+	return -1;
 }
 
 /**
@@ -1296,6 +1420,8 @@ int drm_add_modes_noedid(struct drm_conn
 					ptr->vdisplay > vdisplay)
 				continue;
 		}
+		if (drm_mode_vrefresh(ptr) > 61)
+			continue;
 		mode = drm_mode_duplicate(dev, ptr);
 		if (mode) {
 			drm_mode_probed_add(connector, mode);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_fb_helper.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fb_helper.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_fb_helper.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fb_helper.c	2010-02-24 13:52:17.000000000 -0500
@@ -156,7 +156,7 @@ static bool drm_fb_helper_connector_pars
 			force = DRM_FORCE_ON;
 			break;
 		case 'D':
-			if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) ||
+			if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
 			    (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
 				force = DRM_FORCE_ON;
 			else
@@ -373,11 +373,9 @@ static void drm_fb_helper_off(struct fb_
 					mutex_unlock(&dev->mode_config.mutex);
 				}
 			}
-			if (dpms_mode == DRM_MODE_DPMS_OFF) {
-				mutex_lock(&dev->mode_config.mutex);
-				crtc_funcs->dpms(crtc, dpms_mode);
-				mutex_unlock(&dev->mode_config.mutex);
-			}
+			mutex_lock(&dev->mode_config.mutex);
+			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+			mutex_unlock(&dev->mode_config.mutex);
 		}
 	}
 }
@@ -385,18 +383,23 @@ static void drm_fb_helper_off(struct fb_
 int drm_fb_helper_blank(int blank, struct fb_info *info)
 {
 	switch (blank) {
+	/* Display: On; HSync: On, VSync: On */
 	case FB_BLANK_UNBLANK:
 		drm_fb_helper_on(info);
 		break;
+	/* Display: Off; HSync: On, VSync: On */
 	case FB_BLANK_NORMAL:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
 		break;
+	/* Display: Off; HSync: Off, VSync: On */
 	case FB_BLANK_HSYNC_SUSPEND:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
 		break;
+	/* Display: Off; HSync: On, VSync: Off */
 	case FB_BLANK_VSYNC_SUSPEND:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
 		break;
+	/* Display: Off; HSync: Off, VSync: Off */
 	case FB_BLANK_POWERDOWN:
 		drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
 		break;
@@ -603,11 +606,10 @@ int drm_fb_helper_check_var(struct fb_va
 		return -EINVAL;
 
 	/* Need to resize the fb object !!! */
-	if (var->xres > fb->width || var->yres > fb->height) {
-		DRM_ERROR("Requested width/height is greater than current fb "
-			   "object %dx%d > %dx%d\n", var->xres, var->yres,
-			   fb->width, fb->height);
-		DRM_ERROR("Need resizing code.\n");
+	if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) {
+		DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
+			  "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel,
+			  fb->width, fb->height, fb->bits_per_pixel);
 		return -EINVAL;
 	}
 
@@ -905,8 +907,13 @@ int drm_fb_helper_single_fb_probe(struct
 
 	if (new_fb) {
 		info->var.pixclock = 0;
-		if (register_framebuffer(info) < 0)
+		ret = fb_alloc_cmap(&info->cmap, modeset->crtc->gamma_size, 0);
+		if (ret)
+			return ret;
+		if (register_framebuffer(info) < 0) {
+			fb_dealloc_cmap(&info->cmap);
 			return -EINVAL;
+		}
 	} else {
 		drm_fb_helper_set_par(info);
 	}
@@ -936,6 +943,7 @@ void drm_fb_helper_free(struct drm_fb_he
 		unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
 	}
 	drm_fb_helper_crtc_free(helper);
+	fb_dealloc_cmap(&helper->fb->fbdev->cmap);
 }
 EXPORT_SYMBOL(drm_fb_helper_free);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_fops.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fops.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_fops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_fops.c	2010-02-24 13:52:17.000000000 -0500
@@ -257,6 +257,9 @@ static int drm_open_helper(struct inode
 
 	INIT_LIST_HEAD(&priv->lhead);
 	INIT_LIST_HEAD(&priv->fbs);
+	INIT_LIST_HEAD(&priv->event_list);
+	init_waitqueue_head(&priv->event_wait);
+	priv->event_space = 4096; /* set aside 4k for event buffer */
 
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_open(dev, priv);
@@ -297,6 +300,18 @@ static int drm_open_helper(struct inode
 				goto out_free;
 			}
 		}
+		mutex_lock(&dev->struct_mutex);
+		if (dev->driver->master_set) {
+			ret = dev->driver->master_set(dev, priv, true);
+			if (ret) {
+				/* drop both references if this fails */
+				drm_master_put(&priv->minor->master);
+				drm_master_put(&priv->master);
+				mutex_unlock(&dev->struct_mutex);
+				goto out_free;
+			}
+		}
+		mutex_unlock(&dev->struct_mutex);
 	} else {
 		/* get a reference to the master */
 		priv->master = drm_master_get(priv->minor->master);
@@ -413,6 +428,30 @@ static void drm_master_release(struct dr
 	}
 }
 
+static void drm_events_release(struct drm_file *file_priv)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_event *e, *et;
+	struct drm_pending_vblank_event *v, *vt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	/* Remove pending flips */
+	list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link)
+		if (v->base.file_priv == file_priv) {
+			list_del(&v->base.link);
+			drm_vblank_put(dev, v->pipe);
+			v->base.destroy(&v->base);
+		}
+
+	/* Remove unconsumed events */
+	list_for_each_entry_safe(e, et, &file_priv->event_list, link)
+		e->destroy(e);
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 /**
  * Release file.
  *
@@ -451,6 +490,8 @@ int drm_release(struct inode *inode, str
 	if (file_priv->minor->master)
 		drm_master_release(dev, filp);
 
+	drm_events_release(file_priv);
+
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_release(dev, file_priv);
 
@@ -504,6 +545,8 @@ int drm_release(struct inode *inode, str
 
 		if (file_priv->minor->master == file_priv->master) {
 			/* drop the reference held my the minor */
+			if (dev->driver->master_drop)
+				dev->driver->master_drop(dev, file_priv, true);
 			drm_master_put(&file_priv->minor->master);
 		}
 	}
@@ -544,9 +587,74 @@ int drm_release(struct inode *inode, str
 }
 EXPORT_SYMBOL(drm_release);
 
-/** No-op. */
+static bool
+drm_dequeue_event(struct drm_file *file_priv,
+		  size_t total, size_t max, struct drm_pending_event **out)
+{
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_event *e;
+	unsigned long flags;
+	bool ret = false;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	*out = NULL;
+	if (list_empty(&file_priv->event_list))
+		goto out;
+	e = list_first_entry(&file_priv->event_list,
+			     struct drm_pending_event, link);
+	if (e->event->length + total > max)
+		goto out;
+
+	file_priv->event_space += e->event->length;
+	list_del(&e->link);
+	*out = e;
+	ret = true;
+
+out:
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+	return ret;
+}
+
+ssize_t drm_read(struct file *filp, char __user *buffer,
+		 size_t count, loff_t *offset)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_pending_event *e;
+	size_t total;
+	ssize_t ret;
+
+	ret = wait_event_interruptible(file_priv->event_wait,
+				       !list_empty(&file_priv->event_list));
+	if (ret < 0)
+		return ret;
+
+	total = 0;
+	while (drm_dequeue_event(file_priv, total, count, &e)) {
+		if (copy_to_user(buffer + total,
+				 e->event, e->event->length)) {
+			total = -EFAULT;
+			break;
+		}
+
+		total += e->event->length;
+		e->destroy(e);
+	}
+
+	return total;
+}
+EXPORT_SYMBOL(drm_read);
+
 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
 {
-	return 0;
+	struct drm_file *file_priv = filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &file_priv->event_wait, wait);
+
+	if (!list_empty(&file_priv->event_list))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
 }
 EXPORT_SYMBOL(drm_poll);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_gem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_gem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_gem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_gem.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,19 +142,6 @@ drm_gem_object_alloc(struct drm_device *
 	if (IS_ERR(obj->filp))
 		goto free;
 
-	/* Basically we want to disable the OOM killer and handle ENOMEM
-	 * ourselves by sacrificing pages from cached buffers.
-	 * XXX shmem_file_[gs]et_gfp_mask()
-	 */
-	mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
-			     GFP_HIGHUSER |
-			     __GFP_COLD |
-			     __GFP_FS |
-			     __GFP_RECLAIMABLE |
-			     __GFP_NORETRY |
-			     __GFP_NOWARN |
-			     __GFP_NOMEMALLOC);
-
 	kref_init(&obj->refcount);
 	kref_init(&obj->handlecount);
 	obj->size = size;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_ioc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,7 @@ static int compat_drm_version(struct fil
 			  &version->desc))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
+	err = drm_ioctl(file,
 			DRM_IOCTL_VERSION, (unsigned long)version);
 	if (err)
 		return err;
@@ -145,8 +145,7 @@ static int compat_drm_getunique(struct f
 			  &u->unique))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
+	err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
 	if (err)
 		return err;
 
@@ -174,8 +173,7 @@ static int compat_drm_setunique(struct f
 			  &u->unique))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
+	return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
 }
 
 typedef struct drm_map32 {
@@ -205,8 +203,7 @@ static int compat_drm_getmap(struct file
 	if (__put_user(idx, &map->offset))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_GET_MAP, (unsigned long)map);
+	err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map);
 	if (err)
 		return err;
 
@@ -246,8 +243,7 @@ static int compat_drm_addmap(struct file
 	    || __put_user(m32.flags, &map->flags))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_ADD_MAP, (unsigned long)map);
+	err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map);
 	if (err)
 		return err;
 
@@ -284,8 +280,7 @@ static int compat_drm_rmmap(struct file
 	if (__put_user((void *)(unsigned long)handle, &map->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RM_MAP, (unsigned long)map);
+	return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map);
 }
 
 typedef struct drm_client32 {
@@ -314,8 +309,7 @@ static int compat_drm_getclient(struct f
 	if (__put_user(idx, &client->idx))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_GET_CLIENT, (unsigned long)client);
+	err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client);
 	if (err)
 		return err;
 
@@ -351,8 +345,7 @@ static int compat_drm_getstats(struct fi
 	if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_GET_STATS, (unsigned long)stats);
+	err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats);
 	if (err)
 		return err;
 
@@ -395,8 +388,7 @@ static int compat_drm_addbufs(struct fil
 	    || __put_user(agp_start, &buf->agp_start))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
+	err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
 	if (err)
 		return err;
 
@@ -427,8 +419,7 @@ static int compat_drm_markbufs(struct fi
 	    || __put_user(b32.high_mark, &buf->high_mark))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
+	return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
 }
 
 typedef struct drm_buf_info32 {
@@ -469,8 +460,7 @@ static int compat_drm_infobufs(struct fi
 	    || __put_user(list, &request->list))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_INFO_BUFS, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request);
 	if (err)
 		return err;
 
@@ -531,8 +521,7 @@ static int compat_drm_mapbufs(struct fil
 	    || __put_user(list, &request->list))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_MAP_BUFS, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request);
 	if (err)
 		return err;
 
@@ -578,8 +567,7 @@ static int compat_drm_freebufs(struct fi
 			  &request->list))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_FREE_BUFS, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request);
 }
 
 typedef struct drm_ctx_priv_map32 {
@@ -605,8 +593,7 @@ static int compat_drm_setsareactx(struct
 			  &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
 }
 
 static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
@@ -628,8 +615,7 @@ static int compat_drm_getsareactx(struct
 	if (__put_user(ctx_id, &request->ctx_id))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
 	if (err)
 		return err;
 
@@ -664,8 +650,7 @@ static int compat_drm_resctx(struct file
 			  &res->contexts))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_RES_CTX, (unsigned long)res);
+	err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res);
 	if (err)
 		return err;
 
@@ -718,8 +703,7 @@ static int compat_drm_dma(struct file *f
 			  &d->request_sizes))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_DMA, (unsigned long)d);
+	err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d);
 	if (err)
 		return err;
 
@@ -751,8 +735,7 @@ static int compat_drm_agp_enable(struct
 	if (put_user(m32.mode, &mode->mode))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
+	return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
 }
 
 typedef struct drm_agp_info32 {
@@ -781,8 +764,7 @@ static int compat_drm_agp_info(struct fi
 	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_AGP_INFO, (unsigned long)info);
+	err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info);
 	if (err)
 		return err;
 
@@ -827,16 +809,14 @@ static int compat_drm_agp_alloc(struct f
 	    || __put_user(req32.type, &request->type))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
 	if (err)
 		return err;
 
 	if (__get_user(req32.handle, &request->handle)
 	    || __get_user(req32.physical, &request->physical)
 	    || copy_to_user(argp, &req32, sizeof(req32))) {
-		drm_ioctl(file->f_path.dentry->d_inode, file,
-			  DRM_IOCTL_AGP_FREE, (unsigned long)request);
+		drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
 		return -EFAULT;
 	}
 
@@ -856,8 +836,7 @@ static int compat_drm_agp_free(struct fi
 	    || __put_user(handle, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_AGP_FREE, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
 }
 
 typedef struct drm_agp_binding32 {
@@ -881,8 +860,7 @@ static int compat_drm_agp_bind(struct fi
 	    || __put_user(req32.offset, &request->offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_AGP_BIND, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request);
 }
 
 static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
@@ -898,8 +876,7 @@ static int compat_drm_agp_unbind(struct
 	    || __put_user(handle, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
 }
 #endif				/* __OS_HAS_AGP */
 
@@ -923,8 +900,7 @@ static int compat_drm_sg_alloc(struct fi
 	    || __put_user(x, &request->size))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_SG_ALLOC, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request);
 	if (err)
 		return err;
 
@@ -950,8 +926,7 @@ static int compat_drm_sg_free(struct fil
 	    || __put_user(x << PAGE_SHIFT, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_SG_FREE, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request);
 }
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
@@ -981,8 +956,7 @@ static int compat_drm_update_draw(struct
 	    __put_user(update32.data, &request->data))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
 	return err;
 }
 #endif
@@ -1023,8 +997,7 @@ static int compat_drm_wait_vblank(struct
 	    || __put_user(req32.request.signal, &request->request.signal))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
+	err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
 	if (err)
 		return err;
 
@@ -1094,16 +1067,14 @@ long drm_compat_ioctl(struct file *filp,
 	 * than always failing.
 	 */
 	if (nr >= ARRAY_SIZE(drm_compat_ioctls))
-		return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		return drm_ioctl(filp, cmd, arg);
 
 	fn = drm_compat_ioctls[nr];
 
-	lock_kernel();		/* XXX for now */
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_irq.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_irq.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,6 +115,7 @@ void drm_vblank_cleanup(struct drm_devic
 
 	dev->num_crtcs = 0;
 }
+EXPORT_SYMBOL(drm_vblank_cleanup);
 
 int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 {
@@ -163,7 +164,6 @@ int drm_vblank_init(struct drm_device *d
 	}
 
 	dev->vblank_disable_allowed = 0;
-
 	return 0;
 
 err:
@@ -429,15 +429,21 @@ int drm_vblank_get(struct drm_device *de
 
 	spin_lock_irqsave(&dev->vbl_lock, irqflags);
 	/* Going from 0->1 means we have to enable interrupts again */
-	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
-	    !dev->vblank_enabled[crtc]) {
-		ret = dev->driver->enable_vblank(dev, crtc);
-		DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
-		if (ret)
+	if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
+		if (!dev->vblank_enabled[crtc]) {
+			ret = dev->driver->enable_vblank(dev, crtc);
+			DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
+			if (ret)
+				atomic_dec(&dev->vblank_refcount[crtc]);
+			else {
+				dev->vblank_enabled[crtc] = 1;
+				drm_update_vblank_count(dev, crtc);
+			}
+		}
+	} else {
+		if (!dev->vblank_enabled[crtc]) {
 			atomic_dec(&dev->vblank_refcount[crtc]);
-		else {
-			dev->vblank_enabled[crtc] = 1;
-			drm_update_vblank_count(dev, crtc);
+			ret = -EINVAL;
 		}
 	}
 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -464,6 +470,18 @@ void drm_vblank_put(struct drm_device *d
 }
 EXPORT_SYMBOL(drm_vblank_put);
 
+void drm_vblank_off(struct drm_device *dev, int crtc)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev->vbl_lock, irqflags);
+	DRM_WAKEUP(&dev->vbl_queue[crtc]);
+	dev->vblank_enabled[crtc] = 0;
+	dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
+	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+}
+EXPORT_SYMBOL(drm_vblank_off);
+
 /**
  * drm_vblank_pre_modeset - account for vblanks across mode sets
  * @dev: DRM device
@@ -475,6 +493,9 @@ EXPORT_SYMBOL(drm_vblank_put);
  */
 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
 {
+	/* vblank is not initialized (IRQ not installed ?) */
+	if (!dev->num_crtcs)
+		return;
 	/*
 	 * To avoid all the problems that might happen if interrupts
 	 * were enabled/disabled around or between these calls, we just
@@ -550,6 +571,63 @@ out:
 	return ret;
 }
 
+static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
+				  union drm_wait_vblank *vblwait,
+				  struct drm_file *file_priv)
+{
+	struct drm_pending_vblank_event *e;
+	struct timeval now;
+	unsigned long flags;
+	unsigned int seq;
+
+	e = kzalloc(sizeof *e, GFP_KERNEL);
+	if (e == NULL)
+		return -ENOMEM;
+
+	e->pipe = pipe;
+	e->event.base.type = DRM_EVENT_VBLANK;
+	e->event.base.length = sizeof e->event;
+	e->event.user_data = vblwait->request.signal;
+	e->base.event = &e->event.base;
+	e->base.file_priv = file_priv;
+	e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+	do_gettimeofday(&now);
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	if (file_priv->event_space < sizeof e->event) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(e);
+		return -ENOMEM;
+	}
+
+	file_priv->event_space -= sizeof e->event;
+	seq = drm_vblank_count(dev, pipe);
+	if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
+	    (seq - vblwait->request.sequence) <= (1 << 23)) {
+		vblwait->request.sequence = seq + 1;
+		vblwait->reply.sequence = vblwait->request.sequence;
+	}
+
+	DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
+		  vblwait->request.sequence, seq, pipe);
+
+	e->event.sequence = vblwait->request.sequence;
+	if ((seq - vblwait->request.sequence) <= (1 << 23)) {
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		drm_vblank_put(dev, e->pipe);
+		list_add_tail(&e->base.link, &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	} else {
+		list_add_tail(&e->base.link, &dev->vblank_event_list);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return 0;
+}
+
 /**
  * Wait for VBLANK.
  *
@@ -609,6 +687,9 @@ int drm_wait_vblank(struct drm_device *d
 		goto done;
 	}
 
+	if (flags & _DRM_VBLANK_EVENT)
+		return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
+
 	if ((flags & _DRM_VBLANK_NEXTONMISS) &&
 	    (seq - vblwait->request.sequence) <= (1<<23)) {
 		vblwait->request.sequence = seq + 1;
@@ -641,6 +722,38 @@ done:
 	return ret;
 }
 
+void drm_handle_vblank_events(struct drm_device *dev, int crtc)
+{
+	struct drm_pending_vblank_event *e, *t;
+	struct timeval now;
+	unsigned long flags;
+	unsigned int seq;
+
+	do_gettimeofday(&now);
+	seq = drm_vblank_count(dev, crtc);
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
+		if (e->pipe != crtc)
+			continue;
+		if ((seq - e->event.sequence) > (1<<23))
+			continue;
+
+		DRM_DEBUG("vblank event on %d, current %d\n",
+			  e->event.sequence, seq);
+
+		e->event.sequence = seq;
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		drm_vblank_put(dev, e->pipe);
+		list_move_tail(&e->base.link, &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 /**
  * drm_handle_vblank - handle a vblank event
  * @dev: DRM device
@@ -651,7 +764,11 @@ done:
  */
 void drm_handle_vblank(struct drm_device *dev, int crtc)
 {
+	if (!dev->num_crtcs)
+		return;
+
 	atomic_inc(&dev->_vblank_count[crtc]);
 	DRM_WAKEUP(&dev->vbl_queue[crtc]);
+	drm_handle_vblank_events(dev, crtc);
 }
 EXPORT_SYMBOL(drm_handle_vblank);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_mm.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_mm.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_mm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_mm.c	2010-02-24 13:52:17.000000000 -0500
@@ -226,6 +226,44 @@ struct drm_mm_node *drm_mm_get_block_gen
 }
 EXPORT_SYMBOL(drm_mm_get_block_generic);
 
+struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int atomic)
+{
+	struct drm_mm_node *align_splitoff = NULL;
+	unsigned tmp = 0;
+	unsigned wasted = 0;
+
+	if (node->start < start)
+		wasted += start - node->start;
+	if (alignment)
+		tmp = ((node->start + wasted) % alignment);
+
+	if (tmp)
+		wasted += alignment - tmp;
+	if (wasted) {
+		align_splitoff = drm_mm_split_at_start(node, wasted, atomic);
+		if (unlikely(align_splitoff == NULL))
+			return NULL;
+	}
+
+	if (node->size == size) {
+		list_del_init(&node->fl_entry);
+		node->free = 0;
+	} else {
+		node = drm_mm_split_at_start(node, size, atomic);
+	}
+
+	if (align_splitoff)
+		drm_mm_put_block(align_splitoff);
+
+	return node;
+}
+EXPORT_SYMBOL(drm_mm_get_block_range_generic);
+
 /*
  * Put a block. Merge with the previous and / or next block if they are free.
  * Otherwise add to the free stack.
@@ -320,7 +358,7 @@ struct drm_mm_node *drm_mm_search_free(c
 		if (entry->size >= size + wasted) {
 			if (!best_match)
 				return entry;
-			if (size < best_size) {
+			if (entry->size < best_size) {
 				best = entry;
 				best_size = entry->size;
 			}
@@ -331,6 +369,57 @@ struct drm_mm_node *drm_mm_search_free(c
 }
 EXPORT_SYMBOL(drm_mm_search_free);
 
+struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
+						unsigned long size,
+						unsigned alignment,
+						unsigned long start,
+						unsigned long end,
+						int best_match)
+{
+	struct list_head *list;
+	const struct list_head *free_stack = &mm->fl_entry;
+	struct drm_mm_node *entry;
+	struct drm_mm_node *best;
+	unsigned long best_size;
+	unsigned wasted;
+
+	best = NULL;
+	best_size = ~0UL;
+
+	list_for_each(list, free_stack) {
+		entry = list_entry(list, struct drm_mm_node, fl_entry);
+		wasted = 0;
+
+		if (entry->size < size)
+			continue;
+
+		if (entry->start > end || (entry->start+entry->size) < start)
+			continue;
+
+		if (entry->start < start)
+			wasted += start - entry->start;
+
+		if (alignment) {
+			register unsigned tmp = (entry->start + wasted) % alignment;
+			if (tmp)
+				wasted += alignment - tmp;
+		}
+
+		if (entry->size >= size + wasted &&
+		    (entry->start + wasted + size) <= end) {
+			if (!best_match)
+				return entry;
+			if (entry->size < best_size) {
+				best = entry;
+				best_size = entry->size;
+			}
+		}
+	}
+
+	return best;
+}
+EXPORT_SYMBOL(drm_mm_search_free_in_range);
+
 int drm_mm_clean(struct drm_mm * mm)
 {
 	struct list_head *head = &mm->ml_entry;
@@ -381,6 +470,26 @@ 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)
+{
+	struct drm_mm_node *entry;
+	int total_used = 0, total_free = 0, total = 0;
+
+	list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n",
+			prefix, entry->start, entry->start + entry->size,
+			entry->size, entry->free ? "free" : "used");
+		total += entry->size;
+		if (entry->free)
+			total_free += entry->size;
+		else
+			total_used += entry->size;
+	}
+	printk(KERN_DEBUG "%s total: %d, used %d free %d\n", prefix, total,
+		total_used, total_free);
+}
+EXPORT_SYMBOL(drm_mm_debug_table);
+
 #if defined(CONFIG_DEBUG_FS)
 int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
 {
@@ -395,7 +504,7 @@ int drm_mm_dump_table(struct seq_file *m
 		else
 			total_used += entry->size;
 	}
-	seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used);
+	seq_printf(m, "total: %d, used %d free %d\n", total, total_used, total_free);
 	return 0;
 }
 EXPORT_SYMBOL(drm_mm_dump_table);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_modes.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_modes.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_modes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_modes.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,4 @@
 /*
- * The list_sort function is (presumably) licensed under the GPL (see the
- * top level "COPYING" file for details).
- *
- * The remainder of this file is:
- *
  * Copyright © 1997-2003 by The XFree86 Project, Inc.
  * Copyright © 2007 Dave Airlie
  * Copyright © 2007-2008 Intel Corporation
@@ -36,6 +31,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/list_sort.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -553,6 +549,32 @@ int drm_mode_height(struct drm_display_m
 }
 EXPORT_SYMBOL(drm_mode_height);
 
+/** drm_mode_hsync - get the hsync of a mode
+ * @mode: mode
+ *
+ * LOCKING:
+ * None.
+ *
+ * Return @modes's hsync rate in kHz, rounded to the nearest int.
+ */
+int drm_mode_hsync(struct drm_display_mode *mode)
+{
+	unsigned int calc_val;
+
+	if (mode->hsync)
+		return mode->hsync;
+
+	if (mode->htotal < 0)
+		return 0;
+
+	calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */
+	calc_val += 500;				/* round to 1000Hz */
+	calc_val /= 1000;				/* truncate to kHz */
+
+	return calc_val;
+}
+EXPORT_SYMBOL(drm_mode_hsync);
+
 /**
  * drm_mode_vrefresh - get the vrefresh of a mode
  * @mode: mode
@@ -560,7 +582,7 @@ EXPORT_SYMBOL(drm_mode_height);
  * LOCKING:
  * None.
  *
- * Return @mode's vrefresh rate or calculate it if necessary.
+ * Return @mode's vrefresh rate in Hz or calculate it if necessary.
  *
  * FIXME: why is this needed?  shouldn't vrefresh be set already?
  *
@@ -829,6 +851,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid);
 
 /**
  * drm_mode_compare - compare modes for favorability
+ * @priv: unused
  * @lh_a: list_head for first mode
  * @lh_b: list_head for second mode
  *
@@ -842,7 +865,7 @@ EXPORT_SYMBOL(drm_mode_prune_invalid);
  * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
  * positive if @lh_b is better than @lh_a.
  */
-static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b)
+static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b)
 {
 	struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head);
 	struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head);
@@ -859,85 +882,6 @@ static int drm_mode_compare(struct list_
 	return diff;
 }
 
-/* FIXME: what we don't have a list sort function? */
-/* list sort from Mark J Roberts (mjr@znex.org) */
-void list_sort(struct list_head *head,
-	       int (*cmp)(struct list_head *a, struct list_head *b))
-{
-	struct list_head *p, *q, *e, *list, *tail, *oldhead;
-	int insize, nmerges, psize, qsize, i;
-
-	list = head->next;
-	list_del(head);
-	insize = 1;
-	for (;;) {
-		p = oldhead = list;
-		list = tail = NULL;
-		nmerges = 0;
-
-		while (p) {
-			nmerges++;
-			q = p;
-			psize = 0;
-			for (i = 0; i < insize; i++) {
-				psize++;
-				q = q->next == oldhead ? NULL : q->next;
-				if (!q)
-					break;
-			}
-
-			qsize = insize;
-			while (psize > 0 || (qsize > 0 && q)) {
-				if (!psize) {
-					e = q;
-					q = q->next;
-					qsize--;
-					if (q == oldhead)
-						q = NULL;
-				} else if (!qsize || !q) {
-					e = p;
-					p = p->next;
-					psize--;
-					if (p == oldhead)
-						p = NULL;
-				} else if (cmp(p, q) <= 0) {
-					e = p;
-					p = p->next;
-					psize--;
-					if (p == oldhead)
-						p = NULL;
-				} else {
-					e = q;
-					q = q->next;
-					qsize--;
-					if (q == oldhead)
-						q = NULL;
-				}
-				if (tail)
-					tail->next = e;
-				else
-					list = e;
-				e->prev = tail;
-				tail = e;
-			}
-			p = q;
-		}
-
-		tail->next = list;
-		list->prev = tail;
-
-		if (nmerges <= 1)
-			break;
-
-		insize *= 2;
-	}
-
-	head->next = list;
-	head->prev = list->prev;
-	list->prev->next = head;
-	list->prev = head;
-}
-
 /**
  * drm_mode_sort - sort mode list
  * @mode_list: list to sort
@@ -949,7 +893,7 @@ void list_sort(struct list_head *head,
  */
 void drm_mode_sort(struct list_head *mode_list)
 {
-	list_sort(mode_list, drm_mode_compare);
+	list_sort(NULL, mode_list, drm_mode_compare);
 }
 EXPORT_SYMBOL(drm_mode_sort);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_pci.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_pci.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,8 +47,7 @@
 /**
  * \brief Allocate a PCI consistent memory block, for DMA.
  */
-drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align,
-				dma_addr_t maxaddr)
+drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
 {
 	drm_dma_handle_t *dmah;
 #if 1
@@ -63,11 +62,6 @@ drm_dma_handle_t *drm_pci_alloc(struct d
 	if (align > size)
 		return NULL;
 
-	if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) {
-		DRM_ERROR("Setting pci dma mask failed\n");
-		return NULL;
-	}
-
 	dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
 	if (!dmah)
 		return NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_stub.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_stub.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/drm_stub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/drm_stub.c	2010-02-24 13:52:17.000000000 -0500
@@ -128,6 +128,7 @@ struct drm_master *drm_master_get(struct
 	kref_get(&master->refcount);
 	return master;
 }
+EXPORT_SYMBOL(drm_master_get);
 
 static void drm_master_destroy(struct kref *kref)
 {
@@ -170,10 +171,13 @@ void drm_master_put(struct drm_master **
 	kref_put(&(*master)->refcount, drm_master_destroy);
 	*master = NULL;
 }
+EXPORT_SYMBOL(drm_master_put);
 
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
+	int ret = 0;
+
 	if (file_priv->is_master)
 		return 0;
 
@@ -188,6 +192,13 @@ int drm_setmaster_ioctl(struct drm_devic
 		mutex_lock(&dev->struct_mutex);
 		file_priv->minor->master = drm_master_get(file_priv->master);
 		file_priv->is_master = 1;
+		if (dev->driver->master_set) {
+			ret = dev->driver->master_set(dev, file_priv, false);
+			if (unlikely(ret != 0)) {
+				file_priv->is_master = 0;
+				drm_master_put(&file_priv->minor->master);
+			}
+		}
 		mutex_unlock(&dev->struct_mutex);
 	}
 
@@ -204,6 +215,8 @@ int drm_dropmaster_ioctl(struct drm_devi
 		return -EINVAL;
 
 	mutex_lock(&dev->struct_mutex);
+	if (dev->driver->master_drop)
+		dev->driver->master_drop(dev, file_priv, false);
 	drm_master_put(&file_priv->minor->master);
 	file_priv->is_master = 0;
 	mutex_unlock(&dev->struct_mutex);
@@ -220,9 +233,11 @@ static int drm_fill_in_dev(struct drm_de
 	INIT_LIST_HEAD(&dev->ctxlist);
 	INIT_LIST_HEAD(&dev->vmalist);
 	INIT_LIST_HEAD(&dev->maplist);
+	INIT_LIST_HEAD(&dev->vblank_event_list);
 
 	spin_lock_init(&dev->count_lock);
 	spin_lock_init(&dev->drw_lock);
+	spin_lock_init(&dev->event_lock);
 	init_timer(&dev->timer);
 	mutex_init(&dev->struct_mutex);
 	mutex_init(&dev->ctxlist_mutex);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_drv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "ch7006_priv.h"
+
+/* DRM encoder functions */
+
+static void ch7006_encoder_set_config(struct drm_encoder *encoder,
+				      void *params)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	priv->params = params;
+}
+
+static void ch7006_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	drm_property_destroy(encoder->dev, priv->scale_property);
+
+	kfree(priv);
+	to_encoder_slave(encoder)->slave_priv = NULL;
+
+	drm_i2c_encoder_destroy(encoder);
+}
+
+static void  ch7006_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+
+	ch7006_dbg(client, "\n");
+
+	if (mode == priv->last_dpms)
+		return;
+	priv->last_dpms = mode;
+
+	ch7006_setup_power_state(encoder);
+
+	ch7006_load_reg(client, state, CH7006_POWER);
+}
+
+static void ch7006_encoder_save(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_state_save(client, &priv->saved_state);
+}
+
+static void ch7006_encoder_restore(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_state_load(client, &priv->saved_state);
+}
+
+static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+
+	/* The ch7006 is painfully picky with the input timings so no
+	 * custom modes for now... */
+
+	priv->mode = ch7006_lookup_mode(encoder, mode);
+
+	return !!priv->mode;
+}
+
+static int ch7006_encoder_mode_valid(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode)
+{
+	if (ch7006_lookup_mode(encoder, mode))
+		return MODE_OK;
+	else
+		return MODE_BAD;
+}
+
+static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
+				     struct drm_display_mode *drm_mode,
+				     struct drm_display_mode *adjusted_mode)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_encoder_params *params = priv->params;
+	struct ch7006_state *state = &priv->state;
+	uint8_t *regs = state->regs;
+	struct ch7006_mode *mode = priv->mode;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	int start_active;
+
+	ch7006_dbg(client, "\n");
+
+	regs[CH7006_DISPMODE] = norm->dispmode | mode->dispmode;
+	regs[CH7006_BWIDTH] = 0;
+	regs[CH7006_INPUT_FORMAT] = bitf(CH7006_INPUT_FORMAT_FORMAT,
+					 params->input_format);
+
+	regs[CH7006_CLKMODE] = CH7006_CLKMODE_SUBC_LOCK
+		| bitf(CH7006_CLKMODE_XCM, params->xcm)
+		| bitf(CH7006_CLKMODE_PCM, params->pcm);
+	if (params->clock_mode)
+		regs[CH7006_CLKMODE] |= CH7006_CLKMODE_MASTER;
+	if (params->clock_edge)
+		regs[CH7006_CLKMODE] |= CH7006_CLKMODE_POS_EDGE;
+
+	start_active = (drm_mode->htotal & ~0x7) - (drm_mode->hsync_start & ~0x7);
+	regs[CH7006_POV] = bitf(CH7006_POV_START_ACTIVE_8, start_active);
+	regs[CH7006_START_ACTIVE] = bitf(CH7006_START_ACTIVE_0, start_active);
+
+	regs[CH7006_INPUT_SYNC] = 0;
+	if (params->sync_direction)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_OUTPUT;
+	if (params->sync_encoding)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_EMBEDDED;
+	if (drm_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PVSYNC;
+	if (drm_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PHSYNC;
+
+	regs[CH7006_DETECT] = 0;
+	regs[CH7006_BCLKOUT] = 0;
+
+	regs[CH7006_SUBC_INC3] = 0;
+	if (params->pout_level)
+		regs[CH7006_SUBC_INC3] |= CH7006_SUBC_INC3_POUT_3_3V;
+
+	regs[CH7006_SUBC_INC4] = 0;
+	if (params->active_detect)
+		regs[CH7006_SUBC_INC4] |= CH7006_SUBC_INC4_DS_INPUT;
+
+	regs[CH7006_PLL_CONTROL] = priv->saved_state.regs[CH7006_PLL_CONTROL];
+
+	ch7006_setup_levels(encoder);
+	ch7006_setup_subcarrier(encoder);
+	ch7006_setup_pll(encoder);
+	ch7006_setup_power_state(encoder);
+	ch7006_setup_properties(encoder);
+
+	ch7006_state_load(client, state);
+}
+
+static enum drm_connector_status ch7006_encoder_detect(struct drm_encoder *encoder,
+						       struct drm_connector *connector)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	int det;
+
+	ch7006_dbg(client, "\n");
+
+	ch7006_save_reg(client, state, CH7006_DETECT);
+	ch7006_save_reg(client, state, CH7006_POWER);
+	ch7006_save_reg(client, state, CH7006_CLKMODE);
+
+	ch7006_write(client, CH7006_POWER, CH7006_POWER_RESET |
+					   bitfs(CH7006_POWER_LEVEL, NORMAL));
+	ch7006_write(client, CH7006_CLKMODE, CH7006_CLKMODE_MASTER);
+
+	ch7006_write(client, CH7006_DETECT, CH7006_DETECT_SENSE);
+
+	ch7006_write(client, CH7006_DETECT, 0);
+
+	det = ch7006_read(client, CH7006_DETECT);
+
+	ch7006_load_reg(client, state, CH7006_CLKMODE);
+	ch7006_load_reg(client, state, CH7006_POWER);
+	ch7006_load_reg(client, state, CH7006_DETECT);
+
+	if ((det & (CH7006_DETECT_SVIDEO_Y_TEST|
+		    CH7006_DETECT_SVIDEO_C_TEST|
+		    CH7006_DETECT_CVBS_TEST)) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
+	else if ((det & (CH7006_DETECT_SVIDEO_Y_TEST|
+			 CH7006_DETECT_SVIDEO_C_TEST)) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
+	else if ((det & CH7006_DETECT_CVBS_TEST) == 0)
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
+	else
+		priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+
+	drm_connector_property_set_value(connector,
+			encoder->dev->mode_config.tv_subconnector_property,
+							priv->subconnector);
+
+	return priv->subconnector ? connector_status_connected :
+					connector_status_disconnected;
+}
+
+static int ch7006_encoder_get_modes(struct drm_encoder *encoder,
+				    struct drm_connector *connector)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_mode *mode;
+	int n = 0;
+
+	for (mode = ch7006_modes; mode->mode.clock; mode++) {
+		if (~mode->valid_scales & 1<<priv->scale ||
+		    ~mode->valid_norms & 1<<priv->norm)
+			continue;
+
+		drm_mode_probed_add(connector,
+				drm_mode_duplicate(encoder->dev, &mode->mode));
+
+		n++;
+	}
+
+	return n;
+}
+
+static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
+					   struct drm_connector *connector)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_mode_config *conf = &dev->mode_config;
+
+	drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
+
+	priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE,
+						   "scale", 2);
+	priv->scale_property->values[0] = 0;
+	priv->scale_property->values[1] = 2;
+
+	drm_connector_attach_property(connector, conf->tv_select_subconnector_property,
+				      priv->select_subconnector);
+	drm_connector_attach_property(connector, conf->tv_subconnector_property,
+				      priv->subconnector);
+	drm_connector_attach_property(connector, conf->tv_left_margin_property,
+				      priv->hmargin);
+	drm_connector_attach_property(connector, conf->tv_bottom_margin_property,
+				      priv->vmargin);
+	drm_connector_attach_property(connector, conf->tv_mode_property,
+				      priv->norm);
+	drm_connector_attach_property(connector, conf->tv_brightness_property,
+				      priv->brightness);
+	drm_connector_attach_property(connector, conf->tv_contrast_property,
+				      priv->contrast);
+	drm_connector_attach_property(connector, conf->tv_flicker_reduction_property,
+				      priv->flicker);
+	drm_connector_attach_property(connector, priv->scale_property,
+				      priv->scale);
+
+	return 0;
+}
+
+static int ch7006_encoder_set_property(struct drm_encoder *encoder,
+				       struct drm_connector *connector,
+				       struct drm_property *property,
+				       uint64_t val)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct drm_mode_config *conf = &encoder->dev->mode_config;
+	struct drm_crtc *crtc = encoder->crtc;
+	bool modes_changed = false;
+
+	ch7006_dbg(client, "\n");
+
+	if (property == conf->tv_select_subconnector_property) {
+		priv->select_subconnector = val;
+
+		ch7006_setup_power_state(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POWER);
+
+	} else if (property == conf->tv_left_margin_property) {
+		priv->hmargin = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POV);
+		ch7006_load_reg(client, state, CH7006_HPOS);
+
+	} else if (property == conf->tv_bottom_margin_property) {
+		priv->vmargin = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_POV);
+		ch7006_load_reg(client, state, CH7006_VPOS);
+
+	} else if (property == conf->tv_mode_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		priv->norm = val;
+
+		modes_changed = true;
+
+	} else if (property == conf->tv_brightness_property) {
+		priv->brightness = val;
+
+		ch7006_setup_levels(encoder);
+
+		ch7006_load_reg(client, state, CH7006_BLACK_LEVEL);
+
+	} else if (property == conf->tv_contrast_property) {
+		priv->contrast = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_CONTRAST);
+
+	} else if (property == conf->tv_flicker_reduction_property) {
+		priv->flicker = val;
+
+		ch7006_setup_properties(encoder);
+
+		ch7006_load_reg(client, state, CH7006_FFILTER);
+
+	} else if (property == priv->scale_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		priv->scale = val;
+
+		modes_changed = true;
+
+	} else {
+		return -EINVAL;
+	}
+
+	if (modes_changed) {
+		drm_helper_probe_single_connector_modes(connector, 0, 0);
+
+		/* Disable the crtc to ensure a full modeset is
+		 * performed whenever it's turned on again. */
+		if (crtc) {
+			struct drm_mode_set modeset = {
+				.crtc = crtc,
+			};
+
+			crtc->funcs->set_config(&modeset);
+		}
+	}
+
+	return 0;
+}
+
+static struct drm_encoder_slave_funcs ch7006_encoder_funcs = {
+	.set_config = ch7006_encoder_set_config,
+	.destroy = ch7006_encoder_destroy,
+	.dpms = ch7006_encoder_dpms,
+	.save = ch7006_encoder_save,
+	.restore = ch7006_encoder_restore,
+	.mode_fixup = ch7006_encoder_mode_fixup,
+	.mode_valid = ch7006_encoder_mode_valid,
+	.mode_set = ch7006_encoder_mode_set,
+	.detect = ch7006_encoder_detect,
+	.get_modes = ch7006_encoder_get_modes,
+	.create_resources = ch7006_encoder_create_resources,
+	.set_property = ch7006_encoder_set_property,
+};
+
+
+/* I2C driver functions */
+
+static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	uint8_t addr = CH7006_VERSION_ID;
+	uint8_t val;
+	int ret;
+
+	ch7006_dbg(client, "\n");
+
+	ret = i2c_master_send(client, &addr, sizeof(addr));
+	if (ret < 0)
+		goto fail;
+
+	ret = i2c_master_recv(client, &val, sizeof(val));
+	if (ret < 0)
+		goto fail;
+
+	ch7006_info(client, "Detected version ID: %x\n", val);
+
+	/* I don't know what this is for, but otherwise I get no
+	 * signal.
+	 */
+	ch7006_write(client, 0x3d, 0x0);
+
+	return 0;
+
+fail:
+	ch7006_err(client, "Error %d reading version ID\n", ret);
+
+	return -ENODEV;
+}
+
+static int ch7006_remove(struct i2c_client *client)
+{
+	ch7006_dbg(client, "\n");
+
+	return 0;
+}
+
+static int ch7006_encoder_init(struct i2c_client *client,
+			       struct drm_device *dev,
+			       struct drm_encoder_slave *encoder)
+{
+	struct ch7006_priv *priv;
+	int i;
+
+	ch7006_dbg(client, "\n");
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	encoder->slave_priv = priv;
+	encoder->slave_funcs = &ch7006_encoder_funcs;
+
+	priv->norm = TV_NORM_PAL;
+	priv->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
+	priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+	priv->scale = 1;
+	priv->contrast = 50;
+	priv->brightness = 50;
+	priv->flicker = 50;
+	priv->hmargin = 50;
+	priv->vmargin = 50;
+	priv->last_dpms = -1;
+
+	if (ch7006_tv_norm) {
+		for (i = 0; i < NUM_TV_NORMS; i++) {
+			if (!strcmp(ch7006_tv_norm_names[i], ch7006_tv_norm)) {
+				priv->norm = i;
+				break;
+			}
+		}
+
+		if (i == NUM_TV_NORMS)
+			ch7006_err(client, "Invalid TV norm setting \"%s\".\n",
+				   ch7006_tv_norm);
+	}
+
+	if (ch7006_scale >= 0 && ch7006_scale <= 2)
+		priv->scale = ch7006_scale;
+	else
+		ch7006_err(client, "Invalid scale setting \"%d\".\n",
+			   ch7006_scale);
+
+	return 0;
+}
+
+static struct i2c_device_id ch7006_ids[] = {
+	{ "ch7006", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ch7006_ids);
+
+static struct drm_i2c_encoder_driver ch7006_driver = {
+	.i2c_driver = {
+		.probe = ch7006_probe,
+		.remove = ch7006_remove,
+
+		.driver = {
+			.name = "ch7006",
+		},
+
+		.id_table = ch7006_ids,
+	},
+
+	.encoder_init = ch7006_encoder_init,
+};
+
+
+/* Module initialization */
+
+static int __init ch7006_init(void)
+{
+	return drm_i2c_encoder_register(THIS_MODULE, &ch7006_driver);
+}
+
+static void __exit ch7006_exit(void)
+{
+	drm_i2c_encoder_unregister(&ch7006_driver);
+}
+
+int ch7006_debug;
+module_param_named(debug, ch7006_debug, int, 0600);
+MODULE_PARM_DESC(debug, "Enable debug output.");
+
+char *ch7006_tv_norm;
+module_param_named(tv_norm, ch7006_tv_norm, charp, 0600);
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
+		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, PAL-60, NTSC-M, NTSC-J.\n"
+		 "\t\tDefault: PAL");
+
+int ch7006_scale = 1;
+module_param_named(scale, ch7006_scale, int, 0600);
+MODULE_PARM_DESC(scale, "Default scale.\n"
+		 "\t\tSupported: 0 -> Select video modes with a higher blanking ratio.\n"
+		 "\t\t\t1 -> Select default video modes.\n"
+		 "\t\t\t2 -> Select video modes with a lower blanking ratio.");
+
+MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>");
+MODULE_DESCRIPTION("Chrontel ch7006 TV encoder driver");
+MODULE_LICENSE("GPL and additional rights");
+
+module_init(ch7006_init);
+module_exit(ch7006_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_mode.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_mode.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_mode.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_mode.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "ch7006_priv.h"
+
+char *ch7006_tv_norm_names[] = {
+	[TV_NORM_PAL] = "PAL",
+	[TV_NORM_PAL_M] = "PAL-M",
+	[TV_NORM_PAL_N] = "PAL-N",
+	[TV_NORM_PAL_NC] = "PAL-Nc",
+	[TV_NORM_PAL_60] = "PAL-60",
+	[TV_NORM_NTSC_M] = "NTSC-M",
+	[TV_NORM_NTSC_J] = "NTSC-J",
+};
+
+#define NTSC_LIKE_TIMINGS .vrefresh = 60 * fixed1/1.001,		\
+		.vdisplay = 480,					\
+		.vtotal = 525,						\
+		.hvirtual = 660
+
+#define PAL_LIKE_TIMINGS .vrefresh = 50 * fixed1,		\
+		.vdisplay = 576,				\
+		.vtotal = 625,					\
+		.hvirtual = 810
+
+struct ch7006_tv_norm_info ch7006_tv_norms[] = {
+	[TV_NORM_NTSC_M] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 3579545 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC),
+		.voffset = 0,
+	},
+	[TV_NORM_NTSC_J] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.286 * fixed1,
+		.subc_freq = 3579545 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC_J),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_M] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 3575611.433 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M),
+		.voffset = 16,
+	},
+
+	/* The following modes seem to work right but they're
+	 * undocumented */
+
+	[TV_NORM_PAL_N] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.339 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_NC] = {
+		PAL_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 3582056.25 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL),
+		.voffset = 0,
+	},
+	[TV_NORM_PAL_60] = {
+		NTSC_LIKE_TIMINGS,
+		.black_level = 0.3 * fixed1,
+		.subc_freq = 4433618.75 * fixed1,
+		.dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M),
+		.voffset = 16,
+	},
+};
+
+#define __MODE(f, hd, vd, ht, vt, hsynp, vsynp,				\
+	       subc, scale, scale_mask, norm_mask, e_hd, e_vd) {	\
+		.mode = {						\
+			.name = #hd "x" #vd,				\
+			.status = 0,					\
+			.type = DRM_MODE_TYPE_DRIVER,			\
+			.clock = f,					\
+			.hdisplay = hd,					\
+			.hsync_start = e_hd + 16,			\
+			.hsync_end = e_hd + 80,				\
+			.htotal = ht,					\
+			.hskew = 0,					\
+			.vdisplay = vd,					\
+			.vsync_start = vd + 10,				\
+			.vsync_end = vd + 26,				\
+			.vtotal = vt,					\
+			.vscan = 0,					\
+			.flags = DRM_MODE_FLAG_##hsynp##HSYNC |		\
+				DRM_MODE_FLAG_##vsynp##VSYNC,		\
+			.vrefresh = 0,					\
+		},							\
+		.enc_hdisp = e_hd,					\
+		.enc_vdisp = e_vd,					\
+		.subc_coeff = subc * fixed1,				\
+		.dispmode = bitfs(CH7006_DISPMODE_SCALING_RATIO, scale) | \
+			    bitfs(CH7006_DISPMODE_INPUT_RES, e_hd##x##e_vd), \
+		.valid_scales = scale_mask,				\
+		.valid_norms = norm_mask				\
+	 }
+
+#define MODE(f, hd, vd, ht, vt, hsynp, vsynp,				\
+	     subc, scale, scale_mask, norm_mask)			\
+	__MODE(f, hd, vd, ht, vt, hsynp, vsynp, subc, scale,		\
+	       scale_mask, norm_mask, hd, vd)
+
+#define NTSC_LIKE (1 << TV_NORM_NTSC_M | 1 << TV_NORM_NTSC_J |		\
+		   1 << TV_NORM_PAL_M | 1 << TV_NORM_PAL_60)
+
+#define PAL_LIKE (1 << TV_NORM_PAL | 1 << TV_NORM_PAL_N | 1 << TV_NORM_PAL_NC)
+
+struct ch7006_mode ch7006_modes[] = {
+	MODE(21000, 512, 384, 840, 500, N, N, 181.797557582, 5_4, 0x6, PAL_LIKE),
+	MODE(26250, 512, 384, 840, 625, N, N, 145.438046066, 1_1, 0x1, PAL_LIKE),
+	MODE(20140, 512, 384, 800, 420, N, N, 213.257083791, 5_4, 0x4, NTSC_LIKE),
+	MODE(24671, 512, 384, 784, 525, N, N, 174.0874153, 1_1, 0x3, NTSC_LIKE),
+	MODE(28125, 720, 400, 1125, 500, N, N, 135.742176298, 5_4, 0x6, PAL_LIKE),
+	MODE(34875, 720, 400, 1116, 625, N, N, 109.469496898, 1_1, 0x1, PAL_LIKE),
+	MODE(23790, 720, 400, 945, 420, N, N, 160.475642016, 5_4, 0x4, NTSC_LIKE),
+	MODE(29455, 720, 400, 936, 525, N, N, 129.614941843, 1_1, 0x3, NTSC_LIKE),
+	MODE(25000, 640, 400, 1000, 500, N, N, 152.709948279, 5_4, 0x6, PAL_LIKE),
+	MODE(31500, 640, 400, 1008, 625, N, N, 121.198371646, 1_1, 0x1, PAL_LIKE),
+	MODE(21147, 640, 400, 840, 420, N, N, 180.535097338, 5_4, 0x4, NTSC_LIKE),
+	MODE(26434, 640, 400, 840, 525, N, N, 144.42807787, 1_1, 0x2, NTSC_LIKE),
+	MODE(30210, 640, 400, 840, 600, N, N, 126.374568276, 7_8, 0x1, NTSC_LIKE),
+	MODE(21000, 640, 480, 840, 500, N, N, 181.797557582, 5_4, 0x4, PAL_LIKE),
+	MODE(26250, 640, 480, 840, 625, N, N, 145.438046066, 1_1, 0x2, PAL_LIKE),
+	MODE(31500, 640, 480, 840, 750, N, N, 121.198371646, 5_6, 0x1, PAL_LIKE),
+	MODE(24671, 640, 480, 784, 525, N, N, 174.0874153, 1_1, 0x4, NTSC_LIKE),
+	MODE(28196, 640, 480, 784, 600, N, N, 152.326488422, 7_8, 0x2, NTSC_LIKE),
+	MODE(30210, 640, 480, 800, 630, N, N, 142.171389101, 5_6, 0x1, NTSC_LIKE),
+	__MODE(29500, 720, 576, 944, 625, P, P, 145.592111636, 1_1, 0x7, PAL_LIKE, 800, 600),
+	MODE(36000, 800, 600, 960, 750, P, P, 119.304647022, 5_6, 0x6, PAL_LIKE),
+	MODE(39000, 800, 600, 936, 836, P, P, 110.127366499, 3_4, 0x1, PAL_LIKE),
+	MODE(39273, 800, 600, 1040, 630, P, P, 145.816809399, 5_6, 0x4, NTSC_LIKE),
+	MODE(43636, 800, 600, 1040, 700, P, P, 131.235128487, 3_4, 0x2, NTSC_LIKE),
+	MODE(47832, 800, 600, 1064, 750, P, P, 119.723275165, 7_10, 0x1, NTSC_LIKE),
+	{}
+};
+
+struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+				       struct drm_display_mode *drm_mode)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_mode *mode;
+
+	for (mode = ch7006_modes; mode->mode.clock; mode++) {
+
+		if (~mode->valid_norms & 1<<priv->norm)
+			continue;
+
+		if (mode->mode.hdisplay != drm_mode->hdisplay ||
+		    mode->mode.vdisplay != drm_mode->vdisplay ||
+		    mode->mode.vtotal != drm_mode->vtotal ||
+		    mode->mode.htotal != drm_mode->htotal ||
+		    mode->mode.clock != drm_mode->clock)
+			continue;
+
+		return mode;
+	}
+
+	return NULL;
+}
+
+/* Some common HW state calculation code */
+
+void ch7006_setup_levels(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *regs = priv->state.regs;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	int gain;
+	int black_level;
+
+	/* Set DAC_GAIN if the voltage drop between white and black is
+	 * high enough. */
+	if (norm->black_level < 339*fixed1/1000) {
+		gain = 76;
+
+		regs[CH7006_INPUT_FORMAT] |= CH7006_INPUT_FORMAT_DAC_GAIN;
+	} else {
+		gain = 71;
+
+		regs[CH7006_INPUT_FORMAT] &= ~CH7006_INPUT_FORMAT_DAC_GAIN;
+	}
+
+	black_level = round_fixed(norm->black_level*26625)/gain;
+
+	/* Correct it with the specified brightness. */
+	black_level = interpolate(90, black_level, 208, priv->brightness);
+
+	regs[CH7006_BLACK_LEVEL] = bitf(CH7006_BLACK_LEVEL_0, black_level);
+
+	ch7006_dbg(client, "black level: %d\n", black_level);
+}
+
+void ch7006_setup_subcarrier(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	struct ch7006_mode *mode = priv->mode;
+	uint32_t subc_inc;
+
+	subc_inc = round_fixed((mode->subc_coeff >> 8)
+			       * (norm->subc_freq >> 24));
+
+	setbitf(state, CH7006_SUBC_INC0, 28, subc_inc);
+	setbitf(state, CH7006_SUBC_INC1, 24, subc_inc);
+	setbitf(state, CH7006_SUBC_INC2, 20, subc_inc);
+	setbitf(state, CH7006_SUBC_INC3, 16, subc_inc);
+	setbitf(state, CH7006_SUBC_INC4, 12, subc_inc);
+	setbitf(state, CH7006_SUBC_INC5, 8, subc_inc);
+	setbitf(state, CH7006_SUBC_INC6, 4, subc_inc);
+	setbitf(state, CH7006_SUBC_INC7, 0, subc_inc);
+
+	ch7006_dbg(client, "subcarrier inc: %u\n", subc_inc);
+}
+
+void ch7006_setup_pll(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *regs = priv->state.regs;
+	struct ch7006_mode *mode = priv->mode;
+	int n, best_n = 0;
+	int m, best_m = 0;
+	int freq, best_freq = 0;
+
+	for (n = 0; n < CH7006_MAXN; n++) {
+		for (m = 0; m < CH7006_MAXM; m++) {
+			freq = CH7006_FREQ0*(n+2)/(m+2);
+
+			if (abs(freq - mode->mode.clock) <
+			    abs(best_freq - mode->mode.clock)) {
+				best_freq = freq;
+				best_n = n;
+				best_m = m;
+			}
+		}
+	}
+
+	regs[CH7006_PLLOV] = bitf(CH7006_PLLOV_N_8, best_n) |
+		bitf(CH7006_PLLOV_M_8, best_m);
+
+	regs[CH7006_PLLM] = bitf(CH7006_PLLM_0, best_m);
+	regs[CH7006_PLLN] = bitf(CH7006_PLLN_0, best_n);
+
+	if (best_n < 108)
+		regs[CH7006_PLL_CONTROL] |= CH7006_PLL_CONTROL_CAPACITOR;
+	else
+		regs[CH7006_PLL_CONTROL] &= ~CH7006_PLL_CONTROL_CAPACITOR;
+
+	ch7006_dbg(client, "n=%d m=%d f=%d c=%d\n",
+		   best_n, best_m, best_freq, best_n < 108);
+}
+
+void ch7006_setup_power_state(struct drm_encoder *encoder)
+{
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	uint8_t *power = &priv->state.regs[CH7006_POWER];
+	int subconnector;
+
+	subconnector = priv->select_subconnector ? priv->select_subconnector :
+							priv->subconnector;
+
+	*power = CH7006_POWER_RESET;
+
+	if (priv->last_dpms == DRM_MODE_DPMS_ON) {
+		switch (subconnector) {
+		case DRM_MODE_SUBCONNECTOR_SVIDEO:
+			*power |= bitfs(CH7006_POWER_LEVEL, CVBS_OFF);
+			break;
+		case DRM_MODE_SUBCONNECTOR_Composite:
+			*power |= bitfs(CH7006_POWER_LEVEL, SVIDEO_OFF);
+			break;
+		case DRM_MODE_SUBCONNECTOR_SCART:
+			*power |= bitfs(CH7006_POWER_LEVEL, NORMAL) |
+				CH7006_POWER_SCART;
+			break;
+		}
+
+	} else {
+		*power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
+	}
+}
+
+void ch7006_setup_properties(struct drm_encoder *encoder)
+{
+	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
+	struct ch7006_priv *priv = to_ch7006_priv(encoder);
+	struct ch7006_state *state = &priv->state;
+	struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm];
+	struct ch7006_mode *ch_mode = priv->mode;
+	struct drm_display_mode *mode = &ch_mode->mode;
+	uint8_t *regs = state->regs;
+	int flicker, contrast, hpos, vpos;
+	uint64_t scale, aspect;
+
+	flicker = interpolate(0, 2, 3, priv->flicker);
+	regs[CH7006_FFILTER] = bitf(CH7006_FFILTER_TEXT, flicker) |
+		bitf(CH7006_FFILTER_LUMA, flicker) |
+		bitf(CH7006_FFILTER_CHROMA, 1);
+
+	contrast = interpolate(0, 5, 7, priv->contrast);
+	regs[CH7006_CONTRAST] = bitf(CH7006_CONTRAST_0, contrast);
+
+	scale = norm->vtotal*fixed1;
+	do_div(scale, mode->vtotal);
+
+	aspect = ch_mode->enc_hdisp*fixed1;
+	do_div(aspect, ch_mode->enc_vdisp);
+
+	hpos = round_fixed((norm->hvirtual * aspect - mode->hdisplay * scale)
+			   * priv->hmargin * mode->vtotal) / norm->vtotal / 100 / 4;
+
+	setbitf(state, CH7006_POV, HPOS_8, hpos);
+	setbitf(state, CH7006_HPOS, 0, hpos);
+
+	vpos = max(0, norm->vdisplay - round_fixed(mode->vdisplay*scale)
+		   + norm->voffset) * priv->vmargin / 100 / 2;
+
+	setbitf(state, CH7006_POV, VPOS_8, vpos);
+	setbitf(state, CH7006_VPOS, 0, vpos);
+
+	ch7006_dbg(client, "hpos: %d, vpos: %d\n", hpos, vpos);
+}
+
+/* HW access functions */
+
+void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val)
+{
+	uint8_t buf[] = {addr, val};
+	int ret;
+
+	ret = i2c_master_send(client, buf, ARRAY_SIZE(buf));
+	if (ret < 0)
+		ch7006_err(client, "Error %d writing to subaddress 0x%x\n",
+			   ret, addr);
+}
+
+uint8_t ch7006_read(struct i2c_client *client, uint8_t addr)
+{
+	uint8_t val;
+	int ret;
+
+	ret = i2c_master_send(client, &addr, sizeof(addr));
+	if (ret < 0)
+		goto fail;
+
+	ret = i2c_master_recv(client, &val, sizeof(val));
+	if (ret < 0)
+		goto fail;
+
+	return val;
+
+fail:
+	ch7006_err(client, "Error %d reading from subaddress 0x%x\n",
+		   ret, addr);
+	return 0;
+}
+
+void ch7006_state_load(struct i2c_client *client,
+		       struct ch7006_state *state)
+{
+	ch7006_load_reg(client, state, CH7006_POWER);
+
+	ch7006_load_reg(client, state, CH7006_DISPMODE);
+	ch7006_load_reg(client, state, CH7006_FFILTER);
+	ch7006_load_reg(client, state, CH7006_BWIDTH);
+	ch7006_load_reg(client, state, CH7006_INPUT_FORMAT);
+	ch7006_load_reg(client, state, CH7006_CLKMODE);
+	ch7006_load_reg(client, state, CH7006_START_ACTIVE);
+	ch7006_load_reg(client, state, CH7006_POV);
+	ch7006_load_reg(client, state, CH7006_BLACK_LEVEL);
+	ch7006_load_reg(client, state, CH7006_HPOS);
+	ch7006_load_reg(client, state, CH7006_VPOS);
+	ch7006_load_reg(client, state, CH7006_INPUT_SYNC);
+	ch7006_load_reg(client, state, CH7006_DETECT);
+	ch7006_load_reg(client, state, CH7006_CONTRAST);
+	ch7006_load_reg(client, state, CH7006_PLLOV);
+	ch7006_load_reg(client, state, CH7006_PLLM);
+	ch7006_load_reg(client, state, CH7006_PLLN);
+	ch7006_load_reg(client, state, CH7006_BCLKOUT);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC0);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC1);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC2);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC3);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC4);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC5);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC6);
+	ch7006_load_reg(client, state, CH7006_SUBC_INC7);
+	ch7006_load_reg(client, state, CH7006_PLL_CONTROL);
+	ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0);
+}
+
+void ch7006_state_save(struct i2c_client *client,
+		       struct ch7006_state *state)
+{
+	ch7006_save_reg(client, state, CH7006_POWER);
+
+	ch7006_save_reg(client, state, CH7006_DISPMODE);
+	ch7006_save_reg(client, state, CH7006_FFILTER);
+	ch7006_save_reg(client, state, CH7006_BWIDTH);
+	ch7006_save_reg(client, state, CH7006_INPUT_FORMAT);
+	ch7006_save_reg(client, state, CH7006_CLKMODE);
+	ch7006_save_reg(client, state, CH7006_START_ACTIVE);
+	ch7006_save_reg(client, state, CH7006_POV);
+	ch7006_save_reg(client, state, CH7006_BLACK_LEVEL);
+	ch7006_save_reg(client, state, CH7006_HPOS);
+	ch7006_save_reg(client, state, CH7006_VPOS);
+	ch7006_save_reg(client, state, CH7006_INPUT_SYNC);
+	ch7006_save_reg(client, state, CH7006_DETECT);
+	ch7006_save_reg(client, state, CH7006_CONTRAST);
+	ch7006_save_reg(client, state, CH7006_PLLOV);
+	ch7006_save_reg(client, state, CH7006_PLLM);
+	ch7006_save_reg(client, state, CH7006_PLLN);
+	ch7006_save_reg(client, state, CH7006_BCLKOUT);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC0);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC1);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC2);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC3);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC4);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC5);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC6);
+	ch7006_save_reg(client, state, CH7006_SUBC_INC7);
+	ch7006_save_reg(client, state, CH7006_PLL_CONTROL);
+	ch7006_save_reg(client, state, CH7006_CALC_SUBC_INC0);
+
+	state->regs[CH7006_FFILTER] = (state->regs[CH7006_FFILTER] & 0xf0) |
+		(state->regs[CH7006_FFILTER] & 0x0c) >> 2 |
+		(state->regs[CH7006_FFILTER] & 0x03) << 2;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_priv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_priv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/ch7006_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/ch7006_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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 __DRM_I2C_CH7006_PRIV_H__
+#define __DRM_I2C_CH7006_PRIV_H__
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "drm_encoder_slave.h"
+#include "i2c/ch7006.h"
+
+typedef int64_t fixed;
+#define fixed1 (1LL << 32)
+
+enum ch7006_tv_norm {
+	TV_NORM_PAL,
+	TV_NORM_PAL_M,
+	TV_NORM_PAL_N,
+	TV_NORM_PAL_NC,
+	TV_NORM_PAL_60,
+	TV_NORM_NTSC_M,
+	TV_NORM_NTSC_J,
+	NUM_TV_NORMS
+};
+
+struct ch7006_tv_norm_info {
+	fixed vrefresh;
+	int vdisplay;
+	int vtotal;
+	int hvirtual;
+
+	fixed subc_freq;
+	fixed black_level;
+
+	uint32_t dispmode;
+	int voffset;
+};
+
+struct ch7006_mode {
+	struct drm_display_mode mode;
+
+	int enc_hdisp;
+	int enc_vdisp;
+
+	fixed subc_coeff;
+	uint32_t dispmode;
+
+	uint32_t valid_scales;
+	uint32_t valid_norms;
+};
+
+struct ch7006_state {
+	uint8_t regs[0x26];
+};
+
+struct ch7006_priv {
+	struct ch7006_encoder_params *params;
+	struct ch7006_mode *mode;
+
+	struct ch7006_state state;
+	struct ch7006_state saved_state;
+
+	struct drm_property *scale_property;
+
+	int select_subconnector;
+	int subconnector;
+	int hmargin;
+	int vmargin;
+	enum ch7006_tv_norm norm;
+	int brightness;
+	int contrast;
+	int flicker;
+	int scale;
+
+	int last_dpms;
+};
+
+#define to_ch7006_priv(x) \
+	((struct ch7006_priv *)to_encoder_slave(x)->slave_priv)
+
+extern int ch7006_debug;
+extern char *ch7006_tv_norm;
+extern int ch7006_scale;
+
+extern char *ch7006_tv_norm_names[];
+extern struct ch7006_tv_norm_info ch7006_tv_norms[];
+extern struct ch7006_mode ch7006_modes[];
+
+struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder,
+				       struct drm_display_mode *drm_mode);
+
+void ch7006_setup_levels(struct drm_encoder *encoder);
+void ch7006_setup_subcarrier(struct drm_encoder *encoder);
+void ch7006_setup_pll(struct drm_encoder *encoder);
+void ch7006_setup_power_state(struct drm_encoder *encoder);
+void ch7006_setup_properties(struct drm_encoder *encoder);
+
+void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val);
+uint8_t ch7006_read(struct i2c_client *client, uint8_t addr);
+
+void ch7006_state_load(struct i2c_client *client,
+		       struct ch7006_state *state);
+void ch7006_state_save(struct i2c_client *client,
+		       struct ch7006_state *state);
+
+/* Some helper macros */
+
+#define ch7006_dbg(client, format, ...) do {				\
+		if (ch7006_debug)					\
+			dev_printk(KERN_DEBUG, &client->dev,		\
+				   "%s: " format, __func__, ## __VA_ARGS__); \
+	} while (0)
+#define ch7006_info(client, format, ...) \
+				dev_info(&client->dev, format, __VA_ARGS__)
+#define ch7006_err(client, format, ...) \
+				dev_err(&client->dev, format, __VA_ARGS__)
+
+#define __mask(src, bitfield) \
+		(((2 << (1 ? bitfield)) - 1) & ~((1 << (0 ? bitfield)) - 1))
+#define mask(bitfield) __mask(bitfield)
+
+#define __bitf(src, bitfield, x) \
+		(((x) >> (src) << (0 ? bitfield)) &  __mask(src, bitfield))
+#define bitf(bitfield, x) __bitf(bitfield, x)
+#define bitfs(bitfield, s) __bitf(bitfield, bitfield##_##s)
+#define setbitf(state, reg, bitfield, x)				\
+	state->regs[reg] = (state->regs[reg] & ~mask(reg##_##bitfield))	\
+		| bitf(reg##_##bitfield, x)
+
+#define __unbitf(src, bitfield, x) \
+		((x & __mask(src, bitfield)) >> (0 ? bitfield) << (src))
+#define unbitf(bitfield, x) __unbitf(bitfield, x)
+
+static inline int interpolate(int y0, int y1, int y2, int x)
+{
+	return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50;
+}
+
+static inline int32_t round_fixed(fixed x)
+{
+	return (x + fixed1/2) >> 32;
+}
+
+#define ch7006_load_reg(client, state, reg) ch7006_write(client, reg, state->regs[reg])
+#define ch7006_save_reg(client, state, reg) state->regs[reg] = ch7006_read(client, reg)
+
+/* Fixed hardware specs */
+
+#define CH7006_FREQ0				14318
+#define CH7006_MAXN				650
+#define CH7006_MAXM				315
+
+/* Register definitions */
+
+#define CH7006_DISPMODE				0x00
+#define CH7006_DISPMODE_INPUT_RES		0, 7:5
+#define CH7006_DISPMODE_INPUT_RES_512x384	0x0
+#define CH7006_DISPMODE_INPUT_RES_720x400	0x1
+#define CH7006_DISPMODE_INPUT_RES_640x400	0x2
+#define CH7006_DISPMODE_INPUT_RES_640x480	0x3
+#define CH7006_DISPMODE_INPUT_RES_800x600	0x4
+#define CH7006_DISPMODE_INPUT_RES_NATIVE	0x5
+#define CH7006_DISPMODE_OUTPUT_STD		0, 4:3
+#define CH7006_DISPMODE_OUTPUT_STD_PAL		0x0
+#define CH7006_DISPMODE_OUTPUT_STD_NTSC		0x1
+#define CH7006_DISPMODE_OUTPUT_STD_PAL_M	0x2
+#define CH7006_DISPMODE_OUTPUT_STD_NTSC_J	0x3
+#define CH7006_DISPMODE_SCALING_RATIO		0, 2:0
+#define CH7006_DISPMODE_SCALING_RATIO_5_4	0x0
+#define CH7006_DISPMODE_SCALING_RATIO_1_1	0x1
+#define CH7006_DISPMODE_SCALING_RATIO_7_8	0x2
+#define CH7006_DISPMODE_SCALING_RATIO_5_6	0x3
+#define CH7006_DISPMODE_SCALING_RATIO_3_4	0x4
+#define CH7006_DISPMODE_SCALING_RATIO_7_10	0x5
+
+#define CH7006_FFILTER				0x01
+#define CH7006_FFILTER_TEXT			0, 5:4
+#define CH7006_FFILTER_LUMA			0, 3:2
+#define CH7006_FFILTER_CHROMA			0, 1:0
+#define CH7006_FFILTER_CHROMA_NO_DCRAWL		0x3
+
+#define CH7006_BWIDTH				0x03
+#define CH7006_BWIDTH_5L_FFILER			(1 << 7)
+#define CH7006_BWIDTH_CVBS_NO_CHROMA		(1 << 6)
+#define CH7006_BWIDTH_CHROMA			0, 5:4
+#define CH7006_BWIDTH_SVIDEO_YPEAK		(1 << 3)
+#define CH7006_BWIDTH_SVIDEO_LUMA		0, 2:1
+#define CH7006_BWIDTH_CVBS_LUMA			0, 0:0
+
+#define CH7006_INPUT_FORMAT			0x04
+#define CH7006_INPUT_FORMAT_DAC_GAIN		(1 << 6)
+#define CH7006_INPUT_FORMAT_RGB_PASS_THROUGH	(1 << 5)
+#define CH7006_INPUT_FORMAT_FORMAT		0, 3:0
+#define CH7006_INPUT_FORMAT_FORMAT_RGB16	0x0
+#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m16	0x1
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m16	0x2
+#define CH7006_INPUT_FORMAT_FORMAT_RGB15	0x3
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12C	0x4
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12I	0x5
+#define CH7006_INPUT_FORMAT_FORMAT_RGB24m8	0x6
+#define CH7006_INPUT_FORMAT_FORMAT_RGB16m8	0x7
+#define CH7006_INPUT_FORMAT_FORMAT_RGB15m8	0x8
+#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m8	0x9
+
+#define CH7006_CLKMODE				0x06
+#define CH7006_CLKMODE_SUBC_LOCK		(1 << 7)
+#define CH7006_CLKMODE_MASTER			(1 << 6)
+#define CH7006_CLKMODE_POS_EDGE			(1 << 4)
+#define CH7006_CLKMODE_XCM			0, 3:2
+#define CH7006_CLKMODE_PCM			0, 1:0
+
+#define CH7006_START_ACTIVE			0x07
+#define CH7006_START_ACTIVE_0			0, 7:0
+
+#define CH7006_POV				0x08
+#define CH7006_POV_START_ACTIVE_8		8, 2:2
+#define CH7006_POV_HPOS_8			8, 1:1
+#define CH7006_POV_VPOS_8			8, 0:0
+
+#define CH7006_BLACK_LEVEL			0x09
+#define CH7006_BLACK_LEVEL_0			0, 7:0
+
+#define CH7006_HPOS				0x0a
+#define CH7006_HPOS_0				0, 7:0
+
+#define CH7006_VPOS				0x0b
+#define CH7006_VPOS_0				0, 7:0
+
+#define CH7006_INPUT_SYNC			0x0d
+#define CH7006_INPUT_SYNC_EMBEDDED		(1 << 3)
+#define CH7006_INPUT_SYNC_OUTPUT		(1 << 2)
+#define CH7006_INPUT_SYNC_PVSYNC		(1 << 1)
+#define CH7006_INPUT_SYNC_PHSYNC		(1 << 0)
+
+#define CH7006_POWER				0x0e
+#define CH7006_POWER_SCART			(1 << 4)
+#define CH7006_POWER_RESET			(1 << 3)
+#define CH7006_POWER_LEVEL			0, 2:0
+#define CH7006_POWER_LEVEL_CVBS_OFF		0x0
+#define CH7006_POWER_LEVEL_POWER_OFF		0x1
+#define CH7006_POWER_LEVEL_SVIDEO_OFF		0x2
+#define CH7006_POWER_LEVEL_NORMAL		0x3
+#define CH7006_POWER_LEVEL_FULL_POWER_OFF	0x4
+
+#define CH7006_DETECT				0x10
+#define CH7006_DETECT_SVIDEO_Y_TEST		(1 << 3)
+#define CH7006_DETECT_SVIDEO_C_TEST		(1 << 2)
+#define CH7006_DETECT_CVBS_TEST			(1 << 1)
+#define CH7006_DETECT_SENSE			(1 << 0)
+
+#define CH7006_CONTRAST				0x11
+#define CH7006_CONTRAST_0			0, 2:0
+
+#define CH7006_PLLOV	 			0x13
+#define CH7006_PLLOV_N_8	 		8, 2:1
+#define CH7006_PLLOV_M_8	 		8, 0:0
+
+#define CH7006_PLLM	 			0x14
+#define CH7006_PLLM_0	 			0, 7:0
+
+#define CH7006_PLLN	 			0x15
+#define CH7006_PLLN_0	 			0, 7:0
+
+#define CH7006_BCLKOUT	 			0x17
+
+#define CH7006_SUBC_INC0			0x18
+#define CH7006_SUBC_INC0_28			28, 3:0
+
+#define CH7006_SUBC_INC1			0x19
+#define CH7006_SUBC_INC1_24			24, 3:0
+
+#define CH7006_SUBC_INC2			0x1a
+#define CH7006_SUBC_INC2_20			20, 3:0
+
+#define CH7006_SUBC_INC3			0x1b
+#define CH7006_SUBC_INC3_GPIO1_VAL		(1 << 7)
+#define CH7006_SUBC_INC3_GPIO0_VAL		(1 << 6)
+#define CH7006_SUBC_INC3_POUT_3_3V		(1 << 5)
+#define CH7006_SUBC_INC3_POUT_INV		(1 << 4)
+#define CH7006_SUBC_INC3_16			16, 3:0
+
+#define CH7006_SUBC_INC4			0x1c
+#define CH7006_SUBC_INC4_GPIO1_IN		(1 << 7)
+#define CH7006_SUBC_INC4_GPIO0_IN		(1 << 6)
+#define CH7006_SUBC_INC4_DS_INPUT		(1 << 4)
+#define CH7006_SUBC_INC4_12			12, 3:0
+
+#define CH7006_SUBC_INC5			0x1d
+#define CH7006_SUBC_INC5_8			8, 3:0
+
+#define CH7006_SUBC_INC6			0x1e
+#define CH7006_SUBC_INC6_4			4, 3:0
+
+#define CH7006_SUBC_INC7			0x1f
+#define CH7006_SUBC_INC7_0			0, 3:0
+
+#define CH7006_PLL_CONTROL			0x20
+#define CH7006_PLL_CONTROL_CPI			(1 << 5)
+#define CH7006_PLL_CONTROL_CAPACITOR		(1 << 4)
+#define CH7006_PLL_CONTROL_7STAGES		(1 << 3)
+#define CH7006_PLL_CONTROL_DIGITAL_5V		(1 << 2)
+#define CH7006_PLL_CONTROL_ANALOG_5V		(1 << 1)
+#define CH7006_PLL_CONTROL_MEMORY_5V		(1 << 0)
+
+#define CH7006_CALC_SUBC_INC0			0x21
+#define CH7006_CALC_SUBC_INC0_24		24, 4:3
+#define CH7006_CALC_SUBC_INC0_HYST		0, 2:1
+#define CH7006_CALC_SUBC_INC0_AUTO		(1 << 0)
+
+#define CH7006_CALC_SUBC_INC1			0x22
+#define CH7006_CALC_SUBC_INC1_16		16, 7:0
+
+#define CH7006_CALC_SUBC_INC2			0x23
+#define CH7006_CALC_SUBC_INC2_8			8, 7:0
+
+#define CH7006_CALC_SUBC_INC3			0x24
+#define CH7006_CALC_SUBC_INC3_0			0, 7:0
+
+#define CH7006_VERSION_ID			0x25
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i2c/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i2c/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,4 @@
+ccflags-y := -Iinclude/drm
+
+ch7006-y := ch7006_drv.o ch7006_mode.o
+obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i810/i810_dma.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_dma.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i810/i810_dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,7 +115,7 @@ static int i810_mmap_buffers(struct file
 static const struct file_operations i810_buffer_fops = {
 	.open = drm_open,
 	.release = drm_release,
-	.ioctl = drm_ioctl,
+	.unlocked_ioctl = drm_ioctl,
 	.mmap = i810_mmap_buffers,
 	.fasync = drm_fasync,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i810/i810_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i810/i810_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i810/i810_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i830/i830_dma.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_dma.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i830/i830_dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,7 @@ static int i830_mmap_buffers(struct file
 static const struct file_operations i830_buffer_fops = {
 	.open = drm_open,
 	.release = drm_release,
-	.ioctl = drm_ioctl,
+	.unlocked_ioctl = drm_ioctl,
 	.mmap = i830_mmap_buffers,
 	.fasync = drm_fasync,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i830/i830_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i830/i830_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i830/i830_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ch7017.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ch7017.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ch7017.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ch7017.c	2010-02-24 13:52:17.000000000 -0500
@@ -249,7 +249,8 @@ static bool ch7017_init(struct intel_dvo
 	if (val != CH7017_DEVICE_ID_VALUE &&
 	    val != CH7018_DEVICE_ID_VALUE &&
 	    val != CH7019_DEVICE_ID_VALUE) {
-		DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
+				"Slave %d.\n",
 			  val, i2cbus->adapter.name,dvo->slave_addr);
 		goto fail;
 	}
@@ -284,7 +285,7 @@ static void ch7017_mode_set(struct intel
 	uint8_t horizontal_active_pixel_output, vertical_active_line_output;
 	uint8_t active_input_line_output;
 
-	DRM_DEBUG("Registers before mode setting\n");
+	DRM_DEBUG_KMS("Registers before mode setting\n");
 	ch7017_dump_regs(dvo);
 
 	/* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
@@ -346,7 +347,7 @@ static void ch7017_mode_set(struct intel
 	/* Turn the LVDS back on with new settings. */
 	ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down);
 
-	DRM_DEBUG("Registers after mode setting\n");
+	DRM_DEBUG_KMS("Registers after mode setting\n");
 	ch7017_dump_regs(dvo);
 }
 
@@ -386,7 +387,7 @@ static void ch7017_dump_regs(struct inte
 #define DUMP(reg)					\
 do {							\
 	ch7017_read(dvo, reg, &val);			\
-	DRM_DEBUG(#reg ": %02x\n", val);		\
+	DRM_DEBUG_KMS(#reg ": %02x\n", val);		\
 } while (0)
 
 	DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ch7xxx.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ch7xxx.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ch7xxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ch7xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,7 +152,7 @@ static bool ch7xxx_readb(struct intel_dv
 	};
 
 	if (!ch7xxx->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -179,7 +179,7 @@ static bool ch7xxx_writeb(struct intel_d
 		return true;
 
 	if (!ch7xxx->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -207,7 +207,8 @@ static bool ch7xxx_init(struct intel_dvo
 
 	name = ch7xxx_get_id(vendor);
 	if (!name) {
-		DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
 			  vendor, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -217,13 +218,14 @@ static bool ch7xxx_init(struct intel_dvo
 		goto out;
 
 	if (device != CH7xxx_DID) {
-		DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
+		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
+				"slave %d.\n",
 			  vendor, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 
 	ch7xxx->quiet = false;
-	DRM_DEBUG("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
+	DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
 		  name, vendor, device);
 	return true;
 out:
@@ -315,8 +317,8 @@ static void ch7xxx_dump_regs(struct inte
 
 	for (i = 0; i < CH7xxx_NUM_REGS; i++) {
 		if ((i % 8) == 0 )
-			DRM_DEBUG("\n %02X: ", i);
-		DRM_DEBUG("%02X ", ch7xxx->mode_reg.regs[i]);
+			DRM_LOG_KMS("\n %02X: ", i);
+		DRM_LOG_KMS("%02X ", ch7xxx->mode_reg.regs[i]);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ivch.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ivch.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_ivch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_ivch.c	2010-02-24 13:52:17.000000000 -0500
@@ -202,7 +202,8 @@ static bool ivch_read(struct intel_dvo_d
 	};
 
 	if (!priv->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from "
+				"%s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -230,7 +231,7 @@ static bool ivch_write(struct intel_dvo_
 		return true;
 
 	if (!priv->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -261,7 +262,7 @@ static bool ivch_init(struct intel_dvo_d
 	 * the address it's responding on.
 	 */
 	if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) {
-		DRM_DEBUG("ivch detect failed due to address mismatch "
+		DRM_DEBUG_KMS("ivch detect failed due to address mismatch "
 			  "(%d vs %d)\n",
 			  (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr);
 		goto out;
@@ -367,41 +368,41 @@ static void ivch_dump_regs(struct intel_
 	uint16_t val;
 
 	ivch_read(dvo, VR00, &val);
-	DRM_DEBUG("VR00: 0x%04x\n", val);
+	DRM_LOG_KMS("VR00: 0x%04x\n", val);
 	ivch_read(dvo, VR01, &val);
-	DRM_DEBUG("VR01: 0x%04x\n", val);
+	DRM_LOG_KMS("VR01: 0x%04x\n", val);
 	ivch_read(dvo, VR30, &val);
-	DRM_DEBUG("VR30: 0x%04x\n", val);
+	DRM_LOG_KMS("VR30: 0x%04x\n", val);
 	ivch_read(dvo, VR40, &val);
-	DRM_DEBUG("VR40: 0x%04x\n", val);
+	DRM_LOG_KMS("VR40: 0x%04x\n", val);
 
 	/* GPIO registers */
 	ivch_read(dvo, VR80, &val);
-	DRM_DEBUG("VR80: 0x%04x\n", val);
+	DRM_LOG_KMS("VR80: 0x%04x\n", val);
 	ivch_read(dvo, VR81, &val);
-	DRM_DEBUG("VR81: 0x%04x\n", val);
+	DRM_LOG_KMS("VR81: 0x%04x\n", val);
 	ivch_read(dvo, VR82, &val);
-	DRM_DEBUG("VR82: 0x%04x\n", val);
+	DRM_LOG_KMS("VR82: 0x%04x\n", val);
 	ivch_read(dvo, VR83, &val);
-	DRM_DEBUG("VR83: 0x%04x\n", val);
+	DRM_LOG_KMS("VR83: 0x%04x\n", val);
 	ivch_read(dvo, VR84, &val);
-	DRM_DEBUG("VR84: 0x%04x\n", val);
+	DRM_LOG_KMS("VR84: 0x%04x\n", val);
 	ivch_read(dvo, VR85, &val);
-	DRM_DEBUG("VR85: 0x%04x\n", val);
+	DRM_LOG_KMS("VR85: 0x%04x\n", val);
 	ivch_read(dvo, VR86, &val);
-	DRM_DEBUG("VR86: 0x%04x\n", val);
+	DRM_LOG_KMS("VR86: 0x%04x\n", val);
 	ivch_read(dvo, VR87, &val);
-	DRM_DEBUG("VR87: 0x%04x\n", val);
+	DRM_LOG_KMS("VR87: 0x%04x\n", val);
 	ivch_read(dvo, VR88, &val);
-	DRM_DEBUG("VR88: 0x%04x\n", val);
+	DRM_LOG_KMS("VR88: 0x%04x\n", val);
 
 	/* Scratch register 0 - AIM Panel type */
 	ivch_read(dvo, VR8E, &val);
-	DRM_DEBUG("VR8E: 0x%04x\n", val);
+	DRM_LOG_KMS("VR8E: 0x%04x\n", val);
 
 	/* Scratch register 1 - Status register */
 	ivch_read(dvo, VR8F, &val);
-	DRM_DEBUG("VR8F: 0x%04x\n", val);
+	DRM_LOG_KMS("VR8F: 0x%04x\n", val);
 }
 
 static void ivch_save(struct intel_dvo_device *dvo)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_sil164.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_sil164.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_sil164.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_sil164.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,7 +105,7 @@ static bool sil164_readb(struct intel_dv
 	};
 
 	if (!sil->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -131,7 +131,7 @@ static bool sil164_writeb(struct intel_d
 		return true;
 
 	if (!sil->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -158,7 +158,7 @@ static bool sil164_init(struct intel_dvo
 		goto out;
 
 	if (ch != (SIL164_VID & 0xff)) {
-		DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
 			  ch, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -167,13 +167,13 @@ static bool sil164_init(struct intel_dvo
 		goto out;
 
 	if (ch != (SIL164_DID & 0xff)) {
-		DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
 			  ch, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 	sil->quiet = false;
 
-	DRM_DEBUG("init sil164 dvo controller successfully!\n");
+	DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n");
 	return true;
 
 out:
@@ -241,15 +241,15 @@ static void sil164_dump_regs(struct inte
 	uint8_t val;
 
 	sil164_readb(dvo, SIL164_FREQ_LO, &val);
-	DRM_DEBUG("SIL164_FREQ_LO: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_FREQ_LO: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_FREQ_HI, &val);
-	DRM_DEBUG("SIL164_FREQ_HI: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_FREQ_HI: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REG8, &val);
-	DRM_DEBUG("SIL164_REG8: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REG8: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REG9, &val);
-	DRM_DEBUG("SIL164_REG9: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REG9: 0x%02x\n", val);
 	sil164_readb(dvo, SIL164_REGC, &val);
-	DRM_DEBUG("SIL164_REGC: 0x%02x\n", val);
+	DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val);
 }
 
 static void sil164_save(struct intel_dvo_device *dvo)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_tfp410.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_tfp410.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/dvo_tfp410.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/dvo_tfp410.c	2010-02-24 13:52:17.000000000 -0500
@@ -130,7 +130,7 @@ static bool tfp410_readb(struct intel_dv
 	};
 
 	if (!tfp->quiet) {
-		DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
+		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 	return false;
@@ -156,7 +156,7 @@ static bool tfp410_writeb(struct intel_d
 		return true;
 
 	if (!tfp->quiet) {
-		DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
+		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, i2cbus->adapter.name, dvo->slave_addr);
 	}
 
@@ -191,13 +191,15 @@ static bool tfp410_init(struct intel_dvo
 	tfp->quiet = true;
 
 	if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
-		DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
+				"Slave %d.\n",
 			  id, adapter->name, dvo->slave_addr);
 		goto out;
 	}
 
 	if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
-		DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n",
+		DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
+				"Slave %d.\n",
 			  id, adapter->name, dvo->slave_addr);
 		goto out;
 	}
@@ -262,33 +264,33 @@ static void tfp410_dump_regs(struct inte
 	uint8_t val, val2;
 
 	tfp410_readb(dvo, TFP410_REV, &val);
-	DRM_DEBUG("TFP410_REV: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_REV: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_1, &val);
-	DRM_DEBUG("TFP410_CTL1: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL1: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_2, &val);
-	DRM_DEBUG("TFP410_CTL2: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL2: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_CTL_3, &val);
-	DRM_DEBUG("TFP410_CTL3: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_CTL3: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_USERCFG, &val);
-	DRM_DEBUG("TFP410_USERCFG: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_USERCFG: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_DLY, &val);
-	DRM_DEBUG("TFP410_DE_DLY: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_CTL, &val);
-	DRM_DEBUG("TFP410_DE_CTL: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_TOP, &val);
-	DRM_DEBUG("TFP410_DE_TOP: 0x%02X\n", val);
+	DRM_LOG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
 	tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
 	tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
-	DRM_DEBUG("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
 	tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
-	DRM_DEBUG("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_H_RES_LO, &val);
 	tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
-	DRM_DEBUG("TFP410_H_RES: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
 	tfp410_readb(dvo, TFP410_V_RES_LO, &val);
 	tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
-	DRM_DEBUG("TFP410_V_RES: 0x%02X%02X\n", val2, val);
+	DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
 }
 
 static void tfp410_save(struct intel_dvo_device *dvo)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_debugfs.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
  */
 
 #include <linux/seq_file.h>
+#include <linux/debugfs.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -96,13 +97,14 @@ static int i915_gem_object_list_info(str
 	{
 		struct drm_gem_object *obj = obj_priv->obj;
 
-		seq_printf(m, "    %p: %s %8zd %08x %08x %d %s",
+		seq_printf(m, "    %p: %s %8zd %08x %08x %d%s%s",
 			   obj,
 			   get_pin_flag(obj_priv),
 			   obj->size,
 			   obj->read_domains, obj->write_domain,
 			   obj_priv->last_rendering_seqno,
-			   obj_priv->dirty ? "dirty" : "");
+			   obj_priv->dirty ? " dirty" : "",
+			   obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : "");
 
 		if (obj->name)
 			seq_printf(m, " (name: %d)", obj->name);
@@ -160,7 +162,7 @@ static int i915_interrupt_info(struct se
 	struct drm_device *dev = node->minor->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		seq_printf(m, "Interrupt enable:    %08x\n",
 			   I915_READ(IER));
 		seq_printf(m, "Interrupt identity:  %08x\n",
@@ -270,7 +272,7 @@ static void i915_dump_pages(struct seq_f
 		mem = kmap_atomic(pages[page], KM_USER0);
 		for (i = 0; i < PAGE_SIZE; i += 4)
 			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
-		kunmap_atomic(pages[page], KM_USER0);
+		kunmap_atomic(mem, KM_USER0);
 	}
 }
 
@@ -288,7 +290,7 @@ static int i915_batchbuffer_info(struct
 	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
 		obj = obj_priv->obj;
 		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
-		    ret = i915_gem_object_get_pages(obj);
+		    ret = i915_gem_object_get_pages(obj, 0);
 		    if (ret) {
 			    DRM_ERROR("Failed to get pages: %d\n", ret);
 			    spin_unlock(&dev_priv->mm.active_list_lock);
@@ -384,37 +386,111 @@ out:
 	return 0;
 }
 
-static int i915_registers_info(struct seq_file *m, void *data) {
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
+static int
+i915_wedged_open(struct inode *inode,
+		 struct file *filp)
+{
+	filp->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t
+i915_wedged_read(struct file *filp,
+		 char __user *ubuf,
+		 size_t max,
+		 loff_t *ppos)
+{
+	struct drm_device *dev = filp->private_data;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t reg;
+	char buf[80];
+	int len;
 
-#define DUMP_RANGE(start, end) \
-	for (reg=start; reg < end; reg += 4) \
-	seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
+	len = snprintf(buf, sizeof (buf),
+		       "wedged :  %d\n",
+		       atomic_read(&dev_priv->mm.wedged));
 
-	DUMP_RANGE(0x00000, 0x00fff);   /* VGA registers */
-	DUMP_RANGE(0x02000, 0x02fff);   /* instruction, memory, interrupt control registers */
-	DUMP_RANGE(0x03000, 0x031ff);   /* FENCE and PPGTT control registers */
-	DUMP_RANGE(0x03200, 0x03fff);   /* frame buffer compression registers */
-	DUMP_RANGE(0x05000, 0x05fff);   /* I/O control registers */
-	DUMP_RANGE(0x06000, 0x06fff);   /* clock control registers */
-	DUMP_RANGE(0x07000, 0x07fff);   /* 3D internal debug registers */
-	DUMP_RANGE(0x07400, 0x088ff);   /* GPE debug registers */
-	DUMP_RANGE(0x0a000, 0x0afff);   /* display palette registers */
-	DUMP_RANGE(0x10000, 0x13fff);   /* MMIO MCHBAR */
-	DUMP_RANGE(0x30000, 0x3ffff);   /* overlay registers */
-	DUMP_RANGE(0x60000, 0x6ffff);   /* display engine pipeline registers */
-	DUMP_RANGE(0x70000, 0x72fff);   /* display and cursor registers */
-	DUMP_RANGE(0x73000, 0x73fff);   /* performance counters */
+	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
+}
+
+static ssize_t
+i915_wedged_write(struct file *filp,
+		  const char __user *ubuf,
+		  size_t cnt,
+		  loff_t *ppos)
+{
+	struct drm_device *dev = filp->private_data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	char buf[20];
+	int val = 1;
+
+	if (cnt > 0) {
+		if (cnt > sizeof (buf) - 1)
+			return -EINVAL;
+
+		if (copy_from_user(buf, ubuf, cnt))
+			return -EFAULT;
+		buf[cnt] = 0;
+
+		val = simple_strtoul(buf, NULL, 0);
+	}
+
+	DRM_INFO("Manually setting wedged to %d\n", val);
+
+	atomic_set(&dev_priv->mm.wedged, val);
+	if (val) {
+		DRM_WAKEUP(&dev_priv->irq_queue);
+		queue_work(dev_priv->wq, &dev_priv->error_work);
+	}
+
+	return cnt;
+}
+
+static const struct file_operations i915_wedged_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_wedged_open,
+	.read = i915_wedged_read,
+	.write = i915_wedged_write,
+};
+
+/* As the drm_debugfs_init() routines are called before dev->dev_private is
+ * allocated we need to hook into the minor for release. */
+static int
+drm_add_fake_info_node(struct drm_minor *minor,
+		       struct dentry *ent,
+		       const void *key)
+{
+	struct drm_info_node *node;
+
+	node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
+	if (node == NULL) {
+		debugfs_remove(ent);
+		return -ENOMEM;
+	}
+
+	node->minor = minor;
+	node->dent = ent;
+	node->info_ent = (void *) key;
+	list_add(&node->list, &minor->debugfs_nodes.list);
 
 	return 0;
 }
 
+static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+
+	ent = debugfs_create_file("i915_wedged",
+				  S_IRUGO | S_IWUSR,
+				  root, dev,
+				  &i915_wedged_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+
+	return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
+}
 
 static struct drm_info_list i915_debugfs_list[] = {
-	{"i915_regs", i915_registers_info, 0},
 	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
 	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
 	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
@@ -432,6 +508,12 @@ static struct drm_info_list i915_debugfs
 
 int i915_debugfs_init(struct drm_minor *minor)
 {
+	int ret;
+
+	ret = i915_wedged_create(minor->debugfs_root, minor);
+	if (ret)
+		return ret;
+
 	return drm_debugfs_create_files(i915_debugfs_list,
 					I915_DEBUGFS_ENTRIES,
 					minor->debugfs_root, minor);
@@ -441,7 +523,8 @@ void i915_debugfs_cleanup(struct drm_min
 {
 	drm_debugfs_remove_files(i915_debugfs_list,
 				 I915_DEBUGFS_ENTRIES, minor);
+	drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
+				 1, minor);
 }
 
 #endif /* CONFIG_DEBUG_FS */
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_dma.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,7 +123,7 @@ static int i915_init_phys_hws(struct drm
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	/* Program Hardware Status Page */
 	dev_priv->status_page_dmah =
-		drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+		drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE);
 
 	if (!dev_priv->status_page_dmah) {
 		DRM_ERROR("Can not allocate hardware status page\n");
@@ -134,6 +134,10 @@ static int i915_init_phys_hws(struct drm
 
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 
+	if (IS_I965G(dev))
+		dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) &
+					     0xf0;
+
 	I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
 	DRM_DEBUG_DRIVER("Enabled hardware status page\n");
 	return 0;
@@ -731,8 +735,10 @@ static int i915_cmdbuffer(struct drm_dev
 	if (cmdbuf->num_cliprects) {
 		cliprects = kcalloc(cmdbuf->num_cliprects,
 				    sizeof(struct drm_clip_rect), GFP_KERNEL);
-		if (cliprects == NULL)
+		if (cliprects == NULL) {
+			ret = -ENOMEM;
 			goto fail_batch_free;
+		}
 
 		ret = copy_from_user(cliprects, cmdbuf->cliprects,
 				     cmdbuf->num_cliprects *
@@ -807,9 +813,19 @@ static int i915_getparam(struct drm_devi
 	case I915_PARAM_NUM_FENCES_AVAIL:
 		value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
 		break;
+	case I915_PARAM_HAS_OVERLAY:
+		value = dev_priv->overlay ? 1 : 0;
+		break;
+	case I915_PARAM_HAS_PAGEFLIPPING:
+		value = 1;
+		break;
+	case I915_PARAM_HAS_EXECBUF2:
+		/* depends on GEM */
+		value = dev_priv->has_gem;
+		break;
 	default:
 		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
-					param->param);
+				 param->param);
 		return -EINVAL;
 	}
 
@@ -962,7 +978,7 @@ static int i915_probe_agp(struct drm_dev
 	 * Some of the preallocated space is taken by the GTT
 	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
 	 */
-	if (IS_G4X(dev) || IS_IGD(dev) || IS_IGDNG(dev))
+	if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev))
 		overhead = 4096;
 	else
 		overhead = (*aperture_size / 1024) + 4096;
@@ -1048,7 +1064,7 @@ static unsigned long i915_gtt_to_phys(st
 	int gtt_offset, gtt_size;
 
 	if (IS_I965G(dev)) {
-		if (IS_G4X(dev) || IS_IGDNG(dev)) {
+		if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
 			gtt_offset = 2*1024*1024;
 			gtt_size = 2*1024*1024;
 		} else {
@@ -1070,7 +1086,7 @@ static unsigned long i915_gtt_to_phys(st
 
 	entry = *(volatile u32 *)(gtt + (gtt_addr / 1024));
 
-	DRM_DEBUG("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry);
+	DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry);
 
 	/* Mask out these reserved bits on this hardware. */
 	if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) ||
@@ -1096,7 +1112,7 @@ static unsigned long i915_gtt_to_phys(st
 	phys =(entry & PTE_ADDRESS_MASK) |
 		((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
 
-	DRM_DEBUG("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys);
+	DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys);
 
 	return phys;
 }
@@ -1111,7 +1127,8 @@ static void i915_setup_compression(struc
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_mm_node *compressed_fb, *compressed_llb;
-	unsigned long cfb_base, ll_base;
+	unsigned long cfb_base;
+	unsigned long ll_base = 0;
 
 	/* Leave 1M for line length buffer & misc. */
 	compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0);
@@ -1194,14 +1211,6 @@ static int i915_load_modeset_init(struct
 	dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
 		0xff000000;
 
-	if (IS_MOBILE(dev) || IS_I9XX(dev))
-		dev_priv->cursor_needs_physical = true;
-	else
-		dev_priv->cursor_needs_physical = false;
-
-	if (IS_I965G(dev) || IS_G33(dev))
-		dev_priv->cursor_needs_physical = false;
-
 	/* Basic memrange allocator for stolen space (aka vram) */
 	drm_mm_init(&dev_priv->vram, 0, prealloc_size);
 	DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024));
@@ -1251,6 +1260,8 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		goto destroy_ringbuffer;
 
+	intel_modeset_init(dev);
+
 	ret = drm_irq_install(dev);
 	if (ret)
 		goto destroy_ringbuffer;
@@ -1265,8 +1276,6 @@ static int i915_load_modeset_init(struct
 
 	I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
 
-	intel_modeset_init(dev);
-
 	drm_helper_initial_config(dev);
 
 	return 0;
@@ -1306,7 +1315,7 @@ static void i915_get_mem_freq(struct drm
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	u32 tmp;
 
-	if (!IS_IGD(dev))
+	if (!IS_PINEVIEW(dev))
 		return;
 
 	tmp = I915_READ(CLKCFG);
@@ -1354,7 +1363,7 @@ int i915_driver_load(struct drm_device *
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	resource_size_t base, size;
-	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
+	int ret = 0, mmio_bar;
 	uint32_t agp_size, prealloc_size, prealloc_start;
 
 	/* i915 has 4 more counters */
@@ -1370,8 +1379,10 @@ int i915_driver_load(struct drm_device *
 
 	dev->dev_private = (void *)dev_priv;
 	dev_priv->dev = dev;
+	dev_priv->info = (struct intel_device_info *) flags;
 
 	/* Add register map (needed for suspend/resume) */
+	mmio_bar = IS_I9XX(dev) ? 0 : 1;
 	base = drm_get_resource_start(dev, mmio_bar);
 	size = drm_get_resource_len(dev, mmio_bar);
 
@@ -1413,7 +1424,7 @@ int i915_driver_load(struct drm_device *
 	if (ret)
 		goto out_iomapfree;
 
-	dev_priv->wq = create_workqueue("i915");
+	dev_priv->wq = create_singlethread_workqueue("i915");
 	if (dev_priv->wq == NULL) {
 		DRM_ERROR("Failed to create our workqueue.\n");
 		ret = -ENOMEM;
@@ -1434,7 +1445,7 @@ int i915_driver_load(struct drm_device *
 
 	dev->driver->get_vblank_counter = i915_get_vblank_counter;
 	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-	if (IS_G4X(dev) || IS_IGDNG(dev)) {
+	if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
 		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
 		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
 	}
@@ -1489,9 +1500,7 @@ int i915_driver_load(struct drm_device *
 	}
 
 	/* Must be done after probing outputs */
-	/* FIXME: verify on IGDNG */
-	if (!IS_IGDNG(dev))
-		intel_opregion_init(dev, 0);
+	intel_opregion_init(dev, 0);
 
 	setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
 		    (unsigned long) dev);
@@ -1525,6 +1534,15 @@ int i915_driver_unload(struct drm_device
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		/*
+		 * 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;
+		}
 		drm_irq_uninstall(dev);
 		vga_client_register(dev->pdev, NULL, NULL, NULL);
 	}
@@ -1535,8 +1553,7 @@ int i915_driver_unload(struct drm_device
 	if (dev_priv->regs != NULL)
 		iounmap(dev_priv->regs);
 
-	if (!IS_IGDNG(dev))
-		intel_opregion_free(dev, 0);
+	intel_opregion_free(dev, 0);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		intel_modeset_cleanup(dev);
@@ -1548,6 +1565,8 @@ int i915_driver_unload(struct drm_device
 		mutex_unlock(&dev->struct_mutex);
 		drm_mm_takedown(&dev_priv->vram);
 		i915_gem_lastclose(dev);
+
+		intel_cleanup_overlay(dev);
 	}
 
 	pci_dev_put(dev_priv->bridge_dev);
@@ -1638,6 +1657,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
@@ -1656,6 +1676,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
 	DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
 	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,6 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-#include "drm_pciids.h"
 #include <linux/console.h>
 #include "drm_crtc_helper.h"
 
@@ -46,36 +45,149 @@ module_param_named(fbpercrtc, i915_fbper
 unsigned int i915_powersave = 1;
 module_param_named(powersave, i915_powersave, int, 0400);
 
+unsigned int i915_lvds_downclock = 0;
+module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
+
 static struct drm_driver driver;
 
-static struct pci_device_id pciidlist[] = {
-	i915_PCI_IDS
+#define INTEL_VGA_DEVICE(id, info) {		\
+	.class = PCI_CLASS_DISPLAY_VGA << 8,	\
+	.class_mask = 0xffff00,			\
+	.vendor = 0x8086,			\
+	.device = id,				\
+	.subvendor = PCI_ANY_ID,		\
+	.subdevice = PCI_ANY_ID,		\
+	.driver_data = (unsigned long) info }
+
+const static struct intel_device_info intel_i830_info = {
+	.is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+};
+
+const static struct intel_device_info intel_845g_info = {
+	.is_i8xx = 1,
+};
+
+const static struct intel_device_info intel_i85x_info = {
+	.is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+};
+
+const static struct intel_device_info intel_i865g_info = {
+	.is_i8xx = 1,
+};
+
+const static struct intel_device_info intel_i915g_info = {
+	.is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
+};
+const static struct intel_device_info intel_i915gm_info = {
+	.is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1,
+	.cursor_needs_physical = 1,
+};
+const static struct intel_device_info intel_i945g_info = {
+	.is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
+};
+const static struct intel_device_info intel_i945gm_info = {
+	.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+	.has_hotplug = 1, .cursor_needs_physical = 1,
+};
+
+const static struct intel_device_info intel_i965g_info = {
+	.is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_i965gm_info = {
+	.is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
+	.is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_g33_info = {
+	.is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_g45_info = {
+	.is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+	.has_pipe_cxsr = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_gm45_info = {
+	.is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
+	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
+	.has_pipe_cxsr = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_pineview_info = {
+	.is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
+	.need_gfx_hws = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_ironlake_d_info = {
+	.is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+	.has_pipe_cxsr = 1,
+	.has_hotplug = 1,
+};
+
+const static struct intel_device_info intel_ironlake_m_info = {
+	.is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
+	.need_gfx_hws = 1, .has_rc6 = 1,
+	.has_hotplug = 1,
+};
+
+const static struct pci_device_id pciidlist[] = {
+	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
+	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
+	INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
+	INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info),
+	INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
+	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
+	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
+	INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
+	INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
+	INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
+	INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
+	INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
+	INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
+	INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
+	INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
+	INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
+	INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
+	INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
+	INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
+	INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
+	INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
+	INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
+	INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
+	INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
+	INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
+	INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
+	INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
+	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
+	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
+	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
+	{0, 0, 0}
 };
 
 #if defined(CONFIG_DRM_I915_KMS)
 MODULE_DEVICE_TABLE(pci, pciidlist);
 #endif
 
-static int i915_suspend(struct drm_device *dev, pm_message_t state)
+static int i915_drm_freeze(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (!dev || !dev_priv) {
-		DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv);
-		DRM_ERROR("DRM not initialized, aborting suspend.\n");
-		return -ENODEV;
-	}
-
-	if (state.event == PM_EVENT_PRETHAW)
-		return 0;
-
 	pci_save_state(dev->pdev);
 
 	/* If KMS is active, we do the leavevt stuff here */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-		if (i915_gem_idle(dev))
+		int error = i915_gem_idle(dev);
+		if (error) {
 			dev_err(&dev->pdev->dev,
-				"GEM idle failed, resume may fail\n");
+				"GEM idle failed, resume might fail\n");
+			return error;
+		}
 		drm_irq_uninstall(dev);
 	}
 
@@ -83,26 +195,42 @@ static int i915_suspend(struct drm_devic
 
 	intel_opregion_free(dev, 1);
 
+	/* Modeset on resume, not lid events */
+	dev_priv->modeset_on_lid = 0;
+
+	return 0;
+}
+
+static int i915_suspend(struct drm_device *dev, pm_message_t state)
+{
+	int error;
+
+	if (!dev || !dev->dev_private) {
+		DRM_ERROR("dev: %p\n", dev);
+		DRM_ERROR("DRM not initialized, aborting suspend.\n");
+		return -ENODEV;
+	}
+
+	if (state.event == PM_EVENT_PRETHAW)
+		return 0;
+
+	error = i915_drm_freeze(dev);
+	if (error)
+		return error;
+
 	if (state.event == PM_EVENT_SUSPEND) {
 		/* Shut down the device */
 		pci_disable_device(dev->pdev);
 		pci_set_power_state(dev->pdev, PCI_D3hot);
 	}
 
-	/* Modeset on resume, not lid events */
-	dev_priv->modeset_on_lid = 0;
-
 	return 0;
 }
 
-static int i915_resume(struct drm_device *dev)
+static int i915_drm_thaw(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int ret = 0;
-
-	if (pci_enable_device(dev->pdev))
-		return -1;
-	pci_set_master(dev->pdev);
+	int error = 0;
 
 	i915_restore_state(dev);
 
@@ -113,21 +241,28 @@ static int i915_resume(struct drm_device
 		mutex_lock(&dev->struct_mutex);
 		dev_priv->mm.suspended = 0;
 
-		ret = i915_gem_init_ringbuffer(dev);
-		if (ret != 0)
-			ret = -1;
+		error = i915_gem_init_ringbuffer(dev);
 		mutex_unlock(&dev->struct_mutex);
 
 		drm_irq_install(dev);
-	}
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+
 		/* Resume the modeset for every activated CRTC */
 		drm_helper_resume_force_mode(dev);
 	}
 
 	dev_priv->modeset_on_lid = 0;
 
-	return ret;
+	return error;
+}
+
+static int i915_resume(struct drm_device *dev)
+{
+	if (pci_enable_device(dev->pdev))
+		return -EIO;
+
+	pci_set_master(dev->pdev);
+
+	return i915_drm_thaw(dev);
 }
 
 /**
@@ -268,22 +403,73 @@ i915_pci_remove(struct pci_dev *pdev)
 	drm_put_dev(dev);
 }
 
-static int
-i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int i915_pm_suspend(struct device *dev)
 {
-	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	int error;
 
-	return i915_suspend(dev, state);
+	if (!drm_dev || !drm_dev->dev_private) {
+		dev_err(dev, "DRM not initialized, aborting suspend.\n");
+		return -ENODEV;
+	}
+
+	error = i915_drm_freeze(drm_dev);
+	if (error)
+		return error;
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	return 0;
 }
 
-static int
-i915_pci_resume(struct pci_dev *pdev)
+static int i915_pm_resume(struct device *dev)
 {
-	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
 
-	return i915_resume(dev);
+	return i915_resume(drm_dev);
+}
+
+static int i915_pm_freeze(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	if (!drm_dev || !drm_dev->dev_private) {
+		dev_err(dev, "DRM not initialized, aborting suspend.\n");
+		return -ENODEV;
+	}
+
+	return i915_drm_freeze(drm_dev);
+}
+
+static int i915_pm_thaw(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	return i915_drm_thaw(drm_dev);
 }
 
+static int i915_pm_poweroff(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	return i915_drm_freeze(drm_dev);
+}
+
+const struct dev_pm_ops i915_pm_ops = {
+     .suspend = i915_pm_suspend,
+     .resume = i915_pm_resume,
+     .freeze = i915_pm_freeze,
+     .thaw = i915_pm_thaw,
+     .poweroff = i915_pm_poweroff,
+     .restore = i915_pm_resume,
+};
+
 static struct vm_operations_struct i915_gem_vm_ops = {
 	.fault = i915_gem_fault,
 	.open = drm_gem_vm_open,
@@ -303,8 +489,11 @@ static struct drm_driver driver = {
 	.lastclose = i915_driver_lastclose,
 	.preclose = i915_driver_preclose,
 	.postclose = i915_driver_postclose,
+
+	/* Used in place of i915_pm_ops for non-DRIVER_MODESET */
 	.suspend = i915_suspend,
 	.resume = i915_resume,
+
 	.device_is_agp = i915_driver_device_is_agp,
 	.enable_vblank = i915_enable_vblank,
 	.disable_vblank = i915_disable_vblank,
@@ -329,10 +518,11 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_gem_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
+		 .read = drm_read,
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = i915_compat_ioctl,
 #endif
@@ -343,10 +533,7 @@ static struct drm_driver driver = {
 		 .id_table = pciidlist,
 		 .probe = i915_pci_probe,
 		 .remove = i915_pci_remove,
-#ifdef CONFIG_PM
-		 .resume = i915_pci_resume,
-		 .suspend = i915_pci_suspend,
-#endif
+		 .driver.pm = &i915_pm_ops,
 	},
 
 	.name = DRIVER_NAME,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_drv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_drv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -170,9 +170,33 @@ struct drm_i915_display_funcs {
 	/* clock gating init */
 };
 
+struct intel_overlay;
+
+struct intel_device_info {
+	u8 is_mobile : 1;
+	u8 is_i8xx : 1;
+	u8 is_i915g : 1;
+	u8 is_i9xx : 1;
+	u8 is_i945gm : 1;
+	u8 is_i965g : 1;
+	u8 is_i965gm : 1;
+	u8 is_g33 : 1;
+	u8 need_gfx_hws : 1;
+	u8 is_g4x : 1;
+	u8 is_pineview : 1;
+	u8 is_ironlake : 1;
+	u8 has_fbc : 1;
+	u8 has_rc6 : 1;
+	u8 has_pipe_cxsr : 1;
+	u8 has_hotplug : 1;
+	u8 cursor_needs_physical : 1;
+};
+
 typedef struct drm_i915_private {
 	struct drm_device *dev;
 
+	const struct intel_device_info *info;
+
 	int has_gem;
 
 	void __iomem *regs;
@@ -187,6 +211,7 @@ typedef struct drm_i915_private {
 	unsigned int status_gfx_addr;
 	drm_local_map_t hws_map;
 	struct drm_gem_object *hws_obj;
+	struct drm_gem_object *pwrctx;
 
 	struct resource mch_res;
 
@@ -206,11 +231,13 @@ typedef struct drm_i915_private {
 	/** Cached value of IMR to avoid reads in updating the bitfield */
 	u32 irq_mask_reg;
 	u32 pipestat[2];
-	/** splitted irq regs for graphics and display engine on IGDNG,
+	/** splitted irq regs for graphics and display engine on Ironlake,
 	    irq_mask_reg is still used for display irq. */
 	u32 gt_irq_mask_reg;
 	u32 gt_irq_enable_reg;
 	u32 de_irq_enable_reg;
+	u32 pch_irq_mask_reg;
+	u32 pch_irq_enable_reg;
 
 	u32 hotplug_supported_mask;
 	struct work_struct hotplug_work;
@@ -227,8 +254,6 @@ typedef struct drm_i915_private {
 	int hangcheck_count;
 	uint32_t last_acthd;
 
-	bool cursor_needs_physical;
-
 	struct drm_mm vram;
 
 	unsigned long cfb_size;
@@ -240,6 +265,9 @@ typedef struct drm_i915_private {
 
 	struct intel_opregion opregion;
 
+	/* overlay */
+	struct intel_overlay *overlay;
+
 	/* LVDS info */
 	int backlight_duty_cycle;  /* restore backlight to this value */
 	bool panel_wants_dither;
@@ -255,10 +283,11 @@ typedef struct drm_i915_private {
 	unsigned int lvds_use_ssc:1;
 	unsigned int edp_support:1;
 	int lvds_ssc_freq;
+	int edp_bpp;
 
 	struct notifier_block lid_notifier;
 
-	int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
+	int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */
 	struct drm_i915_fence_reg fence_regs[16]; /* 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 */
@@ -279,7 +308,6 @@ typedef struct drm_i915_private {
 	u32 saveDSPACNTR;
 	u32 saveDSPBCNTR;
 	u32 saveDSPARB;
-	u32 saveRENDERSTANDBY;
 	u32 saveHWS;
 	u32 savePIPEACONF;
 	u32 savePIPEBCONF;
@@ -374,8 +402,6 @@ typedef struct drm_i915_private {
 	u32 saveFDI_RXA_IMR;
 	u32 saveFDI_RXB_IMR;
 	u32 saveCACHE_MODE_0;
-	u32 saveD_STATE;
-	u32 saveDSPCLK_GATE_D;
 	u32 saveMI_ARB_STATE;
 	u32 saveSWF0[16];
 	u32 saveSWF1[16];
@@ -467,6 +493,15 @@ typedef struct drm_i915_private {
 		struct list_head flushing_list;
 
 		/**
+		 * List of objects currently pending a GPU write flush.
+		 *
+		 * All elements on this list will belong to either the
+		 * active_list or flushing_list, last_rendering_seqno can
+		 * be used to differentiate between the two elements.
+		 */
+		struct list_head gpu_write_list;
+
+		/**
 		 * LRU list of objects which are not in the ringbuffer and
 		 * are ready to unbind, but are still in the GTT.
 		 *
@@ -539,13 +574,22 @@ typedef struct drm_i915_private {
 	/* indicate whether the LVDS_BORDER should be enabled or not */
 	unsigned int lvds_border_bits;
 
+	struct drm_crtc *plane_to_crtc_mapping[2];
+	struct drm_crtc *pipe_to_crtc_mapping[2];
+	wait_queue_head_t pending_flip_queue;
+
 	/* Reclocking support */
 	bool render_reclock_avail;
 	bool lvds_downclock_avail;
+	/* indicates the reduced downclock for LVDS*/
+	int lvds_downclock;
 	struct work_struct idle_work;
 	struct timer_list idle_timer;
 	bool busy;
 	u16 orig_clock;
+	int child_dev_num;
+	struct child_device_config *child_dev;
+	struct drm_connector *int_lvds_connector;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -557,6 +601,8 @@ struct drm_i915_gem_object {
 
 	/** This object's place on the active/flushing/inactive lists */
 	struct list_head list;
+	/** This object's place on GPU write list */
+	struct list_head gpu_write_list;
 
 	/** This object's place on the fenced object LRU */
 	struct list_head fence_list;
@@ -638,6 +684,13 @@ struct drm_i915_gem_object {
 	 * Advice: are the backing pages purgeable?
 	 */
 	int madv;
+
+	/**
+	 * Number of crtcs where this object is currently the fb, but
+	 * will be page flipped away on the next vblank.  When it
+	 * reaches 0, dev_priv->pending_flip_queue will be woken up.
+	 */
+	atomic_t pending_flip;
 };
 
 /**
@@ -681,6 +734,7 @@ extern struct drm_ioctl_desc i915_ioctls
 extern int i915_max_ioctl;
 extern unsigned int i915_fbpercrtc;
 extern unsigned int i915_powersave;
+extern unsigned int i915_lvds_downclock;
 
 extern void i915_save_display(struct drm_device *dev);
 extern void i915_restore_display(struct drm_device *dev);
@@ -738,6 +792,8 @@ 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);
+
 
 /* i915_mem.c */
 extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -770,6 +826,8 @@ int i915_gem_sw_finish_ioctl(struct drm_
 			     struct drm_file *file_priv);
 int i915_gem_execbuffer(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
+int i915_gem_execbuffer2(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
 int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
 		       struct drm_file *file_priv);
 int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
@@ -813,17 +871,22 @@ void i915_gem_cleanup_ringbuffer(struct
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
 		     unsigned long end);
 int i915_gem_idle(struct drm_device *dev);
+uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
+			  uint32_t flush_domains);
+int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
 				      int write);
+int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj);
 int i915_gem_attach_phys_object(struct drm_device *dev,
 				struct drm_gem_object *obj, int id);
 void i915_gem_detach_phys_object(struct drm_device *dev,
 				 struct drm_gem_object *obj);
 void i915_gem_free_all_phys_object(struct drm_device *dev);
-int i915_gem_object_get_pages(struct drm_gem_object *obj);
+int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
 void i915_gem_object_put_pages(struct drm_gem_object *obj);
 void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
+void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
 
 void i915_gem_shrinker_init(void);
 void i915_gem_shrinker_exit(void);
@@ -832,6 +895,9 @@ void i915_gem_shrinker_exit(void);
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
 void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
 void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
+bool i915_tiling_ok(struct drm_device *dev, int stride, int size,
+		    int tiling_mode);
+bool i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj);
 
 /* i915_gem_debug.c */
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
@@ -863,11 +929,13 @@ extern int i915_restore_state(struct drm
 extern int intel_opregion_init(struct drm_device *dev, int resume);
 extern void intel_opregion_free(struct drm_device *dev, int suspend);
 extern void opregion_asle_intr(struct drm_device *dev);
+extern void ironlake_opregion_gse_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
 static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
 static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
+static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
 
@@ -952,85 +1020,52 @@ extern void g4x_disable_fbc(struct drm_d
 extern int i915_wrap_ring(struct drm_device * dev);
 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
-#define IS_I830(dev) ((dev)->pci_device == 0x3577)
-#define IS_845G(dev) ((dev)->pci_device == 0x2562)
-#define IS_I85X(dev) ((dev)->pci_device == 0x3582)
-#define IS_I855(dev) ((dev)->pci_device == 0x3582)
-#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
-
-#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
-#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
-#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
-#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\
-		        (dev)->pci_device == 0x27AE)
-#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
-		       (dev)->pci_device == 0x2982 || \
-		       (dev)->pci_device == 0x2992 || \
-		       (dev)->pci_device == 0x29A2 || \
-		       (dev)->pci_device == 0x2A02 || \
-		       (dev)->pci_device == 0x2A12 || \
-		       (dev)->pci_device == 0x2A42 || \
-		       (dev)->pci_device == 0x2E02 || \
-		       (dev)->pci_device == 0x2E12 || \
-		       (dev)->pci_device == 0x2E22 || \
-		       (dev)->pci_device == 0x2E32 || \
-		       (dev)->pci_device == 0x2E42 || \
-		       (dev)->pci_device == 0x0042 || \
-		       (dev)->pci_device == 0x0046)
-
-#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02 || \
-			(dev)->pci_device == 0x2A12)
-
-#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
-
-#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
-		     (dev)->pci_device == 0x2E12 || \
-		     (dev)->pci_device == 0x2E22 || \
-		     (dev)->pci_device == 0x2E32 || \
-		     (dev)->pci_device == 0x2E42 || \
-		     IS_GM45(dev))
-
-#define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
-#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
-#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
-
-#define IS_G33(dev)    ((dev)->pci_device == 0x29C2 ||	\
-			(dev)->pci_device == 0x29B2 ||	\
-			(dev)->pci_device == 0x29D2 ||  \
-			(IS_IGD(dev)))
-
-#define IS_IGDNG_D(dev)	((dev)->pci_device == 0x0042)
-#define IS_IGDNG_M(dev)	((dev)->pci_device == 0x0046)
-#define IS_IGDNG(dev)	(IS_IGDNG_D(dev) || IS_IGDNG_M(dev))
+#define INTEL_INFO(dev)	(((struct drm_i915_private *) (dev)->dev_private)->info)
 
-#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
-		      IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \
-		      IS_IGDNG(dev))
+#define IS_I830(dev)		((dev)->pci_device == 0x3577)
+#define IS_845G(dev)		((dev)->pci_device == 0x2562)
+#define IS_I85X(dev)		((dev)->pci_device == 0x3582)
+#define IS_I865G(dev)		((dev)->pci_device == 0x2572)
+#define IS_I8XX(dev)		(INTEL_INFO(dev)->is_i8xx)
+#define IS_I915G(dev)		(INTEL_INFO(dev)->is_i915g)
+#define IS_I915GM(dev)		((dev)->pci_device == 0x2592)
+#define IS_I945G(dev)		((dev)->pci_device == 0x2772)
+#define IS_I945GM(dev)		(INTEL_INFO(dev)->is_i945gm)
+#define IS_I965G(dev)		(INTEL_INFO(dev)->is_i965g)
+#define IS_I965GM(dev)		(INTEL_INFO(dev)->is_i965gm)
+#define IS_GM45(dev)		((dev)->pci_device == 0x2A42)
+#define IS_G4X(dev)		(INTEL_INFO(dev)->is_g4x)
+#define IS_PINEVIEW_G(dev)	((dev)->pci_device == 0xa001)
+#define IS_PINEVIEW_M(dev)	((dev)->pci_device == 0xa011)
+#define IS_PINEVIEW(dev)	(INTEL_INFO(dev)->is_pineview)
+#define IS_G33(dev)		(INTEL_INFO(dev)->is_g33)
+#define IS_IRONLAKE_D(dev)	((dev)->pci_device == 0x0042)
+#define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)
+#define IS_IRONLAKE(dev)	(INTEL_INFO(dev)->is_ironlake)
+#define IS_I9XX(dev)		(INTEL_INFO(dev)->is_i9xx)
+#define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
 
-#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
-			IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
-			IS_IGD(dev) || IS_IGDNG_M(dev))
+#define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
-#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \
-				IS_IGDNG(dev))
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
  * rows, which changed the alignment requirements and fence programming.
  */
 #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
 						      IS_I915GM(dev)))
-#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
-#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
-#define SUPPORTS_EDP(dev)		(IS_IGDNG_M(dev))
-#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
+#define SUPPORTS_DIGITAL_OUTPUTS(dev)	(IS_I9XX(dev) && !IS_PINEVIEW(dev))
+#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IRONLAKE(dev))
+#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IRONLAKE(dev))
+#define SUPPORTS_EDP(dev)		(IS_IRONLAKE_M(dev))
+#define SUPPORTS_TV(dev)		(IS_I9XX(dev) && IS_MOBILE(dev) && \
+					!IS_IRONLAKE(dev) && !IS_PINEVIEW(dev))
+#define I915_HAS_HOTPLUG(dev)		 (INTEL_INFO(dev)->has_hotplug)
 /* dsparb controlled by hw only */
-#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
 
-#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
-#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
-#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \
-			   (IS_I9XX(dev) || IS_GM45(dev)) && \
-			   !IS_IGD(dev) && \
-			   !IS_IGDNG(dev))
+#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev))
+#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
+#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
+#define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6)
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_gem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_gem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem.c	2010-02-24 13:52:17.000000000 -0500
@@ -277,7 +277,7 @@ i915_gem_shmem_pread_fast(struct drm_dev
 
 	mutex_lock(&dev->struct_mutex);
 
-	ret = i915_gem_object_get_pages(obj);
+	ret = i915_gem_object_get_pages(obj, 0);
 	if (ret != 0)
 		goto fail_unlock;
 
@@ -321,40 +321,24 @@ fail_unlock:
 	return ret;
 }
 
-static inline gfp_t
-i915_gem_object_get_page_gfp_mask (struct drm_gem_object *obj)
-{
-	return mapping_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping);
-}
-
-static inline void
-i915_gem_object_set_page_gfp_mask (struct drm_gem_object *obj, gfp_t gfp)
-{
-	mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, gfp);
-}
-
 static int
 i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
 {
 	int ret;
 
-	ret = i915_gem_object_get_pages(obj);
+	ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN);
 
 	/* If we've insufficient memory to map in the pages, attempt
 	 * to make some space by throwing out some old buffers.
 	 */
 	if (ret == -ENOMEM) {
 		struct drm_device *dev = obj->dev;
-		gfp_t gfp;
 
 		ret = i915_gem_evict_something(dev, obj->size);
 		if (ret)
 			return ret;
 
-		gfp = i915_gem_object_get_page_gfp_mask(obj);
-		i915_gem_object_set_page_gfp_mask(obj, gfp & ~__GFP_NORETRY);
-		ret = i915_gem_object_get_pages(obj);
-		i915_gem_object_set_page_gfp_mask (obj, gfp);
+		ret = i915_gem_object_get_pages(obj, 0);
 	}
 
 	return ret;
@@ -790,7 +774,7 @@ i915_gem_shmem_pwrite_fast(struct drm_de
 
 	mutex_lock(&dev->struct_mutex);
 
-	ret = i915_gem_object_get_pages(obj);
+	ret = i915_gem_object_get_pages(obj, 0);
 	if (ret != 0)
 		goto fail_unlock;
 
@@ -1288,6 +1272,7 @@ i915_gem_create_mmap_offset(struct drm_g
 	list->hash.key = list->file_offset_node->start;
 	if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
 		DRM_ERROR("failed to add to map hash\n");
+		ret = -ENOMEM;
 		goto out_free_mm;
 	}
 
@@ -1309,7 +1294,7 @@ out_free_list:
  * i915_gem_release_mmap - remove physical page mappings
  * @obj: obj in question
  *
- * Preserve the reservation of the mmaping with the DRM core code, but
+ * Preserve the reservation of the mmapping with the DRM core code, but
  * relinquish ownership of the pages back to the system.
  *
  * It is vital that we remove the page mapping if we have mapped a tiled
@@ -1567,6 +1552,8 @@ i915_gem_object_move_to_inactive(struct
 	else
 		list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
 
+	BUG_ON(!list_empty(&obj_priv->gpu_write_list));
+
 	obj_priv->last_rendering_seqno = 0;
 	if (obj_priv->active) {
 		obj_priv->active = 0;
@@ -1583,7 +1570,7 @@ i915_gem_object_move_to_inactive(struct
  *
  * Returned sequence numbers are nonzero on success.
  */
-static uint32_t
+uint32_t
 i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
 		 uint32_t flush_domains)
 {
@@ -1617,7 +1604,7 @@ i915_add_request(struct drm_device *dev,
 	OUT_RING(MI_USER_INTERRUPT);
 	ADVANCE_LP_RING();
 
-	DRM_DEBUG("%d\n", seqno);
+	DRM_DEBUG_DRIVER("%d\n", seqno);
 
 	request->seqno = seqno;
 	request->emitted_jiffies = jiffies;
@@ -1637,7 +1624,8 @@ i915_add_request(struct drm_device *dev,
 		struct drm_i915_gem_object *obj_priv, *next;
 
 		list_for_each_entry_safe(obj_priv, next,
-					 &dev_priv->mm.flushing_list, list) {
+					 &dev_priv->mm.gpu_write_list,
+					 gpu_write_list) {
 			struct drm_gem_object *obj = obj_priv->obj;
 
 			if ((obj->write_domain & flush_domains) ==
@@ -1645,6 +1633,7 @@ i915_add_request(struct drm_device *dev,
 				uint32_t old_write_domain = obj->write_domain;
 
 				obj->write_domain = 0;
+				list_del_init(&obj_priv->gpu_write_list);
 				i915_gem_object_move_to_active(obj, seqno);
 
 				trace_i915_gem_object_change_domain(obj,
@@ -1820,12 +1809,8 @@ i915_gem_retire_work_handler(struct work
 	mutex_unlock(&dev->struct_mutex);
 }
 
-/**
- * Waits for a sequence number to be signaled, and cleans up the
- * request and object lists appropriately for that event.
- */
-static int
-i915_wait_request(struct drm_device *dev, uint32_t seqno)
+int
+i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	u32 ier;
@@ -1837,7 +1822,7 @@ i915_wait_request(struct drm_device *dev
 		return -EIO;
 
 	if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			ier = I915_READ(DEIER) | I915_READ(GTIER);
 		else
 			ier = I915_READ(IER);
@@ -1852,10 +1837,15 @@ i915_wait_request(struct drm_device *dev
 
 		dev_priv->mm.waiting_gem_seqno = seqno;
 		i915_user_irq_get(dev);
-		ret = wait_event_interruptible(dev_priv->irq_queue,
-					       i915_seqno_passed(i915_get_gem_seqno(dev),
-								 seqno) ||
-					       atomic_read(&dev_priv->mm.wedged));
+		if (interruptible)
+			ret = wait_event_interruptible(dev_priv->irq_queue,
+				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+				atomic_read(&dev_priv->mm.wedged));
+		else
+			wait_event(dev_priv->irq_queue,
+				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
+				atomic_read(&dev_priv->mm.wedged));
+
 		i915_user_irq_put(dev);
 		dev_priv->mm.waiting_gem_seqno = 0;
 
@@ -1879,6 +1869,16 @@ i915_wait_request(struct drm_device *dev
 	return ret;
 }
 
+/**
+ * Waits for a sequence number to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+static int
+i915_wait_request(struct drm_device *dev, uint32_t seqno)
+{
+	return i915_do_wait_request(dev, seqno, 1);
+}
+
 static void
 i915_gem_flush(struct drm_device *dev,
 	       uint32_t invalidate_domains,
@@ -1947,7 +1947,7 @@ i915_gem_flush(struct drm_device *dev,
 #endif
 		BEGIN_LP_RING(2);
 		OUT_RING(cmd);
-		OUT_RING(0); /* noop */
+		OUT_RING(MI_NOOP);
 		ADVANCE_LP_RING();
 	}
 }
@@ -2009,9 +2009,6 @@ i915_gem_object_unbind(struct drm_gem_ob
 	/* blow away mappings if mapped through GTT */
 	i915_gem_release_mmap(obj);
 
-	if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
-		i915_gem_clear_fence_reg(obj);
-
 	/* Move the object to the CPU domain to ensure that
 	 * any possible CPU writes while it's not in the GTT
 	 * are flushed when we go to remap it. This will
@@ -2027,6 +2024,10 @@ i915_gem_object_unbind(struct drm_gem_ob
 
 	BUG_ON(obj_priv->active);
 
+	/* release the fence reg _after_ flushing */
+	if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+		i915_gem_clear_fence_reg(obj);
+
 	if (obj_priv->agp_mem != NULL) {
 		drm_unbind_agp(obj_priv->agp_mem);
 		drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
@@ -2087,8 +2088,8 @@ static int
 i915_gem_evict_everything(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t seqno;
 	int ret;
+	uint32_t seqno;
 	bool lists_empty;
 
 	spin_lock(&dev_priv->mm.active_list_lock);
@@ -2110,6 +2111,8 @@ i915_gem_evict_everything(struct drm_dev
 	if (ret)
 		return ret;
 
+	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+
 	ret = i915_gem_evict_from_inactive_list(dev);
 	if (ret)
 		return ret;
@@ -2217,7 +2220,8 @@ i915_gem_evict_something(struct drm_devi
 }
 
 int
-i915_gem_object_get_pages(struct drm_gem_object *obj)
+i915_gem_object_get_pages(struct drm_gem_object *obj,
+			  gfp_t gfpmask)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int page_count, i;
@@ -2243,7 +2247,10 @@ i915_gem_object_get_pages(struct drm_gem
 	inode = obj->filp->f_path.dentry->d_inode;
 	mapping = inode->i_mapping;
 	for (i = 0; i < page_count; i++) {
-		page = read_mapping_page(mapping, i, NULL);
+		page = read_cache_page_gfp(mapping, i,
+					   mapping_gfp_mask (mapping) |
+					   __GFP_COLD |
+					   gfpmask);
 		if (IS_ERR(page)) {
 			ret = PTR_ERR(page);
 			i915_gem_object_put_pages(obj);
@@ -2566,12 +2573,9 @@ i915_gem_object_bind_to_gtt(struct drm_g
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	struct drm_mm_node *free_space;
-	bool retry_alloc = false;
+	gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;
 	int ret;
 
-	if (dev_priv->mm.suspended)
-		return -EBUSY;
-
 	if (obj_priv->madv != I915_MADV_WILLNEED) {
 		DRM_ERROR("Attempting to bind a purgeable object\n");
 		return -EINVAL;
@@ -2613,15 +2617,7 @@ i915_gem_object_bind_to_gtt(struct drm_g
 	DRM_INFO("Binding object of size %zd at 0x%08x\n",
 		 obj->size, obj_priv->gtt_offset);
 #endif
-	if (retry_alloc) {
-		i915_gem_object_set_page_gfp_mask (obj,
-						   i915_gem_object_get_page_gfp_mask (obj) & ~__GFP_NORETRY);
-	}
-	ret = i915_gem_object_get_pages(obj);
-	if (retry_alloc) {
-		i915_gem_object_set_page_gfp_mask (obj,
-						   i915_gem_object_get_page_gfp_mask (obj) | __GFP_NORETRY);
-	}
+	ret = i915_gem_object_get_pages(obj, gfpmask);
 	if (ret) {
 		drm_mm_put_block(obj_priv->gtt_space);
 		obj_priv->gtt_space = NULL;
@@ -2631,9 +2627,9 @@ i915_gem_object_bind_to_gtt(struct drm_g
 			ret = i915_gem_evict_something(dev, obj->size);
 			if (ret) {
 				/* now try to shrink everyone else */
-				if (! retry_alloc) {
-				    retry_alloc = true;
-				    goto search_free;
+				if (gfpmask) {
+					gfpmask = 0;
+					goto search_free;
 				}
 
 				return ret;
@@ -2711,7 +2707,7 @@ i915_gem_object_flush_gpu_write_domain(s
 	old_write_domain = obj->write_domain;
 	i915_gem_flush(dev, 0, obj->write_domain);
 	seqno = i915_add_request(dev, NULL, obj->write_domain);
-	obj->write_domain = 0;
+	BUG_ON(obj->write_domain);
 	i915_gem_object_move_to_active(obj, seqno);
 
 	trace_i915_gem_object_change_domain(obj,
@@ -2760,6 +2756,22 @@ i915_gem_object_flush_cpu_write_domain(s
 					    old_write_domain);
 }
 
+void
+i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
+{
+	switch (obj->write_domain) {
+	case I915_GEM_DOMAIN_GTT:
+		i915_gem_object_flush_gtt_write_domain(obj);
+		break;
+	case I915_GEM_DOMAIN_CPU:
+		i915_gem_object_flush_cpu_write_domain(obj);
+		break;
+	default:
+		i915_gem_object_flush_gpu_write_domain(obj);
+		break;
+	}
+}
+
 /**
  * Moves a single object to the GTT read, and possibly write domain.
  *
@@ -2811,6 +2823,57 @@ i915_gem_object_set_to_gtt_domain(struct
 	return 0;
 }
 
+/*
+ * Prepare buffer for display plane. Use uninterruptible for possible flush
+ * wait, as in modesetting process we're not supposed to be interrupted.
+ */
+int
+i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	uint32_t old_write_domain, old_read_domains;
+	int ret;
+
+	/* Not valid to be called on unbound objects. */
+	if (obj_priv->gtt_space == NULL)
+		return -EINVAL;
+
+	i915_gem_object_flush_gpu_write_domain(obj);
+
+	/* Wait on any GPU rendering and flushing to occur. */
+	if (obj_priv->active) {
+#if WATCH_BUF
+		DRM_INFO("%s: object %p wait for seqno %08x\n",
+			  __func__, obj, obj_priv->last_rendering_seqno);
+#endif
+		ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0);
+		if (ret != 0)
+			return ret;
+	}
+
+	old_write_domain = obj->write_domain;
+	old_read_domains = obj->read_domains;
+
+	obj->read_domains &= I915_GEM_DOMAIN_GTT;
+
+	i915_gem_object_flush_cpu_write_domain(obj);
+
+	/* It should now be out of any other write domains, and we can update
+	 * the domain values for our changes.
+	 */
+	BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
+	obj->read_domains |= I915_GEM_DOMAIN_GTT;
+	obj->write_domain = I915_GEM_DOMAIN_GTT;
+	obj_priv->dirty = 1;
+
+	trace_i915_gem_object_change_domain(obj,
+					    old_read_domains,
+					    old_write_domain);
+
+	return 0;
+}
+
 /**
  * Moves a single object to the CPU read, and possibly write domain.
  *
@@ -3170,7 +3233,7 @@ i915_gem_object_set_cpu_read_domain_rang
 static int
 i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 				 struct drm_file *file_priv,
-				 struct drm_i915_gem_exec_object *entry,
+				 struct drm_i915_gem_exec_object2 *entry,
 				 struct drm_i915_gem_relocation_entry *relocs)
 {
 	struct drm_device *dev = obj->dev;
@@ -3178,12 +3241,35 @@ i915_gem_object_pin_and_relocate(struct
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int i, ret;
 	void __iomem *reloc_page;
+	bool need_fence;
+
+	need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
+	             obj_priv->tiling_mode != I915_TILING_NONE;
+
+	/* Check fence reg constraints and rebind if necessary */
+	if (need_fence && !i915_obj_fenceable(dev, obj))
+		i915_gem_object_unbind(obj);
 
 	/* Choose the GTT offset for our buffer and put it there. */
 	ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
 	if (ret)
 		return ret;
 
+	/*
+	 * Pre-965 chips need a fence register set up in order to
+	 * properly handle blits to/from tiled surfaces.
+	 */
+	if (need_fence) {
+		ret = i915_gem_object_get_fence_reg(obj);
+		if (ret != 0) {
+			if (ret != -EBUSY && ret != -ERESTARTSYS)
+				DRM_ERROR("Failure to install fence: %d\n",
+					  ret);
+			i915_gem_object_unpin(obj);
+			return ret;
+		}
+	}
+
 	entry->offset = obj_priv->gtt_offset;
 
 	/* Apply the relocations, using the GTT aperture to avoid cache
@@ -3345,7 +3431,7 @@ i915_gem_object_pin_and_relocate(struct
  */
 static int
 i915_dispatch_gem_execbuffer(struct drm_device *dev,
-			      struct drm_i915_gem_execbuffer *exec,
+			      struct drm_i915_gem_execbuffer2 *exec,
 			      struct drm_clip_rect *cliprects,
 			      uint64_t exec_offset)
 {
@@ -3435,7 +3521,7 @@ i915_gem_ring_throttle(struct drm_device
 }
 
 static int
-i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
+i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object2 *exec_list,
 			      uint32_t buffer_count,
 			      struct drm_i915_gem_relocation_entry **relocs)
 {
@@ -3450,8 +3536,10 @@ i915_gem_get_relocs_from_user(struct drm
 	}
 
 	*relocs = drm_calloc_large(reloc_count, sizeof(**relocs));
-	if (*relocs == NULL)
+	if (*relocs == NULL) {
+		DRM_ERROR("failed to alloc relocs, count %d\n", reloc_count);
 		return -ENOMEM;
+	}
 
 	for (i = 0; i < buffer_count; i++) {
 		struct drm_i915_gem_relocation_entry __user *user_relocs;
@@ -3475,13 +3563,16 @@ i915_gem_get_relocs_from_user(struct drm
 }
 
 static int
-i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list,
+i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *exec_list,
 			    uint32_t buffer_count,
 			    struct drm_i915_gem_relocation_entry *relocs)
 {
 	uint32_t reloc_count = 0, i;
 	int ret = 0;
 
+	if (relocs == NULL)
+	    return 0;
+
 	for (i = 0; i < buffer_count; i++) {
 		struct drm_i915_gem_relocation_entry __user *user_relocs;
 		int unwritten;
@@ -3508,7 +3599,7 @@ err:
 }
 
 static int
-i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec,
+i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec,
 			   uint64_t exec_offset)
 {
 	uint32_t exec_start, exec_len;
@@ -3525,22 +3616,57 @@ i915_gem_check_execbuffer (struct drm_i9
 	return 0;
 }
 
+static int
+i915_gem_wait_for_pending_flip(struct drm_device *dev,
+			       struct drm_gem_object **object_list,
+			       int count)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv;
+	DEFINE_WAIT(wait);
+	int i, ret = 0;
+
+	for (;;) {
+		prepare_to_wait(&dev_priv->pending_flip_queue,
+				&wait, TASK_INTERRUPTIBLE);
+		for (i = 0; i < count; i++) {
+			obj_priv = object_list[i]->driver_private;
+			if (atomic_read(&obj_priv->pending_flip) > 0)
+				break;
+		}
+		if (i == count)
+			break;
+
+		if (!signal_pending(current)) {
+			mutex_unlock(&dev->struct_mutex);
+			schedule();
+			mutex_lock(&dev->struct_mutex);
+			continue;
+		}
+		ret = -ERESTARTSYS;
+		break;
+	}
+	finish_wait(&dev_priv->pending_flip_queue, &wait);
+
+	return ret;
+}
+
 int
-i915_gem_execbuffer(struct drm_device *dev, void *data,
-		    struct drm_file *file_priv)
+i915_gem_do_execbuffer(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv,
+		       struct drm_i915_gem_execbuffer2 *args,
+		       struct drm_i915_gem_exec_object2 *exec_list)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_execbuffer *args = data;
-	struct drm_i915_gem_exec_object *exec_list = NULL;
 	struct drm_gem_object **object_list = NULL;
 	struct drm_gem_object *batch_obj;
 	struct drm_i915_gem_object *obj_priv;
 	struct drm_clip_rect *cliprects = NULL;
-	struct drm_i915_gem_relocation_entry *relocs;
-	int ret, ret2, i, pinned = 0;
+	struct drm_i915_gem_relocation_entry *relocs = NULL;
+	int ret = 0, ret2, i, pinned = 0;
 	uint64_t exec_offset;
 	uint32_t seqno, flush_domains, reloc_index;
-	int pin_tries;
+	int pin_tries, flips;
 
 #if WATCH_EXEC
 	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -3551,31 +3677,21 @@ i915_gem_execbuffer(struct drm_device *d
 		DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
 		return -EINVAL;
 	}
-	/* Copy in the exec list from userland */
-	exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count);
-	object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count);
-	if (exec_list == NULL || object_list == NULL) {
-		DRM_ERROR("Failed to allocate exec or object list "
-			  "for %d buffers\n",
+	object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count);
+	if (object_list == NULL) {
+		DRM_ERROR("Failed to allocate object list for %d buffers\n",
 			  args->buffer_count);
 		ret = -ENOMEM;
 		goto pre_mutex_err;
 	}
-	ret = copy_from_user(exec_list,
-			     (struct drm_i915_relocation_entry __user *)
-			     (uintptr_t) args->buffers_ptr,
-			     sizeof(*exec_list) * args->buffer_count);
-	if (ret != 0) {
-		DRM_ERROR("copy %d exec entries failed %d\n",
-			  args->buffer_count, ret);
-		goto pre_mutex_err;
-	}
 
 	if (args->num_cliprects != 0) {
 		cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects),
 				    GFP_KERNEL);
-		if (cliprects == NULL)
+		if (cliprects == NULL) {
+			ret = -ENOMEM;
 			goto pre_mutex_err;
+		}
 
 		ret = copy_from_user(cliprects,
 				     (struct drm_clip_rect __user *)
@@ -3598,26 +3714,27 @@ i915_gem_execbuffer(struct drm_device *d
 	i915_verify_inactive(dev, __FILE__, __LINE__);
 
 	if (atomic_read(&dev_priv->mm.wedged)) {
-		DRM_ERROR("Execbuf while wedged\n");
 		mutex_unlock(&dev->struct_mutex);
 		ret = -EIO;
 		goto pre_mutex_err;
 	}
 
 	if (dev_priv->mm.suspended) {
-		DRM_ERROR("Execbuf while VT-switched.\n");
 		mutex_unlock(&dev->struct_mutex);
 		ret = -EBUSY;
 		goto pre_mutex_err;
 	}
 
 	/* Look up object handles */
+	flips = 0;
 	for (i = 0; i < args->buffer_count; i++) {
 		object_list[i] = drm_gem_object_lookup(dev, file_priv,
 						       exec_list[i].handle);
 		if (object_list[i] == NULL) {
 			DRM_ERROR("Invalid object handle %d at index %d\n",
 				   exec_list[i].handle, i);
+			/* prevent error path from reading uninitialized data */
+			args->buffer_count = i + 1;
 			ret = -EBADF;
 			goto err;
 		}
@@ -3626,10 +3743,20 @@ i915_gem_execbuffer(struct drm_device *d
 		if (obj_priv->in_execbuffer) {
 			DRM_ERROR("Object %p appears more than once in object list\n",
 				   object_list[i]);
+			/* prevent error path from reading uninitialized data */
+			args->buffer_count = i + 1;
 			ret = -EBADF;
 			goto err;
 		}
 		obj_priv->in_execbuffer = true;
+		flips += atomic_read(&obj_priv->pending_flip);
+	}
+
+	if (flips > 0) {
+		ret = i915_gem_wait_for_pending_flip(dev, object_list,
+						     args->buffer_count);
+		if (ret)
+			goto err;
 	}
 
 	/* Pin and relocate */
@@ -3731,16 +3858,23 @@ i915_gem_execbuffer(struct drm_device *d
 		i915_gem_flush(dev,
 			       dev->invalidate_domains,
 			       dev->flush_domains);
-		if (dev->flush_domains)
+		if (dev->flush_domains & I915_GEM_GPU_DOMAINS)
 			(void)i915_add_request(dev, file_priv,
 					       dev->flush_domains);
 	}
 
 	for (i = 0; i < args->buffer_count; i++) {
 		struct drm_gem_object *obj = object_list[i];
+		struct drm_i915_gem_object *obj_priv = obj->driver_private;
 		uint32_t old_write_domain = obj->write_domain;
 
 		obj->write_domain = obj->pending_write_domain;
+		if (obj->write_domain)
+			list_move_tail(&obj_priv->gpu_write_list,
+				       &dev_priv->mm.gpu_write_list);
+		else
+			list_del_init(&obj_priv->gpu_write_list);
+
 		trace_i915_gem_object_change_domain(obj,
 						    obj->read_domains,
 						    old_write_domain);
@@ -3814,8 +3948,101 @@ err:
 
 	mutex_unlock(&dev->struct_mutex);
 
+pre_mutex_err:
+	/* Copy the updated relocations out regardless of current error
+	 * state.  Failure to update the relocs would mean that the next
+	 * time userland calls execbuf, it would do so with presumed offset
+	 * state that didn't match the actual object state.
+	 */
+	ret2 = i915_gem_put_relocs_to_user(exec_list, args->buffer_count,
+					   relocs);
+	if (ret2 != 0) {
+		DRM_ERROR("Failed to copy relocations back out: %d\n", ret2);
+
+		if (ret == 0)
+			ret = ret2;
+	}
+
+	drm_free_large(object_list);
+	kfree(cliprects);
+
+	return ret;
+}
+
+/*
+ * Legacy execbuffer just creates an exec2 list from the original exec object
+ * list array and passes it to the real function.
+ */
+int
+i915_gem_execbuffer(struct drm_device *dev, void *data,
+		    struct drm_file *file_priv)
+{
+	struct drm_i915_gem_execbuffer *args = data;
+	struct drm_i915_gem_execbuffer2 exec2;
+	struct drm_i915_gem_exec_object *exec_list = NULL;
+	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
+	int ret, i;
+
+#if WATCH_EXEC
+	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
+		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
+#endif
+
+	if (args->buffer_count < 1) {
+		DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
+		return -EINVAL;
+	}
+
+	/* Copy in the exec list from userland */
+	exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
+	exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
+	if (exec_list == NULL || exec2_list == NULL) {
+		DRM_ERROR("Failed to allocate exec list for %d buffers\n",
+			  args->buffer_count);
+		drm_free_large(exec_list);
+		drm_free_large(exec2_list);
+		return -ENOMEM;
+	}
+	ret = copy_from_user(exec_list,
+			     (struct drm_i915_relocation_entry __user *)
+			     (uintptr_t) args->buffers_ptr,
+			     sizeof(*exec_list) * args->buffer_count);
+	if (ret != 0) {
+		DRM_ERROR("copy %d exec entries failed %d\n",
+			  args->buffer_count, ret);
+		drm_free_large(exec_list);
+		drm_free_large(exec2_list);
+		return -EFAULT;
+	}
+
+	for (i = 0; i < args->buffer_count; i++) {
+		exec2_list[i].handle = exec_list[i].handle;
+		exec2_list[i].relocation_count = exec_list[i].relocation_count;
+		exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
+		exec2_list[i].alignment = exec_list[i].alignment;
+		exec2_list[i].offset = exec_list[i].offset;
+		if (!IS_I965G(dev))
+			exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
+		else
+			exec2_list[i].flags = 0;
+	}
+
+	exec2.buffers_ptr = args->buffers_ptr;
+	exec2.buffer_count = args->buffer_count;
+	exec2.batch_start_offset = args->batch_start_offset;
+	exec2.batch_len = args->batch_len;
+	exec2.DR1 = args->DR1;
+	exec2.DR4 = args->DR4;
+	exec2.num_cliprects = args->num_cliprects;
+	exec2.cliprects_ptr = args->cliprects_ptr;
+	exec2.flags = 0;
+
+	ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list);
 	if (!ret) {
 		/* Copy the new buffer offsets back to the user's exec list. */
+		for (i = 0; i < args->buffer_count; i++)
+			exec_list[i].offset = exec2_list[i].offset;
+		/* ... and back out to userspace */
 		ret = copy_to_user((struct drm_i915_relocation_entry __user *)
 				   (uintptr_t) args->buffers_ptr,
 				   exec_list,
@@ -3828,25 +4055,62 @@ err:
 		}
 	}
 
-	/* Copy the updated relocations out regardless of current error
-	 * state.  Failure to update the relocs would mean that the next
-	 * time userland calls execbuf, it would do so with presumed offset
-	 * state that didn't match the actual object state.
-	 */
-	ret2 = i915_gem_put_relocs_to_user(exec_list, args->buffer_count,
-					   relocs);
-	if (ret2 != 0) {
-		DRM_ERROR("Failed to copy relocations back out: %d\n", ret2);
+	drm_free_large(exec_list);
+	drm_free_large(exec2_list);
+	return ret;
+}
 
-		if (ret == 0)
-			ret = ret2;
+int
+i915_gem_execbuffer2(struct drm_device *dev, void *data,
+		     struct drm_file *file_priv)
+{
+	struct drm_i915_gem_execbuffer2 *args = data;
+	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
+	int ret;
+
+#if WATCH_EXEC
+	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
+		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
+#endif
+
+	if (args->buffer_count < 1) {
+		DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count);
+		return -EINVAL;
 	}
 
-pre_mutex_err:
-	drm_free_large(object_list);
-	drm_free_large(exec_list);
-	kfree(cliprects);
+	exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
+	if (exec2_list == NULL) {
+		DRM_ERROR("Failed to allocate exec list for %d buffers\n",
+			  args->buffer_count);
+		return -ENOMEM;
+	}
+	ret = copy_from_user(exec2_list,
+			     (struct drm_i915_relocation_entry __user *)
+			     (uintptr_t) args->buffers_ptr,
+			     sizeof(*exec2_list) * args->buffer_count);
+	if (ret != 0) {
+		DRM_ERROR("copy %d exec entries failed %d\n",
+			  args->buffer_count, ret);
+		drm_free_large(exec2_list);
+		return -EFAULT;
+	}
 
+	ret = i915_gem_do_execbuffer(dev, data, file_priv, args, exec2_list);
+	if (!ret) {
+		/* Copy the new buffer offsets back to the user's exec list. */
+		ret = copy_to_user((struct drm_i915_relocation_entry __user *)
+				   (uintptr_t) args->buffers_ptr,
+				   exec2_list,
+				   sizeof(*exec2_list) * args->buffer_count);
+		if (ret) {
+			ret = -EFAULT;
+			DRM_ERROR("failed to copy %d exec entries "
+				  "back to user (%d)\n",
+				  args->buffer_count, ret);
+		}
+	}
+
+	drm_free_large(exec2_list);
 	return ret;
 }
 
@@ -3863,19 +4127,7 @@ i915_gem_object_pin(struct drm_gem_objec
 		if (ret)
 			return ret;
 	}
-	/*
-	 * Pre-965 chips need a fence register set up in order to
-	 * properly handle tiled surfaces.
-	 */
-	if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) {
-		ret = i915_gem_object_get_fence_reg(obj);
-		if (ret != 0) {
-			if (ret != -EBUSY && ret != -ERESTARTSYS)
-				DRM_ERROR("Failure to install fence: %d\n",
-					  ret);
-			return ret;
-		}
-	}
+
 	obj_priv->pin_count++;
 
 	/* If the object is not active and not pending a flush,
@@ -4133,6 +4385,7 @@ int i915_gem_init_object(struct drm_gem_
 	obj_priv->obj = obj;
 	obj_priv->fence_reg = I915_FENCE_REG_NONE;
 	INIT_LIST_HEAD(&obj_priv->list);
+	INIT_LIST_HEAD(&obj_priv->gpu_write_list);
 	INIT_LIST_HEAD(&obj_priv->fence_list);
 	obj_priv->madv = I915_MADV_WILLNEED;
 
@@ -4356,7 +4609,7 @@ i915_gem_init_hws(struct drm_device *dev
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
 	I915_READ(HWS_PGA); /* posting read */
-	DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
+	DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
 	return 0;
 }
@@ -4584,6 +4837,7 @@ i915_gem_load(struct drm_device *dev)
 	spin_lock_init(&dev_priv->mm.active_list_lock);
 	INIT_LIST_HEAD(&dev_priv->mm.active_list);
 	INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
+	INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
 	INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
 	INIT_LIST_HEAD(&dev_priv->mm.request_list);
 	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
@@ -4614,8 +4868,8 @@ i915_gem_load(struct drm_device *dev)
 			for (i = 0; i < 8; i++)
 				I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
 	}
-
 	i915_gem_detect_bit_6_swizzle(dev);
+	init_waitqueue_head(&dev_priv->pending_flip_queue);
 }
 
 /*
@@ -4638,7 +4892,7 @@ int i915_gem_init_phys_object(struct drm
 
 	phys_obj->id = id;
 
-	phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff);
+	phys_obj->handle = drm_pci_alloc(dev, size, 0);
 	if (!phys_obj->handle) {
 		ret = -ENOMEM;
 		goto kfree_obj;
@@ -4696,7 +4950,7 @@ void i915_gem_detach_phys_object(struct
 	if (!obj_priv->phys_obj)
 		return;
 
-	ret = i915_gem_object_get_pages(obj);
+	ret = i915_gem_object_get_pages(obj, 0);
 	if (ret)
 		goto out;
 
@@ -4754,7 +5008,7 @@ i915_gem_attach_phys_object(struct drm_d
 	obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1];
 	obj_priv->phys_obj->cur_obj = obj;
 
-	ret = i915_gem_object_get_pages(obj);
+	ret = i915_gem_object_get_pages(obj, 0);
 	if (ret) {
 		DRM_ERROR("failed to get page list\n");
 		goto out;
@@ -4790,7 +5044,7 @@ i915_gem_phys_pwrite(struct drm_device *
 	user_data = (char __user *) (uintptr_t) args->data_ptr;
 	obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
 
-	DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
+	DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
 	ret = copy_from_user(obj_addr, user_data, args->size);
 	if (ret)
 		return -EFAULT;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2010-02-24 13:52:17.000000000 -0500
@@ -121,7 +121,7 @@ intel_alloc_mchbar_resource(struct drm_d
 				     0,   pcibios_align_resource,
 				     dev_priv->bridge_dev);
 	if (ret) {
-		DRM_DEBUG("failed bus alloc: %d\n", ret);
+		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
 		dev_priv->mch_res.start = 0;
 		goto out;
 	}
@@ -209,8 +209,8 @@ i915_gem_detect_bit_6_swizzle(struct drm
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 	bool need_disable;
 
-	if (IS_IGDNG(dev)) {
-		/* On IGDNG whatever DRAM config, GPU always do
+	if (IS_IRONLAKE(dev)) {
+		/* On Ironlake whatever DRAM config, GPU always do
 		 * same swizzling setup.
 		 */
 		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
@@ -304,35 +304,39 @@ i915_gem_detect_bit_6_swizzle(struct drm
 
 
 /**
- * Returns the size of the fence for a tiled object of the given size.
+ * Returns whether an object is currently fenceable.  If not, it may need
+ * to be unbound and have its pitch adjusted.
  */
-static int
-i915_get_fence_size(struct drm_device *dev, int size)
+bool
+i915_obj_fenceable(struct drm_device *dev, struct drm_gem_object *obj)
 {
-	int i;
-	int start;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 
 	if (IS_I965G(dev)) {
 		/* The 965 can have fences at any page boundary. */
-		return ALIGN(size, 4096);
+		if (obj->size & 4095)
+			return false;
+		return true;
+	} else if (IS_I9XX(dev)) {
+		if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK)
+			return false;
 	} else {
-		/* Align the size to a power of two greater than the smallest
-		 * fence size.
-		 */
-		if (IS_I9XX(dev))
-			start = 1024 * 1024;
-		else
-			start = 512 * 1024;
+		if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK)
+			return false;
+	}
 
-		for (i = start; i < size; i <<= 1)
-			;
+	/* Power of two sized... */
+	if (obj->size & (obj->size - 1))
+		return false;
 
-		return i;
-	}
+	/* Objects must be size aligned as well */
+	if (obj_priv->gtt_offset & (obj->size - 1))
+		return false;
+	return true;
 }
 
 /* Check pitch constriants for all chips & tiling formats */
-static bool
+bool
 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
 {
 	int tile_width;
@@ -384,12 +388,6 @@ i915_tiling_ok(struct drm_device *dev, i
 	if (stride & (stride - 1))
 		return false;
 
-	/* We don't 0handle the aperture area covered by the fence being bigger
-	 * than the object size.
-	 */
-	if (i915_get_fence_size(dev, size) != size)
-		return false;
-
 	return true;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_ioc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,8 +66,7 @@ static int compat_i915_batchbuffer(struc
 			  &batchbuffer->cliprects))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_I915_BATCHBUFFER,
+	return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER,
 			 (unsigned long)batchbuffer);
 }
 
@@ -102,8 +101,8 @@ static int compat_i915_cmdbuffer(struct
 			  &cmdbuffer->cliprects))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
+	return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER,
+			 (unsigned long)cmdbuffer);
 }
 
 typedef struct drm_i915_irq_emit32 {
@@ -125,8 +124,8 @@ static int compat_i915_irq_emit(struct f
 			  &request->irq_seq))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT,
+			 (unsigned long)request);
 }
 typedef struct drm_i915_getparam32 {
 	int param;
@@ -149,8 +148,8 @@ static int compat_i915_getparam(struct f
 			  &request->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
+			 (unsigned long)request);
 }
 
 typedef struct drm_i915_mem_alloc32 {
@@ -178,8 +177,8 @@ static int compat_i915_alloc(struct file
 			  &request->region_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_I915_ALLOC, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_I915_ALLOC,
+			 (unsigned long)request);
 }
 
 drm_ioctl_compat_t *i915_compat_ioctls[] = {
@@ -211,12 +210,10 @@ long i915_compat_ioctl(struct file *filp
 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
 		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-	lock_kernel();		/* XXX for now */
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_irq.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,10 +43,13 @@
  * we leave them always unmasked in IMR and then control enabling them through
  * PIPESTAT alone.
  */
-#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT |		 \
-				   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
-				   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
-				   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+#define I915_INTERRUPT_ENABLE_FIX			\
+	(I915_ASLE_INTERRUPT |				\
+	 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |		\
+	 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |		\
+	 I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |	\
+	 I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT |	\
+	 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
 
 /** Interrupts that we mask and unmask at runtime. */
 #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
@@ -61,7 +64,7 @@
 					 DRM_I915_VBLANK_PIPE_B)
 
 void
-igdng_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->gt_irq_mask_reg & mask) != 0) {
 		dev_priv->gt_irq_mask_reg &= ~mask;
@@ -71,7 +74,7 @@ igdng_enable_graphics_irq(drm_i915_priva
 }
 
 static inline void
-igdng_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
 		dev_priv->gt_irq_mask_reg |= mask;
@@ -82,7 +85,7 @@ igdng_disable_graphics_irq(drm_i915_priv
 
 /* For display hotplug interrupt */
 void
-igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->irq_mask_reg & mask) != 0) {
 		dev_priv->irq_mask_reg &= ~mask;
@@ -92,7 +95,7 @@ igdng_enable_display_irq(drm_i915_privat
 }
 
 static inline void
-igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
 	if ((dev_priv->irq_mask_reg & mask) != mask) {
 		dev_priv->irq_mask_reg |= mask;
@@ -157,6 +160,20 @@ i915_disable_pipestat(drm_i915_private_t
 }
 
 /**
+ * intel_enable_asle - enable ASLE interrupt for OpRegion
+ */
+void intel_enable_asle (struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+	if (IS_IRONLAKE(dev))
+		ironlake_enable_display_irq(dev_priv, DE_GSE);
+	else
+		i915_enable_pipestat(dev_priv, 1,
+				     I915_LEGACY_BLC_EVENT_ENABLE);
+}
+
+/**
  * i915_pipe_enabled - check if a pipe is enabled
  * @dev: DRM device
  * @pipe: pipe to check
@@ -191,7 +208,8 @@ u32 i915_get_vblank_counter(struct drm_d
 	low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+				"pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -220,7 +238,8 @@ u32 gm45_get_vblank_counter(struct drm_d
 	int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+					"pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -250,12 +269,11 @@ static void i915_hotplug_work_func(struc
 	drm_sysfs_hotplug_event(dev);
 }
 
-irqreturn_t igdng_irq_handler(struct drm_device *dev)
+irqreturn_t ironlake_irq_handler(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int ret = IRQ_NONE;
-	u32 de_iir, gt_iir, de_ier;
-	u32 new_de_iir, new_gt_iir;
+	u32 de_iir, gt_iir, de_ier, pch_iir;
 	struct drm_i915_master_private *master_priv;
 
 	/* disable master interrupt before clearing iir  */
@@ -265,36 +283,60 @@ irqreturn_t igdng_irq_handler(struct drm
 
 	de_iir = I915_READ(DEIIR);
 	gt_iir = I915_READ(GTIIR);
+	pch_iir = I915_READ(SDEIIR);
 
-	for (;;) {
-		if (de_iir == 0 && gt_iir == 0)
-			break;
+	if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
+		goto done;
 
-		ret = IRQ_HANDLED;
+	ret = IRQ_HANDLED;
 
-		I915_WRITE(DEIIR, de_iir);
-		new_de_iir = I915_READ(DEIIR);
-		I915_WRITE(GTIIR, gt_iir);
-		new_gt_iir = I915_READ(GTIIR);
+	if (dev->primary->master) {
+		master_priv = dev->primary->master->driver_priv;
+		if (master_priv->sarea_priv)
+			master_priv->sarea_priv->last_dispatch =
+				READ_BREADCRUMB(dev_priv);
+	}
 
-		if (dev->primary->master) {
-			master_priv = dev->primary->master->driver_priv;
-			if (master_priv->sarea_priv)
-				master_priv->sarea_priv->last_dispatch =
-					READ_BREADCRUMB(dev_priv);
-		}
+	if (gt_iir & GT_USER_INTERRUPT) {
+		u32 seqno = i915_get_gem_seqno(dev);
+		dev_priv->mm.irq_gem_seqno = seqno;
+		trace_i915_gem_request_complete(dev, seqno);
+		DRM_WAKEUP(&dev_priv->irq_queue);
+		dev_priv->hangcheck_count = 0;
+		mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
+	}
 
-		if (gt_iir & GT_USER_INTERRUPT) {
-			u32 seqno = i915_get_gem_seqno(dev);
-			dev_priv->mm.irq_gem_seqno = seqno;
-			trace_i915_gem_request_complete(dev, seqno);
-			DRM_WAKEUP(&dev_priv->irq_queue);
-		}
+	if (de_iir & DE_GSE)
+		ironlake_opregion_gse_intr(dev);
 
-		de_iir = new_de_iir;
-		gt_iir = new_gt_iir;
+	if (de_iir & DE_PLANEA_FLIP_DONE) {
+		intel_prepare_page_flip(dev, 0);
+		intel_finish_page_flip(dev, 0);
+	}
+
+	if (de_iir & DE_PLANEB_FLIP_DONE) {
+		intel_prepare_page_flip(dev, 1);
+		intel_finish_page_flip(dev, 1);
+	}
+
+	if (de_iir & DE_PIPEA_VBLANK)
+		drm_handle_vblank(dev, 0);
+
+	if (de_iir & DE_PIPEB_VBLANK)
+		drm_handle_vblank(dev, 1);
+
+	/* check event from PCH */
+	if ((de_iir & DE_PCH_EVENT) &&
+	    (pch_iir & SDE_HOTPLUG_MASK)) {
+		queue_work(dev_priv->wq, &dev_priv->hotplug_work);
 	}
 
+	/* should clear PCH hotplug event before clear CPU irq */
+	I915_WRITE(SDEIIR, pch_iir);
+	I915_WRITE(GTIIR, gt_iir);
+	I915_WRITE(DEIIR, de_iir);
+
+done:
 	I915_WRITE(DEIER, de_ier);
 	(void)I915_READ(DEIER);
 
@@ -317,19 +359,19 @@ static void i915_error_work_func(struct
 	char *reset_event[] = { "RESET=1", NULL };
 	char *reset_done_event[] = { "ERROR=0", NULL };
 
-	DRM_DEBUG("generating error event\n");
+	DRM_DEBUG_DRIVER("generating error event\n");
 	kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
 
 	if (atomic_read(&dev_priv->mm.wedged)) {
 		if (IS_I965G(dev)) {
-			DRM_DEBUG("resetting chip\n");
+			DRM_DEBUG_DRIVER("resetting chip\n");
 			kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
 			if (!i965_reset(dev, GDRST_RENDER)) {
 				atomic_set(&dev_priv->mm.wedged, 0);
 				kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
 			}
 		} else {
-			printk("reboot required\n");
+			DRM_DEBUG_DRIVER("reboot required\n");
 		}
 	}
 }
@@ -355,7 +397,7 @@ static void i915_capture_error_state(str
 
 	error = kmalloc(sizeof(*error), GFP_ATOMIC);
 	if (!error) {
-		DRM_DEBUG("out ot memory, not capturing error state\n");
+		DRM_DEBUG_DRIVER("out ot memory, not capturing error state\n");
 		goto out;
 	}
 
@@ -512,7 +554,6 @@ static void i915_handle_error(struct drm
 		/*
 		 * Wakeup waiting processes so they don't hang
 		 */
-		printk("i915: Waking up sleeping processes\n");
 		DRM_WAKEUP(&dev_priv->irq_queue);
 	}
 
@@ -535,8 +576,8 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 	atomic_inc(&dev_priv->irq_received);
 
-	if (IS_IGDNG(dev))
-		return igdng_irq_handler(dev);
+	if (IS_IRONLAKE(dev))
+		return ironlake_irq_handler(dev);
 
 	iir = I915_READ(IIR);
 
@@ -568,14 +609,14 @@ irqreturn_t i915_driver_irq_handler(DRM_
 		 */
 		if (pipea_stats & 0x8000ffff) {
 			if (pipea_stats &  PIPE_FIFO_UNDERRUN_STATUS)
-				DRM_DEBUG("pipe a underrun\n");
+				DRM_DEBUG_DRIVER("pipe a underrun\n");
 			I915_WRITE(PIPEASTAT, pipea_stats);
 			irq_received = 1;
 		}
 
 		if (pipeb_stats & 0x8000ffff) {
 			if (pipeb_stats &  PIPE_FIFO_UNDERRUN_STATUS)
-				DRM_DEBUG("pipe b underrun\n");
+				DRM_DEBUG_DRIVER("pipe b underrun\n");
 			I915_WRITE(PIPEBSTAT, pipeb_stats);
 			irq_received = 1;
 		}
@@ -591,7 +632,7 @@ irqreturn_t i915_driver_irq_handler(DRM_
 		    (iir & I915_DISPLAY_PORT_INTERRUPT)) {
 			u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
 
-			DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
 			if (hotplug_status & dev_priv->hotplug_supported_mask)
 				queue_work(dev_priv->wq,
@@ -599,27 +640,6 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
-
-			/* EOS interrupts occurs */
-			if (IS_IGD(dev) &&
-				(hotplug_status & CRT_EOS_INT_STATUS)) {
-				u32 temp;
-
-				DRM_DEBUG("EOS interrupt occurs\n");
-				/* status is already cleared */
-				temp = I915_READ(ADPA);
-				temp &= ~ADPA_DAC_ENABLE;
-				I915_WRITE(ADPA, temp);
-
-				temp = I915_READ(PORT_HOTPLUG_EN);
-				temp &= ~CRT_EOS_INT_EN;
-				I915_WRITE(PORT_HOTPLUG_EN, temp);
-
-				temp = I915_READ(PORT_HOTPLUG_STAT);
-				if (temp & CRT_EOS_INT_STATUS)
-					I915_WRITE(PORT_HOTPLUG_STAT,
-						CRT_EOS_INT_STATUS);
-			}
 		}
 
 		I915_WRITE(IIR, iir);
@@ -641,14 +661,22 @@ irqreturn_t i915_driver_irq_handler(DRM_
 			mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
 		}
 
+		if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
+			intel_prepare_page_flip(dev, 0);
+
+		if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
+			intel_prepare_page_flip(dev, 1);
+
 		if (pipea_stats & vblank_status) {
 			vblank++;
 			drm_handle_vblank(dev, 0);
+			intel_finish_page_flip(dev, 0);
 		}
 
 		if (pipeb_stats & vblank_status) {
 			vblank++;
 			drm_handle_vblank(dev, 1);
+			intel_finish_page_flip(dev, 1);
 		}
 
 		if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
@@ -684,7 +712,7 @@ static int i915_emit_irq(struct drm_devi
 
 	i915_kernel_lost_context(dev);
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_DRIVER("\n");
 
 	dev_priv->counter++;
 	if (dev_priv->counter > 0x7FFFFFFFUL)
@@ -709,8 +737,8 @@ void i915_user_irq_get(struct drm_device
 
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
-		if (IS_IGDNG(dev))
-			igdng_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (IS_IRONLAKE(dev))
+			ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
 		else
 			i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -725,8 +753,8 @@ void i915_user_irq_put(struct drm_device
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
 	BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
 	if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
-		if (IS_IGDNG(dev))
-			igdng_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+		if (IS_IRONLAKE(dev))
+			ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
 		else
 			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
 	}
@@ -749,7 +777,7 @@ static int i915_wait_irq(struct drm_devi
 	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
 	int ret = 0;
 
-	DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
+	DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
 		  READ_BREADCRUMB(dev_priv));
 
 	if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
@@ -832,11 +860,11 @@ int i915_enable_vblank(struct drm_device
 	if (!(pipeconf & PIPEACONF_ENABLE))
 		return -EINVAL;
 
-	if (IS_IGDNG(dev))
-		return 0;
-
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	if (IS_I965G(dev))
+	if (IS_IRONLAKE(dev))
+		ironlake_enable_display_irq(dev_priv, (pipe == 0) ? 
+					    DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
+	else if (IS_I965G(dev))
 		i915_enable_pipestat(dev_priv, pipe,
 				     PIPE_START_VBLANK_INTERRUPT_ENABLE);
 	else
@@ -854,13 +882,14 @@ void i915_disable_vblank(struct drm_devi
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
 
-	if (IS_IGDNG(dev))
-		return;
-
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	i915_disable_pipestat(dev_priv, pipe,
-			      PIPE_VBLANK_INTERRUPT_ENABLE |
-			      PIPE_START_VBLANK_INTERRUPT_ENABLE);
+	if (IS_IRONLAKE(dev))
+		ironlake_disable_display_irq(dev_priv, (pipe == 0) ? 
+					     DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
+	else
+		i915_disable_pipestat(dev_priv, pipe,
+				      PIPE_VBLANK_INTERRUPT_ENABLE |
+				      PIPE_START_VBLANK_INTERRUPT_ENABLE);
 	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
@@ -868,7 +897,7 @@ void i915_enable_interrupt (struct drm_d
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		opregion_enable_asle(dev);
 	dev_priv->irq_enabled = 1;
 }
@@ -976,7 +1005,7 @@ void i915_hangcheck_elapsed(unsigned lon
 
 /* drm_dma.h hooks
 */
-static void igdng_irq_preinstall(struct drm_device *dev)
+static void ironlake_irq_preinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
@@ -992,17 +1021,25 @@ static void igdng_irq_preinstall(struct
 	I915_WRITE(GTIMR, 0xffffffff);
 	I915_WRITE(GTIER, 0x0);
 	(void) I915_READ(GTIER);
+
+	/* south display irq */
+	I915_WRITE(SDEIMR, 0xffffffff);
+	I915_WRITE(SDEIER, 0x0);
+	(void) I915_READ(SDEIER);
 }
 
-static int igdng_irq_postinstall(struct drm_device *dev)
+static int ironlake_irq_postinstall(struct drm_device *dev)
 {
 	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_PCH_EVENT */;
+	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
+			   DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
 	u32 render_mask = GT_USER_INTERRUPT;
+	u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
+			   SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
 	dev_priv->irq_mask_reg = ~display_mask;
-	dev_priv->de_irq_enable_reg = display_mask;
+	dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK;
 
 	/* should always can generate irq */
 	I915_WRITE(DEIIR, I915_READ(DEIIR));
@@ -1019,6 +1056,14 @@ static int igdng_irq_postinstall(struct
 	I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
 	(void) I915_READ(GTIER);
 
+	dev_priv->pch_irq_mask_reg = ~hotplug_mask;
+	dev_priv->pch_irq_enable_reg = hotplug_mask;
+
+	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+	I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg);
+	I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg);
+	(void) I915_READ(SDEIER);
+
 	return 0;
 }
 
@@ -1031,8 +1076,8 @@ void i915_driver_irq_preinstall(struct d
 	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 
-	if (IS_IGDNG(dev)) {
-		igdng_irq_preinstall(dev);
+	if (IS_IRONLAKE(dev)) {
+		ironlake_irq_preinstall(dev);
 		return;
 	}
 
@@ -1049,6 +1094,10 @@ void i915_driver_irq_preinstall(struct d
 	(void) I915_READ(IER);
 }
 
+/*
+ * Must be called after intel_modeset_init or hotplug interrupts won't be
+ * enabled correctly.
+ */
 int i915_driver_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1059,8 +1108,8 @@ int i915_driver_irq_postinstall(struct d
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
-	if (IS_IGDNG(dev))
-		return igdng_irq_postinstall(dev);
+	if (IS_IRONLAKE(dev))
+		return ironlake_irq_postinstall(dev);
 
 	/* Unmask the interrupts that we always want on. */
 	dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
@@ -1071,19 +1120,23 @@ int i915_driver_irq_postinstall(struct d
 	if (I915_HAS_HOTPLUG(dev)) {
 		u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 
-		/* Leave other bits alone */
-		hotplug_en |= HOTPLUG_EN_MASK;
+		/* Note HDMI and DP share bits */
+		if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
+			hotplug_en |= HDMIB_HOTPLUG_INT_EN;
+		if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
+			hotplug_en |= HDMIC_HOTPLUG_INT_EN;
+		if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
+			hotplug_en |= HDMID_HOTPLUG_INT_EN;
+		if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS)
+			hotplug_en |= SDVOC_HOTPLUG_INT_EN;
+		if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
+			hotplug_en |= SDVOB_HOTPLUG_INT_EN;
+		if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS)
+			hotplug_en |= CRT_HOTPLUG_INT_EN;
+		/* Ignore TV since it's buggy */
+
 		I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
 
-		dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS |
-			TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS |
-			SDVOB_HOTPLUG_INT_STATUS;
-		if (IS_G4X(dev)) {
-			dev_priv->hotplug_supported_mask |=
-				HDMIB_HOTPLUG_INT_STATUS |
-				HDMIC_HOTPLUG_INT_STATUS |
-				HDMID_HOTPLUG_INT_STATUS;
-		}
 		/* Enable in IER... */
 		enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
 		/* and unmask in IMR */
@@ -1120,7 +1173,7 @@ int i915_driver_irq_postinstall(struct d
 	return 0;
 }
 
-static void igdng_irq_uninstall(struct drm_device *dev)
+static void ironlake_irq_uninstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	I915_WRITE(HWSTAM, 0xffffffff);
@@ -1143,8 +1196,8 @@ void i915_driver_irq_uninstall(struct dr
 
 	dev_priv->vblank_pipe = 0;
 
-	if (IS_IGDNG(dev)) {
-		igdng_irq_uninstall(dev);
+	if (IS_IRONLAKE(dev)) {
+		ironlake_irq_uninstall(dev);
 		return;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_opregion.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_opregion.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,6 +118,10 @@ struct opregion_asle {
 #define ASLE_BACKLIGHT_FAIL    (2<<12)
 #define ASLE_PFIT_FAIL         (2<<14)
 #define ASLE_PWM_FREQ_FAIL     (2<<16)
+#define ASLE_ALS_ILLUM_FAILED	(1<<10)
+#define ASLE_BACKLIGHT_FAILED	(1<<12)
+#define ASLE_PFIT_FAILED	(1<<14)
+#define ASLE_PWM_FREQ_FAILED	(1<<16)
 
 /* ASLE backlight brightness to set */
 #define ASLE_BCLP_VALID                (1<<31)
@@ -163,7 +167,7 @@ static u32 asle_set_backlight(struct drm
 	if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
 		pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
 	else {
-		if (IS_IGD(dev)) {
+		if (IS_PINEVIEW(dev)) {
 			blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
 			max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> 
 					BACKLIGHT_MODULATION_FREQ_SHIFT;
@@ -224,7 +228,7 @@ void opregion_asle_intr(struct drm_devic
 	asle_req = asle->aslc & ASLE_REQ_MSK;
 
 	if (!asle_req) {
-		DRM_DEBUG("non asle set request??\n");
+		DRM_DEBUG_DRIVER("non asle set request??\n");
 		return;
 	}
 
@@ -243,6 +247,73 @@ void opregion_asle_intr(struct drm_devic
 	asle->aslc = asle_stat;
 }
 
+static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 cpu_pwm_ctl, pch_pwm_ctl2;
+	u32 max_backlight, level;
+
+	if (!(bclp & ASLE_BCLP_VALID))
+		return ASLE_BACKLIGHT_FAILED;
+
+	bclp &= ASLE_BCLP_MSK;
+	if (bclp < 0 || bclp > 255)
+		return ASLE_BACKLIGHT_FAILED;
+
+	cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL);
+	pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+	/* get the max PWM frequency */
+	max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK;
+	/* calculate the expected PMW frequency */
+	level = (bclp * max_backlight) / 255;
+	/* reserve the high 16 bits */
+	cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK);
+	/* write the updated PWM frequency */
+	I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level);
+
+	asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
+
+	return 0;
+}
+
+void ironlake_opregion_gse_intr(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 asle_stat = 0;
+	u32 asle_req;
+
+	if (!asle)
+		return;
+
+	asle_req = 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_ironlake(dev, 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;
+	}
+
+	asle->aslc = asle_stat;
+}
 #define ASLE_ALS_EN    (1<<0)
 #define ASLE_BLC_EN    (1<<1)
 #define ASLE_PFIT_EN   (1<<2)
@@ -258,8 +329,7 @@ void opregion_enable_asle(struct drm_dev
 			unsigned long irqflags;
 
 			spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-			i915_enable_pipestat(dev_priv, 1,
-					     I915_LEGACY_BLC_EVENT_ENABLE);
+			intel_enable_asle(dev);
 			spin_unlock_irqrestore(&dev_priv->user_irq_lock,
 					       irqflags);
 		}
@@ -361,9 +431,9 @@ int intel_opregion_init(struct drm_devic
 	int err = 0;
 
 	pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
-	DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
+	DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
 	if (asls == 0) {
-		DRM_DEBUG("ACPI OpRegion not supported!\n");
+		DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
 		return -ENOTSUPP;
 	}
 
@@ -373,30 +443,30 @@ int intel_opregion_init(struct drm_devic
 
 	opregion->header = base;
 	if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
-		DRM_DEBUG("opregion signature mismatch\n");
+		DRM_DEBUG_DRIVER("opregion signature mismatch\n");
 		err = -EINVAL;
 		goto err_out;
 	}
 
 	mboxes = opregion->header->mboxes;
 	if (mboxes & MBOX_ACPI) {
-		DRM_DEBUG("Public ACPI methods supported\n");
+		DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
 		opregion->acpi = base + OPREGION_ACPI_OFFSET;
 		if (drm_core_check_feature(dev, DRIVER_MODESET))
 			intel_didl_outputs(dev);
 	} else {
-		DRM_DEBUG("Public ACPI methods not supported\n");
+		DRM_DEBUG_DRIVER("Public ACPI methods not supported\n");
 		err = -ENOTSUPP;
 		goto err_out;
 	}
 	opregion->enabled = 1;
 
 	if (mboxes & MBOX_SWSCI) {
-		DRM_DEBUG("SWSCI supported\n");
+		DRM_DEBUG_DRIVER("SWSCI supported\n");
 		opregion->swsci = base + OPREGION_SWSCI_OFFSET;
 	}
 	if (mboxes & MBOX_ASLE) {
-		DRM_DEBUG("ASLE supported\n");
+		DRM_DEBUG_DRIVER("ASLE supported\n");
 		opregion->asle = base + OPREGION_ASLE_OFFSET;
 		opregion_enable_asle(dev);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -140,6 +140,7 @@
 #define MI_NOOP			MI_INSTR(0, 0)
 #define MI_USER_INTERRUPT	MI_INSTR(0x02, 0)
 #define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
+#define   MI_WAIT_FOR_OVERLAY_FLIP	(1<<16)
 #define   MI_WAIT_FOR_PLANE_B_FLIP      (1<<6)
 #define   MI_WAIT_FOR_PLANE_A_FLIP      (1<<2)
 #define   MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
@@ -151,7 +152,13 @@
 #define   MI_END_SCENE		(1 << 4) /* flush binner and incr scene count */
 #define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
 #define MI_REPORT_HEAD		MI_INSTR(0x07, 0)
+#define MI_OVERLAY_FLIP		MI_INSTR(0x11,0)
+#define   MI_OVERLAY_CONTINUE	(0x0<<21)
+#define   MI_OVERLAY_ON		(0x1<<21)
+#define   MI_OVERLAY_OFF	(0x2<<21)
 #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+#define MI_DISPLAY_FLIP		MI_INSTR(0x14, 2)
+#define   MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
 #define MI_STORE_DWORD_IMM	MI_INSTR(0x20, 1)
 #define   MI_MEM_VIRTUAL	(1 << 22) /* 965+ only */
 #define MI_STORE_DWORD_INDEX	MI_INSTR(0x21, 1)
@@ -260,6 +267,8 @@
 #define HWS_PGA		0x02080
 #define HWS_ADDRESS_MASK	0xfffff000
 #define HWS_START_ADDRESS_SHIFT	4
+#define PWRCTXA		0x2088 /* 965GM+ only */
+#define   PWRCTX_EN	(1<<0)
 #define IPEIR		0x02088
 #define IPEHR		0x0208c
 #define INSTDONE	0x02090
@@ -329,6 +338,7 @@
 #define   FBC_CTL_PERIODIC	(1<<30)
 #define   FBC_CTL_INTERVAL_SHIFT (16)
 #define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define   FBC_C3_IDLE		(1<<13)
 #define   FBC_CTL_STRIDE_SHIFT	(5)
 #define   FBC_CTL_FENCENO	(1<<0)
 #define FBC_COMMAND		0x0320c
@@ -405,6 +415,13 @@
 # define GPIO_DATA_VAL_IN		(1 << 12)
 # define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
 
+#define GMBUS0			0x5100
+#define GMBUS1			0x5104
+#define GMBUS2			0x5108
+#define GMBUS3			0x510c
+#define GMBUS4			0x5110
+#define GMBUS5			0x5120
+
 /*
  * Clock control & power management
  */
@@ -435,7 +452,7 @@
 #define   DPLLB_LVDS_P2_CLOCK_DIV_7	(1 << 24) /* i915 */
 #define   DPLL_P2_CLOCK_DIV_MASK	0x03000000 /* i915 */
 #define   DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000 /* i915 */
-#define   DPLL_FPA01_P1_POST_DIV_MASK_IGD	0x00ff8000 /* IGD */
+#define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW	0x00ff8000 /* Pineview */
 
 #define I915_FIFO_UNDERRUN_STATUS		(1UL<<31)
 #define I915_CRC_ERROR_ENABLE			(1UL<<29)
@@ -512,7 +529,7 @@
  */
 #define   DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
 #define   DPLL_FPA01_P1_POST_DIV_SHIFT	16
-#define   DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15
+#define   DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15
 /* i830, required in DVO non-gang */
 #define   PLL_P2_DIVIDE_BY_4		(1 << 23)
 #define   PLL_P1_DIVIDE_BY_TWO		(1 << 21) /* i830 */
@@ -522,7 +539,7 @@
 #define   PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
 #define   PLL_REF_INPUT_MASK		(3 << 13)
 #define   PLL_LOAD_PULSE_PHASE_SHIFT		9
-/* IGDNG */
+/* Ironlake */
 # define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT     9
 # define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK      (7 << 9)
 # define PLL_REF_SDVO_HDMI_MULTIPLIER(x)	(((x)-1) << 9)
@@ -586,12 +603,12 @@
 #define FPB0	0x06048
 #define FPB1	0x0604c
 #define   FP_N_DIV_MASK		0x003f0000
-#define   FP_N_IGD_DIV_MASK	0x00ff0000
+#define   FP_N_PINEVIEW_DIV_MASK	0x00ff0000
 #define   FP_N_DIV_SHIFT		16
 #define   FP_M1_DIV_MASK	0x00003f00
 #define   FP_M1_DIV_SHIFT		 8
 #define   FP_M2_DIV_MASK	0x0000003f
-#define   FP_M2_IGD_DIV_MASK	0x000000ff
+#define   FP_M2_PINEVIEW_DIV_MASK	0x000000ff
 #define   FP_M2_DIV_SHIFT		 0
 #define DPLL_TEST	0x606c
 #define   DPLLB_TEST_SDVO_DIV_1		(0 << 22)
@@ -769,7 +786,8 @@
 
 /** GM965 GM45 render standby register */
 #define MCHBAR_RENDER_STANDBY	0x111B8
-
+#define   RCX_SW_EXIT		(1<<23)
+#define   RSX_STATUS_MASK	0x00700000
 #define PEG_BAND_GAP_DATA	0x14d68
 
 /*
@@ -844,7 +862,6 @@
 #define   SDVOB_HOTPLUG_INT_EN			(1 << 26)
 #define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
-#define   CRT_EOS_INT_EN			(1 << 10)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 #define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
@@ -863,14 +880,6 @@
 #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
 #define CRT_HOTPLUG_MASK			(0x3fc) /* Bits 9-2 */
 #define CRT_FORCE_HOTPLUG_MASK			0xfffffe1f
-#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
-			 HDMIC_HOTPLUG_INT_EN |	  \
-			 HDMID_HOTPLUG_INT_EN |	  \
-			 SDVOB_HOTPLUG_INT_EN |	  \
-			 SDVOC_HOTPLUG_INT_EN |	  \
-			 TV_HOTPLUG_INT_EN |	  \
-			 CRT_HOTPLUG_INT_EN)
-
 
 #define PORT_HOTPLUG_STAT	0x61114
 #define   HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
@@ -879,7 +888,6 @@
 #define   DPC_HOTPLUG_INT_STATUS		(1 << 28)
 #define   HDMID_HOTPLUG_INT_STATUS		(1 << 27)
 #define   DPD_HOTPLUG_INT_STATUS		(1 << 27)
-#define   CRT_EOS_INT_STATUS			(1 << 12)
 #define   CRT_HOTPLUG_INT_STATUS		(1 << 11)
 #define   TV_HOTPLUG_INT_STATUS			(1 << 10)
 #define   CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
@@ -968,6 +976,8 @@
 #define   LVDS_PORT_EN			(1 << 31)
 /* Selects pipe B for LVDS data.  Must be set on pre-965. */
 #define   LVDS_PIPEB_SELECT		(1 << 30)
+/* LVDS dithering flag on 965/g4x platform */
+#define   LVDS_ENABLE_DITHER		(1 << 25)
 /* Enable border for unscaled (or aspect-scaled) display */
 #define   LVDS_BORDER_ENABLE		(1 << 15)
 /*
@@ -1620,7 +1630,7 @@
 #define   DP_CLOCK_OUTPUT_ENABLE	(1 << 13)
 
 #define   DP_SCRAMBLING_DISABLE		(1 << 12)
-#define   DP_SCRAMBLING_DISABLE_IGDNG	(1 << 7)
+#define   DP_SCRAMBLING_DISABLE_IRONLAKE	(1 << 7)
 
 /** limit RGB values to avoid confusing TVs */
 #define   DP_COLOR_RANGE_16_235		(1 << 8)
@@ -1737,6 +1747,8 @@
 
 /* Display & cursor control */
 
+/* dithering flag on Ironlake */
+#define PIPE_ENABLE_DITHER	(1 << 4)
 /* Pipe A */
 #define PIPEADSL		0x70000
 #define PIPEACONF		0x70008
@@ -1804,11 +1816,11 @@
 #define   DSPFW_PLANEB_SHIFT	8
 #define DSPFW2			0x70038
 #define   DSPFW_CURSORA_MASK	0x00003f00
-#define   DSPFW_CURSORA_SHIFT	16
+#define   DSPFW_CURSORA_SHIFT	8
 #define DSPFW3			0x7003c
 #define   DSPFW_HPLL_SR_EN	(1<<31)
 #define   DSPFW_CURSOR_SR_SHIFT	24
-#define   IGD_SELF_REFRESH_EN	(1<<30)
+#define   PINEVIEW_SELF_REFRESH_EN	(1<<30)
 
 /* FIFO watermark sizes etc */
 #define G4X_FIFO_LINE_SIZE	64
@@ -1824,16 +1836,16 @@
 #define G4X_MAX_WM		0x3f
 #define I915_MAX_WM		0x3f
 
-#define IGD_DISPLAY_FIFO	512 /* in 64byte unit */
-#define IGD_FIFO_LINE_SIZE	64
-#define IGD_MAX_WM		0x1ff
-#define IGD_DFT_WM		0x3f
-#define IGD_DFT_HPLLOFF_WM	0
-#define IGD_GUARD_WM		10
-#define IGD_CURSOR_FIFO		64
-#define IGD_CURSOR_MAX_WM	0x3f
-#define IGD_CURSOR_DFT_WM	0
-#define IGD_CURSOR_GUARD_WM	5
+#define PINEVIEW_DISPLAY_FIFO	512 /* in 64byte unit */
+#define PINEVIEW_FIFO_LINE_SIZE	64
+#define PINEVIEW_MAX_WM		0x1ff
+#define PINEVIEW_DFT_WM		0x3f
+#define PINEVIEW_DFT_HPLLOFF_WM	0
+#define PINEVIEW_GUARD_WM		10
+#define PINEVIEW_CURSOR_FIFO		64
+#define PINEVIEW_CURSOR_MAX_WM	0x3f
+#define PINEVIEW_CURSOR_DFT_WM	0
+#define PINEVIEW_CURSOR_GUARD_WM	5
 
 /*
  * The two pipe frame counter registers are not synchronized, so
@@ -1907,6 +1919,7 @@
 #define   DISPPLANE_16BPP			(0x5<<26)
 #define   DISPPLANE_32BPP_NO_ALPHA		(0x6<<26)
 #define   DISPPLANE_32BPP			(0x7<<26)
+#define   DISPPLANE_32BPP_30BIT_NO_ALPHA	(0xa<<26)
 #define   DISPPLANE_STEREO_ENABLE		(1<<25)
 #define   DISPPLANE_STEREO_DISABLE		0
 #define   DISPPLANE_SEL_PIPE_MASK		(1<<24)
@@ -1918,7 +1931,7 @@
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
-#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* IGDNG */
+#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* Ironlake */
 #define   DISPPLANE_TILED			(1<<10)
 #define DSPAADDR		0x70184
 #define DSPASTRIDE		0x70188
@@ -1971,7 +1984,7 @@
 # define VGA_2X_MODE				(1 << 30)
 # define VGA_PIPE_B_SELECT			(1 << 29)
 
-/* IGDNG */
+/* Ironlake */
 
 #define CPU_VGACNTRL	0x41000
 
@@ -2117,6 +2130,7 @@
 #define SDE_PORTC_HOTPLUG       (1 << 9)
 #define SDE_PORTB_HOTPLUG       (1 << 8)
 #define SDE_SDVOB_HOTPLUG       (1 << 6)
+#define SDE_HOTPLUG_MASK	(0xf << 8)
 
 #define SDEISR  0xc4000
 #define SDEIMR  0xc4004
@@ -2157,6 +2171,13 @@
 #define PCH_GPIOE               0xc5020
 #define PCH_GPIOF               0xc5024
 
+#define PCH_GMBUS0		0xc5100
+#define PCH_GMBUS1		0xc5104
+#define PCH_GMBUS2		0xc5108
+#define PCH_GMBUS3		0xc510c
+#define PCH_GMBUS4		0xc5110
+#define PCH_GMBUS5		0xc5120
+
 #define PCH_DPLL_A              0xc6014
 #define PCH_DPLL_B              0xc6018
 
@@ -2292,7 +2313,7 @@
 #define  FDI_DP_PORT_WIDTH_X3           (2<<19)
 #define  FDI_DP_PORT_WIDTH_X4           (3<<19)
 #define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
-/* IGDNG: hardwired to 1 */
+/* Ironlake: hardwired to 1 */
 #define  FDI_TX_PLL_ENABLE              (1<<14)
 /* both Tx and Rx */
 #define  FDI_SCRAMBLING_ENABLE          (0<<7)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_suspend.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,14 +27,14 @@
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
-#include "i915_drv.h"
+#include "intel_drv.h"
 
 static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32	dpll_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
 	} else {
 		dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
@@ -53,7 +53,7 @@ static void i915_save_palette(struct drm
 	if (!i915_pipe_enabled(dev, pipe))
 		return;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
 	if (pipe == PIPE_A)
@@ -75,7 +75,7 @@ static void i915_restore_palette(struct
 	if (!i915_pipe_enabled(dev, pipe))
 		return;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
 
 	if (pipe == PIPE_A)
@@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
 		dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
 	}
@@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct
 	/* Pipe & plane A info */
 	dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
 	dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
 		dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
 		dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
@@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct
 		dev_priv->saveFPA1 = I915_READ(FPA1);
 		dev_priv->saveDPLL_A = I915_READ(DPLL_A);
 	}
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
 	dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
 	dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct
 	dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
 	dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
 	dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
 		dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
 		dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
@@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct
 	/* Pipe & plane B info */
 	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
 	dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
 		dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
 		dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
@@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct
 		dev_priv->saveFPB1 = I915_READ(FPB1);
 		dev_priv->saveDPLL_B = I915_READ(DPLL_B);
 	}
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
 	dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
 	dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct
 	dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
 	dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
 	dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
 		dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
 		dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
@@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(str
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dpll_a_reg = PCH_DPLL_A;
 		dpll_b_reg = PCH_DPLL_B;
 		fpa0_reg = PCH_FPA0;
@@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(str
 		fpb1_reg = FPB1;
 	}
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
 		I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
 	}
@@ -402,7 +402,7 @@ static void i915_restore_modeset_reg(str
 	/* Actually enable it */
 	I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
 	DRM_UDELAY(150);
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
 	DRM_UDELAY(150);
 
@@ -413,10 +413,10 @@ static void i915_restore_modeset_reg(str
 	I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
 	I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
 	I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
 		I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
 		I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
@@ -467,7 +467,7 @@ static void i915_restore_modeset_reg(str
 	/* Actually enable it */
 	I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
 	DRM_UDELAY(150);
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
 	DRM_UDELAY(150);
 
@@ -478,10 +478,10 @@ static void i915_restore_modeset_reg(str
 	I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
 	I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
 	I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
 		I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
 		I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
@@ -546,14 +546,14 @@ void i915_save_display(struct drm_device
 		dev_priv->saveCURSIZE = I915_READ(CURSIZE);
 
 	/* CRT state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveADPA = I915_READ(PCH_ADPA);
 	} else {
 		dev_priv->saveADPA = I915_READ(ADPA);
 	}
 
 	/* LVDS state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
 		dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
 		dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
@@ -571,10 +571,10 @@ void i915_save_display(struct drm_device
 			dev_priv->saveLVDS = I915_READ(LVDS);
 	}
 
-	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
 		dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
 		dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
 		dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
@@ -614,7 +614,7 @@ void i915_save_display(struct drm_device
 	dev_priv->saveVGA0 = I915_READ(VGA0);
 	dev_priv->saveVGA1 = I915_READ(VGA1);
 	dev_priv->saveVGA_PD = I915_READ(VGA_PD);
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
 	else
 		dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
@@ -656,24 +656,24 @@ void i915_restore_display(struct drm_dev
 		I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
 
 	/* CRT state */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
 	else
 		I915_WRITE(ADPA, dev_priv->saveADPA);
 
 	/* LVDS state */
-	if (IS_I965G(dev) && !IS_IGDNG(dev))
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
 	} else if (IS_MOBILE(dev) && !IS_I830(dev))
 		I915_WRITE(LVDS, dev_priv->saveLVDS);
 
-	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
 		I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
 		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
 		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
@@ -713,7 +713,7 @@ void i915_restore_display(struct drm_dev
 	}
 
 	/* VGA state */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
 	else
 		I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
@@ -732,17 +732,13 @@ int i915_save_state(struct drm_device *d
 
 	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
 
-	/* Render Standby */
-	if (IS_I965G(dev) && IS_MOBILE(dev))
-		dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
-
 	/* Hardware status page */
 	dev_priv->saveHWS = I915_READ(HWS_PGA);
 
 	i915_save_display(dev);
 
 	/* Interrupt state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		dev_priv->saveDEIER = I915_READ(DEIER);
 		dev_priv->saveDEIMR = I915_READ(DEIMR);
 		dev_priv->saveGTIER = I915_READ(GTIER);
@@ -754,10 +750,6 @@ int i915_save_state(struct drm_device *d
 		dev_priv->saveIMR = I915_READ(IMR);
 	}
 
-	/* Clock gating state */
-	dev_priv->saveD_STATE = I915_READ(D_STATE);
-	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); /* Not sure about this */
-
 	/* Cache mode state */
 	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
 
@@ -795,10 +787,6 @@ int i915_restore_state(struct drm_device
 
 	pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
 
-	/* Render Standby */
-	if (IS_I965G(dev) && IS_MOBILE(dev))
-		I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
-
 	/* Hardware status page */
 	I915_WRITE(HWS_PGA, dev_priv->saveHWS);
 
@@ -817,7 +805,7 @@ int i915_restore_state(struct drm_device
 	i915_restore_display(dev);
 
 	/* Interrupt state */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(DEIER, dev_priv->saveDEIER);
 		I915_WRITE(DEIMR, dev_priv->saveDEIMR);
 		I915_WRITE(GTIER, dev_priv->saveGTIER);
@@ -830,8 +818,7 @@ int i915_restore_state(struct drm_device
 	}
 
 	/* Clock gating state */
-	I915_WRITE (D_STATE, dev_priv->saveD_STATE);
-	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+	intel_init_clock_gating(dev);
 
 	/* Cache mode state */
 	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
@@ -846,6 +833,9 @@ int i915_restore_state(struct drm_device
 	for (i = 0; i < 3; i++)
 		I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
 
+	/* I2C state */
+	intel_i2c_reset_gmbus(dev);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_bios.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_bios.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,8 @@
 #define	SLAVE_ADDR1	0x70
 #define	SLAVE_ADDR2	0x72
 
+static int panel_type;
+
 static void *
 find_section(struct bdb_header *bdb, int section_id)
 {
@@ -114,6 +116,8 @@ parse_lfp_panel_data(struct drm_i915_pri
 	struct lvds_dvo_timing *dvo_timing;
 	struct drm_display_mode *panel_fixed_mode;
 	int lfp_data_size, dvo_timing_offset;
+	int i, temp_downclock;
+	struct drm_display_mode *temp_mode;
 
 	/* Defaults if we can't find VBT info */
 	dev_priv->lvds_dither = 0;
@@ -126,6 +130,7 @@ parse_lfp_panel_data(struct drm_i915_pri
 	dev_priv->lvds_dither = lvds_options->pixel_dither;
 	if (lvds_options->panel_type == 0xff)
 		return;
+	panel_type = lvds_options->panel_type;
 
 	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
 	if (!lvds_lfp_data)
@@ -159,9 +164,50 @@ parse_lfp_panel_data(struct drm_i915_pri
 
 	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
-	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+	DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
 	drm_mode_debug_printmodeline(panel_fixed_mode);
 
+	temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL);
+	temp_downclock = panel_fixed_mode->clock;
+	/*
+	 * enumerate the LVDS panel timing info entry in VBT to check whether
+	 * the LVDS downclock is found.
+	 */
+	for (i = 0; i < 16; i++) {
+		entry = (struct bdb_lvds_lfp_data_entry *)
+			((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i));
+		dvo_timing = (struct lvds_dvo_timing *)
+			((unsigned char *)entry + dvo_timing_offset);
+
+		fill_detail_timing_data(temp_mode, dvo_timing);
+
+		if (temp_mode->hdisplay == panel_fixed_mode->hdisplay &&
+		temp_mode->hsync_start == panel_fixed_mode->hsync_start &&
+		temp_mode->hsync_end == panel_fixed_mode->hsync_end &&
+		temp_mode->htotal == panel_fixed_mode->htotal &&
+		temp_mode->vdisplay == panel_fixed_mode->vdisplay &&
+		temp_mode->vsync_start == panel_fixed_mode->vsync_start &&
+		temp_mode->vsync_end == panel_fixed_mode->vsync_end &&
+		temp_mode->vtotal == panel_fixed_mode->vtotal &&
+		temp_mode->clock < temp_downclock) {
+			/*
+			 * downclock is already found. But we expect
+			 * to find the lower downclock.
+			 */
+			temp_downclock = temp_mode->clock;
+		}
+		/* clear it to zero */
+		memset(temp_mode, 0, sizeof(*temp_mode));
+	}
+	kfree(temp_mode);
+	if (temp_downclock < panel_fixed_mode->clock &&
+	    i915_lvds_downclock) {
+		dev_priv->lvds_downclock_avail = 1;
+		dev_priv->lvds_downclock = temp_downclock;
+		DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
+				"Normal Clock %dKHz, downclock %dKHz\n",
+				temp_downclock, panel_fixed_mode->clock);
+	}
 	return;
 }
 
@@ -217,7 +263,7 @@ parse_general_features(struct drm_i915_p
 			if (IS_I85X(dev_priv->dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 66 : 48;
-			else if (IS_IGDNG(dev_priv->dev))
+			else if (IS_IRONLAKE(dev_priv->dev))
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 100 : 120;
 			else
@@ -241,22 +287,18 @@ parse_general_definitions(struct drm_i91
 		GPIOF,
 	};
 
-	/* Set sensible defaults in case we can't find the general block
-	   or it is the wrong chipset */
-	dev_priv->crt_ddc_bus = -1;
-
 	general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 	if (general) {
 		u16 block_size = get_blocksize(general);
 		if (block_size >= sizeof(*general)) {
 			int bus_pin = general->crt_ddc_gmbus_pin;
-			DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
+			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
 			if ((bus_pin >= 1) && (bus_pin <= 6)) {
 				dev_priv->crt_ddc_bus =
 					crt_bus_map_table[bus_pin-1];
 			}
 		} else {
-			DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
+			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
 				  block_size);
 		}
 	}
@@ -274,7 +316,7 @@ parse_sdvo_device_mapping(struct drm_i91
 
 	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 	if (!p_defs) {
-		DRM_DEBUG("No general definition block is found\n");
+		DRM_DEBUG_KMS("No general definition block is found\n");
 		return;
 	}
 	/* judge whether the size of child device meets the requirements.
@@ -284,7 +326,7 @@ parse_sdvo_device_mapping(struct drm_i91
 	 */
 	if (p_defs->child_dev_size != sizeof(*p_child)) {
 		/* different child dev size . Ignore it */
-		DRM_DEBUG("different child size is found. Invalid.\n");
+		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
 		return;
 	}
 	/* get the block size of general definitions */
@@ -310,11 +352,11 @@ parse_sdvo_device_mapping(struct drm_i91
 		if (p_child->dvo_port != DEVICE_PORT_DVOB &&
 			p_child->dvo_port != DEVICE_PORT_DVOC) {
 			/* skip the incorrect SDVO port */
-			DRM_DEBUG("Incorrect SDVO port. Skip it \n");
+			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
 			continue;
 		}
-		DRM_DEBUG("the SDVO device with slave addr %2x is found on "
-				"%s port\n",
+		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+				" %s port\n",
 				p_child->slave_addr,
 				(p_child->dvo_port == DEVICE_PORT_DVOB) ?
 					"SDVOB" : "SDVOC");
@@ -325,21 +367,21 @@ parse_sdvo_device_mapping(struct drm_i91
 			p_mapping->dvo_wiring = p_child->dvo_wiring;
 			p_mapping->initialized = 1;
 		} else {
-			DRM_DEBUG("Maybe one SDVO port is shared by "
+			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
 					 "two SDVO device.\n");
 		}
 		if (p_child->slave2_addr) {
 			/* Maybe this is a SDVO device with multiple inputs */
 			/* And the mapping info is not added */
-			DRM_DEBUG("there exists the slave2_addr. Maybe this "
-				"is a SDVO device with multiple inputs.\n");
+			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
+				" is a SDVO device with multiple inputs.\n");
 		}
 		count++;
 	}
 
 	if (!count) {
 		/* No SDVO device info is found */
-		DRM_DEBUG("No SDVO device info is found in VBT\n");
+		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
 	}
 	return;
 }
@@ -366,6 +408,98 @@ parse_driver_features(struct drm_i915_pr
 		dev_priv->render_reclock_avail = true;
 }
 
+static void
+parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
+{
+	struct bdb_edp *edp;
+
+	edp = find_section(bdb, BDB_EDP);
+	if (!edp) {
+		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
+			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\
+				       assume 18bpp panel color depth.\n");
+			dev_priv->edp_bpp = 18;
+		}
+		return;
+	}
+
+	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
+	case EDP_18BPP:
+		dev_priv->edp_bpp = 18;
+		break;
+	case EDP_24BPP:
+		dev_priv->edp_bpp = 24;
+		break;
+	case EDP_30BPP:
+		dev_priv->edp_bpp = 30;
+		break;
+	}
+}
+
+static void
+parse_device_mapping(struct drm_i915_private *dev_priv,
+		       struct bdb_header *bdb)
+{
+	struct bdb_general_definitions *p_defs;
+	struct child_device_config *p_child, *child_dev_ptr;
+	int i, child_device_num, count;
+	u16	block_size;
+
+	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+	if (!p_defs) {
+		DRM_DEBUG_KMS("No general definition block is found\n");
+		return;
+	}
+	/* judge whether the size of child device meets the requirements.
+	 * If the child device size obtained from general definition block
+	 * is different with sizeof(struct child_device_config), skip the
+	 * parsing of sdvo device info
+	 */
+	if (p_defs->child_dev_size != sizeof(*p_child)) {
+		/* different child dev size . Ignore it */
+		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
+		return;
+	}
+	/* get the block size of general definitions */
+	block_size = get_blocksize(p_defs);
+	/* get the number of child device */
+	child_device_num = (block_size - sizeof(*p_defs)) /
+				sizeof(*p_child);
+	count = 0;
+	/* get the number of child device that is present */
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		count++;
+	}
+	if (!count) {
+		DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
+		return;
+	}
+	dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
+	if (!dev_priv->child_dev) {
+		DRM_DEBUG_KMS("No memory space for child device\n");
+		return;
+	}
+
+	dev_priv->child_dev_num = count;
+	count = 0;
+	for (i = 0; i < child_device_num; i++) {
+		p_child = &(p_defs->devices[i]);
+		if (!p_child->device_type) {
+			/* skip the device block if device type is invalid */
+			continue;
+		}
+		child_dev_ptr = dev_priv->child_dev + count;
+		count++;
+		memcpy((void *)child_dev_ptr, (void *)p_child,
+					sizeof(*p_child));
+	}
+	return;
+}
 /**
  * intel_init_bios - initialize VBIOS settings & find VBT
  * @dev: DRM device
@@ -417,7 +551,9 @@ intel_init_bios(struct drm_device *dev)
 	parse_lfp_panel_data(dev_priv, bdb);
 	parse_sdvo_panel_data(dev_priv, bdb);
 	parse_sdvo_device_mapping(dev_priv, bdb);
+	parse_device_mapping(dev_priv, bdb);
 	parse_driver_features(dev_priv, bdb);
+	parse_edp(dev_priv, bdb);
 
 	pci_unmap_rom(pdev, bios);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_bios.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_bios.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_bios.h	2010-02-24 13:52:17.000000000 -0500
@@ -98,6 +98,7 @@ struct vbios_data {
 #define BDB_SDVO_LVDS_PNP_IDS	 24
 #define BDB_SDVO_LVDS_POWER_SEQ	 25
 #define BDB_TV_OPTIONS		 26
+#define BDB_EDP			 27
 #define BDB_LVDS_OPTIONS	 40
 #define BDB_LVDS_LFP_DATA_PTRS	 41
 #define BDB_LVDS_LFP_DATA	 42
@@ -426,6 +427,45 @@ struct bdb_driver_features {
 	u8 custom_vbt_version;
 } __attribute__((packed));
 
+#define EDP_18BPP	0
+#define EDP_24BPP	1
+#define EDP_30BPP	2
+#define EDP_RATE_1_62	0
+#define EDP_RATE_2_7	1
+#define EDP_LANE_1	0
+#define EDP_LANE_2	1
+#define EDP_LANE_4	3
+#define EDP_PREEMPHASIS_NONE	0
+#define EDP_PREEMPHASIS_3_5dB	1
+#define EDP_PREEMPHASIS_6dB	2
+#define EDP_PREEMPHASIS_9_5dB	3
+#define EDP_VSWING_0_4V		0
+#define EDP_VSWING_0_6V		1
+#define EDP_VSWING_0_8V		2
+#define EDP_VSWING_1_2V		3
+
+struct edp_power_seq {
+	u16 t3;
+	u16 t7;
+	u16 t9;
+	u16 t10;
+	u16 t12;
+} __attribute__ ((packed));
+
+struct edp_link_params {
+	u8 rate:4;
+	u8 lanes:4;
+	u8 preemphasis:4;
+	u8 vswing:4;
+} __attribute__ ((packed));
+
+struct bdb_edp {
+	struct edp_power_seq power_seqs[16];
+	u32 color_depth;
+	u32 sdrrs_msa_timing_delay;
+	struct edp_link_params link_params[16];
+} __attribute__ ((packed));
+
 bool intel_init_bios(struct drm_device *dev);
 
 /*
@@ -549,4 +589,21 @@ bool intel_init_bios(struct drm_device *
 #define   SWF14_APM_STANDBY	0x1
 #define   SWF14_APM_RESTORE	0x0
 
+/* Add the device class for LFP, TV, HDMI */
+#define	 DEVICE_TYPE_INT_LFP	0x1022
+#define	 DEVICE_TYPE_INT_TV	0x1009
+#define	 DEVICE_TYPE_HDMI	0x60D2
+#define	 DEVICE_TYPE_DP		0x68C6
+#define	 DEVICE_TYPE_eDP	0x78C6
+
+/* define the DVO port for HDMI output type */
+#define		DVO_B		1
+#define		DVO_C		2
+#define		DVO_D		3
+
+/* define the PORT for DP output type */
+#define		PORT_IDPB	7
+#define		PORT_IDPC	8
+#define		PORT_IDPD	9
+
 #endif /* _I830_BIOS_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_crt.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_crt.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_crt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_crt.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,7 @@ static void intel_crt_dpms(struct drm_en
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 temp, reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = PCH_ADPA;
 	else
 		reg = ADPA;
@@ -64,34 +64,6 @@ static void intel_crt_dpms(struct drm_en
 	}
 
 	I915_WRITE(reg, temp);
-
-	if (IS_IGD(dev)) {
-		if (mode == DRM_MODE_DPMS_OFF) {
-			/* turn off DAC */
-			temp = I915_READ(PORT_HOTPLUG_EN);
-			temp &= ~CRT_EOS_INT_EN;
-			I915_WRITE(PORT_HOTPLUG_EN, temp);
-
-			temp = I915_READ(PORT_HOTPLUG_STAT);
-			if (temp & CRT_EOS_INT_STATUS)
-				I915_WRITE(PORT_HOTPLUG_STAT,
-					CRT_EOS_INT_STATUS);
-		} else {
-			/* turn on DAC. EOS interrupt must be enabled after DAC
-			 * is enabled, so it sounds not good to enable it in
-			 * i915_driver_irq_postinstall()
-			 * wait 12.5ms after DAC is enabled
-			 */
-			msleep(13);
-			temp = I915_READ(PORT_HOTPLUG_STAT);
-			if (temp & CRT_EOS_INT_STATUS)
-				I915_WRITE(PORT_HOTPLUG_STAT,
-					CRT_EOS_INT_STATUS);
-			temp = I915_READ(PORT_HOTPLUG_EN);
-			temp |= CRT_EOS_INT_EN;
-			I915_WRITE(PORT_HOTPLUG_EN, temp);
-		}
-	}
 }
 
 static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -141,7 +113,7 @@ static void intel_crt_mode_set(struct dr
 	else
 		dpll_md_reg = DPLL_B_MD;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		adpa_reg = PCH_ADPA;
 	else
 		adpa_reg = ADPA;
@@ -150,7 +122,7 @@ static void intel_crt_mode_set(struct dr
 	 * Disable separate mode multiplier used when cloning SDVO to CRT
 	 * XXX this needs to be adjusted when we really are cloning
 	 */
-	if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+	if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
 		dpll_md = I915_READ(dpll_md_reg);
 		I915_WRITE(dpll_md_reg,
 			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -164,18 +136,18 @@ static void intel_crt_mode_set(struct dr
 
 	if (intel_crtc->pipe == 0) {
 		adpa |= ADPA_PIPE_A_SELECT;
-		if (!IS_IGDNG(dev))
+		if (!IS_IRONLAKE(dev))
 			I915_WRITE(BCLRPAT_A, 0);
 	} else {
 		adpa |= ADPA_PIPE_B_SELECT;
-		if (!IS_IGDNG(dev))
+		if (!IS_IRONLAKE(dev))
 			I915_WRITE(BCLRPAT_B, 0);
 	}
 
 	I915_WRITE(adpa_reg, adpa);
 }
 
-static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -185,6 +157,9 @@ static bool intel_igdng_crt_detect_hotpl
 	adpa = I915_READ(PCH_ADPA);
 
 	adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+	/* disable HPD first */
+	I915_WRITE(PCH_ADPA, adpa);
+	(void)I915_READ(PCH_ADPA);
 
 	adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
 			ADPA_CRT_HOTPLUG_WARMUP_10MS |
@@ -194,7 +169,7 @@ static bool intel_igdng_crt_detect_hotpl
 			ADPA_CRT_HOTPLUG_ENABLE |
 			ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
 
-	DRM_DEBUG("pch crt adpa 0x%x", adpa);
+	DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
 	I915_WRITE(PCH_ADPA, adpa);
 
 	while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
@@ -227,8 +202,8 @@ static bool intel_crt_detect_hotplug(str
 	u32 hotplug_en;
 	int i, tries = 0;
 
-	if (IS_IGDNG(dev))
-		return intel_igdng_crt_detect_hotplug(connector);
+	if (IS_IRONLAKE(dev))
+		return intel_ironlake_crt_detect_hotplug(connector);
 
 	/*
 	 * On 4 series desktop, CRT detect sequence need to be done twice
@@ -549,12 +524,12 @@ void intel_crt_init(struct drm_device *d
 					  &intel_output->enc);
 
 	/* Set up the DDC bus. */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		i2c_reg = PCH_GPIOA;
 	else {
 		i2c_reg = GPIOA;
 		/* Use VBT information for CRT DDC if available */
-		if (dev_priv->crt_ddc_bus != -1)
+		if (dev_priv->crt_ddc_bus != 0)
 			i2c_reg = dev_priv->crt_ddc_bus;
 	}
 	intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
@@ -576,4 +551,6 @@ void intel_crt_init(struct drm_device *d
 	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
 	drm_sysfs_connector_add(connector);
+
+	dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_display.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_display.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
 
 #include "drm_crtc_helper.h"
 
@@ -70,8 +70,6 @@ struct intel_limit {
     intel_p2_t	    p2;
     bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
 		      int, int, intel_clock_t *);
-    bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
-			      int, int, intel_clock_t *);
 };
 
 #define I8XX_DOT_MIN		  25000
@@ -102,32 +100,32 @@ struct intel_limit {
 #define I9XX_DOT_MAX		 400000
 #define I9XX_VCO_MIN		1400000
 #define I9XX_VCO_MAX		2800000
-#define IGD_VCO_MIN		1700000
-#define IGD_VCO_MAX		3500000
+#define PINEVIEW_VCO_MIN		1700000
+#define PINEVIEW_VCO_MAX		3500000
 #define I9XX_N_MIN		      1
 #define I9XX_N_MAX		      6
-/* IGD's Ncounter is a ring counter */
-#define IGD_N_MIN		      3
-#define IGD_N_MAX		      6
+/* Pineview's Ncounter is a ring counter */
+#define PINEVIEW_N_MIN		      3
+#define PINEVIEW_N_MAX		      6
 #define I9XX_M_MIN		     70
 #define I9XX_M_MAX		    120
-#define IGD_M_MIN		      2
-#define IGD_M_MAX		    256
+#define PINEVIEW_M_MIN		      2
+#define PINEVIEW_M_MAX		    256
 #define I9XX_M1_MIN		     10
 #define I9XX_M1_MAX		     22
 #define I9XX_M2_MIN		      5
 #define I9XX_M2_MAX		      9
-/* IGD M1 is reserved, and must be 0 */
-#define IGD_M1_MIN		      0
-#define IGD_M1_MAX		      0
-#define IGD_M2_MIN		      0
-#define IGD_M2_MAX		      254
+/* Pineview M1 is reserved, and must be 0 */
+#define PINEVIEW_M1_MIN		      0
+#define PINEVIEW_M1_MAX		      0
+#define PINEVIEW_M2_MIN		      0
+#define PINEVIEW_M2_MAX		      254
 #define I9XX_P_SDVO_DAC_MIN	      5
 #define I9XX_P_SDVO_DAC_MAX	     80
 #define I9XX_P_LVDS_MIN		      7
 #define I9XX_P_LVDS_MAX		     98
-#define IGD_P_LVDS_MIN		      7
-#define IGD_P_LVDS_MAX		     112
+#define PINEVIEW_P_LVDS_MIN		      7
+#define PINEVIEW_P_LVDS_MAX		     112
 #define I9XX_P1_MIN		      1
 #define I9XX_P1_MAX		      8
 #define I9XX_P2_SDVO_DAC_SLOW		     10
@@ -234,53 +232,108 @@ struct intel_limit {
 #define G4X_P2_DISPLAY_PORT_FAST           10
 #define G4X_P2_DISPLAY_PORT_LIMIT          0
 
-/* IGDNG */
+/* Ironlake */
 /* as we calculate clock using (register_value + 2) for
    N/M1/M2, so here the range value for them is (actual_value-2).
  */
-#define IGDNG_DOT_MIN         25000
-#define IGDNG_DOT_MAX         350000
-#define IGDNG_VCO_MIN         1760000
-#define IGDNG_VCO_MAX         3510000
-#define IGDNG_N_MIN           1
-#define IGDNG_N_MAX           5
-#define IGDNG_M_MIN           79
-#define IGDNG_M_MAX           118
-#define IGDNG_M1_MIN          12
-#define IGDNG_M1_MAX          23
-#define IGDNG_M2_MIN          5
-#define IGDNG_M2_MAX          9
-#define IGDNG_P_SDVO_DAC_MIN  5
-#define IGDNG_P_SDVO_DAC_MAX  80
-#define IGDNG_P_LVDS_MIN      28
-#define IGDNG_P_LVDS_MAX      112
-#define IGDNG_P1_MIN          1
-#define IGDNG_P1_MAX          8
-#define IGDNG_P2_SDVO_DAC_SLOW 10
-#define IGDNG_P2_SDVO_DAC_FAST 5
-#define IGDNG_P2_LVDS_SLOW    14 /* single channel */
-#define IGDNG_P2_LVDS_FAST    7  /* double channel */
-#define IGDNG_P2_DOT_LIMIT    225000 /* 225Mhz */
+#define IRONLAKE_DOT_MIN         25000
+#define IRONLAKE_DOT_MAX         350000
+#define IRONLAKE_VCO_MIN         1760000
+#define IRONLAKE_VCO_MAX         3510000
+#define IRONLAKE_M1_MIN          12
+#define IRONLAKE_M1_MAX          22
+#define IRONLAKE_M2_MIN          5
+#define IRONLAKE_M2_MAX          9
+#define IRONLAKE_P2_DOT_LIMIT    225000 /* 225Mhz */
+
+/* We have parameter ranges for different type of outputs. */
+
+/* DAC & HDMI Refclk 120Mhz */
+#define IRONLAKE_DAC_N_MIN	1
+#define IRONLAKE_DAC_N_MAX	5
+#define IRONLAKE_DAC_M_MIN	79
+#define IRONLAKE_DAC_M_MAX	127
+#define IRONLAKE_DAC_P_MIN	5
+#define IRONLAKE_DAC_P_MAX	80
+#define IRONLAKE_DAC_P1_MIN	1
+#define IRONLAKE_DAC_P1_MAX	8
+#define IRONLAKE_DAC_P2_SLOW	10
+#define IRONLAKE_DAC_P2_FAST	5
+
+/* LVDS single-channel 120Mhz refclk */
+#define IRONLAKE_LVDS_S_N_MIN	1
+#define IRONLAKE_LVDS_S_N_MAX	3
+#define IRONLAKE_LVDS_S_M_MIN	79
+#define IRONLAKE_LVDS_S_M_MAX	118
+#define IRONLAKE_LVDS_S_P_MIN	28
+#define IRONLAKE_LVDS_S_P_MAX	112
+#define IRONLAKE_LVDS_S_P1_MIN	2
+#define IRONLAKE_LVDS_S_P1_MAX	8
+#define IRONLAKE_LVDS_S_P2_SLOW	14
+#define IRONLAKE_LVDS_S_P2_FAST	14
+
+/* LVDS dual-channel 120Mhz refclk */
+#define IRONLAKE_LVDS_D_N_MIN	1
+#define IRONLAKE_LVDS_D_N_MAX	3
+#define IRONLAKE_LVDS_D_M_MIN	79
+#define IRONLAKE_LVDS_D_M_MAX	127
+#define IRONLAKE_LVDS_D_P_MIN	14
+#define IRONLAKE_LVDS_D_P_MAX	56
+#define IRONLAKE_LVDS_D_P1_MIN	2
+#define IRONLAKE_LVDS_D_P1_MAX	8
+#define IRONLAKE_LVDS_D_P2_SLOW	7
+#define IRONLAKE_LVDS_D_P2_FAST	7
+
+/* LVDS single-channel 100Mhz refclk */
+#define IRONLAKE_LVDS_S_SSC_N_MIN	1
+#define IRONLAKE_LVDS_S_SSC_N_MAX	2
+#define IRONLAKE_LVDS_S_SSC_M_MIN	79
+#define IRONLAKE_LVDS_S_SSC_M_MAX	126
+#define IRONLAKE_LVDS_S_SSC_P_MIN	28
+#define IRONLAKE_LVDS_S_SSC_P_MAX	112
+#define IRONLAKE_LVDS_S_SSC_P1_MIN	2
+#define IRONLAKE_LVDS_S_SSC_P1_MAX	8
+#define IRONLAKE_LVDS_S_SSC_P2_SLOW	14
+#define IRONLAKE_LVDS_S_SSC_P2_FAST	14
+
+/* LVDS dual-channel 100Mhz refclk */
+#define IRONLAKE_LVDS_D_SSC_N_MIN	1
+#define IRONLAKE_LVDS_D_SSC_N_MAX	3
+#define IRONLAKE_LVDS_D_SSC_M_MIN	79
+#define IRONLAKE_LVDS_D_SSC_M_MAX	126
+#define IRONLAKE_LVDS_D_SSC_P_MIN	14
+#define IRONLAKE_LVDS_D_SSC_P_MAX	42
+#define IRONLAKE_LVDS_D_SSC_P1_MIN	2
+#define IRONLAKE_LVDS_D_SSC_P1_MAX	6
+#define IRONLAKE_LVDS_D_SSC_P2_SLOW	7
+#define IRONLAKE_LVDS_D_SSC_P2_FAST	7
+
+/* DisplayPort */
+#define IRONLAKE_DP_N_MIN		1
+#define IRONLAKE_DP_N_MAX		2
+#define IRONLAKE_DP_M_MIN		81
+#define IRONLAKE_DP_M_MAX		90
+#define IRONLAKE_DP_P_MIN		10
+#define IRONLAKE_DP_P_MAX		20
+#define IRONLAKE_DP_P2_FAST		10
+#define IRONLAKE_DP_P2_SLOW		10
+#define IRONLAKE_DP_P2_LIMIT		0
+#define IRONLAKE_DP_P1_MIN		1
+#define IRONLAKE_DP_P1_MAX		2
 
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 		    int target, int refclk, intel_clock_t *best_clock);
 static bool
-intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			    int target, int refclk, 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 *best_clock);
-static bool
-intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, 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 *best_clock);
 static bool
-intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock);
+intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
+			   int target, int refclk, intel_clock_t *best_clock);
 
 static const intel_limit_t intel_limits_i8xx_dvo = {
         .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
@@ -294,7 +347,6 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -309,7 +361,6 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_LVDS_SLOW,	.p2_fast = I8XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 	
 static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -324,7 +375,6 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -342,7 +392,6 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
     /* below parameter and function is for G4X Chipset Family*/
@@ -360,7 +409,6 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_SDVO_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
-	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -377,7 +425,6 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_HDMI_DAC_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
-	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -402,7 +449,6 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
-	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -427,7 +473,6 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
-	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_display_port = {
@@ -453,74 +498,162 @@ static const intel_limit_t intel_limits_
         .find_pll = intel_find_pll_g4x_dp,
 };
 
-static const intel_limit_t intel_limits_igd_sdvo = {
+static const intel_limit_t intel_limits_pineview_sdvo = {
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX},
-        .vco = { .min = IGD_VCO_MIN,		.max = IGD_VCO_MAX },
-        .n   = { .min = IGD_N_MIN,		.max = IGD_N_MAX },
-        .m   = { .min = IGD_M_MIN,		.max = IGD_M_MAX },
-        .m1  = { .min = IGD_M1_MIN,		.max = IGD_M1_MAX },
-        .m2  = { .min = IGD_M2_MIN,		.max = IGD_M2_MAX },
+        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
+        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
+        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
+        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
+        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
         .p   = { .min = I9XX_P_SDVO_DAC_MIN,    .max = I9XX_P_SDVO_DAC_MAX },
         .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
-static const intel_limit_t intel_limits_igd_lvds = {
+static const intel_limit_t intel_limits_pineview_lvds = {
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
-        .vco = { .min = IGD_VCO_MIN,		.max = IGD_VCO_MAX },
-        .n   = { .min = IGD_N_MIN,		.max = IGD_N_MAX },
-        .m   = { .min = IGD_M_MIN,		.max = IGD_M_MAX },
-        .m1  = { .min = IGD_M1_MIN,		.max = IGD_M1_MAX },
-        .m2  = { .min = IGD_M2_MIN,		.max = IGD_M2_MAX },
-        .p   = { .min = IGD_P_LVDS_MIN,	.max = IGD_P_LVDS_MAX },
+        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
+        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
+        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
+        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
+        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
+        .p   = { .min = PINEVIEW_P_LVDS_MIN,	.max = PINEVIEW_P_LVDS_MAX },
         .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	/* IGD only supports single-channel mode. */
+	/* Pineview only supports single-channel mode. */
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
 	.find_pll = intel_find_best_PLL,
-	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
-static const intel_limit_t intel_limits_igdng_sdvo = {
-	.dot = { .min = IGDNG_DOT_MIN,          .max = IGDNG_DOT_MAX },
-	.vco = { .min = IGDNG_VCO_MIN,          .max = IGDNG_VCO_MAX },
-	.n   = { .min = IGDNG_N_MIN,            .max = IGDNG_N_MAX },
-	.m   = { .min = IGDNG_M_MIN,            .max = IGDNG_M_MAX },
-	.m1  = { .min = IGDNG_M1_MIN,           .max = IGDNG_M1_MAX },
-	.m2  = { .min = IGDNG_M2_MIN,           .max = IGDNG_M2_MAX },
-	.p   = { .min = IGDNG_P_SDVO_DAC_MIN,   .max = IGDNG_P_SDVO_DAC_MAX },
-	.p1  = { .min = IGDNG_P1_MIN,           .max = IGDNG_P1_MAX },
-	.p2  = { .dot_limit = IGDNG_P2_DOT_LIMIT,
-		 .p2_slow = IGDNG_P2_SDVO_DAC_SLOW,
-		 .p2_fast = IGDNG_P2_SDVO_DAC_FAST },
-	.find_pll = intel_igdng_find_best_PLL,
+static const intel_limit_t intel_limits_ironlake_dac = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_DAC_N_MIN,        .max = IRONLAKE_DAC_N_MAX },
+	.m   = { .min = IRONLAKE_DAC_M_MIN,        .max = IRONLAKE_DAC_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_DAC_P_MIN,	   .max = IRONLAKE_DAC_P_MAX },
+	.p1  = { .min = IRONLAKE_DAC_P1_MIN,       .max = IRONLAKE_DAC_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_DAC_P2_SLOW,
+		 .p2_fast = IRONLAKE_DAC_P2_FAST },
+	.find_pll = intel_g4x_find_best_PLL,
 };
 
-static const intel_limit_t intel_limits_igdng_lvds = {
-	.dot = { .min = IGDNG_DOT_MIN,          .max = IGDNG_DOT_MAX },
-	.vco = { .min = IGDNG_VCO_MIN,          .max = IGDNG_VCO_MAX },
-	.n   = { .min = IGDNG_N_MIN,            .max = IGDNG_N_MAX },
-	.m   = { .min = IGDNG_M_MIN,            .max = IGDNG_M_MAX },
-	.m1  = { .min = IGDNG_M1_MIN,           .max = IGDNG_M1_MAX },
-	.m2  = { .min = IGDNG_M2_MIN,           .max = IGDNG_M2_MAX },
-	.p   = { .min = IGDNG_P_LVDS_MIN,       .max = IGDNG_P_LVDS_MAX },
-	.p1  = { .min = IGDNG_P1_MIN,           .max = IGDNG_P1_MAX },
-	.p2  = { .dot_limit = IGDNG_P2_DOT_LIMIT,
-		 .p2_slow = IGDNG_P2_LVDS_SLOW,
-		 .p2_fast = IGDNG_P2_LVDS_FAST },
-	.find_pll = intel_igdng_find_best_PLL,
+static const intel_limit_t intel_limits_ironlake_single_lvds = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_LVDS_S_N_MIN,     .max = IRONLAKE_LVDS_S_N_MAX },
+	.m   = { .min = IRONLAKE_LVDS_S_M_MIN,     .max = IRONLAKE_LVDS_S_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_LVDS_S_P_MIN,     .max = IRONLAKE_LVDS_S_P_MAX },
+	.p1  = { .min = IRONLAKE_LVDS_S_P1_MIN,    .max = IRONLAKE_LVDS_S_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_LVDS_S_P2_SLOW,
+		 .p2_fast = IRONLAKE_LVDS_S_P2_FAST },
+	.find_pll = intel_g4x_find_best_PLL,
 };
 
-static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc)
+static const intel_limit_t intel_limits_ironlake_dual_lvds = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_LVDS_D_N_MIN,     .max = IRONLAKE_LVDS_D_N_MAX },
+	.m   = { .min = IRONLAKE_LVDS_D_M_MIN,     .max = IRONLAKE_LVDS_D_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_LVDS_D_P_MIN,     .max = IRONLAKE_LVDS_D_P_MAX },
+	.p1  = { .min = IRONLAKE_LVDS_D_P1_MIN,    .max = IRONLAKE_LVDS_D_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_LVDS_D_P2_SLOW,
+		 .p2_fast = IRONLAKE_LVDS_D_P2_FAST },
+	.find_pll = intel_g4x_find_best_PLL,
+};
+
+static const intel_limit_t intel_limits_ironlake_single_lvds_100m = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX },
+	.m   = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX },
+	.p1  = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW,
+		 .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST },
+	.find_pll = intel_g4x_find_best_PLL,
+};
+
+static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
+	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
+	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
+	.n   = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX },
+	.m   = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX },
+	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
+	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
+	.p   = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX },
+	.p1  = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX },
+	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+		 .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW,
+		 .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST },
+	.find_pll = intel_g4x_find_best_PLL,
+};
+
+static const intel_limit_t intel_limits_ironlake_display_port = {
+        .dot = { .min = IRONLAKE_DOT_MIN,
+                 .max = IRONLAKE_DOT_MAX },
+        .vco = { .min = IRONLAKE_VCO_MIN,
+                 .max = IRONLAKE_VCO_MAX},
+        .n   = { .min = IRONLAKE_DP_N_MIN,
+                 .max = IRONLAKE_DP_N_MAX },
+        .m   = { .min = IRONLAKE_DP_M_MIN,
+                 .max = IRONLAKE_DP_M_MAX },
+        .m1  = { .min = IRONLAKE_M1_MIN,
+                 .max = IRONLAKE_M1_MAX },
+        .m2  = { .min = IRONLAKE_M2_MIN,
+                 .max = IRONLAKE_M2_MAX },
+        .p   = { .min = IRONLAKE_DP_P_MIN,
+                 .max = IRONLAKE_DP_P_MAX },
+        .p1  = { .min = IRONLAKE_DP_P1_MIN,
+                 .max = IRONLAKE_DP_P1_MAX},
+        .p2  = { .dot_limit = IRONLAKE_DP_P2_LIMIT,
+                 .p2_slow = IRONLAKE_DP_P2_SLOW,
+                 .p2_fast = IRONLAKE_DP_P2_FAST },
+        .find_pll = intel_find_pll_ironlake_dp,
+};
+
+static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc)
 {
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	const intel_limit_t *limit;
-	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-		limit = &intel_limits_igdng_lvds;
+	int refclk = 120;
+
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+		if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100)
+			refclk = 100;
+
+		if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
+		    LVDS_CLKB_POWER_UP) {
+			/* LVDS dual channel */
+			if (refclk == 100)
+				limit = &intel_limits_ironlake_dual_lvds_100m;
+			else
+				limit = &intel_limits_ironlake_dual_lvds;
+		} else {
+			if (refclk == 100)
+				limit = &intel_limits_ironlake_single_lvds_100m;
+			else
+				limit = &intel_limits_ironlake_single_lvds;
+		}
+	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+			HAS_eDP)
+		limit = &intel_limits_ironlake_display_port;
 	else
-		limit = &intel_limits_igdng_sdvo;
+		limit = &intel_limits_ironlake_dac;
 
 	return limit;
 }
@@ -557,20 +690,20 @@ static const intel_limit_t *intel_limit(
 	struct drm_device *dev = crtc->dev;
 	const intel_limit_t *limit;
 
-	if (IS_IGDNG(dev))
-		limit = intel_igdng_limit(crtc);
+	if (IS_IRONLAKE(dev))
+		limit = intel_ironlake_limit(crtc);
 	else if (IS_G4X(dev)) {
 		limit = intel_g4x_limit(crtc);
-	} else if (IS_I9XX(dev) && !IS_IGD(dev)) {
+	} else if (IS_I9XX(dev) && !IS_PINEVIEW(dev)) {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i9xx_lvds;
 		else
 			limit = &intel_limits_i9xx_sdvo;
-	} else if (IS_IGD(dev)) {
+	} else if (IS_PINEVIEW(dev)) {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-			limit = &intel_limits_igd_lvds;
+			limit = &intel_limits_pineview_lvds;
 		else
-			limit = &intel_limits_igd_sdvo;
+			limit = &intel_limits_pineview_sdvo;
 	} else {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i8xx_lvds;
@@ -580,8 +713,8 @@ static const intel_limit_t *intel_limit(
 	return limit;
 }
 
-/* m1 is reserved as 0 in IGD, n is a ring counter */
-static void igd_clock(int refclk, intel_clock_t *clock)
+/* m1 is reserved as 0 in Pineview, n is a ring counter */
+static void pineview_clock(int refclk, intel_clock_t *clock)
 {
 	clock->m = clock->m2 + 2;
 	clock->p = clock->p1 * clock->p2;
@@ -591,8 +724,8 @@ static void igd_clock(int refclk, intel_
 
 static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
 {
-	if (IS_IGD(dev)) {
-		igd_clock(refclk, clock);
+	if (IS_PINEVIEW(dev)) {
+		pineview_clock(refclk, clock);
 		return;
 	}
 	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
@@ -657,7 +790,7 @@ static bool intel_PLL_is_valid(struct dr
 		INTELPllInvalid ("m2 out of range\n");
 	if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
 		INTELPllInvalid ("m1 out of range\n");
-	if (clock->m1 <= clock->m2 && !IS_IGD(dev))
+	if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
 		INTELPllInvalid ("m1 <= m2\n");
 	if (clock->m   < limit->m.min   || limit->m.max   < clock->m)
 		INTELPllInvalid ("m out of range\n");
@@ -706,16 +839,17 @@ intel_find_best_PLL(const intel_limit_t
 
 	memset (best_clock, 0, sizeof (*best_clock));
 
-	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
-		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++) {
-				/* m1 is always 0 in IGD */
-				if (clock.m2 >= clock.m1 && !IS_IGD(dev))
-					break;
-				for (clock.n = limit->n.min;
-				     clock.n <= limit->n.max; clock.n++) {
+	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++) {
+			/* m1 is always 0 in Pineview */
+			if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
+				break;
+			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;
 
 					intel_clock(dev, refclk, &clock);
@@ -736,46 +870,6 @@ intel_find_best_PLL(const intel_limit_t
 	return (err != target);
 }
 
-
-static bool
-intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			    int target, int refclk, intel_clock_t *best_clock)
-
-{
-	struct drm_device *dev = crtc->dev;
-	intel_clock_t clock;
-	int err = target;
-	bool found = false;
-
-	memcpy(&clock, best_clock, sizeof(intel_clock_t));
-
-	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++) {
-			/* m1 is always 0 in IGD */
-			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
-				break;
-			for (clock.n = limit->n.min; clock.n <= limit->n.max;
-			     clock.n++) {
-				int this_err;
-
-				intel_clock(dev, refclk, &clock);
-
-				if (!intel_PLL_is_valid(crtc, &clock))
-					continue;
-
-				this_err = abs(clock.dot - target);
-				if (this_err < err) {
-					*best_clock = clock;
-					err = this_err;
-					found = true;
-				}
-			}
-		}
-	}
-
-	return found;
-}
-
 static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock)
@@ -790,7 +884,13 @@ intel_g4x_find_best_PLL(const intel_limi
 	found = false;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+		int lvds_reg;
+
+		if (IS_IRONLAKE(dev))
+			lvds_reg = PCH_LVDS;
+		else
+			lvds_reg = LVDS;
+		if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) ==
 		    LVDS_CLKB_POWER_UP)
 			clock.p2 = limit->p2.p2_fast;
 		else
@@ -833,11 +933,16 @@ intel_g4x_find_best_PLL(const intel_limi
 }
 
 static bool
-intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock)
+intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
+			   int target, int refclk, intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
+
+	/* return directly when it is eDP */
+	if (HAS_eDP)
+		return true;
+
 	if (target < 200000) {
 		clock.n = 1;
 		clock.p1 = 2;
@@ -856,68 +961,6 @@ intel_find_pll_igdng_dp(const intel_limi
 	return true;
 }
 
-static bool
-intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *best_clock)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	intel_clock_t clock;
-	int err_most = 47;
-	int err_min = 10000;
-
-	/* eDP has only 2 clock choice, no n/m/p setting */
-	if (HAS_eDP)
-		return true;
-
-	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
-		return intel_find_pll_igdng_dp(limit, crtc, target,
-					       refclk, best_clock);
-
-	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
-			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.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
-		/* based on hardware requriment prefer smaller n to precision */
-		for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
-			/* based on hardware requirment prefere larger m1,m2 */
-			for (clock.m1 = limit->m1.max;
-			     clock.m1 >= limit->m1.min; clock.m1--) {
-				for (clock.m2 = limit->m2.max;
-				     clock.m2 >= limit->m2.min; clock.m2--) {
-					int this_err;
-
-					intel_clock(dev, refclk, &clock);
-					if (!intel_PLL_is_valid(crtc, &clock))
-						continue;
-					this_err = abs((10000 - (target*10000/clock.dot)));
-					if (this_err < err_most) {
-						*best_clock = clock;
-						/* found on first matching */
-						goto out;
-					} else if (this_err < err_min) {
-						*best_clock = clock;
-						err_min = this_err;
-					}
-				}
-			}
-		}
-	}
-out:
-	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,
@@ -949,7 +992,7 @@ void
 intel_wait_for_vblank(struct drm_device *dev)
 {
 	/* Wait for 20ms, i.e. one cycle at 50hz. */
-	mdelay(20);
+	msleep(20);
 }
 
 /* Parameters have changed, update FBC info */
@@ -988,13 +1031,15 @@ static void i8xx_enable_fbc(struct drm_c
 
 	/* enable it... */
 	fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
+	if (IS_I945GM(dev))
+		fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
 	fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
 	fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
 	if (obj_priv->tiling_mode != I915_TILING_NONE)
 		fbc_ctl |= dev_priv->cfb_fence;
 	I915_WRITE(FBC_CONTROL, fbc_ctl);
 
-	DRM_DEBUG("enabled FBC, pitch %ld, yoff %d, plane %d, ",
+	DRM_DEBUG_KMS("enabled FBC, pitch %ld, yoff %d, plane %d, ",
 		  dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane);
 }
 
@@ -1017,7 +1062,7 @@ void i8xx_disable_fbc(struct drm_device
 
 	intel_wait_for_vblank(dev);
 
-	DRM_DEBUG("disabled FBC\n");
+	DRM_DEBUG_KMS("disabled FBC\n");
 }
 
 static bool i8xx_fbc_enabled(struct drm_crtc *crtc)
@@ -1062,7 +1107,7 @@ static void g4x_enable_fbc(struct drm_cr
 	/* enable it... */
 	I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN);
 
-	DRM_DEBUG("enabled fbc on plane %d\n", intel_crtc->plane);
+	DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
 }
 
 void g4x_disable_fbc(struct drm_device *dev)
@@ -1076,7 +1121,7 @@ void g4x_disable_fbc(struct drm_device *
 	I915_WRITE(DPFC_CONTROL, dpfc_ctl);
 	intel_wait_for_vblank(dev);
 
-	DRM_DEBUG("disabled FBC\n");
+	DRM_DEBUG_KMS("disabled FBC\n");
 }
 
 static bool g4x_fbc_enabled(struct drm_crtc *crtc)
@@ -1141,25 +1186,27 @@ static void intel_update_fbc(struct drm_
 	 *   - going to an unsupported config (interlace, pixel multiply, etc.)
 	 */
 	if (intel_fb->obj->size > dev_priv->cfb_size) {
-		DRM_DEBUG("framebuffer too large, disabling compression\n");
+		DRM_DEBUG_KMS("framebuffer too large, disabling "
+				"compression\n");
 		goto out_disable;
 	}
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 	    (mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
-		DRM_DEBUG("mode incompatible with compression, disabling\n");
+		DRM_DEBUG_KMS("mode incompatible with compression, "
+				"disabling\n");
 		goto out_disable;
 	}
 	if ((mode->hdisplay > 2048) ||
 	    (mode->vdisplay > 1536)) {
-		DRM_DEBUG("mode too large for compression, disabling\n");
+		DRM_DEBUG_KMS("mode too large for compression, disabling\n");
 		goto out_disable;
 	}
 	if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
-		DRM_DEBUG("plane not 0, disabling compression\n");
+		DRM_DEBUG_KMS("plane not 0, disabling compression\n");
 		goto out_disable;
 	}
 	if (obj_priv->tiling_mode != I915_TILING_X) {
-		DRM_DEBUG("framebuffer not tiled, disabling compression\n");
+		DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n");
 		goto out_disable;
 	}
 
@@ -1181,13 +1228,57 @@ static void intel_update_fbc(struct drm_
 	return;
 
 out_disable:
-	DRM_DEBUG("unsupported config, disabling FBC\n");
+	DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
 	/* Multiple disables should be harmless */
 	if (dev_priv->display.fbc_enabled(crtc))
 		dev_priv->display.disable_fbc(dev);
 }
 
 static int
+intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	u32 alignment;
+	int ret;
+
+	switch (obj_priv->tiling_mode) {
+	case I915_TILING_NONE:
+		alignment = 64 * 1024;
+		break;
+	case I915_TILING_X:
+		/* pin() will align the object as required by fence */
+		alignment = 0;
+		break;
+	case I915_TILING_Y:
+		/* FIXME: Is this true? */
+		DRM_ERROR("Y tiled not allowed for scan out buffers\n");
+		return -EINVAL;
+	default:
+		BUG();
+	}
+
+	ret = i915_gem_object_pin(obj, alignment);
+	if (ret != 0)
+		return ret;
+
+	/* Install a fence for tiled scan-out. Pre-i965 always needs a
+	 * fence, whereas 965+ only requires a fence if using
+	 * framebuffer compression.  For simplicity, we always install
+	 * a fence as the cost is not that onerous.
+	 */
+	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+	    obj_priv->tiling_mode != I915_TILING_NONE) {
+		ret = i915_gem_object_get_fence_reg(obj);
+		if (ret != 0) {
+			i915_gem_object_unpin(obj);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		    struct drm_framebuffer *old_fb)
 {
@@ -1206,12 +1297,12 @@ intel_pipe_set_base(struct drm_crtc *crt
 	int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
 	int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
 	int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
-	u32 dspcntr, alignment;
+	u32 dspcntr;
 	int ret;
 
 	/* no fb bound */
 	if (!crtc->fb) {
-		DRM_DEBUG("No FB bound\n");
+		DRM_DEBUG_KMS("No FB bound\n");
 		return 0;
 	}
 
@@ -1228,50 +1319,20 @@ intel_pipe_set_base(struct drm_crtc *crt
 	obj = intel_fb->obj;
 	obj_priv = obj->driver_private;
 
-	switch (obj_priv->tiling_mode) {
-	case I915_TILING_NONE:
-		alignment = 64 * 1024;
-		break;
-	case I915_TILING_X:
-		/* pin() will align the object as required by fence */
-		alignment = 0;
-		break;
-	case I915_TILING_Y:
-		/* FIXME: Is this true? */
-		DRM_ERROR("Y tiled not allowed for scan out buffers\n");
-		return -EINVAL;
-	default:
-		BUG();
-	}
-
 	mutex_lock(&dev->struct_mutex);
-	ret = i915_gem_object_pin(obj, alignment);
+	ret = intel_pin_and_fence_fb_obj(dev, obj);
 	if (ret != 0) {
 		mutex_unlock(&dev->struct_mutex);
 		return ret;
 	}
 
-	ret = i915_gem_object_set_to_gtt_domain(obj, 1);
+	ret = i915_gem_object_set_to_display_plane(obj);
 	if (ret != 0) {
 		i915_gem_object_unpin(obj);
 		mutex_unlock(&dev->struct_mutex);
 		return ret;
 	}
 
-	/* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
-	 * whereas 965+ only requires a fence if using framebuffer compression.
-	 * For simplicity, we always install a fence as the cost is not that onerous.
-	 */
-	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
-	    obj_priv->tiling_mode != I915_TILING_NONE) {
-		ret = i915_gem_object_get_fence_reg(obj);
-		if (ret != 0) {
-			i915_gem_object_unpin(obj);
-			mutex_unlock(&dev->struct_mutex);
-			return ret;
-		}
-	}
-
 	dspcntr = I915_READ(dspcntr_reg);
 	/* Mask out pixel format bits in case we change it */
 	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
@@ -1287,7 +1348,10 @@ intel_pipe_set_base(struct drm_crtc *crt
 		break;
 	case 24:
 	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+		if (crtc->fb->depth == 30)
+			dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
+		else
+			dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 		break;
 	default:
 		DRM_ERROR("Unknown color depth\n");
@@ -1302,7 +1366,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 			dspcntr &= ~DISPPLANE_TILED;
 	}
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		/* must disable */
 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
@@ -1311,7 +1375,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 	Start = obj_priv->gtt_offset;
 	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
-	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
 	I915_WRITE(dspstride, crtc->fb->pitch);
 	if (IS_I965G(dev)) {
 		I915_WRITE(dspbase, Offset);
@@ -1363,7 +1427,7 @@ static void i915_disable_vga (struct drm
 	u8 sr1;
 	u32 vga_reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		vga_reg = CPU_VGACNTRL;
 	else
 		vga_reg = VGACNTRL;
@@ -1379,19 +1443,19 @@ static void i915_disable_vga (struct drm
 	I915_WRITE(vga_reg, VGA_DISP_DISABLE);
 }
 
-static void igdng_disable_pll_edp (struct drm_crtc *crtc)
+static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_ENABLE;
 	I915_WRITE(DP_A, dpa_ctl);
 }
 
-static void igdng_enable_pll_edp (struct drm_crtc *crtc)
+static void ironlake_enable_pll_edp (struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1404,13 +1468,13 @@ static void igdng_enable_pll_edp (struct
 }
 
 
-static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock)
+static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG("eDP PLL enable for clock %d\n", clock);
+	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock);
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_FREQ_MASK;
 
@@ -1440,7 +1504,7 @@ static void igdng_set_pll_edp (struct dr
 	udelay(500);
 }
 
-static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1473,6 +1537,10 @@ static void igdng_crtc_dpms(struct drm_c
 	int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B;
 	u32 temp;
 	int tries = 5, j, n;
+	u32 pipe_bpc;
+
+	temp = I915_READ(pipeconf_reg);
+	pipe_bpc = temp & PIPE_BPC_MASK;
 
 	/* XXX: When our outputs are all unaware of DPMS modes other than off
 	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
@@ -1481,10 +1549,19 @@ static void igdng_crtc_dpms(struct drm_c
 	case DRM_MODE_DPMS_ON:
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
-		DRM_DEBUG("crtc %d dpms on\n", pipe);
+		DRM_DEBUG_KMS("crtc %d dpms on\n", pipe);
+
+		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+			temp = I915_READ(PCH_LVDS);
+			if ((temp & LVDS_PORT_EN) == 0) {
+				I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
+				POSTING_READ(PCH_LVDS);
+			}
+		}
+
 		if (HAS_eDP) {
 			/* enable eDP PLL */
-			igdng_enable_pll_edp(crtc);
+			ironlake_enable_pll_edp(crtc);
 		} else {
 			/* enable PCH DPLL */
 			temp = I915_READ(pch_dpll_reg);
@@ -1495,13 +1572,19 @@ static void igdng_crtc_dpms(struct drm_c
 
 			/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
 			temp = I915_READ(fdi_rx_reg);
+			/*
+			 * make the BPC in FDI Rx be consistent with that in
+			 * pipeconf reg.
+			 */
+			temp &= ~(0x7 << 16);
+			temp |= (pipe_bpc << 11);
 			I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE |
 					FDI_SEL_PCDCLK |
 					FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */
 			I915_READ(fdi_rx_reg);
 			udelay(200);
 
-			/* Enable CPU FDI TX PLL, always on for IGDNG */
+			/* Enable CPU FDI TX PLL, always on for Ironlake */
 			temp = I915_READ(fdi_tx_reg);
 			if ((temp & FDI_TX_PLL_ENABLE) == 0) {
 				I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE);
@@ -1568,12 +1651,13 @@ static void igdng_crtc_dpms(struct drm_c
 			udelay(150);
 
 			temp = I915_READ(fdi_rx_iir_reg);
-			DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
 			if ((temp & FDI_RX_BIT_LOCK) == 0) {
 				for (j = 0; j < tries; j++) {
 					temp = I915_READ(fdi_rx_iir_reg);
-					DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+					DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+								temp);
 					if (temp & FDI_RX_BIT_LOCK)
 						break;
 					udelay(200);
@@ -1582,11 +1666,11 @@ static void igdng_crtc_dpms(struct drm_c
 					I915_WRITE(fdi_rx_iir_reg,
 							temp | FDI_RX_BIT_LOCK);
 				else
-					DRM_DEBUG("train 1 fail\n");
+					DRM_DEBUG_KMS("train 1 fail\n");
 			} else {
 				I915_WRITE(fdi_rx_iir_reg,
 						temp | FDI_RX_BIT_LOCK);
-				DRM_DEBUG("train 1 ok 2!\n");
+				DRM_DEBUG_KMS("train 1 ok 2!\n");
 			}
 			temp = I915_READ(fdi_tx_reg);
 			temp &= ~FDI_LINK_TRAIN_NONE;
@@ -1601,12 +1685,13 @@ static void igdng_crtc_dpms(struct drm_c
 			udelay(150);
 
 			temp = I915_READ(fdi_rx_iir_reg);
-			DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+			DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
 
 			if ((temp & FDI_RX_SYMBOL_LOCK) == 0) {
 				for (j = 0; j < tries; j++) {
 					temp = I915_READ(fdi_rx_iir_reg);
-					DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+					DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+								temp);
 					if (temp & FDI_RX_SYMBOL_LOCK)
 						break;
 					udelay(200);
@@ -1614,15 +1699,15 @@ static void igdng_crtc_dpms(struct drm_c
 				if (j != tries) {
 					I915_WRITE(fdi_rx_iir_reg,
 							temp | FDI_RX_SYMBOL_LOCK);
-					DRM_DEBUG("train 2 ok 1!\n");
+					DRM_DEBUG_KMS("train 2 ok 1!\n");
 				} else
-					DRM_DEBUG("train 2 fail\n");
+					DRM_DEBUG_KMS("train 2 fail\n");
 			} else {
 				I915_WRITE(fdi_rx_iir_reg,
 						temp | FDI_RX_SYMBOL_LOCK);
-				DRM_DEBUG("train 2 ok 2!\n");
+				DRM_DEBUG_KMS("train 2 ok 2!\n");
 			}
-			DRM_DEBUG("train done\n");
+			DRM_DEBUG_KMS("train done\n");
 
 			/* set transcoder timing */
 			I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg));
@@ -1635,6 +1720,12 @@ static void igdng_crtc_dpms(struct drm_c
 
 			/* enable PCH transcoder */
 			temp = I915_READ(transconf_reg);
+			/*
+			 * make the BPC in transcoder be consistent with
+			 * that in pipeconf reg.
+			 */
+			temp &= ~PIPE_BPC_MASK;
+			temp |= pipe_bpc;
 			I915_WRITE(transconf_reg, temp | TRANS_ENABLE);
 			I915_READ(transconf_reg);
 
@@ -1664,10 +1755,9 @@ static void igdng_crtc_dpms(struct drm_c
 
 	break;
 	case DRM_MODE_DPMS_OFF:
-		DRM_DEBUG("crtc %d dpms off\n", pipe);
-
-		i915_disable_vga(dev);
+		DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
 
+		drm_vblank_off(dev, pipe);
 		/* Disable display plane */
 		temp = I915_READ(dspcntr_reg);
 		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -1677,6 +1767,8 @@ static void igdng_crtc_dpms(struct drm_c
 			I915_READ(dspbase_reg);
 		}
 
+		i915_disable_vga(dev);
+
 		/* disable cpu pipe, disable after all planes disabled */
 		temp = I915_READ(pipeconf_reg);
 		if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -1690,16 +1782,23 @@ static void igdng_crtc_dpms(struct drm_c
 					udelay(500);
 					continue;
 				} else {
-					DRM_DEBUG("pipe %d off delay\n", pipe);
+					DRM_DEBUG_KMS("pipe %d off delay\n",
+								pipe);
 					break;
 				}
 			}
 		} else
-			DRM_DEBUG("crtc %d is disabled\n", pipe);
+			DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
 
-		if (HAS_eDP) {
-			igdng_disable_pll_edp(crtc);
+		udelay(100);
+
+		/* Disable PF */
+		temp = I915_READ(pf_ctl_reg);
+		if ((temp & PF_ENABLE) != 0) {
+			I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+			I915_READ(pf_ctl_reg);
 		}
+		I915_WRITE(pf_win_size, 0);
 
 		/* disable CPU FDI tx and PCH FDI rx */
 		temp = I915_READ(fdi_tx_reg);
@@ -1707,6 +1806,9 @@ static void igdng_crtc_dpms(struct drm_c
 		I915_READ(fdi_tx_reg);
 
 		temp = I915_READ(fdi_rx_reg);
+		/* BPC in FDI rx is consistent with that in pipeconf */
+		temp &= ~(0x07 << 16);
+		temp |= (pipe_bpc << 11);
 		I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE);
 		I915_READ(fdi_rx_reg);
 
@@ -1725,6 +1827,13 @@ static void igdng_crtc_dpms(struct drm_c
 
 		udelay(100);
 
+		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+			temp = I915_READ(PCH_LVDS);
+			I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
+			I915_READ(PCH_LVDS);
+			udelay(100);
+		}
+
 		/* disable PCH transcoder */
 		temp = I915_READ(transconf_reg);
 		if ((temp & TRANS_ENABLE) != 0) {
@@ -1738,11 +1847,19 @@ static void igdng_crtc_dpms(struct drm_c
 					udelay(500);
 					continue;
 				} else {
-					DRM_DEBUG("transcoder %d off delay\n", pipe);
+					DRM_DEBUG_KMS("transcoder %d off "
+							"delay\n", pipe);
 					break;
 				}
 			}
 		}
+		temp = I915_READ(transconf_reg);
+		/* BPC in transcoder is consistent with that in pipeconf */
+		temp &= ~PIPE_BPC_MASK;
+		temp |= pipe_bpc;
+		I915_WRITE(transconf_reg, temp);
+		I915_READ(transconf_reg);
+		udelay(100);
 
 		/* disable PCH DPLL */
 		temp = I915_READ(pch_dpll_reg);
@@ -1751,14 +1868,20 @@ static void igdng_crtc_dpms(struct drm_c
 			I915_READ(pch_dpll_reg);
 		}
 
-		temp = I915_READ(fdi_rx_reg);
-		if ((temp & FDI_RX_PLL_ENABLE) != 0) {
-			temp &= ~FDI_SEL_PCDCLK;
-			temp &= ~FDI_RX_PLL_ENABLE;
-			I915_WRITE(fdi_rx_reg, temp);
-			I915_READ(fdi_rx_reg);
+		if (HAS_eDP) {
+			ironlake_disable_pll_edp(crtc);
 		}
 
+		temp = I915_READ(fdi_rx_reg);
+		temp &= ~FDI_SEL_PCDCLK;
+		I915_WRITE(fdi_rx_reg, temp);
+		I915_READ(fdi_rx_reg);
+
+		temp = I915_READ(fdi_rx_reg);
+		temp &= ~FDI_RX_PLL_ENABLE;
+		I915_WRITE(fdi_rx_reg, temp);
+		I915_READ(fdi_rx_reg);
+
 		/* Disable CPU FDI TX PLL */
 		temp = I915_READ(fdi_tx_reg);
 		if ((temp & FDI_TX_PLL_ENABLE) != 0) {
@@ -1767,20 +1890,43 @@ static void igdng_crtc_dpms(struct drm_c
 			udelay(100);
 		}
 
-		/* Disable PF */
-		temp = I915_READ(pf_ctl_reg);
-		if ((temp & PF_ENABLE) != 0) {
-			I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
-			I915_READ(pf_ctl_reg);
-		}
-		I915_WRITE(pf_win_size, 0);
-
 		/* Wait for the clocks to turn off. */
-		udelay(150);
+		udelay(100);
 		break;
 	}
 }
 
+static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
+{
+	struct intel_overlay *overlay;
+	int ret;
+
+	if (!enable && intel_crtc->overlay) {
+		overlay = intel_crtc->overlay;
+		mutex_lock(&overlay->dev->struct_mutex);
+		for (;;) {
+			ret = intel_overlay_switch_off(overlay);
+			if (ret == 0)
+				break;
+
+			ret = intel_overlay_recover_from_interrupt(overlay, 0);
+			if (ret != 0) {
+				/* overlay doesn't react anymore. Usually
+				 * results in a black screen and an unkillable
+				 * X server. */
+				BUG();
+				overlay->hw_wedged = HW_WEDGED;
+				break;
+			}
+		}
+		mutex_unlock(&overlay->dev->struct_mutex);
+	}
+	/* Let userspace switch the overlay on again. In most cases userspace
+	 * has to recompute where to put it anyway. */
+
+	return;
+}
+
 static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
 	struct drm_device *dev = crtc->dev;
@@ -1839,12 +1985,14 @@ static void i9xx_crtc_dpms(struct drm_cr
 			intel_update_fbc(crtc, &crtc->mode);
 
 		/* Give the overlay scaler a chance to enable if it's on this pipe */
-		//intel_crtc_dpms_video(crtc, true); TODO
+		intel_crtc_dpms_overlay(intel_crtc, true);
 	break;
 	case DRM_MODE_DPMS_OFF:
 		intel_update_watermarks(dev);
+
 		/* Give the overlay scaler a chance to disable if it's on this pipe */
-		//intel_crtc_dpms_video(crtc, FALSE); TODO
+		intel_crtc_dpms_overlay(intel_crtc, false);
+		drm_vblank_off(dev, pipe);
 
 		if (dev_priv->cfb_plane == plane &&
 		    dev_priv->display.disable_fbc)
@@ -1963,7 +2111,7 @@ static bool intel_crtc_mode_fixup(struct
 				  struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = crtc->dev;
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		/* FDI link clock is fixed at 2.7G */
 		if (mode->clock * 3 > 27000 * 4)
 			return MODE_CLOCK_HIGH;
@@ -2039,7 +2187,7 @@ static int i830_get_display_clock_speed(
  * Return the pipe currently connected to the panel fitter,
  * or -1 if the panel fitter is not present or not in use
  */
-static int intel_panel_fitter_pipe (struct drm_device *dev)
+int intel_panel_fitter_pipe (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32  pfit_control;
@@ -2083,9 +2231,8 @@ fdi_reduce_ratio(u32 *num, u32 *den)
 #define LINK_N 0x80000
 
 static void
-igdng_compute_m_n(int bits_per_pixel, int nlanes,
-		int pixel_clock, int link_clock,
-		struct fdi_m_n *m_n)
+ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
+		     int link_clock, struct fdi_m_n *m_n)
 {
 	u64 temp;
 
@@ -2113,34 +2260,34 @@ struct intel_watermark_params {
 	unsigned long cacheline_size;
 };
 
-/* IGD has different values for various configs */
-static struct intel_watermark_params igd_display_wm = {
-	IGD_DISPLAY_FIFO,
-	IGD_MAX_WM,
-	IGD_DFT_WM,
-	IGD_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+/* Pineview has different values for various configs */
+static struct intel_watermark_params pineview_display_wm = {
+	PINEVIEW_DISPLAY_FIFO,
+	PINEVIEW_MAX_WM,
+	PINEVIEW_DFT_WM,
+	PINEVIEW_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
-static struct intel_watermark_params igd_display_hplloff_wm = {
-	IGD_DISPLAY_FIFO,
-	IGD_MAX_WM,
-	IGD_DFT_HPLLOFF_WM,
-	IGD_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+static struct intel_watermark_params pineview_display_hplloff_wm = {
+	PINEVIEW_DISPLAY_FIFO,
+	PINEVIEW_MAX_WM,
+	PINEVIEW_DFT_HPLLOFF_WM,
+	PINEVIEW_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
-static struct intel_watermark_params igd_cursor_wm = {
-	IGD_CURSOR_FIFO,
-	IGD_CURSOR_MAX_WM,
-	IGD_CURSOR_DFT_WM,
-	IGD_CURSOR_GUARD_WM,
-	IGD_FIFO_LINE_SIZE,
+static struct intel_watermark_params pineview_cursor_wm = {
+	PINEVIEW_CURSOR_FIFO,
+	PINEVIEW_CURSOR_MAX_WM,
+	PINEVIEW_CURSOR_DFT_WM,
+	PINEVIEW_CURSOR_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE,
 };
-static struct intel_watermark_params igd_cursor_hplloff_wm = {
-	IGD_CURSOR_FIFO,
-	IGD_CURSOR_MAX_WM,
-	IGD_CURSOR_DFT_WM,
-	IGD_CURSOR_GUARD_WM,
-	IGD_FIFO_LINE_SIZE
+static struct intel_watermark_params pineview_cursor_hplloff_wm = {
+	PINEVIEW_CURSOR_FIFO,
+	PINEVIEW_CURSOR_MAX_WM,
+	PINEVIEW_CURSOR_DFT_WM,
+	PINEVIEW_CURSOR_GUARD_WM,
+	PINEVIEW_FIFO_LINE_SIZE
 };
 static struct intel_watermark_params g4x_wm_info = {
 	G4X_FIFO_SIZE,
@@ -2213,11 +2360,11 @@ static unsigned long intel_calculate_wm(
 		1000;
 	entries_required /= wm->cacheline_size;
 
-	DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
+	DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
 
 	wm_size = wm->fifo_size - (entries_required + wm->guard_size);
 
-	DRM_DEBUG("FIFO watermark level: %d\n", wm_size);
+	DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size);
 
 	/* Don't promote wm_size to unsigned... */
 	if (wm_size > (long)wm->max_wm)
@@ -2279,50 +2426,50 @@ static struct cxsr_latency *intel_get_cx
 			return latency;
 	}
 
-	DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
+	DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
 
 	return NULL;
 }
 
-static void igd_disable_cxsr(struct drm_device *dev)
+static void pineview_disable_cxsr(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
 	/* deactivate cxsr */
 	reg = I915_READ(DSPFW3);
-	reg &= ~(IGD_SELF_REFRESH_EN);
+	reg &= ~(PINEVIEW_SELF_REFRESH_EN);
 	I915_WRITE(DSPFW3, reg);
 	DRM_INFO("Big FIFO is disabled\n");
 }
 
-static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
-			    int pixel_size)
+static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock,
+				 int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 	unsigned long wm;
 	struct cxsr_latency *latency;
 
-	latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
+	latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq,
 		dev_priv->mem_freq);
 	if (!latency) {
-		DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
-		igd_disable_cxsr(dev);
+		DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+		pineview_disable_cxsr(dev);
 		return;
 	}
 
 	/* Display SR */
-	wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_display_wm, pixel_size,
 				latency->display_sr);
 	reg = I915_READ(DSPFW1);
 	reg &= 0x7fffff;
 	reg |= wm << 23;
 	I915_WRITE(DSPFW1, reg);
-	DRM_DEBUG("DSPFW1 register is %x\n", reg);
+	DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
 
 	/* cursor SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_cursor_wm, pixel_size,
 				latency->cursor_sr);
 	reg = I915_READ(DSPFW3);
 	reg &= ~(0x3f << 24);
@@ -2330,7 +2477,7 @@ static void igd_enable_cxsr(struct drm_d
 	I915_WRITE(DSPFW3, reg);
 
 	/* Display HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_display_hplloff_wm,
+	wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm,
 		latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
 	reg = I915_READ(DSPFW3);
 	reg &= 0xfffffe00;
@@ -2338,17 +2485,17 @@ static void igd_enable_cxsr(struct drm_d
 	I915_WRITE(DSPFW3, reg);
 
 	/* cursor HPLL off SR */
-	wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size,
+	wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, pixel_size,
 				latency->cursor_hpll_disable);
 	reg = I915_READ(DSPFW3);
 	reg &= ~(0x3f << 16);
 	reg |= (wm & 0x3f) << 16;
 	I915_WRITE(DSPFW3, reg);
-	DRM_DEBUG("DSPFW3 register is %x\n", reg);
+	DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
 
 	/* activate cxsr */
 	reg = I915_READ(DSPFW3);
-	reg |= IGD_SELF_REFRESH_EN;
+	reg |= PINEVIEW_SELF_REFRESH_EN;
 	I915_WRITE(DSPFW3, reg);
 
 	DRM_INFO("Big FIFO is enabled\n");
@@ -2370,7 +2517,7 @@ static void igd_enable_cxsr(struct drm_d
  * A value of 5us seems to be a good balance; safe for very low end
  * platforms but not overly aggressive on lower latency configs.
  */
-const static int latency_ns = 5000;
+static const int latency_ns = 5000;
 
 static int i9xx_get_fifo_size(struct drm_device *dev, int plane)
 {
@@ -2384,8 +2531,8 @@ static int i9xx_get_fifo_size(struct drm
 		size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
 			(dsparb & 0x7f);
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2403,8 +2550,8 @@ static int i85x_get_fifo_size(struct drm
 			(dsparb & 0x1ff);
 	size >>= 1; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2418,7 +2565,8 @@ static int i845_get_fifo_size(struct drm
 	size = dsparb & 0x7f;
 	size >>= 2; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A",
 		  size);
 
 	return size;
@@ -2433,8 +2581,8 @@ static int i830_get_fifo_size(struct drm
 	size = dsparb & 0x7f;
 	size >>= 1; /* Convert to cachelines */
 
-	DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
-		  size);
+	DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+			plane ? "B" : "A", size);
 
 	return size;
 }
@@ -2480,7 +2628,7 @@ static void g4x_update_wm(struct drm_dev
 	/* Calc sr entries for one plane configs */
 	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
 		/* self-refresh has much higher latency */
-		const static int sr_latency_ns = 12000;
+		static const int sr_latency_ns = 12000;
 
 		sr_clock = planea_clock ? planea_clock : planeb_clock;
 		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
@@ -2491,6 +2639,10 @@ static void g4x_update_wm(struct drm_dev
 		sr_entries = roundup(sr_entries / cacheline_size, 1);
 		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
 		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+	} else {
+		/* Turn off self refresh if both pipes are enabled */
+		I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+					& ~FW_BLC_SELF_EN);
 	}
 
 	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
@@ -2509,15 +2661,43 @@ static void g4x_update_wm(struct drm_dev
 		   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
 }
 
-static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
-			   int unused3, int unused4)
+static void i965_update_wm(struct drm_device *dev, int planea_clock,
+			   int planeb_clock, int sr_hdisplay, int pixel_size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long line_time_us;
+	int sr_clock, sr_entries, srwm = 1;
 
-	DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n");
+	/* Calc sr entries for one plane configs */
+	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+		/* self-refresh has much higher latency */
+		static const int sr_latency_ns = 12000;
+
+		sr_clock = planea_clock ? planea_clock : planeb_clock;
+		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+
+		/* Use ns/us then divide to preserve precision */
+		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
+			      pixel_size * sr_hdisplay) / 1000;
+		sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
+		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+		srwm = I945_FIFO_SIZE - sr_entries;
+		if (srwm < 0)
+			srwm = 1;
+		srwm &= 0x3f;
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+	} else {
+		/* Turn off self refresh if both pipes are enabled */
+		I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+					& ~FW_BLC_SELF_EN);
+	}
+
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
+		      srwm);
 
 	/* 965 has limitations... */
-	I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0));
+	I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
+		   (8 << 0));
 	I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
 }
 
@@ -2553,7 +2733,7 @@ static void i9xx_update_wm(struct drm_de
 				       pixel_size, latency_ns);
 	planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
 				       pixel_size, latency_ns);
-	DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
 	/*
 	 * Overlay gets an aggressive default since video jitter is bad.
@@ -2564,7 +2744,7 @@ static void i9xx_update_wm(struct drm_de
 	if (HAS_FW_BLC(dev) && sr_hdisplay &&
 	    (!planea_clock || !planeb_clock)) {
 		/* self-refresh has much higher latency */
-		const static int sr_latency_ns = 6000;
+		static const int sr_latency_ns = 6000;
 
 		sr_clock = planea_clock ? planea_clock : planeb_clock;
 		line_time_us = ((sr_hdisplay * 1000) / sr_clock);
@@ -2573,14 +2753,18 @@ static void i9xx_update_wm(struct drm_de
 		sr_entries = (((sr_latency_ns / line_time_us) + 1) *
 			      pixel_size * sr_hdisplay) / 1000;
 		sr_entries = roundup(sr_entries / cacheline_size, 1);
-		DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+		DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries);
 		srwm = total_size - sr_entries;
 		if (srwm < 0)
 			srwm = 1;
 		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
+	} else {
+		/* Turn off self refresh if both pipes are enabled */
+		I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+					& ~FW_BLC_SELF_EN);
 	}
 
-	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
 		  planea_wm, planeb_wm, cwm, srwm);
 
 	fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
@@ -2607,7 +2791,7 @@ static void i830_update_wm(struct drm_de
 				       pixel_size, latency_ns);
 	fwater_lo |= (3<<8) | planea_wm;
 
-	DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm);
+	DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);
 
 	I915_WRITE(FW_BLC, fwater_lo);
 }
@@ -2661,11 +2845,11 @@ static void intel_update_watermarks(stru
 		if (crtc->enabled) {
 			enabled++;
 			if (intel_crtc->plane == 0) {
-				DRM_DEBUG("plane A (pipe %d) clock: %d\n",
+				DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
 				planea_clock = crtc->mode.clock;
 			} else {
-				DRM_DEBUG("plane B (pipe %d) clock: %d\n",
+				DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n",
 					  intel_crtc->pipe, crtc->mode.clock);
 				planeb_clock = crtc->mode.clock;
 			}
@@ -2682,10 +2866,10 @@ static void intel_update_watermarks(stru
 		return;
 
 	/* Single plane configs can enable self refresh */
-	if (enabled == 1 && IS_IGD(dev))
-		igd_enable_cxsr(dev, sr_clock, pixel_size);
-	else if (IS_IGD(dev))
-		igd_disable_cxsr(dev);
+	if (enabled == 1 && IS_PINEVIEW(dev))
+		pineview_enable_cxsr(dev, sr_clock, pixel_size);
+	else if (IS_PINEVIEW(dev))
+		pineview_disable_cxsr(dev);
 
 	dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
 				    sr_hdisplay, pixel_size);
@@ -2779,10 +2963,11 @@ static int intel_crtc_mode_set(struct dr
 
 	if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
 		refclk = dev_priv->lvds_ssc_freq * 1000;
-		DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
+					refclk / 1000);
 	} else if (IS_I9XX(dev)) {
 		refclk = 96000;
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			refclk = 120000; /* 120Mhz refclk */
 	} else {
 		refclk = 48000;
@@ -2802,14 +2987,23 @@ static int intel_crtc_mode_set(struct dr
 		return -EINVAL;
 	}
 
-	if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
-		memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
-		has_reduced_clock = limit->find_reduced_pll(limit, crtc,
-							    (adjusted_mode->clock*3/4),
+	if (is_lvds && dev_priv->lvds_downclock_avail) {
+		has_reduced_clock = limit->find_pll(limit, crtc,
+							    dev_priv->lvds_downclock,
 							    refclk,
 							    &reduced_clock);
+		if (has_reduced_clock && (clock.p != reduced_clock.p)) {
+			/*
+			 * If the different P is found, it means that we can't
+			 * switch the display clock by using the FP0/FP1.
+			 * In such case we will disable the LVDS downclock
+			 * feature.
+			 */
+			DRM_DEBUG_KMS("Different P is found for "
+						"LVDS clock/downclock\n");
+			has_reduced_clock = 0;
+		}
 	}
-
 	/* SDVO TV has fixed PLL values depend on its clock range,
 	   this mirrors vbios setting. */
 	if (is_sdvo && is_tv) {
@@ -2831,7 +3025,7 @@ static int intel_crtc_mode_set(struct dr
 	}
 
 	/* FDI link */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		int lane, link_bw, bpp;
 		/* eDP doesn't require FDI link, so just set DP M/N
 		   according to current link config */
@@ -2854,6 +3048,33 @@ static int intel_crtc_mode_set(struct dr
 
 		/* determine panel color depth */
 		temp = I915_READ(pipeconf_reg);
+		temp &= ~PIPE_BPC_MASK;
+		if (is_lvds) {
+			int lvds_reg = I915_READ(PCH_LVDS);
+			/* the BPC will be 6 if it is 18-bit LVDS panel */
+			if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
+				temp |= PIPE_8BPC;
+			else
+				temp |= PIPE_6BPC;
+		} else if (is_edp) {
+			switch (dev_priv->edp_bpp/3) {
+			case 8:
+				temp |= PIPE_8BPC;
+				break;
+			case 10:
+				temp |= PIPE_10BPC;
+				break;
+			case 6:
+				temp |= PIPE_6BPC;
+				break;
+			case 12:
+				temp |= PIPE_12BPC;
+				break;
+			}
+		} else
+			temp |= PIPE_8BPC;
+		I915_WRITE(pipeconf_reg, temp);
+		I915_READ(pipeconf_reg);
 
 		switch (temp & PIPE_BPC_MASK) {
 		case PIPE_8BPC:
@@ -2873,8 +3094,7 @@ static int intel_crtc_mode_set(struct dr
 			bpp = 24;
 		}
 
-		igdng_compute_m_n(bpp, lane, target_clock,
-				  link_bw, &m_n);
+		ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
 	}
 
 	/* Ironlake: try to setup display ref clock before DPLL
@@ -2882,7 +3102,7 @@ static int intel_crtc_mode_set(struct dr
 	 * PCH B stepping, previous chipset stepping should be
 	 * ignoring this setting.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		temp = I915_READ(PCH_DREF_CONTROL);
 		/* Always enable nonspread source */
 		temp &= ~DREF_NONSPREAD_SOURCE_MASK;
@@ -2917,7 +3137,7 @@ static int intel_crtc_mode_set(struct dr
 		}
 	}
 
-	if (IS_IGD(dev)) {
+	if (IS_PINEVIEW(dev)) {
 		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
 		if (has_reduced_clock)
 			fp2 = (1 << reduced_clock.n) << 16 |
@@ -2929,7 +3149,7 @@ static int intel_crtc_mode_set(struct dr
 				reduced_clock.m2;
 	}
 
-	if (!IS_IGDNG(dev))
+	if (!IS_IRONLAKE(dev))
 		dpll = DPLL_VGA_MODE_DIS;
 
 	if (IS_I9XX(dev)) {
@@ -2942,19 +3162,19 @@ static int intel_crtc_mode_set(struct dr
 			sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 			if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-			else if (IS_IGDNG(dev))
+			else if (IS_IRONLAKE(dev))
 				dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
 		}
 		if (is_dp)
 			dpll |= DPLL_DVO_HIGH_SPEED;
 
 		/* compute bitmask from p1 value */
-		if (IS_IGD(dev))
-			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+		if (IS_PINEVIEW(dev))
+			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
 		else {
 			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 			/* also FPA1 */
-			if (IS_IGDNG(dev))
+			if (IS_IRONLAKE(dev))
 				dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 			if (IS_G4X(dev) && has_reduced_clock)
 				dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
@@ -2973,7 +3193,7 @@ static int intel_crtc_mode_set(struct dr
 			dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 			break;
 		}
-		if (IS_I965G(dev) && !IS_IGDNG(dev))
+		if (IS_I965G(dev) && !IS_IRONLAKE(dev))
 			dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 	} else {
 		if (is_lvds) {
@@ -3005,9 +3225,9 @@ static int intel_crtc_mode_set(struct dr
 	/* Set up the display plane register */
 	dspcntr = DISPPLANE_GAMMA_ENABLE;
 
-	/* IGDNG's plane is forced to pipe, bit 24 is to
+	/* Ironlake's plane is forced to pipe, bit 24 is to
 	   enable color space conversion */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		if (pipe == 0)
 			dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
 		else
@@ -3034,20 +3254,20 @@ static int intel_crtc_mode_set(struct dr
 
 
 	/* Disable the panel fitter if it was on our pipe */
-	if (!IS_IGDNG(dev) && intel_panel_fitter_pipe(dev) == pipe)
+	if (!IS_IRONLAKE(dev) && intel_panel_fitter_pipe(dev) == pipe)
 		I915_WRITE(PFIT_CONTROL, 0);
 
-	DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
+	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 	drm_mode_debug_printmodeline(mode);
 
-	/* assign to IGDNG registers */
-	if (IS_IGDNG(dev)) {
+	/* assign to Ironlake registers */
+	if (IS_IRONLAKE(dev)) {
 		fp_reg = pch_fp_reg;
 		dpll_reg = pch_dpll_reg;
 	}
 
 	if (is_edp) {
-		igdng_disable_pll_edp(crtc);
+		ironlake_disable_pll_edp(crtc);
 	} else if ((dpll & DPLL_VCO_ENABLE)) {
 		I915_WRITE(fp_reg, fp);
 		I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
@@ -3062,7 +3282,7 @@ static int intel_crtc_mode_set(struct dr
 	if (is_lvds) {
 		u32 lvds;
 
-		if (IS_IGDNG(dev))
+		if (IS_IRONLAKE(dev))
 			lvds_reg = PCH_LVDS;
 
 		lvds = I915_READ(lvds_reg);
@@ -3081,7 +3301,20 @@ static int intel_crtc_mode_set(struct dr
 		 * appropriately here, but we need to look more thoroughly into how
 		 * panels behave in the two modes.
 		 */
-
+		/* set the dithering flag */
+		if (IS_I965G(dev)) {
+			if (dev_priv->lvds_dither) {
+				if (IS_IRONLAKE(dev))
+					pipeconf |= PIPE_ENABLE_DITHER;
+				else
+					lvds |= LVDS_ENABLE_DITHER;
+			} else {
+				if (IS_IRONLAKE(dev))
+					pipeconf &= ~PIPE_ENABLE_DITHER;
+				else
+					lvds &= ~LVDS_ENABLE_DITHER;
+			}
+		}
 		I915_WRITE(lvds_reg, lvds);
 		I915_READ(lvds_reg);
 	}
@@ -3095,7 +3328,7 @@ static int intel_crtc_mode_set(struct dr
 		/* Wait for the clocks to stabilize. */
 		udelay(150);
 
-		if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+		if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
 			if (is_sdvo) {
 				sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 				I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
@@ -3115,14 +3348,14 @@ static int intel_crtc_mode_set(struct dr
 		I915_WRITE(fp_reg + 4, fp2);
 		intel_crtc->lowfreq_avail = true;
 		if (HAS_PIPE_CXSR(dev)) {
-			DRM_DEBUG("enabling CxSR downclocking\n");
+			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
 			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
 		}
 	} else {
 		I915_WRITE(fp_reg + 4, fp);
 		intel_crtc->lowfreq_avail = false;
 		if (HAS_PIPE_CXSR(dev)) {
-			DRM_DEBUG("disabling CxSR downclocking\n");
+			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
 			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
 		}
 	}
@@ -3142,21 +3375,21 @@ static int intel_crtc_mode_set(struct dr
 	/* pipesrc and dspsize control the size that is scaled from, which should
 	 * always be the user's requested size.
 	 */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) |
 				(mode->hdisplay - 1));
 		I915_WRITE(dsppos_reg, 0);
 	}
 	I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m);
 		I915_WRITE(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n);
 		I915_WRITE(link_m1_reg, m_n.link_m);
 		I915_WRITE(link_n1_reg, m_n.link_n);
 
 		if (is_edp) {
-			igdng_set_pll_edp(crtc, adjusted_mode->clock);
+			ironlake_set_pll_edp(crtc, adjusted_mode->clock);
 		} else {
 			/* enable FDI RX PLL too */
 			temp = I915_READ(fdi_rx_reg);
@@ -3170,7 +3403,7 @@ static int intel_crtc_mode_set(struct dr
 
 	intel_wait_for_vblank(dev);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		/* enable address swizzle for tiling buffer */
 		temp = I915_READ(DISP_ARB_CTL);
 		I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
@@ -3204,8 +3437,8 @@ void intel_crtc_load_lut(struct drm_crtc
 	if (!crtc->enabled)
 		return;
 
-	/* use legacy palette for IGDNG */
-	if (IS_IGDNG(dev))
+	/* use legacy palette for Ironlake */
+	if (IS_IRONLAKE(dev))
 		palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A :
 						   LGC_PALETTE_B;
 
@@ -3234,11 +3467,11 @@ static int intel_crtc_cursor_set(struct
 	size_t addr;
 	int ret;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	/* if we want to turn off the cursor ignore width and height */
 	if (!handle) {
-		DRM_DEBUG("cursor off\n");
+		DRM_DEBUG_KMS("cursor off\n");
 		if (IS_MOBILE(dev) || IS_I9XX(dev)) {
 			temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
 			temp |= CURSOR_MODE_DISABLE;
@@ -3271,7 +3504,7 @@ static int intel_crtc_cursor_set(struct
 
 	/* we only need to pin inside GTT if cursor is non-phy */
 	mutex_lock(&dev->struct_mutex);
-	if (!dev_priv->cursor_needs_physical) {
+	if (!dev_priv->info->cursor_needs_physical) {
 		ret = i915_gem_object_pin(bo, PAGE_SIZE);
 		if (ret) {
 			DRM_ERROR("failed to pin cursor bo\n");
@@ -3306,7 +3539,7 @@ static int intel_crtc_cursor_set(struct
 	I915_WRITE(base, addr);
 
 	if (intel_crtc->cursor_bo) {
-		if (dev_priv->cursor_needs_physical) {
+		if (dev_priv->info->cursor_needs_physical) {
 			if (intel_crtc->cursor_bo != bo)
 				i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
 		} else
@@ -3546,18 +3779,18 @@ static int intel_crtc_clock_get(struct d
 		fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
 
 	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-	if (IS_IGD(dev)) {
-		clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
-		clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+	if (IS_PINEVIEW(dev)) {
+		clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+		clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
 	} else {
 		clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
 		clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
 	}
 
 	if (IS_I9XX(dev)) {
-		if (IS_IGD(dev))
-			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
-				DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+		if (IS_PINEVIEW(dev))
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
+				DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
 		else
 			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
 			       DPLL_FPA01_P1_POST_DIV_SHIFT);
@@ -3572,7 +3805,7 @@ static int intel_crtc_clock_get(struct d
 				7 : 14;
 			break;
 		default:
-			DRM_DEBUG("Unknown DPLL mode %08x in programmed "
+			DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
 				  "mode\n", (int)(dpll & DPLL_MODE_MASK));
 			return 0;
 		}
@@ -3658,132 +3891,13 @@ static void intel_gpu_idle_timer(unsigne
 	struct drm_device *dev = (struct drm_device *)arg;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
-	DRM_DEBUG("idle timer fired, downclocking\n");
+	DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
 
 	dev_priv->busy = false;
 
 	queue_work(dev_priv->wq, &dev_priv->idle_work);
 }
 
-void intel_increase_renderclock(struct drm_device *dev, bool schedule)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	if (IS_IGDNG(dev))
-		return;
-
-	if (!dev_priv->render_reclock_avail) {
-		DRM_DEBUG("not reclocking render clock\n");
-		return;
-	}
-
-	/* Restore render clock frequency to original value */
-	if (IS_G4X(dev) || IS_I9XX(dev))
-		pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
-	else if (IS_I85X(dev))
-		pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
-	DRM_DEBUG("increasing render clock frequency\n");
-
-	/* Schedule downclock */
-	if (schedule)
-		mod_timer(&dev_priv->idle_timer, jiffies +
-			  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
-}
-
-void intel_decrease_renderclock(struct drm_device *dev)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	if (IS_IGDNG(dev))
-		return;
-
-	if (!dev_priv->render_reclock_avail) {
-		DRM_DEBUG("not reclocking render clock\n");
-		return;
-	}
-
-	if (IS_G4X(dev)) {
-		u16 gcfgc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
-
-		/* Down to minimum... */
-		gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
-		gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
-
-		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
-	} else if (IS_I965G(dev)) {
-		u16 gcfgc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
-
-		/* Down to minimum... */
-		gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
-		gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
-
-		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
-	} else if (IS_I945G(dev) || IS_I945GM(dev)) {
-		u16 gcfgc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
-
-		/* Down to minimum... */
-		gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
-		gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
-
-		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
-	} else if (IS_I915G(dev)) {
-		u16 gcfgc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
-
-		/* Down to minimum... */
-		gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
-		gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
-
-		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
-	} else if (IS_I85X(dev)) {
-		u16 hpllcc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
-
-		/* Up to maximum... */
-		hpllcc &= ~GC_CLOCK_CONTROL_MASK;
-		hpllcc |= GC_CLOCK_133_200;
-
-		pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
-	}
-	DRM_DEBUG("decreasing render clock frequency\n");
-}
-
-/* Note that no increase function is needed for this - increase_renderclock()
- *  will also rewrite these bits
- */
-void intel_decrease_displayclock(struct drm_device *dev)
-{
-	if (IS_IGDNG(dev))
-		return;
-
-	if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
-	    IS_I915GM(dev)) {
-		u16 gcfgc;
-
-		/* Adjust render clock... */
-		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
-
-		/* Down to minimum... */
-		gcfgc &= ~0xf0;
-		gcfgc |= 0x80;
-
-		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
-	}
-}
-
 #define CRTC_IDLE_TIMEOUT 1000 /* ms */
 
 static void intel_crtc_idle_timer(unsigned long arg)
@@ -3792,7 +3906,7 @@ static void intel_crtc_idle_timer(unsign
 	struct drm_crtc *crtc = &intel_crtc->base;
 	drm_i915_private_t *dev_priv = crtc->dev->dev_private;
 
-	DRM_DEBUG("idle timer fired, downclocking\n");
+	DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
 
 	intel_crtc->busy = false;
 
@@ -3808,14 +3922,14 @@ static void intel_increase_pllclock(stru
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
 		return;
 
 	if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
-		DRM_DEBUG("upclocking LVDS\n");
+		DRM_DEBUG_DRIVER("upclocking LVDS\n");
 
 		/* Unlock panel regs */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
@@ -3826,7 +3940,7 @@ static void intel_increase_pllclock(stru
 		intel_wait_for_vblank(dev);
 		dpll = I915_READ(dpll_reg);
 		if (dpll & DISPLAY_RATE_SELECT_FPA1)
-			DRM_DEBUG("failed to upclock LVDS!\n");
+			DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
 
 		/* ...and lock them again */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
@@ -3847,7 +3961,7 @@ static void intel_decrease_pllclock(stru
 	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 	int dpll = I915_READ(dpll_reg);
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	if (!dev_priv->lvds_downclock_avail)
@@ -3858,7 +3972,7 @@ static void intel_decrease_pllclock(stru
 	 * the manual case.
 	 */
 	if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
-		DRM_DEBUG("downclocking LVDS\n");
+		DRM_DEBUG_DRIVER("downclocking LVDS\n");
 
 		/* Unlock panel regs */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
@@ -3869,7 +3983,7 @@ static void intel_decrease_pllclock(stru
 		intel_wait_for_vblank(dev);
 		dpll = I915_READ(dpll_reg);
 		if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
-			DRM_DEBUG("failed to downclock LVDS!\n");
+			DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
 
 		/* ...and lock them again */
 		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
@@ -3897,12 +4011,6 @@ static void intel_idle_update(struct wor
 
 	mutex_lock(&dev->struct_mutex);
 
-	/* GPU isn't processing, downclock it. */
-	if (!dev_priv->busy) {
-		intel_decrease_renderclock(dev);
-		intel_decrease_displayclock(dev);
-	}
-
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		/* Skip inactive CRTCs */
 		if (!crtc->fb)
@@ -3936,8 +4044,11 @@ void intel_mark_busy(struct drm_device *
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return;
 
-	dev_priv->busy = true;
-	intel_increase_renderclock(dev, true);
+	if (!dev_priv->busy)
+		dev_priv->busy = true;
+	else
+		mod_timer(&dev_priv->idle_timer, jiffies +
+			  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		if (!crtc->fb)
@@ -3967,6 +4078,180 @@ static void intel_crtc_destroy(struct dr
 	kfree(intel_crtc);
 }
 
+struct intel_unpin_work {
+	struct work_struct work;
+	struct drm_device *dev;
+	struct drm_gem_object *old_fb_obj;
+	struct drm_gem_object *pending_flip_obj;
+	struct drm_pending_vblank_event *event;
+	int pending;
+};
+
+static void intel_unpin_work_fn(struct work_struct *__work)
+{
+	struct intel_unpin_work *work =
+		container_of(__work, struct intel_unpin_work, work);
+
+	mutex_lock(&work->dev->struct_mutex);
+	i915_gem_object_unpin(work->old_fb_obj);
+	drm_gem_object_unreference(work->pending_flip_obj);
+	drm_gem_object_unreference(work->old_fb_obj);
+	mutex_unlock(&work->dev->struct_mutex);
+	kfree(work);
+}
+
+void intel_finish_page_flip(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *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);
+	struct intel_unpin_work *work;
+	struct drm_i915_gem_object *obj_priv;
+	struct drm_pending_vblank_event *e;
+	struct timeval now;
+	unsigned long flags;
+
+	/* Ignore early vblank irqs */
+	if (intel_crtc == NULL)
+		return;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	work = intel_crtc->unpin_work;
+	if (work == NULL || !work->pending) {
+		if (work && !work->pending) {
+			obj_priv = work->pending_flip_obj->driver_private;
+			DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
+					 obj_priv,
+					 atomic_read(&obj_priv->pending_flip));
+		}
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		return;
+	}
+
+	intel_crtc->unpin_work = NULL;
+	drm_vblank_put(dev, intel_crtc->pipe);
+
+	if (work->event) {
+		e = work->event;
+		do_gettimeofday(&now);
+		e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe);
+		e->event.tv_sec = now.tv_sec;
+		e->event.tv_usec = now.tv_usec;
+		list_add_tail(&e->base.link,
+			      &e->base.file_priv->event_list);
+		wake_up_interruptible(&e->base.file_priv->event_wait);
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	obj_priv = work->pending_flip_obj->driver_private;
+
+	/* Initial scanout buffer will have a 0 pending flip count */
+	if ((atomic_read(&obj_priv->pending_flip) == 0) ||
+	    atomic_dec_and_test(&obj_priv->pending_flip))
+		DRM_WAKEUP(&dev_priv->pending_flip_queue);
+	schedule_work(&work->work);
+}
+
+void intel_prepare_page_flip(struct drm_device *dev, int plane)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (intel_crtc->unpin_work) {
+		intel_crtc->unpin_work->pending = 1;
+	} else {
+		DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static int intel_crtc_page_flip(struct drm_crtc *crtc,
+				struct drm_framebuffer *fb,
+				struct drm_pending_vblank_event *event)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj_priv;
+	struct drm_gem_object *obj;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_unpin_work *work;
+	unsigned long flags;
+	int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
+	int ret, pipesrc;
+	RING_LOCALS;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (work == NULL)
+		return -ENOMEM;
+
+	mutex_lock(&dev->struct_mutex);
+
+	work->event = event;
+	work->dev = crtc->dev;
+	intel_fb = to_intel_framebuffer(crtc->fb);
+	work->old_fb_obj = intel_fb->obj;
+	INIT_WORK(&work->work, intel_unpin_work_fn);
+
+	/* We borrow the event spin lock for protecting unpin_work */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (intel_crtc->unpin_work) {
+		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		kfree(work);
+		mutex_unlock(&dev->struct_mutex);
+		return -EBUSY;
+	}
+	intel_crtc->unpin_work = work;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj);
+	if (ret != 0) {
+		DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
+			  obj->driver_private);
+		kfree(work);
+		intel_crtc->unpin_work = NULL;
+		mutex_unlock(&dev->struct_mutex);
+		return ret;
+	}
+
+	/* Reference the objects for the scheduled work. */
+	drm_gem_object_reference(work->old_fb_obj);
+	drm_gem_object_reference(obj);
+
+	crtc->fb = fb;
+	i915_gem_object_flush_write_domain(obj);
+	drm_vblank_get(dev, intel_crtc->pipe);
+	obj_priv = obj->driver_private;
+	atomic_inc(&obj_priv->pending_flip);
+	work->pending_flip_obj = obj;
+
+	BEGIN_LP_RING(4);
+	OUT_RING(MI_DISPLAY_FLIP |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch);
+	if (IS_I965G(dev)) {
+		OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
+		pipesrc = I915_READ(pipesrc_reg); 
+		OUT_RING(pipesrc & 0x0fff0fff);
+	} else {
+		OUT_RING(obj_priv->gtt_offset);
+		OUT_RING(MI_NOOP);
+	}
+	ADVANCE_LP_RING();
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
 static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.dpms = intel_crtc_dpms,
 	.mode_fixup = intel_crtc_mode_fixup,
@@ -3983,11 +4268,13 @@ static const struct drm_crtc_funcs intel
 	.gamma_set = intel_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = intel_crtc_destroy,
+	.page_flip = intel_crtc_page_flip,
 };
 
 
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
+	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc;
 	int i;
 
@@ -4010,10 +4297,15 @@ static void intel_crtc_init(struct drm_d
 	intel_crtc->pipe = pipe;
 	intel_crtc->plane = pipe;
 	if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) {
-		DRM_DEBUG("swapping pipes & planes for FBC\n");
+		DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
 		intel_crtc->plane = ((pipe == 0) ? 1 : 0);
 	}
 
+	BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+	       dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
+	dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
+	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+
 	intel_crtc->cursor_addr = 0;
 	intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
 	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
@@ -4090,7 +4382,7 @@ static void intel_setup_outputs(struct d
 	if (IS_MOBILE(dev) && !IS_I830(dev))
 		intel_lvds_init(dev);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		int found;
 
 		if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
@@ -4118,37 +4410,51 @@ static void intel_setup_outputs(struct d
 		if (I915_READ(PCH_DP_D) & DP_DETECTED)
 			intel_dp_init(dev, PCH_DP_D);
 
-	} else if (IS_I9XX(dev)) {
+	} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
 		bool found = false;
 
 		if (I915_READ(SDVOB) & SDVO_DETECTED) {
+			DRM_DEBUG_KMS("probing SDVOB\n");
 			found = intel_sdvo_init(dev, SDVOB);
-			if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+			if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) {
+				DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
 				intel_hdmi_init(dev, SDVOB);
+			}
 
-			if (!found && SUPPORTS_INTEGRATED_DP(dev))
+			if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
+				DRM_DEBUG_KMS("probing DP_B\n");
 				intel_dp_init(dev, DP_B);
+			}
 		}
 
 		/* Before G4X SDVOC doesn't have its own detect register */
 
-		if (I915_READ(SDVOB) & SDVO_DETECTED)
+		if (I915_READ(SDVOB) & SDVO_DETECTED) {
+			DRM_DEBUG_KMS("probing SDVOC\n");
 			found = intel_sdvo_init(dev, SDVOC);
+		}
 
 		if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
 
-			if (SUPPORTS_INTEGRATED_HDMI(dev))
+			if (SUPPORTS_INTEGRATED_HDMI(dev)) {
+				DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
 				intel_hdmi_init(dev, SDVOC);
-			if (SUPPORTS_INTEGRATED_DP(dev))
+			}
+			if (SUPPORTS_INTEGRATED_DP(dev)) {
+				DRM_DEBUG_KMS("probing DP_C\n");
 				intel_dp_init(dev, DP_C);
+			}
 		}
 
-		if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
+		if (SUPPORTS_INTEGRATED_DP(dev) &&
+		    (I915_READ(DP_D) & DP_DETECTED)) {
+			DRM_DEBUG_KMS("probing DP_D\n");
 			intel_dp_init(dev, DP_D);
-	} else
+		}
+	} else if (IS_I8XX(dev))
 		intel_dvo_init(dev);
 
-	if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev))
+	if (SUPPORTS_TV(dev))
 		intel_tv_init(dev);
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -4249,6 +4555,42 @@ static const struct drm_mode_config_func
 	.fb_changed = intelfb_probe,
 };
 
+static struct drm_gem_object *
+intel_alloc_power_context(struct drm_device *dev)
+{
+	struct drm_gem_object *pwrctx;
+	int ret;
+
+	pwrctx = drm_gem_object_alloc(dev, 4096);
+	if (!pwrctx) {
+		DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
+		return NULL;
+	}
+
+	mutex_lock(&dev->struct_mutex);
+	ret = i915_gem_object_pin(pwrctx, 4096);
+	if (ret) {
+		DRM_ERROR("failed to pin power context: %d\n", ret);
+		goto err_unref;
+	}
+
+	ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1);
+	if (ret) {
+		DRM_ERROR("failed to set-domain on power context: %d\n", ret);
+		goto err_unpin;
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	return pwrctx;
+
+err_unpin:
+	i915_gem_object_unpin(pwrctx);
+err_unref:
+	drm_gem_object_unreference(pwrctx);
+	mutex_unlock(&dev->struct_mutex);
+	return NULL;
+}
+
 void intel_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4257,7 +4599,7 @@ void intel_init_clock_gating(struct drm_
 	 * Disable clock gating reported to work incorrectly according to the
 	 * specs, but enable as much else as we can.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		return;
 	} else if (IS_G4X(dev)) {
 		uint32_t dspclk_gate;
@@ -4291,11 +4633,37 @@ void intel_init_clock_gating(struct drm_
 		dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
 			DSTATE_DOT_CLOCK_GATING;
 		I915_WRITE(D_STATE, dstate);
-	} else if (IS_I855(dev) || IS_I865G(dev)) {
+	} else if (IS_I85X(dev) || IS_I865G(dev)) {
 		I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
 	} else if (IS_I830(dev)) {
 		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
 	}
+
+	/*
+	 * GPU can automatically power down the render unit if given a page
+	 * to save state.
+	 */
+	if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) {
+		struct drm_i915_gem_object *obj_priv = NULL;
+
+		if (dev_priv->pwrctx) {
+			obj_priv = dev_priv->pwrctx->driver_private;
+		} else {
+			struct drm_gem_object *pwrctx;
+
+			pwrctx = intel_alloc_power_context(dev);
+			if (pwrctx) {
+				dev_priv->pwrctx = pwrctx;
+				obj_priv = pwrctx->driver_private;
+			}
+		}
+
+		if (obj_priv) {
+			I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN);
+			I915_WRITE(MCHBAR_RENDER_STANDBY,
+				   I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT);
+		}
+	}
 }
 
 /* Set up chip specific display functions */
@@ -4304,8 +4672,8 @@ static void intel_init_display(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* We always want a DPMS function */
-	if (IS_IGDNG(dev))
-		dev_priv->display.dpms = igdng_crtc_dpms;
+	if (IS_IRONLAKE(dev))
+		dev_priv->display.dpms = ironlake_crtc_dpms;
 	else
 		dev_priv->display.dpms = i9xx_crtc_dpms;
 
@@ -4324,13 +4692,13 @@ static void intel_init_display(struct dr
 	}
 
 	/* Returns the core display clock speed */
-	if (IS_I945G(dev))
+	if (IS_I945G(dev) || (IS_G33(dev) && ! IS_PINEVIEW_M(dev)))
 		dev_priv->display.get_display_clock_speed =
 			i945_get_display_clock_speed;
 	else if (IS_I915G(dev))
 		dev_priv->display.get_display_clock_speed =
 			i915_get_display_clock_speed;
-	else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
+	else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev))
 		dev_priv->display.get_display_clock_speed =
 			i9xx_misc_get_display_clock_speed;
 	else if (IS_I915GM(dev))
@@ -4339,7 +4707,7 @@ static void intel_init_display(struct dr
 	else if (IS_I865G(dev))
 		dev_priv->display.get_display_clock_speed =
 			i865_get_display_clock_speed;
-	else if (IS_I855(dev))
+	else if (IS_I85X(dev))
 		dev_priv->display.get_display_clock_speed =
 			i855_get_display_clock_speed;
 	else /* 852, 830 */
@@ -4347,7 +4715,7 @@ static void intel_init_display(struct dr
 			i830_get_display_clock_speed;
 
 	/* For FIFO watermark updates */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		dev_priv->display.update_wm = NULL;
 	else if (IS_G4X(dev))
 		dev_priv->display.update_wm = g4x_update_wm;
@@ -4403,7 +4771,7 @@ void intel_modeset_init(struct drm_devic
 		num_pipe = 2;
 	else
 		num_pipe = 1;
-	DRM_DEBUG("%d display pipe%s available.\n",
+	DRM_DEBUG_KMS("%d display pipe%s available.\n",
 		  num_pipe, num_pipe > 1 ? "s" : "");
 
 	if (IS_I85X(dev))
@@ -4422,6 +4790,15 @@ void intel_modeset_init(struct drm_devic
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);
+
+	intel_setup_overlay(dev);
+
+	if (IS_PINEVIEW(dev) && !intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+							dev_priv->fsb_freq,
+							dev_priv->mem_freq))
+		DRM_INFO("failed to find known CxSR latency "
+			 "(found fsb freq %d, mem freq %d), disabling CxSR\n",
+			 dev_priv->fsb_freq, dev_priv->mem_freq);
 }
 
 void intel_modeset_cleanup(struct drm_device *dev)
@@ -4442,14 +4819,23 @@ void intel_modeset_cleanup(struct drm_de
 		del_timer_sync(&intel_crtc->idle_timer);
 	}
 
-	intel_increase_renderclock(dev, false);
 	del_timer_sync(&dev_priv->idle_timer);
 
-	mutex_unlock(&dev->struct_mutex);
-
 	if (dev_priv->display.disable_fbc)
 		dev_priv->display.disable_fbc(dev);
 
+	if (dev_priv->pwrctx) {
+		struct drm_i915_gem_object *obj_priv;
+
+		obj_priv = dev_priv->pwrctx->driver_private;
+		I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
+		I915_READ(PWRCTXA);
+		i915_gem_object_unpin(dev_priv->pwrctx);
+		drm_gem_object_unreference(dev_priv->pwrctx);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+
 	drm_mode_config_cleanup(dev);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,8 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
+
 
 #define DP_LINK_STATUS_SIZE	6
 #define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
@@ -124,9 +125,15 @@ intel_dp_link_clock(uint8_t link_bw)
 
 /* I think this is a fiction */
 static int
-intel_dp_link_required(int pixel_clock)
+intel_dp_link_required(struct drm_device *dev,
+		       struct intel_output *intel_output, int pixel_clock)
 {
-	return pixel_clock * 3;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_eDP(intel_output))
+		return (pixel_clock * dev_priv->edp_bpp) / 8;
+	else
+		return pixel_clock * 3;
 }
 
 static int
@@ -137,7 +144,8 @@ intel_dp_mode_valid(struct drm_connector
 	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
 	int max_lanes = intel_dp_max_lane_count(intel_output);
 
-	if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes)
+	if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+			> max_link_clock * max_lanes)
 		return MODE_CLOCK_HIGH;
 
 	if (mode->clock < 10000)
@@ -223,8 +231,8 @@ intel_dp_aux_ch(struct intel_output *int
 	 */
 	if (IS_eDP(intel_output))
 		aux_clock_divider = 225; /* eDP input clock at 450Mhz */
-	else if (IS_IGDNG(dev))
-		aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */
+	else if (IS_IRONLAKE(dev))
+		aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
 	else
 		aux_clock_divider = intel_hrawclk(dev) / 2;
 
@@ -282,7 +290,7 @@ intel_dp_aux_ch(struct intel_output *int
 	/* Timeouts occur when the device isn't connected, so they're
 	 * "normal" -- don't fill the kernel log with these */
 	if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
-		DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status);
+		DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
 		return -ETIMEDOUT;
 	}
 
@@ -382,17 +390,77 @@ intel_dp_aux_native_read(struct intel_ou
 }
 
 static int
-intel_dp_i2c_aux_ch(struct i2c_adapter *adapter,
-		    uint8_t *send, int send_bytes,
-		    uint8_t *recv, int recv_bytes)
+intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+		    uint8_t write_byte, uint8_t *read_byte)
 {
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 	struct intel_dp_priv *dp_priv = container_of(adapter,
 						     struct intel_dp_priv,
 						     adapter);
 	struct intel_output *intel_output = dp_priv->intel_output;
+	uint16_t address = algo_data->address;
+	uint8_t msg[5];
+	uint8_t reply[2];
+	int msg_bytes;
+	int reply_bytes;
+	int ret;
 
-	return intel_dp_aux_ch(intel_output,
-			       send, send_bytes, recv, recv_bytes);
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[0] = AUX_I2C_READ << 4;
+	else
+		msg[0] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[0] |= AUX_I2C_MOT << 4;
+
+	msg[1] = address >> 8;
+	msg[2] = address;
+
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg[3] = 0;
+		msg[4] = write_byte;
+		msg_bytes = 5;
+		reply_bytes = 1;
+		break;
+	case MODE_I2C_READ:
+		msg[3] = 0;
+		msg_bytes = 4;
+		reply_bytes = 2;
+		break;
+	default:
+		msg_bytes = 3;
+		reply_bytes = 1;
+		break;
+	}
+
+	for (;;) {
+	  ret = intel_dp_aux_ch(intel_output,
+				msg, msg_bytes,
+				reply, reply_bytes);
+		if (ret < 0) {
+			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+			return ret;
+		}
+		switch (reply[0] & AUX_I2C_REPLY_MASK) {
+		case AUX_I2C_REPLY_ACK:
+			if (mode == MODE_I2C_READ) {
+				*read_byte = reply[1];
+			}
+			return reply_bytes - 1;
+		case AUX_I2C_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_ch nack\n");
+			return -EREMOTEIO;
+		case AUX_I2C_REPLY_DEFER:
+			DRM_DEBUG_KMS("aux_ch defer\n");
+			udelay(100);
+			break;
+		default:
+			DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+			return -EREMOTEIO;
+		}
+	}
 }
 
 static int
@@ -431,11 +499,13 @@ intel_dp_mode_fixup(struct drm_encoder *
 		for (clock = 0; clock <= max_clock; clock++) {
 			int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-			if (intel_dp_link_required(mode->clock) <= link_avail) {
+			if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+					<= link_avail) {
 				dp_priv->link_bw = bws[clock];
 				dp_priv->lane_count = lane_count;
 				adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
-				DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n",
+				DRM_DEBUG_KMS("Display port link bw %02x lane "
+						"count %d clock %d\n",
 				       dp_priv->link_bw, dp_priv->lane_count,
 				       adjusted_mode->clock);
 				return true;
@@ -514,7 +584,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc,
 	intel_dp_compute_m_n(3, lane_count,
 			     mode->clock, adjusted_mode->clock, &m_n);
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		if (intel_crtc->pipe == 0) {
 			I915_WRITE(TRANSA_DATA_M1,
 				   ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
@@ -606,23 +676,23 @@ intel_dp_mode_set(struct drm_encoder *en
 	}
 }
 
-static void igdng_edp_backlight_on (struct drm_device *dev)
+static void ironlake_edp_backlight_on (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	pp = I915_READ(PCH_PP_CONTROL);
 	pp |= EDP_BLC_ENABLE;
 	I915_WRITE(PCH_PP_CONTROL, pp);
 }
 
-static void igdng_edp_backlight_off (struct drm_device *dev)
+static void ironlake_edp_backlight_off (struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	pp = I915_READ(PCH_PP_CONTROL);
 	pp &= ~EDP_BLC_ENABLE;
 	I915_WRITE(PCH_PP_CONTROL, pp);
@@ -641,13 +711,13 @@ intel_dp_dpms(struct drm_encoder *encode
 		if (dp_reg & DP_PORT_EN) {
 			intel_dp_link_down(intel_output, dp_priv->DP);
 			if (IS_eDP(intel_output))
-				igdng_edp_backlight_off(dev);
+				ironlake_edp_backlight_off(dev);
 		}
 	} else {
 		if (!(dp_reg & DP_PORT_EN)) {
 			intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
 			if (IS_eDP(intel_output))
-				igdng_edp_backlight_on(dev);
+				ironlake_edp_backlight_on(dev);
 		}
 	}
 	dp_priv->dpms_mode = mode;
@@ -1010,7 +1080,7 @@ intel_dp_link_down(struct intel_output *
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	if (IS_eDP(intel_output)) {
 		DP &= ~DP_PLL_ENABLE;
@@ -1071,7 +1141,7 @@ intel_dp_check_link_status(struct intel_
 }
 
 static enum drm_connector_status
-igdng_dp_detect(struct drm_connector *connector)
+ironlake_dp_detect(struct drm_connector *connector)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_dp_priv *dp_priv = intel_output->dev_priv;
@@ -1106,8 +1176,8 @@ intel_dp_detect(struct drm_connector *co
 
 	dp_priv->has_audio = false;
 
-	if (IS_IGDNG(dev))
-		return igdng_dp_detect(connector);
+	if (IS_IRONLAKE(dev))
+		return ironlake_dp_detect(connector);
 
 	temp = I915_READ(PORT_HOTPLUG_EN);
 
@@ -1254,18 +1324,17 @@ intel_dp_init(struct drm_device *dev, in
 	else
 		intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
 
-	if (output_reg == DP_B)
+	if (output_reg == DP_B || output_reg == PCH_DP_B)
 		intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
-	else if (output_reg == DP_C)
+	else if (output_reg == DP_C || output_reg == PCH_DP_C)
 		intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
-	else if (output_reg == DP_D)
+	else if (output_reg == DP_D || output_reg == PCH_DP_D)
 		intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-	if (IS_eDP(intel_output)) {
-		intel_output->crtc_mask = (1 << 1);
+	if (IS_eDP(intel_output))
 		intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
-	} else
-		intel_output->crtc_mask = (1 << 0) | (1 << 1);
+
+	intel_output->crtc_mask = (1 << 0) | (1 << 1);
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
 
@@ -1290,14 +1359,20 @@ intel_dp_init(struct drm_device *dev, in
 			break;
 		case DP_B:
 		case PCH_DP_B:
+			dev_priv->hotplug_supported_mask |=
+				HDMIB_HOTPLUG_INT_STATUS;
 			name = "DPDDC-B";
 			break;
 		case DP_C:
 		case PCH_DP_C:
+			dev_priv->hotplug_supported_mask |=
+				HDMIC_HOTPLUG_INT_STATUS;
 			name = "DPDDC-C";
 			break;
 		case DP_D:
 		case PCH_DP_D:
+			dev_priv->hotplug_supported_mask |=
+				HDMID_HOTPLUG_INT_STATUS;
 			name = "DPDDC-D";
 			break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,144 +0,0 @@
-/*
- * Copyright © 2008 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, 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 _INTEL_DP_H_
-#define _INTEL_DP_H_
-
-/* From the VESA DisplayPort spec */
-
-#define AUX_NATIVE_WRITE	0x8
-#define AUX_NATIVE_READ		0x9
-#define AUX_I2C_WRITE		0x0
-#define AUX_I2C_READ		0x1
-#define AUX_I2C_STATUS		0x2
-#define AUX_I2C_MOT		0x4
-
-#define AUX_NATIVE_REPLY_ACK	(0x0 << 4)
-#define AUX_NATIVE_REPLY_NACK	(0x1 << 4)
-#define AUX_NATIVE_REPLY_DEFER	(0x2 << 4)
-#define AUX_NATIVE_REPLY_MASK	(0x3 << 4)
-
-#define AUX_I2C_REPLY_ACK	(0x0 << 6)
-#define AUX_I2C_REPLY_NACK	(0x1 << 6)
-#define AUX_I2C_REPLY_DEFER	(0x2 << 6)
-#define AUX_I2C_REPLY_MASK	(0x3 << 6)
-
-/* AUX CH addresses */
-#define	DP_LINK_BW_SET		0x100
-# define DP_LINK_BW_1_62		    0x06
-# define DP_LINK_BW_2_7			    0x0a
-
-#define DP_LANE_COUNT_SET	0x101
-# define DP_LANE_COUNT_MASK		    0x0f
-# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
-
-#define DP_TRAINING_PATTERN_SET	0x102
-
-# define DP_TRAINING_PATTERN_DISABLE	    0
-# define DP_TRAINING_PATTERN_1		    1
-# define DP_TRAINING_PATTERN_2		    2
-# define DP_TRAINING_PATTERN_MASK	    0x3
-
-# define DP_LINK_QUAL_PATTERN_DISABLE	    (0 << 2)
-# define DP_LINK_QUAL_PATTERN_D10_2	    (1 << 2)
-# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
-# define DP_LINK_QUAL_PATTERN_PRBS7	    (3 << 2)
-# define DP_LINK_QUAL_PATTERN_MASK	    (3 << 2)
-
-# define DP_RECOVERED_CLOCK_OUT_EN	    (1 << 4)
-# define DP_LINK_SCRAMBLING_DISABLE	    (1 << 5)
-
-# define DP_SYMBOL_ERROR_COUNT_BOTH	    (0 << 6)
-# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
-# define DP_SYMBOL_ERROR_COUNT_SYMBOL	    (2 << 6)
-# define DP_SYMBOL_ERROR_COUNT_MASK	    (3 << 6)
-
-#define DP_TRAINING_LANE0_SET		    0x103
-#define DP_TRAINING_LANE1_SET		    0x104
-#define DP_TRAINING_LANE2_SET		    0x105
-#define DP_TRAINING_LANE3_SET		    0x106
-
-# define DP_TRAIN_VOLTAGE_SWING_MASK	    0x3
-# define DP_TRAIN_VOLTAGE_SWING_SHIFT	    0
-# define DP_TRAIN_MAX_SWING_REACHED	    (1 << 2)
-# define DP_TRAIN_VOLTAGE_SWING_400	    (0 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_600	    (1 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_800	    (2 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_1200	    (3 << 0)
-
-# define DP_TRAIN_PRE_EMPHASIS_MASK	    (3 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_0	    (0 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_3_5	    (1 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_6	    (2 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_9_5	    (3 << 3)
-
-# define DP_TRAIN_PRE_EMPHASIS_SHIFT	    3
-# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
-
-#define DP_DOWNSPREAD_CTRL		    0x107
-# define DP_SPREAD_AMP_0_5		    (1 << 4)
-
-#define DP_MAIN_LINK_CHANNEL_CODING_SET	    0x108
-# define DP_SET_ANSI_8B10B		    (1 << 0)
-
-#define DP_LANE0_1_STATUS		    0x202
-#define DP_LANE2_3_STATUS		    0x203
-
-# define DP_LANE_CR_DONE		    (1 << 0)
-# define DP_LANE_CHANNEL_EQ_DONE	    (1 << 1)
-# define DP_LANE_SYMBOL_LOCKED		    (1 << 2)
-
-#define DP_LANE_ALIGN_STATUS_UPDATED	    0x204
-
-#define DP_INTERLANE_ALIGN_DONE		    (1 << 0)
-#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
-#define DP_LINK_STATUS_UPDATED		    (1 << 7)
-
-#define DP_SINK_STATUS			    0x205
-
-#define DP_RECEIVE_PORT_0_STATUS	    (1 << 0)
-#define DP_RECEIVE_PORT_1_STATUS	    (1 << 1)
-
-#define DP_ADJUST_REQUEST_LANE0_1	    0x206
-#define DP_ADJUST_REQUEST_LANE2_3	    0x207
-
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
-
-struct i2c_algo_dp_aux_data {
-	bool running;
-	u16 address;
-	int (*aux_ch) (struct i2c_adapter *adapter,
-		       uint8_t *send, int send_bytes,
-		       uint8_t *recv, int recv_bytes);
-};
-
-int
-i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
-
-#endif /* _INTEL_DP_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp_i2c.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_dp_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_dp_i2c.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,273 +0,0 @@
-/*
- * Copyright © 2009 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, 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/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include "intel_dp.h"
-#include "drmP.h"
-
-/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
-
-#define MODE_I2C_START	1
-#define MODE_I2C_WRITE	2
-#define MODE_I2C_READ	4
-#define MODE_I2C_STOP	8
-
-static int
-i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
-			    uint8_t write_byte, uint8_t *read_byte)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	uint16_t address = algo_data->address;
-	uint8_t msg[5];
-	uint8_t reply[2];
-	int msg_bytes;
-	int reply_bytes;
-	int ret;
-
-	/* Set up the command byte */
-	if (mode & MODE_I2C_READ)
-		msg[0] = AUX_I2C_READ << 4;
-	else
-		msg[0] = AUX_I2C_WRITE << 4;
-
-	if (!(mode & MODE_I2C_STOP))
-		msg[0] |= AUX_I2C_MOT << 4;
-
-	msg[1] = address >> 8;
-	msg[2] = address;
-
-	switch (mode) {
-	case MODE_I2C_WRITE:
-		msg[3] = 0;
-		msg[4] = write_byte;
-		msg_bytes = 5;
-		reply_bytes = 1;
-		break;
-	case MODE_I2C_READ:
-		msg[3] = 0;
-		msg_bytes = 4;
-		reply_bytes = 2;
-		break;
-	default:
-		msg_bytes = 3;
-		reply_bytes = 1;
-		break;
-	}
-
-	for (;;) {
-		ret = (*algo_data->aux_ch)(adapter,
-					   msg, msg_bytes,
-					   reply, reply_bytes);
-		if (ret < 0) {
-			DRM_DEBUG("aux_ch failed %d\n", ret);
-			return ret;
-		}
-		switch (reply[0] & AUX_I2C_REPLY_MASK) {
-		case AUX_I2C_REPLY_ACK:
-			if (mode == MODE_I2C_READ) {
-				*read_byte = reply[1];
-			}
-			return reply_bytes - 1;
-		case AUX_I2C_REPLY_NACK:
-			DRM_DEBUG("aux_ch nack\n");
-			return -EREMOTEIO;
-		case AUX_I2C_REPLY_DEFER:
-			DRM_DEBUG("aux_ch defer\n");
-			udelay(100);
-			break;
-		default:
-			DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
-			return -EREMOTEIO;
-		}
-	}
-}
-
-/*
- * I2C over AUX CH
- */
-
-/*
- * Send the address. If the I2C link is running, this 'restarts'
- * the connection with the new address, this is used for doing
- * a write followed by a read (as needed for DDC)
- */
-static int
-i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int mode = MODE_I2C_START;
-	int ret;
-
-	if (reading)
-		mode |= MODE_I2C_READ;
-	else
-		mode |= MODE_I2C_WRITE;
-	algo_data->address = address;
-	algo_data->running = true;
-	ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
-	return ret;
-}
-
-/*
- * Stop the I2C transaction. This closes out the link, sending
- * a bare address packet with the MOT bit turned off
- */
-static void
-i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int mode = MODE_I2C_STOP;
-
-	if (reading)
-		mode |= MODE_I2C_READ;
-	else
-		mode |= MODE_I2C_WRITE;
-	if (algo_data->running) {
-		(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
-		algo_data->running = false;
-	}
-}
-
-/*
- * Write a single byte to the current I2C address, the
- * the I2C link must be running or this returns -EIO
- */
-static int
-i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int ret;
-
-	if (!algo_data->running)
-		return -EIO;
-
-	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
-	return ret;
-}
-
-/*
- * Read a single byte from the current I2C address, the
- * I2C link must be running or this returns -EIO
- */
-static int
-i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	int ret;
-
-	if (!algo_data->running)
-		return -EIO;
-
-	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
-	return ret;
-}
-
-static int
-i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
-		     struct i2c_msg *msgs,
-		     int num)
-{
-	int ret = 0;
-	bool reading = false;
-	int m;
-	int b;
-
-	for (m = 0; m < num; m++) {
-		u16 len = msgs[m].len;
-		u8 *buf = msgs[m].buf;
-		reading = (msgs[m].flags & I2C_M_RD) != 0;
-		ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
-		if (ret < 0)
-			break;
-		if (reading) {
-			for (b = 0; b < len; b++) {
-				ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
-				if (ret < 0)
-					break;
-			}
-		} else {
-			for (b = 0; b < len; b++) {
-				ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
-				if (ret < 0)
-					break;
-			}
-		}
-		if (ret < 0)
-			break;
-	}
-	if (ret >= 0)
-		ret = num;
-	i2c_algo_dp_aux_stop(adapter, reading);
-	DRM_DEBUG("dp_aux_xfer return %d\n", ret);
-	return ret;
-}
-
-static u32
-i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
-	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
-	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
-	       I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm i2c_dp_aux_algo = {
-	.master_xfer	= i2c_algo_dp_aux_xfer,
-	.functionality	= i2c_algo_dp_aux_functionality,
-};
-
-static void
-i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
-{
-	(void) i2c_algo_dp_aux_address(adapter, 0, false);
-	(void) i2c_algo_dp_aux_stop(adapter, false);
-					   
-}
-
-static int
-i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
-{
-	adapter->algo = &i2c_dp_aux_algo;
-	adapter->retries = 3;
-	i2c_dp_aux_reset_bus(adapter);
-	return 0;
-}
-
-int
-i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
-{
-	int error;
-	
-	error = i2c_dp_aux_prepare_bus(adapter);
-	if (error)
-		return error;
-	error = i2c_add_adapter(adapter);
-	return error;
-}
-EXPORT_SYMBOL(i2c_dp_aux_add_bus);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_drv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_drv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -110,6 +110,32 @@ struct intel_output {
 	int clone_mask;
 };
 
+struct intel_crtc;
+struct intel_overlay {
+	struct drm_device *dev;
+	struct intel_crtc *crtc;
+	struct drm_i915_gem_object *vid_bo;
+	struct drm_i915_gem_object *old_vid_bo;
+	int active;
+	int pfit_active;
+	u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
+	u32 color_key;
+	u32 brightness, contrast, saturation;
+	u32 old_xscale, old_yscale;
+	/* register access */
+	u32 flip_addr;
+	struct drm_i915_gem_object *reg_bo;
+	void *virt_addr;
+	/* flip handling */
+	uint32_t last_flip_req;
+	int hw_wedged;
+#define HW_WEDGED		1
+#define NEEDS_WAIT_FOR_FLIP	2
+#define RELEASE_OLD_VID		3
+#define SWITCH_OFF_STAGE_1	4
+#define SWITCH_OFF_STAGE_2	5
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -121,6 +147,8 @@ struct intel_crtc {
 	bool busy; /* is scanout buffer being updated frequently? */
 	struct timer_list idle_timer;
 	bool lowfreq_avail;
+	struct intel_overlay *overlay;
+	struct intel_unpin_work *unpin_work;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -134,6 +162,8 @@ void intel_i2c_destroy(struct i2c_adapte
 int intel_ddc_get_modes(struct intel_output *intel_output);
 extern bool intel_ddc_probe(struct intel_output *intel_output);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
+void intel_i2c_reset_gmbus(struct drm_device *dev);
+
 extern void intel_crt_init(struct drm_device *dev);
 extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
 extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
@@ -148,6 +178,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc,
 extern void intel_edp_link_config (struct intel_output *, int *, int *);
 
 
+extern int intel_panel_fitter_pipe (struct drm_device *dev);
 extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 extern void intel_encoder_prepare (struct drm_encoder *encoder);
 extern void intel_encoder_commit (struct drm_encoder *encoder);
@@ -177,10 +208,23 @@ extern void intel_crtc_fb_gamma_set(stru
 				    u16 blue, int regno);
 extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 				    u16 *blue, int regno);
+extern void intel_init_clock_gating(struct drm_device *dev);
 
 extern int intel_framebuffer_create(struct drm_device *dev,
 				    struct drm_mode_fb_cmd *mode_cmd,
 				    struct drm_framebuffer **fb,
 				    struct drm_gem_object *obj);
 
+extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
+extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
+
+extern void intel_setup_overlay(struct drm_device *dev);
+extern void intel_cleanup_overlay(struct drm_device *dev);
+extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
+						int interruptible);
+extern int intel_overlay_put_image(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
+extern int intel_overlay_attrs(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv);
 #endif /* __INTEL_DRV_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_fb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ static struct drm_fb_helper_funcs intel_
 
 
 /**
- * Curretly it is assumed that the old framebuffer is reused.
+ * Currently it is assumed that the old framebuffer is reused.
  *
  * LOCKING
  * caller should hold the mode config lock.
@@ -148,7 +148,7 @@ static int intelfb_create(struct drm_dev
 
 	mutex_lock(&dev->struct_mutex);
 
-	ret = i915_gem_object_pin(fbo, PAGE_SIZE);
+	ret = i915_gem_object_pin(fbo, 64*1024);
 	if (ret) {
 		DRM_ERROR("failed to pin fb: %d\n", ret);
 		goto out_unref;
@@ -230,8 +230,9 @@ static int intelfb_create(struct drm_dev
 	par->intel_fb = intel_fb;
 
 	/* To allow resizeing without swapping buffers */
-	DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
-		  intel_fb->base.height, obj_priv->gtt_offset, fbo);
+	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
+			intel_fb->base.width, intel_fb->base.height,
+			obj_priv->gtt_offset, fbo);
 
 	mutex_unlock(&dev->struct_mutex);
 	return 0;
@@ -249,7 +250,7 @@ int intelfb_probe(struct drm_device *dev
 {
 	int ret;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 	ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_hdmi.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,7 @@ static void intel_hdmi_dpms(struct drm_e
 	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
 	 * we do this anyway which shows more stable in testing.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -99,7 +99,7 @@ static void intel_hdmi_dpms(struct drm_e
 	/* HW workaround, need to write this twice for issue that may result
 	 * in first write getting masked.
 	 */
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		I915_WRITE(hdmi_priv->sdvox_reg, temp);
 		POSTING_READ(hdmi_priv->sdvox_reg);
 	}
@@ -225,7 +225,6 @@ static const struct drm_encoder_funcs in
 	.destroy = intel_hdmi_enc_destroy,
 };
 
-
 void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -254,21 +253,26 @@ void intel_hdmi_init(struct drm_device *
 	if (sdvox_reg == SDVOB) {
 		intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == SDVOC) {
 		intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMIB) {
 		intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
 								"HDMIB");
+		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMIC) {
 		intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
 								"HDMIC");
+		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
 	} else if (sdvox_reg == HDMID) {
 		intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
 								"HDMID");
+		dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
 	}
 	if (!intel_output->ddc_bus)
 		goto err_connector;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_i2c.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,7 @@ void intel_i2c_quirk_set(struct drm_devi
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* When using bit bashing for I2C, this bit needs to be set to 1 */
-	if (!IS_IGD(dev))
+	if (!IS_PINEVIEW(dev))
 		return;
 	if (enable)
 		I915_WRITE(DSPCLK_GATE_D,
@@ -118,6 +118,23 @@ static void set_data(void *data, int sta
 	udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
 }
 
+/* Clears the GMBUS setup.  Our driver doesn't make use of the GMBUS I2C
+ * engine, but if the BIOS leaves it enabled, then that can break our use
+ * of the bit-banging I2C interfaces.  This is notably the case with the
+ * Mac Mini in EFI mode.
+ */
+void
+intel_i2c_reset_gmbus(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (IS_IRONLAKE(dev)) {
+		I915_WRITE(PCH_GMBUS0, 0);
+	} else {
+		I915_WRITE(GMBUS0, 0);
+	}
+}
+
 /**
  * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
  * @dev: DRM device
@@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(str
 	if(i2c_bit_add_bus(&chan->adapter))
 		goto out_free;
 
+	intel_i2c_reset_gmbus(dev);
+
 	/* JJJ:  raise SCL and SDA? */
 	intel_i2c_quirk_set(dev, true);
 	set_data(chan, 1);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_lvds.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@ static void intel_lvds_set_backlight(str
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 blc_pwm_ctl, reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -74,7 +74,7 @@ static u32 intel_lvds_get_max_backlight(
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_PCH_CTL2;
 	else
 		reg = BLC_PWM_CTL;
@@ -91,7 +91,7 @@ static void intel_lvds_set_power(struct
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp_status, ctl_reg, status_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		ctl_reg = PCH_PP_CONTROL;
 		status_reg = PCH_PP_STATUS;
 	} else {
@@ -137,7 +137,7 @@ static void intel_lvds_save(struct drm_c
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -174,7 +174,7 @@ static void intel_lvds_restore(struct dr
 	u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
 	u32 pwm_ctl_reg;
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_ctl_reg = PCH_PP_CONTROL;
@@ -297,7 +297,7 @@ static bool intel_lvds_mode_fixup(struct
 	}
 
 	/* full screen scale for now */
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		goto out;
 
 	/* 965+ wants fuzzy fitting */
@@ -327,7 +327,7 @@ static bool intel_lvds_mode_fixup(struct
 	 * to register description and PRM.
 	 * Change the value here to see the borders for debugging
 	 */
-	if (!IS_IGDNG(dev)) {
+	if (!IS_IRONLAKE(dev)) {
 		I915_WRITE(BCLRPAT_A, 0);
 		I915_WRITE(BCLRPAT_B, 0);
 	}
@@ -548,7 +548,7 @@ static void intel_lvds_prepare(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 reg;
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		reg = BLC_PWM_CPU_CTL;
 	else
 		reg = BLC_PWM_CTL;
@@ -587,7 +587,7 @@ static void intel_lvds_mode_set(struct d
 	 * settings.
 	 */
 
-	if (IS_IGDNG(dev))
+	if (IS_IRONLAKE(dev))
 		return;
 
 	/*
@@ -602,12 +602,47 @@ static void intel_lvds_mode_set(struct d
 /* Some lid devices report incorrect lid status, assume they're connected */
 static const struct dmi_system_id bad_lid_status[] = {
 	{
+		.ident = "Compaq nx9020",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_BOARD_NAME, "3084"),
+		},
+	},
+	{
+		.ident = "Samsung SX20S",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
+			DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
+		},
+	},
+	{
 		.ident = "Aspire One",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
 		},
 	},
+	{
+		.ident = "Aspire 1810T",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"),
+		},
+	},
+	{
+		.ident = "PC-81005",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
+		},
+	},
+	{
+		.ident = "Clevo M5x0N",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
+			DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
+		},
+	},
 	{ }
 };
 
@@ -622,7 +657,7 @@ static enum drm_connector_status intel_l
 {
 	enum drm_connector_status status = connector_status_connected;
 
-	if (!acpi_lid_open() && !dmi_check_system(bad_lid_status))
+	if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
 		status = connector_status_disconnected;
 
 	return status;
@@ -679,7 +714,14 @@ static int intel_lid_notify(struct notif
 	struct drm_i915_private *dev_priv =
 		container_of(nb, struct drm_i915_private, lid_notifier);
 	struct drm_device *dev = dev_priv->dev;
+	struct drm_connector *connector = dev_priv->int_lvds_connector;
 
+	/*
+	 * check and update the status of LVDS connector after receiving
+	 * the LID nofication event.
+	 */
+	if (connector)
+		connector->status = connector->funcs->detect(connector);
 	if (!acpi_lid_open()) {
 		dev_priv->modeset_on_lid = 1;
 		return NOTIFY_OK;
@@ -854,64 +896,101 @@ static const struct dmi_system_id intel_
 	{ }	/* terminating entry */
 };
 
-#ifdef CONFIG_ACPI
-/*
- * check_lid_device -- check whether @handle is an ACPI LID device.
- * @handle: ACPI device handle
- * @level : depth in the ACPI namespace tree
- * @context: the number of LID device when we find the device
- * @rv: a return value to fill if desired (Not use)
+/**
+ * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID
+ * @dev: drm device
+ * @connector: LVDS connector
+ *
+ * Find the reduced downclock for LVDS in EDID.
  */
-static acpi_status
-check_lid_device(acpi_handle handle, u32 level, void *context,
-			void **return_value)
+static void intel_find_lvds_downclock(struct drm_device *dev,
+				struct drm_connector *connector)
 {
-	struct acpi_device *acpi_dev;
-	int *lid_present = context;
-
-	acpi_dev = NULL;
-	/* Get the acpi device for device handle */
-	if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) {
-		/* If there is no ACPI device for handle, return */
-		return AE_OK;
-	}
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *scan, *panel_fixed_mode;
+	int temp_downclock;
 
-	if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7))
-		*lid_present = 1;
+	panel_fixed_mode = dev_priv->panel_fixed_mode;
+	temp_downclock = panel_fixed_mode->clock;
 
-	return AE_OK;
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		/*
+		 * If one mode has the same resolution with the fixed_panel
+		 * mode while they have the different refresh rate, it means
+		 * that the reduced downclock is found for the LVDS. In such
+		 * case we can set the different FPx0/1 to dynamically select
+		 * between low and high frequency.
+		 */
+		if (scan->hdisplay == panel_fixed_mode->hdisplay &&
+			scan->hsync_start == panel_fixed_mode->hsync_start &&
+			scan->hsync_end == panel_fixed_mode->hsync_end &&
+			scan->htotal == panel_fixed_mode->htotal &&
+			scan->vdisplay == panel_fixed_mode->vdisplay &&
+			scan->vsync_start == panel_fixed_mode->vsync_start &&
+			scan->vsync_end == panel_fixed_mode->vsync_end &&
+			scan->vtotal == panel_fixed_mode->vtotal) {
+			if (scan->clock < temp_downclock) {
+				/*
+				 * The downclock is already found. But we
+				 * expect to find the lower downclock.
+				 */
+				temp_downclock = scan->clock;
+			}
+		}
+	}
+	mutex_unlock(&dev->mode_config.mutex);
+	if (temp_downclock < panel_fixed_mode->clock &&
+	    i915_lvds_downclock) {
+		/* We found the downclock for LVDS. */
+		dev_priv->lvds_downclock_avail = 1;
+		dev_priv->lvds_downclock = temp_downclock;
+		DRM_DEBUG_KMS("LVDS downclock is found in EDID. "
+				"Normal clock %dKhz, downclock %dKhz\n",
+				panel_fixed_mode->clock, temp_downclock);
+	}
+	return;
 }
 
-/**
- * check whether there exists the ACPI LID device by enumerating the ACPI
- * device tree.
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ * Note: The addin_offset should also be checked for LVDS panel.
+ * Only when it is non-zero, it is assumed that it is present.
  */
-static int intel_lid_present(void)
+static int lvds_is_present_in_vbt(struct drm_device *dev)
 {
-	int lid_present = 0;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, ret;
 
-	if (acpi_disabled) {
-		/* If ACPI is disabled, there is no ACPI device tree to
-		 * check, so assume the LID device would have been present.
-		 */
+	if (!dev_priv->child_dev_num)
 		return 1;
-	}
 
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-				ACPI_UINT32_MAX,
-				check_lid_device, &lid_present, NULL);
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not LFP, continue.
+		 * If the device type is 0x22, it is also regarded as LFP.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
+			p_child->device_type != DEVICE_TYPE_LFP)
+			continue;
 
-	return lid_present;
-}
-#else
-static int intel_lid_present(void)
-{
-	/* In the absence of ACPI built in, assume that the LID device would
-	 * have been present.
-	 */
-	return 1;
+		/* The addin_offset should be checked. Only when it is
+		 * non-zero, it is regarded as present.
+		 */
+		if (p_child->addin_offset) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
 }
-#endif
 
 /**
  * intel_lvds_init - setup LVDS connectors on this device
@@ -936,21 +1015,16 @@ void intel_lvds_init(struct drm_device *
 	if (dmi_check_system(intel_no_lvds))
 		return;
 
-	/* Assume that any device without an ACPI LID device also doesn't
-	 * have an integrated LVDS.  We would be better off parsing the BIOS
-	 * to get a reliable indicator, but that code isn't written yet.
-	 *
-	 * In the case of all-in-one desktops using LVDS that we've seen,
-	 * they're using SDVO LVDS.
-	 */
-	if (!intel_lid_present())
+	if (!lvds_is_present_in_vbt(dev)) {
+		DRM_DEBUG_KMS("LVDS is not present in VBT\n");
 		return;
+	}
 
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
 			return;
 		if (dev_priv->edp_support) {
-			DRM_DEBUG("disable LVDS for eDP support\n");
+			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
 			return;
 		}
 		gpio = PCH_GPIOC;
@@ -1023,6 +1097,7 @@ void intel_lvds_init(struct drm_device *
 			dev_priv->panel_fixed_mode =
 				drm_mode_duplicate(dev, scan);
 			mutex_unlock(&dev->mode_config.mutex);
+			intel_find_lvds_downclock(dev, connector);
 			goto out;
 		}
 		mutex_unlock(&dev->mode_config.mutex);
@@ -1047,8 +1122,8 @@ void intel_lvds_init(struct drm_device *
 	 * correct mode.
 	 */
 
-	/* IGDNG: FIXME if still fail, not try pipe mode now */
-	if (IS_IGDNG(dev))
+	/* Ironlake: FIXME if still fail, not try pipe mode now */
+	if (IS_IRONLAKE(dev))
 		goto failed;
 
 	lvds = I915_READ(LVDS);
@@ -1069,7 +1144,7 @@ void intel_lvds_init(struct drm_device *
 		goto failed;
 
 out:
-	if (IS_IGDNG(dev)) {
+	if (IS_IRONLAKE(dev)) {
 		u32 pwm;
 		/* make sure PWM is enabled */
 		pwm = I915_READ(BLC_PWM_CPU_CTL2);
@@ -1082,9 +1157,11 @@ out:
 	}
 	dev_priv->lid_notifier.notifier_call = intel_lid_notify;
 	if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) {
-		DRM_DEBUG("lid notifier registration failed\n");
+		DRM_DEBUG_KMS("lid notifier registration failed\n");
 		dev_priv->lid_notifier.notifier_call = NULL;
 	}
+	/* keep the LVDS connector */
+	dev_priv->int_lvds_connector = connector;
 	drm_sysfs_connector_add(connector);
 	return;
 
@@ -1093,5 +1170,6 @@ failed:
 	if (intel_output->ddc_bus)
 		intel_i2c_destroy(intel_output->ddc_bus);
 	drm_connector_cleanup(connector);
+	drm_encoder_cleanup(encoder);
 	kfree(intel_output);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_overlay.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_overlay.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_overlay.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_overlay.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1416 @@
+/*
+ * Copyright © 2009
+ *
+ * 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.
+ *
+ * Authors:
+ *    Daniel Vetter <daniel@ffwll.ch>
+ *
+ * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+#include "i915_reg.h"
+#include "intel_drv.h"
+
+/* Limits for overlay size. According to intel doc, the real limits are:
+ * Y width: 4095, UV width (planar): 2047, Y height: 2047,
+ * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
+ * the mininum of both.  */
+#define IMAGE_MAX_WIDTH		2048
+#define IMAGE_MAX_HEIGHT	2046 /* 2 * 1023 */
+/* on 830 and 845 these large limits result in the card hanging */
+#define IMAGE_MAX_WIDTH_LEGACY	1024
+#define IMAGE_MAX_HEIGHT_LEGACY	1088
+
+/* overlay register definitions */
+/* OCMD register */
+#define OCMD_TILED_SURFACE	(0x1<<19)
+#define OCMD_MIRROR_MASK	(0x3<<17)
+#define OCMD_MIRROR_MODE	(0x3<<17)
+#define OCMD_MIRROR_HORIZONTAL	(0x1<<17)
+#define OCMD_MIRROR_VERTICAL	(0x2<<17)
+#define OCMD_MIRROR_BOTH	(0x3<<17)
+#define OCMD_BYTEORDER_MASK	(0x3<<14) /* zero for YUYV or FOURCC YUY2 */
+#define OCMD_UV_SWAP		(0x1<<14) /* YVYU */
+#define OCMD_Y_SWAP		(0x2<<14) /* UYVY or FOURCC UYVY */
+#define OCMD_Y_AND_UV_SWAP	(0x3<<14) /* VYUY */
+#define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
+#define OCMD_RGB_888		(0x1<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_555		(0x2<<10) /* not in i965 Intel docs */
+#define OCMD_RGB_565		(0x3<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_422_PACKED	(0x8<<10)
+#define OCMD_YUV_411_PACKED	(0x9<<10) /* not in i965 Intel docs */
+#define OCMD_YUV_420_PLANAR	(0xc<<10)
+#define OCMD_YUV_422_PLANAR	(0xd<<10)
+#define OCMD_YUV_410_PLANAR	(0xe<<10) /* also 411 */
+#define OCMD_TVSYNCFLIP_PARITY	(0x1<<9)
+#define OCMD_TVSYNCFLIP_ENABLE	(0x1<<7)
+#define OCMD_BUF_TYPE_MASK	(Ox1<<5)
+#define OCMD_BUF_TYPE_FRAME	(0x0<<5)
+#define OCMD_BUF_TYPE_FIELD	(0x1<<5)
+#define OCMD_TEST_MODE		(0x1<<4)
+#define OCMD_BUFFER_SELECT	(0x3<<2)
+#define OCMD_BUFFER0		(0x0<<2)
+#define OCMD_BUFFER1		(0x1<<2)
+#define OCMD_FIELD_SELECT	(0x1<<2)
+#define OCMD_FIELD0		(0x0<<1)
+#define OCMD_FIELD1		(0x1<<1)
+#define OCMD_ENABLE		(0x1<<0)
+
+/* OCONFIG register */
+#define OCONF_PIPE_MASK		(0x1<<18)
+#define OCONF_PIPE_A		(0x0<<18)
+#define OCONF_PIPE_B		(0x1<<18)
+#define OCONF_GAMMA2_ENABLE	(0x1<<16)
+#define OCONF_CSC_MODE_BT601	(0x0<<5)
+#define OCONF_CSC_MODE_BT709	(0x1<<5)
+#define OCONF_CSC_BYPASS	(0x1<<4)
+#define OCONF_CC_OUT_8BIT	(0x1<<3)
+#define OCONF_TEST_MODE		(0x1<<2)
+#define OCONF_THREE_LINE_BUFFER	(0x1<<0)
+#define OCONF_TWO_LINE_BUFFER	(0x0<<0)
+
+/* DCLRKM (dst-key) register */
+#define DST_KEY_ENABLE		(0x1<<31)
+#define CLK_RGB24_MASK		0x0
+#define CLK_RGB16_MASK		0x070307
+#define CLK_RGB15_MASK		0x070707
+#define CLK_RGB8I_MASK		0xffffff
+
+#define RGB16_TO_COLORKEY(c) \
+	(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
+#define RGB15_TO_COLORKEY(c) \
+	(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
+
+/* overlay flip addr flag */
+#define OFC_UPDATE		0x1
+
+/* polyphase filter coefficients */
+#define N_HORIZ_Y_TAPS          5
+#define N_VERT_Y_TAPS           3
+#define N_HORIZ_UV_TAPS         3
+#define N_VERT_UV_TAPS          3
+#define N_PHASES                17
+#define MAX_TAPS                5
+
+/* memory bufferd overlay registers */
+struct overlay_registers {
+    u32 OBUF_0Y;
+    u32 OBUF_1Y;
+    u32 OBUF_0U;
+    u32 OBUF_0V;
+    u32 OBUF_1U;
+    u32 OBUF_1V;
+    u32 OSTRIDE;
+    u32 YRGB_VPH;
+    u32 UV_VPH;
+    u32 HORZ_PH;
+    u32 INIT_PHS;
+    u32 DWINPOS;
+    u32 DWINSZ;
+    u32 SWIDTH;
+    u32 SWIDTHSW;
+    u32 SHEIGHT;
+    u32 YRGBSCALE;
+    u32 UVSCALE;
+    u32 OCLRC0;
+    u32 OCLRC1;
+    u32 DCLRKV;
+    u32 DCLRKM;
+    u32 SCLRKVH;
+    u32 SCLRKVL;
+    u32 SCLRKEN;
+    u32 OCONFIG;
+    u32 OCMD;
+    u32 RESERVED1; /* 0x6C */
+    u32 OSTART_0Y;
+    u32 OSTART_1Y;
+    u32 OSTART_0U;
+    u32 OSTART_0V;
+    u32 OSTART_1U;
+    u32 OSTART_1V;
+    u32 OTILEOFF_0Y;
+    u32 OTILEOFF_1Y;
+    u32 OTILEOFF_0U;
+    u32 OTILEOFF_0V;
+    u32 OTILEOFF_1U;
+    u32 OTILEOFF_1V;
+    u32 FASTHSCALE; /* 0xA0 */
+    u32 UVSCALEV; /* 0xA4 */
+    u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
+    u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
+    u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
+    u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
+    u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
+    u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
+    u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
+    u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
+    u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
+};
+
+/* overlay flip addr flag */
+#define OFC_UPDATE		0x1
+
+#define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev))
+#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev))
+
+
+static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+{
+        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+	struct overlay_registers *regs;
+
+	/* no recursive mappings */
+	BUG_ON(overlay->virt_addr);
+
+	if (OVERLAY_NONPHYSICAL(overlay->dev)) {
+		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+				overlay->reg_bo->gtt_offset);
+
+		if (!regs) {
+			DRM_ERROR("failed to map overlay regs in GTT\n");
+			return NULL;
+		}
+	} else
+		regs = overlay->reg_bo->phys_obj->handle->vaddr;
+
+	return overlay->virt_addr = regs;
+}
+
+static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (OVERLAY_NONPHYSICAL(overlay->dev))
+		io_mapping_unmap_atomic(overlay->virt_addr);
+
+	overlay->virt_addr = NULL;
+
+	I915_READ(OVADD); /* flush wc cashes */
+
+	return;
+}
+
+/* overlay needs to be disable in OCMD reg */
+static int intel_overlay_on(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	RING_LOCALS;
+
+	BUG_ON(overlay->active);
+
+	overlay->active = 1;
+	overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
+	OUT_RING(overlay->flip_addr | OFC_UPDATE);
+	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* overlay needs to be enabled in OCMD reg */
+static void intel_overlay_continue(struct intel_overlay *overlay,
+			    bool load_polyphase_filter)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 flip_addr = overlay->flip_addr;
+	u32 tmp;
+	RING_LOCALS;
+
+	BUG_ON(!overlay->active);
+
+	if (load_polyphase_filter)
+		flip_addr |= OFC_UPDATE;
+
+	/* check for underruns */
+	tmp = I915_READ(DOVSTA);
+	if (tmp & (1 << 17))
+		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
+
+	BEGIN_LP_RING(4);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	OUT_RING(flip_addr);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+}
+
+static int intel_overlay_wait_flip(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	u32 tmp;
+	RING_LOCALS;
+
+	if (overlay->last_flip_req != 0) {
+		ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+		if (ret == 0) {
+			overlay->last_flip_req = 0;
+
+			tmp = I915_READ(ISR);
+
+			if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT))
+				return 0;
+		}
+	}
+
+	/* synchronous slowpath */
+	overlay->hw_wedged = RELEASE_OLD_VID;
+
+	BEGIN_LP_RING(2);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* overlay needs to be disabled in OCMD reg */
+static int intel_overlay_off(struct intel_overlay *overlay)
+{
+	u32 flip_addr = overlay->flip_addr;
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	RING_LOCALS;
+
+	BUG_ON(!overlay->active);
+
+	/* According to intel docs the overlay hw may hang (when switching
+	 * off) without loading the filter coeffs. It is however unclear whether
+	 * this applies to the disabling of the overlay or to the switching off
+	 * of the hw. Do it in both cases */
+	flip_addr |= OFC_UPDATE;
+
+	/* wait for overlay to go idle */
+	overlay->hw_wedged = SWITCH_OFF_STAGE_1;
+
+	BEGIN_LP_RING(6);
+	OUT_RING(MI_FLUSH);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
+	OUT_RING(flip_addr);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+        ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	/* turn overlay off */
+	overlay->hw_wedged = SWITCH_OFF_STAGE_2;
+
+	BEGIN_LP_RING(6);
+        OUT_RING(MI_FLUSH);
+        OUT_RING(MI_NOOP);
+        OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+	OUT_RING(flip_addr);
+        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+        OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+
+	overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+	if (overlay->last_flip_req == 0)
+		return -ENOMEM;
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, 1);
+	if (ret != 0)
+		return ret;
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return ret;
+}
+
+static void intel_overlay_off_tail(struct intel_overlay *overlay)
+{
+	struct drm_gem_object *obj;
+
+	/* never have the overlay hw on without showing a frame */
+	BUG_ON(!overlay->vid_bo);
+	obj = overlay->vid_bo->obj;
+
+	i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(obj);
+	overlay->vid_bo = NULL;
+
+	overlay->crtc->overlay = NULL;
+	overlay->crtc = NULL;
+	overlay->active = 0;
+}
+
+/* recover from an interruption due to a signal
+ * We have to be careful not to repeat work forever an make forward progess. */
+int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
+					 int interruptible)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	u32 flip_addr;
+	int ret;
+	RING_LOCALS;
+
+	if (overlay->hw_wedged == HW_WEDGED)
+		return -EIO;
+
+	if (overlay->last_flip_req == 0) {
+		overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+		if (overlay->last_flip_req == 0)
+			return -ENOMEM;
+	}
+
+	ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible);
+	if (ret != 0)
+		return ret;
+
+	switch (overlay->hw_wedged) {
+		case RELEASE_OLD_VID:
+			obj = overlay->old_vid_bo->obj;
+			i915_gem_object_unpin(obj);
+			drm_gem_object_unreference(obj);
+			overlay->old_vid_bo = NULL;
+			break;
+		case SWITCH_OFF_STAGE_1:
+			flip_addr = overlay->flip_addr;
+			flip_addr |= OFC_UPDATE;
+
+			overlay->hw_wedged = SWITCH_OFF_STAGE_2;
+
+			BEGIN_LP_RING(6);
+			OUT_RING(MI_FLUSH);
+			OUT_RING(MI_NOOP);
+			OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+			OUT_RING(flip_addr);
+			OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+			OUT_RING(MI_NOOP);
+			ADVANCE_LP_RING();
+
+			overlay->last_flip_req = i915_add_request(dev, NULL, 0);
+			if (overlay->last_flip_req == 0)
+				return -ENOMEM;
+
+			ret = i915_do_wait_request(dev, overlay->last_flip_req,
+					interruptible);
+			if (ret != 0)
+				return ret;
+
+		case SWITCH_OFF_STAGE_2:
+			intel_overlay_off_tail(overlay);
+			break;
+		default:
+			BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
+	}
+
+	overlay->hw_wedged = 0;
+	overlay->last_flip_req = 0;
+	return 0;
+}
+
+/* Wait for pending overlay flip and release old frame.
+ * Needs to be called before the overlay register are changed
+ * via intel_overlay_(un)map_regs_atomic */
+static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+{
+	int ret;
+	struct drm_gem_object *obj;
+
+	/* only wait if there is actually an old frame to release to
+	 * guarantee forward progress */
+	if (!overlay->old_vid_bo)
+		return 0;
+
+	ret = intel_overlay_wait_flip(overlay);
+	if (ret != 0)
+		return ret;
+
+	obj = overlay->old_vid_bo->obj;
+	i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(obj);
+	overlay->old_vid_bo = NULL;
+
+	return 0;
+}
+
+struct put_image_params {
+	int format;
+	short dst_x;
+	short dst_y;
+	short dst_w;
+	short dst_h;
+	short src_w;
+	short src_scan_h;
+	short src_scan_w;
+	short src_h;
+	short stride_Y;
+	short stride_UV;
+	int offset_Y;
+	int offset_U;
+	int offset_V;
+};
+
+static int packed_depth_bytes(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			return 4;
+		case I915_OVERLAY_YUV411:
+			/* return 6; not implemented */
+		default:
+			return -EINVAL;
+	}
+}
+
+static int packed_width_bytes(u32 format, short width)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+			return width << 1;
+		default:
+			return -EINVAL;
+	}
+}
+
+static int uv_hsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV422:
+		case I915_OVERLAY_YUV420:
+			return 2;
+		case I915_OVERLAY_YUV411:
+		case I915_OVERLAY_YUV410:
+			return 4;
+		default:
+			return -EINVAL;
+	}
+}
+
+static int uv_vsubsampling(u32 format)
+{
+	switch (format & I915_OVERLAY_DEPTH_MASK) {
+		case I915_OVERLAY_YUV420:
+		case I915_OVERLAY_YUV410:
+			return 2;
+		case I915_OVERLAY_YUV422:
+		case I915_OVERLAY_YUV411:
+			return 1;
+		default:
+			return -EINVAL;
+	}
+}
+
+static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
+{
+	u32 mask, shift, ret;
+	if (IS_I9XX(dev)) {
+		mask = 0x3f;
+		shift = 6;
+	} else {
+		mask = 0x1f;
+		shift = 5;
+	}
+	ret = ((offset + width + mask) >> shift) - (offset >> shift);
+	if (IS_I9XX(dev))
+		ret <<= 1;
+	ret -=1;
+	return ret << 2;
+}
+
+static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
+	0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
+	0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
+	0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
+	0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
+	0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
+	0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
+	0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
+	0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
+	0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
+	0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
+	0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
+	0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
+	0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
+	0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
+	0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
+	0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
+	0xb000, 0x3000, 0x0800, 0x3000, 0xb000};
+static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
+	0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
+	0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
+	0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
+	0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
+	0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
+	0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
+	0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
+	0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
+	0x3000, 0x0800, 0x3000};
+
+static void update_polyphase_filter(struct overlay_registers *regs)
+{
+	memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
+	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
+}
+
+static bool update_scaling_factors(struct intel_overlay *overlay,
+				   struct overlay_registers *regs,
+				   struct put_image_params *params)
+{
+	/* fixed point with a 12 bit shift */
+	u32 xscale, yscale, xscale_UV, yscale_UV;
+#define FP_SHIFT 12
+#define FRACT_MASK 0xfff
+	bool scale_changed = false;
+	int uv_hscale = uv_hsubsampling(params->format);
+	int uv_vscale = uv_vsubsampling(params->format);
+
+	if (params->dst_w > 1)
+		xscale = ((params->src_scan_w - 1) << FP_SHIFT)
+			/(params->dst_w);
+	else
+		xscale = 1 << FP_SHIFT;
+
+	if (params->dst_h > 1)
+		yscale = ((params->src_scan_h - 1) << FP_SHIFT)
+			/(params->dst_h);
+	else
+		yscale = 1 << FP_SHIFT;
+
+	/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
+		xscale_UV = xscale/uv_hscale;
+		yscale_UV = yscale/uv_vscale;
+		/* make the Y scale to UV scale ratio an exact multiply */
+		xscale = xscale_UV * uv_hscale;
+		yscale = yscale_UV * uv_vscale;
+	/*} else {
+		xscale_UV = 0;
+		yscale_UV = 0;
+	}*/
+
+	if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
+		scale_changed = true;
+	overlay->old_xscale = xscale;
+	overlay->old_yscale = yscale;
+
+	regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20)
+		| ((xscale >> FP_SHIFT) << 16)
+		| ((xscale & FRACT_MASK) << 3);
+	regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20)
+		| ((xscale_UV >> FP_SHIFT) << 16)
+		| ((xscale_UV & FRACT_MASK) << 3);
+	regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16)
+		| ((yscale_UV >> FP_SHIFT) << 0);
+
+	if (scale_changed)
+		update_polyphase_filter(regs);
+
+	return scale_changed;
+}
+
+static void update_colorkey(struct intel_overlay *overlay,
+			    struct overlay_registers *regs)
+{
+	u32 key = overlay->color_key;
+	switch (overlay->crtc->base.fb->bits_per_pixel) {
+		case 8:
+			regs->DCLRKV = 0;
+			regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
+		case 16:
+			if (overlay->crtc->base.fb->depth == 15) {
+				regs->DCLRKV = RGB15_TO_COLORKEY(key);
+				regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
+			} else {
+				regs->DCLRKV = RGB16_TO_COLORKEY(key);
+				regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
+			}
+		case 24:
+		case 32:
+			regs->DCLRKV = key;
+			regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
+	}
+}
+
+static u32 overlay_cmd_reg(struct put_image_params *params)
+{
+	u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+			case I915_OVERLAY_YUV422:
+				cmd |= OCMD_YUV_422_PLANAR;
+				break;
+			case I915_OVERLAY_YUV420:
+				cmd |= OCMD_YUV_420_PLANAR;
+				break;
+			case I915_OVERLAY_YUV411:
+			case I915_OVERLAY_YUV410:
+				cmd |= OCMD_YUV_410_PLANAR;
+				break;
+		}
+	} else { /* YUV packed */
+		switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+			case I915_OVERLAY_YUV422:
+				cmd |= OCMD_YUV_422_PACKED;
+				break;
+			case I915_OVERLAY_YUV411:
+				cmd |= OCMD_YUV_411_PACKED;
+				break;
+		}
+
+		switch (params->format & I915_OVERLAY_SWAP_MASK) {
+			case I915_OVERLAY_NO_SWAP:
+				break;
+			case I915_OVERLAY_UV_SWAP:
+				cmd |= OCMD_UV_SWAP;
+				break;
+			case I915_OVERLAY_Y_SWAP:
+				cmd |= OCMD_Y_SWAP;
+				break;
+			case I915_OVERLAY_Y_AND_UV_SWAP:
+				cmd |= OCMD_Y_AND_UV_SWAP;
+				break;
+		}
+	}
+
+	return cmd;
+}
+
+int intel_overlay_do_put_image(struct intel_overlay *overlay,
+			       struct drm_gem_object *new_bo,
+			       struct put_image_params *params)
+{
+	int ret, tmp_width;
+	struct overlay_registers *regs;
+	bool scale_changed = false;
+	struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+	struct drm_device *dev = overlay->dev;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
+	BUG_ON(!overlay);
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_pin(new_bo, PAGE_SIZE);
+	if (ret != 0)
+		return ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
+	if (ret != 0)
+		goto out_unpin;
+
+	if (!overlay->active) {
+		regs = intel_overlay_map_regs_atomic(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unpin;
+		}
+		regs->OCONFIG = OCONF_CC_OUT_8BIT;
+		if (IS_I965GM(overlay->dev))
+			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
+		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
+			OCONF_PIPE_A : OCONF_PIPE_B;
+		intel_overlay_unmap_regs_atomic(overlay);
+
+		ret = intel_overlay_on(overlay);
+		if (ret != 0)
+			goto out_unpin;
+	}
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	if (!regs) {
+		ret = -ENOMEM;
+		goto out_unpin;
+	}
+
+	regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
+	regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
+
+	if (params->format & I915_OVERLAY_YUV_PACKED)
+		tmp_width = packed_width_bytes(params->format, params->src_w);
+	else
+		tmp_width = params->src_w;
+
+	regs->SWIDTH = params->src_w;
+	regs->SWIDTHSW = calc_swidthsw(overlay->dev,
+			params->offset_Y, tmp_width);
+	regs->SHEIGHT = params->src_h;
+	regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
+	regs->OSTRIDE = params->stride_Y;
+
+	if (params->format & I915_OVERLAY_YUV_PLANAR) {
+		int uv_hscale = uv_hsubsampling(params->format);
+		int uv_vscale = uv_vsubsampling(params->format);
+		u32 tmp_U, tmp_V;
+		regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
+		tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
+				params->src_w/uv_hscale);
+		tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
+				params->src_w/uv_hscale);
+		regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
+		regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
+		regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
+		regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V;
+		regs->OSTRIDE |= params->stride_UV << 16;
+	}
+
+	scale_changed = update_scaling_factors(overlay, regs, params);
+
+	update_colorkey(overlay, regs);
+
+	regs->OCMD = overlay_cmd_reg(params);
+
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	intel_overlay_continue(overlay, scale_changed);
+
+	overlay->old_vid_bo = overlay->vid_bo;
+	overlay->vid_bo = new_bo->driver_private;
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_unpin(new_bo);
+	return ret;
+}
+
+int intel_overlay_switch_off(struct intel_overlay *overlay)
+{
+	int ret;
+	struct overlay_registers *regs;
+	struct drm_device *dev = overlay->dev;
+
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
+
+	if (overlay->hw_wedged) {
+		ret = intel_overlay_recover_from_interrupt(overlay, 1);
+		if (ret != 0)
+			return ret;
+	}
+
+	if (!overlay->active)
+		return 0;
+
+	ret = intel_overlay_release_old_vid(overlay);
+	if (ret != 0)
+		return ret;
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	regs->OCMD = 0;
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	ret = intel_overlay_off(overlay);
+	if (ret != 0)
+		return ret;
+
+	intel_overlay_off_tail(overlay);
+
+	return 0;
+}
+
+static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+					  struct intel_crtc *crtc)
+{
+        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+	u32 pipeconf;
+	int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
+
+	if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
+		return -EINVAL;
+
+	pipeconf = I915_READ(pipeconf_reg);
+
+	/* can't use the overlay with double wide pipe */
+	if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+{
+	struct drm_device *dev = overlay->dev;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 ratio;
+	u32 pfit_control = I915_READ(PFIT_CONTROL);
+
+	/* XXX: This is not the same logic as in the xorg driver, but more in
+	 * line with the intel documentation for the i965 */
+	if (!IS_I965G(dev) && (pfit_control & VERT_AUTO_SCALE)) {
+		ratio = I915_READ(PFIT_AUTO_RATIOS) >> PFIT_VERT_SCALE_SHIFT;
+	} else { /* on i965 use the PGM reg to read out the autoscaler values */
+		ratio = I915_READ(PFIT_PGM_RATIOS);
+		if (IS_I965G(dev))
+			ratio >>= PFIT_VERT_SCALE_SHIFT_965;
+		else
+			ratio >>= PFIT_VERT_SCALE_SHIFT;
+	}
+
+	overlay->pfit_vscale_ratio = ratio;
+}
+
+static int check_overlay_dst(struct intel_overlay *overlay,
+			     struct drm_intel_overlay_put_image *rec)
+{
+	struct drm_display_mode *mode = &overlay->crtc->base.mode;
+
+	if ((rec->dst_x < mode->crtc_hdisplay)
+	    && (rec->dst_x + rec->dst_width
+		    <= mode->crtc_hdisplay)
+	    && (rec->dst_y < mode->crtc_vdisplay)
+	    && (rec->dst_y + rec->dst_height
+		    <= mode->crtc_vdisplay))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int check_overlay_scaling(struct put_image_params *rec)
+{
+	u32 tmp;
+
+	/* downscaling limit is 8.0 */
+	tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+	tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
+	if (tmp > 7)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int check_overlay_src(struct drm_device *dev,
+			     struct drm_intel_overlay_put_image *rec,
+			     struct drm_gem_object *new_bo)
+{
+	u32 stride_mask;
+	int depth;
+	int uv_hscale = uv_hsubsampling(rec->flags);
+	int uv_vscale = uv_vsubsampling(rec->flags);
+	size_t tmp;
+
+	/* check src dimensions */
+	if (IS_845G(dev) || IS_I830(dev)) {
+		if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY
+		    || rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
+			return -EINVAL;
+	} else {
+		if (rec->src_height > IMAGE_MAX_HEIGHT
+		    || rec->src_width > IMAGE_MAX_WIDTH)
+			return -EINVAL;
+	}
+	/* better safe than sorry, use 4 as the maximal subsampling ratio */
+	if (rec->src_height < N_VERT_Y_TAPS*4
+	    || rec->src_width < N_HORIZ_Y_TAPS*4)
+		return -EINVAL;
+
+	/* check alingment constrains */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+		case I915_OVERLAY_RGB:
+			/* not implemented */
+			return -EINVAL;
+		case I915_OVERLAY_YUV_PACKED:
+			depth = packed_depth_bytes(rec->flags);
+			if (uv_vscale != 1)
+				return -EINVAL;
+			if (depth < 0)
+				return depth;
+			/* ignore UV planes */
+			rec->stride_UV = 0;
+			rec->offset_U = 0;
+			rec->offset_V = 0;
+			/* check pixel alignment */
+			if (rec->offset_Y % depth)
+				return -EINVAL;
+			break;
+		case I915_OVERLAY_YUV_PLANAR:
+			if (uv_vscale < 0 || uv_hscale < 0)
+				return -EINVAL;
+			/* no offset restrictions for planar formats */
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	if (rec->src_width % uv_hscale)
+		return -EINVAL;
+
+	/* stride checking */
+	stride_mask = 63;
+
+	if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
+		return -EINVAL;
+	if (IS_I965G(dev) && rec->stride_Y < 512)
+		return -EINVAL;
+
+	tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
+		4 : 8;
+	if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024)
+		return -EINVAL;
+
+	/* check buffer dimensions */
+	switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
+		case I915_OVERLAY_RGB:
+		case I915_OVERLAY_YUV_PACKED:
+			/* always 4 Y values per depth pixels */
+			if (packed_width_bytes(rec->flags, rec->src_width)
+					> rec->stride_Y)
+				return -EINVAL;
+
+			tmp = rec->stride_Y*rec->src_height;
+			if (rec->offset_Y + tmp > new_bo->size)
+				return -EINVAL;
+			break;
+		case I915_OVERLAY_YUV_PLANAR:
+			if (rec->src_width > rec->stride_Y)
+				return -EINVAL;
+			if (rec->src_width/uv_hscale > rec->stride_UV)
+				return -EINVAL;
+
+			tmp = rec->stride_Y*rec->src_height;
+			if (rec->offset_Y + tmp > new_bo->size)
+				return -EINVAL;
+			tmp = rec->stride_UV*rec->src_height;
+			tmp /= uv_vscale;
+			if (rec->offset_U + tmp > new_bo->size
+			    || rec->offset_V + tmp > new_bo->size)
+				return -EINVAL;
+			break;
+	}
+
+	return 0;
+}
+
+int intel_overlay_put_image(struct drm_device *dev, void *data,
+                            struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_put_image *put_image_rec = data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_mode_object *drmmode_obj;
+	struct intel_crtc *crtc;
+	struct drm_gem_object *new_bo;
+	struct put_image_params *params;
+	int ret;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
+		mutex_lock(&dev->mode_config.mutex);
+		mutex_lock(&dev->struct_mutex);
+
+		ret = intel_overlay_switch_off(overlay);
+
+		mutex_unlock(&dev->struct_mutex);
+		mutex_unlock(&dev->mode_config.mutex);
+
+		return ret;
+	}
+
+	params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
+                        DRM_MODE_OBJECT_CRTC);
+	if (!drmmode_obj)
+		return -ENOENT;
+	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
+
+	new_bo = drm_gem_object_lookup(dev, file_priv,
+			put_image_rec->bo_handle);
+	if (!new_bo)
+		return -ENOENT;
+
+	mutex_lock(&dev->mode_config.mutex);
+	mutex_lock(&dev->struct_mutex);
+
+	if (overlay->hw_wedged) {
+		ret = intel_overlay_recover_from_interrupt(overlay, 1);
+		if (ret != 0)
+			goto out_unlock;
+	}
+
+	if (overlay->crtc != crtc) {
+		struct drm_display_mode *mode = &crtc->base.mode;
+		ret = intel_overlay_switch_off(overlay);
+		if (ret != 0)
+			goto out_unlock;
+
+		ret = check_overlay_possible_on_crtc(overlay, crtc);
+		if (ret != 0)
+			goto out_unlock;
+
+		overlay->crtc = crtc;
+		crtc->overlay = overlay;
+
+		if (intel_panel_fitter_pipe(dev) == crtc->pipe
+		    /* and line to wide, i.e. one-line-mode */
+		    && mode->hdisplay > 1024) {
+			overlay->pfit_active = 1;
+			update_pfit_vscale_ratio(overlay);
+		} else
+			overlay->pfit_active = 0;
+	}
+
+	ret = check_overlay_dst(overlay, put_image_rec);
+	if (ret != 0)
+		goto out_unlock;
+
+	if (overlay->pfit_active) {
+		params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
+			overlay->pfit_vscale_ratio);
+		/* shifting right rounds downwards, so add 1 */
+		params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
+			overlay->pfit_vscale_ratio) + 1;
+	} else {
+		params->dst_y = put_image_rec->dst_y;
+		params->dst_h = put_image_rec->dst_height;
+	}
+	params->dst_x = put_image_rec->dst_x;
+	params->dst_w = put_image_rec->dst_width;
+
+	params->src_w = put_image_rec->src_width;
+	params->src_h = put_image_rec->src_height;
+	params->src_scan_w = put_image_rec->src_scan_width;
+	params->src_scan_h = put_image_rec->src_scan_height;
+	if (params->src_scan_h > params->src_h
+	    || params->src_scan_w > params->src_w) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	ret = check_overlay_src(dev, put_image_rec, new_bo);
+	if (ret != 0)
+		goto out_unlock;
+	params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
+	params->stride_Y = put_image_rec->stride_Y;
+	params->stride_UV = put_image_rec->stride_UV;
+	params->offset_Y = put_image_rec->offset_Y;
+	params->offset_U = put_image_rec->offset_U;
+	params->offset_V = put_image_rec->offset_V;
+
+	/* Check scaling after src size to prevent a divide-by-zero. */
+	ret = check_overlay_scaling(params);
+	if (ret != 0)
+		goto out_unlock;
+
+	ret = intel_overlay_do_put_image(overlay, new_bo, params);
+	if (ret != 0)
+		goto out_unlock;
+
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	kfree(params);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+	drm_gem_object_unreference(new_bo);
+	kfree(params);
+
+	return ret;
+}
+
+static void update_reg_attrs(struct intel_overlay *overlay,
+			     struct overlay_registers *regs)
+{
+	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
+	regs->OCLRC1 = overlay->saturation;
+}
+
+static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
+{
+	int i;
+
+	if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
+		return false;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
+			return false;
+	}
+
+	return true;
+}
+
+static bool check_gamma5_errata(u32 gamma5)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (((gamma5 >> i*8) & 0xff) == 0x80)
+			return false;
+	}
+
+	return true;
+}
+
+static int check_gamma(struct drm_intel_overlay_attrs *attrs)
+{
+	if (!check_gamma_bounds(0, attrs->gamma0)
+	    || !check_gamma_bounds(attrs->gamma0, attrs->gamma1)
+	    || !check_gamma_bounds(attrs->gamma1, attrs->gamma2)
+	    || !check_gamma_bounds(attrs->gamma2, attrs->gamma3)
+	    || !check_gamma_bounds(attrs->gamma3, attrs->gamma4)
+	    || !check_gamma_bounds(attrs->gamma4, attrs->gamma5)
+	    || !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
+		return -EINVAL;
+	if (!check_gamma5_errata(attrs->gamma5))
+		return -EINVAL;
+	return 0;
+}
+
+int intel_overlay_attrs(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
+{
+	struct drm_intel_overlay_attrs *attrs = data;
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct overlay_registers *regs;
+	int ret;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	overlay = dev_priv->overlay;
+	if (!overlay) {
+		DRM_DEBUG("userspace bug: no overlay\n");
+		return -ENODEV;
+	}
+
+	mutex_lock(&dev->mode_config.mutex);
+	mutex_lock(&dev->struct_mutex);
+
+	if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
+		attrs->color_key = overlay->color_key;
+		attrs->brightness = overlay->brightness;
+		attrs->contrast = overlay->contrast;
+		attrs->saturation = overlay->saturation;
+
+		if (IS_I9XX(dev)) {
+			attrs->gamma0 = I915_READ(OGAMC0);
+			attrs->gamma1 = I915_READ(OGAMC1);
+			attrs->gamma2 = I915_READ(OGAMC2);
+			attrs->gamma3 = I915_READ(OGAMC3);
+			attrs->gamma4 = I915_READ(OGAMC4);
+			attrs->gamma5 = I915_READ(OGAMC5);
+		}
+		ret = 0;
+	} else {
+		overlay->color_key = attrs->color_key;
+		if (attrs->brightness >= -128 && attrs->brightness <= 127) {
+			overlay->brightness = attrs->brightness;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		if (attrs->contrast <= 255) {
+			overlay->contrast = attrs->contrast;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		if (attrs->saturation <= 1023) {
+			overlay->saturation = attrs->saturation;
+		} else {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		regs = intel_overlay_map_regs_atomic(overlay);
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out_unlock;
+		}
+
+		update_reg_attrs(overlay, regs);
+
+		intel_overlay_unmap_regs_atomic(overlay);
+
+		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
+			if (!IS_I9XX(dev)) {
+				ret = -EINVAL;
+				goto out_unlock;
+			}
+
+			if (overlay->active) {
+				ret = -EBUSY;
+				goto out_unlock;
+			}
+
+			ret = check_gamma(attrs);
+			if (ret != 0)
+				goto out_unlock;
+
+			I915_WRITE(OGAMC0, attrs->gamma0);
+			I915_WRITE(OGAMC1, attrs->gamma1);
+			I915_WRITE(OGAMC2, attrs->gamma2);
+			I915_WRITE(OGAMC3, attrs->gamma3);
+			I915_WRITE(OGAMC4, attrs->gamma4);
+			I915_WRITE(OGAMC5, attrs->gamma5);
+		}
+		ret = 0;
+	}
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return ret;
+}
+
+void intel_setup_overlay(struct drm_device *dev)
+{
+        drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_overlay *overlay;
+	struct drm_gem_object *reg_bo;
+	struct overlay_registers *regs;
+	int ret;
+
+	if (!OVERLAY_EXISTS(dev))
+		return;
+
+	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
+	if (!overlay)
+		return;
+	overlay->dev = dev;
+
+	reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
+	if (!reg_bo)
+		goto out_free;
+	overlay->reg_bo = reg_bo->driver_private;
+
+	if (OVERLAY_NONPHYSICAL(dev)) {
+		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
+		if (ret) {
+                        DRM_ERROR("failed to pin overlay register bo\n");
+                        goto out_free_bo;
+                }
+		overlay->flip_addr = overlay->reg_bo->gtt_offset;
+	} else {
+		ret = i915_gem_attach_phys_object(dev, reg_bo,
+				I915_GEM_PHYS_OVERLAY_REGS);
+                if (ret) {
+                        DRM_ERROR("failed to attach phys overlay regs\n");
+                        goto out_free_bo;
+                }
+		overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
+	}
+
+	/* init all values */
+	overlay->color_key = 0x0101fe;
+	overlay->brightness = -19;
+	overlay->contrast = 75;
+	overlay->saturation = 146;
+
+	regs = intel_overlay_map_regs_atomic(overlay);
+	if (!regs)
+		goto out_free_bo;
+
+	memset(regs, 0, sizeof(struct overlay_registers));
+	update_polyphase_filter(regs);
+
+	update_reg_attrs(overlay, regs);
+
+	intel_overlay_unmap_regs_atomic(overlay);
+
+	dev_priv->overlay = overlay;
+	DRM_INFO("initialized overlay support\n");
+	return;
+
+out_free_bo:
+	drm_gem_object_unreference(reg_bo);
+out_free:
+	kfree(overlay);
+	return;
+}
+
+void intel_cleanup_overlay(struct drm_device *dev)
+{
+        drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (dev_priv->overlay) {
+		/* The bo's should be free'd by the generic code already.
+		 * Furthermore modesetting teardown happens beforehand so the
+		 * hardware should be off already */
+		BUG_ON(dev_priv->overlay->active);
+
+		kfree(dev_priv->overlay);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_sdvo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,8 +36,6 @@
 #include "i915_drv.h"
 #include "intel_sdvo_regs.h"
 
-#undef SDVO_DEBUG
-
 static char *tv_format_names[] = {
 	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
 	"PAL_B"    , "PAL_D"   , "PAL_G"   ,
@@ -356,7 +354,6 @@ static const struct _sdvo_cmd_name {
 #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
 #define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
 
-#ifdef SDVO_DEBUG
 static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
 				   void *args, int args_len)
 {
@@ -379,9 +376,6 @@ static void intel_sdvo_debug_write(struc
 		DRM_LOG_KMS("(%02X)", cmd);
 	DRM_LOG_KMS("\n");
 }
-#else
-#define intel_sdvo_debug_write(o, c, a, l)
-#endif
 
 static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
 				 void *args, int args_len)
@@ -398,7 +392,6 @@ static void intel_sdvo_write_cmd(struct
 	intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
 }
 
-#ifdef SDVO_DEBUG
 static const char *cmd_status_names[] = {
 	"Power on",
 	"Success",
@@ -427,9 +420,6 @@ static void intel_sdvo_debug_response(st
 		DRM_LOG_KMS("(??? %d)", status);
 	DRM_LOG_KMS("\n");
 }
-#else
-#define intel_sdvo_debug_response(o, r, l, s)
-#endif
 
 static u8 intel_sdvo_read_response(struct intel_output *intel_output,
 				   void *response, int response_len)
@@ -472,14 +462,63 @@ static int intel_sdvo_get_pixel_multipli
 }
 
 /**
- * Don't check status code from this as it switches the bus back to the
- * SDVO chips which defeats the purpose of doing a bus switch in the first
- * place.
+ * Try to read the response after issuie the DDC switch command. But it
+ * is noted that we must do the action of reading response and issuing DDC
+ * switch command in one I2C transaction. Otherwise when we try to start
+ * another I2C transaction after issuing the DDC bus switch, it will be
+ * switched to the internal SDVO register.
  */
 static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
 					      u8 target)
 {
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
+	struct i2c_msg msgs[] = {
+		{
+			.addr = sdvo_priv->slave_addr >> 1,
+			.flags = 0,
+			.len = 2,
+			.buf = out_buf,
+		},
+		/* the following two are to read the response */
+		{
+			.addr = sdvo_priv->slave_addr >> 1,
+			.flags = 0,
+			.len = 1,
+			.buf = cmd_buf,
+		},
+		{
+			.addr = sdvo_priv->slave_addr >> 1,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = ret_value,
+		},
+	};
+
+	intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+					&target, 1);
+	/* write the DDC switch command argument */
+	intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+
+	out_buf[0] = SDVO_I2C_OPCODE;
+	out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
+	cmd_buf[0] = SDVO_I2C_CMD_STATUS;
+	cmd_buf[1] = 0;
+	ret_value[0] = 0;
+	ret_value[1] = 0;
+
+	ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+	if (ret != 3) {
+		/* failure in I2C transfer */
+		DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
+		return;
+	}
+	if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) {
+		DRM_DEBUG_KMS("DDC switch command returns response %d\n",
+					ret_value[0]);
+		return;
+	}
+	return;
 }
 
 static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
@@ -1589,6 +1628,32 @@ intel_sdvo_hdmi_sink_detect(struct drm_c
 	edid = drm_get_edid(&intel_output->base,
 			    intel_output->ddc_bus);
 
+	/* This is only applied to SDVO cards with multiple outputs */
+	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+		uint8_t saved_ddc, temp_ddc;
+		saved_ddc = sdvo_priv->ddc_bus;
+		temp_ddc = sdvo_priv->ddc_bus >> 1;
+		/*
+		 * Don't use the 1 as the argument of DDC bus switch to get
+		 * the EDID. It is used for SDVO SPD ROM.
+		 */
+		while(temp_ddc > 1) {
+			sdvo_priv->ddc_bus = temp_ddc;
+			edid = drm_get_edid(&intel_output->base,
+				intel_output->ddc_bus);
+			if (edid) {
+				/*
+				 * When we can get the EDID, maybe it is the
+				 * correct DDC bus. Update it.
+				 */
+				sdvo_priv->ddc_bus = temp_ddc;
+				break;
+			}
+			temp_ddc >>= 1;
+		}
+		if (edid == NULL)
+			sdvo_priv->ddc_bus = saved_ddc;
+	}
 	/* when there is no edid and no monitor is connected with VGA
 	 * port, try to use the CRT ddc to read the EDID for DVI-connector
 	 */
@@ -1627,6 +1692,10 @@ static enum drm_connector_status intel_s
 
 	intel_sdvo_write_cmd(intel_output,
 			     SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+	if (sdvo_priv->is_tv) {
+		/* add 30ms delay when the output type is SDVO-TV */
+		mdelay(30);
+	}
 	status = intel_sdvo_read_response(intel_output, &response, 2);
 
 	DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
@@ -2276,6 +2345,14 @@ intel_sdvo_output_setup(struct intel_out
 		connector->connector_type = DRM_MODE_CONNECTOR_VGA;
 		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 					(1 << INTEL_ANALOG_CLONE_BIT);
+	} else if (flags & SDVO_OUTPUT_CVBS0) {
+
+		sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0;
+		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+		sdvo_priv->is_tv = true;
+		intel_output->needs_tv_clock = true;
+		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
 	} else if (flags & SDVO_OUTPUT_LVDS0) {
 
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
@@ -2668,6 +2745,7 @@ static void intel_sdvo_create_enhance_pr
 
 bool intel_sdvo_init(struct drm_device *dev, int output_device)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
 	struct intel_output *intel_output;
 	struct intel_sdvo_priv *sdvo_priv;
@@ -2714,10 +2792,12 @@ bool intel_sdvo_init(struct drm_device *
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
 		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
 						"SDVOB/VGA DDC BUS");
+		dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
 	} else {
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
 		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
 						"SDVOC/VGA DDC BUS");
+		dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
 	}
 
 	if (intel_output->ddc_bus == NULL)
@@ -2726,7 +2806,7 @@ bool intel_sdvo_init(struct drm_device *
 	/* Wrap with our custom algo which switches to DDC mode */
 	intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
-	/* In defaut case sdvo lvds is false */
+	/* In default case sdvo lvds is false */
 	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
 
 	if (intel_sdvo_output_setup(intel_output,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_tv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_tv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/intel_tv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/intel_tv.c	2010-02-24 13:52:17.000000000 -0500
@@ -1213,20 +1213,17 @@ intel_tv_mode_set(struct drm_encoder *en
 		tv_ctl |= TV_TRILEVEL_SYNC;
 	if (tv_mode->pal_burst)
 		tv_ctl |= TV_PAL_BURST;
+
 	scctl1 = 0;
-	/* dda1 implies valid video levels */
-	if (tv_mode->dda1_inc) {
+	if (tv_mode->dda1_inc)
 		scctl1 |= TV_SC_DDA1_EN;
-	}
-
 	if (tv_mode->dda2_inc)
 		scctl1 |= TV_SC_DDA2_EN;
-
 	if (tv_mode->dda3_inc)
 		scctl1 |= TV_SC_DDA3_EN;
-
 	scctl1 |= tv_mode->sc_reset;
-	scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
+	if (video_levels)
+		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
 	scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
 
 	scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@@ -1416,16 +1413,16 @@ intel_tv_detect_type (struct drm_crtc *c
 	 *  0 0 0 Component
 	 */
 	if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
-		DRM_DEBUG("Detected Composite TV connection\n");
+		DRM_DEBUG_KMS("Detected Composite TV connection\n");
 		type = DRM_MODE_CONNECTOR_Composite;
 	} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
-		DRM_DEBUG("Detected S-Video TV connection\n");
+		DRM_DEBUG_KMS("Detected S-Video TV connection\n");
 		type = DRM_MODE_CONNECTOR_SVIDEO;
 	} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
-		DRM_DEBUG("Detected Component TV connection\n");
+		DRM_DEBUG_KMS("Detected Component TV connection\n");
 		type = DRM_MODE_CONNECTOR_Component;
 	} else {
-		DRM_DEBUG("No TV connection detected\n");
+		DRM_DEBUG_KMS("No TV connection detected\n");
 		type = -1;
 	}
 
@@ -1702,6 +1699,41 @@ static const struct drm_encoder_funcs in
 	.destroy = intel_tv_enc_destroy,
 };
 
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the integrated TV is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the TV is present.
+ */
+static int tv_is_present_in_vbt(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct child_device_config *p_child;
+	int i, ret;
+
+	if (!dev_priv->child_dev_num)
+		return 1;
+
+	ret = 0;
+	for (i = 0; i < dev_priv->child_dev_num; i++) {
+		p_child = dev_priv->child_dev + i;
+		/*
+		 * If the device type is not TV, continue.
+		 */
+		if (p_child->device_type != DEVICE_TYPE_INT_TV &&
+			p_child->device_type != DEVICE_TYPE_TV)
+			continue;
+		/* Only when the addin_offset is non-zero, it is regarded
+		 * as present.
+		 */
+		if (p_child->addin_offset) {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
 
 void
 intel_tv_init(struct drm_device *dev)
@@ -1717,6 +1749,10 @@ intel_tv_init(struct drm_device *dev)
 	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
 		return;
 
+	if (!tv_is_present_in_vbt(dev)) {
+		DRM_DEBUG_KMS("Integrated TV is not present.\n");
+		return;
+	}
 	/* Even if we have an encoder we may not have a connector */
 	if (!dev_priv->int_tv_support)
 		return;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/i915/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/i915/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq
 	  intel_lvds.o \
 	  intel_bios.o \
 	  intel_dp.o \
-	  intel_dp_i2c.o \
 	  intel_hdmi.o \
 	  intel_sdvo.o \
 	  intel_modes.o \
@@ -23,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq
 	  intel_fb.o \
 	  intel_tv.o \
 	  intel_dvo.o \
+	  intel_overlay.o \
 	  dvo_ch7xxx.o \
 	  dvo_ch7017.o \
 	  dvo_ivch.o \
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/Kconfig linux-libre-2.6.33-gnu1/drivers/gpu/drm/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -66,6 +66,8 @@ config DRM_RADEON
 
 	  If M is selected, the module will be called radeon.
 
+source "drivers/gpu/drm/radeon/Kconfig"
+
 config DRM_I810
 	tristate "Intel I810"
 	depends on DRM && AGP && AGP_INTEL
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@ drm-y       :=	drm_auth.o drm_bufs.o drm
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
-drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
+drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
@@ -30,4 +30,7 @@ obj-$(CONFIG_DRM_I830)	+= i830/
 obj-$(CONFIG_DRM_I915)  += i915/
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
+obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
 obj-$(CONFIG_DRM_VIA)	+=via/
+obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
+obj-y			+= i2c/
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/mga/mga_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/mga/mga_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/mga/mga_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/mga/mga_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,7 +68,7 @@ static struct drm_driver driver = {
 		.owner = THIS_MODULE,
 		.open = drm_open,
 		.release = drm_release,
-		.ioctl = drm_ioctl,
+		.unlocked_ioctl = drm_ioctl,
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/mga/mga_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/mga/mga_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/mga/mga_ioc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/mga/mga_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,8 +100,7 @@ static int compat_mga_init(struct file *
 	if (err)
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_MGA_INIT, (unsigned long)init);
+	return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init);
 }
 
 typedef struct drm_mga_getparam32 {
@@ -125,8 +124,7 @@ static int compat_mga_getparam(struct fi
 			  &getparam->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+	return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
 }
 
 typedef struct drm_mga_drm_bootstrap32 {
@@ -166,8 +164,7 @@ static int compat_mga_dma_bootstrap(stru
 	    || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_path.dentry->d_inode, file,
-			DRM_IOCTL_MGA_DMA_BOOTSTRAP,
+	err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP,
 			(unsigned long)dma_bootstrap);
 	if (err)
 		return err;
@@ -220,12 +217,10 @@ long mga_compat_ioctl(struct file *filp,
 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
 		fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-	lock_kernel();		/* XXX for now */
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/Kconfig linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,44 @@
+config DRM_NOUVEAU
+	tristate "Nouveau (nVidia) cards"
+	depends on DRM
+        select FW_LOADER
+	select DRM_KMS_HELPER
+	select DRM_TTM
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB
+	select FRAMEBUFFER_CONSOLE if !EMBEDDED
+	select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
+	help
+	  Choose this option for open-source nVidia support.
+
+config DRM_NOUVEAU_BACKLIGHT
+	bool "Support for backlight control"
+	depends on DRM_NOUVEAU
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display
+	  (e.g. a laptop panel).
+
+config DRM_NOUVEAU_DEBUG
+	bool "Build in Nouveau's debugfs support"
+	depends on DRM_NOUVEAU && DEBUG_FS
+	default y
+	help
+	  Say Y here if you want Nouveau to output debugging information
+	  via debugfs.
+
+menu "I2C encoder or helper chips"
+     depends on DRM && DRM_KMS_HELPER && I2C
+
+config DRM_I2C_CH7006
+	tristate "Chrontel ch7006 TV encoder"
+	default m if DRM_NOUVEAU
+	help
+	  Support for Chrontel ch7006 and similar TV encoders, found
+	  on some nVidia video cards.
+
+	  This driver is currently only useful if you're also using
+	  the nouveau driver.
+endmenu
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+ccflags-y := -Iinclude/drm
+nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
+             nouveau_object.o nouveau_irq.o nouveau_notifier.o \
+             nouveau_sgdma.o nouveau_dma.o \
+             nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
+             nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
+             nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
+             nouveau_dp.o nouveau_grctx.o \
+             nv04_timer.o \
+             nv04_mc.o nv40_mc.o nv50_mc.o \
+             nv04_fb.o nv10_fb.o nv40_fb.o \
+             nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
+             nv04_graph.o nv10_graph.o nv20_graph.o \
+             nv40_graph.o nv50_graph.o \
+             nv40_grctx.o \
+             nv04_instmem.o nv50_instmem.o \
+             nv50_crtc.o nv50_dac.o nv50_sor.o \
+             nv50_cursor.o nv50_display.o nv50_fbcon.o \
+             nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
+             nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
+             nv17_gpio.o
+
+nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
+nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
+nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
+
+obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,125 @@
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nv50_display.h"
+
+#define NOUVEAU_DSM_SUPPORTED 0x00
+#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
+
+#define NOUVEAU_DSM_ACTIVE 0x01
+#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
+
+#define NOUVEAU_DSM_LED 0x02
+#define NOUVEAU_DSM_LED_STATE 0x00
+#define NOUVEAU_DSM_LED_OFF 0x10
+#define NOUVEAU_DSM_LED_STAMINA 0x11
+#define NOUVEAU_DSM_LED_SPEED 0x12
+
+#define NOUVEAU_DSM_POWER 0x03
+#define NOUVEAU_DSM_POWER_STATE 0x00
+#define NOUVEAU_DSM_POWER_SPEED 0x01
+#define NOUVEAU_DSM_POWER_STAMINA 0x02
+
+static int nouveau_dsm(struct drm_device *dev, int func, int arg, int *result)
+{
+	static char muid[] = {
+		0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
+		0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
+	};
+
+	struct pci_dev *pdev = dev->pdev;
+	struct acpi_handle *handle;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_object_list input;
+	union acpi_object params[4];
+	union acpi_object *obj;
+	int err;
+
+	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+
+	if (!handle)
+		return -ENODEV;
+
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = sizeof(muid);
+	params[0].buffer.pointer = (char *)muid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = 0x00000102;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_INTEGER;
+	params[3].integer.value = arg;
+
+	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
+	if (err) {
+		NV_INFO(dev, "failed to evaluate _DSM: %d\n", err);
+		return err;
+	}
+
+	obj = (union acpi_object *)output.pointer;
+
+	if (obj->type == ACPI_TYPE_INTEGER)
+		if (obj->integer.value == 0x80000002)
+			return -ENODEV;
+
+	if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length == 4 && result) {
+			*result = 0;
+			*result |= obj->buffer.pointer[0];
+			*result |= (obj->buffer.pointer[1] << 8);
+			*result |= (obj->buffer.pointer[2] << 16);
+			*result |= (obj->buffer.pointer[3] << 24);
+		}
+	}
+
+	kfree(output.pointer);
+	return 0;
+}
+
+int nouveau_hybrid_setup(struct drm_device *dev)
+{
+	int result;
+
+	if (nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STATE,
+								&result))
+		return -ENODEV;
+
+	NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);
+
+	if (result) { /* Ensure that the external GPU is enabled */
+		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
+		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
+									NULL);
+	} else { /* Stamina mode - disable the external GPU */
+		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
+									NULL);
+		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
+									NULL);
+	}
+
+	return 0;
+}
+
+bool nouveau_dsm_probe(struct drm_device *dev)
+{
+	int support = 0;
+
+	if (nouveau_dsm(dev, NOUVEAU_DSM_SUPPORTED,
+				NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support))
+		return false;
+
+	if (!support)
+		return false;
+
+	return true;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_backlight.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 Red Hat <mjg@redhat.com>
+ *
+ * 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 OWNER(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:
+ *  Matthew Garrett <mjg@redhat.com>
+ *
+ * Register locations derived from NVClock by Roderick Colenbrander
+ */
+
+#include <linux/backlight.h>
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+
+static int nv40_get_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)
+									>> 16;
+
+	return val;
+}
+
+static int nv40_set_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = bd->props.brightness;
+	int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT);
+
+	nv_wr32(dev, NV40_PMC_BACKLIGHT,
+		 (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK));
+
+	return 0;
+}
+
+static struct backlight_ops nv40_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = nv40_get_intensity,
+	.update_status = nv40_set_intensity,
+};
+
+static int nv50_get_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+
+	return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT);
+}
+
+static int nv50_set_intensity(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(bd);
+	int val = bd->props.brightness;
+
+	nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT,
+		val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE);
+	return 0;
+}
+
+static struct backlight_ops nv50_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.get_brightness = nv50_get_intensity,
+	.update_status = nv50_set_intensity,
+};
+
+static int nouveau_nv40_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct backlight_device *bd;
+
+	if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
+		return 0;
+
+	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
+				       &nv40_bl_ops);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
+
+	dev_priv->backlight = bd;
+	bd->props.max_brightness = 31;
+	bd->props.brightness = nv40_get_intensity(bd);
+	backlight_update_status(bd);
+
+	return 0;
+}
+
+static int nouveau_nv50_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct backlight_device *bd;
+
+	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
+		return 0;
+
+	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
+				       &nv50_bl_ops);
+	if (IS_ERR(bd))
+		return PTR_ERR(bd);
+
+	dev_priv->backlight = bd;
+	bd->props.max_brightness = 1025;
+	bd->props.brightness = nv50_get_intensity(bd);
+	backlight_update_status(bd);
+	return 0;
+}
+
+int nouveau_backlight_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	switch (dev_priv->card_type) {
+	case NV_40:
+		return nouveau_nv40_backlight_init(dev);
+	case NV_50:
+		return nouveau_nv50_backlight_init(dev);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void nouveau_backlight_exit(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->backlight) {
+		backlight_device_unregister(dev_priv->backlight);
+		dev_priv->backlight = NULL;
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,6051 @@
+/*
+ * Copyright 2005-2006 Erik Waling
+ * Copyright 2006 Stephane Marchesin
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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"
+#define NV_DEBUG_NOTRACE
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+/* these defines are made up */
+#define NV_CIO_CRE_44_HEADA 0x0
+#define NV_CIO_CRE_44_HEADB 0x3
+#define FEATURE_MOBILE 0x10	/* also FEATURE_QUADRO for BMP */
+#define LEGACY_I2C_CRT 0x80
+#define LEGACY_I2C_PANEL 0x81
+#define LEGACY_I2C_TV 0x82
+
+#define EDID1_LEN 128
+
+#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip->dev, fmt, ##arg)
+#define LOG_OLD_VALUE(x)
+
+#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x))
+#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x))
+
+struct init_exec {
+	bool execute;
+	bool repeat;
+};
+
+static bool nv_cksum(const uint8_t *data, unsigned int length)
+{
+	/*
+	 * There's a few checksums in the BIOS, so here's a generic checking
+	 * function.
+	 */
+	int i;
+	uint8_t sum = 0;
+
+	for (i = 0; i < length; i++)
+		sum += data[i];
+
+	if (sum)
+		return true;
+
+	return false;
+}
+
+static int
+score_vbios(struct drm_device *dev, const uint8_t *data, const bool writeable)
+{
+	if (!(data[0] == 0x55 && data[1] == 0xAA)) {
+		NV_TRACEWARN(dev, "... BIOS signature not found\n");
+		return 0;
+	}
+
+	if (nv_cksum(data, data[2] * 512)) {
+		NV_TRACEWARN(dev, "... BIOS checksum invalid\n");
+		/* if a ro image is somewhat bad, it's probably all rubbish */
+		return writeable ? 2 : 1;
+	} else
+		NV_TRACE(dev, "... appears to be valid\n");
+
+	return 3;
+}
+
+static void load_vbios_prom(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t pci_nv_20, save_pci_nv_20;
+	int pcir_ptr;
+	int i;
+
+	if (dev_priv->card_type >= NV_50)
+		pci_nv_20 = 0x88050;
+	else
+		pci_nv_20 = NV_PBUS_PCI_NV_20;
+
+	/* enable ROM access */
+	save_pci_nv_20 = nvReadMC(dev, pci_nv_20);
+	nvWriteMC(dev, pci_nv_20,
+		  save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
+
+	/* bail if no rom signature */
+	if (nv_rd08(dev, NV_PROM_OFFSET) != 0x55 ||
+	    nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa)
+		goto out;
+
+	/* additional check (see note below) - read PCI record header */
+	pcir_ptr = nv_rd08(dev, NV_PROM_OFFSET + 0x18) |
+		   nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8;
+	if (nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr) != 'P' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 1) != 'C' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 2) != 'I' ||
+	    nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 3) != 'R')
+		goto out;
+
+	/* on some 6600GT/6800LE prom reads are messed up.  nvclock alleges a
+	 * a good read may be obtained by waiting or re-reading (cargocult: 5x)
+	 * each byte.  we'll hope pramin has something usable instead
+	 */
+	for (i = 0; i < NV_PROM_SIZE; i++)
+		data[i] = nv_rd08(dev, NV_PROM_OFFSET + i);
+
+out:
+	/* disable ROM access */
+	nvWriteMC(dev, pci_nv_20,
+		  save_pci_nv_20 | NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
+}
+
+static void load_vbios_pramin(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t old_bar0_pramin = 0;
+	int i;
+
+	if (dev_priv->card_type >= NV_50) {
+		uint32_t vbios_vram = (nv_rd32(dev, 0x619f04) & ~0xff) << 8;
+
+		if (!vbios_vram)
+			vbios_vram = (nv_rd32(dev, 0x1700) << 16) + 0xf0000;
+
+		old_bar0_pramin = nv_rd32(dev, 0x1700);
+		nv_wr32(dev, 0x1700, vbios_vram >> 16);
+	}
+
+	/* bail if no rom signature */
+	if (nv_rd08(dev, NV_PRAMIN_OFFSET) != 0x55 ||
+	    nv_rd08(dev, NV_PRAMIN_OFFSET + 1) != 0xaa)
+		goto out;
+
+	for (i = 0; i < NV_PROM_SIZE; i++)
+		data[i] = nv_rd08(dev, NV_PRAMIN_OFFSET + i);
+
+out:
+	if (dev_priv->card_type >= NV_50)
+		nv_wr32(dev, 0x1700, old_bar0_pramin);
+}
+
+static void load_vbios_pci(struct drm_device *dev, uint8_t *data)
+{
+	void __iomem *rom = NULL;
+	size_t rom_len;
+	int ret;
+
+	ret = pci_enable_rom(dev->pdev);
+	if (ret)
+		return;
+
+	rom = pci_map_rom(dev->pdev, &rom_len);
+	if (!rom)
+		goto out;
+	memcpy_fromio(data, rom, rom_len);
+	pci_unmap_rom(dev->pdev, rom);
+
+out:
+	pci_disable_rom(dev->pdev);
+}
+
+struct methods {
+	const char desc[8];
+	void (*loadbios)(struct drm_device *, uint8_t *);
+	const bool rw;
+};
+
+static struct methods nv04_methods[] = {
+	{ "PROM", load_vbios_prom, false },
+	{ "PRAMIN", load_vbios_pramin, true },
+	{ "PCIROM", load_vbios_pci, true },
+};
+
+static struct methods nv50_methods[] = {
+	{ "PRAMIN", load_vbios_pramin, true },
+	{ "PROM", load_vbios_prom, false },
+	{ "PCIROM", load_vbios_pci, true },
+};
+
+#define METHODCNT 3
+
+static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct methods *methods;
+	int i;
+	int testscore = 3;
+	int scores[METHODCNT];
+
+	if (nouveau_vbios) {
+		methods = nv04_methods;
+		for (i = 0; i < METHODCNT; i++)
+			if (!strcasecmp(nouveau_vbios, methods[i].desc))
+				break;
+
+		if (i < METHODCNT) {
+			NV_INFO(dev, "Attempting to use BIOS image from %s\n",
+				methods[i].desc);
+
+			methods[i].loadbios(dev, data);
+			if (score_vbios(dev, data, methods[i].rw))
+				return true;
+		}
+
+		NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
+	}
+
+	if (dev_priv->card_type < NV_50)
+		methods = nv04_methods;
+	else
+		methods = nv50_methods;
+
+	for (i = 0; i < METHODCNT; i++) {
+		NV_TRACE(dev, "Attempting to load BIOS image from %s\n",
+			 methods[i].desc);
+		data[0] = data[1] = 0;	/* avoid reuse of previous image */
+		methods[i].loadbios(dev, data);
+		scores[i] = score_vbios(dev, data, methods[i].rw);
+		if (scores[i] == testscore)
+			return true;
+	}
+
+	while (--testscore > 0) {
+		for (i = 0; i < METHODCNT; i++) {
+			if (scores[i] == testscore) {
+				NV_TRACE(dev, "Using BIOS image from %s\n",
+					 methods[i].desc);
+				methods[i].loadbios(dev, data);
+				return true;
+			}
+		}
+	}
+
+	NV_ERROR(dev, "No valid BIOS image found\n");
+	return false;
+}
+
+struct init_tbl_entry {
+	char *name;
+	uint8_t id;
+	int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
+};
+
+struct bit_entry {
+	uint8_t id[2];
+	uint16_t length;
+	uint16_t offset;
+};
+
+static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *);
+
+#define MACRO_INDEX_SIZE	2
+#define MACRO_SIZE		8
+#define CONDITION_SIZE		12
+#define IO_FLAG_CONDITION_SIZE	9
+#define IO_CONDITION_SIZE	5
+#define MEM_INIT_SIZE		66
+
+static void still_alive(void)
+{
+#if 0
+	sync();
+	msleep(2);
+#endif
+}
+
+static uint32_t
+munge_reg(struct nvbios *bios, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct dcb_entry *dcbent = bios->display.output;
+
+	if (dev_priv->card_type < NV_50)
+		return reg;
+
+	if (reg & 0x40000000) {
+		BUG_ON(!dcbent);
+
+		reg += (ffs(dcbent->or) - 1) * 0x800;
+		if ((reg & 0x20000000) && !(dcbent->sorconf.link & 1))
+			reg += 0x00000080;
+	}
+
+	reg &= ~0x60000000;
+	return reg;
+}
+
+static int
+valid_reg(struct nvbios *bios, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	/* C51 has misaligned regs on purpose. Marvellous */
+	if (reg & 0x2 ||
+	    (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51))
+		NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg);
+
+	/* warn on C51 regs that haven't been verified accessible in tracing */
+	if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 &&
+	    reg != 0x130d && reg != 0x1311 && reg != 0x60081d)
+		NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n",
+			reg);
+
+	if (reg >= (8*1024*1024)) {
+		NV_ERROR(dev, "=== reg 0x%08x out of mapped bounds ===\n", reg);
+		return 0;
+	}
+
+	return 1;
+}
+
+static bool
+valid_idx_port(struct nvbios *bios, uint16_t port)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	/*
+	 * If adding more ports here, the read/write functions below will need
+	 * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
+	 * used for the port in question
+	 */
+	if (dev_priv->card_type < NV_50) {
+		if (port == NV_CIO_CRX__COLOR)
+			return true;
+		if (port == NV_VIO_SRX)
+			return true;
+	} else {
+		if (port == NV_CIO_CRX__COLOR)
+			return true;
+	}
+
+	NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n",
+		 port);
+
+	return false;
+}
+
+static bool
+valid_port(struct nvbios *bios, uint16_t port)
+{
+	struct drm_device *dev = bios->dev;
+
+	/*
+	 * If adding more ports here, the read/write functions below will need
+	 * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
+	 * used for the port in question
+	 */
+	if (port == NV_VIO_VSE2)
+		return true;
+
+	NV_ERROR(dev, "========== unknown io port 0x%04X ==========\n", port);
+
+	return false;
+}
+
+static uint32_t
+bios_rd32(struct nvbios *bios, uint32_t reg)
+{
+	uint32_t data;
+
+	reg = munge_reg(bios, reg);
+	if (!valid_reg(bios, reg))
+		return 0;
+
+	/*
+	 * C51 sometimes uses regs with bit0 set in the address. For these
+	 * cases there should exist a translation in a BIOS table to an IO
+	 * port address which the BIOS uses for accessing the reg
+	 *
+	 * These only seem to appear for the power control regs to a flat panel,
+	 * and the GPIO regs at 0x60081*.  In C51 mmio traces the normal regs
+	 * for 0x1308 and 0x1310 are used - hence the mask below.  An S3
+	 * suspend-resume mmio trace from a C51 will be required to see if this
+	 * is true for the power microcode in 0x14.., or whether the direct IO
+	 * port access method is needed
+	 */
+	if (reg & 0x1)
+		reg &= ~0x1;
+
+	data = nv_rd32(bios->dev, reg);
+
+	BIOSLOG(bios, "	Read:  Reg: 0x%08X, Data: 0x%08X\n", reg, data);
+
+	return data;
+}
+
+static void
+bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+
+	reg = munge_reg(bios, reg);
+	if (!valid_reg(bios, reg))
+		return;
+
+	/* see note in bios_rd32 */
+	if (reg & 0x1)
+		reg &= 0xfffffffe;
+
+	LOG_OLD_VALUE(bios_rd32(bios, reg));
+	BIOSLOG(bios, "	Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
+
+	if (dev_priv->VBIOS.execute) {
+		still_alive();
+		nv_wr32(bios->dev, reg, data);
+	}
+}
+
+static uint8_t
+bios_idxprt_rd(struct nvbios *bios, uint16_t port, uint8_t index)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+	uint8_t data;
+
+	if (!valid_idx_port(bios, port))
+		return 0;
+
+	if (dev_priv->card_type < NV_50) {
+		if (port == NV_VIO_SRX)
+			data = NVReadVgaSeq(dev, bios->state.crtchead, index);
+		else	/* assume NV_CIO_CRX__COLOR */
+			data = NVReadVgaCrtc(dev, bios->state.crtchead, index);
+	} else {
+		uint32_t data32;
+
+		data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
+		data = (data32 >> ((index & 3) << 3)) & 0xff;
+	}
+
+	BIOSLOG(bios, "	Indexed IO read:  Port: 0x%04X, Index: 0x%02X, "
+		      "Head: 0x%02X, Data: 0x%02X\n",
+		port, index, bios->state.crtchead, data);
+	return data;
+}
+
+static void
+bios_idxprt_wr(struct nvbios *bios, uint16_t port, uint8_t index, uint8_t data)
+{
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	struct drm_device *dev = bios->dev;
+
+	if (!valid_idx_port(bios, port))
+		return;
+
+	/*
+	 * The current head is maintained in the nvbios member  state.crtchead.
+	 * We trap changes to CR44 and update the head variable and hence the
+	 * register set written.
+	 * As CR44 only exists on CRTC0, we update crtchead to head0 in advance
+	 * of the write, and to head1 after the write
+	 */
+	if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 &&
+	    data != NV_CIO_CRE_44_HEADB)
+		bios->state.crtchead = 0;
+
+	LOG_OLD_VALUE(bios_idxprt_rd(bios, port, index));
+	BIOSLOG(bios, "	Indexed IO write: Port: 0x%04X, Index: 0x%02X, "
+		      "Head: 0x%02X, Data: 0x%02X\n",
+		port, index, bios->state.crtchead, data);
+
+	if (bios->execute && dev_priv->card_type < NV_50) {
+		still_alive();
+		if (port == NV_VIO_SRX)
+			NVWriteVgaSeq(dev, bios->state.crtchead, index, data);
+		else	/* assume NV_CIO_CRX__COLOR */
+			NVWriteVgaCrtc(dev, bios->state.crtchead, index, data);
+	} else
+	if (bios->execute) {
+		uint32_t data32, shift = (index & 3) << 3;
+
+		still_alive();
+
+		data32  = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
+		data32 &= ~(0xff << shift);
+		data32 |= (data << shift);
+		bios_wr32(bios, NV50_PDISPLAY_VGACRTC(index & ~3), data32);
+	}
+
+	if (port == NV_CIO_CRX__COLOR &&
+	    index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB)
+		bios->state.crtchead = 1;
+}
+
+static uint8_t
+bios_port_rd(struct nvbios *bios, uint16_t port)
+{
+	uint8_t data, head = bios->state.crtchead;
+
+	if (!valid_port(bios, port))
+		return 0;
+
+	data = NVReadPRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port);
+
+	BIOSLOG(bios, "	IO read:  Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
+		port, head, data);
+
+	return data;
+}
+
+static void
+bios_port_wr(struct nvbios *bios, uint16_t port, uint8_t data)
+{
+	int head = bios->state.crtchead;
+
+	if (!valid_port(bios, port))
+		return;
+
+	LOG_OLD_VALUE(bios_port_rd(bios, port));
+	BIOSLOG(bios, "	IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
+		port, head, data);
+
+	if (!bios->execute)
+		return;
+
+	still_alive();
+	NVWritePRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port, data);
+}
+
+static bool
+io_flag_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The IO flag condition entry has 2 bytes for the CRTC port; 1 byte
+	 * for the CRTC index; 1 byte for the mask to apply to the value
+	 * retrieved from the CRTC; 1 byte for the shift right to apply to the
+	 * masked CRTC value; 2 bytes for the offset to the flag array, to
+	 * which the shifted value is added; 1 byte for the mask applied to the
+	 * value read from the flag array; and 1 byte for the value to compare
+	 * against the masked byte from the flag table.
+	 */
+
+	uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE;
+	uint16_t crtcport = ROM16(bios->data[condptr]);
+	uint8_t crtcindex = bios->data[condptr + 2];
+	uint8_t mask = bios->data[condptr + 3];
+	uint8_t shift = bios->data[condptr + 4];
+	uint16_t flagarray = ROM16(bios->data[condptr + 5]);
+	uint8_t flagarraymask = bios->data[condptr + 7];
+	uint8_t cmpval = bios->data[condptr + 8];
+	uint8_t data;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, "
+		      "Cmpval: 0x%02X\n",
+		offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval);
+
+	data = bios_idxprt_rd(bios, crtcport, crtcindex);
+
+	data = bios->data[flagarray + ((data & mask) >> shift)];
+	data &= flagarraymask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static bool
+bios_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The condition table entry has 4 bytes for the address of the
+	 * register to check, 4 bytes for a mask to apply to the register and
+	 * 4 for a test comparison value
+	 */
+
+	uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE;
+	uint32_t reg = ROM32(bios->data[condptr]);
+	uint32_t mask = ROM32(bios->data[condptr + 4]);
+	uint32_t cmpval = ROM32(bios->data[condptr + 8]);
+	uint32_t data;
+
+	BIOSLOG(bios, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n",
+		offset, cond, reg, mask);
+
+	data = bios_rd32(bios, reg) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static bool
+io_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
+{
+	/*
+	 * The IO condition entry has 2 bytes for the IO port address; 1 byte
+	 * for the index to write to io_port; 1 byte for the mask to apply to
+	 * the byte read from io_port+1; and 1 byte for the value to compare
+	 * against the masked byte.
+	 */
+
+	uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE;
+	uint16_t io_port = ROM16(bios->data[condptr]);
+	uint8_t port_index = bios->data[condptr + 2];
+	uint8_t mask = bios->data[condptr + 3];
+	uint8_t cmpval = bios->data[condptr + 4];
+
+	uint8_t data = bios_idxprt_rd(bios, io_port, port_index) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
+		offset, data, cmpval);
+
+	return (data == cmpval);
+}
+
+static int
+nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t reg0 = nv_rd32(dev, reg + 0);
+	uint32_t reg1 = nv_rd32(dev, reg + 4);
+	struct nouveau_pll_vals pll;
+	struct pll_lims pll_limits;
+	int ret;
+
+	ret = get_pll_limits(dev, reg, &pll_limits);
+	if (ret)
+		return ret;
+
+	clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll);
+	if (!clk)
+		return -ERANGE;
+
+	reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
+	reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
+
+	if (dev_priv->VBIOS.execute) {
+		still_alive();
+		nv_wr32(dev, reg + 4, reg1);
+		nv_wr32(dev, reg + 0, reg0);
+	}
+
+	return 0;
+}
+
+static int
+setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk)
+{
+	struct drm_device *dev = bios->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	/* clk in kHz */
+	struct pll_lims pll_lim;
+	struct nouveau_pll_vals pllvals;
+	int ret;
+
+	if (dev_priv->card_type >= NV_50)
+		return nv50_pll_set(dev, reg, clk);
+
+	/* high regs (such as in the mac g5 table) are not -= 4 */
+	ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim);
+	if (ret)
+		return ret;
+
+	clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals);
+	if (!clk)
+		return -ERANGE;
+
+	if (bios->execute) {
+		still_alive();
+		nouveau_hw_setpll(dev, reg, &pllvals);
+	}
+
+	return 0;
+}
+
+static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	/*
+	 * For the results of this function to be correct, CR44 must have been
+	 * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0,
+	 * and the DCB table parsed, before the script calling the function is
+	 * run.  run_digital_op_script is example of how to do such setup
+	 */
+
+	uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0);
+
+	if (dcb_entry > bios->bdcb.dcb.entries) {
+		NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently "
+				"(%02X)\n", dcb_entry);
+		dcb_entry = 0x7f;	/* unused / invalid marker */
+	}
+
+	return dcb_entry;
+}
+
+static struct nouveau_i2c_chan *
+init_i2c_device_find(struct drm_device *dev, int i2c_index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct bios_parsed_dcb *bdcb = &dev_priv->VBIOS.bdcb;
+
+	if (i2c_index == 0xff) {
+		/* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
+		int idx = dcb_entry_idx_from_crtchead(dev), shift = 0;
+		int default_indices = bdcb->i2c_default_indices;
+
+		if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default)
+			shift = 4;
+
+		i2c_index = (default_indices >> shift) & 0xf;
+	}
+	if (i2c_index == 0x80)	/* g80+ */
+		i2c_index = bdcb->i2c_default_indices & 0xf;
+
+	return nouveau_i2c_find(dev, i2c_index);
+}
+
+static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv)
+{
+	/*
+	 * For mlv < 0x80, it is an index into a table of TMDS base addresses.
+	 * For mlv == 0x80 use the "or" value of the dcb_entry indexed by
+	 * CR58 for CR57 = 0 to index a table of offsets to the basic
+	 * 0x6808b0 address.
+	 * For mlv == 0x81 use the "or" value of the dcb_entry indexed by
+	 * CR58 for CR57 = 0 to index a table of offsets to the basic
+	 * 0x6808b0 address, and then flip the offset by 8.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int pramdac_offset[13] = {
+		0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
+	const uint32_t pramdac_table[4] = {
+		0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 };
+
+	if (mlv >= 0x80) {
+		int dcb_entry, dacoffset;
+
+		/* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
+		dcb_entry = dcb_entry_idx_from_crtchead(dev);
+		if (dcb_entry == 0x7f)
+			return 0;
+		dacoffset = pramdac_offset[
+				dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or];
+		if (mlv == 0x81)
+			dacoffset ^= 8;
+		return 0x6808b0 + dacoffset;
+	} else {
+		if (mlv > ARRAY_SIZE(pramdac_table)) {
+			NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n",
+									mlv);
+			return 0;
+		}
+		return pramdac_table[mlv];
+	}
+}
+
+static int
+init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PROG   opcode: 0x32 ('2')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): register
+	 * offset + 11 (32 bit): configuration 1
+	 * ...
+	 *
+	 * Starting at offset + 11 there are "count" 32 bit values.
+	 * To find out which value to use read index "CRTC index" on "CRTC
+	 * port", AND this value with "mask" and then bit shift right "shift"
+	 * bits.  Read the appropriate value using this index and write to
+	 * "register"
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t reg = ROM32(bios->data[offset + 7]);
+	uint8_t config;
+	uint32_t configval;
+	int len = 11 + count * 4;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift, count, reg);
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return 0;
+	}
+
+	configval = ROM32(bios->data[offset + 11 + config * 4]);
+
+	BIOSLOG(bios, "0x%04X: Writing config %02X\n", offset, config);
+
+	bios_wr32(bios, reg, configval);
+
+	return len;
+}
+
+static int
+init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_REPEAT   opcode: 0x33 ('3')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): count
+	 *
+	 * Execute script following this opcode up to INIT_REPEAT_END
+	 * "count" times
+	 */
+
+	uint8_t count = bios->data[offset + 1];
+	uint8_t i;
+
+	/* no iexec->execute check by design */
+
+	BIOSLOG(bios, "0x%04X: Repeating following segment %d times\n",
+		offset, count);
+
+	iexec->repeat = true;
+
+	/*
+	 * count - 1, as the script block will execute once when we leave this
+	 * opcode -- this is compatible with bios behaviour as:
+	 * a) the block is always executed at least once, even if count == 0
+	 * b) the bios interpreter skips to the op following INIT_END_REPEAT,
+	 * while we don't
+	 */
+	for (i = 0; i < count - 1; i++)
+		parse_init_table(bios, offset + 2, iexec);
+
+	iexec->repeat = false;
+
+	return 2;
+}
+
+static int
+init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
+		     struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PLL   opcode: 0x34 ('4')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): IO flag condition index
+	 * offset + 7  (8  bit): count
+	 * offset + 8  (32 bit): register
+	 * offset + 12 (16 bit): frequency 1
+	 * ...
+	 *
+	 * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz).
+	 * Set PLL register "register" to coefficients for frequency n,
+	 * selected by reading index "CRTC index" of "CRTC port" ANDed with
+	 * "mask" and shifted right by "shift".
+	 *
+	 * If "IO flag condition index" > 0, and condition met, double
+	 * frequency before setting it.
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	int8_t io_flag_condition_idx = bios->data[offset + 6];
+	uint8_t count = bios->data[offset + 7];
+	uint32_t reg = ROM32(bios->data[offset + 8]);
+	uint8_t config;
+	uint16_t freq;
+	int len = 12 + count * 2;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, IO Flag Condition: 0x%02X, "
+		      "Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift,
+		io_flag_condition_idx, count, reg);
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return 0;
+	}
+
+	freq = ROM16(bios->data[offset + 12 + config * 2]);
+
+	if (io_flag_condition_idx > 0) {
+		if (io_flag_condition_met(bios, offset, io_flag_condition_idx)) {
+			BIOSLOG(bios, "0x%04X: Condition fulfilled -- "
+				      "frequency doubled\n", offset);
+			freq *= 2;
+		} else
+			BIOSLOG(bios, "0x%04X: Condition not fulfilled -- "
+				      "frequency unchanged\n", offset);
+	}
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n",
+		offset, reg, config, freq);
+
+	setPLL(bios, reg, freq * 10);
+
+	return len;
+}
+
+static int
+init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_END_REPEAT   opcode: 0x36 ('6')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Marks the end of the block for INIT_REPEAT to repeat
+	 */
+
+	/* no iexec->execute check by design */
+
+	/*
+	 * iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when
+	 * we're not in repeat mode
+	 */
+	if (iexec->repeat)
+		return 0;
+
+	return 1;
+}
+
+static int
+init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY   opcode: 0x37 ('7')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): srcmask
+	 * offset + 7  (16 bit): CRTC port
+	 * offset + 9  (8 bit): CRTC index
+	 * offset + 10  (8 bit): mask
+	 *
+	 * Read index "CRTC index" on "CRTC port", AND with "mask", OR with
+	 * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC
+	 * port
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t srcmask = bios->data[offset + 6];
+	uint16_t crtcport = ROM16(bios->data[offset + 7]);
+	uint8_t crtcindex = bios->data[offset + 9];
+	uint8_t mask = bios->data[offset + 10];
+	uint32_t data;
+	uint8_t crtcdata;
+
+	if (!iexec->execute)
+		return 11;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, "
+		      "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n",
+		offset, reg, shift, srcmask, crtcport, crtcindex, mask);
+
+	data = bios_rd32(bios, reg);
+
+	if (shift < 0x80)
+		data >>= shift;
+	else
+		data <<= (0x100 - shift);
+
+	data &= srcmask;
+
+	crtcdata  = bios_idxprt_rd(bios, crtcport, crtcindex) & mask;
+	crtcdata |= (uint8_t)data;
+	bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata);
+
+	return 11;
+}
+
+static int
+init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_NOT   opcode: 0x38 ('8')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * Invert the current execute / no-execute condition (i.e. "else")
+	 */
+	if (iexec->execute)
+		BIOSLOG(bios, "0x%04X: ------ Skipping following commands  ------\n", offset);
+	else
+		BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset);
+
+	iexec->execute = !iexec->execute;
+	return 1;
+}
+
+static int
+init_io_flag_condition(struct nvbios *bios, uint16_t offset,
+		       struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_FLAG_CONDITION   opcode: 0x39 ('9')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the IO flag condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return 2;
+
+	if (io_flag_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return 2;
+}
+
+static int
+init_idx_addr_latched(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_INDEX_ADDRESS_LATCHED   opcode: 0x49 ('I')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): control register
+	 * offset + 5  (32 bit): data register
+	 * offset + 9  (32 bit): mask
+	 * offset + 13 (32 bit): data
+	 * offset + 17 (8  bit): count
+	 * offset + 18 (8  bit): address 1
+	 * offset + 19 (8  bit): data 1
+	 * ...
+	 *
+	 * For each of "count" address and data pairs, write "data n" to
+	 * "data register", read the current value of "control register",
+	 * and write it back once ANDed with "mask", ORed with "data",
+	 * and ORed with "address n"
+	 */
+
+	uint32_t controlreg = ROM32(bios->data[offset + 1]);
+	uint32_t datareg = ROM32(bios->data[offset + 5]);
+	uint32_t mask = ROM32(bios->data[offset + 9]);
+	uint32_t data = ROM32(bios->data[offset + 13]);
+	uint8_t count = bios->data[offset + 17];
+	int len = 18 + count * 2;
+	uint32_t value;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, "
+		      "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n",
+		offset, controlreg, datareg, mask, data, count);
+
+	for (i = 0; i < count; i++) {
+		uint8_t instaddress = bios->data[offset + 18 + i * 2];
+		uint8_t instdata = bios->data[offset + 19 + i * 2];
+
+		BIOSLOG(bios, "0x%04X: Address: 0x%02X, Data: 0x%02X\n",
+			offset, instaddress, instdata);
+
+		bios_wr32(bios, datareg, instdata);
+		value  = bios_rd32(bios, controlreg) & mask;
+		value |= data;
+		value |= instaddress;
+		bios_wr32(bios, controlreg, value);
+	}
+
+	return len;
+}
+
+static int
+init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_RESTRICT_PLL2   opcode: 0x4A ('J')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): register
+	 * offset + 11 (32 bit): frequency 1
+	 * ...
+	 *
+	 * Starting at offset + 11 there are "count" 32 bit frequencies (kHz).
+	 * Set PLL register "register" to coefficients for frequency n,
+	 * selected by reading index "CRTC index" of "CRTC port" ANDed with
+	 * "mask" and shifted right by "shift".
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t shift = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t reg = ROM32(bios->data[offset + 7]);
+	int len = 11 + count * 4;
+	uint8_t config;
+	uint32_t freq;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
+		offset, crtcport, crtcindex, mask, shift, count, reg);
+
+	if (!reg)
+		return len;
+
+	config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
+	if (config > count) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
+			 offset, config, count);
+		return 0;
+	}
+
+	freq = ROM32(bios->data[offset + 11 + config * 4]);
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n",
+		offset, reg, config, freq);
+
+	setPLL(bios, reg, freq);
+
+	return len;
+}
+
+static int
+init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_PLL2   opcode: 0x4B ('K')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): freq
+	 *
+	 * Set PLL register "register" to coefficients for frequency "freq"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t freq = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return 9;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n",
+		offset, reg, freq);
+
+	setPLL(bios, reg, freq);
+	return 9;
+}
+
+static int
+init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_I2C_BYTE   opcode: 0x4C ('L')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): I2C register 1
+	 * offset + 5  (8 bit): mask 1
+	 * offset + 6  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" registers given by "I2C register n" on the device
+	 * addressed by "I2C slave address" on the I2C bus given by
+	 * "DCB I2C table entry index", read the register, AND the result with
+	 * "mask n" and OR it with "data n" before writing it back to the device
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	int len = 4 + count * 3;
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		uint8_t i2c_reg = bios->data[offset + 4 + i * 3];
+		uint8_t mask = bios->data[offset + 5 + i * 3];
+		uint8_t data = bios->data[offset + 6 + i * 3];
+		uint8_t value;
+
+		msg.addr = i2c_address;
+		msg.flags = I2C_M_RD;
+		msg.len = 1;
+		msg.buf = &value;
+		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+			return 0;
+
+		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
+			      "Mask: 0x%02X, Data: 0x%02X\n",
+			offset, i2c_reg, value, mask, data);
+
+		value = (value & mask) | data;
+
+		if (bios->execute) {
+			msg.addr = i2c_address;
+			msg.flags = 0;
+			msg.len = 1;
+			msg.buf = &value;
+			if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+				return 0;
+		}
+	}
+
+	return len;
+}
+
+static int
+init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_I2C_BYTE   opcode: 0x4D ('M')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): I2C register 1
+	 * offset + 5  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" registers given by "I2C register n" on the device
+	 * addressed by "I2C slave address" on the I2C bus given by
+	 * "DCB I2C table entry index", set the register to "data n"
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	int len = 4 + count * 2;
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		uint8_t i2c_reg = bios->data[offset + 4 + i * 2];
+		uint8_t data = bios->data[offset + 5 + i * 2];
+
+		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
+			offset, i2c_reg, data);
+
+		if (bios->execute) {
+			msg.addr = i2c_address;
+			msg.flags = 0;
+			msg.len = 1;
+			msg.buf = &data;
+			if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+				return 0;
+		}
+	}
+
+	return len;
+}
+
+static int
+init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_I2C   opcode: 0x4E ('N')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): DCB I2C table entry index
+	 * offset + 2  (8 bit): I2C slave address
+	 * offset + 3  (8 bit): count
+	 * offset + 4  (8 bit): data 1
+	 * ...
+	 *
+	 * Send "count" bytes ("data n") to the device addressed by "I2C slave
+	 * address" on the I2C bus given by "DCB I2C table entry index"
+	 */
+
+	uint8_t i2c_index = bios->data[offset + 1];
+	uint8_t i2c_address = bios->data[offset + 2];
+	uint8_t count = bios->data[offset + 3];
+	int len = 4 + count;
+	struct nouveau_i2c_chan *chan;
+	struct i2c_msg msg;
+	uint8_t data[256];
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, i2c_index, i2c_address, count);
+
+	chan = init_i2c_device_find(bios->dev, i2c_index);
+	if (!chan)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		data[i] = bios->data[offset + 4 + i];
+
+		BIOSLOG(bios, "0x%04X: Data: 0x%02X\n", offset, data[i]);
+	}
+
+	if (bios->execute) {
+		msg.addr = i2c_address;
+		msg.flags = 0;
+		msg.len = count;
+		msg.buf = data;
+		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
+			return 0;
+	}
+
+	return len;
+}
+
+static int
+init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_TMDS   opcode: 0x4F ('O')	(non-canon name)
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): magic lookup value
+	 * offset + 2  (8 bit): TMDS address
+	 * offset + 3  (8 bit): mask
+	 * offset + 4  (8 bit): data
+	 *
+	 * Read the data reg for TMDS address "TMDS address", AND it with mask
+	 * and OR it with data, then write it back
+	 * "magic lookup value" determines which TMDS base address register is
+	 * used -- see get_tmds_index_reg()
+	 */
+
+	uint8_t mlv = bios->data[offset + 1];
+	uint32_t tmdsaddr = bios->data[offset + 2];
+	uint8_t mask = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+	uint32_t reg, value;
+
+	if (!iexec->execute)
+		return 5;
+
+	BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, "
+		      "Mask: 0x%02X, Data: 0x%02X\n",
+		offset, mlv, tmdsaddr, mask, data);
+
+	reg = get_tmds_index_reg(bios->dev, mlv);
+	if (!reg)
+		return 0;
+
+	bios_wr32(bios, reg,
+		  tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
+	value = (bios_rd32(bios, reg + 4) & mask) | data;
+	bios_wr32(bios, reg + 4, value);
+	bios_wr32(bios, reg, tmdsaddr);
+
+	return 5;
+}
+
+static int
+init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_TMDS_GROUP   opcode: 0x50 ('P')	(non-canon name)
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): magic lookup value
+	 * offset + 2  (8 bit): count
+	 * offset + 3  (8 bit): addr 1
+	 * offset + 4  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" TMDS address and data pairs write "data n" to
+	 * "addr n".  "magic lookup value" determines which TMDS base address
+	 * register is used -- see get_tmds_index_reg()
+	 */
+
+	uint8_t mlv = bios->data[offset + 1];
+	uint8_t count = bios->data[offset + 2];
+	int len = 3 + count * 2;
+	uint32_t reg;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n",
+		offset, mlv, count);
+
+	reg = get_tmds_index_reg(bios->dev, mlv);
+	if (!reg)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
+		uint8_t tmdsdata = bios->data[offset + 4 + i * 2];
+
+		bios_wr32(bios, reg + 4, tmdsdata);
+		bios_wr32(bios, reg, tmdsaddr);
+	}
+
+	return len;
+}
+
+static int
+init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_CR_INDEX_ADDRESS_LATCHED   opcode: 0x51 ('Q')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): CRTC index1
+	 * offset + 2  (8 bit): CRTC index2
+	 * offset + 3  (8 bit): baseaddr
+	 * offset + 4  (8 bit): count
+	 * offset + 5  (8 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" address and data pairs, write "baseaddr + n" to
+	 * "CRTC index1" and "data n" to "CRTC index2"
+	 * Once complete, restore initial value read from "CRTC index1"
+	 */
+	uint8_t crtcindex1 = bios->data[offset + 1];
+	uint8_t crtcindex2 = bios->data[offset + 2];
+	uint8_t baseaddr = bios->data[offset + 3];
+	uint8_t count = bios->data[offset + 4];
+	int len = 5 + count;
+	uint8_t oldaddr, data;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, "
+		      "BaseAddr: 0x%02X, Count: 0x%02X\n",
+		offset, crtcindex1, crtcindex2, baseaddr, count);
+
+	oldaddr = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex1);
+
+	for (i = 0; i < count; i++) {
+		bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1,
+				     baseaddr + i);
+		data = bios->data[offset + 5 + i];
+		bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex2, data);
+	}
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr);
+
+	return len;
+}
+
+static int
+init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_CR   opcode: 0x52 ('R')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (8  bit): CRTC index
+	 * offset + 2  (8  bit): mask
+	 * offset + 3  (8  bit): data
+	 *
+	 * Assign the value of at "CRTC index" ANDed with mask and ORed with
+	 * data back to "CRTC index"
+	 */
+
+	uint8_t crtcindex = bios->data[offset + 1];
+	uint8_t mask = bios->data[offset + 2];
+	uint8_t data = bios->data[offset + 3];
+	uint8_t value;
+
+	if (!iexec->execute)
+		return 4;
+
+	BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
+		offset, crtcindex, mask, data);
+
+	value  = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex) & mask;
+	value |= data;
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value);
+
+	return 4;
+}
+
+static int
+init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_CR   opcode: 0x53 ('S')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): CRTC index
+	 * offset + 2  (8 bit): value
+	 *
+	 * Assign "value" to CRTC register with index "CRTC index".
+	 */
+
+	uint8_t crtcindex = ROM32(bios->data[offset + 1]);
+	uint8_t data = bios->data[offset + 2];
+
+	if (!iexec->execute)
+		return 3;
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data);
+
+	return 3;
+}
+
+static int
+init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_CR_GROUP   opcode: 0x54 ('T')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): count
+	 * offset + 2  (8 bit): CRTC index 1
+	 * offset + 3  (8 bit): value 1
+	 * ...
+	 *
+	 * For "count", assign "value n" to CRTC register with index
+	 * "CRTC index n".
+	 */
+
+	uint8_t count = bios->data[offset + 1];
+	int len = 2 + count * 2;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	for (i = 0; i < count; i++)
+		init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec);
+
+	return len;
+}
+
+static int
+init_condition_time(struct nvbios *bios, uint16_t offset,
+		    struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONDITION_TIME   opcode: 0x56 ('V')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 * offset + 2  (8 bit): retries / 50
+	 *
+	 * Check condition "condition number" in the condition table.
+	 * Bios code then sleeps for 2ms if the condition is not met, and
+	 * repeats up to "retries" times, but on one C51 this has proved
+	 * insufficient.  In mmiotraces the driver sleeps for 20ms, so we do
+	 * this, and bail after "retries" times, or 2s, whichever is less.
+	 * If still not met after retries, clear execution flag for this table.
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+	uint16_t retries = bios->data[offset + 2] * 50;
+	unsigned cnt;
+
+	if (!iexec->execute)
+		return 3;
+
+	if (retries > 100)
+		retries = 100;
+
+	BIOSLOG(bios, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n",
+		offset, cond, retries);
+
+	if (!bios->execute) /* avoid 2s delays when "faking" execution */
+		retries = 1;
+
+	for (cnt = 0; cnt < retries; cnt++) {
+		if (bios_condition_met(bios, offset, cond)) {
+			BIOSLOG(bios, "0x%04X: Condition met, continuing\n",
+								offset);
+			break;
+		} else {
+			BIOSLOG(bios, "0x%04X: "
+				"Condition not met, sleeping for 20ms\n",
+								offset);
+			msleep(20);
+		}
+	}
+
+	if (!bios_condition_met(bios, offset, cond)) {
+		NV_WARN(bios->dev,
+			"0x%04X: Condition still not met after %dms, "
+			"skipping following opcodes\n", offset, 20 * retries);
+		iexec->execute = false;
+	}
+
+	return 3;
+}
+
+static int
+init_zm_reg_sequence(struct nvbios *bios, uint16_t offset,
+		     struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG_SEQUENCE   opcode: 0x58 ('X')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): base register
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (32 bit): value 1
+	 * ...
+	 *
+	 * Starting at offset + 6 there are "count" 32 bit values.
+	 * For "count" iterations set "base register" + 4 * current_iteration
+	 * to "value current_iteration"
+	 */
+
+	uint32_t basereg = ROM32(bios->data[offset + 1]);
+	uint32_t count = bios->data[offset + 5];
+	int len = 6 + count * 4;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n",
+		offset, basereg, count);
+
+	for (i = 0; i < count; i++) {
+		uint32_t reg = basereg + i * 4;
+		uint32_t data = ROM32(bios->data[offset + 6 + i * 4]);
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return len;
+}
+
+static int
+init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_SUB_DIRECT   opcode: 0x5B ('[')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): subroutine offset (in bios)
+	 *
+	 * Calls a subroutine that will execute commands until INIT_DONE
+	 * is found.
+	 */
+
+	uint16_t sub_offset = ROM16(bios->data[offset + 1]);
+
+	if (!iexec->execute)
+		return 3;
+
+	BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n",
+		offset, sub_offset);
+
+	parse_init_table(bios, sub_offset, iexec);
+
+	BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset);
+
+	return 3;
+}
+
+static int
+init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY_NV_REG   opcode: 0x5F ('_')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): src reg
+	 * offset + 5  (8  bit): shift
+	 * offset + 6  (32 bit): src mask
+	 * offset + 10 (32 bit): xor
+	 * offset + 14 (32 bit): dst reg
+	 * offset + 18 (32 bit): dst mask
+	 *
+	 * Shift REGVAL("src reg") right by (signed) "shift", AND result with
+	 * "src mask", then XOR with "xor". Write this OR'd with
+	 * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg"
+	 */
+
+	uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1]));
+	uint8_t shift = bios->data[offset + 5];
+	uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6]));
+	uint32_t xor = *((uint32_t *)(&bios->data[offset + 10]));
+	uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14]));
+	uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18]));
+	uint32_t srcvalue, dstvalue;
+
+	if (!iexec->execute)
+		return 22;
+
+	BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, "
+		      "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n",
+		offset, srcreg, shift, srcmask, xor, dstreg, dstmask);
+
+	srcvalue = bios_rd32(bios, srcreg);
+
+	if (shift < 0x80)
+		srcvalue >>= shift;
+	else
+		srcvalue <<= (0x100 - shift);
+
+	srcvalue = (srcvalue & srcmask) ^ xor;
+
+	dstvalue = bios_rd32(bios, dstreg) & dstmask;
+
+	bios_wr32(bios, dstreg, dstvalue | srcvalue);
+
+	return 22;
+}
+
+static int
+init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_INDEX_IO   opcode: 0x62 ('b')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): data
+	 *
+	 * Write "data" to index "CRTC index" of "CRTC port"
+	 */
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+
+	if (!iexec->execute)
+		return 5;
+
+	bios_idxprt_wr(bios, crtcport, crtcindex, data);
+
+	return 5;
+}
+
+static int
+init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COMPUTE_MEM   opcode: 0x63 ('c')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
+	 * that the hardware can correctly calculate how much VRAM it has
+	 * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
+	 *
+	 * The implementation of this opcode in general consists of two parts:
+	 * 1) determination of the memory bus width
+	 * 2) determination of how many of the card's RAM pads have ICs attached
+	 *
+	 * 1) is done by a cunning combination of writes to offsets 0x1c and
+	 * 0x3c in the framebuffer, and seeing whether the written values are
+	 * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
+	 *
+	 * 2) is done by a cunning combination of writes to an offset slightly
+	 * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
+	 * if the test pattern can be read back. This then affects bits 12-15 of
+	 * NV_PFB_CFG0
+	 *
+	 * In this context a "cunning combination" may include multiple reads
+	 * and writes to varying locations, often alternating the test pattern
+	 * and 0, doubtless to make sure buffers are filled, residual charges
+	 * on tracks are removed etc.
+	 *
+	 * Unfortunately, the "cunning combination"s mentioned above, and the
+	 * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
+	 * trace I have.
+	 *
+	 * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
+	 * we started was correct, and use that instead
+	 */
+
+	/* no iexec->execute check by design */
+
+	/*
+	 * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS
+	 * and kmmio traces of the binary driver POSTing the card show nothing
+	 * being done for this opcode.  why is it still listed in the table?!
+	 */
+
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_40)
+		return 1;
+
+	/*
+	 * On every card I've seen, this step gets done for us earlier in
+	 * the init scripts
+	uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01);
+	bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20);
+	 */
+
+	/*
+	 * This also has probably been done in the scripts, but an mmio trace of
+	 * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
+	 */
+	bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
+
+	/* write back the saved configuration value */
+	bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0);
+
+	return 1;
+}
+
+static int
+init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESET   opcode: 0x65 ('e')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): value1
+	 * offset + 9  (32 bit): value2
+	 *
+	 * Assign "value1" to "register", then assign "value2" to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t value1 = ROM32(bios->data[offset + 5]);
+	uint32_t value2 = ROM32(bios->data[offset + 9]);
+	uint32_t pci_nv_19, pci_nv_20;
+
+	/* no iexec->execute check by design */
+
+	pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
+	bios_wr32(bios, NV_PBUS_PCI_NV_19, 0);
+	bios_wr32(bios, reg, value1);
+
+	udelay(10);
+
+	bios_wr32(bios, reg, value2);
+	bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19);
+
+	pci_nv_20 = bios_rd32(bios, NV_PBUS_PCI_NV_20);
+	pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;	/* 0xfffffffe */
+	bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20);
+
+	return 13;
+}
+
+static int
+init_configure_mem(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_MEM   opcode: 0x66 ('f')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, sets up the memory registers, using values
+	 * taken from the memory init table
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
+	uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6;
+	uint32_t reg, data;
+
+	if (bios->major_version > 2)
+		return 0;
+
+	bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
+		       bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
+
+	if (bios->data[meminitoffs] & 1)
+		seqtbloffs = bios->legacy.ddr_seq_tbl_ptr;
+
+	for (reg = ROM32(bios->data[seqtbloffs]);
+	     reg != 0xffffffff;
+	     reg = ROM32(bios->data[seqtbloffs += 4])) {
+
+		switch (reg) {
+		case NV_PFB_PRE:
+			data = NV_PFB_PRE_CMD_PRECHARGE;
+			break;
+		case NV_PFB_PAD:
+			data = NV_PFB_PAD_CKE_NORMAL;
+			break;
+		case NV_PFB_REF:
+			data = NV_PFB_REF_CMD_REFRESH;
+			break;
+		default:
+			data = ROM32(bios->data[meminitdata]);
+			meminitdata += 4;
+			if (data == 0xffffffff)
+				continue;
+		}
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return 1;
+}
+
+static int
+init_configure_clk(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_CLK   opcode: 0x67 ('g')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, sets up the NVClk and MClk PLLs, using
+	 * values taken from the memory init table
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
+	int clock;
+
+	if (bios->major_version > 2)
+		return 0;
+
+	clock = ROM16(bios->data[meminitoffs + 4]) * 10;
+	setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
+
+	clock = ROM16(bios->data[meminitoffs + 2]) * 10;
+	if (bios->data[meminitoffs] & 1) /* DDR */
+		clock *= 2;
+	setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock);
+
+	return 1;
+}
+
+static int
+init_configure_preinit(struct nvbios *bios, uint16_t offset,
+		       struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONFIGURE_PREINIT   opcode: 0x68 ('h')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Equivalent to INIT_DONE on bios version 3 or greater.
+	 * For early bios versions, does early init, loading ram and crystal
+	 * configuration from straps into CR3C
+	 */
+
+	/* no iexec->execute check by design */
+
+	uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
+	uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
+
+	if (bios->major_version > 2)
+		return 0;
+
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
+			     NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
+
+	return 1;
+}
+
+static int
+init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO   opcode: 0x69 ('i')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): mask
+	 * offset + 4  (8  bit): data
+	 *
+	 * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port"
+	 */
+
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t mask = bios->data[offset + 3];
+	uint8_t data = bios->data[offset + 4];
+
+	if (!iexec->execute)
+		return 5;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n",
+		offset, crtcport, mask, data);
+
+	/*
+	 * I have no idea what this does, but NVIDIA do this magic sequence
+	 * in the places where this INIT_IO happens..
+	 */
+	if (dev_priv->card_type >= NV_50 && crtcport == 0x3c3 && data == 1) {
+		int i;
+
+		bios_wr32(bios, 0x614100, (bios_rd32(
+			  bios, 0x614100) & 0x0fffffff) | 0x00800000);
+
+		bios_wr32(bios, 0x00e18c, bios_rd32(
+			  bios, 0x00e18c) | 0x00020000);
+
+		bios_wr32(bios, 0x614900, (bios_rd32(
+			  bios, 0x614900) & 0x0fffffff) | 0x00800000);
+
+		bios_wr32(bios, 0x000200, bios_rd32(
+			  bios, 0x000200) & ~0x40000000);
+
+		mdelay(10);
+
+		bios_wr32(bios, 0x00e18c, bios_rd32(
+			  bios, 0x00e18c) & ~0x00020000);
+
+		bios_wr32(bios, 0x000200, bios_rd32(
+			  bios, 0x000200) | 0x40000000);
+
+		bios_wr32(bios, 0x614100, 0x00800018);
+		bios_wr32(bios, 0x614900, 0x00800018);
+
+		mdelay(10);
+
+		bios_wr32(bios, 0x614100, 0x10000018);
+		bios_wr32(bios, 0x614900, 0x10000018);
+
+		for (i = 0; i < 3; i++)
+			bios_wr32(bios, 0x614280 + (i*0x800), bios_rd32(
+				  bios, 0x614280 + (i*0x800)) & 0xf0f0f0f0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614300 + (i*0x800), bios_rd32(
+				  bios, 0x614300 + (i*0x800)) & 0xfffff0f0);
+
+		for (i = 0; i < 3; i++)
+			bios_wr32(bios, 0x614380 + (i*0x800), bios_rd32(
+				  bios, 0x614380 + (i*0x800)) & 0xfffff0f0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614200 + (i*0x800), bios_rd32(
+				  bios, 0x614200 + (i*0x800)) & 0xfffffff0);
+
+		for (i = 0; i < 2; i++)
+			bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32(
+				  bios, 0x614108 + (i*0x800)) & 0x0fffffff);
+		return 5;
+	}
+
+	bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) |
+									data);
+	return 5;
+}
+
+static int
+init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_SUB   opcode: 0x6B ('k')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): script number
+	 *
+	 * Execute script number "script number", as a subroutine
+	 */
+
+	uint8_t sub = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return 2;
+
+	BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub);
+
+	parse_init_table(bios,
+			 ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]),
+			 iexec);
+
+	BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub);
+
+	return 2;
+}
+
+static int
+init_ram_condition(struct nvbios *bios, uint16_t offset,
+		   struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_CONDITION   opcode: 0x6D ('m')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): mask
+	 * offset + 2  (8 bit): cmpval
+	 *
+	 * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t mask = bios->data[offset + 1];
+	uint8_t cmpval = bios->data[offset + 2];
+	uint8_t data;
+
+	if (!iexec->execute)
+		return 3;
+
+	data = bios_rd32(bios, NV_PFB_BOOT_0) & mask;
+
+	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
+		offset, data, cmpval);
+
+	if (data == cmpval)
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return 3;
+}
+
+static int
+init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_NV_REG   opcode: 0x6E ('n')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): mask
+	 * offset + 9  (32 bit): data
+	 *
+	 * Assign ((REGVAL("register") & "mask") | "data") to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t mask = ROM32(bios->data[offset + 5]);
+	uint32_t data = ROM32(bios->data[offset + 9]);
+
+	if (!iexec->execute)
+		return 13;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n",
+		offset, reg, mask, data);
+
+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data);
+
+	return 13;
+}
+
+static int
+init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_MACRO   opcode: 0x6F ('o')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): macro number
+	 *
+	 * Look up macro index "macro number" in the macro index table.
+	 * The macro index table entry has 1 byte for the index in the macro
+	 * table, and 1 byte for the number of times to repeat the macro.
+	 * The macro table entry has 4 bytes for the register address and
+	 * 4 bytes for the value to write to that register
+	 */
+
+	uint8_t macro_index_tbl_idx = bios->data[offset + 1];
+	uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE);
+	uint8_t macro_tbl_idx = bios->data[tmp];
+	uint8_t count = bios->data[tmp + 1];
+	uint32_t reg, data;
+	int i;
+
+	if (!iexec->execute)
+		return 2;
+
+	BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, "
+		      "Count: 0x%02X\n",
+		offset, macro_index_tbl_idx, macro_tbl_idx, count);
+
+	for (i = 0; i < count; i++) {
+		uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE;
+
+		reg = ROM32(bios->data[macroentryptr]);
+		data = ROM32(bios->data[macroentryptr + 4]);
+
+		bios_wr32(bios, reg, data);
+	}
+
+	return 2;
+}
+
+static int
+init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_DONE   opcode: 0x71 ('q')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * End the current script
+	 */
+
+	/* mild retval abuse to stop parsing this table */
+	return 0;
+}
+
+static int
+init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESUME   opcode: 0x72 ('r')
+	 *
+	 * offset      (8  bit): opcode
+	 *
+	 * End the current execute / no-execute condition
+	 */
+
+	if (iexec->execute)
+		return 1;
+
+	iexec->execute = true;
+	BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset);
+
+	return 1;
+}
+
+static int
+init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_TIME   opcode: 0x74 ('t')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): time
+	 *
+	 * Sleep for "time" microseconds.
+	 */
+
+	unsigned time = ROM16(bios->data[offset + 1]);
+
+	if (!iexec->execute)
+		return 3;
+
+	BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n",
+		offset, time);
+
+	if (time < 1000)
+		udelay(time);
+	else
+		msleep((time + 900) / 1000);
+
+	return 3;
+}
+
+static int
+init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_CONDITION   opcode: 0x75 ('u')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return 2;
+
+	BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond);
+
+	if (bios_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return 2;
+}
+
+static int
+init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_IO_CONDITION  opcode: 0x76
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): condition number
+	 *
+	 * Check condition "condition number" in the io condition table.
+	 * If condition not met skip subsequent opcodes until condition is
+	 * inverted (INIT_NOT), or we hit INIT_RESUME
+	 */
+
+	uint8_t cond = bios->data[offset + 1];
+
+	if (!iexec->execute)
+		return 2;
+
+	BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond);
+
+	if (io_condition_met(bios, offset, cond))
+		BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
+	else {
+		BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
+		iexec->execute = false;
+	}
+
+	return 2;
+}
+
+static int
+init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_INDEX_IO   opcode: 0x78 ('x')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (16 bit): CRTC port
+	 * offset + 3  (8  bit): CRTC index
+	 * offset + 4  (8  bit): mask
+	 * offset + 5  (8  bit): data
+	 *
+	 * Read value at index "CRTC index" on "CRTC port", AND with "mask",
+	 * OR with "data", write-back
+	 */
+
+	uint16_t crtcport = ROM16(bios->data[offset + 1]);
+	uint8_t crtcindex = bios->data[offset + 3];
+	uint8_t mask = bios->data[offset + 4];
+	uint8_t data = bios->data[offset + 5];
+	uint8_t value;
+
+	if (!iexec->execute)
+		return 6;
+
+	BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
+		      "Data: 0x%02X\n",
+		offset, crtcport, crtcindex, mask, data);
+
+	value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data;
+	bios_idxprt_wr(bios, crtcport, crtcindex, value);
+
+	return 6;
+}
+
+static int
+init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_PLL   opcode: 0x79 ('y')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (16 bit): freq
+	 *
+	 * Set PLL register "register" to coefficients for frequency (10kHz)
+	 * "freq"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint16_t freq = ROM16(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return 7;
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq);
+
+	setPLL(bios, reg, freq * 10);
+
+	return 7;
+}
+
+static int
+init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG   opcode: 0x7A ('z')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): value
+	 *
+	 * Assign "value" to "register"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t value = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return 9;
+
+	if (reg == 0x000200)
+		value |= 1;
+
+	bios_wr32(bios, reg, value);
+
+	return 9;
+}
+
+static int
+init_ram_restrict_pll(struct nvbios *bios, uint16_t offset,
+		      struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_RESTRICT_PLL   opcode: 0x87 ('')
+	 *
+	 * offset      (8 bit): opcode
+	 * offset + 1  (8 bit): PLL type
+	 * offset + 2 (32 bit): frequency 0
+	 *
+	 * Uses the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
+	 * ram_restrict_table_ptr.  The value read from there is used to select
+	 * a frequency from the table starting at 'frequency 0' to be
+	 * programmed into the PLL corresponding to 'type'.
+	 *
+	 * The PLL limits table on cards using this opcode has a mapping of
+	 * 'type' to the relevant registers.
+	 */
+
+	struct drm_device *dev = bios->dev;
+	uint32_t strap = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2;
+	uint8_t index = bios->data[bios->ram_restrict_tbl_ptr + strap];
+	uint8_t type = bios->data[offset + 1];
+	uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]);
+	uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry;
+	int len = 2 + bios->ram_restrict_group_count * 4;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) {
+		NV_ERROR(dev, "PLL limits table not version 3.x\n");
+		return len; /* deliberate, allow default clocks to remain */
+	}
+
+	entry = pll_limits + pll_limits[1];
+	for (i = 0; i < pll_limits[3]; i++, entry += pll_limits[2]) {
+		if (entry[0] == type) {
+			uint32_t reg = ROM32(entry[3]);
+
+			BIOSLOG(bios, "0x%04X: "
+				      "Type %02x Reg 0x%08x Freq %dKHz\n",
+				offset, type, reg, freq);
+
+			setPLL(bios, reg, freq);
+			return len;
+		}
+	}
+
+	NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type);
+	return len;
+}
+
+static int
+init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_8C   opcode: 0x8C ('')
+	 *
+	 * NOP so far....
+	 *
+	 */
+
+	return 1;
+}
+
+static int
+init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_8D   opcode: 0x8D ('')
+	 *
+	 * NOP so far....
+	 *
+	 */
+
+	return 1;
+}
+
+static int
+init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_GPIO   opcode: 0x8E ('')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Loop over all entries in the DCB GPIO table, and initialise
+	 * each GPIO according to various values listed in each entry
+	 */
+
+	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
+	const uint8_t *gpio_table = &bios->data[bios->bdcb.gpio_table_ptr];
+	const uint8_t *gpio_entry;
+	int i;
+
+	if (!iexec->execute)
+		return 1;
+
+	if (bios->bdcb.version != 0x40) {
+		NV_ERROR(bios->dev, "DCB table not version 4.0\n");
+		return 0;
+	}
+
+	if (!bios->bdcb.gpio_table_ptr) {
+		NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
+		return 0;
+	}
+
+	gpio_entry = gpio_table + gpio_table[1];
+	for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
+		uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
+		int line = (entry & 0x0000001f);
+
+		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+
+		if ((entry & 0x0000ff00) == 0x0000ff00)
+			continue;
+
+		r = nv50_gpio_reg[line >> 3];
+		s = (line & 0x07) << 2;
+		v = bios_rd32(bios, r) & ~(0x00000003 << s);
+		if (entry & 0x01000000)
+			v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
+		else
+			v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
+		bios_wr32(bios, r, v);
+
+		r = nv50_gpio_ctl[line >> 4];
+		s = (line & 0x0f);
+		v = bios_rd32(bios, r) & ~(0x00010001 << s);
+		switch ((entry & 0x06000000) >> 25) {
+		case 1:
+			v |= (0x00000001 << s);
+			break;
+		case 2:
+			v |= (0x00010000 << s);
+			break;
+		default:
+			break;
+		}
+		bios_wr32(bios, r, v);
+	}
+
+	return 1;
+}
+
+static int
+init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
+			       struct init_exec *iexec)
+{
+	/*
+	 * INIT_RAM_RESTRICT_ZM_REG_GROUP   opcode: 0x8F ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): reg
+	 * offset + 5  (8  bit): regincrement
+	 * offset + 6  (8  bit): count
+	 * offset + 7  (32 bit): value 1,1
+	 * ...
+	 *
+	 * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
+	 * ram_restrict_table_ptr. The value read from here is 'n', and
+	 * "value 1,n" gets written to "reg". This repeats "count" times and on
+	 * each iteration 'm', "reg" increases by "regincrement" and
+	 * "value m,n" is used. The extent of n is limited by a number read
+	 * from the 'M' BIT table, herein called "blocklen"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t regincrement = bios->data[offset + 5];
+	uint8_t count = bios->data[offset + 6];
+	uint32_t strap_ramcfg, data;
+	/* previously set by 'M' BIT table */
+	uint16_t blocklen = bios->ram_restrict_group_count * 4;
+	int len = 7 + count * blocklen;
+	uint8_t index;
+	int i;
+
+
+	if (!iexec->execute)
+		return len;
+
+	if (!blocklen) {
+		NV_ERROR(bios->dev,
+			 "0x%04X: Zero block length - has the M table "
+			 "been parsed?\n", offset);
+		return 0;
+	}
+
+	strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
+	index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
+
+	BIOSLOG(bios, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, "
+		      "Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n",
+		offset, reg, regincrement, count, strap_ramcfg, index);
+
+	for (i = 0; i < count; i++) {
+		data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]);
+
+		bios_wr32(bios, reg, data);
+
+		reg += regincrement;
+	}
+
+	return len;
+}
+
+static int
+init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_COPY_ZM_REG   opcode: 0x90 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): src reg
+	 * offset + 5  (32 bit): dst reg
+	 *
+	 * Put contents of "src reg" into "dst reg"
+	 */
+
+	uint32_t srcreg = ROM32(bios->data[offset + 1]);
+	uint32_t dstreg = ROM32(bios->data[offset + 5]);
+
+	if (!iexec->execute)
+		return 9;
+
+	bios_wr32(bios, dstreg, bios_rd32(bios, srcreg));
+
+	return 9;
+}
+
+static int
+init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset,
+			       struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_REG_GROUP_ADDRESS_LATCHED   opcode: 0x91 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): dst reg
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (32 bit): data 1
+	 * ...
+	 *
+	 * For each of "count" values write "data n" to "dst reg"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint8_t count = bios->data[offset + 5];
+	int len = 6 + count * 4;
+	int i;
+
+	if (!iexec->execute)
+		return len;
+
+	for (i = 0; i < count; i++) {
+		uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]);
+		bios_wr32(bios, reg, data);
+	}
+
+	return len;
+}
+
+static int
+init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_RESERVED   opcode: 0x92 ('')
+	 *
+	 * offset      (8 bit): opcode
+	 *
+	 * Seemingly does nothing
+	 */
+
+	return 1;
+}
+
+static int
+init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_96   opcode: 0x96 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): sreg
+	 * offset + 5  (8  bit): sshift
+	 * offset + 6  (8  bit): smask
+	 * offset + 7  (8  bit): index
+	 * offset + 8  (32 bit): reg
+	 * offset + 12 (32 bit): mask
+	 * offset + 16 (8  bit): shift
+	 *
+	 */
+
+	uint16_t xlatptr = bios->init96_tbl_ptr + (bios->data[offset + 7] * 2);
+	uint32_t reg = ROM32(bios->data[offset + 8]);
+	uint32_t mask = ROM32(bios->data[offset + 12]);
+	uint32_t val;
+
+	val = bios_rd32(bios, ROM32(bios->data[offset + 1]));
+	if (bios->data[offset + 5] < 0x80)
+		val >>= bios->data[offset + 5];
+	else
+		val <<= (0x100 - bios->data[offset + 5]);
+	val &= bios->data[offset + 6];
+
+	val   = bios->data[ROM16(bios->data[xlatptr]) + val];
+	val <<= bios->data[offset + 16];
+
+	if (!iexec->execute)
+		return 17;
+
+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val);
+	return 17;
+}
+
+static int
+init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_97   opcode: 0x97 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): register
+	 * offset + 5  (32 bit): mask
+	 * offset + 9  (32 bit): value
+	 *
+	 * Adds "value" to "register" preserving the fields specified
+	 * by "mask"
+	 */
+
+	uint32_t reg = ROM32(bios->data[offset + 1]);
+	uint32_t mask = ROM32(bios->data[offset + 5]);
+	uint32_t add = ROM32(bios->data[offset + 9]);
+	uint32_t val;
+
+	val = bios_rd32(bios, reg);
+	val = (val & mask) | ((val + add) & ~mask);
+
+	if (!iexec->execute)
+		return 13;
+
+	bios_wr32(bios, reg, val);
+	return 13;
+}
+
+static int
+init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_AUXCH   opcode: 0x98 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): address
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (8  bit): mask 0
+	 * offset + 7  (8  bit): data 0
+	 *  ...
+	 *
+	 */
+
+	struct drm_device *dev = bios->dev;
+	struct nouveau_i2c_chan *auxch;
+	uint32_t addr = ROM32(bios->data[offset + 1]);
+	uint8_t count = bios->data[offset + 5];
+	int len = 6 + count * 2;
+	int ret, i;
+
+	if (!bios->display.output) {
+		NV_ERROR(dev, "INIT_AUXCH: no active output\n");
+		return 0;
+	}
+
+	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
+	if (!auxch) {
+		NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
+			 bios->display.output->i2c_index);
+		return 0;
+	}
+
+	if (!iexec->execute)
+		return len;
+
+	offset += 6;
+	for (i = 0; i < count; i++, offset += 2) {
+		uint8_t data;
+
+		ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
+			return 0;
+		}
+
+		data &= bios->data[offset + 0];
+		data |= bios->data[offset + 1];
+
+		ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
+			return 0;
+		}
+	}
+
+	return len;
+}
+
+static int
+init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
+{
+	/*
+	 * INIT_ZM_AUXCH   opcode: 0x99 ('')
+	 *
+	 * offset      (8  bit): opcode
+	 * offset + 1  (32 bit): address
+	 * offset + 5  (8  bit): count
+	 * offset + 6  (8  bit): data 0
+	 *  ...
+	 *
+	 */
+
+	struct drm_device *dev = bios->dev;
+	struct nouveau_i2c_chan *auxch;
+	uint32_t addr = ROM32(bios->data[offset + 1]);
+	uint8_t count = bios->data[offset + 5];
+	int len = 6 + count;
+	int ret, i;
+
+	if (!bios->display.output) {
+		NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
+		return 0;
+	}
+
+	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
+	if (!auxch) {
+		NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
+			 bios->display.output->i2c_index);
+		return 0;
+	}
+
+	if (!iexec->execute)
+		return len;
+
+	offset += 6;
+	for (i = 0; i < count; i++, offset++) {
+		ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
+		if (ret) {
+			NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
+			return 0;
+		}
+	}
+
+	return len;
+}
+
+static struct init_tbl_entry itbl_entry[] = {
+	/* command name                       , id  , length  , offset  , mult    , command handler                 */
+	/* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
+	{ "INIT_IO_RESTRICT_PROG"             , 0x32, init_io_restrict_prog           },
+	{ "INIT_REPEAT"                       , 0x33, init_repeat                     },
+	{ "INIT_IO_RESTRICT_PLL"              , 0x34, init_io_restrict_pll            },
+	{ "INIT_END_REPEAT"                   , 0x36, init_end_repeat                 },
+	{ "INIT_COPY"                         , 0x37, init_copy                       },
+	{ "INIT_NOT"                          , 0x38, init_not                        },
+	{ "INIT_IO_FLAG_CONDITION"            , 0x39, init_io_flag_condition          },
+	{ "INIT_INDEX_ADDRESS_LATCHED"        , 0x49, init_idx_addr_latched           },
+	{ "INIT_IO_RESTRICT_PLL2"             , 0x4A, init_io_restrict_pll2           },
+	{ "INIT_PLL2"                         , 0x4B, init_pll2                       },
+	{ "INIT_I2C_BYTE"                     , 0x4C, init_i2c_byte                   },
+	{ "INIT_ZM_I2C_BYTE"                  , 0x4D, init_zm_i2c_byte                },
+	{ "INIT_ZM_I2C"                       , 0x4E, init_zm_i2c                     },
+	{ "INIT_TMDS"                         , 0x4F, init_tmds                       },
+	{ "INIT_ZM_TMDS_GROUP"                , 0x50, init_zm_tmds_group              },
+	{ "INIT_CR_INDEX_ADDRESS_LATCHED"     , 0x51, init_cr_idx_adr_latch           },
+	{ "INIT_CR"                           , 0x52, init_cr                         },
+	{ "INIT_ZM_CR"                        , 0x53, init_zm_cr                      },
+	{ "INIT_ZM_CR_GROUP"                  , 0x54, init_zm_cr_group                },
+	{ "INIT_CONDITION_TIME"               , 0x56, init_condition_time             },
+	{ "INIT_ZM_REG_SEQUENCE"              , 0x58, init_zm_reg_sequence            },
+	/* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
+	{ "INIT_SUB_DIRECT"                   , 0x5B, init_sub_direct                 },
+	{ "INIT_COPY_NV_REG"                  , 0x5F, init_copy_nv_reg                },
+	{ "INIT_ZM_INDEX_IO"                  , 0x62, init_zm_index_io                },
+	{ "INIT_COMPUTE_MEM"                  , 0x63, init_compute_mem                },
+	{ "INIT_RESET"                        , 0x65, init_reset                      },
+	{ "INIT_CONFIGURE_MEM"                , 0x66, init_configure_mem              },
+	{ "INIT_CONFIGURE_CLK"                , 0x67, init_configure_clk              },
+	{ "INIT_CONFIGURE_PREINIT"            , 0x68, init_configure_preinit          },
+	{ "INIT_IO"                           , 0x69, init_io                         },
+	{ "INIT_SUB"                          , 0x6B, init_sub                        },
+	{ "INIT_RAM_CONDITION"                , 0x6D, init_ram_condition              },
+	{ "INIT_NV_REG"                       , 0x6E, init_nv_reg                     },
+	{ "INIT_MACRO"                        , 0x6F, init_macro                      },
+	{ "INIT_DONE"                         , 0x71, init_done                       },
+	{ "INIT_RESUME"                       , 0x72, init_resume                     },
+	/* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */
+	{ "INIT_TIME"                         , 0x74, init_time                       },
+	{ "INIT_CONDITION"                    , 0x75, init_condition                  },
+	{ "INIT_IO_CONDITION"                 , 0x76, init_io_condition               },
+	{ "INIT_INDEX_IO"                     , 0x78, init_index_io                   },
+	{ "INIT_PLL"                          , 0x79, init_pll                        },
+	{ "INIT_ZM_REG"                       , 0x7A, init_zm_reg                     },
+	{ "INIT_RAM_RESTRICT_PLL"             , 0x87, init_ram_restrict_pll           },
+	{ "INIT_8C"                           , 0x8C, init_8c                         },
+	{ "INIT_8D"                           , 0x8D, init_8d                         },
+	{ "INIT_GPIO"                         , 0x8E, init_gpio                       },
+	{ "INIT_RAM_RESTRICT_ZM_REG_GROUP"    , 0x8F, init_ram_restrict_zm_reg_group  },
+	{ "INIT_COPY_ZM_REG"                  , 0x90, init_copy_zm_reg                },
+	{ "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, init_zm_reg_group_addr_latched  },
+	{ "INIT_RESERVED"                     , 0x92, init_reserved                   },
+	{ "INIT_96"                           , 0x96, init_96                         },
+	{ "INIT_97"                           , 0x97, init_97                         },
+	{ "INIT_AUXCH"                        , 0x98, init_auxch                      },
+	{ "INIT_ZM_AUXCH"                     , 0x99, init_zm_auxch                   },
+	{ NULL                                , 0   , NULL                            }
+};
+
+#define MAX_TABLE_OPS 1000
+
+static int
+parse_init_table(struct nvbios *bios, unsigned int offset,
+		 struct init_exec *iexec)
+{
+	/*
+	 * Parses all commands in an init table.
+	 *
+	 * We start out executing all commands found in the init table. Some
+	 * opcodes may change the status of iexec->execute to SKIP, which will
+	 * cause the following opcodes to perform no operation until the value
+	 * is changed back to EXECUTE.
+	 */
+
+	int count = 0, i, res;
+	uint8_t id;
+
+	/*
+	 * Loop until INIT_DONE causes us to break out of the loop
+	 * (or until offset > bios length just in case... )
+	 * (and no more than MAX_TABLE_OPS iterations, just in case... )
+	 */
+	while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) {
+		id = bios->data[offset];
+
+		/* Find matching id in itbl_entry */
+		for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
+			;
+
+		if (itbl_entry[i].name) {
+			BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n",
+				offset, itbl_entry[i].id, itbl_entry[i].name);
+
+			/* execute eventual command handler */
+			res = (*itbl_entry[i].handler)(bios, offset, iexec);
+			if (!res)
+				break;
+			/*
+			 * Add the offset of the current command including all data
+			 * of that command. The offset will then be pointing on the
+			 * next op code.
+			 */
+			offset += res;
+		} else {
+			NV_ERROR(bios->dev,
+				 "0x%04X: Init table command not found: "
+				 "0x%02X\n", offset, id);
+			return -ENOENT;
+		}
+	}
+
+	if (offset >= bios->length)
+		NV_WARN(bios->dev,
+			"Offset 0x%04X greater than known bios image length.  "
+			"Corrupt image?\n", offset);
+	if (count >= MAX_TABLE_OPS)
+		NV_WARN(bios->dev,
+			"More than %d opcodes to a table is unlikely, "
+			"is the bios image corrupt?\n", MAX_TABLE_OPS);
+
+	return 0;
+}
+
+static void
+parse_init_tables(struct nvbios *bios)
+{
+	/* Loops and calls parse_init_table() for each present table. */
+
+	int i = 0;
+	uint16_t table;
+	struct init_exec iexec = {true, false};
+
+	if (bios->old_style_init) {
+		if (bios->init_script_tbls_ptr)
+			parse_init_table(bios, bios->init_script_tbls_ptr, &iexec);
+		if (bios->extra_init_script_tbl_ptr)
+			parse_init_table(bios, bios->extra_init_script_tbl_ptr, &iexec);
+
+		return;
+	}
+
+	while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) {
+		NV_INFO(bios->dev,
+			"Parsing VBIOS init table %d at offset 0x%04X\n",
+			i / 2, table);
+		BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", table);
+
+		parse_init_table(bios, table, &iexec);
+		i += 2;
+	}
+}
+
+static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk)
+{
+	int compare_record_len, i = 0;
+	uint16_t compareclk, scriptptr = 0;
+
+	if (bios->major_version < 5) /* pre BIT */
+		compare_record_len = 3;
+	else
+		compare_record_len = 4;
+
+	do {
+		compareclk = ROM16(bios->data[clktable + compare_record_len * i]);
+		if (pxclk >= compareclk * 10) {
+			if (bios->major_version < 5) {
+				uint8_t tmdssub = bios->data[clktable + 2 + compare_record_len * i];
+				scriptptr = ROM16(bios->data[bios->init_script_tbls_ptr + tmdssub * 2]);
+			} else
+				scriptptr = ROM16(bios->data[clktable + 2 + compare_record_len * i]);
+			break;
+		}
+		i++;
+	} while (compareclk);
+
+	return scriptptr;
+}
+
+static void
+run_digital_op_script(struct drm_device *dev, uint16_t scriptptr,
+		      struct dcb_entry *dcbent, int head, bool dl)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct init_exec iexec = {true, false};
+
+	NV_TRACE(dev, "0x%04X: Parsing digital output script table\n",
+		 scriptptr);
+	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_44,
+		       head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA);
+	/* note: if dcb entries have been merged, index may be misleading */
+	NVWriteVgaCrtc5758(dev, head, 0, dcbent->index);
+	parse_init_table(bios, scriptptr, &iexec);
+
+	nv04_dfp_bind_head(dev, dcbent, head, dl);
+}
+
+static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0);
+	uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]);
+
+	if (!bios->fp.xlated_entry || !sub || !scriptofs)
+		return -EINVAL;
+
+	run_digital_op_script(dev, scriptofs, dcbent, head, bios->fp.dual_link);
+
+	if (script == LVDS_PANEL_OFF) {
+		/* off-on delay in ms */
+		msleep(ROM16(bios->data[bios->fp.xlated_entry + 7]));
+	}
+#ifdef __powerpc__
+	/* Powerbook specific quirks */
+	if ((dev->pci_device & 0xffff) == 0x0179 ||
+	    (dev->pci_device & 0xffff) == 0x0189 ||
+	    (dev->pci_device & 0xffff) == 0x0329) {
+		if (script == LVDS_RESET) {
+			nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72);
+
+		} else if (script == LVDS_PANEL_ON) {
+			bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL,
+				  bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL)
+				  | (1 << 31));
+			bios_wr32(bios, NV_PCRTC_GPIO_EXT,
+				  bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1);
+
+		} else if (script == LVDS_PANEL_OFF) {
+			bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL,
+				  bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL)
+				  & ~(1 << 31));
+			bios_wr32(bios, NV_PCRTC_GPIO_EXT,
+				  bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+{
+	/*
+	 * The BIT LVDS table's header has the information to setup the
+	 * necessary registers. Following the standard 4 byte header are:
+	 * A bitmask byte and a dual-link transition pxclk value for use in
+	 * selecting the init script when not using straps; 4 script pointers
+	 * for panel power, selected by output and on/off; and 8 table pointers
+	 * for panel init, the needed one determined by output, and bits in the
+	 * conf byte. These tables are similar to the TMDS tables, consisting
+	 * of a list of pxclks and script pointers.
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
+	uint16_t scriptptr = 0, clktable;
+	uint8_t clktableptr = 0;
+
+	/*
+	 * For now we assume version 3.0 table - g80 support will need some
+	 * changes
+	 */
+
+	switch (script) {
+	case LVDS_INIT:
+		return -ENOSYS;
+	case LVDS_BACKLIGHT_ON:
+	case LVDS_PANEL_ON:
+		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 7 + outputset * 2]);
+		break;
+	case LVDS_BACKLIGHT_OFF:
+	case LVDS_PANEL_OFF:
+		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
+		break;
+	case LVDS_RESET:
+		if (dcbent->lvdsconf.use_straps_for_mode) {
+			if (bios->fp.dual_link)
+				clktableptr += 2;
+			if (bios->fp.BITbit1)
+				clktableptr++;
+		} else {
+			/* using EDID */
+			uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+			int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+
+			if (bios->fp.dual_link) {
+				clktableptr += 2;
+				fallbackcmpval *= 2;
+			}
+			if (fallbackcmpval & fallback)
+				clktableptr++;
+		}
+
+		/* adding outputset * 8 may not be correct */
+		clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+		if (!clktable) {
+			NV_ERROR(dev, "Pixel clock comparison table not found\n");
+			return -ENOENT;
+		}
+		scriptptr = clkcmptable(bios, clktable, pxclk);
+	}
+
+	if (!scriptptr) {
+		NV_ERROR(dev, "LVDS output init script not found\n");
+		return -ENOENT;
+	}
+	run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link);
+
+	return 0;
+}
+
+int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+{
+	/*
+	 * LVDS operations are multiplexed in an effort to present a single API
+	 * which works with two vastly differing underlying structures.
+	 * This acts as the demux
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
+	uint32_t sel_clk_binding, sel_clk;
+	int ret;
+
+	if (bios->fp.last_script_invoc == (script << 1 | head) || !lvds_ver ||
+	    (lvds_ver >= 0x30 && script == LVDS_INIT))
+		return 0;
+
+	if (!bios->fp.lvds_init_run) {
+		bios->fp.lvds_init_run = true;
+		call_lvds_script(dev, dcbent, head, LVDS_INIT, pxclk);
+	}
+
+	if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change)
+		call_lvds_script(dev, dcbent, head, LVDS_RESET, pxclk);
+	if (script == LVDS_RESET && bios->fp.power_off_for_reset)
+		call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk);
+
+	NV_TRACE(dev, "Calling LVDS script %d:\n", script);
+
+	/* don't let script change pll->head binding */
+	sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+
+	if (lvds_ver < 0x30)
+		ret = call_lvds_manufacturer_script(dev, dcbent, head, script);
+	else
+		ret = run_lvds_table(dev, dcbent, head, script, pxclk);
+
+	bios->fp.last_script_invoc = (script << 1 | head);
+
+	sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
+	/* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+
+	return ret;
+}
+
+struct lvdstableheader {
+	uint8_t lvds_ver, headerlen, recordlen;
+};
+
+static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct nvbios *bios, struct lvdstableheader *lth)
+{
+	/*
+	 * BMP version (0xa) LVDS table has a simple header of version and
+	 * record length. The BIT LVDS table has the typical BIT table header:
+	 * version byte, header length byte, record length byte, and a byte for
+	 * the maximum number of records that can be held in the table.
+	 */
+
+	uint8_t lvds_ver, headerlen, recordlen;
+
+	memset(lth, 0, sizeof(struct lvdstableheader));
+
+	if (bios->fp.lvdsmanufacturerpointer == 0x0) {
+		NV_ERROR(dev, "Pointer to LVDS manufacturer table invalid\n");
+		return -EINVAL;
+	}
+
+	lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
+
+	switch (lvds_ver) {
+	case 0x0a:	/* pre NV40 */
+		headerlen = 2;
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		break;
+	case 0x30:	/* NV4x */
+		headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		if (headerlen < 0x1f) {
+			NV_ERROR(dev, "LVDS table header not understood\n");
+			return -EINVAL;
+		}
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
+		break;
+	case 0x40:	/* G80/G90 */
+		headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
+		if (headerlen < 0x7) {
+			NV_ERROR(dev, "LVDS table header not understood\n");
+			return -EINVAL;
+		}
+		recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
+		break;
+	default:
+		NV_ERROR(dev,
+			 "LVDS table revision %d.%d not currently supported\n",
+			 lvds_ver >> 4, lvds_ver & 0xf);
+		return -ENOSYS;
+	}
+
+	lth->lvds_ver = lvds_ver;
+	lth->headerlen = headerlen;
+	lth->recordlen = recordlen;
+
+	return 0;
+}
+
+static int
+get_fp_strap(struct drm_device *dev, struct nvbios *bios)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/*
+	 * The fp strap is normally dictated by the "User Strap" in
+	 * PEXTDEV_BOOT_0[20:16], but on BMP cards when bit 2 of the
+	 * Internal_Flags struct at 0x48 is set, the user strap gets overriden
+	 * by the PCI subsystem ID during POST, but not before the previous user
+	 * strap has been committed to CR58 for CR57=0xf on head A, which may be
+	 * read and used instead
+	 */
+
+	if (bios->major_version < 5 && bios->data[0x48] & 0x4)
+		return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf;
+
+	if (dev_priv->card_type >= NV_50)
+		return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
+	else
+		return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 16) & 0xf;
+}
+
+static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
+{
+	uint8_t *fptable;
+	uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex;
+	int ret, ofs, fpstrapping;
+	struct lvdstableheader lth;
+
+	if (bios->fp.fptablepointer == 0x0) {
+		/* Apple cards don't have the fp table; the laptops use DDC */
+		/* The table is also missing on some x86 IGPs */
+#ifndef __powerpc__
+		NV_ERROR(dev, "Pointer to flat panel table invalid\n");
+#endif
+		bios->pub.digital_min_front_porch = 0x4b;
+		return 0;
+	}
+
+	fptable = &bios->data[bios->fp.fptablepointer];
+	fptable_ver = fptable[0];
+
+	switch (fptable_ver) {
+	/*
+	 * BMP version 0x5.0x11 BIOSen have version 1 like tables, but no
+	 * version field, and miss one of the spread spectrum/PWM bytes.
+	 * This could affect early GF2Go parts (not seen any appropriate ROMs
+	 * though). Here we assume that a version of 0x05 matches this case
+	 * (combining with a BMP version check would be better), as the
+	 * common case for the panel type field is 0x0005, and that is in
+	 * fact what we are reading the first byte of.
+	 */
+	case 0x05:	/* some NV10, 11, 15, 16 */
+		recordlen = 42;
+		ofs = -1;
+		break;
+	case 0x10:	/* some NV15/16, and NV11+ */
+		recordlen = 44;
+		ofs = 0;
+		break;
+	case 0x20:	/* NV40+ */
+		headerlen = fptable[1];
+		recordlen = fptable[2];
+		fpentries = fptable[3];
+		/*
+		 * fptable[4] is the minimum
+		 * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap
+		 */
+		bios->pub.digital_min_front_porch = fptable[4];
+		ofs = -7;
+		break;
+	default:
+		NV_ERROR(dev,
+			 "FP table revision %d.%d not currently supported\n",
+			 fptable_ver >> 4, fptable_ver & 0xf);
+		return -ENOSYS;
+	}
+
+	if (!bios->is_mobile) /* !mobile only needs digital_min_front_porch */
+		return 0;
+
+	ret = parse_lvds_manufacturer_table_header(dev, bios, &lth);
+	if (ret)
+		return ret;
+
+	if (lth.lvds_ver == 0x30 || lth.lvds_ver == 0x40) {
+		bios->fp.fpxlatetableptr = bios->fp.lvdsmanufacturerpointer +
+							lth.headerlen + 1;
+		bios->fp.xlatwidth = lth.recordlen;
+	}
+	if (bios->fp.fpxlatetableptr == 0x0) {
+		NV_ERROR(dev, "Pointer to flat panel xlat table invalid\n");
+		return -EINVAL;
+	}
+
+	fpstrapping = get_fp_strap(dev, bios);
+
+	fpindex = bios->data[bios->fp.fpxlatetableptr +
+					fpstrapping * bios->fp.xlatwidth];
+
+	if (fpindex > fpentries) {
+		NV_ERROR(dev, "Bad flat panel table index\n");
+		return -ENOENT;
+	}
+
+	/* nv4x cards need both a strap value and fpindex of 0xf to use DDC */
+	if (lth.lvds_ver > 0x10)
+		bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
+
+	/*
+	 * If either the strap or xlated fpindex value are 0xf there is no
+	 * panel using a strap-derived bios mode present.  this condition
+	 * includes, but is different from, the DDC panel indicator above
+	 */
+	if (fpstrapping == 0xf || fpindex == 0xf)
+		return 0;
+
+	bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen +
+			    recordlen * fpindex + ofs;
+
+	NV_TRACE(dev, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n",
+		 ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1,
+		 ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1,
+		 ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10);
+
+	return 0;
+}
+
+bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr];
+
+	if (!mode)	/* just checking whether we can produce a mode */
+		return bios->fp.mode_ptr;
+
+	memset(mode, 0, sizeof(struct drm_display_mode));
+	/*
+	 * For version 1.0 (version in byte 0):
+	 * bytes 1-2 are "panel type", including bits on whether Colour/mono,
+	 * single/dual link, and type (TFT etc.)
+	 * bytes 3-6 are bits per colour in RGBX
+	 */
+	mode->clock = ROM16(mode_entry[7]) * 10;
+	/* bytes 9-10 is HActive */
+	mode->hdisplay = ROM16(mode_entry[11]) + 1;
+	/*
+	 * bytes 13-14 is HValid Start
+	 * bytes 15-16 is HValid End
+	 */
+	mode->hsync_start = ROM16(mode_entry[17]) + 1;
+	mode->hsync_end = ROM16(mode_entry[19]) + 1;
+	mode->htotal = ROM16(mode_entry[21]) + 1;
+	/* bytes 23-24, 27-30 similarly, but vertical */
+	mode->vdisplay = ROM16(mode_entry[25]) + 1;
+	mode->vsync_start = ROM16(mode_entry[31]) + 1;
+	mode->vsync_end = ROM16(mode_entry[33]) + 1;
+	mode->vtotal = ROM16(mode_entry[35]) + 1;
+	mode->flags |= (mode_entry[37] & 0x10) ?
+			DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
+	mode->flags |= (mode_entry[37] & 0x1) ?
+			DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
+	/*
+	 * bytes 38-39 relate to spread spectrum settings
+	 * bytes 40-43 are something to do with PWM
+	 */
+
+	mode->status = MODE_OK;
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	drm_mode_set_name(mode);
+	return bios->fp.mode_ptr;
+}
+
+int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, bool *if_is_24bit)
+{
+	/*
+	 * The LVDS table header is (mostly) described in
+	 * parse_lvds_manufacturer_table_header(): the BIT header additionally
+	 * contains the dual-link transition pxclk (in 10s kHz), at byte 5 - if
+	 * straps are not being used for the panel, this specifies the frequency
+	 * at which modes should be set up in the dual link style.
+	 *
+	 * Following the header, the BMP (ver 0xa) table has several records,
+	 * indexed by a seperate xlat table, indexed in turn by the fp strap in
+	 * EXTDEV_BOOT. Each record had a config byte, followed by 6 script
+	 * numbers for use by INIT_SUB which controlled panel init and power,
+	 * and finally a dword of ms to sleep between power off and on
+	 * operations.
+	 *
+	 * In the BIT versions, the table following the header serves as an
+	 * integrated config and xlat table: the records in the table are
+	 * indexed by the FP strap nibble in EXTDEV_BOOT, and each record has
+	 * two bytes - the first as a config byte, the second for indexing the
+	 * fp mode table pointed to by the BIT 'D' table
+	 *
+	 * DDC is not used until after card init, so selecting the correct table
+	 * entry and setting the dual link flag for EDID equipped panels,
+	 * requiring tests against the native-mode pixel clock, cannot be done
+	 * until later, when this function should be called with non-zero pxclk
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0;
+	struct lvdstableheader lth;
+	uint16_t lvdsofs;
+	int ret, chip_version = bios->pub.chip_version;
+
+	ret = parse_lvds_manufacturer_table_header(dev, bios, &lth);
+	if (ret)
+		return ret;
+
+	switch (lth.lvds_ver) {
+	case 0x0a:	/* pre NV40 */
+		lvdsmanufacturerindex = bios->data[
+					bios->fp.fpxlatemanufacturertableptr +
+					fpstrapping];
+
+		/* we're done if this isn't the EDID panel case */
+		if (!pxclk)
+			break;
+
+		if (chip_version < 0x25) {
+			/* nv17 behaviour
+			 *
+			 * It seems the old style lvds script pointer is reused
+			 * to select 18/24 bit colour depth for EDID panels.
+			 */
+			lvdsmanufacturerindex =
+				(bios->legacy.lvds_single_a_script_ptr & 1) ?
+									2 : 0;
+			if (pxclk >= bios->fp.duallink_transition_clk)
+				lvdsmanufacturerindex++;
+		} else if (chip_version < 0x30) {
+			/* nv28 behaviour (off-chip encoder)
+			 *
+			 * nv28 does a complex dance of first using byte 121 of
+			 * the EDID to choose the lvdsmanufacturerindex, then
+			 * later attempting to match the EDID manufacturer and
+			 * product IDs in a table (signature 'pidt' (panel id
+			 * table?)), setting an lvdsmanufacturerindex of 0 and
+			 * an fp strap of the match index (or 0xf if none)
+			 */
+			lvdsmanufacturerindex = 0;
+		} else {
+			/* nv31, nv34 behaviour */
+			lvdsmanufacturerindex = 0;
+			if (pxclk >= bios->fp.duallink_transition_clk)
+				lvdsmanufacturerindex = 2;
+			if (pxclk >= 140000)
+				lvdsmanufacturerindex = 3;
+		}
+
+		/*
+		 * nvidia set the high nibble of (cr57=f, cr58) to
+		 * lvdsmanufacturerindex in this case; we don't
+		 */
+		break;
+	case 0x30:	/* NV4x */
+	case 0x40:	/* G80/G90 */
+		lvdsmanufacturerindex = fpstrapping;
+		break;
+	default:
+		NV_ERROR(dev, "LVDS table revision not currently supported\n");
+		return -ENOSYS;
+	}
+
+	lvdsofs = bios->fp.xlated_entry = bios->fp.lvdsmanufacturerpointer + lth.headerlen + lth.recordlen * lvdsmanufacturerindex;
+	switch (lth.lvds_ver) {
+	case 0x0a:
+		bios->fp.power_off_for_reset = bios->data[lvdsofs] & 1;
+		bios->fp.reset_after_pclk_change = bios->data[lvdsofs] & 2;
+		bios->fp.dual_link = bios->data[lvdsofs] & 4;
+		bios->fp.link_c_increment = bios->data[lvdsofs] & 8;
+		*if_is_24bit = bios->data[lvdsofs] & 16;
+		break;
+	case 0x30:
+		/*
+		 * My money would be on there being a 24 bit interface bit in
+		 * this table, but I have no example of a laptop bios with a
+		 * 24 bit panel to confirm that. Hence we shout loudly if any
+		 * bit other than bit 0 is set (I've not even seen bit 1)
+		 */
+		if (bios->data[lvdsofs] > 1)
+			NV_ERROR(dev,
+				 "You have a very unusual laptop display; please report it\n");
+		/*
+		 * No sign of the "power off for reset" or "reset for panel
+		 * on" bits, but it's safer to assume we should
+		 */
+		bios->fp.power_off_for_reset = true;
+		bios->fp.reset_after_pclk_change = true;
+		/*
+		 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
+		 * over-written, and BITbit1 isn't used
+		 */
+		bios->fp.dual_link = bios->data[lvdsofs] & 1;
+		bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
+		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+		break;
+	case 0x40:
+		bios->fp.dual_link = bios->data[lvdsofs] & 1;
+		bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
+		bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+		break;
+	}
+
+	/* set dual_link flag for EDID case */
+	if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
+		bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
+
+	*dl = bios->fp.dual_link;
+
+	return 0;
+}
+
+static uint8_t *
+bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent,
+			 uint16_t record, int record_len, int record_nr)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t entry;
+	uint16_t table;
+	int i, v;
+
+	for (i = 0; i < record_nr; i++, record += record_len) {
+		table = ROM16(bios->data[record]);
+		if (!table)
+			continue;
+		entry = ROM32(bios->data[table]);
+
+		v = (entry & 0x000f0000) >> 16;
+		if (!(v & dcbent->or))
+			continue;
+
+		v = (entry & 0x000000f0) >> 4;
+		if (v != dcbent->location)
+			continue;
+
+		v = (entry & 0x0000000f);
+		if (v != dcbent->type)
+			continue;
+
+		return &bios->data[table];
+	}
+
+	return NULL;
+}
+
+void *
+nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent,
+		      int *length)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *table;
+
+	if (!bios->display.dp_table_ptr) {
+		NV_ERROR(dev, "No pointer to DisplayPort table\n");
+		return NULL;
+	}
+	table = &bios->data[bios->display.dp_table_ptr];
+
+	if (table[0] != 0x21) {
+		NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n",
+			 table[0]);
+		return NULL;
+	}
+
+	*length = table[4];
+	return bios_output_config_match(dev, dcbent,
+					bios->display.dp_table_ptr + table[1],
+					table[2], table[3]);
+}
+
+int
+nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
+			       uint32_t sub, int pxclk)
+{
+	/*
+	 * The display script table is located by the BIT 'U' table.
+	 *
+	 * It contains an array of pointers to various tables describing
+	 * a particular output type.  The first 32-bits of the output
+	 * tables contains similar information to a DCB entry, and is
+	 * used to decide whether that particular table is suitable for
+	 * the output you want to access.
+	 *
+	 * The "record header length" field here seems to indicate the
+	 * offset of the first configuration entry in the output tables.
+	 * This is 10 on most cards I've seen, but 12 has been witnessed
+	 * on DP cards, and there's another script pointer within the
+	 * header.
+	 *
+	 * offset + 0   ( 8 bits): version
+	 * offset + 1   ( 8 bits): header length
+	 * offset + 2   ( 8 bits): record length
+	 * offset + 3   ( 8 bits): number of records
+	 * offset + 4   ( 8 bits): record header length
+	 * offset + 5   (16 bits): pointer to first output script table
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint8_t *table = &bios->data[bios->display.script_table_ptr];
+	uint8_t *otable = NULL;
+	uint16_t script;
+	int i = 0;
+
+	if (!bios->display.script_table_ptr) {
+		NV_ERROR(dev, "No pointer to output script table\n");
+		return 1;
+	}
+
+	/*
+	 * Nothing useful has been in any of the pre-2.0 tables I've seen,
+	 * so until they are, we really don't need to care.
+	 */
+	if (table[0] < 0x20)
+		return 1;
+
+	if (table[0] != 0x20 && table[0] != 0x21) {
+		NV_ERROR(dev, "Output script table version 0x%02x unknown\n",
+			 table[0]);
+		return 1;
+	}
+
+	/*
+	 * The output script tables describing a particular output type
+	 * look as follows:
+	 *
+	 * offset + 0   (32 bits): output this table matches (hash of DCB)
+	 * offset + 4   ( 8 bits): unknown
+	 * offset + 5   ( 8 bits): number of configurations
+	 * offset + 6   (16 bits): pointer to some script
+	 * offset + 8   (16 bits): pointer to some script
+	 *
+	 * headerlen == 10
+	 * offset + 10           : configuration 0
+	 *
+	 * headerlen == 12
+	 * offset + 10           : pointer to some script
+	 * offset + 12           : configuration 0
+	 *
+	 * Each config entry is as follows:
+	 *
+	 * offset + 0   (16 bits): unknown, assumed to be a match value
+	 * offset + 2   (16 bits): pointer to script table (clock set?)
+	 * offset + 4   (16 bits): pointer to script table (reset?)
+	 *
+	 * There doesn't appear to be a count value to say how many
+	 * entries exist in each script table, instead, a 0 value in
+	 * the first 16-bit word seems to indicate both the end of the
+	 * list and the default entry.  The second 16-bit word in the
+	 * script tables is a pointer to the script to execute.
+	 */
+
+	NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n",
+			dcbent->type, dcbent->location, dcbent->or);
+	otable = bios_output_config_match(dev, dcbent, table[1] +
+					  bios->display.script_table_ptr,
+					  table[2], table[3]);
+	if (!otable) {
+		NV_ERROR(dev, "Couldn't find matching output script table\n");
+		return 1;
+	}
+
+	if (pxclk < -2 || pxclk > 0) {
+		/* Try to find matching script table entry */
+		for (i = 0; i < otable[5]; i++) {
+			if (ROM16(otable[table[4] + i*6]) == sub)
+				break;
+		}
+
+		if (i == otable[5]) {
+			NV_ERROR(dev, "Table 0x%04x not found for %d/%d, "
+				      "using first\n",
+				 sub, dcbent->type, dcbent->or);
+			i = 0;
+		}
+	}
+
+	if (pxclk == 0) {
+		script = ROM16(otable[6]);
+		if (!script) {
+			NV_DEBUG_KMS(dev, "output script 0 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
+		nouveau_bios_run_init_table(dev, script, dcbent);
+	} else
+	if (pxclk == -1) {
+		script = ROM16(otable[8]);
+		if (!script) {
+			NV_DEBUG_KMS(dev, "output script 1 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
+		nouveau_bios_run_init_table(dev, script, dcbent);
+	} else
+	if (pxclk == -2) {
+		if (table[4] >= 12)
+			script = ROM16(otable[10]);
+		else
+			script = 0;
+		if (!script) {
+			NV_DEBUG_KMS(dev, "output script 2 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
+		nouveau_bios_run_init_table(dev, script, dcbent);
+	} else
+	if (pxclk > 0) {
+		script = ROM16(otable[table[4] + i*6 + 2]);
+		if (script)
+			script = clkcmptable(bios, script, pxclk);
+		if (!script) {
+			NV_ERROR(dev, "clock script 0 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
+		nouveau_bios_run_init_table(dev, script, dcbent);
+	} else
+	if (pxclk < 0) {
+		script = ROM16(otable[table[4] + i*6 + 4]);
+		if (script)
+			script = clkcmptable(bios, script, -pxclk);
+		if (!script) {
+			NV_DEBUG_KMS(dev, "clock script 1 not found\n");
+			return 1;
+		}
+
+		NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
+		nouveau_bios_run_init_table(dev, script, dcbent);
+	}
+
+	return 0;
+}
+
+
+int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, int pxclk)
+{
+	/*
+	 * the pxclk parameter is in kHz
+	 *
+	 * This runs the TMDS regs setting code found on BIT bios cards
+	 *
+	 * For ffs(or) == 1 use the first table, for ffs(or) == 2 and
+	 * ffs(or) == 3, use the second.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int cv = bios->pub.chip_version;
+	uint16_t clktable = 0, scriptptr;
+	uint32_t sel_clk_binding, sel_clk;
+
+	/* pre-nv17 off-chip tmds uses scripts, post nv17 doesn't */
+	if (cv >= 0x17 && cv != 0x1a && cv != 0x20 &&
+	    dcbent->location != DCB_LOC_ON_CHIP)
+		return 0;
+
+	switch (ffs(dcbent->or)) {
+	case 1:
+		clktable = bios->tmds.output0_script_ptr;
+		break;
+	case 2:
+	case 3:
+		clktable = bios->tmds.output1_script_ptr;
+		break;
+	}
+
+	if (!clktable) {
+		NV_ERROR(dev, "Pixel clock comparison table not found\n");
+		return -EINVAL;
+	}
+
+	scriptptr = clkcmptable(bios, clktable, pxclk);
+
+	if (!scriptptr) {
+		NV_ERROR(dev, "TMDS output init script not found\n");
+		return -ENOENT;
+	}
+
+	/* don't let script change pll->head binding */
+	sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+	run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000);
+	sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
+
+	return 0;
+}
+
+int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim)
+{
+	/*
+	 * PLL limits table
+	 *
+	 * Version 0x10: NV30, NV31
+	 * One byte header (version), one record of 24 bytes
+	 * Version 0x11: NV36 - Not implemented
+	 * Seems to have same record style as 0x10, but 3 records rather than 1
+	 * Version 0x20: Found on Geforce 6 cards
+	 * Trivial 4 byte BIT header. 31 (0x1f) byte record length
+	 * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards
+	 * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record
+	 * length in general, some (integrated) have an extra configuration byte
+	 * Version 0x30: Found on Geforce 8, separates the register mapping
+	 * from the limits tables.
+	 */
+
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int cv = bios->pub.chip_version, pllindex = 0;
+	uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
+	uint32_t crystal_strap_mask, crystal_straps;
+
+	if (!bios->pll_limit_tbl_ptr) {
+		if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+		    cv >= 0x40) {
+			NV_ERROR(dev, "Pointer to PLL limits table invalid\n");
+			return -EINVAL;
+		}
+	} else
+		pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr];
+
+	crystal_strap_mask = 1 << 6;
+	/* open coded dev->twoHeads test */
+	if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20)
+		crystal_strap_mask |= 1 << 22;
+	crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) &
+							crystal_strap_mask;
+
+	switch (pll_lim_ver) {
+	/*
+	 * We use version 0 to indicate a pre limit table bios (single stage
+	 * pll) and load the hard coded limits instead.
+	 */
+	case 0:
+		break;
+	case 0x10:
+	case 0x11:
+		/*
+		 * Strictly v0x11 has 3 entries, but the last two don't seem
+		 * to get used.
+		 */
+		headerlen = 1;
+		recordlen = 0x18;
+		entries = 1;
+		pllindex = 0;
+		break;
+	case 0x20:
+	case 0x21:
+	case 0x30:
+	case 0x40:
+		headerlen = bios->data[bios->pll_limit_tbl_ptr + 1];
+		recordlen = bios->data[bios->pll_limit_tbl_ptr + 2];
+		entries = bios->data[bios->pll_limit_tbl_ptr + 3];
+		break;
+	default:
+		NV_ERROR(dev, "PLL limits table revision 0x%X not currently "
+				"supported\n", pll_lim_ver);
+		return -ENOSYS;
+	}
+
+	/* initialize all members to zero */
+	memset(pll_lim, 0, sizeof(struct pll_lims));
+
+	if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
+		uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
+
+		pll_lim->vco1.minfreq = ROM32(pll_rec[0]);
+		pll_lim->vco1.maxfreq = ROM32(pll_rec[4]);
+		pll_lim->vco2.minfreq = ROM32(pll_rec[8]);
+		pll_lim->vco2.maxfreq = ROM32(pll_rec[12]);
+		pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]);
+		pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]);
+		pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX;
+
+		/* these values taken from nv30/31/36 */
+		pll_lim->vco1.min_n = 0x1;
+		if (cv == 0x36)
+			pll_lim->vco1.min_n = 0x5;
+		pll_lim->vco1.max_n = 0xff;
+		pll_lim->vco1.min_m = 0x1;
+		pll_lim->vco1.max_m = 0xd;
+		pll_lim->vco2.min_n = 0x4;
+		/*
+		 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
+		 * table version (apart from nv35)), N2 is compared to
+		 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
+		 * save a comparison
+		 */
+		pll_lim->vco2.max_n = 0x28;
+		if (cv == 0x30 || cv == 0x35)
+			/* only 5 bits available for N2 on nv30/35 */
+			pll_lim->vco2.max_n = 0x1f;
+		pll_lim->vco2.min_m = 0x1;
+		pll_lim->vco2.max_m = 0x4;
+		pll_lim->max_log2p = 0x7;
+		pll_lim->max_usable_log2p = 0x6;
+	} else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
+		uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
+		uint32_t reg = 0; /* default match */
+		uint8_t *pll_rec;
+		int i;
+
+		/*
+		 * First entry is default match, if nothing better. warn if
+		 * reg field nonzero
+		 */
+		if (ROM32(bios->data[plloffs]))
+			NV_WARN(dev, "Default PLL limit entry has non-zero "
+				       "register field\n");
+
+		if (limit_match > MAX_PLL_TYPES)
+			/* we've been passed a reg as the match */
+			reg = limit_match;
+		else /* limit match is a pll type */
+			for (i = 1; i < entries && !reg; i++) {
+				uint32_t cmpreg = ROM32(bios->data[plloffs + recordlen * i]);
+
+				if (limit_match == NVPLL &&
+				    (cmpreg == NV_PRAMDAC_NVPLL_COEFF || cmpreg == 0x4000))
+					reg = cmpreg;
+				if (limit_match == MPLL &&
+				    (cmpreg == NV_PRAMDAC_MPLL_COEFF || cmpreg == 0x4020))
+					reg = cmpreg;
+				if (limit_match == VPLL1 &&
+				    (cmpreg == NV_PRAMDAC_VPLL_COEFF || cmpreg == 0x4010))
+					reg = cmpreg;
+				if (limit_match == VPLL2 &&
+				    (cmpreg == NV_RAMDAC_VPLL2 || cmpreg == 0x4018))
+					reg = cmpreg;
+			}
+
+		for (i = 1; i < entries; i++)
+			if (ROM32(bios->data[plloffs + recordlen * i]) == reg) {
+				pllindex = i;
+				break;
+			}
+
+		pll_rec = &bios->data[plloffs + recordlen * pllindex];
+
+		BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n",
+			pllindex ? reg : 0);
+
+		/*
+		 * Frequencies are stored in tables in MHz, kHz are more
+		 * useful, so we convert.
+		 */
+
+		/* What output frequencies can each VCO generate? */
+		pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000;
+		pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000;
+		pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000;
+
+		/* What input frequencies they accept (past the m-divider)? */
+		pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000;
+		pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000;
+		pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000;
+
+		/* What values are accepted as multiplier and divider? */
+		pll_lim->vco1.min_n = pll_rec[20];
+		pll_lim->vco1.max_n = pll_rec[21];
+		pll_lim->vco1.min_m = pll_rec[22];
+		pll_lim->vco1.max_m = pll_rec[23];
+		pll_lim->vco2.min_n = pll_rec[24];
+		pll_lim->vco2.max_n = pll_rec[25];
+		pll_lim->vco2.min_m = pll_rec[26];
+		pll_lim->vco2.max_m = pll_rec[27];
+
+		pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
+		if (pll_lim->max_log2p > 0x7)
+			/* pll decoding in nv_hw.c assumes never > 7 */
+			NV_WARN(dev, "Max log2 P value greater than 7 (%d)\n",
+				pll_lim->max_log2p);
+		if (cv < 0x60)
+			pll_lim->max_usable_log2p = 0x6;
+		pll_lim->log2p_bias = pll_rec[30];
+
+		if (recordlen > 0x22)
+			pll_lim->refclk = ROM32(pll_rec[31]);
+
+		if (recordlen > 0x23 && pll_rec[35])
+			NV_WARN(dev,
+				"Bits set in PLL configuration byte (%x)\n",
+				pll_rec[35]);
+
+		/* C51 special not seen elsewhere */
+		if (cv == 0x51 && !pll_lim->refclk) {
+			uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK);
+
+			if (((limit_match == NV_PRAMDAC_VPLL_COEFF || limit_match == VPLL1) && sel_clk & 0x20) ||
+			    ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) {
+				if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
+					pll_lim->refclk = 200000;
+				else
+					pll_lim->refclk = 25000;
+			}
+		}
+	} else if (pll_lim_ver == 0x30) { /* ver 0x30 */
+		uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
+		uint8_t *record = NULL;
+		int i;
+
+		BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
+			limit_match);
+
+		for (i = 0; i < entries; i++, entry += recordlen) {
+			if (ROM32(entry[3]) == limit_match) {
+				record = &bios->data[ROM16(entry[1])];
+				break;
+			}
+		}
+
+		if (!record) {
+			NV_ERROR(dev, "Register 0x%08x not found in PLL "
+				 "limits table", limit_match);
+			return -ENOENT;
+		}
+
+		pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
+		pll_lim->vco2.minfreq = ROM16(record[4]) * 1000;
+		pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000;
+		pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000;
+		pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000;
+		pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000;
+		pll_lim->vco1.min_n = record[16];
+		pll_lim->vco1.max_n = record[17];
+		pll_lim->vco1.min_m = record[18];
+		pll_lim->vco1.max_m = record[19];
+		pll_lim->vco2.min_n = record[20];
+		pll_lim->vco2.max_n = record[21];
+		pll_lim->vco2.min_m = record[22];
+		pll_lim->vco2.max_m = record[23];
+		pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
+		pll_lim->log2p_bias = record[27];
+		pll_lim->refclk = ROM32(record[28]);
+	} else if (pll_lim_ver) { /* ver 0x40 */
+		uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
+		uint8_t *record = NULL;
+		int i;
+
+		BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
+			limit_match);
+
+		for (i = 0; i < entries; i++, entry += recordlen) {
+			if (ROM32(entry[3]) == limit_match) {
+				record = &bios->data[ROM16(entry[1])];
+				break;
+			}
+		}
+
+		if (!record) {
+			NV_ERROR(dev, "Register 0x%08x not found in PLL "
+				 "limits table", limit_match);
+			return -ENOENT;
+		}
+
+		pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
+		pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
+		pll_lim->vco1.min_inputfreq = ROM16(record[4]) * 1000;
+		pll_lim->vco1.max_inputfreq = ROM16(record[6]) * 1000;
+		pll_lim->vco1.min_m = record[8];
+		pll_lim->vco1.max_m = record[9];
+		pll_lim->vco1.min_n = record[10];
+		pll_lim->vco1.max_n = record[11];
+		pll_lim->min_p = record[12];
+		pll_lim->max_p = record[13];
+		/* where did this go to?? */
+		if (limit_match == 0x00614100 || limit_match == 0x00614900)
+			pll_lim->refclk = 27000;
+		else
+			pll_lim->refclk = 100000;
+	}
+
+	/*
+	 * By now any valid limit table ought to have set a max frequency for
+	 * vco1, so if it's zero it's either a pre limit table bios, or one
+	 * with an empty limit table (seen on nv18)
+	 */
+	if (!pll_lim->vco1.maxfreq) {
+		pll_lim->vco1.minfreq = bios->fminvco;
+		pll_lim->vco1.maxfreq = bios->fmaxvco;
+		pll_lim->vco1.min_inputfreq = 0;
+		pll_lim->vco1.max_inputfreq = INT_MAX;
+		pll_lim->vco1.min_n = 0x1;
+		pll_lim->vco1.max_n = 0xff;
+		pll_lim->vco1.min_m = 0x1;
+		if (crystal_straps == 0) {
+			/* nv05 does this, nv11 doesn't, nv10 unknown */
+			if (cv < 0x11)
+				pll_lim->vco1.min_m = 0x7;
+			pll_lim->vco1.max_m = 0xd;
+		} else {
+			if (cv < 0x11)
+				pll_lim->vco1.min_m = 0x8;
+			pll_lim->vco1.max_m = 0xe;
+		}
+		if (cv < 0x17 || cv == 0x1a || cv == 0x20)
+			pll_lim->max_log2p = 4;
+		else
+			pll_lim->max_log2p = 5;
+		pll_lim->max_usable_log2p = pll_lim->max_log2p;
+	}
+
+	if (!pll_lim->refclk)
+		switch (crystal_straps) {
+		case 0:
+			pll_lim->refclk = 13500;
+			break;
+		case (1 << 6):
+			pll_lim->refclk = 14318;
+			break;
+		case (1 << 22):
+			pll_lim->refclk = 27000;
+			break;
+		case (1 << 22 | 1 << 6):
+			pll_lim->refclk = 25000;
+			break;
+		}
+
+#if 0 /* for easy debugging */
+	ErrorF("pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
+	ErrorF("pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
+	ErrorF("pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
+	ErrorF("pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
+
+	ErrorF("pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
+	ErrorF("pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
+	ErrorF("pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
+	ErrorF("pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
+
+	ErrorF("pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
+	ErrorF("pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
+	ErrorF("pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
+	ErrorF("pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
+	ErrorF("pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
+	ErrorF("pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
+	ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
+	ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
+
+	ErrorF("pll.max_log2p: %d\n", pll_lim->max_log2p);
+	ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias);
+
+	ErrorF("pll.refclk: %d\n", pll_lim->refclk);
+#endif
+
+	return 0;
+}
+
+static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset)
+{
+	/*
+	 * offset + 0  (8 bits): Micro version
+	 * offset + 1  (8 bits): Minor version
+	 * offset + 2  (8 bits): Chip version
+	 * offset + 3  (8 bits): Major version
+	 */
+
+	bios->major_version = bios->data[offset + 3];
+	bios->pub.chip_version = bios->data[offset + 2];
+	NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n",
+		 bios->data[offset + 3], bios->data[offset + 2],
+		 bios->data[offset + 1], bios->data[offset]);
+}
+
+static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset)
+{
+	/*
+	 * Parses the init table segment for pointers used in script execution.
+	 *
+	 * offset + 0  (16 bits): init script tables pointer
+	 * offset + 2  (16 bits): macro index table pointer
+	 * offset + 4  (16 bits): macro table pointer
+	 * offset + 6  (16 bits): condition table pointer
+	 * offset + 8  (16 bits): io condition table pointer
+	 * offset + 10 (16 bits): io flag condition table pointer
+	 * offset + 12 (16 bits): init function table pointer
+	 */
+
+	bios->init_script_tbls_ptr = ROM16(bios->data[offset]);
+	bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]);
+	bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]);
+	bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]);
+	bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]);
+	bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]);
+	bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]);
+}
+
+static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the load detect values for g80 cards.
+	 *
+	 * offset + 0 (16 bits): loadval table pointer
+	 */
+
+	uint16_t load_table_ptr;
+	uint8_t version, headerlen, entrylen, num_entries;
+
+	if (bitentry->length != 3) {
+		NV_ERROR(dev, "Do not understand BIT A table\n");
+		return -EINVAL;
+	}
+
+	load_table_ptr = ROM16(bios->data[bitentry->offset]);
+
+	if (load_table_ptr == 0x0) {
+		NV_ERROR(dev, "Pointer to BIT loadval table invalid\n");
+		return -EINVAL;
+	}
+
+	version = bios->data[load_table_ptr];
+
+	if (version != 0x10) {
+		NV_ERROR(dev, "BIT loadval table version %d.%d not supported\n",
+			 version >> 4, version & 0xF);
+		return -ENOSYS;
+	}
+
+	headerlen = bios->data[load_table_ptr + 1];
+	entrylen = bios->data[load_table_ptr + 2];
+	num_entries = bios->data[load_table_ptr + 3];
+
+	if (headerlen != 4 || entrylen != 4 || num_entries != 2) {
+		NV_ERROR(dev, "Do not understand BIT loadval table\n");
+		return -EINVAL;
+	}
+
+	/* First entry is normal dac, 2nd tv-out perhaps? */
+	bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff;
+
+	return 0;
+}
+
+static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * offset + 8  (16 bits): PLL limits table pointer
+	 *
+	 * There's more in here, but that's unknown.
+	 */
+
+	if (bitentry->length < 10) {
+		NV_ERROR(dev, "Do not understand BIT C table\n");
+		return -EINVAL;
+	}
+
+	bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]);
+
+	return 0;
+}
+
+static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the flat panel table segment that the bit entry points to.
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): ??? table pointer - seems to have 18 byte
+	 * records beginning with a freq.
+	 * offset + 2  (16 bits): mode table pointer
+	 */
+
+	if (bitentry->length != 4) {
+		NV_ERROR(dev, "Do not understand BIT display table\n");
+		return -EINVAL;
+	}
+
+	bios->fp.fptablepointer = ROM16(bios->data[bitentry->offset + 2]);
+
+	return 0;
+}
+
+static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the init table segment that the bit entry points to.
+	 *
+	 * See parse_script_table_pointers for layout
+	 */
+
+	if (bitentry->length < 14) {
+		NV_ERROR(dev, "Do not understand init table\n");
+		return -EINVAL;
+	}
+
+	parse_script_table_pointers(bios, bitentry->offset);
+
+	if (bitentry->length >= 16)
+		bios->some_script_ptr = ROM16(bios->data[bitentry->offset + 14]);
+	if (bitentry->length >= 18)
+		bios->init96_tbl_ptr = ROM16(bios->data[bitentry->offset + 16]);
+
+	return 0;
+}
+
+static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * BIT 'i' (info?) table
+	 *
+	 * offset + 0  (32 bits): BIOS version dword (as in B table)
+	 * offset + 5  (8  bits): BIOS feature byte (same as for BMP?)
+	 * offset + 13 (16 bits): pointer to table containing DAC load
+	 * detection comparison values
+	 *
+	 * There's other things in the table, purpose unknown
+	 */
+
+	uint16_t daccmpoffset;
+	uint8_t dacver, dacheaderlen;
+
+	if (bitentry->length < 6) {
+		NV_ERROR(dev, "BIT i table too short for needed information\n");
+		return -EINVAL;
+	}
+
+	parse_bios_version(dev, bios, bitentry->offset);
+
+	/*
+	 * bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's
+	 * Quadro identity crisis), other bits possibly as for BMP feature byte
+	 */
+	bios->feature_byte = bios->data[bitentry->offset + 5];
+	bios->is_mobile = bios->feature_byte & FEATURE_MOBILE;
+
+	if (bitentry->length < 15) {
+		NV_WARN(dev, "BIT i table not long enough for DAC load "
+			       "detection comparison table\n");
+		return -EINVAL;
+	}
+
+	daccmpoffset = ROM16(bios->data[bitentry->offset + 13]);
+
+	/* doesn't exist on g80 */
+	if (!daccmpoffset)
+		return 0;
+
+	/*
+	 * The first value in the table, following the header, is the
+	 * comparison value, the second entry is a comparison value for
+	 * TV load detection.
+	 */
+
+	dacver = bios->data[daccmpoffset];
+	dacheaderlen = bios->data[daccmpoffset + 1];
+
+	if (dacver != 0x00 && dacver != 0x10) {
+		NV_WARN(dev, "DAC load detection comparison table version "
+			       "%d.%d not known\n", dacver >> 4, dacver & 0xf);
+		return -ENOSYS;
+	}
+
+	bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]);
+	bios->pub.tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]);
+
+	return 0;
+}
+
+static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the LVDS table segment that the bit entry points to.
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): LVDS strap xlate table pointer
+	 */
+
+	if (bitentry->length != 2) {
+		NV_ERROR(dev, "Do not understand BIT LVDS table\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * No idea if it's still called the LVDS manufacturer table, but
+	 * the concept's close enough.
+	 */
+	bios->fp.lvdsmanufacturerpointer = ROM16(bios->data[bitentry->offset]);
+
+	return 0;
+}
+
+static int
+parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+		      struct bit_entry *bitentry)
+{
+	/*
+	 * offset + 2  (8  bits): number of options in an
+	 * 	INIT_RAM_RESTRICT_ZM_REG_GROUP opcode option set
+	 * offset + 3  (16 bits): pointer to strap xlate table for RAM
+	 * 	restrict option selection
+	 *
+	 * There's a bunch of bits in this table other than the RAM restrict
+	 * stuff that we don't use - their use currently unknown
+	 */
+
+	/*
+	 * Older bios versions don't have a sufficiently long table for
+	 * what we want
+	 */
+	if (bitentry->length < 0x5)
+		return 0;
+
+	if (bitentry->id[1] < 2) {
+		bios->ram_restrict_group_count = bios->data[bitentry->offset + 2];
+		bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]);
+	} else {
+		bios->ram_restrict_group_count = bios->data[bitentry->offset + 0];
+		bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 1]);
+	}
+
+	return 0;
+}
+
+static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the pointer to the TMDS table
+	 *
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): TMDS table pointer
+	 *
+	 * The TMDS table is typically found just before the DCB table, with a
+	 * characteristic signature of 0x11,0x13 (1.1 being version, 0x13 being
+	 * length?)
+	 *
+	 * At offset +7 is a pointer to a script, which I don't know how to
+	 * run yet.
+	 * At offset +9 is a pointer to another script, likewise
+	 * Offset +11 has a pointer to a table where the first word is a pxclk
+	 * frequency and the second word a pointer to a script, which should be
+	 * run if the comparison pxclk frequency is less than the pxclk desired.
+	 * This repeats for decreasing comparison frequencies
+	 * Offset +13 has a pointer to a similar table
+	 * The selection of table (and possibly +7/+9 script) is dictated by
+	 * "or" from the DCB.
+	 */
+
+	uint16_t tmdstableptr, script1, script2;
+
+	if (bitentry->length != 2) {
+		NV_ERROR(dev, "Do not understand BIT TMDS table\n");
+		return -EINVAL;
+	}
+
+	tmdstableptr = ROM16(bios->data[bitentry->offset]);
+
+	if (tmdstableptr == 0x0) {
+		NV_ERROR(dev, "Pointer to TMDS table invalid\n");
+		return -EINVAL;
+	}
+
+	/* nv50+ has v2.0, but we don't parse it atm */
+	if (bios->data[tmdstableptr] != 0x11) {
+		NV_WARN(dev,
+			"TMDS table revision %d.%d not currently supported\n",
+			bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
+		return -ENOSYS;
+	}
+
+	/*
+	 * These two scripts are odd: they don't seem to get run even when
+	 * they are not stubbed.
+	 */
+	script1 = ROM16(bios->data[tmdstableptr + 7]);
+	script2 = ROM16(bios->data[tmdstableptr + 9]);
+	if (bios->data[script1] != 'q' || bios->data[script2] != 'q')
+		NV_WARN(dev, "TMDS table script pointers not stubbed\n");
+
+	bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]);
+	bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]);
+
+	return 0;
+}
+
+static int
+parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+		      struct bit_entry *bitentry)
+{
+	/*
+	 * Parses the pointer to the G80 output script tables
+	 *
+	 * Starting at bitentry->offset:
+	 *
+	 * offset + 0  (16 bits): output script table pointer
+	 */
+
+	uint16_t outputscripttableptr;
+
+	if (bitentry->length != 3) {
+		NV_ERROR(dev, "Do not understand BIT U table\n");
+		return -EINVAL;
+	}
+
+	outputscripttableptr = ROM16(bios->data[bitentry->offset]);
+	bios->display.script_table_ptr = outputscripttableptr;
+	return 0;
+}
+
+static int
+parse_bit_displayport_tbl_entry(struct drm_device *dev, struct nvbios *bios,
+				struct bit_entry *bitentry)
+{
+	bios->display.dp_table_ptr = ROM16(bios->data[bitentry->offset]);
+	return 0;
+}
+
+struct bit_table {
+	const char id;
+	int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *);
+};
+
+#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry })
+
+static int
+parse_bit_table(struct nvbios *bios, const uint16_t bitoffset,
+		struct bit_table *table)
+{
+	struct drm_device *dev = bios->dev;
+	uint8_t maxentries = bios->data[bitoffset + 4];
+	int i, offset;
+	struct bit_entry bitentry;
+
+	for (i = 0, offset = bitoffset + 6; i < maxentries; i++, offset += 6) {
+		bitentry.id[0] = bios->data[offset];
+
+		if (bitentry.id[0] != table->id)
+			continue;
+
+		bitentry.id[1] = bios->data[offset + 1];
+		bitentry.length = ROM16(bios->data[offset + 2]);
+		bitentry.offset = ROM16(bios->data[offset + 4]);
+
+		return table->parse_fn(dev, bios, &bitentry);
+	}
+
+	NV_INFO(dev, "BIT table '%c' not found\n", table->id);
+	return -ENOSYS;
+}
+
+static int
+parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset)
+{
+	int ret;
+
+	/*
+	 * The only restriction on parsing order currently is having 'i' first
+	 * for use of bios->*_version or bios->feature_byte while parsing;
+	 * functions shouldn't be actually *doing* anything apart from pulling
+	 * data from the image into the bios struct, thus no interdependencies
+	 */
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('i', i));
+	if (ret) /* info? */
+		return ret;
+	if (bios->major_version >= 0x60) /* g80+ */
+		parse_bit_table(bios, bitoffset, &BIT_TABLE('A', A));
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('C', C));
+	if (ret)
+		return ret;
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('D', display));
+	ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('I', init));
+	if (ret)
+		return ret;
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U));
+	parse_bit_table(bios, bitoffset, &BIT_TABLE('d', displayport));
+
+	return 0;
+}
+
+static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsigned int offset)
+{
+	/*
+	 * Parses the BMP structure for useful things, but does not act on them
+	 *
+	 * offset +   5: BMP major version
+	 * offset +   6: BMP minor version
+	 * offset +   9: BMP feature byte
+	 * offset +  10: BCD encoded BIOS version
+	 *
+	 * offset +  18: init script table pointer (for bios versions < 5.10h)
+	 * offset +  20: extra init script table pointer (for bios
+	 * versions < 5.10h)
+	 *
+	 * offset +  24: memory init table pointer (used on early bios versions)
+	 * offset +  26: SDR memory sequencing setup data table
+	 * offset +  28: DDR memory sequencing setup data table
+	 *
+	 * offset +  54: index of I2C CRTC pair to use for CRT output
+	 * offset +  55: index of I2C CRTC pair to use for TV output
+	 * offset +  56: index of I2C CRTC pair to use for flat panel output
+	 * offset +  58: write CRTC index for I2C pair 0
+	 * offset +  59: read CRTC index for I2C pair 0
+	 * offset +  60: write CRTC index for I2C pair 1
+	 * offset +  61: read CRTC index for I2C pair 1
+	 *
+	 * offset +  67: maximum internal PLL frequency (single stage PLL)
+	 * offset +  71: minimum internal PLL frequency (single stage PLL)
+	 *
+	 * offset +  75: script table pointers, as described in
+	 * parse_script_table_pointers
+	 *
+	 * offset +  89: TMDS single link output A table pointer
+	 * offset +  91: TMDS single link output B table pointer
+	 * offset +  95: LVDS single link output A table pointer
+	 * offset + 105: flat panel timings table pointer
+	 * offset + 107: flat panel strapping translation table pointer
+	 * offset + 117: LVDS manufacturer panel config table pointer
+	 * offset + 119: LVDS manufacturer strapping translation table pointer
+	 *
+	 * offset + 142: PLL limits table pointer
+	 *
+	 * offset + 156: minimum pixel clock for LVDS dual link
+	 */
+
+	uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor;
+	uint16_t bmplength;
+	uint16_t legacy_scripts_offset, legacy_i2c_offset;
+
+	/* load needed defaults in case we can't parse this info */
+	bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
+	bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
+	bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
+	bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
+	bios->pub.digital_min_front_porch = 0x4b;
+	bios->fmaxvco = 256000;
+	bios->fminvco = 128000;
+	bios->fp.duallink_transition_clk = 90000;
+
+	bmp_version_major = bmp[5];
+	bmp_version_minor = bmp[6];
+
+	NV_TRACE(dev, "BMP version %d.%d\n",
+		 bmp_version_major, bmp_version_minor);
+
+	/*
+	 * Make sure that 0x36 is blank and can't be mistaken for a DCB
+	 * pointer on early versions
+	 */
+	if (bmp_version_major < 5)
+		*(uint16_t *)&bios->data[0x36] = 0;
+
+	/*
+	 * Seems that the minor version was 1 for all major versions prior
+	 * to 5. Version 6 could theoretically exist, but I suspect BIT
+	 * happened instead.
+	 */
+	if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) {
+		NV_ERROR(dev, "You have an unsupported BMP version. "
+				"Please send in your bios\n");
+		return -ENOSYS;
+	}
+
+	if (bmp_version_major == 0)
+		/* nothing that's currently useful in this version */
+		return 0;
+	else if (bmp_version_major == 1)
+		bmplength = 44; /* exact for 1.01 */
+	else if (bmp_version_major == 2)
+		bmplength = 48; /* exact for 2.01 */
+	else if (bmp_version_major == 3)
+		bmplength = 54;
+		/* guessed - mem init tables added in this version */
+	else if (bmp_version_major == 4 || bmp_version_minor < 0x1)
+		/* don't know if 5.0 exists... */
+		bmplength = 62;
+		/* guessed - BMP I2C indices added in version 4*/
+	else if (bmp_version_minor < 0x6)
+		bmplength = 67; /* exact for 5.01 */
+	else if (bmp_version_minor < 0x10)
+		bmplength = 75; /* exact for 5.06 */
+	else if (bmp_version_minor == 0x10)
+		bmplength = 89; /* exact for 5.10h */
+	else if (bmp_version_minor < 0x14)
+		bmplength = 118; /* exact for 5.11h */
+	else if (bmp_version_minor < 0x24)
+		/*
+		 * Not sure of version where pll limits came in;
+		 * certainly exist by 0x24 though.
+		 */
+		/* length not exact: this is long enough to get lvds members */
+		bmplength = 123;
+	else if (bmp_version_minor < 0x27)
+		/*
+		 * Length not exact: this is long enough to get pll limit
+		 * member
+		 */
+		bmplength = 144;
+	else
+		/*
+		 * Length not exact: this is long enough to get dual link
+		 * transition clock.
+		 */
+		bmplength = 158;
+
+	/* checksum */
+	if (nv_cksum(bmp, 8)) {
+		NV_ERROR(dev, "Bad BMP checksum\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Bit 4 seems to indicate either a mobile bios or a quadro card --
+	 * mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl
+	 * (not nv10gl), bit 5 that the flat panel tables are present, and
+	 * bit 6 a tv bios.
+	 */
+	bios->feature_byte = bmp[9];
+
+	parse_bios_version(dev, bios, offset + 10);
+
+	if (bmp_version_major < 5 || bmp_version_minor < 0x10)
+		bios->old_style_init = true;
+	legacy_scripts_offset = 18;
+	if (bmp_version_major < 2)
+		legacy_scripts_offset -= 4;
+	bios->init_script_tbls_ptr = ROM16(bmp[legacy_scripts_offset]);
+	bios->extra_init_script_tbl_ptr = ROM16(bmp[legacy_scripts_offset + 2]);
+
+	if (bmp_version_major > 2) {	/* appears in BMP 3 */
+		bios->legacy.mem_init_tbl_ptr = ROM16(bmp[24]);
+		bios->legacy.sdr_seq_tbl_ptr = ROM16(bmp[26]);
+		bios->legacy.ddr_seq_tbl_ptr = ROM16(bmp[28]);
+	}
+
+	legacy_i2c_offset = 0x48;	/* BMP version 2 & 3 */
+	if (bmplength > 61)
+		legacy_i2c_offset = offset + 54;
+	bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
+	bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
+	bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
+	bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
+	bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
+	bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
+	bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
+
+	if (bmplength > 74) {
+		bios->fmaxvco = ROM32(bmp[67]);
+		bios->fminvco = ROM32(bmp[71]);
+	}
+	if (bmplength > 88)
+		parse_script_table_pointers(bios, offset + 75);
+	if (bmplength > 94) {
+		bios->tmds.output0_script_ptr = ROM16(bmp[89]);
+		bios->tmds.output1_script_ptr = ROM16(bmp[91]);
+		/*
+		 * Never observed in use with lvds scripts, but is reused for
+		 * 18/24 bit panel interface default for EDID equipped panels
+		 * (if_is_24bit not set directly to avoid any oscillation).
+		 */
+		bios->legacy.lvds_single_a_script_ptr = ROM16(bmp[95]);
+	}
+	if (bmplength > 108) {
+		bios->fp.fptablepointer = ROM16(bmp[105]);
+		bios->fp.fpxlatetableptr = ROM16(bmp[107]);
+		bios->fp.xlatwidth = 1;
+	}
+	if (bmplength > 120) {
+		bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]);
+		bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]);
+	}
+	if (bmplength > 143)
+		bios->pll_limit_tbl_ptr = ROM16(bmp[142]);
+
+	if (bmplength > 157)
+		bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10;
+
+	return 0;
+}
+
+static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
+{
+	int i, j;
+
+	for (i = 0; i <= (n - len); i++) {
+		for (j = 0; j < len; j++)
+			if (data[i + j] != str[j])
+				break;
+		if (j == len)
+			return i;
+	}
+
+	return 0;
+}
+
+static int
+read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
+{
+	uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
+	int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
+	int recordoffset = 0, rdofs = 1, wrofs = 0;
+	uint8_t port_type = 0;
+
+	if (!i2ctable)
+		return -EINVAL;
+
+	if (dcb_version >= 0x30) {
+		if (i2ctable[0] != dcb_version) /* necessary? */
+			NV_WARN(dev,
+				"DCB I2C table version mismatch (%02X vs %02X)\n",
+				i2ctable[0], dcb_version);
+		dcb_i2c_ver = i2ctable[0];
+		headerlen = i2ctable[1];
+		if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
+			i2c_entries = i2ctable[2];
+		else
+			NV_WARN(dev,
+				"DCB I2C table has more entries than indexable "
+				"(%d entries, max index 15)\n", i2ctable[2]);
+		entry_len = i2ctable[3];
+		/* [4] is i2c_default_indices, read in parse_dcb_table() */
+	}
+	/*
+	 * It's your own fault if you call this function on a DCB 1.1 BIOS --
+	 * the test below is for DCB 1.2
+	 */
+	if (dcb_version < 0x14) {
+		recordoffset = 2;
+		rdofs = 0;
+		wrofs = 1;
+	}
+
+	if (index == 0xf)
+		return 0;
+	if (index > i2c_entries) {
+		NV_ERROR(dev, "DCB I2C index too big (%d > %d)\n",
+			 index, i2ctable[2]);
+		return -ENOENT;
+	}
+	if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
+		NV_ERROR(dev, "DCB I2C entry invalid\n");
+		return -EINVAL;
+	}
+
+	if (dcb_i2c_ver >= 0x30) {
+		port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
+
+		/*
+		 * Fixup for chips using same address offset for read and
+		 * write.
+		 */
+		if (port_type == 4)	/* seen on C51 */
+			rdofs = wrofs = 1;
+		if (port_type >= 5)	/* G80+ */
+			rdofs = wrofs = 0;
+	}
+
+	if (dcb_i2c_ver >= 0x40 && port_type != 5 && port_type != 6)
+		NV_WARN(dev, "DCB I2C table has port type %d\n", port_type);
+
+	i2c->port_type = port_type;
+	i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
+	i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
+
+	return 0;
+}
+
+static struct dcb_gpio_entry *
+new_gpio_entry(struct nvbios *bios)
+{
+	struct parsed_dcb_gpio *gpio = &bios->bdcb.gpio;
+
+	return &gpio->entry[gpio->entries++];
+}
+
+struct dcb_gpio_entry *
+nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int i;
+
+	for (i = 0; i < bios->bdcb.gpio.entries; i++) {
+		if (bios->bdcb.gpio.entry[i].tag != tag)
+			continue;
+
+		return &bios->bdcb.gpio.entry[i];
+	}
+
+	return NULL;
+}
+
+static void
+parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
+{
+	struct dcb_gpio_entry *gpio;
+	uint16_t ent = ROM16(bios->data[offset]);
+	uint8_t line = ent & 0x1f,
+		tag = ent >> 5 & 0x3f,
+		flags = ent >> 11 & 0x1f;
+
+	if (tag == 0x3f)
+		return;
+
+	gpio = new_gpio_entry(bios);
+
+	gpio->tag = tag;
+	gpio->line = line;
+	gpio->invert = flags != 4;
+}
+
+static void
+parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
+{
+	struct dcb_gpio_entry *gpio;
+	uint32_t ent = ROM32(bios->data[offset]);
+	uint8_t line = ent & 0x1f,
+		tag = ent >> 8 & 0xff;
+
+	if (tag == 0xff)
+		return;
+
+	gpio = new_gpio_entry(bios);
+
+	/* Currently unused, we may need more fields parsed at some
+	 * point. */
+	gpio->tag = tag;
+	gpio->line = line;
+}
+
+static void
+parse_dcb_gpio_table(struct nvbios *bios)
+{
+	struct drm_device *dev = bios->dev;
+	uint16_t gpio_table_ptr = bios->bdcb.gpio_table_ptr;
+	uint8_t *gpio_table = &bios->data[gpio_table_ptr];
+	int header_len = gpio_table[1],
+	    entries = gpio_table[2],
+	    entry_len = gpio_table[3];
+	void (*parse_entry)(struct nvbios *, uint16_t) = NULL;
+	int i;
+
+	if (bios->bdcb.version >= 0x40) {
+		if (gpio_table_ptr && entry_len != 4) {
+			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
+			return;
+		}
+
+		parse_entry = parse_dcb40_gpio_entry;
+
+	} else if (bios->bdcb.version >= 0x30) {
+		if (gpio_table_ptr && entry_len != 2) {
+			NV_WARN(dev, "Invalid DCB GPIO table entry length.\n");
+			return;
+		}
+
+		parse_entry = parse_dcb30_gpio_entry;
+
+	} else if (bios->bdcb.version >= 0x22) {
+		/*
+		 * DCBs older than v3.0 don't really have a GPIO
+		 * table, instead they keep some GPIO info at fixed
+		 * locations.
+		 */
+		uint16_t dcbptr = ROM16(bios->data[0x36]);
+		uint8_t *tvdac_gpio = &bios->data[dcbptr - 5];
+
+		if (tvdac_gpio[0] & 1) {
+			struct dcb_gpio_entry *gpio = new_gpio_entry(bios);
+
+			gpio->tag = DCB_GPIO_TVDAC0;
+			gpio->line = tvdac_gpio[1] >> 4;
+			gpio->invert = tvdac_gpio[0] & 2;
+		}
+	}
+
+	if (!gpio_table_ptr)
+		return;
+
+	if (entries > DCB_MAX_NUM_GPIO_ENTRIES) {
+		NV_WARN(dev, "Too many entries in the DCB GPIO table.\n");
+		entries = DCB_MAX_NUM_GPIO_ENTRIES;
+	}
+
+	for (i = 0; i < entries; i++)
+		parse_entry(bios, gpio_table_ptr + header_len + entry_len * i);
+}
+
+struct dcb_connector_table_entry *
+nouveau_bios_connector_entry(struct drm_device *dev, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct dcb_connector_table_entry *cte;
+
+	if (index >= bios->bdcb.connector.entries)
+		return NULL;
+
+	cte = &bios->bdcb.connector.entry[index];
+	if (cte->type == 0xff)
+		return NULL;
+
+	return cte;
+}
+
+static void
+parse_dcb_connector_table(struct nvbios *bios)
+{
+	struct drm_device *dev = bios->dev;
+	struct dcb_connector_table *ct = &bios->bdcb.connector;
+	struct dcb_connector_table_entry *cte;
+	uint8_t *conntab = &bios->data[bios->bdcb.connector_table_ptr];
+	uint8_t *entry;
+	int i;
+
+	if (!bios->bdcb.connector_table_ptr) {
+		NV_DEBUG_KMS(dev, "No DCB connector table present\n");
+		return;
+	}
+
+	NV_INFO(dev, "DCB connector table: VHER 0x%02x %d %d %d\n",
+		conntab[0], conntab[1], conntab[2], conntab[3]);
+	if ((conntab[0] != 0x30 && conntab[0] != 0x40) ||
+	    (conntab[3] != 2 && conntab[3] != 4)) {
+		NV_ERROR(dev, "  Unknown!  Please report.\n");
+		return;
+	}
+
+	ct->entries = conntab[2];
+
+	entry = conntab + conntab[1];
+	cte = &ct->entry[0];
+	for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
+		if (conntab[3] == 2)
+			cte->entry = ROM16(entry[0]);
+		else
+			cte->entry = ROM32(entry[0]);
+		cte->type  = (cte->entry & 0x000000ff) >> 0;
+		cte->index = (cte->entry & 0x00000f00) >> 8;
+		switch (cte->entry & 0x00033000) {
+		case 0x00001000:
+			cte->gpio_tag = 0x07;
+			break;
+		case 0x00002000:
+			cte->gpio_tag = 0x08;
+			break;
+		case 0x00010000:
+			cte->gpio_tag = 0x51;
+			break;
+		case 0x00020000:
+			cte->gpio_tag = 0x52;
+			break;
+		default:
+			cte->gpio_tag = 0xff;
+			break;
+		}
+
+		if (cte->type == 0xff)
+			continue;
+
+		NV_INFO(dev, "  %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
+			i, cte->entry, cte->type, cte->index, cte->gpio_tag);
+	}
+}
+
+static struct dcb_entry *new_dcb_entry(struct parsed_dcb *dcb)
+{
+	struct dcb_entry *entry = &dcb->entry[dcb->entries];
+
+	memset(entry, 0, sizeof(struct dcb_entry));
+	entry->index = dcb->entries++;
+
+	return entry;
+}
+
+static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 0;
+	entry->i2c_index = i2c;
+	entry->heads = heads;
+	entry->location = DCB_LOC_ON_CHIP;
+	/* "or" mostly unused in early gen crt modesetting, 0 is fine */
+}
+
+static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 2;
+	entry->i2c_index = LEGACY_I2C_PANEL;
+	entry->heads = twoHeads ? 3 : 1;
+	entry->location = !DCB_LOC_ON_CHIP;	/* ie OFF CHIP */
+	entry->or = 1;	/* means |0x10 gets set on CRE_LCD__INDEX */
+	entry->duallink_possible = false; /* SiI164 and co. are single link */
+
+#if 0
+	/*
+	 * For dvi-a either crtc probably works, but my card appears to only
+	 * support dvi-d.  "nvidia" still attempts to program it for dvi-a,
+	 * doing the full fp output setup (program 0x6808.. fp dimension regs,
+	 * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880);
+	 * the monitor picks up the mode res ok and lights up, but no pixel
+	 * data appears, so the board manufacturer probably connected up the
+	 * sync lines, but missed the video traces / components
+	 *
+	 * with this introduction, dvi-a left as an exercise for the reader.
+	 */
+	fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads);
+#endif
+}
+
+static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads)
+{
+	struct dcb_entry *entry = new_dcb_entry(dcb);
+
+	entry->type = 1;
+	entry->i2c_index = LEGACY_I2C_TV;
+	entry->heads = twoHeads ? 3 : 1;
+	entry->location = !DCB_LOC_ON_CHIP;	/* ie OFF CHIP */
+}
+
+static bool
+parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+{
+	entry->type = conn & 0xf;
+	entry->i2c_index = (conn >> 4) & 0xf;
+	entry->heads = (conn >> 8) & 0xf;
+	if (bdcb->version >= 0x40)
+		entry->connector = (conn >> 12) & 0xf;
+	entry->bus = (conn >> 16) & 0xf;
+	entry->location = (conn >> 20) & 0x3;
+	entry->or = (conn >> 24) & 0xf;
+	/*
+	 * Normal entries consist of a single bit, but dual link has the
+	 * next most significant bit set too
+	 */
+	entry->duallink_possible =
+			((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
+
+	switch (entry->type) {
+	case OUTPUT_ANALOG:
+		/*
+		 * Although the rest of a CRT conf dword is usually
+		 * zeros, mac biosen have stuff there so we must mask
+		 */
+		entry->crtconf.maxfreq = (bdcb->version < 0x30) ?
+					 (conf & 0xffff) * 10 :
+					 (conf & 0xff) * 10000;
+		break;
+	case OUTPUT_LVDS:
+		{
+		uint32_t mask;
+		if (conf & 0x1)
+			entry->lvdsconf.use_straps_for_mode = true;
+		if (bdcb->version < 0x22) {
+			mask = ~0xd;
+			/*
+			 * The laptop in bug 14567 lies and claims to not use
+			 * straps when it does, so assume all DCB 2.0 laptops
+			 * use straps, until a broken EDID using one is produced
+			 */
+			entry->lvdsconf.use_straps_for_mode = true;
+			/*
+			 * Both 0x4 and 0x8 show up in v2.0 tables; assume they
+			 * mean the same thing (probably wrong, but might work)
+			 */
+			if (conf & 0x4 || conf & 0x8)
+				entry->lvdsconf.use_power_scripts = true;
+		} else {
+			mask = ~0x5;
+			if (conf & 0x4)
+				entry->lvdsconf.use_power_scripts = true;
+		}
+		if (conf & mask) {
+			/*
+			 * Until we even try to use these on G8x, it's
+			 * useless reporting unknown bits.  They all are.
+			 */
+			if (bdcb->version >= 0x40)
+				break;
+
+			NV_ERROR(dev, "Unknown LVDS configuration bits, "
+				      "please report\n");
+		}
+		break;
+		}
+	case OUTPUT_TV:
+	{
+		if (bdcb->version >= 0x30)
+			entry->tvconf.has_component_output = conf & (0x8 << 4);
+		else
+			entry->tvconf.has_component_output = false;
+
+		break;
+	}
+	case OUTPUT_DP:
+		entry->dpconf.sor.link = (conf & 0x00000030) >> 4;
+		entry->dpconf.link_bw = (conf & 0x00e00000) >> 21;
+		switch ((conf & 0x0f000000) >> 24) {
+		case 0xf:
+			entry->dpconf.link_nr = 4;
+			break;
+		case 0x3:
+			entry->dpconf.link_nr = 2;
+			break;
+		default:
+			entry->dpconf.link_nr = 1;
+			break;
+		}
+		break;
+	case OUTPUT_TMDS:
+		entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4;
+		break;
+	case 0xe:
+		/* weird g80 mobile type that "nv" treats as a terminator */
+		bdcb->dcb.entries--;
+		return false;
+	}
+
+	/* unsure what DCB version introduces this, 3.0? */
+	if (conf & 0x100000)
+		entry->i2c_upper_default = true;
+
+	return true;
+}
+
+static bool
+parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb,
+		  uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+{
+	switch (conn & 0x0000000f) {
+	case 0:
+		entry->type = OUTPUT_ANALOG;
+		break;
+	case 1:
+		entry->type = OUTPUT_TV;
+		break;
+	case 2:
+	case 3:
+		entry->type = OUTPUT_LVDS;
+		break;
+	case 4:
+		switch ((conn & 0x000000f0) >> 4) {
+		case 0:
+			entry->type = OUTPUT_TMDS;
+			break;
+		case 1:
+			entry->type = OUTPUT_LVDS;
+			break;
+		default:
+			NV_ERROR(dev, "Unknown DCB subtype 4/%d\n",
+				 (conn & 0x000000f0) >> 4);
+			return false;
+		}
+		break;
+	default:
+		NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f);
+		return false;
+	}
+
+	entry->i2c_index = (conn & 0x0003c000) >> 14;
+	entry->heads = ((conn & 0x001c0000) >> 18) + 1;
+	entry->or = entry->heads; /* same as heads, hopefully safe enough */
+	entry->location = (conn & 0x01e00000) >> 21;
+	entry->bus = (conn & 0x0e000000) >> 25;
+	entry->duallink_possible = false;
+
+	switch (entry->type) {
+	case OUTPUT_ANALOG:
+		entry->crtconf.maxfreq = (conf & 0xffff) * 10;
+		break;
+	case OUTPUT_TV:
+		entry->tvconf.has_component_output = false;
+		break;
+	case OUTPUT_TMDS:
+		/*
+		 * Invent a DVI-A output, by copying the fields of the DVI-D
+		 * output; reported to work by math_b on an NV20(!).
+		 */
+		fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
+		break;
+	case OUTPUT_LVDS:
+		if ((conn & 0x00003f00) != 0x10)
+			entry->lvdsconf.use_straps_for_mode = true;
+		entry->lvdsconf.use_power_scripts = true;
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+static bool parse_dcb_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb,
+			    uint32_t conn, uint32_t conf)
+{
+	struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb);
+	bool ret;
+
+	if (bdcb->version >= 0x20)
+		ret = parse_dcb20_entry(dev, bdcb, conn, conf, entry);
+	else
+		ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry);
+	if (!ret)
+		return ret;
+
+	read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table,
+			   entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]);
+
+	return true;
+}
+
+static
+void merge_like_dcb_entries(struct drm_device *dev, struct parsed_dcb *dcb)
+{
+	/*
+	 * DCB v2.0 lists each output combination separately.
+	 * Here we merge compatible entries to have fewer outputs, with
+	 * more options
+	 */
+
+	int i, newentries = 0;
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *ient = &dcb->entry[i];
+		int j;
+
+		for (j = i + 1; j < dcb->entries; j++) {
+			struct dcb_entry *jent = &dcb->entry[j];
+
+			if (jent->type == 100) /* already merged entry */
+				continue;
+
+			/* merge heads field when all other fields the same */
+			if (jent->i2c_index == ient->i2c_index &&
+			    jent->type == ient->type &&
+			    jent->location == ient->location &&
+			    jent->or == ient->or) {
+				NV_TRACE(dev, "Merging DCB entries %d and %d\n",
+					 i, j);
+				ient->heads |= jent->heads;
+				jent->type = 100; /* dummy value */
+			}
+		}
+	}
+
+	/* Compact entries merged into others out of dcb */
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].type == 100)
+			continue;
+
+		if (newentries != i) {
+			dcb->entry[newentries] = dcb->entry[i];
+			dcb->entry[newentries].index = newentries;
+		}
+		newentries++;
+	}
+
+	dcb->entries = newentries;
+}
+
+static int
+parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct bios_parsed_dcb *bdcb = &bios->bdcb;
+	struct parsed_dcb *dcb;
+	uint16_t dcbptr = 0, i2ctabptr = 0;
+	uint8_t *dcbtable;
+	uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES;
+	bool configblock = true;
+	int recordlength = 8, confofs = 4;
+	int i;
+
+	dcb = bios->pub.dcb = &bdcb->dcb;
+	dcb->entries = 0;
+
+	/* get the offset from 0x36 */
+	if (dev_priv->card_type > NV_04) {
+		dcbptr = ROM16(bios->data[0x36]);
+		if (dcbptr == 0x0000)
+			NV_WARN(dev, "No output data (DCB) found in BIOS\n");
+	}
+
+	/* this situation likely means a really old card, pre DCB */
+	if (dcbptr == 0x0) {
+		NV_INFO(dev, "Assuming a CRT output exists\n");
+		fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
+
+		if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
+			fabricate_tv_output(dcb, twoHeads);
+
+		return 0;
+	}
+
+	dcbtable = &bios->data[dcbptr];
+
+	/* get DCB version */
+	bdcb->version = dcbtable[0];
+	NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n",
+		 bdcb->version >> 4, bdcb->version & 0xf);
+
+	if (bdcb->version >= 0x20) { /* NV17+ */
+		uint32_t sig;
+
+		if (bdcb->version >= 0x30) { /* NV40+ */
+			headerlen = dcbtable[1];
+			entries = dcbtable[2];
+			recordlength = dcbtable[3];
+			i2ctabptr = ROM16(dcbtable[4]);
+			sig = ROM32(dcbtable[6]);
+			bdcb->gpio_table_ptr = ROM16(dcbtable[10]);
+			bdcb->connector_table_ptr = ROM16(dcbtable[20]);
+		} else {
+			i2ctabptr = ROM16(dcbtable[2]);
+			sig = ROM32(dcbtable[4]);
+			headerlen = 8;
+		}
+
+		if (sig != 0x4edcbdcb) {
+			NV_ERROR(dev, "Bad Display Configuration Block "
+					"signature (%08X)\n", sig);
+			return -EINVAL;
+		}
+	} else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */
+		char sig[8] = { 0 };
+
+		strncpy(sig, (char *)&dcbtable[-7], 7);
+		i2ctabptr = ROM16(dcbtable[2]);
+		recordlength = 10;
+		confofs = 6;
+
+		if (strcmp(sig, "DEV_REC")) {
+			NV_ERROR(dev, "Bad Display Configuration Block "
+					"signature (%s)\n", sig);
+			return -EINVAL;
+		}
+	} else {
+		/*
+		 * v1.4 (some NV15/16, NV11+) seems the same as v1.5, but always
+		 * has the same single (crt) entry, even when tv-out present, so
+		 * the conclusion is this version cannot really be used.
+		 * v1.2 tables (some NV6/10, and NV15+) normally have the same
+		 * 5 entries, which are not specific to the card and so no use.
+		 * v1.2 does have an I2C table that read_dcb_i2c_table can
+		 * handle, but cards exist (nv11 in #14821) with a bad i2c table
+		 * pointer, so use the indices parsed in parse_bmp_structure.
+		 * v1.1 (NV5+, maybe some NV4) is entirely unhelpful
+		 */
+		NV_TRACEWARN(dev, "No useful information in BIOS output table; "
+				  "adding all possible outputs\n");
+		fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1);
+
+		/*
+		 * Attempt to detect TV before DVI because the test
+		 * for the former is more accurate and it rules the
+		 * latter out.
+		 */
+		if (nv04_tv_identify(dev,
+				     bios->legacy.i2c_indices.tv) >= 0)
+			fabricate_tv_output(dcb, twoHeads);
+
+		else if (bios->tmds.output0_script_ptr ||
+			 bios->tmds.output1_script_ptr)
+			fabricate_dvi_i_output(dcb, twoHeads);
+
+		return 0;
+	}
+
+	if (!i2ctabptr)
+		NV_WARN(dev, "No pointer to DCB I2C port table\n");
+	else {
+		bdcb->i2c_table = &bios->data[i2ctabptr];
+		if (bdcb->version >= 0x30)
+			bdcb->i2c_default_indices = bdcb->i2c_table[4];
+	}
+
+	parse_dcb_gpio_table(bios);
+	parse_dcb_connector_table(bios);
+
+	if (entries > DCB_MAX_NUM_ENTRIES)
+		entries = DCB_MAX_NUM_ENTRIES;
+
+	for (i = 0; i < entries; i++) {
+		uint32_t connection, config = 0;
+
+		connection = ROM32(dcbtable[headerlen + recordlength * i]);
+		if (configblock)
+			config = ROM32(dcbtable[headerlen + confofs + recordlength * i]);
+
+		/* seen on an NV11 with DCB v1.5 */
+		if (connection == 0x00000000)
+			break;
+
+		/* seen on an NV17 with DCB v2.0 */
+		if (connection == 0xffffffff)
+			break;
+
+		if ((connection & 0x0000000f) == 0x0000000f)
+			continue;
+
+		NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
+			     dcb->entries, connection, config);
+
+		if (!parse_dcb_entry(dev, bdcb, connection, config))
+			break;
+	}
+
+	/*
+	 * apart for v2.1+ not being known for requiring merging, this
+	 * guarantees dcbent->index is the index of the entry in the rom image
+	 */
+	if (bdcb->version < 0x21)
+		merge_like_dcb_entries(dev, dcb);
+
+	return dcb->entries ? 0 : -ENXIO;
+}
+
+static void
+fixup_legacy_connector(struct nvbios *bios)
+{
+	struct bios_parsed_dcb *bdcb = &bios->bdcb;
+	struct parsed_dcb *dcb = &bdcb->dcb;
+	int high = 0, i;
+
+	/*
+	 * DCB 3.0 also has the table in most cases, but there are some cards
+	 * where the table is filled with stub entries, and the DCB entriy
+	 * indices are all 0.  We don't need the connector indices on pre-G80
+	 * chips (yet?) so limit the use to DCB 4.0 and above.
+	 */
+	if (bdcb->version >= 0x40)
+		return;
+
+	/*
+	 * No known connector info before v3.0, so make it up.  the rule here
+	 * is: anything on the same i2c bus is considered to be on the same
+	 * connector.  any output without an associated i2c bus is assigned
+	 * its own unique connector index.
+	 */
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index == 0xf)
+			continue;
+
+		/*
+		 * Ignore the I2C index for on-chip TV-out, as there
+		 * are cards with bogus values (nv31m in bug 23212),
+		 * and it's otherwise useless.
+		 */
+		if (dcb->entry[i].type == OUTPUT_TV &&
+		    dcb->entry[i].location == DCB_LOC_ON_CHIP) {
+			dcb->entry[i].i2c_index = 0xf;
+			continue;
+		}
+
+		dcb->entry[i].connector = dcb->entry[i].i2c_index;
+		if (dcb->entry[i].connector > high)
+			high = dcb->entry[i].connector;
+	}
+
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index != 0xf)
+			continue;
+
+		dcb->entry[i].connector = ++high;
+	}
+}
+
+static void
+fixup_legacy_i2c(struct nvbios *bios)
+{
+	struct parsed_dcb *dcb = &bios->bdcb.dcb;
+	int i;
+
+	for (i = 0; i < dcb->entries; i++) {
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_CRT)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.crt;
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_PANEL)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.panel;
+		if (dcb->entry[i].i2c_index == LEGACY_I2C_TV)
+			dcb->entry[i].i2c_index = bios->legacy.i2c_indices.tv;
+	}
+}
+
+static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry)
+{
+	/*
+	 * The header following the "HWSQ" signature has the number of entries,
+	 * and the entry size
+	 *
+	 * An entry consists of a dword to write to the sequencer control reg
+	 * (0x00001304), followed by the ucode bytes, written sequentially,
+	 * starting at reg 0x00001400
+	 */
+
+	uint8_t bytes_to_write;
+	uint16_t hwsq_entry_offset;
+	int i;
+
+	if (bios->data[hwsq_offset] <= entry) {
+		NV_ERROR(dev, "Too few entries in HW sequencer table for "
+				"requested entry\n");
+		return -ENOENT;
+	}
+
+	bytes_to_write = bios->data[hwsq_offset + 1];
+
+	if (bytes_to_write != 36) {
+		NV_ERROR(dev, "Unknown HW sequencer entry size\n");
+		return -EINVAL;
+	}
+
+	NV_TRACE(dev, "Loading NV17 power sequencing microcode\n");
+
+	hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write;
+
+	/* set sequencer control */
+	bios_wr32(bios, 0x00001304, ROM32(bios->data[hwsq_entry_offset]));
+	bytes_to_write -= 4;
+
+	/* write ucode */
+	for (i = 0; i < bytes_to_write; i += 4)
+		bios_wr32(bios, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4]));
+
+	/* twiddle NV_PBUS_DEBUG_4 */
+	bios_wr32(bios, NV_PBUS_DEBUG_4, bios_rd32(bios, NV_PBUS_DEBUG_4) | 0x18);
+
+	return 0;
+}
+
+static int load_nv17_hw_sequencer_ucode(struct drm_device *dev,
+					struct nvbios *bios)
+{
+	/*
+	 * BMP based cards, from NV17, need a microcode loading to correctly
+	 * control the GPIO etc for LVDS panels
+	 *
+	 * BIT based cards seem to do this directly in the init scripts
+	 *
+	 * The microcode entries are found by the "HWSQ" signature.
+	 */
+
+	const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' };
+	const int sz = sizeof(hwsq_signature);
+	int hwsq_offset;
+
+	hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, sz);
+	if (!hwsq_offset)
+		return 0;
+
+	/* always use entry 0? */
+	return load_nv17_hwsq_ucode_entry(dev, bios, hwsq_offset + sz, 0);
+}
+
+uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	const uint8_t edid_sig[] = {
+			0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
+	uint16_t offset = 0;
+	uint16_t newoffset;
+	int searchlen = NV_PROM_SIZE;
+
+	if (bios->fp.edid)
+		return bios->fp.edid;
+
+	while (searchlen) {
+		newoffset = findstr(&bios->data[offset], searchlen,
+								edid_sig, 8);
+		if (!newoffset)
+			return NULL;
+		offset += newoffset;
+		if (!nv_cksum(&bios->data[offset], EDID1_LEN))
+			break;
+
+		searchlen -= offset;
+		offset++;
+	}
+
+	NV_TRACE(dev, "Found EDID in BIOS\n");
+
+	return bios->fp.edid = &bios->data[offset];
+}
+
+void
+nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
+			    struct dcb_entry *dcbent)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct init_exec iexec = { true, false };
+
+	mutex_lock(&bios->lock);
+	bios->display.output = dcbent;
+	parse_init_table(bios, table, &iexec);
+	bios->display.output = NULL;
+	mutex_unlock(&bios->lock);
+}
+
+static bool NVInitVBIOS(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	memset(bios, 0, sizeof(struct nvbios));
+	mutex_init(&bios->lock);
+	bios->dev = dev;
+
+	if (!NVShadowVBIOS(dev, bios->data))
+		return false;
+
+	bios->length = NV_PROM_SIZE;
+	return true;
+}
+
+static int nouveau_parse_vbios_struct(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' };
+	const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 };
+	int offset;
+
+	offset = findstr(bios->data, bios->length,
+					bit_signature, sizeof(bit_signature));
+	if (offset) {
+		NV_TRACE(dev, "BIT BIOS found\n");
+		return parse_bit_structure(bios, offset + 6);
+	}
+
+	offset = findstr(bios->data, bios->length,
+					bmp_signature, sizeof(bmp_signature));
+	if (offset) {
+		NV_TRACE(dev, "BMP BIOS found\n");
+		return parse_bmp_structure(dev, bios, offset);
+	}
+
+	NV_ERROR(dev, "No known BIOS signature found\n");
+	return -ENODEV;
+}
+
+int
+nouveau_run_vbios_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	int i, ret = 0;
+
+	NVLockVgaCrtcs(dev, false);
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, bios->state.crtchead);
+
+	if (bios->major_version < 5)	/* BMP only */
+		load_nv17_hw_sequencer_ucode(dev, bios);
+
+	if (bios->execute) {
+		bios->fp.last_script_invoc = 0;
+		bios->fp.lvds_init_run = false;
+	}
+
+	parse_init_tables(bios);
+
+	/*
+	 * Runs some additional script seen on G8x VBIOSen.  The VBIOS'
+	 * parser will run this right after the init tables, the binary
+	 * driver appears to run it at some point later.
+	 */
+	if (bios->some_script_ptr) {
+		struct init_exec iexec = {true, false};
+
+		NV_INFO(dev, "Parsing VBIOS init table at offset 0x%04X\n",
+			bios->some_script_ptr);
+		parse_init_table(bios, bios->some_script_ptr, &iexec);
+	}
+
+	if (dev_priv->card_type >= NV_50) {
+		for (i = 0; i < bios->bdcb.dcb.entries; i++) {
+			nouveau_bios_run_display_table(dev,
+						       &bios->bdcb.dcb.entry[i],
+						       0, 0);
+		}
+	}
+
+	NVLockVgaCrtcs(dev, true);
+
+	return ret;
+}
+
+static void
+nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	struct dcb_i2c_entry *entry;
+	int i;
+
+	entry = &bios->bdcb.dcb.i2c[0];
+	for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++)
+		nouveau_i2c_fini(dev, entry);
+}
+
+int
+nouveau_bios_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t saved_nv_pextdev_boot_0;
+	bool was_locked;
+	int ret;
+
+	dev_priv->vbios = &bios->pub;
+
+	if (!NVInitVBIOS(dev))
+		return -ENODEV;
+
+	ret = nouveau_parse_vbios_struct(dev);
+	if (ret)
+		return ret;
+
+	ret = parse_dcb_table(dev, bios, nv_two_heads(dev));
+	if (ret)
+		return ret;
+
+	fixup_legacy_i2c(bios);
+	fixup_legacy_connector(bios);
+
+	if (!bios->major_version)	/* we don't run version 0 bios */
+		return 0;
+
+	/* these will need remembering across a suspend */
+	saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
+	bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0);
+
+	/* init script execution disabled */
+	bios->execute = false;
+
+	/* ... unless card isn't POSTed already */
+	if (dev_priv->card_type >= NV_10 &&
+	    NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
+	    NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
+		NV_INFO(dev, "Adaptor not initialised\n");
+		if (dev_priv->card_type < NV_50) {
+			NV_ERROR(dev, "Unable to POST this chipset\n");
+			return -ENODEV;
+		}
+
+		NV_INFO(dev, "Running VBIOS init tables\n");
+		bios->execute = true;
+	}
+
+	bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
+
+	ret = nouveau_run_vbios_init(dev);
+	if (ret) {
+		dev_priv->vbios = NULL;
+		return ret;
+	}
+
+	/* feature_byte on BMP is poor, but init always sets CR4B */
+	was_locked = NVLockVgaCrtcs(dev, false);
+	if (bios->major_version < 5)
+		bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
+
+	/* all BIT systems need p_f_m_t for digital_min_front_porch */
+	if (bios->is_mobile || bios->major_version >= 5)
+		ret = parse_fp_mode_table(dev, bios);
+	NVLockVgaCrtcs(dev, was_locked);
+
+	/* allow subsequent scripts to execute */
+	bios->execute = true;
+
+	return 0;
+}
+
+void
+nouveau_bios_takedown(struct drm_device *dev)
+{
+	nouveau_bios_i2c_devices_takedown(dev);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bios.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2007-2008 Nouveau Project
+ *
+ * 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.
+ */
+
+#ifndef __NOUVEAU_BIOS_H__
+#define __NOUVEAU_BIOS_H__
+
+#include "nvreg.h"
+#include "nouveau_i2c.h"
+
+#define DCB_MAX_NUM_ENTRIES 16
+#define DCB_MAX_NUM_I2C_ENTRIES 16
+#define DCB_MAX_NUM_GPIO_ENTRIES 32
+#define DCB_MAX_NUM_CONNECTOR_ENTRIES 16
+
+#define DCB_LOC_ON_CHIP 0
+
+struct dcb_entry {
+	int index;	/* may not be raw dcb index if merging has happened */
+	uint8_t type;
+	uint8_t i2c_index;
+	uint8_t heads;
+	uint8_t connector;
+	uint8_t bus;
+	uint8_t location;
+	uint8_t or;
+	bool duallink_possible;
+	union {
+		struct sor_conf {
+			int link;
+		} sorconf;
+		struct {
+			int maxfreq;
+		} crtconf;
+		struct {
+			struct sor_conf sor;
+			bool use_straps_for_mode;
+			bool use_power_scripts;
+		} lvdsconf;
+		struct {
+			bool has_component_output;
+		} tvconf;
+		struct {
+			struct sor_conf sor;
+			int link_nr;
+			int link_bw;
+		} dpconf;
+		struct {
+			struct sor_conf sor;
+		} tmdsconf;
+	};
+	bool i2c_upper_default;
+};
+
+struct dcb_i2c_entry {
+	uint8_t port_type;
+	uint8_t read, write;
+	struct nouveau_i2c_chan *chan;
+};
+
+struct parsed_dcb {
+	int entries;
+	struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
+	struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
+};
+
+enum dcb_gpio_tag {
+	DCB_GPIO_TVDAC0 = 0xc,
+	DCB_GPIO_TVDAC1 = 0x2d,
+};
+
+struct dcb_gpio_entry {
+	enum dcb_gpio_tag tag;
+	int line;
+	bool invert;
+};
+
+struct parsed_dcb_gpio {
+	int entries;
+	struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
+};
+
+struct dcb_connector_table_entry {
+	uint32_t entry;
+	uint8_t type;
+	uint8_t index;
+	uint8_t gpio_tag;
+};
+
+struct dcb_connector_table {
+	int entries;
+	struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
+};
+
+struct bios_parsed_dcb {
+	uint8_t version;
+
+	struct parsed_dcb dcb;
+
+	uint8_t *i2c_table;
+	uint8_t i2c_default_indices;
+
+	uint16_t gpio_table_ptr;
+	struct parsed_dcb_gpio gpio;
+	uint16_t connector_table_ptr;
+	struct dcb_connector_table connector;
+};
+
+enum nouveau_encoder_type {
+	OUTPUT_ANALOG = 0,
+	OUTPUT_TV = 1,
+	OUTPUT_TMDS = 2,
+	OUTPUT_LVDS = 3,
+	OUTPUT_DP = 6,
+	OUTPUT_ANY = -1
+};
+
+enum nouveau_or {
+	OUTPUT_A = (1 << 0),
+	OUTPUT_B = (1 << 1),
+	OUTPUT_C = (1 << 2)
+};
+
+enum LVDS_script {
+	/* Order *does* matter here */
+	LVDS_INIT = 1,
+	LVDS_RESET,
+	LVDS_BACKLIGHT_ON,
+	LVDS_BACKLIGHT_OFF,
+	LVDS_PANEL_ON,
+	LVDS_PANEL_OFF
+};
+
+/* changing these requires matching changes to reg tables in nv_get_clock */
+#define MAX_PLL_TYPES	4
+enum pll_types {
+	NVPLL,
+	MPLL,
+	VPLL1,
+	VPLL2
+};
+
+struct pll_lims {
+	struct {
+		int minfreq;
+		int maxfreq;
+		int min_inputfreq;
+		int max_inputfreq;
+
+		uint8_t min_m;
+		uint8_t max_m;
+		uint8_t min_n;
+		uint8_t max_n;
+	} vco1, vco2;
+
+	uint8_t max_log2p;
+	/*
+	 * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
+	 * value) is no different to 6 (at least for vplls) so allowing the MNP
+	 * calc to use 7 causes the generated clock to be out by a factor of 2.
+	 * however, max_log2p cannot be fixed-up during parsing as the
+	 * unmodified max_log2p value is still needed for setting mplls, hence
+	 * an additional max_usable_log2p member
+	 */
+	uint8_t max_usable_log2p;
+	uint8_t log2p_bias;
+
+	uint8_t min_p;
+	uint8_t max_p;
+
+	int refclk;
+};
+
+struct nouveau_bios_info {
+	struct parsed_dcb *dcb;
+
+	uint8_t chip_version;
+
+	uint32_t dactestval;
+	uint32_t tvdactestval;
+	uint8_t digital_min_front_porch;
+	bool fp_no_ddc;
+};
+
+struct nvbios {
+	struct drm_device *dev;
+	struct nouveau_bios_info pub;
+
+	struct mutex lock;
+
+	uint8_t data[NV_PROM_SIZE];
+	unsigned int length;
+	bool execute;
+
+	uint8_t major_version;
+	uint8_t feature_byte;
+	bool is_mobile;
+
+	uint32_t fmaxvco, fminvco;
+
+	bool old_style_init;
+	uint16_t init_script_tbls_ptr;
+	uint16_t extra_init_script_tbl_ptr;
+	uint16_t macro_index_tbl_ptr;
+	uint16_t macro_tbl_ptr;
+	uint16_t condition_tbl_ptr;
+	uint16_t io_condition_tbl_ptr;
+	uint16_t io_flag_condition_tbl_ptr;
+	uint16_t init_function_tbl_ptr;
+
+	uint16_t pll_limit_tbl_ptr;
+	uint16_t ram_restrict_tbl_ptr;
+	uint8_t ram_restrict_group_count;
+
+	uint16_t some_script_ptr; /* BIT I + 14 */
+	uint16_t init96_tbl_ptr; /* BIT I + 16 */
+
+	struct bios_parsed_dcb bdcb;
+
+	struct {
+		int crtchead;
+		/* these need remembering across suspend */
+		uint32_t saved_nv_pfb_cfg0;
+	} state;
+
+	struct {
+		struct dcb_entry *output;
+		uint16_t script_table_ptr;
+		uint16_t dp_table_ptr;
+	} display;
+
+	struct {
+		uint16_t fptablepointer;	/* also used by tmds */
+		uint16_t fpxlatetableptr;
+		int xlatwidth;
+		uint16_t lvdsmanufacturerpointer;
+		uint16_t fpxlatemanufacturertableptr;
+		uint16_t mode_ptr;
+		uint16_t xlated_entry;
+		bool power_off_for_reset;
+		bool reset_after_pclk_change;
+		bool dual_link;
+		bool link_c_increment;
+		bool BITbit1;
+		bool if_is_24bit;
+		int duallink_transition_clk;
+		uint8_t strapless_is_24bit;
+		uint8_t *edid;
+
+		/* will need resetting after suspend */
+		int last_script_invoc;
+		bool lvds_init_run;
+	} fp;
+
+	struct {
+		uint16_t output0_script_ptr;
+		uint16_t output1_script_ptr;
+	} tmds;
+
+	struct {
+		uint16_t mem_init_tbl_ptr;
+		uint16_t sdr_seq_tbl_ptr;
+		uint16_t ddr_seq_tbl_ptr;
+
+		struct {
+			uint8_t crt, tv, panel;
+		} i2c_indices;
+
+		uint16_t lvds_single_a_script_ptr;
+	} legacy;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_bo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,773 @@
+/*
+ * Copyright 2007 Dave Airlied
+ * 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, 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
+ * VA LINUX SYSTEMS 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: Dave Airlied <airlied@linux.ie>
+ *	    Ben Skeggs   <darktama@iinet.net.au>
+ *	    Jeremy Kolb  <jkolb@brandeis.edu>
+ */
+
+#include "drmP.h"
+
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+#include <linux/log2.h>
+
+static void
+nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct drm_device *dev = dev_priv->dev;
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+	ttm_bo_kunmap(&nvbo->kmap);
+
+	if (unlikely(nvbo->gem))
+		DRM_ERROR("bo %p still attached to GEM object\n", bo);
+
+	if (nvbo->tile)
+		nv10_mem_expire_tiling(dev, nvbo->tile, NULL);
+
+	spin_lock(&dev_priv->ttm.bo_list_lock);
+	list_del(&nvbo->head);
+	spin_unlock(&dev_priv->ttm.bo_list_lock);
+	kfree(nvbo);
+}
+
+static void
+nouveau_bo_fixup_align(struct drm_device *dev,
+		       uint32_t tile_mode, uint32_t tile_flags,
+		       int *align, int *size)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/*
+	 * Some of the tile_flags have a periodic structure of N*4096 bytes,
+	 * align to to that as well as the page size. Align the size to the
+	 * appropriate boundaries. This does imply that sizes are rounded up
+	 * 3-7 pages, so be aware of this and do not waste memory by allocating
+	 * many small buffers.
+	 */
+	if (dev_priv->card_type == NV_50) {
+		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
+		int i;
+
+		switch (tile_flags) {
+		case 0x1800:
+		case 0x2800:
+		case 0x4800:
+		case 0x7a00:
+			if (is_power_of_2(block_size)) {
+				for (i = 1; i < 10; i++) {
+					*align = 12 * i * block_size;
+					if (!(*align % 65536))
+						break;
+				}
+			} else {
+				for (i = 1; i < 10; i++) {
+					*align = 8 * i * block_size;
+					if (!(*align % 65536))
+						break;
+				}
+			}
+			*size = roundup(*size, *align);
+			break;
+		default:
+			break;
+		}
+
+	} else {
+		if (tile_mode) {
+			if (dev_priv->chipset >= 0x40) {
+				*align = 65536;
+				*size = roundup(*size, 64 * tile_mode);
+
+			} else if (dev_priv->chipset >= 0x30) {
+				*align = 32768;
+				*size = roundup(*size, 64 * tile_mode);
+
+			} else if (dev_priv->chipset >= 0x20) {
+				*align = 16384;
+				*size = roundup(*size, 64 * tile_mode);
+
+			} else if (dev_priv->chipset >= 0x10) {
+				*align = 16384;
+				*size = roundup(*size, 32 * tile_mode);
+			}
+		}
+	}
+
+	/* ALIGN works only on powers of two. */
+	*size = roundup(*size, PAGE_SIZE);
+
+	if (dev_priv->card_type == NV_50) {
+		*size = roundup(*size, 65536);
+		*align = max(65536, *align);
+	}
+}
+
+int
+nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
+	       int size, int align, uint32_t flags, uint32_t tile_mode,
+	       uint32_t tile_flags, bool no_vm, bool mappable,
+	       struct nouveau_bo **pnvbo)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_bo *nvbo;
+	int ret = 0;
+
+	nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL);
+	if (!nvbo)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&nvbo->head);
+	INIT_LIST_HEAD(&nvbo->entry);
+	nvbo->mappable = mappable;
+	nvbo->no_vm = no_vm;
+	nvbo->tile_mode = tile_mode;
+	nvbo->tile_flags = tile_flags;
+
+	nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size);
+	align >>= PAGE_SHIFT;
+
+	nvbo->placement.fpfn = 0;
+	nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
+	nouveau_bo_placement_set(nvbo, flags);
+
+	nvbo->channel = chan;
+	ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
+			  ttm_bo_type_device, &nvbo->placement, align, 0,
+			  false, NULL, size, nouveau_bo_del_ttm);
+	nvbo->channel = NULL;
+	if (ret) {
+		/* ttm will call nouveau_bo_del_ttm if it fails.. */
+		return ret;
+	}
+
+	spin_lock(&dev_priv->ttm.bo_list_lock);
+	list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list);
+	spin_unlock(&dev_priv->ttm.bo_list_lock);
+	*pnvbo = nvbo;
+	return 0;
+}
+
+void
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+{
+	int n = 0;
+
+	if (memtype & TTM_PL_FLAG_VRAM)
+		nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
+	if (memtype & TTM_PL_FLAG_TT)
+		nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	if (memtype & TTM_PL_FLAG_SYSTEM)
+		nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
+	nvbo->placement.placement = nvbo->placements;
+	nvbo->placement.busy_placement = nvbo->placements;
+	nvbo->placement.num_placement = n;
+	nvbo->placement.num_busy_placement = n;
+
+	if (nvbo->pin_refcnt) {
+		while (n--)
+			nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
+	}
+}
+
+int
+nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	int ret, i;
+
+	if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
+		NV_ERROR(nouveau_bdev(bo->bdev)->dev,
+			 "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
+			 1 << bo->mem.mem_type, memtype);
+		return -EINVAL;
+	}
+
+	if (nvbo->pin_refcnt++)
+		return 0;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (ret)
+		goto out;
+
+	nouveau_bo_placement_set(nvbo, memtype);
+	for (i = 0; i < nvbo->placement.num_placement; i++)
+		nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
+	if (ret == 0) {
+		switch (bo->mem.mem_type) {
+		case TTM_PL_VRAM:
+			dev_priv->fb_aper_free -= bo->mem.size;
+			break;
+		case TTM_PL_TT:
+			dev_priv->gart_info.aper_free -= bo->mem.size;
+			break;
+		default:
+			break;
+		}
+	}
+	ttm_bo_unreserve(bo);
+out:
+	if (unlikely(ret))
+		nvbo->pin_refcnt--;
+	return ret;
+}
+
+int
+nouveau_bo_unpin(struct nouveau_bo *nvbo)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	int ret, i;
+
+	if (--nvbo->pin_refcnt)
+		return 0;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nvbo->placement.num_placement; i++)
+		nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
+	if (ret == 0) {
+		switch (bo->mem.mem_type) {
+		case TTM_PL_VRAM:
+			dev_priv->fb_aper_free += bo->mem.size;
+			break;
+		case TTM_PL_TT:
+			dev_priv->gart_info.aper_free += bo->mem.size;
+			break;
+		default:
+			break;
+		}
+	}
+
+	ttm_bo_unreserve(bo);
+	return ret;
+}
+
+int
+nouveau_bo_map(struct nouveau_bo *nvbo)
+{
+	int ret;
+
+	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap);
+	ttm_bo_unreserve(&nvbo->bo);
+	return ret;
+}
+
+void
+nouveau_bo_unmap(struct nouveau_bo *nvbo)
+{
+	ttm_bo_kunmap(&nvbo->kmap);
+}
+
+u16
+nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index)
+{
+	bool is_iomem;
+	u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		return ioread16_native((void __force __iomem *)mem);
+	else
+		return *mem;
+}
+
+void
+nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val)
+{
+	bool is_iomem;
+	u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		iowrite16_native(val, (void __force __iomem *)mem);
+	else
+		*mem = val;
+}
+
+u32
+nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		return ioread32_native((void __force __iomem *)mem);
+	else
+		return *mem;
+}
+
+void
+nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
+	mem = &mem[index];
+	if (is_iomem)
+		iowrite32_native(val, (void __force __iomem *)mem);
+	else
+		*mem = val;
+}
+
+static struct ttm_backend *
+nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+	struct drm_device *dev = dev_priv->dev;
+
+	switch (dev_priv->gart_info.type) {
+#if __OS_HAS_AGP
+	case NOUVEAU_GART_AGP:
+		return ttm_agp_backend_init(bdev, dev->agp->bridge);
+#endif
+	case NOUVEAU_GART_SGDMA:
+		return nouveau_sgdma_init_ttm(dev);
+	default:
+		NV_ERROR(dev, "Unknown GART type %d\n",
+			 dev_priv->gart_info.type);
+		break;
+	}
+
+	return NULL;
+}
+
+static int
+nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
+{
+	/* We'll do this from user space. */
+	return 0;
+}
+
+static int
+nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+			 struct ttm_mem_type_manager *man)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+	struct drm_device *dev = dev_priv->dev;
+
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case TTM_PL_VRAM:
+		man->flags = TTM_MEMTYPE_FLAG_FIXED |
+			     TTM_MEMTYPE_FLAG_MAPPABLE |
+			     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
+		man->available_caching = TTM_PL_FLAG_UNCACHED |
+					 TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_WC;
+
+		man->io_addr = NULL;
+		man->io_offset = drm_get_resource_start(dev, 1);
+		man->io_size = drm_get_resource_len(dev, 1);
+		if (man->io_size > nouveau_mem_fb_amount(dev))
+			man->io_size = nouveau_mem_fb_amount(dev);
+
+		man->gpu_offset = dev_priv->vm_vram_base;
+		break;
+	case TTM_PL_TT:
+		switch (dev_priv->gart_info.type) {
+		case NOUVEAU_GART_AGP:
+			man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+				     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
+			man->available_caching = TTM_PL_FLAG_UNCACHED;
+			man->default_caching = TTM_PL_FLAG_UNCACHED;
+			break;
+		case NOUVEAU_GART_SGDMA:
+			man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
+				     TTM_MEMTYPE_FLAG_CMA;
+			man->available_caching = TTM_PL_MASK_CACHING;
+			man->default_caching = TTM_PL_FLAG_CACHED;
+			break;
+		default:
+			NV_ERROR(dev, "Unknown GART type: %d\n",
+				 dev_priv->gart_info.type);
+			return -EINVAL;
+		}
+
+		man->io_offset  = dev_priv->gart_info.aper_base;
+		man->io_size    = dev_priv->gart_info.aper_size;
+		man->io_addr   = NULL;
+		man->gpu_offset = dev_priv->vm_gart_base;
+		break;
+	default:
+		NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void
+nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
+{
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+	switch (bo->mem.mem_type) {
+	case TTM_PL_VRAM:
+		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT |
+					 TTM_PL_FLAG_SYSTEM);
+		break;
+	default:
+		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+		break;
+	}
+
+	*pl = nvbo->placement;
+}
+
+
+/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access
+ * TTM_PL_{VRAM,TT} directly.
+ */
+
+static int
+nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
+			      struct nouveau_bo *nvbo, bool evict, bool no_wait,
+			      struct ttm_mem_reg *new_mem)
+{
+	struct nouveau_fence *fence = NULL;
+	int ret;
+
+	ret = nouveau_fence_new(chan, &fence, true);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
+					evict, no_wait, new_mem);
+	if (nvbo->channel && nvbo->channel != chan)
+		ret = nouveau_fence_wait(fence, NULL, false, false);
+	nouveau_fence_unref((void *)&fence);
+	return ret;
+}
+
+static inline uint32_t
+nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
+		      struct ttm_mem_reg *mem)
+{
+	if (chan == nouveau_bdev(nvbo->bo.bdev)->channel) {
+		if (mem->mem_type == TTM_PL_TT)
+			return NvDmaGART;
+		return NvDmaVRAM;
+	}
+
+	if (mem->mem_type == TTM_PL_TT)
+		return chan->gart_handle;
+	return chan->vram_handle;
+}
+
+static int
+nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
+		     int no_wait, struct ttm_mem_reg *new_mem)
+{
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct ttm_mem_reg *old_mem = &bo->mem;
+	struct nouveau_channel *chan;
+	uint64_t src_offset, dst_offset;
+	uint32_t page_count;
+	int ret;
+
+	chan = nvbo->channel;
+	if (!chan || nvbo->tile_flags || nvbo->no_vm)
+		chan = dev_priv->channel;
+
+	src_offset = old_mem->mm_node->start << PAGE_SHIFT;
+	dst_offset = new_mem->mm_node->start << PAGE_SHIFT;
+	if (chan != dev_priv->channel) {
+		if (old_mem->mem_type == TTM_PL_TT)
+			src_offset += dev_priv->vm_gart_base;
+		else
+			src_offset += dev_priv->vm_vram_base;
+
+		if (new_mem->mem_type == TTM_PL_TT)
+			dst_offset += dev_priv->vm_gart_base;
+		else
+			dst_offset += dev_priv->vm_vram_base;
+	}
+
+	ret = RING_SPACE(chan, 3);
+	if (ret)
+		return ret;
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2);
+	OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, old_mem));
+	OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, new_mem));
+
+	if (dev_priv->card_type >= NV_50) {
+		ret = RING_SPACE(chan, 4);
+		if (ret)
+			return ret;
+		BEGIN_RING(chan, NvSubM2MF, 0x0200, 1);
+		OUT_RING(chan, 1);
+		BEGIN_RING(chan, NvSubM2MF, 0x021c, 1);
+		OUT_RING(chan, 1);
+	}
+
+	page_count = new_mem->num_pages;
+	while (page_count) {
+		int line_count = (page_count > 2047) ? 2047 : page_count;
+
+		if (dev_priv->card_type >= NV_50) {
+			ret = RING_SPACE(chan, 3);
+			if (ret)
+				return ret;
+			BEGIN_RING(chan, NvSubM2MF, 0x0238, 2);
+			OUT_RING(chan, upper_32_bits(src_offset));
+			OUT_RING(chan, upper_32_bits(dst_offset));
+		}
+		ret = RING_SPACE(chan, 11);
+		if (ret)
+			return ret;
+		BEGIN_RING(chan, NvSubM2MF,
+				 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+		OUT_RING(chan, lower_32_bits(src_offset));
+		OUT_RING(chan, lower_32_bits(dst_offset));
+		OUT_RING(chan, PAGE_SIZE); /* src_pitch */
+		OUT_RING(chan, PAGE_SIZE); /* dst_pitch */
+		OUT_RING(chan, PAGE_SIZE); /* line_length */
+		OUT_RING(chan, line_count);
+		OUT_RING(chan, (1<<8)|(1<<0));
+		OUT_RING(chan, 0);
+		BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
+		OUT_RING(chan, 0);
+
+		page_count -= line_count;
+		src_offset += (PAGE_SIZE * line_count);
+		dst_offset += (PAGE_SIZE * line_count);
+	}
+
+	return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait, new_mem);
+}
+
+static int
+nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
+		      bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	struct ttm_placement placement;
+	struct ttm_mem_reg tmp_mem;
+	int ret;
+
+	placement.fpfn = placement.lpfn = 0;
+	placement.num_placement = placement.num_busy_placement = 1;
+	placement.placement = placement.busy_placement = &placement_memtype;
+
+	tmp_mem = *new_mem;
+	tmp_mem.mm_node = NULL;
+	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait);
+	if (ret)
+		return ret;
+
+	ret = ttm_tt_bind(bo->ttm, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem);
+out:
+	if (tmp_mem.mm_node) {
+		spin_lock(&bo->bdev->glob->lru_lock);
+		drm_mm_put_block(tmp_mem.mm_node);
+		spin_unlock(&bo->bdev->glob->lru_lock);
+	}
+
+	return ret;
+}
+
+static int
+nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
+		      bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
+	struct ttm_placement placement;
+	struct ttm_mem_reg tmp_mem;
+	int ret;
+
+	placement.fpfn = placement.lpfn = 0;
+	placement.num_placement = placement.num_busy_placement = 1;
+	placement.placement = placement.busy_placement = &placement_memtype;
+
+	tmp_mem = *new_mem;
+	tmp_mem.mm_node = NULL;
+	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_move_ttm(bo, evict, no_wait, &tmp_mem);
+	if (ret)
+		goto out;
+
+	ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem);
+	if (ret)
+		goto out;
+
+out:
+	if (tmp_mem.mm_node) {
+		spin_lock(&bo->bdev->glob->lru_lock);
+		drm_mm_put_block(tmp_mem.mm_node);
+		spin_unlock(&bo->bdev->glob->lru_lock);
+	}
+
+	return ret;
+}
+
+static int
+nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
+		   struct nouveau_tile_reg **new_tile)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct drm_device *dev = dev_priv->dev;
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+	uint64_t offset;
+	int ret;
+
+	if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) {
+		/* Nothing to do. */
+		*new_tile = NULL;
+		return 0;
+	}
+
+	offset = new_mem->mm_node->start << PAGE_SHIFT;
+
+	if (dev_priv->card_type == NV_50) {
+		ret = nv50_mem_vm_bind_linear(dev,
+					      offset + dev_priv->vm_vram_base,
+					      new_mem->size, nvbo->tile_flags,
+					      offset);
+		if (ret)
+			return ret;
+
+	} else if (dev_priv->card_type >= NV_10) {
+		*new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size,
+						nvbo->tile_mode);
+	}
+
+	return 0;
+}
+
+static void
+nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
+		      struct nouveau_tile_reg *new_tile,
+		      struct nouveau_tile_reg **old_tile)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct drm_device *dev = dev_priv->dev;
+
+	if (dev_priv->card_type >= NV_10 &&
+	    dev_priv->card_type < NV_50) {
+		if (*old_tile)
+			nv10_mem_expire_tiling(dev, *old_tile, bo->sync_obj);
+
+		*old_tile = new_tile;
+	}
+}
+
+static int
+nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
+		bool no_wait, struct ttm_mem_reg *new_mem)
+{
+	struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+	struct nouveau_bo *nvbo = nouveau_bo(bo);
+	struct ttm_mem_reg *old_mem = &bo->mem;
+	struct nouveau_tile_reg *new_tile = NULL;
+	int ret = 0;
+
+	ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile);
+	if (ret)
+		return ret;
+
+	/* Software copy if the card isn't up and running yet. */
+	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
+	    !dev_priv->channel) {
+		ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+		goto out;
+	}
+
+	/* Fake bo copy. */
+	if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) {
+		BUG_ON(bo->mem.mm_node != NULL);
+		bo->mem = *new_mem;
+		new_mem->mm_node = NULL;
+		goto out;
+	}
+
+	/* Hardware assisted copy. */
+	if (new_mem->mem_type == TTM_PL_SYSTEM)
+		ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem);
+	else if (old_mem->mem_type == TTM_PL_SYSTEM)
+		ret = nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem);
+	else
+		ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem);
+
+	if (!ret)
+		goto out;
+
+	/* Fallback to software copy. */
+	ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+
+out:
+	if (ret)
+		nouveau_bo_vm_cleanup(bo, NULL, &new_tile);
+	else
+		nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile);
+
+	return ret;
+}
+
+static int
+nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+	return 0;
+}
+
+struct ttm_bo_driver nouveau_bo_driver = {
+	.create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
+	.invalidate_caches = nouveau_bo_invalidate_caches,
+	.init_mem_type = nouveau_bo_init_mem_type,
+	.evict_flags = nouveau_bo_evict_flags,
+	.move = nouveau_bo_move,
+	.verify_access = nouveau_bo_verify_access,
+	.sync_obj_signaled = nouveau_fence_signalled,
+	.sync_obj_wait = nouveau_fence_wait,
+	.sync_obj_flush = nouveau_fence_flush,
+	.sync_obj_unref = nouveau_fence_unref,
+	.sync_obj_ref = nouveau_fence_ref,
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_calc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,478 @@
+/*
+ * Copyright 1993-2003 NVIDIA, Corporation
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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 "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+/****************************************************************************\
+*                                                                            *
+* The video arbitration routines calculate some "magic" numbers.  Fixes      *
+* the snow seen when accessing the framebuffer without it.                   *
+* It just works (I hope).                                                    *
+*                                                                            *
+\****************************************************************************/
+
+struct nv_fifo_info {
+	int lwm;
+	int burst;
+};
+
+struct nv_sim_state {
+	int pclk_khz;
+	int mclk_khz;
+	int nvclk_khz;
+	int bpp;
+	int mem_page_miss;
+	int mem_latency;
+	int memory_type;
+	int memory_width;
+	int two_heads;
+};
+
+static void
+nv04_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
+{
+	int pagemiss, cas, width, bpp;
+	int nvclks, mclks, pclks, crtpagemiss;
+	int found, mclk_extra, mclk_loop, cbs, m1, p1;
+	int mclk_freq, pclk_freq, nvclk_freq;
+	int us_m, us_n, us_p, crtc_drain_rate;
+	int cpm_us, us_crt, clwm;
+
+	pclk_freq = arb->pclk_khz;
+	mclk_freq = arb->mclk_khz;
+	nvclk_freq = arb->nvclk_khz;
+	pagemiss = arb->mem_page_miss;
+	cas = arb->mem_latency;
+	width = arb->memory_width >> 6;
+	bpp = arb->bpp;
+	cbs = 128;
+
+	pclks = 2;
+	nvclks = 10;
+	mclks = 13 + cas;
+	mclk_extra = 3;
+	found = 0;
+
+	while (!found) {
+		found = 1;
+
+		mclk_loop = mclks + mclk_extra;
+		us_m = mclk_loop * 1000 * 1000 / mclk_freq;
+		us_n = nvclks * 1000 * 1000 / nvclk_freq;
+		us_p = nvclks * 1000 * 1000 / pclk_freq;
+
+		crtc_drain_rate = pclk_freq * bpp / 8;
+		crtpagemiss = 2;
+		crtpagemiss += 1;
+		cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
+		us_crt = cpm_us + us_m + us_n + us_p;
+		clwm = us_crt * crtc_drain_rate / (1000 * 1000);
+		clwm++;
+
+		m1 = clwm + cbs - 512;
+		p1 = m1 * pclk_freq / mclk_freq;
+		p1 = p1 * bpp / 8;
+		if ((p1 < m1 && m1 > 0) || clwm > 519) {
+			found = !mclk_extra;
+			mclk_extra--;
+		}
+		if (clwm < 384)
+			clwm = 384;
+
+		fifo->lwm = clwm;
+		fifo->burst = cbs;
+	}
+}
+
+static void
+nv10_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
+{
+	int fill_rate, drain_rate;
+	int pclks, nvclks, mclks, xclks;
+	int pclk_freq, nvclk_freq, mclk_freq;
+	int fill_lat, extra_lat;
+	int max_burst_o, max_burst_l;
+	int fifo_len, min_lwm, max_lwm;
+	const int burst_lat = 80; /* Maximum allowable latency due
+				   * to the CRTC FIFO burst. (ns) */
+
+	pclk_freq = arb->pclk_khz;
+	nvclk_freq = arb->nvclk_khz;
+	mclk_freq = arb->mclk_khz;
+
+	fill_rate = mclk_freq * arb->memory_width / 8; /* kB/s */
+	drain_rate = pclk_freq * arb->bpp / 8; /* kB/s */
+
+	fifo_len = arb->two_heads ? 1536 : 1024; /* B */
+
+	/* Fixed FIFO refill latency. */
+
+	pclks = 4;	/* lwm detect. */
+
+	nvclks = 3	/* lwm -> sync. */
+		+ 2	/* fbi bus cycles (1 req + 1 busy) */
+		+ 1	/* 2 edge sync.  may be very close to edge so
+			 * just put one. */
+		+ 1	/* fbi_d_rdv_n */
+		+ 1	/* Fbi_d_rdata */
+		+ 1;	/* crtfifo load */
+
+	mclks = 1	/* 2 edge sync.  may be very close to edge so
+			 * just put one. */
+		+ 1	/* arb_hp_req */
+		+ 5	/* tiling pipeline */
+		+ 2	/* latency fifo */
+		+ 2	/* memory request to fbio block */
+		+ 7;	/* data returned from fbio block */
+
+	/* Need to accumulate 256 bits for read */
+	mclks += (arb->memory_type == 0 ? 2 : 1)
+		* arb->memory_width / 32;
+
+	fill_lat = mclks * 1000 * 1000 / mclk_freq   /* minimum mclk latency */
+		+ nvclks * 1000 * 1000 / nvclk_freq  /* nvclk latency */
+		+ pclks * 1000 * 1000 / pclk_freq;   /* pclk latency */
+
+	/* Conditional FIFO refill latency. */
+
+	xclks = 2 * arb->mem_page_miss + mclks /* Extra latency due to
+						* the overlay. */
+		+ 2 * arb->mem_page_miss       /* Extra pagemiss latency. */
+		+ (arb->bpp == 32 ? 8 : 4);    /* Margin of error. */
+
+	extra_lat = xclks * 1000 * 1000 / mclk_freq;
+
+	if (arb->two_heads)
+		/* Account for another CRTC. */
+		extra_lat += fill_lat + extra_lat + burst_lat;
+
+	/* FIFO burst */
+
+	/* Max burst not leading to overflows. */
+	max_burst_o = (1 + fifo_len - extra_lat * drain_rate / (1000 * 1000))
+		* (fill_rate / 1000) / ((fill_rate - drain_rate) / 1000);
+	fifo->burst = min(max_burst_o, 1024);
+
+	/* Max burst value with an acceptable latency. */
+	max_burst_l = burst_lat * fill_rate / (1000 * 1000);
+	fifo->burst = min(max_burst_l, fifo->burst);
+
+	fifo->burst = rounddown_pow_of_two(fifo->burst);
+
+	/* FIFO low watermark */
+
+	min_lwm = (fill_lat + extra_lat) * drain_rate / (1000 * 1000) + 1;
+	max_lwm = fifo_len - fifo->burst
+		+ fill_lat * drain_rate / (1000 * 1000)
+		+ fifo->burst * drain_rate / fill_rate;
+
+	fifo->lwm = min_lwm + 10 * (max_lwm - min_lwm) / 100; /* Empirical. */
+}
+
+static void
+nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
+		int *burst, int *lwm)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv_fifo_info fifo_data;
+	struct nv_sim_state sim_data;
+	int MClk = nouveau_hw_get_clock(dev, MPLL);
+	int NVClk = nouveau_hw_get_clock(dev, NVPLL);
+	uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1);
+
+	sim_data.pclk_khz = VClk;
+	sim_data.mclk_khz = MClk;
+	sim_data.nvclk_khz = NVClk;
+	sim_data.bpp = bpp;
+	sim_data.two_heads = nv_two_heads(dev);
+	if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
+	    (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
+		uint32_t type;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type);
+
+		sim_data.memory_type = (type >> 12) & 1;
+		sim_data.memory_width = 64;
+		sim_data.mem_latency = 3;
+		sim_data.mem_page_miss = 10;
+	} else {
+		sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1;
+		sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
+		sim_data.mem_latency = cfg1 & 0xf;
+		sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
+	}
+
+	if (dev_priv->card_type == NV_04)
+		nv04_calc_arb(&fifo_data, &sim_data);
+	else
+		nv10_calc_arb(&fifo_data, &sim_data);
+
+	*burst = ilog2(fifo_data.burst >> 4);
+	*lwm = fifo_data.lwm >> 3;
+}
+
+static void
+nv30_update_arb(int *burst, int *lwm)
+{
+	unsigned int fifo_size, burst_size, graphics_lwm;
+
+	fifo_size = 2048;
+	burst_size = 512;
+	graphics_lwm = fifo_size - burst_size;
+
+	*burst = ilog2(burst_size >> 5);
+	*lwm = graphics_lwm >> 3;
+}
+
+void
+nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->card_type < NV_30)
+		nv04_update_arb(dev, vclk, bpp, burst, lwm);
+	else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
+		 (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
+		*burst = 128;
+		*lwm = 0x0480;
+	} else
+		nv30_update_arb(burst, lwm);
+}
+
+static int
+getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+	      struct nouveau_pll_vals *bestpv)
+{
+	/* Find M, N and P for a single stage PLL
+	 *
+	 * Note that some bioses (NV3x) have lookup tables of precomputed MNP
+	 * values, but we're too lazy to use those atm
+	 *
+	 * "clk" parameter in kHz
+	 * returns calculated clock
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int cv = dev_priv->vbios->chip_version;
+	int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
+	int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
+	int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
+	int minU = pll_lim->vco1.min_inputfreq;
+	int maxU = pll_lim->vco1.max_inputfreq;
+	int minP = pll_lim->max_p ? pll_lim->min_p : 0;
+	int maxP = pll_lim->max_p ? pll_lim->max_p : pll_lim->max_usable_log2p;
+	int crystal = pll_lim->refclk;
+	int M, N, thisP, P;
+	int clkP, calcclk;
+	int delta, bestdelta = INT_MAX;
+	int bestclk = 0;
+
+	/* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
+	/* possibly correlated with introduction of 27MHz crystal */
+	if (dev_priv->card_type < NV_50) {
+		if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
+			if (clk > 250000)
+				maxM = 6;
+			if (clk > 340000)
+				maxM = 2;
+		} else if (cv < 0x40) {
+			if (clk > 150000)
+				maxM = 6;
+			if (clk > 200000)
+				maxM = 4;
+			if (clk > 340000)
+				maxM = 2;
+		}
+	}
+
+	P = pll_lim->max_p ? maxP : (1 << maxP);
+	if ((clk * P) < minvco) {
+		minvco = clk * maxP;
+		maxvco = minvco * 2;
+	}
+
+	if (clk + clk/200 > maxvco)	/* +0.5% */
+		maxvco = clk + clk/200;
+
+	/* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
+	for (thisP = minP; thisP <= maxP; thisP++) {
+		P = pll_lim->max_p ? thisP : (1 << thisP);
+		clkP = clk * P;
+
+		if (clkP < minvco)
+			continue;
+		if (clkP > maxvco)
+			return bestclk;
+
+		for (M = minM; M <= maxM; M++) {
+			if (crystal/M < minU)
+				return bestclk;
+			if (crystal/M > maxU)
+				continue;
+
+			/* add crystal/2 to round better */
+			N = (clkP * M + crystal/2) / crystal;
+
+			if (N < minN)
+				continue;
+			if (N > maxN)
+				break;
+
+			/* more rounding additions */
+			calcclk = ((N * crystal + P/2) / P + M/2) / M;
+			delta = abs(calcclk - clk);
+			/* we do an exhaustive search rather than terminating
+			 * on an optimality condition...
+			 */
+			if (delta < bestdelta) {
+				bestdelta = delta;
+				bestclk = calcclk;
+				bestpv->N1 = N;
+				bestpv->M1 = M;
+				bestpv->log2P = thisP;
+				if (delta == 0)	/* except this one */
+					return bestclk;
+			}
+		}
+	}
+
+	return bestclk;
+}
+
+static int
+getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+	      struct nouveau_pll_vals *bestpv)
+{
+	/* Find M, N and P for a two stage PLL
+	 *
+	 * Note that some bioses (NV30+) have lookup tables of precomputed MNP
+	 * values, but we're too lazy to use those atm
+	 *
+	 * "clk" parameter in kHz
+	 * returns calculated clock
+	 */
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
+	int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
+	int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
+	int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq;
+	int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m;
+	int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n;
+	int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m;
+	int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n;
+	int maxlog2P = pll_lim->max_usable_log2p;
+	int crystal = pll_lim->refclk;
+	bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
+	int M1, N1, M2, N2, log2P;
+	int clkP, calcclk1, calcclk2, calcclkout;
+	int delta, bestdelta = INT_MAX;
+	int bestclk = 0;
+
+	int vco2 = (maxvco2 - maxvco2/200) / 2;
+	for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
+		;
+	clkP = clk << log2P;
+
+	if (maxvco2 < clk + clk/200)	/* +0.5% */
+		maxvco2 = clk + clk/200;
+
+	for (M1 = minM1; M1 <= maxM1; M1++) {
+		if (crystal/M1 < minU1)
+			return bestclk;
+		if (crystal/M1 > maxU1)
+			continue;
+
+		for (N1 = minN1; N1 <= maxN1; N1++) {
+			calcclk1 = crystal * N1 / M1;
+			if (calcclk1 < minvco1)
+				continue;
+			if (calcclk1 > maxvco1)
+				break;
+
+			for (M2 = minM2; M2 <= maxM2; M2++) {
+				if (calcclk1/M2 < minU2)
+					break;
+				if (calcclk1/M2 > maxU2)
+					continue;
+
+				/* add calcclk1/2 to round better */
+				N2 = (clkP * M2 + calcclk1/2) / calcclk1;
+				if (N2 < minN2)
+					continue;
+				if (N2 > maxN2)
+					break;
+
+				if (!fixedgain2) {
+					if (chip_version < 0x60)
+						if (N2/M2 < 4 || N2/M2 > 10)
+							continue;
+
+					calcclk2 = calcclk1 * N2 / M2;
+					if (calcclk2 < minvco2)
+						break;
+					if (calcclk2 > maxvco2)
+						continue;
+				} else
+					calcclk2 = calcclk1;
+
+				calcclkout = calcclk2 >> log2P;
+				delta = abs(calcclkout - clk);
+				/* we do an exhaustive search rather than terminating
+				 * on an optimality condition...
+				 */
+				if (delta < bestdelta) {
+					bestdelta = delta;
+					bestclk = calcclkout;
+					bestpv->N1 = N1;
+					bestpv->M1 = M1;
+					bestpv->N2 = N2;
+					bestpv->M2 = M2;
+					bestpv->log2P = log2P;
+					if (delta == 0)	/* except this one */
+						return bestclk;
+				}
+			}
+		}
+	}
+
+	return bestclk;
+}
+
+int
+nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
+		     struct nouveau_pll_vals *pv)
+{
+	int outclk;
+
+	if (!pll_lim->vco2.maxfreq)
+		outclk = getMNP_single(dev, pll_lim, clk, pv);
+	else
+		outclk = getMNP_double(dev, pll_lim, clk, pv);
+
+	if (!outclk)
+		NV_ERROR(dev, "Could not find a compatible set of PLL values\n");
+
+	return outclk;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_channel.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2005-2006 Stephane Marchesin
+ * 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, 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+
+static int
+nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_bo *pb = chan->pushbuf_bo;
+	struct nouveau_gpuobj *pushbuf = NULL;
+	uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
+	int ret;
+
+	if (pb->bo.mem.mem_type == TTM_PL_TT) {
+		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
+						  dev_priv->gart_info.aper_size,
+						  NV_DMA_ACCESS_RO, &pushbuf,
+						  NULL);
+		chan->pushbuf_base = start;
+	} else
+	if (dev_priv->card_type != NV_04) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
+					     dev_priv->fb_available_size,
+					     NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_VIDMEM, &pushbuf);
+		chan->pushbuf_base = start;
+	} else {
+		/* NV04 cmdbuf hack, from original ddx.. not sure of it's
+		 * exact reason for existing :)  PCI access to cmdbuf in
+		 * VRAM.
+		 */
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     drm_get_resource_start(dev, 1),
+					     dev_priv->fb_available_size,
+					     NV_DMA_ACCESS_RO,
+					     NV_DMA_TARGET_PCI, &pushbuf);
+		chan->pushbuf_base = start;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing pushbuf ctxdma: %d\n", ret);
+		if (pushbuf != dev_priv->gart_info.sg_ctxdma)
+			nouveau_gpuobj_del(dev, &pushbuf);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct nouveau_bo *
+nouveau_channel_user_pushbuf_alloc(struct drm_device *dev)
+{
+	struct nouveau_bo *pushbuf = NULL;
+	int location, ret;
+
+	if (nouveau_vram_pushbuf)
+		location = TTM_PL_FLAG_VRAM;
+	else
+		location = TTM_PL_FLAG_TT;
+
+	ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false,
+			     true, &pushbuf);
+	if (ret) {
+		NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret);
+		return NULL;
+	}
+
+	ret = nouveau_bo_pin(pushbuf, location);
+	if (ret) {
+		NV_ERROR(dev, "error pinning DMA push buffer: %d\n", ret);
+		nouveau_bo_ref(NULL, &pushbuf);
+		return NULL;
+	}
+
+	return pushbuf;
+}
+
+/* allocates and initializes a fifo for user space consumption */
+int
+nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
+		      struct drm_file *file_priv,
+		      uint32_t vram_handle, uint32_t tt_handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	int channel, user;
+	int ret;
+
+	/*
+	 * Alright, here is the full story
+	 * Nvidia cards have multiple hw fifo contexts (praise them for that,
+	 * no complicated crash-prone context switches)
+	 * We allocate a new context for each app and let it write to it
+	 * directly (woo, full userspace command submission !)
+	 * When there are no more contexts, you lost
+	 */
+	for (channel = 0; channel < pfifo->channels; channel++) {
+		if (dev_priv->fifos[channel] == NULL)
+			break;
+	}
+
+	/* no more fifos. you lost. */
+	if (channel == pfifo->channels)
+		return -EINVAL;
+
+	dev_priv->fifos[channel] = kzalloc(sizeof(struct nouveau_channel),
+					   GFP_KERNEL);
+	if (!dev_priv->fifos[channel])
+		return -ENOMEM;
+	dev_priv->fifo_alloc_count++;
+	chan = dev_priv->fifos[channel];
+	INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
+	INIT_LIST_HEAD(&chan->fence.pending);
+	chan->dev = dev;
+	chan->id = channel;
+	chan->file_priv = file_priv;
+	chan->vram_handle = vram_handle;
+	chan->gart_handle = tt_handle;
+
+	NV_INFO(dev, "Allocating FIFO number %d\n", channel);
+
+	/* Allocate DMA push buffer */
+	chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev);
+	if (!chan->pushbuf_bo) {
+		ret = -ENOMEM;
+		NV_ERROR(dev, "pushbuf %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	nouveau_dma_pre_init(chan);
+
+	/* Locate channel's user control regs */
+	if (dev_priv->card_type < NV_40)
+		user = NV03_USER(channel);
+	else
+	if (dev_priv->card_type < NV_50)
+		user = NV40_USER(channel);
+	else
+		user = NV50_USER(channel);
+
+	chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user,
+								PAGE_SIZE);
+	if (!chan->user) {
+		NV_ERROR(dev, "ioremap of regs failed.\n");
+		nouveau_channel_free(chan);
+		return -ENOMEM;
+	}
+	chan->user_put = 0x40;
+	chan->user_get = 0x44;
+
+	/* Allocate space for per-channel fixed notifier memory */
+	ret = nouveau_notifier_init_channel(chan);
+	if (ret) {
+		NV_ERROR(dev, "ntfy %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Setup channel's default objects */
+	ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle);
+	if (ret) {
+		NV_ERROR(dev, "gpuobj %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Create a dma object for the push buffer */
+	ret = nouveau_channel_pushbuf_ctxdma_init(chan);
+	if (ret) {
+		NV_ERROR(dev, "pbctxdma %d\n", ret);
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* disable the fifo caches */
+	pfifo->reassign(dev, false);
+
+	/* Create a graphics context for new channel */
+	ret = pgraph->create_context(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	/* Construct inital RAMFC for new channel */
+	ret = pfifo->create_context(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	pfifo->reassign(dev, true);
+
+	ret = nouveau_dma_init(chan);
+	if (!ret)
+		ret = nouveau_fence_init(chan);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	nouveau_debugfs_channel_init(chan);
+
+	NV_INFO(dev, "%s: initialised FIFO %d\n", __func__, channel);
+	*chan_ret = chan;
+	return 0;
+}
+
+/* stops a fifo */
+void
+nouveau_channel_free(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	unsigned long flags;
+	int ret;
+
+	NV_INFO(dev, "%s: freeing fifo %d\n", __func__, chan->id);
+
+	nouveau_debugfs_channel_fini(chan);
+
+	/* Give outstanding push buffers a chance to complete */
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	nouveau_fence_update(chan);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+	if (chan->fence.sequence != chan->fence.sequence_ack) {
+		struct nouveau_fence *fence = NULL;
+
+		ret = nouveau_fence_new(chan, &fence, true);
+		if (ret == 0) {
+			ret = nouveau_fence_wait(fence, NULL, false, false);
+			nouveau_fence_unref((void *)&fence);
+		}
+
+		if (ret)
+			NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id);
+	}
+
+	/* Ensure all outstanding fences are signaled.  They should be if the
+	 * above attempts at idling were OK, but if we failed this'll tell TTM
+	 * we're done with the buffers.
+	 */
+	nouveau_fence_fini(chan);
+
+	/* Ensure the channel is no longer active on the GPU */
+	pfifo->reassign(dev, false);
+
+	pgraph->fifo_access(dev, false);
+	if (pgraph->channel(dev) == chan)
+		pgraph->unload_context(dev);
+	pgraph->destroy_context(chan);
+	pgraph->fifo_access(dev, true);
+
+	if (pfifo->channel_id(dev) == chan->id) {
+		pfifo->disable(dev);
+		pfifo->unload_context(dev);
+		pfifo->enable(dev);
+	}
+	pfifo->destroy_context(chan);
+
+	pfifo->reassign(dev, true);
+
+	/* Release the channel's resources */
+	nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
+	if (chan->pushbuf_bo) {
+		nouveau_bo_unpin(chan->pushbuf_bo);
+		nouveau_bo_ref(NULL, &chan->pushbuf_bo);
+	}
+	nouveau_gpuobj_channel_takedown(chan);
+	nouveau_notifier_takedown_channel(chan);
+	if (chan->user)
+		iounmap(chan->user);
+
+	dev_priv->fifos[chan->id] = NULL;
+	dev_priv->fifo_alloc_count--;
+	kfree(chan);
+}
+
+/* cleans up all the fifos from file_priv */
+void
+nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	int i;
+
+	NV_DEBUG(dev, "clearing FIFO enables from file_priv\n");
+	for (i = 0; i < engine->fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->file_priv == file_priv)
+			nouveau_channel_free(chan);
+	}
+}
+
+int
+nouveau_channel_owner(struct drm_device *dev, struct drm_file *file_priv,
+		      int channel)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	if (channel >= engine->fifo.channels)
+		return 0;
+	if (dev_priv->fifos[channel] == NULL)
+		return 0;
+
+	return (dev_priv->fifos[channel]->file_priv == file_priv);
+}
+
+/***********************************
+ * ioctls wrapping the functions
+ ***********************************/
+
+static int
+nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_channel_alloc *init = data;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (dev_priv->engine.graph.accel_blocked)
+		return -ENODEV;
+
+	if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
+		return -EINVAL;
+
+	ret = nouveau_channel_alloc(dev, &chan, file_priv,
+				    init->fb_ctxdma_handle,
+				    init->tt_ctxdma_handle);
+	if (ret)
+		return ret;
+	init->channel  = chan->id;
+
+	init->subchan[0].handle = NvM2MF;
+	if (dev_priv->card_type < NV_50)
+		init->subchan[0].grclass = 0x0039;
+	else
+		init->subchan[0].grclass = 0x5039;
+	init->subchan[1].handle = NvSw;
+	init->subchan[1].grclass = NV_SW;
+	init->nr_subchan = 2;
+
+	/* Named memory object area */
+	ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
+				    &init->notifier_handle);
+	if (ret) {
+		nouveau_channel_free(chan);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_nouveau_channel_free *cfree = data;
+	struct nouveau_channel *chan;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
+
+	nouveau_channel_free(chan);
+	return 0;
+}
+
+/***********************************
+ * finally, the ioctl table
+ ***********************************/
+
+struct drm_ioctl_desc nouveau_ioctls[] = {
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH),
+};
+
+int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,846 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include <acpi/button.h>
+
+#include "drmP.h"
+#include "drm_edid.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_connector.h"
+#include "nouveau_hw.h"
+
+static inline struct drm_encoder_slave_funcs *
+get_slave_funcs(struct nouveau_encoder *enc)
+{
+	return to_encoder_slave(to_drm_encoder(enc))->slave_funcs;
+}
+
+static struct nouveau_encoder *
+find_encoder_by_type(struct drm_connector *connector, int type)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_encoder *nv_encoder;
+	struct drm_mode_object *obj;
+	int i, id;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		id = connector->encoder_ids[i];
+		if (!id)
+			break;
+
+		obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+
+		if (type == OUTPUT_ANY || nv_encoder->dcb->type == type)
+			return nv_encoder;
+	}
+
+	return NULL;
+}
+
+struct nouveau_connector *
+nouveau_encoder_connector_get(struct nouveau_encoder *encoder)
+{
+	struct drm_device *dev = to_drm_encoder(encoder)->dev;
+	struct drm_connector *drm_connector;
+
+	list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
+		if (drm_connector->encoder == to_drm_encoder(encoder))
+			return nouveau_connector(drm_connector);
+	}
+
+	return NULL;
+}
+
+
+static void
+nouveau_connector_destroy(struct drm_connector *drm_connector)
+{
+	struct nouveau_connector *nv_connector =
+		nouveau_connector(drm_connector);
+	struct drm_device *dev;
+
+	if (!nv_connector)
+		return;
+
+	dev = nv_connector->base.dev;
+	NV_DEBUG_KMS(dev, "\n");
+
+	kfree(nv_connector->edid);
+	drm_sysfs_connector_remove(drm_connector);
+	drm_connector_cleanup(drm_connector);
+	kfree(drm_connector);
+}
+
+static void
+nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_50)
+		return;
+
+	*flags = 0;
+	if (NVLockVgaCrtcs(dev_priv->dev, false))
+		*flags |= 1;
+	if (nv_heads_tied(dev_priv->dev))
+		*flags |= 2;
+
+	if (*flags & 2)
+		NVSetOwner(dev_priv->dev, 0); /* necessary? */
+}
+
+static void
+nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+
+	if (dev_priv->card_type >= NV_50)
+		return;
+
+	if (flags & 2)
+		NVSetOwner(dev_priv->dev, 4);
+	if (flags & 1)
+		NVLockVgaCrtcs(dev_priv->dev, true);
+}
+
+static struct nouveau_i2c_chan *
+nouveau_connector_ddc_detect(struct drm_connector *connector,
+			     struct nouveau_encoder **pnv_encoder)
+{
+	struct drm_device *dev = connector->dev;
+	uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
+	int ret, flags, i;
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = 0x50,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = 0x50,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = buf,
+		}
+	};
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		struct nouveau_i2c_chan *i2c = NULL;
+		struct nouveau_encoder *nv_encoder;
+		struct drm_mode_object *obj;
+		int id;
+
+		id = connector->encoder_ids[i];
+		if (!id)
+			break;
+
+		obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+
+		if (nv_encoder->dcb->i2c_index < 0xf)
+			i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+		if (!i2c)
+			continue;
+
+		nouveau_connector_ddc_prepare(connector, &flags);
+		ret = i2c_transfer(&i2c->adapter, msgs, 2);
+		nouveau_connector_ddc_finish(connector, flags);
+
+		if (ret == 2) {
+			*pnv_encoder = nv_encoder;
+			return i2c;
+		}
+	}
+
+	return NULL;
+}
+
+static void
+nouveau_connector_set_encoder(struct drm_connector *connector,
+			      struct nouveau_encoder *nv_encoder)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+	struct drm_device *dev = connector->dev;
+
+	if (nv_connector->detected_encoder == nv_encoder)
+		return;
+	nv_connector->detected_encoder = nv_encoder;
+
+	if (nv_encoder->dcb->type == OUTPUT_LVDS ||
+	    nv_encoder->dcb->type == OUTPUT_TMDS) {
+		connector->doublescan_allowed = false;
+		connector->interlace_allowed = false;
+	} else {
+		connector->doublescan_allowed = true;
+		if (dev_priv->card_type == NV_20 ||
+		   (dev_priv->card_type == NV_10 &&
+		    (dev->pci_device & 0x0ff0) != 0x0100 &&
+		    (dev->pci_device & 0x0ff0) != 0x0150))
+			/* HW is broken */
+			connector->interlace_allowed = false;
+		else
+			connector->interlace_allowed = true;
+	}
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+		drm_connector_property_set_value(connector,
+			dev->mode_config.dvi_i_subconnector_property,
+			nv_encoder->dcb->type == OUTPUT_TMDS ?
+			DRM_MODE_SUBCONNECTOR_DVID :
+			DRM_MODE_SUBCONNECTOR_DVIA);
+	}
+}
+
+static enum drm_connector_status
+nouveau_connector_detect(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = NULL;
+	struct nouveau_i2c_chan *i2c;
+	int type, flags;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+		nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+	if (nv_encoder && nv_connector->native_mode) {
+#ifdef CONFIG_ACPI
+		if (!nouveau_ignorelid && !acpi_lid_open())
+			return connector_status_disconnected;
+#endif
+		nouveau_connector_set_encoder(connector, nv_encoder);
+		return connector_status_connected;
+	}
+
+	/* Cleanup the previous EDID block. */
+	if (nv_connector->edid) {
+		drm_mode_connector_update_edid_property(connector, NULL);
+		kfree(nv_connector->edid);
+		nv_connector->edid = NULL;
+	}
+
+	i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
+	if (i2c) {
+		nouveau_connector_ddc_prepare(connector, &flags);
+		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
+		nouveau_connector_ddc_finish(connector, flags);
+		drm_mode_connector_update_edid_property(connector,
+							nv_connector->edid);
+		if (!nv_connector->edid) {
+			NV_ERROR(dev, "DDC responded, but no EDID for %s\n",
+				 drm_get_connector_name(connector));
+			goto detect_analog;
+		}
+
+		if (nv_encoder->dcb->type == OUTPUT_DP &&
+		    !nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
+			NV_ERROR(dev, "Detected %s, but failed init\n",
+				 drm_get_connector_name(connector));
+			return connector_status_disconnected;
+		}
+
+		/* Override encoder type for DVI-I based on whether EDID
+		 * says the display is digital or analog, both use the
+		 * same i2c channel so the value returned from ddc_detect
+		 * isn't necessarily correct.
+		 */
+		if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+			if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
+				type = OUTPUT_TMDS;
+			else
+				type = OUTPUT_ANALOG;
+
+			nv_encoder = find_encoder_by_type(connector, type);
+			if (!nv_encoder) {
+				NV_ERROR(dev, "Detected %d encoder on %s, "
+					      "but no object!\n", type,
+					 drm_get_connector_name(connector));
+				return connector_status_disconnected;
+			}
+		}
+
+		nouveau_connector_set_encoder(connector, nv_encoder);
+		return connector_status_connected;
+	}
+
+detect_analog:
+	nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
+	if (!nv_encoder)
+		nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
+	if (nv_encoder) {
+		struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
+		struct drm_encoder_helper_funcs *helper =
+						encoder->helper_private;
+
+		if (helper->detect(encoder, connector) ==
+						connector_status_connected) {
+			nouveau_connector_set_encoder(connector, nv_encoder);
+			return connector_status_connected;
+		}
+
+	}
+
+	return connector_status_disconnected;
+}
+
+static void
+nouveau_connector_force(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_encoder *nv_encoder;
+	int type;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
+		if (connector->force == DRM_FORCE_ON_DIGITAL)
+			type = OUTPUT_TMDS;
+		else
+			type = OUTPUT_ANALOG;
+	} else
+		type = OUTPUT_ANY;
+
+	nv_encoder = find_encoder_by_type(connector, type);
+	if (!nv_encoder) {
+		NV_ERROR(dev, "can't find encoder to force %s on!\n",
+			 drm_get_connector_name(connector));
+		connector->status = connector_status_disconnected;
+		return;
+	}
+
+	nouveau_connector_set_encoder(connector, nv_encoder);
+}
+
+static int
+nouveau_connector_set_property(struct drm_connector *connector,
+			       struct drm_property *property, uint64_t value)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	/* Scaling mode */
+	if (property == dev->mode_config.scaling_mode_property) {
+		struct nouveau_crtc *nv_crtc = NULL;
+		bool modeset = false;
+
+		switch (value) {
+		case DRM_MODE_SCALE_NONE:
+		case DRM_MODE_SCALE_FULLSCREEN:
+		case DRM_MODE_SCALE_CENTER:
+		case DRM_MODE_SCALE_ASPECT:
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		/* LVDS always needs gpu scaling */
+		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+		    value == DRM_MODE_SCALE_NONE)
+			return -EINVAL;
+
+		/* Changing between GPU and panel scaling requires a full
+		 * modeset
+		 */
+		if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) ||
+		    (value == DRM_MODE_SCALE_NONE))
+			modeset = true;
+		nv_connector->scaling_mode = value;
+
+		if (connector->encoder && connector->encoder->crtc)
+			nv_crtc = nouveau_crtc(connector->encoder->crtc);
+		if (!nv_crtc)
+			return 0;
+
+		if (modeset || !nv_crtc->set_scale) {
+			ret = drm_crtc_helper_set_mode(&nv_crtc->base,
+							&nv_crtc->base.mode,
+							nv_crtc->base.x,
+							nv_crtc->base.y, NULL);
+			if (!ret)
+				return -EINVAL;
+		} else {
+			ret = nv_crtc->set_scale(nv_crtc, value, true);
+			if (ret)
+				return ret;
+		}
+
+		return 0;
+	}
+
+	/* Dithering */
+	if (property == dev->mode_config.dithering_mode_property) {
+		struct nouveau_crtc *nv_crtc = NULL;
+
+		if (value == DRM_MODE_DITHERING_ON)
+			nv_connector->use_dithering = true;
+		else
+			nv_connector->use_dithering = false;
+
+		if (connector->encoder && connector->encoder->crtc)
+			nv_crtc = nouveau_crtc(connector->encoder->crtc);
+
+		if (!nv_crtc || !nv_crtc->set_dither)
+			return 0;
+
+		return nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering,
+					   true);
+	}
+
+	if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV)
+		return get_slave_funcs(nv_encoder)->
+			set_property(to_drm_encoder(nv_encoder), connector, property, value);
+
+	return -EINVAL;
+}
+
+static struct drm_display_mode *
+nouveau_connector_native_mode(struct nouveau_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_display_mode *mode, *largest = NULL;
+	int high_w = 0, high_h = 0, high_v = 0;
+
+	/* Use preferred mode if there is one.. */
+	list_for_each_entry(mode, &connector->base.probed_modes, head) {
+		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
+			NV_DEBUG_KMS(dev, "native mode from preferred\n");
+			return drm_mode_duplicate(dev, mode);
+		}
+	}
+
+	/* Otherwise, take the resolution with the largest width, then height,
+	 * then vertical refresh
+	 */
+	list_for_each_entry(mode, &connector->base.probed_modes, head) {
+		if (mode->hdisplay < high_w)
+			continue;
+
+		if (mode->hdisplay == high_w && mode->vdisplay < high_h)
+			continue;
+
+		if (mode->hdisplay == high_w && mode->vdisplay == high_h &&
+		    mode->vrefresh < high_v)
+			continue;
+
+		high_w = mode->hdisplay;
+		high_h = mode->vdisplay;
+		high_v = mode->vrefresh;
+		largest = mode;
+	}
+
+	NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n",
+		      high_w, high_h, high_v);
+	return largest ? drm_mode_duplicate(dev, largest) : NULL;
+}
+
+struct moderec {
+	int hdisplay;
+	int vdisplay;
+};
+
+static struct moderec scaler_modes[] = {
+	{ 1920, 1200 },
+	{ 1920, 1080 },
+	{ 1680, 1050 },
+	{ 1600, 1200 },
+	{ 1400, 1050 },
+	{ 1280, 1024 },
+	{ 1280, 960 },
+	{ 1152, 864 },
+	{ 1024, 768 },
+	{ 800, 600 },
+	{ 720, 400 },
+	{ 640, 480 },
+	{ 640, 400 },
+	{ 640, 350 },
+	{}
+};
+
+static int
+nouveau_connector_scaler_modes_add(struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_display_mode *native = nv_connector->native_mode, *m;
+	struct drm_device *dev = connector->dev;
+	struct moderec *mode = &scaler_modes[0];
+	int modes = 0;
+
+	if (!native)
+		return 0;
+
+	while (mode->hdisplay) {
+		if (mode->hdisplay <= native->hdisplay &&
+		    mode->vdisplay <= native->vdisplay) {
+			m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay,
+					 drm_mode_vrefresh(native), false,
+					 false, false);
+			if (!m)
+				continue;
+
+			m->type |= DRM_MODE_TYPE_DRIVER;
+
+			drm_mode_probed_add(connector, m);
+			modes++;
+		}
+
+		mode++;
+	}
+
+	return modes;
+}
+
+static int
+nouveau_connector_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	int ret = 0;
+
+	/* If we're not LVDS, destroy the previous native mode, the attached
+	 * monitor could have changed.
+	 */
+	if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
+	    nv_connector->native_mode) {
+		drm_mode_destroy(dev, nv_connector->native_mode);
+		nv_connector->native_mode = NULL;
+	}
+
+	if (nv_connector->edid)
+		ret = drm_add_edid_modes(connector, nv_connector->edid);
+
+	/* Find the native mode if this is a digital panel, if we didn't
+	 * find any modes through DDC previously add the native mode to
+	 * the list of modes.
+	 */
+	if (!nv_connector->native_mode)
+		nv_connector->native_mode =
+			nouveau_connector_native_mode(nv_connector);
+	if (ret == 0 && nv_connector->native_mode) {
+		struct drm_display_mode *mode;
+
+		mode = drm_mode_duplicate(dev, nv_connector->native_mode);
+		drm_mode_probed_add(connector, mode);
+		ret = 1;
+	}
+
+	if (nv_encoder->dcb->type == OUTPUT_TV)
+		ret = get_slave_funcs(nv_encoder)->
+			get_modes(to_drm_encoder(nv_encoder), connector);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+		ret += nouveau_connector_scaler_modes_add(connector);
+
+	return ret;
+}
+
+static int
+nouveau_connector_mode_valid(struct drm_connector *connector,
+			     struct drm_display_mode *mode)
+{
+	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
+	unsigned min_clock = 25000, max_clock = min_clock;
+	unsigned clock = mode->clock;
+
+	switch (nv_encoder->dcb->type) {
+	case OUTPUT_LVDS:
+		BUG_ON(!nv_connector->native_mode);
+		if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
+		    mode->vdisplay > nv_connector->native_mode->vdisplay)
+			return MODE_PANEL;
+
+		min_clock = 0;
+		max_clock = 400000;
+		break;
+	case OUTPUT_TMDS:
+		if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
+		    (dev_priv->card_type < NV_50 &&
+		     !nv_encoder->dcb->duallink_possible))
+			max_clock = 165000;
+		else
+			max_clock = 330000;
+		break;
+	case OUTPUT_ANALOG:
+		max_clock = nv_encoder->dcb->crtconf.maxfreq;
+		if (!max_clock)
+			max_clock = 350000;
+		break;
+	case OUTPUT_TV:
+		return get_slave_funcs(nv_encoder)->
+			mode_valid(to_drm_encoder(nv_encoder), mode);
+	case OUTPUT_DP:
+		if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7)
+			max_clock = nv_encoder->dp.link_nr * 270000;
+		else
+			max_clock = nv_encoder->dp.link_nr * 162000;
+
+		clock *= 3;
+		break;
+	}
+
+	if (clock < min_clock)
+		return MODE_CLOCK_LOW;
+
+	if (clock > max_clock)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+nouveau_connector_best_encoder(struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+
+	if (nv_connector->detected_encoder)
+		return to_drm_encoder(nv_connector->detected_encoder);
+
+	return NULL;
+}
+
+static const struct drm_connector_helper_funcs
+nouveau_connector_helper_funcs = {
+	.get_modes = nouveau_connector_get_modes,
+	.mode_valid = nouveau_connector_mode_valid,
+	.best_encoder = nouveau_connector_best_encoder,
+};
+
+static const struct drm_connector_funcs
+nouveau_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.save = NULL,
+	.restore = NULL,
+	.detect = nouveau_connector_detect,
+	.destroy = nouveau_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = nouveau_connector_set_property,
+	.force = nouveau_connector_force
+};
+
+static int
+nouveau_connector_create_lvds(struct drm_device *dev,
+			      struct drm_connector *connector)
+{
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_i2c_chan *i2c = NULL;
+	struct nouveau_encoder *nv_encoder;
+	struct drm_display_mode native, *mode, *temp;
+	bool dummy, if_is_24bit = false;
+	int ret, flags;
+
+	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+	if (!nv_encoder)
+		return -ENODEV;
+
+	ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
+	if (ret) {
+		NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
+		return ret;
+	}
+	nv_connector->use_dithering = !if_is_24bit;
+
+	/* Firstly try getting EDID over DDC, if allowed and I2C channel
+	 * is available.
+	 */
+	if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
+		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+
+	if (i2c) {
+		nouveau_connector_ddc_prepare(connector, &flags);
+		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
+		nouveau_connector_ddc_finish(connector, flags);
+	}
+
+	/* If no EDID found above, and the VBIOS indicates a hardcoded
+	 * modeline is avalilable for the panel, set it as the panel's
+	 * native mode and exit.
+	 */
+	if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
+	     (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
+	      dev_priv->VBIOS.pub.fp_no_ddc)) {
+		nv_connector->native_mode = drm_mode_duplicate(dev, &native);
+		goto out;
+	}
+
+	/* Still nothing, some VBIOS images have a hardcoded EDID block
+	 * stored for the panel stored in them.
+	 */
+	if (!nv_connector->edid && !nv_connector->native_mode &&
+	    !dev_priv->VBIOS.pub.fp_no_ddc) {
+		struct edid *edid =
+			(struct edid *)nouveau_bios_embedded_edid(dev);
+		if (edid) {
+			nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+			*(nv_connector->edid) = *edid;
+		}
+	}
+
+	if (!nv_connector->edid)
+		goto out;
+
+	/* We didn't find/use a panel mode from the VBIOS, so parse the EDID
+	 * block and look for the preferred mode there.
+	 */
+	ret = drm_add_edid_modes(connector, nv_connector->edid);
+	if (ret == 0)
+		goto out;
+	nv_connector->detected_encoder = nv_encoder;
+	nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
+	list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
+		drm_mode_remove(connector, mode);
+
+out:
+	if (!nv_connector->native_mode) {
+		NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
+			      "determine its native mode.  Disabling.\n");
+		return -ENODEV;
+	}
+
+	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
+	return 0;
+}
+
+int
+nouveau_connector_create(struct drm_device *dev, int index, int type)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_connector *nv_connector = NULL;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
+	if (!nv_connector)
+		return -ENOMEM;
+	nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
+	connector = &nv_connector->base;
+
+	switch (type) {
+	case DRM_MODE_CONNECTOR_VGA:
+		NV_INFO(dev, "Detected a VGA connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DVID:
+		NV_INFO(dev, "Detected a DVI-D connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DVII:
+		NV_INFO(dev, "Detected a DVI-I connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_LVDS:
+		NV_INFO(dev, "Detected a LVDS connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_TV:
+		NV_INFO(dev, "Detected a TV connector\n");
+		break;
+	case DRM_MODE_CONNECTOR_DisplayPort:
+		NV_INFO(dev, "Detected a DisplayPort connector\n");
+		break;
+	default:
+		NV_ERROR(dev, "Unknown connector, this is not good.\n");
+		break;
+	}
+
+	/* defaults, will get overridden in detect() */
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
+	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
+
+	/* Init DVI-I specific properties */
+	if (type == DRM_MODE_CONNECTOR_DVII) {
+		drm_mode_create_dvi_i_properties(dev);
+		drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
+		drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
+	}
+
+	if (type != DRM_MODE_CONNECTOR_LVDS)
+		nv_connector->use_dithering = false;
+
+	if (type == DRM_MODE_CONNECTOR_DVID ||
+	    type == DRM_MODE_CONNECTOR_DVII ||
+	    type == DRM_MODE_CONNECTOR_LVDS ||
+	    type == DRM_MODE_CONNECTOR_DisplayPort) {
+		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
+
+		drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property,
+					      nv_connector->scaling_mode);
+		drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property,
+					      nv_connector->use_dithering ? DRM_MODE_DITHERING_ON
+					      : DRM_MODE_DITHERING_OFF);
+
+	} else {
+		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
+
+		if (type == DRM_MODE_CONNECTOR_VGA  &&
+				dev_priv->card_type >= NV_50) {
+			drm_connector_attach_property(connector,
+					dev->mode_config.scaling_mode_property,
+					nv_connector->scaling_mode);
+		}
+	}
+
+	/* attach encoders */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (nv_encoder->dcb->connector != index)
+			continue;
+
+		if (get_slave_funcs(nv_encoder))
+			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+
+		drm_mode_connector_attach_encoder(connector, encoder);
+	}
+
+	drm_sysfs_connector_add(connector);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+		ret = nouveau_connector_create_lvds(dev, connector);
+		if (ret) {
+			connector->funcs->destroy(connector);
+			return ret;
+		}
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_connector.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NOUVEAU_CONNECTOR_H__
+#define __NOUVEAU_CONNECTOR_H__
+
+#include "drm_edid.h"
+#include "nouveau_i2c.h"
+
+struct nouveau_connector {
+	struct drm_connector base;
+
+	struct dcb_connector_table_entry *dcb;
+
+	int scaling_mode;
+	bool use_dithering;
+
+	struct nouveau_encoder *detected_encoder;
+	struct edid *edid;
+	struct drm_display_mode *native_mode;
+};
+
+static inline struct nouveau_connector *nouveau_connector(
+						struct drm_connector *con)
+{
+	return container_of(con, struct nouveau_connector, base);
+}
+
+int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
+
+#endif /* __NOUVEAU_CONNECTOR_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_crtc.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_crtc.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_crtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_crtc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NOUVEAU_CRTC_H__
+#define __NOUVEAU_CRTC_H__
+
+struct nouveau_crtc {
+	struct drm_crtc base;
+
+	int index;
+
+	struct drm_display_mode *mode;
+
+	uint32_t dpms_saved_fp_control;
+	uint32_t fp_users;
+	int saturation;
+	int sharpness;
+	int last_dpms;
+
+	struct {
+		int cpp;
+		bool blanked;
+		uint32_t offset;
+		uint32_t tile_flags;
+	} fb;
+
+	struct {
+		struct nouveau_bo *nvbo;
+		bool visible;
+		uint32_t offset;
+		void (*set_offset)(struct nouveau_crtc *, uint32_t offset);
+		void (*set_pos)(struct nouveau_crtc *, int x, int y);
+		void (*hide)(struct nouveau_crtc *, bool update);
+		void (*show)(struct nouveau_crtc *, bool update);
+	} cursor;
+
+	struct {
+		struct nouveau_bo *nvbo;
+		uint16_t r[256];
+		uint16_t g[256];
+		uint16_t b[256];
+		int depth;
+	} lut;
+
+	int (*set_dither)(struct nouveau_crtc *crtc, bool on, bool update);
+	int (*set_scale)(struct nouveau_crtc *crtc, int mode, bool update);
+};
+
+static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct nouveau_crtc, base);
+}
+
+static inline struct drm_crtc *to_drm_crtc(struct nouveau_crtc *crtc)
+{
+	return &crtc->base;
+}
+
+int nv50_crtc_create(struct drm_device *dev, int index);
+int nv50_cursor_init(struct nouveau_crtc *);
+void nv50_cursor_fini(struct nouveau_crtc *);
+int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv,
+			 uint32_t buffer_handle, uint32_t width,
+			 uint32_t height);
+int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y);
+
+int nv04_cursor_init(struct nouveau_crtc *);
+
+struct nouveau_connector *
+nouveau_crtc_connector_get(struct nouveau_crtc *crtc);
+
+#endif /* __NOUVEAU_CRTC_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 Red Hat <bskeggs@redhat.com>
+ *
+ * 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 OWNER(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:
+ *  Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include <linux/debugfs.h>
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+static int
+nouveau_debugfs_channel_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_channel *chan = node->info_ent->data;
+
+	seq_printf(m, "channel id    : %d\n", chan->id);
+
+	seq_printf(m, "cpu fifo state:\n");
+	seq_printf(m, "          base: 0x%08x\n", chan->pushbuf_base);
+	seq_printf(m, "           max: 0x%08x\n", chan->dma.max << 2);
+	seq_printf(m, "           cur: 0x%08x\n", chan->dma.cur << 2);
+	seq_printf(m, "           put: 0x%08x\n", chan->dma.put << 2);
+	seq_printf(m, "          free: 0x%08x\n", chan->dma.free << 2);
+
+	seq_printf(m, "gpu fifo state:\n");
+	seq_printf(m, "           get: 0x%08x\n",
+					nvchan_rd32(chan, chan->user_get));
+	seq_printf(m, "           put: 0x%08x\n",
+					nvchan_rd32(chan, chan->user_put));
+
+	seq_printf(m, "last fence    : %d\n", chan->fence.sequence);
+	seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack);
+	return 0;
+}
+
+int
+nouveau_debugfs_channel_init(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_minor *minor = chan->dev->primary;
+	int ret;
+
+	if (!dev_priv->debugfs.channel_root) {
+		dev_priv->debugfs.channel_root =
+			debugfs_create_dir("channel", minor->debugfs_root);
+		if (!dev_priv->debugfs.channel_root)
+			return -ENOENT;
+	}
+
+	snprintf(chan->debugfs.name, 32, "%d", chan->id);
+	chan->debugfs.info.name = chan->debugfs.name;
+	chan->debugfs.info.show = nouveau_debugfs_channel_info;
+	chan->debugfs.info.driver_features = 0;
+	chan->debugfs.info.data = chan;
+
+	ret = drm_debugfs_create_files(&chan->debugfs.info, 1,
+				       dev_priv->debugfs.channel_root,
+				       chan->dev->primary);
+	if (ret == 0)
+		chan->debugfs.active = true;
+	return ret;
+}
+
+void
+nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+
+	if (!chan->debugfs.active)
+		return;
+
+	drm_debugfs_remove_files(&chan->debugfs.info, 1, chan->dev->primary);
+	chan->debugfs.active = false;
+
+	if (chan == dev_priv->channel) {
+		debugfs_remove(dev_priv->debugfs.channel_root);
+		dev_priv->debugfs.channel_root = NULL;
+	}
+}
+
+static int
+nouveau_debugfs_chipset_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *dev = minor->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t ppci_0;
+
+	ppci_0 = nv_rd32(dev, dev_priv->chipset >= 0x40 ? 0x88000 : 0x1800);
+
+	seq_printf(m, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev, NV03_PMC_BOOT_0));
+	seq_printf(m, "PCI ID    : 0x%04x:0x%04x\n",
+		   ppci_0 & 0xffff, ppci_0 >> 16);
+	return 0;
+}
+
+static int
+nouveau_debugfs_memory_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_minor *minor = node->minor;
+	struct drm_device *dev = minor->dev;
+
+	seq_printf(m, "VRAM total: %dKiB\n",
+		   (int)(nouveau_mem_fb_amount(dev) >> 10));
+	return 0;
+}
+
+static struct drm_info_list nouveau_debugfs_list[] = {
+	{ "chipset", nouveau_debugfs_chipset_info, 0, NULL },
+	{ "memory", nouveau_debugfs_memory_info, 0, NULL },
+};
+#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
+
+int
+nouveau_debugfs_init(struct drm_minor *minor)
+{
+	drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
+				 minor->debugfs_root, minor);
+	return 0;
+}
+
+void
+nouveau_debugfs_takedown(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
+				 minor);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+
+static void
+nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
+{
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	struct drm_device *dev = drm_fb->dev;
+
+	if (drm_fb->fbdev)
+		nouveau_fbcon_remove(dev, drm_fb);
+
+	if (fb->nvbo) {
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(fb->nvbo->gem);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	drm_framebuffer_cleanup(drm_fb);
+	kfree(fb);
+}
+
+static int
+nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
+				       struct drm_file *file_priv,
+				       unsigned int *handle)
+{
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+
+	return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle);
+}
+
+static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
+	.destroy = nouveau_user_framebuffer_destroy,
+	.create_handle = nouveau_user_framebuffer_create_handle,
+};
+
+struct drm_framebuffer *
+nouveau_framebuffer_create(struct drm_device *dev, struct nouveau_bo *nvbo,
+			   struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct nouveau_framebuffer *fb;
+	int ret;
+
+	fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
+	if (!fb)
+		return NULL;
+
+	ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs);
+	if (ret) {
+		kfree(fb);
+		return NULL;
+	}
+
+	drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+
+	fb->nvbo = nvbo;
+	return &fb->base;
+}
+
+static struct drm_framebuffer *
+nouveau_user_framebuffer_create(struct drm_device *dev,
+				struct drm_file *file_priv,
+				struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *gem;
+
+	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
+	if (!gem)
+		return NULL;
+
+	fb = nouveau_framebuffer_create(dev, nouveau_gem_object(gem), mode_cmd);
+	if (!fb) {
+		drm_gem_object_unreference(gem);
+		return NULL;
+	}
+
+	return fb;
+}
+
+const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
+	.fb_create = nouveau_user_framebuffer_create,
+	.fb_changed = nouveau_fbcon_probe,
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+void
+nouveau_dma_pre_init(struct nouveau_channel *chan)
+{
+	chan->dma.max  = (chan->pushbuf_bo->bo.mem.size >> 2) - 2;
+	chan->dma.put  = 0;
+	chan->dma.cur  = chan->dma.put;
+	chan->dma.free = chan->dma.max - chan->dma.cur;
+}
+
+int
+nouveau_dma_init(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *m2mf = NULL;
+	struct nouveau_gpuobj *nvsw = NULL;
+	int ret, i;
+
+	/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
+	ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ?
+				    0x0039 : 0x5039, &m2mf);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, NvM2MF, m2mf, NULL);
+	if (ret)
+		return ret;
+
+	/* Create an NV_SW object for various sync purposes */
+	ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL);
+	if (ret)
+		return ret;
+
+	/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
+	ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy);
+	if (ret)
+		return ret;
+
+	/* Map push buffer */
+	ret = nouveau_bo_map(chan->pushbuf_bo);
+	if (ret)
+		return ret;
+
+	/* Map M2MF notifier object - fbcon. */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = nouveau_bo_map(chan->notifier_bo);
+		if (ret)
+			return ret;
+	}
+
+	/* Insert NOPS for NOUVEAU_DMA_SKIPS */
+	ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+		OUT_RING(chan, 0);
+
+	/* Initialise NV_MEMORY_TO_MEMORY_FORMAT */
+	ret = RING_SPACE(chan, 4);
+	if (ret)
+		return ret;
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
+	OUT_RING(chan, NvM2MF);
+	BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+	OUT_RING(chan, NvNotify0);
+
+	/* Initialise NV_SW */
+	ret = RING_SPACE(chan, 2);
+	if (ret)
+		return ret;
+	BEGIN_RING(chan, NvSubSw, 0, 1);
+	OUT_RING(chan, NvSw);
+
+	/* Sit back and pray the channel works.. */
+	FIRE_RING(chan);
+
+	return 0;
+}
+
+void
+OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
+{
+	bool is_iomem;
+	u32 *mem = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap, &is_iomem);
+	mem = &mem[chan->dma.cur];
+	if (is_iomem)
+		memcpy_toio((void __force __iomem *)mem, data, nr_dwords * 4);
+	else
+		memcpy(mem, data, nr_dwords * 4);
+	chan->dma.cur += nr_dwords;
+}
+
+/* Fetch and adjust GPU GET pointer
+ *
+ * Returns:
+ *  value >= 0, the adjusted GET pointer
+ *  -EINVAL if GET pointer currently outside main push buffer
+ *  -EBUSY if timeout exceeded
+ */
+static inline int
+READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout)
+{
+	uint32_t val;
+
+	val = nvchan_rd32(chan, chan->user_get);
+
+	/* reset counter as long as GET is still advancing, this is
+	 * to avoid misdetecting a GPU lockup if the GPU happens to
+	 * just be processing an operation that takes a long time
+	 */
+	if (val != *prev_get) {
+		*prev_get = val;
+		*timeout = 0;
+	}
+
+	if ((++*timeout & 0xff) == 0) {
+		DRM_UDELAY(1);
+		if (*timeout > 100000)
+			return -EBUSY;
+	}
+
+	if (val < chan->pushbuf_base ||
+	    val > chan->pushbuf_base + (chan->dma.max << 2))
+		return -EINVAL;
+
+	return (val - chan->pushbuf_base) >> 2;
+}
+
+int
+nouveau_dma_wait(struct nouveau_channel *chan, int size)
+{
+	uint32_t prev_get = 0, cnt = 0;
+	int get;
+
+	while (chan->dma.free < size) {
+		get = READ_GET(chan, &prev_get, &cnt);
+		if (unlikely(get == -EBUSY))
+			return -EBUSY;
+
+		/* loop until we have a usable GET pointer.  the value
+		 * we read from the GPU may be outside the main ring if
+		 * PFIFO is processing a buffer called from the main ring,
+		 * discard these values until something sensible is seen.
+		 *
+		 * the other case we discard GET is while the GPU is fetching
+		 * from the SKIPS area, so the code below doesn't have to deal
+		 * with some fun corner cases.
+		 */
+		if (unlikely(get == -EINVAL) || get < NOUVEAU_DMA_SKIPS)
+			continue;
+
+		if (get <= chan->dma.cur) {
+			/* engine is fetching behind us, or is completely
+			 * idle (GET == PUT) so we have free space up until
+			 * the end of the push buffer
+			 *
+			 * we can only hit that path once per call due to
+			 * looping back to the beginning of the push buffer,
+			 * we'll hit the fetching-ahead-of-us path from that
+			 * point on.
+			 *
+			 * the *one* exception to that rule is if we read
+			 * GET==PUT, in which case the below conditional will
+			 * always succeed and break us out of the wait loop.
+			 */
+			chan->dma.free = chan->dma.max - chan->dma.cur;
+			if (chan->dma.free >= size)
+				break;
+
+			/* not enough space left at the end of the push buffer,
+			 * instruct the GPU to jump back to the start right
+			 * after processing the currently pending commands.
+			 */
+			OUT_RING(chan, chan->pushbuf_base | 0x20000000);
+
+			/* wait for GET to depart from the skips area.
+			 * prevents writing GET==PUT and causing a race
+			 * condition that causes us to think the GPU is
+			 * idle when it's not.
+			 */
+			do {
+				get = READ_GET(chan, &prev_get, &cnt);
+				if (unlikely(get == -EBUSY))
+					return -EBUSY;
+				if (unlikely(get == -EINVAL))
+					continue;
+			} while (get <= NOUVEAU_DMA_SKIPS);
+			WRITE_PUT(NOUVEAU_DMA_SKIPS);
+
+			/* we're now submitting commands at the start of
+			 * the push buffer.
+			 */
+			chan->dma.cur  =
+			chan->dma.put  = NOUVEAU_DMA_SKIPS;
+		}
+
+		/* engine fetching ahead of us, we have space up until the
+		 * current GET pointer.  the "- 1" is to ensure there's
+		 * space left to emit a jump back to the beginning of the
+		 * push buffer if we require it.  we can never get GET == PUT
+		 * here, so this is safe.
+		 */
+		chan->dma.free = get - chan->dma.cur - 1;
+	}
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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 __NOUVEAU_DMA_H__
+#define __NOUVEAU_DMA_H__
+
+#ifndef NOUVEAU_DMA_DEBUG
+#define NOUVEAU_DMA_DEBUG 0
+#endif
+
+/*
+ * There's a hw race condition where you can't jump to your PUT offset,
+ * to avoid this we jump to offset + SKIPS and fill the difference with
+ * NOPs.
+ *
+ * xf86-video-nv configures the DMA fetch size to 32 bytes, and uses
+ * a SKIPS value of 8.  Lets assume that the race condition is to do
+ * with writing into the fetch area, we configure a fetch size of 128
+ * bytes so we need a larger SKIPS value.
+ */
+#define NOUVEAU_DMA_SKIPS (128 / 4)
+
+/* Hardcoded object assignments to subchannels (subchannel id). */
+enum {
+	NvSubM2MF	= 0,
+	NvSubSw		= 1,
+	NvSub2D		= 2,
+	NvSubCtxSurf2D  = 2,
+	NvSubGdiRect    = 3,
+	NvSubImageBlit  = 4
+};
+
+/* Object handles. */
+enum {
+	NvM2MF		= 0x80000001,
+	NvDmaFB		= 0x80000002,
+	NvDmaTT		= 0x80000003,
+	NvDmaVRAM	= 0x80000004,
+	NvDmaGART	= 0x80000005,
+	NvNotify0       = 0x80000006,
+	Nv2D		= 0x80000007,
+	NvCtxSurf2D	= 0x80000008,
+	NvRop		= 0x80000009,
+	NvImagePatt	= 0x8000000a,
+	NvClipRect	= 0x8000000b,
+	NvGdiRect	= 0x8000000c,
+	NvImageBlit	= 0x8000000d,
+	NvSw		= 0x8000000e,
+
+	/* G80+ display objects */
+	NvEvoVRAM	= 0x01000000,
+	NvEvoFB16	= 0x01000001,
+	NvEvoFB32	= 0x01000002
+};
+
+#define NV_MEMORY_TO_MEMORY_FORMAT                                    0x00000039
+#define NV_MEMORY_TO_MEMORY_FORMAT_NAME                               0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF                            0x00000050
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOP                                0x00000100
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY                             0x00000104
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE                 0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN       0x00000001
+#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY                         0x00000180
+#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE                         0x00000184
+#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN                          0x0000030c
+
+#define NV50_MEMORY_TO_MEMORY_FORMAT                                  0x00005039
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200                           0x00000200
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C                           0x0000021c
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH                   0x00000238
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH                  0x0000023c
+
+static __must_check inline int
+RING_SPACE(struct nouveau_channel *chan, int size)
+{
+	if (chan->dma.free < size) {
+		int ret;
+
+		ret = nouveau_dma_wait(chan, size);
+		if (ret)
+			return ret;
+	}
+
+	chan->dma.free -= size;
+	return 0;
+}
+
+static inline void
+OUT_RING(struct nouveau_channel *chan, int data)
+{
+	if (NOUVEAU_DMA_DEBUG) {
+		NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n",
+			chan->id, chan->dma.cur << 2, data);
+	}
+
+	nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data);
+}
+
+extern void
+OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords);
+
+static inline void
+BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size)
+{
+	OUT_RING(chan, (subc << 13) | (size << 18) | mthd);
+}
+
+#define WRITE_PUT(val) do {                                                    \
+	DRM_MEMORYBARRIER();                                                   \
+	nouveau_bo_rd32(chan->pushbuf_bo, 0);                                  \
+	nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base);  \
+} while (0)
+
+static inline void
+FIRE_RING(struct nouveau_channel *chan)
+{
+	if (NOUVEAU_DMA_DEBUG) {
+		NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n",
+			chan->id, chan->dma.cur << 2);
+	}
+
+	if (chan->dma.cur == chan->dma.put)
+		return;
+	chan->accel_done = true;
+
+	WRITE_PUT(chan->dma.cur);
+	chan->dma.put = chan->dma.cur;
+}
+
+static inline void
+WIND_RING(struct nouveau_channel *chan)
+{
+	chan->dma.cur = chan->dma.put;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_dp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,575 @@
+/*
+ * Copyright 2009 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 "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_i2c.h"
+#include "nouveau_encoder.h"
+
+static int
+auxch_rd(struct drm_encoder *encoder, int address, uint8_t *buf, int size)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_i2c_chan *auxch;
+	int ret;
+
+	auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+	if (!auxch)
+		return -ENODEV;
+
+	ret = nouveau_dp_auxch(auxch, 9, address, buf, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+auxch_wr(struct drm_encoder *encoder, int address, uint8_t *buf, int size)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_i2c_chan *auxch;
+	int ret;
+
+	auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+	if (!auxch)
+		return -ENODEV;
+
+	ret = nouveau_dp_auxch(auxch, 8, address, buf, size);
+	return ret;
+}
+
+static int
+nouveau_dp_lane_count_set(struct drm_encoder *encoder, uint8_t cmd)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+
+	tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+	tmp &= ~(NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED |
+		 NV50_SOR_DP_CTRL_LANE_MASK);
+	tmp |= ((1 << (cmd & DP_LANE_COUNT_MASK)) - 1) << 16;
+	if (cmd & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+		tmp |= NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED;
+	nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+
+	return auxch_wr(encoder, DP_LANE_COUNT_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_link_bw_set(struct drm_encoder *encoder, uint8_t cmd)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	int reg = 0x614300 + (nv_encoder->or * 0x800);
+
+	tmp  = nv_rd32(dev, reg);
+	tmp &= 0xfff3ffff;
+	if (cmd == DP_LINK_BW_2_7)
+		tmp |= 0x00040000;
+	nv_wr32(dev, reg, tmp);
+
+	return auxch_wr(encoder, DP_LINK_BW_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_link_train_set(struct drm_encoder *encoder, int pattern)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t tmp;
+	uint8_t cmd;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+	int ret;
+
+	tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+	tmp &= ~NV50_SOR_DP_CTRL_TRAINING_PATTERN;
+	tmp |= (pattern << 24);
+	nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+
+	ret = auxch_rd(encoder, DP_TRAINING_PATTERN_SET, &cmd, 1);
+	if (ret)
+		return ret;
+	cmd &= ~DP_TRAINING_PATTERN_MASK;
+	cmd |= (pattern & DP_TRAINING_PATTERN_MASK);
+	return auxch_wr(encoder, DP_TRAINING_PATTERN_SET, &cmd, 1);
+}
+
+static int
+nouveau_dp_max_voltage_swing(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int i, dpe_headerlen, max_vs = 0;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe_headerlen; i++, dpse++) {
+		if (dpse->vs_level > max_vs)
+			max_vs = dpse->vs_level;
+	}
+
+	return max_vs;
+}
+
+static int
+nouveau_dp_max_pre_emphasis(struct drm_encoder *encoder, int vs)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int i, dpe_headerlen, max_pre = 0;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe_headerlen; i++, dpse++) {
+		if (dpse->vs_level != vs)
+			continue;
+
+		if (dpse->pre_level > max_pre)
+			max_pre = dpse->pre_level;
+	}
+
+	return max_pre;
+}
+
+static bool
+nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int ret, i, dpe_headerlen, vs = 0, pre = 0;
+	uint8_t request[2];
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	ret = auxch_rd(encoder, DP_ADJUST_REQUEST_LANE0_1, request, 2);
+	if (ret)
+		return false;
+
+	NV_DEBUG_KMS(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]);
+
+	/* Keep all lanes at the same level.. */
+	for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+		int lane_req = (request[i >> 1] >> ((i & 1) << 2)) & 0xf;
+		int lane_vs = lane_req & 3;
+		int lane_pre = (lane_req >> 2) & 3;
+
+		if (lane_vs > vs)
+			vs = lane_vs;
+		if (lane_pre > pre)
+			pre = lane_pre;
+	}
+
+	if (vs >= nouveau_dp_max_voltage_swing(encoder)) {
+		vs  = nouveau_dp_max_voltage_swing(encoder);
+		vs |= 4;
+	}
+
+	if (pre >= nouveau_dp_max_pre_emphasis(encoder, vs & 3)) {
+		pre  = nouveau_dp_max_pre_emphasis(encoder, vs & 3);
+		pre |= 4;
+	}
+
+	/* Update the configuration for all lanes.. */
+	for (i = 0; i < nv_encoder->dp.link_nr; i++)
+		config[i] = (pre << 3) | vs;
+
+	return true;
+}
+
+static bool
+nouveau_dp_link_train_commit(struct drm_encoder *encoder, uint8_t *config)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct bit_displayport_encoder_table_entry *dpse;
+	struct bit_displayport_encoder_table *dpe;
+	int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
+	int dpe_headerlen, ret, i;
+
+	NV_DEBUG_KMS(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		 config[0], config[1], config[2], config[3]);
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe)
+		return false;
+	dpse = (void *)((char *)dpe + dpe_headerlen);
+
+	for (i = 0; i < dpe->record_nr; i++, dpse++) {
+		if (dpse->vs_level == (config[0] & 3) &&
+		    dpse->pre_level == ((config[0] >> 3) & 3))
+			break;
+	}
+	BUG_ON(i == dpe->record_nr);
+
+	for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+		const int shift[4] = { 16, 8, 0, 24 };
+		uint32_t mask = 0xff << shift[i];
+		uint32_t reg0, reg1, reg2;
+
+		reg0  = nv_rd32(dev, NV50_SOR_DP_UNK118(or, link)) & ~mask;
+		reg0 |= (dpse->reg0 << shift[i]);
+		reg1  = nv_rd32(dev, NV50_SOR_DP_UNK120(or, link)) & ~mask;
+		reg1 |= (dpse->reg1 << shift[i]);
+		reg2  = nv_rd32(dev, NV50_SOR_DP_UNK130(or, link)) & 0xffff00ff;
+		reg2 |= (dpse->reg2 << 8);
+		nv_wr32(dev, NV50_SOR_DP_UNK118(or, link), reg0);
+		nv_wr32(dev, NV50_SOR_DP_UNK120(or, link), reg1);
+		nv_wr32(dev, NV50_SOR_DP_UNK130(or, link), reg2);
+	}
+
+	ret = auxch_wr(encoder, DP_TRAINING_LANE0_SET, config, 4);
+	if (ret)
+		return false;
+
+	return true;
+}
+
+bool
+nouveau_dp_link_train(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint8_t config[4];
+	uint8_t status[3];
+	bool cr_done, cr_max_vs, eq_done;
+	int ret = 0, i, tries, voltage;
+
+	NV_DEBUG_KMS(dev, "link training!!\n");
+train:
+	cr_done = eq_done = false;
+
+	/* set link configuration */
+	NV_DEBUG_KMS(dev, "\tbegin train: bw %d, lanes %d\n",
+		 nv_encoder->dp.link_bw, nv_encoder->dp.link_nr);
+
+	ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw);
+	if (ret)
+		return false;
+
+	config[0] = nv_encoder->dp.link_nr;
+	if (nv_encoder->dp.dpcd_version >= 0x11)
+		config[0] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	ret = nouveau_dp_lane_count_set(encoder, config[0]);
+	if (ret)
+		return false;
+
+	/* clock recovery */
+	NV_DEBUG_KMS(dev, "\tbegin cr\n");
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1);
+	if (ret)
+		goto stop;
+
+	tries = 0;
+	voltage = -1;
+	memset(config, 0x00, sizeof(config));
+	for (;;) {
+		if (!nouveau_dp_link_train_commit(encoder, config))
+			break;
+
+		udelay(100);
+
+		ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2);
+		if (ret)
+			break;
+		NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n",
+			 status[0], status[1]);
+
+		cr_done = true;
+		cr_max_vs = false;
+		for (i = 0; i < nv_encoder->dp.link_nr; i++) {
+			int lane = (status[i >> 1] >> ((i & 1) * 4)) & 0xf;
+
+			if (!(lane & DP_LANE_CR_DONE)) {
+				cr_done = false;
+				if (config[i] & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED)
+					cr_max_vs = true;
+				break;
+			}
+		}
+
+		if ((config[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
+			voltage = config[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+			tries = 0;
+		}
+
+		if (cr_done || cr_max_vs || (++tries == 5))
+			break;
+
+		if (!nouveau_dp_link_train_adjust(encoder, config))
+			break;
+	}
+
+	if (!cr_done)
+		goto stop;
+
+	/* channel equalisation */
+	NV_DEBUG_KMS(dev, "\tbegin eq\n");
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2);
+	if (ret)
+		goto stop;
+
+	for (tries = 0; tries <= 5; tries++) {
+		udelay(400);
+
+		ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3);
+		if (ret)
+			break;
+		NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n",
+			 status[0], status[1]);
+
+		eq_done = true;
+		if (!(status[2] & DP_INTERLANE_ALIGN_DONE))
+			eq_done = false;
+
+		for (i = 0; eq_done && i < nv_encoder->dp.link_nr; i++) {
+			int lane = (status[i >> 1] >> ((i & 1) * 4)) & 0xf;
+
+			if (!(lane & DP_LANE_CR_DONE)) {
+				cr_done = false;
+				break;
+			}
+
+			if (!(lane & DP_LANE_CHANNEL_EQ_DONE) ||
+			    !(lane & DP_LANE_SYMBOL_LOCKED)) {
+				eq_done = false;
+				break;
+			}
+		}
+
+		if (eq_done || !cr_done)
+			break;
+
+		if (!nouveau_dp_link_train_adjust(encoder, config) ||
+		    !nouveau_dp_link_train_commit(encoder, config))
+			break;
+	}
+
+stop:
+	/* end link training */
+	ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_DISABLE);
+	if (ret)
+		return false;
+
+	/* retry at a lower setting, if possible */
+	if (!ret && !(eq_done && cr_done)) {
+		NV_DEBUG_KMS(dev, "\twe failed\n");
+		if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) {
+			NV_DEBUG_KMS(dev, "retry link training at low rate\n");
+			nv_encoder->dp.link_bw = DP_LINK_BW_1_62;
+			goto train;
+		}
+	}
+
+	return eq_done;
+}
+
+bool
+nouveau_dp_detect(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	uint8_t dpcd[4];
+	int ret;
+
+	ret = auxch_rd(encoder, 0x0000, dpcd, 4);
+	if (ret)
+		return false;
+
+	NV_DEBUG_KMS(dev, "encoder: link_bw %d, link_nr %d\n"
+		      "display: link_bw %d, link_nr %d version 0x%02x\n",
+		 nv_encoder->dcb->dpconf.link_bw,
+		 nv_encoder->dcb->dpconf.link_nr,
+		 dpcd[1], dpcd[2] & 0x0f, dpcd[0]);
+
+	nv_encoder->dp.dpcd_version = dpcd[0];
+
+	nv_encoder->dp.link_bw = dpcd[1];
+	if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62 &&
+	    !nv_encoder->dcb->dpconf.link_bw)
+		nv_encoder->dp.link_bw = DP_LINK_BW_1_62;
+
+	nv_encoder->dp.link_nr = dpcd[2] & 0xf;
+	if (nv_encoder->dp.link_nr > nv_encoder->dcb->dpconf.link_nr)
+		nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr;
+
+	return true;
+}
+
+int
+nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
+		 uint8_t *data, int data_nr)
+{
+	struct drm_device *dev = auxch->dev;
+	uint32_t tmp, ctrl, stat = 0, data32[4] = {};
+	int ret = 0, i, index = auxch->rd;
+
+	NV_DEBUG_KMS(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr);
+
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000);
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	if (!(tmp & 0x01000000)) {
+		NV_ERROR(dev, "expected bit 24 == 1, got 0x%08x\n", tmp);
+		ret = -EIO;
+		goto out;
+	}
+
+	for (i = 0; i < 3; i++) {
+		tmp = nv_rd32(dev, NV50_AUXCH_STAT(auxch->rd));
+		if (tmp & NV50_AUXCH_STAT_STATE_READY)
+			break;
+		udelay(100);
+	}
+
+	if (i == 3) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (!(cmd & 1)) {
+		memcpy(data32, data, data_nr);
+		for (i = 0; i < 4; i++) {
+			NV_DEBUG_KMS(dev, "wr %d: 0x%08x\n", i, data32[i]);
+			nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]);
+		}
+	}
+
+	nv_wr32(dev, NV50_AUXCH_ADDR(index), addr);
+	ctrl  = nv_rd32(dev, NV50_AUXCH_CTRL(index));
+	ctrl &= ~(NV50_AUXCH_CTRL_CMD | NV50_AUXCH_CTRL_LEN);
+	ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
+	ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
+
+	for (;;) {
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
+		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
+		if (!nv_wait(NV50_AUXCH_CTRL(index), 0x00010000, 0x00000000)) {
+			NV_ERROR(dev, "expected bit 16 == 0, got 0x%08x\n",
+				 nv_rd32(dev, NV50_AUXCH_CTRL(index)));
+			ret = -EBUSY;
+			goto out;
+		}
+
+		udelay(400);
+
+		stat = nv_rd32(dev, NV50_AUXCH_STAT(index));
+		if ((stat & NV50_AUXCH_STAT_REPLY_AUX) !=
+			    NV50_AUXCH_STAT_REPLY_AUX_DEFER)
+			break;
+	}
+
+	if (cmd & 1) {
+		if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {
+			ret = -EREMOTEIO;
+			goto out;
+		}
+
+		for (i = 0; i < 4; i++) {
+			data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i));
+			NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]);
+		}
+		memcpy(data, data32, data_nr);
+	}
+
+out:
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp & ~0x00100000);
+	tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
+	if (tmp & 0x01000000) {
+		NV_ERROR(dev, "expected bit 24 == 0, got 0x%08x\n", tmp);
+		ret = -EIO;
+	}
+
+	udelay(400);
+
+	return ret ? ret : (stat & NV50_AUXCH_STAT_REPLY);
+}
+
+int
+nouveau_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+		      uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adapter;
+	struct drm_device *dev = auxch->dev;
+	int ret = 0, cmd, addr = algo_data->address;
+	uint8_t *buf;
+
+	if (mode == MODE_I2C_READ) {
+		cmd = AUX_I2C_READ;
+		buf = read_byte;
+	} else {
+		cmd = (mode & MODE_I2C_READ) ? AUX_I2C_READ : AUX_I2C_WRITE;
+		buf = &write_byte;
+	}
+
+	if (!(mode & MODE_I2C_STOP))
+		cmd |= AUX_I2C_MOT;
+
+	if (mode & MODE_I2C_START)
+		return 1;
+
+	for (;;) {
+		ret = nouveau_dp_auxch(auxch, cmd, addr, buf, 1);
+		if (ret < 0)
+			return ret;
+
+		switch (ret & NV50_AUXCH_STAT_REPLY_I2C) {
+		case NV50_AUXCH_STAT_REPLY_I2C_ACK:
+			return 1;
+		case NV50_AUXCH_STAT_REPLY_I2C_NACK:
+			return -EREMOTEIO;
+		case NV50_AUXCH_STAT_REPLY_I2C_DEFER:
+			udelay(100);
+			break;
+		default:
+			NV_ERROR(dev, "invalid auxch status: 0x%08x\n", ret);
+			return -EREMOTEIO;
+		}
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2005 Stephane Marchesin.
+ * 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, 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include <linux/console.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+#include "nv50_display.h"
+
+#include "drm_pciids.h"
+
+MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
+int nouveau_ctxfw = 0;
+module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
+
+MODULE_PARM_DESC(noagp, "Disable AGP");
+int nouveau_noagp;
+module_param_named(noagp, nouveau_noagp, int, 0400);
+
+MODULE_PARM_DESC(modeset, "Enable kernel modesetting");
+static int nouveau_modeset = -1; /* kms */
+module_param_named(modeset, nouveau_modeset, int, 0400);
+
+MODULE_PARM_DESC(vbios, "Override default VBIOS location");
+char *nouveau_vbios;
+module_param_named(vbios, nouveau_vbios, charp, 0400);
+
+MODULE_PARM_DESC(vram_pushbuf, "Force DMA push buffers to be in VRAM");
+int nouveau_vram_pushbuf;
+module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
+
+MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
+int nouveau_vram_notify = 1;
+module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
+
+MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
+int nouveau_duallink = 1;
+module_param_named(duallink, nouveau_duallink, int, 0400);
+
+MODULE_PARM_DESC(uscript_lvds, "LVDS output script table ID (>=GeForce 8)");
+int nouveau_uscript_lvds = -1;
+module_param_named(uscript_lvds, nouveau_uscript_lvds, int, 0400);
+
+MODULE_PARM_DESC(uscript_tmds, "TMDS output script table ID (>=GeForce 8)");
+int nouveau_uscript_tmds = -1;
+module_param_named(uscript_tmds, nouveau_uscript_tmds, int, 0400);
+
+MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
+int nouveau_ignorelid = 0;
+module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
+
+MODULE_PARM_DESC(noagp, "Disable all acceleration");
+int nouveau_noaccel = 0;
+module_param_named(noaccel, nouveau_noaccel, int, 0400);
+
+MODULE_PARM_DESC(noagp, "Disable fbcon acceleration");
+int nouveau_nofbaccel = 0;
+module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
+
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
+		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
+		 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
+		 "\t\tDefault: PAL\n"
+		 "\t\t*NOTE* Ignored for cards with external TV encoders.");
+char *nouveau_tv_norm;
+module_param_named(tv_norm, nouveau_tv_norm, charp, 0400);
+
+MODULE_PARM_DESC(reg_debug, "Register access debug bitmask:\n"
+		"\t\t0x1 mc, 0x2 video, 0x4 fb, 0x8 extdev,\n"
+		"\t\t0x10 crtc, 0x20 ramdac, 0x40 vgacrtc, 0x80 rmvio,\n"
+		"\t\t0x100 vgaattr, 0x200 EVO (G80+). ");
+int nouveau_reg_debug;
+module_param_named(reg_debug, nouveau_reg_debug, int, 0600);
+
+int nouveau_fbpercrtc;
+#if 0
+module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400);
+#endif
+
+static struct pci_device_id pciidlist[] = {
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+		.class = PCI_BASE_CLASS_DISPLAY << 16,
+		.class_mask  = 0xff << 16,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
+		.class = PCI_BASE_CLASS_DISPLAY << 16,
+		.class_mask  = 0xff << 16,
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
+static struct drm_driver driver;
+
+static int __devinit
+nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return drm_get_dev(pdev, ent, &driver);
+}
+
+static void
+nouveau_pci_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_put_dev(dev);
+}
+
+static int
+nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	struct drm_crtc *crtc;
+	uint32_t fbdev_flags;
+	int ret, i;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -ENODEV;
+
+	if (pm_state.event == PM_EVENT_PRETHAW)
+		return 0;
+
+	fbdev_flags = dev_priv->fbdev_info->flags;
+	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_framebuffer *nouveau_fb;
+
+		nouveau_fb = nouveau_framebuffer(crtc->fb);
+		if (!nouveau_fb || !nouveau_fb->nvbo)
+			continue;
+
+		nouveau_bo_unpin(nouveau_fb->nvbo);
+	}
+
+	NV_INFO(dev, "Evicting buffers...\n");
+	ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
+
+	NV_INFO(dev, "Idling channels...\n");
+	for (i = 0; i < pfifo->channels; i++) {
+		struct nouveau_fence *fence = NULL;
+
+		chan = dev_priv->fifos[i];
+		if (!chan || (dev_priv->card_type >= NV_50 &&
+			      chan == dev_priv->fifos[0]))
+			continue;
+
+		ret = nouveau_fence_new(chan, &fence, true);
+		if (ret == 0) {
+			ret = nouveau_fence_wait(fence, NULL, false, false);
+			nouveau_fence_unref((void *)&fence);
+		}
+
+		if (ret) {
+			NV_ERROR(dev, "Failed to idle channel %d for suspend\n",
+				 chan->id);
+		}
+	}
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+	pfifo->reassign(dev, false);
+	pfifo->disable(dev);
+	pfifo->unload_context(dev);
+	pgraph->unload_context(dev);
+
+	NV_INFO(dev, "Suspending GPU objects...\n");
+	ret = nouveau_gpuobj_suspend(dev);
+	if (ret) {
+		NV_ERROR(dev, "... failed: %d\n", ret);
+		goto out_abort;
+	}
+
+	ret = pinstmem->suspend(dev);
+	if (ret) {
+		NV_ERROR(dev, "... failed: %d\n", ret);
+		nouveau_gpuobj_suspend_cleanup(dev);
+		goto out_abort;
+	}
+
+	NV_INFO(dev, "And we're gone!\n");
+	pci_save_state(pdev);
+	if (pm_state.event == PM_EVENT_SUSPEND) {
+		pci_disable_device(pdev);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
+	acquire_console_sem();
+	fb_set_suspend(dev_priv->fbdev_info, 1);
+	release_console_sem();
+	dev_priv->fbdev_info->flags = fbdev_flags;
+	return 0;
+
+out_abort:
+	NV_INFO(dev, "Re-enabling acceleration..\n");
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+	pgraph->fifo_access(dev, true);
+	return ret;
+}
+
+static int
+nouveau_pci_resume(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct drm_crtc *crtc;
+	uint32_t fbdev_flags;
+	int ret, i;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -ENODEV;
+
+	fbdev_flags = dev_priv->fbdev_info->flags;
+	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+
+	NV_INFO(dev, "We're back, enabling device...\n");
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	if (pci_enable_device(pdev))
+		return -1;
+	pci_set_master(dev->pdev);
+
+	NV_INFO(dev, "POSTing device...\n");
+	ret = nouveau_run_vbios_init(dev);
+	if (ret)
+		return ret;
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+		ret = nouveau_mem_init_agp(dev);
+		if (ret) {
+			NV_ERROR(dev, "error reinitialising AGP: %d\n", ret);
+			return ret;
+		}
+	}
+
+	NV_INFO(dev, "Reinitialising engines...\n");
+	engine->instmem.resume(dev);
+	engine->mc.init(dev);
+	engine->timer.init(dev);
+	engine->fb.init(dev);
+	engine->graph.init(dev);
+	engine->fifo.init(dev);
+
+	NV_INFO(dev, "Restoring GPU objects...\n");
+	nouveau_gpuobj_resume(dev);
+
+	nouveau_irq_postinstall(dev);
+
+	/* Re-write SKIPS, they'll have been lost over the suspend */
+	if (nouveau_vram_pushbuf) {
+		struct nouveau_channel *chan;
+		int j;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			chan = dev_priv->fifos[i];
+			if (!chan || !chan->pushbuf_bo)
+				continue;
+
+			for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
+				nouveau_bo_wr32(chan->pushbuf_bo, i, 0);
+		}
+	}
+
+	NV_INFO(dev, "Restoring mode...\n");
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_framebuffer *nouveau_fb;
+
+		nouveau_fb = nouveau_framebuffer(crtc->fb);
+		if (!nouveau_fb || !nouveau_fb->nvbo)
+			continue;
+
+		nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
+	}
+
+	if (dev_priv->card_type < NV_50) {
+		nv04_display_restore(dev);
+		NVLockVgaCrtcs(dev, false);
+	} else
+		nv50_display_init(dev);
+
+	/* Force CLUT to get re-loaded during modeset */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+		nv_crtc->lut.depth = 0;
+	}
+
+	acquire_console_sem();
+	fb_set_suspend(dev_priv->fbdev_info, 0);
+	release_console_sem();
+
+	nouveau_fbcon_zfill(dev);
+
+	drm_helper_resume_force_mode(dev);
+	dev_priv->fbdev_info->flags = fbdev_flags;
+	return 0;
+}
+
+static struct drm_driver driver = {
+	.driver_features =
+		DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
+		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
+	.load = nouveau_load,
+	.firstopen = nouveau_firstopen,
+	.lastclose = nouveau_lastclose,
+	.unload = nouveau_unload,
+	.preclose = nouveau_preclose,
+#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
+	.debugfs_init = nouveau_debugfs_init,
+	.debugfs_cleanup = nouveau_debugfs_takedown,
+#endif
+	.irq_preinstall = nouveau_irq_preinstall,
+	.irq_postinstall = nouveau_irq_postinstall,
+	.irq_uninstall = nouveau_irq_uninstall,
+	.irq_handler = nouveau_irq_handler,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.ioctls = nouveau_ioctls,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.unlocked_ioctl = drm_ioctl,
+		.mmap = nouveau_ttm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+#if defined(CONFIG_COMPAT)
+		.compat_ioctl = nouveau_compat_ioctl,
+#endif
+	},
+	.pci_driver = {
+		.name = DRIVER_NAME,
+		.id_table = pciidlist,
+		.probe = nouveau_pci_probe,
+		.remove = nouveau_pci_remove,
+		.suspend = nouveau_pci_suspend,
+		.resume = nouveau_pci_resume
+	},
+
+	.gem_init_object = nouveau_gem_object_new,
+	.gem_free_object = nouveau_gem_object_del,
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+#ifdef GIT_REVISION
+	.date = GIT_REVISION,
+#else
+	.date = DRIVER_DATE,
+#endif
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int __init nouveau_init(void)
+{
+	driver.num_ioctls = nouveau_max_ioctl;
+
+	if (nouveau_modeset == -1) {
+#ifdef CONFIG_VGA_CONSOLE
+		if (vgacon_text_force())
+			nouveau_modeset = 0;
+		else
+#endif
+			nouveau_modeset = 1;
+	}
+
+	if (nouveau_modeset == 1)
+		driver.driver_features |= DRIVER_MODESET;
+
+	return drm_init(&driver);
+}
+
+static void __exit nouveau_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(nouveau_init);
+module_exit(nouveau_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1351 @@
+/*
+ * Copyright 2005 Stephane Marchesin.
+ * 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, 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
+ * VA LINUX SYSTEMS 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 __NOUVEAU_DRV_H__
+#define __NOUVEAU_DRV_H__
+
+#define DRIVER_AUTHOR		"Stephane Marchesin"
+#define DRIVER_EMAIL		"dri-devel@lists.sourceforge.net"
+
+#define DRIVER_NAME		"nouveau"
+#define DRIVER_DESC		"nVidia Riva/TNT/GeForce"
+#define DRIVER_DATE		"20090420"
+
+#define DRIVER_MAJOR		0
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	15
+
+#define NOUVEAU_FAMILY   0x0000FFFF
+#define NOUVEAU_FLAGS    0xFFFF0000
+
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_memory.h"
+#include "ttm/ttm_module.h"
+
+struct nouveau_fpriv {
+	struct ttm_object_file *tfile;
+};
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "nouveau_bios.h"
+struct nouveau_grctx;
+
+#define MAX_NUM_DCB_ENTRIES 16
+
+#define NOUVEAU_MAX_CHANNEL_NR 128
+#define NOUVEAU_MAX_TILE_NR 15
+
+#define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL)
+#define NV50_VM_BLOCK    (512*1024*1024ULL)
+#define NV50_VM_VRAM_NR  (NV50_VM_MAX_VRAM / NV50_VM_BLOCK)
+
+struct nouveau_tile_reg {
+	struct nouveau_fence *fence;
+	uint32_t addr;
+	uint32_t size;
+	bool used;
+};
+
+struct nouveau_bo {
+	struct ttm_buffer_object bo;
+	struct ttm_placement placement;
+	u32 placements[3];
+	struct ttm_bo_kmap_obj kmap;
+	struct list_head head;
+
+	/* protected by ttm_bo_reserve() */
+	struct drm_file *reserved_by;
+	struct list_head entry;
+	int pbbo_index;
+
+	struct nouveau_channel *channel;
+
+	bool mappable;
+	bool no_vm;
+
+	uint32_t tile_mode;
+	uint32_t tile_flags;
+	struct nouveau_tile_reg *tile;
+
+	struct drm_gem_object *gem;
+	struct drm_file *cpu_filp;
+	int pin_refcnt;
+};
+
+static inline struct nouveau_bo *
+nouveau_bo(struct ttm_buffer_object *bo)
+{
+	return container_of(bo, struct nouveau_bo, bo);
+}
+
+static inline struct nouveau_bo *
+nouveau_gem_object(struct drm_gem_object *gem)
+{
+	return gem ? gem->driver_private : NULL;
+}
+
+/* TODO: submit equivalent to TTM generic API upstream? */
+static inline void __iomem *
+nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
+{
+	bool is_iomem;
+	void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual(
+						&nvbo->kmap, &is_iomem);
+	WARN_ON_ONCE(ioptr && !is_iomem);
+	return ioptr;
+}
+
+struct mem_block {
+	struct mem_block *next;
+	struct mem_block *prev;
+	uint64_t start;
+	uint64_t size;
+	struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
+};
+
+enum nouveau_flags {
+	NV_NFORCE   = 0x10000000,
+	NV_NFORCE2  = 0x20000000
+};
+
+#define NVOBJ_ENGINE_SW		0
+#define NVOBJ_ENGINE_GR		1
+#define NVOBJ_ENGINE_DISPLAY	2
+#define NVOBJ_ENGINE_INT	0xdeadbeef
+
+#define NVOBJ_FLAG_ALLOW_NO_REFS	(1 << 0)
+#define NVOBJ_FLAG_ZERO_ALLOC		(1 << 1)
+#define NVOBJ_FLAG_ZERO_FREE		(1 << 2)
+#define NVOBJ_FLAG_FAKE			(1 << 3)
+struct nouveau_gpuobj {
+	struct list_head list;
+
+	struct nouveau_channel *im_channel;
+	struct mem_block *im_pramin;
+	struct nouveau_bo *im_backing;
+	uint32_t im_backing_start;
+	uint32_t *im_backing_suspend;
+	int im_bound;
+
+	uint32_t flags;
+	int refcount;
+
+	uint32_t engine;
+	uint32_t class;
+
+	void (*dtor)(struct drm_device *, struct nouveau_gpuobj *);
+	void *priv;
+};
+
+struct nouveau_gpuobj_ref {
+	struct list_head list;
+
+	struct nouveau_gpuobj *gpuobj;
+	uint32_t instance;
+
+	struct nouveau_channel *channel;
+	int handle;
+};
+
+struct nouveau_channel {
+	struct drm_device *dev;
+	int id;
+
+	/* owner of this fifo */
+	struct drm_file *file_priv;
+	/* mapping of the fifo itself */
+	struct drm_local_map *map;
+
+	/* mapping of the regs controling the fifo */
+	void __iomem *user;
+	uint32_t user_get;
+	uint32_t user_put;
+
+	/* Fencing */
+	struct {
+		/* lock protects the pending list only */
+		spinlock_t lock;
+		struct list_head pending;
+		uint32_t sequence;
+		uint32_t sequence_ack;
+		uint32_t last_sequence_irq;
+	} fence;
+
+	/* DMA push buffer */
+	struct nouveau_gpuobj_ref *pushbuf;
+	struct nouveau_bo         *pushbuf_bo;
+	uint32_t                   pushbuf_base;
+
+	/* Notifier memory */
+	struct nouveau_bo *notifier_bo;
+	struct mem_block *notifier_heap;
+
+	/* PFIFO context */
+	struct nouveau_gpuobj_ref *ramfc;
+	struct nouveau_gpuobj_ref *cache;
+
+	/* PGRAPH context */
+	/* XXX may be merge 2 pointers as private data ??? */
+	struct nouveau_gpuobj_ref *ramin_grctx;
+	void *pgraph_ctx;
+
+	/* NV50 VM */
+	struct nouveau_gpuobj     *vm_pd;
+	struct nouveau_gpuobj_ref *vm_gart_pt;
+	struct nouveau_gpuobj_ref *vm_vram_pt[NV50_VM_VRAM_NR];
+
+	/* Objects */
+	struct nouveau_gpuobj_ref *ramin; /* Private instmem */
+	struct mem_block          *ramin_heap; /* Private PRAMIN heap */
+	struct nouveau_gpuobj_ref *ramht; /* Hash table */
+	struct list_head           ramht_refs; /* Objects referenced by RAMHT */
+
+	/* GPU object info for stuff used in-kernel (mm_enabled) */
+	uint32_t m2mf_ntfy;
+	uint32_t vram_handle;
+	uint32_t gart_handle;
+	bool accel_done;
+
+	/* Push buffer state (only for drm's channel on !mm_enabled) */
+	struct {
+		int max;
+		int free;
+		int cur;
+		int put;
+		/* access via pushbuf_bo */
+	} dma;
+
+	uint32_t sw_subchannel[8];
+
+	struct {
+		struct nouveau_gpuobj *vblsem;
+		uint32_t vblsem_offset;
+		uint32_t vblsem_rval;
+		struct list_head vbl_wait;
+	} nvsw;
+
+	struct {
+		bool active;
+		char name[32];
+		struct drm_info_list info;
+	} debugfs;
+};
+
+struct nouveau_instmem_engine {
+	void	*priv;
+
+	int	(*init)(struct drm_device *dev);
+	void	(*takedown)(struct drm_device *dev);
+	int	(*suspend)(struct drm_device *dev);
+	void	(*resume)(struct drm_device *dev);
+
+	int	(*populate)(struct drm_device *, struct nouveau_gpuobj *,
+			    uint32_t *size);
+	void	(*clear)(struct drm_device *, struct nouveau_gpuobj *);
+	int	(*bind)(struct drm_device *, struct nouveau_gpuobj *);
+	int	(*unbind)(struct drm_device *, struct nouveau_gpuobj *);
+	void	(*prepare_access)(struct drm_device *, bool write);
+	void	(*finish_access)(struct drm_device *);
+};
+
+struct nouveau_mc_engine {
+	int  (*init)(struct drm_device *dev);
+	void (*takedown)(struct drm_device *dev);
+};
+
+struct nouveau_timer_engine {
+	int      (*init)(struct drm_device *dev);
+	void     (*takedown)(struct drm_device *dev);
+	uint64_t (*read)(struct drm_device *dev);
+};
+
+struct nouveau_fb_engine {
+	int num_tiles;
+
+	int  (*init)(struct drm_device *dev);
+	void (*takedown)(struct drm_device *dev);
+
+	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
+				 uint32_t size, uint32_t pitch);
+};
+
+struct nouveau_fifo_engine {
+	void *priv;
+
+	int  channels;
+
+	int  (*init)(struct drm_device *);
+	void (*takedown)(struct drm_device *);
+
+	void (*disable)(struct drm_device *);
+	void (*enable)(struct drm_device *);
+	bool (*reassign)(struct drm_device *, bool enable);
+	bool (*cache_flush)(struct drm_device *dev);
+	bool (*cache_pull)(struct drm_device *dev, bool enable);
+
+	int  (*channel_id)(struct drm_device *);
+
+	int  (*create_context)(struct nouveau_channel *);
+	void (*destroy_context)(struct nouveau_channel *);
+	int  (*load_context)(struct nouveau_channel *);
+	int  (*unload_context)(struct drm_device *);
+};
+
+struct nouveau_pgraph_object_method {
+	int id;
+	int (*exec)(struct nouveau_channel *chan, int grclass, int mthd,
+		      uint32_t data);
+};
+
+struct nouveau_pgraph_object_class {
+	int id;
+	bool software;
+	struct nouveau_pgraph_object_method *methods;
+};
+
+struct nouveau_pgraph_engine {
+	struct nouveau_pgraph_object_class *grclass;
+	bool accel_blocked;
+	void *ctxprog;
+	void *ctxvals;
+	int grctx_size;
+
+	int  (*init)(struct drm_device *);
+	void (*takedown)(struct drm_device *);
+
+	void (*fifo_access)(struct drm_device *, bool);
+
+	struct nouveau_channel *(*channel)(struct drm_device *);
+	int  (*create_context)(struct nouveau_channel *);
+	void (*destroy_context)(struct nouveau_channel *);
+	int  (*load_context)(struct nouveau_channel *);
+	int  (*unload_context)(struct drm_device *);
+
+	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
+				  uint32_t size, uint32_t pitch);
+};
+
+struct nouveau_engine {
+	struct nouveau_instmem_engine instmem;
+	struct nouveau_mc_engine      mc;
+	struct nouveau_timer_engine   timer;
+	struct nouveau_fb_engine      fb;
+	struct nouveau_pgraph_engine  graph;
+	struct nouveau_fifo_engine    fifo;
+};
+
+struct nouveau_pll_vals {
+	union {
+		struct {
+#ifdef __BIG_ENDIAN
+			uint8_t N1, M1, N2, M2;
+#else
+			uint8_t M1, N1, M2, N2;
+#endif
+		};
+		struct {
+			uint16_t NM1, NM2;
+		} __attribute__((packed));
+	};
+	int log2P;
+
+	int refclk;
+};
+
+enum nv04_fp_display_regs {
+	FP_DISPLAY_END,
+	FP_TOTAL,
+	FP_CRTC,
+	FP_SYNC_START,
+	FP_SYNC_END,
+	FP_VALID_START,
+	FP_VALID_END
+};
+
+struct nv04_crtc_reg {
+	unsigned char MiscOutReg;     /* */
+	uint8_t CRTC[0x9f];
+	uint8_t CR58[0x10];
+	uint8_t Sequencer[5];
+	uint8_t Graphics[9];
+	uint8_t Attribute[21];
+	unsigned char DAC[768];       /* Internal Colorlookuptable */
+
+	/* PCRTC regs */
+	uint32_t fb_start;
+	uint32_t crtc_cfg;
+	uint32_t cursor_cfg;
+	uint32_t gpio_ext;
+	uint32_t crtc_830;
+	uint32_t crtc_834;
+	uint32_t crtc_850;
+	uint32_t crtc_eng_ctrl;
+
+	/* PRAMDAC regs */
+	uint32_t nv10_cursync;
+	struct nouveau_pll_vals pllvals;
+	uint32_t ramdac_gen_ctrl;
+	uint32_t ramdac_630;
+	uint32_t ramdac_634;
+	uint32_t tv_setup;
+	uint32_t tv_vtotal;
+	uint32_t tv_vskew;
+	uint32_t tv_vsync_delay;
+	uint32_t tv_htotal;
+	uint32_t tv_hskew;
+	uint32_t tv_hsync_delay;
+	uint32_t tv_hsync_delay2;
+	uint32_t fp_horiz_regs[7];
+	uint32_t fp_vert_regs[7];
+	uint32_t dither;
+	uint32_t fp_control;
+	uint32_t dither_regs[6];
+	uint32_t fp_debug_0;
+	uint32_t fp_debug_1;
+	uint32_t fp_debug_2;
+	uint32_t fp_margin_color;
+	uint32_t ramdac_8c0;
+	uint32_t ramdac_a20;
+	uint32_t ramdac_a24;
+	uint32_t ramdac_a34;
+	uint32_t ctv_regs[38];
+};
+
+struct nv04_output_reg {
+	uint32_t output;
+	int head;
+};
+
+struct nv04_mode_state {
+	uint32_t bpp;
+	uint32_t width;
+	uint32_t height;
+	uint32_t interlace;
+	uint32_t repaint0;
+	uint32_t repaint1;
+	uint32_t screen;
+	uint32_t scale;
+	uint32_t dither;
+	uint32_t extra;
+	uint32_t fifo;
+	uint32_t pixel;
+	uint32_t horiz;
+	int arbitration0;
+	int arbitration1;
+	uint32_t pll;
+	uint32_t pllB;
+	uint32_t vpll;
+	uint32_t vpll2;
+	uint32_t vpllB;
+	uint32_t vpll2B;
+	uint32_t pllsel;
+	uint32_t sel_clk;
+	uint32_t general;
+	uint32_t crtcOwner;
+	uint32_t head;
+	uint32_t head2;
+	uint32_t cursorConfig;
+	uint32_t cursor0;
+	uint32_t cursor1;
+	uint32_t cursor2;
+	uint32_t timingH;
+	uint32_t timingV;
+	uint32_t displayV;
+	uint32_t crtcSync;
+
+	struct nv04_crtc_reg crtc_reg[2];
+};
+
+enum nouveau_card_type {
+	NV_04      = 0x00,
+	NV_10      = 0x10,
+	NV_20      = 0x20,
+	NV_30      = 0x30,
+	NV_40      = 0x40,
+	NV_50      = 0x50,
+};
+
+struct drm_nouveau_private {
+	struct drm_device *dev;
+	enum {
+		NOUVEAU_CARD_INIT_DOWN,
+		NOUVEAU_CARD_INIT_DONE,
+		NOUVEAU_CARD_INIT_FAILED
+	} init_state;
+
+	/* the card type, takes NV_* as values */
+	enum nouveau_card_type card_type;
+	/* exact chipset, derived from NV_PMC_BOOT_0 */
+	int chipset;
+	int flags;
+
+	void __iomem *mmio;
+	void __iomem *ramin;
+	uint32_t ramin_size;
+
+	struct nouveau_bo *vga_ram;
+
+	struct workqueue_struct *wq;
+	struct work_struct irq_work;
+
+	struct list_head vbl_waiting;
+
+	struct {
+		struct ttm_global_reference mem_global_ref;
+		struct ttm_bo_global_ref bo_global_ref;
+		struct ttm_bo_device bdev;
+		spinlock_t bo_list_lock;
+		struct list_head bo_list;
+		atomic_t validate_sequence;
+	} ttm;
+
+	struct fb_info *fbdev_info;
+
+	int fifo_alloc_count;
+	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
+
+	struct nouveau_engine engine;
+	struct nouveau_channel *channel;
+
+	/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
+	struct nouveau_gpuobj *ramht;
+	uint32_t ramin_rsvd_vram;
+	uint32_t ramht_offset;
+	uint32_t ramht_size;
+	uint32_t ramht_bits;
+	uint32_t ramfc_offset;
+	uint32_t ramfc_size;
+	uint32_t ramro_offset;
+	uint32_t ramro_size;
+
+	/* base physical adresses */
+	uint64_t fb_phys;
+	uint64_t fb_available_size;
+	uint64_t fb_mappable_pages;
+	uint64_t fb_aper_free;
+
+	struct {
+		enum {
+			NOUVEAU_GART_NONE = 0,
+			NOUVEAU_GART_AGP,
+			NOUVEAU_GART_SGDMA
+		} type;
+		uint64_t aper_base;
+		uint64_t aper_size;
+		uint64_t aper_free;
+
+		struct nouveau_gpuobj *sg_ctxdma;
+		struct page *sg_dummy_page;
+		dma_addr_t sg_dummy_bus;
+
+		/* nottm hack */
+		struct drm_ttm_backend *sg_be;
+		unsigned long sg_handle;
+	} gart_info;
+
+	/* nv10-nv40 tiling regions */
+	struct {
+		struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR];
+		spinlock_t lock;
+	} tile;
+
+	/* G8x/G9x virtual address space */
+	uint64_t vm_gart_base;
+	uint64_t vm_gart_size;
+	uint64_t vm_vram_base;
+	uint64_t vm_vram_size;
+	uint64_t vm_end;
+	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
+	int vm_vram_pt_nr;
+	uint64_t vram_sys_base;
+
+	/* the mtrr covering the FB */
+	int fb_mtrr;
+
+	struct mem_block *ramin_heap;
+
+	/* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
+	uint32_t ctx_table_size;
+	struct nouveau_gpuobj_ref *ctx_table;
+
+	struct list_head gpuobj_list;
+
+	struct nvbios VBIOS;
+	struct nouveau_bios_info *vbios;
+
+	struct nv04_mode_state mode_reg;
+	struct nv04_mode_state saved_reg;
+	uint32_t saved_vga_font[4][16384];
+	uint32_t crtc_owner;
+	uint32_t dac_users[4];
+
+	struct nouveau_suspend_resume {
+		uint32_t fifo_mode;
+		uint32_t graph_ctx_control;
+		uint32_t graph_state;
+		uint32_t *ramin_copy;
+		uint64_t ramin_size;
+	} susres;
+
+	struct backlight_device *backlight;
+	bool acpi_dsm;
+
+	struct nouveau_channel *evo;
+
+	struct {
+		struct dentry *channel_root;
+	} debugfs;
+};
+
+static inline struct drm_nouveau_private *
+nouveau_bdev(struct ttm_bo_device *bd)
+{
+	return container_of(bd, struct drm_nouveau_private, ttm.bdev);
+}
+
+static inline int
+nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
+{
+	struct nouveau_bo *prev;
+
+	if (!pnvbo)
+		return -EINVAL;
+	prev = *pnvbo;
+
+	*pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL;
+	if (prev) {
+		struct ttm_buffer_object *bo = &prev->bo;
+
+		ttm_bo_unref(&bo);
+	}
+
+	return 0;
+}
+
+#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do {            \
+	struct drm_nouveau_private *nv = dev->dev_private;    \
+	if (nv->init_state != NOUVEAU_CARD_INIT_DONE) {       \
+		NV_ERROR(dev, "called without init\n");       \
+		return -EINVAL;                               \
+	}                                                     \
+} while (0)
+
+#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do {    \
+	struct drm_nouveau_private *nv = dev->dev_private;       \
+	if (!nouveau_channel_owner(dev, (cl), (id))) {           \
+		NV_ERROR(dev, "pid %d doesn't own channel %d\n", \
+			 DRM_CURRENTPID, (id));                  \
+		return -EPERM;                                   \
+	}                                                        \
+	(ch) = nv->fifos[(id)];                                  \
+} while (0)
+
+/* nouveau_drv.c */
+extern int nouveau_noagp;
+extern int nouveau_duallink;
+extern int nouveau_uscript_lvds;
+extern int nouveau_uscript_tmds;
+extern int nouveau_vram_pushbuf;
+extern int nouveau_vram_notify;
+extern int nouveau_fbpercrtc;
+extern char *nouveau_tv_norm;
+extern int nouveau_reg_debug;
+extern char *nouveau_vbios;
+extern int nouveau_ctxfw;
+extern int nouveau_ignorelid;
+extern int nouveau_nofbaccel;
+extern int nouveau_noaccel;
+
+/* nouveau_state.c */
+extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
+extern int  nouveau_load(struct drm_device *, unsigned long flags);
+extern int  nouveau_firstopen(struct drm_device *);
+extern void nouveau_lastclose(struct drm_device *);
+extern int  nouveau_unload(struct drm_device *);
+extern int  nouveau_ioctl_getparam(struct drm_device *, void *data,
+				   struct drm_file *);
+extern int  nouveau_ioctl_setparam(struct drm_device *, void *data,
+				   struct drm_file *);
+extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
+			       uint32_t reg, uint32_t mask, uint32_t val);
+extern bool nouveau_wait_for_idle(struct drm_device *);
+extern int  nouveau_card_init(struct drm_device *);
+extern int  nouveau_ioctl_card_init(struct drm_device *, void *data,
+				    struct drm_file *);
+extern int  nouveau_ioctl_suspend(struct drm_device *, void *data,
+				  struct drm_file *);
+extern int  nouveau_ioctl_resume(struct drm_device *, void *data,
+				 struct drm_file *);
+
+/* nouveau_mem.c */
+extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
+				 uint64_t size);
+extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
+						 uint64_t size, int align2,
+						 struct drm_file *, int tail);
+extern void nouveau_mem_takedown(struct mem_block **heap);
+extern void nouveau_mem_free_block(struct mem_block *);
+extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
+extern int  nouveau_mem_init(struct drm_device *);
+extern int  nouveau_mem_init_agp(struct drm_device *);
+extern void nouveau_mem_close(struct drm_device *);
+extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev,
+						    uint32_t addr,
+						    uint32_t size,
+						    uint32_t pitch);
+extern void nv10_mem_expire_tiling(struct drm_device *dev,
+				   struct nouveau_tile_reg *tile,
+				   struct nouveau_fence *fence);
+extern int  nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt,
+				    uint32_t size, uint32_t flags,
+				    uint64_t phys);
+extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt,
+			       uint32_t size);
+
+/* nouveau_notifier.c */
+extern int  nouveau_notifier_init_channel(struct nouveau_channel *);
+extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
+extern int  nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
+				   int cout, uint32_t *offset);
+extern int  nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *);
+extern int  nouveau_ioctl_notifier_alloc(struct drm_device *, void *data,
+					 struct drm_file *);
+extern int  nouveau_ioctl_notifier_free(struct drm_device *, void *data,
+					struct drm_file *);
+
+/* nouveau_channel.c */
+extern struct drm_ioctl_desc nouveau_ioctls[];
+extern int nouveau_max_ioctl;
+extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *);
+extern int  nouveau_channel_owner(struct drm_device *, struct drm_file *,
+				  int channel);
+extern int  nouveau_channel_alloc(struct drm_device *dev,
+				  struct nouveau_channel **chan,
+				  struct drm_file *file_priv,
+				  uint32_t fb_ctxdma, uint32_t tt_ctxdma);
+extern void nouveau_channel_free(struct nouveau_channel *);
+
+/* nouveau_object.c */
+extern int  nouveau_gpuobj_early_init(struct drm_device *);
+extern int  nouveau_gpuobj_init(struct drm_device *);
+extern void nouveau_gpuobj_takedown(struct drm_device *);
+extern void nouveau_gpuobj_late_takedown(struct drm_device *);
+extern int  nouveau_gpuobj_suspend(struct drm_device *dev);
+extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev);
+extern void nouveau_gpuobj_resume(struct drm_device *dev);
+extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
+				       uint32_t vram_h, uint32_t tt_h);
+extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
+extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *,
+			      uint32_t size, int align, uint32_t flags,
+			      struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *,
+				  uint32_t handle, struct nouveau_gpuobj *,
+				  struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_ref_del(struct drm_device *,
+				  struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle,
+				   struct nouveau_gpuobj_ref **ref_ret);
+extern int nouveau_gpuobj_new_ref(struct drm_device *,
+				  struct nouveau_channel *alloc_chan,
+				  struct nouveau_channel *ref_chan,
+				  uint32_t handle, uint32_t size, int align,
+				  uint32_t flags, struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_new_fake(struct drm_device *,
+				   uint32_t p_offset, uint32_t b_offset,
+				   uint32_t size, uint32_t flags,
+				   struct nouveau_gpuobj **,
+				   struct nouveau_gpuobj_ref**);
+extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class,
+				  uint64_t offset, uint64_t size, int access,
+				  int target, struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
+				       uint64_t offset, uint64_t size,
+				       int access, struct nouveau_gpuobj **,
+				       uint32_t *o_ret);
+extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
+				 struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class,
+				 struct nouveau_gpuobj **);
+extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
+				     struct drm_file *);
+extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
+				     struct drm_file *);
+
+/* nouveau_irq.c */
+extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
+extern void        nouveau_irq_preinstall(struct drm_device *);
+extern int         nouveau_irq_postinstall(struct drm_device *);
+extern void        nouveau_irq_uninstall(struct drm_device *);
+
+/* nouveau_sgdma.c */
+extern int nouveau_sgdma_init(struct drm_device *);
+extern void nouveau_sgdma_takedown(struct drm_device *);
+extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
+				  uint32_t *page);
+extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+
+/* nouveau_debugfs.c */
+#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
+extern int  nouveau_debugfs_init(struct drm_minor *);
+extern void nouveau_debugfs_takedown(struct drm_minor *);
+extern int  nouveau_debugfs_channel_init(struct nouveau_channel *);
+extern void nouveau_debugfs_channel_fini(struct nouveau_channel *);
+#else
+static inline int
+nouveau_debugfs_init(struct drm_minor *minor)
+{
+	return 0;
+}
+
+static inline void nouveau_debugfs_takedown(struct drm_minor *minor)
+{
+}
+
+static inline int
+nouveau_debugfs_channel_init(struct nouveau_channel *chan)
+{
+	return 0;
+}
+
+static inline void
+nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
+{
+}
+#endif
+
+/* nouveau_dma.c */
+extern void nouveau_dma_pre_init(struct nouveau_channel *);
+extern int  nouveau_dma_init(struct nouveau_channel *);
+extern int  nouveau_dma_wait(struct nouveau_channel *, int size);
+
+/* nouveau_acpi.c */
+#ifdef CONFIG_ACPI
+extern int nouveau_hybrid_setup(struct drm_device *dev);
+extern bool nouveau_dsm_probe(struct drm_device *dev);
+#else
+static inline int nouveau_hybrid_setup(struct drm_device *dev)
+{
+	return 0;
+}
+static inline bool nouveau_dsm_probe(struct drm_device *dev)
+{
+	return false;
+}
+#endif
+
+/* nouveau_backlight.c */
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+extern int nouveau_backlight_init(struct drm_device *);
+extern void nouveau_backlight_exit(struct drm_device *);
+#else
+static inline int nouveau_backlight_init(struct drm_device *dev)
+{
+	return 0;
+}
+
+static inline void nouveau_backlight_exit(struct drm_device *dev) { }
+#endif
+
+/* nouveau_bios.c */
+extern int nouveau_bios_init(struct drm_device *);
+extern void nouveau_bios_takedown(struct drm_device *dev);
+extern int nouveau_run_vbios_init(struct drm_device *);
+extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table,
+					struct dcb_entry *);
+extern struct dcb_gpio_entry *nouveau_bios_gpio_entry(struct drm_device *,
+						      enum dcb_gpio_tag);
+extern struct dcb_connector_table_entry *
+nouveau_bios_connector_entry(struct drm_device *, int index);
+extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
+			  struct pll_lims *);
+extern int nouveau_bios_run_display_table(struct drm_device *,
+					  struct dcb_entry *,
+					  uint32_t script, int pxclk);
+extern void *nouveau_bios_dp_table(struct drm_device *, struct dcb_entry *,
+				   int *length);
+extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
+extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
+extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
+					 bool *dl, bool *if_is_24bit);
+extern int run_tmds_table(struct drm_device *, struct dcb_entry *,
+			  int head, int pxclk);
+extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
+			    enum LVDS_script, int pxclk);
+
+/* nouveau_ttm.c */
+int nouveau_ttm_global_init(struct drm_nouveau_private *);
+void nouveau_ttm_global_release(struct drm_nouveau_private *);
+int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
+
+/* nouveau_dp.c */
+int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
+		     uint8_t *data, int data_nr);
+bool nouveau_dp_detect(struct drm_encoder *);
+bool nouveau_dp_link_train(struct drm_encoder *);
+
+/* nv04_fb.c */
+extern int  nv04_fb_init(struct drm_device *);
+extern void nv04_fb_takedown(struct drm_device *);
+
+/* nv10_fb.c */
+extern int  nv10_fb_init(struct drm_device *);
+extern void nv10_fb_takedown(struct drm_device *);
+extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t,
+				      uint32_t, uint32_t);
+
+/* nv40_fb.c */
+extern int  nv40_fb_init(struct drm_device *);
+extern void nv40_fb_takedown(struct drm_device *);
+extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
+				      uint32_t, uint32_t);
+
+/* nv04_fifo.c */
+extern int  nv04_fifo_init(struct drm_device *);
+extern void nv04_fifo_disable(struct drm_device *);
+extern void nv04_fifo_enable(struct drm_device *);
+extern bool nv04_fifo_reassign(struct drm_device *, bool);
+extern bool nv04_fifo_cache_flush(struct drm_device *);
+extern bool nv04_fifo_cache_pull(struct drm_device *, bool);
+extern int  nv04_fifo_channel_id(struct drm_device *);
+extern int  nv04_fifo_create_context(struct nouveau_channel *);
+extern void nv04_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv04_fifo_load_context(struct nouveau_channel *);
+extern int  nv04_fifo_unload_context(struct drm_device *);
+
+/* nv10_fifo.c */
+extern int  nv10_fifo_init(struct drm_device *);
+extern int  nv10_fifo_channel_id(struct drm_device *);
+extern int  nv10_fifo_create_context(struct nouveau_channel *);
+extern void nv10_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv10_fifo_load_context(struct nouveau_channel *);
+extern int  nv10_fifo_unload_context(struct drm_device *);
+
+/* nv40_fifo.c */
+extern int  nv40_fifo_init(struct drm_device *);
+extern int  nv40_fifo_create_context(struct nouveau_channel *);
+extern void nv40_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv40_fifo_load_context(struct nouveau_channel *);
+extern int  nv40_fifo_unload_context(struct drm_device *);
+
+/* nv50_fifo.c */
+extern int  nv50_fifo_init(struct drm_device *);
+extern void nv50_fifo_takedown(struct drm_device *);
+extern int  nv50_fifo_channel_id(struct drm_device *);
+extern int  nv50_fifo_create_context(struct nouveau_channel *);
+extern void nv50_fifo_destroy_context(struct nouveau_channel *);
+extern int  nv50_fifo_load_context(struct nouveau_channel *);
+extern int  nv50_fifo_unload_context(struct drm_device *);
+
+/* nv04_graph.c */
+extern struct nouveau_pgraph_object_class nv04_graph_grclass[];
+extern int  nv04_graph_init(struct drm_device *);
+extern void nv04_graph_takedown(struct drm_device *);
+extern void nv04_graph_fifo_access(struct drm_device *, bool);
+extern struct nouveau_channel *nv04_graph_channel(struct drm_device *);
+extern int  nv04_graph_create_context(struct nouveau_channel *);
+extern void nv04_graph_destroy_context(struct nouveau_channel *);
+extern int  nv04_graph_load_context(struct nouveau_channel *);
+extern int  nv04_graph_unload_context(struct drm_device *);
+extern void nv04_graph_context_switch(struct drm_device *);
+
+/* nv10_graph.c */
+extern struct nouveau_pgraph_object_class nv10_graph_grclass[];
+extern int  nv10_graph_init(struct drm_device *);
+extern void nv10_graph_takedown(struct drm_device *);
+extern struct nouveau_channel *nv10_graph_channel(struct drm_device *);
+extern int  nv10_graph_create_context(struct nouveau_channel *);
+extern void nv10_graph_destroy_context(struct nouveau_channel *);
+extern int  nv10_graph_load_context(struct nouveau_channel *);
+extern int  nv10_graph_unload_context(struct drm_device *);
+extern void nv10_graph_context_switch(struct drm_device *);
+extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t,
+					 uint32_t, uint32_t);
+
+/* nv20_graph.c */
+extern struct nouveau_pgraph_object_class nv20_graph_grclass[];
+extern struct nouveau_pgraph_object_class nv30_graph_grclass[];
+extern int  nv20_graph_create_context(struct nouveau_channel *);
+extern void nv20_graph_destroy_context(struct nouveau_channel *);
+extern int  nv20_graph_load_context(struct nouveau_channel *);
+extern int  nv20_graph_unload_context(struct drm_device *);
+extern int  nv20_graph_init(struct drm_device *);
+extern void nv20_graph_takedown(struct drm_device *);
+extern int  nv30_graph_init(struct drm_device *);
+extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t,
+					 uint32_t, uint32_t);
+
+/* nv40_graph.c */
+extern struct nouveau_pgraph_object_class nv40_graph_grclass[];
+extern int  nv40_graph_init(struct drm_device *);
+extern void nv40_graph_takedown(struct drm_device *);
+extern struct nouveau_channel *nv40_graph_channel(struct drm_device *);
+extern int  nv40_graph_create_context(struct nouveau_channel *);
+extern void nv40_graph_destroy_context(struct nouveau_channel *);
+extern int  nv40_graph_load_context(struct nouveau_channel *);
+extern int  nv40_graph_unload_context(struct drm_device *);
+extern void nv40_grctx_init(struct nouveau_grctx *);
+extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t,
+					 uint32_t, uint32_t);
+
+/* nv50_graph.c */
+extern struct nouveau_pgraph_object_class nv50_graph_grclass[];
+extern int  nv50_graph_init(struct drm_device *);
+extern void nv50_graph_takedown(struct drm_device *);
+extern void nv50_graph_fifo_access(struct drm_device *, bool);
+extern struct nouveau_channel *nv50_graph_channel(struct drm_device *);
+extern int  nv50_graph_create_context(struct nouveau_channel *);
+extern void nv50_graph_destroy_context(struct nouveau_channel *);
+extern int  nv50_graph_load_context(struct nouveau_channel *);
+extern int  nv50_graph_unload_context(struct drm_device *);
+extern void nv50_graph_context_switch(struct drm_device *);
+
+/* nouveau_grctx.c */
+extern int  nouveau_grctx_prog_load(struct drm_device *);
+extern void nouveau_grctx_vals_load(struct drm_device *,
+				    struct nouveau_gpuobj *);
+extern void nouveau_grctx_fini(struct drm_device *);
+
+/* nv04_instmem.c */
+extern int  nv04_instmem_init(struct drm_device *);
+extern void nv04_instmem_takedown(struct drm_device *);
+extern int  nv04_instmem_suspend(struct drm_device *);
+extern void nv04_instmem_resume(struct drm_device *);
+extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+				  uint32_t *size);
+extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
+extern void nv04_instmem_finish_access(struct drm_device *);
+
+/* nv50_instmem.c */
+extern int  nv50_instmem_init(struct drm_device *);
+extern void nv50_instmem_takedown(struct drm_device *);
+extern int  nv50_instmem_suspend(struct drm_device *);
+extern void nv50_instmem_resume(struct drm_device *);
+extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+				  uint32_t *size);
+extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
+extern void nv50_instmem_finish_access(struct drm_device *);
+
+/* nv04_mc.c */
+extern int  nv04_mc_init(struct drm_device *);
+extern void nv04_mc_takedown(struct drm_device *);
+
+/* nv40_mc.c */
+extern int  nv40_mc_init(struct drm_device *);
+extern void nv40_mc_takedown(struct drm_device *);
+
+/* nv50_mc.c */
+extern int  nv50_mc_init(struct drm_device *);
+extern void nv50_mc_takedown(struct drm_device *);
+
+/* nv04_timer.c */
+extern int  nv04_timer_init(struct drm_device *);
+extern uint64_t nv04_timer_read(struct drm_device *);
+extern void nv04_timer_takedown(struct drm_device *);
+
+extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg);
+
+/* nv04_dac.c */
+extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
+extern int nv04_dac_output_offset(struct drm_encoder *encoder);
+extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
+
+/* nv04_dfp.c */
+extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
+extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
+			       int head, bool dl);
+extern void nv04_dfp_disable(struct drm_device *dev, int head);
+extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
+
+/* nv04_tv.c */
+extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
+extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+
+/* nv17_tv.c */
+extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+
+/* nv04_display.c */
+extern int nv04_display_create(struct drm_device *);
+extern void nv04_display_destroy(struct drm_device *);
+extern void nv04_display_restore(struct drm_device *);
+
+/* nv04_crtc.c */
+extern int nv04_crtc_create(struct drm_device *, int index);
+
+/* nouveau_bo.c */
+extern struct ttm_bo_driver nouveau_bo_driver;
+extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *,
+			  int size, int align, uint32_t flags,
+			  uint32_t tile_mode, uint32_t tile_flags,
+			  bool no_vm, bool mappable, struct nouveau_bo **);
+extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
+extern int nouveau_bo_unpin(struct nouveau_bo *);
+extern int nouveau_bo_map(struct nouveau_bo *);
+extern void nouveau_bo_unmap(struct nouveau_bo *);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
+extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
+extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
+extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
+
+/* nouveau_fence.c */
+struct nouveau_fence;
+extern int nouveau_fence_init(struct nouveau_channel *);
+extern void nouveau_fence_fini(struct nouveau_channel *);
+extern void nouveau_fence_update(struct nouveau_channel *);
+extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **,
+			     bool emit);
+extern int nouveau_fence_emit(struct nouveau_fence *);
+struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *);
+extern bool nouveau_fence_signalled(void *obj, void *arg);
+extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
+extern int nouveau_fence_flush(void *obj, void *arg);
+extern void nouveau_fence_unref(void **obj);
+extern void *nouveau_fence_ref(void *obj);
+extern void nouveau_fence_handler(struct drm_device *dev, int channel);
+
+/* nouveau_gem.c */
+extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
+			   int size, int align, uint32_t flags,
+			   uint32_t tile_mode, uint32_t tile_flags,
+			   bool no_vm, bool mappable, struct nouveau_bo **);
+extern int nouveau_gem_object_new(struct drm_gem_object *);
+extern void nouveau_gem_object_del(struct drm_gem_object *);
+extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
+				 struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
+				     struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *,
+					  struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *,
+					   struct drm_file *);
+extern int nouveau_gem_ioctl_pin(struct drm_device *, void *,
+				 struct drm_file *);
+extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *,
+				   struct drm_file *);
+extern int nouveau_gem_ioctl_tile(struct drm_device *, void *,
+				  struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
+				      struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
+				      struct drm_file *);
+extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
+				  struct drm_file *);
+
+/* nv17_gpio.c */
+int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
+#ifndef ioread32_native
+#ifdef __BIG_ENDIAN
+#define ioread16_native ioread16be
+#define iowrite16_native iowrite16be
+#define ioread32_native  ioread32be
+#define iowrite32_native iowrite32be
+#else /* def __BIG_ENDIAN */
+#define ioread16_native ioread16
+#define iowrite16_native iowrite16
+#define ioread32_native  ioread32
+#define iowrite32_native iowrite32
+#endif /* def __BIG_ENDIAN else */
+#endif /* !ioread32_native */
+
+/* channel control reg access */
+static inline u32 nvchan_rd32(struct nouveau_channel *chan, unsigned reg)
+{
+	return ioread32_native(chan->user + reg);
+}
+
+static inline void nvchan_wr32(struct nouveau_channel *chan,
+							unsigned reg, u32 val)
+{
+	iowrite32_native(val, chan->user + reg);
+}
+
+/* register access */
+static inline u32 nv_rd32(struct drm_device *dev, unsigned reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread32_native(dev_priv->mmio + reg);
+}
+
+static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite32_native(val, dev_priv->mmio + reg);
+}
+
+static inline u8 nv_rd08(struct drm_device *dev, unsigned reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread8(dev_priv->mmio + reg);
+}
+
+static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite8(val, dev_priv->mmio + reg);
+}
+
+#define nv_wait(reg, mask, val) \
+	nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val))
+
+/* PRAMIN access */
+static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return ioread32_native(dev_priv->ramin + offset);
+}
+
+static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	iowrite32_native(val, dev_priv->ramin + offset);
+}
+
+/* object access */
+static inline u32 nv_ro32(struct drm_device *dev, struct nouveau_gpuobj *obj,
+				unsigned index)
+{
+	return nv_ri32(dev, obj->im_pramin->start + index * 4);
+}
+
+static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj,
+				unsigned index, u32 val)
+{
+	nv_wi32(dev, obj->im_pramin->start + index * 4, val);
+}
+
+/*
+ * Logging
+ * Argument d is (struct drm_device *).
+ */
+#define NV_PRINTK(level, d, fmt, arg...) \
+	printk(level "[" DRM_NAME "] " DRIVER_NAME " %s: " fmt, \
+					pci_name(d->pdev), ##arg)
+#ifndef NV_DEBUG_NOTRACE
+#define NV_DEBUG(d, fmt, arg...) do {                                          \
+	if (drm_debug & DRM_UT_DRIVER) {                                       \
+		NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__,             \
+			  __LINE__, ##arg);                                    \
+	}                                                                      \
+} while (0)
+#define NV_DEBUG_KMS(d, fmt, arg...) do {                                      \
+	if (drm_debug & DRM_UT_KMS) {                                          \
+		NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__,             \
+			  __LINE__, ##arg);                                    \
+	}                                                                      \
+} while (0)
+#else
+#define NV_DEBUG(d, fmt, arg...) do {                                          \
+	if (drm_debug & DRM_UT_DRIVER)                                         \
+		NV_PRINTK(KERN_DEBUG, d, fmt, ##arg);                          \
+} while (0)
+#define NV_DEBUG_KMS(d, fmt, arg...) do {                                      \
+	if (drm_debug & DRM_UT_KMS)                                            \
+		NV_PRINTK(KERN_DEBUG, d, fmt, ##arg);                          \
+} while (0)
+#endif
+#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg)
+#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
+#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg)
+#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
+#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg)
+
+/* nouveau_reg_debug bitmask */
+enum {
+	NOUVEAU_REG_DEBUG_MC             = 0x1,
+	NOUVEAU_REG_DEBUG_VIDEO          = 0x2,
+	NOUVEAU_REG_DEBUG_FB             = 0x4,
+	NOUVEAU_REG_DEBUG_EXTDEV         = 0x8,
+	NOUVEAU_REG_DEBUG_CRTC           = 0x10,
+	NOUVEAU_REG_DEBUG_RAMDAC         = 0x20,
+	NOUVEAU_REG_DEBUG_VGACRTC        = 0x40,
+	NOUVEAU_REG_DEBUG_RMVIO          = 0x80,
+	NOUVEAU_REG_DEBUG_VGAATTR        = 0x100,
+	NOUVEAU_REG_DEBUG_EVO            = 0x200,
+};
+
+#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \
+	if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_##type) \
+		NV_PRINTK(KERN_DEBUG, dev, "%s: " fmt, __func__, ##arg); \
+} while (0)
+
+static inline bool
+nv_two_heads(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int impl = dev->pci_device & 0x0ff0;
+
+	if (dev_priv->card_type >= NV_10 && impl != 0x0100 &&
+	    impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
+		return true;
+
+	return false;
+}
+
+static inline bool
+nv_gf4_disp_arch(struct drm_device *dev)
+{
+	return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110;
+}
+
+static inline bool
+nv_two_reg_pll(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const int impl = dev->pci_device & 0x0ff0;
+
+	if (impl == 0x0310 || impl == 0x0340 || dev_priv->card_type >= NV_40)
+		return true;
+	return false;
+}
+
+#define NV_SW                                                        0x0000506e
+#define NV_SW_DMA_SEMAPHORE                                          0x00000060
+#define NV_SW_SEMAPHORE_OFFSET                                       0x00000064
+#define NV_SW_SEMAPHORE_ACQUIRE                                      0x00000068
+#define NV_SW_SEMAPHORE_RELEASE                                      0x0000006c
+#define NV_SW_DMA_VBLSEM                                             0x0000018c
+#define NV_SW_VBLSEM_OFFSET                                          0x00000400
+#define NV_SW_VBLSEM_RELEASE_VALUE                                   0x00000404
+#define NV_SW_VBLSEM_RELEASE                                         0x00000408
+
+#endif /* __NOUVEAU_DRV_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_encoder.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NOUVEAU_ENCODER_H__
+#define __NOUVEAU_ENCODER_H__
+
+#include "drm_encoder_slave.h"
+#include "nouveau_drv.h"
+
+#define NV_DPMS_CLEARED 0x80
+
+struct nouveau_encoder {
+	struct drm_encoder_slave base;
+
+	struct dcb_entry *dcb;
+	int or;
+
+	struct drm_display_mode mode;
+	int last_dpms;
+
+	struct nv04_output_reg restore;
+
+	void (*disconnect)(struct nouveau_encoder *encoder);
+
+	union {
+		struct {
+			int dpcd_version;
+			int link_nr;
+			int link_bw;
+		} dp;
+	};
+};
+
+static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc)
+{
+	struct drm_encoder_slave *slave = to_encoder_slave(enc);
+
+	return container_of(slave, struct nouveau_encoder, base);
+}
+
+static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
+{
+	return &enc->base.base;
+}
+
+struct nouveau_connector *
+nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
+int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
+int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+
+struct bit_displayport_encoder_table {
+	uint32_t match;
+	uint8_t  record_nr;
+	uint8_t  unknown;
+	uint16_t script0;
+	uint16_t script1;
+	uint16_t unknown_table;
+} __attribute__ ((packed));
+
+struct bit_displayport_encoder_table_entry {
+	uint8_t vs_level;
+	uint8_t pre_level;
+	uint8_t reg0;
+	uint8_t reg1;
+	uint8_t reg2;
+} __attribute__ ((packed));
+
+#endif /* __NOUVEAU_ENCODER_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2007 David Airlie
+ *
+ * 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.
+ *
+ * Authors:
+ *     David Airlie
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/screen_info.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_fbcon.h"
+#include "nouveau_dma.h"
+
+static int
+nouveau_fbcon_sync(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	int ret, i;
+
+	if (!chan || !chan->accel_done ||
+	    info->state != FBINFO_STATE_RUNNING ||
+	    info->flags & FBINFO_HWACCEL_DISABLED)
+		return 0;
+
+	if (RING_SPACE(chan, 4)) {
+		nouveau_fbcon_gpu_lockup(info);
+		return 0;
+	}
+
+	BEGIN_RING(chan, 0, 0x0104, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, 0, 0x0100, 1);
+	OUT_RING(chan, 0);
+	nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff);
+	FIRE_RING(chan);
+
+	ret = -EBUSY;
+	for (i = 0; i < 100000; i++) {
+		if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) {
+			ret = 0;
+			break;
+		}
+		DRM_UDELAY(1);
+	}
+
+	if (ret) {
+		nouveau_fbcon_gpu_lockup(info);
+		return 0;
+	}
+
+	chan->accel_done = false;
+	return 0;
+}
+
+static struct fb_ops nouveau_fbcon_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_sync = nouveau_fbcon_sync,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static struct fb_ops nv04_fbcon_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
+	.fb_fillrect = nv04_fbcon_fillrect,
+	.fb_copyarea = nv04_fbcon_copyarea,
+	.fb_imageblit = nv04_fbcon_imageblit,
+	.fb_sync = nouveau_fbcon_sync,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static struct fb_ops nv50_fbcon_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
+	.fb_fillrect = nv50_fbcon_fillrect,
+	.fb_copyarea = nv50_fbcon_copyarea,
+	.fb_imageblit = nv50_fbcon_imageblit,
+	.fb_sync = nouveau_fbcon_sync,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+				    u16 blue, int regno)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->lut.r[regno] = red;
+	nv_crtc->lut.g[regno] = green;
+	nv_crtc->lut.b[regno] = blue;
+}
+
+static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+				    u16 *blue, int regno)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	*red = nv_crtc->lut.r[regno];
+	*green = nv_crtc->lut.g[regno];
+	*blue = nv_crtc->lut.b[regno];
+}
+
+static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
+	.gamma_set = nouveau_fbcon_gamma_set,
+	.gamma_get = nouveau_fbcon_gamma_get
+};
+
+#if defined(__i386__) || defined(__x86_64__)
+static bool
+nouveau_fbcon_has_vesafb_or_efifb(struct drm_device *dev)
+{
+	struct pci_dev *pdev = dev->pdev;
+	int ramin;
+
+	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB &&
+	    screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
+		return false;
+
+	if (screen_info.lfb_base < pci_resource_start(pdev, 1))
+		goto not_fb;
+
+	if (screen_info.lfb_base + screen_info.lfb_size >=
+	    pci_resource_start(pdev, 1) + pci_resource_len(pdev, 1))
+		goto not_fb;
+
+	return true;
+not_fb:
+	ramin = 2;
+	if (pci_resource_len(pdev, ramin) == 0) {
+		ramin = 3;
+		if (pci_resource_len(pdev, ramin) == 0)
+			return false;
+	}
+
+	if (screen_info.lfb_base < pci_resource_start(pdev, ramin))
+		return false;
+
+	if (screen_info.lfb_base + screen_info.lfb_size >=
+	    pci_resource_start(pdev, ramin) + pci_resource_len(pdev, ramin))
+		return false;
+
+	return true;
+}
+#endif
+
+void
+nouveau_fbcon_zfill(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct fb_info *info = dev_priv->fbdev_info;
+	struct fb_fillrect rect;
+
+	/* Clear the entire fbcon.  The drm will program every connector
+	 * with it's preferred mode.  If the sizes differ, one display will
+	 * quite likely have garbage around the console.
+	 */
+	rect.dx = rect.dy = 0;
+	rect.width = info->var.xres_virtual;
+	rect.height = info->var.yres_virtual;
+	rect.color = 0;
+	rect.rop = ROP_COPY;
+	info->fbops->fb_fillrect(info, &rect);
+}
+
+static int
+nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
+		     uint32_t fb_height, uint32_t surface_width,
+		     uint32_t surface_height, uint32_t surface_depth,
+		     uint32_t surface_bpp, struct drm_framebuffer **pfb)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct fb_info *info;
+	struct nouveau_fbcon_par *par;
+	struct drm_framebuffer *fb;
+	struct nouveau_framebuffer *nouveau_fb;
+	struct nouveau_bo *nvbo;
+	struct drm_mode_fb_cmd mode_cmd;
+	struct device *device = &dev->pdev->dev;
+	int size, ret;
+
+	mode_cmd.width = surface_width;
+	mode_cmd.height = surface_height;
+
+	mode_cmd.bpp = surface_bpp;
+	mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3);
+	mode_cmd.pitch = roundup(mode_cmd.pitch, 256);
+	mode_cmd.depth = surface_depth;
+
+	size = mode_cmd.pitch * mode_cmd.height;
+	size = roundup(size, PAGE_SIZE);
+
+	ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM,
+			      0, 0x0000, false, true, &nvbo);
+	if (ret) {
+		NV_ERROR(dev, "failed to allocate framebuffer\n");
+		goto out;
+	}
+
+	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "failed to pin fb: %d\n", ret);
+		nouveau_bo_ref(NULL, &nvbo);
+		goto out;
+	}
+
+	ret = nouveau_bo_map(nvbo);
+	if (ret) {
+		NV_ERROR(dev, "failed to map fb: %d\n", ret);
+		nouveau_bo_unpin(nvbo);
+		nouveau_bo_ref(NULL, &nvbo);
+		goto out;
+	}
+
+	mutex_lock(&dev->struct_mutex);
+
+	fb = nouveau_framebuffer_create(dev, nvbo, &mode_cmd);
+	if (!fb) {
+		ret = -ENOMEM;
+		NV_ERROR(dev, "failed to allocate fb.\n");
+		goto out_unref;
+	}
+
+	list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
+
+	nouveau_fb = nouveau_framebuffer(fb);
+	*pfb = fb;
+
+	info = framebuffer_alloc(sizeof(struct nouveau_fbcon_par), device);
+	if (!info) {
+		ret = -ENOMEM;
+		goto out_unref;
+	}
+
+	par = info->par;
+	par->helper.funcs = &nouveau_fbcon_helper_funcs;
+	par->helper.dev = dev;
+	ret = drm_fb_helper_init_crtc_count(&par->helper, 2, 4);
+	if (ret)
+		goto out_unref;
+	dev_priv->fbdev_info = info;
+
+	strcpy(info->fix.id, "nouveaufb");
+	if (nouveau_nofbaccel)
+		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED;
+	else
+		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
+			      FBINFO_HWACCEL_FILLRECT |
+			      FBINFO_HWACCEL_IMAGEBLIT;
+	info->fbops = &nouveau_fbcon_ops;
+	info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset -
+			       dev_priv->vm_vram_base;
+	info->fix.smem_len = size;
+
+	info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
+	info->screen_size = size;
+
+	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
+	drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
+
+	/* FIXME: we really shouldn't expose mmio space at all */
+	info->fix.mmio_start = pci_resource_start(dev->pdev, 1);
+	info->fix.mmio_len = pci_resource_len(dev->pdev, 1);
+
+	/* Set aperture base/size for vesafb takeover */
+#if defined(__i386__) || defined(__x86_64__)
+	if (nouveau_fbcon_has_vesafb_or_efifb(dev)) {
+		/* Some NVIDIA VBIOS' are stupid and decide to put the
+		 * framebuffer in the middle of the PRAMIN BAR for
+		 * whatever reason.  We need to know the exact lfb_base
+		 * to get vesafb kicked off, and the only reliable way
+		 * we have left is to find out lfb_base the same way
+		 * vesafb did.
+		 */
+		info->aperture_base = screen_info.lfb_base;
+		info->aperture_size = screen_info.lfb_size;
+		if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
+			info->aperture_size *= 65536;
+	} else
+#endif
+	{
+		info->aperture_base = info->fix.mmio_start;
+		info->aperture_size = info->fix.mmio_len;
+	}
+
+	info->pixmap.size = 64*1024;
+	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+	info->pixmap.scan_align = 1;
+
+	fb->fbdev = info;
+
+	par->nouveau_fb = nouveau_fb;
+	par->dev = dev;
+
+	if (dev_priv->channel && !nouveau_nofbaccel) {
+		switch (dev_priv->card_type) {
+		case NV_50:
+			nv50_fbcon_accel_init(info);
+			info->fbops = &nv50_fbcon_ops;
+			break;
+		default:
+			nv04_fbcon_accel_init(info);
+			info->fbops = &nv04_fbcon_ops;
+			break;
+		};
+	}
+
+	nouveau_fbcon_zfill(dev);
+
+	/* To allow resizeing without swapping buffers */
+	NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
+						nouveau_fb->base.width,
+						nouveau_fb->base.height,
+						nvbo->bo.offset, nvbo);
+
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+
+out_unref:
+	mutex_unlock(&dev->struct_mutex);
+out:
+	return ret;
+}
+
+int
+nouveau_fbcon_probe(struct drm_device *dev)
+{
+	NV_DEBUG_KMS(dev, "\n");
+
+	return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create);
+}
+
+int
+nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb)
+{
+	struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fb);
+	struct fb_info *info;
+
+	if (!fb)
+		return -EINVAL;
+
+	info = fb->fbdev;
+	if (info) {
+		struct nouveau_fbcon_par *par = info->par;
+
+		unregister_framebuffer(info);
+		nouveau_bo_unmap(nouveau_fb->nvbo);
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(nouveau_fb->nvbo->gem);
+		nouveau_fb->nvbo = NULL;
+		mutex_unlock(&dev->struct_mutex);
+		if (par)
+			drm_fb_helper_free(&par->helper);
+		framebuffer_release(info);
+	}
+
+	return 0;
+}
+
+void nouveau_fbcon_gpu_lockup(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+
+	NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+	info->flags |= FBINFO_HWACCEL_DISABLED;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fbcon.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NOUVEAU_FBCON_H__
+#define __NOUVEAU_FBCON_H__
+
+#include "drm_fb_helper.h"
+
+struct nouveau_fbcon_par {
+	struct drm_fb_helper helper;
+	struct drm_device *dev;
+	struct nouveau_framebuffer *nouveau_fb;
+};
+
+int nouveau_fbcon_probe(struct drm_device *dev);
+int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb);
+void nouveau_fbcon_restore(void);
+void nouveau_fbcon_zfill(struct drm_device *dev);
+
+void nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
+void nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
+int nv04_fbcon_accel_init(struct fb_info *info);
+void nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
+void nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
+int nv50_fbcon_accel_init(struct fb_info *info);
+
+void nouveau_fbcon_gpu_lockup(struct fb_info *info);
+#endif /* __NV50_FBCON_H__ */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fb.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fb.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NOUVEAU_FB_H__
+#define __NOUVEAU_FB_H__
+
+struct nouveau_framebuffer {
+	struct drm_framebuffer base;
+	struct nouveau_bo *nvbo;
+};
+
+static inline struct nouveau_framebuffer *
+nouveau_framebuffer(struct drm_framebuffer *fb)
+{
+	return container_of(fb, struct nouveau_framebuffer, base);
+}
+
+extern const struct drm_mode_config_funcs nouveau_mode_config_funcs;
+
+struct drm_framebuffer *
+nouveau_framebuffer_create(struct drm_device *, struct nouveau_bo *,
+			   struct drm_mode_fb_cmd *);
+
+#endif /* __NOUVEAU_FB_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fence.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fence.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_fence.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_fence.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+#define USE_REFCNT (dev_priv->card_type >= NV_10)
+
+struct nouveau_fence {
+	struct nouveau_channel *channel;
+	struct kref refcount;
+	struct list_head entry;
+
+	uint32_t sequence;
+	bool signalled;
+};
+
+static inline struct nouveau_fence *
+nouveau_fence(void *sync_obj)
+{
+	return (struct nouveau_fence *)sync_obj;
+}
+
+static void
+nouveau_fence_del(struct kref *ref)
+{
+	struct nouveau_fence *fence =
+		container_of(ref, struct nouveau_fence, refcount);
+
+	kfree(fence);
+}
+
+void
+nouveau_fence_update(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct list_head *entry, *tmp;
+	struct nouveau_fence *fence;
+	uint32_t sequence;
+
+	if (USE_REFCNT)
+		sequence = nvchan_rd32(chan, 0x48);
+	else
+		sequence = chan->fence.last_sequence_irq;
+
+	if (chan->fence.sequence_ack == sequence)
+		return;
+	chan->fence.sequence_ack = sequence;
+
+	list_for_each_safe(entry, tmp, &chan->fence.pending) {
+		fence = list_entry(entry, struct nouveau_fence, entry);
+
+		sequence = fence->sequence;
+		fence->signalled = true;
+		list_del(&fence->entry);
+		kref_put(&fence->refcount, nouveau_fence_del);
+
+		if (sequence == chan->fence.sequence_ack)
+			break;
+	}
+}
+
+int
+nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence,
+		  bool emit)
+{
+	struct nouveau_fence *fence;
+	int ret = 0;
+
+	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+	if (!fence)
+		return -ENOMEM;
+	kref_init(&fence->refcount);
+	fence->channel = chan;
+
+	if (emit)
+		ret = nouveau_fence_emit(fence);
+
+	if (ret)
+		nouveau_fence_unref((void *)&fence);
+	*pfence = fence;
+	return ret;
+}
+
+struct nouveau_channel *
+nouveau_fence_channel(struct nouveau_fence *fence)
+{
+	return fence ? fence->channel : NULL;
+}
+
+int
+nouveau_fence_emit(struct nouveau_fence *fence)
+{
+	struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
+	struct nouveau_channel *chan = fence->channel;
+	unsigned long flags;
+	int ret;
+
+	ret = RING_SPACE(chan, 2);
+	if (ret)
+		return ret;
+
+	if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
+		spin_lock_irqsave(&chan->fence.lock, flags);
+		nouveau_fence_update(chan);
+		spin_unlock_irqrestore(&chan->fence.lock, flags);
+
+		BUG_ON(chan->fence.sequence ==
+		       chan->fence.sequence_ack - 1);
+	}
+
+	fence->sequence = ++chan->fence.sequence;
+
+	kref_get(&fence->refcount);
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	list_add_tail(&fence->entry, &chan->fence.pending);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+
+	BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
+	OUT_RING(chan, fence->sequence);
+	FIRE_RING(chan);
+
+	return 0;
+}
+
+void
+nouveau_fence_unref(void **sync_obj)
+{
+	struct nouveau_fence *fence = nouveau_fence(*sync_obj);
+
+	if (fence)
+		kref_put(&fence->refcount, nouveau_fence_del);
+	*sync_obj = NULL;
+}
+
+void *
+nouveau_fence_ref(void *sync_obj)
+{
+	struct nouveau_fence *fence = nouveau_fence(sync_obj);
+
+	kref_get(&fence->refcount);
+	return sync_obj;
+}
+
+bool
+nouveau_fence_signalled(void *sync_obj, void *sync_arg)
+{
+	struct nouveau_fence *fence = nouveau_fence(sync_obj);
+	struct nouveau_channel *chan = fence->channel;
+	unsigned long flags;
+
+	if (fence->signalled)
+		return true;
+
+	spin_lock_irqsave(&chan->fence.lock, flags);
+	nouveau_fence_update(chan);
+	spin_unlock_irqrestore(&chan->fence.lock, flags);
+	return fence->signalled;
+}
+
+int
+nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
+{
+	unsigned long timeout = jiffies + (3 * DRM_HZ);
+	int ret = 0;
+
+	__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+
+	while (1) {
+		if (nouveau_fence_signalled(sync_obj, sync_arg))
+			break;
+
+		if (time_after_eq(jiffies, timeout)) {
+			ret = -EBUSY;
+			break;
+		}
+
+		if (lazy)
+			schedule_timeout(1);
+
+		if (intr && signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+
+	__set_current_state(TASK_RUNNING);
+
+	return ret;
+}
+
+int
+nouveau_fence_flush(void *sync_obj, void *sync_arg)
+{
+	return 0;
+}
+
+void
+nouveau_fence_handler(struct drm_device *dev, int channel)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = NULL;
+
+	if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
+		chan = dev_priv->fifos[channel];
+
+	if (chan) {
+		spin_lock_irq(&chan->fence.lock);
+		nouveau_fence_update(chan);
+		spin_unlock_irq(&chan->fence.lock);
+	}
+}
+
+int
+nouveau_fence_init(struct nouveau_channel *chan)
+{
+	INIT_LIST_HEAD(&chan->fence.pending);
+	spin_lock_init(&chan->fence.lock);
+	return 0;
+}
+
+void
+nouveau_fence_fini(struct nouveau_channel *chan)
+{
+	struct list_head *entry, *tmp;
+	struct nouveau_fence *fence;
+
+	list_for_each_safe(entry, tmp, &chan->fence.pending) {
+		fence = list_entry(entry, struct nouveau_fence, entry);
+
+		fence->signalled = true;
+		list_del(&fence->entry);
+		kref_put(&fence->refcount, nouveau_fence_del);
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_gem.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,994 @@
+/*
+ * Copyright (C) 2008 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+
+#define nouveau_gem_pushbuf_sync(chan) 0
+
+int
+nouveau_gem_object_new(struct drm_gem_object *gem)
+{
+	return 0;
+}
+
+void
+nouveau_gem_object_del(struct drm_gem_object *gem)
+{
+	struct nouveau_bo *nvbo = gem->driver_private;
+	struct ttm_buffer_object *bo = &nvbo->bo;
+
+	if (!nvbo)
+		return;
+	nvbo->gem = NULL;
+
+	if (unlikely(nvbo->cpu_filp))
+		ttm_bo_synccpu_write_release(bo);
+
+	if (unlikely(nvbo->pin_refcnt)) {
+		nvbo->pin_refcnt = 1;
+		nouveau_bo_unpin(nvbo);
+	}
+
+	ttm_bo_unref(&bo);
+}
+
+int
+nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan,
+		int size, int align, uint32_t flags, uint32_t tile_mode,
+		uint32_t tile_flags, bool no_vm, bool mappable,
+		struct nouveau_bo **pnvbo)
+{
+	struct nouveau_bo *nvbo;
+	int ret;
+
+	ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode,
+			     tile_flags, no_vm, mappable, pnvbo);
+	if (ret)
+		return ret;
+	nvbo = *pnvbo;
+
+	nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
+	if (!nvbo->gem) {
+		nouveau_bo_ref(NULL, pnvbo);
+		return -ENOMEM;
+	}
+
+	nvbo->bo.persistant_swap_storage = nvbo->gem->filp;
+	nvbo->gem->driver_private = nvbo;
+	return 0;
+}
+
+static int
+nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep)
+{
+	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+		rep->domain = NOUVEAU_GEM_DOMAIN_GART;
+	else
+		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
+
+	rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
+	rep->offset = nvbo->bo.offset;
+	rep->map_handle = nvbo->mappable ? nvbo->bo.addr_space_offset : 0;
+	rep->tile_mode = nvbo->tile_mode;
+	rep->tile_flags = nvbo->tile_flags;
+	return 0;
+}
+
+static bool
+nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) {
+	switch (tile_flags) {
+	case 0x0000:
+	case 0x1800:
+	case 0x2800:
+	case 0x4800:
+	case 0x7000:
+	case 0x7400:
+	case 0x7a00:
+	case 0xe000:
+		break;
+	default:
+		NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
+		return false;
+	}
+
+	return true;
+}
+
+int
+nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_new *req = data;
+	struct nouveau_bo *nvbo = NULL;
+	struct nouveau_channel *chan = NULL;
+	uint32_t flags = 0;
+	int ret = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
+		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
+
+	if (req->channel_hint) {
+		NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint,
+						     file_priv, chan);
+	}
+
+	if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
+		flags |= TTM_PL_FLAG_VRAM;
+	if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART)
+		flags |= TTM_PL_FLAG_TT;
+	if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU)
+		flags |= TTM_PL_FLAG_SYSTEM;
+
+	if (!nouveau_gem_tile_flags_valid(dev, req->info.tile_flags))
+		return -EINVAL;
+
+	ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags,
+			      req->info.tile_mode, req->info.tile_flags, false,
+			      (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE),
+			      &nvbo);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gem_info(nvbo->gem, &req->info);
+	if (ret)
+		goto out;
+
+	ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_handle_unreference(nvbo->gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	if (ret)
+		drm_gem_object_unreference(nvbo->gem);
+	return ret;
+}
+
+static int
+nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
+		       uint32_t write_domains, uint32_t valid_domains)
+{
+	struct nouveau_bo *nvbo = gem->driver_private;
+	struct ttm_buffer_object *bo = &nvbo->bo;
+	uint64_t flags;
+
+	if (!valid_domains || (!read_domains && !write_domains))
+		return -EINVAL;
+
+	if (write_domains) {
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
+			flags = TTM_PL_FLAG_VRAM;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    (write_domains & NOUVEAU_GEM_DOMAIN_GART))
+			flags = TTM_PL_FLAG_TT;
+		else
+			return -EINVAL;
+	} else {
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    bo->mem.mem_type == TTM_PL_VRAM)
+			flags = TTM_PL_FLAG_VRAM;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
+		    bo->mem.mem_type == TTM_PL_TT)
+			flags = TTM_PL_FLAG_TT;
+		else
+		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
+			flags = TTM_PL_FLAG_VRAM;
+		else
+			flags = TTM_PL_FLAG_TT;
+	}
+
+	nouveau_bo_placement_set(nvbo, flags);
+	return 0;
+}
+
+struct validate_op {
+	struct list_head vram_list;
+	struct list_head gart_list;
+	struct list_head both_list;
+};
+
+static void
+validate_fini_list(struct list_head *list, struct nouveau_fence *fence)
+{
+	struct list_head *entry, *tmp;
+	struct nouveau_bo *nvbo;
+
+	list_for_each_safe(entry, tmp, list) {
+		nvbo = list_entry(entry, struct nouveau_bo, entry);
+		if (likely(fence)) {
+			struct nouveau_fence *prev_fence;
+
+			spin_lock(&nvbo->bo.lock);
+			prev_fence = nvbo->bo.sync_obj;
+			nvbo->bo.sync_obj = nouveau_fence_ref(fence);
+			spin_unlock(&nvbo->bo.lock);
+			nouveau_fence_unref((void *)&prev_fence);
+		}
+
+		list_del(&nvbo->entry);
+		nvbo->reserved_by = NULL;
+		ttm_bo_unreserve(&nvbo->bo);
+		drm_gem_object_unreference(nvbo->gem);
+	}
+}
+
+static void
+validate_fini(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);
+}
+
+static int
+validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
+	      struct drm_nouveau_gem_pushbuf_bo *pbbo,
+	      int nr_buffers, struct validate_op *op)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t sequence;
+	int trycnt = 0;
+	int ret, i;
+
+	sequence = atomic_add_return(1, &dev_priv->ttm.validate_sequence);
+retry:
+	if (++trycnt > 100000) {
+		NV_ERROR(dev, "%s failed and gave up.\n", __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < nr_buffers; i++) {
+		struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[i];
+		struct drm_gem_object *gem;
+		struct nouveau_bo *nvbo;
+
+		gem = drm_gem_object_lookup(dev, file_priv, b->handle);
+		if (!gem) {
+			NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+		nvbo = gem->driver_private;
+
+		if (nvbo->reserved_by && nvbo->reserved_by == file_priv) {
+			NV_ERROR(dev, "multiple instances of buffer %d on "
+				      "validation list\n", b->handle);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+
+		ret = ttm_bo_reserve(&nvbo->bo, false, false, true, sequence);
+		if (ret) {
+			validate_fini(op, NULL);
+			if (ret == -EAGAIN)
+				ret = ttm_bo_wait_unreserved(&nvbo->bo, false);
+			drm_gem_object_unreference(gem);
+			if (ret)
+				return ret;
+			goto retry;
+		}
+
+		nvbo->reserved_by = file_priv;
+		nvbo->pbbo_index = i;
+		if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+		    (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART))
+			list_add_tail(&nvbo->entry, &op->both_list);
+		else
+		if (b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+			list_add_tail(&nvbo->entry, &op->vram_list);
+		else
+		if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+			list_add_tail(&nvbo->entry, &op->gart_list);
+		else {
+			NV_ERROR(dev, "invalid valid domains: 0x%08x\n",
+				 b->valid_domains);
+			list_add_tail(&nvbo->entry, &op->both_list);
+			validate_fini(op, NULL);
+			return -EINVAL;
+		}
+
+		if (unlikely(atomic_read(&nvbo->bo.cpu_writers) > 0)) {
+			validate_fini(op, NULL);
+
+			if (nvbo->cpu_filp == file_priv) {
+				NV_ERROR(dev, "bo %p mapped by process trying "
+					      "to validate it!\n", nvbo);
+				return -EINVAL;
+			}
+
+			ret = ttm_bo_wait_cpu(&nvbo->bo, false);
+			if (ret)
+				return ret;
+			goto retry;
+		}
+	}
+
+	return 0;
+}
+
+static int
+validate_list(struct nouveau_channel *chan, struct list_head *list,
+	      struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
+{
+	struct drm_nouveau_gem_pushbuf_bo __user *upbbo =
+				(void __force __user *)(uintptr_t)user_pbbo_ptr;
+	struct nouveau_bo *nvbo;
+	int ret, relocs = 0;
+
+	list_for_each_entry(nvbo, list, entry) {
+		struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
+		struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
+
+		if (prev_fence && nouveau_fence_channel(prev_fence) != chan) {
+			spin_lock(&nvbo->bo.lock);
+			ret = ttm_bo_wait(&nvbo->bo, false, false, false);
+			spin_unlock(&nvbo->bo.lock);
+			if (unlikely(ret))
+				return ret;
+		}
+
+		ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
+					     b->write_domains,
+					     b->valid_domains);
+		if (unlikely(ret))
+			return ret;
+
+		nvbo->channel = chan;
+		ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
+				      false, false);
+		nvbo->channel = NULL;
+		if (unlikely(ret))
+			return ret;
+
+		if (nvbo->bo.offset == b->presumed_offset &&
+		    ((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
+		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
+		     (nvbo->bo.mem.mem_type == TTM_PL_TT &&
+		      b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART)))
+			continue;
+
+		if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+			b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART;
+		else
+			b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM;
+		b->presumed_offset = nvbo->bo.offset;
+		b->presumed_ok = 0;
+		relocs++;
+
+		if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index], b, sizeof(*b)))
+			return -EFAULT;
+	}
+
+	return relocs;
+}
+
+static int
+nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
+			     struct drm_file *file_priv,
+			     struct drm_nouveau_gem_pushbuf_bo *pbbo,
+			     uint64_t user_buffers, int nr_buffers,
+			     struct validate_op *op, int *apply_relocs)
+{
+	int ret, relocs = 0;
+
+	INIT_LIST_HEAD(&op->vram_list);
+	INIT_LIST_HEAD(&op->gart_list);
+	INIT_LIST_HEAD(&op->both_list);
+
+	if (nr_buffers == 0)
+		return 0;
+
+	ret = validate_init(chan, file_priv, pbbo, nr_buffers, op);
+	if (unlikely(ret))
+		return ret;
+
+	ret = validate_list(chan, &op->vram_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	ret = validate_list(chan, &op->gart_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	ret = validate_list(chan, &op->both_list, pbbo, user_buffers);
+	if (unlikely(ret < 0)) {
+		validate_fini(op, NULL);
+		return ret;
+	}
+	relocs += ret;
+
+	*apply_relocs = relocs;
+	return 0;
+}
+
+static inline void *
+u_memcpya(uint64_t user, unsigned nmemb, unsigned size)
+{
+	void *mem;
+	void __user *userptr = (void __force __user *)(uintptr_t)user;
+
+	mem = kmalloc(nmemb * size, GFP_KERNEL);
+	if (!mem)
+		return ERR_PTR(-ENOMEM);
+
+	if (DRM_COPY_FROM_USER(mem, userptr, nmemb * size)) {
+		kfree(mem);
+		return ERR_PTR(-EFAULT);
+	}
+
+	return mem;
+}
+
+static int
+nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo,
+				struct drm_nouveau_gem_pushbuf_bo *bo,
+				unsigned nr_relocs, uint64_t ptr_relocs,
+				unsigned nr_dwords, unsigned first_dword,
+				uint32_t *pushbuf, bool is_iomem)
+{
+	struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL;
+	struct drm_device *dev = chan->dev;
+	int ret = 0;
+	unsigned i;
+
+	reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc));
+	if (IS_ERR(reloc))
+		return PTR_ERR(reloc);
+
+	for (i = 0; i < nr_relocs; i++) {
+		struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i];
+		struct drm_nouveau_gem_pushbuf_bo *b;
+		uint32_t data;
+
+		if (r->bo_index >= nr_bo || r->reloc_index < first_dword ||
+		    r->reloc_index >= first_dword + nr_dwords) {
+			NV_ERROR(dev, "Bad relocation %d\n", i);
+			NV_ERROR(dev, "  bo: %d max %d\n", r->bo_index, nr_bo);
+			NV_ERROR(dev, "  id: %d max %d\n", r->reloc_index, nr_dwords);
+			ret = -EINVAL;
+			break;
+		}
+
+		b = &bo[r->bo_index];
+		if (b->presumed_ok)
+			continue;
+
+		if (r->flags & NOUVEAU_GEM_RELOC_LOW)
+			data = b->presumed_offset + r->data;
+		else
+		if (r->flags & NOUVEAU_GEM_RELOC_HIGH)
+			data = (b->presumed_offset + r->data) >> 32;
+		else
+			data = r->data;
+
+		if (r->flags & NOUVEAU_GEM_RELOC_OR) {
+			if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART)
+				data |= r->tor;
+			else
+				data |= r->vor;
+		}
+
+		if (is_iomem)
+			iowrite32_native(data, (void __force __iomem *)
+						&pushbuf[r->reloc_index]);
+		else
+			pushbuf[r->reloc_index] = data;
+	}
+
+	kfree(reloc);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pushbuf *req = data;
+	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
+	struct nouveau_channel *chan;
+	struct validate_op op;
+	struct nouveau_fence* fence = 0;
+	uint32_t *pushbuf = NULL;
+	int ret = 0, do_reloc = 0, i;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
+
+	if (req->nr_dwords >= chan->dma.max ||
+	    req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
+	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
+		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
+		NV_ERROR(dev, "  dwords : %d max %d\n", req->nr_dwords,
+			 chan->dma.max - 1);
+		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
+			 NOUVEAU_GEM_MAX_BUFFERS);
+		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
+			 NOUVEAU_GEM_MAX_RELOCS);
+		return -EINVAL;
+	}
+
+	pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t));
+	if (IS_ERR(pushbuf))
+		return PTR_ERR(pushbuf);
+
+	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
+	if (IS_ERR(bo)) {
+		kfree(pushbuf);
+		return PTR_ERR(bo);
+	}
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Validate buffer list */
+	ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
+					   req->nr_buffers, &op, &do_reloc);
+	if (ret)
+		goto out;
+
+	/* Apply any relocations that are required */
+	if (do_reloc) {
+		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers,
+						      bo, req->nr_relocs,
+						      req->relocs,
+						      req->nr_dwords, 0,
+						      pushbuf, false);
+		if (ret)
+			goto out;
+	}
+
+	/* Emit push buffer to the hw
+	 */
+	ret = RING_SPACE(chan, req->nr_dwords);
+	if (ret)
+		goto out;
+
+	OUT_RINGp(chan, pushbuf, req->nr_dwords);
+
+	ret = nouveau_fence_new(chan, &fence, true);
+	if (ret) {
+		NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
+		WIND_RING(chan);
+		goto out;
+	}
+
+	if (nouveau_gem_pushbuf_sync(chan)) {
+		ret = nouveau_fence_wait(fence, NULL, false, false);
+		if (ret) {
+			for (i = 0; i < req->nr_dwords; i++)
+				NV_ERROR(dev, "0x%08x\n", pushbuf[i]);
+			NV_ERROR(dev, "^^ above push buffer is fail :(\n");
+		}
+	}
+
+out:
+	validate_fini(&op, fence);
+	nouveau_fence_unref((void**)&fence);
+	mutex_unlock(&dev->struct_mutex);
+	kfree(pushbuf);
+	kfree(bo);
+	return ret;
+}
+
+#define PUSHBUF_CAL (dev_priv->card_type >= NV_20)
+
+int
+nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data,
+			       struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_pushbuf_call *req = data;
+	struct drm_nouveau_gem_pushbuf_bo *bo = NULL;
+	struct nouveau_channel *chan;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *pbbo;
+	struct validate_op op;
+	struct nouveau_fence* fence = 0;
+	int i, ret = 0, do_reloc = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
+
+	if (unlikely(req->handle == 0))
+		goto out_next;
+
+	if (req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS ||
+	    req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) {
+		NV_ERROR(dev, "Pushbuf config exceeds limits:\n");
+		NV_ERROR(dev, "  buffers: %d max %d\n", req->nr_buffers,
+			 NOUVEAU_GEM_MAX_BUFFERS);
+		NV_ERROR(dev, "  relocs : %d max %d\n", req->nr_relocs,
+			 NOUVEAU_GEM_MAX_RELOCS);
+		return -EINVAL;
+	}
+
+	bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
+	if (IS_ERR(bo))
+		return PTR_ERR(bo);
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* Validate buffer list */
+	ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
+					   req->nr_buffers, &op, &do_reloc);
+	if (ret) {
+		NV_ERROR(dev, "validate: %d\n", ret);
+		goto out;
+	}
+
+	/* Validate DMA push buffer */
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem) {
+		NV_ERROR(dev, "Unknown pb handle 0x%08x\n", req->handle);
+		ret = -EINVAL;
+		goto out;
+	}
+	pbbo = nouveau_gem_object(gem);
+
+	if ((req->offset & 3) || req->nr_dwords < 2 ||
+	    (unsigned long)req->offset > (unsigned long)pbbo->bo.mem.size ||
+	    (unsigned long)req->nr_dwords >
+	     ((unsigned long)(pbbo->bo.mem.size - req->offset ) >> 2)) {
+		NV_ERROR(dev, "pb call misaligned or out of bounds: "
+			      "%d + %d * 4 > %ld\n",
+			 req->offset, req->nr_dwords, pbbo->bo.mem.size);
+		ret = -EINVAL;
+		drm_gem_object_unreference(gem);
+		goto out;
+	}
+
+	ret = ttm_bo_reserve(&pbbo->bo, false, false, true,
+			     chan->fence.sequence);
+	if (ret) {
+		NV_ERROR(dev, "resv pb: %d\n", ret);
+		drm_gem_object_unreference(gem);
+		goto out;
+	}
+
+	nouveau_bo_placement_set(pbbo, 1 << chan->pushbuf_bo->bo.mem.mem_type);
+	ret = ttm_bo_validate(&pbbo->bo, &pbbo->placement, false, false);
+	if (ret) {
+		NV_ERROR(dev, "validate pb: %d\n", ret);
+		ttm_bo_unreserve(&pbbo->bo);
+		drm_gem_object_unreference(gem);
+		goto out;
+	}
+
+	list_add_tail(&pbbo->entry, &op.both_list);
+
+	/* If presumed return address doesn't match, we need to map the
+	 * push buffer and fix it..
+	 */
+	if (!PUSHBUF_CAL) {
+		uint32_t retaddy;
+
+		if (chan->dma.free < 4 + NOUVEAU_DMA_SKIPS) {
+			ret = nouveau_dma_wait(chan, 4 + NOUVEAU_DMA_SKIPS);
+			if (ret) {
+				NV_ERROR(dev, "jmp_space: %d\n", ret);
+				goto out;
+			}
+		}
+
+		retaddy  = chan->pushbuf_base + ((chan->dma.cur + 2) << 2);
+		retaddy |= 0x20000000;
+		if (retaddy != req->suffix0) {
+			req->suffix0 = retaddy;
+			do_reloc = 1;
+		}
+	}
+
+	/* Apply any relocations that are required */
+	if (do_reloc) {
+		void *pbvirt;
+		bool is_iomem;
+		ret = ttm_bo_kmap(&pbbo->bo, 0, pbbo->bo.mem.num_pages,
+				  &pbbo->kmap);
+		if (ret) {
+			NV_ERROR(dev, "kmap pb: %d\n", ret);
+			goto out;
+		}
+
+		pbvirt = ttm_kmap_obj_virtual(&pbbo->kmap, &is_iomem);
+		ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, bo,
+						      req->nr_relocs,
+						      req->relocs,
+						      req->nr_dwords,
+						      req->offset / 4,
+						      pbvirt, is_iomem);
+
+		if (!PUSHBUF_CAL) {
+			nouveau_bo_wr32(pbbo,
+					req->offset / 4 + req->nr_dwords - 2,
+					req->suffix0);
+		}
+
+		ttm_bo_kunmap(&pbbo->kmap);
+		if (ret) {
+			NV_ERROR(dev, "reloc apply: %d\n", ret);
+			goto out;
+		}
+	}
+
+	if (PUSHBUF_CAL) {
+		ret = RING_SPACE(chan, 2);
+		if (ret) {
+			NV_ERROR(dev, "cal_space: %d\n", ret);
+			goto out;
+		}
+		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
+				  req->offset) | 2);
+		OUT_RING(chan, 0);
+	} else {
+		ret = RING_SPACE(chan, 2 + NOUVEAU_DMA_SKIPS);
+		if (ret) {
+			NV_ERROR(dev, "jmp_space: %d\n", ret);
+			goto out;
+		}
+		OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) +
+				  req->offset) | 0x20000000);
+		OUT_RING(chan, 0);
+
+		/* Space the jumps apart with NOPs. */
+		for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+			OUT_RING(chan, 0);
+	}
+
+	ret = nouveau_fence_new(chan, &fence, true);
+	if (ret) {
+		NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
+		WIND_RING(chan);
+		goto out;
+	}
+
+out:
+	validate_fini(&op, fence);
+	nouveau_fence_unref((void**)&fence);
+	mutex_unlock(&dev->struct_mutex);
+	kfree(bo);
+
+out_next:
+	if (PUSHBUF_CAL) {
+		req->suffix0 = 0x00020000;
+		req->suffix1 = 0x00000000;
+	} else {
+		req->suffix0 = 0x20000000 |
+			      (chan->pushbuf_base + ((chan->dma.cur + 2) << 2));
+		req->suffix1 = 0x00000000;
+	}
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_pushbuf_call2(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_gem_pushbuf_call *req = data;
+
+	req->vram_available = dev_priv->fb_aper_free;
+	req->gart_available = dev_priv->gart_info.aper_free;
+
+	return nouveau_gem_ioctl_pushbuf_call(dev, data, file_priv);
+}
+
+static inline uint32_t
+domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain)
+{
+	uint32_t flags = 0;
+
+	if (domain & NOUVEAU_GEM_DOMAIN_VRAM)
+		flags |= TTM_PL_FLAG_VRAM;
+	if (domain & NOUVEAU_GEM_DOMAIN_GART)
+		flags |= TTM_PL_FLAG_TT;
+
+	return flags;
+}
+
+int
+nouveau_gem_ioctl_pin(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pin *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	int ret = 0;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		NV_ERROR(dev, "pin only allowed without kernel modesetting\n");
+		return -EINVAL;
+	}
+
+	if (!DRM_SUSER(DRM_CURPROC))
+		return -EPERM;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+	nvbo = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_pin(nvbo, domain_to_ttm(nvbo, req->domain));
+	if (ret)
+		goto out;
+
+	req->offset = nvbo->bo.offset;
+	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+		req->domain = NOUVEAU_GEM_DOMAIN_GART;
+	else
+		req->domain = NOUVEAU_GEM_DOMAIN_VRAM;
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_pin *req = data;
+	struct drm_gem_object *gem;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+
+	ret = nouveau_bo_unpin(nouveau_gem_object(gem));
+
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_cpu_prep *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
+	int ret = -EINVAL;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return ret;
+	nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->cpu_filp) {
+		if (nvbo->cpu_filp == file_priv)
+			goto out;
+
+		ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait);
+		if (ret)
+			goto out;
+	}
+
+	if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) {
+		spin_lock(&nvbo->bo.lock);
+		ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait);
+		spin_unlock(&nvbo->bo.lock);
+	} else {
+		ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait);
+		if (ret == 0)
+			nvbo->cpu_filp = file_priv;
+	}
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_cpu_prep *req = data;
+	struct drm_gem_object *gem;
+	struct nouveau_bo *nvbo;
+	int ret = -EINVAL;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return ret;
+	nvbo = nouveau_gem_object(gem);
+
+	if (nvbo->cpu_filp != file_priv)
+		goto out;
+	nvbo->cpu_filp = NULL;
+
+	ttm_bo_synccpu_write_release(&nvbo->bo);
+	ret = 0;
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_nouveau_gem_info *req = data;
+	struct drm_gem_object *gem;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
+	if (!gem)
+		return -EINVAL;
+
+	ret = nouveau_gem_info(gem, req);
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.c	2013-05-03 12:03:17.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2009 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 <linux/firmware.h>
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+struct nouveau_ctxprog {
+	uint32_t signature;
+	uint8_t  version;
+	uint16_t length;
+	uint32_t data[];
+} __attribute__ ((packed));
+
+struct nouveau_ctxvals {
+	uint32_t signature;
+	uint8_t  version;
+	uint32_t length;
+	struct {
+		uint32_t offset;
+		uint32_t value;
+	} data[];
+} __attribute__ ((packed));
+
+int
+nouveau_grctx_prog_load(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	const int chipset = dev_priv->chipset;
+	const struct firmware *fw;
+	const struct nouveau_ctxprog *cp;
+	const struct nouveau_ctxvals *cv;
+	char name[32];
+	int ret, i;
+
+	if (pgraph->accel_blocked)
+		return -ENODEV;
+
+	if (!pgraph->ctxprog) {
+		sprintf(name, "/*(DEBLOBBED)*/", chipset);
+		ret = reject_firmware(&fw, name, &dev->pdev->dev);
+		if (ret) {
+			NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
+			return ret;
+		}
+
+		pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL);
+		if (!pgraph->ctxprog) {
+			NV_ERROR(dev, "OOM copying ctxprog\n");
+			release_firmware(fw);
+			return -ENOMEM;
+		}
+		memcpy(pgraph->ctxprog, fw->data, fw->size);
+
+		cp = pgraph->ctxprog;
+		if (le32_to_cpu(cp->signature) != 0x5043564e ||
+		    cp->version != 0 ||
+		    le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
+			NV_ERROR(dev, "ctxprog invalid\n");
+			release_firmware(fw);
+			nouveau_grctx_fini(dev);
+			return -EINVAL;
+		}
+		release_firmware(fw);
+	}
+
+	if (!pgraph->ctxvals) {
+		sprintf(name, "/*(DEBLOBBED)*/", chipset);
+		ret = reject_firmware(&fw, name, &dev->pdev->dev);
+		if (ret) {
+			NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
+			nouveau_grctx_fini(dev);
+			return ret;
+		}
+
+		pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL);
+		if (!pgraph->ctxvals) {
+			NV_ERROR(dev, "OOM copying ctxvals\n");
+			release_firmware(fw);
+			nouveau_grctx_fini(dev);
+			return -ENOMEM;
+		}
+		memcpy(pgraph->ctxvals, fw->data, fw->size);
+
+		cv = (void *)pgraph->ctxvals;
+		if (le32_to_cpu(cv->signature) != 0x5643564e ||
+		    cv->version != 0 ||
+		    le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
+			NV_ERROR(dev, "ctxvals invalid\n");
+			release_firmware(fw);
+			nouveau_grctx_fini(dev);
+			return -EINVAL;
+		}
+		release_firmware(fw);
+	}
+
+	cp = pgraph->ctxprog;
+
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+	for (i = 0; i < le16_to_cpu(cp->length); i++)
+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
+			le32_to_cpu(cp->data[i]));
+
+	return 0;
+}
+
+void
+nouveau_grctx_fini(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+
+	if (pgraph->ctxprog) {
+		kfree(pgraph->ctxprog);
+		pgraph->ctxprog = NULL;
+	}
+
+	if (pgraph->ctxvals) {
+		kfree(pgraph->ctxprog);
+		pgraph->ctxvals = NULL;
+	}
+}
+
+void
+nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_ctxvals *cv = pgraph->ctxvals;
+	int i;
+
+	if (!cv)
+		return;
+
+	for (i = 0; i < le32_to_cpu(cv->length); i++)
+		nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
+			le32_to_cpu(cv->data[i].value));
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_grctx.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,133 @@
+#ifndef __NOUVEAU_GRCTX_H__
+#define __NOUVEAU_GRCTX_H__
+
+struct nouveau_grctx {
+	struct drm_device *dev;
+
+	enum {
+		NOUVEAU_GRCTX_PROG,
+		NOUVEAU_GRCTX_VALS
+	} mode;
+	void *data;
+
+	uint32_t ctxprog_max;
+	uint32_t ctxprog_len;
+	uint32_t ctxprog_reg;
+	int      ctxprog_label[32];
+	uint32_t ctxvals_pos;
+	uint32_t ctxvals_base;
+};
+
+#ifdef CP_CTX
+static inline void
+cp_out(struct nouveau_grctx *ctx, uint32_t inst)
+{
+	uint32_t *ctxprog = ctx->data;
+
+	if (ctx->mode != NOUVEAU_GRCTX_PROG)
+		return;
+
+	BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
+	ctxprog[ctx->ctxprog_len++] = inst;
+}
+
+static inline void
+cp_lsr(struct nouveau_grctx *ctx, uint32_t val)
+{
+	cp_out(ctx, CP_LOAD_SR | val);
+}
+
+static inline void
+cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length)
+{
+	ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
+
+	ctx->ctxvals_base = ctx->ctxvals_pos;
+	ctx->ctxvals_pos = ctx->ctxvals_base + length;
+
+	if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
+		cp_lsr(ctx, length);
+		length = 0;
+	}
+
+	cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
+}
+
+static inline void
+cp_name(struct nouveau_grctx *ctx, int name)
+{
+	uint32_t *ctxprog = ctx->data;
+	int i;
+
+	if (ctx->mode != NOUVEAU_GRCTX_PROG)
+		return;
+
+	ctx->ctxprog_label[name] = ctx->ctxprog_len;
+	for (i = 0; i < ctx->ctxprog_len; i++) {
+		if ((ctxprog[i] & 0xfff00000) != 0xff400000)
+			continue;
+		if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
+			continue;
+		ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
+			     (ctx->ctxprog_len << CP_BRA_IP_SHIFT);
+	}
+}
+
+static inline void
+_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
+{
+	int ip = 0;
+
+	if (mod != 2) {
+		ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
+		if (ip == 0)
+			ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
+	}
+
+	cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
+		    (state ? 0 : CP_BRA_IF_CLEAR));
+}
+#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
+#ifdef CP_BRA_MOD
+#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
+#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
+#endif
+
+static inline void
+_cp_wait(struct nouveau_grctx *ctx, int flag, int state)
+{
+	cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
+}
+#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
+
+static inline void
+_cp_set(struct nouveau_grctx *ctx, int flag, int state)
+{
+	cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
+}
+#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
+
+static inline void
+cp_pos(struct nouveau_grctx *ctx, int offset)
+{
+	ctx->ctxvals_pos = offset;
+	ctx->ctxvals_base = ctx->ctxvals_pos;
+
+	cp_lsr(ctx, ctx->ctxvals_pos);
+	cp_out(ctx, CP_SET_CONTEXT_POINTER);
+}
+
+static inline void
+gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val)
+{
+	if (ctx->mode != NOUVEAU_GRCTX_VALS)
+		return;
+
+	reg = (reg - 0x00400000) / 4;
+	reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
+
+	nv_wo32(ctx->dev, ctx->data, reg, val);
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1080 @@
+/*
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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 "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+#define CHIPSET_NFORCE 0x01a0
+#define CHIPSET_NFORCE2 0x01f0
+
+/*
+ * misc hw access wrappers/control functions
+ */
+
+void
+NVWriteVgaSeq(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index);
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SR, value);
+}
+
+uint8_t
+NVReadVgaSeq(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index);
+	return NVReadPRMVIO(dev, head, NV_PRMVIO_SR);
+}
+
+void
+NVWriteVgaGr(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index);
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GX, value);
+}
+
+uint8_t
+NVReadVgaGr(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index);
+	return NVReadPRMVIO(dev, head, NV_PRMVIO_GX);
+}
+
+/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
+ * it affects only the 8 bit vga io regs, which we access using mmio at
+ * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
+ * in general, the set value of cr44 does not matter: reg access works as
+ * expected and values can be set for the appropriate head by using a 0x2000
+ * offset as required
+ * however:
+ * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
+ *    cr44 must be set to 0 or 3 for accessing values on the correct head
+ *    through the common 0xc03c* addresses
+ * b) in tied mode (4) head B is programmed to the values set on head A, and
+ *    access using the head B addresses can have strange results, ergo we leave
+ *    tied mode in init once we know to what cr44 should be restored on exit
+ *
+ * the owner parameter is slightly abused:
+ * 0 and 1 are treated as head values and so the set value is (owner * 3)
+ * other values are treated as literal values to set
+ */
+void
+NVSetOwner(struct drm_device *dev, int owner)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (owner == 1)
+		owner *= 3;
+
+	if (dev_priv->chipset == 0x11) {
+		/* This might seem stupid, but the blob does it and
+		 * omitting it often locks the system up.
+		 */
+		NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
+		NVReadVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX);
+	}
+
+	/* CR44 is always changed on CRTC0 */
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner);
+
+	if (dev_priv->chipset == 0x11) {	/* set me harder */
+		NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
+		NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
+	}
+}
+
+void
+NVBlankScreen(struct drm_device *dev, int head, bool blank)
+{
+	unsigned char seq1;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, head);
+
+	seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX);
+
+	NVVgaSeqReset(dev, head, true);
+	if (blank)
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
+	else
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);
+	NVVgaSeqReset(dev, head, false);
+}
+
+/*
+ * PLL setting
+ */
+
+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 NV_RAMDAC_VPLL2:
+		shift += 4;
+	case NV_PRAMDAC_VPLL_COEFF:
+		shift += 4;
+	case NV_PRAMDAC_MPLL_COEFF:
+		shift += 4;
+	case NV_PRAMDAC_NVPLL_COEFF:
+		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 drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	uint32_t oldpll = NVReadRAMDAC(dev, 0, 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 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
+			(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 */
+		NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff));
+	else
+		/* downclock -- write new NM first */
+		NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1);
+
+	if (chip_version < 0x17 && chip_version != 0x11)
+		/* wait a bit on older chips */
+		msleep(64);
+	NVReadRAMDAC(dev, 0, reg);
+
+	/* then write the other half as well */
+	NVWriteRAMDAC(dev, 0, reg, pll);
+
+	if (shift_powerctrl_1 >= 0)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
+}
+
+static uint32_t
+new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
+{
+	bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF);
+
+	if (ss)	/* single stage pll mode */
+		ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE :
+				      NV_RAMDAC_580_VPLL2_ACTIVE;
+	else
+		ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE :
+				      ~NV_RAMDAC_580_VPLL2_ACTIVE;
+
+	return ramdac580;
+}
+
+static void
+setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
+		       struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chip_version = dev_priv->vbios->chip_version;
+	bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
+	uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
+	uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
+	uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, 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 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */
+		oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
+		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 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
+			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+			1 << shift_powerctrl_1);
+	}
+
+	if (chip_version >= 0x40) {
+		int shift_c040 = 14;
+
+		switch (reg1) {
+		case NV_PRAMDAC_MPLL_COEFF:
+			shift_c040 += 2;
+		case NV_PRAMDAC_NVPLL_COEFF:
+			shift_c040 += 2;
+		case NV_RAMDAC_VPLL2:
+			shift_c040 += 2;
+		case NV_PRAMDAC_VPLL_COEFF:
+			shift_c040 += 2;
+		}
+
+		savedc040 = nvReadMC(dev, 0xc040);
+		if (shift_c040 != 14)
+			nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040));
+	}
+
+	if (oldramdac580 != ramdac580)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580);
+
+	if (!nv3035)
+		NVWriteRAMDAC(dev, 0, reg2, pll2);
+	NVWriteRAMDAC(dev, 0, reg1, pll1);
+
+	if (shift_powerctrl_1 >= 0)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
+	if (chip_version >= 0x40)
+		nvWriteMC(dev, 0xc040, savedc040);
+}
+
+static void
+setPLL_double_lowregs(struct drm_device *dev, uint32_t 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 = nvReadMC(dev, Preg);
+	uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
+	uint32_t Pval = (oldPval & (mpll ? ~(0x11 << 16) : ~(1 << 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 (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
+		return;
+
+	if (Preg == 0x4000)
+		maskc040 = ~0x333;
+	if (Preg == 0x4058)
+		maskc040 = ~(0xc << 24);
+
+	if (mpll) {
+		struct pll_lims pll_lim;
+		uint8_t Pval2;
+
+		if (get_pll_limits(dev, Preg, &pll_lim))
+			return;
+
+		Pval2 = pv->log2P + pll_lim.log2p_bias;
+		if (Pval2 > pll_lim.max_log2p)
+			Pval2 = pll_lim.max_log2p;
+		Pval |= 1 << 28 | Pval2 << 20;
+
+		saved4600 = nvReadMC(dev, 0x4600);
+		nvWriteMC(dev, 0x4600, saved4600 | 8 << 28);
+	}
+	if (single_stage)
+		Pval |= mpll ? 1 << 12 : 1 << 8;
+
+	nvWriteMC(dev, Preg, oldPval | 1 << 28);
+	nvWriteMC(dev, Preg, Pval & ~(4 << 28));
+	if (mpll) {
+		Pval |= 8 << 20;
+		nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28));
+		nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28));
+	}
+
+	savedc040 = nvReadMC(dev, 0xc040);
+	nvWriteMC(dev, 0xc040, savedc040 & maskc040);
+
+	nvWriteMC(dev, NMNMreg, NMNM);
+	if (NMNMreg == 0x4024)
+		nvWriteMC(dev, 0x403c, NMNM);
+
+	nvWriteMC(dev, Preg, Pval);
+	if (mpll) {
+		Pval &= ~(8 << 20);
+		nvWriteMC(dev, 0x4020, Pval);
+		nvWriteMC(dev, 0x4038, Pval);
+		nvWriteMC(dev, 0x4600, saved4600);
+	}
+
+	nvWriteMC(dev, 0xc040, savedc040);
+
+	if (mpll) {
+		nvWriteMC(dev, 0x4020, Pval & ~(1 << 28));
+		nvWriteMC(dev, 0x4038, Pval & ~(1 << 28));
+	}
+}
+
+void
+nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
+		  struct nouveau_pll_vals *pv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int cv = dev_priv->vbios->chip_version;
+
+	if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+	    cv >= 0x40) {
+		if (reg1 > 0x405c)
+			setPLL_double_highregs(dev, reg1, pv);
+		else
+			setPLL_double_lowregs(dev, reg1, pv);
+	} else
+		setPLL_single(dev, reg1, pv);
+}
+
+/*
+ * PLL getting
+ */
+
+static void
+nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
+		      uint32_t pll2, struct nouveau_pll_vals *pllvals)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */
+
+	/* log2P is & 0x7 as never more than 7, and nv30/35 only uses 3 bits */
+	pllvals->log2P = (pll1 >> 16) & 0x7;
+	pllvals->N2 = pllvals->M2 = 1;
+
+	if (reg1 <= 0x405c) {
+		pllvals->NM1 = pll2 & 0xffff;
+		/* single stage NVPLL and VPLLs use 1 << 8, MPLL uses 1 << 12 */
+		if (!(pll1 & 0x1100))
+			pllvals->NM2 = pll2 >> 16;
+	} else {
+		pllvals->NM1 = pll1 & 0xffff;
+		if (nv_two_reg_pll(dev) && pll2 & NV31_RAMDAC_ENABLE_VCO2)
+			pllvals->NM2 = pll2 & 0xffff;
+		else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 0x35) {
+			pllvals->M1 &= 0xf; /* only 4 bits */
+			if (pll1 & NV30_RAMDAC_ENABLE_VCO2) {
+				pllvals->M2 = (pll1 >> 4) & 0x7;
+				pllvals->N2 = ((pll1 >> 21) & 0x18) |
+					      ((pll1 >> 19) & 0x7);
+			}
+		}
+	}
+}
+
+int
+nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype,
+		       struct nouveau_pll_vals *pllvals)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_PRAMDAC_NVPLL_COEFF,
+						    NV_PRAMDAC_MPLL_COEFF,
+						    NV_PRAMDAC_VPLL_COEFF,
+						    NV_RAMDAC_VPLL2 };
+	const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000,
+						    0x4020,
+						    NV_PRAMDAC_VPLL_COEFF,
+						    NV_RAMDAC_VPLL2 };
+	uint32_t reg1, pll1, pll2 = 0;
+	struct pll_lims pll_lim;
+	int ret;
+
+	if (dev_priv->card_type < NV_40)
+		reg1 = nv04_regs[plltype];
+	else
+		reg1 = nv40_regs[plltype];
+
+	pll1 = nvReadMC(dev, reg1);
+
+	if (reg1 <= 0x405c)
+		pll2 = nvReadMC(dev, reg1 + 4);
+	else if (nv_two_reg_pll(dev)) {
+		uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70);
+
+		pll2 = nvReadMC(dev, reg2);
+	}
+
+	if (dev_priv->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) {
+		uint32_t ramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
+
+		/* check whether vpll has been forced into single stage mode */
+		if (reg1 == NV_PRAMDAC_VPLL_COEFF) {
+			if (ramdac580 & NV_RAMDAC_580_VPLL1_ACTIVE)
+				pll2 = 0;
+		} else
+			if (ramdac580 & NV_RAMDAC_580_VPLL2_ACTIVE)
+				pll2 = 0;
+	}
+
+	nouveau_hw_decode_pll(dev, reg1, pll1, pll2, pllvals);
+
+	ret = get_pll_limits(dev, plltype, &pll_lim);
+	if (ret)
+		return ret;
+
+	pllvals->refclk = pll_lim.refclk;
+
+	return 0;
+}
+
+int
+nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
+{
+	/* Avoid divide by zero if called at an inappropriate time */
+	if (!pv->M1 || !pv->M2)
+		return 0;
+
+	return pv->N1 * pv->N2 * pv->refclk / (pv->M1 * pv->M2) >> pv->log2P;
+}
+
+int
+nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype)
+{
+	struct nouveau_pll_vals pllvals;
+
+	if (plltype == MPLL && (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) {
+		uint32_t mpllP;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
+		if (!mpllP)
+			mpllP = 4;
+
+		return 400000 / mpllP;
+	} else
+	if (plltype == MPLL && (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) {
+		uint32_t clock;
+
+		pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
+		return clock;
+	}
+
+	nouveau_hw_get_pllvals(dev, plltype, &pllvals);
+
+	return nouveau_hw_pllvals_to_clk(&pllvals);
+}
+
+static void
+nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
+{
+	/* the vpll on an unused head can come up with a random value, way
+	 * beyond the pll limits.  for some reason this causes the chip to
+	 * lock up when reading the dac palette regs, so set a valid pll here
+	 * when such a condition detected.  only seen on nv11 to date
+	 */
+
+	struct pll_lims pll_lim;
+	struct nouveau_pll_vals pv;
+	uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+
+	if (get_pll_limits(dev, head ? VPLL2 : VPLL1, &pll_lim))
+		return;
+	nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &pv);
+
+	if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
+	    pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
+	    pv.log2P <= pll_lim.max_log2p)
+		return;
+
+	NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1);
+
+	/* set lowest clock within static limits */
+	pv.M1 = pll_lim.vco1.max_m;
+	pv.N1 = pll_lim.vco1.min_n;
+	pv.log2P = pll_lim.max_usable_log2p;
+	nouveau_hw_setpll(dev, pllreg, &pv);
+}
+
+/*
+ * vga font save/restore
+ */
+
+static void nouveau_vga_font_io(struct drm_device *dev,
+				void __iomem *iovram,
+				bool save, unsigned plane)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned i;
+
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane);
+	for (i = 0; i < 16384; i++) {
+		if (save) {
+			dev_priv->saved_vga_font[plane][i] =
+					ioread32_native(iovram + i * 4);
+		} else {
+			iowrite32_native(dev_priv->saved_vga_font[plane][i],
+							iovram + i * 4);
+		}
+	}
+}
+
+void
+nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
+{
+	uint8_t misc, gr4, gr5, gr6, seq2, seq4;
+	bool graphicsmode;
+	unsigned plane;
+	void __iomem *iovram;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, 0);
+
+	NVSetEnablePalette(dev, 0, true);
+	graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1;
+	NVSetEnablePalette(dev, 0, false);
+
+	if (graphicsmode) /* graphics mode => framebuffer => no need to save */
+		return;
+
+	NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor");
+
+	/* map first 64KiB of VRAM, holds VGA fonts etc */
+	iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536);
+	if (!iovram) {
+		NV_ERROR(dev, "Failed to map VRAM, "
+					"cannot save/restore VGA fonts.\n");
+		return;
+	}
+
+	if (nv_two_heads(dev))
+		NVBlankScreen(dev, 1, true);
+	NVBlankScreen(dev, 0, true);
+
+	/* save control regs */
+	misc = NVReadPRMVIO(dev, 0, NV_PRMVIO_MISC__READ);
+	seq2 = NVReadVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX);
+	seq4 = NVReadVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX);
+	gr4 = NVReadVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX);
+	gr5 = NVReadVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX);
+	gr6 = NVReadVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX);
+
+	NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, 0x67);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5);
+
+	/* store font in planes 0..3 */
+	for (plane = 0; plane < 4; plane++)
+		nouveau_vga_font_io(dev, iovram, save, plane);
+
+	/* restore control regs */
+	NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, gr4);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, gr5);
+	NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, gr6);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4);
+
+	if (nv_two_heads(dev))
+		NVBlankScreen(dev, 1, false);
+	NVBlankScreen(dev, 0, false);
+
+	iounmap(iovram);
+}
+
+/*
+ * mode state save/load
+ */
+
+static void
+rd_cio_state(struct drm_device *dev, int head,
+	     struct nv04_crtc_reg *crtcstate, int index)
+{
+	crtcstate->CRTC[index] = NVReadVgaCrtc(dev, head, index);
+}
+
+static void
+wr_cio_state(struct drm_device *dev, int head,
+	     struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(dev, head, index, crtcstate->CRTC[index]);
+}
+
+static void
+nv_save_state_ramdac(struct drm_device *dev, int head,
+		     struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	if (dev_priv->card_type >= NV_10)
+		regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC);
+
+	nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, &regp->pllvals);
+	state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT);
+	if (nv_two_heads(dev))
+		state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
+	if (dev_priv->chipset == 0x11)
+		regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11);
+
+	regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL);
+
+	if (nv_gf4_disp_arch(dev))
+		regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630);
+	if (dev_priv->chipset >= 0x30)
+		regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634);
+
+	regp->tv_setup = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP);
+	regp->tv_vtotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL);
+	regp->tv_vskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW);
+	regp->tv_vsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY);
+	regp->tv_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL);
+	regp->tv_hskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW);
+	regp->tv_hsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY);
+	regp->tv_hsync_delay2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2);
+
+	for (i = 0; i < 7; i++) {
+		uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
+		regp->fp_vert_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg);
+		regp->fp_horiz_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg + 0x20);
+	}
+
+	if (nv_gf4_disp_arch(dev)) {
+		regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_FP_DITHER);
+		for (i = 0; i < 3; i++) {
+			regp->dither_regs[i] = NVReadRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4);
+			regp->dither_regs[i + 3] = NVReadRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4);
+		}
+	}
+
+	regp->fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
+	regp->fp_debug_0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0);
+	if (!nv_gf4_disp_arch(dev) && head == 0) {
+		/* early chips don't allow access to PRAMDAC_TMDS_* without
+		 * the head A FPCLK on (nv11 even locks up) */
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0 &
+			      ~NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK);
+	}
+	regp->fp_debug_1 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1);
+	regp->fp_debug_2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2);
+
+	regp->fp_margin_color = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR);
+
+	if (nv_gf4_disp_arch(dev))
+		regp->ramdac_8c0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_8C0);
+
+	if (dev_priv->card_type == NV_40) {
+		regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20);
+		regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24);
+		regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34);
+
+		for (i = 0; i < 38; i++)
+			regp->ctv_regs[i] = NVReadRAMDAC(dev, head,
+							 NV_PRAMDAC_CTV + 4*i);
+	}
+}
+
+static void
+nv_load_state_ramdac(struct drm_device *dev, int head,
+		     struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+	int i;
+
+	if (dev_priv->card_type >= NV_10)
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
+
+	nouveau_hw_setpll(dev, pllreg, &regp->pllvals);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
+	if (nv_two_heads(dev))
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk);
+	if (dev_priv->chipset == 0x11)
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl);
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630);
+	if (dev_priv->chipset >= 0x30)
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, regp->tv_setup);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL, regp->tv_vtotal);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW, regp->tv_vskew);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY, regp->tv_vsync_delay);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL, regp->tv_htotal);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW, regp->tv_hskew);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY, regp->tv_hsync_delay);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2, regp->tv_hsync_delay2);
+
+	for (i = 0; i < 7; i++) {
+		uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
+
+		NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_vert_regs[i]);
+		NVWriteRAMDAC(dev, head, ramdac_reg + 0x20, regp->fp_horiz_regs[i]);
+	}
+
+	if (nv_gf4_disp_arch(dev)) {
+		NVWriteRAMDAC(dev, head, NV_RAMDAC_FP_DITHER, regp->dither);
+		for (i = 0; i < 3; i++) {
+			NVWriteRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]);
+			NVWriteRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]);
+		}
+	}
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR, regp->fp_margin_color);
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_8C0, regp->ramdac_8c0);
+
+	if (dev_priv->card_type == NV_40) {
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20);
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24);
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34);
+
+		for (i = 0; i < 38; i++)
+			NVWriteRAMDAC(dev, head,
+				      NV_PRAMDAC_CTV + 4*i, regp->ctv_regs[i]);
+	}
+}
+
+static void
+nv_save_state_vga(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	regp->MiscOutReg = NVReadPRMVIO(dev, head, NV_PRMVIO_MISC__READ);
+
+	for (i = 0; i < 25; i++)
+		rd_cio_state(dev, head, regp, i);
+
+	NVSetEnablePalette(dev, head, true);
+	for (i = 0; i < 21; i++)
+		regp->Attribute[i] = NVReadVgaAttr(dev, head, i);
+	NVSetEnablePalette(dev, head, false);
+
+	for (i = 0; i < 9; i++)
+		regp->Graphics[i] = NVReadVgaGr(dev, head, i);
+
+	for (i = 0; i < 5; i++)
+		regp->Sequencer[i] = NVReadVgaSeq(dev, head, i);
+}
+
+static void
+nv_load_state_vga(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	NVWritePRMVIO(dev, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg);
+
+	for (i = 0; i < 5; i++)
+		NVWriteVgaSeq(dev, head, i, regp->Sequencer[i]);
+
+	nv_lock_vga_crtc_base(dev, head, false);
+	for (i = 0; i < 25; i++)
+		wr_cio_state(dev, head, regp, i);
+	nv_lock_vga_crtc_base(dev, head, true);
+
+	for (i = 0; i < 9; i++)
+		NVWriteVgaGr(dev, head, i, regp->Graphics[i]);
+
+	NVSetEnablePalette(dev, head, true);
+	for (i = 0; i < 21; i++)
+		NVWriteVgaAttr(dev, head, i, regp->Attribute[i]);
+	NVSetEnablePalette(dev, head, false);
+}
+
+static void
+nv_save_state_ext(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	int i;
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX);
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_21);
+	if (dev_priv->card_type >= NV_30)
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_47);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_49);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
+
+	if (dev_priv->card_type >= NV_10) {
+		regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830);
+		regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834);
+
+		if (dev_priv->card_type >= NV_30)
+			regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT);
+
+		if (dev_priv->card_type == NV_40)
+			regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850);
+
+		if (nv_two_heads(dev))
+			regp->crtc_eng_ctrl = NVReadCRTC(dev, head, NV_PCRTC_ENGINE_CTRL);
+		regp->cursor_cfg = NVReadCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG);
+	}
+
+	regp->crtc_cfg = NVReadCRTC(dev, head, NV_PCRTC_CONFIG);
+
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
+	rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
+	if (dev_priv->card_type >= NV_10) {
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_4B);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
+	}
+	/* NV11 and NV20 don't have this, they stop at 0x52. */
+	if (nv_gf4_disp_arch(dev)) {
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_53);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_54);
+
+		for (i = 0; i < 0x10; i++)
+			regp->CR58[i] = NVReadVgaCrtc5758(dev, head, i);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_59);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_5B);
+
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_85);
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_86);
+	}
+
+	regp->fb_start = NVReadCRTC(dev, head, NV_PCRTC_START);
+}
+
+static void
+nv_load_state_ext(struct drm_device *dev, int head,
+		  struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[head];
+	uint32_t reg900;
+	int i;
+
+	if (dev_priv->card_type >= NV_10) {
+		if (nv_two_heads(dev))
+			/* setting ENGINE_CTRL (EC) *must* come before
+			 * CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in
+			 * EC that should not be overwritten by writing stale EC
+			 */
+			NVWriteCRTC(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl);
+
+		nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0);
+		nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1);
+		nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+
+		NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg);
+		NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830);
+		NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834);
+
+		if (dev_priv->card_type >= NV_30)
+			NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext);
+
+		if (dev_priv->card_type == NV_40) {
+			NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850);
+
+			reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900);
+			if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC)
+				NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000);
+			else
+				NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000);
+		}
+	}
+
+	NVWriteCRTC(dev, head, NV_PCRTC_CONFIG, regp->crtc_cfg);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
+	if (dev_priv->card_type >= NV_30)
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_47);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_49);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, head);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
+
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
+	wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
+	if (dev_priv->card_type >= NV_10) {
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_4B);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
+	}
+	/* NV11 and NV20 stop at 0x52. */
+	if (nv_gf4_disp_arch(dev)) {
+		if (dev_priv->card_type == NV_10) {
+			/* Not waiting for vertical retrace before modifying
+			   CRE_53/CRE_54 causes lockups. */
+			nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
+			nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
+		}
+
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_54);
+
+		for (i = 0; i < 0x10; i++)
+			NVWriteVgaCrtc5758(dev, head, i, regp->CR58[i]);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_59);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_5B);
+
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_85);
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_86);
+	}
+
+	NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start);
+
+	/* Setting 1 on this value gives you interrupts for every vblank period. */
+	NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0);
+	NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK);
+}
+
+static void
+nv_save_state_palette(struct drm_device *dev, int head,
+		      struct nv04_mode_state *state)
+{
+	int head_offset = head * NV_PRMDIO_SIZE, i;
+
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+				NV_PRMDIO_PIXEL_MASK_MASK);
+	nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0);
+
+	for (i = 0; i < 768; i++) {
+		state->crtc_reg[head].DAC[i] = nv_rd08(dev,
+				NV_PRMDIO_PALETTE_DATA + head_offset);
+	}
+
+	NVSetEnablePalette(dev, head, false);
+}
+
+void
+nouveau_hw_load_state_palette(struct drm_device *dev, int head,
+			      struct nv04_mode_state *state)
+{
+	int head_offset = head * NV_PRMDIO_SIZE, i;
+
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+				NV_PRMDIO_PIXEL_MASK_MASK);
+	nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0);
+
+	for (i = 0; i < 768; i++) {
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA + head_offset,
+				state->crtc_reg[head].DAC[i]);
+	}
+
+	NVSetEnablePalette(dev, head, false);
+}
+
+void nouveau_hw_save_state(struct drm_device *dev, int head,
+			   struct nv04_mode_state *state)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset == 0x11)
+		/* NB: no attempt is made to restore the bad pll later on */
+		nouveau_hw_fix_bad_vpll(dev, head);
+	nv_save_state_ramdac(dev, head, state);
+	nv_save_state_vga(dev, head, state);
+	nv_save_state_palette(dev, head, state);
+	nv_save_state_ext(dev, head, state);
+}
+
+void nouveau_hw_load_state(struct drm_device *dev, int head,
+			   struct nv04_mode_state *state)
+{
+	NVVgaProtect(dev, head, true);
+	nv_load_state_ramdac(dev, head, state);
+	nv_load_state_ext(dev, head, state);
+	nouveau_hw_load_state_palette(dev, head, state);
+	nv_load_state_vga(dev, head, state);
+	NVVgaProtect(dev, head, false);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2008 Stuart Bennett
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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 __NOUVEAU_HW_H__
+#define __NOUVEAU_HW_H__
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+
+#define MASK(field) ( \
+	(0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field))
+
+#define XLATE(src, srclowbit, outfield) ( \
+	(((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield))
+
+void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value);
+uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index);
+void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value);
+uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
+void NVSetOwner(struct drm_device *, int owner);
+void NVBlankScreen(struct drm_device *, int head, bool blank);
+void nouveau_hw_setpll(struct drm_device *, uint32_t reg1,
+		       struct nouveau_pll_vals *pv);
+int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype,
+			   struct nouveau_pll_vals *pllvals);
+int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
+int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype);
+void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
+void nouveau_hw_save_state(struct drm_device *, int head,
+			   struct nv04_mode_state *state);
+void nouveau_hw_load_state(struct drm_device *, int head,
+			   struct nv04_mode_state *state);
+void nouveau_hw_load_state_palette(struct drm_device *, int head,
+				   struct nv04_mode_state *state);
+
+/* nouveau_calc.c */
+extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp,
+			     int *burst, int *lwm);
+extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim,
+				int clk, struct nouveau_pll_vals *pv);
+
+static inline uint32_t
+nvReadMC(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadVIDEO(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadFB(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t
+nvReadEXTDEV(struct drm_device *dev, uint32_t reg)
+{
+	uint32_t val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
+	return val;
+}
+
+static inline void
+nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t NVReadCRTC(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	uint32_t val;
+	if (head)
+		reg += NV_PCRTC0_SIZE;
+	val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
+	return val;
+}
+
+static inline void NVWriteCRTC(struct drm_device *dev,
+					int head, uint32_t reg, uint32_t val)
+{
+	if (head)
+		reg += NV_PCRTC0_SIZE;
+	NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t NVReadRAMDAC(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	uint32_t val;
+	if (head)
+		reg += NV_PRAMDAC0_SIZE;
+	val = nv_rd32(dev, reg);
+	NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
+							head, reg, val);
+	return val;
+}
+
+static inline void NVWriteRAMDAC(struct drm_device *dev,
+					int head, uint32_t reg, uint32_t val)
+{
+	if (head)
+		reg += NV_PRAMDAC0_SIZE;
+	NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
+							head, reg, val);
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint8_t nv_read_tmds(struct drm_device *dev,
+					int or, int dl, uint8_t address)
+{
+	int ramdac = (or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
+	NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
+	return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8);
+}
+
+static inline void nv_write_tmds(struct drm_device *dev,
+					int or, int dl, uint8_t address,
+					uint8_t data)
+{
+	int ramdac = (or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
+}
+
+static inline void NVWriteVgaCrtc(struct drm_device *dev,
+					int head, uint8_t index, uint8_t value)
+{
+	NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, value);
+	nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+	nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
+}
+
+static inline uint8_t NVReadVgaCrtc(struct drm_device *dev,
+					int head, uint8_t index)
+{
+	uint8_t val;
+	nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+	val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, val);
+	return val;
+}
+
+/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58
+ * I suspect they in fact do nothing, but are merely a way to carry useful
+ * per-head variables around
+ *
+ * Known uses:
+ * CR57		CR58
+ * 0x00		index to the appropriate dcb entry (or 7f for inactive)
+ * 0x02		dcb entry's "or" value (or 00 for inactive)
+ * 0x03		bit0 set for dual link (LVDS, possibly elsewhere too)
+ * 0x08 or 0x09	pxclk in MHz
+ * 0x0f		laptop panel info -	low nibble for PEXTDEV_BOOT_0 strap
+ * 					high nibble for xlat strap value
+ */
+
+static inline void
+NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value)
+{
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value);
+}
+
+static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index)
+{
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
+	return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58);
+}
+
+static inline uint8_t NVReadPRMVIO(struct drm_device *dev,
+					int head, uint32_t reg)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint8_t val;
+
+	/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+	 * NVSetOwner for the relevant head to be programmed */
+	if (head && dev_priv->card_type == NV_40)
+		reg += NV_PRMVIO_SIZE;
+
+	val = nv_rd08(dev, reg);
+	NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val);
+	return val;
+}
+
+static inline void NVWritePRMVIO(struct drm_device *dev,
+					int head, uint32_t reg, uint8_t value)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+	 * NVSetOwner for the relevant head to be programmed */
+	if (head && dev_priv->card_type == NV_40)
+		reg += NV_PRMVIO_SIZE;
+
+	NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n",
+						head, reg, value);
+	nv_wr08(dev, reg, value);
+}
+
+static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable)
+{
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20);
+}
+
+static inline bool NVGetEnablePalette(struct drm_device *dev, int head)
+{
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20);
+}
+
+static inline void NVWriteVgaAttr(struct drm_device *dev,
+					int head, uint8_t index, uint8_t value)
+{
+	if (NVGetEnablePalette(dev, head))
+		index &= ~0x20;
+	else
+		index |= 0x20;
+
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, value);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+	nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
+}
+
+static inline uint8_t NVReadVgaAttr(struct drm_device *dev,
+					int head, uint8_t index)
+{
+	uint8_t val;
+	if (NVGetEnablePalette(dev, head))
+		index &= ~0x20;
+	else
+		index |= 0x20;
+
+	nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+	nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+	val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
+	NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
+							head, index, val);
+	return val;
+}
+
+static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start)
+{
+	NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3);
+}
+
+static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect)
+{
+	uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX);
+
+	if (protect) {
+		NVVgaSeqReset(dev, head, true);
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
+	} else {
+		/* Reenable sequencer, then turn on screen */
+		NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);   /* reenable display */
+		NVVgaSeqReset(dev, head, false);
+	}
+	NVSetEnablePalette(dev, head, protect);
+}
+
+static inline bool
+nv_heads_tied(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset == 0x11)
+		return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28));
+
+	return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4;
+}
+
+/* makes cr0-7 on the specified head read-only */
+static inline bool
+nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock)
+{
+	uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX);
+	bool waslocked = cr11 & 0x80;
+
+	if (lock)
+		cr11 |= 0x80;
+	else
+		cr11 &= ~0x80;
+	NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11);
+
+	return waslocked;
+}
+
+static inline void
+nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock)
+{
+	/* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs
+	 * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB
+	 * bit6: seems to have some effect on CR09 (double scan, VBS_9)
+	 * bit5: unlocks HDE
+	 * bit4: unlocks VDE
+	 * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR
+	 * bit2: same as bit 1 of 0x60?804
+	 * bit0: same as bit 0 of 0x60?804
+	 */
+
+	uint8_t cr21 = lock;
+
+	if (lock < 0)
+		/* 0xfa is generic "unlock all" mask */
+		cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa;
+
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21);
+}
+
+/* renders the extended crtc regs (cr19+) on all crtcs impervious:
+ * immutable and unreadable
+ */
+static inline bool
+NVLockVgaCrtcs(struct drm_device *dev, bool lock)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
+
+	NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX,
+		       lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
+	/* NV11 has independently lockable extended crtcs, except when tied */
+	if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev))
+		NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX,
+			       lock ? NV_CIO_SR_LOCK_VALUE :
+				      NV_CIO_SR_UNLOCK_RW_VALUE);
+
+	return waslocked;
+}
+
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
+static inline void
+nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
+{
+	/* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40,
+	 * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS
+	 * for changes to the CRTC CURCTL regs to take effect, whether changing
+	 * the pixmap location, or just showing/hiding the cursor
+	 */
+	uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos);
+}
+
+static inline void
+nv_show_cursor(struct drm_device *dev, int head, bool show)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint8_t *curctl1 =
+		&dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
+
+	if (show)
+		*curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
+	else
+		*curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
+
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, head);
+}
+
+static inline uint32_t
+nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int mask;
+
+	if (bpp == 15)
+		bpp = 16;
+	if (bpp == 24)
+		bpp = 8;
+
+	/* Alignment requirements taken from the Haiku driver */
+	if (dev_priv->card_type == NV_04)
+		mask = 128 / bpp - 1;
+	else
+		mask = 512 / bpp - 1;
+
+	return (width + mask) & ~mask;
+}
+
+#endif	/* __NOUVEAU_HW_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2009 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 "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_i2c.h"
+#include "nouveau_hw.h"
+
+static void
+nv04_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
+	NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
+}
+
+static void
+nv04_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
+	NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
+}
+
+static int
+nv04_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4);
+}
+
+static int
+nv04_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8);
+}
+
+static void
+nv4e_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
+	nv_wr32(dev, i2c->wr, val | 0x01);
+}
+
+static void
+nv4e_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+	uint8_t val;
+
+	val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
+	nv_wr32(dev, i2c->wr, val | 0x01);
+}
+
+static int
+nv4e_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!((nv_rd32(dev, i2c->rd) >> 16) & 4);
+}
+
+static int
+nv4e_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
+}
+
+static int
+nv50_i2c_getscl(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(nv_rd32(dev, i2c->rd) & 1);
+}
+
+
+static int
+nv50_i2c_getsda(void *data)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	return !!(nv_rd32(dev, i2c->rd) & 2);
+}
+
+static void
+nv50_i2c_setscl(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
+}
+
+static void
+nv50_i2c_setsda(void *data, int state)
+{
+	struct nouveau_i2c_chan *i2c = data;
+	struct drm_device *dev = i2c->dev;
+
+	nv_wr32(dev, i2c->wr,
+			(nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
+	i2c->data = state;
+}
+
+static const uint32_t nv50_i2c_port[] = {
+	0x00e138, 0x00e150, 0x00e168, 0x00e180,
+	0x00e254, 0x00e274, 0x00e764, 0x00e780,
+	0x00e79c, 0x00e7b8
+};
+#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
+
+int
+nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_i2c_chan *i2c;
+	int ret;
+
+	if (entry->chan)
+		return -EEXIST;
+
+	if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) {
+		NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
+		return -EINVAL;
+	}
+
+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+	if (i2c == NULL)
+		return -ENOMEM;
+
+	switch (entry->port_type) {
+	case 0:
+		i2c->algo.bit.setsda = nv04_i2c_setsda;
+		i2c->algo.bit.setscl = nv04_i2c_setscl;
+		i2c->algo.bit.getsda = nv04_i2c_getsda;
+		i2c->algo.bit.getscl = nv04_i2c_getscl;
+		i2c->rd = entry->read;
+		i2c->wr = entry->write;
+		break;
+	case 4:
+		i2c->algo.bit.setsda = nv4e_i2c_setsda;
+		i2c->algo.bit.setscl = nv4e_i2c_setscl;
+		i2c->algo.bit.getsda = nv4e_i2c_getsda;
+		i2c->algo.bit.getscl = nv4e_i2c_getscl;
+		i2c->rd = 0x600800 + entry->read;
+		i2c->wr = 0x600800 + entry->write;
+		break;
+	case 5:
+		i2c->algo.bit.setsda = nv50_i2c_setsda;
+		i2c->algo.bit.setscl = nv50_i2c_setscl;
+		i2c->algo.bit.getsda = nv50_i2c_getsda;
+		i2c->algo.bit.getscl = nv50_i2c_getscl;
+		i2c->rd = nv50_i2c_port[entry->read];
+		i2c->wr = i2c->rd;
+		break;
+	case 6:
+		i2c->rd = entry->read;
+		i2c->wr = entry->write;
+		break;
+	default:
+		NV_ERROR(dev, "DCB I2C port type %d unknown\n",
+			 entry->port_type);
+		kfree(i2c);
+		return -EINVAL;
+	}
+
+	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+		 "nouveau-%s-%d", pci_name(dev->pdev), index);
+	i2c->adapter.owner = THIS_MODULE;
+	i2c->adapter.dev.parent = &dev->pdev->dev;
+	i2c->dev = dev;
+	i2c_set_adapdata(&i2c->adapter, i2c);
+
+	if (entry->port_type < 6) {
+		i2c->adapter.algo_data = &i2c->algo.bit;
+		i2c->algo.bit.udelay = 40;
+		i2c->algo.bit.timeout = usecs_to_jiffies(5000);
+		i2c->algo.bit.data = i2c;
+		ret = i2c_bit_add_bus(&i2c->adapter);
+	} else {
+		i2c->adapter.algo_data = &i2c->algo.dp;
+		i2c->algo.dp.running = false;
+		i2c->algo.dp.address = 0;
+		i2c->algo.dp.aux_ch = nouveau_dp_i2c_aux_ch;
+		ret = i2c_dp_aux_add_bus(&i2c->adapter);
+	}
+
+	if (ret) {
+		NV_ERROR(dev, "Failed to register i2c %d\n", index);
+		kfree(i2c);
+		return ret;
+	}
+
+	entry->chan = i2c;
+	return 0;
+}
+
+void
+nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
+{
+	if (!entry->chan)
+		return;
+
+	i2c_del_adapter(&entry->chan->adapter);
+	kfree(entry->chan);
+	entry->chan = NULL;
+}
+
+struct nouveau_i2c_chan *
+nouveau_i2c_find(struct drm_device *dev, int index)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvbios *bios = &dev_priv->VBIOS;
+
+	if (index > DCB_MAX_NUM_I2C_ENTRIES)
+		return NULL;
+
+	if (!bios->bdcb.dcb.i2c[index].chan) {
+		if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
+			return NULL;
+	}
+
+	return bios->bdcb.dcb.i2c[index].chan;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_i2c.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef __NOUVEAU_I2C_H__
+#define __NOUVEAU_I2C_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+#include "drm_dp_helper.h"
+
+struct dcb_i2c_entry;
+
+struct nouveau_i2c_chan {
+	struct i2c_adapter adapter;
+	struct drm_device *dev;
+	union {
+		struct i2c_algo_bit_data bit;
+		struct i2c_algo_dp_aux_data dp;
+	} algo;
+	unsigned rd;
+	unsigned wr;
+	unsigned data;
+};
+
+int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
+void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
+struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
+
+int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
+			  uint8_t *read_byte);
+
+#endif /* __NOUVEAU_I2C_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_ioc32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,70 @@
+/**
+ * \file mga_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the MGA DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * 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, 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 AUTHOR 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/compat.h>
+
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+#if 0
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
+		fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE];
+#endif
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp, cmd, arg);
+
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2006 Ben Skeggs.
+ *
+ * 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, 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 OWNER(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:
+ *   Ben Skeggs <darktama@iinet.net.au>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_reg.h"
+#include <linux/ratelimit.h>
+
+/* needed for hotplug irq */
+#include "nouveau_connector.h"
+#include "nv50_display.h"
+
+void
+nouveau_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* Master disable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+
+	if (dev_priv->card_type == NV_50) {
+		INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+		INIT_LIST_HEAD(&dev_priv->vbl_waiting);
+	}
+}
+
+int
+nouveau_irq_postinstall(struct drm_device *dev)
+{
+	/* Master enable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
+	return 0;
+}
+
+void
+nouveau_irq_uninstall(struct drm_device *dev)
+{
+	/* Master disable */
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+}
+
+static int
+nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_pgraph_object_method *grm;
+	struct nouveau_pgraph_object_class *grc;
+
+	grc = dev_priv->engine.graph.grclass;
+	while (grc->id) {
+		if (grc->id == class)
+			break;
+		grc++;
+	}
+
+	if (grc->id != class || !grc->methods)
+		return -ENOENT;
+
+	grm = grc->methods;
+	while (grm->id) {
+		if (grm->id == mthd)
+			return grm->exec(chan, class, mthd, data);
+		grm++;
+	}
+
+	return -ENOENT;
+}
+
+static bool
+nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	const int subc = (addr >> 13) & 0x7;
+	const int mthd = addr & 0x1ffc;
+
+	if (mthd == 0x0000) {
+		struct nouveau_gpuobj_ref *ref = NULL;
+
+		if (nouveau_gpuobj_ref_find(chan, data, &ref))
+			return false;
+
+		if (ref->gpuobj->engine != NVOBJ_ENGINE_SW)
+			return false;
+
+		chan->sw_subchannel[subc] = ref->gpuobj->class;
+		nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev,
+			NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4));
+		return true;
+	}
+
+	/* hw object */
+	if (nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE) & (1 << (subc*4)))
+		return false;
+
+	if (nouveau_call_method(chan, chan->sw_subchannel[subc], mthd, data))
+		return false;
+
+	return true;
+}
+
+static void
+nouveau_fifo_irq_handler(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	uint32_t status, reassign;
+	int cnt = 0;
+
+	reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1;
+	while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
+		struct nouveau_channel *chan = NULL;
+		uint32_t chid, get;
+
+		nv_wr32(dev, NV03_PFIFO_CACHES, 0);
+
+		chid = engine->fifo.channel_id(dev);
+		if (chid >= 0 && chid < engine->fifo.channels)
+			chan = dev_priv->fifos[chid];
+		get  = nv_rd32(dev, NV03_PFIFO_CACHE1_GET);
+
+		if (status & NV_PFIFO_INTR_CACHE_ERROR) {
+			uint32_t mthd, data;
+			int ptr;
+
+			/* NV_PFIFO_CACHE1_GET actually goes to 0xffc before
+			 * wrapping on my G80 chips, but CACHE1 isn't big
+			 * enough for this much data.. Tests show that it
+			 * wraps around to the start at GET=0x800.. No clue
+			 * as to why..
+			 */
+			ptr = (get & 0x7ff) >> 2;
+
+			if (dev_priv->card_type < NV_40) {
+				mthd = nv_rd32(dev,
+					NV04_PFIFO_CACHE1_METHOD(ptr));
+				data = nv_rd32(dev,
+					NV04_PFIFO_CACHE1_DATA(ptr));
+			} else {
+				mthd = nv_rd32(dev,
+					NV40_PFIFO_CACHE1_METHOD(ptr));
+				data = nv_rd32(dev,
+					NV40_PFIFO_CACHE1_DATA(ptr));
+			}
+
+			if (!chan || !nouveau_fifo_swmthd(chan, mthd, data)) {
+				NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d "
+					     "Mthd 0x%04x Data 0x%08x\n",
+					chid, (mthd >> 13) & 7, mthd & 0x1ffc,
+					data);
+			}
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
+			nv_wr32(dev, NV03_PFIFO_INTR_0,
+						NV_PFIFO_INTR_CACHE_ERROR);
+
+			nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
+				nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1);
+			nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
+			nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
+				nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1);
+			nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH,
+				nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
+			nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
+
+			status &= ~NV_PFIFO_INTR_CACHE_ERROR;
+		}
+
+		if (status & NV_PFIFO_INTR_DMA_PUSHER) {
+			NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d\n", chid);
+
+			status &= ~NV_PFIFO_INTR_DMA_PUSHER;
+			nv_wr32(dev, NV03_PFIFO_INTR_0,
+						NV_PFIFO_INTR_DMA_PUSHER);
+
+			nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000);
+			if (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT) != get)
+				nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET,
+								get + 4);
+		}
+
+		if (status & NV_PFIFO_INTR_SEMAPHORE) {
+			uint32_t sem;
+
+			status &= ~NV_PFIFO_INTR_SEMAPHORE;
+			nv_wr32(dev, NV03_PFIFO_INTR_0,
+				NV_PFIFO_INTR_SEMAPHORE);
+
+			sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE);
+			nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
+
+			nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
+			nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
+		}
+
+		if (status) {
+			NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
+				status, chid);
+			nv_wr32(dev, NV03_PFIFO_INTR_0, status);
+			status = 0;
+		}
+
+		nv_wr32(dev, NV03_PFIFO_CACHES, reassign);
+	}
+
+	if (status) {
+		NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt);
+		nv_wr32(dev, 0x2140, 0);
+		nv_wr32(dev, 0x140, 0);
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
+}
+
+struct nouveau_bitfield_names {
+	uint32_t mask;
+	const char *name;
+};
+
+static struct nouveau_bitfield_names nstatus_names[] =
+{
+	{ NV04_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
+	{ NV04_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
+	{ NV04_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
+	{ NV04_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" }
+};
+
+static struct nouveau_bitfield_names nstatus_names_nv10[] =
+{
+	{ NV10_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
+	{ NV10_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
+	{ NV10_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
+	{ NV10_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" }
+};
+
+static struct nouveau_bitfield_names nsource_names[] =
+{
+	{ NV03_PGRAPH_NSOURCE_NOTIFICATION,       "NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DATA_ERROR,         "DATA_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR,   "PROTECTION_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION,    "RANGE_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_COLOR,        "LIMIT_COLOR" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_ZETA,         "LIMIT_ZETA" },
+	{ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD,       "ILLEGAL_MTHD" },
+	{ NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION,   "DMA_R_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION,   "DMA_W_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION,   "FORMAT_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION,    "PATCH_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_STATE_INVALID,      "STATE_INVALID" },
+	{ NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY,      "DOUBLE_NOTIFY" },
+	{ NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE,      "NOTIFY_IN_USE" },
+	{ NV03_PGRAPH_NSOURCE_METHOD_CNT,         "METHOD_CNT" },
+	{ NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION,   "BFR_NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_A,        "DMA_WIDTH_A" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_B,        "DMA_WIDTH_B" },
+};
+
+static void
+nouveau_print_bitfield_names_(uint32_t value,
+				const struct nouveau_bitfield_names *namelist,
+				const int namelist_len)
+{
+	/*
+	 * Caller must have already printed the KERN_* log level for us.
+	 * Also the caller is responsible for adding the newline.
+	 */
+	int i;
+	for (i = 0; i < namelist_len; ++i) {
+		uint32_t mask = namelist[i].mask;
+		if (value & mask) {
+			printk(" %s", namelist[i].name);
+			value &= ~mask;
+		}
+	}
+	if (value)
+		printk(" (unknown bits 0x%08x)", value);
+}
+#define nouveau_print_bitfield_names(val, namelist) \
+	nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist))
+
+
+static int
+nouveau_graph_chid_from_grctx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	if (dev_priv->card_type < NV_40)
+		return dev_priv->engine.fifo.channels;
+	else
+	if (dev_priv->card_type < NV_50) {
+		inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 4;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			struct nouveau_channel *chan = dev_priv->fifos[i];
+
+			if (!chan || !chan->ramin_grctx)
+				continue;
+
+			if (inst == chan->ramin_grctx->instance)
+				break;
+		}
+	} else {
+		inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 12;
+
+		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+			struct nouveau_channel *chan = dev_priv->fifos[i];
+
+			if (!chan || !chan->ramin)
+				continue;
+
+			if (inst == chan->ramin->instance)
+				break;
+		}
+	}
+
+
+	return i;
+}
+
+static int
+nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	int channel;
+
+	if (dev_priv->card_type < NV_10)
+		channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf;
+	else
+	if (dev_priv->card_type < NV_40)
+		channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+	else
+		channel = nouveau_graph_chid_from_grctx(dev);
+
+	if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) {
+		NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel);
+		return -EINVAL;
+	}
+
+	*channel_ret = channel;
+	return 0;
+}
+
+struct nouveau_pgraph_trap {
+	int channel;
+	int class;
+	int subc, mthd, size;
+	uint32_t data, data2;
+	uint32_t nsource, nstatus;
+};
+
+static void
+nouveau_graph_trap_info(struct drm_device *dev,
+			struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t address;
+
+	trap->nsource = trap->nstatus = 0;
+	if (dev_priv->card_type < NV_50) {
+		trap->nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+		trap->nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
+	}
+
+	if (nouveau_graph_trapped_channel(dev, &trap->channel))
+		trap->channel = -1;
+	address = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
+
+	trap->mthd = address & 0x1FFC;
+	trap->data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
+	if (dev_priv->card_type < NV_10) {
+		trap->subc  = (address >> 13) & 0x7;
+	} else {
+		trap->subc  = (address >> 16) & 0x7;
+		trap->data2 = nv_rd32(dev, NV10_PGRAPH_TRAPPED_DATA_HIGH);
+	}
+
+	if (dev_priv->card_type < NV_10)
+		trap->class = nv_rd32(dev, 0x400180 + trap->subc*4) & 0xFF;
+	else if (dev_priv->card_type < NV_40)
+		trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFF;
+	else if (dev_priv->card_type < NV_50)
+		trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFFF;
+	else
+		trap->class = nv_rd32(dev, 0x400814);
+}
+
+static void
+nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id,
+			     struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t nsource = trap->nsource, nstatus = trap->nstatus;
+
+	NV_INFO(dev, "%s - nSource:", id);
+	nouveau_print_bitfield_names(nsource, nsource_names);
+	printk(", nStatus:");
+	if (dev_priv->card_type < NV_10)
+		nouveau_print_bitfield_names(nstatus, nstatus_names);
+	else
+		nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
+	printk("\n");
+
+	NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "
+					"Data 0x%08x:0x%08x\n",
+					id, trap->channel, trap->subc,
+					trap->class, trap->mthd,
+					trap->data2, trap->data);
+}
+
+static int
+nouveau_pgraph_intr_swmthd(struct drm_device *dev,
+			   struct nouveau_pgraph_trap *trap)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (trap->channel < 0 ||
+	    trap->channel >= dev_priv->engine.fifo.channels ||
+	    !dev_priv->fifos[trap->channel])
+		return -ENODEV;
+
+	return nouveau_call_method(dev_priv->fifos[trap->channel],
+				   trap->class, trap->mthd, trap->data);
+}
+
+static inline void
+nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource)
+{
+	struct nouveau_pgraph_trap trap;
+	int unhandled = 0;
+
+	nouveau_graph_trap_info(dev, &trap);
+
+	if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+		if (nouveau_pgraph_intr_swmthd(dev, &trap))
+			unhandled = 1;
+	} else {
+		unhandled = 1;
+	}
+
+	if (unhandled)
+		nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap);
+}
+
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
+
+static int nouveau_ratelimit(void)
+{
+	return __ratelimit(&nouveau_ratelimit_state);
+}
+
+
+static inline void
+nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource)
+{
+	struct nouveau_pgraph_trap trap;
+	int unhandled = 0;
+
+	nouveau_graph_trap_info(dev, &trap);
+	trap.nsource = nsource;
+
+	if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+		if (nouveau_pgraph_intr_swmthd(dev, &trap))
+			unhandled = 1;
+	} else if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
+		uint32_t v = nv_rd32(dev, 0x402000);
+		nv_wr32(dev, 0x402000, v);
+
+		/* dump the error anyway for now: it's useful for
+		   Gallium development */
+		unhandled = 1;
+	} else {
+		unhandled = 1;
+	}
+
+	if (unhandled && nouveau_ratelimit())
+		nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap);
+}
+
+static inline void
+nouveau_pgraph_intr_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	uint32_t chid;
+
+	chid = engine->fifo.channel_id(dev);
+	NV_DEBUG(dev, "PGRAPH context switch interrupt channel %x\n", chid);
+
+	switch (dev_priv->card_type) {
+	case NV_04:
+		nv04_graph_context_switch(dev);
+		break;
+	case NV_10:
+		nv10_graph_context_switch(dev);
+		break;
+	default:
+		NV_ERROR(dev, "Context switch not implemented\n");
+		break;
+	}
+}
+
+static void
+nouveau_pgraph_irq_handler(struct drm_device *dev)
+{
+	uint32_t status;
+
+	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+
+		if (status & NV_PGRAPH_INTR_NOTIFY) {
+			nouveau_pgraph_intr_notify(dev, nsource);
+
+			status &= ~NV_PGRAPH_INTR_NOTIFY;
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY);
+		}
+
+		if (status & NV_PGRAPH_INTR_ERROR) {
+			nouveau_pgraph_intr_error(dev, nsource);
+
+			status &= ~NV_PGRAPH_INTR_ERROR;
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR);
+		}
+
+		if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+			nouveau_pgraph_intr_context_switch(dev);
+
+			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+			nv_wr32(dev, NV03_PGRAPH_INTR,
+				 NV_PGRAPH_INTR_CONTEXT_SWITCH);
+		}
+
+		if (status) {
+			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
+			nv_wr32(dev, NV03_PGRAPH_INTR, status);
+		}
+
+		if ((nv_rd32(dev, NV04_PGRAPH_FIFO) & (1 << 0)) == 0)
+			nv_wr32(dev, NV04_PGRAPH_FIFO, 1);
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+}
+
+static void
+nv50_pgraph_irq_handler(struct drm_device *dev)
+{
+	uint32_t status;
+
+	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+
+		if (status & 0x00000001) {
+			nouveau_pgraph_intr_notify(dev, nsource);
+			status &= ~0x00000001;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
+		}
+
+		if (status & 0x00000010) {
+			nouveau_pgraph_intr_error(dev, nsource |
+					NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+
+			status &= ~0x00000010;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
+		}
+
+		if (status & 0x00001000) {
+			nv_wr32(dev, 0x400500, 0x00000000);
+			nv_wr32(dev, NV03_PGRAPH_INTR,
+				NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+				NV40_PGRAPH_INTR_EN) &
+				~NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, 0x400500, 0x00010001);
+
+			nv50_graph_context_switch(dev);
+
+			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+		}
+
+		if (status & 0x00100000) {
+			nouveau_pgraph_intr_error(dev, nsource |
+					NV03_PGRAPH_NSOURCE_DATA_ERROR);
+
+			status &= ~0x00100000;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
+		}
+
+		if (status & 0x00200000) {
+			int r;
+
+			nouveau_pgraph_intr_error(dev, nsource |
+					NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
+
+			NV_ERROR(dev, "magic set 1:\n");
+			for (r = 0x408900; r <= 0x408910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x408900,
+				nv_rd32(dev, 0x408904) | 0xc0000000);
+			for (r = 0x408e08; r <= 0x408e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+							nv_rd32(dev, r));
+			nv_wr32(dev, 0x408e08,
+				nv_rd32(dev, 0x408e08) | 0xc0000000);
+
+			NV_ERROR(dev, "magic set 2:\n");
+			for (r = 0x409900; r <= 0x409910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409900,
+				nv_rd32(dev, 0x409904) | 0xc0000000);
+			for (r = 0x409e08; r <= 0x409e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409e08,
+				nv_rd32(dev, 0x409e08) | 0xc0000000);
+
+			status &= ~0x00200000;
+			nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
+		}
+
+		if (status) {
+			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
+				status);
+			nv_wr32(dev, NV03_PGRAPH_INTR, status);
+		}
+
+		{
+			const int isb = (1 << 16) | (1 << 0);
+
+			if ((nv_rd32(dev, 0x400500) & isb) != isb)
+				nv_wr32(dev, 0x400500,
+					nv_rd32(dev, 0x400500) | isb);
+		}
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+}
+
+static void
+nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
+{
+	if (crtc & 1)
+		nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
+
+	if (crtc & 2)
+		nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
+}
+
+irqreturn_t
+nouveau_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *)arg;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t status, fbdev_flags = 0;
+
+	status = nv_rd32(dev, NV03_PMC_INTR_0);
+	if (!status)
+		return IRQ_NONE;
+
+	if (dev_priv->fbdev_info) {
+		fbdev_flags = dev_priv->fbdev_info->flags;
+		dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+	}
+
+	if (status & NV_PMC_INTR_0_PFIFO_PENDING) {
+		nouveau_fifo_irq_handler(dev);
+		status &= ~NV_PMC_INTR_0_PFIFO_PENDING;
+	}
+
+	if (status & NV_PMC_INTR_0_PGRAPH_PENDING) {
+		if (dev_priv->card_type >= NV_50)
+			nv50_pgraph_irq_handler(dev);
+		else
+			nouveau_pgraph_irq_handler(dev);
+
+		status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
+	}
+
+	if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
+		nouveau_crtc_irq_handler(dev, (status>>24)&3);
+		status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
+	}
+
+	if (status & (NV_PMC_INTR_0_NV50_DISPLAY_PENDING |
+		      NV_PMC_INTR_0_NV50_I2C_PENDING)) {
+		nv50_display_irq_handler(dev);
+		status &= ~(NV_PMC_INTR_0_NV50_DISPLAY_PENDING |
+			    NV_PMC_INTR_0_NV50_I2C_PENDING);
+	}
+
+	if (status)
+		NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status);
+
+	if (dev_priv->fbdev_info)
+		dev_priv->fbdev_info->flags = fbdev_flags;
+
+	return IRQ_HANDLED;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_mem.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+ * Copyright 2005 Stephane Marchesin
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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 AND/OR THEIR 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:
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "nouveau_drv.h"
+
+static struct mem_block *
+split_block(struct mem_block *p, uint64_t start, uint64_t size,
+	    struct drm_file *file_priv)
+{
+	/* Maybe cut off the start of an existing block */
+	if (start > p->start) {
+		struct mem_block *newblock =
+			kmalloc(sizeof(*newblock), GFP_KERNEL);
+		if (!newblock)
+			goto out;
+		newblock->start = start;
+		newblock->size = p->size - (start - p->start);
+		newblock->file_priv = NULL;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size -= newblock->size;
+		p = newblock;
+	}
+
+	/* Maybe cut off the end of an existing block */
+	if (size < p->size) {
+		struct mem_block *newblock =
+			kmalloc(sizeof(*newblock), GFP_KERNEL);
+		if (!newblock)
+			goto out;
+		newblock->start = start + size;
+		newblock->size = p->size - size;
+		newblock->file_priv = NULL;
+		newblock->next = p->next;
+		newblock->prev = p;
+		p->next->prev = newblock;
+		p->next = newblock;
+		p->size = size;
+	}
+
+out:
+	/* Our block is in the middle */
+	p->file_priv = file_priv;
+	return p;
+}
+
+struct mem_block *
+nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
+			int align2, struct drm_file *file_priv, int tail)
+{
+	struct mem_block *p;
+	uint64_t mask = (1 << align2) - 1;
+
+	if (!heap)
+		return NULL;
+
+	if (tail) {
+		list_for_each_prev(p, heap) {
+			uint64_t start = ((p->start + p->size) - size) & ~mask;
+
+			if (p->file_priv == NULL && start >= p->start &&
+			    start + size <= p->start + p->size)
+				return split_block(p, start, size, file_priv);
+		}
+	} else {
+		list_for_each(p, heap) {
+			uint64_t start = (p->start + mask) & ~mask;
+
+			if (p->file_priv == NULL &&
+			    start + size <= p->start + p->size)
+				return split_block(p, start, size, file_priv);
+		}
+	}
+
+	return NULL;
+}
+
+void nouveau_mem_free_block(struct mem_block *p)
+{
+	p->file_priv = NULL;
+
+	/* Assumes a single contiguous range.  Needs a special file_priv in
+	 * 'heap' to stop it being subsumed.
+	 */
+	if (p->next->file_priv == NULL) {
+		struct mem_block *q = p->next;
+		p->size += q->size;
+		p->next = q->next;
+		p->next->prev = p;
+		kfree(q);
+	}
+
+	if (p->prev->file_priv == NULL) {
+		struct mem_block *q = p->prev;
+		q->size += p->size;
+		q->next = p->next;
+		q->next->prev = q;
+		kfree(p);
+	}
+}
+
+/* Initialize.  How to check for an uninitialized heap?
+ */
+int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
+			  uint64_t size)
+{
+	struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
+
+	if (!blocks)
+		return -ENOMEM;
+
+	*heap = kmalloc(sizeof(**heap), GFP_KERNEL);
+	if (!*heap) {
+		kfree(blocks);
+		return -ENOMEM;
+	}
+
+	blocks->start = start;
+	blocks->size = size;
+	blocks->file_priv = NULL;
+	blocks->next = blocks->prev = *heap;
+
+	memset(*heap, 0, sizeof(**heap));
+	(*heap)->file_priv = (struct drm_file *) -1;
+	(*heap)->next = (*heap)->prev = blocks;
+	return 0;
+}
+
+/*
+ * Free all blocks associated with the releasing file_priv
+ */
+void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
+{
+	struct mem_block *p;
+
+	if (!heap || !heap->next)
+		return;
+
+	list_for_each(p, heap) {
+		if (p->file_priv == file_priv)
+			p->file_priv = NULL;
+	}
+
+	/* Assumes a single contiguous range.  Needs a special file_priv in
+	 * 'heap' to stop it being subsumed.
+	 */
+	list_for_each(p, heap) {
+		while ((p->file_priv == NULL) &&
+					(p->next->file_priv == NULL) &&
+					(p->next != heap)) {
+			struct mem_block *q = p->next;
+			p->size += q->size;
+			p->next = q->next;
+			p->next->prev = p;
+			kfree(q);
+		}
+	}
+}
+
+/*
+ * NV10-NV40 tiling helpers
+ */
+
+static void
+nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			   uint32_t size, uint32_t pitch)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
+
+	tile->addr = addr;
+	tile->size = size;
+	tile->used = !!pitch;
+	nouveau_fence_unref((void **)&tile->fence);
+
+	if (!pfifo->cache_flush(dev))
+		return;
+
+	pfifo->reassign(dev, false);
+	pfifo->cache_flush(dev);
+	pfifo->cache_pull(dev, false);
+
+	nouveau_wait_for_idle(dev);
+
+	pgraph->set_region_tiling(dev, i, addr, size, pitch);
+	pfb->set_region_tiling(dev, i, addr, size, pitch);
+
+	pfifo->cache_pull(dev, true);
+	pfifo->reassign(dev, true);
+}
+
+struct nouveau_tile_reg *
+nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size,
+		    uint32_t pitch)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+	struct nouveau_tile_reg *tile = dev_priv->tile.reg, *found = NULL;
+	int i;
+
+	spin_lock(&dev_priv->tile.lock);
+
+	for (i = 0; i < pfb->num_tiles; i++) {
+		if (tile[i].used)
+			/* Tile region in use. */
+			continue;
+
+		if (tile[i].fence &&
+		    !nouveau_fence_signalled(tile[i].fence, NULL))
+			/* Pending tile region. */
+			continue;
+
+		if (max(tile[i].addr, addr) <
+		    min(tile[i].addr + tile[i].size, addr + size))
+			/* Kill an intersecting tile region. */
+			nv10_mem_set_region_tiling(dev, i, 0, 0, 0);
+
+		if (pitch && !found) {
+			/* Free tile region. */
+			nv10_mem_set_region_tiling(dev, i, addr, size, pitch);
+			found = &tile[i];
+		}
+	}
+
+	spin_unlock(&dev_priv->tile.lock);
+
+	return found;
+}
+
+void
+nv10_mem_expire_tiling(struct drm_device *dev, struct nouveau_tile_reg *tile,
+		       struct nouveau_fence *fence)
+{
+	if (fence) {
+		/* Mark it as pending. */
+		tile->fence = fence;
+		nouveau_fence_ref(fence);
+	}
+
+	tile->used = false;
+}
+
+/*
+ * NV50 VM helpers
+ */
+int
+nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
+			uint32_t flags, uint64_t phys)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *pgt;
+	unsigned block;
+	int i;
+
+	virt = ((virt - dev_priv->vm_vram_base) >> 16) << 1;
+	size = (size >> 16) << 1;
+
+	phys |= ((uint64_t)flags << 32);
+	phys |= 1;
+	if (dev_priv->vram_sys_base) {
+		phys += dev_priv->vram_sys_base;
+		phys |= 0x30;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (size) {
+		unsigned offset_h = upper_32_bits(phys);
+		unsigned offset_l = lower_32_bits(phys);
+		unsigned pte, end;
+
+		for (i = 7; i >= 0; i--) {
+			block = 1 << (i + 1);
+			if (size >= block && !(virt & (block - 1)))
+				break;
+		}
+		offset_l |= (i << 7);
+
+		phys += block << 15;
+		size -= block;
+
+		while (block) {
+			pgt = dev_priv->vm_vram_pt[virt >> 14];
+			pte = virt & 0x3ffe;
+
+			end = pte + block;
+			if (end > 16384)
+				end = 16384;
+			block -= (end - pte);
+			virt  += (end - pte);
+
+			while (pte < end) {
+				nv_wo32(dev, pgt, pte++, offset_l);
+				nv_wo32(dev, pgt, pte++, offset_h);
+			}
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x100c80, 0x00050001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00000001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+void
+nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *pgt;
+	unsigned pages, pte, end;
+
+	virt -= dev_priv->vm_vram_base;
+	pages = (size >> 16) << 1;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (pages) {
+		pgt = dev_priv->vm_vram_pt[virt >> 29];
+		pte = (virt & 0x1ffe0000ULL) >> 15;
+
+		end = pte + pages;
+		if (end > 16384)
+			end = 16384;
+		pages -= (end - pte);
+		virt  += (end - pte) << 15;
+
+		while (pte < end)
+			nv_wo32(dev, pgt, pte++, 0);
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x100c80, 0x00050001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00000001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+	}
+}
+
+/*
+ * Cleanup everything
+ */
+void nouveau_mem_takedown(struct mem_block **heap)
+{
+	struct mem_block *p;
+
+	if (!*heap)
+		return;
+
+	for (p = (*heap)->next; p != *heap;) {
+		struct mem_block *q = p;
+		p = p->next;
+		kfree(q);
+	}
+
+	kfree(*heap);
+	*heap = NULL;
+}
+
+void nouveau_mem_close(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nouveau_bo_unpin(dev_priv->vga_ram);
+	nouveau_bo_ref(NULL, &dev_priv->vga_ram);
+
+	ttm_bo_device_release(&dev_priv->ttm.bdev);
+
+	nouveau_ttm_global_release(dev_priv);
+
+	if (drm_core_has_AGP(dev) && dev->agp &&
+	    drm_core_check_feature(dev, DRIVER_MODESET)) {
+		struct drm_agp_mem *entry, *tempe;
+
+		/* Remove AGP resources, but leave dev->agp
+		   intact until drv_cleanup is called. */
+		list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
+			if (entry->bound)
+				drm_unbind_agp(entry->memory);
+			drm_free_agp(entry->memory, entry->pages);
+			kfree(entry);
+		}
+		INIT_LIST_HEAD(&dev->agp->memory);
+
+		if (dev->agp->acquired)
+			drm_agp_release(dev);
+
+		dev->agp->acquired = 0;
+		dev->agp->enabled = 0;
+	}
+
+	if (dev_priv->fb_mtrr) {
+		drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
+			     drm_get_resource_len(dev, 1), DRM_MTRR_WC);
+		dev_priv->fb_mtrr = 0;
+	}
+}
+
+/*XXX won't work on BSD because of pci_read_config_dword */
+static uint32_t
+nouveau_mem_fb_amount_igp(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct pci_dev *bridge;
+	uint32_t mem;
+
+	bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+	if (!bridge) {
+		NV_ERROR(dev, "no bridge device\n");
+		return 0;
+	}
+
+	if (dev_priv->flags&NV_NFORCE) {
+		pci_read_config_dword(bridge, 0x7C, &mem);
+		return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
+	} else
+	if (dev_priv->flags&NV_NFORCE2) {
+		pci_read_config_dword(bridge, 0x84, &mem);
+		return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
+	}
+
+	NV_ERROR(dev, "impossible!\n");
+	return 0;
+}
+
+/* returns the amount of FB ram in bytes */
+uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t boot0;
+
+	switch (dev_priv->card_type) {
+	case NV_04:
+		boot0 = nv_rd32(dev, NV03_BOOT_0);
+		if (boot0 & 0x00000100)
+			return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+		switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+		case NV04_BOOT_0_RAM_AMOUNT_32MB:
+			return 32 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_16MB:
+			return 16 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_8MB:
+			return 8 * 1024 * 1024;
+		case NV04_BOOT_0_RAM_AMOUNT_4MB:
+			return 4 * 1024 * 1024;
+		}
+		break;
+	case NV_10:
+	case NV_20:
+	case NV_30:
+	case NV_40:
+	case NV_50:
+	default:
+		if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+			return nouveau_mem_fb_amount_igp(dev);
+		} else {
+			uint64_t mem;
+			mem = (nv_rd32(dev, NV04_FIFO_DATA) &
+					NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
+					NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
+			return mem * 1024 * 1024;
+		}
+		break;
+	}
+
+	NV_ERROR(dev,
+		"Unable to detect video ram size. Please report your setup to "
+							DRIVER_EMAIL "\n");
+	return 0;
+}
+
+#if __OS_HAS_AGP
+static void nouveau_mem_reset_agp(struct drm_device *dev)
+{
+	uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
+
+	saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
+	saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19);
+
+	/* clear busmaster bit */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
+	/* clear SBA and AGP bits */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
+
+	/* power cycle pgraph, if enabled */
+	pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
+	if (pmc_enable & NV_PMC_ENABLE_PGRAPH) {
+		nv_wr32(dev, NV03_PMC_ENABLE,
+				pmc_enable & ~NV_PMC_ENABLE_PGRAPH);
+		nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+				NV_PMC_ENABLE_PGRAPH);
+	}
+
+	/* and restore (gives effect of resetting AGP) */
+	nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
+	nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
+}
+#endif
+
+int
+nouveau_mem_init_agp(struct drm_device *dev)
+{
+#if __OS_HAS_AGP
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_agp_info info;
+	struct drm_agp_mode mode;
+	int ret;
+
+	if (nouveau_noagp)
+		return 0;
+
+	nouveau_mem_reset_agp(dev);
+
+	if (!dev->agp->acquired) {
+		ret = drm_agp_acquire(dev);
+		if (ret) {
+			NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = drm_agp_info(dev, &info);
+	if (ret) {
+		NV_ERROR(dev, "Unable to get AGP info: %d\n", ret);
+		return ret;
+	}
+
+	/* see agp.h for the AGPSTAT_* modes available */
+	mode.mode = info.mode;
+	ret = drm_agp_enable(dev, mode);
+	if (ret) {
+		NV_ERROR(dev, "Unable to enable AGP: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->gart_info.type	= NOUVEAU_GART_AGP;
+	dev_priv->gart_info.aper_base	= info.aperture_base;
+	dev_priv->gart_info.aper_size	= info.aperture_size;
+#endif
+	return 0;
+}
+
+int
+nouveau_mem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
+	int ret, dma_bits = 32;
+
+	dev_priv->fb_phys = drm_get_resource_start(dev, 1);
+	dev_priv->gart_info.type = NOUVEAU_GART_NONE;
+
+	if (dev_priv->card_type >= NV_50 &&
+	    pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
+		dma_bits = 40;
+
+	ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
+	if (ret) {
+		NV_ERROR(dev, "Error setting DMA mask: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_ttm_global_init(dev_priv);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_device_init(&dev_priv->ttm.bdev,
+				 dev_priv->ttm.bo_global_ref.ref.object,
+				 &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET,
+				 dma_bits <= 32 ? true : false);
+	if (ret) {
+		NV_ERROR(dev, "Error initialising bo driver: %d\n", ret);
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&dev_priv->ttm.bo_list);
+	spin_lock_init(&dev_priv->ttm.bo_list_lock);
+	spin_lock_init(&dev_priv->tile.lock);
+
+	dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
+
+	dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
+	if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
+		dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
+	dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
+
+	NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
+
+	/* remove reserved space at end of vram from available amount */
+	dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
+	dev_priv->fb_aper_free = dev_priv->fb_available_size;
+
+	/* mappable vram */
+	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
+			     dev_priv->fb_available_size >> PAGE_SHIFT);
+	if (ret) {
+		NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_bo_new(dev, NULL, 256*1024, 0, TTM_PL_FLAG_VRAM,
+			     0, 0, true, true, &dev_priv->vga_ram);
+	if (ret == 0)
+		ret = nouveau_bo_pin(dev_priv->vga_ram, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_WARN(dev, "failed to reserve VGA memory\n");
+		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
+	}
+
+	/* GART */
+#if !defined(__powerpc__) && !defined(__ia64__)
+	if (drm_device_is_agp(dev) && dev->agp) {
+		ret = nouveau_mem_init_agp(dev);
+		if (ret)
+			NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
+	}
+#endif
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
+		ret = nouveau_sgdma_init(dev);
+		if (ret) {
+			NV_ERROR(dev, "Error initialising PCI(E): %d\n", ret);
+			return ret;
+		}
+	}
+
+	NV_INFO(dev, "%d MiB GART (aperture)\n",
+		(int)(dev_priv->gart_info.aper_size >> 20));
+	dev_priv->gart_info.aper_free = dev_priv->gart_info.aper_size;
+
+	ret = ttm_bo_init_mm(bdev, TTM_PL_TT,
+			     dev_priv->gart_info.aper_size >> PAGE_SHIFT);
+	if (ret) {
+		NV_ERROR(dev, "Failed TT mm init: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
+					 drm_get_resource_len(dev, 1),
+					 DRM_MTRR_WC);
+
+	return 0;
+}
+
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_notifier.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+int
+nouveau_notifier_init_channel(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct nouveau_bo *ntfy = NULL;
+	uint32_t flags;
+	int ret;
+
+	if (nouveau_vram_notify)
+		flags = TTM_PL_FLAG_VRAM;
+	else
+		flags = TTM_PL_FLAG_TT;
+
+	ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags,
+			      0, 0x0000, false, true, &ntfy);
+	if (ret)
+		return ret;
+
+	ret = nouveau_bo_pin(ntfy, flags);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_bo_map(ntfy);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size);
+	if (ret)
+		goto out_err;
+
+	chan->notifier_bo = ntfy;
+out_err:
+	if (ret) {
+		mutex_lock(&dev->struct_mutex);
+		drm_gem_object_unreference(ntfy->gem);
+		mutex_unlock(&dev->struct_mutex);
+	}
+
+	return ret;
+}
+
+void
+nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	if (!chan->notifier_bo)
+		return;
+
+	nouveau_bo_unmap(chan->notifier_bo);
+	mutex_lock(&dev->struct_mutex);
+	nouveau_bo_unpin(chan->notifier_bo);
+	drm_gem_object_unreference(chan->notifier_bo->gem);
+	mutex_unlock(&dev->struct_mutex);
+	nouveau_mem_takedown(&chan->notifier_heap);
+}
+
+static void
+nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
+			     struct nouveau_gpuobj *gpuobj)
+{
+	NV_DEBUG(dev, "\n");
+
+	if (gpuobj->priv)
+		nouveau_mem_free_block(gpuobj->priv);
+}
+
+int
+nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
+		       int size, uint32_t *b_offset)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *nobj = NULL;
+	struct mem_block *mem;
+	uint32_t offset;
+	int target, ret;
+
+	if (!chan->notifier_heap) {
+		NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n",
+			 chan->id);
+		return -EINVAL;
+	}
+
+	mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
+				      (struct drm_file *)-2, 0);
+	if (!mem) {
+		NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
+		return -ENOMEM;
+	}
+
+	offset = chan->notifier_bo->bo.mem.mm_node->start << PAGE_SHIFT;
+	if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) {
+		target = NV_DMA_TARGET_VIDMEM;
+	} else
+	if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) {
+		if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA &&
+		    dev_priv->card_type < NV_50) {
+			ret = nouveau_sgdma_get_page(dev, offset, &offset);
+			if (ret)
+				return ret;
+			target = NV_DMA_TARGET_PCI;
+		} else {
+			target = NV_DMA_TARGET_AGP;
+			if (dev_priv->card_type >= NV_50)
+				offset += dev_priv->vm_gart_base;
+		}
+	} else {
+		NV_ERROR(dev, "Bad DMA target, mem_type %d!\n",
+			 chan->notifier_bo->bo.mem.mem_type);
+		return -EINVAL;
+	}
+	offset += mem->start;
+
+	ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset,
+				     mem->size, NV_DMA_ACCESS_RW, target,
+				     &nobj);
+	if (ret) {
+		nouveau_mem_free_block(mem);
+		NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
+		return ret;
+	}
+	nobj->dtor   = nouveau_notifier_gpuobj_dtor;
+	nobj->priv   = mem;
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &nobj);
+		nouveau_mem_free_block(mem);
+		NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	*b_offset = mem->start;
+	return 0;
+}
+
+int
+nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
+{
+	if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor)
+		return -EINVAL;
+
+	if (poffset) {
+		struct mem_block *mem = nobj->priv;
+
+		if (*poffset >= mem->size)
+			return false;
+
+		*poffset += mem->start;
+	}
+
+	return 0;
+}
+
+int
+nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+	struct drm_nouveau_notifierobj_alloc *na = data;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
+
+	ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_object.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_object.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_object.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_object.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2006 Ben Skeggs.
+ *
+ * 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, 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 OWNER(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:
+ *   Ben Skeggs <darktama@iinet.net.au>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+/* NVidia uses context objects to drive drawing operations.
+
+   Context objects can be selected into 8 subchannels in the FIFO,
+   and then used via DMA command buffers.
+
+   A context object is referenced by a user defined handle (CARD32). The HW
+   looks up graphics objects in a hash table in the instance RAM.
+
+   An entry in the hash table consists of 2 CARD32. The first CARD32 contains
+   the handle, the second one a bitfield, that contains the address of the
+   object in instance RAM.
+
+   The format of the second CARD32 seems to be:
+
+   NV4 to NV30:
+
+   15: 0  instance_addr >> 4
+   17:16  engine (here uses 1 = graphics)
+   28:24  channel id (here uses 0)
+   31	  valid (use 1)
+
+   NV40:
+
+   15: 0  instance_addr >> 4   (maybe 19-0)
+   21:20  engine (here uses 1 = graphics)
+   I'm unsure about the other bits, but using 0 seems to work.
+
+   The key into the hash table depends on the object handle and channel id and
+   is given as:
+*/
+static uint32_t
+nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t hash = 0;
+	int i;
+
+	NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle);
+
+	for (i = 32; i > 0; i -= dev_priv->ramht_bits) {
+		hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
+		handle >>= dev_priv->ramht_bits;
+	}
+
+	if (dev_priv->card_type < NV_50)
+		hash ^= channel << (dev_priv->ramht_bits - 4);
+	hash <<= 3;
+
+	NV_DEBUG(dev, "hash=0x%08x\n", hash);
+	return hash;
+}
+
+static int
+nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht,
+			  uint32_t offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t ctx = nv_ro32(dev, ramht, (offset + 4)/4);
+
+	if (dev_priv->card_type < NV_40)
+		return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0);
+	return (ctx != 0);
+}
+
+static int
+nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_channel *chan = ref->channel;
+	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
+	uint32_t ctx, co, ho;
+
+	if (!ramht) {
+		NV_ERROR(dev, "No hash table!\n");
+		return -EINVAL;
+	}
+
+	if (dev_priv->card_type < NV_40) {
+		ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) |
+		      (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+		      (ref->gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT);
+	} else
+	if (dev_priv->card_type < NV_50) {
+		ctx = (ref->instance >> 4) |
+		      (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
+		      (ref->gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
+	} else {
+		if (ref->gpuobj->engine == NVOBJ_ENGINE_DISPLAY) {
+			ctx = (ref->instance << 10) | 2;
+		} else {
+			ctx = (ref->instance >> 4) |
+			      ((ref->gpuobj->engine <<
+				NV40_RAMHT_CONTEXT_ENGINE_SHIFT));
+		}
+	}
+
+	instmem->prepare_access(dev, true);
+	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
+	do {
+		if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
+			NV_DEBUG(dev,
+				 "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+				 chan->id, co, ref->handle, ctx);
+			nv_wo32(dev, ramht, (co + 0)/4, ref->handle);
+			nv_wo32(dev, ramht, (co + 4)/4, ctx);
+
+			list_add_tail(&ref->list, &chan->ramht_refs);
+			instmem->finish_access(dev);
+			return 0;
+		}
+		NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
+			 chan->id, co, nv_ro32(dev, ramht, co/4));
+
+		co += 8;
+		if (co >= dev_priv->ramht_size)
+			co = 0;
+	} while (co != ho);
+	instmem->finish_access(dev);
+
+	NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
+	return -ENOMEM;
+}
+
+static void
+nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_channel *chan = ref->channel;
+	struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
+	uint32_t co, ho;
+
+	if (!ramht) {
+		NV_ERROR(dev, "No hash table!\n");
+		return;
+	}
+
+	instmem->prepare_access(dev, true);
+	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
+	do {
+		if (nouveau_ramht_entry_valid(dev, ramht, co) &&
+		    (ref->handle == nv_ro32(dev, ramht, (co/4)))) {
+			NV_DEBUG(dev,
+				 "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
+				 chan->id, co, ref->handle,
+				 nv_ro32(dev, ramht, (co + 4)));
+			nv_wo32(dev, ramht, (co + 0)/4, 0x00000000);
+			nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);
+
+			list_del(&ref->list);
+			instmem->finish_access(dev);
+			return;
+		}
+
+		co += 8;
+		if (co >= dev_priv->ramht_size)
+			co = 0;
+	} while (co != ho);
+	list_del(&ref->list);
+	instmem->finish_access(dev);
+
+	NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
+		 chan->id, ref->handle);
+}
+
+int
+nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
+		   uint32_t size, int align, uint32_t flags,
+		   struct nouveau_gpuobj **gpuobj_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct nouveau_gpuobj *gpuobj;
+	struct mem_block *pramin = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
+		 chan ? chan->id : -1, size, align, flags);
+
+	if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
+		return -EINVAL;
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
+	gpuobj->flags = flags;
+	gpuobj->im_channel = chan;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+
+	/* Choose between global instmem heap, and per-channel private
+	 * instmem heap.  On <NV50 allow requests for private instmem
+	 * to be satisfied from global heap if no per-channel area
+	 * available.
+	 */
+	if (chan) {
+		if (chan->ramin_heap) {
+			NV_DEBUG(dev, "private heap\n");
+			pramin = chan->ramin_heap;
+		} else
+		if (dev_priv->card_type < NV_50) {
+			NV_DEBUG(dev, "global heap fallback\n");
+			pramin = dev_priv->ramin_heap;
+		}
+	} else {
+		NV_DEBUG(dev, "global heap\n");
+		pramin = dev_priv->ramin_heap;
+	}
+
+	if (!pramin) {
+		NV_ERROR(dev, "No PRAMIN heap!\n");
+		return -EINVAL;
+	}
+
+	if (!chan) {
+		ret = engine->instmem.populate(dev, gpuobj, &size);
+		if (ret) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return ret;
+		}
+	}
+
+	/* Allocate a chunk of the PRAMIN aperture */
+	gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size,
+						    drm_order(align),
+						    (struct drm_file *)-2, 0);
+	if (!gpuobj->im_pramin) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return -ENOMEM;
+	}
+
+	if (!chan) {
+		ret = engine->instmem.bind(dev, gpuobj);
+		if (ret) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return ret;
+		}
+	}
+
+	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
+		int i;
+
+		engine->instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		engine->instmem.finish_access(dev);
+	}
+
+	*gpuobj_ret = gpuobj;
+	return 0;
+}
+
+int
+nouveau_gpuobj_early_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	INIT_LIST_HEAD(&dev_priv->gpuobj_list);
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	if (dev_priv->card_type < NV_50) {
+		ret = nouveau_gpuobj_new_fake(dev,
+			dev_priv->ramht_offset, ~0, dev_priv->ramht_size,
+			NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ALLOW_NO_REFS,
+						&dev_priv->ramht, NULL);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	nouveau_gpuobj_del(dev, &dev_priv->ramht);
+}
+
+void
+nouveau_gpuobj_late_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	struct list_head *entry, *tmp;
+
+	NV_DEBUG(dev, "\n");
+
+	list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
+		gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
+
+		NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n",
+			 gpuobj, gpuobj->refcount);
+		gpuobj->refcount = 0;
+		nouveau_gpuobj_del(dev, &gpuobj);
+	}
+}
+
+int
+nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL);
+
+	if (!dev_priv || !pgpuobj || !(*pgpuobj))
+		return -EINVAL;
+	gpuobj = *pgpuobj;
+
+	if (gpuobj->refcount != 0) {
+		NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount);
+		return -EINVAL;
+	}
+
+	if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
+		engine->instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		engine->instmem.finish_access(dev);
+	}
+
+	if (gpuobj->dtor)
+		gpuobj->dtor(dev, gpuobj);
+
+	if (gpuobj->im_backing && !(gpuobj->flags & NVOBJ_FLAG_FAKE))
+		engine->instmem.clear(dev, gpuobj);
+
+	if (gpuobj->im_pramin) {
+		if (gpuobj->flags & NVOBJ_FLAG_FAKE)
+			kfree(gpuobj->im_pramin);
+		else
+			nouveau_mem_free_block(gpuobj->im_pramin);
+	}
+
+	list_del(&gpuobj->list);
+
+	*pgpuobj = NULL;
+	kfree(gpuobj);
+	return 0;
+}
+
+static int
+nouveau_gpuobj_instance_get(struct drm_device *dev,
+			    struct nouveau_channel *chan,
+			    struct nouveau_gpuobj *gpuobj, uint32_t *inst)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *cpramin;
+
+	/* <NV50 use PRAMIN address everywhere */
+	if (dev_priv->card_type < NV_50) {
+		*inst = gpuobj->im_pramin->start;
+		return 0;
+	}
+
+	if (chan && gpuobj->im_channel != chan) {
+		NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n",
+			 gpuobj->im_channel->id, chan->id);
+		return -EINVAL;
+	}
+
+	/* NV50 channel-local instance */
+	if (chan) {
+		cpramin = chan->ramin->gpuobj;
+		*inst = gpuobj->im_pramin->start - cpramin->im_pramin->start;
+		return 0;
+	}
+
+	/* NV50 global (VRAM) instance */
+	if (!gpuobj->im_channel) {
+		/* ...from global heap */
+		if (!gpuobj->im_backing) {
+			NV_ERROR(dev, "AII, no VRAM backing gpuobj\n");
+			return -EINVAL;
+		}
+		*inst = gpuobj->im_backing_start;
+		return 0;
+	} else {
+		/* ...from local heap */
+		cpramin = gpuobj->im_channel->ramin->gpuobj;
+		*inst = cpramin->im_backing_start +
+			(gpuobj->im_pramin->start - cpramin->im_pramin->start);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+int
+nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan,
+		       uint32_t handle, struct nouveau_gpuobj *gpuobj,
+		       struct nouveau_gpuobj_ref **ref_ret)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj_ref *ref;
+	uint32_t instance;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n",
+		 chan ? chan->id : -1, handle, gpuobj);
+
+	if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL))
+		return -EINVAL;
+
+	if (!chan && !ref_ret)
+		return -EINVAL;
+
+	if (gpuobj->engine == NVOBJ_ENGINE_SW && !gpuobj->im_pramin) {
+		/* sw object */
+		instance = 0x40;
+	} else {
+		ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance);
+		if (ret)
+			return ret;
+	}
+
+	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+	if (!ref)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&ref->list);
+	ref->gpuobj   = gpuobj;
+	ref->channel  = chan;
+	ref->instance = instance;
+
+	if (!ref_ret) {
+		ref->handle = handle;
+
+		ret = nouveau_ramht_insert(dev, ref);
+		if (ret) {
+			kfree(ref);
+			return ret;
+		}
+	} else {
+		ref->handle = ~0;
+		*ref_ret = ref;
+	}
+
+	ref->gpuobj->refcount++;
+	return 0;
+}
+
+int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref)
+{
+	struct nouveau_gpuobj_ref *ref;
+
+	NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL);
+
+	if (!dev || !pref || *pref == NULL)
+		return -EINVAL;
+	ref = *pref;
+
+	if (ref->handle != ~0)
+		nouveau_ramht_remove(dev, ref);
+
+	if (ref->gpuobj) {
+		ref->gpuobj->refcount--;
+
+		if (ref->gpuobj->refcount == 0) {
+			if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS))
+				nouveau_gpuobj_del(dev, &ref->gpuobj);
+		}
+	}
+
+	*pref = NULL;
+	kfree(ref);
+	return 0;
+}
+
+int
+nouveau_gpuobj_new_ref(struct drm_device *dev,
+		       struct nouveau_channel *oc, struct nouveau_channel *rc,
+		       uint32_t handle, uint32_t size, int align,
+		       uint32_t flags, struct nouveau_gpuobj_ref **ref)
+{
+	struct nouveau_gpuobj *gpuobj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &gpuobj);
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle,
+			struct nouveau_gpuobj_ref **ref_ret)
+{
+	struct nouveau_gpuobj_ref *ref;
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
+
+		if (ref->handle == handle) {
+			if (ref_ret)
+				*ref_ret = ref;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int
+nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
+			uint32_t b_offset, uint32_t size,
+			uint32_t flags, struct nouveau_gpuobj **pgpuobj,
+			struct nouveau_gpuobj_ref **pref)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	int i;
+
+	NV_DEBUG(dev,
+		 "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n",
+		 p_offset, b_offset, size, flags);
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
+	gpuobj->im_channel = NULL;
+	gpuobj->flags      = flags | NVOBJ_FLAG_FAKE;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+
+	if (p_offset != ~0) {
+		gpuobj->im_pramin = kzalloc(sizeof(struct mem_block),
+					    GFP_KERNEL);
+		if (!gpuobj->im_pramin) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return -ENOMEM;
+		}
+		gpuobj->im_pramin->start = p_offset;
+		gpuobj->im_pramin->size  = size;
+	}
+
+	if (b_offset != ~0) {
+		gpuobj->im_backing = (struct nouveau_bo *)-1;
+		gpuobj->im_backing_start = b_offset;
+	}
+
+	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
+		dev_priv->engine.instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
+			nv_wo32(dev, gpuobj, i/4, 0);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	if (pref) {
+		i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref);
+		if (i) {
+			nouveau_gpuobj_del(dev, &gpuobj);
+			return i;
+		}
+	}
+
+	if (pgpuobj)
+		*pgpuobj = gpuobj;
+	return 0;
+}
+
+
+static uint32_t
+nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/*XXX: dodgy hack for now */
+	if (dev_priv->card_type >= NV_50)
+		return 24;
+	if (dev_priv->card_type >= NV_40)
+		return 32;
+	return 16;
+}
+
+/*
+   DMA objects are used to reference a piece of memory in the
+   framebuffer, PCI or AGP address space. Each object is 16 bytes big
+   and looks as follows:
+
+   entry[0]
+   11:0  class (seems like I can always use 0 here)
+   12    page table present?
+   13    page entry linear?
+   15:14 access: 0 rw, 1 ro, 2 wo
+   17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
+   31:20 dma adjust (bits 0-11 of the address)
+   entry[1]
+   dma limit (size of transfer)
+   entry[X]
+   1     0 readonly, 1 readwrite
+   31:12 dma frame address of the page (bits 12-31 of the address)
+   entry[N]
+   page table terminator, same value as the first pte, as does nvidia
+   rivatv uses 0xffffffff
+
+   Non linear page tables need a list of frame addresses afterwards,
+   the rivatv project has some info on this.
+
+   The method below creates a DMA object in instance RAM and returns a handle
+   to it that can be used to set up context objects.
+*/
+int
+nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
+		       uint64_t offset, uint64_t size, int access,
+		       int target, struct nouveau_gpuobj **gpuobj)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
+		 chan->id, class, offset, size);
+	NV_DEBUG(dev, "access=%d target=%d\n", access, target);
+
+	switch (target) {
+	case NV_DMA_TARGET_AGP:
+		offset += dev_priv->gart_info.aper_base;
+		break;
+	default:
+		break;
+	}
+
+	ret = nouveau_gpuobj_new(dev, chan,
+				 nouveau_gpuobj_class_instmem_size(dev, class),
+				 16, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
+		return ret;
+	}
+
+	instmem->prepare_access(dev, true);
+
+	if (dev_priv->card_type < NV_50) {
+		uint32_t frame, adjust, pte_flags = 0;
+
+		if (access != NV_DMA_ACCESS_RO)
+			pte_flags |= (1<<1);
+		adjust = offset &  0x00000fff;
+		frame  = offset & ~0x00000fff;
+
+		nv_wo32(dev, *gpuobj, 0, ((1<<12) | (1<<13) |
+				(adjust << 20) |
+				 (access << 14) |
+				 (target << 16) |
+				  class));
+		nv_wo32(dev, *gpuobj, 1, size - 1);
+		nv_wo32(dev, *gpuobj, 2, frame | pte_flags);
+		nv_wo32(dev, *gpuobj, 3, frame | pte_flags);
+	} else {
+		uint64_t limit = offset + size - 1;
+		uint32_t flags0, flags5;
+
+		if (target == NV_DMA_TARGET_VIDMEM) {
+			flags0 = 0x00190000;
+			flags5 = 0x00010000;
+		} else {
+			flags0 = 0x7fc00000;
+			flags5 = 0x00080000;
+		}
+
+		nv_wo32(dev, *gpuobj, 0, flags0 | class);
+		nv_wo32(dev, *gpuobj, 1, lower_32_bits(limit));
+		nv_wo32(dev, *gpuobj, 2, lower_32_bits(offset));
+		nv_wo32(dev, *gpuobj, 3, ((upper_32_bits(limit) & 0xff) << 24) |
+					(upper_32_bits(offset) & 0xff));
+		nv_wo32(dev, *gpuobj, 5, flags5);
+	}
+
+	instmem->finish_access(dev);
+
+	(*gpuobj)->engine = NVOBJ_ENGINE_SW;
+	(*gpuobj)->class  = class;
+	return 0;
+}
+
+int
+nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan,
+			    uint64_t offset, uint64_t size, int access,
+			    struct nouveau_gpuobj **gpuobj,
+			    uint32_t *o_ret)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP ||
+	    (dev_priv->card_type >= NV_50 &&
+	     dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     offset + dev_priv->vm_gart_base,
+					     size, access, NV_DMA_TARGET_AGP,
+					     gpuobj);
+		if (o_ret)
+			*o_ret = 0;
+	} else
+	if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
+		*gpuobj = dev_priv->gart_info.sg_ctxdma;
+		if (offset & ~0xffffffffULL) {
+			NV_ERROR(dev, "obj offset exceeds 32-bits\n");
+			return -EINVAL;
+		}
+		if (o_ret)
+			*o_ret = (uint32_t)offset;
+		ret = (*gpuobj != NULL) ? 0 : -EINVAL;
+	} else {
+		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/* Context objects in the instance RAM have the following structure.
+ * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.
+
+   NV4 - NV30:
+
+   entry[0]
+   11:0 class
+   12   chroma key enable
+   13   user clip enable
+   14   swizzle enable
+   17:15 patch config:
+       scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
+   18   synchronize enable
+   19   endian: 1 big, 0 little
+   21:20 dither mode
+   23    single step enable
+   24    patch status: 0 invalid, 1 valid
+   25    context_surface 0: 1 valid
+   26    context surface 1: 1 valid
+   27    context pattern: 1 valid
+   28    context rop: 1 valid
+   29,30 context beta, beta4
+   entry[1]
+   7:0   mono format
+   15:8  color format
+   31:16 notify instance address
+   entry[2]
+   15:0  dma 0 instance address
+   31:16 dma 1 instance address
+   entry[3]
+   dma method traps
+
+   NV40:
+   No idea what the exact format is. Here's what can be deducted:
+
+   entry[0]:
+   11:0  class  (maybe uses more bits here?)
+   17    user clip enable
+   21:19 patch config
+   25    patch status valid ?
+   entry[1]:
+   15:0  DMA notifier  (maybe 20:0)
+   entry[2]:
+   15:0  DMA 0 instance (maybe 20:0)
+   24    big endian
+   entry[3]:
+   15:0  DMA 1 instance (maybe 20:0)
+   entry[4]:
+   entry[5]:
+   set to 0?
+*/
+int
+nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
+		      struct nouveau_gpuobj **gpuobj)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
+
+	ret = nouveau_gpuobj_new(dev, chan,
+				 nouveau_gpuobj_class_instmem_size(dev, class),
+				 16,
+				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
+				 gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (dev_priv->card_type >= NV_50) {
+		nv_wo32(dev, *gpuobj, 0, class);
+		nv_wo32(dev, *gpuobj, 5, 0x00010000);
+	} else {
+		switch (class) {
+		case NV_CLASS_NULL:
+			nv_wo32(dev, *gpuobj, 0, 0x00001030);
+			nv_wo32(dev, *gpuobj, 1, 0xFFFFFFFF);
+			break;
+		default:
+			if (dev_priv->card_type >= NV_40) {
+				nv_wo32(dev, *gpuobj, 0, class);
+#ifdef __BIG_ENDIAN
+				nv_wo32(dev, *gpuobj, 2, 0x01000000);
+#endif
+			} else {
+#ifdef __BIG_ENDIAN
+				nv_wo32(dev, *gpuobj, 0, class | 0x00080000);
+#else
+				nv_wo32(dev, *gpuobj, 0, class);
+#endif
+			}
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	(*gpuobj)->engine = NVOBJ_ENGINE_GR;
+	(*gpuobj)->class  = class;
+	return 0;
+}
+
+int
+nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
+		      struct nouveau_gpuobj **gpuobj_ret)
+{
+	struct drm_nouveau_private *dev_priv;
+	struct nouveau_gpuobj *gpuobj;
+
+	if (!chan || !gpuobj_ret || *gpuobj_ret != NULL)
+		return -EINVAL;
+	dev_priv = chan->dev->dev_private;
+
+	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
+	if (!gpuobj)
+		return -ENOMEM;
+	gpuobj->engine = NVOBJ_ENGINE_SW;
+	gpuobj->class = class;
+
+	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+	*gpuobj_ret = gpuobj;
+	return 0;
+}
+
+static int
+nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *pramin = NULL;
+	uint32_t size;
+	uint32_t base;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	/* Base amount for object storage (4KiB enough?) */
+	size = 0x1000;
+	base = 0;
+
+	/* PGRAPH context */
+
+	if (dev_priv->card_type == NV_50) {
+		/* Various fixed table thingos */
+		size += 0x1400; /* mostly unknown stuff */
+		size += 0x4000; /* vm pd */
+		base  = 0x6000;
+		/* RAMHT, not sure about setting size yet, 32KiB to be safe */
+		size += 0x8000;
+		/* RAMFC */
+		size += 0x1000;
+		/* PGRAPH context */
+		size += 0x70000;
+	}
+
+	NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
+		 chan->id, size, base);
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
+				     &chan->ramin);
+	if (ret) {
+		NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
+		return ret;
+	}
+	pramin = chan->ramin->gpuobj;
+
+	ret = nouveau_mem_init_heap(&chan->ramin_heap,
+				    pramin->im_pramin->start + base, size);
+	if (ret) {
+		NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
+			    uint32_t vram_h, uint32_t tt_h)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	struct nouveau_gpuobj *vram = NULL, *tt = NULL;
+	int ret, i;
+
+	INIT_LIST_HEAD(&chan->ramht_refs);
+
+	NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
+
+	/* Reserve a block of PRAMIN for the channel
+	 *XXX: maybe on <NV50 too at some point
+	 */
+	if (0 || dev_priv->card_type == NV_50) {
+		ret = nouveau_gpuobj_channel_init_pramin(chan);
+		if (ret) {
+			NV_ERROR(dev, "init pramin\n");
+			return ret;
+		}
+	}
+
+	/* NV50 VM
+	 *  - Allocate per-channel page-directory
+	 *  - Map GART and VRAM into the channel's address space at the
+	 *    locations determined during init.
+	 */
+	if (dev_priv->card_type >= NV_50) {
+		uint32_t vm_offset, pde;
+
+		instmem->prepare_access(dev, true);
+
+		vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
+		vm_offset += chan->ramin->gpuobj->im_pramin->start;
+
+		ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
+							0, &chan->vm_pd, NULL);
+		if (ret) {
+			instmem->finish_access(dev);
+			return ret;
+		}
+		for (i = 0; i < 0x4000; i += 8) {
+			nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
+			nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
+		}
+
+		pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2;
+		ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
+					     dev_priv->gart_info.sg_ctxdma,
+					     &chan->vm_gart_pt);
+		if (ret) {
+			instmem->finish_access(dev);
+			return ret;
+		}
+		nv_wo32(dev, chan->vm_pd, pde++,
+			    chan->vm_gart_pt->instance | 0x03);
+		nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
+
+		pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2;
+		for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+			ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
+						     dev_priv->vm_vram_pt[i],
+						     &chan->vm_vram_pt[i]);
+			if (ret) {
+				instmem->finish_access(dev);
+				return ret;
+			}
+
+			nv_wo32(dev, chan->vm_pd, pde++,
+				    chan->vm_vram_pt[i]->instance | 0x61);
+			nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
+		}
+
+		instmem->finish_access(dev);
+	}
+
+	/* RAMHT */
+	if (dev_priv->card_type < NV_50) {
+		ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht,
+					     &chan->ramht);
+		if (ret)
+			return ret;
+	} else {
+		ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0,
+					     0x8000, 16,
+					     NVOBJ_FLAG_ZERO_ALLOC,
+					     &chan->ramht);
+		if (ret)
+			return ret;
+	}
+
+	/* VRAM ctxdma */
+	if (dev_priv->card_type >= NV_50) {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     0, dev_priv->vm_end,
+					     NV_DMA_ACCESS_RW,
+					     NV_DMA_TARGET_AGP, &vram);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
+			return ret;
+		}
+	} else {
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+						0, dev_priv->fb_available_size,
+						NV_DMA_ACCESS_RW,
+						NV_DMA_TARGET_VIDMEM, &vram);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	/* TT memory ctxdma */
+	if (dev_priv->card_type >= NV_50) {
+		tt = vram;
+	} else
+	if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
+		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
+						  dev_priv->gart_info.aper_size,
+						  NV_DMA_ACCESS_RW, &tt, NULL);
+	} else {
+		NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
+		ret = -EINVAL;
+	}
+
+	if (ret) {
+		NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_device *dev = chan->dev;
+	struct list_head *entry, *tmp;
+	struct nouveau_gpuobj_ref *ref;
+	int i;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (!chan->ramht_refs.next)
+		return;
+
+	list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+		ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
+
+		nouveau_gpuobj_ref_del(dev, &ref);
+	}
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramht);
+
+	nouveau_gpuobj_del(dev, &chan->vm_pd);
+	nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt);
+	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
+		nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
+
+	if (chan->ramin_heap)
+		nouveau_mem_takedown(&chan->ramin_heap);
+	if (chan->ramin)
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+
+}
+
+int
+nouveau_gpuobj_suspend(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	if (dev_priv->card_type < NV_50) {
+		dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram);
+		if (!dev_priv->susres.ramin_copy)
+			return -ENOMEM;
+
+		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
+			dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i);
+		return 0;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing || (gpuobj->flags & NVOBJ_FLAG_FAKE))
+			continue;
+
+		gpuobj->im_backing_suspend = vmalloc(gpuobj->im_pramin->size);
+		if (!gpuobj->im_backing_suspend) {
+			nouveau_gpuobj_resume(dev);
+			return -ENOMEM;
+		}
+
+		dev_priv->engine.instmem.prepare_access(dev, false);
+		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
+			gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	return 0;
+}
+
+void
+nouveau_gpuobj_suspend_cleanup(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+
+	if (dev_priv->card_type < NV_50) {
+		vfree(dev_priv->susres.ramin_copy);
+		dev_priv->susres.ramin_copy = NULL;
+		return;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing_suspend)
+			continue;
+
+		vfree(gpuobj->im_backing_suspend);
+		gpuobj->im_backing_suspend = NULL;
+	}
+}
+
+void
+nouveau_gpuobj_resume(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+	int i;
+
+	if (dev_priv->card_type < NV_50) {
+		for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
+			nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]);
+		nouveau_gpuobj_suspend_cleanup(dev);
+		return;
+	}
+
+	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
+		if (!gpuobj->im_backing_suspend)
+			continue;
+
+		dev_priv->engine.instmem.prepare_access(dev, true);
+		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
+			nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
+		dev_priv->engine.instmem.finish_access(dev);
+	}
+
+	nouveau_gpuobj_suspend_cleanup(dev);
+}
+
+int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_grobj_alloc *init = data;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_pgraph_object_class *grc;
+	struct nouveau_gpuobj *gr = NULL;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
+
+	if (init->handle == ~0)
+		return -EINVAL;
+
+	grc = pgraph->grclass;
+	while (grc->id) {
+		if (grc->id == init->class)
+			break;
+		grc++;
+	}
+
+	if (!grc->id) {
+		NV_ERROR(dev, "Illegal object class: 0x%x\n", init->class);
+		return -EPERM;
+	}
+
+	if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0)
+		return -EEXIST;
+
+	if (!grc->software)
+		ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr);
+	else
+		ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr);
+
+	if (ret) {
+		NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
+			 ret, init->channel, init->handle);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL);
+	if (ret) {
+		NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n",
+			 ret, init->channel, init->handle);
+		nouveau_gpuobj_del(dev, &gr);
+		return ret;
+	}
+
+	return 0;
+}
+
+int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_nouveau_gpuobj_free *objfree = data;
+	struct nouveau_gpuobj_ref *ref;
+	struct nouveau_channel *chan;
+	int ret;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
+
+	ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);
+	if (ret)
+		return ret;
+	nouveau_gpuobj_ref_del(dev, &ref);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,837 @@
+
+
+#define NV03_BOOT_0                                        0x00100000
+#    define NV03_BOOT_0_RAM_AMOUNT                         0x00000003
+#    define NV03_BOOT_0_RAM_AMOUNT_8MB                     0x00000000
+#    define NV03_BOOT_0_RAM_AMOUNT_2MB                     0x00000001
+#    define NV03_BOOT_0_RAM_AMOUNT_4MB                     0x00000002
+#    define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM               0x00000003
+#    define NV04_BOOT_0_RAM_AMOUNT_32MB                    0x00000000
+#    define NV04_BOOT_0_RAM_AMOUNT_4MB                     0x00000001
+#    define NV04_BOOT_0_RAM_AMOUNT_8MB                     0x00000002
+#    define NV04_BOOT_0_RAM_AMOUNT_16MB                    0x00000003
+
+#define NV04_FIFO_DATA                                     0x0010020c
+#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK              0xfff00000
+#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT             20
+
+#define NV_RAMIN                                           0x00700000
+
+#define NV_RAMHT_HANDLE_OFFSET                             0
+#define NV_RAMHT_CONTEXT_OFFSET                            4
+#    define NV_RAMHT_CONTEXT_VALID                         (1<<31)
+#    define NV_RAMHT_CONTEXT_CHANNEL_SHIFT                 24
+#    define NV_RAMHT_CONTEXT_ENGINE_SHIFT                  16
+#        define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE           0
+#        define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS           1
+#    define NV_RAMHT_CONTEXT_INSTANCE_SHIFT                0
+#    define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT               23
+#    define NV40_RAMHT_CONTEXT_ENGINE_SHIFT                20
+#    define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT              0
+
+/* DMA object defines */
+#define NV_DMA_ACCESS_RW 0
+#define NV_DMA_ACCESS_RO 1
+#define NV_DMA_ACCESS_WO 2
+#define NV_DMA_TARGET_VIDMEM 0
+#define NV_DMA_TARGET_PCI    2
+#define NV_DMA_TARGET_AGP    3
+/* The following is not a real value used by the card, it's changed by
+ * nouveau_object_dma_create */
+#define NV_DMA_TARGET_PCI_NONLINEAR 8
+
+/* Some object classes we care about in the drm */
+#define NV_CLASS_DMA_FROM_MEMORY                           0x00000002
+#define NV_CLASS_DMA_TO_MEMORY                             0x00000003
+#define NV_CLASS_NULL                                      0x00000030
+#define NV_CLASS_DMA_IN_MEMORY                             0x0000003D
+
+#define NV03_USER(i)                             (0x00800000+(i*NV03_USER_SIZE))
+#define NV03_USER__SIZE                                                       16
+#define NV10_USER__SIZE                                                       32
+#define NV03_USER_SIZE                                                0x00010000
+#define NV03_USER_DMA_PUT(i)                     (0x00800040+(i*NV03_USER_SIZE))
+#define NV03_USER_DMA_PUT__SIZE                                               16
+#define NV10_USER_DMA_PUT__SIZE                                               32
+#define NV03_USER_DMA_GET(i)                     (0x00800044+(i*NV03_USER_SIZE))
+#define NV03_USER_DMA_GET__SIZE                                               16
+#define NV10_USER_DMA_GET__SIZE                                               32
+#define NV03_USER_REF_CNT(i)                     (0x00800048+(i*NV03_USER_SIZE))
+#define NV03_USER_REF_CNT__SIZE                                               16
+#define NV10_USER_REF_CNT__SIZE                                               32
+
+#define NV40_USER(i)                             (0x00c00000+(i*NV40_USER_SIZE))
+#define NV40_USER_SIZE                                                0x00001000
+#define NV40_USER_DMA_PUT(i)                     (0x00c00040+(i*NV40_USER_SIZE))
+#define NV40_USER_DMA_PUT__SIZE                                               32
+#define NV40_USER_DMA_GET(i)                     (0x00c00044+(i*NV40_USER_SIZE))
+#define NV40_USER_DMA_GET__SIZE                                               32
+#define NV40_USER_REF_CNT(i)                     (0x00c00048+(i*NV40_USER_SIZE))
+#define NV40_USER_REF_CNT__SIZE                                               32
+
+#define NV50_USER(i)                             (0x00c00000+(i*NV50_USER_SIZE))
+#define NV50_USER_SIZE                                                0x00002000
+#define NV50_USER_DMA_PUT(i)                     (0x00c00040+(i*NV50_USER_SIZE))
+#define NV50_USER_DMA_PUT__SIZE                                              128
+#define NV50_USER_DMA_GET(i)                     (0x00c00044+(i*NV50_USER_SIZE))
+#define NV50_USER_DMA_GET__SIZE                                              128
+#define NV50_USER_REF_CNT(i)                     (0x00c00048+(i*NV50_USER_SIZE))
+#define NV50_USER_REF_CNT__SIZE                                              128
+
+#define NV03_FIFO_SIZE                                     0x8000UL
+
+#define NV03_PMC_BOOT_0                                    0x00000000
+#define NV03_PMC_BOOT_1                                    0x00000004
+#define NV03_PMC_INTR_0                                    0x00000100
+#    define NV_PMC_INTR_0_PFIFO_PENDING                        (1<<8)
+#    define NV_PMC_INTR_0_PGRAPH_PENDING                      (1<<12)
+#    define NV_PMC_INTR_0_NV50_I2C_PENDING                    (1<<21)
+#    define NV_PMC_INTR_0_CRTC0_PENDING                       (1<<24)
+#    define NV_PMC_INTR_0_CRTC1_PENDING                       (1<<25)
+#    define NV_PMC_INTR_0_NV50_DISPLAY_PENDING                (1<<26)
+#    define NV_PMC_INTR_0_CRTCn_PENDING                       (3<<24)
+#define NV03_PMC_INTR_EN_0                                 0x00000140
+#    define NV_PMC_INTR_EN_0_MASTER_ENABLE                     (1<<0)
+#define NV03_PMC_ENABLE                                    0x00000200
+#    define NV_PMC_ENABLE_PFIFO                                (1<<8)
+#    define NV_PMC_ENABLE_PGRAPH                              (1<<12)
+/* Disabling the below bit breaks newer (G7X only?) mobile chipsets,
+ * the card will hang early on in the X init process.
+ */
+#    define NV_PMC_ENABLE_UNK13                               (1<<13)
+#define NV40_PMC_GRAPH_UNITS				   0x00001540
+#define NV40_PMC_BACKLIGHT				   0x000015f0
+#	define NV40_PMC_BACKLIGHT_MASK			   0x001f0000
+#define NV40_PMC_1700                                      0x00001700
+#define NV40_PMC_1704                                      0x00001704
+#define NV40_PMC_1708                                      0x00001708
+#define NV40_PMC_170C                                      0x0000170C
+
+/* probably PMC ? */
+#define NV50_PUNK_BAR0_PRAMIN                              0x00001700
+#define NV50_PUNK_BAR_CFG_BASE                             0x00001704
+#define NV50_PUNK_BAR_CFG_BASE_VALID                          (1<<30)
+#define NV50_PUNK_BAR1_CTXDMA                              0x00001708
+#define NV50_PUNK_BAR1_CTXDMA_VALID                           (1<<31)
+#define NV50_PUNK_BAR3_CTXDMA                              0x0000170C
+#define NV50_PUNK_BAR3_CTXDMA_VALID                           (1<<31)
+#define NV50_PUNK_UNK1710                                  0x00001710
+
+#define NV04_PBUS_PCI_NV_1                                 0x00001804
+#define NV04_PBUS_PCI_NV_19                                0x0000184C
+#define NV04_PBUS_PCI_NV_20				0x00001850
+#	define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED		(0 << 0)
+#	define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED		(1 << 0)
+
+#define NV04_PTIMER_INTR_0                                 0x00009100
+#define NV04_PTIMER_INTR_EN_0                              0x00009140
+#define NV04_PTIMER_NUMERATOR                              0x00009200
+#define NV04_PTIMER_DENOMINATOR                            0x00009210
+#define NV04_PTIMER_TIME_0                                 0x00009400
+#define NV04_PTIMER_TIME_1                                 0x00009410
+#define NV04_PTIMER_ALARM_0                                0x00009420
+
+#define NV04_PFB_CFG0                                      0x00100200
+#define NV04_PFB_CFG1                                      0x00100204
+#define NV40_PFB_020C                                      0x0010020C
+#define NV10_PFB_TILE(i)                                   (0x00100240 + (i*16))
+#define NV10_PFB_TILE__SIZE                                8
+#define NV10_PFB_TLIMIT(i)                                 (0x00100244 + (i*16))
+#define NV10_PFB_TSIZE(i)                                  (0x00100248 + (i*16))
+#define NV10_PFB_TSTATUS(i)                                (0x0010024C + (i*16))
+#define NV10_PFB_CLOSE_PAGE2                               0x0010033C
+#define NV40_PFB_TILE(i)                                   (0x00100600 + (i*16))
+#define NV40_PFB_TILE__SIZE_0                              12
+#define NV40_PFB_TILE__SIZE_1                              15
+#define NV40_PFB_TLIMIT(i)                                 (0x00100604 + (i*16))
+#define NV40_PFB_TSIZE(i)                                  (0x00100608 + (i*16))
+#define NV40_PFB_TSTATUS(i)                                (0x0010060C + (i*16))
+#define NV40_PFB_UNK_800					0x00100800
+
+#define NV04_PGRAPH_DEBUG_0                                0x00400080
+#define NV04_PGRAPH_DEBUG_1                                0x00400084
+#define NV04_PGRAPH_DEBUG_2                                0x00400088
+#define NV04_PGRAPH_DEBUG_3                                0x0040008c
+#define NV10_PGRAPH_DEBUG_4                                0x00400090
+#define NV03_PGRAPH_INTR                                   0x00400100
+#define NV03_PGRAPH_NSTATUS                                0x00400104
+#    define NV04_PGRAPH_NSTATUS_STATE_IN_USE                  (1<<11)
+#    define NV04_PGRAPH_NSTATUS_INVALID_STATE                 (1<<12)
+#    define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT                  (1<<13)
+#    define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT              (1<<14)
+#    define NV10_PGRAPH_NSTATUS_STATE_IN_USE                  (1<<23)
+#    define NV10_PGRAPH_NSTATUS_INVALID_STATE                 (1<<24)
+#    define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT                  (1<<25)
+#    define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT              (1<<26)
+#define NV03_PGRAPH_NSOURCE                                0x00400108
+#    define NV03_PGRAPH_NSOURCE_NOTIFICATION                   (1<<0)
+#    define NV03_PGRAPH_NSOURCE_DATA_ERROR                     (1<<1)
+#    define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR               (1<<2)
+#    define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION                (1<<3)
+#    define NV03_PGRAPH_NSOURCE_LIMIT_COLOR                    (1<<4)
+#    define NV03_PGRAPH_NSOURCE_LIMIT_ZETA                     (1<<5)
+#    define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD                   (1<<6)
+#    define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION               (1<<7)
+#    define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION               (1<<8)
+#    define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION               (1<<9)
+#    define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION               (1<<10)
+#    define NV03_PGRAPH_NSOURCE_STATE_INVALID                 (1<<11)
+#    define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY                 (1<<12)
+#    define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE                 (1<<13)
+#    define NV03_PGRAPH_NSOURCE_METHOD_CNT                    (1<<14)
+#    define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION              (1<<15)
+#    define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION            (1<<16)
+#    define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A                   (1<<17)
+#    define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B                   (1<<18)
+#define NV03_PGRAPH_INTR_EN                                0x00400140
+#define NV40_PGRAPH_INTR_EN                                0x0040013C
+#    define NV_PGRAPH_INTR_NOTIFY                              (1<<0)
+#    define NV_PGRAPH_INTR_MISSING_HW                          (1<<4)
+#    define NV_PGRAPH_INTR_CONTEXT_SWITCH                     (1<<12)
+#    define NV_PGRAPH_INTR_BUFFER_NOTIFY                      (1<<16)
+#    define NV_PGRAPH_INTR_ERROR                              (1<<20)
+#define NV10_PGRAPH_CTX_CONTROL                            0x00400144
+#define NV10_PGRAPH_CTX_USER                               0x00400148
+#define NV10_PGRAPH_CTX_SWITCH1                            0x0040014C
+#define NV10_PGRAPH_CTX_SWITCH2                            0x00400150
+#define NV10_PGRAPH_CTX_SWITCH3                            0x00400154
+#define NV10_PGRAPH_CTX_SWITCH4                            0x00400158
+#define NV10_PGRAPH_CTX_SWITCH5                            0x0040015C
+#define NV04_PGRAPH_CTX_SWITCH1                            0x00400160
+#define NV10_PGRAPH_CTX_CACHE1                             0x00400160
+#define NV04_PGRAPH_CTX_SWITCH2                            0x00400164
+#define NV04_PGRAPH_CTX_SWITCH3                            0x00400168
+#define NV04_PGRAPH_CTX_SWITCH4                            0x0040016C
+#define NV04_PGRAPH_CTX_CONTROL                            0x00400170
+#define NV04_PGRAPH_CTX_USER                               0x00400174
+#define NV04_PGRAPH_CTX_CACHE1                             0x00400180
+#define NV10_PGRAPH_CTX_CACHE2                             0x00400180
+#define NV03_PGRAPH_CTX_CONTROL                            0x00400190
+#define NV03_PGRAPH_CTX_USER                               0x00400194
+#define NV04_PGRAPH_CTX_CACHE2                             0x004001A0
+#define NV10_PGRAPH_CTX_CACHE3                             0x004001A0
+#define NV04_PGRAPH_CTX_CACHE3                             0x004001C0
+#define NV10_PGRAPH_CTX_CACHE4                             0x004001C0
+#define NV04_PGRAPH_CTX_CACHE4                             0x004001E0
+#define NV10_PGRAPH_CTX_CACHE5                             0x004001E0
+#define NV40_PGRAPH_CTXCTL_0304                            0x00400304
+#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX                   0x00000001
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT                      0x00400308
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK              0xff000000
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT                     24
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK              0x00ffffff
+#define NV40_PGRAPH_CTXCTL_0310                            0x00400310
+#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE                  0x00000020
+#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD                  0x00000040
+#define NV40_PGRAPH_CTXCTL_030C                            0x0040030c
+#define NV40_PGRAPH_CTXCTL_UCODE_INDEX                     0x00400324
+#define NV40_PGRAPH_CTXCTL_UCODE_DATA                      0x00400328
+#define NV40_PGRAPH_CTXCTL_CUR                             0x0040032c
+#define NV40_PGRAPH_CTXCTL_CUR_LOADED                      0x01000000
+#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE                    0x000FFFFF
+#define NV40_PGRAPH_CTXCTL_NEXT                            0x00400330
+#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE                   0x000fffff
+#define NV50_PGRAPH_CTXCTL_CUR                             0x0040032c
+#define NV50_PGRAPH_CTXCTL_CUR_LOADED                      0x80000000
+#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE                    0x00ffffff
+#define NV50_PGRAPH_CTXCTL_NEXT                            0x00400330
+#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE                   0x00ffffff
+#define NV03_PGRAPH_ABS_X_RAM                              0x00400400
+#define NV03_PGRAPH_ABS_Y_RAM                              0x00400480
+#define NV03_PGRAPH_X_MISC                                 0x00400500
+#define NV03_PGRAPH_Y_MISC                                 0x00400504
+#define NV04_PGRAPH_VALID1                                 0x00400508
+#define NV04_PGRAPH_SOURCE_COLOR                           0x0040050C
+#define NV04_PGRAPH_MISC24_0                               0x00400510
+#define NV03_PGRAPH_XY_LOGIC_MISC0                         0x00400514
+#define NV03_PGRAPH_XY_LOGIC_MISC1                         0x00400518
+#define NV03_PGRAPH_XY_LOGIC_MISC2                         0x0040051C
+#define NV03_PGRAPH_XY_LOGIC_MISC3                         0x00400520
+#define NV03_PGRAPH_CLIPX_0                                0x00400524
+#define NV03_PGRAPH_CLIPX_1                                0x00400528
+#define NV03_PGRAPH_CLIPY_0                                0x0040052C
+#define NV03_PGRAPH_CLIPY_1                                0x00400530
+#define NV03_PGRAPH_ABS_ICLIP_XMAX                         0x00400534
+#define NV03_PGRAPH_ABS_ICLIP_YMAX                         0x00400538
+#define NV03_PGRAPH_ABS_UCLIP_XMIN                         0x0040053C
+#define NV03_PGRAPH_ABS_UCLIP_YMIN                         0x00400540
+#define NV03_PGRAPH_ABS_UCLIP_XMAX                         0x00400544
+#define NV03_PGRAPH_ABS_UCLIP_YMAX                         0x00400548
+#define NV03_PGRAPH_ABS_UCLIPA_XMIN                        0x00400560
+#define NV03_PGRAPH_ABS_UCLIPA_YMIN                        0x00400564
+#define NV03_PGRAPH_ABS_UCLIPA_XMAX                        0x00400568
+#define NV03_PGRAPH_ABS_UCLIPA_YMAX                        0x0040056C
+#define NV04_PGRAPH_MISC24_1                               0x00400570
+#define NV04_PGRAPH_MISC24_2                               0x00400574
+#define NV04_PGRAPH_VALID2                                 0x00400578
+#define NV04_PGRAPH_PASSTHRU_0                             0x0040057C
+#define NV04_PGRAPH_PASSTHRU_1                             0x00400580
+#define NV04_PGRAPH_PASSTHRU_2                             0x00400584
+#define NV10_PGRAPH_DIMX_TEXTURE                           0x00400588
+#define NV10_PGRAPH_WDIMX_TEXTURE                          0x0040058C
+#define NV04_PGRAPH_COMBINE_0_ALPHA                        0x00400590
+#define NV04_PGRAPH_COMBINE_0_COLOR                        0x00400594
+#define NV04_PGRAPH_COMBINE_1_ALPHA                        0x00400598
+#define NV04_PGRAPH_COMBINE_1_COLOR                        0x0040059C
+#define NV04_PGRAPH_FORMAT_0                               0x004005A8
+#define NV04_PGRAPH_FORMAT_1                               0x004005AC
+#define NV04_PGRAPH_FILTER_0                               0x004005B0
+#define NV04_PGRAPH_FILTER_1                               0x004005B4
+#define NV03_PGRAPH_MONO_COLOR0                            0x00400600
+#define NV04_PGRAPH_ROP3                                   0x00400604
+#define NV04_PGRAPH_BETA_AND                               0x00400608
+#define NV04_PGRAPH_BETA_PREMULT                           0x0040060C
+#define NV04_PGRAPH_LIMIT_VIOL_PIX                         0x00400610
+#define NV04_PGRAPH_FORMATS                                0x00400618
+#define NV10_PGRAPH_DEBUG_2                                0x00400620
+#define NV04_PGRAPH_BOFFSET0                               0x00400640
+#define NV04_PGRAPH_BOFFSET1                               0x00400644
+#define NV04_PGRAPH_BOFFSET2                               0x00400648
+#define NV04_PGRAPH_BOFFSET3                               0x0040064C
+#define NV04_PGRAPH_BOFFSET4                               0x00400650
+#define NV04_PGRAPH_BOFFSET5                               0x00400654
+#define NV04_PGRAPH_BBASE0                                 0x00400658
+#define NV04_PGRAPH_BBASE1                                 0x0040065C
+#define NV04_PGRAPH_BBASE2                                 0x00400660
+#define NV04_PGRAPH_BBASE3                                 0x00400664
+#define NV04_PGRAPH_BBASE4                                 0x00400668
+#define NV04_PGRAPH_BBASE5                                 0x0040066C
+#define NV04_PGRAPH_BPITCH0                                0x00400670
+#define NV04_PGRAPH_BPITCH1                                0x00400674
+#define NV04_PGRAPH_BPITCH2                                0x00400678
+#define NV04_PGRAPH_BPITCH3                                0x0040067C
+#define NV04_PGRAPH_BPITCH4                                0x00400680
+#define NV04_PGRAPH_BLIMIT0                                0x00400684
+#define NV04_PGRAPH_BLIMIT1                                0x00400688
+#define NV04_PGRAPH_BLIMIT2                                0x0040068C
+#define NV04_PGRAPH_BLIMIT3                                0x00400690
+#define NV04_PGRAPH_BLIMIT4                                0x00400694
+#define NV04_PGRAPH_BLIMIT5                                0x00400698
+#define NV04_PGRAPH_BSWIZZLE2                              0x0040069C
+#define NV04_PGRAPH_BSWIZZLE5                              0x004006A0
+#define NV03_PGRAPH_STATUS                                 0x004006B0
+#define NV04_PGRAPH_STATUS                                 0x00400700
+#define NV04_PGRAPH_TRAPPED_ADDR                           0x00400704
+#define NV04_PGRAPH_TRAPPED_DATA                           0x00400708
+#define NV04_PGRAPH_SURFACE                                0x0040070C
+#define NV10_PGRAPH_TRAPPED_DATA_HIGH                      0x0040070C
+#define NV04_PGRAPH_STATE                                  0x00400710
+#define NV10_PGRAPH_SURFACE                                0x00400710
+#define NV04_PGRAPH_NOTIFY                                 0x00400714
+#define NV10_PGRAPH_STATE                                  0x00400714
+#define NV10_PGRAPH_NOTIFY                                 0x00400718
+
+#define NV04_PGRAPH_FIFO                                   0x00400720
+
+#define NV04_PGRAPH_BPIXEL                                 0x00400724
+#define NV10_PGRAPH_RDI_INDEX                              0x00400750
+#define NV04_PGRAPH_FFINTFC_ST2                            0x00400754
+#define NV10_PGRAPH_RDI_DATA                               0x00400754
+#define NV04_PGRAPH_DMA_PITCH                              0x00400760
+#define NV10_PGRAPH_FFINTFC_ST2                            0x00400764
+#define NV04_PGRAPH_DVD_COLORFMT                           0x00400764
+#define NV04_PGRAPH_SCALED_FORMAT                          0x00400768
+#define NV10_PGRAPH_DMA_PITCH                              0x00400770
+#define NV10_PGRAPH_DVD_COLORFMT                           0x00400774
+#define NV10_PGRAPH_SCALED_FORMAT                          0x00400778
+#define NV20_PGRAPH_CHANNEL_CTX_TABLE                      0x00400780
+#define NV20_PGRAPH_CHANNEL_CTX_POINTER                    0x00400784
+#define NV20_PGRAPH_CHANNEL_CTX_XFER                       0x00400788
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD                  0x00000001
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE                  0x00000002
+#define NV04_PGRAPH_PATT_COLOR0                            0x00400800
+#define NV04_PGRAPH_PATT_COLOR1                            0x00400804
+#define NV04_PGRAPH_PATTERN                                0x00400808
+#define NV04_PGRAPH_PATTERN_SHAPE                          0x00400810
+#define NV04_PGRAPH_CHROMA                                 0x00400814
+#define NV04_PGRAPH_CONTROL0                               0x00400818
+#define NV04_PGRAPH_CONTROL1                               0x0040081C
+#define NV04_PGRAPH_CONTROL2                               0x00400820
+#define NV04_PGRAPH_BLEND                                  0x00400824
+#define NV04_PGRAPH_STORED_FMT                             0x00400830
+#define NV04_PGRAPH_PATT_COLORRAM                          0x00400900
+#define NV20_PGRAPH_TILE(i)                                (0x00400900 + (i*16))
+#define NV20_PGRAPH_TLIMIT(i)                              (0x00400904 + (i*16))
+#define NV20_PGRAPH_TSIZE(i)                               (0x00400908 + (i*16))
+#define NV20_PGRAPH_TSTATUS(i)                             (0x0040090C + (i*16))
+#define NV10_PGRAPH_TILE(i)                                (0x00400B00 + (i*16))
+#define NV10_PGRAPH_TLIMIT(i)                              (0x00400B04 + (i*16))
+#define NV10_PGRAPH_TSIZE(i)                               (0x00400B08 + (i*16))
+#define NV10_PGRAPH_TSTATUS(i)                             (0x00400B0C + (i*16))
+#define NV04_PGRAPH_U_RAM                                  0x00400D00
+#define NV47_PGRAPH_TILE(i)                                (0x00400D00 + (i*16))
+#define NV47_PGRAPH_TLIMIT(i)                              (0x00400D04 + (i*16))
+#define NV47_PGRAPH_TSIZE(i)                               (0x00400D08 + (i*16))
+#define NV47_PGRAPH_TSTATUS(i)                             (0x00400D0C + (i*16))
+#define NV04_PGRAPH_V_RAM                                  0x00400D40
+#define NV04_PGRAPH_W_RAM                                  0x00400D80
+#define NV10_PGRAPH_COMBINER0_IN_ALPHA                     0x00400E40
+#define NV10_PGRAPH_COMBINER1_IN_ALPHA                     0x00400E44
+#define NV10_PGRAPH_COMBINER0_IN_RGB                       0x00400E48
+#define NV10_PGRAPH_COMBINER1_IN_RGB                       0x00400E4C
+#define NV10_PGRAPH_COMBINER_COLOR0                        0x00400E50
+#define NV10_PGRAPH_COMBINER_COLOR1                        0x00400E54
+#define NV10_PGRAPH_COMBINER0_OUT_ALPHA                    0x00400E58
+#define NV10_PGRAPH_COMBINER1_OUT_ALPHA                    0x00400E5C
+#define NV10_PGRAPH_COMBINER0_OUT_RGB                      0x00400E60
+#define NV10_PGRAPH_COMBINER1_OUT_RGB                      0x00400E64
+#define NV10_PGRAPH_COMBINER_FINAL0                        0x00400E68
+#define NV10_PGRAPH_COMBINER_FINAL1                        0x00400E6C
+#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL                  0x00400F00
+#define NV10_PGRAPH_WINDOWCLIP_VERTICAL                    0x00400F20
+#define NV10_PGRAPH_XFMODE0                                0x00400F40
+#define NV10_PGRAPH_XFMODE1                                0x00400F44
+#define NV10_PGRAPH_GLOBALSTATE0                           0x00400F48
+#define NV10_PGRAPH_GLOBALSTATE1                           0x00400F4C
+#define NV10_PGRAPH_PIPE_ADDRESS                           0x00400F50
+#define NV10_PGRAPH_PIPE_DATA                              0x00400F54
+#define NV04_PGRAPH_DMA_START_0                            0x00401000
+#define NV04_PGRAPH_DMA_START_1                            0x00401004
+#define NV04_PGRAPH_DMA_LENGTH                             0x00401008
+#define NV04_PGRAPH_DMA_MISC                               0x0040100C
+#define NV04_PGRAPH_DMA_DATA_0                             0x00401020
+#define NV04_PGRAPH_DMA_DATA_1                             0x00401024
+#define NV04_PGRAPH_DMA_RM                                 0x00401030
+#define NV04_PGRAPH_DMA_A_XLATE_INST                       0x00401040
+#define NV04_PGRAPH_DMA_A_CONTROL                          0x00401044
+#define NV04_PGRAPH_DMA_A_LIMIT                            0x00401048
+#define NV04_PGRAPH_DMA_A_TLB_PTE                          0x0040104C
+#define NV04_PGRAPH_DMA_A_TLB_TAG                          0x00401050
+#define NV04_PGRAPH_DMA_A_ADJ_OFFSET                       0x00401054
+#define NV04_PGRAPH_DMA_A_OFFSET                           0x00401058
+#define NV04_PGRAPH_DMA_A_SIZE                             0x0040105C
+#define NV04_PGRAPH_DMA_A_Y_SIZE                           0x00401060
+#define NV04_PGRAPH_DMA_B_XLATE_INST                       0x00401080
+#define NV04_PGRAPH_DMA_B_CONTROL                          0x00401084
+#define NV04_PGRAPH_DMA_B_LIMIT                            0x00401088
+#define NV04_PGRAPH_DMA_B_TLB_PTE                          0x0040108C
+#define NV04_PGRAPH_DMA_B_TLB_TAG                          0x00401090
+#define NV04_PGRAPH_DMA_B_ADJ_OFFSET                       0x00401094
+#define NV04_PGRAPH_DMA_B_OFFSET                           0x00401098
+#define NV04_PGRAPH_DMA_B_SIZE                             0x0040109C
+#define NV04_PGRAPH_DMA_B_Y_SIZE                           0x004010A0
+#define NV40_PGRAPH_TILE1(i)                               (0x00406900 + (i*16))
+#define NV40_PGRAPH_TLIMIT1(i)                             (0x00406904 + (i*16))
+#define NV40_PGRAPH_TSIZE1(i)                              (0x00406908 + (i*16))
+#define NV40_PGRAPH_TSTATUS1(i)                            (0x0040690C + (i*16))
+
+
+/* It's a guess that this works on NV03. Confirmed on NV04, though */
+#define NV04_PFIFO_DELAY_0                                 0x00002040
+#define NV04_PFIFO_DMA_TIMESLICE                           0x00002044
+#define NV04_PFIFO_NEXT_CHANNEL                            0x00002050
+#define NV03_PFIFO_INTR_0                                  0x00002100
+#define NV03_PFIFO_INTR_EN_0                               0x00002140
+#    define NV_PFIFO_INTR_CACHE_ERROR                          (1<<0)
+#    define NV_PFIFO_INTR_RUNOUT                               (1<<4)
+#    define NV_PFIFO_INTR_RUNOUT_OVERFLOW                      (1<<8)
+#    define NV_PFIFO_INTR_DMA_PUSHER                          (1<<12)
+#    define NV_PFIFO_INTR_DMA_PT                              (1<<16)
+#    define NV_PFIFO_INTR_SEMAPHORE                           (1<<20)
+#    define NV_PFIFO_INTR_ACQUIRE_TIMEOUT                     (1<<24)
+#define NV03_PFIFO_RAMHT                                   0x00002210
+#define NV03_PFIFO_RAMFC                                   0x00002214
+#define NV03_PFIFO_RAMRO                                   0x00002218
+#define NV40_PFIFO_RAMFC                                   0x00002220
+#define NV03_PFIFO_CACHES                                  0x00002500
+#define NV04_PFIFO_MODE                                    0x00002504
+#define NV04_PFIFO_DMA                                     0x00002508
+#define NV04_PFIFO_SIZE                                    0x0000250c
+#define NV50_PFIFO_CTX_TABLE(c)                        (0x2600+(c)*4)
+#define NV50_PFIFO_CTX_TABLE__SIZE                                128
+#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED                  (1<<31)
+#define NV50_PFIFO_CTX_TABLE_UNK30_BAD                        (1<<30)
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80             0x0FFFFFFF
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84             0x00FFFFFF
+#define NV03_PFIFO_CACHE0_PUSH0                            0x00003000
+#define NV03_PFIFO_CACHE0_PULL0                            0x00003040
+#define NV04_PFIFO_CACHE0_PULL0                            0x00003050
+#define NV04_PFIFO_CACHE0_PULL1                            0x00003054
+#define NV03_PFIFO_CACHE1_PUSH0                            0x00003200
+#define NV03_PFIFO_CACHE1_PUSH1                            0x00003204
+#define NV03_PFIFO_CACHE1_PUSH1_DMA                            (1<<8)
+#define NV40_PFIFO_CACHE1_PUSH1_DMA                           (1<<16)
+#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000000f
+#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000001f
+#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK                  0x0000007f
+#define NV03_PFIFO_CACHE1_PUT                              0x00003210
+#define NV04_PFIFO_CACHE1_DMA_PUSH                         0x00003220
+#define NV04_PFIFO_CACHE1_DMA_FETCH                        0x00003224
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES         0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES        0x00000008
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES        0x00000010
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES        0x00000018
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES        0x00000020
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES        0x00000028
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES        0x00000030
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES        0x00000038
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES        0x00000040
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES        0x00000048
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES        0x00000050
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES        0x00000058
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES       0x00000060
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES       0x00000068
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES       0x00000070
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES       0x00000078
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES       0x00000080
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES       0x00000088
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES       0x00000090
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES       0x00000098
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES       0x000000A0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES       0x000000A8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES       0x000000B0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES       0x000000B8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES       0x000000C0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES       0x000000C8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES       0x000000D0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES       0x000000D8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES       0x000000E0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES       0x000000E8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES       0x000000F0
+#    define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES       0x000000F8
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE                 0x0000E000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES        0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES        0x00002000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES        0x00004000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES       0x00006000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES       0x00008000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES       0x0000A000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES       0x0000C000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES       0x0000E000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS             0x001F0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0           0x00000000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1           0x00010000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2           0x00020000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3           0x00030000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4           0x00040000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5           0x00050000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6           0x00060000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7           0x00070000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8           0x00080000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9           0x00090000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10          0x000A0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11          0x000B0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12          0x000C0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13          0x000D0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14          0x000E0000
+#    define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15          0x000F0000
+#    define NV_PFIFO_CACHE1_ENDIAN                         0x80000000
+#    define NV_PFIFO_CACHE1_LITTLE_ENDIAN                  0x7FFFFFFF
+#    define NV_PFIFO_CACHE1_BIG_ENDIAN                     0x80000000
+#define NV04_PFIFO_CACHE1_DMA_STATE                        0x00003228
+#define NV04_PFIFO_CACHE1_DMA_INSTANCE                     0x0000322c
+#define NV04_PFIFO_CACHE1_DMA_CTL                          0x00003230
+#define NV04_PFIFO_CACHE1_DMA_PUT                          0x00003240
+#define NV04_PFIFO_CACHE1_DMA_GET                          0x00003244
+#define NV10_PFIFO_CACHE1_REF_CNT                          0x00003248
+#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE                   0x0000324C
+#define NV03_PFIFO_CACHE1_PULL0                            0x00003240
+#define NV04_PFIFO_CACHE1_PULL0                            0x00003250
+#define NV03_PFIFO_CACHE1_PULL1                            0x00003250
+#define NV04_PFIFO_CACHE1_PULL1                            0x00003254
+#define NV04_PFIFO_CACHE1_HASH                             0x00003258
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT                  0x00003260
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP                0x00003264
+#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE                    0x00003268
+#define NV10_PFIFO_CACHE1_SEMAPHORE                        0x0000326C
+#define NV03_PFIFO_CACHE1_GET                              0x00003270
+#define NV04_PFIFO_CACHE1_ENGINE                           0x00003280
+#define NV04_PFIFO_CACHE1_DMA_DCOUNT                       0x000032A0
+#define NV40_PFIFO_GRCTX_INSTANCE                          0x000032E0
+#define NV40_PFIFO_UNK32E4                                 0x000032E4
+#define NV04_PFIFO_CACHE1_METHOD(i)                (0x00003800+(i*8))
+#define NV04_PFIFO_CACHE1_DATA(i)                  (0x00003804+(i*8))
+#define NV40_PFIFO_CACHE1_METHOD(i)                (0x00090000+(i*8))
+#define NV40_PFIFO_CACHE1_DATA(i)                  (0x00090004+(i*8))
+
+#define NV_CRTC0_INTSTAT                                   0x00600100
+#define NV_CRTC0_INTEN                                     0x00600140
+#define NV_CRTC1_INTSTAT                                   0x00602100
+#define NV_CRTC1_INTEN                                     0x00602140
+#    define NV_CRTC_INTR_VBLANK                                (1<<0)
+
+#define NV04_PRAMIN						0x00700000
+
+/* Fifo commands. These are not regs, neither masks */
+#define NV03_FIFO_CMD_JUMP                                 0x20000000
+#define NV03_FIFO_CMD_JUMP_OFFSET_MASK                     0x1ffffffc
+#define NV03_FIFO_CMD_REWIND                               (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))
+
+/* This is a partial import from rules-ng, a few things may be duplicated.
+ * Eventually we should completely import everything from rules-ng.
+ * For the moment check rules-ng for docs.
+  */
+
+#define NV50_PMC                                            0x00000000
+#define NV50_PMC__LEN                                              0x1
+#define NV50_PMC__ESIZE                                         0x2000
+#    define NV50_PMC_BOOT_0                                 0x00000000
+#        define NV50_PMC_BOOT_0_REVISION                    0x000000ff
+#        define NV50_PMC_BOOT_0_REVISION__SHIFT                      0
+#        define NV50_PMC_BOOT_0_ARCH                        0x0ff00000
+#        define NV50_PMC_BOOT_0_ARCH__SHIFT                         20
+#    define NV50_PMC_INTR_0                                 0x00000100
+#        define NV50_PMC_INTR_0_PFIFO                           (1<<8)
+#        define NV50_PMC_INTR_0_PGRAPH                         (1<<12)
+#        define NV50_PMC_INTR_0_PTIMER                         (1<<20)
+#        define NV50_PMC_INTR_0_HOTPLUG                        (1<<21)
+#        define NV50_PMC_INTR_0_DISPLAY                        (1<<26)
+#    define NV50_PMC_INTR_EN_0                              0x00000140
+#        define NV50_PMC_INTR_EN_0_MASTER                       (1<<0)
+#            define NV50_PMC_INTR_EN_0_MASTER_DISABLED          (0<<0)
+#            define NV50_PMC_INTR_EN_0_MASTER_ENABLED           (1<<0)
+#    define NV50_PMC_ENABLE                                 0x00000200
+#        define NV50_PMC_ENABLE_PFIFO                           (1<<8)
+#        define NV50_PMC_ENABLE_PGRAPH                         (1<<12)
+
+#define NV50_PCONNECTOR                                     0x0000e000
+#define NV50_PCONNECTOR__LEN                                       0x1
+#define NV50_PCONNECTOR__ESIZE                                  0x1000
+#    define NV50_PCONNECTOR_HOTPLUG_INTR                    0x0000e050
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0          (1<<0)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1          (1<<1)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2          (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3          (1<<3)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0       (1<<16)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1       (1<<17)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2       (1<<18)
+#        define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3       (1<<19)
+#    define NV50_PCONNECTOR_HOTPLUG_CTRL                    0x0000e054
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0          (1<<0)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1          (1<<1)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2          (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3          (1<<3)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0       (1<<16)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1       (1<<17)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2       (1<<18)
+#        define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3       (1<<19)
+#    define NV50_PCONNECTOR_HOTPLUG_STATE                   0x0000e104
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10)
+#        define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14)
+#    define NV50_PCONNECTOR_I2C_PORT_0                      0x0000e138
+#    define NV50_PCONNECTOR_I2C_PORT_1                      0x0000e150
+#    define NV50_PCONNECTOR_I2C_PORT_2                      0x0000e168
+#    define NV50_PCONNECTOR_I2C_PORT_3                      0x0000e180
+#    define NV50_PCONNECTOR_I2C_PORT_4                      0x0000e240
+#    define NV50_PCONNECTOR_I2C_PORT_5                      0x0000e258
+
+#define NV50_AUXCH_DATA_OUT(i,n)             ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
+#define NV50_AUXCH_DATA_OUT__SIZE                                             4
+#define NV50_AUXCH_DATA_IN(i,n)              ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
+#define NV50_AUXCH_DATA_IN__SIZE                                              4
+#define NV50_AUXCH_ADDR(i)                             ((i) * 0x50 + 0x0000e4e0)
+#define NV50_AUXCH_CTRL(i)                             ((i) * 0x50 + 0x0000e4e4)
+#define NV50_AUXCH_CTRL_LINKSTAT                                     0x01000000
+#define NV50_AUXCH_CTRL_LINKSTAT_NOT_READY                           0x00000000
+#define NV50_AUXCH_CTRL_LINKSTAT_READY                               0x01000000
+#define NV50_AUXCH_CTRL_LINKEN                                       0x00100000
+#define NV50_AUXCH_CTRL_LINKEN_DISABLED                              0x00000000
+#define NV50_AUXCH_CTRL_LINKEN_ENABLED                               0x00100000
+#define NV50_AUXCH_CTRL_EXEC                                         0x00010000
+#define NV50_AUXCH_CTRL_EXEC_COMPLETE                                0x00000000
+#define NV50_AUXCH_CTRL_EXEC_IN_PROCESS                              0x00010000
+#define NV50_AUXCH_CTRL_CMD                                          0x0000f000
+#define NV50_AUXCH_CTRL_CMD_SHIFT                                            12
+#define NV50_AUXCH_CTRL_LEN                                          0x0000000f
+#define NV50_AUXCH_CTRL_LEN_SHIFT                                             0
+#define NV50_AUXCH_STAT(i)                             ((i) * 0x50 + 0x0000e4e8)
+#define NV50_AUXCH_STAT_STATE                                        0x10000000
+#define NV50_AUXCH_STAT_STATE_NOT_READY                              0x00000000
+#define NV50_AUXCH_STAT_STATE_READY                                  0x10000000
+#define NV50_AUXCH_STAT_REPLY                                        0x000f0000
+#define NV50_AUXCH_STAT_REPLY_AUX                                    0x00030000
+#define NV50_AUXCH_STAT_REPLY_AUX_ACK                                0x00000000
+#define NV50_AUXCH_STAT_REPLY_AUX_NACK                               0x00010000
+#define NV50_AUXCH_STAT_REPLY_AUX_DEFER                              0x00020000
+#define NV50_AUXCH_STAT_REPLY_I2C                                    0x000c0000
+#define NV50_AUXCH_STAT_REPLY_I2C_ACK                                0x00000000
+#define NV50_AUXCH_STAT_REPLY_I2C_NACK                               0x00040000
+#define NV50_AUXCH_STAT_REPLY_I2C_DEFER                              0x00080000
+#define NV50_AUXCH_STAT_COUNT                                        0x0000001f
+
+#define NV50_PBUS                                           0x00088000
+#define NV50_PBUS__LEN                                             0x1
+#define NV50_PBUS__ESIZE                                        0x1000
+#    define NV50_PBUS_PCI_ID                                0x00088000
+#        define NV50_PBUS_PCI_ID_VENDOR_ID                  0x0000ffff
+#        define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT                    0
+#        define NV50_PBUS_PCI_ID_DEVICE_ID                  0xffff0000
+#        define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT                   16
+
+#define NV50_PFB                                            0x00100000
+#define NV50_PFB__LEN                                              0x1
+#define NV50_PFB__ESIZE                                         0x1000
+
+#define NV50_PEXTDEV                                        0x00101000
+#define NV50_PEXTDEV__LEN                                          0x1
+#define NV50_PEXTDEV__ESIZE                                     0x1000
+
+#define NV50_PROM                                           0x00300000
+#define NV50_PROM__LEN                                             0x1
+#define NV50_PROM__ESIZE                                       0x10000
+
+#define NV50_PGRAPH                                         0x00400000
+#define NV50_PGRAPH__LEN                                           0x1
+#define NV50_PGRAPH__ESIZE                                     0x10000
+
+#define NV50_PDISPLAY                                                0x00610000
+#define NV50_PDISPLAY_OBJECTS                                        0x00610010
+#define NV50_PDISPLAY_INTR_0                                         0x00610020
+#define NV50_PDISPLAY_INTR_1                                         0x00610024
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC                             0x0000000c
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_SHIFT                                2
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(n)                   (1 << ((n) + 2))
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0                           0x00000004
+#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1                           0x00000008
+#define NV50_PDISPLAY_INTR_1_CLK_UNK10                               0x00000010
+#define NV50_PDISPLAY_INTR_1_CLK_UNK20                               0x00000020
+#define NV50_PDISPLAY_INTR_1_CLK_UNK40                               0x00000040
+#define NV50_PDISPLAY_INTR_EN                                        0x0061002c
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC                            0x0000000c
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n)                   (1 << ((n) + 2))
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0                          0x00000004
+#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1                          0x00000008
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK10                              0x00000010
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK20                              0x00000020
+#define NV50_PDISPLAY_INTR_EN_CLK_UNK40                              0x00000040
+#define NV50_PDISPLAY_UNK30_CTRL                                     0x00610030
+#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0                        0x00000200
+#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1                        0x00000400
+#define NV50_PDISPLAY_UNK30_CTRL_PENDING                             0x80000000
+#define NV50_PDISPLAY_TRAPPED_ADDR                                   0x00610080
+#define NV50_PDISPLAY_TRAPPED_DATA                                   0x00610084
+#define NV50_PDISPLAY_CHANNEL_STAT(i)                  ((i) * 0x10 + 0x00610200)
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA                               0x00000010
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA_DISABLED                      0x00000000
+#define NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED                       0x00000010
+#define NV50_PDISPLAY_CHANNEL_DMA_CB(i)                ((i) * 0x10 + 0x00610204)
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION                        0x00000002
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM                   0x00000000
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_SYSTEM                 0x00000002
+#define NV50_PDISPLAY_CHANNEL_DMA_CB_VALID                           0x00000001
+#define NV50_PDISPLAY_CHANNEL_UNK2(i)                  ((i) * 0x10 + 0x00610208)
+#define NV50_PDISPLAY_CHANNEL_UNK3(i)                  ((i) * 0x10 + 0x0061020c)
+
+#define NV50_PDISPLAY_CURSOR                                         0x00610270
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)           ((i) * 0x10 + 0x00610270)
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON                         0x00000001
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS                     0x00030000
+#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE              0x00010000
+
+#define NV50_PDISPLAY_CTRL_STATE                                     0x00610300
+#define NV50_PDISPLAY_CTRL_STATE_PENDING                             0x80000000
+#define NV50_PDISPLAY_CTRL_STATE_METHOD                              0x00001ffc
+#define NV50_PDISPLAY_CTRL_STATE_ENABLE                              0x00000001
+#define NV50_PDISPLAY_CTRL_VAL                                       0x00610304
+#define NV50_PDISPLAY_UNK_380                                        0x00610380
+#define NV50_PDISPLAY_RAM_AMOUNT                                     0x00610384
+#define NV50_PDISPLAY_UNK_388                                        0x00610388
+#define NV50_PDISPLAY_UNK_38C                                        0x0061038c
+
+#define NV50_PDISPLAY_CRTC_P(i, r)        ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r)
+#define NV50_PDISPLAY_CRTC_C(i, r)    (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r)
+#define NV50_PDISPLAY_CRTC_UNK_0A18 /* mthd 0x0900 */                0x00610a18
+#define NV50_PDISPLAY_CRTC_CLUT_MODE                                 0x00610a24
+#define NV50_PDISPLAY_CRTC_INTERLACE                                 0x00610a48
+#define NV50_PDISPLAY_CRTC_SCALE_CTRL                                0x00610a50
+#define NV50_PDISPLAY_CRTC_CURSOR_CTRL                               0x00610a58
+#define NV50_PDISPLAY_CRTC_UNK0A78 /* mthd 0x0904 */                 0x00610a78
+#define NV50_PDISPLAY_CRTC_UNK0AB8                                   0x00610ab8
+#define NV50_PDISPLAY_CRTC_DEPTH                                     0x00610ac8
+#define NV50_PDISPLAY_CRTC_CLOCK                                     0x00610ad0
+#define NV50_PDISPLAY_CRTC_COLOR_CTRL                                0x00610ae0
+#define NV50_PDISPLAY_CRTC_SYNC_START_TO_BLANK_END                   0x00610ae8
+#define NV50_PDISPLAY_CRTC_MODE_UNK1                                 0x00610af0
+#define NV50_PDISPLAY_CRTC_DISPLAY_TOTAL                             0x00610af8
+#define NV50_PDISPLAY_CRTC_SYNC_DURATION                             0x00610b00
+#define NV50_PDISPLAY_CRTC_MODE_UNK2                                 0x00610b08
+#define NV50_PDISPLAY_CRTC_UNK_0B10 /* mthd 0x0828 */                0x00610b10
+#define NV50_PDISPLAY_CRTC_FB_SIZE                                   0x00610b18
+#define NV50_PDISPLAY_CRTC_FB_PITCH                                  0x00610b20
+#define NV50_PDISPLAY_CRTC_FB_PITCH_LINEAR                           0x00100000
+#define NV50_PDISPLAY_CRTC_FB_POS                                    0x00610b28
+#define NV50_PDISPLAY_CRTC_SCALE_CENTER_OFFSET                       0x00610b38
+#define NV50_PDISPLAY_CRTC_REAL_RES                                  0x00610b40
+#define NV50_PDISPLAY_CRTC_SCALE_RES1                                0x00610b48
+#define NV50_PDISPLAY_CRTC_SCALE_RES2                                0x00610b50
+
+#define NV50_PDISPLAY_DAC_MODE_CTRL_P(i)                (0x00610b58 + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL_C(i)                (0x00610b5c + (i) * 0x8)
+#define NV50_PDISPLAY_SOR_MODE_CTRL_P(i)                (0x00610b70 + (i) * 0x8)
+#define NV50_PDISPLAY_SOR_MODE_CTRL_C(i)                (0x00610b74 + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL2_P(i)               (0x00610bdc + (i) * 0x8)
+#define NV50_PDISPLAY_DAC_MODE_CTRL2_C(i)               (0x00610be0 + (i) * 0x8)
+
+#define NV90_PDISPLAY_SOR_MODE_CTRL_P(i)                (0x00610794 + (i) * 0x8)
+#define NV90_PDISPLAY_SOR_MODE_CTRL_C(i)                (0x00610798 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL_P(i)                (0x00610b58 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL_C(i)                (0x00610b5c + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL2_P(i)               (0x00610b80 + (i) * 0x8)
+#define NV90_PDISPLAY_DAC_MODE_CTRL2_C(i)               (0x00610b84 + (i) * 0x8)
+
+#define NV50_PDISPLAY_CRTC_CLK                                       0x00614000
+#define NV50_PDISPLAY_CRTC_CLK_CTRL1(i)                 ((i) * 0x800 + 0x614100)
+#define NV50_PDISPLAY_CRTC_CLK_CTRL1_CONNECTED                       0x00000600
+#define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i)                ((i) * 0x800 + 0x614104)
+#define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i)                ((i) * 0x800 + 0x614108)
+#define NV50_PDISPLAY_CRTC_CLK_CTRL2(i)                 ((i) * 0x800 + 0x614200)
+
+#define NV50_PDISPLAY_DAC_CLK                                        0x00614000
+#define NV50_PDISPLAY_DAC_CLK_CTRL2(i)                  ((i) * 0x800 + 0x614280)
+
+#define NV50_PDISPLAY_SOR_CLK                                        0x00614000
+#define NV50_PDISPLAY_SOR_CLK_CTRL2(i)                  ((i) * 0x800 + 0x614300)
+
+#define NV50_PDISPLAY_VGACRTC(r)                                ((r) + 0x619400)
+
+#define NV50_PDISPLAY_DAC                                            0x0061a000
+#define NV50_PDISPLAY_DAC_DPMS_CTRL(i)                (0x0061a004 + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF                        0x00000001
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF                        0x00000004
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED                          0x00000010
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_OFF                              0x00000040
+#define NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING                          0x80000000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL(i)                (0x0061a00c + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE                           0x00100000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT                          0x38000000
+#define NV50_PDISPLAY_DAC_LOAD_CTRL_DONE                             0x80000000
+#define NV50_PDISPLAY_DAC_CLK_CTRL1(i)                (0x0061a010 + (i) * 0x800)
+#define NV50_PDISPLAY_DAC_CLK_CTRL1_CONNECTED                        0x00000600
+
+#define NV50_PDISPLAY_SOR                                            0x0061c000
+#define NV50_PDISPLAY_SOR_DPMS_CTRL(i)                (0x0061c004 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING                          0x80000000
+#define NV50_PDISPLAY_SOR_DPMS_CTRL_ON                               0x00000001
+#define NV50_PDISPLAY_SOR_CLK_CTRL1(i)                (0x0061c008 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_CLK_CTRL1_CONNECTED                        0x00000600
+#define NV50_PDISPLAY_SOR_DPMS_STATE(i)               (0x0061c030 + (i) * 0x800)
+#define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE                          0x00030000
+#define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED                         0x00080000
+#define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT                            0x10000000
+#define NV50_PDISPLAY_SOR_BACKLIGHT                                  0x0061c084
+#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE                           0x80000000
+#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL                            0x00000fff
+#define NV50_SOR_DP_CTRL(i,l)            (0x0061c10c + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED                      0x00004000
+#define NV50_SOR_DP_CTRL_LANE_MASK                                   0x001f0000
+#define NV50_SOR_DP_CTRL_LANE_0_ENABLED                              0x00010000
+#define NV50_SOR_DP_CTRL_LANE_1_ENABLED                              0x00020000
+#define NV50_SOR_DP_CTRL_LANE_2_ENABLED                              0x00040000
+#define NV50_SOR_DP_CTRL_LANE_3_ENABLED                              0x00080000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN                            0x0f000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED                   0x00000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1                          0x01000000
+#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2                          0x02000000
+#define NV50_SOR_DP_UNK118(i,l)          (0x0061c118 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK120(i,l)          (0x0061c120 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK130(i,l)          (0x0061c130 + (i) * 0x800 + (l) * 0x80)
+
+#define NV50_PDISPLAY_USER(i)                        ((i) * 0x1000 + 0x00640000)
+#define NV50_PDISPLAY_USER_PUT(i)                    ((i) * 0x1000 + 0x00640000)
+#define NV50_PDISPLAY_USER_GET(i)                    ((i) * 0x1000 + 0x00640004)
+
+#define NV50_PDISPLAY_CURSOR_USER                                    0x00647000
+#define NV50_PDISPLAY_CURSOR_USER_POS_CTRL(i)        ((i) * 0x1000 + 0x00647080)
+#define NV50_PDISPLAY_CURSOR_USER_POS(i)             ((i) * 0x1000 + 0x00647084)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_sgdma.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,322 @@
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include <linux/pagemap.h>
+
+#define NV_CTXDMA_PAGE_SHIFT 12
+#define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT)
+#define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)
+
+struct nouveau_sgdma_be {
+	struct ttm_backend backend;
+	struct drm_device *dev;
+
+	dma_addr_t *pages;
+	unsigned nr_pages;
+
+	unsigned pte_start;
+	bool bound;
+};
+
+static int
+nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
+		       struct page **pages, struct page *dummy_read_page)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+
+	NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages);
+
+	if (nvbe->pages)
+		return -EINVAL;
+
+	nvbe->pages = kmalloc(sizeof(dma_addr_t) * num_pages, GFP_KERNEL);
+	if (!nvbe->pages)
+		return -ENOMEM;
+
+	nvbe->nr_pages = 0;
+	while (num_pages--) {
+		nvbe->pages[nvbe->nr_pages] =
+			pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0,
+				     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(dev->pdev,
+					  nvbe->pages[nvbe->nr_pages])) {
+			be->func->clear(be);
+			return -EFAULT;
+		}
+
+		nvbe->nr_pages++;
+	}
+
+	return 0;
+}
+
+static void
+nouveau_sgdma_clear(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev;
+
+	if (nvbe && nvbe->pages) {
+		dev = nvbe->dev;
+		NV_DEBUG(dev, "\n");
+
+		if (nvbe->bound)
+			be->func->unbind(be);
+
+		while (nvbe->nr_pages--) {
+			pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
+				       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		}
+		kfree(nvbe->pages);
+		nvbe->pages = NULL;
+		nvbe->nr_pages = 0;
+	}
+}
+
+static inline unsigned
+nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
+
+	if (dev_priv->card_type < NV_50)
+		return pte + 2;
+
+	return pte << 1;
+}
+
+static int
+nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	unsigned i, j, pte;
+
+	NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start);
+
+	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
+	pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT);
+	nvbe->pte_start = pte;
+	for (i = 0; i < nvbe->nr_pages; i++) {
+		dma_addr_t dma_offset = nvbe->pages[i];
+		uint32_t offset_l = lower_32_bits(dma_offset);
+		uint32_t offset_h = upper_32_bits(dma_offset);
+
+		for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
+			if (dev_priv->card_type < NV_50)
+				nv_wo32(dev, gpuobj, pte++, offset_l | 3);
+			else {
+				nv_wo32(dev, gpuobj, pte++, offset_l | 0x21);
+				nv_wo32(dev, gpuobj, pte++, offset_h & 0xff);
+			}
+
+			dma_offset += NV_CTXDMA_PAGE_SIZE;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(nvbe->dev);
+
+	if (dev_priv->card_type == NV_50) {
+		nv_wr32(dev, 0x100c80, 0x00050001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+
+		nv_wr32(dev, 0x100c80, 0x00000001);
+		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+						nv_rd32(dev, 0x100c80));
+			return -EBUSY;
+		}
+	}
+
+	nvbe->bound = true;
+	return 0;
+}
+
+static int
+nouveau_sgdma_unbind(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+	struct drm_device *dev = nvbe->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	unsigned i, j, pte;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!nvbe->bound)
+		return 0;
+
+	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
+	pte = nvbe->pte_start;
+	for (i = 0; i < nvbe->nr_pages; i++) {
+		dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
+
+		for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
+			if (dev_priv->card_type < NV_50)
+				nv_wo32(dev, gpuobj, pte++, dma_offset | 3);
+			else {
+				nv_wo32(dev, gpuobj, pte++, dma_offset | 0x21);
+				nv_wo32(dev, gpuobj, pte++, 0x00000000);
+			}
+
+			dma_offset += NV_CTXDMA_PAGE_SIZE;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(nvbe->dev);
+
+	nvbe->bound = false;
+	return 0;
+}
+
+static void
+nouveau_sgdma_destroy(struct ttm_backend *be)
+{
+	struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+
+	if (be) {
+		NV_DEBUG(nvbe->dev, "\n");
+
+		if (nvbe) {
+			if (nvbe->pages)
+				be->func->clear(be);
+			kfree(nvbe);
+		}
+	}
+}
+
+static struct ttm_backend_func nouveau_sgdma_backend = {
+	.populate		= nouveau_sgdma_populate,
+	.clear			= nouveau_sgdma_clear,
+	.bind			= nouveau_sgdma_bind,
+	.unbind			= nouveau_sgdma_unbind,
+	.destroy		= nouveau_sgdma_destroy
+};
+
+struct ttm_backend *
+nouveau_sgdma_init_ttm(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_sgdma_be *nvbe;
+
+	if (!dev_priv->gart_info.sg_ctxdma)
+		return NULL;
+
+	nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
+	if (!nvbe)
+		return NULL;
+
+	nvbe->dev = dev;
+
+	nvbe->backend.func	= &nouveau_sgdma_backend;
+
+	return &nvbe->backend;
+}
+
+int
+nouveau_sgdma_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = NULL;
+	uint32_t aper_size, obj_size;
+	int i, ret;
+
+	if (dev_priv->card_type < NV_50) {
+		aper_size = (64 * 1024 * 1024);
+		obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
+		obj_size += 8; /* ctxdma header */
+	} else {
+		/* 1 entire VM page table */
+		aper_size = (512 * 1024 * 1024);
+		obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8;
+	}
+
+	ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16,
+				      NVOBJ_FLAG_ALLOW_NO_REFS |
+				      NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, &gpuobj);
+	if (ret) {
+		NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
+		return ret;
+	}
+
+	dev_priv->gart_info.sg_dummy_page =
+		alloc_page(GFP_KERNEL|__GFP_DMA32);
+	set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags);
+	dev_priv->gart_info.sg_dummy_bus =
+		pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
+			     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (dev_priv->card_type < NV_50) {
+		/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
+		 * confirmed to work on c51.  Perhaps means NV_DMA_TARGET_PCIE
+		 * on those cards? */
+		nv_wo32(dev, gpuobj, 0, NV_CLASS_DMA_IN_MEMORY |
+				       (1 << 12) /* PT present */ |
+				       (0 << 13) /* PT *not* linear */ |
+				       (NV_DMA_ACCESS_RW  << 14) |
+				       (NV_DMA_TARGET_PCI << 16));
+		nv_wo32(dev, gpuobj, 1, aper_size - 1);
+		for (i = 2; i < 2 + (aper_size >> 12); i++) {
+			nv_wo32(dev, gpuobj, i,
+				    dev_priv->gart_info.sg_dummy_bus | 3);
+		}
+	} else {
+		for (i = 0; i < obj_size; i += 8) {
+			nv_wo32(dev, gpuobj, (i+0)/4,
+				    dev_priv->gart_info.sg_dummy_bus | 0x21);
+			nv_wo32(dev, gpuobj, (i+4)/4, 0);
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	dev_priv->gart_info.type      = NOUVEAU_GART_SGDMA;
+	dev_priv->gart_info.aper_base = 0;
+	dev_priv->gart_info.aper_size = aper_size;
+	dev_priv->gart_info.sg_ctxdma = gpuobj;
+	return 0;
+}
+
+void
+nouveau_sgdma_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->gart_info.sg_dummy_page) {
+		pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus,
+			       NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		unlock_page(dev_priv->gart_info.sg_dummy_page);
+		__free_page(dev_priv->gart_info.sg_dummy_page);
+		dev_priv->gart_info.sg_dummy_page = NULL;
+		dev_priv->gart_info.sg_dummy_bus = 0;
+	}
+
+	nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma);
+}
+
+int
+nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
+	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
+	int pte;
+
+	pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
+	if (dev_priv->card_type < NV_50) {
+		instmem->prepare_access(dev, false);
+		*page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
+		instmem->finish_access(dev);
+		return 0;
+	}
+
+	NV_ERROR(dev, "Unimplemented on NV50\n");
+	return -EINVAL;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_state.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,897 @@
+/*
+ * Copyright 2005 Stephane Marchesin
+ * Copyright 2008 Stuart Bennett
+ * 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, 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include <linux/swab.h>
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+#include "drm_crtc_helper.h"
+#include <linux/vgaarb.h>
+
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nv50_display.h"
+
+static int nouveau_stub_init(struct drm_device *dev) { return 0; }
+static void nouveau_stub_takedown(struct drm_device *dev) {}
+
+static int nouveau_init_engine_ptrs(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	switch (dev_priv->chipset & 0xf0) {
+	case 0x00:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv04_fb_init;
+		engine->fb.takedown		= nv04_fb_takedown;
+		engine->graph.grclass		= nv04_graph_grclass;
+		engine->graph.init		= nv04_graph_init;
+		engine->graph.takedown		= nv04_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv04_graph_channel;
+		engine->graph.create_context	= nv04_graph_create_context;
+		engine->graph.destroy_context	= nv04_graph_destroy_context;
+		engine->graph.load_context	= nv04_graph_load_context;
+		engine->graph.unload_context	= nv04_graph_unload_context;
+		engine->fifo.channels		= 16;
+		engine->fifo.init		= nv04_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
+		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
+		engine->fifo.channel_id		= nv04_fifo_channel_id;
+		engine->fifo.create_context	= nv04_fifo_create_context;
+		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
+		engine->fifo.load_context	= nv04_fifo_load_context;
+		engine->fifo.unload_context	= nv04_fifo_unload_context;
+		break;
+	case 0x10:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
+		engine->graph.grclass		= nv10_graph_grclass;
+		engine->graph.init		= nv10_graph_init;
+		engine->graph.takedown		= nv10_graph_takedown;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv10_graph_create_context;
+		engine->graph.destroy_context	= nv10_graph_destroy_context;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.load_context	= nv10_graph_load_context;
+		engine->graph.unload_context	= nv10_graph_unload_context;
+		engine->graph.set_region_tiling	= nv10_graph_set_region_tiling;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
+		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x20:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
+		engine->graph.grclass		= nv20_graph_grclass;
+		engine->graph.init		= nv20_graph_init;
+		engine->graph.takedown		= nv20_graph_takedown;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv20_graph_create_context;
+		engine->graph.destroy_context	= nv20_graph_destroy_context;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.load_context	= nv20_graph_load_context;
+		engine->graph.unload_context	= nv20_graph_unload_context;
+		engine->graph.set_region_tiling	= nv20_graph_set_region_tiling;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
+		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x30:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv04_mc_init;
+		engine->mc.takedown		= nv04_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv10_fb_init;
+		engine->fb.takedown		= nv10_fb_takedown;
+		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
+		engine->graph.grclass		= nv30_graph_grclass;
+		engine->graph.init		= nv30_graph_init;
+		engine->graph.takedown		= nv20_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv10_graph_channel;
+		engine->graph.create_context	= nv20_graph_create_context;
+		engine->graph.destroy_context	= nv20_graph_destroy_context;
+		engine->graph.load_context	= nv20_graph_load_context;
+		engine->graph.unload_context	= nv20_graph_unload_context;
+		engine->graph.set_region_tiling	= nv20_graph_set_region_tiling;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv10_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
+		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv10_fifo_create_context;
+		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
+		engine->fifo.load_context	= nv10_fifo_load_context;
+		engine->fifo.unload_context	= nv10_fifo_unload_context;
+		break;
+	case 0x40:
+	case 0x60:
+		engine->instmem.init		= nv04_instmem_init;
+		engine->instmem.takedown	= nv04_instmem_takedown;
+		engine->instmem.suspend		= nv04_instmem_suspend;
+		engine->instmem.resume		= nv04_instmem_resume;
+		engine->instmem.populate	= nv04_instmem_populate;
+		engine->instmem.clear		= nv04_instmem_clear;
+		engine->instmem.bind		= nv04_instmem_bind;
+		engine->instmem.unbind		= nv04_instmem_unbind;
+		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
+		engine->instmem.finish_access	= nv04_instmem_finish_access;
+		engine->mc.init			= nv40_mc_init;
+		engine->mc.takedown		= nv40_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nv40_fb_init;
+		engine->fb.takedown		= nv40_fb_takedown;
+		engine->fb.set_region_tiling	= nv40_fb_set_region_tiling;
+		engine->graph.grclass		= nv40_graph_grclass;
+		engine->graph.init		= nv40_graph_init;
+		engine->graph.takedown		= nv40_graph_takedown;
+		engine->graph.fifo_access	= nv04_graph_fifo_access;
+		engine->graph.channel		= nv40_graph_channel;
+		engine->graph.create_context	= nv40_graph_create_context;
+		engine->graph.destroy_context	= nv40_graph_destroy_context;
+		engine->graph.load_context	= nv40_graph_load_context;
+		engine->graph.unload_context	= nv40_graph_unload_context;
+		engine->graph.set_region_tiling	= nv40_graph_set_region_tiling;
+		engine->fifo.channels		= 32;
+		engine->fifo.init		= nv40_fifo_init;
+		engine->fifo.takedown		= nouveau_stub_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
+		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
+		engine->fifo.channel_id		= nv10_fifo_channel_id;
+		engine->fifo.create_context	= nv40_fifo_create_context;
+		engine->fifo.destroy_context	= nv40_fifo_destroy_context;
+		engine->fifo.load_context	= nv40_fifo_load_context;
+		engine->fifo.unload_context	= nv40_fifo_unload_context;
+		break;
+	case 0x50:
+	case 0x80: /* gotta love NVIDIA's consistency.. */
+	case 0x90:
+	case 0xA0:
+		engine->instmem.init		= nv50_instmem_init;
+		engine->instmem.takedown	= nv50_instmem_takedown;
+		engine->instmem.suspend		= nv50_instmem_suspend;
+		engine->instmem.resume		= nv50_instmem_resume;
+		engine->instmem.populate	= nv50_instmem_populate;
+		engine->instmem.clear		= nv50_instmem_clear;
+		engine->instmem.bind		= nv50_instmem_bind;
+		engine->instmem.unbind		= nv50_instmem_unbind;
+		engine->instmem.prepare_access	= nv50_instmem_prepare_access;
+		engine->instmem.finish_access	= nv50_instmem_finish_access;
+		engine->mc.init			= nv50_mc_init;
+		engine->mc.takedown		= nv50_mc_takedown;
+		engine->timer.init		= nv04_timer_init;
+		engine->timer.read		= nv04_timer_read;
+		engine->timer.takedown		= nv04_timer_takedown;
+		engine->fb.init			= nouveau_stub_init;
+		engine->fb.takedown		= nouveau_stub_takedown;
+		engine->graph.grclass		= nv50_graph_grclass;
+		engine->graph.init		= nv50_graph_init;
+		engine->graph.takedown		= nv50_graph_takedown;
+		engine->graph.fifo_access	= nv50_graph_fifo_access;
+		engine->graph.channel		= nv50_graph_channel;
+		engine->graph.create_context	= nv50_graph_create_context;
+		engine->graph.destroy_context	= nv50_graph_destroy_context;
+		engine->graph.load_context	= nv50_graph_load_context;
+		engine->graph.unload_context	= nv50_graph_unload_context;
+		engine->fifo.channels		= 128;
+		engine->fifo.init		= nv50_fifo_init;
+		engine->fifo.takedown		= nv50_fifo_takedown;
+		engine->fifo.disable		= nv04_fifo_disable;
+		engine->fifo.enable		= nv04_fifo_enable;
+		engine->fifo.reassign		= nv04_fifo_reassign;
+		engine->fifo.channel_id		= nv50_fifo_channel_id;
+		engine->fifo.create_context	= nv50_fifo_create_context;
+		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
+		engine->fifo.load_context	= nv50_fifo_load_context;
+		engine->fifo.unload_context	= nv50_fifo_unload_context;
+		break;
+	default:
+		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
+		return 1;
+	}
+
+	return 0;
+}
+
+static unsigned int
+nouveau_vga_set_decode(void *priv, bool state)
+{
+	struct drm_device *dev = priv;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset >= 0x40)
+		nv_wr32(dev, 0x88054, state);
+	else
+		nv_wr32(dev, 0x1854, state);
+
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
+static int
+nouveau_card_init_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *gpuobj;
+	int ret;
+
+	ret = nouveau_channel_alloc(dev, &dev_priv->channel,
+				    (struct drm_file *)-2,
+				    NvDmaFB, NvDmaTT);
+	if (ret)
+		return ret;
+
+	gpuobj = NULL;
+	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
+				     0, nouveau_mem_fb_amount(dev),
+				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
+				     &gpuobj);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
+				     gpuobj, NULL);
+	if (ret)
+		goto out_err;
+
+	gpuobj = NULL;
+	ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
+					  dev_priv->gart_info.aper_size,
+					  NV_DMA_ACCESS_RW, &gpuobj, NULL);
+	if (ret)
+		goto out_err;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
+				     gpuobj, NULL);
+	if (ret)
+		goto out_err;
+
+	return 0;
+out_err:
+	nouveau_gpuobj_del(dev, &gpuobj);
+	nouveau_channel_free(dev_priv->channel);
+	dev_priv->channel = NULL;
+	return ret;
+}
+
+int
+nouveau_card_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine;
+	int ret;
+
+	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
+
+	if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
+		return 0;
+
+	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
+
+	/* Initialise internal driver API hooks */
+	ret = nouveau_init_engine_ptrs(dev);
+	if (ret)
+		goto out;
+	engine = &dev_priv->engine;
+	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
+
+	/* Parse BIOS tables / Run init tables if card not POSTed */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		ret = nouveau_bios_init(dev);
+		if (ret)
+			goto out;
+	}
+
+	ret = nouveau_gpuobj_early_init(dev);
+	if (ret)
+		goto out_bios;
+
+	/* Initialise instance memory, must happen before mem_init so we
+	 * know exactly how much VRAM we're able to use for "normal"
+	 * purposes.
+	 */
+	ret = engine->instmem.init(dev);
+	if (ret)
+		goto out_gpuobj_early;
+
+	/* Setup the memory manager */
+	ret = nouveau_mem_init(dev);
+	if (ret)
+		goto out_instmem;
+
+	ret = nouveau_gpuobj_init(dev);
+	if (ret)
+		goto out_mem;
+
+	/* PMC */
+	ret = engine->mc.init(dev);
+	if (ret)
+		goto out_gpuobj;
+
+	/* PTIMER */
+	ret = engine->timer.init(dev);
+	if (ret)
+		goto out_mc;
+
+	/* PFB */
+	ret = engine->fb.init(dev);
+	if (ret)
+		goto out_timer;
+
+	if (nouveau_noaccel)
+		engine->graph.accel_blocked = true;
+	else {
+		/* PGRAPH */
+		ret = engine->graph.init(dev);
+		if (ret)
+			goto out_fb;
+
+		/* PFIFO */
+		ret = engine->fifo.init(dev);
+		if (ret)
+			goto out_graph;
+	}
+
+	/* this call irq_preinstall, register irq handler and
+	 * call irq_postinstall
+	 */
+	ret = drm_irq_install(dev);
+	if (ret)
+		goto out_fifo;
+
+	ret = drm_vblank_init(dev, 0);
+	if (ret)
+		goto out_irq;
+
+	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
+
+	if (!engine->graph.accel_blocked) {
+		ret = nouveau_card_init_channel(dev);
+		if (ret)
+			goto out_irq;
+	}
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		if (dev_priv->card_type >= NV_50)
+			ret = nv50_display_create(dev);
+		else
+			ret = nv04_display_create(dev);
+		if (ret)
+			goto out_irq;
+	}
+
+	ret = nouveau_backlight_init(dev);
+	if (ret)
+		NV_ERROR(dev, "Error %d registering backlight\n", ret);
+
+	dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		drm_helper_initial_config(dev);
+
+	return 0;
+
+out_irq:
+	drm_irq_uninstall(dev);
+out_fifo:
+	if (!nouveau_noaccel)
+		engine->fifo.takedown(dev);
+out_graph:
+	if (!nouveau_noaccel)
+		engine->graph.takedown(dev);
+out_fb:
+	engine->fb.takedown(dev);
+out_timer:
+	engine->timer.takedown(dev);
+out_mc:
+	engine->mc.takedown(dev);
+out_gpuobj:
+	nouveau_gpuobj_takedown(dev);
+out_mem:
+	nouveau_mem_close(dev);
+out_instmem:
+	engine->instmem.takedown(dev);
+out_gpuobj_early:
+	nouveau_gpuobj_late_takedown(dev);
+out_bios:
+	nouveau_bios_takedown(dev);
+out:
+	vga_client_register(dev->pdev, NULL, NULL, NULL);
+	return ret;
+}
+
+static void nouveau_card_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
+
+	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
+		nouveau_backlight_exit(dev);
+
+		if (dev_priv->channel) {
+			nouveau_channel_free(dev_priv->channel);
+			dev_priv->channel = NULL;
+		}
+
+		if (!nouveau_noaccel) {
+			engine->fifo.takedown(dev);
+			engine->graph.takedown(dev);
+		}
+		engine->fb.takedown(dev);
+		engine->timer.takedown(dev);
+		engine->mc.takedown(dev);
+
+		mutex_lock(&dev->struct_mutex);
+		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
+		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
+		mutex_unlock(&dev->struct_mutex);
+		nouveau_sgdma_takedown(dev);
+
+		nouveau_gpuobj_takedown(dev);
+		nouveau_mem_close(dev);
+		engine->instmem.takedown(dev);
+
+		if (drm_core_check_feature(dev, DRIVER_MODESET))
+			drm_irq_uninstall(dev);
+
+		nouveau_gpuobj_late_takedown(dev);
+		nouveau_bios_takedown(dev);
+
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
+
+		dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
+	}
+}
+
+/* here a client dies, release the stuff that was allocated for its
+ * file_priv */
+void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+	nouveau_channel_cleanup(dev, file_priv);
+}
+
+/* first module load, setup the mmio/fb mapping */
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+int nouveau_firstopen(struct drm_device *dev)
+{
+	return 0;
+}
+
+/* if we have an OF card, copy vbios to RAMIN */
+static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
+{
+#if defined(__powerpc__)
+	int size, i;
+	const uint32_t *bios;
+	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
+	if (!dn) {
+		NV_INFO(dev, "Unable to get the OF node\n");
+		return;
+	}
+
+	bios = of_get_property(dn, "NVDA,BMP", &size);
+	if (bios) {
+		for (i = 0; i < size; i += 4)
+			nv_wi32(dev, i, bios[i/4]);
+		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
+	} else {
+		NV_INFO(dev, "Unable to get the OF bios\n");
+	}
+#endif
+}
+
+int nouveau_load(struct drm_device *dev, unsigned long flags)
+{
+	struct drm_nouveau_private *dev_priv;
+	uint32_t reg0;
+	resource_size_t mmio_start_offs;
+
+	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+	if (!dev_priv)
+		return -ENOMEM;
+	dev->dev_private = dev_priv;
+	dev_priv->dev = dev;
+
+	dev_priv->flags = flags & NOUVEAU_FLAGS;
+	dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
+
+	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
+		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
+
+	dev_priv->acpi_dsm = nouveau_dsm_probe(dev);
+
+	if (dev_priv->acpi_dsm)
+		nouveau_hybrid_setup(dev);
+
+	dev_priv->wq = create_workqueue("nouveau");
+	if (!dev_priv->wq)
+		return -EINVAL;
+
+	/* resource 0 is mmio regs */
+	/* resource 1 is linear FB */
+	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
+	/* resource 6 is bios */
+
+	/* map the mmio regs */
+	mmio_start_offs = pci_resource_start(dev->pdev, 0);
+	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
+	if (!dev_priv->mmio) {
+		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
+			 "Please report your setup to " DRIVER_EMAIL "\n");
+		return -EINVAL;
+	}
+	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
+					(unsigned long long)mmio_start_offs);
+
+#ifdef __BIG_ENDIAN
+	/* Put the card in BE mode if it's not */
+	if (nv_rd32(dev, NV03_PMC_BOOT_1))
+		nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
+
+	DRM_MEMORYBARRIER();
+#endif
+
+	/* Time to determine the card architecture */
+	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
+
+	/* We're dealing with >=NV10 */
+	if ((reg0 & 0x0f000000) > 0) {
+		/* Bit 27-20 contain the architecture in hex */
+		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
+	/* NV04 or NV05 */
+	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
+		if (reg0 & 0x00f00000)
+			dev_priv->chipset = 0x05;
+		else
+			dev_priv->chipset = 0x04;
+	} else
+		dev_priv->chipset = 0xff;
+
+	switch (dev_priv->chipset & 0xf0) {
+	case 0x00:
+	case 0x10:
+	case 0x20:
+	case 0x30:
+		dev_priv->card_type = dev_priv->chipset & 0xf0;
+		break;
+	case 0x40:
+	case 0x60:
+		dev_priv->card_type = NV_40;
+		break;
+	case 0x50:
+	case 0x80:
+	case 0x90:
+	case 0xa0:
+		dev_priv->card_type = NV_50;
+		break;
+	default:
+		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
+		return -EINVAL;
+	}
+
+	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
+		dev_priv->card_type, reg0);
+
+	/* map larger RAMIN aperture on NV40 cards */
+	dev_priv->ramin  = NULL;
+	if (dev_priv->card_type >= NV_40) {
+		int ramin_bar = 2;
+		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
+			ramin_bar = 3;
+
+		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
+		dev_priv->ramin = ioremap(
+				pci_resource_start(dev->pdev, ramin_bar),
+				dev_priv->ramin_size);
+		if (!dev_priv->ramin) {
+			NV_ERROR(dev, "Failed to init RAMIN mapping, "
+				      "limited instance memory available\n");
+		}
+	}
+
+	/* On older cards (or if the above failed), create a map covering
+	 * the BAR0 PRAMIN aperture */
+	if (!dev_priv->ramin) {
+		dev_priv->ramin_size = 1 * 1024 * 1024;
+		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
+							dev_priv->ramin_size);
+		if (!dev_priv->ramin) {
+			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
+			return -ENOMEM;
+		}
+	}
+
+	nouveau_OF_copy_vbios_to_ramin(dev);
+
+	/* Special flags */
+	if (dev->pci_device == 0x01a0)
+		dev_priv->flags |= NV_NFORCE;
+	else if (dev->pci_device == 0x01f0)
+		dev_priv->flags |= NV_NFORCE2;
+
+	/* For kernel modesetting, init card now and bring up fbcon */
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		int ret = nouveau_card_init(dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void nouveau_close(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	/* In the case of an error dev_priv may not be allocated yet */
+	if (dev_priv)
+		nouveau_card_takedown(dev);
+}
+
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+void nouveau_lastclose(struct drm_device *dev)
+{
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		return;
+
+	nouveau_close(dev);
+}
+
+int nouveau_unload(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		if (dev_priv->card_type >= NV_50)
+			nv50_display_destroy(dev);
+		else
+			nv04_display_destroy(dev);
+		nouveau_close(dev);
+	}
+
+	iounmap(dev_priv->mmio);
+	iounmap(dev_priv->ramin);
+
+	kfree(dev_priv);
+	dev->dev_private = NULL;
+	return 0;
+}
+
+int
+nouveau_ioctl_card_init(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	return nouveau_card_init(dev);
+}
+
+int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
+						struct drm_file *file_priv)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_nouveau_getparam *getparam = data;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	switch (getparam->param) {
+	case NOUVEAU_GETPARAM_CHIPSET_ID:
+		getparam->value = dev_priv->chipset;
+		break;
+	case NOUVEAU_GETPARAM_PCI_VENDOR:
+		getparam->value = dev->pci_vendor;
+		break;
+	case NOUVEAU_GETPARAM_PCI_DEVICE:
+		getparam->value = dev->pci_device;
+		break;
+	case NOUVEAU_GETPARAM_BUS_TYPE:
+		if (drm_device_is_agp(dev))
+			getparam->value = NV_AGP;
+		else if (drm_device_is_pcie(dev))
+			getparam->value = NV_PCIE;
+		else
+			getparam->value = NV_PCI;
+		break;
+	case NOUVEAU_GETPARAM_FB_PHYSICAL:
+		getparam->value = dev_priv->fb_phys;
+		break;
+	case NOUVEAU_GETPARAM_AGP_PHYSICAL:
+		getparam->value = dev_priv->gart_info.aper_base;
+		break;
+	case NOUVEAU_GETPARAM_PCI_PHYSICAL:
+		if (dev->sg) {
+			getparam->value = (unsigned long)dev->sg->virtual;
+		} else {
+			NV_ERROR(dev, "Requested PCIGART address, "
+					"while no PCIGART was created\n");
+			return -EINVAL;
+		}
+		break;
+	case NOUVEAU_GETPARAM_FB_SIZE:
+		getparam->value = dev_priv->fb_available_size;
+		break;
+	case NOUVEAU_GETPARAM_AGP_SIZE:
+		getparam->value = dev_priv->gart_info.aper_size;
+		break;
+	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
+		getparam->value = dev_priv->vm_vram_base;
+		break;
+	case NOUVEAU_GETPARAM_GRAPH_UNITS:
+		/* NV40 and NV50 versions are quite different, but register
+		 * address is the same. User is supposed to know the card
+		 * family anyway... */
+		if (dev_priv->chipset >= 0x40) {
+			getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
+			break;
+		}
+		/* FALLTHRU */
+	default:
+		NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+nouveau_ioctl_setparam(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_nouveau_setparam *setparam = data;
+
+	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+	switch (setparam->param) {
+	default:
+		NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Wait until (value(reg) & mask) == val, up until timeout has hit */
+bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
+			uint32_t reg, uint32_t mask, uint32_t val)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+	uint64_t start = ptimer->read(dev);
+
+	do {
+		if ((nv_rd32(dev, reg) & mask) == val)
+			return true;
+	} while (ptimer->read(dev) - start < timeout);
+
+	return false;
+}
+
+/* Waits for PGRAPH to go completely idle */
+bool nouveau_wait_for_idle(struct drm_device *dev)
+{
+	if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) {
+		NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
+			 nv_rd32(dev, NV04_PGRAPH_STATUS));
+		return false;
+	}
+
+	return true;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_ttm.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_ttm.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nouveau_ttm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nouveau_ttm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA,
+ * All Rights Reserved.
+ * Copyright (c) 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.
+ */
+
+#include "drmP.h"
+
+#include "nouveau_drv.h"
+
+int
+nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_nouveau_private *dev_priv =
+		file_priv->minor->dev->dev_private;
+
+	if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+		return drm_mmap(filp, vma);
+
+	return ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev);
+}
+
+static int
+nouveau_ttm_mem_global_init(struct ttm_global_reference *ref)
+{
+	return ttm_mem_global_init(ref->object);
+}
+
+static void
+nouveau_ttm_mem_global_release(struct ttm_global_reference *ref)
+{
+	ttm_mem_global_release(ref->object);
+}
+
+int
+nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
+{
+	struct ttm_global_reference *global_ref;
+	int ret;
+
+	global_ref = &dev_priv->ttm.mem_global_ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+	global_ref->size = sizeof(struct ttm_mem_global);
+	global_ref->init = &nouveau_ttm_mem_global_init;
+	global_ref->release = &nouveau_ttm_mem_global_release;
+
+	ret = ttm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM memory accounting\n");
+		dev_priv->ttm.mem_global_ref.release = NULL;
+		return ret;
+	}
+
+	dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object;
+	global_ref = &dev_priv->ttm.bo_global_ref.ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_BO;
+	global_ref->size = sizeof(struct ttm_bo_global);
+	global_ref->init = &ttm_bo_global_init;
+	global_ref->release = &ttm_bo_global_release;
+
+	ret = ttm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM BO subsystem\n");
+		ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+		dev_priv->ttm.mem_global_ref.release = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv)
+{
+	if (dev_priv->ttm.mem_global_ref.release == NULL)
+		return;
+
+	ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref);
+	ttm_global_item_unref(&dev_priv->ttm.mem_global_ref);
+	dev_priv->ttm.mem_global_ref.release = NULL;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_crtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1002 @@
+/*
+ * Copyright 1993-2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ *
+ * 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 "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb);
+
+static void
+crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index,
+		       crtcstate->CRTC[index]);
+}
+
+static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level;
+	if (nv_crtc->saturation && nv_gf4_disp_arch(crtc->dev)) {
+		regp->CRTC[NV_CIO_CRE_CSB] = 0x80;
+		regp->CRTC[NV_CIO_CRE_5B] = nv_crtc->saturation << 2;
+		crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_5B);
+	}
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_CSB);
+}
+
+static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	nv_crtc->sharpness = level;
+	if (level < 0)	/* blur is in hw range 0x3f -> 0x20 */
+		level += 0x40;
+	regp->ramdac_634 = level;
+	NVWriteRAMDAC(crtc->dev, nv_crtc->index, NV_PRAMDAC_634, regp->ramdac_634);
+}
+
+#define PLLSEL_VPLL1_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL	\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2)
+#define PLLSEL_VPLL2_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2)
+#define PLLSEL_TV_MASK					\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2	\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2)
+
+/* NV4x 0x40.. pll notes:
+ * gpu pll: 0x4000 + 0x4004
+ * ?gpu? pll: 0x4008 + 0x400c
+ * vpll1: 0x4010 + 0x4014
+ * vpll2: 0x4018 + 0x401c
+ * mpll: 0x4020 + 0x4024
+ * mpll: 0x4038 + 0x403c
+ *
+ * the first register of each pair has some unknown details:
+ * bits 0-7: redirected values from elsewhere? (similar to PLL_SETUP_CONTROL?)
+ * bits 20-23: (mpll) something to do with post divider?
+ * bits 28-31: related to single stage mode? (bit 8/12)
+ */
+
+static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mode * mode, int dot_clock)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
+	struct nouveau_pll_vals *pv = &regp->pllvals;
+	struct pll_lims pll_lim;
+
+	if (get_pll_limits(dev, nv_crtc->index ? VPLL2 : VPLL1, &pll_lim))
+		return;
+
+	/* NM2 == 0 is used to determine single stage mode on two stage plls */
+	pv->NM2 = 0;
+
+	/* for newer nv4x the blob uses only the first stage of the vpll below a
+	 * certain clock.  for a certain nv4b this is 150MHz.  since the max
+	 * output frequency of the first stage for this card is 300MHz, it is
+	 * assumed the threshold is given by vco1 maxfreq/2
+	 */
+	/* for early nv4x, specifically nv40 and *some* nv43 (devids 0 and 6,
+	 * not 8, others unknown), the blob always uses both plls.  no problem
+	 * has yet been observed in allowing the use a single stage pll on all
+	 * nv43 however.  the behaviour of single stage use is untested on nv40
+	 */
+	if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2))
+		memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2));
+
+	if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv))
+		return;
+
+	state->pllsel &= PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK;
+
+	/* The blob uses this always, so let's do the same */
+	if (dev_priv->card_type == NV_40)
+		state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE;
+	/* again nv40 and some nv43 act more like nv3x as described above */
+	if (dev_priv->chipset < 0x41)
+		state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL |
+				 NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL;
+	state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK;
+
+	if (pv->NM2)
+		NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
+			 pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P);
+	else
+		NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n",
+			 pv->N1, pv->M1, pv->log2P);
+
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
+}
+
+static void
+nv_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned char seq1 = 0, crtc17 = 0;
+	unsigned char crtc1A;
+
+	NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode,
+							nv_crtc->index);
+
+	if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */
+		return;
+
+	nv_crtc->last_dpms = mode;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, nv_crtc->index);
+
+	/* nv4ref indicates these two RPC1 bits inhibit h/v sync */
+	crtc1A = NVReadVgaCrtc(dev, nv_crtc->index,
+					NV_CIO_CRE_RPC1_INDEX) & ~0xC0;
+	switch (mode) {
+	case DRM_MODE_DPMS_STANDBY:
+		/* Screen: Off; HSync: Off, VSync: On -- Not Supported */
+		seq1 = 0x20;
+		crtc17 = 0x80;
+		crtc1A |= 0x80;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		/* Screen: Off; HSync: On, VSync: Off -- Not Supported */
+		seq1 = 0x20;
+		crtc17 = 0x80;
+		crtc1A |= 0x40;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		/* Screen: Off; HSync: Off, VSync: Off */
+		seq1 = 0x20;
+		crtc17 = 0x00;
+		crtc1A |= 0xC0;
+		break;
+	case DRM_MODE_DPMS_ON:
+	default:
+		/* Screen: On; HSync: On, VSync: On */
+		seq1 = 0x00;
+		crtc17 = 0x80;
+		break;
+	}
+
+	NVVgaSeqReset(dev, nv_crtc->index, true);
+	/* Each head has it's own sequencer, so we can turn it off when we want */
+	seq1 |= (NVReadVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX) & ~0x20);
+	NVWriteVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX, seq1);
+	crtc17 |= (NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX) & ~0x80);
+	mdelay(10);
+	NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX, crtc17);
+	NVVgaSeqReset(dev, nv_crtc->index, false);
+
+	NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
+}
+
+static bool
+nv_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		   struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void
+nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_framebuffer *fb = crtc->fb;
+
+	/* Calculate our timings */
+	int horizDisplay	= (mode->crtc_hdisplay >> 3) 	- 1;
+	int horizStart		= (mode->crtc_hsync_start >> 3) 	- 1;
+	int horizEnd		= (mode->crtc_hsync_end >> 3) 	- 1;
+	int horizTotal		= (mode->crtc_htotal >> 3)		- 5;
+	int horizBlankStart	= (mode->crtc_hdisplay >> 3)		- 1;
+	int horizBlankEnd	= (mode->crtc_htotal >> 3)		- 1;
+	int vertDisplay		= mode->crtc_vdisplay			- 1;
+	int vertStart		= mode->crtc_vsync_start 		- 1;
+	int vertEnd		= mode->crtc_vsync_end			- 1;
+	int vertTotal		= mode->crtc_vtotal 			- 2;
+	int vertBlankStart	= mode->crtc_vdisplay 			- 1;
+	int vertBlankEnd	= mode->crtc_vtotal			- 1;
+
+	struct drm_encoder *encoder;
+	bool fp_output = false;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (encoder->crtc == crtc &&
+		    (nv_encoder->dcb->type == OUTPUT_LVDS ||
+		     nv_encoder->dcb->type == OUTPUT_TMDS))
+			fp_output = true;
+	}
+
+	if (fp_output) {
+		vertStart = vertTotal - 3;
+		vertEnd = vertTotal - 2;
+		vertBlankStart = vertStart;
+		horizStart = horizTotal - 5;
+		horizEnd = horizTotal - 2;
+		horizBlankEnd = horizTotal + 4;
+#if 0
+		if (dev->overlayAdaptor && dev_priv->card_type >= NV_10)
+			/* This reportedly works around some video overlay bandwidth problems */
+			horizTotal += 2;
+#endif
+	}
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		vertTotal |= 1;
+
+#if 0
+	ErrorF("horizDisplay: 0x%X \n", horizDisplay);
+	ErrorF("horizStart: 0x%X \n", horizStart);
+	ErrorF("horizEnd: 0x%X \n", horizEnd);
+	ErrorF("horizTotal: 0x%X \n", horizTotal);
+	ErrorF("horizBlankStart: 0x%X \n", horizBlankStart);
+	ErrorF("horizBlankEnd: 0x%X \n", horizBlankEnd);
+	ErrorF("vertDisplay: 0x%X \n", vertDisplay);
+	ErrorF("vertStart: 0x%X \n", vertStart);
+	ErrorF("vertEnd: 0x%X \n", vertEnd);
+	ErrorF("vertTotal: 0x%X \n", vertTotal);
+	ErrorF("vertBlankStart: 0x%X \n", vertBlankStart);
+	ErrorF("vertBlankEnd: 0x%X \n", vertBlankEnd);
+#endif
+
+	/*
+	* compute correct Hsync & Vsync polarity
+	*/
+	if ((mode->flags & (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC))
+		&& (mode->flags & (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))) {
+
+		regp->MiscOutReg = 0x23;
+		if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+			regp->MiscOutReg |= 0x40;
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			regp->MiscOutReg |= 0x80;
+	} else {
+		int vdisplay = mode->vdisplay;
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			vdisplay *= 2;
+		if (mode->vscan > 1)
+			vdisplay *= mode->vscan;
+		if (vdisplay < 400)
+			regp->MiscOutReg = 0xA3;	/* +hsync -vsync */
+		else if (vdisplay < 480)
+			regp->MiscOutReg = 0x63;	/* -hsync +vsync */
+		else if (vdisplay < 768)
+			regp->MiscOutReg = 0xE3;	/* -hsync -vsync */
+		else
+			regp->MiscOutReg = 0x23;	/* +hsync +vsync */
+	}
+
+	regp->MiscOutReg |= (mode->clock_index & 0x03) << 2;
+
+	/*
+	 * Time Sequencer
+	 */
+	regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00;
+	/* 0x20 disables the sequencer */
+	if (mode->flags & DRM_MODE_FLAG_CLKDIV2)
+		regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x29;
+	else
+		regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x21;
+	regp->Sequencer[NV_VIO_SR_PLANE_MASK_INDEX] = 0x0F;
+	regp->Sequencer[NV_VIO_SR_CHAR_MAP_INDEX] = 0x00;
+	regp->Sequencer[NV_VIO_SR_MEM_MODE_INDEX] = 0x0E;
+
+	/*
+	 * CRTC
+	 */
+	regp->CRTC[NV_CIO_CR_HDT_INDEX] = horizTotal;
+	regp->CRTC[NV_CIO_CR_HDE_INDEX] = horizDisplay;
+	regp->CRTC[NV_CIO_CR_HBS_INDEX] = horizBlankStart;
+	regp->CRTC[NV_CIO_CR_HBE_INDEX] = (1 << 7) |
+					  XLATE(horizBlankEnd, 0, NV_CIO_CR_HBE_4_0);
+	regp->CRTC[NV_CIO_CR_HRS_INDEX] = horizStart;
+	regp->CRTC[NV_CIO_CR_HRE_INDEX] = XLATE(horizBlankEnd, 5, NV_CIO_CR_HRE_HBE_5) |
+					  XLATE(horizEnd, 0, NV_CIO_CR_HRE_4_0);
+	regp->CRTC[NV_CIO_CR_VDT_INDEX] = vertTotal;
+	regp->CRTC[NV_CIO_CR_OVL_INDEX] = XLATE(vertStart, 9, NV_CIO_CR_OVL_VRS_9) |
+					  XLATE(vertDisplay, 9, NV_CIO_CR_OVL_VDE_9) |
+					  XLATE(vertTotal, 9, NV_CIO_CR_OVL_VDT_9) |
+					  (1 << 4) |
+					  XLATE(vertBlankStart, 8, NV_CIO_CR_OVL_VBS_8) |
+					  XLATE(vertStart, 8, NV_CIO_CR_OVL_VRS_8) |
+					  XLATE(vertDisplay, 8, NV_CIO_CR_OVL_VDE_8) |
+					  XLATE(vertTotal, 8, NV_CIO_CR_OVL_VDT_8);
+	regp->CRTC[NV_CIO_CR_RSAL_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_CELL_HT_INDEX] = ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ? MASK(NV_CIO_CR_CELL_HT_SCANDBL) : 0) |
+					      1 << 6 |
+					      XLATE(vertBlankStart, 9, NV_CIO_CR_CELL_HT_VBS_9);
+	regp->CRTC[NV_CIO_CR_CURS_ST_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_CURS_END_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_SA_HI_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_SA_LO_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_TCOFF_HI_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_TCOFF_LO_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_VRS_INDEX] = vertStart;
+	regp->CRTC[NV_CIO_CR_VRE_INDEX] = 1 << 5 | XLATE(vertEnd, 0, NV_CIO_CR_VRE_3_0);
+	regp->CRTC[NV_CIO_CR_VDE_INDEX] = vertDisplay;
+	/* framebuffer can be larger than crtc scanout area. */
+	regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = fb->pitch / 8;
+	regp->CRTC[NV_CIO_CR_ULINE_INDEX] = 0x00;
+	regp->CRTC[NV_CIO_CR_VBS_INDEX] = vertBlankStart;
+	regp->CRTC[NV_CIO_CR_VBE_INDEX] = vertBlankEnd;
+	regp->CRTC[NV_CIO_CR_MODE_INDEX] = 0x43;
+	regp->CRTC[NV_CIO_CR_LCOMP_INDEX] = 0xff;
+
+	/*
+	 * Some extended CRTC registers (they are not saved with the rest of the vga regs).
+	 */
+
+	/* framebuffer can be larger than crtc scanout area. */
+	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ?
+					    MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
+	regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
+					   XLATE(vertBlankStart, 10, NV_CIO_CRE_LSR_VBS_10) |
+					   XLATE(vertStart, 10, NV_CIO_CRE_LSR_VRS_10) |
+					   XLATE(vertDisplay, 10, NV_CIO_CRE_LSR_VDE_10) |
+					   XLATE(vertTotal, 10, NV_CIO_CRE_LSR_VDT_10);
+	regp->CRTC[NV_CIO_CRE_HEB__INDEX] = XLATE(horizStart, 8, NV_CIO_CRE_HEB_HRS_8) |
+					    XLATE(horizBlankStart, 8, NV_CIO_CRE_HEB_HBS_8) |
+					    XLATE(horizDisplay, 8, NV_CIO_CRE_HEB_HDE_8) |
+					    XLATE(horizTotal, 8, NV_CIO_CRE_HEB_HDT_8);
+	regp->CRTC[NV_CIO_CRE_EBR_INDEX] = XLATE(vertBlankStart, 11, NV_CIO_CRE_EBR_VBS_11) |
+					   XLATE(vertStart, 11, NV_CIO_CRE_EBR_VRS_11) |
+					   XLATE(vertDisplay, 11, NV_CIO_CRE_EBR_VDE_11) |
+					   XLATE(vertTotal, 11, NV_CIO_CRE_EBR_VDT_11);
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		horizTotal = (horizTotal >> 1) & ~1;
+		regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = horizTotal;
+		regp->CRTC[NV_CIO_CRE_HEB__INDEX] |= XLATE(horizTotal, 8, NV_CIO_CRE_HEB_ILC_8);
+	} else
+		regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = 0xff;  /* interlace off */
+
+	/*
+	* Graphics Display Controller
+	*/
+	regp->Graphics[NV_VIO_GX_SR_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_SREN_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_CCOMP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_ROP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_READ_MAP_INDEX] = 0x00;
+	regp->Graphics[NV_VIO_GX_MODE_INDEX] = 0x40; /* 256 color mode */
+	regp->Graphics[NV_VIO_GX_MISC_INDEX] = 0x05; /* map 64k mem + graphic mode */
+	regp->Graphics[NV_VIO_GX_DONT_CARE_INDEX] = 0x0F;
+	regp->Graphics[NV_VIO_GX_BIT_MASK_INDEX] = 0xFF;
+
+	regp->Attribute[0]  = 0x00; /* standard colormap translation */
+	regp->Attribute[1]  = 0x01;
+	regp->Attribute[2]  = 0x02;
+	regp->Attribute[3]  = 0x03;
+	regp->Attribute[4]  = 0x04;
+	regp->Attribute[5]  = 0x05;
+	regp->Attribute[6]  = 0x06;
+	regp->Attribute[7]  = 0x07;
+	regp->Attribute[8]  = 0x08;
+	regp->Attribute[9]  = 0x09;
+	regp->Attribute[10] = 0x0A;
+	regp->Attribute[11] = 0x0B;
+	regp->Attribute[12] = 0x0C;
+	regp->Attribute[13] = 0x0D;
+	regp->Attribute[14] = 0x0E;
+	regp->Attribute[15] = 0x0F;
+	regp->Attribute[NV_CIO_AR_MODE_INDEX] = 0x01; /* Enable graphic mode */
+	/* Non-vga */
+	regp->Attribute[NV_CIO_AR_OSCAN_INDEX] = 0x00;
+	regp->Attribute[NV_CIO_AR_PLANE_INDEX] = 0x0F; /* enable all color planes */
+	regp->Attribute[NV_CIO_AR_HPP_INDEX] = 0x00;
+	regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00;
+}
+
+/**
+ * Sets up registers for the given mode/adjusted_mode pair.
+ *
+ * The clocks, CRTCs and outputs attached to this CRTC must be off.
+ *
+ * This shouldn't enable any clocks, CRTCs, or outputs, but they should
+ * be easily turned on/off after this.
+ */
+static void
+nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+	struct drm_encoder *encoder;
+	bool lvds_output = false, tmds_output = false, tv_output = false,
+		off_chip_digital = false;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+		bool digital = false;
+
+		if (encoder->crtc != crtc)
+			continue;
+
+		if (nv_encoder->dcb->type == OUTPUT_LVDS)
+			digital = lvds_output = true;
+		if (nv_encoder->dcb->type == OUTPUT_TV)
+			tv_output = true;
+		if (nv_encoder->dcb->type == OUTPUT_TMDS)
+			digital = tmds_output = true;
+		if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && digital)
+			off_chip_digital = true;
+	}
+
+	/* Registers not directly related to the (s)vga mode */
+
+	/* What is the meaning of this register? */
+	/* A few popular values are 0x18, 0x1c, 0x38, 0x3c */
+	regp->CRTC[NV_CIO_CRE_ENH_INDEX] = savep->CRTC[NV_CIO_CRE_ENH_INDEX] & ~(1<<5);
+
+	regp->crtc_eng_ctrl = 0;
+	/* Except for rare conditions I2C is enabled on the primary crtc */
+	if (nv_crtc->index == 0)
+		regp->crtc_eng_ctrl |= NV_CRTC_FSEL_I2C;
+#if 0
+	/* Set overlay to desired crtc. */
+	if (dev->overlayAdaptor) {
+		NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(dev);
+		if (pPriv->overlayCRTC == nv_crtc->index)
+			regp->crtc_eng_ctrl |= NV_CRTC_FSEL_OVERLAY;
+	}
+#endif
+
+	/* ADDRESS_SPACE_PNVM is the same as setting HCUR_ASI */
+	regp->cursor_cfg = NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 |
+			     NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 |
+			     NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM;
+	if (dev_priv->chipset >= 0x11)
+		regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32;
+	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+		regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE;
+
+	/* Unblock some timings */
+	regp->CRTC[NV_CIO_CRE_53] = 0;
+	regp->CRTC[NV_CIO_CRE_54] = 0;
+
+	/* 0x00 is disabled, 0x11 is lvds, 0x22 crt and 0x88 tmds */
+	if (lvds_output)
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x11;
+	else if (tmds_output)
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x88;
+	else
+		regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x22;
+
+	/* These values seem to vary */
+	/* This register seems to be used by the bios to make certain decisions on some G70 cards? */
+	regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = savep->CRTC[NV_CIO_CRE_SCRATCH4__INDEX];
+
+	nv_crtc_set_digital_vibrance(crtc, nv_crtc->saturation);
+
+	/* probably a scratch reg, but kept for cargo-cult purposes:
+	 * bit0: crtc0?, head A
+	 * bit6: lvds, head A
+	 * bit7: (only in X), head A
+	 */
+	if (nv_crtc->index == 0)
+		regp->CRTC[NV_CIO_CRE_4B] = savep->CRTC[NV_CIO_CRE_4B] | 0x80;
+
+	/* The blob seems to take the current value from crtc 0, add 4 to that
+	 * and reuse the old value for crtc 1 */
+	regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = dev_priv->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY];
+	if (!nv_crtc->index)
+		regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] += 4;
+
+	/* the blob sometimes sets |= 0x10 (which is the same as setting |=
+	 * 1 << 30 on 0x60.830), for no apparent reason */
+	regp->CRTC[NV_CIO_CRE_59] = off_chip_digital;
+
+	regp->crtc_830 = mode->crtc_vdisplay - 3;
+	regp->crtc_834 = mode->crtc_vdisplay - 1;
+
+	if (dev_priv->card_type == NV_40)
+		/* This is what the blob does */
+		regp->crtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850);
+
+	if (dev_priv->card_type >= NV_30)
+		regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT);
+
+	regp->crtc_cfg = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC;
+
+	/* Some misc regs */
+	if (dev_priv->card_type == NV_40) {
+		regp->CRTC[NV_CIO_CRE_85] = 0xFF;
+		regp->CRTC[NV_CIO_CRE_86] = 0x1;
+	}
+
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8;
+	/* Enable slaved mode (called MODE_TV in nv4ref.h) */
+	if (lvds_output || tmds_output || tv_output)
+		regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7);
+
+	/* Generic PRAMDAC regs */
+
+	if (dev_priv->card_type >= NV_10)
+		/* Only bit that bios and blob set. */
+		regp->nv10_cursync = (1 << 25);
+
+	regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
+				NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL |
+				NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON;
+	if (crtc->fb->depth == 16)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	if (dev_priv->chipset >= 0x11)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG;
+
+	regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */
+	regp->tv_setup = 0;
+
+	nv_crtc_set_image_sharpening(crtc, nv_crtc->sharpness);
+
+	/* Some values the blob sets */
+	regp->ramdac_8c0 = 0x100;
+	regp->ramdac_a20 = 0x0;
+	regp->ramdac_a24 = 0xfffff;
+	regp->ramdac_a34 = 0x1;
+}
+
+/**
+ * Sets up registers for the given mode/adjusted_mode pair.
+ *
+ * The clocks, CRTCs and outputs attached to this CRTC must be off.
+ *
+ * This shouldn't enable any clocks, CRTCs, or outputs, but they should
+ * be easily turned on/off after this.
+ */
+static int
+nv_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 drm_device *dev = crtc->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index);
+	drm_mode_debug_printmodeline(adjusted_mode);
+
+	/* unlock must come after turning off FP_TG_CONTROL in output_prepare */
+	nv_lock_vga_crtc_shadow(dev, nv_crtc->index, -1);
+
+	nv_crtc_mode_set_vga(crtc, adjusted_mode);
+	/* calculated in nv04_dfp_prepare, nv40 needs it written before calculating PLLs */
+	if (dev_priv->card_type == NV_40)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+	nv_crtc_mode_set_regs(crtc, adjusted_mode);
+	nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->clock);
+	return 0;
+}
+
+static void nv_crtc_save(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	struct nv04_crtc_reg *crtc_state = &state->crtc_reg[nv_crtc->index];
+	struct nv04_mode_state *saved = &dev_priv->saved_reg;
+	struct nv04_crtc_reg *crtc_saved = &saved->crtc_reg[nv_crtc->index];
+
+	if (nv_two_heads(crtc->dev))
+		NVSetOwner(crtc->dev, nv_crtc->index);
+
+	nouveau_hw_save_state(crtc->dev, nv_crtc->index, saved);
+
+	/* init some state to saved value */
+	state->sel_clk = saved->sel_clk & ~(0x5 << 16);
+	crtc_state->CRTC[NV_CIO_CRE_LCD__INDEX] = crtc_saved->CRTC[NV_CIO_CRE_LCD__INDEX];
+	state->pllsel = saved->pllsel & ~(PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK);
+	crtc_state->gpio_ext = crtc_saved->gpio_ext;
+}
+
+static void nv_crtc_restore(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	int head = nv_crtc->index;
+	uint8_t saved_cr21 = dev_priv->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21];
+
+	if (nv_two_heads(crtc->dev))
+		NVSetOwner(crtc->dev, head);
+
+	nouveau_hw_load_state(crtc->dev, head, &dev_priv->saved_reg);
+	nv_lock_vga_crtc_shadow(crtc->dev, head, saved_cr21);
+
+	nv_crtc->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
+
+	if (nv_two_heads(dev))
+		NVSetOwner(dev, nv_crtc->index);
+
+	funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+	NVBlankScreen(dev, nv_crtc->index, true);
+
+	/* Some more preperation. */
+	NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA);
+	if (dev_priv->card_type == NV_40) {
+		uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900);
+		NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900, reg900 & ~0x10000);
+	}
+}
+
+static void nv_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nouveau_hw_load_state(dev, nv_crtc->index, &dev_priv->mode_reg);
+	nv04_crtc_mode_set_base(crtc, crtc->x, crtc->y, NULL);
+
+#ifdef __BIG_ENDIAN
+	/* turn on LFB swapping */
+	{
+		uint8_t tmp = NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR);
+		tmp |= MASK(NV_CIO_CRE_RCR_ENDIAN_BIG);
+		NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR, tmp);
+	}
+#endif
+
+	funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static void nv_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	NV_DEBUG_KMS(crtc->dev, "\n");
+
+	if (!nv_crtc)
+		return;
+
+	drm_crtc_cleanup(crtc);
+
+	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	kfree(nv_crtc);
+}
+
+static void
+nv_crtc_gamma_load(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
+	int i;
+
+	rgbs = (struct rgb *)dev_priv->mode_reg.crtc_reg[nv_crtc->index].DAC;
+	for (i = 0; i < 256; i++) {
+		rgbs[i].r = nv_crtc->lut.r[i] >> 8;
+		rgbs[i].g = nv_crtc->lut.g[i] >> 8;
+		rgbs[i].b = nv_crtc->lut.b[i] >> 8;
+	}
+
+	nouveau_hw_load_state_palette(dev, nv_crtc->index, &dev_priv->mode_reg);
+}
+
+static void
+nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t size)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int i;
+
+	if (size != 256)
+		return;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = r[i];
+		nv_crtc->lut.g[i] = g[i];
+		nv_crtc->lut.b[i] = b[i];
+	}
+
+	/* We need to know the depth before we upload, but it's possible to
+	 * get called before a framebuffer is bound.  If this is the case,
+	 * mark the lut values as dirty by setting depth==0, and it'll be
+	 * uploaded on the first mode_set_base()
+	 */
+	if (!nv_crtc->base.fb) {
+		nv_crtc->lut.depth = 0;
+		return;
+	}
+
+	nv_crtc_gamma_load(crtc);
+}
+
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	int arb_burst, arb_lwm;
+	int ret;
+
+	ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		return ret;
+
+	if (old_fb) {
+		struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
+		nouveau_bo_unpin(ofb->nvbo);
+	}
+
+	nv_crtc->fb.offset = fb->nvbo->bo.offset;
+
+	if (nv_crtc->lut.depth != drm_fb->depth) {
+		nv_crtc->lut.depth = drm_fb->depth;
+		nv_crtc_gamma_load(crtc);
+	}
+
+	/* Update the framebuffer format. */
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3;
+	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8;
+	regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	if (crtc->fb->depth == 16)
+		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX);
+	NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL,
+		      regp->ramdac_gen_ctrl);
+
+	regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3;
+	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+		XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
+
+	/* Update the framebuffer location. */
+	regp->fb_start = nv_crtc->fb.offset & ~3;
+	regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8);
+	NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start);
+
+	/* Update the arbitration parameters. */
+	nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel,
+			 &arb_burst, &arb_lwm);
+
+	regp->CRTC[NV_CIO_CRE_FF_INDEX] = arb_burst;
+	regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = arb_lwm & 0xff;
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX);
+
+	if (dev_priv->card_type >= NV_30) {
+		regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8;
+		crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47);
+	}
+
+	return 0;
+}
+
+static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
+			       struct nouveau_bo *dst)
+{
+	int width = nv_cursor_width(dev);
+	uint32_t pixel;
+	int i, j;
+
+	for (i = 0; i < width; i++) {
+		for (j = 0; j < width; j++) {
+			pixel = nouveau_bo_rd32(src, i*64 + j);
+
+			nouveau_bo_wr16(dst, i*width + j, (pixel & 0x80000000) >> 16
+				     | (pixel & 0xf80000) >> 9
+				     | (pixel & 0xf800) >> 6
+				     | (pixel & 0xf8) >> 3);
+		}
+	}
+}
+
+static void nv11_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
+			       struct nouveau_bo *dst)
+{
+	uint32_t pixel;
+	int alpha, i;
+
+	/* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
+	 * cursors (though NPM in combination with fp dithering may not work on
+	 * nv11, from "nv" driver history)
+	 * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
+	 * blob uses, however we get given PM cursors so we use PM mode
+	 */
+	for (i = 0; i < 64 * 64; i++) {
+		pixel = nouveau_bo_rd32(src, i);
+
+		/* hw gets unhappy if alpha <= rgb values.  for a PM image "less
+		 * than" shouldn't happen; fix "equal to" case by adding one to
+		 * alpha channel (slightly inaccurate, but so is attempting to
+		 * get back to NPM images, due to limits of integer precision)
+		 */
+		alpha = pixel >> 24;
+		if (alpha > 0 && alpha < 255)
+			pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
+
+#ifdef __BIG_ENDIAN
+		{
+			struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+			if (dev_priv->chipset == 0x11) {
+				pixel = ((pixel & 0x000000ff) << 24) |
+					((pixel & 0x0000ff00) << 8) |
+					((pixel & 0x00ff0000) >> 8) |
+					((pixel & 0xff000000) >> 24);
+			}
+		}
+#endif
+
+		nouveau_bo_wr32(dst, i, pixel);
+	}
+}
+
+static int
+nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+		     uint32_t buffer_handle, uint32_t width, uint32_t height)
+{
+	struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+	struct drm_device *dev = dev_priv->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_bo *cursor = NULL;
+	struct drm_gem_object *gem;
+	int ret = 0;
+
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
+	if (!buffer_handle) {
+		nv_crtc->cursor.hide(nv_crtc, true);
+		return 0;
+	}
+
+	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
+	if (!gem)
+		return -EINVAL;
+	cursor = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_map(cursor);
+	if (ret)
+		goto out;
+
+	if (dev_priv->chipset >= 0x11)
+		nv11_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
+	else
+		nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
+
+	nouveau_bo_unmap(cursor);
+	nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset;
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
+	nv_crtc->cursor.show(nv_crtc, true);
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+static int
+nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->cursor.set_pos(nv_crtc, x, y);
+	return 0;
+}
+
+static const struct drm_crtc_funcs nv04_crtc_funcs = {
+	.save = nv_crtc_save,
+	.restore = nv_crtc_restore,
+	.cursor_set = nv04_crtc_cursor_set,
+	.cursor_move = nv04_crtc_cursor_move,
+	.gamma_set = nv_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = nv_crtc_destroy,
+};
+
+static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
+	.dpms = nv_crtc_dpms,
+	.prepare = nv_crtc_prepare,
+	.commit = nv_crtc_commit,
+	.mode_fixup = nv_crtc_mode_fixup,
+	.mode_set = nv_crtc_mode_set,
+	.mode_set_base = nv04_crtc_mode_set_base,
+	.load_lut = nv_crtc_gamma_load,
+};
+
+int
+nv04_crtc_create(struct drm_device *dev, int crtc_num)
+{
+	struct nouveau_crtc *nv_crtc;
+	int ret, i;
+
+	nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
+	if (!nv_crtc)
+		return -ENOMEM;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = i << 8;
+		nv_crtc->lut.g[i] = i << 8;
+		nv_crtc->lut.b[i] = i << 8;
+	}
+	nv_crtc->lut.depth = 0;
+
+	nv_crtc->index = crtc_num;
+	nv_crtc->last_dpms = NV_DPMS_CLEARED;
+
+	drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
+	drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
+	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
+
+	ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	}
+
+	nv04_cursor_init(nv_crtc);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_cursor.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_cursor.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_cursor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_cursor.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,70 @@
+#include "drmP.h"
+#include "drm_mode.h"
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+
+static void
+nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
+{
+	nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, true);
+}
+
+static void
+nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
+{
+	nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, false);
+}
+
+static void
+nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+	NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
+		      NV_PRAMDAC_CU_START_POS,
+		      XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
+		      XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X));
+}
+
+static void
+crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index)
+{
+	NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index,
+		       crtcstate->CRTC[index]);
+}
+
+static void
+nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct drm_crtc *crtc = &nv_crtc->base;
+
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] =
+		MASK(NV_CIO_CRE_HCUR_ASI) |
+		XLATE(offset, 17, NV_CIO_CRE_HCUR_ADDR0_ADR);
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] =
+		XLATE(offset, 11, NV_CIO_CRE_HCUR_ADDR1_ADR);
+	if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
+		regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |=
+			MASK(NV_CIO_CRE_HCUR_ADDR1_CUR_DBL);
+	regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = offset >> 24;
+
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+	if (dev_priv->card_type == NV_40)
+		nv_fix_nv40_hw_cursor(dev, nv_crtc->index);
+}
+
+int
+nv04_cursor_init(struct nouveau_crtc *crtc)
+{
+	crtc->cursor.set_offset = nv04_cursor_set_offset;
+	crtc->cursor.set_pos = nv04_cursor_set_pos;
+	crtc->cursor.hide = nv04_cursor_hide;
+	crtc->cursor.show = nv04_cursor_show;
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dac.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * 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 "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+int nv04_dac_output_offset(struct drm_encoder *encoder)
+{
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	int offset = 0;
+
+	if (dcb->or & (8 | OUTPUT_C))
+		offset += 0x68;
+	if (dcb->or & (8 | OUTPUT_B))
+		offset += 0x2000;
+
+	return offset;
+}
+
+/*
+ * arbitrary limit to number of sense oscillations tolerated in one sample
+ * period (observed to be at least 13 in "nvidia")
+ */
+#define MAX_HBLANK_OSC 20
+
+/*
+ * arbitrary limit to number of conflicting sample pairs to tolerate at a
+ * voltage step (observed to be at least 5 in "nvidia")
+ */
+#define MAX_SAMPLE_PAIRS 10
+
+static int sample_load_twice(struct drm_device *dev, bool sense[2])
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		bool sense_a, sense_b, sense_b_prime;
+		int j = 0;
+
+		/*
+		 * wait for bit 0 clear -- out of hblank -- (say reg value 0x4),
+		 * then wait for transition 0x4->0x5->0x4: enter hblank, leave
+		 * hblank again
+		 * use a 10ms timeout (guards against crtc being inactive, in
+		 * which case blank state would never change)
+		 */
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000000))
+			return -EBUSY;
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000001))
+			return -EBUSY;
+		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
+					0x00000001, 0x00000000))
+			return -EBUSY;
+
+		udelay(100);
+		/* when level triggers, sense is _LO_ */
+		sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+
+		/* take another reading until it agrees with sense_a... */
+		do {
+			udelay(100);
+			sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+			if (sense_a != sense_b) {
+				sense_b_prime =
+					nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+				if (sense_b == sense_b_prime) {
+					/* ... unless two consecutive subsequent
+					 * samples agree; sense_a is replaced */
+					sense_a = sense_b;
+					/* force mis-match so we loop */
+					sense_b = !sense_a;
+				}
+			}
+		} while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC);
+
+		if (j == MAX_HBLANK_OSC)
+			/* with so much oscillation, default to sense:LO */
+			sense[i] = false;
+		else
+			sense[i] = sense_a;
+	}
+
+	return 0;
+}
+
+static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
+						 struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode;
+	uint8_t saved_palette0[3], saved_palette_mask;
+	uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
+	int i;
+	uint8_t blue;
+	bool sense = true;
+
+	/*
+	 * for this detection to work, there needs to be a mode set up on the
+	 * CRTC.  this is presumed to be the case
+	 */
+
+	if (nv_two_heads(dev))
+		/* only implemented for head A for now */
+		NVSetOwner(dev, 0);
+
+	saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80);
+
+	saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
+
+	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL,
+		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
+
+	msleep(10);
+
+	saved_pi = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX,
+		       saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT)));
+	saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
+
+	nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
+	for (i = 0; i < 3; i++)
+		saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA);
+	saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK);
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0);
+
+	saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL,
+		      (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
+					   NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) |
+		      NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON);
+
+	blue = 8;	/* start of test range */
+
+	do {
+		bool sense_pair[2];
+
+		nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
+		/* testing blue won't find monochrome monitors.  I don't care */
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue);
+
+		i = 0;
+		/* take sample pairs until both samples in the pair agree */
+		do {
+			if (sample_load_twice(dev, sense_pair))
+				goto out;
+		} while ((sense_pair[0] != sense_pair[1]) &&
+							++i < MAX_SAMPLE_PAIRS);
+
+		if (i == MAX_SAMPLE_PAIRS)
+			/* too much oscillation defaults to LO */
+			sense = false;
+		else
+			sense = sense_pair[0];
+
+	/*
+	 * if sense goes LO before blue ramps to 0x18, monitor is not connected.
+	 * ergo, if blue gets to 0x18, monitor must be connected
+	 */
+	} while (++blue < 0x18 && sense);
+
+out:
+	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
+	nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+	for (i = 0; i < 3; i++)
+		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
+	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
+	NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
+
+	if (blue == 0x18) {
+		NV_INFO(dev, "Load detected on head A\n");
+		return connector_status_connected;
+	}
+
+	return connector_status_disconnected;
+}
+
+uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
+	uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
+		saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput;
+	int head;
+
+#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
+	if (dcb->type == OUTPUT_TV) {
+		testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
+
+		if (dev_priv->vbios->tvdactestval)
+			testval = dev_priv->vbios->tvdactestval;
+	} else {
+		testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
+
+		if (dev_priv->vbios->dactestval)
+			testval = dev_priv->vbios->dactestval;
+	}
+
+	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
+		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
+
+	saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2);
+
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
+	if (regoffset == 0x68) {
+		saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4);
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
+	}
+
+	saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1);
+	saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
+
+	msleep(4);
+
+	saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
+	head = (saved_routput & 0x100) >> 8;
+#if 0
+	/* if there's a spare crtc, using it will minimise flicker for the case
+	 * where the in-use crtc is in use by an off-chip tmds encoder */
+	if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
+		head ^= 1;
+#endif
+	/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
+	routput = (saved_routput & 0xfffffece) | head << 8;
+
+	if (dev_priv->card_type >= NV_40) {
+		if (dcb->type == OUTPUT_TV)
+			routput |= 0x1a << 16;
+		else
+			routput &= ~(0x1a << 16);
+	}
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, routput);
+	msleep(1);
+
+	temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA,
+		      NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval);
+	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
+		      temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
+	msleep(5);
+
+	sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
+
+	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
+		      temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, 0);
+
+	/* bios does something more complex for restoring, but I think this is good enough */
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
+	if (regoffset == 0x68)
+		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
+	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
+
+	return sample;
+}
+
+static enum drm_connector_status
+nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	uint32_t sample = nv17_dac_sample_load(encoder);
+
+	if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
+		NV_INFO(dev, "Load detected on output %c\n",
+			'@' + ffs(dcb->or));
+		return connector_status_connected;
+	} else {
+		return connector_status_disconnected;
+	}
+}
+
+static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void nv04_dac_prepare(struct drm_encoder *encoder)
+{
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44))
+		crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] = 0;
+}
+
+
+static void nv04_dac_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+
+	if (nv_gf4_disp_arch(dev)) {
+		struct drm_encoder *rebind;
+		uint32_t dac_offset = nv04_dac_output_offset(encoder);
+		uint32_t otherdac;
+
+		/* bit 16-19 are bits that are set on some G70 cards,
+		 * but don't seem to have much effect */
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
+			      head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK);
+		/* force any other vga encoders to bind to the other crtc */
+		list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) {
+			if (rebind == encoder
+			    || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG)
+				continue;
+
+			dac_offset = nv04_dac_output_offset(rebind);
+			otherdac = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset);
+			NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
+				      (otherdac & ~0x0100) | (head ^ 1) << 8);
+		}
+	}
+
+	/* This could use refinement for flatpanels, but it should work this way */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
+}
+
+static void nv04_dac_commit(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+
+	if (nv_gf4_disp_arch(dev)) {
+		uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1];
+		int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder);
+		uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off);
+
+		if (enable) {
+			*dac_users |= 1 << dcb->index;
+			NVWriteRAMDAC(dev, 0, dacclk_off, dacclk | NV_PRAMDAC_DACCLK_SEL_DACCLK);
+
+		} else {
+			*dac_users &= ~(1 << dcb->index);
+			if (!*dac_users)
+				NVWriteRAMDAC(dev, 0, dacclk_off,
+					dacclk & ~NV_PRAMDAC_DACCLK_SEL_DACCLK);
+		}
+	}
+}
+
+static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
+}
+
+static void nv04_dac_save(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_gf4_disp_arch(dev))
+		nv_encoder->restore.output = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
+							  nv04_dac_output_offset(encoder));
+}
+
+static void nv04_dac_restore(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_gf4_disp_arch(dev))
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder),
+			      nv_encoder->restore.output);
+
+	nv_encoder->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv04_dac_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	NV_DEBUG_KMS(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = {
+	.dpms = nv04_dac_dpms,
+	.save = nv04_dac_save,
+	.restore = nv04_dac_restore,
+	.mode_fixup = nv04_dac_mode_fixup,
+	.prepare = nv04_dac_prepare,
+	.commit = nv04_dac_commit,
+	.mode_set = nv04_dac_mode_set,
+	.detect = nv04_dac_detect
+};
+
+static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = {
+	.dpms = nv04_dac_dpms,
+	.save = nv04_dac_save,
+	.restore = nv04_dac_restore,
+	.mode_fixup = nv04_dac_mode_fixup,
+	.prepare = nv04_dac_prepare,
+	.commit = nv04_dac_commit,
+	.mode_set = nv04_dac_mode_set,
+	.detect = nv17_dac_detect
+};
+
+static const struct drm_encoder_funcs nv04_dac_funcs = {
+	.destroy = nv04_dac_destroy,
+};
+
+int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	const struct drm_encoder_helper_funcs *helper;
+	struct drm_encoder *encoder;
+	struct nouveau_encoder *nv_encoder = NULL;
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	if (nv_gf4_disp_arch(dev))
+		helper = &nv17_dac_helper_funcs;
+	else
+		helper = &nv04_dac_helper_funcs;
+
+	drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC);
+	drm_encoder_helper_add(encoder, helper);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_dfp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,623 @@
+/*
+ * Copyright 2003 NVIDIA, Corporation
+ * Copyright 2006 Dave Airlie
+ * Copyright 2007 Maarten Maathuis
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * 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 "drmP.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nvreg.h"
+
+#define FP_TG_CONTROL_ON  (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |		\
+			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
+#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE |	\
+			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)
+
+static inline bool is_fpc_off(uint32_t fpc)
+{
+	return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) ==
+			FP_TG_CONTROL_OFF);
+}
+
+int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent)
+{
+	/* special case of nv_read_tmds to find crtc associated with an output.
+	 * this does not give a correct answer for off-chip dvi, but there's no
+	 * use for such an answer anyway
+	 */
+	int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+
+	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
+	NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
+	return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac;
+}
+
+void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
+			int head, bool dl)
+{
+	/* The BIOS scripts don't do this for us, sadly
+	 * Luckily we do know the values ;-)
+	 *
+	 * head < 0 indicates we wish to force a setting with the overrideval
+	 * (for VT restore etc.)
+	 */
+
+	int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+	uint8_t tmds04 = 0x80;
+
+	if (head != ramdac)
+		tmds04 = 0x88;
+
+	if (dcbent->type == OUTPUT_LVDS)
+		tmds04 |= 0x01;
+
+	nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04);
+
+	if (dl)	/* dual link */
+		nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08);
+}
+
+void nv04_dfp_disable(struct drm_device *dev, int head)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+
+	if (NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL) &
+	    FP_TG_CONTROL_ON) {
+		/* digital remnants must be cleaned before new crtc
+		 * values programmed.  delay is time for the vga stuff
+		 * to realise it's in control again
+		 */
+		NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
+			      FP_TG_CONTROL_OFF);
+		msleep(50);
+	}
+	/* don't inadvertently turn it on when state written later */
+	crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
+}
+
+void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct nouveau_crtc *nv_crtc;
+	uint32_t *fpc;
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		nv_crtc = nouveau_crtc(encoder->crtc);
+		fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+
+		if (is_fpc_off(*fpc)) {
+			/* using saved value is ok, as (is_digital && dpms_on &&
+			 * fp_control==OFF) is (at present) *only* true when
+			 * fpc's most recent change was by below "off" code
+			 */
+			*fpc = nv_crtc->dpms_saved_fp_control;
+		}
+
+		nv_crtc->fp_users |= 1 << nouveau_encoder(encoder)->dcb->index;
+		NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
+	} else {
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			nv_crtc = nouveau_crtc(crtc);
+			fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+
+			nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index);
+			if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
+				nv_crtc->dpms_saved_fp_control = *fpc;
+				/* cut the FP output */
+				*fpc &= ~FP_TG_CONTROL_ON;
+				*fpc |= FP_TG_CONTROL_OFF;
+				NVWriteRAMDAC(dev, nv_crtc->index,
+					      NV_PRAMDAC_FP_TG_CONTROL, *fpc);
+			}
+		}
+	}
+}
+
+static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
+
+	/* For internal panels and gpu scaling on DVI we need the native mode */
+	if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
+		if (!nv_connector->native_mode)
+			return false;
+		nv_encoder->mode = *nv_connector->native_mode;
+		adjusted_mode->clock = nv_connector->native_mode->clock;
+	} else {
+		nv_encoder->mode = *adjusted_mode;
+	}
+
+	return true;
+}
+
+static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
+				     struct nouveau_encoder *nv_encoder, int head)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;
+
+	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
+		return;
+
+	/* SEL_CLK is only used on the primary ramdac
+	 * It toggles spread spectrum PLL output and sets the bindings of PLLs
+	 * to heads on digital outputs
+	 */
+	if (head)
+		state->sel_clk |= bits1618;
+	else
+		state->sel_clk &= ~bits1618;
+
+	/* nv30:
+	 *	bit 0		NVClk spread spectrum on/off
+	 *	bit 2		MemClk spread spectrum on/off
+	 * 	bit 4		PixClk1 spread spectrum on/off toggle
+	 * 	bit 6		PixClk2 spread spectrum on/off toggle
+	 *
+	 * nv40 (observations from bios behaviour and mmio traces):
+	 * 	bits 4&6	as for nv30
+	 * 	bits 5&7	head dependent as for bits 4&6, but do not appear with 4&6;
+	 * 			maybe a different spread mode
+	 * 	bits 8&10	seen on dual-link dvi outputs, purpose unknown (set by POST scripts)
+	 * 	The logic behind turning spread spectrum on/off in the first place,
+	 * 	and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
+	 * 	entry has the necessary info)
+	 */
+	if (nv_encoder->dcb->type == OUTPUT_LVDS && dev_priv->saved_reg.sel_clk & 0xf0) {
+		int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1;
+
+		state->sel_clk &= ~0xf0;
+		state->sel_clk |= (head ? 0x40 : 0x10) << shift;
+	}
+}
+
+static void nv04_dfp_prepare(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+	uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
+	uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_prepare_sel_clk(dev, nv_encoder, head);
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(*cr_lcd & 0x44)) {
+		*cr_lcd = 0x3;
+
+		if (nv_two_heads(dev)) {
+			if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP)
+				*cr_lcd |= head ? 0x0 : 0x8;
+			else {
+				*cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
+				if (nv_encoder->dcb->type == OUTPUT_LVDS)
+					*cr_lcd |= 0x30;
+				if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
+					/* avoid being connected to both crtcs */
+					*cr_lcd_oth &= ~0x30;
+					NVWriteVgaCrtc(dev, head ^ 1,
+						       NV_CIO_CRE_LCD__INDEX,
+						       *cr_lcd_oth);
+				}
+			}
+		}
+	}
+}
+
+
+static void nv04_dfp_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+	struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+	struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_display_mode *output_mode = &nv_encoder->mode;
+	uint32_t mode_ratio, panel_ratio;
+
+	NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
+	drm_mode_debug_printmodeline(output_mode);
+
+	/* Initialize the FP registers in this CRTC. */
+	regp->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
+	regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
+	if (!nv_gf4_disp_arch(dev) ||
+	    (output_mode->hsync_start - output_mode->hdisplay) >=
+					dev_priv->vbios->digital_min_front_porch)
+		regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
+	else
+		regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1;
+	regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
+	regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
+	regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
+	regp->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - 1;
+
+	regp->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
+	regp->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
+	regp->fp_vert_regs[FP_CRTC] = output_mode->vtotal - 5 - 1;
+	regp->fp_vert_regs[FP_SYNC_START] = output_mode->vsync_start - 1;
+	regp->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
+	regp->fp_vert_regs[FP_VALID_START] = 0;
+	regp->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - 1;
+
+	/* bit26: a bit seen on some g7x, no as yet discernable purpose */
+	regp->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
+			   (savep->fp_control & (1 << 26 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG));
+	/* Deal with vsync/hsync polarity */
+	/* LVDS screens do set this, but modes with +ve syncs are very rare */
+	if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
+	if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
+	/* panel scaling first, as native would get set otherwise */
+	if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
+	    nv_connector->scaling_mode == DRM_MODE_SCALE_CENTER)	/* panel handles it */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER;
+	else if (adjusted_mode->hdisplay == output_mode->hdisplay &&
+		 adjusted_mode->vdisplay == output_mode->vdisplay) /* native mode */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE;
+	else /* gpu needs to scale */
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE;
+	if (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
+		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
+	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP &&
+	    output_mode->clock > 165000)
+		regp->fp_control |= (2 << 24);
+	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+		bool duallink, dummy;
+
+		nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode->
+					      clock, &duallink, &dummy);
+		if (duallink)
+			regp->fp_control |= (8 << 28);
+	} else
+	if (output_mode->clock > 165000)
+		regp->fp_control |= (8 << 28);
+
+	regp->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
+			   NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
+			   NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
+			   NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
+			   NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
+			   NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
+			   NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
+
+	/* We want automatic scaling */
+	regp->fp_debug_1 = 0;
+	/* This can override HTOTAL and VTOTAL */
+	regp->fp_debug_2 = 0;
+
+	/* Use 20.12 fixed point format to avoid floats */
+	mode_ratio = (1 << 12) * adjusted_mode->hdisplay / adjusted_mode->vdisplay;
+	panel_ratio = (1 << 12) * output_mode->hdisplay / output_mode->vdisplay;
+	/* if ratios are equal, SCALE_ASPECT will automatically (and correctly)
+	 * get treated the same as SCALE_FULLSCREEN */
+	if (nv_connector->scaling_mode == DRM_MODE_SCALE_ASPECT &&
+	    mode_ratio != panel_ratio) {
+		uint32_t diff, scale;
+		bool divide_by_2 = nv_gf4_disp_arch(dev);
+
+		if (mode_ratio < panel_ratio) {
+			/* vertical needs to expand to glass size (automatic)
+			 * horizontal needs to be scaled at vertical scale factor
+			 * to maintain aspect */
+
+			scale = (1 << 12) * adjusted_mode->vdisplay / output_mode->vdisplay;
+			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
+					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
+
+			/* restrict area of screen used, horizontally */
+			diff = output_mode->hdisplay -
+			       output_mode->vdisplay * mode_ratio / (1 << 12);
+			regp->fp_horiz_regs[FP_VALID_START] += diff / 2;
+			regp->fp_horiz_regs[FP_VALID_END] -= diff / 2;
+		}
+
+		if (mode_ratio > panel_ratio) {
+			/* horizontal needs to expand to glass size (automatic)
+			 * vertical needs to be scaled at horizontal scale factor
+			 * to maintain aspect */
+
+			scale = (1 << 12) * adjusted_mode->hdisplay / output_mode->hdisplay;
+			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
+					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE);
+
+			/* restrict area of screen used, vertically */
+			diff = output_mode->vdisplay -
+			       (1 << 12) * output_mode->hdisplay / mode_ratio;
+			regp->fp_vert_regs[FP_VALID_START] += diff / 2;
+			regp->fp_vert_regs[FP_VALID_END] -= diff / 2;
+		}
+	}
+
+	/* Output property. */
+	if (nv_connector->use_dithering) {
+		if (dev_priv->chipset == 0x11)
+			regp->dither = savep->dither | 0x00010000;
+		else {
+			int i;
+			regp->dither = savep->dither | 0x00000001;
+			for (i = 0; i < 3; i++) {
+				regp->dither_regs[i] = 0xe4e4e4e4;
+				regp->dither_regs[i + 3] = 0x44444444;
+			}
+		}
+	} else {
+		if (dev_priv->chipset != 0x11) {
+			/* reset them */
+			int i;
+			for (i = 0; i < 3; i++) {
+				regp->dither_regs[i] = savep->dither_regs[i];
+				regp->dither_regs[i + 3] = savep->dither_regs[i + 3];
+			}
+		}
+		regp->dither = savep->dither;
+	}
+
+	regp->fp_margin_color = 0;
+}
+
+static void nv04_dfp_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct dcb_entry *dcbe = nv_encoder->dcb;
+	int head = nouveau_crtc(encoder->crtc)->index;
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+
+	if (dcbe->type == OUTPUT_TMDS)
+		run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
+	else if (dcbe->type == OUTPUT_LVDS)
+		call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock);
+
+	/* update fp_control state for any changes made by scripts,
+	 * so correct value is written at DPMS on */
+	dev_priv->mode_reg.crtc_reg[head].fp_control =
+		NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
+
+	/* This could use refinement for flatpanels, but it should work this way */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+static inline bool is_powersaving_dpms(int mode)
+{
+	return (mode != DRM_MODE_DPMS_ON);
+}
+
+static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	if (was_powersaving && is_powersaving_dpms(mode))
+		return;
+
+	if (nv_encoder->dcb->lvdsconf.use_power_scripts) {
+		struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
+
+		/* when removing an output, crtc may not be set, but PANEL_OFF
+		 * must still be run
+		 */
+		int head = crtc ? nouveau_crtc(crtc)->index :
+			   nv04_dfp_get_bound_head(dev, nv_encoder->dcb);
+
+		if (mode == DRM_MODE_DPMS_ON) {
+			if (!nv_connector->native_mode) {
+				NV_ERROR(dev, "Not turning on LVDS without native mode\n");
+				return;
+			}
+			call_lvds_script(dev, nv_encoder->dcb, head,
+					 LVDS_PANEL_ON, nv_connector->native_mode->clock);
+		} else
+			/* pxclk of 0 is fine for PANEL_OFF, and for a
+			 * disconnected LVDS encoder there is no native_mode
+			 */
+			call_lvds_script(dev, nv_encoder->dcb, head,
+					 LVDS_PANEL_OFF, 0);
+	}
+
+	nv04_dfp_update_fp_control(encoder, mode);
+
+	if (mode == DRM_MODE_DPMS_ON)
+		nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index);
+	else {
+		dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
+		dev_priv->mode_reg.sel_clk &= ~0xf0;
+	}
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+}
+
+static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (nv_encoder->last_dpms == mode)
+		return;
+	nv_encoder->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
+		     mode, nv_encoder->dcb->index);
+
+	nv04_dfp_update_fp_control(encoder, mode);
+}
+
+static void nv04_dfp_save(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+
+	if (nv_two_heads(dev))
+		nv_encoder->restore.head =
+			nv04_dfp_get_bound_head(dev, nv_encoder->dcb);
+}
+
+static void nv04_dfp_restore(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nv_encoder->restore.head;
+
+	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+		struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode;
+		if (native_mode)
+			call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
+					 native_mode->clock);
+		else
+			NV_ERROR(dev, "Not restoring LVDS without native mode\n");
+
+	} else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
+		int clock = nouveau_hw_pllvals_to_clk
+					(&dev_priv->saved_reg.crtc_reg[head].pllvals);
+
+		run_tmds_table(dev, nv_encoder->dcb, head, clock);
+	}
+
+	nv_encoder->last_dpms = NV_DPMS_CLEARED;
+}
+
+static void nv04_dfp_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	NV_DEBUG_KMS(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
+	.dpms = nv04_lvds_dpms,
+	.save = nv04_dfp_save,
+	.restore = nv04_dfp_restore,
+	.mode_fixup = nv04_dfp_mode_fixup,
+	.prepare = nv04_dfp_prepare,
+	.commit = nv04_dfp_commit,
+	.mode_set = nv04_dfp_mode_set,
+	.detect = NULL,
+};
+
+static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = {
+	.dpms = nv04_tmds_dpms,
+	.save = nv04_dfp_save,
+	.restore = nv04_dfp_restore,
+	.mode_fixup = nv04_dfp_mode_fixup,
+	.prepare = nv04_dfp_prepare,
+	.commit = nv04_dfp_commit,
+	.mode_set = nv04_dfp_mode_set,
+	.detect = NULL,
+};
+
+static const struct drm_encoder_funcs nv04_dfp_funcs = {
+	.destroy = nv04_dfp_destroy,
+};
+
+int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	const struct drm_encoder_helper_funcs *helper;
+	struct drm_encoder *encoder;
+	struct nouveau_encoder *nv_encoder = NULL;
+	int type;
+
+	switch (entry->type) {
+	case OUTPUT_TMDS:
+		type = DRM_MODE_ENCODER_TMDS;
+		helper = &nv04_tmds_helper_funcs;
+		break;
+	case OUTPUT_LVDS:
+		type = DRM_MODE_ENCODER_LVDS;
+		helper = &nv04_lvds_helper_funcs;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
+	drm_encoder_helper_add(encoder, helper);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_display.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_display.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_display.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2009 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.
+ *
+ * Author: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+
+#include "nouveau_drv.h"
+#include "nouveau_fb.h"
+#include "nouveau_hw.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+
+#define MULTIPLE_ENCODERS(e) (e & (e - 1))
+
+static void
+nv04_display_store_initial_head_owner(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset != 0x11) {
+		dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
+		goto ownerknown;
+	}
+
+	/* reading CR44 is broken on nv11, so we attempt to infer it */
+	if (nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28))	/* heads tied, restore both */
+		dev_priv->crtc_owner = 0x4;
+	else {
+		uint8_t slaved_on_A, slaved_on_B;
+		bool tvA = false;
+		bool tvB = false;
+
+		NVLockVgaCrtcs(dev, false);
+
+		slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
+									0x80;
+		if (slaved_on_B)
+			tvB = !(NVReadVgaCrtc(dev, 1, NV_CIO_CRE_LCD__INDEX) &
+					MASK(NV_CIO_CRE_LCD_LCD_SELECT));
+
+		slaved_on_A = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX) &
+									0x80;
+		if (slaved_on_A)
+			tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
+					MASK(NV_CIO_CRE_LCD_LCD_SELECT));
+
+		NVLockVgaCrtcs(dev, true);
+
+		if (slaved_on_A && !tvA)
+			dev_priv->crtc_owner = 0x0;
+		else if (slaved_on_B && !tvB)
+			dev_priv->crtc_owner = 0x3;
+		else if (slaved_on_A)
+			dev_priv->crtc_owner = 0x0;
+		else if (slaved_on_B)
+			dev_priv->crtc_owner = 0x3;
+		else
+			dev_priv->crtc_owner = 0x0;
+	}
+
+ownerknown:
+	NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner);
+
+	/* we need to ensure the heads are not tied henceforth, or reading any
+	 * 8 bit reg on head B will fail
+	 * setting a single arbitrary head solves that */
+	NVSetOwner(dev, 0);
+}
+
+int
+nv04_display_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+	uint16_t connector[16] = { 0 };
+	int i, ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	if (nv_two_heads(dev))
+		nv04_display_store_initial_head_owner(dev);
+	nouveau_hw_save_vga_fonts(dev, 1);
+
+	drm_mode_config_init(dev);
+	drm_mode_create_scaling_mode_property(dev);
+	drm_mode_create_dithering_property(dev);
+
+	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+	switch (dev_priv->card_type) {
+	case NV_04:
+		dev->mode_config.max_width = 2048;
+		dev->mode_config.max_height = 2048;
+		break;
+	default:
+		dev->mode_config.max_width = 4096;
+		dev->mode_config.max_height = 4096;
+		break;
+	}
+
+	dev->mode_config.fb_base = dev_priv->fb_phys;
+
+	nv04_crtc_create(dev, 0);
+	if (nv_two_heads(dev))
+		nv04_crtc_create(dev, 1);
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dcb->entry[i];
+
+		switch (dcbent->type) {
+		case OUTPUT_ANALOG:
+			ret = nv04_dac_create(dev, dcbent);
+			break;
+		case OUTPUT_LVDS:
+		case OUTPUT_TMDS:
+			ret = nv04_dfp_create(dev, dcbent);
+			break;
+		case OUTPUT_TV:
+			if (dcbent->location == DCB_LOC_ON_CHIP)
+				ret = nv17_tv_create(dev, dcbent);
+			else
+				ret = nv04_tv_create(dev, dcbent);
+			break;
+		default:
+			NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
+			continue;
+		}
+
+		if (ret)
+			continue;
+
+		connector[dcbent->connector] |= (1 << dcbent->type);
+	}
+
+	for (i = 0; i < dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dcb->entry[i];
+		uint16_t encoders;
+		int type;
+
+		encoders = connector[dcbent->connector];
+		if (!(encoders & (1 << dcbent->type)))
+			continue;
+		connector[dcbent->connector] = 0;
+
+		switch (dcbent->type) {
+		case OUTPUT_ANALOG:
+			if (!MULTIPLE_ENCODERS(encoders))
+				type = DRM_MODE_CONNECTOR_VGA;
+			else
+				type = DRM_MODE_CONNECTOR_DVII;
+			break;
+		case OUTPUT_TMDS:
+			if (!MULTIPLE_ENCODERS(encoders))
+				type = DRM_MODE_CONNECTOR_DVID;
+			else
+				type = DRM_MODE_CONNECTOR_DVII;
+			break;
+		case OUTPUT_LVDS:
+			type = DRM_MODE_CONNECTOR_LVDS;
+#if 0
+			/* don't create i2c adapter when lvds ddc not allowed */
+			if (dcbent->lvdsconf.use_straps_for_mode ||
+			    dev_priv->vbios->fp_no_ddc)
+				i2c_index = 0xf;
+#endif
+			break;
+		case OUTPUT_TV:
+			type = DRM_MODE_CONNECTOR_TV;
+			break;
+		default:
+			type = DRM_MODE_CONNECTOR_Unknown;
+			continue;
+		}
+
+		nouveau_connector_create(dev, dcbent->connector, type);
+	}
+
+	/* Save previous state */
+	NVLockVgaCrtcs(dev, false);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->save(crtc);
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->save(encoder);
+	}
+
+	return 0;
+}
+
+void
+nv04_display_destroy(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	/* Turn every CRTC off. */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct drm_mode_set modeset = {
+			.crtc = crtc,
+		};
+
+		crtc->funcs->set_config(&modeset);
+	}
+
+	/* Restore state */
+	NVLockVgaCrtcs(dev, false);
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->restore(encoder);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->restore(crtc);
+
+	drm_mode_config_cleanup(dev);
+
+	nouveau_hw_save_vga_fonts(dev, 0);
+}
+
+void
+nv04_display_restore(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+
+	NVLockVgaCrtcs(dev, false);
+
+	/* meh.. modeset apparently doesn't setup all the regs and depends
+	 * on pre-existing state, for now load the state of the card *before*
+	 * nouveau was loaded, and then do a modeset.
+	 *
+	 * best thing to do probably is to make save/restore routines not
+	 * save/restore "pre-load" state, but more general so we can save
+	 * on suspend too.
+	 */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct drm_encoder_helper_funcs *func = encoder->helper_private;
+
+		func->restore(encoder);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		crtc->funcs->restore(crtc);
+
+	if (nv_two_heads(dev)) {
+		NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n",
+			dev_priv->crtc_owner);
+		NVSetOwner(dev, dev_priv->crtc_owner);
+	}
+
+	NVLockVgaCrtcs(dev, true);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,21 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_fb_init(struct drm_device *dev)
+{
+	/* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
+	 * nvidia reading PFB_CFG_0, then writing back its original value.
+	 * (which was 0x701114 in this case)
+	 */
+
+	nv_wr32(dev, NV04_PFB_CFG0, 0x1114);
+	return 0;
+}
+
+void
+nv04_fb_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fbcon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2009 Ben Skeggs
+ * Copyright 2008 Stuart Bennett
+ *
+ * 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 "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_fbcon.h"
+
+void
+nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_copyarea(info, region);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3);
+	OUT_RING(chan, (region->sy << 16) | region->sx);
+	OUT_RING(chan, (region->dy << 16) | region->dx);
+	OUT_RING(chan, (region->height << 16) | region->width);
+	FIRE_RING(chan);
+}
+
+void
+nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1);
+	OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3);
+	BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1);
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
+		OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]);
+	else
+		OUT_RING(chan, rect->color);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2);
+	OUT_RING(chan, (rect->dx << 16) | rect->dy);
+	OUT_RING(chan, (rect->width << 16) | rect->height);
+	FIRE_RING(chan);
+}
+
+void
+nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	uint32_t fg;
+	uint32_t bg;
+	uint32_t dsize;
+	uint32_t width;
+	uint32_t *data = (uint32_t *)image->data;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (image->depth != 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	width = (image->width + 31) & ~31;
+	dsize = (width * image->height) >> 5;
+
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
+		bg = ((uint32_t *) info->pseudo_palette)[image->bg_color];
+	} else {
+		fg = image->fg_color;
+		bg = image->bg_color;
+	}
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x0be4, 7);
+	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+	OUT_RING(chan, ((image->dy + image->height) << 16) |
+			 ((image->dx + image->width) & 0xffff));
+	OUT_RING(chan, bg);
+	OUT_RING(chan, fg);
+	OUT_RING(chan, (image->height << 16) | image->width);
+	OUT_RING(chan, (image->height << 16) | width);
+	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+
+	while (dsize) {
+		int iter_len = dsize > 128 ? 128 : dsize;
+
+		if (RING_SPACE(chan, iter_len + 1)) {
+			nouveau_fbcon_gpu_lockup(info);
+			cfb_imageblit(info, image);
+			return;
+		}
+
+		BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len);
+		OUT_RINGp(chan, data, iter_len);
+		data += iter_len;
+		dsize -= iter_len;
+	}
+
+	FIRE_RING(chan);
+}
+
+static int
+nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_gr_new(dev_priv->channel, class, &obj);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, handle, obj, NULL);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int
+nv04_fbcon_accel_init(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	const int sub = NvSubCtxSurf2D;
+	int surface_fmt, pattern_fmt, rect_fmt;
+	int ret;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		surface_fmt = 1;
+		pattern_fmt = 3;
+		rect_fmt = 3;
+		break;
+	case 16:
+		surface_fmt = 4;
+		pattern_fmt = 1;
+		rect_fmt = 1;
+		break;
+	case 32:
+		switch (info->var.transp.length) {
+		case 0: /* depth 24 */
+		case 8: /* depth 32 */
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		surface_fmt = 6;
+		pattern_fmt = 3;
+		rect_fmt = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ?
+				   0x0062 : 0x0042, NvCtxSurf2D);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0019, NvClipRect);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0043, NvRop);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x0044, NvImagePatt);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, 0x004a, NvGdiRect);
+	if (ret)
+		return ret;
+
+	ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ?
+				   0x009f : 0x005f, NvImageBlit);
+	if (ret)
+		return ret;
+
+	if (RING_SPACE(chan, 49)) {
+		nouveau_fbcon_gpu_lockup(info);
+		return 0;
+	}
+
+	BEGIN_RING(chan, sub, 0x0000, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, sub, 0x0184, 2);
+	OUT_RING(chan, NvDmaFB);
+	OUT_RING(chan, NvDmaFB);
+	BEGIN_RING(chan, sub, 0x0300, 4);
+	OUT_RING(chan, surface_fmt);
+	OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16));
+	OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
+	OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
+
+	BEGIN_RING(chan, sub, 0x0000, 1);
+	OUT_RING(chan, NvRop);
+	BEGIN_RING(chan, sub, 0x0300, 1);
+	OUT_RING(chan, 0x55);
+
+	BEGIN_RING(chan, sub, 0x0000, 1);
+	OUT_RING(chan, NvImagePatt);
+	BEGIN_RING(chan, sub, 0x0300, 8);
+	OUT_RING(chan, pattern_fmt);
+#ifdef __BIG_ENDIAN
+	OUT_RING(chan, 2);
+#else
+	OUT_RING(chan, 1);
+#endif
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+	OUT_RING(chan, ~0);
+
+	BEGIN_RING(chan, sub, 0x0000, 1);
+	OUT_RING(chan, NvClipRect);
+	BEGIN_RING(chan, sub, 0x0300, 2);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual);
+
+	BEGIN_RING(chan, NvSubImageBlit, 0x0000, 1);
+	OUT_RING(chan, NvImageBlit);
+	BEGIN_RING(chan, NvSubImageBlit, 0x019c, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, NvSubImageBlit, 0x02fc, 1);
+	OUT_RING(chan, 3);
+
+	BEGIN_RING(chan, NvSubGdiRect, 0x0000, 1);
+	OUT_RING(chan, NvGdiRect);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0198, 1);
+	OUT_RING(chan, NvCtxSurf2D);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0188, 2);
+	OUT_RING(chan, NvImagePatt);
+	OUT_RING(chan, NvRop);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0304, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSubGdiRect, 0x0300, 1);
+	OUT_RING(chan, rect_fmt);
+	BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1);
+	OUT_RING(chan, 3);
+
+	FIRE_RING(chan);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_fifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE))
+#define NV04_RAMFC__SIZE 32
+#define NV04_RAMFC_DMA_PUT                                       0x00
+#define NV04_RAMFC_DMA_GET                                       0x04
+#define NV04_RAMFC_DMA_INSTANCE                                  0x08
+#define NV04_RAMFC_DMA_STATE                                     0x0C
+#define NV04_RAMFC_DMA_FETCH                                     0x10
+#define NV04_RAMFC_ENGINE                                        0x14
+#define NV04_RAMFC_PULL1_ENGINE                                  0x18
+
+#define RAMFC_WR(offset, val) nv_wo32(dev, chan->ramfc->gpuobj, \
+					 NV04_RAMFC_##offset/4, (val))
+#define RAMFC_RD(offset)      nv_ro32(dev, chan->ramfc->gpuobj, \
+					 NV04_RAMFC_##offset/4)
+
+void
+nv04_fifo_disable(struct drm_device *dev)
+{
+	uint32_t tmp;
+
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, tmp & ~1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
+	tmp = nv_rd32(dev, NV03_PFIFO_CACHE1_PULL1);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, tmp & ~1);
+}
+
+void
+nv04_fifo_enable(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
+}
+
+bool
+nv04_fifo_reassign(struct drm_device *dev, bool enable)
+{
+	uint32_t reassign = nv_rd32(dev, NV03_PFIFO_CACHES);
+
+	nv_wr32(dev, NV03_PFIFO_CACHES, enable ? 1 : 0);
+	return (reassign == 1);
+}
+
+bool
+nv04_fifo_cache_flush(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+	uint64_t start = ptimer->read(dev);
+
+	do {
+		if (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) ==
+		    nv_rd32(dev, NV03_PFIFO_CACHE1_PUT))
+			return true;
+
+	} while (ptimer->read(dev) - start < 100000000);
+
+	NV_ERROR(dev, "Timeout flushing the PFIFO cache.\n");
+
+	return false;
+}
+
+bool
+nv04_fifo_cache_pull(struct drm_device *dev, bool enable)
+{
+	uint32_t pull = nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0);
+
+	if (enable) {
+		nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull | 1);
+	} else {
+		nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, pull & ~1);
+		nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
+	}
+
+	return !!(pull & 1);
+}
+
+int
+nv04_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv04_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0,
+						NV04_RAMFC__SIZE,
+						NVOBJ_FLAG_ZERO_ALLOC |
+						NVOBJ_FLAG_ZERO_FREE,
+						NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	/* Setup initial state */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	RAMFC_WR(DMA_PUT, chan->pushbuf_base);
+	RAMFC_WR(DMA_GET, chan->pushbuf_base);
+	RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
+	RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			     0));
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv04_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv04_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV04_RAMFC(chid), tmp;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	tmp = nv_ri32(dev, fc + 8);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 12));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24));
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv04_fifo_load_context(struct nouveau_channel *chan)
+{
+	uint32_t tmp;
+
+	nv_wr32(chan->dev, NV03_PFIFO_CACHE1_PUSH1,
+			   NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv04_fifo_do_load_context(chan->dev, chan->id);
+	nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv04_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan = NULL;
+	uint32_t tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+
+	chan = dev_priv->fifos[chid];
+	if (!chan) {
+		NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid);
+		return -EINVAL;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
+	tmp |= nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE);
+	RAMFC_WR(DMA_INSTANCE, tmp);
+	RAMFC_WR(DMA_STATE, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
+	RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv04_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+	return 0;
+}
+
+static void
+nv04_fifo_init_reset(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x002044, 0x0101ffff);
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003000, 0x00000000);
+	nv_wr32(dev, 0x003050, 0x00000000);
+	nv_wr32(dev, 0x003200, 0x00000000);
+	nv_wr32(dev, 0x003250, 0x00000000);
+	nv_wr32(dev, 0x003220, 0x00000000);
+
+	nv_wr32(dev, 0x003250, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+	nv_wr32(dev, 0x003210, 0x00000000);
+}
+
+static void
+nv04_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+	nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+}
+
+static void
+nv04_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv04_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv04_fifo_init_reset(dev);
+	nv04_fifo_init_ramxx(dev);
+
+	nv04_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv04_fifo_init_intr(dev);
+	pfifo->enable(dev);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_graph.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_graph.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_graph.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_graph.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2007 Stephane Marchesin
+ * 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, 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+
+static uint32_t nv04_graph_ctx_regs[] = {
+	0x0040053c,
+	0x00400544,
+	0x00400540,
+	0x00400548,
+	NV04_PGRAPH_CTX_SWITCH1,
+	NV04_PGRAPH_CTX_SWITCH2,
+	NV04_PGRAPH_CTX_SWITCH3,
+	NV04_PGRAPH_CTX_SWITCH4,
+	NV04_PGRAPH_CTX_CACHE1,
+	NV04_PGRAPH_CTX_CACHE2,
+	NV04_PGRAPH_CTX_CACHE3,
+	NV04_PGRAPH_CTX_CACHE4,
+	0x00400184,
+	0x004001a4,
+	0x004001c4,
+	0x004001e4,
+	0x00400188,
+	0x004001a8,
+	0x004001c8,
+	0x004001e8,
+	0x0040018c,
+	0x004001ac,
+	0x004001cc,
+	0x004001ec,
+	0x00400190,
+	0x004001b0,
+	0x004001d0,
+	0x004001f0,
+	0x00400194,
+	0x004001b4,
+	0x004001d4,
+	0x004001f4,
+	0x00400198,
+	0x004001b8,
+	0x004001d8,
+	0x004001f8,
+	0x0040019c,
+	0x004001bc,
+	0x004001dc,
+	0x004001fc,
+	0x00400174,
+	NV04_PGRAPH_DMA_START_0,
+	NV04_PGRAPH_DMA_START_1,
+	NV04_PGRAPH_DMA_LENGTH,
+	NV04_PGRAPH_DMA_MISC,
+	NV04_PGRAPH_DMA_PITCH,
+	NV04_PGRAPH_BOFFSET0,
+	NV04_PGRAPH_BBASE0,
+	NV04_PGRAPH_BLIMIT0,
+	NV04_PGRAPH_BOFFSET1,
+	NV04_PGRAPH_BBASE1,
+	NV04_PGRAPH_BLIMIT1,
+	NV04_PGRAPH_BOFFSET2,
+	NV04_PGRAPH_BBASE2,
+	NV04_PGRAPH_BLIMIT2,
+	NV04_PGRAPH_BOFFSET3,
+	NV04_PGRAPH_BBASE3,
+	NV04_PGRAPH_BLIMIT3,
+	NV04_PGRAPH_BOFFSET4,
+	NV04_PGRAPH_BBASE4,
+	NV04_PGRAPH_BLIMIT4,
+	NV04_PGRAPH_BOFFSET5,
+	NV04_PGRAPH_BBASE5,
+	NV04_PGRAPH_BLIMIT5,
+	NV04_PGRAPH_BPITCH0,
+	NV04_PGRAPH_BPITCH1,
+	NV04_PGRAPH_BPITCH2,
+	NV04_PGRAPH_BPITCH3,
+	NV04_PGRAPH_BPITCH4,
+	NV04_PGRAPH_SURFACE,
+	NV04_PGRAPH_STATE,
+	NV04_PGRAPH_BSWIZZLE2,
+	NV04_PGRAPH_BSWIZZLE5,
+	NV04_PGRAPH_BPIXEL,
+	NV04_PGRAPH_NOTIFY,
+	NV04_PGRAPH_PATT_COLOR0,
+	NV04_PGRAPH_PATT_COLOR1,
+	NV04_PGRAPH_PATT_COLORRAM+0x00,
+	NV04_PGRAPH_PATT_COLORRAM+0x04,
+	NV04_PGRAPH_PATT_COLORRAM+0x08,
+	NV04_PGRAPH_PATT_COLORRAM+0x0c,
+	NV04_PGRAPH_PATT_COLORRAM+0x10,
+	NV04_PGRAPH_PATT_COLORRAM+0x14,
+	NV04_PGRAPH_PATT_COLORRAM+0x18,
+	NV04_PGRAPH_PATT_COLORRAM+0x1c,
+	NV04_PGRAPH_PATT_COLORRAM+0x20,
+	NV04_PGRAPH_PATT_COLORRAM+0x24,
+	NV04_PGRAPH_PATT_COLORRAM+0x28,
+	NV04_PGRAPH_PATT_COLORRAM+0x2c,
+	NV04_PGRAPH_PATT_COLORRAM+0x30,
+	NV04_PGRAPH_PATT_COLORRAM+0x34,
+	NV04_PGRAPH_PATT_COLORRAM+0x38,
+	NV04_PGRAPH_PATT_COLORRAM+0x3c,
+	NV04_PGRAPH_PATT_COLORRAM+0x40,
+	NV04_PGRAPH_PATT_COLORRAM+0x44,
+	NV04_PGRAPH_PATT_COLORRAM+0x48,
+	NV04_PGRAPH_PATT_COLORRAM+0x4c,
+	NV04_PGRAPH_PATT_COLORRAM+0x50,
+	NV04_PGRAPH_PATT_COLORRAM+0x54,
+	NV04_PGRAPH_PATT_COLORRAM+0x58,
+	NV04_PGRAPH_PATT_COLORRAM+0x5c,
+	NV04_PGRAPH_PATT_COLORRAM+0x60,
+	NV04_PGRAPH_PATT_COLORRAM+0x64,
+	NV04_PGRAPH_PATT_COLORRAM+0x68,
+	NV04_PGRAPH_PATT_COLORRAM+0x6c,
+	NV04_PGRAPH_PATT_COLORRAM+0x70,
+	NV04_PGRAPH_PATT_COLORRAM+0x74,
+	NV04_PGRAPH_PATT_COLORRAM+0x78,
+	NV04_PGRAPH_PATT_COLORRAM+0x7c,
+	NV04_PGRAPH_PATT_COLORRAM+0x80,
+	NV04_PGRAPH_PATT_COLORRAM+0x84,
+	NV04_PGRAPH_PATT_COLORRAM+0x88,
+	NV04_PGRAPH_PATT_COLORRAM+0x8c,
+	NV04_PGRAPH_PATT_COLORRAM+0x90,
+	NV04_PGRAPH_PATT_COLORRAM+0x94,
+	NV04_PGRAPH_PATT_COLORRAM+0x98,
+	NV04_PGRAPH_PATT_COLORRAM+0x9c,
+	NV04_PGRAPH_PATT_COLORRAM+0xa0,
+	NV04_PGRAPH_PATT_COLORRAM+0xa4,
+	NV04_PGRAPH_PATT_COLORRAM+0xa8,
+	NV04_PGRAPH_PATT_COLORRAM+0xac,
+	NV04_PGRAPH_PATT_COLORRAM+0xb0,
+	NV04_PGRAPH_PATT_COLORRAM+0xb4,
+	NV04_PGRAPH_PATT_COLORRAM+0xb8,
+	NV04_PGRAPH_PATT_COLORRAM+0xbc,
+	NV04_PGRAPH_PATT_COLORRAM+0xc0,
+	NV04_PGRAPH_PATT_COLORRAM+0xc4,
+	NV04_PGRAPH_PATT_COLORRAM+0xc8,
+	NV04_PGRAPH_PATT_COLORRAM+0xcc,
+	NV04_PGRAPH_PATT_COLORRAM+0xd0,
+	NV04_PGRAPH_PATT_COLORRAM+0xd4,
+	NV04_PGRAPH_PATT_COLORRAM+0xd8,
+	NV04_PGRAPH_PATT_COLORRAM+0xdc,
+	NV04_PGRAPH_PATT_COLORRAM+0xe0,
+	NV04_PGRAPH_PATT_COLORRAM+0xe4,
+	NV04_PGRAPH_PATT_COLORRAM+0xe8,
+	NV04_PGRAPH_PATT_COLORRAM+0xec,
+	NV04_PGRAPH_PATT_COLORRAM+0xf0,
+	NV04_PGRAPH_PATT_COLORRAM+0xf4,
+	NV04_PGRAPH_PATT_COLORRAM+0xf8,
+	NV04_PGRAPH_PATT_COLORRAM+0xfc,
+	NV04_PGRAPH_PATTERN,
+	0x0040080c,
+	NV04_PGRAPH_PATTERN_SHAPE,
+	0x00400600,
+	NV04_PGRAPH_ROP3,
+	NV04_PGRAPH_CHROMA,
+	NV04_PGRAPH_BETA_AND,
+	NV04_PGRAPH_BETA_PREMULT,
+	NV04_PGRAPH_CONTROL0,
+	NV04_PGRAPH_CONTROL1,
+	NV04_PGRAPH_CONTROL2,
+	NV04_PGRAPH_BLEND,
+	NV04_PGRAPH_STORED_FMT,
+	NV04_PGRAPH_SOURCE_COLOR,
+	0x00400560,
+	0x00400568,
+	0x00400564,
+	0x0040056c,
+	0x00400400,
+	0x00400480,
+	0x00400404,
+	0x00400484,
+	0x00400408,
+	0x00400488,
+	0x0040040c,
+	0x0040048c,
+	0x00400410,
+	0x00400490,
+	0x00400414,
+	0x00400494,
+	0x00400418,
+	0x00400498,
+	0x0040041c,
+	0x0040049c,
+	0x00400420,
+	0x004004a0,
+	0x00400424,
+	0x004004a4,
+	0x00400428,
+	0x004004a8,
+	0x0040042c,
+	0x004004ac,
+	0x00400430,
+	0x004004b0,
+	0x00400434,
+	0x004004b4,
+	0x00400438,
+	0x004004b8,
+	0x0040043c,
+	0x004004bc,
+	0x00400440,
+	0x004004c0,
+	0x00400444,
+	0x004004c4,
+	0x00400448,
+	0x004004c8,
+	0x0040044c,
+	0x004004cc,
+	0x00400450,
+	0x004004d0,
+	0x00400454,
+	0x004004d4,
+	0x00400458,
+	0x004004d8,
+	0x0040045c,
+	0x004004dc,
+	0x00400460,
+	0x004004e0,
+	0x00400464,
+	0x004004e4,
+	0x00400468,
+	0x004004e8,
+	0x0040046c,
+	0x004004ec,
+	0x00400470,
+	0x004004f0,
+	0x00400474,
+	0x004004f4,
+	0x00400478,
+	0x004004f8,
+	0x0040047c,
+	0x004004fc,
+	0x00400534,
+	0x00400538,
+	0x00400514,
+	0x00400518,
+	0x0040051c,
+	0x00400520,
+	0x00400524,
+	0x00400528,
+	0x0040052c,
+	0x00400530,
+	0x00400d00,
+	0x00400d40,
+	0x00400d80,
+	0x00400d04,
+	0x00400d44,
+	0x00400d84,
+	0x00400d08,
+	0x00400d48,
+	0x00400d88,
+	0x00400d0c,
+	0x00400d4c,
+	0x00400d8c,
+	0x00400d10,
+	0x00400d50,
+	0x00400d90,
+	0x00400d14,
+	0x00400d54,
+	0x00400d94,
+	0x00400d18,
+	0x00400d58,
+	0x00400d98,
+	0x00400d1c,
+	0x00400d5c,
+	0x00400d9c,
+	0x00400d20,
+	0x00400d60,
+	0x00400da0,
+	0x00400d24,
+	0x00400d64,
+	0x00400da4,
+	0x00400d28,
+	0x00400d68,
+	0x00400da8,
+	0x00400d2c,
+	0x00400d6c,
+	0x00400dac,
+	0x00400d30,
+	0x00400d70,
+	0x00400db0,
+	0x00400d34,
+	0x00400d74,
+	0x00400db4,
+	0x00400d38,
+	0x00400d78,
+	0x00400db8,
+	0x00400d3c,
+	0x00400d7c,
+	0x00400dbc,
+	0x00400590,
+	0x00400594,
+	0x00400598,
+	0x0040059c,
+	0x004005a8,
+	0x004005ac,
+	0x004005b0,
+	0x004005b4,
+	0x004005c0,
+	0x004005c4,
+	0x004005c8,
+	0x004005cc,
+	0x004005d0,
+	0x004005d4,
+	0x004005d8,
+	0x004005dc,
+	0x004005e0,
+	NV04_PGRAPH_PASSTHRU_0,
+	NV04_PGRAPH_PASSTHRU_1,
+	NV04_PGRAPH_PASSTHRU_2,
+	NV04_PGRAPH_DVD_COLORFMT,
+	NV04_PGRAPH_SCALED_FORMAT,
+	NV04_PGRAPH_MISC24_0,
+	NV04_PGRAPH_MISC24_1,
+	NV04_PGRAPH_MISC24_2,
+	0x00400500,
+	0x00400504,
+	NV04_PGRAPH_VALID1,
+	NV04_PGRAPH_VALID2,
+	NV04_PGRAPH_DEBUG_3
+};
+
+struct graph_state {
+	int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
+};
+
+struct nouveau_channel *
+nv04_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chid = dev_priv->engine.fifo.channels;
+
+	if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
+		chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
+
+	if (chid >= dev_priv->engine.fifo.channels)
+		return NULL;
+
+	return dev_priv->fifos[chid];
+}
+
+void
+nv04_graph_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	int chid;
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+
+	/* If previous context is valid, we need to save it */
+	pgraph->unload_context(dev);
+
+	/* Load context for next channel */
+	chid = dev_priv->engine.fifo.channel_id(dev);
+	chan = dev_priv->fifos[chid];
+	if (chan)
+		nv04_graph_load_context(chan);
+
+	pgraph->fifo_access(dev, true);
+}
+
+static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
+		if (nv04_graph_ctx_regs[i] == reg)
+			return &ctx->nv04[i];
+	}
+
+	return NULL;
+}
+
+int nv04_graph_create_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx;
+	NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
+
+	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
+						GFP_KERNEL);
+	if (pgraph_ctx == NULL)
+		return -ENOMEM;
+
+	*ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
+
+	return 0;
+}
+
+void nv04_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+
+	kfree(pgraph_ctx);
+	chan->pgraph_ctx = NULL;
+}
+
+int nv04_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	uint32_t tmp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+		nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
+
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+
+	tmp  = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24);
+
+	tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
+	nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
+
+	return 0;
+}
+
+int
+nv04_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	struct graph_state *ctx;
+	uint32_t tmp;
+	int i;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	ctx = chan->pgraph_ctx;
+
+	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+		ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
+
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+int nv04_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	/* Enable PGRAPH interrupts */
+	nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
+	nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
+	/*1231C000 blob, 001 haiku*/
+	//*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
+	/*0x72111100 blob , 01 haiku*/
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
+	/*haiku same*/
+
+	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
+	/*haiku and blob 10d4*/
+
+	nv_wr32(dev, NV04_PGRAPH_STATE        , 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL  , 0x10000100);
+	tmp  = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
+	nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
+
+	/* These don't belong here, they're part of a per-channel context */
+	nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
+
+	return 0;
+}
+
+void nv04_graph_takedown(struct drm_device *dev)
+{
+}
+
+void
+nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
+{
+	if (enabled)
+		nv_wr32(dev, NV04_PGRAPH_FIFO,
+					nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
+	else
+		nv_wr32(dev, NV04_PGRAPH_FIFO,
+					nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
+}
+
+static int
+nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
+			int mthd, uint32_t data)
+{
+	chan->fence.last_sequence_irq = data;
+	nouveau_fence_handler(chan->dev, chan->id);
+	return 0;
+}
+
+static int
+nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
+			      int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
+	int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
+	uint32_t tmp;
+
+	tmp  = nv_ri32(dev, instance);
+	tmp &= ~0x00038000;
+	tmp |= ((data & 7) << 15);
+
+	nv_wi32(dev, instance, tmp);
+	nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
+	nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
+	return 0;
+}
+
+static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = {
+	{ 0x0150, nv04_graph_mthd_set_ref },
+	{}
+};
+
+static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = {
+	{ 0x02fc, nv04_graph_mthd_set_operation },
+	{},
+};
+
+struct nouveau_pgraph_object_class nv04_graph_grclass[] = {
+	{ 0x0039, false, NULL },
+	{ 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */
+	{ 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */
+	{ 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */
+	{ 0x0077, false, nv04_graph_mthds_set_operation }, /* sifm */
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0042, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x0052, false, NULL }, /* swzsurf */
+	{ 0x0053, false, NULL }, /* surf3d */
+	{ 0x0054, false, NULL }, /* tex_tri */
+	{ 0x0055, false, NULL }, /* multitex_tri */
+	{ 0x506e, true, nv04_graph_mthds_sw },
+	{}
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_instmem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_instmem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_instmem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_instmem.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,208 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+/* returns the size of fifo context */
+static int
+nouveau_fifo_ctx_size(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset >= 0x40)
+		return 128;
+	else
+	if (dev_priv->chipset >= 0x17)
+		return 64;
+
+	return 32;
+}
+
+static void
+nv04_instmem_determine_amount(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i;
+
+	/* Figure out how much instance memory we need */
+	if (dev_priv->card_type >= NV_40) {
+		/* We'll want more instance memory than this on some NV4x cards.
+		 * There's a 16MB aperture to play with that maps onto the end
+		 * of vram.  For now, only reserve a small piece until we know
+		 * more about what each chipset requires.
+		 */
+		switch (dev_priv->chipset) {
+		case 0x40:
+		case 0x47:
+		case 0x49:
+		case 0x4b:
+			dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024);
+			break;
+		default:
+			dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024);
+			break;
+		}
+	} else {
+		/*XXX: what *are* the limits on <NV40 cards?
+		 */
+		dev_priv->ramin_rsvd_vram = (512 * 1024);
+	}
+	NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10);
+
+	/* Clear all of it, except the BIOS image that's in the first 64KiB */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4)
+		nv_wi32(dev, i, 0x00000000);
+	dev_priv->engine.instmem.finish_access(dev);
+}
+
+static void
+nv04_instmem_configure_fixed_tables(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
+
+	/* FIFO hash table (RAMHT)
+	 *   use 4k hash table at RAMIN+0x10000
+	 *   TODO: extend the hash table
+	 */
+	dev_priv->ramht_offset = 0x10000;
+	dev_priv->ramht_bits   = 9;
+	dev_priv->ramht_size   = (1 << dev_priv->ramht_bits); /* nr entries */
+	dev_priv->ramht_size  *= 8; /* 2 32-bit values per entry in RAMHT */
+	NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset,
+						      dev_priv->ramht_size);
+
+	/* FIFO runout table (RAMRO) - 512k at 0x11200 */
+	dev_priv->ramro_offset = 0x11200;
+	dev_priv->ramro_size   = 512;
+	NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset,
+						      dev_priv->ramro_size);
+
+	/* FIFO context table (RAMFC)
+	 *   NV40  : Not sure exactly how to position RAMFC on some cards,
+	 *           0x30002 seems to position it at RAMIN+0x20000 on these
+	 *           cards.  RAMFC is 4kb (32 fifos, 128byte entries).
+	 *   Others: Position RAMFC at RAMIN+0x11400
+	 */
+	dev_priv->ramfc_size = engine->fifo.channels *
+						nouveau_fifo_ctx_size(dev);
+	switch (dev_priv->card_type) {
+	case NV_40:
+		dev_priv->ramfc_offset = 0x20000;
+		break;
+	case NV_30:
+	case NV_20:
+	case NV_10:
+	case NV_04:
+	default:
+		dev_priv->ramfc_offset = 0x11400;
+		break;
+	}
+	NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
+						      dev_priv->ramfc_size);
+}
+
+int nv04_instmem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t offset;
+	int ret = 0;
+
+	nv04_instmem_determine_amount(dev);
+	nv04_instmem_configure_fixed_tables(dev);
+
+	/* Create a heap to manage RAMIN allocations, we don't allocate
+	 * the space that was reserved for RAMHT/FC/RO.
+	 */
+	offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+
+	/* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
+	 * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
+	 * ("new style" control) the upper 16-bits of 0x2220 points at this
+	 * other mysterious table that's clobbering important things.
+	 *
+	 * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
+	 * smashed to pieces on us, so reserve 0x30000-0x40000 too..
+	 */
+	if (dev_priv->card_type >= NV_40) {
+		if (offset < 0x40000)
+			offset = 0x40000;
+	}
+
+	ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
+				    offset, dev_priv->ramin_rsvd_vram - offset);
+	if (ret) {
+		dev_priv->ramin_heap = NULL;
+		NV_ERROR(dev, "Failed to init RAMIN heap\n");
+	}
+
+	return ret;
+}
+
+void
+nv04_instmem_takedown(struct drm_device *dev)
+{
+}
+
+int
+nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz)
+{
+	if (gpuobj->im_backing)
+		return -EINVAL;
+
+	return 0;
+}
+
+void
+nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (gpuobj && gpuobj->im_backing) {
+		if (gpuobj->im_bound)
+			dev_priv->engine.instmem.unbind(dev, gpuobj);
+		gpuobj->im_backing = NULL;
+	}
+}
+
+int
+nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	if (!gpuobj->im_pramin || gpuobj->im_bound)
+		return -EINVAL;
+
+	gpuobj->im_bound = 1;
+	return 0;
+}
+
+int
+nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	if (gpuobj->im_bound == 0)
+		return -EINVAL;
+
+	gpuobj->im_bound = 0;
+	return 0;
+}
+
+void
+nv04_instmem_prepare_access(struct drm_device *dev, bool write)
+{
+}
+
+void
+nv04_instmem_finish_access(struct drm_device *dev)
+{
+}
+
+int
+nv04_instmem_suspend(struct drm_device *dev)
+{
+	return 0;
+}
+
+void
+nv04_instmem_resume(struct drm_device *dev)
+{
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_mc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_mc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_mc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_mc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_mc_init(struct drm_device *dev)
+{
+	/* Power up everything, resetting each individual unit will
+	 * be done later if needed.
+	 */
+
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+	return 0;
+}
+
+void
+nv04_mc_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_timer.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_timer.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,51 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_timer_init(struct drm_device *dev)
+{
+	nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000);
+	nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF);
+
+	/* Just use the pre-existing values when possible for now; these regs
+	 * are not written in nv (driver writer missed a /4 on the address), and
+	 * writing 8 and 3 to the correct regs breaks the timings on the LVDS
+	 * hardware sequencing microcode.
+	 * A correct solution (involving calculations with the GPU PLL) can
+	 * be done when kernel modesetting lands
+	 */
+	if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) ||
+				!nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) {
+		nv_wr32(dev, NV04_PTIMER_NUMERATOR, 0x00000008);
+		nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 0x00000003);
+	}
+
+	return 0;
+}
+
+uint64_t
+nv04_timer_read(struct drm_device *dev)
+{
+	uint32_t low;
+	/* From kmmio dumps on nv28 this looks like how the blob does this.
+	 * It reads the high dword twice, before and after.
+	 * The only explanation seems to be that the 64-bit timer counter
+	 * advances between high and low dword reads and may corrupt the
+	 * result. Not confirmed.
+	 */
+	uint32_t high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
+	uint32_t high1;
+	do {
+		high1 = high2;
+		low = nv_rd32(dev, NV04_PTIMER_TIME_0);
+		high2 = nv_rd32(dev, NV04_PTIMER_TIME_1);
+	} while (high1 != high2);
+	return (((uint64_t)high2) << 32) | (uint64_t)low;
+}
+
+void
+nv04_timer_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv04_tv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "drm_crtc_helper.h"
+
+#include "i2c/ch7006.h"
+
+static struct {
+	struct i2c_board_info board_info;
+	struct drm_encoder_funcs funcs;
+	struct drm_encoder_helper_funcs hfuncs;
+	void *params;
+
+} nv04_tv_encoder_info[] = {
+	{
+		.board_info = { I2C_BOARD_INFO("ch7006", 0x75) },
+		.params = &(struct ch7006_encoder_params) {
+			CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
+			0, 0, 0,
+			CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
+			CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
+		},
+	},
+};
+
+static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
+{
+	struct i2c_msg msg = {
+		.addr = addr,
+		.len = 0,
+	};
+
+	return i2c_transfer(adapter, &msg, 1) == 1;
+}
+
+int nv04_tv_identify(struct drm_device *dev, int i2c_index)
+{
+	struct nouveau_i2c_chan *i2c;
+	bool was_locked;
+	int i, ret;
+
+	NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);
+
+	i2c = nouveau_i2c_find(dev, i2c_index);
+	if (!i2c)
+		return -ENODEV;
+
+	was_locked = NVLockVgaCrtcs(dev, false);
+
+	for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
+		if (probe_i2c_addr(&i2c->adapter,
+				   nv04_tv_encoder_info[i].board_info.addr)) {
+			ret = i;
+			break;
+		}
+	}
+
+	if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
+		NV_TRACE(dev, "Detected TV encoder: %s\n",
+			 nv04_tv_encoder_info[i].board_info.type);
+
+	} else {
+		NV_TRACE(dev, "No TV encoders found.\n");
+		i = -ENODEV;
+	}
+
+	NVLockVgaCrtcs(dev, was_locked);
+	return i;
+}
+
+#define PLLSEL_TV_CRTC1_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
+#define PLLSEL_TV_CRTC2_MASK				\
+	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2		\
+	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2)
+
+static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_mode_state *state = &dev_priv->mode_reg;
+	uint8_t crtc1A;
+
+	NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+		mode, nv_encoder->dcb->index);
+
+	state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		int head = nouveau_crtc(encoder->crtc)->index;
+		crtc1A = NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX);
+
+		state->pllsel |= head ? PLLSEL_TV_CRTC2_MASK :
+					PLLSEL_TV_CRTC1_MASK;
+
+		/* Inhibit hsync */
+		crtc1A |= 0x80;
+
+		NVWriteVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX, crtc1A);
+	}
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
+
+	to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode);
+}
+
+static void nv04_tv_bind(struct drm_device *dev, int head, bool bind)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv04_crtc_reg *state = &dev_priv->mode_reg.crtc_reg[head];
+
+	state->tv_setup = 0;
+
+	if (bind) {
+		state->CRTC[NV_CIO_CRE_LCD__INDEX] = 0;
+		state->CRTC[NV_CIO_CRE_49] |= 0x10;
+	} else {
+		state->CRTC[NV_CIO_CRE_49] &= ~0x10;
+	}
+
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_LCD__INDEX,
+		       state->CRTC[NV_CIO_CRE_LCD__INDEX]);
+	NVWriteVgaCrtc(dev, head, NV_CIO_CRE_49,
+		       state->CRTC[NV_CIO_CRE_49]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP,
+		      state->tv_setup);
+}
+
+static void nv04_tv_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	if (nv_two_heads(dev))
+		nv04_tv_bind(dev, head ^ 1, false);
+
+	nv04_tv_bind(dev, head, true);
+}
+
+static void nv04_tv_mode_set(struct drm_encoder *encoder,
+			     struct drm_display_mode *mode,
+			     struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+
+	regp->tv_htotal = adjusted_mode->htotal;
+	regp->tv_vtotal = adjusted_mode->vtotal;
+
+	/* These delay the TV signals with respect to the VGA port,
+	 * they might be useful if we ever allow a CRTC to drive
+	 * multiple outputs.
+	 */
+	regp->tv_hskew = 1;
+	regp->tv_hsync_delay = 1;
+	regp->tv_hsync_delay2 = 64;
+	regp->tv_vskew = 1;
+	regp->tv_vsync_delay = 1;
+
+	to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode);
+}
+
+static void nv04_tv_commit(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		      drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index,
+		      '@' + ffs(nv_encoder->dcb->or));
+}
+
+static void nv04_tv_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	to_encoder_slave(encoder)->slave_funcs->destroy(encoder);
+
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+}
+
+int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder;
+	struct drm_encoder *encoder;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct i2c_adapter *adap;
+	struct drm_encoder_funcs *funcs = NULL;
+	struct drm_encoder_helper_funcs *hfuncs = NULL;
+	struct drm_encoder_slave_funcs *sfuncs = NULL;
+	int i2c_index = entry->i2c_index;
+	int type, ret;
+	bool was_locked;
+
+	/* Ensure that we can talk to this encoder */
+	type = nv04_tv_identify(dev, i2c_index);
+	if (type < 0)
+		return type;
+
+	/* Allocate the necessary memory */
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+
+	/* Initialize the common members */
+	encoder = to_drm_encoder(nv_encoder);
+
+	funcs = &nv04_tv_encoder_info[type].funcs;
+	hfuncs = &nv04_tv_encoder_info[type].hfuncs;
+
+	drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
+	drm_encoder_helper_add(encoder, hfuncs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	/* Run the slave-specific initialization */
+	adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter;
+
+	was_locked = NVLockVgaCrtcs(dev, false);
+
+	ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
+				   &nv04_tv_encoder_info[type].board_info);
+
+	NVLockVgaCrtcs(dev, was_locked);
+
+	if (ret < 0)
+		goto fail;
+
+	/* Fill the function pointers */
+	sfuncs = to_encoder_slave(encoder)->slave_funcs;
+
+	*funcs = (struct drm_encoder_funcs) {
+		.destroy = nv04_tv_destroy,
+	};
+
+	*hfuncs = (struct drm_encoder_helper_funcs) {
+		.dpms = nv04_tv_dpms,
+		.save = sfuncs->save,
+		.restore = sfuncs->restore,
+		.mode_fixup = sfuncs->mode_fixup,
+		.prepare = nv04_tv_prepare,
+		.commit = nv04_tv_commit,
+		.mode_set = nv04_tv_mode_set,
+		.detect = sfuncs->detect,
+	};
+
+	/* Set the slave encoder configuration */
+	sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
+
+	return 0;
+
+fail:
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,44 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+void
+nv10_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			  uint32_t size, uint32_t pitch)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t limit = max(1u, addr + size) - 1;
+
+	if (pitch) {
+		if (dev_priv->card_type >= NV_20)
+			addr |= 1;
+		else
+			addr |= 1 << 31;
+	}
+
+	nv_wr32(dev, NV10_PFB_TLIMIT(i), limit);
+	nv_wr32(dev, NV10_PFB_TSIZE(i), pitch);
+	nv_wr32(dev, NV10_PFB_TILE(i), addr);
+}
+
+int
+nv10_fb_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+	int i;
+
+	pfb->num_tiles = NV10_PFB_TILE__SIZE;
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < pfb->num_tiles; i++)
+		pfb->set_region_tiling(dev, i, 0, 0, 0);
+
+	return 0;
+}
+
+void
+nv10_fb_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_fifo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_fifo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_fifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_fifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE))
+#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32)
+
+int
+nv10_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV10_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv10_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_device *dev = chan->dev;
+	uint32_t fc = NV10_RAMFC(chan->id);
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0,
+				      NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	/* Fill entries that are seen filled in dumps of nvidia driver just
+	 * after channel's is put into DMA mode
+	 */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc +  0, chan->pushbuf_base);
+	nv_wi32(dev, fc +  4, chan->pushbuf_base);
+	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
+	nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			      NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			      0);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv10_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+			nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv10_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV10_RAMFC(chid), tmp;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
+
+	tmp = nv_ri32(dev, fc + 12);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 20));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 24));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 28));
+
+	if (dev_priv->chipset < 0x17)
+		goto out;
+
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 32));
+	tmp = nv_ri32(dev, fc + 36);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 40));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 44));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48));
+
+out:
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv10_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t tmp;
+
+	nv10_fifo_do_load_context(dev, chan->id);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv10_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	uint32_t fc, tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+	fc = NV10_RAMFC(chid);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wi32(dev, fc +  0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	nv_wi32(dev, fc +  4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc +  8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF;
+	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16);
+	nv_wi32(dev, fc + 12, tmp);
+	nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
+	nv_wi32(dev, fc + 24, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+
+	if (dev_priv->chipset < 0x17)
+		goto out;
+
+	nv_wi32(dev, fc + 32, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE));
+	tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP);
+	nv_wi32(dev, fc + 36, tmp);
+	nv_wi32(dev, fc + 40, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT));
+	nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE));
+	nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+
+out:
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv10_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+	return 0;
+}
+
+static void
+nv10_fifo_init_reset(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x002044, 0x0101ffff);
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003000, 0x00000000);
+	nv_wr32(dev, 0x003050, 0x00000000);
+
+	nv_wr32(dev, 0x003258, 0x00000000);
+	nv_wr32(dev, 0x003210, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+}
+
+static void
+nv10_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+
+	if (dev_priv->chipset < 0x17) {
+		nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8);
+	} else {
+		nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) |
+					       (1 << 16) /* 64 Bytes entry*/);
+		/* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */
+	}
+}
+
+static void
+nv10_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv10_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv10_fifo_init_reset(dev);
+	nv10_fifo_init_ramxx(dev);
+
+	nv10_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv10_fifo_init_intr(dev);
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_graph.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_graph.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv10_graph.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv10_graph.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1009 @@
+/*
+ * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
+ * 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, 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+#include "nouveau_drv.h"
+
+#define NV10_FIFO_NUMBER 32
+
+struct pipe_state {
+	uint32_t pipe_0x0000[0x040/4];
+	uint32_t pipe_0x0040[0x010/4];
+	uint32_t pipe_0x0200[0x0c0/4];
+	uint32_t pipe_0x4400[0x080/4];
+	uint32_t pipe_0x6400[0x3b0/4];
+	uint32_t pipe_0x6800[0x2f0/4];
+	uint32_t pipe_0x6c00[0x030/4];
+	uint32_t pipe_0x7000[0x130/4];
+	uint32_t pipe_0x7400[0x0c0/4];
+	uint32_t pipe_0x7800[0x0c0/4];
+};
+
+static int nv10_graph_ctx_regs[] = {
+	NV10_PGRAPH_CTX_SWITCH1,
+	NV10_PGRAPH_CTX_SWITCH2,
+	NV10_PGRAPH_CTX_SWITCH3,
+	NV10_PGRAPH_CTX_SWITCH4,
+	NV10_PGRAPH_CTX_SWITCH5,
+	NV10_PGRAPH_CTX_CACHE1,	/* 8 values from 0x400160 to 0x40017c */
+	NV10_PGRAPH_CTX_CACHE2,	/* 8 values from 0x400180 to 0x40019c */
+	NV10_PGRAPH_CTX_CACHE3,	/* 8 values from 0x4001a0 to 0x4001bc */
+	NV10_PGRAPH_CTX_CACHE4,	/* 8 values from 0x4001c0 to 0x4001dc */
+	NV10_PGRAPH_CTX_CACHE5,	/* 8 values from 0x4001e0 to 0x4001fc */
+	0x00400164,
+	0x00400184,
+	0x004001a4,
+	0x004001c4,
+	0x004001e4,
+	0x00400168,
+	0x00400188,
+	0x004001a8,
+	0x004001c8,
+	0x004001e8,
+	0x0040016c,
+	0x0040018c,
+	0x004001ac,
+	0x004001cc,
+	0x004001ec,
+	0x00400170,
+	0x00400190,
+	0x004001b0,
+	0x004001d0,
+	0x004001f0,
+	0x00400174,
+	0x00400194,
+	0x004001b4,
+	0x004001d4,
+	0x004001f4,
+	0x00400178,
+	0x00400198,
+	0x004001b8,
+	0x004001d8,
+	0x004001f8,
+	0x0040017c,
+	0x0040019c,
+	0x004001bc,
+	0x004001dc,
+	0x004001fc,
+	NV10_PGRAPH_CTX_USER,
+	NV04_PGRAPH_DMA_START_0,
+	NV04_PGRAPH_DMA_START_1,
+	NV04_PGRAPH_DMA_LENGTH,
+	NV04_PGRAPH_DMA_MISC,
+	NV10_PGRAPH_DMA_PITCH,
+	NV04_PGRAPH_BOFFSET0,
+	NV04_PGRAPH_BBASE0,
+	NV04_PGRAPH_BLIMIT0,
+	NV04_PGRAPH_BOFFSET1,
+	NV04_PGRAPH_BBASE1,
+	NV04_PGRAPH_BLIMIT1,
+	NV04_PGRAPH_BOFFSET2,
+	NV04_PGRAPH_BBASE2,
+	NV04_PGRAPH_BLIMIT2,
+	NV04_PGRAPH_BOFFSET3,
+	NV04_PGRAPH_BBASE3,
+	NV04_PGRAPH_BLIMIT3,
+	NV04_PGRAPH_BOFFSET4,
+	NV04_PGRAPH_BBASE4,
+	NV04_PGRAPH_BLIMIT4,
+	NV04_PGRAPH_BOFFSET5,
+	NV04_PGRAPH_BBASE5,
+	NV04_PGRAPH_BLIMIT5,
+	NV04_PGRAPH_BPITCH0,
+	NV04_PGRAPH_BPITCH1,
+	NV04_PGRAPH_BPITCH2,
+	NV04_PGRAPH_BPITCH3,
+	NV04_PGRAPH_BPITCH4,
+	NV10_PGRAPH_SURFACE,
+	NV10_PGRAPH_STATE,
+	NV04_PGRAPH_BSWIZZLE2,
+	NV04_PGRAPH_BSWIZZLE5,
+	NV04_PGRAPH_BPIXEL,
+	NV10_PGRAPH_NOTIFY,
+	NV04_PGRAPH_PATT_COLOR0,
+	NV04_PGRAPH_PATT_COLOR1,
+	NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
+	0x00400904,
+	0x00400908,
+	0x0040090c,
+	0x00400910,
+	0x00400914,
+	0x00400918,
+	0x0040091c,
+	0x00400920,
+	0x00400924,
+	0x00400928,
+	0x0040092c,
+	0x00400930,
+	0x00400934,
+	0x00400938,
+	0x0040093c,
+	0x00400940,
+	0x00400944,
+	0x00400948,
+	0x0040094c,
+	0x00400950,
+	0x00400954,
+	0x00400958,
+	0x0040095c,
+	0x00400960,
+	0x00400964,
+	0x00400968,
+	0x0040096c,
+	0x00400970,
+	0x00400974,
+	0x00400978,
+	0x0040097c,
+	0x00400980,
+	0x00400984,
+	0x00400988,
+	0x0040098c,
+	0x00400990,
+	0x00400994,
+	0x00400998,
+	0x0040099c,
+	0x004009a0,
+	0x004009a4,
+	0x004009a8,
+	0x004009ac,
+	0x004009b0,
+	0x004009b4,
+	0x004009b8,
+	0x004009bc,
+	0x004009c0,
+	0x004009c4,
+	0x004009c8,
+	0x004009cc,
+	0x004009d0,
+	0x004009d4,
+	0x004009d8,
+	0x004009dc,
+	0x004009e0,
+	0x004009e4,
+	0x004009e8,
+	0x004009ec,
+	0x004009f0,
+	0x004009f4,
+	0x004009f8,
+	0x004009fc,
+	NV04_PGRAPH_PATTERN,	/* 2 values from 0x400808 to 0x40080c */
+	0x0040080c,
+	NV04_PGRAPH_PATTERN_SHAPE,
+	NV03_PGRAPH_MONO_COLOR0,
+	NV04_PGRAPH_ROP3,
+	NV04_PGRAPH_CHROMA,
+	NV04_PGRAPH_BETA_AND,
+	NV04_PGRAPH_BETA_PREMULT,
+	0x00400e70,
+	0x00400e74,
+	0x00400e78,
+	0x00400e7c,
+	0x00400e80,
+	0x00400e84,
+	0x00400e88,
+	0x00400e8c,
+	0x00400ea0,
+	0x00400ea4,
+	0x00400ea8,
+	0x00400e90,
+	0x00400e94,
+	0x00400e98,
+	0x00400e9c,
+	NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
+	NV10_PGRAPH_WINDOWCLIP_VERTICAL,   /* 8 values from 0x400f20-0x400f3c */
+	0x00400f04,
+	0x00400f24,
+	0x00400f08,
+	0x00400f28,
+	0x00400f0c,
+	0x00400f2c,
+	0x00400f10,
+	0x00400f30,
+	0x00400f14,
+	0x00400f34,
+	0x00400f18,
+	0x00400f38,
+	0x00400f1c,
+	0x00400f3c,
+	NV10_PGRAPH_XFMODE0,
+	NV10_PGRAPH_XFMODE1,
+	NV10_PGRAPH_GLOBALSTATE0,
+	NV10_PGRAPH_GLOBALSTATE1,
+	NV04_PGRAPH_STORED_FMT,
+	NV04_PGRAPH_SOURCE_COLOR,
+	NV03_PGRAPH_ABS_X_RAM,	/* 32 values from 0x400400 to 0x40047c */
+	NV03_PGRAPH_ABS_Y_RAM,	/* 32 values from 0x400480 to 0x4004fc */
+	0x00400404,
+	0x00400484,
+	0x00400408,
+	0x00400488,
+	0x0040040c,
+	0x0040048c,
+	0x00400410,
+	0x00400490,
+	0x00400414,
+	0x00400494,
+	0x00400418,
+	0x00400498,
+	0x0040041c,
+	0x0040049c,
+	0x00400420,
+	0x004004a0,
+	0x00400424,
+	0x004004a4,
+	0x00400428,
+	0x004004a8,
+	0x0040042c,
+	0x004004ac,
+	0x00400430,
+	0x004004b0,
+	0x00400434,
+	0x004004b4,
+	0x00400438,
+	0x004004b8,
+	0x0040043c,
+	0x004004bc,
+	0x00400440,
+	0x004004c0,
+	0x00400444,
+	0x004004c4,
+	0x00400448,
+	0x004004c8,
+	0x0040044c,
+	0x004004cc,
+	0x00400450,
+	0x004004d0,
+	0x00400454,
+	0x004004d4,
+	0x00400458,
+	0x004004d8,
+	0x0040045c,
+	0x004004dc,
+	0x00400460,
+	0x004004e0,
+	0x00400464,
+	0x004004e4,
+	0x00400468,
+	0x004004e8,
+	0x0040046c,
+	0x004004ec,
+	0x00400470,
+	0x004004f0,
+	0x00400474,
+	0x004004f4,
+	0x00400478,
+	0x004004f8,
+	0x0040047c,
+	0x004004fc,
+	NV03_PGRAPH_ABS_UCLIP_XMIN,
+	NV03_PGRAPH_ABS_UCLIP_XMAX,
+	NV03_PGRAPH_ABS_UCLIP_YMIN,
+	NV03_PGRAPH_ABS_UCLIP_YMAX,
+	0x00400550,
+	0x00400558,
+	0x00400554,
+	0x0040055c,
+	NV03_PGRAPH_ABS_UCLIPA_XMIN,
+	NV03_PGRAPH_ABS_UCLIPA_XMAX,
+	NV03_PGRAPH_ABS_UCLIPA_YMIN,
+	NV03_PGRAPH_ABS_UCLIPA_YMAX,
+	NV03_PGRAPH_ABS_ICLIP_XMAX,
+	NV03_PGRAPH_ABS_ICLIP_YMAX,
+	NV03_PGRAPH_XY_LOGIC_MISC0,
+	NV03_PGRAPH_XY_LOGIC_MISC1,
+	NV03_PGRAPH_XY_LOGIC_MISC2,
+	NV03_PGRAPH_XY_LOGIC_MISC3,
+	NV03_PGRAPH_CLIPX_0,
+	NV03_PGRAPH_CLIPX_1,
+	NV03_PGRAPH_CLIPY_0,
+	NV03_PGRAPH_CLIPY_1,
+	NV10_PGRAPH_COMBINER0_IN_ALPHA,
+	NV10_PGRAPH_COMBINER1_IN_ALPHA,
+	NV10_PGRAPH_COMBINER0_IN_RGB,
+	NV10_PGRAPH_COMBINER1_IN_RGB,
+	NV10_PGRAPH_COMBINER_COLOR0,
+	NV10_PGRAPH_COMBINER_COLOR1,
+	NV10_PGRAPH_COMBINER0_OUT_ALPHA,
+	NV10_PGRAPH_COMBINER1_OUT_ALPHA,
+	NV10_PGRAPH_COMBINER0_OUT_RGB,
+	NV10_PGRAPH_COMBINER1_OUT_RGB,
+	NV10_PGRAPH_COMBINER_FINAL0,
+	NV10_PGRAPH_COMBINER_FINAL1,
+	0x00400e00,
+	0x00400e04,
+	0x00400e08,
+	0x00400e0c,
+	0x00400e10,
+	0x00400e14,
+	0x00400e18,
+	0x00400e1c,
+	0x00400e20,
+	0x00400e24,
+	0x00400e28,
+	0x00400e2c,
+	0x00400e30,
+	0x00400e34,
+	0x00400e38,
+	0x00400e3c,
+	NV04_PGRAPH_PASSTHRU_0,
+	NV04_PGRAPH_PASSTHRU_1,
+	NV04_PGRAPH_PASSTHRU_2,
+	NV10_PGRAPH_DIMX_TEXTURE,
+	NV10_PGRAPH_WDIMX_TEXTURE,
+	NV10_PGRAPH_DVD_COLORFMT,
+	NV10_PGRAPH_SCALED_FORMAT,
+	NV04_PGRAPH_MISC24_0,
+	NV04_PGRAPH_MISC24_1,
+	NV04_PGRAPH_MISC24_2,
+	NV03_PGRAPH_X_MISC,
+	NV03_PGRAPH_Y_MISC,
+	NV04_PGRAPH_VALID1,
+	NV04_PGRAPH_VALID2,
+};
+
+static int nv17_graph_ctx_regs[] = {
+	NV10_PGRAPH_DEBUG_4,
+	0x004006b0,
+	0x00400eac,
+	0x00400eb0,
+	0x00400eb4,
+	0x00400eb8,
+	0x00400ebc,
+	0x00400ec0,
+	0x00400ec4,
+	0x00400ec8,
+	0x00400ecc,
+	0x00400ed0,
+	0x00400ed4,
+	0x00400ed8,
+	0x00400edc,
+	0x00400ee0,
+	0x00400a00,
+	0x00400a04,
+};
+
+struct graph_state {
+	int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
+	int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
+	struct pipe_state pipe_state;
+	uint32_t lma_window[4];
+};
+
+#define PIPE_SAVE(dev, state, addr)					\
+	do {								\
+		int __i;						\
+		nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);		\
+		for (__i = 0; __i < ARRAY_SIZE(state); __i++)		\
+			state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
+	} while (0)
+
+#define PIPE_RESTORE(dev, state, addr)					\
+	do {								\
+		int __i;						\
+		nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr);		\
+		for (__i = 0; __i < ARRAY_SIZE(state); __i++)		\
+			nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \
+	} while (0)
+
+static void nv10_graph_save_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
+
+	PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
+	PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
+	PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400);
+	PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800);
+	PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00);
+	PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000);
+	PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400);
+	PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800);
+	PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040);
+	PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000);
+}
+
+static void nv10_graph_load_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
+	uint32_t xfmode0, xfmode1;
+	int i;
+
+	nouveau_wait_for_idle(dev);
+	/* XXX check haiku comments */
+	xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
+	xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
+
+
+	PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
+	nouveau_wait_for_idle(dev);
+
+	/* restore XFMODE */
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
+	PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
+	PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
+	PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
+	PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
+	PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
+	PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
+	PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
+	PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
+	PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
+	nouveau_wait_for_idle(dev);
+}
+
+static void nv10_graph_create_pipe(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
+	uint32_t *fifo_pipe_state_addr;
+	int i;
+#define PIPE_INIT(addr) \
+	do { \
+		fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
+	} while (0)
+#define PIPE_INIT_END(addr) \
+	do { \
+		uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
+				ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
+		if (fifo_pipe_state_addr != __end_addr) \
+			NV_ERROR(dev, "incomplete pipe init for 0x%x :  %p/%p\n", \
+				addr, fifo_pipe_state_addr, __end_addr); \
+	} while (0)
+#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
+
+	PIPE_INIT(0x0200);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0200);
+
+	PIPE_INIT(0x6400);
+	for (i = 0; i < 211; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x40000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f000000);
+	NV_WRITE_PIPE_INIT(0x3f000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	PIPE_INIT_END(0x6400);
+
+	PIPE_INIT(0x6800);
+	for (i = 0; i < 162; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x3f800000);
+	for (i = 0; i < 25; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x6800);
+
+	PIPE_INIT(0x6c00);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0xbf800000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x6c00);
+
+	PIPE_INIT(0x7000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x00000000);
+	NV_WRITE_PIPE_INIT(0x7149f2ca);
+	for (i = 0; i < 35; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7000);
+
+	PIPE_INIT(0x7400);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7400);
+
+	PIPE_INIT(0x7800);
+	for (i = 0; i < 48; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x7800);
+
+	PIPE_INIT(0x4400);
+	for (i = 0; i < 32; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x4400);
+
+	PIPE_INIT(0x0000);
+	for (i = 0; i < 16; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0000);
+
+	PIPE_INIT(0x0040);
+	for (i = 0; i < 4; i++)
+		NV_WRITE_PIPE_INIT(0x00000000);
+	PIPE_INIT_END(0x0040);
+
+#undef PIPE_INIT
+#undef PIPE_INIT_END
+#undef NV_WRITE_PIPE_INIT
+}
+
+static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
+		if (nv10_graph_ctx_regs[i] == reg)
+			return i;
+	}
+	NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
+	return -1;
+}
+
+static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
+		if (nv17_graph_ctx_regs[i] == reg)
+			return i;
+	}
+	NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
+	return -1;
+}
+
+int nv10_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	uint32_t tmp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+		nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
+	if (dev_priv->chipset >= 0x17) {
+		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+			nv_wr32(dev, nv17_graph_ctx_regs[i],
+						pgraph_ctx->nv17[i]);
+	}
+
+	nv10_graph_load_pipe(chan);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+	tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
+	tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
+	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
+	return 0;
+}
+
+int
+nv10_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	struct graph_state *ctx;
+	uint32_t tmp;
+	int i;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	ctx = chan->pgraph_ctx;
+
+	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+		ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
+
+	if (dev_priv->chipset >= 0x17) {
+		for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+			ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
+	}
+
+	nv10_graph_save_pipe(chan);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (pfifo->channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+void
+nv10_graph_context_switch(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_channel *chan = NULL;
+	int chid;
+
+	pgraph->fifo_access(dev, false);
+	nouveau_wait_for_idle(dev);
+
+	/* If previous context is valid, we need to save it */
+	nv10_graph_unload_context(dev);
+
+	/* Load context for next channel */
+	chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+	chan = dev_priv->fifos[chid];
+	if (chan)
+		nv10_graph_load_context(chan);
+
+	pgraph->fifo_access(dev, true);
+}
+
+#define NV_WRITE_CTX(reg, val) do { \
+	int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
+	if (offset > 0) \
+		pgraph_ctx->nv10[offset] = val; \
+	} while (0)
+
+#define NV17_WRITE_CTX(reg, val) do { \
+	int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
+	if (offset > 0) \
+		pgraph_ctx->nv17[offset] = val; \
+	} while (0)
+
+struct nouveau_channel *
+nv10_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int chid = dev_priv->engine.fifo.channels;
+
+	if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
+		chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
+
+	if (chid >= dev_priv->engine.fifo.channels)
+		return NULL;
+
+	return dev_priv->fifos[chid];
+}
+
+int nv10_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct graph_state *pgraph_ctx;
+
+	NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
+
+	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
+						GFP_KERNEL);
+	if (pgraph_ctx == NULL)
+		return -ENOMEM;
+
+
+	NV_WRITE_CTX(0x00400e88, 0x08000000);
+	NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
+	NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
+	NV_WRITE_CTX(0x00400e10, 0x00001000);
+	NV_WRITE_CTX(0x00400e14, 0x00001000);
+	NV_WRITE_CTX(0x00400e30, 0x00080008);
+	NV_WRITE_CTX(0x00400e34, 0x00080008);
+	if (dev_priv->chipset >= 0x17) {
+		/* is it really needed ??? */
+		NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
+					nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
+		NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
+		NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
+		NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
+		NV17_WRITE_CTX(0x00400ec0, 0x00000080);
+		NV17_WRITE_CTX(0x00400ed0, 0x00000080);
+	}
+	NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
+
+	nv10_graph_create_pipe(chan);
+	return 0;
+}
+
+void nv10_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+
+	kfree(pgraph_ctx);
+	chan->pgraph_ctx = NULL;
+}
+
+void
+nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			     uint32_t size, uint32_t pitch)
+{
+	uint32_t limit = max(1u, addr + size) - 1;
+
+	if (pitch)
+		addr |= 1 << 31;
+
+	nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit);
+	nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch);
+	nv_wr32(dev, NV10_PGRAPH_TILE(i), addr);
+}
+
+int nv10_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+	int i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
+	/* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
+				      (1<<29) |
+				      (1<<31));
+	if (dev_priv->chipset >= 0x17) {
+		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
+		nv_wr32(dev, 0x400a10, 0x3ff3fb6);
+		nv_wr32(dev, 0x400838, 0x2f8684);
+		nv_wr32(dev, 0x40083c, 0x115f3f);
+		nv_wr32(dev, 0x004006b0, 0x40000020);
+	} else
+		nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
+		nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
+
+	return 0;
+}
+
+void nv10_graph_takedown(struct drm_device *dev)
+{
+}
+
+static int
+nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass,
+			   int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	struct graph_state *ctx = chan->pgraph_ctx;
+	struct pipe_state *pipe = &ctx->pipe_state;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
+	uint32_t xfmode0, xfmode1;
+	int i;
+
+	ctx->lma_window[(mthd - 0x1638) / 4] = data;
+
+	if (mthd != 0x1644)
+		return 0;
+
+	nouveau_wait_for_idle(dev);
+
+	PIPE_SAVE(dev, pipe_0x0040, 0x0040);
+	PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
+
+	PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
+
+	nouveau_wait_for_idle(dev);
+
+	xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
+	xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
+
+	PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
+	PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
+	PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
+	PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
+
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+	for (i = 0; i < 4; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
+	for (i = 0; i < 3; i++)
+		nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
+
+	PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
+
+	nouveau_wait_for_idle(dev);
+
+	PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
+
+	nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
+	nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
+
+	PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
+	PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
+	PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
+	PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
+
+	nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
+	nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+	nouveau_wait_for_idle(dev);
+
+	pgraph->fifo_access(dev, true);
+
+	return 0;
+}
+
+static int
+nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass,
+			   int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
+		nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
+	nv_wr32(dev, 0x004006b0,
+		nv_rd32(dev, 0x004006b0) | 0x8 << 24);
+
+	pgraph->fifo_access(dev, true);
+
+	return 0;
+}
+
+static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = {
+	{ 0x1638, nv17_graph_mthd_lma_window },
+	{ 0x163c, nv17_graph_mthd_lma_window },
+	{ 0x1640, nv17_graph_mthd_lma_window },
+	{ 0x1644, nv17_graph_mthd_lma_window },
+	{ 0x1658, nv17_graph_mthd_lma_enable },
+	{}
+};
+
+struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x005f, false, NULL }, /* imageblit */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x0052, false, NULL }, /* swzsurf */
+	{ 0x0093, false, NULL }, /* surf3d */
+	{ 0x0094, false, NULL }, /* tex_tri */
+	{ 0x0095, false, NULL }, /* multitex_tri */
+	{ 0x0056, false, NULL }, /* celcius (nv10) */
+	{ 0x0096, false, NULL }, /* celcius (nv11) */
+	{ 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */
+	{}
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_gpio.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_gpio.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_gpio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static bool
+get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift,
+		  uint32_t *mask)
+{
+	if (ent->line < 2) {
+		*reg = NV_PCRTC_GPIO;
+		*shift = ent->line * 16;
+		*mask = 0x11;
+
+	} else if (ent->line < 10) {
+		*reg = NV_PCRTC_GPIO_EXT;
+		*shift = (ent->line - 2) * 4;
+		*mask = 0x3;
+
+	} else if (ent->line < 14) {
+		*reg = NV_PCRTC_850;
+		*shift = (ent->line - 10) * 4;
+		*mask = 0x3;
+
+	} else {
+		return false;
+	}
+
+	return true;
+}
+
+int
+nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+	struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
+	uint32_t reg, shift, mask, value;
+
+	if (!ent)
+		return -ENODEV;
+
+	if (!get_gpio_location(ent, &reg, &shift, &mask))
+		return -ENODEV;
+
+	value = NVReadCRTC(dev, 0, reg) >> shift;
+
+	return (ent->invert ? 1 : 0) ^ (value & 1);
+}
+
+int
+nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+	struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
+	uint32_t reg, shift, mask, value;
+
+	if (!ent)
+		return -ENODEV;
+
+	if (!get_gpio_location(ent, &reg, &shift, &mask))
+		return -ENODEV;
+
+	value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift;
+	mask = ~(mask << shift);
+
+	NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask));
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,778 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nv17_tv.h"
+
+static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
+	uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
+		fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
+	uint32_t sample = 0;
+	int head;
+
+#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
+	testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
+	if (dev_priv->vbios->tvdactestval)
+		testval = dev_priv->vbios->tvdactestval;
+
+	dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
+	head = (dacclk & 0x100) >> 8;
+
+	/* Save the previous state. */
+	gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1);
+	gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0);
+	fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL);
+	fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START);
+	fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END);
+	fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
+	test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
+	ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c);
+	ctv_14 = NVReadRAMDAC(dev, head, 0x680c14);
+	ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c);
+
+	/* Prepare the DAC for load detection.  */
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
+		      NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
+		      NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 |
+		      NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
+		      NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |
+		      NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS);
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0);
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
+		      (dacclk & ~0xff) | 0x22);
+	msleep(1);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
+		      (dacclk & ~0xff) | 0x21);
+
+	NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20);
+	NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16);
+
+	/* Sample pin 0x4 (usually S-video luma). */
+	NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff);
+	msleep(20);
+	sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
+		& 0x4 << 28;
+
+	/* Sample the remaining pins. */
+	NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff);
+	msleep(20);
+	sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
+		& 0xa << 28;
+
+	/* Restore the previous state. */
+	NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c);
+	NVWriteRAMDAC(dev, head, 0x680c14, ctv_14);
+	NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk);
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0);
+
+	return sample;
+}
+
+static enum drm_connector_status
+nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_mode_config *conf = &dev->mode_config;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct dcb_entry *dcb = tv_enc->base.dcb;
+
+	if (dev_priv->chipset == 0x42 ||
+	    dev_priv->chipset == 0x43)
+		tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe;
+	else
+		tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe;
+
+	switch (tv_enc->pin_mask) {
+	case 0x2:
+	case 0x4:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
+		break;
+	case 0xc:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
+		break;
+	case 0xe:
+		if (dcb->tvconf.has_component_output)
+			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component;
+		else
+			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
+		break;
+	default:
+		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+		break;
+	}
+
+	drm_connector_property_set_value(connector,
+					 conf->tv_subconnector_property,
+					 tv_enc->subconnector);
+
+	if (tv_enc->subconnector) {
+		NV_INFO(dev, "Load detected on output %c\n",
+			'@' + ffs(dcb->or));
+		return connector_status_connected;
+	} else {
+		return connector_status_disconnected;
+	}
+}
+
+static const struct {
+	int hdisplay;
+	int vdisplay;
+} modes[] = {
+	{ 640, 400 },
+	{ 640, 480 },
+	{ 720, 480 },
+	{ 720, 576 },
+	{ 800, 600 },
+	{ 1024, 768 },
+	{ 1280, 720 },
+	{ 1280, 1024 },
+	{ 1920, 1080 }
+};
+
+static int nv17_tv_get_modes(struct drm_encoder *encoder,
+			     struct drm_connector *connector)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	struct drm_display_mode *mode;
+	struct drm_display_mode *output_mode;
+	int n = 0;
+	int i;
+
+	if (tv_norm->kind != CTV_ENC_MODE) {
+		struct drm_display_mode *tv_mode;
+
+		for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) {
+			mode = drm_mode_duplicate(encoder->dev, tv_mode);
+
+			mode->clock = tv_norm->tv_enc_mode.vrefresh *
+						mode->htotal / 1000 *
+						mode->vtotal / 1000;
+
+			if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+				mode->clock *= 2;
+
+			if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay &&
+			    mode->vdisplay == tv_norm->tv_enc_mode.vdisplay)
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+			drm_mode_probed_add(connector, mode);
+			n++;
+		}
+		return n;
+	}
+
+	/* tv_norm->kind == CTV_ENC_MODE */
+	output_mode = &tv_norm->ctv_enc_mode.mode;
+	for (i = 0; i < ARRAY_SIZE(modes); i++) {
+		if (modes[i].hdisplay > output_mode->hdisplay ||
+		    modes[i].vdisplay > output_mode->vdisplay)
+			continue;
+
+		if (modes[i].hdisplay == output_mode->hdisplay &&
+		    modes[i].vdisplay == output_mode->vdisplay) {
+			mode = drm_mode_duplicate(encoder->dev, output_mode);
+			mode->type |= DRM_MODE_TYPE_PREFERRED;
+		} else {
+			mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay,
+				modes[i].vdisplay, 60, false,
+				output_mode->flags & DRM_MODE_FLAG_INTERLACE,
+				false);
+		}
+
+		/* CVT modes are sometimes unsuitable... */
+		if (output_mode->hdisplay <= 720
+		    || output_mode->hdisplay >= 1920) {
+			mode->htotal = output_mode->htotal;
+			mode->hsync_start = (mode->hdisplay + (mode->htotal
+					     - mode->hdisplay) * 9 / 10) & ~7;
+			mode->hsync_end = mode->hsync_start + 8;
+		}
+		if (output_mode->vdisplay >= 1024) {
+			mode->vtotal = output_mode->vtotal;
+			mode->vsync_start = output_mode->vsync_start;
+			mode->vsync_end = output_mode->vsync_end;
+		}
+
+		mode->type |= DRM_MODE_TYPE_DRIVER;
+		drm_mode_probed_add(connector, mode);
+		n++;
+	}
+	return n;
+}
+
+static int nv17_tv_mode_valid(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		struct drm_display_mode *output_mode =
+						&tv_norm->ctv_enc_mode.mode;
+
+		if (mode->clock > 400000)
+			return MODE_CLOCK_HIGH;
+
+		if (mode->hdisplay > output_mode->hdisplay ||
+		    mode->vdisplay > output_mode->vdisplay)
+			return MODE_BAD;
+
+		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) !=
+		    (output_mode->flags & DRM_MODE_FLAG_INTERLACE))
+			return MODE_NO_INTERLACE;
+
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			return MODE_NO_DBLESCAN;
+
+	} else {
+		const int vsync_tolerance = 600;
+
+		if (mode->clock > 70000)
+			return MODE_CLOCK_HIGH;
+
+		if (abs(drm_mode_vrefresh(mode) * 1000 -
+			tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance)
+			return MODE_VSYNC;
+
+		/* The encoder takes care of the actual interlacing */
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			return MODE_NO_INTERLACE;
+	}
+
+	return MODE_OK;
+}
+
+static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (tv_norm->kind == CTV_ENC_MODE)
+		adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
+	else
+		adjusted_mode->clock = 90000;
+
+	return true;
+}
+
+static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+
+	if (nouveau_encoder(encoder)->last_dpms == mode)
+		return;
+	nouveau_encoder(encoder)->last_dpms = mode;
+
+	NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+		 mode, nouveau_encoder(encoder)->dcb->index);
+
+	regs->ptv_200 &= ~1;
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		nv04_dfp_update_fp_control(encoder, mode);
+
+	} else {
+		nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF);
+
+		if (mode == DRM_MODE_DPMS_ON)
+			regs->ptv_200 |= 1;
+	}
+
+	nv_load_ptv(dev, regs, 200);
+
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
+	nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);
+
+	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
+}
+
+static void nv17_tv_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int head = nouveau_crtc(encoder->crtc)->index;
+	uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[
+							NV_CIO_CRE_LCD__INDEX];
+	uint32_t dacclk_off = NV_PRAMDAC_DACCLK +
+					nv04_dac_output_offset(encoder);
+	uint32_t dacclk;
+
+	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	nv04_dfp_disable(dev, head);
+
+	/* Unbind any FP encoders from this head if we need the FP
+	 * stuff enabled. */
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		struct drm_encoder *enc;
+
+		list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
+			struct dcb_entry *dcb = nouveau_encoder(enc)->dcb;
+
+			if ((dcb->type == OUTPUT_TMDS ||
+			     dcb->type == OUTPUT_LVDS) &&
+			     !enc->crtc &&
+			     nv04_dfp_get_bound_head(dev, dcb) == head) {
+				nv04_dfp_bind_head(dev, dcb, head ^ 1,
+						dev_priv->VBIOS.fp.dual_link);
+			}
+		}
+
+	}
+
+	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
+	 * at LCD__INDEX which we don't alter
+	 */
+	if (!(*cr_lcd & 0x44)) {
+		if (tv_norm->kind == CTV_ENC_MODE)
+			*cr_lcd = 0x1 | (head ? 0x0 : 0x8);
+		else
+			*cr_lcd = 0;
+	}
+
+	/* Set the DACCLK register */
+	dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1;
+
+	if (dev_priv->card_type == NV_40)
+		dacclk |= 0x1a << 16;
+
+	if (tv_norm->kind == CTV_ENC_MODE) {
+		dacclk |=  0x20;
+
+		if (head)
+			dacclk |= 0x100;
+		else
+			dacclk &= ~0x100;
+
+	} else {
+		dacclk |= 0x10;
+
+	}
+
+	NVWriteRAMDAC(dev, 0, dacclk_off, dacclk);
+}
+
+static void nv17_tv_mode_set(struct drm_encoder *encoder,
+			     struct drm_display_mode *drm_mode,
+			     struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+	struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int i;
+
+	regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */
+	regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */
+	regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */
+	regs->tv_setup = 1;
+	regs->ramdac_8c0 = 0x0;
+
+	if (tv_norm->kind == TV_ENC_MODE) {
+		tv_regs->ptv_200 = 0x13111100;
+		if (head)
+			tv_regs->ptv_200 |= 0x10;
+
+		tv_regs->ptv_20c = 0x808010;
+		tv_regs->ptv_304 = 0x2d00000;
+		tv_regs->ptv_600 = 0x0;
+		tv_regs->ptv_60c = 0x0;
+		tv_regs->ptv_610 = 0x1e00000;
+
+		if (tv_norm->tv_enc_mode.vdisplay == 576) {
+			tv_regs->ptv_508 = 0x1200000;
+			tv_regs->ptv_614 = 0x33;
+
+		} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
+			tv_regs->ptv_508 = 0xf00000;
+			tv_regs->ptv_614 = 0x13;
+		}
+
+		if (dev_priv->card_type >= NV_30) {
+			tv_regs->ptv_500 = 0xe8e0;
+			tv_regs->ptv_504 = 0x1710;
+			tv_regs->ptv_604 = 0x0;
+			tv_regs->ptv_608 = 0x0;
+		} else {
+			if (tv_norm->tv_enc_mode.vdisplay == 576) {
+				tv_regs->ptv_604 = 0x20;
+				tv_regs->ptv_608 = 0x10;
+				tv_regs->ptv_500 = 0x19710;
+				tv_regs->ptv_504 = 0x68f0;
+
+			} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
+				tv_regs->ptv_604 = 0x10;
+				tv_regs->ptv_608 = 0x20;
+				tv_regs->ptv_500 = 0x4b90;
+				tv_regs->ptv_504 = 0x1b480;
+			}
+		}
+
+		for (i = 0; i < 0x40; i++)
+			tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i];
+
+	} else {
+		struct drm_display_mode *output_mode =
+						&tv_norm->ctv_enc_mode.mode;
+
+		/* The registers in PRAMDAC+0xc00 control some timings and CSC
+		 * parameters for the CTV encoder (It's only used for "HD" TV
+		 * modes, I don't think I have enough working to guess what
+		 * they exactly mean...), it's probably connected at the
+		 * output of the FP encoder, but it also needs the analog
+		 * encoder in its OR enabled and routed to the head it's
+		 * using. It's enabled with the DACCLK register, bits [5:4].
+		 */
+		for (i = 0; i < 38; i++)
+			regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i];
+
+		regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
+		regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
+		regs->fp_horiz_regs[FP_SYNC_START] =
+						output_mode->hsync_start - 1;
+		regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
+		regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay +
+			max((output_mode->hdisplay-600)/40 - 1, 1);
+
+		regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
+		regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
+		regs->fp_vert_regs[FP_SYNC_START] =
+						output_mode->vsync_start - 1;
+		regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
+		regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1;
+
+		regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
+			NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
+			NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
+
+		if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
+			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
+		if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
+			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
+
+		regs->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
+			NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
+			NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
+			NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
+			NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
+			NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
+			NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
+
+		regs->fp_debug_2 = 0;
+
+		regs->fp_margin_color = 0x801080;
+
+	}
+}
+
+static void nv17_tv_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
+
+	if (get_tv_norm(encoder)->kind == TV_ENC_MODE) {
+		nv17_tv_update_rescaler(encoder);
+		nv17_tv_update_properties(encoder);
+	} else {
+		nv17_ctv_update_rescaler(encoder);
+	}
+
+	nv17_tv_state_load(dev, &to_tv_enc(encoder)->state);
+
+	/* This could use refinement for flatpanels, but it should work */
+	if (dev_priv->chipset < 0x44)
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
+					nv04_dac_output_offset(encoder),
+					0xf0000000);
+	else
+		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
+					nv04_dac_output_offset(encoder),
+					0x00100000);
+
+	helper->dpms(encoder, DRM_MODE_DPMS_ON);
+
+	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+		drm_get_connector_name(
+			&nouveau_encoder_connector_get(nv_encoder)->base),
+		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
+}
+
+static void nv17_tv_save(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+
+	nouveau_encoder(encoder)->restore.output =
+					NVReadRAMDAC(dev, 0,
+					NV_PRAMDAC_DACCLK +
+					nv04_dac_output_offset(encoder));
+
+	nv17_tv_state_save(dev, &tv_enc->saved_state);
+
+	tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200;
+}
+
+static void nv17_tv_restore(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+
+	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
+				nv04_dac_output_offset(encoder),
+				nouveau_encoder(encoder)->restore.output);
+
+	nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);
+
+	nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED;
+}
+
+static int nv17_tv_create_resources(struct drm_encoder *encoder,
+				    struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_mode_config *conf = &dev->mode_config;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+	int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
+							NUM_LD_TV_NORMS;
+	int i;
+
+	if (nouveau_tv_norm) {
+		for (i = 0; i < num_tv_norms; i++) {
+			if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) {
+				tv_enc->tv_norm = i;
+				break;
+			}
+		}
+
+		if (i == num_tv_norms)
+			NV_WARN(dev, "Invalid TV norm setting \"%s\"\n",
+				nouveau_tv_norm);
+	}
+
+	drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);
+
+	drm_connector_attach_property(connector,
+					conf->tv_select_subconnector_property,
+					tv_enc->select_subconnector);
+	drm_connector_attach_property(connector,
+					conf->tv_subconnector_property,
+					tv_enc->subconnector);
+	drm_connector_attach_property(connector,
+					conf->tv_mode_property,
+					tv_enc->tv_norm);
+	drm_connector_attach_property(connector,
+					conf->tv_flicker_reduction_property,
+					tv_enc->flicker);
+	drm_connector_attach_property(connector,
+					conf->tv_saturation_property,
+					tv_enc->saturation);
+	drm_connector_attach_property(connector,
+					conf->tv_hue_property,
+					tv_enc->hue);
+	drm_connector_attach_property(connector,
+					conf->tv_overscan_property,
+					tv_enc->overscan);
+
+	return 0;
+}
+
+static int nv17_tv_set_property(struct drm_encoder *encoder,
+				struct drm_connector *connector,
+				struct drm_property *property,
+				uint64_t val)
+{
+	struct drm_mode_config *conf = &encoder->dev->mode_config;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	bool modes_changed = false;
+
+	if (property == conf->tv_overscan_property) {
+		tv_enc->overscan = val;
+		if (encoder->crtc) {
+			if (tv_norm->kind == CTV_ENC_MODE)
+				nv17_ctv_update_rescaler(encoder);
+			else
+				nv17_tv_update_rescaler(encoder);
+		}
+
+	} else if (property == conf->tv_saturation_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->saturation = val;
+		nv17_tv_update_properties(encoder);
+
+	} else if (property == conf->tv_hue_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->hue = val;
+		nv17_tv_update_properties(encoder);
+
+	} else if (property == conf->tv_flicker_reduction_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->flicker = val;
+		if (encoder->crtc)
+			nv17_tv_update_rescaler(encoder);
+
+	} else if (property == conf->tv_mode_property) {
+		if (connector->dpms != DRM_MODE_DPMS_OFF)
+			return -EINVAL;
+
+		tv_enc->tv_norm = val;
+
+		modes_changed = true;
+
+	} else if (property == conf->tv_select_subconnector_property) {
+		if (tv_norm->kind != TV_ENC_MODE)
+			return -EINVAL;
+
+		tv_enc->select_subconnector = val;
+		nv17_tv_update_properties(encoder);
+
+	} else {
+		return -EINVAL;
+	}
+
+	if (modes_changed) {
+		drm_helper_probe_single_connector_modes(connector, 0, 0);
+
+		/* Disable the crtc to ensure a full modeset is
+		 * performed whenever it's turned on again. */
+		if (crtc) {
+			struct drm_mode_set modeset = {
+				.crtc = crtc,
+			};
+
+			crtc->funcs->set_config(&modeset);
+		}
+	}
+
+	return 0;
+}
+
+static void nv17_tv_destroy(struct drm_encoder *encoder)
+{
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+
+	NV_DEBUG_KMS(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(tv_enc);
+}
+
+static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = {
+	.dpms = nv17_tv_dpms,
+	.save = nv17_tv_save,
+	.restore = nv17_tv_restore,
+	.mode_fixup = nv17_tv_mode_fixup,
+	.prepare = nv17_tv_prepare,
+	.commit = nv17_tv_commit,
+	.mode_set = nv17_tv_mode_set,
+	.detect = nv17_tv_detect,
+};
+
+static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = {
+	.get_modes = nv17_tv_get_modes,
+	.mode_valid = nv17_tv_mode_valid,
+	.create_resources = nv17_tv_create_resources,
+	.set_property = nv17_tv_set_property,
+};
+
+static struct drm_encoder_funcs nv17_tv_funcs = {
+	.destroy = nv17_tv_destroy,
+};
+
+int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct drm_encoder *encoder;
+	struct nv17_tv_encoder *tv_enc = NULL;
+
+	tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL);
+	if (!tv_enc)
+		return -ENOMEM;
+
+	tv_enc->overscan = 50;
+	tv_enc->flicker = 50;
+	tv_enc->saturation = 50;
+	tv_enc->hue = 0;
+	tv_enc->tv_norm = TV_NORM_PAL;
+	tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+	tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
+	tv_enc->pin_mask = 0;
+
+	encoder = to_drm_encoder(&tv_enc->base);
+
+	tv_enc->base.dcb = entry;
+	tv_enc->base.or = ffs(entry->or) - 1;
+
+	drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC);
+	drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs);
+	to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs;
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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 __NV17_TV_H__
+#define __NV17_TV_H__
+
+struct nv17_tv_state {
+	uint8_t tv_enc[0x40];
+
+	uint32_t hfilter[4][7];
+	uint32_t hfilter2[4][7];
+	uint32_t vfilter[4][7];
+
+	uint32_t ptv_200;
+	uint32_t ptv_204;
+	uint32_t ptv_208;
+	uint32_t ptv_20c;
+	uint32_t ptv_304;
+	uint32_t ptv_500;
+	uint32_t ptv_504;
+	uint32_t ptv_508;
+	uint32_t ptv_600;
+	uint32_t ptv_604;
+	uint32_t ptv_608;
+	uint32_t ptv_60c;
+	uint32_t ptv_610;
+	uint32_t ptv_614;
+};
+
+enum nv17_tv_norm{
+	TV_NORM_PAL,
+	TV_NORM_PAL_M,
+	TV_NORM_PAL_N,
+	TV_NORM_PAL_NC,
+	TV_NORM_NTSC_M,
+	TV_NORM_NTSC_J,
+	NUM_LD_TV_NORMS,
+	TV_NORM_HD480I = NUM_LD_TV_NORMS,
+	TV_NORM_HD480P,
+	TV_NORM_HD576I,
+	TV_NORM_HD576P,
+	TV_NORM_HD720P,
+	TV_NORM_HD1080I,
+	NUM_TV_NORMS
+};
+
+struct nv17_tv_encoder {
+	struct nouveau_encoder base;
+
+	struct nv17_tv_state state;
+	struct nv17_tv_state saved_state;
+
+	int overscan;
+	int flicker;
+	int saturation;
+	int hue;
+	enum nv17_tv_norm tv_norm;
+	int subconnector;
+	int select_subconnector;
+	uint32_t pin_mask;
+};
+#define to_tv_enc(x) container_of(nouveau_encoder(x),		\
+				  struct nv17_tv_encoder, base)
+
+extern char *nv17_tv_norm_names[NUM_TV_NORMS];
+
+extern struct nv17_tv_norm_params {
+	enum {
+		TV_ENC_MODE,
+		CTV_ENC_MODE,
+	} kind;
+
+	union {
+		struct {
+			int hdisplay;
+			int vdisplay;
+			int vrefresh; /* mHz */
+
+			uint8_t tv_enc[0x40];
+		} tv_enc_mode;
+
+		struct {
+			struct drm_display_mode mode;
+
+			uint32_t ctv_regs[38];
+		} ctv_enc_mode;
+	};
+
+} nv17_tv_norms[NUM_TV_NORMS];
+#define get_tv_norm(enc) (&nv17_tv_norms[to_tv_enc(enc)->tv_norm])
+
+extern struct drm_display_mode nv17_tv_modes[];
+
+static inline int interpolate(int y0, int y1, int y2, int x)
+{
+	return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50;
+}
+
+void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state);
+void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state);
+void nv17_tv_update_properties(struct drm_encoder *encoder);
+void nv17_tv_update_rescaler(struct drm_encoder *encoder);
+void nv17_ctv_update_rescaler(struct drm_encoder *encoder);
+
+/* TV hardware access functions */
+
+static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, uint32_t val)
+{
+	nv_wr32(dev, reg, val);
+}
+
+static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg)
+{
+	return nv_rd32(dev, reg);
+}
+
+static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, uint8_t val)
+{
+	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
+	nv_write_ptv(dev, NV_PTV_TV_DATA, val);
+}
+
+static inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg)
+{
+	nv_write_ptv(dev, NV_PTV_TV_INDEX, reg);
+	return nv_read_ptv(dev, NV_PTV_TV_DATA);
+}
+
+#define nv_load_ptv(dev, state, reg) nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg)
+#define nv_save_ptv(dev, state, reg) state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg)
+#define nv_load_tv_enc(dev, state, reg) nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg])
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv_modes.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv_modes.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv17_tv_modes.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv17_tv_modes.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "nouveau_drv.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_hw.h"
+#include "nv17_tv.h"
+
+char *nv17_tv_norm_names[NUM_TV_NORMS] = {
+	[TV_NORM_PAL] = "PAL",
+	[TV_NORM_PAL_M] = "PAL-M",
+	[TV_NORM_PAL_N] = "PAL-N",
+	[TV_NORM_PAL_NC] = "PAL-Nc",
+	[TV_NORM_NTSC_M] = "NTSC-M",
+	[TV_NORM_NTSC_J] = "NTSC-J",
+	[TV_NORM_HD480I] = "hd480i",
+	[TV_NORM_HD480P] = "hd480p",
+	[TV_NORM_HD576I] = "hd576i",
+	[TV_NORM_HD576P] = "hd576p",
+	[TV_NORM_HD720P] = "hd720p",
+	[TV_NORM_HD1080I] = "hd1080i"
+};
+
+/* TV standard specific parameters */
+
+struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = {
+	[TV_NORM_PAL] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_M] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_N] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_PAL_NC] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_NTSC_M] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_NTSC_J] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD480I] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 480, 59940, {
+					0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0,
+					0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1,
+					0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4,
+					0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD576I] = { TV_ENC_MODE, {
+			.tv_enc_mode = { 720, 576, 50000, {
+					0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18,
+					0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3,
+					0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c,
+					0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3,
+					0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5,
+					0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0,
+					0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b,
+					0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0
+				} } } },
+
+
+	[TV_NORM_HD480P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000,
+						   720, 735, 743, 858, 0, 480, 490, 494, 525, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
+					      0x354003a, 0x40000, 0x6f0344, 0x18100000,
+					      0x10160004, 0x10060005, 0x1006000c, 0x10060020,
+					      0x10060021, 0x140e0022, 0x10060202, 0x1802020a,
+					      0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x70,
+					      0x3ff0000, 0x57, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
+					      0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
+				} } } },
+
+	[TV_NORM_HD576P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000,
+						   720, 730, 738, 864, 0, 576, 581, 585, 625, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x3540000, 0x0, 0x0, 0x314,
+					      0x354003a, 0x40000, 0x6f0344, 0x18100000,
+					      0x10060001, 0x10060009, 0x10060026, 0x10060027,
+					      0x140e0028, 0x10060268, 0x1810026d, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff,
+					      0x10000fff, 0x10000fff, 0x10000fff, 0x69,
+					      0x3ff0000, 0x57, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x80960019, 0x12c0300,
+					      0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400
+				} } } },
+
+	[TV_NORM_HD720P] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250,
+						   1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+				.ctv_regs = { 0x1260394, 0x0, 0x0, 0x622,
+					      0x66b0021, 0x6004a, 0x1210626, 0x8170000,
+					      0x70004, 0x70016, 0x70017, 0x40f0018,
+					      0x702e8, 0x81702ed, 0xfff, 0xfff,
+					      0xfff, 0xfff, 0xfff, 0xfff,
+					      0xfff, 0xfff, 0xfff, 0x0,
+					      0x2e40001, 0x58, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300,
+					      0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0
+				} } } },
+
+	[TV_NORM_HD1080I] = { CTV_ENC_MODE, {
+			.ctv_enc_mode = {
+				.mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250,
+						   1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0,
+						   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
+						   | DRM_MODE_FLAG_INTERLACE) },
+				.ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868,
+					      0x8940028, 0x60054, 0xe80870, 0xbf70000,
+					      0xbc70004, 0x70005, 0x70012, 0x70013,
+					      0x40f0014, 0x70230, 0xbf70232, 0xbf70233,
+					      0x1c70237, 0x70238, 0x70244, 0x70245,
+					      0x40f0246, 0x70462, 0x1f70464, 0x0,
+					      0x2e40001, 0x58, 0x2e001e, 0x258012c,
+					      0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300,
+					      0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0
+				} } } }
+};
+
+/*
+ * The following is some guesswork on how the TV encoder flicker
+ * filter/rescaler works:
+ *
+ * It seems to use some sort of resampling filter, it is controlled
+ * through the registers at NV_PTV_HFILTER and NV_PTV_VFILTER, they
+ * control the horizontal and vertical stage respectively, there is
+ * also NV_PTV_HFILTER2 the blob fills identically to NV_PTV_HFILTER,
+ * but they seem to do nothing. A rough guess might be that they could
+ * be used to independently control the filtering of each interlaced
+ * field, but I don't know how they are enabled. The whole filtering
+ * process seems to be disabled with bits 26:27 of PTV_200, but we
+ * aren't doing that.
+ *
+ * The layout of both register sets is the same:
+ *
+ * A: [BASE+0x18]...[BASE+0x0] [BASE+0x58]..[BASE+0x40]
+ * B: [BASE+0x34]...[BASE+0x1c] [BASE+0x74]..[BASE+0x5c]
+ *
+ * Each coefficient is stored in bits [31],[15:9] in two's complement
+ * format. They seem to be some kind of weights used in a low-pass
+ * filter. Both A and B coefficients are applied to the 14 nearest
+ * samples on each side (Listed from nearest to furthermost.  They
+ * roughly cover 2 framebuffer pixels on each side).  They are
+ * probably multiplied with some more hardwired weights before being
+ * used: B-coefficients are applied the same on both sides,
+ * A-coefficients are inverted before being applied to the opposite
+ * side.
+ *
+ * After all the hassle, I got the following formula by empirical
+ * means...
+ */
+
+#define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o)
+
+#define id1 (1LL << 8)
+#define id2 (1LL << 16)
+#define id3 (1LL << 24)
+#define id4 (1LL << 32)
+#define id5 (1LL << 48)
+
+static struct filter_params{
+	int64_t k1;
+	int64_t ki;
+	int64_t ki2;
+	int64_t ki3;
+	int64_t kr;
+	int64_t kir;
+	int64_t ki2r;
+	int64_t ki3r;
+	int64_t kf;
+	int64_t kif;
+	int64_t ki2f;
+	int64_t ki3f;
+	int64_t krf;
+	int64_t kirf;
+	int64_t ki2rf;
+	int64_t ki3rf;
+} fparams[2][4] = {
+	/* Horizontal filter parameters */
+	{
+		{64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5,
+		 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4,
+		 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3,
+		 -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1},
+		{-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5,
+		 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4,
+		 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3,
+		 -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1},
+		{-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5,
+		 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4,
+		 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3,
+		 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1},
+		{51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5,
+		 -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4,
+		 -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3,
+		 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1},
+	},
+
+	/* Vertical filter parameters */
+	{
+		{67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5,
+		 -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4,
+		 -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3,
+		 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1},
+		{6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5,
+		 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4,
+		 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3,
+		 -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1},
+		{-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5,
+		 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4,
+		 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3,
+		 -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1},
+		{-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5,
+		 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4,
+		 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3,
+		 -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1},
+	}
+};
+
+static void tv_setup_filter(struct drm_encoder *encoder)
+{
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	struct drm_display_mode *mode = &encoder->crtc->mode;
+	uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter,
+				       &tv_enc->state.vfilter};
+	int i, j, k;
+	int32_t overscan = calc_overscan(tv_enc->overscan);
+	int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100);
+	uint64_t rs[] = {mode->hdisplay * id3,
+			 mode->vdisplay * id3};
+
+	do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay);
+	do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay);
+
+	for (k = 0; k < 2; k++) {
+		rs[k] = max((int64_t)rs[k], id2);
+
+		for (j = 0; j < 4; j++) {
+			struct filter_params *p = &fparams[k][j];
+
+			for (i = 0; i < 7; i++) {
+				int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + p->ki3*i*i*i)
+					+ (p->kr + p->kir*i + p->ki2r*i*i + p->ki3r*i*i*i)*rs[k]
+					+ (p->kf + p->kif*i + p->ki2f*i*i + p->ki3f*i*i*i)*flicker
+					+ (p->krf + p->kirf*i + p->ki2rf*i*i + p->ki3rf*i*i*i)*flicker*rs[k];
+
+				(*filters[k])[j][i] = (c + id5/2) >> 39 & (0x1 << 31 | 0x7f << 9);
+			}
+		}
+	}
+}
+
+/* Hardware state saving/restoring */
+
+static void tv_save_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7])
+{
+	int i, j;
+	uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 7; j++)
+			regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j);
+	}
+}
+
+static void tv_load_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7])
+{
+	int i, j;
+	uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c };
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 7; j++)
+			nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]);
+	}
+}
+
+void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state)
+{
+	int i;
+
+	for (i = 0; i < 0x40; i++)
+		state->tv_enc[i] = nv_read_tv_enc(dev, i);
+
+	tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter);
+	tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
+	tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter);
+
+	nv_save_ptv(dev, state, 200);
+	nv_save_ptv(dev, state, 204);
+	nv_save_ptv(dev, state, 208);
+	nv_save_ptv(dev, state, 20c);
+	nv_save_ptv(dev, state, 304);
+	nv_save_ptv(dev, state, 500);
+	nv_save_ptv(dev, state, 504);
+	nv_save_ptv(dev, state, 508);
+	nv_save_ptv(dev, state, 600);
+	nv_save_ptv(dev, state, 604);
+	nv_save_ptv(dev, state, 608);
+	nv_save_ptv(dev, state, 60c);
+	nv_save_ptv(dev, state, 610);
+	nv_save_ptv(dev, state, 614);
+}
+
+void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state)
+{
+	int i;
+
+	for (i = 0; i < 0x40; i++)
+		nv_write_tv_enc(dev, i, state->tv_enc[i]);
+
+	tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter);
+	tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2);
+	tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter);
+
+	nv_load_ptv(dev, state, 200);
+	nv_load_ptv(dev, state, 204);
+	nv_load_ptv(dev, state, 208);
+	nv_load_ptv(dev, state, 20c);
+	nv_load_ptv(dev, state, 304);
+	nv_load_ptv(dev, state, 500);
+	nv_load_ptv(dev, state, 504);
+	nv_load_ptv(dev, state, 508);
+	nv_load_ptv(dev, state, 600);
+	nv_load_ptv(dev, state, 604);
+	nv_load_ptv(dev, state, 608);
+	nv_load_ptv(dev, state, 60c);
+	nv_load_ptv(dev, state, 610);
+	nv_load_ptv(dev, state, 614);
+
+	/* This is required for some settings to kick in. */
+	nv_write_tv_enc(dev, 0x3e, 1);
+	nv_write_tv_enc(dev, 0x3e, 0);
+}
+
+/* Timings similar to the ones the blob sets */
+
+struct drm_display_mode nv17_tv_modes[] = {
+	{ DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0,
+		   320, 344, 392, 560, 0, 200, 200, 202, 220, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0,
+		   320, 344, 392, 560, 0, 240, 240, 246, 263, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0,
+		   400, 432, 496, 640, 0, 300, 300, 303, 314, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC
+		   | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) },
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0,
+		   640, 672, 768, 880, 0, 480, 480, 492, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0,
+		   720, 752, 872, 960, 0, 480, 480, 493, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0,
+		   720, 776, 856, 960, 0, 576, 576, 588, 597, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0,
+		   800, 840, 920, 1040, 0, 600, 600, 604, 618, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0,
+		   1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	{}
+};
+
+void nv17_tv_update_properties(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_state *regs = &tv_enc->state;
+	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
+	int subconnector = tv_enc->select_subconnector ?
+						tv_enc->select_subconnector :
+						tv_enc->subconnector;
+
+	switch (subconnector) {
+	case DRM_MODE_SUBCONNECTOR_Composite:
+	{
+		regs->ptv_204 = 0x2;
+
+		/* The composite connector may be found on either pin. */
+		if (tv_enc->pin_mask & 0x4)
+			regs->ptv_204 |= 0x010000;
+		else if (tv_enc->pin_mask & 0x2)
+			regs->ptv_204 |= 0x100000;
+		else
+			regs->ptv_204 |= 0x110000;
+
+		regs->tv_enc[0x7] = 0x10;
+		break;
+	}
+	case DRM_MODE_SUBCONNECTOR_SVIDEO:
+		regs->ptv_204 = 0x11012;
+		regs->tv_enc[0x7] = 0x18;
+		break;
+
+	case DRM_MODE_SUBCONNECTOR_Component:
+		regs->ptv_204 = 0x111333;
+		regs->tv_enc[0x7] = 0x14;
+		break;
+
+	case DRM_MODE_SUBCONNECTOR_SCART:
+		regs->ptv_204 = 0x111012;
+		regs->tv_enc[0x7] = 0x18;
+		break;
+	}
+
+	regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], 255,
+					 tv_enc->saturation);
+	regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], 255,
+					 tv_enc->saturation);
+	regs->tv_enc[0x25] = tv_enc->hue * 255 / 100;
+
+	nv_load_ptv(dev, regs, 204);
+	nv_load_tv_enc(dev, regs, 7);
+	nv_load_tv_enc(dev, regs, 20);
+	nv_load_tv_enc(dev, regs, 22);
+	nv_load_tv_enc(dev, regs, 25);
+}
+
+void nv17_tv_update_rescaler(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	struct nv17_tv_state *regs = &tv_enc->state;
+
+	regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8);
+
+	tv_setup_filter(encoder);
+
+	nv_load_ptv(dev, regs, 208);
+	tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter);
+	tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2);
+	tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter);
+}
+
+void nv17_ctv_update_rescaler(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
+	int head = nouveau_crtc(encoder->crtc)->index;
+	struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+	struct drm_display_mode *crtc_mode = &encoder->crtc->mode;
+	struct drm_display_mode *output_mode = &get_tv_norm(encoder)->ctv_enc_mode.mode;
+	int overscan, hmargin, vmargin, hratio, vratio;
+
+	/* The rescaler doesn't do the right thing for interlaced modes. */
+	if (output_mode->flags & DRM_MODE_FLAG_INTERLACE)
+		overscan = 100;
+	else
+		overscan = tv_enc->overscan;
+
+	hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2;
+	vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2;
+
+	hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), hmargin,
+			      overscan);
+	vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), vmargin,
+			      overscan);
+
+	hratio = crtc_mode->hdisplay * 0x800 / (output_mode->hdisplay - 2*hmargin);
+	vratio = crtc_mode->vdisplay * 0x800 / (output_mode->vdisplay - 2*vmargin) & ~3;
+
+	regs->fp_horiz_regs[FP_VALID_START] = hmargin;
+	regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1;
+	regs->fp_vert_regs[FP_VALID_START] = vmargin;
+	regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1;
+
+	regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
+		XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) |
+		NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
+		XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
+
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START,
+		      regs->fp_horiz_regs[FP_VALID_START]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END,
+		      regs->fp_horiz_regs[FP_VALID_END]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START,
+		      regs->fp_vert_regs[FP_VALID_START]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END,
+		      regs->fp_vert_regs[FP_VALID_END]);
+	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv20_graph.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv20_graph.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv20_graph.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv20_graph.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,775 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+/*
+ * NV20
+ * -----
+ * There are 3 families :
+ * NV20 is 0x10de:0x020*
+ * NV25/28 is 0x10de:0x025* / 0x10de:0x028*
+ * NV2A is 0x10de:0x02A0
+ *
+ * NV30
+ * -----
+ * There are 3 families :
+ * NV30/31 is 0x10de:0x030* / 0x10de:0x031*
+ * NV34 is 0x10de:0x032*
+ * NV35/36 is 0x10de:0x033* / 0x10de:0x034*
+ *
+ * Not seen in the wild, no dumps (probably NV35) :
+ * NV37 is 0x10de:0x00fc, 0x10de:0x00fd
+ * NV38 is 0x10de:0x0333, 0x10de:0x00fe
+ *
+ */
+
+#define NV20_GRCTX_SIZE (3580*4)
+#define NV25_GRCTX_SIZE (3529*4)
+#define NV2A_GRCTX_SIZE (3500*4)
+
+#define NV30_31_GRCTX_SIZE (24392)
+#define NV34_GRCTX_SIZE    (18140)
+#define NV35_36_GRCTX_SIZE (22396)
+
+static void
+nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x033c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x047c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0490/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04a8/4, 0x44400000);
+	for (i = 0x04d4; i <= 0x04e0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x04f4; i <= 0x0500; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x050c; i <= 0x0518; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x051c; i <= 0x0528; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x052c; i <= 0x0538; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x055c; i <= 0x0598; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x05fc/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0604/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0610/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0618/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x061c/4, 0x00010000);
+	for (i = 0x1c1c; i <= 0x248c; i += 16) {
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x281c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2830/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x285c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2860/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2864/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x286c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2870/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2878/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2880/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x34a4/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x3530/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x3540/4, 0x002fe000);
+	for (i = 0x355c; i <= 0x3578; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x035c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03c0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03c4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x049c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x04b0/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04c8/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x04cc/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x04d0/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x04e4/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x04fc/4, 0x4b800000);
+	for (i = 0x0510; i <= 0x051c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x0530; i <= 0x053c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x0548; i <= 0x0554; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0558; i <= 0x0564; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x0568; i <= 0x0574; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x0598; i <= 0x05d4; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05e0/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x0620/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0624/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0628/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x062c/4, 0xb0a09080);
+	nv_wo32(dev, ctx, 0x0630/4, 0xf0e0d0c0);
+	nv_wo32(dev, ctx, 0x0664/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x066c/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0678/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0680/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0684/4, 0x00010000);
+	for (i = 0x1b04; i <= 0x2374; i += 16) {
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x2704/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2718/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2744/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2748/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x274c/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x2754/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2758/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2760/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2768/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x308c/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x3108/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x3468/4, 0x002fe000);
+	for (i = 0x3484; i <= 0x34a0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x033c/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x047c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0490/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x04a8/4, 0x44400000);
+	for (i = 0x04d4; i <= 0x04e0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x04f4; i <= 0x0500; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080000);
+	for (i = 0x050c; i <= 0x0518; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x051c; i <= 0x0528; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x000105b8);
+	for (i = 0x052c; i <= 0x0538; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	for (i = 0x055c; i <= 0x0598; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x05fc/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0604/4, 0x00004000);
+	nv_wo32(dev, ctx, 0x0610/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0618/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x061c/4, 0x00010000);
+	for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */
+		nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9);
+		nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c);
+		nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b);
+	}
+	nv_wo32(dev, ctx, 0x269c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26b0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26dc/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x26e0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26e4/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x26ec/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x26f0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x26f8/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2700/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x3024/4, 0x000fe000);
+	nv_wo32(dev, ctx, 0x30a0/4, 0x000003f8);
+	nv_wo32(dev, ctx, 0x33fc/4, 0x002fe000);
+	for (i = 0x341c; i <= 0x3438; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x001c527c);
+}
+
+static void
+nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x0410/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0428/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0444/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0448/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x044c/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x0460/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x048c/4, 0xffff0000);
+	for (i = 0x04e0; i < 0x04e8; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04ec/4, 0x00011100);
+	for (i = 0x0508; i < 0x0548; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x0550/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x058c/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0590/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0594/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0598/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x059c/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05b0/4, 0xb0000000);
+	for (i = 0x0600; i < 0x0640; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0640; i < 0x0680; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06c0; i < 0x0700; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x0700; i < 0x0740; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0740; i < 0x0780; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x085c/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0860/4, 0x00010000);
+	for (i = 0x0864; i < 0x0874; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x1f18; i <= 0x3088 ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x30b8; i < 0x30c8; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x344c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3808/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x381c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3848/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x384c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3850/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x3858/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x385c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3864/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x386c/4, 0xbf800000);
+}
+
+static void
+nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x040c/4, 0x01000101);
+	nv_wo32(dev, ctx, 0x0420/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0440/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0444/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x0448/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x045c/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x0480/4, 0xffff0000);
+	for (i = 0x04d4; i < 0x04dc; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04e0/4, 0x00011100);
+	for (i = 0x04fc; i < 0x053c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x0544/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x057c/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0580/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0584/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0588/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x058c/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05a0/4, 0xb0000000);
+	for (i = 0x05f0; i < 0x0630; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0630; i < 0x0670; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06b0; i < 0x06f0; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x06f0; i < 0x0730; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0730; i < 0x0770; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x0850/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0854/4, 0x00010000);
+	for (i = 0x0858; i < 0x0868; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x15ac; i <= 0x271c ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x274c; i < 0x275c; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x2ae0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2e9c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2eb0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2edc/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2ee0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2ee4/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x2eec/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x2ef0/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x2ef8/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x2f00/4, 0xbf800000);
+}
+
+static void
+nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+	int i;
+
+	nv_wo32(dev, ctx, 0x040c/4, 0x00000101);
+	nv_wo32(dev, ctx, 0x0420/4, 0x00000111);
+	nv_wo32(dev, ctx, 0x0424/4, 0x00000060);
+	nv_wo32(dev, ctx, 0x0440/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x0444/4, 0xffff0000);
+	nv_wo32(dev, ctx, 0x0448/4, 0x00000001);
+	nv_wo32(dev, ctx, 0x045c/4, 0x44400000);
+	nv_wo32(dev, ctx, 0x0488/4, 0xffff0000);
+	for (i = 0x04dc; i < 0x04e4; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0fff0000);
+	nv_wo32(dev, ctx, 0x04e8/4, 0x00011100);
+	for (i = 0x0504; i < 0x0544; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x07ff0000);
+	nv_wo32(dev, ctx, 0x054c/4, 0x4b7fffff);
+	nv_wo32(dev, ctx, 0x0588/4, 0x00000080);
+	nv_wo32(dev, ctx, 0x058c/4, 0x30201000);
+	nv_wo32(dev, ctx, 0x0590/4, 0x70605040);
+	nv_wo32(dev, ctx, 0x0594/4, 0xb8a89888);
+	nv_wo32(dev, ctx, 0x0598/4, 0xf8e8d8c8);
+	nv_wo32(dev, ctx, 0x05ac/4, 0xb0000000);
+	for (i = 0x0604; i < 0x0644; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00010588);
+	for (i = 0x0644; i < 0x0684; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00030303);
+	for (i = 0x06c4; i < 0x0704; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0008aae4);
+	for (i = 0x0704; i < 0x0744; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x01012000);
+	for (i = 0x0744; i < 0x0784; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00080008);
+	nv_wo32(dev, ctx, 0x0860/4, 0x00040000);
+	nv_wo32(dev, ctx, 0x0864/4, 0x00010000);
+	for (i = 0x0868; i < 0x0878; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x00040004);
+	for (i = 0x1f1c; i <= 0x308c ; i += 16) {
+		nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9);
+		nv_wo32(dev, ctx, i/4 + 1, 0x0436086c);
+		nv_wo32(dev, ctx, i/4 + 2, 0x000c001b);
+	}
+	for (i = 0x30bc; i < 0x30cc; i += 4)
+		nv_wo32(dev, ctx, i/4, 0x0000ffff);
+	nv_wo32(dev, ctx, 0x3450/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x380c/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3820/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x384c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x3850/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3854/4, 0x3f000000);
+	nv_wo32(dev, ctx, 0x385c/4, 0x40000000);
+	nv_wo32(dev, ctx, 0x3860/4, 0x3f800000);
+	nv_wo32(dev, ctx, 0x3868/4, 0xbf800000);
+	nv_wo32(dev, ctx, 0x3870/4, 0xbf800000);
+}
+
+int
+nv20_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
+	unsigned int ctx_size;
+	unsigned int idoffs = 0x28/4;
+	int ret;
+
+	switch (dev_priv->chipset) {
+	case 0x20:
+		ctx_size = NV20_GRCTX_SIZE;
+		ctx_init = nv20_graph_context_init;
+		idoffs = 0;
+		break;
+	case 0x25:
+	case 0x28:
+		ctx_size = NV25_GRCTX_SIZE;
+		ctx_init = nv25_graph_context_init;
+		break;
+	case 0x2a:
+		ctx_size = NV2A_GRCTX_SIZE;
+		ctx_init = nv2a_graph_context_init;
+		idoffs = 0;
+		break;
+	case 0x30:
+	case 0x31:
+		ctx_size = NV30_31_GRCTX_SIZE;
+		ctx_init = nv30_31_graph_context_init;
+		break;
+	case 0x34:
+		ctx_size = NV34_GRCTX_SIZE;
+		ctx_init = nv34_graph_context_init;
+		break;
+	case 0x35:
+	case 0x36:
+		ctx_size = NV35_36_GRCTX_SIZE;
+		ctx_init = nv35_36_graph_context_init;
+		break;
+	default:
+		ctx_size = 0;
+		ctx_init = nv35_36_graph_context_init;
+		NV_ERROR(dev, "Please contact the devs if you want your NV%x"
+			      " card to work\n", dev_priv->chipset);
+		return -ENOSYS;
+		break;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
+					  NVOBJ_FLAG_ZERO_ALLOC,
+					  &chan->ramin_grctx);
+	if (ret)
+		return ret;
+
+	/* Initialise default context values */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	ctx_init(dev, chan->ramin_grctx->gpuobj);
+
+	/* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
+	nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs,
+					(chan->id << 24) | 0x1); /* CTX_USER */
+
+	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id,
+			chan->ramin_grctx->instance >> 4);
+
+	dev_priv->engine.instmem.finish_access(dev);
+	return 0;
+}
+
+void
+nv20_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (chan->ramin_grctx)
+		nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0);
+	dev_priv->engine.instmem.finish_access(dev);
+}
+
+int
+nv20_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t inst;
+
+	if (!chan->ramin_grctx)
+		return -EINVAL;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
+		     NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD);
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+
+	nouveau_wait_for_idle(dev);
+	return 0;
+}
+
+int
+nv20_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	uint32_t inst, tmp;
+
+	chan = pgraph->channel(dev);
+	if (!chan)
+		return 0;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
+		     NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
+
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (pfifo->channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
+
+static void
+nv20_graph_rdi(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i, writecount = 32;
+	uint32_t rdi_index = 0x2c80000;
+
+	if (dev_priv->chipset == 0x20) {
+		rdi_index = 0x3d0000;
+		writecount = 15;
+	}
+
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
+	for (i = 0; i < writecount; i++)
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
+
+	nouveau_wait_for_idle(dev);
+}
+
+void
+nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			     uint32_t size, uint32_t pitch)
+{
+	uint32_t limit = max(1u, addr + size) - 1;
+
+	if (pitch)
+		addr |= 1;
+
+	nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
+	nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
+	nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
+
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, limit);
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, pitch);
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, addr);
+}
+
+int
+nv20_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv =
+		(struct drm_nouveau_private *)dev->dev_private;
+	uint32_t tmp, vramsz;
+	int ret, i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
+
+	if (!dev_priv->ctx_table) {
+		/* Create Context Pointer Table */
+		dev_priv->ctx_table_size = 32 * 4;
+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
+						  dev_priv->ctx_table_size, 16,
+						  NVOBJ_FLAG_ZERO_ALLOC,
+						  &dev_priv->ctx_table);
+		if (ret)
+			return ret;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
+		 dev_priv->ctx_table->instance >> 4);
+
+	nv20_graph_rdi(dev);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
+	nv_wr32(dev, 0x40009C           , 0x00000040);
+
+	if (dev_priv->chipset >= 0x25) {
+		nv_wr32(dev, 0x400890, 0x00080000);
+		nv_wr32(dev, 0x400610, 0x304B1FB6);
+		nv_wr32(dev, 0x400B80, 0x18B82880);
+		nv_wr32(dev, 0x400B84, 0x44000000);
+		nv_wr32(dev, 0x400098, 0x40000080);
+		nv_wr32(dev, 0x400B88, 0x000000ff);
+	} else {
+		nv_wr32(dev, 0x400880, 0x00080000); /* 0x0008c7df */
+		nv_wr32(dev, 0x400094, 0x00000005);
+		nv_wr32(dev, 0x400B80, 0x45CAA208); /* 0x45eae20e */
+		nv_wr32(dev, 0x400B84, 0x24000000);
+		nv_wr32(dev, 0x400098, 0x00000040);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
+	}
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
+		nv20_graph_set_region_tiling(dev, i, 0, 0, 0);
+
+	for (i = 0; i < 8; i++) {
+		nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4));
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
+					nv_rd32(dev, 0x100300 + i * 4));
+	}
+	nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324));
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00;
+	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
+	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100;
+	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
+
+	/* begin RAM config */
+	vramsz = drm_get_resource_len(dev, 0) - 1;
+	nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1));
+	nv_wr32(dev, 0x400820, 0);
+	nv_wr32(dev, 0x400824, 0);
+	nv_wr32(dev, 0x400864, vramsz - 1);
+	nv_wr32(dev, 0x400868, vramsz - 1);
+
+	/* interesting.. the below overwrites some of the tile setup above.. */
+	nv_wr32(dev, 0x400B20, 0x00000000);
+	nv_wr32(dev, 0x400B04, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
+	return 0;
+}
+
+void
+nv20_graph_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table);
+}
+
+int
+nv30_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int ret, i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
+
+	if (!dev_priv->ctx_table) {
+		/* Create Context Pointer Table */
+		dev_priv->ctx_table_size = 32 * 4;
+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
+						  dev_priv->ctx_table_size, 16,
+						  NVOBJ_FLAG_ZERO_ALLOC,
+						  &dev_priv->ctx_table);
+		if (ret)
+			return ret;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
+			dev_priv->ctx_table->instance >> 4);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+	nv_wr32(dev, 0x400890, 0x01b463ff);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf2de0475);
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
+	nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
+	nv_wr32(dev, 0x400B80, 0x1003d888);
+	nv_wr32(dev, 0x400B84, 0x0c000000);
+	nv_wr32(dev, 0x400098, 0x00000000);
+	nv_wr32(dev, 0x40009C, 0x0005ad00);
+	nv_wr32(dev, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */
+	nv_wr32(dev, 0x4000a0, 0x00000000);
+	nv_wr32(dev, 0x4000a4, 0x00000008);
+	nv_wr32(dev, 0x4008a8, 0xb784a400);
+	nv_wr32(dev, 0x400ba0, 0x002f8685);
+	nv_wr32(dev, 0x400ba4, 0x00231f3f);
+	nv_wr32(dev, 0x4008a4, 0x40000020);
+
+	if (dev_priv->chipset == 0x34) {
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00200201);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000008);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000032);
+		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00004);
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000002);
+	}
+
+	nv_wr32(dev, 0x4000c0, 0x00000016);
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
+		nv20_graph_set_region_tiling(dev, i, 0, 0, 0);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+	nv_wr32(dev, 0x0040075c             , 0x00000001);
+
+	/* begin RAM config */
+	/* vramsz = drm_get_resource_len(dev, 0) - 1; */
+	nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+	nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+	if (dev_priv->chipset != 0x34) {
+		nv_wr32(dev, 0x400750, 0x00EA0000);
+		nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x400750, 0x00EA0004);
+		nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG1));
+	}
+
+	return 0;
+}
+
+struct nouveau_pgraph_object_class nv20_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x009e, false, NULL }, /* swzsurf */
+	{ 0x0096, false, NULL }, /* celcius */
+	{ 0x0097, false, NULL }, /* kelvin (nv20) */
+	{ 0x0597, false, NULL }, /* kelvin (nv25) */
+	{}
+};
+
+struct nouveau_pgraph_object_class nv30_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x038a, false, NULL }, /* ifc (nv30) */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x0389, false, NULL }, /* sifm (nv30) */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x0362, false, NULL }, /* surf2d (nv30) */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x039e, false, NULL }, /* swzsurf */
+	{ 0x0397, false, NULL }, /* rankine (nv30) */
+	{ 0x0497, false, NULL }, /* rankine (nv35) */
+	{ 0x0697, false, NULL }, /* rankine (nv34) */
+	{}
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,75 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+void
+nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			  uint32_t size, uint32_t pitch)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t limit = max(1u, addr + size) - 1;
+
+	if (pitch)
+		addr |= 1;
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+		nv_wr32(dev, NV10_PFB_TLIMIT(i), limit);
+		nv_wr32(dev, NV10_PFB_TSIZE(i), pitch);
+		nv_wr32(dev, NV10_PFB_TILE(i), addr);
+		break;
+
+	default:
+		nv_wr32(dev, NV40_PFB_TLIMIT(i), limit);
+		nv_wr32(dev, NV40_PFB_TSIZE(i), pitch);
+		nv_wr32(dev, NV40_PFB_TILE(i), addr);
+		break;
+	}
+}
+
+int
+nv40_fb_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+	uint32_t tmp;
+	int i;
+
+	/* This is strictly a NV4x register (don't know about NV5x). */
+	/* The blob sets these to all kinds of values, and they mess up our setup. */
+	/* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */
+	/* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */
+	/* Any idea what this is? */
+	nv_wr32(dev, NV40_PFB_UNK_800, 0x1);
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x45:
+		tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
+		nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
+		pfb->num_tiles = NV10_PFB_TILE__SIZE;
+		break;
+	case 0x46: /* G72 */
+	case 0x47: /* G70 */
+	case 0x49: /* G71 */
+	case 0x4b: /* G73 */
+	case 0x4c: /* C51 (G7X version) */
+		pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
+		break;
+	default:
+		pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
+		break;
+	}
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < pfb->num_tiles; i++)
+		pfb->set_region_tiling(dev, i, 0, 0, 0);
+
+	return 0;
+}
+
+void
+nv40_fb_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_fifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV40_RAMFC__SIZE))
+#define NV40_RAMFC__SIZE 128
+
+int
+nv40_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV40_RAMFC(chan->id);
+	int ret;
+
+	ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0,
+				      NV40_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC |
+				      NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc +  0, chan->pushbuf_base);
+	nv_wi32(dev, fc +  4, chan->pushbuf_base);
+	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
+	nv_wi32(dev, fc + 24, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+			      NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
+#ifdef __BIG_ENDIAN
+			      NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+			      0x30000000 /* no idea.. */);
+	nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4);
+	nv_wi32(dev, fc + 60, 0x0001FFFF);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/* enable the fifo dma operation */
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id));
+	return 0;
+}
+
+void
+nv40_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, NV04_PFIFO_MODE,
+		nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
+
+	if (chan->ramfc)
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+}
+
+static void
+nv40_fifo_do_load_context(struct drm_device *dev, int chid)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t fc = NV40_RAMFC(chid), tmp, tmp2;
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, nv_ri32(dev, fc + 12));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, nv_ri32(dev, fc + 16));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 20));
+
+	/* No idea what 0x2058 is.. */
+	tmp   = nv_ri32(dev, fc + 24);
+	tmp2  = nv_rd32(dev, 0x2058) & 0xFFF;
+	tmp2 |= (tmp & 0x30000000);
+	nv_wr32(dev, 0x2058, tmp2);
+	tmp  &= ~0x30000000;
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, tmp);
+
+	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 28));
+	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 32));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 36));
+	tmp = nv_ri32(dev, fc + 40);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp);
+	nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 44));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 48));
+	nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 52));
+	nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, nv_ri32(dev, fc + 56));
+
+	/* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */
+	tmp  = nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF;
+	tmp |= nv_ri32(dev, fc + 60) & 0x1FFFF;
+	nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, tmp);
+
+	nv_wr32(dev, 0x32e4, nv_ri32(dev, fc + 64));
+	/* NVIDIA does this next line twice... */
+	nv_wr32(dev, 0x32e8, nv_ri32(dev, fc + 68));
+	nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
+	nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
+}
+
+int
+nv40_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t tmp;
+
+	nv40_fifo_do_load_context(dev, chan->id);
+
+	/* Set channel active, and in DMA mode */
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV40_PFIFO_CACHE1_PUSH1_DMA | chan->id);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1);
+
+	/* Reset DMA_CTL_AT_INFO to INVALID */
+	tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31);
+	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp);
+
+	return 0;
+}
+
+int
+nv40_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	uint32_t fc, tmp;
+	int chid;
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
+		return 0;
+	fc = NV40_RAMFC(chid);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
+	nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
+	nv_wi32(dev, fc + 12, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE));
+	nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT));
+	nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE));
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH);
+	tmp |= nv_rd32(dev, 0x2058) & 0x30000000;
+	nv_wi32(dev, fc + 24, tmp);
+	nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
+	nv_wi32(dev, fc + 32, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
+	nv_wi32(dev, fc + 36, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE));
+	tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP);
+	nv_wi32(dev, fc + 40, tmp);
+	nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT));
+	nv_wi32(dev, fc + 48, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE));
+	/* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something
+	 * more involved depending on the value of 0x3228?
+	 */
+	nv_wi32(dev, fc + 52, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
+	nv_wi32(dev, fc + 56, nv_rd32(dev, NV40_PFIFO_GRCTX_INSTANCE));
+	nv_wi32(dev, fc + 60, nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & 0x1ffff);
+	/* No idea what the below is for exactly, ripped from a mmio-trace */
+	nv_wi32(dev, fc + 64, nv_rd32(dev, NV40_PFIFO_UNK32E4));
+	/* NVIDIA do this next line twice.. bug? */
+	nv_wi32(dev, fc + 68, nv_rd32(dev, 0x32e8));
+	nv_wi32(dev, fc + 76, nv_rd32(dev, 0x2088));
+	nv_wi32(dev, fc + 80, nv_rd32(dev, 0x3300));
+#if 0 /* no real idea which is PUT/GET in UNK_48.. */
+	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_GET);
+	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
+	nv_wi32(dev, fc + 72, tmp);
+#endif
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
+		     NV40_PFIFO_CACHE1_PUSH1_DMA | (pfifo->channels - 1));
+	return 0;
+}
+
+static void
+nv40_fifo_init_reset(struct drm_device *dev)
+{
+	int i;
+
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO);
+	nv_wr32(dev, NV03_PMC_ENABLE,
+		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PFIFO);
+
+	nv_wr32(dev, 0x003224, 0x000f0078);
+	nv_wr32(dev, 0x003210, 0x00000000);
+	nv_wr32(dev, 0x003270, 0x00000000);
+	nv_wr32(dev, 0x003240, 0x00000000);
+	nv_wr32(dev, 0x003244, 0x00000000);
+	nv_wr32(dev, 0x003258, 0x00000000);
+	nv_wr32(dev, 0x002504, 0x00000000);
+	for (i = 0; i < 16; i++)
+		nv_wr32(dev, 0x002510 + (i * 4), 0x00000000);
+	nv_wr32(dev, 0x00250c, 0x0000ffff);
+	nv_wr32(dev, 0x002048, 0x00000000);
+	nv_wr32(dev, 0x003228, 0x00000000);
+	nv_wr32(dev, 0x0032e8, 0x00000000);
+	nv_wr32(dev, 0x002410, 0x00000000);
+	nv_wr32(dev, 0x002420, 0x00000000);
+	nv_wr32(dev, 0x002058, 0x00000001);
+	nv_wr32(dev, 0x00221c, 0x00000000);
+	/* something with 0x2084, read/modify/write, no change */
+	nv_wr32(dev, 0x002040, 0x000000ff);
+	nv_wr32(dev, 0x002500, 0x00000000);
+	nv_wr32(dev, 0x003200, 0x00000000);
+
+	nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff);
+}
+
+static void
+nv40_fifo_init_ramxx(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+				       ((dev_priv->ramht_bits - 9) << 16) |
+				       (dev_priv->ramht_offset >> 8));
+	nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
+
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		nv_wr32(dev, 0x2230, 1);
+		break;
+	default:
+		break;
+	}
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x45:
+	case 0x47:
+	case 0x48:
+	case 0x49:
+	case 0x4b:
+		nv_wr32(dev, NV40_PFIFO_RAMFC, 0x30002);
+		break;
+	default:
+		nv_wr32(dev, 0x2230, 0);
+		nv_wr32(dev, NV40_PFIFO_RAMFC,
+			((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+			  dev_priv->ramfc_offset) >> 16) | (3 << 16));
+		break;
+	}
+}
+
+static void
+nv40_fifo_init_intr(struct drm_device *dev)
+{
+	nv_wr32(dev, 0x002100, 0xffffffff);
+	nv_wr32(dev, 0x002140, 0xffffffff);
+}
+
+int
+nv40_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	int i;
+
+	nv40_fifo_init_reset(dev);
+	nv40_fifo_init_ramxx(dev);
+
+	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
+
+	nv40_fifo_init_intr(dev);
+	pfifo->enable(dev);
+	pfifo->reassign(dev, true);
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (dev_priv->fifos[i]) {
+			uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE);
+			nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i));
+		}
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_graph.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_grctx.h"
+
+struct nouveau_channel *
+nv40_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
+		return NULL;
+	inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4;
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->ramin_grctx &&
+		    chan->ramin_grctx->instance == inst)
+			return chan;
+	}
+
+	return NULL;
+}
+
+int
+nv40_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	int ret;
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
+				     16, NVOBJ_FLAG_ZERO_ALLOC,
+				     &chan->ramin_grctx);
+	if (ret)
+		return ret;
+
+	/* Initialise default context values */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	if (!pgraph->ctxprog) {
+		struct nouveau_grctx ctx = {};
+
+		ctx.dev = chan->dev;
+		ctx.mode = NOUVEAU_GRCTX_VALS;
+		ctx.data = chan->ramin_grctx->gpuobj;
+		nv40_grctx_init(&ctx);
+	} else {
+		nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj);
+	}
+	nv_wo32(dev, chan->ramin_grctx->gpuobj, 0,
+		     chan->ramin_grctx->gpuobj->im_pramin->start);
+	dev_priv->engine.instmem.finish_access(dev);
+	return 0;
+}
+
+void
+nv40_graph_destroy_context(struct nouveau_channel *chan)
+{
+	nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx);
+}
+
+static int
+nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
+{
+	uint32_t old_cp, tv = 1000, tmp;
+	int i;
+
+	old_cp = nv_rd32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+
+	tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310);
+	tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
+		      NV40_PGRAPH_CTXCTL_0310_XFER_LOAD;
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_0310, tmp);
+
+	tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0304);
+	tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX;
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_0304, tmp);
+
+	nouveau_wait_for_idle(dev);
+
+	for (i = 0; i < tv; i++) {
+		if (nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C) == 0)
+			break;
+	}
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp);
+
+	if (i == tv) {
+		uint32_t ucstat = nv_rd32(dev, NV40_PGRAPH_CTXCTL_UCODE_STAT);
+		NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save);
+		NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n",
+			 ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT,
+			 ucstat  & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK);
+		NV_ERROR(dev, "0x40030C = 0x%08x\n",
+			 nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+/* Restore the context for a specific channel into PGRAPH */
+int
+nv40_graph_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	uint32_t inst;
+	int ret;
+
+	if (!chan->ramin_grctx)
+		return -EINVAL;
+	inst = chan->ramin_grctx->instance >> 4;
+
+	ret = nv40_graph_transfer_context(dev, inst, 0);
+	if (ret)
+		return ret;
+
+	/* 0x40032C, no idea of it's exact function.  Could simply be a
+	 * record of the currently active PGRAPH context.  It's currently
+	 * unknown as to what bit 24 does.  The nv ddx has it set, so we will
+	 * set it here too.
+	 */
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR,
+		 (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) |
+		  NV40_PGRAPH_CTXCTL_CUR_LOADED);
+	/* 0x32E0 records the instance address of the active FIFO's PGRAPH
+	 * context.  If at any time this doesn't match 0x40032C, you will
+	 * recieve PGRAPH_INTR_CONTEXT_SWITCH
+	 */
+	nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst);
+	return 0;
+}
+
+int
+nv40_graph_unload_context(struct drm_device *dev)
+{
+	uint32_t inst;
+	int ret;
+
+	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
+
+	ret = nv40_graph_transfer_context(dev, inst, 1);
+
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
+	return ret;
+}
+
+void
+nv40_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
+			     uint32_t size, uint32_t pitch)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t limit = max(1u, addr + size) - 1;
+
+	if (pitch)
+		addr |= 1;
+
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x4a:
+	case 0x4e:
+		nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
+		nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
+		nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
+		break;
+
+	case 0x46:
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		nv_wr32(dev, NV47_PGRAPH_TSIZE(i), pitch);
+		nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), limit);
+		nv_wr32(dev, NV47_PGRAPH_TILE(i), addr);
+		nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch);
+		nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit);
+		nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr);
+		break;
+
+	default:
+		nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch);
+		nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit);
+		nv_wr32(dev, NV20_PGRAPH_TILE(i), addr);
+		nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch);
+		nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit);
+		nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr);
+		break;
+	}
+}
+
+/*
+ * G70		0x47
+ * G71		0x49
+ * NV45		0x48
+ * G72[M]	0x46
+ * G73		0x4b
+ * C51_G7X	0x4c
+ * C51		0x4e
+ */
+int
+nv40_graph_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv =
+		(struct drm_nouveau_private *)dev->dev_private;
+	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+	uint32_t vramsz;
+	int i, j;
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
+			~NV_PMC_ENABLE_PGRAPH);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
+			 NV_PMC_ENABLE_PGRAPH);
+
+	if (nouveau_ctxfw) {
+		nouveau_grctx_prog_load(dev);
+		dev_priv->engine.graph.grctx_size = 175 * 1024;
+	}
+
+	if (!dev_priv->engine.graph.ctxprog) {
+		struct nouveau_grctx ctx = {};
+		uint32_t cp[256];
+
+		ctx.dev = dev;
+		ctx.mode = NOUVEAU_GRCTX_PROG;
+		ctx.data = cp;
+		ctx.ctxprog_max = 256;
+		nv40_grctx_init(&ctx);
+		dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
+
+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+		for (i = 0; i < ctx.ctxprog_len; i++)
+			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
+	}
+
+	/* No context present currently */
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
+
+	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xe0de8055);
+	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
+	nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+
+	j = nv_rd32(dev, 0x1540) & 0xff;
+	if (j) {
+		for (i = 0; !(j & 1); j >>= 1, i++)
+			;
+		nv_wr32(dev, 0x405000, i);
+	}
+
+	if (dev_priv->chipset == 0x40) {
+		nv_wr32(dev, 0x4009b0, 0x83280fff);
+		nv_wr32(dev, 0x4009b4, 0x000000a0);
+	} else {
+		nv_wr32(dev, 0x400820, 0x83280eff);
+		nv_wr32(dev, 0x400824, 0x000000a0);
+	}
+
+	switch (dev_priv->chipset) {
+	case 0x40:
+	case 0x45:
+		nv_wr32(dev, 0x4009b8, 0x0078e366);
+		nv_wr32(dev, 0x4009bc, 0x0000014c);
+		break;
+	case 0x41:
+	case 0x42: /* pciid also 0x00Cx */
+	/* case 0x0120: XXX (pciid) */
+		nv_wr32(dev, 0x400828, 0x007596ff);
+		nv_wr32(dev, 0x40082c, 0x00000108);
+		break;
+	case 0x43:
+		nv_wr32(dev, 0x400828, 0x0072cb77);
+		nv_wr32(dev, 0x40082c, 0x00000108);
+		break;
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4a:
+	case 0x4c: /* G7x-based C51 */
+	case 0x4e:
+		nv_wr32(dev, 0x400860, 0);
+		nv_wr32(dev, 0x400864, 0);
+		break;
+	case 0x47: /* G70 */
+	case 0x49: /* G71 */
+	case 0x4b: /* G73 */
+		nv_wr32(dev, 0x400828, 0x07830610);
+		nv_wr32(dev, 0x40082c, 0x0000016A);
+		break;
+	default:
+		break;
+	}
+
+	nv_wr32(dev, 0x400b38, 0x2ffff800);
+	nv_wr32(dev, 0x400b3c, 0x00006000);
+
+	/* Turn all the tiling regions off. */
+	for (i = 0; i < pfb->num_tiles; i++)
+		nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
+
+	/* begin RAM config */
+	vramsz = drm_get_resource_len(dev, 0) - 1;
+	switch (dev_priv->chipset) {
+	case 0x40:
+		nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x4069A4, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4069A8, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x400820, 0);
+		nv_wr32(dev, 0x400824, 0);
+		nv_wr32(dev, 0x400864, vramsz);
+		nv_wr32(dev, 0x400868, vramsz);
+		break;
+	default:
+		switch (dev_priv->chipset) {
+		case 0x46:
+		case 0x47:
+		case 0x49:
+		case 0x4b:
+			nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0));
+			nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1));
+			break;
+		default:
+			nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0));
+			nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1));
+			break;
+		}
+		nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0));
+		nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1));
+		nv_wr32(dev, 0x400840, 0);
+		nv_wr32(dev, 0x400844, 0);
+		nv_wr32(dev, 0x4008A0, vramsz);
+		nv_wr32(dev, 0x4008A4, vramsz);
+		break;
+	}
+
+	return 0;
+}
+
+void nv40_graph_takedown(struct drm_device *dev)
+{
+	nouveau_grctx_fini(dev);
+}
+
+struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x0039, false, NULL }, /* m2mf */
+	{ 0x004a, false, NULL }, /* gdirect */
+	{ 0x009f, false, NULL }, /* imageblit (nv12) */
+	{ 0x008a, false, NULL }, /* ifc */
+	{ 0x0089, false, NULL }, /* sifm */
+	{ 0x3089, false, NULL }, /* sifm (nv40) */
+	{ 0x0062, false, NULL }, /* surf2d */
+	{ 0x3062, false, NULL }, /* surf2d (nv40) */
+	{ 0x0043, false, NULL }, /* rop */
+	{ 0x0012, false, NULL }, /* beta1 */
+	{ 0x0072, false, NULL }, /* beta4 */
+	{ 0x0019, false, NULL }, /* cliprect */
+	{ 0x0044, false, NULL }, /* pattern */
+	{ 0x309e, false, NULL }, /* swzsurf */
+	{ 0x4097, false, NULL }, /* curie (nv40) */
+	{ 0x4497, false, NULL }, /* curie (nv44) */
+	{}
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_grctx.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_grctx.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_grctx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_grctx.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,678 @@
+/*
+ * Copyright 2009 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
+ */
+
+/* NVIDIA context programs handle a number of other conditions which are
+ * not implemented in our versions.  It's not clear why NVIDIA context
+ * programs have this code, nor whether it's strictly necessary for
+ * correct operation.  We'll implement additional handling if/when we
+ * discover it's necessary.
+ *
+ * - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state"
+ *   flag is set, this gets saved into the context.
+ * - On context save, the context program for all cards load nsource
+ *   into a flag register and check for ILLEGAL_MTHD.  If it's set,
+ *   opcode 0x60000d is called before resuming normal operation.
+ * - Some context programs check more conditions than the above.  NV44
+ *   checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001))
+ *   and calls 0x60000d before resuming normal operation.
+ * - At the very beginning of NVIDIA's context programs, flag 9 is checked
+ *   and if true 0x800001 is called with count=0, pos=0, the flag is cleared
+ *   and then the ctxprog is aborted.  It looks like a complicated NOP,
+ *   its purpose is unknown.
+ * - In the section of code that loads the per-vs state, NVIDIA check
+ *   flag 10.  If it's set, they only transfer the small 0x300 byte block
+ *   of state + the state for a single vs as opposed to the state for
+ *   all vs units.  It doesn't seem likely that it'll occur in normal
+ *   operation, especially seeing as it appears NVIDIA may have screwed
+ *   up the ctxprogs for some cards and have an invalid instruction
+ *   rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction.
+ * - There's a number of places where context offset 0 (where we place
+ *   the PRAMIN offset of the context) is loaded into either 0x408000,
+ *   0x408004 or 0x408008.  Not sure what's up there either.
+ * - The ctxprogs for some cards save 0x400a00 again during the cleanup
+ *   path for auto-loadctx.
+ */
+
+#define CP_FLAG_CLEAR                 0
+#define CP_FLAG_SET                   1
+#define CP_FLAG_SWAP_DIRECTION        ((0 * 32) + 0)
+#define CP_FLAG_SWAP_DIRECTION_LOAD   0
+#define CP_FLAG_SWAP_DIRECTION_SAVE   1
+#define CP_FLAG_USER_SAVE             ((0 * 32) + 5)
+#define CP_FLAG_USER_SAVE_NOT_PENDING 0
+#define CP_FLAG_USER_SAVE_PENDING     1
+#define CP_FLAG_USER_LOAD             ((0 * 32) + 6)
+#define CP_FLAG_USER_LOAD_NOT_PENDING 0
+#define CP_FLAG_USER_LOAD_PENDING     1
+#define CP_FLAG_STATUS                ((3 * 32) + 0)
+#define CP_FLAG_STATUS_IDLE           0
+#define CP_FLAG_STATUS_BUSY           1
+#define CP_FLAG_AUTO_SAVE             ((3 * 32) + 4)
+#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0
+#define CP_FLAG_AUTO_SAVE_PENDING     1
+#define CP_FLAG_AUTO_LOAD             ((3 * 32) + 5)
+#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
+#define CP_FLAG_AUTO_LOAD_PENDING     1
+#define CP_FLAG_UNK54                 ((3 * 32) + 6)
+#define CP_FLAG_UNK54_CLEAR           0
+#define CP_FLAG_UNK54_SET             1
+#define CP_FLAG_ALWAYS                ((3 * 32) + 8)
+#define CP_FLAG_ALWAYS_FALSE          0
+#define CP_FLAG_ALWAYS_TRUE           1
+#define CP_FLAG_UNK57                 ((3 * 32) + 9)
+#define CP_FLAG_UNK57_CLEAR           0
+#define CP_FLAG_UNK57_SET             1
+
+#define CP_CTX                   0x00100000
+#define CP_CTX_COUNT             0x000fc000
+#define CP_CTX_COUNT_SHIFT               14
+#define CP_CTX_REG               0x00003fff
+#define CP_LOAD_SR               0x00200000
+#define CP_LOAD_SR_VALUE         0x000fffff
+#define CP_BRA                   0x00400000
+#define CP_BRA_IP                0x0000ff00
+#define CP_BRA_IP_SHIFT                   8
+#define CP_BRA_IF_CLEAR          0x00000080
+#define CP_BRA_FLAG              0x0000007f
+#define CP_WAIT                  0x00500000
+#define CP_WAIT_SET              0x00000080
+#define CP_WAIT_FLAG             0x0000007f
+#define CP_SET                   0x00700000
+#define CP_SET_1                 0x00000080
+#define CP_SET_FLAG              0x0000007f
+#define CP_NEXT_TO_SWAP          0x00600007
+#define CP_NEXT_TO_CURRENT       0x00600009
+#define CP_SET_CONTEXT_POINTER   0x0060000a
+#define CP_END                   0x0060000e
+#define CP_LOAD_MAGIC_UNK01      0x00800001 /* unknown */
+#define CP_LOAD_MAGIC_NV44TCL    0x00800029 /* per-vs state (0x4497) */
+#define CP_LOAD_MAGIC_NV40TCL    0x00800041 /* per-vs state (0x4097) */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_grctx.h"
+
+/* TODO:
+ *  - get vs count from 0x1540
+ *  - document unimplemented bits compared to nvidia
+ *    - nsource handling
+ *    - R0 & 0x0200 handling
+ *    - single-vs handling
+ *    - 400314 bit 0
+ */
+
+static int
+nv40_graph_4097(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if ((dev_priv->chipset & 0xf0) == 0x60)
+		return 0;
+
+	return !!(0x0baf & (1 << dev_priv->chipset));
+}
+
+static int
+nv40_graph_vs_count(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		return 8;
+	case 0x40:
+		return 6;
+	case 0x41:
+	case 0x42:
+		return 5;
+	case 0x43:
+	case 0x44:
+	case 0x46:
+	case 0x4a:
+		return 3;
+	case 0x4c:
+	case 0x4e:
+	case 0x67:
+	default:
+		return 1;
+	}
+}
+
+
+enum cp_label {
+	cp_check_load = 1,
+	cp_setup_auto_load,
+	cp_setup_load,
+	cp_setup_save,
+	cp_swap_state,
+	cp_swap_state3d_3_is_save,
+	cp_prepare_exit,
+	cp_exit,
+};
+
+static void
+nv40_graph_construct_general(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i;
+
+	cp_ctx(ctx, 0x4000a4, 1);
+	gr_def(ctx, 0x4000a4, 0x00000008);
+	cp_ctx(ctx, 0x400144, 58);
+	gr_def(ctx, 0x400144, 0x00000001);
+	cp_ctx(ctx, 0x400314, 1);
+	gr_def(ctx, 0x400314, 0x00000000);
+	cp_ctx(ctx, 0x400400, 10);
+	cp_ctx(ctx, 0x400480, 10);
+	cp_ctx(ctx, 0x400500, 19);
+	gr_def(ctx, 0x400514, 0x00040000);
+	gr_def(ctx, 0x400524, 0x55555555);
+	gr_def(ctx, 0x400528, 0x55555555);
+	gr_def(ctx, 0x40052c, 0x55555555);
+	gr_def(ctx, 0x400530, 0x55555555);
+	cp_ctx(ctx, 0x400560, 6);
+	gr_def(ctx, 0x400568, 0x0000ffff);
+	gr_def(ctx, 0x40056c, 0x0000ffff);
+	cp_ctx(ctx, 0x40057c, 5);
+	cp_ctx(ctx, 0x400710, 3);
+	gr_def(ctx, 0x400710, 0x20010001);
+	gr_def(ctx, 0x400714, 0x0f73ef00);
+	cp_ctx(ctx, 0x400724, 1);
+	gr_def(ctx, 0x400724, 0x02008821);
+	cp_ctx(ctx, 0x400770, 3);
+	if (dev_priv->chipset == 0x40) {
+		cp_ctx(ctx, 0x400814, 4);
+		cp_ctx(ctx, 0x400828, 5);
+		cp_ctx(ctx, 0x400840, 5);
+		gr_def(ctx, 0x400850, 0x00000040);
+		cp_ctx(ctx, 0x400858, 4);
+		gr_def(ctx, 0x400858, 0x00000040);
+		gr_def(ctx, 0x40085c, 0x00000040);
+		gr_def(ctx, 0x400864, 0x80000000);
+		cp_ctx(ctx, 0x40086c, 9);
+		gr_def(ctx, 0x40086c, 0x80000000);
+		gr_def(ctx, 0x400870, 0x80000000);
+		gr_def(ctx, 0x400874, 0x80000000);
+		gr_def(ctx, 0x400878, 0x80000000);
+		gr_def(ctx, 0x400888, 0x00000040);
+		gr_def(ctx, 0x40088c, 0x80000000);
+		cp_ctx(ctx, 0x4009c0, 8);
+		gr_def(ctx, 0x4009cc, 0x80000000);
+		gr_def(ctx, 0x4009dc, 0x80000000);
+	} else {
+		cp_ctx(ctx, 0x400840, 20);
+		if (!nv40_graph_4097(ctx->dev)) {
+			for (i = 0; i < 8; i++)
+				gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
+		}
+		gr_def(ctx, 0x400880, 0x00000040);
+		gr_def(ctx, 0x400884, 0x00000040);
+		gr_def(ctx, 0x400888, 0x00000040);
+		cp_ctx(ctx, 0x400894, 11);
+		gr_def(ctx, 0x400894, 0x00000040);
+		if (nv40_graph_4097(ctx->dev)) {
+			for (i = 0; i < 8; i++)
+				gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
+		}
+		cp_ctx(ctx, 0x4008e0, 2);
+		cp_ctx(ctx, 0x4008f8, 2);
+		if (dev_priv->chipset == 0x4c ||
+		    (dev_priv->chipset & 0xf0) == 0x60)
+			cp_ctx(ctx, 0x4009f8, 1);
+	}
+	cp_ctx(ctx, 0x400a00, 73);
+	gr_def(ctx, 0x400b0c, 0x0b0b0b0c);
+	cp_ctx(ctx, 0x401000, 4);
+	cp_ctx(ctx, 0x405004, 1);
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		cp_ctx(ctx, 0x403448, 1);
+		gr_def(ctx, 0x403448, 0x00001010);
+		break;
+	default:
+		cp_ctx(ctx, 0x403440, 1);
+		switch (dev_priv->chipset) {
+		case 0x40:
+			gr_def(ctx, 0x403440, 0x00000010);
+			break;
+		case 0x44:
+		case 0x46:
+		case 0x4a:
+			gr_def(ctx, 0x403440, 0x00003010);
+			break;
+		case 0x41:
+		case 0x42:
+		case 0x43:
+		case 0x4c:
+		case 0x4e:
+		case 0x67:
+		default:
+			gr_def(ctx, 0x403440, 0x00001010);
+			break;
+		}
+		break;
+	}
+}
+
+static void
+nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i;
+
+	if (dev_priv->chipset == 0x40) {
+		cp_ctx(ctx, 0x401880, 51);
+		gr_def(ctx, 0x401940, 0x00000100);
+	} else
+	if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 ||
+	    dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) {
+		cp_ctx(ctx, 0x401880, 32);
+		for (i = 0; i < 16; i++)
+			gr_def(ctx, 0x401880 + (i * 4), 0x00000111);
+		if (dev_priv->chipset == 0x46)
+			cp_ctx(ctx, 0x401900, 16);
+		cp_ctx(ctx, 0x401940, 3);
+	}
+	cp_ctx(ctx, 0x40194c, 18);
+	gr_def(ctx, 0x401954, 0x00000111);
+	gr_def(ctx, 0x401958, 0x00080060);
+	gr_def(ctx, 0x401974, 0x00000080);
+	gr_def(ctx, 0x401978, 0xffff0000);
+	gr_def(ctx, 0x40197c, 0x00000001);
+	gr_def(ctx, 0x401990, 0x46400000);
+	if (dev_priv->chipset == 0x40) {
+		cp_ctx(ctx, 0x4019a0, 2);
+		cp_ctx(ctx, 0x4019ac, 5);
+	} else {
+		cp_ctx(ctx, 0x4019a0, 1);
+		cp_ctx(ctx, 0x4019b4, 3);
+	}
+	gr_def(ctx, 0x4019bc, 0xffff0000);
+	switch (dev_priv->chipset) {
+	case 0x46:
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		cp_ctx(ctx, 0x4019c0, 18);
+		for (i = 0; i < 16; i++)
+			gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888);
+		break;
+	}
+	cp_ctx(ctx, 0x401a08, 8);
+	gr_def(ctx, 0x401a10, 0x0fff0000);
+	gr_def(ctx, 0x401a14, 0x0fff0000);
+	gr_def(ctx, 0x401a1c, 0x00011100);
+	cp_ctx(ctx, 0x401a2c, 4);
+	cp_ctx(ctx, 0x401a44, 26);
+	for (i = 0; i < 16; i++)
+		gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000);
+	gr_def(ctx, 0x401a8c, 0x4b7fffff);
+	if (dev_priv->chipset == 0x40) {
+		cp_ctx(ctx, 0x401ab8, 3);
+	} else {
+		cp_ctx(ctx, 0x401ab8, 1);
+		cp_ctx(ctx, 0x401ac0, 1);
+	}
+	cp_ctx(ctx, 0x401ad0, 8);
+	gr_def(ctx, 0x401ad0, 0x30201000);
+	gr_def(ctx, 0x401ad4, 0x70605040);
+	gr_def(ctx, 0x401ad8, 0xb8a89888);
+	gr_def(ctx, 0x401adc, 0xf8e8d8c8);
+	cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1);
+	gr_def(ctx, 0x401b10, 0x40100000);
+	cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5);
+	gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ?
+			      0x00000004 : 0x00000000);
+	cp_ctx(ctx, 0x401b30, 25);
+	gr_def(ctx, 0x401b34, 0x0000ffff);
+	gr_def(ctx, 0x401b68, 0x435185d6);
+	gr_def(ctx, 0x401b6c, 0x2155b699);
+	gr_def(ctx, 0x401b70, 0xfedcba98);
+	gr_def(ctx, 0x401b74, 0x00000098);
+	gr_def(ctx, 0x401b84, 0xffffffff);
+	gr_def(ctx, 0x401b88, 0x00ff7000);
+	gr_def(ctx, 0x401b8c, 0x0000ffff);
+	if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a &&
+	    dev_priv->chipset != 0x4e)
+		cp_ctx(ctx, 0x401b94, 1);
+	cp_ctx(ctx, 0x401b98, 8);
+	gr_def(ctx, 0x401b9c, 0x00ff0000);
+	cp_ctx(ctx, 0x401bc0, 9);
+	gr_def(ctx, 0x401be0, 0x00ffff00);
+	cp_ctx(ctx, 0x401c00, 192);
+	for (i = 0; i < 16; i++) { /* fragment texture units */
+		gr_def(ctx, 0x401c40 + (i * 4), 0x00018488);
+		gr_def(ctx, 0x401c80 + (i * 4), 0x00028202);
+		gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4);
+		gr_def(ctx, 0x401d40 + (i * 4), 0x01012000);
+		gr_def(ctx, 0x401d80 + (i * 4), 0x00080008);
+		gr_def(ctx, 0x401e00 + (i * 4), 0x00100008);
+	}
+	for (i = 0; i < 4; i++) { /* vertex texture units */
+		gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80);
+		gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202);
+		gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008);
+		gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008);
+	}
+	cp_ctx(ctx, 0x400f5c, 3);
+	gr_def(ctx, 0x400f5c, 0x00000002);
+	cp_ctx(ctx, 0x400f84, 1);
+}
+
+static void
+nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
+{
+	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+	int i;
+
+	cp_ctx(ctx, 0x402000, 1);
+	cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2);
+	switch (dev_priv->chipset) {
+	case 0x40:
+		gr_def(ctx, 0x402404, 0x00000001);
+		break;
+	case 0x4c:
+	case 0x4e:
+	case 0x67:
+		gr_def(ctx, 0x402404, 0x00000020);
+		break;
+	case 0x46:
+	case 0x49:
+	case 0x4b:
+		gr_def(ctx, 0x402404, 0x00000421);
+		break;
+	default:
+		gr_def(ctx, 0x402404, 0x00000021);
+	}
+	if (dev_priv->chipset != 0x40)
+		gr_def(ctx, 0x402408, 0x030c30c3);
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x46:
+	case 0x4a:
+	case 0x4c:
+	case 0x4e:
+	case 0x67:
+		cp_ctx(ctx, 0x402440, 1);
+		gr_def(ctx, 0x402440, 0x00011001);
+		break;
+	default:
+		break;
+	}
+	cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9);
+	gr_def(ctx, 0x402488, 0x3e020200);
+	gr_def(ctx, 0x40248c, 0x00ffffff);
+	switch (dev_priv->chipset) {
+	case 0x40:
+		gr_def(ctx, 0x402490, 0x60103f00);
+		break;
+	case 0x47:
+		gr_def(ctx, 0x402490, 0x40103f00);
+		break;
+	case 0x41:
+	case 0x42:
+	case 0x49:
+	case 0x4b:
+		gr_def(ctx, 0x402490, 0x20103f00);
+		break;
+	default:
+		gr_def(ctx, 0x402490, 0x0c103f00);
+		break;
+	}
+	gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ?
+			      0x00020000 : 0x00040000);
+	cp_ctx(ctx, 0x402500, 31);
+	gr_def(ctx, 0x402530, 0x00008100);
+	if (dev_priv->chipset == 0x40)
+		cp_ctx(ctx, 0x40257c, 6);
+	cp_ctx(ctx, 0x402594, 16);
+	cp_ctx(ctx, 0x402800, 17);
+	gr_def(ctx, 0x402800, 0x00000001);
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		cp_ctx(ctx, 0x402864, 1);
+		gr_def(ctx, 0x402864, 0x00001001);
+		cp_ctx(ctx, 0x402870, 3);
+		gr_def(ctx, 0x402878, 0x00000003);
+		if (dev_priv->chipset != 0x47) { /* belong at end!! */
+			cp_ctx(ctx, 0x402900, 1);
+			cp_ctx(ctx, 0x402940, 1);
+			cp_ctx(ctx, 0x402980, 1);
+			cp_ctx(ctx, 0x4029c0, 1);
+			cp_ctx(ctx, 0x402a00, 1);
+			cp_ctx(ctx, 0x402a40, 1);
+			cp_ctx(ctx, 0x402a80, 1);
+			cp_ctx(ctx, 0x402ac0, 1);
+		}
+		break;
+	case 0x40:
+		cp_ctx(ctx, 0x402844, 1);
+		gr_def(ctx, 0x402844, 0x00000001);
+		cp_ctx(ctx, 0x402850, 1);
+		break;
+	default:
+		cp_ctx(ctx, 0x402844, 1);
+		gr_def(ctx, 0x402844, 0x00001001);
+		cp_ctx(ctx, 0x402850, 2);
+		gr_def(ctx, 0x402854, 0x00000003);
+		break;
+	}
+
+	cp_ctx(ctx, 0x402c00, 4);
+	gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ?
+			      0x80800001 : 0x00888001);
+	switch (dev_priv->chipset) {
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		cp_ctx(ctx, 0x402c20, 40);
+		for (i = 0; i < 32; i++)
+			gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff);
+		cp_ctx(ctx, 0x4030b8, 13);
+		gr_def(ctx, 0x4030dc, 0x00000005);
+		gr_def(ctx, 0x4030e8, 0x0000ffff);
+		break;
+	default:
+		cp_ctx(ctx, 0x402c10, 4);
+		if (dev_priv->chipset == 0x40)
+			cp_ctx(ctx, 0x402c20, 36);
+		else
+		if (dev_priv->chipset <= 0x42)
+			cp_ctx(ctx, 0x402c20, 24);
+		else
+		if (dev_priv->chipset <= 0x4a)
+			cp_ctx(ctx, 0x402c20, 16);
+		else
+			cp_ctx(ctx, 0x402c20, 8);
+		cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13);
+		gr_def(ctx, 0x402cd4, 0x00000005);
+		if (dev_priv->chipset != 0x40)
+			gr_def(ctx, 0x402ce0, 0x0000ffff);
+		break;
+	}
+
+	cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3);
+	cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3);
+	cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev));
+	for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++)
+		gr_def(ctx, 0x403420 + (i * 4), 0x00005555);
+
+	if (dev_priv->chipset != 0x40) {
+		cp_ctx(ctx, 0x403600, 1);
+		gr_def(ctx, 0x403600, 0x00000001);
+	}
+	cp_ctx(ctx, 0x403800, 1);
+
+	cp_ctx(ctx, 0x403c18, 1);
+	gr_def(ctx, 0x403c18, 0x00000001);
+	switch (dev_priv->chipset) {
+	case 0x46:
+	case 0x47:
+	case 0x49:
+	case 0x4b:
+		cp_ctx(ctx, 0x405018, 1);
+		gr_def(ctx, 0x405018, 0x08e00001);
+		cp_ctx(ctx, 0x405c24, 1);
+		gr_def(ctx, 0x405c24, 0x000e3000);
+		break;
+	}
+	if (dev_priv->chipset != 0x4e)
+		cp_ctx(ctx, 0x405800, 11);
+	cp_ctx(ctx, 0x407000, 1);
+}
+
+static void
+nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
+{
+	int len = nv40_graph_4097(ctx->dev) ? 0x0684 : 0x0084;
+
+	cp_out (ctx, 0x300000);
+	cp_lsr (ctx, len - 4);
+	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save);
+	cp_lsr (ctx, len);
+	cp_name(ctx, cp_swap_state3d_3_is_save);
+	cp_out (ctx, 0x800001);
+
+	ctx->ctxvals_pos += len;
+}
+
+static void
+nv40_graph_construct_shader(struct nouveau_grctx *ctx)
+{
+	struct drm_device *dev = ctx->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *obj = ctx->data;
+	int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset;
+	int offset, i;
+
+	vs_nr    = nv40_graph_vs_count(ctx->dev);
+	vs_nr_b0 = 363;
+	vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64;
+	if (dev_priv->chipset == 0x40) {
+		b0_offset = 0x2200/4; /* 33a0 */
+		b1_offset = 0x55a0/4; /* 1500 */
+		vs_len = 0x6aa0/4;
+	} else
+	if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) {
+		b0_offset = 0x2200/4; /* 2200 */
+		b1_offset = 0x4400/4; /* 0b00 */
+		vs_len = 0x4f00/4;
+	} else {
+		b0_offset = 0x1d40/4; /* 2200 */
+		b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
+		vs_len = nv40_graph_4097(dev) ? 0x4a40/4 : 0x4980/4;
+	}
+
+	cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
+	cp_out(ctx, nv40_graph_4097(dev) ? 0x800041 : 0x800029);
+
+	offset = ctx->ctxvals_pos;
+	ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
+
+	if (ctx->mode != NOUVEAU_GRCTX_VALS)
+		return;
+
+	offset += 0x0280/4;
+	for (i = 0; i < 16; i++, offset += 2)
+		nv_wo32(dev, obj, offset, 0x3f800000);
+
+	for (vs = 0; vs < vs_nr; vs++, offset += vs_len) {
+		for (i = 0; i < vs_nr_b0 * 6; i += 6)
+			nv_wo32(dev, obj, offset + b0_offset + i, 0x00000001);
+		for (i = 0; i < vs_nr_b1 * 4; i += 4)
+			nv_wo32(dev, obj, offset + b1_offset + i, 0x3f800000);
+	}
+}
+
+void
+nv40_grctx_init(struct nouveau_grctx *ctx)
+{
+	/* decide whether we're loading/unloading the context */
+	cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
+	cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);
+
+	cp_name(ctx, cp_check_load);
+	cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
+	cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
+	cp_bra (ctx, ALWAYS, TRUE, cp_exit);
+
+	/* setup for context load */
+	cp_name(ctx, cp_setup_auto_load);
+	cp_wait(ctx, STATUS, IDLE);
+	cp_out (ctx, CP_NEXT_TO_SWAP);
+	cp_name(ctx, cp_setup_load);
+	cp_wait(ctx, STATUS, IDLE);
+	cp_set (ctx, SWAP_DIRECTION, LOAD);
+	cp_out (ctx, 0x00910880); /* ?? */
+	cp_out (ctx, 0x00901ffe); /* ?? */
+	cp_out (ctx, 0x01940000); /* ?? */
+	cp_lsr (ctx, 0x20);
+	cp_out (ctx, 0x0060000b); /* ?? */
+	cp_wait(ctx, UNK57, CLEAR);
+	cp_out (ctx, 0x0060000c); /* ?? */
+	cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);
+
+	/* setup for context save */
+	cp_name(ctx, cp_setup_save);
+	cp_set (ctx, SWAP_DIRECTION, SAVE);
+
+	/* general PGRAPH state */
+	cp_name(ctx, cp_swap_state);
+	cp_pos (ctx, 0x00020/4);
+	nv40_graph_construct_general(ctx);
+	cp_wait(ctx, STATUS, IDLE);
+
+	/* 3D state, block 1 */
+	cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
+	nv40_graph_construct_state3d(ctx);
+	cp_wait(ctx, STATUS, IDLE);
+
+	/* 3D state, block 2 */
+	nv40_graph_construct_state3d_2(ctx);
+
+	/* Some other block of "random" state */
+	nv40_graph_construct_state3d_3(ctx);
+
+	/* Per-vertex shader state */
+	cp_pos (ctx, ctx->ctxvals_pos);
+	nv40_graph_construct_shader(ctx);
+
+	/* pre-exit state updates */
+	cp_name(ctx, cp_prepare_exit);
+	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
+	cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
+	cp_out (ctx, CP_NEXT_TO_CURRENT);
+
+	cp_name(ctx, cp_exit);
+	cp_set (ctx, USER_SAVE, NOT_PENDING);
+	cp_set (ctx, USER_LOAD, NOT_PENDING);
+	cp_out (ctx, CP_END);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_mc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_mc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv40_mc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv40_mc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,38 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_mc_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	/* Power up everything, resetting each individual unit will
+	 * be done later if needed.
+	 */
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4e:
+	case 0x4c: /* C51_G7X */
+		tmp = nv_rd32(dev, NV40_PFB_020C);
+		nv_wr32(dev, NV40_PMC_1700, tmp);
+		nv_wr32(dev, NV40_PMC_1704, 0);
+		nv_wr32(dev, NV40_PMC_1708, 0);
+		nv_wr32(dev, NV40_PMC_170C, tmp);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void
+nv40_mc_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_crtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,792 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_mode.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+#include "nouveau_encoder.h"
+#include "nouveau_crtc.h"
+#include "nouveau_fb.h"
+#include "nouveau_connector.h"
+#include "nv50_display.h"
+
+static void
+nv50_crtc_lut_load(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
+	int i;
+
+	NV_DEBUG_KMS(crtc->dev, "\n");
+
+	for (i = 0; i < 256; i++) {
+		writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
+		writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2);
+		writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4);
+	}
+
+	if (nv_crtc->lut.depth == 30) {
+		writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0);
+		writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2);
+		writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4);
+	}
+}
+
+int
+nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int index = nv_crtc->index, ret;
+
+	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+	NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked");
+
+	if (blanked) {
+		nv_crtc->cursor.hide(nv_crtc, false);
+
+		ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5);
+		if (ret) {
+			NV_ERROR(dev, "no space while blanking crtc\n");
+			return ret;
+		}
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
+		OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK);
+		OUT_RING(evo, 0);
+		if (dev_priv->chipset != 0x50) {
+			BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
+			OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE);
+		}
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
+		OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
+	} else {
+		if (nv_crtc->cursor.visible)
+			nv_crtc->cursor.show(nv_crtc, false);
+		else
+			nv_crtc->cursor.hide(nv_crtc, false);
+
+		ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8);
+		if (ret) {
+			NV_ERROR(dev, "no space while unblanking crtc\n");
+			return ret;
+		}
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
+		OUT_RING(evo, nv_crtc->lut.depth == 8 ?
+				NV50_EVO_CRTC_CLUT_MODE_OFF :
+				NV50_EVO_CRTC_CLUT_MODE_ON);
+		OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.mm_node->start <<
+				 PAGE_SHIFT) >> 8);
+		if (dev_priv->chipset != 0x50) {
+			BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
+			OUT_RING(evo, NvEvoVRAM);
+		}
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2);
+		OUT_RING(evo, nv_crtc->fb.offset >> 8);
+		OUT_RING(evo, 0);
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
+		if (dev_priv->chipset != 0x50)
+			if (nv_crtc->fb.tile_flags == 0x7a00)
+				OUT_RING(evo, NvEvoFB32);
+			else
+			if (nv_crtc->fb.tile_flags == 0x7000)
+				OUT_RING(evo, NvEvoFB16);
+			else
+				OUT_RING(evo, NvEvoVRAM);
+		else
+			OUT_RING(evo, NvEvoVRAM);
+	}
+
+	nv_crtc->fb.blanked = blanked;
+	return 0;
+}
+
+static int
+nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	ret = RING_SPACE(evo, 2 + (update ? 2 : 0));
+	if (ret) {
+		NV_ERROR(dev, "no space while setting dither\n");
+		return ret;
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DITHER_CTRL), 1);
+	if (on)
+		OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_ON);
+	else
+		OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_OFF);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+struct nouveau_connector *
+nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_connector *connector;
+	struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
+
+	/* The safest approach is to find an encoder with the right crtc, that
+	 * is also linked to a connector. */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder)
+			if (connector->encoder->crtc == crtc)
+				return nouveau_connector(connector);
+	}
+
+	return NULL;
+}
+
+static int
+nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
+{
+	struct nouveau_connector *nv_connector =
+		nouveau_crtc_connector_get(nv_crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_display_mode *native_mode = NULL;
+	struct drm_display_mode *mode = &nv_crtc->base.mode;
+	uint32_t outX, outY, horiz, vert;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	switch (scaling_mode) {
+	case DRM_MODE_SCALE_NONE:
+		break;
+	default:
+		if (!nv_connector || !nv_connector->native_mode) {
+			NV_ERROR(dev, "No native mode, forcing panel scaling\n");
+			scaling_mode = DRM_MODE_SCALE_NONE;
+		} else {
+			native_mode = nv_connector->native_mode;
+		}
+		break;
+	}
+
+	switch (scaling_mode) {
+	case DRM_MODE_SCALE_ASPECT:
+		horiz = (native_mode->hdisplay << 19) / mode->hdisplay;
+		vert = (native_mode->vdisplay << 19) / mode->vdisplay;
+
+		if (vert > horiz) {
+			outX = (mode->hdisplay * horiz) >> 19;
+			outY = (mode->vdisplay * horiz) >> 19;
+		} else {
+			outX = (mode->hdisplay * vert) >> 19;
+			outY = (mode->vdisplay * vert) >> 19;
+		}
+		break;
+	case DRM_MODE_SCALE_FULLSCREEN:
+		outX = native_mode->hdisplay;
+		outY = native_mode->vdisplay;
+		break;
+	case DRM_MODE_SCALE_CENTER:
+	case DRM_MODE_SCALE_NONE:
+	default:
+		outX = mode->hdisplay;
+		outY = mode->vdisplay;
+		break;
+	}
+
+	ret = RING_SPACE(evo, update ? 7 : 5);
+	if (ret)
+		return ret;
+
+	/* Got a better name for SCALER_ACTIVE? */
+	/* One day i've got to really figure out why this is needed. */
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1);
+	if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ||
+	    (mode->flags & DRM_MODE_FLAG_INTERLACE) ||
+	    mode->hdisplay != outX || mode->vdisplay != outY) {
+		OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_ACTIVE);
+	} else {
+		OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_INACTIVE);
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2);
+	OUT_RING(evo, outY << 16 | outX);
+	OUT_RING(evo, outY << 16 | outX);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+int
+nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
+{
+	uint32_t pll_reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head);
+	struct nouveau_pll_vals pll;
+	struct pll_lims limits;
+	uint32_t reg1, reg2;
+	int ret;
+
+	ret = get_pll_limits(dev, pll_reg, &limits);
+	if (ret)
+		return ret;
+
+	ret = nouveau_calc_pll_mnp(dev, &limits, pclk, &pll);
+	if (ret <= 0)
+		return ret;
+
+	if (limits.vco2.maxfreq) {
+		reg1 = nv_rd32(dev, pll_reg + 4) & 0xff00ff00;
+		reg2 = nv_rd32(dev, pll_reg + 8) & 0x8000ff00;
+		nv_wr32(dev, pll_reg, 0x10000611);
+		nv_wr32(dev, pll_reg + 4, reg1 | (pll.M1 << 16) | pll.N1);
+		nv_wr32(dev, pll_reg + 8,
+			reg2 | (pll.log2P << 28) | (pll.M2 << 16) | pll.N2);
+	} else {
+		reg1 = nv_rd32(dev, pll_reg + 4) & 0xffc00000;
+		nv_wr32(dev, pll_reg, 0x50000610);
+		nv_wr32(dev, pll_reg + 4, reg1 |
+			(pll.log2P << 16) | (pll.M1 << 8) | pll.N1);
+	}
+
+	return 0;
+}
+
+static void
+nv50_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct drm_device *dev;
+	struct nouveau_crtc *nv_crtc;
+
+	if (!crtc)
+		return;
+
+	dev = crtc->dev;
+	nv_crtc = nouveau_crtc(crtc);
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	drm_crtc_cleanup(&nv_crtc->base);
+
+	nv50_cursor_fini(nv_crtc);
+
+	nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	kfree(nv_crtc->mode);
+	kfree(nv_crtc);
+}
+
+int
+nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+		     uint32_t buffer_handle, uint32_t width, uint32_t height)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_bo *cursor = NULL;
+	struct drm_gem_object *gem;
+	int ret = 0, i;
+
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
+	if (!buffer_handle) {
+		nv_crtc->cursor.hide(nv_crtc, true);
+		return 0;
+	}
+
+	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
+	if (!gem)
+		return -EINVAL;
+	cursor = nouveau_gem_object(gem);
+
+	ret = nouveau_bo_map(cursor);
+	if (ret)
+		goto out;
+
+	/* The simple will do for now. */
+	for (i = 0; i < 64 * 64; i++)
+		nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i));
+
+	nouveau_bo_unmap(cursor);
+
+	nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset -
+					    dev_priv->vm_vram_base);
+	nv_crtc->cursor.show(nv_crtc, true);
+
+out:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(gem);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+int
+nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+	nv_crtc->cursor.set_pos(nv_crtc, x, y);
+	return 0;
+}
+
+static void
+nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
+		    uint32_t size)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int i;
+
+	if (size != 256)
+		return;
+
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = r[i];
+		nv_crtc->lut.g[i] = g[i];
+		nv_crtc->lut.b[i] = b[i];
+	}
+
+	/* We need to know the depth before we upload, but it's possible to
+	 * get called before a framebuffer is bound.  If this is the case,
+	 * mark the lut values as dirty by setting depth==0, and it'll be
+	 * uploaded on the first mode_set_base()
+	 */
+	if (!nv_crtc->base.fb) {
+		nv_crtc->lut.depth = 0;
+		return;
+	}
+
+	nv50_crtc_lut_load(crtc);
+}
+
+static void
+nv50_crtc_save(struct drm_crtc *crtc)
+{
+	NV_ERROR(crtc->dev, "!!\n");
+}
+
+static void
+nv50_crtc_restore(struct drm_crtc *crtc)
+{
+	NV_ERROR(crtc->dev, "!!\n");
+}
+
+static const struct drm_crtc_funcs nv50_crtc_funcs = {
+	.save = nv50_crtc_save,
+	.restore = nv50_crtc_restore,
+	.cursor_set = nv50_crtc_cursor_set,
+	.cursor_move = nv50_crtc_cursor_move,
+	.gamma_set = nv50_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = nv50_crtc_destroy,
+};
+
+static void
+nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+}
+
+static void
+nv50_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_encoder *encoder;
+	uint32_t dac = 0, sor = 0;
+
+	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+
+	/* Disconnect all unused encoders. */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (!drm_helper_encoder_in_use(encoder))
+			continue;
+
+		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
+		    nv_encoder->dcb->type == OUTPUT_TV)
+			dac |= (1 << nv_encoder->or);
+		else
+			sor |= (1 << nv_encoder->or);
+	}
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
+		    nv_encoder->dcb->type == OUTPUT_TV) {
+			if (dac & (1 << nv_encoder->or))
+				continue;
+		} else {
+			if (sor & (1 << nv_encoder->or))
+				continue;
+		}
+
+		nv_encoder->disconnect(nv_encoder);
+	}
+
+	nv50_crtc_blank(nv_crtc, true);
+}
+
+static void
+nv50_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc *crtc2;
+	struct drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int ret;
+
+	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+
+	nv50_crtc_blank(nv_crtc, false);
+
+	/* Explicitly blank all unused crtc's. */
+	list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
+		if (!drm_helper_crtc_in_use(crtc2))
+			nv50_crtc_blank(nouveau_crtc(crtc2), true);
+	}
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while committing crtc\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+	OUT_RING(evo, 0);
+	FIRE_RING(evo);
+}
+
+static bool
+nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
+		     struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static int
+nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			   struct drm_framebuffer *old_fb, bool update)
+{
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct drm_device *dev = nv_crtc->base.dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
+	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
+	int ret, format;
+
+	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+
+	switch (drm_fb->depth) {
+	case  8:
+		format = NV50_EVO_CRTC_FB_DEPTH_8;
+		break;
+	case 15:
+		format = NV50_EVO_CRTC_FB_DEPTH_15;
+		break;
+	case 16:
+		format = NV50_EVO_CRTC_FB_DEPTH_16;
+		break;
+	case 24:
+	case 32:
+		format = NV50_EVO_CRTC_FB_DEPTH_24;
+		break;
+	case 30:
+		format = NV50_EVO_CRTC_FB_DEPTH_30;
+		break;
+	default:
+		 NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
+		 return -EINVAL;
+	}
+
+	ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		return ret;
+
+	if (old_fb) {
+		struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
+		nouveau_bo_unpin(ofb->nvbo);
+	}
+
+	nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
+	nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
+	nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
+	if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
+		ret = RING_SPACE(evo, 2);
+		if (ret)
+			return ret;
+
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
+		if (nv_crtc->fb.tile_flags == 0x7a00)
+			OUT_RING(evo, NvEvoFB32);
+		else
+		if (nv_crtc->fb.tile_flags == 0x7000)
+			OUT_RING(evo, NvEvoFB16);
+		else
+			OUT_RING(evo, NvEvoVRAM);
+	}
+
+	ret = RING_SPACE(evo, 12);
+	if (ret)
+		return ret;
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
+	OUT_RING(evo, nv_crtc->fb.offset >> 8);
+	OUT_RING(evo, 0);
+	OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width);
+	if (!nv_crtc->fb.tile_flags) {
+		OUT_RING(evo, drm_fb->pitch | (1 << 20));
+	} else {
+		OUT_RING(evo, ((drm_fb->pitch / 4) << 4) |
+				  fb->nvbo->tile_mode);
+	}
+	if (dev_priv->chipset == 0x50)
+		OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format);
+	else
+		OUT_RING(evo, format);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
+	OUT_RING(evo, fb->base.depth == 8 ?
+		 NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
+	OUT_RING(evo, (y << 16) | x);
+
+	if (nv_crtc->lut.depth != fb->base.depth) {
+		nv_crtc->lut.depth = fb->base.depth;
+		nv50_crtc_lut_load(crtc);
+	}
+
+	if (update) {
+		ret = RING_SPACE(evo, 2);
+		if (ret)
+			return ret;
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+	}
+
+	return 0;
+}
+
+static int
+nv50_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 drm_device *dev = crtc->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nouveau_connector *nv_connector = NULL;
+	uint32_t hsync_dur,  vsync_dur, hsync_start_to_end, vsync_start_to_end;
+	uint32_t hunk1, vunk1, vunk2a, vunk2b;
+	int ret;
+
+	/* Find the connector attached to this CRTC */
+	nv_connector = nouveau_crtc_connector_get(nv_crtc);
+
+	*nv_crtc->mode = *adjusted_mode;
+
+	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+
+	hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
+	vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
+	hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start;
+	vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start;
+	/* I can't give this a proper name, anyone else can? */
+	hunk1 = adjusted_mode->htotal -
+		adjusted_mode->hsync_start + adjusted_mode->hdisplay;
+	vunk1 = adjusted_mode->vtotal -
+		adjusted_mode->vsync_start + adjusted_mode->vdisplay;
+	/* Another strange value, this time only for interlaced adjusted_modes. */
+	vunk2a = 2 * adjusted_mode->vtotal -
+		 adjusted_mode->vsync_start + adjusted_mode->vdisplay;
+	vunk2b = adjusted_mode->vtotal -
+		 adjusted_mode->vsync_start + adjusted_mode->vtotal;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		vsync_dur /= 2;
+		vsync_start_to_end  /= 2;
+		vunk1 /= 2;
+		vunk2a /= 2;
+		vunk2b /= 2;
+		/* magic */
+		if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+			vsync_start_to_end -= 1;
+			vunk1 -= 1;
+			vunk2a -= 1;
+			vunk2b -= 1;
+		}
+	}
+
+	ret = RING_SPACE(evo, 17);
+	if (ret)
+		return ret;
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLOCK), 2);
+	OUT_RING(evo, adjusted_mode->clock | 0x800000);
+	OUT_RING(evo, (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0);
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DISPLAY_START), 5);
+	OUT_RING(evo, 0);
+	OUT_RING(evo, (adjusted_mode->vtotal << 16) | adjusted_mode->htotal);
+	OUT_RING(evo, (vsync_dur - 1) << 16 | (hsync_dur - 1));
+	OUT_RING(evo, (vsync_start_to_end - 1) << 16 |
+			(hsync_start_to_end - 1));
+	OUT_RING(evo, (vunk1 - 1) << 16 | (hunk1 - 1));
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK0824), 1);
+		OUT_RING(evo, (vunk2b - 1) << 16 | (vunk2a - 1));
+	} else {
+		OUT_RING(evo, 0);
+		OUT_RING(evo, 0);
+	}
+
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK082C), 1);
+	OUT_RING(evo, 0);
+
+	/* This is the actual resolution of the mode. */
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, REAL_RES), 1);
+	OUT_RING(evo, (mode->vdisplay << 16) | mode->hdisplay);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CENTER_OFFSET), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(0, 0));
+
+	nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
+	nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
+
+	return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+}
+
+static int
+nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb)
+{
+	return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+}
+
+static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
+	.dpms = nv50_crtc_dpms,
+	.prepare = nv50_crtc_prepare,
+	.commit = nv50_crtc_commit,
+	.mode_fixup = nv50_crtc_mode_fixup,
+	.mode_set = nv50_crtc_mode_set,
+	.mode_set_base = nv50_crtc_mode_set_base,
+	.load_lut = nv50_crtc_lut_load,
+};
+
+int
+nv50_crtc_create(struct drm_device *dev, int index)
+{
+	struct nouveau_crtc *nv_crtc = NULL;
+	int ret, i;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
+	if (!nv_crtc)
+		return -ENOMEM;
+
+	nv_crtc->mode = kzalloc(sizeof(*nv_crtc->mode), GFP_KERNEL);
+	if (!nv_crtc->mode) {
+		kfree(nv_crtc);
+		return -ENOMEM;
+	}
+
+	/* Default CLUT parameters, will be activated on the hw upon
+	 * first mode set.
+	 */
+	for (i = 0; i < 256; i++) {
+		nv_crtc->lut.r[i] = i << 8;
+		nv_crtc->lut.g[i] = i << 8;
+		nv_crtc->lut.b[i] = i << 8;
+	}
+	nv_crtc->lut.depth = 0;
+
+	ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->lut.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->lut.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+	}
+
+	if (ret) {
+		kfree(nv_crtc->mode);
+		kfree(nv_crtc);
+		return ret;
+	}
+
+	nv_crtc->index = index;
+
+	/* set function pointers */
+	nv_crtc->set_dither = nv50_crtc_set_dither;
+	nv_crtc->set_scale = nv50_crtc_set_scale;
+
+	drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs);
+	drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs);
+	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
+
+	ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
+			     0, 0x0000, false, true, &nv_crtc->cursor.nvbo);
+	if (!ret) {
+		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+		if (!ret)
+			ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+		if (ret)
+			nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+	}
+
+	nv50_cursor_init(nv_crtc);
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_cursor.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_cursor.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_cursor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_cursor.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_mode.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
+{
+	struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_device *dev = nv_crtc->base.dev;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	if (update && nv_crtc->cursor.visible)
+		return;
+
+	ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while unhiding cursor\n");
+		return;
+	}
+
+	if (dev_priv->chipset != 0x50) {
+		BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
+		OUT_RING(evo, NvEvoVRAM);
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2);
+	OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_SHOW);
+	OUT_RING(evo, nv_crtc->cursor.offset >> 8);
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+		nv_crtc->cursor.visible = true;
+	}
+}
+
+static void
+nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
+{
+	struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_device *dev = nv_crtc->base.dev;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	if (update && !nv_crtc->cursor.visible)
+		return;
+
+	ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while hiding cursor\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2);
+	OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE);
+	OUT_RING(evo, 0);
+	if (dev_priv->chipset != 0x50) {
+		BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
+		OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE);
+	}
+
+	if (update) {
+		BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(evo, 0);
+		FIRE_RING(evo);
+		nv_crtc->cursor.visible = false;
+	}
+}
+
+static void
+nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
+		((y & 0xFFFF) << 16) | (x & 0xFFFF));
+	/* Needed to make the cursor move. */
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc->index), 0);
+}
+
+static void
+nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
+{
+	NV_DEBUG_KMS(nv_crtc->base.dev, "\n");
+	if (offset == nv_crtc->cursor.offset)
+		return;
+
+	nv_crtc->cursor.offset = offset;
+	if (nv_crtc->cursor.visible) {
+		nv_crtc->cursor.visible = false;
+		nv_crtc->cursor.show(nv_crtc, true);
+	}
+}
+
+int
+nv50_cursor_init(struct nouveau_crtc *nv_crtc)
+{
+	nv_crtc->cursor.set_offset = nv50_cursor_set_offset;
+	nv_crtc->cursor.set_pos = nv50_cursor_set_pos;
+	nv_crtc->cursor.hide = nv50_cursor_hide;
+	nv_crtc->cursor.show = nv50_cursor_show;
+	return 0;
+}
+
+void
+nv50_cursor_fini(struct nouveau_crtc *nv_crtc)
+{
+	struct drm_device *dev = nv_crtc->base.dev;
+	int idx = nv_crtc->index;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0);
+	if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx),
+		     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
+		NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+		NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
+			 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx)));
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_dac.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
+{
+	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while disconnecting DAC\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, 0);
+}
+
+static enum drm_connector_status
+nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	enum drm_connector_status status = connector_status_disconnected;
+	uint32_t dpms_state, load_pattern, load_state;
+	int or = nv_encoder->or;
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001);
+	dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or));
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+	if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		     NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+			  nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+		return status;
+	}
+
+	/* Use bios provided value if possible. */
+	if (dev_priv->vbios->dactestval) {
+		load_pattern = dev_priv->vbios->dactestval;
+		NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n",
+			  load_pattern);
+	} else {
+		load_pattern = 340;
+		NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n",
+			 load_pattern);
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or),
+		NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern);
+	mdelay(45); /* give it some time to process */
+	load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or));
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0);
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state |
+		NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+
+	if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) ==
+			  NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT)
+		status = connector_status_connected;
+
+	if (status == connector_status_connected)
+		NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or);
+	else
+		NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or);
+
+	return status;
+}
+
+static void
+nv50_dac_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	uint32_t val;
+	int or = nv_encoder->or;
+
+	NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
+
+	/* wait for it to be done */
+	if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+		     NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+		return;
+	}
+
+	val = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F;
+
+	if (mode != DRM_MODE_DPMS_ON)
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED;
+
+	switch (mode) {
+	case DRM_MODE_DPMS_STANDBY:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF;
+		break;
+	case DRM_MODE_DPMS_SUSPEND:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF;
+		break;
+	case DRM_MODE_DPMS_OFF:
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_OFF;
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF;
+		val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF;
+		break;
+	default:
+		break;
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val |
+		NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+}
+
+static void
+nv50_dac_save(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static void
+nv50_dac_restore(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static bool
+nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		    struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *connector;
+
+	NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or);
+
+	connector = nouveau_encoder_connector_get(nv_encoder);
+	if (!connector) {
+		NV_ERROR(encoder->dev, "Encoder has no connector\n");
+		return false;
+	}
+
+	if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
+	     connector->native_mode) {
+		int id = adjusted_mode->base.id;
+		*adjusted_mode = *connector->native_mode;
+		adjusted_mode->base.id = id;
+	}
+
+	return true;
+}
+
+static void
+nv50_dac_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_dac_commit(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		  struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
+	uint32_t mode_ctl = 0, mode_ctl2 = 0;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
+
+	nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
+
+	if (crtc->index == 1)
+		mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC1;
+	else
+		mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC0;
+
+	/* Lacking a working tv-out, this is not a 100% sure. */
+	if (nv_encoder->dcb->type == OUTPUT_ANALOG)
+		mode_ctl |= 0x40;
+	else
+	if (nv_encoder->dcb->type == OUTPUT_TV)
+		mode_ctl |= 0x100;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+		mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NHSYNC;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+		mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NVSYNC;
+
+	ret = RING_SPACE(evo, 3);
+	if (ret) {
+		NV_ERROR(dev, "no space while connecting DAC\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
+	OUT_RING(evo, mode_ctl);
+	OUT_RING(evo, mode_ctl2);
+}
+
+static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
+	.dpms = nv50_dac_dpms,
+	.save = nv50_dac_save,
+	.restore = nv50_dac_restore,
+	.mode_fixup = nv50_dac_mode_fixup,
+	.prepare = nv50_dac_prepare,
+	.commit = nv50_dac_commit,
+	.mode_set = nv50_dac_mode_set,
+	.detect = nv50_dac_detect
+};
+
+static void
+nv50_dac_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (!encoder)
+		return;
+
+	NV_DEBUG_KMS(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
+	.destroy = nv50_dac_destroy,
+};
+
+int
+nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder;
+	struct drm_encoder *encoder;
+
+	NV_DEBUG_KMS(dev, "\n");
+	NV_INFO(dev, "Detected a DAC output\n");
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	nv_encoder->disconnect = nv50_dac_disconnect;
+
+	drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs,
+			 DRM_MODE_ENCODER_DAC);
+	drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_display.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_display.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "nv50_display.h"
+#include "nouveau_crtc.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_fb.h"
+#include "drm_crtc_helper.h"
+
+static void
+nv50_evo_channel_del(struct nouveau_channel **pchan)
+{
+	struct nouveau_channel *chan = *pchan;
+
+	if (!chan)
+		return;
+	*pchan = NULL;
+
+	nouveau_gpuobj_channel_takedown(chan);
+	nouveau_bo_ref(NULL, &chan->pushbuf_bo);
+
+	if (chan->user)
+		iounmap(chan->user);
+
+	kfree(chan);
+}
+
+static int
+nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
+		    uint32_t tile_flags, uint32_t magic_flags,
+		    uint32_t offset, uint32_t limit)
+{
+	struct drm_nouveau_private *dev_priv = evo->dev->dev_private;
+	struct drm_device *dev = evo->dev;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj);
+	if (ret)
+		return ret;
+	obj->engine = NVOBJ_ENGINE_DISPLAY;
+
+	ret = nouveau_gpuobj_ref_add(dev, evo, name, obj, NULL);
+	if (ret) {
+		nouveau_gpuobj_del(dev, &obj);
+		return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
+	nv_wo32(dev, obj, 1, limit);
+	nv_wo32(dev, obj, 2, offset);
+	nv_wo32(dev, obj, 3, 0x00000000);
+	nv_wo32(dev, obj, 4, 0x00000000);
+	nv_wo32(dev, obj, 5, 0x00010000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	return 0;
+}
+
+static int
+nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	int ret;
+
+	chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+	*pchan = chan;
+
+	chan->id = -1;
+	chan->dev = dev;
+	chan->user_get = 4;
+	chan->user_put = 0;
+
+	INIT_LIST_HEAD(&chan->ramht_refs);
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32768, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin);
+	if (ret) {
+		NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj->
+				    im_pramin->start, 32768);
+	if (ret) {
+		NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 4096, 16,
+				     0, &chan->ramht);
+	if (ret) {
+		NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	if (dev_priv->chipset != 0x50) {
+		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19,
+					  0, 0xffffffff);
+		if (ret) {
+			nv50_evo_channel_del(pchan);
+			return ret;
+		}
+
+
+		ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19,
+					  0, 0xffffffff);
+		if (ret) {
+			nv50_evo_channel_del(pchan);
+			return ret;
+		}
+	}
+
+	ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
+				  0, nouveau_mem_fb_amount(dev));
+	if (ret) {
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0,
+			     false, true, &chan->pushbuf_bo);
+	if (ret == 0)
+		ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	ret = nouveau_bo_map(chan->pushbuf_bo);
+	if (ret) {
+		NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret);
+		nv50_evo_channel_del(pchan);
+		return ret;
+	}
+
+	chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
+					NV50_PDISPLAY_USER(0), PAGE_SIZE);
+	if (!chan->user) {
+		NV_ERROR(dev, "Error mapping EVO control regs.\n");
+		nv50_evo_channel_del(pchan);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int
+nv50_display_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct drm_connector *connector;
+	uint32_t val, ram_amount, hpd_en[2];
+	uint64_t start;
+	int ret, i;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004));
+	/*
+	 * I think the 0x006101XX range is some kind of main control area
+	 * that enables things.
+	 */
+	/* CRTC? */
+	for (i = 0; i < 2; i++) {
+		val = nv_rd32(dev, 0x00616100 + (i * 0x800));
+		nv_wr32(dev, 0x00610190 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x00616104 + (i * 0x800));
+		nv_wr32(dev, 0x00610194 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x00616108 + (i * 0x800));
+		nv_wr32(dev, 0x00610198 + (i * 0x10), val);
+		val = nv_rd32(dev, 0x0061610c + (i * 0x800));
+		nv_wr32(dev, 0x0061019c + (i * 0x10), val);
+	}
+	/* DAC */
+	for (i = 0; i < 3; i++) {
+		val = nv_rd32(dev, 0x0061a000 + (i * 0x800));
+		nv_wr32(dev, 0x006101d0 + (i * 0x04), val);
+	}
+	/* SOR */
+	for (i = 0; i < 4; i++) {
+		val = nv_rd32(dev, 0x0061c000 + (i * 0x800));
+		nv_wr32(dev, 0x006101e0 + (i * 0x04), val);
+	}
+	/* Something not yet in use, tv-out maybe. */
+	for (i = 0; i < 3; i++) {
+		val = nv_rd32(dev, 0x0061e000 + (i * 0x800));
+		nv_wr32(dev, 0x006101f0 + (i * 0x04), val);
+	}
+
+	for (i = 0; i < 3; i++) {
+		nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
+			NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
+		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
+	}
+
+	/* This used to be in crtc unblank, but seems out of place there. */
+	nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
+	/* RAM is clamped to 256 MiB. */
+	ram_amount = nouveau_mem_fb_amount(dev);
+	NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
+	if (ram_amount > 256*1024*1024)
+		ram_amount = 256*1024*1024;
+	nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1);
+	nv_wr32(dev, NV50_PDISPLAY_UNK_388, 0x150000);
+	nv_wr32(dev, NV50_PDISPLAY_UNK_38C, 0);
+
+	/* The precise purpose is unknown, i suspect it has something to do
+	 * with text mode.
+	 */
+	if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) {
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100);
+		nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1);
+		if (!nv_wait(0x006194e8, 2, 0)) {
+			NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n");
+			NV_ERROR(dev, "0x6194e8 = 0x%08x\n",
+						nv_rd32(dev, 0x6194e8));
+			return -EBUSY;
+		}
+	}
+
+	/* taken from nv bug #12637, attempts to un-wedge the hw if it's
+	 * stuck in some unspecified state
+	 */
+	start = ptimer->read(dev);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x2b00);
+	while ((val = nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))) & 0x1e0000) {
+		if ((val & 0x9f0000) == 0x20000)
+			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+							val | 0x800000);
+
+		if ((val & 0x3f0000) == 0x30000)
+			nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+							val | 0x200000);
+
+		if (ptimer->read(dev) - start > 1000000000ULL) {
+			NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n");
+			NV_ERROR(dev, "0x610200 = 0x%08x\n", val);
+			return -EBUSY;
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03);
+	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n",
+			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
+		return -EBUSY;
+	}
+
+	for (i = 0; i < 2; i++) {
+		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
+		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
+			NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+			NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
+				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+			return -EBUSY;
+		}
+
+		nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
+		if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
+			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
+			NV_ERROR(dev, "timeout: "
+				      "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
+			NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
+				 nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+			return -EBUSY;
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->instance >> 8) | 9);
+
+	/* initialise fifo */
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0),
+		((evo->pushbuf_bo->bo.mem.mm_node->start << PAGE_SHIFT) >> 8) |
+		NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM |
+		NV50_PDISPLAY_CHANNEL_DMA_CB_VALID);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002);
+	if (!nv_wait(0x610200, 0x80000000, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200));
+		return -EBUSY;
+	}
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0),
+		(nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)) & ~0x00000003) |
+		 NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
+	nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0);
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 |
+		NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED);
+	nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1);
+
+	evo->dma.max = (4096/4) - 2;
+	evo->dma.put = 0;
+	evo->dma.cur = evo->dma.put;
+	evo->dma.free = evo->dma.max - evo->dma.cur;
+
+	ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+		OUT_RING(evo, 0);
+
+	ret = RING_SPACE(evo, 11);
+	if (ret)
+		return ret;
+	BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2);
+	OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
+	OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1);
+	OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1);
+	OUT_RING(evo, 0);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, DISPLAY_START), 1);
+	OUT_RING(evo, 0);
+	BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1);
+	OUT_RING(evo, 0);
+	FIRE_RING(evo);
+	if (!nv_wait(0x640004, 0xffffffff, evo->dma.put << 2))
+		NV_ERROR(dev, "evo pushbuf stalled\n");
+
+	/* enable clock change interrupts. */
+	nv_wr32(dev, 0x610028, 0x00010001);
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 |
+					     NV50_PDISPLAY_INTR_EN_CLK_UNK20 |
+					     NV50_PDISPLAY_INTR_EN_CLK_UNK40));
+
+	/* enable hotplug interrupts */
+	hpd_en[0] = hpd_en[1] = 0;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct nouveau_connector *conn = nouveau_connector(connector);
+		struct dcb_gpio_entry *gpio;
+
+		if (connector->connector_type != DRM_MODE_CONNECTOR_DVII &&
+		    connector->connector_type != DRM_MODE_CONNECTOR_DVID &&
+		    connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+			continue;
+
+		gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
+		if (!gpio)
+			continue;
+
+		hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf));
+	}
+
+	nv_wr32(dev, 0xe054, 0xffffffff);
+	nv_wr32(dev, 0xe050, hpd_en[0]);
+	if (dev_priv->chipset >= 0x90) {
+		nv_wr32(dev, 0xe074, 0xffffffff);
+		nv_wr32(dev, 0xe070, hpd_en[1]);
+	}
+
+	return 0;
+}
+
+static int nv50_display_disable(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_crtc *drm_crtc;
+	int ret, i;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
+
+		nv50_crtc_blank(crtc, true);
+	}
+
+	ret = RING_SPACE(dev_priv->evo, 2);
+	if (ret == 0) {
+		BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1);
+		OUT_RING(dev_priv->evo, 0);
+	}
+	FIRE_RING(dev_priv->evo);
+
+	/* Almost like ack'ing a vblank interrupt, maybe in the spirit of
+	 * cleaning up?
+	 */
+	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
+		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
+		uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index);
+
+		if (!crtc->base.enabled)
+			continue;
+
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask);
+		if (!nv_wait(NV50_PDISPLAY_INTR_1, mask, mask)) {
+			NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == "
+				      "0x%08x\n", mask, mask);
+			NV_ERROR(dev, "0x610024 = 0x%08x\n",
+				 nv_rd32(dev, NV50_PDISPLAY_INTR_1));
+		}
+	}
+
+	nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0);
+	nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0);
+	if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) {
+		NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n");
+		NV_ERROR(dev, "0x610200 = 0x%08x\n",
+			  nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)));
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(i),
+			     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
+			NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
+			NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
+				  nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
+		}
+	}
+
+	/* disable interrupts. */
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000);
+
+	/* disable hotplug interrupts */
+	nv_wr32(dev, 0xe054, 0xffffffff);
+	nv_wr32(dev, 0xe050, 0x00000000);
+	if (dev_priv->chipset >= 0x90) {
+		nv_wr32(dev, 0xe074, 0xffffffff);
+		nv_wr32(dev, 0xe070, 0x00000000);
+	}
+	return 0;
+}
+
+int nv50_display_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct parsed_dcb *dcb = dev_priv->vbios->dcb;
+	uint32_t connector[16] = {};
+	int ret, i;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	/* init basic kernel modesetting */
+	drm_mode_config_init(dev);
+
+	/* Initialise some optional connector properties. */
+	drm_mode_create_scaling_mode_property(dev);
+	drm_mode_create_dithering_property(dev);
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+
+	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
+
+	dev->mode_config.max_width = 8192;
+	dev->mode_config.max_height = 8192;
+
+	dev->mode_config.fb_base = dev_priv->fb_phys;
+
+	/* Create EVO channel */
+	ret = nv50_evo_channel_new(dev, &dev_priv->evo);
+	if (ret) {
+		NV_ERROR(dev, "Error creating EVO channel: %d\n", ret);
+		return ret;
+	}
+
+	/* Create CRTC objects */
+	for (i = 0; i < 2; i++)
+		nv50_crtc_create(dev, i);
+
+	/* We setup the encoders from the BIOS table */
+	for (i = 0 ; i < dcb->entries; i++) {
+		struct dcb_entry *entry = &dcb->entry[i];
+
+		if (entry->location != DCB_LOC_ON_CHIP) {
+			NV_WARN(dev, "Off-chip encoder %d/%d unsupported\n",
+				entry->type, ffs(entry->or) - 1);
+			continue;
+		}
+
+		switch (entry->type) {
+		case OUTPUT_TMDS:
+		case OUTPUT_LVDS:
+		case OUTPUT_DP:
+			nv50_sor_create(dev, entry);
+			break;
+		case OUTPUT_ANALOG:
+			nv50_dac_create(dev, entry);
+			break;
+		default:
+			NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
+			continue;
+		}
+
+		connector[entry->connector] |= (1 << entry->type);
+	}
+
+	/* It appears that DCB 3.0+ VBIOS has a connector table, however,
+	 * I'm not 100% certain how to decode it correctly yet so just
+	 * look at what encoders are present on each connector index and
+	 * attempt to derive the connector type from that.
+	 */
+	for (i = 0 ; i < dcb->entries; i++) {
+		struct dcb_entry *entry = &dcb->entry[i];
+		uint16_t encoders;
+		int type;
+
+		encoders = connector[entry->connector];
+		if (!(encoders & (1 << entry->type)))
+			continue;
+		connector[entry->connector] = 0;
+
+		if (encoders & (1 << OUTPUT_DP)) {
+			type = DRM_MODE_CONNECTOR_DisplayPort;
+		} else if (encoders & (1 << OUTPUT_TMDS)) {
+			if (encoders & (1 << OUTPUT_ANALOG))
+				type = DRM_MODE_CONNECTOR_DVII;
+			else
+				type = DRM_MODE_CONNECTOR_DVID;
+		} else if (encoders & (1 << OUTPUT_ANALOG)) {
+			type = DRM_MODE_CONNECTOR_VGA;
+		} else if (encoders & (1 << OUTPUT_LVDS)) {
+			type = DRM_MODE_CONNECTOR_LVDS;
+		} else {
+			type = DRM_MODE_CONNECTOR_Unknown;
+		}
+
+		if (type == DRM_MODE_CONNECTOR_Unknown)
+			continue;
+
+		nouveau_connector_create(dev, entry->connector, type);
+	}
+
+	ret = nv50_display_init(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int nv50_display_destroy(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	drm_mode_config_cleanup(dev);
+
+	nv50_display_disable(dev);
+	nv50_evo_channel_del(&dev_priv->evo);
+
+	return 0;
+}
+
+static inline uint32_t
+nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t mc;
+
+	if (sor) {
+		if (dev_priv->chipset < 0x90 ||
+		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or));
+		else
+			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or));
+	} else {
+		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or));
+	}
+
+	return mc;
+}
+
+static int
+nv50_display_irq_head(struct drm_device *dev, int *phead,
+		      struct dcb_entry **pdcbent)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL);
+	uint32_t dac = 0, sor = 0;
+	int head, i, or = 0, type = OUTPUT_ANY;
+
+	/* We're assuming that head 0 *or* head 1 will be active here,
+	 * and not both.  I'm not sure if the hw will even signal both
+	 * ever, but it definitely shouldn't for us as we commit each
+	 * CRTC separately, and submission will be blocked by the GPU
+	 * until we handle each in turn.
+	 */
+	NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+	head = ffs((unk30 >> 9) & 3) - 1;
+	if (head < 0)
+		return -EINVAL;
+
+	/* This assumes CRTCs are never bound to multiple encoders, which
+	 * should be the case.
+	 */
+	for (i = 0; i < 3 && type == OUTPUT_ANY; i++) {
+		uint32_t mc = nv50_display_mode_ctrl(dev, false, i);
+		if (!(mc & (1 << head)))
+			continue;
+
+		switch ((mc >> 8) & 0xf) {
+		case 0: type = OUTPUT_ANALOG; break;
+		case 1: type = OUTPUT_TV; break;
+		default:
+			NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac);
+			return -1;
+		}
+
+		or = i;
+	}
+
+	for (i = 0; i < 4 && type == OUTPUT_ANY; i++) {
+		uint32_t mc = nv50_display_mode_ctrl(dev, true, i);
+		if (!(mc & (1 << head)))
+			continue;
+
+		switch ((mc >> 8) & 0xf) {
+		case 0: type = OUTPUT_LVDS; break;
+		case 1: type = OUTPUT_TMDS; break;
+		case 2: type = OUTPUT_TMDS; break;
+		case 5: type = OUTPUT_TMDS; break;
+		case 8: type = OUTPUT_DP; break;
+		case 9: type = OUTPUT_DP; break;
+		default:
+			NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor);
+			return -1;
+		}
+
+		or = i;
+	}
+
+	NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or);
+	if (type == OUTPUT_ANY) {
+		NV_ERROR(dev, "unknown encoder!!\n");
+		return -1;
+	}
+
+	for (i = 0; i < dev_priv->vbios->dcb->entries; i++) {
+		struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i];
+
+		if (dcbent->type != type)
+			continue;
+
+		if (!(dcbent->or & (1 << or)))
+			continue;
+
+		*phead = head;
+		*pdcbent = dcbent;
+		return 0;
+	}
+
+	NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or);
+	return 0;
+}
+
+static uint32_t
+nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
+			   int pxclk)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_connector *nv_connector = NULL;
+	struct drm_encoder *encoder;
+	struct nvbios *bios = &dev_priv->VBIOS;
+	uint32_t mc, script = 0, or;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+		if (nv_encoder->dcb != dcbent)
+			continue;
+
+		nv_connector = nouveau_encoder_connector_get(nv_encoder);
+		break;
+	}
+
+	or = ffs(dcbent->or) - 1;
+	mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or);
+	switch (dcbent->type) {
+	case OUTPUT_LVDS:
+		script = (mc >> 8) & 0xf;
+		if (bios->pub.fp_no_ddc) {
+			if (bios->fp.dual_link)
+				script |= 0x0100;
+			if (bios->fp.if_is_24bit)
+				script |= 0x0200;
+		} else {
+			if (pxclk >= bios->fp.duallink_transition_clk) {
+				script |= 0x0100;
+				if (bios->fp.strapless_is_24bit & 2)
+					script |= 0x0200;
+			} else
+			if (bios->fp.strapless_is_24bit & 1)
+				script |= 0x0200;
+
+			if (nv_connector && nv_connector->edid &&
+			    (nv_connector->edid->revision >= 4) &&
+			    (nv_connector->edid->input & 0x70) >= 0x20)
+				script |= 0x0200;
+		}
+
+		if (nouveau_uscript_lvds >= 0) {
+			NV_INFO(dev, "override script 0x%04x with 0x%04x "
+				     "for output LVDS-%d\n", script,
+				     nouveau_uscript_lvds, or);
+			script = nouveau_uscript_lvds;
+		}
+		break;
+	case OUTPUT_TMDS:
+		script = (mc >> 8) & 0xf;
+		if (pxclk >= 165000)
+			script |= 0x0100;
+
+		if (nouveau_uscript_tmds >= 0) {
+			NV_INFO(dev, "override script 0x%04x with 0x%04x "
+				     "for output TMDS-%d\n", script,
+				     nouveau_uscript_tmds, or);
+			script = nouveau_uscript_tmds;
+		}
+		break;
+	case OUTPUT_DP:
+		script = (mc >> 8) & 0xf;
+		break;
+	case OUTPUT_ANALOG:
+		script = 0xff;
+		break;
+	default:
+		NV_ERROR(dev, "modeset on unsupported output type!\n");
+		break;
+	}
+
+	return script;
+}
+
+static void
+nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) {
+		chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait);
+
+		nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset,
+						chan->nvsw.vblsem_rval);
+		list_del(&chan->nvsw.vbl_wait);
+	}
+}
+
+static void
+nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
+{
+	intr &= NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
+
+	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0)
+		nv50_display_vblank_crtc_handler(dev, 0);
+
+	if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
+		nv50_display_vblank_crtc_handler(dev, 1);
+
+	nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
+		     NV50_PDISPLAY_INTR_EN) & ~intr);
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
+}
+
+static void
+nv50_display_unk10_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	int head, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+
+	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
+
+	nouveau_bios_run_display_table(dev, dcbent, 0, -1);
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
+	nv_wr32(dev, 0x610030, 0x80000000);
+}
+
+static void
+nv50_display_unk20_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	uint32_t tmp, pclk, script;
+	int head, or, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+	or = ffs(dcbent->or) - 1;
+	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
+	script = nv50_display_script_select(dev, dcbent, pclk);
+
+	NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk);
+
+	if (dcbent->type != OUTPUT_DP)
+		nouveau_bios_run_display_table(dev, dcbent, 0, -2);
+
+	nv50_crtc_set_clock(dev, head, pclk);
+
+	nouveau_bios_run_display_table(dev, dcbent, script, pclk);
+
+	tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
+	tmp &= ~0x000000f;
+	nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);
+
+	if (dcbent->type != OUTPUT_ANALOG) {
+		tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
+		tmp &= ~0x00000f0f;
+		if (script & 0x0100)
+			tmp |= 0x00000101;
+		nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp);
+	} else {
+		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
+	}
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
+	nv_wr32(dev, 0x610030, 0x80000000);
+}
+
+static void
+nv50_display_unk40_handler(struct drm_device *dev)
+{
+	struct dcb_entry *dcbent;
+	int head, pclk, script, ret;
+
+	ret = nv50_display_irq_head(dev, &head, &dcbent);
+	if (ret)
+		goto ack;
+	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
+	script = nv50_display_script_select(dev, dcbent, pclk);
+
+	nouveau_bios_run_display_table(dev, dcbent, script, -pclk);
+
+ack:
+	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
+	nv_wr32(dev, 0x610030, 0x80000000);
+	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8);
+}
+
+void
+nv50_display_irq_handler_bh(struct work_struct *work)
+{
+	struct drm_nouveau_private *dev_priv =
+		container_of(work, struct drm_nouveau_private, irq_work);
+	struct drm_device *dev = dev_priv->dev;
+
+	for (;;) {
+		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
+		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+
+		NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
+
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10)
+			nv50_display_unk10_handler(dev);
+		else
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK20)
+			nv50_display_unk20_handler(dev);
+		else
+		if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK40)
+			nv50_display_unk40_handler(dev);
+		else
+			break;
+	}
+
+	nv_wr32(dev, NV03_PMC_INTR_EN_0, 1);
+}
+
+static void
+nv50_display_error_handler(struct drm_device *dev)
+{
+	uint32_t addr, data;
+
+	nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000);
+	addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR);
+	data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA);
+
+	NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n",
+		 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
+
+	nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
+}
+
+static void
+nv50_display_irq_hotplug(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_connector *connector;
+	const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+	uint32_t unplug_mask, plug_mask, change_mask;
+	uint32_t hpd0, hpd1 = 0;
+
+	hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
+	if (dev_priv->chipset >= 0x90)
+		hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
+
+	plug_mask   = (hpd0 & 0x0000ffff) | (hpd1 << 16);
+	unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
+	change_mask = plug_mask | unplug_mask;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct drm_encoder_helper_funcs *helper;
+		struct nouveau_connector *nv_connector =
+			nouveau_connector(connector);
+		struct nouveau_encoder *nv_encoder;
+		struct dcb_gpio_entry *gpio;
+		uint32_t reg;
+		bool plugged;
+
+		if (!nv_connector->dcb)
+			continue;
+
+		gpio = nouveau_bios_gpio_entry(dev, nv_connector->dcb->gpio_tag);
+		if (!gpio || !(change_mask & (1 << gpio->line)))
+			continue;
+
+		reg = nv_rd32(dev, gpio_reg[gpio->line >> 3]);
+		plugged = !!(reg & (4 << ((gpio->line & 7) << 2)));
+		NV_INFO(dev, "%splugged %s\n", plugged ? "" : "un",
+			drm_get_connector_name(connector)) ;
+
+		if (!connector->encoder || !connector->encoder->crtc ||
+		    !connector->encoder->crtc->enabled)
+			continue;
+		nv_encoder = nouveau_encoder(connector->encoder);
+		helper = connector->encoder->helper_private;
+
+		if (nv_encoder->dcb->type != OUTPUT_DP)
+			continue;
+
+		if (plugged)
+			helper->dpms(connector->encoder, DRM_MODE_DPMS_ON);
+		else
+			helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
+	}
+
+	nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
+	if (dev_priv->chipset >= 0x90)
+		nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
+}
+
+void
+nv50_display_irq_handler(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t delayed = 0;
+
+	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
+		nv50_display_irq_hotplug(dev);
+
+	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
+		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
+		uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+		uint32_t clock;
+
+		NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
+
+		if (!intr0 && !(intr1 & ~delayed))
+			break;
+
+		if (intr0 & 0x00010000) {
+			nv50_display_error_handler(dev);
+			intr0 &= ~0x00010000;
+		}
+
+		if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
+			nv50_display_vblank_handler(dev, intr1);
+			intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
+		}
+
+		clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 |
+				  NV50_PDISPLAY_INTR_1_CLK_UNK20 |
+				  NV50_PDISPLAY_INTR_1_CLK_UNK40));
+		if (clock) {
+			nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+			if (!work_pending(&dev_priv->irq_work))
+				queue_work(dev_priv->wq, &dev_priv->irq_work);
+			delayed |= clock;
+			intr1 &= ~clock;
+		}
+
+		if (intr0) {
+			NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0);
+			nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0);
+		}
+
+		if (intr1) {
+			NV_ERROR(dev,
+				 "unknown PDISPLAY_INTR_1: 0x%08x\n", intr1);
+			nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1);
+		}
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_display.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_display.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_display.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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 __NV50_DISPLAY_H__
+#define __NV50_DISPLAY_H__
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_reg.h"
+#include "nouveau_crtc.h"
+#include "nv50_evo.h"
+
+void nv50_display_irq_handler(struct drm_device *dev);
+void nv50_display_irq_handler_bh(struct work_struct *work);
+int nv50_display_init(struct drm_device *dev);
+int nv50_display_create(struct drm_device *dev);
+int nv50_display_destroy(struct drm_device *dev);
+int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
+int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
+
+#endif /* __NV50_DISPLAY_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_evo.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_evo.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_evo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_evo.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#define NV50_EVO_UPDATE                                              0x00000080
+#define NV50_EVO_UNK84                                               0x00000084
+#define NV50_EVO_UNK84_NOTIFY                                        0x40000000
+#define NV50_EVO_UNK84_NOTIFY_DISABLED                               0x00000000
+#define NV50_EVO_UNK84_NOTIFY_ENABLED                                0x40000000
+#define NV50_EVO_DMA_NOTIFY                                          0x00000088
+#define NV50_EVO_DMA_NOTIFY_HANDLE                                   0xffffffff
+#define NV50_EVO_DMA_NOTIFY_HANDLE_NONE                              0x00000000
+#define NV50_EVO_UNK8C                                               0x0000008C
+
+#define NV50_EVO_DAC(n, r)                       ((n) * 0x80 + NV50_EVO_DAC_##r)
+#define NV50_EVO_DAC_MODE_CTRL                                       0x00000400
+#define NV50_EVO_DAC_MODE_CTRL_CRTC0                                 0x00000001
+#define NV50_EVO_DAC_MODE_CTRL_CRTC1                                 0x00000002
+#define NV50_EVO_DAC_MODE_CTRL2                                      0x00000404
+#define NV50_EVO_DAC_MODE_CTRL2_NHSYNC                               0x00000001
+#define NV50_EVO_DAC_MODE_CTRL2_NVSYNC                               0x00000002
+
+#define NV50_EVO_SOR(n, r)                       ((n) * 0x40 + NV50_EVO_SOR_##r)
+#define NV50_EVO_SOR_MODE_CTRL                                       0x00000600
+#define NV50_EVO_SOR_MODE_CTRL_CRTC0                                 0x00000001
+#define NV50_EVO_SOR_MODE_CTRL_CRTC1                                 0x00000002
+#define NV50_EVO_SOR_MODE_CTRL_TMDS                                  0x00000100
+#define NV50_EVO_SOR_MODE_CTRL_TMDS_DUAL_LINK                        0x00000400
+#define NV50_EVO_SOR_MODE_CTRL_NHSYNC                                0x00001000
+#define NV50_EVO_SOR_MODE_CTRL_NVSYNC                                0x00002000
+
+#define NV50_EVO_CRTC(n, r)                    ((n) * 0x400 + NV50_EVO_CRTC_##r)
+#define NV84_EVO_CRTC(n, r)                    ((n) * 0x400 + NV84_EVO_CRTC_##r)
+#define NV50_EVO_CRTC_UNK0800                                        0x00000800
+#define NV50_EVO_CRTC_CLOCK                                          0x00000804
+#define NV50_EVO_CRTC_INTERLACE                                      0x00000808
+#define NV50_EVO_CRTC_DISPLAY_START                                  0x00000810
+#define NV50_EVO_CRTC_DISPLAY_TOTAL                                  0x00000814
+#define NV50_EVO_CRTC_SYNC_DURATION                                  0x00000818
+#define NV50_EVO_CRTC_SYNC_START_TO_BLANK_END                        0x0000081c
+#define NV50_EVO_CRTC_UNK0820                                        0x00000820
+#define NV50_EVO_CRTC_UNK0824                                        0x00000824
+#define NV50_EVO_CRTC_UNK082C                                        0x0000082c
+#define NV50_EVO_CRTC_CLUT_MODE                                      0x00000840
+/* You can't have a palette in 8 bit mode (=OFF) */
+#define NV50_EVO_CRTC_CLUT_MODE_BLANK                                0x00000000
+#define NV50_EVO_CRTC_CLUT_MODE_OFF                                  0x80000000
+#define NV50_EVO_CRTC_CLUT_MODE_ON                                   0xC0000000
+#define NV50_EVO_CRTC_CLUT_OFFSET                                    0x00000844
+#define NV84_EVO_CRTC_CLUT_DMA                                       0x0000085C
+#define NV84_EVO_CRTC_CLUT_DMA_HANDLE                                0xffffffff
+#define NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE                           0x00000000
+#define NV50_EVO_CRTC_FB_OFFSET                                      0x00000860
+#define NV50_EVO_CRTC_FB_SIZE                                        0x00000868
+#define NV50_EVO_CRTC_FB_CONFIG                                      0x0000086c
+#define NV50_EVO_CRTC_FB_CONFIG_MODE                                 0x00100000
+#define NV50_EVO_CRTC_FB_CONFIG_MODE_TILE                            0x00000000
+#define NV50_EVO_CRTC_FB_CONFIG_MODE_PITCH                           0x00100000
+#define NV50_EVO_CRTC_FB_DEPTH                                       0x00000870
+#define NV50_EVO_CRTC_FB_DEPTH_8                                     0x00001e00
+#define NV50_EVO_CRTC_FB_DEPTH_15                                    0x0000e900
+#define NV50_EVO_CRTC_FB_DEPTH_16                                    0x0000e800
+#define NV50_EVO_CRTC_FB_DEPTH_24                                    0x0000cf00
+#define NV50_EVO_CRTC_FB_DEPTH_30                                    0x0000d100
+#define NV50_EVO_CRTC_FB_DMA                                         0x00000874
+#define NV50_EVO_CRTC_FB_DMA_HANDLE                                  0xffffffff
+#define NV50_EVO_CRTC_FB_DMA_HANDLE_NONE                             0x00000000
+#define NV50_EVO_CRTC_CURSOR_CTRL                                    0x00000880
+#define NV50_EVO_CRTC_CURSOR_CTRL_HIDE                               0x05000000
+#define NV50_EVO_CRTC_CURSOR_CTRL_SHOW                               0x85000000
+#define NV50_EVO_CRTC_CURSOR_OFFSET                                  0x00000884
+#define NV84_EVO_CRTC_CURSOR_DMA                                     0x0000089c
+#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE                              0xffffffff
+#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE                         0x00000000
+#define NV50_EVO_CRTC_DITHER_CTRL                                    0x000008a0
+#define NV50_EVO_CRTC_DITHER_CTRL_OFF                                0x00000000
+#define NV50_EVO_CRTC_DITHER_CTRL_ON                                 0x00000011
+#define NV50_EVO_CRTC_SCALE_CTRL                                     0x000008a4
+#define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE                            0x00000000
+#define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE                              0x00000009
+#define NV50_EVO_CRTC_COLOR_CTRL                                     0x000008a8
+#define NV50_EVO_CRTC_COLOR_CTRL_COLOR                               0x00040000
+#define NV50_EVO_CRTC_FB_POS                                         0x000008c0
+#define NV50_EVO_CRTC_REAL_RES                                       0x000008c8
+#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET                            0x000008d4
+#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) \
+	((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF))
+/* Both of these are needed, otherwise nothing happens. */
+#define NV50_EVO_CRTC_SCALE_RES1                                     0x000008d8
+#define NV50_EVO_CRTC_SCALE_RES2                                     0x000008dc
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fbcon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,267 @@
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_fbcon.h"
+
+void
+nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) &&
+	     RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+
+	if (rect->rop != ROP_COPY) {
+		BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+		OUT_RING(chan, 1);
+	}
+	BEGIN_RING(chan, NvSub2D, 0x0588, 1);
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
+		OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]);
+	else
+		OUT_RING(chan, rect->color);
+	BEGIN_RING(chan, NvSub2D, 0x0600, 4);
+	OUT_RING(chan, rect->dx);
+	OUT_RING(chan, rect->dy);
+	OUT_RING(chan, rect->dx + rect->width);
+	OUT_RING(chan, rect->dy + rect->height);
+	if (rect->rop != ROP_COPY) {
+		BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+		OUT_RING(chan, 3);
+	}
+	FIRE_RING(chan);
+}
+
+void
+nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_copyarea(info, region);
+		return;
+	}
+
+	BEGIN_RING(chan, NvSub2D, 0x0110, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x08b0, 4);
+	OUT_RING(chan, region->dx);
+	OUT_RING(chan, region->dy);
+	OUT_RING(chan, region->width);
+	OUT_RING(chan, region->height);
+	BEGIN_RING(chan, NvSub2D, 0x08d0, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, region->sx);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, region->sy);
+	FIRE_RING(chan);
+}
+
+void
+nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	uint32_t width, dwords, *data = (uint32_t *)image->data;
+	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+	uint32_t *palette = info->pseudo_palette;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+
+	if (image->depth != 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) {
+		nouveau_fbcon_gpu_lockup(info);
+	}
+
+	if (info->flags & FBINFO_HWACCEL_DISABLED) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	width = (image->width + 31) & ~31;
+	dwords = (width * image->height) >> 5;
+
+	BEGIN_RING(chan, NvSub2D, 0x0814, 2);
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+		OUT_RING(chan, palette[image->bg_color] | mask);
+		OUT_RING(chan, palette[image->fg_color] | mask);
+	} else {
+		OUT_RING(chan, image->bg_color);
+		OUT_RING(chan, image->fg_color);
+	}
+	BEGIN_RING(chan, NvSub2D, 0x0838, 2);
+	OUT_RING(chan, image->width);
+	OUT_RING(chan, image->height);
+	BEGIN_RING(chan, NvSub2D, 0x0850, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, image->dx);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, image->dy);
+
+	while (dwords) {
+		int push = dwords > 2047 ? 2047 : dwords;
+
+		if (RING_SPACE(chan, push + 1)) {
+			nouveau_fbcon_gpu_lockup(info);
+			cfb_imageblit(info, image);
+			return;
+		}
+
+		dwords -= push;
+
+		BEGIN_RING(chan, NvSub2D, 0x40000860, push);
+		OUT_RINGp(chan, data, push);
+		data += push;
+	}
+
+	FIRE_RING(chan);
+}
+
+int
+nv50_fbcon_accel_init(struct fb_info *info)
+{
+	struct nouveau_fbcon_par *par = info->par;
+	struct drm_device *dev = par->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->channel;
+	struct nouveau_gpuobj *eng2d = NULL;
+	int ret, format;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		format = 0xf3;
+		break;
+	case 15:
+		format = 0xf8;
+		break;
+	case 16:
+		format = 0xe8;
+		break;
+	case 32:
+		switch (info->var.transp.length) {
+		case 0: /* depth 24 */
+		case 8: /* depth 32, just use 24.. */
+			format = 0xe6;
+			break;
+		case 2: /* depth 30 */
+			format = 0xd1;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = nouveau_gpuobj_gr_new(dev_priv->channel, 0x502d, &eng2d);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, Nv2D, eng2d, NULL);
+	if (ret)
+		return ret;
+
+	ret = RING_SPACE(chan, 59);
+	if (ret) {
+		nouveau_fbcon_gpu_lockup(info);
+		return ret;
+	}
+
+	BEGIN_RING(chan, NvSub2D, 0x0000, 1);
+	OUT_RING(chan, Nv2D);
+	BEGIN_RING(chan, NvSub2D, 0x0180, 4);
+	OUT_RING(chan, NvNotify0);
+	OUT_RING(chan, chan->vram_handle);
+	OUT_RING(chan, chan->vram_handle);
+	OUT_RING(chan, chan->vram_handle);
+	BEGIN_RING(chan, NvSub2D, 0x0290, 1);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x0888, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
+	OUT_RING(chan, 3);
+	BEGIN_RING(chan, NvSub2D, 0x02a0, 1);
+	OUT_RING(chan, 0x55);
+	BEGIN_RING(chan, NvSub2D, 0x08c0, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0580, 2);
+	OUT_RING(chan, 4);
+	OUT_RING(chan, format);
+	BEGIN_RING(chan, NvSub2D, 0x02e8, 2);
+	OUT_RING(chan, 2);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0804, 1);
+	OUT_RING(chan, format);
+	BEGIN_RING(chan, NvSub2D, 0x0800, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0808, 3);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 0);
+	BEGIN_RING(chan, NvSub2D, 0x081c, 1);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0840, 4);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0200, 2);
+	OUT_RING(chan, format);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0214, 5);
+	OUT_RING(chan, info->fix.line_length);
+	OUT_RING(chan, info->var.xres_virtual);
+	OUT_RING(chan, info->var.yres_virtual);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
+			 dev_priv->vm_vram_base);
+	BEGIN_RING(chan, NvSub2D, 0x0230, 2);
+	OUT_RING(chan, format);
+	OUT_RING(chan, 1);
+	BEGIN_RING(chan, NvSub2D, 0x0244, 5);
+	OUT_RING(chan, info->fix.line_length);
+	OUT_RING(chan, info->var.xres_virtual);
+	OUT_RING(chan, info->var.yres_virtual);
+	OUT_RING(chan, 0);
+	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
+			 dev_priv->vm_vram_base);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_fifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+struct nv50_fifo_priv {
+	struct nouveau_gpuobj_ref *thingo[2];
+	int cur_thingo;
+};
+
+#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
+
+static void
+nv50_fifo_init_thingo(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+	struct nouveau_gpuobj_ref *cur;
+	int i, nr;
+
+	NV_DEBUG(dev, "\n");
+
+	cur = priv->thingo[priv->cur_thingo];
+	priv->cur_thingo = !priv->cur_thingo;
+
+	/* We never schedule channel 0 or 127 */
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = 1, nr = 0; i < 127; i++) {
+		if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc)
+			nv_wo32(dev, cur->gpuobj, nr++, i);
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x32f4, cur->instance >> 12);
+	nv_wr32(dev, 0x32ec, nr);
+	nv_wr32(dev, 0x2500, 0x101);
+}
+
+static int
+nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->fifos[channel];
+	uint32_t inst;
+
+	NV_DEBUG(dev, "ch%d\n", channel);
+
+	if (!chan->ramfc)
+		return -EINVAL;
+
+	if (IS_G80)
+		inst = chan->ramfc->instance >> 12;
+	else
+		inst = chan->ramfc->instance >> 8;
+	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel),
+		 inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
+
+	if (!nt)
+		nv50_fifo_init_thingo(dev);
+	return 0;
+}
+
+static void
+nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+
+	NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt);
+
+	if (IS_G80)
+		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80;
+	else
+		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84;
+	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst);
+
+	if (!nt)
+		nv50_fifo_init_thingo(dev);
+}
+
+static void
+nv50_fifo_init_reset(struct drm_device *dev)
+{
+	uint32_t pmc_e = NV_PMC_ENABLE_PFIFO;
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |  pmc_e);
+}
+
+static void
+nv50_fifo_init_intr(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF);
+	nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
+}
+
+static void
+nv50_fifo_init_context_table(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i;
+
+	NV_DEBUG(dev, "\n");
+
+	for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) {
+		if (dev_priv->fifos[i])
+			nv50_fifo_channel_enable(dev, i, true);
+		else
+			nv50_fifo_channel_disable(dev, i, true);
+	}
+
+	nv50_fifo_init_thingo(dev);
+}
+
+static void
+nv50_fifo_init_regs__nv(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x250c, 0x6f3cfc34);
+}
+
+static void
+nv50_fifo_init_regs(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x2500, 0);
+	nv_wr32(dev, 0x3250, 0);
+	nv_wr32(dev, 0x3220, 0);
+	nv_wr32(dev, 0x3204, 0);
+	nv_wr32(dev, 0x3210, 0);
+	nv_wr32(dev, 0x3270, 0);
+
+	/* Enable dummy channels setup by nv50_instmem.c */
+	nv50_fifo_channel_enable(dev, 0, true);
+	nv50_fifo_channel_enable(dev, 127, true);
+}
+
+int
+nv50_fifo_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv;
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	priv = dev_priv->engine.fifo.priv;
+	if (priv) {
+		priv->cur_thingo = !priv->cur_thingo;
+		goto just_reset;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_priv->engine.fifo.priv = priv;
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]);
+	if (ret) {
+		NV_ERROR(dev, "error creating thingo0: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]);
+	if (ret) {
+		NV_ERROR(dev, "error creating thingo1: %d\n", ret);
+		return ret;
+	}
+
+just_reset:
+	nv50_fifo_init_reset(dev);
+	nv50_fifo_init_intr(dev);
+	nv50_fifo_init_context_table(dev);
+	nv50_fifo_init_regs__nv(dev);
+	nv50_fifo_init_regs(dev);
+	dev_priv->engine.fifo.enable(dev);
+	dev_priv->engine.fifo.reassign(dev, true);
+
+	return 0;
+}
+
+void
+nv50_fifo_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!priv)
+		return;
+
+	nouveau_gpuobj_ref_del(dev, &priv->thingo[0]);
+	nouveau_gpuobj_ref_del(dev, &priv->thingo[1]);
+
+	dev_priv->engine.fifo.priv = NULL;
+	kfree(priv);
+}
+
+int
+nv50_fifo_channel_id(struct drm_device *dev)
+{
+	return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
+			NV50_PFIFO_CACHE1_PUSH1_CHID_MASK;
+}
+
+int
+nv50_fifo_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramfc = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (IS_G80) {
+		uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start;
+		uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start;
+
+		ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset,
+					      0x100, NVOBJ_FLAG_ZERO_ALLOC |
+					      NVOBJ_FLAG_ZERO_FREE, &ramfc,
+					      &chan->ramfc);
+		if (ret)
+			return ret;
+
+		ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400,
+					      ramin_voffset + 0x0400, 4096,
+					      0, NULL, &chan->cache);
+		if (ret)
+			return ret;
+	} else {
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256,
+					     NVOBJ_FLAG_ZERO_ALLOC |
+					     NVOBJ_FLAG_ZERO_FREE,
+					     &chan->ramfc);
+		if (ret)
+			return ret;
+		ramfc = chan->ramfc->gpuobj;
+
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 4096, 1024,
+					     0, &chan->cache);
+		if (ret)
+			return ret;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base);
+	nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base);
+	nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
+	nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
+	nv_wo32(dev, ramfc, 0x3c/4, 0x00086078);
+	nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
+	nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
+	nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
+	nv_wo32(dev, ramfc, 0x7c/4, 0x30000001);
+	nv_wo32(dev, ramfc, 0x78/4, 0x00000000);
+	nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff);
+
+	if (!IS_G80) {
+		nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
+		nv_wo32(dev, chan->ramin->gpuobj, 1,
+						chan->ramfc->instance >> 8);
+
+		nv_wo32(dev, ramfc, 0x88/4, chan->cache->instance >> 10);
+		nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12);
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	ret = nv50_fifo_channel_enable(dev, chan->id, false);
+	if (ret) {
+		NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+		return ret;
+	}
+
+	return 0;
+}
+
+void
+nv50_fifo_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct nouveau_gpuobj_ref *ramfc = chan->ramfc;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	/* This will ensure the channel is seen as disabled. */
+	chan->ramfc = NULL;
+	nv50_fifo_channel_disable(dev, chan->id, false);
+
+	/* Dummy channel, also used on ch 127 */
+	if (chan->id == 0)
+		nv50_fifo_channel_disable(dev, 127, false);
+
+	nouveau_gpuobj_ref_del(dev, &ramfc);
+	nouveau_gpuobj_ref_del(dev, &chan->cache);
+}
+
+int
+nv50_fifo_load_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj;
+	struct nouveau_gpuobj *cache = chan->cache->gpuobj;
+	int ptr, cnt;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	dev_priv->engine.instmem.prepare_access(dev, false);
+
+	nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4));
+	nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4));
+	nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4));
+	nv_wr32(dev, 0x3320, nv_ro32(dev, ramfc, 0x0c/4));
+	nv_wr32(dev, 0x3244, nv_ro32(dev, ramfc, 0x10/4));
+	nv_wr32(dev, 0x3328, nv_ro32(dev, ramfc, 0x14/4));
+	nv_wr32(dev, 0x3368, nv_ro32(dev, ramfc, 0x18/4));
+	nv_wr32(dev, 0x336c, nv_ro32(dev, ramfc, 0x1c/4));
+	nv_wr32(dev, 0x3370, nv_ro32(dev, ramfc, 0x20/4));
+	nv_wr32(dev, 0x3374, nv_ro32(dev, ramfc, 0x24/4));
+	nv_wr32(dev, 0x3378, nv_ro32(dev, ramfc, 0x28/4));
+	nv_wr32(dev, 0x337c, nv_ro32(dev, ramfc, 0x2c/4));
+	nv_wr32(dev, 0x3228, nv_ro32(dev, ramfc, 0x30/4));
+	nv_wr32(dev, 0x3364, nv_ro32(dev, ramfc, 0x34/4));
+	nv_wr32(dev, 0x32a0, nv_ro32(dev, ramfc, 0x38/4));
+	nv_wr32(dev, 0x3224, nv_ro32(dev, ramfc, 0x3c/4));
+	nv_wr32(dev, 0x324c, nv_ro32(dev, ramfc, 0x40/4));
+	nv_wr32(dev, 0x2044, nv_ro32(dev, ramfc, 0x44/4));
+	nv_wr32(dev, 0x322c, nv_ro32(dev, ramfc, 0x48/4));
+	nv_wr32(dev, 0x3234, nv_ro32(dev, ramfc, 0x4c/4));
+	nv_wr32(dev, 0x3340, nv_ro32(dev, ramfc, 0x50/4));
+	nv_wr32(dev, 0x3344, nv_ro32(dev, ramfc, 0x54/4));
+	nv_wr32(dev, 0x3280, nv_ro32(dev, ramfc, 0x58/4));
+	nv_wr32(dev, 0x3254, nv_ro32(dev, ramfc, 0x5c/4));
+	nv_wr32(dev, 0x3260, nv_ro32(dev, ramfc, 0x60/4));
+	nv_wr32(dev, 0x3264, nv_ro32(dev, ramfc, 0x64/4));
+	nv_wr32(dev, 0x3268, nv_ro32(dev, ramfc, 0x68/4));
+	nv_wr32(dev, 0x326c, nv_ro32(dev, ramfc, 0x6c/4));
+	nv_wr32(dev, 0x32e4, nv_ro32(dev, ramfc, 0x70/4));
+	nv_wr32(dev, 0x3248, nv_ro32(dev, ramfc, 0x74/4));
+	nv_wr32(dev, 0x2088, nv_ro32(dev, ramfc, 0x78/4));
+	nv_wr32(dev, 0x2058, nv_ro32(dev, ramfc, 0x7c/4));
+	nv_wr32(dev, 0x2210, nv_ro32(dev, ramfc, 0x80/4));
+
+	cnt = nv_ro32(dev, ramfc, 0x84/4);
+	for (ptr = 0; ptr < cnt; ptr++) {
+		nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr),
+			nv_ro32(dev, cache, (ptr * 2) + 0));
+		nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr),
+			nv_ro32(dev, cache, (ptr * 2) + 1));
+	}
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2);
+	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
+
+	/* guessing that all the 0x34xx regs aren't on NV50 */
+	if (!IS_G80) {
+		nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4));
+		nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4));
+		nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4));
+		nv_wr32(dev, 0x3408, nv_ro32(dev, ramfc, 0x94/4));
+		nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4));
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
+	return 0;
+}
+
+int
+nv50_fifo_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_gpuobj *ramfc, *cache;
+	struct nouveau_channel *chan = NULL;
+	int chid, get, put, ptr;
+
+	NV_DEBUG(dev, "\n");
+
+	chid = pfifo->channel_id(dev);
+	if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1)
+		return 0;
+
+	chan = dev_priv->fifos[chid];
+	if (!chan) {
+		NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid);
+		return -EINVAL;
+	}
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+	ramfc = chan->ramfc->gpuobj;
+	cache = chan->cache->gpuobj;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+
+	nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330));
+	nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334));
+	nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240));
+	nv_wo32(dev, ramfc, 0x0c/4, nv_rd32(dev, 0x3320));
+	nv_wo32(dev, ramfc, 0x10/4, nv_rd32(dev, 0x3244));
+	nv_wo32(dev, ramfc, 0x14/4, nv_rd32(dev, 0x3328));
+	nv_wo32(dev, ramfc, 0x18/4, nv_rd32(dev, 0x3368));
+	nv_wo32(dev, ramfc, 0x1c/4, nv_rd32(dev, 0x336c));
+	nv_wo32(dev, ramfc, 0x20/4, nv_rd32(dev, 0x3370));
+	nv_wo32(dev, ramfc, 0x24/4, nv_rd32(dev, 0x3374));
+	nv_wo32(dev, ramfc, 0x28/4, nv_rd32(dev, 0x3378));
+	nv_wo32(dev, ramfc, 0x2c/4, nv_rd32(dev, 0x337c));
+	nv_wo32(dev, ramfc, 0x30/4, nv_rd32(dev, 0x3228));
+	nv_wo32(dev, ramfc, 0x34/4, nv_rd32(dev, 0x3364));
+	nv_wo32(dev, ramfc, 0x38/4, nv_rd32(dev, 0x32a0));
+	nv_wo32(dev, ramfc, 0x3c/4, nv_rd32(dev, 0x3224));
+	nv_wo32(dev, ramfc, 0x40/4, nv_rd32(dev, 0x324c));
+	nv_wo32(dev, ramfc, 0x44/4, nv_rd32(dev, 0x2044));
+	nv_wo32(dev, ramfc, 0x48/4, nv_rd32(dev, 0x322c));
+	nv_wo32(dev, ramfc, 0x4c/4, nv_rd32(dev, 0x3234));
+	nv_wo32(dev, ramfc, 0x50/4, nv_rd32(dev, 0x3340));
+	nv_wo32(dev, ramfc, 0x54/4, nv_rd32(dev, 0x3344));
+	nv_wo32(dev, ramfc, 0x58/4, nv_rd32(dev, 0x3280));
+	nv_wo32(dev, ramfc, 0x5c/4, nv_rd32(dev, 0x3254));
+	nv_wo32(dev, ramfc, 0x60/4, nv_rd32(dev, 0x3260));
+	nv_wo32(dev, ramfc, 0x64/4, nv_rd32(dev, 0x3264));
+	nv_wo32(dev, ramfc, 0x68/4, nv_rd32(dev, 0x3268));
+	nv_wo32(dev, ramfc, 0x6c/4, nv_rd32(dev, 0x326c));
+	nv_wo32(dev, ramfc, 0x70/4, nv_rd32(dev, 0x32e4));
+	nv_wo32(dev, ramfc, 0x74/4, nv_rd32(dev, 0x3248));
+	nv_wo32(dev, ramfc, 0x78/4, nv_rd32(dev, 0x2088));
+	nv_wo32(dev, ramfc, 0x7c/4, nv_rd32(dev, 0x2058));
+	nv_wo32(dev, ramfc, 0x80/4, nv_rd32(dev, 0x2210));
+
+	put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2;
+	get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2;
+	ptr = 0;
+	while (put != get) {
+		nv_wo32(dev, cache, ptr++,
+			    nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get)));
+		nv_wo32(dev, cache, ptr++,
+			    nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get)));
+		get = (get + 1) & 0x1ff;
+	}
+
+	/* guessing that all the 0x34xx regs aren't on NV50 */
+	if (!IS_G80) {
+		nv_wo32(dev, ramfc, 0x84/4, ptr >> 1);
+		nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c));
+		nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400));
+		nv_wo32(dev, ramfc, 0x90/4, nv_rd32(dev, 0x3404));
+		nv_wo32(dev, ramfc, 0x94/4, nv_rd32(dev, 0x3408));
+		nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410));
+	}
+
+	dev_priv->engine.instmem.finish_access(dev);
+
+	/*XXX: probably reload ch127 (NULL) state back too */
+	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127);
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_graph.c	2013-05-03 12:03:19.000000000 -0400
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+/*(DEBLOBBED)*/
+
+#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
+
+static void
+nv50_graph_init_reset(struct drm_device *dev)
+{
+	uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21);
+
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e);
+	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |  pmc_e);
+}
+
+static void
+nv50_graph_init_intr(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff);
+	nv_wr32(dev, 0x400138, 0xffffffff);
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff);
+}
+
+static void
+nv50_graph_init_regs__nv(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, 0x400804, 0xc0000000);
+	nv_wr32(dev, 0x406800, 0xc0000000);
+	nv_wr32(dev, 0x400c04, 0xc0000000);
+	nv_wr32(dev, 0x401800, 0xc0000000);
+	nv_wr32(dev, 0x405018, 0xc0000000);
+	nv_wr32(dev, 0x402000, 0xc0000000);
+
+	nv_wr32(dev, 0x400108, 0xffffffff);
+
+	nv_wr32(dev, 0x400824, 0x00004000);
+	nv_wr32(dev, 0x400500, 0x00010001);
+}
+
+static void
+nv50_graph_init_regs(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+
+	nv_wr32(dev, NV04_PGRAPH_DEBUG_3,
+				(1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */);
+	nv_wr32(dev, 0x402ca8, 0x800);
+}
+
+static int
+nv50_graph_init_ctxctl(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	NV_DEBUG(dev, "\n");
+
+	nouveau_grctx_prog_load(dev);
+	if (!dev_priv->engine.graph.ctxprog)
+		dev_priv->engine.graph.accel_blocked = true;
+
+	nv_wr32(dev, 0x400320, 4);
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0);
+	return 0;
+}
+
+int
+nv50_graph_init(struct drm_device *dev)
+{
+	int ret;
+
+	NV_DEBUG(dev, "\n");
+
+	nv50_graph_init_reset(dev);
+	nv50_graph_init_regs__nv(dev);
+	nv50_graph_init_regs(dev);
+	nv50_graph_init_intr(dev);
+
+	ret = nv50_graph_init_ctxctl(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void
+nv50_graph_takedown(struct drm_device *dev)
+{
+	NV_DEBUG(dev, "\n");
+	nouveau_grctx_fini(dev);
+}
+
+void
+nv50_graph_fifo_access(struct drm_device *dev, bool enabled)
+{
+	const uint32_t mask = 0x00010001;
+
+	if (enabled)
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask);
+	else
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask);
+}
+
+struct nouveau_channel *
+nv50_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	/* Be sure we're not in the middle of a context switch or bad things
+	 * will happen, such as unloading the wrong pgraph context.
+	 */
+	if (!nv_wait(0x400300, 0x00000001, 0x00000000))
+		NV_ERROR(dev, "Ctxprog is still running\n");
+
+	inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return NULL;
+	inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12;
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->fifos[i];
+
+		if (chan && chan->ramin && chan->ramin->instance == inst)
+			return chan;
+	}
+
+	return NULL;
+}
+
+int
+nv50_graph_create_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	struct nouveau_gpuobj *ctx;
+	uint32_t grctx_size = 0x70000;
+	int hdr, ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000,
+				     NVOBJ_FLAG_ZERO_ALLOC |
+				     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
+	if (ret)
+		return ret;
+	ctx = chan->ramin_grctx->gpuobj;
+
+	hdr = IS_G80 ? 0x200 : 0x20;
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
+	nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
+					   grctx_size - 1);
+	nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance);
+	nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
+	nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
+	nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	nouveau_grctx_vals_load(dev, ctx);
+	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
+	if ((dev_priv->chipset & 0xf0) == 0xa0)
+		nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
+	else
+		nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	return 0;
+}
+
+void
+nv50_graph_destroy_context(struct nouveau_channel *chan)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i, hdr = IS_G80 ? 0x200 : 0x20;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	if (!chan->ramin || !chan->ramin->gpuobj)
+		return;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	for (i = hdr; i < hdr + 24; i += 4)
+		nv_wo32(dev, chan->ramin->gpuobj, i/4, 0);
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+}
+
+static int
+nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
+{
+	uint32_t fifo = nv_rd32(dev, 0x400500);
+
+	nv_wr32(dev, 0x400500, fifo & ~1);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40);
+	nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11);
+	nv_wr32(dev, 0x400040, 0xffffffff);
+	(void)nv_rd32(dev, 0x400040);
+	nv_wr32(dev, 0x400040, 0x00000000);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1);
+
+	if (nouveau_wait_for_idle(dev))
+		nv_wr32(dev, 0x40032c, inst | (1<<31));
+	nv_wr32(dev, 0x400500, fifo);
+
+	return 0;
+}
+
+int
+nv50_graph_load_context(struct nouveau_channel *chan)
+{
+	uint32_t inst = chan->ramin->instance >> 12;
+
+	NV_DEBUG(chan->dev, "ch%d\n", chan->id);
+	return nv50_graph_do_load_context(chan->dev, inst);
+}
+
+int
+nv50_graph_unload_context(struct drm_device *dev)
+{
+	uint32_t inst;
+
+	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
+
+	nouveau_wait_for_idle(dev);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
+	return 0;
+}
+
+void
+nv50_graph_context_switch(struct drm_device *dev)
+{
+	uint32_t inst;
+
+	nv50_graph_unload_context(dev);
+
+	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_NEXT);
+	inst &= NV50_PGRAPH_CTXCTL_NEXT_INSTANCE;
+	nv50_graph_do_load_context(dev, inst);
+
+	nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+		NV40_PGRAPH_INTR_EN) | NV_PGRAPH_INTR_CONTEXT_SWITCH);
+}
+
+static int
+nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass,
+			   int mthd, uint32_t data)
+{
+	struct nouveau_gpuobj_ref *ref = NULL;
+
+	if (nouveau_gpuobj_ref_find(chan, data, &ref))
+		return -ENOENT;
+
+	if (nouveau_notifier_offset(ref->gpuobj, NULL))
+		return -EINVAL;
+
+	chan->nvsw.vblsem = ref->gpuobj;
+	chan->nvsw.vblsem_offset = ~0;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass,
+			      int mthd, uint32_t data)
+{
+	if (nouveau_notifier_offset(chan->nvsw.vblsem, &data))
+		return -ERANGE;
+
+	chan->nvsw.vblsem_offset = data >> 2;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass,
+				   int mthd, uint32_t data)
+{
+	chan->nvsw.vblsem_rval = data;
+	return 0;
+}
+
+static int
+nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass,
+			       int mthd, uint32_t data)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1)
+		return -EINVAL;
+
+	if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) &
+		      NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) {
+		nv_wr32(dev, NV50_PDISPLAY_INTR_1,
+			NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data));
+		nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
+			NV50_PDISPLAY_INTR_EN) |
+			NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data));
+	}
+
+	list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting);
+	return 0;
+}
+
+static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = {
+	{ 0x018c, nv50_graph_nvsw_dma_vblsem },
+	{ 0x0400, nv50_graph_nvsw_vblsem_offset },
+	{ 0x0404, nv50_graph_nvsw_vblsem_release_val },
+	{ 0x0408, nv50_graph_nvsw_vblsem_release },
+	{}
+};
+
+struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
+	{ 0x506e, true, nv50_graph_nvsw_methods }, /* nvsw */
+	{ 0x0030, false, NULL }, /* null */
+	{ 0x5039, false, NULL }, /* m2mf */
+	{ 0x502d, false, NULL }, /* 2d */
+	{ 0x50c0, false, NULL }, /* compute */
+	{ 0x5097, false, NULL }, /* tesla (nv50) */
+	{ 0x8297, false, NULL }, /* tesla (nv80/nv90) */
+	{ 0x8397, false, NULL }, /* tesla (nva0) */
+	{ 0x8597, false, NULL }, /* tesla (nva8) */
+	{}
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_instmem.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+struct nv50_instmem_priv {
+	uint32_t save1700[5]; /* 0x1700->0x1710 */
+
+	struct nouveau_gpuobj_ref *pramin_pt;
+	struct nouveau_gpuobj_ref *pramin_bar;
+	struct nouveau_gpuobj_ref *fb_bar;
+
+	bool last_access_wr;
+};
+
+#define NV50_INSTMEM_PAGE_SHIFT 12
+#define NV50_INSTMEM_PAGE_SIZE  (1 << NV50_INSTMEM_PAGE_SHIFT)
+#define NV50_INSTMEM_PT_SIZE(a)	(((a) >> 12) << 3)
+
+/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN
+ */
+#define BAR0_WI32(g, o, v) do {                                   \
+	uint32_t offset;                                          \
+	if ((g)->im_backing) {                                    \
+		offset = (g)->im_backing_start;                   \
+	} else {                                                  \
+		offset  = chan->ramin->gpuobj->im_backing_start;  \
+		offset += (g)->im_pramin->start;                  \
+	}                                                         \
+	offset += (o);                                            \
+	nv_wr32(dev, NV_RAMIN + (offset & 0xfffff), (v));              \
+} while (0)
+
+int
+nv50_instmem_init(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan;
+	uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+	struct nv50_instmem_priv *priv;
+	int ret, i;
+	uint32_t v, save_nv001700;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_priv->engine.instmem.priv = priv;
+
+	/* Save state, will restore at takedown. */
+	for (i = 0x1700; i <= 0x1710; i += 4)
+		priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
+
+	if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+		dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
+	else
+		dev_priv->vram_sys_base = 0;
+
+	/* Reserve the last MiB of VRAM, we should probably try to avoid
+	 * setting up the below tables over the top of the VBIOS image at
+	 * some point.
+	 */
+	dev_priv->ramin_rsvd_vram = 1 << 20;
+	c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+	c_size   = 128 << 10;
+	c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
+	c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
+	c_base   = c_vmpd + 0x4000;
+	pt_size  = NV50_INSTMEM_PT_SIZE(dev_priv->ramin_size);
+
+	NV_DEBUG(dev, " Rsvd VRAM base: 0x%08x\n", c_offset);
+	NV_DEBUG(dev, "    VBIOS image: 0x%08x\n",
+				(nv_rd32(dev, 0x619f04) & ~0xff) << 8);
+	NV_DEBUG(dev, "  Aperture size: %d MiB\n", dev_priv->ramin_size >> 20);
+	NV_DEBUG(dev, "        PT size: %d KiB\n", pt_size >> 10);
+
+	/* Determine VM layout, we need to do this first to make sure
+	 * we allocate enough memory for all the page tables.
+	 */
+	dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK);
+	dev_priv->vm_gart_size = NV50_VM_BLOCK;
+
+	dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
+	dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+	if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
+		dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
+	dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
+	dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK;
+
+	dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size;
+
+	NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n",
+		 dev_priv->vm_gart_base,
+		 dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1);
+	NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n",
+		 dev_priv->vm_vram_base,
+		 dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1);
+
+	c_size += dev_priv->vm_vram_pt_nr * (NV50_VM_BLOCK / 65536 * 8);
+
+	/* Map BAR0 PRAMIN aperture over the memory we want to use */
+	save_nv001700 = nv_rd32(dev, NV50_PUNK_BAR0_PRAMIN);
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16));
+
+	/* Create a fake channel, and use it as our "dummy" channels 0/127.
+	 * The main reason for creating a channel is so we can use the gpuobj
+	 * code.  However, it's probably worth noting that NVIDIA also setup
+	 * their channels 0/127 with the same values they configure here.
+	 * So, there may be some other reason for doing this.
+	 *
+	 * Have to create the entire channel manually, as the real channel
+	 * creation code assumes we have PRAMIN access, and we don't until
+	 * we're done here.
+	 */
+	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+	chan->id = 0;
+	chan->dev = dev;
+	chan->file_priv = (struct drm_file *)-2;
+	dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
+
+	/* Channel's PRAMIN object + heap */
+	ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0,
+							NULL, &chan->ramin);
+	if (ret)
+		return ret;
+
+	if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base))
+		return -ENOMEM;
+
+	/* RAMFC + zero channel's PRAMIN up to start of VM pagedir */
+	ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc,
+						0x4000, 0, NULL, &chan->ramfc);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < c_vmpd; i += 4)
+		BAR0_WI32(chan->ramin->gpuobj, i, 0);
+
+	/* VM page directory */
+	ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd,
+					   0x4000, 0, &chan->vm_pd, NULL);
+	if (ret)
+		return ret;
+	for (i = 0; i < 0x4000; i += 8) {
+		BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000);
+		BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000);
+	}
+
+	/* PRAMIN page table, cheat and map into VM at 0x0000000000.
+	 * We map the entire fake channel into the start of the PRAMIN BAR
+	 */
+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000,
+				     0, &priv->pramin_pt);
+	if (ret)
+		return ret;
+
+	v = c_offset | 1;
+	if (dev_priv->vram_sys_base) {
+		v += dev_priv->vram_sys_base;
+		v |= 0x30;
+	}
+
+	i = 0;
+	while (v < dev_priv->vram_sys_base + c_offset + c_size) {
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+		v += 0x1000;
+		i += 8;
+	}
+
+	while (i < pt_size) {
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000000);
+		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+		i += 8;
+	}
+
+	BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63);
+	BAR0_WI32(chan->vm_pd, 0x04, 0x00000000);
+
+	/* VRAM page table(s), mapped into VM at +1GiB  */
+	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+		ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0,
+					     NV50_VM_BLOCK/65536*8, 0, 0,
+					     &chan->vm_vram_pt[i]);
+		if (ret) {
+			NV_ERROR(dev, "Error creating VRAM page tables: %d\n",
+									ret);
+			dev_priv->vm_vram_pt_nr = i;
+			return ret;
+		}
+		dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]->gpuobj;
+
+		for (v = 0; v < dev_priv->vm_vram_pt[i]->im_pramin->size;
+								v += 4)
+			BAR0_WI32(dev_priv->vm_vram_pt[i], v, 0);
+
+		BAR0_WI32(chan->vm_pd, 0x10 + (i*8),
+			  chan->vm_vram_pt[i]->instance | 0x61);
+		BAR0_WI32(chan->vm_pd, 0x14 + (i*8), 0);
+	}
+
+	/* DMA object for PRAMIN BAR */
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0,
+							&priv->pramin_bar);
+	if (ret)
+		return ret;
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin_size - 1);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000);
+	BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000);
+
+	/* DMA object for FB BAR */
+	ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0,
+							&priv->fb_bar);
+	if (ret)
+		return ret;
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 +
+					      drm_get_resource_len(dev, 1) - 1);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000);
+	BAR0_WI32(priv->fb_bar->gpuobj, 0x14, 0x00000000);
+
+	/* Poke the relevant regs, and pray it works :) */
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12));
+	nv_wr32(dev, NV50_PUNK_UNK1710, 0);
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) |
+					 NV50_PUNK_BAR_CFG_BASE_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) |
+					NV50_PUNK_BAR1_CTXDMA_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) |
+					NV50_PUNK_BAR3_CTXDMA_VALID);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(dev, 0x1900 + (i*4), 0);
+
+	/* Assume that praying isn't enough, check that we can re-read the
+	 * entire fake channel back from the PRAMIN BAR */
+	dev_priv->engine.instmem.prepare_access(dev, false);
+	for (i = 0; i < c_size; i += 4) {
+		if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) {
+			NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n",
+									i);
+			dev_priv->engine.instmem.finish_access(dev);
+			return -EINVAL;
+		}
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700);
+
+	/* Global PRAMIN heap */
+	if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
+				  c_size, dev_priv->ramin_size - c_size)) {
+		dev_priv->ramin_heap = NULL;
+		NV_ERROR(dev, "Failed to init RAMIN heap\n");
+	}
+
+	/*XXX: incorrect, but needed to make hash func "work" */
+	dev_priv->ramht_offset = 0x10000;
+	dev_priv->ramht_bits   = 9;
+	dev_priv->ramht_size   = (1 << dev_priv->ramht_bits);
+	return 0;
+}
+
+void
+nv50_instmem_takedown(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	int i;
+
+	NV_DEBUG(dev, "\n");
+
+	if (!priv)
+		return;
+
+	/* Restore state from before init */
+	for (i = 0x1700; i <= 0x1710; i += 4)
+		nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]);
+
+	nouveau_gpuobj_ref_del(dev, &priv->fb_bar);
+	nouveau_gpuobj_ref_del(dev, &priv->pramin_bar);
+	nouveau_gpuobj_ref_del(dev, &priv->pramin_pt);
+
+	/* Destroy dummy channel */
+	if (chan) {
+		for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
+			nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
+			dev_priv->vm_vram_pt[i] = NULL;
+		}
+		dev_priv->vm_vram_pt_nr = 0;
+
+		nouveau_gpuobj_del(dev, &chan->vm_pd);
+		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+		nouveau_gpuobj_ref_del(dev, &chan->ramin);
+		nouveau_mem_takedown(&chan->ramin_heap);
+
+		dev_priv->fifos[0] = dev_priv->fifos[127] = NULL;
+		kfree(chan);
+	}
+
+	dev_priv->engine.instmem.priv = NULL;
+	kfree(priv);
+}
+
+int
+nv50_instmem_suspend(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	int i;
+
+	ramin->im_backing_suspend = vmalloc(ramin->im_pramin->size);
+	if (!ramin->im_backing_suspend)
+		return -ENOMEM;
+
+	for (i = 0; i < ramin->im_pramin->size; i += 4)
+		ramin->im_backing_suspend[i/4] = nv_ri32(dev, i);
+	return 0;
+}
+
+void
+nv50_instmem_resume(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	struct nouveau_channel *chan = dev_priv->fifos[0];
+	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
+	int i;
+
+	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (ramin->im_backing_start >> 16));
+	for (i = 0; i < ramin->im_pramin->size; i += 4)
+		BAR0_WI32(ramin, i, ramin->im_backing_suspend[i/4]);
+	vfree(ramin->im_backing_suspend);
+	ramin->im_backing_suspend = NULL;
+
+	/* Poke the relevant regs, and pray it works :) */
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12));
+	nv_wr32(dev, NV50_PUNK_UNK1710, 0);
+	nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) |
+					 NV50_PUNK_BAR_CFG_BASE_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) |
+					NV50_PUNK_BAR1_CTXDMA_VALID);
+	nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) |
+					NV50_PUNK_BAR3_CTXDMA_VALID);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(dev, 0x1900 + (i*4), 0);
+}
+
+int
+nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
+		      uint32_t *sz)
+{
+	int ret;
+
+	if (gpuobj->im_backing)
+		return -EINVAL;
+
+	*sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1);
+	if (*sz == 0)
+		return -EINVAL;
+
+	ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000,
+			     true, false, &gpuobj->im_backing);
+	if (ret) {
+		NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret);
+		return ret;
+	}
+
+	ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret);
+		nouveau_bo_ref(NULL, &gpuobj->im_backing);
+		return ret;
+	}
+
+	gpuobj->im_backing_start = gpuobj->im_backing->bo.mem.mm_node->start;
+	gpuobj->im_backing_start <<= PAGE_SHIFT;
+
+	return 0;
+}
+
+void
+nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (gpuobj && gpuobj->im_backing) {
+		if (gpuobj->im_bound)
+			dev_priv->engine.instmem.unbind(dev, gpuobj);
+		nouveau_bo_unpin(gpuobj->im_backing);
+		nouveau_bo_ref(NULL, &gpuobj->im_backing);
+		gpuobj->im_backing = NULL;
+	}
+}
+
+int
+nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	struct nouveau_gpuobj *pramin_pt = priv->pramin_pt->gpuobj;
+	uint32_t pte, pte_end;
+	uint64_t vram;
+
+	if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
+		return -EINVAL;
+
+	NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n",
+		 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
+
+	pte     = (gpuobj->im_pramin->start >> 12) << 1;
+	pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
+	vram    = gpuobj->im_backing_start;
+
+	NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n",
+		 gpuobj->im_pramin->start, pte, pte_end);
+	NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
+
+	vram |= 1;
+	if (dev_priv->vram_sys_base) {
+		vram += dev_priv->vram_sys_base;
+		vram |= 0x30;
+	}
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (pte < pte_end) {
+		nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram));
+		nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram));
+		vram += NV50_INSTMEM_PAGE_SIZE;
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	nv_wr32(dev, 0x100c80, 0x00040001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	nv_wr32(dev, 0x100c80, 0x00060001);
+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+		return -EBUSY;
+	}
+
+	gpuobj->im_bound = 1;
+	return 0;
+}
+
+int
+nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+	uint32_t pte, pte_end;
+
+	if (gpuobj->im_bound == 0)
+		return -EINVAL;
+
+	pte     = (gpuobj->im_pramin->start >> 12) << 1;
+	pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
+
+	dev_priv->engine.instmem.prepare_access(dev, true);
+	while (pte < pte_end) {
+		nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
+		nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
+	}
+	dev_priv->engine.instmem.finish_access(dev);
+
+	gpuobj->im_bound = 0;
+	return 0;
+}
+
+void
+nv50_instmem_prepare_access(struct drm_device *dev, bool write)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+
+	priv->last_access_wr = write;
+}
+
+void
+nv50_instmem_finish_access(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
+
+	if (priv->last_access_wr) {
+		nv_wr32(dev, 0x070000, 0x00000001);
+		if (!nv_wait(0x070000, 0x00000001, 0x00000000))
+			NV_ERROR(dev, "PRAMIN flush timeout\n");
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_mc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_mc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_mc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_mc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+
+int
+nv50_mc_init(struct drm_device *dev)
+{
+	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
+	return 0;
+}
+
+void nv50_mc_takedown(struct drm_device *dev)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nv50_sor.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2008 Maarten Maathuis.
+ * 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, 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 OWNER(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.
+ *
+ */
+
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+
+#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_reg.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+#include "nouveau_encoder.h"
+#include "nouveau_connector.h"
+#include "nouveau_crtc.h"
+#include "nv50_display.h"
+
+static void
+nv50_sor_disconnect(struct nouveau_encoder *nv_encoder)
+{
+	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while disconnecting SOR\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, 0);
+}
+
+static void
+nv50_sor_dp_link_train(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct bit_displayport_encoder_table *dpe;
+	int dpe_headerlen;
+
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
+	if (!dpe) {
+		NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
+		return;
+	}
+
+	if (dpe->script0) {
+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
+					    nv_encoder->dcb);
+	}
+
+	if (!nouveau_dp_link_train(encoder))
+		NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or);
+
+	if (dpe->script1) {
+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
+					    nv_encoder->dcb);
+	}
+}
+
+static void
+nv50_sor_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_encoder *enc;
+	uint32_t val;
+	int or = nv_encoder->or;
+
+	NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
+
+	nv_encoder->last_dpms = mode;
+	list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
+		struct nouveau_encoder *nvenc = nouveau_encoder(enc);
+
+		if (nvenc == nv_encoder ||
+		    nvenc->disconnect != nv50_sor_disconnect ||
+		    nvenc->dcb->or != nv_encoder->dcb->or)
+			continue;
+
+		if (nvenc->last_dpms == DRM_MODE_DPMS_ON)
+			return;
+	}
+
+	/* wait for it to be done */
+	if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or),
+		     NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) {
+		NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
+		NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)));
+	}
+
+	val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or));
+
+	if (mode == DRM_MODE_DPMS_ON)
+		val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
+	else
+		val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
+
+	nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val |
+		NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING);
+	if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(or),
+		     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
+		NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
+		NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or,
+			 nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
+	}
+
+	if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON)
+		nv50_sor_dp_link_train(encoder);
+}
+
+static void
+nv50_sor_save(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static void
+nv50_sor_restore(struct drm_encoder *encoder)
+{
+	NV_ERROR(encoder->dev, "!!\n");
+}
+
+static bool
+nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		    struct drm_display_mode *adjusted_mode)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct nouveau_connector *connector;
+
+	NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or);
+
+	connector = nouveau_encoder_connector_get(nv_encoder);
+	if (!connector) {
+		NV_ERROR(encoder->dev, "Encoder has no connector\n");
+		return false;
+	}
+
+	if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
+	     connector->native_mode) {
+		int id = adjusted_mode->base.id;
+		*adjusted_mode = *connector->native_mode;
+		adjusted_mode->base.id = id;
+	}
+
+	return true;
+}
+
+static void
+nv50_sor_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_sor_commit(struct drm_encoder *encoder)
+{
+}
+
+static void
+nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+		  struct drm_display_mode *adjusted_mode)
+{
+	struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
+	struct nouveau_channel *evo = dev_priv->evo;
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
+	uint32_t mode_ctl = 0;
+	int ret;
+
+	NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
+
+	nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
+
+	switch (nv_encoder->dcb->type) {
+	case OUTPUT_TMDS:
+		if (nv_encoder->dcb->sorconf.link & 1) {
+			if (adjusted_mode->clock < 165000)
+				mode_ctl = 0x0100;
+			else
+				mode_ctl = 0x0500;
+		} else
+			mode_ctl = 0x0200;
+		break;
+	case OUTPUT_DP:
+		mode_ctl |= 0x00050000;
+		if (nv_encoder->dcb->sorconf.link & 1)
+			mode_ctl |= 0x00000800;
+		else
+			mode_ctl |= 0x00000900;
+		break;
+	default:
+		break;
+	}
+
+	if (crtc->index == 1)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1;
+	else
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+		mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC;
+
+	ret = RING_SPACE(evo, 2);
+	if (ret) {
+		NV_ERROR(dev, "no space while connecting SOR\n");
+		return;
+	}
+	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
+	OUT_RING(evo, mode_ctl);
+}
+
+static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
+	.dpms = nv50_sor_dpms,
+	.save = nv50_sor_save,
+	.restore = nv50_sor_restore,
+	.mode_fixup = nv50_sor_mode_fixup,
+	.prepare = nv50_sor_prepare,
+	.commit = nv50_sor_commit,
+	.mode_set = nv50_sor_mode_set,
+	.detect = NULL
+};
+
+static void
+nv50_sor_destroy(struct drm_encoder *encoder)
+{
+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+	if (!encoder)
+		return;
+
+	NV_DEBUG_KMS(encoder->dev, "\n");
+
+	drm_encoder_cleanup(encoder);
+
+	kfree(nv_encoder);
+}
+
+static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
+	.destroy = nv50_sor_destroy,
+};
+
+int
+nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
+{
+	struct nouveau_encoder *nv_encoder = NULL;
+	struct drm_encoder *encoder;
+	bool dum;
+	int type;
+
+	NV_DEBUG_KMS(dev, "\n");
+
+	switch (entry->type) {
+	case OUTPUT_TMDS:
+		NV_INFO(dev, "Detected a TMDS output\n");
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
+	case OUTPUT_LVDS:
+		NV_INFO(dev, "Detected a LVDS output\n");
+		type = DRM_MODE_ENCODER_LVDS;
+
+		if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
+			NV_ERROR(dev, "Failed parsing LVDS table\n");
+			return -EINVAL;
+		}
+		break;
+	case OUTPUT_DP:
+		NV_INFO(dev, "Detected a DP output\n");
+		type = DRM_MODE_ENCODER_TMDS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
+	if (!nv_encoder)
+		return -ENOMEM;
+	encoder = to_drm_encoder(nv_encoder);
+
+	nv_encoder->dcb = entry;
+	nv_encoder->or = ffs(entry->or) - 1;
+
+	nv_encoder->disconnect = nv50_sor_disconnect;
+
+	drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
+	drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
+
+	encoder->possible_crtcs = entry->heads;
+	encoder->possible_clones = 0;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nvreg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nvreg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/nouveau/nvreg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/nouveau/nvreg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,535 @@
+/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
+/*
+ * Copyright 1996-1997  David J. McKay
+ *
+ * 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
+ * DAVID J. MCKAY 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.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.6 2002/01/25 21:56:06 tsi Exp $ */
+
+#ifndef __NVREG_H_
+#define __NVREG_H_
+
+#define NV_PMC_OFFSET               0x00000000
+#define NV_PMC_SIZE                 0x00001000
+
+#define NV_PBUS_OFFSET              0x00001000
+#define NV_PBUS_SIZE                0x00001000
+
+#define NV_PFIFO_OFFSET             0x00002000
+#define NV_PFIFO_SIZE               0x00002000
+
+#define NV_HDIAG_OFFSET             0x00005000
+#define NV_HDIAG_SIZE               0x00001000
+
+#define NV_PRAM_OFFSET              0x00006000
+#define NV_PRAM_SIZE                0x00001000
+
+#define NV_PVIDEO_OFFSET            0x00008000
+#define NV_PVIDEO_SIZE              0x00001000
+
+#define NV_PTIMER_OFFSET            0x00009000
+#define NV_PTIMER_SIZE              0x00001000
+
+#define NV_PPM_OFFSET               0x0000A000
+#define NV_PPM_SIZE                 0x00001000
+
+#define NV_PTV_OFFSET               0x0000D000
+#define NV_PTV_SIZE                 0x00001000
+
+#define NV_PRMVGA_OFFSET            0x000A0000
+#define NV_PRMVGA_SIZE              0x00020000
+
+#define NV_PRMVIO0_OFFSET           0x000C0000
+#define NV_PRMVIO_SIZE              0x00002000
+#define NV_PRMVIO1_OFFSET           0x000C2000
+
+#define NV_PFB_OFFSET               0x00100000
+#define NV_PFB_SIZE                 0x00001000
+
+#define NV_PEXTDEV_OFFSET           0x00101000
+#define NV_PEXTDEV_SIZE             0x00001000
+
+#define NV_PME_OFFSET               0x00200000
+#define NV_PME_SIZE                 0x00001000
+
+#define NV_PROM_OFFSET              0x00300000
+#define NV_PROM_SIZE                0x00010000
+
+#define NV_PGRAPH_OFFSET            0x00400000
+#define NV_PGRAPH_SIZE              0x00010000
+
+#define NV_PCRTC0_OFFSET            0x00600000
+#define NV_PCRTC0_SIZE              0x00002000 /* empirical */
+
+#define NV_PRMCIO0_OFFSET           0x00601000
+#define NV_PRMCIO_SIZE              0x00002000
+#define NV_PRMCIO1_OFFSET           0x00603000
+
+#define NV50_DISPLAY_OFFSET           0x00610000
+#define NV50_DISPLAY_SIZE             0x0000FFFF
+
+#define NV_PRAMDAC0_OFFSET          0x00680000
+#define NV_PRAMDAC0_SIZE            0x00002000
+
+#define NV_PRMDIO0_OFFSET           0x00681000
+#define NV_PRMDIO_SIZE              0x00002000
+#define NV_PRMDIO1_OFFSET           0x00683000
+
+#define NV_PRAMIN_OFFSET            0x00700000
+#define NV_PRAMIN_SIZE              0x00100000
+
+#define NV_FIFO_OFFSET              0x00800000
+#define NV_FIFO_SIZE                0x00800000
+
+#define NV_PMC_BOOT_0			0x00000000
+#define NV_PMC_ENABLE			0x00000200
+
+#define NV_VIO_VSE2			0x000003c3
+#define NV_VIO_SRX			0x000003c4
+
+#define NV_CIO_CRX__COLOR		0x000003d4
+#define NV_CIO_CR__COLOR		0x000003d5
+
+#define NV_PBUS_DEBUG_1			0x00001084
+#define NV_PBUS_DEBUG_4			0x00001098
+#define NV_PBUS_DEBUG_DUALHEAD_CTL	0x000010f0
+#define NV_PBUS_POWERCTRL_1		0x00001584
+#define NV_PBUS_POWERCTRL_2		0x00001588
+#define NV_PBUS_POWERCTRL_4		0x00001590
+#define NV_PBUS_PCI_NV_19		0x0000184C
+#define NV_PBUS_PCI_NV_20		0x00001850
+#	define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED	(0 << 0)
+#	define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED	(1 << 0)
+
+#define NV_PFIFO_RAMHT			0x00002210
+
+#define NV_PTV_TV_INDEX			0x0000d220
+#define NV_PTV_TV_DATA			0x0000d224
+#define NV_PTV_HFILTER			0x0000d310
+#define NV_PTV_HFILTER2			0x0000d390
+#define NV_PTV_VFILTER			0x0000d510
+
+#define NV_PRMVIO_MISC__WRITE		0x000c03c2
+#define NV_PRMVIO_SRX			0x000c03c4
+#define NV_PRMVIO_SR			0x000c03c5
+#	define NV_VIO_SR_RESET_INDEX		0x00
+#	define NV_VIO_SR_CLOCK_INDEX		0x01
+#	define NV_VIO_SR_PLANE_MASK_INDEX	0x02
+#	define NV_VIO_SR_CHAR_MAP_INDEX		0x03
+#	define NV_VIO_SR_MEM_MODE_INDEX		0x04
+#define NV_PRMVIO_MISC__READ		0x000c03cc
+#define NV_PRMVIO_GRX			0x000c03ce
+#define NV_PRMVIO_GX			0x000c03cf
+#	define NV_VIO_GX_SR_INDEX		0x00
+#	define NV_VIO_GX_SREN_INDEX		0x01
+#	define NV_VIO_GX_CCOMP_INDEX		0x02
+#	define NV_VIO_GX_ROP_INDEX		0x03
+#	define NV_VIO_GX_READ_MAP_INDEX		0x04
+#	define NV_VIO_GX_MODE_INDEX		0x05
+#	define NV_VIO_GX_MISC_INDEX		0x06
+#	define NV_VIO_GX_DONT_CARE_INDEX	0x07
+#	define NV_VIO_GX_BIT_MASK_INDEX		0x08
+
+#define NV_PFB_BOOT_0			0x00100000
+#define NV_PFB_CFG0			0x00100200
+#define NV_PFB_CFG1			0x00100204
+#define NV_PFB_CSTATUS			0x0010020C
+#define NV_PFB_REFCTRL			0x00100210
+#	define NV_PFB_REFCTRL_VALID_1			(1 << 31)
+#define NV_PFB_PAD			0x0010021C
+#	define NV_PFB_PAD_CKE_NORMAL			(1 << 0)
+#define NV_PFB_TILE_NV10		0x00100240
+#define NV_PFB_TILE_SIZE_NV10		0x00100244
+#define NV_PFB_REF			0x001002D0
+#	define NV_PFB_REF_CMD_REFRESH			(1 << 0)
+#define NV_PFB_PRE			0x001002D4
+#	define NV_PFB_PRE_CMD_PRECHARGE			(1 << 0)
+#define NV_PFB_CLOSE_PAGE2		0x0010033C
+#define NV_PFB_TILE_NV40		0x00100600
+#define NV_PFB_TILE_SIZE_NV40		0x00100604
+
+#define NV_PEXTDEV_BOOT_0		0x00101000
+#	define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT	(8 << 12)
+#define NV_PEXTDEV_BOOT_3		0x0010100c
+
+#define NV_PCRTC_INTR_0					0x00600100
+#	define NV_PCRTC_INTR_0_VBLANK				(1 << 0)
+#define NV_PCRTC_INTR_EN_0				0x00600140
+#define NV_PCRTC_START					0x00600800
+#define NV_PCRTC_CONFIG					0x00600804
+#	define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA		(1 << 0)
+#	define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC		(2 << 0)
+#define NV_PCRTC_CURSOR_CONFIG				0x00600810
+#	define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE		(1 << 0)
+#	define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE	(1 << 4)
+#	define NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM	(1 << 8)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32		(1 << 12)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64		(1 << 16)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_32		(2 << 24)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64		(4 << 24)
+#	define NV_PCRTC_CURSOR_CONFIG_CUR_BLEND_ALPHA		(1 << 28)
+
+/* note: PCRTC_GPIO is not available on nv10, and in fact aliases 0x600810 */
+#define NV_PCRTC_GPIO					0x00600818
+#define NV_PCRTC_GPIO_EXT				0x0060081c
+#define NV_PCRTC_830					0x00600830
+#define NV_PCRTC_834					0x00600834
+#define NV_PCRTC_850					0x00600850
+#define NV_PCRTC_ENGINE_CTRL				0x00600860
+#	define NV_CRTC_FSEL_I2C					(1 << 4)
+#	define NV_CRTC_FSEL_OVERLAY				(1 << 12)
+
+#define NV_PRMCIO_ARX			0x006013c0
+#define NV_PRMCIO_AR__WRITE		0x006013c0
+#define NV_PRMCIO_AR__READ		0x006013c1
+#	define NV_CIO_AR_MODE_INDEX		0x10
+#	define NV_CIO_AR_OSCAN_INDEX		0x11
+#	define NV_CIO_AR_PLANE_INDEX		0x12
+#	define NV_CIO_AR_HPP_INDEX		0x13
+#	define NV_CIO_AR_CSEL_INDEX		0x14
+#define NV_PRMCIO_INP0			0x006013c2
+#define NV_PRMCIO_CRX__COLOR		0x006013d4
+#define NV_PRMCIO_CR__COLOR		0x006013d5
+	/* Standard VGA CRTC registers */
+#	define NV_CIO_CR_HDT_INDEX		0x00	/* horizontal display total */
+#	define NV_CIO_CR_HDE_INDEX		0x01	/* horizontal display end */
+#	define NV_CIO_CR_HBS_INDEX		0x02	/* horizontal blanking start */
+#	define NV_CIO_CR_HBE_INDEX		0x03	/* horizontal blanking end */
+#		define NV_CIO_CR_HBE_4_0		4:0
+#	define NV_CIO_CR_HRS_INDEX		0x04	/* horizontal retrace start */
+#	define NV_CIO_CR_HRE_INDEX		0x05	/* horizontal retrace end */
+#		define NV_CIO_CR_HRE_4_0		4:0
+#		define NV_CIO_CR_HRE_HBE_5		7:7
+#	define NV_CIO_CR_VDT_INDEX		0x06	/* vertical display total */
+#	define NV_CIO_CR_OVL_INDEX		0x07	/* overflow bits */
+#		define NV_CIO_CR_OVL_VDT_8		0:0
+#		define NV_CIO_CR_OVL_VDE_8		1:1
+#		define NV_CIO_CR_OVL_VRS_8		2:2
+#		define NV_CIO_CR_OVL_VBS_8		3:3
+#		define NV_CIO_CR_OVL_VDT_9		5:5
+#		define NV_CIO_CR_OVL_VDE_9		6:6
+#		define NV_CIO_CR_OVL_VRS_9		7:7
+#	define NV_CIO_CR_RSAL_INDEX		0x08	/* normally "preset row scan" */
+#	define NV_CIO_CR_CELL_HT_INDEX		0x09	/* cell height?! normally "max scan line" */
+#		define NV_CIO_CR_CELL_HT_VBS_9		5:5
+#		define NV_CIO_CR_CELL_HT_SCANDBL	7:7
+#	define NV_CIO_CR_CURS_ST_INDEX		0x0a	/* cursor start */
+#	define NV_CIO_CR_CURS_END_INDEX		0x0b	/* cursor end */
+#	define NV_CIO_CR_SA_HI_INDEX		0x0c	/* screen start address high */
+#	define NV_CIO_CR_SA_LO_INDEX		0x0d	/* screen start address low */
+#	define NV_CIO_CR_TCOFF_HI_INDEX		0x0e	/* cursor offset high */
+#	define NV_CIO_CR_TCOFF_LO_INDEX		0x0f	/* cursor offset low */
+#	define NV_CIO_CR_VRS_INDEX		0x10	/* vertical retrace start */
+#	define NV_CIO_CR_VRE_INDEX		0x11	/* vertical retrace end */
+#		define NV_CIO_CR_VRE_3_0		3:0
+#	define NV_CIO_CR_VDE_INDEX		0x12	/* vertical display end */
+#	define NV_CIO_CR_OFFSET_INDEX		0x13	/* sets screen pitch */
+#	define NV_CIO_CR_ULINE_INDEX		0x14	/* underline location */
+#	define NV_CIO_CR_VBS_INDEX		0x15	/* vertical blank start */
+#	define NV_CIO_CR_VBE_INDEX		0x16	/* vertical blank end */
+#	define NV_CIO_CR_MODE_INDEX		0x17	/* crtc mode control */
+#	define NV_CIO_CR_LCOMP_INDEX		0x18	/* line compare */
+	/* Extended VGA CRTC registers */
+#	define NV_CIO_CRE_RPC0_INDEX		0x19	/* repaint control 0 */
+#		define NV_CIO_CRE_RPC0_OFFSET_10_8	7:5
+#	define NV_CIO_CRE_RPC1_INDEX		0x1a	/* repaint control 1 */
+#		define NV_CIO_CRE_RPC1_LARGE		2:2
+#	define NV_CIO_CRE_FF_INDEX		0x1b	/* fifo control */
+#	define NV_CIO_CRE_ENH_INDEX		0x1c	/* enhanced? */
+#	define NV_CIO_SR_LOCK_INDEX		0x1f	/* crtc lock */
+#		define NV_CIO_SR_UNLOCK_RW_VALUE	0x57
+#		define NV_CIO_SR_LOCK_VALUE		0x99
+#	define NV_CIO_CRE_FFLWM__INDEX		0x20	/* fifo low water mark */
+#	define NV_CIO_CRE_21			0x21	/* vga shadow crtc lock */
+#	define NV_CIO_CRE_LSR_INDEX		0x25	/* ? */
+#		define NV_CIO_CRE_LSR_VDT_10		0:0
+#		define NV_CIO_CRE_LSR_VDE_10		1:1
+#		define NV_CIO_CRE_LSR_VRS_10		2:2
+#		define NV_CIO_CRE_LSR_VBS_10		3:3
+#		define NV_CIO_CRE_LSR_HBE_6		4:4
+#	define NV_CIO_CR_ARX_INDEX		0x26	/* attribute index -- ro copy of 0x60.3c0 */
+#	define NV_CIO_CRE_CHIP_ID_INDEX		0x27	/* chip revision */
+#	define NV_CIO_CRE_PIXEL_INDEX		0x28
+#		define NV_CIO_CRE_PIXEL_FORMAT		1:0
+#	define NV_CIO_CRE_HEB__INDEX		0x2d	/* horizontal extra bits? */
+#		define NV_CIO_CRE_HEB_HDT_8		0:0
+#		define NV_CIO_CRE_HEB_HDE_8		1:1
+#		define NV_CIO_CRE_HEB_HBS_8		2:2
+#		define NV_CIO_CRE_HEB_HRS_8		3:3
+#		define NV_CIO_CRE_HEB_ILC_8		4:4
+#	define NV_CIO_CRE_2E			0x2e	/* some scratch or dummy reg to force writes to sink in */
+#	define NV_CIO_CRE_HCUR_ADDR2_INDEX	0x2f	/* cursor */
+#	define NV_CIO_CRE_HCUR_ADDR0_INDEX	0x30		/* pixmap */
+#		define NV_CIO_CRE_HCUR_ADDR0_ADR	6:0
+#		define NV_CIO_CRE_HCUR_ASI		7:7
+#	define NV_CIO_CRE_HCUR_ADDR1_INDEX	0x31			/* address */
+#		define NV_CIO_CRE_HCUR_ADDR1_ENABLE	0:0
+#		define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL	1:1
+#		define NV_CIO_CRE_HCUR_ADDR1_ADR	7:2
+#	define NV_CIO_CRE_LCD__INDEX		0x33
+#		define NV_CIO_CRE_LCD_LCD_SELECT	0:0
+#	define NV_CIO_CRE_DDC0_STATUS__INDEX	0x36
+#	define NV_CIO_CRE_DDC0_WR__INDEX	0x37
+#	define NV_CIO_CRE_ILACE__INDEX		0x39	/* interlace */
+#	define NV_CIO_CRE_SCRATCH3__INDEX	0x3b
+#	define NV_CIO_CRE_SCRATCH4__INDEX	0x3c
+#	define NV_CIO_CRE_DDC_STATUS__INDEX	0x3e
+#	define NV_CIO_CRE_DDC_WR__INDEX		0x3f
+#	define NV_CIO_CRE_EBR_INDEX		0x41	/* extra bits ? (vertical) */
+#		define NV_CIO_CRE_EBR_VDT_11		0:0
+#		define NV_CIO_CRE_EBR_VDE_11		2:2
+#		define NV_CIO_CRE_EBR_VRS_11		4:4
+#		define NV_CIO_CRE_EBR_VBS_11		6:6
+#	define NV_CIO_CRE_43			0x43
+#	define NV_CIO_CRE_44			0x44	/* head control */
+#	define NV_CIO_CRE_CSB			0x45	/* colour saturation boost */
+#	define NV_CIO_CRE_RCR			0x46
+#		define NV_CIO_CRE_RCR_ENDIAN_BIG	7:7
+#	define NV_CIO_CRE_47			0x47	/* extended fifo lwm, used on nv30+ */
+#	define NV_CIO_CRE_49			0x49
+#	define NV_CIO_CRE_4B			0x4b	/* given patterns in 0x[2-3][a-c] regs, probably scratch 6 */
+#	define NV_CIO_CRE_TVOUT_LATENCY		0x52
+#	define NV_CIO_CRE_53			0x53	/* `fp_htiming' according to Haiku */
+#	define NV_CIO_CRE_54			0x54	/* `fp_vtiming' according to Haiku */
+#	define NV_CIO_CRE_57			0x57	/* index reg for cr58 */
+#	define NV_CIO_CRE_58			0x58	/* data reg for cr57 */
+#	define NV_CIO_CRE_59			0x59	/* related to on/off-chip-ness of digital outputs */
+#	define NV_CIO_CRE_5B			0x5B	/* newer colour saturation reg */
+#	define NV_CIO_CRE_85			0x85
+#	define NV_CIO_CRE_86			0x86
+#define NV_PRMCIO_INP0__COLOR		0x006013da
+
+#define NV_PRAMDAC_CU_START_POS				0x00680300
+#	define NV_PRAMDAC_CU_START_POS_X			15:0
+#	define NV_PRAMDAC_CU_START_POS_Y			31:16
+#define NV_RAMDAC_NV10_CURSYNC				0x00680404
+
+#define NV_PRAMDAC_NVPLL_COEFF				0x00680500
+#define NV_PRAMDAC_MPLL_COEFF				0x00680504
+#define NV_PRAMDAC_VPLL_COEFF				0x00680508
+#	define NV30_RAMDAC_ENABLE_VCO2				(8 << 4)
+
+#define NV_PRAMDAC_PLL_COEFF_SELECT			0x0068050c
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE	(4 << 0)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL	(1 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL	(2 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL	(4 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2	(8 << 8)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		(1 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1		(2 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2		(4 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2		(8 << 16)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_TV_CLK_SOURCE_VIP	(1 << 20)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2	(1 << 28)
+#	define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2	(2 << 28)
+
+#define NV_PRAMDAC_PLL_SETUP_CONTROL			0x00680510
+#define NV_RAMDAC_VPLL2					0x00680520
+#define NV_PRAMDAC_SEL_CLK				0x00680524
+#define NV_RAMDAC_DITHER_NV11				0x00680528
+#define NV_PRAMDAC_DACCLK				0x0068052c
+#	define NV_PRAMDAC_DACCLK_SEL_DACCLK			(1 << 0)
+
+#define NV_RAMDAC_NVPLL_B				0x00680570
+#define NV_RAMDAC_MPLL_B				0x00680574
+#define NV_RAMDAC_VPLL_B				0x00680578
+#define NV_RAMDAC_VPLL2_B				0x0068057c
+#	define NV31_RAMDAC_ENABLE_VCO2				(8 << 28)
+#define NV_PRAMDAC_580					0x00680580
+#	define NV_RAMDAC_580_VPLL1_ACTIVE			(1 << 8)
+#	define NV_RAMDAC_580_VPLL2_ACTIVE			(1 << 28)
+
+#define NV_PRAMDAC_GENERAL_CONTROL			0x00680600
+#	define NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON		(3 << 4)
+#	define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL		(1 << 8)
+#	define NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL		(1 << 12)
+#	define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM	(2 << 16)
+#	define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS		(1 << 20)
+#	define NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG		(2 << 28)
+#define NV_PRAMDAC_TEST_CONTROL				0x00680608
+#	define NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED	(1 << 12)
+#	define NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF		(1 << 16)
+#	define NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI		(1 << 28)
+#define NV_PRAMDAC_TESTPOINT_DATA			0x00680610
+#	define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK		(8 << 28)
+#define NV_PRAMDAC_630					0x00680630
+#define NV_PRAMDAC_634					0x00680634
+
+#define NV_PRAMDAC_TV_SETUP				0x00680700
+#define NV_PRAMDAC_TV_VTOTAL				0x00680720
+#define NV_PRAMDAC_TV_VSKEW				0x00680724
+#define NV_PRAMDAC_TV_VSYNC_DELAY			0x00680728
+#define NV_PRAMDAC_TV_HTOTAL				0x0068072c
+#define NV_PRAMDAC_TV_HSKEW				0x00680730
+#define NV_PRAMDAC_TV_HSYNC_DELAY			0x00680734
+#define NV_PRAMDAC_TV_HSYNC_DELAY2			0x00680738
+
+#define NV_PRAMDAC_TV_SETUP                             0x00680700
+
+#define NV_PRAMDAC_FP_VDISPLAY_END			0x00680800
+#define NV_PRAMDAC_FP_VTOTAL				0x00680804
+#define NV_PRAMDAC_FP_VCRTC				0x00680808
+#define NV_PRAMDAC_FP_VSYNC_START			0x0068080c
+#define NV_PRAMDAC_FP_VSYNC_END				0x00680810
+#define NV_PRAMDAC_FP_VVALID_START			0x00680814
+#define NV_PRAMDAC_FP_VVALID_END			0x00680818
+#define NV_PRAMDAC_FP_HDISPLAY_END			0x00680820
+#define NV_PRAMDAC_FP_HTOTAL				0x00680824
+#define NV_PRAMDAC_FP_HCRTC				0x00680828
+#define NV_PRAMDAC_FP_HSYNC_START			0x0068082c
+#define NV_PRAMDAC_FP_HSYNC_END				0x00680830
+#define NV_PRAMDAC_FP_HVALID_START			0x00680834
+#define NV_PRAMDAC_FP_HVALID_END			0x00680838
+
+#define NV_RAMDAC_FP_DITHER				0x0068083c
+#define NV_PRAMDAC_FP_TG_CONTROL			0x00680848
+#	define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS		(1 << 0)
+#	define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE		(2 << 0)
+#	define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS		(1 << 4)
+#	define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE		(2 << 4)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE		(0 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER		(1 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE		(2 << 8)
+#	define NV_PRAMDAC_FP_TG_CONTROL_READ_PROG		(1 << 20)
+#	define NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12		(1 << 24)
+#	define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS		(1 << 28)
+#	define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE		(2 << 28)
+#define NV_PRAMDAC_FP_MARGIN_COLOR			0x0068084c
+#define NV_PRAMDAC_850					0x00680850
+#define NV_PRAMDAC_85C					0x0068085c
+#define NV_PRAMDAC_FP_DEBUG_0				0x00680880
+#	define NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE		(1 << 0)
+#	define NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE		(1 << 4)
+/* This doesn't seem to be essential for tmds, but still often set */
+#	define NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED		(8 << 4)
+#	define NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR		(1 << 8)
+#	define NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR		(1 << 12)
+#	define NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND		(1 << 20)
+#	define NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND		(1 << 24)
+#       define NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK              (1 << 28)
+#define NV_PRAMDAC_FP_DEBUG_1				0x00680884
+#	define NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE		11:0
+#	define NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE	(1 << 12)
+#	define NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE		27:16
+#	define NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE	(1 << 28)
+#define NV_PRAMDAC_FP_DEBUG_2				0x00680888
+#define NV_PRAMDAC_FP_DEBUG_3				0x0068088C
+
+/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */
+#define NV_PRAMDAC_FP_TMDS_CONTROL			0x006808b0
+#	define NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE		(1 << 16)
+#define NV_PRAMDAC_FP_TMDS_DATA				0x006808b4
+
+#define NV_PRAMDAC_8C0                                  0x006808c0
+
+/* Some kind of switch */
+#define NV_PRAMDAC_900					0x00680900
+#define NV_PRAMDAC_A20					0x00680A20
+#define NV_PRAMDAC_A24					0x00680A24
+#define NV_PRAMDAC_A34					0x00680A34
+
+#define NV_PRAMDAC_CTV					0x00680c00
+
+/* names fabricated from NV_USER_DAC info */
+#define NV_PRMDIO_PIXEL_MASK		0x006813c6
+#	define NV_PRMDIO_PIXEL_MASK_MASK	0xff
+#define NV_PRMDIO_READ_MODE_ADDRESS	0x006813c7
+#define NV_PRMDIO_WRITE_MODE_ADDRESS	0x006813c8
+#define NV_PRMDIO_PALETTE_DATA		0x006813c9
+
+#define NV_PGRAPH_DEBUG_0		0x00400080
+#define NV_PGRAPH_DEBUG_1		0x00400084
+#define NV_PGRAPH_DEBUG_2_NV04		0x00400088
+#define NV_PGRAPH_DEBUG_2		0x00400620
+#define NV_PGRAPH_DEBUG_3		0x0040008c
+#define NV_PGRAPH_DEBUG_4		0x00400090
+#define NV_PGRAPH_INTR			0x00400100
+#define NV_PGRAPH_INTR_EN		0x00400140
+#define NV_PGRAPH_CTX_CONTROL		0x00400144
+#define NV_PGRAPH_CTX_CONTROL_NV04	0x00400170
+#define NV_PGRAPH_ABS_UCLIP_XMIN	0x0040053C
+#define NV_PGRAPH_ABS_UCLIP_YMIN	0x00400540
+#define NV_PGRAPH_ABS_UCLIP_XMAX	0x00400544
+#define NV_PGRAPH_ABS_UCLIP_YMAX	0x00400548
+#define NV_PGRAPH_BETA_AND		0x00400608
+#define NV_PGRAPH_LIMIT_VIOL_PIX	0x00400610
+#define NV_PGRAPH_BOFFSET0		0x00400640
+#define NV_PGRAPH_BOFFSET1		0x00400644
+#define NV_PGRAPH_BOFFSET2		0x00400648
+#define NV_PGRAPH_BLIMIT0		0x00400684
+#define NV_PGRAPH_BLIMIT1		0x00400688
+#define NV_PGRAPH_BLIMIT2		0x0040068c
+#define NV_PGRAPH_STATUS		0x00400700
+#define NV_PGRAPH_SURFACE		0x00400710
+#define NV_PGRAPH_STATE			0x00400714
+#define NV_PGRAPH_FIFO			0x00400720
+#define NV_PGRAPH_PATTERN_SHAPE		0x00400810
+#define NV_PGRAPH_TILE			0x00400b00
+
+#define NV_PVIDEO_INTR_EN		0x00008140
+#define NV_PVIDEO_BUFFER		0x00008700
+#define NV_PVIDEO_STOP			0x00008704
+#define NV_PVIDEO_UVPLANE_BASE(buff)	(0x00008800+(buff)*4)
+#define NV_PVIDEO_UVPLANE_LIMIT(buff)	(0x00008808+(buff)*4)
+#define NV_PVIDEO_UVPLANE_OFFSET_BUFF(buff)	(0x00008820+(buff)*4)
+#define NV_PVIDEO_BASE(buff)		(0x00008900+(buff)*4)
+#define NV_PVIDEO_LIMIT(buff)		(0x00008908+(buff)*4)
+#define NV_PVIDEO_LUMINANCE(buff)	(0x00008910+(buff)*4)
+#define NV_PVIDEO_CHROMINANCE(buff)	(0x00008918+(buff)*4)
+#define NV_PVIDEO_OFFSET_BUFF(buff)	(0x00008920+(buff)*4)
+#define NV_PVIDEO_SIZE_IN(buff)		(0x00008928+(buff)*4)
+#define NV_PVIDEO_POINT_IN(buff)	(0x00008930+(buff)*4)
+#define NV_PVIDEO_DS_DX(buff)		(0x00008938+(buff)*4)
+#define NV_PVIDEO_DT_DY(buff)		(0x00008940+(buff)*4)
+#define NV_PVIDEO_POINT_OUT(buff)	(0x00008948+(buff)*4)
+#define NV_PVIDEO_SIZE_OUT(buff)	(0x00008950+(buff)*4)
+#define NV_PVIDEO_FORMAT(buff)		(0x00008958+(buff)*4)
+#	define NV_PVIDEO_FORMAT_PLANAR			(1 << 0)
+#	define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8	(1 << 16)
+#	define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY	(1 << 20)
+#	define NV_PVIDEO_FORMAT_MATRIX_ITURBT709	(1 << 24)
+#define NV_PVIDEO_COLOR_KEY		0x00008B00
+
+/* NV04 overlay defines from VIDIX & Haiku */
+#define NV_PVIDEO_INTR_EN_0		0x00680140
+#define NV_PVIDEO_STEP_SIZE		0x00680200
+#define NV_PVIDEO_CONTROL_Y		0x00680204
+#define NV_PVIDEO_CONTROL_X		0x00680208
+#define NV_PVIDEO_BUFF0_START_ADDRESS	0x0068020c
+#define NV_PVIDEO_BUFF0_PITCH_LENGTH	0x00680214
+#define NV_PVIDEO_BUFF0_OFFSET		0x0068021c
+#define NV_PVIDEO_BUFF1_START_ADDRESS	0x00680210
+#define NV_PVIDEO_BUFF1_PITCH_LENGTH	0x00680218
+#define NV_PVIDEO_BUFF1_OFFSET		0x00680220
+#define NV_PVIDEO_OE_STATE		0x00680224
+#define NV_PVIDEO_SU_STATE		0x00680228
+#define NV_PVIDEO_RM_STATE		0x0068022c
+#define NV_PVIDEO_WINDOW_START		0x00680230
+#define NV_PVIDEO_WINDOW_SIZE		0x00680234
+#define NV_PVIDEO_FIFO_THRES_SIZE	0x00680238
+#define NV_PVIDEO_FIFO_BURST_LENGTH	0x0068023c
+#define NV_PVIDEO_KEY			0x00680240
+#define NV_PVIDEO_OVERLAY		0x00680244
+#define NV_PVIDEO_RED_CSC_OFFSET	0x00680280
+#define NV_PVIDEO_GREEN_CSC_OFFSET	0x00680284
+#define NV_PVIDEO_BLUE_CSC_OFFSET	0x00680288
+#define NV_PVIDEO_CSC_ADJUST		0x0068028c
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/r128/r128_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/r128/r128_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,7 +64,7 @@ static struct drm_driver driver = {
 		.owner = THIS_MODULE,
 		.open = drm_open,
 		.release = drm_release,
-		.ioctl = drm_ioctl,
+		.unlocked_ioctl = drm_ioctl,
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/r128/r128_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/r128/r128_ioc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/r128/r128_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -95,8 +95,7 @@ static int compat_r128_init(struct file
 			  &init->agp_textures_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_R128_INIT, (unsigned long)init);
+	return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init);
 }
 
 typedef struct drm_r128_depth32 {
@@ -129,8 +128,7 @@ static int compat_r128_depth(struct file
 			  &depth->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
+	return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
 
 }
 
@@ -153,8 +151,7 @@ static int compat_r128_stipple(struct fi
 			  &stipple->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
+	return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
 }
 
 typedef struct drm_r128_getparam32 {
@@ -178,8 +175,7 @@ static int compat_r128_getparam(struct f
 			  &getparam->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+	return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
 }
 
 drm_ioctl_compat_t *r128_compat_ioctls[] = {
@@ -210,12 +206,10 @@ long r128_compat_ioctl(struct file *filp
 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))
 		fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-	lock_kernel();		/* XXX for now */
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_crtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc
 {
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
@@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc
 		if (ASIC_IS_DCE3(rdev))
 			atombios_enable_crtc_memreq(crtc, 1);
 		atombios_blank_crtc(crtc, 0);
+		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+		radeon_crtc_load_lut(crtc);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
+		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
 		atombios_blank_crtc(crtc, 1);
 		if (ASIC_IS_DCE3(rdev))
 			atombios_enable_crtc_memreq(crtc, 0);
 		atombios_enable_crtc(crtc, 0);
 		break;
 	}
-
-	if (mode != DRM_MODE_DPMS_OFF) {
-		radeon_crtc_load_lut(crtc);
-	}
 }
 
 static void
@@ -307,7 +307,6 @@ atombios_set_crtc_dtd_timing(struct drm_
 	args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
 	args.ucCRTC = radeon_crtc->crtc_id;
 
-	printk("executing set crtc dtd timing\n");
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
@@ -347,7 +346,6 @@ static void atombios_crtc_set_timing(str
 	args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
 	args.ucCRTC = radeon_crtc->crtc_id;
 
-	printk("executing set crtc timing\n");
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
@@ -409,60 +407,57 @@ static void atombios_set_ss(struct drm_c
 	}
 }
 
-void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+union adjust_pixel_clock {
+	ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
+};
+
+static u32 atombios_adjust_pll(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct radeon_pll *pll)
 {
-	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_encoder *encoder = NULL;
 	struct radeon_encoder *radeon_encoder = NULL;
-	uint8_t frev, crev;
-	int index;
-	SET_PIXEL_CLOCK_PS_ALLOCATION args;
-	PIXEL_CLOCK_PARAMETERS *spc1_ptr;
-	PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
-	PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
-	uint32_t pll_clock = mode->clock;
-	uint32_t adjusted_clock;
-	uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
-	struct radeon_pll *pll;
-	int pll_flags = 0;
+	u32 adjusted_clock = mode->clock;
 
-	memset(&args, 0, sizeof(args));
+	/* reset the pll flags */
+	pll->flags = 0;
 
 	if (ASIC_IS_AVIVO(rdev)) {
 		if ((rdev->family == CHIP_RS600) ||
 		    (rdev->family == CHIP_RS690) ||
 		    (rdev->family == CHIP_RS740))
-			pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
-				      RADEON_PLL_PREFER_CLOSEST_LOWER);
+			pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
+				       RADEON_PLL_PREFER_CLOSEST_LOWER);
 
 		if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)	/* range limits??? */
-			pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
 		else
-			pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
 	} else {
-		pll_flags |= RADEON_PLL_LEGACY;
+		pll->flags |= RADEON_PLL_LEGACY;
 
 		if (mode->clock > 200000)	/* range limits??? */
-			pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
 		else
-			pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
 
 	}
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
-			if (!ASIC_IS_AVIVO(rdev)) {
-				if (encoder->encoder_type !=
-				    DRM_MODE_ENCODER_DAC)
-					pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
-				if (!ASIC_IS_AVIVO(rdev)
-				    && (encoder->encoder_type ==
-					DRM_MODE_ENCODER_LVDS))
-					pll_flags |= RADEON_PLL_USE_REF_DIV;
-			}
 			radeon_encoder = to_radeon_encoder(encoder);
+			if (ASIC_IS_AVIVO(rdev)) {
+				/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
+				if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
+					adjusted_clock = mode->clock * 2;
+			} else {
+				if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
+					pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
+				if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
+					pll->flags |= RADEON_PLL_USE_REF_DIV;
+			}
 			break;
 		}
 	}
@@ -472,36 +467,101 @@ void atombios_crtc_set_pll(struct drm_cr
 	 * special hw requirements.
 	 */
 	if (ASIC_IS_DCE3(rdev)) {
-		ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args;
-
-		if (!encoder)
-			return;
+		union adjust_pixel_clock args;
+		struct radeon_encoder_atom_dig *dig;
+		u8 frev, crev;
+		int index;
 
-		memset(&adjust_pll_args, 0, sizeof(adjust_pll_args));
-		adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10);
-		adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id;
-		adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
+		if (!radeon_encoder->enc_priv)
+			return adjusted_clock;
+		dig = radeon_encoder->enc_priv;
 
 		index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
-		atom_execute_table(rdev->mode_info.atom_context,
-				   index, (uint32_t *)&adjust_pll_args);
-		adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10;
-	} else {
-		/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
-		if (ASIC_IS_AVIVO(rdev) &&
-		    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))
-			adjusted_clock = mode->clock * 2;
-		else
-			adjusted_clock = mode->clock;
+		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+				      &crev);
+
+		memset(&args, 0, sizeof(args));
+
+		switch (frev) {
+		case 1:
+			switch (crev) {
+			case 1:
+			case 2:
+				args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
+				args.v1.ucTransmitterID = radeon_encoder->encoder_id;
+				args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder);
+
+				atom_execute_table(rdev->mode_info.atom_context,
+						   index, (uint32_t *)&args);
+				adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
+				break;
+			default:
+				DRM_ERROR("Unknown table version %d %d\n", frev, crev);
+				return adjusted_clock;
+			}
+			break;
+		default:
+			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
+			return adjusted_clock;
+		}
+	}
+	return adjusted_clock;
+}
+
+union set_pixel_clock {
+	SET_PIXEL_CLOCK_PS_ALLOCATION base;
+	PIXEL_CLOCK_PARAMETERS v1;
+	PIXEL_CLOCK_PARAMETERS_V2 v2;
+	PIXEL_CLOCK_PARAMETERS_V3 v3;
+};
+
+void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_encoder *encoder = NULL;
+	struct radeon_encoder *radeon_encoder = NULL;
+	u8 frev, crev;
+	int index;
+	union set_pixel_clock args;
+	u32 pll_clock = mode->clock;
+	u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
+	struct radeon_pll *pll;
+	u32 adjusted_clock;
+
+	memset(&args, 0, sizeof(args));
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (encoder->crtc == crtc) {
+			radeon_encoder = to_radeon_encoder(encoder);
+			break;
+		}
 	}
 
+	if (!radeon_encoder)
+		return;
+
 	if (radeon_crtc->crtc_id == 0)
 		pll = &rdev->clock.p1pll;
 	else
 		pll = &rdev->clock.p2pll;
 
-	radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-			   &ref_div, &post_div, pll_flags);
+	/* adjust pixel clock as needed */
+	adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
+
+	if (ASIC_IS_AVIVO(rdev)) {
+		if (radeon_new_pll)
+			radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
+						 &fb_div, &frac_fb_div,
+						 &ref_div, &post_div);
+		else
+			radeon_compute_pll(pll, adjusted_clock, &pll_clock,
+					   &fb_div, &frac_fb_div,
+					   &ref_div, &post_div);
+	} else
+		radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+				   &ref_div, &post_div);
 
 	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
 	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
@@ -511,45 +571,38 @@ void atombios_crtc_set_pll(struct drm_cr
 	case 1:
 		switch (crev) {
 		case 1:
-			spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput;
-			spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
-			spc1_ptr->usRefDiv = cpu_to_le16(ref_div);
-			spc1_ptr->usFbDiv = cpu_to_le16(fb_div);
-			spc1_ptr->ucFracFbDiv = frac_fb_div;
-			spc1_ptr->ucPostDiv = post_div;
-			spc1_ptr->ucPpll =
+			args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
+			args.v1.usRefDiv = cpu_to_le16(ref_div);
+			args.v1.usFbDiv = cpu_to_le16(fb_div);
+			args.v1.ucFracFbDiv = frac_fb_div;
+			args.v1.ucPostDiv = post_div;
+			args.v1.ucPpll =
 			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-			spc1_ptr->ucCRTC = radeon_crtc->crtc_id;
-			spc1_ptr->ucRefDivSrc = 1;
+			args.v1.ucCRTC = radeon_crtc->crtc_id;
+			args.v1.ucRefDivSrc = 1;
 			break;
 		case 2:
-			spc2_ptr =
-			    (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput;
-			spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
-			spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
-			spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
-			spc2_ptr->ucFracFbDiv = frac_fb_div;
-			spc2_ptr->ucPostDiv = post_div;
-			spc2_ptr->ucPpll =
+			args.v2.usPixelClock = cpu_to_le16(mode->clock / 10);
+			args.v2.usRefDiv = cpu_to_le16(ref_div);
+			args.v2.usFbDiv = cpu_to_le16(fb_div);
+			args.v2.ucFracFbDiv = frac_fb_div;
+			args.v2.ucPostDiv = post_div;
+			args.v2.ucPpll =
 			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-			spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
-			spc2_ptr->ucRefDivSrc = 1;
+			args.v2.ucCRTC = radeon_crtc->crtc_id;
+			args.v2.ucRefDivSrc = 1;
 			break;
 		case 3:
-			if (!encoder)
-				return;
-			spc3_ptr =
-			    (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput;
-			spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10);
-			spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
-			spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
-			spc3_ptr->ucFracFbDiv = frac_fb_div;
-			spc3_ptr->ucPostDiv = post_div;
-			spc3_ptr->ucPpll =
+			args.v3.usPixelClock = cpu_to_le16(mode->clock / 10);
+			args.v3.usRefDiv = cpu_to_le16(ref_div);
+			args.v3.usFbDiv = cpu_to_le16(fb_div);
+			args.v3.ucFracFbDiv = frac_fb_div;
+			args.v3.ucPostDiv = post_div;
+			args.v3.ucPpll =
 			    radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-			spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
-			spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id;
-			spc3_ptr->ucEncoderMode =
+			args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
+			args.v3.ucTransmitterId = radeon_encoder->encoder_id;
+			args.v3.ucEncoderMode =
 			    atombios_get_encoder_mode(encoder);
 			break;
 		default:
@@ -562,33 +615,43 @@ void atombios_crtc_set_pll(struct drm_cr
 		return;
 	}
 
-	printk("executing set pll\n");
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
-			   struct drm_framebuffer *old_fb)
+static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
+			       struct drm_framebuffer *old_fb)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_framebuffer *radeon_fb;
 	struct drm_gem_object *obj;
-	struct drm_radeon_gem_object *obj_priv;
+	struct radeon_bo *rbo;
 	uint64_t fb_location;
 	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+	int r;
 
-	if (!crtc->fb)
-		return -EINVAL;
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
 
 	radeon_fb = to_radeon_framebuffer(crtc->fb);
 
+	/* Pin framebuffer & get tilling informations */
 	obj = radeon_fb->obj;
-	obj_priv = obj->driver_private;
-
-	if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
+	rbo = obj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
+	if (unlikely(r != 0)) {
+		radeon_bo_unreserve(rbo);
 		return -EINVAL;
 	}
+	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(rbo);
 
 	switch (crtc->fb->bits_per_pixel) {
 	case 8:
@@ -618,8 +681,6 @@ int atombios_crtc_set_base(struct drm_cr
 		return -EINVAL;
 	}
 
-	radeon_object_get_tiling_flags(obj->driver_private,
-				       &tiling_flags, NULL);
 	if (tiling_flags & RADEON_TILING_MACRO)
 		fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 
@@ -674,7 +735,12 @@ int atombios_crtc_set_base(struct drm_cr
 
 	if (old_fb && old_fb != crtc->fb) {
 		radeon_fb = to_radeon_framebuffer(old_fb);
-		radeon_gem_object_unpin(radeon_fb->obj);
+		rbo = radeon_fb->obj->driver_private;
+		r = radeon_bo_reserve(rbo, false);
+		if (unlikely(r != 0))
+			return r;
+		radeon_bo_unpin(rbo);
+		radeon_bo_unreserve(rbo);
 	}
 
 	/* Bytes per pixel may have changed */
@@ -683,6 +749,42 @@ int atombios_crtc_set_base(struct drm_cr
 	return 0;
 }
 
+int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
+			   struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (ASIC_IS_AVIVO(rdev))
+		return avivo_crtc_set_base(crtc, x, y, old_fb);
+	else
+		return radeon_crtc_set_base(crtc, x, y, old_fb);
+}
+
+/* properly set additional regs when using atombios */
+static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	u32 disp_merge_cntl;
+
+	switch (radeon_crtc->crtc_id) {
+	case 0:
+		disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
+		disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+		WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
+		break;
+	case 1:
+		disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
+		disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
+		WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
+		WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
+		WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
+		break;
+	}
+}
+
 int atombios_crtc_mode_set(struct drm_crtc *crtc,
 			   struct drm_display_mode *mode,
 			   struct drm_display_mode *adjusted_mode,
@@ -704,8 +806,8 @@ int atombios_crtc_mode_set(struct drm_cr
 	else {
 		if (radeon_crtc->crtc_id == 0)
 			atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
-		radeon_crtc_set_base(crtc, x, y, old_fb);
-		radeon_legacy_atom_set_surface(crtc);
+		atombios_crtc_set_base(crtc, x, y, old_fb);
+		radeon_legacy_atom_fixup(crtc);
 	}
 	atombios_overscan_setup(crtc, mode, adjusted_mode);
 	atombios_scaler_setup(crtc);
@@ -723,8 +825,8 @@ static bool atombios_crtc_mode_fixup(str
 
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
-	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 	atombios_lock_crtc(crtc, 1);
+	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void atombios_crtc_commit(struct drm_crtc *crtc)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios_dp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_dp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios_dp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios_dp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,789 @@
+/*
+ * Copyright 2007-8 Advanced Micro Devices, Inc.
+ * Copyright 2008 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: Dave Airlie
+ *          Alex Deucher
+ */
+#include "drmP.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+
+#include "atom.h"
+#include "atom-bits.h"
+#include "drm_dp_helper.h"
+
+/* move these to drm_dp_helper.c/h */
+#define DP_LINK_CONFIGURATION_SIZE 9
+#define DP_LINK_STATUS_SIZE	   6
+#define DP_DPCD_SIZE	           8
+
+static char *voltage_names[] = {
+        "0.4V", "0.6V", "0.8V", "1.2V"
+};
+static char *pre_emph_names[] = {
+        "0dB", "3.5dB", "6dB", "9.5dB"
+};
+
+static const int dp_clocks[] = {
+	54000,  /* 1 lane, 1.62 Ghz */
+	90000,  /* 1 lane, 2.70 Ghz */
+	108000, /* 2 lane, 1.62 Ghz */
+	180000, /* 2 lane, 2.70 Ghz */
+	216000, /* 4 lane, 1.62 Ghz */
+	360000, /* 4 lane, 2.70 Ghz */
+};
+
+static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
+
+/* common helper functions */
+static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int i;
+	u8 max_link_bw;
+	u8 max_lane_count;
+
+	if (!dpcd)
+		return 0;
+
+	max_link_bw = dpcd[DP_MAX_LINK_RATE];
+	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	default:
+		for (i = 0; i < num_dp_clocks; i++) {
+			if (i % 2)
+				continue;
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock) {
+				if (i < 2)
+					return 1;
+				else if (i < 4)
+					return 2;
+				else
+					return 4;
+			}
+		}
+		break;
+	case DP_LINK_BW_2_7:
+		for (i = 0; i < num_dp_clocks; i++) {
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock) {
+				if (i < 2)
+					return 1;
+				else if (i < 4)
+					return 2;
+				else
+					return 4;
+			}
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int i;
+	u8 max_link_bw;
+	u8 max_lane_count;
+
+	if (!dpcd)
+		return 0;
+
+	max_link_bw = dpcd[DP_MAX_LINK_RATE];
+	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+
+	switch (max_link_bw) {
+	case DP_LINK_BW_1_62:
+	default:
+		for (i = 0; i < num_dp_clocks; i++) {
+			if (i % 2)
+				continue;
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock)
+				return 162000;
+		}
+		break;
+	case DP_LINK_BW_2_7:
+		for (i = 0; i < num_dp_clocks; i++) {
+			switch (max_lane_count) {
+			case 1:
+				if (i > 1)
+					return 0;
+				break;
+			case 2:
+				if (i > 3)
+					return 0;
+				break;
+			case 4:
+			default:
+				break;
+			}
+			if (dp_clocks[i] > mode_clock)
+				return (i % 2) ? 270000 : 162000;
+		}
+	}
+
+	return 0;
+}
+
+int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+{
+	int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
+	int bw = dp_lanes_for_mode_clock(dpcd, mode_clock);
+
+	if ((lanes == 0) || (bw == 0))
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
+{
+	return link_status[r - DP_LANE0_1_STATUS];
+}
+
+static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
+			     int lane)
+{
+	int i = DP_LANE0_1_STATUS + (lane >> 1);
+	int s = (lane & 1) * 4;
+	u8 l = dp_link_status(link_status, i);
+	return (l >> s) & 0xf;
+}
+
+static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
+				 int lane_count)
+{
+	int lane;
+	u8 lane_status;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = dp_get_lane_status(link_status, lane);
+		if ((lane_status & DP_LANE_CR_DONE) == 0)
+			return false;
+	}
+	return true;
+}
+
+static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
+			     int lane_count)
+{
+	u8 lane_align;
+	u8 lane_status;
+	int lane;
+
+	lane_align = dp_link_status(link_status,
+				    DP_LANE_ALIGN_STATUS_UPDATED);
+	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
+		return false;
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = dp_get_lane_status(link_status, lane);
+		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
+			return false;
+	}
+	return true;
+}
+
+static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+					int lane)
+
+{
+	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int s = ((lane & 1) ?
+		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
+		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
+	u8 l = dp_link_status(link_status, i);
+
+	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
+}
+
+static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+					     int lane)
+{
+	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+	int s = ((lane & 1) ?
+		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
+		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
+	u8 l = dp_link_status(link_status, i);
+
+	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+}
+
+/* XXX fix me -- chip specific */
+#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
+static u8 dp_pre_emphasis_max(u8 voltage_swing)
+{
+	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_400:
+		return DP_TRAIN_PRE_EMPHASIS_6;
+	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;
+	}
+}
+
+static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
+				int lane_count,
+				u8 train_set[4])
+{
+	u8 v = 0;
+	u8 p = 0;
+	int lane;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
+		u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
+
+		DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n",
+			  lane,
+			  voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
+			  pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
+
+		if (this_v > v)
+			v = this_v;
+		if (this_p > p)
+			p = this_p;
+	}
+
+	if (v >= DP_VOLTAGE_MAX)
+		v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+
+	if (p >= dp_pre_emphasis_max(v))
+		p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+	DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n",
+		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
+		  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
+
+	for (lane = 0; lane < 4; lane++)
+		train_set[lane] = v | p;
+}
+
+
+/* radeon aux chan functions */
+bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
+			   int num_bytes, u8 *read_byte,
+			   u8 read_buf_len, u8 delay)
+{
+	struct drm_device *dev = chan->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
+	unsigned char *base;
+	int retry_count = 0;
+
+	memset(&args, 0, sizeof(args));
+
+	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
+
+retry:
+	memcpy(base, req_bytes, num_bytes);
+
+	args.lpAuxRequest = 0;
+	args.lpDataOut = 16;
+	args.ucDataOutLen = 0;
+	args.ucChannelID = chan->rec.i2c_id;
+	args.ucDelay = delay / 10;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	if (args.ucReplyStatus && !args.ucDataOutLen) {
+		if (args.ucReplyStatus == 0x20 && retry_count++ < 10)
+			goto retry;
+		DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
+			  req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
+			  chan->rec.i2c_id, args.ucReplyStatus, retry_count);
+		return false;
+	}
+
+	if (args.ucDataOutLen && read_byte && read_buf_len) {
+		if (read_buf_len < args.ucDataOutLen) {
+			DRM_ERROR("Buffer to small for return answer %d %d\n",
+				  read_buf_len, args.ucDataOutLen);
+			return false;
+		}
+		{
+			int len = min(read_buf_len, args.ucDataOutLen);
+			memcpy(read_byte, base + 16, len);
+		}
+	}
+	return true;
+}
+
+bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
+				uint8_t send_bytes, uint8_t *send)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[20];
+	u8 msg_len, dp_msg_len;
+	bool ret;
+
+	dp_msg_len = 4;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_WRITE << 4;
+	dp_msg_len += send_bytes;
+	msg[3] = (dp_msg_len << 4) | (send_bytes - 1);
+
+	if (send_bytes > 16)
+		return false;
+
+	memcpy(&msg[4], send, send_bytes);
+	msg_len = 4 + send_bytes;
+	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
+	return ret;
+}
+
+bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
+			       uint8_t delay, uint8_t expected_bytes,
+			       uint8_t *read_p)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[20];
+	u8 msg_len, dp_msg_len;
+	bool ret = false;
+	msg_len = 4;
+	dp_msg_len = 4;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_READ << 4;
+	msg[3] = (dp_msg_len) << 4;
+	msg[3] |= expected_bytes - 1;
+
+	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
+	return ret;
+}
+
+/* radeon dp functions */
+static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
+				    uint8_t ucconfig, uint8_t lane_num)
+{
+	DP_ENCODER_SERVICE_PARAMETERS args;
+	int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
+
+	memset(&args, 0, sizeof(args));
+	args.ucLinkClock = dp_clock / 10;
+	args.ucConfig = ucconfig;
+	args.ucAction = action;
+	args.ucLaneNum = lane_num;
+	args.ucStatus = 0;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+	return args.ucStatus;
+}
+
+u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	struct drm_device *dev = radeon_connector->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
+					 dig_connector->dp_i2c_bus->rec.i2c_id, 0);
+}
+
+bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[25];
+	int ret;
+
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
+	if (ret) {
+		memcpy(dig_connector->dpcd, msg, 8);
+		{
+			int i;
+			DRM_DEBUG("DPCD: ");
+			for (i = 0; i < 8; i++)
+				DRM_DEBUG("%02x ", msg[i]);
+			DRM_DEBUG("\n");
+		}
+		return true;
+	}
+	dig_connector->dpcd[0] = 0;
+	return false;
+}
+
+void radeon_dp_set_link_config(struct drm_connector *connector,
+			       struct drm_display_mode *mode)
+{
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+
+	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
+	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
+		return;
+
+	radeon_connector = to_radeon_connector(connector);
+	if (!radeon_connector->con_priv)
+		return;
+	dig_connector = radeon_connector->con_priv;
+
+	dig_connector->dp_clock =
+		dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock);
+	dig_connector->dp_lane_count =
+		dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock);
+}
+
+int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+				struct drm_display_mode *mode)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+
+	return dp_mode_valid(dig_connector->dpcd, mode->clock);
+}
+
+static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
+				    u8 link_status[DP_LINK_STATUS_SIZE])
+{
+	int ret;
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
+					DP_LINK_STATUS_SIZE, link_status);
+	if (!ret) {
+		DRM_ERROR("displayport link status failed\n");
+		return false;
+	}
+
+	DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n",
+		  link_status[0], link_status[1], link_status[2],
+		  link_status[3], link_status[4], link_status[5]);
+	return true;
+}
+
+bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (!atom_dp_get_link_status(radeon_connector, link_status))
+		return false;
+	if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
+		return false;
+	return true;
+}
+
+static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+
+	if (dig_connector->dpcd[0] >= 0x11) {
+		radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
+					   &power_state);
+	}
+}
+
+static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread)
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1,
+				   &downspread);
+}
+
+static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector,
+				 u8 link_configuration[DP_LINK_CONFIGURATION_SIZE])
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2,
+				   link_configuration);
+}
+
+static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
+				struct drm_encoder *encoder,
+				u8 train_set[4])
+{
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	int i;
+
+	for (i = 0; i < dig_connector->dp_lane_count; i++)
+		atombios_dig_transmitter_setup(encoder,
+					       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
+					       i, train_set[i]);
+
+	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
+				   dig_connector->dp_lane_count, train_set);
+}
+
+static void dp_set_training(struct radeon_connector *radeon_connector,
+			    u8 training)
+{
+	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
+				   1, &training);
+}
+
+void dp_link_train(struct drm_encoder *encoder,
+		   struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig;
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+	int enc_id = 0;
+	bool clock_recovery, channel_eq;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	u8 link_configuration[DP_LINK_CONFIGURATION_SIZE];
+	u8 tries, voltage;
+	u8 train_set[4];
+	int i;
+
+	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
+	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
+		return;
+
+	if (!radeon_encoder->enc_priv)
+		return;
+	dig = radeon_encoder->enc_priv;
+
+	radeon_connector = to_radeon_connector(connector);
+	if (!radeon_connector->con_priv)
+		return;
+	dig_connector = radeon_connector->con_priv;
+
+	if (dig->dig_encoder)
+		enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
+	else
+		enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
+	if (dig_connector->linkb)
+		enc_id |= ATOM_DP_CONFIG_LINK_B;
+	else
+		enc_id |= ATOM_DP_CONFIG_LINK_A;
+
+	memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+	if (dig_connector->dp_clock == 270000)
+		link_configuration[0] = DP_LINK_BW_2_7;
+	else
+		link_configuration[0] = DP_LINK_BW_1_62;
+	link_configuration[1] = dig_connector->dp_lane_count;
+	if (dig_connector->dpcd[0] >= 0x11)
+		link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	/* power up the sink */
+	dp_set_power(radeon_connector, DP_SET_POWER_D0);
+	/* disable the training pattern on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+	/* set link bw and lanes on the sink */
+	dp_set_link_bw_lanes(radeon_connector, link_configuration);
+	/* disable downspread on the sink */
+	dp_set_downspread(radeon_connector, 0);
+	/* start training on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
+				  dig_connector->dp_clock, enc_id, 0);
+	/* set training pattern 1 on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+				  dig_connector->dp_clock, enc_id, 0);
+
+	/* set initial vs/emph */
+	memset(train_set, 0, 4);
+	udelay(400);
+	/* set training pattern 1 on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1);
+
+	dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+
+	/* clock recovery loop */
+	clock_recovery = false;
+	tries = 0;
+	voltage = 0xff;
+	for (;;) {
+		udelay(100);
+		if (!atom_dp_get_link_status(radeon_connector, link_status))
+			break;
+
+		if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) {
+			clock_recovery = true;
+			break;
+		}
+
+		for (i = 0; i < dig_connector->dp_lane_count; i++) {
+			if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+				break;
+		}
+		if (i == dig_connector->dp_lane_count) {
+			DRM_ERROR("clock recovery reached max voltage\n");
+			break;
+		}
+
+		if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++tries;
+			if (tries == 5) {
+				DRM_ERROR("clock recovery tried 5 times\n");
+				break;
+			}
+		} else
+			tries = 0;
+
+		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Compute new train_set as requested by sink */
+		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
+		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+	}
+	if (!clock_recovery)
+		DRM_ERROR("clock recovery failed\n");
+	else
+		DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n",
+			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			  DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+
+	/* set training pattern 2 on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
+	/* set training pattern 2 on the source */
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+				  dig_connector->dp_clock, enc_id, 1);
+
+	/* channel equalization loop */
+	tries = 0;
+	channel_eq = false;
+	for (;;) {
+		udelay(400);
+		if (!atom_dp_get_link_status(radeon_connector, link_status))
+			break;
+
+		if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) {
+			channel_eq = true;
+			break;
+		}
+
+		/* Try 5 times */
+		if (tries > 5) {
+			DRM_ERROR("channel eq failed: 5 tries\n");
+			break;
+		}
+
+		/* Compute new train_set as requested by sink */
+		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
+		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+
+		tries++;
+	}
+
+	if (!channel_eq)
+		DRM_ERROR("channel eq failed\n");
+	else
+		DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n",
+			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
+			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+	/* disable the training pattern on the sink */
+	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+
+	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
+				  dig_connector->dp_clock, enc_id, 0);
+}
+
+int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+			 uint8_t write_byte, uint8_t *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
+	int ret = 0;
+	uint16_t address = algo_data->address;
+	uint8_t msg[5];
+	uint8_t reply[2];
+	int msg_len, dp_msg_len;
+	int reply_bytes;
+
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[2] = AUX_I2C_READ << 4;
+	else
+		msg[2] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[2] |= AUX_I2C_MOT << 4;
+
+	msg[0] = address;
+	msg[1] = address >> 8;
+
+	reply_bytes = 1;
+
+	msg_len = 4;
+	dp_msg_len = 3;
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg[4] = write_byte;
+		msg_len++;
+		dp_msg_len += 2;
+		break;
+	case MODE_I2C_READ:
+		dp_msg_len += 1;
+		break;
+	default:
+		break;
+	}
+
+	msg[3] = (dp_msg_len) << 4;
+	ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);
+
+	if (ret) {
+		if (read_byte)
+			*read_byte = reply[0];
+		return reply_bytes;
+	}
+	return -EREMOTEIO;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atombios.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atombios.h	2010-02-24 13:52:17.000000000 -0500
@@ -1141,7 +1141,7 @@ typedef struct _LVDS_ENCODER_CONTROL_PAR
 /* ucTableFormatRevision=1,ucTableContentRevision=2 */
 typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 {
 	USHORT usPixelClock;	/*  in 10KHz; for bios convenient */
-	UCHAR ucMisc;		/*  see PANEL_ENCODER_MISC_xx defintions below */
+	UCHAR ucMisc;		/*  see PANEL_ENCODER_MISC_xx definitions below */
 	UCHAR ucAction;		/*  0: turn off encoder */
 	/*  1: setup and turn on encoder */
 	UCHAR ucTruncate;	/*  bit0=0: Disable truncate */
@@ -1424,7 +1424,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_I
 /*  Structures used in FirmwareInfoTable */
 /****************************************************************************/
 
-/*  usBIOSCapability Defintion: */
+/*  usBIOSCapability Definition: */
 /*  Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */
 /*  Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */
 /*  Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */
@@ -2386,7 +2386,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
 } ATOM_ANALOG_TV_INFO_V1_2;
 
 /**************************************************************************/
-/*  VRAM usage and their defintions */
+/*  VRAM usage and their definitions */
 
 /*  One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */
 /*  Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */
@@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD {
 typedef struct _ATOM_HPD_INT_RECORD {
 	ATOM_COMMON_RECORD_HEADER sheader;
 	UCHAR ucHPDIntGPIOID;	/* Corresponding block in GPIO_PIN_INFO table gives the pin info */
-	UCHAR ucPluggged_PinState;
+	UCHAR ucPlugged_PinState;
 } ATOM_HPD_INT_RECORD;
 
 typedef struct _ATOM_OUTPUT_PROTECTION_RECORD {
@@ -3046,7 +3046,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC     2
 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S0_CRT1_MONOb0             0x01
 #define ATOM_S0_CRT1_COLORb0            0x02
 #define ATOM_S0_CRT1_MASKb0             (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0)
@@ -3131,7 +3131,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30
 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK   0xC0000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S2_TV1_STANDARD_MASKb0     0x0F
 #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF
 #define ATOM_S2_CRT1_DPMS_STATEb2       0x01
@@ -3190,7 +3190,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S3_ALLOW_FAST_PWR_SWITCH   0x40000000L
 #define ATOM_S3_RQST_GPU_USE_MIN_PWR    0x80000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S3_CRT1_ACTIVEb0           0x01
 #define ATOM_S3_LCD1_ACTIVEb0           0x02
 #define ATOM_S3_TV1_ACTIVEb0            0x04
@@ -3230,7 +3230,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S4_LCD1_REFRESH_MASK       0x0000FF00L
 #define ATOM_S4_LCD1_REFRESH_SHIFT      8
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S4_LCD1_PANEL_ID_MASKb0	  0x0FF
 #define ATOM_S4_LCD1_REFRESH_MASKb1		  ATOM_S4_LCD1_PANEL_ID_MASKb0
 #define ATOM_S4_VRAM_INFO_MASKb2        ATOM_S4_LCD1_PANEL_ID_MASKb0
@@ -3310,7 +3310,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_IN
 #define ATOM_S6_VRI_BRIGHTNESS_CHANGE       0x40000000L
 #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK  0x80000000L
 
-/* Byte aligned defintion for BIOS usage */
+/* Byte aligned definition for BIOS usage */
 #define ATOM_S6_DEVICE_CHANGEb0         0x01
 #define ATOM_S6_SCALER_CHANGEb0         0x02
 #define ATOM_S6_LID_CHANGEb0            0x04
@@ -4690,6 +4690,205 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 {
 	ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
 } ATOM_POWERPLAY_INFO_V3;
 
+/* New PPlib */
+/**************************************************************************/
+typedef struct _ATOM_PPLIB_THERMALCONTROLLER
+
+{
+    UCHAR ucType;           // one of ATOM_PP_THERMALCONTROLLER_*
+    UCHAR ucI2cLine;        // as interpreted by DAL I2C
+    UCHAR ucI2cAddress;
+    UCHAR ucFanParameters;  // Fan Control Parameters.
+    UCHAR ucFanMinRPM;      // Fan Minimum RPM (hundreds) -- for display purposes only.
+    UCHAR ucFanMaxRPM;      // Fan Maximum RPM (hundreds) -- for display purposes only.
+    UCHAR ucReserved;       // ----
+    UCHAR ucFlags;          // to be defined
+} ATOM_PPLIB_THERMALCONTROLLER;
+
+#define ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f
+#define ATOM_PP_FANPARAMETERS_NOFAN                                 0x80    // No fan is connected to this controller.
+
+#define ATOM_PP_THERMALCONTROLLER_NONE      0
+#define ATOM_PP_THERMALCONTROLLER_LM63      1  // Not used by PPLib
+#define ATOM_PP_THERMALCONTROLLER_ADM1032   2  // Not used by PPLib
+#define ATOM_PP_THERMALCONTROLLER_ADM1030   3  // Not used by PPLib
+#define ATOM_PP_THERMALCONTROLLER_MUA6649   4  // Not used by PPLib
+#define ATOM_PP_THERMALCONTROLLER_LM64      5
+#define ATOM_PP_THERMALCONTROLLER_F75375    6  // Not used by PPLib
+#define ATOM_PP_THERMALCONTROLLER_RV6xx     7
+#define ATOM_PP_THERMALCONTROLLER_RV770     8
+#define ATOM_PP_THERMALCONTROLLER_ADT7473   9
+
+typedef struct _ATOM_PPLIB_STATE
+{
+    UCHAR ucNonClockStateIndex;
+    UCHAR ucClockStateIndices[1]; // variable-sized
+} ATOM_PPLIB_STATE;
+
+//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
+#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1
+#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2
+#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4
+#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8
+#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16
+#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32
+#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64
+#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128
+#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256
+#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512
+#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024
+#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048
+
+typedef struct _ATOM_PPLIB_POWERPLAYTABLE
+{
+      ATOM_COMMON_TABLE_HEADER sHeader;
+
+      UCHAR ucDataRevision;
+
+      UCHAR ucNumStates;
+      UCHAR ucStateEntrySize;
+      UCHAR ucClockInfoSize;
+      UCHAR ucNonClockSize;
+
+      // offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures
+      USHORT usStateArrayOffset;
+
+      // offset from start of this table to array of ASIC-specific structures,
+      // currently ATOM_PPLIB_CLOCK_INFO.
+      USHORT usClockInfoArrayOffset;
+
+      // offset from start of this table to array of ATOM_PPLIB_NONCLOCK_INFO
+      USHORT usNonClockInfoArrayOffset;
+
+      USHORT usBackbiasTime;    // in microseconds
+      USHORT usVoltageTime;     // in microseconds
+      USHORT usTableSize;       //the size of this structure, or the extended structure
+
+      ULONG ulPlatformCaps;            // See ATOM_PPLIB_CAPS_*
+
+      ATOM_PPLIB_THERMALCONTROLLER    sThermalController;
+
+      USHORT usBootClockInfoOffset;
+      USHORT usBootNonClockInfoOffset;
+
+} ATOM_PPLIB_POWERPLAYTABLE;
+
+//// ATOM_PPLIB_NONCLOCK_INFO::usClassification
+#define ATOM_PPLIB_CLASSIFICATION_UI_MASK          0x0007
+#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT         0
+#define ATOM_PPLIB_CLASSIFICATION_UI_NONE          0
+#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY       1
+#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED      3
+#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE   5
+// 2, 4, 6, 7 are reserved
+
+#define ATOM_PPLIB_CLASSIFICATION_BOOT                   0x0008
+#define ATOM_PPLIB_CLASSIFICATION_THERMAL                0x0010
+#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE     0x0020
+#define ATOM_PPLIB_CLASSIFICATION_REST                   0x0040
+#define ATOM_PPLIB_CLASSIFICATION_FORCED                 0x0080
+#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE          0x0100
+#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE      0x0200
+#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE               0x0400
+#define ATOM_PPLIB_CLASSIFICATION_3DLOW                  0x0800
+#define ATOM_PPLIB_CLASSIFICATION_ACPI                   0x1000
+// remaining 3 bits are reserved
+
+//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings
+#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY           0x00000001
+#define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK         0x00000002
+
+// 0 is 2.5Gb/s, 1 is 5Gb/s
+#define ATOM_PPLIB_PCIE_LINK_SPEED_MASK            0x00000004
+#define ATOM_PPLIB_PCIE_LINK_SPEED_SHIFT           2
+
+// lanes - 1: 1, 2, 4, 8, 12, 16 permitted by PCIE spec
+#define ATOM_PPLIB_PCIE_LINK_WIDTH_MASK            0x000000F8
+#define ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT           3
+
+// lookup into reduced refresh-rate table
+#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK  0x00000F00
+#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT 8
+
+#define ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED    0
+#define ATOM_PPLIB_LIMITED_REFRESHRATE_50HZ         1
+// 2-15 TBD as needed.
+
+#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING        0x00001000
+#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS  0x00002000
+#define ATOM_PPLIB_ENABLE_VARIBRIGHT                     0x00008000
+
+#define ATOM_PPLIB_DISALLOW_ON_DC                       0x00004000
+
+// Contained in an array starting at the offset
+// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset.
+// referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex
+typedef struct _ATOM_PPLIB_NONCLOCK_INFO
+{
+      USHORT usClassification;
+      UCHAR  ucMinTemperature;
+      UCHAR  ucMaxTemperature;
+      ULONG  ulCapsAndSettings;
+      UCHAR  ucRequiredPower;
+      UCHAR  ucUnused1[3];
+} ATOM_PPLIB_NONCLOCK_INFO;
+
+// Contained in an array starting at the offset
+// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset.
+// referenced from ATOM_PPLIB_STATE::ucClockStateIndices
+typedef struct _ATOM_PPLIB_R600_CLOCK_INFO
+{
+      USHORT usEngineClockLow;
+      UCHAR ucEngineClockHigh;
+
+      USHORT usMemoryClockLow;
+      UCHAR ucMemoryClockHigh;
+
+      USHORT usVDDC;
+      USHORT usUnused1;
+      USHORT usUnused2;
+
+      ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_*
+
+} ATOM_PPLIB_R600_CLOCK_INFO;
+
+// ulFlags in ATOM_PPLIB_R600_CLOCK_INFO
+#define ATOM_PPLIB_R600_FLAGS_PCIEGEN2          1
+#define ATOM_PPLIB_R600_FLAGS_UVDSAFE           2
+#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE    4
+#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF    8
+#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF    16
+
+typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO
+
+{
+      USHORT usLowEngineClockLow;         // Low Engine clock in MHz (the same way as on the R600).
+      UCHAR  ucLowEngineClockHigh;
+      USHORT usHighEngineClockLow;        // High Engine clock in MHz.
+      UCHAR  ucHighEngineClockHigh;
+      USHORT usMemoryClockLow;            // For now one of the ATOM_PPLIB_RS780_SPMCLK_XXXX constants.
+      UCHAR  ucMemoryClockHigh;           // Currentyl unused.
+      UCHAR  ucPadding;                   // For proper alignment and size.
+      USHORT usVDDC;                      // For the 780, use: None, Low, High, Variable
+      UCHAR  ucMaxHTLinkWidth;            // From SBIOS - {2, 4, 8, 16}
+      UCHAR  ucMinHTLinkWidth;            // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement.
+      USHORT usHTLinkFreq;                // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200).
+      ULONG  ulFlags;
+} ATOM_PPLIB_RS780_CLOCK_INFO;
+
+#define ATOM_PPLIB_RS780_VOLTAGE_NONE       0
+#define ATOM_PPLIB_RS780_VOLTAGE_LOW        1
+#define ATOM_PPLIB_RS780_VOLTAGE_HIGH       2
+#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE   3
+
+#define ATOM_PPLIB_RS780_SPMCLK_NONE        0   // We cannot change the side port memory clock, leave it as it is.
+#define ATOM_PPLIB_RS780_SPMCLK_LOW         1
+#define ATOM_PPLIB_RS780_SPMCLK_HIGH        2
+
+#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE       0
+#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW        1
+#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH       2
+
 /**************************************************************************/
 
 /*  Following definitions are for compatiblity issue in different SW components. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atom.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <asm/unaligned.h>
 
 #define ATOM_DEBUG
 
@@ -58,6 +59,7 @@ typedef struct {
 } atom_exec_context;
 
 int atom_debug = 0;
+static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
 void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
 
 static uint32_t atom_arg_mask[8] =
@@ -211,7 +213,9 @@ static uint32_t atom_get_src_int(atom_ex
 	case ATOM_ARG_PS:
 		idx = U8(*ptr);
 		(*ptr)++;
-		val = le32_to_cpu(ctx->ps[idx]);
+		/* get_unaligned_le32 avoids unaligned accesses from atombios
+		 * tables, noticed on a DEC Alpha. */
+		val = get_unaligned_le32((u32 *)&ctx->ps[idx]);
 		if (print)
 			DEBUG("PS[0x%02X,0x%04X]", idx, val);
 		break;
@@ -245,6 +249,9 @@ static uint32_t atom_get_src_int(atom_ex
 		case ATOM_WS_ATTRIBUTES:
 			val = gctx->io_attr;
 			break;
+		case ATOM_WS_REGPTR:
+			val = gctx->reg_block;
+			break;
 		default:
 			val = ctx->ws[idx];
 		}
@@ -263,10 +270,10 @@ static uint32_t atom_get_src_int(atom_ex
 	case ATOM_ARG_FB:
 		idx = U8(*ptr);
 		(*ptr)++;
+		val = gctx->scratch[((gctx->fb_base + idx) / 4)];
 		if (print)
 			DEBUG("FB[0x%02X]", idx);
-		printk(KERN_INFO "FB access is not implemented.\n");
-		return 0;
+		break;
 	case ATOM_ARG_IMM:
 		switch (align) {
 		case ATOM_SRC_DWORD:
@@ -384,6 +391,32 @@ static uint32_t atom_get_src(atom_exec_c
 	return atom_get_src_int(ctx, attr, ptr, NULL, 1);
 }
 
+static uint32_t atom_get_src_direct(atom_exec_context *ctx, uint8_t align, int *ptr)
+{
+	uint32_t val = 0xCDCDCDCD;
+
+	switch (align) {
+	case ATOM_SRC_DWORD:
+		val = U32(*ptr);
+		(*ptr) += 4;
+		break;
+	case ATOM_SRC_WORD0:
+	case ATOM_SRC_WORD8:
+	case ATOM_SRC_WORD16:
+		val = U16(*ptr);
+		(*ptr) += 2;
+		break;
+	case ATOM_SRC_BYTE0:
+	case ATOM_SRC_BYTE8:
+	case ATOM_SRC_BYTE16:
+	case ATOM_SRC_BYTE24:
+		val = U8(*ptr);
+		(*ptr)++;
+		break;
+	}
+	return val;
+}
+
 static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr,
 			     int *ptr, uint32_t *saved, int print)
 {
@@ -481,6 +514,9 @@ static void atom_put_dst(atom_exec_conte
 		case ATOM_WS_ATTRIBUTES:
 			gctx->io_attr = val;
 			break;
+		case ATOM_WS_REGPTR:
+			gctx->reg_block = val;
+			break;
 		default:
 			ctx->ws[idx] = val;
 		}
@@ -488,9 +524,9 @@ static void atom_put_dst(atom_exec_conte
 	case ATOM_ARG_FB:
 		idx = U8(*ptr);
 		(*ptr)++;
+		gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
 		DEBUG("FB[0x%02X]", idx);
-		printk(KERN_INFO "FB access is not implemented.\n");
-		return;
+		break;
 	case ATOM_ARG_PLL:
 		idx = U8(*ptr);
 		(*ptr)++;
@@ -573,7 +609,7 @@ static void atom_op_calltable(atom_exec_
 	else
 		SDEBUG("   table: %d\n", idx);
 	if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-		atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+		atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
 }
 
 static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
@@ -607,7 +643,7 @@ static void atom_op_delay(atom_exec_cont
 	uint8_t count = U8((*ptr)++);
 	SDEBUG("   count: %d\n", count);
 	if (arg == ATOM_UNIT_MICROSEC)
-		schedule_timeout_uninterruptible(usecs_to_jiffies(count));
+		udelay(count);
 	else
 		schedule_timeout_uninterruptible(msecs_to_jiffies(count));
 }
@@ -676,7 +712,7 @@ static void atom_op_mask(atom_exec_conte
 	SDEBUG("   dst: ");
 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
 	SDEBUG("   src1: ");
-	src1 = atom_get_src(ctx, attr, ptr);
+	src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr);
 	SDEBUG("   src2: ");
 	src2 = atom_get_src(ctx, attr, ptr);
 	dst &= src1;
@@ -808,6 +844,38 @@ static void atom_op_setregblock(atom_exe
 	SDEBUG("   base: 0x%04X\n", ctx->ctx->reg_block);
 }
 
+static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg)
+{
+	uint8_t attr = U8((*ptr)++), shift;
+	uint32_t saved, dst;
+	int dptr = *ptr;
+	attr &= 0x38;
+	attr |= atom_def_dst[attr >> 3] << 6;
+	SDEBUG("   dst: ");
+	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+	shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
+	SDEBUG("   shift: %d\n", shift);
+	dst <<= shift;
+	SDEBUG("   dst: ");
+	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg)
+{
+	uint8_t attr = U8((*ptr)++), shift;
+	uint32_t saved, dst;
+	int dptr = *ptr;
+	attr &= 0x38;
+	attr |= atom_def_dst[attr >> 3] << 6;
+	SDEBUG("   dst: ");
+	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+	shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
+	SDEBUG("   shift: %d\n", shift);
+	dst >>= shift;
+	SDEBUG("   dst: ");
+	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
 static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
 {
 	uint8_t attr = U8((*ptr)++), shift;
@@ -817,7 +885,7 @@ static void atom_op_shl(atom_exec_contex
 	attr |= atom_def_dst[attr >> 3] << 6;
 	SDEBUG("   dst: ");
 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-	shift = U8((*ptr)++);
+	shift = atom_get_src(ctx, attr, ptr);
 	SDEBUG("   shift: %d\n", shift);
 	dst <<= shift;
 	SDEBUG("   dst: ");
@@ -833,7 +901,7 @@ static void atom_op_shr(atom_exec_contex
 	attr |= atom_def_dst[attr >> 3] << 6;
 	SDEBUG("   dst: ");
 	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-	shift = U8((*ptr)++);
+	shift = atom_get_src(ctx, attr, ptr);
 	SDEBUG("   shift: %d\n", shift);
 	dst >>= shift;
 	SDEBUG("   dst: ");
@@ -936,18 +1004,18 @@ static struct {
 	atom_op_or, ATOM_ARG_FB}, {
 	atom_op_or, ATOM_ARG_PLL}, {
 	atom_op_or, ATOM_ARG_MC}, {
-	atom_op_shl, ATOM_ARG_REG}, {
-	atom_op_shl, ATOM_ARG_PS}, {
-	atom_op_shl, ATOM_ARG_WS}, {
-	atom_op_shl, ATOM_ARG_FB}, {
-	atom_op_shl, ATOM_ARG_PLL}, {
-	atom_op_shl, ATOM_ARG_MC}, {
-	atom_op_shr, ATOM_ARG_REG}, {
-	atom_op_shr, ATOM_ARG_PS}, {
-	atom_op_shr, ATOM_ARG_WS}, {
-	atom_op_shr, ATOM_ARG_FB}, {
-	atom_op_shr, ATOM_ARG_PLL}, {
-	atom_op_shr, ATOM_ARG_MC}, {
+	atom_op_shift_left, ATOM_ARG_REG}, {
+	atom_op_shift_left, ATOM_ARG_PS}, {
+	atom_op_shift_left, ATOM_ARG_WS}, {
+	atom_op_shift_left, ATOM_ARG_FB}, {
+	atom_op_shift_left, ATOM_ARG_PLL}, {
+	atom_op_shift_left, ATOM_ARG_MC}, {
+	atom_op_shift_right, ATOM_ARG_REG}, {
+	atom_op_shift_right, ATOM_ARG_PS}, {
+	atom_op_shift_right, ATOM_ARG_WS}, {
+	atom_op_shift_right, ATOM_ARG_FB}, {
+	atom_op_shift_right, ATOM_ARG_PLL}, {
+	atom_op_shift_right, ATOM_ARG_MC}, {
 	atom_op_mul, ATOM_ARG_REG}, {
 	atom_op_mul, ATOM_ARG_PS}, {
 	atom_op_mul, ATOM_ARG_WS}, {
@@ -1040,7 +1108,7 @@ static struct {
 	atom_op_shr, ATOM_ARG_MC}, {
 atom_op_debug, 0},};
 
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
 {
 	int base = CU16(ctx->cmd_table + 4 + 2 * index);
 	int len, ws, ps, ptr;
@@ -1057,8 +1125,6 @@ void atom_execute_table(struct atom_cont
 
 	SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps);
 
-	/* reset reg block */
-	ctx->reg_block = 0;
 	ectx.ctx = ctx;
 	ectx.ps_shift = ps / 4;
 	ectx.start = base;
@@ -1092,6 +1158,19 @@ void atom_execute_table(struct atom_cont
 		kfree(ectx.ws);
 }
 
+void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+{
+	mutex_lock(&ctx->mutex);
+	/* reset reg block */
+	ctx->reg_block = 0;
+	/* reset fb window */
+	ctx->fb_base = 0;
+	/* reset io mode */
+	ctx->io_mode = ATOM_IO_MM;
+	atom_execute_table_locked(ctx, index, params);
+	mutex_unlock(&ctx->mutex);
+}
+
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
 
 static void atom_index_iio(struct atom_context *ctx, int base)
@@ -1214,3 +1293,28 @@ void atom_parse_cmd_header(struct atom_c
 		*crev = CU8(idx + 3);
 	return;
 }
+
+int atom_allocate_fb_scratch(struct atom_context *ctx)
+{
+	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
+	uint16_t data_offset;
+	int usage_bytes;
+	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
+
+	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
+
+	firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
+
+	DRM_DEBUG("atom firmware requested %08x %dkb\n",
+		  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+		  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
+
+	usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+	if (usage_bytes == 0)
+		usage_bytes = 20 * 1024;
+	/* allocate some scratch memory */
+	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
+	if (!ctx->scratch)
+		return -ENOMEM;
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atom.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/atom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/atom.h	2010-02-24 13:52:17.000000000 -0500
@@ -91,6 +91,7 @@
 #define ATOM_WS_AND_MASK	0x45
 #define ATOM_WS_FB_WINDOW	0x46
 #define ATOM_WS_ATTRIBUTES	0x47
+#define ATOM_WS_REGPTR  	0x48
 
 #define ATOM_IIO_NOP		0
 #define ATOM_IIO_START		1
@@ -120,6 +121,7 @@ struct card_info {
 
 struct atom_context {
 	struct card_info *card;
+	struct mutex mutex;
 	void *bios;
 	uint32_t cmd_table, data_table;
 	uint16_t *iio;
@@ -132,6 +134,7 @@ struct atom_context {
 	uint8_t shift;
 	int cs_equal, cs_above;
 	int io_mode;
+	uint32_t *scratch;
 };
 
 extern int atom_debug;
@@ -142,6 +145,7 @@ int atom_asic_init(struct atom_context *
 void atom_destroy(struct atom_context *);
 void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
 void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
+int atom_allocate_fb_scratch(struct atom_context *ctx);
 #include "atom-types.h"
 #include "atombios.h"
 #include "ObjectID.h"
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/Kconfig linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,10 +1,14 @@
 config DRM_RADEON_KMS
-	bool "Enable modesetting on radeon by default"
+	bool "Enable modesetting on radeon by default - NEW DRIVER"
 	depends on DRM_RADEON
 	help
-	  Choose this option if you want kernel modesetting enabled by default,
-	  and you have a new enough userspace to support this. Running old
-	  userspaces with this enabled will cause pain.
+	  Choose this option if you want kernel modesetting enabled by default.
+
+	  This is a completely new driver. It's only part of the existing drm
+	  for compatibility reasons. It requires an entirely different graphics
+	  stack above it and works very differently from the old drm stack.
+	  i.e. don't enable this unless you know what you are doing it may
+	  cause issues or bugs compared to the previous userspace driver stack.
 
 	  When kernel modesetting is enabled the IOCTL of radeon/drm
 	  driver are considered as invalid and an error message is printed
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,9 @@ $(obj)/rv515_reg_safe.h: $(src)/reg_srcs
 $(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable
 	$(call if_changed,mkregtable)
 
+$(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
 $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
 	$(call if_changed,mkregtable)
 
@@ -35,6 +38,8 @@ $(obj)/rv515.o: $(obj)/rv515_reg_safe.h
 
 $(obj)/r300.o: $(obj)/r300_reg_safe.h
 
+$(obj)/r420.o: $(obj)/r420_reg_safe.h
+
 $(obj)/rs600.o: $(obj)/rs600_reg_safe.h
 
 radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
@@ -49,7 +54,7 @@ radeon-y += radeon_device.o radeon_kms.o
 	radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
 	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
 	r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
-	r600_blit_kms.o radeon_pm.o
+	r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/mkregtable.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/mkregtable.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/mkregtable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/mkregtable.c	2010-02-24 13:52:17.000000000 -0500
@@ -661,8 +661,10 @@ static int parser_auth(struct table *t,
 	fseek(file, 0, SEEK_SET);
 
 	/* get header */
-	if (fgets(buf, 1024, file) == NULL)
+	if (fgets(buf, 1024, file) == NULL) {
+		fclose(file);
 		return -1;
+	}
 
 	/* first line will contain the last register
 	 * and gpu name */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/ObjectID.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/ObjectID.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/ObjectID.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/ObjectID.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-* Copyright 2006-2007 Advanced Micro Devices, Inc.
+* Copyright 2006-2007 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"),
@@ -41,14 +41,14 @@
 /****************************************************/
 /* Encoder Object ID Definition                     */
 /****************************************************/
-#define ENCODER_OBJECT_ID_NONE                    0x00
+#define ENCODER_OBJECT_ID_NONE                    0x00 
 
 /* Radeon Class Display Hardware */
 #define ENCODER_OBJECT_ID_INTERNAL_LVDS           0x01
 #define ENCODER_OBJECT_ID_INTERNAL_TMDS1          0x02
 #define ENCODER_OBJECT_ID_INTERNAL_TMDS2          0x03
 #define ENCODER_OBJECT_ID_INTERNAL_DAC1           0x04
-#define ENCODER_OBJECT_ID_INTERNAL_DAC2           0x05	/* TV/CV DAC */
+#define ENCODER_OBJECT_ID_INTERNAL_DAC2           0x05     /* TV/CV DAC */
 #define ENCODER_OBJECT_ID_INTERNAL_SDVOA          0x06
 #define ENCODER_OBJECT_ID_INTERNAL_SDVOB          0x07
 
@@ -56,11 +56,11 @@
 #define ENCODER_OBJECT_ID_SI170B                  0x08
 #define ENCODER_OBJECT_ID_CH7303                  0x09
 #define ENCODER_OBJECT_ID_CH7301                  0x0A
-#define ENCODER_OBJECT_ID_INTERNAL_DVO1           0x0B	/* This belongs to Radeon Class Display Hardware */
+#define ENCODER_OBJECT_ID_INTERNAL_DVO1           0x0B    /* This belongs to Radeon Class Display Hardware */
 #define ENCODER_OBJECT_ID_EXTERNAL_SDVOA          0x0C
 #define ENCODER_OBJECT_ID_EXTERNAL_SDVOB          0x0D
 #define ENCODER_OBJECT_ID_TITFP513                0x0E
-#define ENCODER_OBJECT_ID_INTERNAL_LVTM1          0x0F	/* not used for Radeon */
+#define ENCODER_OBJECT_ID_INTERNAL_LVTM1          0x0F    /* not used for Radeon */
 #define ENCODER_OBJECT_ID_VT1623                  0x10
 #define ENCODER_OBJECT_ID_HDMI_SI1930             0x11
 #define ENCODER_OBJECT_ID_HDMI_INTERNAL           0x12
@@ -68,9 +68,9 @@
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1   0x13
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1    0x14
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1    0x15
-#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2    0x16	/* Shared with CV/TV and CRT */
-#define ENCODER_OBJECT_ID_SI178                   0X17	/* External TMDS (dual link, no HDCP.) */
-#define ENCODER_OBJECT_ID_MVPU_FPGA               0x18	/* MVPU FPGA chip */
+#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2    0x16  /* Shared with CV/TV and CRT */
+#define ENCODER_OBJECT_ID_SI178                   0X17  /* External TMDS (dual link, no HDCP.) */
+#define ENCODER_OBJECT_ID_MVPU_FPGA               0x18  /* MVPU FPGA chip */
 #define ENCODER_OBJECT_ID_INTERNAL_DDI            0x19
 #define ENCODER_OBJECT_ID_VT1625                  0x1A
 #define ENCODER_OBJECT_ID_HDMI_SI1932             0x1B
@@ -86,7 +86,7 @@
 /****************************************************/
 /* Connector Object ID Definition                   */
 /****************************************************/
-#define CONNECTOR_OBJECT_ID_NONE                  0x00
+#define CONNECTOR_OBJECT_ID_NONE                  0x00 
 #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I     0x01
 #define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I       0x02
 #define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D     0x03
@@ -96,7 +96,7 @@
 #define CONNECTOR_OBJECT_ID_SVIDEO                0x07
 #define CONNECTOR_OBJECT_ID_YPbPr                 0x08
 #define CONNECTOR_OBJECT_ID_D_CONNECTOR           0x09
-#define CONNECTOR_OBJECT_ID_9PIN_DIN              0x0A	/* Supports both CV & TV */
+#define CONNECTOR_OBJECT_ID_9PIN_DIN              0x0A  /* Supports both CV & TV */
 #define CONNECTOR_OBJECT_ID_SCART                 0x0B
 #define CONNECTOR_OBJECT_ID_HDMI_TYPE_A           0x0C
 #define CONNECTOR_OBJECT_ID_HDMI_TYPE_B           0x0D
@@ -106,6 +106,8 @@
 #define CONNECTOR_OBJECT_ID_CROSSFIRE             0x11
 #define CONNECTOR_OBJECT_ID_HARDCODE_DVI          0x12
 #define CONNECTOR_OBJECT_ID_DISPLAYPORT           0x13
+#define CONNECTOR_OBJECT_ID_eDP                   0x14
+#define CONNECTOR_OBJECT_ID_MXM                   0x15
 
 /* deleted */
 
@@ -116,6 +118,14 @@
 #define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL				0x01
 
 /****************************************************/
+/* Generic Object ID Definition                     */
+/****************************************************/
+#define GENERIC_OBJECT_ID_NONE                    0x00
+#define GENERIC_OBJECT_ID_GLSYNC                  0x01
+#define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE        0x02
+#define GENERIC_OBJECT_ID_MXM_OPM                 0x03
+
+/****************************************************/
 /* Graphics Object ENUM ID Definition               */
 /****************************************************/
 #define GRAPH_OBJECT_ENUM_ID1                     0x01
@@ -124,6 +134,7 @@
 #define GRAPH_OBJECT_ENUM_ID4                     0x04
 #define GRAPH_OBJECT_ENUM_ID5                     0x05
 #define GRAPH_OBJECT_ENUM_ID6                     0x06
+#define GRAPH_OBJECT_ENUM_ID7                     0x07
 
 /****************************************************/
 /* Graphics Object ID Bit definition                */
@@ -133,35 +144,35 @@
 #define RESERVED1_ID_MASK                         0x0800
 #define OBJECT_TYPE_MASK                          0x7000
 #define RESERVED2_ID_MASK                         0x8000
-
+                                                  
 #define OBJECT_ID_SHIFT                           0x00
 #define ENUM_ID_SHIFT                             0x08
 #define OBJECT_TYPE_SHIFT                         0x0C
 
+
 /****************************************************/
 /* Graphics Object family definition                */
 /****************************************************/
-#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) \
-	(GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
-	 GRAPHICS_OBJECT_ID   << OBJECT_ID_SHIFT)
+#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
+                                                                           GRAPHICS_OBJECT_ID   << OBJECT_ID_SHIFT)
 /****************************************************/
 /* GPU Object ID definition - Shared with BIOS      */
 /****************************************************/
-#define GPU_ENUM_ID1	(GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
-			 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
+#define GPU_ENUM_ID1                            ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
 
 /****************************************************/
 /* Encoder Object ID definition - Shared with BIOS  */
 /****************************************************/
 /*
-#define ENCODER_INTERNAL_LVDS_ENUM_ID1        0x2101
+#define ENCODER_INTERNAL_LVDS_ENUM_ID1        0x2101      
 #define ENCODER_INTERNAL_TMDS1_ENUM_ID1       0x2102
 #define ENCODER_INTERNAL_TMDS2_ENUM_ID1       0x2103
 #define ENCODER_INTERNAL_DAC1_ENUM_ID1        0x2104
 #define ENCODER_INTERNAL_DAC2_ENUM_ID1        0x2105
 #define ENCODER_INTERNAL_SDVOA_ENUM_ID1       0x2106
 #define ENCODER_INTERNAL_SDVOB_ENUM_ID1       0x2107
-#define ENCODER_SIL170B_ENUM_ID1              0x2108
+#define ENCODER_SIL170B_ENUM_ID1              0x2108  
 #define ENCODER_CH7303_ENUM_ID1               0x2109
 #define ENCODER_CH7301_ENUM_ID1               0x210A
 #define ENCODER_INTERNAL_DVO1_ENUM_ID1        0x210B
@@ -175,8 +186,8 @@
 #define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1   0x2113
 #define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1    0x2114
 #define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1    0x2115
-#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1    0x2116
-#define ENCODER_SI178_ENUM_ID1                   0x2117
+#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1    0x2116  
+#define ENCODER_SI178_ENUM_ID1                   0x2117 
 #define ENCODER_MVPU_FPGA_ENUM_ID1               0x2118
 #define ENCODER_INTERNAL_DDI_ENUM_ID1            0x2119
 #define ENCODER_VT1625_ENUM_ID1                  0x211A
@@ -185,205 +196,169 @@
 #define ENCODER_DP_DP501_ENUM_ID1                0x211D
 #define ENCODER_INTERNAL_UNIPHY_ENUM_ID1         0x211E
 */
-#define ENCODER_INTERNAL_LVDS_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_LVDS_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_TMDS1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_TMDS2_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_DAC1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_DAC1_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_DAC2_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_DAC2_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_SDVOA_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_SDVOA_ENUM_ID2    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_SDVOB_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
 
-#define ENCODER_SIL170B_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
+#define ENCODER_SIL170B_ENUM_ID1           ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
 
-#define ENCODER_CH7303_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
+#define ENCODER_CH7303_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
 
-#define ENCODER_CH7301_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
+#define ENCODER_CH7301_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_DVO1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_DVO1_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
+#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
 
-#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
+#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
 
-#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
 
-#define ENCODER_TITFP513_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
+#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_VT1623_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
+#define ENCODER_TITFP513_ENUM_ID1          ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
 
-#define ENCODER_HDMI_SI1930_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_LVTM1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_HDMI_INTERNAL_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
+#define ENCODER_VT1623_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
+#define ENCODER_HDMI_SI1930_ENUM_ID1       ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
+#define ENCODER_HDMI_INTERNAL_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1   ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) /* Shared with CV/TV and CRT */
+#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2   ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_SI178_ENUM_ID1  \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)
 
-#define ENCODER_MVPU_FPGA_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_DDI_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
 
-#define ENCODER_VT1625_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT)  // Shared with CV/TV and CRT
 
-#define ENCODER_HDMI_SI1932_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
+#define ENCODER_SI178_ENUM_ID1                    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)  
 
-#define ENCODER_DP_DP501_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
+#define ENCODER_MVPU_FPGA_ENUM_ID1                ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
 
-#define ENCODER_DP_AN9801_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_DDI_ENUM_ID1     (  GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) 
 
-#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
+#define ENCODER_VT1625_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
+#define ENCODER_HDMI_SI1932_ENUM_ID1       ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT)
+#define ENCODER_DP_DP501_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
+#define ENCODER_DP_AN9801_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
 
-#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
+#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1   ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << 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)
+#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << 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)
 
 /****************************************************/
 /* Connector Object ID definition - Shared with BIOS */
@@ -406,167 +381,253 @@
 #define CONNECTOR_7PIN_DIN_ENUM_ID1                 0x310F
 #define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1           0x3110
 */
-#define CONNECTOR_LVDS_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
+#define CONNECTOR_LVDS_ENUM_ID1                ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
+#define CONNECTOR_LVDS_ENUM_ID2                ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
+#define CONNECTOR_eDP_ENUM_ID1                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
+#define CONNECTOR_eDP_ENUM_ID2                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
+#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << 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)
+#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << 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)
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_VGA_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_COMPOSITE_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_COMPOSITE << 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)
 
-#define CONNECTOR_SVIDEO_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID2     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_YPbPr_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID3     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_D_CONNECTOR_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_D_CONNECTOR << 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)
 
-#define CONNECTOR_9PIN_DIN_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
+#define CONNECTOR_VGA_ENUM_ID2                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_SCART_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
+#define CONNECTOR_COMPOSITE_ENUM_ID1           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+#define CONNECTOR_COMPOSITE_ENUM_ID2           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_COMPOSITE << 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)
+#define CONNECTOR_SVIDEO_ENUM_ID1              ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_7PIN_DIN_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
+#define CONNECTOR_SVIDEO_ENUM_ID2              ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
+#define CONNECTOR_YPbPr_ENUM_ID1               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
+#define CONNECTOR_YPbPr_ENUM_ID2               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_CROSSFIRE_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+#define CONNECTOR_D_CONNECTOR_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_CROSSFIRE_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+#define CONNECTOR_D_CONNECTOR_ENUM_ID2         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+#define CONNECTOR_9PIN_DIN_ENUM_ID1            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+#define CONNECTOR_9PIN_DIN_ENUM_ID2            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DISPLAYPORT_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+#define CONNECTOR_SCART_ENUM_ID1               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DISPLAYPORT_ENUM_ID2 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+#define CONNECTOR_SCART_ENUM_ID2               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DISPLAYPORT_ENUM_ID3 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
 
-#define CONNECTOR_DISPLAYPORT_ENUM_ID4 \
-	(GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
-	 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID2         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID3         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID3 << 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)
+
+#define CONNECTOR_HDMI_TYPE_B_ENUM_ID2         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_7PIN_DIN_ENUM_ID1            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
+#define CONNECTOR_7PIN_DIN_ENUM_ID2            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1      ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2      ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_CROSSFIRE_ENUM_ID1           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_CROSSFIRE_ENUM_ID2           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+
+
+#define CONNECTOR_HARDCODE_DVI_ENUM_ID1        ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HARDCODE_DVI_ENUM_ID2        ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID2         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID3         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID4         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID5         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID6         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_MXM_ENUM_ID1                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_DP_A
+
+#define CONNECTOR_MXM_ENUM_ID2                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_DP_B
+
+#define CONNECTOR_MXM_ENUM_ID3                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_DP_C
+
+#define CONNECTOR_MXM_ENUM_ID4                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_DP_D
+
+#define CONNECTOR_MXM_ENUM_ID5                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_LVDS_TXxx
+
+#define CONNECTOR_MXM_ENUM_ID6                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_LVDS_UXxx
+
+#define CONNECTOR_MXM_ENUM_ID7                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT)          //Mapping to MXM_DAC
 
 /****************************************************/
 /* Router Object ID definition - Shared with BIOS   */
 /****************************************************/
-#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 \
-	(GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
-	 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
-	 ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
+#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1      ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
+                                                GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
 
 /* deleted */
 
 /****************************************************/
+/* Generic Object ID definition - Shared with BIOS  */
+/****************************************************/
+#define GENERICOBJECT_GLSYNC_ENUM_ID1           (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 GENERIC_OBJECT_ID_GLSYNC << OBJECT_ID_SHIFT)
+
+#define GENERICOBJECT_PX2_NON_DRIVABLE_ID1       (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT)
+
+#define GENERICOBJECT_PX2_NON_DRIVABLE_ID2       (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT)
+
+#define GENERICOBJECT_MXM_OPM_ENUM_ID1           (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT)
+
+/****************************************************/
 /* Object Cap definition - Shared with BIOS         */
 /****************************************************/
 #define GRAPHICS_OBJECT_CAP_I2C                 0x00000001L
 #define GRAPHICS_OBJECT_CAP_TABLE_ID            0x00000002L
 
+
 #define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID                   0x01
 #define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID     0x02
 #define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID    0x03
@@ -575,4 +636,8 @@
 #pragma pack()
 #endif
 
-#endif /*GRAPHICTYPE */
+#endif  /*GRAPHICTYPE */
+
+
+
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r100.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r100.c	2013-05-03 13:55:53.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100.c	2013-05-03 12:03:44.000000000 -0400
@@ -59,6 +59,96 @@
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  */
 
+/* hpd for digital panel detect/disconnect */
+bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	bool connected = false;
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
+			connected = true;
+		break;
+	case RADEON_HPD_2:
+		if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
+			connected = true;
+		break;
+	default:
+		break;
+	}
+	return connected;
+}
+
+void r100_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = r100_hpd_sense(rdev, hpd);
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(RADEON_FP_GEN_CNTL);
+		if (connected)
+			tmp &= ~RADEON_FP_DETECT_INT_POL;
+		else
+			tmp |= RADEON_FP_DETECT_INT_POL;
+		WREG32(RADEON_FP_GEN_CNTL, tmp);
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(RADEON_FP2_GEN_CNTL);
+		if (connected)
+			tmp &= ~RADEON_FP2_DETECT_INT_POL;
+		else
+			tmp |= RADEON_FP2_DETECT_INT_POL;
+		WREG32(RADEON_FP2_GEN_CNTL, tmp);
+		break;
+	default:
+		break;
+	}
+}
+
+void r100_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			rdev->irq.hpd[0] = true;
+			break;
+		case RADEON_HPD_2:
+			rdev->irq.hpd[1] = true;
+			break;
+		default:
+			break;
+		}
+	}
+	if (rdev->irq.installed)
+		r100_irq_set(rdev);
+}
+
+void r100_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			rdev->irq.hpd[0] = false;
+			break;
+		case RADEON_HPD_2:
+			rdev->irq.hpd[1] = false;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 /*
  * PCI GART
  */
@@ -88,6 +178,15 @@ int r100_pci_gart_init(struct radeon_dev
 	return radeon_gart_table_ram_alloc(rdev);
 }
 
+/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+void r100_enable_bm(struct radeon_device *rdev)
+{
+	uint32_t tmp;
+	/* Enable bus mastering */
+	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+	WREG32(RADEON_BUS_CNTL, tmp);
+}
+
 int r100_pci_gart_enable(struct radeon_device *rdev)
 {
 	uint32_t tmp;
@@ -99,9 +198,6 @@ int r100_pci_gart_enable(struct radeon_d
 	WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
 	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
 	WREG32(RADEON_AIC_HI_ADDR, tmp);
-	/* Enable bus mastering */
-	tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
-	WREG32(RADEON_BUS_CNTL, tmp);
 	/* set PCI GART page-table base address */
 	WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
@@ -142,6 +238,11 @@ int r100_irq_set(struct radeon_device *r
 {
 	uint32_t tmp = 0;
 
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+		WREG32(R_000040_GEN_INT_CNTL, 0);
+		return -EINVAL;
+	}
 	if (rdev->irq.sw_int) {
 		tmp |= RADEON_SW_INT_ENABLE;
 	}
@@ -151,6 +252,12 @@ int r100_irq_set(struct radeon_device *r
 	if (rdev->irq.crtc_vblank_int[1]) {
 		tmp |= RADEON_CRTC2_VBLANK_MASK;
 	}
+	if (rdev->irq.hpd[0]) {
+		tmp |= RADEON_FP_DETECT_MASK;
+	}
+	if (rdev->irq.hpd[1]) {
+		tmp |= RADEON_FP2_DETECT_MASK;
+	}
 	WREG32(RADEON_GEN_INT_CNTL, tmp);
 	return 0;
 }
@@ -169,8 +276,9 @@ void r100_irq_disable(struct radeon_devi
 static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
 {
 	uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
-	uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
-		RADEON_CRTC2_VBLANK_STAT;
+	uint32_t irq_mask = RADEON_SW_INT_TEST |
+		RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
+		RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
 
 	if (irqs) {
 		WREG32(RADEON_GEN_INT_STATUS, irqs);
@@ -181,6 +289,7 @@ static inline uint32_t r100_irq_ack(stru
 int r100_irq_process(struct radeon_device *rdev)
 {
 	uint32_t status, msi_rearm;
+	bool queue_hotplug = false;
 
 	status = r100_irq_ack(rdev);
 	if (!status) {
@@ -201,8 +310,18 @@ int r100_irq_process(struct radeon_devic
 		if (status & RADEON_CRTC2_VBLANK_STAT) {
 			drm_handle_vblank(rdev->ddev, 1);
 		}
+		if (status & RADEON_FP_DETECT_STAT) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD1\n");
+		}
+		if (status & RADEON_FP2_DETECT_STAT) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD2\n");
+		}
 		status = r100_irq_ack(rdev);
 	}
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
 	if (rdev->msi_enabled) {
 		switch (rdev->family) {
 		case CHIP_RS400:
@@ -229,14 +348,25 @@ u32 r100_get_vblank_counter(struct radeo
 		return RREG32(RADEON_CRTC2_CRNT_FRAME);
 }
 
+/* Who ever call radeon_fence_emit should call ring_lock and ask
+ * for enough space (today caller are ib schedule and buffer move) */
 void r100_fence_ring_emit(struct radeon_device *rdev,
 			  struct radeon_fence *fence)
 {
-	/* Who ever call radeon_fence_emit should call ring_lock and ask
-	 * for enough space (today caller are ib schedule and buffer move) */
+	/* We have to make sure that caches are flushed before
+	 * CPU might read something from VRAM. */
+	radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));
+	radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL);
+	radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));
+	radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL);
 	/* Wait until IDLE & CLEAN */
 	radeon_ring_write(rdev, PACKET0(0x1720, 0));
 	radeon_ring_write(rdev, (1 << 16) | (1 << 17));
+	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+	radeon_ring_write(rdev, rdev->config.r100.hdp_cntl |
+				RADEON_HDP_READ_BUFFER_INVALIDATE);
+	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+	radeon_ring_write(rdev, rdev->config.r100.hdp_cntl);
 	/* Emit fence sequence & fire IRQ */
 	radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0));
 	radeon_ring_write(rdev, fence->seq);
@@ -249,24 +379,27 @@ int r100_wb_init(struct radeon_device *r
 	int r;
 
 	if (rdev->wb.wb_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
-					 true,
-					 RADEON_GEM_DOMAIN_GTT,
-					 false, &rdev->wb.wb_obj);
+		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+					RADEON_GEM_DOMAIN_GTT,
+					&rdev->wb.wb_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->wb.wb_obj,
-				      RADEON_GEM_DOMAIN_GTT,
-				      &rdev->wb.gpu_addr);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+					&rdev->wb.gpu_addr);
 		if (r) {
-			DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
+			radeon_bo_unreserve(rdev->wb.wb_obj);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+			dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
 			return r;
 		}
 	}
@@ -284,11 +417,19 @@ void r100_wb_disable(struct radeon_devic
 
 void r100_wb_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	r100_wb_disable(rdev);
 	if (rdev->wb.wb_obj) {
-		radeon_object_kunmap(rdev->wb.wb_obj);
-		radeon_object_unpin(rdev->wb.wb_obj);
-		radeon_object_unref(&rdev->wb.wb_obj);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0)) {
+			dev_err(rdev->dev, "(%d) can't finish WB\n", r);
+			return;
+		}
+		radeon_bo_kunmap(rdev->wb.wb_obj);
+		radeon_bo_unpin(rdev->wb.wb_obj);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
+		radeon_bo_unref(&rdev->wb.wb_obj);
 		rdev->wb.wb = NULL;
 		rdev->wb.wb_obj = NULL;
 	}
@@ -1244,7 +1385,6 @@ static int r100_packet0_check(struct rad
 		case RADEON_TXFORMAT_ARGB4444:
 		case RADEON_TXFORMAT_VYUY422:
 		case RADEON_TXFORMAT_YVYU422:
-		case RADEON_TXFORMAT_DXT1:
 		case RADEON_TXFORMAT_SHADOW16:
 		case RADEON_TXFORMAT_LDUDV655:
 		case RADEON_TXFORMAT_DUDV88:
@@ -1252,12 +1392,19 @@ static int r100_packet0_check(struct rad
 			break;
 		case RADEON_TXFORMAT_ARGB8888:
 		case RADEON_TXFORMAT_RGBA8888:
-		case RADEON_TXFORMAT_DXT23:
-		case RADEON_TXFORMAT_DXT45:
 		case RADEON_TXFORMAT_SHADOW32:
 		case RADEON_TXFORMAT_LDUDUV8888:
 			track->textures[i].cpp = 4;
 			break;
+		case RADEON_TXFORMAT_DXT1:
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
+			break;
+		case RADEON_TXFORMAT_DXT23:
+		case RADEON_TXFORMAT_DXT45:
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
+			break;
 		}
 		track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
 		track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
@@ -1282,17 +1429,17 @@ static int r100_packet0_check(struct rad
 
 int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
 					 struct radeon_cs_packet *pkt,
-					 struct radeon_object *robj)
+					 struct radeon_bo *robj)
 {
 	unsigned idx;
 	u32 value;
 	idx = pkt->idx + 1;
 	value = radeon_get_ib_value(p, idx + 2);
-	if ((value + 1) > radeon_object_size(robj)) {
+	if ((value + 1) > radeon_bo_size(robj)) {
 		DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
 			  "(need %u have %lu) !\n",
 			  value + 1,
-			  radeon_object_size(robj));
+			  radeon_bo_size(robj));
 		return -EINVAL;
 	}
 	return 0;
@@ -1357,6 +1504,7 @@ static int r100_packet3_check(struct rad
 			DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
 			return -EINVAL;
 		}
+		track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 0));
 		track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
 		track->immd_dwords = pkt->count - 1;
 		r = r100_cs_track_check(p->rdev, track);
@@ -1644,6 +1792,17 @@ int r100_gpu_reset(struct radeon_device
 	return 0;
 }
 
+void r100_set_common_regs(struct radeon_device *rdev)
+{
+	/* set these so they don't interfere with anything */
+	WREG32(RADEON_OV0_SCALE_CNTL, 0);
+	WREG32(RADEON_SUBPIC_CNTL, 0);
+	WREG32(RADEON_VIPH_CONTROL, 0);
+	WREG32(RADEON_I2C_CNTL_1, 0);
+	WREG32(RADEON_DVI_I2C_CNTL_1, 0);
+	WREG32(RADEON_CAP0_TRIG_CNTL, 0);
+	WREG32(RADEON_CAP1_TRIG_CNTL, 0);
+}
 
 /*
  * VRAM info
@@ -2582,13 +2741,14 @@ static inline void r100_cs_track_texture
 	DRM_ERROR("coordinate type            %d\n", t->tex_coord_type);
 	DRM_ERROR("width round to power of 2  %d\n", t->roundup_w);
 	DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
+	DRM_ERROR("compress format            %d\n", t->compress_format);
 }
 
 static int r100_cs_track_cube(struct radeon_device *rdev,
 			      struct r100_cs_track *track, unsigned idx)
 {
 	unsigned face, w, h;
-	struct radeon_object *cube_robj;
+	struct radeon_bo *cube_robj;
 	unsigned long size;
 
 	for (face = 0; face < 5; face++) {
@@ -2601,9 +2761,9 @@ static int r100_cs_track_cube(struct rad
 
 		size += track->textures[idx].cube_info[face].offset;
 
-		if (size > radeon_object_size(cube_robj)) {
+		if (size > radeon_bo_size(cube_robj)) {
 			DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
-				  size, radeon_object_size(cube_robj));
+				  size, radeon_bo_size(cube_robj));
 			r100_cs_track_texture_print(&track->textures[idx]);
 			return -1;
 		}
@@ -2611,10 +2771,40 @@ static int r100_cs_track_cube(struct rad
 	return 0;
 }
 
+static int r100_track_compress_size(int compress_format, int w, int h)
+{
+	int block_width, block_height, block_bytes;
+	int wblocks, hblocks;
+	int min_wblocks;
+	int sz;
+
+	block_width = 4;
+	block_height = 4;
+
+	switch (compress_format) {
+	case R100_TRACK_COMP_DXT1:
+		block_bytes = 8;
+		min_wblocks = 4;
+		break;
+	default:
+	case R100_TRACK_COMP_DXT35:
+		block_bytes = 16;
+		min_wblocks = 2;
+		break;
+	}
+
+	hblocks = (h + block_height - 1) / block_height;
+	wblocks = (w + block_width - 1) / block_width;
+	if (wblocks < min_wblocks)
+		wblocks = min_wblocks;
+	sz = wblocks * hblocks * block_bytes;
+	return sz;
+}
+
 static int r100_cs_track_texture_check(struct radeon_device *rdev,
 				       struct r100_cs_track *track)
 {
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	unsigned long size;
 	unsigned u, i, w, h;
 	int ret;
@@ -2648,9 +2838,15 @@ static int r100_cs_track_texture_check(s
 			h = h / (1 << i);
 			if (track->textures[u].roundup_h)
 				h = roundup_pow_of_two(h);
-			size += w * h;
+			if (track->textures[u].compress_format) {
+
+				size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+				/* compressed textures are block based */
+			} else
+				size += w * h;
 		}
 		size *= track->textures[u].cpp;
+
 		switch (track->textures[u].tex_coord_type) {
 		case 0:
 			break;
@@ -2670,9 +2866,9 @@ static int r100_cs_track_texture_check(s
 				  "%u\n", track->textures[u].tex_coord_type, u);
 			return -EINVAL;
 		}
-		if (size > radeon_object_size(robj)) {
+		if (size > radeon_bo_size(robj)) {
 			DRM_ERROR("Texture of unit %u needs %lu bytes but is "
-				  "%lu\n", u, size, radeon_object_size(robj));
+				  "%lu\n", u, size, radeon_bo_size(robj));
 			r100_cs_track_texture_print(&track->textures[u]);
 			return -EINVAL;
 		}
@@ -2689,15 +2885,19 @@ int r100_cs_track_check(struct radeon_de
 
 	for (i = 0; i < track->num_cb; i++) {
 		if (track->cb[i].robj == NULL) {
+			if (!(track->fastfill || track->color_channel_mask ||
+			      track->blend_read_enable)) {
+				continue;
+			}
 			DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
 			return -EINVAL;
 		}
 		size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
 		size += track->cb[i].offset;
-		if (size > radeon_object_size(track->cb[i].robj)) {
+		if (size > radeon_bo_size(track->cb[i].robj)) {
 			DRM_ERROR("[drm] Buffer too small for color buffer %d "
 				  "(need %lu have %lu) !\n", i, size,
-				  radeon_object_size(track->cb[i].robj));
+				  radeon_bo_size(track->cb[i].robj));
 			DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
 				  i, track->cb[i].pitch, track->cb[i].cpp,
 				  track->cb[i].offset, track->maxy);
@@ -2711,10 +2911,10 @@ int r100_cs_track_check(struct radeon_de
 		}
 		size = track->zb.pitch * track->zb.cpp * track->maxy;
 		size += track->zb.offset;
-		if (size > radeon_object_size(track->zb.robj)) {
+		if (size > radeon_bo_size(track->zb.robj)) {
 			DRM_ERROR("[drm] Buffer too small for z buffer "
 				  "(need %lu have %lu) !\n", size,
-				  radeon_object_size(track->zb.robj));
+				  radeon_bo_size(track->zb.robj));
 			DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
 				  track->zb.pitch, track->zb.cpp,
 				  track->zb.offset, track->maxy);
@@ -2732,11 +2932,12 @@ int r100_cs_track_check(struct radeon_de
 					  "bound\n", prim_walk, i);
 				return -EINVAL;
 			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i,
-					   size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
+			if (size > radeon_bo_size(track->arrays[i].robj)) {
+				dev_err(rdev->dev, "(PW %u) Vertex array %u "
+					"need %lu dwords have %lu dwords\n",
+					prim_walk, i, size >> 2,
+					radeon_bo_size(track->arrays[i].robj)
+					>> 2);
 				DRM_ERROR("Max indices %u\n", track->max_indx);
 				return -EINVAL;
 			}
@@ -2750,10 +2951,12 @@ int r100_cs_track_check(struct radeon_de
 					  "bound\n", prim_walk, i);
 				return -EINVAL;
 			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i, size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
+			if (size > radeon_bo_size(track->arrays[i].robj)) {
+				dev_err(rdev->dev, "(PW %u) Vertex array %u "
+					"need %lu dwords have %lu dwords\n",
+					prim_walk, i, size >> 2,
+					radeon_bo_size(track->arrays[i].robj)
+					>> 2);
 				return -EINVAL;
 			}
 		}
@@ -2815,6 +3018,7 @@ void r100_cs_track_clear(struct radeon_d
 		track->arrays[i].esize = 0x7F;
 	}
 	for (i = 0; i < track->num_texture; i++) {
+		track->textures[i].compress_format = R100_TRACK_COMP_NONE;
 		track->textures[i].pitch = 16536;
 		track->textures[i].width = 16536;
 		track->textures[i].height = 16536;
@@ -3095,6 +3299,9 @@ static int r100_startup(struct radeon_de
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r100_mc_program(rdev);
 	/* Resume clock */
 	r100_clock_startup(rdev);
@@ -3102,14 +3309,15 @@ static int r100_startup(struct radeon_de
 	r100_gpu_init(rdev);
 	/* Initialize GART (initialize after TTM so we can allocate
 	 * memory through TTM but finalize after TTM) */
+	r100_enable_bm(rdev);
 	if (rdev->flags & RADEON_IS_PCI) {
 		r = r100_pci_gart_enable(rdev);
 		if (r)
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
+	rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -3144,6 +3352,8 @@ int r100_resume(struct radeon_device *rd
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r100_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r100_startup(rdev);
 }
 
@@ -3159,16 +3369,16 @@ int r100_suspend(struct radeon_device *r
 
 void r100_fini(struct radeon_device *rdev)
 {
-	r100_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
 	radeon_gem_fini(rdev);
 	if (rdev->flags & RADEON_IS_PCI)
 		r100_pci_gart_fini(rdev);
+	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -3189,9 +3399,7 @@ int r100_mc_init(struct radeon_device *r
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
 		if (r) {
-			printk(KERN_WARNING "[drm] Disabling AGP\n");
-			rdev->flags &= ~RADEON_IS_AGP;
-			rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+			radeon_agp_disable(rdev);
 		} else {
 			rdev->mc.gtt_location = rdev->mc.agp_base;
 		}
@@ -3236,14 +3444,14 @@ int r100_init(struct radeon_device *rdev
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Set asic errata */
 	r100_errata(rdev);
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
+	/* Initialize power management */
+	radeon_pm_init(rdev);
 	/* Get vram informations */
 	r100_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
@@ -3258,7 +3466,7 @@ int r100_init(struct radeon_device *rdev
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	if (rdev->flags & RADEON_IS_PCI) {
@@ -3272,13 +3480,12 @@ int r100_init(struct radeon_device *rdev
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		r100_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		if (rdev->flags & RADEON_IS_PCI)
 			r100_pci_gart_fini(rdev);
-		radeon_irq_kms_fini(rdev);
 		rdev->accel_working = false;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r100_track.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100_track.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r100_track.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r100_track.h	2010-02-24 13:52:17.000000000 -0500
@@ -10,26 +10,30 @@
  * CS functions
  */
 struct r100_cs_track_cb {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	unsigned		pitch;
 	unsigned		cpp;
 	unsigned		offset;
 };
 
 struct r100_cs_track_array {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	unsigned		esize;
 };
 
 struct r100_cs_cube_info {
-	struct radeon_object	*robj;
-	unsigned                offset;
+	struct radeon_bo	*robj;
+	unsigned		offset;
 	unsigned		width;
 	unsigned		height;
 };
 
+#define R100_TRACK_COMP_NONE   0
+#define R100_TRACK_COMP_DXT1   1
+#define R100_TRACK_COMP_DXT35  2
+
 struct r100_cs_track_texture {
-	struct radeon_object	*robj;
+	struct radeon_bo	*robj;
 	struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
 	unsigned		pitch;
 	unsigned		width;
@@ -44,6 +48,7 @@ struct r100_cs_track_texture {
 	bool			enabled;
 	bool			roundup_w;
 	bool			roundup_h;
+	unsigned                compress_format;
 };
 
 struct r100_cs_track_limits {
@@ -62,13 +67,15 @@ struct r100_cs_track {
 	unsigned			immd_dwords;
 	unsigned			num_arrays;
 	unsigned			max_indx;
+	unsigned			color_channel_mask;
 	struct r100_cs_track_array	arrays[11];
 	struct r100_cs_track_cb 	cb[R300_MAX_CB];
 	struct r100_cs_track_cb 	zb;
 	struct r100_cs_track_texture	textures[R300_TRACK_MAX_TEXTURE];
 	bool				z_enabled;
 	bool                            separate_cube;
-
+	bool				fastfill;
+	bool				blend_read_enable;
 };
 
 int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r200.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r200.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r200.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r200.c	2010-02-24 13:52:17.000000000 -0500
@@ -371,13 +371,16 @@ int r200_packet0_check(struct radeon_cs_
 		case 5:
 		case 6:
 		case 7:
+			/* 1D/2D */
 			track->textures[i].tex_coord_type = 0;
 			break;
 		case 1:
-			track->textures[i].tex_coord_type = 1;
+			/* CUBE */
+			track->textures[i].tex_coord_type = 2;
 			break;
 		case 2:
-			track->textures[i].tex_coord_type = 2;
+			/* 3D */
+			track->textures[i].tex_coord_type = 1;
 			break;
 		}
 		break;
@@ -401,7 +404,6 @@ int r200_packet0_check(struct radeon_cs_
 		case R200_TXFORMAT_Y8:
 			track->textures[i].cpp = 1;
 			break;
-		case R200_TXFORMAT_DXT1:
 		case R200_TXFORMAT_AI88:
 		case R200_TXFORMAT_ARGB1555:
 		case R200_TXFORMAT_RGB565:
@@ -418,9 +420,16 @@ int r200_packet0_check(struct radeon_cs_
 		case R200_TXFORMAT_ABGR8888:
 		case R200_TXFORMAT_BGR111110:
 		case R200_TXFORMAT_LDVDU8888:
+			track->textures[i].cpp = 4;
+			break;
+		case R200_TXFORMAT_DXT1:
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
+			break;
 		case R200_TXFORMAT_DXT23:
 		case R200_TXFORMAT_DXT45:
-			track->textures[i].cpp = 4;
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
 			break;
 		}
 		track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,7 +36,15 @@
 #include "rv350d.h"
 #include "r300_reg_safe.h"
 
-/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */
+/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380
+ *
+ * GPU Errata:
+ * - HOST_PATH_CNTL: r300 family seems to dislike write to HOST_PATH_CNTL
+ *   using MMIO to flush host path read cache, this lead to HARDLOCKUP.
+ *   However, scheduling such write to the ring seems harmless, i suspect
+ *   the CP read collide with the flush somehow, or maybe the MC, hard to
+ *   tell. (Jerome Glisse)
+ */
 
 /*
  * rv370,rv380 PCIE GART
@@ -137,14 +145,19 @@ int rv370_pcie_gart_enable(struct radeon
 
 void rv370_pcie_gart_disable(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u32 tmp;
+	int r;
 
 	tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
 	tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -173,6 +186,11 @@ void r300_fence_ring_emit(struct radeon_
 	/* Wait until IDLE & CLEAN */
 	radeon_ring_write(rdev, PACKET0(0x1720, 0));
 	radeon_ring_write(rdev, (1 << 17) | (1 << 16)  | (1 << 9));
+	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+	radeon_ring_write(rdev, rdev->config.r300.hdp_cntl |
+				RADEON_HDP_READ_BUFFER_INVALIDATE);
+	radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+	radeon_ring_write(rdev, rdev->config.r300.hdp_cntl);
 	/* Emit fence sequence & fire IRQ */
 	radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0));
 	radeon_ring_write(rdev, fence->seq);
@@ -488,11 +506,14 @@ void r300_vram_info(struct radeon_device
 
 	/* DDR for all card after R300 & IGP */
 	rdev->mc.vram_is_ddr = true;
+
 	tmp = RREG32(RADEON_MEM_CNTL);
-	if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
-		rdev->mc.vram_width = 128;
-	} else {
-		rdev->mc.vram_width = 64;
+	tmp &= R300_MEM_NUM_CHANNELS_MASK;
+	switch (tmp) {
+	case 0: rdev->mc.vram_width = 64; break;
+	case 1: rdev->mc.vram_width = 128; break;
+	case 2: rdev->mc.vram_width = 256; break;
+	default:  rdev->mc.vram_width = 128; break;
 	}
 
 	r100_vram_init_sizes(rdev);
@@ -681,7 +702,15 @@ static int r300_packet0_check(struct rad
 			r100_cs_dump_packet(p, pkt);
 			return r;
 		}
-		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
+
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+			tile_flags |= R300_TXO_MACRO_TILE;
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+			tile_flags |= R300_TXO_MICRO_TILE;
+
+		tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
+		tmp |= tile_flags;
+		ib[idx] = tmp;
 		track->textures[i].robj = reloc->robj;
 		break;
 	/* Tracked registers */
@@ -847,7 +876,6 @@ static int r300_packet0_check(struct rad
 		case R300_TX_FORMAT_Z6Y5X5:
 		case R300_TX_FORMAT_W4Z4Y4X4:
 		case R300_TX_FORMAT_W1Z5Y5X5:
-		case R300_TX_FORMAT_DXT1:
 		case R300_TX_FORMAT_D3DMFT_CxV8U8:
 		case R300_TX_FORMAT_B8G8_B8G8:
 		case R300_TX_FORMAT_G8R8_G8B8:
@@ -861,8 +889,6 @@ static int r300_packet0_check(struct rad
 		case 0x17:
 		case R300_TX_FORMAT_FL_I32:
 		case 0x1e:
-		case R300_TX_FORMAT_DXT3:
-		case R300_TX_FORMAT_DXT5:
 			track->textures[i].cpp = 4;
 			break;
 		case R300_TX_FORMAT_W16Z16Y16X16:
@@ -873,6 +899,23 @@ static int r300_packet0_check(struct rad
 		case R300_TX_FORMAT_FL_R32G32B32A32:
 			track->textures[i].cpp = 16;
 			break;
+		case R300_TX_FORMAT_DXT1:
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
+			break;
+		case R300_TX_FORMAT_ATI2N:
+			if (p->rdev->family < CHIP_R420) {
+				DRM_ERROR("Invalid texture format %u\n",
+					  (idx_value & 0x1F));
+				return -EINVAL;
+			}
+			/* The same rules apply as for DXT3/5. */
+			/* Pass through. */
+		case R300_TX_FORMAT_DXT3:
+		case R300_TX_FORMAT_DXT5:
+			track->textures[i].cpp = 1;
+			track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
+			break;
 		default:
 			DRM_ERROR("Invalid texture format %u\n",
 				  (idx_value & 0x1F));
@@ -932,6 +975,16 @@ static int r300_packet0_check(struct rad
 			track->textures[i].width_11 = tmp;
 			tmp = ((idx_value >> 16) & 1) << 11;
 			track->textures[i].height_11 = tmp;
+
+			/* ATI1N */
+			if (idx_value & (1 << 14)) {
+				/* The same rules apply as for DXT1. */
+				track->textures[i].compress_format =
+					R100_TRACK_COMP_DXT1;
+			}
+		} else if (idx_value & (1 << 14)) {
+			DRM_ERROR("Forbidden bit TXFORMAT_MSB\n");
+			return -EINVAL;
 		}
 		break;
 	case 0x4480:
@@ -973,6 +1026,18 @@ static int r300_packet0_check(struct rad
 		}
 		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
 		break;
+	case 0x4e0c:
+		/* RB3D_COLOR_CHANNEL_MASK */
+		track->color_channel_mask = idx_value;
+		break;
+	case 0x4d1c:
+		/* ZB_BW_CNTL */
+		track->fastfill = !!(idx_value & (1 << 2));
+		break;
+	case 0x4e04:
+		/* RB3D_BLENDCNTL */
+		track->blend_read_enable = !!(idx_value & (1 << 2));
+		break;
 	case 0x4be8:
 		/* valid register only on RV530 */
 		if (p->rdev->family == CHIP_RV530)
@@ -1181,6 +1246,9 @@ static int r300_startup(struct radeon_de
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r300_mc_program(rdev);
 	/* Resume clock */
 	r300_clock_startup(rdev);
@@ -1193,14 +1261,20 @@ static int r300_startup(struct radeon_de
 		if (r)
 			return r;
 	}
+
+	if (rdev->family == CHIP_R300 ||
+	    rdev->family == CHIP_R350 ||
+	    rdev->family == CHIP_RV350)
+		r100_enable_bm(rdev);
+
 	if (rdev->flags & RADEON_IS_PCI) {
 		r = r100_pci_gart_enable(rdev);
 		if (r)
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -1237,6 +1311,8 @@ int r300_resume(struct radeon_device *rd
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r300_startup(rdev);
 }
 
@@ -1254,7 +1330,6 @@ int r300_suspend(struct radeon_device *r
 
 void r300_fini(struct radeon_device *rdev)
 {
-	r300_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -1263,9 +1338,10 @@ void r300_fini(struct radeon_device *rde
 		rv370_pcie_gart_fini(rdev);
 	if (rdev->flags & RADEON_IS_PCI)
 		r100_pci_gart_fini(rdev);
+	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -1303,14 +1379,14 @@ int r300_init(struct radeon_device *rdev
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Set asic errata */
 	r300_errata(rdev);
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
+	/* Initialize power management */
+	radeon_pm_init(rdev);
 	/* Get vram informations */
 	r300_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
@@ -1325,7 +1401,7 @@ int r300_init(struct radeon_device *rdev
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	if (rdev->flags & RADEON_IS_PCIE) {
@@ -1344,15 +1420,15 @@ int r300_init(struct radeon_device *rdev
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		r300_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		if (rdev->flags & RADEON_IS_PCIE)
 			rv370_pcie_gart_fini(rdev);
 		if (rdev->flags & RADEON_IS_PCI)
 			r100_pci_gart_fini(rdev);
-		radeon_irq_kms_fini(rdev);
+		radeon_agp_fini(rdev);
 		rdev->accel_working = false;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2010-02-24 13:52:17.000000000 -0500
@@ -990,7 +990,7 @@ static inline int r300_emit_r500fp(drm_r
 	int sz;
 	int addr;
 	int type;
-	int clamp;
+	int isclamp;
 	int stride;
 	RING_LOCALS;
 
@@ -999,10 +999,10 @@ static inline int r300_emit_r500fp(drm_r
 	addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;
 
 	type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
-	clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
+	isclamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
 
 	addr |= (type << 16);
-	addr |= (clamp << 17);
+	addr |= (isclamp << 17);
 
 	stride = type ? 4 : 6;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -900,6 +900,7 @@
 #	define R300_TX_FORMAT_FL_I32		    0x1B
 #	define R300_TX_FORMAT_FL_I32A32		    0x1C
 #	define R300_TX_FORMAT_FL_R32G32B32A32	    0x1D
+#	define R300_TX_FORMAT_ATI2N		    0x1F
 	/* alpha modes, convenience mostly */
 	/* if you have alpha, pick constant appropriate to the
 	   number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r420.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r420.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r420.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r420.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,15 @@
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "atom.h"
+#include "r100d.h"
 #include "r420d.h"
+#include "r420_reg_safe.h"
+
+static void r420_set_reg_safe(struct radeon_device *rdev)
+{
+	rdev->config.r300.reg_safe_bm = r420_reg_safe_bm;
+	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);
+}
 
 int r420_mc_init(struct radeon_device *rdev)
 {
@@ -42,9 +50,7 @@ int r420_mc_init(struct radeon_device *r
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
 		if (r) {
-			printk(KERN_WARNING "[drm] Disabling AGP\n");
-			rdev->flags &= ~RADEON_IS_AGP;
-			rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+			radeon_agp_disable(rdev);
 		} else {
 			rdev->mc.gtt_location = rdev->mc.agp_base;
 		}
@@ -165,10 +171,41 @@ static void r420_clock_resume(struct rad
 	WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);
 }
 
+static void r420_cp_errata_init(struct radeon_device *rdev)
+{
+	/* RV410 and R420 can lock up if CP DMA to host memory happens
+	 * while the 2D engine is busy.
+	 *
+	 * The proper workaround is to queue a RESYNC at the beginning
+	 * of the CP init, apparently.
+	 */
+	radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch);
+	radeon_ring_lock(rdev, 8);
+	radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1));
+	radeon_ring_write(rdev, rdev->config.r300.resync_scratch);
+	radeon_ring_write(rdev, 0xDEADBEEF);
+	radeon_ring_unlock_commit(rdev);
+}
+
+static void r420_cp_errata_fini(struct radeon_device *rdev)
+{
+	/* Catch the RESYNC we dispatched all the way back,
+	 * at the very beginning of the CP init.
+	 */
+	radeon_ring_lock(rdev, 8);
+	radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+	radeon_ring_write(rdev, R300_RB3D_DC_FINISH);
+	radeon_ring_unlock_commit(rdev);
+	radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);
+}
+
 static int r420_startup(struct radeon_device *rdev)
 {
 	int r;
 
+	/* set common regs */
+	r100_set_common_regs(rdev);
+	/* program mc */
 	r300_mc_program(rdev);
 	/* Resume clock */
 	r420_clock_resume(rdev);
@@ -186,14 +223,15 @@ static int r420_startup(struct radeon_de
 	}
 	r420_pipes_init(rdev);
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
 		dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
 		return r;
 	}
+	r420_cp_errata_init(rdev);
 	r = r100_wb_init(rdev);
 	if (r) {
 		dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
@@ -229,12 +267,14 @@ int r420_resume(struct radeon_device *rd
 	}
 	/* Resume clock after posting */
 	r420_clock_resume(rdev);
-
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r420_startup(rdev);
 }
 
 int r420_suspend(struct radeon_device *rdev)
 {
+	r420_cp_errata_fini(rdev);
 	r100_cp_disable(rdev);
 	r100_wb_disable(rdev);
 	r100_irq_disable(rdev);
@@ -258,7 +298,7 @@ void r420_fini(struct radeon_device *rde
 	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	if (rdev->is_atom_bios) {
 		radeon_atombios_fini(rdev);
 	} else {
@@ -301,14 +341,9 @@ int r420_init(struct radeon_device *rdev
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		if (rdev->is_atom_bios) {
-			atom_asic_init(rdev->mode_info.atom_context);
-		} else {
-			radeon_combios_asic_init(rdev->ddev);
-		}
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -331,10 +366,13 @@ int r420_init(struct radeon_device *rdev
 		return r;
 	}
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r) {
 		return r;
 	}
+	if (rdev->family == CHIP_R420)
+		r100_enable_bm(rdev);
+
 	if (rdev->flags & RADEON_IS_PCIE) {
 		r = rv370_pcie_gart_init(rdev);
 		if (r)
@@ -345,22 +383,21 @@ int r420_init(struct radeon_device *rdev
 		if (r)
 			return r;
 	}
-	r300_set_reg_safe(rdev);
+	r420_set_reg_safe(rdev);
 	rdev->accel_working = true;
 	r = r420_startup(rdev);
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		r420_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		if (rdev->flags & RADEON_IS_PCIE)
 			rv370_pcie_gart_fini(rdev);
 		if (rdev->flags & RADEON_IS_PCI)
 			r100_pci_gart_fini(rdev);
 		radeon_agp_fini(rdev);
-		radeon_irq_kms_fini(rdev);
 		rdev->accel_working = false;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r500_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r500_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r500_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r500_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -716,6 +716,8 @@
 
 #define AVIVO_DVOA_BIT_DEPTH_CONTROL			0x7988
 
+#define AVIVO_DC_GPIO_HPD_A                 0x7e94
+
 #define AVIVO_GPIO_0                        0x7e30
 #define AVIVO_GPIO_1                        0x7e40
 #define AVIVO_GPIO_2                        0x7e50
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r520.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r520.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r520.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r520.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,8 +185,8 @@ static int r520_startup(struct radeon_de
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -221,6 +221,8 @@ int r520_resume(struct radeon_device *rd
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return r520_startup(rdev);
 }
 
@@ -254,6 +256,9 @@ int r520_init(struct radeon_device *rdev
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	if (!radeon_card_posted(rdev) && rdev->bios) {
 		DRM_INFO("GPU not posted. posting now...\n");
 		atom_asic_init(rdev->mode_info.atom_context);
@@ -277,7 +282,7 @@ int r520_init(struct radeon_device *rdev
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rv370_pcie_gart_init(rdev);
@@ -289,13 +294,12 @@ int r520_init(struct radeon_device *rdev
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		rv515_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		rv370_pcie_gart_fini(rdev);
 		radeon_agp_fini(rdev);
-		radeon_irq_kms_fini(rdev);
 		rdev->accel_working = false;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_audio.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_audio.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_audio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_audio.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Christian König.
+ *
+ * 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: Christian König
+ */
+#include "drmP.h"
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "atom.h"
+
+#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */
+
+/*
+ * check if the chipset is supported
+ */
+static int r600_audio_chipset_supported(struct radeon_device *rdev)
+{
+	return (rdev->family >= CHIP_R600 && rdev->family < CHIP_RV710)
+		|| rdev->family == CHIP_RS600
+		|| rdev->family == CHIP_RS690
+		|| rdev->family == CHIP_RS740;
+}
+
+/*
+ * current number of channels
+ */
+static int r600_audio_channels(struct radeon_device *rdev)
+{
+	return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1;
+}
+
+/*
+ * current bits per sample
+ */
+static int r600_audio_bits_per_sample(struct radeon_device *rdev)
+{
+	uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
+	switch (value) {
+	case 0x0: return  8;
+	case 0x1: return 16;
+	case 0x2: return 20;
+	case 0x3: return 24;
+	case 0x4: return 32;
+	}
+
+	DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value);
+
+	return 16;
+}
+
+/*
+ * current sampling rate in HZ
+ */
+static int r600_audio_rate(struct radeon_device *rdev)
+{
+	uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
+	uint32_t result;
+
+	if (value & 0x4000)
+		result = 44100;
+	else
+		result = 48000;
+
+	result *= ((value >> 11) & 0x7) + 1;
+	result /= ((value >> 8) & 0x7) + 1;
+
+	return result;
+}
+
+/*
+ * iec 60958 status bits
+ */
+static uint8_t r600_audio_status_bits(struct radeon_device *rdev)
+{
+	return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
+}
+
+/*
+ * iec 60958 category code
+ */
+static uint8_t r600_audio_category_code(struct radeon_device *rdev)
+{
+	return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
+}
+
+/*
+ * update all hdmi interfaces with current audio parameters
+ */
+static void r600_audio_update_hdmi(unsigned long param)
+{
+	struct radeon_device *rdev = (struct radeon_device *)param;
+	struct drm_device *dev = rdev->ddev;
+
+	int channels = r600_audio_channels(rdev);
+	int rate = r600_audio_rate(rdev);
+	int bps = r600_audio_bits_per_sample(rdev);
+	uint8_t status_bits = r600_audio_status_bits(rdev);
+	uint8_t category_code = r600_audio_category_code(rdev);
+
+	struct drm_encoder *encoder;
+	int changes = 0;
+
+	changes |= channels != rdev->audio_channels;
+	changes |= rate != rdev->audio_rate;
+	changes |= bps != rdev->audio_bits_per_sample;
+	changes |= status_bits != rdev->audio_status_bits;
+	changes |= category_code != rdev->audio_category_code;
+
+	if (changes) {
+		rdev->audio_channels = channels;
+		rdev->audio_rate = rate;
+		rdev->audio_bits_per_sample = bps;
+		rdev->audio_status_bits = status_bits;
+		rdev->audio_category_code = category_code;
+	}
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (changes || r600_hdmi_buffer_status_changed(encoder))
+			r600_hdmi_update_audio_settings(
+				encoder, channels,
+				rate, bps, status_bits,
+				category_code);
+	}
+
+	mod_timer(&rdev->audio_timer,
+		jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));
+}
+
+/*
+ * initialize the audio vars and register the update timer
+ */
+int r600_audio_init(struct radeon_device *rdev)
+{
+	if (!r600_audio_chipset_supported(rdev))
+		return 0;
+
+	DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling");
+	WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000);
+
+	rdev->audio_channels = -1;
+	rdev->audio_rate = -1;
+	rdev->audio_bits_per_sample = -1;
+	rdev->audio_status_bits = 0;
+	rdev->audio_category_code = 0;
+
+	setup_timer(
+		&rdev->audio_timer,
+		r600_audio_update_hdmi,
+		(unsigned long)rdev);
+
+	mod_timer(&rdev->audio_timer, jiffies + 1);
+
+	return 0;
+}
+
+/*
+ * determin how the encoders and audio interface is wired together
+ */
+int r600_audio_tmds_index(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_encoder *other;
+
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+		return 0;
+
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		/* special case check if an TMDS1 is present */
+		list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
+			if (to_radeon_encoder(other)->encoder_id ==
+				ENCODER_OBJECT_ID_INTERNAL_TMDS1)
+				return 1;
+		}
+		return 0;
+
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		return 1;
+
+	default:
+		DRM_ERROR("Unsupported encoder type 0x%02X\n",
+			  radeon_encoder->encoder_id);
+		return -1;
+	}
+}
+
+/*
+ * atach the audio codec to the clock source of the encoder
+ */
+void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	int base_rate = 48000;
+
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
+		break;
+
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
+		break;
+
+	default:
+		DRM_ERROR("Unsupported encoder type 0x%02X\n",
+			  radeon_encoder->encoder_id);
+		return;
+	}
+
+	switch (r600_audio_tmds_index(encoder)) {
+	case 0:
+		WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
+		WREG32(R600_AUDIO_PLL1_DIV, clock*100);
+		WREG32(R600_AUDIO_CLK_SRCSEL, 0);
+		break;
+
+	case 1:
+		WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
+		WREG32(R600_AUDIO_PLL2_DIV, clock*100);
+		WREG32(R600_AUDIO_CLK_SRCSEL, 1);
+		break;
+	}
+}
+
+/*
+ * release the audio timer
+ * TODO: How to do this correctly on SMP systems?
+ */
+void r600_audio_fini(struct radeon_device *rdev)
+{
+	if (!r600_audio_chipset_supported(rdev))
+		return;
+
+	del_timer(&rdev->audio_timer);
+	WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_blit_kms.c	2010-02-24 13:52:17.000000000 -0500
@@ -449,6 +449,7 @@ int r600_blit_init(struct radeon_device
 	u32 packet2s[16];
 	int num_packet2s = 0;
 
+	mutex_init(&rdev->r600_blit.mutex);
 	rdev->r600_blit.state_offset = 0;
 
 	if (rdev->family >= CHIP_RV770)
@@ -473,9 +474,8 @@ int r600_blit_init(struct radeon_device
 	obj_size += r6xx_ps_size * 4;
 	obj_size = ALIGN(obj_size, 256);
 
-	r = radeon_object_create(rdev, NULL, obj_size,
-				 true, RADEON_GEM_DOMAIN_VRAM,
-				 false, &rdev->r600_blit.shader_obj);
+	r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+				&rdev->r600_blit.shader_obj);
 	if (r) {
 		DRM_ERROR("r600 failed to allocate shader\n");
 		return r;
@@ -485,12 +485,14 @@ int r600_blit_init(struct radeon_device
 		  obj_size,
 		  rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
 
-	r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr);
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr);
 	if (r) {
 		DRM_ERROR("failed to map blit object %d\n", r);
 		return r;
 	}
-
 	if (rdev->family >= CHIP_RV770)
 		memcpy_toio(ptr + rdev->r600_blit.state_offset,
 			    r7xx_default_state, rdev->r600_blit.state_len * 4);
@@ -500,19 +502,28 @@ int r600_blit_init(struct radeon_device
 	if (num_packet2s)
 		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
 			    packet2s, num_packet2s * 4);
-
-
 	memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
 	memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
-
-	radeon_object_kunmap(rdev->r600_blit.shader_obj);
+	radeon_bo_kunmap(rdev->r600_blit.shader_obj);
+	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 	return 0;
 }
 
 void r600_blit_fini(struct radeon_device *rdev)
 {
-	radeon_object_unpin(rdev->r600_blit.shader_obj);
-	radeon_object_unref(&rdev->r600_blit.shader_obj);
+	int r;
+
+	if (rdev->r600_blit.shader_obj == NULL)
+		return;
+	/* If we can't reserve the bo, unref should be enough to destroy
+	 * it when it becomes idle.
+	 */
+	r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+	if (!r) {
+		radeon_bo_unpin(rdev->r600_blit.shader_obj);
+		radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+	}
+	radeon_bo_unref(&rdev->r600_blit.shader_obj);
 }
 
 int r600_vb_ib_get(struct radeon_device *rdev)
@@ -532,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device
 void r600_vb_ib_put(struct radeon_device *rdev)
 {
 	radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
-	mutex_lock(&rdev->ib_pool.mutex);
-	list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
-	mutex_unlock(&rdev->ib_pool.mutex);
 	radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
 }
 
@@ -547,7 +555,8 @@ int r600_blit_prepare_copy(struct radeon
 	int dwords_per_loop = 76, num_loops;
 
 	r = r600_vb_ib_get(rdev);
-	WARN_ON(r);
+	if (r)
+		return r;
 
 	/* set_render_target emits 2 extra dwords on rv6xx */
 	if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
@@ -569,11 +578,12 @@ int r600_blit_prepare_copy(struct radeon
 	ring_size = num_loops * dwords_per_loop;
 	/* set default  + shaders */
 	ring_size += 40; /* shaders + def state */
-	ring_size += 3; /* fence emit for VB IB */
+	ring_size += 7; /* fence emit for VB IB */
 	ring_size += 5; /* done copy */
-	ring_size += 3; /* fence emit for done copy */
+	ring_size += 7; /* fence emit for done copy */
 	r = radeon_ring_lock(rdev, ring_size);
-	WARN_ON(r);
+	if (r)
+		return r;
 
 	set_default_state(rdev); /* 14 */
 	set_shaders(rdev); /* 26 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600.c	2013-05-03 13:55:55.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600.c	2013-05-03 12:03:47.000000000 -0400
@@ -38,8 +38,10 @@
 
 #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
 
 /* Firmware Names */
 /*(DEBLOBBED)*/
@@ -51,6 +53,282 @@ int r600_mc_wait_for_idle(struct radeon_
 void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 
+/* hpd for digital panel detect/disconnect */
+bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	bool connected = false;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_2:
+			if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_3:
+			if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_4:
+			if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+			/* DCE 3.2 */
+		case RADEON_HPD_5:
+			if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_6:
+			if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
+				connected = true;
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_2:
+			if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		case RADEON_HPD_3:
+			if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
+				connected = true;
+			break;
+		default:
+			break;
+		}
+	}
+	return connected;
+}
+
+void r600_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = r600_hpd_sense(rdev, hpd);
+
+	if (ASIC_IS_DCE3(rdev)) {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			tmp = RREG32(DC_HPD1_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD1_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_2:
+			tmp = RREG32(DC_HPD2_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD2_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_3:
+			tmp = RREG32(DC_HPD3_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD3_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_4:
+			tmp = RREG32(DC_HPD4_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD4_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_5:
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD5_INT_CONTROL, tmp);
+			break;
+			/* DCE 3.2 */
+		case RADEON_HPD_6:
+			tmp = RREG32(DC_HPD6_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HPDx_INT_POLARITY;
+			else
+				tmp |= DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD6_INT_CONTROL, tmp);
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (hpd) {
+		case RADEON_HPD_1:
+			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_2:
+			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+			break;
+		case RADEON_HPD_3:
+			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
+			if (connected)
+				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			else
+				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
+			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void r600_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
+		if (ASIC_IS_DCE32(rdev))
+			tmp |= DC_HPDx_EN;
+
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HPD1_CONTROL, tmp);
+				rdev->irq.hpd[0] = true;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HPD2_CONTROL, tmp);
+				rdev->irq.hpd[1] = true;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HPD3_CONTROL, tmp);
+				rdev->irq.hpd[2] = true;
+				break;
+			case RADEON_HPD_4:
+				WREG32(DC_HPD4_CONTROL, tmp);
+				rdev->irq.hpd[3] = true;
+				break;
+				/* DCE 3.2 */
+			case RADEON_HPD_5:
+				WREG32(DC_HPD5_CONTROL, tmp);
+				rdev->irq.hpd[4] = true;
+				break;
+			case RADEON_HPD_6:
+				WREG32(DC_HPD6_CONTROL, tmp);
+				rdev->irq.hpd[5] = true;
+				break;
+			default:
+				break;
+			}
+		}
+	} else {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[0] = true;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[1] = true;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+				rdev->irq.hpd[2] = true;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	if (rdev->irq.installed)
+		r600_irq_set(rdev);
+}
+
+void r600_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HPD1_CONTROL, 0);
+				rdev->irq.hpd[0] = false;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HPD2_CONTROL, 0);
+				rdev->irq.hpd[1] = false;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HPD3_CONTROL, 0);
+				rdev->irq.hpd[2] = false;
+				break;
+			case RADEON_HPD_4:
+				WREG32(DC_HPD4_CONTROL, 0);
+				rdev->irq.hpd[3] = false;
+				break;
+				/* DCE 3.2 */
+			case RADEON_HPD_5:
+				WREG32(DC_HPD5_CONTROL, 0);
+				rdev->irq.hpd[4] = false;
+				break;
+			case RADEON_HPD_6:
+				WREG32(DC_HPD6_CONTROL, 0);
+				rdev->irq.hpd[5] = false;
+				break;
+			default:
+				break;
+			}
+		}
+	} else {
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			switch (radeon_connector->hpd.hpd) {
+			case RADEON_HPD_1:
+				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
+				rdev->irq.hpd[0] = false;
+				break;
+			case RADEON_HPD_2:
+				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
+				rdev->irq.hpd[1] = false;
+				break;
+			case RADEON_HPD_3:
+				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
+				rdev->irq.hpd[2] = false;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
 /*
  * R600 PCIE GART
  */
@@ -161,7 +439,7 @@ int r600_pcie_gart_enable(struct radeon_
 void r600_pcie_gart_disable(struct radeon_device *rdev)
 {
 	u32 tmp;
-	int i;
+	int i, r;
 
 	/* Disable all tables */
 	for (i = 0; i < 7; i++)
@@ -189,8 +467,12 @@ void r600_pcie_gart_disable(struct radeo
 	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
 	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -321,7 +603,6 @@ int r600_mc_init(struct radeon_device *r
 	fixed20_12 a;
 	u32 tmp;
 	int chansize, numchan;
-	int r;
 
 	/* Get VRAM informations */
 	rdev->mc.vram_is_ddr = true;
@@ -364,9 +645,6 @@ int r600_mc_init(struct radeon_device *r
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
 
 	if (rdev->flags & RADEON_IS_AGP) {
-		r = radeon_agp_init(rdev);
-		if (r)
-			return r;
 		/* gtt_size is setup by radeon_agp_init */
 		rdev->mc.gtt_location = rdev->mc.agp_base;
 		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
@@ -375,11 +653,11 @@ int r600_mc_init(struct radeon_device *r
 		 * AGP so that GPU can catch out of VRAM/AGP access
 		 */
 		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enought place before */
+			/* Enough place before */
 			rdev->mc.vram_location = rdev->mc.gtt_location -
 							rdev->mc.mc_vram_size;
 		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enought place after */
+			/* Enough place after */
 			rdev->mc.vram_location = rdev->mc.gtt_location +
 							rdev->mc.gtt_size;
 		} else {
@@ -424,6 +702,10 @@ int r600_mc_init(struct radeon_device *r
 	a.full = rfixed_const(100);
 	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
 	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+
+	if (rdev->flags & RADEON_IS_IGP)
+		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+
 	return 0;
 }
 
@@ -1082,7 +1364,6 @@ void r600_pciep_wreg(struct radeon_devic
 	(void)RREG32(PCIE_PORT_DATA);
 }
 
-
 /*
  * CP & Ring
  */
@@ -1091,11 +1372,12 @@ void r600_cp_stop(struct radeon_device *
 	WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
 }
 
-int r600_cp_init_microcode(struct radeon_device *rdev)
+int r600_init_microcode(struct radeon_device *rdev)
 {
 	struct platform_device *pdev;
 	const char *chip_name;
-	size_t pfp_req_size, me_req_size;
+	const char *rlc_chip_name;
+	size_t pfp_req_size, me_req_size, rlc_req_size;
 	char fw_name[30];
 	int err;
 
@@ -1109,30 +1391,62 @@ int r600_cp_init_microcode(struct radeon
 	}
 
 	switch (rdev->family) {
-	case CHIP_R600: chip_name = "R600"; break;
-	case CHIP_RV610: chip_name = "RV610"; break;
-	case CHIP_RV630: chip_name = "RV630"; break;
-	case CHIP_RV620: chip_name = "RV620"; break;
-	case CHIP_RV635: chip_name = "RV635"; break;
-	case CHIP_RV670: chip_name = "RV670"; break;
+	case CHIP_R600:
+		chip_name = "R600";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV610:
+		chip_name = "RV610";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV630:
+		chip_name = "RV630";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV620:
+		chip_name = "RV620";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV635:
+		chip_name = "RV635";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV670:
+		chip_name = "RV670";
+		rlc_chip_name = "R600";
+		break;
 	case CHIP_RS780:
-	case CHIP_RS880: chip_name = "RS780"; break;
-	case CHIP_RV770: chip_name = "RV770"; break;
+	case CHIP_RS880:
+		chip_name = "RS780";
+		rlc_chip_name = "R600";
+		break;
+	case CHIP_RV770:
+		chip_name = "RV770";
+		rlc_chip_name = "R700";
+		break;
 	case CHIP_RV730:
-	case CHIP_RV740: chip_name = "RV730"; break;
-	case CHIP_RV710: chip_name = "RV710"; break;
+	case CHIP_RV740:
+		chip_name = "RV730";
+		rlc_chip_name = "R700";
+		break;
+	case CHIP_RV710:
+		chip_name = "RV710";
+		rlc_chip_name = "R700";
+		break;
 	default: BUG();
 	}
 
 	if (rdev->family >= CHIP_RV770) {
 		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
 		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;
 	}
 
-	DRM_INFO("Loading %s CP Microcode\n", chip_name);
+	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);
@@ -1156,6 +1470,18 @@ int r600_cp_init_microcode(struct radeon
 		       rdev->me_fw->size, fw_name);
 		err = -EINVAL;
 	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", rlc_chip_name);
+	err = reject_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (rdev->rlc_fw->size != rlc_req_size) {
+		printk(KERN_ERR
+		       "r600_rlc: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->rlc_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
 out:
 	platform_device_unregister(pdev);
 
@@ -1168,6 +1494,8 @@ out:
 		rdev->pfp_fw = NULL;
 		release_firmware(rdev->me_fw);
 		rdev->me_fw = NULL;
+		release_firmware(rdev->rlc_fw);
+		rdev->rlc_fw = NULL;
 	}
 	return err;
 }
@@ -1305,6 +1633,12 @@ void r600_ring_init(struct radeon_device
 	rdev->cp.align_mask = 16 - 1;
 }
 
+void r600_cp_fini(struct radeon_device *rdev)
+{
+	r600_cp_stop(rdev);
+	radeon_ring_fini(rdev);
+}
+
 
 /*
  * GPU scratch registers helpers function.
@@ -1362,10 +1696,16 @@ int r600_ring_test(struct radeon_device
 
 void r600_wb_disable(struct radeon_device *rdev)
 {
+	int r;
+
 	WREG32(SCRATCH_UMSK, 0);
 	if (rdev->wb.wb_obj) {
-		radeon_object_kunmap(rdev->wb.wb_obj);
-		radeon_object_unpin(rdev->wb.wb_obj);
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0))
+			return;
+		radeon_bo_kunmap(rdev->wb.wb_obj);
+		radeon_bo_unpin(rdev->wb.wb_obj);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
 	}
 }
 
@@ -1373,7 +1713,7 @@ void r600_wb_fini(struct radeon_device *
 {
 	r600_wb_disable(rdev);
 	if (rdev->wb.wb_obj) {
-		radeon_object_unref(&rdev->wb.wb_obj);
+		radeon_bo_unref(&rdev->wb.wb_obj);
 		rdev->wb.wb = NULL;
 		rdev->wb.wb_obj = NULL;
 	}
@@ -1384,22 +1724,29 @@ int r600_wb_enable(struct radeon_device
 	int r;
 
 	if (rdev->wb.wb_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
-				RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
+		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+				RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
 		if (r) {
-			dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
+			dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+		r = radeon_bo_reserve(rdev->wb.wb_obj, false);
+		if (unlikely(r != 0)) {
+			r600_wb_fini(rdev);
+			return r;
+		}
+		r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
 				&rdev->wb.gpu_addr);
 		if (r) {
-			dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
+			radeon_bo_unreserve(rdev->wb.wb_obj);
+			dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r);
 			r600_wb_fini(rdev);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		radeon_bo_unreserve(rdev->wb.wb_obj);
 		if (r) {
-			dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
+			dev_warn(rdev->dev, "(%d) map WB bo failed\n", r);
 			r600_wb_fini(rdev);
 			return r;
 		}
@@ -1414,41 +1761,36 @@ int r600_wb_enable(struct radeon_device
 void r600_fence_ring_emit(struct radeon_device *rdev,
 			  struct radeon_fence *fence)
 {
+	/* Also consider EVENT_WRITE_EOP.  it handles the interrupts + timestamps + events */
 	/* Emit fence sequence & fire IRQ */
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
 	radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
 	radeon_ring_write(rdev, fence->seq);
-}
-
-int r600_copy_dma(struct radeon_device *rdev,
-		  uint64_t src_offset,
-		  uint64_t dst_offset,
-		  unsigned num_pages,
-		  struct radeon_fence *fence)
-{
-	/* FIXME: implement */
-	return 0;
+	radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
+	radeon_ring_write(rdev, 1);
+	/* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
+	radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
+	radeon_ring_write(rdev, RB_INT_STAT);
 }
 
 int r600_copy_blit(struct radeon_device *rdev,
 		   uint64_t src_offset, uint64_t dst_offset,
 		   unsigned num_pages, struct radeon_fence *fence)
 {
-	r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+	int r;
+
+	mutex_lock(&rdev->r600_blit.mutex);
+	rdev->r600_blit.vb_ib = NULL;
+	r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+	if (r) {
+		if (rdev->r600_blit.vb_ib)
+			radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
+		mutex_unlock(&rdev->r600_blit.mutex);
+		return r;
+	}
 	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
 	r600_blit_done_copy(rdev, fence);
-	return 0;
-}
-
-int r600_irq_process(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-	return 0;
-}
-
-int r600_irq_set(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
+	mutex_unlock(&rdev->r600_blit.mutex);
 	return 0;
 }
 
@@ -1487,6 +1829,14 @@ int r600_startup(struct radeon_device *r
 {
 	int r;
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
 	r600_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		r600_agp_enable(rdev);
@@ -1496,13 +1846,33 @@ int r600_startup(struct radeon_device *r
 			return r;
 	}
 	r600_gpu_init(rdev);
-
-	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
-			      &rdev->r600_blit.shader_gpu_addr);
+	r = r600_blit_init(rdev);
 	if (r) {
-		DRM_ERROR("failed to pin blit object %d\n", r);
+		r600_blit_fini(rdev);
+		rdev->asic->copy = NULL;
+		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
+	}
+	/* pin copy shader into vram */
+	if (rdev->r600_blit.shader_obj) {
+		r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+				&rdev->r600_blit.shader_gpu_addr);
+		radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+		if (r) {
+			dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
+			return r;
+		}
+	}
+	/* Enable IRQ */
+	r = r600_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
 		return r;
 	}
+	r600_irq_set(rdev);
 
 	r = radeon_ring_init(rdev, rdev->cp.ring_size);
 	if (r)
@@ -1559,18 +1929,35 @@ int r600_resume(struct radeon_device *rd
 		DRM_ERROR("radeon: failled testing IB (%d).\n", r);
 		return r;
 	}
+
+	r = r600_audio_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: audio resume failed\n");
+		return r;
+	}
+
 	return r;
 }
 
 int r600_suspend(struct radeon_device *rdev)
 {
+	int r;
+
+	r600_audio_fini(rdev);
 	/* FIXME: we should wait for ring to be empty */
 	r600_cp_stop(rdev);
 	rdev->cp.ready = false;
+	r600_irq_suspend(rdev);
 	r600_wb_disable(rdev);
 	r600_pcie_gart_disable(rdev);
 	/* unpin shaders bo */
-	radeon_object_unpin(rdev->r600_blit.shader_obj);
+	if (rdev->r600_blit.shader_obj) {
+		r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+		if (!r) {
+			radeon_bo_unpin(rdev->r600_blit.shader_obj);
+			radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+		}
+	}
 	return 0;
 }
 
@@ -1608,7 +1995,11 @@ int r600_init(struct radeon_device *rdev
 	if (r)
 		return r;
 	/* Post card if necessary */
-	if (!r600_card_posted(rdev) && rdev->bios) {
+	if (!r600_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);
 	}
@@ -1627,73 +2018,78 @@ int r600_init(struct radeon_device *rdev
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r)
+			radeon_agp_disable(rdev);
+	}
 	r = r600_mc_init(rdev);
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
+	if (r)
+		return r;
+
+	r = radeon_irq_kms_init(rdev);
 	if (r)
 		return r;
+
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
-	if (!rdev->me_fw || !rdev->pfp_fw) {
-		r = r600_cp_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
+	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 = r600_blit_init(rdev);
-	if (r) {
-		DRM_ERROR("radeon: failled blitter (%d).\n", r);
-		return r;
-	}
-
 	r = r600_startup(rdev);
 	if (r) {
-		r600_suspend(rdev);
+		dev_err(rdev->dev, "disabling GPU acceleration\n");
+		r600_cp_fini(rdev);
 		r600_wb_fini(rdev);
-		radeon_ring_fini(rdev);
+		r600_irq_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		r600_pcie_gart_fini(rdev);
 		rdev->accel_working = false;
 	}
 	if (rdev->accel_working) {
 		r = radeon_ib_pool_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
-			rdev->accel_working = false;
-		}
-		r = r600_ib_test(rdev);
-		if (r) {
-			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
 			rdev->accel_working = false;
+		} else {
+			r = r600_ib_test(rdev);
+			if (r) {
+				dev_err(rdev->dev, "IB test failed (%d).\n", r);
+				rdev->accel_working = false;
+			}
 		}
 	}
+
+	r = r600_audio_init(rdev);
+	if (r)
+		return r; /* TODO error handling */
 	return 0;
 }
 
 void r600_fini(struct radeon_device *rdev)
 {
-	/* Suspend operations */
-	r600_suspend(rdev);
-
+	r600_audio_fini(rdev);
 	r600_blit_fini(rdev);
-	radeon_ring_fini(rdev);
+	r600_cp_fini(rdev);
 	r600_wb_fini(rdev);
+	r600_irq_fini(rdev);
+	radeon_irq_kms_fini(rdev);
 	r600_pcie_gart_fini(rdev);
+	radeon_agp_fini(rdev);
 	radeon_gem_fini(rdev);
 	radeon_fence_driver_fini(rdev);
 	radeon_clocks_fini(rdev);
-	if (rdev->flags & RADEON_IS_AGP)
-		radeon_agp_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -1779,8 +2175,668 @@ int r600_ib_test(struct radeon_device *r
 	return r;
 }
 
+/*
+ * Interrupts
+ *
+ * Interrupts use a ring buffer on r6xx/r7xx hardware.  It works pretty
+ * the same as the CP ring buffer, but in reverse.  Rather than the CPU
+ * writing to the ring and the GPU consuming, the GPU writes to the ring
+ * and host consumes.  As the host irq handler processes interrupts, it
+ * increments the rptr.  When the rptr catches up with the wptr, all the
+ * current interrupts have been processed.
+ */
 
+void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
+{
+	u32 rb_bufsz;
 
+	/* Align ring size */
+	rb_bufsz = drm_order(ring_size / 4);
+	ring_size = (1 << rb_bufsz) * 4;
+	rdev->ih.ring_size = ring_size;
+	rdev->ih.ptr_mask = rdev->ih.ring_size - 1;
+	rdev->ih.rptr = 0;
+}
+
+static int r600_ih_ring_alloc(struct radeon_device *rdev)
+{
+	int r;
+
+	/* Allocate ring buffer */
+	if (rdev->ih.ring_obj == NULL) {
+		r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
+				     true,
+				     RADEON_GEM_DOMAIN_GTT,
+				     &rdev->ih.ring_obj);
+		if (r) {
+			DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->ih.ring_obj,
+				  RADEON_GEM_DOMAIN_GTT,
+				  &rdev->ih.gpu_addr);
+		if (r) {
+			radeon_bo_unreserve(rdev->ih.ring_obj);
+			DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_bo_kmap(rdev->ih.ring_obj,
+				   (void **)&rdev->ih.ring);
+		radeon_bo_unreserve(rdev->ih.ring_obj);
+		if (r) {
+			DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
+			return r;
+		}
+	}
+	return 0;
+}
+
+static void r600_ih_ring_fini(struct radeon_device *rdev)
+{
+	int r;
+	if (rdev->ih.ring_obj) {
+		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->ih.ring_obj);
+			radeon_bo_unpin(rdev->ih.ring_obj);
+			radeon_bo_unreserve(rdev->ih.ring_obj);
+		}
+		radeon_bo_unref(&rdev->ih.ring_obj);
+		rdev->ih.ring = NULL;
+		rdev->ih.ring_obj = NULL;
+	}
+}
+
+static void r600_rlc_stop(struct radeon_device *rdev)
+{
+
+	if (rdev->family >= CHIP_RV770) {
+		/* r7xx asics need to soft reset RLC before halting */
+		WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
+		RREG32(SRBM_SOFT_RESET);
+		udelay(15000);
+		WREG32(SRBM_SOFT_RESET, 0);
+		RREG32(SRBM_SOFT_RESET);
+	}
+
+	WREG32(RLC_CNTL, 0);
+}
+
+static void r600_rlc_start(struct radeon_device *rdev)
+{
+	WREG32(RLC_CNTL, RLC_ENABLE);
+}
+
+static int r600_rlc_init(struct radeon_device *rdev)
+{
+	u32 i;
+	const __be32 *fw_data;
+
+	if (!rdev->rlc_fw)
+		return -EINVAL;
+
+	r600_rlc_stop(rdev);
+
+	WREG32(RLC_HB_BASE, 0);
+	WREG32(RLC_HB_CNTL, 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_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++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	}
+	WREG32(RLC_UCODE_ADDR, 0);
+
+	r600_rlc_start(rdev);
+
+	return 0;
+}
+
+static void r600_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;
+}
+
+static void r600_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.wptr = 0;
+	rdev->ih.rptr = 0;
+}
+
+static void r600_disable_interrupt_state(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(CP_INT_CNTL, 0);
+	WREG32(GRBM_INT_CNTL, 0);
+	WREG32(DxMODE_INT_MASK, 0);
+	if (ASIC_IS_DCE3(rdev)) {
+		WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
+		WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
+		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);
+		if (ASIC_IS_DCE32(rdev)) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD5_INT_CONTROL, 0);
+			tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+			WREG32(DC_HPD6_INT_CONTROL, 0);
+		}
+	} else {
+		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
+		WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+		tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
+		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
+	}
+}
+
+int r600_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 */
+	r600_disable_interrupts(rdev);
+
+	/* init rlc */
+	ret = r600_rlc_init(rdev);
+	if (ret) {
+		r600_ih_ring_fini(rdev);
+		return ret;
+	}
+
+	/* setup interrupt control */
+	/* set dummy read address to ring address */
+	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));
+	/* WPTR writeback, not yet */
+	/*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/
+	WREG32(IH_RB_WPTR_ADDR_LO, 0);
+	WREG32(IH_RB_WPTR_ADDR_HI, 0);
+
+	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);
+	/* RPTR_REARM only works if msi's are enabled */
+	if (rdev->msi_enabled)
+		ih_cntl |= RPTR_REARM;
+
+#ifdef __BIG_ENDIAN
+	ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT);
+#endif
+	WREG32(IH_CNTL, ih_cntl);
+
+	/* force the active interrupt state to all disabled */
+	r600_disable_interrupt_state(rdev);
+
+	/* enable irqs */
+	r600_enable_interrupts(rdev);
+
+	return ret;
+}
+
+void r600_irq_suspend(struct radeon_device *rdev)
+{
+	r600_disable_interrupts(rdev);
+	r600_rlc_stop(rdev);
+}
+
+void r600_irq_fini(struct radeon_device *rdev)
+{
+	r600_irq_suspend(rdev);
+	r600_ih_ring_fini(rdev);
+}
+
+int r600_irq_set(struct radeon_device *rdev)
+{
+	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
+	u32 mode_int = 0;
+	u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
+
+	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) {
+		r600_disable_interrupts(rdev);
+		/* force the active interrupt state to all disabled */
+		r600_disable_interrupt_state(rdev);
+		return 0;
+	}
+
+	if (ASIC_IS_DCE3(rdev)) {
+		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;
+		if (ASIC_IS_DCE32(rdev)) {
+			hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
+			hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		}
+	} else {
+		hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN;
+		hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	}
+
+	if (rdev->irq.sw_int) {
+		DRM_DEBUG("r600_irq_set: sw int\n");
+		cp_int_cntl |= RB_INT_ENABLE;
+	}
+	if (rdev->irq.crtc_vblank_int[0]) {
+		DRM_DEBUG("r600_irq_set: vblank 0\n");
+		mode_int |= D1MODE_VBLANK_INT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[1]) {
+		DRM_DEBUG("r600_irq_set: vblank 1\n");
+		mode_int |= D2MODE_VBLANK_INT_MASK;
+	}
+	if (rdev->irq.hpd[0]) {
+		DRM_DEBUG("r600_irq_set: hpd 1\n");
+		hpd1 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[1]) {
+		DRM_DEBUG("r600_irq_set: hpd 2\n");
+		hpd2 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[2]) {
+		DRM_DEBUG("r600_irq_set: hpd 3\n");
+		hpd3 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[3]) {
+		DRM_DEBUG("r600_irq_set: hpd 4\n");
+		hpd4 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[4]) {
+		DRM_DEBUG("r600_irq_set: hpd 5\n");
+		hpd5 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[5]) {
+		DRM_DEBUG("r600_irq_set: hpd 6\n");
+		hpd6 |= DC_HPDx_INT_EN;
+	}
+
+	WREG32(CP_INT_CNTL, cp_int_cntl);
+	WREG32(DxMODE_INT_MASK, mode_int);
+	if (ASIC_IS_DCE3(rdev)) {
+		WREG32(DC_HPD1_INT_CONTROL, hpd1);
+		WREG32(DC_HPD2_INT_CONTROL, hpd2);
+		WREG32(DC_HPD3_INT_CONTROL, hpd3);
+		WREG32(DC_HPD4_INT_CONTROL, hpd4);
+		if (ASIC_IS_DCE32(rdev)) {
+			WREG32(DC_HPD5_INT_CONTROL, hpd5);
+			WREG32(DC_HPD6_INT_CONTROL, hpd6);
+		}
+	} else {
+		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
+		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
+		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
+	}
+
+	return 0;
+}
+
+static inline void r600_irq_ack(struct radeon_device *rdev,
+				u32 *disp_int,
+				u32 *disp_int_cont,
+				u32 *disp_int_cont2)
+{
+	u32 tmp;
+
+	if (ASIC_IS_DCE3(rdev)) {
+		*disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
+		*disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
+		*disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
+	} else {
+		*disp_int = RREG32(DISP_INTERRUPT_STATUS);
+		*disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
+		*disp_int_cont2 = 0;
+	}
+
+	if (*disp_int & LB_D1_VBLANK_INTERRUPT)
+		WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
+	if (*disp_int & LB_D1_VLINE_INTERRUPT)
+		WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
+	if (*disp_int & LB_D2_VBLANK_INTERRUPT)
+		WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
+	if (*disp_int & LB_D2_VLINE_INTERRUPT)
+		WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
+	if (*disp_int & DC_HPD1_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD1_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD1_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int & DC_HPD2_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD2_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD2_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int_cont & DC_HPD3_INTERRUPT) {
+		if (ASIC_IS_DCE3(rdev)) {
+			tmp = RREG32(DC_HPD3_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD3_INT_CONTROL, tmp);
+		} else {
+			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
+		}
+	}
+	if (*disp_int_cont & DC_HPD4_INTERRUPT) {
+		tmp = RREG32(DC_HPD4_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD4_INT_CONTROL, tmp);
+	}
+	if (ASIC_IS_DCE32(rdev)) {
+		if (*disp_int_cont2 & DC_HPD5_INTERRUPT) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD5_INT_CONTROL, tmp);
+		}
+		if (*disp_int_cont2 & DC_HPD6_INTERRUPT) {
+			tmp = RREG32(DC_HPD5_INT_CONTROL);
+			tmp |= DC_HPDx_INT_ACK;
+			WREG32(DC_HPD6_INT_CONTROL, tmp);
+		}
+	}
+}
+
+void r600_irq_disable(struct radeon_device *rdev)
+{
+	u32 disp_int, disp_int_cont, disp_int_cont2;
+
+	r600_disable_interrupts(rdev);
+	/* Wait and acknowledge irq */
+	mdelay(1);
+	r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
+	r600_disable_interrupt_state(rdev);
+}
+
+static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
+{
+	u32 wptr, tmp;
+
+	/* XXX use writeback */
+	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);
+}
+
+/*        r600 IV Ring
+ * Each IV ring entry is 128 bits:
+ * [7:0]    - interrupt source id
+ * [31:8]   - reserved
+ * [59:32]  - interrupt source data
+ * [127:60]  - reserved
+ *
+ * The basic interrupt vector entries
+ * are decoded as follows:
+ * src_id  src_data  description
+ *      1         0  D1 Vblank
+ *      1         1  D1 Vline
+ *      5         0  D2 Vblank
+ *      5         1  D2 Vline
+ *     19         0  FP Hot plug detection A
+ *     19         1  FP Hot plug detection B
+ *     19         2  DAC A auto-detection
+ *     19         3  DAC B auto-detection
+ *    176         -  CP_INT RB
+ *    177         -  CP_INT IB1
+ *    178         -  CP_INT IB2
+ *    181         -  EOP Interrupt
+ *    233         -  GUI Idle
+ *
+ * Note, these are based on r600 and may need to be
+ * adjusted or added to on newer asics
+ */
+
+int r600_irq_process(struct radeon_device *rdev)
+{
+	u32 wptr = r600_get_ih_wptr(rdev);
+	u32 rptr = rdev->ih.rptr;
+	u32 src_id, src_data;
+	u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
+	unsigned long flags;
+	bool queue_hotplug = false;
+
+	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+	if (!rdev->ih.enabled)
+		return IRQ_NONE;
+
+	spin_lock_irqsave(&rdev->ih.lock, flags);
+
+	if (rptr == wptr) {
+		spin_unlock_irqrestore(&rdev->ih.lock, flags);
+		return IRQ_NONE;
+	}
+	if (rdev->shutdown) {
+		spin_unlock_irqrestore(&rdev->ih.lock, flags);
+		return IRQ_NONE;
+	}
+
+restart_ih:
+	/* display interrupts */
+	r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
+
+	rdev->ih.wptr = wptr;
+	while (rptr != wptr) {
+		/* wptr/rptr are in bytes! */
+		ring_index = rptr / 4;
+		src_id =  rdev->ih.ring[ring_index] & 0xff;
+		src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
+
+		switch (src_id) {
+		case 1: /* D1 vblank/vline */
+			switch (src_data) {
+			case 0: /* D1 vblank */
+				if (disp_int & LB_D1_VBLANK_INTERRUPT) {
+					drm_handle_vblank(rdev->ddev, 0);
+					disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D1 vblank\n");
+				}
+				break;
+			case 1: /* D1 vline */
+				if (disp_int & LB_D1_VLINE_INTERRUPT) {
+					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 5: /* D2 vblank/vline */
+			switch (src_data) {
+			case 0: /* D2 vblank */
+				if (disp_int & LB_D2_VBLANK_INTERRUPT) {
+					drm_handle_vblank(rdev->ddev, 1);
+					disp_int &= ~LB_D2_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D2 vblank\n");
+				}
+				break;
+			case 1: /* D1 vline */
+				if (disp_int & LB_D2_VLINE_INTERRUPT) {
+					disp_int &= ~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 19: /* HPD/DAC hotplug */
+			switch (src_data) {
+			case 0:
+				if (disp_int & DC_HPD1_INTERRUPT) {
+					disp_int &= ~DC_HPD1_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD1\n");
+				}
+				break;
+			case 1:
+				if (disp_int & DC_HPD2_INTERRUPT) {
+					disp_int &= ~DC_HPD2_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD2\n");
+				}
+				break;
+			case 4:
+				if (disp_int_cont & DC_HPD3_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD3_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD3\n");
+				}
+				break;
+			case 5:
+				if (disp_int_cont & DC_HPD4_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD4_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD4\n");
+				}
+				break;
+			case 10:
+				if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
+					disp_int_cont &= ~DC_HPD5_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD5\n");
+				}
+				break;
+			case 12:
+				if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
+					disp_int_cont &= ~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 176: /* CP_INT in ring buffer */
+		case 177: /* CP_INT in IB1 */
+		case 178: /* CP_INT in IB2 */
+			DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
+			radeon_fence_process(rdev);
+			break;
+		case 181: /* CP EOP event */
+			DRM_DEBUG("IH: CP EOP\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;
+	}
+	/* make sure wptr hasn't changed while processing */
+	wptr = r600_get_ih_wptr(rdev);
+	if (wptr != rdev->ih.wptr)
+		goto restart_ih;
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
+	rdev->ih.rptr = rptr;
+	WREG32(IH_RB_RPTR, rdev->ih.rptr);
+	spin_unlock_irqrestore(&rdev->ih.lock, flags);
+	return IRQ_HANDLED;
+}
 
 /*
  * Debugfs info
@@ -1792,21 +2848,21 @@ static int r600_debugfs_cp_ring_info(str
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
-	uint32_t rdp, wdp;
 	unsigned count, i, j;
 
 	radeon_ring_free_size(rdev);
-	rdp = RREG32(CP_RB_RPTR);
-	wdp = RREG32(CP_RB_WPTR);
-	count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
+	count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw;
 	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
-	seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
-	seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
+	seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR));
+	seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR));
+	seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr);
+	seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr);
 	seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
 	seq_printf(m, "%u dwords in ring\n", count);
+	i = rdev->cp.rptr;
 	for (j = 0; j <= count; j++) {
-		i = (rdp + j) & rdev->cp.ptr_mask;
 		seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
+		i = (i + 1) & rdev->cp.ptr_mask;
 	}
 	return 0;
 }
@@ -1836,3 +2892,18 @@ int r600_debugfs_mc_info_init(struct rad
 	return 0;
 #endif
 }
+
+/**
+ * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl
+ * rdev: radeon device structure
+ * bo: buffer object struct which userspace is waiting for idle
+ *
+ * Some R6XX/R7XX doesn't seems to take into account HDP flush performed
+ * through ring buffer, this leads to corruption in rendering, see
+ * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we
+ * directly perform HDP flush by writing register through MMIO.
+ */
+void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
+{
+	WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_cp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_cp.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cp.c	2013-05-03 12:03:49.000000000 -0400
@@ -1409,9 +1409,12 @@ static void r700_gfx_init(struct drm_dev
 
 	gb_tiling_config |= R600_BANK_SWAPS(1);
 
-	backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
-							dev_priv->r600_max_backends,
-							(0xff << dev_priv->r600_max_backends) & 0xff);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)
+		backend_map = 0x28;
+	else
+		backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+								dev_priv->r600_max_backends,
+								(0xff << dev_priv->r600_max_backends) & 0xff);
 	gb_tiling_config |= R600_BACKEND_MAP(backend_map);
 
 	cc_gc_shader_pipe_config =
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_cs.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cs.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,10 @@ static int r600_cs_packet_next_reloc_nom
 typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
 static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
 
+struct r600_cs_track {
+	u32	cb_color0_base_last;
+};
+
 /**
  * r600_cs_packet_parse() - parse cp packet and point ib index to next packet
  * @parser:	parser structure holding parsing context.
@@ -170,13 +174,35 @@ static int r600_cs_packet_next_reloc_nom
 			  idx, relocs_chunk->length_dw);
 		return -EINVAL;
 	}
-	*cs_reloc = &p->relocs[0];
+	*cs_reloc = p->relocs;
 	(*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32;
 	(*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0];
 	return 0;
 }
 
 /**
+ * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
+ * @parser:		parser structure holding parsing context.
+ *
+ * Check next packet is relocation packet3, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+static inline int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
+{
+	struct radeon_cs_packet p3reloc;
+	int r;
+
+	r = r600_cs_packet_parse(p, &p3reloc, p->idx);
+	if (r) {
+		return 0;
+	}
+	if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+		return 0;
+	}
+	return 1;
+}
+
+/**
  * r600_cs_packet_next_vline() - parse userspace VLINE packet
  * @parser:		parser structure holding parsing context.
  *
@@ -337,6 +363,7 @@ static int r600_packet3_check(struct rad
 				struct radeon_cs_packet *pkt)
 {
 	struct radeon_cs_reloc *reloc;
+	struct r600_cs_track *track;
 	volatile u32 *ib;
 	unsigned idx;
 	unsigned i;
@@ -344,6 +371,7 @@ static int r600_packet3_check(struct rad
 	int r;
 	u32 idx_value;
 
+	track = (struct r600_cs_track *)p->track;
 	ib = p->ib->ptr;
 	idx = pkt->idx + 1;
 	idx_value = radeon_get_ib_value(p, idx);
@@ -503,9 +531,60 @@ static int r600_packet3_check(struct rad
 		for (i = 0; i < pkt->count; i++) {
 			reg = start_reg + (4 * i);
 			switch (reg) {
+			/* This register were added late, there is userspace
+			 * which does provide relocation for those but set
+			 * 0 offset. In order to avoid breaking old userspace
+			 * we detect this and set address to point to last
+			 * CB_COLOR0_BASE, note that if userspace doesn't set
+			 * CB_COLOR0_BASE before this register we will report
+			 * error. Old userspace always set CB_COLOR0_BASE
+			 * before any of this.
+			 */
+			case R_0280E0_CB_COLOR0_FRAG:
+			case R_0280E4_CB_COLOR1_FRAG:
+			case R_0280E8_CB_COLOR2_FRAG:
+			case R_0280EC_CB_COLOR3_FRAG:
+			case R_0280F0_CB_COLOR4_FRAG:
+			case R_0280F4_CB_COLOR5_FRAG:
+			case R_0280F8_CB_COLOR6_FRAG:
+			case R_0280FC_CB_COLOR7_FRAG:
+			case R_0280C0_CB_COLOR0_TILE:
+			case R_0280C4_CB_COLOR1_TILE:
+			case R_0280C8_CB_COLOR2_TILE:
+			case R_0280CC_CB_COLOR3_TILE:
+			case R_0280D0_CB_COLOR4_TILE:
+			case R_0280D4_CB_COLOR5_TILE:
+			case R_0280D8_CB_COLOR6_TILE:
+			case R_0280DC_CB_COLOR7_TILE:
+				if (!r600_cs_packet_next_is_pkt3_nop(p)) {
+					if (!track->cb_color0_base_last) {
+						dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
+						return -EINVAL;
+					}
+					ib[idx+1+i] = track->cb_color0_base_last;
+					printk_once(KERN_WARNING "radeon: You have old & broken userspace "
+						"please consider updating mesa & xf86-video-ati\n");
+				} else {
+					r = r600_cs_packet_next_reloc(p, &reloc);
+					if (r) {
+						dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
+						return -EINVAL;
+					}
+					ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				}
+				break;
 			case DB_DEPTH_BASE:
 			case DB_HTILE_DATA_BASE:
 			case CB_COLOR0_BASE:
+				r = r600_cs_packet_next_reloc(p, &reloc);
+				if (r) {
+					DRM_ERROR("bad SET_CONTEXT_REG "
+							"0x%04X\n", reg);
+					return -EINVAL;
+				}
+				ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				track->cb_color0_base_last = ib[idx+1+i];
+				break;
 			case CB_COLOR1_BASE:
 			case CB_COLOR2_BASE:
 			case CB_COLOR3_BASE:
@@ -678,8 +757,11 @@ static int r600_packet3_check(struct rad
 int r600_cs_parse(struct radeon_cs_parser *p)
 {
 	struct radeon_cs_packet pkt;
+	struct r600_cs_track *track;
 	int r;
 
+	track = kzalloc(sizeof(*track), GFP_KERNEL);
+	p->track = track;
 	do {
 		r = r600_cs_packet_parse(p, &pkt, p->idx);
 		if (r) {
@@ -717,7 +799,7 @@ static int r600_cs_parser_relocs_legacy(
 	if (p->chunk_relocs_idx == -1) {
 		return 0;
 	}
-	p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
+	p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL);
 	if (p->relocs == NULL) {
 		return -ENOMEM;
 	}
@@ -757,6 +839,7 @@ int r600_cs_legacy(struct drm_device *de
 	/* initialize parser */
 	memset(&parser, 0, sizeof(struct radeon_cs_parser));
 	parser.filp = filp;
+	parser.dev = &dev->pdev->dev;
 	parser.rdev = NULL;
 	parser.family = family;
 	parser.ib = &fake_ib;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600d.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600d.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600d.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600d.h	2010-02-24 13:52:17.000000000 -0500
@@ -456,7 +456,215 @@
 #define         WAIT_2D_IDLECLEAN_bit                           (1 << 16)
 #define         WAIT_3D_IDLECLEAN_bit                           (1 << 17)
 
+#define IH_RB_CNTL                                        0x3e00
+#       define IH_RB_ENABLE                               (1 << 0)
+#       define IH_IB_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) << 2)
+#       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 RLC_CNTL                                          0x3f00
+#       define RLC_ENABLE                                 (1 << 0)
+#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
+
+#define SRBM_SOFT_RESET                                   0xe60
+#       define SOFT_RESET_RLC                             (1 << 13)
+
+#define CP_INT_CNTL                                       0xc124
+#       define CNTX_BUSY_INT_ENABLE                       (1 << 19)
+#       define CNTX_EMPTY_INT_ENABLE                      (1 << 20)
+#       define SCRATCH_INT_ENABLE                         (1 << 25)
+#       define TIME_STAMP_INT_ENABLE                      (1 << 26)
+#       define IB2_INT_ENABLE                             (1 << 29)
+#       define IB1_INT_ENABLE                             (1 << 30)
+#       define RB_INT_ENABLE                              (1 << 31)
+#define CP_INT_STATUS                                     0xc128
+#       define SCRATCH_INT_STAT                           (1 << 25)
+#       define TIME_STAMP_INT_STAT                        (1 << 26)
+#       define IB2_INT_STAT                               (1 << 29)
+#       define IB1_INT_STAT                               (1 << 30)
+#       define RB_INT_STAT                                (1 << 31)
+
+#define GRBM_INT_CNTL                                     0x8060
+#       define RDERR_INT_ENABLE                           (1 << 0)
+#       define WAIT_COUNT_TIMEOUT_INT_ENABLE              (1 << 1)
+#       define GUI_IDLE_INT_ENABLE                        (1 << 19)
 
+#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 D1MODE_VBLANK_STATUS                              0x6534
+#define D2MODE_VBLANK_STATUS                              0x6d34
+#       define DxMODE_VBLANK_OCCURRED                     (1 << 0)
+#       define DxMODE_VBLANK_ACK                          (1 << 4)
+#       define DxMODE_VBLANK_STAT                         (1 << 12)
+#       define DxMODE_VBLANK_INTERRUPT                    (1 << 16)
+#       define DxMODE_VBLANK_INTERRUPT_TYPE               (1 << 17)
+#define D1MODE_VLINE_STATUS                               0x653c
+#define D2MODE_VLINE_STATUS                               0x6d3c
+#       define DxMODE_VLINE_OCCURRED                      (1 << 0)
+#       define DxMODE_VLINE_ACK                           (1 << 4)
+#       define DxMODE_VLINE_STAT                          (1 << 12)
+#       define DxMODE_VLINE_INTERRUPT                     (1 << 16)
+#       define DxMODE_VLINE_INTERRUPT_TYPE                (1 << 17)
+#define DxMODE_INT_MASK                                   0x6540
+#       define D1MODE_VBLANK_INT_MASK                     (1 << 0)
+#       define D1MODE_VLINE_INT_MASK                      (1 << 4)
+#       define D2MODE_VBLANK_INT_MASK                     (1 << 8)
+#       define D2MODE_VLINE_INT_MASK                      (1 << 12)
+#define DCE3_DISP_INTERRUPT_STATUS                        0x7ddc
+#       define DC_HPD1_INTERRUPT                          (1 << 18)
+#       define DC_HPD2_INTERRUPT                          (1 << 19)
+#define DISP_INTERRUPT_STATUS                             0x7edc
+#       define LB_D1_VLINE_INTERRUPT                      (1 << 2)
+#       define LB_D2_VLINE_INTERRUPT                      (1 << 3)
+#       define LB_D1_VBLANK_INTERRUPT                     (1 << 4)
+#       define LB_D2_VBLANK_INTERRUPT                     (1 << 5)
+#       define DACA_AUTODETECT_INTERRUPT                  (1 << 16)
+#       define DACB_AUTODETECT_INTERRUPT                  (1 << 17)
+#       define DC_HOT_PLUG_DETECT1_INTERRUPT              (1 << 18)
+#       define DC_HOT_PLUG_DETECT2_INTERRUPT              (1 << 19)
+#       define DC_I2C_SW_DONE_INTERRUPT                   (1 << 20)
+#       define DC_I2C_HW_DONE_INTERRUPT                   (1 << 21)
+#define DISP_INTERRUPT_STATUS_CONTINUE                    0x7ee8
+#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE               0x7de8
+#       define DC_HPD4_INTERRUPT                          (1 << 14)
+#       define DC_HPD4_RX_INTERRUPT                       (1 << 15)
+#       define DC_HPD3_INTERRUPT                          (1 << 28)
+#       define DC_HPD1_RX_INTERRUPT                       (1 << 29)
+#       define DC_HPD2_RX_INTERRUPT                       (1 << 30)
+#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2              0x7dec
+#       define DC_HPD3_RX_INTERRUPT                       (1 << 0)
+#       define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT       (1 << 1)
+#       define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT      (1 << 2)
+#       define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT       (1 << 3)
+#       define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT      (1 << 4)
+#       define AUX1_SW_DONE_INTERRUPT                     (1 << 5)
+#       define AUX1_LS_DONE_INTERRUPT                     (1 << 6)
+#       define AUX2_SW_DONE_INTERRUPT                     (1 << 7)
+#       define AUX2_LS_DONE_INTERRUPT                     (1 << 8)
+#       define AUX3_SW_DONE_INTERRUPT                     (1 << 9)
+#       define AUX3_LS_DONE_INTERRUPT                     (1 << 10)
+#       define AUX4_SW_DONE_INTERRUPT                     (1 << 11)
+#       define AUX4_LS_DONE_INTERRUPT                     (1 << 12)
+#       define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT   (1 << 13)
+#       define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT   (1 << 14)
+/* DCE 3.2 */
+#       define AUX5_SW_DONE_INTERRUPT                     (1 << 15)
+#       define AUX5_LS_DONE_INTERRUPT                     (1 << 16)
+#       define AUX6_SW_DONE_INTERRUPT                     (1 << 17)
+#       define AUX6_LS_DONE_INTERRUPT                     (1 << 18)
+#       define DC_HPD5_INTERRUPT                          (1 << 19)
+#       define DC_HPD5_RX_INTERRUPT                       (1 << 20)
+#       define DC_HPD6_INTERRUPT                          (1 << 21)
+#       define DC_HPD6_RX_INTERRUPT                       (1 << 22)
+
+#define DACA_AUTO_DETECT_CONTROL                          0x7828
+#define DACB_AUTO_DETECT_CONTROL                          0x7a28
+#define DCE3_DACA_AUTO_DETECT_CONTROL                     0x7028
+#define DCE3_DACB_AUTO_DETECT_CONTROL                     0x7128
+#       define DACx_AUTODETECT_MODE(x)                    ((x) << 0)
+#       define DACx_AUTODETECT_MODE_NONE                  0
+#       define DACx_AUTODETECT_MODE_CONNECT               1
+#       define DACx_AUTODETECT_MODE_DISCONNECT            2
+#       define DACx_AUTODETECT_FRAME_TIME_COUNTER(x)      ((x) << 8)
+/* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */
+#       define DACx_AUTODETECT_CHECK_MASK(x)              ((x) << 16)
+
+#define DCE3_DACA_AUTODETECT_INT_CONTROL                  0x7038
+#define DCE3_DACB_AUTODETECT_INT_CONTROL                  0x7138
+#define DACA_AUTODETECT_INT_CONTROL                       0x7838
+#define DACB_AUTODETECT_INT_CONTROL                       0x7a38
+#       define DACx_AUTODETECT_ACK                        (1 << 0)
+#       define DACx_AUTODETECT_INT_ENABLE                 (1 << 16)
+
+#define DC_HOT_PLUG_DETECT1_CONTROL                       0x7d00
+#define DC_HOT_PLUG_DETECT2_CONTROL                       0x7d10
+#define DC_HOT_PLUG_DETECT3_CONTROL                       0x7d24
+#       define DC_HOT_PLUG_DETECTx_EN                     (1 << 0)
+
+#define DC_HOT_PLUG_DETECT1_INT_STATUS                    0x7d04
+#define DC_HOT_PLUG_DETECT2_INT_STATUS                    0x7d14
+#define DC_HOT_PLUG_DETECT3_INT_STATUS                    0x7d28
+#       define DC_HOT_PLUG_DETECTx_INT_STATUS             (1 << 0)
+#       define DC_HOT_PLUG_DETECTx_SENSE                  (1 << 1)
+
+/* DCE 3.0 */
+#define DC_HPD1_INT_STATUS                                0x7d00
+#define DC_HPD2_INT_STATUS                                0x7d0c
+#define DC_HPD3_INT_STATUS                                0x7d18
+#define DC_HPD4_INT_STATUS                                0x7d24
+/* DCE 3.2 */
+#define DC_HPD5_INT_STATUS                                0x7dc0
+#define DC_HPD6_INT_STATUS                                0x7df4
+#       define DC_HPDx_INT_STATUS                         (1 << 0)
+#       define DC_HPDx_SENSE                              (1 << 1)
+#       define DC_HPDx_RX_INT_STATUS                      (1 << 8)
+
+#define DC_HOT_PLUG_DETECT1_INT_CONTROL                   0x7d08
+#define DC_HOT_PLUG_DETECT2_INT_CONTROL                   0x7d18
+#define DC_HOT_PLUG_DETECT3_INT_CONTROL                   0x7d2c
+#       define DC_HOT_PLUG_DETECTx_INT_ACK                (1 << 0)
+#       define DC_HOT_PLUG_DETECTx_INT_POLARITY           (1 << 8)
+#       define DC_HOT_PLUG_DETECTx_INT_EN                 (1 << 16)
+/* DCE 3.0 */
+#define DC_HPD1_INT_CONTROL                               0x7d04
+#define DC_HPD2_INT_CONTROL                               0x7d10
+#define DC_HPD3_INT_CONTROL                               0x7d1c
+#define DC_HPD4_INT_CONTROL                               0x7d28
+/* DCE 3.2 */
+#define DC_HPD5_INT_CONTROL                               0x7dc4
+#define DC_HPD6_INT_CONTROL                               0x7df8
+#       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)
+
+/* DCE 3.0 */
+#define DC_HPD1_CONTROL                                   0x7d08
+#define DC_HPD2_CONTROL                                   0x7d14
+#define DC_HPD3_CONTROL                                   0x7d20
+#define DC_HPD4_CONTROL                                   0x7d2c
+/* DCE 3.2 */
+#define DC_HPD5_CONTROL                                   0x7dc8
+#define DC_HPD6_CONTROL                                   0x7dfc
+#       define DC_HPDx_CONNECTION_TIMER(x)                ((x) << 0)
+#       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
+/* DCE 3.2 */
+#       define DC_HPDx_EN                                 (1 << 28)
 
 /*
  * PM4
@@ -500,7 +708,6 @@
 #define	PACKET3_WAIT_REG_MEM				0x3C
 #define	PACKET3_MEM_WRITE				0x3D
 #define	PACKET3_INDIRECT_BUFFER				0x32
-#define	PACKET3_CP_INTERRUPT				0x40
 #define	PACKET3_SURFACE_SYNC				0x43
 #              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
 #              define PACKET3_TC_ACTION_ENA        (1 << 23)
@@ -674,4 +881,30 @@
 #define		S_000E60_SOFT_RESET_TSC(x)		(((x) & 1) << 16)
 #define		S_000E60_SOFT_RESET_VMC(x)		(((x) & 1) << 17)
 
+#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL		0x5480
+
+#define R_0280E0_CB_COLOR0_FRAG                      0x0280E0
+#define   S_0280E0_BASE_256B(x)                        (((x) & 0xFFFFFFFF) << 0)
+#define   G_0280E0_BASE_256B(x)                        (((x) >> 0) & 0xFFFFFFFF)
+#define   C_0280E0_BASE_256B                           0x00000000
+#define R_0280E4_CB_COLOR1_FRAG                      0x0280E4
+#define R_0280E8_CB_COLOR2_FRAG                      0x0280E8
+#define R_0280EC_CB_COLOR3_FRAG                      0x0280EC
+#define R_0280F0_CB_COLOR4_FRAG                      0x0280F0
+#define R_0280F4_CB_COLOR5_FRAG                      0x0280F4
+#define R_0280F8_CB_COLOR6_FRAG                      0x0280F8
+#define R_0280FC_CB_COLOR7_FRAG                      0x0280FC
+#define R_0280C0_CB_COLOR0_TILE                      0x0280C0
+#define   S_0280C0_BASE_256B(x)                        (((x) & 0xFFFFFFFF) << 0)
+#define   G_0280C0_BASE_256B(x)                        (((x) >> 0) & 0xFFFFFFFF)
+#define   C_0280C0_BASE_256B                           0x00000000
+#define R_0280C4_CB_COLOR1_TILE                      0x0280C4
+#define R_0280C8_CB_COLOR2_TILE                      0x0280C8
+#define R_0280CC_CB_COLOR3_TILE                      0x0280CC
+#define R_0280D0_CB_COLOR4_TILE                      0x0280D0
+#define R_0280D4_CB_COLOR5_TILE                      0x0280D4
+#define R_0280D8_CB_COLOR6_TILE                      0x0280D8
+#define R_0280DC_CB_COLOR7_TILE                      0x0280DC
+
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_hdmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Christian König.
+ *
+ * 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: Christian König
+ */
+#include "drmP.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+#include "atom.h"
+
+/*
+ * HDMI color format
+ */
+enum r600_hdmi_color_format {
+	RGB = 0,
+	YCC_422 = 1,
+	YCC_444 = 2
+};
+
+/*
+ * IEC60958 status bits
+ */
+enum r600_hdmi_iec_status_bits {
+	AUDIO_STATUS_DIG_ENABLE   = 0x01,
+	AUDIO_STATUS_V	    = 0x02,
+	AUDIO_STATUS_VCFG	 = 0x04,
+	AUDIO_STATUS_EMPHASIS     = 0x08,
+	AUDIO_STATUS_COPYRIGHT    = 0x10,
+	AUDIO_STATUS_NONAUDIO     = 0x20,
+	AUDIO_STATUS_PROFESSIONAL = 0x40,
+	AUDIO_STATUS_LEVEL	= 0x80
+};
+
+struct {
+	uint32_t Clock;
+
+	int N_32kHz;
+	int CTS_32kHz;
+
+	int N_44_1kHz;
+	int CTS_44_1kHz;
+
+	int N_48kHz;
+	int CTS_48kHz;
+
+} r600_hdmi_ACR[] = {
+    /*	     32kHz	  44.1kHz	48kHz    */
+    /* Clock      N     CTS      N     CTS      N     CTS */
+    {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
+    {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
+    {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
+    {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
+    {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
+    {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
+    {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
+    {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
+    { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
+    { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
+    {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
+};
+
+/*
+ * calculate CTS value if it's not found in the table
+ */
+static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
+{
+	if (*CTS == 0)
+		*CTS = clock*N/(128*freq)*1000;
+	DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
+		  N, *CTS, freq);
+}
+
+/*
+ * update the N and CTS parameters for a given pixel clock rate
+ */
+static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+	int CTS;
+	int N;
+	int i;
+
+	for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);
+
+	CTS = r600_hdmi_ACR[i].CTS_32kHz;
+	N = r600_hdmi_ACR[i].N_32kHz;
+	r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
+	WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12);
+	WREG32(offset+R600_HDMI_32kHz_N, N);
+
+	CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
+	N = r600_hdmi_ACR[i].N_44_1kHz;
+	r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
+	WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12);
+	WREG32(offset+R600_HDMI_44_1kHz_N, N);
+
+	CTS = r600_hdmi_ACR[i].CTS_48kHz;
+	N = r600_hdmi_ACR[i].N_48kHz;
+	r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
+	WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12);
+	WREG32(offset+R600_HDMI_48kHz_N, N);
+}
+
+/*
+ * calculate the crc for a given info frame
+ */
+static void r600_hdmi_infoframe_checksum(uint8_t packetType,
+					 uint8_t versionNumber,
+					 uint8_t length,
+					 uint8_t *frame)
+{
+    int i;
+    frame[0] = packetType + versionNumber + length;
+    for (i = 1; i <= length; i++)
+	frame[0] += frame[i];
+    frame[0] = 0x100 - frame[0];
+}
+
+/*
+ * build a HDMI Video Info Frame
+ */
+static void r600_hdmi_videoinfoframe(
+	struct drm_encoder *encoder,
+	enum r600_hdmi_color_format color_format,
+	int active_information_present,
+	uint8_t active_format_aspect_ratio,
+	uint8_t scan_information,
+	uint8_t colorimetry,
+	uint8_t ex_colorimetry,
+	uint8_t quantization,
+	int ITC,
+	uint8_t picture_aspect_ratio,
+	uint8_t video_format_identification,
+	uint8_t pixel_repetition,
+	uint8_t non_uniform_picture_scaling,
+	uint8_t bar_info_data_valid,
+	uint16_t top_bar,
+	uint16_t bottom_bar,
+	uint16_t left_bar,
+	uint16_t right_bar
+)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	uint8_t frame[14];
+
+	frame[0x0] = 0;
+	frame[0x1] =
+		(scan_information & 0x3) |
+		((bar_info_data_valid & 0x3) << 2) |
+		((active_information_present & 0x1) << 4) |
+		((color_format & 0x3) << 5);
+	frame[0x2] =
+		(active_format_aspect_ratio & 0xF) |
+		((picture_aspect_ratio & 0x3) << 4) |
+		((colorimetry & 0x3) << 6);
+	frame[0x3] =
+		(non_uniform_picture_scaling & 0x3) |
+		((quantization & 0x3) << 2) |
+		((ex_colorimetry & 0x7) << 4) |
+		((ITC & 0x1) << 7);
+	frame[0x4] = (video_format_identification & 0x7F);
+	frame[0x5] = (pixel_repetition & 0xF);
+	frame[0x6] = (top_bar & 0xFF);
+	frame[0x7] = (top_bar >> 8);
+	frame[0x8] = (bottom_bar & 0xFF);
+	frame[0x9] = (bottom_bar >> 8);
+	frame[0xA] = (left_bar & 0xFF);
+	frame[0xB] = (left_bar >> 8);
+	frame[0xC] = (right_bar & 0xFF);
+	frame[0xD] = (right_bar >> 8);
+
+	r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
+
+	WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
+		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
+	WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1,
+		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
+	WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2,
+		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
+	WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3,
+		frame[0xC] | (frame[0xD] << 8));
+}
+
+/*
+ * build a Audio Info Frame
+ */
+static void r600_hdmi_audioinfoframe(
+	struct drm_encoder *encoder,
+	uint8_t channel_count,
+	uint8_t coding_type,
+	uint8_t sample_size,
+	uint8_t sample_frequency,
+	uint8_t format,
+	uint8_t channel_allocation,
+	uint8_t level_shift,
+	int downmix_inhibit
+)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	uint8_t frame[11];
+
+	frame[0x0] = 0;
+	frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
+	frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
+	frame[0x3] = format;
+	frame[0x4] = channel_allocation;
+	frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
+	frame[0x6] = 0;
+	frame[0x7] = 0;
+	frame[0x8] = 0;
+	frame[0x9] = 0;
+	frame[0xA] = 0;
+
+	r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
+
+	WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0,
+		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
+	WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1,
+		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
+}
+
+/*
+ * test if audio buffer is filled enough to start playing
+ */
+static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0;
+}
+
+/*
+ * have buffer status changed since last call?
+ */
+int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	int status, result;
+
+	if (!radeon_encoder->hdmi_offset)
+		return 0;
+
+	status = r600_hdmi_is_audio_buffer_filled(encoder);
+	result = radeon_encoder->hdmi_buffer_status != status;
+	radeon_encoder->hdmi_buffer_status = status;
+
+	return result;
+}
+
+/*
+ * write the audio workaround status to the hardware
+ */
+void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	uint32_t offset = radeon_encoder->hdmi_offset;
+
+	if (!offset)
+		return;
+
+	if (r600_hdmi_is_audio_buffer_filled(encoder)) {
+		/* disable audio workaround and start delivering of audio frames */
+		WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001);
+
+	} else if (radeon_encoder->hdmi_audio_workaround) {
+		/* enable audio workaround and start delivering of audio frames */
+		WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001);
+
+	} else {
+		/* disable audio workaround and stop delivering of audio frames */
+		WREG32_P(offset+R600_HDMI_CNTL, 0x00000000, ~0x00001001);
+	}
+}
+
+
+/*
+ * update the info frames with the data from the current display mode
+ */
+void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	if (!offset)
+		return;
+
+	r600_audio_set_clock(encoder, mode->clock);
+
+	WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000);
+	WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0);
+	WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000);
+
+	r600_hdmi_update_ACR(encoder, mode->clock);
+
+	WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13);
+
+	WREG32(offset+R600_HDMI_VERSION, 0x202);
+
+	r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+	/* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */
+	WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
+	WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
+	WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001);
+	WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001);
+
+	r600_hdmi_audio_workaround(encoder);
+
+	/* audio packets per line, does anyone know how to calc this ? */
+	WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000);
+
+	/* update? reset? don't realy know */
+	WREG32_P(offset+R600_HDMI_CNTL, 0x14000000, ~0x14000000);
+}
+
+/*
+ * update settings with current parameters from audio engine
+ */
+void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
+				     int channels,
+				     int rate,
+				     int bps,
+				     uint8_t status_bits,
+				     uint8_t category_code)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	uint32_t iec;
+
+	if (!offset)
+		return;
+
+	DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
+		 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
+		channels, rate, bps);
+	DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
+		  (int)status_bits, (int)category_code);
+
+	iec = 0;
+	if (status_bits & AUDIO_STATUS_PROFESSIONAL)
+		iec |= 1 << 0;
+	if (status_bits & AUDIO_STATUS_NONAUDIO)
+		iec |= 1 << 1;
+	if (status_bits & AUDIO_STATUS_COPYRIGHT)
+		iec |= 1 << 2;
+	if (status_bits & AUDIO_STATUS_EMPHASIS)
+		iec |= 1 << 3;
+
+	iec |= category_code << 8;
+
+	switch (rate) {
+	case  32000: iec |= 0x3 << 24; break;
+	case  44100: iec |= 0x0 << 24; break;
+	case  88200: iec |= 0x8 << 24; break;
+	case 176400: iec |= 0xc << 24; break;
+	case  48000: iec |= 0x2 << 24; break;
+	case  96000: iec |= 0xa << 24; break;
+	case 192000: iec |= 0xe << 24; break;
+	}
+
+	WREG32(offset+R600_HDMI_IEC60958_1, iec);
+
+	iec = 0;
+	switch (bps) {
+	case 16: iec |= 0x2; break;
+	case 20: iec |= 0x3; break;
+	case 24: iec |= 0xb; break;
+	}
+	if (status_bits & AUDIO_STATUS_V)
+		iec |= 0x5 << 16;
+
+	WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f);
+
+	/* 0x021 or 0x031 sets the audio frame length */
+	WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31);
+	r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0);
+
+	r600_hdmi_audio_workaround(encoder);
+
+	/* update? reset? don't realy know */
+	WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
+}
+
+/*
+ * enable/disable the HDMI engine
+ */
+void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+
+	if (!offset)
+		return;
+
+	DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
+
+	/* some version of atombios ignore the enable HDMI flag
+	 * so enabling/disabling HDMI was moved here for TMDS1+2 */
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+		WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
+		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
+		break;
+
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
+		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
+		break;
+
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		/* This part is doubtfull in my opinion */
+		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
+		break;
+
+	default:
+		DRM_ERROR("unknown HDMI output type\n");
+		break;
+	}
+}
+
+/*
+ * determin at which register offset the HDMI encoder is
+ */
+void r600_hdmi_init(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+		radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
+		break;
+
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		switch (r600_audio_tmds_index(encoder)) {
+		case 0:
+			radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
+			break;
+		case 1:
+			radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
+			break;
+		default:
+			radeon_encoder->hdmi_offset = 0;
+			break;
+		}
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
+		break;
+
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		radeon_encoder->hdmi_offset = R600_HDMI_DIG;
+		break;
+
+	default:
+		radeon_encoder->hdmi_offset = 0;
+		break;
+	}
+
+	DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
+		  radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+
+	/* TODO: make this configureable */
+	radeon_encoder->hdmi_audio_workaround = 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/r600_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/r600_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -110,5 +110,79 @@
 #define R600_BIOS_6_SCRATCH               0x173c
 #define R600_BIOS_7_SCRATCH               0x1740
 
+/* Audio, these regs were reverse enginered,
+ * so the chance is high that the naming is wrong
+ * R6xx+ ??? */
+
+/* Audio clocks */
+#define R600_AUDIO_PLL1_MUL               0x0514
+#define R600_AUDIO_PLL1_DIV               0x0518
+#define R600_AUDIO_PLL2_MUL               0x0524
+#define R600_AUDIO_PLL2_DIV               0x0528
+#define R600_AUDIO_CLK_SRCSEL             0x0534
+
+/* Audio general */
+#define R600_AUDIO_ENABLE                 0x7300
+#define R600_AUDIO_TIMING                 0x7344
+
+/* Audio params */
+#define R600_AUDIO_VENDOR_ID              0x7380
+#define R600_AUDIO_REVISION_ID            0x7384
+#define R600_AUDIO_ROOT_NODE_COUNT        0x7388
+#define R600_AUDIO_NID1_NODE_COUNT        0x738c
+#define R600_AUDIO_NID1_TYPE              0x7390
+#define R600_AUDIO_SUPPORTED_SIZE_RATE    0x7394
+#define R600_AUDIO_SUPPORTED_CODEC        0x7398
+#define R600_AUDIO_SUPPORTED_POWER_STATES 0x739c
+#define R600_AUDIO_NID2_CAPS              0x73a0
+#define R600_AUDIO_NID3_CAPS              0x73a4
+#define R600_AUDIO_NID3_PIN_CAPS          0x73a8
+
+/* Audio conn list */
+#define R600_AUDIO_CONN_LIST_LEN          0x73ac
+#define R600_AUDIO_CONN_LIST              0x73b0
+
+/* Audio verbs */
+#define R600_AUDIO_RATE_BPS_CHANNEL       0x73c0
+#define R600_AUDIO_PLAYING                0x73c4
+#define R600_AUDIO_IMPLEMENTATION_ID      0x73c8
+#define R600_AUDIO_CONFIG_DEFAULT         0x73cc
+#define R600_AUDIO_PIN_SENSE              0x73d0
+#define R600_AUDIO_PIN_WIDGET_CNTL        0x73d4
+#define R600_AUDIO_STATUS_BITS            0x73d8
+
+/* HDMI base register addresses */
+#define R600_HDMI_TMDS1                   0x7400
+#define R600_HDMI_TMDS2                   0x7700
+#define R600_HDMI_DIG                     0x7800
+
+/* HDMI registers */
+#define R600_HDMI_ENABLE           0x00
+#define R600_HDMI_STATUS           0x04
+#define R600_HDMI_CNTL             0x08
+#define R600_HDMI_UNKNOWN_0        0x0C
+#define R600_HDMI_AUDIOCNTL        0x10
+#define R600_HDMI_VIDEOCNTL        0x14
+#define R600_HDMI_VERSION          0x18
+#define R600_HDMI_UNKNOWN_1        0x28
+#define R600_HDMI_VIDEOINFOFRAME_0 0x54
+#define R600_HDMI_VIDEOINFOFRAME_1 0x58
+#define R600_HDMI_VIDEOINFOFRAME_2 0x5c
+#define R600_HDMI_VIDEOINFOFRAME_3 0x60
+#define R600_HDMI_32kHz_CTS        0xac
+#define R600_HDMI_32kHz_N          0xb0
+#define R600_HDMI_44_1kHz_CTS      0xb4
+#define R600_HDMI_44_1kHz_N        0xb8
+#define R600_HDMI_48kHz_CTS        0xbc
+#define R600_HDMI_48kHz_N          0xc0
+#define R600_HDMI_AUDIOINFOFRAME_0 0xcc
+#define R600_HDMI_AUDIOINFOFRAME_1 0xd0
+#define R600_HDMI_IEC60958_1       0xd4
+#define R600_HDMI_IEC60958_2       0xd8
+#define R600_HDMI_UNKNOWN_2        0xdc
+#define R600_HDMI_AUDIO_DEBUG_0    0xe0
+#define R600_HDMI_AUDIO_DEBUG_1    0xe4
+#define R600_HDMI_AUDIO_DEBUG_2    0xe8
+#define R600_HDMI_AUDIO_DEBUG_3    0xec
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_agp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_agp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_agp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_agp.c	2010-02-24 13:52:17.000000000 -0500
@@ -144,9 +144,19 @@ int radeon_agp_init(struct radeon_device
 
 	ret = drm_agp_info(rdev->ddev, &info);
 	if (ret) {
+		drm_agp_release(rdev->ddev);
 		DRM_ERROR("Unable to get AGP info: %d\n", ret);
 		return ret;
 	}
+
+	if (rdev->ddev->agp->agp_info.aper_size < 32) {
+		drm_agp_release(rdev->ddev);
+		dev_warn(rdev->dev, "AGP aperture too small (%zuM) "
+			"need at least 32M, disabling AGP\n",
+			rdev->ddev->agp->agp_info.aper_size);
+		return -EINVAL;
+	}
+
 	mode.mode = info.mode;
 	agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode;
 	is_v3 = !!(agp_status & RADEON_AGPv3_MODE);
@@ -221,6 +231,7 @@ int radeon_agp_init(struct radeon_device
 	ret = drm_agp_enable(rdev->ddev, mode);
 	if (ret) {
 		DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
+		drm_agp_release(rdev->ddev);
 		return ret;
 	}
 
@@ -252,10 +263,8 @@ void radeon_agp_resume(struct radeon_dev
 void radeon_agp_fini(struct radeon_device *rdev)
 {
 #if __OS_HAS_AGP
-	if (rdev->flags & RADEON_IS_AGP) {
-		if (rdev->ddev->agp && rdev->ddev->agp->acquired) {
-			drm_agp_release(rdev->ddev);
-		}
+	if (rdev->ddev->agp && rdev->ddev->agp->acquired) {
+		drm_agp_release(rdev->ddev);
 	}
 #endif
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_asic.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_asic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_asic.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
  */
 uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev);
 void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
+uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev);
 void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
 
 uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev);
@@ -76,6 +77,11 @@ int r100_clear_surface_reg(struct radeon
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r100_ring_test(struct radeon_device *rdev);
+void r100_hpd_init(struct radeon_device *rdev);
+void r100_hpd_fini(struct radeon_device *rdev);
+bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void r100_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd);
 
 static struct radeon_asic r100_asic = {
 	.init = &r100_init,
@@ -100,13 +106,18 @@ static struct radeon_asic r100_asic = {
 	.copy = &r100_copy_blit,
 	.get_engine_clock = &radeon_legacy_get_engine_clock,
 	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = NULL,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
 	.set_memory_clock = NULL,
 	.set_pcie_lanes = NULL,
 	.set_clock_gating = &radeon_legacy_set_clock_gating,
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -155,13 +166,18 @@ static struct radeon_asic r300_asic = {
 	.copy = &r100_copy_blit,
 	.get_engine_clock = &radeon_legacy_get_engine_clock,
 	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = NULL,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
 	.set_memory_clock = NULL,
 	.set_pcie_lanes = &rv370_set_pcie_lanes,
 	.set_clock_gating = &radeon_legacy_set_clock_gating,
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 /*
@@ -201,6 +217,11 @@ static struct radeon_asic r420_asic = {
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -238,13 +259,18 @@ static struct radeon_asic rs400_asic = {
 	.copy = &r100_copy_blit,
 	.get_engine_clock = &radeon_legacy_get_engine_clock,
 	.set_engine_clock = &radeon_legacy_set_engine_clock,
-	.get_memory_clock = NULL,
+	.get_memory_clock = &radeon_legacy_get_memory_clock,
 	.set_memory_clock = NULL,
 	.set_pcie_lanes = NULL,
 	.set_clock_gating = &radeon_legacy_set_clock_gating,
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &r100_bandwidth_update,
+	.hpd_init = &r100_hpd_init,
+	.hpd_fini = &r100_hpd_fini,
+	.hpd_sense = &r100_hpd_sense,
+	.hpd_set_polarity = &r100_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -263,6 +289,12 @@ int rs600_gart_set_page(struct radeon_de
 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs600_bandwidth_update(struct radeon_device *rdev);
+void rs600_hpd_init(struct radeon_device *rdev);
+void rs600_hpd_fini(struct radeon_device *rdev);
+bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void rs600_hpd_set_polarity(struct radeon_device *rdev,
+			    enum radeon_hpd_id hpd);
+
 static struct radeon_asic rs600_asic = {
 	.init = &rs600_init,
 	.fini = &rs600_fini,
@@ -291,6 +323,11 @@ static struct radeon_asic rs600_asic = {
 	.set_pcie_lanes = NULL,
 	.set_clock_gating = &radeon_atom_set_clock_gating,
 	.bandwidth_update = &rs600_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -334,6 +371,11 @@ static struct radeon_asic rs690_asic = {
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rs690_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -381,6 +423,11 @@ static struct radeon_asic rv515_asic = {
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 
@@ -419,6 +466,11 @@ static struct radeon_asic r520_asic = {
 	.set_surface_reg = r100_set_surface_reg,
 	.clear_surface_reg = r100_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &rs600_hpd_init,
+	.hpd_fini = &rs600_hpd_fini,
+	.hpd_sense = &rs600_hpd_sense,
+	.hpd_set_polarity = &rs600_hpd_set_polarity,
+	.ioctl_wait_idle = NULL,
 };
 
 /*
@@ -455,6 +507,12 @@ int r600_ring_test(struct radeon_device
 int r600_copy_blit(struct radeon_device *rdev,
 		   uint64_t src_offset, uint64_t dst_offset,
 		   unsigned num_pages, struct radeon_fence *fence);
+void r600_hpd_init(struct radeon_device *rdev);
+void r600_hpd_fini(struct radeon_device *rdev);
+bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+void r600_hpd_set_polarity(struct radeon_device *rdev,
+			   enum radeon_hpd_id hpd);
+extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
 
 static struct radeon_asic r600_asic = {
 	.init = &r600_init,
@@ -470,6 +528,7 @@ static struct radeon_asic r600_asic = {
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,
 	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
 	.fence_ring_emit = &r600_fence_ring_emit,
 	.cs_parse = &r600_cs_parse,
 	.copy_blit = &r600_copy_blit,
@@ -484,6 +543,11 @@ static struct radeon_asic r600_asic = {
 	.set_surface_reg = r600_set_surface_reg,
 	.clear_surface_reg = r600_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 };
 
 /*
@@ -509,6 +573,7 @@ static struct radeon_asic rv770_asic = {
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,
 	.irq_process = &r600_irq_process,
+	.get_vblank_counter = &rs600_get_vblank_counter,
 	.fence_ring_emit = &r600_fence_ring_emit,
 	.cs_parse = &r600_cs_parse,
 	.copy_blit = &r600_copy_blit,
@@ -523,6 +588,11 @@ static struct radeon_asic rv770_asic = {
 	.set_surface_reg = r600_set_surface_reg,
 	.clear_surface_reg = r600_clear_surface_reg,
 	.bandwidth_update = &rv515_bandwidth_update,
+	.hpd_init = &r600_hpd_init,
+	.hpd_fini = &r600_hpd_fini,
+	.hpd_sense = &r600_hpd_sense,
+	.hpd_set_polarity = &r600_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 };
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_atombios.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_dev
 			  int connector_type,
 			  struct radeon_i2c_bus_rec *i2c_bus,
 			  bool linkb, uint32_t igp_lane_info,
-			  uint16_t connector_object_id);
+			  uint16_t connector_object_id,
+			  struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -60,16 +61,16 @@ union atom_supported_devices {
 	struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
 };
 
-static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device
-							   *dev, uint8_t id)
+static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
+							       uint8_t id)
 {
-	struct radeon_device *rdev = dev->dev_private;
 	struct atom_context *ctx = rdev->mode_info.atom_context;
-	ATOM_GPIO_I2C_ASSIGMENT gpio;
+	ATOM_GPIO_I2C_ASSIGMENT *gpio;
 	struct radeon_i2c_bus_rec i2c;
 	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
 	struct _ATOM_GPIO_I2C_INFO *i2c_info;
 	uint16_t data_offset;
+	int i;
 
 	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
 	i2c.valid = false;
@@ -78,34 +79,122 @@ static inline struct radeon_i2c_bus_rec
 
 	i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
-	gpio = i2c_info->asGPIO_Info[id];
 
-	i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
-	i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
-	i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
-	i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
-	i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
-	i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
-	i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
-	i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
-	i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
-	i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
-	i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
-	i2c.put_data_mask = (1 << gpio.ucDataEnShift);
-	i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
-	i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
-	i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
-	i2c.a_data_mask = (1 << gpio.ucDataA_Shift);
-	i2c.valid = true;
+	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+		gpio = &i2c_info->asGPIO_Info[i];
+
+		if (gpio->sucI2cId.ucAccess == id) {
+			i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+			i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+			i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+			i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+			i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+			i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+			i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+			i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+			i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+			i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+			i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+			i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+			i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+			i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+			i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+			i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+			if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+				i2c.hw_capable = true;
+			else
+				i2c.hw_capable = false;
+
+			if (gpio->sucI2cId.ucAccess == 0xa0)
+				i2c.mm_i2c = true;
+			else
+				i2c.mm_i2c = false;
+
+			i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+			i2c.valid = true;
+			break;
+		}
+	}
 
 	return i2c;
 }
 
+static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
+							u8 id)
+{
+	struct atom_context *ctx = rdev->mode_info.atom_context;
+	struct radeon_gpio_rec gpio;
+	int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT);
+	struct _ATOM_GPIO_PIN_LUT *gpio_info;
+	ATOM_GPIO_PIN_ASSIGNMENT *pin;
+	u16 data_offset, size;
+	int i, num_indices;
+
+	memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
+	gpio.valid = false;
+
+	atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
+
+	gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+
+	num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
+
+	for (i = 0; i < num_indices; i++) {
+		pin = &gpio_info->asGPIO_Pin[i];
+		if (id == pin->ucGPIO_ID) {
+			gpio.id = pin->ucGPIO_ID;
+			gpio.reg = pin->usGpioPin_AIndex * 4;
+			gpio.mask = (1 << pin->ucGpioPinBitShift);
+			gpio.valid = true;
+			break;
+		}
+	}
+
+	return gpio;
+}
+
+static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev,
+							    struct radeon_gpio_rec *gpio)
+{
+	struct radeon_hpd hpd;
+	hpd.gpio = *gpio;
+	if (gpio->reg == AVIVO_DC_GPIO_HPD_A) {
+		switch(gpio->mask) {
+		case (1 << 0):
+			hpd.hpd = RADEON_HPD_1;
+			break;
+		case (1 << 8):
+			hpd.hpd = RADEON_HPD_2;
+			break;
+		case (1 << 16):
+			hpd.hpd = RADEON_HPD_3;
+			break;
+		case (1 << 24):
+			hpd.hpd = RADEON_HPD_4;
+			break;
+		case (1 << 26):
+			hpd.hpd = RADEON_HPD_5;
+			break;
+		case (1 << 28):
+			hpd.hpd = RADEON_HPD_6;
+			break;
+		default:
+			hpd.hpd = RADEON_HPD_NONE;
+			break;
+		}
+	} else
+		hpd.hpd = RADEON_HPD_NONE;
+	return hpd;
+}
+
 static bool radeon_atom_apply_quirks(struct drm_device *dev,
 				     uint32_t supported_device,
 				     int *connector_type,
 				     struct radeon_i2c_bus_rec *i2c_bus,
-				     uint16_t *line_mux)
+				     uint16_t *line_mux,
+				     struct radeon_hpd *hpd)
 {
 
 	/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
@@ -117,6 +206,15 @@ static bool radeon_atom_apply_quirks(str
 			*connector_type = DRM_MODE_CONNECTOR_DVID;
 	}
 
+	/* Asrock RS600 board lists the DVI port as HDMI */
+	if ((dev->pdev->device == 0x7941) &&
+	    (dev->pdev->subsystem_vendor == 0x1849) &&
+	    (dev->pdev->subsystem_device == 0x7941)) {
+		if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
+		    (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
+			*connector_type = DRM_MODE_CONNECTOR_DVID;
+	}
+
 	/* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
 	if ((dev->pdev->device == 0x7941) &&
 	    (dev->pdev->subsystem_vendor == 0x147b) &&
@@ -135,6 +233,23 @@ static bool radeon_atom_apply_quirks(str
 		}
 	}
 
+	/* HIS X1300 is DVI+VGA, not DVI+DVI */
+	if ((dev->pdev->device == 0x7146) &&
+	    (dev->pdev->subsystem_vendor == 0x17af) &&
+	    (dev->pdev->subsystem_device == 0x2058)) {
+		if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+			return false;
+	}
+
+	/* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
+	if ((dev->pdev->device == 0x7142) &&
+	    (dev->pdev->subsystem_vendor == 0x1458) &&
+	    (dev->pdev->subsystem_device == 0x2134)) {
+		if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+			return false;
+	}
+
+
 	/* Funky macbooks */
 	if ((dev->pdev->device == 0x71C5) &&
 	    (dev->pdev->subsystem_vendor == 0x106b) &&
@@ -172,6 +287,24 @@ static bool radeon_atom_apply_quirks(str
 		}
 	}
 
+	/* Acer laptop reports DVI-D as DVI-I */
+	if ((dev->pdev->device == 0x95c4) &&
+	    (dev->pdev->subsystem_vendor == 0x1025) &&
+	    (dev->pdev->subsystem_device == 0x013c)) {
+		if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
+		    (supported_device == ATOM_DEVICE_DFP1_SUPPORT))
+			*connector_type = DRM_MODE_CONNECTOR_DVID;
+	}
+
+	/* XFX Pine Group device rv730 reports no VGA DDC lines
+	 * even though they are wired up to record 0x93
+	 */
+	if ((dev->pdev->device == 0x9498) &&
+	    (dev->pdev->subsystem_vendor == 0x1682) &&
+	    (dev->pdev->subsystem_device == 0x2452)) {
+		struct radeon_device *rdev = dev->dev_private;
+		*i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93);
+	}
 	return true;
 }
 
@@ -231,7 +364,9 @@ const int object_connector_convert[] = {
 	DRM_MODE_CONNECTOR_Unknown,
 	DRM_MODE_CONNECTOR_Unknown,
 	DRM_MODE_CONNECTOR_Unknown,
-	DRM_MODE_CONNECTOR_DisplayPort
+	DRM_MODE_CONNECTOR_DisplayPort,
+	DRM_MODE_CONNECTOR_eDP,
+	DRM_MODE_CONNECTOR_Unknown
 };
 
 bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
@@ -240,16 +375,18 @@ bool radeon_get_atom_connector_info_from
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	struct atom_context *ctx = mode_info->atom_context;
 	int index = GetIndexIntoMasterTable(DATA, Object_Header);
-	uint16_t size, data_offset;
-	uint8_t frev, crev, line_mux = 0;
+	u16 size, data_offset;
+	u8 frev, crev;
 	ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
 	ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
 	ATOM_OBJECT_HEADER *obj_header;
 	int i, j, path_size, device_support;
 	int connector_type;
-	uint16_t igp_lane_info, conn_id, connector_object_id;
+	u16 igp_lane_info, conn_id, connector_object_id;
 	bool linkb;
 	struct radeon_i2c_bus_rec ddc_bus;
+	struct radeon_gpio_rec gpio;
+	struct radeon_hpd hpd;
 
 	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
 
@@ -276,7 +413,6 @@ bool radeon_get_atom_connector_info_from
 		path = (ATOM_DISPLAY_OBJECT_PATH *) addr;
 		path_size += le16_to_cpu(path->usSize);
 		linkb = false;
-
 		if (device_support & le16_to_cpu(path->usDeviceTag)) {
 			uint8_t con_obj_id, con_obj_num, con_obj_type;
 
@@ -377,10 +513,9 @@ bool radeon_get_atom_connector_info_from
 				}
 			}
 
-			/* look up gpio for ddc */
+			/* look up gpio for ddc, hpd */
 			if ((le16_to_cpu(path->usDeviceTag) &
-			     (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-			    == 0) {
+			     (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
 				for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
 					if (le16_to_cpu(path->usConnObjectId) ==
 					    le16_to_cpu(con_obj->asObjects[j].
@@ -394,21 +529,34 @@ bool radeon_get_atom_connector_info_from
 								 asObjects[j].
 								 usRecordOffset));
 						ATOM_I2C_RECORD *i2c_record;
+						ATOM_HPD_INT_RECORD *hpd_record;
+						ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
+						hpd.hpd = RADEON_HPD_NONE;
 
 						while (record->ucRecordType > 0
 						       && record->
 						       ucRecordType <=
 						       ATOM_MAX_OBJECT_RECORD_NUMBER) {
-							switch (record->
-								ucRecordType) {
+							switch (record->ucRecordType) {
 							case ATOM_I2C_RECORD_TYPE:
 								i2c_record =
-								    (ATOM_I2C_RECORD
-								     *) record;
-								line_mux =
-								    i2c_record->
-								    sucI2cId.
-								    bfI2C_LineMux;
+								    (ATOM_I2C_RECORD *)
+									record;
+								i2c_config =
+									(ATOM_I2C_ID_CONFIG_ACCESS *)
+									&i2c_record->sucI2cId;
+								ddc_bus = radeon_lookup_i2c_gpio(rdev,
+												 i2c_config->
+												 ucAccess);
+								break;
+							case ATOM_HPD_INT_RECORD_TYPE:
+								hpd_record =
+									(ATOM_HPD_INT_RECORD *)
+									record;
+								gpio = radeon_lookup_gpio(rdev,
+											  hpd_record->ucHPDIntGPIOID);
+								hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
+								hpd.plugged_state = hpd_record->ucPlugged_PinState;
 								break;
 							}
 							record =
@@ -421,24 +569,16 @@ bool radeon_get_atom_connector_info_from
 						break;
 					}
 				}
-			} else
-				line_mux = 0;
-
-			if ((le16_to_cpu(path->usDeviceTag) ==
-			     ATOM_DEVICE_TV1_SUPPORT)
-			    || (le16_to_cpu(path->usDeviceTag) ==
-				ATOM_DEVICE_TV2_SUPPORT)
-			    || (le16_to_cpu(path->usDeviceTag) ==
-				ATOM_DEVICE_CV_SUPPORT))
+			} else {
+				hpd.hpd = RADEON_HPD_NONE;
 				ddc_bus.valid = false;
-			else
-				ddc_bus = radeon_lookup_gpio(dev, line_mux);
+			}
 
 			conn_id = le16_to_cpu(path->usConnObjectId);
 
 			if (!radeon_atom_apply_quirks
 			    (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
-			     &ddc_bus, &conn_id))
+			     &ddc_bus, &conn_id, &hpd))
 				continue;
 
 			radeon_add_atom_connector(dev,
@@ -447,7 +587,8 @@ bool radeon_get_atom_connector_info_from
 							      usDeviceTag),
 						  connector_type, &ddc_bus,
 						  linkb, igp_lane_info,
-						  connector_object_id);
+						  connector_object_id,
+						  &hpd);
 
 		}
 	}
@@ -502,6 +643,7 @@ struct bios_connector {
 	uint16_t devices;
 	int connector_type;
 	struct radeon_i2c_bus_rec ddc_bus;
+	struct radeon_hpd hpd;
 };
 
 bool radeon_get_atom_connector_info_from_supported_devices_table(struct
@@ -517,7 +659,7 @@ bool radeon_get_atom_connector_info_from
 	uint16_t device_support;
 	uint8_t dac;
 	union atom_supported_devices *supported_devices;
-	int i, j;
+	int i, j, max_device;
 	struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
 	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
@@ -527,7 +669,12 @@ bool radeon_get_atom_connector_info_from
 
 	device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
 
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	if (frev > 1)
+		max_device = ATOM_MAX_SUPPORTED_DEVICE;
+	else
+		max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
+
+	for (i = 0; i < max_device; i++) {
 		ATOM_CONNECTOR_INFO_I2C ci =
 		    supported_devices->info.asConnInfo[i];
 
@@ -553,22 +700,8 @@ bool radeon_get_atom_connector_info_from
 
 		dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
 
-		if ((rdev->family == CHIP_RS690) ||
-		    (rdev->family == CHIP_RS740)) {
-			if ((i == ATOM_DEVICE_DFP2_INDEX)
-			    && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2))
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
-			else if ((i == ATOM_DEVICE_DFP3_INDEX)
-				 && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1))
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1;
-			else
-				bios_connectors[i].line_mux =
-				    ci.sucI2cId.sbfAccess.bfI2C_LineMux;
-		} else
-			bios_connectors[i].line_mux =
-			    ci.sucI2cId.sbfAccess.bfI2C_LineMux;
+		bios_connectors[i].line_mux =
+			ci.sucI2cId.ucAccess;
 
 		/* give tv unique connector ids */
 		if (i == ATOM_DEVICE_TV1_INDEX) {
@@ -582,8 +715,30 @@ bool radeon_get_atom_connector_info_from
 			bios_connectors[i].line_mux = 52;
 		} else
 			bios_connectors[i].ddc_bus =
-			    radeon_lookup_gpio(dev,
-					       bios_connectors[i].line_mux);
+			    radeon_lookup_i2c_gpio(rdev,
+						   bios_connectors[i].line_mux);
+
+		if ((crev > 1) && (frev > 1)) {
+			u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap;
+			switch (isb) {
+			case 0x4:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+				break;
+			case 0xa:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+				break;
+			default:
+				bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+				break;
+			}
+		} else {
+			if (i == ATOM_DEVICE_DFP1_INDEX)
+				bios_connectors[i].hpd.hpd = RADEON_HPD_1;
+			else if (i == ATOM_DEVICE_DFP2_INDEX)
+				bios_connectors[i].hpd.hpd = RADEON_HPD_2;
+			else
+				bios_connectors[i].hpd.hpd = RADEON_HPD_NONE;
+		}
 
 		/* Always set the connector type to VGA for CRT1/CRT2. if they are
 		 * shared with a DVI port, we'll pick up the DVI connector when we
@@ -595,7 +750,8 @@ bool radeon_get_atom_connector_info_from
 
 		if (!radeon_atom_apply_quirks
 		    (dev, (1 << i), &bios_connectors[i].connector_type,
-		     &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux))
+		     &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux,
+		     &bios_connectors[i].hpd))
 			continue;
 
 		bios_connectors[i].valid = true;
@@ -610,41 +766,42 @@ bool radeon_get_atom_connector_info_from
 		else
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
-									(1 <<
-									 i),
+									(1 << i),
 									dac),
 						  (1 << i));
 	}
 
 	/* combine shared connectors */
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	for (i = 0; i < max_device; i++) {
 		if (bios_connectors[i].valid) {
-			for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+			for (j = 0; j < max_device; j++) {
 				if (bios_connectors[j].valid && (i != j)) {
 					if (bios_connectors[i].line_mux ==
 					    bios_connectors[j].line_mux) {
-						if (((bios_connectors[i].
-						      devices &
-						      (ATOM_DEVICE_DFP_SUPPORT))
-						     && (bios_connectors[j].
-							 devices &
-							 (ATOM_DEVICE_CRT_SUPPORT)))
-						    ||
-						    ((bios_connectors[j].
-						      devices &
-						      (ATOM_DEVICE_DFP_SUPPORT))
-						     && (bios_connectors[i].
-							 devices &
-							 (ATOM_DEVICE_CRT_SUPPORT)))) {
-							bios_connectors[i].
-							    devices |=
-							    bios_connectors[j].
-							    devices;
-							bios_connectors[i].
-							    connector_type =
-							    DRM_MODE_CONNECTOR_DVII;
-							bios_connectors[j].
-							    valid = false;
+						/* make sure not to combine LVDS */
+						if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+							bios_connectors[i].line_mux = 53;
+							bios_connectors[i].ddc_bus.valid = false;
+							continue;
+						}
+						if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+							bios_connectors[j].line_mux = 53;
+							bios_connectors[j].ddc_bus.valid = false;
+							continue;
+						}
+						/* combine analog and digital for DVI-I */
+						if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
+						     (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) ||
+						    ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
+						     (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) {
+							bios_connectors[i].devices |=
+								bios_connectors[j].devices;
+							bios_connectors[i].connector_type =
+								DRM_MODE_CONNECTOR_DVII;
+							if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT))
+								bios_connectors[i].hpd =
+									bios_connectors[j].hpd;
+							bios_connectors[j].valid = false;
 						}
 					}
 				}
@@ -653,7 +810,7 @@ bool radeon_get_atom_connector_info_from
 	}
 
 	/* add the connectors */
-	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	for (i = 0; i < max_device; i++) {
 		if (bios_connectors[i].valid) {
 			uint16_t connector_object_id =
 				atombios_get_connector_object_id(dev,
@@ -666,7 +823,8 @@ bool radeon_get_atom_connector_info_from
 						  connector_type,
 						  &bios_connectors[i].ddc_bus,
 						  false, 0,
-						  connector_object_id);
+						  connector_object_id,
+						  &bios_connectors[i].hpd);
 		}
 	}
 
@@ -731,7 +889,8 @@ bool radeon_atom_get_clock_info(struct d
 			 * pre-DCE 3.0 r6xx hardware.  This might need to be adjusted per
 			 * family.
 			 */
-			p1pll->pll_out_min = 64800;
+			if (!radeon_new_pll)
+				p1pll->pll_out_min = 64800;
 		}
 
 		p1pll->pll_in_min =
@@ -797,6 +956,43 @@ bool radeon_atom_get_clock_info(struct d
 	return false;
 }
 
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+};
+
+bool radeon_atombios_sideport_present(struct radeon_device *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;
+
+	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 (igp_info) {
+		switch (crev) {
+		case 1:
+			if (igp_info->info.ucMemoryType & 0xf0)
+				return true;
+			break;
+		case 2:
+			if (igp_info->info_2.ucMemoryType & 0x0f)
+				return true;
+			break;
+		default:
+			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
+			break;
+		}
+	}
+	return false;
+}
+
 bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
 				   struct radeon_encoder_int_tmds *tmds)
 {
@@ -861,6 +1057,7 @@ static struct radeon_atom_ss *radeon_ato
 	struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info;
 	uint8_t frev, crev;
 	struct radeon_atom_ss *ss = NULL;
+	int i;
 
 	if (id > ATOM_MAX_SS_ENTRY)
 		return NULL;
@@ -878,12 +1075,18 @@ static struct radeon_atom_ss *radeon_ato
 		if (!ss)
 			return NULL;
 
-		ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage);
-		ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType;
-		ss->step = ss_info->asSS_Info[id].ucSS_Step;
-		ss->delay = ss_info->asSS_Info[id].ucSS_Delay;
-		ss->range = ss_info->asSS_Info[id].ucSS_Range;
-		ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div;
+		for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) {
+			if (ss_info->asSS_Info[i].ucSS_Id == id) {
+				ss->percentage =
+					le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage);
+				ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType;
+				ss->step = ss_info->asSS_Info[i].ucSS_Step;
+				ss->delay = ss_info->asSS_Info[i].ucSS_Delay;
+				ss->range = ss_info->asSS_Info[i].ucSS_Range;
+				ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div;
+				break;
+			}
+		}
 	}
 	return ss;
 }
@@ -901,7 +1104,7 @@ struct radeon_encoder_atom_dig *radeon_a
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
-	uint16_t data_offset;
+	uint16_t data_offset, misc;
 	union lvds_info *lvds_info;
 	uint8_t frev, crev;
 	struct radeon_encoder_atom_dig *lvds = NULL;
@@ -940,6 +1143,19 @@ struct radeon_encoder_atom_dig *radeon_a
 		lvds->panel_pwr_delay =
 		    le16_to_cpu(lvds_info->info.usOffDelayInMs);
 		lvds->lvds_misc = lvds_info->info.ucLVDS_Misc;
+
+		misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);
+		if (misc & ATOM_VSYNC_POLARITY)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;
+		if (misc & ATOM_HSYNC_POLARITY)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;
+		if (misc & ATOM_COMPOSITESYNC)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;
+		if (misc & ATOM_INTERLACE)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+		if (misc & ATOM_DOUBLE_CLOCK_MODE)
+			lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;
+
 		/* set crtc values */
 		drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
 
@@ -1074,6 +1290,61 @@ bool radeon_atom_get_tv_timings(struct r
 	return true;
 }
 
+enum radeon_tv_std
+radeon_atombios_get_tv_info(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
+	uint16_t data_offset;
+	uint8_t frev, crev;
+	struct _ATOM_ANALOG_TV_INFO *tv_info;
+	enum radeon_tv_std tv_std = TV_STD_NTSC;
+
+	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+
+	tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
+
+	switch (tv_info->ucTV_BootUpDefaultStandard) {
+	case ATOM_TV_NTSC:
+		tv_std = TV_STD_NTSC;
+		DRM_INFO("Default TV standard: NTSC\n");
+		break;
+	case ATOM_TV_NTSCJ:
+		tv_std = TV_STD_NTSC_J;
+		DRM_INFO("Default TV standard: NTSC-J\n");
+		break;
+	case ATOM_TV_PAL:
+		tv_std = TV_STD_PAL;
+		DRM_INFO("Default TV standard: PAL\n");
+		break;
+	case ATOM_TV_PALM:
+		tv_std = TV_STD_PAL_M;
+		DRM_INFO("Default TV standard: PAL-M\n");
+		break;
+	case ATOM_TV_PALN:
+		tv_std = TV_STD_PAL_N;
+		DRM_INFO("Default TV standard: PAL-N\n");
+		break;
+	case ATOM_TV_PALCN:
+		tv_std = TV_STD_PAL_CN;
+		DRM_INFO("Default TV standard: PAL-CN\n");
+		break;
+	case ATOM_TV_PAL60:
+		tv_std = TV_STD_PAL_60;
+		DRM_INFO("Default TV standard: PAL-60\n");
+		break;
+	case ATOM_TV_SECAM:
+		tv_std = TV_STD_SECAM;
+		DRM_INFO("Default TV standard: SECAM\n");
+		break;
+	default:
+		tv_std = TV_STD_NTSC;
+		DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
+		break;
+	}
+	return tv_std;
+}
+
 struct radeon_encoder_tv_dac *
 radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
 {
@@ -1109,6 +1380,7 @@ radeon_atombios_get_tv_dac_info(struct r
 		dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;
 		tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
 
+		tv_dac->tv_std = radeon_atombios_get_tv_info(rdev);
 	}
 	return tv_dac;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_benchmark.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_benchmark.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_benchmark.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_benchmark.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,8 +29,8 @@
 void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
 			   unsigned sdomain, unsigned ddomain)
 {
-	struct radeon_object *dobj = NULL;
-	struct radeon_object *sobj = NULL;
+	struct radeon_bo *dobj = NULL;
+	struct radeon_bo *sobj = NULL;
 	struct radeon_fence *fence = NULL;
 	uint64_t saddr, daddr;
 	unsigned long start_jiffies;
@@ -41,47 +41,66 @@ void radeon_benchmark_move(struct radeon
 
 	size = bsize;
 	n = 1024;
-	r = radeon_object_create(rdev, NULL, size, true, sdomain, false, &sobj);
+	r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_pin(sobj, sdomain, &saddr);
+	r = radeon_bo_reserve(sobj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	r = radeon_bo_pin(sobj, sdomain, &saddr);
+	radeon_bo_unreserve(sobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_create(rdev, NULL, size, true, ddomain, false, &dobj);
+	r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	r = radeon_object_pin(dobj, ddomain, &daddr);
+	r = radeon_bo_reserve(dobj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	r = radeon_bo_pin(dobj, ddomain, &daddr);
+	radeon_bo_unreserve(dobj);
 	if (r) {
 		goto out_cleanup;
 	}
-	start_jiffies = jiffies;
-	for (i = 0; i < n; i++) {
-		r = radeon_fence_create(rdev, &fence);
-		if (r) {
-			goto out_cleanup;
-		}
-		r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence);
-		if (r) {
-			goto out_cleanup;
+
+	/* r100 doesn't have dma engine so skip the test */
+	if (rdev->asic->copy_dma) {
+
+		start_jiffies = jiffies;
+		for (i = 0; i < n; i++) {
+			r = radeon_fence_create(rdev, &fence);
+			if (r) {
+				goto out_cleanup;
+			}
+
+			r = radeon_copy_dma(rdev, saddr, daddr,
+					size / RADEON_GPU_PAGE_SIZE, fence);
+
+			if (r) {
+				goto out_cleanup;
+			}
+			r = radeon_fence_wait(fence, false);
+			if (r) {
+				goto out_cleanup;
+			}
+			radeon_fence_unref(&fence);
 		}
-		r = radeon_fence_wait(fence, false);
-		if (r) {
-			goto out_cleanup;
+		end_jiffies = jiffies;
+		time = end_jiffies - start_jiffies;
+		time = jiffies_to_msecs(time);
+		if (time > 0) {
+			i = ((n * size) >> 10) / time;
+			printk(KERN_INFO "radeon: dma %u bo moves of %ukb from"
+					" %d to %d in %lums (%ukb/ms %ukb/s %uM/s)\n",
+					n, size >> 10,
+					sdomain, ddomain, time,
+					i, i * 1000, (i * 1000) / 1024);
 		}
-		radeon_fence_unref(&fence);
-	}
-	end_jiffies = jiffies;
-	time = end_jiffies - start_jiffies;
-	time = jiffies_to_msecs(time);
-	if (time > 0) {
-		i = ((n * size) >> 10) / time;
-		printk(KERN_INFO "radeon: dma %u bo moves of %ukb from %d to %d"
-		       " in %lums (%ukb/ms %ukb/s %uM/s)\n", n, size >> 10,
-		       sdomain, ddomain, time, i, i * 1000, (i * 1000) / 1024);
 	}
+
 	start_jiffies = jiffies;
 	for (i = 0; i < n; i++) {
 		r = radeon_fence_create(rdev, &fence);
@@ -109,12 +128,20 @@ void radeon_benchmark_move(struct radeon
 	}
 out_cleanup:
 	if (sobj) {
-		radeon_object_unpin(sobj);
-		radeon_object_unref(&sobj);
+		r = radeon_bo_reserve(sobj, false);
+		if (likely(r == 0)) {
+			radeon_bo_unpin(sobj);
+			radeon_bo_unreserve(sobj);
+		}
+		radeon_bo_unref(&sobj);
 	}
 	if (dobj) {
-		radeon_object_unpin(dobj);
-		radeon_object_unref(&dobj);
+		r = radeon_bo_reserve(dobj, false);
+		if (likely(r == 0)) {
+			radeon_bo_unpin(dobj);
+			radeon_bo_unreserve(dobj);
+		}
+		radeon_bo_unref(&dobj);
 	}
 	if (fence) {
 		radeon_fence_unref(&fence);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_clocks.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,10 @@ uint32_t radeon_legacy_get_engine_clock(
 
 	ref_div =
 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
+
+	if (ref_div == 0)
+		return 0;
+
 	sclk = fb_div / ref_div;
 
 	post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
@@ -52,13 +56,13 @@ uint32_t radeon_legacy_get_engine_clock(
 	else if (post_div == 3)
 		sclk >>= 2;
 	else if (post_div == 4)
-		sclk >>= 4;
+		sclk >>= 3;
 
 	return sclk;
 }
 
 /* 10 khz */
-static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
+uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
 {
 	struct radeon_pll *mpll = &rdev->clock.mpll;
 	uint32_t fb_div, ref_div, post_div, mclk;
@@ -70,6 +74,10 @@ static uint32_t radeon_legacy_get_memory
 
 	ref_div =
 	    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;
+
+	if (ref_div == 0)
+		return 0;
+
 	mclk = fb_div / ref_div;
 
 	post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
@@ -78,7 +86,7 @@ static uint32_t radeon_legacy_get_memory
 	else if (post_div == 3)
 		mclk >>= 2;
 	else if (post_div == 4)
-		mclk >>= 4;
+		mclk >>= 3;
 
 	return mclk;
 }
@@ -98,8 +106,19 @@ void radeon_get_clock_info(struct drm_de
 		ret = radeon_combios_get_clock_info(dev);
 
 	if (ret) {
-		if (p1pll->reference_div < 2)
-			p1pll->reference_div = 12;
+		if (p1pll->reference_div < 2) {
+			if (!ASIC_IS_AVIVO(rdev)) {
+				u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
+				if (ASIC_IS_R300(rdev))
+					p1pll->reference_div =
+						(tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
+				else
+					p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
+				if (p1pll->reference_div < 2)
+					p1pll->reference_div = 12;
+			} else
+				p1pll->reference_div = 12;
+		}
 		if (p2pll->reference_div < 2)
 			p2pll->reference_div = 12;
 		if (rdev->family < CHIP_RS600) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_combios.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_combios.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_combios.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_combios.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,8 @@ radeon_add_legacy_connector(struct drm_d
 			    uint32_t supported_device,
 			    int connector_type,
 			    struct radeon_i2c_bus_rec *i2c_bus,
-			    uint16_t connector_object_id);
+			    uint16_t connector_object_id,
+			    struct radeon_hpd *hpd);
 
 /* from radeon_legacy_encoder.c */
 extern void
@@ -442,38 +443,70 @@ static uint16_t combios_get_table_offset
 
 }
 
-struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
+static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
+						       int ddc_line)
 {
 	struct radeon_i2c_bus_rec i2c;
 
-	i2c.mask_clk_mask = RADEON_GPIO_EN_1;
-	i2c.mask_data_mask = RADEON_GPIO_EN_0;
-	i2c.a_clk_mask = RADEON_GPIO_A_1;
-	i2c.a_data_mask = RADEON_GPIO_A_0;
-	i2c.put_clk_mask = RADEON_GPIO_EN_1;
-	i2c.put_data_mask = RADEON_GPIO_EN_0;
-	i2c.get_clk_mask = RADEON_GPIO_Y_1;
-	i2c.get_data_mask = RADEON_GPIO_Y_0;
-	if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
-	    (ddc_line == RADEON_MDGPIO_EN_REG)) {
-		i2c.mask_clk_reg = ddc_line;
-		i2c.mask_data_reg = ddc_line;
-		i2c.a_clk_reg = ddc_line;
-		i2c.a_data_reg = ddc_line;
-		i2c.put_clk_reg = ddc_line;
-		i2c.put_data_reg = ddc_line;
-		i2c.get_clk_reg = ddc_line + 4;
-		i2c.get_data_reg = ddc_line + 4;
+	if (ddc_line == RADEON_GPIOPAD_MASK) {
+		i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
+		i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
+		i2c.a_clk_reg = RADEON_GPIOPAD_A;
+		i2c.a_data_reg = RADEON_GPIOPAD_A;
+		i2c.en_clk_reg = RADEON_GPIOPAD_EN;
+		i2c.en_data_reg = RADEON_GPIOPAD_EN;
+		i2c.y_clk_reg = RADEON_GPIOPAD_Y;
+		i2c.y_data_reg = RADEON_GPIOPAD_Y;
+	} else if (ddc_line == RADEON_MDGPIO_MASK) {
+		i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
+		i2c.mask_data_reg = RADEON_MDGPIO_MASK;
+		i2c.a_clk_reg = RADEON_MDGPIO_A;
+		i2c.a_data_reg = RADEON_MDGPIO_A;
+		i2c.en_clk_reg = RADEON_MDGPIO_EN;
+		i2c.en_data_reg = RADEON_MDGPIO_EN;
+		i2c.y_clk_reg = RADEON_MDGPIO_Y;
+		i2c.y_data_reg = RADEON_MDGPIO_Y;
 	} else {
+		i2c.mask_clk_mask = RADEON_GPIO_EN_1;
+		i2c.mask_data_mask = RADEON_GPIO_EN_0;
+		i2c.a_clk_mask = RADEON_GPIO_A_1;
+		i2c.a_data_mask = RADEON_GPIO_A_0;
+		i2c.en_clk_mask = RADEON_GPIO_EN_1;
+		i2c.en_data_mask = RADEON_GPIO_EN_0;
+		i2c.y_clk_mask = RADEON_GPIO_Y_1;
+		i2c.y_data_mask = RADEON_GPIO_Y_0;
+
 		i2c.mask_clk_reg = ddc_line;
 		i2c.mask_data_reg = ddc_line;
 		i2c.a_clk_reg = ddc_line;
 		i2c.a_data_reg = ddc_line;
-		i2c.put_clk_reg = ddc_line;
-		i2c.put_data_reg = ddc_line;
-		i2c.get_clk_reg = ddc_line;
-		i2c.get_data_reg = ddc_line;
+		i2c.en_clk_reg = ddc_line;
+		i2c.en_data_reg = ddc_line;
+		i2c.y_clk_reg = ddc_line;
+		i2c.y_data_reg = ddc_line;
+	}
+
+	if (rdev->family < CHIP_R200)
+		i2c.hw_capable = false;
+	else {
+		switch (ddc_line) {
+		case RADEON_GPIO_VGA_DDC:
+		case RADEON_GPIO_DVI_DDC:
+			i2c.hw_capable = true;
+			break;
+		case RADEON_GPIO_MONID:
+			/* hw i2c on RADEON_GPIO_MONID doesn't seem to work
+			 * reliably on some pre-r4xx hardware; not sure why.
+			 */
+			i2c.hw_capable = false;
+			break;
+		default:
+			i2c.hw_capable = false;
+			break;
+		}
 	}
+	i2c.mm_i2c = false;
+	i2c.i2c_id = 0;
 
 	if (ddc_line)
 		i2c.valid = true;
@@ -495,7 +528,7 @@ bool radeon_combios_get_clock_info(struc
 	uint16_t sclk, mclk;
 
 	if (rdev->bios == NULL)
-		return NULL;
+		return false;
 
 	pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
 	if (pll_info) {
@@ -562,6 +595,48 @@ bool radeon_combios_get_clock_info(struc
 	return false;
 }
 
+bool radeon_combios_sideport_present(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	u16 igp_info;
+
+	igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
+
+	if (igp_info) {
+		if (RBIOS16(igp_info + 0x4))
+			return true;
+	}
+	return false;
+}
+
+static const uint32_t default_primarydac_adj[CHIP_LAST] = {
+	0x00000808,		/* r100  */
+	0x00000808,		/* rv100 */
+	0x00000808,		/* rs100 */
+	0x00000808,		/* rv200 */
+	0x00000808,		/* rs200 */
+	0x00000808,		/* r200  */
+	0x00000808,		/* rv250 */
+	0x00000000,		/* rs300 */
+	0x00000808,		/* rv280 */
+	0x00000808,		/* r300  */
+	0x00000808,		/* r350  */
+	0x00000808,		/* rv350 */
+	0x00000808,		/* rv380 */
+	0x00000808,		/* r420  */
+	0x00000808,		/* r423  */
+	0x00000808,		/* rv410 */
+	0x00000000,		/* rs400 */
+	0x00000000,		/* rs480 */
+};
+
+static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev,
+							  struct radeon_encoder_primary_dac *p_dac)
+{
+	p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family];
+	return;
+}
+
 struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
 								       radeon_encoder
 								       *encoder)
@@ -571,20 +646,20 @@ struct radeon_encoder_primary_dac *radeo
 	uint16_t dac_info;
 	uint8_t rev, bg, dac;
 	struct radeon_encoder_primary_dac *p_dac = NULL;
+	int found = 0;
 
-	if (rdev->bios == NULL)
+	p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac),
+			GFP_KERNEL);
+
+	if (!p_dac)
 		return NULL;
 
+	if (rdev->bios == NULL)
+		goto out;
+
 	/* check CRT table */
 	dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
 	if (dac_info) {
-		p_dac =
-		    kzalloc(sizeof(struct radeon_encoder_primary_dac),
-			    GFP_KERNEL);
-
-		if (!p_dac)
-			return NULL;
-
 		rev = RBIOS8(dac_info) & 0x3;
 		if (rev < 2) {
 			bg = RBIOS8(dac_info + 0x2) & 0xf;
@@ -595,20 +670,26 @@ struct radeon_encoder_primary_dac *radeo
 			dac = RBIOS8(dac_info + 0x3) & 0xf;
 			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
 		}
-
+		found = 1;
 	}
 
+out:
+	if (!found) /* fallback to defaults */
+		radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
+
 	return p_dac;
 }
 
-static enum radeon_tv_std
-radeon_combios_get_tv_info(struct radeon_encoder *encoder)
+enum radeon_tv_std
+radeon_combios_get_tv_info(struct radeon_device *rdev)
 {
-	struct drm_device *dev = encoder->base.dev;
-	struct radeon_device *rdev = dev->dev_private;
+	struct drm_device *dev = rdev->ddev;
 	uint16_t tv_info;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
+	if (rdev->bios == NULL)
+		return tv_std;
+
 	tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
 	if (tv_info) {
 		if (RBIOS8(tv_info + 6) == 'T') {
@@ -746,7 +827,7 @@ struct radeon_encoder_tv_dac *radeon_com
 			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
 			found = 1;
 		}
-		tv_dac->tv_std = radeon_combios_get_tv_info(encoder);
+		tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
 	}
 	if (!found) {
 		/* then check CRT table */
@@ -890,8 +971,7 @@ struct radeon_encoder_lvds *radeon_combi
 			 lvds->native_mode.vdisplay);
 
 		lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
-		if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0)
-			lvds->panel_vcc_delay = 2000;
+		lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000);
 
 		lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24);
 		lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf;
@@ -993,8 +1073,8 @@ static const struct radeon_tmds_pll defa
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R420  */
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R423  */
 	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RV410 */
-	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RS400 */
-	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RS480 */
+	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS400 */
+	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS480 */
 };
 
 bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
@@ -1028,7 +1108,6 @@ bool radeon_legacy_get_tmds_info_from_co
 	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
 
 	if (tmds_info) {
-
 		ver = RBIOS8(tmds_info);
 		DRM_INFO("DFP table revision: %d\n", ver);
 		if (ver == 3) {
@@ -1063,51 +1142,139 @@ bool radeon_legacy_get_tmds_info_from_co
 					  tmds->tmds_pll[i].value);
 			}
 		}
-	} else
+	} else {
 		DRM_INFO("No TMDS info found in BIOS\n");
+		return false;
+	}
 	return true;
 }
 
-struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
+bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
+						struct radeon_encoder_ext_tmds *tmds)
 {
-	struct radeon_encoder_int_tmds *tmds = NULL;
-	bool ret;
-
-	tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_i2c_bus_rec i2c_bus;
 
-	if (!tmds)
-		return NULL;
+	/* default for macs */
+	i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+	tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
 
-	ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
-	if (ret == false)
-		radeon_legacy_get_tmds_info_from_table(encoder, tmds);
+	/* XXX some macs have duallink chips */
+	switch (rdev->mode_info.connector_table) {
+	case CT_POWERBOOK_EXTERNAL:
+	case CT_MINI_EXTERNAL:
+	default:
+		tmds->dvo_chip = DVO_SIL164;
+		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
+		break;
+	}
 
-	return tmds;
+	return true;
 }
 
-void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder)
+bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
+						  struct radeon_encoder_ext_tmds *tmds)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct radeon_device *rdev = dev->dev_private;
-	uint16_t ext_tmds_info;
-	uint8_t ver;
+	uint16_t offset;
+	uint8_t ver, id, blocks, clk, data;
+	int i;
+	enum radeon_combios_ddc gpio;
+	struct radeon_i2c_bus_rec i2c_bus;
 
 	if (rdev->bios == NULL)
-		return;
+		return false;
 
-	ext_tmds_info =
-	    combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
-	if (ext_tmds_info) {
-		ver = RBIOS8(ext_tmds_info);
-		DRM_INFO("External TMDS Table revision: %d\n", ver);
-		// TODO
+	tmds->i2c_bus = NULL;
+	if (rdev->flags & RADEON_IS_IGP) {
+		offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
+		if (offset) {
+			ver = RBIOS8(offset);
+			DRM_INFO("GPIO Table revision: %d\n", ver);
+			blocks = RBIOS8(offset + 2);
+			for (i = 0; i < blocks; i++) {
+				id = RBIOS8(offset + 3 + (i * 5) + 0);
+				if (id == 136) {
+					clk = RBIOS8(offset + 3 + (i * 5) + 3);
+					data = RBIOS8(offset + 3 + (i * 5) + 4);
+					i2c_bus.valid = true;
+					i2c_bus.mask_clk_mask = (1 << clk);
+					i2c_bus.mask_data_mask = (1 << data);
+					i2c_bus.a_clk_mask = (1 << clk);
+					i2c_bus.a_data_mask = (1 << data);
+					i2c_bus.en_clk_mask = (1 << clk);
+					i2c_bus.en_data_mask = (1 << data);
+					i2c_bus.y_clk_mask = (1 << clk);
+					i2c_bus.y_data_mask = (1 << data);
+					i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
+					i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
+					i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
+					i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
+					i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
+					i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
+					i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
+					i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
+					tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+					tmds->dvo_chip = DVO_SIL164;
+					tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
+					break;
+				}
+			}
+		}
+	} else {
+		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+		if (offset) {
+			ver = RBIOS8(offset);
+			DRM_INFO("External TMDS Table revision: %d\n", ver);
+			tmds->slave_addr = RBIOS8(offset + 4 + 2);
+			tmds->slave_addr >>= 1; /* 7 bit addressing */
+			gpio = RBIOS8(offset + 4 + 3);
+			switch (gpio) {
+			case DDC_MONID:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_DVI:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_VGA:
+				i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_CRT2:
+				/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
+				if (rdev->family >= CHIP_R300)
+					i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+				else
+					i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+				tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
+				break;
+			case DDC_LCD: /* MM i2c */
+				DRM_ERROR("MM i2c requires hw i2c engine\n");
+				break;
+			default:
+				DRM_ERROR("Unsupported gpio %d\n", gpio);
+				break;
+			}
+		}
+	}
+
+	if (!tmds->i2c_bus) {
+		DRM_INFO("No valid Ext TMDS info found in BIOS\n");
+		return false;
 	}
+
+	return true;
 }
 
 bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_i2c_bus_rec ddc_i2c;
+	struct radeon_hpd hpd;
 
 	rdev->mode_info.connector_table = radeon_connector_table;
 	if (rdev->mode_info.connector_table == CT_NONE) {
@@ -1168,7 +1335,8 @@ bool radeon_get_legacy_connector_info_fr
 		/* these are the most common settings */
 		if (rdev->flags & RADEON_SINGLE_CRTC) {
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1178,10 +1346,12 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		} else if (rdev->flags & RADEON_IS_MOBILITY) {
 			/* LVDS */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+			ddc_i2c = combios_setup_i2c_bus(rdev, 0);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_LCD1_SUPPORT,
@@ -1191,10 +1361,12 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_LCD1_SUPPORT,
 						    DRM_MODE_CONNECTOR_LVDS,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_LVDS);
+						    CONNECTOR_OBJECT_ID_LVDS,
+						    &hpd);
 
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1204,10 +1376,12 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		} else {
 			/* DVI-I - tv dac, int tmds */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+			hpd.hpd = RADEON_HPD_1;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_DFP1_SUPPORT,
@@ -1223,10 +1397,12 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_CRT2_SUPPORT,
 						    DRM_MODE_CONNECTOR_DVII,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+						    &hpd);
 
 			/* VGA - primary dac */
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_CRT1_SUPPORT,
@@ -1236,11 +1412,14 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_CRT1_SUPPORT,
 						    DRM_MODE_CONNECTOR_VGA,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_VGA);
+						    CONNECTOR_OBJECT_ID_VGA,
+						    &hpd);
 		}
 
 		if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
 			/* TV - tv dac */
+			ddc_i2c.valid = false;
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_encoder(dev,
 						  radeon_get_encoder_id(dev,
 									ATOM_DEVICE_TV1_SUPPORT,
@@ -1250,14 +1429,16 @@ bool radeon_get_legacy_connector_info_fr
 						    ATOM_DEVICE_TV1_SUPPORT,
 						    DRM_MODE_CONNECTOR_SVIDEO,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SVIDEO);
+						    CONNECTOR_OBJECT_ID_SVIDEO,
+						    &hpd);
 		}
 		break;
 	case CT_IBOOK:
 		DRM_INFO("Connector Table: %d (ibook)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1265,9 +1446,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* VGA - TV DAC */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1275,8 +1458,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1285,13 +1471,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_EXTERNAL:
 		DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1299,9 +1487,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* DVI-I - primary dac, ext tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_2; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP2_SUPPORT,
@@ -1317,8 +1507,11 @@ bool radeon_get_legacy_connector_info_fr
 					    ATOM_DEVICE_DFP2_SUPPORT |
 					    ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1327,13 +1520,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_INTERNAL:
 		DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1341,9 +1536,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* DVI-I - primary dac, int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1358,8 +1555,11 @@ bool radeon_get_legacy_connector_info_fr
 					    ATOM_DEVICE_DFP1_SUPPORT |
 					    ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1368,13 +1568,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_POWERBOOK_VGA:
 		DRM_INFO("Connector Table: %d (powerbook vga)\n",
 			 rdev->mode_info.connector_table);
 		/* LVDS */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_LCD1_SUPPORT,
@@ -1382,9 +1584,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_LCD1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
 					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_LVDS);
+					    CONNECTOR_OBJECT_ID_LVDS,
+					    &hpd);
 		/* VGA - primary dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT1_SUPPORT,
@@ -1392,8 +1596,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_CRT1_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1402,13 +1609,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_MINI_EXTERNAL:
 		DRM_INFO("Connector Table: %d (mini external tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-I - tv dac, ext tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_2; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP2_SUPPORT,
@@ -1424,8 +1633,11 @@ bool radeon_get_legacy_connector_info_fr
 					    ATOM_DEVICE_DFP2_SUPPORT |
 					    ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1434,13 +1646,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_MINI_INTERNAL:
 		DRM_INFO("Connector Table: %d (mini internal tmds)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-I - tv dac, int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1455,8 +1669,11 @@ bool radeon_get_legacy_connector_info_fr
 					    ATOM_DEVICE_DFP1_SUPPORT |
 					    ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1465,13 +1682,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_IMAC_G5_ISIGHT:
 		DRM_INFO("Connector Table: %d (imac g5 isight)\n",
 			 rdev->mode_info.connector_table);
 		/* DVI-D - int tmds */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
+		hpd.hpd = RADEON_HPD_1; /* ??? */
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_DFP1_SUPPORT,
@@ -1479,9 +1698,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_DFP1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
 					    DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+					    &hpd);
 		/* VGA - tv dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1489,8 +1710,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1499,13 +1723,15 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	case CT_EMAC:
 		DRM_INFO("Connector Table: %d (emac)\n",
 			 rdev->mode_info.connector_table);
 		/* VGA - primary dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT1_SUPPORT,
@@ -1513,9 +1739,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_CRT1_SUPPORT);
 		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* VGA - tv dac */
-		ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_CRT2_SUPPORT,
@@ -1523,8 +1751,11 @@ bool radeon_get_legacy_connector_info_fr
 					  ATOM_DEVICE_CRT2_SUPPORT);
 		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
 					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_VGA);
+					    CONNECTOR_OBJECT_ID_VGA,
+					    &hpd);
 		/* TV - TV DAC */
+		ddc_i2c.valid = false;
+		hpd.hpd = RADEON_HPD_NONE;
 		radeon_add_legacy_encoder(dev,
 					  radeon_get_encoder_id(dev,
 								ATOM_DEVICE_TV1_SUPPORT,
@@ -1533,7 +1764,8 @@ bool radeon_get_legacy_connector_info_fr
 		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
 					    DRM_MODE_CONNECTOR_SVIDEO,
 					    &ddc_i2c,
-					    CONNECTOR_OBJECT_ID_SVIDEO);
+					    CONNECTOR_OBJECT_ID_SVIDEO,
+					    &hpd);
 		break;
 	default:
 		DRM_INFO("Connector table: %d (invalid)\n",
@@ -1550,7 +1782,8 @@ static bool radeon_apply_legacy_quirks(s
 				       int bios_index,
 				       enum radeon_combios_connector
 				       *legacy_connector,
-				       struct radeon_i2c_bus_rec *ddc_i2c)
+				       struct radeon_i2c_bus_rec *ddc_i2c,
+				       struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 
@@ -1558,29 +1791,26 @@ static bool radeon_apply_legacy_quirks(s
 	if ((rdev->family == CHIP_RS400 ||
 	     rdev->family == CHIP_RS480) &&
 	    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
-		*ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
 	else if ((rdev->family == CHIP_RS400 ||
 		  rdev->family == CHIP_RS480) &&
 		 ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) {
-		ddc_i2c->valid = true;
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK);
 		ddc_i2c->mask_clk_mask = (0x20 << 8);
 		ddc_i2c->mask_data_mask = 0x80;
 		ddc_i2c->a_clk_mask = (0x20 << 8);
 		ddc_i2c->a_data_mask = 0x80;
-		ddc_i2c->put_clk_mask = (0x20 << 8);
-		ddc_i2c->put_data_mask = 0x80;
-		ddc_i2c->get_clk_mask = (0x20 << 8);
-		ddc_i2c->get_data_mask = 0x80;
-		ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK;
-		ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK;
-		ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A;
-		ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
-		ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN;
-		ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN;
-		ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG;
-		ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG;
+		ddc_i2c->en_clk_mask = (0x20 << 8);
+		ddc_i2c->en_data_mask = 0x80;
+		ddc_i2c->y_clk_mask = (0x20 << 8);
+		ddc_i2c->y_data_mask = 0x80;
 	}
 
+	/* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
+	if ((rdev->family >= CHIP_R300) &&
+	    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
+		*ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+
 	/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
 	   one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
 	if (dev->pdev->device == 0x515e &&
@@ -1624,6 +1854,12 @@ static bool radeon_apply_legacy_tv_quirk
 	    dev->pdev->subsystem_device == 0x280a)
 		return false;
 
+	/* MSI S270 has non-existent TV port */
+	if (dev->pdev->device == 0x5955 &&
+	    dev->pdev->subsystem_vendor == 0x1462 &&
+	    dev->pdev->subsystem_device == 0x0131)
+		return false;
+
 	return true;
 }
 
@@ -1671,6 +1907,7 @@ bool radeon_get_legacy_connector_info_fr
 	enum radeon_combios_connector connector;
 	int i = 0;
 	struct radeon_i2c_bus_rec ddc_i2c;
+	struct radeon_hpd hpd;
 
 	if (rdev->bios == NULL)
 		return false;
@@ -1691,26 +1928,40 @@ bool radeon_get_legacy_connector_info_fr
 			switch (ddc_type) {
 			case DDC_MONID:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_MONID);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID);
 				break;
 			case DDC_DVI:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
 				break;
 			case DDC_VGA:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
 				break;
 			case DDC_CRT2:
 				ddc_i2c =
-				    combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+					combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC);
+				break;
+			default:
+				break;
+			}
+
+			switch (connector) {
+			case CONNECTOR_PROPRIETARY_LEGACY:
+			case CONNECTOR_DVI_I_LEGACY:
+			case CONNECTOR_DVI_D_LEGACY:
+				if ((tmp >> 4) & 0x1)
+					hpd.hpd = RADEON_HPD_2;
+				else
+					hpd.hpd = RADEON_HPD_1;
 				break;
 			default:
+				hpd.hpd = RADEON_HPD_NONE;
 				break;
 			}
 
 			if (!radeon_apply_legacy_quirks(dev, i, &connector,
-						       &ddc_i2c))
+							&ddc_i2c, &hpd))
 				continue;
 
 			switch (connector) {
@@ -1727,7 +1978,8 @@ bool radeon_get_legacy_connector_info_fr
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D);
+							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
+							    &hpd);
 				break;
 			case CONNECTOR_CRT_LEGACY:
 				if (tmp & 0x1) {
@@ -1753,7 +2005,8 @@ bool radeon_get_legacy_connector_info_fr
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_VGA);
+							    CONNECTOR_OBJECT_ID_VGA,
+							    &hpd);
 				break;
 			case CONNECTOR_DVI_I_LEGACY:
 				devices = 0;
@@ -1799,7 +2052,8 @@ bool radeon_get_legacy_connector_info_fr
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    connector_object_id);
+							    connector_object_id,
+							    &hpd);
 				break;
 			case CONNECTOR_DVI_D_LEGACY:
 				if ((tmp >> 4) & 0x1) {
@@ -1817,7 +2071,8 @@ bool radeon_get_legacy_connector_info_fr
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    connector_object_id);
+							    connector_object_id,
+							    &hpd);
 				break;
 			case CONNECTOR_CTV_LEGACY:
 			case CONNECTOR_STV_LEGACY:
@@ -1832,7 +2087,8 @@ bool radeon_get_legacy_connector_info_fr
 							    legacy_connector_convert
 							    [connector],
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_SVIDEO);
+							    CONNECTOR_OBJECT_ID_SVIDEO,
+							    &hpd);
 				break;
 			default:
 				DRM_ERROR("Unknown connector type: %d\n",
@@ -1858,14 +2114,16 @@ bool radeon_get_legacy_connector_info_fr
 									0),
 						  ATOM_DEVICE_DFP1_SUPPORT);
 
-			ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+			ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC);
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_connector(dev,
 						    0,
 						    ATOM_DEVICE_CRT1_SUPPORT |
 						    ATOM_DEVICE_DFP1_SUPPORT,
 						    DRM_MODE_CONNECTOR_DVII,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I);
+						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
+						    &hpd);
 		} else {
 			uint16_t crt_info =
 				combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
@@ -1876,13 +2134,15 @@ bool radeon_get_legacy_connector_info_fr
 										ATOM_DEVICE_CRT1_SUPPORT,
 										1),
 							  ATOM_DEVICE_CRT1_SUPPORT);
-				ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+				ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC);
+				hpd.hpd = RADEON_HPD_NONE;
 				radeon_add_legacy_connector(dev,
 							    0,
 							    ATOM_DEVICE_CRT1_SUPPORT,
 							    DRM_MODE_CONNECTOR_VGA,
 							    &ddc_i2c,
-							    CONNECTOR_OBJECT_ID_VGA);
+							    CONNECTOR_OBJECT_ID_VGA,
+							    &hpd);
 			} else {
 				DRM_DEBUG("No connector info found\n");
 				return false;
@@ -1910,27 +2170,27 @@ bool radeon_get_legacy_connector_info_fr
 				case DDC_MONID:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_MONID);
+						(rdev, RADEON_GPIO_MONID);
 					break;
 				case DDC_DVI:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_DVI_DDC);
+						(rdev, RADEON_GPIO_DVI_DDC);
 					break;
 				case DDC_VGA:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_VGA_DDC);
+						(rdev, RADEON_GPIO_VGA_DDC);
 					break;
 				case DDC_CRT2:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_GPIO_CRT2_DDC);
+						(rdev, RADEON_GPIO_CRT2_DDC);
 					break;
 				case DDC_LCD:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_LCD_GPIO_MASK);
+						(rdev, RADEON_GPIOPAD_MASK);
 					ddc_i2c.mask_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.mask_data_mask =
@@ -1939,19 +2199,19 @@ bool radeon_get_legacy_connector_info_fr
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.a_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.put_clk_mask =
+					ddc_i2c.en_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.put_data_mask =
+					ddc_i2c.en_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.get_clk_mask =
+					ddc_i2c.y_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.get_data_mask =
+					ddc_i2c.y_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
 					break;
 				case DDC_GPIO:
 					ddc_i2c =
 					    combios_setup_i2c_bus
-					    (RADEON_MDGPIO_EN_REG);
+						(rdev, RADEON_MDGPIO_MASK);
 					ddc_i2c.mask_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.mask_data_mask =
@@ -1960,13 +2220,13 @@ bool radeon_get_legacy_connector_info_fr
 					    RBIOS32(lcd_ddc_info + 3);
 					ddc_i2c.a_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.put_clk_mask =
+					ddc_i2c.en_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.put_data_mask =
+					ddc_i2c.en_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
-					ddc_i2c.get_clk_mask =
+					ddc_i2c.y_clk_mask =
 					    RBIOS32(lcd_ddc_info + 3);
-					ddc_i2c.get_data_mask =
+					ddc_i2c.y_data_mask =
 					    RBIOS32(lcd_ddc_info + 7);
 					break;
 				default:
@@ -1977,12 +2237,14 @@ bool radeon_get_legacy_connector_info_fr
 			} else
 				ddc_i2c.valid = false;
 
+			hpd.hpd = RADEON_HPD_NONE;
 			radeon_add_legacy_connector(dev,
 						    5,
 						    ATOM_DEVICE_LCD1_SUPPORT,
 						    DRM_MODE_CONNECTOR_LVDS,
 						    &ddc_i2c,
-						    CONNECTOR_OBJECT_ID_LVDS);
+						    CONNECTOR_OBJECT_ID_LVDS,
+						    &hpd);
 		}
 	}
 
@@ -1993,6 +2255,7 @@ bool radeon_get_legacy_connector_info_fr
 		if (tv_info) {
 			if (RBIOS8(tv_info + 6) == 'T') {
 				if (radeon_apply_legacy_tv_quirks(dev)) {
+					hpd.hpd = RADEON_HPD_NONE;
 					radeon_add_legacy_encoder(dev,
 								  radeon_get_encoder_id
 								  (dev,
@@ -2003,7 +2266,8 @@ bool radeon_get_legacy_connector_info_fr
 								    ATOM_DEVICE_TV1_SUPPORT,
 								    DRM_MODE_CONNECTOR_SVIDEO,
 								    &ddc_i2c,
-								    CONNECTOR_OBJECT_ID_SVIDEO);
+								    CONNECTOR_OBJECT_ID_SVIDEO,
+								    &hpd);
 				}
 			}
 		}
@@ -2014,6 +2278,193 @@ bool radeon_get_legacy_connector_info_fr
 	return true;
 }
 
+void radeon_external_tmds_setup(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+
+	if (!tmds)
+		return;
+
+	switch (tmds->dvo_chip) {
+	case DVO_SIL164:
+		/* sil 164 */
+		radeon_i2c_do_lock(tmds->i2c_bus, 1);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x08, 0x30);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x09, 0x00);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x0a, 0x90);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x0c, 0x89);
+		radeon_i2c_sw_put_byte(tmds->i2c_bus,
+				       tmds->slave_addr,
+				       0x08, 0x3b);
+		radeon_i2c_do_lock(tmds->i2c_bus, 0);
+		break;
+	case DVO_SIL1178:
+		/* sil 1178 - untested */
+		/*
+		 * 0x0f, 0x44
+		 * 0x0f, 0x4c
+		 * 0x0e, 0x01
+		 * 0x0a, 0x80
+		 * 0x09, 0x30
+		 * 0x0c, 0xc9
+		 * 0x0d, 0x70
+		 * 0x08, 0x32
+		 * 0x08, 0x33
+		 */
+		break;
+	default:
+		break;
+	}
+
+}
+
+bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	uint16_t offset;
+	uint8_t blocks, slave_addr, rev;
+	uint32_t index, id;
+	uint32_t reg, val, and_mask, or_mask;
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+
+	if (rdev->bios == NULL)
+		return false;
+
+	if (!tmds)
+		return false;
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
+		rev = RBIOS8(offset);
+		if (offset) {
+			rev = RBIOS8(offset);
+			if (rev > 1) {
+				blocks = RBIOS8(offset + 3);
+				index = offset + 4;
+				while (blocks > 0) {
+					id = RBIOS16(index);
+					index += 2;
+					switch (id >> 13) {
+					case 0:
+						reg = (id & 0x1fff) * 4;
+						val = RBIOS32(index);
+						index += 4;
+						WREG32(reg, val);
+						break;
+					case 2:
+						reg = (id & 0x1fff) * 4;
+						and_mask = RBIOS32(index);
+						index += 4;
+						or_mask = RBIOS32(index);
+						index += 4;
+						val = RREG32(reg);
+						val = (val & and_mask) | or_mask;
+						WREG32(reg, val);
+						break;
+					case 3:
+						val = RBIOS16(index);
+						index += 2;
+						udelay(val);
+						break;
+					case 4:
+						val = RBIOS16(index);
+						index += 2;
+						udelay(val * 1000);
+						break;
+					case 6:
+						slave_addr = id & 0xff;
+						slave_addr >>= 1; /* 7 bit addressing */
+						index++;
+						reg = RBIOS8(index);
+						index++;
+						val = RBIOS8(index);
+						index++;
+						radeon_i2c_do_lock(tmds->i2c_bus, 1);
+						radeon_i2c_sw_put_byte(tmds->i2c_bus,
+								       slave_addr,
+								       reg, val);
+						radeon_i2c_do_lock(tmds->i2c_bus, 0);
+						break;
+					default:
+						DRM_ERROR("Unknown id %d\n", id >> 13);
+						break;
+					}
+					blocks--;
+				}
+				return true;
+			}
+		}
+	} else {
+		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
+		if (offset) {
+			index = offset + 10;
+			id = RBIOS16(index);
+			while (id != 0xffff) {
+				index += 2;
+				switch (id >> 13) {
+				case 0:
+					reg = (id & 0x1fff) * 4;
+					val = RBIOS32(index);
+					WREG32(reg, val);
+					break;
+				case 2:
+					reg = (id & 0x1fff) * 4;
+					and_mask = RBIOS32(index);
+					index += 4;
+					or_mask = RBIOS32(index);
+					index += 4;
+					val = RREG32(reg);
+					val = (val & and_mask) | or_mask;
+					WREG32(reg, val);
+					break;
+				case 4:
+					val = RBIOS16(index);
+					index += 2;
+					udelay(val);
+					break;
+				case 5:
+					reg = id & 0x1fff;
+					and_mask = RBIOS32(index);
+					index += 4;
+					or_mask = RBIOS32(index);
+					index += 4;
+					val = RREG32_PLL(reg);
+					val = (val & and_mask) | or_mask;
+					WREG32_PLL(reg, val);
+					break;
+				case 6:
+					reg = id & 0x1fff;
+					val = RBIOS8(index);
+					index += 1;
+					radeon_i2c_do_lock(tmds->i2c_bus, 1);
+					radeon_i2c_sw_put_byte(tmds->i2c_bus,
+							       tmds->slave_addr,
+							       reg, val);
+					radeon_i2c_do_lock(tmds->i2c_bus, 0);
+					break;
+				default:
+					DRM_ERROR("Unknown id %d\n", id >> 13);
+					break;
+				}
+				id = RBIOS16(index);
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
 static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
 {
 	struct radeon_device *rdev = dev->dev_private;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_connectors.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,28 @@ radeon_atombios_connected_scratch_regs(s
 				       struct drm_encoder *encoder,
 				       bool connected);
 
+void radeon_connector_hotplug(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+	if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
+		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+
+	if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+	    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+		if ((radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+		    (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_eDP)) {
+			if (radeon_dp_needs_link_train(radeon_connector)) {
+				if (connector->encoder)
+					dp_link_train(connector->encoder, connector);
+			}
+		}
+	}
+
+}
+
 static void radeon_property_change_mode(struct drm_encoder *encoder)
 {
 	struct drm_crtc *crtc = encoder->crtc;
@@ -188,6 +210,18 @@ static struct drm_display_mode *radeon_f
 		drm_mode_set_name(mode);
 
 		DRM_DEBUG("Adding native panel mode %s\n", mode->name);
+	} else if (native_mode->hdisplay != 0 &&
+		   native_mode->vdisplay != 0) {
+		/* mac laptops without an edid */
+		/* Note that this is not necessarily the exact panel mode,
+		 * but an approximation based on the cvt formula.  For these
+		 * systems we should ideally read the mode info out of the
+		 * registers or add a mode table, but this works and is much
+		 * simpler.
+		 */
+		mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
+		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
+		DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name);
 	}
 	return mode;
 }
@@ -445,10 +479,10 @@ static enum drm_connector_status radeon_
 		ret = connector_status_connected;
 	else {
 		if (radeon_connector->ddc_bus) {
-			radeon_i2c_do_lock(radeon_connector, 1);
+			radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
 							      &radeon_connector->ddc_bus->adapter);
-			radeon_i2c_do_lock(radeon_connector, 0);
+			radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 			if (radeon_connector->edid)
 				ret = connector_status_connected;
 		}
@@ -546,24 +580,26 @@ static enum drm_connector_status radeon_
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct drm_encoder *encoder;
 	struct drm_encoder_helper_funcs *encoder_funcs;
-	bool dret;
+	bool dret = false;
 	enum drm_connector_status ret = connector_status_disconnected;
 
 	encoder = radeon_best_single_encoder(connector);
 	if (!encoder)
 		ret = connector_status_disconnected;
 
-	radeon_i2c_do_lock(radeon_connector, 1);
-	dret = radeon_ddc_probe(radeon_connector);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	if (radeon_connector->ddc_bus) {
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+		dret = radeon_ddc_probe(radeon_connector);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
+	}
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -583,7 +619,7 @@ static enum drm_connector_status radeon_
 				ret = connector_status_connected;
 		}
 	} else {
-		if (radeon_connector->dac_load_detect) {
+		if (radeon_connector->dac_load_detect && encoder) {
 			encoder_funcs = encoder->helper_private;
 			ret = encoder_funcs->detect(encoder, connector);
 		}
@@ -706,19 +742,21 @@ static enum drm_connector_status radeon_
 	struct drm_mode_object *obj;
 	int i;
 	enum drm_connector_status ret = connector_status_disconnected;
-	bool dret;
+	bool dret = false;
 
-	radeon_i2c_do_lock(radeon_connector, 1);
-	dret = radeon_ddc_probe(radeon_connector);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	if (radeon_connector->ddc_bus) {
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+		dret = radeon_ddc_probe(radeon_connector);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
+	}
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
 			radeon_connector->edid = NULL;
 		}
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -735,6 +773,39 @@ static enum drm_connector_status radeon_
 				ret = connector_status_disconnected;
 			} else
 				ret = connector_status_connected;
+
+			/* multiple connectors on the same encoder with the same ddc line
+			 * This tends to be HDMI and DVI on the same encoder with the
+			 * same ddc line.  If the edid says HDMI, consider the HDMI port
+			 * connected and the DVI port disconnected.  If the edid doesn't
+			 * say HDMI, vice versa.
+			 */
+			if (radeon_connector->shared_ddc && (ret == connector_status_connected)) {
+				struct drm_device *dev = connector->dev;
+				struct drm_connector *list_connector;
+				struct radeon_connector *list_radeon_connector;
+				list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
+					if (connector == list_connector)
+						continue;
+					list_radeon_connector = to_radeon_connector(list_connector);
+					if (radeon_connector->devices == list_radeon_connector->devices) {
+						if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+							if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
+								kfree(radeon_connector->edid);
+								radeon_connector->edid = NULL;
+								ret = connector_status_disconnected;
+							}
+						} else {
+							if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
+							    (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
+								kfree(radeon_connector->edid);
+								radeon_connector->edid = NULL;
+								ret = connector_status_disconnected;
+							}
+						}
+					}
+				}
+			}
 		}
 	}
 
@@ -833,10 +904,18 @@ static void radeon_dvi_force(struct drm_
 static int radeon_dvi_mode_valid(struct drm_connector *connector,
 				  struct drm_display_mode *mode)
 {
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
 	/* XXX check mode bandwidth */
 
+	/* clocks over 135 MHz have heat issues with DVI on RV100 */
+	if (radeon_connector->use_digital &&
+	    (rdev->family == CHIP_RV100) &&
+	    (mode->clock > 135000))
+		return MODE_CLOCK_HIGH;
+
 	if (radeon_connector->use_digital && (mode->clock > 165000)) {
 		if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
 		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
@@ -863,6 +942,93 @@ struct drm_connector_funcs radeon_dvi_co
 	.force = radeon_dvi_force,
 };
 
+static void radeon_dp_connector_destroy(struct drm_connector *connector)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+
+	if (radeon_connector->ddc_bus)
+		radeon_i2c_destroy(radeon_connector->ddc_bus);
+	if (radeon_connector->edid)
+		kfree(radeon_connector->edid);
+	if (radeon_dig_connector->dp_i2c_bus)
+		radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
+	kfree(radeon_connector->con_priv);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
+static int radeon_dp_get_modes(struct drm_connector *connector)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	int ret;
+
+	ret = radeon_ddc_get_modes(radeon_connector);
+	return ret;
+}
+
+static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	enum drm_connector_status ret = connector_status_disconnected;
+	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+	u8 sink_type;
+
+	if (radeon_connector->edid) {
+		kfree(radeon_connector->edid);
+		radeon_connector->edid = NULL;
+	}
+
+	sink_type = radeon_dp_getsinktype(radeon_connector);
+	if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+	    (sink_type == CONNECTOR_OBJECT_ID_eDP)) {
+		if (radeon_dp_getdpcd(radeon_connector)) {
+			radeon_dig_connector->dp_sink_type = sink_type;
+			ret = connector_status_connected;
+		}
+	} else {
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
+		if (radeon_ddc_probe(radeon_connector)) {
+			radeon_dig_connector->dp_sink_type = sink_type;
+			ret = connector_status_connected;
+		}
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
+	}
+
+	return ret;
+}
+
+static int radeon_dp_mode_valid(struct drm_connector *connector,
+				  struct drm_display_mode *mode)
+{
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+
+	/* XXX check mode bandwidth */
+
+	if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+	    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+		return radeon_dp_mode_valid_helper(radeon_connector, mode);
+	else
+		return MODE_OK;
+}
+
+struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
+	.get_modes = radeon_dp_get_modes,
+	.mode_valid = radeon_dp_mode_valid,
+	.best_encoder = radeon_dvi_encoder,
+};
+
+struct drm_connector_funcs radeon_dp_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = radeon_dp_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = radeon_connector_set_property,
+	.destroy = radeon_dp_connector_destroy,
+	.force = radeon_dvi_force,
+};
+
 void
 radeon_add_atom_connector(struct drm_device *dev,
 			  uint32_t connector_id,
@@ -871,7 +1037,8 @@ radeon_add_atom_connector(struct drm_dev
 			  struct radeon_i2c_bus_rec *i2c_bus,
 			  bool linkb,
 			  uint32_t igp_lane_info,
-			  uint16_t connector_object_id)
+			  uint16_t connector_object_id,
+			  struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
@@ -893,8 +1060,7 @@ radeon_add_atom_connector(struct drm_dev
 			return;
 		}
 		if (radeon_connector->ddc_bus && i2c_bus->valid) {
-			if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus,
-				    sizeof(struct radeon_i2c_bus_rec)) == 0) {
+			if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {
 				radeon_connector->shared_ddc = true;
 				shared_ddc = true;
 			}
@@ -911,6 +1077,7 @@ radeon_add_atom_connector(struct drm_dev
 	radeon_connector->devices = supported_device;
 	radeon_connector->shared_ddc = shared_ddc;
 	radeon_connector->connector_object_id = connector_object_id;
+	radeon_connector->hpd = *hpd;
 	switch (connector_type) {
 	case DRM_MODE_CONNECTOR_VGA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -963,10 +1130,12 @@ radeon_add_atom_connector(struct drm_dev
 		drm_connector_attach_property(&radeon_connector->base,
 					      rdev->mode_info.coherent_mode_property,
 					      1);
-		radeon_connector->dac_load_detect = true;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.load_detect_property,
-					      1);
+		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
+			radeon_connector->dac_load_detect = true;
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.load_detect_property,
+						      1);
+		}
 		break;
 	case DRM_MODE_CONNECTOR_HDMIA:
 	case DRM_MODE_CONNECTOR_HDMIB:
@@ -991,22 +1160,36 @@ radeon_add_atom_connector(struct drm_dev
 		subpixel_order = SubPixelHorizontalRGB;
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
+	case DRM_MODE_CONNECTOR_eDP:
 		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
 		if (!radeon_dig_connector)
 			goto failed;
 		radeon_dig_connector->linkb = linkb;
 		radeon_dig_connector->igp_lane_info = igp_lane_info;
 		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
-		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
+		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
 		if (ret)
 			goto failed;
 		if (i2c_bus->valid) {
-			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
+			/* add DP i2c bus */
+			if (connector_type == DRM_MODE_CONNECTOR_eDP)
+				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
+			else
+				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
+			if (!radeon_dig_connector->dp_i2c_bus)
+				goto failed;
+			if (connector_type == DRM_MODE_CONNECTOR_eDP)
+				radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "eDP");
+			else
+				radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
 		subpixel_order = SubPixelHorizontalRGB;
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.coherent_mode_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_SVIDEO:
 	case DRM_MODE_CONNECTOR_Composite:
@@ -1020,6 +1203,9 @@ radeon_add_atom_connector(struct drm_dev
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
 						      1);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.tv_std_property,
+						      radeon_atombios_get_tv_info(rdev));
 		}
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -1038,7 +1224,6 @@ radeon_add_atom_connector(struct drm_dev
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
-		drm_mode_create_scaling_mode_property(dev);
 		drm_connector_attach_property(&radeon_connector->base,
 					      dev->mode_config.scaling_mode_property,
 					      DRM_MODE_SCALE_FULLSCREEN);
@@ -1063,7 +1248,8 @@ radeon_add_legacy_connector(struct drm_d
 			    uint32_t supported_device,
 			    int connector_type,
 			    struct radeon_i2c_bus_rec *i2c_bus,
-			    uint16_t connector_object_id)
+			    uint16_t connector_object_id,
+			    struct radeon_hpd *hpd)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
@@ -1093,6 +1279,7 @@ radeon_add_legacy_connector(struct drm_d
 	radeon_connector->connector_id = connector_id;
 	radeon_connector->devices = supported_device;
 	radeon_connector->connector_object_id = connector_object_id;
+	radeon_connector->hpd = *hpd;
 	switch (connector_type) {
 	case DRM_MODE_CONNECTOR_VGA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1159,7 +1346,10 @@ radeon_add_legacy_connector(struct drm_d
 				radeon_connector->dac_load_detect = false;
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
-						      1);
+						      radeon_connector->dac_load_detect);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.tv_std_property,
+						      radeon_combios_get_tv_info(rdev));
 		}
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_cp.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cp.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 13:55:50.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 12:03:41.000000000 -0400
@@ -1935,8 +1935,8 @@ struct drm_buf *radeon_freelist_get(stru
 	for (t = 0; t < dev_priv->usec_timeout; t++) {
 		u32 done_age = GET_SCRATCH(dev_priv, 1);
 		DRM_DEBUG("done_age = %d\n", done_age);
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
+		for (i = 0; i < dma->buf_count; i++) {
+			buf = dma->buflist[start];
 			buf_priv = buf->dev_private;
 			if (buf->file_priv == NULL || (buf->pending &&
 						       buf_priv->age <=
@@ -1945,7 +1945,8 @@ struct drm_buf *radeon_freelist_get(stru
 				buf->pending = 0;
 				return buf;
 			}
-			start = 0;
+			if (++start >= dma->buf_count)
+				start = 0;
 		}
 
 		if (t) {
@@ -1954,46 +1955,8 @@ struct drm_buf *radeon_freelist_get(stru
 		}
 	}
 
-	DRM_DEBUG("returning NULL!\n");
-	return NULL;
-}
-
-#if 0
-struct drm_buf *radeon_freelist_get(struct drm_device * dev)
-{
-	struct drm_device_dma *dma = dev->dma;
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	drm_radeon_buf_priv_t *buf_priv;
-	struct drm_buf *buf;
-	int i, t;
-	int start;
-	u32 done_age;
-
-	done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
-	if (++dev_priv->last_buf >= dma->buf_count)
-		dev_priv->last_buf = 0;
-
-	start = dev_priv->last_buf;
-	dev_priv->stats.freelist_loops++;
-
-	for (t = 0; t < 2; t++) {
-		for (i = start; i < dma->buf_count; i++) {
-			buf = dma->buflist[i];
-			buf_priv = buf->dev_private;
-			if (buf->file_priv == 0 || (buf->pending &&
-						    buf_priv->age <=
-						    done_age)) {
-				dev_priv->stats.requested_bufs++;
-				buf->pending = 0;
-				return buf;
-			}
-		}
-		start = 0;
-	}
-
 	return NULL;
 }
-#endif
 
 void radeon_freelist_reset(struct drm_device * dev)
 {
@@ -2176,6 +2139,7 @@ int radeon_master_create(struct drm_devi
 			 &master_priv->sarea);
 	if (ret) {
 		DRM_ERROR("SAREA setup failed\n");
+		kfree(master_priv);
 		return ret;
 	}
 	master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_cs.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cs.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,17 +76,17 @@ int radeon_cs_parser_relocs(struct radeo
 			}
 			p->relocs_ptr[i] = &p->relocs[i];
 			p->relocs[i].robj = p->relocs[i].gobj->driver_private;
-			p->relocs[i].lobj.robj = p->relocs[i].robj;
+			p->relocs[i].lobj.bo = p->relocs[i].robj;
 			p->relocs[i].lobj.rdomain = r->read_domains;
 			p->relocs[i].lobj.wdomain = r->write_domain;
 			p->relocs[i].handle = r->handle;
 			p->relocs[i].flags = r->flags;
 			INIT_LIST_HEAD(&p->relocs[i].lobj.list);
-			radeon_object_list_add_object(&p->relocs[i].lobj,
-						      &p->validated);
+			radeon_bo_list_add_object(&p->relocs[i].lobj,
+						&p->validated);
 		}
 	}
-	return radeon_object_list_validate(&p->validated, p->ib->fence);
+	return radeon_bo_list_validate(&p->validated);
 }
 
 int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
@@ -189,11 +189,10 @@ static void radeon_cs_parser_fini(struct
 {
 	unsigned i;
 
-	if (error) {
-		radeon_object_list_unvalidate(&parser->validated);
-	} else {
-		radeon_object_list_clean(&parser->validated);
+	if (!error && parser->ib) {
+		radeon_bo_list_fence(&parser->validated, parser->ib->fence);
 	}
+	radeon_bo_list_unreserve(&parser->validated);
 	for (i = 0; i < parser->nrelocs; i++) {
 		if (parser->relocs[i].gobj) {
 			mutex_lock(&parser->rdev->ddev->struct_mutex);
@@ -230,6 +229,7 @@ int radeon_cs_ioctl(struct drm_device *d
 	memset(&parser, 0, sizeof(struct radeon_cs_parser));
 	parser.filp = filp;
 	parser.rdev = rdev;
+	parser.dev = rdev->dev;
 	r = radeon_cs_parser_init(&parser, data);
 	if (r) {
 		DRM_ERROR("Failed to initialize parser !\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_device.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_device.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,10 +44,11 @@ void radeon_surface_init(struct radeon_d
 	if (rdev->family < CHIP_R600) {
 		int i;
 
-		for (i = 0; i < 8; i++) {
-			WREG32(RADEON_SURFACE0_INFO +
-			       i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
-			       0);
+		for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
+			if (rdev->surface_regs[i].bo)
+				radeon_bo_get_surface_reg(rdev->surface_regs[i].bo);
+			else
+				radeon_clear_surface_reg(rdev, i);
 		}
 		/* enable surfaces */
 		WREG32(RADEON_SURFACE_CNTL, 0);
@@ -208,6 +209,24 @@ bool radeon_card_posted(struct radeon_de
 
 }
 
+bool radeon_boot_test_post_card(struct radeon_device *rdev)
+{
+	if (radeon_card_posted(rdev))
+		return true;
+
+	if (rdev->bios) {
+		DRM_INFO("GPU not posted. posting now...\n");
+		if (rdev->is_atom_bios)
+			atom_asic_init(rdev->mode_info.atom_context);
+		else
+			radeon_combios_asic_init(rdev->ddev);
+		return true;
+	} else {
+		dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+		return false;
+	}
+}
+
 int radeon_dummy_page_init(struct radeon_device *rdev)
 {
 	rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
@@ -372,6 +391,12 @@ int radeon_asic_init(struct radeon_devic
 		/* FIXME: not supported yet */
 		return -EINVAL;
 	}
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		rdev->asic->get_memory_clock = NULL;
+		rdev->asic->set_memory_clock = NULL;
+	}
+
 	return 0;
 }
 
@@ -462,13 +487,18 @@ int radeon_atombios_init(struct radeon_d
 	atom_card_info->pll_write = cail_pll_write;
 
 	rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
+	mutex_init(&rdev->mode_info.atom_context->mutex);
 	radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
+	atom_allocate_fb_scratch(rdev->mode_info.atom_context);
 	return 0;
 }
 
 void radeon_atombios_fini(struct radeon_device *rdev)
 {
-	kfree(rdev->mode_info.atom_context);
+	if (rdev->mode_info.atom_context) {
+		kfree(rdev->mode_info.atom_context->scratch);
+		kfree(rdev->mode_info.atom_context);
+	}
 	kfree(rdev->mode_info.atom_card_info);
 }
 
@@ -514,11 +544,75 @@ void radeon_agp_disable(struct radeon_de
 		rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
 		rdev->asic->gart_set_page = &r100_pci_gart_set_page;
 	}
+	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+}
+
+void radeon_check_arguments(struct radeon_device *rdev)
+{
+	/* vramlimit must be a power of two */
+	switch (radeon_vram_limit) {
+	case 0:
+	case 4:
+	case 8:
+	case 16:
+	case 32:
+	case 64:
+	case 128:
+	case 256:
+	case 512:
+	case 1024:
+	case 2048:
+	case 4096:
+		break;
+	default:
+		dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
+				radeon_vram_limit);
+		radeon_vram_limit = 0;
+		break;
+	}
+	radeon_vram_limit = radeon_vram_limit << 20;
+	/* gtt size must be power of two and greater or equal to 32M */
+	switch (radeon_gart_size) {
+	case 4:
+	case 8:
+	case 16:
+		dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n",
+				radeon_gart_size);
+		radeon_gart_size = 512;
+		break;
+	case 32:
+	case 64:
+	case 128:
+	case 256:
+	case 512:
+	case 1024:
+	case 2048:
+	case 4096:
+		break;
+	default:
+		dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
+				radeon_gart_size);
+		radeon_gart_size = 512;
+		break;
+	}
+	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+	/* AGP mode can only be -1, 1, 2, 4, 8 */
+	switch (radeon_agpmode) {
+	case -1:
+	case 0:
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		break;
+	default:
+		dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: "
+				"-1, 0, 1, 2, 4, 8)\n", radeon_agpmode);
+		radeon_agpmode = 0;
+		break;
+	}
 }
 
-/*
- * Radeon device.
- */
 int radeon_device_init(struct radeon_device *rdev,
 		       struct drm_device *ddev,
 		       struct pci_dev *pdev,
@@ -544,16 +638,24 @@ int radeon_device_init(struct radeon_dev
 	mutex_init(&rdev->cs_mutex);
 	mutex_init(&rdev->ib_pool.mutex);
 	mutex_init(&rdev->cp.mutex);
+	if (rdev->family >= CHIP_R600)
+		spin_lock_init(&rdev->ih.lock);
+	mutex_init(&rdev->gem.mutex);
 	rwlock_init(&rdev->fence_drv.lock);
 	INIT_LIST_HEAD(&rdev->gem.objects);
 
+	/* setup workqueue */
+	rdev->wq = create_workqueue("radeon");
+	if (rdev->wq == NULL)
+		return -ENOMEM;
+
 	/* Set asic functions */
 	r = radeon_asic_init(rdev);
-	if (r) {
+	if (r)
 		return r;
-	}
+	radeon_check_arguments(rdev);
 
-	if (radeon_agpmode == -1) {
+	if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
 		radeon_agp_disable(rdev);
 	}
 
@@ -620,6 +722,7 @@ void radeon_device_fini(struct radeon_de
 	DRM_INFO("radeon: finishing device.\n");
 	rdev->shutdown = true;
 	radeon_fini(rdev);
+	destroy_workqueue(rdev->wq);
 	vga_client_register(rdev->pdev, NULL, NULL, NULL);
 	iounmap(rdev->rmmio);
 	rdev->rmmio = NULL;
@@ -631,38 +734,46 @@ void radeon_device_fini(struct radeon_de
  */
 int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 {
-	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_device *rdev;
 	struct drm_crtc *crtc;
+	int r;
 
-	if (dev == NULL || rdev == NULL) {
+	if (dev == NULL || dev->dev_private == NULL) {
 		return -ENODEV;
 	}
 	if (state.event == PM_EVENT_PRETHAW) {
 		return 0;
 	}
+	rdev = dev->dev_private;
+
 	/* unpin the front buffers */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
-		struct radeon_object *robj;
+		struct radeon_bo *robj;
 
 		if (rfb == NULL || rfb->obj == NULL) {
 			continue;
 		}
 		robj = rfb->obj->driver_private;
-		if (robj != rdev->fbdev_robj) {
-			radeon_object_unpin(robj);
+		if (robj != rdev->fbdev_rbo) {
+			r = radeon_bo_reserve(robj, false);
+			if (unlikely(r == 0)) {
+				radeon_bo_unpin(robj);
+				radeon_bo_unreserve(robj);
+			}
 		}
 	}
 	/* evict vram memory */
-	radeon_object_evict_vram(rdev);
+	radeon_bo_evict_vram(rdev);
 	/* wait for gpu to finish processing current batch */
 	radeon_fence_wait_last(rdev);
 
 	radeon_save_bios_scratch_regs(rdev);
 
 	radeon_suspend(rdev);
+	radeon_hpd_fini(rdev);
 	/* evict remaining vram memory */
-	radeon_object_evict_vram(rdev);
+	radeon_bo_evict_vram(rdev);
 
 	pci_save_state(dev->pdev);
 	if (state.event == PM_EVENT_SUSPEND) {
@@ -695,6 +806,8 @@ int radeon_resume_kms(struct drm_device
 	fb_set_suspend(rdev->fbdev_info, 0);
 	release_console_sem();
 
+	/* reset hpd state */
+	radeon_hpd_init(rdev);
 	/* blat the mode back in */
 	drm_helper_resume_force_mode(dev);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_display.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_display.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_display.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -234,7 +234,7 @@ static const char *encoder_names[34] = {
 	"INTERNAL_UNIPHY2",
 };
 
-static const char *connector_names[13] = {
+static const char *connector_names[15] = {
 	"Unknown",
 	"VGA",
 	"DVI-I",
@@ -248,6 +248,18 @@ static const char *connector_names[13] =
 	"DisplayPort",
 	"HDMI-A",
 	"HDMI-B",
+	"TV",
+	"eDP",
+};
+
+static const char *hpd_names[7] = {
+	"NONE",
+	"HPD1",
+	"HPD2",
+	"HPD3",
+	"HPD4",
+	"HPD5",
+	"HPD6",
 };
 
 static void radeon_print_display_setup(struct drm_device *dev)
@@ -264,16 +276,27 @@ static void radeon_print_display_setup(s
 		radeon_connector = to_radeon_connector(connector);
 		DRM_INFO("Connector %d:\n", i);
 		DRM_INFO("  %s\n", connector_names[connector->connector_type]);
-		if (radeon_connector->ddc_bus)
+		if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
+			DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
+		if (radeon_connector->ddc_bus) {
 			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
 				 radeon_connector->ddc_bus->rec.mask_clk_reg,
 				 radeon_connector->ddc_bus->rec.mask_data_reg,
 				 radeon_connector->ddc_bus->rec.a_clk_reg,
 				 radeon_connector->ddc_bus->rec.a_data_reg,
-				 radeon_connector->ddc_bus->rec.put_clk_reg,
-				 radeon_connector->ddc_bus->rec.put_data_reg,
-				 radeon_connector->ddc_bus->rec.get_clk_reg,
-				 radeon_connector->ddc_bus->rec.get_data_reg);
+				 radeon_connector->ddc_bus->rec.en_clk_reg,
+				 radeon_connector->ddc_bus->rec.en_data_reg,
+				 radeon_connector->ddc_bus->rec.y_clk_reg,
+				 radeon_connector->ddc_bus->rec.y_data_reg);
+		} else {
+			if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
+			    connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
+			    connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
+			    connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
+			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
+				DRM_INFO("  DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
+		}
 		DRM_INFO("  Encoders:\n");
 		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 			radeon_encoder = to_radeon_encoder(encoder);
@@ -317,13 +340,17 @@ static bool radeon_setup_enc_conn(struct
 				ret = radeon_get_atom_connector_info_from_object_table(dev);
 			else
 				ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
-		} else
+		} else {
 			ret = radeon_get_legacy_connector_info_from_bios(dev);
+			if (ret == false)
+				ret = radeon_get_legacy_connector_info_from_table(dev);
+		}
 	} else {
 		if (!ASIC_IS_AVIVO(rdev))
 			ret = radeon_get_legacy_connector_info_from_table(dev);
 	}
 	if (ret) {
+		radeon_setup_encoder_clones(dev);
 		radeon_print_display_setup(dev);
 		list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
 			radeon_ddc_dump(drm_connector);
@@ -336,12 +363,19 @@ int radeon_ddc_get_modes(struct radeon_c
 {
 	int ret = 0;
 
+	if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+	    (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
+		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
+		     dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
+			radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
+	}
 	if (!radeon_connector->ddc_bus)
 		return -1;
 	if (!radeon_connector->edid) {
-		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-		radeon_i2c_do_lock(radeon_connector, 0);
+		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	}
 
 	if (radeon_connector->edid) {
@@ -361,9 +395,9 @@ static int radeon_ddc_dump(struct drm_co
 
 	if (!radeon_connector->ddc_bus)
 		return -1;
-	radeon_i2c_do_lock(radeon_connector, 1);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
 	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
 	if (edid) {
 		kfree(edid);
 	}
@@ -386,11 +420,12 @@ void radeon_compute_pll(struct radeon_pl
 			uint32_t *fb_div_p,
 			uint32_t *frac_fb_div_p,
 			uint32_t *ref_div_p,
-			uint32_t *post_div_p,
-			int flags)
+			uint32_t *post_div_p)
 {
 	uint32_t min_ref_div = pll->min_ref_div;
 	uint32_t max_ref_div = pll->max_ref_div;
+	uint32_t min_post_div = pll->min_post_div;
+	uint32_t max_post_div = pll->max_post_div;
 	uint32_t min_fractional_feed_div = 0;
 	uint32_t max_fractional_feed_div = 0;
 	uint32_t best_vco = pll->best_vco;
@@ -406,7 +441,7 @@ void radeon_compute_pll(struct radeon_pl
 	DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
 	freq = freq * 1000;
 
-	if (flags & RADEON_PLL_USE_REF_DIV)
+	if (pll->flags & RADEON_PLL_USE_REF_DIV)
 		min_ref_div = max_ref_div = pll->reference_div;
 	else {
 		while (min_ref_div < max_ref_div-1) {
@@ -421,19 +456,22 @@ void radeon_compute_pll(struct radeon_pl
 		}
 	}
 
-	if (flags & RADEON_PLL_USE_FRAC_FB_DIV) {
+	if (pll->flags & RADEON_PLL_USE_POST_DIV)
+		min_post_div = max_post_div = pll->post_div;
+
+	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
 		min_fractional_feed_div = pll->min_frac_feedback_div;
 		max_fractional_feed_div = pll->max_frac_feedback_div;
 	}
 
-	for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
+	for (post_div = min_post_div; post_div <= max_post_div; ++post_div) {
 		uint32_t ref_div;
 
-		if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
+		if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
 			continue;
 
 		/* legacy radeons only have a few post_divs */
-		if (flags & RADEON_PLL_LEGACY) {
+		if (pll->flags & RADEON_PLL_LEGACY) {
 			if ((post_div == 5) ||
 			    (post_div == 7) ||
 			    (post_div == 9) ||
@@ -480,7 +518,7 @@ void radeon_compute_pll(struct radeon_pl
 					tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
 					current_freq = radeon_div(tmp, ref_div * post_div);
 
-					if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
+					if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
 						error = freq - current_freq;
 						error = error < 0 ? 0xffffffff : error;
 					} else
@@ -507,12 +545,12 @@ void radeon_compute_pll(struct radeon_pl
 							best_freq = current_freq;
 							best_error = error;
 							best_vco_diff = vco_diff;
-						} else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
-							   ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
-							   ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
-							   ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
-							   ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
-							   ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
+						} else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
+							   ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
+							   ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
+							   ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
+							   ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
+							   ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
 							best_post_div = post_div;
 							best_ref_div = ref_div;
 							best_feedback_div = feedback_div;
@@ -542,6 +580,97 @@ void radeon_compute_pll(struct radeon_pl
 	*post_div_p = best_post_div;
 }
 
+void radeon_compute_pll_avivo(struct radeon_pll *pll,
+			      uint64_t freq,
+			      uint32_t *dot_clock_p,
+			      uint32_t *fb_div_p,
+			      uint32_t *frac_fb_div_p,
+			      uint32_t *ref_div_p,
+			      uint32_t *post_div_p)
+{
+	fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
+	fixed20_12 pll_out_max, pll_out_min;
+	fixed20_12 pll_in_max, pll_in_min;
+	fixed20_12 reference_freq;
+	fixed20_12 error, ffreq, a, b;
+
+	pll_out_max.full = rfixed_const(pll->pll_out_max);
+	pll_out_min.full = rfixed_const(pll->pll_out_min);
+	pll_in_max.full = rfixed_const(pll->pll_in_max);
+	pll_in_min.full = rfixed_const(pll->pll_in_min);
+	reference_freq.full = rfixed_const(pll->reference_freq);
+	do_div(freq, 10);
+	ffreq.full = rfixed_const(freq);
+	error.full = rfixed_const(100 * 100);
+
+	/* max p */
+	p.full = rfixed_div(pll_out_max, ffreq);
+	p.full = rfixed_floor(p);
+
+	/* min m */
+	m.full = rfixed_div(reference_freq, pll_in_max);
+	m.full = rfixed_ceil(m);
+
+	while (1) {
+		n.full = rfixed_div(ffreq, reference_freq);
+		n.full = rfixed_mul(n, m);
+		n.full = rfixed_mul(n, p);
+
+		f_vco.full = rfixed_div(n, m);
+		f_vco.full = rfixed_mul(f_vco, reference_freq);
+
+		f_pclk.full = rfixed_div(f_vco, p);
+
+		if (f_pclk.full > ffreq.full)
+			error.full = f_pclk.full - ffreq.full;
+		else
+			error.full = ffreq.full - f_pclk.full;
+		error.full = rfixed_div(error, f_pclk);
+		a.full = rfixed_const(100 * 100);
+		error.full = rfixed_mul(error, a);
+
+		a.full = rfixed_mul(m, p);
+		a.full = rfixed_div(n, a);
+		best_freq.full = rfixed_mul(reference_freq, a);
+
+		if (rfixed_trunc(error) < 25)
+			break;
+
+		a.full = rfixed_const(1);
+		m.full = m.full + a.full;
+		a.full = rfixed_div(reference_freq, m);
+		if (a.full >= pll_in_min.full)
+			continue;
+
+		m.full = rfixed_div(reference_freq, pll_in_max);
+		m.full = rfixed_ceil(m);
+		a.full= rfixed_const(1);
+		p.full = p.full - a.full;
+		a.full = rfixed_mul(p, ffreq);
+		if (a.full >= pll_out_min.full)
+			continue;
+		else {
+			DRM_ERROR("Unable to find pll dividers\n");
+			break;
+		}
+	}
+
+	a.full = rfixed_const(10);
+	b.full = rfixed_mul(n, a);
+
+	frac_n.full = rfixed_floor(n);
+	frac_n.full = rfixed_mul(frac_n, a);
+	frac_n.full = b.full - frac_n.full;
+
+	*dot_clock_p = rfixed_trunc(best_freq);
+	*fb_div_p = rfixed_trunc(n);
+	*frac_fb_div_p = rfixed_trunc(frac_n);
+	*ref_div_p = rfixed_trunc(m);
+	*post_div_p = rfixed_trunc(p);
+
+	DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
+}
+
 static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
 	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
@@ -551,7 +680,6 @@ static void radeon_user_framebuffer_dest
 		radeonfb_remove(dev, fb);
 
 	if (radeon_fb->obj) {
-		radeon_gem_object_unpin(radeon_fb->obj);
 		mutex_lock(&dev->struct_mutex);
 		drm_gem_object_unreference(radeon_fb->obj);
 		mutex_unlock(&dev->struct_mutex);
@@ -599,7 +727,11 @@ radeon_user_framebuffer_create(struct dr
 	struct drm_gem_object *obj;
 
 	obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
-
+	if (obj ==  NULL) {
+		dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, "
+			"can't create framebuffer\n", mode_cmd->handle);
+		return NULL;
+	}
 	return radeon_framebuffer_create(dev, mode_cmd, obj);
 }
 
@@ -629,7 +761,7 @@ static struct drm_prop_enum_list radeon_
 	{ TV_STD_SECAM, "secam" },
 };
 
-int radeon_modeset_create_props(struct radeon_device *rdev)
+static int radeon_modeset_create_props(struct radeon_device *rdev)
 {
 	int i, sz;
 
@@ -642,7 +774,7 @@ int radeon_modeset_create_props(struct r
 			return -ENOMEM;
 
 		rdev->mode_info.coherent_mode_property->values[0] = 0;
-		rdev->mode_info.coherent_mode_property->values[0] = 1;
+		rdev->mode_info.coherent_mode_property->values[1] = 1;
 	}
 
 	if (!ASIC_IS_AVIVO(rdev)) {
@@ -666,7 +798,7 @@ int radeon_modeset_create_props(struct r
 	if (!rdev->mode_info.load_detect_property)
 		return -ENOMEM;
 	rdev->mode_info.load_detect_property->values[0] = 0;
-	rdev->mode_info.load_detect_property->values[0] = 1;
+	rdev->mode_info.load_detect_property->values[1] = 1;
 
 	drm_mode_create_scaling_mode_property(rdev->ddev);
 
@@ -723,6 +855,8 @@ int radeon_modeset_init(struct radeon_de
 	if (!ret) {
 		return ret;
 	}
+	/* initialize hpd */
+	radeon_hpd_init(rdev);
 	drm_helper_initial_config(rdev->ddev);
 	return 0;
 }
@@ -730,6 +864,7 @@ int radeon_modeset_init(struct radeon_de
 void radeon_modeset_fini(struct radeon_device *rdev)
 {
 	if (rdev->mode_info.mode_config_initialized) {
+		radeon_hpd_fini(rdev);
 		drm_mode_config_cleanup(rdev->ddev);
 		rdev->mode_info.mode_config_initialized = false;
 	}
@@ -750,9 +885,17 @@ bool radeon_crtc_scaling_mode_fixup(stru
 		if (encoder->crtc != crtc)
 			continue;
 		if (first) {
-			radeon_crtc->rmx_type = radeon_encoder->rmx_type;
+			/* set scaling */
+			if (radeon_encoder->rmx_type == RMX_OFF)
+				radeon_crtc->rmx_type = RMX_OFF;
+			else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
+				 mode->vdisplay < radeon_encoder->native_mode.vdisplay)
+				radeon_crtc->rmx_type = radeon_encoder->rmx_type;
+			else
+				radeon_crtc->rmx_type = RMX_OFF;
+			/* copy native mode */
 			memcpy(&radeon_crtc->native_mode,
-				&radeon_encoder->native_mode,
+			       &radeon_encoder->native_mode,
 				sizeof(struct drm_display_mode));
 			first = false;
 		} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,6 +86,8 @@ int radeon_benchmarking = 0;
 int radeon_testing = 0;
 int radeon_connector_table = 0;
 int radeon_tv = 1;
+int radeon_new_pll = 1;
+int radeon_audio = 1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -120,6 +122,12 @@ module_param_named(connector_table, rade
 MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
 module_param_named(tv, radeon_tv, int, 0444);
 
+MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
+module_param_named(new_pll, radeon_new_pll, int, 0444);
+
+MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
+module_param_named(audio, radeon_audio, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -188,7 +196,7 @@ static struct drm_driver driver_old = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
@@ -276,7 +284,7 @@ static struct drm_driver kms_driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = radeon_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_drv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,9 +106,10 @@
  * 1.29- R500 3D cmd buffer support
  * 1.30- Add support for occlusion queries
  * 1.31- Add support for num Z pipes from GET_PARAM
+ * 1.32- fixes for rv740 setup
  */
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		31
+#define DRIVER_MINOR		32
 #define DRIVER_PATCHLEVEL	0
 
 enum radeon_cp_microcode_version {
@@ -1104,7 +1105,6 @@ extern u32 radeon_get_scratch(drm_radeon
 #       define R600_IT_WAIT_REG_MEM             0x00003C00
 #       define R600_IT_MEM_WRITE                0x00003D00
 #       define R600_IT_INDIRECT_BUFFER          0x00003200
-#       define R600_IT_CP_INTERRUPT             0x00004000
 #       define R600_IT_SURFACE_SYNC             0x00004300
 #              define R600_CB0_DEST_BASE_ENA    (1 << 6)
 #              define R600_TC_ACTION_ENA        (1 << 23)
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_encoders.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,51 @@ extern int atom_debug;
 bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
 				struct drm_display_mode *mode);
 
+static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_encoder *clone_encoder;
+	uint32_t index_mask = 0;
+	int count;
+
+	/* DIG routing gets problematic */
+	if (rdev->family >= CHIP_R600)
+		return index_mask;
+	/* LVDS/TV are too wacky */
+	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
+		return index_mask;
+	/* DVO requires 2x ppll clocks depending on tmds chip */
+	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		return index_mask;
+	
+	count = -1;
+	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
+		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
+		count++;
+
+		if (clone_encoder == encoder)
+			continue;
+		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
+			continue;
+		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
+			continue;
+		else
+			index_mask |= (1 << count);
+	}
+	return index_mask;
+}
+
+void radeon_setup_encoder_clones(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		encoder->possible_clones = radeon_encoder_clones(encoder);
+	}
+}
+
 uint32_t
 radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
 {
@@ -111,6 +156,26 @@ radeon_get_encoder_id(struct drm_device
 	return ret;
 }
 
+static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+	case ENCODER_OBJECT_ID_INTERNAL_DDI:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		return true;
+	default:
+		return false;
+	}
+}
 void
 radeon_link_encoder_connector(struct drm_device *dev)
 {
@@ -157,35 +222,12 @@ radeon_get_connector_for_encoder(struct
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		radeon_connector = to_radeon_connector(connector);
-		if (radeon_encoder->devices & radeon_connector->devices)
+		if (radeon_encoder->active_device & radeon_connector->devices)
 			return connector;
 	}
 	return NULL;
 }
 
-/* used for both atom and legacy */
-void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
-			   struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode)
-{
-	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	struct drm_device *dev = encoder->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-
-	if (mode->hdisplay < native_mode->hdisplay ||
-	    mode->vdisplay < native_mode->vdisplay) {
-		int mode_id = adjusted_mode->base.id;
-		*adjusted_mode = *native_mode;
-		if (!ASIC_IS_AVIVO(rdev)) {
-			adjusted_mode->hdisplay = mode->hdisplay;
-			adjusted_mode->vdisplay = mode->vdisplay;
-		}
-		adjusted_mode->base.id = mode_id;
-	}
-}
-
-
 static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
 				   struct drm_display_mode *mode,
 				   struct drm_display_mode *adjusted_mode)
@@ -198,14 +240,26 @@ static bool radeon_atom_mode_fixup(struc
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	if (radeon_encoder->rmx_type != RMX_OFF)
-		radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
-
 	/* hw bug */
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
 	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
 		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
+	/* get the native mode for LVDS */
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+		int mode_id = adjusted_mode->base.id;
+		*adjusted_mode = *native_mode;
+		if (!ASIC_IS_AVIVO(rdev)) {
+			adjusted_mode->hdisplay = mode->hdisplay;
+			adjusted_mode->vdisplay = mode->vdisplay;
+			adjusted_mode->crtc_hdisplay = mode->hdisplay;
+			adjusted_mode->crtc_vdisplay = mode->vdisplay;
+		}
+		adjusted_mode->base.id = mode_id;
+	}
+
+	/* get the native mode for TV */
 	if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
 		if (tv_dac) {
@@ -218,6 +272,12 @@ static bool radeon_atom_mode_fixup(struc
 		}
 	}
 
+	if (ASIC_IS_DCE3(rdev) &&
+	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+		radeon_dp_set_link_config(connector, mode);
+	}
+
 	return true;
 }
 
@@ -392,7 +452,7 @@ union lvds_encoder_control {
 	LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
 };
 
-static void
+void
 atombios_digital_setup(struct drm_encoder *encoder, int action)
 {
 	struct drm_device *dev = encoder->dev;
@@ -400,6 +460,7 @@ atombios_digital_setup(struct drm_encode
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	union lvds_encoder_control args;
 	int index = 0;
+	int hdmi_detected = 0;
 	uint8_t frev, crev;
 	struct radeon_encoder_atom_dig *dig;
 	struct drm_connector *connector;
@@ -420,6 +481,9 @@ atombios_digital_setup(struct drm_encode
 	if (!radeon_connector->con_priv)
 		return;
 
+	if (drm_detect_hdmi_monitor(radeon_connector->edid))
+		hdmi_detected = 1;
+
 	dig_connector = radeon_connector->con_priv;
 
 	memset(&args, 0, sizeof(args));
@@ -449,13 +513,13 @@ atombios_digital_setup(struct drm_encode
 		case 1:
 			args.v1.ucMisc = 0;
 			args.v1.ucAction = action;
-			if (drm_detect_hdmi_monitor(radeon_connector->edid))
+			if (hdmi_detected)
 				args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 			args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-				if (dig->lvds_misc & (1 << 0))
+				if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
 					args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-				if (dig->lvds_misc & (1 << 1))
+				if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
 					args.v1.ucMisc |= (1 << 1);
 			} else {
 				if (dig_connector->linkb)
@@ -474,7 +538,7 @@ atombios_digital_setup(struct drm_encode
 				if (dig->coherent_mode)
 					args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
 			}
-			if (drm_detect_hdmi_monitor(radeon_connector->edid))
+			if (hdmi_detected)
 				args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 			args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 			args.v2.ucTruncate = 0;
@@ -482,18 +546,18 @@ atombios_digital_setup(struct drm_encode
 			args.v2.ucTemporal = 0;
 			args.v2.ucFRC = 0;
 			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-				if (dig->lvds_misc & (1 << 0))
+				if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
 					args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-				if (dig->lvds_misc & (1 << 5)) {
+				if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) {
 					args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
-					if (dig->lvds_misc & (1 << 1))
+					if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
 						args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
 				}
-				if (dig->lvds_misc & (1 << 6)) {
+				if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) {
 					args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
-					if (dig->lvds_misc & (1 << 1))
+					if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
 						args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
-					if (((dig->lvds_misc >> 2) & 0x3) == 2)
+					if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)
 						args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
 				}
 			} else {
@@ -514,7 +578,7 @@ atombios_digital_setup(struct drm_encode
 	}
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
+	r600_hdmi_enable(encoder, hdmi_detected);
 }
 
 int
@@ -522,6 +586,7 @@ atombios_get_encoder_mode(struct drm_enc
 {
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *radeon_dig_connector;
 
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector)
@@ -551,21 +616,23 @@ atombios_get_encoder_mode(struct drm_enc
 		return ATOM_ENCODER_MODE_LVDS;
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
-		/*if (radeon_output->MonType == MT_DP)
-		  return ATOM_ENCODER_MODE_DP;
-		  else*/
-		if (drm_detect_hdmi_monitor(radeon_connector->edid))
+	case DRM_MODE_CONNECTOR_eDP:
+		radeon_dig_connector = radeon_connector->con_priv;
+		if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+		    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+			return ATOM_ENCODER_MODE_DP;
+		else if (drm_detect_hdmi_monitor(radeon_connector->edid))
 			return ATOM_ENCODER_MODE_HDMI;
 		else
 			return ATOM_ENCODER_MODE_DVI;
 		break;
-	case CONNECTOR_DVI_A:
-	case CONNECTOR_VGA:
+	case DRM_MODE_CONNECTOR_DVIA:
+	case DRM_MODE_CONNECTOR_VGA:
 		return ATOM_ENCODER_MODE_CRT;
 		break;
-	case CONNECTOR_STV:
-	case CONNECTOR_CTV:
-	case CONNECTOR_DIN:
+	case DRM_MODE_CONNECTOR_Composite:
+	case DRM_MODE_CONNECTOR_SVIDEO:
+	case DRM_MODE_CONNECTOR_9PinDIN:
 		/* fix me */
 		return ATOM_ENCODER_MODE_TV;
 		/*return ATOM_ENCODER_MODE_CV;*/
@@ -573,6 +640,30 @@ atombios_get_encoder_mode(struct drm_enc
 	}
 }
 
+/*
+ * DIG Encoder/Transmitter Setup
+ *
+ * DCE 3.0/3.1
+ * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
+ * Supports up to 3 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1 can drive UNIPHY link A or link B
+ * DIG2 can drive UNIPHY link B or LVTMA
+ *
+ * DCE 3.2
+ * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
+ * Supports up to 5 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1/2 can drive UNIPHY0/1/2 link A or link B
+ *
+ * Routing
+ * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
+ * Examples:
+ * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI
+ * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP
+ * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
+ * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
+ */
 static void
 atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
 {
@@ -605,24 +696,11 @@ atombios_dig_encoder_setup(struct drm_en
 
 	memset(&args, 0, sizeof(args));
 
-	if (ASIC_IS_DCE32(rdev)) {
-		if (dig->dig_block)
-			index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-		else
-			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
-		num = dig->dig_block + 1;
-	} else {
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
-			num = 1;
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-			index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-			num = 2;
-			break;
-		}
-	}
+	if (dig->dig_encoder)
+		index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	else
+		index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	num = dig->dig_encoder + 1;
 
 	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
 
@@ -652,18 +730,21 @@ atombios_dig_encoder_setup(struct drm_en
 		}
 	}
 
-	if (radeon_encoder->pixel_clock > 165000) {
-		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
+	args.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+	if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+		if (dig_connector->dp_clock == 270000)
+			args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+		args.ucLaneNum = dig_connector->dp_lane_count;
+	} else if (radeon_encoder->pixel_clock > 165000)
 		args.ucLaneNum = 8;
-	} else {
-		if (dig_connector->linkb)
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
-		else
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+	else
 		args.ucLaneNum = 4;
-	}
 
-	args.ucEncoderMode = atombios_get_encoder_mode(encoder);
+	if (dig_connector->linkb)
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+	else
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
@@ -674,8 +755,8 @@ union dig_transmitter_control {
 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
 };
 
-static void
-atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
+void
+atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -687,6 +768,7 @@ atombios_dig_transmitter_setup(struct dr
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *dig_connector;
+	bool is_dp = false;
 
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector)
@@ -704,6 +786,9 @@ atombios_dig_transmitter_setup(struct dr
 
 	dig_connector = radeon_connector->con_priv;
 
+	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
+		is_dp = true;
+
 	memset(&args, 0, sizeof(args));
 
 	if (ASIC_IS_DCE32(rdev))
@@ -724,17 +809,23 @@ atombios_dig_transmitter_setup(struct dr
 	args.v1.ucAction = action;
 	if (action == ATOM_TRANSMITTER_ACTION_INIT) {
 		args.v1.usInitInfo = radeon_connector->connector_object_id;
+	} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+		args.v1.asMode.ucLaneSel = lane_num;
+		args.v1.asMode.ucLaneSet = lane_set;
 	} else {
-		if (radeon_encoder->pixel_clock > 165000)
+		if (is_dp)
+			args.v1.usPixelClock =
+				cpu_to_le16(dig_connector->dp_clock / 10);
+		else if (radeon_encoder->pixel_clock > 165000)
 			args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
 		else
 			args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 	}
 	if (ASIC_IS_DCE32(rdev)) {
-		if (radeon_encoder->pixel_clock > 165000)
-			args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
-		if (dig->dig_block)
+		if (dig->dig_encoder == 1)
 			args.v2.acConfig.ucEncoderSel = 1;
+		if (dig_connector->linkb)
+			args.v2.acConfig.ucLinkSel = 1;
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -751,26 +842,30 @@ atombios_dig_transmitter_setup(struct dr
 			break;
 		}
 
-		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+		if (is_dp)
+			args.v2.acConfig.fCoherentMode = 1;
+		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v2.acConfig.fCoherentMode = 1;
 		}
 	} else {
+
 		args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 
+		if (dig->dig_encoder)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+		else
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 			if (rdev->flags & RADEON_IS_IGP) {
 				if (radeon_encoder->pixel_clock > 165000) {
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B);
 					if (dig_connector->igp_lane_info & 0x3)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
 					else if (dig_connector->igp_lane_info & 0xc)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
 				} else {
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
 					if (dig_connector->igp_lane_info & 0x1)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
 					else if (dig_connector->igp_lane_info & 0x2)
@@ -780,42 +875,27 @@ atombios_dig_transmitter_setup(struct dr
 					else if (dig_connector->igp_lane_info & 0x8)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
 				}
-			} else {
-				if (radeon_encoder->pixel_clock > 165000)
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-							     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-				else {
-					if (dig_connector->linkb)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-					else
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				}
-			}
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-			if (radeon_encoder->pixel_clock > 165000)
-				args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-						     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-						     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-			else {
-				if (dig_connector->linkb)
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				else
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
 			}
 			break;
 		}
 
-		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+		if (radeon_encoder->pixel_clock > 165000)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
+
+		if (dig_connector->linkb)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
+		else
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+
+		if (is_dp)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
 		}
 	}
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 }
 
 static void
@@ -918,12 +998,16 @@ radeon_atom_encoder_dpms(struct drm_enco
 	if (is_dig) {
 		switch (mode) {
 		case DRM_MODE_DPMS_ON:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+			{
+				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+				dp_link_train(encoder, connector);
+			}
 			break;
 		case DRM_MODE_DPMS_STANDBY:
 		case DRM_MODE_DPMS_SUSPEND:
 		case DRM_MODE_DPMS_OFF:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
 			break;
 		}
 	} else {
@@ -957,6 +1041,7 @@ atombios_set_encoder_crtc_source(struct
 	union crtc_sourc_param args;
 	int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
 	uint8_t frev, crev;
+	struct radeon_encoder_atom_dig *dig;
 
 	memset(&args, 0, sizeof(args));
 
@@ -1020,20 +1105,16 @@ atombios_set_encoder_crtc_source(struct
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-				if (ASIC_IS_DCE32(rdev)) {
-					if (radeon_crtc->crtc_id)
-						args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-					else
-						args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-				} else
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+				dig = radeon_encoder->enc_priv;
+				if (dig->dig_encoder)
+					args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+				else
 					args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 				args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
 				break;
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-				args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
 				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
@@ -1060,7 +1141,6 @@ atombios_set_encoder_crtc_source(struct
 	}
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 }
 
 static void
@@ -1094,6 +1174,47 @@ atombios_apply_encoder_quirks(struct drm
 	}
 }
 
+static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_encoder *test_encoder;
+	struct radeon_encoder_atom_dig *dig;
+	uint32_t dig_enc_in_use = 0;
+	/* on DCE32 and encoder can driver any block so just crtc id */
+	if (ASIC_IS_DCE32(rdev)) {
+		return radeon_crtc->crtc_id;
+	}
+
+	/* on DCE3 - LVTMA can only be driven by DIGB */
+	list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
+		struct radeon_encoder *radeon_test_encoder;
+
+		if (encoder == test_encoder)
+			continue;
+
+		if (!radeon_encoder_is_digital(test_encoder))
+			continue;
+
+		radeon_test_encoder = to_radeon_encoder(test_encoder);
+		dig = radeon_test_encoder->enc_priv;
+
+		if (dig->dig_encoder >= 0)
+			dig_enc_in_use |= (1 << dig->dig_encoder);
+	}
+
+	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {
+		if (dig_enc_in_use & 0x2)
+			DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");
+		return 1;
+	}
+	if (!(dig_enc_in_use & 1))
+		return 0;
+	return 1;
+}
+
 static void
 radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 			     struct drm_display_mode *mode,
@@ -1104,11 +1225,11 @@ radeon_atom_encoder_mode_set(struct drm_
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
-	if (radeon_encoder->enc_priv) {
-		struct radeon_encoder_atom_dig *dig;
-
-		dig = radeon_encoder->enc_priv;
-		dig->dig_block = radeon_crtc->crtc_id;
+	if (radeon_encoder->active_device &
+	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+		if (dig)
+			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
 	}
 	radeon_encoder->pixel_clock = adjusted_mode->clock;
 
@@ -1134,14 +1255,14 @@ radeon_atom_encoder_mode_set(struct drm_
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		/* disable the encoder and transmitter */
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
 		atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
 
 		/* setup and enable the encoder and transmitter */
 		atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
 		atombios_ddia_setup(encoder, ATOM_ENABLE);
@@ -1160,6 +1281,8 @@ radeon_atom_encoder_mode_set(struct drm_
 		break;
 	}
 	atombios_apply_encoder_quirks(encoder, adjusted_mode);
+
+	r600_hdmi_setmode(encoder, adjusted_mode);
 }
 
 static bool
@@ -1266,7 +1389,13 @@ static void radeon_atom_encoder_commit(s
 static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig;
 	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	if (radeon_encoder_is_digital(encoder)) {
+		dig = radeon_encoder->enc_priv;
+		dig->dig_encoder = -1;
+	}
 	radeon_encoder->active_device = 0;
 }
 
@@ -1323,6 +1452,7 @@ radeon_atombios_set_dig_info(struct rade
 
 	/* coherent mode by default */
 	dig->coherent_mode = true;
+	dig->dig_encoder = -1;
 
 	return dig;
 }
@@ -1354,7 +1484,6 @@ radeon_add_atom_encoder(struct drm_devic
 		encoder->possible_crtcs = 0x1;
 	else
 		encoder->possible_crtcs = 0x3;
-	encoder->possible_clones = 0;
 
 	radeon_encoder->enc_priv = NULL;
 
@@ -1406,4 +1535,6 @@ radeon_add_atom_encoder(struct drm_devic
 		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
 		break;
 	}
+
+	r600_hdmi_init(encoder);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@ static struct fb_ops radeonfb_ops = {
 };
 
 /**
- * Curretly it is assumed that the old framebuffer is reused.
+ * Currently it is assumed that the old framebuffer is reused.
  *
  * LOCKING
  * caller should hold the mode config lock.
@@ -140,7 +140,7 @@ int radeonfb_create(struct drm_device *d
 	struct radeon_framebuffer *rfb;
 	struct drm_mode_fb_cmd mode_cmd;
 	struct drm_gem_object *gobj = NULL;
-	struct radeon_object *robj = NULL;
+	struct radeon_bo *rbo = NULL;
 	struct device *device = &rdev->pdev->dev;
 	int size, aligned_size, ret;
 	u64 fb_gpuaddr;
@@ -168,14 +168,14 @@ int radeonfb_create(struct drm_device *d
 	ret = radeon_gem_object_create(rdev, aligned_size, 0,
 			RADEON_GEM_DOMAIN_VRAM,
 			false, ttm_bo_type_kernel,
-			false, &gobj);
+			&gobj);
 	if (ret) {
 		printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
 		       surface_width, surface_height);
 		ret = -ENOMEM;
 		goto out;
 	}
-	robj = gobj->driver_private;
+	rbo = gobj->driver_private;
 
 	if (fb_tiled)
 		tiling_flags = RADEON_TILING_MACRO;
@@ -192,8 +192,13 @@ int radeonfb_create(struct drm_device *d
 	}
 #endif
 
-	if (tiling_flags)
-		radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
+	if (tiling_flags) {
+		ret = radeon_bo_set_tiling_flags(rbo,
+					tiling_flags | RADEON_TILING_SURFACE,
+					mode_cmd.pitch);
+		if (ret)
+			dev_err(rdev->dev, "FB failed to set tiling flags\n");
+	}
 	mutex_lock(&rdev->ddev->struct_mutex);
 	fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
 	if (fb == NULL) {
@@ -201,10 +206,19 @@ int radeonfb_create(struct drm_device *d
 		ret = -ENOMEM;
 		goto out_unref;
 	}
-	ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
+	ret = radeon_bo_reserve(rbo, false);
+	if (unlikely(ret != 0))
+		goto out_unref;
+	ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
+	if (ret) {
+		radeon_bo_unreserve(rbo);
+		goto out_unref;
+	}
+	if (fb_tiled)
+		radeon_bo_check_tiling(rbo, 0, 0);
+	ret = radeon_bo_kmap(rbo, &fbptr);
+	radeon_bo_unreserve(rbo);
 	if (ret) {
-		printk(KERN_ERR "failed to pin framebuffer\n");
-		ret = -ENOMEM;
 		goto out_unref;
 	}
 
@@ -213,7 +227,7 @@ int radeonfb_create(struct drm_device *d
 	*fb_p = fb;
 	rfb = to_radeon_framebuffer(fb);
 	rdev->fbdev_rfb = rfb;
-	rdev->fbdev_robj = robj;
+	rdev->fbdev_rbo = rbo;
 
 	info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
 	if (info == NULL) {
@@ -234,15 +248,7 @@ int radeonfb_create(struct drm_device *d
 	if (ret)
 		goto out_unref;
 
-	if (fb_tiled)
-		radeon_object_check_tiling(robj, 0, 0);
-
-	ret = radeon_object_kmap(robj, &fbptr);
-	if (ret) {
-		goto out_unref;
-	}
-
-	memset_io(fbptr, 0, aligned_size);
+	memset_io(fbptr, 0x0, aligned_size);
 
 	strcpy(info->fix.id, "radeondrmfb");
 
@@ -288,8 +294,12 @@ int radeonfb_create(struct drm_device *d
 	return 0;
 
 out_unref:
-	if (robj) {
-		radeon_object_kunmap(robj);
+	if (rbo) {
+		ret = radeon_bo_reserve(rbo, false);
+		if (likely(ret == 0)) {
+			radeon_bo_kunmap(rbo);
+			radeon_bo_unreserve(rbo);
+		}
 	}
 	if (fb && ret) {
 		list_del(&fb->filp_head);
@@ -321,14 +331,22 @@ int radeon_parse_options(char *options)
 
 int radeonfb_probe(struct drm_device *dev)
 {
-	return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create);
+	struct radeon_device *rdev = dev->dev_private;
+	int bpp_sel = 32;
+
+	/* select 8 bpp console on RN50 or 16MB cards */
+	if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
+		bpp_sel = 8;
+
+	return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create);
 }
 
 int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
 {
 	struct fb_info *info;
 	struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
-	struct radeon_object *robj;
+	struct radeon_bo *rbo;
+	int r;
 
 	if (!fb) {
 		return -EINVAL;
@@ -336,10 +354,14 @@ int radeonfb_remove(struct drm_device *d
 	info = fb->fbdev;
 	if (info) {
 		struct radeon_fb_device *rfbdev = info->par;
-		robj = rfb->obj->driver_private;
+		rbo = rfb->obj->driver_private;
 		unregister_framebuffer(info);
-		radeon_object_kunmap(robj);
-		radeon_object_unpin(robj);
+		r = radeon_bo_reserve(rbo, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rbo);
+			radeon_bo_unpin(rbo);
+			radeon_bo_unreserve(rbo);
+		}
 		drm_fb_helper_free(&rfbdev->helper);
 		framebuffer_release(info);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fence.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fence.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fence.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fence.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,16 +140,15 @@ int radeon_fence_create(struct radeon_de
 
 bool radeon_fence_signaled(struct radeon_fence *fence)
 {
-	struct radeon_device *rdev = fence->rdev;
 	unsigned long irq_flags;
 	bool signaled = false;
 
-	if (rdev->gpu_lockup) {
+	if (!fence)
 		return true;
-	}
-	if (fence == NULL) {
+
+	if (fence->rdev->gpu_lockup)
 		return true;
-	}
+
 	write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags);
 	signaled = fence->signaled;
 	/* if we are shuting down report all fence as signaled */
@@ -168,37 +167,6 @@ bool radeon_fence_signaled(struct radeon
 	return signaled;
 }
 
-int r600_fence_wait(struct radeon_fence *fence,  bool intr, bool lazy)
-{
-	struct radeon_device *rdev;
-	int ret = 0;
-
-	rdev = fence->rdev;
-
-	__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-
-	while (1) {
-		if (radeon_fence_signaled(fence))
-			break;
-
-		if (time_after_eq(jiffies, fence->timeout)) {
-			ret = -EBUSY;
-			break;
-		}
-
-		if (lazy)
-			schedule_timeout(1);
-
-		if (intr && signal_pending(current)) {
-			ret = -ERESTARTSYS;
-			break;
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-
 int radeon_fence_wait(struct radeon_fence *fence, bool intr)
 {
 	struct radeon_device *rdev;
@@ -216,13 +184,6 @@ int radeon_fence_wait(struct radeon_fenc
 		return 0;
 	}
 
-	if (rdev->family >= CHIP_R600) {
-		r = r600_fence_wait(fence, intr, 0);
-		if (r == -ERESTARTSYS)
-			return -EBUSY;
-		return r;
-	}
-
 retry:
 	cur_jiffies = jiffies;
 	timeout = HZ / 100;
@@ -231,14 +192,17 @@ retry:
 	}
 
 	if (intr) {
+		radeon_irq_kms_sw_irq_get(rdev);
 		r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
 				radeon_fence_signaled(fence), timeout);
-		if (unlikely(r == -ERESTARTSYS)) {
-			return -EBUSY;
-		}
+		radeon_irq_kms_sw_irq_put(rdev);
+		if (unlikely(r < 0))
+			return r;
 	} else {
+		radeon_irq_kms_sw_irq_get(rdev);
 		r = wait_event_timeout(rdev->fence_drv.queue,
 			 radeon_fence_signaled(fence), timeout);
+		radeon_irq_kms_sw_irq_put(rdev);
 	}
 	if (unlikely(!radeon_fence_signaled(fence))) {
 		if (unlikely(r == 0)) {
@@ -359,7 +323,7 @@ int radeon_fence_driver_init(struct rade
 	write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
 	r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg);
 	if (r) {
-		DRM_ERROR("Fence failed to get a scratch register.");
+		dev_err(rdev->dev, "fence failed to get scratch register\n");
 		write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
 		return r;
 	}
@@ -370,9 +334,10 @@ int radeon_fence_driver_init(struct rade
 	INIT_LIST_HEAD(&rdev->fence_drv.signaled);
 	rdev->fence_drv.count_timeout = 0;
 	init_waitqueue_head(&rdev->fence_drv.queue);
+	rdev->fence_drv.initialized = true;
 	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
 	if (radeon_debugfs_fence_init(rdev)) {
-		DRM_ERROR("Failed to register debugfs file for fence !\n");
+		dev_err(rdev->dev, "fence debugfs file creation failed\n");
 	}
 	return 0;
 }
@@ -381,11 +346,13 @@ void radeon_fence_driver_fini(struct rad
 {
 	unsigned long irq_flags;
 
+	if (!rdev->fence_drv.initialized)
+		return;
 	wake_up_all(&rdev->fence_drv.queue);
 	write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
 	radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg);
 	write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
-	DRM_INFO("radeon: fence finalized\n");
+	rdev->fence_drv.initialized = false;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fixed.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fixed.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_fixed.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_fixed.h	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,23 @@ typedef union rfixed {
 #define fixed_init_half(A) { .full = rfixed_const_half((A)) }
 #define rfixed_trunc(A) ((A).full >> 12)
 
+static inline u32 rfixed_floor(fixed20_12 A)
+{
+	u32 non_frac = rfixed_trunc(A);
+
+	return rfixed_const(non_frac);
+}
+
+static inline u32 rfixed_ceil(fixed20_12 A)
+{
+	u32 non_frac = rfixed_trunc(A);
+
+	if (A.full > rfixed_const(non_frac))
+		return rfixed_const(non_frac + 1);
+	else
+		return rfixed_const(non_frac);
+}
+
 static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B)
 {
 	u64 tmp = ((u64)A.full << 13);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_gart.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gart.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_gart.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gart.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,11 +78,9 @@ int radeon_gart_table_vram_alloc(struct
 	int r;
 
 	if (rdev->gart.table.vram.robj == NULL) {
-		r = radeon_object_create(rdev, NULL,
-					 rdev->gart.table_size,
-					 true,
-					 RADEON_GEM_DOMAIN_VRAM,
-					 false, &rdev->gart.table.vram.robj);
+		r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
+					true, RADEON_GEM_DOMAIN_VRAM,
+					&rdev->gart.table.vram.robj);
 		if (r) {
 			return r;
 		}
@@ -95,32 +93,38 @@ int radeon_gart_table_vram_pin(struct ra
 	uint64_t gpu_addr;
 	int r;
 
-	r = radeon_object_pin(rdev->gart.table.vram.robj,
-			      RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
-	if (r) {
-		radeon_object_unref(&rdev->gart.table.vram.robj);
+	r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+	if (unlikely(r != 0))
 		return r;
-	}
-	r = radeon_object_kmap(rdev->gart.table.vram.robj,
-			       (void **)&rdev->gart.table.vram.ptr);
+	r = radeon_bo_pin(rdev->gart.table.vram.robj,
+				RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
 	if (r) {
-		radeon_object_unpin(rdev->gart.table.vram.robj);
-		radeon_object_unref(&rdev->gart.table.vram.robj);
-		DRM_ERROR("radeon: failed to map gart vram table.\n");
+		radeon_bo_unreserve(rdev->gart.table.vram.robj);
 		return r;
 	}
+	r = radeon_bo_kmap(rdev->gart.table.vram.robj,
+				(void **)&rdev->gart.table.vram.ptr);
+	if (r)
+		radeon_bo_unpin(rdev->gart.table.vram.robj);
+	radeon_bo_unreserve(rdev->gart.table.vram.robj);
 	rdev->gart.table_addr = gpu_addr;
-	return 0;
+	return r;
 }
 
 void radeon_gart_table_vram_free(struct radeon_device *rdev)
 {
+	int r;
+
 	if (rdev->gart.table.vram.robj == NULL) {
 		return;
 	}
-	radeon_object_kunmap(rdev->gart.table.vram.robj);
-	radeon_object_unpin(rdev->gart.table.vram.robj);
-	radeon_object_unref(&rdev->gart.table.vram.robj);
+	r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+	if (likely(r == 0)) {
+		radeon_bo_kunmap(rdev->gart.table.vram.robj);
+		radeon_bo_unpin(rdev->gart.table.vram.robj);
+		radeon_bo_unreserve(rdev->gart.table.vram.robj);
+	}
+	radeon_bo_unref(&rdev->gart.table.vram.robj);
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_gem.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gem.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_gem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_gem.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_ge
 
 void radeon_gem_object_free(struct drm_gem_object *gobj)
 {
-	struct radeon_object *robj = gobj->driver_private;
+	struct radeon_bo *robj = gobj->driver_private;
 
 	gobj->driver_private = NULL;
 	if (robj) {
-		radeon_object_unref(&robj);
+		radeon_bo_unref(&robj);
 	}
 }
 
 int radeon_gem_object_create(struct radeon_device *rdev, int size,
-			     int alignment, int initial_domain,
-			     bool discardable, bool kernel,
-			     bool interruptible,
-			     struct drm_gem_object **obj)
+				int alignment, int initial_domain,
+				bool discardable, bool kernel,
+				struct drm_gem_object **obj)
 {
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	*obj = NULL;
@@ -65,11 +64,11 @@ int radeon_gem_object_create(struct rade
 	if (alignment < PAGE_SIZE) {
 		alignment = PAGE_SIZE;
 	}
-	r = radeon_object_create(rdev, gobj, size, kernel, initial_domain,
-				 interruptible, &robj);
+	r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
 	if (r) {
-		DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
-			  size, initial_domain, alignment);
+		if (r != -ERESTARTSYS)
+			DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
+				  size, initial_domain, alignment, r);
 		mutex_lock(&rdev->ddev->struct_mutex);
 		drm_gem_object_unreference(gobj);
 		mutex_unlock(&rdev->ddev->struct_mutex);
@@ -83,33 +82,33 @@ int radeon_gem_object_create(struct rade
 int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
 			  uint64_t *gpu_addr)
 {
-	struct radeon_object *robj = obj->driver_private;
-	uint32_t flags;
+	struct radeon_bo *robj = obj->driver_private;
+	int r;
 
-	switch (pin_domain) {
-	case RADEON_GEM_DOMAIN_VRAM:
-		flags = TTM_PL_FLAG_VRAM;
-		break;
-	case RADEON_GEM_DOMAIN_GTT:
-		flags = TTM_PL_FLAG_TT;
-		break;
-	default:
-		flags = TTM_PL_FLAG_SYSTEM;
-		break;
-	}
-	return radeon_object_pin(robj, flags, gpu_addr);
+	r = radeon_bo_reserve(robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(robj, pin_domain, gpu_addr);
+	radeon_bo_unreserve(robj);
+	return r;
 }
 
 void radeon_gem_object_unpin(struct drm_gem_object *obj)
 {
-	struct radeon_object *robj = obj->driver_private;
-	radeon_object_unpin(robj);
+	struct radeon_bo *robj = obj->driver_private;
+	int r;
+
+	r = radeon_bo_reserve(robj, false);
+	if (likely(r == 0)) {
+		radeon_bo_unpin(robj);
+		radeon_bo_unreserve(robj);
+	}
 }
 
 int radeon_gem_set_domain(struct drm_gem_object *gobj,
 			  uint32_t rdomain, uint32_t wdomain)
 {
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	uint32_t domain;
 	int r;
 
@@ -127,7 +126,7 @@ int radeon_gem_set_domain(struct drm_gem
 	}
 	if (domain == RADEON_GEM_DOMAIN_CPU) {
 		/* Asking for cpu access wait for object idle */
-		r = radeon_object_wait(robj);
+		r = radeon_bo_wait(robj, NULL, false);
 		if (r) {
 			printk(KERN_ERR "Failed to wait for object !\n");
 			return r;
@@ -144,7 +143,7 @@ int radeon_gem_init(struct radeon_device
 
 void radeon_gem_fini(struct radeon_device *rdev)
 {
-	radeon_object_force_delete(rdev);
+	radeon_bo_force_delete(rdev);
 }
 
 
@@ -158,9 +157,13 @@ int radeon_gem_info_ioctl(struct drm_dev
 	struct drm_radeon_gem_info *args = data;
 
 	args->vram_size = rdev->mc.real_vram_size;
-	/* FIXME: report somethings that makes sense */
-	args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024);
-	args->gart_size = rdev->mc.gtt_size;
+	args->vram_visible = rdev->mc.real_vram_size;
+	if (rdev->stollen_vga_memory)
+		args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
+	if (rdev->fbdev_rbo)
+		args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo);
+	args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
+		RADEON_IB_POOL_SIZE*64*1024;
 	return 0;
 }
 
@@ -192,8 +195,8 @@ int radeon_gem_create_ioctl(struct drm_d
 	/* create a gem object to contain this object in */
 	args->size = roundup(args->size, PAGE_SIZE);
 	r = radeon_gem_object_create(rdev, args->size, args->alignment,
-				     args->initial_domain, false,
-				     false, true, &gobj);
+					args->initial_domain, false,
+					false, &gobj);
 	if (r) {
 		return r;
 	}
@@ -218,7 +221,7 @@ int radeon_gem_set_domain_ioctl(struct d
 	 * just validate the BO into a certain domain */
 	struct drm_radeon_gem_set_domain *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	/* for now if someone requests domain CPU -
@@ -244,19 +247,18 @@ int radeon_gem_mmap_ioctl(struct drm_dev
 {
 	struct drm_radeon_gem_mmap *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
-	int r;
+	struct radeon_bo *robj;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL) {
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_mmap(robj, &args->addr_ptr);
+	args->addr_ptr = radeon_bo_mmap_offset(robj);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
-	return r;
+	return 0;
 }
 
 int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
@@ -264,16 +266,16 @@ int radeon_gem_busy_ioctl(struct drm_dev
 {
 	struct drm_radeon_gem_busy *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
-	uint32_t cur_placement;
+	uint32_t cur_placement = 0;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL) {
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_busy_domain(robj, &cur_placement);
+	r = radeon_bo_wait(robj, &cur_placement, true);
 	switch (cur_placement) {
 	case TTM_PL_VRAM:
 		args->domain = RADEON_GEM_DOMAIN_VRAM;
@@ -297,7 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct dr
 {
 	struct drm_radeon_gem_wait_idle *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r;
 
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
@@ -305,7 +307,10 @@ int radeon_gem_wait_idle_ioctl(struct dr
 		return -EINVAL;
 	}
 	robj = gobj->driver_private;
-	r = radeon_object_wait(robj);
+	r = radeon_bo_wait(robj, NULL, false);
+	/* callback hw specific functions if any */
+	if (robj->rdev->asic->ioctl_wait_idle)
+		robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
@@ -317,7 +322,7 @@ int radeon_gem_set_tiling_ioctl(struct d
 {
 	struct drm_radeon_gem_set_tiling *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *robj;
 	int r = 0;
 
 	DRM_DEBUG("%d \n", args->handle);
@@ -325,7 +330,7 @@ int radeon_gem_set_tiling_ioctl(struct d
 	if (gobj == NULL)
 		return -EINVAL;
 	robj = gobj->driver_private;
-	radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch);
+	r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
@@ -337,16 +342,20 @@ int radeon_gem_get_tiling_ioctl(struct d
 {
 	struct drm_radeon_gem_get_tiling *args = data;
 	struct drm_gem_object *gobj;
-	struct radeon_object *robj;
+	struct radeon_bo *rbo;
 	int r = 0;
 
 	DRM_DEBUG("\n");
 	gobj = drm_gem_object_lookup(dev, filp, args->handle);
 	if (gobj == NULL)
 		return -EINVAL;
-	robj = gobj->driver_private;
-	radeon_object_get_tiling_flags(robj, &args->tiling_flags,
-				       &args->pitch);
+	rbo = gobj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		goto out;
+	radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
+	radeon_bo_unreserve(rbo);
+out:
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_unreference(gobj);
 	mutex_unlock(&dev->struct_mutex);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,8 +28,6 @@
 #ifndef __RADEON_H__
 #define __RADEON_H__
 
-#include "radeon_object.h"
-
 /* TODO: Here are things that needs to be done :
  *	- surface allocator & initializer : (bit like scratch reg) should
  *	  initialize HDP_ stuff on RS600, R600, R700 hw, well anythings
@@ -67,6 +65,11 @@
 #include <linux/list.h>
 #include <linux/kref.h>
 
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement.h>
+#include <ttm/ttm_module.h>
+
 #include "radeon_family.h"
 #include "radeon_mode.h"
 #include "radeon_reg.h"
@@ -85,12 +88,15 @@ extern int radeon_benchmarking;
 extern int radeon_testing;
 extern int radeon_connector_table;
 extern int radeon_tv;
+extern int radeon_new_pll;
+extern int radeon_audio;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
  * symbol;
  */
 #define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */
+/* RADEON_IB_POOL_SIZE must be a power of 2 */
 #define RADEON_IB_POOL_SIZE		16
 #define RADEON_DEBUGFS_MAX_NUM_FILES	32
 #define RADEONFB_CONN_LIMIT		4
@@ -157,6 +163,7 @@ struct radeon_fence_driver {
 	struct list_head		created;
 	struct list_head		emited;
 	struct list_head		signaled;
+	bool				initialized;
 };
 
 struct radeon_fence {
@@ -186,76 +193,63 @@ void radeon_fence_unref(struct radeon_fe
  * Tiling registers
  */
 struct radeon_surface_reg {
-	struct radeon_object *robj;
+	struct radeon_bo *bo;
 };
 
 #define RADEON_GEM_MAX_SURFACES 8
 
 /*
- * Radeon buffer.
+ * TTM.
  */
-struct radeon_object;
+struct radeon_mman {
+	struct ttm_bo_global_ref        bo_global_ref;
+	struct ttm_global_reference	mem_global_ref;
+	struct ttm_bo_device		bdev;
+	bool				mem_global_referenced;
+	bool				initialized;
+};
 
-struct radeon_object_list {
+struct radeon_bo {
+	/* Protected by gem.mutex */
+	struct list_head		list;
+	/* Protected by tbo.reserved */
+	u32				placements[3];
+	struct ttm_placement		placement;
+	struct ttm_buffer_object	tbo;
+	struct ttm_bo_kmap_obj		kmap;
+	unsigned			pin_count;
+	void				*kptr;
+	u32				tiling_flags;
+	u32				pitch;
+	int				surface_reg;
+	/* Constant after initialization */
+	struct radeon_device		*rdev;
+	struct drm_gem_object		*gobj;
+};
+
+struct radeon_bo_list {
 	struct list_head	list;
-	struct radeon_object	*robj;
+	struct radeon_bo	*bo;
 	uint64_t		gpu_offset;
 	unsigned		rdomain;
 	unsigned		wdomain;
-	uint32_t                tiling_flags;
+	u32			tiling_flags;
 };
 
-int radeon_object_init(struct radeon_device *rdev);
-void radeon_object_fini(struct radeon_device *rdev);
-int radeon_object_create(struct radeon_device *rdev,
-			 struct drm_gem_object *gobj,
-			 unsigned long size,
-			 bool kernel,
-			 uint32_t domain,
-			 bool interruptible,
-			 struct radeon_object **robj_ptr);
-int radeon_object_kmap(struct radeon_object *robj, void **ptr);
-void radeon_object_kunmap(struct radeon_object *robj);
-void radeon_object_unref(struct radeon_object **robj);
-int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
-		      uint64_t *gpu_addr);
-void radeon_object_unpin(struct radeon_object *robj);
-int radeon_object_wait(struct radeon_object *robj);
-int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement);
-int radeon_object_evict_vram(struct radeon_device *rdev);
-int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset);
-void radeon_object_force_delete(struct radeon_device *rdev);
-void radeon_object_list_add_object(struct radeon_object_list *lobj,
-				   struct list_head *head);
-int radeon_object_list_validate(struct list_head *head, void *fence);
-void radeon_object_list_unvalidate(struct list_head *head);
-void radeon_object_list_clean(struct list_head *head);
-int radeon_object_fbdev_mmap(struct radeon_object *robj,
-			     struct vm_area_struct *vma);
-unsigned long radeon_object_size(struct radeon_object *robj);
-void radeon_object_clear_surface_reg(struct radeon_object *robj);
-int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
-			       bool force_drop);
-void radeon_object_set_tiling_flags(struct radeon_object *robj,
-				    uint32_t tiling_flags, uint32_t pitch);
-void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch);
-void radeon_bo_move_notify(struct ttm_buffer_object *bo,
-			   struct ttm_mem_reg *mem);
-void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
 /*
  * GEM objects.
  */
 struct radeon_gem {
+	struct mutex		mutex;
 	struct list_head	objects;
 };
 
 int radeon_gem_init(struct radeon_device *rdev);
 void radeon_gem_fini(struct radeon_device *rdev);
 int radeon_gem_object_create(struct radeon_device *rdev, int size,
-			     int alignment, int initial_domain,
-			     bool discardable, bool kernel,
-			     bool interruptible,
-			     struct drm_gem_object **obj);
+				int alignment, int initial_domain,
+				bool discardable, bool kernel,
+				struct drm_gem_object **obj);
 int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
 			  uint64_t *gpu_addr);
 void radeon_gem_object_unpin(struct drm_gem_object *obj);
@@ -271,7 +265,7 @@ struct radeon_gart_table_ram {
 };
 
 struct radeon_gart_table_vram {
-	struct radeon_object		*robj;
+	struct radeon_bo		*robj;
 	volatile uint32_t		*ptr;
 };
 
@@ -326,10 +320,12 @@ struct radeon_mc {
 	u64			real_vram_size;
 	int			vram_mtrr;
 	bool			vram_is_ddr;
+	bool                    igp_sideport_enabled;
 };
 
 int radeon_mc_setup(struct radeon_device *rdev);
-
+bool radeon_combios_sideport_present(struct radeon_device *rdev);
+bool radeon_atombios_sideport_present(struct radeon_device *rdev);
 
 /*
  * GPU scratch registers structures, functions & helpers
@@ -352,22 +348,28 @@ struct radeon_irq {
 	bool		sw_int;
 	/* FIXME: use a define max crtc rather than hardcode it */
 	bool		crtc_vblank_int[2];
+	/* FIXME: use defines for max hpd/dacs */
+	bool            hpd[6];
+	spinlock_t sw_lock;
+	int sw_refcount;
 };
 
 int radeon_irq_kms_init(struct radeon_device *rdev);
 void radeon_irq_kms_fini(struct radeon_device *rdev);
-
+void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev);
+void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
 
 /*
  * CP & ring.
  */
 struct radeon_ib {
 	struct list_head	list;
-	unsigned long		idx;
+	unsigned		idx;
 	uint64_t		gpu_addr;
 	struct radeon_fence	*fence;
-	uint32_t	*ptr;
+	uint32_t		*ptr;
 	uint32_t		length_dw;
+	bool			free;
 };
 
 /*
@@ -376,15 +378,14 @@ struct radeon_ib {
  */
 struct radeon_ib_pool {
 	struct mutex		mutex;
-	struct radeon_object	*robj;
-	struct list_head	scheduled_ibs;
+	struct radeon_bo	*robj;
 	struct radeon_ib	ibs[RADEON_IB_POOL_SIZE];
 	bool			ready;
-	DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE);
+	unsigned		head_id;
 };
 
 struct radeon_cp {
-	struct radeon_object	*ring_obj;
+	struct radeon_bo	*ring_obj;
 	volatile uint32_t	*ring;
 	unsigned		rptr;
 	unsigned		wptr;
@@ -399,8 +400,25 @@ struct radeon_cp {
 	bool			ready;
 };
 
+/*
+ * R6xx+ IH ring
+ */
+struct r600_ih {
+	struct radeon_bo	*ring_obj;
+	volatile uint32_t	*ring;
+	unsigned		rptr;
+	unsigned		wptr;
+	unsigned		wptr_old;
+	unsigned		ring_size;
+	uint64_t		gpu_addr;
+	uint32_t		ptr_mask;
+	spinlock_t              lock;
+	bool                    enabled;
+};
+
 struct r600_blit {
-	struct radeon_object	*shader_obj;
+	struct mutex		mutex;
+	struct radeon_bo	*shader_obj;
 	u64 shader_gpu_addr;
 	u32 vs_offset, ps_offset;
 	u32 state_offset;
@@ -430,8 +448,8 @@ void radeon_ring_fini(struct radeon_devi
  */
 struct radeon_cs_reloc {
 	struct drm_gem_object		*gobj;
-	struct radeon_object		*robj;
-	struct radeon_object_list	lobj;
+	struct radeon_bo		*robj;
+	struct radeon_bo_list		lobj;
 	uint32_t			handle;
 	uint32_t			flags;
 };
@@ -448,6 +466,7 @@ struct radeon_cs_chunk {
 };
 
 struct radeon_cs_parser {
+	struct device		*dev;
 	struct radeon_device	*rdev;
 	struct drm_file		*filp;
 	/* chunks */
@@ -527,7 +546,7 @@ void radeon_agp_fini(struct radeon_devic
  * Writeback
  */
 struct radeon_wb {
-	struct radeon_object	*wb_obj;
+	struct radeon_bo	*wb_obj;
 	volatile uint32_t	*wb;
 	uint64_t		gpu_addr;
 };
@@ -639,6 +658,17 @@ struct radeon_asic {
 			       uint32_t offset, uint32_t obj_size);
 	int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
 	void (*bandwidth_update)(struct radeon_device *rdev);
+	void (*hpd_init)(struct radeon_device *rdev);
+	void (*hpd_fini)(struct radeon_device *rdev);
+	bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+	void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
+	/* ioctl hw specific callback. Some hw might want to perform special
+	 * operation on specific ioctl. For instance on wait idle some hw
+	 * might want to perform and HDP flush through MMIO as it seems that
+	 * some R6XX/R7XX hw doesn't take HDP flush into account if programmed
+	 * through ring.
+	 */
+	void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo);
 };
 
 /*
@@ -647,11 +677,14 @@ struct radeon_asic {
 struct r100_asic {
 	const unsigned	*reg_safe_bm;
 	unsigned	reg_safe_bm_size;
+	u32		hdp_cntl;
 };
 
 struct r300_asic {
 	const unsigned	*reg_safe_bm;
 	unsigned	reg_safe_bm_size;
+	u32		resync_scratch;
+	u32		hdp_cntl;
 };
 
 struct r600_asic {
@@ -751,9 +784,9 @@ struct radeon_device {
 	uint8_t				*bios;
 	bool				is_atom_bios;
 	uint16_t			bios_header_start;
-	struct radeon_object		*stollen_vga_memory;
+	struct radeon_bo		*stollen_vga_memory;
 	struct fb_info			*fbdev_info;
-	struct radeon_object		*fbdev_robj;
+	struct radeon_bo		*fbdev_rbo;
 	struct radeon_framebuffer	*fbdev_rfb;
 	/* Register mmio */
 	resource_size_t			rmmio_base;
@@ -791,8 +824,20 @@ struct radeon_device {
 	struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
 	const struct firmware *me_fw;	/* all family ME firmware */
 	const struct firmware *pfp_fw;	/* r6/700 PFP firmware */
+	const struct firmware *rlc_fw;	/* r6/700 RLC firmware */
 	struct r600_blit r600_blit;
 	int msi_enabled; /* msi enabled */
+	struct r600_ih ih; /* r6/700 interrupt ring */
+	struct workqueue_struct *wq;
+	struct work_struct hotplug_work;
+
+	/* audio stuff */
+	struct timer_list	audio_timer;
+	int			audio_channels;
+	int			audio_rate;
+	int			audio_bits_per_sample;
+	uint8_t			audio_status_bits;
+	uint8_t			audio_category_code;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -811,7 +856,7 @@ void r600_kms_blit_copy(struct radeon_de
 
 static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg)
 {
-	if (reg < 0x10000)
+	if (reg < rdev->rmmio_size)
 		return readl(((void __iomem *)rdev->rmmio) + reg);
 	else {
 		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
@@ -821,7 +866,7 @@ static inline uint32_t r100_mm_rreg(stru
 
 static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
 {
-	if (reg < 0x10000)
+	if (reg < rdev->rmmio_size)
 		writel(v, ((void __iomem *)rdev->rmmio) + reg);
 	else {
 		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
@@ -829,6 +874,10 @@ static inline void r100_mm_wreg(struct r
 	}
 }
 
+/*
+ * Cast helper
+ */
+#define to_radeon_fence(p) ((struct radeon_fence *)(p))
 
 /*
  * Registers read & write functions.
@@ -965,18 +1014,25 @@ static inline void radeon_ring_write(str
 #define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
 #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
 #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
-#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
+#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e))
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
 #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
 #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
+#define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev))
+#define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev))
+#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd))
+#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd))
 
 /* Common functions */
+/* AGP */
+extern void radeon_agp_disable(struct radeon_device *rdev);
 extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern void radeon_modeset_fini(struct radeon_device *rdev);
 extern bool radeon_card_posted(struct radeon_device *rdev);
+extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
 extern int radeon_clocks_init(struct radeon_device *rdev);
 extern void radeon_clocks_fini(struct radeon_device *rdev);
 extern void radeon_scratch_init(struct radeon_device *rdev);
@@ -984,6 +1040,8 @@ extern void radeon_surface_init(struct r
 extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
 extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
+extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
+extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
 struct r100_mc_save {
@@ -1021,7 +1079,7 @@ extern int r100_cp_reset(struct radeon_d
 extern void r100_vga_render_disable(struct radeon_device *rdev);
 extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
 						struct radeon_cs_packet *pkt,
-						struct radeon_object *robj);
+						struct radeon_bo *robj);
 extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt,
 				const unsigned *auth, unsigned n,
@@ -1029,6 +1087,8 @@ extern int r100_cs_parse_packet0(struct
 extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt,
 				unsigned idx);
+extern void r100_enable_bm(struct radeon_device *rdev);
+extern void r100_set_common_regs(struct radeon_device *rdev);
 
 /* rv200,rv250,rv280 */
 extern void r200_set_safe_registers(struct radeon_device *rdev);
@@ -1091,6 +1151,7 @@ extern bool r600_card_posted(struct rade
 extern void r600_cp_stop(struct radeon_device *rdev);
 extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size);
 extern int r600_cp_resume(struct radeon_device *rdev);
+extern void r600_cp_fini(struct radeon_device *rdev);
 extern int r600_count_pipe_bits(uint32_t val);
 extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
 extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
@@ -1104,7 +1165,30 @@ extern void r600_wb_disable(struct radeo
 extern void r600_scratch_init(struct radeon_device *rdev);
 extern int r600_blit_init(struct radeon_device *rdev);
 extern void r600_blit_fini(struct radeon_device *rdev);
-extern int r600_cp_init_microcode(struct radeon_device *rdev);
+extern int r600_init_microcode(struct radeon_device *rdev);
 extern int r600_gpu_reset(struct radeon_device *rdev);
+/* r600 irq */
+extern int r600_irq_init(struct radeon_device *rdev);
+extern void r600_irq_fini(struct radeon_device *rdev);
+extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
+extern int r600_irq_set(struct radeon_device *rdev);
+extern void r600_irq_suspend(struct radeon_device *rdev);
+/* r600 audio */
+extern int r600_audio_init(struct radeon_device *rdev);
+extern int r600_audio_tmds_index(struct drm_encoder *encoder);
+extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
+extern void r600_audio_fini(struct radeon_device *rdev);
+extern void r600_hdmi_init(struct drm_encoder *encoder);
+extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
+extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
+extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
+extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
+					    int channels,
+					    int rate,
+					    int bps,
+					    uint8_t status_bits,
+					    uint8_t category_code);
+
+#include "radeon_object.h"
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,35 +59,43 @@ bool radeon_ddc_probe(struct radeon_conn
 }
 
 
-void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state)
+void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
 {
-	struct radeon_device *rdev = radeon_connector->base.dev->dev_private;
+	struct radeon_device *rdev = i2c->dev->dev_private;
+	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t temp;
-	struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
 
 	/* RV410 appears to have a bug where the hw i2c in reset
 	 * holds the i2c port in a bad state - switch hw i2c away before
 	 * doing DDC - do this for all r200s/r300s/r400s for safety sake
 	 */
-	if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
-		if (rec->a_clk_reg == RADEON_GPIO_MONID) {
-			WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-						R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
-		} else {
-			WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
-						R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+	if (rec->hw_capable) {
+		if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) {
+			if (rec->a_clk_reg == RADEON_GPIO_MONID) {
+				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1)));
+			} else {
+				WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+							       R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3)));
+			}
 		}
 	}
-	if (lock_state) {
-		temp = RREG32(rec->a_clk_reg);
-		temp &= ~(rec->a_clk_mask);
-		WREG32(rec->a_clk_reg, temp);
 
-		temp = RREG32(rec->a_data_reg);
-		temp &= ~(rec->a_data_mask);
-		WREG32(rec->a_data_reg, temp);
-	}
+	/* clear the output pin values */
+	temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
+	WREG32(rec->a_clk_reg, temp);
+
+	temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask;
+	WREG32(rec->a_data_reg, temp);
+
+	/* set the pins to input */
+	temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
+	WREG32(rec->en_clk_reg, temp);
 
+	temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
+	WREG32(rec->en_data_reg, temp);
+
+	/* mask the gpio pins for software use */
 	temp = RREG32(rec->mask_clk_reg);
 	if (lock_state)
 		temp |= rec->mask_clk_mask;
@@ -112,8 +120,9 @@ static int get_clock(void *i2c_priv)
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->get_clk_reg);
-	val &= rec->get_clk_mask;
+	/* read the value off the pin */
+	val = RREG32(rec->y_clk_reg);
+	val &= rec->y_clk_mask;
 
 	return (val != 0);
 }
@@ -126,8 +135,10 @@ static int get_data(void *i2c_priv)
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->get_data_reg);
-	val &= rec->get_data_mask;
+	/* read the value off the pin */
+	val = RREG32(rec->y_data_reg);
+	val &= rec->y_data_mask;
+
 	return (val != 0);
 }
 
@@ -138,9 +149,10 @@ static void set_clock(void *i2c_priv, in
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask);
-	val |= clock ? 0 : rec->put_clk_mask;
-	WREG32(rec->put_clk_reg, val);
+	/* set pin direction */
+	val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask;
+	val |= clock ? 0 : rec->en_clk_mask;
+	WREG32(rec->en_clk_reg, val);
 }
 
 static void set_data(void *i2c_priv, int data)
@@ -150,14 +162,15 @@ static void set_data(void *i2c_priv, int
 	struct radeon_i2c_bus_rec *rec = &i2c->rec;
 	uint32_t val;
 
-	val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask);
-	val |= data ? 0 : rec->put_data_mask;
-	WREG32(rec->put_data_reg, val);
+	/* set pin direction */
+	val = RREG32(rec->en_data_reg) & ~rec->en_data_mask;
+	val |= data ? 0 : rec->en_data_mask;
+	WREG32(rec->en_data_reg, val);
 }
 
 struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
-		struct radeon_i2c_bus_rec *rec,
-		const char *name)
+					  struct radeon_i2c_bus_rec *rec,
+					  const char *name)
 {
 	struct radeon_i2c_chan *i2c;
 	int ret;
@@ -167,20 +180,19 @@ struct radeon_i2c_chan *radeon_i2c_creat
 		return NULL;
 
 	i2c->adapter.owner = THIS_MODULE;
-	i2c->adapter.algo_data = &i2c->algo;
 	i2c->dev = dev;
-	i2c->algo.setsda = set_data;
-	i2c->algo.setscl = set_clock;
-	i2c->algo.getsda = get_data;
-	i2c->algo.getscl = get_clock;
-	i2c->algo.udelay = 20;
+	i2c_set_adapdata(&i2c->adapter, i2c);
+	i2c->adapter.algo_data = &i2c->algo.bit;
+	i2c->algo.bit.setsda = set_data;
+	i2c->algo.bit.setscl = set_clock;
+	i2c->algo.bit.getsda = get_data;
+	i2c->algo.bit.getscl = get_clock;
+	i2c->algo.bit.udelay = 20;
 	/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
 	 * make this, 2 jiffies is a lot more reliable */
-	i2c->algo.timeout = 2;
-	i2c->algo.data = i2c;
+	i2c->algo.bit.timeout = 2;
+	i2c->algo.bit.data = i2c;
 	i2c->rec = *rec;
-	i2c_set_adapdata(&i2c->adapter, i2c);
-
 	ret = i2c_bit_add_bus(&i2c->adapter);
 	if (ret) {
 		DRM_INFO("Failed to register i2c %s\n", name);
@@ -194,6 +206,38 @@ out_free:
 
 }
 
+struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
+					     struct radeon_i2c_bus_rec *rec,
+					     const char *name)
+{
+	struct radeon_i2c_chan *i2c;
+	int ret;
+
+	i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
+	if (i2c == NULL)
+		return NULL;
+
+	i2c->rec = *rec;
+	i2c->adapter.owner = THIS_MODULE;
+	i2c->dev = dev;
+	i2c_set_adapdata(&i2c->adapter, i2c);
+	i2c->adapter.algo_data = &i2c->algo.dp;
+	i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
+	i2c->algo.dp.address = 0;
+	ret = i2c_dp_aux_add_bus(&i2c->adapter);
+	if (ret) {
+		DRM_INFO("Failed to register i2c %s\n", name);
+		goto out_free;
+	}
+
+	return i2c;
+out_free:
+	kfree(i2c);
+	return NULL;
+
+}
+
+
 void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 {
 	if (!i2c)
@@ -207,3 +251,59 @@ struct drm_encoder *radeon_best_encoder(
 {
 	return NULL;
 }
+
+void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
+			    u8 slave_addr,
+			    u8 addr,
+			    u8 *val)
+{
+	u8 out_buf[2];
+	u8 in_buf[2];
+	struct i2c_msg msgs[] = {
+		{
+			.addr = slave_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = out_buf,
+		},
+		{
+			.addr = slave_addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = in_buf,
+		}
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = 0;
+
+	if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
+		*val = in_buf[0];
+		DRM_DEBUG("val = 0x%02x\n", *val);
+	} else {
+		DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
+			  addr, *val);
+	}
+}
+
+void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus,
+			    u8 slave_addr,
+			    u8 addr,
+			    u8 val)
+{
+	uint8_t out_buf[2];
+	struct i2c_msg msg = {
+		.addr = slave_addr,
+		.flags = 0,
+		.len = 2,
+		.buf = out_buf,
+	};
+
+	out_buf[0] = addr;
+	out_buf[1] = val;
+
+	if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
+		DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
+			  addr, val);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ioc32.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ioc32.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ioc32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ioc32.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,8 +92,7 @@ static int compat_radeon_cp_init(struct
 			  &init->gart_textures_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
 }
 
 typedef struct drm_radeon_clear32 {
@@ -125,8 +124,7 @@ static int compat_radeon_cp_clear(struct
 			  &clr->depth_boxes))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
 }
 
 typedef struct drm_radeon_stipple32 {
@@ -149,8 +147,7 @@ static int compat_radeon_cp_stipple(stru
 			  &request->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
 }
 
 typedef struct drm_radeon_tex_image32 {
@@ -204,8 +201,7 @@ static int compat_radeon_cp_texture(stru
 			  &image->data))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
 }
 
 typedef struct drm_radeon_vertex2_32 {
@@ -238,8 +234,7 @@ static int compat_radeon_cp_vertex2(stru
 			  &request->prim))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
 }
 
 typedef struct drm_radeon_cmd_buffer32 {
@@ -268,8 +263,7 @@ static int compat_radeon_cp_cmdbuf(struc
 			  &request->boxes))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
 }
 
 typedef struct drm_radeon_getparam32 {
@@ -293,8 +287,7 @@ static int compat_radeon_cp_getparam(str
 			  &request->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
 }
 
 typedef struct drm_radeon_mem_alloc32 {
@@ -322,8 +315,7 @@ static int compat_radeon_mem_alloc(struc
 			  &request->region_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
 }
 
 typedef struct drm_radeon_irq_emit32 {
@@ -345,8 +337,7 @@ static int compat_radeon_irq_emit(struct
 			  &request->irq_seq))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_path.dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
 }
 
 /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
@@ -372,8 +363,7 @@ static int compat_radeon_cp_setparam(str
 			  &request->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
-			 DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
+	return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
 }
 #else
 #define compat_radeon_cp_setparam NULL
@@ -413,12 +403,10 @@ long radeon_compat_ioctl(struct file *fi
 	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
 		fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-	lock_kernel();		/* XXX for now */
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
@@ -431,9 +419,7 @@ long radeon_kms_compat_ioctl(struct file
 	if (nr < DRM_COMMAND_BASE)
 		return drm_compat_ioctl(filp, cmd, arg);
 
-	lock_kernel();		/* XXX for now */
-	ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-	unlock_kernel();
+	ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_irq.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -289,16 +289,16 @@ int radeon_irq_emit(struct drm_device *d
 	drm_radeon_irq_emit_t *emit = data;
 	int result;
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
-		return -EINVAL;
-
-	LOCK_TEST_WITH_RETURN(dev, file_priv);
-
 	if (!dev_priv) {
 		DRM_ERROR("called with no initialization\n");
 		return -EINVAL;
 	}
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return -EINVAL;
+
+	LOCK_TEST_WITH_RETURN(dev, file_priv);
+
 	result = radeon_emit_irq(dev);
 
 	if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_irq_kms.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_km
 	return radeon_irq_process(rdev);
 }
 
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void radeon_hotplug_work_func(struct work_struct *work)
+{
+	struct radeon_device *rdev = container_of(work, struct radeon_device,
+						  hotplug_work);
+	struct drm_device *dev = rdev->ddev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct drm_connector *connector;
+
+	if (mode_config->num_connector) {
+		list_for_each_entry(connector, &mode_config->connector_list, head)
+			radeon_connector_hotplug(connector);
+	}
+	/* Just fire off a uevent and let userspace tell us what to do */
+	drm_sysfs_hotplug_event(dev);
+}
+
 void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	unsigned i;
 
+	INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+
 	/* Disable *all* interrupts */
 	rdev->irq.sw_int = false;
 	for (i = 0; i < 2; i++) {
@@ -76,6 +97,7 @@ void radeon_driver_irq_uninstall_kms(str
 	rdev->irq.sw_int = false;
 	for (i = 0; i < 2; i++) {
 		rdev->irq.crtc_vblank_int[i] = false;
+		rdev->irq.hpd[i] = false;
 	}
 	radeon_irq_set(rdev);
 }
@@ -87,30 +109,69 @@ int radeon_irq_kms_init(struct radeon_de
 
 	if (rdev->flags & RADEON_SINGLE_CRTC)
 		num_crtc = 1;
-
+	spin_lock_init(&rdev->irq.sw_lock);
 	r = drm_vblank_init(rdev->ddev, num_crtc);
 	if (r) {
 		return r;
 	}
 	/* enable msi */
 	rdev->msi_enabled = 0;
-	if (rdev->family >= CHIP_RV380) {
+	/* MSIs don't seem to work on my rs780;
+	 * not sure about rs880 or other rs780s.
+	 * Needs more investigation.
+	 */
+	if ((rdev->family >= CHIP_RV380) &&
+	    (rdev->family != CHIP_RS780) &&
+	    (rdev->family != CHIP_RS880)) {
 		int ret = pci_enable_msi(rdev->pdev);
-		if (!ret)
+		if (!ret) {
 			rdev->msi_enabled = 1;
+			DRM_INFO("radeon: using MSI.\n");
+		}
 	}
-	drm_irq_install(rdev->ddev);
 	rdev->irq.installed = true;
+	r = drm_irq_install(rdev->ddev);
+	if (r) {
+		rdev->irq.installed = false;
+		return r;
+	}
 	DRM_INFO("radeon: irq initialized.\n");
 	return 0;
 }
 
 void radeon_irq_kms_fini(struct radeon_device *rdev)
 {
+	drm_vblank_cleanup(rdev->ddev);
 	if (rdev->irq.installed) {
-		rdev->irq.installed = false;
 		drm_irq_uninstall(rdev->ddev);
+		rdev->irq.installed = false;
 		if (rdev->msi_enabled)
 			pci_disable_msi(rdev->pdev);
 	}
 }
+
+void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
+	if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) {
+		rdev->irq.sw_int = true;
+		radeon_irq_set(rdev);
+	}
+	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
+}
+
+void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev)
+{
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
+	BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0);
+	if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) {
+		rdev->irq.sw_int = false;
+		radeon_irq_set(rdev);
+	}
+	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_kms.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_kms.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_kms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_kms.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,10 +30,19 @@
 #include "radeon.h"
 #include "radeon_drm.h"
 
+int radeon_driver_unload_kms(struct drm_device *dev)
+{
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (rdev == NULL)
+		return 0;
+	radeon_modeset_fini(rdev);
+	radeon_device_fini(rdev);
+	kfree(rdev);
+	dev->dev_private = NULL;
+	return 0;
+}
 
-/*
- * Driver load/unload
- */
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
 	struct radeon_device *rdev;
@@ -62,31 +71,20 @@ int radeon_driver_load_kms(struct drm_de
 	 */
 	r = radeon_device_init(rdev, dev, dev->pdev, flags);
 	if (r) {
-		DRM_ERROR("Fatal error while trying to initialize radeon.\n");
-		return r;
+		dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
+		goto out;
 	}
 	/* Again modeset_init should fail only on fatal error
 	 * otherwise it should provide enough functionalities
 	 * for shadowfb to run
 	 */
 	r = radeon_modeset_init(rdev);
-	if (r) {
-		return r;
-	}
-	return 0;
-}
-
-int radeon_driver_unload_kms(struct drm_device *dev)
-{
-	struct radeon_device *rdev = dev->dev_private;
-
-	if (rdev == NULL)
-		return 0;
-	radeon_modeset_fini(rdev);
-	radeon_device_fini(rdev);
-	kfree(rdev);
-	dev->dev_private = NULL;
-	return 0;
+	if (r)
+		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+out:
+	if (r)
+		radeon_driver_unload_kms(dev);
+	return r;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,9 +30,20 @@
 #include "radeon.h"
 #include "atom.h"
 
+static void radeon_overscan_setup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+	WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0);
+	WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0);
+	WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0);
+}
+
 static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
-				       struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
+				       struct drm_display_mode *mode)
 {
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -292,8 +303,7 @@ void radeon_crtc_dpms(struct drm_crtc *c
 	uint32_t mask;
 
 	if (radeon_crtc->crtc_id)
-		mask = (RADEON_CRTC2_EN |
-			RADEON_CRTC2_DISP_DIS |
+		mask = (RADEON_CRTC2_DISP_DIS |
 			RADEON_CRTC2_VSYNC_DIS |
 			RADEON_CRTC2_HSYNC_DIS |
 			RADEON_CRTC2_DISP_REQ_EN_B);
@@ -305,7 +315,7 @@ void radeon_crtc_dpms(struct drm_crtc *c
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		if (radeon_crtc->crtc_id)
-			WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask);
+			WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask));
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
 									 RADEON_CRTC_DISP_REQ_EN_B));
@@ -319,7 +329,7 @@ void radeon_crtc_dpms(struct drm_crtc *c
 	case DRM_MODE_DPMS_OFF:
 		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
 		if (radeon_crtc->crtc_id)
-			WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+			WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
 		else {
 			WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
 										    RADEON_CRTC_DISP_REQ_EN_B));
@@ -329,69 +339,6 @@ void radeon_crtc_dpms(struct drm_crtc *c
 	}
 }
 
-/* properly set crtc bpp when using atombios */
-void radeon_legacy_atom_set_surface(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-	int format;
-	uint32_t crtc_gen_cntl;
-	uint32_t disp_merge_cntl;
-	uint32_t crtc_pitch;
-
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		format = 2;
-		break;
-	case 15:      /*  555 */
-		format = 3;
-		break;
-	case 16:      /*  565 */
-		format = 4;
-		break;
-	case 24:      /*  RGB */
-		format = 5;
-		break;
-	case 32:      /* xRGB */
-		format = 6;
-		break;
-	default:
-		return;
-	}
-
-	crtc_pitch  = ((((crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8)) * crtc->fb->bits_per_pixel) +
-			((crtc->fb->bits_per_pixel * 8) - 1)) /
-		       (crtc->fb->bits_per_pixel * 8));
-	crtc_pitch |= crtc_pitch << 16;
-
-	WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
-
-	switch (radeon_crtc->crtc_id) {
-	case 0:
-		disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
-		disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-		WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
-
-		crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0xfffff0ff;
-		crtc_gen_cntl |= (format << 8);
-		crtc_gen_cntl |= RADEON_CRTC_EXT_DISP_EN;
-		WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl);
-		break;
-	case 1:
-		disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
-		disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
-		WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
-
-		crtc_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0xfffff0ff;
-		crtc_gen_cntl |= (format << 8);
-		WREG32(RADEON_CRTC2_GEN_CNTL, crtc_gen_cntl);
-		WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
-		WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
-		break;
-	}
-}
-
 int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 			 struct drm_framebuffer *old_fb)
 {
@@ -400,14 +347,21 @@ int radeon_crtc_set_base(struct drm_crtc
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_framebuffer *radeon_fb;
 	struct drm_gem_object *obj;
+	struct radeon_bo *rbo;
 	uint64_t base;
 	uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
 	uint32_t crtc_pitch, pitch_pixels;
 	uint32_t tiling_flags;
 	int format;
 	uint32_t gen_cntl_reg, gen_cntl_val;
+	int r;
 
 	DRM_DEBUG("\n");
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
 
 	radeon_fb = to_radeon_framebuffer(crtc->fb);
 
@@ -431,10 +385,22 @@ int radeon_crtc_set_base(struct drm_crtc
 		return false;
 	}
 
+	/* Pin framebuffer & get tilling informations */
 	obj = radeon_fb->obj;
-	if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
+	rbo = obj->driver_private;
+	r = radeon_bo_reserve(rbo, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base);
+	if (unlikely(r != 0)) {
+		radeon_bo_unreserve(rbo);
 		return -EINVAL;
 	}
+	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
+	radeon_bo_unreserve(rbo);
+	if (tiling_flags & RADEON_TILING_MICRO)
+		DRM_ERROR("trying to scanout microtiled buffer\n");
+
 	/* if scanout was in GTT this really wouldn't work */
 	/* crtc offset is from display base addr not FB location */
 	radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location;
@@ -449,10 +415,6 @@ int radeon_crtc_set_base(struct drm_crtc
 		       (crtc->fb->bits_per_pixel * 8));
 	crtc_pitch |= crtc_pitch << 16;
 
-	radeon_object_get_tiling_flags(obj->driver_private,
-				       &tiling_flags, NULL);
-	if (tiling_flags & RADEON_TILING_MICRO)
-		DRM_ERROR("trying to scanout microtiled buffer\n");
 
 	if (tiling_flags & RADEON_TILING_MACRO) {
 		if (ASIC_IS_R300(rdev))
@@ -530,7 +492,12 @@ int radeon_crtc_set_base(struct drm_crtc
 
 	if (old_fb && old_fb != crtc->fb) {
 		radeon_fb = to_radeon_framebuffer(old_fb);
-		radeon_gem_object_unpin(radeon_fb->obj);
+		rbo = radeon_fb->obj->driver_private;
+		r = radeon_bo_reserve(rbo, false);
+		if (unlikely(r != 0))
+			return r;
+		radeon_bo_unpin(rbo);
+		radeon_bo_unreserve(rbo);
 	}
 
 	/* Bytes per pixel may have changed */
@@ -642,12 +609,8 @@ static bool radeon_set_crtc_timing(struc
 		uint32_t crtc2_gen_cntl;
 		uint32_t disp2_merge_cntl;
 
-		/* check to see if TV DAC is enabled for another crtc and keep it enabled */
-		if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON)
-			crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
-		else
-			crtc2_gen_cntl = 0;
-
+		/* if TV DAC is enabled for another crtc and keep it enabled */
+		crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080;
 		crtc2_gen_cntl |= ((format << 8)
 				   | RADEON_CRTC2_VSYNC_DIS
 				   | RADEON_CRTC2_HSYNC_DIS
@@ -676,7 +639,8 @@ static bool radeon_set_crtc_timing(struc
 		uint32_t crtc_ext_cntl;
 		uint32_t disp_merge_cntl;
 
-		crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+		crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000;
+		crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN
 				 | (format << 8)
 				 | RADEON_CRTC_DISP_REQ_EN_B
 				 | ((mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -728,7 +692,6 @@ static void radeon_set_pll(struct drm_cr
 	uint32_t post_divider = 0;
 	uint32_t freq = 0;
 	uint8_t pll_gain;
-	int pll_flags = RADEON_PLL_LEGACY;
 	bool use_bios_divs = false;
 	/* PLL registers */
 	uint32_t pll_ref_div = 0;
@@ -762,10 +725,12 @@ static void radeon_set_pll(struct drm_cr
 	else
 		pll = &rdev->clock.p1pll;
 
+	pll->flags = RADEON_PLL_LEGACY;
+
 	if (mode->clock > 200000) /* range limits??? */
-		pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+		pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
 	else
-		pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+		pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
@@ -777,20 +742,22 @@ static void radeon_set_pll(struct drm_cr
 			}
 
 			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
-				pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+				pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
 			if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
-				struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-				struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
-				if (lvds) {
-					if (lvds->use_bios_dividers) {
-						pll_ref_div = lvds->panel_ref_divider;
-						pll_fb_post_div   = (lvds->panel_fb_divider |
-								     (lvds->panel_post_divider << 16));
-						htotal_cntl  = 0;
-						use_bios_divs = true;
+				if (!rdev->is_atom_bios) {
+					struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+					struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
+					if (lvds) {
+						if (lvds->use_bios_dividers) {
+							pll_ref_div = lvds->panel_ref_divider;
+							pll_fb_post_div   = (lvds->panel_fb_divider |
+									     (lvds->panel_post_divider << 16));
+							htotal_cntl  = 0;
+							use_bios_divs = true;
+						}
 					}
 				}
-				pll_flags |= RADEON_PLL_USE_REF_DIV;
+				pll->flags |= RADEON_PLL_USE_REF_DIV;
 			}
 		}
 	}
@@ -800,8 +767,7 @@ static void radeon_set_pll(struct drm_cr
 	if (!use_bios_divs) {
 		radeon_compute_pll(pll, mode->clock,
 				   &freq, &feedback_div, &frac_fb_div,
-				   &reference_div, &post_divider,
-				   pll_flags);
+				   &reference_div, &post_divider);
 
 		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
 			if (post_div->divider == post_divider)
@@ -1027,8 +993,9 @@ static int radeon_crtc_mode_set(struct d
 	radeon_crtc_set_base(crtc, x, y, old_fb);
 	radeon_set_crtc_timing(crtc, adjusted_mode);
 	radeon_set_pll(crtc, adjusted_mode);
+	radeon_overscan_setup(crtc, adjusted_mode);
 	if (radeon_crtc->crtc_id == 0) {
-		radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
+		radeon_legacy_rmx_mode_set(crtc, adjusted_mode);
 	} else {
 		if (radeon_crtc->rmx_type != RMX_OFF) {
 			/* FIXME: only first crtc has rmx what should we
@@ -1042,12 +1009,29 @@ static int radeon_crtc_mode_set(struct d
 
 static void radeon_crtc_prepare(struct drm_crtc *crtc)
 {
-	radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc *crtci;
+
+	/*
+	* The hardware wedges sometimes if you reconfigure one CRTC
+	* whilst another is running (see fdo bug #24611).
+	*/
+	list_for_each_entry(crtci, &dev->mode_config.crtc_list, head)
+		radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF);
 }
 
 static void radeon_crtc_commit(struct drm_crtc *crtc)
 {
-	radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+	struct drm_device *dev = crtc->dev;
+	struct drm_crtc *crtci;
+
+	/*
+	* Reenable the CRTCs that should be running.
+	*/
+	list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) {
+		if (crtci->enabled)
+			radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON);
+	}
 }
 
 static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_encoders.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@ static void radeon_legacy_lvds_dpms(stru
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man;
 	int panel_pwr_delay = 2000;
+	bool is_mac = false;
 	DRM_DEBUG("\n");
 
 	if (radeon_encoder->enc_priv) {
@@ -58,6 +59,15 @@ static void radeon_legacy_lvds_dpms(stru
 		}
 	}
 
+	/* macs (and possibly some x86 oem systems?) wire up LVDS strangely
+	 * Taken from radeonfb.
+	 */
+	if ((rdev->mode_info.connector_table == CT_IBOOK) ||
+	    (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) ||
+	    (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) ||
+	    (rdev->mode_info.connector_table == CT_POWERBOOK_VGA))
+		is_mac = true;
+
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN);
@@ -74,6 +84,8 @@ static void radeon_legacy_lvds_dpms(stru
 
 		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
 		lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON | RADEON_LVDS_BLON);
+		if (is_mac)
+			lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
 		lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
 		udelay(panel_pwr_delay * 1000);
 		WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
@@ -85,7 +97,14 @@ static void radeon_legacy_lvds_dpms(stru
 		WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
 		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
 		lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
-		lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
+		if (is_mac) {
+			lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN;
+			WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+			lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_EN);
+		} else {
+			WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+			lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
+		}
 		udelay(panel_pwr_delay * 1000);
 		WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
 		WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
@@ -136,7 +155,14 @@ static void radeon_legacy_lvds_mode_set(
 	lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
 
 	lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
-	if ((!rdev->is_atom_bios)) {
+	if (rdev->is_atom_bios) {
+		/* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl
+		 * need to call that on resume to set up the reg properly.
+		 */
+		radeon_encoder->pixel_clock = adjusted_mode->clock;
+		atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
+		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
+	} else {
 		struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv;
 		if (lvds) {
 			DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl);
@@ -147,8 +173,7 @@ static void radeon_legacy_lvds_mode_set(
 					     (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT));
 		} else
 			lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
-	} else
-		lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
+	}
 	lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
 	lvds_gen_cntl &= ~(RADEON_LVDS_ON |
 			   RADEON_LVDS_BLON |
@@ -184,9 +209,9 @@ static void radeon_legacy_lvds_mode_set(
 		radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
-static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder,
-					  struct drm_display_mode *mode,
-					  struct drm_display_mode *adjusted_mode)
+static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adjusted_mode)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
@@ -194,15 +219,24 @@ static bool radeon_legacy_lvds_mode_fixu
 	radeon_encoder_set_active_device(encoder);
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	if (radeon_encoder->rmx_type != RMX_OFF)
-		radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
+	/* get the native mode for LVDS */
+	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+		int mode_id = adjusted_mode->base.id;
+		*adjusted_mode = *native_mode;
+		adjusted_mode->hdisplay = mode->hdisplay;
+		adjusted_mode->vdisplay = mode->vdisplay;
+		adjusted_mode->crtc_hdisplay = mode->hdisplay;
+		adjusted_mode->crtc_vdisplay = mode->vdisplay;
+		adjusted_mode->base.id = mode_id;
+	}
 
 	return true;
 }
 
 static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
 	.dpms = radeon_legacy_lvds_dpms,
-	.mode_fixup = radeon_legacy_lvds_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_lvds_prepare,
 	.mode_set = radeon_legacy_lvds_mode_set,
 	.commit = radeon_legacy_lvds_commit,
@@ -214,17 +248,6 @@ static const struct drm_encoder_funcs ra
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder,
-						 struct drm_display_mode *mode,
-						 struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -410,7 +433,7 @@ static enum drm_connector_status radeon_
 
 static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = {
 	.dpms = radeon_legacy_primary_dac_dpms,
-	.mode_fixup = radeon_legacy_primary_dac_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_primary_dac_prepare,
 	.mode_set = radeon_legacy_primary_dac_mode_set,
 	.commit = radeon_legacy_primary_dac_commit,
@@ -423,16 +446,6 @@ static const struct drm_encoder_funcs ra
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder,
-					      struct drm_display_mode *mode,
-					      struct drm_display_mode *adjusted_mode)
-{
-
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -584,7 +597,7 @@ static void radeon_legacy_tmds_int_mode_
 
 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = {
 	.dpms = radeon_legacy_tmds_int_dpms,
-	.mode_fixup = radeon_legacy_tmds_int_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tmds_int_prepare,
 	.mode_set = radeon_legacy_tmds_int_mode_set,
 	.commit = radeon_legacy_tmds_int_commit,
@@ -596,17 +609,6 @@ static const struct drm_encoder_funcs ra
 	.destroy = radeon_enc_destroy,
 };
 
-static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder,
-					      struct drm_display_mode *mode,
-					      struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -697,6 +699,8 @@ static void radeon_legacy_tmds_ext_mode_
 			/*if (mode->clock > 165000)
 			  fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/
 		}
+		if (!radeon_combios_external_tmds_setup(encoder))
+			radeon_external_tmds_setup(encoder);
 	}
 
 	if (radeon_crtc->crtc_id == 0) {
@@ -724,9 +728,22 @@ static void radeon_legacy_tmds_ext_mode_
 		radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
+static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
+	if (tmds) {
+		if (tmds->i2c_bus)
+			radeon_i2c_destroy(tmds->i2c_bus);
+	}
+	kfree(radeon_encoder->enc_priv);
+	drm_encoder_cleanup(encoder);
+	kfree(radeon_encoder);
+}
+
 static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = {
 	.dpms = radeon_legacy_tmds_ext_dpms,
-	.mode_fixup = radeon_legacy_tmds_ext_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tmds_ext_prepare,
 	.mode_set = radeon_legacy_tmds_ext_mode_set,
 	.commit = radeon_legacy_tmds_ext_commit,
@@ -735,20 +752,9 @@ static const struct drm_encoder_helper_f
 
 
 static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = {
-	.destroy = radeon_enc_destroy,
+	.destroy = radeon_ext_tmds_enc_destroy,
 };
 
-static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder,
-					    struct drm_display_mode *mode,
-					    struct drm_display_mode *adjusted_mode)
-{
-	/* set the active encoder to connector routing */
-	radeon_encoder_set_active_device(encoder);
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-	return true;
-}
-
 static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -1265,7 +1271,7 @@ static enum drm_connector_status radeon_
 
 static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = {
 	.dpms = radeon_legacy_tv_dac_dpms,
-	.mode_fixup = radeon_legacy_tv_dac_mode_fixup,
+	.mode_fixup = radeon_legacy_mode_fixup,
 	.prepare = radeon_legacy_tv_dac_prepare,
 	.mode_set = radeon_legacy_tv_dac_mode_set,
 	.commit = radeon_legacy_tv_dac_commit,
@@ -1302,6 +1308,29 @@ static struct radeon_encoder_int_tmds *r
 	return tmds;
 }
 
+static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder_ext_tmds *tmds = NULL;
+	bool ret;
+
+	if (rdev->is_atom_bios)
+		return NULL;
+
+	tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL);
+
+	if (!tmds)
+		return NULL;
+
+	ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds);
+
+	if (ret == false)
+		radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds);
+
+	return tmds;
+}
+
 void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
 {
@@ -1329,7 +1358,6 @@ radeon_add_legacy_encoder(struct drm_dev
 		encoder->possible_crtcs = 0x1;
 	else
 		encoder->possible_crtcs = 0x3;
-	encoder->possible_clones = 0;
 
 	radeon_encoder->enc_priv = NULL;
 
@@ -1373,7 +1401,7 @@ radeon_add_legacy_encoder(struct drm_dev
 		drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
 		drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
 		if (!rdev->is_atom_bios)
-			radeon_combios_get_ext_tmds_info(radeon_encoder);
+			radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_legacy_tv.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,7 @@ struct radeon_tv_mode_constants {
 	unsigned pix_to_tv;
 };
 
-static const uint16_t hor_timing_NTSC[] = {
+static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = {
 	0x0007,
 	0x003f,
 	0x0263,
@@ -98,7 +98,7 @@ static const uint16_t hor_timing_NTSC[]
 	0
 };
 
-static const uint16_t vert_timing_NTSC[] = {
+static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = {
 	0x2001,
 	0x200d,
 	0x1006,
@@ -115,7 +115,7 @@ static const uint16_t vert_timing_NTSC[]
 	0
 };
 
-static const uint16_t hor_timing_PAL[] = {
+static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = {
 	0x0007,
 	0x0058,
 	0x027c,
@@ -136,7 +136,7 @@ static const uint16_t hor_timing_PAL[] =
 	0
 };
 
-static const uint16_t vert_timing_PAL[] = 	{
+static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = {
 	0x2001,
 	0x200c,
 	0x1005,
@@ -623,9 +623,9 @@ void radeon_legacy_tv_mode_set(struct dr
 	}
 	flicker_removal = (tmp + 500) / 1000;
 
-	if (flicker_removal < 3)
-		flicker_removal = 3;
-	for (i = 0; i < 6; ++i) {
+	if (flicker_removal < 2)
+		flicker_removal = 2;
+	for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) {
 		if (flicker_removal == SLOPE_limit[i])
 			break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_mode.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_mode.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_mode.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_mode.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <drm_crtc.h>
 #include <drm_mode.h>
 #include <drm_edid.h>
+#include <drm_dp_helper.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
@@ -45,32 +46,6 @@ struct radeon_device;
 #define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base)
 #define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base)
 
-enum radeon_connector_type {
-	CONNECTOR_NONE,
-	CONNECTOR_VGA,
-	CONNECTOR_DVI_I,
-	CONNECTOR_DVI_D,
-	CONNECTOR_DVI_A,
-	CONNECTOR_STV,
-	CONNECTOR_CTV,
-	CONNECTOR_LVDS,
-	CONNECTOR_DIGITAL,
-	CONNECTOR_SCART,
-	CONNECTOR_HDMI_TYPE_A,
-	CONNECTOR_HDMI_TYPE_B,
-	CONNECTOR_0XC,
-	CONNECTOR_0XD,
-	CONNECTOR_DIN,
-	CONNECTOR_DISPLAY_PORT,
-	CONNECTOR_UNSUPPORTED
-};
-
-enum radeon_dvi_type {
-	DVI_AUTO,
-	DVI_DIGITAL,
-	DVI_ANALOG
-};
-
 enum radeon_rmx_type {
 	RMX_OFF,
 	RMX_FULL,
@@ -87,26 +62,48 @@ enum radeon_tv_std {
 	TV_STD_SCART_PAL,
 	TV_STD_SECAM,
 	TV_STD_PAL_CN,
+	TV_STD_PAL_N,
 };
 
+/* radeon gpio-based i2c
+ * 1. "mask" reg and bits
+ *    grabs the gpio pins for software use
+ *    0=not held  1=held
+ * 2. "a" reg and bits
+ *    output pin value
+ *    0=low 1=high
+ * 3. "en" reg and bits
+ *    sets the pin direction
+ *    0=input 1=output
+ * 4. "y" reg and bits
+ *    input pin value
+ *    0=low 1=high
+ */
 struct radeon_i2c_bus_rec {
 	bool valid;
+	/* id used by atom */
+	uint8_t i2c_id;
+	/* can be used with hw i2c engine */
+	bool hw_capable;
+	/* uses multi-media i2c engine */
+	bool mm_i2c;
+	/* regs and bits */
 	uint32_t mask_clk_reg;
 	uint32_t mask_data_reg;
 	uint32_t a_clk_reg;
 	uint32_t a_data_reg;
-	uint32_t put_clk_reg;
-	uint32_t put_data_reg;
-	uint32_t get_clk_reg;
-	uint32_t get_data_reg;
+	uint32_t en_clk_reg;
+	uint32_t en_data_reg;
+	uint32_t y_clk_reg;
+	uint32_t y_data_reg;
 	uint32_t mask_clk_mask;
 	uint32_t mask_data_mask;
-	uint32_t put_clk_mask;
-	uint32_t put_data_mask;
-	uint32_t get_clk_mask;
-	uint32_t get_data_mask;
 	uint32_t a_clk_mask;
 	uint32_t a_data_mask;
+	uint32_t en_clk_mask;
+	uint32_t en_data_mask;
+	uint32_t y_clk_mask;
+	uint32_t y_data_mask;
 };
 
 struct radeon_tmds_pll {
@@ -128,16 +125,24 @@ struct radeon_tmds_pll {
 #define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
 #define RADEON_PLL_USE_FRAC_FB_DIV      (1 << 10)
 #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
+#define RADEON_PLL_USE_POST_DIV         (1 << 12)
 
 struct radeon_pll {
-	uint16_t reference_freq;
-	uint16_t reference_div;
+	/* reference frequency */
+	uint32_t reference_freq;
+
+	/* fixed dividers */
+	uint32_t reference_div;
+	uint32_t post_div;
+
+	/* pll in/out limits */
 	uint32_t pll_in_min;
 	uint32_t pll_in_max;
 	uint32_t pll_out_min;
 	uint32_t pll_out_max;
-	uint16_t xclk;
+	uint32_t best_vco;
 
+	/* divider limits */
 	uint32_t min_ref_div;
 	uint32_t max_ref_div;
 	uint32_t min_post_div;
@@ -146,13 +151,21 @@ struct radeon_pll {
 	uint32_t max_feedback_div;
 	uint32_t min_frac_feedback_div;
 	uint32_t max_frac_feedback_div;
-	uint32_t best_vco;
+
+	/* flags for the current clock */
+	uint32_t flags;
+
+	/* pll id */
+	uint32_t id;
 };
 
 struct radeon_i2c_chan {
-	struct drm_device *dev;
 	struct i2c_adapter adapter;
-	struct i2c_algo_bit_data algo;
+	struct drm_device *dev;
+	union {
+		struct i2c_algo_dp_aux_data dp;
+		struct i2c_algo_bit_data bit;
+	} algo;
 	struct radeon_i2c_bus_rec rec;
 };
 
@@ -170,6 +183,11 @@ enum radeon_connector_table {
 	CT_EMAC,
 };
 
+enum radeon_dvo_chip {
+	DVO_SIL164,
+	DVO_SIL1178,
+};
+
 struct radeon_mode_info {
 	struct atom_context *atom_context;
 	struct card_info *atom_card_info;
@@ -261,6 +279,13 @@ struct radeon_encoder_int_tmds {
 	struct radeon_tmds_pll tmds_pll[4];
 };
 
+struct radeon_encoder_ext_tmds {
+	/* tmds over dvo */
+	struct radeon_i2c_chan *i2c_bus;
+	uint8_t slave_addr;
+	enum radeon_dvo_chip dvo_chip;
+};
+
 /* spread spectrum */
 struct radeon_atom_ss {
 	uint16_t percentage;
@@ -274,7 +299,7 @@ struct radeon_atom_ss {
 struct radeon_encoder_atom_dig {
 	/* atom dig */
 	bool coherent_mode;
-	int dig_block;
+	int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */
 	/* atom lvds */
 	uint32_t lvds_misc;
 	uint16_t panel_pwr_delay;
@@ -297,11 +322,43 @@ struct radeon_encoder {
 	enum radeon_rmx_type rmx_type;
 	struct drm_display_mode native_mode;
 	void *enc_priv;
+	int hdmi_offset;
+	int hdmi_audio_workaround;
+	int hdmi_buffer_status;
 };
 
 struct radeon_connector_atom_dig {
 	uint32_t igp_lane_info;
 	bool linkb;
+	/* displayport */
+	struct radeon_i2c_chan *dp_i2c_bus;
+	u8 dpcd[8];
+	u8 dp_sink_type;
+	int dp_clock;
+	int dp_lane_count;
+};
+
+struct radeon_gpio_rec {
+	bool valid;
+	u8 id;
+	u32 reg;
+	u32 mask;
+};
+
+enum radeon_hpd_id {
+	RADEON_HPD_NONE = 0,
+	RADEON_HPD_1,
+	RADEON_HPD_2,
+	RADEON_HPD_3,
+	RADEON_HPD_4,
+	RADEON_HPD_5,
+	RADEON_HPD_6,
+};
+
+struct radeon_hpd {
+	enum radeon_hpd_id hpd;
+	u8 plugged_state;
+	struct radeon_gpio_rec gpio;
 };
 
 struct radeon_connector {
@@ -318,6 +375,7 @@ struct radeon_connector {
 	void *con_priv;
 	bool dac_load_detect;
 	uint16_t connector_object_id;
+	struct radeon_hpd hpd;
 };
 
 struct radeon_framebuffer {
@@ -325,10 +383,42 @@ struct radeon_framebuffer {
 	struct drm_gem_object *obj;
 };
 
+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_connector_hotplug(struct drm_connector *connector);
+extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
+extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+				       struct drm_display_mode *mode);
+extern void radeon_dp_set_link_config(struct drm_connector *connector,
+				      struct drm_display_mode *mode);
+extern void dp_link_train(struct drm_encoder *encoder,
+			  struct drm_connector *connector);
+extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
+extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
+					   int action, uint8_t lane_num,
+					   uint8_t lane_set);
+extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+				uint8_t write_byte, uint8_t *read_byte);
+
+extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
+						    struct radeon_i2c_bus_rec *rec,
+						    const char *name);
 extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 						 struct radeon_i2c_bus_rec *rec,
 						 const char *name);
 extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
+extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
+				   u8 slave_addr,
+				   u8 addr,
+				   u8 *val);
+extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c,
+				   u8 slave_addr,
+				   u8 addr,
+				   u8 val);
 extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
@@ -340,8 +430,17 @@ extern void radeon_compute_pll(struct ra
 			       uint32_t *fb_div_p,
 			       uint32_t *frac_fb_div_p,
 			       uint32_t *ref_div_p,
-			       uint32_t *post_div_p,
-			       int flags);
+			       uint32_t *post_div_p);
+
+extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
+				     uint64_t freq,
+				     uint32_t *dot_clock_p,
+				     uint32_t *fb_div_p,
+				     uint32_t *frac_fb_div_p,
+				     uint32_t *ref_div_p,
+				     uint32_t *post_div_p);
+
+extern void radeon_setup_encoder_clones(struct drm_device *dev);
 
 struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv);
@@ -349,6 +448,7 @@ struct drm_encoder *radeon_encoder_legac
 struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
+extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
@@ -364,7 +464,6 @@ extern void atombios_crtc_dpms(struct dr
 
 extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 				 struct drm_framebuffer *old_fb);
-extern void radeon_legacy_atom_set_surface(struct drm_crtc *crtc);
 
 extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
 				  struct drm_file *file_priv,
@@ -378,12 +477,16 @@ extern bool radeon_atom_get_clock_info(s
 extern bool radeon_combios_get_clock_info(struct drm_device *dev);
 extern struct radeon_encoder_atom_dig *
 radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
-bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
-				   struct radeon_encoder_int_tmds *tmds);
-bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
-					   struct radeon_encoder_int_tmds *tmds);
-bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
-					    struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
+					  struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
+						     struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
+						   struct radeon_encoder_int_tmds *tmds);
+extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
+							 struct radeon_encoder_ext_tmds *tmds);
+extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
+						       struct radeon_encoder_ext_tmds *tmds);
 extern struct radeon_encoder_primary_dac *
 radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_tv_dac *
@@ -395,6 +498,8 @@ extern struct radeon_encoder_tv_dac *
 radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_primary_dac *
 radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
+extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder);
+extern void radeon_external_tmds_setup(struct drm_encoder *encoder);
 extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
 extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
@@ -426,16 +531,13 @@ void radeon_atombios_init_crtc(struct dr
 			       struct radeon_crtc *radeon_crtc);
 void radeon_legacy_init_crtc(struct drm_device *dev,
 			     struct radeon_crtc *radeon_crtc);
-void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state);
+extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
 
 void radeon_get_clock_info(struct drm_device *dev);
 
 extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev);
 extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev);
 
-void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
-			   struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode);
 void radeon_enc_destroy(struct drm_encoder *encoder);
 void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
 void radeon_combios_asic_init(struct drm_device *dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_object.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_object.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,100 +34,62 @@
 #include "radeon_drm.h"
 #include "radeon.h"
 
-struct radeon_object {
-	struct ttm_buffer_object	tobj;
-	struct list_head		list;
-	struct radeon_device		*rdev;
-	struct drm_gem_object		*gobj;
-	struct ttm_bo_kmap_obj		kmap;
-	unsigned			pin_count;
-	uint64_t			gpu_addr;
-	void				*kptr;
-	bool				is_iomem;
-	uint32_t			tiling_flags;
-	uint32_t			pitch;
-	int				surface_reg;
-};
 
 int radeon_ttm_init(struct radeon_device *rdev);
 void radeon_ttm_fini(struct radeon_device *rdev);
+static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
 
 /*
  * To exclude mutual BO access we rely on bo_reserve exclusion, as all
  * function are calling it.
  */
 
-static int radeon_object_reserve(struct radeon_object *robj, bool interruptible)
+static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
 {
-	return ttm_bo_reserve(&robj->tobj, interruptible, false, false, 0);
-}
+	struct radeon_bo *bo;
 
-static void radeon_object_unreserve(struct radeon_object *robj)
-{
-	ttm_bo_unreserve(&robj->tobj);
+	bo = container_of(tbo, struct radeon_bo, tbo);
+	mutex_lock(&bo->rdev->gem.mutex);
+	list_del_init(&bo->list);
+	mutex_unlock(&bo->rdev->gem.mutex);
+	radeon_bo_clear_surface_reg(bo);
+	kfree(bo);
 }
 
-static void radeon_ttm_object_object_destroy(struct ttm_buffer_object *tobj)
+bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo)
 {
-	struct radeon_object *robj;
-
-	robj = container_of(tobj, struct radeon_object, tobj);
-	list_del_init(&robj->list);
-	radeon_object_clear_surface_reg(robj);
-	kfree(robj);
+	if (bo->destroy == &radeon_ttm_bo_destroy)
+		return true;
+	return false;
 }
 
-static inline void radeon_object_gpu_addr(struct radeon_object *robj)
+void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
 {
-	/* Default gpu address */
-	robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
-	if (robj->tobj.mem.mm_node == NULL) {
-		return;
-	}
-	robj->gpu_addr = ((u64)robj->tobj.mem.mm_node->start) << PAGE_SHIFT;
-	switch (robj->tobj.mem.mem_type) {
-	case TTM_PL_VRAM:
-		robj->gpu_addr += (u64)robj->rdev->mc.vram_location;
-		break;
-	case TTM_PL_TT:
-		robj->gpu_addr += (u64)robj->rdev->mc.gtt_location;
-		break;
-	default:
-		DRM_ERROR("Unknown placement %d\n", robj->tobj.mem.mem_type);
-		robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL;
-		return;
-	}
-}
+	u32 c = 0;
 
-static inline uint32_t radeon_object_flags_from_domain(uint32_t domain)
-{
-	uint32_t flags = 0;
-	if (domain & RADEON_GEM_DOMAIN_VRAM) {
-		flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-	}
-	if (domain & RADEON_GEM_DOMAIN_GTT) {
-		flags |= TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	}
-	if (domain & RADEON_GEM_DOMAIN_CPU) {
-		flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-	}
-	if (!flags) {
-		flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-	}
-	return flags;
+	rbo->placement.fpfn = 0;
+	rbo->placement.lpfn = 0;
+	rbo->placement.placement = rbo->placements;
+	rbo->placement.busy_placement = rbo->placements;
+	if (domain & RADEON_GEM_DOMAIN_VRAM)
+		rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
+					TTM_PL_FLAG_VRAM;
+	if (domain & RADEON_GEM_DOMAIN_GTT)
+		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	if (domain & RADEON_GEM_DOMAIN_CPU)
+		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+	if (!c)
+		rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+	rbo->placement.num_placement = c;
+	rbo->placement.num_busy_placement = c;
 }
 
-int radeon_object_create(struct radeon_device *rdev,
-			 struct drm_gem_object *gobj,
-			 unsigned long size,
-			 bool kernel,
-			 uint32_t domain,
-			 bool interruptible,
-			 struct radeon_object **robj_ptr)
+int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
+			unsigned long size, bool kernel, u32 domain,
+			struct radeon_bo **bo_ptr)
 {
-	struct radeon_object *robj;
+	struct radeon_bo *bo;
 	enum ttm_bo_type type;
-	uint32_t flags;
 	int r;
 
 	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -138,238 +100,161 @@ int radeon_object_create(struct radeon_d
 	} else {
 		type = ttm_bo_type_device;
 	}
-	*robj_ptr = NULL;
-	robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL);
-	if (robj == NULL) {
+	*bo_ptr = NULL;
+	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
+	if (bo == NULL)
 		return -ENOMEM;
-	}
-	robj->rdev = rdev;
-	robj->gobj = gobj;
-	robj->surface_reg = -1;
-	INIT_LIST_HEAD(&robj->list);
+	bo->rdev = rdev;
+	bo->gobj = gobj;
+	bo->surface_reg = -1;
+	INIT_LIST_HEAD(&bo->list);
 
-	flags = radeon_object_flags_from_domain(domain);
-	r = ttm_buffer_object_init(&rdev->mman.bdev, &robj->tobj, size, type, flags,
-				   0, 0, false, NULL, size,
-				   &radeon_ttm_object_object_destroy);
+	radeon_ttm_placement_from_domain(bo, domain);
+	/* Kernel allocation are uninterruptible */
+	r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
+			&bo->placement, 0, 0, !kernel, NULL, size,
+			&radeon_ttm_bo_destroy);
 	if (unlikely(r != 0)) {
-		/* ttm call radeon_ttm_object_object_destroy if error happen */
-		DRM_ERROR("Failed to allocate TTM object (%ld, 0x%08X, %u)\n",
-			  size, flags, 0);
+		if (r != -ERESTARTSYS)
+			dev_err(rdev->dev,
+				"object_init failed for (%lu, 0x%08X)\n",
+				size, domain);
 		return r;
 	}
-	*robj_ptr = robj;
+	*bo_ptr = bo;
 	if (gobj) {
-		list_add_tail(&robj->list, &rdev->gem.objects);
+		mutex_lock(&bo->rdev->gem.mutex);
+		list_add_tail(&bo->list, &rdev->gem.objects);
+		mutex_unlock(&bo->rdev->gem.mutex);
 	}
 	return 0;
 }
 
-int radeon_object_kmap(struct radeon_object *robj, void **ptr)
+int radeon_bo_kmap(struct radeon_bo *bo, void **ptr)
 {
+	bool is_iomem;
 	int r;
 
-	spin_lock(&robj->tobj.lock);
-	if (robj->kptr) {
+	if (bo->kptr) {
 		if (ptr) {
-			*ptr = robj->kptr;
+			*ptr = bo->kptr;
 		}
-		spin_unlock(&robj->tobj.lock);
 		return 0;
 	}
-	spin_unlock(&robj->tobj.lock);
-	r = ttm_bo_kmap(&robj->tobj, 0, robj->tobj.num_pages, &robj->kmap);
+	r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap);
 	if (r) {
 		return r;
 	}
-	spin_lock(&robj->tobj.lock);
-	robj->kptr = ttm_kmap_obj_virtual(&robj->kmap, &robj->is_iomem);
-	spin_unlock(&robj->tobj.lock);
+	bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
 	if (ptr) {
-		*ptr = robj->kptr;
+		*ptr = bo->kptr;
 	}
-	radeon_object_check_tiling(robj, 0, 0);
+	radeon_bo_check_tiling(bo, 0, 0);
 	return 0;
 }
 
-void radeon_object_kunmap(struct radeon_object *robj)
+void radeon_bo_kunmap(struct radeon_bo *bo)
 {
-	spin_lock(&robj->tobj.lock);
-	if (robj->kptr == NULL) {
-		spin_unlock(&robj->tobj.lock);
+	if (bo->kptr == NULL)
 		return;
-	}
-	robj->kptr = NULL;
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_check_tiling(robj, 0, 0);
-	ttm_bo_kunmap(&robj->kmap);
+	bo->kptr = NULL;
+	radeon_bo_check_tiling(bo, 0, 0);
+	ttm_bo_kunmap(&bo->kmap);
 }
 
-void radeon_object_unref(struct radeon_object **robj)
+void radeon_bo_unref(struct radeon_bo **bo)
 {
-	struct ttm_buffer_object *tobj;
+	struct ttm_buffer_object *tbo;
 
-	if ((*robj) == NULL) {
+	if ((*bo) == NULL)
 		return;
-	}
-	tobj = &((*robj)->tobj);
-	ttm_bo_unref(&tobj);
-	if (tobj == NULL) {
-		*robj = NULL;
-	}
-}
-
-int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset)
-{
-	*offset = robj->tobj.addr_space_offset;
-	return 0;
+	tbo = &((*bo)->tbo);
+	ttm_bo_unref(&tbo);
+	if (tbo == NULL)
+		*bo = NULL;
 }
 
-int radeon_object_pin(struct radeon_object *robj, uint32_t domain,
-		      uint64_t *gpu_addr)
+int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
 {
-	uint32_t flags;
-	uint32_t tmp;
-	int r;
+	int r, i;
 
-	flags = radeon_object_flags_from_domain(domain);
-	spin_lock(&robj->tobj.lock);
-	if (robj->pin_count) {
-		robj->pin_count++;
-		if (gpu_addr != NULL) {
-			*gpu_addr = robj->gpu_addr;
-		}
-		spin_unlock(&robj->tobj.lock);
+	radeon_ttm_placement_from_domain(bo, domain);
+	if (bo->pin_count) {
+		bo->pin_count++;
+		if (gpu_addr)
+			*gpu_addr = radeon_bo_gpu_offset(bo);
 		return 0;
 	}
-	spin_unlock(&robj->tobj.lock);
-	r = radeon_object_reserve(robj, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for pinning it.\n");
-		return r;
-	}
-	tmp = robj->tobj.mem.placement;
-	ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM);
-	robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING;
-	r = ttm_buffer_object_validate(&robj->tobj,
-				       robj->tobj.proposed_placement,
-				       false, false);
-	radeon_object_gpu_addr(robj);
-	if (gpu_addr != NULL) {
-		*gpu_addr = robj->gpu_addr;
-	}
-	robj->pin_count = 1;
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to pin object.\n");
-	}
-	radeon_object_unreserve(robj);
-	return r;
-}
-
-void radeon_object_unpin(struct radeon_object *robj)
-{
-	uint32_t flags;
-	int r;
-
-	spin_lock(&robj->tobj.lock);
-	if (!robj->pin_count) {
-		spin_unlock(&robj->tobj.lock);
-		printk(KERN_WARNING "Unpin not necessary for %p !\n", robj);
-		return;
-	}
-	robj->pin_count--;
-	if (robj->pin_count) {
-		spin_unlock(&robj->tobj.lock);
-		return;
-	}
-	spin_unlock(&robj->tobj.lock);
-	r = radeon_object_reserve(robj, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for unpinning it.\n");
-		return;
-	}
-	flags = robj->tobj.mem.placement;
-	robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT;
-	r = ttm_buffer_object_validate(&robj->tobj,
-				       robj->tobj.proposed_placement,
-				       false, false);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to unpin buffer.\n");
-	}
-	radeon_object_unreserve(robj);
-}
-
-int radeon_object_wait(struct radeon_object *robj)
-{
-	int r = 0;
-
-	/* FIXME: should use block reservation instead */
-	r = radeon_object_reserve(robj, true);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for waiting.\n");
-		return r;
-	}
-	spin_lock(&robj->tobj.lock);
-	if (robj->tobj.sync_obj) {
-		r = ttm_bo_wait(&robj->tobj, true, true, false);
+	radeon_ttm_placement_from_domain(bo, domain);
+	for (i = 0; i < bo->placement.num_placement; i++)
+		bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
+	if (likely(r == 0)) {
+		bo->pin_count = 1;
+		if (gpu_addr != NULL)
+			*gpu_addr = radeon_bo_gpu_offset(bo);
 	}
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_unreserve(robj);
+	if (unlikely(r != 0))
+		dev_err(bo->rdev->dev, "%p pin failed\n", bo);
 	return r;
 }
 
-int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement)
+int radeon_bo_unpin(struct radeon_bo *bo)
 {
-	int r = 0;
+	int r, i;
 
-	r = radeon_object_reserve(robj, true);
-	if (unlikely(r != 0)) {
-		DRM_ERROR("radeon: failed to reserve object for waiting.\n");
-		return r;
-	}
-	spin_lock(&robj->tobj.lock);
-	*cur_placement = robj->tobj.mem.mem_type;
-	if (robj->tobj.sync_obj) {
-		r = ttm_bo_wait(&robj->tobj, true, true, true);
+	if (!bo->pin_count) {
+		dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo);
+		return 0;
 	}
-	spin_unlock(&robj->tobj.lock);
-	radeon_object_unreserve(robj);
+	bo->pin_count--;
+	if (bo->pin_count)
+		return 0;
+	for (i = 0; i < bo->placement.num_placement; i++)
+		bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
+	if (unlikely(r != 0))
+		dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo);
 	return r;
 }
 
-int radeon_object_evict_vram(struct radeon_device *rdev)
+int radeon_bo_evict_vram(struct radeon_device *rdev)
 {
-	if (rdev->flags & RADEON_IS_IGP) {
-		/* Useless to evict on IGP chips */
-		return 0;
+	/* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */
+	if (0 && (rdev->flags & RADEON_IS_IGP)) {
+		if (rdev->mc.igp_sideport_enabled == false)
+			/* Useless to evict on IGP chips */
+			return 0;
 	}
 	return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 }
 
-void radeon_object_force_delete(struct radeon_device *rdev)
+void radeon_bo_force_delete(struct radeon_device *rdev)
 {
-	struct radeon_object *robj, *n;
+	struct radeon_bo *bo, *n;
 	struct drm_gem_object *gobj;
 
 	if (list_empty(&rdev->gem.objects)) {
 		return;
 	}
-	DRM_ERROR("Userspace still has active objects !\n");
-	list_for_each_entry_safe(robj, n, &rdev->gem.objects, list) {
+	dev_err(rdev->dev, "Userspace still has active objects !\n");
+	list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) {
 		mutex_lock(&rdev->ddev->struct_mutex);
-		gobj = robj->gobj;
-		DRM_ERROR("Force free for (%p,%p,%lu,%lu)\n",
-			  gobj, robj, (unsigned long)gobj->size,
-			  *((unsigned long *)&gobj->refcount));
-		list_del_init(&robj->list);
-		radeon_object_unref(&robj);
+		gobj = bo->gobj;
+		dev_err(rdev->dev, "%p %p %lu %lu force free\n",
+			gobj, bo, (unsigned long)gobj->size,
+			*((unsigned long *)&gobj->refcount));
+		mutex_lock(&bo->rdev->gem.mutex);
+		list_del_init(&bo->list);
+		mutex_unlock(&bo->rdev->gem.mutex);
+		radeon_bo_unref(&bo);
 		gobj->driver_private = NULL;
 		drm_gem_object_unreference(gobj);
 		mutex_unlock(&rdev->ddev->struct_mutex);
 	}
 }
 
-int radeon_object_init(struct radeon_device *rdev)
+int radeon_bo_init(struct radeon_device *rdev)
 {
 	/* Add an MTRR for the VRAM */
 	rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
@@ -382,13 +267,13 @@ int radeon_object_init(struct radeon_dev
 	return radeon_ttm_init(rdev);
 }
 
-void radeon_object_fini(struct radeon_device *rdev)
+void radeon_bo_fini(struct radeon_device *rdev)
 {
 	radeon_ttm_fini(rdev);
 }
 
-void radeon_object_list_add_object(struct radeon_object_list *lobj,
-				   struct list_head *head)
+void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
+				struct list_head *head)
 {
 	if (lobj->wdomain) {
 		list_add(&lobj->list, head);
@@ -397,125 +282,102 @@ void radeon_object_list_add_object(struc
 	}
 }
 
-int radeon_object_list_reserve(struct list_head *head)
+int radeon_bo_list_reserve(struct list_head *head)
 {
-	struct radeon_object_list *lobj;
+	struct radeon_bo_list *lobj;
 	int r;
 
 	list_for_each_entry(lobj, head, list){
-		if (!lobj->robj->pin_count) {
-			r = radeon_object_reserve(lobj->robj, true);
-			if (unlikely(r != 0)) {
-				DRM_ERROR("radeon: failed to reserve object.\n");
-				return r;
-			}
-		} else {
-		}
+		r = radeon_bo_reserve(lobj->bo, false);
+		if (unlikely(r != 0))
+			return r;
 	}
 	return 0;
 }
 
-void radeon_object_list_unreserve(struct list_head *head)
+void radeon_bo_list_unreserve(struct list_head *head)
 {
-	struct radeon_object_list *lobj;
+	struct radeon_bo_list *lobj;
 
 	list_for_each_entry(lobj, head, list) {
-		if (!lobj->robj->pin_count) {
-			radeon_object_unreserve(lobj->robj);
-		}
+		/* only unreserve object we successfully reserved */
+		if (radeon_bo_is_reserved(lobj->bo))
+			radeon_bo_unreserve(lobj->bo);
 	}
 }
 
-int radeon_object_list_validate(struct list_head *head, void *fence)
+int radeon_bo_list_validate(struct list_head *head)
 {
-	struct radeon_object_list *lobj;
-	struct radeon_object *robj;
-	struct radeon_fence *old_fence = NULL;
+	struct radeon_bo_list *lobj;
+	struct radeon_bo *bo;
 	int r;
 
-	r = radeon_object_list_reserve(head);
+	r = radeon_bo_list_reserve(head);
 	if (unlikely(r != 0)) {
-		radeon_object_list_unreserve(head);
 		return r;
 	}
 	list_for_each_entry(lobj, head, list) {
-		robj = lobj->robj;
-		if (!robj->pin_count) {
+		bo = lobj->bo;
+		if (!bo->pin_count) {
 			if (lobj->wdomain) {
-				robj->tobj.proposed_placement =
-					radeon_object_flags_from_domain(lobj->wdomain);
+				radeon_ttm_placement_from_domain(bo,
+								lobj->wdomain);
 			} else {
-				robj->tobj.proposed_placement =
-					radeon_object_flags_from_domain(lobj->rdomain);
+				radeon_ttm_placement_from_domain(bo,
+								lobj->rdomain);
 			}
-			r = ttm_buffer_object_validate(&robj->tobj,
-						       robj->tobj.proposed_placement,
-						       true, false);
-			if (unlikely(r)) {
-				DRM_ERROR("radeon: failed to validate.\n");
+			r = ttm_bo_validate(&bo->tbo, &bo->placement,
+						true, false);
+			if (unlikely(r))
 				return r;
-			}
-			radeon_object_gpu_addr(robj);
-		}
-		lobj->gpu_offset = robj->gpu_addr;
-		lobj->tiling_flags = robj->tiling_flags;
-		if (fence) {
-			old_fence = (struct radeon_fence *)robj->tobj.sync_obj;
-			robj->tobj.sync_obj = radeon_fence_ref(fence);
-			robj->tobj.sync_obj_arg = NULL;
-		}
-		if (old_fence) {
-			radeon_fence_unref(&old_fence);
 		}
+		lobj->gpu_offset = radeon_bo_gpu_offset(bo);
+		lobj->tiling_flags = bo->tiling_flags;
 	}
 	return 0;
 }
 
-void radeon_object_list_unvalidate(struct list_head *head)
+void radeon_bo_list_fence(struct list_head *head, void *fence)
 {
-	struct radeon_object_list *lobj;
+	struct radeon_bo_list *lobj;
+	struct radeon_bo *bo;
 	struct radeon_fence *old_fence = NULL;
 
 	list_for_each_entry(lobj, head, list) {
-		old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
-		lobj->robj->tobj.sync_obj = NULL;
+		bo = lobj->bo;
+		spin_lock(&bo->tbo.lock);
+		old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
+		bo->tbo.sync_obj = radeon_fence_ref(fence);
+		bo->tbo.sync_obj_arg = NULL;
+		spin_unlock(&bo->tbo.lock);
 		if (old_fence) {
 			radeon_fence_unref(&old_fence);
 		}
 	}
-	radeon_object_list_unreserve(head);
 }
 
-void radeon_object_list_clean(struct list_head *head)
-{
-	radeon_object_list_unreserve(head);
-}
-
-int radeon_object_fbdev_mmap(struct radeon_object *robj,
+int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
 			     struct vm_area_struct *vma)
 {
-	return ttm_fbdev_mmap(vma, &robj->tobj);
-}
-
-unsigned long radeon_object_size(struct radeon_object *robj)
-{
-	return robj->tobj.num_pages << PAGE_SHIFT;
+	return ttm_fbdev_mmap(vma, &bo->tbo);
 }
 
-int radeon_object_get_surface_reg(struct radeon_object *robj)
+int radeon_bo_get_surface_reg(struct radeon_bo *bo)
 {
-	struct radeon_device *rdev = robj->rdev;
+	struct radeon_device *rdev = bo->rdev;
 	struct radeon_surface_reg *reg;
-	struct radeon_object *old_object;
+	struct radeon_bo *old_object;
 	int steal;
 	int i;
 
-	if (!robj->tiling_flags)
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
+
+	if (!bo->tiling_flags)
 		return 0;
 
-	if (robj->surface_reg >= 0) {
-		reg = &rdev->surface_regs[robj->surface_reg];
-		i = robj->surface_reg;
+	if (bo->surface_reg >= 0) {
+		reg = &rdev->surface_regs[bo->surface_reg];
+		i = bo->surface_reg;
 		goto out;
 	}
 
@@ -523,10 +385,10 @@ int radeon_object_get_surface_reg(struct
 	for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
 
 		reg = &rdev->surface_regs[i];
-		if (!reg->robj)
+		if (!reg->bo)
 			break;
 
-		old_object = reg->robj;
+		old_object = reg->bo;
 		if (old_object->pin_count == 0)
 			steal = i;
 	}
@@ -537,91 +399,107 @@ int radeon_object_get_surface_reg(struct
 			return -ENOMEM;
 		/* find someone with a surface reg and nuke their BO */
 		reg = &rdev->surface_regs[steal];
-		old_object = reg->robj;
+		old_object = reg->bo;
 		/* blow away the mapping */
 		DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object);
-		ttm_bo_unmap_virtual(&old_object->tobj);
+		ttm_bo_unmap_virtual(&old_object->tbo);
 		old_object->surface_reg = -1;
 		i = steal;
 	}
 
-	robj->surface_reg = i;
-	reg->robj = robj;
+	bo->surface_reg = i;
+	reg->bo = bo;
 
 out:
-	radeon_set_surface_reg(rdev, i, robj->tiling_flags, robj->pitch,
-			       robj->tobj.mem.mm_node->start << PAGE_SHIFT,
-			       robj->tobj.num_pages << PAGE_SHIFT);
+	radeon_set_surface_reg(rdev, i, bo->tiling_flags, bo->pitch,
+			       bo->tbo.mem.mm_node->start << PAGE_SHIFT,
+			       bo->tbo.num_pages << PAGE_SHIFT);
 	return 0;
 }
 
-void radeon_object_clear_surface_reg(struct radeon_object *robj)
+static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
 {
-	struct radeon_device *rdev = robj->rdev;
+	struct radeon_device *rdev = bo->rdev;
 	struct radeon_surface_reg *reg;
 
-	if (robj->surface_reg == -1)
+	if (bo->surface_reg == -1)
 		return;
 
-	reg = &rdev->surface_regs[robj->surface_reg];
-	radeon_clear_surface_reg(rdev, robj->surface_reg);
+	reg = &rdev->surface_regs[bo->surface_reg];
+	radeon_clear_surface_reg(rdev, bo->surface_reg);
 
-	reg->robj = NULL;
-	robj->surface_reg = -1;
+	reg->bo = NULL;
+	bo->surface_reg = -1;
 }
 
-void radeon_object_set_tiling_flags(struct radeon_object *robj,
-				    uint32_t tiling_flags, uint32_t pitch)
+int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
+				uint32_t tiling_flags, uint32_t pitch)
 {
-	robj->tiling_flags = tiling_flags;
-	robj->pitch = pitch;
+	int r;
+
+	r = radeon_bo_reserve(bo, false);
+	if (unlikely(r != 0))
+		return r;
+	bo->tiling_flags = tiling_flags;
+	bo->pitch = pitch;
+	radeon_bo_unreserve(bo);
+	return 0;
 }
 
-void radeon_object_get_tiling_flags(struct radeon_object *robj,
-				    uint32_t *tiling_flags,
-				    uint32_t *pitch)
+void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
+				uint32_t *tiling_flags,
+				uint32_t *pitch)
 {
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
 	if (tiling_flags)
-		*tiling_flags = robj->tiling_flags;
+		*tiling_flags = bo->tiling_flags;
 	if (pitch)
-		*pitch = robj->pitch;
+		*pitch = bo->pitch;
 }
 
-int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
-			       bool force_drop)
+int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
+				bool force_drop)
 {
-	if (!(robj->tiling_flags & RADEON_TILING_SURFACE))
+	BUG_ON(!atomic_read(&bo->tbo.reserved));
+
+	if (!(bo->tiling_flags & RADEON_TILING_SURFACE))
 		return 0;
 
 	if (force_drop) {
-		radeon_object_clear_surface_reg(robj);
+		radeon_bo_clear_surface_reg(bo);
 		return 0;
 	}
 
-	if (robj->tobj.mem.mem_type != TTM_PL_VRAM) {
+	if (bo->tbo.mem.mem_type != TTM_PL_VRAM) {
 		if (!has_moved)
 			return 0;
 
-		if (robj->surface_reg >= 0)
-			radeon_object_clear_surface_reg(robj);
+		if (bo->surface_reg >= 0)
+			radeon_bo_clear_surface_reg(bo);
 		return 0;
 	}
 
-	if ((robj->surface_reg >= 0) && !has_moved)
+	if ((bo->surface_reg >= 0) && !has_moved)
 		return 0;
 
-	return radeon_object_get_surface_reg(robj);
+	return radeon_bo_get_surface_reg(bo);
 }
 
 void radeon_bo_move_notify(struct ttm_buffer_object *bo,
-			  struct ttm_mem_reg *mem)
+			   struct ttm_mem_reg *mem)
 {
-	struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
-	radeon_object_check_tiling(robj, 0, 1);
+	struct radeon_bo *rbo;
+	if (!radeon_ttm_bo_is_radeon_bo(bo))
+		return;
+	rbo = container_of(bo, struct radeon_bo, tbo);
+	radeon_bo_check_tiling(rbo, 0, 1);
 }
 
 void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
 {
-	struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
-	radeon_object_check_tiling(robj, 0, 0);
+	struct radeon_bo *rbo;
+	if (!radeon_ttm_bo_is_radeon_bo(bo))
+		return;
+	rbo = container_of(bo, struct radeon_bo, tbo);
+	radeon_bo_check_tiling(rbo, 0, 0);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_object.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_object.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_object.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,19 +28,146 @@
 #ifndef __RADEON_OBJECT_H__
 #define __RADEON_OBJECT_H__
 
-#include <ttm/ttm_bo_api.h>
-#include <ttm/ttm_bo_driver.h>
-#include <ttm/ttm_placement.h>
-#include <ttm/ttm_module.h>
+#include <drm/radeon_drm.h>
+#include "radeon.h"
 
-/*
- * TTM.
+/**
+ * radeon_mem_type_to_domain - return domain corresponding to mem_type
+ * @mem_type:	ttm memory type
+ *
+ * Returns corresponding domain of the ttm mem_type
  */
-struct radeon_mman {
-	struct ttm_bo_global_ref        bo_global_ref;
-	struct ttm_global_reference	mem_global_ref;
-	bool				mem_global_referenced;
-	struct ttm_bo_device		bdev;
-};
+static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
+{
+	switch (mem_type) {
+	case TTM_PL_VRAM:
+		return RADEON_GEM_DOMAIN_VRAM;
+	case TTM_PL_TT:
+		return RADEON_GEM_DOMAIN_GTT;
+	case TTM_PL_SYSTEM:
+		return RADEON_GEM_DOMAIN_CPU;
+	default:
+		break;
+	}
+	return 0;
+}
+
+/**
+ * radeon_bo_reserve - reserve bo
+ * @bo:		bo structure
+ * @no_wait:		don't sleep while trying to reserve (return -EBUSY)
+ *
+ * Returns:
+ * -EBUSY: buffer is busy and @no_wait is true
+ * -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_wait)
+{
+	int r;
+
+	r = ttm_bo_reserve(&bo->tbo, true, no_wait, 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)
+{
+	ttm_bo_unreserve(&bo->tbo);
+}
 
+/**
+ * radeon_bo_gpu_offset - return GPU offset of bo
+ * @bo:	radeon object for which we query the offset
+ *
+ * Returns current GPU offset of the object.
+ *
+ * Note: object should either be pinned or reserved when calling this
+ * function, it might be usefull to add check for this for debugging.
+ */
+static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
+{
+	return bo->tbo.offset;
+}
+
+static inline unsigned long radeon_bo_size(struct radeon_bo *bo)
+{
+	return bo->tbo.num_pages << PAGE_SHIFT;
+}
+
+static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
+{
+	return !!atomic_read(&bo->tbo.reserved);
+}
+
+/**
+ * radeon_bo_mmap_offset - return mmap offset of bo
+ * @bo:	radeon object for which we query the offset
+ *
+ * Returns mmap offset of the object.
+ *
+ * Note: addr_space_offset is constant after ttm bo init thus isn't protected
+ * by any lock.
+ */
+static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
+{
+	return bo->tbo.addr_space_offset;
+}
+
+static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
+					bool no_wait)
+{
+	int r;
+
+	r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+	if (unlikely(r != 0)) {
+		if (r != -ERESTARTSYS)
+			dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
+		return r;
+	}
+	spin_lock(&bo->tbo.lock);
+	if (mem_type)
+		*mem_type = bo->tbo.mem.mem_type;
+	if (bo->tbo.sync_obj)
+		r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
+	spin_unlock(&bo->tbo.lock);
+	ttm_bo_unreserve(&bo->tbo);
+	return r;
+}
+
+extern int radeon_bo_create(struct radeon_device *rdev,
+				struct drm_gem_object *gobj, unsigned long size,
+				bool kernel, u32 domain,
+				struct radeon_bo **bo_ptr);
+extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
+extern void radeon_bo_kunmap(struct radeon_bo *bo);
+extern void radeon_bo_unref(struct radeon_bo **bo);
+extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
+extern int radeon_bo_unpin(struct radeon_bo *bo);
+extern int radeon_bo_evict_vram(struct radeon_device *rdev);
+extern void radeon_bo_force_delete(struct radeon_device *rdev);
+extern int radeon_bo_init(struct radeon_device *rdev);
+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_reserve(struct list_head *head);
+extern void radeon_bo_list_unreserve(struct list_head *head);
+extern int radeon_bo_list_validate(struct list_head *head);
+extern void radeon_bo_list_fence(struct list_head *head, void *fence);
+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,
+				u32 tiling_flags, u32 pitch);
+extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
+				u32 *tiling_flags, u32 *pitch);
+extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
+				bool force_drop);
+extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
+					struct ttm_mem_reg *mem);
+extern void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
+extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_pm.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_pm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_pm.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@ int radeon_debugfs_pm_init(struct radeon
 int radeon_pm_init(struct radeon_device *rdev)
 {
 	if (radeon_debugfs_pm_init(rdev)) {
-		DRM_ERROR("Failed to register debugfs file for CP !\n");
+		DRM_ERROR("Failed to register debugfs file for PM!\n");
 	}
 
 	return 0;
@@ -44,8 +44,11 @@ static int radeon_debugfs_pm_info(struct
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
-	seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev));
-	seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev));
+	seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk);
+	seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
+	seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
+	if (rdev->asic->get_memory_clock)
+		seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -887,6 +887,7 @@
 #       define RADEON_FP_PANEL_FORMAT          (1 <<  3)
 #       define RADEON_FP_EN_TMDS               (1 <<  7)
 #       define RADEON_FP_DETECT_SENSE          (1 <<  8)
+#       define RADEON_FP_DETECT_INT_POL        (1 <<  9)
 #       define R200_FP_SOURCE_SEL_MASK         (3 <<  10)
 #       define R200_FP_SOURCE_SEL_CRTC1        (0 <<  10)
 #       define R200_FP_SOURCE_SEL_CRTC2        (1 <<  10)
@@ -894,6 +895,7 @@
 #       define R200_FP_SOURCE_SEL_TRANS        (3 <<  10)
 #       define RADEON_FP_SEL_CRTC1             (0 << 13)
 #       define RADEON_FP_SEL_CRTC2             (1 << 13)
+#       define R300_HPD_SEL(x)                 ((x) << 13)
 #       define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15)
 #       define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
 #       define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17)
@@ -909,6 +911,7 @@
 #       define RADEON_FP2_ON                   (1 <<  2)
 #       define RADEON_FP2_PANEL_FORMAT         (1 <<  3)
 #       define RADEON_FP2_DETECT_SENSE         (1 <<  8)
+#       define RADEON_FP2_DETECT_INT_POL       (1 <<  9)
 #       define R200_FP2_SOURCE_SEL_MASK        (3 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC1       (0 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC2       (1 << 10)
@@ -988,14 +991,20 @@
 
 #define RADEON_GEN_INT_CNTL                 0x0040
 #	define RADEON_CRTC_VBLANK_MASK		(1 << 0)
+#	define RADEON_FP_DETECT_MASK		(1 << 4)
 #	define RADEON_CRTC2_VBLANK_MASK		(1 << 9)
+#	define RADEON_FP2_DETECT_MASK		(1 << 10)
 #	define RADEON_SW_INT_ENABLE		(1 << 25)
 #define RADEON_GEN_INT_STATUS               0x0044
 #	define AVIVO_DISPLAY_INT_STATUS		(1 << 0)
 #	define RADEON_CRTC_VBLANK_STAT		(1 << 0)
 #	define RADEON_CRTC_VBLANK_STAT_ACK	(1 << 0)
+#	define RADEON_FP_DETECT_STAT		(1 << 4)
+#	define RADEON_FP_DETECT_STAT_ACK	(1 << 4)
 #	define RADEON_CRTC2_VBLANK_STAT		(1 << 9)
 #	define RADEON_CRTC2_VBLANK_STAT_ACK	(1 << 9)
+#	define RADEON_FP2_DETECT_STAT		(1 << 10)
+#	define RADEON_FP2_DETECT_STAT_ACK	(1 << 10)
 #	define RADEON_SW_INT_FIRE		(1 << 26)
 #	define RADEON_SW_INT_TEST		(1 << 25)
 #	define RADEON_SW_INT_TEST_ACK		(1 << 25)
@@ -1051,20 +1060,25 @@
 
        /* Multimedia I2C bus */
 #define RADEON_I2C_CNTL_0		    0x0090
-#define RADEON_I2C_DONE (1<<0)
-#define RADEON_I2C_NACK (1<<1)
-#define RADEON_I2C_HALT (1<<2)
-#define RADEON_I2C_SOFT_RST (1<<5)
-#define RADEON_I2C_DRIVE_EN (1<<6)
-#define RADEON_I2C_DRIVE_SEL (1<<7)
-#define RADEON_I2C_START (1<<8)
-#define RADEON_I2C_STOP (1<<9)
-#define RADEON_I2C_RECEIVE (1<<10)
-#define RADEON_I2C_ABORT (1<<11)
-#define RADEON_I2C_GO (1<<12)
+#define RADEON_I2C_DONE                     (1 << 0)
+#define RADEON_I2C_NACK                     (1 << 1)
+#define RADEON_I2C_HALT                     (1 << 2)
+#define RADEON_I2C_SOFT_RST                 (1 << 5)
+#define RADEON_I2C_DRIVE_EN                 (1 << 6)
+#define RADEON_I2C_DRIVE_SEL                (1 << 7)
+#define RADEON_I2C_START                    (1 << 8)
+#define RADEON_I2C_STOP                     (1 << 9)
+#define RADEON_I2C_RECEIVE                  (1 << 10)
+#define RADEON_I2C_ABORT                    (1 << 11)
+#define RADEON_I2C_GO                       (1 << 12)
+#define RADEON_I2C_PRESCALE_SHIFT           16
 #define RADEON_I2C_CNTL_1                   0x0094
-#define RADEON_I2C_SEL         (1<<16)
-#define RADEON_I2C_EN          (1<<17)
+#define RADEON_I2C_DATA_COUNT_SHIFT         0
+#define RADEON_I2C_ADDR_COUNT_SHIFT         4
+#define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT   8
+#define RADEON_I2C_SEL                      (1 << 16)
+#define RADEON_I2C_EN                       (1 << 17)
+#define RADEON_I2C_TIME_LIMIT_SHIFT         24
 #define RADEON_I2C_DATA			    0x0098
 
 #define RADEON_DVI_I2C_CNTL_0		    0x02e0
@@ -1072,7 +1086,7 @@
 #       define R200_SEL_DDC1                0 /* 0x60 - VGA_DDC */
 #       define R200_SEL_DDC2                1 /* 0x64 - DVI_DDC */
 #       define R200_SEL_DDC3                2 /* 0x68 - MONID_DDC */
-#define RADEON_DVI_I2C_CNTL_1               0x02e4 /* ? */
+#define RADEON_DVI_I2C_CNTL_1               0x02e4
 #define RADEON_DVI_I2C_DATA		    0x02e8
 
 #define RADEON_INTERRUPT_LINE               0x0f3c /* PCI */
@@ -1143,15 +1157,16 @@
 #       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
-#define RADEON_LCD_GPIO_MASK                0x01a0
-#define RADEON_GPIOPAD_EN                   0x01a0
-#define RADEON_LCD_GPIO_Y_REG               0x01a4
-#define RADEON_MDGPIO_A_REG                 0x01ac
-#define RADEON_MDGPIO_EN_REG                0x01b0
-#define RADEON_MDGPIO_MASK                  0x0198
+
 #define RADEON_GPIOPAD_MASK                 0x0198
 #define RADEON_GPIOPAD_A		    0x019c
-#define RADEON_MDGPIO_Y_REG                 0x01b4
+#define RADEON_GPIOPAD_EN                   0x01a0
+#define RADEON_GPIOPAD_Y                    0x01a4
+#define RADEON_MDGPIO_MASK                  0x01a8
+#define RADEON_MDGPIO_A                     0x01ac
+#define RADEON_MDGPIO_EN                    0x01b0
+#define RADEON_MDGPIO_Y                     0x01b4
+
 #define RADEON_MEM_ADDR_CONFIG              0x0148
 #define RADEON_MEM_BASE                     0x0f10 /* PCI */
 #define RADEON_MEM_CNTL                     0x0140
@@ -1360,6 +1375,9 @@
 #define RADEON_OVR_CLR                      0x0230
 #define RADEON_OVR_WID_LEFT_RIGHT           0x0234
 #define RADEON_OVR_WID_TOP_BOTTOM           0x0238
+#define RADEON_OVR2_CLR                     0x0330
+#define RADEON_OVR2_WID_LEFT_RIGHT          0x0334
+#define RADEON_OVR2_WID_TOP_BOTTOM          0x0338
 
 /* first capture unit */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ring.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ring.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ring.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ring.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,68 +41,55 @@ int radeon_ib_get(struct radeon_device *
 {
 	struct radeon_fence *fence;
 	struct radeon_ib *nib;
-	unsigned long i;
-	int r = 0;
+	int r = 0, i, c;
 
 	*ib = NULL;
 	r = radeon_fence_create(rdev, &fence);
 	if (r) {
-		DRM_ERROR("failed to create fence for new IB\n");
+		dev_err(rdev->dev, "failed to create fence for new IB\n");
 		return r;
 	}
 	mutex_lock(&rdev->ib_pool.mutex);
-	i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
-	if (i < RADEON_IB_POOL_SIZE) {
-		set_bit(i, rdev->ib_pool.alloc_bm);
-		rdev->ib_pool.ibs[i].length_dw = 0;
-		*ib = &rdev->ib_pool.ibs[i];
-		mutex_unlock(&rdev->ib_pool.mutex);
-		goto out;
+	for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
+		i &= (RADEON_IB_POOL_SIZE - 1);
+		if (rdev->ib_pool.ibs[i].free) {
+			nib = &rdev->ib_pool.ibs[i];
+			break;
+		}
 	}
-	if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
-		/* we go do nothings here */
+	if (nib == NULL) {
+		/* This should never happen, it means we allocated all
+		 * IB and haven't scheduled one yet, return EBUSY to
+		 * userspace hoping that on ioctl recall we get better
+		 * luck
+		 */
+		dev_err(rdev->dev, "no free indirect buffer !\n");
 		mutex_unlock(&rdev->ib_pool.mutex);
-		DRM_ERROR("all IB allocated none scheduled.\n");
-		r = -EINVAL;
-		goto out;
+		radeon_fence_unref(&fence);
+		return -EBUSY;
 	}
-	/* get the first ib on the scheduled list */
-	nib = list_entry(rdev->ib_pool.scheduled_ibs.next,
-			 struct radeon_ib, list);
-	if (nib->fence == NULL) {
-		/* we go do nothings here */
+	rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
+	nib->free = false;
+	if (nib->fence) {
 		mutex_unlock(&rdev->ib_pool.mutex);
-		DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
-		r = -EINVAL;
-		goto out;
-	}
-	mutex_unlock(&rdev->ib_pool.mutex);
-
-	r = radeon_fence_wait(nib->fence, false);
-	if (r) {
-		DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
-			  (unsigned long)nib->gpu_addr, nib->length_dw);
-		DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n");
-		goto out;
+		r = radeon_fence_wait(nib->fence, false);
+		if (r) {
+			dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
+				nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
+			mutex_lock(&rdev->ib_pool.mutex);
+			nib->free = true;
+			mutex_unlock(&rdev->ib_pool.mutex);
+			radeon_fence_unref(&fence);
+			return r;
+		}
+		mutex_lock(&rdev->ib_pool.mutex);
 	}
 	radeon_fence_unref(&nib->fence);
-
+	nib->fence = fence;
 	nib->length_dw = 0;
-
-	/* scheduled list is accessed here */
-	mutex_lock(&rdev->ib_pool.mutex);
-	list_del(&nib->list);
-	INIT_LIST_HEAD(&nib->list);
 	mutex_unlock(&rdev->ib_pool.mutex);
-
 	*ib = nib;
-out:
-	if (r) {
-		radeon_fence_unref(&fence);
-	} else {
-		(*ib)->fence = fence;
-	}
-	return r;
+	return 0;
 }
 
 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
@@ -113,19 +100,10 @@ void radeon_ib_free(struct radeon_device
 	if (tmp == NULL) {
 		return;
 	}
-	mutex_lock(&rdev->ib_pool.mutex);
-	if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) {
-		/* IB is scheduled & not signaled don't do anythings */
-		mutex_unlock(&rdev->ib_pool.mutex);
-		return;
-	}
-	list_del(&tmp->list);
-	INIT_LIST_HEAD(&tmp->list);
-	if (tmp->fence)
+	if (!tmp->fence->emited)
 		radeon_fence_unref(&tmp->fence);
-
-	tmp->length_dw = 0;
-	clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
+	mutex_lock(&rdev->ib_pool.mutex);
+	tmp->free = true;
 	mutex_unlock(&rdev->ib_pool.mutex);
 }
 
@@ -135,7 +113,7 @@ int radeon_ib_schedule(struct radeon_dev
 
 	if (!ib->length_dw || !rdev->cp.ready) {
 		/* TODO: Nothings in the ib we should report. */
-		DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx);
+		DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
 		return -EINVAL;
 	}
 
@@ -148,7 +126,8 @@ int radeon_ib_schedule(struct radeon_dev
 	radeon_ring_ib_execute(rdev, ib);
 	radeon_fence_emit(rdev, ib->fence);
 	mutex_lock(&rdev->ib_pool.mutex);
-	list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
+	/* once scheduled IB is considered free and protected by the fence */
+	ib->free = true;
 	mutex_unlock(&rdev->ib_pool.mutex);
 	radeon_ring_unlock_commit(rdev);
 	return 0;
@@ -164,20 +143,24 @@ int radeon_ib_pool_init(struct radeon_de
 	if (rdev->ib_pool.robj)
 		return 0;
 	/* Allocate 1M object buffer */
-	INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
-	r = radeon_object_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
-				 true, RADEON_GEM_DOMAIN_GTT,
-				 false, &rdev->ib_pool.robj);
+	r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
+				true, RADEON_GEM_DOMAIN_GTT,
+				&rdev->ib_pool.robj);
 	if (r) {
 		DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
 		return r;
 	}
-	r = radeon_object_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
+	r = radeon_bo_reserve(rdev->ib_pool.robj, false);
+	if (unlikely(r != 0))
+		return r;
+	r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr);
 	if (r) {
+		radeon_bo_unreserve(rdev->ib_pool.robj);
 		DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r);
 		return r;
 	}
-	r = radeon_object_kmap(rdev->ib_pool.robj, &ptr);
+	r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
+	radeon_bo_unreserve(rdev->ib_pool.robj);
 	if (r) {
 		DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
 		return r;
@@ -190,9 +173,9 @@ int radeon_ib_pool_init(struct radeon_de
 		rdev->ib_pool.ibs[i].ptr = ptr + offset;
 		rdev->ib_pool.ibs[i].idx = i;
 		rdev->ib_pool.ibs[i].length_dw = 0;
-		INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list);
+		rdev->ib_pool.ibs[i].free = true;
 	}
-	bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
+	rdev->ib_pool.head_id = 0;
 	rdev->ib_pool.ready = true;
 	DRM_INFO("radeon: ib pool ready.\n");
 	if (radeon_debugfs_ib_init(rdev)) {
@@ -203,14 +186,20 @@ int radeon_ib_pool_init(struct radeon_de
 
 void radeon_ib_pool_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	if (!rdev->ib_pool.ready) {
 		return;
 	}
 	mutex_lock(&rdev->ib_pool.mutex);
-	bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
 	if (rdev->ib_pool.robj) {
-		radeon_object_kunmap(rdev->ib_pool.robj);
-		radeon_object_unref(&rdev->ib_pool.robj);
+		r = radeon_bo_reserve(rdev->ib_pool.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->ib_pool.robj);
+			radeon_bo_unpin(rdev->ib_pool.robj);
+			radeon_bo_unreserve(rdev->ib_pool.robj);
+		}
+		radeon_bo_unref(&rdev->ib_pool.robj);
 		rdev->ib_pool.robj = NULL;
 	}
 	mutex_unlock(&rdev->ib_pool.mutex);
@@ -288,29 +277,28 @@ int radeon_ring_init(struct radeon_devic
 	rdev->cp.ring_size = ring_size;
 	/* Allocate ring buffer */
 	if (rdev->cp.ring_obj == NULL) {
-		r = radeon_object_create(rdev, NULL, rdev->cp.ring_size,
-					 true,
-					 RADEON_GEM_DOMAIN_GTT,
-					 false,
-					 &rdev->cp.ring_obj);
+		r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
+					RADEON_GEM_DOMAIN_GTT,
+					&rdev->cp.ring_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			dev_err(rdev->dev, "(%d) ring create failed\n", r);
 			return r;
 		}
-		r = radeon_object_pin(rdev->cp.ring_obj,
-				      RADEON_GEM_DOMAIN_GTT,
-				      &rdev->cp.gpu_addr);
+		r = radeon_bo_reserve(rdev->cp.ring_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT,
+					&rdev->cp.gpu_addr);
 		if (r) {
-			DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			radeon_bo_unreserve(rdev->cp.ring_obj);
+			dev_err(rdev->dev, "(%d) ring pin failed\n", r);
 			return r;
 		}
-		r = radeon_object_kmap(rdev->cp.ring_obj,
+		r = radeon_bo_kmap(rdev->cp.ring_obj,
 				       (void **)&rdev->cp.ring);
+		radeon_bo_unreserve(rdev->cp.ring_obj);
 		if (r) {
-			DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r);
-			mutex_unlock(&rdev->cp.mutex);
+			dev_err(rdev->dev, "(%d) ring map failed\n", r);
 			return r;
 		}
 	}
@@ -321,11 +309,17 @@ int radeon_ring_init(struct radeon_devic
 
 void radeon_ring_fini(struct radeon_device *rdev)
 {
+	int r;
+
 	mutex_lock(&rdev->cp.mutex);
 	if (rdev->cp.ring_obj) {
-		radeon_object_kunmap(rdev->cp.ring_obj);
-		radeon_object_unpin(rdev->cp.ring_obj);
-		radeon_object_unref(&rdev->cp.ring_obj);
+		r = radeon_bo_reserve(rdev->cp.ring_obj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->cp.ring_obj);
+			radeon_bo_unpin(rdev->cp.ring_obj);
+			radeon_bo_unreserve(rdev->cp.ring_obj);
+		}
+		radeon_bo_unref(&rdev->cp.ring_obj);
 		rdev->cp.ring = NULL;
 		rdev->cp.ring_obj = NULL;
 	}
@@ -346,7 +340,7 @@ static int radeon_debugfs_ib_info(struct
 	if (ib == NULL) {
 		return 0;
 	}
-	seq_printf(m, "IB %04lu\n", ib->idx);
+	seq_printf(m, "IB %04u\n", ib->idx);
 	seq_printf(m, "IB fence %p\n", ib->fence);
 	seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
 	for (i = 0; i < ib->length_dw; i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_state.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_state.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2010-02-24 13:52:17.000000000 -0500
@@ -1950,7 +1950,7 @@ static void radeon_apply_surface_regs(in
  * Note that refcount can be at most 2, since during a free refcount=3
  * might mean we have to allocate a new surface which might not always
  * be available.
- * For example : we allocate three contigous surfaces ABC. If B is
+ * For example : we allocate three contiguous surfaces ABC. If B is
  * freed, we suddenly need two surfaces to store A and C, which might
  * not always be available.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_test.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_test.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_test.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_test.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,8 +30,8 @@
 /* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
 void radeon_test_moves(struct radeon_device *rdev)
 {
-	struct radeon_object *vram_obj = NULL;
-	struct radeon_object **gtt_obj = NULL;
+	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;
@@ -42,8 +42,8 @@ void radeon_test_moves(struct radeon_dev
 	/* Number of tests =
 	 * (Total GTT - IB pool - writeback page - ring buffer) / test size
 	 */
-	n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
-	     rdev->cp.ring_size) / size;
+	n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
+	     rdev->cp.ring_size)) / size;
 
 	gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
 	if (!gtt_obj) {
@@ -52,38 +52,42 @@ void radeon_test_moves(struct radeon_dev
 		goto out_cleanup;
 	}
 
-	r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
-				 false, &vram_obj);
+	r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
+				&vram_obj);
 	if (r) {
 		DRM_ERROR("Failed to create VRAM object\n");
 		goto out_cleanup;
 	}
-
-	r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
+	r = radeon_bo_reserve(vram_obj, false);
+	if (unlikely(r != 0))
+		goto out_cleanup;
+	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;
 	}
-
 	for (i = 0; i < n; i++) {
 		void *gtt_map, *vram_map;
 		void **gtt_start, **gtt_end;
 		void **vram_start, **vram_end;
 
-		r = radeon_object_create(rdev, NULL, size, true,
-					 RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i);
+		r = radeon_bo_create(rdev, NULL, size, true,
+					 RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
 		if (r) {
 			DRM_ERROR("Failed to create GTT object %d\n", i);
 			goto out_cleanup;
 		}
 
-		r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr);
+		r = radeon_bo_reserve(gtt_obj[i], false);
+		if (unlikely(r != 0))
+			goto out_cleanup;
+		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;
 		}
 
-		r = radeon_object_kmap(gtt_obj[i], &gtt_map);
+		r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
 		if (r) {
 			DRM_ERROR("Failed to map GTT object %d\n", i);
 			goto out_cleanup;
@@ -94,7 +98,7 @@ void radeon_test_moves(struct radeon_dev
 		     gtt_start++)
 			*gtt_start = gtt_start;
 
-		radeon_object_kunmap(gtt_obj[i]);
+		radeon_bo_kunmap(gtt_obj[i]);
 
 		r = radeon_fence_create(rdev, &fence);
 		if (r) {
@@ -116,7 +120,7 @@ void radeon_test_moves(struct radeon_dev
 
 		radeon_fence_unref(&fence);
 
-		r = radeon_object_kmap(vram_obj, &vram_map);
+		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;
@@ -131,13 +135,13 @@ void radeon_test_moves(struct radeon_dev
 					  "expected 0x%p (GTT map 0x%p-0x%p)\n",
 					  i, *vram_start, gtt_start, gtt_map,
 					  gtt_end);
-				radeon_object_kunmap(vram_obj);
+				radeon_bo_kunmap(vram_obj);
 				goto out_cleanup;
 			}
 			*vram_start = vram_start;
 		}
 
-		radeon_object_kunmap(vram_obj);
+		radeon_bo_kunmap(vram_obj);
 
 		r = radeon_fence_create(rdev, &fence);
 		if (r) {
@@ -159,7 +163,7 @@ void radeon_test_moves(struct radeon_dev
 
 		radeon_fence_unref(&fence);
 
-		r = radeon_object_kmap(gtt_obj[i], &gtt_map);
+		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;
@@ -174,12 +178,12 @@ void radeon_test_moves(struct radeon_dev
 					  "expected 0x%p (VRAM map 0x%p-0x%p)\n",
 					  i, *gtt_start, vram_start, vram_map,
 					  vram_end);
-				radeon_object_kunmap(gtt_obj[i]);
+				radeon_bo_kunmap(gtt_obj[i]);
 				goto out_cleanup;
 			}
 		}
 
-		radeon_object_kunmap(gtt_obj[i]);
+		radeon_bo_kunmap(gtt_obj[i]);
 
 		DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
 			 gtt_addr - rdev->mc.gtt_location);
@@ -187,14 +191,20 @@ void radeon_test_moves(struct radeon_dev
 
 out_cleanup:
 	if (vram_obj) {
-		radeon_object_unpin(vram_obj);
-		radeon_object_unref(&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]) {
-				radeon_object_unpin(gtt_obj[i]);
-				radeon_object_unref(&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]);
 			}
 		}
 		kfree(gtt_obj);
@@ -206,4 +216,3 @@ out_cleanup:
 		printk(KERN_WARNING "Error while testing BO move.\n");
 	}
 }
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/radeon_ttm.c	2010-02-24 13:52:17.000000000 -0500
@@ -150,7 +150,7 @@ static int radeon_init_mem_type(struct t
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		break;
 	case TTM_PL_TT:
-		man->gpu_offset = 0;
+		man->gpu_offset = rdev->mc.gtt_location;
 		man->available_caching = TTM_PL_MASK_CACHING;
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -180,7 +180,7 @@ static int radeon_init_mem_type(struct t
 		break;
 	case TTM_PL_VRAM:
 		/* "On-card" video ram */
-		man->gpu_offset = 0;
+		man->gpu_offset = rdev->mc.vram_location;
 		man->flags = TTM_MEMTYPE_FLAG_FIXED |
 			     TTM_MEMTYPE_FLAG_NEEDS_IOREMAP |
 			     TTM_MEMTYPE_FLAG_MAPPABLE;
@@ -197,16 +197,34 @@ static int radeon_init_mem_type(struct t
 	return 0;
 }
 
-static uint32_t radeon_evict_flags(struct ttm_buffer_object *bo)
+static void radeon_evict_flags(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement)
 {
-	uint32_t cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEMTYPE;
+	struct radeon_bo *rbo;
+	static u32 placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
 
+	if (!radeon_ttm_bo_is_radeon_bo(bo)) {
+		placement->fpfn = 0;
+		placement->lpfn = 0;
+		placement->placement = &placements;
+		placement->busy_placement = &placements;
+		placement->num_placement = 1;
+		placement->num_busy_placement = 1;
+		return;
+	}
+	rbo = container_of(bo, struct radeon_bo, tbo);
 	switch (bo->mem.mem_type) {
+	case TTM_PL_VRAM:
+		if (rbo->rdev->cp.ready == false)
+			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
+		else
+			radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
+		break;
+	case TTM_PL_TT:
 	default:
-		return (cur_placement & ~TTM_PL_MASK_CACHING) |
-			TTM_PL_FLAG_SYSTEM |
-			TTM_PL_FLAG_CACHED;
+		radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
 	}
+	*placement = rbo->placement;
 }
 
 static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp)
@@ -283,14 +301,21 @@ static int radeon_move_vram_ram(struct t
 	struct radeon_device *rdev;
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	struct ttm_mem_reg tmp_mem;
-	uint32_t proposed_placement;
+	u32 placements;
+	struct ttm_placement placement;
 	int r;
 
 	rdev = radeon_get_rdev(bo->bdev);
 	tmp_mem = *new_mem;
 	tmp_mem.mm_node = NULL;
-	proposed_placement = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	r = ttm_bo_mem_space(bo, proposed_placement, &tmp_mem,
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 1;
+	placement.placement = &placements;
+	placement.num_busy_placement = 1;
+	placement.busy_placement = &placements;
+	placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
 			     interruptible, no_wait);
 	if (unlikely(r)) {
 		return r;
@@ -329,15 +354,21 @@ static int radeon_move_ram_vram(struct t
 	struct radeon_device *rdev;
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	struct ttm_mem_reg tmp_mem;
-	uint32_t proposed_flags;
+	struct ttm_placement placement;
+	u32 placements;
 	int r;
 
 	rdev = radeon_get_rdev(bo->bdev);
 	tmp_mem = *new_mem;
 	tmp_mem.mm_node = NULL;
-	proposed_flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-	r = ttm_bo_mem_space(bo, proposed_flags, &tmp_mem,
-			     interruptible, no_wait);
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 1;
+	placement.placement = &placements;
+	placement.num_busy_placement = 1;
+	placement.busy_placement = &placements;
+	placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
+	r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait);
 	if (unlikely(r)) {
 		return r;
 	}
@@ -378,7 +409,7 @@ static int radeon_bo_move(struct ttm_buf
 	     new_mem->mem_type == TTM_PL_SYSTEM) ||
 	    (old_mem->mem_type == TTM_PL_SYSTEM &&
 	     new_mem->mem_type == TTM_PL_TT)) {
-		/* bind is enought */
+		/* bind is enough */
 		radeon_move_null(bo, new_mem);
 		return 0;
 	}
@@ -407,18 +438,6 @@ memcpy:
 	return r;
 }
 
-const uint32_t radeon_mem_prios[] = {
-	TTM_PL_VRAM,
-	TTM_PL_TT,
-	TTM_PL_SYSTEM,
-};
-
-const uint32_t radeon_busy_prios[] = {
-	TTM_PL_TT,
-	TTM_PL_VRAM,
-	TTM_PL_SYSTEM,
-};
-
 static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg,
 				bool lazy, bool interruptible)
 {
@@ -446,10 +465,6 @@ static bool radeon_sync_obj_signaled(voi
 }
 
 static struct ttm_bo_driver radeon_bo_driver = {
-	.mem_type_prio = radeon_mem_prios,
-	.mem_busy_prio = radeon_busy_prios,
-	.num_mem_type_prio = ARRAY_SIZE(radeon_mem_prios),
-	.num_mem_busy_prio = ARRAY_SIZE(radeon_busy_prios),
 	.create_ttm_backend_entry = &radeon_create_ttm_backend_entry,
 	.invalidate_caches = &radeon_invalidate_caches,
 	.init_mem_type = &radeon_init_mem_type,
@@ -482,27 +497,32 @@ int radeon_ttm_init(struct radeon_device
 		DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
 		return r;
 	}
-	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0,
-			   ((rdev->mc.real_vram_size) >> PAGE_SHIFT));
+	rdev->mman.initialized = true;
+	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM,
+				rdev->mc.real_vram_size >> PAGE_SHIFT);
 	if (r) {
 		DRM_ERROR("Failed initializing VRAM heap.\n");
 		return r;
 	}
-	r = radeon_object_create(rdev, NULL, 256 * 1024, true,
-				 RADEON_GEM_DOMAIN_VRAM, false,
-				 &rdev->stollen_vga_memory);
+	r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
+				RADEON_GEM_DOMAIN_VRAM,
+				&rdev->stollen_vga_memory);
 	if (r) {
 		return r;
 	}
-	r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+	r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+	if (r)
+		return r;
+	r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+	radeon_bo_unreserve(rdev->stollen_vga_memory);
 	if (r) {
-		radeon_object_unref(&rdev->stollen_vga_memory);
+		radeon_bo_unref(&rdev->stollen_vga_memory);
 		return r;
 	}
 	DRM_INFO("radeon: %uM of VRAM memory ready\n",
 		 (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
-	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
-			   ((rdev->mc.gtt_size) >> PAGE_SHIFT));
+	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT,
+				rdev->mc.gtt_size >> PAGE_SHIFT);
 	if (r) {
 		DRM_ERROR("Failed initializing GTT heap.\n");
 		return r;
@@ -523,15 +543,24 @@ int radeon_ttm_init(struct radeon_device
 
 void radeon_ttm_fini(struct radeon_device *rdev)
 {
+	int r;
+
+	if (!rdev->mman.initialized)
+		return;
 	if (rdev->stollen_vga_memory) {
-		radeon_object_unpin(rdev->stollen_vga_memory);
-		radeon_object_unref(&rdev->stollen_vga_memory);
+		r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+		if (r == 0) {
+			radeon_bo_unpin(rdev->stollen_vga_memory);
+			radeon_bo_unreserve(rdev->stollen_vga_memory);
+		}
+		radeon_bo_unref(&rdev->stollen_vga_memory);
 	}
 	ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);
 	ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);
 	ttm_bo_device_release(&rdev->mman.bdev);
 	radeon_gart_fini(rdev);
 	radeon_ttm_global_fini(rdev);
+	rdev->mman.initialized = false;
 	DRM_INFO("radeon: ttm finalized\n");
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/r200 linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r200
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/r200	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r200	2010-02-24 13:52:17.000000000 -0500
@@ -91,6 +91,8 @@ r200 0x3294
 0x22b8 SE_TCL_TEX_CYL_WRAP_CTL
 0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL
 0x22c4 SE_TCL_POINT_SPRITE_CNTL
+0x22d0 SE_PVS_CNTL
+0x22d4 SE_PVS_CONST_CNTL
 0x2648 RE_POINTSIZE
 0x26c0 RE_TOP_LEFT
 0x26c4 RE_MISC
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420 linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/r420	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,795 @@
+r420 0x4f60
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1D98 VAP_VPORT_XSCALE
+0x1D9C VAP_VPORT_XOFFSET
+0x1DA0 VAP_VPORT_YSCALE
+0x1DA4 VAP_VPORT_YOFFSET
+0x1DA8 VAP_VPORT_ZSCALE
+0x1DAC VAP_VPORT_ZOFFSET
+0x2080 VAP_CNTL
+0x2090 VAP_OUT_VTX_FMT_0
+0x2094 VAP_OUT_VTX_FMT_1
+0x20B0 VAP_VTE_CNTL
+0x2138 VAP_VF_MIN_VTX_INDX
+0x2140 VAP_CNTL_STATUS
+0x2150 VAP_PROG_STREAM_CNTL_0
+0x2154 VAP_PROG_STREAM_CNTL_1
+0x2158 VAP_PROG_STREAM_CNTL_2
+0x215C VAP_PROG_STREAM_CNTL_3
+0x2160 VAP_PROG_STREAM_CNTL_4
+0x2164 VAP_PROG_STREAM_CNTL_5
+0x2168 VAP_PROG_STREAM_CNTL_6
+0x216C VAP_PROG_STREAM_CNTL_7
+0x2180 VAP_VTX_STATE_CNTL
+0x2184 VAP_VSM_VTX_ASSM
+0x2188 VAP_VTX_STATE_IND_REG_0
+0x218C VAP_VTX_STATE_IND_REG_1
+0x2190 VAP_VTX_STATE_IND_REG_2
+0x2194 VAP_VTX_STATE_IND_REG_3
+0x2198 VAP_VTX_STATE_IND_REG_4
+0x219C VAP_VTX_STATE_IND_REG_5
+0x21A0 VAP_VTX_STATE_IND_REG_6
+0x21A4 VAP_VTX_STATE_IND_REG_7
+0x21A8 VAP_VTX_STATE_IND_REG_8
+0x21AC VAP_VTX_STATE_IND_REG_9
+0x21B0 VAP_VTX_STATE_IND_REG_10
+0x21B4 VAP_VTX_STATE_IND_REG_11
+0x21B8 VAP_VTX_STATE_IND_REG_12
+0x21BC VAP_VTX_STATE_IND_REG_13
+0x21C0 VAP_VTX_STATE_IND_REG_14
+0x21C4 VAP_VTX_STATE_IND_REG_15
+0x21DC VAP_PSC_SGN_NORM_CNTL
+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0
+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1
+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2
+0x21EC VAP_PROG_STREAM_CNTL_EXT_3
+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4
+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5
+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6
+0x21FC VAP_PROG_STREAM_CNTL_EXT_7
+0x2200 VAP_PVS_VECTOR_INDX_REG
+0x2204 VAP_PVS_VECTOR_DATA_REG
+0x2208 VAP_PVS_VECTOR_DATA_REG_128
+0x221C VAP_CLIP_CNTL
+0x2220 VAP_GB_VERT_CLIP_ADJ
+0x2224 VAP_GB_VERT_DISC_ADJ
+0x2228 VAP_GB_HORZ_CLIP_ADJ
+0x222C VAP_GB_HORZ_DISC_ADJ
+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3
+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7
+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11
+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x2288 VAP_PVS_VTX_TIMEOUT_REG
+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
+0x22D0 VAP_PVS_CODE_CNTL_0
+0x22D4 VAP_PVS_CONST_CNTL
+0x22D8 VAP_PVS_CODE_CNTL_1
+0x22DC VAP_PVS_FLOW_CNTL_OPC
+0x342C RB2D_DSTCACHE_CTLSTAT
+0x4000 GB_VAP_RASTER_VTX_FMT_0
+0x4004 GB_VAP_RASTER_VTX_FMT_1
+0x4008 GB_ENABLE
+0x401C GB_SELECT
+0x4020 GB_AA_CONFIG
+0x4024 GB_FIFO_SIZE
+0x4100 TX_INVALTAGS
+0x4200 GA_POINT_S0
+0x4204 GA_POINT_T0
+0x4208 GA_POINT_S1
+0x420C GA_POINT_T1
+0x4214 GA_TRIANGLE_STIPPLE
+0x421C GA_POINT_SIZE
+0x4230 GA_POINT_MINMAX
+0x4234 GA_LINE_CNTL
+0x4238 GA_LINE_STIPPLE_CONFIG
+0x4260 GA_LINE_STIPPLE_VALUE
+0x4264 GA_LINE_S0
+0x4268 GA_LINE_S1
+0x4278 GA_COLOR_CONTROL
+0x427C GA_SOLID_RG
+0x4280 GA_SOLID_BA
+0x4288 GA_POLY_MODE
+0x428C GA_ROUND_MODE
+0x4290 GA_OFFSET
+0x4294 GA_FOG_SCALE
+0x4298 GA_FOG_OFFSET
+0x42A0 SU_TEX_WRAP
+0x42A4 SU_POLY_OFFSET_FRONT_SCALE
+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET
+0x42AC SU_POLY_OFFSET_BACK_SCALE
+0x42B0 SU_POLY_OFFSET_BACK_OFFSET
+0x42B4 SU_POLY_OFFSET_ENABLE
+0x42B8 SU_CULL_MODE
+0x42C0 SU_DEPTH_SCALE
+0x42C4 SU_DEPTH_OFFSET
+0x42C8 SU_REG_DEST
+0x4300 RS_COUNT
+0x4304 RS_INST_COUNT
+0x4310 RS_IP_0
+0x4314 RS_IP_1
+0x4318 RS_IP_2
+0x431C RS_IP_3
+0x4320 RS_IP_4
+0x4324 RS_IP_5
+0x4328 RS_IP_6
+0x432C RS_IP_7
+0x4330 RS_INST_0
+0x4334 RS_INST_1
+0x4338 RS_INST_2
+0x433C RS_INST_3
+0x4340 RS_INST_4
+0x4344 RS_INST_5
+0x4348 RS_INST_6
+0x434C RS_INST_7
+0x4350 RS_INST_8
+0x4354 RS_INST_9
+0x4358 RS_INST_10
+0x435C RS_INST_11
+0x4360 RS_INST_12
+0x4364 RS_INST_13
+0x4368 RS_INST_14
+0x436C RS_INST_15
+0x43A4 SC_HYPERZ_EN
+0x43A8 SC_EDGERULE
+0x43B0 SC_CLIP_0_A
+0x43B4 SC_CLIP_0_B
+0x43B8 SC_CLIP_1_A
+0x43BC SC_CLIP_1_B
+0x43C0 SC_CLIP_2_A
+0x43C4 SC_CLIP_2_B
+0x43C8 SC_CLIP_3_A
+0x43CC SC_CLIP_3_B
+0x43D0 SC_CLIP_RULE
+0x43E0 SC_SCISSOR0
+0x43E8 SC_SCREENDOOR
+0x4440 TX_FILTER1_0
+0x4444 TX_FILTER1_1
+0x4448 TX_FILTER1_2
+0x444C TX_FILTER1_3
+0x4450 TX_FILTER1_4
+0x4454 TX_FILTER1_5
+0x4458 TX_FILTER1_6
+0x445C TX_FILTER1_7
+0x4460 TX_FILTER1_8
+0x4464 TX_FILTER1_9
+0x4468 TX_FILTER1_10
+0x446C TX_FILTER1_11
+0x4470 TX_FILTER1_12
+0x4474 TX_FILTER1_13
+0x4478 TX_FILTER1_14
+0x447C TX_FILTER1_15
+0x4580 TX_CHROMA_KEY_0
+0x4584 TX_CHROMA_KEY_1
+0x4588 TX_CHROMA_KEY_2
+0x458C TX_CHROMA_KEY_3
+0x4590 TX_CHROMA_KEY_4
+0x4594 TX_CHROMA_KEY_5
+0x4598 TX_CHROMA_KEY_6
+0x459C TX_CHROMA_KEY_7
+0x45A0 TX_CHROMA_KEY_8
+0x45A4 TX_CHROMA_KEY_9
+0x45A8 TX_CHROMA_KEY_10
+0x45AC TX_CHROMA_KEY_11
+0x45B0 TX_CHROMA_KEY_12
+0x45B4 TX_CHROMA_KEY_13
+0x45B8 TX_CHROMA_KEY_14
+0x45BC TX_CHROMA_KEY_15
+0x45C0 TX_BORDER_COLOR_0
+0x45C4 TX_BORDER_COLOR_1
+0x45C8 TX_BORDER_COLOR_2
+0x45CC TX_BORDER_COLOR_3
+0x45D0 TX_BORDER_COLOR_4
+0x45D4 TX_BORDER_COLOR_5
+0x45D8 TX_BORDER_COLOR_6
+0x45DC TX_BORDER_COLOR_7
+0x45E0 TX_BORDER_COLOR_8
+0x45E4 TX_BORDER_COLOR_9
+0x45E8 TX_BORDER_COLOR_10
+0x45EC TX_BORDER_COLOR_11
+0x45F0 TX_BORDER_COLOR_12
+0x45F4 TX_BORDER_COLOR_13
+0x45F8 TX_BORDER_COLOR_14
+0x45FC TX_BORDER_COLOR_15
+0x4600 US_CONFIG
+0x4604 US_PIXSIZE
+0x4608 US_CODE_OFFSET
+0x460C US_RESET
+0x4610 US_CODE_ADDR_0
+0x4614 US_CODE_ADDR_1
+0x4618 US_CODE_ADDR_2
+0x461C US_CODE_ADDR_3
+0x4620 US_TEX_INST_0
+0x4624 US_TEX_INST_1
+0x4628 US_TEX_INST_2
+0x462C US_TEX_INST_3
+0x4630 US_TEX_INST_4
+0x4634 US_TEX_INST_5
+0x4638 US_TEX_INST_6
+0x463C US_TEX_INST_7
+0x4640 US_TEX_INST_8
+0x4644 US_TEX_INST_9
+0x4648 US_TEX_INST_10
+0x464C US_TEX_INST_11
+0x4650 US_TEX_INST_12
+0x4654 US_TEX_INST_13
+0x4658 US_TEX_INST_14
+0x465C US_TEX_INST_15
+0x4660 US_TEX_INST_16
+0x4664 US_TEX_INST_17
+0x4668 US_TEX_INST_18
+0x466C US_TEX_INST_19
+0x4670 US_TEX_INST_20
+0x4674 US_TEX_INST_21
+0x4678 US_TEX_INST_22
+0x467C US_TEX_INST_23
+0x4680 US_TEX_INST_24
+0x4684 US_TEX_INST_25
+0x4688 US_TEX_INST_26
+0x468C US_TEX_INST_27
+0x4690 US_TEX_INST_28
+0x4694 US_TEX_INST_29
+0x4698 US_TEX_INST_30
+0x469C US_TEX_INST_31
+0x46A4 US_OUT_FMT_0
+0x46A8 US_OUT_FMT_1
+0x46AC US_OUT_FMT_2
+0x46B0 US_OUT_FMT_3
+0x46B4 US_W_FMT
+0x46B8 US_CODE_BANK
+0x46BC US_CODE_EXT
+0x46C0 US_ALU_RGB_ADDR_0
+0x46C4 US_ALU_RGB_ADDR_1
+0x46C8 US_ALU_RGB_ADDR_2
+0x46CC US_ALU_RGB_ADDR_3
+0x46D0 US_ALU_RGB_ADDR_4
+0x46D4 US_ALU_RGB_ADDR_5
+0x46D8 US_ALU_RGB_ADDR_6
+0x46DC US_ALU_RGB_ADDR_7
+0x46E0 US_ALU_RGB_ADDR_8
+0x46E4 US_ALU_RGB_ADDR_9
+0x46E8 US_ALU_RGB_ADDR_10
+0x46EC US_ALU_RGB_ADDR_11
+0x46F0 US_ALU_RGB_ADDR_12
+0x46F4 US_ALU_RGB_ADDR_13
+0x46F8 US_ALU_RGB_ADDR_14
+0x46FC US_ALU_RGB_ADDR_15
+0x4700 US_ALU_RGB_ADDR_16
+0x4704 US_ALU_RGB_ADDR_17
+0x4708 US_ALU_RGB_ADDR_18
+0x470C US_ALU_RGB_ADDR_19
+0x4710 US_ALU_RGB_ADDR_20
+0x4714 US_ALU_RGB_ADDR_21
+0x4718 US_ALU_RGB_ADDR_22
+0x471C US_ALU_RGB_ADDR_23
+0x4720 US_ALU_RGB_ADDR_24
+0x4724 US_ALU_RGB_ADDR_25
+0x4728 US_ALU_RGB_ADDR_26
+0x472C US_ALU_RGB_ADDR_27
+0x4730 US_ALU_RGB_ADDR_28
+0x4734 US_ALU_RGB_ADDR_29
+0x4738 US_ALU_RGB_ADDR_30
+0x473C US_ALU_RGB_ADDR_31
+0x4740 US_ALU_RGB_ADDR_32
+0x4744 US_ALU_RGB_ADDR_33
+0x4748 US_ALU_RGB_ADDR_34
+0x474C US_ALU_RGB_ADDR_35
+0x4750 US_ALU_RGB_ADDR_36
+0x4754 US_ALU_RGB_ADDR_37
+0x4758 US_ALU_RGB_ADDR_38
+0x475C US_ALU_RGB_ADDR_39
+0x4760 US_ALU_RGB_ADDR_40
+0x4764 US_ALU_RGB_ADDR_41
+0x4768 US_ALU_RGB_ADDR_42
+0x476C US_ALU_RGB_ADDR_43
+0x4770 US_ALU_RGB_ADDR_44
+0x4774 US_ALU_RGB_ADDR_45
+0x4778 US_ALU_RGB_ADDR_46
+0x477C US_ALU_RGB_ADDR_47
+0x4780 US_ALU_RGB_ADDR_48
+0x4784 US_ALU_RGB_ADDR_49
+0x4788 US_ALU_RGB_ADDR_50
+0x478C US_ALU_RGB_ADDR_51
+0x4790 US_ALU_RGB_ADDR_52
+0x4794 US_ALU_RGB_ADDR_53
+0x4798 US_ALU_RGB_ADDR_54
+0x479C US_ALU_RGB_ADDR_55
+0x47A0 US_ALU_RGB_ADDR_56
+0x47A4 US_ALU_RGB_ADDR_57
+0x47A8 US_ALU_RGB_ADDR_58
+0x47AC US_ALU_RGB_ADDR_59
+0x47B0 US_ALU_RGB_ADDR_60
+0x47B4 US_ALU_RGB_ADDR_61
+0x47B8 US_ALU_RGB_ADDR_62
+0x47BC US_ALU_RGB_ADDR_63
+0x47C0 US_ALU_ALPHA_ADDR_0
+0x47C4 US_ALU_ALPHA_ADDR_1
+0x47C8 US_ALU_ALPHA_ADDR_2
+0x47CC US_ALU_ALPHA_ADDR_3
+0x47D0 US_ALU_ALPHA_ADDR_4
+0x47D4 US_ALU_ALPHA_ADDR_5
+0x47D8 US_ALU_ALPHA_ADDR_6
+0x47DC US_ALU_ALPHA_ADDR_7
+0x47E0 US_ALU_ALPHA_ADDR_8
+0x47E4 US_ALU_ALPHA_ADDR_9
+0x47E8 US_ALU_ALPHA_ADDR_10
+0x47EC US_ALU_ALPHA_ADDR_11
+0x47F0 US_ALU_ALPHA_ADDR_12
+0x47F4 US_ALU_ALPHA_ADDR_13
+0x47F8 US_ALU_ALPHA_ADDR_14
+0x47FC US_ALU_ALPHA_ADDR_15
+0x4800 US_ALU_ALPHA_ADDR_16
+0x4804 US_ALU_ALPHA_ADDR_17
+0x4808 US_ALU_ALPHA_ADDR_18
+0x480C US_ALU_ALPHA_ADDR_19
+0x4810 US_ALU_ALPHA_ADDR_20
+0x4814 US_ALU_ALPHA_ADDR_21
+0x4818 US_ALU_ALPHA_ADDR_22
+0x481C US_ALU_ALPHA_ADDR_23
+0x4820 US_ALU_ALPHA_ADDR_24
+0x4824 US_ALU_ALPHA_ADDR_25
+0x4828 US_ALU_ALPHA_ADDR_26
+0x482C US_ALU_ALPHA_ADDR_27
+0x4830 US_ALU_ALPHA_ADDR_28
+0x4834 US_ALU_ALPHA_ADDR_29
+0x4838 US_ALU_ALPHA_ADDR_30
+0x483C US_ALU_ALPHA_ADDR_31
+0x4840 US_ALU_ALPHA_ADDR_32
+0x4844 US_ALU_ALPHA_ADDR_33
+0x4848 US_ALU_ALPHA_ADDR_34
+0x484C US_ALU_ALPHA_ADDR_35
+0x4850 US_ALU_ALPHA_ADDR_36
+0x4854 US_ALU_ALPHA_ADDR_37
+0x4858 US_ALU_ALPHA_ADDR_38
+0x485C US_ALU_ALPHA_ADDR_39
+0x4860 US_ALU_ALPHA_ADDR_40
+0x4864 US_ALU_ALPHA_ADDR_41
+0x4868 US_ALU_ALPHA_ADDR_42
+0x486C US_ALU_ALPHA_ADDR_43
+0x4870 US_ALU_ALPHA_ADDR_44
+0x4874 US_ALU_ALPHA_ADDR_45
+0x4878 US_ALU_ALPHA_ADDR_46
+0x487C US_ALU_ALPHA_ADDR_47
+0x4880 US_ALU_ALPHA_ADDR_48
+0x4884 US_ALU_ALPHA_ADDR_49
+0x4888 US_ALU_ALPHA_ADDR_50
+0x488C US_ALU_ALPHA_ADDR_51
+0x4890 US_ALU_ALPHA_ADDR_52
+0x4894 US_ALU_ALPHA_ADDR_53
+0x4898 US_ALU_ALPHA_ADDR_54
+0x489C US_ALU_ALPHA_ADDR_55
+0x48A0 US_ALU_ALPHA_ADDR_56
+0x48A4 US_ALU_ALPHA_ADDR_57
+0x48A8 US_ALU_ALPHA_ADDR_58
+0x48AC US_ALU_ALPHA_ADDR_59
+0x48B0 US_ALU_ALPHA_ADDR_60
+0x48B4 US_ALU_ALPHA_ADDR_61
+0x48B8 US_ALU_ALPHA_ADDR_62
+0x48BC US_ALU_ALPHA_ADDR_63
+0x48C0 US_ALU_RGB_INST_0
+0x48C4 US_ALU_RGB_INST_1
+0x48C8 US_ALU_RGB_INST_2
+0x48CC US_ALU_RGB_INST_3
+0x48D0 US_ALU_RGB_INST_4
+0x48D4 US_ALU_RGB_INST_5
+0x48D8 US_ALU_RGB_INST_6
+0x48DC US_ALU_RGB_INST_7
+0x48E0 US_ALU_RGB_INST_8
+0x48E4 US_ALU_RGB_INST_9
+0x48E8 US_ALU_RGB_INST_10
+0x48EC US_ALU_RGB_INST_11
+0x48F0 US_ALU_RGB_INST_12
+0x48F4 US_ALU_RGB_INST_13
+0x48F8 US_ALU_RGB_INST_14
+0x48FC US_ALU_RGB_INST_15
+0x4900 US_ALU_RGB_INST_16
+0x4904 US_ALU_RGB_INST_17
+0x4908 US_ALU_RGB_INST_18
+0x490C US_ALU_RGB_INST_19
+0x4910 US_ALU_RGB_INST_20
+0x4914 US_ALU_RGB_INST_21
+0x4918 US_ALU_RGB_INST_22
+0x491C US_ALU_RGB_INST_23
+0x4920 US_ALU_RGB_INST_24
+0x4924 US_ALU_RGB_INST_25
+0x4928 US_ALU_RGB_INST_26
+0x492C US_ALU_RGB_INST_27
+0x4930 US_ALU_RGB_INST_28
+0x4934 US_ALU_RGB_INST_29
+0x4938 US_ALU_RGB_INST_30
+0x493C US_ALU_RGB_INST_31
+0x4940 US_ALU_RGB_INST_32
+0x4944 US_ALU_RGB_INST_33
+0x4948 US_ALU_RGB_INST_34
+0x494C US_ALU_RGB_INST_35
+0x4950 US_ALU_RGB_INST_36
+0x4954 US_ALU_RGB_INST_37
+0x4958 US_ALU_RGB_INST_38
+0x495C US_ALU_RGB_INST_39
+0x4960 US_ALU_RGB_INST_40
+0x4964 US_ALU_RGB_INST_41
+0x4968 US_ALU_RGB_INST_42
+0x496C US_ALU_RGB_INST_43
+0x4970 US_ALU_RGB_INST_44
+0x4974 US_ALU_RGB_INST_45
+0x4978 US_ALU_RGB_INST_46
+0x497C US_ALU_RGB_INST_47
+0x4980 US_ALU_RGB_INST_48
+0x4984 US_ALU_RGB_INST_49
+0x4988 US_ALU_RGB_INST_50
+0x498C US_ALU_RGB_INST_51
+0x4990 US_ALU_RGB_INST_52
+0x4994 US_ALU_RGB_INST_53
+0x4998 US_ALU_RGB_INST_54
+0x499C US_ALU_RGB_INST_55
+0x49A0 US_ALU_RGB_INST_56
+0x49A4 US_ALU_RGB_INST_57
+0x49A8 US_ALU_RGB_INST_58
+0x49AC US_ALU_RGB_INST_59
+0x49B0 US_ALU_RGB_INST_60
+0x49B4 US_ALU_RGB_INST_61
+0x49B8 US_ALU_RGB_INST_62
+0x49BC US_ALU_RGB_INST_63
+0x49C0 US_ALU_ALPHA_INST_0
+0x49C4 US_ALU_ALPHA_INST_1
+0x49C8 US_ALU_ALPHA_INST_2
+0x49CC US_ALU_ALPHA_INST_3
+0x49D0 US_ALU_ALPHA_INST_4
+0x49D4 US_ALU_ALPHA_INST_5
+0x49D8 US_ALU_ALPHA_INST_6
+0x49DC US_ALU_ALPHA_INST_7
+0x49E0 US_ALU_ALPHA_INST_8
+0x49E4 US_ALU_ALPHA_INST_9
+0x49E8 US_ALU_ALPHA_INST_10
+0x49EC US_ALU_ALPHA_INST_11
+0x49F0 US_ALU_ALPHA_INST_12
+0x49F4 US_ALU_ALPHA_INST_13
+0x49F8 US_ALU_ALPHA_INST_14
+0x49FC US_ALU_ALPHA_INST_15
+0x4A00 US_ALU_ALPHA_INST_16
+0x4A04 US_ALU_ALPHA_INST_17
+0x4A08 US_ALU_ALPHA_INST_18
+0x4A0C US_ALU_ALPHA_INST_19
+0x4A10 US_ALU_ALPHA_INST_20
+0x4A14 US_ALU_ALPHA_INST_21
+0x4A18 US_ALU_ALPHA_INST_22
+0x4A1C US_ALU_ALPHA_INST_23
+0x4A20 US_ALU_ALPHA_INST_24
+0x4A24 US_ALU_ALPHA_INST_25
+0x4A28 US_ALU_ALPHA_INST_26
+0x4A2C US_ALU_ALPHA_INST_27
+0x4A30 US_ALU_ALPHA_INST_28
+0x4A34 US_ALU_ALPHA_INST_29
+0x4A38 US_ALU_ALPHA_INST_30
+0x4A3C US_ALU_ALPHA_INST_31
+0x4A40 US_ALU_ALPHA_INST_32
+0x4A44 US_ALU_ALPHA_INST_33
+0x4A48 US_ALU_ALPHA_INST_34
+0x4A4C US_ALU_ALPHA_INST_35
+0x4A50 US_ALU_ALPHA_INST_36
+0x4A54 US_ALU_ALPHA_INST_37
+0x4A58 US_ALU_ALPHA_INST_38
+0x4A5C US_ALU_ALPHA_INST_39
+0x4A60 US_ALU_ALPHA_INST_40
+0x4A64 US_ALU_ALPHA_INST_41
+0x4A68 US_ALU_ALPHA_INST_42
+0x4A6C US_ALU_ALPHA_INST_43
+0x4A70 US_ALU_ALPHA_INST_44
+0x4A74 US_ALU_ALPHA_INST_45
+0x4A78 US_ALU_ALPHA_INST_46
+0x4A7C US_ALU_ALPHA_INST_47
+0x4A80 US_ALU_ALPHA_INST_48
+0x4A84 US_ALU_ALPHA_INST_49
+0x4A88 US_ALU_ALPHA_INST_50
+0x4A8C US_ALU_ALPHA_INST_51
+0x4A90 US_ALU_ALPHA_INST_52
+0x4A94 US_ALU_ALPHA_INST_53
+0x4A98 US_ALU_ALPHA_INST_54
+0x4A9C US_ALU_ALPHA_INST_55
+0x4AA0 US_ALU_ALPHA_INST_56
+0x4AA4 US_ALU_ALPHA_INST_57
+0x4AA8 US_ALU_ALPHA_INST_58
+0x4AAC US_ALU_ALPHA_INST_59
+0x4AB0 US_ALU_ALPHA_INST_60
+0x4AB4 US_ALU_ALPHA_INST_61
+0x4AB8 US_ALU_ALPHA_INST_62
+0x4ABC US_ALU_ALPHA_INST_63
+0x4AC0 US_ALU_EXT_ADDR_0
+0x4AC4 US_ALU_EXT_ADDR_1
+0x4AC8 US_ALU_EXT_ADDR_2
+0x4ACC US_ALU_EXT_ADDR_3
+0x4AD0 US_ALU_EXT_ADDR_4
+0x4AD4 US_ALU_EXT_ADDR_5
+0x4AD8 US_ALU_EXT_ADDR_6
+0x4ADC US_ALU_EXT_ADDR_7
+0x4AE0 US_ALU_EXT_ADDR_8
+0x4AE4 US_ALU_EXT_ADDR_9
+0x4AE8 US_ALU_EXT_ADDR_10
+0x4AEC US_ALU_EXT_ADDR_11
+0x4AF0 US_ALU_EXT_ADDR_12
+0x4AF4 US_ALU_EXT_ADDR_13
+0x4AF8 US_ALU_EXT_ADDR_14
+0x4AFC US_ALU_EXT_ADDR_15
+0x4B00 US_ALU_EXT_ADDR_16
+0x4B04 US_ALU_EXT_ADDR_17
+0x4B08 US_ALU_EXT_ADDR_18
+0x4B0C US_ALU_EXT_ADDR_19
+0x4B10 US_ALU_EXT_ADDR_20
+0x4B14 US_ALU_EXT_ADDR_21
+0x4B18 US_ALU_EXT_ADDR_22
+0x4B1C US_ALU_EXT_ADDR_23
+0x4B20 US_ALU_EXT_ADDR_24
+0x4B24 US_ALU_EXT_ADDR_25
+0x4B28 US_ALU_EXT_ADDR_26
+0x4B2C US_ALU_EXT_ADDR_27
+0x4B30 US_ALU_EXT_ADDR_28
+0x4B34 US_ALU_EXT_ADDR_29
+0x4B38 US_ALU_EXT_ADDR_30
+0x4B3C US_ALU_EXT_ADDR_31
+0x4B40 US_ALU_EXT_ADDR_32
+0x4B44 US_ALU_EXT_ADDR_33
+0x4B48 US_ALU_EXT_ADDR_34
+0x4B4C US_ALU_EXT_ADDR_35
+0x4B50 US_ALU_EXT_ADDR_36
+0x4B54 US_ALU_EXT_ADDR_37
+0x4B58 US_ALU_EXT_ADDR_38
+0x4B5C US_ALU_EXT_ADDR_39
+0x4B60 US_ALU_EXT_ADDR_40
+0x4B64 US_ALU_EXT_ADDR_41
+0x4B68 US_ALU_EXT_ADDR_42
+0x4B6C US_ALU_EXT_ADDR_43
+0x4B70 US_ALU_EXT_ADDR_44
+0x4B74 US_ALU_EXT_ADDR_45
+0x4B78 US_ALU_EXT_ADDR_46
+0x4B7C US_ALU_EXT_ADDR_47
+0x4B80 US_ALU_EXT_ADDR_48
+0x4B84 US_ALU_EXT_ADDR_49
+0x4B88 US_ALU_EXT_ADDR_50
+0x4B8C US_ALU_EXT_ADDR_51
+0x4B90 US_ALU_EXT_ADDR_52
+0x4B94 US_ALU_EXT_ADDR_53
+0x4B98 US_ALU_EXT_ADDR_54
+0x4B9C US_ALU_EXT_ADDR_55
+0x4BA0 US_ALU_EXT_ADDR_56
+0x4BA4 US_ALU_EXT_ADDR_57
+0x4BA8 US_ALU_EXT_ADDR_58
+0x4BAC US_ALU_EXT_ADDR_59
+0x4BB0 US_ALU_EXT_ADDR_60
+0x4BB4 US_ALU_EXT_ADDR_61
+0x4BB8 US_ALU_EXT_ADDR_62
+0x4BBC US_ALU_EXT_ADDR_63
+0x4BC0 FG_FOG_BLEND
+0x4BC4 FG_FOG_FACTOR
+0x4BC8 FG_FOG_COLOR_R
+0x4BCC FG_FOG_COLOR_G
+0x4BD0 FG_FOG_COLOR_B
+0x4BD4 FG_ALPHA_FUNC
+0x4BD8 FG_DEPTH_SRC
+0x4C00 US_ALU_CONST_R_0
+0x4C04 US_ALU_CONST_G_0
+0x4C08 US_ALU_CONST_B_0
+0x4C0C US_ALU_CONST_A_0
+0x4C10 US_ALU_CONST_R_1
+0x4C14 US_ALU_CONST_G_1
+0x4C18 US_ALU_CONST_B_1
+0x4C1C US_ALU_CONST_A_1
+0x4C20 US_ALU_CONST_R_2
+0x4C24 US_ALU_CONST_G_2
+0x4C28 US_ALU_CONST_B_2
+0x4C2C US_ALU_CONST_A_2
+0x4C30 US_ALU_CONST_R_3
+0x4C34 US_ALU_CONST_G_3
+0x4C38 US_ALU_CONST_B_3
+0x4C3C US_ALU_CONST_A_3
+0x4C40 US_ALU_CONST_R_4
+0x4C44 US_ALU_CONST_G_4
+0x4C48 US_ALU_CONST_B_4
+0x4C4C US_ALU_CONST_A_4
+0x4C50 US_ALU_CONST_R_5
+0x4C54 US_ALU_CONST_G_5
+0x4C58 US_ALU_CONST_B_5
+0x4C5C US_ALU_CONST_A_5
+0x4C60 US_ALU_CONST_R_6
+0x4C64 US_ALU_CONST_G_6
+0x4C68 US_ALU_CONST_B_6
+0x4C6C US_ALU_CONST_A_6
+0x4C70 US_ALU_CONST_R_7
+0x4C74 US_ALU_CONST_G_7
+0x4C78 US_ALU_CONST_B_7
+0x4C7C US_ALU_CONST_A_7
+0x4C80 US_ALU_CONST_R_8
+0x4C84 US_ALU_CONST_G_8
+0x4C88 US_ALU_CONST_B_8
+0x4C8C US_ALU_CONST_A_8
+0x4C90 US_ALU_CONST_R_9
+0x4C94 US_ALU_CONST_G_9
+0x4C98 US_ALU_CONST_B_9
+0x4C9C US_ALU_CONST_A_9
+0x4CA0 US_ALU_CONST_R_10
+0x4CA4 US_ALU_CONST_G_10
+0x4CA8 US_ALU_CONST_B_10
+0x4CAC US_ALU_CONST_A_10
+0x4CB0 US_ALU_CONST_R_11
+0x4CB4 US_ALU_CONST_G_11
+0x4CB8 US_ALU_CONST_B_11
+0x4CBC US_ALU_CONST_A_11
+0x4CC0 US_ALU_CONST_R_12
+0x4CC4 US_ALU_CONST_G_12
+0x4CC8 US_ALU_CONST_B_12
+0x4CCC US_ALU_CONST_A_12
+0x4CD0 US_ALU_CONST_R_13
+0x4CD4 US_ALU_CONST_G_13
+0x4CD8 US_ALU_CONST_B_13
+0x4CDC US_ALU_CONST_A_13
+0x4CE0 US_ALU_CONST_R_14
+0x4CE4 US_ALU_CONST_G_14
+0x4CE8 US_ALU_CONST_B_14
+0x4CEC US_ALU_CONST_A_14
+0x4CF0 US_ALU_CONST_R_15
+0x4CF4 US_ALU_CONST_G_15
+0x4CF8 US_ALU_CONST_B_15
+0x4CFC US_ALU_CONST_A_15
+0x4D00 US_ALU_CONST_R_16
+0x4D04 US_ALU_CONST_G_16
+0x4D08 US_ALU_CONST_B_16
+0x4D0C US_ALU_CONST_A_16
+0x4D10 US_ALU_CONST_R_17
+0x4D14 US_ALU_CONST_G_17
+0x4D18 US_ALU_CONST_B_17
+0x4D1C US_ALU_CONST_A_17
+0x4D20 US_ALU_CONST_R_18
+0x4D24 US_ALU_CONST_G_18
+0x4D28 US_ALU_CONST_B_18
+0x4D2C US_ALU_CONST_A_18
+0x4D30 US_ALU_CONST_R_19
+0x4D34 US_ALU_CONST_G_19
+0x4D38 US_ALU_CONST_B_19
+0x4D3C US_ALU_CONST_A_19
+0x4D40 US_ALU_CONST_R_20
+0x4D44 US_ALU_CONST_G_20
+0x4D48 US_ALU_CONST_B_20
+0x4D4C US_ALU_CONST_A_20
+0x4D50 US_ALU_CONST_R_21
+0x4D54 US_ALU_CONST_G_21
+0x4D58 US_ALU_CONST_B_21
+0x4D5C US_ALU_CONST_A_21
+0x4D60 US_ALU_CONST_R_22
+0x4D64 US_ALU_CONST_G_22
+0x4D68 US_ALU_CONST_B_22
+0x4D6C US_ALU_CONST_A_22
+0x4D70 US_ALU_CONST_R_23
+0x4D74 US_ALU_CONST_G_23
+0x4D78 US_ALU_CONST_B_23
+0x4D7C US_ALU_CONST_A_23
+0x4D80 US_ALU_CONST_R_24
+0x4D84 US_ALU_CONST_G_24
+0x4D88 US_ALU_CONST_B_24
+0x4D8C US_ALU_CONST_A_24
+0x4D90 US_ALU_CONST_R_25
+0x4D94 US_ALU_CONST_G_25
+0x4D98 US_ALU_CONST_B_25
+0x4D9C US_ALU_CONST_A_25
+0x4DA0 US_ALU_CONST_R_26
+0x4DA4 US_ALU_CONST_G_26
+0x4DA8 US_ALU_CONST_B_26
+0x4DAC US_ALU_CONST_A_26
+0x4DB0 US_ALU_CONST_R_27
+0x4DB4 US_ALU_CONST_G_27
+0x4DB8 US_ALU_CONST_B_27
+0x4DBC US_ALU_CONST_A_27
+0x4DC0 US_ALU_CONST_R_28
+0x4DC4 US_ALU_CONST_G_28
+0x4DC8 US_ALU_CONST_B_28
+0x4DCC US_ALU_CONST_A_28
+0x4DD0 US_ALU_CONST_R_29
+0x4DD4 US_ALU_CONST_G_29
+0x4DD8 US_ALU_CONST_B_29
+0x4DDC US_ALU_CONST_A_29
+0x4DE0 US_ALU_CONST_R_30
+0x4DE4 US_ALU_CONST_G_30
+0x4DE8 US_ALU_CONST_B_30
+0x4DEC US_ALU_CONST_A_30
+0x4DF0 US_ALU_CONST_R_31
+0x4DF4 US_ALU_CONST_G_31
+0x4DF8 US_ALU_CONST_B_31
+0x4DFC US_ALU_CONST_A_31
+0x4E04 RB3D_BLENDCNTL_R3
+0x4E08 RB3D_ABLENDCNTL_R3
+0x4E0C RB3D_COLOR_CHANNEL_MASK
+0x4E10 RB3D_CONSTANT_COLOR
+0x4E14 RB3D_COLOR_CLEAR_VALUE
+0x4E18 RB3D_ROPCNTL_R3
+0x4E1C RB3D_CLRCMP_FLIPE_R3
+0x4E20 RB3D_CLRCMP_CLR_R3
+0x4E24 RB3D_CLRCMP_MSK_R3
+0x4E48 RB3D_DEBUG_CTL
+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3
+0x4E50 RB3D_DITHER_CTL
+0x4E54 RB3D_CMASK_OFFSET0
+0x4E58 RB3D_CMASK_OFFSET1
+0x4E5C RB3D_CMASK_OFFSET2
+0x4E60 RB3D_CMASK_OFFSET3
+0x4E64 RB3D_CMASK_PITCH0
+0x4E68 RB3D_CMASK_PITCH1
+0x4E6C RB3D_CMASK_PITCH2
+0x4E70 RB3D_CMASK_PITCH3
+0x4E74 RB3D_CMASK_WRINDEX
+0x4E78 RB3D_CMASK_DWORD
+0x4E7C RB3D_CMASK_RDINDEX
+0x4E80 RB3D_AARESOLVE_OFFSET
+0x4E84 RB3D_AARESOLVE_PITCH
+0x4E88 RB3D_AARESOLVE_CTL
+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
+0x4F04 ZB_ZSTENCILCNTL
+0x4F08 ZB_STENCILREFMASK
+0x4F14 ZB_ZTOP
+0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F1C ZB_BW_CNTL
+0x4F28 ZB_DEPTHCLEARVALUE
+0x4F30 ZB_ZMASK_OFFSET
+0x4F34 ZB_ZMASK_PITCH
+0x4F38 ZB_ZMASK_WRINDEX
+0x4F3C ZB_ZMASK_DWORD
+0x4F40 ZB_ZMASK_RDINDEX
+0x4F44 ZB_HIZ_OFFSET
+0x4F48 ZB_HIZ_WRINDEX
+0x4F4C ZB_HIZ_DWORD
+0x4F50 ZB_HIZ_RDINDEX
+0x4F54 ZB_HIZ_PITCH
+0x4F58 ZB_ZPASS_DATA
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600 linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rs600	2010-02-24 13:52:17.000000000 -0500
@@ -153,7 +153,7 @@ rs600 0x6d40
 0x42A4 SU_POLY_OFFSET_FRONT_SCALE
 0x42A8 SU_POLY_OFFSET_FRONT_OFFSET
 0x42AC SU_POLY_OFFSET_BACK_SCALE
-0x42B0 SU_POLY_OFFSET_BACK_OFFSET 
+0x42B0 SU_POLY_OFFSET_BACK_OFFSET
 0x42B4 SU_POLY_OFFSET_ENABLE
 0x42B8 SU_CULL_MODE
 0x42C0 SU_DEPTH_SCALE
@@ -291,6 +291,8 @@ rs600 0x6d40
 0x46AC US_OUT_FMT_2
 0x46B0 US_OUT_FMT_3
 0x46B4 US_W_FMT
+0x46B8 US_CODE_BANK
+0x46BC US_CODE_EXT
 0x46C0 US_ALU_RGB_ADDR_0
 0x46C4 US_ALU_RGB_ADDR_1
 0x46C8 US_ALU_RGB_ADDR_2
@@ -547,6 +549,70 @@ rs600 0x6d40
 0x4AB4 US_ALU_ALPHA_INST_61
 0x4AB8 US_ALU_ALPHA_INST_62
 0x4ABC US_ALU_ALPHA_INST_63
+0x4AC0 US_ALU_EXT_ADDR_0
+0x4AC4 US_ALU_EXT_ADDR_1
+0x4AC8 US_ALU_EXT_ADDR_2
+0x4ACC US_ALU_EXT_ADDR_3
+0x4AD0 US_ALU_EXT_ADDR_4
+0x4AD4 US_ALU_EXT_ADDR_5
+0x4AD8 US_ALU_EXT_ADDR_6
+0x4ADC US_ALU_EXT_ADDR_7
+0x4AE0 US_ALU_EXT_ADDR_8
+0x4AE4 US_ALU_EXT_ADDR_9
+0x4AE8 US_ALU_EXT_ADDR_10
+0x4AEC US_ALU_EXT_ADDR_11
+0x4AF0 US_ALU_EXT_ADDR_12
+0x4AF4 US_ALU_EXT_ADDR_13
+0x4AF8 US_ALU_EXT_ADDR_14
+0x4AFC US_ALU_EXT_ADDR_15
+0x4B00 US_ALU_EXT_ADDR_16
+0x4B04 US_ALU_EXT_ADDR_17
+0x4B08 US_ALU_EXT_ADDR_18
+0x4B0C US_ALU_EXT_ADDR_19
+0x4B10 US_ALU_EXT_ADDR_20
+0x4B14 US_ALU_EXT_ADDR_21
+0x4B18 US_ALU_EXT_ADDR_22
+0x4B1C US_ALU_EXT_ADDR_23
+0x4B20 US_ALU_EXT_ADDR_24
+0x4B24 US_ALU_EXT_ADDR_25
+0x4B28 US_ALU_EXT_ADDR_26
+0x4B2C US_ALU_EXT_ADDR_27
+0x4B30 US_ALU_EXT_ADDR_28
+0x4B34 US_ALU_EXT_ADDR_29
+0x4B38 US_ALU_EXT_ADDR_30
+0x4B3C US_ALU_EXT_ADDR_31
+0x4B40 US_ALU_EXT_ADDR_32
+0x4B44 US_ALU_EXT_ADDR_33
+0x4B48 US_ALU_EXT_ADDR_34
+0x4B4C US_ALU_EXT_ADDR_35
+0x4B50 US_ALU_EXT_ADDR_36
+0x4B54 US_ALU_EXT_ADDR_37
+0x4B58 US_ALU_EXT_ADDR_38
+0x4B5C US_ALU_EXT_ADDR_39
+0x4B60 US_ALU_EXT_ADDR_40
+0x4B64 US_ALU_EXT_ADDR_41
+0x4B68 US_ALU_EXT_ADDR_42
+0x4B6C US_ALU_EXT_ADDR_43
+0x4B70 US_ALU_EXT_ADDR_44
+0x4B74 US_ALU_EXT_ADDR_45
+0x4B78 US_ALU_EXT_ADDR_46
+0x4B7C US_ALU_EXT_ADDR_47
+0x4B80 US_ALU_EXT_ADDR_48
+0x4B84 US_ALU_EXT_ADDR_49
+0x4B88 US_ALU_EXT_ADDR_50
+0x4B8C US_ALU_EXT_ADDR_51
+0x4B90 US_ALU_EXT_ADDR_52
+0x4B94 US_ALU_EXT_ADDR_53
+0x4B98 US_ALU_EXT_ADDR_54
+0x4B9C US_ALU_EXT_ADDR_55
+0x4BA0 US_ALU_EXT_ADDR_56
+0x4BA4 US_ALU_EXT_ADDR_57
+0x4BA8 US_ALU_EXT_ADDR_58
+0x4BAC US_ALU_EXT_ADDR_59
+0x4BB0 US_ALU_EXT_ADDR_60
+0x4BB4 US_ALU_EXT_ADDR_61
+0x4BB8 US_ALU_EXT_ADDR_62
+0x4BBC US_ALU_EXT_ADDR_63
 0x4BC0 FG_FOG_BLEND
 0x4BC4 FG_FOG_FACTOR
 0x4BC8 FG_FOG_COLOR_R
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515 linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/reg_srcs/rv515	2010-02-24 13:52:17.000000000 -0500
@@ -161,7 +161,12 @@ rv515 0x6d40
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
+0x4028 GB_Z_PEQ_CONFIG
 0x4100 TX_INVALTAGS
+0x4114 SU_TEX_WRAP_PS3
+0x4118 PS3_ENABLE
+0x411c PS3_VTX_FMT
+0x4120 PS3_TEX_SOURCE
 0x4200 GA_POINT_S0
 0x4204 GA_POINT_T0
 0x4208 GA_POINT_S1
@@ -171,6 +176,7 @@ rv515 0x6d40
 0x4230 GA_POINT_MINMAX
 0x4234 GA_LINE_CNTL
 0x4238 GA_LINE_STIPPLE_CONFIG
+0x4258 GA_COLOR_CONTROL_PS3
 0x4260 GA_LINE_STIPPLE_VALUE
 0x4264 GA_LINE_S0
 0x4268 GA_LINE_S1
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs400.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs400.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs400.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs400.c	2010-02-24 13:52:17.000000000 -0500
@@ -223,15 +223,31 @@ int rs400_gart_set_page(struct radeon_de
 	return 0;
 }
 
+int rs400_mc_wait_for_idle(struct radeon_device *rdev)
+{
+	unsigned i;
+	uint32_t tmp;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		/* read MC_STATUS */
+		tmp = RREG32(0x0150);
+		if (tmp & (1 << 2)) {
+			return 0;
+		}
+		DRM_UDELAY(1);
+	}
+	return -1;
+}
+
 void rs400_gpu_init(struct radeon_device *rdev)
 {
 	/* FIXME: HDP same place on rs400 ? */
 	r100_hdp_reset(rdev);
 	/* FIXME: is this correct ? */
 	r420_pipes_init(rdev);
-	if (r300_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
+	if (rs400_mc_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "rs400: Failed to wait MC idle while "
+		       "programming pipes. Bad things might happen. %08x\n", RREG32(0x150));
 	}
 }
 
@@ -352,10 +368,11 @@ static int rs400_mc_init(struct radeon_d
 	u32 tmp;
 
 	/* Setup GPU memory space */
-	tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+	tmp = RREG32(R_00015C_NB_TOM);
 	rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
 	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev);
 	if (r)
 		return r;
 	return 0;
@@ -369,8 +386,8 @@ void rs400_mc_program(struct radeon_devi
 	r100_mc_stop(rdev, &save);
 
 	/* Wait for mc idle */
-	if (r300_mc_wait_for_idle(rdev))
-		dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
+	if (rs400_mc_wait_for_idle(rdev))
+		dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n");
 	WREG32(R_000148_MC_FB_LOCATION,
 		S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
 		S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
@@ -387,14 +404,15 @@ static int rs400_startup(struct radeon_d
 	r300_clock_startup(rdev);
 	/* Initialize GPU configuration (# pipes, ...) */
 	rs400_gpu_init(rdev);
+	r100_enable_bm(rdev);
 	/* Initialize GART (initialize after TTM so we can allocate
 	 * memory through TTM but finalize after TTM) */
 	r = rs400_gart_enable(rdev);
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	r100_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -430,6 +448,8 @@ int rs400_resume(struct radeon_device *r
 	radeon_combios_asic_init(rdev->ddev);
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs400_startup(rdev);
 }
 
@@ -444,7 +464,6 @@ int rs400_suspend(struct radeon_device *
 
 void rs400_fini(struct radeon_device *rdev)
 {
-	rs400_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -452,7 +471,7 @@ void rs400_fini(struct radeon_device *rd
 	rs400_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -490,12 +509,13 @@ int rs400_init(struct radeon_device *rde
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		radeon_combios_asic_init(rdev->ddev);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
+	/* Initialize power management */
+	radeon_pm_init(rdev);
 	/* Get vram informations */
 	rs400_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
@@ -510,7 +530,7 @@ int rs400_init(struct radeon_device *rde
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs400_gart_init(rdev);
@@ -522,7 +542,6 @@ int rs400_init(struct radeon_device *rde
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		rs400_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs600.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs600.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,6 +45,124 @@
 void rs600_gpu_init(struct radeon_device *rdev);
 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
 
+int rs600_mc_init(struct radeon_device *rdev)
+{
+	/* read back the MC value from the hw */
+	int r;
+	u32 tmp;
+
+	/* Setup GPU memory space */
+	tmp = RREG32_MC(R_000004_MC_FB_LOCATION);
+	rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16;
+	rdev->mc.gtt_location = 0xffffffffUL;
+	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
+/* hpd for digital panel detect/disconnect */
+bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = false;
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS);
+		if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp))
+			connected = true;
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS);
+		if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp))
+			connected = true;
+		break;
+	default:
+		break;
+	}
+	return connected;
+}
+
+void rs600_hpd_set_polarity(struct radeon_device *rdev,
+			    enum radeon_hpd_id hpd)
+{
+	u32 tmp;
+	bool connected = rs600_hpd_sense(rdev, hpd);
+
+	switch (hpd) {
+	case RADEON_HPD_1:
+		tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
+		if (connected)
+			tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
+		else
+			tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1);
+		WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		break;
+	case RADEON_HPD_2:
+		tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
+		if (connected)
+			tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
+		else
+			tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1);
+		WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		break;
+	default:
+		break;
+	}
+}
+
+void rs600_hpd_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
+			       S_007D00_DC_HOT_PLUG_DETECT1_EN(1));
+			rdev->irq.hpd[0] = true;
+			break;
+		case RADEON_HPD_2:
+			WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+			       S_007D10_DC_HOT_PLUG_DETECT2_EN(1));
+			rdev->irq.hpd[1] = true;
+			break;
+		default:
+			break;
+		}
+	}
+	if (rdev->irq.installed)
+		rs600_irq_set(rdev);
+}
+
+void rs600_hpd_fini(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+		switch (radeon_connector->hpd.hpd) {
+		case RADEON_HPD_1:
+			WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL,
+			       S_007D00_DC_HOT_PLUG_DETECT1_EN(0));
+			rdev->irq.hpd[0] = false;
+			break;
+		case RADEON_HPD_2:
+			WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+			       S_007D10_DC_HOT_PLUG_DETECT2_EN(0));
+			rdev->irq.hpd[1] = false;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 /*
  * GART.
  */
@@ -100,40 +218,40 @@ int rs600_gart_enable(struct radeon_devi
 	WREG32(R_00004C_BUS_CNTL, tmp);
 	/* FIXME: setup default page */
 	WREG32_MC(R_000100_MC_PT0_CNTL,
-		 (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
-		  S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
+		  (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
+		   S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
+
 	for (i = 0; i < 19; i++) {
 		WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
-			S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
-			S_00016C_SYSTEM_ACCESS_MODE_MASK(
-				V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
-			S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
-				V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
-			S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
-			S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
-			S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
+			  S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
+			  S_00016C_SYSTEM_ACCESS_MODE_MASK(
+				  V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) |
+			  S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
+				  V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) |
+			  S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) |
+			  S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
+			  S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3));
 	}
-
-	/* System context map to GART space */
-	WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
-	WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
-
 	/* enable first context */
-	WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
-	WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
 	WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
-			S_000102_ENABLE_PAGE_TABLE(1) |
-			S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
+		  S_000102_ENABLE_PAGE_TABLE(1) |
+		  S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
+
 	/* disable all other contexts */
-	for (i = 1; i < 8; i++) {
+	for (i = 1; i < 8; i++)
 		WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
-	}
 
 	/* setup the page table */
 	WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
-			rdev->gart.table_addr);
+		  rdev->gart.table_addr);
+	WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
+	WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
 	WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
 
+	/* System context maps to VRAM space */
+	WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start);
+	WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end);
+
 	/* enable page tables */
 	tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
 	WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
@@ -146,15 +264,20 @@ int rs600_gart_enable(struct radeon_devi
 
 void rs600_gart_disable(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u32 tmp;
+	int r;
 
 	/* FIXME: disable out of gart access */
 	WREG32_MC(R_000100_MC_PT0_CNTL, 0);
 	tmp = RREG32_MC(R_000009_MC_CNTL1);
 	WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (r == 0) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -189,7 +312,16 @@ int rs600_irq_set(struct radeon_device *
 {
 	uint32_t tmp = 0;
 	uint32_t mode_int = 0;
+	u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) &
+		~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
+	u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) &
+		~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+		WREG32(R_000040_GEN_INT_CNTL, 0);
+		return -EINVAL;
+	}
 	if (rdev->irq.sw_int) {
 		tmp |= S_000040_SW_INT_EN(1);
 	}
@@ -199,8 +331,16 @@ int rs600_irq_set(struct radeon_device *
 	if (rdev->irq.crtc_vblank_int[1]) {
 		mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1);
 	}
+	if (rdev->irq.hpd[0]) {
+		hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1);
+	}
+	if (rdev->irq.hpd[1]) {
+		hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
+	}
 	WREG32(R_000040_GEN_INT_CNTL, tmp);
 	WREG32(R_006540_DxMODE_INT_MASK, mode_int);
+	WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
+	WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
 	return 0;
 }
 
@@ -208,6 +348,7 @@ static inline uint32_t rs600_irq_ack(str
 {
 	uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS);
 	uint32_t irq_mask = ~C_000044_SW_INT;
+	u32 tmp;
 
 	if (G_000044_DISPLAY_INT_STAT(irqs)) {
 		*r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
@@ -219,6 +360,16 @@ static inline uint32_t rs600_irq_ack(str
 			WREG32(R_006D34_D2MODE_VBLANK_STATUS,
 				S_006D34_D2MODE_VBLANK_ACK(1));
 		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) {
+			tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL);
+			tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1);
+			WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
+		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) {
+			tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL);
+			tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1);
+			WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
+		}
 	} else {
 		*r500_disp_int = 0;
 	}
@@ -244,6 +395,7 @@ int rs600_irq_process(struct radeon_devi
 {
 	uint32_t status, msi_rearm;
 	uint32_t r500_disp_int;
+	bool queue_hotplug = false;
 
 	status = rs600_irq_ack(rdev, &r500_disp_int);
 	if (!status && !r500_disp_int) {
@@ -251,15 +403,25 @@ int rs600_irq_process(struct radeon_devi
 	}
 	while (status || r500_disp_int) {
 		/* SW interrupt */
-		if (G_000040_SW_INT_EN(status))
+		if (G_000044_SW_INT(status))
 			radeon_fence_process(rdev);
 		/* Vertical blank interrupts */
 		if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int))
 			drm_handle_vblank(rdev->ddev, 0);
 		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
 			drm_handle_vblank(rdev->ddev, 1);
+		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD1\n");
+		}
+		if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) {
+			queue_hotplug = true;
+			DRM_DEBUG("HPD2\n");
+		}
 		status = rs600_irq_ack(rdev, &r500_disp_int);
 	}
+	if (queue_hotplug)
+		queue_work(rdev->wq, &rdev->hotplug_work);
 	if (rdev->msi_enabled) {
 		switch (rdev->family) {
 		case CHIP_RS600:
@@ -301,9 +463,7 @@ int rs600_mc_wait_for_idle(struct radeon
 
 void rs600_gpu_init(struct radeon_device *rdev)
 {
-	/* FIXME: HDP same place on rs600 ? */
 	r100_hdp_reset(rdev);
-	/* FIXME: is this correct ? */
 	r420_pipes_init(rdev);
 	/* Wait for mc idle */
 	if (rs600_mc_wait_for_idle(rdev))
@@ -312,9 +472,20 @@ void rs600_gpu_init(struct radeon_device
 
 void rs600_vram_info(struct radeon_device *rdev)
 {
-	/* FIXME: to do or is these values sane ? */
 	rdev->mc.vram_is_ddr = true;
 	rdev->mc.vram_width = 128;
+
+	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
+	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+		rdev->mc.mc_vram_size = rdev->mc.aper_size;
+
+	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+		rdev->mc.real_vram_size = rdev->mc.aper_size;
 }
 
 void rs600_bandwidth_update(struct radeon_device *rdev)
@@ -388,8 +559,8 @@ static int rs600_startup(struct radeon_d
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -423,6 +594,8 @@ int rs600_resume(struct radeon_device *r
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs600_startup(rdev);
 }
 
@@ -437,7 +610,6 @@ int rs600_suspend(struct radeon_device *
 
 void rs600_fini(struct radeon_device *rdev)
 {
-	rs600_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -445,7 +617,7 @@ void rs600_fini(struct radeon_device *rd
 	rs600_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -482,10 +654,9 @@ int rs600_init(struct radeon_device *rde
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -493,7 +664,7 @@ int rs600_init(struct radeon_device *rde
 	/* Get vram informations */
 	rs600_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
+	r = rs600_mc_init(rdev);
 	if (r)
 		return r;
 	rs600_debugfs(rdev);
@@ -505,7 +676,7 @@ int rs600_init(struct radeon_device *rde
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs600_gart_init(rdev);
@@ -517,7 +688,6 @@ int rs600_init(struct radeon_device *rde
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		rs600_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs600d.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600d.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs600d.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs600d.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,27 +30,12 @@
 
 /* Registers */
 #define R_000040_GEN_INT_CNTL                        0x000040
-#define   S_000040_DISPLAY_INT_STATUS(x)               (((x) & 0x1) << 0)
-#define   G_000040_DISPLAY_INT_STATUS(x)               (((x) >> 0) & 0x1)
-#define   C_000040_DISPLAY_INT_STATUS                  0xFFFFFFFE
-#define   S_000040_DMA_VIPH0_INT_EN(x)                 (((x) & 0x1) << 12)
-#define   G_000040_DMA_VIPH0_INT_EN(x)                 (((x) >> 12) & 0x1)
-#define   C_000040_DMA_VIPH0_INT_EN                    0xFFFFEFFF
-#define   S_000040_CRTC2_VSYNC(x)                      (((x) & 0x1) << 6)
-#define   G_000040_CRTC2_VSYNC(x)                      (((x) >> 6) & 0x1)
-#define   C_000040_CRTC2_VSYNC                         0xFFFFFFBF
-#define   S_000040_SNAPSHOT2(x)                        (((x) & 0x1) << 7)
-#define   G_000040_SNAPSHOT2(x)                        (((x) >> 7) & 0x1)
-#define   C_000040_SNAPSHOT2                           0xFFFFFF7F
-#define   S_000040_CRTC2_VBLANK(x)                     (((x) & 0x1) << 9)
-#define   G_000040_CRTC2_VBLANK(x)                     (((x) >> 9) & 0x1)
-#define   C_000040_CRTC2_VBLANK                        0xFFFFFDFF
-#define   S_000040_FP2_DETECT(x)                       (((x) & 0x1) << 10)
-#define   G_000040_FP2_DETECT(x)                       (((x) >> 10) & 0x1)
-#define   C_000040_FP2_DETECT                          0xFFFFFBFF
-#define   S_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) & 0x1) << 11)
-#define   G_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) >> 11) & 0x1)
-#define   C_000040_VSYNC_DIFF_OVER_LIMIT               0xFFFFF7FF
+#define   S_000040_SCRATCH_INT_MASK(x)                 (((x) & 0x1) << 18)
+#define   G_000040_SCRATCH_INT_MASK(x)                 (((x) >> 18) & 0x1)
+#define   C_000040_SCRATCH_INT_MASK                    0xFFFBFFFF
+#define   S_000040_GUI_IDLE_MASK(x)                    (((x) & 0x1) << 19)
+#define   G_000040_GUI_IDLE_MASK(x)                    (((x) >> 19) & 0x1)
+#define   C_000040_GUI_IDLE_MASK                       0xFFF7FFFF
 #define   S_000040_DMA_VIPH1_INT_EN(x)                 (((x) & 0x1) << 13)
 #define   G_000040_DMA_VIPH1_INT_EN(x)                 (((x) >> 13) & 0x1)
 #define   C_000040_DMA_VIPH1_INT_EN                    0xFFFFDFFF
@@ -370,7 +355,90 @@
 #define   S_007EDC_LB_D2_VBLANK_INTERRUPT(x)           (((x) & 0x1) << 5)
 #define   G_007EDC_LB_D2_VBLANK_INTERRUPT(x)           (((x) >> 5) & 0x1)
 #define   C_007EDC_LB_D2_VBLANK_INTERRUPT              0xFFFFFFDF
-
+#define   S_007EDC_DACA_AUTODETECT_INTERRUPT(x)        (((x) & 0x1) << 16)
+#define   G_007EDC_DACA_AUTODETECT_INTERRUPT(x)        (((x) >> 16) & 0x1)
+#define   C_007EDC_DACA_AUTODETECT_INTERRUPT           0xFFFEFFFF
+#define   S_007EDC_DACB_AUTODETECT_INTERRUPT(x)        (((x) & 0x1) << 17)
+#define   G_007EDC_DACB_AUTODETECT_INTERRUPT(x)        (((x) >> 17) & 0x1)
+#define   C_007EDC_DACB_AUTODETECT_INTERRUPT           0xFFFDFFFF
+#define   S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x)    (((x) & 0x1) << 18)
+#define   G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x)    (((x) >> 18) & 0x1)
+#define   C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT       0xFFFBFFFF
+#define   S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x)    (((x) & 0x1) << 19)
+#define   G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x)    (((x) >> 19) & 0x1)
+#define   C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT       0xFFF7FFFF
+#define R_007828_DACA_AUTODETECT_CONTROL               0x007828
+#define   S_007828_DACA_AUTODETECT_MODE(x)             (((x) & 0x3) << 0)
+#define   G_007828_DACA_AUTODETECT_MODE(x)             (((x) >> 0) & 0x3)
+#define   C_007828_DACA_AUTODETECT_MODE                0xFFFFFFFC
+#define   S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
+#define   G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
+#define   C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER  0xFFFF00FF
+#define   S_007828_DACA_AUTODETECT_CHECK_MASK(x)       (((x) & 0x3) << 16)
+#define   G_007828_DACA_AUTODETECT_CHECK_MASK(x)       (((x) >> 16) & 0x3)
+#define   C_007828_DACA_AUTODETECT_CHECK_MASK          0xFFFCFFFF
+#define R_007838_DACA_AUTODETECT_INT_CONTROL           0x007838
+#define   S_007838_DACA_AUTODETECT_ACK(x)              (((x) & 0x1) << 0)
+#define   C_007838_DACA_DACA_AUTODETECT_ACK            0xFFFFFFFE
+#define   S_007838_DACA_AUTODETECT_INT_ENABLE(x)       (((x) & 0x1) << 16)
+#define   G_007838_DACA_AUTODETECT_INT_ENABLE(x)       (((x) >> 16) & 0x1)
+#define   C_007838_DACA_AUTODETECT_INT_ENABLE          0xFFFCFFFF
+#define R_007A28_DACB_AUTODETECT_CONTROL               0x007A28
+#define   S_007A28_DACB_AUTODETECT_MODE(x)             (((x) & 0x3) << 0)
+#define   G_007A28_DACB_AUTODETECT_MODE(x)             (((x) >> 0) & 0x3)
+#define   C_007A28_DACB_AUTODETECT_MODE                0xFFFFFFFC
+#define   S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8)
+#define   G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff)
+#define   C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER  0xFFFF00FF
+#define   S_007A28_DACB_AUTODETECT_CHECK_MASK(x)       (((x) & 0x3) << 16)
+#define   G_007A28_DACB_AUTODETECT_CHECK_MASK(x)       (((x) >> 16) & 0x3)
+#define   C_007A28_DACB_AUTODETECT_CHECK_MASK          0xFFFCFFFF
+#define R_007A38_DACB_AUTODETECT_INT_CONTROL           0x007A38
+#define   S_007A38_DACB_AUTODETECT_ACK(x)              (((x) & 0x1) << 0)
+#define   C_007A38_DACB_DACA_AUTODETECT_ACK            0xFFFFFFFE
+#define   S_007A38_DACB_AUTODETECT_INT_ENABLE(x)       (((x) & 0x1) << 16)
+#define   G_007A38_DACB_AUTODETECT_INT_ENABLE(x)       (((x) >> 16) & 0x1)
+#define   C_007A38_DACB_AUTODETECT_INT_ENABLE          0xFFFCFFFF
+#define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL           0x007D00
+#define   S_007D00_DC_HOT_PLUG_DETECT1_EN(x)           (((x) & 0x1) << 0)
+#define   G_007D00_DC_HOT_PLUG_DETECT1_EN(x)           (((x) >> 0) & 0x1)
+#define   C_007D00_DC_HOT_PLUG_DETECT1_EN              0xFFFFFFFE
+#define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS        0x007D04
+#define   S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x)   (((x) & 0x1) << 0)
+#define   G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x)   (((x) >> 0) & 0x1)
+#define   C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS      0xFFFFFFFE
+#define   S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x)        (((x) & 0x1) << 1)
+#define   G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x)        (((x) >> 1) & 0x1)
+#define   C_007D04_DC_HOT_PLUG_DETECT1_SENSE           0xFFFFFFFD
+#define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL       0x007D08
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x)      (((x) & 0x1) << 0)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK         0xFFFFFFFE
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8)
+#define   G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY    0xFFFFFEFF
+#define   S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x)       (((x) & 0x1) << 16)
+#define   G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x)       (((x) >> 16) & 0x1)
+#define   C_007D08_DC_HOT_PLUG_DETECT1_INT_EN          0xFFFEFFFF
+#define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL           0x007D10
+#define   S_007D10_DC_HOT_PLUG_DETECT2_EN(x)           (((x) & 0x1) << 0)
+#define   G_007D10_DC_HOT_PLUG_DETECT2_EN(x)           (((x) >> 0) & 0x1)
+#define   C_007D10_DC_HOT_PLUG_DETECT2_EN              0xFFFFFFFE
+#define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS        0x007D14
+#define   S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x)   (((x) & 0x1) << 0)
+#define   G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x)   (((x) >> 0) & 0x1)
+#define   C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS      0xFFFFFFFE
+#define   S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x)        (((x) & 0x1) << 1)
+#define   G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x)        (((x) >> 1) & 0x1)
+#define   C_007D14_DC_HOT_PLUG_DETECT2_SENSE           0xFFFFFFFD
+#define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL       0x007D18
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x)      (((x) & 0x1) << 0)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK         0xFFFFFFFE
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8)
+#define   G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY    0xFFFFFEFF
+#define   S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x)       (((x) & 0x1) << 16)
+#define   G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x)       (((x) >> 16) & 0x1)
+#define   C_007D18_DC_HOT_PLUG_DETECT2_INT_EN          0xFFFEFFFF
 
 /* MC registers */
 #define R_000000_MC_STATUS                           0x000000
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs690.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rs690.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rs690.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,24 +131,25 @@ void rs690_pm_info(struct radeon_device
 
 void rs690_vram_info(struct radeon_device *rdev)
 {
-	uint32_t tmp;
 	fixed20_12 a;
 
 	rs400_gart_adjust_size(rdev);
-	/* DDR for all card after R300 & IGP */
+
 	rdev->mc.vram_is_ddr = true;
-	/* FIXME: is this correct for RS690/RS740 ? */
-	tmp = RREG32(RADEON_MEM_CNTL);
-	if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
-		rdev->mc.vram_width = 128;
-	} else {
-		rdev->mc.vram_width = 64;
-	}
+	rdev->mc.vram_width = 128;
+
 	rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
 	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
 
 	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
 	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+
+	if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+		rdev->mc.mc_vram_size = rdev->mc.aper_size;
+
+	if (rdev->mc.real_vram_size > rdev->mc.aper_size)
+		rdev->mc.real_vram_size = rdev->mc.aper_size;
+
 	rs690_pm_info(rdev);
 	/* FIXME: we should enforce default clock in case GPU is not in
 	 * default setup
@@ -161,6 +162,22 @@ void rs690_vram_info(struct radeon_devic
 	rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
 }
 
+static int rs690_mc_init(struct radeon_device *rdev)
+{
+	int r;
+	u32 tmp;
+
+	/* Setup GPU memory space */
+	tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
+	rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16;
+	rdev->mc.gtt_location = 0xFFFFFFFFUL;
+	r = radeon_mc_setup(rdev);
+	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
 void rs690_line_buffer_adjust(struct radeon_device *rdev,
 			      struct drm_display_mode *mode1,
 			      struct drm_display_mode *mode2)
@@ -244,8 +261,9 @@ void rs690_crtc_bandwidth_compute(struct
 
 	b.full = rfixed_const(mode->crtc_hdisplay);
 	c.full = rfixed_const(256);
-	a.full = rfixed_mul(wm->num_line_pair, b);
-	request_fifo_depth.full = rfixed_div(a, c);
+	a.full = rfixed_div(b, c);
+	request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
+	request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
 	if (a.full < rfixed_const(4)) {
 		wm->lb_request_fifo_depth = 4;
 	} else {
@@ -374,6 +392,7 @@ void rs690_crtc_bandwidth_compute(struct
 	a.full = rfixed_const(16);
 	wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
 	wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
+	wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
 
 	/* Determine estimated width */
 	estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
@@ -383,6 +402,7 @@ void rs690_crtc_bandwidth_compute(struct
 	} else {
 		a.full = rfixed_const(16);
 		wm->priority_mark.full = rfixed_div(estimated_width, a);
+		wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
 		wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
 	}
 }
@@ -605,8 +625,8 @@ static int rs690_startup(struct radeon_d
 	if (r)
 		return r;
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -640,6 +660,8 @@ int rs690_resume(struct radeon_device *r
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rs690_startup(rdev);
 }
 
@@ -654,7 +676,6 @@ int rs690_suspend(struct radeon_device *
 
 void rs690_fini(struct radeon_device *rdev)
 {
-	rs690_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
@@ -662,7 +683,7 @@ void rs690_fini(struct radeon_device *rd
 	rs400_gart_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -700,10 +721,9 @@ int rs690_init(struct radeon_device *rde
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
+
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -711,7 +731,7 @@ int rs690_init(struct radeon_device *rde
 	/* Get vram informations */
 	rs690_vram_info(rdev);
 	/* Initialize memory controller (also test AGP) */
-	r = r420_mc_init(rdev);
+	r = rs690_mc_init(rdev);
 	if (r)
 		return r;
 	rv515_debugfs(rdev);
@@ -723,7 +743,7 @@ int rs690_init(struct radeon_device *rde
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rs400_gart_init(rdev);
@@ -735,7 +755,6 @@ int rs690_init(struct radeon_device *rde
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		rs690_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rv515.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv515.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rv515.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv515.c	2010-02-24 13:52:17.000000000 -0500
@@ -478,8 +478,8 @@ static int rv515_startup(struct radeon_d
 			return r;
 	}
 	/* Enable IRQ */
-	rdev->irq.sw_int = true;
 	rs600_irq_set(rdev);
+	rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
 	/* 1M ring buffer */
 	r = r100_cp_init(rdev, 1024 * 1024);
 	if (r) {
@@ -514,6 +514,8 @@ int rv515_resume(struct radeon_device *r
 	atom_asic_init(rdev->mode_info.atom_context);
 	/* Resume clock after posting */
 	rv515_clock_startup(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
 	return rv515_startup(rdev);
 }
 
@@ -535,16 +537,15 @@ void rv515_set_safe_registers(struct rad
 
 void rv515_fini(struct radeon_device *rdev)
 {
-	rv515_suspend(rdev);
 	r100_cp_fini(rdev);
 	r100_wb_fini(rdev);
 	r100_ib_fini(rdev);
 	radeon_gem_fini(rdev);
-    rv370_pcie_gart_fini(rdev);
+	rv370_pcie_gart_fini(rdev);
 	radeon_agp_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	radeon_fence_driver_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
@@ -580,10 +581,8 @@ int rv515_init(struct radeon_device *rde
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		atom_asic_init(rdev->mode_info.atom_context);
-	}
+	if (radeon_boot_test_post_card(rdev) == false)
+		return -EINVAL;
 	/* Initialize clocks */
 	radeon_get_clock_info(rdev->ddev);
 	/* Initialize power management */
@@ -603,7 +602,7 @@ int rv515_init(struct radeon_device *rde
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
 	if (r)
 		return r;
 	r = rv370_pcie_gart_init(rdev);
@@ -615,13 +614,12 @@ int rv515_init(struct radeon_device *rde
 	if (r) {
 		/* Somethings want wront with the accel init stop accel */
 		dev_err(rdev->dev, "Disabling GPU acceleration\n");
-		rv515_suspend(rdev);
 		r100_cp_fini(rdev);
 		r100_wb_fini(rdev);
 		r100_ib_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		rv370_pcie_gart_fini(rdev);
 		radeon_agp_fini(rdev);
-		radeon_irq_kms_fini(rdev);
 		rdev->accel_working = false;
 	}
 	return 0;
@@ -892,8 +890,9 @@ void rv515_crtc_bandwidth_compute(struct
 
 	b.full = rfixed_const(mode->crtc_hdisplay);
 	c.full = rfixed_const(256);
-	a.full = rfixed_mul(wm->num_line_pair, b);
-	request_fifo_depth.full = rfixed_div(a, c);
+	a.full = rfixed_div(b, c);
+	request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair);
+	request_fifo_depth.full = rfixed_ceil(request_fifo_depth);
 	if (a.full < rfixed_const(4)) {
 		wm->lb_request_fifo_depth = 4;
 	} else {
@@ -995,15 +994,17 @@ void rv515_crtc_bandwidth_compute(struct
 	a.full = rfixed_const(16);
 	wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
 	wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
+	wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max);
 
 	/* Determine estimated width */
 	estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
 	estimated_width.full = rfixed_div(estimated_width, consumption_time);
 	if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) {
-		wm->priority_mark.full = rfixed_const(10);
+		wm->priority_mark.full = wm->priority_mark_max.full;
 	} else {
 		a.full = rfixed_const(16);
 		wm->priority_mark.full = rfixed_div(estimated_width, a);
+		wm->priority_mark.full = rfixed_ceil(wm->priority_mark);
 		wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rv770.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/radeon/rv770.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/radeon/rv770.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,7 +92,7 @@ int rv770_pcie_gart_enable(struct radeon
 void rv770_pcie_gart_disable(struct radeon_device *rdev)
 {
 	u32 tmp;
-	int i;
+	int i, r;
 
 	/* Disable all tables */
 	for (i = 0; i < 7; i++)
@@ -113,8 +113,12 @@ void rv770_pcie_gart_disable(struct rade
 	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
 	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
 	if (rdev->gart.table.vram.robj) {
-		radeon_object_kunmap(rdev->gart.table.vram.robj);
-		radeon_object_unpin(rdev->gart.table.vram.robj);
+		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+		if (likely(r == 0)) {
+			radeon_bo_kunmap(rdev->gart.table.vram.robj);
+			radeon_bo_unpin(rdev->gart.table.vram.robj);
+			radeon_bo_unreserve(rdev->gart.table.vram.robj);
+		}
 	}
 }
 
@@ -545,9 +549,12 @@ static void rv770_gpu_init(struct radeon
 
 	gb_tiling_config |= BANK_SWAPS(1);
 
-	backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
-							rdev->config.rv770.max_backends,
-							(0xff << rdev->config.rv770.max_backends) & 0xff);
+	if (rdev->family == CHIP_RV740)
+		backend_map = 0x28;
+	else
+		backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
+								rdev->config.rv770.max_backends,
+								(0xff << rdev->config.rv770.max_backends) & 0xff);
 	gb_tiling_config |= BACKEND_MAP(backend_map);
 
 	cc_gc_shader_pipe_config =
@@ -775,7 +782,6 @@ int rv770_mc_init(struct radeon_device *
 	fixed20_12 a;
 	u32 tmp;
 	int chansize, numchan;
-	int r;
 
 	/* Get VRAM informations */
 	rdev->mc.vram_is_ddr = true;
@@ -818,9 +824,6 @@ int rv770_mc_init(struct radeon_device *
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
 
 	if (rdev->flags & RADEON_IS_AGP) {
-		r = radeon_agp_init(rdev);
-		if (r)
-			return r;
 		/* gtt_size is setup by radeon_agp_init */
 		rdev->mc.gtt_location = rdev->mc.agp_base;
 		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
@@ -829,11 +832,11 @@ int rv770_mc_init(struct radeon_device *
 		 * AGP so that GPU can catch out of VRAM/AGP access
 		 */
 		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
-			/* Enought place before */
+			/* Enough place before */
 			rdev->mc.vram_location = rdev->mc.gtt_location -
 							rdev->mc.mc_vram_size;
 		} else if (tmp > rdev->mc.mc_vram_size) {
-			/* Enought place after */
+			/* Enough place after */
 			rdev->mc.vram_location = rdev->mc.gtt_location +
 							rdev->mc.gtt_size;
 		} else {
@@ -870,6 +873,14 @@ static int rv770_startup(struct radeon_d
 {
 	int r;
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
 	rv770_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		rv770_agp_enable(rdev);
@@ -879,13 +890,33 @@ static int rv770_startup(struct radeon_d
 			return r;
 	}
 	rv770_gpu_init(rdev);
-
-	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
-			      &rdev->r600_blit.shader_gpu_addr);
+	r = r600_blit_init(rdev);
 	if (r) {
-		DRM_ERROR("failed to pin blit object %d\n", r);
+		r600_blit_fini(rdev);
+		rdev->asic->copy = NULL;
+		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
+	}
+	/* pin copy shader into vram */
+	if (rdev->r600_blit.shader_obj) {
+		r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+		if (unlikely(r != 0))
+			return r;
+		r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+				&rdev->r600_blit.shader_gpu_addr);
+		radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+		if (r) {
+			DRM_ERROR("failed to pin blit object %d\n", r);
+			return r;
+		}
+	}
+	/* Enable IRQ */
+	r = r600_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
 		return r;
 	}
+	r600_irq_set(rdev);
 
 	r = radeon_ring_init(rdev, rdev->cp.ring_size);
 	if (r)
@@ -934,13 +965,22 @@ int rv770_resume(struct radeon_device *r
 
 int rv770_suspend(struct radeon_device *rdev)
 {
+	int r;
+
 	/* FIXME: we should wait for ring to be empty */
 	r700_cp_stop(rdev);
 	rdev->cp.ready = false;
+	r600_irq_suspend(rdev);
 	r600_wb_disable(rdev);
 	rv770_pcie_gart_disable(rdev);
 	/* unpin shaders bo */
-        radeon_object_unpin(rdev->r600_blit.shader_obj);
+	if (rdev->r600_blit.shader_obj) {
+		r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+		if (likely(r == 0)) {
+			radeon_bo_unpin(rdev->r600_blit.shader_obj);
+			radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+		}
+	}
 	return 0;
 }
 
@@ -975,7 +1015,11 @@ int rv770_init(struct radeon_device *rde
 	if (r)
 		return r;
 	/* Post card if necessary */
-	if (!r600_card_posted(rdev) && rdev->bios) {
+	if (!r600_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);
 	}
@@ -994,53 +1038,55 @@ int rv770_init(struct radeon_device *rde
 	r = radeon_fence_driver_init(rdev);
 	if (r)
 		return r;
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r)
+			radeon_agp_disable(rdev);
+	}
 	r = rv770_mc_init(rdev);
 	if (r)
 		return r;
 	/* Memory manager */
-	r = radeon_object_init(rdev);
+	r = radeon_bo_init(rdev);
+	if (r)
+		return r;
+
+	r = radeon_irq_kms_init(rdev);
 	if (r)
 		return r;
+
 	rdev->cp.ring_obj = NULL;
 	r600_ring_init(rdev, 1024 * 1024);
 
-	if (!rdev->me_fw || !rdev->pfp_fw) {
-		r = r600_cp_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
+	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 = r600_blit_init(rdev);
-	if (r) {
-		DRM_ERROR("radeon: failled blitter (%d).\n", r);
-		rdev->accel_working = false;
-	}
-
 	r = rv770_startup(rdev);
 	if (r) {
-		rv770_suspend(rdev);
+		dev_err(rdev->dev, "disabling GPU acceleration\n");
+		r600_cp_fini(rdev);
 		r600_wb_fini(rdev);
-		radeon_ring_fini(rdev);
+		r600_irq_fini(rdev);
+		radeon_irq_kms_fini(rdev);
 		rv770_pcie_gart_fini(rdev);
 		rdev->accel_working = false;
 	}
 	if (rdev->accel_working) {
 		r = radeon_ib_pool_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
-			rdev->accel_working = false;
-		}
-		r = r600_ib_test(rdev);
-		if (r) {
-			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
 			rdev->accel_working = false;
+		} else {
+			r = r600_ib_test(rdev);
+			if (r) {
+				dev_err(rdev->dev, "IB test failed (%d).\n", r);
+				rdev->accel_working = false;
+			}
 		}
 	}
 	return 0;
@@ -1048,18 +1094,17 @@ int rv770_init(struct radeon_device *rde
 
 void rv770_fini(struct radeon_device *rdev)
 {
-	rv770_suspend(rdev);
-
 	r600_blit_fini(rdev);
-	radeon_ring_fini(rdev);
+	r600_cp_fini(rdev);
 	r600_wb_fini(rdev);
+	r600_irq_fini(rdev);
+	radeon_irq_kms_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
 	radeon_gem_fini(rdev);
 	radeon_fence_driver_fini(rdev);
 	radeon_clocks_fini(rdev);
-	if (rdev->flags & RADEON_IS_AGP)
-		radeon_agp_fini(rdev);
-	radeon_object_fini(rdev);
+	radeon_agp_fini(rdev);
+	radeon_bo_fini(rdev);
 	radeon_atombios_fini(rdev);
 	kfree(rdev->bios);
 	rdev->bios = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/savage/savage_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/savage/savage_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/savage/savage_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/savage/savage_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,7 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/sis/sis_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/sis/sis_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/sis/sis_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/sis/sis_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -80,7 +80,7 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/tdfx/tdfx_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/tdfx/tdfx_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/tdfx/tdfx_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/tdfx/tdfx_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,7 @@ static struct drm_driver driver = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
 		 .release = drm_release,
-		 .ioctl = drm_ioctl,
+		 .unlocked_ioctl = drm_ioctl,
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,6 +3,7 @@
 
 ccflags-y := -Iinclude/drm
 ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \
-	ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o
+	ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o \
+	ttm_object.o ttm_lock.o ttm_execbuf_util.o
 
 obj-$(CONFIG_DRM_TTM) += ttm.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,14 @@
 /*
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
+/* Notes:
+ *
+ * We store bo pointer in drm_mm_node struct so we know which bo own a
+ * specific node. There is no protection on the pointer, thus to make
+ * sure things don't go berserk you have to access this pointer while
+ * holding the global lru lock and make sure anytime you free a node you
+ * reset the pointer to NULL.
+ */
 
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
@@ -51,6 +59,59 @@ static struct attribute ttm_bo_count = {
 	.mode = S_IRUGO
 };
 
+static inline int ttm_mem_type_from_flags(uint32_t flags, uint32_t *mem_type)
+{
+	int i;
+
+	for (i = 0; i <= TTM_PL_PRIV5; i++)
+		if (flags & (1 << i)) {
+			*mem_type = i;
+			return 0;
+		}
+	return -EINVAL;
+}
+
+static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
+{
+	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+
+	printk(KERN_ERR TTM_PFX "    has_type: %d\n", man->has_type);
+	printk(KERN_ERR TTM_PFX "    use_type: %d\n", man->use_type);
+	printk(KERN_ERR TTM_PFX "    flags: 0x%08X\n", man->flags);
+	printk(KERN_ERR TTM_PFX "    gpu_offset: 0x%08lX\n", man->gpu_offset);
+	printk(KERN_ERR TTM_PFX "    io_offset: 0x%08lX\n", man->io_offset);
+	printk(KERN_ERR TTM_PFX "    io_size: %ld\n", man->io_size);
+	printk(KERN_ERR TTM_PFX "    size: %llu\n", man->size);
+	printk(KERN_ERR TTM_PFX "    available_caching: 0x%08X\n",
+		man->available_caching);
+	printk(KERN_ERR TTM_PFX "    default_caching: 0x%08X\n",
+		man->default_caching);
+	if (mem_type != TTM_PL_SYSTEM) {
+		spin_lock(&bdev->glob->lru_lock);
+		drm_mm_debug_table(&man->manager, TTM_PFX);
+		spin_unlock(&bdev->glob->lru_lock);
+	}
+}
+
+static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
+					struct ttm_placement *placement)
+{
+	int i, ret, mem_type;
+
+	printk(KERN_ERR TTM_PFX "No space for %p (%lu pages, %luK, %luM)\n",
+		bo, bo->mem.num_pages, bo->mem.size >> 10,
+		bo->mem.size >> 20);
+	for (i = 0; i < placement->num_placement; i++) {
+		ret = ttm_mem_type_from_flags(placement->placement[i],
+						&mem_type);
+		if (ret)
+			return;
+		printk(KERN_ERR TTM_PFX "  placement[%d]=0x%08X (%d)\n",
+			i, placement->placement[i], mem_type);
+		ttm_mem_type_debug(bo->bdev, mem_type);
+	}
+}
+
 static ssize_t ttm_bo_global_show(struct kobject *kobj,
 				  struct attribute *attr,
 				  char *buffer)
@@ -117,12 +178,13 @@ int ttm_bo_wait_unreserved(struct ttm_bu
 		ret = wait_event_interruptible(bo->event_queue,
 					       atomic_read(&bo->reserved) == 0);
 		if (unlikely(ret != 0))
-			return -ERESTART;
+			return ret;
 	} else {
 		wait_event(bo->event_queue, atomic_read(&bo->reserved) == 0);
 	}
 	return 0;
 }
+EXPORT_SYMBOL(ttm_bo_wait_unreserved);
 
 static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
 {
@@ -247,7 +309,6 @@ EXPORT_SYMBOL(ttm_bo_unreserve);
 /*
  * Call bo->mutex locked.
  */
-
 static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
@@ -275,9 +336,10 @@ static int ttm_bo_add_ttm(struct ttm_buf
 		bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
 					page_flags | TTM_PAGE_FLAG_USER,
 					glob->dummy_read_page);
-		if (unlikely(bo->ttm == NULL))
+		if (unlikely(bo->ttm == NULL)) {
 			ret = -ENOMEM;
-		break;
+			break;
+		}
 
 		ret = ttm_tt_set_user(bo->ttm, current,
 				      bo->buffer_start, bo->num_pages);
@@ -328,14 +390,8 @@ static int ttm_bo_handle_move_mem(struct
 		}
 
 		if (bo->mem.mem_type == TTM_PL_SYSTEM) {
-
-			struct ttm_mem_reg *old_mem = &bo->mem;
-			uint32_t save_flags = old_mem->placement;
-
-			*old_mem = *mem;
+			bo->mem = *mem;
 			mem->mm_node = NULL;
-			ttm_flag_masked(&save_flags, mem->placement,
-					TTM_PL_MASK_MEMTYPE);
 			goto moved;
 		}
 
@@ -370,7 +426,8 @@ moved:
 		    bdev->man[bo->mem.mem_type].gpu_offset;
 		bo->cur_placement = bo->mem.placement;
 		spin_unlock(&bo->lock);
-	}
+	} else
+		bo->offset = 0;
 
 	return 0;
 
@@ -408,6 +465,8 @@ static int ttm_bo_cleanup_refs(struct tt
 		spin_unlock(&bo->lock);
 
 		spin_lock(&glob->lru_lock);
+		put_count = ttm_bo_del_from_lru(bo);
+
 		ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
 		BUG_ON(ret);
 		if (bo->ttm)
@@ -415,19 +474,19 @@ static int ttm_bo_cleanup_refs(struct tt
 
 		if (!list_empty(&bo->ddestroy)) {
 			list_del_init(&bo->ddestroy);
-			kref_put(&bo->list_kref, ttm_bo_ref_bug);
+			++put_count;
 		}
 		if (bo->mem.mm_node) {
+			bo->mem.mm_node->private = NULL;
 			drm_mm_put_block(bo->mem.mm_node);
 			bo->mem.mm_node = NULL;
 		}
-		put_count = ttm_bo_del_from_lru(bo);
 		spin_unlock(&glob->lru_lock);
 
 		atomic_set(&bo->reserved, 0);
 
 		while (put_count--)
-			kref_put(&bo->list_kref, ttm_bo_release_list);
+			kref_put(&bo->list_kref, ttm_bo_ref_bug);
 
 		return 0;
 	}
@@ -465,52 +524,44 @@ static int ttm_bo_cleanup_refs(struct tt
 static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
 {
 	struct ttm_bo_global *glob = bdev->glob;
-	struct ttm_buffer_object *entry, *nentry;
-	struct list_head *list, *next;
-	int ret;
+	struct ttm_buffer_object *entry = NULL;
+	int ret = 0;
 
 	spin_lock(&glob->lru_lock);
-	list_for_each_safe(list, next, &bdev->ddestroy) {
-		entry = list_entry(list, struct ttm_buffer_object, ddestroy);
-		nentry = NULL;
+	if (list_empty(&bdev->ddestroy))
+		goto out_unlock;
 
-		/*
-		 * Protect the next list entry from destruction while we
-		 * unlock the lru_lock.
-		 */
+	entry = list_first_entry(&bdev->ddestroy,
+		struct ttm_buffer_object, ddestroy);
+	kref_get(&entry->list_kref);
 
-		if (next != &bdev->ddestroy) {
-			nentry = list_entry(next, struct ttm_buffer_object,
-					    ddestroy);
+	for (;;) {
+		struct ttm_buffer_object *nentry = NULL;
+
+		if (entry->ddestroy.next != &bdev->ddestroy) {
+			nentry = list_first_entry(&entry->ddestroy,
+				struct ttm_buffer_object, ddestroy);
 			kref_get(&nentry->list_kref);
 		}
-		kref_get(&entry->list_kref);
 
 		spin_unlock(&glob->lru_lock);
 		ret = ttm_bo_cleanup_refs(entry, remove_all);
 		kref_put(&entry->list_kref, ttm_bo_release_list);
+		entry = nentry;
 
-		spin_lock(&glob->lru_lock);
-		if (nentry) {
-			bool next_onlist = !list_empty(next);
-			spin_unlock(&glob->lru_lock);
-			kref_put(&nentry->list_kref, ttm_bo_release_list);
-			spin_lock(&glob->lru_lock);
-			/*
-			 * Someone might have raced us and removed the
-			 * next entry from the list. We don't bother restarting
-			 * list traversal.
-			 */
+		if (ret || !entry)
+			goto out;
 
-			if (!next_onlist)
-				break;
-		}
-		if (ret)
+		spin_lock(&glob->lru_lock);
+		if (list_empty(&entry->ddestroy))
 			break;
 	}
-	ret = !list_empty(&bdev->ddestroy);
-	spin_unlock(&glob->lru_lock);
 
+out_unlock:
+	spin_unlock(&glob->lru_lock);
+out:
+	if (entry)
+		kref_put(&entry->list_kref, ttm_bo_release_list);
 	return ret;
 }
 
@@ -554,24 +605,21 @@ void ttm_bo_unref(struct ttm_buffer_obje
 }
 EXPORT_SYMBOL(ttm_bo_unref);
 
-static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
-			bool interruptible, bool no_wait)
+static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible,
+			bool no_wait)
 {
-	int ret = 0;
 	struct ttm_bo_device *bdev = bo->bdev;
 	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_reg evict_mem;
-	uint32_t proposed_placement;
-
-	if (bo->mem.mem_type != mem_type)
-		goto out;
+	struct ttm_placement placement;
+	int ret = 0;
 
 	spin_lock(&bo->lock);
 	ret = ttm_bo_wait(bo, false, interruptible, no_wait);
 	spin_unlock(&bo->lock);
 
 	if (unlikely(ret != 0)) {
-		if (ret != -ERESTART) {
+		if (ret != -ERESTARTSYS) {
 			printk(KERN_ERR TTM_PFX
 			       "Failed to expire sync object before "
 			       "buffer eviction.\n");
@@ -584,116 +632,165 @@ static int ttm_bo_evict(struct ttm_buffe
 	evict_mem = bo->mem;
 	evict_mem.mm_node = NULL;
 
-	proposed_placement = bdev->driver->evict_flags(bo);
-
-	ret = ttm_bo_mem_space(bo, proposed_placement,
-			       &evict_mem, interruptible, no_wait);
-	if (unlikely(ret != 0 && ret != -ERESTART))
-		ret = ttm_bo_mem_space(bo, TTM_PL_FLAG_SYSTEM,
-				       &evict_mem, interruptible, no_wait);
-
+	placement.fpfn = 0;
+	placement.lpfn = 0;
+	placement.num_placement = 0;
+	placement.num_busy_placement = 0;
+	bdev->driver->evict_flags(bo, &placement);
+	ret = ttm_bo_mem_space(bo, &placement, &evict_mem, interruptible,
+				no_wait);
 	if (ret) {
-		if (ret != -ERESTART)
+		if (ret != -ERESTARTSYS) {
 			printk(KERN_ERR TTM_PFX
 			       "Failed to find memory space for "
 			       "buffer 0x%p eviction.\n", bo);
+			ttm_bo_mem_space_debug(bo, &placement);
+		}
 		goto out;
 	}
 
 	ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, interruptible,
 				     no_wait);
 	if (ret) {
-		if (ret != -ERESTART)
+		if (ret != -ERESTARTSYS)
 			printk(KERN_ERR TTM_PFX "Buffer eviction failed\n");
+		spin_lock(&glob->lru_lock);
+		if (evict_mem.mm_node) {
+			evict_mem.mm_node->private = NULL;
+			drm_mm_put_block(evict_mem.mm_node);
+			evict_mem.mm_node = NULL;
+		}
+		spin_unlock(&glob->lru_lock);
 		goto out;
 	}
-
-	spin_lock(&glob->lru_lock);
-	if (evict_mem.mm_node) {
-		drm_mm_put_block(evict_mem.mm_node);
-		evict_mem.mm_node = NULL;
-	}
-	spin_unlock(&glob->lru_lock);
 	bo->evicted = true;
 out:
 	return ret;
 }
 
-/**
- * Repeatedly evict memory from the LRU for @mem_type until we create enough
- * space, or we've evicted everything and there isn't enough space.
- */
-static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
-				  struct ttm_mem_reg *mem,
-				  uint32_t mem_type,
-				  bool interruptible, bool no_wait)
+static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+				uint32_t mem_type,
+				bool interruptible, bool no_wait)
 {
 	struct ttm_bo_global *glob = bdev->glob;
-	struct drm_mm_node *node;
-	struct ttm_buffer_object *entry;
 	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
-	struct list_head *lru;
-	unsigned long num_pages = mem->num_pages;
-	int put_count = 0;
-	int ret;
-
-retry_pre_get:
-	ret = drm_mm_pre_get(&man->manager);
-	if (unlikely(ret != 0))
-		return ret;
+	struct ttm_buffer_object *bo;
+	int ret, put_count = 0;
 
+retry:
 	spin_lock(&glob->lru_lock);
-	do {
-		node = drm_mm_search_free(&man->manager, num_pages,
-					  mem->page_alignment, 1);
-		if (node)
-			break;
+	if (list_empty(&man->lru)) {
+		spin_unlock(&glob->lru_lock);
+		return -EBUSY;
+	}
 
-		lru = &man->lru;
-		if (list_empty(lru))
-			break;
+	bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru);
+	kref_get(&bo->list_kref);
 
-		entry = list_first_entry(lru, struct ttm_buffer_object, lru);
-		kref_get(&entry->list_kref);
+	ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
 
-		ret =
-		    ttm_bo_reserve_locked(entry, interruptible, no_wait,
-					  false, 0);
+	if (unlikely(ret == -EBUSY)) {
+		spin_unlock(&glob->lru_lock);
+		if (likely(!no_wait))
+			ret = ttm_bo_wait_unreserved(bo, interruptible);
 
-		if (likely(ret == 0))
-			put_count = ttm_bo_del_from_lru(entry);
+		kref_put(&bo->list_kref, ttm_bo_release_list);
 
-		spin_unlock(&glob->lru_lock);
+		/**
+		 * We *need* to retry after releasing the lru lock.
+		 */
 
 		if (unlikely(ret != 0))
 			return ret;
+		goto retry;
+	}
 
-		while (put_count--)
-			kref_put(&entry->list_kref, ttm_bo_ref_bug);
+	put_count = ttm_bo_del_from_lru(bo);
+	spin_unlock(&glob->lru_lock);
 
-		ret = ttm_bo_evict(entry, mem_type, interruptible, no_wait);
+	BUG_ON(ret != 0);
 
-		ttm_bo_unreserve(entry);
+	while (put_count--)
+		kref_put(&bo->list_kref, ttm_bo_ref_bug);
 
-		kref_put(&entry->list_kref, ttm_bo_release_list);
-		if (ret)
+	ret = ttm_bo_evict(bo, interruptible, no_wait);
+	ttm_bo_unreserve(bo);
+
+	kref_put(&bo->list_kref, ttm_bo_release_list);
+	return ret;
+}
+
+static int ttm_bo_man_get_node(struct ttm_buffer_object *bo,
+				struct ttm_mem_type_manager *man,
+				struct ttm_placement *placement,
+				struct ttm_mem_reg *mem,
+				struct drm_mm_node **node)
+{
+	struct ttm_bo_global *glob = bo->glob;
+	unsigned long lpfn;
+	int ret;
+
+	lpfn = placement->lpfn;
+	if (!lpfn)
+		lpfn = man->size;
+	*node = NULL;
+	do {
+		ret = drm_mm_pre_get(&man->manager);
+		if (unlikely(ret))
 			return ret;
 
 		spin_lock(&glob->lru_lock);
-	} while (1);
-
-	if (!node) {
+		*node = drm_mm_search_free_in_range(&man->manager,
+					mem->num_pages, mem->page_alignment,
+					placement->fpfn, lpfn, 1);
+		if (unlikely(*node == NULL)) {
+			spin_unlock(&glob->lru_lock);
+			return 0;
+		}
+		*node = drm_mm_get_block_atomic_range(*node, mem->num_pages,
+							mem->page_alignment,
+							placement->fpfn,
+							lpfn);
 		spin_unlock(&glob->lru_lock);
-		return -ENOMEM;
-	}
+	} while (*node == NULL);
+	return 0;
+}
 
-	node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment);
-	if (unlikely(!node)) {
-		spin_unlock(&glob->lru_lock);
-		goto retry_pre_get;
-	}
+/**
+ * Repeatedly evict memory from the LRU for @mem_type until we create enough
+ * space, or we've evicted everything and there isn't enough space.
+ */
+static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
+					uint32_t mem_type,
+					struct ttm_placement *placement,
+					struct ttm_mem_reg *mem,
+					bool interruptible, bool no_wait)
+{
+	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bdev->glob;
+	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+	struct drm_mm_node *node;
+	int ret;
 
-	spin_unlock(&glob->lru_lock);
+	do {
+		ret = ttm_bo_man_get_node(bo, man, placement, mem, &node);
+		if (unlikely(ret != 0))
+			return ret;
+		if (node)
+			break;
+		spin_lock(&glob->lru_lock);
+		if (list_empty(&man->lru)) {
+			spin_unlock(&glob->lru_lock);
+			break;
+		}
+		spin_unlock(&glob->lru_lock);
+		ret = ttm_mem_evict_first(bdev, mem_type, interruptible,
+						no_wait);
+		if (unlikely(ret != 0))
+			return ret;
+	} while (1);
+	if (node == NULL)
+		return -ENOMEM;
 	mem->mm_node = node;
 	mem->mem_type = mem_type;
 	return 0;
@@ -724,7 +821,6 @@ static uint32_t ttm_bo_select_caching(st
 	return result;
 }
 
-
 static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
 				 bool disallow_fixed,
 				 uint32_t mem_type,
@@ -757,66 +853,55 @@ static bool ttm_bo_mt_compatible(struct
  * space.
  */
 int ttm_bo_mem_space(struct ttm_buffer_object *bo,
-		     uint32_t proposed_placement,
-		     struct ttm_mem_reg *mem,
-		     bool interruptible, bool no_wait)
+			struct ttm_placement *placement,
+			struct ttm_mem_reg *mem,
+			bool interruptible, bool no_wait)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
-	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_type_manager *man;
-
-	uint32_t num_prios = bdev->driver->num_mem_type_prio;
-	const uint32_t *prios = bdev->driver->mem_type_prio;
-	uint32_t i;
 	uint32_t mem_type = TTM_PL_SYSTEM;
 	uint32_t cur_flags = 0;
 	bool type_found = false;
 	bool type_ok = false;
-	bool has_eagain = false;
+	bool has_erestartsys = false;
 	struct drm_mm_node *node = NULL;
-	int ret;
+	int i, ret;
 
 	mem->mm_node = NULL;
-	for (i = 0; i < num_prios; ++i) {
-		mem_type = prios[i];
+	for (i = 0; i < placement->num_placement; ++i) {
+		ret = ttm_mem_type_from_flags(placement->placement[i],
+						&mem_type);
+		if (ret)
+			return ret;
 		man = &bdev->man[mem_type];
 
 		type_ok = ttm_bo_mt_compatible(man,
-					       bo->type == ttm_bo_type_user,
-					       mem_type, proposed_placement,
-					       &cur_flags);
+						bo->type == ttm_bo_type_user,
+						mem_type,
+						placement->placement[i],
+						&cur_flags);
 
 		if (!type_ok)
 			continue;
 
 		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
 						  cur_flags);
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the memory placement flags to the current flags
+		 */
+		ttm_flag_masked(&cur_flags, placement->placement[i],
+				~TTM_PL_MASK_MEMTYPE);
 
 		if (mem_type == TTM_PL_SYSTEM)
 			break;
 
 		if (man->has_type && man->use_type) {
 			type_found = true;
-			do {
-				ret = drm_mm_pre_get(&man->manager);
-				if (unlikely(ret))
-					return ret;
-
-				spin_lock(&glob->lru_lock);
-				node = drm_mm_search_free(&man->manager,
-							  mem->num_pages,
-							  mem->page_alignment,
-							  1);
-				if (unlikely(!node)) {
-					spin_unlock(&glob->lru_lock);
-					break;
-				}
-				node = drm_mm_get_block_atomic(node,
-							       mem->num_pages,
-							       mem->
-							       page_alignment);
-				spin_unlock(&glob->lru_lock);
-			} while (!node);
+			ret = ttm_bo_man_get_node(bo, man, placement, mem,
+							&node);
+			if (unlikely(ret))
+				return ret;
 		}
 		if (node)
 			break;
@@ -826,67 +911,74 @@ int ttm_bo_mem_space(struct ttm_buffer_o
 		mem->mm_node = node;
 		mem->mem_type = mem_type;
 		mem->placement = cur_flags;
+		if (node)
+			node->private = bo;
 		return 0;
 	}
 
 	if (!type_found)
 		return -EINVAL;
 
-	num_prios = bdev->driver->num_mem_busy_prio;
-	prios = bdev->driver->mem_busy_prio;
-
-	for (i = 0; i < num_prios; ++i) {
-		mem_type = prios[i];
+	for (i = 0; i < placement->num_busy_placement; ++i) {
+		ret = ttm_mem_type_from_flags(placement->busy_placement[i],
+						&mem_type);
+		if (ret)
+			return ret;
 		man = &bdev->man[mem_type];
-
 		if (!man->has_type)
 			continue;
-
 		if (!ttm_bo_mt_compatible(man,
-					  bo->type == ttm_bo_type_user,
-					  mem_type,
-					  proposed_placement, &cur_flags))
+						bo->type == ttm_bo_type_user,
+						mem_type,
+						placement->busy_placement[i],
+						&cur_flags))
 			continue;
 
 		cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
 						  cur_flags);
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the memory placement flags to the current flags
+		 */
+		ttm_flag_masked(&cur_flags, placement->busy_placement[i],
+				~TTM_PL_MASK_MEMTYPE);
 
-		ret = ttm_bo_mem_force_space(bdev, mem, mem_type,
-					     interruptible, no_wait);
 
-		if (ret == 0 && mem->mm_node) {
+		if (mem_type == TTM_PL_SYSTEM) {
+			mem->mem_type = mem_type;
 			mem->placement = cur_flags;
+			mem->mm_node = NULL;
 			return 0;
 		}
 
-		if (ret == -ERESTART)
-			has_eagain = true;
+		ret = ttm_bo_mem_force_space(bo, mem_type, placement, mem,
+						interruptible, no_wait);
+		if (ret == 0 && mem->mm_node) {
+			mem->placement = cur_flags;
+			mem->mm_node->private = bo;
+			return 0;
+		}
+		if (ret == -ERESTARTSYS)
+			has_erestartsys = true;
 	}
-
-	ret = (has_eagain) ? -ERESTART : -ENOMEM;
+	ret = (has_erestartsys) ? -ERESTARTSYS : -ENOMEM;
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_mem_space);
 
 int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait)
 {
-	int ret = 0;
-
 	if ((atomic_read(&bo->cpu_writers) > 0) && no_wait)
 		return -EBUSY;
 
-	ret = wait_event_interruptible(bo->event_queue,
-				       atomic_read(&bo->cpu_writers) == 0);
-
-	if (ret == -ERESTARTSYS)
-		ret = -ERESTART;
-
-	return ret;
+	return wait_event_interruptible(bo->event_queue,
+					atomic_read(&bo->cpu_writers) == 0);
 }
+EXPORT_SYMBOL(ttm_bo_wait_cpu);
 
 int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
-		       uint32_t proposed_placement,
-		       bool interruptible, bool no_wait)
+			struct ttm_placement *placement,
+			bool interruptible, bool no_wait)
 {
 	struct ttm_bo_global *glob = bo->glob;
 	int ret = 0;
@@ -899,147 +991,138 @@ int ttm_bo_move_buffer(struct ttm_buffer
 	 * Have the driver move function wait for idle when necessary,
 	 * instead of doing it here.
 	 */
-
 	spin_lock(&bo->lock);
 	ret = ttm_bo_wait(bo, false, interruptible, no_wait);
 	spin_unlock(&bo->lock);
-
 	if (ret)
 		return ret;
-
 	mem.num_pages = bo->num_pages;
 	mem.size = mem.num_pages << PAGE_SHIFT;
 	mem.page_alignment = bo->mem.page_alignment;
-
 	/*
 	 * Determine where to move the buffer.
 	 */
-
-	ret = ttm_bo_mem_space(bo, proposed_placement, &mem,
-			       interruptible, no_wait);
+	ret = ttm_bo_mem_space(bo, placement, &mem, interruptible, no_wait);
 	if (ret)
 		goto out_unlock;
-
 	ret = ttm_bo_handle_move_mem(bo, &mem, false, interruptible, no_wait);
-
 out_unlock:
 	if (ret && mem.mm_node) {
 		spin_lock(&glob->lru_lock);
+		mem.mm_node->private = NULL;
 		drm_mm_put_block(mem.mm_node);
 		spin_unlock(&glob->lru_lock);
 	}
 	return ret;
 }
 
-static int ttm_bo_mem_compat(uint32_t proposed_placement,
+static int ttm_bo_mem_compat(struct ttm_placement *placement,
 			     struct ttm_mem_reg *mem)
 {
-	if ((proposed_placement & mem->placement & TTM_PL_MASK_MEM) == 0)
-		return 0;
-	if ((proposed_placement & mem->placement & TTM_PL_MASK_CACHING) == 0)
-		return 0;
+	int i;
+	struct drm_mm_node *node = mem->mm_node;
 
-	return 1;
+	if (node && placement->lpfn != 0 &&
+	    (node->start < placement->fpfn ||
+	     node->start + node->size > placement->lpfn))
+		return -1;
+
+	for (i = 0; i < placement->num_placement; i++) {
+		if ((placement->placement[i] & mem->placement &
+			TTM_PL_MASK_CACHING) &&
+			(placement->placement[i] & mem->placement &
+			TTM_PL_MASK_MEM))
+			return i;
+	}
+	return -1;
 }
 
-int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
-			       uint32_t proposed_placement,
-			       bool interruptible, bool no_wait)
+int ttm_bo_validate(struct ttm_buffer_object *bo,
+			struct ttm_placement *placement,
+			bool interruptible, bool no_wait)
 {
 	int ret;
 
 	BUG_ON(!atomic_read(&bo->reserved));
-	bo->proposed_placement = proposed_placement;
-
-	TTM_DEBUG("Proposed placement 0x%08lx, Old flags 0x%08lx\n",
-		  (unsigned long)proposed_placement,
-		  (unsigned long)bo->mem.placement);
-
+	/* Check that range is valid */
+	if (placement->lpfn || placement->fpfn)
+		if (placement->fpfn > placement->lpfn ||
+			(placement->lpfn - placement->fpfn) < bo->num_pages)
+			return -EINVAL;
 	/*
 	 * Check whether we need to move buffer.
 	 */
-
-	if (!ttm_bo_mem_compat(bo->proposed_placement, &bo->mem)) {
-		ret = ttm_bo_move_buffer(bo, bo->proposed_placement,
-					 interruptible, no_wait);
-		if (ret) {
-			if (ret != -ERESTART)
-				printk(KERN_ERR TTM_PFX
-				       "Failed moving buffer. "
-				       "Proposed placement 0x%08x\n",
-				       bo->proposed_placement);
-			if (ret == -ENOMEM)
-				printk(KERN_ERR TTM_PFX
-				       "Out of aperture space or "
-				       "DRM memory quota.\n");
+	ret = ttm_bo_mem_compat(placement, &bo->mem);
+	if (ret < 0) {
+		ret = ttm_bo_move_buffer(bo, placement, interruptible, no_wait);
+		if (ret)
 			return ret;
-		}
+	} else {
+		/*
+		 * Use the access and other non-mapping-related flag bits from
+		 * the compatible memory placement flags to the active flags
+		 */
+		ttm_flag_masked(&bo->mem.placement, placement->placement[ret],
+				~TTM_PL_MASK_MEMTYPE);
 	}
-
 	/*
 	 * We might need to add a TTM.
 	 */
-
 	if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
 		ret = ttm_bo_add_ttm(bo, true);
 		if (ret)
 			return ret;
 	}
-	/*
-	 * Validation has succeeded, move the access and other
-	 * non-mapping-related flag bits from the proposed flags to
-	 * the active flags
-	 */
-
-	ttm_flag_masked(&bo->mem.placement, bo->proposed_placement,
-			~TTM_PL_MASK_MEMTYPE);
-
 	return 0;
 }
-EXPORT_SYMBOL(ttm_buffer_object_validate);
+EXPORT_SYMBOL(ttm_bo_validate);
 
-int
-ttm_bo_check_placement(struct ttm_buffer_object *bo,
-		       uint32_t set_flags, uint32_t clr_flags)
+int ttm_bo_check_placement(struct ttm_buffer_object *bo,
+				struct ttm_placement *placement)
 {
-	uint32_t new_mask = set_flags | clr_flags;
-
-	if ((bo->type == ttm_bo_type_user) &&
-	    (clr_flags & TTM_PL_FLAG_CACHED)) {
-		printk(KERN_ERR TTM_PFX
-		       "User buffers require cache-coherent memory.\n");
-		return -EINVAL;
-	}
+	int i;
 
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (new_mask & TTM_PL_FLAG_NO_EVICT) {
-			printk(KERN_ERR TTM_PFX "Need to be root to modify"
-			       " NO_EVICT status.\n");
+	if (placement->fpfn || placement->lpfn) {
+		if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) {
+			printk(KERN_ERR TTM_PFX "Page number range to small "
+				"Need %lu pages, range is [%u, %u]\n",
+				bo->mem.num_pages, placement->fpfn,
+				placement->lpfn);
 			return -EINVAL;
 		}
-
-		if ((clr_flags & bo->mem.placement & TTM_PL_MASK_MEMTYPE) &&
-		    (bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
-			printk(KERN_ERR TTM_PFX
-			       "Incompatible memory specification"
-			       " for NO_EVICT buffer.\n");
-			return -EINVAL;
+	}
+	for (i = 0; i < placement->num_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
+		}
+	}
+	for (i = 0; i < placement->num_busy_placement; i++) {
+		if (!capable(CAP_SYS_ADMIN)) {
+			if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
+				printk(KERN_ERR TTM_PFX "Need to be root to "
+					"modify NO_EVICT status.\n");
+				return -EINVAL;
+			}
 		}
 	}
 	return 0;
 }
 
-int ttm_buffer_object_init(struct ttm_bo_device *bdev,
-			   struct ttm_buffer_object *bo,
-			   unsigned long size,
-			   enum ttm_bo_type type,
-			   uint32_t flags,
-			   uint32_t page_alignment,
-			   unsigned long buffer_start,
-			   bool interruptible,
-			   struct file *persistant_swap_storage,
-			   size_t acc_size,
-			   void (*destroy) (struct ttm_buffer_object *))
+int ttm_bo_init(struct ttm_bo_device *bdev,
+		struct ttm_buffer_object *bo,
+		unsigned long size,
+		enum ttm_bo_type type,
+		struct ttm_placement *placement,
+		uint32_t page_alignment,
+		unsigned long buffer_start,
+		bool interruptible,
+		struct file *persistant_swap_storage,
+		size_t acc_size,
+		void (*destroy) (struct ttm_buffer_object *))
 {
 	int ret = 0;
 	unsigned long num_pages;
@@ -1065,6 +1148,7 @@ int ttm_buffer_object_init(struct ttm_bo
 	bo->glob = bdev->glob;
 	bo->type = type;
 	bo->num_pages = num_pages;
+	bo->mem.size = num_pages << PAGE_SHIFT;
 	bo->mem.mem_type = TTM_PL_SYSTEM;
 	bo->mem.num_pages = bo->num_pages;
 	bo->mem.mm_node = NULL;
@@ -1077,29 +1161,21 @@ int ttm_buffer_object_init(struct ttm_bo
 	bo->acc_size = acc_size;
 	atomic_inc(&bo->glob->bo_count);
 
-	ret = ttm_bo_check_placement(bo, flags, 0ULL);
+	ret = ttm_bo_check_placement(bo, placement);
 	if (unlikely(ret != 0))
 		goto out_err;
 
 	/*
-	 * If no caching attributes are set, accept any form of caching.
-	 */
-
-	if ((flags & TTM_PL_MASK_CACHING) == 0)
-		flags |= TTM_PL_MASK_CACHING;
-
-	/*
 	 * For ttm_bo_type_device buffers, allocate
 	 * address space from the device.
 	 */
-
 	if (bo->type == ttm_bo_type_device) {
 		ret = ttm_bo_setup_vm(bo);
 		if (ret)
 			goto out_err;
 	}
 
-	ret = ttm_buffer_object_validate(bo, flags, interruptible, false);
+	ret = ttm_bo_validate(bo, placement, interruptible, false);
 	if (ret)
 		goto out_err;
 
@@ -1112,7 +1188,7 @@ out_err:
 
 	return ret;
 }
-EXPORT_SYMBOL(ttm_buffer_object_init);
+EXPORT_SYMBOL(ttm_bo_init);
 
 static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
 				 unsigned long num_pages)
@@ -1123,19 +1199,19 @@ static inline size_t ttm_bo_size(struct
 	return glob->ttm_bo_size + 2 * page_array_size;
 }
 
-int ttm_buffer_object_create(struct ttm_bo_device *bdev,
-			     unsigned long size,
-			     enum ttm_bo_type type,
-			     uint32_t flags,
-			     uint32_t page_alignment,
-			     unsigned long buffer_start,
-			     bool interruptible,
-			     struct file *persistant_swap_storage,
-			     struct ttm_buffer_object **p_bo)
+int ttm_bo_create(struct ttm_bo_device *bdev,
+			unsigned long size,
+			enum ttm_bo_type type,
+			struct ttm_placement *placement,
+			uint32_t page_alignment,
+			unsigned long buffer_start,
+			bool interruptible,
+			struct file *persistant_swap_storage,
+			struct ttm_buffer_object **p_bo)
 {
 	struct ttm_buffer_object *bo;
-	int ret;
 	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	int ret;
 
 	size_t acc_size =
 	    ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
@@ -1150,76 +1226,41 @@ int ttm_buffer_object_create(struct ttm_
 		return -ENOMEM;
 	}
 
-	ret = ttm_buffer_object_init(bdev, bo, size, type, flags,
-				     page_alignment, buffer_start,
-				     interruptible,
-				     persistant_swap_storage, acc_size, NULL);
+	ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
+				buffer_start, interruptible,
+				persistant_swap_storage, acc_size, NULL);
 	if (likely(ret == 0))
 		*p_bo = bo;
 
 	return ret;
 }
 
-static int ttm_bo_leave_list(struct ttm_buffer_object *bo,
-			     uint32_t mem_type, bool allow_errors)
-{
-	int ret;
-
-	spin_lock(&bo->lock);
-	ret = ttm_bo_wait(bo, false, false, false);
-	spin_unlock(&bo->lock);
-
-	if (ret && allow_errors)
-		goto out;
-
-	if (bo->mem.mem_type == mem_type)
-		ret = ttm_bo_evict(bo, mem_type, false, false);
-
-	if (ret) {
-		if (allow_errors) {
-			goto out;
-		} else {
-			ret = 0;
-			printk(KERN_ERR TTM_PFX "Cleanup eviction failed\n");
-		}
-	}
-
-out:
-	return ret;
-}
-
 static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
-				   struct list_head *head,
-				   unsigned mem_type, bool allow_errors)
+					unsigned mem_type, bool allow_errors)
 {
+	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
 	struct ttm_bo_global *glob = bdev->glob;
-	struct ttm_buffer_object *entry;
 	int ret;
-	int put_count;
 
 	/*
 	 * Can't use standard list traversal since we're unlocking.
 	 */
 
 	spin_lock(&glob->lru_lock);
-
-	while (!list_empty(head)) {
-		entry = list_first_entry(head, struct ttm_buffer_object, lru);
-		kref_get(&entry->list_kref);
-		ret = ttm_bo_reserve_locked(entry, false, false, false, 0);
-		put_count = ttm_bo_del_from_lru(entry);
+	while (!list_empty(&man->lru)) {
 		spin_unlock(&glob->lru_lock);
-		while (put_count--)
-			kref_put(&entry->list_kref, ttm_bo_ref_bug);
-		BUG_ON(ret);
-		ret = ttm_bo_leave_list(entry, mem_type, allow_errors);
-		ttm_bo_unreserve(entry);
-		kref_put(&entry->list_kref, ttm_bo_release_list);
+		ret = ttm_mem_evict_first(bdev, mem_type, false, false);
+		if (ret) {
+			if (allow_errors) {
+				return ret;
+			} else {
+				printk(KERN_ERR TTM_PFX
+					"Cleanup eviction failed\n");
+			}
+		}
 		spin_lock(&glob->lru_lock);
 	}
-
 	spin_unlock(&glob->lru_lock);
-
 	return 0;
 }
 
@@ -1246,7 +1287,7 @@ int ttm_bo_clean_mm(struct ttm_bo_device
 
 	ret = 0;
 	if (mem_type > 0) {
-		ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false);
+		ttm_bo_force_list_clean(bdev, mem_type, false);
 
 		spin_lock(&glob->lru_lock);
 		if (drm_mm_clean(&man->manager))
@@ -1279,12 +1320,12 @@ int ttm_bo_evict_mm(struct ttm_bo_device
 		return 0;
 	}
 
-	return ttm_bo_force_list_clean(bdev, &man->lru, mem_type, true);
+	return ttm_bo_force_list_clean(bdev, mem_type, true);
 }
 EXPORT_SYMBOL(ttm_bo_evict_mm);
 
 int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
-		   unsigned long p_offset, unsigned long p_size)
+			unsigned long p_size)
 {
 	int ret = -EINVAL;
 	struct ttm_mem_type_manager *man;
@@ -1314,7 +1355,7 @@ int ttm_bo_init_mm(struct ttm_bo_device
 			       type);
 			return ret;
 		}
-		ret = drm_mm_init(&man->manager, p_offset, p_size);
+		ret = drm_mm_init(&man->manager, 0, p_size);
 		if (ret)
 			return ret;
 	}
@@ -1463,7 +1504,7 @@ int ttm_bo_device_init(struct ttm_bo_dev
 	 * Initialize the system memory buffer type.
 	 * Other types need to be driver / IOCTL initialized.
 	 */
-	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0);
+	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0);
 	if (unlikely(ret != 0))
 		goto out_no_sys;
 
@@ -1693,7 +1734,7 @@ int ttm_bo_block_reservation(struct ttm_
 			ret = wait_event_interruptible
 			    (bo->event_queue, atomic_read(&bo->reserved) == 0);
 			if (unlikely(ret != 0))
-				return -ERESTART;
+				return ret;
 		} else {
 			wait_event(bo->event_queue,
 				   atomic_read(&bo->reserved) == 0);
@@ -1722,12 +1763,14 @@ int ttm_bo_synccpu_write_grab(struct ttm
 	ttm_bo_unreserve(bo);
 	return ret;
 }
+EXPORT_SYMBOL(ttm_bo_synccpu_write_grab);
 
 void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
 {
 	if (atomic_dec_and_test(&bo->cpu_writers))
 		wake_up_all(&bo->event_queue);
 }
+EXPORT_SYMBOL(ttm_bo_synccpu_write_release);
 
 /**
  * A buffer object shrink method that tries to swap out the first
@@ -1808,6 +1851,9 @@ static int ttm_bo_swapout(struct ttm_mem
 	 * anyone tries to access a ttm page.
 	 */
 
+	if (bo->bdev->driver->swap_notify)
+		bo->bdev->driver->swap_notify(bo);
+
 	ret = ttm_tt_swapout(bo->ttm, bo->persistant_swap_storage);
 out:
 
@@ -1828,3 +1874,4 @@ void ttm_bo_swapout_all(struct ttm_bo_de
 	while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
 		;
 }
+EXPORT_SYMBOL(ttm_bo_swapout_all);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_util.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,6 @@ int ttm_bo_move_ttm(struct ttm_buffer_ob
 {
 	struct ttm_tt *ttm = bo->ttm;
 	struct ttm_mem_reg *old_mem = &bo->mem;
-	uint32_t save_flags = old_mem->placement;
 	int ret;
 
 	if (old_mem->mem_type != TTM_PL_SYSTEM) {
@@ -62,7 +61,6 @@ int ttm_bo_move_ttm(struct ttm_buffer_ob
 		ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
 				TTM_PL_MASK_MEM);
 		old_mem->mem_type = TTM_PL_SYSTEM;
-		save_flags = old_mem->placement;
 	}
 
 	ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
@@ -77,7 +75,7 @@ int ttm_bo_move_ttm(struct ttm_buffer_ob
 
 	*old_mem = *new_mem;
 	new_mem->mm_node = NULL;
-	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
+
 	return 0;
 }
 EXPORT_SYMBOL(ttm_bo_move_ttm);
@@ -219,7 +217,6 @@ int ttm_bo_move_memcpy(struct ttm_buffer
 	void *old_iomap;
 	void *new_iomap;
 	int ret;
-	uint32_t save_flags = old_mem->placement;
 	unsigned long i;
 	unsigned long page;
 	unsigned long add = 0;
@@ -270,7 +267,6 @@ out2:
 
 	*old_mem = *new_mem;
 	new_mem->mm_node = NULL;
-	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
 
 	if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
 		ttm_tt_unbind(ttm);
@@ -369,6 +365,7 @@ pgprot_t ttm_io_prot(uint32_t caching_fl
 #endif
 	return tmp;
 }
+EXPORT_SYMBOL(ttm_io_prot);
 
 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
 			  unsigned long bus_base,
@@ -427,7 +424,7 @@ static int ttm_bo_kmap_ttm(struct ttm_bu
 
 		/*
 		 * We need to use vmap to get the desired page protection
-		 * or to make the buffer object look contigous.
+		 * or to make the buffer object look contiguous.
 		 */
 		prot = (mem->placement & TTM_PL_FLAG_CACHED) ?
 			PAGE_KERNEL :
@@ -536,7 +533,6 @@ int ttm_bo_move_accel_cleanup(struct ttm
 	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	int ret;
-	uint32_t save_flags = old_mem->placement;
 	struct ttm_buffer_object *ghost_obj;
 	void *tmp_obj = NULL;
 
@@ -597,7 +593,7 @@ int ttm_bo_move_accel_cleanup(struct ttm
 
 	*old_mem = *new_mem;
 	new_mem->mm_node = NULL;
-	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
+
 	return 0;
 }
 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo_vm.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_vm.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_bo_vm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_bo_vm.c	2010-02-24 13:52:17.000000000 -0500
@@ -114,7 +114,7 @@ static int ttm_bo_vm_fault(struct vm_are
 		ret = ttm_bo_wait(bo, false, true, false);
 		spin_unlock(&bo->lock);
 		if (unlikely(ret != 0)) {
-			retval = (ret != -ERESTART) ?
+			retval = (ret != -ERESTARTSYS) ?
 			    VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
 			goto out_unlock;
 		}
@@ -320,7 +320,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *
 		return -EFAULT;
 
 	driver = bo->bdev->driver;
-	if (unlikely(driver->verify_access)) {
+	if (unlikely(!driver->verify_access)) {
 		ret = -EPERM;
 		goto out_unref;
 	}
@@ -349,9 +349,6 @@ ssize_t ttm_bo_io(struct ttm_bo_device *
 	switch (ret) {
 	case 0:
 		break;
-	case -ERESTART:
-		ret = -EINTR;
-		goto out_unref;
 	case -EBUSY:
 		ret = -EAGAIN;
 		goto out_unref;
@@ -421,8 +418,6 @@ ssize_t ttm_bo_fbdev_io(struct ttm_buffe
 	switch (ret) {
 	case 0:
 		break;
-	case -ERESTART:
-		return -EINTR;
 	case -EBUSY:
 		return -EAGAIN;
 	default:
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_execbuf_util.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_execbuf_util.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_execbuf_util.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_execbuf_util.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,117 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#include "ttm/ttm_execbuf_util.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+void ttm_eu_backoff_reservation(struct list_head *list)
+{
+	struct ttm_validate_buffer *entry;
+
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+		if (!entry->reserved)
+			continue;
+
+		entry->reserved = false;
+		ttm_bo_unreserve(bo);
+	}
+}
+EXPORT_SYMBOL(ttm_eu_backoff_reservation);
+
+/*
+ * Reserve buffers for validation.
+ *
+ * If a buffer in the list is marked for CPU access, we back off and
+ * wait for that buffer to become free for GPU access.
+ *
+ * If a buffer is reserved for another validation, the validator with
+ * the highest validation sequence backs off and waits for that buffer
+ * to become unreserved. This prevents deadlocks when validating multiple
+ * buffers in different orders.
+ */
+
+int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq)
+{
+	struct ttm_validate_buffer *entry;
+	int ret;
+
+retry:
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+
+		entry->reserved = false;
+		ret = ttm_bo_reserve(bo, true, false, true, val_seq);
+		if (ret != 0) {
+			ttm_eu_backoff_reservation(list);
+			if (ret == -EAGAIN) {
+				ret = ttm_bo_wait_unreserved(bo, true);
+				if (unlikely(ret != 0))
+					return ret;
+				goto retry;
+			} else
+				return ret;
+		}
+
+		entry->reserved = true;
+		if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
+			ttm_eu_backoff_reservation(list);
+			ret = ttm_bo_wait_cpu(bo, false);
+			if (ret)
+				return ret;
+			goto retry;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(ttm_eu_reserve_buffers);
+
+void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
+{
+	struct ttm_validate_buffer *entry;
+
+	list_for_each_entry(entry, list, head) {
+		struct ttm_buffer_object *bo = entry->bo;
+		struct ttm_bo_driver *driver = bo->bdev->driver;
+		void *old_sync_obj;
+
+		spin_lock(&bo->lock);
+		old_sync_obj = bo->sync_obj;
+		bo->sync_obj = driver->sync_obj_ref(sync_obj);
+		bo->sync_obj_arg = entry->new_sync_obj_arg;
+		spin_unlock(&bo->lock);
+		ttm_bo_unreserve(bo);
+		entry->reserved = false;
+		if (old_sync_obj)
+			driver->sync_obj_unref(&old_sync_obj);
+	}
+}
+EXPORT_SYMBOL(ttm_eu_fence_buffer_objects);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_lock.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_lock.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_lock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_lock.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,313 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2007-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 "ttm/ttm_lock.h"
+#include "ttm/ttm_module.h"
+#include <asm/atomic.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+#define TTM_WRITE_LOCK_PENDING    (1 << 0)
+#define TTM_VT_LOCK_PENDING       (1 << 1)
+#define TTM_SUSPEND_LOCK_PENDING  (1 << 2)
+#define TTM_VT_LOCK               (1 << 3)
+#define TTM_SUSPEND_LOCK          (1 << 4)
+
+void ttm_lock_init(struct ttm_lock *lock)
+{
+	spin_lock_init(&lock->lock);
+	init_waitqueue_head(&lock->queue);
+	lock->rw = 0;
+	lock->flags = 0;
+	lock->kill_takers = false;
+	lock->signal = SIGKILL;
+}
+EXPORT_SYMBOL(ttm_lock_init);
+
+void ttm_read_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	if (--lock->rw == 0)
+		wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+EXPORT_SYMBOL(ttm_read_unlock);
+
+static bool __ttm_read_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw >= 0 && lock->flags == 0) {
+		++lock->rw;
+		locked = true;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+
+	if (interruptible)
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_read_lock(lock));
+	else
+		wait_event(lock->queue, __ttm_read_lock(lock));
+	return ret;
+}
+EXPORT_SYMBOL(ttm_read_lock);
+
+static bool __ttm_read_trylock(struct ttm_lock *lock, bool *locked)
+{
+	bool block = true;
+
+	*locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw >= 0 && lock->flags == 0) {
+		++lock->rw;
+		block = false;
+		*locked = true;
+	} else if (lock->flags == 0) {
+		block = false;
+	}
+	spin_unlock(&lock->lock);
+
+	return !block;
+}
+
+int ttm_read_trylock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+	bool locked;
+
+	if (interruptible)
+		ret = wait_event_interruptible
+			(lock->queue, __ttm_read_trylock(lock, &locked));
+	else
+		wait_event(lock->queue, __ttm_read_trylock(lock, &locked));
+
+	if (unlikely(ret != 0)) {
+		BUG_ON(locked);
+		return ret;
+	}
+
+	return (locked) ? 0 : -EBUSY;
+}
+
+void ttm_write_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->rw = 0;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+EXPORT_SYMBOL(ttm_write_unlock);
+
+static bool __ttm_write_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (unlikely(lock->kill_takers)) {
+		send_sig(lock->signal, current, 0);
+		spin_unlock(&lock->lock);
+		return false;
+	}
+	if (lock->rw == 0 && ((lock->flags & ~TTM_WRITE_LOCK_PENDING) == 0)) {
+		lock->rw = -1;
+		lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+		locked = true;
+	} else {
+		lock->flags |= TTM_WRITE_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
+{
+	int ret = 0;
+
+	if (interruptible) {
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_write_lock(lock));
+		if (unlikely(ret != 0)) {
+			spin_lock(&lock->lock);
+			lock->flags &= ~TTM_WRITE_LOCK_PENDING;
+			wake_up_all(&lock->queue);
+			spin_unlock(&lock->lock);
+		}
+	} else
+		wait_event(lock->queue, __ttm_read_lock(lock));
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_write_lock);
+
+void ttm_write_lock_downgrade(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->rw = 1;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+
+static int __ttm_vt_unlock(struct ttm_lock *lock)
+{
+	int ret = 0;
+
+	spin_lock(&lock->lock);
+	if (unlikely(!(lock->flags & TTM_VT_LOCK)))
+		ret = -EINVAL;
+	lock->flags &= ~TTM_VT_LOCK;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+	printk(KERN_INFO TTM_PFX "vt unlock.\n");
+
+	return ret;
+}
+
+static void ttm_vt_lock_remove(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct ttm_lock *lock = container_of(base, struct ttm_lock, base);
+	int ret;
+
+	*p_base = NULL;
+	ret = __ttm_vt_unlock(lock);
+	BUG_ON(ret != 0);
+}
+
+static bool __ttm_vt_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (lock->rw == 0) {
+		lock->flags &= ~TTM_VT_LOCK_PENDING;
+		lock->flags |= TTM_VT_LOCK;
+		locked = true;
+	} else {
+		lock->flags |= TTM_VT_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+int ttm_vt_lock(struct ttm_lock *lock,
+		bool interruptible,
+		struct ttm_object_file *tfile)
+{
+	int ret = 0;
+
+	if (interruptible) {
+		ret = wait_event_interruptible(lock->queue,
+					       __ttm_vt_lock(lock));
+		if (unlikely(ret != 0)) {
+			spin_lock(&lock->lock);
+			lock->flags &= ~TTM_VT_LOCK_PENDING;
+			wake_up_all(&lock->queue);
+			spin_unlock(&lock->lock);
+			return ret;
+		}
+	} else
+		wait_event(lock->queue, __ttm_vt_lock(lock));
+
+	/*
+	 * Add a base-object, the destructor of which will
+	 * make sure the lock is released if the client dies
+	 * while holding it.
+	 */
+
+	ret = ttm_base_object_init(tfile, &lock->base, false,
+				   ttm_lock_type, &ttm_vt_lock_remove, NULL);
+	if (ret)
+		(void)__ttm_vt_unlock(lock);
+	else {
+		lock->vt_holder = tfile;
+		printk(KERN_INFO TTM_PFX "vt lock.\n");
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_vt_lock);
+
+int ttm_vt_unlock(struct ttm_lock *lock)
+{
+	return ttm_ref_object_base_unref(lock->vt_holder,
+					 lock->base.hash.key, TTM_REF_USAGE);
+}
+EXPORT_SYMBOL(ttm_vt_unlock);
+
+void ttm_suspend_unlock(struct ttm_lock *lock)
+{
+	spin_lock(&lock->lock);
+	lock->flags &= ~TTM_SUSPEND_LOCK;
+	wake_up_all(&lock->queue);
+	spin_unlock(&lock->lock);
+}
+EXPORT_SYMBOL(ttm_suspend_unlock);
+
+static bool __ttm_suspend_lock(struct ttm_lock *lock)
+{
+	bool locked = false;
+
+	spin_lock(&lock->lock);
+	if (lock->rw == 0) {
+		lock->flags &= ~TTM_SUSPEND_LOCK_PENDING;
+		lock->flags |= TTM_SUSPEND_LOCK;
+		locked = true;
+	} else {
+		lock->flags |= TTM_SUSPEND_LOCK_PENDING;
+	}
+	spin_unlock(&lock->lock);
+	return locked;
+}
+
+void ttm_suspend_lock(struct ttm_lock *lock)
+{
+	wait_event(lock->queue, __ttm_suspend_lock(lock));
+}
+EXPORT_SYMBOL(ttm_suspend_lock);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_memory.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_memory.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_memory.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -274,16 +274,17 @@ static int ttm_mem_init_kernel_zone(stru
 static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
 				     const struct sysinfo *si)
 {
-	struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	struct ttm_mem_zone *zone;
 	uint64_t mem;
 	int ret;
 
-	if (unlikely(!zone))
-		return -ENOMEM;
-
 	if (si->totalhigh == 0)
 		return 0;
 
+	zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	if (unlikely(!zone))
+		return -ENOMEM;
+
 	mem = si->totalram;
 	mem *= si->mem_unit;
 
@@ -322,8 +323,10 @@ static int ttm_mem_init_dma32_zone(struc
 	 * No special dma32 zone needed.
 	 */
 
-	if (mem <= ((uint64_t) 1ULL << 32))
+	if (mem <= ((uint64_t) 1ULL << 32)) {
+		kfree(zone);
 		return 0;
+	}
 
 	/*
 	 * Limit max dma32 memory to 4GB for now
@@ -460,6 +463,7 @@ void ttm_mem_global_free(struct ttm_mem_
 {
 	return ttm_mem_global_free_zone(glob, NULL, amount);
 }
+EXPORT_SYMBOL(ttm_mem_global_free);
 
 static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 				  struct ttm_mem_zone *single_zone,
@@ -533,6 +537,7 @@ int ttm_mem_global_alloc(struct ttm_mem_
 	return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
 					 interruptible);
 }
+EXPORT_SYMBOL(ttm_mem_global_alloc);
 
 int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
 			      struct page *page,
@@ -588,3 +593,4 @@ size_t ttm_round_pot(size_t size)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(ttm_round_pot);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_object.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_object.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_object.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_object.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,452 @@
+/**************************************************************************
+ *
+ * Copyright (c) 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>
+ */
+/** @file ttm_ref_object.c
+ *
+ * Base- and reference object implementation for the various
+ * ttm objects. Implements reference counting, minimal security checks
+ * and release on file close.
+ */
+
+/**
+ * struct ttm_object_file
+ *
+ * @tdev: Pointer to the ttm_object_device.
+ *
+ * @lock: Lock that protects the ref_list list and the
+ * ref_hash hash tables.
+ *
+ * @ref_list: List of ttm_ref_objects to be destroyed at
+ * file release.
+ *
+ * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
+ * for fast lookup of ref objects given a base object.
+ */
+
+#include "ttm/ttm_object.h"
+#include "ttm/ttm_module.h"
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/atomic.h>
+
+struct ttm_object_file {
+	struct ttm_object_device *tdev;
+	rwlock_t lock;
+	struct list_head ref_list;
+	struct drm_open_hash ref_hash[TTM_REF_NUM];
+	struct kref refcount;
+};
+
+/**
+ * struct ttm_object_device
+ *
+ * @object_lock: lock that protects the object_hash hash table.
+ *
+ * @object_hash: hash table for fast lookup of object global names.
+ *
+ * @object_count: Per device object count.
+ *
+ * This is the per-device data structure needed for ttm object management.
+ */
+
+struct ttm_object_device {
+	rwlock_t object_lock;
+	struct drm_open_hash object_hash;
+	atomic_t object_count;
+	struct ttm_mem_global *mem_glob;
+};
+
+/**
+ * struct ttm_ref_object
+ *
+ * @hash: Hash entry for the per-file object reference hash.
+ *
+ * @head: List entry for the per-file list of ref-objects.
+ *
+ * @kref: Ref count.
+ *
+ * @obj: Base object this ref object is referencing.
+ *
+ * @ref_type: Type of ref object.
+ *
+ * This is similar to an idr object, but it also has a hash table entry
+ * that allows lookup with a pointer to the referenced object as a key. In
+ * that way, one can easily detect whether a base object is referenced by
+ * a particular ttm_object_file. It also carries a ref count to avoid creating
+ * multiple ref objects if a ttm_object_file references the same base
+ * object more than once.
+ */
+
+struct ttm_ref_object {
+	struct drm_hash_item hash;
+	struct list_head head;
+	struct kref kref;
+	enum ttm_ref_type ref_type;
+	struct ttm_base_object *obj;
+	struct ttm_object_file *tfile;
+};
+
+static inline struct ttm_object_file *
+ttm_object_file_ref(struct ttm_object_file *tfile)
+{
+	kref_get(&tfile->refcount);
+	return tfile;
+}
+
+static void ttm_object_file_destroy(struct kref *kref)
+{
+	struct ttm_object_file *tfile =
+		container_of(kref, struct ttm_object_file, refcount);
+
+	kfree(tfile);
+}
+
+
+static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
+{
+	struct ttm_object_file *tfile = *p_tfile;
+
+	*p_tfile = NULL;
+	kref_put(&tfile->refcount, ttm_object_file_destroy);
+}
+
+
+int ttm_base_object_init(struct ttm_object_file *tfile,
+			 struct ttm_base_object *base,
+			 bool shareable,
+			 enum ttm_object_type object_type,
+			 void (*refcount_release) (struct ttm_base_object **),
+			 void (*ref_obj_release) (struct ttm_base_object *,
+						  enum ttm_ref_type ref_type))
+{
+	struct ttm_object_device *tdev = tfile->tdev;
+	int ret;
+
+	base->shareable = shareable;
+	base->tfile = ttm_object_file_ref(tfile);
+	base->refcount_release = refcount_release;
+	base->ref_obj_release = ref_obj_release;
+	base->object_type = object_type;
+	write_lock(&tdev->object_lock);
+	kref_init(&base->refcount);
+	ret = drm_ht_just_insert_please(&tdev->object_hash,
+					&base->hash,
+					(unsigned long)base, 31, 0, 0);
+	write_unlock(&tdev->object_lock);
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	ttm_base_object_unref(&base);
+
+	return 0;
+out_err1:
+	(void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+out_err0:
+	return ret;
+}
+EXPORT_SYMBOL(ttm_base_object_init);
+
+static void ttm_release_base(struct kref *kref)
+{
+	struct ttm_base_object *base =
+	    container_of(kref, struct ttm_base_object, refcount);
+	struct ttm_object_device *tdev = base->tfile->tdev;
+
+	(void)drm_ht_remove_item(&tdev->object_hash, &base->hash);
+	write_unlock(&tdev->object_lock);
+	if (base->refcount_release) {
+		ttm_object_file_unref(&base->tfile);
+		base->refcount_release(&base);
+	}
+	write_lock(&tdev->object_lock);
+}
+
+void ttm_base_object_unref(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct ttm_object_device *tdev = base->tfile->tdev;
+
+	*p_base = NULL;
+
+	/*
+	 * Need to take the lock here to avoid racing with
+	 * users trying to look up the object.
+	 */
+
+	write_lock(&tdev->object_lock);
+	(void)kref_put(&base->refcount, &ttm_release_base);
+	write_unlock(&tdev->object_lock);
+}
+EXPORT_SYMBOL(ttm_base_object_unref);
+
+struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
+					       uint32_t key)
+{
+	struct ttm_object_device *tdev = tfile->tdev;
+	struct ttm_base_object *base;
+	struct drm_hash_item *hash;
+	int ret;
+
+	read_lock(&tdev->object_lock);
+	ret = drm_ht_find_item(&tdev->object_hash, key, &hash);
+
+	if (likely(ret == 0)) {
+		base = drm_hash_entry(hash, struct ttm_base_object, hash);
+		kref_get(&base->refcount);
+	}
+	read_unlock(&tdev->object_lock);
+
+	if (unlikely(ret != 0))
+		return NULL;
+
+	if (tfile != base->tfile && !base->shareable) {
+		printk(KERN_ERR TTM_PFX
+		       "Attempted access of non-shareable object.\n");
+		ttm_base_object_unref(&base);
+		return NULL;
+	}
+
+	return base;
+}
+EXPORT_SYMBOL(ttm_base_object_lookup);
+
+int ttm_ref_object_add(struct ttm_object_file *tfile,
+		       struct ttm_base_object *base,
+		       enum ttm_ref_type ref_type, bool *existed)
+{
+	struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+	struct ttm_ref_object *ref;
+	struct drm_hash_item *hash;
+	struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+	int ret = -EINVAL;
+
+	if (existed != NULL)
+		*existed = true;
+
+	while (ret == -EINVAL) {
+		read_lock(&tfile->lock);
+		ret = drm_ht_find_item(ht, base->hash.key, &hash);
+
+		if (ret == 0) {
+			ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+			kref_get(&ref->kref);
+			read_unlock(&tfile->lock);
+			break;
+		}
+
+		read_unlock(&tfile->lock);
+		ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
+					   false, false);
+		if (unlikely(ret != 0))
+			return ret;
+		ref = kmalloc(sizeof(*ref), GFP_KERNEL);
+		if (unlikely(ref == NULL)) {
+			ttm_mem_global_free(mem_glob, sizeof(*ref));
+			return -ENOMEM;
+		}
+
+		ref->hash.key = base->hash.key;
+		ref->obj = base;
+		ref->tfile = tfile;
+		ref->ref_type = ref_type;
+		kref_init(&ref->kref);
+
+		write_lock(&tfile->lock);
+		ret = drm_ht_insert_item(ht, &ref->hash);
+
+		if (likely(ret == 0)) {
+			list_add_tail(&ref->head, &tfile->ref_list);
+			kref_get(&base->refcount);
+			write_unlock(&tfile->lock);
+			if (existed != NULL)
+				*existed = false;
+			break;
+		}
+
+		write_unlock(&tfile->lock);
+		BUG_ON(ret != -EINVAL);
+
+		ttm_mem_global_free(mem_glob, sizeof(*ref));
+		kfree(ref);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ttm_ref_object_add);
+
+static void ttm_ref_object_release(struct kref *kref)
+{
+	struct ttm_ref_object *ref =
+	    container_of(kref, struct ttm_ref_object, kref);
+	struct ttm_base_object *base = ref->obj;
+	struct ttm_object_file *tfile = ref->tfile;
+	struct drm_open_hash *ht;
+	struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
+
+	ht = &tfile->ref_hash[ref->ref_type];
+	(void)drm_ht_remove_item(ht, &ref->hash);
+	list_del(&ref->head);
+	write_unlock(&tfile->lock);
+
+	if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
+		base->ref_obj_release(base, ref->ref_type);
+
+	ttm_base_object_unref(&ref->obj);
+	ttm_mem_global_free(mem_glob, sizeof(*ref));
+	kfree(ref);
+	write_lock(&tfile->lock);
+}
+
+int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
+			      unsigned long key, enum ttm_ref_type ref_type)
+{
+	struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+	struct ttm_ref_object *ref;
+	struct drm_hash_item *hash;
+	int ret;
+
+	write_lock(&tfile->lock);
+	ret = drm_ht_find_item(ht, key, &hash);
+	if (unlikely(ret != 0)) {
+		write_unlock(&tfile->lock);
+		return -EINVAL;
+	}
+	ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
+	kref_put(&ref->kref, ttm_ref_object_release);
+	write_unlock(&tfile->lock);
+	return 0;
+}
+EXPORT_SYMBOL(ttm_ref_object_base_unref);
+
+void ttm_object_file_release(struct ttm_object_file **p_tfile)
+{
+	struct ttm_ref_object *ref;
+	struct list_head *list;
+	unsigned int i;
+	struct ttm_object_file *tfile = *p_tfile;
+
+	*p_tfile = NULL;
+	write_lock(&tfile->lock);
+
+	/*
+	 * Since we release the lock within the loop, we have to
+	 * restart it from the beginning each time.
+	 */
+
+	while (!list_empty(&tfile->ref_list)) {
+		list = tfile->ref_list.next;
+		ref = list_entry(list, struct ttm_ref_object, head);
+		ttm_ref_object_release(&ref->kref);
+	}
+
+	for (i = 0; i < TTM_REF_NUM; ++i)
+		drm_ht_remove(&tfile->ref_hash[i]);
+
+	write_unlock(&tfile->lock);
+	ttm_object_file_unref(&tfile);
+}
+EXPORT_SYMBOL(ttm_object_file_release);
+
+struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
+					     unsigned int hash_order)
+{
+	struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
+	unsigned int i;
+	unsigned int j = 0;
+	int ret;
+
+	if (unlikely(tfile == NULL))
+		return NULL;
+
+	rwlock_init(&tfile->lock);
+	tfile->tdev = tdev;
+	kref_init(&tfile->refcount);
+	INIT_LIST_HEAD(&tfile->ref_list);
+
+	for (i = 0; i < TTM_REF_NUM; ++i) {
+		ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
+		if (ret) {
+			j = i;
+			goto out_err;
+		}
+	}
+
+	return tfile;
+out_err:
+	for (i = 0; i < j; ++i)
+		drm_ht_remove(&tfile->ref_hash[i]);
+
+	kfree(tfile);
+
+	return NULL;
+}
+EXPORT_SYMBOL(ttm_object_file_init);
+
+struct ttm_object_device *ttm_object_device_init(struct ttm_mem_global
+						 *mem_glob,
+						 unsigned int hash_order)
+{
+	struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
+	int ret;
+
+	if (unlikely(tdev == NULL))
+		return NULL;
+
+	tdev->mem_glob = mem_glob;
+	rwlock_init(&tdev->object_lock);
+	atomic_set(&tdev->object_count, 0);
+	ret = drm_ht_create(&tdev->object_hash, hash_order);
+
+	if (likely(ret == 0))
+		return tdev;
+
+	kfree(tdev);
+	return NULL;
+}
+EXPORT_SYMBOL(ttm_object_device_init);
+
+void ttm_object_device_release(struct ttm_object_device **p_tdev)
+{
+	struct ttm_object_device *tdev = *p_tdev;
+
+	*p_tdev = NULL;
+
+	write_lock(&tdev->object_lock);
+	drm_ht_remove(&tdev->object_hash);
+	write_unlock(&tdev->object_lock);
+
+	kfree(tdev);
+}
+EXPORT_SYMBOL(ttm_object_device_release);
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_tt.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_tt.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/ttm/ttm_tt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/ttm/ttm_tt.c	2010-02-24 13:52:17.000000000 -0500
@@ -192,26 +192,38 @@ int ttm_tt_populate(struct ttm_tt *ttm)
 	ttm->state = tt_unbound;
 	return 0;
 }
+EXPORT_SYMBOL(ttm_tt_populate);
 
 #ifdef CONFIG_X86
 static inline int ttm_tt_set_page_caching(struct page *p,
-					  enum ttm_caching_state c_state)
+					  enum ttm_caching_state c_old,
+					  enum ttm_caching_state c_new)
 {
+	int ret = 0;
+
 	if (PageHighMem(p))
 		return 0;
 
-	switch (c_state) {
-	case tt_cached:
-		return set_pages_wb(p, 1);
-	case tt_wc:
-	    return set_memory_wc((unsigned long) page_address(p), 1);
-	default:
-		return set_pages_uc(p, 1);
+	if (c_old != tt_cached) {
+		/* p isn't in the default caching state, set it to
+		 * writeback first to free its current memtype. */
+
+		ret = set_pages_wb(p, 1);
+		if (ret)
+			return ret;
 	}
+
+	if (c_new == tt_wc)
+		ret = set_memory_wc((unsigned long) page_address(p), 1);
+	else if (c_new == tt_uncached)
+		ret = set_pages_uc(p, 1);
+
+	return ret;
 }
 #else /* CONFIG_X86 */
 static inline int ttm_tt_set_page_caching(struct page *p,
-					  enum ttm_caching_state c_state)
+					  enum ttm_caching_state c_old,
+					  enum ttm_caching_state c_new)
 {
 	return 0;
 }
@@ -244,7 +256,9 @@ static int ttm_tt_set_caching(struct ttm
 	for (i = 0; i < ttm->num_pages; ++i) {
 		cur_page = ttm->pages[i];
 		if (likely(cur_page != NULL)) {
-			ret = ttm_tt_set_page_caching(cur_page, c_state);
+			ret = ttm_tt_set_page_caching(cur_page,
+						      ttm->caching_state,
+						      c_state);
 			if (unlikely(ret != 0))
 				goto out_err;
 		}
@@ -258,7 +272,7 @@ out_err:
 	for (j = 0; j < i; ++j) {
 		cur_page = ttm->pages[j];
 		if (likely(cur_page != NULL)) {
-			(void)ttm_tt_set_page_caching(cur_page,
+			(void)ttm_tt_set_page_caching(cur_page, c_state,
 						      ttm->caching_state);
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/via/via_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/via/via_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/via/via_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@ static struct drm_driver driver = {
 		.owner = THIS_MODULE,
 		.open = drm_open,
 		.release = drm_release,
-		.ioctl = drm_ioctl,
+		.unlocked_ioctl = drm_ioctl,
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/Kconfig linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,13 @@
+config DRM_VMWGFX
+	tristate "DRM driver for VMware Virtual GPU"
+	depends on DRM && PCI
+	select FB_DEFERRED_IO
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select DRM_TTM
+	help
+	  KMS enabled DRM driver for SVGA2 virtual hardware.
+
+	  If unsure say n. The compiled module will be
+	  called vmwgfx.ko
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/Makefile linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Makefile
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,9 @@
+
+ccflags-y := -Iinclude/drm
+
+vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
+	    vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \
+	    vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
+	    vmwgfx_overlay.o
+
+obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga3d_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga3d_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga3d_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga3d_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1793 @@
+/**********************************************************
+ * Copyright 1998-2009 VMware, Inc.  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, 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.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_reg.h --
+ *
+ *       SVGA 3D hardware definitions
+ */
+
+#ifndef _SVGA3D_REG_H_
+#define _SVGA3D_REG_H_
+
+#include "svga_reg.h"
+
+
+/*
+ * 3D Hardware Version
+ *
+ *   The hardware version is stored in the SVGA_FIFO_3D_HWVERSION fifo
+ *   register.   Is set by the host and read by the guest.  This lets
+ *   us make new guest drivers which are backwards-compatible with old
+ *   SVGA hardware revisions.  It does not let us support old guest
+ *   drivers.  Good enough for now.
+ *
+ */
+
+#define SVGA3D_MAKE_HWVERSION(major, minor)      (((major) << 16) | ((minor) & 0xFF))
+#define SVGA3D_MAJOR_HWVERSION(version)          ((version) >> 16)
+#define SVGA3D_MINOR_HWVERSION(version)          ((version) & 0xFF)
+
+typedef enum {
+   SVGA3D_HWVERSION_WS5_RC1   = SVGA3D_MAKE_HWVERSION(0, 1),
+   SVGA3D_HWVERSION_WS5_RC2   = SVGA3D_MAKE_HWVERSION(0, 2),
+   SVGA3D_HWVERSION_WS51_RC1  = SVGA3D_MAKE_HWVERSION(0, 3),
+   SVGA3D_HWVERSION_WS6_B1    = SVGA3D_MAKE_HWVERSION(1, 1),
+   SVGA3D_HWVERSION_FUSION_11 = SVGA3D_MAKE_HWVERSION(1, 4),
+   SVGA3D_HWVERSION_WS65_B1   = SVGA3D_MAKE_HWVERSION(2, 0),
+   SVGA3D_HWVERSION_CURRENT   = SVGA3D_HWVERSION_WS65_B1,
+} SVGA3dHardwareVersion;
+
+/*
+ * Generic Types
+ */
+
+typedef uint32 SVGA3dBool; /* 32-bit Bool definition */
+#define SVGA3D_NUM_CLIPPLANES                   6
+#define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS  8
+
+
+/*
+ * Surface formats.
+ *
+ * If you modify this list, be sure to keep GLUtil.c in sync. It
+ * includes the internal format definition of each surface in
+ * GLUtil_ConvertSurfaceFormat, and it contains a table of
+ * human-readable names in GLUtil_GetFormatName.
+ */
+
+typedef enum SVGA3dSurfaceFormat {
+   SVGA3D_FORMAT_INVALID = 0,
+
+   SVGA3D_X8R8G8B8       = 1,
+   SVGA3D_A8R8G8B8       = 2,
+
+   SVGA3D_R5G6B5         = 3,
+   SVGA3D_X1R5G5B5       = 4,
+   SVGA3D_A1R5G5B5       = 5,
+   SVGA3D_A4R4G4B4       = 6,
+
+   SVGA3D_Z_D32          = 7,
+   SVGA3D_Z_D16          = 8,
+   SVGA3D_Z_D24S8        = 9,
+   SVGA3D_Z_D15S1        = 10,
+
+   SVGA3D_LUMINANCE8            = 11,
+   SVGA3D_LUMINANCE4_ALPHA4     = 12,
+   SVGA3D_LUMINANCE16           = 13,
+   SVGA3D_LUMINANCE8_ALPHA8     = 14,
+
+   SVGA3D_DXT1           = 15,
+   SVGA3D_DXT2           = 16,
+   SVGA3D_DXT3           = 17,
+   SVGA3D_DXT4           = 18,
+   SVGA3D_DXT5           = 19,
+
+   SVGA3D_BUMPU8V8       = 20,
+   SVGA3D_BUMPL6V5U5     = 21,
+   SVGA3D_BUMPX8L8V8U8   = 22,
+   SVGA3D_BUMPL8V8U8     = 23,
+
+   SVGA3D_ARGB_S10E5     = 24,   /* 16-bit floating-point ARGB */
+   SVGA3D_ARGB_S23E8     = 25,   /* 32-bit floating-point ARGB */
+
+   SVGA3D_A2R10G10B10    = 26,
+
+   /* signed formats */
+   SVGA3D_V8U8           = 27,
+   SVGA3D_Q8W8V8U8       = 28,
+   SVGA3D_CxV8U8         = 29,
+
+   /* mixed formats */
+   SVGA3D_X8L8V8U8       = 30,
+   SVGA3D_A2W10V10U10    = 31,
+
+   SVGA3D_ALPHA8         = 32,
+
+   /* Single- and dual-component floating point formats */
+   SVGA3D_R_S10E5        = 33,
+   SVGA3D_R_S23E8        = 34,
+   SVGA3D_RG_S10E5       = 35,
+   SVGA3D_RG_S23E8       = 36,
+
+   /*
+    * Any surface can be used as a buffer object, but SVGA3D_BUFFER is
+    * the most efficient format to use when creating new surfaces
+    * expressly for index or vertex data.
+    */
+   SVGA3D_BUFFER         = 37,
+
+   SVGA3D_Z_D24X8        = 38,
+
+   SVGA3D_V16U16         = 39,
+
+   SVGA3D_G16R16         = 40,
+   SVGA3D_A16B16G16R16   = 41,
+
+   /* Packed Video formats */
+   SVGA3D_UYVY           = 42,
+   SVGA3D_YUY2           = 43,
+
+   SVGA3D_FORMAT_MAX
+} SVGA3dSurfaceFormat;
+
+typedef uint32 SVGA3dColor; /* a, r, g, b */
+
+/*
+ * These match the D3DFORMAT_OP definitions used by Direct3D. We need
+ * them so that we can query the host for what the supported surface
+ * operations are (when we're using the D3D backend, in particular),
+ * and so we can send those operations to the guest.
+ */
+typedef enum {
+   SVGA3DFORMAT_OP_TEXTURE                               = 0x00000001,
+   SVGA3DFORMAT_OP_VOLUMETEXTURE                         = 0x00000002,
+   SVGA3DFORMAT_OP_CUBETEXTURE                           = 0x00000004,
+   SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET                = 0x00000008,
+   SVGA3DFORMAT_OP_SAME_FORMAT_RENDERTARGET              = 0x00000010,
+   SVGA3DFORMAT_OP_ZSTENCIL                              = 0x00000040,
+   SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH   = 0x00000080,
+
+/*
+ * This format can be used as a render target if the current display mode
+ * is the same depth if the alpha channel is ignored. e.g. if the device
+ * can render to A8R8G8B8 when the display mode is X8R8G8B8, then the
+ * format op list entry for A8R8G8B8 should have this cap.
+ */
+   SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET  = 0x00000100,
+
+/*
+ * This format contains DirectDraw support (including Flip).  This flag
+ * should not to be set on alpha formats.
+ */
+   SVGA3DFORMAT_OP_DISPLAYMODE                           = 0x00000400,
+
+/*
+ * The rasterizer can support some level of Direct3D support in this format
+ * and implies that the driver can create a Context in this mode (for some
+ * render target format).  When this flag is set, the SVGA3DFORMAT_OP_DISPLAYMODE
+ * flag must also be set.
+ */
+   SVGA3DFORMAT_OP_3DACCELERATION                        = 0x00000800,
+
+/*
+ * This is set for a private format when the driver has put the bpp in
+ * the structure.
+ */
+   SVGA3DFORMAT_OP_PIXELSIZE                             = 0x00001000,
+
+/*
+ * Indicates that this format can be converted to any RGB format for which
+ * SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB is specified
+ */
+   SVGA3DFORMAT_OP_CONVERT_TO_ARGB                       = 0x00002000,
+
+/*
+ * Indicates that this format can be used to create offscreen plain surfaces.
+ */
+   SVGA3DFORMAT_OP_OFFSCREENPLAIN                        = 0x00004000,
+
+/*
+ * Indicated that this format can be read as an SRGB texture (meaning that the
+ * sampler will linearize the looked up data)
+ */
+   SVGA3DFORMAT_OP_SRGBREAD                              = 0x00008000,
+
+/*
+ * Indicates that this format can be used in the bumpmap instructions
+ */
+   SVGA3DFORMAT_OP_BUMPMAP                               = 0x00010000,
+
+/*
+ * Indicates that this format can be sampled by the displacement map sampler
+ */
+   SVGA3DFORMAT_OP_DMAP                                  = 0x00020000,
+
+/*
+ * Indicates that this format cannot be used with texture filtering
+ */
+   SVGA3DFORMAT_OP_NOFILTER                              = 0x00040000,
+
+/*
+ * Indicates that format conversions are supported to this RGB format if
+ * SVGA3DFORMAT_OP_CONVERT_TO_ARGB is specified in the source format.
+ */
+   SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB                    = 0x00080000,
+
+/*
+ * Indicated that this format can be written as an SRGB target (meaning that the
+ * pixel pipe will DE-linearize data on output to format)
+ */
+   SVGA3DFORMAT_OP_SRGBWRITE                             = 0x00100000,
+
+/*
+ * Indicates that this format cannot be used with alpha blending
+ */
+   SVGA3DFORMAT_OP_NOALPHABLEND                          = 0x00200000,
+
+/*
+ * Indicates that the device can auto-generated sublevels for resources
+ * of this format
+ */
+   SVGA3DFORMAT_OP_AUTOGENMIPMAP                         = 0x00400000,
+
+/*
+ * Indicates that this format can be used by vertex texture sampler
+ */
+   SVGA3DFORMAT_OP_VERTEXTEXTURE                         = 0x00800000,
+
+/*
+ * Indicates that this format supports neither texture coordinate wrap
+ * modes, nor mipmapping
+ */
+   SVGA3DFORMAT_OP_NOTEXCOORDWRAPNORMIP                  = 0x01000000
+} SVGA3dFormatOp;
+
+/*
+ * This structure is a conversion of SVGA3DFORMAT_OP_*.
+ * Entries must be located at the same position.
+ */
+typedef union {
+   uint32 value;
+   struct {
+      uint32 texture : 1;
+      uint32 volumeTexture : 1;
+      uint32 cubeTexture : 1;
+      uint32 offscreenRenderTarget : 1;
+      uint32 sameFormatRenderTarget : 1;
+      uint32 unknown1 : 1;
+      uint32 zStencil : 1;
+      uint32 zStencilArbitraryDepth : 1;
+      uint32 sameFormatUpToAlpha : 1;
+      uint32 unknown2 : 1;
+      uint32 displayMode : 1;
+      uint32 acceleration3d : 1;
+      uint32 pixelSize : 1;
+      uint32 convertToARGB : 1;
+      uint32 offscreenPlain : 1;
+      uint32 sRGBRead : 1;
+      uint32 bumpMap : 1;
+      uint32 dmap : 1;
+      uint32 noFilter : 1;
+      uint32 memberOfGroupARGB : 1;
+      uint32 sRGBWrite : 1;
+      uint32 noAlphaBlend : 1;
+      uint32 autoGenMipMap : 1;
+      uint32 vertexTexture : 1;
+      uint32 noTexCoordWrapNorMip : 1;
+   };
+} SVGA3dSurfaceFormatCaps;
+
+/*
+ * SVGA_3D_CMD_SETRENDERSTATE Types.  All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+   SVGA3D_RS_INVALID                   = 0,
+   SVGA3D_RS_ZENABLE                   = 1,     /* SVGA3dBool */
+   SVGA3D_RS_ZWRITEENABLE              = 2,     /* SVGA3dBool */
+   SVGA3D_RS_ALPHATESTENABLE           = 3,     /* SVGA3dBool */
+   SVGA3D_RS_DITHERENABLE              = 4,     /* SVGA3dBool */
+   SVGA3D_RS_BLENDENABLE               = 5,     /* SVGA3dBool */
+   SVGA3D_RS_FOGENABLE                 = 6,     /* SVGA3dBool */
+   SVGA3D_RS_SPECULARENABLE            = 7,     /* SVGA3dBool */
+   SVGA3D_RS_STENCILENABLE             = 8,     /* SVGA3dBool */
+   SVGA3D_RS_LIGHTINGENABLE            = 9,     /* SVGA3dBool */
+   SVGA3D_RS_NORMALIZENORMALS          = 10,    /* SVGA3dBool */
+   SVGA3D_RS_POINTSPRITEENABLE         = 11,    /* SVGA3dBool */
+   SVGA3D_RS_POINTSCALEENABLE          = 12,    /* SVGA3dBool */
+   SVGA3D_RS_STENCILREF                = 13,    /* uint32 */
+   SVGA3D_RS_STENCILMASK               = 14,    /* uint32 */
+   SVGA3D_RS_STENCILWRITEMASK          = 15,    /* uint32 */
+   SVGA3D_RS_FOGSTART                  = 16,    /* float */
+   SVGA3D_RS_FOGEND                    = 17,    /* float */
+   SVGA3D_RS_FOGDENSITY                = 18,    /* float */
+   SVGA3D_RS_POINTSIZE                 = 19,    /* float */
+   SVGA3D_RS_POINTSIZEMIN              = 20,    /* float */
+   SVGA3D_RS_POINTSIZEMAX              = 21,    /* float */
+   SVGA3D_RS_POINTSCALE_A              = 22,    /* float */
+   SVGA3D_RS_POINTSCALE_B              = 23,    /* float */
+   SVGA3D_RS_POINTSCALE_C              = 24,    /* float */
+   SVGA3D_RS_FOGCOLOR                  = 25,    /* SVGA3dColor */
+   SVGA3D_RS_AMBIENT                   = 26,    /* SVGA3dColor */
+   SVGA3D_RS_CLIPPLANEENABLE           = 27,    /* SVGA3dClipPlanes */
+   SVGA3D_RS_FOGMODE                   = 28,    /* SVGA3dFogMode */
+   SVGA3D_RS_FILLMODE                  = 29,    /* SVGA3dFillMode */
+   SVGA3D_RS_SHADEMODE                 = 30,    /* SVGA3dShadeMode */
+   SVGA3D_RS_LINEPATTERN               = 31,    /* SVGA3dLinePattern */
+   SVGA3D_RS_SRCBLEND                  = 32,    /* SVGA3dBlendOp */
+   SVGA3D_RS_DSTBLEND                  = 33,    /* SVGA3dBlendOp */
+   SVGA3D_RS_BLENDEQUATION             = 34,    /* SVGA3dBlendEquation */
+   SVGA3D_RS_CULLMODE                  = 35,    /* SVGA3dFace */
+   SVGA3D_RS_ZFUNC                     = 36,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_ALPHAFUNC                 = 37,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_STENCILFUNC               = 38,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_STENCILFAIL               = 39,    /* SVGA3dStencilOp */
+   SVGA3D_RS_STENCILZFAIL              = 40,    /* SVGA3dStencilOp */
+   SVGA3D_RS_STENCILPASS               = 41,    /* SVGA3dStencilOp */
+   SVGA3D_RS_ALPHAREF                  = 42,    /* float (0.0 .. 1.0) */
+   SVGA3D_RS_FRONTWINDING              = 43,    /* SVGA3dFrontWinding */
+   SVGA3D_RS_COORDINATETYPE            = 44,    /* SVGA3dCoordinateType */
+   SVGA3D_RS_ZBIAS                     = 45,    /* float */
+   SVGA3D_RS_RANGEFOGENABLE            = 46,    /* SVGA3dBool */
+   SVGA3D_RS_COLORWRITEENABLE          = 47,    /* SVGA3dColorMask */
+   SVGA3D_RS_VERTEXMATERIALENABLE      = 48,    /* SVGA3dBool */
+   SVGA3D_RS_DIFFUSEMATERIALSOURCE     = 49,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_SPECULARMATERIALSOURCE    = 50,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_AMBIENTMATERIALSOURCE     = 51,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_EMISSIVEMATERIALSOURCE    = 52,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_TEXTUREFACTOR             = 53,    /* SVGA3dColor */
+   SVGA3D_RS_LOCALVIEWER               = 54,    /* SVGA3dBool */
+   SVGA3D_RS_SCISSORTESTENABLE         = 55,    /* SVGA3dBool */
+   SVGA3D_RS_BLENDCOLOR                = 56,    /* SVGA3dColor */
+   SVGA3D_RS_STENCILENABLE2SIDED       = 57,    /* SVGA3dBool */
+   SVGA3D_RS_CCWSTENCILFUNC            = 58,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_CCWSTENCILFAIL            = 59,    /* SVGA3dStencilOp */
+   SVGA3D_RS_CCWSTENCILZFAIL           = 60,    /* SVGA3dStencilOp */
+   SVGA3D_RS_CCWSTENCILPASS            = 61,    /* SVGA3dStencilOp */
+   SVGA3D_RS_VERTEXBLEND               = 62,    /* SVGA3dVertexBlendFlags */
+   SVGA3D_RS_SLOPESCALEDEPTHBIAS       = 63,    /* float */
+   SVGA3D_RS_DEPTHBIAS                 = 64,    /* float */
+
+
+   /*
+    * Output Gamma Level
+    *
+    * Output gamma effects the gamma curve of colors that are output from the
+    * rendering pipeline.  A value of 1.0 specifies a linear color space. If the
+    * value is <= 0.0, gamma correction is ignored and linear color space is
+    * used.
+    */
+
+   SVGA3D_RS_OUTPUTGAMMA               = 65,    /* float */
+   SVGA3D_RS_ZVISIBLE                  = 66,    /* SVGA3dBool */
+   SVGA3D_RS_LASTPIXEL                 = 67,    /* SVGA3dBool */
+   SVGA3D_RS_CLIPPING                  = 68,    /* SVGA3dBool */
+   SVGA3D_RS_WRAP0                     = 69,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP1                     = 70,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP2                     = 71,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP3                     = 72,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP4                     = 73,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP5                     = 74,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP6                     = 75,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP7                     = 76,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP8                     = 77,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP9                     = 78,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP10                    = 79,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP11                    = 80,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP12                    = 81,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP13                    = 82,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP14                    = 83,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP15                    = 84,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_MULTISAMPLEANTIALIAS      = 85,    /* SVGA3dBool */
+   SVGA3D_RS_MULTISAMPLEMASK           = 86,    /* uint32 */
+   SVGA3D_RS_INDEXEDVERTEXBLENDENABLE  = 87,    /* SVGA3dBool */
+   SVGA3D_RS_TWEENFACTOR               = 88,    /* float */
+   SVGA3D_RS_ANTIALIASEDLINEENABLE     = 89,    /* SVGA3dBool */
+   SVGA3D_RS_COLORWRITEENABLE1         = 90,    /* SVGA3dColorMask */
+   SVGA3D_RS_COLORWRITEENABLE2         = 91,    /* SVGA3dColorMask */
+   SVGA3D_RS_COLORWRITEENABLE3         = 92,    /* SVGA3dColorMask */
+   SVGA3D_RS_SEPARATEALPHABLENDENABLE  = 93,    /* SVGA3dBool */
+   SVGA3D_RS_SRCBLENDALPHA             = 94,    /* SVGA3dBlendOp */
+   SVGA3D_RS_DSTBLENDALPHA             = 95,    /* SVGA3dBlendOp */
+   SVGA3D_RS_BLENDEQUATIONALPHA        = 96,    /* SVGA3dBlendEquation */
+   SVGA3D_RS_MAX
+} SVGA3dRenderStateName;
+
+typedef enum {
+   SVGA3D_VERTEXMATERIAL_NONE     = 0,    /* Use the value in the current material */
+   SVGA3D_VERTEXMATERIAL_DIFFUSE  = 1,    /* Use the value in the diffuse component */
+   SVGA3D_VERTEXMATERIAL_SPECULAR = 2,    /* Use the value in the specular component */
+} SVGA3dVertexMaterial;
+
+typedef enum {
+   SVGA3D_FILLMODE_INVALID = 0,
+   SVGA3D_FILLMODE_POINT   = 1,
+   SVGA3D_FILLMODE_LINE    = 2,
+   SVGA3D_FILLMODE_FILL    = 3,
+   SVGA3D_FILLMODE_MAX
+} SVGA3dFillModeType;
+
+
+typedef
+union {
+   struct {
+      uint16   mode;       /* SVGA3dFillModeType */
+      uint16   face;       /* SVGA3dFace */
+   };
+   uint32 uintValue;
+} SVGA3dFillMode;
+
+typedef enum {
+   SVGA3D_SHADEMODE_INVALID = 0,
+   SVGA3D_SHADEMODE_FLAT    = 1,
+   SVGA3D_SHADEMODE_SMOOTH  = 2,
+   SVGA3D_SHADEMODE_PHONG   = 3,     /* Not supported */
+   SVGA3D_SHADEMODE_MAX
+} SVGA3dShadeMode;
+
+typedef
+union {
+   struct {
+      uint16 repeat;
+      uint16 pattern;
+   };
+   uint32 uintValue;
+} SVGA3dLinePattern;
+
+typedef enum {
+   SVGA3D_BLENDOP_INVALID            = 0,
+   SVGA3D_BLENDOP_ZERO               = 1,
+   SVGA3D_BLENDOP_ONE                = 2,
+   SVGA3D_BLENDOP_SRCCOLOR           = 3,
+   SVGA3D_BLENDOP_INVSRCCOLOR        = 4,
+   SVGA3D_BLENDOP_SRCALPHA           = 5,
+   SVGA3D_BLENDOP_INVSRCALPHA        = 6,
+   SVGA3D_BLENDOP_DESTALPHA          = 7,
+   SVGA3D_BLENDOP_INVDESTALPHA       = 8,
+   SVGA3D_BLENDOP_DESTCOLOR          = 9,
+   SVGA3D_BLENDOP_INVDESTCOLOR       = 10,
+   SVGA3D_BLENDOP_SRCALPHASAT        = 11,
+   SVGA3D_BLENDOP_BLENDFACTOR        = 12,
+   SVGA3D_BLENDOP_INVBLENDFACTOR     = 13,
+   SVGA3D_BLENDOP_MAX
+} SVGA3dBlendOp;
+
+typedef enum {
+   SVGA3D_BLENDEQ_INVALID            = 0,
+   SVGA3D_BLENDEQ_ADD                = 1,
+   SVGA3D_BLENDEQ_SUBTRACT           = 2,
+   SVGA3D_BLENDEQ_REVSUBTRACT        = 3,
+   SVGA3D_BLENDEQ_MINIMUM            = 4,
+   SVGA3D_BLENDEQ_MAXIMUM            = 5,
+   SVGA3D_BLENDEQ_MAX
+} SVGA3dBlendEquation;
+
+typedef enum {
+   SVGA3D_FRONTWINDING_INVALID = 0,
+   SVGA3D_FRONTWINDING_CW      = 1,
+   SVGA3D_FRONTWINDING_CCW     = 2,
+   SVGA3D_FRONTWINDING_MAX
+} SVGA3dFrontWinding;
+
+typedef enum {
+   SVGA3D_FACE_INVALID  = 0,
+   SVGA3D_FACE_NONE     = 1,
+   SVGA3D_FACE_FRONT    = 2,
+   SVGA3D_FACE_BACK     = 3,
+   SVGA3D_FACE_FRONT_BACK = 4,
+   SVGA3D_FACE_MAX
+} SVGA3dFace;
+
+/*
+ * The order and the values should not be changed
+ */
+
+typedef enum {
+   SVGA3D_CMP_INVALID              = 0,
+   SVGA3D_CMP_NEVER                = 1,
+   SVGA3D_CMP_LESS                 = 2,
+   SVGA3D_CMP_EQUAL                = 3,
+   SVGA3D_CMP_LESSEQUAL            = 4,
+   SVGA3D_CMP_GREATER              = 5,
+   SVGA3D_CMP_NOTEQUAL             = 6,
+   SVGA3D_CMP_GREATEREQUAL         = 7,
+   SVGA3D_CMP_ALWAYS               = 8,
+   SVGA3D_CMP_MAX
+} SVGA3dCmpFunc;
+
+/*
+ * SVGA3D_FOGFUNC_* specifies the fog equation, or PER_VERTEX which allows
+ * the fog factor to be specified in the alpha component of the specular
+ * (a.k.a. secondary) vertex color.
+ */
+typedef enum {
+   SVGA3D_FOGFUNC_INVALID          = 0,
+   SVGA3D_FOGFUNC_EXP              = 1,
+   SVGA3D_FOGFUNC_EXP2             = 2,
+   SVGA3D_FOGFUNC_LINEAR           = 3,
+   SVGA3D_FOGFUNC_PER_VERTEX       = 4
+} SVGA3dFogFunction;
+
+/*
+ * SVGA3D_FOGTYPE_* specifies if fog factors are computed on a per-vertex
+ * or per-pixel basis.
+ */
+typedef enum {
+   SVGA3D_FOGTYPE_INVALID          = 0,
+   SVGA3D_FOGTYPE_VERTEX           = 1,
+   SVGA3D_FOGTYPE_PIXEL            = 2,
+   SVGA3D_FOGTYPE_MAX              = 3
+} SVGA3dFogType;
+
+/*
+ * SVGA3D_FOGBASE_* selects depth or range-based fog. Depth-based fog is
+ * computed using the eye Z value of each pixel (or vertex), whereas range-
+ * based fog is computed using the actual distance (range) to the eye.
+ */
+typedef enum {
+   SVGA3D_FOGBASE_INVALID          = 0,
+   SVGA3D_FOGBASE_DEPTHBASED       = 1,
+   SVGA3D_FOGBASE_RANGEBASED       = 2,
+   SVGA3D_FOGBASE_MAX              = 3
+} SVGA3dFogBase;
+
+typedef enum {
+   SVGA3D_STENCILOP_INVALID        = 0,
+   SVGA3D_STENCILOP_KEEP           = 1,
+   SVGA3D_STENCILOP_ZERO           = 2,
+   SVGA3D_STENCILOP_REPLACE        = 3,
+   SVGA3D_STENCILOP_INCRSAT        = 4,
+   SVGA3D_STENCILOP_DECRSAT        = 5,
+   SVGA3D_STENCILOP_INVERT         = 6,
+   SVGA3D_STENCILOP_INCR           = 7,
+   SVGA3D_STENCILOP_DECR           = 8,
+   SVGA3D_STENCILOP_MAX
+} SVGA3dStencilOp;
+
+typedef enum {
+   SVGA3D_CLIPPLANE_0              = (1 << 0),
+   SVGA3D_CLIPPLANE_1              = (1 << 1),
+   SVGA3D_CLIPPLANE_2              = (1 << 2),
+   SVGA3D_CLIPPLANE_3              = (1 << 3),
+   SVGA3D_CLIPPLANE_4              = (1 << 4),
+   SVGA3D_CLIPPLANE_5              = (1 << 5),
+} SVGA3dClipPlanes;
+
+typedef enum {
+   SVGA3D_CLEAR_COLOR              = 0x1,
+   SVGA3D_CLEAR_DEPTH              = 0x2,
+   SVGA3D_CLEAR_STENCIL            = 0x4
+} SVGA3dClearFlag;
+
+typedef enum {
+   SVGA3D_RT_DEPTH                 = 0,
+   SVGA3D_RT_STENCIL               = 1,
+   SVGA3D_RT_COLOR0                = 2,
+   SVGA3D_RT_COLOR1                = 3,
+   SVGA3D_RT_COLOR2                = 4,
+   SVGA3D_RT_COLOR3                = 5,
+   SVGA3D_RT_COLOR4                = 6,
+   SVGA3D_RT_COLOR5                = 7,
+   SVGA3D_RT_COLOR6                = 8,
+   SVGA3D_RT_COLOR7                = 9,
+   SVGA3D_RT_MAX,
+   SVGA3D_RT_INVALID               = ((uint32)-1),
+} SVGA3dRenderTargetType;
+
+#define SVGA3D_MAX_RT_COLOR (SVGA3D_RT_COLOR7 - SVGA3D_RT_COLOR0 + 1)
+
+typedef
+union {
+   struct {
+      uint32  red   : 1;
+      uint32  green : 1;
+      uint32  blue  : 1;
+      uint32  alpha : 1;
+   };
+   uint32 uintValue;
+} SVGA3dColorMask;
+
+typedef enum {
+   SVGA3D_VBLEND_DISABLE            = 0,
+   SVGA3D_VBLEND_1WEIGHT            = 1,
+   SVGA3D_VBLEND_2WEIGHT            = 2,
+   SVGA3D_VBLEND_3WEIGHT            = 3,
+} SVGA3dVertexBlendFlags;
+
+typedef enum {
+   SVGA3D_WRAPCOORD_0   = 1 << 0,
+   SVGA3D_WRAPCOORD_1   = 1 << 1,
+   SVGA3D_WRAPCOORD_2   = 1 << 2,
+   SVGA3D_WRAPCOORD_3   = 1 << 3,
+   SVGA3D_WRAPCOORD_ALL = 0xF,
+} SVGA3dWrapFlags;
+
+/*
+ * SVGA_3D_CMD_TEXTURESTATE Types.  All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+   SVGA3D_TS_INVALID                    = 0,
+   SVGA3D_TS_BIND_TEXTURE               = 1,    /* SVGA3dSurfaceId */
+   SVGA3D_TS_COLOROP                    = 2,    /* SVGA3dTextureCombiner */
+   SVGA3D_TS_COLORARG1                  = 3,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_COLORARG2                  = 4,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAOP                    = 5,    /* SVGA3dTextureCombiner */
+   SVGA3D_TS_ALPHAARG1                  = 6,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAARG2                  = 7,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ADDRESSU                   = 8,    /* SVGA3dTextureAddress */
+   SVGA3D_TS_ADDRESSV                   = 9,    /* SVGA3dTextureAddress */
+   SVGA3D_TS_MIPFILTER                  = 10,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_MAGFILTER                  = 11,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_MINFILTER                  = 12,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_BORDERCOLOR                = 13,   /* SVGA3dColor */
+   SVGA3D_TS_TEXCOORDINDEX              = 14,   /* uint32 */
+   SVGA3D_TS_TEXTURETRANSFORMFLAGS      = 15,   /* SVGA3dTexTransformFlags */
+   SVGA3D_TS_TEXCOORDGEN                = 16,   /* SVGA3dTextureCoordGen */
+   SVGA3D_TS_BUMPENVMAT00               = 17,   /* float */
+   SVGA3D_TS_BUMPENVMAT01               = 18,   /* float */
+   SVGA3D_TS_BUMPENVMAT10               = 19,   /* float */
+   SVGA3D_TS_BUMPENVMAT11               = 20,   /* float */
+   SVGA3D_TS_TEXTURE_MIPMAP_LEVEL       = 21,   /* uint32 */
+   SVGA3D_TS_TEXTURE_LOD_BIAS           = 22,   /* float */
+   SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL  = 23,   /* uint32 */
+   SVGA3D_TS_ADDRESSW                   = 24,   /* SVGA3dTextureAddress */
+
+
+   /*
+    * Sampler Gamma Level
+    *
+    * Sampler gamma effects the color of samples taken from the sampler.  A
+    * value of 1.0 will produce linear samples.  If the value is <= 0.0 the
+    * gamma value is ignored and a linear space is used.
+    */
+
+   SVGA3D_TS_GAMMA                      = 25,   /* float */
+   SVGA3D_TS_BUMPENVLSCALE              = 26,   /* float */
+   SVGA3D_TS_BUMPENVLOFFSET             = 27,   /* float */
+   SVGA3D_TS_COLORARG0                  = 28,   /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAARG0                  = 29,   /* SVGA3dTextureArgData */
+   SVGA3D_TS_MAX
+} SVGA3dTextureStateName;
+
+typedef enum {
+   SVGA3D_TC_INVALID                   = 0,
+   SVGA3D_TC_DISABLE                   = 1,
+   SVGA3D_TC_SELECTARG1                = 2,
+   SVGA3D_TC_SELECTARG2                = 3,
+   SVGA3D_TC_MODULATE                  = 4,
+   SVGA3D_TC_ADD                       = 5,
+   SVGA3D_TC_ADDSIGNED                 = 6,
+   SVGA3D_TC_SUBTRACT                  = 7,
+   SVGA3D_TC_BLENDTEXTUREALPHA         = 8,
+   SVGA3D_TC_BLENDDIFFUSEALPHA         = 9,
+   SVGA3D_TC_BLENDCURRENTALPHA         = 10,
+   SVGA3D_TC_BLENDFACTORALPHA          = 11,
+   SVGA3D_TC_MODULATE2X                = 12,
+   SVGA3D_TC_MODULATE4X                = 13,
+   SVGA3D_TC_DSDT                      = 14,
+   SVGA3D_TC_DOTPRODUCT3               = 15,
+   SVGA3D_TC_BLENDTEXTUREALPHAPM       = 16,
+   SVGA3D_TC_ADDSIGNED2X               = 17,
+   SVGA3D_TC_ADDSMOOTH                 = 18,
+   SVGA3D_TC_PREMODULATE               = 19,
+   SVGA3D_TC_MODULATEALPHA_ADDCOLOR    = 20,
+   SVGA3D_TC_MODULATECOLOR_ADDALPHA    = 21,
+   SVGA3D_TC_MODULATEINVALPHA_ADDCOLOR = 22,
+   SVGA3D_TC_MODULATEINVCOLOR_ADDALPHA = 23,
+   SVGA3D_TC_BUMPENVMAPLUMINANCE       = 24,
+   SVGA3D_TC_MULTIPLYADD               = 25,
+   SVGA3D_TC_LERP                      = 26,
+   SVGA3D_TC_MAX
+} SVGA3dTextureCombiner;
+
+#define SVGA3D_TC_CAP_BIT(svga3d_tc_op) (svga3d_tc_op ? (1 << (svga3d_tc_op - 1)) : 0)
+
+typedef enum {
+   SVGA3D_TEX_ADDRESS_INVALID    = 0,
+   SVGA3D_TEX_ADDRESS_WRAP       = 1,
+   SVGA3D_TEX_ADDRESS_MIRROR     = 2,
+   SVGA3D_TEX_ADDRESS_CLAMP      = 3,
+   SVGA3D_TEX_ADDRESS_BORDER     = 4,
+   SVGA3D_TEX_ADDRESS_MIRRORONCE = 5,
+   SVGA3D_TEX_ADDRESS_EDGE       = 6,
+   SVGA3D_TEX_ADDRESS_MAX
+} SVGA3dTextureAddress;
+
+/*
+ * SVGA3D_TEX_FILTER_NONE as the minification filter means mipmapping is
+ * disabled, and the rasterizer should use the magnification filter instead.
+ */
+typedef enum {
+   SVGA3D_TEX_FILTER_NONE           = 0,
+   SVGA3D_TEX_FILTER_NEAREST        = 1,
+   SVGA3D_TEX_FILTER_LINEAR         = 2,
+   SVGA3D_TEX_FILTER_ANISOTROPIC    = 3,
+   SVGA3D_TEX_FILTER_FLATCUBIC      = 4, // Deprecated, not implemented
+   SVGA3D_TEX_FILTER_GAUSSIANCUBIC  = 5, // Deprecated, not implemented
+   SVGA3D_TEX_FILTER_PYRAMIDALQUAD  = 6, // Not currently implemented
+   SVGA3D_TEX_FILTER_GAUSSIANQUAD   = 7, // Not currently implemented
+   SVGA3D_TEX_FILTER_MAX
+} SVGA3dTextureFilter;
+
+typedef enum {
+   SVGA3D_TEX_TRANSFORM_OFF    = 0,
+   SVGA3D_TEX_TRANSFORM_S      = (1 << 0),
+   SVGA3D_TEX_TRANSFORM_T      = (1 << 1),
+   SVGA3D_TEX_TRANSFORM_R      = (1 << 2),
+   SVGA3D_TEX_TRANSFORM_Q      = (1 << 3),
+   SVGA3D_TEX_PROJECTED        = (1 << 15),
+} SVGA3dTexTransformFlags;
+
+typedef enum {
+   SVGA3D_TEXCOORD_GEN_OFF              = 0,
+   SVGA3D_TEXCOORD_GEN_EYE_POSITION     = 1,
+   SVGA3D_TEXCOORD_GEN_EYE_NORMAL       = 2,
+   SVGA3D_TEXCOORD_GEN_REFLECTIONVECTOR = 3,
+   SVGA3D_TEXCOORD_GEN_SPHERE           = 4,
+   SVGA3D_TEXCOORD_GEN_MAX
+} SVGA3dTextureCoordGen;
+
+/*
+ * Texture argument constants for texture combiner
+ */
+typedef enum {
+   SVGA3D_TA_INVALID    = 0,
+   SVGA3D_TA_CONSTANT   = 1,
+   SVGA3D_TA_PREVIOUS   = 2,
+   SVGA3D_TA_DIFFUSE    = 3,
+   SVGA3D_TA_TEXTURE    = 4,
+   SVGA3D_TA_SPECULAR   = 5,
+   SVGA3D_TA_MAX
+} SVGA3dTextureArgData;
+
+#define SVGA3D_TM_MASK_LEN 4
+
+/* Modifiers for texture argument constants defined above. */
+typedef enum {
+   SVGA3D_TM_NONE       = 0,
+   SVGA3D_TM_ALPHA      = (1 << SVGA3D_TM_MASK_LEN),
+   SVGA3D_TM_ONE_MINUS  = (2 << SVGA3D_TM_MASK_LEN),
+} SVGA3dTextureArgModifier;
+
+#define SVGA3D_INVALID_ID         ((uint32)-1)
+#define SVGA3D_MAX_CLIP_PLANES    6
+
+/*
+ * This is the limit to the number of fixed-function texture
+ * transforms and texture coordinates we can support. It does *not*
+ * correspond to the number of texture image units (samplers) we
+ * support!
+ */
+#define SVGA3D_MAX_TEXTURE_COORDS 8
+
+/*
+ * Vertex declarations
+ *
+ * Notes:
+ *
+ * SVGA3D_DECLUSAGE_POSITIONT is for pre-transformed vertices. If you
+ * draw with any POSITIONT vertex arrays, the programmable vertex
+ * pipeline will be implicitly disabled. Drawing will take place as if
+ * no vertex shader was bound.
+ */
+
+typedef enum {
+   SVGA3D_DECLUSAGE_POSITION     = 0,
+   SVGA3D_DECLUSAGE_BLENDWEIGHT,       //  1
+   SVGA3D_DECLUSAGE_BLENDINDICES,      //  2
+   SVGA3D_DECLUSAGE_NORMAL,            //  3
+   SVGA3D_DECLUSAGE_PSIZE,             //  4
+   SVGA3D_DECLUSAGE_TEXCOORD,          //  5
+   SVGA3D_DECLUSAGE_TANGENT,           //  6
+   SVGA3D_DECLUSAGE_BINORMAL,          //  7
+   SVGA3D_DECLUSAGE_TESSFACTOR,        //  8
+   SVGA3D_DECLUSAGE_POSITIONT,         //  9
+   SVGA3D_DECLUSAGE_COLOR,             // 10
+   SVGA3D_DECLUSAGE_FOG,               // 11
+   SVGA3D_DECLUSAGE_DEPTH,             // 12
+   SVGA3D_DECLUSAGE_SAMPLE,            // 13
+   SVGA3D_DECLUSAGE_MAX
+} SVGA3dDeclUsage;
+
+typedef enum {
+   SVGA3D_DECLMETHOD_DEFAULT     = 0,
+   SVGA3D_DECLMETHOD_PARTIALU,
+   SVGA3D_DECLMETHOD_PARTIALV,
+   SVGA3D_DECLMETHOD_CROSSUV,          // Normal
+   SVGA3D_DECLMETHOD_UV,
+   SVGA3D_DECLMETHOD_LOOKUP,           // Lookup a displacement map
+   SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map
+} SVGA3dDeclMethod;
+
+typedef enum {
+   SVGA3D_DECLTYPE_FLOAT1        =  0,
+   SVGA3D_DECLTYPE_FLOAT2        =  1,
+   SVGA3D_DECLTYPE_FLOAT3        =  2,
+   SVGA3D_DECLTYPE_FLOAT4        =  3,
+   SVGA3D_DECLTYPE_D3DCOLOR      =  4,
+   SVGA3D_DECLTYPE_UBYTE4        =  5,
+   SVGA3D_DECLTYPE_SHORT2        =  6,
+   SVGA3D_DECLTYPE_SHORT4        =  7,
+   SVGA3D_DECLTYPE_UBYTE4N       =  8,
+   SVGA3D_DECLTYPE_SHORT2N       =  9,
+   SVGA3D_DECLTYPE_SHORT4N       = 10,
+   SVGA3D_DECLTYPE_USHORT2N      = 11,
+   SVGA3D_DECLTYPE_USHORT4N      = 12,
+   SVGA3D_DECLTYPE_UDEC3         = 13,
+   SVGA3D_DECLTYPE_DEC3N         = 14,
+   SVGA3D_DECLTYPE_FLOAT16_2     = 15,
+   SVGA3D_DECLTYPE_FLOAT16_4     = 16,
+   SVGA3D_DECLTYPE_MAX,
+} SVGA3dDeclType;
+
+/*
+ * This structure is used for the divisor for geometry instancing;
+ * it's a direct translation of the Direct3D equivalent.
+ */
+typedef union {
+   struct {
+      /*
+       * For index data, this number represents the number of instances to draw.
+       * For instance data, this number represents the number of
+       * instances/vertex in this stream
+       */
+      uint32 count : 30;
+
+      /*
+       * This is 1 if this is supposed to be the data that is repeated for
+       * every instance.
+       */
+      uint32 indexedData : 1;
+
+      /*
+       * This is 1 if this is supposed to be the per-instance data.
+       */
+      uint32 instanceData : 1;
+   };
+
+   uint32 value;
+} SVGA3dVertexDivisor;
+
+typedef enum {
+   SVGA3D_PRIMITIVE_INVALID                     = 0,
+   SVGA3D_PRIMITIVE_TRIANGLELIST                = 1,
+   SVGA3D_PRIMITIVE_POINTLIST                   = 2,
+   SVGA3D_PRIMITIVE_LINELIST                    = 3,
+   SVGA3D_PRIMITIVE_LINESTRIP                   = 4,
+   SVGA3D_PRIMITIVE_TRIANGLESTRIP               = 5,
+   SVGA3D_PRIMITIVE_TRIANGLEFAN                 = 6,
+   SVGA3D_PRIMITIVE_MAX
+} SVGA3dPrimitiveType;
+
+typedef enum {
+   SVGA3D_COORDINATE_INVALID                   = 0,
+   SVGA3D_COORDINATE_LEFTHANDED                = 1,
+   SVGA3D_COORDINATE_RIGHTHANDED               = 2,
+   SVGA3D_COORDINATE_MAX
+} SVGA3dCoordinateType;
+
+typedef enum {
+   SVGA3D_TRANSFORM_INVALID                     = 0,
+   SVGA3D_TRANSFORM_WORLD                       = 1,
+   SVGA3D_TRANSFORM_VIEW                        = 2,
+   SVGA3D_TRANSFORM_PROJECTION                  = 3,
+   SVGA3D_TRANSFORM_TEXTURE0                    = 4,
+   SVGA3D_TRANSFORM_TEXTURE1                    = 5,
+   SVGA3D_TRANSFORM_TEXTURE2                    = 6,
+   SVGA3D_TRANSFORM_TEXTURE3                    = 7,
+   SVGA3D_TRANSFORM_TEXTURE4                    = 8,
+   SVGA3D_TRANSFORM_TEXTURE5                    = 9,
+   SVGA3D_TRANSFORM_TEXTURE6                    = 10,
+   SVGA3D_TRANSFORM_TEXTURE7                    = 11,
+   SVGA3D_TRANSFORM_WORLD1                      = 12,
+   SVGA3D_TRANSFORM_WORLD2                      = 13,
+   SVGA3D_TRANSFORM_WORLD3                      = 14,
+   SVGA3D_TRANSFORM_MAX
+} SVGA3dTransformType;
+
+typedef enum {
+   SVGA3D_LIGHTTYPE_INVALID                     = 0,
+   SVGA3D_LIGHTTYPE_POINT                       = 1,
+   SVGA3D_LIGHTTYPE_SPOT1                       = 2, /* 1-cone, in degrees */
+   SVGA3D_LIGHTTYPE_SPOT2                       = 3, /* 2-cone, in radians */
+   SVGA3D_LIGHTTYPE_DIRECTIONAL                 = 4,
+   SVGA3D_LIGHTTYPE_MAX
+} SVGA3dLightType;
+
+typedef enum {
+   SVGA3D_CUBEFACE_POSX                         = 0,
+   SVGA3D_CUBEFACE_NEGX                         = 1,
+   SVGA3D_CUBEFACE_POSY                         = 2,
+   SVGA3D_CUBEFACE_NEGY                         = 3,
+   SVGA3D_CUBEFACE_POSZ                         = 4,
+   SVGA3D_CUBEFACE_NEGZ                         = 5,
+} SVGA3dCubeFace;
+
+typedef enum {
+   SVGA3D_SHADERTYPE_COMPILED_DX8               = 0,
+   SVGA3D_SHADERTYPE_VS                         = 1,
+   SVGA3D_SHADERTYPE_PS                         = 2,
+   SVGA3D_SHADERTYPE_MAX
+} SVGA3dShaderType;
+
+typedef enum {
+   SVGA3D_CONST_TYPE_FLOAT                      = 0,
+   SVGA3D_CONST_TYPE_INT                        = 1,
+   SVGA3D_CONST_TYPE_BOOL                       = 2,
+} SVGA3dShaderConstType;
+
+#define SVGA3D_MAX_SURFACE_FACES                6
+
+typedef enum {
+   SVGA3D_STRETCH_BLT_POINT                     = 0,
+   SVGA3D_STRETCH_BLT_LINEAR                    = 1,
+   SVGA3D_STRETCH_BLT_MAX
+} SVGA3dStretchBltMode;
+
+typedef enum {
+   SVGA3D_QUERYTYPE_OCCLUSION                   = 0,
+   SVGA3D_QUERYTYPE_MAX
+} SVGA3dQueryType;
+
+typedef enum {
+   SVGA3D_QUERYSTATE_PENDING     = 0,      /* Waiting on the host (set by guest) */
+   SVGA3D_QUERYSTATE_SUCCEEDED   = 1,      /* Completed successfully (set by host) */
+   SVGA3D_QUERYSTATE_FAILED      = 2,      /* Completed unsuccessfully (set by host) */
+   SVGA3D_QUERYSTATE_NEW         = 3,      /* Never submitted (For guest use only) */
+} SVGA3dQueryState;
+
+typedef enum {
+   SVGA3D_WRITE_HOST_VRAM        = 1,
+   SVGA3D_READ_HOST_VRAM         = 2,
+} SVGA3dTransferType;
+
+/*
+ * The maximum number vertex arrays we're guaranteed to support in
+ * SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_VERTEX_ARRAYS   32
+
+/*
+ * Identifiers for commands in the command FIFO.
+ *
+ * IDs between 1000 and 1039 (inclusive) were used by obsolete versions of
+ * the SVGA3D protocol and remain reserved; they should not be used in the
+ * future.
+ *
+ * IDs between 1040 and 1999 (inclusive) are available for use by the
+ * current SVGA3D protocol.
+ *
+ * FIFO clients other than SVGA3D should stay below 1000, or at 2000
+ * and up.
+ */
+
+#define SVGA_3D_CMD_LEGACY_BASE            1000
+#define SVGA_3D_CMD_BASE                   1040
+
+#define SVGA_3D_CMD_SURFACE_DEFINE         SVGA_3D_CMD_BASE + 0
+#define SVGA_3D_CMD_SURFACE_DESTROY        SVGA_3D_CMD_BASE + 1
+#define SVGA_3D_CMD_SURFACE_COPY           SVGA_3D_CMD_BASE + 2
+#define SVGA_3D_CMD_SURFACE_STRETCHBLT     SVGA_3D_CMD_BASE + 3
+#define SVGA_3D_CMD_SURFACE_DMA            SVGA_3D_CMD_BASE + 4
+#define SVGA_3D_CMD_CONTEXT_DEFINE         SVGA_3D_CMD_BASE + 5
+#define SVGA_3D_CMD_CONTEXT_DESTROY        SVGA_3D_CMD_BASE + 6
+#define SVGA_3D_CMD_SETTRANSFORM           SVGA_3D_CMD_BASE + 7
+#define SVGA_3D_CMD_SETZRANGE              SVGA_3D_CMD_BASE + 8
+#define SVGA_3D_CMD_SETRENDERSTATE         SVGA_3D_CMD_BASE + 9
+#define SVGA_3D_CMD_SETRENDERTARGET        SVGA_3D_CMD_BASE + 10
+#define SVGA_3D_CMD_SETTEXTURESTATE        SVGA_3D_CMD_BASE + 11
+#define SVGA_3D_CMD_SETMATERIAL            SVGA_3D_CMD_BASE + 12
+#define SVGA_3D_CMD_SETLIGHTDATA           SVGA_3D_CMD_BASE + 13
+#define SVGA_3D_CMD_SETLIGHTENABLED        SVGA_3D_CMD_BASE + 14
+#define SVGA_3D_CMD_SETVIEWPORT            SVGA_3D_CMD_BASE + 15
+#define SVGA_3D_CMD_SETCLIPPLANE           SVGA_3D_CMD_BASE + 16
+#define SVGA_3D_CMD_CLEAR                  SVGA_3D_CMD_BASE + 17
+#define SVGA_3D_CMD_PRESENT                SVGA_3D_CMD_BASE + 18    // Deprecated
+#define SVGA_3D_CMD_SHADER_DEFINE          SVGA_3D_CMD_BASE + 19
+#define SVGA_3D_CMD_SHADER_DESTROY         SVGA_3D_CMD_BASE + 20
+#define SVGA_3D_CMD_SET_SHADER             SVGA_3D_CMD_BASE + 21
+#define SVGA_3D_CMD_SET_SHADER_CONST       SVGA_3D_CMD_BASE + 22
+#define SVGA_3D_CMD_DRAW_PRIMITIVES        SVGA_3D_CMD_BASE + 23
+#define SVGA_3D_CMD_SETSCISSORRECT         SVGA_3D_CMD_BASE + 24
+#define SVGA_3D_CMD_BEGIN_QUERY            SVGA_3D_CMD_BASE + 25
+#define SVGA_3D_CMD_END_QUERY              SVGA_3D_CMD_BASE + 26
+#define SVGA_3D_CMD_WAIT_FOR_QUERY         SVGA_3D_CMD_BASE + 27
+#define SVGA_3D_CMD_PRESENT_READBACK       SVGA_3D_CMD_BASE + 28    // Deprecated
+#define SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN SVGA_3D_CMD_BASE + 29
+#define SVGA_3D_CMD_MAX                    SVGA_3D_CMD_BASE + 30
+
+#define SVGA_3D_CMD_FUTURE_MAX             2000
+
+/*
+ * Common substructures used in multiple FIFO commands:
+ */
+
+typedef struct {
+   union {
+      struct {
+         uint16  function;       // SVGA3dFogFunction
+         uint8   type;           // SVGA3dFogType
+         uint8   base;           // SVGA3dFogBase
+      };
+      uint32     uintValue;
+   };
+} SVGA3dFogMode;
+
+/*
+ * Uniquely identify one image (a 1D/2D/3D array) from a surface. This
+ * is a surface ID as well as face/mipmap indices.
+ */
+
+typedef
+struct SVGA3dSurfaceImageId {
+   uint32               sid;
+   uint32               face;
+   uint32               mipmap;
+} SVGA3dSurfaceImageId;
+
+typedef
+struct SVGA3dGuestImage {
+   SVGAGuestPtr         ptr;
+
+   /*
+    * A note on interpretation of pitch: This value of pitch is the
+    * number of bytes between vertically adjacent image
+    * blocks. Normally this is the number of bytes between the first
+    * pixel of two adjacent scanlines. With compressed textures,
+    * however, this may represent the number of bytes between
+    * compression blocks rather than between rows of pixels.
+    *
+    * XXX: Compressed textures currently must be tightly packed in guest memory.
+    *
+    * If the image is 1-dimensional, pitch is ignored.
+    *
+    * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+    * assuming each row of blocks is tightly packed.
+    */
+   uint32 pitch;
+} SVGA3dGuestImage;
+
+
+/*
+ * FIFO command format definitions:
+ */
+
+/*
+ * The data size header following cmdNum for every 3d command
+ */
+typedef
+struct {
+   uint32               id;
+   uint32               size;
+} SVGA3dCmdHeader;
+
+/*
+ * A surface is a hierarchy of host VRAM surfaces: 1D, 2D, or 3D, with
+ * optional mipmaps and cube faces.
+ */
+
+typedef
+struct {
+   uint32               width;
+   uint32               height;
+   uint32               depth;
+} SVGA3dSize;
+
+typedef enum {
+   SVGA3D_SURFACE_CUBEMAP              = (1 << 0),
+   SVGA3D_SURFACE_HINT_STATIC          = (1 << 1),
+   SVGA3D_SURFACE_HINT_DYNAMIC         = (1 << 2),
+   SVGA3D_SURFACE_HINT_INDEXBUFFER     = (1 << 3),
+   SVGA3D_SURFACE_HINT_VERTEXBUFFER    = (1 << 4),
+   SVGA3D_SURFACE_HINT_TEXTURE         = (1 << 5),
+   SVGA3D_SURFACE_HINT_RENDERTARGET    = (1 << 6),
+   SVGA3D_SURFACE_HINT_DEPTHSTENCIL    = (1 << 7),
+   SVGA3D_SURFACE_HINT_WRITEONLY       = (1 << 8),
+} SVGA3dSurfaceFlags;
+
+typedef
+struct {
+   uint32               numMipLevels;
+} SVGA3dSurfaceFace;
+
+typedef
+struct {
+   uint32                      sid;
+   SVGA3dSurfaceFlags          surfaceFlags;
+   SVGA3dSurfaceFormat         format;
+   SVGA3dSurfaceFace           face[SVGA3D_MAX_SURFACE_FACES];
+   /*
+    * Followed by an SVGA3dSize structure for each mip level in each face.
+    *
+    * A note on surface sizes: Sizes are always specified in pixels,
+    * even if the true surface size is not a multiple of the minimum
+    * block size of the surface's format. For example, a 3x3x1 DXT1
+    * compressed texture would actually be stored as a 4x4x1 image in
+    * memory.
+    */
+} SVGA3dCmdDefineSurface;       /* SVGA_3D_CMD_SURFACE_DEFINE */
+
+typedef
+struct {
+   uint32               sid;
+} SVGA3dCmdDestroySurface;      /* SVGA_3D_CMD_SURFACE_DESTROY */
+
+typedef
+struct {
+   uint32               cid;
+} SVGA3dCmdDefineContext;       /* SVGA_3D_CMD_CONTEXT_DEFINE */
+
+typedef
+struct {
+   uint32               cid;
+} SVGA3dCmdDestroyContext;      /* SVGA_3D_CMD_CONTEXT_DESTROY */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dClearFlag      clearFlag;
+   uint32               color;
+   float                depth;
+   uint32               stencil;
+   /* Followed by variable number of SVGA3dRect structures */
+} SVGA3dCmdClear;               /* SVGA_3D_CMD_CLEAR */
+
+typedef
+struct SVGA3dCopyRect {
+   uint32               x;
+   uint32               y;
+   uint32               w;
+   uint32               h;
+   uint32               srcx;
+   uint32               srcy;
+} SVGA3dCopyRect;
+
+typedef
+struct SVGA3dCopyBox {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+   uint32               w;
+   uint32               h;
+   uint32               d;
+   uint32               srcx;
+   uint32               srcy;
+   uint32               srcz;
+} SVGA3dCopyBox;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               w;
+   uint32               h;
+} SVGA3dRect;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+   uint32               w;
+   uint32               h;
+   uint32               d;
+} SVGA3dBox;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+} SVGA3dPoint;
+
+typedef
+struct {
+   SVGA3dLightType      type;
+   SVGA3dBool           inWorldSpace;
+   float                diffuse[4];
+   float                specular[4];
+   float                ambient[4];
+   float                position[4];
+   float                direction[4];
+   float                range;
+   float                falloff;
+   float                attenuation0;
+   float                attenuation1;
+   float                attenuation2;
+   float                theta;
+   float                phi;
+} SVGA3dLightData;
+
+typedef
+struct {
+   uint32               sid;
+   /* Followed by variable number of SVGA3dCopyRect structures */
+} SVGA3dCmdPresent;             /* SVGA_3D_CMD_PRESENT */
+
+typedef
+struct {
+   SVGA3dRenderStateName   state;
+   union {
+      uint32               uintValue;
+      float                floatValue;
+   };
+} SVGA3dRenderState;
+
+typedef
+struct {
+   uint32               cid;
+   /* Followed by variable number of SVGA3dRenderState structures */
+} SVGA3dCmdSetRenderState;      /* SVGA_3D_CMD_SETRENDERSTATE */
+
+typedef
+struct {
+   uint32                 cid;
+   SVGA3dRenderTargetType type;
+   SVGA3dSurfaceImageId   target;
+} SVGA3dCmdSetRenderTarget;     /* SVGA_3D_CMD_SETRENDERTARGET */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId  src;
+   SVGA3dSurfaceImageId  dest;
+   /* Followed by variable number of SVGA3dCopyBox structures */
+} SVGA3dCmdSurfaceCopy;               /* SVGA_3D_CMD_SURFACE_COPY */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId  src;
+   SVGA3dSurfaceImageId  dest;
+   SVGA3dBox             boxSrc;
+   SVGA3dBox             boxDest;
+   SVGA3dStretchBltMode  mode;
+} SVGA3dCmdSurfaceStretchBlt;         /* SVGA_3D_CMD_SURFACE_STRETCHBLT */
+
+typedef
+struct {
+   /*
+    * If the discard flag is present in a surface DMA operation, the host may
+    * discard the contents of the current mipmap level and face of the target
+    * surface before applying the surface DMA contents.
+    */
+   uint32 discard : 1;
+
+   /*
+    * If the unsynchronized flag is present, the host may perform this upload
+    * without syncing to pending reads on this surface.
+    */
+   uint32 unsynchronized : 1;
+
+   /*
+    * Guests *MUST* set the reserved bits to 0 before submitting the command
+    * suffix as future flags may occupy these bits.
+    */
+   uint32 reserved : 30;
+} SVGA3dSurfaceDMAFlags;
+
+typedef
+struct {
+   SVGA3dGuestImage      guest;
+   SVGA3dSurfaceImageId  host;
+   SVGA3dTransferType    transfer;
+   /*
+    * Followed by variable number of SVGA3dCopyBox structures. For consistency
+    * in all clipping logic and coordinate translation, we define the
+    * "source" in each copyBox as the guest image and the
+    * "destination" as the host image, regardless of transfer
+    * direction.
+    *
+    * For efficiency, the SVGA3D device is free to copy more data than
+    * specified. For example, it may round copy boxes outwards such
+    * that they lie on particular alignment boundaries.
+    */
+} SVGA3dCmdSurfaceDMA;                /* SVGA_3D_CMD_SURFACE_DMA */
+
+/*
+ * SVGA3dCmdSurfaceDMASuffix --
+ *
+ *    This is a command suffix that will appear after a SurfaceDMA command in
+ *    the FIFO.  It contains some extra information that hosts may use to
+ *    optimize performance or protect the guest.  This suffix exists to preserve
+ *    backwards compatibility while also allowing for new functionality to be
+ *    implemented.
+ */
+
+typedef
+struct {
+   uint32 suffixSize;
+
+   /*
+    * The maximum offset is used to determine the maximum offset from the
+    * guestPtr base address that will be accessed or written to during this
+    * surfaceDMA.  If the suffix is supported, the host will respect this
+    * boundary while performing surface DMAs.
+    *
+    * Defaults to MAX_UINT32
+    */
+   uint32 maximumOffset;
+
+   /*
+    * A set of flags that describes optimizations that the host may perform
+    * while performing this surface DMA operation.  The guest should never rely
+    * on behaviour that is different when these flags are set for correctness.
+    *
+    * Defaults to 0
+    */
+   SVGA3dSurfaceDMAFlags flags;
+} SVGA3dCmdSurfaceDMASuffix;
+
+/*
+ * SVGA_3D_CMD_DRAW_PRIMITIVES --
+ *
+ *   This command is the SVGA3D device's generic drawing entry point.
+ *   It can draw multiple ranges of primitives, optionally using an
+ *   index buffer, using an arbitrary collection of vertex buffers.
+ *
+ *   Each SVGA3dVertexDecl defines a distinct vertex array to bind
+ *   during this draw call. The declarations specify which surface
+ *   the vertex data lives in, what that vertex data is used for,
+ *   and how to interpret it.
+ *
+ *   Each SVGA3dPrimitiveRange defines a collection of primitives
+ *   to render using the same vertex arrays. An index buffer is
+ *   optional.
+ */
+
+typedef
+struct {
+   /*
+    * A range hint is an optional specification for the range of indices
+    * in an SVGA3dArray that will be used. If 'last' is zero, it is assumed
+    * that the entire array will be used.
+    *
+    * These are only hints. The SVGA3D device may use them for
+    * performance optimization if possible, but it's also allowed to
+    * ignore these values.
+    */
+   uint32               first;
+   uint32               last;
+} SVGA3dArrayRangeHint;
+
+typedef
+struct {
+   /*
+    * Define the origin and shape of a vertex or index array. Both
+    * 'offset' and 'stride' are in bytes. The provided surface will be
+    * reinterpreted as a flat array of bytes in the same format used
+    * by surface DMA operations. To avoid unnecessary conversions, the
+    * surface should be created with the SVGA3D_BUFFER format.
+    *
+    * Index 0 in the array starts 'offset' bytes into the surface.
+    * Index 1 begins at byte 'offset + stride', etc. Array indices may
+    * not be negative.
+    */
+   uint32               surfaceId;
+   uint32               offset;
+   uint32               stride;
+} SVGA3dArray;
+
+typedef
+struct {
+   /*
+    * Describe a vertex array's data type, and define how it is to be
+    * used by the fixed function pipeline or the vertex shader. It
+    * isn't useful to have two VertexDecls with the same
+    * VertexArrayIdentity in one draw call.
+    */
+   SVGA3dDeclType       type;
+   SVGA3dDeclMethod     method;
+   SVGA3dDeclUsage      usage;
+   uint32               usageIndex;
+} SVGA3dVertexArrayIdentity;
+
+typedef
+struct {
+   SVGA3dVertexArrayIdentity  identity;
+   SVGA3dArray                array;
+   SVGA3dArrayRangeHint       rangeHint;
+} SVGA3dVertexDecl;
+
+typedef
+struct {
+   /*
+    * Define a group of primitives to render, from sequential indices.
+    *
+    * The value of 'primitiveType' and 'primitiveCount' imply the
+    * total number of vertices that will be rendered.
+    */
+   SVGA3dPrimitiveType  primType;
+   uint32               primitiveCount;
+
+   /*
+    * Optional index buffer. If indexArray.surfaceId is
+    * SVGA3D_INVALID_ID, we render without an index buffer. Rendering
+    * without an index buffer is identical to rendering with an index
+    * buffer containing the sequence [0, 1, 2, 3, ...].
+    *
+    * If an index buffer is in use, indexWidth specifies the width in
+    * bytes of each index value. It must be less than or equal to
+    * indexArray.stride.
+    *
+    * (Currently, the SVGA3D device requires index buffers to be tightly
+    * packed. In other words, indexWidth == indexArray.stride)
+    */
+   SVGA3dArray          indexArray;
+   uint32               indexWidth;
+
+   /*
+    * Optional index bias. This number is added to all indices from
+    * indexArray before they are used as vertex array indices. This
+    * can be used in multiple ways:
+    *
+    *  - When not using an indexArray, this bias can be used to
+    *    specify where in the vertex arrays to begin rendering.
+    *
+    *  - A positive number here is equivalent to increasing the
+    *    offset in each vertex array.
+    *
+    *  - A negative number can be used to render using a small
+    *    vertex array and an index buffer that contains large
+    *    values. This may be used by some applications that
+    *    crop a vertex buffer without modifying their index
+    *    buffer.
+    *
+    * Note that rendering with a negative bias value may be slower and
+    * use more memory than rendering with a positive or zero bias.
+    */
+   int32                indexBias;
+} SVGA3dPrimitiveRange;
+
+typedef
+struct {
+   uint32               cid;
+   uint32               numVertexDecls;
+   uint32               numRanges;
+
+   /*
+    * There are two variable size arrays after the
+    * SVGA3dCmdDrawPrimitives structure. In order,
+    * they are:
+    *
+    * 1. SVGA3dVertexDecl, quantity 'numVertexDecls'
+    * 2. SVGA3dPrimitiveRange, quantity 'numRanges'
+    * 3. Optionally, SVGA3dVertexDivisor, quantity 'numVertexDecls' (contains
+    *    the frequency divisor for this the corresponding vertex decl)
+    */
+} SVGA3dCmdDrawPrimitives;      /* SVGA_3D_CMD_DRAWPRIMITIVES */
+
+typedef
+struct {
+   uint32                   stage;
+   SVGA3dTextureStateName   name;
+   union {
+      uint32                value;
+      float                 floatValue;
+   };
+} SVGA3dTextureState;
+
+typedef
+struct {
+   uint32               cid;
+   /* Followed by variable number of SVGA3dTextureState structures */
+} SVGA3dCmdSetTextureState;      /* SVGA_3D_CMD_SETTEXTURESTATE */
+
+typedef
+struct {
+   uint32                   cid;
+   SVGA3dTransformType      type;
+   float                    matrix[16];
+} SVGA3dCmdSetTransform;          /* SVGA_3D_CMD_SETTRANSFORM */
+
+typedef
+struct {
+   float                min;
+   float                max;
+} SVGA3dZRange;
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dZRange         zRange;
+} SVGA3dCmdSetZRange;             /* SVGA_3D_CMD_SETZRANGE */
+
+typedef
+struct {
+   float                diffuse[4];
+   float                ambient[4];
+   float                specular[4];
+   float                emissive[4];
+   float                shininess;
+} SVGA3dMaterial;
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dFace           face;
+   SVGA3dMaterial       material;
+} SVGA3dCmdSetMaterial;           /* SVGA_3D_CMD_SETMATERIAL */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   SVGA3dLightData      data;
+} SVGA3dCmdSetLightData;           /* SVGA_3D_CMD_SETLIGHTDATA */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   uint32               enabled;
+} SVGA3dCmdSetLightEnabled;      /* SVGA_3D_CMD_SETLIGHTENABLED */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dRect           rect;
+} SVGA3dCmdSetViewport;           /* SVGA_3D_CMD_SETVIEWPORT */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dRect           rect;
+} SVGA3dCmdSetScissorRect;         /* SVGA_3D_CMD_SETSCISSORRECT */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   float                plane[4];
+} SVGA3dCmdSetClipPlane;           /* SVGA_3D_CMD_SETCLIPPLANE */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               shid;
+   SVGA3dShaderType     type;
+   /* Followed by variable number of DWORDs for shader bycode */
+} SVGA3dCmdDefineShader;           /* SVGA_3D_CMD_SHADER_DEFINE */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               shid;
+   SVGA3dShaderType     type;
+} SVGA3dCmdDestroyShader;         /* SVGA_3D_CMD_SHADER_DESTROY */
+
+typedef
+struct {
+   uint32                  cid;
+   uint32                  reg;     /* register number */
+   SVGA3dShaderType        type;
+   SVGA3dShaderConstType   ctype;
+   uint32                  values[4];
+} SVGA3dCmdSetShaderConst;        /* SVGA_3D_CMD_SET_SHADER_CONST */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dShaderType     type;
+   uint32               shid;
+} SVGA3dCmdSetShader;             /* SVGA_3D_CMD_SET_SHADER */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dQueryType      type;
+} SVGA3dCmdBeginQuery;           /* SVGA_3D_CMD_BEGIN_QUERY */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dQueryType      type;
+   SVGAGuestPtr         guestResult;  /* Points to an SVGA3dQueryResult structure */
+} SVGA3dCmdEndQuery;                  /* SVGA_3D_CMD_END_QUERY */
+
+typedef
+struct {
+   uint32               cid;          /* Same parameters passed to END_QUERY */
+   SVGA3dQueryType      type;
+   SVGAGuestPtr         guestResult;
+} SVGA3dCmdWaitForQuery;              /* SVGA_3D_CMD_WAIT_FOR_QUERY */
+
+typedef
+struct {
+   uint32               totalSize;    /* Set by guest before query is ended. */
+   SVGA3dQueryState     state;        /* Set by host or guest. See SVGA3dQueryState. */
+   union {                            /* Set by host on exit from PENDING state */
+      uint32            result32;
+   };
+} SVGA3dQueryResult;
+
+/*
+ * SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN --
+ *
+ *    This is a blit from an SVGA3D surface to a Screen Object. Just
+ *    like GMR-to-screen blits, this blit may be directed at a
+ *    specific screen or to the virtual coordinate space.
+ *
+ *    The blit copies from a rectangular region of an SVGA3D surface
+ *    image to a rectangular region of a screen or screens.
+ *
+ *    This command takes an optional variable-length list of clipping
+ *    rectangles after the body of the command. If no rectangles are
+ *    specified, there is no clipping region. The entire destRect is
+ *    drawn to. If one or more rectangles are included, they describe
+ *    a clipping region. The clip rectangle coordinates are measured
+ *    relative to the top-left corner of destRect.
+ *
+ *    This clipping region serves multiple purposes:
+ *
+ *      - It can be used to perform an irregularly shaped blit more
+ *        efficiently than by issuing many separate blit commands.
+ *
+ *      - It is equivalent to allowing blits with non-integer
+ *        source coordinates. You could blit just one half-pixel
+ *        of a source, for example, by specifying a larger
+ *        destination rectangle than you need, then removing
+ *        part of it using a clip rectangle.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ *
+ * Limitations:
+ *
+ *    - Currently, no backend supports blits from a mipmap or face
+ *      other than the first one.
+ */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId srcImage;
+   SVGASignedRect       srcRect;
+   uint32               destScreenId; /* Screen ID or SVGA_ID_INVALID for virt. coords */
+   SVGASignedRect       destRect;     /* Supports scaling if src/rest different size */
+   /* Clipping: zero or more SVGASignedRects follow */
+} SVGA3dCmdBlitSurfaceToScreen;         /* SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN */
+
+
+/*
+ * Capability query index.
+ *
+ * Notes:
+ *
+ *   1. SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of
+ *      fixed-function texture units available. Each of these units
+ *      work in both FFP and Shader modes, and they support texture
+ *      transforms and texture coordinates. The host may have additional
+ *      texture image units that are only usable with shaders.
+ *
+ *   2. The BUFFER_FORMAT capabilities are deprecated, and they always
+ *      return TRUE. Even on physical hardware that does not support
+ *      these formats natively, the SVGA3D device will provide an emulation
+ *      which should be invisible to the guest OS.
+ *
+ *      In general, the SVGA3D device should support any operation on
+ *      any surface format, it just may perform some of these
+ *      operations in software depending on the capabilities of the
+ *      available physical hardware.
+ *
+ *      XXX: In the future, we will add capabilities that describe in
+ *      detail what formats are supported in hardware for what kinds
+ *      of operations.
+ */
+
+typedef enum {
+   SVGA3D_DEVCAP_3D                                = 0,
+   SVGA3D_DEVCAP_MAX_LIGHTS                        = 1,
+   SVGA3D_DEVCAP_MAX_TEXTURES                      = 2,  /* See note (1) */
+   SVGA3D_DEVCAP_MAX_CLIP_PLANES                   = 3,
+   SVGA3D_DEVCAP_VERTEX_SHADER_VERSION             = 4,
+   SVGA3D_DEVCAP_VERTEX_SHADER                     = 5,
+   SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION           = 6,
+   SVGA3D_DEVCAP_FRAGMENT_SHADER                   = 7,
+   SVGA3D_DEVCAP_MAX_RENDER_TARGETS                = 8,
+   SVGA3D_DEVCAP_S23E8_TEXTURES                    = 9,
+   SVGA3D_DEVCAP_S10E5_TEXTURES                    = 10,
+   SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND             = 11,
+   SVGA3D_DEVCAP_D16_BUFFER_FORMAT                 = 12, /* See note (2) */
+   SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT               = 13, /* See note (2) */
+   SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT               = 14, /* See note (2) */
+   SVGA3D_DEVCAP_QUERY_TYPES                       = 15,
+   SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING         = 16,
+   SVGA3D_DEVCAP_MAX_POINT_SIZE                    = 17,
+   SVGA3D_DEVCAP_MAX_SHADER_TEXTURES               = 18,
+   SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH                 = 19,
+   SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT                = 20,
+   SVGA3D_DEVCAP_MAX_VOLUME_EXTENT                 = 21,
+   SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT                = 22,
+   SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO          = 23,
+   SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY            = 24,
+   SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT               = 25,
+   SVGA3D_DEVCAP_MAX_VERTEX_INDEX                  = 26,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS    = 27,
+   SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS  = 28,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS           = 29,
+   SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS         = 30,
+   SVGA3D_DEVCAP_TEXTURE_OPS                       = 31,
+   SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8               = 32,
+   SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8               = 33,
+   SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10            = 34,
+   SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5               = 35,
+   SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5               = 36,
+   SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4               = 37,
+   SVGA3D_DEVCAP_SURFACEFMT_R5G6B5                 = 38,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16            = 39,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8      = 40,
+   SVGA3D_DEVCAP_SURFACEFMT_ALPHA8                 = 41,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8             = 42,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D16                  = 43,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8                = 44,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8                = 45,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT1                   = 46,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT2                   = 47,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT3                   = 48,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT4                   = 49,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT5                   = 50,
+   SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8           = 51,
+   SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10            = 52,
+   SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8               = 53,
+   SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8               = 54,
+   SVGA3D_DEVCAP_SURFACEFMT_CxV8U8                 = 55,
+   SVGA3D_DEVCAP_SURFACEFMT_R_S10E5                = 56,
+   SVGA3D_DEVCAP_SURFACEFMT_R_S23E8                = 57,
+   SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5               = 58,
+   SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8               = 59,
+   SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5             = 60,
+   SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8             = 61,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES        = 63,
+
+   /*
+    * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color
+    * render targets.  This does no include the depth or stencil targets.
+    */
+   SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS   = 64,
+
+   SVGA3D_DEVCAP_SURFACEFMT_V16U16                 = 65,
+   SVGA3D_DEVCAP_SURFACEFMT_G16R16                 = 66,
+   SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16           = 67,
+   SVGA3D_DEVCAP_SURFACEFMT_UYVY                   = 68,
+   SVGA3D_DEVCAP_SURFACEFMT_YUY2                   = 69,
+
+   /*
+    * Don't add new caps into the previous section; the values in this
+    * enumeration must not change. You can put new values right before
+    * SVGA3D_DEVCAP_MAX.
+    */
+   SVGA3D_DEVCAP_MAX                                  /* This must be the last index. */
+} SVGA3dDevCapIndex;
+
+typedef union {
+   Bool   b;
+   uint32 u;
+   int32  i;
+   float  f;
+} SVGA3dDevCapResult;
+
+#endif /* _SVGA3D_REG_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_escape.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_escape.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_escape.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_escape.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,89 @@
+/**********************************************************
+ * Copyright 2007-2009 VMware, Inc.  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, 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_escape.h --
+ *
+ *    Definitions for our own (vendor-specific) SVGA Escape commands.
+ */
+
+#ifndef _SVGA_ESCAPE_H_
+#define _SVGA_ESCAPE_H_
+
+
+/*
+ * Namespace IDs for the escape command
+ */
+
+#define SVGA_ESCAPE_NSID_VMWARE 0x00000000
+#define SVGA_ESCAPE_NSID_DEVEL  0xFFFFFFFF
+
+
+/*
+ * Within SVGA_ESCAPE_NSID_VMWARE, we multiplex commands according to
+ * the first DWORD of escape data (after the nsID and size). As a
+ * guideline we're using the high word and low word as a major and
+ * minor command number, respectively.
+ *
+ * Major command number allocation:
+ *
+ *   0000: Reserved
+ *   0001: SVGA_ESCAPE_VMWARE_LOG (svga_binary_logger.h)
+ *   0002: SVGA_ESCAPE_VMWARE_VIDEO (svga_overlay.h)
+ *   0003: SVGA_ESCAPE_VMWARE_HINT (svga_escape.h)
+ */
+
+#define SVGA_ESCAPE_VMWARE_MAJOR_MASK  0xFFFF0000
+
+
+/*
+ * SVGA Hint commands.
+ *
+ * These escapes let the SVGA driver provide optional information to
+ * he host about the state of the guest or guest applications. The
+ * host can use these hints to make user interface or performance
+ * decisions.
+ *
+ * Notes:
+ *
+ *   - SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN is deprecated for guests
+ *     that use the SVGA Screen Object extension. Instead of sending
+ *     this escape, use the SVGA_SCREEN_FULLSCREEN_HINT flag on your
+ *     Screen Object.
+ */
+
+#define SVGA_ESCAPE_VMWARE_HINT               0x00030000
+#define SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN    0x00030001  // Deprecated
+
+typedef
+struct {
+   uint32 command;
+   uint32 fullscreen;
+   struct {
+      int32 x, y;
+   } monitorPosition;
+} SVGAEscapeHintFullscreen;
+
+#endif /* _SVGA_ESCAPE_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_overlay.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_overlay.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_overlay.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_overlay.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,201 @@
+/**********************************************************
+ * Copyright 2007-2009 VMware, Inc.  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, 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_overlay.h --
+ *
+ *    Definitions for video-overlay support.
+ */
+
+#ifndef _SVGA_OVERLAY_H_
+#define _SVGA_OVERLAY_H_
+
+#include "svga_reg.h"
+
+/*
+ * Video formats we support
+ */
+
+#define VMWARE_FOURCC_YV12 0x32315659 // 'Y' 'V' '1' '2'
+#define VMWARE_FOURCC_YUY2 0x32595559 // 'Y' 'U' 'Y' '2'
+#define VMWARE_FOURCC_UYVY 0x59565955 // 'U' 'Y' 'V' 'Y'
+
+typedef enum {
+   SVGA_OVERLAY_FORMAT_INVALID = 0,
+   SVGA_OVERLAY_FORMAT_YV12 = VMWARE_FOURCC_YV12,
+   SVGA_OVERLAY_FORMAT_YUY2 = VMWARE_FOURCC_YUY2,
+   SVGA_OVERLAY_FORMAT_UYVY = VMWARE_FOURCC_UYVY,
+} SVGAOverlayFormat;
+
+#define SVGA_VIDEO_COLORKEY_MASK             0x00ffffff
+
+#define SVGA_ESCAPE_VMWARE_VIDEO             0x00020000
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS    0x00020001
+        /* FIFO escape layout:
+         * Type, Stream Id, (Register Id, Value) pairs */
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_FLUSH       0x00020002
+        /* FIFO escape layout:
+         * Type, Stream Id */
+
+typedef
+struct SVGAEscapeVideoSetRegs {
+   struct {
+      uint32 cmdType;
+      uint32 streamId;
+   } header;
+
+   // May include zero or more items.
+   struct {
+      uint32 registerId;
+      uint32 value;
+   } items[1];
+} SVGAEscapeVideoSetRegs;
+
+typedef
+struct SVGAEscapeVideoFlush {
+   uint32 cmdType;
+   uint32 streamId;
+} SVGAEscapeVideoFlush;
+
+
+/*
+ * Struct definitions for the video overlay commands built on
+ * SVGAFifoCmdEscape.
+ */
+typedef
+struct {
+   uint32 command;
+   uint32 overlay;
+} SVGAFifoEscapeCmdVideoBase;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+} SVGAFifoEscapeCmdVideoFlush;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+   struct {
+      uint32 regId;
+      uint32 value;
+   } items[1];
+} SVGAFifoEscapeCmdVideoSetRegs;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+   struct {
+      uint32 regId;
+      uint32 value;
+   } items[SVGA_VIDEO_NUM_REGS];
+} SVGAFifoEscapeCmdVideoSetAllRegs;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMwareVideoGetAttributes --
+ *
+ *      Computes the size, pitches and offsets for YUV frames.
+ *
+ * Results:
+ *      TRUE on success; otherwise FALSE on failure.
+ *
+ * Side effects:
+ *      Pitches and offsets for the given YUV frame are put in 'pitches'
+ *      and 'offsets' respectively. They are both optional though.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline bool
+VMwareVideoGetAttributes(const SVGAOverlayFormat format,    // IN
+                         uint32 *width,                     // IN / OUT
+                         uint32 *height,                    // IN / OUT
+                         uint32 *size,                      // OUT
+                         uint32 *pitches,                   // OUT (optional)
+                         uint32 *offsets)                   // OUT (optional)
+{
+    int tmp;
+
+    *width = (*width + 1) & ~1;
+
+    if (offsets) {
+        offsets[0] = 0;
+    }
+
+    switch (format) {
+    case VMWARE_FOURCC_YV12:
+       *height = (*height + 1) & ~1;
+       *size = (*width + 3) & ~3;
+
+       if (pitches) {
+          pitches[0] = *size;
+       }
+
+       *size *= *height;
+
+       if (offsets) {
+          offsets[1] = *size;
+       }
+
+       tmp = ((*width >> 1) + 3) & ~3;
+
+       if (pitches) {
+          pitches[1] = pitches[2] = tmp;
+       }
+
+       tmp *= (*height >> 1);
+       *size += tmp;
+
+       if (offsets) {
+          offsets[2] = *size;
+       }
+
+       *size += tmp;
+       break;
+
+    case VMWARE_FOURCC_YUY2:
+    case VMWARE_FOURCC_UYVY:
+       *size = *width * 2;
+
+       if (pitches) {
+          pitches[0] = *size;
+       }
+
+       *size *= *height;
+       break;
+
+    default:
+       return false;
+    }
+
+    return true;
+}
+
+#endif // _SVGA_OVERLAY_H_
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1346 @@
+/**********************************************************
+ * Copyright 1998-2009 VMware, Inc.  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, 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ *    Virtual hardware definitions for the VMware SVGA II device.
+ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+/*
+ * PCI device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE            0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2      0x0405
+
+/*
+ * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned
+ * cursor bypass mode. This is still supported, but no new guest
+ * drivers should use it.
+ */
+#define SVGA_CURSOR_ON_HIDE            0x0   /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW            0x1   /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB  0x2   /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB   0x3   /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * The maximum framebuffer size that can traced for e.g. guests in VESA mode.
+ * The changeMap in the monitor is proportional to this number. Therefore, we'd
+ * like to keep it as small as possible to reduce monitor overhead (using
+ * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over
+ * 4k!).
+ *
+ * NB: For compatibility reasons, this value must be greater than 0xff0000.
+ *     See bug 335072.
+ */
+#define SVGA_FB_MAX_TRACEABLE_SIZE      0x1000000
+
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH      8
+#define SVGA_MAX_PSEUDOCOLORS           (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+#define SVGA_NUM_PALETTE_REGS           (3 * SVGA_MAX_PSEUDOCOLORS)
+
+#define SVGA_MAGIC         0x900000UL
+#define SVGA_MAKE_ID(ver)  (SVGA_MAGIC << 8 | (ver))
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2     2
+#define SVGA_ID_2          SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+   PALETTE_BASE has moved */
+#define SVGA_VERSION_1     1
+#define SVGA_ID_1          SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0     0
+#define SVGA_ID_0          SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */
+#define SVGA_ID_INVALID    0xFFFFFFFF
+
+/* Port offsets, relative to BAR0 */
+#define SVGA_INDEX_PORT         0x0
+#define SVGA_VALUE_PORT         0x1
+#define SVGA_BIOS_PORT          0x2
+#define SVGA_IRQSTATUS_PORT     0x8
+
+/*
+ * Interrupt source flags for IRQSTATUS_PORT and IRQMASK.
+ *
+ * Interrupts are only supported when the
+ * SVGA_CAP_IRQMASK capability is present.
+ */
+#define SVGA_IRQFLAG_ANY_FENCE            0x1    /* Any fence was passed */
+#define SVGA_IRQFLAG_FIFO_PROGRESS        0x2    /* Made forward progress in the FIFO */
+#define SVGA_IRQFLAG_FENCE_GOAL           0x4    /* SVGA_FIFO_FENCE_GOAL reached */
+
+/*
+ * Registers
+ */
+
+enum {
+   SVGA_REG_ID = 0,
+   SVGA_REG_ENABLE = 1,
+   SVGA_REG_WIDTH = 2,
+   SVGA_REG_HEIGHT = 3,
+   SVGA_REG_MAX_WIDTH = 4,
+   SVGA_REG_MAX_HEIGHT = 5,
+   SVGA_REG_DEPTH = 6,
+   SVGA_REG_BITS_PER_PIXEL = 7,       /* Current bpp in the guest */
+   SVGA_REG_PSEUDOCOLOR = 8,
+   SVGA_REG_RED_MASK = 9,
+   SVGA_REG_GREEN_MASK = 10,
+   SVGA_REG_BLUE_MASK = 11,
+   SVGA_REG_BYTES_PER_LINE = 12,
+   SVGA_REG_FB_START = 13,            /* (Deprecated) */
+   SVGA_REG_FB_OFFSET = 14,
+   SVGA_REG_VRAM_SIZE = 15,
+   SVGA_REG_FB_SIZE = 16,
+
+   /* ID 0 implementation only had the above registers, then the palette */
+
+   SVGA_REG_CAPABILITIES = 17,
+   SVGA_REG_MEM_START = 18,           /* (Deprecated) */
+   SVGA_REG_MEM_SIZE = 19,
+   SVGA_REG_CONFIG_DONE = 20,         /* Set when memory area configured */
+   SVGA_REG_SYNC = 21,                /* See "FIFO Synchronization Registers" */
+   SVGA_REG_BUSY = 22,                /* See "FIFO Synchronization Registers" */
+   SVGA_REG_GUEST_ID = 23,            /* Set guest OS identifier */
+   SVGA_REG_CURSOR_ID = 24,           /* (Deprecated) */
+   SVGA_REG_CURSOR_X = 25,            /* (Deprecated) */
+   SVGA_REG_CURSOR_Y = 26,            /* (Deprecated) */
+   SVGA_REG_CURSOR_ON = 27,           /* (Deprecated) */
+   SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */
+   SVGA_REG_SCRATCH_SIZE = 29,        /* Number of scratch registers */
+   SVGA_REG_MEM_REGS = 30,            /* Number of FIFO registers */
+   SVGA_REG_NUM_DISPLAYS = 31,        /* (Deprecated) */
+   SVGA_REG_PITCHLOCK = 32,           /* Fixed pitch for all modes */
+   SVGA_REG_IRQMASK = 33,             /* Interrupt mask */
+
+   /* Legacy multi-monitor support */
+   SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */
+   SVGA_REG_DISPLAY_ID = 35,        /* Display ID for the following display attributes */
+   SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */
+   SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */
+   SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */
+   SVGA_REG_DISPLAY_WIDTH = 39,     /* The display's width */
+   SVGA_REG_DISPLAY_HEIGHT = 40,    /* The display's height */
+
+   /* See "Guest memory regions" below. */
+   SVGA_REG_GMR_ID = 41,
+   SVGA_REG_GMR_DESCRIPTOR = 42,
+   SVGA_REG_GMR_MAX_IDS = 43,
+   SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44,
+
+   SVGA_REG_TRACES = 45,            /* Enable trace-based updates even when FIFO is on */
+   SVGA_REG_TOP = 46,               /* Must be 1 more than the last register */
+
+   SVGA_PALETTE_BASE = 1024,        /* Base of SVGA color map */
+   /* Next 768 (== 256*3) registers exist for colormap */
+
+   SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
+                                    /* Base of scratch registers */
+   /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
+      First 4 are reserved for VESA BIOS Extension; any remaining are for
+      the use of the current SVGA driver. */
+};
+
+
+/*
+ * Guest memory regions (GMRs):
+ *
+ * This is a new memory mapping feature available in SVGA devices
+ * which have the SVGA_CAP_GMR bit set. Previously, there were two
+ * fixed memory regions available with which to share data between the
+ * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs
+ * are our name for an extensible way of providing arbitrary DMA
+ * buffers for use between the driver and the SVGA device. They are a
+ * new alternative to framebuffer memory, usable for both 2D and 3D
+ * graphics operations.
+ *
+ * Since GMR mapping must be done synchronously with guest CPU
+ * execution, we use a new pair of SVGA registers:
+ *
+ *   SVGA_REG_GMR_ID --
+ *
+ *     Read/write.
+ *     This register holds the 32-bit ID (a small positive integer)
+ *     of a GMR to create, delete, or redefine. Writing this register
+ *     has no side-effects.
+ *
+ *   SVGA_REG_GMR_DESCRIPTOR --
+ *
+ *     Write-only.
+ *     Writing this register will create, delete, or redefine the GMR
+ *     specified by the above ID register. If this register is zero,
+ *     the GMR is deleted. Any pointers into this GMR (including those
+ *     currently being processed by FIFO commands) will be
+ *     synchronously invalidated.
+ *
+ *     If this register is nonzero, it must be the physical page
+ *     number (PPN) of a data structure which describes the physical
+ *     layout of the memory region this GMR should describe. The
+ *     descriptor structure will be read synchronously by the SVGA
+ *     device when this register is written. The descriptor need not
+ *     remain allocated for the lifetime of the GMR.
+ *
+ *     The guest driver should write SVGA_REG_GMR_ID first, then
+ *     SVGA_REG_GMR_DESCRIPTOR.
+ *
+ *   SVGA_REG_GMR_MAX_IDS --
+ *
+ *     Read-only.
+ *     The SVGA device may choose to support a maximum number of
+ *     user-defined GMR IDs. This register holds the number of supported
+ *     IDs. (The maximum supported ID plus 1)
+ *
+ *   SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH --
+ *
+ *     Read-only.
+ *     The SVGA device may choose to put a limit on the total number
+ *     of SVGAGuestMemDescriptor structures it will read when defining
+ *     a single GMR.
+ *
+ * The descriptor structure is an array of SVGAGuestMemDescriptor
+ * structures. Each structure may do one of three things:
+ *
+ *   - Terminate the GMR descriptor list.
+ *     (ppn==0, numPages==0)
+ *
+ *   - Add a PPN or range of PPNs to the GMR's virtual address space.
+ *     (ppn != 0, numPages != 0)
+ *
+ *   - Provide the PPN of the next SVGAGuestMemDescriptor, in order to
+ *     support multi-page GMR descriptor tables without forcing the
+ *     driver to allocate physically contiguous memory.
+ *     (ppn != 0, numPages == 0)
+ *
+ * Note that each physical page of SVGAGuestMemDescriptor structures
+ * can describe at least 2MB of guest memory. If the driver needs to
+ * use more than one page of descriptor structures, it must use one of
+ * its SVGAGuestMemDescriptors to point to an additional page.  The
+ * device will never automatically cross a page boundary.
+ *
+ * Once the driver has described a GMR, it is immediately available
+ * for use via any FIFO command that uses an SVGAGuestPtr structure.
+ * These pointers include a GMR identifier plus an offset into that
+ * GMR.
+ *
+ * The driver must check the SVGA_CAP_GMR bit before using the GMR
+ * registers.
+ */
+
+/*
+ * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer
+ * memory as well.  In the future, these IDs could even be used to
+ * allow legacy memory regions to be redefined by the guest as GMRs.
+ *
+ * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA
+ * is being phased out. Please try to use user-defined GMRs whenever
+ * possible.
+ */
+#define SVGA_GMR_NULL         ((uint32) -1)
+#define SVGA_GMR_FRAMEBUFFER  ((uint32) -2)  // Guest Framebuffer (GFB)
+
+typedef
+struct SVGAGuestMemDescriptor {
+   uint32 ppn;
+   uint32 numPages;
+} SVGAGuestMemDescriptor;
+
+typedef
+struct SVGAGuestPtr {
+   uint32 gmrId;
+   uint32 offset;
+} SVGAGuestPtr;
+
+
+/*
+ * SVGAGMRImageFormat --
+ *
+ *    This is a packed representation of the source 2D image format
+ *    for a GMR-to-screen blit. Currently it is defined as an encoding
+ *    of the screen's color depth and bits-per-pixel, however, 16 bits
+ *    are reserved for future use to identify other encodings (such as
+ *    RGBA or higher-precision images).
+ *
+ *    Currently supported formats:
+ *
+ *       bpp depth  Format Name
+ *       --- -----  -----------
+ *        32    24  32-bit BGRX
+ *        24    24  24-bit BGR
+ *        16    16  RGB 5-6-5
+ *        16    15  RGB 5-5-5
+ *
+ */
+
+typedef
+struct SVGAGMRImageFormat {
+   union {
+      struct {
+         uint32 bitsPerPixel : 8;
+         uint32 colorDepth   : 8;
+         uint32 reserved     : 16;  // Must be zero
+      };
+
+      uint32 value;
+   };
+} SVGAGMRImageFormat;
+
+/*
+ * SVGAColorBGRX --
+ *
+ *    A 24-bit color format (BGRX), which does not depend on the
+ *    format of the legacy guest framebuffer (GFB) or the current
+ *    GMRFB state.
+ */
+
+typedef
+struct SVGAColorBGRX {
+   union {
+      struct {
+         uint32 b : 8;
+         uint32 g : 8;
+         uint32 r : 8;
+         uint32 x : 8;  // Unused
+      };
+
+      uint32 value;
+   };
+} SVGAColorBGRX;
+
+
+/*
+ * SVGASignedRect --
+ * SVGASignedPoint --
+ *
+ *    Signed rectangle and point primitives. These are used by the new
+ *    2D primitives for drawing to Screen Objects, which can occupy a
+ *    signed virtual coordinate space.
+ *
+ *    SVGASignedRect specifies a half-open interval: the (left, top)
+ *    pixel is part of the rectangle, but the (right, bottom) pixel is
+ *    not.
+ */
+
+typedef
+struct SVGASignedRect {
+   int32  left;
+   int32  top;
+   int32  right;
+   int32  bottom;
+} SVGASignedRect;
+
+typedef
+struct SVGASignedPoint {
+   int32  x;
+   int32  y;
+} SVGASignedPoint;
+
+
+/*
+ *  Capabilities
+ *
+ *  Note the holes in the bitfield. Missing bits have been deprecated,
+ *  and must not be reused. Those capabilities will never be reported
+ *  by new versions of the SVGA device.
+ */
+
+#define SVGA_CAP_NONE               0x00000000
+#define SVGA_CAP_RECT_COPY          0x00000002
+#define SVGA_CAP_CURSOR             0x00000020
+#define SVGA_CAP_CURSOR_BYPASS      0x00000040   // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_CURSOR_BYPASS_2    0x00000080   // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_8BIT_EMULATION     0x00000100
+#define SVGA_CAP_ALPHA_CURSOR       0x00000200
+#define SVGA_CAP_3D                 0x00004000
+#define SVGA_CAP_EXTENDED_FIFO      0x00008000
+#define SVGA_CAP_MULTIMON           0x00010000   // Legacy multi-monitor support
+#define SVGA_CAP_PITCHLOCK          0x00020000
+#define SVGA_CAP_IRQMASK            0x00040000
+#define SVGA_CAP_DISPLAY_TOPOLOGY   0x00080000   // Legacy multi-monitor support
+#define SVGA_CAP_GMR                0x00100000
+#define SVGA_CAP_TRACES             0x00200000
+
+
+/*
+ * FIFO register indices.
+ *
+ * The FIFO is a chunk of device memory mapped into guest physmem.  It
+ * is always treated as 32-bit words.
+ *
+ * The guest driver gets to decide how to partition it between
+ * - FIFO registers (there are always at least 4, specifying where the
+ *   following data area is and how much data it contains; there may be
+ *   more registers following these, depending on the FIFO protocol
+ *   version in use)
+ * - FIFO data, written by the guest and slurped out by the VMX.
+ * These indices are 32-bit word offsets into the FIFO.
+ */
+
+enum {
+   /*
+    * Block 1 (basic registers): The originally defined FIFO registers.
+    * These exist and are valid for all versions of the FIFO protocol.
+    */
+
+   SVGA_FIFO_MIN = 0,
+   SVGA_FIFO_MAX,       /* The distance from MIN to MAX must be at least 10K */
+   SVGA_FIFO_NEXT_CMD,
+   SVGA_FIFO_STOP,
+
+   /*
+    * Block 2 (extended registers): Mandatory registers for the extended
+    * FIFO.  These exist if the SVGA caps register includes
+    * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their
+    * associated capability bit is enabled.
+    *
+    * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied
+    * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE.
+    * This means that the guest has to test individually (in most cases
+    * using FIFO caps) for the presence of registers after this; the VMX
+    * can define "extended FIFO" to mean whatever it wants, and currently
+    * won't enable it unless there's room for that set and much more.
+    */
+
+   SVGA_FIFO_CAPABILITIES = 4,
+   SVGA_FIFO_FLAGS,
+   // Valid with SVGA_FIFO_CAP_FENCE:
+   SVGA_FIFO_FENCE,
+
+   /*
+    * Block 3a (optional extended registers): Additional registers for the
+    * extended FIFO, whose presence isn't actually implied by
+    * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to
+    * leave room for them.
+    *
+    * These in block 3a, the VMX currently considers mandatory for the
+    * extended FIFO.
+    */
+
+   // Valid if exists (i.e. if extended FIFO enabled):
+   SVGA_FIFO_3D_HWVERSION,       /* See SVGA3dHardwareVersion in svga3d_reg.h */
+   // Valid with SVGA_FIFO_CAP_PITCHLOCK:
+   SVGA_FIFO_PITCHLOCK,
+
+   // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3:
+   SVGA_FIFO_CURSOR_ON,          /* Cursor bypass 3 show/hide register */
+   SVGA_FIFO_CURSOR_X,           /* Cursor bypass 3 x register */
+   SVGA_FIFO_CURSOR_Y,           /* Cursor bypass 3 y register */
+   SVGA_FIFO_CURSOR_COUNT,       /* Incremented when any of the other 3 change */
+   SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */
+
+   // Valid with SVGA_FIFO_CAP_RESERVE:
+   SVGA_FIFO_RESERVED,           /* Bytes past NEXT_CMD with real contents */
+
+   /*
+    * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT:
+    *
+    * By default this is SVGA_ID_INVALID, to indicate that the cursor
+    * coordinates are specified relative to the virtual root. If this
+    * is set to a specific screen ID, cursor position is reinterpreted
+    * as a signed offset relative to that screen's origin. This is the
+    * only way to place the cursor on a non-rooted screen.
+    */
+   SVGA_FIFO_CURSOR_SCREEN_ID,
+
+   /*
+    * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new
+    * registers, but this must be done carefully and with judicious use of
+    * capability bits, since comparisons based on SVGA_FIFO_MIN aren't
+    * enough to tell you whether the register exists: we've shipped drivers
+    * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of
+    * the earlier ones.  The actual order of introduction was:
+    * - PITCHLOCK
+    * - 3D_CAPS
+    * - CURSOR_* (cursor bypass 3)
+    * - RESERVED
+    * So, code that wants to know whether it can use any of the
+    * aforementioned registers, or anything else added after PITCHLOCK and
+    * before 3D_CAPS, needs to reason about something other than
+    * SVGA_FIFO_MIN.
+    */
+
+   /*
+    * 3D caps block space; valid with 3D hardware version >=
+    * SVGA3D_HWVERSION_WS6_B1.
+    */
+   SVGA_FIFO_3D_CAPS      = 32,
+   SVGA_FIFO_3D_CAPS_LAST = 32 + 255,
+
+   /*
+    * End of VMX's current definition of "extended-FIFO registers".
+    * Registers before here are always enabled/disabled as a block; either
+    * the extended FIFO is enabled and includes all preceding registers, or
+    * it's disabled entirely.
+    *
+    * Block 3b (truly optional extended registers): Additional registers for
+    * the extended FIFO, which the VMX already knows how to enable and
+    * disable with correct granularity.
+    *
+    * Registers after here exist if and only if the guest SVGA driver
+    * sets SVGA_FIFO_MIN high enough to leave room for them.
+    */
+
+   // Valid if register exists:
+   SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */
+   SVGA_FIFO_FENCE_GOAL,         /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */
+   SVGA_FIFO_BUSY,               /* See "FIFO Synchronization Registers" */
+
+   /*
+    * Always keep this last.  This defines the maximum number of
+    * registers we know about.  At power-on, this value is placed in
+    * the SVGA_REG_MEM_REGS register, and we expect the guest driver
+    * to allocate this much space in FIFO memory for registers.
+    */
+    SVGA_FIFO_NUM_REGS
+};
+
+
+/*
+ * Definition of registers included in extended FIFO support.
+ *
+ * The guest SVGA driver gets to allocate the FIFO between registers
+ * and data.  It must always allocate at least 4 registers, but old
+ * drivers stopped there.
+ *
+ * The VMX will enable extended FIFO support if and only if the guest
+ * left enough room for all registers defined as part of the mandatory
+ * set for the extended FIFO.
+ *
+ * Note that the guest drivers typically allocate the FIFO only at
+ * initialization time, not at mode switches, so it's likely that the
+ * number of FIFO registers won't change without a reboot.
+ *
+ * All registers less than this value are guaranteed to be present if
+ * svgaUser->fifo.extended is set. Any later registers must be tested
+ * individually for compatibility at each use (in the VMX).
+ *
+ * This value is used only by the VMX, so it can change without
+ * affecting driver compatibility; keep it that way?
+ */
+#define SVGA_FIFO_EXTENDED_MANDATORY_REGS  (SVGA_FIFO_3D_CAPS_LAST + 1)
+
+
+/*
+ * FIFO Synchronization Registers
+ *
+ *  This explains the relationship between the various FIFO
+ *  sync-related registers in IOSpace and in FIFO space.
+ *
+ *  SVGA_REG_SYNC --
+ *
+ *       The SYNC register can be used in two different ways by the guest:
+ *
+ *         1. If the guest wishes to fully sync (drain) the FIFO,
+ *            it will write once to SYNC then poll on the BUSY
+ *            register. The FIFO is sync'ed once BUSY is zero.
+ *
+ *         2. If the guest wants to asynchronously wake up the host,
+ *            it will write once to SYNC without polling on BUSY.
+ *            Ideally it will do this after some new commands have
+ *            been placed in the FIFO, and after reading a zero
+ *            from SVGA_FIFO_BUSY.
+ *
+ *       (1) is the original behaviour that SYNC was designed to
+ *       support.  Originally, a write to SYNC would implicitly
+ *       trigger a read from BUSY. This causes us to synchronously
+ *       process the FIFO.
+ *
+ *       This behaviour has since been changed so that writing SYNC
+ *       will *not* implicitly cause a read from BUSY. Instead, it
+ *       makes a channel call which asynchronously wakes up the MKS
+ *       thread.
+ *
+ *       New guests can use this new behaviour to implement (2)
+ *       efficiently. This lets guests get the host's attention
+ *       without waiting for the MKS to poll, which gives us much
+ *       better CPU utilization on SMP hosts and on UP hosts while
+ *       we're blocked on the host GPU.
+ *
+ *       Old guests shouldn't notice the behaviour change. SYNC was
+ *       never guaranteed to process the entire FIFO, since it was
+ *       bounded to a particular number of CPU cycles. Old guests will
+ *       still loop on the BUSY register until the FIFO is empty.
+ *
+ *       Writing to SYNC currently has the following side-effects:
+ *
+ *         - Sets SVGA_REG_BUSY to TRUE (in the monitor)
+ *         - Asynchronously wakes up the MKS thread for FIFO processing
+ *         - The value written to SYNC is recorded as a "reason", for
+ *           stats purposes.
+ *
+ *       If SVGA_FIFO_BUSY is available, drivers are advised to only
+ *       write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set
+ *       SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will
+ *       eventually set SVGA_FIFO_BUSY on its own, but this approach
+ *       lets the driver avoid sending multiple asynchronous wakeup
+ *       messages to the MKS thread.
+ *
+ *  SVGA_REG_BUSY --
+ *
+ *       This register is set to TRUE when SVGA_REG_SYNC is written,
+ *       and it reads as FALSE when the FIFO has been completely
+ *       drained.
+ *
+ *       Every read from this register causes us to synchronously
+ *       process FIFO commands. There is no guarantee as to how many
+ *       commands each read will process.
+ *
+ *       CPU time spent processing FIFO commands will be billed to
+ *       the guest.
+ *
+ *       New drivers should avoid using this register unless they
+ *       need to guarantee that the FIFO is completely drained. It
+ *       is overkill for performing a sync-to-fence. Older drivers
+ *       will use this register for any type of synchronization.
+ *
+ *  SVGA_FIFO_BUSY --
+ *
+ *       This register is a fast way for the guest driver to check
+ *       whether the FIFO is already being processed. It reads and
+ *       writes at normal RAM speeds, with no monitor intervention.
+ *
+ *       If this register reads as TRUE, the host is guaranteeing that
+ *       any new commands written into the FIFO will be noticed before
+ *       the MKS goes back to sleep.
+ *
+ *       If this register reads as FALSE, no such guarantee can be
+ *       made.
+ *
+ *       The guest should use this register to quickly determine
+ *       whether or not it needs to wake up the host. If the guest
+ *       just wrote a command or group of commands that it would like
+ *       the host to begin processing, it should:
+ *
+ *         1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further
+ *            action is necessary.
+ *
+ *         2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest
+ *            code that we've already sent a SYNC to the host and we
+ *            don't need to send a duplicate.
+ *
+ *         3. Write a reason to SVGA_REG_SYNC. This will send an
+ *            asynchronous wakeup to the MKS thread.
+ */
+
+
+/*
+ * FIFO Capabilities
+ *
+ *      Fence -- Fence register and command are supported
+ *      Accel Front -- Front buffer only commands are supported
+ *      Pitch Lock -- Pitch lock register is supported
+ *      Video -- SVGA Video overlay units are supported
+ *      Escape -- Escape command is supported
+ *
+ * XXX: Add longer descriptions for each capability, including a list
+ *      of the new features that each capability provides.
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT --
+ *
+ *    Provides dynamic multi-screen rendering, for improved Unity and
+ *    multi-monitor modes. With Screen Object, the guest can
+ *    dynamically create and destroy 'screens', which can represent
+ *    Unity windows or virtual monitors. Screen Object also provides
+ *    strong guarantees that DMA operations happen only when
+ *    guest-initiated. Screen Object deprecates the BAR1 guest
+ *    framebuffer (GFB) and all commands that work only with the GFB.
+ *
+ *    New registers:
+ *       FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID
+ *
+ *    New 2D commands:
+ *       DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN,
+ *       BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY
+ *
+ *    New 3D commands:
+ *       BLIT_SURFACE_TO_SCREEN
+ *
+ *    New guarantees:
+ *
+ *       - The host will not read or write guest memory, including the GFB,
+ *         except when explicitly initiated by a DMA command.
+ *
+ *       - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK,
+ *         is guaranteed to complete before any subsequent FENCEs.
+ *
+ *       - All legacy commands which affect a Screen (UPDATE, PRESENT,
+ *         PRESENT_READBACK) as well as new Screen blit commands will
+ *         all behave consistently as blits, and memory will be read
+ *         or written in FIFO order.
+ *
+ *         For example, if you PRESENT from one SVGA3D surface to multiple
+ *         places on the screen, the data copied will always be from the
+ *         SVGA3D surface at the time the PRESENT was issued in the FIFO.
+ *         This was not necessarily true on devices without Screen Object.
+ *
+ *         This means that on devices that support Screen Object, the
+ *         PRESENT_READBACK command should not be necessary unless you
+ *         actually want to read back the results of 3D rendering into
+ *         system memory. (And for that, the BLIT_SCREEN_TO_GMRFB
+ *         command provides a strict superset of functionality.)
+ *
+ *       - When a screen is resized, either using Screen Object commands or
+ *         legacy multimon registers, its contents are preserved.
+ */
+
+#define SVGA_FIFO_CAP_NONE                  0
+#define SVGA_FIFO_CAP_FENCE             (1<<0)
+#define SVGA_FIFO_CAP_ACCELFRONT        (1<<1)
+#define SVGA_FIFO_CAP_PITCHLOCK         (1<<2)
+#define SVGA_FIFO_CAP_VIDEO             (1<<3)
+#define SVGA_FIFO_CAP_CURSOR_BYPASS_3   (1<<4)
+#define SVGA_FIFO_CAP_ESCAPE            (1<<5)
+#define SVGA_FIFO_CAP_RESERVE           (1<<6)
+#define SVGA_FIFO_CAP_SCREEN_OBJECT     (1<<7)
+
+
+/*
+ * FIFO Flags
+ *
+ *      Accel Front -- Driver should use front buffer only commands
+ */
+
+#define SVGA_FIFO_FLAG_NONE                 0
+#define SVGA_FIFO_FLAG_ACCELFRONT       (1<<0)
+#define SVGA_FIFO_FLAG_RESERVED        (1<<31) // Internal use only
+
+/*
+ * FIFO reservation sentinel value
+ */
+
+#define SVGA_FIFO_RESERVED_UNKNOWN      0xffffffff
+
+
+/*
+ * Video overlay support
+ */
+
+#define SVGA_NUM_OVERLAY_UNITS 32
+
+
+/*
+ * Video capabilities that the guest is currently using
+ */
+
+#define SVGA_VIDEO_FLAG_COLORKEY        0x0001
+
+
+/*
+ * Offsets for the video overlay registers
+ */
+
+enum {
+   SVGA_VIDEO_ENABLED = 0,
+   SVGA_VIDEO_FLAGS,
+   SVGA_VIDEO_DATA_OFFSET,
+   SVGA_VIDEO_FORMAT,
+   SVGA_VIDEO_COLORKEY,
+   SVGA_VIDEO_SIZE,          // Deprecated
+   SVGA_VIDEO_WIDTH,
+   SVGA_VIDEO_HEIGHT,
+   SVGA_VIDEO_SRC_X,
+   SVGA_VIDEO_SRC_Y,
+   SVGA_VIDEO_SRC_WIDTH,
+   SVGA_VIDEO_SRC_HEIGHT,
+   SVGA_VIDEO_DST_X,         // Signed int32
+   SVGA_VIDEO_DST_Y,         // Signed int32
+   SVGA_VIDEO_DST_WIDTH,
+   SVGA_VIDEO_DST_HEIGHT,
+   SVGA_VIDEO_PITCH_1,
+   SVGA_VIDEO_PITCH_2,
+   SVGA_VIDEO_PITCH_3,
+   SVGA_VIDEO_DATA_GMRID,    // Optional, defaults to SVGA_GMR_FRAMEBUFFER
+   SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID)
+   SVGA_VIDEO_NUM_REGS
+};
+
+
+/*
+ * SVGA Overlay Units
+ *
+ *      width and height relate to the entire source video frame.
+ *      srcX, srcY, srcWidth and srcHeight represent subset of the source
+ *      video frame to be displayed.
+ */
+
+typedef struct SVGAOverlayUnit {
+   uint32 enabled;
+   uint32 flags;
+   uint32 dataOffset;
+   uint32 format;
+   uint32 colorKey;
+   uint32 size;
+   uint32 width;
+   uint32 height;
+   uint32 srcX;
+   uint32 srcY;
+   uint32 srcWidth;
+   uint32 srcHeight;
+   int32  dstX;
+   int32  dstY;
+   uint32 dstWidth;
+   uint32 dstHeight;
+   uint32 pitches[3];
+   uint32 dataGMRId;
+   uint32 dstScreenId;
+} SVGAOverlayUnit;
+
+
+/*
+ * SVGAScreenObject --
+ *
+ *    This is a new way to represent a guest's multi-monitor screen or
+ *    Unity window. Screen objects are only supported if the
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set.
+ *
+ *    If Screen Objects are supported, they can be used to fully
+ *    replace the functionality provided by the framebuffer registers
+ *    (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY.
+ *
+ *    The screen object is a struct with guaranteed binary
+ *    compatibility. New flags can be added, and the struct may grow,
+ *    but existing fields must retain their meaning.
+ *
+ */
+
+#define SVGA_SCREEN_HAS_ROOT    (1 << 0)  // Screen is present in the virtual coord space
+#define SVGA_SCREEN_IS_PRIMARY  (1 << 1)  // Guest considers this screen to be 'primary'
+#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2)   // Guest is running a fullscreen app here
+
+typedef
+struct SVGAScreenObject {
+   uint32 structSize;   // sizeof(SVGAScreenObject)
+   uint32 id;
+   uint32 flags;
+   struct {
+      uint32 width;
+      uint32 height;
+   } size;
+   struct {
+      int32 x;
+      int32 y;
+   } root;              // Only used if SVGA_SCREEN_HAS_ROOT is set.
+} SVGAScreenObject;
+
+
+/*
+ *  Commands in the command FIFO:
+ *
+ *  Command IDs defined below are used for the traditional 2D FIFO
+ *  communication (not all commands are available for all versions of the
+ *  SVGA FIFO protocol).
+ *
+ *  Note the holes in the command ID numbers: These commands have been
+ *  deprecated, and the old IDs must not be reused.
+ *
+ *  Command IDs from 1000 to 1999 are reserved for use by the SVGA3D
+ *  protocol.
+ *
+ *  Each command's parameters are described by the comments and
+ *  structs below.
+ */
+
+typedef enum {
+   SVGA_CMD_INVALID_CMD           = 0,
+   SVGA_CMD_UPDATE                = 1,
+   SVGA_CMD_RECT_COPY             = 3,
+   SVGA_CMD_DEFINE_CURSOR         = 19,
+   SVGA_CMD_DEFINE_ALPHA_CURSOR   = 22,
+   SVGA_CMD_UPDATE_VERBOSE        = 25,
+   SVGA_CMD_FRONT_ROP_FILL        = 29,
+   SVGA_CMD_FENCE                 = 30,
+   SVGA_CMD_ESCAPE                = 33,
+   SVGA_CMD_DEFINE_SCREEN         = 34,
+   SVGA_CMD_DESTROY_SCREEN        = 35,
+   SVGA_CMD_DEFINE_GMRFB          = 36,
+   SVGA_CMD_BLIT_GMRFB_TO_SCREEN  = 37,
+   SVGA_CMD_BLIT_SCREEN_TO_GMRFB  = 38,
+   SVGA_CMD_ANNOTATION_FILL       = 39,
+   SVGA_CMD_ANNOTATION_COPY       = 40,
+   SVGA_CMD_MAX
+} SVGAFifoCmdId;
+
+#define SVGA_CMD_MAX_ARGS           64
+
+
+/*
+ * SVGA_CMD_UPDATE --
+ *
+ *    This is a DMA transfer which copies from the Guest Framebuffer
+ *    (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which
+ *    intersect with the provided virtual rectangle.
+ *
+ *    This command does not support using arbitrary guest memory as a
+ *    data source- it only works with the pre-defined GFB memory.
+ *    This command also does not support signed virtual coordinates.
+ *    If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with
+ *    negative root x/y coordinates, the negative portion of those
+ *    screens will not be reachable by this command.
+ *
+ *    This command is not necessary when using framebuffer
+ *    traces. Traces are automatically enabled if the SVGA FIFO is
+ *    disabled, and you may explicitly enable/disable traces using
+ *    SVGA_REG_TRACES. With traces enabled, any write to the GFB will
+ *    automatically act as if a subsequent SVGA_CMD_UPDATE was issued.
+ *
+ *    Traces and SVGA_CMD_UPDATE are the only supported ways to render
+ *    pseudocolor screen updates. The newer Screen Object commands
+ *    only support true color formats.
+ *
+ * Availability:
+ *    Always available.
+ */
+
+typedef
+struct {
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+} SVGAFifoCmdUpdate;
+
+
+/*
+ * SVGA_CMD_RECT_COPY --
+ *
+ *    Perform a rectangular DMA transfer from one area of the GFB to
+ *    another, and copy the result to any screens which intersect it.
+ *
+ * Availability:
+ *    SVGA_CAP_RECT_COPY
+ */
+
+typedef
+struct {
+   uint32 srcX;
+   uint32 srcY;
+   uint32 destX;
+   uint32 destY;
+   uint32 width;
+   uint32 height;
+} SVGAFifoCmdRectCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_CURSOR --
+ *
+ *    Provide a new cursor image, as an AND/XOR mask.
+ *
+ *    The recommended way to position the cursor overlay is by using
+ *    the SVGA_FIFO_CURSOR_* registers, supported by the
+ *    SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ *    SVGA_CAP_CURSOR
+ */
+
+typedef
+struct {
+   uint32 id;             // Reserved, must be zero.
+   uint32 hotspotX;
+   uint32 hotspotY;
+   uint32 width;
+   uint32 height;
+   uint32 andMaskDepth;   // Value must be 1 or equal to BITS_PER_PIXEL
+   uint32 xorMaskDepth;   // Value must be 1 or equal to BITS_PER_PIXEL
+   /*
+    * Followed by scanline data for AND mask, then XOR mask.
+    * Each scanline is padded to a 32-bit boundary.
+   */
+} SVGAFifoCmdDefineCursor;
+
+
+/*
+ * SVGA_CMD_DEFINE_ALPHA_CURSOR --
+ *
+ *    Provide a new cursor image, in 32-bit BGRA format.
+ *
+ *    The recommended way to position the cursor overlay is by using
+ *    the SVGA_FIFO_CURSOR_* registers, supported by the
+ *    SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ *    SVGA_CAP_ALPHA_CURSOR
+ */
+
+typedef
+struct {
+   uint32 id;             // Reserved, must be zero.
+   uint32 hotspotX;
+   uint32 hotspotY;
+   uint32 width;
+   uint32 height;
+   /* Followed by scanline data */
+} SVGAFifoCmdDefineAlphaCursor;
+
+
+/*
+ * SVGA_CMD_UPDATE_VERBOSE --
+ *
+ *    Just like SVGA_CMD_UPDATE, but also provide a per-rectangle
+ *    'reason' value, an opaque cookie which is used by internal
+ *    debugging tools. Third party drivers should not use this
+ *    command.
+ *
+ * Availability:
+ *    SVGA_CAP_EXTENDED_FIFO
+ */
+
+typedef
+struct {
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+   uint32 reason;
+} SVGAFifoCmdUpdateVerbose;
+
+
+/*
+ * SVGA_CMD_FRONT_ROP_FILL --
+ *
+ *    This is a hint which tells the SVGA device that the driver has
+ *    just filled a rectangular region of the GFB with a solid
+ *    color. Instead of reading these pixels from the GFB, the device
+ *    can assume that they all equal 'color'. This is primarily used
+ *    for remote desktop protocols.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_ACCELFRONT
+ */
+
+#define  SVGA_ROP_COPY                    0x03
+
+typedef
+struct {
+   uint32 color;     // In the same format as the GFB
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+   uint32 rop;       // Must be SVGA_ROP_COPY
+} SVGAFifoCmdFrontRopFill;
+
+
+/*
+ * SVGA_CMD_FENCE --
+ *
+ *    Insert a synchronization fence.  When the SVGA device reaches
+ *    this command, it will copy the 'fence' value into the
+ *    SVGA_FIFO_FENCE register. It will also compare the fence against
+ *    SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the
+ *    SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will
+ *    raise this interrupt.
+ *
+ * Availability:
+ *    SVGA_FIFO_FENCE for this command,
+ *    SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL.
+ */
+
+typedef
+struct {
+   uint32 fence;
+} SVGAFifoCmdFence;
+
+
+/*
+ * SVGA_CMD_ESCAPE --
+ *
+ *    Send an extended or vendor-specific variable length command.
+ *    This is used for video overlay, third party plugins, and
+ *    internal debugging tools. See svga_escape.h
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_ESCAPE
+ */
+
+typedef
+struct {
+   uint32 nsid;
+   uint32 size;
+   /* followed by 'size' bytes of data */
+} SVGAFifoCmdEscape;
+
+
+/*
+ * SVGA_CMD_DEFINE_SCREEN --
+ *
+ *    Define or redefine an SVGAScreenObject. See the description of
+ *    SVGAScreenObject above.  The video driver is responsible for
+ *    generating new screen IDs. They should be small positive
+ *    integers. The virtual device will have an implementation
+ *    specific upper limit on the number of screen IDs
+ *    supported. Drivers are responsible for recycling IDs. The first
+ *    valid ID is zero.
+ *
+ *    - Interaction with other registers:
+ *
+ *    For backwards compatibility, when the GFB mode registers (WIDTH,
+ *    HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device
+ *    deletes all screens other than screen #0, and redefines screen
+ *    #0 according to the specified mode. Drivers that use
+ *    SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0.
+ *
+ *    If you use screen objects, do not use the legacy multi-mon
+ *    registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*).
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAScreenObject screen;   // Variable-length according to version
+} SVGAFifoCmdDefineScreen;
+
+
+/*
+ * SVGA_CMD_DESTROY_SCREEN --
+ *
+ *    Destroy an SVGAScreenObject. Its ID is immediately available for
+ *    re-use.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   uint32 screenId;
+} SVGAFifoCmdDestroyScreen;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMRFB --
+ *
+ *    This command sets a piece of SVGA device state called the
+ *    Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a
+ *    piece of light-weight state which identifies the location and
+ *    format of an image in guest memory or in BAR1. The GMRFB has
+ *    an arbitrary size, and it doesn't need to match the geometry
+ *    of the GFB or any screen object.
+ *
+ *    The GMRFB can be redefined as often as you like. You could
+ *    always use the same GMRFB, you could redefine it before
+ *    rendering from a different guest screen, or you could even
+ *    redefine it before every blit.
+ *
+ *    There are multiple ways to use this command. The simplest way is
+ *    to use it to move the framebuffer either to elsewhere in the GFB
+ *    (BAR1) memory region, or to a user-defined GMR. This lets a
+ *    driver use a framebuffer allocated entirely out of normal system
+ *    memory, which we encourage.
+ *
+ *    Another way to use this command is to set up a ring buffer of
+ *    updates in GFB memory. If a driver wants to ensure that no
+ *    frames are skipped by the SVGA device, it is important that the
+ *    driver not modify the source data for a blit until the device is
+ *    done processing the command. One efficient way to accomplish
+ *    this is to use a ring of small DMA buffers. Each buffer is used
+ *    for one blit, then we move on to the next buffer in the
+ *    ring. The FENCE mechanism is used to protect each buffer from
+ *    re-use until the device is finished with that buffer's
+ *    corresponding blit.
+ *
+ *    This command does not affect the meaning of SVGA_CMD_UPDATE.
+ *    UPDATEs always occur from the legacy GFB memory area. This
+ *    command has no support for pseudocolor GMRFBs. Currently only
+ *    true-color 15, 16, and 24-bit depths are supported. Future
+ *    devices may expose capabilities for additional framebuffer
+ *    formats.
+ *
+ *    The default GMRFB value is undefined. Drivers must always send
+ *    this command at least once before performing any blit from the
+ *    GMRFB.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAGuestPtr        ptr;
+   uint32              bytesPerLine;
+   SVGAGMRImageFormat  format;
+} SVGAFifoCmdDefineGMRFB;
+
+
+/*
+ * SVGA_CMD_BLIT_GMRFB_TO_SCREEN --
+ *
+ *    This is a guest-to-host blit. It performs a DMA operation to
+ *    copy a rectangular region of pixels from the current GMRFB to
+ *    one or more Screen Objects.
+ *
+ *    The destination coordinate may be specified relative to a
+ *    screen's origin (if a screen ID is specified) or relative to the
+ *    virtual coordinate system's origin (if the screen ID is
+ *    SVGA_ID_INVALID). The actual destination may span zero or more
+ *    screens, in the case of a virtual destination rect or a rect
+ *    which extends off the edge of the specified screen.
+ *
+ *    This command writes to the screen's "base layer": the underlying
+ *    framebuffer which exists below any cursor or video overlays. No
+ *    action is necessary to explicitly hide or update any overlays
+ *    which exist on top of the updated region.
+ *
+ *    The SVGA device is guaranteed to finish reading from the GMRFB
+ *    by the time any subsequent FENCE commands are reached.
+ *
+ *    This command consumes an annotation. See the
+ *    SVGA_CMD_ANNOTATION_* commands for details.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  srcOrigin;
+   SVGASignedRect   destRect;
+   uint32           destScreenId;
+} SVGAFifoCmdBlitGMRFBToScreen;
+
+
+/*
+ * SVGA_CMD_BLIT_SCREEN_TO_GMRFB --
+ *
+ *    This is a host-to-guest blit. It performs a DMA operation to
+ *    copy a rectangular region of pixels from a single Screen Object
+ *    back to the current GMRFB.
+ *
+ *    Usage note: This command should be used rarely. It will
+ *    typically be inefficient, but it is necessary for some types of
+ *    synchronization between 3D (GPU) and 2D (CPU) rendering into
+ *    overlapping areas of a screen.
+ *
+ *    The source coordinate is specified relative to a screen's
+ *    origin. The provided screen ID must be valid. If any parameters
+ *    are invalid, the resulting pixel values are undefined.
+ *
+ *    This command reads the screen's "base layer". Overlays like
+ *    video and cursor are not included, but any data which was sent
+ *    using a blit-to-screen primitive will be available, no matter
+ *    whether the data's original source was the GMRFB or the 3D
+ *    acceleration hardware.
+ *
+ *    Note that our guest-to-host blits and host-to-guest blits aren't
+ *    symmetric in their current implementation. While the parameters
+ *    are identical, host-to-guest blits are a lot less featureful.
+ *    They do not support clipping: If the source parameters don't
+ *    fully fit within a screen, the blit fails. They must originate
+ *    from exactly one screen. Virtual coordinates are not directly
+ *    supported.
+ *
+ *    Host-to-guest blits do support the same set of GMRFB formats
+ *    offered by guest-to-host blits.
+ *
+ *    The SVGA device is guaranteed to finish writing to the GMRFB by
+ *    the time any subsequent FENCE commands are reached.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  destOrigin;
+   SVGASignedRect   srcRect;
+   uint32           srcScreenId;
+} SVGAFifoCmdBlitScreenToGMRFB;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_FILL --
+ *
+ *    This is a blit annotation. This command stores a small piece of
+ *    device state which is consumed by the next blit-to-screen
+ *    command. The state is only cleared by commands which are
+ *    specifically documented as consuming an annotation. Other
+ *    commands (such as ESCAPEs for debugging) may intervene between
+ *    the annotation and its associated blit.
+ *
+ *    This annotation is a promise about the contents of the next
+ *    blit: The video driver is guaranteeing that all pixels in that
+ *    blit will have the same value, specified here as a color in
+ *    SVGAColorBGRX format.
+ *
+ *    The SVGA device can still render the blit correctly even if it
+ *    ignores this annotation, but the annotation may allow it to
+ *    perform the blit more efficiently, for example by ignoring the
+ *    source data and performing a fill in hardware.
+ *
+ *    This annotation is most important for performance when the
+ *    user's display is being remoted over a network connection.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAColorBGRX  color;
+} SVGAFifoCmdAnnotationFill;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_COPY --
+ *
+ *    This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more
+ *    information about annotations.
+ *
+ *    This annotation is a promise about the contents of the next
+ *    blit: The video driver is guaranteeing that all pixels in that
+ *    blit will have the same value as those which already exist at an
+ *    identically-sized region on the same or a different screen.
+ *
+ *    Note that the source pixels for the COPY in this annotation are
+ *    sampled before applying the anqnotation's associated blit. They
+ *    are allowed to overlap with the blit's destination pixels.
+ *
+ *    The copy source rectangle is specified the same way as the blit
+ *    destination: it can be a rectangle which spans zero or more
+ *    screens, specified relative to either a screen or to the virtual
+ *    coordinate system's origin. If the source rectangle includes
+ *    pixels which are not from exactly one screen, the results are
+ *    undefined.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  srcOrigin;
+   uint32           srcScreenId;
+} SVGAFifoCmdAnnotationCopy;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_types.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_types.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/svga_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/svga_types.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,45 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+/**
+ * Silly typedefs for the svga headers. Currently the headers are shared
+ * between all components that talk to svga. And as such the headers are
+ * are in a completely different style and use weird defines.
+ *
+ * This file lets all the ugly be prefixed with svga*.
+ */
+
+#ifndef _SVGA_TYPES_H_
+#define _SVGA_TYPES_H_
+
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint8_t uint8;
+typedef int32_t int32;
+typedef bool Bool;
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,252 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+
+static uint32_t vram_placement_flags = TTM_PL_FLAG_VRAM |
+	TTM_PL_FLAG_CACHED;
+
+static uint32_t vram_ne_placement_flags = TTM_PL_FLAG_VRAM |
+	TTM_PL_FLAG_CACHED |
+	TTM_PL_FLAG_NO_EVICT;
+
+static uint32_t sys_placement_flags = TTM_PL_FLAG_SYSTEM |
+	TTM_PL_FLAG_CACHED;
+
+struct ttm_placement vmw_vram_placement = {
+	.fpfn = 0,
+	.lpfn = 0,
+	.num_placement = 1,
+	.placement = &vram_placement_flags,
+	.num_busy_placement = 1,
+	.busy_placement = &vram_placement_flags
+};
+
+struct ttm_placement vmw_vram_sys_placement = {
+	.fpfn = 0,
+	.lpfn = 0,
+	.num_placement = 1,
+	.placement = &vram_placement_flags,
+	.num_busy_placement = 1,
+	.busy_placement = &sys_placement_flags
+};
+
+struct ttm_placement vmw_vram_ne_placement = {
+	.fpfn = 0,
+	.lpfn = 0,
+	.num_placement = 1,
+	.placement = &vram_ne_placement_flags,
+	.num_busy_placement = 1,
+	.busy_placement = &vram_ne_placement_flags
+};
+
+struct ttm_placement vmw_sys_placement = {
+	.fpfn = 0,
+	.lpfn = 0,
+	.num_placement = 1,
+	.placement = &sys_placement_flags,
+	.num_busy_placement = 1,
+	.busy_placement = &sys_placement_flags
+};
+
+struct vmw_ttm_backend {
+	struct ttm_backend backend;
+};
+
+static int vmw_ttm_populate(struct ttm_backend *backend,
+			    unsigned long num_pages, struct page **pages,
+			    struct page *dummy_read_page)
+{
+	return 0;
+}
+
+static int vmw_ttm_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem)
+{
+	return 0;
+}
+
+static int vmw_ttm_unbind(struct ttm_backend *backend)
+{
+	return 0;
+}
+
+static void vmw_ttm_clear(struct ttm_backend *backend)
+{
+}
+
+static void vmw_ttm_destroy(struct ttm_backend *backend)
+{
+	struct vmw_ttm_backend *vmw_be =
+	    container_of(backend, struct vmw_ttm_backend, backend);
+
+	kfree(vmw_be);
+}
+
+static struct ttm_backend_func vmw_ttm_func = {
+	.populate = vmw_ttm_populate,
+	.clear = vmw_ttm_clear,
+	.bind = vmw_ttm_bind,
+	.unbind = vmw_ttm_unbind,
+	.destroy = vmw_ttm_destroy,
+};
+
+struct ttm_backend *vmw_ttm_backend_init(struct ttm_bo_device *bdev)
+{
+	struct vmw_ttm_backend *vmw_be;
+
+	vmw_be = kmalloc(sizeof(*vmw_be), GFP_KERNEL);
+	if (!vmw_be)
+		return NULL;
+
+	vmw_be->backend.func = &vmw_ttm_func;
+
+	return &vmw_be->backend;
+}
+
+int vmw_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
+{
+	return 0;
+}
+
+int vmw_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+		      struct ttm_mem_type_manager *man)
+{
+	struct vmw_private *dev_priv =
+	    container_of(bdev, struct vmw_private, bdev);
+
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		/* System memory */
+
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case TTM_PL_VRAM:
+		/* "On-card" video ram */
+		man->gpu_offset = 0;
+		man->io_offset = dev_priv->vram_start;
+		man->io_size = dev_priv->vram_size;
+		man->flags = TTM_MEMTYPE_FLAG_FIXED |
+		    TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->io_addr = NULL;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_WC;
+		break;
+	default:
+		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+void vmw_evict_flags(struct ttm_buffer_object *bo,
+		     struct ttm_placement *placement)
+{
+	*placement = vmw_sys_placement;
+}
+
+/**
+ * FIXME: Proper access checks on buffers.
+ */
+
+static int vmw_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+	return 0;
+}
+
+static void vmw_move_notify(struct ttm_buffer_object *bo,
+		     struct ttm_mem_reg *new_mem)
+{
+	if (new_mem->mem_type != TTM_PL_SYSTEM)
+		vmw_dmabuf_gmr_unbind(bo);
+}
+
+static void vmw_swap_notify(struct ttm_buffer_object *bo)
+{
+	vmw_dmabuf_gmr_unbind(bo);
+}
+
+/**
+ * FIXME: We're using the old vmware polling method to sync.
+ * Do this with fences instead.
+ */
+
+static void *vmw_sync_obj_ref(void *sync_obj)
+{
+	return sync_obj;
+}
+
+static void vmw_sync_obj_unref(void **sync_obj)
+{
+	*sync_obj = NULL;
+}
+
+static int vmw_sync_obj_flush(void *sync_obj, void *sync_arg)
+{
+	struct vmw_private *dev_priv = (struct vmw_private *)sync_arg;
+
+	mutex_lock(&dev_priv->hw_mutex);
+	vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC);
+	mutex_unlock(&dev_priv->hw_mutex);
+	return 0;
+}
+
+static bool vmw_sync_obj_signaled(void *sync_obj, void *sync_arg)
+{
+	struct vmw_private *dev_priv = (struct vmw_private *)sync_arg;
+	uint32_t sequence = (unsigned long) sync_obj;
+
+	return vmw_fence_signaled(dev_priv, sequence);
+}
+
+static int vmw_sync_obj_wait(void *sync_obj, void *sync_arg,
+			     bool lazy, bool interruptible)
+{
+	struct vmw_private *dev_priv = (struct vmw_private *)sync_arg;
+	uint32_t sequence = (unsigned long) sync_obj;
+
+	return vmw_wait_fence(dev_priv, false, sequence, false, 3*HZ);
+}
+
+struct ttm_bo_driver vmw_bo_driver = {
+	.create_ttm_backend_entry = vmw_ttm_backend_init,
+	.invalidate_caches = vmw_invalidate_caches,
+	.init_mem_type = vmw_init_mem_type,
+	.evict_flags = vmw_evict_flags,
+	.move = NULL,
+	.verify_access = vmw_verify_access,
+	.sync_obj_signaled = vmw_sync_obj_signaled,
+	.sync_obj_wait = vmw_sync_obj_wait,
+	.sync_obj_flush = vmw_sync_obj_flush,
+	.sync_obj_unref = vmw_sync_obj_unref,
+	.sync_obj_ref = vmw_sync_obj_ref,
+	.move_notify = vmw_move_notify,
+	.swap_notify = vmw_swap_notify
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,783 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_object.h"
+#include "ttm/ttm_module.h"
+
+#define VMWGFX_DRIVER_NAME "vmwgfx"
+#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
+#define VMWGFX_CHIP_SVGAII 0
+#define VMW_FB_RESERVATION 0
+
+/**
+ * Fully encoded drm commands. Might move to vmw_drm.h
+ */
+
+#define DRM_IOCTL_VMW_GET_PARAM					\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GET_PARAM,		\
+		 struct drm_vmw_getparam_arg)
+#define DRM_IOCTL_VMW_ALLOC_DMABUF				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_ALLOC_DMABUF,	\
+		union drm_vmw_alloc_dmabuf_arg)
+#define DRM_IOCTL_VMW_UNREF_DMABUF				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_DMABUF,	\
+		struct drm_vmw_unref_dmabuf_arg)
+#define DRM_IOCTL_VMW_CURSOR_BYPASS				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CURSOR_BYPASS,	\
+		 struct drm_vmw_cursor_bypass_arg)
+
+#define DRM_IOCTL_VMW_CONTROL_STREAM				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CONTROL_STREAM,	\
+		 struct drm_vmw_control_stream_arg)
+#define DRM_IOCTL_VMW_CLAIM_STREAM				\
+	DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CLAIM_STREAM,	\
+		 struct drm_vmw_stream_arg)
+#define DRM_IOCTL_VMW_UNREF_STREAM				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_STREAM,	\
+		 struct drm_vmw_stream_arg)
+
+#define DRM_IOCTL_VMW_CREATE_CONTEXT				\
+	DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CREATE_CONTEXT,	\
+		struct drm_vmw_context_arg)
+#define DRM_IOCTL_VMW_UNREF_CONTEXT				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_CONTEXT,	\
+		struct drm_vmw_context_arg)
+#define DRM_IOCTL_VMW_CREATE_SURFACE				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_CREATE_SURFACE,	\
+		 union drm_vmw_surface_create_arg)
+#define DRM_IOCTL_VMW_UNREF_SURFACE				\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_SURFACE,	\
+		 struct drm_vmw_surface_arg)
+#define DRM_IOCTL_VMW_REF_SURFACE				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_REF_SURFACE,	\
+		 union drm_vmw_surface_reference_arg)
+#define DRM_IOCTL_VMW_EXECBUF					\
+	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF,		\
+		struct drm_vmw_execbuf_arg)
+#define DRM_IOCTL_VMW_FIFO_DEBUG				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FIFO_DEBUG,		\
+		 struct drm_vmw_fifo_debug_arg)
+#define DRM_IOCTL_VMW_FENCE_WAIT				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT,		\
+		 struct drm_vmw_fence_wait_arg)
+
+
+/**
+ * The core DRM version of this macro doesn't account for
+ * DRM_COMMAND_BASE.
+ */
+
+#define VMW_IOCTL_DEF(ioctl, func, flags) \
+	[DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
+
+/**
+ * Ioctl definitions.
+ */
+
+static struct drm_ioctl_desc vmw_ioctls[] = {
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS,
+		      vmw_kms_cursor_bypass_ioctl,
+		      DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
+
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl,
+		      DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
+		      DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
+		      DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED),
+
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
+		      DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED),
+	VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
+		      DRM_AUTH | DRM_UNLOCKED)
+};
+
+static struct pci_device_id vmw_pci_id_list[] = {
+	{0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},
+	{0, 0, 0}
+};
+
+static char *vmw_devname = "vmwgfx";
+
+static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
+static void vmw_master_init(struct vmw_master *);
+static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
+			      void *ptr);
+
+static void vmw_print_capabilities(uint32_t capabilities)
+{
+	DRM_INFO("Capabilities:\n");
+	if (capabilities & SVGA_CAP_RECT_COPY)
+		DRM_INFO("  Rect copy.\n");
+	if (capabilities & SVGA_CAP_CURSOR)
+		DRM_INFO("  Cursor.\n");
+	if (capabilities & SVGA_CAP_CURSOR_BYPASS)
+		DRM_INFO("  Cursor bypass.\n");
+	if (capabilities & SVGA_CAP_CURSOR_BYPASS_2)
+		DRM_INFO("  Cursor bypass 2.\n");
+	if (capabilities & SVGA_CAP_8BIT_EMULATION)
+		DRM_INFO("  8bit emulation.\n");
+	if (capabilities & SVGA_CAP_ALPHA_CURSOR)
+		DRM_INFO("  Alpha cursor.\n");
+	if (capabilities & SVGA_CAP_3D)
+		DRM_INFO("  3D.\n");
+	if (capabilities & SVGA_CAP_EXTENDED_FIFO)
+		DRM_INFO("  Extended Fifo.\n");
+	if (capabilities & SVGA_CAP_MULTIMON)
+		DRM_INFO("  Multimon.\n");
+	if (capabilities & SVGA_CAP_PITCHLOCK)
+		DRM_INFO("  Pitchlock.\n");
+	if (capabilities & SVGA_CAP_IRQMASK)
+		DRM_INFO("  Irq mask.\n");
+	if (capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)
+		DRM_INFO("  Display Topology.\n");
+	if (capabilities & SVGA_CAP_GMR)
+		DRM_INFO("  GMR.\n");
+	if (capabilities & SVGA_CAP_TRACES)
+		DRM_INFO("  Traces.\n");
+}
+
+static int vmw_request_device(struct vmw_private *dev_priv)
+{
+	int ret;
+
+	vmw_kms_save_vga(dev_priv);
+
+	ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Unable to initialize FIFO.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void vmw_release_device(struct vmw_private *dev_priv)
+{
+	vmw_fifo_release(dev_priv, &dev_priv->fifo);
+	vmw_kms_restore_vga(dev_priv);
+}
+
+
+static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
+{
+	struct vmw_private *dev_priv;
+	int ret;
+	uint32_t svga_id;
+
+	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+	if (unlikely(dev_priv == NULL)) {
+		DRM_ERROR("Failed allocating a device private struct.\n");
+		return -ENOMEM;
+	}
+	memset(dev_priv, 0, sizeof(*dev_priv));
+
+	dev_priv->dev = dev;
+	dev_priv->vmw_chipset = chipset;
+	dev_priv->last_read_sequence = (uint32_t) -100;
+	mutex_init(&dev_priv->hw_mutex);
+	mutex_init(&dev_priv->cmdbuf_mutex);
+	rwlock_init(&dev_priv->resource_lock);
+	idr_init(&dev_priv->context_idr);
+	idr_init(&dev_priv->surface_idr);
+	idr_init(&dev_priv->stream_idr);
+	ida_init(&dev_priv->gmr_ida);
+	mutex_init(&dev_priv->init_mutex);
+	init_waitqueue_head(&dev_priv->fence_queue);
+	init_waitqueue_head(&dev_priv->fifo_queue);
+	atomic_set(&dev_priv->fence_queue_waiters, 0);
+	atomic_set(&dev_priv->fifo_queue_waiters, 0);
+	INIT_LIST_HEAD(&dev_priv->gmr_lru);
+
+	dev_priv->io_start = pci_resource_start(dev->pdev, 0);
+	dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
+	dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
+
+	mutex_lock(&dev_priv->hw_mutex);
+
+	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
+	svga_id = vmw_read(dev_priv, SVGA_REG_ID);
+	if (svga_id != SVGA_ID_2) {
+		ret = -ENOSYS;
+		DRM_ERROR("Unsuported SVGA ID 0x%x\n", svga_id);
+		mutex_unlock(&dev_priv->hw_mutex);
+		goto out_err0;
+	}
+
+	dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
+
+	if (dev_priv->capabilities & SVGA_CAP_GMR) {
+		dev_priv->max_gmr_descriptors =
+			vmw_read(dev_priv,
+				 SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH);
+		dev_priv->max_gmr_ids =
+			vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS);
+	}
+
+	dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE);
+	dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE);
+	dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH);
+	dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT);
+
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	vmw_print_capabilities(dev_priv->capabilities);
+
+	if (dev_priv->capabilities & SVGA_CAP_GMR) {
+		DRM_INFO("Max GMR ids is %u\n",
+			 (unsigned)dev_priv->max_gmr_ids);
+		DRM_INFO("Max GMR descriptors is %u\n",
+			 (unsigned)dev_priv->max_gmr_descriptors);
+	}
+	DRM_INFO("VRAM at 0x%08x size is %u kiB\n",
+		 dev_priv->vram_start, dev_priv->vram_size / 1024);
+	DRM_INFO("MMIO at 0x%08x size is %u kiB\n",
+		 dev_priv->mmio_start, dev_priv->mmio_size / 1024);
+
+	ret = vmw_ttm_global_init(dev_priv);
+	if (unlikely(ret != 0))
+		goto out_err0;
+
+
+	vmw_master_init(&dev_priv->fbdev_master);
+	ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
+	dev_priv->active_master = &dev_priv->fbdev_master;
+
+
+	ret = ttm_bo_device_init(&dev_priv->bdev,
+				 dev_priv->bo_global_ref.ref.object,
+				 &vmw_bo_driver, VMWGFX_FILE_PAGE_OFFSET,
+				 false);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed initializing TTM buffer object driver.\n");
+		goto out_err1;
+	}
+
+	ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
+			     (dev_priv->vram_size >> PAGE_SHIFT));
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed initializing memory manager for VRAM.\n");
+		goto out_err2;
+	}
+
+	dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start,
+					   dev_priv->mmio_size, DRM_MTRR_WC);
+
+	dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start,
+					 dev_priv->mmio_size);
+
+	if (unlikely(dev_priv->mmio_virt == NULL)) {
+		ret = -ENOMEM;
+		DRM_ERROR("Failed mapping MMIO.\n");
+		goto out_err3;
+	}
+
+	dev_priv->tdev = ttm_object_device_init
+	    (dev_priv->mem_global_ref.object, 12);
+
+	if (unlikely(dev_priv->tdev == NULL)) {
+		DRM_ERROR("Unable to initialize TTM object management.\n");
+		ret = -ENOMEM;
+		goto out_err4;
+	}
+
+	dev->dev_private = dev_priv;
+
+	if (!dev->devname)
+		dev->devname = vmw_devname;
+
+	if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
+		ret = drm_irq_install(dev);
+		if (unlikely(ret != 0)) {
+			DRM_ERROR("Failed installing irq: %d\n", ret);
+			goto out_no_irq;
+		}
+	}
+
+	ret = pci_request_regions(dev->pdev, "vmwgfx probe");
+	dev_priv->stealth = (ret != 0);
+	if (dev_priv->stealth) {
+		/**
+		 * Request at least the mmio PCI resource.
+		 */
+
+		DRM_INFO("It appears like vesafb is loaded. "
+			 "Ignore above error if any.\n");
+		ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe");
+		if (unlikely(ret != 0)) {
+			DRM_ERROR("Failed reserving the SVGA MMIO resource.\n");
+			goto out_no_device;
+		}
+	}
+	ret = vmw_request_device(dev_priv);
+	if (unlikely(ret != 0))
+		goto out_no_device;
+	vmw_kms_init(dev_priv);
+	vmw_overlay_init(dev_priv);
+	vmw_fb_init(dev_priv);
+
+	dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
+	register_pm_notifier(&dev_priv->pm_nb);
+
+	DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
+
+	return 0;
+
+out_no_device:
+	if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
+		drm_irq_uninstall(dev_priv->dev);
+	if (dev->devname == vmw_devname)
+		dev->devname = NULL;
+out_no_irq:
+	ttm_object_device_release(&dev_priv->tdev);
+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);
+	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+out_err2:
+	(void)ttm_bo_device_release(&dev_priv->bdev);
+out_err1:
+	vmw_ttm_global_release(dev_priv);
+out_err0:
+	ida_destroy(&dev_priv->gmr_ida);
+	idr_destroy(&dev_priv->surface_idr);
+	idr_destroy(&dev_priv->context_idr);
+	idr_destroy(&dev_priv->stream_idr);
+	kfree(dev_priv);
+	return ret;
+}
+
+static int vmw_driver_unload(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+
+	DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n");
+
+	unregister_pm_notifier(&dev_priv->pm_nb);
+
+	vmw_fb_close(dev_priv);
+	vmw_kms_close(dev_priv);
+	vmw_overlay_close(dev_priv);
+	vmw_release_device(dev_priv);
+	if (dev_priv->stealth)
+		pci_release_region(dev->pdev, 2);
+	else
+		pci_release_regions(dev->pdev);
+
+	if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
+		drm_irq_uninstall(dev_priv->dev);
+	if (dev->devname == vmw_devname)
+		dev->devname = NULL;
+	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);
+	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+	(void)ttm_bo_device_release(&dev_priv->bdev);
+	vmw_ttm_global_release(dev_priv);
+	ida_destroy(&dev_priv->gmr_ida);
+	idr_destroy(&dev_priv->surface_idr);
+	idr_destroy(&dev_priv->context_idr);
+	idr_destroy(&dev_priv->stream_idr);
+
+	kfree(dev_priv);
+
+	return 0;
+}
+
+static void vmw_postclose(struct drm_device *dev,
+			 struct drm_file *file_priv)
+{
+	struct vmw_fpriv *vmw_fp;
+
+	vmw_fp = vmw_fpriv(file_priv);
+	ttm_object_file_release(&vmw_fp->tfile);
+	if (vmw_fp->locked_master)
+		drm_master_put(&vmw_fp->locked_master);
+	kfree(vmw_fp);
+}
+
+static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_fpriv *vmw_fp;
+	int ret = -ENOMEM;
+
+	vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL);
+	if (unlikely(vmw_fp == NULL))
+		return ret;
+
+	vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
+	if (unlikely(vmw_fp->tfile == NULL))
+		goto out_no_tfile;
+
+	file_priv->driver_priv = vmw_fp;
+
+	if (unlikely(dev_priv->bdev.dev_mapping == NULL))
+		dev_priv->bdev.dev_mapping =
+			file_priv->filp->f_path.dentry->d_inode->i_mapping;
+
+	return 0;
+
+out_no_tfile:
+	kfree(vmw_fp);
+	return ret;
+}
+
+static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
+			       unsigned long arg)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_device *dev = file_priv->minor->dev;
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+
+	/*
+	 * Do extra checking on driver private ioctls.
+	 */
+
+	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
+	    && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
+		struct drm_ioctl_desc *ioctl =
+		    &vmw_ioctls[nr - DRM_COMMAND_BASE];
+
+		if (unlikely(ioctl->cmd != cmd)) {
+			DRM_ERROR("Invalid command format, ioctl %d\n",
+				  nr - DRM_COMMAND_BASE);
+			return -EINVAL;
+		}
+	}
+
+	return drm_ioctl(filp, cmd, arg);
+}
+
+static int vmw_firstopen(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	dev_priv->is_opened = true;
+
+	return 0;
+}
+
+static void vmw_lastclose(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct drm_crtc *crtc;
+	struct drm_mode_set set;
+	int ret;
+
+	/**
+	 * Do nothing on the lastclose call from drm_unload.
+	 */
+
+	if (!dev_priv->is_opened)
+		return;
+
+	dev_priv->is_opened = false;
+	set.x = 0;
+	set.y = 0;
+	set.fb = NULL;
+	set.mode = NULL;
+	set.connectors = NULL;
+	set.num_connectors = 0;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		set.crtc = crtc;
+		ret = crtc->funcs->set_config(&set);
+		WARN_ON(ret != 0);
+	}
+
+}
+
+static void vmw_master_init(struct vmw_master *vmaster)
+{
+	ttm_lock_init(&vmaster->lock);
+}
+
+static int vmw_master_create(struct drm_device *dev,
+			     struct drm_master *master)
+{
+	struct vmw_master *vmaster;
+
+	DRM_INFO("Master create.\n");
+	vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
+	if (unlikely(vmaster == NULL))
+		return -ENOMEM;
+
+	ttm_lock_init(&vmaster->lock);
+	ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
+	master->driver_priv = vmaster;
+
+	return 0;
+}
+
+static void vmw_master_destroy(struct drm_device *dev,
+			       struct drm_master *master)
+{
+	struct vmw_master *vmaster = vmw_master(master);
+
+	DRM_INFO("Master destroy.\n");
+	master->driver_priv = NULL;
+	kfree(vmaster);
+}
+
+
+static int vmw_master_set(struct drm_device *dev,
+			  struct drm_file *file_priv,
+			  bool from_open)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	struct vmw_master *active = dev_priv->active_master;
+	struct vmw_master *vmaster = vmw_master(file_priv->master);
+	int ret = 0;
+
+	DRM_INFO("Master set.\n");
+
+	if (active) {
+		BUG_ON(active != &dev_priv->fbdev_master);
+		ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
+		if (unlikely(ret != 0))
+			goto out_no_active_lock;
+
+		ttm_lock_set_kill(&active->lock, true, SIGTERM);
+		ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
+		if (unlikely(ret != 0)) {
+			DRM_ERROR("Unable to clean VRAM on "
+				  "master drop.\n");
+		}
+
+		dev_priv->active_master = NULL;
+	}
+
+	ttm_lock_set_kill(&vmaster->lock, false, SIGTERM);
+	if (!from_open) {
+		ttm_vt_unlock(&vmaster->lock);
+		BUG_ON(vmw_fp->locked_master != file_priv->master);
+		drm_master_put(&vmw_fp->locked_master);
+	}
+
+	dev_priv->active_master = vmaster;
+
+	return 0;
+
+out_no_active_lock:
+	vmw_release_device(dev_priv);
+	return ret;
+}
+
+static void vmw_master_drop(struct drm_device *dev,
+			    struct drm_file *file_priv,
+			    bool from_release)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	struct vmw_master *vmaster = vmw_master(file_priv->master);
+	int ret;
+
+	DRM_INFO("Master drop.\n");
+
+	/**
+	 * Make sure the master doesn't disappear while we have
+	 * it locked.
+	 */
+
+	vmw_fp->locked_master = drm_master_get(file_priv->master);
+	ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
+
+	if (unlikely((ret != 0))) {
+		DRM_ERROR("Unable to lock TTM at VT switch.\n");
+		drm_master_put(&vmw_fp->locked_master);
+	}
+
+	ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
+
+	dev_priv->active_master = &dev_priv->fbdev_master;
+	ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
+	ttm_vt_unlock(&dev_priv->fbdev_master.lock);
+
+	vmw_fb_on(dev_priv);
+}
+
+
+static void vmw_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_put_dev(dev);
+}
+
+static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
+			      void *ptr)
+{
+	struct vmw_private *dev_priv =
+		container_of(nb, struct vmw_private, pm_nb);
+	struct vmw_master *vmaster = dev_priv->active_master;
+
+	switch (val) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		ttm_suspend_lock(&vmaster->lock);
+
+		/**
+		 * This empties VRAM and unbinds all GMR bindings.
+		 * Buffer contents is moved to swappable memory.
+		 */
+		ttm_bo_swapout_all(&dev_priv->bdev);
+		break;
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		ttm_suspend_unlock(&vmaster->lock);
+		break;
+	case PM_RESTORE_PREPARE:
+		break;
+	case PM_POST_RESTORE:
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+/**
+ * These might not be needed with the virtual SVGA device.
+ */
+
+int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+	return 0;
+}
+
+int vmw_pci_resume(struct pci_dev *pdev)
+{
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	return pci_enable_device(pdev);
+}
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+	DRIVER_MODESET,
+	.load = vmw_driver_load,
+	.unload = vmw_driver_unload,
+	.firstopen = vmw_firstopen,
+	.lastclose = vmw_lastclose,
+	.irq_preinstall = vmw_irq_preinstall,
+	.irq_postinstall = vmw_irq_postinstall,
+	.irq_uninstall = vmw_irq_uninstall,
+	.irq_handler = vmw_irq_handler,
+	.reclaim_buffers_locked = NULL,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.ioctls = vmw_ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls),
+	.dma_quiescent = NULL,	/*vmw_dma_quiescent, */
+	.master_create = vmw_master_create,
+	.master_destroy = vmw_master_destroy,
+	.master_set = vmw_master_set,
+	.master_drop = vmw_master_drop,
+	.open = vmw_driver_open,
+	.postclose = vmw_postclose,
+	.fops = {
+		 .owner = THIS_MODULE,
+		 .open = drm_open,
+		 .release = drm_release,
+		 .unlocked_ioctl = vmw_unlocked_ioctl,
+		 .mmap = vmw_mmap,
+		 .poll = drm_poll,
+		 .fasync = drm_fasync,
+#if defined(CONFIG_COMPAT)
+		 .compat_ioctl = drm_compat_ioctl,
+#endif
+		 },
+	.pci_driver = {
+		       .name = VMWGFX_DRIVER_NAME,
+		       .id_table = vmw_pci_id_list,
+		       .probe = vmw_probe,
+		       .remove = vmw_remove,
+		       .suspend = vmw_pci_suspend,
+		       .resume = vmw_pci_resume
+		       },
+	.name = VMWGFX_DRIVER_NAME,
+	.desc = VMWGFX_DRIVER_DESC,
+	.date = VMWGFX_DRIVER_DATE,
+	.major = VMWGFX_DRIVER_MAJOR,
+	.minor = VMWGFX_DRIVER_MINOR,
+	.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
+};
+
+static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return drm_get_dev(pdev, ent, &driver);
+}
+
+static int __init vmwgfx_init(void)
+{
+	int ret;
+	ret = drm_init(&driver);
+	if (ret)
+		DRM_ERROR("Failed initializing DRM.\n");
+	return ret;
+}
+
+static void __exit vmwgfx_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(vmwgfx_init);
+module_exit(vmwgfx_exit);
+
+MODULE_AUTHOR("VMware Inc. and others");
+MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device");
+MODULE_LICENSE("GPL and additional rights");
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,521 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#ifndef _VMWGFX_DRV_H_
+#define _VMWGFX_DRV_H_
+
+#include "vmwgfx_reg.h"
+#include "drmP.h"
+#include "vmwgfx_drm.h"
+#include "drm_hashtab.h"
+#include "linux/suspend.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_object.h"
+#include "ttm/ttm_lock.h"
+#include "ttm/ttm_execbuf_util.h"
+#include "ttm/ttm_module.h"
+
+#define VMWGFX_DRIVER_DATE "20100209"
+#define VMWGFX_DRIVER_MAJOR 1
+#define VMWGFX_DRIVER_MINOR 0
+#define VMWGFX_DRIVER_PATCHLEVEL 0
+#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
+#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
+#define VMWGFX_MAX_RELOCATIONS 2048
+#define VMWGFX_MAX_GMRS 2048
+
+struct vmw_fpriv {
+	struct drm_master *locked_master;
+	struct ttm_object_file *tfile;
+};
+
+struct vmw_dma_buffer {
+	struct ttm_buffer_object base;
+	struct list_head validate_list;
+	struct list_head gmr_lru;
+	uint32_t gmr_id;
+	bool gmr_bound;
+	uint32_t cur_validate_node;
+	bool on_validate_list;
+};
+
+struct vmw_resource {
+	struct kref kref;
+	struct vmw_private *dev_priv;
+	struct idr *idr;
+	int id;
+	enum ttm_object_type res_type;
+	bool avail;
+	void (*hw_destroy) (struct vmw_resource *res);
+	void (*res_free) (struct vmw_resource *res);
+
+	/* TODO is a generic snooper needed? */
+#if 0
+	void (*snoop)(struct vmw_resource *res,
+		      struct ttm_object_file *tfile,
+		      SVGA3dCmdHeader *header);
+	void *snoop_priv;
+#endif
+};
+
+struct vmw_cursor_snooper {
+	struct drm_crtc *crtc;
+	size_t age;
+	uint32_t *image;
+};
+
+struct vmw_surface {
+	struct vmw_resource res;
+	uint32_t flags;
+	uint32_t format;
+	uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
+	struct drm_vmw_size *sizes;
+	uint32_t num_sizes;
+
+	bool scanout;
+
+	/* TODO so far just a extra pointer */
+	struct vmw_cursor_snooper snooper;
+};
+
+struct vmw_fifo_state {
+	unsigned long reserved_size;
+	__le32 *dynamic_buffer;
+	__le32 *static_buffer;
+	__le32 *last_buffer;
+	uint32_t last_data_size;
+	uint32_t last_buffer_size;
+	bool last_buffer_add;
+	unsigned long static_buffer_size;
+	bool using_bounce_buffer;
+	uint32_t capabilities;
+	struct mutex fifo_mutex;
+	struct rw_semaphore rwsem;
+};
+
+struct vmw_relocation {
+	SVGAGuestPtr *location;
+	uint32_t index;
+};
+
+struct vmw_sw_context{
+	struct ida bo_list;
+	uint32_t last_cid;
+	bool cid_valid;
+	uint32_t last_sid;
+	uint32_t sid_translation;
+	bool sid_valid;
+	struct ttm_object_file *tfile;
+	struct list_head validate_nodes;
+	struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS];
+	uint32_t cur_reloc;
+	struct ttm_validate_buffer val_bufs[VMWGFX_MAX_GMRS];
+	uint32_t cur_val_buf;
+};
+
+struct vmw_legacy_display;
+struct vmw_overlay;
+
+struct vmw_master {
+	struct ttm_lock lock;
+};
+
+struct vmw_private {
+	struct ttm_bo_device bdev;
+	struct ttm_bo_global_ref bo_global_ref;
+	struct ttm_global_reference mem_global_ref;
+
+	struct vmw_fifo_state fifo;
+
+	struct drm_device *dev;
+	unsigned long vmw_chipset;
+	unsigned int io_start;
+	uint32_t vram_start;
+	uint32_t vram_size;
+	uint32_t mmio_start;
+	uint32_t mmio_size;
+	uint32_t fb_max_width;
+	uint32_t fb_max_height;
+	__le32 __iomem *mmio_virt;
+	int mmio_mtrr;
+	uint32_t capabilities;
+	uint32_t max_gmr_descriptors;
+	uint32_t max_gmr_ids;
+	struct mutex hw_mutex;
+
+	/*
+	 * VGA registers.
+	 */
+
+	uint32_t vga_width;
+	uint32_t vga_height;
+	uint32_t vga_depth;
+	uint32_t vga_bpp;
+	uint32_t vga_pseudo;
+	uint32_t vga_red_mask;
+	uint32_t vga_blue_mask;
+	uint32_t vga_green_mask;
+
+	/*
+	 * Framebuffer info.
+	 */
+
+	void *fb_info;
+	struct vmw_legacy_display *ldu_priv;
+	struct vmw_overlay *overlay_priv;
+
+	/*
+	 * Context and surface management.
+	 */
+
+	rwlock_t resource_lock;
+	struct idr context_idr;
+	struct idr surface_idr;
+	struct idr stream_idr;
+
+	/*
+	 * Block lastclose from racing with firstopen.
+	 */
+
+	struct mutex init_mutex;
+
+	/*
+	 * A resource manager for kernel-only surfaces and
+	 * contexts.
+	 */
+
+	struct ttm_object_device *tdev;
+
+	/*
+	 * Fencing and IRQs.
+	 */
+
+	atomic_t fence_seq;
+	wait_queue_head_t fence_queue;
+	wait_queue_head_t fifo_queue;
+	atomic_t fence_queue_waiters;
+	atomic_t fifo_queue_waiters;
+	uint32_t last_read_sequence;
+	spinlock_t irq_lock;
+
+	/*
+	 * Device state
+	 */
+
+	uint32_t traces_state;
+	uint32_t enable_state;
+	uint32_t config_done_state;
+
+	/**
+	 * Execbuf
+	 */
+	/**
+	 * Protected by the cmdbuf mutex.
+	 */
+
+	struct vmw_sw_context ctx;
+	uint32_t val_seq;
+	struct mutex cmdbuf_mutex;
+
+	/**
+	 * GMR management. Protected by the lru spinlock.
+	 */
+
+	struct ida gmr_ida;
+	struct list_head gmr_lru;
+
+
+	/**
+	 * Operating mode.
+	 */
+
+	bool stealth;
+	bool is_opened;
+
+	/**
+	 * Master management.
+	 */
+
+	struct vmw_master *active_master;
+	struct vmw_master fbdev_master;
+	struct notifier_block pm_nb;
+};
+
+static inline struct vmw_private *vmw_priv(struct drm_device *dev)
+{
+	return (struct vmw_private *)dev->dev_private;
+}
+
+static inline struct vmw_fpriv *vmw_fpriv(struct drm_file *file_priv)
+{
+	return (struct vmw_fpriv *)file_priv->driver_priv;
+}
+
+static inline struct vmw_master *vmw_master(struct drm_master *master)
+{
+	return (struct vmw_master *) master->driver_priv;
+}
+
+static inline void vmw_write(struct vmw_private *dev_priv,
+			     unsigned int offset, uint32_t value)
+{
+	outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
+	outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT);
+}
+
+static inline uint32_t vmw_read(struct vmw_private *dev_priv,
+				unsigned int offset)
+{
+	uint32_t val;
+
+	outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
+	val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT);
+	return val;
+}
+
+/**
+ * GMR utilities - vmwgfx_gmr.c
+ */
+
+extern int vmw_gmr_bind(struct vmw_private *dev_priv,
+			struct ttm_buffer_object *bo);
+extern void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id);
+
+/**
+ * Resource utilities - vmwgfx_resource.c
+ */
+
+extern struct vmw_resource *vmw_context_alloc(struct vmw_private *dev_priv);
+extern void vmw_resource_unreference(struct vmw_resource **p_res);
+extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res);
+extern int vmw_context_destroy_ioctl(struct drm_device *dev, void *data,
+				     struct drm_file *file_priv);
+extern int vmw_context_define_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+extern int vmw_context_check(struct vmw_private *dev_priv,
+			     struct ttm_object_file *tfile,
+			     int id);
+extern void vmw_surface_res_free(struct vmw_resource *res);
+extern int vmw_surface_init(struct vmw_private *dev_priv,
+			    struct vmw_surface *srf,
+			    void (*res_free) (struct vmw_resource *res));
+extern int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv,
+					  struct ttm_object_file *tfile,
+					  uint32_t handle,
+					  struct vmw_surface **out);
+extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
+				     struct drm_file *file_priv);
+extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
+extern int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
+				       struct drm_file *file_priv);
+extern int vmw_surface_check(struct vmw_private *dev_priv,
+			     struct ttm_object_file *tfile,
+			     uint32_t handle, int *id);
+extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo);
+extern int vmw_dmabuf_init(struct vmw_private *dev_priv,
+			   struct vmw_dma_buffer *vmw_bo,
+			   size_t size, struct ttm_placement *placement,
+			   bool interuptable,
+			   void (*bo_free) (struct ttm_buffer_object *bo));
+extern int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo,
+					 uint32_t cur_validate_node);
+extern void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo);
+extern int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
+				  uint32_t id, struct vmw_dma_buffer **out);
+extern uint32_t vmw_dmabuf_gmr(struct ttm_buffer_object *bo);
+extern void vmw_dmabuf_set_gmr(struct ttm_buffer_object *bo, uint32_t id);
+extern int vmw_gmr_id_alloc(struct vmw_private *dev_priv, uint32_t *p_id);
+extern int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
+				       struct vmw_dma_buffer *bo);
+extern int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv,
+				struct vmw_dma_buffer *bo);
+extern void vmw_dmabuf_gmr_unbind(struct ttm_buffer_object *bo);
+extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+extern int vmw_user_stream_lookup(struct vmw_private *dev_priv,
+				  struct ttm_object_file *tfile,
+				  uint32_t *inout_id,
+				  struct vmw_resource **out);
+
+
+/**
+ * Misc Ioctl functionality - vmwgfx_ioctl.c
+ */
+
+extern int vmw_getparam_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+extern int vmw_fifo_debug_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+
+/**
+ * Fifo utilities - vmwgfx_fifo.c
+ */
+
+extern int vmw_fifo_init(struct vmw_private *dev_priv,
+			 struct vmw_fifo_state *fifo);
+extern void vmw_fifo_release(struct vmw_private *dev_priv,
+			     struct vmw_fifo_state *fifo);
+extern void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes);
+extern void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes);
+extern int vmw_fifo_send_fence(struct vmw_private *dev_priv,
+			       uint32_t *sequence);
+extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
+extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
+extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
+
+/**
+ * TTM glue - vmwgfx_ttm_glue.c
+ */
+
+extern int vmw_ttm_global_init(struct vmw_private *dev_priv);
+extern void vmw_ttm_global_release(struct vmw_private *dev_priv);
+extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/**
+ * TTM buffer object driver - vmwgfx_buffer.c
+ */
+
+extern struct ttm_placement vmw_vram_placement;
+extern struct ttm_placement vmw_vram_ne_placement;
+extern struct ttm_placement vmw_vram_sys_placement;
+extern struct ttm_placement vmw_sys_placement;
+extern struct ttm_bo_driver vmw_bo_driver;
+extern int vmw_dma_quiescent(struct drm_device *dev);
+
+/**
+ * Command submission - vmwgfx_execbuf.c
+ */
+
+extern int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv);
+
+/**
+ * IRQs and wating - vmwgfx_irq.c
+ */
+
+extern irqreturn_t vmw_irq_handler(DRM_IRQ_ARGS);
+extern int vmw_wait_fence(struct vmw_private *dev_priv, bool lazy,
+			  uint32_t sequence, bool interruptible,
+			  unsigned long timeout);
+extern void vmw_irq_preinstall(struct drm_device *dev);
+extern int vmw_irq_postinstall(struct drm_device *dev);
+extern void vmw_irq_uninstall(struct drm_device *dev);
+extern bool vmw_fence_signaled(struct vmw_private *dev_priv,
+			       uint32_t sequence);
+extern int vmw_fence_wait_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+extern int vmw_fallback_wait(struct vmw_private *dev_priv,
+			     bool lazy,
+			     bool fifo_idle,
+			     uint32_t sequence,
+			     bool interruptible,
+			     unsigned long timeout);
+
+/**
+ * Kernel framebuffer - vmwgfx_fb.c
+ */
+
+int vmw_fb_init(struct vmw_private *vmw_priv);
+int vmw_fb_close(struct vmw_private *dev_priv);
+int vmw_fb_off(struct vmw_private *vmw_priv);
+int vmw_fb_on(struct vmw_private *vmw_priv);
+
+/**
+ * Kernel modesetting - vmwgfx_kms.c
+ */
+
+int vmw_kms_init(struct vmw_private *dev_priv);
+int vmw_kms_close(struct vmw_private *dev_priv);
+int vmw_kms_save_vga(struct vmw_private *vmw_priv);
+int vmw_kms_restore_vga(struct vmw_private *vmw_priv);
+int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
+void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv);
+void vmw_kms_cursor_snoop(struct vmw_surface *srf,
+			  struct ttm_object_file *tfile,
+			  struct ttm_buffer_object *bo,
+			  SVGA3dCmdHeader *header);
+
+/**
+ * Overlay control - vmwgfx_overlay.c
+ */
+
+int vmw_overlay_init(struct vmw_private *dev_priv);
+int vmw_overlay_close(struct vmw_private *dev_priv);
+int vmw_overlay_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv);
+int vmw_overlay_stop_all(struct vmw_private *dev_priv);
+int vmw_overlay_resume_all(struct vmw_private *dev_priv);
+int vmw_overlay_pause_all(struct vmw_private *dev_priv);
+int vmw_overlay_claim(struct vmw_private *dev_priv, uint32_t *out);
+int vmw_overlay_unref(struct vmw_private *dev_priv, uint32_t stream_id);
+int vmw_overlay_num_overlays(struct vmw_private *dev_priv);
+int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv);
+
+/**
+ * Inline helper functions
+ */
+
+static inline void vmw_surface_unreference(struct vmw_surface **srf)
+{
+	struct vmw_surface *tmp_srf = *srf;
+	struct vmw_resource *res = &tmp_srf->res;
+	*srf = NULL;
+
+	vmw_resource_unreference(&res);
+}
+
+static inline struct vmw_surface *vmw_surface_reference(struct vmw_surface *srf)
+{
+	(void) vmw_resource_reference(&srf->res);
+	return srf;
+}
+
+static inline void vmw_dmabuf_unreference(struct vmw_dma_buffer **buf)
+{
+	struct vmw_dma_buffer *tmp_buf = *buf;
+	struct ttm_buffer_object *bo = &tmp_buf->base;
+	*buf = NULL;
+
+	ttm_bo_unref(&bo);
+}
+
+static inline struct vmw_dma_buffer *vmw_dmabuf_reference(struct vmw_dma_buffer *buf)
+{
+	if (ttm_bo_reference(&buf->base))
+		return buf;
+	return NULL;
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,716 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "vmwgfx_reg.h"
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_placement.h"
+
+static int vmw_cmd_invalid(struct vmw_private *dev_priv,
+			   struct vmw_sw_context *sw_context,
+			   SVGA3dCmdHeader *header)
+{
+	return capable(CAP_SYS_ADMIN) ? : -EINVAL;
+}
+
+static int vmw_cmd_ok(struct vmw_private *dev_priv,
+		      struct vmw_sw_context *sw_context,
+		      SVGA3dCmdHeader *header)
+{
+	return 0;
+}
+
+static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
+			     struct vmw_sw_context *sw_context,
+			     SVGA3dCmdHeader *header)
+{
+	struct vmw_cid_cmd {
+		SVGA3dCmdHeader header;
+		__le32 cid;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_cid_cmd, header);
+	if (likely(sw_context->cid_valid && cmd->cid == sw_context->last_cid))
+		return 0;
+
+	ret = vmw_context_check(dev_priv, sw_context->tfile, cmd->cid);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Could not find or use context %u\n",
+			  (unsigned) cmd->cid);
+		return ret;
+	}
+
+	sw_context->last_cid = cmd->cid;
+	sw_context->cid_valid = true;
+
+	return 0;
+}
+
+static int vmw_cmd_sid_check(struct vmw_private *dev_priv,
+			     struct vmw_sw_context *sw_context,
+			     uint32_t *sid)
+{
+	if (*sid == SVGA3D_INVALID_ID)
+		return 0;
+
+	if (unlikely((!sw_context->sid_valid  ||
+		      *sid != sw_context->last_sid))) {
+		int real_id;
+		int ret = vmw_surface_check(dev_priv, sw_context->tfile,
+					    *sid, &real_id);
+
+		if (unlikely(ret != 0)) {
+			DRM_ERROR("Could ot find or use surface 0x%08x "
+				  "address 0x%08lx\n",
+				  (unsigned int) *sid,
+				  (unsigned long) sid);
+			return ret;
+		}
+
+		sw_context->last_sid = *sid;
+		sw_context->sid_valid = true;
+		*sid = real_id;
+		sw_context->sid_translation = real_id;
+	} else
+		*sid = sw_context->sid_translation;
+
+	return 0;
+}
+
+
+static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
+					   struct vmw_sw_context *sw_context,
+					   SVGA3dCmdHeader *header)
+{
+	struct vmw_sid_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSetRenderTarget body;
+	} *cmd;
+	int ret;
+
+	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		return ret;
+
+	cmd = container_of(header, struct vmw_sid_cmd, header);
+	ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid);
+	return ret;
+}
+
+static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
+				      struct vmw_sw_context *sw_context,
+				      SVGA3dCmdHeader *header)
+{
+	struct vmw_sid_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSurfaceCopy body;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_sid_cmd, header);
+	ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
+	if (unlikely(ret != 0))
+		return ret;
+	return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
+}
+
+static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
+				     struct vmw_sw_context *sw_context,
+				     SVGA3dCmdHeader *header)
+{
+	struct vmw_sid_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSurfaceStretchBlt body;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_sid_cmd, header);
+	ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
+	if (unlikely(ret != 0))
+		return ret;
+	return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
+}
+
+static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
+					 struct vmw_sw_context *sw_context,
+					 SVGA3dCmdHeader *header)
+{
+	struct vmw_sid_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdBlitSurfaceToScreen body;
+	} *cmd;
+
+	cmd = container_of(header, struct vmw_sid_cmd, header);
+	return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid);
+}
+
+static int vmw_cmd_present_check(struct vmw_private *dev_priv,
+				 struct vmw_sw_context *sw_context,
+				 SVGA3dCmdHeader *header)
+{
+	struct vmw_sid_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdPresent body;
+	} *cmd;
+
+	cmd = container_of(header, struct vmw_sid_cmd, header);
+	return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid);
+}
+
+static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
+				   struct vmw_sw_context *sw_context,
+				   SVGAGuestPtr *ptr,
+				   struct vmw_dma_buffer **vmw_bo_p)
+{
+	struct vmw_dma_buffer *vmw_bo = NULL;
+	struct ttm_buffer_object *bo;
+	uint32_t handle = ptr->gmrId;
+	struct vmw_relocation *reloc;
+	uint32_t cur_validate_node;
+	struct ttm_validate_buffer *val_buf;
+	int ret;
+
+	ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Could not find or use GMR region.\n");
+		return -EINVAL;
+	}
+	bo = &vmw_bo->base;
+
+	if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
+		DRM_ERROR("Max number relocations per submission"
+			  " exceeded\n");
+		ret = -EINVAL;
+		goto out_no_reloc;
+	}
+
+	reloc = &sw_context->relocs[sw_context->cur_reloc++];
+	reloc->location = ptr;
+
+	cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf);
+	if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) {
+		DRM_ERROR("Max number of DMA buffers per submission"
+			  " exceeded.\n");
+		ret = -EINVAL;
+		goto out_no_reloc;
+	}
+
+	reloc->index = cur_validate_node;
+	if (unlikely(cur_validate_node == sw_context->cur_val_buf)) {
+		val_buf = &sw_context->val_bufs[cur_validate_node];
+		val_buf->bo = ttm_bo_reference(bo);
+		val_buf->new_sync_obj_arg = (void *) dev_priv;
+		list_add_tail(&val_buf->head, &sw_context->validate_nodes);
+		++sw_context->cur_val_buf;
+	}
+	*vmw_bo_p = vmw_bo;
+	return 0;
+
+out_no_reloc:
+	vmw_dmabuf_unreference(&vmw_bo);
+	vmw_bo_p = NULL;
+	return ret;
+}
+
+static int vmw_cmd_end_query(struct vmw_private *dev_priv,
+			     struct vmw_sw_context *sw_context,
+			     SVGA3dCmdHeader *header)
+{
+	struct vmw_dma_buffer *vmw_bo;
+	struct vmw_query_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdEndQuery q;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_query_cmd, header);
+	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
+				      &cmd->q.guestResult,
+				      &vmw_bo);
+	if (unlikely(ret != 0))
+		return ret;
+
+	vmw_dmabuf_unreference(&vmw_bo);
+	return 0;
+}
+
+static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
+			      struct vmw_sw_context *sw_context,
+			      SVGA3dCmdHeader *header)
+{
+	struct vmw_dma_buffer *vmw_bo;
+	struct vmw_query_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdWaitForQuery q;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_query_cmd, header);
+	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
+				      &cmd->q.guestResult,
+				      &vmw_bo);
+	if (unlikely(ret != 0))
+		return ret;
+
+	vmw_dmabuf_unreference(&vmw_bo);
+	return 0;
+}
+
+
+static int vmw_cmd_dma(struct vmw_private *dev_priv,
+		       struct vmw_sw_context *sw_context,
+		       SVGA3dCmdHeader *header)
+{
+	struct vmw_dma_buffer *vmw_bo = NULL;
+	struct ttm_buffer_object *bo;
+	struct vmw_surface *srf = NULL;
+	struct vmw_dma_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSurfaceDMA dma;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_dma_cmd, header);
+	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
+				      &cmd->dma.guest.ptr,
+				      &vmw_bo);
+	if (unlikely(ret != 0))
+		return ret;
+
+	bo = &vmw_bo->base;
+	ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile,
+					     cmd->dma.host.sid, &srf);
+	if (ret) {
+		DRM_ERROR("could not find surface\n");
+		goto out_no_reloc;
+	}
+
+	/**
+	 * Patch command stream with device SID.
+	 */
+
+	cmd->dma.host.sid = srf->res.id;
+	vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header);
+	/**
+	 * FIXME: May deadlock here when called from the
+	 * command parsing code.
+	 */
+	vmw_surface_unreference(&srf);
+
+out_no_reloc:
+	vmw_dmabuf_unreference(&vmw_bo);
+	return ret;
+}
+
+static int vmw_cmd_draw(struct vmw_private *dev_priv,
+			struct vmw_sw_context *sw_context,
+			SVGA3dCmdHeader *header)
+{
+	struct vmw_draw_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdDrawPrimitives body;
+	} *cmd;
+	SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
+		(unsigned long)header + sizeof(*cmd));
+	SVGA3dPrimitiveRange *range;
+	uint32_t i;
+	uint32_t maxnum;
+	int ret;
+
+	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		return ret;
+
+	cmd = container_of(header, struct vmw_draw_cmd, header);
+	maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
+
+	if (unlikely(cmd->body.numVertexDecls > maxnum)) {
+		DRM_ERROR("Illegal number of vertex declarations.\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
+		ret = vmw_cmd_sid_check(dev_priv, sw_context,
+					&decl->array.surfaceId);
+		if (unlikely(ret != 0))
+			return ret;
+	}
+
+	maxnum = (header->size - sizeof(cmd->body) -
+		  cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
+	if (unlikely(cmd->body.numRanges > maxnum)) {
+		DRM_ERROR("Illegal number of index ranges.\n");
+		return -EINVAL;
+	}
+
+	range = (SVGA3dPrimitiveRange *) decl;
+	for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
+		ret = vmw_cmd_sid_check(dev_priv, sw_context,
+					&range->indexArray.surfaceId);
+		if (unlikely(ret != 0))
+			return ret;
+	}
+	return 0;
+}
+
+
+static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
+			     struct vmw_sw_context *sw_context,
+			     SVGA3dCmdHeader *header)
+{
+	struct vmw_tex_state_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSetTextureState state;
+	};
+
+	SVGA3dTextureState *last_state = (SVGA3dTextureState *)
+	  ((unsigned long) header + header->size + sizeof(header));
+	SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
+		((unsigned long) header + sizeof(struct vmw_tex_state_cmd));
+	int ret;
+
+	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		return ret;
+
+	for (; cur_state < last_state; ++cur_state) {
+		if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
+			continue;
+
+		ret = vmw_cmd_sid_check(dev_priv, sw_context,
+					&cur_state->value);
+		if (unlikely(ret != 0))
+			return ret;
+	}
+
+	return 0;
+}
+
+
+typedef int (*vmw_cmd_func) (struct vmw_private *,
+			     struct vmw_sw_context *,
+			     SVGA3dCmdHeader *);
+
+#define VMW_CMD_DEF(cmd, func) \
+	[cmd - SVGA_3D_CMD_BASE] = func
+
+static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = {
+	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid),
+	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid),
+	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma),
+	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid),
+	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
+		    &vmw_cmd_set_render_target_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw),
+	VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check),
+	VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query),
+	VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query),
+	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok),
+	VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
+		    &vmw_cmd_blt_surf_screen_check)
+};
+
+static int vmw_cmd_check(struct vmw_private *dev_priv,
+			 struct vmw_sw_context *sw_context,
+			 void *buf, uint32_t *size)
+{
+	uint32_t cmd_id;
+	uint32_t size_remaining = *size;
+	SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
+	int ret;
+
+	cmd_id = ((uint32_t *)buf)[0];
+	if (cmd_id == SVGA_CMD_UPDATE) {
+		*size = 5 << 2;
+		return 0;
+	}
+
+	cmd_id = le32_to_cpu(header->id);
+	*size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader);
+
+	cmd_id -= SVGA_3D_CMD_BASE;
+	if (unlikely(*size > size_remaining))
+		goto out_err;
+
+	if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
+		goto out_err;
+
+	ret = vmw_cmd_funcs[cmd_id](dev_priv, sw_context, header);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	return 0;
+out_err:
+	DRM_ERROR("Illegal / Invalid SVGA3D command: %d\n",
+		  cmd_id + SVGA_3D_CMD_BASE);
+	return -EINVAL;
+}
+
+static int vmw_cmd_check_all(struct vmw_private *dev_priv,
+			     struct vmw_sw_context *sw_context,
+			     void *buf, uint32_t size)
+{
+	int32_t cur_size = size;
+	int ret;
+
+	while (cur_size > 0) {
+		size = cur_size;
+		ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
+		if (unlikely(ret != 0))
+			return ret;
+		buf = (void *)((unsigned long) buf + size);
+		cur_size -= size;
+	}
+
+	if (unlikely(cur_size != 0)) {
+		DRM_ERROR("Command verifier out of sync.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void vmw_free_relocations(struct vmw_sw_context *sw_context)
+{
+	sw_context->cur_reloc = 0;
+}
+
+static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
+{
+	uint32_t i;
+	struct vmw_relocation *reloc;
+	struct ttm_validate_buffer *validate;
+	struct ttm_buffer_object *bo;
+
+	for (i = 0; i < sw_context->cur_reloc; ++i) {
+		reloc = &sw_context->relocs[i];
+		validate = &sw_context->val_bufs[reloc->index];
+		bo = validate->bo;
+		reloc->location->offset += bo->offset;
+		reloc->location->gmrId = vmw_dmabuf_gmr(bo);
+	}
+	vmw_free_relocations(sw_context);
+}
+
+static void vmw_clear_validations(struct vmw_sw_context *sw_context)
+{
+	struct ttm_validate_buffer *entry, *next;
+
+	list_for_each_entry_safe(entry, next, &sw_context->validate_nodes,
+				 head) {
+		list_del(&entry->head);
+		vmw_dmabuf_validate_clear(entry->bo);
+		ttm_bo_unref(&entry->bo);
+		sw_context->cur_val_buf--;
+	}
+	BUG_ON(sw_context->cur_val_buf != 0);
+}
+
+static int vmw_validate_single_buffer(struct vmw_private *dev_priv,
+				      struct ttm_buffer_object *bo)
+{
+	int ret;
+
+	if (vmw_dmabuf_gmr(bo) != SVGA_GMR_NULL)
+		return 0;
+
+	/**
+	 * Put BO in VRAM, only if there is space.
+	 */
+
+	ret = ttm_bo_validate(bo, &vmw_vram_sys_placement, true, false);
+	if (unlikely(ret == -ERESTARTSYS))
+		return ret;
+
+	/**
+	 * Otherwise, set it up as GMR.
+	 */
+
+	if (vmw_dmabuf_gmr(bo) != SVGA_GMR_NULL)
+		return 0;
+
+	ret = vmw_gmr_bind(dev_priv, bo);
+	if (likely(ret == 0 || ret == -ERESTARTSYS))
+		return ret;
+
+	/**
+	 * If that failed, try VRAM again, this time evicting
+	 * previous contents.
+	 */
+
+	ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false);
+	return ret;
+}
+
+
+static int vmw_validate_buffers(struct vmw_private *dev_priv,
+				struct vmw_sw_context *sw_context)
+{
+	struct ttm_validate_buffer *entry;
+	int ret;
+
+	list_for_each_entry(entry, &sw_context->validate_nodes, head) {
+		ret = vmw_validate_single_buffer(dev_priv, entry->bo);
+		if (unlikely(ret != 0))
+			return ret;
+	}
+	return 0;
+}
+
+int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data;
+	struct drm_vmw_fence_rep fence_rep;
+	struct drm_vmw_fence_rep __user *user_fence_rep;
+	int ret;
+	void *user_cmd;
+	void *cmd;
+	uint32_t sequence;
+	struct vmw_sw_context *sw_context = &dev_priv->ctx;
+	struct vmw_master *vmaster = vmw_master(file_priv->master);
+
+	ret = ttm_read_lock(&vmaster->lock, true);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
+	if (unlikely(ret != 0)) {
+		ret = -ERESTARTSYS;
+		goto out_no_cmd_mutex;
+	}
+
+	cmd = vmw_fifo_reserve(dev_priv, arg->command_size);
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Failed reserving fifo space for commands.\n");
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	user_cmd = (void __user *)(unsigned long)arg->commands;
+	ret = copy_from_user(cmd, user_cmd, arg->command_size);
+
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed copying commands.\n");
+		goto out_commit;
+	}
+
+	sw_context->tfile = vmw_fpriv(file_priv)->tfile;
+	sw_context->cid_valid = false;
+	sw_context->sid_valid = false;
+	sw_context->cur_reloc = 0;
+	sw_context->cur_val_buf = 0;
+
+	INIT_LIST_HEAD(&sw_context->validate_nodes);
+
+	ret = vmw_cmd_check_all(dev_priv, sw_context, cmd, arg->command_size);
+	if (unlikely(ret != 0))
+		goto out_err;
+	ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes,
+				     dev_priv->val_seq++);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	ret = vmw_validate_buffers(dev_priv, sw_context);
+	if (unlikely(ret != 0))
+		goto out_err;
+
+	vmw_apply_relocations(sw_context);
+	vmw_fifo_commit(dev_priv, arg->command_size);
+
+	ret = vmw_fifo_send_fence(dev_priv, &sequence);
+
+	ttm_eu_fence_buffer_objects(&sw_context->validate_nodes,
+				    (void *)(unsigned long) sequence);
+	vmw_clear_validations(sw_context);
+	mutex_unlock(&dev_priv->cmdbuf_mutex);
+
+	/*
+	 * This error is harmless, because if fence submission fails,
+	 * vmw_fifo_send_fence will sync.
+	 */
+
+	if (ret != 0)
+		DRM_ERROR("Fence submission error. Syncing.\n");
+
+	fence_rep.error = ret;
+	fence_rep.fence_seq = (uint64_t) sequence;
+
+	user_fence_rep = (struct drm_vmw_fence_rep __user *)
+	    (unsigned long)arg->fence_rep;
+
+	/*
+	 * copy_to_user errors will be detected by user space not
+	 * seeing fence_rep::error filled in.
+	 */
+
+	ret = copy_to_user(user_fence_rep, &fence_rep, sizeof(fence_rep));
+
+	vmw_kms_cursor_post_execbuf(dev_priv);
+	ttm_read_unlock(&vmaster->lock);
+	return 0;
+out_err:
+	vmw_free_relocations(sw_context);
+	ttm_eu_backoff_reservation(&sw_context->validate_nodes);
+	vmw_clear_validations(sw_context);
+out_commit:
+	vmw_fifo_commit(dev_priv, 0);
+out_unlock:
+	mutex_unlock(&dev_priv->cmdbuf_mutex);
+out_no_cmd_mutex:
+	ttm_read_unlock(&vmaster->lock);
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,737 @@
+/**************************************************************************
+ *
+ * Copyright © 2007 David Airlie
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+
+#include "ttm/ttm_placement.h"
+
+#define VMW_DIRTY_DELAY (HZ / 30)
+
+struct vmw_fb_par {
+	struct vmw_private *vmw_priv;
+
+	void *vmalloc;
+
+	struct vmw_dma_buffer *vmw_bo;
+	struct ttm_bo_kmap_obj map;
+
+	u32 pseudo_palette[17];
+
+	unsigned depth;
+	unsigned bpp;
+
+	unsigned max_width;
+	unsigned max_height;
+
+	void *bo_ptr;
+	unsigned bo_size;
+	bool bo_iowrite;
+
+	struct {
+		spinlock_t lock;
+		bool active;
+		unsigned x1;
+		unsigned y1;
+		unsigned x2;
+		unsigned y2;
+	} dirty;
+};
+
+static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *info)
+{
+	struct vmw_fb_par *par = info->par;
+	u32 *pal = par->pseudo_palette;
+
+	if (regno > 15) {
+		DRM_ERROR("Bad regno %u.\n", regno);
+		return 1;
+	}
+
+	switch (par->depth) {
+	case 24:
+	case 32:
+		pal[regno] = ((red & 0xff00) << 8) |
+			      (green & 0xff00) |
+			     ((blue  & 0xff00) >> 8);
+		break;
+	default:
+		DRM_ERROR("Bad depth %u, bpp %u.\n", par->depth, par->bpp);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int vmw_fb_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info)
+{
+	int depth = var->bits_per_pixel;
+	struct vmw_fb_par *par = info->par;
+	struct vmw_private *vmw_priv = par->vmw_priv;
+
+	switch (var->bits_per_pixel) {
+	case 32:
+		depth = (var->transp.length > 0) ? 32 : 24;
+		break;
+	default:
+		DRM_ERROR("Bad bpp %u.\n", var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	switch (depth) {
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		break;
+	case 32:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.length = 8;
+		var->transp.offset = 24;
+		break;
+	default:
+		DRM_ERROR("Bad depth %u.\n", depth);
+		return -EINVAL;
+	}
+
+	/* without multimon its hard to resize */
+	if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) &&
+	    (var->xres != par->max_width ||
+	     var->yres != par->max_height)) {
+		DRM_ERROR("Tried to resize, but we don't have multimon\n");
+		return -EINVAL;
+	}
+
+	if (var->xres > par->max_width ||
+	    var->yres > par->max_height) {
+		DRM_ERROR("Requested geom can not fit in framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vmw_fb_set_par(struct fb_info *info)
+{
+	struct vmw_fb_par *par = info->par;
+	struct vmw_private *vmw_priv = par->vmw_priv;
+
+	if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
+		vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+
+		vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
+		vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width);
+		vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height);
+		vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp);
+		vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth);
+		vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
+		vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
+		vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
+
+		/* TODO check if pitch and offset changes */
+
+		vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, info->var.yoffset);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+	} else {
+		vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres);
+		vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres);
+
+		/* TODO check if pitch and offset changes */
+	}
+
+	return 0;
+}
+
+static int vmw_fb_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info)
+{
+	return 0;
+}
+
+static int vmw_fb_blank(int blank, struct fb_info *info)
+{
+	return 0;
+}
+
+/*
+ * Dirty code
+ */
+
+static void vmw_fb_dirty_flush(struct vmw_fb_par *par)
+{
+	struct vmw_private *vmw_priv = par->vmw_priv;
+	struct fb_info *info = vmw_priv->fb_info;
+	int stride = (info->fix.line_length / 4);
+	int *src = (int *)info->screen_base;
+	__le32 __iomem *vram_mem = par->bo_ptr;
+	unsigned long flags;
+	unsigned x, y, w, h;
+	int i, k;
+	struct {
+		uint32_t header;
+		SVGAFifoCmdUpdate body;
+	} *cmd;
+
+	spin_lock_irqsave(&par->dirty.lock, flags);
+	if (!par->dirty.active) {
+		spin_unlock_irqrestore(&par->dirty.lock, flags);
+		return;
+	}
+	x = par->dirty.x1;
+	y = par->dirty.y1;
+	w = min(par->dirty.x2, info->var.xres) - x;
+	h = min(par->dirty.y2, info->var.yres) - y;
+	par->dirty.x1 = par->dirty.x2 = 0;
+	par->dirty.y1 = par->dirty.y2 = 0;
+	spin_unlock_irqrestore(&par->dirty.lock, flags);
+
+	for (i = y * stride; i < info->fix.smem_len / 4; i += stride) {
+		for (k = i+x; k < i+x+w && k < info->fix.smem_len / 4; k++)
+			iowrite32(src[k], vram_mem + k);
+	}
+
+#if 0
+	DRM_INFO("%s, (%u, %u) (%ux%u)\n", __func__, x, y, w, h);
+#endif
+
+	cmd = vmw_fifo_reserve(vmw_priv, sizeof(*cmd));
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed.\n");
+		return;
+	}
+
+	cmd->header = cpu_to_le32(SVGA_CMD_UPDATE);
+	cmd->body.x = cpu_to_le32(x);
+	cmd->body.y = cpu_to_le32(y);
+	cmd->body.width = cpu_to_le32(w);
+	cmd->body.height = cpu_to_le32(h);
+	vmw_fifo_commit(vmw_priv, sizeof(*cmd));
+}
+
+static void vmw_fb_dirty_mark(struct vmw_fb_par *par,
+			      unsigned x1, unsigned y1,
+			      unsigned width, unsigned height)
+{
+	struct fb_info *info = par->vmw_priv->fb_info;
+	unsigned long flags;
+	unsigned x2 = x1 + width;
+	unsigned y2 = y1 + height;
+
+	spin_lock_irqsave(&par->dirty.lock, flags);
+	if (par->dirty.x1 == par->dirty.x2) {
+		par->dirty.x1 = x1;
+		par->dirty.y1 = y1;
+		par->dirty.x2 = x2;
+		par->dirty.y2 = y2;
+		/* if we are active start the dirty work
+		 * we share the work with the defio system */
+		if (par->dirty.active)
+			schedule_delayed_work(&info->deferred_work, VMW_DIRTY_DELAY);
+	} else {
+		if (x1 < par->dirty.x1)
+			par->dirty.x1 = x1;
+		if (y1 < par->dirty.y1)
+			par->dirty.y1 = y1;
+		if (x2 > par->dirty.x2)
+			par->dirty.x2 = x2;
+		if (y2 > par->dirty.y2)
+			par->dirty.y2 = y2;
+	}
+	spin_unlock_irqrestore(&par->dirty.lock, flags);
+}
+
+static void vmw_deferred_io(struct fb_info *info,
+			    struct list_head *pagelist)
+{
+	struct vmw_fb_par *par = info->par;
+	unsigned long start, end, min, max;
+	unsigned long flags;
+	struct page *page;
+	int y1, y2;
+
+	min = ULONG_MAX;
+	max = 0;
+	list_for_each_entry(page, pagelist, lru) {
+		start = page->index << PAGE_SHIFT;
+		end = start + PAGE_SIZE - 1;
+		min = min(min, start);
+		max = max(max, end);
+	}
+
+	if (min < max) {
+		y1 = min / info->fix.line_length;
+		y2 = (max / info->fix.line_length) + 1;
+
+		spin_lock_irqsave(&par->dirty.lock, flags);
+		par->dirty.x1 = 0;
+		par->dirty.y1 = y1;
+		par->dirty.x2 = info->var.xres;
+		par->dirty.y2 = y2;
+		spin_unlock_irqrestore(&par->dirty.lock, flags);
+	}
+
+	vmw_fb_dirty_flush(par);
+};
+
+struct fb_deferred_io vmw_defio = {
+	.delay		= VMW_DIRTY_DELAY,
+	.deferred_io	= vmw_deferred_io,
+};
+
+/*
+ * Draw code
+ */
+
+static void vmw_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	cfb_fillrect(info, rect);
+	vmw_fb_dirty_mark(info->par, rect->dx, rect->dy,
+			  rect->width, rect->height);
+}
+
+static void vmw_fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+{
+	cfb_copyarea(info, region);
+	vmw_fb_dirty_mark(info->par, region->dx, region->dy,
+			  region->width, region->height);
+}
+
+static void vmw_fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	cfb_imageblit(info, image);
+	vmw_fb_dirty_mark(info->par, image->dx, image->dy,
+			  image->width, image->height);
+}
+
+/*
+ * Bring up code
+ */
+
+static struct fb_ops vmw_fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = vmw_fb_check_var,
+	.fb_set_par = vmw_fb_set_par,
+	.fb_setcolreg = vmw_fb_setcolreg,
+	.fb_fillrect = vmw_fb_fillrect,
+	.fb_copyarea = vmw_fb_copyarea,
+	.fb_imageblit = vmw_fb_imageblit,
+	.fb_pan_display = vmw_fb_pan_display,
+	.fb_blank = vmw_fb_blank,
+};
+
+static int vmw_fb_create_bo(struct vmw_private *vmw_priv,
+			    size_t size, struct vmw_dma_buffer **out)
+{
+	struct vmw_dma_buffer *vmw_bo;
+	struct ttm_placement ne_placement = vmw_vram_ne_placement;
+	int ret;
+
+	ne_placement.lpfn = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	/* interuptable? */
+	ret = ttm_write_lock(&vmw_priv->fbdev_master.lock, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	vmw_bo = kmalloc(sizeof(*vmw_bo), GFP_KERNEL);
+	if (!vmw_bo)
+		goto err_unlock;
+
+	ret = vmw_dmabuf_init(vmw_priv, vmw_bo, size,
+			      &ne_placement,
+			      false,
+			      &vmw_dmabuf_bo_free);
+	if (unlikely(ret != 0))
+		goto err_unlock; /* init frees the buffer on failure */
+
+	*out = vmw_bo;
+
+	ttm_write_unlock(&vmw_priv->fbdev_master.lock);
+
+	return 0;
+
+err_unlock:
+	ttm_write_unlock(&vmw_priv->fbdev_master.lock);
+	return ret;
+}
+
+int vmw_fb_init(struct vmw_private *vmw_priv)
+{
+	struct device *device = &vmw_priv->dev->pdev->dev;
+	struct vmw_fb_par *par;
+	struct fb_info *info;
+	unsigned initial_width, initial_height;
+	unsigned fb_width, fb_height;
+	unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size;
+	int ret;
+
+	initial_width = 800;
+	initial_height = 600;
+
+	fb_bbp = 32;
+	fb_depth = 24;
+
+	if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
+		fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
+		fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
+	} else {
+		fb_width = min(vmw_priv->fb_max_width, initial_width);
+		fb_height = min(vmw_priv->fb_max_height, initial_height);
+	}
+
+	initial_width = min(fb_width, initial_width);
+	initial_height = min(fb_height, initial_height);
+
+	vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width);
+	vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height);
+	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp);
+	vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth);
+	vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000);
+	vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
+	vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
+
+	fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE);
+	fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET);
+	fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE);
+
+	DRM_DEBUG("width  %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH));
+	DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT));
+	DRM_DEBUG("width  %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH));
+	DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT));
+	DRM_DEBUG("bpp    %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL));
+	DRM_DEBUG("depth  %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH));
+	DRM_DEBUG("bpl    %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE));
+	DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK));
+	DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK));
+	DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK));
+	DRM_DEBUG("fb_offset 0x%08x\n", fb_offset);
+	DRM_DEBUG("fb_pitch  %u\n", fb_pitch);
+	DRM_DEBUG("fb_size   %u kiB\n", fb_size / 1024);
+
+	info = framebuffer_alloc(sizeof(*par), device);
+	if (!info)
+		return -ENOMEM;
+
+	/*
+	 * Par
+	 */
+	vmw_priv->fb_info = info;
+	par = info->par;
+	par->vmw_priv = vmw_priv;
+	par->depth = fb_depth;
+	par->bpp = fb_bbp;
+	par->vmalloc = NULL;
+	par->max_width = fb_width;
+	par->max_height = fb_height;
+
+	/*
+	 * Create buffers and alloc memory
+	 */
+	par->vmalloc = vmalloc(fb_size);
+	if (unlikely(par->vmalloc == NULL)) {
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
+	ret = vmw_fb_create_bo(vmw_priv, fb_size, &par->vmw_bo);
+	if (unlikely(ret != 0))
+		goto err_free;
+
+	ret = ttm_bo_kmap(&par->vmw_bo->base,
+			  0,
+			  par->vmw_bo->base.num_pages,
+			  &par->map);
+	if (unlikely(ret != 0))
+		goto err_unref;
+	par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
+	par->bo_size = fb_size;
+
+	/*
+	 * Fixed and var
+	 */
+	strcpy(info->fix.id, "svgadrmfb");
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+	info->fix.type_aux = 0;
+	info->fix.xpanstep = 1; /* doing it in hw */
+	info->fix.ypanstep = 1; /* doing it in hw */
+	info->fix.ywrapstep = 0;
+	info->fix.accel = FB_ACCEL_NONE;
+	info->fix.line_length = fb_pitch;
+
+	info->fix.smem_start = 0;
+	info->fix.smem_len = fb_size;
+
+	info->fix.mmio_start = 0;
+	info->fix.mmio_len = 0;
+
+	info->pseudo_palette = par->pseudo_palette;
+	info->screen_base = par->vmalloc;
+	info->screen_size = fb_size;
+
+	info->flags = FBINFO_DEFAULT;
+	info->fbops = &vmw_fb_ops;
+
+	/* 24 depth per default */
+	info->var.red.offset = 16;
+	info->var.green.offset = 8;
+	info->var.blue.offset = 0;
+	info->var.red.length = 8;
+	info->var.green.length = 8;
+	info->var.blue.length = 8;
+	info->var.transp.offset = 0;
+	info->var.transp.length = 0;
+
+	info->var.xres_virtual = fb_width;
+	info->var.yres_virtual = fb_height;
+	info->var.bits_per_pixel = par->bpp;
+	info->var.xoffset = 0;
+	info->var.yoffset = 0;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.height = -1;
+	info->var.width = -1;
+
+	info->var.xres = initial_width;
+	info->var.yres = initial_height;
+
+#if 0
+	info->pixmap.size = 64*1024;
+	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+	info->pixmap.scan_align = 1;
+#else
+	info->pixmap.size = 0;
+	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+	info->pixmap.scan_align = 1;
+#endif
+
+	info->aperture_base = vmw_priv->vram_start;
+	info->aperture_size = vmw_priv->vram_size;
+
+	/*
+	 * Dirty & Deferred IO
+	 */
+	par->dirty.x1 = par->dirty.x2 = 0;
+	par->dirty.y1 = par->dirty.y1 = 0;
+	par->dirty.active = true;
+	spin_lock_init(&par->dirty.lock);
+	info->fbdefio = &vmw_defio;
+	fb_deferred_io_init(info);
+
+	ret = register_framebuffer(info);
+	if (unlikely(ret != 0))
+		goto err_defio;
+
+	return 0;
+
+err_defio:
+	fb_deferred_io_cleanup(info);
+	ttm_bo_kunmap(&par->map);
+err_unref:
+	ttm_bo_unref((struct ttm_buffer_object **)&par->vmw_bo);
+err_free:
+	vfree(par->vmalloc);
+	framebuffer_release(info);
+	vmw_priv->fb_info = NULL;
+
+	return ret;
+}
+
+int vmw_fb_close(struct vmw_private *vmw_priv)
+{
+	struct fb_info *info;
+	struct vmw_fb_par *par;
+	struct ttm_buffer_object *bo;
+
+	if (!vmw_priv->fb_info)
+		return 0;
+
+	info = vmw_priv->fb_info;
+	par = info->par;
+	bo = &par->vmw_bo->base;
+	par->vmw_bo = NULL;
+
+	/* ??? order */
+	fb_deferred_io_cleanup(info);
+	unregister_framebuffer(info);
+
+	ttm_bo_kunmap(&par->map);
+	ttm_bo_unref(&bo);
+
+	vfree(par->vmalloc);
+	framebuffer_release(info);
+
+	return 0;
+}
+
+int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv,
+			 struct vmw_dma_buffer *vmw_bo)
+{
+	struct ttm_buffer_object *bo = &vmw_bo->base;
+	int ret = 0;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = ttm_bo_validate(bo, &vmw_sys_placement, false, false);
+	ttm_bo_unreserve(bo);
+
+	return ret;
+}
+
+int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv,
+				struct vmw_dma_buffer *vmw_bo)
+{
+	struct ttm_buffer_object *bo = &vmw_bo->base;
+	struct ttm_placement ne_placement = vmw_vram_ne_placement;
+	int ret = 0;
+
+	ne_placement.lpfn = bo->num_pages;
+
+	/* interuptable? */
+	ret = ttm_write_lock(&vmw_priv->active_master->lock, false);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = ttm_bo_reserve(bo, false, false, false, 0);
+	if (unlikely(ret != 0))
+		goto err_unlock;
+
+	ret = ttm_bo_validate(bo, &ne_placement, false, false);
+	ttm_bo_unreserve(bo);
+err_unlock:
+	ttm_write_unlock(&vmw_priv->active_master->lock);
+
+	return ret;
+}
+
+int vmw_fb_off(struct vmw_private *vmw_priv)
+{
+	struct fb_info *info;
+	struct vmw_fb_par *par;
+	unsigned long flags;
+
+	if (!vmw_priv->fb_info)
+		return -EINVAL;
+
+	info = vmw_priv->fb_info;
+	par = info->par;
+
+	spin_lock_irqsave(&par->dirty.lock, flags);
+	par->dirty.active = false;
+	spin_unlock_irqrestore(&par->dirty.lock, flags);
+
+	flush_scheduled_work();
+
+	par->bo_ptr = NULL;
+	ttm_bo_kunmap(&par->map);
+
+	vmw_dmabuf_from_vram(vmw_priv, par->vmw_bo);
+
+	return 0;
+}
+
+int vmw_fb_on(struct vmw_private *vmw_priv)
+{
+	struct fb_info *info;
+	struct vmw_fb_par *par;
+	unsigned long flags;
+	bool dummy;
+	int ret;
+
+	if (!vmw_priv->fb_info)
+		return -EINVAL;
+
+	info = vmw_priv->fb_info;
+	par = info->par;
+
+	/* we are already active */
+	if (par->bo_ptr != NULL)
+		return 0;
+
+	/* Make sure that all overlays are stoped when we take over */
+	vmw_overlay_stop_all(vmw_priv);
+
+	ret = vmw_dmabuf_to_start_of_vram(vmw_priv, par->vmw_bo);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("could not move buffer to start of VRAM\n");
+		goto err_no_buffer;
+	}
+
+	ret = ttm_bo_kmap(&par->vmw_bo->base,
+			  0,
+			  par->vmw_bo->base.num_pages,
+			  &par->map);
+	BUG_ON(ret != 0);
+	par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &dummy);
+
+	spin_lock_irqsave(&par->dirty.lock, flags);
+	par->dirty.active = true;
+	spin_unlock_irqrestore(&par->dirty.lock, flags);
+
+err_no_buffer:
+	vmw_fb_set_par(info);
+
+	vmw_fb_dirty_mark(par, 0, 0, info->var.xres, info->var.yres);
+
+	/* If there already was stuff dirty we wont
+	 * schedule a new work, so lets do it now */
+	schedule_delayed_work(&info->deferred_work, 0);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,538 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "drmP.h"
+#include "ttm/ttm_placement.h"
+
+bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t fifo_min, hwversion;
+
+	fifo_min = ioread32(fifo_mem  + SVGA_FIFO_MIN);
+	if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
+		return false;
+
+	hwversion = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION);
+	if (hwversion == 0)
+		return false;
+
+	if (hwversion < SVGA3D_HWVERSION_WS65_B1)
+		return false;
+
+	return true;
+}
+
+int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t max;
+	uint32_t min;
+	uint32_t dummy;
+	int ret;
+
+	fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE;
+	fifo->static_buffer = vmalloc(fifo->static_buffer_size);
+	if (unlikely(fifo->static_buffer == NULL))
+		return -ENOMEM;
+
+	fifo->last_buffer_size = VMWGFX_FIFO_STATIC_SIZE;
+	fifo->last_data_size = 0;
+	fifo->last_buffer_add = false;
+	fifo->last_buffer = vmalloc(fifo->last_buffer_size);
+	if (unlikely(fifo->last_buffer == NULL)) {
+		ret = -ENOMEM;
+		goto out_err;
+	}
+
+	fifo->dynamic_buffer = NULL;
+	fifo->reserved_size = 0;
+	fifo->using_bounce_buffer = false;
+
+	mutex_init(&fifo->fifo_mutex);
+	init_rwsem(&fifo->rwsem);
+
+	/*
+	 * Allow mapping the first page read-only to user-space.
+	 */
+
+	DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH));
+	DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT));
+	DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL));
+
+	mutex_lock(&dev_priv->hw_mutex);
+	dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
+	dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
+	vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
+
+	min = 4;
+	if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)
+		min = vmw_read(dev_priv, SVGA_REG_MEM_REGS);
+	min <<= 2;
+
+	if (min < PAGE_SIZE)
+		min = PAGE_SIZE;
+
+	iowrite32(min, fifo_mem + SVGA_FIFO_MIN);
+	iowrite32(dev_priv->mmio_size, fifo_mem + SVGA_FIFO_MAX);
+	wmb();
+	iowrite32(min,  fifo_mem + SVGA_FIFO_NEXT_CMD);
+	iowrite32(min,  fifo_mem + SVGA_FIFO_STOP);
+	iowrite32(0, fifo_mem + SVGA_FIFO_BUSY);
+	mb();
+
+	vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1);
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	max = ioread32(fifo_mem + SVGA_FIFO_MAX);
+	min = ioread32(fifo_mem  + SVGA_FIFO_MIN);
+	fifo->capabilities = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES);
+
+	DRM_INFO("Fifo max 0x%08x min 0x%08x cap 0x%08x\n",
+		 (unsigned int) max,
+		 (unsigned int) min,
+		 (unsigned int) fifo->capabilities);
+
+	atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence);
+	iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE);
+
+	return vmw_fifo_send_fence(dev_priv, &dummy);
+out_err:
+	vfree(fifo->static_buffer);
+	fifo->static_buffer = NULL;
+	return ret;
+}
+
+void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+
+	mutex_lock(&dev_priv->hw_mutex);
+
+	if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) {
+		iowrite32(1, fifo_mem + SVGA_FIFO_BUSY);
+		vmw_write(dev_priv, SVGA_REG_SYNC, reason);
+	}
+
+	mutex_unlock(&dev_priv->hw_mutex);
+}
+
+void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+
+	mutex_lock(&dev_priv->hw_mutex);
+
+	while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0)
+		vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC);
+
+	dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE);
+
+	vmw_write(dev_priv, SVGA_REG_CONFIG_DONE,
+		  dev_priv->config_done_state);
+	vmw_write(dev_priv, SVGA_REG_ENABLE,
+		  dev_priv->enable_state);
+
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	if (likely(fifo->last_buffer != NULL)) {
+		vfree(fifo->last_buffer);
+		fifo->last_buffer = NULL;
+	}
+
+	if (likely(fifo->static_buffer != NULL)) {
+		vfree(fifo->static_buffer);
+		fifo->static_buffer = NULL;
+	}
+
+	if (likely(fifo->dynamic_buffer != NULL)) {
+		vfree(fifo->dynamic_buffer);
+		fifo->dynamic_buffer = NULL;
+	}
+}
+
+static bool vmw_fifo_is_full(struct vmw_private *dev_priv, uint32_t bytes)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t max = ioread32(fifo_mem + SVGA_FIFO_MAX);
+	uint32_t next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD);
+	uint32_t min = ioread32(fifo_mem + SVGA_FIFO_MIN);
+	uint32_t stop = ioread32(fifo_mem + SVGA_FIFO_STOP);
+
+	return ((max - next_cmd) + (stop - min) <= bytes);
+}
+
+static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv,
+			       uint32_t bytes, bool interruptible,
+			       unsigned long timeout)
+{
+	int ret = 0;
+	unsigned long end_jiffies = jiffies + timeout;
+	DEFINE_WAIT(__wait);
+
+	DRM_INFO("Fifo wait noirq.\n");
+
+	for (;;) {
+		prepare_to_wait(&dev_priv->fifo_queue, &__wait,
+				(interruptible) ?
+				TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+		if (!vmw_fifo_is_full(dev_priv, bytes))
+			break;
+		if (time_after_eq(jiffies, end_jiffies)) {
+			ret = -EBUSY;
+			DRM_ERROR("SVGA device lockup.\n");
+			break;
+		}
+		schedule_timeout(1);
+		if (interruptible && signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+	finish_wait(&dev_priv->fifo_queue, &__wait);
+	wake_up_all(&dev_priv->fifo_queue);
+	DRM_INFO("Fifo noirq exit.\n");
+	return ret;
+}
+
+static int vmw_fifo_wait(struct vmw_private *dev_priv,
+			 uint32_t bytes, bool interruptible,
+			 unsigned long timeout)
+{
+	long ret = 1L;
+	unsigned long irq_flags;
+
+	if (likely(!vmw_fifo_is_full(dev_priv, bytes)))
+		return 0;
+
+	vmw_fifo_ping_host(dev_priv, SVGA_SYNC_FIFOFULL);
+	if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
+		return vmw_fifo_wait_noirq(dev_priv, bytes,
+					   interruptible, timeout);
+
+	mutex_lock(&dev_priv->hw_mutex);
+	if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) {
+		spin_lock_irqsave(&dev_priv->irq_lock, irq_flags);
+		outl(SVGA_IRQFLAG_FIFO_PROGRESS,
+		     dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+		vmw_write(dev_priv, SVGA_REG_IRQMASK,
+			  vmw_read(dev_priv, SVGA_REG_IRQMASK) |
+			  SVGA_IRQFLAG_FIFO_PROGRESS);
+		spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags);
+	}
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	if (interruptible)
+		ret = wait_event_interruptible_timeout
+		    (dev_priv->fifo_queue,
+		     !vmw_fifo_is_full(dev_priv, bytes), timeout);
+	else
+		ret = wait_event_timeout
+		    (dev_priv->fifo_queue,
+		     !vmw_fifo_is_full(dev_priv, bytes), timeout);
+
+	if (unlikely(ret == 0))
+		ret = -EBUSY;
+	else if (likely(ret > 0))
+		ret = 0;
+
+	mutex_lock(&dev_priv->hw_mutex);
+	if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) {
+		spin_lock_irqsave(&dev_priv->irq_lock, irq_flags);
+		vmw_write(dev_priv, SVGA_REG_IRQMASK,
+			  vmw_read(dev_priv, SVGA_REG_IRQMASK) &
+			  ~SVGA_IRQFLAG_FIFO_PROGRESS);
+		spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags);
+	}
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	return ret;
+}
+
+void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes)
+{
+	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t max;
+	uint32_t min;
+	uint32_t next_cmd;
+	uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE;
+	int ret;
+
+	mutex_lock(&fifo_state->fifo_mutex);
+	max = ioread32(fifo_mem + SVGA_FIFO_MAX);
+	min = ioread32(fifo_mem + SVGA_FIFO_MIN);
+	next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD);
+
+	if (unlikely(bytes >= (max - min)))
+		goto out_err;
+
+	BUG_ON(fifo_state->reserved_size != 0);
+	BUG_ON(fifo_state->dynamic_buffer != NULL);
+
+	fifo_state->reserved_size = bytes;
+
+	while (1) {
+		uint32_t stop = ioread32(fifo_mem + SVGA_FIFO_STOP);
+		bool need_bounce = false;
+		bool reserve_in_place = false;
+
+		if (next_cmd >= stop) {
+			if (likely((next_cmd + bytes < max ||
+				    (next_cmd + bytes == max && stop > min))))
+				reserve_in_place = true;
+
+			else if (vmw_fifo_is_full(dev_priv, bytes)) {
+				ret = vmw_fifo_wait(dev_priv, bytes,
+						    false, 3 * HZ);
+				if (unlikely(ret != 0))
+					goto out_err;
+			} else
+				need_bounce = true;
+
+		} else {
+
+			if (likely((next_cmd + bytes < stop)))
+				reserve_in_place = true;
+			else {
+				ret = vmw_fifo_wait(dev_priv, bytes,
+						    false, 3 * HZ);
+				if (unlikely(ret != 0))
+					goto out_err;
+			}
+		}
+
+		if (reserve_in_place) {
+			if (reserveable || bytes <= sizeof(uint32_t)) {
+				fifo_state->using_bounce_buffer = false;
+
+				if (reserveable)
+					iowrite32(bytes, fifo_mem +
+						  SVGA_FIFO_RESERVED);
+				return fifo_mem + (next_cmd >> 2);
+			} else {
+				need_bounce = true;
+			}
+		}
+
+		if (need_bounce) {
+			fifo_state->using_bounce_buffer = true;
+			if (bytes < fifo_state->static_buffer_size)
+				return fifo_state->static_buffer;
+			else {
+				fifo_state->dynamic_buffer = vmalloc(bytes);
+				return fifo_state->dynamic_buffer;
+			}
+		}
+	}
+out_err:
+	fifo_state->reserved_size = 0;
+	mutex_unlock(&fifo_state->fifo_mutex);
+	return NULL;
+}
+
+static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state,
+			      __le32 __iomem *fifo_mem,
+			      uint32_t next_cmd,
+			      uint32_t max, uint32_t min, uint32_t bytes)
+{
+	uint32_t chunk_size = max - next_cmd;
+	uint32_t rest;
+	uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ?
+	    fifo_state->dynamic_buffer : fifo_state->static_buffer;
+
+	if (bytes < chunk_size)
+		chunk_size = bytes;
+
+	iowrite32(bytes, fifo_mem + SVGA_FIFO_RESERVED);
+	mb();
+	memcpy_toio(fifo_mem + (next_cmd >> 2), buffer, chunk_size);
+	rest = bytes - chunk_size;
+	if (rest)
+		memcpy_toio(fifo_mem + (min >> 2), buffer + (chunk_size >> 2),
+			    rest);
+}
+
+static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state,
+			       __le32 __iomem *fifo_mem,
+			       uint32_t next_cmd,
+			       uint32_t max, uint32_t min, uint32_t bytes)
+{
+	uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ?
+	    fifo_state->dynamic_buffer : fifo_state->static_buffer;
+
+	while (bytes > 0) {
+		iowrite32(*buffer++, fifo_mem + (next_cmd >> 2));
+		next_cmd += sizeof(uint32_t);
+		if (unlikely(next_cmd == max))
+			next_cmd = min;
+		mb();
+		iowrite32(next_cmd, fifo_mem + SVGA_FIFO_NEXT_CMD);
+		mb();
+		bytes -= sizeof(uint32_t);
+	}
+}
+
+void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes)
+{
+	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD);
+	uint32_t max = ioread32(fifo_mem + SVGA_FIFO_MAX);
+	uint32_t min = ioread32(fifo_mem + SVGA_FIFO_MIN);
+	bool reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE;
+
+	BUG_ON((bytes & 3) != 0);
+	BUG_ON(bytes > fifo_state->reserved_size);
+
+	fifo_state->reserved_size = 0;
+
+	if (fifo_state->using_bounce_buffer) {
+		if (reserveable)
+			vmw_fifo_res_copy(fifo_state, fifo_mem,
+					  next_cmd, max, min, bytes);
+		else
+			vmw_fifo_slow_copy(fifo_state, fifo_mem,
+					   next_cmd, max, min, bytes);
+
+		if (fifo_state->dynamic_buffer) {
+			vfree(fifo_state->dynamic_buffer);
+			fifo_state->dynamic_buffer = NULL;
+		}
+
+	}
+
+	down_write(&fifo_state->rwsem);
+	if (fifo_state->using_bounce_buffer || reserveable) {
+		next_cmd += bytes;
+		if (next_cmd >= max)
+			next_cmd -= max - min;
+		mb();
+		iowrite32(next_cmd, fifo_mem + SVGA_FIFO_NEXT_CMD);
+	}
+
+	if (reserveable)
+		iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED);
+	mb();
+	up_write(&fifo_state->rwsem);
+	vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
+	mutex_unlock(&fifo_state->fifo_mutex);
+}
+
+int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence)
+{
+	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+	struct svga_fifo_cmd_fence *cmd_fence;
+	void *fm;
+	int ret = 0;
+	uint32_t bytes = sizeof(__le32) + sizeof(*cmd_fence);
+
+	fm = vmw_fifo_reserve(dev_priv, bytes);
+	if (unlikely(fm == NULL)) {
+		*sequence = atomic_read(&dev_priv->fence_seq);
+		ret = -ENOMEM;
+		(void)vmw_fallback_wait(dev_priv, false, true, *sequence,
+					false, 3*HZ);
+		goto out_err;
+	}
+
+	do {
+		*sequence = atomic_add_return(1, &dev_priv->fence_seq);
+	} while (*sequence == 0);
+
+	if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) {
+
+		/*
+		 * Don't request hardware to send a fence. The
+		 * waiting code in vmwgfx_irq.c will emulate this.
+		 */
+
+		vmw_fifo_commit(dev_priv, 0);
+		return 0;
+	}
+
+	*(__le32 *) fm = cpu_to_le32(SVGA_CMD_FENCE);
+	cmd_fence = (struct svga_fifo_cmd_fence *)
+	    ((unsigned long)fm + sizeof(__le32));
+
+	iowrite32(*sequence, &cmd_fence->fence);
+	fifo_state->last_buffer_add = true;
+	vmw_fifo_commit(dev_priv, bytes);
+	fifo_state->last_buffer_add = false;
+
+out_err:
+	return ret;
+}
+
+/**
+ * Map the first page of the FIFO read-only to user-space.
+ */
+
+static int vmw_fifo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	int ret;
+	unsigned long address = (unsigned long)vmf->virtual_address;
+
+	if (address != vma->vm_start)
+		return VM_FAULT_SIGBUS;
+
+	ret = vm_insert_pfn(vma, address, vma->vm_pgoff);
+	if (likely(ret == -EBUSY || ret == 0))
+		return VM_FAULT_NOPAGE;
+	else if (ret == -ENOMEM)
+		return VM_FAULT_OOM;
+
+	return VM_FAULT_SIGBUS;
+}
+
+static struct vm_operations_struct vmw_fifo_vm_ops = {
+	.fault = vmw_fifo_vm_fault,
+	.open = NULL,
+	.close = NULL
+};
+
+int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv;
+	struct vmw_private *dev_priv;
+
+	file_priv = (struct drm_file *)filp->private_data;
+	dev_priv = vmw_priv(file_priv->minor->dev);
+
+	if (vma->vm_pgoff != (dev_priv->mmio_start >> PAGE_SHIFT) ||
+	    (vma->vm_end - vma->vm_start) != PAGE_SIZE)
+		return -EINVAL;
+
+	vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_SHARED;
+	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+	vma->vm_page_prot = ttm_io_prot(TTM_PL_FLAG_UNCACHED,
+					vma->vm_page_prot);
+	vma->vm_ops = &vmw_fifo_vm_ops;
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,213 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "drmP.h"
+#include "ttm/ttm_bo_driver.h"
+
+/**
+ * FIXME: Adjust to the ttm lowmem / highmem storage to minimize
+ * the number of used descriptors.
+ */
+
+static int vmw_gmr_build_descriptors(struct list_head *desc_pages,
+				     struct page *pages[],
+				     unsigned long num_pages)
+{
+	struct page *page, *next;
+	struct svga_guest_mem_descriptor *page_virtual = NULL;
+	struct svga_guest_mem_descriptor *desc_virtual = NULL;
+	unsigned int desc_per_page;
+	unsigned long prev_pfn;
+	unsigned long pfn;
+	int ret;
+
+	desc_per_page = PAGE_SIZE /
+	    sizeof(struct svga_guest_mem_descriptor) - 1;
+
+	while (likely(num_pages != 0)) {
+		page = alloc_page(__GFP_HIGHMEM);
+		if (unlikely(page == NULL)) {
+			ret = -ENOMEM;
+			goto out_err;
+		}
+
+		list_add_tail(&page->lru, desc_pages);
+
+		/*
+		 * Point previous page terminating descriptor to this
+		 * page before unmapping it.
+		 */
+
+		if (likely(page_virtual != NULL)) {
+			desc_virtual->ppn = page_to_pfn(page);
+			kunmap_atomic(page_virtual, KM_USER0);
+		}
+
+		page_virtual = kmap_atomic(page, KM_USER0);
+		desc_virtual = page_virtual - 1;
+		prev_pfn = ~(0UL);
+
+		while (likely(num_pages != 0)) {
+			pfn = page_to_pfn(*pages);
+
+			if (pfn != prev_pfn + 1) {
+
+				if (desc_virtual - page_virtual ==
+				    desc_per_page - 1)
+					break;
+
+				(++desc_virtual)->ppn = cpu_to_le32(pfn);
+				desc_virtual->num_pages = cpu_to_le32(1);
+			} else {
+				uint32_t tmp =
+				    le32_to_cpu(desc_virtual->num_pages);
+				desc_virtual->num_pages = cpu_to_le32(tmp + 1);
+			}
+			prev_pfn = pfn;
+			--num_pages;
+			++pages;
+		}
+
+		(++desc_virtual)->ppn = cpu_to_le32(0);
+		desc_virtual->num_pages = cpu_to_le32(0);
+	}
+
+	if (likely(page_virtual != NULL))
+		kunmap_atomic(page_virtual, KM_USER0);
+
+	return 0;
+out_err:
+	list_for_each_entry_safe(page, next, desc_pages, lru) {
+		list_del_init(&page->lru);
+		__free_page(page);
+	}
+	return ret;
+}
+
+static inline void vmw_gmr_free_descriptors(struct list_head *desc_pages)
+{
+	struct page *page, *next;
+
+	list_for_each_entry_safe(page, next, desc_pages, lru) {
+		list_del_init(&page->lru);
+		__free_page(page);
+	}
+}
+
+static void vmw_gmr_fire_descriptors(struct vmw_private *dev_priv,
+				     int gmr_id, struct list_head *desc_pages)
+{
+	struct page *page;
+
+	if (unlikely(list_empty(desc_pages)))
+		return;
+
+	page = list_entry(desc_pages->next, struct page, lru);
+
+	mutex_lock(&dev_priv->hw_mutex);
+
+	vmw_write(dev_priv, SVGA_REG_GMR_ID, gmr_id);
+	wmb();
+	vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, page_to_pfn(page));
+	mb();
+
+	mutex_unlock(&dev_priv->hw_mutex);
+
+}
+
+/**
+ * FIXME: Adjust to the ttm lowmem / highmem storage to minimize
+ * the number of used descriptors.
+ */
+
+static unsigned long vmw_gmr_count_descriptors(struct page *pages[],
+					       unsigned long num_pages)
+{
+	unsigned long prev_pfn = ~(0UL);
+	unsigned long pfn;
+	unsigned long descriptors = 0;
+
+	while (num_pages--) {
+		pfn = page_to_pfn(*pages++);
+		if (prev_pfn + 1 != pfn)
+			++descriptors;
+		prev_pfn = pfn;
+	}
+
+	return descriptors;
+}
+
+int vmw_gmr_bind(struct vmw_private *dev_priv,
+		 struct ttm_buffer_object *bo)
+{
+	struct ttm_tt *ttm = bo->ttm;
+	unsigned long descriptors;
+	int ret;
+	uint32_t id;
+	struct list_head desc_pages;
+
+	if (!(dev_priv->capabilities & SVGA_CAP_GMR))
+		return -EINVAL;
+
+	ret = ttm_tt_populate(ttm);
+	if (unlikely(ret != 0))
+		return ret;
+
+	descriptors = vmw_gmr_count_descriptors(ttm->pages, ttm->num_pages);
+	if (unlikely(descriptors > dev_priv->max_gmr_descriptors))
+		return -EINVAL;
+
+	INIT_LIST_HEAD(&desc_pages);
+	ret = vmw_gmr_build_descriptors(&desc_pages, ttm->pages,
+					ttm->num_pages);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = vmw_gmr_id_alloc(dev_priv, &id);
+	if (unlikely(ret != 0))
+		goto out_no_id;
+
+	vmw_gmr_fire_descriptors(dev_priv, id, &desc_pages);
+	vmw_gmr_free_descriptors(&desc_pages);
+	vmw_dmabuf_set_gmr(bo, id);
+	return 0;
+
+out_no_id:
+	vmw_gmr_free_descriptors(&desc_pages);
+	return ret;
+}
+
+void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id)
+{
+	mutex_lock(&dev_priv->hw_mutex);
+	vmw_write(dev_priv, SVGA_REG_GMR_ID, gmr_id);
+	wmb();
+	vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, 0);
+	mb();
+	mutex_unlock(&dev_priv->hw_mutex);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,87 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "vmwgfx_drm.h"
+
+int vmw_getparam_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct drm_vmw_getparam_arg *param =
+	    (struct drm_vmw_getparam_arg *)data;
+
+	switch (param->param) {
+	case DRM_VMW_PARAM_NUM_STREAMS:
+		param->value = vmw_overlay_num_overlays(dev_priv);
+		break;
+	case DRM_VMW_PARAM_NUM_FREE_STREAMS:
+		param->value = vmw_overlay_num_free_overlays(dev_priv);
+		break;
+	case DRM_VMW_PARAM_3D:
+		param->value = vmw_fifo_have_3d(dev_priv) ? 1 : 0;
+		break;
+	case DRM_VMW_PARAM_FIFO_OFFSET:
+		param->value = dev_priv->mmio_start;
+		break;
+	case DRM_VMW_PARAM_HW_CAPS:
+		param->value = dev_priv->capabilities;
+		break;
+	case DRM_VMW_PARAM_FIFO_CAPS:
+		param->value = dev_priv->fifo.capabilities;
+		break;
+	default:
+		DRM_ERROR("Illegal vmwgfx get param request: %d\n",
+			  param->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vmw_fifo_debug_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+	struct drm_vmw_fifo_debug_arg *arg =
+	    (struct drm_vmw_fifo_debug_arg *)data;
+	__le32 __user *buffer = (__le32 __user *)
+	    (unsigned long)arg->debug_buffer;
+
+	if (unlikely(fifo_state->last_buffer == NULL))
+		return -EINVAL;
+
+	if (arg->debug_buffer_size < fifo_state->last_data_size) {
+		arg->used_size = arg->debug_buffer_size;
+		arg->did_not_fit = 1;
+	} else {
+		arg->used_size = fifo_state->last_data_size;
+		arg->did_not_fit = 0;
+	}
+	return copy_to_user(buffer, fifo_state->last_buffer, arg->used_size);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,286 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+
+#define VMW_FENCE_WRAP (1 << 24)
+
+irqreturn_t vmw_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *)arg;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	uint32_t status;
+
+	spin_lock(&dev_priv->irq_lock);
+	status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+	spin_unlock(&dev_priv->irq_lock);
+
+	if (status & SVGA_IRQFLAG_ANY_FENCE)
+		wake_up_all(&dev_priv->fence_queue);
+	if (status & SVGA_IRQFLAG_FIFO_PROGRESS)
+		wake_up_all(&dev_priv->fifo_queue);
+
+	if (likely(status)) {
+		outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t sequence)
+{
+	uint32_t busy;
+
+	mutex_lock(&dev_priv->hw_mutex);
+	busy = vmw_read(dev_priv, SVGA_REG_BUSY);
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	return (busy == 0);
+}
+
+
+bool vmw_fence_signaled(struct vmw_private *dev_priv,
+			uint32_t sequence)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	struct vmw_fifo_state *fifo_state;
+	bool ret;
+
+	if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
+		return true;
+
+	dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE);
+	if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
+		return true;
+
+	fifo_state = &dev_priv->fifo;
+	if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) &&
+	    vmw_fifo_idle(dev_priv, sequence))
+		return true;
+
+	/**
+	 * Then check if the sequence is higher than what we've actually
+	 * emitted. Then the fence is stale and signaled.
+	 */
+
+	ret = ((atomic_read(&dev_priv->fence_seq) - sequence)
+	       > VMW_FENCE_WRAP);
+
+	return ret;
+}
+
+int vmw_fallback_wait(struct vmw_private *dev_priv,
+		      bool lazy,
+		      bool fifo_idle,
+		      uint32_t sequence,
+		      bool interruptible,
+		      unsigned long timeout)
+{
+	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+
+	uint32_t count = 0;
+	uint32_t signal_seq;
+	int ret;
+	unsigned long end_jiffies = jiffies + timeout;
+	bool (*wait_condition)(struct vmw_private *, uint32_t);
+	DEFINE_WAIT(__wait);
+
+	wait_condition = (fifo_idle) ? &vmw_fifo_idle :
+		&vmw_fence_signaled;
+
+	/**
+	 * Block command submission while waiting for idle.
+	 */
+
+	if (fifo_idle)
+		down_read(&fifo_state->rwsem);
+	signal_seq = atomic_read(&dev_priv->fence_seq);
+	ret = 0;
+
+	for (;;) {
+		prepare_to_wait(&dev_priv->fence_queue, &__wait,
+				(interruptible) ?
+				TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+		if (wait_condition(dev_priv, sequence))
+			break;
+		if (time_after_eq(jiffies, end_jiffies)) {
+			DRM_ERROR("SVGA device lockup.\n");
+			break;
+		}
+		if (lazy)
+			schedule_timeout(1);
+		else if ((++count & 0x0F) == 0) {
+			/**
+			 * FIXME: Use schedule_hr_timeout here for
+			 * newer kernels and lower CPU utilization.
+			 */
+
+			__set_current_state(TASK_RUNNING);
+			schedule();
+			__set_current_state((interruptible) ?
+					    TASK_INTERRUPTIBLE :
+					    TASK_UNINTERRUPTIBLE);
+		}
+		if (interruptible && signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+	finish_wait(&dev_priv->fence_queue, &__wait);
+	if (ret == 0 && fifo_idle) {
+		__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+		iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE);
+	}
+	wake_up_all(&dev_priv->fence_queue);
+	if (fifo_idle)
+		up_read(&fifo_state->rwsem);
+
+	return ret;
+}
+
+int vmw_wait_fence(struct vmw_private *dev_priv,
+		   bool lazy, uint32_t sequence,
+		   bool interruptible, unsigned long timeout)
+{
+	long ret;
+	unsigned long irq_flags;
+	struct vmw_fifo_state *fifo = &dev_priv->fifo;
+
+	if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP))
+		return 0;
+
+	if (likely(vmw_fence_signaled(dev_priv, sequence)))
+		return 0;
+
+	vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
+
+	if (!(fifo->capabilities & SVGA_FIFO_CAP_FENCE))
+		return vmw_fallback_wait(dev_priv, lazy, true, sequence,
+					 interruptible, timeout);
+
+	if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
+		return vmw_fallback_wait(dev_priv, lazy, false, sequence,
+					 interruptible, timeout);
+
+	mutex_lock(&dev_priv->hw_mutex);
+	if (atomic_add_return(1, &dev_priv->fence_queue_waiters) > 0) {
+		spin_lock_irqsave(&dev_priv->irq_lock, irq_flags);
+		outl(SVGA_IRQFLAG_ANY_FENCE,
+		     dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+		vmw_write(dev_priv, SVGA_REG_IRQMASK,
+			  vmw_read(dev_priv, SVGA_REG_IRQMASK) |
+			  SVGA_IRQFLAG_ANY_FENCE);
+		spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags);
+	}
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	if (interruptible)
+		ret = wait_event_interruptible_timeout
+		    (dev_priv->fence_queue,
+		     vmw_fence_signaled(dev_priv, sequence),
+		     timeout);
+	else
+		ret = wait_event_timeout
+		    (dev_priv->fence_queue,
+		     vmw_fence_signaled(dev_priv, sequence),
+		     timeout);
+
+	if (unlikely(ret == 0))
+		ret = -EBUSY;
+	else if (likely(ret > 0))
+		ret = 0;
+
+	mutex_lock(&dev_priv->hw_mutex);
+	if (atomic_dec_and_test(&dev_priv->fence_queue_waiters)) {
+		spin_lock_irqsave(&dev_priv->irq_lock, irq_flags);
+		vmw_write(dev_priv, SVGA_REG_IRQMASK,
+			  vmw_read(dev_priv, SVGA_REG_IRQMASK) &
+			  ~SVGA_IRQFLAG_ANY_FENCE);
+		spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags);
+	}
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	return ret;
+}
+
+void vmw_irq_preinstall(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	uint32_t status;
+
+	if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
+		return;
+
+	spin_lock_init(&dev_priv->irq_lock);
+	status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+	outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+}
+
+int vmw_irq_postinstall(struct drm_device *dev)
+{
+	return 0;
+}
+
+void vmw_irq_uninstall(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	uint32_t status;
+
+	if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
+		return;
+
+	mutex_lock(&dev_priv->hw_mutex);
+	vmw_write(dev_priv, SVGA_REG_IRQMASK, 0);
+	mutex_unlock(&dev_priv->hw_mutex);
+
+	status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+	outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+}
+
+#define VMW_FENCE_WAIT_TIMEOUT 3*HZ;
+
+int vmw_fence_wait_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct drm_vmw_fence_wait_arg *arg =
+	    (struct drm_vmw_fence_wait_arg *)data;
+	unsigned long timeout;
+
+	if (!arg->cookie_valid) {
+		arg->cookie_valid = 1;
+		arg->kernel_cookie = jiffies + VMW_FENCE_WAIT_TIMEOUT;
+	}
+
+	timeout = jiffies;
+	if (time_after_eq(timeout, (unsigned long)arg->kernel_cookie))
+		return -EBUSY;
+
+	timeout = (unsigned long)arg->kernel_cookie - timeout;
+	return vmw_wait_fence(vmw_priv(dev), true, arg->sequence, true, timeout);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,880 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_kms.h"
+
+/* Might need a hrtimer here? */
+#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
+
+
+void vmw_display_unit_cleanup(struct vmw_display_unit *du)
+{
+	if (du->cursor_surface)
+		vmw_surface_unreference(&du->cursor_surface);
+	if (du->cursor_dmabuf)
+		vmw_dmabuf_unreference(&du->cursor_dmabuf);
+	drm_crtc_cleanup(&du->crtc);
+	drm_encoder_cleanup(&du->encoder);
+	drm_connector_cleanup(&du->connector);
+}
+
+/*
+ * Display Unit Cursor functions
+ */
+
+int vmw_cursor_update_image(struct vmw_private *dev_priv,
+			    u32 *image, u32 width, u32 height,
+			    u32 hotspotX, u32 hotspotY)
+{
+	struct {
+		u32 cmd;
+		SVGAFifoCmdDefineAlphaCursor cursor;
+	} *cmd;
+	u32 image_size = width * height * 4;
+	u32 cmd_size = sizeof(*cmd) + image_size;
+
+	if (!image)
+		return -EINVAL;
+
+	cmd = vmw_fifo_reserve(dev_priv, cmd_size);
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed.\n");
+		return -ENOMEM;
+	}
+
+	memset(cmd, 0, sizeof(*cmd));
+
+	memcpy(&cmd[1], image, image_size);
+
+	cmd->cmd = cpu_to_le32(SVGA_CMD_DEFINE_ALPHA_CURSOR);
+	cmd->cursor.id = cpu_to_le32(0);
+	cmd->cursor.width = cpu_to_le32(width);
+	cmd->cursor.height = cpu_to_le32(height);
+	cmd->cursor.hotspotX = cpu_to_le32(hotspotX);
+	cmd->cursor.hotspotY = cpu_to_le32(hotspotY);
+
+	vmw_fifo_commit(dev_priv, cmd_size);
+
+	return 0;
+}
+
+void vmw_cursor_update_position(struct vmw_private *dev_priv,
+				bool show, int x, int y)
+{
+	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
+	uint32_t count;
+
+	iowrite32(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON);
+	iowrite32(x, fifo_mem + SVGA_FIFO_CURSOR_X);
+	iowrite32(y, fifo_mem + SVGA_FIFO_CURSOR_Y);
+	count = ioread32(fifo_mem + SVGA_FIFO_CURSOR_COUNT);
+	iowrite32(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
+}
+
+int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+			   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;
+	int ret;
+
+	if (handle) {
+		ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
+						     handle, &surface);
+		if (!ret) {
+			if (!surface->snooper.image) {
+				DRM_ERROR("surface not suitable for cursor\n");
+				return -EINVAL;
+			}
+		} else {
+			ret = vmw_user_dmabuf_lookup(tfile,
+						     handle, &dmabuf);
+			if (ret) {
+				DRM_ERROR("failed to find surface or dmabuf: %i\n", ret);
+				return -EINVAL;
+			}
+		}
+	}
+
+	/* takedown old cursor */
+	if (du->cursor_surface) {
+		du->cursor_surface->snooper.crtc = NULL;
+		vmw_surface_unreference(&du->cursor_surface);
+	}
+	if (du->cursor_dmabuf)
+		vmw_dmabuf_unreference(&du->cursor_dmabuf);
+
+	/* setup new image */
+	if (surface) {
+		/* vmw_user_surface_lookup takes one reference */
+		du->cursor_surface = surface;
+
+		du->cursor_surface->snooper.crtc = crtc;
+		du->cursor_age = du->cursor_surface->snooper.age;
+		vmw_cursor_update_image(dev_priv, surface->snooper.image,
+					64, 64, du->hotspot_x, du->hotspot_y);
+	} else if (dmabuf) {
+		struct ttm_bo_kmap_obj map;
+		unsigned long kmap_offset;
+		unsigned long kmap_num;
+		void *virtual;
+		bool dummy;
+
+		/* vmw_user_surface_lookup takes one reference */
+		du->cursor_dmabuf = dmabuf;
+
+		kmap_offset = 0;
+		kmap_num = (64*64*4) >> PAGE_SHIFT;
+
+		ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0);
+		if (unlikely(ret != 0)) {
+			DRM_ERROR("reserve failed\n");
+			return -EINVAL;
+		}
+
+		ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map);
+		if (unlikely(ret != 0))
+			goto err_unreserve;
+
+		virtual = ttm_kmap_obj_virtual(&map, &dummy);
+		vmw_cursor_update_image(dev_priv, virtual, 64, 64,
+					du->hotspot_x, du->hotspot_y);
+
+		ttm_bo_kunmap(&map);
+err_unreserve:
+		ttm_bo_unreserve(&dmabuf->base);
+
+	} else {
+		vmw_cursor_update_position(dev_priv, false, 0, 0);
+		return 0;
+	}
+
+	vmw_cursor_update_position(dev_priv, true, du->cursor_x, du->cursor_y);
+
+	return 0;
+}
+
+int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
+	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
+	bool shown = du->cursor_surface || du->cursor_dmabuf ? true : false;
+
+	du->cursor_x = x + crtc->x;
+	du->cursor_y = y + crtc->y;
+
+	vmw_cursor_update_position(dev_priv, shown,
+				   du->cursor_x, du->cursor_y);
+
+	return 0;
+}
+
+void vmw_kms_cursor_snoop(struct vmw_surface *srf,
+			  struct ttm_object_file *tfile,
+			  struct ttm_buffer_object *bo,
+			  SVGA3dCmdHeader *header)
+{
+	struct ttm_bo_kmap_obj map;
+	unsigned long kmap_offset;
+	unsigned long kmap_num;
+	SVGA3dCopyBox *box;
+	unsigned box_count;
+	void *virtual;
+	bool dummy;
+	struct vmw_dma_cmd {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdSurfaceDMA dma;
+	} *cmd;
+	int ret;
+
+	cmd = container_of(header, struct vmw_dma_cmd, header);
+
+	/* No snooper installed */
+	if (!srf->snooper.image)
+		return;
+
+	if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) {
+		DRM_ERROR("face and mipmap for cursors should never != 0\n");
+		return;
+	}
+
+	if (cmd->header.size < 64) {
+		DRM_ERROR("at least one full copy box must be given\n");
+		return;
+	}
+
+	box = (SVGA3dCopyBox *)&cmd[1];
+	box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
+			sizeof(SVGA3dCopyBox);
+
+	if (cmd->dma.guest.pitch != (64 * 4) ||
+	    cmd->dma.guest.ptr.offset % PAGE_SIZE ||
+	    box->x != 0    || box->y != 0    || box->z != 0    ||
+	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
+	    box->w != 64   || box->h != 64   || box->d != 1    ||
+	    box_count != 1) {
+		/* TODO handle none page aligned offsets */
+		/* TODO handle partial uploads and pitch != 256 */
+		/* TODO handle more then one copy (size != 64) */
+		DRM_ERROR("lazy programer, cant handle wierd stuff\n");
+		return;
+	}
+
+	kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
+	kmap_num = (64*64*4) >> PAGE_SHIFT;
+
+	ret = ttm_bo_reserve(bo, true, false, false, 0);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("reserve failed\n");
+		return;
+	}
+
+	ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
+	if (unlikely(ret != 0))
+		goto err_unreserve;
+
+	virtual = ttm_kmap_obj_virtual(&map, &dummy);
+
+	memcpy(srf->snooper.image, virtual, 64*64*4);
+	srf->snooper.age++;
+
+	/* we can't call this function from this function since execbuf has
+	 * reserved fifo space.
+	 *
+	 * if (srf->snooper.crtc)
+	 *	vmw_ldu_crtc_cursor_update_image(dev_priv,
+	 *					 srf->snooper.image, 64, 64,
+	 *					 du->hotspot_x, du->hotspot_y);
+	 */
+
+	ttm_bo_kunmap(&map);
+err_unreserve:
+	ttm_bo_unreserve(bo);
+}
+
+void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct vmw_display_unit *du;
+	struct drm_crtc *crtc;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		du = vmw_crtc_to_du(crtc);
+		if (!du->cursor_surface ||
+		    du->cursor_age == du->cursor_surface->snooper.age)
+			continue;
+
+		du->cursor_age = du->cursor_surface->snooper.age;
+		vmw_cursor_update_image(dev_priv,
+					du->cursor_surface->snooper.image,
+					64, 64, du->hotspot_x, du->hotspot_y);
+	}
+
+	mutex_unlock(&dev->mode_config.mutex);
+}
+
+/*
+ * Generic framebuffer code
+ */
+
+int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
+				  struct drm_file *file_priv,
+				  unsigned int *handle)
+{
+	if (handle)
+		handle = 0;
+
+	return 0;
+}
+
+/*
+ * Surface framebuffer code
+ */
+
+#define vmw_framebuffer_to_vfbs(x) \
+	container_of(x, struct vmw_framebuffer_surface, base.base)
+
+struct vmw_framebuffer_surface {
+	struct vmw_framebuffer base;
+	struct vmw_surface *surface;
+	struct delayed_work d_work;
+	struct mutex work_lock;
+	bool present_fs;
+};
+
+void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
+{
+	struct vmw_framebuffer_surface *vfb =
+		vmw_framebuffer_to_vfbs(framebuffer);
+
+	cancel_delayed_work_sync(&vfb->d_work);
+	drm_framebuffer_cleanup(framebuffer);
+	vmw_surface_unreference(&vfb->surface);
+
+	kfree(framebuffer);
+}
+
+static void vmw_framebuffer_present_fs_callback(struct work_struct *work)
+{
+	struct delayed_work *d_work =
+		container_of(work, struct delayed_work, work);
+	struct vmw_framebuffer_surface *vfbs =
+		container_of(d_work, struct vmw_framebuffer_surface, d_work);
+	struct vmw_surface *surf = vfbs->surface;
+	struct drm_framebuffer *framebuffer = &vfbs->base.base;
+	struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdPresent body;
+		SVGA3dCopyRect cr;
+	} *cmd;
+
+	mutex_lock(&vfbs->work_lock);
+	if (!vfbs->present_fs)
+		goto out_unlock;
+
+	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
+	if (unlikely(cmd == NULL))
+		goto out_resched;
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT);
+	cmd->header.size = cpu_to_le32(sizeof(cmd->body) + sizeof(cmd->cr));
+	cmd->body.sid = cpu_to_le32(surf->res.id);
+	cmd->cr.x = cpu_to_le32(0);
+	cmd->cr.y = cpu_to_le32(0);
+	cmd->cr.srcx = cmd->cr.x;
+	cmd->cr.srcy = cmd->cr.y;
+	cmd->cr.w = cpu_to_le32(framebuffer->width);
+	cmd->cr.h = cpu_to_le32(framebuffer->height);
+	vfbs->present_fs = false;
+	vmw_fifo_commit(dev_priv, sizeof(*cmd));
+out_resched:
+	/**
+	 * Will not re-add if already pending.
+	 */
+	schedule_delayed_work(&vfbs->d_work, VMWGFX_PRESENT_RATE);
+out_unlock:
+	mutex_unlock(&vfbs->work_lock);
+}
+
+
+int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
+				  unsigned flags, unsigned color,
+				  struct drm_clip_rect *clips,
+				  unsigned num_clips)
+{
+	struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+	struct vmw_framebuffer_surface *vfbs =
+		vmw_framebuffer_to_vfbs(framebuffer);
+	struct vmw_surface *surf = vfbs->surface;
+	struct drm_clip_rect norect;
+	SVGA3dCopyRect *cr;
+	int i, inc = 1;
+
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdPresent body;
+		SVGA3dCopyRect cr;
+	} *cmd;
+
+	if (!num_clips ||
+	    !(dev_priv->fifo.capabilities &
+	      SVGA_FIFO_CAP_SCREEN_OBJECT)) {
+		int ret;
+
+		mutex_lock(&vfbs->work_lock);
+		vfbs->present_fs = true;
+		ret = schedule_delayed_work(&vfbs->d_work, VMWGFX_PRESENT_RATE);
+		mutex_unlock(&vfbs->work_lock);
+		if (ret) {
+			/**
+			 * No work pending, Force immediate present.
+			 */
+			vmw_framebuffer_present_fs_callback(&vfbs->d_work.work);
+		}
+		return 0;
+	}
+
+	if (!num_clips) {
+		num_clips = 1;
+		clips = &norect;
+		norect.x1 = norect.y1 = 0;
+		norect.x2 = framebuffer->width;
+		norect.y2 = framebuffer->height;
+	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
+		num_clips /= 2;
+		inc = 2; /* skip source rects */
+	}
+
+	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr));
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed.\n");
+		return -ENOMEM;
+	}
+
+	memset(cmd, 0, sizeof(*cmd));
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT);
+	cmd->header.size = cpu_to_le32(sizeof(cmd->body) + num_clips * sizeof(cmd->cr));
+	cmd->body.sid = cpu_to_le32(surf->res.id);
+
+	for (i = 0, cr = &cmd->cr; i < num_clips; i++, cr++, clips += inc) {
+		cr->x = cpu_to_le16(clips->x1);
+		cr->y = cpu_to_le16(clips->y1);
+		cr->srcx = cr->x;
+		cr->srcy = cr->y;
+		cr->w = cpu_to_le16(clips->x2 - clips->x1);
+		cr->h = cpu_to_le16(clips->y2 - clips->y1);
+	}
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr));
+
+	return 0;
+}
+
+static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
+	.destroy = vmw_framebuffer_surface_destroy,
+	.dirty = vmw_framebuffer_surface_dirty,
+	.create_handle = vmw_framebuffer_create_handle,
+};
+
+int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
+				    struct vmw_surface *surface,
+				    struct vmw_framebuffer **out,
+				    unsigned width, unsigned height)
+
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct vmw_framebuffer_surface *vfbs;
+	int ret;
+
+	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
+	if (!vfbs) {
+		ret = -ENOMEM;
+		goto out_err1;
+	}
+
+	ret = drm_framebuffer_init(dev, &vfbs->base.base,
+				   &vmw_framebuffer_surface_funcs);
+	if (ret)
+		goto out_err2;
+
+	if (!vmw_surface_reference(surface)) {
+		DRM_ERROR("failed to reference surface %p\n", surface);
+		goto out_err3;
+	}
+
+	/* XXX get the first 3 from the surface info */
+	vfbs->base.base.bits_per_pixel = 32;
+	vfbs->base.base.pitch = width * 32 / 4;
+	vfbs->base.base.depth = 24;
+	vfbs->base.base.width = width;
+	vfbs->base.base.height = height;
+	vfbs->base.pin = NULL;
+	vfbs->base.unpin = NULL;
+	vfbs->surface = surface;
+	mutex_init(&vfbs->work_lock);
+	INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback);
+	*out = &vfbs->base;
+
+	return 0;
+
+out_err3:
+	drm_framebuffer_cleanup(&vfbs->base.base);
+out_err2:
+	kfree(vfbs);
+out_err1:
+	return ret;
+}
+
+/*
+ * Dmabuf framebuffer code
+ */
+
+#define vmw_framebuffer_to_vfbd(x) \
+	container_of(x, struct vmw_framebuffer_dmabuf, base.base)
+
+struct vmw_framebuffer_dmabuf {
+	struct vmw_framebuffer base;
+	struct vmw_dma_buffer *buffer;
+};
+
+void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
+{
+	struct vmw_framebuffer_dmabuf *vfbd =
+		vmw_framebuffer_to_vfbd(framebuffer);
+
+	drm_framebuffer_cleanup(framebuffer);
+	vmw_dmabuf_unreference(&vfbd->buffer);
+
+	kfree(vfbd);
+}
+
+int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
+				 unsigned flags, unsigned color,
+				 struct drm_clip_rect *clips,
+				 unsigned num_clips)
+{
+	struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+	struct drm_clip_rect norect;
+	struct {
+		uint32_t header;
+		SVGAFifoCmdUpdate body;
+	} *cmd;
+	int i, increment = 1;
+
+	if (!num_clips) {
+		num_clips = 1;
+		clips = &norect;
+		norect.x1 = norect.y1 = 0;
+		norect.x2 = framebuffer->width;
+		norect.y2 = framebuffer->height;
+	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
+		num_clips /= 2;
+		increment = 2;
+	}
+
+	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips);
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed.\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_clips; i++, clips += increment) {
+		cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE);
+		cmd[i].body.x = cpu_to_le32(clips->x1);
+		cmd[i].body.y = cpu_to_le32(clips->y1);
+		cmd[i].body.width = cpu_to_le32(clips->x2 - clips->x1);
+		cmd[i].body.height = cpu_to_le32(clips->y2 - clips->y1);
+	}
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmd) * num_clips);
+
+	return 0;
+}
+
+static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
+	.destroy = vmw_framebuffer_dmabuf_destroy,
+	.dirty = vmw_framebuffer_dmabuf_dirty,
+	.create_handle = vmw_framebuffer_create_handle,
+};
+
+static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
+{
+	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
+	struct vmw_framebuffer_dmabuf *vfbd =
+		vmw_framebuffer_to_vfbd(&vfb->base);
+	int ret;
+
+	vmw_overlay_pause_all(dev_priv);
+
+	ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer);
+
+	if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
+		vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+
+		vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
+		vmw_write(dev_priv, SVGA_REG_WIDTH, vfb->base.width);
+		vmw_write(dev_priv, SVGA_REG_HEIGHT, vfb->base.height);
+		vmw_write(dev_priv, SVGA_REG_BITS_PER_PIXEL, vfb->base.bits_per_pixel);
+		vmw_write(dev_priv, SVGA_REG_DEPTH, vfb->base.depth);
+		vmw_write(dev_priv, SVGA_REG_RED_MASK, 0x00ff0000);
+		vmw_write(dev_priv, SVGA_REG_GREEN_MASK, 0x0000ff00);
+		vmw_write(dev_priv, SVGA_REG_BLUE_MASK, 0x000000ff);
+	} else
+		WARN_ON(true);
+
+	vmw_overlay_resume_all(dev_priv);
+
+	return 0;
+}
+
+static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb)
+{
+	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
+	struct vmw_framebuffer_dmabuf *vfbd =
+		vmw_framebuffer_to_vfbd(&vfb->base);
+
+	if (!vfbd->buffer) {
+		WARN_ON(!vfbd->buffer);
+		return 0;
+	}
+
+	return vmw_dmabuf_from_vram(dev_priv, vfbd->buffer);
+}
+
+int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
+				   struct vmw_dma_buffer *dmabuf,
+				   struct vmw_framebuffer **out,
+				   unsigned width, unsigned height)
+
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct vmw_framebuffer_dmabuf *vfbd;
+	int ret;
+
+	vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL);
+	if (!vfbd) {
+		ret = -ENOMEM;
+		goto out_err1;
+	}
+
+	ret = drm_framebuffer_init(dev, &vfbd->base.base,
+				   &vmw_framebuffer_dmabuf_funcs);
+	if (ret)
+		goto out_err2;
+
+	if (!vmw_dmabuf_reference(dmabuf)) {
+		DRM_ERROR("failed to reference dmabuf %p\n", dmabuf);
+		goto out_err3;
+	}
+
+	/* XXX get the first 3 from the surface info */
+	vfbd->base.base.bits_per_pixel = 32;
+	vfbd->base.base.pitch = width * 32 / 4;
+	vfbd->base.base.depth = 24;
+	vfbd->base.base.width = width;
+	vfbd->base.base.height = height;
+	vfbd->base.pin = vmw_framebuffer_dmabuf_pin;
+	vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin;
+	vfbd->buffer = dmabuf;
+	*out = &vfbd->base;
+
+	return 0;
+
+out_err3:
+	drm_framebuffer_cleanup(&vfbd->base.base);
+out_err2:
+	kfree(vfbd);
+out_err1:
+	return ret;
+}
+
+/*
+ * Generic Kernel modesetting functions
+ */
+
+static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
+						 struct drm_file *file_priv,
+						 struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct vmw_framebuffer *vfb = NULL;
+	struct vmw_surface *surface = NULL;
+	struct vmw_dma_buffer *bo = NULL;
+	int ret;
+
+	ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
+					     mode_cmd->handle, &surface);
+	if (ret)
+		goto try_dmabuf;
+
+	if (!surface->scanout)
+		goto err_not_scanout;
+
+	ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
+					      mode_cmd->width, mode_cmd->height);
+
+	/* vmw_user_surface_lookup takes one ref so does new_fb */
+	vmw_surface_unreference(&surface);
+
+	if (ret) {
+		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
+		return NULL;
+	}
+	return &vfb->base;
+
+try_dmabuf:
+	DRM_INFO("%s: trying buffer\n", __func__);
+
+	ret = vmw_user_dmabuf_lookup(tfile, mode_cmd->handle, &bo);
+	if (ret) {
+		DRM_ERROR("failed to find buffer: %i\n", ret);
+		return NULL;
+	}
+
+	ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb,
+					     mode_cmd->width, mode_cmd->height);
+
+	/* vmw_user_dmabuf_lookup takes one ref so does new_fb */
+	vmw_dmabuf_unreference(&bo);
+
+	if (ret) {
+		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
+		return NULL;
+	}
+
+	return &vfb->base;
+
+err_not_scanout:
+	DRM_ERROR("surface not marked as scanout\n");
+	/* vmw_user_surface_lookup takes one ref */
+	vmw_surface_unreference(&surface);
+
+	return NULL;
+}
+
+static int vmw_kms_fb_changed(struct drm_device *dev)
+{
+	return 0;
+}
+
+static struct drm_mode_config_funcs vmw_kms_funcs = {
+	.fb_create = vmw_kms_fb_create,
+	.fb_changed = vmw_kms_fb_changed,
+};
+
+int vmw_kms_init(struct vmw_private *dev_priv)
+{
+	struct drm_device *dev = dev_priv->dev;
+	int ret;
+
+	drm_mode_config_init(dev);
+	dev->mode_config.funcs = &vmw_kms_funcs;
+	dev->mode_config.min_width = 1;
+	dev->mode_config.min_height = 1;
+	dev->mode_config.max_width = dev_priv->fb_max_width;
+	dev->mode_config.max_height = dev_priv->fb_max_height;
+
+	ret = vmw_kms_init_legacy_display_system(dev_priv);
+
+	return 0;
+}
+
+int vmw_kms_close(struct vmw_private *dev_priv)
+{
+	/*
+	 * Docs says we should take the lock before calling this function
+	 * but since it destroys encoders and our destructor calls
+	 * drm_encoder_cleanup which takes the lock we deadlock.
+	 */
+	drm_mode_config_cleanup(dev_priv->dev);
+	vmw_kms_close_legacy_display_system(dev_priv);
+	return 0;
+}
+
+int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct drm_vmw_cursor_bypass_arg *arg = data;
+	struct vmw_display_unit *du;
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	int ret = 0;
+
+
+	mutex_lock(&dev->mode_config.mutex);
+	if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
+
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			du = vmw_crtc_to_du(crtc);
+			du->hotspot_x = arg->xhot;
+			du->hotspot_y = arg->yhot;
+		}
+
+		mutex_unlock(&dev->mode_config.mutex);
+		return 0;
+	}
+
+	obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	crtc = obj_to_crtc(obj);
+	du = vmw_crtc_to_du(crtc);
+
+	du->hotspot_x = arg->xhot;
+	du->hotspot_y = arg->yhot;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return ret;
+}
+
+int vmw_kms_save_vga(struct vmw_private *vmw_priv)
+{
+	/*
+	 * setup a single multimon monitor with the size
+	 * of 0x0, this stops the UI from resizing when we
+	 * change the framebuffer size
+	 */
+	if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) {
+		vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
+		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+	}
+
+	vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
+	vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
+	vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
+	vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH);
+	vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR);
+	vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK);
+	vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
+	vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK);
+
+	return 0;
+}
+
+int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
+{
+	vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
+	vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
+	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
+	vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth);
+	vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo);
+	vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask);
+	vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask);
+	vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask);
+
+	/* TODO check for multimon */
+	vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#ifndef VMWGFX_KMS_H_
+#define VMWGFX_KMS_H_
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+
+
+#define vmw_framebuffer_to_vfb(x) \
+	container_of(x, struct vmw_framebuffer, base)
+
+/**
+ * Base class for framebuffers
+ *
+ * @pin is called the when ever a crtc uses this framebuffer
+ * @unpin is called
+ */
+struct vmw_framebuffer {
+	struct drm_framebuffer base;
+	int (*pin)(struct vmw_framebuffer *fb);
+	int (*unpin)(struct vmw_framebuffer *fb);
+};
+
+
+#define vmw_crtc_to_du(x) \
+	container_of(x, struct vmw_display_unit, crtc)
+
+/*
+ * Basic cursor manipulation
+ */
+int vmw_cursor_update_image(struct vmw_private *dev_priv,
+			    u32 *image, u32 width, u32 height,
+			    u32 hotspotX, u32 hotspotY);
+void vmw_cursor_update_position(struct vmw_private *dev_priv,
+				bool show, int x, int y);
+
+/**
+ * Base class display unit.
+ *
+ * Since the SVGA hw doesn't have a concept of a crtc, encoder or connector
+ * so the display unit is all of them at the same time. This is true for both
+ * legacy multimon and screen objects.
+ */
+struct vmw_display_unit {
+	struct drm_crtc crtc;
+	struct drm_encoder encoder;
+	struct drm_connector connector;
+
+	struct vmw_surface *cursor_surface;
+	struct vmw_dma_buffer *cursor_dmabuf;
+	size_t cursor_age;
+
+	int cursor_x;
+	int cursor_y;
+
+	int hotspot_x;
+	int hotspot_y;
+
+	unsigned unit;
+};
+
+/*
+ * Shared display unit functions - vmwgfx_kms.c
+ */
+void vmw_display_unit_cleanup(struct vmw_display_unit *du);
+int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+			   uint32_t handle, uint32_t width, uint32_t height);
+int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
+
+/*
+ * Legacy display unit functions - vmwgfx_ldu.h
+ */
+int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv);
+int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv);
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,516 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_kms.h"
+
+#define vmw_crtc_to_ldu(x) \
+	container_of(x, struct vmw_legacy_display_unit, base.crtc)
+#define vmw_encoder_to_ldu(x) \
+	container_of(x, struct vmw_legacy_display_unit, base.encoder)
+#define vmw_connector_to_ldu(x) \
+	container_of(x, struct vmw_legacy_display_unit, base.connector)
+
+struct vmw_legacy_display {
+	struct list_head active;
+
+	unsigned num_active;
+
+	struct vmw_framebuffer *fb;
+};
+
+/**
+ * Display unit using the legacy register interface.
+ */
+struct vmw_legacy_display_unit {
+	struct vmw_display_unit base;
+
+	struct list_head active;
+
+	unsigned unit;
+};
+
+static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu)
+{
+	list_del_init(&ldu->active);
+	vmw_display_unit_cleanup(&ldu->base);
+	kfree(ldu);
+}
+
+
+/*
+ * Legacy Display Unit CRTC functions
+ */
+
+static void vmw_ldu_crtc_save(struct drm_crtc *crtc)
+{
+}
+
+static void vmw_ldu_crtc_restore(struct drm_crtc *crtc)
+{
+}
+
+static void vmw_ldu_crtc_gamma_set(struct drm_crtc *crtc,
+				   u16 *r, u16 *g, u16 *b,
+				   uint32_t size)
+{
+}
+
+static void vmw_ldu_crtc_destroy(struct drm_crtc *crtc)
+{
+	vmw_ldu_destroy(vmw_crtc_to_ldu(crtc));
+}
+
+static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
+{
+	struct vmw_legacy_display *lds = dev_priv->ldu_priv;
+	struct vmw_legacy_display_unit *entry;
+	struct drm_crtc *crtc;
+	int i = 0;
+
+	/* to stop the screen from changing size on resize */
+	vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0);
+	for (i = 0; i < lds->num_active; i++) {
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+	}
+
+	/* Now set the mode */
+	vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active);
+	i = 0;
+	list_for_each_entry(entry, &lds->active, active) {
+		crtc = &entry->base.crtc;
+
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, crtc->x);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, crtc->y);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, crtc->mode.hdisplay);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, crtc->mode.vdisplay);
+		vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
+
+		i++;
+	}
+
+	return 0;
+}
+
+static int vmw_ldu_del_active(struct vmw_private *vmw_priv,
+			      struct vmw_legacy_display_unit *ldu)
+{
+	struct vmw_legacy_display *ld = vmw_priv->ldu_priv;
+	if (list_empty(&ldu->active))
+		return 0;
+
+	list_del_init(&ldu->active);
+	if (--(ld->num_active) == 0) {
+		BUG_ON(!ld->fb);
+		if (ld->fb->unpin)
+			ld->fb->unpin(ld->fb);
+		ld->fb = NULL;
+	}
+
+	return 0;
+}
+
+static int vmw_ldu_add_active(struct vmw_private *vmw_priv,
+			      struct vmw_legacy_display_unit *ldu,
+			      struct vmw_framebuffer *vfb)
+{
+	struct vmw_legacy_display *ld = vmw_priv->ldu_priv;
+	struct vmw_legacy_display_unit *entry;
+	struct list_head *at;
+
+	if (!list_empty(&ldu->active))
+		return 0;
+
+	at = &ld->active;
+	list_for_each_entry(entry, &ld->active, active) {
+		if (entry->unit > ldu->unit)
+			break;
+
+		at = &entry->active;
+	}
+
+	list_add(&ldu->active, at);
+	if (ld->num_active++ == 0) {
+		BUG_ON(ld->fb);
+		if (vfb->pin)
+			vfb->pin(vfb);
+		ld->fb = vfb;
+	}
+
+	return 0;
+}
+
+static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
+{
+	struct vmw_private *dev_priv;
+	struct vmw_legacy_display_unit *ldu;
+	struct drm_connector *connector;
+	struct drm_display_mode *mode;
+	struct drm_encoder *encoder;
+	struct vmw_framebuffer *vfb;
+	struct drm_framebuffer *fb;
+	struct drm_crtc *crtc;
+
+	if (!set)
+		return -EINVAL;
+
+	if (!set->crtc)
+		return -EINVAL;
+
+	/* get the ldu */
+	crtc = set->crtc;
+	ldu = vmw_crtc_to_ldu(crtc);
+	vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL;
+	dev_priv = vmw_priv(crtc->dev);
+
+	if (set->num_connectors > 1) {
+		DRM_ERROR("to many connectors\n");
+		return -EINVAL;
+	}
+
+	if (set->num_connectors == 1 &&
+	    set->connectors[0] != &ldu->base.connector) {
+		DRM_ERROR("connector doesn't match %p %p\n",
+			set->connectors[0], &ldu->base.connector);
+		return -EINVAL;
+	}
+
+	/* ldu only supports one fb active at the time */
+	if (dev_priv->ldu_priv->fb && vfb &&
+	    dev_priv->ldu_priv->fb != vfb) {
+		DRM_ERROR("Multiple framebuffers not supported\n");
+		return -EINVAL;
+	}
+
+	/* since they always map one to one these are safe */
+	connector = &ldu->base.connector;
+	encoder = &ldu->base.encoder;
+
+	/* should we turn the crtc off? */
+	if (set->num_connectors == 0 || !set->mode || !set->fb) {
+
+		connector->encoder = NULL;
+		encoder->crtc = NULL;
+		crtc->fb = NULL;
+
+		vmw_ldu_del_active(dev_priv, ldu);
+
+		vmw_ldu_commit_list(dev_priv);
+
+		return 0;
+	}
+
+
+	/* we now know we want to set a mode */
+	mode = set->mode;
+	fb = set->fb;
+
+	if (set->x + mode->hdisplay > fb->width ||
+	    set->y + mode->vdisplay > fb->height) {
+		DRM_ERROR("set outside of framebuffer\n");
+		return -EINVAL;
+	}
+
+	vmw_fb_off(dev_priv);
+
+	crtc->fb = fb;
+	encoder->crtc = crtc;
+	connector->encoder = encoder;
+	crtc->x = set->x;
+	crtc->y = set->y;
+	crtc->mode = *mode;
+
+	vmw_ldu_add_active(dev_priv, ldu, vfb);
+
+	vmw_ldu_commit_list(dev_priv);
+
+	return 0;
+}
+
+static struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
+	.save = vmw_ldu_crtc_save,
+	.restore = vmw_ldu_crtc_restore,
+	.cursor_set = vmw_du_crtc_cursor_set,
+	.cursor_move = vmw_du_crtc_cursor_move,
+	.gamma_set = vmw_ldu_crtc_gamma_set,
+	.destroy = vmw_ldu_crtc_destroy,
+	.set_config = vmw_ldu_crtc_set_config,
+};
+
+/*
+ * Legacy Display Unit encoder functions
+ */
+
+static void vmw_ldu_encoder_destroy(struct drm_encoder *encoder)
+{
+	vmw_ldu_destroy(vmw_encoder_to_ldu(encoder));
+}
+
+static struct drm_encoder_funcs vmw_legacy_encoder_funcs = {
+	.destroy = vmw_ldu_encoder_destroy,
+};
+
+/*
+ * Legacy Display Unit connector functions
+ */
+
+static void vmw_ldu_connector_dpms(struct drm_connector *connector, int mode)
+{
+}
+
+static void vmw_ldu_connector_save(struct drm_connector *connector)
+{
+}
+
+static void vmw_ldu_connector_restore(struct drm_connector *connector)
+{
+}
+
+static enum drm_connector_status
+	vmw_ldu_connector_detect(struct drm_connector *connector)
+{
+	/* XXX vmwctrl should control connection status */
+	if (vmw_connector_to_ldu(connector)->base.unit == 0)
+		return connector_status_connected;
+	return connector_status_disconnected;
+}
+
+static struct drm_display_mode vmw_ldu_connector_builtin[] = {
+	/* 640x480@60Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
+		   752, 800, 0, 480, 489, 492, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 800x600@60Hz */
+	{ DRM_MODE("800x600",
+		   DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+		   40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628,
+		   0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1024x768@60Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+		   1184, 1344, 0, 768, 771, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1152x864@75Hz */
+	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
+		   1344, 1600, 0, 864, 865, 868, 900, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x768@60Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
+		   1472, 1664, 0, 768, 771, 778, 798, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x800@60Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
+		   1480, 1680, 0, 800, 803, 809, 831, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x960@60Hz */
+	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
+		   1488, 1800, 0, 960, 961, 964, 1000, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x1024@60Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
+		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1360x768@60Hz */
+	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
+		   1536, 1792, 0, 768, 771, 777, 795, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x1050@60Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
+		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x900@60Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
+		   1672, 1904, 0, 900, 903, 909, 934, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@60Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1680x1050@60Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
+		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1792x1344@60Hz */
+	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
+		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1853x1392@60Hz */
+	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
+		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1200@60Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
+		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1440@60Hz */
+	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
+		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1600@60Hz */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
+		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* Terminate */
+	{ DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
+};
+
+static int vmw_ldu_connector_fill_modes(struct drm_connector *connector,
+					uint32_t max_width, uint32_t max_height)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode = NULL;
+	int i;
+
+	for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) {
+		if (vmw_ldu_connector_builtin[i].hdisplay > max_width ||
+		    vmw_ldu_connector_builtin[i].vdisplay > max_height)
+			continue;
+
+		mode = drm_mode_duplicate(dev, &vmw_ldu_connector_builtin[i]);
+		if (!mode)
+			return 0;
+		mode->vrefresh = drm_mode_vrefresh(mode);
+
+		drm_mode_probed_add(connector, mode);
+	}
+
+	drm_mode_connector_list_update(connector);
+
+	return 1;
+}
+
+static int vmw_ldu_connector_set_property(struct drm_connector *connector,
+					  struct drm_property *property,
+					  uint64_t val)
+{
+	return 0;
+}
+
+static void vmw_ldu_connector_destroy(struct drm_connector *connector)
+{
+	vmw_ldu_destroy(vmw_connector_to_ldu(connector));
+}
+
+static struct drm_connector_funcs vmw_legacy_connector_funcs = {
+	.dpms = vmw_ldu_connector_dpms,
+	.save = vmw_ldu_connector_save,
+	.restore = vmw_ldu_connector_restore,
+	.detect = vmw_ldu_connector_detect,
+	.fill_modes = vmw_ldu_connector_fill_modes,
+	.set_property = vmw_ldu_connector_set_property,
+	.destroy = vmw_ldu_connector_destroy,
+};
+
+static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
+{
+	struct vmw_legacy_display_unit *ldu;
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct drm_crtc *crtc;
+
+	ldu = kzalloc(sizeof(*ldu), GFP_KERNEL);
+	if (!ldu)
+		return -ENOMEM;
+
+	ldu->unit = unit;
+	crtc = &ldu->base.crtc;
+	encoder = &ldu->base.encoder;
+	connector = &ldu->base.connector;
+
+	drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
+			   DRM_MODE_CONNECTOR_LVDS);
+	/* Initial status */
+	if (unit == 0)
+		connector->status = connector_status_connected;
+	else
+		connector->status = connector_status_disconnected;
+
+	drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
+			 DRM_MODE_ENCODER_LVDS);
+	drm_mode_connector_attach_encoder(connector, encoder);
+	encoder->possible_crtcs = (1 << unit);
+	encoder->possible_clones = 0;
+
+	INIT_LIST_HEAD(&ldu->active);
+
+	drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs);
+
+	drm_connector_attach_property(connector,
+				      dev->mode_config.dirty_info_property,
+				      1);
+
+	return 0;
+}
+
+int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
+{
+	if (dev_priv->ldu_priv) {
+		DRM_INFO("ldu system already on\n");
+		return -EINVAL;
+	}
+
+	dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv));
+
+	if (!dev_priv->ldu_priv)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&dev_priv->ldu_priv->active);
+	dev_priv->ldu_priv->num_active = 0;
+	dev_priv->ldu_priv->fb = NULL;
+
+	drm_mode_create_dirty_info_property(dev_priv->dev);
+
+	vmw_ldu_init(dev_priv, 0);
+	vmw_ldu_init(dev_priv, 1);
+	vmw_ldu_init(dev_priv, 2);
+	vmw_ldu_init(dev_priv, 3);
+	vmw_ldu_init(dev_priv, 4);
+	vmw_ldu_init(dev_priv, 5);
+	vmw_ldu_init(dev_priv, 6);
+	vmw_ldu_init(dev_priv, 7);
+
+	return 0;
+}
+
+int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
+{
+	if (!dev_priv->ldu_priv)
+		return -ENOSYS;
+
+	BUG_ON(!list_empty(&dev_priv->ldu_priv->active));
+
+	kfree(dev_priv->ldu_priv);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,625 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+
+#include "ttm/ttm_placement.h"
+
+#include "svga_overlay.h"
+#include "svga_escape.h"
+
+#define VMW_MAX_NUM_STREAMS 1
+
+struct vmw_stream {
+	struct vmw_dma_buffer *buf;
+	bool claimed;
+	bool paused;
+	struct drm_vmw_control_stream_arg saved;
+};
+
+/**
+ * Overlay control
+ */
+struct vmw_overlay {
+	/*
+	 * Each stream is a single overlay. In Xv these are called ports.
+	 */
+	struct mutex mutex;
+	struct vmw_stream stream[VMW_MAX_NUM_STREAMS];
+};
+
+static inline struct vmw_overlay *vmw_overlay(struct drm_device *dev)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	return dev_priv ? dev_priv->overlay_priv : NULL;
+}
+
+struct vmw_escape_header {
+	uint32_t cmd;
+	SVGAFifoCmdEscape body;
+};
+
+struct vmw_escape_video_flush {
+	struct vmw_escape_header escape;
+	SVGAEscapeVideoFlush flush;
+};
+
+static inline void fill_escape(struct vmw_escape_header *header,
+			       uint32_t size)
+{
+	header->cmd = SVGA_CMD_ESCAPE;
+	header->body.nsid = SVGA_ESCAPE_NSID_VMWARE;
+	header->body.size = size;
+}
+
+static inline void fill_flush(struct vmw_escape_video_flush *cmd,
+			      uint32_t stream_id)
+{
+	fill_escape(&cmd->escape, sizeof(cmd->flush));
+	cmd->flush.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
+	cmd->flush.streamId = stream_id;
+}
+
+/**
+ * Pin or unpin a buffer in vram.
+ *
+ * @dev_priv:  Driver private.
+ * @buf:  DMA buffer to pin or unpin.
+ * @pin:  Pin buffer in vram if true.
+ * @interruptible:  Use interruptible wait.
+ *
+ * Takes the current masters ttm lock in read.
+ *
+ * Returns
+ * -ERESTARTSYS if interrupted by a signal.
+ */
+static int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv,
+				  struct vmw_dma_buffer *buf,
+				  bool pin, bool interruptible)
+{
+	struct ttm_buffer_object *bo = &buf->base;
+	struct ttm_placement *overlay_placement = &vmw_vram_placement;
+	int ret;
+
+	ret = ttm_read_lock(&dev_priv->active_master->lock, interruptible);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
+	if (unlikely(ret != 0))
+		goto err;
+
+	if (pin)
+		overlay_placement = &vmw_vram_ne_placement;
+
+	ret = ttm_bo_validate(bo, overlay_placement, interruptible, false);
+
+	ttm_bo_unreserve(bo);
+
+err:
+	ttm_read_unlock(&dev_priv->active_master->lock);
+
+	return ret;
+}
+
+/**
+ * Send put command to hw.
+ *
+ * Returns
+ * -ERESTARTSYS if interrupted by a signal.
+ */
+static int vmw_overlay_send_put(struct vmw_private *dev_priv,
+				struct vmw_dma_buffer *buf,
+				struct drm_vmw_control_stream_arg *arg,
+				bool interruptible)
+{
+	struct {
+		struct vmw_escape_header escape;
+		struct {
+			struct {
+				uint32_t cmdType;
+				uint32_t streamId;
+			} header;
+			struct {
+				uint32_t registerId;
+				uint32_t value;
+			} items[SVGA_VIDEO_PITCH_3 + 1];
+		} body;
+		struct vmw_escape_video_flush flush;
+	} *cmds;
+	uint32_t offset;
+	int i, ret;
+
+	for (;;) {
+		cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds));
+		if (cmds)
+			break;
+
+		ret = vmw_fallback_wait(dev_priv, false, true, 0,
+					interruptible, 3*HZ);
+		if (interruptible && ret == -ERESTARTSYS)
+			return ret;
+		else
+			BUG_ON(ret != 0);
+	}
+
+	fill_escape(&cmds->escape, sizeof(cmds->body));
+	cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
+	cmds->body.header.streamId = arg->stream_id;
+
+	for (i = 0; i <= SVGA_VIDEO_PITCH_3; i++)
+		cmds->body.items[i].registerId = i;
+
+	offset = buf->base.offset + arg->offset;
+
+	cmds->body.items[SVGA_VIDEO_ENABLED].value     = true;
+	cmds->body.items[SVGA_VIDEO_FLAGS].value       = arg->flags;
+	cmds->body.items[SVGA_VIDEO_DATA_OFFSET].value = offset;
+	cmds->body.items[SVGA_VIDEO_FORMAT].value      = arg->format;
+	cmds->body.items[SVGA_VIDEO_COLORKEY].value    = arg->color_key;
+	cmds->body.items[SVGA_VIDEO_SIZE].value        = arg->size;
+	cmds->body.items[SVGA_VIDEO_WIDTH].value       = arg->width;
+	cmds->body.items[SVGA_VIDEO_HEIGHT].value      = arg->height;
+	cmds->body.items[SVGA_VIDEO_SRC_X].value       = arg->src.x;
+	cmds->body.items[SVGA_VIDEO_SRC_Y].value       = arg->src.y;
+	cmds->body.items[SVGA_VIDEO_SRC_WIDTH].value   = arg->src.w;
+	cmds->body.items[SVGA_VIDEO_SRC_HEIGHT].value  = arg->src.h;
+	cmds->body.items[SVGA_VIDEO_DST_X].value       = arg->dst.x;
+	cmds->body.items[SVGA_VIDEO_DST_Y].value       = arg->dst.y;
+	cmds->body.items[SVGA_VIDEO_DST_WIDTH].value   = arg->dst.w;
+	cmds->body.items[SVGA_VIDEO_DST_HEIGHT].value  = arg->dst.h;
+	cmds->body.items[SVGA_VIDEO_PITCH_1].value     = arg->pitch[0];
+	cmds->body.items[SVGA_VIDEO_PITCH_2].value     = arg->pitch[1];
+	cmds->body.items[SVGA_VIDEO_PITCH_3].value     = arg->pitch[2];
+
+	fill_flush(&cmds->flush, arg->stream_id);
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmds));
+
+	return 0;
+}
+
+/**
+ * Send stop command to hw.
+ *
+ * Returns
+ * -ERESTARTSYS if interrupted by a signal.
+ */
+static int vmw_overlay_send_stop(struct vmw_private *dev_priv,
+				 uint32_t stream_id,
+				 bool interruptible)
+{
+	struct {
+		struct vmw_escape_header escape;
+		SVGAEscapeVideoSetRegs body;
+		struct vmw_escape_video_flush flush;
+	} *cmds;
+	int ret;
+
+	for (;;) {
+		cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds));
+		if (cmds)
+			break;
+
+		ret = vmw_fallback_wait(dev_priv, false, true, 0,
+					interruptible, 3*HZ);
+		if (interruptible && ret == -ERESTARTSYS)
+			return ret;
+		else
+			BUG_ON(ret != 0);
+	}
+
+	fill_escape(&cmds->escape, sizeof(cmds->body));
+	cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
+	cmds->body.header.streamId = stream_id;
+	cmds->body.items[0].registerId = SVGA_VIDEO_ENABLED;
+	cmds->body.items[0].value = false;
+	fill_flush(&cmds->flush, stream_id);
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmds));
+
+	return 0;
+}
+
+/**
+ * Stop or pause a stream.
+ *
+ * If the stream is paused the no evict flag is removed from the buffer
+ * but left in vram. This allows for instance mode_set to evict it
+ * should it need to.
+ *
+ * The caller must hold the overlay lock.
+ *
+ * @stream_id which stream to stop/pause.
+ * @pause true to pause, false to stop completely.
+ */
+static int vmw_overlay_stop(struct vmw_private *dev_priv,
+			    uint32_t stream_id, bool pause,
+			    bool interruptible)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	struct vmw_stream *stream = &overlay->stream[stream_id];
+	int ret;
+
+	/* no buffer attached the stream is completely stopped */
+	if (!stream->buf)
+		return 0;
+
+	/* If the stream is paused this is already done */
+	if (!stream->paused) {
+		ret = vmw_overlay_send_stop(dev_priv, stream_id,
+					    interruptible);
+		if (ret)
+			return ret;
+
+		/* We just remove the NO_EVICT flag so no -ENOMEM */
+		ret = vmw_dmabuf_pin_in_vram(dev_priv, stream->buf, false,
+					     interruptible);
+		if (interruptible && ret == -ERESTARTSYS)
+			return ret;
+		else
+			BUG_ON(ret != 0);
+	}
+
+	if (!pause) {
+		vmw_dmabuf_unreference(&stream->buf);
+		stream->paused = false;
+	} else {
+		stream->paused = true;
+	}
+
+	return 0;
+}
+
+/**
+ * Update a stream and send any put or stop fifo commands needed.
+ *
+ * The caller must hold the overlay lock.
+ *
+ * Returns
+ * -ENOMEM if buffer doesn't fit in vram.
+ * -ERESTARTSYS if interrupted.
+ */
+static int vmw_overlay_update_stream(struct vmw_private *dev_priv,
+				     struct vmw_dma_buffer *buf,
+				     struct drm_vmw_control_stream_arg *arg,
+				     bool interruptible)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	struct vmw_stream *stream = &overlay->stream[arg->stream_id];
+	int ret = 0;
+
+	if (!buf)
+		return -EINVAL;
+
+	DRM_DEBUG("   %s: old %p, new %p, %spaused\n", __func__,
+		  stream->buf, buf, stream->paused ? "" : "not ");
+
+	if (stream->buf != buf) {
+		ret = vmw_overlay_stop(dev_priv, arg->stream_id,
+				       false, interruptible);
+		if (ret)
+			return ret;
+	} else if (!stream->paused) {
+		/* If the buffers match and not paused then just send
+		 * the put command, no need to do anything else.
+		 */
+		ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible);
+		if (ret == 0)
+			stream->saved = *arg;
+		else
+			BUG_ON(!interruptible);
+
+		return ret;
+	}
+
+	/* We don't start the old stream if we are interrupted.
+	 * Might return -ENOMEM if it can't fit the buffer in vram.
+	 */
+	ret = vmw_dmabuf_pin_in_vram(dev_priv, buf, true, interruptible);
+	if (ret)
+		return ret;
+
+	ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible);
+	if (ret) {
+		/* This one needs to happen no matter what. We only remove
+		 * the NO_EVICT flag so this is safe from -ENOMEM.
+		 */
+		BUG_ON(vmw_dmabuf_pin_in_vram(dev_priv, buf, false, false) != 0);
+		return ret;
+	}
+
+	if (stream->buf != buf)
+		stream->buf = vmw_dmabuf_reference(buf);
+	stream->saved = *arg;
+
+	return 0;
+}
+
+/**
+ * Stop all streams.
+ *
+ * Used by the fb code when starting.
+ *
+ * Takes the overlay lock.
+ */
+int vmw_overlay_stop_all(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	int i, ret;
+
+	if (!overlay)
+		return 0;
+
+	mutex_lock(&overlay->mutex);
+
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+		struct vmw_stream *stream = &overlay->stream[i];
+		if (!stream->buf)
+			continue;
+
+		ret = vmw_overlay_stop(dev_priv, i, false, false);
+		WARN_ON(ret != 0);
+	}
+
+	mutex_unlock(&overlay->mutex);
+
+	return 0;
+}
+
+/**
+ * Try to resume all paused streams.
+ *
+ * Used by the kms code after moving a new scanout buffer to vram.
+ *
+ * Takes the overlay lock.
+ */
+int vmw_overlay_resume_all(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	int i, ret;
+
+	if (!overlay)
+		return 0;
+
+	mutex_lock(&overlay->mutex);
+
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+		struct vmw_stream *stream = &overlay->stream[i];
+		if (!stream->paused)
+			continue;
+
+		ret = vmw_overlay_update_stream(dev_priv, stream->buf,
+						&stream->saved, false);
+		if (ret != 0)
+			DRM_INFO("%s: *warning* failed to resume stream %i\n",
+				 __func__, i);
+	}
+
+	mutex_unlock(&overlay->mutex);
+
+	return 0;
+}
+
+/**
+ * Pauses all active streams.
+ *
+ * Used by the kms code when moving a new scanout buffer to vram.
+ *
+ * Takes the overlay lock.
+ */
+int vmw_overlay_pause_all(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	int i, ret;
+
+	if (!overlay)
+		return 0;
+
+	mutex_lock(&overlay->mutex);
+
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+		if (overlay->stream[i].paused)
+			DRM_INFO("%s: *warning* stream %i already paused\n",
+				 __func__, i);
+		ret = vmw_overlay_stop(dev_priv, i, true, false);
+		WARN_ON(ret != 0);
+	}
+
+	mutex_unlock(&overlay->mutex);
+
+	return 0;
+}
+
+int vmw_overlay_ioctl(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv)
+{
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	struct drm_vmw_control_stream_arg *arg =
+	    (struct drm_vmw_control_stream_arg *)data;
+	struct vmw_dma_buffer *buf;
+	struct vmw_resource *res;
+	int ret;
+
+	if (!overlay)
+		return -ENOSYS;
+
+	ret = vmw_user_stream_lookup(dev_priv, tfile, &arg->stream_id, &res);
+	if (ret)
+		return ret;
+
+	mutex_lock(&overlay->mutex);
+
+	if (!arg->enabled) {
+		ret = vmw_overlay_stop(dev_priv, arg->stream_id, false, true);
+		goto out_unlock;
+	}
+
+	ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &buf);
+	if (ret)
+		goto out_unlock;
+
+	ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);
+
+	vmw_dmabuf_unreference(&buf);
+
+out_unlock:
+	mutex_unlock(&overlay->mutex);
+	vmw_resource_unreference(&res);
+
+	return ret;
+}
+
+int vmw_overlay_num_overlays(struct vmw_private *dev_priv)
+{
+	if (!dev_priv->overlay_priv)
+		return 0;
+
+	return VMW_MAX_NUM_STREAMS;
+}
+
+int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	int i, k;
+
+	if (!overlay)
+		return 0;
+
+	mutex_lock(&overlay->mutex);
+
+	for (i = 0, k = 0; i < VMW_MAX_NUM_STREAMS; i++)
+		if (!overlay->stream[i].claimed)
+			k++;
+
+	mutex_unlock(&overlay->mutex);
+
+	return k;
+}
+
+int vmw_overlay_claim(struct vmw_private *dev_priv, uint32_t *out)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	int i;
+
+	if (!overlay)
+		return -ENOSYS;
+
+	mutex_lock(&overlay->mutex);
+
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+
+		if (overlay->stream[i].claimed)
+			continue;
+
+		overlay->stream[i].claimed = true;
+		*out = i;
+		mutex_unlock(&overlay->mutex);
+		return 0;
+	}
+
+	mutex_unlock(&overlay->mutex);
+	return -ESRCH;
+}
+
+int vmw_overlay_unref(struct vmw_private *dev_priv, uint32_t stream_id)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+
+	BUG_ON(stream_id >= VMW_MAX_NUM_STREAMS);
+
+	if (!overlay)
+		return -ENOSYS;
+
+	mutex_lock(&overlay->mutex);
+
+	WARN_ON(!overlay->stream[stream_id].claimed);
+	vmw_overlay_stop(dev_priv, stream_id, false, false);
+	overlay->stream[stream_id].claimed = false;
+
+	mutex_unlock(&overlay->mutex);
+	return 0;
+}
+
+int vmw_overlay_init(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay;
+	int i;
+
+	if (dev_priv->overlay_priv)
+		return -EINVAL;
+
+	if (!(dev_priv->fifo.capabilities & SVGA_FIFO_CAP_VIDEO) &&
+	     (dev_priv->fifo.capabilities & SVGA_FIFO_CAP_ESCAPE)) {
+		DRM_INFO("hardware doesn't support overlays\n");
+		return -ENOSYS;
+	}
+
+	overlay = kmalloc(GFP_KERNEL, sizeof(*overlay));
+	if (!overlay)
+		return -ENOMEM;
+
+	memset(overlay, 0, sizeof(*overlay));
+	mutex_init(&overlay->mutex);
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+		overlay->stream[i].buf = NULL;
+		overlay->stream[i].paused = false;
+		overlay->stream[i].claimed = false;
+	}
+
+	dev_priv->overlay_priv = overlay;
+
+	return 0;
+}
+
+int vmw_overlay_close(struct vmw_private *dev_priv)
+{
+	struct vmw_overlay *overlay = dev_priv->overlay_priv;
+	bool forgotten_buffer = false;
+	int i;
+
+	if (!overlay)
+		return -ENOSYS;
+
+	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
+		if (overlay->stream[i].buf) {
+			forgotten_buffer = true;
+			vmw_overlay_stop(dev_priv, i, false, false);
+		}
+	}
+
+	WARN_ON(forgotten_buffer);
+
+	dev_priv->overlay_priv = NULL;
+	kfree(overlay);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+/**
+ * This file contains virtual hardware defines for kernel space.
+ */
+
+#ifndef _VMWGFX_REG_H_
+#define _VMWGFX_REG_H_
+
+#include <linux/types.h>
+
+#define VMWGFX_INDEX_PORT     0x0
+#define VMWGFX_VALUE_PORT     0x1
+#define VMWGFX_IRQSTATUS_PORT 0x8
+
+struct svga_guest_mem_descriptor {
+	__le32 ppn;
+	__le32 num_pages;
+};
+
+struct svga_fifo_cmd_fence {
+	__le32 fence;
+};
+
+#define SVGA_SYNC_GENERIC         1
+#define SVGA_SYNC_FIFOFULL        2
+
+#include "svga_types.h"
+
+#include "svga3d_reg.h"
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1187 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "vmwgfx_drm.h"
+#include "ttm/ttm_object.h"
+#include "ttm/ttm_placement.h"
+#include "drmP.h"
+
+#define VMW_RES_CONTEXT ttm_driver_type0
+#define VMW_RES_SURFACE ttm_driver_type1
+#define VMW_RES_STREAM ttm_driver_type2
+
+struct vmw_user_context {
+	struct ttm_base_object base;
+	struct vmw_resource res;
+};
+
+struct vmw_user_surface {
+	struct ttm_base_object base;
+	struct vmw_surface srf;
+};
+
+struct vmw_user_dma_buffer {
+	struct ttm_base_object base;
+	struct vmw_dma_buffer dma;
+};
+
+struct vmw_bo_user_rep {
+	uint32_t handle;
+	uint64_t map_handle;
+};
+
+struct vmw_stream {
+	struct vmw_resource res;
+	uint32_t stream_id;
+};
+
+struct vmw_user_stream {
+	struct ttm_base_object base;
+	struct vmw_stream stream;
+};
+
+static inline struct vmw_dma_buffer *
+vmw_dma_buffer(struct ttm_buffer_object *bo)
+{
+	return container_of(bo, struct vmw_dma_buffer, base);
+}
+
+static inline struct vmw_user_dma_buffer *
+vmw_user_dma_buffer(struct ttm_buffer_object *bo)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+	return container_of(vmw_bo, struct vmw_user_dma_buffer, dma);
+}
+
+struct vmw_resource *vmw_resource_reference(struct vmw_resource *res)
+{
+	kref_get(&res->kref);
+	return res;
+}
+
+static void vmw_resource_release(struct kref *kref)
+{
+	struct vmw_resource *res =
+	    container_of(kref, struct vmw_resource, kref);
+	struct vmw_private *dev_priv = res->dev_priv;
+
+	idr_remove(res->idr, res->id);
+	write_unlock(&dev_priv->resource_lock);
+
+	if (likely(res->hw_destroy != NULL))
+		res->hw_destroy(res);
+
+	if (res->res_free != NULL)
+		res->res_free(res);
+	else
+		kfree(res);
+
+	write_lock(&dev_priv->resource_lock);
+}
+
+void vmw_resource_unreference(struct vmw_resource **p_res)
+{
+	struct vmw_resource *res = *p_res;
+	struct vmw_private *dev_priv = res->dev_priv;
+
+	*p_res = NULL;
+	write_lock(&dev_priv->resource_lock);
+	kref_put(&res->kref, vmw_resource_release);
+	write_unlock(&dev_priv->resource_lock);
+}
+
+static int vmw_resource_init(struct vmw_private *dev_priv,
+			     struct vmw_resource *res,
+			     struct idr *idr,
+			     enum ttm_object_type obj_type,
+			     void (*res_free) (struct vmw_resource *res))
+{
+	int ret;
+
+	kref_init(&res->kref);
+	res->hw_destroy = NULL;
+	res->res_free = res_free;
+	res->res_type = obj_type;
+	res->idr = idr;
+	res->avail = false;
+	res->dev_priv = dev_priv;
+
+	do {
+		if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
+			return -ENOMEM;
+
+		write_lock(&dev_priv->resource_lock);
+		ret = idr_get_new_above(idr, res, 1, &res->id);
+		write_unlock(&dev_priv->resource_lock);
+
+	} while (ret == -EAGAIN);
+
+	return ret;
+}
+
+/**
+ * vmw_resource_activate
+ *
+ * @res:        Pointer to the newly created resource
+ * @hw_destroy: Destroy function. NULL if none.
+ *
+ * Activate a resource after the hardware has been made aware of it.
+ * Set tye destroy function to @destroy. Typically this frees the
+ * resource and destroys the hardware resources associated with it.
+ * Activate basically means that the function vmw_resource_lookup will
+ * find it.
+ */
+
+static void vmw_resource_activate(struct vmw_resource *res,
+				  void (*hw_destroy) (struct vmw_resource *))
+{
+	struct vmw_private *dev_priv = res->dev_priv;
+
+	write_lock(&dev_priv->resource_lock);
+	res->avail = true;
+	res->hw_destroy = hw_destroy;
+	write_unlock(&dev_priv->resource_lock);
+}
+
+struct vmw_resource *vmw_resource_lookup(struct vmw_private *dev_priv,
+					 struct idr *idr, int id)
+{
+	struct vmw_resource *res;
+
+	read_lock(&dev_priv->resource_lock);
+	res = idr_find(idr, id);
+	if (res && res->avail)
+		kref_get(&res->kref);
+	else
+		res = NULL;
+	read_unlock(&dev_priv->resource_lock);
+
+	if (unlikely(res == NULL))
+		return NULL;
+
+	return res;
+}
+
+/**
+ * Context management:
+ */
+
+static void vmw_hw_context_destroy(struct vmw_resource *res)
+{
+
+	struct vmw_private *dev_priv = res->dev_priv;
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdDestroyContext body;
+	} *cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
+
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Failed reserving FIFO space for surface "
+			  "destruction.\n");
+		return;
+	}
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DESTROY);
+	cmd->header.size = cpu_to_le32(sizeof(cmd->body));
+	cmd->body.cid = cpu_to_le32(res->id);
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmd));
+}
+
+static int vmw_context_init(struct vmw_private *dev_priv,
+			    struct vmw_resource *res,
+			    void (*res_free) (struct vmw_resource *res))
+{
+	int ret;
+
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdDefineContext body;
+	} *cmd;
+
+	ret = vmw_resource_init(dev_priv, res, &dev_priv->context_idr,
+				VMW_RES_CONTEXT, res_free);
+
+	if (unlikely(ret != 0)) {
+		if (res_free == NULL)
+			kfree(res);
+		else
+			res_free(res);
+		return ret;
+	}
+
+	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed.\n");
+		vmw_resource_unreference(&res);
+		return -ENOMEM;
+	}
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DEFINE);
+	cmd->header.size = cpu_to_le32(sizeof(cmd->body));
+	cmd->body.cid = cpu_to_le32(res->id);
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmd));
+	vmw_resource_activate(res, vmw_hw_context_destroy);
+	return 0;
+}
+
+struct vmw_resource *vmw_context_alloc(struct vmw_private *dev_priv)
+{
+	struct vmw_resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+	int ret;
+
+	if (unlikely(res == NULL))
+		return NULL;
+
+	ret = vmw_context_init(dev_priv, res, NULL);
+	return (ret == 0) ? res : NULL;
+}
+
+/**
+ * User-space context management:
+ */
+
+static void vmw_user_context_free(struct vmw_resource *res)
+{
+	struct vmw_user_context *ctx =
+	    container_of(res, struct vmw_user_context, res);
+
+	kfree(ctx);
+}
+
+/**
+ * This function is called when user space has no more references on the
+ * base object. It releases the base-object's reference on the resource object.
+ */
+
+static void vmw_user_context_base_release(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct vmw_user_context *ctx =
+	    container_of(base, struct vmw_user_context, base);
+	struct vmw_resource *res = &ctx->res;
+
+	*p_base = NULL;
+	vmw_resource_unreference(&res);
+}
+
+int vmw_context_destroy_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_resource *res;
+	struct vmw_user_context *ctx;
+	struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	int ret = 0;
+
+	res = vmw_resource_lookup(dev_priv, &dev_priv->context_idr, arg->cid);
+	if (unlikely(res == NULL))
+		return -EINVAL;
+
+	if (res->res_free != &vmw_user_context_free) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ctx = container_of(res, struct vmw_user_context, res);
+	if (ctx->base.tfile != tfile && !ctx->base.shareable) {
+		ret = -EPERM;
+		goto out;
+	}
+
+	ttm_ref_object_base_unref(tfile, ctx->base.hash.key, TTM_REF_USAGE);
+out:
+	vmw_resource_unreference(&res);
+	return ret;
+}
+
+int vmw_context_define_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_user_context *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+	struct vmw_resource *res;
+	struct vmw_resource *tmp;
+	struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	int ret;
+
+	if (unlikely(ctx == NULL))
+		return -ENOMEM;
+
+	res = &ctx->res;
+	ctx->base.shareable = false;
+	ctx->base.tfile = NULL;
+
+	ret = vmw_context_init(dev_priv, res, vmw_user_context_free);
+	if (unlikely(ret != 0))
+		return ret;
+
+	tmp = vmw_resource_reference(&ctx->res);
+	ret = ttm_base_object_init(tfile, &ctx->base, false, VMW_RES_CONTEXT,
+				   &vmw_user_context_base_release, NULL);
+
+	if (unlikely(ret != 0)) {
+		vmw_resource_unreference(&tmp);
+		goto out_err;
+	}
+
+	arg->cid = res->id;
+out_err:
+	vmw_resource_unreference(&res);
+	return ret;
+
+}
+
+int vmw_context_check(struct vmw_private *dev_priv,
+		      struct ttm_object_file *tfile,
+		      int id)
+{
+	struct vmw_resource *res;
+	int ret = 0;
+
+	read_lock(&dev_priv->resource_lock);
+	res = idr_find(&dev_priv->context_idr, id);
+	if (res && res->avail) {
+		struct vmw_user_context *ctx =
+			container_of(res, struct vmw_user_context, res);
+		if (ctx->base.tfile != tfile && !ctx->base.shareable)
+			ret = -EPERM;
+	} else
+		ret = -EINVAL;
+	read_unlock(&dev_priv->resource_lock);
+
+	return ret;
+}
+
+
+/**
+ * Surface management.
+ */
+
+static void vmw_hw_surface_destroy(struct vmw_resource *res)
+{
+
+	struct vmw_private *dev_priv = res->dev_priv;
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdDestroySurface body;
+	} *cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
+
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Failed reserving FIFO space for surface "
+			  "destruction.\n");
+		return;
+	}
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_SURFACE_DESTROY);
+	cmd->header.size = cpu_to_le32(sizeof(cmd->body));
+	cmd->body.sid = cpu_to_le32(res->id);
+
+	vmw_fifo_commit(dev_priv, sizeof(*cmd));
+}
+
+void vmw_surface_res_free(struct vmw_resource *res)
+{
+	struct vmw_surface *srf = container_of(res, struct vmw_surface, res);
+
+	kfree(srf->sizes);
+	kfree(srf->snooper.image);
+	kfree(srf);
+}
+
+int vmw_surface_init(struct vmw_private *dev_priv,
+		     struct vmw_surface *srf,
+		     void (*res_free) (struct vmw_resource *res))
+{
+	int ret;
+	struct {
+		SVGA3dCmdHeader header;
+		SVGA3dCmdDefineSurface body;
+	} *cmd;
+	SVGA3dSize *cmd_size;
+	struct vmw_resource *res = &srf->res;
+	struct drm_vmw_size *src_size;
+	size_t submit_size;
+	uint32_t cmd_len;
+	int i;
+
+	BUG_ON(res_free == NULL);
+	ret = vmw_resource_init(dev_priv, res, &dev_priv->surface_idr,
+				VMW_RES_SURFACE, res_free);
+
+	if (unlikely(ret != 0)) {
+		res_free(res);
+		return ret;
+	}
+
+	submit_size = sizeof(*cmd) + srf->num_sizes * sizeof(SVGA3dSize);
+	cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize);
+
+	cmd = vmw_fifo_reserve(dev_priv, submit_size);
+	if (unlikely(cmd == NULL)) {
+		DRM_ERROR("Fifo reserve failed for create surface.\n");
+		vmw_resource_unreference(&res);
+		return -ENOMEM;
+	}
+
+	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_SURFACE_DEFINE);
+	cmd->header.size = cpu_to_le32(cmd_len);
+	cmd->body.sid = cpu_to_le32(res->id);
+	cmd->body.surfaceFlags = cpu_to_le32(srf->flags);
+	cmd->body.format = cpu_to_le32(srf->format);
+	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
+		cmd->body.face[i].numMipLevels =
+		    cpu_to_le32(srf->mip_levels[i]);
+	}
+
+	cmd += 1;
+	cmd_size = (SVGA3dSize *) cmd;
+	src_size = srf->sizes;
+
+	for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) {
+		cmd_size->width = cpu_to_le32(src_size->width);
+		cmd_size->height = cpu_to_le32(src_size->height);
+		cmd_size->depth = cpu_to_le32(src_size->depth);
+	}
+
+	vmw_fifo_commit(dev_priv, submit_size);
+	vmw_resource_activate(res, vmw_hw_surface_destroy);
+	return 0;
+}
+
+static void vmw_user_surface_free(struct vmw_resource *res)
+{
+	struct vmw_surface *srf = container_of(res, struct vmw_surface, res);
+	struct vmw_user_surface *user_srf =
+	    container_of(srf, struct vmw_user_surface, srf);
+
+	kfree(srf->sizes);
+	kfree(srf->snooper.image);
+	kfree(user_srf);
+}
+
+int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv,
+				   struct ttm_object_file *tfile,
+				   uint32_t handle, struct vmw_surface **out)
+{
+	struct vmw_resource *res;
+	struct vmw_surface *srf;
+	struct vmw_user_surface *user_srf;
+	struct ttm_base_object *base;
+	int ret = -EINVAL;
+
+	base = ttm_base_object_lookup(tfile, handle);
+	if (unlikely(base == NULL))
+		return -EINVAL;
+
+	if (unlikely(base->object_type != VMW_RES_SURFACE))
+		goto out_bad_resource;
+
+	user_srf = container_of(base, struct vmw_user_surface, base);
+	srf = &user_srf->srf;
+	res = &srf->res;
+
+	read_lock(&dev_priv->resource_lock);
+
+	if (!res->avail || res->res_free != &vmw_user_surface_free) {
+		read_unlock(&dev_priv->resource_lock);
+		goto out_bad_resource;
+	}
+
+	kref_get(&res->kref);
+	read_unlock(&dev_priv->resource_lock);
+
+	*out = srf;
+	ret = 0;
+
+out_bad_resource:
+	ttm_base_object_unref(&base);
+
+	return ret;
+}
+
+static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct vmw_user_surface *user_srf =
+	    container_of(base, struct vmw_user_surface, base);
+	struct vmw_resource *res = &user_srf->srf.res;
+
+	*p_base = NULL;
+	vmw_resource_unreference(&res);
+}
+
+int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv)
+{
+	struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+
+	return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE);
+}
+
+int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_user_surface *user_srf =
+	    kmalloc(sizeof(*user_srf), GFP_KERNEL);
+	struct vmw_surface *srf;
+	struct vmw_resource *res;
+	struct vmw_resource *tmp;
+	union drm_vmw_surface_create_arg *arg =
+	    (union drm_vmw_surface_create_arg *)data;
+	struct drm_vmw_surface_create_req *req = &arg->req;
+	struct drm_vmw_surface_arg *rep = &arg->rep;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct drm_vmw_size __user *user_sizes;
+	int ret;
+	int i;
+
+	if (unlikely(user_srf == NULL))
+		return -ENOMEM;
+
+	srf = &user_srf->srf;
+	res = &srf->res;
+
+	srf->flags = req->flags;
+	srf->format = req->format;
+	srf->scanout = req->scanout;
+	memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels));
+	srf->num_sizes = 0;
+	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
+		srf->num_sizes += srf->mip_levels[i];
+
+	if (srf->num_sizes > DRM_VMW_MAX_SURFACE_FACES *
+	    DRM_VMW_MAX_MIP_LEVELS) {
+		ret = -EINVAL;
+		goto out_err0;
+	}
+
+	srf->sizes = kmalloc(srf->num_sizes * sizeof(*srf->sizes), GFP_KERNEL);
+	if (unlikely(srf->sizes == NULL)) {
+		ret = -ENOMEM;
+		goto out_err0;
+	}
+
+	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
+	    req->size_addr;
+
+	ret = copy_from_user(srf->sizes, user_sizes,
+			     srf->num_sizes * sizeof(*srf->sizes));
+	if (unlikely(ret != 0))
+		goto out_err1;
+
+	if (srf->scanout &&
+	    srf->num_sizes == 1 &&
+	    srf->sizes[0].width == 64 &&
+	    srf->sizes[0].height == 64 &&
+	    srf->format == SVGA3D_A8R8G8B8) {
+
+		srf->snooper.image = kmalloc(64 * 64 * 4, GFP_KERNEL);
+		/* clear the image */
+		if (srf->snooper.image) {
+			memset(srf->snooper.image, 0x00, 64 * 64 * 4);
+		} else {
+			DRM_ERROR("Failed to allocate cursor_image\n");
+			ret = -ENOMEM;
+			goto out_err1;
+		}
+	} else {
+		srf->snooper.image = NULL;
+	}
+	srf->snooper.crtc = NULL;
+
+	user_srf->base.shareable = false;
+	user_srf->base.tfile = NULL;
+
+	/**
+	 * From this point, the generic resource management functions
+	 * destroy the object on failure.
+	 */
+
+	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
+	if (unlikely(ret != 0))
+		return ret;
+
+	tmp = vmw_resource_reference(&srf->res);
+	ret = ttm_base_object_init(tfile, &user_srf->base,
+				   req->shareable, VMW_RES_SURFACE,
+				   &vmw_user_surface_base_release, NULL);
+
+	if (unlikely(ret != 0)) {
+		vmw_resource_unreference(&tmp);
+		vmw_resource_unreference(&res);
+		return ret;
+	}
+
+	rep->sid = user_srf->base.hash.key;
+	if (rep->sid == SVGA3D_INVALID_ID)
+		DRM_ERROR("Created bad Surface ID.\n");
+
+	vmw_resource_unreference(&res);
+	return 0;
+out_err1:
+	kfree(srf->sizes);
+out_err0:
+	kfree(user_srf);
+	return ret;
+}
+
+int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	union drm_vmw_surface_reference_arg *arg =
+	    (union drm_vmw_surface_reference_arg *)data;
+	struct drm_vmw_surface_arg *req = &arg->req;
+	struct drm_vmw_surface_create_req *rep = &arg->rep;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct vmw_surface *srf;
+	struct vmw_user_surface *user_srf;
+	struct drm_vmw_size __user *user_sizes;
+	struct ttm_base_object *base;
+	int ret = -EINVAL;
+
+	base = ttm_base_object_lookup(tfile, req->sid);
+	if (unlikely(base == NULL)) {
+		DRM_ERROR("Could not find surface to reference.\n");
+		return -EINVAL;
+	}
+
+	if (unlikely(base->object_type != VMW_RES_SURFACE))
+		goto out_bad_resource;
+
+	user_srf = container_of(base, struct vmw_user_surface, base);
+	srf = &user_srf->srf;
+
+	ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Could not add a reference to a surface.\n");
+		goto out_no_reference;
+	}
+
+	rep->flags = srf->flags;
+	rep->format = srf->format;
+	memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels));
+	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
+	    rep->size_addr;
+
+	if (user_sizes)
+		ret = copy_to_user(user_sizes, srf->sizes,
+				   srf->num_sizes * sizeof(*srf->sizes));
+	if (unlikely(ret != 0))
+		DRM_ERROR("copy_to_user failed %p %u\n",
+			  user_sizes, srf->num_sizes);
+out_bad_resource:
+out_no_reference:
+	ttm_base_object_unref(&base);
+
+	return ret;
+}
+
+int vmw_surface_check(struct vmw_private *dev_priv,
+		      struct ttm_object_file *tfile,
+		      uint32_t handle, int *id)
+{
+	struct ttm_base_object *base;
+	struct vmw_user_surface *user_srf;
+
+	int ret = -EPERM;
+
+	base = ttm_base_object_lookup(tfile, handle);
+	if (unlikely(base == NULL))
+		return -EINVAL;
+
+	if (unlikely(base->object_type != VMW_RES_SURFACE))
+		goto out_bad_surface;
+
+	user_srf = container_of(base, struct vmw_user_surface, base);
+	*id = user_srf->srf.res.id;
+	ret = 0;
+
+out_bad_surface:
+	/**
+	 * FIXME: May deadlock here when called from the
+	 * command parsing code.
+	 */
+
+	ttm_base_object_unref(&base);
+	return ret;
+}
+
+/**
+ * Buffer management.
+ */
+
+static size_t vmw_dmabuf_acc_size(struct ttm_bo_global *glob,
+				  unsigned long num_pages)
+{
+	static size_t bo_user_size = ~0;
+
+	size_t page_array_size =
+	    (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK;
+
+	if (unlikely(bo_user_size == ~0)) {
+		bo_user_size = glob->ttm_bo_extra_size +
+		    ttm_round_pot(sizeof(struct vmw_dma_buffer));
+	}
+
+	return bo_user_size + page_array_size;
+}
+
+void vmw_dmabuf_gmr_unbind(struct ttm_buffer_object *bo)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+	struct ttm_bo_global *glob = bo->glob;
+	struct vmw_private *dev_priv =
+		container_of(bo->bdev, struct vmw_private, bdev);
+
+	if (vmw_bo->gmr_bound) {
+		vmw_gmr_unbind(dev_priv, vmw_bo->gmr_id);
+		spin_lock(&glob->lru_lock);
+		ida_remove(&dev_priv->gmr_ida, vmw_bo->gmr_id);
+		spin_unlock(&glob->lru_lock);
+		vmw_bo->gmr_bound = false;
+	}
+}
+
+void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+	struct ttm_bo_global *glob = bo->glob;
+
+	vmw_dmabuf_gmr_unbind(bo);
+	ttm_mem_global_free(glob->mem_glob, bo->acc_size);
+	kfree(vmw_bo);
+}
+
+int vmw_dmabuf_init(struct vmw_private *dev_priv,
+		    struct vmw_dma_buffer *vmw_bo,
+		    size_t size, struct ttm_placement *placement,
+		    bool interruptible,
+		    void (*bo_free) (struct ttm_buffer_object *bo))
+{
+	struct ttm_bo_device *bdev = &dev_priv->bdev;
+	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	size_t acc_size;
+	int ret;
+
+	BUG_ON(!bo_free);
+
+	acc_size =
+	    vmw_dmabuf_acc_size(bdev->glob,
+				(size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+
+	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+	if (unlikely(ret != 0)) {
+		/* we must free the bo here as
+		 * ttm_buffer_object_init does so as well */
+		bo_free(&vmw_bo->base);
+		return ret;
+	}
+
+	memset(vmw_bo, 0, sizeof(*vmw_bo));
+
+	INIT_LIST_HEAD(&vmw_bo->gmr_lru);
+	INIT_LIST_HEAD(&vmw_bo->validate_list);
+	vmw_bo->gmr_id = 0;
+	vmw_bo->gmr_bound = false;
+
+	ret = ttm_bo_init(bdev, &vmw_bo->base, size,
+			  ttm_bo_type_device, placement,
+			  0, 0, interruptible,
+			  NULL, acc_size, bo_free);
+	return ret;
+}
+
+static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo)
+{
+	struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo);
+	struct ttm_bo_global *glob = bo->glob;
+
+	vmw_dmabuf_gmr_unbind(bo);
+	ttm_mem_global_free(glob->mem_glob, bo->acc_size);
+	kfree(vmw_user_bo);
+}
+
+static void vmw_user_dmabuf_release(struct ttm_base_object **p_base)
+{
+	struct vmw_user_dma_buffer *vmw_user_bo;
+	struct ttm_base_object *base = *p_base;
+	struct ttm_buffer_object *bo;
+
+	*p_base = NULL;
+
+	if (unlikely(base == NULL))
+		return;
+
+	vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
+	bo = &vmw_user_bo->dma.base;
+	ttm_bo_unref(&bo);
+}
+
+int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	union drm_vmw_alloc_dmabuf_arg *arg =
+	    (union drm_vmw_alloc_dmabuf_arg *)data;
+	struct drm_vmw_alloc_dmabuf_req *req = &arg->req;
+	struct drm_vmw_dmabuf_rep *rep = &arg->rep;
+	struct vmw_user_dma_buffer *vmw_user_bo;
+	struct ttm_buffer_object *tmp;
+	struct vmw_master *vmaster = vmw_master(file_priv->master);
+	int ret;
+
+	vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
+	if (unlikely(vmw_user_bo == NULL))
+		return -ENOMEM;
+
+	ret = ttm_read_lock(&vmaster->lock, true);
+	if (unlikely(ret != 0)) {
+		kfree(vmw_user_bo);
+		return ret;
+	}
+
+	ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, req->size,
+			      &vmw_vram_sys_placement, true,
+			      &vmw_user_dmabuf_destroy);
+	if (unlikely(ret != 0))
+		return ret;
+
+	tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
+	ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
+				   &vmw_user_bo->base,
+				   false,
+				   ttm_buffer_type,
+				   &vmw_user_dmabuf_release, NULL);
+	if (unlikely(ret != 0)) {
+		ttm_bo_unref(&tmp);
+	} else {
+		rep->handle = vmw_user_bo->base.hash.key;
+		rep->map_handle = vmw_user_bo->dma.base.addr_space_offset;
+		rep->cur_gmr_id = vmw_user_bo->base.hash.key;
+		rep->cur_gmr_offset = 0;
+	}
+	ttm_bo_unref(&tmp);
+
+	ttm_read_unlock(&vmaster->lock);
+
+	return 0;
+}
+
+int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_vmw_unref_dmabuf_arg *arg =
+	    (struct drm_vmw_unref_dmabuf_arg *)data;
+
+	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
+					 arg->handle,
+					 TTM_REF_USAGE);
+}
+
+uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo,
+				  uint32_t cur_validate_node)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+
+	if (likely(vmw_bo->on_validate_list))
+		return vmw_bo->cur_validate_node;
+
+	vmw_bo->cur_validate_node = cur_validate_node;
+	vmw_bo->on_validate_list = true;
+
+	return cur_validate_node;
+}
+
+void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+
+	vmw_bo->on_validate_list = false;
+}
+
+uint32_t vmw_dmabuf_gmr(struct ttm_buffer_object *bo)
+{
+	struct vmw_dma_buffer *vmw_bo;
+
+	if (bo->mem.mem_type == TTM_PL_VRAM)
+		return SVGA_GMR_FRAMEBUFFER;
+
+	vmw_bo = vmw_dma_buffer(bo);
+
+	return (vmw_bo->gmr_bound) ? vmw_bo->gmr_id : SVGA_GMR_NULL;
+}
+
+void vmw_dmabuf_set_gmr(struct ttm_buffer_object *bo, uint32_t id)
+{
+	struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
+	vmw_bo->gmr_bound = true;
+	vmw_bo->gmr_id = id;
+}
+
+int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
+			   uint32_t handle, struct vmw_dma_buffer **out)
+{
+	struct vmw_user_dma_buffer *vmw_user_bo;
+	struct ttm_base_object *base;
+
+	base = ttm_base_object_lookup(tfile, handle);
+	if (unlikely(base == NULL)) {
+		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		return -ESRCH;
+	}
+
+	if (unlikely(base->object_type != ttm_buffer_type)) {
+		ttm_base_object_unref(&base);
+		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
+		       (unsigned long)handle);
+		return -EINVAL;
+	}
+
+	vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
+	(void)ttm_bo_reference(&vmw_user_bo->dma.base);
+	ttm_base_object_unref(&base);
+	*out = &vmw_user_bo->dma;
+
+	return 0;
+}
+
+/**
+ * TODO: Implement a gmr id eviction mechanism. Currently we just fail
+ * when we're out of ids, causing GMR space to be allocated
+ * out of VRAM.
+ */
+
+int vmw_gmr_id_alloc(struct vmw_private *dev_priv, uint32_t *p_id)
+{
+	struct ttm_bo_global *glob = dev_priv->bdev.glob;
+	int id;
+	int ret;
+
+	do {
+		if (unlikely(ida_pre_get(&dev_priv->gmr_ida, GFP_KERNEL) == 0))
+			return -ENOMEM;
+
+		spin_lock(&glob->lru_lock);
+		ret = ida_get_new(&dev_priv->gmr_ida, &id);
+		spin_unlock(&glob->lru_lock);
+	} while (ret == -EAGAIN);
+
+	if (unlikely(ret != 0))
+		return ret;
+
+	if (unlikely(id >= dev_priv->max_gmr_ids)) {
+		spin_lock(&glob->lru_lock);
+		ida_remove(&dev_priv->gmr_ida, id);
+		spin_unlock(&glob->lru_lock);
+		return -EBUSY;
+	}
+
+	*p_id = (uint32_t) id;
+	return 0;
+}
+
+/*
+ * Stream managment
+ */
+
+static void vmw_stream_destroy(struct vmw_resource *res)
+{
+	struct vmw_private *dev_priv = res->dev_priv;
+	struct vmw_stream *stream;
+	int ret;
+
+	DRM_INFO("%s: unref\n", __func__);
+	stream = container_of(res, struct vmw_stream, res);
+
+	ret = vmw_overlay_unref(dev_priv, stream->stream_id);
+	WARN_ON(ret != 0);
+}
+
+static int vmw_stream_init(struct vmw_private *dev_priv,
+			   struct vmw_stream *stream,
+			   void (*res_free) (struct vmw_resource *res))
+{
+	struct vmw_resource *res = &stream->res;
+	int ret;
+
+	ret = vmw_resource_init(dev_priv, res, &dev_priv->stream_idr,
+				VMW_RES_STREAM, res_free);
+
+	if (unlikely(ret != 0)) {
+		if (res_free == NULL)
+			kfree(stream);
+		else
+			res_free(&stream->res);
+		return ret;
+	}
+
+	ret = vmw_overlay_claim(dev_priv, &stream->stream_id);
+	if (ret) {
+		vmw_resource_unreference(&res);
+		return ret;
+	}
+
+	DRM_INFO("%s: claimed\n", __func__);
+
+	vmw_resource_activate(&stream->res, vmw_stream_destroy);
+	return 0;
+}
+
+/**
+ * User-space context management:
+ */
+
+static void vmw_user_stream_free(struct vmw_resource *res)
+{
+	struct vmw_user_stream *stream =
+	    container_of(res, struct vmw_user_stream, stream.res);
+
+	kfree(stream);
+}
+
+/**
+ * This function is called when user space has no more references on the
+ * base object. It releases the base-object's reference on the resource object.
+ */
+
+static void vmw_user_stream_base_release(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct vmw_user_stream *stream =
+	    container_of(base, struct vmw_user_stream, base);
+	struct vmw_resource *res = &stream->stream.res;
+
+	*p_base = NULL;
+	vmw_resource_unreference(&res);
+}
+
+int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_resource *res;
+	struct vmw_user_stream *stream;
+	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	int ret = 0;
+
+	res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, arg->stream_id);
+	if (unlikely(res == NULL))
+		return -EINVAL;
+
+	if (res->res_free != &vmw_user_stream_free) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	stream = container_of(res, struct vmw_user_stream, stream.res);
+	if (stream->base.tfile != tfile) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ttm_ref_object_base_unref(tfile, stream->base.hash.key, TTM_REF_USAGE);
+out:
+	vmw_resource_unreference(&res);
+	return ret;
+}
+
+int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_user_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
+	struct vmw_resource *res;
+	struct vmw_resource *tmp;
+	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	int ret;
+
+	if (unlikely(stream == NULL))
+		return -ENOMEM;
+
+	res = &stream->stream.res;
+	stream->base.shareable = false;
+	stream->base.tfile = NULL;
+
+	ret = vmw_stream_init(dev_priv, &stream->stream, vmw_user_stream_free);
+	if (unlikely(ret != 0))
+		return ret;
+
+	tmp = vmw_resource_reference(res);
+	ret = ttm_base_object_init(tfile, &stream->base, false, VMW_RES_STREAM,
+				   &vmw_user_stream_base_release, NULL);
+
+	if (unlikely(ret != 0)) {
+		vmw_resource_unreference(&tmp);
+		goto out_err;
+	}
+
+	arg->stream_id = res->id;
+out_err:
+	vmw_resource_unreference(&res);
+	return ret;
+}
+
+int vmw_user_stream_lookup(struct vmw_private *dev_priv,
+			   struct ttm_object_file *tfile,
+			   uint32_t *inout_id, struct vmw_resource **out)
+{
+	struct vmw_user_stream *stream;
+	struct vmw_resource *res;
+	int ret;
+
+	res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, *inout_id);
+	if (unlikely(res == NULL))
+		return -EINVAL;
+
+	if (res->res_free != &vmw_user_stream_free) {
+		ret = -EINVAL;
+		goto err_ref;
+	}
+
+	stream = container_of(res, struct vmw_user_stream, stream.res);
+	if (stream->base.tfile != tfile) {
+		ret = -EPERM;
+		goto err_ref;
+	}
+
+	*inout_id = stream->stream.stream_id;
+	*out = res;
+	return 0;
+err_ref:
+	vmw_resource_unreference(&res);
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,99 @@
+/**************************************************************************
+ *
+ * Copyright © 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.
+ *
+ **************************************************************************/
+
+#include "drmP.h"
+#include "vmwgfx_drv.h"
+
+int vmw_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv;
+	struct vmw_private *dev_priv;
+
+	if (unlikely(vma->vm_pgoff < VMWGFX_FILE_PAGE_OFFSET)) {
+		if (vmw_fifo_mmap(filp, vma) == 0)
+			return 0;
+		return drm_mmap(filp, vma);
+	}
+
+	file_priv = (struct drm_file *)filp->private_data;
+	dev_priv = vmw_priv(file_priv->minor->dev);
+	return ttm_bo_mmap(filp, vma, &dev_priv->bdev);
+}
+
+static int vmw_ttm_mem_global_init(struct ttm_global_reference *ref)
+{
+	DRM_INFO("global init.\n");
+	return ttm_mem_global_init(ref->object);
+}
+
+static void vmw_ttm_mem_global_release(struct ttm_global_reference *ref)
+{
+	ttm_mem_global_release(ref->object);
+}
+
+int vmw_ttm_global_init(struct vmw_private *dev_priv)
+{
+	struct ttm_global_reference *global_ref;
+	int ret;
+
+	global_ref = &dev_priv->mem_global_ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+	global_ref->size = sizeof(struct ttm_mem_global);
+	global_ref->init = &vmw_ttm_mem_global_init;
+	global_ref->release = &vmw_ttm_mem_global_release;
+
+	ret = ttm_global_item_ref(global_ref);
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM memory accounting.\n");
+		return ret;
+	}
+
+	dev_priv->bo_global_ref.mem_glob =
+		dev_priv->mem_global_ref.object;
+	global_ref = &dev_priv->bo_global_ref.ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_BO;
+	global_ref->size = sizeof(struct ttm_bo_global);
+	global_ref->init = &ttm_bo_global_init;
+	global_ref->release = &ttm_bo_global_release;
+		ret = ttm_global_item_ref(global_ref);
+
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed setting up TTM buffer objects.\n");
+		goto out_no_bo;
+	}
+
+	return 0;
+out_no_bo:
+	ttm_global_item_unref(&dev_priv->mem_global_ref);
+	return ret;
+}
+
+void vmw_ttm_global_release(struct vmw_private *dev_priv)
+{
+	ttm_global_item_unref(&dev_priv->bo_global_ref.ref);
+	ttm_global_item_unref(&dev_priv->mem_global_ref);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/gpu/vga/vgaarb.c linux-libre-2.6.33-gnu1/drivers/gpu/vga/vgaarb.c
--- linux-libre-2.6.32-gnu1/drivers/gpu/vga/vgaarb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/gpu/vga/vgaarb.c	2010-02-24 13:52:17.000000000 -0500
@@ -961,7 +961,7 @@ static ssize_t vga_arb_write(struct file
 		remaining -= 7;
 		pr_devel("client 0x%p called 'target'\n", priv);
 		/* if target is default */
-		if (!strncmp(buf, "default", 7))
+		if (!strncmp(curr_pos, "default", 7))
 			pdev = pci_dev_get(vga_default_device());
 		else {
 			if (!vga_pci_str_to_vars(curr_pos, remaining,
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-apple.c linux-libre-2.6.33-gnu1/drivers/hid/hid-apple.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-apple.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-apple.c	2010-02-24 13:52:17.000000000 -0500
@@ -431,6 +431,13 @@ 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_WELLSPRING3_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),
+		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+			APPLE_ISO_KEYBOARD },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
+		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-core.c linux-libre-2.6.33-gnu1/drivers/hid/hid-core.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,6 @@
  * Version Information
  */
 
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
@@ -1287,6 +1285,9 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_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) },
 	{ 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) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
@@ -1294,6 +1295,7 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
@@ -1326,6 +1328,8 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
@@ -1552,6 +1556,7 @@ static const struct hid_device_id hid_ig
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
@@ -1620,6 +1625,7 @@ static const struct hid_device_id hid_ig
 	{ 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) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
@@ -1918,5 +1924,8 @@ static void __exit hid_exit(void)
 module_init(hid_init);
 module_exit(hid_exit);
 
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
 MODULE_LICENSE(DRIVER_LICENSE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-cypress.c linux-libre-2.6.33-gnu1/drivers/hid/hid-cypress.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-cypress.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-cypress.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,6 +126,8 @@ static const struct hid_device_id cp_dev
 		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2),
 		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),
+		.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
 		.driver_data = CP_2WHEEL_MOUSE_HACK },
 	{ }
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-ids.h linux-libre-2.6.33-gnu1/drivers/hid/hid-ids.h
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-ids.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-ids.h	2010-02-24 13:52:17.000000000 -0500
@@ -88,6 +88,9 @@
 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI	0x0236
 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO	0x0237
 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS	0x0238
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI  0x0239
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO   0x023a
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS   0x023b
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY	0x030a
 #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY	0x030b
 #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL	0x8241
@@ -117,6 +120,7 @@
 #define USB_DEVICE_ID_CH_PRO_PEDALS	0x00f2
 #define USB_DEVICE_ID_CH_COMBATSTICK	0x00f4
 #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE	0x00ff
+#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK	0x00d3
 
 #define USB_VENDOR_ID_CHERRY		0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
@@ -145,6 +149,7 @@
 #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE	0x7417
 #define USB_DEVICE_ID_CYPRESS_BARCODE_1	0xde61
 #define USB_DEVICE_ID_CYPRESS_BARCODE_2	0xde64
+#define USB_DEVICE_ID_CYPRESS_BARCODE_3	0xbca1
 
 #define USB_VENDOR_ID_DEALEXTREAME	0x10c5
 #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701	0x819a
@@ -164,6 +169,9 @@
 #define USB_VENDOR_ID_ESSENTIAL_REALITY	0x0d7f
 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
 
+#define USB_VENDOR_ID_ETT		0x0664
+#define USB_DEVICE_ID_TC5UH		0x0309
+
 #define USB_VENDOR_ID_EZKEY 		0x0518
 #define USB_DEVICE_ID_BTC_8193		0x0002
 
@@ -304,6 +312,8 @@
 #define USB_DEVICE_ID_S510_RECEIVER_2	0xc517
 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500	0xc512
 #define USB_DEVICE_ID_MX3000_RECEIVER	0xc513
+#define USB_DEVICE_ID_SPACETRAVELLER	0xc623
+#define USB_DEVICE_ID_SPACENAVIGATOR	0xc626
 #define USB_DEVICE_ID_DINOVO_DESKTOP	0xc704
 #define USB_DEVICE_ID_DINOVO_EDGE	0xc714
 #define USB_DEVICE_ID_DINOVO_MINI	0xc71f
@@ -346,6 +356,9 @@
 #define USB_VENDOR_ID_NEC		0x073e
 #define USB_DEVICE_ID_NEC_USB_GAME_PAD	0x0301
 
+#define USB_VENDOR_ID_NEXTWINDOW	0x1926
+#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN	0x0003
+
 #define USB_VENDOR_ID_NTRIG                0x1b96
 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN   0x0001
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-lg.c linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-lg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #define LG_NOGET		0x100
 #define LG_FF			0x200
 #define LG_FF2			0x400
+#define LG_RDESC_REL_ABS	0x800
 
 /*
  * Certain Logitech keyboards send in report #3 keys which are far
@@ -51,6 +52,13 @@ static void lg_report_fixup(struct hid_d
 		rdesc[84] = rdesc[89] = 0x4d;
 		rdesc[85] = rdesc[90] = 0x10;
 	}
+	if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
+			rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
+			rdesc[49] == 0x81 && rdesc[50] == 0x06) {
+		dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
+				"report descriptor\n");
+		rdesc[33] = rdesc[50] = 0x02;
+	}
 }
 
 #define lg_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
@@ -89,6 +97,22 @@ static int lg_ultrax_remote_mapping(stru
 	return 1;
 }
 
+static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+
+	case 0x00d: lg_map_key_clear(KEY_MEDIA);	break;
+	default:
+		return 0;
+
+	}
+	return 1;
+}
+
 static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
@@ -164,6 +188,10 @@ static int lg_input_mapping(struct hid_d
 			lg_ultrax_remote_mapping(hi, usage, bit, max))
 		return 1;
 
+	if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
+			lg_dinovo_mapping(hi, usage, bit, max))
+		return 1;
+
 	if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
 		return 1;
 
@@ -303,8 +331,13 @@ static const struct hid_device_id lg_dev
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
 		.driver_data = LG_FF2 },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
+		.driver_data = LG_RDESC_REL_ABS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
+		.driver_data = LG_RDESC_REL_ABS },
 	{ }
 };
+
 MODULE_DEVICE_TABLE(hid, lg_devices);
 
 static struct hid_driver lg_driver = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-lg.h linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.h
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-lg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-lg.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,6 @@
 #ifndef __HID_LG_H
 #define __HID_LG_H
 
-#include <linux/autoconf.h>
-
 #ifdef CONFIG_LOGITECH_FF
 int lgff_init(struct hid_device *hdev);
 #else
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-samsung.c linux-libre-2.6.33-gnu1/drivers/hid/hid-samsung.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-samsung.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-samsung.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,17 @@
  *
  * 3. 135 byte report descriptor
  * Report #4 has an array field with logical range 0..17 instead of 1..14.
+ *
+ * 4. 171 byte report descriptor
+ * Report #3 has an array field with logical range 0..1 instead of 1..3.
  */
+static inline void samsung_dev_trace(struct hid_device *hdev,
+		unsigned int rsize)
+{
+	dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+			"descriptor\n", rsize);
+}
+
 static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int rsize)
 {
@@ -47,8 +57,7 @@ static void samsung_report_fixup(struct
 			rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
 			rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
 			rdesc[182] == 0x40) {
-		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
-				"descriptor\n", 184);
+		samsung_dev_trace(hdev, 184);
 		rdesc[176] = 0xff;
 		rdesc[178] = 0x08;
 		rdesc[180] = 0x06;
@@ -56,17 +65,21 @@ static void samsung_report_fixup(struct
 	} else
 	if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
 			rdesc[194] == 0x25 && rdesc[195] == 0x12) {
-		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
-				"descriptor\n", 203);
+		samsung_dev_trace(hdev, 203);
 		rdesc[193] = 0x1;
 		rdesc[195] = 0xf;
 	} else
 	if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
 			rdesc[126] == 0x25 && rdesc[127] == 0x11) {
-		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
-				"descriptor\n", 135);
+		samsung_dev_trace(hdev, 135);
 		rdesc[125] = 0x1;
 		rdesc[127] = 0xe;
+	} else
+	if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
+			rdesc[162] == 0x25 && rdesc[163] == 0x01) {
+		samsung_dev_trace(hdev, 171);
+		rdesc[161] = 0x1;
+		rdesc[163] = 0x3;
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/hid-wacom.c linux-libre-2.6.33-gnu1/drivers/hid/hid-wacom.c
--- linux-libre-2.6.32-gnu1/drivers/hid/hid-wacom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/hid-wacom.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,6 +142,7 @@ static int wacom_raw_event(struct hid_de
 		wdata->butstate = rw;
 		input_report_key(input, BTN_0, rw & 0x02);
 		input_report_key(input, BTN_1, rw & 0x01);
+		input_report_key(input, BTN_TOOL_FINGER, 0xf0);
 		input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
 		input_sync(input);
 	}
@@ -196,6 +197,9 @@ static int wacom_probe(struct hid_device
 	/* Pad */
 	input->evbit[0] |= BIT(EV_MSC);
 	input->mscbit[0] |= BIT(MSC_SERIAL);
+	set_bit(BTN_0, input->keybit);
+	set_bit(BTN_1, input->keybit);
+	set_bit(BTN_TOOL_FINGER, input->keybit);
 
 	/* Distance, rubber and mouse */
 	input->absbit[0] |= BIT(ABS_DISTANCE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-core.c linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-core.c
--- linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,8 +41,6 @@
  * Version Information
  */
 
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
 #define DRIVER_DESC "USB HID core driver"
 #define DRIVER_LICENSE "GPL"
 
@@ -998,7 +996,8 @@ static int usbhid_start(struct hid_devic
 	usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
 	usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-	usbhid_init_reports(hid);
+	if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+		usbhid_init_reports(hid);
 
 	set_bit(HID_STARTED, &usbhid->iofl);
 
@@ -1254,10 +1253,9 @@ static int hid_suspend(struct usb_interf
 {
 	struct hid_device *hid = usb_get_intfdata(intf);
 	struct usbhid_device *usbhid = hid->driver_data;
-	struct usb_device *udev = interface_to_usbdev(intf);
 	int status;
 
-	if (udev->auto_pm) {
+	if (message.event & PM_EVENT_AUTO) {
 		spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
 		if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
 		    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
@@ -1282,7 +1280,7 @@ static int hid_suspend(struct usb_interf
 			return -EIO;
 	}
 
-	if (!ignoreled && udev->auto_pm) {
+	if (!ignoreled && (message.event & PM_EVENT_AUTO)) {
 		spin_lock_irq(&usbhid->lock);
 		if (test_bit(HID_LED_ON, &usbhid->iofl)) {
 			spin_unlock_irq(&usbhid->lock);
@@ -1295,7 +1293,8 @@ static int hid_suspend(struct usb_interf
 	hid_cancel_delayed_stuff(usbhid);
 	hid_cease_io(usbhid);
 
-	if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+	if ((message.event & PM_EVENT_AUTO) &&
+			test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
 		/* lost race against keypresses */
 		status = hid_start_in(hid);
 		if (status < 0)
@@ -1395,8 +1394,7 @@ static int __init hid_init(void)
 	retval = usb_register(&hid_driver);
 	if (retval)
 		goto usb_register_fail;
-	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-			DRIVER_DESC "\n");
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
 
 	return 0;
 usb_register_fail:
@@ -1423,6 +1421,8 @@ static void __exit hid_exit(void)
 module_init(hid_init);
 module_exit(hid_exit);
 
-MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR("Andreas Gal");
+MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Jiri Kosina");
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE(DRIVER_LICENSE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hiddev.c linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hiddev.c
--- linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hiddev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hiddev.c	2010-02-24 13:52:17.000000000 -0500
@@ -450,7 +450,6 @@ static noinline int hiddev_ioctl_usage(s
 	uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
 	if (!uref_multi)
 		return -ENOMEM;
-	lock_kernel();
 	uref = &uref_multi->uref;
 	if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
 		if (copy_from_user(uref_multi, user_arg,
@@ -528,7 +527,6 @@ static noinline int hiddev_ioctl_usage(s
 
 		case HIDIOCGCOLLECTIONINDEX:
 			i = field->usage[uref->usage_index].collection_index;
-			unlock_kernel();
 			kfree(uref_multi);
 			return i;
 		case HIDIOCGUSAGES:
@@ -547,15 +545,12 @@ static noinline int hiddev_ioctl_usage(s
 		}
 
 goodreturn:
-		unlock_kernel();
 		kfree(uref_multi);
 		return 0;
 fault:
-		unlock_kernel();
 		kfree(uref_multi);
 		return -EFAULT;
 inval:
-		unlock_kernel();
 		kfree(uref_multi);
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-pidff.c linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-pidff.c
--- linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-pidff.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-pidff.c	2010-02-24 13:52:17.000000000 -0500
@@ -1181,12 +1181,11 @@ static void pidff_reset(struct pidff_dev
 	usbhid_wait_io(hid);
 
 	if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
-		int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
-		while (sim_effects < 2) {
+		while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
 			if (i++ > 20) {
 				printk(KERN_WARNING "hid-pidff: device reports "
 				       "%d simultaneous effects\n",
-				       sim_effects);
+				       pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
 				break;
 			}
 			debug("pid_pool requested again");
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-quirks.c linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-quirks.c
--- linux-libre-2.6.32-gnu1/drivers/hid/usbhid/hid-quirks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/usbhid/hid-quirks.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
+	{ USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
 	{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
 
@@ -53,6 +54,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
@@ -280,7 +282,7 @@ u32 usbhid_lookup_quirk(const u16 idVend
 	if (idVendor == USB_VENDOR_ID_NCR &&
 			idProduct >= USB_DEVICE_ID_NCR_FIRST &&
 			idProduct <= USB_DEVICE_ID_NCR_LAST)
-			return HID_QUIRK_NOGET;
+			return HID_QUIRK_NO_INIT_REPORTS;
 
 	down_read(&dquirks_rwsem);
 	bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hid/usbhid/usbkbd.c linux-libre-2.6.33-gnu1/drivers/hid/usbhid/usbkbd.c
--- linux-libre-2.6.32-gnu1/drivers/hid/usbhid/usbkbd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hid/usbhid/usbkbd.c	2010-02-24 13:52:17.000000000 -0500
@@ -266,7 +266,7 @@ static int usb_kbd_probe(struct usb_inte
 			 le16_to_cpu(dev->descriptor.idProduct));
 
 	usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
-	strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
+	strlcat(kbd->phys, "/input0", sizeof(kbd->phys));
 
 	input_dev->name = kbd->name;
 	input_dev->phys = kbd->phys;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm1021.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm1021.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm1021.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm1021.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,9 +34,8 @@
 static const unsigned short normal_i2c[] = {
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
-			mc1066);
+enum chips {
+	adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066 };
 
 /* adm1021 constants specified below */
 
@@ -97,7 +96,7 @@ struct adm1021_data {
 
 static int adm1021_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm1021_detect(struct i2c_client *client, int kind,
+static int adm1021_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static void adm1021_init_client(struct i2c_client *client);
 static int adm1021_remove(struct i2c_client *client);
@@ -130,7 +129,7 @@ static struct i2c_driver adm1021_driver
 	.remove		= adm1021_remove,
 	.id_table	= adm1021_id,
 	.detect		= adm1021_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static ssize_t show_temp(struct device *dev,
@@ -284,13 +283,12 @@ static const struct attribute_group adm1
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm1021_detect(struct i2c_client *client, int kind,
+static int adm1021_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i;
-	const char *type_name = "";
-	int conv_rate, status, config;
+	const char *type_name;
+	int conv_rate, status, config, man_id, dev_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		pr_debug("adm1021: detect failed, "
@@ -303,62 +301,37 @@ static int adm1021_detect(struct i2c_cli
 					     ADM1021_REG_CONV_RATE_R);
 	config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R);
 
-	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00
-		    || (conv_rate & 0xF8) != 0x00) {
-			pr_debug("adm1021: detect failed, "
-				 "chip not detected!\n");
-			return -ENODEV;
-		}
+	/* Check unused bits */
+	if ((status & 0x03) || (config & 0x3F) || (conv_rate & 0xF8)) {
+		pr_debug("adm1021: detect failed, chip not detected!\n");
+		return -ENODEV;
 	}
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
-		if (i == 0x41)
-			if ((i2c_smbus_read_byte_data(client,
-					ADM1021_REG_DEV_ID) & 0xF0) == 0x30)
-				kind = adm1023;
-			else
-				kind = adm1021;
-		else if (i == 0x49)
-			kind = thmc10;
-		else if (i == 0x23)
-			kind = gl523sm;
-		else if ((i == 0x4d) &&
-			 (i2c_smbus_read_byte_data(client,
-						   ADM1021_REG_DEV_ID) == 0x01))
-			kind = max1617a;
-		else if (i == 0x54)
-			kind = mc1066;
-		/* LM84 Mfr ID in a different place, and it has more unused bits */
-		else if (conv_rate == 0x00
-			 && (kind == 0 /* skip extra detection */
-			     || ((config & 0x7F) == 0x00
-				 && (status & 0xAB) == 0x00)))
-			kind = lm84;
-		else
-			kind = max1617;
-	}
+	man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
+	dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
 
-	if (kind == max1617) {
-		type_name = "max1617";
-	} else if (kind == max1617a) {
+	if (man_id == 0x4d && dev_id == 0x01)
 		type_name = "max1617a";
-	} else if (kind == adm1021) {
-		type_name = "adm1021";
-	} else if (kind == adm1023) {
-		type_name = "adm1023";
-	} else if (kind == thmc10) {
+	else if (man_id == 0x41) {
+		if ((dev_id & 0xF0) == 0x30)
+			type_name = "adm1023";
+		else
+			type_name = "adm1021";
+	} else if (man_id == 0x49)
 		type_name = "thmc10";
-	} else if (kind == lm84) {
-		type_name = "lm84";
-	} else if (kind == gl523sm) {
+	else if (man_id == 0x23)
 		type_name = "gl523sm";
-	} else if (kind == mc1066) {
+	else if (man_id == 0x54)
 		type_name = "mc1066";
-	}
+	/* LM84 Mfr ID in a different place, and it has more unused bits */
+	else if (conv_rate == 0x00
+		 && (config & 0x7F) == 0x00
+		 && (status & 0xAB) == 0x00)
+		type_name = "lm84";
+	else
+		type_name = "max1617";
+
 	pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
 		 type_name, i2c_adapter_id(adapter), client->addr);
 	strlcpy(info->type, type_name, I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm1025.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm1025.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm1025.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm1025.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  * adm1025.c
  *
  * Copyright (C) 2000       Chen-Yuan Wu <gwu@esoft.com>
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6
  * voltages (including its own power source) and up to two temperatures
@@ -64,11 +64,7 @@
 
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-/*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_2(adm1025, ne1619);
+enum chips { adm1025, ne1619 };
 
 /*
  * The ADM1025 registers
@@ -111,7 +107,7 @@ static const int in_scale[6] = { 2500, 2
 
 static int adm1025_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm1025_detect(struct i2c_client *client, int kind,
+static int adm1025_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static void adm1025_init_client(struct i2c_client *client);
 static int adm1025_remove(struct i2c_client *client);
@@ -137,7 +133,7 @@ static struct i2c_driver adm1025_driver
 	.remove		= adm1025_remove,
 	.id_table	= adm1025_id,
 	.detect		= adm1025_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -409,71 +405,38 @@ static const struct attribute_group adm1
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm1025_detect(struct i2c_client *client, int kind,
+static int adm1025_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	const char *name = "";
-	u8 config;
+	const char *name;
+	u8 man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
-	if (kind < 0) { /* detection */
-		if ((config & 0x80) != 0x00
-		 || (i2c_smbus_read_byte_data(client,
-		     ADM1025_REG_STATUS1) & 0xC0) != 0x00
-		 || (i2c_smbus_read_byte_data(client,
-		     ADM1025_REG_STATUS2) & 0xBC) != 0x00) {
-			dev_dbg(&adapter->dev,
-				"ADM1025 detection failed at 0x%02x.\n",
-				client->addr);
-			return -ENODEV;
-		}
+	/* Check for unused bits */
+	if ((i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG) & 0x80)
+	 || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS1) & 0xC0)
+	 || (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS2) & 0xBC)) {
+		dev_dbg(&adapter->dev, "ADM1025 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-
-		man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID);
-
-		if (man_id == 0x41) { /* Analog Devices */
-			if ((chip_id & 0xF0) == 0x20) { /* ADM1025/ADM1025A */
-				kind = adm1025;
-			}
-		} else
-		if (man_id == 0xA1) { /* Philips */
-			if (client->addr != 0x2E
-			 && (chip_id & 0xF0) == 0x20) { /* NE1619 */
-				kind = ne1619;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
-	}
+	/* Identification */
+	chip_id = i2c_smbus_read_byte_data(client, ADM1025_REG_CHIP_ID);
+	if ((chip_id & 0xF0) != 0x20)
+		return -ENODEV;
 
-	if (kind == adm1025) {
+	man_id = i2c_smbus_read_byte_data(client, ADM1025_REG_MAN_ID);
+	if (man_id == 0x41)
 		name = "adm1025";
-	} else if (kind == ne1619) {
+	else if (man_id == 0xA1 && client->addr != 0x2E)
 		name = "ne1619";
-	}
+	else
+		return -ENODEV;
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm1026.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm1026.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm1026.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm1026.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,9 +37,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(adm1026);
-
 static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
 				-1, -1, -1, -1, -1, -1, -1, -1 };
 static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -293,7 +290,7 @@ struct adm1026_data {
 
 static int adm1026_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm1026_detect(struct i2c_client *client, int kind,
+static int adm1026_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int adm1026_remove(struct i2c_client *client);
 static int adm1026_read_value(struct i2c_client *client, u8 reg);
@@ -305,7 +302,7 @@ static void adm1026_init_client(struct i
 
 
 static const struct i2c_device_id adm1026_id[] = {
-	{ "adm1026", adm1026 },
+	{ "adm1026", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adm1026_id);
@@ -319,7 +316,7 @@ static struct i2c_driver adm1026_driver
 	.remove		= adm1026_remove,
 	.id_table	= adm1026_id,
 	.detect		= adm1026_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int adm1026_read_value(struct i2c_client *client, u8 reg)
@@ -1650,7 +1647,7 @@ static const struct attribute_group adm1
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm1026_detect(struct i2c_client *client, int kind,
+static int adm1026_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -1672,35 +1669,26 @@ static int adm1026_detect(struct i2c_cli
 		i2c_adapter_id(client->adapter), client->addr,
 		company, verstep);
 
-	/* If auto-detecting, Determine the chip type. */
-	if (kind <= 0) {
-		dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x "
-			"...\n", i2c_adapter_id(adapter), address);
-		if (company == ADM1026_COMPANY_ANALOG_DEV
-		    && verstep == ADM1026_VERSTEP_ADM1026) {
-			kind = adm1026;
-		} else if (company == ADM1026_COMPANY_ANALOG_DEV
-			&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "Unrecognized stepping "
-				"0x%02x. Defaulting to ADM1026.\n", verstep);
-			kind = adm1026;
-		} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "Found version/stepping "
-				"0x%02x. Assuming generic ADM1026.\n",
-				verstep);
-			kind = any_chip;
-		} else {
-			dev_dbg(&adapter->dev, "Autodetection failed\n");
-			/* Not an ADM1026 ... */
-			if (kind == 0) { /* User used force=x,y */
-				dev_err(&adapter->dev, "Generic ADM1026 not "
-					"found at %d,0x%02x.  Try "
-					"force_adm1026.\n",
-					i2c_adapter_id(adapter), address);
-			}
-			return -ENODEV;
-		}
+	/* Determine the chip type. */
+	dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x...\n",
+		i2c_adapter_id(adapter), address);
+	if (company == ADM1026_COMPANY_ANALOG_DEV
+	    && verstep == ADM1026_VERSTEP_ADM1026) {
+		/* Analog Devices ADM1026 */
+	} else if (company == ADM1026_COMPANY_ANALOG_DEV
+		&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+		dev_err(&adapter->dev, "Unrecognized stepping "
+			"0x%02x. Defaulting to ADM1026.\n", verstep);
+	} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+		dev_err(&adapter->dev, "Found version/stepping "
+			"0x%02x. Assuming generic ADM1026.\n",
+			verstep);
+	} else {
+		dev_dbg(&adapter->dev, "Autodetection failed\n");
+		/* Not an ADM1026... */
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, "adm1026", I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm1029.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm1029.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm1029.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm1029.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,12 +44,6 @@ static const unsigned short normal_i2c[]
 };
 
 /*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_1(adm1029);
-
-/*
  * The ADM1029 registers
  * Manufacturer ID is 0x41 for Analog Devices
  */
@@ -117,7 +111,7 @@ static const u8 ADM1029_REG_FAN_DIV[] =
 
 static int adm1029_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm1029_detect(struct i2c_client *client, int kind,
+static int adm1029_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int adm1029_remove(struct i2c_client *client);
 static struct adm1029_data *adm1029_update_device(struct device *dev);
@@ -128,7 +122,7 @@ static int adm1029_init_client(struct i2
  */
 
 static const struct i2c_device_id adm1029_id[] = {
-	{ "adm1029", adm1029 },
+	{ "adm1029", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adm1029_id);
@@ -142,7 +136,7 @@ static struct i2c_driver adm1029_driver
 	.remove		= adm1029_remove,
 	.id_table	= adm1029_id,
 	.detect		= adm1029_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -297,63 +291,40 @@ static const struct attribute_group adm1
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm1029_detect(struct i2c_client *client, int kind,
+static int adm1029_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Now we do the detection and identification. A negative kind
-	 * means that the driver was loaded with no force parameter
-	 * (default), so we must both detect and identify the chip
-	 * (actually there is only one possible kind of chip for now, adm1029).
-	 * A zero kind means that the driver was loaded with the force
-	 * parameter, the detection step shall be skipped. A positive kind
-	 * means that the driver was loaded with the force parameter and a
-	 * given kind of chip is requested, so both the detection and the
-	 * identification steps are skipped. */
-
-	/* Default to an adm1029 if forced */
-	if (kind == 0)
-		kind = adm1029;
-
 	/* ADM1029 doesn't have CHIP ID, check just MAN ID
 	 * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
 	 * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
 	 * documented
 	 */
 
-	if (kind <= 0) {	/* identification */
-		u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
-
-		man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
-		temp_devices_installed = i2c_smbus_read_byte_data(client,
+	man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
+	temp_devices_installed = i2c_smbus_read_byte_data(client,
 					ADM1029_REG_TEMP_DEVICES_INSTALLED);
-		nb_fan_support = i2c_smbus_read_byte_data(client,
+	nb_fan_support = i2c_smbus_read_byte_data(client,
 						ADM1029_REG_NB_FAN_SUPPORT);
-		/* 0x41 is Analog Devices */
-		if (man_id == 0x41 && (temp_devices_installed & 0xf9) == 0x01
-		    && nb_fan_support == 0x03) {
-			if ((chip_id & 0xF0) == 0x00) {
-				kind = adm1029;
-			} else {
-				/* There are no "official" CHIP ID, so actually
-				 * we use Major/Minor revision for that */
-				printk(KERN_INFO
-				       "adm1029: Unknown major revision %x, "
-				       "please let us know\n", chip_id);
-			}
-		}
+	/* 0x41 is Analog Devices */
+	if (man_id != 0x41 || (temp_devices_installed & 0xf9) != 0x01
+	    || nb_fan_support != 0x03)
+		return -ENODEV;
 
-		if (kind <= 0) {	/* identification failed */
-			pr_debug("adm1029: Unsupported chip (man_id=0x%02X, "
-				 "chip_id=0x%02X)\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if ((chip_id & 0xF0) != 0x00) {
+		/* There are no "official" CHIP ID, so actually
+		 * we use Major/Minor revision for that */
+		pr_info("adm1029: Unknown major revision %x, "
+			"please let us know\n", chip_id);
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, "adm1029", I2C_NAME_SIZE);
 
 	return 0;
@@ -432,7 +403,7 @@ static int adm1029_remove(struct i2c_cli
 }
 
 /*
-function that update the status of the chips (temperature for exemple)
+function that update the status of the chips (temperature for example)
 */
 static struct adm1029_data *adm1029_update_device(struct device *dev)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm1031.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm1031.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm1031.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm1031.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,8 +64,7 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(adm1030, adm1031);
+enum chips { adm1030, adm1031 };
 
 typedef u8 auto_chan_table_t[8][2];
 
@@ -102,7 +101,7 @@ struct adm1031_data {
 
 static int adm1031_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm1031_detect(struct i2c_client *client, int kind,
+static int adm1031_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static void adm1031_init_client(struct i2c_client *client);
 static int adm1031_remove(struct i2c_client *client);
@@ -125,7 +124,7 @@ static struct i2c_driver adm1031_driver
 	.remove		= adm1031_remove,
 	.id_table	= adm1031_id,
 	.detect		= adm1031_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
@@ -813,35 +812,23 @@ static const struct attribute_group adm1
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm1031_detect(struct i2c_client *client, int kind,
+static int adm1031_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	const char *name = "";
+	const char *name;
+	int id, co;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind < 0) {
-		int id, co;
-		id = i2c_smbus_read_byte_data(client, 0x3d);
-		co = i2c_smbus_read_byte_data(client, 0x3e);
-
-		if (!((id == 0x31 || id == 0x30) && co == 0x41))
-			return -ENODEV;
-		kind = (id == 0x30) ? adm1030 : adm1031;
-	}
+	id = i2c_smbus_read_byte_data(client, 0x3d);
+	co = i2c_smbus_read_byte_data(client, 0x3e);
 
-	if (kind <= 0)
-		kind = adm1031;
+	if (!((id == 0x31 || id == 0x30) && co == 0x41))
+		return -ENODEV;
+	name = (id == 0x30) ? "adm1030" : "adm1031";
 
-	/* Given the detected chip type, set the chip name and the
-	 * auto fan control helper table. */
-	if (kind == adm1030) {
-		name = "adm1030";
-	} else if (kind == adm1031) {
-		name = "adm1031";
-	}
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adm9240.c linux-libre-2.6.33-gnu1/drivers/hwmon/adm9240.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adm9240.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adm9240.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,8 +55,7 @@
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
 					I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81);
+enum chips { adm9240, ds1780, lm81 };
 
 /* ADM9240 registers */
 #define ADM9240_REG_MAN_ID		0x3e
@@ -132,7 +131,7 @@ static inline unsigned int AOUT_FROM_REG
 
 static int adm9240_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adm9240_detect(struct i2c_client *client, int kind,
+static int adm9240_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static void adm9240_init_client(struct i2c_client *client);
 static int adm9240_remove(struct i2c_client *client);
@@ -156,7 +155,7 @@ static struct i2c_driver adm9240_driver
 	.remove		= adm9240_remove,
 	.id_table	= adm9240_id,
 	.detect		= adm9240_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* per client data */
@@ -545,7 +544,7 @@ static const struct attribute_group adm9
 /*** sensor chip detect and driver install ***/
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adm9240_detect(struct i2c_client *new_client, int kind,
+static int adm9240_detect(struct i2c_client *new_client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
@@ -556,51 +555,34 @@ static int adm9240_detect(struct i2c_cli
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind == 0) {
-		kind = adm9240;
-	}
-
-	if (kind < 0) {
-
-		/* verify chip: reg address should match i2c address */
-		if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
-				!= address) {
-			dev_err(&adapter->dev, "detect fail: address match, "
-					"0x%02x\n", address);
-			return -ENODEV;
-		}
-
-		/* check known chip manufacturer */
-		man_id = i2c_smbus_read_byte_data(new_client,
-				ADM9240_REG_MAN_ID);
-		if (man_id == 0x23) {
-			kind = adm9240;
-		} else if (man_id == 0xda) {
-			kind = ds1780;
-		} else if (man_id == 0x01) {
-			kind = lm81;
-		} else {
-			dev_err(&adapter->dev, "detect fail: unknown manuf, "
-					"0x%02x\n", man_id);
-			return -ENODEV;
-		}
-
-		/* successful detect, print chip info */
-		die_rev = i2c_smbus_read_byte_data(new_client,
-				ADM9240_REG_DIE_REV);
-		dev_info(&adapter->dev, "found %s revision %u\n",
-				man_id == 0x23 ? "ADM9240" :
-				man_id == 0xda ? "DS1780" : "LM81", die_rev);
+	/* verify chip: reg address should match i2c address */
+	if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
+			!= address) {
+		dev_err(&adapter->dev, "detect fail: address match, 0x%02x\n",
+			address);
+		return -ENODEV;
 	}
 
-	/* either forced or detected chip kind */
-	if (kind == adm9240) {
+	/* check known chip manufacturer */
+	man_id = i2c_smbus_read_byte_data(new_client, ADM9240_REG_MAN_ID);
+	if (man_id == 0x23) {
 		name = "adm9240";
-	} else if (kind == ds1780) {
+	} else if (man_id == 0xda) {
 		name = "ds1780";
-	} else if (kind == lm81) {
+	} else if (man_id == 0x01) {
 		name = "lm81";
+	} else {
+		dev_err(&adapter->dev, "detect fail: unknown manuf, 0x%02x\n",
+			man_id);
+		return -ENODEV;
 	}
+
+	/* successful detect, print chip info */
+	die_rev = i2c_smbus_read_byte_data(new_client, ADM9240_REG_DIE_REV);
+	dev_info(&adapter->dev, "found %s revision %u\n",
+		 man_id == 0x23 ? "ADM9240" :
+		 man_id == 0xda ? "DS1780" : "LM81", die_rev);
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/ads7828.c linux-libre-2.6.33-gnu1/drivers/hwmon/ads7828.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/ads7828.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/ads7828.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,10 +47,7 @@
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 	I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ads7828);
-
-/* Other module parameters */
+/* Module parameters */
 static int se_input = 1; /* Default is SE, 0 == diff */
 static int int_vref = 1; /* Default is internal ref ON */
 static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */
@@ -72,7 +69,7 @@ struct ads7828_data {
 };
 
 /* Function declaration - necessary due to function dependencies */
-static int ads7828_detect(struct i2c_client *client, int kind,
+static int ads7828_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int ads7828_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
@@ -168,7 +165,7 @@ static int ads7828_remove(struct i2c_cli
 }
 
 static const struct i2c_device_id ads7828_id[] = {
-	{ "ads7828", ads7828 },
+	{ "ads7828", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ads7828_id);
@@ -183,14 +180,15 @@ static struct i2c_driver ads7828_driver
 	.remove = ads7828_remove,
 	.id_table = ads7828_id,
 	.detect = ads7828_detect,
-	.address_data = &addr_data,
+	.address_list = normal_i2c,
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int ads7828_detect(struct i2c_client *client, int kind,
+static int ads7828_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int ch;
 
 	/* Check we have a valid client */
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
@@ -202,20 +200,17 @@ static int ads7828_detect(struct i2c_cli
 	- Read from the 8 channel addresses
 	- Check the top 4 bits of each result are not set (12 data bits)
 	*/
-	if (kind < 0) {
-		int ch;
-		for (ch = 0; ch < ADS7828_NCH; ch++) {
-			u16 in_data;
-			u8 cmd = channel_cmd_byte(ch);
-			in_data = ads7828_read_value(client, cmd);
-			if (in_data & 0xF000) {
-				printk(KERN_DEBUG
-				"%s : Doesn't look like an ads7828 device\n",
-				__func__);
-				return -ENODEV;
-			}
+	for (ch = 0; ch < ADS7828_NCH; ch++) {
+		u16 in_data;
+		u8 cmd = channel_cmd_byte(ch);
+		in_data = ads7828_read_value(client, cmd);
+		if (in_data & 0xF000) {
+			pr_debug("%s : Doesn't look like an ads7828 device\n",
+				 __func__);
+			return -ENODEV;
 		}
 	}
+
 	strlcpy(info->type, "ads7828", I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adt7462.c linux-libre-2.6.33-gnu1/drivers/hwmon/adt7462.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adt7462.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adt7462.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,9 +32,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(adt7462);
-
 /* ADT7462 registers */
 #define ADT7462_REG_DEVICE			0x3D
 #define ADT7462_REG_VENDOR			0x3E
@@ -97,7 +94,7 @@ I2C_CLIENT_INSMOD_1(adt7462);
 #define		ADT7462_PIN24_SHIFT		6
 #define		ADT7462_PIN26_VOLT_INPUT	0x08
 #define		ADT7462_PIN25_VOLT_INPUT	0x20
-#define		ADT7462_PIN28_SHIFT		6	/* cfg3 */
+#define		ADT7462_PIN28_SHIFT		4	/* cfg3 */
 #define		ADT7462_PIN28_VOLT		0x5
 
 #define ADT7462_REG_ALARM1			0xB8
@@ -182,7 +179,7 @@ I2C_CLIENT_INSMOD_1(adt7462);
  *
  * Some, but not all, of these voltages have low/high limits.
  */
-#define ADT7462_VOLT_COUNT	12
+#define ADT7462_VOLT_COUNT	13
 
 #define ADT7462_VENDOR		0x41
 #define ADT7462_DEVICE		0x62
@@ -237,12 +234,12 @@ struct adt7462_data {
 
 static int adt7462_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adt7462_detect(struct i2c_client *client, int kind,
+static int adt7462_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int adt7462_remove(struct i2c_client *client);
 
 static const struct i2c_device_id adt7462_id[] = {
-	{ "adt7462", adt7462 },
+	{ "adt7462", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adt7462_id);
@@ -256,7 +253,7 @@ static struct i2c_driver adt7462_driver
 	.remove		= adt7462_remove,
 	.id_table	= adt7462_id,
 	.detect		= adt7462_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -1902,31 +1899,26 @@ static struct attribute *adt7462_attr[]
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adt7462_detect(struct i2c_client *client, int kind,
+static int adt7462_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
-
-		vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR);
-		if (vendor != ADT7462_VENDOR)
-			return -ENODEV;
+	vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR);
+	if (vendor != ADT7462_VENDOR)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE);
-		if (device != ADT7462_DEVICE)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE);
+	if (device != ADT7462_DEVICE)
+		return -ENODEV;
 
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7462_REG_REVISION);
-		if (revision != ADT7462_REVISION)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION);
+	if (revision != ADT7462_REVISION)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7462", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adt7470.c linux-libre-2.6.33-gnu1/drivers/hwmon/adt7470.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adt7470.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adt7470.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,9 +33,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(adt7470);
-
 /* ADT7470 registers */
 #define ADT7470_REG_BASE_ADDR			0x20
 #define ADT7470_REG_TEMP_BASE_ADDR		0x20
@@ -177,12 +174,12 @@ struct adt7470_data {
 
 static int adt7470_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adt7470_detect(struct i2c_client *client, int kind,
+static int adt7470_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int adt7470_remove(struct i2c_client *client);
 
 static const struct i2c_device_id adt7470_id[] = {
-	{ "adt7470", adt7470 },
+	{ "adt7470", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adt7470_id);
@@ -196,7 +193,7 @@ static struct i2c_driver adt7470_driver
 	.remove		= adt7470_remove,
 	.id_table	= adt7470_id,
 	.detect		= adt7470_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -1225,31 +1222,26 @@ static struct attribute *adt7470_attr[]
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adt7470_detect(struct i2c_client *client, int kind,
+static int adt7470_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
-
-		vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR);
-		if (vendor != ADT7470_VENDOR)
-			return -ENODEV;
+	vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR);
+	if (vendor != ADT7470_VENDOR)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE);
-		if (device != ADT7470_DEVICE)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE);
+	if (device != ADT7470_DEVICE)
+		return -ENODEV;
 
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7470_REG_REVISION);
-		if (revision != ADT7470_REVISION)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7470_REG_REVISION);
+	if (revision != ADT7470_REVISION)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7470", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adt7473.c linux-libre-2.6.33-gnu1/drivers/hwmon/adt7473.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adt7473.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adt7473.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,9 +32,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(adt7473);
-
 /* ADT7473 registers */
 #define ADT7473_REG_BASE_ADDR			0x20
 
@@ -166,15 +163,14 @@ struct adt7473_data {
 
 static int adt7473_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int adt7473_detect(struct i2c_client *client, int kind,
+static int adt7473_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int adt7473_remove(struct i2c_client *client);
 
 static const struct i2c_device_id adt7473_id[] = {
-	{ "adt7473", adt7473 },
+	{ "adt7473", 0 },
 	{ }
 };
-MODULE_DEVICE_TABLE(i2c, adt7473_id);
 
 static struct i2c_driver adt7473_driver = {
 	.class		= I2C_CLASS_HWMON,
@@ -185,7 +181,7 @@ static struct i2c_driver adt7473_driver
 	.remove		= adt7473_remove,
 	.id_table	= adt7473_id,
 	.detect		= adt7473_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -1086,31 +1082,26 @@ static struct attribute *adt7473_attr[]
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int adt7473_detect(struct i2c_client *client, int kind,
+static int adt7473_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
-
-		vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
-		if (vendor != ADT7473_VENDOR)
-			return -ENODEV;
+	vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
+	if (vendor != ADT7473_VENDOR)
+		return -ENODEV;
 
-		device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
-		if (device != ADT7473_DEVICE)
-			return -ENODEV;
+	device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
+	if (device != ADT7473_DEVICE)
+		return -ENODEV;
 
-		revision = i2c_smbus_read_byte_data(client,
-						    ADT7473_REG_REVISION);
-		if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
-			return -ENODEV;
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION);
+	if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
+		return -ENODEV;
 
 	strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
 
@@ -1171,6 +1162,8 @@ static int adt7473_remove(struct i2c_cli
 
 static int __init adt7473_init(void)
 {
+	pr_notice("The adt7473 driver is deprecated, please use the adt7475 "
+		  "driver instead\n");
 	return i2c_add_driver(&adt7473_driver);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/adt7475.c linux-libre-2.6.33-gnu1/drivers/hwmon/adt7475.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/adt7475.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/adt7475.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,8 @@
  * Copyright (C) 2007-2008, Advanced Micro Devices, Inc.
  * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
  * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com>
-
+ * Copyright (C) 2009 Jean Delvare <khali@linux-fr.org>
+ *
  * Derived from the lm83 driver by Jean Delvare
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
 #include <linux/err.h>
 
 /* Indexes for the sysfs hooks */
@@ -39,7 +41,12 @@
 
 /* 7475 Common Registers */
 
-#define REG_VOLTAGE_BASE	0x21
+#define REG_DEVREV2		0x12	/* ADT7490 only */
+
+#define REG_VTT			0x1E	/* ADT7490 only */
+#define REG_EXTEND3		0x1F	/* ADT7490 only */
+
+#define REG_VOLTAGE_BASE	0x20
 #define REG_TEMP_BASE		0x25
 #define REG_TACH_BASE		0x28
 #define REG_PWM_BASE		0x30
@@ -47,12 +54,15 @@
 
 #define REG_DEVID		0x3D
 #define REG_VENDID		0x3E
+#define REG_DEVID2		0x3F
 
 #define REG_STATUS1		0x41
 #define REG_STATUS2		0x42
 
-#define REG_VOLTAGE_MIN_BASE	0x46
-#define REG_VOLTAGE_MAX_BASE	0x47
+#define REG_VID			0x43	/* ADT7476 only */
+
+#define REG_VOLTAGE_MIN_BASE	0x44
+#define REG_VOLTAGE_MAX_BASE	0x45
 
 #define REG_TEMP_MIN_BASE	0x4E
 #define REG_TEMP_MAX_BASE	0x4F
@@ -73,16 +83,39 @@
 
 #define REG_TEMP_OFFSET_BASE	0x70
 
+#define REG_CONFIG2		0x73
+
 #define REG_EXTEND1		0x76
 #define REG_EXTEND2		0x77
+
+#define REG_CONFIG3		0x78
 #define REG_CONFIG5		0x7C
+#define REG_CONFIG4		0x7D
+
+#define REG_STATUS4		0x81	/* ADT7490 only */
+
+#define REG_VTT_MIN		0x84	/* ADT7490 only */
+#define REG_VTT_MAX		0x86	/* ADT7490 only */
+
+#define VID_VIDSEL		0x80	/* ADT7476 only */
+
+#define CONFIG2_ATTN		0x20
+
+#define CONFIG3_SMBALERT	0x01
+#define CONFIG3_THERM		0x02
+
+#define CONFIG4_PINFUNC		0x03
+#define CONFIG4_MAXDUTY		0x08
+#define CONFIG4_ATTN_IN10	0x30
+#define CONFIG4_ATTN_IN43	0xC0
 
 #define CONFIG5_TWOSCOMP	0x01
 #define CONFIG5_TEMPOFFSET	0x02
+#define CONFIG5_VIDGPIO		0x10	/* ADT7476 only */
 
 /* ADT7475 Settings */
 
-#define ADT7475_VOLTAGE_COUNT	2
+#define ADT7475_VOLTAGE_COUNT	5	/* Not counting Vtt */
 #define ADT7475_TEMP_COUNT	3
 #define ADT7475_TACH_COUNT	4
 #define ADT7475_PWM_COUNT	3
@@ -113,12 +146,15 @@
 #define TEMP_OFFSET_REG(idx) (REG_TEMP_OFFSET_BASE + (idx))
 #define TEMP_TRANGE_REG(idx) (REG_TEMP_TRANGE_BASE + (idx))
 
-static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-I2C_CLIENT_INSMOD_1(adt7475);
+enum chips { adt7473, adt7475, adt7476, adt7490 };
 
 static const struct i2c_device_id adt7475_id[] = {
+	{ "adt7473", adt7473 },
 	{ "adt7475", adt7475 },
+	{ "adt7476", adt7476 },
+	{ "adt7490", adt7490 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adt7475_id);
@@ -131,15 +167,24 @@ struct adt7475_data {
 	unsigned long limits_updated;
 	char valid;
 
+	u8 config4;
 	u8 config5;
-	u16 alarms;
-	u16 voltage[3][3];
+	u8 has_voltage;
+	u8 bypass_attn;		/* Bypass voltage attenuator */
+	u8 has_pwm2:1;
+	u8 has_fan4:1;
+	u8 has_vid:1;
+	u32 alarms;
+	u16 voltage[3][6];
 	u16 temp[7][3];
 	u16 tach[2][4];
 	u8 pwm[4][3];
 	u8 range[3];
 	u8 pwmctl[3];
 	u8 pwmchan[3];
+
+	u8 vid;
+	u8 vrm;
 };
 
 static struct i2c_driver adt7475_driver;
@@ -196,26 +241,35 @@ static inline u16 rpm2tach(unsigned long
 	return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF);
 }
 
-static inline int reg2vcc(u16 reg)
-{
-	return (4296 * reg) / 1000;
-}
+/* Scaling factors for voltage inputs, taken from the ADT7490 datasheet */
+static const int adt7473_in_scaling[ADT7475_VOLTAGE_COUNT + 1][2] = {
+	{ 45, 94 },	/* +2.5V */
+	{ 175, 525 },	/* Vccp */
+	{ 68, 71 },	/* Vcc */
+	{ 93, 47 },	/* +5V */
+	{ 120, 20 },	/* +12V */
+	{ 45, 45 },	/* Vtt */
+};
 
-static inline int reg2vccp(u16 reg)
+static inline int reg2volt(int channel, u16 reg, u8 bypass_attn)
 {
-	return (2929 * reg) / 1000;
-}
+	const int *r = adt7473_in_scaling[channel];
 
-static inline u16 vcc2reg(long vcc)
-{
-	vcc = SENSORS_LIMIT(vcc, 0, 4396);
-	return (vcc * 1000) / 4296;
+	if (bypass_attn & (1 << channel))
+		return DIV_ROUND_CLOSEST(reg * 2250, 1024);
+	return DIV_ROUND_CLOSEST(reg * (r[0] + r[1]) * 2250, r[1] * 1024);
 }
 
-static inline u16 vccp2reg(long vcc)
+static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
 {
-	vcc = SENSORS_LIMIT(vcc, 0, 2998);
-	return (vcc * 1000) / 2929;
+	const int *r = adt7473_in_scaling[channel];
+	long reg;
+
+	if (bypass_attn & (1 << channel))
+		reg = (volt * 1024) / 2250;
+	else
+		reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250);
+	return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2);
 }
 
 static u16 adt7475_read_word(struct i2c_client *client, int reg)
@@ -271,12 +325,11 @@ static ssize_t show_voltage(struct devic
 	switch (sattr->nr) {
 	case ALARM:
 		return sprintf(buf, "%d\n",
-			       (data->alarms >> (sattr->index + 1)) & 1);
+			       (data->alarms >> sattr->index) & 1);
 	default:
 		val = data->voltage[sattr->nr][sattr->index];
 		return sprintf(buf, "%d\n",
-			       sattr->index ==
-			       0 ? reg2vccp(val) : reg2vcc(val));
+			       reg2volt(sattr->index, val, data->bypass_attn));
 	}
 }
 
@@ -296,12 +349,19 @@ static ssize_t set_voltage(struct device
 	mutex_lock(&data->lock);
 
 	data->voltage[sattr->nr][sattr->index] =
-		sattr->index ? vcc2reg(val) : vccp2reg(val);
+				volt2reg(sattr->index, val, data->bypass_attn);
 
-	if (sattr->nr == MIN)
-		reg = VOLTAGE_MIN_REG(sattr->index);
-	else
-		reg = VOLTAGE_MAX_REG(sattr->index);
+	if (sattr->index < ADT7475_VOLTAGE_COUNT) {
+		if (sattr->nr == MIN)
+			reg = VOLTAGE_MIN_REG(sattr->index);
+		else
+			reg = VOLTAGE_MAX_REG(sattr->index);
+	} else {
+		if (sattr->nr == MIN)
+			reg = REG_VTT_MIN;
+		else
+			reg = REG_VTT_MAX;
+	}
 
 	i2c_smbus_write_byte_data(client, reg,
 				  data->voltage[sattr->nr][sattr->index] >> 2);
@@ -778,18 +838,103 @@ static ssize_t set_pwmfreq(struct device
 	return count;
 }
 
-static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 0);
-static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
+static ssize_t show_pwm_at_crit(struct device *dev,
+				struct device_attribute *devattr, char *buf)
+{
+	struct adt7475_data *data = adt7475_update_device(dev);
+	return sprintf(buf, "%d\n", !!(data->config4 & CONFIG4_MAXDUTY));
+}
+
+static ssize_t set_pwm_at_crit(struct device *dev,
+			       struct device_attribute *devattr,
+			       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	long val;
+
+	if (strict_strtol(buf, 10, &val))
+		return -EINVAL;
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+	data->config4 = i2c_smbus_read_byte_data(client, REG_CONFIG4);
+	if (val)
+		data->config4 |= CONFIG4_MAXDUTY;
+	else
+		data->config4 &= ~CONFIG4_MAXDUTY;
+	i2c_smbus_write_byte_data(client, REG_CONFIG4, data->config4);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct adt7475_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", (int)data->vrm);
+}
+
+static ssize_t set_vrm(struct device *dev, struct device_attribute *devattr,
+		       const char *buf, size_t count)
+{
+	struct adt7475_data *data = dev_get_drvdata(dev);
+	long val;
+
+	if (strict_strtol(buf, 10, &val))
+		return -EINVAL;
+	if (val < 0 || val > 255)
+		return -EINVAL;
+	data->vrm = val;
+
+	return count;
+}
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct adt7475_data *data = adt7475_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_voltage, NULL, INPUT, 0);
+static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MAX, 0);
-static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MIN, 0);
-static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0);
-static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
-static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0);
+static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 1);
+static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MAX, 1);
-static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
+static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage,
 			    set_voltage, MIN, 1);
-static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1);
+static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1);
+static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 2);
+static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 2);
+static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 2);
+static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 2);
+static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_voltage, NULL, INPUT, 3);
+static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 3);
+static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 3);
+static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, show_voltage, NULL, ALARM, 3);
+static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_voltage, NULL, INPUT, 4);
+static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 4);
+static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 4);
+static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, show_voltage, NULL, ALARM, 8);
+static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_voltage, NULL, INPUT, 5);
+static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MAX, 5);
+static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_voltage,
+			    set_voltage, MIN, 5);
+static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, show_voltage, NULL, ALARM, 31);
 static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0);
 static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0);
 static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0);
@@ -893,6 +1038,13 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_po
 static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MAX, 2);
 
+/* Non-standard name, might need revisiting */
+static DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
+		   show_pwm_at_crit, set_pwm_at_crit);
+
+static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, set_vrm);
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
 static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_max.dev_attr.attr,
@@ -940,60 +1092,156 @@ static struct attribute *adt7475_attrs[]
 	&sensor_dev_attr_fan3_input.dev_attr.attr,
 	&sensor_dev_attr_fan3_min.dev_attr.attr,
 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
-	&sensor_dev_attr_fan4_input.dev_attr.attr,
-	&sensor_dev_attr_fan4_min.dev_attr.attr,
-	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2.dev_attr.attr,
-	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
-	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
-	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+	&dev_attr_pwm_use_point2_pwm_at_crit.attr,
 	NULL,
 };
 
-struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
+static struct attribute *fan4_attrs[] = {
+	&sensor_dev_attr_fan4_input.dev_attr.attr,
+	&sensor_dev_attr_fan4_min.dev_attr.attr,
+	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
+	NULL
+};
 
-static int adt7475_detect(struct i2c_client *client, int kind,
+static struct attribute *pwm2_attrs[] = {
+	&sensor_dev_attr_pwm2.dev_attr.attr,
+	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
+	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in0_attrs[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_max.dev_attr.attr,
+	&sensor_dev_attr_in0_min.dev_attr.attr,
+	&sensor_dev_attr_in0_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in3_attrs[] = {
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in3_max.dev_attr.attr,
+	&sensor_dev_attr_in3_min.dev_attr.attr,
+	&sensor_dev_attr_in3_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in4_attrs[] = {
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_max.dev_attr.attr,
+	&sensor_dev_attr_in4_min.dev_attr.attr,
+	&sensor_dev_attr_in4_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *in5_attrs[] = {
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_max.dev_attr.attr,
+	&sensor_dev_attr_in5_min.dev_attr.attr,
+	&sensor_dev_attr_in5_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *vid_attrs[] = {
+	&dev_attr_cpu0_vid.attr,
+	&dev_attr_vrm.attr,
+	NULL
+};
+
+static struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs };
+static struct attribute_group fan4_attr_group = { .attrs = fan4_attrs };
+static struct attribute_group pwm2_attr_group = { .attrs = pwm2_attrs };
+static struct attribute_group in0_attr_group = { .attrs = in0_attrs };
+static struct attribute_group in3_attr_group = { .attrs = in3_attrs };
+static struct attribute_group in4_attr_group = { .attrs = in4_attrs };
+static struct attribute_group in5_attr_group = { .attrs = in5_attrs };
+static struct attribute_group vid_attr_group = { .attrs = vid_attrs };
+
+static int adt7475_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendid, devid, devid2;
+	const char *name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		if (adt7475_read(REG_VENDID) != 0x41 ||
-		    adt7475_read(REG_DEVID) != 0x75) {
-			dev_err(&adapter->dev,
-				"Couldn't detect a adt7475 part at 0x%02x\n",
-				(unsigned int)client->addr);
-			return -ENODEV;
-		}
+	vendid = adt7475_read(REG_VENDID);
+	devid2 = adt7475_read(REG_DEVID2);
+	if (vendid != 0x41 ||		/* Analog Devices */
+	    (devid2 & 0xf8) != 0x68)
+		return -ENODEV;
+
+	devid = adt7475_read(REG_DEVID);
+	if (devid == 0x73)
+		name = "adt7473";
+	else if (devid == 0x75 && client->addr == 0x2e)
+		name = "adt7475";
+	else if (devid == 0x76)
+		name = "adt7476";
+	else if ((devid2 & 0xfc) == 0x6c)
+		name = "adt7490";
+	else {
+		dev_dbg(&adapter->dev,
+			"Couldn't detect an ADT7473/75/76/90 part at "
+			"0x%02x\n", (unsigned int)client->addr);
+		return -ENODEV;
 	}
 
-	strlcpy(info->type, adt7475_id[0].name, I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
 }
 
+static void adt7475_remove_files(struct i2c_client *client,
+				 struct adt7475_data *data)
+{
+	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	if (data->has_fan4)
+		sysfs_remove_group(&client->dev.kobj, &fan4_attr_group);
+	if (data->has_pwm2)
+		sysfs_remove_group(&client->dev.kobj, &pwm2_attr_group);
+	if (data->has_voltage & (1 << 0))
+		sysfs_remove_group(&client->dev.kobj, &in0_attr_group);
+	if (data->has_voltage & (1 << 3))
+		sysfs_remove_group(&client->dev.kobj, &in3_attr_group);
+	if (data->has_voltage & (1 << 4))
+		sysfs_remove_group(&client->dev.kobj, &in4_attr_group);
+	if (data->has_voltage & (1 << 5))
+		sysfs_remove_group(&client->dev.kobj, &in5_attr_group);
+	if (data->has_vid)
+		sysfs_remove_group(&client->dev.kobj, &vid_attr_group);
+}
+
 static int adt7475_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
+	static const char *names[] = {
+		[adt7473] = "ADT7473",
+		[adt7475] = "ADT7475",
+		[adt7476] = "ADT7476",
+		[adt7490] = "ADT7490",
+	};
+
 	struct adt7475_data *data;
-	int i, ret = 0;
+	int i, ret = 0, revision;
+	u8 config2, config3;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
@@ -1002,6 +1250,70 @@ static int adt7475_probe(struct i2c_clie
 	mutex_init(&data->lock);
 	i2c_set_clientdata(client, data);
 
+	/* Initialize device-specific values */
+	switch (id->driver_data) {
+	case adt7476:
+		data->has_voltage = 0x0e;	/* in1 to in3 */
+		revision = adt7475_read(REG_DEVID2) & 0x07;
+		break;
+	case adt7490:
+		data->has_voltage = 0x3e;	/* in1 to in5 */
+		revision = adt7475_read(REG_DEVID2) & 0x03;
+		if (revision == 0x03)
+			revision += adt7475_read(REG_DEVREV2);
+		break;
+	default:
+		data->has_voltage = 0x06;	/* in1, in2 */
+		revision = adt7475_read(REG_DEVID2) & 0x07;
+	}
+
+	config3 = adt7475_read(REG_CONFIG3);
+	/* Pin PWM2 may alternatively be used for ALERT output */
+	if (!(config3 & CONFIG3_SMBALERT))
+		data->has_pwm2 = 1;
+	/* Meaning of this bit is inverted for the ADT7473-1 */
+	if (id->driver_data == adt7473 && revision >= 1)
+		data->has_pwm2 = !data->has_pwm2;
+
+	data->config4 = adt7475_read(REG_CONFIG4);
+	/* Pin TACH4 may alternatively be used for THERM */
+	if ((data->config4 & CONFIG4_PINFUNC) == 0x0)
+		data->has_fan4 = 1;
+
+	/* THERM configuration is more complex on the ADT7476 and ADT7490,
+	   because 2 different pins (TACH4 and +2.5 Vin) can be used for
+	   this function */
+	if (id->driver_data == adt7490) {
+		if ((data->config4 & CONFIG4_PINFUNC) == 0x1 &&
+		    !(config3 & CONFIG3_THERM))
+			data->has_fan4 = 1;
+	}
+	if (id->driver_data == adt7476 || id->driver_data == adt7490) {
+		if (!(config3 & CONFIG3_THERM) ||
+		    (data->config4 & CONFIG4_PINFUNC) == 0x1)
+			data->has_voltage |= (1 << 0);		/* in0 */
+	}
+
+	/* On the ADT7476, the +12V input pin may instead be used as VID5,
+	   and VID pins may alternatively be used as GPIO */
+	if (id->driver_data == adt7476) {
+		u8 vid = adt7475_read(REG_VID);
+		if (!(vid & VID_VIDSEL))
+			data->has_voltage |= (1 << 4);		/* in4 */
+
+		data->has_vid = !(adt7475_read(REG_CONFIG5) & CONFIG5_VIDGPIO);
+	}
+
+	/* Voltage attenuators can be bypassed, globally or individually */
+	config2 = adt7475_read(REG_CONFIG2);
+	if (config2 & CONFIG2_ATTN) {
+		data->bypass_attn = (0x3 << 3) | 0x3;
+	} else {
+		data->bypass_attn = ((data->config4 & CONFIG4_ATTN_IN10) >> 4) |
+				    ((data->config4 & CONFIG4_ATTN_IN43) >> 3);
+	}
+	data->bypass_attn &= data->has_voltage;
+
 	/* Call adt7475_read_pwm for all pwm's as this will reprogram any
 	   pwm's which are disabled to manual mode with 0% duty cycle */
 	for (i = 0; i < ADT7475_PWM_COUNT; i++)
@@ -1011,16 +1323,70 @@ static int adt7475_probe(struct i2c_clie
 	if (ret)
 		goto efree;
 
+	/* Features that can be disabled individually */
+	if (data->has_fan4) {
+		ret = sysfs_create_group(&client->dev.kobj, &fan4_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_pwm2) {
+		ret = sysfs_create_group(&client->dev.kobj, &pwm2_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 0)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in0_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 3)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in3_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 4)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in4_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_voltage & (1 << 5)) {
+		ret = sysfs_create_group(&client->dev.kobj, &in5_attr_group);
+		if (ret)
+			goto eremove;
+	}
+	if (data->has_vid) {
+		data->vrm = vid_which_vrm();
+		ret = sysfs_create_group(&client->dev.kobj, &vid_attr_group);
+		if (ret)
+			goto eremove;
+	}
+
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		ret = PTR_ERR(data->hwmon_dev);
 		goto eremove;
 	}
 
+	dev_info(&client->dev, "%s device, revision %d\n",
+		 names[id->driver_data], revision);
+	if ((data->has_voltage & 0x11) || data->has_fan4 || data->has_pwm2)
+		dev_info(&client->dev, "Optional features:%s%s%s%s%s\n",
+			 (data->has_voltage & (1 << 0)) ? " in0" : "",
+			 (data->has_voltage & (1 << 4)) ? " in4" : "",
+			 data->has_fan4 ? " fan4" : "",
+			 data->has_pwm2 ? " pwm2" : "",
+			 data->has_vid ? " vid" : "");
+	if (data->bypass_attn)
+		dev_info(&client->dev, "Bypassing attenuators on:%s%s%s%s\n",
+			 (data->bypass_attn & (1 << 0)) ? " in0" : "",
+			 (data->bypass_attn & (1 << 1)) ? " in1" : "",
+			 (data->bypass_attn & (1 << 3)) ? " in3" : "",
+			 (data->bypass_attn & (1 << 4)) ? " in4" : "");
+
 	return 0;
 
 eremove:
-	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	adt7475_remove_files(client, data);
 efree:
 	kfree(data);
 	return ret;
@@ -1031,7 +1397,7 @@ static int adt7475_remove(struct i2c_cli
 	struct adt7475_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
+	adt7475_remove_files(client, data);
 	kfree(data);
 
 	return 0;
@@ -1046,7 +1412,7 @@ static struct i2c_driver adt7475_driver
 	.remove		= adt7475_remove,
 	.id_table	= adt7475_id,
 	.detect		= adt7475_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static void adt7475_read_hystersis(struct i2c_client *client)
@@ -1116,7 +1482,7 @@ static struct adt7475_data *adt7475_upda
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adt7475_data *data = i2c_get_clientdata(client);
-	u8 ext;
+	u16 ext;
 	int i;
 
 	mutex_lock(&data->lock);
@@ -1127,25 +1493,44 @@ static struct adt7475_data *adt7475_upda
 		data->alarms = adt7475_read(REG_STATUS2) << 8;
 		data->alarms |= adt7475_read(REG_STATUS1);
 
-		ext = adt7475_read(REG_EXTEND1);
-		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++)
+		ext = (adt7475_read(REG_EXTEND2) << 8) |
+			adt7475_read(REG_EXTEND1);
+		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
+			if (!(data->has_voltage & (1 << i)))
+				continue;
 			data->voltage[INPUT][i] =
 				(adt7475_read(VOLTAGE_REG(i)) << 2) |
-				((ext >> ((i + 1) * 2)) & 3);
+				((ext >> (i * 2)) & 3);
+		}
 
-		ext = adt7475_read(REG_EXTEND2);
 		for (i = 0; i < ADT7475_TEMP_COUNT; i++)
 			data->temp[INPUT][i] =
 				(adt7475_read(TEMP_REG(i)) << 2) |
-				((ext >> ((i + 1) * 2)) & 3);
+				((ext >> ((i + 5) * 2)) & 3);
 
-		for (i = 0; i < ADT7475_TACH_COUNT; i++)
+		if (data->has_voltage & (1 << 5)) {
+			data->alarms |= adt7475_read(REG_STATUS4) << 24;
+			ext = adt7475_read(REG_EXTEND3);
+			data->voltage[INPUT][5] = adt7475_read(REG_VTT) << 2 |
+				((ext >> 4) & 3);
+		}
+
+		for (i = 0; i < ADT7475_TACH_COUNT; i++) {
+			if (i == 3 && !data->has_fan4)
+				continue;
 			data->tach[INPUT][i] =
 				adt7475_read_word(client, TACH_REG(i));
+		}
 
 		/* Updated by hw when in auto mode */
-		for (i = 0; i < ADT7475_PWM_COUNT; i++)
+		for (i = 0; i < ADT7475_PWM_COUNT; i++) {
+			if (i == 1 && !data->has_pwm2)
+				continue;
 			data->pwm[INPUT][i] = adt7475_read(PWM_REG(i));
+		}
+
+		if (data->has_vid)
+			data->vid = adt7475_read(REG_VID) & 0x3f;
 
 		data->measure_updated = jiffies;
 	}
@@ -1153,9 +1538,12 @@ static struct adt7475_data *adt7475_upda
 	/* Limits and settings, should never change update every 60 seconds */
 	if (time_after(jiffies, data->limits_updated + HZ * 60) ||
 	    !data->valid) {
+		data->config4 = adt7475_read(REG_CONFIG4);
 		data->config5 = adt7475_read(REG_CONFIG5);
 
 		for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) {
+			if (!(data->has_voltage & (1 << i)))
+				continue;
 			/* Adjust values so they match the input precision */
 			data->voltage[MIN][i] =
 				adt7475_read(VOLTAGE_MIN_REG(i)) << 2;
@@ -1163,6 +1551,11 @@ static struct adt7475_data *adt7475_upda
 				adt7475_read(VOLTAGE_MAX_REG(i)) << 2;
 		}
 
+		if (data->has_voltage & (1 << 5)) {
+			data->voltage[MIN][5] = adt7475_read(REG_VTT_MIN) << 2;
+			data->voltage[MAX][5] = adt7475_read(REG_VTT_MAX) << 2;
+		}
+
 		for (i = 0; i < ADT7475_TEMP_COUNT; i++) {
 			/* Adjust values so they match the input precision */
 			data->temp[MIN][i] =
@@ -1178,11 +1571,16 @@ static struct adt7475_data *adt7475_upda
 		}
 		adt7475_read_hystersis(client);
 
-		for (i = 0; i < ADT7475_TACH_COUNT; i++)
+		for (i = 0; i < ADT7475_TACH_COUNT; i++) {
+			if (i == 3 && !data->has_fan4)
+				continue;
 			data->tach[MIN][i] =
 				adt7475_read_word(client, TACH_MIN_REG(i));
+		}
 
 		for (i = 0; i < ADT7475_PWM_COUNT; i++) {
+			if (i == 1 && !data->has_pwm2)
+				continue;
 			data->pwm[MAX][i] = adt7475_read(PWM_MAX_REG(i));
 			data->pwm[MIN][i] = adt7475_read(PWM_MIN_REG(i));
 			/* Set the channel and control information */
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/amc6821.c linux-libre-2.6.33-gnu1/drivers/hwmon/amc6821.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/amc6821.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/amc6821.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1115 @@
+/*
+	amc6821.c - Part of lm_sensors, Linux kernel modules for hardware
+	monitoring
+	Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>
+
+	Based on max6650.c:
+	Copyright (C) 2007 Hans J. Koch <hjk@linutronix.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <linux/kernel.h>	/* Needed for KERN_INFO */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.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>
+
+
+/*
+ * Addresses to scan.
+ */
+
+static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
+	0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
+
+
+
+/*
+ * Insmod parameters
+ */
+
+static int pwminv = 0;	/*Inverted PWM output. */
+module_param(pwminv, int, S_IRUGO);
+
+static int init = 1; /*Power-on initialization.*/
+module_param(init, int, S_IRUGO);
+
+
+enum chips { amc6821 };
+
+#define AMC6821_REG_DEV_ID 0x3D
+#define AMC6821_REG_COMP_ID 0x3E
+#define AMC6821_REG_CONF1 0x00
+#define AMC6821_REG_CONF2 0x01
+#define AMC6821_REG_CONF3 0x3F
+#define AMC6821_REG_CONF4 0x04
+#define AMC6821_REG_STAT1 0x02
+#define AMC6821_REG_STAT2 0x03
+#define AMC6821_REG_TDATA_LOW 0x08
+#define AMC6821_REG_TDATA_HI 0x09
+#define AMC6821_REG_LTEMP_HI 0x0A
+#define AMC6821_REG_RTEMP_HI 0x0B
+#define AMC6821_REG_LTEMP_LIMIT_MIN 0x15
+#define AMC6821_REG_LTEMP_LIMIT_MAX 0x14
+#define AMC6821_REG_RTEMP_LIMIT_MIN 0x19
+#define AMC6821_REG_RTEMP_LIMIT_MAX 0x18
+#define AMC6821_REG_LTEMP_CRIT 0x1B
+#define AMC6821_REG_RTEMP_CRIT 0x1D
+#define AMC6821_REG_PSV_TEMP 0x1C
+#define AMC6821_REG_DCY 0x22
+#define AMC6821_REG_LTEMP_FAN_CTRL 0x24
+#define AMC6821_REG_RTEMP_FAN_CTRL 0x25
+#define AMC6821_REG_DCY_LOW_TEMP 0x21
+
+#define AMC6821_REG_TACH_LLIMITL 0x10
+#define AMC6821_REG_TACH_LLIMITH 0x11
+#define AMC6821_REG_TACH_HLIMITL 0x12
+#define AMC6821_REG_TACH_HLIMITH 0x13
+
+#define AMC6821_CONF1_START 0x01
+#define AMC6821_CONF1_FAN_INT_EN 0x02
+#define AMC6821_CONF1_FANIE 0x04
+#define AMC6821_CONF1_PWMINV 0x08
+#define AMC6821_CONF1_FAN_FAULT_EN 0x10
+#define AMC6821_CONF1_FDRC0 0x20
+#define AMC6821_CONF1_FDRC1 0x40
+#define AMC6821_CONF1_THERMOVIE 0x80
+
+#define AMC6821_CONF2_PWM_EN 0x01
+#define AMC6821_CONF2_TACH_MODE 0x02
+#define AMC6821_CONF2_TACH_EN 0x04
+#define AMC6821_CONF2_RTFIE 0x08
+#define AMC6821_CONF2_LTOIE 0x10
+#define AMC6821_CONF2_RTOIE 0x20
+#define AMC6821_CONF2_PSVIE 0x40
+#define AMC6821_CONF2_RST 0x80
+
+#define AMC6821_CONF3_THERM_FAN_EN 0x80
+#define AMC6821_CONF3_REV_MASK 0x0F
+
+#define AMC6821_CONF4_OVREN 0x10
+#define AMC6821_CONF4_TACH_FAST 0x20
+#define AMC6821_CONF4_PSPR 0x40
+#define AMC6821_CONF4_MODE 0x80
+
+#define AMC6821_STAT1_RPM_ALARM 0x01
+#define AMC6821_STAT1_FANS 0x02
+#define AMC6821_STAT1_RTH 0x04
+#define AMC6821_STAT1_RTL 0x08
+#define AMC6821_STAT1_R_THERM 0x10
+#define AMC6821_STAT1_RTF 0x20
+#define AMC6821_STAT1_LTH 0x40
+#define AMC6821_STAT1_LTL 0x80
+
+#define AMC6821_STAT2_RTC 0x08
+#define AMC6821_STAT2_LTC 0x10
+#define AMC6821_STAT2_LPSV 0x20
+#define AMC6821_STAT2_L_THERM 0x40
+#define AMC6821_STAT2_THERM_IN 0x80
+
+enum {IDX_TEMP1_INPUT = 0, IDX_TEMP1_MIN, IDX_TEMP1_MAX,
+	IDX_TEMP1_CRIT, IDX_TEMP2_INPUT, IDX_TEMP2_MIN,
+	IDX_TEMP2_MAX, IDX_TEMP2_CRIT,
+	TEMP_IDX_LEN, };
+
+static const u8 temp_reg[] = {AMC6821_REG_LTEMP_HI,
+			AMC6821_REG_LTEMP_LIMIT_MIN,
+			AMC6821_REG_LTEMP_LIMIT_MAX,
+			AMC6821_REG_LTEMP_CRIT,
+			AMC6821_REG_RTEMP_HI,
+			AMC6821_REG_RTEMP_LIMIT_MIN,
+			AMC6821_REG_RTEMP_LIMIT_MAX,
+			AMC6821_REG_RTEMP_CRIT, };
+
+enum {IDX_FAN1_INPUT = 0, IDX_FAN1_MIN, IDX_FAN1_MAX,
+	FAN1_IDX_LEN, };
+
+static const u8 fan_reg_low[] = {AMC6821_REG_TDATA_LOW,
+			AMC6821_REG_TACH_LLIMITL,
+			AMC6821_REG_TACH_HLIMITL, };
+
+
+static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
+			AMC6821_REG_TACH_LLIMITH,
+			AMC6821_REG_TACH_HLIMITH, };
+
+static int amc6821_probe(
+		struct i2c_client *client,
+		const struct i2c_device_id *id);
+static int amc6821_detect(
+		struct i2c_client *client,
+		struct i2c_board_info *info);
+static int amc6821_init_client(struct i2c_client *client);
+static int amc6821_remove(struct i2c_client *client);
+static struct amc6821_data *amc6821_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static const struct i2c_device_id amc6821_id[] = {
+	{ "amc6821", amc6821 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, amc6821_id);
+
+static struct i2c_driver amc6821_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "amc6821",
+	},
+	.probe = amc6821_probe,
+	.remove = amc6821_remove,
+	.id_table = amc6821_id,
+	.detect = amc6821_detect,
+	.address_list = normal_i2c,
+};
+
+
+/*
+ * Client data (each client gets its own)
+  */
+
+struct amc6821_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* register values */
+	int temp[TEMP_IDX_LEN];
+
+	u16 fan[FAN1_IDX_LEN];
+	u8 fan1_div;
+
+	u8 pwm1;
+	u8 temp1_auto_point_temp[3];
+	u8 temp2_auto_point_temp[3];
+	u8 pwm1_auto_point_pwm[3];
+	u8 pwm1_enable;
+	u8 pwm1_auto_channels_temp;
+
+	u8 stat1;
+	u8 stat2;
+};
+
+
+static ssize_t get_temp(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	int ix = to_sensor_dev_attr(devattr)->index;
+
+	return sprintf(buf, "%d\n", data->temp[ix] * 1000);
+}
+
+
+
+static ssize_t set_temp(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	int ix = to_sensor_dev_attr(attr)->index;
+	long val;
+
+	int ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+	val = SENSORS_LIMIT(val / 1000, -128, 127);
+
+	mutex_lock(&data->update_lock);
+	data->temp[ix] = val;
+	if (i2c_smbus_write_byte_data(client, temp_reg[ix], data->temp[ix])) {
+		dev_err(&client->dev, "Register write error, aborting.\n");
+		count = -EIO;
+	}
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+
+
+
+static ssize_t get_temp_alarm(
+	struct device *dev,
+	struct device_attribute *devattr,
+	char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	int ix = to_sensor_dev_attr(devattr)->index;
+	u8 flag;
+
+	switch (ix) {
+	case IDX_TEMP1_MIN:
+		flag = data->stat1 & AMC6821_STAT1_LTL;
+		break;
+	case IDX_TEMP1_MAX:
+		flag = data->stat1 & AMC6821_STAT1_LTH;
+		break;
+	case IDX_TEMP1_CRIT:
+		flag = data->stat2 & AMC6821_STAT2_LTC;
+		break;
+	case IDX_TEMP2_MIN:
+		flag = data->stat1 & AMC6821_STAT1_RTL;
+		break;
+	case IDX_TEMP2_MAX:
+		flag = data->stat1 & AMC6821_STAT1_RTH;
+		break;
+	case IDX_TEMP2_CRIT:
+		flag = data->stat2 & AMC6821_STAT2_RTC;
+		break;
+	default:
+		dev_dbg(dev, "Unknown attr->index (%d).\n", ix);
+		return -EINVAL;
+	}
+	if (flag)
+		return sprintf(buf, "1");
+	else
+		return sprintf(buf, "0");
+}
+
+
+
+
+static ssize_t get_temp2_fault(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	if (data->stat1 & AMC6821_STAT1_RTF)
+		return sprintf(buf, "1");
+	else
+		return sprintf(buf, "0");
+}
+
+static ssize_t get_pwm1(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	return sprintf(buf, "%d\n", data->pwm1);
+}
+
+static ssize_t set_pwm1(
+		struct device *dev,
+		struct device_attribute *devattr,
+		const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	long val;
+	int ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&data->update_lock);
+	data->pwm1 = SENSORS_LIMIT(val , 0, 255);
+	i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t get_pwm1_enable(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	return sprintf(buf, "%d\n", data->pwm1_enable);
+}
+
+static ssize_t set_pwm1_enable(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	long val;
+	int config = strict_strtol(buf, 10, &val);
+	if (config)
+		return config;
+
+	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
+	if (config < 0) {
+			dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+			return -EIO;
+	}
+
+	switch (val) {
+	case 1:
+		config &= ~AMC6821_CONF1_FDRC0;
+		config &= ~AMC6821_CONF1_FDRC1;
+		break;
+	case 2:
+		config &= ~AMC6821_CONF1_FDRC0;
+		config |= AMC6821_CONF1_FDRC1;
+		break;
+	case 3:
+		config |= AMC6821_CONF1_FDRC0;
+		config |= AMC6821_CONF1_FDRC1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	mutex_lock(&data->update_lock);
+	if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
+			dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+			count = -EIO;
+	}
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+
+static ssize_t get_pwm1_auto_channels_temp(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
+}
+
+
+static ssize_t get_temp_auto_point_temp(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	int ix = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+	struct amc6821_data *data = amc6821_update_device(dev);
+	switch (nr) {
+	case 1:
+		return sprintf(buf, "%d\n",
+			data->temp1_auto_point_temp[ix] * 1000);
+		break;
+	case 2:
+		return sprintf(buf, "%d\n",
+			data->temp2_auto_point_temp[ix] * 1000);
+		break;
+	default:
+		dev_dbg(dev, "Unknown attr->nr (%d).\n", nr);
+		return -EINVAL;
+	}
+}
+
+
+static ssize_t get_pwm1_auto_point_pwm(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	int ix = to_sensor_dev_attr(devattr)->index;
+	struct amc6821_data *data = amc6821_update_device(dev);
+	return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
+}
+
+
+static inline ssize_t set_slope_register(struct i2c_client *client,
+		u8 reg,
+		u8 dpwm,
+		u8 *ptemp)
+{
+	int dt;
+	u8 tmp;
+
+	dt = ptemp[2]-ptemp[1];
+	for (tmp = 4; tmp > 0; tmp--) {
+		if (dt * (0x20 >> tmp) >= dpwm)
+			break;
+	}
+	tmp |= (ptemp[1] & 0x7C) << 1;
+	if (i2c_smbus_write_byte_data(client,
+			reg, tmp)) {
+		dev_err(&client->dev, "Register write error, aborting.\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+
+
+static ssize_t set_temp_auto_point_temp(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = amc6821_update_device(dev);
+	int ix = to_sensor_dev_attr_2(attr)->index;
+	int nr = to_sensor_dev_attr_2(attr)->nr;
+	u8 *ptemp;
+	u8 reg;
+	int dpwm;
+	long val;
+	int ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	switch (nr) {
+	case 1:
+		ptemp = data->temp1_auto_point_temp;
+		reg = AMC6821_REG_LTEMP_FAN_CTRL;
+		break;
+	case 2:
+		ptemp = data->temp2_auto_point_temp;
+		reg = AMC6821_REG_RTEMP_FAN_CTRL;
+		break;
+	default:
+		dev_dbg(dev, "Unknown attr->nr (%d).\n", nr);
+		return -EINVAL;
+	}
+
+	data->valid = 0;
+	mutex_lock(&data->update_lock);
+	switch (ix) {
+	case 0:
+		ptemp[0] = SENSORS_LIMIT(val / 1000, 0,
+				data->temp1_auto_point_temp[1]);
+		ptemp[0] = SENSORS_LIMIT(ptemp[0], 0,
+				data->temp2_auto_point_temp[1]);
+		ptemp[0] = SENSORS_LIMIT(ptemp[0], 0, 63);
+		if (i2c_smbus_write_byte_data(
+					client,
+					AMC6821_REG_PSV_TEMP,
+					ptemp[0])) {
+				dev_err(&client->dev,
+					"Register write error, aborting.\n");
+				count = -EIO;
+		}
+		goto EXIT;
+		break;
+	case 1:
+		ptemp[1] = SENSORS_LIMIT(
+					val / 1000,
+					(ptemp[0] & 0x7C) + 4,
+					124);
+		ptemp[1] &= 0x7C;
+		ptemp[2] = SENSORS_LIMIT(
+					ptemp[2], ptemp[1] + 1,
+					255);
+		break;
+	case 2:
+		ptemp[2] = SENSORS_LIMIT(
+					val / 1000,
+					ptemp[1]+1,
+					255);
+		break;
+	default:
+		dev_dbg(dev, "Unknown attr->index (%d).\n", ix);
+		count = -EINVAL;
+		goto EXIT;
+	}
+	dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1];
+	if (set_slope_register(client, reg, dpwm, ptemp))
+		count = -EIO;
+
+EXIT:
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+
+
+static ssize_t set_pwm1_auto_point_pwm(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	int dpwm;
+	long val;
+	int ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&data->update_lock);
+	data->pwm1_auto_point_pwm[1] = SENSORS_LIMIT(val, 0, 254);
+	if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP,
+			data->pwm1_auto_point_pwm[1])) {
+		dev_err(&client->dev, "Register write error, aborting.\n");
+		count = -EIO;
+		goto EXIT;
+	}
+	dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1];
+	if (set_slope_register(client, AMC6821_REG_LTEMP_FAN_CTRL, dpwm,
+			data->temp1_auto_point_temp)) {
+		count = -EIO;
+		goto EXIT;
+	}
+	if (set_slope_register(client, AMC6821_REG_RTEMP_FAN_CTRL, dpwm,
+			data->temp2_auto_point_temp)) {
+		count = -EIO;
+		goto EXIT;
+	}
+
+EXIT:
+	data->valid = 0;
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t get_fan(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	int ix = to_sensor_dev_attr(devattr)->index;
+	if (0 == data->fan[ix])
+		return sprintf(buf, "0");
+	return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
+}
+
+
+
+static ssize_t get_fan1_fault(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	if (data->stat1 & AMC6821_STAT1_FANS)
+		return sprintf(buf, "1");
+	else
+		return sprintf(buf, "0");
+}
+
+
+
+static ssize_t set_fan(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	long val;
+	int ix = to_sensor_dev_attr(attr)->index;
+	int ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+	val = 1 > val ? 0xFFFF : 6000000/val;
+
+	mutex_lock(&data->update_lock);
+	data->fan[ix] = (u16) SENSORS_LIMIT(val, 1, 0xFFFF);
+	if (i2c_smbus_write_byte_data(client, fan_reg_low[ix],
+			data->fan[ix] & 0xFF)) {
+		dev_err(&client->dev, "Register write error, aborting.\n");
+		count = -EIO;
+		goto EXIT;
+	}
+	if (i2c_smbus_write_byte_data(client,
+			fan_reg_hi[ix], data->fan[ix] >> 8)) {
+		dev_err(&client->dev, "Register write error, aborting.\n");
+		count = -EIO;
+	}
+EXIT:
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+
+
+static ssize_t get_fan1_div(
+		struct device *dev,
+		struct device_attribute *devattr,
+		char *buf)
+{
+	struct amc6821_data *data = amc6821_update_device(dev);
+	return sprintf(buf, "%d\n", data->fan1_div);
+}
+
+static ssize_t set_fan1_div(
+		struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	long val;
+	int config = strict_strtol(buf, 10, &val);
+	if (config)
+		return config;
+
+	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
+	if (config < 0) {
+		dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+		return -EIO;
+	}
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 2:
+		config &= ~AMC6821_CONF4_PSPR;
+		data->fan1_div = 2;
+		break;
+	case 4:
+		config |= AMC6821_CONF4_PSPR;
+		data->fan1_div = 4;
+		break;
+	default:
+		count = -EINVAL;
+		goto EXIT;
+	}
+	if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, config)) {
+		dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+		count = -EIO;
+	}
+EXIT:
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+	get_temp, NULL, IDX_TEMP1_INPUT);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP1_MIN);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP1_MAX);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP1_CRIT);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP1_MIN);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP1_MAX);
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP1_CRIT);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR,
+	get_temp, NULL, IDX_TEMP2_INPUT);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP2_MIN);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP2_MAX);
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, get_temp,
+	set_temp, IDX_TEMP2_CRIT);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO,
+	get_temp2_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP2_MIN);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP2_MAX);
+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO,
+	get_temp_alarm, NULL, IDX_TEMP2_CRIT);
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, IDX_FAN1_INPUT);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
+	get_fan, set_fan, IDX_FAN1_MIN);
+static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO | S_IWUSR,
+	get_fan, set_fan, IDX_FAN1_MAX);
+static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan1_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+	get_fan1_div, set_fan1_div, 0);
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm1, set_pwm1, 0);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+	get_pwm1_enable, set_pwm1_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO,
+	get_pwm1_auto_point_pwm, NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
+	get_pwm1_auto_point_pwm, set_pwm1_auto_point_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO,
+	get_pwm1_auto_point_pwm, NULL, 2);
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO,
+	get_pwm1_auto_channels_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_auto_point1_temp, S_IRUGO,
+	get_temp_auto_point_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
+	get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_auto_point3_temp, S_IWUSR | S_IRUGO,
+	get_temp_auto_point_temp, set_temp_auto_point_temp, 1, 2);
+
+static SENSOR_DEVICE_ATTR_2(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
+	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
+	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
+	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);
+
+
+
+static struct attribute *amc6821_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp1_crit.dev_attr.attr,
+	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_min.dev_attr.attr,
+	&sensor_dev_attr_temp2_max.dev_attr.attr,
+	&sensor_dev_attr_temp2_crit.dev_attr.attr,
+	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_fault.dev_attr.attr,
+	&sensor_dev_attr_fan1_input.dev_attr.attr,
+	&sensor_dev_attr_fan1_min.dev_attr.attr,
+	&sensor_dev_attr_fan1_max.dev_attr.attr,
+	&sensor_dev_attr_fan1_fault.dev_attr.attr,
+	&sensor_dev_attr_fan1_div.dev_attr.attr,
+	&sensor_dev_attr_pwm1.dev_attr.attr,
+	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
+	&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_temp1_auto_point3_temp.dev_attr.attr,
+	&sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
+	&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
+	&sensor_dev_attr_temp2_auto_point3_temp.dev_attr.attr,
+	NULL
+};
+
+static struct attribute_group amc6821_attr_grp = {
+	.attrs = amc6821_attrs,
+};
+
+
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int amc6821_detect(
+		struct i2c_client *client,
+		struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	int address = client->addr;
+	int dev_id, comp_id;
+
+	dev_dbg(&adapter->dev, "amc6821_detect called.\n");
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_dbg(&adapter->dev,
+			"amc6821: I2C bus doesn't support byte mode, "
+			"skipping.\n");
+		return -ENODEV;
+	}
+
+	dev_id = i2c_smbus_read_byte_data(client, AMC6821_REG_DEV_ID);
+	comp_id = i2c_smbus_read_byte_data(client, AMC6821_REG_COMP_ID);
+	if (dev_id != 0x21 || comp_id != 0x49) {
+		dev_dbg(&adapter->dev,
+			"amc6821: detection failed at 0x%02x.\n",
+			address);
+		return -ENODEV;
+	}
+
+	/* Bit 7 of the address register is ignored, so we can check the
+	   ID registers again */
+	dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID);
+	comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID);
+	if (dev_id != 0x21 || comp_id != 0x49) {
+		dev_dbg(&adapter->dev,
+			"amc6821: detection failed at 0x%02x.\n",
+			address);
+		return -ENODEV;
+	}
+
+	dev_info(&adapter->dev, "amc6821: chip found at 0x%02x.\n", address);
+	strlcpy(info->type, "amc6821", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static int amc6821_probe(
+	struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	struct amc6821_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct amc6821_data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&client->dev, "out of memory.\n");
+		return -ENOMEM;
+	}
+
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	/*
+	 * Initialize the amc6821 chip
+	 */
+	err = amc6821_init_client(client);
+	if (err)
+		goto err_free;
+
+	err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
+	if (err)
+		goto err_free;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (!IS_ERR(data->hwmon_dev))
+		return 0;
+
+	err = PTR_ERR(data->hwmon_dev);
+	dev_err(&client->dev, "error registering hwmon device.\n");
+	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
+err_free:
+	kfree(data);
+	return err;
+}
+
+static int amc6821_remove(struct i2c_client *client)
+{
+	struct amc6821_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
+
+	kfree(data);
+
+	return 0;
+}
+
+
+static int amc6821_init_client(struct i2c_client *client)
+{
+	int config;
+	int err = -EIO;
+
+	if (init) {
+		config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
+
+		if (config < 0) {
+				dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+				return err;
+		}
+
+		config |= AMC6821_CONF4_MODE;
+
+		if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4,
+				config)) {
+			dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+			return err;
+		}
+
+		config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF3);
+
+		if (config < 0) {
+			dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+			return err;
+		}
+
+		dev_info(&client->dev, "Revision %d\n", config & 0x0f);
+
+		config &= ~AMC6821_CONF3_THERM_FAN_EN;
+
+		if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF3,
+				config)) {
+			dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+			return err;
+		}
+
+		config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF2);
+
+		if (config < 0) {
+			dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+			return err;
+		}
+
+		config &= ~AMC6821_CONF2_RTFIE;
+		config &= ~AMC6821_CONF2_LTOIE;
+		config &= ~AMC6821_CONF2_RTOIE;
+		if (i2c_smbus_write_byte_data(client,
+				AMC6821_REG_CONF2, config)) {
+			dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+			return err;
+		}
+
+		config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
+
+		if (config < 0) {
+			dev_err(&client->dev,
+			"Error reading configuration register, aborting.\n");
+			return err;
+		}
+
+		config &= ~AMC6821_CONF1_THERMOVIE;
+		config &= ~AMC6821_CONF1_FANIE;
+		config |= AMC6821_CONF1_START;
+		if (pwminv)
+			config |= AMC6821_CONF1_PWMINV;
+		else
+			config &= ~AMC6821_CONF1_PWMINV;
+
+		if (i2c_smbus_write_byte_data(
+				client, AMC6821_REG_CONF1, config)) {
+			dev_err(&client->dev,
+			"Configuration register write error, aborting.\n");
+			return err;
+		}
+	}
+	return 0;
+}
+
+
+static struct amc6821_data *amc6821_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct amc6821_data *data = i2c_get_clientdata(client);
+	int timeout = HZ;
+	u8 reg;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + timeout) ||
+			!data->valid) {
+
+		for (i = 0; i < TEMP_IDX_LEN; i++)
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+				temp_reg[i]);
+
+		data->stat1 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_STAT1);
+		data->stat2 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_STAT2);
+
+		data->pwm1 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_DCY);
+		for (i = 0; i < FAN1_IDX_LEN; i++) {
+			data->fan[i] = i2c_smbus_read_byte_data(
+					client,
+					fan_reg_low[i]);
+			data->fan[i] += i2c_smbus_read_byte_data(
+					client,
+					fan_reg_hi[i]) << 8;
+		}
+		data->fan1_div = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_CONF4);
+		data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
+
+		data->pwm1_auto_point_pwm[0] = 0;
+		data->pwm1_auto_point_pwm[2] = 255;
+		data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_DCY_LOW_TEMP);
+
+		data->temp1_auto_point_temp[0] =
+			i2c_smbus_read_byte_data(client,
+					AMC6821_REG_PSV_TEMP);
+		data->temp2_auto_point_temp[0] =
+				data->temp1_auto_point_temp[0];
+		reg = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_LTEMP_FAN_CTRL);
+		data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
+		reg &= 0x07;
+		reg = 0x20 >> reg;
+		if (reg > 0)
+			data->temp1_auto_point_temp[2] =
+				data->temp1_auto_point_temp[1] +
+				(data->pwm1_auto_point_pwm[2] -
+				data->pwm1_auto_point_pwm[1]) / reg;
+		else
+			data->temp1_auto_point_temp[2] = 255;
+
+		reg = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_RTEMP_FAN_CTRL);
+		data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
+		reg &= 0x07;
+		reg = 0x20 >> reg;
+		if (reg > 0)
+			data->temp2_auto_point_temp[2] =
+				data->temp2_auto_point_temp[1] +
+				(data->pwm1_auto_point_pwm[2] -
+				data->pwm1_auto_point_pwm[1]) / reg;
+		else
+			data->temp2_auto_point_temp[2] = 255;
+
+		reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
+		reg = (reg >> 5) & 0x3;
+		switch (reg) {
+		case 0: /*open loop: software sets pwm1*/
+			data->pwm1_auto_channels_temp = 0;
+			data->pwm1_enable = 1;
+			break;
+		case 2: /*closed loop: remote T (temp2)*/
+			data->pwm1_auto_channels_temp = 2;
+			data->pwm1_enable = 2;
+			break;
+		case 3: /*closed loop: local and remote T (temp2)*/
+			data->pwm1_auto_channels_temp = 3;
+			data->pwm1_enable = 3;
+			break;
+		case 1: /*semi-open loop: software sets rpm, chip controls pwm1,
+			  *currently not implemented
+			  */
+			data->pwm1_auto_channels_temp = 0;
+			data->pwm1_enable = 0;
+			break;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+	mutex_unlock(&data->update_lock);
+	return data;
+}
+
+
+static int __init amc6821_init(void)
+{
+	return i2c_add_driver(&amc6821_driver);
+}
+
+static void __exit amc6821_exit(void)
+{
+	i2c_del_driver(&amc6821_driver);
+}
+
+module_init(amc6821_init);
+module_exit(amc6821_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>");
+MODULE_DESCRIPTION("Texas Instruments amc6821 hwmon driver");
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/applesmc.c linux-libre-2.6.33-gnu1/drivers/hwmon/applesmc.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/applesmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/applesmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -518,7 +518,7 @@ static int applesmc_pm_restore(struct de
 	return applesmc_pm_resume(dev);
 }
 
-static struct dev_pm_ops applesmc_pm_ops = {
+static const struct dev_pm_ops applesmc_pm_ops = {
 	.resume = applesmc_pm_resume,
 	.restore = applesmc_pm_restore,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/asb100.c linux-libre-2.6.33-gnu1/drivers/hwmon/asb100.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/asb100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/asb100.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,9 +51,6 @@
 /* I2C addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(asb100);
-
 static unsigned short force_subclients[4];
 module_param_array(force_subclients, short, NULL, 0);
 MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
@@ -209,14 +206,14 @@ static void asb100_write_value(struct i2
 
 static int asb100_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
-static int asb100_detect(struct i2c_client *client, int kind,
+static int asb100_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int asb100_remove(struct i2c_client *client);
 static struct asb100_data *asb100_update_device(struct device *dev);
 static void asb100_init_client(struct i2c_client *client);
 
 static const struct i2c_device_id asb100_id[] = {
-	{ "asb100", asb100 },
+	{ "asb100", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, asb100_id);
@@ -230,7 +227,7 @@ static struct i2c_driver asb100_driver =
 	.remove		= asb100_remove,
 	.id_table	= asb100_id,
 	.detect		= asb100_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* 7 Voltages */
@@ -697,10 +694,11 @@ ERROR_SC_2:
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int asb100_detect(struct i2c_client *client, int kind,
+static int asb100_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int val1, val2;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		pr_debug("asb100.o: detect failed, "
@@ -708,50 +706,30 @@ static int asb100_detect(struct i2c_clie
 		return -ENODEV;
 	}
 
-	/* The chip may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the chip will be reset to the right
-	   bank. */
-	if (kind < 0) {
-
-		int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
-		int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
-
-		/* If we're in bank 0 */
-		if ((!(val1 & 0x07)) &&
-				/* Check for ASB100 ID (low byte) */
-				(((!(val1 & 0x80)) && (val2 != 0x94)) ||
-				/* Check for ASB100 ID (high byte ) */
-				((val1 & 0x80) && (val2 != 0x06)))) {
-			pr_debug("asb100.o: detect failed, "
-					"bad chip id 0x%02x!\n", val2);
-			return -ENODEV;
-		}
+	val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
+	val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
 
-	} /* kind < 0 */
+	/* If we're in bank 0 */
+	if ((!(val1 & 0x07)) &&
+			/* Check for ASB100 ID (low byte) */
+			(((!(val1 & 0x80)) && (val2 != 0x94)) ||
+			/* Check for ASB100 ID (high byte ) */
+			((val1 & 0x80) && (val2 != 0x06)))) {
+		pr_debug("asb100: detect failed, bad chip id 0x%02x!\n", val2);
+		return -ENODEV;
+	}
 
-	/* We have either had a force parameter, or we have already detected
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	/* Put it now into bank 0 and Vendor ID High Byte */
 	i2c_smbus_write_byte_data(client, ASB100_REG_BANK,
 		(i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78)
 		| 0x80);
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
-		int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
+	val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
+	val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
 
-		if ((val1 == 0x31) && (val2 == 0x06))
-			kind = asb100;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "ignoring "
-					"'force' parameter for unknown chip "
-					"at adapter %d, address 0x%02x.\n",
-					i2c_adapter_id(adapter), client->addr);
-			return -ENODEV;
-		}
-	}
+	if (val1 != 0x31 || val2 != 0x06)
+		return -ENODEV;
 
 	strlcpy(info->type, "asb100", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/asus_atk0110.c linux-libre-2.6.33-gnu1/drivers/hwmon/asus_atk0110.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/asus_atk0110.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/asus_atk0110.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
  * See COPYING in the top level directory of the kernel tree.
  */
 
+#include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/hwmon.h>
 #include <linux/list.h>
@@ -101,6 +102,11 @@ struct atk_data {
 	int temperature_count;
 	int fan_count;
 	struct list_head sensor_list;
+
+	struct {
+		struct dentry *root;
+		u32 id;
+	} debugfs;
 };
 
 
@@ -624,6 +630,187 @@ static int atk_read_value(struct atk_sen
 	return err;
 }
 
+#ifdef CONFIG_DEBUG_FS
+static int atk_debugfs_gitm_get(void *p, u64 *val)
+{
+	struct atk_data *data = p;
+	union acpi_object *ret;
+	struct atk_acpi_ret_buffer *buf;
+	int err = 0;
+
+	if (!data->read_handle)
+		return -ENODEV;
+
+	if (!data->debugfs.id)
+		return -EINVAL;
+
+	ret = atk_gitm(data, data->debugfs.id);
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+
+	buf = (struct atk_acpi_ret_buffer *)ret->buffer.pointer;
+	if (buf->flags)
+		*val = buf->value;
+	else
+		err = -EIO;
+
+	return err;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(atk_debugfs_gitm,
+			atk_debugfs_gitm_get,
+			NULL,
+			"0x%08llx\n")
+
+static int atk_acpi_print(char *buf, size_t sz, union acpi_object *obj)
+{
+	int ret = 0;
+
+	switch (obj->type) {
+	case ACPI_TYPE_INTEGER:
+		ret = snprintf(buf, sz, "0x%08llx\n", obj->integer.value);
+		break;
+	case ACPI_TYPE_STRING:
+		ret = snprintf(buf, sz, "%s\n", obj->string.pointer);
+		break;
+	}
+
+	return ret;
+}
+
+static void atk_pack_print(char *buf, size_t sz, union acpi_object *pack)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < pack->package.count; i++) {
+		union acpi_object *obj = &pack->package.elements[i];
+
+		ret = atk_acpi_print(buf, sz, obj);
+		if (ret >= sz)
+			break;
+		buf += ret;
+		sz -= ret;
+	}
+}
+
+static int atk_debugfs_ggrp_open(struct inode *inode, struct file *file)
+{
+	struct atk_data *data = inode->i_private;
+	char *buf = NULL;
+	union acpi_object *ret;
+	u8 cls;
+	int i;
+
+	if (!data->enumerate_handle)
+		return -ENODEV;
+	if (!data->debugfs.id)
+		return -EINVAL;
+
+	cls = (data->debugfs.id & 0xff000000) >> 24;
+	ret = atk_ggrp(data, cls);
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+
+	for (i = 0; i < ret->package.count; i++) {
+		union acpi_object *pack = &ret->package.elements[i];
+		union acpi_object *id;
+
+		if (pack->type != ACPI_TYPE_PACKAGE)
+			continue;
+		if (!pack->package.count)
+			continue;
+		id = &pack->package.elements[0];
+		if (id->integer.value == data->debugfs.id) {
+			/* Print the package */
+			buf = kzalloc(512, GFP_KERNEL);
+			if (!buf) {
+				ACPI_FREE(ret);
+				return -ENOMEM;
+			}
+			atk_pack_print(buf, 512, pack);
+			break;
+		}
+	}
+	ACPI_FREE(ret);
+
+	if (!buf)
+		return -EINVAL;
+
+	file->private_data = buf;
+
+	return nonseekable_open(inode, file);
+}
+
+static ssize_t atk_debugfs_ggrp_read(struct file *file, char __user *buf,
+		size_t count, loff_t *pos)
+{
+	char *str = file->private_data;
+	size_t len = strlen(str);
+
+	return simple_read_from_buffer(buf, count, pos, str, len);
+}
+
+static int atk_debugfs_ggrp_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static const struct file_operations atk_debugfs_ggrp_fops = {
+	.read		= atk_debugfs_ggrp_read,
+	.open		= atk_debugfs_ggrp_open,
+	.release	= atk_debugfs_ggrp_release,
+};
+
+static void atk_debugfs_init(struct atk_data *data)
+{
+	struct dentry *d;
+	struct dentry *f;
+
+	data->debugfs.id = 0;
+
+	d = debugfs_create_dir("asus_atk0110", NULL);
+	if (!d || IS_ERR(d))
+		return;
+
+	f = debugfs_create_x32("id", S_IRUSR | S_IWUSR, d, &data->debugfs.id);
+	if (!f || IS_ERR(f))
+		goto cleanup;
+
+	f = debugfs_create_file("gitm", S_IRUSR, d, data,
+			&atk_debugfs_gitm);
+	if (!f || IS_ERR(f))
+		goto cleanup;
+
+	f = debugfs_create_file("ggrp", S_IRUSR, d, data,
+			&atk_debugfs_ggrp_fops);
+	if (!f || IS_ERR(f))
+		goto cleanup;
+
+	data->debugfs.root = d;
+
+	return;
+cleanup:
+	debugfs_remove_recursive(d);
+}
+
+static void atk_debugfs_cleanup(struct atk_data *data)
+{
+	debugfs_remove_recursive(data->debugfs.root);
+}
+
+#else /* CONFIG_DEBUG_FS */
+
+static void atk_debugfs_init(struct atk_data *data)
+{
+}
+
+static void atk_debugfs_cleanup(struct atk_data *data)
+{
+}
+#endif
+
 static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
 {
 	struct device *dev = &data->acpi_dev->dev;
@@ -1047,76 +1234,75 @@ remove:
 	return err;
 }
 
-static int atk_check_old_if(struct atk_data *data)
+static int atk_probe_if(struct atk_data *data)
 {
 	struct device *dev = &data->acpi_dev->dev;
 	acpi_handle ret;
 	acpi_status status;
+	int err = 0;
 
 	/* RTMP: read temperature */
 	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret);
-	if (status != AE_OK) {
+	if (ACPI_SUCCESS(status))
+		data->rtmp_handle = ret;
+	else
 		dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n",
 				acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->rtmp_handle = ret;
 
 	/* RVLT: read voltage */
 	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret);
-	if (status != AE_OK) {
+	if (ACPI_SUCCESS(status))
+		data->rvlt_handle = ret;
+	else
 		dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n",
 				acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->rvlt_handle = ret;
 
 	/* RFAN: read fan status */
 	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret);
-	if (status != AE_OK) {
+	if (ACPI_SUCCESS(status))
+		data->rfan_handle = ret;
+	else
 		dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n",
 				acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->rfan_handle = ret;
-
-	return 0;
-}
-
-static int atk_check_new_if(struct atk_data *data)
-{
-	struct device *dev = &data->acpi_dev->dev;
-	acpi_handle ret;
-	acpi_status status;
 
 	/* Enumeration */
 	status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret);
-	if (status != AE_OK) {
+	if (ACPI_SUCCESS(status))
+		data->enumerate_handle = ret;
+	else
 		dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n",
 				acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->enumerate_handle = ret;
 
 	/* De-multiplexer (read) */
 	status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret);
-	if (status != AE_OK) {
+	if (ACPI_SUCCESS(status))
+		data->read_handle = ret;
+	else
 		dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
 				acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->read_handle = ret;
 
 	/* De-multiplexer (write) */
 	status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret);
-	if (status != AE_OK) {
-		dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
+	if (ACPI_SUCCESS(status))
+		data->write_handle = ret;
+	else
+		dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n",
 				 acpi_format_exception(status));
-		return -ENODEV;
-	}
-	data->write_handle = ret;
 
-	return 0;
+	/* Check for hwmon methods: first check "old" style methods; note that
+	 * both may be present: in this case we stick to the old interface;
+	 * analysis of multiple DSDTs indicates that when both interfaces
+	 * are present the new one (GGRP/GITM) is not functional.
+	 */
+	if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle)
+		data->old_interface = true;
+	else if (data->enumerate_handle && data->read_handle &&
+			data->write_handle)
+		data->old_interface = false;
+	else
+		err = -ENODEV;
+
+	return err;
 }
 
 static int atk_add(struct acpi_device *device)
@@ -1143,40 +1329,30 @@ static int atk_add(struct acpi_device *d
 			&buf, ACPI_TYPE_PACKAGE);
 	if (ret != AE_OK) {
 		dev_dbg(&device->dev, "atk: method MBIF not found\n");
-		err = -ENODEV;
-		goto out;
+	} else {
+		obj = buf.pointer;
+		if (obj->package.count >= 2) {
+			union acpi_object *id = &obj->package.elements[1];
+			if (id->type == ACPI_TYPE_STRING)
+				dev_dbg(&device->dev, "board ID = %s\n",
+					id->string.pointer);
+		}
+		ACPI_FREE(buf.pointer);
 	}
 
-	obj = buf.pointer;
-	if (obj->package.count >= 2 &&
-			obj->package.elements[1].type == ACPI_TYPE_STRING) {
-		dev_dbg(&device->dev, "board ID = %s\n",
-				obj->package.elements[1].string.pointer);
+	err = atk_probe_if(data);
+	if (err) {
+		dev_err(&device->dev, "No usable hwmon interface detected\n");
+		goto out;
 	}
-	ACPI_FREE(buf.pointer);
 
-	/* Check for hwmon methods: first check "old" style methods; note that
-	 * both may be present: in this case we stick to the old interface;
-	 * analysis of multiple DSDTs indicates that when both interfaces
-	 * are present the new one (GGRP/GITM) is not functional.
-	 */
-	err = atk_check_old_if(data);
-	if (!err) {
+	if (data->old_interface) {
 		dev_dbg(&device->dev, "Using old hwmon interface\n");
-		data->old_interface = true;
+		err = atk_enumerate_old_hwmon(data);
 	} else {
-		err = atk_check_new_if(data);
-		if (err)
-			goto out;
-
 		dev_dbg(&device->dev, "Using new hwmon interface\n");
-		data->old_interface = false;
-	}
-
-	if (data->old_interface)
-		err = atk_enumerate_old_hwmon(data);
-	else
 		err = atk_enumerate_new_hwmon(data);
+	}
 	if (err < 0)
 		goto out;
 	if (err == 0) {
@@ -1190,6 +1366,8 @@ static int atk_add(struct acpi_device *d
 	if (err)
 		goto cleanup;
 
+	atk_debugfs_init(data);
+
 	device->driver_data = data;
 	return 0;
 cleanup:
@@ -1208,6 +1386,8 @@ static int atk_remove(struct acpi_device
 
 	device->driver_data = NULL;
 
+	atk_debugfs_cleanup(data);
+
 	atk_remove_files(data);
 	atk_free_sensors(data);
 	hwmon_device_unregister(data->hwmon_dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/atxp1.c linux-libre-2.6.33-gnu1/drivers/hwmon/atxp1.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/atxp1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/atxp1.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,17 +44,14 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@g
 
 static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
 
-I2C_CLIENT_INSMOD_1(atxp1);
-
 static int atxp1_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id);
 static int atxp1_remove(struct i2c_client *client);
 static struct atxp1_data * atxp1_update_device(struct device *dev);
-static int atxp1_detect(struct i2c_client *client, int kind,
-			struct i2c_board_info *info);
+static int atxp1_detect(struct i2c_client *client, struct i2c_board_info *info);
 
 static const struct i2c_device_id atxp1_id[] = {
-	{ "atxp1", atxp1 },
+	{ "atxp1", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, atxp1_id);
@@ -68,7 +65,7 @@ static struct i2c_driver atxp1_driver =
 	.remove		= atxp1_remove,
 	.id_table	= atxp1_id,
 	.detect		= atxp1_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 struct atxp1_data {
@@ -275,7 +272,7 @@ static const struct attribute_group atxp
 
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int atxp1_detect(struct i2c_client *new_client, int kind,
+static int atxp1_detect(struct i2c_client *new_client,
 			struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/coretemp.c linux-libre-2.6.33-gnu1/drivers/hwmon/coretemp.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/coretemp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/coretemp.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/cpu.h>
+#include <linux/pci.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
 
@@ -161,6 +162,7 @@ static int __devinit adjust_tjmax(struct
 	int usemsr_ee = 1;
 	int err;
 	u32 eax, edx;
+	struct pci_dev *host_bridge;
 
 	/* Early chips have no MSR for TjMax */
 
@@ -168,11 +170,21 @@ static int __devinit adjust_tjmax(struct
 		usemsr_ee = 0;
 	}
 
-	/* Atoms seems to have TjMax at 90C */
+	/* Atom CPUs */
 
 	if (c->x86_model == 0x1c) {
 		usemsr_ee = 0;
-		tjmax = 90000;
+
+		host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+
+		if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL
+		    && (host_bridge->device == 0xa000	/* NM10 based nettop */
+		    || host_bridge->device == 0xa010))	/* NM10 based netbook */
+			tjmax = 100000;
+		else
+			tjmax = 90000;
+
+		pci_dev_put(host_bridge);
 	}
 
 	if ((c->x86_model > 0xe) && (usemsr_ee)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/dme1737.c linux-libre-2.6.33-gnu1/drivers/hwmon/dme1737.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/dme1737.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/dme1737.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,11 +57,7 @@ MODULE_PARM_DESC(probe_all_addr, "Includ
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(dme1737, sch5027);
-
-/* ISA chip types */
-enum isa_chips { sch311x = sch5027 + 1 };
+enum chips { dme1737, sch5027, sch311x };
 
 /* ---------------------------------------------------------------------
  * Registers
@@ -2208,7 +2204,7 @@ exit:
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int dme1737_i2c_detect(struct i2c_client *client, int kind,
+static int dme1737_i2c_detect(struct i2c_client *client,
 			      struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -2220,33 +2216,23 @@ static int dme1737_i2c_detect(struct i2c
 		return -ENODEV;
 	}
 
-	/* A negative kind means that the driver was loaded with no force
-	 * parameter (default), so we must identify the chip. */
-	if (kind < 0) {
-		company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
-		verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
-
-		if (company == DME1737_COMPANY_SMSC &&
-		    (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
-			kind = dme1737;
-		} else if (company == DME1737_COMPANY_SMSC &&
-			   verstep == SCH5027_VERSTEP) {
-			kind = sch5027;
-		} else {
-			return -ENODEV;
-		}
-	}
+	company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
+	verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
 
-	if (kind == sch5027) {
+	if (company == DME1737_COMPANY_SMSC &&
+	    verstep == SCH5027_VERSTEP) {
 		name = "sch5027";
-	} else {
-		kind = dme1737;
+
+	} else if (company == DME1737_COMPANY_SMSC &&
+		   (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
 		name = "dme1737";
+	} else {
+		return -ENODEV;
 	}
 
 	dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n",
-		 kind == sch5027 ? "SCH5027" : "DME1737", client->addr,
-		 verstep);
+		 verstep == SCH5027_VERSTEP ? "SCH5027" : "DME1737",
+		 client->addr, verstep);
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
@@ -2328,7 +2314,7 @@ static struct i2c_driver dme1737_i2c_dri
 	.remove = dme1737_i2c_remove,
 	.id_table = dme1737_id,
 	.detect = dme1737_i2c_detect,
-	.address_data = &addr_data,
+	.address_list = normal_i2c,
 };
 
 /* ---------------------------------------------------------------------
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/ds1621.c linux-libre-2.6.33-gnu1/drivers/hwmon/ds1621.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/ds1621.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/ds1621.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,6 @@ static const unsigned short normal_i2c[]
 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ds1621);
 static int polarity = -1;
 module_param(polarity, int, 0);
 MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
@@ -224,7 +223,7 @@ static const struct attribute_group ds16
 
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int ds1621_detect(struct i2c_client *client, int kind,
+static int ds1621_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -237,20 +236,16 @@ static int ds1621_detect(struct i2c_clie
 		return -ENODEV;
 
 	/* Now, we do the remaining detection. It is lousy. */
-	if (kind < 0) {
-		/* 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)
+	/* 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;
-		/* 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);
@@ -309,8 +304,8 @@ static int ds1621_remove(struct i2c_clie
 }
 
 static const struct i2c_device_id ds1621_id[] = {
-	{ "ds1621", ds1621 },
-	{ "ds1625", ds1621 },
+	{ "ds1621", 0 },
+	{ "ds1625", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ds1621_id);
@@ -325,7 +320,7 @@ static struct i2c_driver ds1621_driver =
 	.remove		= ds1621_remove,
 	.id_table	= ds1621_id,
 	.detect		= ds1621_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init ds1621_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/f71882fg.c linux-libre-2.6.33-gnu1/drivers/hwmon/f71882fg.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/f71882fg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/f71882fg.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,7 @@
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
 #define SIO_F8000_ID		0x0581	/* Chipset ID */
 
 #define REGION_LENGTH		8
@@ -95,12 +96,13 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f8000 };
+enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
+	"f71889fg",
 	"f8000",
 };
 
@@ -155,7 +157,7 @@ struct f71882fg_data {
 	u8	pwm_auto_point_hyst[2];
 	u8	pwm_auto_point_mapping[4];
 	u8	pwm_auto_point_pwm[4][5];
-	u8	pwm_auto_point_temp[4][4];
+	s8	pwm_auto_point_temp[4][4];
 };
 
 /* Sysfs in */
@@ -258,7 +260,9 @@ static struct platform_driver f71882fg_d
 
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-/* Temp and in attr for the f71858fg */
+/* Temp and in attr for the f71858fg, the f71858fg is special as it
+   has its temperature indexes start at 0 (the others start at 1) and
+   it only has 3 voltage inputs */
 static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
@@ -302,8 +306,8 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to both the f71862fg and f71882fg */
-static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -371,8 +375,8 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
 };
 
-/* Temp and in attr found only on the f71882fg */
-static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
+/* For models with in1 alarm capability */
+static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
 	SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
 		0, 1),
 	SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
@@ -383,6 +387,7 @@ static struct sensor_device_attribute_2
 /* Temp and in attr for the f8000
    Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
    is used as hysteresis value to clear alarms
+   Also like the f71858fg its temperature indexes start at 0
  */
 static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
@@ -413,61 +418,70 @@ static struct sensor_device_attribute_2
 };
 
 /* Fan / PWM attr common to all models */
-static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
+static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
 	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
 	SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
 		      show_fan_full_speed,
 		      store_fan_full_speed, 0, 0),
 	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
-	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
-	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 1),
-	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
-	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
-	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 2),
-	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
-
 	SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
 	SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 0),
 	SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 0),
-	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 0),
-
+}, {
+	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
+	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 1),
+	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
 	SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
 	SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 1),
 	SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 1),
-	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 1),
-
+}, {
+	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
+	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 2),
+	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
 	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
 	SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 		      store_pwm_enable, 0, 2),
 	SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 2),
-	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
-		      show_pwm_auto_point_channel,
-		      store_pwm_auto_point_channel, 0, 2),
-};
+}, {
+	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 3),
+	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
+	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
+	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 3),
+	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
+} };
 
-/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
-   f71882fg */
-static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
+/* Attr for models which can beep on Fan alarm */
+static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
 	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 0),
 	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 1),
 	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 2),
+	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 3),
+};
 
+/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
+   f71858fg / f71882fg / f71889fg */
+static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 0),
@@ -487,6 +501,9 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 1),
@@ -506,6 +523,9 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
 
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      1, 2),
@@ -526,8 +546,11 @@ static struct sensor_device_attribute_2
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 };
 
-/* Fan / PWM attr common to both the f71882fg and f71858fg */
-static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
+/* PWM attr common to the f71858fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 0),
@@ -565,7 +588,10 @@ static struct sensor_device_attribute_2
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
 	SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
-
+}, {
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 1),
@@ -603,7 +629,10 @@ static struct sensor_device_attribute_2
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
 	SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
-
+}, {
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 2),
@@ -641,30 +670,7 @@ static struct sensor_device_attribute_2
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
 	SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
-};
-
-/* Fan / PWM attr found on the f71882fg but not on the f71858fg */
-static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
-	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 0),
-	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 1),
-	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 2),
-
-	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
-	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
-		      show_fan_full_speed,
-		      store_fan_full_speed, 0, 3),
-	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0, 3),
-	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
-
-	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
-	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
-		      store_pwm_enable, 0, 3),
-	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
-		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
+}, {
 	SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_channel,
 		      store_pwm_auto_point_channel, 0, 3),
@@ -705,14 +711,20 @@ static struct sensor_device_attribute_2
 		      show_pwm_auto_point_temp_hyst, NULL, 2, 3),
 	SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 3),
-};
+} };
 
-/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
-   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
-   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
+/* Fan attr specific to the f8000 (4th fan input can only measure speed) */
 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
 	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+};
 
+/* PWM attr for the f8000, zones mapped to temp instead of to pwm!
+   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
+   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
+static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
 	SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 2),
@@ -751,6 +763,9 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
 	SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 0),
@@ -789,6 +804,9 @@ static struct sensor_device_attribute_2
 	SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
 	SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 		      0, 1),
@@ -929,7 +947,7 @@ static struct f71882fg_data *f71882fg_up
 	/* Update once every 60 seconds */
 	if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
 			!data->valid) {
-		if (data->type == f71882fg) {
+		if (data->type == f71882fg || data->type == f71889fg) {
 			data->in1_max =
 				f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
 			data->in_beep =
@@ -951,7 +969,8 @@ static struct f71882fg_data *f71882fg_up
 						F71882FG_REG_TEMP_HYST(1));
 		}
 
-		if (data->type == f71862fg || data->type == f71882fg) {
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg) {
 			data->fan_beep = f71882fg_read8(data,
 						F71882FG_REG_FAN_BEEP);
 			data->temp_beep = f71882fg_read8(data,
@@ -961,15 +980,33 @@ static struct f71882fg_data *f71882fg_up
 			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
 			data->temp_type[3] = (reg & 0x08) ? 2 : 4;
 		}
-		reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
-		if ((reg2 & 0x03) == 0x01)
-			data->temp_type[1] = 6 /* PECI */;
-		else if ((reg2 & 0x03) == 0x02)
-			data->temp_type[1] = 5 /* AMDSI */;
-		else if (data->type == f71862fg || data->type == f71882fg)
-			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
-		else
-			data->temp_type[1] = 2; /* Only supports BJT */
+		/* Determine temp index 1 sensor type */
+		if (data->type == f71889fg) {
+			reg2 = f71882fg_read8(data, F71882FG_REG_START);
+			switch ((reg2 & 0x60) >> 5) {
+			case 0x00: /* BJT / Thermistor */
+				data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+				break;
+			case 0x01: /* AMDSI */
+				data->temp_type[1] = 5;
+				break;
+			case 0x02: /* PECI */
+			case 0x03: /* Ibex Peak ?? Report as PECI for now */
+				data->temp_type[1] = 6;
+				break;
+			}
+		} else {
+			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
+			if ((reg2 & 0x03) == 0x01)
+				data->temp_type[1] = 6; /* PECI */
+			else if ((reg2 & 0x03) == 0x02)
+				data->temp_type[1] = 5; /* AMDSI */
+			else if (data->type == f71862fg ||
+				 data->type == f71882fg)
+				data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			else /* f71858fg and f8000 only support BJT */
+				data->temp_type[1] = 2;
+		}
 
 		data->pwm_enable = f71882fg_read8(data,
 						  F71882FG_REG_PWM_ENABLE);
@@ -1046,7 +1083,7 @@ static struct f71882fg_data *f71882fg_up
 		if (data->type == f8000)
 			data->fan[3] = f71882fg_read16(data,
 						F71882FG_REG_FAN(3));
-		if (data->type == f71882fg)
+		if (data->type == f71882fg || data->type == f71889fg)
 			data->in_status = f71882fg_read8(data,
 						F71882FG_REG_IN_STATUS);
 		for (nr = 0; nr < nr_ins; nr++)
@@ -1764,7 +1801,11 @@ static ssize_t store_pwm_auto_point_temp
 	int pwm = to_sensor_dev_attr_2(devattr)->index;
 	int point = to_sensor_dev_attr_2(devattr)->nr;
 	long val = simple_strtol(buf, NULL, 10) / 1000;
-	val = SENSORS_LIMIT(val, 0, 255);
+
+	if (data->type == f71889fg)
+		val = SENSORS_LIMIT(val, -128, 127);
+	else
+		val = SENSORS_LIMIT(val, 0, 127);
 
 	mutex_lock(&data->update_lock);
 	f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
@@ -1794,6 +1835,15 @@ static int __devinit f71882fg_create_sys
 	return 0;
 }
 
+static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
+	struct sensor_device_attribute_2 *attr, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		device_remove_file(&pdev->dev, &attr[i].dev_attr);
+}
+
 static int __devinit f71882fg_probe(struct platform_device *pdev)
 {
 	struct f71882fg_data *data;
@@ -1846,16 +1896,17 @@ static int __devinit f71882fg_probe(stru
 					ARRAY_SIZE(f71858fg_in_temp_attr));
 			break;
 		case f71882fg:
+		case f71889fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_in_temp_attr,
-					ARRAY_SIZE(f71882fg_in_temp_attr));
+					fxxxx_in1_alarm_attr,
+					ARRAY_SIZE(fxxxx_in1_alarm_attr));
 			if (err)
 				goto exit_unregister_sysfs;
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f718x2fg_in_temp_attr,
-					ARRAY_SIZE(f718x2fg_in_temp_attr));
+					fxxxx_in_temp_attr,
+					ARRAY_SIZE(fxxxx_in_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -1883,6 +1934,7 @@ static int __devinit f71882fg_probe(stru
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
 		case f71882fg:
+		case f71889fg:
 			err = 0;
 			break;
 		case f8000:
@@ -1897,34 +1949,55 @@ static int __devinit f71882fg_probe(stru
 			goto exit_unregister_sysfs;
 		}
 
-		err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
-					ARRAY_SIZE(fxxxx_fan_attr));
+		err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
+				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
 		if (err)
 			goto exit_unregister_sysfs;
 
-		switch (data->type) {
-		case f71862fg:
-			err = f71882fg_create_sysfs_files(pdev,
-					f71862fg_fan_attr,
-					ARRAY_SIZE(f71862fg_fan_attr));
-			break;
-		case f71882fg:
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg) {
 			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_fan_attr,
-					ARRAY_SIZE(f71882fg_fan_attr));
+					fxxxx_fan_beep_attr, nr_fans);
 			if (err)
 				goto exit_unregister_sysfs;
-			/* fall through! */
-		case f71858fg:
+		}
+
+		switch (data->type) {
+		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					f71882fg_f71858fg_fan_attr,
-					ARRAY_SIZE(f71882fg_f71858fg_fan_attr));
+					f71862fg_auto_pwm_attr,
+					ARRAY_SIZE(f71862fg_auto_pwm_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
 					f8000_fan_attr,
 					ARRAY_SIZE(f8000_fan_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					f8000_auto_pwm_attr,
+					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71889fg:
+			for (i = 0; i < nr_fans; i++) {
+				data->pwm_auto_point_mapping[i] =
+					f71882fg_read8(data,
+						F71882FG_REG_POINT_MAPPING(i));
+				if (data->pwm_auto_point_mapping[i] & 0x80)
+					break;
+			}
+			if (i != nr_fans) {
+				dev_warn(&pdev->dev,
+					 "Auto pwm controlled by raw digital "
+					 "data, disabling pwm auto_point "
+					 "sysfs attributes\n");
+				break;
+			}
+			/* fall through */
+		default: /* f71858fg / f71882fg */
+			err = f71882fg_create_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
 		}
 		if (err)
 			goto exit_unregister_sysfs;
@@ -1954,33 +2027,76 @@ exit_free:
 
 static int f71882fg_remove(struct platform_device *pdev)
 {
-	int i;
 	struct f71882fg_data *data = platform_get_drvdata(pdev);
+	int nr_fans = (data->type == f71882fg) ? 4 : 3;
+	u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
 
 	platform_set_drvdata(pdev, NULL);
 	if (data->hwmon_dev)
 		hwmon_device_unregister(data->hwmon_dev);
 
-	/* Note we are not looping over all attr arrays we have as the ones
-	   below are supersets of the ones skipped. */
 	device_remove_file(&pdev->dev, &dev_attr_name);
 
-	for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
-		device_remove_file(&pdev->dev,
-					&f718x2fg_in_temp_attr[i].dev_attr);
-
-	for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
-		device_remove_file(&pdev->dev,
-					&f71882fg_in_temp_attr[i].dev_attr);
+	if (start_reg & 0x01) {
+		switch (data->type) {
+		case f71858fg:
+			if (data->temp_config & 0x10)
+				f71882fg_remove_sysfs_files(pdev,
+					f8000_in_temp_attr,
+					ARRAY_SIZE(f8000_in_temp_attr));
+			else
+				f71882fg_remove_sysfs_files(pdev,
+					f71858fg_in_temp_attr,
+					ARRAY_SIZE(f71858fg_in_temp_attr));
+			break;
+		case f71882fg:
+		case f71889fg:
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in1_alarm_attr,
+					ARRAY_SIZE(fxxxx_in1_alarm_attr));
+			/* fall through! */
+		case f71862fg:
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_temp_attr,
+					ARRAY_SIZE(fxxxx_in_temp_attr));
+			break;
+		case f8000:
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_in_temp_attr,
+					ARRAY_SIZE(f8000_in_temp_attr));
+			break;
+		}
+	}
 
-	for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
-		device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
+	if (start_reg & 0x02) {
+		f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
+				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
 
-	for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
-		device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
+		if (data->type == f71862fg || data->type == f71882fg ||
+		    data->type == f71889fg)
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_fan_beep_attr, nr_fans);
 
-	for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
-		device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
+		switch (data->type) {
+		case f71862fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71862fg_auto_pwm_attr,
+					ARRAY_SIZE(f71862fg_auto_pwm_attr));
+			break;
+		case f8000:
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_fan_attr,
+					ARRAY_SIZE(f8000_fan_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					f8000_auto_pwm_attr,
+					ARRAY_SIZE(f8000_auto_pwm_attr));
+			break;
+		default: /* f71858fg / f71882fg / f71889fg */
+			f71882fg_remove_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
+		}
+	}
 
 	kfree(data);
 
@@ -2012,11 +2128,15 @@ static int __init f71882fg_find(int sioa
 	case SIO_F71882_ID:
 		sio_data->type = f71882fg;
 		break;
+	case SIO_F71889_ID:
+		sio_data->type = f71889fg;
+		break;
 	case SIO_F8000_ID:
 		sio_data->type = f8000;
 		break;
 	default:
-		printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
+		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
+		       (unsigned int)devid);
 		goto exit;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/f75375s.c linux-libre-2.6.33-gnu1/drivers/hwmon/f75375s.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/f75375s.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/f75375s.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,7 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(f75373, f75375);
+enum chips { f75373, f75375 };
 
 /* Fintek F75375 registers  */
 #define F75375_REG_CONFIG0		0x0
@@ -113,7 +112,7 @@ struct f75375_data {
 	s8 temp_max_hyst[2];
 };
 
-static int f75375_detect(struct i2c_client *client, int kind,
+static int f75375_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int f75375_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
@@ -135,7 +134,7 @@ static struct i2c_driver f75375_driver =
 	.remove = f75375_remove,
 	.id_table = f75375_id,
 	.detect = f75375_detect,
-	.address_data = &addr_data,
+	.address_list = normal_i2c,
 };
 
 static inline int f75375_read8(struct i2c_client *client, u8 reg)
@@ -677,34 +676,24 @@ static int f75375_remove(struct i2c_clie
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int f75375_detect(struct i2c_client *client, int kind,
+static int f75375_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	u8 version = 0;
-	const char *name = "";
-
-	if (kind < 0) {
-		u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
-		u16 chipid = f75375_read16(client, F75375_CHIP_ID);
-		version = f75375_read8(client, F75375_REG_VERSION);
-		if (chipid == 0x0306 && vendid == 0x1934) {
-			kind = f75375;
-		} else if (chipid == 0x0204 && vendid == 0x1934) {
-			kind = f75373;
-		} else {
-			dev_err(&adapter->dev,
-				"failed,%02X,%02X,%02X\n",
-				chipid, version, vendid);
-			return -ENODEV;
-		}
-	}
+	u16 vendid, chipid;
+	u8 version;
+	const char *name;
 
-	if (kind == f75375) {
+	vendid = f75375_read16(client, F75375_REG_VENDOR);
+	chipid = f75375_read16(client, F75375_CHIP_ID);
+	if (chipid == 0x0306 && vendid == 0x1934)
 		name = "f75375";
-	} else if (kind == f75373) {
+	else if (chipid == 0x0204 && vendid == 0x1934)
 		name = "f75373";
-	}
+	else
+		return -ENODEV;
+
+	version = f75375_read8(client, F75375_REG_VERSION);
 	dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/fschmd.c linux-libre-2.6.33-gnu1/drivers/hwmon/fschmd.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/fschmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/fschmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,8 @@ static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl);
+
+enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl };
 
 /*
  * The FSCHMD registers and other defines
@@ -221,7 +222,7 @@ static const int FSCHMD_NO_TEMP_SENSORS[
 
 static int fschmd_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
-static int fschmd_detect(struct i2c_client *client, int kind,
+static int fschmd_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int fschmd_remove(struct i2c_client *client);
 static struct fschmd_data *fschmd_update_device(struct device *dev);
@@ -251,7 +252,7 @@ static struct i2c_driver fschmd_driver =
 	.remove		= fschmd_remove,
 	.id_table	= fschmd_id,
 	.detect		= fschmd_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -767,6 +768,7 @@ leave:
 static int watchdog_open(struct inode *inode, struct file *filp)
 {
 	struct fschmd_data *pos, *data = NULL;
+	int watchdog_is_open;
 
 	/* We get called from drivers/char/misc.c with misc_mtx hold, and we
 	   call misc_register() from fschmd_probe() with watchdog_data_mutex
@@ -781,10 +783,12 @@ static int watchdog_open(struct inode *i
 		}
 	}
 	/* Note we can never not have found data, so we don't check for this */
-	kref_get(&data->kref);
+	watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
+	if (!watchdog_is_open)
+		kref_get(&data->kref);
 	mutex_unlock(&watchdog_data_mutex);
 
-	if (test_and_set_bit(0, &data->watchdog_is_open))
+	if (watchdog_is_open)
 		return -EBUSY;
 
 	/* Start the watchdog */
@@ -1000,43 +1004,38 @@ static void fschmd_dmi_decode(const stru
 	}
 }
 
-static int fschmd_detect(struct i2c_client *client, int kind,
+static int fschmd_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
+	char id[4];
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
 	/* Detect & Identify the chip */
-	if (kind <= 0) {
-		char id[4];
-
-		id[0] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_0);
-		id[1] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_1);
-		id[2] = i2c_smbus_read_byte_data(client,
-				FSCHMD_REG_IDENT_2);
-		id[3] = '\0';
+	id[0] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_0);
+	id[1] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_1);
+	id[2] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_2);
+	id[3] = '\0';
 
-		if (!strcmp(id, "PEG"))
-			kind = fscpos;
-		else if (!strcmp(id, "HER"))
-			kind = fscher;
-		else if (!strcmp(id, "SCY"))
-			kind = fscscy;
-		else if (!strcmp(id, "HRC"))
-			kind = fschrc;
-		else if (!strcmp(id, "HMD"))
-			kind = fschmd;
-		else if (!strcmp(id, "HDS"))
-			kind = fschds;
-		else if (!strcmp(id, "SYL"))
-			kind = fscsyl;
-		else
-			return -ENODEV;
-	}
+	if (!strcmp(id, "PEG"))
+		kind = fscpos;
+	else if (!strcmp(id, "HER"))
+		kind = fscher;
+	else if (!strcmp(id, "SCY"))
+		kind = fscscy;
+	else if (!strcmp(id, "HRC"))
+		kind = fschrc;
+	else if (!strcmp(id, "HMD"))
+		kind = fschmd;
+	else if (!strcmp(id, "HDS"))
+		kind = fschds;
+	else if (!strcmp(id, "SYL"))
+		kind = fscsyl;
+	else
+		return -ENODEV;
 
 	strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/gl518sm.c linux-libre-2.6.33-gnu1/drivers/hwmon/gl518sm.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/gl518sm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/gl518sm.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,8 +46,7 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80);
+enum chips { gl518sm_r00, gl518sm_r80 };
 
 /* Many GL518 constants specified below */
 
@@ -139,8 +138,7 @@ struct gl518_data {
 
 static int gl518_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id);
-static int gl518_detect(struct i2c_client *client, int kind,
-			struct i2c_board_info *info);
+static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void gl518_init_client(struct i2c_client *client);
 static int gl518_remove(struct i2c_client *client);
 static int gl518_read_value(struct i2c_client *client, u8 reg);
@@ -163,7 +161,7 @@ static struct i2c_driver gl518_driver =
 	.remove		= gl518_remove,
 	.id_table	= gl518_id,
 	.detect		= gl518_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -484,40 +482,24 @@ static const struct attribute_group gl51
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int gl518_detect(struct i2c_client *client, int kind,
-			struct i2c_board_info *info)
+static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i;
+	int rev;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
 	/* Now, we do the remaining detection. */
-
-	if (kind < 0) {
-		if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80)
-		 || (gl518_read_value(client, GL518_REG_CONF) & 0x80))
-			return -ENODEV;
-	}
+	if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80)
+	 || (gl518_read_value(client, GL518_REG_CONF) & 0x80))
+		return -ENODEV;
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = gl518_read_value(client, GL518_REG_REVISION);
-		if (i == 0x00) {
-			kind = gl518sm_r00;
-		} else if (i == 0x80) {
-			kind = gl518sm_r80;
-		} else {
-			if (kind <= 0)
-				dev_info(&adapter->dev,
-				    "Ignoring 'force' parameter for unknown "
-				    "chip at adapter %d, address 0x%02x\n",
-				    i2c_adapter_id(adapter), client->addr);
-			return -ENODEV;
-		}
-	}
+	rev = gl518_read_value(client, GL518_REG_REVISION);
+	if (rev != 0x00 && rev != 0x80)
+		return -ENODEV;
 
 	strlcpy(info->type, "gl518sm", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/gl520sm.c linux-libre-2.6.33-gnu1/drivers/hwmon/gl520sm.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/gl520sm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/gl520sm.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,9 +41,6 @@ MODULE_PARM_DESC(extra_sensor_type, "Typ
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(gl520sm);
-
 /* Many GL520 constants specified below
 One of the inputs can be configured as either temp or voltage.
 That's why _TEMP2 and _IN4 access the same register
@@ -81,8 +78,7 @@ static const u8 GL520_REG_TEMP_MAX_HYST[
 
 static int gl520_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id);
-static int gl520_detect(struct i2c_client *client, int kind,
-			struct i2c_board_info *info);
+static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void gl520_init_client(struct i2c_client *client);
 static int gl520_remove(struct i2c_client *client);
 static int gl520_read_value(struct i2c_client *client, u8 reg);
@@ -91,7 +87,7 @@ static struct gl520_data *gl520_update_d
 
 /* Driver data */
 static const struct i2c_device_id gl520_id[] = {
-	{ "gl520sm", gl520sm },
+	{ "gl520sm", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, gl520_id);
@@ -105,7 +101,7 @@ static struct i2c_driver gl520_driver =
 	.remove		= gl520_remove,
 	.id_table	= gl520_id,
 	.detect		= gl520_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* Client data */
@@ -681,8 +677,7 @@ static const struct attribute_group gl52
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int gl520_detect(struct i2c_client *client, int kind,
-			struct i2c_board_info *info)
+static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 
@@ -691,13 +686,11 @@ static int gl520_detect(struct i2c_clien
 		return -ENODEV;
 
 	/* Determine the chip type. */
-	if (kind < 0) {
-		if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
-		    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
-		    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
-			dev_dbg(&client->dev, "Unknown chip type, skipping\n");
-			return -ENODEV;
-		}
+	if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
+	    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
+	    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
+		dev_dbg(&client->dev, "Unknown chip type, skipping\n");
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "gl520sm", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/it87.c linux-libre-2.6.33-gnu1/drivers/hwmon/it87.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/it87.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/it87.c	2010-02-24 13:52:17.000000000 -0500
@@ -124,6 +124,8 @@ superio_exit(void)
 #define IT87_BASE_REG 0x60
 
 /* Logical device 7 registers (IT8712F and later) */
+#define IT87_SIO_GPIO3_REG	0x27
+#define IT87_SIO_GPIO5_REG	0x29
 #define IT87_SIO_PINX2_REG	0x2c	/* Pin selection */
 #define IT87_SIO_VID_REG	0xfc	/* VID value */
 
@@ -244,7 +246,9 @@ struct it87_sio_data {
 	/* Values read from Super-I/O config space */
 	u8 revision;
 	u8 vid_value;
-	/* Values set based on DMI strings */
+	/* Features skipped based on config or DMI */
+	u8 skip_vid;
+	u8 skip_fan;
 	u8 skip_pwm;
 };
 
@@ -1028,11 +1032,35 @@ static int __init it87_find(unsigned sho
 		chip_type, *address, sio_data->revision);
 
 	/* Read GPIO config and VID value from LDN 7 (GPIO) */
-	if (sio_data->type != it87) {
+	if (sio_data->type == it87) {
+		/* The IT8705F doesn't have VID pins at all */
+		sio_data->skip_vid = 1;
+	} else {
 		int reg;
 
 		superio_select(GPIO);
-		if (sio_data->type == it8718 || sio_data->type == it8720)
+		/* We need at least 4 VID pins */
+		reg = superio_inb(IT87_SIO_GPIO3_REG);
+		if (reg & 0x0f) {
+			pr_info("it87: VID is disabled (pins used for GPIO)\n");
+			sio_data->skip_vid = 1;
+		}
+
+		/* Check if fan3 is there or not */
+		if (reg & (1 << 6))
+			sio_data->skip_pwm |= (1 << 2);
+		if (reg & (1 << 7))
+			sio_data->skip_fan |= (1 << 2);
+
+		/* Check if fan2 is there or not */
+		reg = superio_inb(IT87_SIO_GPIO5_REG);
+		if (reg & (1 << 1))
+			sio_data->skip_pwm |= (1 << 1);
+		if (reg & (1 << 2))
+			sio_data->skip_fan |= (1 << 1);
+
+		if ((sio_data->type == it8718 || sio_data->type == it8720)
+		 && !(sio_data->skip_vid))
 			sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
 
 		reg = superio_inb(IT87_SIO_PINX2_REG);
@@ -1236,8 +1264,7 @@ static int __devinit it87_probe(struct p
 		}
 	}
 
-	if (data->type == it8712 || data->type == it8716
-	 || data->type == it8718 || data->type == it8720) {
+	if (!sio_data->skip_vid) {
 		data->vrm = vid_which_vrm();
 		/* VID reading from Super-I/O config space if available */
 		data->vid = sio_data->vid_value;
@@ -1355,8 +1382,10 @@ static int __devinit it87_check_pwm(stru
 /* Called when we have found a new IT87. */
 static void __devinit it87_init_device(struct platform_device *pdev)
 {
+	struct it87_sio_data *sio_data = pdev->dev.platform_data;
 	struct it87_data *data = platform_get_drvdata(pdev);
 	int tmp, i;
+	u8 mask;
 
 	/* initialize to sane defaults:
 	 * - if the chip is in manual pwm mode, this will be overwritten with
@@ -1402,10 +1431,11 @@ static void __devinit it87_init_device(s
 	}
 
 	/* Check if tachometers are reset manually or by some reason */
+	mask = 0x70 & ~(sio_data->skip_fan << 4);
 	data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
-	if ((data->fan_main_ctrl & 0x70) == 0) {
+	if ((data->fan_main_ctrl & mask) == 0) {
 		/* Enable all fan tachometers */
-		data->fan_main_ctrl |= 0x70;
+		data->fan_main_ctrl |= mask;
 		it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
 	}
 	data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
@@ -1428,6 +1458,9 @@ static void __devinit it87_init_device(s
 		}
 	}
 
+	/* Fan input pins may be used for alternative functions */
+	data->has_fan &= ~sio_data->skip_fan;
+
 	/* Set current fan mode registers and the default settings for the
 	 * other mode registers */
 	for (i = 0; i < 3; i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/k10temp.c linux-libre-2.6.33-gnu1/drivers/hwmon/k10temp.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/k10temp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/k10temp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,223 @@
+/*
+ * k10temp.c - AMD Family 10h/11h processor hardware monitoring
+ *
+ * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
+ *
+ *
+ * This driver is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <asm/processor.h>
+
+MODULE_DESCRIPTION("AMD Family 10h/11h CPU core temperature monitor");
+MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
+MODULE_LICENSE("GPL");
+
+static bool force;
+module_param(force, bool, 0444);
+MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
+
+/* CPUID function 0x80000001, ebx */
+#define CPUID_PKGTYPE_MASK	0xf0000000
+#define CPUID_PKGTYPE_F		0x00000000
+#define CPUID_PKGTYPE_AM2R2_AM3	0x10000000
+
+/* DRAM controller (PCI function 2) */
+#define REG_DCT0_CONFIG_HIGH		0x094
+#define  DDR3_MODE			0x00000100
+
+/* miscellaneous (PCI function 3) */
+#define REG_HARDWARE_THERMAL_CONTROL	0x64
+#define  HTC_ENABLE			0x00000001
+
+#define REG_REPORTED_TEMPERATURE	0xa4
+
+#define REG_NORTHBRIDGE_CAPABILITIES	0xe8
+#define  NB_CAP_HTC			0x00000400
+
+static ssize_t show_temp(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	u32 regval;
+
+	pci_read_config_dword(to_pci_dev(dev),
+			      REG_REPORTED_TEMPERATURE, &regval);
+	return sprintf(buf, "%u\n", (regval >> 21) * 125);
+}
+
+static ssize_t show_temp_max(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", 70 * 1000);
+}
+
+static ssize_t show_temp_crit(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int show_hyst = attr->index;
+	u32 regval;
+	int value;
+
+	pci_read_config_dword(to_pci_dev(dev),
+			      REG_HARDWARE_THERMAL_CONTROL, &regval);
+	value = ((regval >> 16) & 0x7f) * 500 + 52000;
+	if (show_hyst)
+		value -= ((regval >> 24) & 0xf) * 500;
+	return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "k10temp\n");
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static bool __devinit has_erratum_319(struct pci_dev *pdev)
+{
+	u32 pkg_type, reg_dram_cfg;
+
+	if (boot_cpu_data.x86 != 0x10)
+		return false;
+
+	/*
+	 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
+	 *              may be unreliable.
+	 */
+	pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
+	if (pkg_type == CPUID_PKGTYPE_F)
+		return true;
+	if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
+		return false;
+
+	/* Differentiate between AM2+ (bad) and AM3 (good) */
+	pci_bus_read_config_dword(pdev->bus,
+				  PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
+				  REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
+	return !(reg_dram_cfg & DDR3_MODE);
+}
+
+static int __devinit k10temp_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *id)
+{
+	struct device *hwmon_dev;
+	u32 reg_caps, reg_htc;
+	int unreliable = has_erratum_319(pdev);
+	int err;
+
+	if (unreliable && !force) {
+		dev_err(&pdev->dev,
+			"unreliable CPU thermal sensor; monitoring disabled\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	err = device_create_file(&pdev->dev, &dev_attr_temp1_input);
+	if (err)
+		goto exit;
+	err = device_create_file(&pdev->dev, &dev_attr_temp1_max);
+	if (err)
+		goto exit_remove;
+
+	pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, &reg_caps);
+	pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, &reg_htc);
+	if ((reg_caps & NB_CAP_HTC) && (reg_htc & HTC_ENABLE)) {
+		err = device_create_file(&pdev->dev,
+				&sensor_dev_attr_temp1_crit.dev_attr);
+		if (err)
+			goto exit_remove;
+		err = device_create_file(&pdev->dev,
+				&sensor_dev_attr_temp1_crit_hyst.dev_attr);
+		if (err)
+			goto exit_remove;
+	}
+
+	err = device_create_file(&pdev->dev, &dev_attr_name);
+	if (err)
+		goto exit_remove;
+
+	hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(hwmon_dev)) {
+		err = PTR_ERR(hwmon_dev);
+		goto exit_remove;
+	}
+	dev_set_drvdata(&pdev->dev, hwmon_dev);
+
+	if (unreliable && force)
+		dev_warn(&pdev->dev,
+			 "unreliable CPU thermal sensor; check erratum 319\n");
+	return 0;
+
+exit_remove:
+	device_remove_file(&pdev->dev, &dev_attr_name);
+	device_remove_file(&pdev->dev, &dev_attr_temp1_input);
+	device_remove_file(&pdev->dev, &dev_attr_temp1_max);
+	device_remove_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_crit.dev_attr);
+	device_remove_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_crit_hyst.dev_attr);
+exit:
+	return err;
+}
+
+static void __devexit k10temp_remove(struct pci_dev *pdev)
+{
+	hwmon_device_unregister(dev_get_drvdata(&pdev->dev));
+	device_remove_file(&pdev->dev, &dev_attr_name);
+	device_remove_file(&pdev->dev, &dev_attr_temp1_input);
+	device_remove_file(&pdev->dev, &dev_attr_temp1_max);
+	device_remove_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_crit.dev_attr);
+	device_remove_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_crit_hyst.dev_attr);
+	dev_set_drvdata(&pdev->dev, NULL);
+}
+
+static const struct pci_device_id k10temp_id_table[] = {
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
+	{}
+};
+MODULE_DEVICE_TABLE(pci, k10temp_id_table);
+
+static struct pci_driver k10temp_driver = {
+	.name = "k10temp",
+	.id_table = k10temp_id_table,
+	.probe = k10temp_probe,
+	.remove = __devexit_p(k10temp_remove),
+};
+
+static int __init k10temp_init(void)
+{
+	return pci_register_driver(&k10temp_driver);
+}
+
+static void __exit k10temp_exit(void)
+{
+	pci_unregister_driver(&k10temp_driver);
+}
+
+module_init(k10temp_init)
+module_exit(k10temp_exit)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/k8temp.c linux-libre-2.6.33-gnu1/drivers/hwmon/k8temp.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/k8temp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/k8temp.c	2010-02-24 13:52:17.000000000 -0500
@@ -136,7 +136,7 @@ static SENSOR_DEVICE_ATTR_2(temp3_input,
 static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-static struct pci_device_id k8temp_ids[] = {
+static const struct pci_device_id k8temp_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 	{ 0 },
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/Kconfig linux-libre-2.6.33-gnu1/drivers/hwmon/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/hwmon/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -191,21 +191,27 @@ config SENSORS_ADT7470
 	  will be called adt7470.
 
 config SENSORS_ADT7473
-	tristate "Analog Devices ADT7473"
+	tristate "Analog Devices ADT7473 (DEPRECATED)"
 	depends on I2C && EXPERIMENTAL
+	select SENSORS_ADT7475
 	help
 	  If you say yes here you get support for the Analog Devices
 	  ADT7473 temperature monitoring chips.
 
+	  This driver is deprecated, you should use the adt7475 driver
+	  instead.
+
 	  This driver can also be built as a module. If so, the module
 	  will be called adt7473.
 
 config SENSORS_ADT7475
-	tristate "Analog Devices ADT7475"
+	tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490"
 	depends on I2C && EXPERIMENTAL
+	select HWMON_VID
 	help
 	  If you say yes here you get support for the Analog Devices
-	  ADT7475 hardware monitoring chips.
+	  ADT7473, ADT7475, ADT7476 and ADT7490 hardware monitoring
+	  chips.
 
 	  This driver can also be build as a module.  If so, the module
 	  will be called adt7475.
@@ -222,6 +228,18 @@ config SENSORS_K8TEMP
 	  This driver can also be built as a module.  If so, the module
 	  will be called k8temp.
 
+config SENSORS_K10TEMP
+	tristate "AMD Phenom/Sempron/Turion/Opteron temperature sensor"
+	depends on X86 && PCI
+	help
+	  If you say yes here you get support for the temperature
+	  sensor(s) inside your CPU. Supported are later revisions of
+	  the AMD Family 10h and all revisions of the AMD Family 11h
+	  microarchitectures.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called k10temp.
+
 config SENSORS_AMS
 	tristate "Apple Motion Sensor driver"
 	depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
@@ -305,12 +323,12 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG and F8000"
+	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
 	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG
-	  and F8000 Super-I/O chips.
+	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called f71882fg.
@@ -374,7 +392,7 @@ config SENSORS_GL520SM
 
 config SENSORS_CORETEMP
 	tristate "Intel Core/Core2/Atom temperature sensor"
-	depends on X86 && EXPERIMENTAL
+	depends on X86 && PCI && EXPERIMENTAL
 	help
 	  If you say yes here you get support for the temperature
 	  sensor inside your CPU. Most of the family 6 CPUs
@@ -442,6 +460,15 @@ config SENSORS_LM70
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm70.
 
+config SENSORS_LM73
+	tristate "National Semiconductor LM73"
+	depends on I2C
+	help
+	  If you say yes here you get support for National Semiconductor LM73
+	  sensor chips.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm73.
+
 config SENSORS_LM75
 	tristate "National Semiconductor LM75 and compatibles"
 	depends on I2C
@@ -765,6 +792,16 @@ config SENSORS_ADS7828
 	  This driver can also be built as a module.  If so, the module
 	  will be called ads7828.
 
+config SENSORS_AMC6821
+	tristate "Texas Instruments AMC6821"
+	depends on I2C  && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  AMC6821 hardware monitoring chips.
+
+	  This driver can also be build as a module.  If so, the module
+	  will be called amc6821.
+
 config SENSORS_THMC50
 	tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
 	depends on I2C && EXPERIMENTAL
@@ -795,6 +832,14 @@ config SENSORS_TMP421
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp421.
 
+config SENSORS_VIA_CPUTEMP
+	tristate "VIA CPU temperature sensor"
+	depends on X86
+	help
+	  If you say yes here you get support for the temperature
+	  sensor inside your CPU. Supported are all known variants of
+	  the VIA C7 and Nano.
+
 config SENSORS_VIA686A
 	tristate "VIA686A"
 	depends on PCI
@@ -841,7 +886,7 @@ config SENSORS_W83781D
 
 config SENSORS_W83791D
 	tristate "Winbond W83791D"
-	depends on I2C && EXPERIMENTAL
+	depends on I2C
 	select HWMON_VID
 	help
 	  If you say yes here you get support for the Winbond W83791D chip.
@@ -983,6 +1028,23 @@ config SENSORS_LIS3_SPI
 	  will be called lis3lv02d and a specific module for the SPI transport
 	  is called lis3lv02d_spi.
 
+config SENSORS_LIS3_I2C
+	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)"
+	depends on I2C && INPUT
+	select INPUT_POLLDEV
+	default n
+	help
+	  This driver provides support for the LIS3LV02Dx accelerometer connected
+	  via I2C. The accelerometer data is readable via
+	  /sys/devices/platform/lis3lv02d.
+
+	  This driver also provides an absolute input class device, allowing
+	  the device to act as a pinball machine-esque joystick.
+
+	  This driver can also be built as modules.  If so, the core module
+	  will be called lis3lv02d and a specific module for the I2C transport
+	  is called lis3lv02d_i2c.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
@@ -1008,6 +1070,12 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the A/D converter on MC13783 PMIC.
+
 if ACPI
 
 comment "ACPI drivers"
@@ -1025,25 +1093,27 @@ config SENSORS_ATK0110
 	  will be called asus_atk0110.
 
 config SENSORS_LIS3LV02D
-	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
+	tristate "STMicroeletronics LIS3* three-axis digital accelerometer"
 	depends on INPUT
 	select INPUT_POLLDEV
 	select NEW_LEDS
 	select LEDS_CLASS
 	default n
 	help
-	  This driver provides support for the LIS3LV02Dx accelerometer. In
-	  particular, it can be found in a number of HP laptops, which have the
-	  "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
-	  systems the driver should load automatically (via ACPI). The
-	  accelerometer might also be found in other systems, connected via SPI
-	  or I2C.  The accelerometer data is readable via
-	  /sys/devices/platform/lis3lv02d.
+	  This driver provides support for the LIS3* accelerometers, such as the
+	  LIS3LV02DL or the LIS331DL. In particular, it can be found in a number
+	  of HP laptops, which have the "Mobile Data Protection System 3D" or
+	  "3D DriveGuard" feature. On such systems the driver should load
+	  automatically (via ACPI alias). The accelerometer might also be found
+	  in other systems, connected via SPI or I2C. The accelerometer data is
+	  readable via /sys/devices/platform/lis3lv02d.
 
 	  This driver also provides an absolute input class device, allowing
-	  the laptop to act as a pinball machine-esque joystick. On HP laptops,
+	  a laptop to act as a pinball machine-esque joystick. It provides also
+	  a misc device which can be used to detect free-fall. On HP laptops,
 	  if the led infrastructure is activated, support for a led indicating
-	  disk protection will be provided as hp:red:hddprotection.
+	  disk protection will be provided as hp::hddprotect. For more
+	  information on the feature, refer to Documentation/hwmon/lis3lv02d.
 
 	  This driver can also be built as modules.  If so, the core module
 	  will be called lis3lv02d and a specific module for HP laptops will be
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d.c linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,13 +43,30 @@
 #define MDPS_POLL_INTERVAL 50
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
- * because their are generated even if the data do not change. So it's better
+ * because they are generated even if the data do not change. So it's better
  * to keep the interrupt for the free-fall event. The values are updated at
  * 40Hz (at the lowest frequency), but as it can be pretty time consuming on
  * some low processor, we poll the sensor only at 20Hz... enough for the
  * joystick.
  */
 
+#define LIS3_PWRON_DELAY_WAI_12B	(5000)
+#define LIS3_PWRON_DELAY_WAI_8B		(3000)
+
+/*
+ * LIS3LV02D spec says 1024 LSBs corresponds 1 G -> 1LSB is 1000/1024 mG
+ * LIS302D spec says: 18 mG / digit
+ * LIS3_ACCURACY is used to increase accuracy of the intermediate
+ * calculation results.
+ */
+#define LIS3_ACCURACY			1024
+/* Sensitivity values for -2G +2G scale */
+#define LIS3_SENSITIVITY_12B		((LIS3_ACCURACY * 1000) / 1024)
+#define LIS3_SENSITIVITY_8B		(18 * LIS3_ACCURACY)
+
+#define LIS3_DEFAULT_FUZZ		3
+#define LIS3_DEFAULT_FLAT		3
+
 struct lis3lv02d lis3_dev = {
 	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
 };
@@ -65,7 +82,7 @@ static s16 lis3lv02d_read_8(struct lis3l
 	return lo;
 }
 
-static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+static s16 lis3lv02d_read_12(struct lis3lv02d *lis3, int reg)
 {
 	u8 lo, hi;
 
@@ -102,16 +119,106 @@ static inline int lis3lv02d_get_axis(s8
 static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 {
 	int position[3];
+	int i;
 
+	mutex_lock(&lis3->mutex);
 	position[0] = lis3->read_data(lis3, OUTX);
 	position[1] = lis3->read_data(lis3, OUTY);
 	position[2] = lis3->read_data(lis3, OUTZ);
+	mutex_unlock(&lis3->mutex);
+
+	for (i = 0; i < 3; i++)
+		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
 
 	*x = lis3lv02d_get_axis(lis3->ac.x, position);
 	*y = lis3lv02d_get_axis(lis3->ac.y, position);
 	*z = lis3lv02d_get_axis(lis3->ac.z, position);
 }
 
+/* conversion btw sampling rate and the register values */
+static int lis3_12_rates[4] = {40, 160, 640, 2560};
+static int lis3_8_rates[2] = {100, 400};
+
+/* ODR is Output Data Rate */
+static int lis3lv02d_get_odr(void)
+{
+	u8 ctrl;
+	int shift;
+
+	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+	ctrl &= lis3_dev.odr_mask;
+	shift = ffs(lis3_dev.odr_mask) - 1;
+	return lis3_dev.odrs[(ctrl >> shift)];
+}
+
+static int lis3lv02d_set_odr(int rate)
+{
+	u8 ctrl;
+	int i, len, shift;
+
+	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+	ctrl &= ~lis3_dev.odr_mask;
+	len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
+	shift = ffs(lis3_dev.odr_mask) - 1;
+
+	for (i = 0; i < len; i++)
+		if (lis3_dev.odrs[i] == rate) {
+			lis3_dev.write(&lis3_dev, CTRL_REG1,
+					ctrl | (i << shift));
+			return 0;
+		}
+	return -EINVAL;
+}
+
+static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
+{
+	u8 reg;
+	s16 x, y, z;
+	u8 selftest;
+	int ret;
+
+	mutex_lock(&lis3->mutex);
+	if (lis3_dev.whoami == WAI_12B)
+		selftest = CTRL1_ST;
+	else
+		selftest = CTRL1_STP;
+
+	lis3->read(lis3, CTRL_REG1, &reg);
+	lis3->write(lis3, CTRL_REG1, (reg | selftest));
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
+	/* Read directly to avoid axis remap */
+	x = lis3->read_data(lis3, OUTX);
+	y = lis3->read_data(lis3, OUTY);
+	z = lis3->read_data(lis3, OUTZ);
+
+	/* back to normal settings */
+	lis3->write(lis3, CTRL_REG1, reg);
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
+	results[0] = x - lis3->read_data(lis3, OUTX);
+	results[1] = y - lis3->read_data(lis3, OUTY);
+	results[2] = z - lis3->read_data(lis3, OUTZ);
+
+	ret = 0;
+	if (lis3->pdata) {
+		int i;
+		for (i = 0; i < 3; i++) {
+			/* Check against selftest acceptance limits */
+			if ((results[i] < lis3->pdata->st_min_limits[i]) ||
+			    (results[i] > lis3->pdata->st_max_limits[i])) {
+				ret = -EIO;
+				goto fail;
+			}
+		}
+	}
+
+	/* test passed */
+fail:
+	mutex_unlock(&lis3->mutex);
+	return ret;
+}
+
 void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
 	/* disable X,Y,Z axis and power down */
@@ -125,14 +232,19 @@ void lis3lv02d_poweron(struct lis3lv02d
 
 	lis3->init(lis3);
 
+	/* LIS3 power on delay is quite long */
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
 	/*
 	 * Common configuration
-	 * BDU: LSB and MSB values are not updated until both have been read.
-	 *      So the value read will always be correct.
+	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
+	 *      both have been read. So the value read will always be correct.
 	 */
-	lis3->read(lis3, CTRL_REG2, &reg);
-	reg |= CTRL2_BDU;
-	lis3->write(lis3, CTRL_REG2, reg);
+	if (lis3->whoami ==  WAI_12B) {
+		lis3->read(lis3, CTRL_REG2, &reg);
+		reg |= CTRL2_BDU;
+		lis3->write(lis3, CTRL_REG2, reg);
+	}
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -273,22 +385,17 @@ static void lis3lv02d_joystick_poll(stru
 	int x, y, z;
 
 	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
-	input_report_abs(pidev->input, ABS_X, x - lis3_dev.xcalib);
-	input_report_abs(pidev->input, ABS_Y, y - lis3_dev.ycalib);
-	input_report_abs(pidev->input, ABS_Z, z - lis3_dev.zcalib);
-}
-
-
-static inline void lis3lv02d_calibrate_joystick(void)
-{
-	lis3lv02d_get_xyz(&lis3_dev,
-		&lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib);
+	input_report_abs(pidev->input, ABS_X, x);
+	input_report_abs(pidev->input, ABS_Y, y);
+	input_report_abs(pidev->input, ABS_Z, z);
+	input_sync(pidev->input);
 }
 
 int lis3lv02d_joystick_enable(void)
 {
 	struct input_dev *input_dev;
 	int err;
+	int max_val, fuzz, flat;
 
 	if (lis3_dev.idev)
 		return -EINVAL;
@@ -301,8 +408,6 @@ int lis3lv02d_joystick_enable(void)
 	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
 	input_dev = lis3_dev.idev->input;
 
-	lis3lv02d_calibrate_joystick();
-
 	input_dev->name       = "ST LIS3LV02DL Accelerometer";
 	input_dev->phys       = DRIVER_NAME "/input0";
 	input_dev->id.bustype = BUS_HOST;
@@ -310,9 +415,12 @@ int lis3lv02d_joystick_enable(void)
 	input_dev->dev.parent = &lis3_dev.pdev->dev;
 
 	set_bit(EV_ABS, input_dev->evbit);
-	input_set_abs_params(input_dev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
-	input_set_abs_params(input_dev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
-	input_set_abs_params(input_dev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
+	fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
+	flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
+	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
+	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
+	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
 
 	err = input_register_polled_device(lis3_dev.idev);
 	if (err) {
@@ -332,11 +440,23 @@ void lis3lv02d_joystick_disable(void)
 	if (lis3_dev.irq)
 		misc_deregister(&lis3lv02d_misc_device);
 	input_unregister_polled_device(lis3_dev.idev);
+	input_free_polled_device(lis3_dev.idev);
 	lis3_dev.idev = NULL;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
 /* Sysfs stuff */
+static ssize_t lis3lv02d_selftest_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	int result;
+	s16 values[3];
+
+	result = lis3lv02d_selftest(&lis3_dev, values);
+	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
+		values[0], values[1], values[2]);
+}
+
 static ssize_t lis3lv02d_position_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -346,41 +466,35 @@ static ssize_t lis3lv02d_position_show(s
 	return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
 }
 
-static ssize_t lis3lv02d_calibrate_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static ssize_t lis3lv02d_rate_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib);
+	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
 }
 
-static ssize_t lis3lv02d_calibrate_store(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+static ssize_t lis3lv02d_rate_set(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
 {
-	lis3lv02d_calibrate_joystick();
-	return count;
-}
+	unsigned long rate;
 
-/* conversion btw sampling rate and the register values */
-static int lis3lv02dl_df_val[4] = {40, 160, 640, 2560};
-static ssize_t lis3lv02d_rate_show(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	u8 ctrl;
-	int val;
+	if (strict_strtoul(buf, 0, &rate))
+		return -EINVAL;
 
-	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
-	val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
-	return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
+	if (lis3lv02d_set_odr(rate))
+		return -EINVAL;
+
+	return count;
 }
 
+static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL);
 static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
-static DEVICE_ATTR(calibrate, S_IRUGO|S_IWUSR, lis3lv02d_calibrate_show,
-	lis3lv02d_calibrate_store);
-static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL);
+static DEVICE_ATTR(rate, S_IRUGO | S_IWUSR, lis3lv02d_rate_show,
+					    lis3lv02d_rate_set);
 
 static struct attribute *lis3lv02d_attributes[] = {
+	&dev_attr_selftest.attr,
 	&dev_attr_position.attr,
-	&dev_attr_calibrate.attr,
 	&dev_attr_rate.attr,
 	NULL
 };
@@ -409,22 +523,30 @@ EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
 
 /*
  * Initialise the accelerometer and the various subsystems.
- * Should be rather independant of the bus system.
+ * Should be rather independent of the bus system.
  */
 int lis3lv02d_init_device(struct lis3lv02d *dev)
 {
 	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
 
 	switch (dev->whoami) {
-	case LIS_DOUBLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
-		dev->read_data = lis3lv02d_read_16;
+	case WAI_12B:
+		printk(KERN_INFO DRIVER_NAME ": 12 bits sensor found\n");
+		dev->read_data = lis3lv02d_read_12;
 		dev->mdps_max_val = 2048;
+		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
+		dev->odrs = lis3_12_rates;
+		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
+		dev->scale = LIS3_SENSITIVITY_12B;
 		break;
-	case LIS_SINGLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+	case WAI_8B:
+		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
 		dev->read_data = lis3lv02d_read_8;
 		dev->mdps_max_val = 128;
+		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
+		dev->odrs = lis3_8_rates;
+		dev->odr_mask = CTRL1_DR;
+		dev->scale = LIS3_SENSITIVITY_8B;
 		break;
 	default:
 		printk(KERN_ERR DRIVER_NAME
@@ -432,6 +554,8 @@ int lis3lv02d_init_device(struct lis3lv0
 		return -EINVAL;
 	}
 
+	mutex_init(&dev->mutex);
+
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
 
@@ -443,7 +567,7 @@ int lis3lv02d_init_device(struct lis3lv0
 	if (dev->pdata) {
 		struct lis3lv02d_platform_data *p = dev->pdata;
 
-		if (p->click_flags && (dev->whoami == LIS_SINGLE_ID)) {
+		if (p->click_flags && (dev->whoami == WAI_8B)) {
 			dev->write(dev, CLICK_CFG, p->click_flags);
 			dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit);
 			dev->write(dev, CLICK_LATENCY, p->click_latency);
@@ -454,7 +578,7 @@ int lis3lv02d_init_device(struct lis3lv0
 					(p->click_thresh_y << 4));
 		}
 
-		if (p->wakeup_flags && (dev->whoami == LIS_SINGLE_ID)) {
+		if (p->wakeup_flags && (dev->whoami == WAI_8B)) {
 			dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
 			dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
 			/* default to 2.5ms for now */
@@ -484,4 +608,3 @@ EXPORT_SYMBOL_GPL(lis3lv02d_init_device)
 MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
 MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
 MODULE_LICENSE("GPL");
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d.h linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d.h
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  *  lis3lv02d.h - ST LIS3LV02DL accelerometer driver
  *
  *  Copyright (C) 2007-2008 Yan Burman
- *  Copyright (C) 2008 Eric Piel
+ *  Copyright (C) 2008-2009 Eric Piel
  *
  *  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
@@ -22,20 +22,18 @@
 #include <linux/input-polldev.h>
 
 /*
- * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
- * be connected via SPI. There exists also several similar chips (such as LIS302DL or
- * LIS3L02DQ) and they have slightly different registers, but we can provide a
- * common interface for all of them.
- * They can also be connected via I²C.
+ * This driver tries to support the "digital" accelerometer chips from
+ * STMicroelectronics such as LIS3LV02DL, LIS302DL, LIS3L02DQ, LIS331DL,
+ * LIS35DE, or LIS202DL. They are very similar in terms of programming, with
+ * almost the same registers. In addition to differing on physical properties,
+ * they differ on the number of axes (2/3), precision (8/12 bits), and special
+ * features (freefall detection, click...). Unfortunately, not all the
+ * differences can be probed via a register.
+ * They can be connected either via I²C or SPI.
  */
 
 #include <linux/lis3lv02d.h>
 
-/* 2-byte registers */
-#define LIS_DOUBLE_ID	0x3A /* LIS3LV02D[LQ] */
-/* 1-byte registers */
-#define LIS_SINGLE_ID	0x3B /* LIS[32]02DL and others */
-
 enum lis3_reg {
 	WHO_AM_I	= 0x0F,
 	OFFSET_X	= 0x16,
@@ -94,7 +92,13 @@ enum lis3lv02d_reg {
 	DD_THSE_H	= 0x3F,
 };
 
-enum lis3lv02d_ctrl1 {
+enum lis3_who_am_i {
+	WAI_12B		= 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
+	WAI_8B		= 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
+	WAI_6B		= 0x52, /* 6 bits: LIS331DLF - not supported */
+};
+
+enum lis3lv02d_ctrl1_12b {
 	CTRL1_Xen	= 0x01,
 	CTRL1_Yen	= 0x02,
 	CTRL1_Zen	= 0x04,
@@ -104,6 +108,16 @@ enum lis3lv02d_ctrl1 {
 	CTRL1_PD0	= 0x40,
 	CTRL1_PD1	= 0x80,
 };
+
+/* Delta to ctrl1_12b version */
+enum lis3lv02d_ctrl1_8b {
+	CTRL1_STM	= 0x08,
+	CTRL1_STP	= 0x10,
+	CTRL1_FS	= 0x20,
+	CTRL1_PD	= 0x40,
+	CTRL1_DR	= 0x80,
+};
+
 enum lis3lv02d_ctrl2 {
 	CTRL2_DAS	= 0x01,
 	CTRL2_SIM	= 0x02,
@@ -194,16 +208,20 @@ struct lis3lv02d {
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
 
-	u8			whoami;    /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
+	int                     *odrs;     /* Supported output data rates */
+	u8                      odr_mask;  /* ODR bit mask */
+	u8			whoami;    /* indicates measurement precision */
 	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
 	int			mdps_max_val;
+	int			pwron_delay;
+	int                     scale; /*
+					* relationship between 1 LBS and mG
+					* (1/1000th of earth gravity)
+					*/
 
 	struct input_polled_dev	*idev;     /* input device */
 	struct platform_device	*pdev;     /* platform device */
 	atomic_t		count;     /* interrupt count after last read */
-	int			xcalib;    /* calibrated null value for x */
-	int			ycalib;    /* calibrated null value for y */
-	int			zcalib;    /* calibrated null value for z */
 	struct axis_conversion	ac;        /* hw -> logical axis */
 
 	u32			irq;       /* IRQ number */
@@ -212,6 +230,7 @@ struct lis3lv02d {
 	unsigned long		misc_opened; /* bit0: whether the device is open */
 
 	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
+	struct mutex		mutex;     /* Serialize poll and selftest */
 };
 
 int lis3lv02d_init_device(struct lis3lv02d *lis3);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d_i2c.c linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lis3lv02d_i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lis3lv02d_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,183 @@
+/*
+ * drivers/hwmon/lis3lv02d_i2c.c
+ *
+ * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer.
+ * Driver is based on corresponding SPI driver written by Daniel Mack
+ * (lis3lv02d_spi.c (C) 2009 Daniel Mack <daniel@caiaq.de> ).
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include "lis3lv02d.h"
+
+#define DRV_NAME 	"lis3lv02d_i2c"
+
+static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
+{
+	struct i2c_client *c = lis3->bus_priv;
+	return i2c_smbus_write_byte_data(c, reg, value);
+}
+
+static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
+{
+	struct i2c_client *c = lis3->bus_priv;
+	*v = i2c_smbus_read_byte_data(c, reg);
+	return 0;
+}
+
+static int lis3_i2c_init(struct lis3lv02d *lis3)
+{
+	u8 reg;
+	int ret;
+
+	/* power up the device */
+	ret = lis3->read(lis3, CTRL_REG1, &reg);
+	if (ret < 0)
+		return ret;
+
+	reg |= CTRL1_PD0;
+	return lis3->write(lis3, CTRL_REG1, reg);
+}
+
+/* Default axis mapping but it can be overwritten by platform data */
+static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X,
+						     LIS3_DEV_Y,
+						     LIS3_DEV_Z };
+
+static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
+
+	if (pdata) {
+		if (pdata->axis_x)
+			lis3lv02d_axis_map.x = pdata->axis_x;
+
+		if (pdata->axis_y)
+			lis3lv02d_axis_map.y = pdata->axis_y;
+
+		if (pdata->axis_z)
+			lis3lv02d_axis_map.z = pdata->axis_z;
+
+		if (pdata->setup_resources)
+			ret = pdata->setup_resources();
+
+		if (ret)
+			goto fail;
+	}
+
+	lis3_dev.pdata	  = pdata;
+	lis3_dev.bus_priv = client;
+	lis3_dev.init	  = lis3_i2c_init;
+	lis3_dev.read	  = lis3_i2c_read;
+	lis3_dev.write	  = lis3_i2c_write;
+	lis3_dev.irq	  = client->irq;
+	lis3_dev.ac	  = lis3lv02d_axis_map;
+
+	i2c_set_clientdata(client, &lis3_dev);
+	ret = lis3lv02d_init_device(&lis3_dev);
+fail:
+	return ret;
+}
+
+static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
+{
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
+
+	if (pdata && pdata->release_resources)
+		pdata->release_resources();
+
+	lis3lv02d_joystick_disable();
+	lis3lv02d_poweroff(lis3);
+
+	return lis3lv02d_remove_fs(&lis3_dev);
+}
+
+#ifdef CONFIG_PM
+static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	if (!lis3->pdata->wakeup_flags)
+		lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static int lis3lv02d_i2c_resume(struct i2c_client *client)
+{
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	if (!lis3->pdata->wakeup_flags)
+		lis3lv02d_poweron(lis3);
+	return 0;
+}
+
+static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
+{
+	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
+}
+#else
+#define lis3lv02d_i2c_suspend	NULL
+#define lis3lv02d_i2c_resume	NULL
+#define lis3lv02d_i2c_shutdown	NULL
+#endif
+
+static const struct i2c_device_id lis3lv02d_id[] = {
+	{"lis3lv02d", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
+
+static struct i2c_driver lis3lv02d_i2c_driver = {
+	.driver	 = {
+		.name   = DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+	.suspend = lis3lv02d_i2c_suspend,
+	.shutdown = lis3lv02d_i2c_shutdown,
+	.resume = lis3lv02d_i2c_resume,
+	.probe	= lis3lv02d_i2c_probe,
+	.remove	= __devexit_p(lis3lv02d_i2c_remove),
+	.id_table = lis3lv02d_id,
+};
+
+static int __init lis3lv02d_init(void)
+{
+	return i2c_add_driver(&lis3lv02d_i2c_driver);
+}
+
+static void __exit lis3lv02d_exit(void)
+{
+	i2c_del_driver(&lis3lv02d_i2c_driver);
+}
+
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_DESCRIPTION("lis3lv02d I2C interface");
+MODULE_LICENSE("GPL");
+
+module_init(lis3lv02d_init);
+module_exit(lis3lv02d_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm63.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm63.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm63.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm63.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,12 +56,6 @@
 static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
 
 /*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_1(lm63);
-
-/*
  * The LM63 registers
  */
 
@@ -134,8 +128,7 @@ static int lm63_remove(struct i2c_client
 
 static struct lm63_data *lm63_update_device(struct device *dev);
 
-static int lm63_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info);
+static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void lm63_init_client(struct i2c_client *client);
 
 /*
@@ -143,7 +136,7 @@ static void lm63_init_client(struct i2c_
  */
 
 static const struct i2c_device_id lm63_id[] = {
-	{ "lm63", lm63 },
+	{ "lm63", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm63_id);
@@ -157,7 +150,7 @@ static struct i2c_driver lm63_driver = {
 	.remove		= lm63_remove,
 	.id_table	= lm63_id,
 	.detect		= lm63_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -423,44 +416,38 @@ static const struct attribute_group lm63
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm63_detect(struct i2c_client *new_client, int kind,
+static int lm63_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	u8 man_id, chip_id, reg_config1, reg_config2;
+	u8 reg_alert_status, reg_alert_mask;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind < 0) { /* must identify */
-		u8 man_id, chip_id, reg_config1, reg_config2;
-		u8 reg_alert_status, reg_alert_mask;
+	man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID);
 
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 LM63_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  LM63_REG_CHIP_ID);
-		reg_config1 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG1);
-		reg_config2 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG2);
-		reg_alert_status = i2c_smbus_read_byte_data(new_client,
-				   LM63_REG_ALERT_STATUS);
-		reg_alert_mask = i2c_smbus_read_byte_data(new_client,
-				 LM63_REG_ALERT_MASK);
+	reg_config1 = i2c_smbus_read_byte_data(new_client,
+		      LM63_REG_CONFIG1);
+	reg_config2 = i2c_smbus_read_byte_data(new_client,
+		      LM63_REG_CONFIG2);
+	reg_alert_status = i2c_smbus_read_byte_data(new_client,
+			   LM63_REG_ALERT_STATUS);
+	reg_alert_mask = i2c_smbus_read_byte_data(new_client,
+			 LM63_REG_ALERT_MASK);
 
-		if (man_id == 0x01 /* National Semiconductor */
-		 && chip_id == 0x41 /* LM63 */
-		 && (reg_config1 & 0x18) == 0x00
-		 && (reg_config2 & 0xF8) == 0x00
-		 && (reg_alert_status & 0x20) == 0x00
-		 && (reg_alert_mask & 0xA4) == 0xA4) {
-			kind = lm63;
-		} else { /* failed */
-			dev_dbg(&adapter->dev, "Unsupported chip "
-				"(man_id=0x%02X, chip_id=0x%02X).\n",
-				man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x01 /* National Semiconductor */
+	 || chip_id != 0x41 /* LM63 */
+	 || (reg_config1 & 0x18) != 0x00
+	 || (reg_config2 & 0xF8) != 0x00
+	 || (reg_alert_status & 0x20) != 0x00
+	 || (reg_alert_mask & 0xA4) != 0xA4) {
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "lm63", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm73.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm73.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm73.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm73.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,202 @@
+/*
+ * LM73 Sensor driver
+ * Based on LM75
+ *
+ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
+ * Copyright (C) 2009, Bollore telecom (www.bolloretelecom.eu).
+ *
+ * Guillaume Ligneul <guillaume.ligneul@gmail.com>
+ * Adrien Demarez <adrien.demarez@bolloretelecom.eu>
+ * Jeremy Laine <jeremy.laine@bolloretelecom.eu>
+ *
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+
+
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
+					0x4d, 0x4e, I2C_CLIENT_END };
+
+/* LM73 registers */
+#define LM73_REG_INPUT		0x00
+#define LM73_REG_CONF		0x01
+#define LM73_REG_MAX		0x02
+#define LM73_REG_MIN		0x03
+#define LM73_REG_CTRL		0x04
+#define LM73_REG_ID		0x07
+
+#define LM73_ID			0x9001 /* or 0x190 after a swab16() */
+#define DRVNAME			"lm73"
+#define LM73_TEMP_MIN		(-40)
+#define LM73_TEMP_MAX		150
+
+/*-----------------------------------------------------------------------*/
+
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *da,
+			const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	long temp;
+	short value;
+
+	int status = strict_strtol(buf, 10, &temp);
+	if (status < 0)
+		return status;
+
+	/* Write value */
+	value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
+		(LM73_TEMP_MAX*4)) << 5;
+	i2c_smbus_write_word_data(client, attr->index, swab16(value));
+	return count;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+			 char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	/* use integer division instead of equivalent right shift to
+	   guarantee arithmetic shift and preserve the sign */
+	int temp = ((s16) (swab16(i2c_smbus_read_word_data(client,
+		attr->index)))*250) / 32;
+	return sprintf(buf, "%d\n", temp);
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+/* sysfs attributes for hwmon */
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+			show_temp, set_temp, LM73_REG_MAX);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
+			show_temp, set_temp, LM73_REG_MIN);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+			show_temp, NULL, LM73_REG_INPUT);
+
+
+static struct attribute *lm73_attributes[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+
+	NULL
+};
+
+static const struct attribute_group lm73_group = {
+	.attrs = lm73_attributes,
+};
+
+/*-----------------------------------------------------------------------*/
+
+/* device probe and removal */
+
+static int
+lm73_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct device *hwmon_dev;
+	int status;
+
+	/* Register sysfs hooks */
+	status = sysfs_create_group(&client->dev.kobj, &lm73_group);
+	if (status)
+		return status;
+
+	hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(hwmon_dev)) {
+		status = PTR_ERR(hwmon_dev);
+		goto exit_remove;
+	}
+	i2c_set_clientdata(client, hwmon_dev);
+
+	dev_info(&client->dev, "%s: sensor '%s'\n",
+		 dev_name(hwmon_dev), client->name);
+
+	return 0;
+
+exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &lm73_group);
+	return status;
+}
+
+static int lm73_remove(struct i2c_client *client)
+{
+	struct device *hwmon_dev = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &lm73_group);
+	i2c_set_clientdata(client, NULL);
+	return 0;
+}
+
+static const struct i2c_device_id lm73_ids[] = {
+	{ "lm73", 0 },
+	{ /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, lm73_ids);
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm73_detect(struct i2c_client *new_client,
+			struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = new_client->adapter;
+	u16 id;
+	u8 ctrl;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+					I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	/* Check device ID */
+	id = i2c_smbus_read_word_data(new_client, LM73_REG_ID);
+	ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
+	if ((id != LM73_ID) || (ctrl & 0x10))
+		return -ENODEV;
+
+	strlcpy(info->type, "lm73", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static struct i2c_driver lm73_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "lm73",
+	},
+	.probe		= lm73_probe,
+	.remove		= lm73_remove,
+	.id_table	= lm73_ids,
+	.detect		= lm73_detect,
+	.address_list	= normal_i2c,
+};
+
+/* module glue */
+
+static int __init sensors_lm73_init(void)
+{
+	return i2c_add_driver(&lm73_driver);
+}
+
+static void __exit sensors_lm73_exit(void)
+{
+	i2c_del_driver(&lm73_driver);
+}
+
+MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>");
+MODULE_DESCRIPTION("LM73 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm73_init);
+module_exit(sensors_lm73_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm75.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm75.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm75.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm75.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,15 +32,12 @@
 
 /*
  * This driver handles the LM75 and compatible digital temperature sensors.
- * Only types which are _not_ listed in I2C_CLIENT_INSMOD_*() need to be
- * listed here.  We start at 9 since I2C_CLIENT_INSMOD_*() currently allow
- * definition of up to 8 chip types (plus zero).
  */
 
 enum lm75_type {		/* keep sorted in alphabetical order */
-	ds1775 = 9,
+	ds1775,
 	ds75,
-	/* lm75 -- in I2C_CLIENT_INSMOD_1() */
+	lm75,
 	lm75a,
 	max6625,
 	max6626,
@@ -58,9 +55,6 @@ enum lm75_type {		/* keep sorted in alph
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm75);
-
 
 /* The LM75 registers */
 #define LM75_REG_CONF		0x01
@@ -234,11 +228,12 @@ static const struct i2c_device_id lm75_i
 MODULE_DEVICE_TABLE(i2c, lm75_ids);
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm75_detect(struct i2c_client *new_client, int kind,
+static int lm75_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int i;
+	int cur, conf, hyst, os;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -251,40 +246,35 @@ static int lm75_detect(struct i2c_client
 	   The cycling+unused addresses combination is not tested,
 	   since it would significantly slow the detection down and would
 	   hardly add any value. */
-	if (kind < 0) {
-		int cur, conf, hyst, os;
 
-		/* Unused addresses */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 4) != hyst
-		 || i2c_smbus_read_word_data(new_client, 5) != hyst
-		 || i2c_smbus_read_word_data(new_client, 6) != hyst
-		 || i2c_smbus_read_word_data(new_client, 7) != hyst)
-			return -ENODEV;
-		os = i2c_smbus_read_word_data(new_client, 3);
-		if (i2c_smbus_read_word_data(new_client, 4) != os
-		 || i2c_smbus_read_word_data(new_client, 5) != os
-		 || i2c_smbus_read_word_data(new_client, 6) != os
-		 || i2c_smbus_read_word_data(new_client, 7) != os)
-			return -ENODEV;
+	/* Unused addresses */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	conf = i2c_smbus_read_byte_data(new_client, 1);
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	if (i2c_smbus_read_word_data(new_client, 4) != hyst
+	 || i2c_smbus_read_word_data(new_client, 5) != hyst
+	 || i2c_smbus_read_word_data(new_client, 6) != hyst
+	 || i2c_smbus_read_word_data(new_client, 7) != hyst)
+		return -ENODEV;
+	os = i2c_smbus_read_word_data(new_client, 3);
+	if (i2c_smbus_read_word_data(new_client, 4) != os
+	 || i2c_smbus_read_word_data(new_client, 5) != os
+	 || i2c_smbus_read_word_data(new_client, 6) != os
+	 || i2c_smbus_read_word_data(new_client, 7) != os)
+		return -ENODEV;
 
-		/* Unused bits */
-		if (conf & 0xe0)
-			return -ENODEV;
+	/* Unused bits */
+	if (conf & 0xe0)
+		return -ENODEV;
 
-		/* Addresses cycling */
-		for (i = 8; i < 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			 || i2c_smbus_read_word_data(new_client, i + 3) != os)
-				return -ENODEV;
+	/* Addresses cycling */
+	for (i = 8; i < 0xff; i += 8) {
+		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+		 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+		 || i2c_smbus_read_word_data(new_client, i + 3) != os)
+			return -ENODEV;
 	}
 
-	/* NOTE: we treat "force=..." and "force_lm75=..." the same.
-	 * Only new-style driver binding distinguishes chip types.
-	 */
 	strlcpy(info->type, "lm75", I2C_NAME_SIZE);
 
 	return 0;
@@ -299,7 +289,7 @@ static struct i2c_driver lm75_driver = {
 	.remove		= lm75_remove,
 	.id_table	= lm75_ids,
 	.detect		= lm75_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*-----------------------------------------------------------------------*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm77.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm77.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm77.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm77.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,9 +39,6 @@
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 						I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm77);
-
 /* The LM77 registers */
 #define LM77_REG_TEMP		0x00
 #define LM77_REG_CONF		0x01
@@ -66,8 +63,7 @@ struct lm77_data {
 
 static int lm77_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
-static int lm77_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info);
+static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void lm77_init_client(struct i2c_client *client);
 static int lm77_remove(struct i2c_client *client);
 static u16 lm77_read_value(struct i2c_client *client, u8 reg);
@@ -77,7 +73,7 @@ static struct lm77_data *lm77_update_dev
 
 
 static const struct i2c_device_id lm77_id[] = {
-	{ "lm77", lm77 },
+	{ "lm77", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm77_id);
@@ -92,7 +88,7 @@ static struct i2c_driver lm77_driver = {
 	.remove		= lm77_remove,
 	.id_table	= lm77_id,
 	.detect		= lm77_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* straight from the datasheet */
@@ -245,10 +241,11 @@ static const struct attribute_group lm77
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm77_detect(struct i2c_client *new_client, int kind,
+static int lm77_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	int i, cur, conf, hyst, crit, min, max;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_WORD_DATA))
@@ -265,51 +262,48 @@ static int lm77_detect(struct i2c_client
 	   4. registers cycling over 8-address boundaries
 
 	   Word-sized registers are high-byte first. */
-	if (kind < 0) {
-		int i, cur, conf, hyst, crit, min, max;
 
-		/* addresses cycling */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		crit = i2c_smbus_read_word_data(new_client, 3);
-		min = i2c_smbus_read_word_data(new_client, 4);
-		max = i2c_smbus_read_word_data(new_client, 5);
-		for (i = 8; i <= 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			    || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			    || i2c_smbus_read_word_data(new_client, i + 3) != crit
-			    || i2c_smbus_read_word_data(new_client, i + 4) != min
-			    || i2c_smbus_read_word_data(new_client, i + 5) != max)
-				return -ENODEV;
-
-		/* sign bits */
-		if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
-		    || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
-		    || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
-		    || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
-		    || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
+	/* addresses cycling */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	conf = i2c_smbus_read_byte_data(new_client, 1);
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	crit = i2c_smbus_read_word_data(new_client, 3);
+	min = i2c_smbus_read_word_data(new_client, 4);
+	max = i2c_smbus_read_word_data(new_client, 5);
+	for (i = 8; i <= 0xff; i += 8) {
+		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+		 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+		 || i2c_smbus_read_word_data(new_client, i + 3) != crit
+		 || i2c_smbus_read_word_data(new_client, i + 4) != min
+		 || i2c_smbus_read_word_data(new_client, i + 5) != max)
 			return -ENODEV;
+	}
 
-		/* unused bits */
-		if (conf & 0xe0)
-			return -ENODEV;
+	/* sign bits */
+	if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
+	 || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
+	 || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
+	 || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
+	 || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
+		return -ENODEV;
 
-		/* 0x06 and 0x07 return the last read value */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		if (i2c_smbus_read_word_data(new_client, 6) != cur
-		    || i2c_smbus_read_word_data(new_client, 7) != cur)
-			return -ENODEV;
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 6) != hyst
-		    || i2c_smbus_read_word_data(new_client, 7) != hyst)
-			return -ENODEV;
-		min = i2c_smbus_read_word_data(new_client, 4);
-		if (i2c_smbus_read_word_data(new_client, 6) != min
-		    || i2c_smbus_read_word_data(new_client, 7) != min)
-			return -ENODEV;
+	/* unused bits */
+	if (conf & 0xe0)
+		return -ENODEV;
 
-	}
+	/* 0x06 and 0x07 return the last read value */
+	cur = i2c_smbus_read_word_data(new_client, 0);
+	if (i2c_smbus_read_word_data(new_client, 6) != cur
+	 || i2c_smbus_read_word_data(new_client, 7) != cur)
+		return -ENODEV;
+	hyst = i2c_smbus_read_word_data(new_client, 2);
+	if (i2c_smbus_read_word_data(new_client, 6) != hyst
+	 || i2c_smbus_read_word_data(new_client, 7) != hyst)
+		return -ENODEV;
+	min = i2c_smbus_read_word_data(new_client, 4);
+	if (i2c_smbus_read_word_data(new_client, 6) != min
+	 || i2c_smbus_read_word_data(new_client, 7) != min)
+		return -ENODEV;
 
 	strlcpy(info->type, "lm77", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm78.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm78.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm78.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm78.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,8 +41,7 @@ static const unsigned short normal_i2c[]
 						0x2e, 0x2f, I2C_CLIENT_END };
 static unsigned short isa_address = 0x290;
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(lm78, lm79);
+enum chips { lm78, lm79 };
 
 /* Many LM78 constants specified below */
 
@@ -142,7 +141,7 @@ struct lm78_data {
 };
 
 
-static int lm78_i2c_detect(struct i2c_client *client, int kind,
+static int lm78_i2c_detect(struct i2c_client *client,
 			   struct i2c_board_info *info);
 static int lm78_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id);
@@ -173,7 +172,7 @@ static struct i2c_driver lm78_driver = {
 	.remove		= lm78_i2c_remove,
 	.id_table	= lm78_i2c_id,
 	.detect		= lm78_i2c_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static struct platform_driver lm78_isa_driver = {
@@ -558,7 +557,7 @@ static int lm78_alias_detect(struct i2c_
 	return 1;
 }
 
-static int lm78_i2c_detect(struct i2c_client *client, int kind,
+static int lm78_i2c_detect(struct i2c_client *client,
 			   struct i2c_board_info *info)
 {
 	int i;
@@ -576,52 +575,34 @@ static int lm78_i2c_detect(struct i2c_cl
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
-	if (kind < 0) {
-		if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
-		 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR)
-		    != address)
-			goto err_nodev;
+	if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
+	 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address)
+		goto err_nodev;
 
-		/* Explicitly prevent the misdetection of Winbond chips */
-		i = i2c_smbus_read_byte_data(client, 0x4f);
-		if (i == 0xa3 || i == 0x5c)
-			goto err_nodev;
-	}
+	/* Explicitly prevent the misdetection of Winbond chips */
+	i = i2c_smbus_read_byte_data(client, 0x4f);
+	if (i == 0xa3 || i == 0x5c)
+		goto err_nodev;
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
-		if (i == 0x00 || i == 0x20	/* LM78 */
-		 || i == 0x40)			/* LM78-J */
-			kind = lm78;
-		else if ((i & 0xfe) == 0xc0)
-			kind = lm79;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "Ignoring 'force' "
-					"parameter for unknown chip at "
-					"adapter %d, address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			goto err_nodev;
-		}
+	i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
+	if (i == 0x00 || i == 0x20	/* LM78 */
+	 || i == 0x40)			/* LM78-J */
+		client_name = "lm78";
+	else if ((i & 0xfe) == 0xc0)
+		client_name = "lm79";
+	else
+		goto err_nodev;
 
-		if (lm78_alias_detect(client, i)) {
-			dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
-				"be the same as ISA device\n", address);
-			goto err_nodev;
-		}
+	if (lm78_alias_detect(client, i)) {
+		dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+			"be the same as ISA device\n", address);
+		goto err_nodev;
 	}
 
 	if (isa)
 		mutex_unlock(&isa->update_lock);
 
-	switch (kind) {
-	case lm79:
-		client_name = "lm79";
-		break;
-	default:
-		client_name = "lm78";
-	}
 	strlcpy(info->type, client_name, I2C_NAME_SIZE);
 
 	return 0;
@@ -870,17 +851,16 @@ static struct lm78_data *lm78_update_dev
 static int __init lm78_isa_found(unsigned short address)
 {
 	int val, save, found = 0;
+	int port;
 
-	/* We have to request the region in two parts because some
-	   boards declare base+4 to base+7 as a PNP device */
-	if (!request_region(address, 4, "lm78")) {
-		pr_debug("lm78: Failed to request low part of region\n");
-		return 0;
-	}
-	if (!request_region(address + 4, 4, "lm78")) {
-		pr_debug("lm78: Failed to request high part of region\n");
-		release_region(address, 4);
-		return 0;
+	/* Some boards declare base+0 to base+7 as a PNP device, some base+4
+	 * to base+7 and some base+5 to base+6. So we better request each port
+	 * individually for the probing phase. */
+	for (port = address; port < address + LM78_EXTENT; port++) {
+		if (!request_region(port, 1, "lm78")) {
+			pr_debug("lm78: Failed to request port 0x%x\n", port);
+			goto release;
+		}
 	}
 
 #define REALLY_SLOW_IO
@@ -944,8 +924,8 @@ static int __init lm78_isa_found(unsigne
 			val & 0x80 ? "LM79" : "LM78", (int)address);
 
  release:
-	release_region(address + 4, 4);
-	release_region(address, 4);
+	for (port--; port >= address; port--)
+		release_region(port, 1);
 	return found;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm80.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm80.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm80.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm80.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,9 +35,6 @@
 static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
 						0x2e, 0x2f, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm80);
-
 /* Many LM80 constants specified below */
 
 /* The LM80 registers */
@@ -133,8 +130,7 @@ struct lm80_data {
 
 static int lm80_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
-static int lm80_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info);
+static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void lm80_init_client(struct i2c_client *client);
 static int lm80_remove(struct i2c_client *client);
 static struct lm80_data *lm80_update_device(struct device *dev);
@@ -146,7 +142,7 @@ static int lm80_write_value(struct i2c_c
  */
 
 static const struct i2c_device_id lm80_id[] = {
-	{ "lm80", lm80 },
+	{ "lm80", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm80_id);
@@ -160,7 +156,7 @@ static struct i2c_driver lm80_driver = {
 	.remove		= lm80_remove,
 	.id_table	= lm80_id,
 	.detect		= lm80_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -447,8 +443,7 @@ static const struct attribute_group lm80
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm80_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info)
+static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	int i, cur;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm83.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm83.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm83.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm83.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
  * a sensor chip made by National Semiconductor. It reports up to four
@@ -51,11 +51,7 @@
 static const unsigned short normal_i2c[] = {
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
-/*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_2(lm83, lm82);
+enum chips { lm83, lm82 };
 
 /*
  * The LM83 registers
@@ -118,7 +114,7 @@ static const u8 LM83_REG_W_HIGH[] = {
  * Functions declaration
  */
 
-static int lm83_detect(struct i2c_client *new_client, int kind,
+static int lm83_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info);
 static int lm83_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
@@ -145,7 +141,7 @@ static struct i2c_driver lm83_driver = {
 	.remove		= lm83_remove,
 	.id_table	= lm83_id,
 	.detect		= lm83_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -291,73 +287,44 @@ static const struct attribute_group lm83
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm83_detect(struct i2c_client *new_client, int kind,
+static int lm83_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
-	const char *name = "";
+	const char *name;
+	u8 man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Now we do the detection and identification. A negative kind
-	 * means that the driver was loaded with no force parameter
-	 * (default), so we must both detect and identify the chip
-	 * (actually there is only one possible kind of chip for now, LM83).
-	 * A zero kind means that the driver was loaded with the force
-	 * parameter, the detection step shall be skipped. A positive kind
-	 * means that the driver was loaded with the force parameter and a
-	 * given kind of chip is requested, so both the detection and the
-	 * identification steps are skipped. */
-
-	/* Default to an LM83 if forced */
-	if (kind == 0)
-		kind = lm83;
-
-	if (kind < 0) { /* detection */
-		if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1)
-		    & 0xA8) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2)
-		    & 0x48) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG)
-		    & 0x41) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"LM83 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* Detection */
+	if ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1) & 0xA8) ||
+	    (i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2) & 0x48) ||
+	    (i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) & 0x41)) {
+		dev_dbg(&adapter->dev, "LM83 detection failed at 0x%02x\n",
+			new_client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-
-		man_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_CHIP_ID);
-
-		if (man_id == 0x01) { /* National Semiconductor */
-			if (chip_id == 0x03) {
-				kind = lm83;
-			} else
-			if (chip_id == 0x01) {
-				kind = lm82;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
-	}
+	/* Identification */
+	man_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_MAN_ID);
+	if (man_id != 0x01)	/* National Semiconductor */
+		return -ENODEV;
 
-	if (kind == lm83) {
+	chip_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_CHIP_ID);
+	switch (chip_id) {
+	case 0x03:
 		name = "lm83";
-	} else
-	if (kind == lm82) {
+		break;
+	case 0x01:
 		name = "lm82";
+		break;
+	default:
+		/* identification failed */
+		dev_info(&adapter->dev,
+			 "Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",
+			 man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, name, I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm85.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm85.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm85.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm85.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,7 @@
     Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
     Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
     Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
-    Copyright (C) 2007, 2008  Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2007--2009  Jean Delvare <khali@linux-fr.org>
 
     Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
 
@@ -38,9 +38,11 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
-		    emc6d102);
+enum chips {
+	any_chip, lm85b, lm85c,
+	adm1027, adt7463, adt7468,
+	emc6d100, emc6d102
+};
 
 /* The LM85 registers */
 
@@ -323,8 +325,7 @@ struct lm85_data {
 	struct lm85_zone zone[3];
 };
 
-static int lm85_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info);
+static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info);
 static int lm85_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
 static int lm85_remove(struct i2c_client *client);
@@ -357,7 +358,7 @@ static struct i2c_driver lm85_driver = {
 	.remove		= lm85_remove,
 	.id_table	= lm85_id,
 	.detect		= lm85_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 
@@ -1156,113 +1157,85 @@ static int lm85_is_fake(struct i2c_clien
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm85_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info)
+static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
 	const char *type_name;
+	int company, verstep;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		/* We need to be able to do byte I/O */
 		return -ENODEV;
 	}
 
-	/* If auto-detecting, determine the chip type */
-	if (kind < 0) {
-		int company = lm85_read_value(client, LM85_REG_COMPANY);
-		int verstep = lm85_read_value(client, LM85_REG_VERSTEP);
+	/* Determine the chip type */
+	company = lm85_read_value(client, LM85_REG_COMPANY);
+	verstep = lm85_read_value(client, LM85_REG_VERSTEP);
 
-		dev_dbg(&adapter->dev, "Detecting device at 0x%02x with "
-			"COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
-			address, company, verstep);
+	dev_dbg(&adapter->dev, "Detecting device at 0x%02x with "
+		"COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
+		address, company, verstep);
 
-		/* All supported chips have the version in common */
-		if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
-		    (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
-			dev_dbg(&adapter->dev, "Autodetection failed: "
-				"unsupported version\n");
-			return -ENODEV;
-		}
-		kind = any_chip;
+	/* All supported chips have the version in common */
+	if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
+	    (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
+		dev_dbg(&adapter->dev,
+			"Autodetection failed: unsupported version\n");
+		return -ENODEV;
+	}
+	type_name = "lm85";
 
-		/* Now, refine the detection */
-		if (company == LM85_COMPANY_NATIONAL) {
-			switch (verstep) {
-			case LM85_VERSTEP_LM85C:
-				kind = lm85c;
-				break;
-			case LM85_VERSTEP_LM85B:
-				kind = lm85b;
-				break;
-			case LM85_VERSTEP_LM96000_1:
-			case LM85_VERSTEP_LM96000_2:
-				/* Check for Winbond WPCD377I */
-				if (lm85_is_fake(client)) {
-					dev_dbg(&adapter->dev,
-						"Found Winbond WPCD377I, "
-						"ignoring\n");
-					return -ENODEV;
-				}
-				break;
-			}
-		} else if (company == LM85_COMPANY_ANALOG_DEV) {
-			switch (verstep) {
-			case LM85_VERSTEP_ADM1027:
-				kind = adm1027;
-				break;
-			case LM85_VERSTEP_ADT7463:
-			case LM85_VERSTEP_ADT7463C:
-				kind = adt7463;
-				break;
-			case LM85_VERSTEP_ADT7468_1:
-			case LM85_VERSTEP_ADT7468_2:
-				kind = adt7468;
-				break;
-			}
-		} else if (company == LM85_COMPANY_SMSC) {
-			switch (verstep) {
-			case LM85_VERSTEP_EMC6D100_A0:
-			case LM85_VERSTEP_EMC6D100_A1:
-				/* Note: we can't tell a '100 from a '101 */
-				kind = emc6d100;
-				break;
-			case LM85_VERSTEP_EMC6D102:
-				kind = emc6d102;
-				break;
+	/* Now, refine the detection */
+	if (company == LM85_COMPANY_NATIONAL) {
+		switch (verstep) {
+		case LM85_VERSTEP_LM85C:
+			type_name = "lm85c";
+			break;
+		case LM85_VERSTEP_LM85B:
+			type_name = "lm85b";
+			break;
+		case LM85_VERSTEP_LM96000_1:
+		case LM85_VERSTEP_LM96000_2:
+			/* Check for Winbond WPCD377I */
+			if (lm85_is_fake(client)) {
+				dev_dbg(&adapter->dev,
+					"Found Winbond WPCD377I, ignoring\n");
+				return -ENODEV;
 			}
-		} else {
-			dev_dbg(&adapter->dev, "Autodetection failed: "
-				"unknown vendor\n");
-			return -ENODEV;
+			break;
 		}
+	} else if (company == LM85_COMPANY_ANALOG_DEV) {
+		switch (verstep) {
+		case LM85_VERSTEP_ADM1027:
+			type_name = "adm1027";
+			break;
+		case LM85_VERSTEP_ADT7463:
+		case LM85_VERSTEP_ADT7463C:
+			type_name = "adt7463";
+			break;
+		case LM85_VERSTEP_ADT7468_1:
+		case LM85_VERSTEP_ADT7468_2:
+			type_name = "adt7468";
+			break;
+		}
+	} else if (company == LM85_COMPANY_SMSC) {
+		switch (verstep) {
+		case LM85_VERSTEP_EMC6D100_A0:
+		case LM85_VERSTEP_EMC6D100_A1:
+			/* Note: we can't tell a '100 from a '101 */
+			type_name = "emc6d100";
+			break;
+		case LM85_VERSTEP_EMC6D102:
+			type_name = "emc6d102";
+			break;
+		}
+	} else {
+		dev_dbg(&adapter->dev,
+			"Autodetection failed: unknown vendor\n");
+		return -ENODEV;
 	}
 
-	switch (kind) {
-	case lm85b:
-		type_name = "lm85b";
-		break;
-	case lm85c:
-		type_name = "lm85c";
-		break;
-	case adm1027:
-		type_name = "adm1027";
-		break;
-	case adt7463:
-		type_name = "adt7463";
-		break;
-	case adt7468:
-		type_name = "adt7468";
-		break;
-	case emc6d100:
-		type_name = "emc6d100";
-		break;
-	case emc6d102:
-		type_name = "emc6d102";
-		break;
-	default:
-		type_name = "lm85";
-	}
 	strlcpy(info->type, type_name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm87.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm87.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm87.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm87.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,11 +74,7 @@
 
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
-/*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_2(lm87, adm1024);
+enum chips { lm87, adm1024 };
 
 /*
  * The LM87 registers
@@ -158,7 +154,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A,
 
 static int lm87_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
-static int lm87_detect(struct i2c_client *new_client, int kind,
+static int lm87_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info);
 static void lm87_init_client(struct i2c_client *client);
 static int lm87_remove(struct i2c_client *client);
@@ -184,7 +180,7 @@ static struct i2c_driver lm87_driver = {
 	.remove		= lm87_remove,
 	.id_table	= lm87_id,
 	.detect		= lm87_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -662,41 +658,36 @@ static const struct attribute_group lm87
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm87_detect(struct i2c_client *new_client, int kind,
+static int lm87_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
-	static const char *names[] = { "lm87", "adm1024" };
+	const char *name;
+	u8 cid, rev;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Default to an LM87 if forced */
-	if (kind == 0)
-		kind = lm87;
+	if (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
+		return -ENODEV;
 
 	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		u8 cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID);
-		u8 rev = lm87_read_value(new_client, LM87_REG_REVISION);
-
-		if (cid == 0x02			/* National Semiconductor */
-		 && (rev >= 0x01 && rev <= 0x08))
-			kind = lm87;
-		else if (cid == 0x41		/* Analog Devices */
-		      && (rev & 0xf0) == 0x10)
-			kind = adm1024;
+	cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID);
+	rev = lm87_read_value(new_client, LM87_REG_REVISION);
 
-		if (kind < 0
-		 || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) {
-			dev_dbg(&adapter->dev,
-				"LM87 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	if (cid == 0x02			/* National Semiconductor */
+	 && (rev >= 0x01 && rev <= 0x08))
+		name = "lm87";
+	else if (cid == 0x41		/* Analog Devices */
+	      && (rev & 0xf0) == 0x10)
+		name = "adm1024";
+	else {
+		dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x\n",
+			new_client->addr);
+		return -ENODEV;
 	}
 
-	strlcpy(info->type, names[kind - 1], I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm90.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm90.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm90.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm90.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Based on the lm83 driver. The LM90 is a sensor chip made by National
  * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -93,12 +93,7 @@
 static const unsigned short normal_i2c[] = {
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
-/*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680,
-		    max6646);
+enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 };
 
 /*
  * The LM90 registers
@@ -152,8 +147,7 @@ I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99,
  * Functions declaration
  */
 
-static int lm90_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info);
+static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
 static int lm90_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id);
 static void lm90_init_client(struct i2c_client *client);
@@ -192,7 +186,7 @@ static struct i2c_driver lm90_driver = {
 	.remove		= lm90_remove,
 	.id_table	= lm90_id,
 	.detect		= lm90_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -656,159 +650,123 @@ static int lm90_read_reg(struct i2c_clie
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm90_detect(struct i2c_client *new_client, int kind,
+static int lm90_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int address = new_client->addr;
-	const char *name = "";
+	const char *name = NULL;
+	int man_id, chip_id, reg_config1, reg_convrate;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-
-	/* Default to an LM90 if forced */
-	if (kind == 0)
-		kind = lm90;
-
-	if (kind < 0) { /* detection and identification */
-		int man_id, chip_id, reg_config1, reg_convrate;
-
-		if ((man_id = i2c_smbus_read_byte_data(new_client,
+	/* detection and identification */
+	if ((man_id = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_MAN_ID)) < 0
-		 || (chip_id = i2c_smbus_read_byte_data(new_client,
+	 || (chip_id = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CHIP_ID)) < 0
-		 || (reg_config1 = i2c_smbus_read_byte_data(new_client,
+	 || (reg_config1 = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CONFIG1)) < 0
-		 || (reg_convrate = i2c_smbus_read_byte_data(new_client,
+	 || (reg_convrate = i2c_smbus_read_byte_data(new_client,
 						LM90_REG_R_CONVRATE)) < 0)
-			return -ENODEV;
-		
-		if ((address == 0x4C || address == 0x4D)
-		 && man_id == 0x01) { /* National Semiconductor */
-			int reg_config2;
+		return -ENODEV;
 
-			if ((reg_config2 = i2c_smbus_read_byte_data(new_client,
-						LM90_REG_R_CONFIG2)) < 0)
-				return -ENODEV;
+	if ((address == 0x4C || address == 0x4D)
+	 && man_id == 0x01) { /* National Semiconductor */
+		int reg_config2;
 
-			if ((reg_config1 & 0x2A) == 0x00
-			 && (reg_config2 & 0xF8) == 0x00
-			 && reg_convrate <= 0x09) {
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x20) { /* LM90 */
-					kind = lm90;
-				} else
-				if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
-					kind = lm99;
-					dev_info(&adapter->dev,
-						 "Assuming LM99 chip at "
-						 "0x%02x\n", address);
-					dev_info(&adapter->dev,
-						 "If it is an LM89, pass "
-						 "force_lm86=%d,0x%02x when "
-						 "loading the lm90 driver\n",
-						 i2c_adapter_id(adapter),
-						 address);
-				} else
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x10) { /* LM86 */
-					kind = lm86;
-				}
-			}
-		} else
-		if ((address == 0x4C || address == 0x4D)
-		 && man_id == 0x41) { /* Analog Devices */
-			if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
-			 && (reg_config1 & 0x3F) == 0x00
-			 && reg_convrate <= 0x0A) {
-				kind = adm1032;
-			} else
-			if (chip_id == 0x51 /* ADT7461 */
-			 && (reg_config1 & 0x1B) == 0x00
-			 && reg_convrate <= 0x0A) {
-				kind = adt7461;
-			}
-		} else
-		if (man_id == 0x4D) { /* Maxim */
-			/*
-			 * The MAX6657, MAX6658 and MAX6659 do NOT have a
-			 * chip_id register. Reading from that address will
-			 * return the last read value, which in our case is
-			 * those of the man_id register. Likewise, the config1
-			 * register seems to lack a low nibble, so the value
-			 * will be those of the previous read, so in our case
-			 * those of the man_id register.
-			 */
-			if (chip_id == man_id
-			 && (address == 0x4C || address == 0x4D)
-			 && (reg_config1 & 0x1F) == (man_id & 0x0F)
-			 && reg_convrate <= 0x09) {
-			 	kind = max6657;
+		reg_config2 = i2c_smbus_read_byte_data(new_client,
+						LM90_REG_R_CONFIG2);
+		if (reg_config2 < 0)
+			return -ENODEV;
+
+		if ((reg_config1 & 0x2A) == 0x00
+		 && (reg_config2 & 0xF8) == 0x00
+		 && reg_convrate <= 0x09) {
+			if (address == 0x4C
+			 && (chip_id & 0xF0) == 0x20) { /* LM90 */
+				name = "lm90";
 			} else
-			/* The chip_id register of the MAX6680 and MAX6681
-			 * holds the revision of the chip.
-			 * the lowest bit of the config1 register is unused
-			 * and should return zero when read, so should the
-			 * second to last bit of config1 (software reset)
-			 */
-			if (chip_id == 0x01
-			 && (reg_config1 & 0x03) == 0x00
-			 && reg_convrate <= 0x07) {
-			 	kind = max6680;
+			if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
+				name = "lm99";
+				dev_info(&adapter->dev,
+					 "Assuming LM99 chip at 0x%02x\n",
+					 address);
+				dev_info(&adapter->dev,
+					 "If it is an LM89, instantiate it "
+					 "with the new_device sysfs "
+					 "interface\n");
 			} else
-			/* The chip_id register of the MAX6646/6647/6649
-			 * holds the revision of the chip.
-			 * The lowest 6 bits of the config1 register are
-			 * unused and should return zero when read.
-			 */
-			if (chip_id == 0x59
-			 && (reg_config1 & 0x3f) == 0x00
-			 && reg_convrate <= 0x07) {
-				kind = max6646;
+			if (address == 0x4C
+			 && (chip_id & 0xF0) == 0x10) { /* LM86 */
+				name = "lm86";
 			}
 		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_dbg(&adapter->dev,
-				"Unsupported chip at 0x%02x (man_id=0x%02X, "
-				"chip_id=0x%02X)\n", address, man_id, chip_id);
-			return -ENODEV;
+	} else
+	if ((address == 0x4C || address == 0x4D)
+	 && man_id == 0x41) { /* Analog Devices */
+		if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
+		 && (reg_config1 & 0x3F) == 0x00
+		 && reg_convrate <= 0x0A) {
+			name = "adm1032";
+			/* The ADM1032 supports PEC, but only if combined
+			   transactions are not used. */
+			if (i2c_check_functionality(adapter,
+						    I2C_FUNC_SMBUS_BYTE))
+				info->flags |= I2C_CLIENT_PEC;
+		} else
+		if (chip_id == 0x51 /* ADT7461 */
+		 && (reg_config1 & 0x1B) == 0x00
+		 && reg_convrate <= 0x0A) {
+			name = "adt7461";
+		}
+	} else
+	if (man_id == 0x4D) { /* Maxim */
+		/*
+		 * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id
+		 * register. Reading from that address will return the last
+		 * read value, which in our case is those of the man_id
+		 * register. Likewise, the config1 register seems to lack a
+		 * low nibble, so the value will be those of the previous
+		 * read, so in our case those of the man_id register.
+		 */
+		if (chip_id == man_id
+		 && (address == 0x4C || address == 0x4D)
+		 && (reg_config1 & 0x1F) == (man_id & 0x0F)
+		 && reg_convrate <= 0x09) {
+			name = "max6657";
+		} else
+		/*
+		 * The chip_id register of the MAX6680 and MAX6681 holds the
+		 * revision of the chip. The lowest bit of the config1 register
+		 * is unused and should return zero when read, so should the
+		 * second to last bit of config1 (software reset).
+		 */
+		if (chip_id == 0x01
+		 && (reg_config1 & 0x03) == 0x00
+		 && reg_convrate <= 0x07) {
+			name = "max6680";
+		} else
+		/*
+		 * The chip_id register of the MAX6646/6647/6649 holds the
+		 * revision of the chip. The lowest 6 bits of the config1
+		 * register are unused and should return zero when read.
+		 */
+		if (chip_id == 0x59
+		 && (reg_config1 & 0x3f) == 0x00
+		 && reg_convrate <= 0x07) {
+			name = "max6646";
 		}
 	}
 
-	/* Fill the i2c board info */
-	if (kind == lm90) {
-		name = "lm90";
-	} else if (kind == adm1032) {
-		name = "adm1032";
-		/* The ADM1032 supports PEC, but only if combined
-		   transactions are not used. */
-		if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
-			info->flags |= I2C_CLIENT_PEC;
-	} else if (kind == lm99) {
-		name = "lm99";
-	} else if (kind == lm86) {
-		name = "lm86";
-	} else if (kind == max6657) {
-		name = "max6657";
-	} else if (kind == max6680) {
-		name = "max6680";
-	} else if (kind == adt7461) {
-		name = "adt7461";
-	} else if (kind == max6646) {
-		name = "max6646";
+	if (!name) { /* identification failed */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip at 0x%02x (man_id=0x%02X, "
+			"chip_id=0x%02X)\n", address, man_id, chip_id);
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm92.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm92.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm92.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm92.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,9 +54,6 @@
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 						I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm92);
-
 /* The LM92 registers */
 #define LM92_REG_CONFIG			0x01 /* 8-bit, RW */
 #define LM92_REG_TEMP			0x00 /* 16-bit, RO */
@@ -319,35 +316,26 @@ static const struct attribute_group lm92
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm92_detect(struct i2c_client *new_client, int kind,
+static int lm92_detect(struct i2c_client *new_client,
 		       struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
+	u8 config;
+	u16 man_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
 					    | I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
-	/* A negative kind means that the driver was loaded with no force
-	   parameter (default), so we must identify the chip. */
-	if (kind < 0) {
-		u8 config = i2c_smbus_read_byte_data(new_client,
-			     LM92_REG_CONFIG);
-		u16 man_id = i2c_smbus_read_word_data(new_client,
-			     LM92_REG_MAN_ID);
+	config = i2c_smbus_read_byte_data(new_client, LM92_REG_CONFIG);
+	man_id = i2c_smbus_read_word_data(new_client, LM92_REG_MAN_ID);
 
-		if ((config & 0xe0) == 0x00
-		 && man_id == 0x0180) {
-			pr_info("lm92: Found National Semiconductor LM92 chip\n");
-	 		kind = lm92;
-		} else
-		if (max6635_check(new_client)) {
-			pr_info("lm92: Found Maxim MAX6635 chip\n");
-			kind = lm92; /* No separate prefix */
-		}
-		else
-			return -ENODEV;
-	}
+	if ((config & 0xe0) == 0x00 && man_id == 0x0180)
+		pr_info("lm92: Found National Semiconductor LM92 chip\n");
+	else if (max6635_check(new_client))
+		pr_info("lm92: Found Maxim MAX6635 chip\n");
+	else
+		return -ENODEV;
 
 	strlcpy(info->type, "lm92", I2C_NAME_SIZE);
 
@@ -410,7 +398,7 @@ static int lm92_remove(struct i2c_client
  */
 
 static const struct i2c_device_id lm92_id[] = {
-	{ "lm92", lm92 },
+	{ "lm92", 0 },
 	/* max6635 could be added here */
 	{ }
 };
@@ -425,7 +413,7 @@ static struct i2c_driver lm92_driver = {
 	.remove		= lm92_remove,
 	.id_table	= lm92_id,
 	.detect		= lm92_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init sensors_lm92_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm93.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm93.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm93.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm93.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,6 @@
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm93);
 
 static int disable_block;
 module_param(disable_block, bool, 0);
@@ -928,7 +927,7 @@ static void lm93_update_client_common(st
 	data->prochot_interval = lm93_read_byte(client,
 			LM93_REG_PROCHOT_INTERVAL);
 
-	/* Fan Boost Termperature registers */
+	/* Fan Boost Temperature registers */
 	for (i = 0; i < 4; i++)
 		data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i));
 
@@ -2501,38 +2500,27 @@ static void lm93_init_client(struct i2c_
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm93_detect(struct i2c_client *client, int kind,
-		       struct i2c_board_info *info)
+static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int mfr, ver;
 
 	if (!i2c_check_functionality(adapter, LM93_SMBUS_FUNC_MIN))
 		return -ENODEV;
 
 	/* detection */
-	if (kind < 0) {
-		int mfr = lm93_read_byte(client, LM93_REG_MFR_ID);
-
-		if (mfr != 0x01) {
-			dev_dbg(&adapter->dev,"detect failed, "
-				"bad manufacturer id 0x%02x!\n", mfr);
-			return -ENODEV;
-		}
+	mfr = lm93_read_byte(client, LM93_REG_MFR_ID);
+	if (mfr != 0x01) {
+		dev_dbg(&adapter->dev,
+			"detect failed, bad manufacturer id 0x%02x!\n", mfr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) {
-		int ver = lm93_read_byte(client, LM93_REG_VER);
-
-		if ((ver == LM93_MFR_ID) || (ver == LM93_MFR_ID_PROTOTYPE)) {
-			kind = lm93;
-		} else {
-			dev_dbg(&adapter->dev,"detect failed, "
-				"bad version id 0x%02x!\n", ver);
-			if (kind == 0)
-				dev_dbg(&adapter->dev,
-					"(ignored 'force' parameter)\n");
-			return -ENODEV;
-		}
+	ver = lm93_read_byte(client, LM93_REG_VER);
+	if (ver != LM93_MFR_ID && ver != LM93_MFR_ID_PROTOTYPE) {
+		dev_dbg(&adapter->dev,
+			"detect failed, bad version id 0x%02x!\n", ver);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "lm93", I2C_NAME_SIZE);
@@ -2613,7 +2601,7 @@ static int lm93_remove(struct i2c_client
 }
 
 static const struct i2c_device_id lm93_id[] = {
-	{ "lm93", lm93 },
+	{ "lm93", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm93_id);
@@ -2627,7 +2615,7 @@ static struct i2c_driver lm93_driver = {
 	.remove		= lm93_remove,
 	.id_table	= lm93_id,
 	.detect		= lm93_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init lm93_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/lm95241.c linux-libre-2.6.33-gnu1/drivers/hwmon/lm95241.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/lm95241.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/lm95241.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,9 +39,6 @@
 static const unsigned short normal_i2c[] = {
 	0x19, 0x2a, 0x2b, I2C_CLIENT_END};
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm95241);
-
 /* LM95241 registers */
 #define LM95241_REG_R_MAN_ID		0xFE
 #define LM95241_REG_R_CHIP_ID		0xFF
@@ -310,56 +307,28 @@ static const struct attribute_group lm95
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm95241_detect(struct i2c_client *new_client, int kind,
+static int lm95241_detect(struct i2c_client *new_client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = new_client->adapter;
 	int address = new_client->addr;
-	const char *name = "";
+	const char *name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) {	/* detection */
-		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
-		     != MANUFACTURER_ID)
-		|| (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		    < DEFAULT_REVISION)) {
-			dev_dbg(&adapter->dev,
-				"LM95241 detection failed at 0x%02x.\n",
-				address);
-			return -ENODEV;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
-		     == MANUFACTURER_ID)
-		&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		    >= DEFAULT_REVISION)) {
-
-			kind = lm95241;
-
-			if (kind <= 0) { /* identification failed */
-				dev_info(&adapter->dev, "Unsupported chip\n");
-				return -ENODEV;
-			}
-		}
+	if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+	     == MANUFACTURER_ID)
+	 && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+	     >= DEFAULT_REVISION)) {
+		name = "lm95241";
+	} else {
+		dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
+			address);
+		return -ENODEV;
 	}
 
 	/* Fill the i2c board info */
-	if (kind == lm95241)
-		name = "lm95241";
 	strlcpy(info->type, name, I2C_NAME_SIZE);
 	return 0;
 }
@@ -474,7 +443,7 @@ static struct lm95241_data *lm95241_upda
 
 /* Driver data (common to all clients) */
 static const struct i2c_device_id lm95241_id[] = {
-	{ "lm95241", lm95241 },
+	{ "lm95241", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm95241_id);
@@ -488,7 +457,7 @@ static struct i2c_driver lm95241_driver
 	.remove		= lm95241_remove,
 	.id_table	= lm95241_id,
 	.detect		= lm95241_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init sensors_lm95241_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/Makefile linux-libre-2.6.33-gnu1/drivers/hwmon/Makefile
--- linux-libre-2.6.32-gnu1/drivers/hwmon/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -53,10 +53,13 @@ obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
 obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_K8TEMP)	+= k8temp.o
+obj-$(CONFIG_SENSORS_K10TEMP)	+= k10temp.o
 obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
 obj-$(CONFIG_SENSORS_LIS3_SPI)	+= lis3lv02d.o lis3lv02d_spi.o
+obj-$(CONFIG_SENSORS_LIS3_I2C)	+= lis3lv02d.o lis3lv02d_i2c.o
 obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
 obj-$(CONFIG_SENSORS_LM70)	+= lm70.o
+obj-$(CONFIG_SENSORS_LM73)	+= lm73.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
 obj-$(CONFIG_SENSORS_LM77)	+= lm77.o
 obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
@@ -73,6 +76,7 @@ obj-$(CONFIG_SENSORS_LTC4245)	+= ltc4245
 obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
@@ -82,9 +86,11 @@ obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
+obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
 obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
+obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_VT1211)	+= vt1211.o
 obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/max1619.c linux-libre-2.6.33-gnu1/drivers/hwmon/max1619.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/max1619.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/max1619.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,12 +41,6 @@ static const unsigned short normal_i2c[]
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
 /*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_1(max1619);
-
-/*
  * The MAX1619 registers
  */
 
@@ -88,7 +82,7 @@ static int temp_to_reg(int val)
 
 static int max1619_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int max1619_detect(struct i2c_client *client, int kind,
+static int max1619_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static void max1619_init_client(struct i2c_client *client);
 static int max1619_remove(struct i2c_client *client);
@@ -99,7 +93,7 @@ static struct max1619_data *max1619_upda
  */
 
 static const struct i2c_device_id max1619_id[] = {
-	{ "max1619", max1619 },
+	{ "max1619", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max1619_id);
@@ -113,7 +107,7 @@ static struct i2c_driver max1619_driver
 	.remove		= max1619_remove,
 	.id_table	= max1619_id,
 	.detect		= max1619_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -226,58 +220,34 @@ static const struct attribute_group max1
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int max1619_detect(struct i2c_client *new_client, int kind,
+static int max1619_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
-	u8 reg_config=0, reg_convrate=0, reg_status=0;
+	struct i2c_adapter *adapter = client->adapter;
+	u8 reg_config, reg_convrate, reg_status, man_id, chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		reg_config = i2c_smbus_read_byte_data(new_client,
-			      MAX1619_REG_R_CONFIG);
-		reg_convrate = i2c_smbus_read_byte_data(new_client,
-			       MAX1619_REG_R_CONVRATE);
-		reg_status = i2c_smbus_read_byte_data(new_client,
-				MAX1619_REG_R_STATUS);
-		if ((reg_config & 0x03) != 0x00
-		 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
-			dev_dbg(&adapter->dev,
-				"MAX1619 detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* detection */
+	reg_config = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONFIG);
+	reg_convrate = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONVRATE);
+	reg_status = i2c_smbus_read_byte_data(client, MAX1619_REG_R_STATUS);
+	if ((reg_config & 0x03) != 0x00
+	 || reg_convrate > 0x07 || (reg_status & 0x61) != 0x00) {
+		dev_dbg(&adapter->dev, "MAX1619 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-	
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 MAX1619_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  MAX1619_REG_R_CHIP_ID);
-		
-		if ((man_id == 0x4D) && (chip_id == 0x04))
-			kind = max1619;
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	/* identification */
+	man_id = i2c_smbus_read_byte_data(client, MAX1619_REG_R_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CHIP_ID);
+	if (man_id != 0x4D || chip_id != 0x04) {
+		dev_info(&adapter->dev,
+			 "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n",
+			 man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "max1619", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/max6650.c linux-libre-2.6.33-gnu1/drivers/hwmon/max6650.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/max6650.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/max6650.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,8 +62,6 @@ module_param(fan_voltage, int, S_IRUGO);
 module_param(prescaler, int, S_IRUGO);
 module_param(clock, int, S_IRUGO);
 
-I2C_CLIENT_INSMOD_1(max6650);
-
 /*
  * MAX 6650/6651 registers
  */
@@ -116,7 +114,7 @@ I2C_CLIENT_INSMOD_1(max6650);
 
 static int max6650_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int max6650_detect(struct i2c_client *client, int kind,
+static int max6650_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int max6650_init_client(struct i2c_client *client);
 static int max6650_remove(struct i2c_client *client);
@@ -127,7 +125,7 @@ static struct max6650_data *max6650_upda
  */
 
 static const struct i2c_device_id max6650_id[] = {
-	{ "max6650", max6650 },
+	{ "max6650", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max6650_id);
@@ -141,7 +139,7 @@ static struct i2c_driver max6650_driver
 	.remove		= max6650_remove,
 	.id_table	= max6650_id,
 	.detect		= max6650_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -528,13 +526,13 @@ static struct attribute_group max6650_at
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int max6650_detect(struct i2c_client *client, int kind,
+static int max6650_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
 
-	dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind);
+	dev_dbg(&adapter->dev, "max6650_detect called\n");
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
@@ -542,23 +540,7 @@ static int max6650_detect(struct i2c_cli
 		return -ENODEV;
 	}
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, max6650). A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 *
-	 * Currently I can find no way to distinguish between a MAX6650 and
-	 * a MAX6651. This driver has only been tried on the former.
-	 */
-
-	if ((kind < 0) &&
-	   (  (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
+	if (((i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0)
 	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/mc13783-adc.c linux-libre-2.6.33-gnu1/drivers/hwmon/mc13783-adc.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/mc13783-adc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/mc13783-adc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,236 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static int mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, unsigned int *val)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int sample[4];
+	int ret;
+
+	ret = mc13783_adc_do_conversion(priv->mc13783,
+			MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+	if (ret)
+		return ret;
+
+	channel &= 0x7;
+
+	*val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return 0;
+}
+
+static ssize_t mc13783_adc_read_bp(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	unsigned val;
+	int ret = mc13783_adc_read(dev, devattr, &val);
+
+	if (ret)
+		return ret;
+
+	/*
+	 * BP (channel 2) reports with offset 2.4V to the actual value to fit
+	 * the input range of the ADC.  unit = 2.25mV = 9/4 mV.
+	 */
+	val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t mc13783_adc_read_gp(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	unsigned val;
+	int ret = mc13783_adc_read(dev, devattr, &val);
+
+	if (ret)
+		return ret;
+
+	/*
+	 * input range is [0, 2.3V], val has 10 bits, so each bit
+	 * is worth 9/4 mV.
+	 */
+	val = DIV_ROUND_CLOSEST(val * 9, 4);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, mc13783_adc_read_bp, NULL, 2);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, mc13783_adc_read_gp, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, mc13783_adc_read_gp, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, mc13783_adc_read_gp, NULL, 7);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, mc13783_adc_read_gp, NULL, 8);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, mc13783_adc_read_gp, NULL, 9);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, mc13783_adc_read_gp, NULL, 10);
+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, mc13783_adc_read_gp, NULL, 11);
+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, mc13783_adc_read_gp, NULL, 12);
+static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13);
+static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14);
+static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15);
+
+static struct attribute *mc13783_attr[] = {
+	&dev_attr_name.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_in9_input.dev_attr.attr,
+	&sensor_dev_attr_in10_input.dev_attr.attr,
+	&sensor_dev_attr_in11_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group mc13783_group = {
+	.attrs = mc13783_attr,
+};
+
+/* last four channels may be occupied by the touchscreen */
+static struct attribute *mc13783_attr_ts[] = {
+	&sensor_dev_attr_in12_input.dev_attr.attr,
+	&sensor_dev_attr_in13_input.dev_attr.attr,
+	&sensor_dev_attr_in14_input.dev_attr.attr,
+	&sensor_dev_attr_in15_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group mc13783_group_ts = {
+	.attrs = mc13783_attr_ts,
+};
+
+static int __init mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+
+	platform_set_drvdata(pdev, priv);
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group);
+	if (ret)
+		goto out_err_create1;
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts);
+		if (ret)
+			goto out_err_create2;
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err_register;
+	}
+
+
+	return 0;
+
+out_err_register:
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
+out_err_create2:
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
+out_err_create1:
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(priv->hwmon_dev);
+
+	if (!(priv->mc13783->flags & MC13783_USE_TOUCHSCREEN))
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_probe(&mc13783_adc_driver, mc13783_adc_probe);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 ADC driver");
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MC13783_ADC_NAME);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/pcf8591.c linux-libre-2.6.33-gnu1/drivers/hwmon/pcf8591.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/pcf8591.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/pcf8591.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,6 @@ static const unsigned short normal_i2c[]
 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(pcf8591);
 
 static int input_mode;
 module_param(input_mode, int, 0);
@@ -169,7 +168,7 @@ static const struct attribute_group pcf8
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int pcf8591_detect(struct i2c_client *client, int kind,
+static int pcf8591_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -299,7 +298,7 @@ static struct i2c_driver pcf8591_driver
 
 	.class		= I2C_CLASS_HWMON,	/* Nearest choice */
 	.detect		= pcf8591_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init pcf8591_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/s3c-hwmon.c linux-libre-2.6.33-gnu1/drivers/hwmon/s3c-hwmon.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/s3c-hwmon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/s3c-hwmon.c	2010-02-24 13:52:17.000000000 -0500
@@ -323,7 +323,7 @@ static int __devinit s3c_hwmon_probe(str
 	}
 
 	for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
-		struct s3c24xx_adc_hwmon_incfg *cfg = pdata->in[i];
+		struct s3c_hwmon_chcfg *cfg = pdata->in[i];
 
 		if (!cfg)
 			continue;
@@ -333,7 +333,7 @@ static int __devinit s3c_hwmon_probe(str
 				 "channel %d multiplier too large\n",
 				 i);
 
-		if (cfg->divider == 0) {
+		if (cfg->div == 0) {
 			dev_err(&dev->dev, "channel %d divider zero\n", i);
 			continue;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/sht15.c linux-libre-2.6.33-gnu1/drivers/hwmon/sht15.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/sht15.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/sht15.c	2010-02-24 13:52:17.000000000 -0500
@@ -305,7 +305,7 @@ static inline int sht15_calc_temp(struct
 	int d1 = 0;
 	int i;
 
-	for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++)
+	for (i = 1; i < ARRAY_SIZE(temppoints); i++)
 		/* Find pointer to interpolate */
 		if (data->supply_uV > temppoints[i - 1].vdd) {
 			d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
@@ -332,12 +332,12 @@ static inline int sht15_calc_humid(struc
 
 	const int c1 = -4;
 	const int c2 = 40500; /* x 10 ^ -6 */
-	const int c3 = 2800; /* x10 ^ -9 */
+	const int c3 = -2800; /* x10 ^ -9 */
 
 	RHlinear = c1*1000
 		+ c2 * data->val_humid/1000
 		+ (data->val_humid * data->val_humid * c3)/1000000;
-	return (temp - 25000) * (10000 + 800 * data->val_humid)
+	return (temp - 25000) * (10000 + 80 * data->val_humid)
 		/ 1000000 + RHlinear;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/sis5595.c linux-libre-2.6.33-gnu1/drivers/hwmon/sis5595.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/sis5595.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/sis5595.c	2010-02-24 13:52:17.000000000 -0500
@@ -697,7 +697,7 @@ static struct sis5595_data *sis5595_upda
 	return data;
 }
 
-static struct pci_device_id sis5595_pci_ids[] = {
+static const struct pci_device_id sis5595_pci_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/smsc47m192.c linux-libre-2.6.33-gnu1/drivers/hwmon/smsc47m192.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/smsc47m192.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/smsc47m192.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,9 +36,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(smsc47m192);
-
 /* SMSC47M192 registers */
 #define SMSC47M192_REG_IN(nr)		((nr)<6 ? (0x20 + (nr)) : \
 					(0x50 + (nr) - 6))
@@ -115,13 +112,13 @@ struct smsc47m192_data {
 
 static int smsc47m192_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id);
-static int smsc47m192_detect(struct i2c_client *client, int kind,
+static int smsc47m192_detect(struct i2c_client *client,
 			     struct i2c_board_info *info);
 static int smsc47m192_remove(struct i2c_client *client);
 static struct smsc47m192_data *smsc47m192_update_device(struct device *dev);
 
 static const struct i2c_device_id smsc47m192_id[] = {
-	{ "smsc47m192", smsc47m192 },
+	{ "smsc47m192", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
@@ -135,7 +132,7 @@ static struct i2c_driver smsc47m192_driv
 	.remove		= smsc47m192_remove,
 	.id_table	= smsc47m192_id,
 	.detect		= smsc47m192_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* Voltages */
@@ -481,7 +478,7 @@ static void smsc47m192_init_client(struc
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int smsc47m192_detect(struct i2c_client *client, int kind,
+static int smsc47m192_detect(struct i2c_client *client,
 			     struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -491,24 +488,22 @@ static int smsc47m192_detect(struct i2c_
 		return -ENODEV;
 
 	/* Detection criteria from sensors_detect script */
-	if (kind < 0) {
-		if (i2c_smbus_read_byte_data(client,
+	version = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VERSION);
+	if (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_COMPANY_ID) == 0x55
-		 && ((version = i2c_smbus_read_byte_data(client,
-				SMSC47M192_REG_VERSION)) & 0xf0) == 0x20
-		 && (i2c_smbus_read_byte_data(client,
+	 && (version & 0xf0) == 0x20
+	 && (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_VID) & 0x70) == 0x00
-		 && (i2c_smbus_read_byte_data(client,
+	 && (i2c_smbus_read_byte_data(client,
 				SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
-			dev_info(&adapter->dev,
-				 "found SMSC47M192 or compatible, "
-				 "version 2, stepping A%d\n", version & 0x0f);
-		} else {
-			dev_dbg(&adapter->dev,
-				"SMSC47M192 detection failed at 0x%02x\n",
-				client->addr);
-			return -ENODEV;
-		}
+		dev_info(&adapter->dev,
+			 "found SMSC47M192 or compatible, "
+			 "version 2, stepping A%d\n", version & 0x0f);
+	} else {
+		dev_dbg(&adapter->dev,
+			"SMSC47M192 detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/smsc47m1.c linux-libre-2.6.33-gnu1/drivers/hwmon/smsc47m1.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/smsc47m1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/smsc47m1.c	2010-02-24 13:52:17.000000000 -0500
@@ -136,11 +136,11 @@ struct smsc47m1_data {
 
 struct smsc47m1_sio_data {
 	enum chips type;
+	u8 activate;		/* Remember initial device state */
 };
 
 
-static int smsc47m1_probe(struct platform_device *pdev);
-static int __devexit smsc47m1_remove(struct platform_device *pdev);
+static int __exit smsc47m1_remove(struct platform_device *pdev);
 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
 		int init);
 
@@ -160,8 +160,7 @@ static struct platform_driver smsc47m1_d
 		.owner	= THIS_MODULE,
 		.name	= DRVNAME,
 	},
-	.probe		= smsc47m1_probe,
-	.remove		= __devexit_p(smsc47m1_remove),
+	.remove		= __exit_p(smsc47m1_remove),
 };
 
 static ssize_t get_fan(struct device *dev, struct device_attribute
@@ -470,24 +469,126 @@ static int __init smsc47m1_find(unsigned
 	superio_select();
 	*addr = (superio_inb(SUPERIO_REG_BASE) << 8)
 	      |  superio_inb(SUPERIO_REG_BASE + 1);
-	val = superio_inb(SUPERIO_REG_ACT);
-	if (*addr == 0 || (val & 0x01) == 0) {
-		pr_info(DRVNAME ": Device is disabled, will not use\n");
+	if (*addr == 0) {
+		pr_info(DRVNAME ": Device address not set, will not use\n");
 		superio_exit();
 		return -ENODEV;
 	}
 
+	/* Enable only if address is set (needed at least on the
+	 * Compaq Presario S4000NX) */
+	sio_data->activate = superio_inb(SUPERIO_REG_ACT);
+	if ((sio_data->activate & 0x01) == 0) {
+		pr_info(DRVNAME ": Enabling device\n");
+		superio_outb(SUPERIO_REG_ACT, sio_data->activate | 0x01);
+	}
+
 	superio_exit();
 	return 0;
 }
 
-static int __devinit smsc47m1_probe(struct platform_device *pdev)
+/* Restore device to its initial state */
+static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
+{
+	if ((sio_data->activate & 0x01) == 0) {
+		superio_enter();
+		superio_select();
+
+		pr_info(DRVNAME ": Disabling device\n");
+		superio_outb(SUPERIO_REG_ACT, sio_data->activate);
+
+		superio_exit();
+	}
+}
+
+#define CHECK		1
+#define REQUEST		2
+#define RELEASE		3
+
+/*
+ * This function can be used to:
+ *  - test for resource conflicts with ACPI
+ *  - request the resources
+ *  - release the resources
+ * We only allocate the I/O ports we really need, to minimize the risk of
+ * conflicts with ACPI or with other drivers.
+ */
+static int smsc47m1_handle_resources(unsigned short address, enum chips type,
+				     int action, struct device *dev)
+{
+	static const u8 ports_m1[] = {
+		/* register, region length */
+		0x04, 1,
+		0x33, 4,
+		0x56, 7,
+	};
+
+	static const u8 ports_m2[] = {
+		/* register, region length */
+		0x04, 1,
+		0x09, 1,
+		0x2c, 2,
+		0x35, 4,
+		0x56, 7,
+		0x69, 4,
+	};
+
+	int i, ports_size, err;
+	const u8 *ports;
+
+	switch (type) {
+	case smsc47m1:
+	default:
+		ports = ports_m1;
+		ports_size = ARRAY_SIZE(ports_m1);
+		break;
+	case smsc47m2:
+		ports = ports_m2;
+		ports_size = ARRAY_SIZE(ports_m2);
+		break;
+	}
+
+	for (i = 0; i + 1 < ports_size; i += 2) {
+		unsigned short start = address + ports[i];
+		unsigned short len = ports[i + 1];
+
+		switch (action) {
+		case CHECK:
+			/* Only check for conflicts */
+			err = acpi_check_region(start, len, DRVNAME);
+			if (err)
+				return err;
+			break;
+		case REQUEST:
+			/* Request the resources */
+			if (!request_region(start, len, DRVNAME)) {
+				dev_err(dev, "Region 0x%hx-0x%hx already in "
+					"use!\n", start, start + len);
+
+				/* Undo all requests */
+				for (i -= 2; i >= 0; i -= 2)
+					release_region(address + ports[i],
+						       ports[i + 1]);
+				return -EBUSY;
+			}
+			break;
+		case RELEASE:
+			/* Release the resources */
+			release_region(start, len);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int __init smsc47m1_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct smsc47m1_sio_data *sio_data = dev->platform_data;
 	struct smsc47m1_data *data;
 	struct resource *res;
-	int err = 0;
+	int err;
 	int fan1, fan2, fan3, pwm1, pwm2, pwm3;
 
 	static const char *names[] = {
@@ -496,12 +597,10 @@ static int __devinit smsc47m1_probe(stru
 	};
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
-		dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
-			(unsigned long)res->start,
-			(unsigned long)res->end);
-		return -EBUSY;
-	}
+	err = smsc47m1_handle_resources(res->start, sio_data->type,
+					REQUEST, dev);
+	if (err < 0)
+		return err;
 
 	if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
 		err = -ENOMEM;
@@ -637,11 +736,11 @@ error_free:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
 error_release:
-	release_region(res->start, SMSC_EXTENT);
+	smsc47m1_handle_resources(res->start, sio_data->type, RELEASE, dev);
 	return err;
 }
 
-static int __devexit smsc47m1_remove(struct platform_device *pdev)
+static int __exit smsc47m1_remove(struct platform_device *pdev)
 {
 	struct smsc47m1_data *data = platform_get_drvdata(pdev);
 	struct resource *res;
@@ -650,7 +749,7 @@ static int __devexit smsc47m1_remove(str
 	sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	release_region(res->start, SMSC_EXTENT);
+	smsc47m1_handle_resources(res->start, data->type, RELEASE, &pdev->dev);
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
 
@@ -717,7 +816,7 @@ static int __init smsc47m1_device_add(un
 	};
 	int err;
 
-	err = acpi_check_resource_conflict(&res);
+	err = smsc47m1_handle_resources(address, sio_data->type, CHECK, NULL);
 	if (err)
 		goto exit;
 
@@ -766,27 +865,29 @@ static int __init sm_smsc47m1_init(void)
 	if (smsc47m1_find(&address, &sio_data))
 		return -ENODEV;
 
-	err = platform_driver_register(&smsc47m1_driver);
+	/* Sets global pdev as a side effect */
+	err = smsc47m1_device_add(address, &sio_data);
 	if (err)
 		goto exit;
 
-	/* Sets global pdev as a side effect */
-	err = smsc47m1_device_add(address, &sio_data);
+	err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe);
 	if (err)
-		goto exit_driver;
+		goto exit_device;
 
 	return 0;
 
-exit_driver:
-	platform_driver_unregister(&smsc47m1_driver);
+exit_device:
+	platform_device_unregister(pdev);
+	smsc47m1_restore(&sio_data);
 exit:
 	return err;
 }
 
 static void __exit sm_smsc47m1_exit(void)
 {
-	platform_device_unregister(pdev);
 	platform_driver_unregister(&smsc47m1_driver);
+	smsc47m1_restore(pdev->dev.platform_data);
+	platform_device_unregister(pdev);
 }
 
 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/thmc50.c linux-libre-2.6.33-gnu1/drivers/hwmon/thmc50.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/thmc50.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/thmc50.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,8 +35,12 @@ MODULE_LICENSE("GPL");
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_2(thmc50, adm1022);
-I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
+enum chips { thmc50, adm1022 };
+
+static unsigned short adm1022_temp3[16];
+static unsigned int adm1022_temp3_num;
+module_param_array(adm1022_temp3, ushort, &adm1022_temp3_num, 0);
+MODULE_PARM_DESC(adm1022_temp3, "List of adapter,address pairs "
 			"to enable 3rd temperature (ADM1022 only)");
 
 /* Many THMC50 constants specified below */
@@ -80,7 +84,7 @@ struct thmc50_data {
 	u8 alarms;
 };
 
-static int thmc50_detect(struct i2c_client *client, int kind,
+static int thmc50_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int thmc50_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
@@ -104,7 +108,7 @@ static struct i2c_driver thmc50_driver =
 	.remove = thmc50_remove,
 	.id_table = thmc50_id,
 	.detect = thmc50_detect,
-	.address_data = &addr_data,
+	.address_list = normal_i2c,
 };
 
 static ssize_t show_analog_out(struct device *dev,
@@ -282,14 +286,13 @@ static const struct attribute_group temp
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int thmc50_detect(struct i2c_client *client, int kind,
+static int thmc50_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
 	unsigned company;
 	unsigned revision;
 	unsigned config;
 	struct i2c_adapter *adapter = client->adapter;
-	int err = 0;
 	const char *type_name;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -301,31 +304,13 @@ static int thmc50_detect(struct i2c_clie
 	pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
 		 client->addr, i2c_adapter_id(client->adapter));
 
-	/* Now, we do the remaining detection. */
 	company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);
 	revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);
 	config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+	if (revision < 0xc0 || (config & 0x10))
+		return -ENODEV;
 
-	if (kind == 0)
-		kind = thmc50;
-	else if (kind < 0) {
-		err = -ENODEV;
-		if (revision >= 0xc0 && ((config & 0x10) == 0)) {
-			if (company == 0x49) {
-				kind = thmc50;
-				err = 0;
-			} else if (company == 0x41) {
-				kind = adm1022;
-				err = 0;
-			}
-		}
-	}
-	if (err == -ENODEV) {
-		pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
-		return err;
-	}
-
-	if (kind == adm1022) {
+	if (company == 0x41) {
 		int id = i2c_adapter_id(client->adapter);
 		int i;
 
@@ -340,9 +325,13 @@ static int thmc50_detect(struct i2c_clie
 							  config);
 				break;
 			}
-	} else {
+	} else if (company == 0x49) {
 		type_name = "thmc50";
+	} else {
+		pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
+		return -ENODEV;
 	}
+
 	pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
 		 type_name, (revision >> 4) - 0xc, revision & 0xf);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/tmp401.c linux-libre-2.6.33-gnu1/drivers/hwmon/tmp401.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/tmp401.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/tmp401.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,8 +42,7 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(tmp401, tmp411);
+enum chips { tmp401, tmp411 };
 
 /*
  * The TMP401 registers, note some registers have different addresses for
@@ -98,7 +97,7 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[
 
 static int tmp401_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
-static int tmp401_detect(struct i2c_client *client, int kind,
+static int tmp401_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int tmp401_remove(struct i2c_client *client);
 static struct tmp401_data *tmp401_update_device(struct device *dev);
@@ -123,7 +122,7 @@ static struct i2c_driver tmp401_driver =
 	.remove		= tmp401_remove,
 	.id_table	= tmp401_id,
 	.detect		= tmp401_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -488,46 +487,43 @@ static void tmp401_init_client(struct i2
 		i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
 }
 
-static int tmp401_detect(struct i2c_client *client, int kind,
+static int tmp401_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
+	u8 reg;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
 	/* Detect and identify the chip */
-	if (kind <= 0) {
-		u8 reg;
+	reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG);
+	if (reg != TMP401_MANUFACTURER_ID)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP401_MANUFACTURER_ID_REG);
-		if (reg != TMP401_MANUFACTURER_ID)
-			return -ENODEV;
+	reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
 
-		reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
+	switch (reg) {
+	case TMP401_DEVICE_ID:
+		kind = tmp401;
+		break;
+	case TMP411_DEVICE_ID:
+		kind = tmp411;
+		break;
+	default:
+		return -ENODEV;
+	}
 
-		switch (reg) {
-		case TMP401_DEVICE_ID:
-			kind = tmp401;
-			break;
-		case TMP411_DEVICE_ID:
-			kind = tmp411;
-			break;
-		default:
-			return -ENODEV;
-		}
+	reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
+	if (reg & 0x1b)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
-		if (reg & 0x1b)
-			return -ENODEV;
+	reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ);
+	/* Datasheet says: 0x1-0x6 */
+	if (reg > 15)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP401_CONVERSION_RATE_READ);
-		/* Datasheet says: 0x1-0x6 */
-		if (reg > 15)
-			return -ENODEV;
-	}
 	strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/tmp421.c linux-libre-2.6.33-gnu1/drivers/hwmon/tmp421.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/tmp421.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/tmp421.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,7 @@
 static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
 				       I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
+enum chips { tmp421, tmp422, tmp423 };
 
 /* The TMP421 registers */
 #define TMP421_CONFIG_REG_1			0x09
@@ -223,39 +222,36 @@ static int tmp421_init_client(struct i2c
 	return 0;
 }
 
-static int tmp421_detect(struct i2c_client *client, int kind,
+static int tmp421_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
+	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
 	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+	u8 reg;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		u8 reg;
-
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP421_MANUFACTURER_ID_REG);
-		if (reg != TMP421_MANUFACTURER_ID)
-			return -ENODEV;
+	reg = i2c_smbus_read_byte_data(client, TMP421_MANUFACTURER_ID_REG);
+	if (reg != TMP421_MANUFACTURER_ID)
+		return -ENODEV;
 
-		reg = i2c_smbus_read_byte_data(client,
-					       TMP421_DEVICE_ID_REG);
-		switch (reg) {
-		case TMP421_DEVICE_ID:
-			kind = tmp421;
-			break;
-		case TMP422_DEVICE_ID:
-			kind = tmp422;
-			break;
-		case TMP423_DEVICE_ID:
-			kind = tmp423;
-			break;
-		default:
-			return -ENODEV;
-		}
+	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
+	switch (reg) {
+	case TMP421_DEVICE_ID:
+		kind = tmp421;
+		break;
+	case TMP422_DEVICE_ID:
+		kind = tmp422;
+		break;
+	case TMP423_DEVICE_ID:
+		kind = tmp423;
+		break;
+	default:
+		return -ENODEV;
 	}
+
 	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
 	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
 		 names[kind - 1], client->addr);
@@ -325,7 +321,7 @@ static struct i2c_driver tmp421_driver =
 	.remove = tmp421_remove,
 	.id_table = tmp421_id,
 	.detect = tmp421_detect,
-	.address_data = &addr_data,
+	.address_list = normal_i2c,
 };
 
 static int __init tmp421_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/via686a.c linux-libre-2.6.33-gnu1/drivers/hwmon/via686a.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/via686a.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/via686a.c	2010-02-24 13:52:17.000000000 -0500
@@ -767,7 +767,7 @@ static struct via686a_data *via686a_upda
 	return data;
 }
 
-static struct pci_device_id via686a_pci_ids[] = {
+static const struct pci_device_id via686a_pci_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/via-cputemp.c linux-libre-2.6.33-gnu1/drivers/hwmon/via-cputemp.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/via-cputemp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/via-cputemp.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,356 @@
+/*
+ * via-cputemp.c - Driver for VIA CPU core temperature monitoring
+ * Copyright (C) 2009 VIA Technologies, Inc.
+ *
+ * based on existing coretemp.c, which is
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * 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 Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+#define DRVNAME	"via_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME } SHOW;
+
+/*
+ * Functions declaration
+ */
+
+struct via_cputemp_data {
+	struct device *hwmon_dev;
+	const char *name;
+	u32 id;
+	u32 msr;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+			  *devattr, char *buf)
+{
+	int ret;
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct via_cputemp_data *data = dev_get_drvdata(dev);
+
+	if (attr->index == SHOW_NAME)
+		ret = sprintf(buf, "%s\n", data->name);
+	else	/* show label */
+		ret = sprintf(buf, "Core %d\n", data->id);
+	return ret;
+}
+
+static ssize_t show_temp(struct device *dev,
+			 struct device_attribute *devattr, char *buf)
+{
+	struct via_cputemp_data *data = dev_get_drvdata(dev);
+	u32 eax, edx;
+	int err;
+
+	err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx);
+	if (err)
+		return -EAGAIN;
+
+	return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
+			  SHOW_TEMP);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
+
+static struct attribute *via_cputemp_attributes[] = {
+	&sensor_dev_attr_name.dev_attr.attr,
+	&sensor_dev_attr_temp1_label.dev_attr.attr,
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group via_cputemp_group = {
+	.attrs = via_cputemp_attributes,
+};
+
+static int __devinit via_cputemp_probe(struct platform_device *pdev)
+{
+	struct via_cputemp_data *data;
+	struct cpuinfo_x86 *c = &cpu_data(pdev->id);
+	int err;
+	u32 eax, edx;
+
+	data = kzalloc(sizeof(struct via_cputemp_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		dev_err(&pdev->dev, "Out of memory\n");
+		goto exit;
+	}
+
+	data->id = pdev->id;
+	data->name = "via_cputemp";
+
+	switch (c->x86_model) {
+	case 0xA:
+		/* C7 A */
+	case 0xD:
+		/* C7 D */
+		data->msr = 0x1169;
+		break;
+	case 0xF:
+		/* Nano */
+		data->msr = 0x1423;
+		break;
+	default:
+		err = -ENODEV;
+		goto exit_free;
+	}
+
+	/* test if we can access the TEMPERATURE MSR */
+	err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx);
+	if (err) {
+		dev_err(&pdev->dev,
+			"Unable to access TEMPERATURE MSR, giving up\n");
+		goto exit_free;
+	}
+
+	platform_set_drvdata(pdev, data);
+
+	err = sysfs_create_group(&pdev->dev.kobj, &via_cputemp_group);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		dev_err(&pdev->dev, "Class registration failed (%d)\n",
+			err);
+		goto exit_remove;
+	}
+
+	return 0;
+
+exit_remove:
+	sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
+exit_free:
+	platform_set_drvdata(pdev, NULL);
+	kfree(data);
+exit:
+	return err;
+}
+
+static int __devexit via_cputemp_remove(struct platform_device *pdev)
+{
+	struct via_cputemp_data *data = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
+	platform_set_drvdata(pdev, NULL);
+	kfree(data);
+	return 0;
+}
+
+static struct platform_driver via_cputemp_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DRVNAME,
+	},
+	.probe = via_cputemp_probe,
+	.remove = __devexit_p(via_cputemp_remove),
+};
+
+struct pdev_entry {
+	struct list_head list;
+	struct platform_device *pdev;
+	unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int __cpuinit via_cputemp_device_add(unsigned int cpu)
+{
+	int err;
+	struct platform_device *pdev;
+	struct pdev_entry *pdev_entry;
+
+	pdev = platform_device_alloc(DRVNAME, cpu);
+	if (!pdev) {
+		err = -ENOMEM;
+		printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+		goto exit;
+	}
+
+	pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+	if (!pdev_entry) {
+		err = -ENOMEM;
+		goto exit_device_put;
+	}
+
+	err = platform_device_add(pdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+		       err);
+		goto exit_device_free;
+	}
+
+	pdev_entry->pdev = pdev;
+	pdev_entry->cpu = cpu;
+	mutex_lock(&pdev_list_mutex);
+	list_add_tail(&pdev_entry->list, &pdev_list);
+	mutex_unlock(&pdev_list_mutex);
+
+	return 0;
+
+exit_device_free:
+	kfree(pdev_entry);
+exit_device_put:
+	platform_device_put(pdev);
+exit:
+	return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void via_cputemp_device_remove(unsigned int cpu)
+{
+	struct pdev_entry *p, *n;
+	mutex_lock(&pdev_list_mutex);
+	list_for_each_entry_safe(p, n, &pdev_list, list) {
+		if (p->cpu == cpu) {
+			platform_device_unregister(p->pdev);
+			list_del(&p->list);
+			kfree(p);
+		}
+	}
+	mutex_unlock(&pdev_list_mutex);
+}
+
+static int __cpuinit via_cputemp_cpu_callback(struct notifier_block *nfb,
+				 unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long) hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+	case CPU_DOWN_FAILED:
+		via_cputemp_device_add(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		via_cputemp_device_remove(cpu);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block via_cputemp_cpu_notifier __refdata = {
+	.notifier_call = via_cputemp_cpu_callback,
+};
+#endif				/* !CONFIG_HOTPLUG_CPU */
+
+static int __init via_cputemp_init(void)
+{
+	int i, err;
+	struct pdev_entry *p, *n;
+
+	if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) {
+		printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	err = platform_driver_register(&via_cputemp_driver);
+	if (err)
+		goto exit;
+
+	for_each_online_cpu(i) {
+		struct cpuinfo_x86 *c = &cpu_data(i);
+
+		if (c->x86 != 6)
+			continue;
+
+		if (c->x86_model < 0x0a)
+			continue;
+
+		if (c->x86_model > 0x0f) {
+			printk(KERN_WARNING DRVNAME ": Unknown CPU "
+				"model 0x%x\n", c->x86_model);
+			continue;
+		}
+
+		err = via_cputemp_device_add(i);
+		if (err)
+			goto exit_devices_unreg;
+	}
+	if (list_empty(&pdev_list)) {
+		err = -ENODEV;
+		goto exit_driver_unreg;
+	}
+
+#ifdef CONFIG_HOTPLUG_CPU
+	register_hotcpu_notifier(&via_cputemp_cpu_notifier);
+#endif
+	return 0;
+
+exit_devices_unreg:
+	mutex_lock(&pdev_list_mutex);
+	list_for_each_entry_safe(p, n, &pdev_list, list) {
+		platform_device_unregister(p->pdev);
+		list_del(&p->list);
+		kfree(p);
+	}
+	mutex_unlock(&pdev_list_mutex);
+exit_driver_unreg:
+	platform_driver_unregister(&via_cputemp_driver);
+exit:
+	return err;
+}
+
+static void __exit via_cputemp_exit(void)
+{
+	struct pdev_entry *p, *n;
+#ifdef CONFIG_HOTPLUG_CPU
+	unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
+#endif
+	mutex_lock(&pdev_list_mutex);
+	list_for_each_entry_safe(p, n, &pdev_list, list) {
+		platform_device_unregister(p->pdev);
+		list_del(&p->list);
+		kfree(p);
+	}
+	mutex_unlock(&pdev_list_mutex);
+	platform_driver_unregister(&via_cputemp_driver);
+}
+
+MODULE_AUTHOR("Harald Welte <HaraldWelte@viatech.com>");
+MODULE_DESCRIPTION("VIA CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(via_cputemp_init)
+module_exit(via_cputemp_exit)
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/vt8231.c linux-libre-2.6.33-gnu1/drivers/hwmon/vt8231.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/vt8231.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/vt8231.c	2010-02-24 13:52:17.000000000 -0500
@@ -697,7 +697,7 @@ static struct platform_driver vt8231_dri
 	.remove	= __devexit_p(vt8231_remove),
 };
 
-static struct pci_device_id vt8231_pci_ids[] = {
+static const struct pci_device_id vt8231_pci_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
 	{ 0, }
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83627ehf.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83627ehf.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83627ehf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83627ehf.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
     Copyright (C) 2006  Yuan Mu (Winbond),
                         Rudolf Marek <r.marek@assembler.cz>
                         David Hubbard <david.c.hubbard@gmail.com>
+			Daniel J Blueman <daniel.blueman@gmail.com>
 
     Shamelessly ripped from the w83627hf driver
     Copyright (C) 2003  Mark Studebaker
@@ -177,12 +178,15 @@ static const u16 W83627EHF_REG_TEMP_CONF
 #define W83627EHF_REG_ALARM3		0x45B
 
 /* SmartFan registers */
+#define W83627EHF_REG_FAN_STEPUP_TIME 0x0f
+#define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e
+
 /* DC or PWM output fan configuration */
 static const u8 W83627EHF_REG_PWM_ENABLE[] = {
 	0x04,			/* SYS FAN0 output mode and PWM mode */
 	0x04,			/* CPU FAN0 output mode and PWM mode */
 	0x12,			/* AUX FAN mode */
-	0x62,			/* CPU fan1 mode */
+	0x62,			/* CPU FAN1 mode */
 };
 
 static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 };
@@ -193,10 +197,12 @@ static const u8 W83627EHF_REG_PWM[] = {
 static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 };
 static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 };
 
-
 /* Advanced Fan control, some values are common for all fans */
-static const u8 W83627EHF_REG_FAN_MIN_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 };
-static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0C, 0x0D, 0x17, 0x66 };
+static const u8 W83627EHF_REG_FAN_START_OUTPUT[] = { 0x0a, 0x0b, 0x16, 0x65 };
+static const u8 W83627EHF_REG_FAN_STOP_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 };
+static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0c, 0x0d, 0x17, 0x66 };
+static const u8 W83627EHF_REG_FAN_MAX_OUTPUT[] = { 0xff, 0x67, 0xff, 0x69 };
+static const u8 W83627EHF_REG_FAN_STEP_OUTPUT[] = { 0xff, 0x68, 0xff, 0x6a };
 
 /*
  * Conversions
@@ -295,14 +301,19 @@ struct w83627ehf_data {
 
 	u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
 	u8 pwm_enable[4]; /* 1->manual
-			     2->thermal cruise (also called SmartFan I) */
+			     2->thermal cruise mode (also called SmartFan I)
+			     3->fan speed cruise mode
+			     4->variable thermal cruise (also called SmartFan III) */
 	u8 pwm_num;		/* number of pwm */
 	u8 pwm[4];
 	u8 target_temp[4];
 	u8 tolerance[4];
 
-	u8 fan_min_output[4]; /* minimum fan speed */
-	u8 fan_stop_time[4];
+	u8 fan_start_output[4]; /* minimum fan speed when spinning up */
+	u8 fan_stop_output[4]; /* minimum fan speed when spinning down */
+	u8 fan_stop_time[4]; /* time at minimum before disabling fan */
+	u8 fan_max_output[4]; /* maximum fan speed */
+	u8 fan_step_output[4]; /* rate of change output value */
 
 	u8 vid;
 	u8 vrm;
@@ -529,8 +540,10 @@ static struct w83627ehf_data *w83627ehf_
 						& 3) + 1;
 			data->pwm[i] = w83627ehf_read_value(data,
 						W83627EHF_REG_PWM[i]);
-			data->fan_min_output[i] = w83627ehf_read_value(data,
-						W83627EHF_REG_FAN_MIN_OUTPUT[i]);
+			data->fan_start_output[i] = w83627ehf_read_value(data,
+						W83627EHF_REG_FAN_START_OUTPUT[i]);
+			data->fan_stop_output[i] = w83627ehf_read_value(data,
+						W83627EHF_REG_FAN_STOP_OUTPUT[i]);
 			data->fan_stop_time[i] = w83627ehf_read_value(data,
 						W83627EHF_REG_FAN_STOP_TIME[i]);
 			data->target_temp[i] =
@@ -976,7 +989,7 @@ store_pwm_enable(struct device *dev, str
 	u32 val = simple_strtoul(buf, NULL, 10);
 	u16 reg;
 
-	if (!val || (val > 2))	/* only modes 1 and 2 are supported */
+	if (!val || (val > 4))
 		return -EINVAL;
 	mutex_lock(&data->update_lock);
 	reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
@@ -1118,7 +1131,10 @@ store_##reg(struct device *dev, struct d
 	return count; \
 }
 
-fan_functions(fan_min_output, FAN_MIN_OUTPUT)
+fan_functions(fan_start_output, FAN_START_OUTPUT)
+fan_functions(fan_stop_output, FAN_STOP_OUTPUT)
+fan_functions(fan_max_output, FAN_MAX_OUTPUT)
+fan_functions(fan_step_output, FAN_STEP_OUTPUT)
 
 #define fan_time_functions(reg, REG) \
 static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
@@ -1161,8 +1177,14 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
 static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
 	SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
 		    store_fan_stop_time, 3),
-	SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
-		    store_fan_min_output, 3),
+	SENSOR_ATTR(pwm4_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
+		    store_fan_start_output, 3),
+	SENSOR_ATTR(pwm4_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
+		    store_fan_stop_output, 3),
+	SENSOR_ATTR(pwm4_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
+		    store_fan_max_output, 3),
+	SENSOR_ATTR(pwm4_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
+		    store_fan_step_output, 3),
 };
 
 static struct sensor_device_attribute sda_sf3_arrays[] = {
@@ -1172,12 +1194,24 @@ static struct sensor_device_attribute sd
 		    store_fan_stop_time, 1),
 	SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
 		    store_fan_stop_time, 2),
-	SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
-		    store_fan_min_output, 0),
-	SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
-		    store_fan_min_output, 1),
-	SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
-		    store_fan_min_output, 2),
+	SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
+		    store_fan_start_output, 0),
+	SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
+		    store_fan_start_output, 1),
+	SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
+		    store_fan_start_output, 2),
+	SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
+		    store_fan_stop_output, 0),
+	SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
+		    store_fan_stop_output, 1),
+	SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
+		    store_fan_stop_output, 2),
+
+	/* pwm1 and pwm3 don't support max and step settings */
+	SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
+		    store_fan_max_output, 1),
+	SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
+		    store_fan_step_output, 1),
 };
 
 static ssize_t
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83627hf.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83627hf.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83627hf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83627hf.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,10 +59,11 @@ static struct platform_device *pdev;
 #define DRVNAME "w83627hf"
 enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
 
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
-		 "Initialize the base address of the sensors");
+struct w83627hf_sio_data {
+	enum chips type;
+	int sioaddr;
+};
+
 static u8 force_i2c = 0x1f;
 module_param(force_i2c, byte, 0);
 MODULE_PARM_DESC(force_i2c,
@@ -77,9 +78,7 @@ module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
 /* modified from kernel/include/traps.c */
-static int REG;		/* The register to read/write */
 #define	DEV	0x07	/* Register: Logical device select */
-static int VAL;		/* The value to read/write */
 
 /* logical device numbers for superio_select (below) */
 #define W83627HF_LD_FDC		0x00
@@ -109,37 +108,37 @@ static int VAL;		/* The value to read/wr
 #define W83687THF_VID_DATA	0xF1 /* w83687thf only */
 
 static inline void
-superio_outb(int reg, int val)
+superio_outb(struct w83627hf_sio_data *sio, int reg, int val)
 {
-	outb(reg, REG);
-	outb(val, VAL);
+	outb(reg, sio->sioaddr);
+	outb(val, sio->sioaddr + 1);
 }
 
 static inline int
-superio_inb(int reg)
+superio_inb(struct w83627hf_sio_data *sio, int reg)
 {
-	outb(reg, REG);
-	return inb(VAL);
+	outb(reg, sio->sioaddr);
+	return inb(sio->sioaddr + 1);
 }
 
 static inline void
-superio_select(int ld)
+superio_select(struct w83627hf_sio_data *sio, int ld)
 {
-	outb(DEV, REG);
-	outb(ld, VAL);
+	outb(DEV, sio->sioaddr);
+	outb(ld,  sio->sioaddr + 1);
 }
 
 static inline void
-superio_enter(void)
+superio_enter(struct w83627hf_sio_data *sio)
 {
-	outb(0x87, REG);
-	outb(0x87, REG);
+	outb(0x87, sio->sioaddr);
+	outb(0x87, sio->sioaddr);
 }
 
 static inline void
-superio_exit(void)
+superio_exit(struct w83627hf_sio_data *sio)
 {
-	outb(0xAA, REG);
+	outb(0xAA, sio->sioaddr);
 }
 
 #define W627_DEVID 0x52
@@ -380,10 +379,6 @@ struct w83627hf_data {
 	u8 vrm_ovt;		/* Register value, 627THF/637HF/687THF only */
 };
 
-struct w83627hf_sio_data {
-	enum chips type;
-};
-
 
 static int w83627hf_probe(struct platform_device *pdev);
 static int __devexit w83627hf_remove(struct platform_device *pdev);
@@ -1140,11 +1135,9 @@ static int __init w83627hf_find(int sioa
 		"W83687THF",
 	};
 
-	REG = sioaddr;
-	VAL = sioaddr + 1;
-
-	superio_enter();
-	val = force_id ? force_id : superio_inb(DEVID);
+	sio_data->sioaddr = sioaddr;
+	superio_enter(sio_data);
+	val = force_id ? force_id : superio_inb(sio_data, DEVID);
 	switch (val) {
 	case W627_DEVID:
 		sio_data->type = w83627hf;
@@ -1168,16 +1161,9 @@ static int __init w83627hf_find(int sioa
 		goto exit;
 	}
 
-	superio_select(W83627HF_LD_HWM);
-	force_addr &= WINB_ALIGNMENT;
-	if (force_addr) {
-		printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n",
-		       force_addr);
-		superio_outb(WINB_BASE_REG, force_addr >> 8);
-		superio_outb(WINB_BASE_REG + 1, force_addr & 0xff);
-	}
-	val = (superio_inb(WINB_BASE_REG) << 8) |
-	       superio_inb(WINB_BASE_REG + 1);
+	superio_select(sio_data, W83627HF_LD_HWM);
+	val = (superio_inb(sio_data, WINB_BASE_REG) << 8) |
+	       superio_inb(sio_data, WINB_BASE_REG + 1);
 	*addr = val & WINB_ALIGNMENT;
 	if (*addr == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set, "
@@ -1185,10 +1171,10 @@ static int __init w83627hf_find(int sioa
 		goto exit;
 	}
 
-	val = superio_inb(WINB_ACT_REG);
+	val = superio_inb(sio_data, WINB_ACT_REG);
 	if (!(val & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");
-		superio_outb(WINB_ACT_REG, val | 0x01);
+		superio_outb(sio_data, WINB_ACT_REG, val | 0x01);
 	}
 
 	err = 0;
@@ -1196,7 +1182,7 @@ static int __init w83627hf_find(int sioa
 		names[sio_data->type], *addr);
 
  exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return err;
 }
 
@@ -1511,20 +1497,21 @@ static int w83627hf_read_value(struct w8
 
 static int __devinit w83627thf_read_gpio5(struct platform_device *pdev)
 {
+	struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
 	int res = 0xff, sel;
 
-	superio_enter();
-	superio_select(W83627HF_LD_GPIO5);
+	superio_enter(sio_data);
+	superio_select(sio_data, W83627HF_LD_GPIO5);
 
 	/* Make sure these GPIO pins are enabled */
-	if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
+	if (!(superio_inb(sio_data, W83627THF_GPIO5_EN) & (1<<3))) {
 		dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n");
 		goto exit;
 	}
 
 	/* Make sure the pins are configured for input
 	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
-	sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f;
+	sel = superio_inb(sio_data, W83627THF_GPIO5_IOSR) & 0x3f;
 	if ((sel & 0x1f) != 0x1f) {
 		dev_dbg(&pdev->dev, "GPIO5 not configured for VID "
 			"function\n");
@@ -1532,37 +1519,38 @@ static int __devinit w83627thf_read_gpio
 	}
 
 	dev_info(&pdev->dev, "Reading VID from GPIO5\n");
-	res = superio_inb(W83627THF_GPIO5_DR) & sel;
+	res = superio_inb(sio_data, W83627THF_GPIO5_DR) & sel;
 
 exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return res;
 }
 
 static int __devinit w83687thf_read_vid(struct platform_device *pdev)
 {
+	struct w83627hf_sio_data *sio_data = pdev->dev.platform_data;
 	int res = 0xff;
 
-	superio_enter();
-	superio_select(W83627HF_LD_HWM);
+	superio_enter(sio_data);
+	superio_select(sio_data, W83627HF_LD_HWM);
 
 	/* Make sure these GPIO pins are enabled */
-	if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) {
+	if (!(superio_inb(sio_data, W83687THF_VID_EN) & (1 << 2))) {
 		dev_dbg(&pdev->dev, "VID disabled, no VID function\n");
 		goto exit;
 	}
 
 	/* Make sure the pins are configured for input */
-	if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) {
+	if (!(superio_inb(sio_data, W83687THF_VID_CFG) & (1 << 4))) {
 		dev_dbg(&pdev->dev, "VID configured as output, "
 			"no VID function\n");
 		goto exit;
 	}
 
-	res = superio_inb(W83687THF_VID_DATA) & 0x3f;
+	res = superio_inb(sio_data, W83687THF_VID_DATA) & 0x3f;
 
 exit:
-	superio_exit();
+	superio_exit(sio_data);
 	return res;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83781d.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83781d.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83781d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83781d.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,9 +56,10 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
 						0x2e, 0x2f, I2C_CLIENT_END };
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f);
 
+enum chips { w83781d, w83782d, w83783s, as99127f };
+
+/* Insmod parameters */
 static unsigned short force_subclients[4];
 module_param_array(force_subclients, short, NULL, 0);
 MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
@@ -1051,14 +1052,13 @@ w83781d_create_files(struct device *dev,
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-w83781d_detect(struct i2c_client *client, int kind,
-	       struct i2c_board_info *info)
+w83781d_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
-	int val1 = 0, val2;
+	int val1, val2;
 	struct w83781d_data *isa = w83781d_data_if_isa();
 	struct i2c_adapter *adapter = client->adapter;
 	int address = client->addr;
-	const char *client_name = "";
+	const char *client_name;
 	enum vendor { winbond, asus } vendid;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -1070,98 +1070,73 @@ w83781d_detect(struct i2c_client *client
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
-	/* The w8378?d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the Winbond will be reset to the right
-	   bank. */
-	if (kind < 0) {
-		if (i2c_smbus_read_byte_data
-		    (client, W83781D_REG_CONFIG) & 0x80) {
-			dev_dbg(&adapter->dev, "Detection of w83781d chip "
-				"failed at step 3\n");
-			goto err_nodev;
-		}
-		val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
-		val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
-		/* Check for Winbond or Asus ID if in bank 0 */
-		if ((!(val1 & 0x07)) &&
-		    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
-		     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
-			dev_dbg(&adapter->dev, "Detection of w83781d chip "
-				"failed at step 4\n");
+	if (i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG) & 0x80) {
+		dev_dbg(&adapter->dev,
+			"Detection of w83781d chip failed at step 3\n");
+		goto err_nodev;
+	}
+
+	val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
+	val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
+	/* Check for Winbond or Asus ID if in bank 0 */
+	if (!(val1 & 0x07) &&
+	    ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) ||
+	     ( (val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) {
+		dev_dbg(&adapter->dev,
+			"Detection of w83781d chip failed at step 4\n");
+		goto err_nodev;
+	}
+	/* If Winbond SMBus, check address at 0x48.
+	   Asus doesn't support, except for as99127f rev.2 */
+	if ((!(val1 & 0x80) && val2 == 0xa3) ||
+	    ( (val1 & 0x80) && val2 == 0x5c)) {
+		if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR)
+		    != address) {
+			dev_dbg(&adapter->dev,
+				"Detection of w83781d chip failed at step 5\n");
 			goto err_nodev;
 		}
-		/* If Winbond SMBus, check address at 0x48.
-		   Asus doesn't support, except for as99127f rev.2 */
-		if ((!(val1 & 0x80) && (val2 == 0xa3)) ||
-		    ((val1 & 0x80) && (val2 == 0x5c))) {
-			if (i2c_smbus_read_byte_data
-			    (client, W83781D_REG_I2C_ADDR) != address) {
-				dev_dbg(&adapter->dev, "Detection of w83781d "
-					"chip failed at step 5\n");
-				goto err_nodev;
-			}
-		}
 	}
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	/* Put it now into bank 0 and Vendor ID High Byte */
 	i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
 		(i2c_smbus_read_byte_data(client, W83781D_REG_BANK)
 		 & 0x78) | 0x80);
 
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
-		if (val2 == 0x5c)
-			vendid = winbond;
-		else if (val2 == 0x12)
-			vendid = asus;
-		else {
-			dev_dbg(&adapter->dev, "w83781d chip vendor is "
-				"neither Winbond nor Asus\n");
-			goto err_nodev;
-		}
-
-		val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
-		if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
-			kind = w83781d;
-		else if (val1 == 0x30 && vendid == winbond)
-			kind = w83782d;
-		else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
-			kind = w83783s;
-		else if (val1 == 0x31)
-			kind = as99127f;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "Ignoring 'force' "
-					 "parameter for unknown chip at "
-					 "address 0x%02x\n", address);
-			goto err_nodev;
-		}
-
-		if ((kind == w83781d || kind == w83782d)
-		 && w83781d_alias_detect(client, val1)) {
-			dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
-				"be the same as ISA device\n", address);
-			goto err_nodev;
-		}
+	/* Get the vendor ID */
+	val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
+	if (val2 == 0x5c)
+		vendid = winbond;
+	else if (val2 == 0x12)
+		vendid = asus;
+	else {
+		dev_dbg(&adapter->dev,
+			"w83781d chip vendor is neither Winbond nor Asus\n");
+		goto err_nodev;
 	}
 
-	if (isa)
-		mutex_unlock(&isa->update_lock);
-
-	if (kind == w83781d) {
+	/* Determine the chip type. */
+	val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
+	if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
 		client_name = "w83781d";
-	} else if (kind == w83782d) {
+	else if (val1 == 0x30 && vendid == winbond)
 		client_name = "w83782d";
-	} else if (kind == w83783s) {
+	else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
 		client_name = "w83783s";
-	} else if (kind == as99127f) {
+	else if (val1 == 0x31)
 		client_name = "as99127f";
+	else
+		goto err_nodev;
+
+	if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) {
+		dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+			"be the same as ISA device\n", address);
+		goto err_nodev;
 	}
 
+	if (isa)
+		mutex_unlock(&isa->update_lock);
+
 	strlcpy(info->type, client_name, I2C_NAME_SIZE);
 
 	return 0;
@@ -1562,7 +1537,7 @@ static struct i2c_driver w83781d_driver
 	.remove		= w83781d_remove,
 	.id_table	= w83781d_ids,
 	.detect		= w83781d_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -1818,17 +1793,17 @@ static int __init
 w83781d_isa_found(unsigned short address)
 {
 	int val, save, found = 0;
+	int port;
 
-	/* We have to request the region in two parts because some
-	   boards declare base+4 to base+7 as a PNP device */
-	if (!request_region(address, 4, "w83781d")) {
-		pr_debug("w83781d: Failed to request low part of region\n");
-		return 0;
-	}
-	if (!request_region(address + 4, 4, "w83781d")) {
-		pr_debug("w83781d: Failed to request high part of region\n");
-		release_region(address, 4);
-		return 0;
+	/* Some boards declare base+0 to base+7 as a PNP device, some base+4
+	 * to base+7 and some base+5 to base+6. So we better request each port
+	 * individually for the probing phase. */
+	for (port = address; port < address + W83781D_EXTENT; port++) {
+		if (!request_region(port, 1, "w83781d")) {
+			pr_debug("w83781d: Failed to request port 0x%x\n",
+				 port);
+			goto release;
+		}
 	}
 
 #define REALLY_SLOW_IO
@@ -1902,8 +1877,8 @@ w83781d_isa_found(unsigned short address
 			val == 0x30 ? "W83782D" : "W83781D", (int)address);
 
  release:
-	release_region(address + 4, 4);
-	release_region(address, 4);
+	for (port--; port >= address; port--)
+		release_region(port, 1);
 	return found;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83791d.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83791d.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83791d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83791d.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,6 @@ static const unsigned short normal_i2c[]
 						I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(w83791d);
 
 static unsigned short force_subclients[4];
 module_param_array(force_subclients, short, NULL, 0);
@@ -326,7 +325,7 @@ struct w83791d_data {
 
 static int w83791d_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int w83791d_detect(struct i2c_client *client, int kind,
+static int w83791d_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int w83791d_remove(struct i2c_client *client);
 
@@ -341,7 +340,7 @@ static void w83791d_print_debug(struct w
 static void w83791d_init_client(struct i2c_client *client);
 
 static const struct i2c_device_id w83791d_id[] = {
-	{ "w83791d", w83791d },
+	{ "w83791d", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, w83791d_id);
@@ -355,7 +354,7 @@ static struct i2c_driver w83791d_driver
 	.remove		= w83791d_remove,
 	.id_table	= w83791d_id,
 	.detect		= w83791d_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /* following are the sysfs callback functions */
@@ -1259,7 +1258,7 @@ error_sc_0:
 
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int w83791d_detect(struct i2c_client *client, int kind,
+static int w83791d_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -1270,56 +1269,32 @@ static int w83791d_detect(struct i2c_cli
 		return -ENODEV;
 	}
 
-	/* The w83791d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=...
-	   parameter, and the Winbond will be reset to the right bank. */
-	if (kind < 0) {
-		if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) {
-			return -ENODEV;
-		}
-		val1 = w83791d_read(client, W83791D_REG_BANK);
-		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
-		/* Check for Winbond ID if in bank 0 */
-		if (!(val1 & 0x07)) {
-			/* yes it is Bank0 */
-			if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
-			    ((val1 & 0x80) && (val2 != 0x5c))) {
-				return -ENODEV;
-			}
-		}
-		/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
-		   should match */
-		if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) {
+	if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80)
+		return -ENODEV;
+
+	val1 = w83791d_read(client, W83791D_REG_BANK);
+	val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+	/* Check for Winbond ID if in bank 0 */
+	if (!(val1 & 0x07)) {
+		if ((!(val1 & 0x80) && val2 != 0xa3) ||
+		    ( (val1 & 0x80) && val2 != 0x5c)) {
 			return -ENODEV;
 		}
 	}
+	/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
+	   should match */
+	if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address)
+		return -ENODEV;
 
-	/* We either have a force parameter or we have reason to
-	   believe it is a Winbond chip. Either way, we want bank 0 and
-	   Vendor ID high byte */
+	/* We want bank 0 and Vendor ID high byte */
 	val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78;
 	w83791d_write(client, W83791D_REG_BANK, val1 | 0x80);
 
 	/* Verify it is a Winbond w83791d */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
-		if (val2 != 0x5c) {	/* the vendor is NOT Winbond */
-			return -ENODEV;
-		}
-		val1 = w83791d_read(client, W83791D_REG_WCHIPID);
-		if (val1 == 0x71) {
-			kind = w83791d;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev,
-					"w83791d: Ignoring 'force' parameter "
-					"for unknown chip at adapter %d, "
-					"address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			return -ENODEV;
-		}
-	}
+	val1 = w83791d_read(client, W83791D_REG_WCHIPID);
+	val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+	if (val1 != 0x71 || val2 != 0x5c)
+		return -ENODEV;
 
 	strlcpy(info->type, "w83791d", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83792d.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83792d.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83792d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83792d.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,6 @@ static const unsigned short normal_i2c[]
 						I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(w83792d);
 
 static unsigned short force_subclients[4];
 module_param_array(force_subclients, short, NULL, 0);
@@ -302,7 +301,7 @@ struct w83792d_data {
 
 static int w83792d_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int w83792d_detect(struct i2c_client *client, int kind,
+static int w83792d_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int w83792d_remove(struct i2c_client *client);
 static struct w83792d_data *w83792d_update_device(struct device *dev);
@@ -314,7 +313,7 @@ static void w83792d_print_debug(struct w
 static void w83792d_init_client(struct i2c_client *client);
 
 static const struct i2c_device_id w83792d_id[] = {
-	{ "w83792d", w83792d },
+	{ "w83792d", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, w83792d_id);
@@ -328,7 +327,7 @@ static struct i2c_driver w83792d_driver
 	.remove		= w83792d_remove,
 	.id_table	= w83792d_id,
 	.detect		= w83792d_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static inline long in_count_from_reg(int nr, struct w83792d_data *data)
@@ -1263,7 +1262,7 @@ static const struct attribute_group w837
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int
-w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
+w83792d_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	int val1, val2;
@@ -1273,58 +1272,33 @@ w83792d_detect(struct i2c_client *client
 		return -ENODEV;
 	}
 
-	/* The w83792d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the Winbond will be reset to the right
-	   bank. */
-	if (kind < 0) {
-		if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
-			return -ENODEV;
-		}
-		val1 = w83792d_read_value(client, W83792D_REG_BANK);
-		val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
-		/* Check for Winbond ID if in bank 0 */
-		if (!(val1 & 0x07)) {  /* is Bank0 */
-			if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
-			     ((val1 & 0x80) && (val2 != 0x5c))) {
-				return -ENODEV;
-			}
-		}
-		/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
-		   should match */
-		if (w83792d_read_value(client,
-					W83792D_REG_I2C_ADDR) != address) {
+	if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80)
+		return -ENODEV;
+
+	val1 = w83792d_read_value(client, W83792D_REG_BANK);
+	val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
+	/* Check for Winbond ID if in bank 0 */
+	if (!(val1 & 0x07)) {  /* is Bank0 */
+		if ((!(val1 & 0x80) && val2 != 0xa3) ||
+		    ( (val1 & 0x80) && val2 != 0x5c))
 			return -ENODEV;
-		}
 	}
+	/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
+	   should match */
+	if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address)
+		return -ENODEV;
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	/*  Put it now into bank 0 and Vendor ID High Byte */
 	w83792d_write_value(client,
 			    W83792D_REG_BANK,
 			    (w83792d_read_value(client,
 				W83792D_REG_BANK) & 0x78) | 0x80);
 
 	/* Determine the chip type. */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
-		if (val2 != 0x5c) {  /* the vendor is NOT Winbond */
-			return -ENODEV;
-		}
-		val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
-		if (val1 == 0x7a) {
-			kind = w83792d;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev,
-					"w83792d: Ignoring 'force' parameter for"
-					" unknown chip at adapter %d, address"
-					" 0x%02x\n", i2c_adapter_id(adapter),
-					address);
-			return -ENODEV;
-		}
-	}
+	val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
+	val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
+	if (val1 != 0x7a || val2 != 0x5c)
+		return -ENODEV;
 
 	strlcpy(info->type, "w83792d", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83793.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83793.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83793.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83793.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,7 +41,6 @@ static const unsigned short normal_i2c[]
 						I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(w83793);
 
 static unsigned short force_subclients[4];
 module_param_array(force_subclients, short, NULL, 0);
@@ -230,7 +229,7 @@ static u8 w83793_read_value(struct i2c_c
 static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
 static int w83793_probe(struct i2c_client *client,
 			const struct i2c_device_id *id);
-static int w83793_detect(struct i2c_client *client, int kind,
+static int w83793_detect(struct i2c_client *client,
 			 struct i2c_board_info *info);
 static int w83793_remove(struct i2c_client *client);
 static void w83793_init_client(struct i2c_client *client);
@@ -238,7 +237,7 @@ static void w83793_update_nonvolatile(st
 static struct w83793_data *w83793_update_device(struct device *dev);
 
 static const struct i2c_device_id w83793_id[] = {
-	{ "w83793", w83793 },
+	{ "w83793", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, w83793_id);
@@ -252,7 +251,7 @@ static struct i2c_driver w83793_driver =
 	.remove		= w83793_remove,
 	.id_table	= w83793_id,
 	.detect		= w83793_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static ssize_t
@@ -1161,10 +1160,10 @@ ERROR_SC_0:
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int w83793_detect(struct i2c_client *client, int kind,
+static int w83793_detect(struct i2c_client *client,
 			 struct i2c_board_info *info)
 {
-	u8 tmp, bank;
+	u8 tmp, bank, chip_id;
 	struct i2c_adapter *adapter = client->adapter;
 	unsigned short address = client->addr;
 
@@ -1174,44 +1173,27 @@ static int w83793_detect(struct i2c_clie
 
 	bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
 
-	if (kind < 0) {
-		tmp = bank & 0x80 ? 0x5c : 0xa3;
-		/* Check Winbond vendor ID */
-		if (tmp != i2c_smbus_read_byte_data(client,
-							W83793_REG_VENDORID)) {
-			pr_debug("w83793: Detection failed at check "
-				 "vendor id\n");
-			return -ENODEV;
-		}
-
-		/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
-		   should match */
-		if ((bank & 0x07) == 0
-		 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
-		    (address << 1)) {
-			pr_debug("w83793: Detection failed at check "
-				 "i2c addr\n");
-			return -ENODEV;
-		}
-
+	tmp = bank & 0x80 ? 0x5c : 0xa3;
+	/* Check Winbond vendor ID */
+	if (tmp != i2c_smbus_read_byte_data(client, W83793_REG_VENDORID)) {
+		pr_debug("w83793: Detection failed at check vendor id\n");
+		return -ENODEV;
 	}
 
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Determine the chip type now */
-
-	if (kind <= 0) {
-		if (0x7b == i2c_smbus_read_byte_data(client,
-						     W83793_REG_CHIPID)) {
-			kind = w83793;
-		} else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "w83793: Ignoring "
-					 "'force' parameter for unknown chip "
-					 "at address 0x%02x\n", address);
-			return -ENODEV;
-		}
+	/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
+	   should match */
+	if ((bank & 0x07) == 0
+	 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
+	    (address << 1)) {
+		pr_debug("w83793: Detection failed at check i2c addr\n");
+		return -ENODEV;
 	}
 
+	/* Determine the chip type now */
+	chip_id = i2c_smbus_read_byte_data(client, W83793_REG_CHIPID);
+	if (chip_id != 0x7b)
+		return -ENODEV;
+
 	strlcpy(info->type, "w83793", I2C_NAME_SIZE);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83l785ts.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83l785ts.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83l785ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83l785ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * w83l785ts.c - Part of lm_sensors, Linux kernel modules for hardware
  *               monitoring
- * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2009  Jean Delvare <khali@linux-fr.org>
  *
  * Inspired from the lm83 driver. The W83L785TS-S is a sensor chip made
  * by Winbond. It reports a single external temperature with a 1 deg
@@ -52,12 +52,6 @@
 static const unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
 
 /*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_1(w83l785ts);
-
-/*
  * The W83L785TS-S registers
  * Manufacturer ID is 0x5CA3 for Winbond.
  */
@@ -83,7 +77,7 @@ I2C_CLIENT_INSMOD_1(w83l785ts);
 
 static int w83l785ts_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id);
-static int w83l785ts_detect(struct i2c_client *client, int kind,
+static int w83l785ts_detect(struct i2c_client *client,
 			    struct i2c_board_info *info);
 static int w83l785ts_remove(struct i2c_client *client);
 static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval);
@@ -94,7 +88,7 @@ static struct w83l785ts_data *w83l785ts_
  */
  
 static const struct i2c_device_id w83l785ts_id[] = {
-	{ "w83l785ts", w83l785ts },
+	{ "w83l785ts", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, w83l785ts_id);
@@ -108,7 +102,7 @@ static struct i2c_driver w83l785ts_drive
 	.remove		= w83l785ts_remove,
 	.id_table	= w83l785ts_id,
 	.detect		= w83l785ts_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 /*
@@ -146,60 +140,36 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_I
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int w83l785ts_detect(struct i2c_client *new_client, int kind,
+static int w83l785ts_detect(struct i2c_client *client,
 			    struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
+	struct i2c_adapter *adapter = client->adapter;
+	u16 man_id;
+	u8 chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, W83L785TS-S). A zero kind means
-	 * that the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		if (((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_CONFIG, 0) & 0x80) != 0x00)
-		 || ((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"W83L785TS-S detection failed at 0x%02x.\n",
-				new_client->addr);
-			return -ENODEV;
-		}
+	/* detection */
+	if ((w83l785ts_read_value(client, W83L785TS_REG_CONFIG, 0) & 0x80)
+	 || (w83l785ts_read_value(client, W83L785TS_REG_TYPE, 0) & 0xFC)) {
+		dev_dbg(&adapter->dev,
+			"W83L785TS-S detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u16 man_id;
-		u8 chip_id;
-
-		man_id = (w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID1, 0) << 8) +
-			 w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID2, 0);
-		chip_id = w83l785ts_read_value(new_client,
-			  W83L785TS_REG_CHIP_ID, 0);
+	/* Identification */
+	man_id = (w83l785ts_read_value(client, W83L785TS_REG_MAN_ID1, 0) << 8)
+	       + w83l785ts_read_value(client, W83L785TS_REG_MAN_ID2, 0);
+	chip_id = w83l785ts_read_value(client, W83L785TS_REG_CHIP_ID, 0);
 
-		if (man_id == 0x5CA3) { /* Winbond */
-			if (chip_id == 0x70) { /* W83L785TS-S */
-				kind = w83l785ts;			
-			}
-		}
-	
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-				 "Unsupported chip (man_id=0x%04X, "
-				 "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x5CA3		/* Winbond */
+	 || chip_id != 0x70) {		/* W83L785TS-S */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%04X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "w83l785ts", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/hwmon/w83l786ng.c linux-libre-2.6.33-gnu1/drivers/hwmon/w83l786ng.c
--- linux-libre-2.6.32-gnu1/drivers/hwmon/w83l786ng.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/hwmon/w83l786ng.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,6 @@
 static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
 
 /* Insmod parameters */
-I2C_CLIENT_INSMOD_1(w83l786ng);
 
 static int reset;
 module_param(reset, bool, 0);
@@ -147,14 +146,14 @@ struct w83l786ng_data {
 
 static int w83l786ng_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id);
-static int w83l786ng_detect(struct i2c_client *client, int kind,
+static int w83l786ng_detect(struct i2c_client *client,
 			    struct i2c_board_info *info);
 static int w83l786ng_remove(struct i2c_client *client);
 static void w83l786ng_init_client(struct i2c_client *client);
 static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
 
 static const struct i2c_device_id w83l786ng_id[] = {
-	{ "w83l786ng", w83l786ng },
+	{ "w83l786ng", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
@@ -168,7 +167,7 @@ static struct i2c_driver w83l786ng_drive
 	.remove		= w83l786ng_remove,
 	.id_table	= w83l786ng_id,
 	.detect		= w83l786ng_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static u8
@@ -586,57 +585,34 @@ static const struct attribute_group w83l
 };
 
 static int
-w83l786ng_detect(struct i2c_client *client, int kind,
-		 struct i2c_board_info *info)
+w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	u16 man_id;
+	u8 chip_id;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		return -ENODEV;
 	}
 
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, W83L786NG). A zero kind means
-	 * that the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		if (((w83l786ng_read_value(client,
-		    W83L786NG_REG_CONFIG) & 0x80) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"W83L786NG detection failed at 0x%02x.\n",
-				client->addr);
-			return -ENODEV;
-		}
+	/* Detection */
+	if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) {
+		dev_dbg(&adapter->dev, "W83L786NG detection failed at 0x%02x\n",
+			client->addr);
+		return -ENODEV;
 	}
 
-	if (kind <= 0) { /* identification */
-		u16 man_id;
-		u8 chip_id;
-
-		man_id = (w83l786ng_read_value(client,
-		    W83L786NG_REG_MAN_ID1) << 8) +
-		    w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2);
-		chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID);
-
-		if (man_id == 0x5CA3) { /* Winbond */
-			if (chip_id == 0x80) { /* W83L786NG */
-				kind = w83l786ng;
-			}
-		}
+	/* Identification */
+	man_id = (w83l786ng_read_value(client, W83L786NG_REG_MAN_ID1) << 8) +
+		 w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2);
+	chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID);
 
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%04X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			return -ENODEV;
-		}
+	if (man_id != 0x5CA3 ||		/* Winbond */
+	    chip_id != 0x80) {		/* W83L786NG */
+		dev_dbg(&adapter->dev,
+			"Unsupported chip (man_id=0x%04X, chip_id=0x%02X)\n",
+			man_id, chip_id);
+		return -ENODEV;
 	}
 
 	strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali1535.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1535.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali1535.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1535.c	2010-02-24 13:52:17.000000000 -0500
@@ -138,7 +138,7 @@ static unsigned short ali1535_smba;
    Note the differences between kernels with the old PCI BIOS interface and
    newer kernels with the real PCI interface. In compat.h some things are
    defined to make the transition easier. */
-static int ali1535_setup(struct pci_dev *dev)
+static int __devinit ali1535_setup(struct pci_dev *dev)
 {
 	int retval = -ENODEV;
 	unsigned char temp;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali1563.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1563.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali1563.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali1563.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,9 +87,9 @@ static int ali1563_transaction(struct i2
 	outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
 
 	timeout = ALI1563_MAX_TIMEOUT;
-	do
+	do {
 		msleep(1);
-	while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout);
+	} while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout);
 
 	dev_dbg(&a->dev, "Transaction (post): STS=%02x, CNTL1=%02x, "
 		"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
@@ -157,9 +157,9 @@ static int ali1563_block_start(struct i2
 	outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
 
 	timeout = ALI1563_MAX_TIMEOUT;
-	do
+	do {
 		msleep(1);
-	while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout);
+	} while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout);
 
 	dev_dbg(&a->dev, "Block (post): STS=%02x, CNTL1=%02x, "
 		"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali15x3.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali15x3.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,7 +131,7 @@ MODULE_PARM_DESC(force_addr,
 static struct pci_driver ali15x3_driver;
 static unsigned short ali15x3_smba;
 
-static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
+static int __devinit ali15x3_setup(struct pci_dev *ALI15X3_dev)
 {
 	u16 a;
 	unsigned char temp;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-bfin-twi.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-bfin-twi.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-bfin-twi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-bfin-twi.c	2010-02-24 13:52:17.000000000 -0500
@@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct pla
 	}
 
 	/* Set TWI internal clock as 10MHz */
-	write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
+	write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F);
 
 	/*
 	 * We will not end up with a CLKDIV=0 because no one will specify
-	 * 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100)
+	 * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)
 	 */
-	clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ;
+	clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2;
 
 	/* Set Twi interface clock as specified */
 	write_CLKDIV(iface, (clkhilow << 8) | clkhilow);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-designware.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-designware.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-designware.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-designware.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Synopsys Designware I2C adapter driver (master only).
+ * Synopsys DesignWare I2C adapter driver (master only).
  *
  * Based on the TI DAVINCI I2C adapter driver.
  *
@@ -49,7 +49,20 @@
 #define DW_IC_FS_SCL_LCNT	0x20
 #define DW_IC_INTR_STAT		0x2c
 #define DW_IC_INTR_MASK		0x30
+#define DW_IC_RAW_INTR_STAT	0x34
+#define DW_IC_RX_TL		0x38
+#define DW_IC_TX_TL		0x3c
 #define DW_IC_CLR_INTR		0x40
+#define DW_IC_CLR_RX_UNDER	0x44
+#define DW_IC_CLR_RX_OVER	0x48
+#define DW_IC_CLR_TX_OVER	0x4c
+#define DW_IC_CLR_RD_REQ	0x50
+#define DW_IC_CLR_TX_ABRT	0x54
+#define DW_IC_CLR_RX_DONE	0x58
+#define DW_IC_CLR_ACTIVITY	0x5c
+#define DW_IC_CLR_STOP_DET	0x60
+#define DW_IC_CLR_START_DET	0x64
+#define DW_IC_CLR_GEN_CALL	0x68
 #define DW_IC_ENABLE		0x6c
 #define DW_IC_STATUS		0x70
 #define DW_IC_TXFLR		0x74
@@ -64,9 +77,23 @@
 #define DW_IC_CON_RESTART_EN		0x20
 #define DW_IC_CON_SLAVE_DISABLE		0x40
 
-#define DW_IC_INTR_TX_EMPTY	0x10
-#define DW_IC_INTR_TX_ABRT	0x40
+#define DW_IC_INTR_RX_UNDER	0x001
+#define DW_IC_INTR_RX_OVER	0x002
+#define DW_IC_INTR_RX_FULL	0x004
+#define DW_IC_INTR_TX_OVER	0x008
+#define DW_IC_INTR_TX_EMPTY	0x010
+#define DW_IC_INTR_RD_REQ	0x020
+#define DW_IC_INTR_TX_ABRT	0x040
+#define DW_IC_INTR_RX_DONE	0x080
+#define DW_IC_INTR_ACTIVITY	0x100
 #define DW_IC_INTR_STOP_DET	0x200
+#define DW_IC_INTR_START_DET	0x400
+#define DW_IC_INTR_GEN_CALL	0x800
+
+#define DW_IC_INTR_DEFAULT_MASK		(DW_IC_INTR_RX_FULL | \
+					 DW_IC_INTR_TX_EMPTY | \
+					 DW_IC_INTR_TX_ABRT | \
+					 DW_IC_INTR_STOP_DET)
 
 #define DW_IC_STATUS_ACTIVITY	0x1
 
@@ -96,31 +123,49 @@
 #define ABRT_SBYTE_ACKDET	7
 #define ABRT_SBYTE_NORSTRT	9
 #define ABRT_10B_RD_NORSTRT	10
-#define ARB_MASTER_DIS		11
+#define ABRT_MASTER_DIS		11
 #define ARB_LOST		12
 
+#define DW_IC_TX_ABRT_7B_ADDR_NOACK	(1UL << ABRT_7B_ADDR_NOACK)
+#define DW_IC_TX_ABRT_10ADDR1_NOACK	(1UL << ABRT_10ADDR1_NOACK)
+#define DW_IC_TX_ABRT_10ADDR2_NOACK	(1UL << ABRT_10ADDR2_NOACK)
+#define DW_IC_TX_ABRT_TXDATA_NOACK	(1UL << ABRT_TXDATA_NOACK)
+#define DW_IC_TX_ABRT_GCALL_NOACK	(1UL << ABRT_GCALL_NOACK)
+#define DW_IC_TX_ABRT_GCALL_READ	(1UL << ABRT_GCALL_READ)
+#define DW_IC_TX_ABRT_SBYTE_ACKDET	(1UL << ABRT_SBYTE_ACKDET)
+#define DW_IC_TX_ABRT_SBYTE_NORSTRT	(1UL << ABRT_SBYTE_NORSTRT)
+#define DW_IC_TX_ABRT_10B_RD_NORSTRT	(1UL << ABRT_10B_RD_NORSTRT)
+#define DW_IC_TX_ABRT_MASTER_DIS	(1UL << ABRT_MASTER_DIS)
+#define DW_IC_TX_ARB_LOST		(1UL << ARB_LOST)
+
+#define DW_IC_TX_ABRT_NOACK		(DW_IC_TX_ABRT_7B_ADDR_NOACK | \
+					 DW_IC_TX_ABRT_10ADDR1_NOACK | \
+					 DW_IC_TX_ABRT_10ADDR2_NOACK | \
+					 DW_IC_TX_ABRT_TXDATA_NOACK | \
+					 DW_IC_TX_ABRT_GCALL_NOACK)
+
 static char *abort_sources[] = {
-	[ABRT_7B_ADDR_NOACK]	=
+	[ABRT_7B_ADDR_NOACK] =
 		"slave address not acknowledged (7bit mode)",
-	[ABRT_10ADDR1_NOACK]	=
+	[ABRT_10ADDR1_NOACK] =
 		"first address byte not acknowledged (10bit mode)",
-	[ABRT_10ADDR2_NOACK]	=
+	[ABRT_10ADDR2_NOACK] =
 		"second address byte not acknowledged (10bit mode)",
-	[ABRT_TXDATA_NOACK]		=
+	[ABRT_TXDATA_NOACK] =
 		"data not acknowledged",
-	[ABRT_GCALL_NOACK]		=
+	[ABRT_GCALL_NOACK] =
 		"no acknowledgement for a general call",
-	[ABRT_GCALL_READ]		=
+	[ABRT_GCALL_READ] =
 		"read after general call",
-	[ABRT_SBYTE_ACKDET]		=
+	[ABRT_SBYTE_ACKDET] =
 		"start byte acknowledged",
-	[ABRT_SBYTE_NORSTRT]	=
+	[ABRT_SBYTE_NORSTRT] =
 		"trying to send start byte when restart is disabled",
-	[ABRT_10B_RD_NORSTRT]	=
+	[ABRT_10B_RD_NORSTRT] =
 		"trying to read when restart is disabled (10bit mode)",
-	[ARB_MASTER_DIS]		=
+	[ABRT_MASTER_DIS] =
 		"trying to use disabled adapter",
-	[ARB_LOST]			=
+	[ARB_LOST] =
 		"lost arbitration",
 };
 
@@ -129,7 +174,6 @@ static char *abort_sources[] = {
  * @dev: driver model device node
  * @base: IO registers pointer
  * @cmd_complete: tx completion indicator
- * @pump_msg: continue in progress transfers
  * @lock: protect this struct and IO registers
  * @clk: input reference clock
  * @cmd_err: run time hadware error code
@@ -155,27 +199,81 @@ struct dw_i2c_dev {
 	struct device		*dev;
 	void __iomem		*base;
 	struct completion	cmd_complete;
-	struct tasklet_struct	pump_msg;
 	struct mutex		lock;
 	struct clk		*clk;
 	int			cmd_err;
 	struct i2c_msg		*msgs;
 	int			msgs_num;
 	int			msg_write_idx;
-	u16			tx_buf_len;
+	u32			tx_buf_len;
 	u8			*tx_buf;
 	int			msg_read_idx;
-	u16			rx_buf_len;
+	u32			rx_buf_len;
 	u8			*rx_buf;
 	int			msg_err;
 	unsigned int		status;
-	u16			abort_source;
+	u32			abort_source;
 	int			irq;
 	struct i2c_adapter	adapter;
 	unsigned int		tx_fifo_depth;
 	unsigned int		rx_fifo_depth;
 };
 
+static u32
+i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
+{
+	/*
+	 * DesignWare I2C core doesn't seem to have solid strategy to meet
+	 * the tHD;STA timing spec.  Configuring _HCNT based on tHIGH spec
+	 * will result in violation of the tHD;STA spec.
+	 */
+	if (cond)
+		/*
+		 * Conditional expression:
+		 *
+		 *   IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH
+		 *
+		 * This is based on the DW manuals, and represents an ideal
+		 * configuration.  The resulting I2C bus speed will be
+		 * faster than any of the others.
+		 *
+		 * If your hardware is free from tHD;STA issue, try this one.
+		 */
+		return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset;
+	else
+		/*
+		 * Conditional expression:
+		 *
+		 *   IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf)
+		 *
+		 * This is just experimental rule; the tHD;STA period turned
+		 * out to be proportinal to (_HCNT + 3).  With this setting,
+		 * we could meet both tHIGH and tHD;STA timing specs.
+		 *
+		 * If unsure, you'd better to take this alternative.
+		 *
+		 * The reason why we need to take into account "tf" here,
+		 * is the same as described in i2c_dw_scl_lcnt().
+		 */
+		return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset;
+}
+
+static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
+{
+	/*
+	 * Conditional expression:
+	 *
+	 *   IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf)
+	 *
+	 * DW I2C core starts counting the SCL CNTs for the LOW period
+	 * of the SCL clock (tLOW) as soon as it pulls the SCL line.
+	 * In order to meet the tLOW timing spec, we need to take into
+	 * account the fall time of SCL signal (tf).  Default tf value
+	 * should be 0.3 us, for safety.
+	 */
+	return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset;
+}
+
 /**
  * i2c_dw_init() - initialize the designware i2c master hardware
  * @dev: device private data
@@ -187,25 +285,49 @@ struct dw_i2c_dev {
 static void i2c_dw_init(struct dw_i2c_dev *dev)
 {
 	u32 input_clock_khz = clk_get_rate(dev->clk) / 1000;
-	u16 ic_con;
+	u32 ic_con, hcnt, lcnt;
 
 	/* Disable the adapter */
-	writeb(0, dev->base + DW_IC_ENABLE);
+	writel(0, dev->base + DW_IC_ENABLE);
 
 	/* set standard and fast speed deviders for high/low periods */
-	writew((input_clock_khz * 40 / 10000)+1, /* std speed high, 4us */
-			dev->base + DW_IC_SS_SCL_HCNT);
-	writew((input_clock_khz * 47 / 10000)+1, /* std speed low, 4.7us */
-			dev->base + DW_IC_SS_SCL_LCNT);
-	writew((input_clock_khz *  6 / 10000)+1, /* fast speed high, 0.6us */
-			dev->base + DW_IC_FS_SCL_HCNT);
-	writew((input_clock_khz * 13 / 10000)+1, /* fast speed low, 1.3us */
-			dev->base + DW_IC_FS_SCL_LCNT);
+
+	/* Standard-mode */
+	hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+				40,	/* tHD;STA = tHIGH = 4.0 us */
+				3,	/* tf = 0.3 us */
+				0,	/* 0: DW default, 1: Ideal */
+				0);	/* No offset */
+	lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+				47,	/* tLOW = 4.7 us */
+				3,	/* tf = 0.3 us */
+				0);	/* No offset */
+	writel(hcnt, dev->base + DW_IC_SS_SCL_HCNT);
+	writel(lcnt, dev->base + DW_IC_SS_SCL_LCNT);
+	dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
+
+	/* Fast-mode */
+	hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+				6,	/* tHD;STA = tHIGH = 0.6 us */
+				3,	/* tf = 0.3 us */
+				0,	/* 0: DW default, 1: Ideal */
+				0);	/* No offset */
+	lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+				13,	/* tLOW = 1.3 us */
+				3,	/* tf = 0.3 us */
+				0);	/* No offset */
+	writel(hcnt, dev->base + DW_IC_FS_SCL_HCNT);
+	writel(lcnt, dev->base + DW_IC_FS_SCL_LCNT);
+	dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
+
+	/* Configure Tx/Rx FIFO threshold levels */
+	writel(dev->tx_fifo_depth - 1, dev->base + DW_IC_TX_TL);
+	writel(0, dev->base + DW_IC_RX_TL);
 
 	/* configure the i2c master */
 	ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
 		DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
-	writew(ic_con, dev->base + DW_IC_CON);
+	writel(ic_con, dev->base + DW_IC_CON);
 }
 
 /*
@@ -215,7 +337,7 @@ static int i2c_dw_wait_bus_not_busy(stru
 {
 	int timeout = TIMEOUT;
 
-	while (readb(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
+	while (readl(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) {
 		if (timeout <= 0) {
 			dev_warn(dev->dev, "timeout waiting for bus ready\n");
 			return -ETIMEDOUT;
@@ -227,106 +349,125 @@ static int i2c_dw_wait_bus_not_busy(stru
 	return 0;
 }
 
-/*
- * Initiate low level master read/write transaction.
- * This function is called from i2c_dw_xfer when starting a transfer.
- * This function is also called from dw_i2c_pump_msg to continue a transfer
- * that is longer than the size of the TX FIFO.
- */
-static void
-i2c_dw_xfer_msg(struct i2c_adapter *adap)
+static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
 	struct i2c_msg *msgs = dev->msgs;
-	int num = dev->msgs_num;
-	u16 ic_con, intr_mask;
-	int tx_limit = dev->tx_fifo_depth - readb(dev->base + DW_IC_TXFLR);
-	int rx_limit = dev->rx_fifo_depth - readb(dev->base + DW_IC_RXFLR);
-	u16 addr = msgs[dev->msg_write_idx].addr;
-	u16 buf_len = dev->tx_buf_len;
+	u32 ic_con;
 
-	if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
-		/* Disable the adapter */
-		writeb(0, dev->base + DW_IC_ENABLE);
+	/* Disable the adapter */
+	writel(0, dev->base + DW_IC_ENABLE);
 
-		/* set the slave (target) address */
-		writew(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR);
+	/* set the slave (target) address */
+	writel(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR);
 
-		/* if the slave address is ten bit address, enable 10BITADDR */
-		ic_con = readw(dev->base + DW_IC_CON);
-		if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
-			ic_con |= DW_IC_CON_10BITADDR_MASTER;
-		else
-			ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
-		writew(ic_con, dev->base + DW_IC_CON);
+	/* if the slave address is ten bit address, enable 10BITADDR */
+	ic_con = readl(dev->base + DW_IC_CON);
+	if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
+		ic_con |= DW_IC_CON_10BITADDR_MASTER;
+	else
+		ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
+	writel(ic_con, dev->base + DW_IC_CON);
 
-		/* Enable the adapter */
-		writeb(1, dev->base + DW_IC_ENABLE);
-	}
+	/* Enable the adapter */
+	writel(1, dev->base + DW_IC_ENABLE);
 
-	for (; dev->msg_write_idx < num; dev->msg_write_idx++) {
-		/* if target address has changed, we need to
+	/* Enable interrupts */
+	writel(DW_IC_INTR_DEFAULT_MASK, dev->base + DW_IC_INTR_MASK);
+}
+
+/*
+ * Initiate (and continue) low level master read/write transaction.
+ * This function is only called from i2c_dw_isr, and pumping i2c_msg
+ * messages into the tx buffer.  Even if the size of i2c_msg data is
+ * longer than the size of the tx buffer, it handles everything.
+ */
+static void
+i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
+{
+	struct i2c_msg *msgs = dev->msgs;
+	u32 intr_mask;
+	int tx_limit, rx_limit;
+	u32 addr = msgs[dev->msg_write_idx].addr;
+	u32 buf_len = dev->tx_buf_len;
+	u8 *buf = dev->tx_buf;;
+
+	intr_mask = DW_IC_INTR_DEFAULT_MASK;
+
+	for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
+		/*
+		 * if target address has changed, we need to
 		 * reprogram the target address in the i2c
 		 * adapter when we are done with this transfer
 		 */
-		if (msgs[dev->msg_write_idx].addr != addr)
-			return;
+		if (msgs[dev->msg_write_idx].addr != addr) {
+			dev_err(dev->dev,
+				"%s: invalid target address\n", __func__);
+			dev->msg_err = -EINVAL;
+			break;
+		}
 
 		if (msgs[dev->msg_write_idx].len == 0) {
 			dev_err(dev->dev,
 				"%s: invalid message length\n", __func__);
 			dev->msg_err = -EINVAL;
-			return;
+			break;
 		}
 
 		if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
 			/* new i2c_msg */
-			dev->tx_buf = msgs[dev->msg_write_idx].buf;
+			buf = msgs[dev->msg_write_idx].buf;
 			buf_len = msgs[dev->msg_write_idx].len;
 		}
 
+		tx_limit = dev->tx_fifo_depth - readl(dev->base + DW_IC_TXFLR);
+		rx_limit = dev->rx_fifo_depth - readl(dev->base + DW_IC_RXFLR);
+
 		while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
 			if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
-				writew(0x100, dev->base + DW_IC_DATA_CMD);
+				writel(0x100, dev->base + DW_IC_DATA_CMD);
 				rx_limit--;
 			} else
-				writew(*(dev->tx_buf++),
-						dev->base + DW_IC_DATA_CMD);
+				writel(*buf++, dev->base + DW_IC_DATA_CMD);
 			tx_limit--; buf_len--;
 		}
+
+		dev->tx_buf = buf;
+		dev->tx_buf_len = buf_len;
+
+		if (buf_len > 0) {
+			/* more bytes to be written */
+			dev->status |= STATUS_WRITE_IN_PROGRESS;
+			break;
+		} else
+			dev->status &= ~STATUS_WRITE_IN_PROGRESS;
 	}
 
-	intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT;
-	if (buf_len > 0) { /* more bytes to be written */
-		intr_mask |= DW_IC_INTR_TX_EMPTY;
-		dev->status |= STATUS_WRITE_IN_PROGRESS;
-	} else
-		dev->status &= ~STATUS_WRITE_IN_PROGRESS;
-	writew(intr_mask, dev->base + DW_IC_INTR_MASK);
+	/*
+	 * If i2c_msg index search is completed, we don't need TX_EMPTY
+	 * interrupt any more.
+	 */
+	if (dev->msg_write_idx == dev->msgs_num)
+		intr_mask &= ~DW_IC_INTR_TX_EMPTY;
 
-	dev->tx_buf_len = buf_len;
+	if (dev->msg_err)
+		intr_mask = 0;
+
+	writel(intr_mask, dev->base + DW_IC_INTR_MASK);
 }
 
 static void
-i2c_dw_read(struct i2c_adapter *adap)
+i2c_dw_read(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
 	struct i2c_msg *msgs = dev->msgs;
-	int num = dev->msgs_num;
-	u16 addr = msgs[dev->msg_read_idx].addr;
-	int rx_valid = readw(dev->base + DW_IC_RXFLR);
+	int rx_valid;
 
-	for (; dev->msg_read_idx < num; dev->msg_read_idx++) {
-		u16 len;
+	for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) {
+		u32 len;
 		u8 *buf;
 
 		if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD))
 			continue;
 
-		/* different i2c client, reprogram the i2c adapter */
-		if (msgs[dev->msg_read_idx].addr != addr)
-			return;
-
 		if (!(dev->status & STATUS_READ_IN_PROGRESS)) {
 			len = msgs[dev->msg_read_idx].len;
 			buf = msgs[dev->msg_read_idx].buf;
@@ -335,8 +476,10 @@ i2c_dw_read(struct i2c_adapter *adap)
 			buf = dev->rx_buf;
 		}
 
+		rx_valid = readl(dev->base + DW_IC_RXFLR);
+
 		for (; len > 0 && rx_valid > 0; len--, rx_valid--)
-			*buf++ = readb(dev->base + DW_IC_DATA_CMD);
+			*buf++ = readl(dev->base + DW_IC_DATA_CMD);
 
 		if (len > 0) {
 			dev->status |= STATUS_READ_IN_PROGRESS;
@@ -348,6 +491,29 @@ i2c_dw_read(struct i2c_adapter *adap)
 	}
 }
 
+static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
+{
+	unsigned long abort_source = dev->abort_source;
+	int i;
+
+	if (abort_source & DW_IC_TX_ABRT_NOACK) {
+		for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+			dev_dbg(dev->dev,
+				"%s: %s\n", __func__, abort_sources[i]);
+		return -EREMOTEIO;
+	}
+
+	for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+		dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
+
+	if (abort_source & DW_IC_TX_ARB_LOST)
+		return -EAGAIN;
+	else if (abort_source & DW_IC_TX_ABRT_GCALL_READ)
+		return -EINVAL; /* wrong msgs[] data */
+	else
+		return -EIO;
+}
+
 /*
  * Prepare controller for a transaction and call i2c_dw_xfer_msg
  */
@@ -369,13 +535,14 @@ i2c_dw_xfer(struct i2c_adapter *adap, st
 	dev->msg_read_idx = 0;
 	dev->msg_err = 0;
 	dev->status = STATUS_IDLE;
+	dev->abort_source = 0;
 
 	ret = i2c_dw_wait_bus_not_busy(dev);
 	if (ret < 0)
 		goto done;
 
 	/* start the transfers */
-	i2c_dw_xfer_msg(adap);
+	i2c_dw_xfer_init(dev);
 
 	/* wait for tx to complete */
 	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
@@ -394,23 +561,16 @@ i2c_dw_xfer(struct i2c_adapter *adap, st
 
 	/* no error */
 	if (likely(!dev->cmd_err)) {
-		/* read rx fifo, and disable the adapter */
-		do {
-			i2c_dw_read(adap);
-		} while (dev->status & STATUS_READ_IN_PROGRESS);
-		writeb(0, dev->base + DW_IC_ENABLE);
+		/* Disable the adapter */
+		writel(0, dev->base + DW_IC_ENABLE);
 		ret = num;
 		goto done;
 	}
 
 	/* We have an error */
 	if (dev->cmd_err == DW_IC_ERR_TX_ABRT) {
-		unsigned long abort_source = dev->abort_source;
-		int i;
-
-		for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) {
-		    dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
-		}
+		ret = i2c_dw_handle_tx_abort(dev);
+		goto done;
 	}
 	ret = -EIO;
 
@@ -422,21 +582,67 @@ done:
 
 static u32 i2c_dw_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
+	return	I2C_FUNC_I2C |
+		I2C_FUNC_10BIT_ADDR |
+		I2C_FUNC_SMBUS_BYTE |
+		I2C_FUNC_SMBUS_BYTE_DATA |
+		I2C_FUNC_SMBUS_WORD_DATA |
+		I2C_FUNC_SMBUS_I2C_BLOCK;
 }
 
-static void dw_i2c_pump_msg(unsigned long data)
+static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
 {
-	struct dw_i2c_dev *dev = (struct dw_i2c_dev *) data;
-	u16 intr_mask;
+	u32 stat;
 
-	i2c_dw_read(&dev->adapter);
-	i2c_dw_xfer_msg(&dev->adapter);
+	/*
+	 * The IC_INTR_STAT register just indicates "enabled" interrupts.
+	 * Ths unmasked raw version of interrupt status bits are available
+	 * in the IC_RAW_INTR_STAT register.
+	 *
+	 * That is,
+	 *   stat = readl(IC_INTR_STAT);
+	 * equals to,
+	 *   stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
+	 *
+	 * The raw version might be useful for debugging purposes.
+	 */
+	stat = readl(dev->base + DW_IC_INTR_STAT);
 
-	intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT;
-	if (dev->status & STATUS_WRITE_IN_PROGRESS)
-		intr_mask |= DW_IC_INTR_TX_EMPTY;
-	writew(intr_mask, dev->base + DW_IC_INTR_MASK);
+	/*
+	 * Do not use the IC_CLR_INTR register to clear interrupts, or
+	 * you'll miss some interrupts, triggered during the period from
+	 * readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
+	 *
+	 * Instead, use the separately-prepared IC_CLR_* registers.
+	 */
+	if (stat & DW_IC_INTR_RX_UNDER)
+		readl(dev->base + DW_IC_CLR_RX_UNDER);
+	if (stat & DW_IC_INTR_RX_OVER)
+		readl(dev->base + DW_IC_CLR_RX_OVER);
+	if (stat & DW_IC_INTR_TX_OVER)
+		readl(dev->base + DW_IC_CLR_TX_OVER);
+	if (stat & DW_IC_INTR_RD_REQ)
+		readl(dev->base + DW_IC_CLR_RD_REQ);
+	if (stat & DW_IC_INTR_TX_ABRT) {
+		/*
+		 * The IC_TX_ABRT_SOURCE register is cleared whenever
+		 * the IC_CLR_TX_ABRT is read.  Preserve it beforehand.
+		 */
+		dev->abort_source = readl(dev->base + DW_IC_TX_ABRT_SOURCE);
+		readl(dev->base + DW_IC_CLR_TX_ABRT);
+	}
+	if (stat & DW_IC_INTR_RX_DONE)
+		readl(dev->base + DW_IC_CLR_RX_DONE);
+	if (stat & DW_IC_INTR_ACTIVITY)
+		readl(dev->base + DW_IC_CLR_ACTIVITY);
+	if (stat & DW_IC_INTR_STOP_DET)
+		readl(dev->base + DW_IC_CLR_STOP_DET);
+	if (stat & DW_IC_INTR_START_DET)
+		readl(dev->base + DW_IC_CLR_START_DET);
+	if (stat & DW_IC_INTR_GEN_CALL)
+		readl(dev->base + DW_IC_CLR_GEN_CALL);
+
+	return stat;
 }
 
 /*
@@ -446,20 +652,37 @@ static void dw_i2c_pump_msg(unsigned lon
 static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
 {
 	struct dw_i2c_dev *dev = dev_id;
-	u16 stat;
+	u32 stat;
 
-	stat = readw(dev->base + DW_IC_INTR_STAT);
+	stat = i2c_dw_read_clear_intrbits(dev);
 	dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
+
 	if (stat & DW_IC_INTR_TX_ABRT) {
-		dev->abort_source = readw(dev->base + DW_IC_TX_ABRT_SOURCE);
 		dev->cmd_err |= DW_IC_ERR_TX_ABRT;
 		dev->status = STATUS_IDLE;
-	} else if (stat & DW_IC_INTR_TX_EMPTY)
-		tasklet_schedule(&dev->pump_msg);
 
-	readb(dev->base + DW_IC_CLR_INTR);	/* clear interrupts */
-	writew(0, dev->base + DW_IC_INTR_MASK);	/* disable interrupts */
-	if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET))
+		/*
+		 * Anytime TX_ABRT is set, the contents of the tx/rx
+		 * buffers are flushed.  Make sure to skip them.
+		 */
+		writel(0, dev->base + DW_IC_INTR_MASK);
+		goto tx_aborted;
+	}
+
+	if (stat & DW_IC_INTR_RX_FULL)
+		i2c_dw_read(dev);
+
+	if (stat & DW_IC_INTR_TX_EMPTY)
+		i2c_dw_xfer_msg(dev);
+
+	/*
+	 * No need to modify or disable the interrupt mask here.
+	 * i2c_dw_xfer_msg() will take care of it according to
+	 * the current transmit status.
+	 */
+
+tx_aborted:
+	if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
 		complete(&dev->cmd_complete);
 
 	return IRQ_HANDLED;
@@ -474,8 +697,8 @@ static int __devinit dw_i2c_probe(struct
 {
 	struct dw_i2c_dev *dev;
 	struct i2c_adapter *adap;
-	struct resource *mem, *irq, *ioarea;
-	int r;
+	struct resource *mem, *ioarea;
+	int irq, r;
 
 	/* NOTE: driver uses the static register mapping */
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -484,10 +707,10 @@ static int __devinit dw_i2c_probe(struct
 		return -EINVAL;
 	}
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!irq) {
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
-		return -EINVAL;
+		return irq; /* -ENXIO */
 	}
 
 	ioarea = request_mem_region(mem->start, resource_size(mem),
@@ -504,10 +727,9 @@ static int __devinit dw_i2c_probe(struct
 	}
 
 	init_completion(&dev->cmd_complete);
-	tasklet_init(&dev->pump_msg, dw_i2c_pump_msg, (unsigned long) dev);
 	mutex_init(&dev->lock);
 	dev->dev = get_device(&pdev->dev);
-	dev->irq = irq->start;
+	dev->irq = irq;
 	platform_set_drvdata(pdev, dev);
 
 	dev->clk = clk_get(&pdev->dev, NULL);
@@ -531,8 +753,8 @@ static int __devinit dw_i2c_probe(struct
 	}
 	i2c_dw_init(dev);
 
-	writew(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */
-	r = request_irq(dev->irq, i2c_dw_isr, 0, pdev->name, dev);
+	writel(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */
+	r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
 	if (r) {
 		dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
 		goto err_iounmap;
@@ -587,7 +809,7 @@ static int __devexit dw_i2c_remove(struc
 	clk_put(dev->clk);
 	dev->clk = NULL;
 
-	writeb(0, dev->base + DW_IC_ENABLE);
+	writel(0, dev->base + DW_IC_ENABLE);
 	free_irq(dev->irq, dev);
 	kfree(dev);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-i801.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-i801.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-i801.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-i801.c	2010-02-24 13:52:17.000000000 -0500
@@ -767,6 +767,9 @@ static int __devinit i801_probe(struct p
 	/* set up the sysfs linkage to our parent device */
 	i801_adapter.dev.parent = &dev->dev;
 
+	/* Retry up to 3 times on lost arbitration */
+	i801_adapter.retries = 3;
+
 	snprintf(i801_adapter.name, sizeof(i801_adapter.name),
 		"SMBus I801 adapter at %04lx", i801_smba);
 	err = i2c_add_adapter(&i801_adapter);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-imx.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-imx.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-imx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-imx.c	2010-02-24 13:52:17.000000000 -0500
@@ -226,7 +226,6 @@ static void i2c_imx_stop(struct imx_i2c_
 		temp = readb(i2c_imx->base + IMX_I2C_I2CR);
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
 		writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
-		i2c_imx->stopped = 1;
 	}
 	if (cpu_is_mx1()) {
 		/*
@@ -236,8 +235,10 @@ static void i2c_imx_stop(struct imx_i2c_
 		udelay(i2c_imx->disable_delay);
 	}
 
-	if (!i2c_imx->stopped)
+	if (!i2c_imx->stopped) {
 		i2c_imx_bus_busy(i2c_imx, 0);
+		i2c_imx->stopped = 1;
+	}
 
 	/* Disable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
@@ -496,22 +497,23 @@ static int __init i2c_imx_probe(struct p
 	}
 
 	res_size = resource_size(res);
+
+	if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {
+		ret = -EBUSY;
+		goto fail0;
+	}
+
 	base = ioremap(res->start, res_size);
 	if (!base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -EIO;
-		goto fail0;
+		goto fail1;
 	}
 
 	i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL);
 	if (!i2c_imx) {
 		dev_err(&pdev->dev, "can't allocate interface\n");
 		ret = -ENOMEM;
-		goto fail1;
-	}
-
-	if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {
-		ret = -EBUSY;
 		goto fail2;
 	}
 
@@ -582,11 +584,11 @@ fail5:
 fail4:
 	clk_put(i2c_imx->clk);
 fail3:
-	release_mem_region(i2c_imx->res->start, resource_size(res));
-fail2:
 	kfree(i2c_imx);
-fail1:
+fail2:
 	iounmap(base);
+fail1:
+	release_mem_region(res->start, resource_size(res));
 fail0:
 	if (pdata && pdata->exit)
 		pdata->exit(&pdev->dev);
@@ -618,8 +620,8 @@ static int __exit i2c_imx_remove(struct
 
 	clk_put(i2c_imx->clk);
 
-	release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
 	iounmap(i2c_imx->base);
+	release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
 	kfree(i2c_imx);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-iop3xx.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-iop3xx.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-iop3xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-iop3xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,12 +56,6 @@ iic_cook_addr(struct i2c_msg *msg)
 	if (msg->flags & I2C_M_RD)
 		addr |= 1;
 
-	/*
-	 * Read or Write?
-	 */
-	if (msg->flags & I2C_M_REV_DIR_ADDR)
-		addr ^= 1;
-
 	return addr;   
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-mv64xxx.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mv64xxx.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -338,9 +338,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xx
 	if (msg->flags & I2C_M_RD)
 		dir = 1;
 
-	if (msg->flags & I2C_M_REV_DIR_ADDR)
-		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;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-omap.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-omap.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-omap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-omap.c	2010-02-24 13:52:17.000000000 -0500
@@ -178,6 +178,12 @@ struct omap_i2c_dev {
 	unsigned		b_hw:1;		/* bad h/w fixes */
 	unsigned		idle:1;
 	u16			iestate;	/* Saved interrupt register */
+	u16			pscstate;
+	u16			scllstate;
+	u16			sclhstate;
+	u16			bufstate;
+	u16			syscstate;
+	u16			westate;
 };
 
 static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -230,7 +236,22 @@ static void omap_i2c_unidle(struct omap_
 
 	clk_enable(dev->iclk);
 	clk_enable(dev->fclk);
+	if (cpu_is_omap34xx()) {
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+		omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate);
+		omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+	}
 	dev->idle = 0;
+
+	/*
+	 * Don't write to this register if the IE state is 0 as it can
+	 * cause deadlock.
+	 */
 	if (dev->iestate)
 		omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
 }
@@ -258,13 +279,18 @@ static void omap_i2c_idle(struct omap_i2
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
 {
-	u16 psc = 0, scll = 0, sclh = 0;
+	u16 psc = 0, scll = 0, sclh = 0, buf = 0;
 	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
 	unsigned long fclk_rate = 12000000;
 	unsigned long timeout;
 	unsigned long internal_clk = 0;
 
 	if (dev->rev >= OMAP_I2C_REV_2) {
+		/* Disable I2C controller before soft reset */
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
+			omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) &
+				~(OMAP_I2C_CON_EN));
+
 		omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK);
 		/* For some reason we need to set the EN bit before the
 		 * reset done bit gets set. */
@@ -287,24 +313,22 @@ static int omap_i2c_init(struct omap_i2c
 					   SYSC_AUTOIDLE_MASK);
 
 		} else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
-			u32 v;
-
-			v = SYSC_AUTOIDLE_MASK;
-			v |= SYSC_ENAWAKEUP_MASK;
-			v |= (SYSC_IDLEMODE_SMART <<
+			dev->syscstate = SYSC_AUTOIDLE_MASK;
+			dev->syscstate |= SYSC_ENAWAKEUP_MASK;
+			dev->syscstate |= (SYSC_IDLEMODE_SMART <<
 			      __ffs(SYSC_SIDLEMODE_MASK));
-			v |= (SYSC_CLOCKACTIVITY_FCLK <<
+			dev->syscstate |= (SYSC_CLOCKACTIVITY_FCLK <<
 			      __ffs(SYSC_CLOCKACTIVITY_MASK));
 
-			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, v);
+			omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
+							dev->syscstate);
 			/*
 			 * Enabling all wakup sources to stop I2C freezing on
 			 * WFI instruction.
 			 * REVISIT: Some wkup sources might not be needed.
 			 */
-			omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
-							OMAP_I2C_WE_ALL);
-
+			dev->westate = OMAP_I2C_WE_ALL;
+			omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
 		}
 	}
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
@@ -394,23 +418,28 @@ static int omap_i2c_init(struct omap_i2c
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
-	if (dev->fifo_size)
-		/* Note: setup required fifo size - 1 */
-		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
-					(dev->fifo_size - 1) << 8 | /* RTRSH */
-					OMAP_I2C_BUF_RXFIF_CLR |
-					(dev->fifo_size - 1) | /* XTRSH */
-					OMAP_I2C_BUF_TXFIF_CLR);
+	if (dev->fifo_size) {
+		/* Note: setup required fifo size - 1. RTRSH and XTRSH */
+		buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+			(dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+	}
 
 	/* Take the I2C module out of reset: */
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
 	/* Enable interrupts */
-	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
-			(OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+	dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
 			OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
 			OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
-				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
+	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+	if (cpu_is_omap34xx()) {
+		dev->pscstate = psc;
+		dev->scllstate = scll;
+		dev->sclhstate = sclh;
+		dev->bufstate = buf;
+	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pca-isa.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pca-isa.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pca-isa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pca-isa.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,7 +75,7 @@ static int pca_isa_waitforcompletion(voi
 	unsigned long timeout;
 
 	if (irq > -1) {
-		ret = wait_event_interruptible_timeout(pca_wait,
+		ret = wait_event_timeout(pca_wait,
 				pca_isa_readbyte(pd, I2C_PCA_CON)
 				& I2C_PCA_CON_SI, pca_isa_ops.timeout);
 	} else {
@@ -96,7 +96,7 @@ static void pca_isa_resetchip(void *pd)
 }
 
 static irqreturn_t pca_handler(int this_irq, void *dev_id) {
-	wake_up_interruptible(&pca_wait);
+	wake_up(&pca_wait);
 	return IRQ_HANDLED;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pca-platform.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pca-platform.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pca-platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pca-platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,7 +84,7 @@ static int i2c_pca_pf_waitforcompletion(
 	unsigned long timeout;
 
 	if (i2c->irq) {
-		ret = wait_event_interruptible_timeout(i2c->wait,
+		ret = wait_event_timeout(i2c->wait,
 			i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
 			& I2C_PCA_CON_SI, i2c->adap.timeout);
 	} else {
@@ -122,7 +122,7 @@ static irqreturn_t i2c_pca_pf_handler(in
 	if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
 		return IRQ_NONE;
 
-	wake_up_interruptible(&i2c->wait);
+	wake_up(&i2c->wait);
 
 	return IRQ_HANDLED;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-piix4.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-piix4.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-piix4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-piix4.c	2010-02-24 13:52:17.000000000 -0500
@@ -324,12 +324,12 @@ static int piix4_transaction(void)
 	else
 		msleep(1);
 
-	while ((timeout++ < MAX_TIMEOUT) &&
+	while ((++timeout < MAX_TIMEOUT) &&
 	       ((temp = inb_p(SMBHSTSTS)) & 0x01))
 		msleep(1);
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout == MAX_TIMEOUT) {
 		dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pnx.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pnx.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pnx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pnx.c	2010-02-24 13:52:17.000000000 -0500
@@ -638,7 +638,8 @@ static int __devinit i2c_pnx_probe(struc
 
 	/* Register this adapter with the I2C subsystem */
 	i2c_pnx->adapter->dev.parent = &pdev->dev;
-	ret = i2c_add_adapter(i2c_pnx->adapter);
+	i2c_pnx->adapter->nr = pdev->id;
+	ret = i2c_add_numbered_adapter(i2c_pnx->adapter);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "I2C: Failed to add bus\n");
 		goto out_irq;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-powermac.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-powermac.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-powermac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-powermac.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,48 +49,38 @@ static s32 i2c_powermac_smbus_xfer(	stru
 	int			rc = 0;
 	int			read = (read_write == I2C_SMBUS_READ);
 	int			addrdir = (addr << 1) | read;
+	int			mode, subsize, len;
+	u32			subaddr;
+	u8			*buf;
 	u8			local[2];
 
-	rc = pmac_i2c_open(bus, 0);
-	if (rc)
-		return rc;
+	if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) {
+		mode = pmac_i2c_mode_std;
+		subsize = 0;
+		subaddr = 0;
+	} else {
+		mode = read ? pmac_i2c_mode_combined : pmac_i2c_mode_stdsub;
+		subsize = 1;
+		subaddr = command;
+	}
 
 	switch (size) {
         case I2C_SMBUS_QUICK:
-		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-		if (rc)
-			goto bail;
-		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0);
+		buf = NULL;
+		len = 0;
 	    	break;
         case I2C_SMBUS_BYTE:
-		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-		if (rc)
-			goto bail;
-		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1);
-	    	break;
         case I2C_SMBUS_BYTE_DATA:
-		rc = pmac_i2c_setmode(bus, read ?
-				      pmac_i2c_mode_combined :
-				      pmac_i2c_mode_stdsub);
-		if (rc)
-			goto bail;
-		rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1);
+		buf = &data->byte;
+		len = 1;
 	    	break;
         case I2C_SMBUS_WORD_DATA:
-		rc = pmac_i2c_setmode(bus, read ?
-				      pmac_i2c_mode_combined :
-				      pmac_i2c_mode_stdsub);
-		if (rc)
-			goto bail;
 		if (!read) {
 			local[0] = data->word & 0xff;
 			local[1] = (data->word >> 8) & 0xff;
 		}
-		rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2);
-		if (rc == 0 && read) {
-			data->word = ((u16)local[1]) << 8;
-			data->word |= local[0];
-		}
+		buf = local;
+		len = 2;
 	    	break;
 
 	/* Note that these are broken vs. the expected smbus API where
@@ -105,28 +95,44 @@ static s32 i2c_powermac_smbus_xfer(	stru
 	 * a repeat start/addr phase (but not stop in between)
 	 */
         case I2C_SMBUS_BLOCK_DATA:
-		rc = pmac_i2c_setmode(bus, read ?
-				      pmac_i2c_mode_combined :
-				      pmac_i2c_mode_stdsub);
-		if (rc)
-			goto bail;
-		rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block,
-				   data->block[0] + 1);
-
+		buf = data->block;
+		len = data->block[0] + 1;
 		break;
 	case I2C_SMBUS_I2C_BLOCK_DATA:
-		rc = pmac_i2c_setmode(bus, read ?
-				      pmac_i2c_mode_combined :
-				      pmac_i2c_mode_stdsub);
-		if (rc)
-			goto bail;
-		rc = pmac_i2c_xfer(bus, addrdir, 1, command,
-				   &data->block[1], data->block[0]);
+		buf = &data->block[1];
+		len = data->block[0];
 		break;
 
         default:
-	    	rc = -EINVAL;
+		return -EINVAL;
 	}
+
+	rc = pmac_i2c_open(bus, 0);
+	if (rc) {
+		dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
+		return rc;
+	}
+
+	rc = pmac_i2c_setmode(bus, mode);
+	if (rc) {
+		dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
+			mode, rc);
+		goto bail;
+	}
+
+	rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
+	if (rc) {
+		dev_err(&adap->dev,
+			"I2C transfer at 0x%02x failed, size %d, err %d\n",
+			addrdir >> 1, size, rc);
+		goto bail;
+	}
+
+	if (size == I2C_SMBUS_WORD_DATA && read) {
+		data->word = ((u16)local[1]) << 8;
+		data->word |= local[0];
+	}
+
  bail:
 	pmac_i2c_close(bus);
 	return rc;
@@ -146,20 +152,33 @@ static int i2c_powermac_master_xfer(	str
 	int			read;
 	int			addrdir;
 
+	if (num != 1) {
+		dev_err(&adap->dev,
+			"Multi-message I2C transactions not supported\n");
+		return -EOPNOTSUPP;
+	}
+
 	if (msgs->flags & I2C_M_TEN)
 		return -EINVAL;
 	read = (msgs->flags & I2C_M_RD) != 0;
 	addrdir = (msgs->addr << 1) | read;
-	if (msgs->flags & I2C_M_REV_DIR_ADDR)
-		addrdir ^= 1;
 
 	rc = pmac_i2c_open(bus, 0);
-	if (rc)
+	if (rc) {
+		dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
 		return rc;
+	}
 	rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-	if (rc)
+	if (rc) {
+		dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
+			pmac_i2c_mode_std, rc);
 		goto bail;
+	}
 	rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
+	if (rc < 0)
+		dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+			addrdir & 1 ? "read from" : "write to", addrdir >> 1,
+			rc);
  bail:
 	pmac_i2c_close(bus);
 	return rc < 0 ? rc : 1;
@@ -183,19 +202,16 @@ static const struct i2c_algorithm i2c_po
 static int __devexit i2c_powermac_remove(struct platform_device *dev)
 {
 	struct i2c_adapter	*adapter = platform_get_drvdata(dev);
-	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adapter);
 	int			rc;
 
 	rc = i2c_del_adapter(adapter);
-	pmac_i2c_detach_adapter(bus, adapter);
-	i2c_set_adapdata(adapter, NULL);
 	/* We aren't that prepared to deal with this... */
 	if (rc)
 		printk(KERN_WARNING
 		       "i2c-powermac.c: Failed to remove bus %s !\n",
 		       adapter->name);
 	platform_set_drvdata(dev, NULL);
-	kfree(adapter);
+	memset(adapter, 0, sizeof(*adapter));
 
 	return 0;
 }
@@ -206,12 +222,12 @@ static int __devinit i2c_powermac_probe(
 	struct pmac_i2c_bus *bus = dev->dev.platform_data;
 	struct device_node *parent = NULL;
 	struct i2c_adapter *adapter;
-	char name[32];
 	const char *basename;
 	int rc;
 
 	if (bus == NULL)
 		return -EINVAL;
+	adapter = pmac_i2c_get_adapter(bus);
 
 	/* Ok, now we need to make up a name for the interface that will
 	 * match what we used to do in the past, that is basically the
@@ -237,29 +253,22 @@ static int __devinit i2c_powermac_probe(
 	default:
 		return -EINVAL;
 	}
-	snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus));
+	snprintf(adapter->name, sizeof(adapter->name), "%s %d", basename,
+		 pmac_i2c_get_channel(bus));
 	of_node_put(parent);
 
-	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (adapter == NULL) {
-		printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
-		return -ENOMEM;
-	}
 	platform_set_drvdata(dev, adapter);
-	strcpy(adapter->name, name);
 	adapter->algo = &i2c_powermac_algorithm;
 	i2c_set_adapdata(adapter, bus);
 	adapter->dev.parent = &dev->dev;
-	pmac_i2c_attach_adapter(bus, adapter);
 	rc = i2c_add_adapter(adapter);
 	if (rc) {
 		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
-		       "failed\n", name);
-		i2c_set_adapdata(adapter, NULL);
-		pmac_i2c_detach_adapter(bus, adapter);
+		       "failed\n", adapter->name);
+		memset(adapter, 0, sizeof(*adapter));
 	}
 
-	printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
+	printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
 
 	if (!strncmp(basename, "uni-n", 5)) {
 		struct device_node *np;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pxa.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pxa.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-pxa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-pxa.c	2010-02-24 13:52:17.000000000 -0500
@@ -1155,7 +1155,7 @@ static int i2c_pxa_resume_noirq(struct d
 	return 0;
 }
 
-static struct dev_pm_ops i2c_pxa_dev_pm_ops = {
+static const struct dev_pm_ops i2c_pxa_dev_pm_ops = {
 	.suspend_noirq = i2c_pxa_suspend_noirq,
 	.resume_noirq = i2c_pxa_resume_noirq,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-s3c2410.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-s3c2410.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2010-02-24 13:52:17.000000000 -0500
@@ -967,7 +967,7 @@ static int s3c24xx_i2c_resume(struct dev
 	return 0;
 }
 
-static struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
+static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
 	.suspend_noirq = s3c24xx_i2c_suspend_noirq,
 	.resume = s3c24xx_i2c_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-scmi.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-scmi.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-scmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-scmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -363,7 +363,7 @@ static int acpi_smbus_cmi_add(struct acp
 	smbus_cmi->cap_write = 0;
 
 	acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
-			    acpi_smbus_cmi_query_methods, smbus_cmi, NULL);
+			    acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
 
 	if (smbus_cmi->cap_info == 0)
 		goto err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sh_mobile.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sh_mobile.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sh_mobile.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sh_mobile.c	2010-02-24 13:52:17.000000000 -0500
@@ -647,7 +647,7 @@ static int sh_mobile_i2c_runtime_nop(str
 	return 0;
 }
 
-static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
+static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
 	.runtime_suspend = sh_mobile_i2c_runtime_nop,
 	.runtime_resume = sh_mobile_i2c_runtime_nop,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sis5595.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis5595.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sis5595.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis5595.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,7 +142,7 @@ static void sis5595_write(u8 reg, u8 dat
 	outb(data, sis5595_base + SMB_DAT);
 }
 
-static int sis5595_setup(struct pci_dev *SIS5595_dev)
+static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
 {
 	u16 a;
 	u8 val;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sis630.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis630.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-sis630.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-sis630.c	2010-02-24 13:52:17.000000000 -0500
@@ -389,7 +389,7 @@ static u32 sis630_func(struct i2c_adapte
 		I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
-static int sis630_setup(struct pci_dev *sis630_dev)
+static int __devinit sis630_setup(struct pci_dev *sis630_dev)
 {
 	unsigned char b;
 	struct pci_dev *dummy = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-stub.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-stub.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-stub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-stub.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,10 @@ module_param_array(chip_addr, ushort, NU
 MODULE_PARM_DESC(chip_addr,
 		 "Chip addresses (up to 10, between 0x03 and 0x77)");
 
+static unsigned long functionality = ~0UL;
+module_param(functionality, ulong, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(functionality, "Override functionality bitfield");
+
 struct stub_chip {
 	u8 pointer;
 	u16 words[256];		/* Byte operations use the LSB as per SMBus
@@ -48,7 +52,7 @@ static s32 stub_xfer(struct i2c_adapter
 	char read_write, u8 command, int size, union i2c_smbus_data * data)
 {
 	s32 ret;
-	int i;
+	int i, len;
 	struct stub_chip *chip = NULL;
 
 	/* Search for the right chip */
@@ -118,6 +122,29 @@ static s32 stub_xfer(struct i2c_adapter
 		ret = 0;
 		break;
 
+	case I2C_SMBUS_I2C_BLOCK_DATA:
+		len = data->block[0];
+		if (read_write == I2C_SMBUS_WRITE) {
+			for (i = 0; i < len; i++) {
+				chip->words[command + i] &= 0xff00;
+				chip->words[command + i] |= data->block[1 + i];
+			}
+			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
+					"wrote %d bytes at 0x%02x.\n",
+					addr, len, command);
+		} else {
+			for (i = 0; i < len; i++) {
+				data->block[1 + i] =
+					chip->words[command + i] & 0xff;
+			}
+			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
+					"read  %d bytes at 0x%02x.\n",
+					addr, len, command);
+		}
+
+		ret = 0;
+		break;
+
 	default:
 		dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
 		ret = -EOPNOTSUPP;
@@ -129,8 +156,9 @@ static s32 stub_xfer(struct i2c_adapter
 
 static u32 stub_func(struct i2c_adapter *adapter)
 {
-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
+	return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+		I2C_FUNC_SMBUS_I2C_BLOCK) & functionality;
 }
 
 static const struct i2c_algorithm smbus_algorithm = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-tiny-usb.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-tiny-usb.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-tiny-usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-tiny-usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/types.h>
 
 /* include interfaces to usb layer */
 #include <linux/usb.h>
@@ -31,8 +32,8 @@
 #define CMD_I2C_IO_END		(1<<1)
 
 /* i2c bit delay, default is 10us -> 100kHz */
-static int delay = 10;
-module_param(delay, int, 0);
+static unsigned short delay = 10;
+module_param(delay, ushort, 0);
 MODULE_PARM_DESC(delay, "bit delay in microseconds, "
 		 "e.g. 10 for 100kHz (default is 100kHz)");
 
@@ -109,7 +110,7 @@ static int usb_xfer(struct i2c_adapter *
 
 static u32 usb_func(struct i2c_adapter *adapter)
 {
-	u32 func;
+	__le32 func;
 
 	/* get functionality from adapter */
 	if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
@@ -118,7 +119,7 @@ static u32 usb_func(struct i2c_adapter *
 		return 0;
 	}
 
-	return func;
+	return le32_to_cpu(func);
 }
 
 /* This is the actual algorithm we define */
@@ -216,8 +217,7 @@ static int i2c_tiny_usb_probe(struct usb
 		 "i2c-tiny-usb at bus %03d device %03d",
 		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
 
-	if (usb_write(&dev->adapter, CMD_SET_DELAY,
-		      cpu_to_le16(delay), 0, NULL, 0) != 0) {
+	if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) {
 		dev_err(&dev->adapter.dev,
 			"failure setting delay to %dus\n", delay);
 		retval = -EIO;
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-viapro.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-viapro.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-viapro.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-viapro.c	2010-02-24 13:52:17.000000000 -0500
@@ -165,10 +165,10 @@ static int vt596_transaction(u8 size)
 	do {
 		msleep(1);
 		temp = inb_p(SMBHSTSTS);
-	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
+	} while ((temp & 0x01) && (++timeout < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout == MAX_TIMEOUT) {
 		result = -ETIMEDOUT;
 		dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-voodoo3.c linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-voodoo3.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/i2c-voodoo3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/i2c-voodoo3.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,248 +0,0 @@
-/*
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    Ralph Metzler <rjkm@thp.uni-koeln.de>, and
-    Mark D. Studebaker <mdsxyz123@yahoo.com>
-    
-    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
-    Simon Vogl
-
-    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.
-*/
-
-/* This interfaces to the I2C bus of the Voodoo3 to gain access to
-    the BT869 and possibly other I2C devices. */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* the only registers we use */
-#define REG		0x78
-#define REG2 		0x70
-
-/* bit locations in the register */
-#define DDC_ENAB	0x00040000
-#define DDC_SCL_OUT	0x00080000
-#define DDC_SDA_OUT	0x00100000
-#define DDC_SCL_IN	0x00200000
-#define DDC_SDA_IN	0x00400000
-#define I2C_ENAB	0x00800000
-#define I2C_SCL_OUT	0x01000000
-#define I2C_SDA_OUT	0x02000000
-#define I2C_SCL_IN	0x04000000
-#define I2C_SDA_IN	0x08000000
-
-/* initialization states */
-#define INIT2		0x2
-#define INIT3		0x4
-
-/* delays */
-#define CYCLE_DELAY	10
-#define TIMEOUT		(HZ / 2)
-
-
-static void __iomem *ioaddr;
-
-/* The voo GPIO registers don't have individual masks for each bit
-   so we always have to read before writing. */
-
-static void bit_vooi2c_setscl(void *data, int val)
-{
-	unsigned int r;
-	r = readl(ioaddr + REG);
-	if (val)
-		r |= I2C_SCL_OUT;
-	else
-		r &= ~I2C_SCL_OUT;
-	writel(r, ioaddr + REG);
-	readl(ioaddr + REG);	/* flush posted write */
-}
-
-static void bit_vooi2c_setsda(void *data, int val)
-{
-	unsigned int r;
-	r = readl(ioaddr + REG);
-	if (val)
-		r |= I2C_SDA_OUT;
-	else
-		r &= ~I2C_SDA_OUT;
-	writel(r, ioaddr + REG);
-	readl(ioaddr + REG);	/* flush posted write */
-}
-
-/* The GPIO pins are open drain, so the pins always remain outputs.
-   We rely on the i2c-algo-bit routines to set the pins high before
-   reading the input from other chips. */
-
-static int bit_vooi2c_getscl(void *data)
-{
-	return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
-}
-
-static int bit_vooi2c_getsda(void *data)
-{
-	return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
-}
-
-static void bit_vooddc_setscl(void *data, int val)
-{
-	unsigned int r;
-	r = readl(ioaddr + REG);
-	if (val)
-		r |= DDC_SCL_OUT;
-	else
-		r &= ~DDC_SCL_OUT;
-	writel(r, ioaddr + REG);
-	readl(ioaddr + REG);	/* flush posted write */
-}
-
-static void bit_vooddc_setsda(void *data, int val)
-{
-	unsigned int r;
-	r = readl(ioaddr + REG);
-	if (val)
-		r |= DDC_SDA_OUT;
-	else
-		r &= ~DDC_SDA_OUT;
-	writel(r, ioaddr + REG);
-	readl(ioaddr + REG);	/* flush posted write */
-}
-
-static int bit_vooddc_getscl(void *data)
-{
-	return (0 != (readl(ioaddr + REG) & DDC_SCL_IN));
-}
-
-static int bit_vooddc_getsda(void *data)
-{
-	return (0 != (readl(ioaddr + REG) & DDC_SDA_IN));
-}
-
-static int config_v3(struct pci_dev *dev)
-{
-	unsigned long cadr;
-
-	/* map Voodoo3 memory */
-	cadr = dev->resource[0].start;
-	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
-	ioaddr = ioremap_nocache(cadr, 0x1000);
-	if (ioaddr) {
-		writel(0x8160, ioaddr + REG2);
-		writel(0xcffc0020, ioaddr + REG);
-		dev_info(&dev->dev, "Using Banshee/Voodoo3 I2C device at %p\n", ioaddr);
-		return 0;
-	}
-	return -ENODEV;
-}
-
-static struct i2c_algo_bit_data voo_i2c_bit_data = {
-	.setsda		= bit_vooi2c_setsda,
-	.setscl		= bit_vooi2c_setscl,
-	.getsda		= bit_vooi2c_getsda,
-	.getscl		= bit_vooi2c_getscl,
-	.udelay		= CYCLE_DELAY,
-	.timeout	= TIMEOUT
-};
-
-static struct i2c_adapter voodoo3_i2c_adapter = {
-	.owner		= THIS_MODULE,
-	.name		= "I2C Voodoo3/Banshee adapter",
-	.algo_data	= &voo_i2c_bit_data,
-};
-
-static struct i2c_algo_bit_data voo_ddc_bit_data = {
-	.setsda		= bit_vooddc_setsda,
-	.setscl		= bit_vooddc_setscl,
-	.getsda		= bit_vooddc_getsda,
-	.getscl		= bit_vooddc_getscl,
-	.udelay		= CYCLE_DELAY,
-	.timeout	= TIMEOUT
-};
-
-static struct i2c_adapter voodoo3_ddc_adapter = {
-	.owner		= THIS_MODULE,
-	.class		= I2C_CLASS_DDC, 
-	.name		= "DDC Voodoo3/Banshee adapter",
-	.algo_data	= &voo_ddc_bit_data,
-};
-
-static struct pci_device_id voodoo3_ids[] __devinitdata = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE) },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, voodoo3_ids);
-
-static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int retval;
-
-	retval = config_v3(dev);
-	if (retval)
-		return retval;
-
-	/* set up the sysfs linkage to our parent device */
-	voodoo3_i2c_adapter.dev.parent = &dev->dev;
-	voodoo3_ddc_adapter.dev.parent = &dev->dev;
-
-	retval = i2c_bit_add_bus(&voodoo3_i2c_adapter);
-	if (retval)
-		return retval;
-	retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
-	if (retval)
-		i2c_del_adapter(&voodoo3_i2c_adapter);
-	return retval;
-}
-
-static void __devexit voodoo3_remove(struct pci_dev *dev)
-{
-	i2c_del_adapter(&voodoo3_i2c_adapter);
-	i2c_del_adapter(&voodoo3_ddc_adapter);
-	iounmap(ioaddr);
-}
-
-static struct pci_driver voodoo3_driver = {
-	.name		= "voodoo3_smbus",
-	.id_table	= voodoo3_ids,
-	.probe		= voodoo3_probe,
-	.remove		= __devexit_p(voodoo3_remove),
-};
-
-static int __init i2c_voodoo3_init(void)
-{
-	return pci_register_driver(&voodoo3_driver);
-}
-
-static void __exit i2c_voodoo3_exit(void)
-{
-	pci_unregister_driver(&voodoo3_driver);
-}
-
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-		"Philip Edelbrock <phil@netroedge.com>, "
-		"Ralph Metzler <rjkm@thp.uni-koeln.de>, "
-		"and Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("Voodoo3 I2C/SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_voodoo3_init);
-module_exit(i2c_voodoo3_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/Kconfig linux-libre-2.6.33-gnu1/drivers/i2c/busses/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -640,22 +640,6 @@ config I2C_TINY_USB
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-tiny-usb.
 
-comment "Graphics adapter I2C/DDC channel drivers"
-	depends on PCI
-
-config I2C_VOODOO3
-	tristate "Voodoo 3 (DEPRECATED)"
-	depends on PCI
-	select I2C_ALGOBIT
-	help
-	  If you say yes to this option, support will be included for the
-	  Voodoo 3 I2C interface. This driver is deprecated and you should
-	  use the tdfxfb driver instead, which additionally provides
-	  framebuffer support.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called i2c-voodoo3.
-
 comment "Other I2C/SMBus bus drivers"
 
 config I2C_ACORN
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/busses/Makefile linux-libre-2.6.33-gnu1/drivers/i2c/busses/Makefile
--- linux-libre-2.6.32-gnu1/drivers/i2c/busses/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/busses/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -61,9 +61,6 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-p
 obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)	+= i2c-tiny-usb.o
 
-# Graphics adapter I2C/DDC channel drivers
-obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
-
 # Other I2C/SMBus bus drivers
 obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/chips/ds1682.c linux-libre-2.6.33-gnu1/drivers/i2c/chips/ds1682.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/chips/ds1682.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/chips/ds1682.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,267 +0,0 @@
-/*
- * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
- *
- * Written by: Grant Likely <grant.likely@secretlab.ca>
- *
- * Copyright (C) 2007 Secret Lab 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.
- */
-
-/*
- * The DS1682 elapsed timer recorder is a simple device that implements
- * one elapsed time counter, one event counter, an alarm signal and 10
- * bytes of general purpose EEPROM.
- *
- * This driver provides access to the DS1682 counters and user data via
- * the sysfs.  The following attributes are added to the device node:
- *     elapsed_time (u32): Total elapsed event time in ms resolution
- *     alarm_time (u32): When elapsed time exceeds the value in alarm_time,
- *                       then the alarm pin is asserted.
- *     event_count (u16): number of times the event pin has gone low.
- *     eeprom (u8[10]): general purpose EEPROM
- *
- * Counter registers and user data are both read/write unless the device
- * has been write protected.  This driver does not support turning off write
- * protection.  Once write protection is turned on, it is impossible to
- * turn it off again, so I have left the feature out of this driver to avoid
- * accidental enabling, but it is trivial to add write protect support.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/sysfs.h>
-#include <linux/ctype.h>
-#include <linux/hwmon-sysfs.h>
-
-/* Device registers */
-#define DS1682_REG_CONFIG		0x00
-#define DS1682_REG_ALARM		0x01
-#define DS1682_REG_ELAPSED		0x05
-#define DS1682_REG_EVT_CNTR		0x09
-#define DS1682_REG_EEPROM		0x0b
-#define DS1682_REG_RESET		0x1d
-#define DS1682_REG_WRITE_DISABLE	0x1e
-#define DS1682_REG_WRITE_MEM_DISABLE	0x1f
-
-#define DS1682_EEPROM_SIZE		10
-
-/*
- * Generic counter attributes
- */
-static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-	struct i2c_client *client = to_i2c_client(dev);
-	__le32 val = 0;
-	int rc;
-
-	dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
-
-	/* Read the register */
-	rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
-					   (u8 *) & val);
-	if (rc < 0)
-		return -EIO;
-
-	/* Special case: the 32 bit regs are time values with 1/4s
-	 * resolution, scale them up to milliseconds */
-	if (sattr->nr == 4)
-		return sprintf(buf, "%llu\n",
-			((unsigned long long)le32_to_cpu(val)) * 250);
-
-	/* Format the output string and return # of bytes */
-	return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
-}
-
-static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-	struct i2c_client *client = to_i2c_client(dev);
-	char *endp;
-	u64 val;
-	__le32 val_le;
-	int rc;
-
-	dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
-
-	/* Decode input */
-	val = simple_strtoull(buf, &endp, 0);
-	if (buf == endp) {
-		dev_dbg(dev, "input string not a number\n");
-		return -EINVAL;
-	}
-
-	/* Special case: the 32 bit regs are time values with 1/4s
-	 * resolution, scale input down to quarter-seconds */
-	if (sattr->nr == 4)
-		do_div(val, 250);
-
-	/* write out the value */
-	val_le = cpu_to_le32(val);
-	rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
-					    (u8 *) & val_le);
-	if (rc < 0) {
-		dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
-			sattr->index, sattr->nr);
-		return -EIO;
-	}
-
-	return count;
-}
-
-/*
- * Simple register attributes
- */
-static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
-			    ds1682_store, 4, DS1682_REG_ELAPSED);
-static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
-			    ds1682_store, 4, DS1682_REG_ALARM);
-static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
-			    ds1682_store, 2, DS1682_REG_EVT_CNTR);
-
-static const struct attribute_group ds1682_group = {
-	.attrs = (struct attribute *[]) {
-		&sensor_dev_attr_elapsed_time.dev_attr.attr,
-		&sensor_dev_attr_alarm_time.dev_attr.attr,
-		&sensor_dev_attr_event_count.dev_attr.attr,
-		NULL,
-	},
-};
-
-/*
- * User data attribute
- */
-static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr,
-				  char *buf, loff_t off, size_t count)
-{
-	struct i2c_client *client = kobj_to_i2c_client(kobj);
-	int rc;
-
-	dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
-		buf, off, count);
-
-	if (off >= DS1682_EEPROM_SIZE)
-		return 0;
-
-	if (off + count > DS1682_EEPROM_SIZE)
-		count = DS1682_EEPROM_SIZE - off;
-
-	rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
-					   count, buf);
-	if (rc < 0)
-		return -EIO;
-
-	return count;
-}
-
-static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr,
-				   char *buf, loff_t off, size_t count)
-{
-	struct i2c_client *client = kobj_to_i2c_client(kobj);
-
-	dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
-		buf, off, count);
-
-	if (off >= DS1682_EEPROM_SIZE)
-		return -ENOSPC;
-
-	if (off + count > DS1682_EEPROM_SIZE)
-		count = DS1682_EEPROM_SIZE - off;
-
-	/* Write out to the device */
-	if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
-					   count, buf) < 0)
-		return -EIO;
-
-	return count;
-}
-
-static struct bin_attribute ds1682_eeprom_attr = {
-	.attr = {
-		.name = "eeprom",
-		.mode = S_IRUGO | S_IWUSR,
-	},
-	.size = DS1682_EEPROM_SIZE,
-	.read = ds1682_eeprom_read,
-	.write = ds1682_eeprom_write,
-};
-
-/*
- * Called when a ds1682 device is matched with this driver
- */
-static int ds1682_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	int rc;
-
-	if (!i2c_check_functionality(client->adapter,
-				     I2C_FUNC_SMBUS_I2C_BLOCK)) {
-		dev_err(&client->dev, "i2c bus does not support the ds1682\n");
-		rc = -ENODEV;
-		goto exit;
-	}
-
-	rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
-	if (rc)
-		goto exit;
-
-	rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
-	if (rc)
-		goto exit_bin_attr;
-
-	return 0;
-
- exit_bin_attr:
-	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
- exit:
-	return rc;
-}
-
-static int ds1682_remove(struct i2c_client *client)
-{
-	sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
-	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
-	return 0;
-}
-
-static const struct i2c_device_id ds1682_id[] = {
-	{ "ds1682", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, ds1682_id);
-
-static struct i2c_driver ds1682_driver = {
-	.driver = {
-		.name = "ds1682",
-	},
-	.probe = ds1682_probe,
-	.remove = ds1682_remove,
-	.id_table = ds1682_id,
-};
-
-static int __init ds1682_init(void)
-{
-	return i2c_add_driver(&ds1682_driver);
-}
-
-static void __exit ds1682_exit(void)
-{
-	i2c_del_driver(&ds1682_driver);
-}
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
-MODULE_LICENSE("GPL");
-
-module_init(ds1682_init);
-module_exit(ds1682_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/chips/Kconfig linux-libre-2.6.33-gnu1/drivers/i2c/chips/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/i2c/chips/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/chips/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -6,16 +6,6 @@
 
 menu "Miscellaneous I2C Chip support"
 
-config DS1682
-	tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
-	depends on EXPERIMENTAL
-	help
-	  If you say yes here you get support for Dallas Semiconductor
-	  DS1682 Total Elapsed Time Recorder.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called ds1682.
-
 config SENSORS_TSL2550
 	tristate "Taos TSL2550 ambient light sensor"
 	depends on EXPERIMENTAL
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/chips/Makefile linux-libre-2.6.33-gnu1/drivers/i2c/chips/Makefile
--- linux-libre-2.6.32-gnu1/drivers/i2c/chips/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/chips/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,6 @@
 # * I/O expander drivers go to drivers/gpio
 #
 
-obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/i2c-core.c linux-libre-2.6.33-gnu1/drivers/i2c/i2c-core.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/i2c-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/i2c-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -155,6 +155,35 @@ static void i2c_device_shutdown(struct d
 		driver->shutdown(client);
 }
 
+#ifdef CONFIG_SUSPEND
+static int i2c_device_pm_suspend(struct device *dev)
+{
+	const struct dev_pm_ops *pm;
+
+	if (!dev->driver)
+		return 0;
+	pm = dev->driver->pm;
+	if (!pm || !pm->suspend)
+		return 0;
+	return pm->suspend(dev);
+}
+
+static int i2c_device_pm_resume(struct device *dev)
+{
+	const struct dev_pm_ops *pm;
+
+	if (!dev->driver)
+		return 0;
+	pm = dev->driver->pm;
+	if (!pm || !pm->resume)
+		return 0;
+	return pm->resume(dev);
+}
+#else
+#define i2c_device_pm_suspend	NULL
+#define i2c_device_pm_resume	NULL
+#endif
+
 static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct i2c_client *client = i2c_verify_client(dev);
@@ -219,6 +248,11 @@ static const struct attribute_group *i2c
 	NULL
 };
 
+static const struct dev_pm_ops i2c_device_pm_ops = {
+	.suspend = i2c_device_pm_suspend,
+	.resume = i2c_device_pm_resume,
+};
+
 struct bus_type i2c_bus_type = {
 	.name		= "i2c",
 	.match		= i2c_device_match,
@@ -227,6 +261,7 @@ struct bus_type i2c_bus_type = {
 	.shutdown	= i2c_device_shutdown,
 	.suspend	= i2c_device_suspend,
 	.resume		= i2c_device_resume,
+	.pm		= &i2c_device_pm_ops,
 };
 EXPORT_SYMBOL_GPL(i2c_bus_type);
 
@@ -558,11 +593,9 @@ static void i2c_scan_static_board_info(s
 	up_read(&__i2c_board_lock);
 }
 
-static int i2c_do_add_adapter(struct device_driver *d, void *data)
+static int i2c_do_add_adapter(struct i2c_driver *driver,
+			      struct i2c_adapter *adap)
 {
-	struct i2c_driver *driver = to_i2c_driver(d);
-	struct i2c_adapter *adap = data;
-
 	/* Detect supported devices on that bus, and instantiate them */
 	i2c_detect(adap, driver);
 
@@ -574,6 +607,11 @@ static int i2c_do_add_adapter(struct dev
 	return 0;
 }
 
+static int __process_new_adapter(struct device_driver *d, void *data)
+{
+	return i2c_do_add_adapter(to_i2c_driver(d), data);
+}
+
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
 	int res = 0, dummy;
@@ -584,7 +622,7 @@ static int i2c_register_adapter(struct i
 		goto out_list;
 	}
 
-	mutex_init(&adap->bus_lock);
+	rt_mutex_init(&adap->bus_lock);
 
 	/* Set default timeout to 1 second if not already set */
 	if (adap->timeout == 0)
@@ -614,7 +652,7 @@ static int i2c_register_adapter(struct i
 	/* Notify drivers */
 	mutex_lock(&core_lock);
 	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-				 i2c_do_add_adapter);
+				 __process_new_adapter);
 	mutex_unlock(&core_lock);
 
 	return 0;
@@ -715,10 +753,9 @@ retry:
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
-static int i2c_do_del_adapter(struct device_driver *d, void *data)
+static int i2c_do_del_adapter(struct i2c_driver *driver,
+			      struct i2c_adapter *adapter)
 {
-	struct i2c_driver *driver = to_i2c_driver(d);
-	struct i2c_adapter *adapter = data;
 	struct i2c_client *client, *_n;
 	int res;
 
@@ -750,6 +787,11 @@ static int __unregister_client(struct de
 	return 0;
 }
 
+static int __process_removed_adapter(struct device_driver *d, void *data)
+{
+	return i2c_do_del_adapter(to_i2c_driver(d), data);
+}
+
 /**
  * i2c_del_adapter - unregister I2C adapter
  * @adap: the adapter being unregistered
@@ -777,7 +819,7 @@ int i2c_del_adapter(struct i2c_adapter *
 	/* Tell drivers about this removal */
 	mutex_lock(&core_lock);
 	res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-			       i2c_do_del_adapter);
+			       __process_removed_adapter);
 	mutex_unlock(&core_lock);
 	if (res)
 		return res;
@@ -801,6 +843,9 @@ int i2c_del_adapter(struct i2c_adapter *
 				 adap->dev.parent);
 #endif
 
+	/* device name is gone after device_unregister */
+	dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
+
 	/* clean up the sysfs representation */
 	init_completion(&adap->dev_released);
 	device_unregister(&adap->dev);
@@ -813,8 +858,6 @@ int i2c_del_adapter(struct i2c_adapter *
 	idr_remove(&i2c_adapter_idr, adap->nr);
 	mutex_unlock(&core_lock);
 
-	dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
-
 	/* Clear the device structure in case this adapter is ever going to be
 	   added again */
 	memset(&adap->dev, 0, sizeof(adap->dev));
@@ -826,22 +869,11 @@ EXPORT_SYMBOL(i2c_del_adapter);
 
 /* ------------------------------------------------------------------------- */
 
-static int __attach_adapter(struct device *dev, void *data)
+static int __process_new_driver(struct device *dev, void *data)
 {
-	struct i2c_adapter *adapter;
-	struct i2c_driver *driver = data;
-
 	if (dev->type != &i2c_adapter_type)
 		return 0;
-	adapter = to_i2c_adapter(dev);
-
-	i2c_detect(adapter, driver);
-
-	/* Legacy drivers scan i2c busses directly */
-	if (driver->attach_adapter)
-		driver->attach_adapter(adapter);
-
-	return 0;
+	return i2c_do_add_adapter(data, to_i2c_adapter(dev));
 }
 
 /*
@@ -873,40 +905,18 @@ int i2c_register_driver(struct module *o
 	INIT_LIST_HEAD(&driver->clients);
 	/* Walk the adapters that are already present */
 	mutex_lock(&core_lock);
-	bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
+	bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
 	mutex_unlock(&core_lock);
 
 	return 0;
 }
 EXPORT_SYMBOL(i2c_register_driver);
 
-static int __detach_adapter(struct device *dev, void *data)
+static int __process_removed_driver(struct device *dev, void *data)
 {
-	struct i2c_adapter *adapter;
-	struct i2c_driver *driver = data;
-	struct i2c_client *client, *_n;
-
 	if (dev->type != &i2c_adapter_type)
 		return 0;
-	adapter = to_i2c_adapter(dev);
-
-	/* Remove the devices we created ourselves as the result of hardware
-	 * probing (using a driver's detect method) */
-	list_for_each_entry_safe(client, _n, &driver->clients, detected) {
-		dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
-			client->name, client->addr);
-		list_del(&client->detected);
-		i2c_unregister_device(client);
-	}
-
-	if (driver->detach_adapter) {
-		if (driver->detach_adapter(adapter))
-			dev_err(&adapter->dev,
-				"detach_adapter failed for driver [%s]\n",
-				driver->driver.name);
-	}
-
-	return 0;
+	return i2c_do_del_adapter(data, to_i2c_adapter(dev));
 }
 
 /**
@@ -917,7 +927,7 @@ static int __detach_adapter(struct devic
 void i2c_del_driver(struct i2c_driver *driver)
 {
 	mutex_lock(&core_lock);
-	bus_for_each_dev(&i2c_bus_type, NULL, driver, __detach_adapter);
+	bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_removed_driver);
 	mutex_unlock(&core_lock);
 
 	driver_unregister(&driver->driver);
@@ -1092,12 +1102,12 @@ int i2c_transfer(struct i2c_adapter *ada
 #endif
 
 		if (in_atomic() || irqs_disabled()) {
-			ret = mutex_trylock(&adap->bus_lock);
+			ret = rt_mutex_trylock(&adap->bus_lock);
 			if (!ret)
 				/* I2C activity is ongoing. */
 				return -EAGAIN;
 		} else {
-			mutex_lock_nested(&adap->bus_lock, adap->level);
+			rt_mutex_lock(&adap->bus_lock);
 		}
 
 		/* Retry automatically on arbitration loss */
@@ -1109,7 +1119,7 @@ int i2c_transfer(struct i2c_adapter *ada
 			if (time_after(jiffies, orig_jiffies + adap->timeout))
 				break;
 		}
-		mutex_unlock(&adap->bus_lock);
+		rt_mutex_unlock(&adap->bus_lock);
 
 		return ret;
 	} else {
@@ -1180,7 +1190,7 @@ EXPORT_SYMBOL(i2c_master_recv);
  * ----------------------------------------------------
  */
 
-static int i2c_detect_address(struct i2c_client *temp_client, int kind,
+static int i2c_detect_address(struct i2c_client *temp_client,
 			      struct i2c_driver *driver)
 {
 	struct i2c_board_info info;
@@ -1199,22 +1209,18 @@ static int i2c_detect_address(struct i2c
 	if (i2c_check_addr(adapter, addr))
 		return 0;
 
-	/* Make sure there is something at this address, unless forced */
-	if (kind < 0) {
-		if (i2c_smbus_xfer(adapter, addr, 0, 0, 0,
-				   I2C_SMBUS_QUICK, NULL) < 0)
-			return 0;
+	/* Make sure there is something at this address */
+	if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
+		return 0;
 
-		/* prevent 24RF08 corruption */
-		if ((addr & ~0x0f) == 0x50)
-			i2c_smbus_xfer(adapter, addr, 0, 0, 0,
-				       I2C_SMBUS_QUICK, NULL);
-	}
+	/* Prevent 24RF08 corruption */
+	if ((addr & ~0x0f) == 0x50)
+		i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
 
 	/* Finally call the custom detection function */
 	memset(&info, 0, sizeof(struct i2c_board_info));
 	info.addr = addr;
-	err = driver->detect(temp_client, kind, &info);
+	err = driver->detect(temp_client, &info);
 	if (err) {
 		/* -ENODEV is returned if the detection fails. We catch it
 		   here as this isn't an error. */
@@ -1244,13 +1250,13 @@ static int i2c_detect_address(struct i2c
 
 static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
 {
-	const struct i2c_client_address_data *address_data;
+	const unsigned short *address_list;
 	struct i2c_client *temp_client;
 	int i, err = 0;
 	int adap_id = i2c_adapter_id(adapter);
 
-	address_data = driver->address_data;
-	if (!driver->detect || !address_data)
+	address_list = driver->address_list;
+	if (!driver->detect || !address_list)
 		return 0;
 
 	/* Set up a temporary client to help detect callback */
@@ -1259,40 +1265,13 @@ static int i2c_detect(struct i2c_adapter
 		return -ENOMEM;
 	temp_client->adapter = adapter;
 
-	/* Force entries are done first, and are not affected by ignore
-	   entries */
-	if (address_data->forces) {
-		const unsigned short * const *forces = address_data->forces;
-		int kind;
-
-		for (kind = 0; forces[kind]; kind++) {
-			for (i = 0; forces[kind][i] != I2C_CLIENT_END;
-			     i += 2) {
-				if (forces[kind][i] == adap_id
-				 || forces[kind][i] == ANY_I2C_BUS) {
-					dev_dbg(&adapter->dev, "found force "
-						"parameter for adapter %d, "
-						"addr 0x%02x, kind %d\n",
-						adap_id, forces[kind][i + 1],
-						kind);
-					temp_client->addr = forces[kind][i + 1];
-					err = i2c_detect_address(temp_client,
-						kind, driver);
-					if (err)
-						goto exit_free;
-				}
-			}
-		}
-	}
-
 	/* Stop here if the classes do not match */
 	if (!(adapter->class & driver->class))
 		goto exit_free;
 
 	/* Stop here if we can't use SMBUS_QUICK */
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
-		if (address_data->probe[0] == I2C_CLIENT_END
-		 && address_data->normal_i2c[0] == I2C_CLIENT_END)
+		if (address_list[0] == I2C_CLIENT_END)
 			goto exit_free;
 
 		dev_warn(&adapter->dev, "SMBus Quick command not supported, "
@@ -1301,48 +1280,11 @@ static int i2c_detect(struct i2c_adapter
 		goto exit_free;
 	}
 
-	/* Probe entries are done second, and are not affected by ignore
-	   entries either */
-	for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {
-		if (address_data->probe[i] == adap_id
-		 || address_data->probe[i] == ANY_I2C_BUS) {
-			dev_dbg(&adapter->dev, "found probe parameter for "
-				"adapter %d, addr 0x%02x\n", adap_id,
-				address_data->probe[i + 1]);
-			temp_client->addr = address_data->probe[i + 1];
-			err = i2c_detect_address(temp_client, -1, driver);
-			if (err)
-				goto exit_free;
-		}
-	}
-
-	/* Normal entries are done last, unless shadowed by an ignore entry */
-	for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) {
-		int j, ignore;
-
-		ignore = 0;
-		for (j = 0; address_data->ignore[j] != I2C_CLIENT_END;
-		     j += 2) {
-			if ((address_data->ignore[j] == adap_id ||
-			     address_data->ignore[j] == ANY_I2C_BUS)
-			 && address_data->ignore[j + 1]
-			    == address_data->normal_i2c[i]) {
-				dev_dbg(&adapter->dev, "found ignore "
-					"parameter for adapter %d, "
-					"addr 0x%02x\n", adap_id,
-					address_data->ignore[j + 1]);
-				ignore = 1;
-				break;
-			}
-		}
-		if (ignore)
-			continue;
-
+	for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
 		dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
-			"addr 0x%02x\n", adap_id,
-			address_data->normal_i2c[i]);
-		temp_client->addr = address_data->normal_i2c[i];
-		err = i2c_detect_address(temp_client, -1, driver);
+			"addr 0x%02x\n", adap_id, address_list[i]);
+		temp_client->addr = address_list[i];
+		err = i2c_detect_address(temp_client, driver);
 		if (err)
 			goto exit_free;
 	}
@@ -1913,7 +1855,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *a
 	flags &= I2C_M_TEN | I2C_CLIENT_PEC;
 
 	if (adapter->algo->smbus_xfer) {
-		mutex_lock(&adapter->bus_lock);
+		rt_mutex_lock(&adapter->bus_lock);
 
 		/* Retry automatically on arbitration loss */
 		orig_jiffies = jiffies;
@@ -1927,7 +1869,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *a
 				       orig_jiffies + adapter->timeout))
 				break;
 		}
-		mutex_unlock(&adapter->bus_lock);
+		rt_mutex_unlock(&adapter->bus_lock);
 	} else
 		res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
 					      command, protocol, data);
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/i2c-dev.c linux-libre-2.6.33-gnu1/drivers/i2c/i2c-dev.c
--- linux-libre-2.6.32-gnu1/drivers/i2c/i2c-dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/i2c-dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,6 @@
 #include <linux/list.h>
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
-#include <linux/smp_lock.h>
 #include <linux/jiffies.h>
 #include <asm/uaccess.h>
 
@@ -445,20 +444,14 @@ static int i2cdev_open(struct inode *ino
 	struct i2c_client *client;
 	struct i2c_adapter *adap;
 	struct i2c_dev *i2c_dev;
-	int ret = 0;
 
-	lock_kernel();
 	i2c_dev = i2c_dev_get_by_minor(minor);
-	if (!i2c_dev) {
-		ret = -ENODEV;
-		goto out;
-	}
+	if (!i2c_dev)
+		return -ENODEV;
 
 	adap = i2c_get_adapter(i2c_dev->adap->nr);
-	if (!adap) {
-		ret = -ENODEV;
-		goto out;
-	}
+	if (!adap)
+		return -ENODEV;
 
 	/* This creates an anonymous i2c_client, which may later be
 	 * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
@@ -470,8 +463,7 @@ static int i2cdev_open(struct inode *ino
 	client = kzalloc(sizeof(*client), GFP_KERNEL);
 	if (!client) {
 		i2c_put_adapter(adap);
-		ret = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
 	client->driver = &i2cdev_driver;
@@ -479,9 +471,7 @@ static int i2cdev_open(struct inode *ino
 	client->adapter = adap;
 	file->private_data = client;
 
-out:
-	unlock_kernel();
-	return ret;
+	return 0;
 }
 
 static int i2cdev_release(struct inode *inode, struct file *file)
diff -druNp linux-libre-2.6.32-gnu1/drivers/i2c/Kconfig linux-libre-2.6.33-gnu1/drivers/i2c/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/i2c/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/i2c/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
 menuconfig I2C
 	tristate "I2C support"
 	depends on HAS_IOMEM
+	select RT_MUTEXES
 	---help---
 	  I2C (pronounce: I-square-C) is a slow serial bus protocol used in
 	  many micro controller applications and developed by Philips.  SMBus,
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/alim15x3.c linux-libre-2.6.33-gnu1/drivers/ide/alim15x3.c
--- linux-libre-2.6.32-gnu1/drivers/ide/alim15x3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/alim15x3.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,16 +40,6 @@
 #define DRV_NAME "alim15x3"
 
 /*
- * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking
- * (this is DANGEROUS and could result in data corruption).
- */
-static int wdc_udma;
-
-module_param(wdc_udma, bool, 0);
-MODULE_PARM_DESC(wdc_udma,
-		 "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)");
-
-/*
  *	ALi devices are not plug in. Otherwise these static values would
  *	need to go. They ought to go away anyway
  */
@@ -132,7 +122,7 @@ static u8 ali_udma_filter(ide_drive_t *d
 	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
 		if (drive->media != ide_disk)
 			return 0;
-		if (wdc_udma == 0 && chip_is_1543c_e &&
+		if (chip_is_1543c_e &&
 		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
 			return 0;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/au1xxx-ide.c linux-libre-2.6.33-gnu1/drivers/ide/au1xxx-ide.c
--- linux-libre-2.6.32-gnu1/drivers/ide/au1xxx-ide.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/au1xxx-ide.c	2010-02-24 13:52:17.000000000 -0500
@@ -532,14 +532,13 @@ static int au_ide_probe(struct platform_
 		goto out;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
-				dev->name)) {
+	if (!request_mem_region(res->start, resource_size(res), dev->name)) {
 		pr_debug("%s: request_mem_region failed\n", DRV_NAME);
 		ret =  -EBUSY;
 		goto out;
 	}
 
-	ahwif->regbase = (u32)ioremap(res->start, res->end - res->start + 1);
+	ahwif->regbase = (u32)ioremap(res->start, resource_size(res));
 	if (ahwif->regbase == 0) {
 		ret = -ENOMEM;
 		goto out;
@@ -575,7 +574,7 @@ static int au_ide_remove(struct platform
 	iounmap((void *)ahwif->regbase);
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/cmd64x.c linux-libre-2.6.33-gnu1/drivers/ide/cmd64x.c
--- linux-libre-2.6.32-gnu1/drivers/ide/cmd64x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/cmd64x.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,14 +20,6 @@
 
 #define DRV_NAME "cmd64x"
 
-#define CMD_DEBUG 0
-
-#if CMD_DEBUG
-#define cmdprintk(x...)	printk(x)
-#else
-#define cmdprintk(x...)
-#endif
-
 /*
  * CMD64x specific registers definition.
  */
@@ -76,9 +68,6 @@ static void program_cycle_times (ide_dri
 		{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
 	static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
 
-	cmdprintk("program_cycle_times parameters: total=%d, active=%d\n",
-		  cycle_time, active_time);
-
 	cycle_count	= quantize_timing( cycle_time, clock_time);
 	active_count	= quantize_timing(active_time, clock_time);
 	recovery_count	= cycle_count - active_count;
@@ -94,9 +83,6 @@ static void program_cycle_times (ide_dri
 	if (active_count > 16)		/* shouldn't actually happen... */
 	 	active_count = 16;
 
-	cmdprintk("Final counts: total=%d, active=%d, recovery=%d\n",
-		  cycle_count, active_count, recovery_count);
-
 	/*
 	 * Convert values to internal chipset representation
 	 */
@@ -106,7 +92,6 @@ static void program_cycle_times (ide_dri
 	/* Program the active/recovery counts into the DRWTIM register */
 	drwtim = (active_count << 4) | recovery_count;
 	(void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim);
-	cmdprintk("Write 0x%02x to reg 0x%x\n", drwtim, drwtim_regs[drive->dn]);
 }
 
 /*
@@ -150,7 +135,6 @@ static void cmd64x_tune_pio(ide_drive_t
 
 	if (setup_count > 5)		/* shouldn't actually happen... */
 		setup_count = 5;
-	cmdprintk("Final address setup count: %d\n", setup_count);
 
 	/*
 	 * Program the address setup clocks into the ARTTIM registers.
@@ -162,7 +146,6 @@ static void cmd64x_tune_pio(ide_drive_t
 	arttim &= ~0xc0;
 	arttim |= setup_values[setup_count];
 	(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
-	cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/cs5535.c linux-libre-2.6.33-gnu1/drivers/ide/cs5535.c
--- linux-libre-2.6.32-gnu1/drivers/ide/cs5535.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/cs5535.c	2010-02-24 13:52:17.000000000 -0500
@@ -187,6 +187,7 @@ static int __devinit cs5535_init_one(str
 
 static const struct pci_device_id cs5535_pci_tbl[] = {
 	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 },
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5535_IDE), },
 	{ 0, },
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/cy82c693.c linux-libre-2.6.33-gnu1/drivers/ide/cy82c693.c
--- linux-libre-2.6.32-gnu1/drivers/ide/cy82c693.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/cy82c693.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,11 +51,6 @@
 #define DRV_NAME "cy82c693"
 
 /*
- *	The following are used to debug the driver.
- */
-#define CY82C693_DEBUG_INFO	0
-
-/*
  *	NOTE: the value for busmaster timeout is tricky and I got it by
  *	trial and error!  By using a to low value will cause DMA timeouts
  *	and drop IDE performance, and by using a to high value will cause
@@ -176,11 +171,6 @@ static void cy82c693_set_dma_mode(ide_dr
 	outb(index, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
 
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
-		drive->name, hwif->channel, drive->dn & 1, mode & 3, single);
-#endif /* CY82C693_DEBUG_INFO */
-
 	/*
 	 * note: below we set the value for Bus Master IDE TimeOut Register
 	 * I'm not absolutly sure what this does, but it solved my problem
@@ -194,11 +184,6 @@ static void cy82c693_set_dma_mode(ide_dr
 	data = BUSMASTER_TIMEOUT;
 	outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
-
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
-		drive->name, data);
-#endif /* CY82C693_DEBUG_INFO */
 }
 
 static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -239,8 +224,6 @@ static void cy82c693_set_pio_mode(ide_dr
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-
-		addrCtrl &= 0xF;
 	} else {
 		/*
 		 * set slave drive
@@ -257,17 +240,7 @@ static void cy82c693_set_pio_mode(ide_dr
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
-
-		addrCtrl >>= 4;
-		addrCtrl &= 0xF;
 	}
-
-#if CY82C693_DEBUG_INFO
-	printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
-		"(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
-		drive->name, hwif->channel, drive->dn & 1,
-		addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
-#endif /* CY82C693_DEBUG_INFO */
 }
 
 static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/hpt366.c linux-libre-2.6.33-gnu1/drivers/ide/hpt366.c
--- linux-libre-2.6.32-gnu1/drivers/ide/hpt366.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/hpt366.c	2010-02-24 13:52:17.000000000 -0500
@@ -297,68 +297,6 @@ static u32 twenty_five_base_hpt36x[] = {
 	/* XFER_PIO_0 */	0xc0d08585
 };
 
-#if 0
-/* These are the timing tables from the HighPoint open source drivers... */
-static u32 thirty_three_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x12446231,	/* 0x12646231 ?? */
-	/* XFER_UDMA_5 */	0x12446231,
-	/* XFER_UDMA_4 */	0x12446231,
-	/* XFER_UDMA_3 */	0x126c6231,
-	/* XFER_UDMA_2 */	0x12486231,
-	/* XFER_UDMA_1 */	0x124c6233,
-	/* XFER_UDMA_0 */	0x12506297,
-
-	/* XFER_MW_DMA_2 */	0x22406c31,
-	/* XFER_MW_DMA_1 */	0x22406c33,
-	/* XFER_MW_DMA_0 */	0x22406c97,
-
-	/* XFER_PIO_4 */	0x06414e31,
-	/* XFER_PIO_3 */	0x06414e42,
-	/* XFER_PIO_2 */	0x06414e53,
-	/* XFER_PIO_1 */	0x06814e93,
-	/* XFER_PIO_0 */	0x06814ea7
-};
-
-static u32 fifty_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x12848242,
-	/* XFER_UDMA_5 */	0x12848242,
-	/* XFER_UDMA_4 */	0x12ac8242,
-	/* XFER_UDMA_3 */	0x128c8242,
-	/* XFER_UDMA_2 */	0x120c8242,
-	/* XFER_UDMA_1 */	0x12148254,
-	/* XFER_UDMA_0 */	0x121882ea,
-
-	/* XFER_MW_DMA_2 */	0x22808242,
-	/* XFER_MW_DMA_1 */	0x22808254,
-	/* XFER_MW_DMA_0 */	0x228082ea,
-
-	/* XFER_PIO_4 */	0x0a81f442,
-	/* XFER_PIO_3 */	0x0a81f443,
-	/* XFER_PIO_2 */	0x0a81f454,
-	/* XFER_PIO_1 */	0x0ac1f465,
-	/* XFER_PIO_0 */	0x0ac1f48a
-};
-
-static u32 sixty_six_base_hpt37x[] = {
-	/* XFER_UDMA_6 */	0x1c869c62,
-	/* XFER_UDMA_5 */	0x1cae9c62,	/* 0x1c8a9c62 */
-	/* XFER_UDMA_4 */	0x1c8a9c62,
-	/* XFER_UDMA_3 */	0x1c8e9c62,
-	/* XFER_UDMA_2 */	0x1c929c62,
-	/* XFER_UDMA_1 */	0x1c9a9c62,
-	/* XFER_UDMA_0 */	0x1c829c62,
-
-	/* XFER_MW_DMA_2 */	0x2c829c62,
-	/* XFER_MW_DMA_1 */	0x2c829c66,
-	/* XFER_MW_DMA_0 */	0x2c829d2e,
-
-	/* XFER_PIO_4 */	0x0c829c62,
-	/* XFER_PIO_3 */	0x0c829c84,
-	/* XFER_PIO_2 */	0x0c829ca6,
-	/* XFER_PIO_1 */	0x0d029d26,
-	/* XFER_PIO_0 */	0x0d029d5e
-};
-#else
 /*
  * The following are the new timing tables with PIO mode data/taskfile transfer
  * overclocking fixed...
@@ -424,16 +362,13 @@ static u32 sixty_six_base_hpt37x[] = {
 	/* XFER_PIO_1 */	0x0d02ff26,
 	/* XFER_PIO_0 */	0x0d42ff7f
 };
-#endif
 
-#define HPT366_DEBUG_DRIVE_INFO		0
 #define HPT371_ALLOW_ATA133_6		1
 #define HPT302_ALLOW_ATA133_6		1
 #define HPT372_ALLOW_ATA133_6		1
 #define HPT370_ALLOW_ATA100_5		0
 #define HPT366_ALLOW_ATA66_4		1
 #define HPT366_ALLOW_ATA66_3		1
-#define HPT366_MAX_DEVS			8
 
 /* Supported ATA clock frequencies */
 enum ata_clock {
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/ide-cs.c linux-libre-2.6.33-gnu1/drivers/ide/ide-cs.c
--- linux-libre-2.6.32-gnu1/drivers/ide/ide-cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/ide-cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,15 +60,6 @@ MODULE_AUTHOR("David Hinds <dahinds@user
 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-#ifdef CONFIG_PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
 typedef struct ide_info_t {
@@ -98,7 +89,7 @@ static int ide_probe(struct pcmcia_devic
 {
     ide_info_t *info;
 
-    DEBUG(0, "ide_attach()\n");
+    dev_dbg(&link->dev, "ide_attach()\n");
 
     /* Create new ide device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -112,7 +103,6 @@ static int ide_probe(struct pcmcia_devic
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -134,7 +124,7 @@ static void ide_detach(struct pcmcia_dev
     ide_hwif_t *hwif = info->host->ports[0];
     unsigned long data_addr, ctl_addr;
 
-    DEBUG(0, "ide_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
 
     data_addr = hwif->io_ports.data_addr;
     ctl_addr  = hwif->io_ports.ctl_addr;
@@ -217,9 +207,6 @@ out_release:
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 struct pcmcia_config_check {
 	unsigned long ctl_base;
 	int skip_vcc;
@@ -282,11 +269,11 @@ static int ide_config(struct pcmcia_devi
 {
     ide_info_t *info = link->priv;
     struct pcmcia_config_check *stk = NULL;
-    int last_ret = 0, last_fn = 0, is_kme = 0;
+    int ret = 0, is_kme = 0;
     unsigned long io_base, ctl_base;
     struct ide_host *host;
 
-    DEBUG(0, "ide_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
 
     is_kme = ((link->manf_id == MANFID_KME) &&
 	      ((link->card_id == PRODID_KME_KXLC005_A) ||
@@ -306,8 +293,12 @@ static int ide_config(struct pcmcia_devi
     io_base = link->io.BasePort1;
     ctl_base = stk->ctl_base;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     /* disable drive interrupts during IDE probe */
     outb(0x02, ctl_base);
@@ -342,8 +333,6 @@ err_mem:
     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
     goto failed;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     kfree(stk);
     ide_release(link);
@@ -363,7 +352,7 @@ static void ide_release(struct pcmcia_de
     ide_info_t *info = link->priv;
     struct ide_host *host = info->host;
 
-    DEBUG(0, "ide_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
 
     if (info->ndev)
 	/* FIXME: if this fails we need to queue the cleanup somehow
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/ide-pci-generic.c linux-libre-2.6.33-gnu1/drivers/ide/ide-pci-generic.c
--- linux-libre-2.6.32-gnu1/drivers/ide/ide-pci-generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/ide-pci-generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,9 +162,10 @@ static const struct pci_device_id generi
 #ifdef CONFIG_BLK_DEV_IDE_SATA
 	{ PCI_VDEVICE(VIA,	PCI_DEVICE_ID_VIA_8237_SATA),		 5 },
 #endif
-	{ PCI_VDEVICE(TOSHIBA,	PCI_DEVICE_ID_TOSHIBA_PICCOLO),		 4 },
 	{ PCI_VDEVICE(TOSHIBA,	PCI_DEVICE_ID_TOSHIBA_PICCOLO_1),	 4 },
 	{ PCI_VDEVICE(TOSHIBA,	PCI_DEVICE_ID_TOSHIBA_PICCOLO_2),	 4 },
+	{ PCI_VDEVICE(TOSHIBA,	PCI_DEVICE_ID_TOSHIBA_PICCOLO_3),	 4 },
+	{ PCI_VDEVICE(TOSHIBA,	PCI_DEVICE_ID_TOSHIBA_PICCOLO_5),	 4 },
 	{ PCI_VDEVICE(NETCELL,	PCI_DEVICE_ID_REVOLUTION),		 6 },
 	/*
 	 * Must come last.  If you add entries adjust
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/ide_platform.c linux-libre-2.6.33-gnu1/drivers/ide/ide_platform.c
--- linux-libre-2.6.32-gnu1/drivers/ide/ide_platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/ide_platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,14 +81,14 @@ static int __devinit plat_ide_probe(stru
 
 	if (mmio) {
 		base = devm_ioremap(&pdev->dev,
-			res_base->start, res_base->end - res_base->start + 1);
+			res_base->start, resource_size(res_base));
 		alt_base = devm_ioremap(&pdev->dev,
-			res_alt->start, res_alt->end - res_alt->start + 1);
+			res_alt->start, resource_size(res_alt));
 	} else {
 		base = devm_ioport_map(&pdev->dev,
-			res_base->start, res_base->end - res_base->start + 1);
+			res_base->start, resource_size(res_base));
 		alt_base = devm_ioport_map(&pdev->dev,
-			res_alt->start, res_alt->end - res_alt->start + 1);
+			res_alt->start, resource_size(res_alt));
 	}
 
 	memset(&hw, 0, sizeof(hw));
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/ide-tape.c linux-libre-2.6.33-gnu1/drivers/ide/ide-tape.c
--- linux-libre-2.6.32-gnu1/drivers/ide/ide-tape.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/ide-tape.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,6 +221,8 @@ typedef struct ide_tape_obj {
 
 static DEFINE_MUTEX(idetape_ref_mutex);
 
+static DEFINE_MUTEX(idetape_chrdev_mutex);
+
 static struct class *idetape_sysfs_class;
 
 static void ide_tape_release(struct device *);
@@ -1457,10 +1459,11 @@ static int idetape_chrdev_open(struct in
 	if (i >= MAX_HWIFS * MAX_DRIVES)
 		return -ENXIO;
 
-	lock_kernel();
+	mutex_lock(&idetape_chrdev_mutex);
+
 	tape = ide_tape_get(NULL, true, i);
 	if (!tape) {
-		unlock_kernel();
+		mutex_unlock(&idetape_chrdev_mutex);
 		return -ENXIO;
 	}
 
@@ -1519,12 +1522,15 @@ static int idetape_chrdev_open(struct in
 				tape->door_locked = DOOR_LOCKED;
 		}
 	}
-	unlock_kernel();
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return 0;
 
 out_put_tape:
 	ide_tape_put(tape);
-	unlock_kernel();
+
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return retval;
 }
 
@@ -1551,7 +1557,8 @@ static int idetape_chrdev_release(struct
 	ide_drive_t *drive = tape->drive;
 	unsigned int minor = iminor(inode);
 
-	lock_kernel();
+	mutex_lock(&idetape_chrdev_mutex);
+
 	tape = drive->driver_data;
 
 	ide_debug_log(IDE_DBG_FUNC, "enter");
@@ -1575,7 +1582,9 @@ static int idetape_chrdev_release(struct
 	}
 	clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
 	ide_tape_put(tape);
-	unlock_kernel();
+
+	mutex_unlock(&idetape_chrdev_mutex);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/Kconfig linux-libre-2.6.33-gnu1/drivers/ide/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/ide/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -7,50 +7,25 @@ config HAVE_IDE
 	bool
 
 menuconfig IDE
-	tristate "ATA/ATAPI/MFM/RLL support"
+	tristate "ATA/ATAPI/MFM/RLL support (DEPRECATED)"
 	depends on HAVE_IDE
 	depends on BLOCK
 	---help---
-	  If you say Y here, your kernel will be able to manage low cost mass
-	  storage units such as ATA/(E)IDE and ATAPI units. The most common
-	  cases are IDE hard drives and ATAPI CD-ROM drives.
-
-	  If your system is pure SCSI and doesn't use these interfaces, you
-	  can say N here.
-
-	  Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
-	  for mass storage units such as hard disks. It was designed by
-	  Western Digital and Compaq Computer in 1984. It was then named
-	  ST506. Quite a number of disks use the IDE interface.
-
-	  AT Attachment (ATA) is the superset of the IDE specifications.
-	  ST506 was also called ATA-1.
-
-	  Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
-	  ATA-3. It provides support for larger disks (up to 8.4GB by means of
-	  the LBA standard), more disks (4 instead of 2) and for other mass
-	  storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
-	  ATA-4 and provides faster (and more CPU friendly) transfer modes
-	  than previous PIO (Programmed processor Input/Output) from previous
-	  ATA/IDE standards by means of fast DMA controllers.
-
-	  ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
-	  CD-ROM drives, similar in many respects to the SCSI protocol.
+	  If you say Y here, your kernel will be able to manage ATA/(E)IDE and
+	  ATAPI units. The most common cases are IDE hard drives and ATAPI
+	  CD-ROM drives.
 
-	  SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
-	  designed in order to prevent data corruption and disk crash by
-	  detecting pre hardware failure conditions (heat, access time, and
-	  the like...). Disks built since June 1995 may follow this standard.
-	  The kernel itself doesn't manage this; however there are quite a
-	  number of user programs such as smart that can query the status of
-	  SMART parameters from disk drives.
+	  This subsystem is currently in maintenance mode with only bug fix
+	  changes applied. Users of ATA hardware are encouraged to migrate to
+	  the newer ATA subsystem ("Serial ATA (prod) and Parallel ATA
+	  (experimental) drivers") which is more actively maintained.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ide-core.
 
 	  For further information, please read <file:Documentation/ide/ide.txt>.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 if IDE
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/pdc202xx_old.c linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_old.c
--- linux-libre-2.6.32-gnu1/drivers/ide/pdc202xx_old.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/pdc202xx_old.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,8 +21,6 @@
 
 #define DRV_NAME "pdc202xx_old"
 
-#define PDC202XX_DEBUG_DRIVE_INFO	0
-
 static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
 
 static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
@@ -34,11 +32,6 @@ static void pdc202xx_set_mode(ide_drive_
 	u8			AP = 0, BP = 0, CP = 0;
 	u8			TA = 0, TB = 0, TC = 0;
 
-#if PDC202XX_DEBUG_DRIVE_INFO
-	u32			drive_conf = 0;
-	pci_read_config_dword(dev, drive_pci, &drive_conf);
-#endif
-
 	/*
 	 * TODO: do this once per channel
 	 */
@@ -89,14 +82,6 @@ static void pdc202xx_set_mode(ide_drive_
 		pci_write_config_byte(dev, drive_pci + 1, BP | TB);
 		pci_write_config_byte(dev, drive_pci + 2, CP | TC);
 	}
-
-#if PDC202XX_DEBUG_DRIVE_INFO
-	printk(KERN_DEBUG "%s: %s drive%d 0x%08x ",
-		drive->name, ide_xfer_verbose(speed),
-		drive->dn, drive_conf);
-	pci_read_config_dword(dev, drive_pci, &drive_conf);
-	printk("0x%08x\n", drive_conf);
-#endif
 }
 
 static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/pmac.c linux-libre-2.6.33-gnu1/drivers/ide/pmac.c
--- linux-libre-2.6.32-gnu1/drivers/ide/pmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/pmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,10 +43,7 @@
 #include <asm/pmac_feature.h>
 #include <asm/sections.h>
 #include <asm/irq.h>
-
-#ifndef CONFIG_PPC64
 #include <asm/mediabay.h>
-#endif
 
 #define DRV_NAME "ide-pmac"
 
@@ -59,13 +56,14 @@ typedef struct pmac_ide_hwif {
 	int				irq;
 	int				kind;
 	int				aapl_bus_id;
-	unsigned			mediabay : 1;
 	unsigned			broken_dma : 1;
 	unsigned			broken_dma_warn : 1;
 	struct device_node*		node;
 	struct macio_dev		*mdev;
 	u32				timings[4];
 	volatile u32 __iomem *		*kauai_fcr;
+	ide_hwif_t			*hwif;
+
 	/* Those fields are duplicating what is in hwif. We currently
 	 * can't use the hwif ones because of some assumptions that are
 	 * beeing done by the generic code about the kind of dma controller
@@ -854,6 +852,11 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
 	pmif->timings[2] = pmif->timings[3] = value2;
 }
 
+static int on_media_bay(pmac_ide_hwif_t *pmif)
+{
+	return pmif->mdev && pmif->mdev->media_bay != NULL;
+}
+
 /* Suspend call back, should be called after the child devices
  * have actually been suspended
  */
@@ -866,7 +869,7 @@ static int pmac_ide_do_suspend(pmac_ide_
 	disable_irq(pmif->irq);
 
 	/* The media bay will handle itself just fine */
-	if (pmif->mediabay)
+	if (on_media_bay(pmif))
 		return 0;
 	
 	/* Kauai has bus control FCRs directly here */
@@ -889,7 +892,7 @@ static int pmac_ide_do_suspend(pmac_ide_
 static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
 {
 	/* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
-	if (!pmif->mediabay) {
+	if (!on_media_bay(pmif)) {
 		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);
 		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
 		msleep(10);
@@ -950,13 +953,11 @@ static void pmac_ide_init_dev(ide_drive_
 	pmac_ide_hwif_t *pmif =
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 
-	if (pmif->mediabay) {
-#ifdef CONFIG_PMAC_MEDIABAY
-		if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) {
+	if (on_media_bay(pmif)) {
+		if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
 			drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
 			return;
 		}
-#endif
 		drive->dev_flags |= IDE_DFLAG_NOPROBE;
 	}
 }
@@ -1072,26 +1073,23 @@ static int __devinit pmac_ide_setup_devi
 		writel(KAUAI_FCR_UATA_MAGIC |
 		       KAUAI_FCR_UATA_RESET_N |
 		       KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);
-
-	pmif->mediabay = 0;
 	
 	/* Make sure we have sane timings */
 	sanitize_timings(pmif);
 
+	/* If we are on a media bay, wait for it to settle and lock it */
+	if (pmif->mdev)
+		lock_media_bay(pmif->mdev->media_bay);
+
 	host = ide_host_alloc(&d, hws, 1);
-	if (host == NULL)
-		return -ENOMEM;
-	hwif = host->ports[0];
+	if (host == NULL) {
+		rc = -ENOMEM;
+		goto bail;
+	}
+	hwif = pmif->hwif = host->ports[0];
 
-#ifndef CONFIG_PPC64
-	/* XXX FIXME: Media bay stuff need re-organizing */
-	if (np->parent && np->parent->name
-	    && strcasecmp(np->parent->name, "media-bay") == 0) {
-#ifdef CONFIG_PMAC_MEDIABAY
-		media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
-					hwif);
-#endif /* CONFIG_PMAC_MEDIABAY */
-		pmif->mediabay = 1;
+	if (on_media_bay(pmif)) {
+		/* Fixup bus ID for media bay */
 		if (!bidp)
 			pmif->aapl_bus_id = 1;
 	} else if (pmif->kind == controller_ohare) {
@@ -1100,9 +1098,7 @@ static int __devinit pmac_ide_setup_devi
 		 * units, I keep the old way
 		 */
 		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);
-	} else
-#endif
-	{
+	} else {
  		/* This is necessary to enable IDE when net-booting */
 		ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);
 		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
@@ -1112,17 +1108,21 @@ static int __devinit pmac_ide_setup_devi
 	}
 
 	printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
-			 "bus ID %d%s, irq %d\n", model_name[pmif->kind],
-			 pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
-			 pmif->mediabay ? " (mediabay)" : "", hw->irq);
+	       "bus ID %d%s, irq %d\n", model_name[pmif->kind],
+	       pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
+	       on_media_bay(pmif) ? " (mediabay)" : "", hw->irq);
 
 	rc = ide_host_register(host, &d, hws);
-	if (rc) {
-		ide_host_free(host);
-		return rc;
-	}
+	if (rc)
+		pmif->hwif = NULL;
 
-	return 0;
+	if (pmif->mdev)
+		unlock_media_bay(pmif->mdev->media_bay);
+
+ bail:
+	if (rc && host)
+		ide_host_free(host);
+	return rc;
 }
 
 static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base)
@@ -1362,6 +1362,25 @@ pmac_ide_pci_resume(struct pci_dev *pdev
 	return rc;
 }
 
+#ifdef CONFIG_PMAC_MEDIABAY
+static void pmac_ide_macio_mb_event(struct macio_dev* mdev, int mb_state)
+{
+	pmac_ide_hwif_t *pmif =
+		(pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
+
+	switch(mb_state) {
+	case MB_CD:
+		if (!pmif->hwif->present)
+			ide_port_scan(pmif->hwif);
+		break;
+	default:
+		if (pmif->hwif->present)
+			ide_port_unregister_devices(pmif->hwif);
+	}
+}
+#endif /* CONFIG_PMAC_MEDIABAY */
+
+
 static struct of_device_id pmac_ide_macio_match[] = 
 {
 	{
@@ -1386,6 +1405,9 @@ static struct macio_driver pmac_ide_maci
 	.probe		= pmac_ide_macio_attach,
 	.suspend	= pmac_ide_macio_suspend,
 	.resume		= pmac_ide_macio_resume,
+#ifdef CONFIG_PMAC_MEDIABAY
+	.mediabay_event	= pmac_ide_macio_mb_event,
+#endif
 };
 
 static const struct pci_device_id pmac_ide_pci_match[] = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/sis5513.c linux-libre-2.6.33-gnu1/drivers/ide/sis5513.c
--- linux-libre-2.6.32-gnu1/drivers/ide/sis5513.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/sis5513.c	2010-02-24 13:52:17.000000000 -0500
@@ -632,12 +632,3 @@ module_exit(sis5513_ide_exit);
 MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
 MODULE_DESCRIPTION("PCI driver module for SIS IDE");
 MODULE_LICENSE("GPL");
-
-/*
- * TODO:
- *	- CLEANUP
- *	- More checks in the config registers (force values instead of
- *	  relying on the BIOS setting them correctly).
- *	- Further optimisations ?
- *	  . for example ATA66+ regs 0x48 & 0x4A
- */
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/sl82c105.c linux-libre-2.6.33-gnu1/drivers/ide/sl82c105.c
--- linux-libre-2.6.32-gnu1/drivers/ide/sl82c105.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/sl82c105.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,13 +24,6 @@
 
 #define DRV_NAME "sl82c105"
 
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(arg) printk arg
-#else
-#define DBG(fmt,...)
-#endif
 /*
  * SL82C105 PCI config register 0x40 bits.
  */
@@ -104,9 +97,6 @@ static void sl82c105_set_dma_mode(ide_dr
 	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
 	u16 drv_ctrl;
 
- 	DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
-	     drive->name, ide_xfer_verbose(speed)));
-
 	drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
 
 	/*
@@ -196,8 +186,6 @@ static void sl82c105_dma_start(ide_drive
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	int reg 		= 0x44 + drive->dn * 4;
 
-	DBG(("%s(drive:%s)\n", __func__, drive->name));
-
 	pci_write_config_word(dev, reg,
 			      (unsigned long)ide_get_drivedata(drive) >> 16);
 
@@ -209,8 +197,6 @@ static void sl82c105_dma_clear(ide_drive
 {
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
 
-	DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
-
 	sl82c105_reset_host(dev);
 }
 
@@ -218,11 +204,7 @@ static int sl82c105_dma_end(ide_drive_t
 {
 	struct pci_dev *dev	= to_pci_dev(drive->hwif->dev);
 	int reg 		= 0x44 + drive->dn * 4;
-	int ret;
-
-	DBG(("%s(drive:%s)\n", __func__, drive->name));
-
-	ret = ide_dma_end(drive);
+	int ret			= ide_dma_end(drive);
 
 	pci_write_config_word(dev, reg,
 			      (unsigned long)ide_get_drivedata(drive));
@@ -239,8 +221,6 @@ static void sl82c105_resetproc(ide_drive
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
 	u32 val;
 
-	DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
-
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= (CTRL_P1F16 | CTRL_P0F16);
 	pci_write_config_dword(dev, 0x40, val);
@@ -291,8 +271,6 @@ static int init_chipset_sl82c105(struct
 {
 	u32 val;
 
-	DBG(("init_chipset_sl82c105()\n"));
-
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/slc90e66.c linux-libre-2.6.33-gnu1/drivers/ide/slc90e66.c
--- linux-libre-2.6.32-gnu1/drivers/ide/slc90e66.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/slc90e66.c	2010-02-24 13:52:17.000000000 -0500
@@ -91,8 +91,7 @@ static void slc90e66_set_dma_mode(ide_dr
 
 		if (!(reg48 & u_flag))
 			pci_write_config_word(dev, 0x48, reg48|u_flag);
-		/* FIXME: (reg4a & a_speed) ? */
-		if ((reg4a & u_speed) != u_speed) {
+		if ((reg4a & a_speed) != u_speed) {
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
 			pci_read_config_word(dev, 0x4a, &reg4a);
 			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
diff -druNp linux-libre-2.6.32-gnu1/drivers/ide/tx4938ide.c linux-libre-2.6.33-gnu1/drivers/ide/tx4938ide.c
--- linux-libre-2.6.32-gnu1/drivers/ide/tx4938ide.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ide/tx4938ide.c	2010-02-24 13:52:17.000000000 -0500
@@ -146,7 +146,7 @@ static int __init tx4938ide_probe(struct
 		return -ENODEV;
 
 	if (!devm_request_mem_region(&pdev->dev, res->start,
-				     res->end - res->start + 1, "tx4938ide"))
+				     resource_size(res), "tx4938ide"))
 		return -EBUSY;
 	mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start,
 					      8 << pdata->ioport_shift);
diff -druNp linux-libre-2.6.32-gnu1/drivers/idle/i7300_idle.c linux-libre-2.6.33-gnu1/drivers/idle/i7300_idle.c
--- linux-libre-2.6.32-gnu1/drivers/idle/i7300_idle.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/idle/i7300_idle.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ static u8 i7300_idle_thrtctl_saved;
 static u8 i7300_idle_thrtlow_saved;
 static u32 i7300_idle_mc_saved;
 
-static cpumask_t idle_cpumask;
+static cpumask_var_t idle_cpumask;
 static ktime_t start_ktime;
 static unsigned long avg_idle_us;
 
@@ -459,9 +459,9 @@ static int i7300_idle_notifier(struct no
 	spin_lock_irqsave(&i7300_idle_lock, flags);
 	if (val == IDLE_START) {
 
-		cpu_set(smp_processor_id(), idle_cpumask);
+		cpumask_set_cpu(smp_processor_id(), idle_cpumask);
 
-		if (cpus_weight(idle_cpumask) != num_online_cpus())
+		if (cpumask_weight(idle_cpumask) != num_online_cpus())
 			goto end;
 
 		now_ktime = ktime_get();
@@ -478,8 +478,8 @@ static int i7300_idle_notifier(struct no
 		i7300_idle_ioat_start();
 
 	} else if (val == IDLE_END) {
-		cpu_clear(smp_processor_id(), idle_cpumask);
-		if (cpus_weight(idle_cpumask) == (num_online_cpus() - 1)) {
+		cpumask_clear_cpu(smp_processor_id(), idle_cpumask);
+		if (cpumask_weight(idle_cpumask) == (num_online_cpus() - 1)) {
 			/* First CPU coming out of idle */
 			u64 idle_duration_us;
 
@@ -553,7 +553,6 @@ struct debugfs_file_info {
 static int __init i7300_idle_init(void)
 {
 	spin_lock_init(&i7300_idle_lock);
-	cpus_clear(idle_cpumask);
 	total_us = 0;
 
 	if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload))
@@ -565,6 +564,9 @@ static int __init i7300_idle_init(void)
 	if (i7300_idle_ioat_init())
 		return -ENODEV;
 
+	if (!zalloc_cpumask_var(&idle_cpumask, GFP_KERNEL))
+		return -ENOMEM;
+
 	debugfs_dir = debugfs_create_dir("i7300_idle", NULL);
 	if (debugfs_dir) {
 		int i = 0;
@@ -589,6 +591,7 @@ static int __init i7300_idle_init(void)
 static void __exit i7300_idle_exit(void)
 {
 	idle_notifier_unregister(&i7300_idle_nb);
+	free_cpumask_var(idle_cpumask);
 
 	if (debugfs_dir) {
 		int i = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ieee1394/dv1394.c linux-libre-2.6.33-gnu1/drivers/ieee1394/dv1394.c
--- linux-libre-2.6.32-gnu1/drivers/ieee1394/dv1394.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ieee1394/dv1394.c	2010-02-24 13:52:17.000000000 -0500
@@ -125,7 +125,7 @@
    0 - no debugging messages
    1 - some debugging messages, but none during DMA frame transmission
    2 - lots of messages, including during DMA frame transmission
-       (will cause undeflows if your machine is too slow!)
+       (will cause underflows if your machine is too slow!)
 */
 
 #define DV1394_DEBUG_LEVEL 0
diff -druNp linux-libre-2.6.32-gnu1/drivers/ieee1394/Kconfig linux-libre-2.6.33-gnu1/drivers/ieee1394/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/ieee1394/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ieee1394/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,3 @@
-menu "IEEE 1394 (FireWire) support"
-	depends on PCI || BROKEN
-
-source "drivers/firewire/Kconfig"
-
 config IEEE1394
 	tristate "Legacy alternative FireWire driver stack"
 	depends on PCI || BROKEN
@@ -16,8 +11,13 @@ config IEEE1394
 	  is the core support only, you will also need to select a driver for
 	  your IEEE 1394 adapter.
 
-	  To compile this driver as a module, say M here: the
-	  module will be called ieee1394.
+	  To compile this driver as a module, say M here: the module will be
+	  called ieee1394.
+
+	  NOTE:
+	  ieee1394 is superseded by the newer firewire-core driver.  See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
 
 config IEEE1394_OHCI1394
 	tristate "OHCI-1394 controllers"
@@ -29,19 +29,23 @@ config IEEE1394_OHCI1394
 	  use one of these chipsets.  It should work with any OHCI-1394
 	  compliant card, however.
 
-	  To compile this driver as a module, say M here: the
-	  module will be called ohci1394.
+	  To compile this driver as a module, say M here: the module will be
+	  called ohci1394.
 
 	  NOTE:
+	  ohci1394 is superseded by the newer firewire-ohci driver.  See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
+
 	  If you want to install firewire-ohci and ohci1394 together, you
 	  should configure them only as modules and blacklist the driver(s)
 	  which you don't want to have auto-loaded.  Add either
 
-	      blacklist firewire-ohci
-	  or
 	      blacklist ohci1394
 	      blacklist video1394
 	      blacklist dv1394
+	  or
+	      blacklist firewire-ohci
 
 	  to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
 	  depending on your distribution.
@@ -58,8 +62,8 @@ config IEEE1394_PCILYNX
 	  Instruments PCILynx chip.  Note: this driver is written for revision
 	  2 of this chip and may not work with revision 0.
 
-	  To compile this driver as a module, say M here: the
-	  module will be called pcilynx.
+	  To compile this driver as a module, say M here: the module will be
+	  called pcilynx.
 
 	  Only some old and now very rare PCI and CardBus cards and
 	  PowerMacs G3 B&W contain the PCILynx controller.  Therefore
@@ -79,6 +83,14 @@ config IEEE1394_SBP2
 	  You should also enable support for disks, CD-ROMs, etc. in the SCSI
 	  configuration section.
 
+	  To compile this driver as a module, say M here: the module will be
+	  called sbp2.
+
+	  NOTE:
+	  sbp2 is superseded by the newer firewire-sbp2 driver. See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
+
 config IEEE1394_SBP2_PHYS_DMA
 	bool "Enable replacement for physical DMA in SBP2"
 	depends on IEEE1394_SBP2 && VIRT_TO_BUS && EXPERIMENTAL
@@ -111,6 +123,11 @@ config IEEE1394_ETH1394
 
 	  The module is called eth1394 although it does not emulate Ethernet.
 
+	  NOTE:
+	  eth1394 is superseded by the newer firewire-net driver. See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
+
 config IEEE1394_RAWIO
 	tristate "raw1394 userspace interface"
 	depends on IEEE1394
@@ -123,6 +140,11 @@ config IEEE1394_RAWIO
 	  To compile this driver as a module, say M here: the module will be
 	  called raw1394.
 
+	  NOTE:
+	  raw1394 is superseded by the newer firewire-core driver. See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
+
 config IEEE1394_VIDEO1394
 	tristate "video1394 userspace interface"
 	depends on IEEE1394 && IEEE1394_OHCI1394
@@ -136,13 +158,18 @@ config IEEE1394_VIDEO1394
 	  To compile this driver as a module, say M here: the module will be
 	  called video1394.
 
+	  NOTE:
+	  video1394 is superseded by the newer firewire-core driver. See
+	  http://ieee1394.wiki.kernel.org/index.php/Juju_Migration for
+	  further information on how to switch to the new FireWire drivers.
+
 config IEEE1394_DV1394
 	tristate "dv1394 userspace interface (deprecated)"
 	depends on IEEE1394 && IEEE1394_OHCI1394
 	help
 	  The dv1394 driver is unsupported and may be removed from Linux in a
-	  future release.  Its functionality is now provided by raw1394 together
-	  with libraries such as libiec61883.
+	  future release.  Its functionality is now provided by either
+	  raw1394 or firewire-core together with libraries such as libiec61883.
 
 config IEEE1394_VERBOSEDEBUG
 	bool "Excessive debugging output"
@@ -153,5 +180,3 @@ config IEEE1394_VERBOSEDEBUG
 	  will quickly result in large amounts of data sent to the system log.
 
 	  Say Y if you really need the debugging output.  Everyone else says N.
-
-endmenu
diff -druNp linux-libre-2.6.32-gnu1/drivers/ieee1394/ohci1394.c linux-libre-2.6.33-gnu1/drivers/ieee1394/ohci1394.c
--- linux-libre-2.6.32-gnu1/drivers/ieee1394/ohci1394.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ieee1394/ohci1394.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,6 +82,7 @@
  *
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -434,7 +435,6 @@ static void initialize_dma_trm_ctx(struc
 /* Count the number of available iso contexts */
 static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
 {
-	int i,ctx=0;
 	u32 tmp;
 
 	reg_write(ohci, reg, 0xffffffff);
@@ -443,11 +443,7 @@ static int get_nb_iso_ctx(struct ti_ohci
 	DBGMSG("Iso contexts reg: %08x implemented: %08x", reg, tmp);
 
 	/* Count the number of contexts */
-	for (i=0; i<32; i++) {
-	    	if (tmp & 1) ctx++;
-		tmp >>= 1;
-	}
-	return ctx;
+	return hweight32(tmp);
 }
 
 /* Global initialization */
diff -druNp linux-libre-2.6.32-gnu1/drivers/ieee802154/fakehard.c linux-libre-2.6.33-gnu1/drivers/ieee802154/fakehard.c
--- linux-libre-2.6.32-gnu1/drivers/ieee802154/fakehard.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ieee802154/fakehard.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,9 +32,29 @@
 #include <net/nl802154.h>
 #include <net/wpan-phy.h>
 
-struct wpan_phy *net_to_phy(struct net_device *dev)
+struct fakehard_priv {
+	struct wpan_phy *phy;
+};
+
+static struct wpan_phy *fake_to_phy(const struct net_device *dev)
 {
-	return container_of(dev->dev.parent, struct wpan_phy, dev);
+	struct fakehard_priv *priv = netdev_priv(dev);
+	return priv->phy;
+}
+
+/**
+ * fake_get_phy - Return a phy corresponding to this device.
+ * @dev: The network device for which to return the wan-phy object
+ *
+ * This function returns a wpan-phy object corresponding to the passed
+ * network device. Reference counter for wpan-phy object is incremented,
+ * so when the wpan-phy isn't necessary, you should drop the reference
+ * via @wpan_phy_put() call.
+ */
+static struct wpan_phy *fake_get_phy(const struct net_device *dev)
+{
+	struct wpan_phy *phy = fake_to_phy(dev);
+	return to_phy(get_device(&phy->dev));
 }
 
 /**
@@ -43,7 +63,7 @@ struct wpan_phy *net_to_phy(struct net_d
  *
  * Return the ID of the PAN from the PIB.
  */
-static u16 fake_get_pan_id(struct net_device *dev)
+static u16 fake_get_pan_id(const struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
 
@@ -58,7 +78,7 @@ static u16 fake_get_pan_id(struct net_de
  * device. If the device has not yet had a short address assigned
  * then this should return 0xFFFF to indicate a lack of association.
  */
-static u16 fake_get_short_addr(struct net_device *dev)
+static u16 fake_get_short_addr(const struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
 
@@ -78,7 +98,7 @@ static u16 fake_get_short_addr(struct ne
  * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
  *       document.
  */
-static u8 fake_get_dsn(struct net_device *dev)
+static u8 fake_get_dsn(const struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
 
@@ -98,7 +118,7 @@ static u8 fake_get_dsn(struct net_device
  * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
  *       document.
  */
-static u8 fake_get_bsn(struct net_device *dev)
+static u8 fake_get_bsn(const struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
 
@@ -121,7 +141,7 @@ static u8 fake_get_bsn(struct net_device
 static int fake_assoc_req(struct net_device *dev,
 		struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
 {
-	struct wpan_phy *phy = net_to_phy(dev);
+	struct wpan_phy *phy = fake_to_phy(dev);
 
 	mutex_lock(&phy->pib_lock);
 	phy->current_channel = channel;
@@ -196,7 +216,7 @@ static int fake_start_req(struct net_dev
 				u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
 				u8 coord_realign)
 {
-	struct wpan_phy *phy = net_to_phy(dev);
+	struct wpan_phy *phy = fake_to_phy(dev);
 
 	mutex_lock(&phy->pib_lock);
 	phy->current_channel = channel;
@@ -239,6 +259,8 @@ static struct ieee802154_mlme_ops fake_m
 	.start_req = fake_start_req,
 	.scan_req = fake_scan_req,
 
+	.get_phy = fake_get_phy,
+
 	.get_pan_id = fake_get_pan_id,
 	.get_short_addr = fake_get_short_addr,
 	.get_dsn = fake_get_dsn,
@@ -310,7 +332,7 @@ static const struct net_device_ops fake_
 
 static void ieee802154_fake_destruct(struct net_device *dev)
 {
-	struct wpan_phy *phy = net_to_phy(dev);
+	struct wpan_phy *phy = fake_to_phy(dev);
 
 	wpan_phy_unregister(phy);
 	free_netdev(dev);
@@ -335,13 +357,14 @@ static void ieee802154_fake_setup(struct
 static int __devinit ieee802154fake_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
+	struct fakehard_priv *priv;
 	struct wpan_phy *phy = wpan_phy_alloc(0);
 	int err;
 
 	if (!phy)
 		return -ENOMEM;
 
-	dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+	dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup);
 	if (!dev) {
 		wpan_phy_free(phy);
 		return -ENOMEM;
@@ -353,12 +376,23 @@ static int __devinit ieee802154fake_prob
 			dev->addr_len);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	phy->channels_supported = (1 << 27) - 1;
+	/*
+	 * For now we'd like to emulate 2.4 GHz-only device,
+	 * both O-QPSK and CSS
+	 */
+	/* 2.4 GHz O-QPSK 802.15.4-2003 */
+	phy->channels_supported[0] |= 0x7FFF800;
+	/* 2.4 GHz CSS 802.15.4a-2007 */
+	phy->channels_supported[3] |= 0x3fff;
+
 	phy->transmit_power = 0xbf;
 
 	dev->netdev_ops = &fake_ops;
 	dev->ml_priv = &fake_mlme;
 
+	priv = netdev_priv(dev);
+	priv->phy = phy;
+
 	/*
 	 * If the name is a format string the caller wants us to do a
 	 * name allocation.
@@ -369,11 +403,12 @@ static int __devinit ieee802154fake_prob
 			goto out;
 	}
 
+	wpan_phy_set_dev(phy, &pdev->dev);
 	SET_NETDEV_DEV(dev, &phy->dev);
 
 	platform_set_drvdata(pdev, dev);
 
-	err = wpan_phy_register(&pdev->dev, phy);
+	err = wpan_phy_register(phy);
 	if (err)
 		goto out;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/addr.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/addr.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/addr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/addr.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,7 +36,6 @@
 #include <linux/mutex.h>
 #include <linux/inetdevice.h>
 #include <linux/workqueue.h>
-#include <linux/if_arp.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
@@ -92,22 +91,12 @@ EXPORT_SYMBOL(rdma_addr_unregister_clien
 int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
 		     const unsigned char *dst_dev_addr)
 {
-	switch (dev->type) {
-	case ARPHRD_INFINIBAND:
-		dev_addr->dev_type = RDMA_NODE_IB_CA;
-		break;
-	case ARPHRD_ETHER:
-		dev_addr->dev_type = RDMA_NODE_RNIC;
-		break;
-	default:
-		return -EADDRNOTAVAIL;
-	}
-
+	dev_addr->dev_type = dev->type;
 	memcpy(dev_addr->src_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
 	memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN);
 	if (dst_dev_addr)
 		memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN);
-	dev_addr->src_dev = dev;
+	dev_addr->bound_dev_if = dev->ifindex;
 	return 0;
 }
 EXPORT_SYMBOL(rdma_copy_addr);
@@ -117,6 +106,15 @@ int rdma_translate_ip(struct sockaddr *a
 	struct net_device *dev;
 	int ret = -EADDRNOTAVAIL;
 
+	if (dev_addr->bound_dev_if) {
+		dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
+		if (!dev)
+			return -ENODEV;
+		ret = rdma_copy_addr(dev_addr, dev, NULL);
+		dev_put(dev);
+		return ret;
+	}
+
 	switch (addr->sa_family) {
 	case AF_INET:
 		dev = ip_dev_find(&init_net,
@@ -131,6 +129,7 @@ int rdma_translate_ip(struct sockaddr *a
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
+		read_lock(&dev_base_lock);
 		for_each_netdev(&init_net, dev) {
 			if (ipv6_chk_addr(&init_net,
 					  &((struct sockaddr_in6 *) addr)->sin6_addr,
@@ -139,6 +138,7 @@ int rdma_translate_ip(struct sockaddr *a
 				break;
 			}
 		}
+		read_unlock(&dev_base_lock);
 		break;
 #endif
 	}
@@ -176,48 +176,9 @@ static void queue_req(struct addr_req *r
 	mutex_unlock(&lock);
 }
 
-static void addr_send_arp(struct sockaddr *dst_in)
-{
-	struct rtable *rt;
-	struct flowi fl;
-
-	memset(&fl, 0, sizeof fl);
-
-	switch (dst_in->sa_family) {
-	case AF_INET:
-		fl.nl_u.ip4_u.daddr =
-			((struct sockaddr_in *) dst_in)->sin_addr.s_addr;
-
-		if (ip_route_output_key(&init_net, &rt, &fl))
-			return;
-
-		neigh_event_send(rt->u.dst.neighbour, NULL);
-		ip_rt_put(rt);
-		break;
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-	{
-		struct dst_entry *dst;
-
-		fl.nl_u.ip6_u.daddr =
-			((struct sockaddr_in6 *) dst_in)->sin6_addr;
-
-		dst = ip6_route_output(&init_net, NULL, &fl);
-		if (!dst)
-			return;
-
-		neigh_event_send(dst->neighbour, NULL);
-		dst_release(dst);
-		break;
-	}
-#endif
-	}
-}
-
-static int addr4_resolve_remote(struct sockaddr_in *src_in,
-			       struct sockaddr_in *dst_in,
-			       struct rdma_dev_addr *addr)
+static int addr4_resolve(struct sockaddr_in *src_in,
+			 struct sockaddr_in *dst_in,
+			 struct rdma_dev_addr *addr)
 {
 	__be32 src_ip = src_in->sin_addr.s_addr;
 	__be32 dst_ip = dst_in->sin_addr.s_addr;
@@ -229,10 +190,22 @@ static int addr4_resolve_remote(struct s
 	memset(&fl, 0, sizeof fl);
 	fl.nl_u.ip4_u.daddr = dst_ip;
 	fl.nl_u.ip4_u.saddr = src_ip;
+	fl.oif = addr->bound_dev_if;
+
 	ret = ip_route_output_key(&init_net, &rt, &fl);
 	if (ret)
 		goto out;
 
+	src_in->sin_family = AF_INET;
+	src_in->sin_addr.s_addr = rt->rt_src;
+
+	if (rt->idev->dev->flags & IFF_LOOPBACK) {
+		ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
+		if (!ret)
+			memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
+		goto put;
+	}
+
 	/* If the device does ARP internally, return 'done' */
 	if (rt->idev->dev->flags & IFF_NOARP) {
 		rdma_copy_addr(addr, rt->idev->dev, NULL);
@@ -240,21 +213,14 @@ static int addr4_resolve_remote(struct s
 	}
 
 	neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev);
-	if (!neigh) {
+	if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+		neigh_event_send(rt->u.dst.neighbour, NULL);
 		ret = -ENODATA;
+		if (neigh)
+			goto release;
 		goto put;
 	}
 
-	if (!(neigh->nud_state & NUD_VALID)) {
-		ret = -ENODATA;
-		goto release;
-	}
-
-	if (!src_ip) {
-		src_in->sin_family = dst_in->sin_family;
-		src_in->sin_addr.s_addr = rt->rt_src;
-	}
-
 	ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
 release:
 	neigh_release(neigh);
@@ -265,52 +231,77 @@ out:
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static int addr6_resolve_remote(struct sockaddr_in6 *src_in,
-			       struct sockaddr_in6 *dst_in,
-			       struct rdma_dev_addr *addr)
+static int addr6_resolve(struct sockaddr_in6 *src_in,
+			 struct sockaddr_in6 *dst_in,
+			 struct rdma_dev_addr *addr)
 {
 	struct flowi fl;
 	struct neighbour *neigh;
 	struct dst_entry *dst;
-	int ret = -ENODATA;
+	int ret;
 
 	memset(&fl, 0, sizeof fl);
-	fl.nl_u.ip6_u.daddr = dst_in->sin6_addr;
-	fl.nl_u.ip6_u.saddr = src_in->sin6_addr;
+	ipv6_addr_copy(&fl.fl6_dst, &dst_in->sin6_addr);
+	ipv6_addr_copy(&fl.fl6_src, &src_in->sin6_addr);
+	fl.oif = addr->bound_dev_if;
 
 	dst = ip6_route_output(&init_net, NULL, &fl);
-	if (!dst)
-		return ret;
+	if ((ret = dst->error))
+		goto put;
+
+	if (ipv6_addr_any(&fl.fl6_src)) {
+		ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev,
+					 &fl.fl6_dst, 0, &fl.fl6_src);
+		if (ret)
+			goto put;
 
+		src_in->sin6_family = AF_INET6;
+		ipv6_addr_copy(&src_in->sin6_addr, &fl.fl6_src);
+	}
+
+	if (dst->dev->flags & IFF_LOOPBACK) {
+		ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
+		if (!ret)
+			memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
+		goto put;
+	}
+
+	/* If the device does ARP internally, return 'done' */
 	if (dst->dev->flags & IFF_NOARP) {
 		ret = rdma_copy_addr(addr, dst->dev, NULL);
-	} else {
-		neigh = dst->neighbour;
-		if (neigh && (neigh->nud_state & NUD_VALID))
-			ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
+		goto put;
 	}
 
+	neigh = dst->neighbour;
+	if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+		neigh_event_send(dst->neighbour, NULL);
+		ret = -ENODATA;
+		goto put;
+	}
+
+	ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
+put:
 	dst_release(dst);
 	return ret;
 }
 #else
-static int addr6_resolve_remote(struct sockaddr_in6 *src_in,
-			       struct sockaddr_in6 *dst_in,
-			       struct rdma_dev_addr *addr)
+static int addr6_resolve(struct sockaddr_in6 *src_in,
+			 struct sockaddr_in6 *dst_in,
+			 struct rdma_dev_addr *addr)
 {
 	return -EADDRNOTAVAIL;
 }
 #endif
 
-static int addr_resolve_remote(struct sockaddr *src_in,
-				struct sockaddr *dst_in,
-				struct rdma_dev_addr *addr)
+static int addr_resolve(struct sockaddr *src_in,
+			struct sockaddr *dst_in,
+			struct rdma_dev_addr *addr)
 {
 	if (src_in->sa_family == AF_INET) {
-		return addr4_resolve_remote((struct sockaddr_in *) src_in,
+		return addr4_resolve((struct sockaddr_in *) src_in,
 			(struct sockaddr_in *) dst_in, addr);
 	} else
-		return addr6_resolve_remote((struct sockaddr_in6 *) src_in,
+		return addr6_resolve((struct sockaddr_in6 *) src_in,
 			(struct sockaddr_in6 *) dst_in, addr);
 }
 
@@ -327,8 +318,7 @@ static void process_req(struct work_stru
 		if (req->status == -ENODATA) {
 			src_in = (struct sockaddr *) &req->src_addr;
 			dst_in = (struct sockaddr *) &req->dst_addr;
-			req->status = addr_resolve_remote(src_in, dst_in,
-							  req->addr);
+			req->status = addr_resolve(src_in, dst_in, req->addr);
 			if (req->status && time_after_eq(jiffies, req->timeout))
 				req->status = -ETIMEDOUT;
 			else if (req->status == -ENODATA)
@@ -352,82 +342,6 @@ static void process_req(struct work_stru
 	}
 }
 
-static int addr_resolve_local(struct sockaddr *src_in,
-			      struct sockaddr *dst_in,
-			      struct rdma_dev_addr *addr)
-{
-	struct net_device *dev;
-	int ret;
-
-	switch (dst_in->sa_family) {
-	case AF_INET:
-	{
-		__be32 src_ip = ((struct sockaddr_in *) src_in)->sin_addr.s_addr;
-		__be32 dst_ip = ((struct sockaddr_in *) dst_in)->sin_addr.s_addr;
-
-		dev = ip_dev_find(&init_net, dst_ip);
-		if (!dev)
-			return -EADDRNOTAVAIL;
-
-		if (ipv4_is_zeronet(src_ip)) {
-			src_in->sa_family = dst_in->sa_family;
-			((struct sockaddr_in *) src_in)->sin_addr.s_addr = dst_ip;
-			ret = rdma_copy_addr(addr, dev, dev->dev_addr);
-		} else if (ipv4_is_loopback(src_ip)) {
-			ret = rdma_translate_ip(dst_in, addr);
-			if (!ret)
-				memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
-		} else {
-			ret = rdma_translate_ip(src_in, addr);
-			if (!ret)
-				memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
-		}
-		dev_put(dev);
-		break;
-	}
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-	{
-		struct in6_addr *a;
-
-		for_each_netdev(&init_net, dev)
-			if (ipv6_chk_addr(&init_net,
-					  &((struct sockaddr_in6 *) dst_in)->sin6_addr,
-					  dev, 1))
-				break;
-
-		if (!dev)
-			return -EADDRNOTAVAIL;
-
-		a = &((struct sockaddr_in6 *) src_in)->sin6_addr;
-
-		if (ipv6_addr_any(a)) {
-			src_in->sa_family = dst_in->sa_family;
-			((struct sockaddr_in6 *) src_in)->sin6_addr =
-				((struct sockaddr_in6 *) dst_in)->sin6_addr;
-			ret = rdma_copy_addr(addr, dev, dev->dev_addr);
-		} else if (ipv6_addr_loopback(a)) {
-			ret = rdma_translate_ip(dst_in, addr);
-			if (!ret)
-				memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
-		} else  {
-			ret = rdma_translate_ip(src_in, addr);
-			if (!ret)
-				memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
-		}
-		break;
-	}
-#endif
-
-	default:
-		ret = -EADDRNOTAVAIL;
-		break;
-	}
-
-	return ret;
-}
-
 int rdma_resolve_ip(struct rdma_addr_client *client,
 		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
 		    struct rdma_dev_addr *addr, int timeout_ms,
@@ -443,22 +357,28 @@ int rdma_resolve_ip(struct rdma_addr_cli
 	if (!req)
 		return -ENOMEM;
 
-	if (src_addr)
-		memcpy(&req->src_addr, src_addr, ip_addr_size(src_addr));
-	memcpy(&req->dst_addr, dst_addr, ip_addr_size(dst_addr));
+	src_in = (struct sockaddr *) &req->src_addr;
+	dst_in = (struct sockaddr *) &req->dst_addr;
+
+	if (src_addr) {
+		if (src_addr->sa_family != dst_addr->sa_family) {
+			ret = -EINVAL;
+			goto err;
+		}
+
+		memcpy(src_in, src_addr, ip_addr_size(src_addr));
+	} else {
+		src_in->sa_family = dst_addr->sa_family;
+	}
+
+	memcpy(dst_in, dst_addr, ip_addr_size(dst_addr));
 	req->addr = addr;
 	req->callback = callback;
 	req->context = context;
 	req->client = client;
 	atomic_inc(&client->refcount);
 
-	src_in = (struct sockaddr *) &req->src_addr;
-	dst_in = (struct sockaddr *) &req->dst_addr;
-
-	req->status = addr_resolve_local(src_in, dst_in, addr);
-	if (req->status == -EADDRNOTAVAIL)
-		req->status = addr_resolve_remote(src_in, dst_in, addr);
-
+	req->status = addr_resolve(src_in, dst_in, addr);
 	switch (req->status) {
 	case 0:
 		req->timeout = jiffies;
@@ -467,15 +387,16 @@ int rdma_resolve_ip(struct rdma_addr_cli
 	case -ENODATA:
 		req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
 		queue_req(req);
-		addr_send_arp(dst_in);
 		break;
 	default:
 		ret = req->status;
 		atomic_dec(&client->refcount);
-		kfree(req);
-		break;
+		goto err;
 	}
 	return ret;
+err:
+	kfree(req);
+	return ret;
 }
 EXPORT_SYMBOL(rdma_resolve_ip);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/cma.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/cma.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/cma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/cma.c	2010-02-24 13:52:17.000000000 -0500
@@ -330,17 +330,7 @@ static int cma_acquire_dev(struct rdma_i
 	union ib_gid gid;
 	int ret = -ENODEV;
 
-	switch (rdma_node_get_transport(dev_addr->dev_type)) {
-	case RDMA_TRANSPORT_IB:
-		ib_addr_get_sgid(dev_addr, &gid);
-		break;
-	case RDMA_TRANSPORT_IWARP:
-		iw_addr_get_sgid(dev_addr, &gid);
-		break;
-	default:
-		return -ENODEV;
-	}
-
+	rdma_addr_get_sgid(dev_addr, &gid);
 	list_for_each_entry(cma_dev, &dev_list, list) {
 		ret = ib_find_cached_gid(cma_dev->device, &gid,
 					 &id_priv->id.port_num, NULL);
@@ -1032,11 +1022,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;
 
-	ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
-	ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
-				&id->route.addr.dev_addr);
-	if (ret)
-		goto destroy_id;
+	if (cma_any_addr((struct sockaddr *) &rt->addr.src_addr)) {
+		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, rt->path_rec[0].pkey);
+	} else {
+		ret = rdma_translate_ip((struct sockaddr *) &rt->addr.src_addr,
+					&rt->addr.dev_addr);
+		if (ret)
+			goto destroy_id;
+	}
+	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 = CMA_CONNECT;
@@ -1071,10 +1067,12 @@ static struct rdma_id_private *cma_new_u
 	cma_save_net_info(&id->route.addr, &listen_id->route.addr,
 			  ip_ver, port, src, dst);
 
-	ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
-				&id->route.addr.dev_addr);
-	if (ret)
-		goto err;
+	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);
+		if (ret)
+			goto err;
+	}
 
 	id_priv = container_of(id, struct rdma_id_private, id);
 	id_priv->state = CMA_CONNECT;
@@ -1474,15 +1472,6 @@ static void cma_listen_on_all(struct rdm
 	mutex_unlock(&lock);
 }
 
-static int cma_bind_any(struct rdma_cm_id *id, sa_family_t af)
-{
-	struct sockaddr_storage addr_in;
-
-	memset(&addr_in, 0, sizeof addr_in);
-	addr_in.ss_family = af;
-	return rdma_bind_addr(id, (struct sockaddr *) &addr_in);
-}
-
 int rdma_listen(struct rdma_cm_id *id, int backlog)
 {
 	struct rdma_id_private *id_priv;
@@ -1490,7 +1479,8 @@ int rdma_listen(struct rdma_cm_id *id, i
 
 	id_priv = container_of(id, struct rdma_id_private, id);
 	if (id_priv->state == CMA_IDLE) {
-		ret = cma_bind_any(id, AF_INET);
+		((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET;
+		ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr);
 		if (ret)
 			return ret;
 	}
@@ -1565,8 +1555,8 @@ static int cma_query_ib_route(struct rdm
 	struct sockaddr_in6 *sin6;
 
 	memset(&path_rec, 0, sizeof path_rec);
-	ib_addr_get_sgid(&addr->dev_addr, &path_rec.sgid);
-	ib_addr_get_dgid(&addr->dev_addr, &path_rec.dgid);
+	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));
 	path_rec.numb_path = 1;
 	path_rec.reversible = 1;
@@ -1781,7 +1771,11 @@ port_found:
 	if (ret)
 		goto out;
 
-	ib_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+	id_priv->id.route.addr.dev_addr.dev_type =
+		(rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB) ?
+		ARPHRD_INFINIBAND : ARPHRD_ETHER;
+
+	rdma_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
 	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);
@@ -1839,7 +1833,7 @@ out:
 static int cma_resolve_loopback(struct rdma_id_private *id_priv)
 {
 	struct cma_work *work;
-	struct sockaddr_in *src_in, *dst_in;
+	struct sockaddr *src, *dst;
 	union ib_gid gid;
 	int ret;
 
@@ -1853,14 +1847,19 @@ static int cma_resolve_loopback(struct r
 			goto err;
 	}
 
-	ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
-	ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
+	rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+	rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
 
-	if (cma_zero_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) {
-		src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
-		dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr;
-		src_in->sin_family = dst_in->sin_family;
-		src_in->sin_addr.s_addr = dst_in->sin_addr.s_addr;
+	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.s_addr =
+				((struct sockaddr_in *) dst)->sin_addr.s_addr;
+		} else {
+			ipv6_addr_copy(&((struct sockaddr_in6 *) src)->sin6_addr,
+				       &((struct sockaddr_in6 *) dst)->sin6_addr);
+		}
 	}
 
 	work->id = id_priv;
@@ -1878,10 +1877,14 @@ err:
 static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 			 struct sockaddr *dst_addr)
 {
-	if (src_addr && src_addr->sa_family)
-		return rdma_bind_addr(id, src_addr);
-	else
-		return cma_bind_any(id, dst_addr->sa_family);
+	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) {
+			((struct sockaddr_in6 *) src_addr)->sin6_scope_id =
+				((struct sockaddr_in6 *) dst_addr)->sin6_scope_id;
+		}
+	}
+	return rdma_bind_addr(id, src_addr);
 }
 
 int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
@@ -2077,6 +2080,25 @@ static int cma_get_port(struct rdma_id_p
 	return ret;
 }
 
+static int cma_check_linklocal(struct rdma_dev_addr *dev_addr,
+			       struct sockaddr *addr)
+{
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct sockaddr_in6 *sin6;
+
+	if (addr->sa_family != AF_INET6)
+		return 0;
+
+	sin6 = (struct sockaddr_in6 *) addr;
+	if ((ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
+	    !sin6->sin6_scope_id)
+			return -EINVAL;
+
+	dev_addr->bound_dev_if = sin6->sin6_scope_id;
+#endif
+	return 0;
+}
+
 int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 {
 	struct rdma_id_private *id_priv;
@@ -2089,6 +2111,10 @@ int rdma_bind_addr(struct rdma_cm_id *id
 	if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND))
 		return -EINVAL;
 
+	ret = cma_check_linklocal(&id->route.addr.dev_addr, addr);
+	if (ret)
+		goto err1;
+
 	if (!cma_any_addr(addr)) {
 		ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
 		if (ret)
@@ -2108,7 +2134,7 @@ int rdma_bind_addr(struct rdma_cm_id *id
 
 	return 0;
 err2:
-	if (!cma_any_addr(addr)) {
+	if (id_priv->cma_dev) {
 		mutex_lock(&lock);
 		cma_detach_from_dev(id_priv);
 		mutex_unlock(&lock);
@@ -2687,10 +2713,15 @@ static void cma_set_mgid(struct rdma_id_
 	if (cma_any_addr(addr)) {
 		memset(mgid, 0, sizeof *mgid);
 	} else if ((addr->sa_family == AF_INET6) &&
-		   ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFF10A01B) ==
+		   ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFFF0FFFF) ==
 								 0xFF10A01B)) {
 		/* IPv6 address is an SA assigned MGID. */
 		memcpy(mgid, &sin6->sin6_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)
+			mc_map[7] = 0x01;	/* Use RDMA CM signature */
+		*mgid = *(union ib_gid *) (mc_map + 4);
 	} else {
 		ip_ib_mc_map(sin->sin_addr.s_addr, dev_addr->broadcast, mc_map);
 		if (id_priv->id.ps == RDMA_PS_UDP)
@@ -2716,7 +2747,7 @@ static int cma_join_ib_multicast(struct
 	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);
-	ib_addr_get_sgid(dev_addr, &rec.port_gid);
+	rdma_addr_get_sgid(dev_addr, &rec.port_gid);
 	rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
 	rec.join_state = 1;
 
@@ -2815,7 +2846,7 @@ static int cma_netdev_change(struct net_
 
 	dev_addr = &id_priv->id.route.addr.dev_addr;
 
-	if ((dev_addr->src_dev == ndev) &&
+	if ((dev_addr->bound_dev_if == ndev->ifindex) &&
 	    memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) {
 		printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n",
 		       ndev->name, &id_priv->id);
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/sa_query.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/sa_query.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/sa_query.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/sa_query.c	2010-02-24 13:52:17.000000000 -0500
@@ -604,6 +604,12 @@ retry:
 	return ret ? ret : id;
 }
 
+void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
+{
+	ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
+}
+EXPORT_SYMBOL(ib_sa_unpack_path);
+
 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
 				    int status,
 				    struct ib_sa_mad *mad)
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/ucma.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucma.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/ucma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/ucma.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,7 @@
 #include <rdma/rdma_user_cm.h>
 #include <rdma/ib_marshall.h>
 #include <rdma/rdma_cm.h>
+#include <rdma/rdma_cm_ib.h>
 
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -562,10 +563,10 @@ static void ucma_copy_ib_route(struct rd
 	switch (route->num_paths) {
 	case 0:
 		dev_addr = &route->addr.dev_addr;
-		ib_addr_get_dgid(dev_addr,
-				 (union ib_gid *) &resp->ib_route[0].dgid);
-		ib_addr_get_sgid(dev_addr,
-				 (union ib_gid *) &resp->ib_route[0].sgid);
+		rdma_addr_get_dgid(dev_addr,
+				   (union ib_gid *) &resp->ib_route[0].dgid);
+		rdma_addr_get_sgid(dev_addr,
+				   (union ib_gid *) &resp->ib_route[0].sgid);
 		resp->ib_route[0].pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
 		break;
 	case 2:
@@ -812,6 +813,51 @@ static int ucma_set_option_id(struct ucm
 	return ret;
 }
 
+static int ucma_set_ib_path(struct ucma_context *ctx,
+			    struct ib_path_rec_data *path_data, size_t optlen)
+{
+	struct ib_sa_path_rec sa_path;
+	struct rdma_cm_event event;
+	int ret;
+
+	if (optlen % sizeof(*path_data))
+		return -EINVAL;
+
+	for (; optlen; optlen -= sizeof(*path_data), path_data++) {
+		if (path_data->flags == (IB_PATH_GMP | IB_PATH_PRIMARY |
+					 IB_PATH_BIDIRECTIONAL))
+			break;
+	}
+
+	if (!optlen)
+		return -EINVAL;
+
+	ib_sa_unpack_path(path_data->path_rec, &sa_path);
+	ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1);
+	if (ret)
+		return ret;
+
+	memset(&event, 0, sizeof event);
+	event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
+	return ucma_event_handler(ctx->cm_id, &event);
+}
+
+static int ucma_set_option_ib(struct ucma_context *ctx, int optname,
+			      void *optval, size_t optlen)
+{
+	int ret;
+
+	switch (optname) {
+	case RDMA_OPTION_IB_PATH:
+		ret = ucma_set_ib_path(ctx, optval, optlen);
+		break;
+	default:
+		ret = -ENOSYS;
+	}
+
+	return ret;
+}
+
 static int ucma_set_option_level(struct ucma_context *ctx, int level,
 				 int optname, void *optval, size_t optlen)
 {
@@ -821,6 +867,9 @@ static int ucma_set_option_level(struct
 	case RDMA_OPTION_ID:
 		ret = ucma_set_option_id(ctx, optname, optval, optlen);
 		break;
+	case RDMA_OPTION_IB:
+		ret = ucma_set_option_ib(ctx, optname, optval, optlen);
+		break;
 	default:
 		ret = -ENOSYS;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/uverbs_cmd.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/uverbs_cmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_cmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -285,7 +285,7 @@ ssize_t ib_uverbs_get_context(struct ib_
 
 	ucontext = ibdev->alloc_ucontext(ibdev, &udata);
 	if (IS_ERR(ucontext)) {
-		ret = PTR_ERR(file->ucontext);
+		ret = PTR_ERR(ucontext);
 		goto err;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/core/uverbs_main.c linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_main.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/core/uverbs_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/core/uverbs_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -492,6 +492,7 @@ struct file *ib_uverbs_alloc_event_file(
 					int is_async, int *fd)
 {
 	struct ib_uverbs_event_file *ev_file;
+	struct path path;
 	struct file *filp;
 	int ret;
 
@@ -519,8 +520,10 @@ struct file *ib_uverbs_alloc_event_file(
 	 * system call on a uverbs file, which will already have a
 	 * module reference.
 	 */
-	filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root),
-			  FMODE_READ, fops_get(&uverbs_event_fops));
+	path.mnt = uverbs_event_mnt;
+	path.dentry = uverbs_event_mnt->mnt_root;
+	path_get(&path);
+	filp = alloc_file(&path, FMODE_READ, fops_get(&uverbs_event_fops));
 	if (!filp) {
 		ret = -ENFILE;
 		goto err_fd;
@@ -531,6 +534,8 @@ struct file *ib_uverbs_alloc_event_file(
 	return filp;
 
 err_fd:
+	fops_put(&uverbs_event_fops);
+	path_put(&path);
 	put_unused_fd(*fd);
 
 err:
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/amso1100/c2_qp.c	2010-02-24 13:52:17.000000000 -0500
@@ -798,8 +798,10 @@ int c2_post_send(struct ib_qp *ibqp, str
 	u8 actual_sge_count;
 	u32 msg_size;
 
-	if (qp->state > IB_QPS_RTS)
-		return -EINVAL;
+	if (qp->state > IB_QPS_RTS) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	while (ib_wr) {
 
@@ -930,6 +932,7 @@ int c2_post_send(struct ib_qp *ibqp, str
 		ib_wr = ib_wr->next;
 	}
 
+out:
 	if (err)
 		*bad_wr = ib_wr;
 	return err;
@@ -944,8 +947,10 @@ int c2_post_receive(struct ib_qp *ibqp,
 	unsigned long lock_flags;
 	int err = 0;
 
-	if (qp->state > IB_QPS_RTS)
-		return -EINVAL;
+	if (qp->state > IB_QPS_RTS) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	/*
 	 * Try and post each work request
@@ -998,6 +1003,7 @@ int c2_post_receive(struct ib_qp *ibqp,
 		ib_wr = ib_wr->next;
 	}
 
+out:
 	if (err)
 		*bad_wr = ib_wr;
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2010-02-24 13:52:17.000000000 -0500
@@ -589,7 +589,7 @@ static int cxio_hal_destroy_ctrl_qp(stru
 
 /* write len bytes of data into addr (32B aligned address)
  * If data is NULL, clear len byte of memory to zero.
- * caller aquires the ctrl_qp lock before the call
+ * caller acquires the ctrl_qp lock before the call
  */
 static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
 				      u32 len, void *data)
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,7 @@
 
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/kfifo.h>
 
 #include "t3_cpl.h"
 #include "t3cdev.h"
@@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp {
 };
 
 struct cxio_hal_resource {
-	struct kfifo *tpt_fifo;
+	struct kfifo tpt_fifo;
 	spinlock_t tpt_fifo_lock;
-	struct kfifo *qpid_fifo;
+	struct kfifo qpid_fifo;
 	spinlock_t qpid_fifo_lock;
-	struct kfifo *cqid_fifo;
+	struct kfifo cqid_fifo;
 	spinlock_t cqid_fifo_lock;
-	struct kfifo *pdid_fifo;
+	struct kfifo pdid_fifo;
 	spinlock_t pdid_fifo_lock;
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,12 +39,12 @@
 #include "cxio_resource.h"
 #include "cxio_hal.h"
 
-static struct kfifo *rhdl_fifo;
+static struct kfifo rhdl_fifo;
 static spinlock_t rhdl_fifo_lock;
 
 #define RANDOM_SIZE 16
 
-static int __cxio_init_resource_fifo(struct kfifo **fifo,
+static int __cxio_init_resource_fifo(struct kfifo *fifo,
 				   spinlock_t *fifo_lock,
 				   u32 nr, u32 skip_low,
 				   u32 skip_high,
@@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(str
 	u32 rarray[16];
 	spin_lock_init(fifo_lock);
 
-	*fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock);
-	if (IS_ERR(*fifo))
+	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		__kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32));
 	if (random) {
 		j = 0;
 		random_bytes = random32();
@@ -72,33 +71,35 @@ static int __cxio_init_resource_fifo(str
 				random_bytes = random32();
 			}
 			idx = (random_bytes >> (j * 2)) & 0xF;
-			__kfifo_put(*fifo,
+			kfifo_in(fifo,
 				(unsigned char *) &rarray[idx],
 				sizeof(u32));
 			rarray[idx] = i;
 			j++;
 		}
 		for (i = 0; i < RANDOM_SIZE; i++)
-			__kfifo_put(*fifo,
+			kfifo_in(fifo,
 				(unsigned char *) &rarray[i],
 				sizeof(u32));
 	} else
 		for (i = skip_low; i < nr - skip_high; i++)
-			__kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32));
+			kfifo_in(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32));
+		if (kfifo_out_locked(fifo, (unsigned char *) &entry,
+				sizeof(u32), fifo_lock) != sizeof(u32))
+					break;
 	return 0;
 }
 
-static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock,
+static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock,
 				   u32 nr, u32 skip_low, u32 skip_high)
 {
 	return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
 					  skip_high, 0));
 }
 
-static int cxio_init_resource_fifo_random(struct kfifo **fifo,
+static int cxio_init_resource_fifo_random(struct kfifo *fifo,
 				   spinlock_t * fifo_lock,
 				   u32 nr, u32 skip_low, u32 skip_high)
 {
@@ -113,15 +114,13 @@ static int cxio_init_qpid_fifo(struct cx
 
 	spin_lock_init(&rdev_p->rscp->qpid_fifo_lock);
 
-	rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32),
-					      GFP_KERNEL,
-					      &rdev_p->rscp->qpid_fifo_lock);
-	if (IS_ERR(rdev_p->rscp->qpid_fifo))
+	if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32),
+					      GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
 		if (!(i & rdev_p->qpmask))
-			__kfifo_put(rdev_p->rscp->qpid_fifo,
+			kfifo_in(&rdev_p->rscp->qpid_fifo,
 				    (unsigned char *) &i, sizeof(u32));
 	return 0;
 }
@@ -134,7 +133,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_r
 
 void cxio_hal_destroy_rhdl_resource(void)
 {
-	kfifo_free(rhdl_fifo);
+	kfifo_free(&rhdl_fifo);
 }
 
 /* nr_* must be power of 2 */
@@ -167,11 +166,11 @@ int cxio_hal_init_resource(struct cxio_r
 		goto pdid_err;
 	return 0;
 pdid_err:
-	kfifo_free(rscp->cqid_fifo);
+	kfifo_free(&rscp->cqid_fifo);
 cqid_err:
-	kfifo_free(rscp->qpid_fifo);
+	kfifo_free(&rscp->qpid_fifo);
 qpid_err:
-	kfifo_free(rscp->tpt_fifo);
+	kfifo_free(&rscp->tpt_fifo);
 tpt_err:
 	return -ENOMEM;
 }
@@ -179,33 +178,37 @@ tpt_err:
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
 	u32 entry;
-	if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+	if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
 		return entry;
 	else
 		return 0;	/* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+		u32 entry)
 {
-	BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+	BUG_ON(
+	kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+	== 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->tpt_fifo);
+	return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-	cxio_hal_put_resource(rscp->tpt_fifo, stag);
+	cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-	u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo);
+	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+			&rscp->qpid_fifo_lock);
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
 	return qpid;
 }
@@ -213,35 +216,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_re
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
-	cxio_hal_put_resource(rscp->qpid_fifo, qpid);
+	cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->cqid_fifo);
+	return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-	cxio_hal_put_resource(rscp->cqid_fifo, cqid);
+	cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->pdid_fifo);
+	return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-	cxio_hal_put_resource(rscp->pdid_fifo, pdid);
+	cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
 {
-	kfifo_free(rscp->tpt_fifo);
-	kfifo_free(rscp->cqid_fifo);
-	kfifo_free(rscp->qpid_fifo);
-	kfifo_free(rscp->pdid_fifo);
+	kfifo_free(&rscp->tpt_fifo);
+	kfifo_free(&rscp->cqid_fifo);
+	kfifo_free(&rscp->qpid_fifo);
+	kfifo_free(&rscp->pdid_fifo);
 	kfree(rscp);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2010-02-24 13:52:17.000000000 -0500
@@ -365,18 +365,19 @@ int iwch_post_send(struct ib_qp *ibqp, s
 	spin_lock_irqsave(&qhp->lock, flag);
 	if (qhp->attr.state > IWCH_QP_STATE_RTS) {
 		spin_unlock_irqrestore(&qhp->lock, flag);
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 	num_wrs = Q_FREECNT(qhp->wq.sq_rptr, qhp->wq.sq_wptr,
 		  qhp->wq.sq_size_log2);
 	if (num_wrs <= 0) {
 		spin_unlock_irqrestore(&qhp->lock, flag);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out;
 	}
 	while (wr) {
 		if (num_wrs == 0) {
 			err = -ENOMEM;
-			*bad_wr = wr;
 			break;
 		}
 		idx = Q_PTR2IDX(qhp->wq.wptr, qhp->wq.size_log2);
@@ -428,10 +429,8 @@ int iwch_post_send(struct ib_qp *ibqp, s
 			     wr->opcode);
 			err = -EINVAL;
 		}
-		if (err) {
-			*bad_wr = wr;
+		if (err)
 			break;
-		}
 		wqe->send.wrid.id0.hi = qhp->wq.sq_wptr;
 		sqp->wr_id = wr->wr_id;
 		sqp->opcode = wr2opcode(t3_wr_opcode);
@@ -454,6 +453,10 @@ int iwch_post_send(struct ib_qp *ibqp, s
 	}
 	spin_unlock_irqrestore(&qhp->lock, flag);
 	ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
+
+out:
+	if (err)
+		*bad_wr = wr;
 	return err;
 }
 
@@ -471,18 +474,19 @@ int iwch_post_receive(struct ib_qp *ibqp
 	spin_lock_irqsave(&qhp->lock, flag);
 	if (qhp->attr.state > IWCH_QP_STATE_RTS) {
 		spin_unlock_irqrestore(&qhp->lock, flag);
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 	num_wrs = Q_FREECNT(qhp->wq.rq_rptr, qhp->wq.rq_wptr,
 			    qhp->wq.rq_size_log2) - 1;
 	if (!wr) {
 		spin_unlock_irqrestore(&qhp->lock, flag);
-		return -EINVAL;
+		err = -ENOMEM;
+		goto out;
 	}
 	while (wr) {
 		if (wr->num_sge > T3_MAX_SGE) {
 			err = -EINVAL;
-			*bad_wr = wr;
 			break;
 		}
 		idx = Q_PTR2IDX(qhp->wq.wptr, qhp->wq.size_log2);
@@ -494,10 +498,10 @@ int iwch_post_receive(struct ib_qp *ibqp
 				err = build_zero_stag_recv(qhp, wqe, wr);
 		else
 			err = -ENOMEM;
-		if (err) {
-			*bad_wr = wr;
+
+		if (err)
 			break;
-		}
+
 		build_fw_riwrh((void *) wqe, T3_WR_RCV, T3_COMPLETION_FLAG,
 			       Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2),
 			       0, sizeof(struct t3_receive_wr) >> 3, T3_SOPEOP);
@@ -511,6 +515,10 @@ int iwch_post_receive(struct ib_qp *ibqp
 	}
 	spin_unlock_irqrestore(&qhp->lock, flag);
 	ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid);
+
+out:
+	if (err)
+		*bad_wr = wr;
 	return err;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_classes.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_classes.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_classes.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_classes.h	2010-02-24 13:52:17.000000000 -0500
@@ -375,6 +375,7 @@ extern rwlock_t ehca_qp_idr_lock;
 extern rwlock_t ehca_cq_idr_lock;
 extern struct idr ehca_qp_idr;
 extern struct idr ehca_cq_idr;
+extern spinlock_t shca_list_lock;
 
 extern int ehca_static_rate;
 extern int ehca_port_act_time;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_eq.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_eq.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_eq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_eq.c	2010-02-24 13:52:17.000000000 -0500
@@ -169,12 +169,15 @@ int ehca_destroy_eq(struct ehca_shca *sh
 	unsigned long flags;
 	u64 h_ret;
 
-	spin_lock_irqsave(&eq->spinlock, flags);
 	ibmebus_free_irq(eq->ist, (void *)shca);
 
-	h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
+	spin_lock_irqsave(&shca_list_lock, flags);
+	eq->is_initialized = 0;
+	spin_unlock_irqrestore(&shca_list_lock, flags);
 
-	spin_unlock_irqrestore(&eq->spinlock, flags);
+	tasklet_kill(&eq->interrupt_task);
+
+	h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
 
 	if (h_ret != H_SUCCESS) {
 		ehca_err(&shca->ib_device, "Can't free EQ resources.");
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -826,8 +826,7 @@ static void __cpuinit take_over_work(str
 		cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
 
 		list_del(&cq->entry);
-		__queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks,
-						  smp_processor_id()));
+		__queue_comp_task(cq, this_cpu_ptr(pool->cpu_comp_tasks));
 	}
 
 	spin_unlock_irqrestore(&cct->task_lock, flags_cct);
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_main.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_main.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,7 +123,7 @@ DEFINE_IDR(ehca_qp_idr);
 DEFINE_IDR(ehca_cq_idr);
 
 static LIST_HEAD(shca_list); /* list of all registered ehcas */
-static DEFINE_SPINLOCK(shca_list_lock);
+DEFINE_SPINLOCK(shca_list_lock);
 
 static struct timer_list poll_eqs_timer;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ehca/ehca_reqs.c	2010-02-24 13:52:17.000000000 -0500
@@ -400,7 +400,6 @@ static inline void map_ib_wc_status(u32
 
 static inline int post_one_send(struct ehca_qp *my_qp,
 			 struct ib_send_wr *cur_send_wr,
-			 struct ib_send_wr **bad_send_wr,
 			 int hidden)
 {
 	struct ehca_wqe *wqe_p;
@@ -412,8 +411,6 @@ static inline int post_one_send(struct e
 	wqe_p = ipz_qeit_get_inc(&my_qp->ipz_squeue);
 	if (unlikely(!wqe_p)) {
 		/* too many posted work requests: queue overflow */
-		if (bad_send_wr)
-			*bad_send_wr = cur_send_wr;
 		ehca_err(my_qp->ib_qp.device, "Too many posted WQEs "
 			 "qp_num=%x", my_qp->ib_qp.qp_num);
 		return -ENOMEM;
@@ -433,8 +430,6 @@ static inline int post_one_send(struct e
 	 */
 	if (unlikely(ret)) {
 		my_qp->ipz_squeue.current_q_offset = start_offset;
-		if (bad_send_wr)
-			*bad_send_wr = cur_send_wr;
 		ehca_err(my_qp->ib_qp.device, "Could not write WQE "
 			 "qp_num=%x", my_qp->ib_qp.qp_num);
 		return -EINVAL;
@@ -448,7 +443,6 @@ int ehca_post_send(struct ib_qp *qp,
 		   struct ib_send_wr **bad_send_wr)
 {
 	struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
-	struct ib_send_wr *cur_send_wr;
 	int wqe_cnt = 0;
 	int ret = 0;
 	unsigned long flags;
@@ -457,7 +451,8 @@ int ehca_post_send(struct ib_qp *qp,
 	if (unlikely(my_qp->state < IB_QPS_RTS)) {
 		ehca_err(qp->device, "Invalid QP state  qp_state=%d qpn=%x",
 			 my_qp->state, qp->qp_num);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	/* LOCK the QUEUE */
@@ -476,24 +471,21 @@ int ehca_post_send(struct ib_qp *qp,
 		struct ib_send_wr circ_wr;
 		memset(&circ_wr, 0, sizeof(circ_wr));
 		circ_wr.opcode = IB_WR_RDMA_READ;
-		post_one_send(my_qp, &circ_wr, NULL, 1); /* ignore retcode */
+		post_one_send(my_qp, &circ_wr, 1); /* ignore retcode */
 		wqe_cnt++;
 		ehca_dbg(qp->device, "posted circ wr  qp_num=%x", qp->qp_num);
 		my_qp->message_count = my_qp->packet_count = 0;
 	}
 
 	/* loop processes list of send reqs */
-	for (cur_send_wr = send_wr; cur_send_wr != NULL;
-	     cur_send_wr = cur_send_wr->next) {
-		ret = post_one_send(my_qp, cur_send_wr, bad_send_wr, 0);
+	while (send_wr) {
+		ret = post_one_send(my_qp, send_wr, 0);
 		if (unlikely(ret)) {
-			/* if one or more WQEs were successful, don't fail */
-			if (wqe_cnt)
-				ret = 0;
 			goto post_send_exit0;
 		}
 		wqe_cnt++;
-	} /* eof for cur_send_wr */
+		send_wr = send_wr->next;
+	}
 
 post_send_exit0:
 	iosync(); /* serialize GAL register access */
@@ -503,6 +495,10 @@ post_send_exit0:
 			 my_qp, qp->qp_num, wqe_cnt, ret);
 	my_qp->message_count += wqe_cnt;
 	spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
+
+out:
+	if (ret)
+		*bad_send_wr = send_wr;
 	return ret;
 }
 
@@ -511,7 +507,6 @@ static int internal_post_recv(struct ehc
 			      struct ib_recv_wr *recv_wr,
 			      struct ib_recv_wr **bad_recv_wr)
 {
-	struct ib_recv_wr *cur_recv_wr;
 	struct ehca_wqe *wqe_p;
 	int wqe_cnt = 0;
 	int ret = 0;
@@ -522,27 +517,23 @@ static int internal_post_recv(struct ehc
 	if (unlikely(!HAS_RQ(my_qp))) {
 		ehca_err(dev, "QP has no RQ  ehca_qp=%p qp_num=%x ext_type=%d",
 			 my_qp, my_qp->real_qp_num, my_qp->ext_type);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out;
 	}
 
 	/* LOCK the QUEUE */
 	spin_lock_irqsave(&my_qp->spinlock_r, flags);
 
-	/* loop processes list of send reqs */
-	for (cur_recv_wr = recv_wr; cur_recv_wr != NULL;
-	     cur_recv_wr = cur_recv_wr->next) {
+	/* loop processes list of recv reqs */
+	while (recv_wr) {
 		u64 start_offset = my_qp->ipz_rqueue.current_q_offset;
 		/* get pointer next to free WQE */
 		wqe_p = ipz_qeit_get_inc(&my_qp->ipz_rqueue);
 		if (unlikely(!wqe_p)) {
 			/* too many posted work requests: queue overflow */
-			if (bad_recv_wr)
-				*bad_recv_wr = cur_recv_wr;
-			if (wqe_cnt == 0) {
-				ret = -ENOMEM;
-				ehca_err(dev, "Too many posted WQEs "
-					 "qp_num=%x", my_qp->real_qp_num);
-			}
+			ret = -ENOMEM;
+			ehca_err(dev, "Too many posted WQEs "
+				"qp_num=%x", my_qp->real_qp_num);
 			goto post_recv_exit0;
 		}
 		/*
@@ -552,7 +543,7 @@ static int internal_post_recv(struct ehc
 		rq_map_idx = start_offset / my_qp->ipz_rqueue.qe_size;
 
 		/* write a RECV WQE into the QUEUE */
-		ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, cur_recv_wr,
+		ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, recv_wr,
 				rq_map_idx);
 		/*
 		 * if something failed,
@@ -560,22 +551,20 @@ static int internal_post_recv(struct ehc
 		 */
 		if (unlikely(ret)) {
 			my_qp->ipz_rqueue.current_q_offset = start_offset;
-			*bad_recv_wr = cur_recv_wr;
-			if (wqe_cnt == 0) {
-				ret = -EINVAL;
-				ehca_err(dev, "Could not write WQE "
-					 "qp_num=%x", my_qp->real_qp_num);
-			}
+			ret = -EINVAL;
+			ehca_err(dev, "Could not write WQE "
+				"qp_num=%x", my_qp->real_qp_num);
 			goto post_recv_exit0;
 		}
 
 		qmap_entry = &my_qp->rq_map.map[rq_map_idx];
-		qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id);
+		qmap_entry->app_wr_id = get_app_wr_id(recv_wr->wr_id);
 		qmap_entry->reported = 0;
 		qmap_entry->cqe_req = 1;
 
 		wqe_cnt++;
-	} /* eof for cur_recv_wr */
+		recv_wr = recv_wr->next;
+	} /* eof for recv_wr */
 
 post_recv_exit0:
 	iosync(); /* serialize GAL register access */
@@ -584,6 +573,11 @@ post_recv_exit0:
 	    ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d ret=%i",
 		     my_qp, my_qp->real_qp_num, wqe_cnt, ret);
 	spin_unlock_irqrestore(&my_qp->spinlock_r, flags);
+
+out:
+	if (ret)
+		*bad_recv_wr = recv_wr;
+
 	return ret;
 }
 
@@ -597,6 +591,7 @@ int ehca_post_recv(struct ib_qp *qp,
 	if (unlikely(my_qp->state == IB_QPS_RESET)) {
 		ehca_err(qp->device, "Invalid QP state  qp_state=%d qpn=%x",
 			 my_qp->state, qp->qp_num);
+		*bad_recv_wr = recv_wr;
 		return -EINVAL;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/bitmap.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
@@ -1697,7 +1698,7 @@ void ipath_chg_pioavailkernel(struct ipa
 			      unsigned len, int avail)
 {
 	unsigned long flags;
-	unsigned end, cnt = 0, next;
+	unsigned end, cnt = 0;
 
 	/* There are two bits per send buffer (busy and generation) */
 	start *= 2;
@@ -1748,12 +1749,7 @@ void ipath_chg_pioavailkernel(struct ipa
 
 	if (dd->ipath_pioupd_thresh) {
 		end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
-		next = find_first_bit(dd->ipath_pioavailkernel, end);
-		while (next < end) {
-			cnt++;
-			next = find_next_bit(dd->ipath_pioavailkernel, end,
-					next + 1);
-		}
+		cnt = bitmap_weight(dd->ipath_pioavailkernel, end);
 	}
 	spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_file_ops.c	2010-02-24 13:52:17.000000000 -0500
@@ -1821,7 +1821,6 @@ done:
 static int ipath_open(struct inode *in, struct file *fp)
 {
 	/* The real work is performed later in ipath_assign_port() */
-	cycle_kernel_lock();
 	fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
 	return fp->private_data ? 0 : -ENOMEM;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2010-02-24 13:52:17.000000000 -0500
@@ -346,10 +346,8 @@ static int ipathfs_fill_super(struct sup
 	list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
 		spin_unlock_irqrestore(&ipath_devs_lock, flags);
 		ret = create_device_files(sb, dd);
-		if (ret) {
-			deactivate_locked_super(sb);
+		if (ret)
 			goto bail;
-		}
 		spin_lock_irqsave(&ipath_devs_lock, flags);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_iba6110.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_iba6110.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_iba6110.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_iba6110.c	2010-02-24 13:52:17.000000000 -0500
@@ -381,7 +381,7 @@ static const ipath_err_t infinipath_hwe_
 #define IPATH_GPIO_SCL \
 	(1ULL << (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT))
 
-/* keep the code below somewhat more readonable; not used elsewhere */
+/* keep the code below somewhat more readable; not used elsewhere */
 #define _IPATH_HTLINK0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr |	\
 				infinipath_hwe_htclnkabyte1crcerr)
 #define _IPATH_HTLINK1_CRCBITS (infinipath_hwe_htclnkbbyte0crcerr |	\
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_sd7220.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_sd7220.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/ipath/ipath_sd7220.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/ipath/ipath_sd7220.c	2010-02-24 13:52:17.000000000 -0500
@@ -614,7 +614,7 @@ static int epb_trans(struct ipath_devdat
  * @wd: Write Data - value to set in register
  * @mask: ones where data should be spliced into reg.
  *
- * Basic register read/modify/write, with un-needed acesses elided. That is,
+ * Basic register read/modify/write, with un-needed accesses elided. That is,
  * a mask of zero will prevent write, while a mask of 0xFF will prevent read.
  * returns current (presumed, if a write was done) contents of selected
  * register, or <0 if errors.
@@ -989,7 +989,7 @@ static struct rxeq_init {
 	/* Set DFELTHFDR/HDR thresholds */
 	RXEQ_VAL(7, 8,    0, 0, 0, 0), /* FDR */
 	RXEQ_VAL(7, 0x21, 0, 0, 0, 0), /* HDR */
-	/* Set TLTHFDR/HDR theshold */
+	/* Set TLTHFDR/HDR threshold */
 	RXEQ_VAL(7, 9,    2, 2, 2, 2), /* FDR */
 	RXEQ_VAL(7, 0x23, 2, 2, 2, 2), /* HDR */
 	/* Set Preamp setting 2 (ZFR/ZCNT) */
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/main.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/main.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -103,7 +103,7 @@ static int mlx4_ib_query_device(struct i
 		props->device_cap_flags |= IB_DEVICE_UD_AV_PORT_ENFORCE;
 	if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM)
 		props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
-	if (dev->dev->caps.max_gso_sz)
+	if (dev->dev->caps.max_gso_sz && dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BLH)
 		props->device_cap_flags |= IB_DEVICE_UD_TSO;
 	if (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_RESERVED_LKEY)
 		props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/qp.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/qp.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/qp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/qp.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,8 @@ enum {
 	/*
 	 * Largest possible UD header: send with GRH and immediate data.
 	 */
-	MLX4_IB_UD_HEADER_SIZE		= 72
+	MLX4_IB_UD_HEADER_SIZE		= 72,
+	MLX4_IB_LSO_HEADER_SPARE	= 128,
 };
 
 struct mlx4_ib_sqp {
@@ -67,7 +68,8 @@ struct mlx4_ib_sqp {
 };
 
 enum {
-	MLX4_IB_MIN_SQ_STRIDE = 6
+	MLX4_IB_MIN_SQ_STRIDE	= 6,
+	MLX4_IB_CACHE_LINE_SIZE	= 64,
 };
 
 static const __be32 mlx4_ib_opcode[] = {
@@ -261,7 +263,7 @@ static int send_wqe_overhead(enum ib_qp_
 	case IB_QPT_UD:
 		return sizeof (struct mlx4_wqe_ctrl_seg) +
 			sizeof (struct mlx4_wqe_datagram_seg) +
-			((flags & MLX4_IB_QP_LSO) ? 64 : 0);
+			((flags & MLX4_IB_QP_LSO) ? MLX4_IB_LSO_HEADER_SPARE : 0);
 	case IB_QPT_UC:
 		return sizeof (struct mlx4_wqe_ctrl_seg) +
 			sizeof (struct mlx4_wqe_raddr_seg);
@@ -352,7 +354,7 @@ static int set_kernel_sq_size(struct mlx
 	 * anymore, so we do this only if selective signaling is off.
 	 *
 	 * Further, on 32-bit platforms, we can't use vmap() to make
-	 * the QP buffer virtually contigious.  Thus we have to use
+	 * the QP buffer virtually contiguous.  Thus we have to use
 	 * constant-sized WRs to make sure a WR is always fully within
 	 * a single page-sized chunk.
 	 *
@@ -897,7 +899,6 @@ static int __mlx4_ib_modify_qp(struct ib
 
 	context->flags = cpu_to_be32((to_mlx4_state(new_state) << 28) |
 				     (to_mlx4_st(ibqp->qp_type) << 16));
-	context->flags     |= cpu_to_be32(1 << 8); /* DE? */
 
 	if (!(attr_mask & IB_QP_PATH_MIG_STATE))
 		context->flags |= cpu_to_be32(MLX4_QP_PM_MIGRATED << 11);
@@ -1467,16 +1468,12 @@ static void __set_data_seg(struct mlx4_w
 
 static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
 			 struct mlx4_ib_qp *qp, unsigned *lso_seg_len,
-			 __be32 *lso_hdr_sz)
+			 __be32 *lso_hdr_sz, __be32 *blh)
 {
 	unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16);
 
-	/*
-	 * This is a temporary limitation and will be removed in
-	 * a forthcoming FW release:
-	 */
-	if (unlikely(halign > 64))
-		return -EINVAL;
+	if (unlikely(halign > MLX4_IB_CACHE_LINE_SIZE))
+		*blh = cpu_to_be32(1 << 6);
 
 	if (unlikely(!(qp->flags & MLX4_IB_QP_LSO) &&
 		     wr->num_sge > qp->sq.max_gs - (halign >> 4)))
@@ -1522,6 +1519,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp
 	__be32 dummy;
 	__be32 *lso_wqe;
 	__be32 uninitialized_var(lso_hdr_sz);
+	__be32 blh;
 	int i;
 
 	spin_lock_irqsave(&qp->sq.lock, flags);
@@ -1530,6 +1528,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp
 
 	for (nreq = 0; wr; ++nreq, wr = wr->next) {
 		lso_wqe = &dummy;
+		blh = 0;
 
 		if (mlx4_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {
 			err = -ENOMEM;
@@ -1616,7 +1615,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp
 			size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
 
 			if (wr->opcode == IB_WR_LSO) {
-				err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz);
+				err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz, &blh);
 				if (unlikely(err)) {
 					*bad_wr = wr;
 					goto out;
@@ -1687,7 +1686,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp
 		}
 
 		ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
-			(ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0);
+			(ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh;
 
 		stamp = ind + qp->sq_spare_wqes;
 		ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
@@ -1753,7 +1752,7 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp
 	ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
 
 	for (nreq = 0; wr; ++nreq, wr = wr->next) {
-		if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.send_cq)) {
+		if (mlx4_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
 			err = -ENOMEM;
 			*bad_wr = wr;
 			goto out;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/srq.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/srq.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/mlx4/srq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/mlx4/srq.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,7 @@ struct ib_srq *mlx4_ib_create_srq(struct
 	struct mlx4_ib_dev *dev = to_mdev(pd->device);
 	struct mlx4_ib_srq *srq;
 	struct mlx4_wqe_srq_next_seg *next;
+	struct mlx4_wqe_data_seg *scatter;
 	int desc_size;
 	int buf_size;
 	int err;
@@ -149,6 +150,11 @@ struct ib_srq *mlx4_ib_create_srq(struct
 			next = get_wqe(srq, i);
 			next->next_wqe_index =
 				cpu_to_be16((i + 1) & (srq->msrq.max - 1));
+
+			for (scatter = (void *) (next + 1);
+			     (void *) scatter < (void *) next + desc_size;
+			     ++scatter)
+				scatter->lkey = cpu_to_be32(MLX4_INVALID_LKEY);
 		}
 
 		err = mlx4_mtt_init(dev->dev, srq->buf.npages, srq->buf.page_shift,
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/Kconfig linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -4,14 +4,13 @@ config INFINIBAND_NES
 	select LIBCRC32C
 	select INET_LRO
 	---help---
-	  This is a low-level driver for NetEffect RDMA enabled
-	  Network Interface Cards (RNIC).
+	  This is the RDMA Network Interface Card (RNIC) driver for
+	  NetEffect Ethernet Cluster Server Adapters.
 
 config INFINIBAND_NES_DEBUG
 	bool "Verbose debugging output"
 	depends on INFINIBAND_NES
 	default n
 	---help---
-	  This option causes the NetEffect RNIC driver to produce debug
-	  messages.  Select this if you are developing the driver
-	  or trying to diagnose a problem.
+	  This option enables debug messages from the NetEffect RNIC
+	  driver.  Select this if you are diagnosing a problem.
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -521,7 +521,8 @@ static int __devinit nes_probe(struct pc
 	spin_lock_init(&nesdev->indexed_regs_lock);
 
 	/* Remap the PCI registers in adapter BAR0 to kernel VA space */
-	mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), sizeof(mmio_regs));
+	mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0),
+				    pci_resource_len(pcidev, BAR_0));
 	if (mmio_regs == NULL) {
 		printk(KERN_ERR PFX "Unable to remap BAR0\n");
 		ret = -EIO;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_cm.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
@@ -52,6 +52,7 @@
 #include <linux/random.h>
 #include <linux/list.h>
 #include <linux/threads.h>
+#include <linux/highmem.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
@@ -251,6 +252,33 @@ static int parse_mpa(struct nes_cm_node
 
 	mpa_frame = (struct ietf_mpa_frame *)buffer;
 	cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len);
+	/* make sure mpa private data len is less than 512 bytes */
+	if (cm_node->mpa_frame_size > IETF_MAX_PRIV_DATA_LEN) {
+		nes_debug(NES_DBG_CM, "The received Length of Private"
+			" Data field exceeds 512 octets\n");
+		return -EINVAL;
+	}
+	/*
+	 * make sure MPA receiver interoperate with the
+	 * received MPA version and MPA key information
+	 *
+	 */
+	if (mpa_frame->rev != mpa_version) {
+		nes_debug(NES_DBG_CM, "The received mpa version"
+				" can not be interoperated\n");
+		return -EINVAL;
+	}
+	if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) {
+		if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) {
+			nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
+			return -EINVAL;
+		}
+	} else {
+		if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) {
+			nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
+			return -EINVAL;
+		}
+	}
 
 	if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
 		nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
@@ -486,6 +514,8 @@ static void nes_retrans_expired(struct n
 		send_reset(cm_node, NULL);
 		break;
 	default:
+		add_ref_cm_node(cm_node);
+		send_reset(cm_node, NULL);
 		create_event(cm_node, NES_CM_EVENT_ABORTED);
 	}
 }
@@ -949,6 +979,7 @@ static int mini_cm_dec_refcnt_listen(str
 				reset_entry);
 		{
 			struct nes_cm_node *loopback = cm_node->loopbackpartner;
+			enum nes_cm_node_state old_state;
 			if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
 				rem_ref_cm_node(cm_node->cm_core, cm_node);
 			} else {
@@ -960,11 +991,12 @@ static int mini_cm_dec_refcnt_listen(str
 							 NES_CM_STATE_CLOSED;
 						WARN_ON(1);
 					} else {
-						cm_node->state =
-							NES_CM_STATE_CLOSED;
-						rem_ref_cm_node(
-							cm_node->cm_core,
-							cm_node);
+						old_state = cm_node->state;
+						cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
+						if (old_state != NES_CM_STATE_MPAREQ_RCVD)
+							rem_ref_cm_node(
+								cm_node->cm_core,
+								cm_node);
 					}
 				} else {
 					struct nes_cm_event event;
@@ -980,20 +1012,9 @@ static int mini_cm_dec_refcnt_listen(str
 							 loopback->loc_port;
 					event.cm_info.cm_id = loopback->cm_id;
 					cm_event_connect_error(&event);
+					cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
 					loopback->state = NES_CM_STATE_CLOSED;
 
-					event.cm_node = cm_node;
-					event.cm_info.rem_addr =
-							 cm_node->rem_addr;
-					event.cm_info.loc_addr =
-							 cm_node->loc_addr;
-					event.cm_info.rem_port =
-							 cm_node->rem_port;
-					event.cm_info.loc_port =
-							 cm_node->loc_port;
-					event.cm_info.cm_id = cm_node->cm_id;
-					cm_event_reset(&event);
-
 					rem_ref_cm_node(cm_node->cm_core,
 							 cm_node);
 
@@ -1077,12 +1098,13 @@ static inline int mini_cm_accelerated(st
 /**
  * nes_addr_resolve_neigh
  */
-static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
+static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex)
 {
 	struct rtable *rt;
 	struct flowi fl;
 	struct neighbour *neigh;
-	int rc = -1;
+	int rc = arpindex;
+	struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
 
 	memset(&fl, 0, sizeof fl);
 	fl.nl_u.ip4_u.daddr = htonl(dst_ip);
@@ -1098,6 +1120,21 @@ static int nes_addr_resolve_neigh(struct
 			nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
 				  " is %pM, Gateway is 0x%08X \n", dst_ip,
 				  neigh->ha, ntohl(rt->rt_gateway));
+
+			if (arpindex >= 0) {
+				if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
+							neigh->ha, ETH_ALEN)){
+					/* Mac address same as in nes_arp_table */
+					neigh_release(neigh);
+					ip_rt_put(rt);
+					return rc;
+				}
+
+				nes_manage_arp_cache(nesvnic->netdev,
+						nesadapter->arp_table[arpindex].mac_addr,
+						dst_ip, NES_ARP_DELETE);
+			}
+
 			nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
 					     dst_ip, NES_ARP_ADD);
 			rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
@@ -1113,7 +1150,6 @@ static int nes_addr_resolve_neigh(struct
 	return rc;
 }
 
-
 /**
  * make_cm_node - create a new instance of a cm node
  */
@@ -1123,6 +1159,7 @@ static struct nes_cm_node *make_cm_node(
 {
 	struct nes_cm_node *cm_node;
 	struct timespec ts;
+	int oldarpindex = 0;
 	int arpindex = 0;
 	struct nes_device *nesdev;
 	struct nes_adapter *nesadapter;
@@ -1176,17 +1213,18 @@ static struct nes_cm_node *make_cm_node(
 	nesadapter = nesdev->nesadapter;
 
 	cm_node->loopbackpartner = NULL;
+
 	/* get the mac addr for the remote node */
 	if (ipv4_is_loopback(htonl(cm_node->rem_addr)))
 		arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE);
-	else
-		arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
+	else {
+		oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
+		arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex);
+
+	}
 	if (arpindex < 0) {
-		arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
-		if (arpindex < 0) {
-			kfree(cm_node);
-			return NULL;
-		}
+		kfree(cm_node);
+		return NULL;
 	}
 
 	/* copy the mac addr to node context */
@@ -1333,13 +1371,20 @@ static void handle_fin_pkt(struct nes_cm
 	case NES_CM_STATE_SYN_RCVD:
 	case NES_CM_STATE_SYN_SENT:
 	case NES_CM_STATE_ESTABLISHED:
-	case NES_CM_STATE_MPAREQ_SENT:
 	case NES_CM_STATE_MPAREJ_RCVD:
 		cm_node->tcp_cntxt.rcv_nxt++;
 		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_LAST_ACK;
 		send_fin(cm_node, NULL);
 		break;
+	case NES_CM_STATE_MPAREQ_SENT:
+		create_event(cm_node, NES_CM_EVENT_ABORTED);
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
+		cm_node->state = NES_CM_STATE_CLOSED;
+		add_ref_cm_node(cm_node);
+		send_reset(cm_node, NULL);
+		break;
 	case NES_CM_STATE_FIN_WAIT1:
 		cm_node->tcp_cntxt.rcv_nxt++;
 		cleanup_retrans_entry(cm_node);
@@ -1590,6 +1635,7 @@ static void handle_syn_pkt(struct nes_cm
 		break;
 	case NES_CM_STATE_CLOSED:
 		cleanup_retrans_entry(cm_node);
+		add_ref_cm_node(cm_node);
 		send_reset(cm_node, skb);
 		break;
 	case NES_CM_STATE_TSA:
@@ -1641,9 +1687,15 @@ static void handle_synack_pkt(struct nes
 		passive_open_err(cm_node, skb, 1);
 		break;
 	case NES_CM_STATE_LISTENING:
+		cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
+		cleanup_retrans_entry(cm_node);
+		cm_node->state = NES_CM_STATE_CLOSED;
+		send_reset(cm_node, skb);
+		break;
 	case NES_CM_STATE_CLOSED:
 		cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
 		cleanup_retrans_entry(cm_node);
+		add_ref_cm_node(cm_node);
 		send_reset(cm_node, skb);
 		break;
 	case NES_CM_STATE_ESTABLISHED:
@@ -1712,8 +1764,13 @@ static int handle_ack_pkt(struct nes_cm_
 			dev_kfree_skb_any(skb);
 		break;
 	case NES_CM_STATE_LISTENING:
+		cleanup_retrans_entry(cm_node);
+		cm_node->state = NES_CM_STATE_CLOSED;
+		send_reset(cm_node, skb);
+		break;
 	case NES_CM_STATE_CLOSED:
 		cleanup_retrans_entry(cm_node);
+		add_ref_cm_node(cm_node);
 		send_reset(cm_node, skb);
 		break;
 	case NES_CM_STATE_LAST_ACK:
@@ -1974,7 +2031,7 @@ static struct nes_cm_node *mini_cm_conne
 	if (!cm_node)
 		return NULL;
 	mpa_frame = &cm_node->mpa_frame;
-	strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ);
+	memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE);
 	mpa_frame->flags = IETF_MPA_FLAGS_CRC;
 	mpa_frame->rev =  IETF_MPA_VERSION;
 	mpa_frame->priv_data_len = htons(private_data_len);
@@ -2102,30 +2159,39 @@ static int mini_cm_reject(struct nes_cm_
 			cm_node->state = NES_CM_STATE_CLOSED;
 			rem_ref_cm_node(cm_core, cm_node);
 		} else {
-			ret = send_mpa_reject(cm_node);
-			if (ret) {
-				cm_node->state = NES_CM_STATE_CLOSED;
-				err = send_reset(cm_node, NULL);
-				if (err)
-					WARN_ON(1);
-			} else
-				cm_id->add_ref(cm_id);
+			if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
+				rem_ref_cm_node(cm_core, cm_node);
+			} else {
+				ret = send_mpa_reject(cm_node);
+				if (ret) {
+					cm_node->state = NES_CM_STATE_CLOSED;
+					err = send_reset(cm_node, NULL);
+					if (err)
+						WARN_ON(1);
+				} else
+					cm_id->add_ref(cm_id);
+			}
 		}
 	} else {
 		cm_node->cm_id = NULL;
-		event.cm_node = loopback;
-		event.cm_info.rem_addr = loopback->rem_addr;
-		event.cm_info.loc_addr = loopback->loc_addr;
-		event.cm_info.rem_port = loopback->rem_port;
-		event.cm_info.loc_port = loopback->loc_port;
-		event.cm_info.cm_id = loopback->cm_id;
-		cm_event_mpa_reject(&event);
-		rem_ref_cm_node(cm_core, cm_node);
-		loopback->state = NES_CM_STATE_CLOSING;
+		if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
+			rem_ref_cm_node(cm_core, cm_node);
+			rem_ref_cm_node(cm_core, loopback);
+		} else {
+			event.cm_node = loopback;
+			event.cm_info.rem_addr = loopback->rem_addr;
+			event.cm_info.loc_addr = loopback->loc_addr;
+			event.cm_info.rem_port = loopback->rem_port;
+			event.cm_info.loc_port = loopback->loc_port;
+			event.cm_info.cm_id = loopback->cm_id;
+			cm_event_mpa_reject(&event);
+			rem_ref_cm_node(cm_core, cm_node);
+			loopback->state = NES_CM_STATE_CLOSING;
 
-		cm_id = loopback->cm_id;
-		rem_ref_cm_node(cm_core, loopback);
-		cm_id->rem_ref(cm_id);
+			cm_id = loopback->cm_id;
+			rem_ref_cm_node(cm_core, loopback);
+			cm_id->rem_ref(cm_id);
+		}
 	}
 
 	return ret;
@@ -2164,11 +2230,15 @@ static int mini_cm_close(struct nes_cm_c
 	case NES_CM_STATE_CLOSING:
 		ret = -1;
 		break;
-	case NES_CM_STATE_MPAREJ_RCVD:
 	case NES_CM_STATE_LISTENING:
+		cleanup_retrans_entry(cm_node);
+		send_reset(cm_node, NULL);
+		break;
+	case NES_CM_STATE_MPAREJ_RCVD:
 	case NES_CM_STATE_UNKNOWN:
 	case NES_CM_STATE_INITED:
 	case NES_CM_STATE_CLOSED:
+	case NES_CM_STATE_LISTENER_DESTROYED:
 		ret = rem_ref_cm_node(cm_core, cm_node);
 		break;
 	case NES_CM_STATE_TSA:
@@ -2687,8 +2757,6 @@ int nes_accept(struct iw_cm_id *cm_id, s
 	struct nes_pd *nespd;
 	u64 tagged_offset;
 
-
-
 	ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
 	if (!ibqp)
 		return -EINVAL;
@@ -2704,6 +2772,13 @@ int nes_accept(struct iw_cm_id *cm_id, s
 		"%s\n", cm_node, nesvnic, nesvnic->netdev,
 		nesvnic->netdev->name);
 
+	if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) {
+		if (cm_node->loopbackpartner)
+			rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner);
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
+		return -EINVAL;
+	}
+
 	/* associate the node with the QP */
 	nesqp->cm_node = (void *)cm_node;
 	cm_node->nesqp = nesqp;
@@ -2786,6 +2861,10 @@ int nes_accept(struct iw_cm_id *cm_id, s
 			cpu_to_le32(conn_param->private_data_len +
 			sizeof(struct ietf_mpa_frame));
 		wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
+		if (nesqp->sq_kmapped) {
+			nesqp->sq_kmapped = 0;
+			kunmap(nesqp->page);
+		}
 
 		nesqp->nesqp_context->ird_ord_sizes |=
 			cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
@@ -2929,7 +3008,7 @@ int nes_reject(struct iw_cm_id *cm_id, c
 	if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
 		return -EINVAL;
 
-	strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
+	memcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
 	if (loopback) {
 		memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
 		loopback->mpa_frame.priv_data_len = pdata_len;
@@ -2974,6 +3053,9 @@ int nes_connect(struct iw_cm_id *cm_id,
 	if (!nesdev)
 		return -EINVAL;
 
+	if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port))
+		return -EINVAL;
+
 	nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
 		"0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
 		ntohl(nesvnic->local_ipaddr),
@@ -3251,6 +3333,11 @@ static void cm_event_connected(struct ne
 		wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
 		wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
 
+		if (nesqp->sq_kmapped) {
+			nesqp->sq_kmapped = 0;
+			kunmap(nesqp->page);
+		}
+
 		/* use the reserved spot on the WQ for the extra first WQE */
 		nesqp->nesqp_context->ird_ord_sizes &=
 			cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
@@ -3346,7 +3433,7 @@ static void cm_event_connect_error(struc
 	nesqp->cm_id = NULL;
 	cm_id->provider_data = NULL;
 	cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
-	cm_event.status = IW_CM_EVENT_STATUS_REJECTED;
+	cm_event.status = -ECONNRESET;
 	cm_event.provider_data = cm_id->provider_data;
 	cm_event.local_addr = cm_id->local_addr;
 	cm_event.remote_addr = cm_id->remote_addr;
@@ -3390,6 +3477,8 @@ static void cm_event_reset(struct nes_cm
 
 	nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id);
 	nesqp = cm_id->provider_data;
+	if (!nesqp)
+		return;
 
 	nesqp->cm_id = NULL;
 	/* cm_id->provider_data = NULL; */
@@ -3401,8 +3490,8 @@ static void cm_event_reset(struct nes_cm
 	cm_event.private_data = NULL;
 	cm_event.private_data_len = 0;
 
-	ret = cm_id->event_handler(cm_id, &cm_event);
 	cm_id->add_ref(cm_id);
+	ret = cm_id->event_handler(cm_id, &cm_event);
 	atomic_inc(&cm_closes);
 	cm_event.event = IW_CM_EVENT_CLOSE;
 	cm_event.status = IW_CM_EVENT_STATUS_OK;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_cm.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_cm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_cm.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
@@ -47,6 +47,8 @@
 #define IEFT_MPA_KEY_REP  "MPA ID Rep Frame"
 #define IETF_MPA_KEY_SIZE 16
 #define IETF_MPA_VERSION  1
+#define IETF_MAX_PRIV_DATA_LEN 512
+#define IETF_MPA_FRAME_SIZE     20
 
 enum ietf_mpa_flags {
 	IETF_MPA_FLAGS_MARKERS = 0x80,	/* receive Markers */
@@ -169,7 +171,7 @@ struct nes_timer_entry {
 
 #define NES_CM_DEF_SEQ2      0x18ed5740
 #define NES_CM_DEF_LOCAL_ID2 0xb807
-#define	MAX_CM_BUFFER	512
+#define	MAX_CM_BUFFER	(IETF_MPA_FRAME_SIZE + IETF_MAX_PRIV_DATA_LEN)
 
 
 typedef u32 nes_addr_t;
@@ -198,6 +200,7 @@ enum nes_cm_node_state {
 	NES_CM_STATE_TIME_WAIT,
 	NES_CM_STATE_LAST_ACK,
 	NES_CM_STATE_CLOSING,
+	NES_CM_STATE_LISTENER_DESTROYED,
 	NES_CM_STATE_CLOSED
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_context.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_context.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_context.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_context.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_hw.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
@@ -424,8 +424,9 @@ struct nes_adapter *nes_init_adapter(str
 
 	nesadapter->base_pd = 1;
 
-	nesadapter->device_cap_flags =
-		IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW;
+	nesadapter->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY |
+				       IB_DEVICE_MEM_WINDOW |
+				       IB_DEVICE_MEM_MGT_EXTENSIONS;
 
 	nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter)
 			[(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]);
@@ -436,11 +437,12 @@ struct nes_adapter *nes_init_adapter(str
 	nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]);
 
 
-	/* mark the usual suspect QPs and CQs as in use */
+	/* mark the usual suspect QPs, MR and CQs as in use */
 	for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) {
 		set_bit(u32temp, nesadapter->allocated_qps);
 		set_bit(u32temp, nesadapter->allocated_cqs);
 	}
+	set_bit(0, nesadapter->allocated_mrs);
 
 	for (u32temp = 0; u32temp < 20; u32temp++)
 		set_bit(u32temp, nesadapter->allocated_pds);
@@ -481,7 +483,7 @@ struct nes_adapter *nes_init_adapter(str
 	nesadapter->max_irrq_wr = (u32temp >> 16) & 3;
 
 	nesadapter->max_sge = 4;
-	nesadapter->max_cqe = 32767;
+	nesadapter->max_cqe = 32766;
 
 	if (nes_read_eeprom_values(nesdev, nesadapter)) {
 		printk(KERN_ERR PFX "Unable to read EEPROM data.\n");
@@ -1355,6 +1357,8 @@ int nes_init_phy(struct nes_device *nesd
 	}
 	if ((phy_type == NES_PHY_TYPE_ARGUS) ||
 	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		u32 first_time = 1;
+
 		/* Check firmware heartbeat */
 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
 		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
@@ -1362,8 +1366,13 @@ int nes_init_phy(struct nes_device *nesd
 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
 		temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
 
-		if (temp_phy_data != temp_phy_data2)
-			return 0;
+		if (temp_phy_data != temp_phy_data2) {
+			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
+			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+			if ((temp_phy_data & 0xff) > 0x20)
+				return 0;
+			printk(PFX "Reinitializing PHY\n");
+		}
 
 		/* no heartbeat, configure the PHY */
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
@@ -1399,7 +1408,7 @@ int nes_init_phy(struct nes_device *nesd
 		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
 		do {
 			if (counter++ > 150) {
-				nes_debug(NES_DBG_PHY, "No PHY heartbeat\n");
+				printk(PFX "No PHY heartbeat\n");
 				break;
 			}
 			mdelay(1);
@@ -1413,11 +1422,20 @@ int nes_init_phy(struct nes_device *nesd
 			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
 			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
 			if (counter++ > 300) {
-				nes_debug(NES_DBG_PHY, "PHY did not track\n");
-				break;
+				if (((temp_phy_data & 0xff) == 0x0) && first_time) {
+					first_time = 0;
+					counter = 0;
+					/* reset AMCC PHY and try again */
+					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0);
+					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040);
+					continue;
+				} else {
+					printk(PFX "PHY did not track\n");
+					break;
+				}
 			}
 			mdelay(10);
-		} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
+		} while ((temp_phy_data & 0xff) < 0x30);
 
 		/* setup signal integrity */
 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_hw.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+* Copyright (c) 2006 - 2009 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
@@ -546,11 +546,23 @@ enum nes_iwarp_sq_fmr_wqe_word_idx {
 	NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX = 14,
 };
 
+enum nes_iwarp_sq_fmr_opcodes {
+	NES_IWARP_SQ_FMR_WQE_ZERO_BASED			= (1<<6),
+	NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K		= (0<<7),
+	NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M		= (1<<7),
+	NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ	= (1<<16),
+	NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE 	= (1<<17),
+	NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ 	= (1<<18),
+	NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE = (1<<19),
+	NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND 	= (1<<20),
+};
+
+#define NES_IWARP_SQ_FMR_WQE_MR_LENGTH_HIGH_MASK	0xFF;
+
 enum nes_iwarp_sq_locinv_wqe_word_idx {
 	NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX = 6,
 };
 
-
 enum nes_iwarp_rq_wqe_word_idx {
 	NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1,
 	NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2,
@@ -1153,6 +1165,19 @@ struct nes_pbl {
 	/* TODO: need to add list for two level tables */
 };
 
+#define NES_4K_PBL_CHUNK_SIZE	4096
+
+struct nes_fast_mr_wqe_pbl {
+	u64		*kva;
+	dma_addr_t	paddr;
+};
+
+struct nes_ib_fast_reg_page_list {
+	struct ib_fast_reg_page_list	ibfrpl;
+	struct nes_fast_mr_wqe_pbl 	nes_wqe_pbl;
+	u64 				pbl;
+};
+
 struct nes_listener {
 	struct work_struct      work;
 	struct workqueue_struct *wq;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_nic.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_nic.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
@@ -1080,11 +1080,14 @@ static int nes_netdev_set_rx_csum(struct
 
 
 /**
- * nes_netdev_get_stats_count
+ * nes_netdev_get_sset_count
  */
-static int nes_netdev_get_stats_count(struct net_device *netdev)
+static int nes_netdev_get_sset_count(struct net_device *netdev, int stringset)
 {
-	return NES_ETHTOOL_STAT_COUNT;
+	if (stringset == ETH_SS_STATS)
+		return NES_ETHTOOL_STAT_COUNT;
+	else
+		return -EINVAL;
 }
 
 
@@ -1264,7 +1267,6 @@ static void nes_netdev_get_drvinfo(struc
 	sprintf(drvinfo->fw_version, "%u.%u", nesadapter->firmware_version>>16,
 				nesadapter->firmware_version & 0x000000ff);
 	strcpy(drvinfo->version, DRV_VERSION);
-	drvinfo->n_stats = nes_netdev_get_stats_count(netdev);
 	drvinfo->testinfo_len = 0;
 	drvinfo->eedump_len = 0;
 	drvinfo->regdump_len = 0;
@@ -1516,7 +1518,7 @@ static const struct ethtool_ops nes_etht
 	.get_rx_csum = nes_netdev_get_rx_csum,
 	.get_sg = ethtool_op_get_sg,
 	.get_strings = nes_netdev_get_strings,
-	.get_stats_count = nes_netdev_get_stats_count,
+	.get_sset_count = nes_netdev_get_sset_count,
 	.get_ethtool_stats = nes_netdev_get_ethtool_stats,
 	.get_drvinfo = nes_netdev_get_drvinfo,
 	.get_coalesce = nes_netdev_get_coalesce,
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_user.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_user.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_user.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_user.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
@@ -86,6 +86,7 @@ enum iwnes_memreg_type {
 	IWNES_MEMREG_TYPE_CQ = 0x0002,
 	IWNES_MEMREG_TYPE_MW = 0x0003,
 	IWNES_MEMREG_TYPE_FMR = 0x0004,
+	IWNES_MEMREG_TYPE_FMEM = 0x0005,
 };
 
 struct nes_mem_reg_req {
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_utils.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_utils.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_verbs.c linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 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
@@ -275,341 +275,235 @@ static int nes_bind_mw(struct ib_qp *ibq
 }
 
 
-/**
- * nes_alloc_fmr
+/*
+ * nes_alloc_fast_mr
  */
-static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,
-		int ibmr_access_flags,
-		struct ib_fmr_attr *ibfmr_attr)
+static int alloc_fast_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
+			     u32 stag, u32 page_count)
 {
-	unsigned long flags;
-	struct nes_pd *nespd = to_nespd(ibpd);
-	struct nes_vnic *nesvnic = to_nesvnic(ibpd->device);
-	struct nes_device *nesdev = nesvnic->nesdev;
-	struct nes_adapter *nesadapter = nesdev->nesadapter;
-	struct nes_fmr *nesfmr;
-	struct nes_cqp_request *cqp_request;
 	struct nes_hw_cqp_wqe *cqp_wqe;
+	struct nes_cqp_request *cqp_request;
+	unsigned long flags;
 	int ret;
-	u32 stag;
-	u32 stag_index = 0;
-	u32 next_stag_index = 0;
-	u32 driver_key = 0;
+	struct nes_adapter *nesadapter = nesdev->nesadapter;
 	u32 opcode = 0;
-	u8 stag_key = 0;
-	int i=0;
-	struct nes_vpbl vpbl;
-
-	get_random_bytes(&next_stag_index, sizeof(next_stag_index));
-	stag_key = (u8)next_stag_index;
-
-	driver_key = 0;
-
-	next_stag_index >>= 8;
-	next_stag_index %= nesadapter->max_mr;
-
-	ret = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs,
-			nesadapter->max_mr, &stag_index, &next_stag_index);
-	if (ret) {
-		goto failed_resource_alloc;
-	}
-
-	nesfmr = kzalloc(sizeof(*nesfmr), GFP_KERNEL);
-	if (!nesfmr) {
-		ret = -ENOMEM;
-		goto failed_fmr_alloc;
-	}
-
-	nesfmr->nesmr.mode = IWNES_MEMREG_TYPE_FMR;
-	if (ibfmr_attr->max_pages == 1) {
-		/* use zero length PBL */
-		nesfmr->nesmr.pbl_4k = 0;
-		nesfmr->nesmr.pbls_used = 0;
-	} else if (ibfmr_attr->max_pages <= 32) {
-		/* use PBL 256 */
-		nesfmr->nesmr.pbl_4k = 0;
-		nesfmr->nesmr.pbls_used = 1;
-	} else if (ibfmr_attr->max_pages <= 512) {
-		/* use 4K PBLs */
-		nesfmr->nesmr.pbl_4k = 1;
-		nesfmr->nesmr.pbls_used = 1;
-	} else {
-		/* use two level 4K PBLs */
-		/* add support for two level 256B PBLs */
-		nesfmr->nesmr.pbl_4k = 1;
-		nesfmr->nesmr.pbls_used = 1 + (ibfmr_attr->max_pages >> 9) +
-				((ibfmr_attr->max_pages & 511) ? 1 : 0);
-	}
-	/* Register the region with the adapter */
-	spin_lock_irqsave(&nesadapter->pbl_lock, flags);
-
-	/* track PBL resources */
-	if (nesfmr->nesmr.pbls_used != 0) {
-		if (nesfmr->nesmr.pbl_4k) {
-			if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) {
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				ret = -ENOMEM;
-				goto failed_vpbl_avail;
-			} else {
-				nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used;
-			}
-		} else {
-			if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) {
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				ret = -ENOMEM;
-				goto failed_vpbl_avail;
-			} else {
-				nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used;
-			}
-		}
-	}
-
-	/* one level pbl */
-	if (nesfmr->nesmr.pbls_used == 0) {
-		nesfmr->root_vpbl.pbl_vbase = NULL;
-		nes_debug(NES_DBG_MR,  "zero level pbl \n");
-	} else if (nesfmr->nesmr.pbls_used == 1) {
-		/* can change it to kmalloc & dma_map_single */
-		nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
-				&nesfmr->root_vpbl.pbl_pbase);
-		if (!nesfmr->root_vpbl.pbl_vbase) {
-			spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-			ret = -ENOMEM;
-			goto failed_vpbl_alloc;
-		}
-		nesfmr->leaf_pbl_cnt = 0;
-		nes_debug(NES_DBG_MR, "one level pbl, root_vpbl.pbl_vbase=%p \n",
-				nesfmr->root_vpbl.pbl_vbase);
-	}
-	/* two level pbl */
-	else {
-		nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192,
-				&nesfmr->root_vpbl.pbl_pbase);
-		if (!nesfmr->root_vpbl.pbl_vbase) {
-			spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-			ret = -ENOMEM;
-			goto failed_vpbl_alloc;
-		}
-
-		nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1;
-		nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC);
-		if (!nesfmr->root_vpbl.leaf_vpbl) {
-			spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-			ret = -ENOMEM;
-			goto failed_leaf_vpbl_alloc;
-		}
-
-		nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p"
-				" leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n",
-				nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl);
-
-		for (i=0; i<nesfmr->leaf_pbl_cnt; i++)
-			nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase = NULL;
-
-		for (i=0; i<nesfmr->leaf_pbl_cnt; i++) {
-			vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
-					&vpbl.pbl_pbase);
-
-			if (!vpbl.pbl_vbase) {
-				ret = -ENOMEM;
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				goto failed_leaf_vpbl_pages_alloc;
-			}
-
-			nesfmr->root_vpbl.pbl_vbase[i].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase);
-			nesfmr->root_vpbl.pbl_vbase[i].pa_high = cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32)));
-			nesfmr->root_vpbl.leaf_vpbl[i] = vpbl;
-
-			nes_debug(NES_DBG_MR, "pbase_low=0x%x, pbase_high=0x%x, vpbl=%p\n",
-					nesfmr->root_vpbl.pbl_vbase[i].pa_low,
-					nesfmr->root_vpbl.pbl_vbase[i].pa_high,
-					&nesfmr->root_vpbl.leaf_vpbl[i]);
-		}
-	}
-	nesfmr->ib_qp = NULL;
-	nesfmr->access_rights =0;
+	u16 major_code;
+	u64 region_length = page_count * PAGE_SIZE;
 
-	stag = stag_index << 8;
-	stag |= driver_key;
-	stag += (u32)stag_key;
 
-	spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
 	cqp_request = nes_get_cqp_request(nesdev);
 	if (cqp_request == NULL) {
 		nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n");
-		ret = -ENOMEM;
-		goto failed_leaf_vpbl_pages_alloc;
+		return -ENOMEM;
 	}
+	nes_debug(NES_DBG_MR, "alloc_fast_reg_mr: page_count = %d, "
+			      "region_length = %llu\n",
+			      page_count, region_length);
 	cqp_request->waiting = 1;
 	cqp_wqe = &cqp_request->cqp_wqe;
 
-	nes_debug(NES_DBG_MR, "Registering STag 0x%08X, index = 0x%08X\n",
-			stag, stag_index);
-
-	opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR;
-
-	if (nesfmr->nesmr.pbl_4k == 1)
-		opcode |= NES_CQP_STAG_PBL_BLK_SIZE;
-
-	if (ibmr_access_flags & IB_ACCESS_REMOTE_WRITE) {
-		opcode |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE |
-				NES_CQP_STAG_RIGHTS_LOCAL_WRITE | NES_CQP_STAG_REM_ACC_EN;
-		nesfmr->access_rights |=
-				NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_RIGHTS_LOCAL_WRITE |
-				NES_CQP_STAG_REM_ACC_EN;
+	spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+	if (nesadapter->free_4kpbl > 0) {
+		nesadapter->free_4kpbl--;
+		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+	} else {
+		/* No 4kpbl's available: */
+		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+		nes_debug(NES_DBG_MR, "Out of Pbls\n");
+		nes_free_cqp_request(nesdev, cqp_request);
+		return -ENOMEM;
 	}
 
-	if (ibmr_access_flags & IB_ACCESS_REMOTE_READ) {
-		opcode |= NES_CQP_STAG_RIGHTS_REMOTE_READ |
-				NES_CQP_STAG_RIGHTS_LOCAL_READ | NES_CQP_STAG_REM_ACC_EN;
-		nesfmr->access_rights |=
-				NES_CQP_STAG_RIGHTS_REMOTE_READ | NES_CQP_STAG_RIGHTS_LOCAL_READ |
-				NES_CQP_STAG_REM_ACC_EN;
-	}
+	opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_MR |
+		 NES_CQP_STAG_PBL_BLK_SIZE | NES_CQP_STAG_VA_TO |
+		 NES_CQP_STAG_REM_ACC_EN;
+	/*
+	 * The current OFED API does not support the zero based TO option.
+	 * If added then need to changed the NES_CQP_STAG_VA* option.  Also,
+	 * the API does not support that ability to have the MR set for local
+	 * access only when created and not allow the SQ op to override. Given
+	 * this the remote enable must be set here.
+	 */
 
 	nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode);
-	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX, (nespd->pd_id & 0x00007fff));
-	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag);
+	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, 1);
 
-	cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX] =
-			cpu_to_le32((nesfmr->nesmr.pbls_used>1) ?
-			(nesfmr->nesmr.pbls_used-1) : nesfmr->nesmr.pbls_used);
+	cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] =
+			cpu_to_le32((u32)(region_length >> 8) & 0xff000000);
+	cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] |=
+			cpu_to_le32(nespd->pd_id & 0x00007fff);
+
+	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag);
+	set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_VA_LOW_IDX, 0);
+	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_LOW_IDX, 0);
+	set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, 0);
+	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (page_count * 8));
+	cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE);
+	barrier();
 
 	atomic_set(&cqp_request->refcount, 2);
 	nes_post_cqp_request(nesdev, cqp_request);
 
 	/* Wait for CQP */
-	ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0),
-			NES_EVENT_TIMEOUT);
-	nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u,"
-			" CQP Major:Minor codes = 0x%04X:0x%04X.\n",
-			stag, ret, cqp_request->major_code, cqp_request->minor_code);
+	ret = wait_event_timeout(cqp_request->waitq,
+				 (0 != cqp_request->request_done),
+				 NES_EVENT_TIMEOUT);
 
-	if ((!ret) || (cqp_request->major_code)) {
-		nes_put_cqp_request(nesdev, cqp_request);
-		ret = (!ret) ? -ETIME : -EIO;
-		goto failed_leaf_vpbl_pages_alloc;
-	}
+	nes_debug(NES_DBG_MR, "Allocate STag 0x%08X completed, "
+		  "wait_event_timeout ret = %u, CQP Major:Minor codes = "
+		  "0x%04X:0x%04X.\n", stag, ret, cqp_request->major_code,
+		  cqp_request->minor_code);
+	major_code = cqp_request->major_code;
 	nes_put_cqp_request(nesdev, cqp_request);
-	nesfmr->nesmr.ibfmr.lkey = stag;
-	nesfmr->nesmr.ibfmr.rkey = stag;
-	nesfmr->attr = *ibfmr_attr;
-
-	return &nesfmr->nesmr.ibfmr;
-
-	failed_leaf_vpbl_pages_alloc:
-	/* unroll all allocated pages */
-	for (i=0; i<nesfmr->leaf_pbl_cnt; i++) {
-		if (nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase) {
-			pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase,
-					nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase);
-		}
-	}
-	if (nesfmr->root_vpbl.leaf_vpbl)
-		kfree(nesfmr->root_vpbl.leaf_vpbl);
-
-	failed_leaf_vpbl_alloc:
-	if (nesfmr->leaf_pbl_cnt == 0) {
-		if (nesfmr->root_vpbl.pbl_vbase)
-			pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase,
-					nesfmr->root_vpbl.pbl_pbase);
-	} else
-		pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase,
-				nesfmr->root_vpbl.pbl_pbase);
 
-	failed_vpbl_alloc:
-	if (nesfmr->nesmr.pbls_used != 0) {
+	if (!ret || major_code) {
 		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
-		if (nesfmr->nesmr.pbl_4k)
-			nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used;
-		else
-			nesadapter->free_256pbl += nesfmr->nesmr.pbls_used;
+		nesadapter->free_4kpbl++;
 		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
 	}
 
-failed_vpbl_avail:
-	kfree(nesfmr);
-
-	failed_fmr_alloc:
-	nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-
-	failed_resource_alloc:
-	return ERR_PTR(ret);
+	if (!ret)
+		return -ETIME;
+	else if (major_code)
+		return -EIO;
+	return 0;
 }
 
-
-/**
- * nes_dealloc_fmr
+/*
+ * nes_alloc_fast_reg_mr
  */
-static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
+struct ib_mr *nes_alloc_fast_reg_mr(struct ib_pd *ibpd, int max_page_list_len)
 {
-	unsigned long flags;
-	struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr);
-	struct nes_fmr *nesfmr = to_nesfmr(nesmr);
-	struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device);
+	struct nes_pd *nespd = to_nespd(ibpd);
+	struct nes_vnic *nesvnic = to_nesvnic(ibpd->device);
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
-	int i = 0;
-	int rc;
 
-	/* free the resources */
-	if (nesfmr->leaf_pbl_cnt == 0) {
-		/* single PBL case */
-		if (nesfmr->root_vpbl.pbl_vbase)
-			pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase,
-					nesfmr->root_vpbl.pbl_pbase);
-	} else {
-		for (i = 0; i < nesfmr->leaf_pbl_cnt; i++) {
-			pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase,
-					nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase);
-		}
-		kfree(nesfmr->root_vpbl.leaf_vpbl);
-		pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase,
-				nesfmr->root_vpbl.pbl_pbase);
-	}
-	nesmr->ibmw.device = ibfmr->device;
-	nesmr->ibmw.pd = ibfmr->pd;
-	nesmr->ibmw.rkey = ibfmr->rkey;
-	nesmr->ibmw.uobject = NULL;
+	u32 next_stag_index;
+	u8 stag_key = 0;
+	u32 driver_key = 0;
+	int err = 0;
+	u32 stag_index = 0;
+	struct nes_mr *nesmr;
+	u32 stag;
+	int ret;
+	struct ib_mr *ibmr;
+/*
+ * Note:  Set to always use a fixed length single page entry PBL.  This is to allow
+ *	 for the fast_reg_mr operation to always know the size of the PBL.
+ */
+	if (max_page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64)))
+		return ERR_PTR(-E2BIG);
 
-	rc = nes_dealloc_mw(&nesmr->ibmw);
+	get_random_bytes(&next_stag_index, sizeof(next_stag_index));
+	stag_key = (u8)next_stag_index;
+	next_stag_index >>= 8;
+	next_stag_index %= nesadapter->max_mr;
 
-	if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) {
-		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
-		if (nesfmr->nesmr.pbl_4k) {
-			nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used;
-			WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl);
-		} else {
-			nesadapter->free_256pbl += nesfmr->nesmr.pbls_used;
-			WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl);
-		}
-		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+	err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs,
+				 nesadapter->max_mr, &stag_index,
+				 &next_stag_index);
+	if (err)
+		return ERR_PTR(err);
+
+	nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL);
+	if (!nesmr) {
+		nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+		return ERR_PTR(-ENOMEM);
 	}
 
-	return rc;
-}
+	stag = stag_index << 8;
+	stag |= driver_key;
+	stag += (u32)stag_key;
 
+	nes_debug(NES_DBG_MR, "Allocating STag 0x%08X index = 0x%08X\n",
+		  stag, stag_index);
 
-/**
- * nes_map_phys_fmr
- */
-static int nes_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
-		int list_len, u64 iova)
-{
-	return 0;
-}
+	ret = alloc_fast_reg_mr(nesdev, nespd, stag, max_page_list_len);
 
+	if (ret == 0) {
+		nesmr->ibmr.rkey = stag;
+		nesmr->ibmr.lkey = stag;
+		nesmr->mode = IWNES_MEMREG_TYPE_FMEM;
+		ibmr = &nesmr->ibmr;
+	} else {
+		kfree(nesmr);
+		nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+		ibmr = ERR_PTR(-ENOMEM);
+	}
+	return ibmr;
+}
 
-/**
- * nes_unmap_frm
+/*
+ * nes_alloc_fast_reg_page_list
  */
-static int nes_unmap_fmr(struct list_head *ibfmr_list)
+static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list(
+							struct ib_device *ibdev,
+							int page_list_len)
 {
-	return 0;
+	struct nes_vnic *nesvnic = to_nesvnic(ibdev);
+	struct nes_device *nesdev = nesvnic->nesdev;
+	struct ib_fast_reg_page_list *pifrpl;
+	struct nes_ib_fast_reg_page_list *pnesfrpl;
+
+	if (page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64)))
+		return ERR_PTR(-E2BIG);
+	/*
+	 * Allocate the ib_fast_reg_page_list structure, the
+	 * nes_fast_bpl structure, and the PLB table.
+	 */
+	pnesfrpl = kmalloc(sizeof(struct nes_ib_fast_reg_page_list) +
+			   page_list_len * sizeof(u64), GFP_KERNEL);
+
+	if (!pnesfrpl)
+		return ERR_PTR(-ENOMEM);
+
+	pifrpl = &pnesfrpl->ibfrpl;
+	pifrpl->page_list = &pnesfrpl->pbl;
+	pifrpl->max_page_list_len = page_list_len;
+	/*
+	 * Allocate the WQE PBL
+	 */
+	pnesfrpl->nes_wqe_pbl.kva = pci_alloc_consistent(nesdev->pcidev,
+							 page_list_len * sizeof(u64),
+							 &pnesfrpl->nes_wqe_pbl.paddr);
+
+	if (!pnesfrpl->nes_wqe_pbl.kva) {
+		kfree(pnesfrpl);
+		return ERR_PTR(-ENOMEM);
+	}
+	nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, "
+		  "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, "
+		  "pbl.paddr= %p\n", pnesfrpl, &pnesfrpl->ibfrpl,
+		  pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva,
+		  (void *)pnesfrpl->nes_wqe_pbl.paddr);
+
+	return pifrpl;
 }
 
+/*
+ * nes_free_fast_reg_page_list
+ */
+static void nes_free_fast_reg_page_list(struct ib_fast_reg_page_list *pifrpl)
+{
+	struct nes_vnic *nesvnic = to_nesvnic(pifrpl->device);
+	struct nes_device *nesdev = nesvnic->nesdev;
+	struct nes_ib_fast_reg_page_list *pnesfrpl;
 
+	pnesfrpl = container_of(pifrpl, struct nes_ib_fast_reg_page_list, ibfrpl);
+	/*
+	 * Free the WQE PBL.
+	 */
+	pci_free_consistent(nesdev->pcidev,
+			    pifrpl->max_page_list_len * sizeof(u64),
+			    pnesfrpl->nes_wqe_pbl.kva,
+			    pnesfrpl->nes_wqe_pbl.paddr);
+	/*
+	 * Free the PBL structure
+	 */
+	kfree(pnesfrpl);
+}
 
 /**
  * nes_query_device
@@ -633,23 +527,23 @@ static int nes_query_device(struct ib_de
 	props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2;
 	props->max_sge = nesdev->nesadapter->max_sge;
 	props->max_cq = nesibdev->max_cq;
-	props->max_cqe = nesdev->nesadapter->max_cqe - 1;
+	props->max_cqe = nesdev->nesadapter->max_cqe;
 	props->max_mr = nesibdev->max_mr;
 	props->max_mw = nesibdev->max_mr;
 	props->max_pd = nesibdev->max_pd;
 	props->max_sge_rd = 1;
 	switch (nesdev->nesadapter->max_irrq_wr) {
 		case 0:
-			props->max_qp_rd_atom = 1;
+			props->max_qp_rd_atom = 2;
 			break;
 		case 1:
-			props->max_qp_rd_atom = 4;
+			props->max_qp_rd_atom = 8;
 			break;
 		case 2:
-			props->max_qp_rd_atom = 16;
+			props->max_qp_rd_atom = 32;
 			break;
 		case 3:
-			props->max_qp_rd_atom = 32;
+			props->max_qp_rd_atom = 64;
 			break;
 		default:
 			props->max_qp_rd_atom = 0;
@@ -1121,6 +1015,7 @@ static int nes_setup_virt_qp(struct nes_
 		kunmap(nesqp->page);
 		return -ENOMEM;
 	}
+	nesqp->sq_kmapped = 1;
 	nesqp->hwqp.q2_vbase = mem;
 	mem += 256;
 	memset(nesqp->hwqp.q2_vbase, 0, 256);
@@ -1198,7 +1093,10 @@ static inline void nes_free_qp_mem(struc
 		pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase);
 		pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase );
 		nesqp->pbl_vbase = NULL;
-		kunmap(nesqp->page);
+		if (nesqp->sq_kmapped) {
+			nesqp->sq_kmapped = 0;
+			kunmap(nesqp->page);
+		}
 	}
 }
 
@@ -1504,8 +1402,6 @@ static struct ib_qp *nes_create_qp(struc
 			nes_debug(NES_DBG_QP, "QP%u structure located @%p.Size = %u.\n",
 					nesqp->hwqp.qp_id, nesqp, (u32)sizeof(*nesqp));
 			spin_lock_init(&nesqp->lock);
-			init_waitqueue_head(&nesqp->state_waitq);
-			init_waitqueue_head(&nesqp->kick_waitq);
 			nes_add_ref(&nesqp->ibqp);
 			break;
 		default:
@@ -1513,6 +1409,8 @@ static struct ib_qp *nes_create_qp(struc
 			return ERR_PTR(-EINVAL);
 	}
 
+	nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
+
 	/* update the QP table */
 	nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp;
 	nes_debug(NES_DBG_QP, "netdev refcnt=%u\n",
@@ -1607,8 +1505,10 @@ static int nes_destroy_qp(struct ib_qp *
 				nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index;
 			}
 		}
-		if (nesqp->pbl_pbase)
+		if (nesqp->pbl_pbase && nesqp->sq_kmapped) {
+			nesqp->sq_kmapped = 0;
 			kunmap(nesqp->page);
+		}
 	} else {
 		/* Clean any pending completions from the cq(s) */
 		if (nesqp->nesscq)
@@ -1649,6 +1549,9 @@ static struct ib_cq *nes_create_cq(struc
 	unsigned long flags;
 	int ret;
 
+	if (entries > nesadapter->max_cqe)
+		return ERR_PTR(-EINVAL);
+
 	err = nes_alloc_resource(nesadapter, nesadapter->allocated_cqs,
 			nesadapter->max_cq, &cq_num, &nesadapter->next_cq);
 	if (err) {
@@ -2606,9 +2509,6 @@ static struct ib_mr *nes_reg_user_mr(str
 			stag = stag_index << 8;
 			stag |= driver_key;
 			stag += (u32)stag_key;
-			if (stag == 0) {
-				stag = 1;
-			}
 
 			iova_start = virt;
 			/* Make the leaf PBL the root if only one PBL */
@@ -3109,7 +3009,6 @@ int nes_modify_qp(struct ib_qp *ibqp, st
 								" already done based on hw state.\n",
 								nesqp->hwqp.qp_id);
 						issue_modify_qp = 0;
-						nesqp->in_disconnect = 0;
 					}
 					switch (nesqp->hw_iwarp_state) {
 						case NES_AEQE_IWARP_STATE_CLOSING:
@@ -3122,7 +3021,6 @@ int nes_modify_qp(struct ib_qp *ibqp, st
 							break;
 						default:
 							next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
-							nesqp->in_disconnect = 1;
 							nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
 							break;
 					}
@@ -3139,7 +3037,6 @@ int nes_modify_qp(struct ib_qp *ibqp, st
 				next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE;
 				nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE;
 				issue_modify_qp = 1;
-				nesqp->in_disconnect = 1;
 				break;
 			case IB_QPS_ERR:
 			case IB_QPS_RESET:
@@ -3162,7 +3059,6 @@ int nes_modify_qp(struct ib_qp *ibqp, st
 				if ((nesqp->hw_tcp_state > NES_AEQE_TCP_STATE_CLOSED) &&
 						(nesqp->hw_tcp_state != NES_AEQE_TCP_STATE_TIME_WAIT)) {
 					next_iwarp_state |= NES_CQP_QP_RESET;
-					nesqp->in_disconnect = 1;
 				} else {
 					nes_debug(NES_DBG_MOD_QP, "QP%u NOT setting NES_CQP_QP_RESET since TCP state = %u\n",
 							nesqp->hwqp.qp_id, nesqp->hw_tcp_state);
@@ -3373,21 +3269,17 @@ static int nes_post_send(struct ib_qp *i
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_qp *nesqp = to_nesqp(ibqp);
 	struct nes_hw_qp_wqe *wqe;
-	int err;
+	int err = 0;
 	u32 qsize = nesqp->hwqp.sq_size;
 	u32 head;
-	u32 wqe_misc;
-	u32 wqe_count;
+	u32 wqe_misc = 0;
+	u32 wqe_count = 0;
 	u32 counter;
-	u32 total_payload_length;
 
-	err = 0;
-	wqe_misc = 0;
-	wqe_count = 0;
-	total_payload_length = 0;
-
-	if (nesqp->ibqp_state > IB_QPS_RTS)
-		return -EINVAL;
+	if (nesqp->ibqp_state > IB_QPS_RTS) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	spin_lock_irqsave(&nesqp->lock, flags);
 
@@ -3413,94 +3305,208 @@ static int nes_post_send(struct ib_qp *i
 		u64temp = (u64)(ib_wr->wr_id);
 		set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX,
 					u64temp);
-			switch (ib_wr->opcode) {
-				case IB_WR_SEND:
-					if (ib_wr->send_flags & IB_SEND_SOLICITED) {
-						wqe_misc = NES_IWARP_SQ_OP_SENDSE;
-					} else {
-						wqe_misc = NES_IWARP_SQ_OP_SEND;
-					}
-					if (ib_wr->num_sge > nesdev->nesadapter->max_sge) {
-						err = -EINVAL;
-						break;
-					}
-					if (ib_wr->send_flags & IB_SEND_FENCE) {
-						wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
-					}
-					if ((ib_wr->send_flags & IB_SEND_INLINE) &&
-							((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
-							(ib_wr->sg_list[0].length <= 64)) {
-						memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
-							       (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
-						set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX,
-								ib_wr->sg_list[0].length);
-						wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA;
-					} else {
-						fill_wqe_sg_send(wqe, ib_wr, 1);
-					}
+		switch (ib_wr->opcode) {
+		case IB_WR_SEND:
+		case IB_WR_SEND_WITH_INV:
+			if (IB_WR_SEND == ib_wr->opcode) {
+				if (ib_wr->send_flags & IB_SEND_SOLICITED)
+					wqe_misc = NES_IWARP_SQ_OP_SENDSE;
+				else
+					wqe_misc = NES_IWARP_SQ_OP_SEND;
+			} else {
+				if (ib_wr->send_flags & IB_SEND_SOLICITED)
+					wqe_misc = NES_IWARP_SQ_OP_SENDSEINV;
+				else
+					wqe_misc = NES_IWARP_SQ_OP_SENDINV;
 
-					break;
-				case IB_WR_RDMA_WRITE:
-					wqe_misc = NES_IWARP_SQ_OP_RDMAW;
-					if (ib_wr->num_sge > nesdev->nesadapter->max_sge) {
-						nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n",
-								ib_wr->num_sge,
-								nesdev->nesadapter->max_sge);
-						err = -EINVAL;
-						break;
-					}
-					if (ib_wr->send_flags & IB_SEND_FENCE) {
-						wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
-					}
+				set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX,
+						    ib_wr->ex.invalidate_rkey);
+			}
 
-					set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
-							ib_wr->wr.rdma.rkey);
-					set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
-							ib_wr->wr.rdma.remote_addr);
+			if (ib_wr->num_sge > nesdev->nesadapter->max_sge) {
+				err = -EINVAL;
+				break;
+			}
 
-					if ((ib_wr->send_flags & IB_SEND_INLINE) &&
-							((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
-							(ib_wr->sg_list[0].length <= 64)) {
-						memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
-							       (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
-						set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX,
-								ib_wr->sg_list[0].length);
-						wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA;
-					} else {
-						fill_wqe_sg_send(wqe, ib_wr, 1);
-					}
-					wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] =
-							wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX];
-					break;
-				case IB_WR_RDMA_READ:
-					/* iWARP only supports 1 sge for RDMA reads */
-					if (ib_wr->num_sge > 1) {
-						nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n",
-								ib_wr->num_sge);
-						err = -EINVAL;
-						break;
-					}
-					wqe_misc = NES_IWARP_SQ_OP_RDMAR;
-					set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
-							ib_wr->wr.rdma.remote_addr);
-					set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
-							ib_wr->wr.rdma.rkey);
-					set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX,
-							ib_wr->sg_list->length);
-					set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
-							ib_wr->sg_list->addr);
-					set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX,
-							ib_wr->sg_list->lkey);
-					break;
-				default:
-					/* error */
-					err = -EINVAL;
-					break;
+			if (ib_wr->send_flags & IB_SEND_FENCE)
+				wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
+
+			if ((ib_wr->send_flags & IB_SEND_INLINE) &&
+			    ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
+			     (ib_wr->sg_list[0].length <= 64)) {
+				memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
+				       (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
+				set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX,
+						    ib_wr->sg_list[0].length);
+				wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA;
+			} else {
+				fill_wqe_sg_send(wqe, ib_wr, 1);
 			}
 
-		if (ib_wr->send_flags & IB_SEND_SIGNALED) {
-			wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL;
+			break;
+		case IB_WR_RDMA_WRITE:
+			wqe_misc = NES_IWARP_SQ_OP_RDMAW;
+			if (ib_wr->num_sge > nesdev->nesadapter->max_sge) {
+				nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n",
+					  ib_wr->num_sge, nesdev->nesadapter->max_sge);
+				err = -EINVAL;
+				break;
+			}
+
+			if (ib_wr->send_flags & IB_SEND_FENCE)
+				wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE;
+
+			set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
+					    ib_wr->wr.rdma.rkey);
+			set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
+					    ib_wr->wr.rdma.remote_addr);
+
+			if ((ib_wr->send_flags & IB_SEND_INLINE) &&
+			    ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) &&
+			     (ib_wr->sg_list[0].length <= 64)) {
+				memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX],
+				       (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length);
+				set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX,
+						    ib_wr->sg_list[0].length);
+				wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA;
+			} else {
+				fill_wqe_sg_send(wqe, ib_wr, 1);
+			}
+
+			wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] =
+				wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX];
+			break;
+		case IB_WR_RDMA_READ:
+		case IB_WR_RDMA_READ_WITH_INV:
+			/* iWARP only supports 1 sge for RDMA reads */
+			if (ib_wr->num_sge > 1) {
+				nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n",
+					  ib_wr->num_sge);
+				err = -EINVAL;
+				break;
+			}
+			if (ib_wr->opcode == IB_WR_RDMA_READ) {
+				wqe_misc = NES_IWARP_SQ_OP_RDMAR;
+			} else {
+				wqe_misc = NES_IWARP_SQ_OP_RDMAR_LOCINV;
+				set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX,
+						    ib_wr->ex.invalidate_rkey);
+			}
+
+			set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX,
+					    ib_wr->wr.rdma.remote_addr);
+			set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX,
+					    ib_wr->wr.rdma.rkey);
+			set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX,
+					    ib_wr->sg_list->length);
+			set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
+					    ib_wr->sg_list->addr);
+			set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX,
+					    ib_wr->sg_list->lkey);
+			break;
+		case IB_WR_LOCAL_INV:
+			wqe_misc = NES_IWARP_SQ_OP_LOCINV;
+			set_wqe_32bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX,
+					    ib_wr->ex.invalidate_rkey);
+			break;
+		case IB_WR_FAST_REG_MR:
+		{
+			int i;
+			int flags = ib_wr->wr.fast_reg.access_flags;
+			struct nes_ib_fast_reg_page_list *pnesfrpl =
+				container_of(ib_wr->wr.fast_reg.page_list,
+					     struct nes_ib_fast_reg_page_list,
+					     ibfrpl);
+			u64 *src_page_list = pnesfrpl->ibfrpl.page_list;
+			u64 *dst_page_list = pnesfrpl->nes_wqe_pbl.kva;
+
+			if (ib_wr->wr.fast_reg.page_list_len >
+			    (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) {
+				nes_debug(NES_DBG_IW_TX, "SQ_FMR: bad page_list_len\n");
+				err = -EINVAL;
+				break;
+			}
+			wqe_misc = NES_IWARP_SQ_OP_FAST_REG;
+			set_wqe_64bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX,
+					    ib_wr->wr.fast_reg.iova_start);
+			set_wqe_32bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX,
+					    ib_wr->wr.fast_reg.length);
+			set_wqe_32bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX,
+					    ib_wr->wr.fast_reg.rkey);
+			/* Set page size: */
+			if (ib_wr->wr.fast_reg.page_shift == 12) {
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K;
+			} else if (ib_wr->wr.fast_reg.page_shift == 21) {
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M;
+			} else {
+				nes_debug(NES_DBG_IW_TX, "Invalid page shift,"
+					  " ib_wr=%u, max=1\n", ib_wr->num_sge);
+				err = -EINVAL;
+				break;
+			}
+			/* Set access_flags */
+			wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ;
+			if (flags & IB_ACCESS_LOCAL_WRITE)
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE;
+
+			if (flags & IB_ACCESS_REMOTE_WRITE)
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE;
+
+			if (flags & IB_ACCESS_REMOTE_READ)
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ;
+
+			if (flags & IB_ACCESS_MW_BIND)
+				wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND;
+
+			/* Fill in PBL info: */
+			if (ib_wr->wr.fast_reg.page_list_len >
+			    pnesfrpl->ibfrpl.max_page_list_len) {
+				nes_debug(NES_DBG_IW_TX, "Invalid page list length,"
+					  " ib_wr=%p, value=%u, max=%u\n",
+					  ib_wr, ib_wr->wr.fast_reg.page_list_len,
+					  pnesfrpl->ibfrpl.max_page_list_len);
+				err = -EINVAL;
+				break;
+			}
+
+			set_wqe_64bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX,
+					    pnesfrpl->nes_wqe_pbl.paddr);
+
+			set_wqe_32bit_value(wqe->wqe_words,
+					    NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX,
+					    ib_wr->wr.fast_reg.page_list_len * 8);
+
+			for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++)
+				dst_page_list[i] = cpu_to_le64(src_page_list[i]);
+
+			nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %p, "
+				  "length: %d, rkey: %0x, pgl_paddr: %p, "
+				  "page_list_len: %u, wqe_misc: %x\n",
+				  (void *)ib_wr->wr.fast_reg.iova_start,
+				  ib_wr->wr.fast_reg.length,
+				  ib_wr->wr.fast_reg.rkey,
+				  (void *)pnesfrpl->nes_wqe_pbl.paddr,
+				  ib_wr->wr.fast_reg.page_list_len,
+				  wqe_misc);
+			break;
+		}
+		default:
+			/* error */
+			err = -EINVAL;
+			break;
 		}
+
+		if (err)
+			break;
+
+		if ((ib_wr->send_flags & IB_SEND_SIGNALED) || nesqp->sig_all)
+			wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL;
+
 		wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(wqe_misc);
 
 		ib_wr = ib_wr->next;
@@ -3522,6 +3528,7 @@ static int nes_post_send(struct ib_qp *i
 
 	spin_unlock_irqrestore(&nesqp->lock, flags);
 
+out:
 	if (err)
 		*bad_wr = ib_wr;
 	return err;
@@ -3548,8 +3555,10 @@ static int nes_post_recv(struct ib_qp *i
 	u32 counter;
 	u32 total_payload_length;
 
-	if (nesqp->ibqp_state > IB_QPS_RTS)
-		return -EINVAL;
+	if (nesqp->ibqp_state > IB_QPS_RTS) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	spin_lock_irqsave(&nesqp->lock, flags);
 
@@ -3612,6 +3621,7 @@ static int nes_post_recv(struct ib_qp *i
 
 	spin_unlock_irqrestore(&nesqp->lock, flags);
 
+out:
 	if (err)
 		*bad_wr = ib_wr;
 	return err;
@@ -3720,6 +3730,12 @@ static int nes_poll_cq(struct ib_cq *ibc
 						nes_debug(NES_DBG_CQ, "Operation = Send.\n");
 						entry->opcode = IB_WC_SEND;
 						break;
+					case NES_IWARP_SQ_OP_LOCINV:
+						entry->opcode = IB_WR_LOCAL_INV;
+						break;
+					case NES_IWARP_SQ_OP_FAST_REG:
+						entry->opcode = IB_WC_FAST_REG_MR;
+						break;
 				}
 
 				nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1);
@@ -3890,10 +3906,9 @@ struct nes_ib_device *nes_init_ofa_devic
 	nesibdev->ibdev.dealloc_mw = nes_dealloc_mw;
 	nesibdev->ibdev.bind_mw = nes_bind_mw;
 
-	nesibdev->ibdev.alloc_fmr = nes_alloc_fmr;
-	nesibdev->ibdev.unmap_fmr = nes_unmap_fmr;
-	nesibdev->ibdev.dealloc_fmr = nes_dealloc_fmr;
-	nesibdev->ibdev.map_phys_fmr = nes_map_phys_fmr;
+	nesibdev->ibdev.alloc_fast_reg_mr = nes_alloc_fast_reg_mr;
+	nesibdev->ibdev.alloc_fast_reg_page_list = nes_alloc_fast_reg_page_list;
+	nesibdev->ibdev.free_fast_reg_page_list = nes_free_fast_reg_page_list;
 
 	nesibdev->ibdev.attach_mcast = nes_multicast_attach;
 	nesibdev->ibdev.detach_mcast = nes_multicast_detach;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_verbs.h linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.h
--- linux-libre-2.6.32-gnu1/drivers/infiniband/hw/nes/nes_verbs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/hw/nes/nes_verbs.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel Corporation.  All rights reserved.
  * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -135,19 +135,15 @@ struct nes_qp {
 	struct ib_qp          ibqp;
 	void                  *allocated_buffer;
 	struct iw_cm_id       *cm_id;
-	struct workqueue_struct *wq;
 	struct nes_cq         *nesscq;
 	struct nes_cq         *nesrcq;
 	struct nes_pd         *nespd;
 	void *cm_node; /* handle of the node this QP is associated with */
 	struct ietf_mpa_frame *ietf_frame;
 	dma_addr_t            ietf_frame_pbase;
-	wait_queue_head_t     state_waitq;
 	struct ib_mr          *lsmm_mr;
-	unsigned long         socket;
 	struct nes_hw_qp      hwqp;
 	struct work_struct    work;
-	struct work_struct    ae_work;
 	enum ib_qp_state      ibqp_state;
 	u32                   iwarp_state;
 	u32                   hte_index;
@@ -165,19 +161,20 @@ struct nes_qp {
 	struct page           *page;
 	struct timer_list     terminate_timer;
 	enum ib_event_type    terminate_eventtype;
-	wait_queue_head_t     kick_waitq;
-	u16                   in_disconnect;
+	u16                   active_conn:1;
+	u16                   skip_lsmm:1;
+	u16                   user_mode:1;
+	u16                   hte_added:1;
+	u16                   flush_issued:1;
+	u16                   destroyed:1;
+	u16                   sig_all:1;
+	u16                   rsvd:9;
 	u16                   private_data_len;
 	u16                   term_sq_flush_code;
 	u16                   term_rq_flush_code;
-	u8                    active_conn;
-	u8                    skip_lsmm;
-	u8                    user_mode;
-	u8                    hte_added;
 	u8                    hw_iwarp_state;
-	u8                    flush_issued;
 	u8                    hw_tcp_state;
 	u8                    term_flags;
-	u8                    destroyed;
+	u8                    sq_kmapped;
 };
 #endif			/* NES_VERBS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -884,6 +884,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(st
 
 	neigh->neighbour = neighbour;
 	neigh->dev = dev;
+	memset(&neigh->dgid.raw, 0, sizeof (union ib_gid));
 	*to_ipoib_neigh(neighbour) = neigh;
 	skb_queue_head_init(&neigh->queue);
 	ipoib_cm_set(neigh, NULL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2010-02-24 13:52:17.000000000 -0500
@@ -625,6 +625,7 @@ static struct iscsi_transport iscsi_iser
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS |
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iser_memory.c linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_memory.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iser_memory.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_memory.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,6 +209,8 @@ void iser_finalize_rdma_unaligned_sg(str
 	mem_copy->copy_buf = NULL;
 }
 
+#define IS_4K_ALIGNED(addr)	((((unsigned long)addr) & ~MASK_4K) == 0)
+
 /**
  * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses
  * and returns the length of resulting physical address array (may be less than
@@ -221,62 +223,52 @@ void iser_finalize_rdma_unaligned_sg(str
  * where --few fragments of the same page-- are present in the SG as
  * consecutive elements. Also, it handles one entry SG.
  */
+
 static int iser_sg_to_page_vec(struct iser_data_buf *data,
 			       struct iser_page_vec *page_vec,
 			       struct ib_device *ibdev)
 {
-	struct scatterlist *sgl = (struct scatterlist *)data->buf;
-	struct scatterlist *sg;
-	u64 first_addr, last_addr, page;
-	int end_aligned;
-	unsigned int cur_page = 0;
+	struct scatterlist *sg, *sgl = (struct scatterlist *)data->buf;
+	u64 start_addr, end_addr, page, chunk_start = 0;
 	unsigned long total_sz = 0;
-	int i;
+	unsigned int dma_len;
+	int i, new_chunk, cur_page, last_ent = data->dma_nents - 1;
 
 	/* compute the offset of first element */
 	page_vec->offset = (u64) sgl[0].offset & ~MASK_4K;
 
+	new_chunk = 1;
+	cur_page  = 0;
 	for_each_sg(sgl, sg, data->dma_nents, i) {
-		unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
-
+		start_addr = ib_sg_dma_address(ibdev, sg);
+		if (new_chunk)
+			chunk_start = start_addr;
+		dma_len = ib_sg_dma_len(ibdev, sg);
+		end_addr = start_addr + dma_len;
 		total_sz += dma_len;
 
-		first_addr = ib_sg_dma_address(ibdev, sg);
-		last_addr  = first_addr + dma_len;
-
-		end_aligned   = !(last_addr  & ~MASK_4K);
-
-		/* continue to collect page fragments till aligned or SG ends */
-		while (!end_aligned && (i + 1 < data->dma_nents)) {
-			sg = sg_next(sg);
-			i++;
-			dma_len = ib_sg_dma_len(ibdev, sg);
-			total_sz += dma_len;
-			last_addr = ib_sg_dma_address(ibdev, sg) + dma_len;
-			end_aligned = !(last_addr  & ~MASK_4K);
+		/* collect page fragments until aligned or end of SG list */
+		if (!IS_4K_ALIGNED(end_addr) && i < last_ent) {
+			new_chunk = 0;
+			continue;
 		}
+		new_chunk = 1;
 
-		/* handle the 1st page in the 1st DMA element */
-		if (cur_page == 0) {
-			page = first_addr & MASK_4K;
-			page_vec->pages[cur_page] = page;
-			cur_page++;
+		/* address of the first page in the contiguous chunk;
+		   masking relevant for the very first SG entry,
+		   which might be unaligned */
+		page = chunk_start & MASK_4K;
+		do {
+			page_vec->pages[cur_page++] = page;
 			page += SIZE_4K;
-		} else
-			page = first_addr;
-
-		for (; page < last_addr; page += SIZE_4K) {
-			page_vec->pages[cur_page] = page;
-			cur_page++;
-		}
-
+		} while (page < end_addr);
 	}
+
 	page_vec->data_size = total_sz;
 	iser_dbg("page_vec->data_size:%d cur_page %d\n", page_vec->data_size,cur_page);
 	return cur_page;
 }
 
-#define IS_4K_ALIGNED(addr)	((((unsigned long)addr) & ~MASK_4K) == 0)
 
 /**
  * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned
@@ -284,42 +276,40 @@ static int iser_sg_to_page_vec(struct is
  * the number of entries which are aligned correctly. Supports the case where
  * consecutive SG elements are actually fragments of the same physcial page.
  */
-static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
-					      struct ib_device *ibdev)
+static int iser_data_buf_aligned_len(struct iser_data_buf *data,
+				      struct ib_device *ibdev)
 {
-	struct scatterlist *sgl, *sg;
-	u64 end_addr, next_addr;
-	int i, cnt;
-	unsigned int ret_len = 0;
+	struct scatterlist *sgl, *sg, *next_sg = NULL;
+	u64 start_addr, end_addr;
+	int i, ret_len, start_check = 0;
+
+	if (data->dma_nents == 1)
+		return 1;
 
 	sgl = (struct scatterlist *)data->buf;
+	start_addr  = ib_sg_dma_address(ibdev, sgl);
 
-	cnt = 0;
 	for_each_sg(sgl, sg, data->dma_nents, i) {
-		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
-		   "offset: %ld sz: %ld\n", i,
-		   (unsigned long)sg_phys(sg),
-		   (unsigned long)sg->offset,
-		   (unsigned long)sg->length); */
-		end_addr = ib_sg_dma_address(ibdev, sg) +
-			   ib_sg_dma_len(ibdev, sg);
-		/* iser_dbg("Checking sg iobuf end address "
-		       "0x%08lX\n", end_addr); */
-		if (i + 1 < data->dma_nents) {
-			next_addr = ib_sg_dma_address(ibdev, sg_next(sg));
-			/* are i, i+1 fragments of the same page? */
-			if (end_addr == next_addr) {
-				cnt++;
-				continue;
-			} else if (!IS_4K_ALIGNED(end_addr)) {
-				ret_len = cnt + 1;
-				break;
-			}
-		}
-		cnt++;
+		if (start_check && !IS_4K_ALIGNED(start_addr))
+			break;
+
+		next_sg = sg_next(sg);
+		if (!next_sg)
+			break;
+
+		end_addr    = start_addr + ib_sg_dma_len(ibdev, sg);
+		start_addr  = ib_sg_dma_address(ibdev, next_sg);
+
+		if (end_addr == start_addr) {
+			start_check = 0;
+			continue;
+		} else
+			start_check = 1;
+
+		if (!IS_4K_ALIGNED(end_addr))
+			break;
 	}
-	if (i == data->dma_nents)
-		ret_len = cnt;	/* loop ended */
+	ret_len = (next_sg) ? i : i+1;
 	iser_dbg("Found %d aligned entries out of %d in sg:0x%p\n",
 		 ret_len, data->dma_nents, data);
 	return ret_len;
diff -druNp linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c
--- linux-libre-2.6.32-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2010-02-24 13:52:17.000000000 -0500
@@ -499,7 +499,7 @@ void iser_conn_init(struct iser_conn *ib
 
  /**
  * starts the process of connecting to the target
- * sleeps untill the connection is established or rejected
+ * sleeps until the connection is established or rejected
  */
 int iser_connect(struct iser_conn   *ib_conn,
 		 struct sockaddr_in *src_addr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/evdev.c linux-libre-2.6.33-gnu1/drivers/input/evdev.c
--- linux-libre-2.6.32-gnu1/drivers/input/evdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/evdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,8 @@ static void evdev_pass_event(struct evde
 	client->head &= EVDEV_BUFFER_SIZE - 1;
 	spin_unlock(&client->buffer_lock);
 
-	kill_fasync(&client->fasync, SIGIO, POLL_IN);
+	if (event->type == EV_SYN)
+		kill_fasync(&client->fasync, SIGIO, POLL_IN);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/ff-core.c linux-libre-2.6.33-gnu1/drivers/input/ff-core.c
--- linux-libre-2.6.32-gnu1/drivers/input/ff-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/ff-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -353,7 +353,7 @@ int input_ff_create(struct input_dev *de
 EXPORT_SYMBOL_GPL(input_ff_create);
 
 /**
- * input_ff_free() - frees force feedback portion of input device
+ * input_ff_destroy() - frees force feedback portion of input device
  * @dev: input device supporting force feedback
  *
  * This function is only needed in error path as input core will
@@ -369,6 +369,7 @@ void input_ff_destroy(struct input_dev *
 		if (ff->destroy)
 			ff->destroy(ff);
 		kfree(ff->private);
+		kfree(ff->effects);
 		kfree(ff);
 		dev->ff = NULL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/ff-memless.c linux-libre-2.6.33-gnu1/drivers/input/ff-memless.c
--- linux-libre-2.6.32-gnu1/drivers/input/ff-memless.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/ff-memless.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,11 +221,27 @@ static int get_compatible_type(struct ff
 }
 
 /*
+ * Only left/right direction should be used (under/over 0x8000) for
+ * forward/reverse motor direction (to keep calculation fast & simple).
+ */
+static u16 ml_calculate_direction(u16 direction, u16 force,
+				  u16 new_direction, u16 new_force)
+{
+	if (!force)
+		return new_direction;
+	if (!new_force)
+		return direction;
+	return (((u32)(direction >> 1) * force +
+		 (new_direction >> 1) * new_force) /
+		(force + new_force)) << 1;
+}
+
+/*
  * Combine two effects and apply gain.
  */
 static void ml_combine_effects(struct ff_effect *effect,
 			       struct ml_effect_state *state,
-			       unsigned int gain)
+			       int gain)
 {
 	struct ff_effect *new = state->effect;
 	unsigned int strong, weak, i;
@@ -252,8 +268,21 @@ static void ml_combine_effects(struct ff
 		break;
 
 	case FF_RUMBLE:
-		strong = new->u.rumble.strong_magnitude * gain / 0xffff;
-		weak = new->u.rumble.weak_magnitude * gain / 0xffff;
+		strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff;
+		weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff;
+
+		if (effect->u.rumble.strong_magnitude + strong)
+			effect->direction = ml_calculate_direction(
+				effect->direction,
+				effect->u.rumble.strong_magnitude,
+				new->direction, strong);
+		else if (effect->u.rumble.weak_magnitude + weak)
+			effect->direction = ml_calculate_direction(
+				effect->direction,
+				effect->u.rumble.weak_magnitude,
+				new->direction, weak);
+		else
+			effect->direction = 0;
 		effect->u.rumble.strong_magnitude =
 			min(strong + effect->u.rumble.strong_magnitude,
 			    0xffffU);
@@ -268,6 +297,13 @@ static void ml_combine_effects(struct ff
 		/* here we also scale it 0x7fff => 0xffff */
 		i = i * gain / 0x7fff;
 
+		if (effect->u.rumble.strong_magnitude + i)
+			effect->direction = ml_calculate_direction(
+				effect->direction,
+				effect->u.rumble.strong_magnitude,
+				new->direction, i);
+		else
+			effect->direction = 0;
 		effect->u.rumble.strong_magnitude =
 			min(i + effect->u.rumble.strong_magnitude, 0xffffU);
 		effect->u.rumble.weak_magnitude =
@@ -411,8 +447,6 @@ static int ml_ff_playback(struct input_d
 				 msecs_to_jiffies(state->effect->replay.length);
 		state->adj_at = state->play_at;
 
-		ml_schedule_timer(ml);
-
 	} else {
 		debug("initiated stop");
 
@@ -420,10 +454,10 @@ static int ml_ff_playback(struct input_d
 			__set_bit(FF_EFFECT_ABORTING, &state->flags);
 		else
 			__clear_bit(FF_EFFECT_STARTED, &state->flags);
-
-		ml_play_effects(ml);
 	}
 
+	ml_play_effects(ml);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/input.c linux-libre-2.6.33-gnu1/drivers/input/input.c
--- linux-libre-2.6.32-gnu1/drivers/input/input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/input.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include <linux/smp_lock.h>
+#include "input-compat.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input core");
@@ -45,6 +46,7 @@ static unsigned int input_abs_bypass_ini
 	ABS_MT_TOOL_TYPE,
 	ABS_MT_BLOB_ID,
 	ABS_MT_TRACKING_ID,
+	ABS_MT_PRESSURE,
 	0
 };
 static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
@@ -296,9 +298,15 @@ static void input_handle_event(struct in
  * @value: value of the event
  *
  * This function should be used by drivers implementing various input
- * devices. See also input_inject_event().
+ * devices to report input events. See also input_inject_event().
+ *
+ * NOTE: input_event() may be safely used right after input device was
+ * allocated with input_allocate_device(), even before it is registered
+ * with input_register_device(), but the event will not reach any of the
+ * input handlers. Such early invocation of input_event() may be used
+ * to 'seed' initial state of a switch or initial position of absolute
+ * axis, etc.
  */
-
 void input_event(struct input_dev *dev,
 		 unsigned int type, unsigned int code, int value)
 {
@@ -758,6 +766,40 @@ static int input_attach_handler(struct i
 	return error;
 }
 
+#ifdef CONFIG_COMPAT
+
+static int input_bits_to_string(char *buf, int buf_size,
+				unsigned long bits, bool skip_empty)
+{
+	int len = 0;
+
+	if (INPUT_COMPAT_TEST) {
+		u32 dword = bits >> 32;
+		if (dword || !skip_empty)
+			len += snprintf(buf, buf_size, "%x ", dword);
+
+		dword = bits & 0xffffffffUL;
+		if (dword || !skip_empty || len)
+			len += snprintf(buf + len, max(buf_size - len, 0),
+					"%x", dword);
+	} else {
+		if (bits || !skip_empty)
+			len += snprintf(buf, buf_size, "%lx", bits);
+	}
+
+	return len;
+}
+
+#else /* !CONFIG_COMPAT */
+
+static int input_bits_to_string(char *buf, int buf_size,
+				unsigned long bits, bool skip_empty)
+{
+	return bits || !skip_empty ?
+		snprintf(buf, buf_size, "%lx", bits) : 0;
+}
+
+#endif
 
 #ifdef CONFIG_PROC_FS
 
@@ -826,14 +868,25 @@ static void input_seq_print_bitmap(struc
 				   unsigned long *bitmap, int max)
 {
 	int i;
-
-	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
-		if (bitmap[i])
-			break;
+	bool skip_empty = true;
+	char buf[18];
 
 	seq_printf(seq, "B: %s=", name);
-	for (; i >= 0; i--)
-		seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : "");
+
+	for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) {
+		if (input_bits_to_string(buf, sizeof(buf),
+					 bitmap[i], skip_empty)) {
+			skip_empty = false;
+			seq_printf(seq, "%s%s", buf, i > 0 ? " " : "");
+		}
+	}
+
+	/*
+	 * If no output was produced print a single 0.
+	 */
+	if (skip_empty)
+		seq_puts(seq, "0");
+
 	seq_putc(seq, '\n');
 }
 
@@ -1122,14 +1175,23 @@ static int input_print_bitmap(char *buf,
 {
 	int i;
 	int len = 0;
+	bool skip_empty = true;
 
-	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
-		if (bitmap[i])
-			break;
+	for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) {
+		len += input_bits_to_string(buf + len, max(buf_size - len, 0),
+					    bitmap[i], skip_empty);
+		if (len) {
+			skip_empty = false;
+			if (i > 0)
+				len += snprintf(buf + len, max(buf_size - len, 0), " ");
+		}
+	}
 
-	for (; i >= 0; i--)
-		len += snprintf(buf + len, max(buf_size - len, 0),
-				"%lx%s", bitmap[i], i > 0 ? " " : "");
+	/*
+	 * If no output was produced print a single 0.
+	 */
+	if (len == 0)
+		len = snprintf(buf, buf_size, "%d", 0);
 
 	if (add_cr)
 		len += snprintf(buf + len, max(buf_size - len, 0), "\n");
@@ -1144,7 +1206,8 @@ static ssize_t input_dev_show_cap_##bm(s
 {									\
 	struct input_dev *input_dev = to_input_dev(dev);		\
 	int len = input_print_bitmap(buf, PAGE_SIZE,			\
-				     input_dev->bm##bit, ev##_MAX, 1);	\
+				     input_dev->bm##bit, ev##_MAX,	\
+				     true);				\
 	return min_t(int, len, PAGE_SIZE);				\
 }									\
 static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
@@ -1208,7 +1271,7 @@ static int input_add_uevent_bm_var(struc
 
 	len = input_print_bitmap(&env->buf[env->buflen - 1],
 				 sizeof(env->buf) - env->buflen,
-				 bitmap, max, 0);
+				 bitmap, max, false);
 	if (len >= (sizeof(env->buf) - env->buflen))
 		return -ENOMEM;
 
@@ -1658,6 +1721,38 @@ void input_unregister_handler(struct inp
 EXPORT_SYMBOL(input_unregister_handler);
 
 /**
+ * input_handler_for_each_handle - handle iterator
+ * @handler: input handler to iterate
+ * @data: data for the callback
+ * @fn: function to be called for each handle
+ *
+ * Iterate over @bus's list of devices, and call @fn for each, passing
+ * it @data and stop when @fn returns a non-zero value. The function is
+ * using RCU to traverse the list and therefore may be usind in atonic
+ * contexts. The @fn callback is invoked from RCU critical section and
+ * thus must not sleep.
+ */
+int input_handler_for_each_handle(struct input_handler *handler, void *data,
+				  int (*fn)(struct input_handle *, void *))
+{
+	struct input_handle *handle;
+	int retval = 0;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(handle, &handler->h_list, h_node) {
+		retval = fn(handle, data);
+		if (retval)
+			break;
+	}
+
+	rcu_read_unlock();
+
+	return retval;
+}
+EXPORT_SYMBOL(input_handler_for_each_handle);
+
+/**
  * input_register_handle - register a new input handle
  * @handle: handle to register
  *
@@ -1690,7 +1785,7 @@ int input_register_handle(struct input_h
 	 * we can't be racing with input_unregister_handle()
 	 * and so separate lock is not needed here.
 	 */
-	list_add_tail(&handle->h_node, &handler->h_list);
+	list_add_tail_rcu(&handle->h_node, &handler->h_list);
 
 	if (handler->start)
 		handler->start(handle);
@@ -1713,7 +1808,7 @@ void input_unregister_handle(struct inpu
 {
 	struct input_dev *dev = handle->dev;
 
-	list_del_init(&handle->h_node);
+	list_del_rcu(&handle->h_node);
 
 	/*
 	 * Take dev->mutex to prevent race with input_release_device().
@@ -1721,6 +1816,7 @@ void input_unregister_handle(struct inpu
 	mutex_lock(&dev->mutex);
 	list_del_rcu(&handle->d_node);
 	mutex_unlock(&dev->mutex);
+
 	synchronize_rcu();
 }
 EXPORT_SYMBOL(input_unregister_handle);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/input-polldev.c linux-libre-2.6.33-gnu1/drivers/input/input-polldev.c
--- linux-libre-2.6.32-gnu1/drivers/input/input-polldev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/input-polldev.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,14 +56,10 @@ static void input_polldev_stop_workqueue
 	mutex_unlock(&polldev_mutex);
 }
 
-static void input_polled_device_work(struct work_struct *work)
+static void input_polldev_queue_work(struct input_polled_dev *dev)
 {
-	struct input_polled_dev *dev =
-		container_of(work, struct input_polled_dev, work.work);
 	unsigned long delay;
 
-	dev->poll(dev);
-
 	delay = msecs_to_jiffies(dev->poll_interval);
 	if (delay >= HZ)
 		delay = round_jiffies_relative(delay);
@@ -71,6 +67,15 @@ static void input_polled_device_work(str
 	queue_delayed_work(polldev_wq, &dev->work, delay);
 }
 
+static void input_polled_device_work(struct work_struct *work)
+{
+	struct input_polled_dev *dev =
+		container_of(work, struct input_polled_dev, work.work);
+
+	dev->poll(dev);
+	input_polldev_queue_work(dev);
+}
+
 static int input_open_polled_device(struct input_dev *input)
 {
 	struct input_polled_dev *dev = input_get_drvdata(input);
@@ -80,11 +85,12 @@ static int input_open_polled_device(stru
 	if (error)
 		return error;
 
-	if (dev->flush)
-		dev->flush(dev);
+	if (dev->open)
+		dev->open(dev);
 
-	queue_delayed_work(polldev_wq, &dev->work,
-			   msecs_to_jiffies(dev->poll_interval));
+	/* Only start polling if polling is enabled */
+	if (dev->poll_interval > 0)
+		queue_delayed_work(polldev_wq, &dev->work, 0);
 
 	return 0;
 }
@@ -94,9 +100,95 @@ static void input_close_polled_device(st
 	struct input_polled_dev *dev = input_get_drvdata(input);
 
 	cancel_delayed_work_sync(&dev->work);
+	/*
+	 * Clean up work struct to remove references to the workqueue.
+	 * It may be destroyed by the next call. This causes problems
+	 * at next device open-close in case of poll_interval == 0.
+	 */
+	INIT_DELAYED_WORK(&dev->work, dev->work.work.func);
 	input_polldev_stop_workqueue();
+
+	if (dev->close)
+		dev->close(dev);
+}
+
+/* SYSFS interface */
+
+static ssize_t input_polldev_get_poll(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval);
 }
 
+static ssize_t input_polldev_set_poll(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+	struct input_dev *input = polldev->input;
+	unsigned long interval;
+
+	if (strict_strtoul(buf, 0, &interval))
+		return -EINVAL;
+
+	if (interval < polldev->poll_interval_min)
+		return -EINVAL;
+
+	if (interval > polldev->poll_interval_max)
+		return -EINVAL;
+
+	mutex_lock(&input->mutex);
+
+	polldev->poll_interval = interval;
+
+	if (input->users) {
+		cancel_delayed_work_sync(&polldev->work);
+		if (polldev->poll_interval > 0)
+			input_polldev_queue_work(polldev);
+	}
+
+	mutex_unlock(&input->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll,
+					    input_polldev_set_poll);
+
+
+static ssize_t input_polldev_get_max(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval_max);
+}
+
+static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL);
+
+static ssize_t input_polldev_get_min(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", polldev->poll_interval_min);
+}
+
+static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL);
+
+static struct attribute *sysfs_attrs[] = {
+	&dev_attr_poll.attr,
+	&dev_attr_max.attr,
+	&dev_attr_min.attr,
+	NULL
+};
+
+static struct attribute_group input_polldev_attribute_group = {
+	.attrs = sysfs_attrs
+};
+
 /**
  * input_allocate_polled_device - allocated memory polled device
  *
@@ -126,7 +218,7 @@ EXPORT_SYMBOL(input_allocate_polled_devi
  * @dev: device to free
  *
  * The function frees memory allocated for polling device and drops
- * reference to the associated input device (if present).
+ * reference to the associated input device.
  */
 void input_free_polled_device(struct input_polled_dev *dev)
 {
@@ -150,15 +242,38 @@ EXPORT_SYMBOL(input_free_polled_device);
 int input_register_polled_device(struct input_polled_dev *dev)
 {
 	struct input_dev *input = dev->input;
+	int error;
 
 	input_set_drvdata(input, dev);
 	INIT_DELAYED_WORK(&dev->work, input_polled_device_work);
 	if (!dev->poll_interval)
 		dev->poll_interval = 500;
+	if (!dev->poll_interval_max)
+		dev->poll_interval_max = dev->poll_interval;
 	input->open = input_open_polled_device;
 	input->close = input_close_polled_device;
 
-	return input_register_device(input);
+	error = input_register_device(input);
+	if (error)
+		return error;
+
+	error = sysfs_create_group(&input->dev.kobj,
+				   &input_polldev_attribute_group);
+	if (error) {
+		input_unregister_device(input);
+		return error;
+	}
+
+	/*
+	 * Take extra reference to the underlying input device so
+	 * that it survives call to input_unregister_polled_device()
+	 * and is deleted only after input_free_polled_device()
+	 * has been invoked. This is needed to ease task of freeing
+	 * sparse keymaps.
+	 */
+	input_get_device(input);
+
+	return 0;
 }
 EXPORT_SYMBOL(input_register_polled_device);
 
@@ -169,13 +284,13 @@ EXPORT_SYMBOL(input_register_polled_devi
  * The function unregisters previously registered polled input
  * device from input layer. Polling is stopped and device is
  * ready to be freed with call to input_free_polled_device().
- * Callers should not attempt to access dev->input pointer
- * after calling this function.
  */
 void input_unregister_polled_device(struct input_polled_dev *dev)
 {
+	sysfs_remove_group(&dev->input->dev.kobj,
+			   &input_polldev_attribute_group);
+
 	input_unregister_device(dev->input);
-	dev->input = NULL;
 }
 EXPORT_SYMBOL(input_unregister_polled_device);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/joystick/gf2k.c linux-libre-2.6.33-gnu1/drivers/input/joystick/gf2k.c
--- linux-libre-2.6.32-gnu1/drivers/input/joystick/gf2k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/joystick/gf2k.c	2010-02-24 13:52:17.000000000 -0500
@@ -277,7 +277,7 @@ static int gf2k_connect(struct gameport
 	}
 
 #ifdef RESET_WORKS
-	if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) ||
+	if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) &&
 	    (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) {
 		err = -ENODEV;
 		goto fail2;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce.h linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce.h
--- linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce.h	2010-02-24 13:52:17.000000000 -0500
@@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *i
 
 /* iforce-usb.c */
 void iforce_usb_xmit(struct iforce *iforce);
-void iforce_usb_delete(struct iforce *iforce);
 
 /* iforce-main.c */
 int iforce_init_device(struct iforce *iforce);
-void iforce_delete_device(struct iforce *iforce);
 
 /* iforce-packets.c */
 int iforce_control_playback(struct iforce*, u16 id, unsigned int);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce-main.c linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-main.c
--- linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce-main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-main.c	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,7 @@ static int iforce_open(struct input_dev
 	return 0;
 }
 
-static void iforce_release(struct input_dev *dev)
+static void iforce_close(struct input_dev *dev)
 {
 	struct iforce *iforce = input_get_drvdata(dev);
 	int i;
@@ -228,30 +228,17 @@ static void iforce_release(struct input_
 
 		/* Disable force feedback playback */
 		iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
+		/* Wait for the command to complete */
+		wait_event_interruptible(iforce->wait,
+			!test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags));
 	}
 
 	switch (iforce->bus) {
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
-		case IFORCE_USB:
-			usb_kill_urb(iforce->irq);
-
-			/* The device was unplugged before the file
-			 * was released */
-			if (iforce->usbdev == NULL) {
-				iforce_delete_device(iforce);
-				kfree(iforce);
-			}
-		break;
-#endif
-	}
-}
-
-void iforce_delete_device(struct iforce *iforce)
-{
-	switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
 	case IFORCE_USB:
-		iforce_usb_delete(iforce);
+		usb_kill_urb(iforce->irq);
+		usb_kill_urb(iforce->out);
+		usb_kill_urb(iforce->ctrl);
 		break;
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
@@ -303,7 +290,7 @@ int iforce_init_device(struct iforce *if
 
 	input_dev->name = "Unknown I-Force device";
 	input_dev->open = iforce_open;
-	input_dev->close = iforce_release;
+	input_dev->close = iforce_close;
 
 /*
  * On-device memory allocation.
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce-usb.c linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-usb.c
--- linux-libre-2.6.32-gnu1/drivers/input/joystick/iforce/iforce-usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/joystick/iforce/iforce-usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,6 +109,7 @@ static void iforce_usb_out(struct urb *u
 	struct iforce *iforce = urb->context;
 
 	if (urb->status) {
+		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
 		dbg("urb->status %d, exiting", urb->status);
 		return;
 	}
@@ -186,33 +187,19 @@ fail:
 	return err;
 }
 
-/* Called by iforce_delete() */
-void iforce_usb_delete(struct iforce* iforce)
-{
-	usb_kill_urb(iforce->irq);
-	usb_kill_urb(iforce->out);
-	usb_kill_urb(iforce->ctrl);
-
-	usb_free_urb(iforce->irq);
-	usb_free_urb(iforce->out);
-	usb_free_urb(iforce->ctrl);
-}
-
 static void iforce_usb_disconnect(struct usb_interface *intf)
 {
 	struct iforce *iforce = usb_get_intfdata(intf);
-	int open = 0; /* FIXME! iforce->dev.handle->open; */
 
 	usb_set_intfdata(intf, NULL);
-	if (iforce) {
-		iforce->usbdev = NULL;
-		input_unregister_device(iforce->dev);
 
-		if (!open) {
-			iforce_delete_device(iforce);
-			kfree(iforce);
-		}
-	}
+	input_unregister_device(iforce->dev);
+
+	usb_free_urb(iforce->irq);
+	usb_free_urb(iforce->out);
+	usb_free_urb(iforce->ctrl);
+
+	kfree(iforce);
 }
 
 static struct usb_device_id iforce_usb_ids [] = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/joystick/xpad.c linux-libre-2.6.33-gnu1/drivers/input/joystick/xpad.c
--- linux-libre-2.6.32-gnu1/drivers/input/joystick/xpad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/joystick/xpad.c	2010-02-24 13:52:17.000000000 -0500
@@ -125,6 +125,7 @@ static const struct xpad_device {
 	{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX },
@@ -146,6 +147,7 @@ static const struct xpad_device {
 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
+	{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
 };
@@ -212,6 +214,7 @@ static struct usb_device_id xpad_table [
 	XPAD_XBOX360_VENDOR(0x1430),		/* RedOctane X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x146b),		/* BigBen Interactive Controllers */
 	XPAD_XBOX360_VENDOR(0x1bad),		/* Rock Band Drums */
+	XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori Controllers */
 	{ }
 };
 
@@ -443,7 +446,7 @@ static void xpad_irq_in(struct urb *urb)
 	}
 
 exit:
-	retval = usb_submit_urb (urb, GFP_ATOMIC);
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
 		     __func__, retval);
@@ -568,7 +571,7 @@ static int xpad_play_effect(struct input
 		xpad->odata[6] = 0x00;
 		xpad->odata[7] = 0x00;
 		xpad->irq_out->transfer_buffer_length = 8;
-		usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+		usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/Kconfig linux-libre-2.6.33-gnu1/drivers/input/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@ menu "Input device support"
 config INPUT
 	tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED
 	default y
-	---help---
+	help
 	  Say Y here if you have any input device (mouse, keyboard, tablet,
 	  joystick, steering wheel ...) connected to your system and want
 	  it to be available to applications. This includes standard PS/2
@@ -27,8 +27,7 @@ if INPUT
 
 config INPUT_FF_MEMLESS
 	tristate "Support for memoryless force-feedback devices"
-	default n
-	---help---
+	help
 	  Say Y here if you have memoryless force-feedback input device
 	  such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual
 	  Power 2, or similar. You will also need to enable hardware-specific
@@ -52,12 +51,25 @@ config INPUT_POLLDEV
 	  To compile this driver as a module, choose M here: the
 	  module will be called input-polldev.
 
+config INPUT_SPARSEKMAP
+	tristate "Sparse keymap support library"
+	help
+	  Say Y here if you are using a driver for an input
+	  device that uses sparse keymap. This option is only
+	  useful for out-of-tree drivers since in-tree drivers
+	  select it automatically.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sparse-keymap.
+
 comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
 	tristate "Mouse interface" if EMBEDDED
 	default y
-	---help---
+	help
 	  Say Y here if you want your mouse to be accessible as char devices
 	  13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
 	  emulated IntelliMouse Explorer PS/2 mouse. That way, all user space
@@ -73,7 +85,7 @@ config INPUT_MOUSEDEV_PSAUX
 	bool "Provide legacy /dev/psaux device"
 	default y
 	depends on INPUT_MOUSEDEV
-	---help---
+	help
 	  Say Y here if you want your mouse also be accessible as char device
 	  10:1 - /dev/psaux. The data available through /dev/psaux is exactly
 	  the same as the data from /dev/input/mice.
@@ -103,7 +115,7 @@ config INPUT_MOUSEDEV_SCREEN_Y
 
 config INPUT_JOYDEV
 	tristate "Joystick interface"
-	---help---
+	help
 	  Say Y here if you want your joystick or gamepad to be
 	  accessible as char device 13:0+ - /dev/input/jsX device.
 
@@ -125,7 +137,7 @@ config INPUT_EVDEV
 
 config INPUT_EVBUG
 	tristate "Event debugging"
-	---help---
+	help
 	  Say Y here if you have a problem with the input subsystem and
 	  want all events (keypresses, mouse movements), to be output to
 	  the system log. While this is useful for debugging, it's also
@@ -140,7 +152,7 @@ config INPUT_EVBUG
 config INPUT_APMPOWER
 	tristate "Input Power Event -> APM Bridge" if EMBEDDED
 	depends on INPUT && APM_EMULATION
-	---help---
+	help
 	  Say Y here if you want suspend key events to trigger a user
 	  requested suspend through APM. This is useful on embedded
 	  systems where such behaviour is desired without userspace
@@ -153,6 +165,7 @@ config XEN_KBDDEV_FRONTEND
 	tristate "Xen virtual keyboard and mouse support"
 	depends on XEN_FBDEV_FRONTEND
 	default y
+	select XEN_XENBUS_FRONTEND
 	help
 	  This driver implements the front-end of the Xen virtual
 	  keyboard and mouse device driver.  It communicates with a back-end
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/adp5520-keys.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5520-keys.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/adp5520-keys.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5520-keys.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,220 @@
+/*
+ * Keypad driver for Analog Devices ADP5520 MFD PMICs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/mfd/adp5520.h>
+
+struct adp5520_keys {
+	struct input_dev *input;
+	struct notifier_block notifier;
+	struct device *master;
+	unsigned short keycode[ADP5520_KEYMAPSIZE];
+};
+
+static void adp5520_keys_report_event(struct adp5520_keys *dev,
+					unsigned short keymask, int value)
+{
+	int i;
+
+	for (i = 0; i < ADP5520_MAXKEYS; i++)
+		if (keymask & (1 << i))
+			input_report_key(dev->input, dev->keycode[i], value);
+
+	input_sync(dev->input);
+}
+
+static int adp5520_keys_notifier(struct notifier_block *nb,
+				 unsigned long event, void *data)
+{
+	struct adp5520_keys *dev;
+	uint8_t reg_val_lo, reg_val_hi;
+	unsigned short keymask;
+
+	dev = container_of(nb, struct adp5520_keys, notifier);
+
+	if (event & ADP5520_KP_INT) {
+		adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, &reg_val_lo);
+		adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, &reg_val_hi);
+
+		keymask = (reg_val_hi << 8) | reg_val_lo;
+		/* Read twice to clear */
+		adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, &reg_val_lo);
+		adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, &reg_val_hi);
+		keymask |= (reg_val_hi << 8) | reg_val_lo;
+		adp5520_keys_report_event(dev, keymask, 1);
+	}
+
+	if (event & ADP5520_KR_INT) {
+		adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, &reg_val_lo);
+		adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, &reg_val_hi);
+
+		keymask = (reg_val_hi << 8) | reg_val_lo;
+		/* Read twice to clear */
+		adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, &reg_val_lo);
+		adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, &reg_val_hi);
+		keymask |= (reg_val_hi << 8) | reg_val_lo;
+		adp5520_keys_report_event(dev, keymask, 0);
+	}
+
+	return 0;
+}
+
+static int __devinit adp5520_keys_probe(struct platform_device *pdev)
+{
+	struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data;
+	struct input_dev *input;
+	struct adp5520_keys *dev;
+	int ret, i;
+	unsigned char en_mask, ctl_mask = 0;
+
+	if (pdev->id != ID_ADP5520) {
+		dev_err(&pdev->dev, "only ADP5520 supports Keypad\n");
+		return -EINVAL;
+	}
+
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "missing platform data\n");
+		return -EINVAL;
+	}
+
+	if (!(pdata->rows_en_mask && pdata->cols_en_mask))
+		return -EINVAL;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&pdev->dev, "failed to alloc memory\n");
+		return -ENOMEM;
+	}
+
+	input = input_allocate_device();
+	if (!input) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	dev->master = pdev->dev.parent;
+	dev->input = input;
+
+	input->name = pdev->name;
+	input->phys = "adp5520-keys/input0";
+	input->dev.parent = &pdev->dev;
+
+	input_set_drvdata(input, dev);
+
+	input->id.bustype = BUS_I2C;
+	input->id.vendor = 0x0001;
+	input->id.product = 0x5520;
+	input->id.version = 0x0001;
+
+	input->keycodesize = sizeof(dev->keycode[0]);
+	input->keycodemax = pdata->keymapsize;
+	input->keycode = dev->keycode;
+
+	memcpy(dev->keycode, pdata->keymap,
+		pdata->keymapsize * input->keycodesize);
+
+	/* setup input device */
+	__set_bit(EV_KEY, input->evbit);
+
+	if (pdata->repeat)
+		__set_bit(EV_REP, input->evbit);
+
+	for (i = 0; i < input->keycodemax; i++)
+		__set_bit(dev->keycode[i], input->keybit);
+	__clear_bit(KEY_RESERVED, input->keybit);
+
+	ret = input_register_device(input);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register input device\n");
+		goto err;
+	}
+
+	en_mask = pdata->rows_en_mask | pdata->cols_en_mask;
+
+	ret = adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_1, en_mask);
+
+	if (en_mask & ADP5520_COL_C3)
+		ctl_mask |= ADP5520_C3_MODE;
+
+	if (en_mask & ADP5520_ROW_R3)
+		ctl_mask |= ADP5520_R3_MODE;
+
+	if (ctl_mask)
+		ret |= adp5520_set_bits(dev->master, ADP5520_LED_CONTROL,
+			ctl_mask);
+
+	ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP,
+		pdata->rows_en_mask);
+
+	if (ret) {
+		dev_err(&pdev->dev, "failed to write\n");
+		ret = -EIO;
+		goto err1;
+	}
+
+	dev->notifier.notifier_call = adp5520_keys_notifier;
+	ret = adp5520_register_notifier(dev->master, &dev->notifier,
+			ADP5520_KP_IEN | ADP5520_KR_IEN);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register notifier\n");
+		goto err1;
+	}
+
+	platform_set_drvdata(pdev, dev);
+	return 0;
+
+err1:
+	input_unregister_device(input);
+	input = NULL;
+err:
+	input_free_device(input);
+	kfree(dev);
+	return ret;
+}
+
+static int __devexit adp5520_keys_remove(struct platform_device *pdev)
+{
+	struct adp5520_keys *dev = platform_get_drvdata(pdev);
+
+	adp5520_unregister_notifier(dev->master, &dev->notifier,
+				ADP5520_KP_IEN | ADP5520_KR_IEN);
+
+	input_unregister_device(dev->input);
+	kfree(dev);
+	return 0;
+}
+
+static struct platform_driver adp5520_keys_driver = {
+	.driver	= {
+		.name	= "adp5520-keys",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= adp5520_keys_probe,
+	.remove		= __devexit_p(adp5520_keys_remove),
+};
+
+static int __init adp5520_keys_init(void)
+{
+	return platform_driver_register(&adp5520_keys_driver);
+}
+module_init(adp5520_keys_init);
+
+static void __exit adp5520_keys_exit(void)
+{
+	platform_driver_unregister(&adp5520_keys_driver);
+}
+module_exit(adp5520_keys_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Keys ADP5520 Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:adp5520-keys");
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/adp5588-keys.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5588-keys.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/adp5588-keys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/adp5588-keys.c	2010-02-24 13:52:17.000000000 -0500
@@ -319,7 +319,7 @@ static int adp5588_resume(struct device
 	return 0;
 }
 
-static struct dev_pm_ops adp5588_dev_pm_ops = {
+static const struct dev_pm_ops adp5588_dev_pm_ops = {
 	.suspend = adp5588_suspend,
 	.resume  = adp5588_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/atkbd.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/atkbd.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/atkbd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/atkbd.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,7 +134,8 @@ static const unsigned short atkbd_unxlat
 #define ATKBD_CMD_GETID		0x02f2
 #define ATKBD_CMD_SETREP	0x10f3
 #define ATKBD_CMD_ENABLE	0x00f4
-#define ATKBD_CMD_RESET_DIS	0x00f5
+#define ATKBD_CMD_RESET_DIS	0x00f5	/* Reset to defaults and disable */
+#define ATKBD_CMD_RESET_DEF	0x00f6	/* Reset to defaults */
 #define ATKBD_CMD_SETALL_MBR	0x00fa
 #define ATKBD_CMD_RESET_BAT	0x02ff
 #define ATKBD_CMD_RESEND	0x00fe
@@ -224,8 +225,10 @@ struct atkbd {
 
 	struct delayed_work event_work;
 	unsigned long event_jiffies;
-	struct mutex event_mutex;
 	unsigned long event_mask;
+
+	/* Serializes reconnect(), attr->set() and event work */
+	struct mutex mutex;
 };
 
 /*
@@ -576,7 +579,7 @@ static void atkbd_event_work(struct work
 {
 	struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work);
 
-	mutex_lock(&atkbd->event_mutex);
+	mutex_lock(&atkbd->mutex);
 
 	if (!atkbd->enabled) {
 		/*
@@ -595,7 +598,7 @@ static void atkbd_event_work(struct work
 			atkbd_set_repeat_rate(atkbd);
 	}
 
-	mutex_unlock(&atkbd->event_mutex);
+	mutex_unlock(&atkbd->mutex);
 }
 
 /*
@@ -611,7 +614,7 @@ static void atkbd_schedule_event_work(st
 
 	atkbd->event_jiffies = jiffies;
 	set_bit(event_bit, &atkbd->event_mask);
-	wmb();
+	mb();
 	schedule_delayed_work(&atkbd->event_work, delay);
 }
 
@@ -836,7 +839,7 @@ static void atkbd_cleanup(struct serio *
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 
 	atkbd_disable(atkbd);
-	ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT);
+	ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF);
 }
 
 
@@ -848,13 +851,20 @@ static void atkbd_disconnect(struct seri
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 
+	sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
+
 	atkbd_disable(atkbd);
 
-	/* make sure we don't have a command in flight */
+	input_unregister_device(atkbd->dev);
+
+	/*
+	 * Make sure we don't have a command in flight.
+	 * Note that since atkbd->enabled is false event work will keep
+	 * rescheduling itself until it gets canceled and will not try
+	 * accessing freed input device or serio port.
+	 */
 	cancel_delayed_work_sync(&atkbd->event_work);
 
-	sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
-	input_unregister_device(atkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(atkbd);
@@ -1086,7 +1096,7 @@ static int atkbd_connect(struct serio *s
 	atkbd->dev = dev;
 	ps2_init(&atkbd->ps2dev, serio);
 	INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work);
-	mutex_init(&atkbd->event_mutex);
+	mutex_init(&atkbd->mutex);
 
 	switch (serio->id.type) {
 
@@ -1159,19 +1169,23 @@ static int atkbd_reconnect(struct serio
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 	struct serio_driver *drv = serio->drv;
+	int retval = -1;
 
 	if (!atkbd || !drv) {
 		printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
 
+	mutex_lock(&atkbd->mutex);
+
 	atkbd_disable(atkbd);
 
 	if (atkbd->write) {
 		if (atkbd_probe(atkbd))
-			return -1;
+			goto out;
+
 		if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
-			return -1;
+			goto out;
 
 		atkbd_activate(atkbd);
 
@@ -1189,8 +1203,11 @@ static int atkbd_reconnect(struct serio
 	}
 
 	atkbd_enable(atkbd);
+	retval = 0;
 
-	return 0;
+ out:
+	mutex_unlock(&atkbd->mutex);
+	return retval;
 }
 
 static struct serio_device_id atkbd_serio_ids[] = {
@@ -1234,47 +1251,28 @@ static ssize_t atkbd_attr_show_helper(st
 				ssize_t (*handler)(struct atkbd *, char *))
 {
 	struct serio *serio = to_serio_port(dev);
-	int retval;
-
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &atkbd_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	retval = handler((struct atkbd *)serio_get_drvdata(serio), buf);
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 
-out:
-	serio_unpin_driver(serio);
-	return retval;
+	return handler(atkbd, buf);
 }
 
 static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
 				ssize_t (*handler)(struct atkbd *, const char *, size_t))
 {
 	struct serio *serio = to_serio_port(dev);
-	struct atkbd *atkbd;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 	int retval;
 
-	retval = serio_pin_driver(serio);
+	retval = mutex_lock_interruptible(&atkbd->mutex);
 	if (retval)
 		return retval;
 
-	if (serio->drv != &atkbd_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	atkbd = serio_get_drvdata(serio);
 	atkbd_disable(atkbd);
 	retval = handler(atkbd, buf, count);
 	atkbd_enable(atkbd);
 
-out:
-	serio_unpin_driver(serio);
+	mutex_unlock(&atkbd->mutex);
+
 	return retval;
 }
 
@@ -1567,9 +1565,8 @@ static int __init atkbd_setup_scancode_f
 	return 0;
 }
 
-static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
 	{
-		.ident = "Dell Laptop",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
@@ -1578,7 +1575,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
-		.ident = "Dell Laptop",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
@@ -1587,7 +1583,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
-		.ident = "HP 2133",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
@@ -1596,7 +1591,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_hp_forced_release_keys,
 	},
 	{
-		.ident = "HP Pavilion ZV6100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
@@ -1605,7 +1599,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
@@ -1614,7 +1607,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
@@ -1623,7 +1615,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "HP Presario R4200",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
@@ -1632,7 +1623,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Inventec Symphony",
+		/* Inventec Symphony */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
@@ -1641,7 +1632,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Samsung NC10",
+		/* Samsung NC10 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
@@ -1650,7 +1641,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Samsung NC20",
+		/* Samsung NC20 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC20"),
@@ -1659,7 +1650,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Samsung SQ45S70S",
+		/* Samsung SQ45S70S */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
@@ -1668,7 +1659,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_samsung_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo PA 1510",
+		/* Fujitsu Amilo PA 1510 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
@@ -1677,7 +1668,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_volume_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo Pi 3525",
+		/* Fujitsu Amilo Pi 3525 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"),
@@ -1686,7 +1677,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_amilo_pi3525_forced_release_keys,
 	},
 	{
-		.ident = "Fujitsu Amilo Xi 3650",
+		/* Fujitsu Amilo Xi 3650 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"),
@@ -1695,7 +1686,6 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkbd_amilo_xi3650_forced_release_keys,
 	},
 	{
-		.ident = "Soltech Corporation TA12",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TA12"),
@@ -1704,7 +1694,7 @@ static struct dmi_system_id atkbd_dmi_qu
 		.driver_data = atkdb_soltech_ta12_forced_release_keys,
 	},
 	{
-		.ident = "OQO Model 01+",
+		/* OQO Model 01+ */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/davinci_keyscan.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/davinci_keyscan.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/davinci_keyscan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/davinci_keyscan.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,345 @@
+/*
+ * DaVinci Key Scan Driver for TI platforms
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
+ *
+ * Intial Code: Sandeep Paulraj <s-paulraj@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/keyscan.h>
+
+/* Key scan registers */
+#define DAVINCI_KEYSCAN_KEYCTRL		0x0000
+#define DAVINCI_KEYSCAN_INTENA		0x0004
+#define DAVINCI_KEYSCAN_INTFLAG		0x0008
+#define DAVINCI_KEYSCAN_INTCLR		0x000c
+#define DAVINCI_KEYSCAN_STRBWIDTH	0x0010
+#define DAVINCI_KEYSCAN_INTERVAL	0x0014
+#define DAVINCI_KEYSCAN_CONTTIME	0x0018
+#define DAVINCI_KEYSCAN_CURRENTST	0x001c
+#define DAVINCI_KEYSCAN_PREVSTATE	0x0020
+#define DAVINCI_KEYSCAN_EMUCTRL		0x0024
+#define DAVINCI_KEYSCAN_IODFTCTRL	0x002c
+
+/* Key Control Register (KEYCTRL) */
+#define DAVINCI_KEYSCAN_KEYEN		0x00000001
+#define DAVINCI_KEYSCAN_PREVMODE	0x00000002
+#define DAVINCI_KEYSCAN_CHATOFF		0x00000004
+#define DAVINCI_KEYSCAN_AUTODET		0x00000008
+#define DAVINCI_KEYSCAN_SCANMODE	0x00000010
+#define DAVINCI_KEYSCAN_OUTTYPE		0x00000020
+
+/* Masks for the interrupts */
+#define DAVINCI_KEYSCAN_INT_CONT	0x00000008
+#define DAVINCI_KEYSCAN_INT_OFF		0x00000004
+#define DAVINCI_KEYSCAN_INT_ON		0x00000002
+#define DAVINCI_KEYSCAN_INT_CHANGE	0x00000001
+#define DAVINCI_KEYSCAN_INT_ALL		0x0000000f
+
+struct davinci_ks {
+	struct input_dev		*input;
+	struct davinci_ks_platform_data	*pdata;
+	int				irq;
+	void __iomem			*base;
+	resource_size_t			pbase;
+	size_t				base_size;
+	unsigned short			keymap[];
+};
+
+/* Initializing the kp Module */
+static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks)
+{
+	struct device *dev = &davinci_ks->input->dev;
+	struct davinci_ks_platform_data *pdata = davinci_ks->pdata;
+	u32 matrix_ctrl;
+
+	/* Enable all interrupts */
+	__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	/* Clear interrupts if any */
+	__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTCLR);
+
+	/* Setup the scan period = strobe + interval */
+	__raw_writel(pdata->strobe,
+		     davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH);
+	__raw_writel(pdata->interval,
+		     davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL);
+	__raw_writel(0x01,
+		     davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME);
+
+	/* Define matrix type */
+	switch (pdata->matrix_type) {
+	case DAVINCI_KEYSCAN_MATRIX_4X4:
+		matrix_ctrl = 0;
+		break;
+	case DAVINCI_KEYSCAN_MATRIX_5X3:
+		matrix_ctrl = (1 << 6);
+		break;
+	default:
+		dev_err(dev->parent, "wrong matrix type\n");
+		return -EINVAL;
+	}
+
+	/* Enable key scan module and set matrix type */
+	__raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN |
+		     matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL);
+
+	return 0;
+}
+
+static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id)
+{
+	struct davinci_ks *davinci_ks = dev_id;
+	struct device *dev = &davinci_ks->input->dev;
+	unsigned short *keymap = davinci_ks->keymap;
+	int keymapsize = davinci_ks->pdata->keymapsize;
+	u32 prev_status, new_status, changed;
+	bool release;
+	int keycode = KEY_UNKNOWN;
+	int i;
+
+	/* Disable interrupt */
+	__raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	/* Reading previous and new status of the key scan */
+	prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE);
+	new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST);
+
+	changed = prev_status ^ new_status;
+
+	if (changed) {
+		/*
+		 * It goes through all bits in 'changed' to ensure
+		 * that no key changes are being missed
+		 */
+		for (i = 0 ; i < keymapsize; i++) {
+			if ((changed>>i) & 0x1) {
+				keycode = keymap[i];
+				release = (new_status >> i) & 0x1;
+				dev_dbg(dev->parent, "key %d %s\n", keycode,
+					release ? "released" : "pressed");
+				input_report_key(davinci_ks->input, keycode,
+						 !release);
+				input_sync(davinci_ks->input);
+			}
+		}
+		/* Clearing interrupt */
+		__raw_writel(DAVINCI_KEYSCAN_INT_ALL,
+			     davinci_ks->base + DAVINCI_KEYSCAN_INTCLR);
+	}
+
+	/* Enable interrupts */
+	__raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA);
+
+	return IRQ_HANDLED;
+}
+
+static int __init davinci_ks_probe(struct platform_device *pdev)
+{
+	struct davinci_ks *davinci_ks;
+	struct input_dev *key_dev;
+	struct resource *res, *mem;
+	struct device *dev = &pdev->dev;
+	struct davinci_ks_platform_data *pdata = pdev->dev.platform_data;
+	int error, i;
+
+	if (pdata->device_enable) {
+		error = pdata->device_enable(dev);
+		if (error < 0) {
+			dev_dbg(dev, "device enable function failed\n");
+			return error;
+		}
+	}
+
+	if (!pdata->keymap) {
+		dev_dbg(dev, "no keymap from pdata\n");
+		return -EINVAL;
+	}
+
+	davinci_ks = kzalloc(sizeof(struct davinci_ks) +
+		sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL);
+	if (!davinci_ks) {
+		dev_dbg(dev, "could not allocate memory for private data\n");
+		return -ENOMEM;
+	}
+
+	memcpy(davinci_ks->keymap, pdata->keymap,
+		sizeof(unsigned short) * pdata->keymapsize);
+
+	key_dev = input_allocate_device();
+	if (!key_dev) {
+		dev_dbg(dev, "could not allocate input device\n");
+		error = -ENOMEM;
+		goto fail1;
+	}
+
+	davinci_ks->input = key_dev;
+
+	davinci_ks->irq = platform_get_irq(pdev, 0);
+	if (davinci_ks->irq < 0) {
+		dev_err(dev, "no key scan irq\n");
+		error = davinci_ks->irq;
+		goto fail2;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "no mem resource\n");
+		error = -EINVAL;
+		goto fail2;
+	}
+
+	davinci_ks->pbase = res->start;
+	davinci_ks->base_size = resource_size(res);
+
+	mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size,
+				 pdev->name);
+	if (!mem) {
+		dev_err(dev, "key scan registers at %08x are not free\n",
+			davinci_ks->pbase);
+		error = -EBUSY;
+		goto fail2;
+	}
+
+	davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size);
+	if (!davinci_ks->base) {
+		dev_err(dev, "can't ioremap MEM resource.\n");
+		error = -ENOMEM;
+		goto fail3;
+	}
+
+	/* Enable auto repeat feature of Linux input subsystem */
+	if (pdata->rep)
+		__set_bit(EV_REP, key_dev->evbit);
+
+	/* Setup input device */
+	__set_bit(EV_KEY, key_dev->evbit);
+
+	/* Setup the platform data */
+	davinci_ks->pdata = pdata;
+
+	for (i = 0; i < davinci_ks->pdata->keymapsize; i++)
+		__set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit);
+
+	key_dev->name = "davinci_keyscan";
+	key_dev->phys = "davinci_keyscan/input0";
+	key_dev->dev.parent = &pdev->dev;
+	key_dev->id.bustype = BUS_HOST;
+	key_dev->id.vendor = 0x0001;
+	key_dev->id.product = 0x0001;
+	key_dev->id.version = 0x0001;
+	key_dev->keycode = davinci_ks->keymap;
+	key_dev->keycodesize = sizeof(davinci_ks->keymap[0]);
+	key_dev->keycodemax = davinci_ks->pdata->keymapsize;
+
+	error = input_register_device(davinci_ks->input);
+	if (error < 0) {
+		dev_err(dev, "unable to register davinci key scan device\n");
+		goto fail4;
+	}
+
+	error = request_irq(davinci_ks->irq, davinci_ks_interrupt,
+			  IRQF_DISABLED, pdev->name, davinci_ks);
+	if (error < 0) {
+		dev_err(dev, "unable to register davinci key scan interrupt\n");
+		goto fail5;
+	}
+
+	error = davinci_ks_initialize(davinci_ks);
+	if (error < 0) {
+		dev_err(dev, "unable to initialize davinci key scan device\n");
+		goto fail6;
+	}
+
+	platform_set_drvdata(pdev, davinci_ks);
+	return 0;
+
+fail6:
+	free_irq(davinci_ks->irq, davinci_ks);
+fail5:
+	input_unregister_device(davinci_ks->input);
+	key_dev = NULL;
+fail4:
+	iounmap(davinci_ks->base);
+fail3:
+	release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
+fail2:
+	input_free_device(key_dev);
+fail1:
+	kfree(davinci_ks);
+
+	return error;
+}
+
+static int __devexit davinci_ks_remove(struct platform_device *pdev)
+{
+	struct davinci_ks *davinci_ks = platform_get_drvdata(pdev);
+
+	free_irq(davinci_ks->irq, davinci_ks);
+
+	input_unregister_device(davinci_ks->input);
+
+	iounmap(davinci_ks->base);
+	release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
+
+	platform_set_drvdata(pdev, NULL);
+
+	kfree(davinci_ks);
+
+	return 0;
+}
+
+static struct platform_driver davinci_ks_driver = {
+	.driver	= {
+		.name = "davinci_keyscan",
+		.owner = THIS_MODULE,
+	},
+	.remove	= __devexit_p(davinci_ks_remove),
+};
+
+static int __init davinci_ks_init(void)
+{
+	return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe);
+}
+module_init(davinci_ks_init);
+
+static void __exit davinci_ks_exit(void)
+{
+	platform_driver_unregister(&davinci_ks_driver);
+}
+module_exit(davinci_ks_exit);
+
+MODULE_AUTHOR("Miguel Aguilar");
+MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/ep93xx_keypad.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/ep93xx_keypad.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/ep93xx_keypad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/ep93xx_keypad.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,11 +22,11 @@
 
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/input.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/input/matrix_keypad.h>
 
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/ep93xx_keypad.h>
 
 /*
@@ -60,38 +60,37 @@
 #define KEY_REG_KEY1_MASK	(0x0000003f)
 #define KEY_REG_KEY1_SHIFT	(0)
 
-#define keypad_readl(off)	__raw_readl(keypad->mmio_base + (off))
-#define keypad_writel(v, off)	__raw_writel((v), keypad->mmio_base + (off))
-
-#define MAX_MATRIX_KEY_NUM	(MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
+#define EP93XX_MATRIX_SIZE	(EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
 
 struct ep93xx_keypad {
 	struct ep93xx_keypad_platform_data *pdata;
-
-	struct clk *clk;
 	struct input_dev *input_dev;
+	struct clk *clk;
+
 	void __iomem *mmio_base;
 
-	int irq;
-	int enabled;
+	unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE];
 
 	int key1;
 	int key2;
 
-	unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
+	int irq;
+
+	bool enabled;
 };
 
 static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
 {
 	struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
 	struct input_dev *input_dev = keypad->input_dev;
+	unsigned int *key;
 	int i;
 
-	for (i = 0; i < pdata->matrix_key_map_size; i++) {
-		unsigned int key = pdata->matrix_key_map[i];
-		int row = (key >> 28) & 0xf;
-		int col = (key >> 24) & 0xf;
-		int code = key & 0xffffff;
+	key = &pdata->matrix_key_map[0];
+	for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
+		int row = KEY_ROW(*key);
+		int col = KEY_COL(*key);
+		int code = KEY_VAL(*key);
 
 		keypad->matrix_keycodes[(row << 3) + col] = code;
 		__set_bit(code, input_dev->keybit);
@@ -102,9 +101,11 @@ static irqreturn_t ep93xx_keypad_irq_han
 {
 	struct ep93xx_keypad *keypad = dev_id;
 	struct input_dev *input_dev = keypad->input_dev;
-	unsigned int status = keypad_readl(KEY_REG);
+	unsigned int status;
 	int keycode, key1, key2;
 
+	status = __raw_readl(keypad->mmio_base + KEY_REG);
+
 	keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
 	key1 = keypad->matrix_keycodes[keycode];
 
@@ -152,7 +153,10 @@ static void ep93xx_keypad_config(struct
 	struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
 	unsigned int val = 0;
 
-	clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV);
+	if (pdata->flags & EP93XX_KEYPAD_KDIV)
+		clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV4);
+	else
+		clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV16);
 
 	if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
 		val |= KEY_INIT_DIS3KY;
@@ -167,7 +171,7 @@ static void ep93xx_keypad_config(struct
 
 	val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
 
-	keypad_writel(val, KEY_INIT);
+	__raw_writel(val, keypad->mmio_base + KEY_INIT);
 }
 
 static int ep93xx_keypad_open(struct input_dev *pdev)
@@ -177,7 +181,7 @@ static int ep93xx_keypad_open(struct inp
 	if (!keypad->enabled) {
 		ep93xx_keypad_config(keypad);
 		clk_enable(keypad->clk);
-		keypad->enabled = 1;
+		keypad->enabled = true;
 	}
 
 	return 0;
@@ -189,7 +193,7 @@ static void ep93xx_keypad_close(struct i
 
 	if (keypad->enabled) {
 		clk_disable(keypad->clk);
-		keypad->enabled = 0;
+		keypad->enabled = false;
 	}
 }
 
@@ -211,7 +215,7 @@ static int ep93xx_keypad_suspend(struct
 
 	if (keypad->enabled) {
 		clk_disable(keypad->clk);
-		keypad->enabled = 0;
+		keypad->enabled = false;
 	}
 
 	mutex_unlock(&input_dev->mutex);
@@ -236,7 +240,7 @@ static int ep93xx_keypad_resume(struct p
 		if (!keypad->enabled) {
 			ep93xx_keypad_config(keypad);
 			clk_enable(keypad->clk);
-			keypad->enabled = 1;
+			keypad->enabled = true;
 		}
 	}
 
@@ -252,88 +256,56 @@ static int ep93xx_keypad_resume(struct p
 static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
 {
 	struct ep93xx_keypad *keypad;
-	struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data;
 	struct input_dev *input_dev;
 	struct resource *res;
-	int irq, err, i, gpio;
-
-	if (!pdata ||
-	    !pdata->matrix_key_rows ||
-	    pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS ||
-	    !pdata->matrix_key_cols ||
-	    pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) {
-		dev_err(&pdev->dev, "invalid or missing platform data\n");
-		return -EINVAL;
-	}
+	int err;
 
 	keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL);
-	if (!keypad) {
-		dev_err(&pdev->dev, "failed to allocate driver data\n");
+	if (!keypad)
 		return -ENOMEM;
-	}
 
-	keypad->pdata = pdata;
+	keypad->pdata = pdev->dev.platform_data;
+	if (!keypad->pdata) {
+		err = -EINVAL;
+		goto failed_free;
+	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "failed to get keypad irq\n");
+	keypad->irq = platform_get_irq(pdev, 0);
+	if (!keypad->irq) {
 		err = -ENXIO;
 		goto failed_free;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(&pdev->dev, "failed to get I/O memory\n");
 		err = -ENXIO;
 		goto failed_free;
 	}
 
 	res = request_mem_region(res->start, resource_size(res), pdev->name);
 	if (!res) {
-		dev_err(&pdev->dev, "failed to request I/O memory\n");
 		err = -EBUSY;
 		goto failed_free;
 	}
 
 	keypad->mmio_base = ioremap(res->start, resource_size(res));
 	if (keypad->mmio_base == NULL) {
-		dev_err(&pdev->dev, "failed to remap I/O memory\n");
 		err = -ENXIO;
 		goto failed_free_mem;
 	}
 
-	/* Request the needed GPIO's */
-	gpio = EP93XX_GPIO_LINE_ROW0;
-	for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) {
-		err = gpio_request(gpio, pdev->name);
-		if (err) {
-			dev_err(&pdev->dev, "failed to request gpio-%d\n",
-				gpio);
-			goto failed_free_rows;
-		}
-	}
-
-	gpio = EP93XX_GPIO_LINE_COL0;
-	for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) {
-		err = gpio_request(gpio, pdev->name);
-		if (err) {
-			dev_err(&pdev->dev, "failed to request gpio-%d\n",
-				gpio);
-			goto failed_free_cols;
-		}
-	}
+	err = ep93xx_keypad_acquire_gpio(pdev);
+	if (err)
+		goto failed_free_io;
 
-	keypad->clk = clk_get(&pdev->dev, "key_clk");
+	keypad->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(keypad->clk)) {
-		dev_err(&pdev->dev, "failed to get keypad clock\n");
 		err = PTR_ERR(keypad->clk);
-		goto failed_free_io;
+		goto failed_free_gpio;
 	}
 
-	/* Create and register the input driver */
 	input_dev = input_allocate_device();
 	if (!input_dev) {
-		dev_err(&pdev->dev, "failed to allocate input device\n");
 		err = -ENOMEM;
 		goto failed_put_clk;
 	}
@@ -358,44 +330,29 @@ static int __devinit ep93xx_keypad_probe
 	ep93xx_keypad_build_keycode(keypad);
 	platform_set_drvdata(pdev, keypad);
 
-	err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED,
-				pdev->name, keypad);
-	if (err) {
-		dev_err(&pdev->dev, "failed to request IRQ\n");
+	err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
+			  IRQF_DISABLED, pdev->name, keypad);
+	if (err)
 		goto failed_free_dev;
-	}
 
-	keypad->irq = irq;
-
-	/* Register the input device */
 	err = input_register_device(input_dev);
-	if (err) {
-		dev_err(&pdev->dev, "failed to register input device\n");
+	if (err)
 		goto failed_free_irq;
-	}
 
 	device_init_wakeup(&pdev->dev, 1);
 
 	return 0;
 
 failed_free_irq:
-	free_irq(irq, pdev);
+	free_irq(keypad->irq, pdev);
 	platform_set_drvdata(pdev, NULL);
 failed_free_dev:
 	input_free_device(input_dev);
 failed_put_clk:
 	clk_put(keypad->clk);
+failed_free_gpio:
+	ep93xx_keypad_release_gpio(pdev);
 failed_free_io:
-	i = keypad->pdata->matrix_key_cols - 1;
-	gpio = EP93XX_GPIO_LINE_COL0 + i;
-failed_free_cols:
-	for ( ; i >= 0; i--, gpio--)
-		gpio_free(gpio);
-	i = keypad->pdata->matrix_key_rows - 1;
-	gpio = EP93XX_GPIO_LINE_ROW0 + i;
-failed_free_rows:
-	for ( ; i >= 0; i--, gpio--)
-		gpio_free(gpio);
 	iounmap(keypad->mmio_base);
 failed_free_mem:
 	release_mem_region(res->start, resource_size(res));
@@ -408,7 +365,6 @@ static int __devexit ep93xx_keypad_remov
 {
 	struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
 	struct resource *res;
-	int i, gpio;
 
 	free_irq(keypad->irq, pdev);
 
@@ -420,15 +376,7 @@ static int __devexit ep93xx_keypad_remov
 
 	input_unregister_device(keypad->input_dev);
 
-	i = keypad->pdata->matrix_key_cols - 1;
-	gpio = EP93XX_GPIO_LINE_COL0 + i;
-	for ( ; i >= 0; i--, gpio--)
-		gpio_free(gpio);
-
-	i = keypad->pdata->matrix_key_rows - 1;
-	gpio = EP93XX_GPIO_LINE_ROW0 + i;
-	for ( ; i >= 0; i--, gpio--)
-		gpio_free(gpio);
+	ep93xx_keypad_release_gpio(pdev);
 
 	iounmap(keypad->mmio_base);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/gpio_keys.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/gpio_keys.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/gpio_keys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/gpio_keys.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,8 +23,7 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/workqueue.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 
 struct gpio_button_data {
 	struct gpio_keys_button *button;
@@ -38,10 +37,8 @@ struct gpio_keys_drvdata {
 	struct gpio_button_data data[0];
 };
 
-static void gpio_keys_report_event(struct work_struct *work)
+static void gpio_keys_report_event(struct gpio_button_data *bdata)
 {
-	struct gpio_button_data *bdata =
-		container_of(work, struct gpio_button_data, work);
 	struct gpio_keys_button *button = bdata->button;
 	struct input_dev *input = bdata->input;
 	unsigned int type = button->type ?: EV_KEY;
@@ -51,6 +48,14 @@ static void gpio_keys_report_event(struc
 	input_sync(input);
 }
 
+static void gpio_keys_work_func(struct work_struct *work)
+{
+	struct gpio_button_data *bdata =
+		container_of(work, struct gpio_button_data, work);
+
+	gpio_keys_report_event(bdata);
+}
+
 static void gpio_keys_timer(unsigned long _data)
 {
 	struct gpio_button_data *data = (struct gpio_button_data *)_data;
@@ -74,10 +79,62 @@ static irqreturn_t gpio_keys_isr(int irq
 	return IRQ_HANDLED;
 }
 
+static int __devinit gpio_keys_setup_key(struct device *dev,
+					 struct gpio_button_data *bdata,
+					 struct gpio_keys_button *button)
+{
+	char *desc = button->desc ? button->desc : "gpio_keys";
+	int irq, error;
+
+	setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata);
+	INIT_WORK(&bdata->work, gpio_keys_work_func);
+
+	error = gpio_request(button->gpio, desc);
+	if (error < 0) {
+		dev_err(dev, "failed to request GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail2;
+	}
+
+	error = gpio_direction_input(button->gpio);
+	if (error < 0) {
+		dev_err(dev, "failed to configure"
+			" direction for GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail3;
+	}
+
+	irq = gpio_to_irq(button->gpio);
+	if (irq < 0) {
+		error = irq;
+		dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n",
+			button->gpio, error);
+		goto fail3;
+	}
+
+	error = request_irq(irq, gpio_keys_isr,
+			    IRQF_SHARED |
+			    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			    desc, bdata);
+	if (error) {
+		dev_err(dev, "Unable to claim irq %d; error %d\n",
+			irq, error);
+		goto fail3;
+	}
+
+	return 0;
+
+fail3:
+	gpio_free(button->gpio);
+fail2:
+	return error;
+}
+
 static int __devinit gpio_keys_probe(struct platform_device *pdev)
 {
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	struct gpio_keys_drvdata *ddata;
+	struct device *dev = &pdev->dev;
 	struct input_dev *input;
 	int i, error;
 	int wakeup = 0;
@@ -87,6 +144,7 @@ static int __devinit gpio_keys_probe(str
 			GFP_KERNEL);
 	input = input_allocate_device();
 	if (!ddata || !input) {
+		dev_err(dev, "failed to allocate state\n");
 		error = -ENOMEM;
 		goto fail1;
 	}
@@ -111,52 +169,14 @@ static int __devinit gpio_keys_probe(str
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
 		struct gpio_button_data *bdata = &ddata->data[i];
-		int irq;
 		unsigned int type = button->type ?: EV_KEY;
 
 		bdata->input = input;
 		bdata->button = button;
-		setup_timer(&bdata->timer,
-			    gpio_keys_timer, (unsigned long)bdata);
-		INIT_WORK(&bdata->work, gpio_keys_report_event);
-
-		error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
-		if (error < 0) {
-			pr_err("gpio-keys: failed to request GPIO %d,"
-				" error %d\n", button->gpio, error);
-			goto fail2;
-		}
-
-		error = gpio_direction_input(button->gpio);
-		if (error < 0) {
-			pr_err("gpio-keys: failed to configure input"
-				" direction for GPIO %d, error %d\n",
-				button->gpio, error);
-			gpio_free(button->gpio);
-			goto fail2;
-		}
 
-		irq = gpio_to_irq(button->gpio);
-		if (irq < 0) {
-			error = irq;
-			pr_err("gpio-keys: Unable to get irq number"
-				" for GPIO %d, error %d\n",
-				button->gpio, error);
-			gpio_free(button->gpio);
-			goto fail2;
-		}
-
-		error = request_irq(irq, gpio_keys_isr,
-				    IRQF_SHARED |
-				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				    button->desc ? button->desc : "gpio_keys",
-				    bdata);
-		if (error) {
-			pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
-				irq, error);
-			gpio_free(button->gpio);
+		error = gpio_keys_setup_key(dev, bdata, button);
+		if (error)
 			goto fail2;
-		}
 
 		if (button->wakeup)
 			wakeup = 1;
@@ -166,11 +186,16 @@ static int __devinit gpio_keys_probe(str
 
 	error = input_register_device(input);
 	if (error) {
-		pr_err("gpio-keys: Unable to register input device, "
+		dev_err(dev, "Unable to register input device, "
 			"error: %d\n", error);
 		goto fail2;
 	}
 
+	/* get current state of buttons */
+	for (i = 0; i < pdata->nbuttons; i++)
+		gpio_keys_report_event(&ddata->data[i]);
+	input_sync(input);
+
 	device_init_wakeup(&pdev->dev, wakeup);
 
 	return 0;
@@ -239,18 +264,21 @@ static int gpio_keys_suspend(struct devi
 static int gpio_keys_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 
-	if (device_may_wakeup(&pdev->dev)) {
-		for (i = 0; i < pdata->nbuttons; i++) {
-			struct gpio_keys_button *button = &pdata->buttons[i];
-			if (button->wakeup) {
-				int irq = gpio_to_irq(button->gpio);
-				disable_irq_wake(irq);
-			}
+	for (i = 0; i < pdata->nbuttons; i++) {
+
+		struct gpio_keys_button *button = &pdata->buttons[i];
+		if (button->wakeup && device_may_wakeup(&pdev->dev)) {
+			int irq = gpio_to_irq(button->gpio);
+			disable_irq_wake(irq);
 		}
+
+		gpio_keys_report_event(&ddata->data[i]);
 	}
+	input_sync(ddata->input);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/Kconfig linux-libre-2.6.33-gnu1/drivers/input/keyboard/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,16 @@ config KEYBOARD_AAED2000
 	  To compile this driver as a module, choose M here: the
 	  module will be called aaed2000_kbd.
 
+config KEYBOARD_ADP5520
+	tristate "Keypad Support for ADP5520 PMIC"
+	depends on PMIC_ADP5520
+	help
+	  This option enables support for the keypad scan matrix
+	  on Analog Devices ADP5520 PMICs.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called adp5520-keys.
+
 config KEYBOARD_ADP5588
 	tristate "ADP5588 I2C QWERTY Keypad and IO Expander"
 	depends on I2C
@@ -361,6 +371,16 @@ config KEYBOARD_SH_KEYSC
 	  To compile this driver as a module, choose M here: the
 	  module will be called sh_keysc.
 
+config KEYBOARD_DAVINCI
+	tristate "TI DaVinci Key Scan"
+	depends on ARCH_DAVINCI_DM365
+	help
+	  Say Y to enable keypad module support for the TI DaVinci
+	  platforms (DM365).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called davinci_keyscan.
+
 config KEYBOARD_OMAP
 	tristate "TI OMAP keypad support"
 	depends on (ARCH_OMAP1 || ARCH_OMAP2)
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/lkkbd.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/lkkbd.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/lkkbd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/lkkbd.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,9 +72,9 @@
 
 #define DRIVER_DESC	"LK keyboard driver"
 
-MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 /*
  * Known parameters:
@@ -85,27 +85,27 @@ MODULE_LICENSE ("GPL");
  * Please notice that there's not yet an API to set these at runtime.
  */
 static int bell_volume = 100; /* % */
-module_param (bell_volume, int, 0);
-MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%");
+module_param(bell_volume, int, 0);
+MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%");
 
 static int keyclick_volume = 100; /* % */
-module_param (keyclick_volume, int, 0);
-MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%");
+module_param(keyclick_volume, int, 0);
+MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%");
 
 static int ctrlclick_volume = 100; /* % */
-module_param (ctrlclick_volume, int, 0);
-MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
+module_param(ctrlclick_volume, int, 0);
+MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
 
 static int lk201_compose_is_alt;
-module_param (lk201_compose_is_alt, int, 0);
-MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
-		"will act as an Alt key");
+module_param(lk201_compose_is_alt, int, 0);
+MODULE_PARM_DESC(lk201_compose_is_alt,
+		 "If set non-zero, LK201' Compose key will act as an Alt key");
 
 
 
 #undef LKKBD_DEBUG
 #ifdef LKKBD_DEBUG
-#define DBG(x...) printk (x)
+#define DBG(x...) printk(x)
 #else
 #define DBG(x...) do {} while (0)
 #endif
@@ -122,7 +122,7 @@ MODULE_PARM_DESC (lk201_compose_is_alt,
 #define LK_MODE_DOWN		0x80
 #define LK_MODE_AUTODOWN	0x82
 #define LK_MODE_UPDOWN		0x86
-#define LK_CMD_SET_MODE(mode,div)	((mode) | ((div) << 3))
+#define LK_CMD_SET_MODE(mode, div)	((mode) | ((div) << 3))
 
 /* Misc commands */
 #define LK_CMD_ENABLE_KEYCLICK	0x1b
@@ -152,11 +152,8 @@ MODULE_PARM_DESC (lk201_compose_is_alt,
 
 #define LK_NUM_KEYCODES		256
 #define LK_NUM_IGNORE_BYTES	6
-typedef u_int16_t lk_keycode_t;
-
 
-
-static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
+static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = {
 	[0x56] = KEY_F1,
 	[0x57] = KEY_F2,
 	[0x58] = KEY_F3,
@@ -268,7 +265,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM
 };
 
 #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do {		\
-	if (test_bit (LED, (LK)->dev->led))			\
+	if (test_bit(LED, (LK)->dev->led))			\
 		VAR_ON |= BITS;					\
 	else							\
 		VAR_OFF |= BITS;				\
@@ -278,7 +275,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM
  * Per-keyboard data
  */
 struct lkkbd {
-	lk_keycode_t keycode[LK_NUM_KEYCODES];
+	unsigned short keycode[LK_NUM_KEYCODES];
 	int ignore_bytes;
 	unsigned char id[LK_NUM_IGNORE_BYTES];
 	struct input_dev *dev;
@@ -301,26 +298,25 @@ static struct {
 	unsigned char *name;
 } lk_response[] = {
 #define RESPONSE(x) { .value = (x), .name = #x, }
-	RESPONSE (LK_STUCK_KEY),
-	RESPONSE (LK_SELFTEST_FAILED),
-	RESPONSE (LK_ALL_KEYS_UP),
-	RESPONSE (LK_METRONOME),
-	RESPONSE (LK_OUTPUT_ERROR),
-	RESPONSE (LK_INPUT_ERROR),
-	RESPONSE (LK_KBD_LOCKED),
-	RESPONSE (LK_KBD_TEST_MODE_ACK),
-	RESPONSE (LK_PREFIX_KEY_DOWN),
-	RESPONSE (LK_MODE_CHANGE_ACK),
-	RESPONSE (LK_RESPONSE_RESERVED),
+	RESPONSE(LK_STUCK_KEY),
+	RESPONSE(LK_SELFTEST_FAILED),
+	RESPONSE(LK_ALL_KEYS_UP),
+	RESPONSE(LK_METRONOME),
+	RESPONSE(LK_OUTPUT_ERROR),
+	RESPONSE(LK_INPUT_ERROR),
+	RESPONSE(LK_KBD_LOCKED),
+	RESPONSE(LK_KBD_TEST_MODE_ACK),
+	RESPONSE(LK_PREFIX_KEY_DOWN),
+	RESPONSE(LK_MODE_CHANGE_ACK),
+	RESPONSE(LK_RESPONSE_RESERVED),
 #undef RESPONSE
 };
 
-static unsigned char *
-response_name (unsigned char value)
+static unsigned char *response_name(unsigned char value)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE (lk_response); i++)
+	for (i = 0; i < ARRAY_SIZE(lk_response); i++)
 		if (lk_response[i].value == value)
 			return lk_response[i].name;
 
@@ -331,8 +327,7 @@ response_name (unsigned char value)
 /*
  * Calculate volume parameter byte for a given volume.
  */
-static unsigned char
-volume_to_hw (int volume_percent)
+static unsigned char volume_to_hw(int volume_percent)
 {
 	unsigned char ret = 0;
 
@@ -363,8 +358,7 @@ volume_to_hw (int volume_percent)
 	return ret;
 }
 
-static void
-lkkbd_detection_done (struct lkkbd *lk)
+static void lkkbd_detection_done(struct lkkbd *lk)
 {
 	int i;
 
@@ -377,190 +371,202 @@ lkkbd_detection_done (struct lkkbd *lk)
 	 * Print keyboard name and modify Compose=Alt on user's request.
 	 */
 	switch (lk->id[4]) {
-		case 1:
-			strlcpy (lk->name, "DEC LK201 keyboard",
-				 sizeof (lk->name));
+	case 1:
+		strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name));
 
-			if (lk201_compose_is_alt)
-				lk->keycode[0xb1] = KEY_LEFTALT;
-			break;
+		if (lk201_compose_is_alt)
+			lk->keycode[0xb1] = KEY_LEFTALT;
+		break;
 
-		case 2:
-			strlcpy (lk->name, "DEC LK401 keyboard",
-				 sizeof (lk->name));
-			break;
+	case 2:
+		strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name));
+		break;
 
-		default:
-			strlcpy (lk->name, "Unknown DEC keyboard",
-				 sizeof (lk->name));
-			printk (KERN_ERR "lkkbd: keyboard on %s is unknown, "
-					"please report to Jan-Benedict Glaw "
-					"<jbglaw@lug-owl.de>\n", lk->phys);
-			printk (KERN_ERR "lkkbd: keyboard ID'ed as:");
-			for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
-				printk (" 0x%02x", lk->id[i]);
-			printk ("\n");
-			break;
+	default:
+		strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name));
+		printk(KERN_ERR
+			"lkkbd: keyboard on %s is unknown, please report to "
+			"Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys);
+		printk(KERN_ERR "lkkbd: keyboard ID'ed as:");
+		for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
+			printk(" 0x%02x", lk->id[i]);
+		printk("\n");
+		break;
 	}
-	printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
-			lk->phys, lk->name);
+
+	printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
+		lk->phys, lk->name);
 
 	/*
 	 * Report errors during keyboard boot-up.
 	 */
 	switch (lk->id[2]) {
-		case 0x00:
-			/* All okay */
-			break;
+	case 0x00:
+		/* All okay */
+		break;
 
-		case LK_STUCK_KEY:
-			printk (KERN_ERR "lkkbd: Stuck key on keyboard at "
-					"%s\n", lk->phys);
-			break;
+	case LK_STUCK_KEY:
+		printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n",
+			lk->phys);
+		break;
 
-		case LK_SELFTEST_FAILED:
-			printk (KERN_ERR "lkkbd: Selftest failed on keyboard "
-					"at %s, keyboard may not work "
-					"properly\n", lk->phys);
-			break;
+	case LK_SELFTEST_FAILED:
+		printk(KERN_ERR
+			"lkkbd: Selftest failed on keyboard at %s, "
+			"keyboard may not work properly\n", lk->phys);
+		break;
 
-		default:
-			printk (KERN_ERR "lkkbd: Unknown error %02x on "
-					"keyboard at %s\n", lk->id[2],
-					lk->phys);
-			break;
+	default:
+		printk(KERN_ERR
+			"lkkbd: Unknown error %02x on keyboard at %s\n",
+			lk->id[2], lk->phys);
+		break;
 	}
 
 	/*
 	 * Try to hint user if there's a stuck key.
 	 */
 	if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0)
-		printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode "
-				"is 0x%04x\n", lk->id[3],
-				lk->keycode[lk->id[3]]);
-
-	return;
+		printk(KERN_ERR
+			"Scancode of stuck key is 0x%02x, keycode is 0x%04x\n",
+			lk->id[3], lk->keycode[lk->id[3]]);
 }
 
 /*
  * lkkbd_interrupt() is called by the low level driver when a character
  * is received.
  */
-static irqreturn_t
-lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
+static irqreturn_t lkkbd_interrupt(struct serio *serio,
+				   unsigned char data, unsigned int flags)
 {
-	struct lkkbd *lk = serio_get_drvdata (serio);
+	struct lkkbd *lk = serio_get_drvdata(serio);
+	struct input_dev *input_dev = lk->dev;
+	unsigned int keycode;
 	int i;
 
-	DBG (KERN_INFO "Got byte 0x%02x\n", data);
+	DBG(KERN_INFO "Got byte 0x%02x\n", data);
 
 	if (lk->ignore_bytes > 0) {
-		DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
+		DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name);
 		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
 
 		if (lk->ignore_bytes == 0)
-			lkkbd_detection_done (lk);
+			lkkbd_detection_done(lk);
 
 		return IRQ_HANDLED;
 	}
 
 	switch (data) {
-		case LK_ALL_KEYS_UP:
-			for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
-				if (lk->keycode[i] != KEY_RESERVED)
-					input_report_key (lk->dev, lk->keycode[i], 0);
-			input_sync (lk->dev);
-			break;
+	case LK_ALL_KEYS_UP:
+		for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++)
+			input_report_key(input_dev, lk->keycode[i], 0);
+		input_sync(input_dev);
+		break;
 
-		case 0x01:
-			DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
-			lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
-			lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
-			schedule_work (&lk->tq);
-			break;
+	case 0x01:
+		DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n");
+		lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
+		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
+		schedule_work(&lk->tq);
+		break;
 
-		case LK_METRONOME:
-		case LK_OUTPUT_ERROR:
-		case LK_INPUT_ERROR:
-		case LK_KBD_LOCKED:
-		case LK_KBD_TEST_MODE_ACK:
-		case LK_PREFIX_KEY_DOWN:
-		case LK_MODE_CHANGE_ACK:
-		case LK_RESPONSE_RESERVED:
-			DBG (KERN_INFO "Got %s and don't know how to handle...\n",
-					response_name (data));
-			break;
+	case LK_METRONOME:
+	case LK_OUTPUT_ERROR:
+	case LK_INPUT_ERROR:
+	case LK_KBD_LOCKED:
+	case LK_KBD_TEST_MODE_ACK:
+	case LK_PREFIX_KEY_DOWN:
+	case LK_MODE_CHANGE_ACK:
+	case LK_RESPONSE_RESERVED:
+		DBG(KERN_INFO "Got %s and don't know how to handle...\n",
+			response_name(data));
+		break;
 
-		default:
-			if (lk->keycode[data] != KEY_RESERVED) {
-				if (!test_bit (lk->keycode[data], lk->dev->key))
-					input_report_key (lk->dev, lk->keycode[data], 1);
-				else
-					input_report_key (lk->dev, lk->keycode[data], 0);
-				input_sync (lk->dev);
-                        } else
-                                printk (KERN_WARNING "%s: Unknown key with "
-						"scancode 0x%02x on %s.\n",
-						__FILE__, data, lk->name);
+	default:
+		keycode = lk->keycode[data];
+		if (keycode != KEY_RESERVED) {
+			input_report_key(input_dev, keycode,
+					 !test_bit(keycode, input_dev->key));
+			input_sync(input_dev);
+		} else {
+			printk(KERN_WARNING
+				"%s: Unknown key with scancode 0x%02x on %s.\n",
+				__FILE__, data, lk->name);
+		}
 	}
 
 	return IRQ_HANDLED;
 }
 
+static void lkkbd_toggle_leds(struct lkkbd *lk)
+{
+	struct serio *serio = lk->serio;
+	unsigned char leds_on = 0;
+	unsigned char leds_off = 0;
+
+	CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
+	CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
+	CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
+	CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
+	if (leds_on != 0) {
+		serio_write(serio, LK_CMD_LED_ON);
+		serio_write(serio, leds_on);
+	}
+	if (leds_off != 0) {
+		serio_write(serio, LK_CMD_LED_OFF);
+		serio_write(serio, leds_off);
+	}
+}
+
+static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on)
+{
+	struct serio *serio = lk->serio;
+
+	if (on) {
+		DBG("%s: Activating key clicks\n", __func__);
+		serio_write(serio, LK_CMD_ENABLE_KEYCLICK);
+		serio_write(serio, volume_to_hw(lk->keyclick_volume));
+		serio_write(serio, LK_CMD_ENABLE_CTRCLICK);
+		serio_write(serio, volume_to_hw(lk->ctrlclick_volume));
+	} else {
+		DBG("%s: Deactivating key clicks\n", __func__);
+		serio_write(serio, LK_CMD_DISABLE_KEYCLICK);
+		serio_write(serio, LK_CMD_DISABLE_CTRCLICK);
+	}
+
+}
+
 /*
  * lkkbd_event() handles events from the input module.
  */
-static int
-lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
-		int value)
+static int lkkbd_event(struct input_dev *dev,
+			unsigned int type, unsigned int code, int value)
 {
-	struct lkkbd *lk = input_get_drvdata (dev);
-	unsigned char leds_on = 0;
-	unsigned char leds_off = 0;
+	struct lkkbd *lk = input_get_drvdata(dev);
 
 	switch (type) {
-		case EV_LED:
-			CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
-			CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
-			CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
-			CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
-			if (leds_on != 0) {
-				serio_write (lk->serio, LK_CMD_LED_ON);
-				serio_write (lk->serio, leds_on);
-			}
-			if (leds_off != 0) {
-				serio_write (lk->serio, LK_CMD_LED_OFF);
-				serio_write (lk->serio, leds_off);
-			}
+	case EV_LED:
+		lkkbd_toggle_leds(lk);
+		return 0;
+
+	case EV_SND:
+		switch (code) {
+		case SND_CLICK:
+			lkkbd_toggle_keyclick(lk, value);
 			return 0;
 
-		case EV_SND:
-			switch (code) {
-				case SND_CLICK:
-					if (value == 0) {
-						DBG ("%s: Deactivating key clicks\n", __func__);
-						serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-						serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
-					} else {
-						DBG ("%s: Activating key clicks\n", __func__);
-						serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-						serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
-						serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-						serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
-					}
-					return 0;
+		case SND_BELL:
+			if (value != 0)
+				serio_write(lk->serio, LK_CMD_SOUND_BELL);
 
-				case SND_BELL:
-					if (value != 0)
-						serio_write (lk->serio, LK_CMD_SOUND_BELL);
+			return 0;
+		}
 
-					return 0;
-			}
-			break;
+		break;
 
-		default:
-			printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
-					__func__, type, code, value);
+	default:
+		printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n",
+			__func__, type, code, value);
 	}
 
 	return -1;
@@ -570,79 +576,56 @@ lkkbd_event (struct input_dev *dev, unsi
  * lkkbd_reinit() sets leds and beeps to a state the computer remembers they
  * were in.
  */
-static void
-lkkbd_reinit (struct work_struct *work)
+static void lkkbd_reinit(struct work_struct *work)
 {
 	struct lkkbd *lk = container_of(work, struct lkkbd, tq);
 	int division;
-	unsigned char leds_on = 0;
-	unsigned char leds_off = 0;
 
 	/* Ask for ID */
-	serio_write (lk->serio, LK_CMD_REQUEST_ID);
+	serio_write(lk->serio, LK_CMD_REQUEST_ID);
 
 	/* Reset parameters */
-	serio_write (lk->serio, LK_CMD_SET_DEFAULTS);
+	serio_write(lk->serio, LK_CMD_SET_DEFAULTS);
 
 	/* Set LEDs */
-	CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
-	CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
-	CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
-	CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
-	if (leds_on != 0) {
-		serio_write (lk->serio, LK_CMD_LED_ON);
-		serio_write (lk->serio, leds_on);
-	}
-	if (leds_off != 0) {
-		serio_write (lk->serio, LK_CMD_LED_OFF);
-		serio_write (lk->serio, leds_off);
-	}
+	lkkbd_toggle_leds(lk);
 
 	/*
 	 * Try to activate extended LK401 mode. This command will
 	 * only work with a LK401 keyboard and grants access to
 	 * LAlt, RAlt, RCompose and RShift.
 	 */
-	serio_write (lk->serio, LK_CMD_ENABLE_LK401);
+	serio_write(lk->serio, LK_CMD_ENABLE_LK401);
 
 	/* Set all keys to UPDOWN mode */
 	for (division = 1; division <= 14; division++)
-		serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
-					division));
+		serio_write(lk->serio,
+			    LK_CMD_SET_MODE(LK_MODE_UPDOWN, division));
 
 	/* Enable bell and set volume */
-	serio_write (lk->serio, LK_CMD_ENABLE_BELL);
-	serio_write (lk->serio, volume_to_hw (lk->bell_volume));
+	serio_write(lk->serio, LK_CMD_ENABLE_BELL);
+	serio_write(lk->serio, volume_to_hw(lk->bell_volume));
 
 	/* Enable/disable keyclick (and possibly set volume) */
-	if (test_bit (SND_CLICK, lk->dev->snd)) {
-		serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-		serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
-		serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-		serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
-	} else {
-		serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-		serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
-	}
+	lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd));
 
 	/* Sound the bell if needed */
-	if (test_bit (SND_BELL, lk->dev->snd))
-		serio_write (lk->serio, LK_CMD_SOUND_BELL);
+	if (test_bit(SND_BELL, lk->dev->snd))
+		serio_write(lk->serio, LK_CMD_SOUND_BELL);
 }
 
 /*
  * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
  */
-static int
-lkkbd_connect (struct serio *serio, struct serio_driver *drv)
+static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct lkkbd *lk;
 	struct input_dev *input_dev;
 	int i;
 	int err;
 
-	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
-	input_dev = input_allocate_device ();
+	lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
 	if (!lk || !input_dev) {
 		err = -ENOMEM;
 		goto fail1;
@@ -650,14 +633,14 @@ lkkbd_connect (struct serio *serio, stru
 
 	lk->serio = serio;
 	lk->dev = input_dev;
-	INIT_WORK (&lk->tq, lkkbd_reinit);
+	INIT_WORK(&lk->tq, lkkbd_reinit);
 	lk->bell_volume = bell_volume;
 	lk->keyclick_volume = keyclick_volume;
 	lk->ctrlclick_volume = ctrlclick_volume;
-	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
+	memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode));
 
-	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
-	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
+	strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name));
+	snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
 
 	input_dev->name = lk->name;
 	input_dev->phys = lk->phys;
@@ -668,62 +651,61 @@ lkkbd_connect (struct serio *serio, stru
 	input_dev->dev.parent = &serio->dev;
 	input_dev->event = lkkbd_event;
 
-	input_set_drvdata (input_dev, lk);
+	input_set_drvdata(input_dev, lk);
 
-	set_bit (EV_KEY, input_dev->evbit);
-	set_bit (EV_LED, input_dev->evbit);
-	set_bit (EV_SND, input_dev->evbit);
-	set_bit (EV_REP, input_dev->evbit);
-	set_bit (LED_CAPSL, input_dev->ledbit);
-	set_bit (LED_SLEEP, input_dev->ledbit);
-	set_bit (LED_COMPOSE, input_dev->ledbit);
-	set_bit (LED_SCROLLL, input_dev->ledbit);
-	set_bit (SND_BELL, input_dev->sndbit);
-	set_bit (SND_CLICK, input_dev->sndbit);
+	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(EV_LED, input_dev->evbit);
+	__set_bit(EV_SND, input_dev->evbit);
+	__set_bit(EV_REP, input_dev->evbit);
+	__set_bit(LED_CAPSL, input_dev->ledbit);
+	__set_bit(LED_SLEEP, input_dev->ledbit);
+	__set_bit(LED_COMPOSE, input_dev->ledbit);
+	__set_bit(LED_SCROLLL, input_dev->ledbit);
+	__set_bit(SND_BELL, input_dev->sndbit);
+	__set_bit(SND_CLICK, input_dev->sndbit);
 
 	input_dev->keycode = lk->keycode;
-	input_dev->keycodesize = sizeof (lk_keycode_t);
-	input_dev->keycodemax = LK_NUM_KEYCODES;
+	input_dev->keycodesize = sizeof(lk->keycode[0]);
+	input_dev->keycodemax = ARRAY_SIZE(lk->keycode);
 
 	for (i = 0; i < LK_NUM_KEYCODES; i++)
-		__set_bit (lk->keycode[i], input_dev->keybit);
+		__set_bit(lk->keycode[i], input_dev->keybit);
 	__clear_bit(KEY_RESERVED, input_dev->keybit);
 
-	serio_set_drvdata (serio, lk);
+	serio_set_drvdata(serio, lk);
 
-	err = serio_open (serio, drv);
+	err = serio_open(serio, drv);
 	if (err)
 		goto fail2;
 
-	err = input_register_device (lk->dev);
+	err = input_register_device(lk->dev);
 	if (err)
 		goto fail3;
 
-	serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+	serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET);
 
 	return 0;
 
- fail3:	serio_close (serio);
- fail2:	serio_set_drvdata (serio, NULL);
- fail1:	input_free_device (input_dev);
-	kfree (lk);
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(lk);
 	return err;
 }
 
 /*
  * lkkbd_disconnect() unregisters and closes behind us.
  */
-static void
-lkkbd_disconnect (struct serio *serio)
+static void lkkbd_disconnect(struct serio *serio)
 {
-	struct lkkbd *lk = serio_get_drvdata (serio);
+	struct lkkbd *lk = serio_get_drvdata(serio);
 
-	input_get_device (lk->dev);
-	input_unregister_device (lk->dev);
-	serio_close (serio);
-	serio_set_drvdata (serio, NULL);
-	input_put_device (lk->dev);
-	kfree (lk);
+	input_get_device(lk->dev);
+	input_unregister_device(lk->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(lk->dev);
+	kfree(lk);
 }
 
 static struct serio_device_id lkkbd_serio_ids[] = {
@@ -752,18 +734,16 @@ static struct serio_driver lkkbd_drv = {
 /*
  * The functions for insering/removing us as a module.
  */
-static int __init
-lkkbd_init (void)
+static int __init lkkbd_init(void)
 {
 	return serio_register_driver(&lkkbd_drv);
 }
 
-static void __exit
-lkkbd_exit (void)
+static void __exit lkkbd_exit(void)
 {
 	serio_unregister_driver(&lkkbd_drv);
 }
 
-module_init (lkkbd_init);
-module_exit (lkkbd_exit);
+module_init(lkkbd_init);
+module_exit(lkkbd_exit);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/Makefile linux-libre-2.6.33-gnu1/drivers/input/keyboard/Makefile
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,12 +5,14 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_KEYBOARD_AAED2000)		+= aaed2000_kbd.o
+obj-$(CONFIG_KEYBOARD_ADP5520)		+= adp5520-keys.o
 obj-$(CONFIG_KEYBOARD_ADP5588)		+= adp5588-keys.o
 obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
 obj-$(CONFIG_KEYBOARD_ATARI)		+= atakbd.o
 obj-$(CONFIG_KEYBOARD_ATKBD)		+= atkbd.o
 obj-$(CONFIG_KEYBOARD_BFIN)		+= bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_CORGI)		+= corgikbd.o
+obj-$(CONFIG_KEYBOARD_DAVINCI)		+= davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)		+= ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)		+= gpio_keys.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/matrix_keypad.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/matrix_keypad.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/matrix_keypad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/matrix_keypad.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,11 +29,13 @@ struct matrix_keypad {
 	unsigned short *keycodes;
 	unsigned int row_shift;
 
+	DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
+
 	uint32_t last_key_state[MATRIX_MAX_COLS];
 	struct delayed_work work;
+	spinlock_t lock;
 	bool scan_pending;
 	bool stopped;
-	spinlock_t lock;
 };
 
 /*
@@ -213,38 +215,53 @@ static void matrix_keypad_stop(struct in
 }
 
 #ifdef CONFIG_PM
-static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state)
+static int matrix_keypad_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 	int i;
 
 	matrix_keypad_stop(keypad->input_dev);
 
-	if (device_may_wakeup(&pdev->dev))
-		for (i = 0; i < pdata->num_row_gpios; i++)
-			enable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->num_row_gpios; i++) {
+			if (!test_bit(i, keypad->disabled_gpios)) {
+				unsigned int gpio = pdata->row_gpios[i];
+
+				if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
+					__set_bit(i, keypad->disabled_gpios);
+			}
+		}
+	}
 
 	return 0;
 }
 
-static int matrix_keypad_resume(struct platform_device *pdev)
+static int matrix_keypad_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 	const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 	int i;
 
-	if (device_may_wakeup(&pdev->dev))
-		for (i = 0; i < pdata->num_row_gpios; i++)
-			disable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->num_row_gpios; i++) {
+			if (test_and_clear_bit(i, keypad->disabled_gpios)) {
+				unsigned int gpio = pdata->row_gpios[i];
+
+				disable_irq_wake(gpio_to_irq(gpio));
+			}
+		}
+	}
 
 	matrix_keypad_start(keypad->input_dev);
 
 	return 0;
 }
-#else
-#define matrix_keypad_suspend	NULL
-#define matrix_keypad_resume	NULL
+
+static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
+				matrix_keypad_suspend, matrix_keypad_resume);
 #endif
 
 static int __devinit init_matrix_gpio(struct platform_device *pdev,
@@ -417,11 +434,12 @@ static int __devexit matrix_keypad_remov
 static struct platform_driver matrix_keypad_driver = {
 	.probe		= matrix_keypad_probe,
 	.remove		= __devexit_p(matrix_keypad_remove),
-	.suspend	= matrix_keypad_suspend,
-	.resume		= matrix_keypad_resume,
 	.driver		= {
 		.name	= "matrix-keypad",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &matrix_keypad_pm_ops,
+#endif
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/omap-keypad.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/omap-keypad.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/omap-keypad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/omap-keypad.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,12 +35,12 @@
 #include <linux/mutex.h>
 #include <linux/errno.h>
 #include <mach/gpio.h>
-#include <mach/keypad.h>
-#include <mach/menelaus.h>
+#include <plat/keypad.h>
+#include <plat/menelaus.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
-#include <mach/mux.h>
+#include <plat/mux.h>
 
 #undef NEW_BOARD_LEARNING_MODE
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/sh_keysc.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/sh_keysc.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/sh_keysc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/sh_keysc.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,9 +18,9 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <asm/sh_keysc.h>
 
 #define KYCR1_OFFS   0x00
 #define KYCR2_OFFS   0x04
@@ -295,7 +295,7 @@ static int sh_keysc_resume(struct device
 	return 0;
 }
 
-static struct dev_pm_ops sh_keysc_dev_pm_ops = {
+static const struct dev_pm_ops sh_keysc_dev_pm_ops = {
 	.suspend = sh_keysc_suspend,
 	.resume = sh_keysc_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/keyboard/twl4030_keypad.c linux-libre-2.6.33-gnu1/drivers/input/keyboard/twl4030_keypad.c
--- linux-libre-2.6.32-gnu1/drivers/input/keyboard/twl4030_keypad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/keyboard/twl4030_keypad.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
@@ -133,7 +133,7 @@ struct twl4030_keypad {
 static int twl4030_kpread(struct twl4030_keypad *kp,
 		u8 *data, u32 reg, u8 num_bytes)
 {
-	int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes);
+	int ret = twl_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes);
 
 	if (ret < 0)
 		dev_warn(kp->dbg_dev,
@@ -145,7 +145,7 @@ static int twl4030_kpread(struct twl4030
 
 static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg)
 {
-	int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg);
+	int ret = twl_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg);
 
 	if (ret < 0)
 		dev_warn(kp->dbg_dev,
@@ -253,14 +253,6 @@ static irqreturn_t do_kp_irq(int irq, vo
 	u8 reg;
 	int ret;
 
-#ifdef CONFIG_LOCKDEP
-	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-	 * we don't want and can't tolerate.  Although it might be
-	 * friendlier not to borrow this thread context...
-	 */
-	local_irq_enable();
-#endif
-
 	/* Read & Clear TWL4030 pending interrupt */
 	ret = twl4030_kpread(kp, &reg, KEYP_ISR1, 1);
 
@@ -403,7 +395,8 @@ static int __devinit twl4030_kp_probe(st
 	 *
 	 * NOTE:  we assume this host is wired to TWL4040 INT1, not INT2 ...
 	 */
-	error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp);
+	error = request_threaded_irq(kp->irq, NULL, do_kp_irq,
+			0, pdev->name, kp);
 	if (error) {
 		dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n",
 			kp->irq);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/Makefile linux-libre-2.6.33-gnu1/drivers/input/Makefile
--- linux-libre-2.6.32-gnu1/drivers/input/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@ input-core-objs := input.o input-compat.
 
 obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o
 obj-$(CONFIG_INPUT_POLLDEV)	+= input-polldev.o
+obj-$(CONFIG_INPUT_SPARSEKMAP)	+= sparse-keymap.o
 
 obj-$(CONFIG_INPUT_MOUSEDEV)	+= mousedev.o
 obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/ati_remote.c linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/ati_remote.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/ati_remote.c	2010-02-24 13:52:17.000000000 -0500
@@ -766,7 +766,7 @@ static int ati_remote_probe(struct usb_i
 	ati_remote->interface = interface;
 
 	usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
-	strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
+	strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
 
 	if (udev->manufacturer)
 		strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/bfin_rotary.c linux-libre-2.6.33-gnu1/drivers/input/misc/bfin_rotary.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/bfin_rotary.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/bfin_rotary.c	2010-02-24 13:52:17.000000000 -0500
@@ -247,7 +247,7 @@ static int bfin_rotary_resume(struct dev
 	return 0;
 }
 
-static struct dev_pm_ops bfin_rotary_pm_ops = {
+static const struct dev_pm_ops bfin_rotary_pm_ops = {
 	.suspend	= bfin_rotary_suspend,
 	.resume		= bfin_rotary_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/dm355evm_keys.c linux-libre-2.6.33-gnu1/drivers/input/misc/dm355evm_keys.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/dm355evm_keys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/dm355evm_keys.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 
@@ -33,12 +34,8 @@ struct dm355evm_keys {
 	int			irq;
 };
 
-/* These initial keycodes can be remapped by dm355evm_setkeycode(). */
-static struct {
-	u16	event;
-	u16	keycode;
-} dm355evm_keys[] = {
-
+/* These initial keycodes can be remapped */
+static const struct key_entry dm355evm_keys[] = {
 	/*
 	 * Pushbuttons on the EVM board ... note that the labels for these
 	 * are SW10/SW11/etc on the PC board.  The left/right orientation
@@ -47,11 +44,11 @@ static struct {
 	 * is to the right.  (That is, rotate the board counter-clockwise
 	 * by 90 degrees from the SW10/etc and "DM355 EVM" labels.)
 	 */
-	{ 0x00d8, KEY_OK, },		/* SW12 */
-	{ 0x00b8, KEY_UP, },		/* SW13 */
-	{ 0x00e8, KEY_DOWN, },		/* SW11 */
-	{ 0x0078, KEY_LEFT, },		/* SW14 */
-	{ 0x00f0, KEY_RIGHT, },		/* SW10 */
+	{ KE_KEY, 0x00d8, { KEY_OK } },		/* SW12 */
+	{ KE_KEY, 0x00b8, { KEY_UP } },		/* SW13 */
+	{ KE_KEY, 0x00e8, { KEY_DOWN } },	/* SW11 */
+	{ KE_KEY, 0x0078, { KEY_LEFT } },	/* SW14 */
+	{ KE_KEY, 0x00f0, { KEY_RIGHT } },	/* SW10 */
 
 	/*
 	 * IR buttons ... codes assigned to match the universal remote
@@ -65,35 +62,35 @@ static struct {
 	 * RC5 codes are 14 bits, with two start bits (0x3 prefix)
 	 * and a toggle bit (masked out below).
 	 */
-	{ 0x300c, KEY_POWER, },		/* NOTE: docs omit this */
-	{ 0x3000, KEY_NUMERIC_0, },
-	{ 0x3001, KEY_NUMERIC_1, },
-	{ 0x3002, KEY_NUMERIC_2, },
-	{ 0x3003, KEY_NUMERIC_3, },
-	{ 0x3004, KEY_NUMERIC_4, },
-	{ 0x3005, KEY_NUMERIC_5, },
-	{ 0x3006, KEY_NUMERIC_6, },
-	{ 0x3007, KEY_NUMERIC_7, },
-	{ 0x3008, KEY_NUMERIC_8, },
-	{ 0x3009, KEY_NUMERIC_9, },
-	{ 0x3022, KEY_ENTER, },
-	{ 0x30ec, KEY_MODE, },		/* "tv/vcr/..." */
-	{ 0x300f, KEY_SELECT, },	/* "info" */
-	{ 0x3020, KEY_CHANNELUP, },	/* "up" */
-	{ 0x302e, KEY_MENU, },		/* "in/out" */
-	{ 0x3011, KEY_VOLUMEDOWN, },	/* "left" */
-	{ 0x300d, KEY_MUTE, },		/* "ok" */
-	{ 0x3010, KEY_VOLUMEUP, },	/* "right" */
-	{ 0x301e, KEY_SUBTITLE, },	/* "cc" */
-	{ 0x3021, KEY_CHANNELDOWN, },	/* "down" */
-	{ 0x3022, KEY_PREVIOUS, },
-	{ 0x3026, KEY_SLEEP, },
-	{ 0x3172, KEY_REWIND, },	/* NOTE: docs wrongly say 0x30ca */
-	{ 0x3175, KEY_PLAY, },
-	{ 0x3174, KEY_FASTFORWARD, },
-	{ 0x3177, KEY_RECORD, },
-	{ 0x3176, KEY_STOP, },
-	{ 0x3169, KEY_PAUSE, },
+	{ KE_KEY, 0x300c, { KEY_POWER } },	/* NOTE: docs omit this */
+	{ KE_KEY, 0x3000, { KEY_NUMERIC_0 } },
+	{ KE_KEY, 0x3001, { KEY_NUMERIC_1 } },
+	{ KE_KEY, 0x3002, { KEY_NUMERIC_2 } },
+	{ KE_KEY, 0x3003, { KEY_NUMERIC_3 } },
+	{ KE_KEY, 0x3004, { KEY_NUMERIC_4 } },
+	{ KE_KEY, 0x3005, { KEY_NUMERIC_5 } },
+	{ KE_KEY, 0x3006, { KEY_NUMERIC_6 } },
+	{ KE_KEY, 0x3007, { KEY_NUMERIC_7 } },
+	{ KE_KEY, 0x3008, { KEY_NUMERIC_8 } },
+	{ KE_KEY, 0x3009, { KEY_NUMERIC_9 } },
+	{ KE_KEY, 0x3022, { KEY_ENTER } },
+	{ KE_KEY, 0x30ec, { KEY_MODE } },	/* "tv/vcr/..." */
+	{ KE_KEY, 0x300f, { KEY_SELECT } },	/* "info" */
+	{ KE_KEY, 0x3020, { KEY_CHANNELUP } },	/* "up" */
+	{ KE_KEY, 0x302e, { KEY_MENU } },	/* "in/out" */
+	{ KE_KEY, 0x3011, { KEY_VOLUMEDOWN } },	/* "left" */
+	{ KE_KEY, 0x300d, { KEY_MUTE } },	/* "ok" */
+	{ KE_KEY, 0x3010, { KEY_VOLUMEUP } },	/* "right" */
+	{ KE_KEY, 0x301e, { KEY_SUBTITLE } },	/* "cc" */
+	{ KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */
+	{ KE_KEY, 0x3022, { KEY_PREVIOUS } },
+	{ KE_KEY, 0x3026, { KEY_SLEEP } },
+	{ KE_KEY, 0x3172, { KEY_REWIND } },	/* NOTE: docs wrongly say 0x30ca */
+	{ KE_KEY, 0x3175, { KEY_PLAY } },
+	{ KE_KEY, 0x3174, { KEY_FASTFORWARD } },
+	{ KE_KEY, 0x3177, { KEY_RECORD } },
+	{ KE_KEY, 0x3176, { KEY_STOP } },
+	{ KE_KEY, 0x3169, { KEY_PAUSE } },
 };
 
 /*
@@ -105,19 +102,18 @@ static struct {
  */
 static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
 {
-	struct dm355evm_keys	*keys = _keys;
-	int			status;
+	static u16 last_event;
+	struct dm355evm_keys *keys = _keys;
+	const struct key_entry *ke;
+	unsigned int keycode;
+	int status;
+	u16 event;
 
 	/* For simplicity we ignore INPUT_COUNT and just read
 	 * events until we get the "queue empty" indicator.
 	 * Reading INPUT_LOW decrements the count.
 	 */
 	for (;;) {
-		static u16	last_event;
-		u16		event;
-		int		keycode;
-		int		i;
-
 		status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
 		if (status < 0) {
 			dev_dbg(keys->dev, "input high err %d\n",
@@ -156,14 +152,9 @@ static irqreturn_t dm355evm_keys_irq(int
 		/* ignore the RC5 toggle bit */
 		event &= ~0x0800;
 
-		/* find the key, or leave it as unknown */
-		keycode = KEY_UNKNOWN;
-		for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
-			if (dm355evm_keys[i].event != event)
-				continue;
-			keycode = dm355evm_keys[i].keycode;
-			break;
-		}
+		/* find the key, or report it as unknown */
+		ke = sparse_keymap_entry_from_scancode(keys->input, event);
+		keycode = ke ? ke->keycode : KEY_UNKNOWN;
 		dev_dbg(keys->dev,
 			"input event 0x%04x--> keycode %d\n",
 			event, keycode);
@@ -174,36 +165,8 @@ static irqreturn_t dm355evm_keys_irq(int
 		input_report_key(keys->input, keycode, 0);
 		input_sync(keys->input);
 	}
-	return IRQ_HANDLED;
-}
 
-static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
-{
-	u16		old_keycode;
-	unsigned	i;
-
-	if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
-		return -EINVAL;
-
-	old_keycode = dm355evm_keys[index].keycode;
-	dm355evm_keys[index].keycode = keycode;
-	set_bit(keycode, dev->keybit);
-
-	for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
-		if (dm355evm_keys[index].keycode == old_keycode)
-			goto done;
-	}
-	clear_bit(old_keycode, dev->keybit);
-done:
-	return 0;
-}
-
-static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode)
-{
-	if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
-		return -EINVAL;
-
-	return dm355evm_keys[index].keycode;
+	return IRQ_HANDLED;
 }
 
 /*----------------------------------------------------------------------*/
@@ -213,7 +176,6 @@ static int __devinit dm355evm_keys_probe
 	struct dm355evm_keys	*keys;
 	struct input_dev	*input;
 	int			status;
-	int			i;
 
 	/* allocate instance struct and input dev */
 	keys = kzalloc(sizeof *keys, GFP_KERNEL);
@@ -242,31 +204,30 @@ static int __devinit dm355evm_keys_probe
 	input->id.product = 0x0355;
 	input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
 
-	input->evbit[0] = BIT(EV_KEY);
-	for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++)
-		__set_bit(dm355evm_keys[i].keycode, input->keybit);
-
-	input->setkeycode = dm355evm_setkeycode;
-	input->getkeycode = dm355evm_getkeycode;
+	status = sparse_keymap_setup(input, dm355evm_keys, NULL);
+	if (status)
+		goto fail1;
 
 	/* REVISIT:  flush the event queue? */
 
 	status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq,
 			IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys);
 	if (status < 0)
-		goto fail1;
+		goto fail2;
 
 	/* register */
 	status = input_register_device(input);
 	if (status < 0)
-		goto fail2;
+		goto fail3;
 
 	platform_set_drvdata(pdev, keys);
 
 	return 0;
 
-fail2:
+fail3:
 	free_irq(keys->irq, keys);
+fail2:
+	sparse_keymap_free(input);
 fail1:
 	input_free_device(input);
 	kfree(keys);
@@ -280,6 +241,7 @@ static int __devexit dm355evm_keys_remov
 	struct dm355evm_keys	*keys = platform_get_drvdata(pdev);
 
 	free_irq(keys->irq, keys);
+	sparse_keymap_free(keys->input);
 	input_unregister_device(keys->input);
 	kfree(keys);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/hp_sdc_rtc.c linux-libre-2.6.33-gnu1/drivers/input/misc/hp_sdc_rtc.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/hp_sdc_rtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/hp_sdc_rtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,6 @@
 
 #include <linux/hp_sdc.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -409,7 +408,6 @@ static unsigned int hp_sdc_rtc_poll(stru
 
 static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
         return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/Kconfig linux-libre-2.6.33-gnu1/drivers/input/misc/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/misc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS
 	tristate "x86 Wistron laptop button interface"
 	depends on X86 && !X86_64
 	select INPUT_POLLDEV
+	select INPUT_SPARSEKMAP
 	select NEW_LEDS
 	select LEDS_CLASS
 	select CHECK_SIGNATURE
@@ -281,6 +282,7 @@ config INPUT_RB532_BUTTON
 config INPUT_DM355EVM
 	tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
 	depends on MFD_DM355EVM_MSP
+	select INPUT_SPARSEKMAP
 	help
 	  Supports the pushbuttons and IR remote used with
 	  the DM355 EVM board.
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/pcf50633-input.c linux-libre-2.6.33-gnu1/drivers/input/misc/pcf50633-input.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/pcf50633-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/pcf50633-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,6 @@ pcf50633_input_irq(int irq, void *data)
 static int __devinit pcf50633_input_probe(struct platform_device *pdev)
 {
 	struct pcf50633_input *input;
-	struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
 	struct input_dev *input_dev;
 	int ret;
 
@@ -71,7 +70,7 @@ static int __devinit pcf50633_input_prob
 	}
 
 	platform_set_drvdata(pdev, input);
-	input->pcf = pdata->pcf;
+	input->pcf = dev_to_pcf50633(pdev->dev.parent);
 	input->input_dev = input_dev;
 
 	input_dev->name = "PCF50633 PMU events";
@@ -85,9 +84,9 @@ static int __devinit pcf50633_input_prob
 		kfree(input);
 		return ret;
 	}
-	pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR,
+	pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,
 				pcf50633_input_irq, input);
-	pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF,
+	pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,
 				pcf50633_input_irq, input);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/pcspkr.c linux-libre-2.6.33-gnu1/drivers/input/misc/pcspkr.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/pcspkr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/pcspkr.c	2010-02-24 13:52:17.000000000 -0500
@@ -127,7 +127,7 @@ static void pcspkr_shutdown(struct platf
 	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 }
 
-static struct dev_pm_ops pcspkr_pm_ops = {
+static const struct dev_pm_ops pcspkr_pm_ops = {
 	.suspend = pcspkr_suspend,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/powermate.c linux-libre-2.6.33-gnu1/drivers/input/misc/powermate.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/powermate.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/powermate.c	2010-02-24 13:52:17.000000000 -0500
@@ -338,7 +338,7 @@ static int powermate_probe(struct usb_in
 	pm->input = input_dev;
 
 	usb_make_path(udev, pm->phys, sizeof(pm->phys));
-	strlcpy(pm->phys, "/input0", sizeof(pm->phys));
+	strlcat(pm->phys, "/input0", sizeof(pm->phys));
 
 	spin_lock_init(&pm->lock);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/twl4030-pwrbutton.c linux-libre-2.6.33-gnu1/drivers/input/misc/twl4030-pwrbutton.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/twl4030-pwrbutton.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/twl4030-pwrbutton.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #define PWR_PWRON_IRQ (1 << 0)
 
@@ -39,18 +39,8 @@ static irqreturn_t powerbutton_irq(int i
 	int err;
 	u8 value;
 
-#ifdef CONFIG_LOCKDEP
-	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-	 * we don't want and can't tolerate since this is a threaded
-	 * IRQ and can sleep due to the i2c reads it has to issue.
-	 * Although it might be friendlier not to borrow this thread
-	 * context...
-	 */
-	local_irq_enable();
-#endif
-
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
-				  STS_HW_CONDITIONS);
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
+				STS_HW_CONDITIONS);
 	if (!err)  {
 		input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
 		input_sync(pwr);
@@ -80,7 +70,7 @@ static int __devinit twl4030_pwrbutton_p
 	pwr->phys = "twl4030_pwrbutton/input0";
 	pwr->dev.parent = &pdev->dev;
 
-	err = request_irq(irq, powerbutton_irq,
+	err = request_threaded_irq(irq, NULL, powerbutton_irq,
 			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
 			"twl4030_pwrbutton", pwr);
 	if (err < 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/winbond-cir.c linux-libre-2.6.33-gnu1/drivers/input/misc/winbond-cir.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/winbond-cir.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/winbond-cir.c	2010-02-24 13:52:17.000000000 -0500
@@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, stru
 		return;
 	}
 
-	dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
+	dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
 		"toggle %u mode %u scan 0x%08X\n",
 		address,
 		command,
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/misc/wistron_btns.c linux-libre-2.6.33-gnu1/drivers/input/misc/wistron_btns.c
--- linux-libre-2.6.32-gnu1/drivers/input/misc/wistron_btns.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/misc/wistron_btns.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,7 @@
 #include <linux/dmi.h>
 #include <linux/init.h>
 #include <linux/input-polldev.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
@@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, in
 
 /* Hardware database */
 
-struct key_entry {
-	char type;		/* See KE_* below */
-	u8 code;
-	union {
-		u16 keycode;		/* For KE_KEY */
-		struct {		/* For KE_SW */
-			u8 code;
-			u8 value;
-		} sw;
-	};
-};
-
-enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
+#define KE_WIFI		(KE_LAST + 1)
+#define KE_BLUETOOTH	(KE_LAST + 2)
 
 #define FE_MAIL_LED 0x01
 #define FE_WIFI_LED 0x02
@@ -644,10 +634,10 @@ static struct key_entry keymap_prestigio
  * a list of buttons and their key codes (reported when loading this module
  * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
  */
-static struct dmi_system_id dmi_ids[] __initdata = {
+static const struct dmi_system_id __initconst dmi_ids[] = {
 	{
+		/* Fujitsu-Siemens Amilo Pro V2000 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo Pro V2000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
@@ -655,8 +645,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Fujitsu-Siemens Amilo Pro Edition V3505 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
@@ -664,8 +654,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_pro_v3505
 	},
 	{
+		/* Fujitsu-Siemens Amilo M7400 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu-Siemens Amilo M7400",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M        "),
@@ -673,8 +663,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Maxdata Pro 7000 DX */
 		.callback = dmi_matched,
-		.ident = "Maxdata Pro 7000 DX",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
@@ -682,8 +672,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Fujitsu N3510 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu N3510",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
@@ -691,8 +681,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fujitsu_n3510
 	},
 	{
+		/* Acer Aspire 1500 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 1500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
@@ -700,8 +690,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_aspire_1500
 	},
 	{
+		/* Acer Aspire 1600 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 1600",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
@@ -709,8 +699,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_aspire_1600
 	},
 	{
+		/* Acer Aspire 3020 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 3020",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
@@ -718,8 +708,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer Aspire 5020 */
 		.callback = dmi_matched,
-		.ident = "Acer Aspire 5020",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
@@ -727,8 +717,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer TravelMate 2100 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
@@ -736,8 +726,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_aspire_5020
 	},
 	{
+		/* Acer TravelMate 2410 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2410",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
@@ -745,8 +735,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_2410
 	},
 	{
+		/* Acer TravelMate C300 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C300",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
@@ -754,8 +744,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_300
 	},
 	{
+		/* Acer TravelMate C100 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
@@ -763,8 +753,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_300
 	},
 	{
+		/* Acer TravelMate C110 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate C110",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
@@ -772,8 +762,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_110
 	},
 	{
+		/* Acer TravelMate 380 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 380",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
@@ -781,8 +771,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_380
 	},
 	{
+		/* Acer TravelMate 370 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 370",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
@@ -790,8 +780,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
 	},
 	{
+		/* Acer TravelMate 220 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 220",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
@@ -799,8 +789,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_220
 	},
 	{
+		/* Acer TravelMate 260 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 260",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
@@ -808,8 +798,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_220
 	},
 	{
+		/* Acer TravelMate 230 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 230",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
@@ -818,8 +808,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_230
 	},
 	{
+		/* Acer TravelMate 280 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 280",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
@@ -827,8 +817,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_230
 	},
 	{
+		/* Acer TravelMate 240 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 240",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
@@ -836,8 +826,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 250 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 250",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
@@ -845,8 +835,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 2424NWXCi */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 2424NWXCi",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
@@ -854,8 +844,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_240
 	},
 	{
+		/* Acer TravelMate 350 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 350",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
@@ -863,8 +853,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_350
 	},
 	{
+		/* Acer TravelMate 360 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 360",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
@@ -872,8 +862,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_360
 	},
 	{
+		/* Acer TravelMate 610 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 610",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
@@ -881,8 +871,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_610
 	},
 	{
+		/* Acer TravelMate 620 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 620",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
@@ -890,8 +880,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_630
 	},
 	{
+		/* Acer TravelMate 630 */
 		.callback = dmi_matched,
-		.ident = "Acer TravelMate 630",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
@@ -899,8 +889,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_acer_travelmate_630
 	},
 	{
+		/* AOpen 1559AS */
 		.callback = dmi_matched,
-		.ident = "AOpen 1559AS",
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
 			DMI_MATCH(DMI_BOARD_NAME, "E2U"),
@@ -908,8 +898,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_aopen_1559as
 	},
 	{
+		/* Medion MD 9783 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 9783",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
@@ -917,8 +907,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_wistron_ms2111
 	},
 	{
+		/* Medion MD 40100 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 40100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
@@ -926,8 +916,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_wistron_md40100
 	},
 	{
+		/* Medion MD 2900 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 2900",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
@@ -935,8 +925,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_wistron_md2900
 	},
 	{
+		/* Medion MD 42200 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 42200",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
@@ -944,8 +934,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_pro_v2000
 	},
 	{
+		/* Medion MD 96500 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 96500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
@@ -953,8 +943,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_wistron_md96500
 	},
 	{
+		/* Medion MD 95400 */
 		.callback = dmi_matched,
-		.ident = "Medion MD 95400",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
@@ -962,8 +952,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_wistron_md96500
 	},
 	{
+		/* Fujitsu Siemens Amilo D7820 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu Siemens Amilo D7820",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
 			DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
@@ -971,8 +961,8 @@ static struct dmi_system_id dmi_ids[] __
 		.driver_data = keymap_fs_amilo_d88x0
 	},
 	{
+		/* Fujitsu Siemens Amilo D88x0 */
 		.callback = dmi_matched,
-		.ident = "Fujitsu Siemens Amilo D88x0",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
@@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press;
 static bool wifi_enabled;
 static bool bluetooth_enabled;
 
-static void report_key(struct input_dev *dev, unsigned int keycode)
-{
-	input_report_key(dev, keycode, 1);
-	input_sync(dev);
-	input_report_key(dev, keycode, 0);
-	input_sync(dev);
-}
-
-static void report_switch(struct input_dev *dev, unsigned int code, int value)
-{
-	input_report_switch(dev, code, value);
-	input_sync(dev);
-}
-
-
  /* led management */
 static void wistron_mail_led_set(struct led_classdev *led_cdev,
 				enum led_brightness value)
@@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(vo
 		led_classdev_resume(&wistron_wifi_led);
 }
 
-static struct key_entry *wistron_get_entry_by_scancode(int code)
-{
-	struct key_entry *key;
-
-	for (key = keymap; key->type != KE_END; key++)
-		if (code == key->code)
-			return key;
-
-	return NULL;
-}
-
-static struct key_entry *wistron_get_entry_by_keycode(int keycode)
-{
-	struct key_entry *key;
-
-	for (key = keymap; key->type != KE_END; key++)
-		if (key->type == KE_KEY && keycode == key->keycode)
-			return key;
-
-	return NULL;
-}
-
 static void handle_key(u8 code)
 {
-	const struct key_entry *key = wistron_get_entry_by_scancode(code);
+	const struct key_entry *key =
+		sparse_keymap_entry_from_scancode(wistron_idev->input, code);
 
 	if (key) {
 		switch (key->type) {
-		case KE_KEY:
-			report_key(wistron_idev->input, key->keycode);
-			break;
-
-		case KE_SW:
-			report_switch(wistron_idev->input,
-				      key->sw.code, key->sw.value);
-			break;
-
 		case KE_WIFI:
 			if (have_wifi) {
 				wifi_enabled = !wifi_enabled;
@@ -1180,7 +1125,9 @@ static void handle_key(u8 code)
 			break;
 
 		default:
-			BUG();
+			sparse_keymap_report_entry(wistron_idev->input,
+						   key, 1, true);
+			break;
 		}
 		jiffies_last_press = jiffies;
 	} else
@@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_po
 		dev->poll_interval = POLL_INTERVAL_DEFAULT;
 }
 
-static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int __devinit wistron_setup_keymap(struct input_dev *dev,
+					  struct key_entry *entry)
 {
-	const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
-
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
-		return 0;
-	}
-
-	return -EINVAL;
-}
+	switch (entry->type) {
 
-static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
-{
-	struct key_entry *key;
-	int old_keycode;
+	/* if wifi or bluetooth are not available, create normal keys */
+	case KE_WIFI:
+		if (!have_wifi) {
+			entry->type = KE_KEY;
+			entry->keycode = KEY_WLAN;
+		}
+		break;
 
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
+	case KE_BLUETOOTH:
+		if (!have_bluetooth) {
+			entry->type = KE_KEY;
+			entry->keycode = KEY_BLUETOOTH;
+		}
+		break;
 
-	key = wistron_get_entry_by_scancode(scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!wistron_get_entry_by_keycode(old_keycode))
-			clear_bit(old_keycode, dev->keybit);
-		return 0;
+	case KE_END:
+		if (entry->code & FE_UNTESTED)
+			printk(KERN_WARNING "Untested laptop multimedia keys, "
+				"please report success or failure to "
+				"eric.piel@tremplin-utc.net\n");
+		break;
 	}
 
-	return -EINVAL;
+	return 0;
 }
 
 static int __devinit setup_input_dev(void)
 {
-	struct key_entry *key;
 	struct input_dev *input_dev;
 	int error;
 
@@ -1263,7 +1207,7 @@ static int __devinit setup_input_dev(voi
 	if (!wistron_idev)
 		return -ENOMEM;
 
-	wistron_idev->flush = wistron_flush;
+	wistron_idev->open = wistron_flush;
 	wistron_idev->poll = wistron_poll;
 	wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
 
@@ -1273,56 +1217,21 @@ static int __devinit setup_input_dev(voi
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->dev.parent = &wistron_device->dev;
 
-	input_dev->getkeycode = wistron_getkeycode;
-	input_dev->setkeycode = wistron_setkeycode;
-
-	for (key = keymap; key->type != KE_END; key++) {
-		switch (key->type) {
-			case KE_KEY:
-				set_bit(EV_KEY, input_dev->evbit);
-				set_bit(key->keycode, input_dev->keybit);
-				break;
-
-			case KE_SW:
-				set_bit(EV_SW, input_dev->evbit);
-				set_bit(key->sw.code, input_dev->swbit);
-				break;
-
-			/* if wifi or bluetooth are not available, create normal keys */
-			case KE_WIFI:
-				if (!have_wifi) {
-					key->type = KE_KEY;
-					key->keycode = KEY_WLAN;
-					key--;
-				}
-				break;
-
-			case KE_BLUETOOTH:
-				if (!have_bluetooth) {
-					key->type = KE_KEY;
-					key->keycode = KEY_BLUETOOTH;
-					key--;
-				}
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	/* reads information flags on KE_END */
-	if (key->code & FE_UNTESTED)
-		printk(KERN_WARNING "Untested laptop multimedia keys, "
-			"please report success or failure to eric.piel"
-			"@tremplin-utc.net\n");
+	error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap);
+	if (error)
+		goto err_free_dev;
 
 	error = input_register_polled_device(wistron_idev);
-	if (error) {
-		input_free_polled_device(wistron_idev);
-		return error;
-	}
+	if (error)
+		goto err_free_keymap;
 
 	return 0;
+
+ err_free_keymap:
+	sparse_keymap_free(input_dev);
+ err_free_dev:
+	input_free_polled_device(wistron_idev);
+	return error;
 }
 
 /* Driver core */
@@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(stru
 {
 	wistron_led_remove();
 	input_unregister_polled_device(wistron_idev);
+	sparse_keymap_free(wistron_idev->input);
 	input_free_polled_device(wistron_idev);
 	bios_detach();
 
@@ -1418,7 +1328,7 @@ static struct platform_driver wistron_dr
 	.driver		= {
 		.name	= "wistron-bios",
 		.owner	= THIS_MODULE,
-#if CONFIG_PM
+#ifdef CONFIG_PM
 		.pm	= &wistron_pm_ops,
 #endif
 	},
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/alps.c linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/alps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
  * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net>
  *
  * ALPS detection, tap switching and status querying info is taken from
  * tpconfig utility (by C. Scott Ananian and Bruce Kall).
@@ -28,13 +29,16 @@
 #define dbg(format, arg...) do {} while (0)
 #endif
 
-#define ALPS_DUALPOINT	0x01
-#define ALPS_WHEEL	0x02
-#define ALPS_FW_BK_1	0x04
-#define ALPS_4BTN	0x08
-#define ALPS_OLDPROTO	0x10
-#define ALPS_PASS	0x20
-#define ALPS_FW_BK_2	0x40
+#define ALPS_OLDPROTO		0x01	/* old style input */
+#define ALPS_DUALPOINT		0x02	/* touchpad has trackstick */
+#define ALPS_PASS		0x04	/* device has a pass-through port */
+
+#define ALPS_WHEEL		0x08	/* hardware wheel present */
+#define ALPS_FW_BK_1		0x10	/* front & back buttons present */
+#define ALPS_FW_BK_2		0x20	/* front & back buttons present */
+#define ALPS_FOUR_BUTTONS	0x40	/* 4 direction button present */
+#define ALPS_PS2_INTERLEAVED	0x80	/* 3-byte PS/2 packet interleaved with
+					   6-byte ALPS packet */
 
 static const struct alps_model_info alps_model_data[] = {
 	{ { 0x32, 0x02, 0x14 },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
@@ -55,8 +59,10 @@ static const struct alps_model_info alps
 	{ { 0x20, 0x02, 0x0e },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
 	{ { 0x22, 0x02, 0x0a },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
 	{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
-	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
-	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 },		  /* Dell Vostro 1400 */
+	/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
+	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
+		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
+	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },	  /* Dell Vostro 1400 */
 };
 
 /*
@@ -66,42 +72,99 @@ static const struct alps_model_info alps
  */
 
 /*
- * ALPS abolute Mode - new format
+ * PS/2 packet format
+ *
+ * byte 0:  0    0 YSGN XSGN    1    M    R    L
+ * byte 1: X7   X6   X5   X4   X3   X2   X1   X0
+ * byte 2: Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0
+ *
+ * Note that the device never signals overflow condition.
+ *
+ * ALPS absolute Mode - new format
  *
  * byte 0:  1    ?    ?    ?    1    ?    ?    ?
  * byte 1:  0   x6   x5   x4   x3   x2   x1   x0
- * byte 2:  0   x10  x9   x8   x7    ?  fin  ges
+ * byte 2:  0  x10   x9   x8   x7    ?  fin  ges
  * byte 3:  0   y9   y8   y7    1    M    R    L
  * byte 4:  0   y6   y5   y4   y3   y2   y1   y0
  * byte 5:  0   z6   z5   z4   z3   z2   z1   z0
  *
+ * Dualpoint device -- interleaved packet format
+ *
+ * byte 0:    1    1    0    0    1    1    1    1
+ * byte 1:    0   x6   x5   x4   x3   x2   x1   x0
+ * byte 2:    0  x10   x9   x8   x7    0  fin  ges
+ * byte 3:    0    0 YSGN XSGN    1    1    1    1
+ * byte 4:   X7   X6   X5   X4   X3   X2   X1   X0
+ * byte 5:   Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0
+ * byte 6:    0   y9   y8   y7    1    m    r    l
+ * byte 7:    0   y6   y5   y4   y3   y2   y1   y0
+ * byte 8:    0   z6   z5   z4   z3   z2   z1   z0
+ *
+ * CAPITALS = stick, miniscules = touchpad
+ *
  * ?'s can have different meanings on different models,
  * such as wheel rotation, extra buttons, stick buttons
  * on a dualpoint, etc.
  */
 
+static bool alps_is_valid_first_byte(const struct alps_model_info *model,
+				     unsigned char data)
+{
+	return (data & model->mask0) == model->byte0;
+}
+
+static void alps_report_buttons(struct psmouse *psmouse,
+				struct input_dev *dev1, struct input_dev *dev2,
+				int left, int right, int middle)
+{
+	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
+
+	if (model->flags & ALPS_PS2_INTERLEAVED) {
+		struct input_dev *dev;
+
+		/*
+		 * If shared button has already been reported on the
+		 * other device (dev2) then this event should be also
+		 * sent through that device.
+		 */
+		dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+		input_report_key(dev, BTN_LEFT, left);
+
+		dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+		input_report_key(dev, BTN_RIGHT, right);
+
+		dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+		input_report_key(dev, BTN_MIDDLE, middle);
+
+		/*
+		 * Sync the _other_ device now, we'll do the first
+		 * device later once we report the rest of the events.
+		 */
+		input_sync(dev2);
+	} else {
+		/*
+		 * For devices with non-interleaved packets we know what
+		 * device buttons belong to so we can simply report them.
+		 */
+		input_report_key(dev1, BTN_LEFT, left);
+		input_report_key(dev1, BTN_RIGHT, right);
+		input_report_key(dev1, BTN_MIDDLE, middle);
+	}
+}
+
 static void alps_process_packet(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
 	unsigned char *packet = psmouse->packet;
 	struct input_dev *dev = psmouse->dev;
 	struct input_dev *dev2 = priv->dev2;
 	int x, y, z, ges, fin, left, right, middle;
 	int back = 0, forward = 0;
 
-	if ((packet[0] & 0xc8) == 0x08) {   /* 3-byte PS/2 packet */
-		input_report_key(dev2, BTN_LEFT,   packet[0] & 1);
-		input_report_key(dev2, BTN_RIGHT,  packet[0] & 2);
-		input_report_key(dev2, BTN_MIDDLE, packet[0] & 4);
-		input_report_rel(dev2, REL_X,
-			packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
-		input_report_rel(dev2, REL_Y,
-			packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
-		input_sync(dev2);
-		return;
-	}
-
-	if (priv->i->flags & ALPS_OLDPROTO) {
+	if (model->flags & ALPS_OLDPROTO) {
 		left = packet[2] & 0x10;
 		right = packet[2] & 0x08;
 		middle = 0;
@@ -117,12 +180,12 @@ static void alps_process_packet(struct p
 		z = packet[5];
 	}
 
-	if (priv->i->flags & ALPS_FW_BK_1) {
+	if (model->flags & ALPS_FW_BK_1) {
 		back = packet[0] & 0x10;
 		forward = packet[2] & 4;
 	}
 
-	if (priv->i->flags & ALPS_FW_BK_2) {
+	if (model->flags & ALPS_FW_BK_2) {
 		back = packet[3] & 4;
 		forward = packet[2] & 4;
 		if ((middle = forward && back))
@@ -132,25 +195,21 @@ static void alps_process_packet(struct p
 	ges = packet[2] & 1;
 	fin = packet[2] & 2;
 
-	if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) {
+	if ((model->flags & ALPS_DUALPOINT) && z == 127) {
 		input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
 		input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
 
-		input_report_key(dev2, BTN_LEFT, left);
-		input_report_key(dev2, BTN_RIGHT, right);
-		input_report_key(dev2, BTN_MIDDLE, middle);
+		alps_report_buttons(psmouse, dev2, dev, left, right, middle);
 
-		input_sync(dev);
 		input_sync(dev2);
 		return;
 	}
 
-	input_report_key(dev, BTN_LEFT, left);
-	input_report_key(dev, BTN_RIGHT, right);
-	input_report_key(dev, BTN_MIDDLE, middle);
+	alps_report_buttons(psmouse, dev, dev2, left, right, middle);
 
 	/* Convert hardware tap to a reasonable Z value */
-	if (ges && !fin) z = 40;
+	if (ges && !fin)
+		z = 40;
 
 	/*
 	 * A "tap and drag" operation is reported by the hardware as a transition
@@ -166,8 +225,10 @@ static void alps_process_packet(struct p
 	}
 	priv->prev_fin = fin;
 
-	if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
-	if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
+	if (z > 30)
+		input_report_key(dev, BTN_TOUCH, 1);
+	if (z < 25)
+		input_report_key(dev, BTN_TOUCH, 0);
 
 	if (z > 0) {
 		input_report_abs(dev, ABS_X, x);
@@ -177,36 +238,186 @@ static void alps_process_packet(struct p
 	input_report_abs(dev, ABS_PRESSURE, z);
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
 
-	if (priv->i->flags & ALPS_WHEEL)
+	if (model->flags & ALPS_WHEEL)
 		input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
 
-	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
 		input_report_key(dev, BTN_FORWARD, forward);
 		input_report_key(dev, BTN_BACK, back);
 	}
 
+	if (model->flags & ALPS_FOUR_BUTTONS) {
+		input_report_key(dev, BTN_0, packet[2] & 4);
+		input_report_key(dev, BTN_1, packet[0] & 0x10);
+		input_report_key(dev, BTN_2, packet[3] & 4);
+		input_report_key(dev, BTN_3, packet[0] & 0x20);
+	}
+
 	input_sync(dev);
 }
 
+static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
+					unsigned char packet[],
+					bool report_buttons)
+{
+	struct alps_data *priv = psmouse->private;
+	struct input_dev *dev2 = priv->dev2;
+
+	if (report_buttons)
+		alps_report_buttons(psmouse, dev2, psmouse->dev,
+				packet[0] & 1, packet[0] & 2, packet[0] & 4);
+
+	input_report_rel(dev2, REL_X,
+		packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
+	input_report_rel(dev2, REL_Y,
+		packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
+
+	input_sync(dev2);
+}
+
+static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
+{
+	struct alps_data *priv = psmouse->private;
+
+	if (psmouse->pktcnt < 6)
+		return PSMOUSE_GOOD_DATA;
+
+	if (psmouse->pktcnt == 6) {
+		/*
+		 * Start a timer to flush the packet if it ends up last
+		 * 6-byte packet in the stream. Timer needs to fire
+		 * psmouse core times out itself. 20 ms should be enough
+		 * to decide if we are getting more data or not.
+		 */
+		mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
+		return PSMOUSE_GOOD_DATA;
+	}
+
+	del_timer(&priv->timer);
+
+	if (psmouse->packet[6] & 0x80) {
+
+		/*
+		 * Highest bit is set - that means we either had
+		 * complete ALPS packet and this is start of the
+		 * next packet or we got garbage.
+		 */
+
+		if (((psmouse->packet[3] |
+		      psmouse->packet[4] |
+		      psmouse->packet[5]) & 0x80) ||
+		    (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
+			dbg("refusing packet %x %x %x %x "
+			    "(suspected interleaved ps/2)\n",
+			    psmouse->packet[3], psmouse->packet[4],
+			    psmouse->packet[5], psmouse->packet[6]);
+			return PSMOUSE_BAD_DATA;
+		}
+
+		alps_process_packet(psmouse);
+
+		/* Continue with the next packet */
+		psmouse->packet[0] = psmouse->packet[6];
+		psmouse->pktcnt = 1;
+
+	} else {
+
+		/*
+		 * High bit is 0 - that means that we indeed got a PS/2
+		 * packet in the middle of ALPS packet.
+		 *
+		 * There is also possibility that we got 6-byte ALPS
+		 * packet followed  by 3-byte packet from trackpoint. We
+		 * can not distinguish between these 2 scenarios but
+		 * becase the latter is unlikely to happen in course of
+		 * normal operation (user would need to press all
+		 * buttons on the pad and start moving trackpoint
+		 * without touching the pad surface) we assume former.
+		 * Even if we are wrong the wost thing that would happen
+		 * the cursor would jump but we should not get protocol
+		 * desynchronization.
+		 */
+
+		alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
+					    false);
+
+		/*
+		 * Continue with the standard ALPS protocol handling,
+		 * but make sure we won't process it as an interleaved
+		 * packet again, which may happen if all buttons are
+		 * pressed. To avoid this let's reset the 4th bit which
+		 * is normally 1.
+		 */
+		psmouse->packet[3] = psmouse->packet[6] & 0xf7;
+		psmouse->pktcnt = 4;
+	}
+
+	return PSMOUSE_GOOD_DATA;
+}
+
+static void alps_flush_packet(unsigned long data)
+{
+	struct psmouse *psmouse = (struct psmouse *)data;
+
+	serio_pause_rx(psmouse->ps2dev.serio);
+
+	if (psmouse->pktcnt == 6) {
+
+		/*
+		 * We did not any more data in reasonable amount of time.
+		 * Validate the last 3 bytes and process as a standard
+		 * ALPS packet.
+		 */
+		if ((psmouse->packet[3] |
+		     psmouse->packet[4] |
+		     psmouse->packet[5]) & 0x80) {
+			dbg("refusing packet %x %x %x "
+			    "(suspected interleaved ps/2)\n",
+			    psmouse->packet[3], psmouse->packet[4],
+			    psmouse->packet[5]);
+		} else {
+			alps_process_packet(psmouse);
+		}
+		psmouse->pktcnt = 0;
+	}
+
+	serio_continue_rx(psmouse->ps2dev.serio);
+}
+
 static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
 
 	if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
 		if (psmouse->pktcnt == 3) {
-			alps_process_packet(psmouse);
+			alps_report_bare_ps2_packet(psmouse, psmouse->packet,
+						    true);
 			return PSMOUSE_FULL_PACKET;
 		}
 		return PSMOUSE_GOOD_DATA;
 	}
 
-	if ((psmouse->packet[0] & priv->i->mask0) != priv->i->byte0)
+	/* Check for PS/2 packet stuffed in the middle of ALPS packet. */
+
+	if ((model->flags & ALPS_PS2_INTERLEAVED) &&
+	    psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
+		return alps_handle_interleaved_ps2(psmouse);
+	}
+
+	if (!alps_is_valid_first_byte(model, psmouse->packet[0])) {
+		dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
+		    psmouse->packet[0], model->mask0, model->byte0);
 		return PSMOUSE_BAD_DATA;
+	}
 
 	/* Bytes 2 - 6 should have 0 in the highest bit */
 	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
-	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80))
+	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
+		dbg("refusing packet[%i] = %x\n",
+		    psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]);
 		return PSMOUSE_BAD_DATA;
+	}
 
 	if (psmouse->pktcnt == 6) {
 		alps_process_packet(psmouse);
@@ -393,15 +604,12 @@ static int alps_poll(struct psmouse *psm
 	return 0;
 }
 
-static int alps_hw_init(struct psmouse *psmouse, int *version)
+static int alps_hw_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+	const struct alps_model_info *model = priv->i;
 
-	priv->i = alps_get_model(psmouse, version);
-	if (!priv->i)
-		return -1;
-
-	if ((priv->i->flags & ALPS_PASS) &&
+	if ((model->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, true)) {
 		return -1;
 	}
@@ -416,7 +624,7 @@ static int alps_hw_init(struct psmouse *
 		return -1;
 	}
 
-	if ((priv->i->flags & ALPS_PASS) &&
+	if ((model->flags & ALPS_PASS) &&
 	    alps_passthrough_mode(psmouse, false)) {
 		return -1;
 	}
@@ -432,12 +640,15 @@ static int alps_hw_init(struct psmouse *
 
 static int alps_reconnect(struct psmouse *psmouse)
 {
+	const struct alps_model_info *model;
+
 	psmouse_reset(psmouse);
 
-	if (alps_hw_init(psmouse, NULL))
+	model = alps_get_model(psmouse, NULL);
+	if (!model)
 		return -1;
 
-	return 0;
+	return alps_hw_init(psmouse);
 }
 
 static void alps_disconnect(struct psmouse *psmouse)
@@ -445,6 +656,7 @@ static void alps_disconnect(struct psmou
 	struct alps_data *priv = psmouse->private;
 
 	psmouse_reset(psmouse);
+	del_timer_sync(&priv->timer);
 	input_unregister_device(priv->dev2);
 	kfree(priv);
 }
@@ -452,6 +664,7 @@ static void alps_disconnect(struct psmou
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
+	const struct alps_model_info *model;
 	struct input_dev *dev1 = psmouse->dev, *dev2;
 	int version;
 
@@ -461,35 +674,63 @@ int alps_init(struct psmouse *psmouse)
 		goto init_fail;
 
 	priv->dev2 = dev2;
+	setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
+
 	psmouse->private = priv;
 
-	if (alps_hw_init(psmouse, &version))
+	model = alps_get_model(psmouse, &version);
+	if (!model)
+		goto init_fail;
+
+	priv->i = model;
+
+	if (alps_hw_init(psmouse))
 		goto init_fail;
 
+	/*
+	 * Undo part of setup done for us by psmouse core since touchpad
+	 * is not a relative device.
+	 */
+	__clear_bit(EV_REL, dev1->evbit);
+	__clear_bit(REL_X, dev1->relbit);
+	__clear_bit(REL_Y, dev1->relbit);
+
+	/*
+	 * Now set up our capabilities.
+	 */
 	dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
 	dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
 	dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
-	dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	dev1->keybit[BIT_WORD(BTN_LEFT)] |=
+		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 
 	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
 	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
 
-	if (priv->i->flags & ALPS_WHEEL) {
+	if (model->flags & ALPS_WHEEL) {
 		dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
 		dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
 	}
 
-	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+	if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
 		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
 		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
 	}
 
+	if (model->flags & ALPS_FOUR_BUTTONS) {
+		dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
+		dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
+		dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
+		dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
+	} else {
+		dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
+	}
+
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
 	dev2->phys = priv->phys;
-	dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
+	dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
 	dev2->id.bustype = BUS_I8042;
 	dev2->id.vendor  = 0x0002;
 	dev2->id.product = PSMOUSE_ALPS;
@@ -497,9 +738,9 @@ int alps_init(struct psmouse *psmouse)
 	dev2->dev.parent = &psmouse->ps2dev.serio->dev;
 
 	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-	dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] =
+		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
 	if (input_register_device(priv->dev2))
 		goto init_fail;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/alps.h linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.h
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/alps.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/alps.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@ struct alps_data {
 	char phys[32];			/* Phys */
 	const struct alps_model_info *i;/* Info */
 	int prev_fin;			/* Finger bit from previous packet */
+	struct timer_list timer;
 };
 
 #ifdef CONFIG_MOUSE_PS2_ALPS
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/bcm5974.c linux-libre-2.6.33-gnu1/drivers/input/mouse/bcm5974.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/bcm5974.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/bcm5974.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,6 +139,7 @@ struct tp_finger {
 /* trackpad finger data size, empirically at least ten fingers */
 #define SIZEOF_FINGER		sizeof(struct tp_finger)
 #define SIZEOF_ALL_FINGERS	(16 * SIZEOF_FINGER)
+#define MAX_FINGER_ORIENTATION	16384
 
 /* device-specific parameters */
 struct bcm5974_param {
@@ -284,6 +285,26 @@ static void setup_events_to_report(struc
 	input_set_abs_params(input_dev, ABS_Y,
 				0, cfg->y.dim, cfg->y.fuzz, 0);
 
+	/* finger touch area */
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	/* finger approach area */
+	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
+			     cfg->w.devmin, cfg->w.devmax, 0, 0);
+	/* finger orientation */
+	input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
+			     -MAX_FINGER_ORIENTATION,
+			     MAX_FINGER_ORIENTATION, 0, 0);
+	/* finger position */
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+			     cfg->x.devmin, cfg->x.devmax, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+			     cfg->y.devmin, cfg->y.devmax, 0, 0);
+
 	__set_bit(EV_KEY, input_dev->evbit);
 	__set_bit(BTN_TOUCH, input_dev->keybit);
 	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
@@ -310,13 +331,29 @@ static int report_bt_state(struct bcm597
 	return 0;
 }
 
+static void report_finger_data(struct input_dev *input,
+			       const struct bcm5974_config *cfg,
+			       const struct tp_finger *f)
+{
+	input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major));
+	input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor));
+	input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major));
+	input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor));
+	input_report_abs(input, ABS_MT_ORIENTATION,
+			 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
+	input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
+	input_report_abs(input, ABS_MT_POSITION_Y,
+			 cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y));
+	input_mt_sync(input);
+}
+
 /* report trackpad data as logical trackpad state */
 static int report_tp_state(struct bcm5974 *dev, int size)
 {
 	const struct bcm5974_config *c = &dev->cfg;
 	const struct tp_finger *f;
 	struct input_dev *input = dev->input;
-	int raw_p, raw_w, raw_x, raw_y, raw_n;
+	int raw_p, raw_w, raw_x, raw_y, raw_n, i;
 	int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
 	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
 
@@ -329,6 +366,11 @@ static int report_tp_state(struct bcm597
 
 	/* always track the first finger; when detached, start over */
 	if (raw_n) {
+
+		/* report raw trackpad data */
+		for (i = 0; i < raw_n; i++)
+			report_finger_data(input, c, &f[i]);
+
 		raw_p = raw2int(f->force_major);
 		raw_w = raw2int(f->size_major);
 		raw_x = raw2int(f->abs_x);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/elantech.c linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/elantech.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/elantech.c	2010-02-24 13:52:17.000000000 -0500
@@ -420,6 +420,7 @@ static void elantech_set_input_params(st
 
 	__set_bit(EV_KEY, dev->evbit);
 	__set_bit(EV_ABS, dev->evbit);
+	__clear_bit(EV_REL, dev->evbit);
 
 	__set_bit(BTN_LEFT, dev->keybit);
 	__set_bit(BTN_RIGHT, dev->keybit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/hgpk.c linux-libre-2.6.33-gnu1/drivers/input/mouse/hgpk.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/hgpk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/hgpk.c	2010-02-24 13:52:17.000000000 -0500
@@ -427,22 +427,8 @@ static void hgpk_recalib_work(struct wor
 
 static int hgpk_register(struct psmouse *psmouse)
 {
-	struct input_dev *dev = psmouse->dev;
 	int err;
 
-	/* unset the things that psmouse-base sets which we don't have */
-	__clear_bit(BTN_MIDDLE, dev->keybit);
-
-	/* set the things we do have */
-	__set_bit(EV_KEY, dev->evbit);
-	__set_bit(EV_REL, dev->evbit);
-
-	__set_bit(REL_X, dev->relbit);
-	__set_bit(REL_Y, dev->relbit);
-
-	__set_bit(BTN_LEFT, dev->keybit);
-	__set_bit(BTN_RIGHT, dev->keybit);
-
 	/* register handlers */
 	psmouse->protocol_handler = hgpk_process_byte;
 	psmouse->poll = hgpk_poll;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/Kconfig linux-libre-2.6.33-gnu1/drivers/input/mouse/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS
 config MOUSE_PS2_LIFEBOOK
 	bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
 	default y
-	depends on MOUSE_PS2 && X86
+	depends on MOUSE_PS2 && X86 && DMI
 	help
 	  Say Y here if you have a Fujitsu B-series Lifebook PS/2
 	  TouchScreen connected to your system.
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/lifebook.c linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/lifebook.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,11 +25,13 @@ struct lifebook_data {
 	char phys[32];
 };
 
+static bool lifebook_present;
+
 static const char *desired_serio_phys;
 
-static int lifebook_set_serio_phys(const struct dmi_system_id *d)
+static int lifebook_limit_serio3(const struct dmi_system_id *d)
 {
-	desired_serio_phys = d->driver_data;
+	desired_serio_phys = "isa0060/serio3";
 	return 0;
 }
 
@@ -41,53 +43,58 @@ static int lifebook_set_6byte_proto(cons
 	return 0;
 }
 
-static const struct dmi_system_id lifebook_dmi_table[] = {
+static const struct dmi_system_id __initconst lifebook_dmi_table[] = {
 	{
-		.ident = "FLORA-ie 55mi",
+		/* FLORA-ie 55mi */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"),
 		},
 	},
 	{
-		.ident = "LifeBook B",
+		/* LifeBook B */
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "Lifebook B Series"),
+		},
+	},
+	{
+		/* LifeBook B */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"),
 		},
 	},
 	{
-		.ident = "Lifebook B",
+		/* Lifebook B */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
 		},
 	},
 	{
-		.ident = "Lifebook B-2130",
+		/* Lifebook B-2130 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"),
 		},
 	},
 	{
-		.ident = "Lifebook B213x/B2150",
+		/* Lifebook B213x/B2150 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"),
 		},
 	},
 	{
-		.ident = "Zephyr",
+		/* Zephyr */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"),
 		},
 	},
 	{
-		.ident = "CF-18",
+		/* Panasonic CF-18 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
 		},
-		.callback = lifebook_set_serio_phys,
-		.driver_data = "isa0060/serio3",
+		.callback = lifebook_limit_serio3,
 	},
 	{
-		.ident = "Panasonic CF-28",
+		/* Panasonic CF-28 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"),
@@ -95,7 +102,7 @@ static const struct dmi_system_id lifebo
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "Panasonic CF-29",
+		/* Panasonic CF-29 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
@@ -103,14 +110,14 @@ static const struct dmi_system_id lifebo
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "CF-72",
+		/* Panasonic CF-72 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"),
 		},
 		.callback = lifebook_set_6byte_proto,
 	},
 	{
-		.ident = "Lifebook B142",
+		/* Lifebook B142 */
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
 		},
@@ -118,6 +125,11 @@ static const struct dmi_system_id lifebo
 	{ }
 };
 
+void __init lifebook_module_init(void)
+{
+	lifebook_present = dmi_check_system(lifebook_dmi_table);
+}
+
 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 {
 	struct lifebook_data *priv = psmouse->private;
@@ -198,10 +210,10 @@ static int lifebook_absolute_mode(struct
 		return -1;
 
 	/*
-	   Enable absolute output -- ps2_command fails always but if
-	   you leave this call out the touchsreen will never send
-	   absolute coordinates
-	*/
+	 * Enable absolute output -- ps2_command fails always but if
+	 * you leave this call out the touchsreen will never send
+	 * absolute coordinates
+	 */
 	param = lifebook_use_6byte_proto ? 0x08 : 0x07;
 	ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
 
@@ -243,7 +255,7 @@ static void lifebook_disconnect(struct p
 
 int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
-        if (!dmi_check_system(lifebook_dmi_table))
+        if (!lifebook_present)
                 return -1;
 
 	if (desired_serio_phys &&
@@ -283,8 +295,8 @@ static int lifebook_create_relative_devi
 
 	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-	dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_RIGHT);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] =
+				BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 
 	error = input_register_device(priv->dev2);
 	if (error)
@@ -309,6 +321,7 @@ int lifebook_init(struct psmouse *psmous
 
 	dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
 	dev1->relbit[0] = 0;
+	dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0;
 	dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/lifebook.h linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.h
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/lifebook.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/lifebook.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,9 +12,13 @@
 #define _LIFEBOOK_H
 
 #ifdef CONFIG_MOUSE_PS2_LIFEBOOK
+void lifebook_module_init(void);
 int lifebook_detect(struct psmouse *psmouse, bool set_properties);
 int lifebook_init(struct psmouse *psmouse);
 #else
+inline void lifebook_module_init(void)
+{
+}
 inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/logips2pp.c linux-libre-2.6.33-gnu1/drivers/input/mouse/logips2pp.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/logips2pp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/logips2pp.c	2010-02-24 13:52:17.000000000 -0500
@@ -404,8 +404,8 @@ int ps2pp_init(struct psmouse *psmouse,
 			}
 		}
 
-		if (buttons < 3)
-			__clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		if (buttons >= 3)
+			__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/psmouse-base.c linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse-base.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/psmouse-base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/psmouse-base.c	2010-02-24 13:52:17.000000000 -0500
@@ -425,6 +425,7 @@ static int genius_detect(struct psmouse
 		return -1;
 
 	if (set_properties) {
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 		__set_bit(REL_WHEEL, psmouse->dev->relbit);
@@ -460,8 +461,10 @@ static int intellimouse_detect(struct ps
 		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(REL_WHEEL, psmouse->dev->relbit);
 
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Wheel Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Wheel Mouse";
 		psmouse->pktsize = 4;
 	}
 
@@ -504,8 +507,10 @@ static int im_explorer_detect(struct psm
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Explorer Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Explorer Mouse";
 		psmouse->pktsize = 4;
 	}
 
@@ -536,6 +541,7 @@ static int thinking_detect(struct psmous
 		return -1;
 
 	if (set_properties) {
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		psmouse->vendor = "Kensington";
@@ -551,8 +557,16 @@ static int thinking_detect(struct psmous
 static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
 {
 	if (set_properties) {
-		if (!psmouse->vendor) psmouse->vendor = "Generic";
-		if (!psmouse->name) psmouse->name = "Mouse";
+		if (!psmouse->vendor)
+			psmouse->vendor = "Generic";
+		if (!psmouse->name)
+			psmouse->name = "Mouse";
+
+/*
+ * We have no way of figuring true number of buttons so let's
+ * assume that the device has 3.
+ */
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 	}
 
 	return 0;
@@ -567,6 +581,8 @@ static int cortron_detect(struct psmouse
 	if (set_properties) {
 		psmouse->vendor = "Cortron";
 		psmouse->name = "PS/2 Trackball";
+
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 	}
 
@@ -611,8 +627,15 @@ static int psmouse_extensions(struct psm
 		synaptics_hardware = true;
 
 		if (max_proto > PSMOUSE_IMEX) {
-			if (!set_properties || synaptics_init(psmouse) == 0)
+/*
+ * Try activating protocol, but check if support is enabled first, since
+ * we try detecting Synaptics even when protocol is disabled.
+ */
+			if (synaptics_supported() &&
+			    (!set_properties || synaptics_init(psmouse) == 0)) {
 				return PSMOUSE_SYNAPTICS;
+			}
+
 /*
  * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
  * Unfortunately Logitech/Genius probes confuse some firmware versions so
@@ -667,19 +690,6 @@ static int psmouse_extensions(struct psm
 		max_proto = PSMOUSE_IMEX;
 	}
 
-/*
- * Try Finger Sensing Pad
- */
-	if (max_proto > PSMOUSE_IMEX) {
-		if (fsp_detect(psmouse, set_properties) == 0) {
-			if (!set_properties || fsp_init(psmouse) == 0)
-				return PSMOUSE_FSP;
-/*
- * Init failed, try basic relative protocols
- */
-			max_proto = PSMOUSE_IMEX;
-		}
-	}
 
 	if (max_proto > PSMOUSE_IMEX) {
 		if (genius_detect(psmouse, set_properties) == 0)
@@ -696,6 +706,21 @@ static int psmouse_extensions(struct psm
 	}
 
 /*
+ * Try Finger Sensing Pad. We do it here because its probe upsets
+ * Trackpoint devices (causing TP_READ_ID command to time out).
+ */
+	if (max_proto > PSMOUSE_IMEX) {
+		if (fsp_detect(psmouse, set_properties) == 0) {
+			if (!set_properties || fsp_init(psmouse) == 0)
+				return PSMOUSE_FSP;
+/*
+ * Init failed, try basic relative protocols
+ */
+			max_proto = PSMOUSE_IMEX;
+		}
+	}
+
+/*
  * Reset to defaults in case the device got confused by extended
  * protocol probes. Note that we follow up with full reset because
  * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
@@ -1116,12 +1141,22 @@ static void psmouse_cleanup(struct serio
 		psmouse_deactivate(parent);
 	}
 
-	psmouse_deactivate(psmouse);
+	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+	/*
+	 * Disable stream mode so cleanup routine can proceed undisturbed.
+	 */
+	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE))
+		printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n",
+			psmouse->ps2dev.serio->phys);
 
 	if (psmouse->cleanup)
 		psmouse->cleanup(psmouse);
 
-	psmouse_reset(psmouse);
+/*
+ * Reset the mouse to defaults (bare PS/2 protocol).
+ */
+	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 
 /*
  * Some boxes, such as HP nx7400, get terribly confused if mouse
@@ -1184,15 +1219,16 @@ static void psmouse_disconnect(struct se
 	mutex_unlock(&psmouse_mutex);
 }
 
-static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto)
+static int psmouse_switch_protocol(struct psmouse *psmouse,
+				   const struct psmouse_protocol *proto)
 {
 	struct input_dev *input_dev = psmouse->dev;
 
 	input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
-		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
+				BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	psmouse->set_rate = psmouse_set_rate;
@@ -1209,8 +1245,7 @@ static int psmouse_switch_protocol(struc
 			return -1;
 
 		psmouse->type = proto->type;
-	}
-	else
+	} else
 		psmouse->type = psmouse_extensions(psmouse,
 						   psmouse_max_proto, true);
 
@@ -1431,24 +1466,10 @@ ssize_t psmouse_attr_show_helper(struct
 	struct serio *serio = to_serio_port(dev);
 	struct psmouse_attribute *attr = to_psmouse_attr(devattr);
 	struct psmouse *psmouse;
-	int retval;
-
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &psmouse_drv) {
-		retval = -ENODEV;
-		goto out;
-	}
 
 	psmouse = serio_get_drvdata(serio);
 
-	retval = attr->show(psmouse, attr->data, buf);
-
-out:
-	serio_unpin_driver(serio);
-	return retval;
+	return attr->show(psmouse, attr->data, buf);
 }
 
 ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr,
@@ -1459,18 +1480,9 @@ ssize_t psmouse_attr_set_helper(struct d
 	struct psmouse *psmouse, *parent = NULL;
 	int retval;
 
-	retval = serio_pin_driver(serio);
-	if (retval)
-		return retval;
-
-	if (serio->drv != &psmouse_drv) {
-		retval = -ENODEV;
-		goto out_unpin;
-	}
-
 	retval = mutex_lock_interruptible(&psmouse_mutex);
 	if (retval)
-		goto out_unpin;
+		goto out;
 
 	psmouse = serio_get_drvdata(serio);
 
@@ -1500,8 +1512,7 @@ ssize_t psmouse_attr_set_helper(struct d
 
  out_unlock:
 	mutex_unlock(&psmouse_mutex);
- out_unpin:
-	serio_unpin_driver(serio);
+ out:
 	return retval;
 }
 
@@ -1563,9 +1574,7 @@ static ssize_t psmouse_attr_set_protocol
 		}
 
 		mutex_unlock(&psmouse_mutex);
-		serio_unpin_driver(serio);
 		serio_unregister_child_port(serio);
-		serio_pin_driver_uninterruptible(serio);
 		mutex_lock(&psmouse_mutex);
 
 		if (serio->drv != &psmouse_drv) {
@@ -1680,6 +1689,9 @@ static int __init psmouse_init(void)
 {
 	int err;
 
+	lifebook_module_init();
+	synaptics_module_init();
+
 	kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
 	if (!kpsmoused_wq) {
 		printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/sentelic.c linux-libre-2.6.33-gnu1/drivers/input/mouse/sentelic.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/sentelic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/sentelic.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  * Finger Sensing Pad PS/2 mouse driver.
  *
  * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
- * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation.
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
@@ -658,9 +658,9 @@ static psmouse_ret_t fsp_process_byte(st
 			if (packet[3] & BIT(1))
 				button_status |= 0x0f;	/* wheel up */
 			if (packet[3] & BIT(2))
-				button_status |= BIT(5);/* horizontal left */
+				button_status |= BIT(4);/* horizontal left */
 			if (packet[3] & BIT(3))
-				button_status |= BIT(4);/* horizontal right */
+				button_status |= BIT(5);/* horizontal right */
 			/* push back to packet queue */
 			if (button_status != 0)
 				packet[3] = button_status;
@@ -836,6 +836,7 @@ int fsp_init(struct psmouse *psmouse)
 	priv->flags |= FSPDRV_FLAG_EN_OPC;
 
 	/* Set up various supported input event bits */
+	__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 	__set_bit(BTN_BACK, psmouse->dev->keybit);
 	__set_bit(BTN_FORWARD, psmouse->dev->keybit);
 	__set_bit(REL_WHEEL, psmouse->dev->relbit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics.c linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
@@ -629,25 +630,26 @@ static int synaptics_reconnect(struct ps
 	return 0;
 }
 
-#if defined(__i386__)
-#include <linux/dmi.h>
-static const struct dmi_system_id toshiba_dmi_table[] = {
+static bool impaired_toshiba_kbc;
+
+static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
 	{
-		.ident = "Toshiba Satellite",
+		/* Toshiba Satellite */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
 		},
 	},
 	{
-		.ident = "Toshiba Dynabook",
+		/* Toshiba Dynabook */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
 		},
 	},
 	{
-		.ident = "Toshiba Portege M300",
+		/* Toshiba Portege M300 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
@@ -655,7 +657,7 @@ static const struct dmi_system_id toshib
 
 	},
 	{
-		.ident = "Toshiba Portege M300",
+		/* Toshiba Portege M300 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
@@ -664,8 +666,13 @@ static const struct dmi_system_id toshib
 
 	},
 	{ }
-};
 #endif
+};
+
+void __init synaptics_module_init(void)
+{
+	impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
+}
 
 int synaptics_init(struct psmouse *psmouse)
 {
@@ -718,18 +725,16 @@ int synaptics_init(struct psmouse *psmou
 	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
 		synaptics_pt_create(psmouse);
 
-#if defined(__i386__)
 	/*
 	 * Toshiba's KBC seems to have trouble handling data from
 	 * Synaptics as full rate, switch to lower rate which is roughly
 	 * thye same as rate of standard PS/2 mouse.
 	 */
-	if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) {
+	if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
 		printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
 			dmi_get_system_info(DMI_PRODUCT_NAME));
 		psmouse->rate = 40;
 	}
-#endif
 
 	return 0;
 
@@ -738,12 +743,26 @@ int synaptics_init(struct psmouse *psmou
 	return -1;
 }
 
+bool synaptics_supported(void)
+{
+	return true;
+}
+
 #else /* CONFIG_MOUSE_PS2_SYNAPTICS */
 
+void __init synaptics_module_init(void)
+{
+}
+
 int synaptics_init(struct psmouse *psmouse)
 {
 	return -ENOSYS;
 }
 
+bool synaptics_supported(void)
+{
+	return false;
+}
+
 #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics.h linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.h
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics.h	2010-02-24 13:52:17.000000000 -0500
@@ -105,8 +105,10 @@ struct synaptics_data {
 	int scroll;
 };
 
+void synaptics_module_init(void);
 int synaptics_detect(struct psmouse *psmouse, bool set_properties);
 int synaptics_init(struct psmouse *psmouse);
 void synaptics_reset(struct psmouse *psmouse);
+bool synaptics_supported(void);
 
 #endif /* _SYNAPTICS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics_i2c.c linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/synaptics_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/synaptics_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -420,8 +420,8 @@ static void synaptics_i2c_check_params(s
 }
 
 /* Control the Device polling rate / Work Handler sleep time */
-unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch,
-					 bool have_data)
+static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch,
+						bool have_data)
 {
 	unsigned long delay, nodata_count_thres;
 
@@ -520,7 +520,7 @@ static void synaptics_i2c_set_input_para
 	__set_bit(BTN_LEFT, input->keybit);
 }
 
-struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
+static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
 {
 	struct synaptics_i2c *touch;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/touchkit_ps2.c linux-libre-2.6.33-gnu1/drivers/input/mouse/touchkit_ps2.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/touchkit_ps2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/touchkit_ps2.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,7 +86,8 @@ int touchkit_ps2_detect(struct psmouse *
 
 	if (set_properties) {
 		dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-		__set_bit(BTN_TOUCH, dev->keybit);
+		dev->keybit[BIT_WORD(BTN_MOUSE)] = 0;
+		dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 		input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
 		input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/trackpoint.c linux-libre-2.6.33-gnu1/drivers/input/mouse/trackpoint.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/trackpoint.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/trackpoint.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,7 +284,6 @@ static int trackpoint_reconnect(struct p
 
 int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 {
-	struct trackpoint_data *priv;
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char firmware_id;
 	unsigned char button_info;
@@ -301,8 +300,8 @@ int trackpoint_detect(struct psmouse *ps
 		button_info = 0;
 	}
 
-	psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
-	if (!priv)
+	psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
+	if (!psmouse->private)
 		return -1;
 
 	psmouse->vendor = "IBM";
@@ -311,7 +310,10 @@ int trackpoint_detect(struct psmouse *ps
 	psmouse->reconnect = trackpoint_reconnect;
 	psmouse->disconnect = trackpoint_disconnect;
 
-	trackpoint_defaults(priv);
+	if ((button_info & 0x0f) >= 3)
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+
+	trackpoint_defaults(psmouse->private);
 	trackpoint_sync(psmouse);
 
 	error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
@@ -319,7 +321,8 @@ int trackpoint_detect(struct psmouse *ps
 		printk(KERN_ERR
 			"trackpoint.c: failed to create sysfs attributes, error: %d\n",
 			error);
-		kfree(priv);
+		kfree(psmouse->private);
+		psmouse->private = NULL;
 		return -1;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/mouse/vsxxxaa.c linux-libre-2.6.33-gnu1/drivers/input/mouse/vsxxxaa.c
--- linux-libre-2.6.32-gnu1/drivers/input/mouse/vsxxxaa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/mouse/vsxxxaa.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,27 +86,28 @@
 
 #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
 
-MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 #undef VSXXXAA_DEBUG
 #ifdef VSXXXAA_DEBUG
-#define DBG(x...) printk (x)
+#define DBG(x...) printk(x)
 #else
 #define DBG(x...) do {} while (0)
 #endif
 
 #define VSXXXAA_INTRO_MASK	0x80
 #define VSXXXAA_INTRO_HEAD	0x80
-#define IS_HDR_BYTE(x)		(((x) & VSXXXAA_INTRO_MASK)	\
-					== VSXXXAA_INTRO_HEAD)
+#define IS_HDR_BYTE(x)			\
+	(((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD)
 
 #define VSXXXAA_PACKET_MASK	0xe0
 #define VSXXXAA_PACKET_REL	0x80
 #define VSXXXAA_PACKET_ABS	0xc0
 #define VSXXXAA_PACKET_POR	0xa0
-#define MATCH_PACKET_TYPE(data, type)	(((data) & VSXXXAA_PACKET_MASK) == (type))
+#define MATCH_PACKET_TYPE(data, type)	\
+	(((data) & VSXXXAA_PACKET_MASK) == (type))
 
 
 
@@ -123,52 +124,50 @@ struct vsxxxaa {
 	char phys[32];
 };
 
-static void
-vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num)
+static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num)
 {
-	if (num >= mouse->count)
+	if (num >= mouse->count) {
 		mouse->count = 0;
-	else {
-		memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num);
+	} else {
+		memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num);
 		mouse->count -= num;
 	}
 }
 
-static void
-vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte)
+static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte)
 {
 	if (mouse->count == BUFLEN) {
-		printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
-				mouse->name, mouse->phys);
-		vsxxxaa_drop_bytes (mouse, 1);
+		printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n",
+			mouse->name, mouse->phys);
+		vsxxxaa_drop_bytes(mouse, 1);
 	}
-	DBG (KERN_INFO "Queueing byte 0x%02x\n", byte);
+
+	DBG(KERN_INFO "Queueing byte 0x%02x\n", byte);
 
 	mouse->buf[mouse->count++] = byte;
 }
 
-static void
-vsxxxaa_detection_done (struct vsxxxaa *mouse)
+static void vsxxxaa_detection_done(struct vsxxxaa *mouse)
 {
 	switch (mouse->type) {
-		case 0x02:
-			strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse",
-				 sizeof (mouse->name));
-			break;
+	case 0x02:
+		strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse",
+			sizeof(mouse->name));
+		break;
 
-		case 0x04:
-			strlcpy (mouse->name, "DEC VSXXX-AB digitizer",
-				 sizeof (mouse->name));
-			break;
+	case 0x04:
+		strlcpy(mouse->name, "DEC VSXXX-AB digitizer",
+			sizeof(mouse->name));
+		break;
 
-		default:
-			snprintf (mouse->name, sizeof (mouse->name),
-				  "unknown DEC pointer device (type = 0x%02x)",
-				  mouse->type);
-			break;
+	default:
+		snprintf(mouse->name, sizeof(mouse->name),
+			 "unknown DEC pointer device (type = 0x%02x)",
+			 mouse->type);
+		break;
 	}
 
-	printk (KERN_INFO
+	printk(KERN_INFO
 		"Found %s version 0x%02x from country 0x%02x on port %s\n",
 		mouse->name, mouse->version, mouse->country, mouse->phys);
 }
@@ -176,42 +175,38 @@ vsxxxaa_detection_done (struct vsxxxaa *
 /*
  * Returns number of bytes to be dropped, 0 if packet is okay.
  */
-static int
-vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len)
+static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len)
 {
 	int i;
 
 	/* First byte must be a header byte */
-	if (!IS_HDR_BYTE (mouse->buf[0])) {
-		DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
+	if (!IS_HDR_BYTE(mouse->buf[0])) {
+		DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]);
 		return 1;
 	}
 
 	/* Check all following bytes */
-	if (packet_len > 1) {
-		for (i = 1; i < packet_len; i++) {
-			if (IS_HDR_BYTE (mouse->buf[i])) {
-				printk (KERN_ERR "Need to drop %d bytes "
-						"of a broken packet.\n",
-						i - 1);
-				DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
-						packet_len, i, mouse->buf[i]);
-				return i - 1;
-			}
+	for (i = 1; i < packet_len; i++) {
+		if (IS_HDR_BYTE(mouse->buf[i])) {
+			printk(KERN_ERR
+				"Need to drop %d bytes of a broken packet.\n",
+				i - 1);
+			DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n",
+			    packet_len, i, mouse->buf[i]);
+			return i - 1;
 		}
 	}
 
 	return 0;
 }
 
-static __inline__ int
-vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len)
+static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse,
+					     unsigned char type, size_t len)
 {
-	return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type);
+	return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type);
 }
 
-static void
-vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -232,43 +227,42 @@ vsxxxaa_handle_REL_packet (struct vsxxxa
 	 * 0, bit 4 of byte 0 is direction.
 	 */
 	dx = buf[1] & 0x7f;
-	dx *= ((buf[0] >> 4) & 0x01)? 1: -1;
+	dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1;
 
 	/*
 	 * Low 7 bit of byte 2 are abs(dy), bit 7 is
 	 * 0, bit 3 of byte 0 is direction.
 	 */
 	dy = buf[2] & 0x7f;
-	dy *= ((buf[0] >> 3) & 0x01)? -1: 1;
+	dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1;
 
 	/*
 	 * Get button state. It's the low three bits
 	 * (for three buttons) of byte 0.
 	 */
-	left	= (buf[0] & 0x04)? 1: 0;
-	middle	= (buf[0] & 0x02)? 1: 0;
-	right	= (buf[0] & 0x01)? 1: 0;
+	left	= buf[0] & 0x04;
+	middle	= buf[0] & 0x02;
+	right	= buf[0] & 0x01;
 
-	vsxxxaa_drop_bytes (mouse, 3);
+	vsxxxaa_drop_bytes(mouse, 3);
 
-	DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
-			mouse->name, mouse->phys, dx, dy,
-			left? "L": "l", middle? "M": "m", right? "R": "r");
+	DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n",
+	    mouse->name, mouse->phys, dx, dy,
+	    left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r");
 
 	/*
 	 * Report what we've found so far...
 	 */
-	input_report_key (dev, BTN_LEFT, left);
-	input_report_key (dev, BTN_MIDDLE, middle);
-	input_report_key (dev, BTN_RIGHT, right);
-	input_report_key (dev, BTN_TOUCH, 0);
-	input_report_rel (dev, REL_X, dx);
-	input_report_rel (dev, REL_Y, dy);
-	input_sync (dev);
+	input_report_key(dev, BTN_LEFT, left);
+	input_report_key(dev, BTN_MIDDLE, middle);
+	input_report_key(dev, BTN_RIGHT, right);
+	input_report_key(dev, BTN_TOUCH, 0);
+	input_report_rel(dev, REL_X, dx);
+	input_report_rel(dev, REL_Y, dy);
+	input_sync(dev);
 }
 
-static void
-vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -296,32 +290,31 @@ vsxxxaa_handle_ABS_packet (struct vsxxxa
 	/*
 	 * Get button state. It's bits <4..1> of byte 0.
 	 */
-	left	= (buf[0] & 0x02)? 1: 0;
-	middle	= (buf[0] & 0x04)? 1: 0;
-	right	= (buf[0] & 0x08)? 1: 0;
-	touch	= (buf[0] & 0x10)? 1: 0;
+	left	= buf[0] & 0x02;
+	middle	= buf[0] & 0x04;
+	right	= buf[0] & 0x08;
+	touch	= buf[0] & 0x10;
 
-	vsxxxaa_drop_bytes (mouse, 5);
+	vsxxxaa_drop_bytes(mouse, 5);
 
-	DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
-			mouse->name, mouse->phys, x, y,
-			left? "L": "l", middle? "M": "m",
-			right? "R": "r", touch? "T": "t");
+	DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n",
+	    mouse->name, mouse->phys, x, y,
+	    left ? "L" : "l", middle ? "M" : "m",
+	    right ? "R" : "r", touch ? "T" : "t");
 
 	/*
 	 * Report what we've found so far...
 	 */
-	input_report_key (dev, BTN_LEFT, left);
-	input_report_key (dev, BTN_MIDDLE, middle);
-	input_report_key (dev, BTN_RIGHT, right);
-	input_report_key (dev, BTN_TOUCH, touch);
-	input_report_abs (dev, ABS_X, x);
-	input_report_abs (dev, ABS_Y, y);
-	input_sync (dev);
+	input_report_key(dev, BTN_LEFT, left);
+	input_report_key(dev, BTN_MIDDLE, middle);
+	input_report_key(dev, BTN_RIGHT, right);
+	input_report_key(dev, BTN_TOUCH, touch);
+	input_report_abs(dev, ABS_X, x);
+	input_report_abs(dev, ABS_Y, y);
+	input_sync(dev);
 }
 
-static void
-vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
+static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse)
 {
 	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
@@ -356,24 +349,24 @@ vsxxxaa_handle_POR_packet (struct vsxxxa
 	 * (for three buttons) of byte 0. Maybe even the bit <3>
 	 * has some meaning if a tablet is attached.
 	 */
-	left	= (buf[0] & 0x04)? 1: 0;
-	middle	= (buf[0] & 0x02)? 1: 0;
-	right	= (buf[0] & 0x01)? 1: 0;
+	left	= buf[0] & 0x04;
+	middle	= buf[0] & 0x02;
+	right	= buf[0] & 0x01;
 
-	vsxxxaa_drop_bytes (mouse, 4);
-	vsxxxaa_detection_done (mouse);
+	vsxxxaa_drop_bytes(mouse, 4);
+	vsxxxaa_detection_done(mouse);
 
 	if (error <= 0x1f) {
 		/* No (serious) error. Report buttons */
-		input_report_key (dev, BTN_LEFT, left);
-		input_report_key (dev, BTN_MIDDLE, middle);
-		input_report_key (dev, BTN_RIGHT, right);
-		input_report_key (dev, BTN_TOUCH, 0);
-		input_sync (dev);
+		input_report_key(dev, BTN_LEFT, left);
+		input_report_key(dev, BTN_MIDDLE, middle);
+		input_report_key(dev, BTN_RIGHT, right);
+		input_report_key(dev, BTN_TOUCH, 0);
+		input_sync(dev);
 
 		if (error != 0)
-			printk (KERN_INFO "Your %s on %s reports error=0x%02x\n",
-					mouse->name, mouse->phys, error);
+			printk(KERN_INFO "Your %s on %s reports error=0x%02x\n",
+				mouse->name, mouse->phys, error);
 
 	}
 
@@ -381,18 +374,18 @@ vsxxxaa_handle_POR_packet (struct vsxxxa
 	 * If the mouse was hot-plugged, we need to force differential mode
 	 * now... However, give it a second to recover from it's reset.
 	 */
-	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
-			"incremental streaming mode and 72 samples/sec\n",
-			mouse->name, mouse->phys);
-	serio_write (mouse->serio, 'S');	/* Standard format */
-	mdelay (50);
-	serio_write (mouse->serio, 'R');	/* Incremental */
-	mdelay (50);
-	serio_write (mouse->serio, 'L');	/* 72 samples/sec */
+	printk(KERN_NOTICE
+		"%s on %s: Forcing standard packet format, "
+		"incremental streaming mode and 72 samples/sec\n",
+		mouse->name, mouse->phys);
+	serio_write(mouse->serio, 'S');	/* Standard format */
+	mdelay(50);
+	serio_write(mouse->serio, 'R');	/* Incremental */
+	mdelay(50);
+	serio_write(mouse->serio, 'L');	/* 72 samples/sec */
 }
 
-static void
-vsxxxaa_parse_buffer (struct vsxxxaa *mouse)
+static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse)
 {
 	unsigned char *buf = mouse->buf;
 	int stray_bytes;
@@ -409,122 +402,107 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mo
 		 * activity on the mouse.
 		 */
 		while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) {
-			printk (KERN_ERR "%s on %s: Dropping a byte to regain "
-					"sync with mouse data stream...\n",
-					mouse->name, mouse->phys);
-			vsxxxaa_drop_bytes (mouse, 1);
+			printk(KERN_ERR "%s on %s: Dropping a byte to regain "
+				"sync with mouse data stream...\n",
+				mouse->name, mouse->phys);
+			vsxxxaa_drop_bytes(mouse, 1);
 		}
 
 		/*
 		 * Check for packets we know about.
 		 */
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) {
+		if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) {
 			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 3);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
+			stray_bytes = vsxxxaa_check_packet(mouse, 3);
+			if (!stray_bytes)
+				vsxxxaa_handle_REL_packet(mouse);
 
-			vsxxxaa_handle_REL_packet (mouse);
-			continue; /* More to parse? */
-		}
+		} else if (vsxxxaa_smells_like_packet(mouse,
+						      VSXXXAA_PACKET_ABS, 5)) {
+			/* Check for broken packet */
+			stray_bytes = vsxxxaa_check_packet(mouse, 5);
+			if (!stray_bytes)
+				vsxxxaa_handle_ABS_packet(mouse);
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) {
+		} else if (vsxxxaa_smells_like_packet(mouse,
+						      VSXXXAA_PACKET_POR, 4)) {
 			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 5);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
+			stray_bytes = vsxxxaa_check_packet(mouse, 4);
+			if (!stray_bytes)
+				vsxxxaa_handle_POR_packet(mouse);
 
-			vsxxxaa_handle_ABS_packet (mouse);
-			continue; /* More to parse? */
+		} else {
+			break; /* No REL, ABS or POR packet found */
 		}
 
-		if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) {
-			/* Check for broken packet */
-			stray_bytes = vsxxxaa_check_packet (mouse, 4);
-			if (stray_bytes > 0) {
-				printk (KERN_ERR "Dropping %d bytes now...\n",
-						stray_bytes);
-				vsxxxaa_drop_bytes (mouse, stray_bytes);
-				continue;
-			}
-
-			vsxxxaa_handle_POR_packet (mouse);
-			continue; /* More to parse? */
+		if (stray_bytes > 0) {
+			printk(KERN_ERR "Dropping %d bytes now...\n",
+				stray_bytes);
+			vsxxxaa_drop_bytes(mouse, stray_bytes);
 		}
 
-		break; /* No REL, ABS or POR packet found */
 	} while (1);
 }
 
-static irqreturn_t
-vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
+static irqreturn_t vsxxxaa_interrupt(struct serio *serio,
+				     unsigned char data, unsigned int flags)
 {
-	struct vsxxxaa *mouse = serio_get_drvdata (serio);
+	struct vsxxxaa *mouse = serio_get_drvdata(serio);
 
-	vsxxxaa_queue_byte (mouse, data);
-	vsxxxaa_parse_buffer (mouse);
+	vsxxxaa_queue_byte(mouse, data);
+	vsxxxaa_parse_buffer(mouse);
 
 	return IRQ_HANDLED;
 }
 
-static void
-vsxxxaa_disconnect (struct serio *serio)
+static void vsxxxaa_disconnect(struct serio *serio)
 {
-	struct vsxxxaa *mouse = serio_get_drvdata (serio);
+	struct vsxxxaa *mouse = serio_get_drvdata(serio);
 
-	serio_close (serio);
-	serio_set_drvdata (serio, NULL);
-	input_unregister_device (mouse->dev);
-	kfree (mouse);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_unregister_device(mouse->dev);
+	kfree(mouse);
 }
 
-static int
-vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
+static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct vsxxxaa *mouse;
 	struct input_dev *input_dev;
 	int err = -ENOMEM;
 
-	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
-	input_dev = input_allocate_device ();
+	mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL);
+	input_dev = input_allocate_device();
 	if (!mouse || !input_dev)
 		goto fail1;
 
 	mouse->dev = input_dev;
 	mouse->serio = serio;
-	strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
-		 sizeof (mouse->name));
-	snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys);
+	strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
+		 sizeof(mouse->name));
+	snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys);
 
 	input_dev->name = mouse->name;
 	input_dev->phys = mouse->phys;
 	input_dev->id.bustype = BUS_RS232;
 	input_dev->dev.parent = &serio->dev;
 
-	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
-	set_bit (EV_REL, input_dev->evbit);
-	set_bit (EV_ABS, input_dev->evbit);
-	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
-	set_bit (BTN_MIDDLE, input_dev->keybit);
-	set_bit (BTN_RIGHT, input_dev->keybit);
-	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
-	set_bit (REL_X, input_dev->relbit);
-	set_bit (REL_Y, input_dev->relbit);
-	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
-	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
+	__set_bit(EV_KEY, input_dev->evbit);		/* We have buttons */
+	__set_bit(EV_REL, input_dev->evbit);
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
+	__set_bit(BTN_MIDDLE, input_dev->keybit);
+	__set_bit(BTN_RIGHT, input_dev->keybit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);	/* ...and Tablet */
+	__set_bit(REL_X, input_dev->relbit);
+	__set_bit(REL_Y, input_dev->relbit);
+	input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
 
-	serio_set_drvdata (serio, mouse);
+	serio_set_drvdata(serio, mouse);
 
-	err = serio_open (serio, drv);
+	err = serio_open(serio, drv);
 	if (err)
 		goto fail2;
 
@@ -532,18 +510,18 @@ vsxxxaa_connect (struct serio *serio, st
 	 * Request selftest. Standard packet format and differential
 	 * mode will be requested after the device ID'ed successfully.
 	 */
-	serio_write (serio, 'T'); /* Test */
+	serio_write(serio, 'T'); /* Test */
 
-	err = input_register_device (input_dev);
+	err = input_register_device(input_dev);
 	if (err)
 		goto fail3;
 
 	return 0;
 
- fail3:	serio_close (serio);
- fail2:	serio_set_drvdata (serio, NULL);
- fail1:	input_free_device (input_dev);
-	kfree (mouse);
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(mouse);
 	return err;
 }
 
@@ -570,18 +548,16 @@ static struct serio_driver vsxxxaa_drv =
 	.disconnect	= vsxxxaa_disconnect,
 };
 
-static int __init
-vsxxxaa_init (void)
+static int __init vsxxxaa_init(void)
 {
 	return serio_register_driver(&vsxxxaa_drv);
 }
 
-static void __exit
-vsxxxaa_exit (void)
+static void __exit vsxxxaa_exit(void)
 {
 	serio_unregister_driver(&vsxxxaa_drv);
 }
 
-module_init (vsxxxaa_init);
-module_exit (vsxxxaa_exit);
+module_init(vsxxxaa_init);
+module_exit(vsxxxaa_exit);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/altera_ps2.c linux-libre-2.6.33-gnu1/drivers/input/serio/altera_ps2.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/altera_ps2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/altera_ps2.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,203 @@
+/*
+ * Altera University Program PS2 controller driver
+ *
+ * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * Based on sa1111ps2.c, which is:
+ * Copyright (C) 2002 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/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_NAME "altera_ps2"
+
+struct ps2if {
+	struct serio *io;
+	struct resource *iomem_res;
+	void __iomem *base;
+	unsigned irq;
+};
+
+/*
+ * Read all bytes waiting in the PS2 port.  There should be
+ * at the most one, but we loop for safety.
+ */
+static irqreturn_t altera_ps2_rxint(int irq, void *dev_id)
+{
+	struct ps2if *ps2if = dev_id;
+	unsigned int status;
+	int handled = IRQ_NONE;
+
+	while ((status = readl(ps2if->base)) & 0xffff0000) {
+		serio_interrupt(ps2if->io, status & 0xff, 0);
+		handled = IRQ_HANDLED;
+	}
+
+	return handled;
+}
+
+/*
+ * Write a byte to the PS2 port.
+ */
+static int altera_ps2_write(struct serio *io, unsigned char val)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	writel(val, ps2if->base);
+	return 0;
+}
+
+static int altera_ps2_open(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	/* clear fifo */
+	while (readl(ps2if->base) & 0xffff0000)
+		/* empty */;
+
+	writel(1, ps2if->base + 4); /* enable rx irq */
+	return 0;
+}
+
+static void altera_ps2_close(struct serio *io)
+{
+	struct ps2if *ps2if = io->port_data;
+
+	writel(0, ps2if->base); /* disable rx irq */
+}
+
+/*
+ * Add one device to this driver.
+ */
+static int __devinit altera_ps2_probe(struct platform_device *pdev)
+{
+	struct ps2if *ps2if;
+	struct serio *serio;
+	int error, irq;
+
+	ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
+	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2if || !serio) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	serio->id.type		= SERIO_8042;
+	serio->write		= altera_ps2_write;
+	serio->open		= altera_ps2_open;
+	serio->close		= altera_ps2_close;
+	strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name));
+	strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
+	serio->port_data	= ps2if;
+	serio->dev.parent	= &pdev->dev;
+	ps2if->io		= serio;
+
+	ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (ps2if->iomem_res == NULL) {
+		error = -ENOENT;
+		goto err_free_mem;
+	}
+
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		error = -ENXIO;
+		goto err_free_mem;
+	}
+	ps2if->irq = irq;
+
+	if (!request_mem_region(ps2if->iomem_res->start,
+				resource_size(ps2if->iomem_res), pdev->name)) {
+		error = -EBUSY;
+		goto err_free_mem;
+	}
+
+	ps2if->base = ioremap(ps2if->iomem_res->start,
+			      resource_size(ps2if->iomem_res));
+	if (!ps2if->base) {
+		error = -ENOMEM;
+		goto err_free_res;
+	}
+
+	error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if);
+	if (error) {
+		dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n",
+			ps2if->irq, error);
+		goto err_unmap;
+	}
+
+	dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq);
+
+	serio_register_port(ps2if->io);
+	platform_set_drvdata(pdev, ps2if);
+
+	return 0;
+
+ err_unmap:
+	iounmap(ps2if->base);
+ err_free_res:
+	release_mem_region(ps2if->iomem_res->start,
+			   resource_size(ps2if->iomem_res));
+ err_free_mem:
+	kfree(ps2if);
+	kfree(serio);
+	return error;
+}
+
+/*
+ * Remove one device from this driver.
+ */
+static int __devexit altera_ps2_remove(struct platform_device *pdev)
+{
+	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);
+	release_mem_region(ps2if->iomem_res->start,
+			   resource_size(ps2if->iomem_res));
+	kfree(ps2if);
+
+	return 0;
+}
+
+/*
+ * Our device driver structure
+ */
+static struct platform_driver altera_ps2_driver = {
+	.probe		= altera_ps2_probe,
+	.remove		= __devexit_p(altera_ps2_remove),
+	.driver	= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init altera_ps2_init(void)
+{
+	return platform_driver_register(&altera_ps2_driver);
+}
+
+static void __exit altera_ps2_exit(void)
+{
+	platform_driver_unregister(&altera_ps2_driver);
+}
+
+module_init(altera_ps2_init);
+module_exit(altera_ps2_exit);
+
+MODULE_DESCRIPTION("Altera University Program PS2 controller driver");
+MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/ambakmi.c linux-libre-2.6.33-gnu1/drivers/input/serio/ambakmi.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/ambakmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/ambakmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio
 	clk_disable(kmi->clk);
 }
 
-static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id)
+static int __devinit amba_kmi_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct amba_kmi_port *kmi;
 	struct serio *io;
@@ -134,7 +134,7 @@ static int amba_kmi_probe(struct amba_de
 	io->port_data	= kmi;
 	io->dev.parent	= &dev->dev;
 
-	kmi->io 	= io;
+	kmi->io		= io;
 	kmi->base	= ioremap(dev->res.start, resource_size(&dev->res));
 	if (!kmi->base) {
 		ret = -ENOMEM;
@@ -162,7 +162,7 @@ static int amba_kmi_probe(struct amba_de
 	return ret;
 }
 
-static int amba_kmi_remove(struct amba_device *dev)
+static int __devexit amba_kmi_remove(struct amba_device *dev)
 {
 	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
 
@@ -197,10 +197,11 @@ static struct amba_id amba_kmi_idtable[]
 static struct amba_driver ambakmi_driver = {
 	.drv		= {
 		.name	= "kmi-pl050",
+		.owner	= THIS_MODULE,
 	},
 	.id_table	= amba_kmi_idtable,
 	.probe		= amba_kmi_probe,
-	.remove		= amba_kmi_remove,
+	.remove		= __devexit_p(amba_kmi_remove),
 	.resume		= amba_kmi_resume,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/at32psif.c linux-libre-2.6.33-gnu1/drivers/input/serio/at32psif.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/at32psif.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/at32psif.c	2010-02-24 13:52:17.000000000 -0500
@@ -137,7 +137,7 @@ static int psif_write(struct serio *io,
 	spin_lock_irqsave(&psif->lock, flags);
 
 	while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--)
-		msleep(10);
+		udelay(50);
 
 	if (timeout >= 0) {
 		psif_writel(psif, THR, val);
@@ -352,6 +352,7 @@ static struct platform_driver psif_drive
 	.remove		= __exit_p(psif_remove),
 	.driver		= {
 		.name	= "atmel_psif",
+		.owner	= THIS_MODULE,
 	},
 	.suspend	= psif_suspend,
 	.resume		= psif_resume,
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/gscps2.c linux-libre-2.6.33-gnu1/drivers/input/serio/gscps2.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/gscps2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/gscps2.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
  *
  * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
- * 	Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
+ *	Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
  *	Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
  *	Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
  *	Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
@@ -326,7 +326,7 @@ static void gscps2_close(struct serio *p
  * @return: success/error report
  */
 
-static int __init gscps2_probe(struct parisc_device *dev)
+static int __devinit gscps2_probe(struct parisc_device *dev)
 {
 	struct gscps2port *ps2port;
 	struct serio *serio;
@@ -443,7 +443,7 @@ static struct parisc_driver parisc_ps2_d
 	.name		= "gsc_ps2",
 	.id_table	= gscps2_device_tbl,
 	.probe		= gscps2_probe,
-	.remove		= gscps2_remove,
+	.remove		= __devexit_p(gscps2_remove),
 };
 
 static int __init gscps2_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/hil_mlc.c linux-libre-2.6.33-gnu1/drivers/input/serio/hil_mlc.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/hil_mlc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/hil_mlc.c	2010-02-24 13:52:17.000000000 -0500
@@ -993,10 +993,8 @@ int hil_mlc_unregister(hil_mlc *mlc)
 
 static int __init hil_mlc_init(void)
 {
-	init_timer(&hil_mlcs_kicker);
-	hil_mlcs_kicker.expires = jiffies + HZ;
-	hil_mlcs_kicker.function = &hil_mlcs_timer;
-	add_timer(&hil_mlcs_kicker);
+	setup_timer(&hil_mlcs_kicker, &hil_mlcs_timer, 0);
+	mod_timer(&hil_mlcs_kicker, jiffies + HZ);
 
 	tasklet_enable(&hil_mlcs_tasklet);
 
@@ -1005,7 +1003,7 @@ static int __init hil_mlc_init(void)
 
 static void __exit hil_mlc_exit(void)
 {
-	del_timer(&hil_mlcs_kicker);
+	del_timer_sync(&hil_mlcs_kicker);
 
 	tasklet_disable(&hil_mlcs_tasklet);
 	tasklet_kill(&hil_mlcs_tasklet);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/hp_sdc.c linux-libre-2.6.33-gnu1/drivers/input/serio/hp_sdc.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/hp_sdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/hp_sdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -955,7 +955,7 @@ static int __init hp_sdc_init_hppa(struc
 	INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed);
 
 	ret = hp_sdc_init();
-	/* after sucessfull initialization give SDC some time to settle
+	/* after successfull initialization give SDC some time to settle
 	 * and then load the hp_sdc_mlc upper layer driver */
 	if (!ret)
 		schedule_delayed_work(&moduleloader_work,
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/hp_sdc_mlc.c linux-libre-2.6.33-gnu1/drivers/input/serio/hp_sdc_mlc.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/hp_sdc_mlc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/hp_sdc_mlc.c	2010-02-24 13:52:17.000000000 -0500
@@ -125,7 +125,7 @@ static void hp_sdc_mlc_isr (int irq, voi
 		break;
 
 	default:
-		printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data);
+		printk(KERN_WARNING PREFIX "Unknown HIL Error status (%x)!\n", data);
 		break;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/i8042.c linux-libre-2.6.33-gnu1/drivers/input/serio/i8042.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/i8042.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/i8042.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,6 +126,8 @@ static unsigned char i8042_suppress_kbd_
 static struct platform_device *i8042_platform_device;
 
 static irqreturn_t i8042_interrupt(int irq, void *dev_id);
+static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
+				     struct serio *serio);
 
 void i8042_lock_chip(void)
 {
@@ -139,6 +141,48 @@ void i8042_unlock_chip(void)
 }
 EXPORT_SYMBOL(i8042_unlock_chip);
 
+int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+					struct serio *serio))
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	if (i8042_platform_filter) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	i8042_platform_filter = filter;
+
+out:
+	spin_unlock_irqrestore(&i8042_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(i8042_install_filter);
+
+int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
+				       struct serio *port))
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	if (i8042_platform_filter != filter) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	i8042_platform_filter = NULL;
+
+out:
+	spin_unlock_irqrestore(&i8042_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(i8042_remove_filter);
+
 /*
  * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
  * be ready for reading values from it / writing values to it.
@@ -369,6 +413,31 @@ static void i8042_stop(struct serio *ser
 }
 
 /*
+ * i8042_filter() filters out unwanted bytes from the input data stream.
+ * It is called from i8042_interrupt and thus is running with interrupts
+ * off and i8042_lock held.
+ */
+static bool i8042_filter(unsigned char data, unsigned char str,
+			 struct serio *serio)
+{
+	if (unlikely(i8042_suppress_kbd_ack)) {
+		if ((~str & I8042_STR_AUXDATA) &&
+		    (data == 0xfa || data == 0xfe)) {
+			i8042_suppress_kbd_ack--;
+			dbg("Extra keyboard ACK - filtered out\n");
+			return true;
+		}
+	}
+
+	if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) {
+		dbg("Filtered out by platfrom filter\n");
+		return true;
+	}
+
+	return false;
+}
+
+/*
  * i8042_interrupt() is the most important function in this driver -
  * it handles the interrupts from the i8042, and sends incoming bytes
  * to the upper layers.
@@ -377,13 +446,16 @@ static void i8042_stop(struct serio *ser
 static irqreturn_t i8042_interrupt(int irq, void *dev_id)
 {
 	struct i8042_port *port;
+	struct serio *serio;
 	unsigned long flags;
 	unsigned char str, data;
 	unsigned int dfl;
 	unsigned int port_no;
+	bool filtered;
 	int ret = 1;
 
 	spin_lock_irqsave(&i8042_lock, flags);
+
 	str = i8042_read_status();
 	if (unlikely(~str & I8042_STR_OBF)) {
 		spin_unlock_irqrestore(&i8042_lock, flags);
@@ -391,8 +463,8 @@ static irqreturn_t i8042_interrupt(int i
 		ret = 0;
 		goto out;
 	}
+
 	data = i8042_read_data();
-	spin_unlock_irqrestore(&i8042_lock, flags);
 
 	if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
 		static unsigned long last_transmit;
@@ -441,21 +513,19 @@ static irqreturn_t i8042_interrupt(int i
 	}
 
 	port = &i8042_ports[port_no];
+	serio = port->exists ? port->serio : NULL;
 
 	dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",
 	    data, port_no, irq,
 	    dfl & SERIO_PARITY ? ", bad parity" : "",
 	    dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-	if (unlikely(i8042_suppress_kbd_ack))
-		if (port_no == I8042_KBD_PORT_NO &&
-		    (data == 0xfa || data == 0xfe)) {
-			i8042_suppress_kbd_ack--;
-			goto out;
-		}
+	filtered = i8042_filter(data, str, serio);
 
-	if (likely(port->exists))
-		serio_interrupt(port->serio, data, dfl);
+	spin_unlock_irqrestore(&i8042_lock, flags);
+
+	if (likely(port->exists && !filtered))
+		serio_interrupt(serio, data, dfl);
 
  out:
 	return IRQ_RETVAL(ret);
@@ -1091,9 +1161,17 @@ static int i8042_pm_restore(struct devic
 	return 0;
 }
 
+static int i8042_pm_thaw(struct device *dev)
+{
+	i8042_interrupt(0, NULL);
+
+	return 0;
+}
+
 static const struct dev_pm_ops i8042_pm_ops = {
 	.suspend	= i8042_pm_reset,
 	.resume		= i8042_pm_restore,
+	.thaw		= i8042_pm_thaw,
 	.poweroff	= i8042_pm_reset,
 	.restore	= i8042_pm_restore,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/i8042-x86ia64io.h linux-libre-2.6.33-gnu1/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-2.6.32-gnu1/drivers/input/serio/i8042-x86ia64io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/i8042-x86ia64io.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,10 +67,12 @@ static inline void i8042_write_command(i
 
 #include <linux/dmi.h>
 
-static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
 	{
-		/* AUX LOOP command does not raise AUX IRQ */
-		.ident = "Arima-Rioworks HDAMB",
+		/*
+		 * Arima-Rioworks HDAMB -
+		 * AUX LOOP command does not raise AUX IRQ
+		 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
 			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
@@ -78,7 +80,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "ASUS G1S",
+		/* ASUS G1S */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
 			DMI_MATCH(DMI_BOARD_NAME, "G1S"),
@@ -86,8 +88,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		/* AUX LOOP command does not raise AUX IRQ */
-		.ident = "ASUS P65UP5",
+		/* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
 			DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
@@ -95,7 +96,6 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Compaq Proliant 8500",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
@@ -103,7 +103,6 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Compaq Proliant DL760",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
@@ -111,7 +110,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "OQO Model 01",
+		/* OQO Model 01 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
@@ -119,8 +118,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		/* AUX LOOP does not work properly */
-		.ident = "ULI EV4873",
+		/* ULI EV4873 - AUX LOOP does not work properly */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
@@ -128,7 +126,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Microsoft Virtual Machine",
+		/* Microsoft Virtual Machine */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
@@ -136,7 +134,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Medion MAM 2070",
+		/* Medion MAM 2070 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
@@ -144,7 +142,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Blue FB5601",
+		/* Blue FB5601 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "blue"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
@@ -152,7 +150,7 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "Gigabyte M912",
+		/* Gigabyte M912 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
@@ -160,7 +158,14 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
-		.ident = "HP DV9700",
+		/* Gigabyte M1022M netbook */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
+			DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
+			DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
+		},
+	},
+	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
@@ -177,72 +182,72 @@ static struct dmi_system_id __initdata i
  * ... apparently some Toshibas don't like MUX mode either and
  * die horrible death on reboot.
  */
-static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
 	{
-		.ident = "Fujitsu Lifebook P7010/P7010D",
+		/* Fujitsu Lifebook P7010/P7010D */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook P7010",
+		/* Fujitsu Lifebook P7010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook P5020D",
+		/* Fujitsu Lifebook P5020D */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook S2000",
+		/* Fujitsu Lifebook S2000 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
 		},
 	},
 	{
-		.ident = "Fujitsu Lifebook S6230",
+		/* Fujitsu Lifebook S6230 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
 		},
 	},
 	{
-		.ident = "Fujitsu T70H",
+		/* Fujitsu T70H */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Lifebook T3010",
+		/* Fujitsu-Siemens Lifebook T3010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Lifebook E4010",
+		/* Fujitsu-Siemens Lifebook E4010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Amilo Pro 2010",
+		/* Fujitsu-Siemens Amilo Pro 2010 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
 		},
 	},
 	{
-		.ident = "Fujitsu-Siemens Amilo Pro 2030",
+		/* Fujitsu-Siemens Amilo Pro 2030 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
@@ -253,7 +258,7 @@ static struct dmi_system_id __initdata i
 		 * No data is coming from the touchscreen unless KBC
 		 * is in legacy mode.
 		 */
-		.ident = "Panasonic CF-29",
+		/* Panasonic CF-29 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
@@ -261,10 +266,10 @@ static struct dmi_system_id __initdata i
 	},
 	{
 		/*
-		 * Errors on MUX ports are reported without raising AUXDATA
+		 * HP Pavilion DV4017EA -
+		 * errors on MUX ports are reported without raising AUXDATA
 		 * causing "spurious NAK" messages.
 		 */
-		.ident = "HP Pavilion DV4017EA",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
@@ -272,9 +277,9 @@ static struct dmi_system_id __initdata i
 	},
 	{
 		/*
-		 * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 * HP Pavilion ZT1000 -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
 		 */
-		.ident = "HP Pavilion ZT1000",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
@@ -283,44 +288,41 @@ static struct dmi_system_id __initdata i
 	},
 	{
 		/*
-		 * Like DV4017EA does not raise AUXERR for errors on MUX ports.
+		 * HP Pavilion DV4270ca -
+		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
 		 */
-		.ident = "HP Pavilion DV4270ca",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
 		},
 	},
 	{
-		.ident = "Toshiba P10",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
 		},
 	},
 	{
-		.ident = "Toshiba Equium A110",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
 		},
 	},
 	{
-		.ident = "Alienware Sentia",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
 		},
 	},
 	{
-		.ident = "Sharp Actius MM20",
+		/* Sharp Actius MM20 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
 		},
 	},
 	{
-		.ident = "Sony Vaio FS-115b",
+		/* Sony Vaio FS-115b */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
@@ -328,73 +330,72 @@ static struct dmi_system_id __initdata i
 	},
 	{
 		/*
-		 * Reset and GET ID commands issued via KBD port are
+		 * Sony Vaio FZ-240E -
+		 * reset and GET ID commands issued via KBD port are
 		 * sometimes being delivered to AUX3.
 		 */
-		.ident = "Sony Vaio FZ-240E",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
 		},
 	},
 	{
-		.ident = "Amoi M636/A737",
+		/* Amoi M636/A737 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
 		},
 	},
 	{
-		.ident = "Lenovo 3000 n100",
+		/* Lenovo 3000 n100 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 1360",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
 		},
 	},
 	{
-		.ident = "Gericom Bellagio",
+		/* Gericom Bellagio */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
 		},
 	},
 	{
-		.ident = "IBM 2656",
+		/* IBM 2656 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
 		},
 	},
 	{
-		.ident = "Dell XPS M1530",
+		/* Dell XPS M1530 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
 		},
 	},
 	{
-		.ident = "Compal HEL80I",
+		/* Compal HEL80I */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1510",
+		/* Dell Vostro 1510 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5536",
+		/* Acer Aspire 5536 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
@@ -404,65 +405,65 @@ static struct dmi_system_id __initdata i
 	{ }
 };
 
-static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
 	{
-		.ident = "MSI Wind U-100",
+		/* MSI Wind U-100 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
 		},
 	},
 	{
-		.ident = "LG Electronics X110",
+		/* LG Electronics X110 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "X110"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
 		},
 	},
 	{
-		.ident = "Acer Aspire One 150",
+		/* Acer Aspire One 150 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
 		},
 	},
 	{
-		.ident = "Advent 4211",
+		/* Advent 4211 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
 		},
 	},
 	{
-		.ident = "Medion Akoya Mini E1210",
+		/* Medion Akoya Mini E1210 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
 		},
 	},
 	{
-		.ident = "Mivvy M310",
+		/* Mivvy M310 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1320",
+		/* Dell Vostro 1320 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1520",
+		/* Dell Vostro 1520 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
 		},
 	},
 	{
-		.ident = "Dell Vostro 1720",
+		/* Dell Vostro 1720 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
@@ -472,16 +473,16 @@ static struct dmi_system_id __initdata i
 };
 
 #ifdef CONFIG_PNP
-static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
 	{
-		.ident = "Intel MBO Desktop D845PESV",
+		/* Intel MBO Desktop D845PESV */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
 		},
 	},
 	{
-		.ident = "MSI Wind U-100",
+		/* MSI Wind U-100 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
@@ -490,27 +491,23 @@ static struct dmi_system_id __initdata i
 	{ }
 };
 
-static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
 	{
-		.ident = "Portable",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
 	},
 	{
-		.ident = "Laptop",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
 		},
 	},
 	{
-		.ident = "Notebook",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
 		},
 	},
 	{
-		.ident = "Sub-Notebook",
 		.matches = {
 			DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
 		},
@@ -525,58 +522,65 @@ static struct dmi_system_id __initdata i
  * Originally, this was just confined to older laptops, but a few Acer laptops
  * have turned up in 2007 that also need this again.
  */
-static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
+static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
 	{
-		.ident = "Acer Aspire 5630",
+		/* Acer Aspire 5610 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+		},
+	},
+	{
+		/* Acer Aspire 5630 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5650",
+		/* Acer Aspire 5650 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5680",
+		/* Acer Aspire 5680 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 5720",
+		/* Acer Aspire 5720 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
 		},
 	},
 	{
-		.ident = "Acer Aspire 9110",
+		/* Acer Aspire 9110 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 660",
+		/* Acer TravelMate 660 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 2490",
+		/* Acer TravelMate 2490 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
 		},
 	},
 	{
-		.ident = "Acer TravelMate 4280",
+		/* Acer TravelMate 4280 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/Kconfig linux-libre-2.6.33-gnu1/drivers/input/serio/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/serio/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,4 +201,12 @@ config SERIO_XILINX_XPS_PS2
 	  To compile this driver as a module, choose M here: the
 	  module will be called xilinx_ps2.
 
+config SERIO_ALTERA_PS2
+	tristate "Altera UP PS/2 controller"
+	help
+	  Say Y here if you have Altera University Program PS/2 ports.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called altera_ps2.
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/Makefile linux-libre-2.6.33-gnu1/drivers/input/serio/Makefile
--- linux-libre-2.6.32-gnu1/drivers/input/serio/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -22,3 +22,4 @@ obj-$(CONFIG_SERIO_MACEPS2)	+= maceps2.o
 obj-$(CONFIG_SERIO_LIBPS2)	+= libps2.o
 obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
 obj-$(CONFIG_SERIO_XILINX_XPS_PS2)	+= xilinx_ps2.o
+obj-$(CONFIG_SERIO_ALTERA_PS2)	+= altera_ps2.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/sa1111ps2.c linux-libre-2.6.33-gnu1/drivers/input/serio/sa1111ps2.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/sa1111ps2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/sa1111ps2.c	2010-02-24 13:52:17.000000000 -0500
@@ -180,8 +180,8 @@ static void __devinit ps2_clear_input(st
 	}
 }
 
-static inline unsigned int
-ps2_test_one(struct ps2if *ps2if, unsigned int mask)
+static unsigned int __devinit ps2_test_one(struct ps2if *ps2if,
+					   unsigned int mask)
 {
 	unsigned int val;
 
@@ -197,7 +197,7 @@ ps2_test_one(struct ps2if *ps2if, unsign
  * Test the keyboard interface.  We basically check to make sure that
  * we can drive each line to the keyboard independently of each other.
  */
-static int __init ps2_test(struct ps2if *ps2if)
+static int __devinit ps2_test(struct ps2if *ps2if)
 {
 	unsigned int stat;
 	int ret = 0;
@@ -312,7 +312,7 @@ static int __devinit ps2_probe(struct sa
 /*
  * Remove one device from this driver.
  */
-static int ps2_remove(struct sa1111_dev *dev)
+static int __devexit ps2_remove(struct sa1111_dev *dev)
 {
 	struct ps2if *ps2if = sa1111_get_drvdata(dev);
 
@@ -335,7 +335,7 @@ static struct sa1111_driver ps2_driver =
 	},
 	.devid		= SA1111_DEVID_PS2,
 	.probe		= ps2_probe,
-	.remove		= ps2_remove,
+	.remove		= __devexit_p(ps2_remove),
 };
 
 static int __init ps2_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/serio/serio.c linux-libre-2.6.33-gnu1/drivers/input/serio/serio.c
--- linux-libre-2.6.32-gnu1/drivers/input/serio/serio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/serio/serio.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,13 +284,7 @@ static void serio_handle_event(void)
 
 	mutex_lock(&serio_mutex);
 
-	/*
-	 * Note that we handle only one event here to give swsusp
-	 * a chance to freeze kseriod thread. Serio events should
-	 * be pretty rare so we are not concerned about taking
-	 * performance hit.
-	 */
-	if ((event = serio_get_event())) {
+	while ((event = serio_get_event())) {
 
 		switch (event->type) {
 			case SERIO_REGISTER_PORT:
@@ -380,10 +374,9 @@ static struct serio *serio_get_pending_c
 
 static int serio_thread(void *nothing)
 {
-	set_freezable();
 	do {
 		serio_handle_event();
-		wait_event_freezable(serio_wait,
+		wait_event_interruptible(serio_wait,
 			kthread_should_stop() || !list_empty(&serio_event_list));
 	} while (!kthread_should_stop());
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/sparse-keymap.c linux-libre-2.6.33-gnu1/drivers/input/sparse-keymap.c
--- linux-libre-2.6.32-gnu1/drivers/input/sparse-keymap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/sparse-keymap.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,250 @@
+/*
+ * Generic support for sparse keymaps
+ *
+ * Copyright (c) 2009 Dmitry Torokhov
+ *
+ * Derived from wistron button driver:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This 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.h>
+#include <linux/input/sparse-keymap.h>
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic support for sparse keymaps");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
+/**
+ * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
+ * @dev: Input device using sparse keymap
+ * @code: Scan code
+ *
+ * This function is used to perform &struct key_entry lookup in an
+ * input device using sparse keymap.
+ */
+struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
+						    unsigned int code)
+{
+	struct key_entry *key;
+
+	for (key = dev->keycode; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);
+
+/**
+ * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
+ * @dev: Input device using sparse keymap
+ * @keycode: Key code
+ *
+ * This function is used to perform &struct key_entry lookup in an
+ * input device using sparse keymap.
+ */
+struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
+						   unsigned int keycode)
+{
+	struct key_entry *key;
+
+	for (key = dev->keycode; key->type != KE_END; key++)
+		if (key->type == KE_KEY && keycode == key->keycode)
+			return key;
+
+	return NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
+
+static int sparse_keymap_getkeycode(struct input_dev *dev,
+				    int scancode, int *keycode)
+{
+	const struct key_entry *key =
+			sparse_keymap_entry_from_scancode(dev, scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int sparse_keymap_setkeycode(struct input_dev *dev,
+				    int scancode, int keycode)
+{
+	struct key_entry *key;
+	int old_keycode;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	key = sparse_keymap_entry_from_scancode(dev, scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * sparse_keymap_setup - set up sparse keymap for an input device
+ * @dev: Input device
+ * @keymap: Keymap in form of array of &key_entry structures ending
+ *	with %KE_END type entry
+ * @setup: Function that can be used to adjust keymap entries
+ *	depending on device's deeds, may be %NULL
+ *
+ * The function calculates size and allocates copy of the original
+ * keymap after which sets up input device event bits appropriately.
+ * Before destroying input device allocated keymap should be freed
+ * with a call to sparse_keymap_free().
+ */
+int sparse_keymap_setup(struct input_dev *dev,
+			const struct key_entry *keymap,
+			int (*setup)(struct input_dev *, struct key_entry *))
+{
+	size_t map_size = 1; /* to account for the last KE_END entry */
+	const struct key_entry *e;
+	struct key_entry *map, *entry;
+	int i;
+	int error;
+
+	for (e = keymap; e->type != KE_END; e++)
+		map_size++;
+
+	map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL);
+	if (!map)
+		return -ENOMEM;
+
+	memcpy(map, keymap, map_size * sizeof (struct key_entry));
+
+	for (i = 0; i < map_size; i++) {
+		entry = &map[i];
+
+		if (setup) {
+			error = setup(dev, entry);
+			if (error)
+				goto err_out;
+		}
+
+		switch (entry->type) {
+		case KE_KEY:
+			__set_bit(EV_KEY, dev->evbit);
+			__set_bit(entry->keycode, dev->keybit);
+			break;
+
+		case KE_SW:
+			__set_bit(EV_SW, dev->evbit);
+			__set_bit(entry->sw.code, dev->swbit);
+			break;
+		}
+	}
+
+	dev->keycode = map;
+	dev->keycodemax = map_size;
+	dev->getkeycode = sparse_keymap_getkeycode;
+	dev->setkeycode = sparse_keymap_setkeycode;
+
+	return 0;
+
+ err_out:
+	kfree(keymap);
+	return error;
+
+}
+EXPORT_SYMBOL(sparse_keymap_setup);
+
+/**
+ * sparse_keymap_free - free memory allocated for sparse keymap
+ * @dev: Input device using sparse keymap
+ *
+ * This function is used to free memory allocated by sparse keymap
+ * in an input device that was set up by sparse_keymap_setup().
+ */
+void sparse_keymap_free(struct input_dev *dev)
+{
+	kfree(dev->keycode);
+	dev->keycode = NULL;
+	dev->keycodemax = 0;
+	dev->getkeycode = NULL;
+	dev->setkeycode = NULL;
+}
+EXPORT_SYMBOL(sparse_keymap_free);
+
+/**
+ * sparse_keymap_report_entry - report event corresponding to given key entry
+ * @dev: Input device for which event should be reported
+ * @ke: key entry describing event
+ * @value: Value that should be reported (ignored by %KE_SW entries)
+ * @autorelease: Signals whether release event should be emitted for %KE_KEY
+ *	entries right after reporting press event, ignored by all other
+ *	entries
+ *
+ * This function is used to report input event described by given
+ * &struct key_entry.
+ */
+void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
+				unsigned int value, bool autorelease)
+{
+	switch (ke->type) {
+	case KE_KEY:
+		input_report_key(dev, ke->keycode, value);
+		input_sync(dev);
+		if (value && autorelease) {
+			input_report_key(dev, ke->keycode, 0);
+			input_sync(dev);
+		}
+		break;
+
+	case KE_SW:
+		value = ke->sw.value;
+		/* fall through */
+
+	case KE_VSW:
+		input_report_switch(dev, ke->sw.code, value);
+		break;
+	}
+}
+EXPORT_SYMBOL(sparse_keymap_report_entry);
+
+/**
+ * sparse_keymap_report_event - report event corresponding to given scancode
+ * @dev: Input device using sparse keymap
+ * @code: Scan code
+ * @value: Value that should be reported (ignored by %KE_SW entries)
+ * @autorelease: Signals whether release event should be emitted for %KE_KEY
+ *	entries right after reporting press event, ignored by all other
+ *	entries
+ *
+ * This function is used to perform lookup in an input device using sparse
+ * keymap and report corresponding event. Returns %true if lookup was
+ * successful and %false otherwise.
+ */
+bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
+				unsigned int value, bool autorelease)
+{
+	const struct key_entry *ke =
+		sparse_keymap_entry_from_scancode(dev, code);
+
+	if (ke) {
+		sparse_keymap_report_entry(dev, ke, value, autorelease);
+		return true;
+	}
+
+	return false;
+}
+EXPORT_SYMBOL(sparse_keymap_report_event);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom.h linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom.h
--- linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * drivers/input/tablet/wacom.h
  *
- *  USB Wacom Graphire and Wacom Intuos tablet support
+ *  USB Wacom tablet support
  *
  *  Copyright (c) 2000-2004 Vojtech Pavlik	<vojtech@ucw.cz>
  *  Copyright (c) 2000 Andreas Bach Aaen	<abach@stofanet.dk>
@@ -69,6 +69,9 @@
  *      v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A)
  *      v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28
  *      v1.51 (pc) - Added support for Intuos4
+ *      v1.52 (pc) - Query Wacom data upon system resume
+ *                 - add defines for features->type
+ *                 - add new devices (0x9F, 0xE2, and 0XE3)
  */
 
 /*
@@ -89,9 +92,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.51"
+#define DRIVER_VERSION "v1.52"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
+#define DRIVER_DESC "USB Wacom tablet driver"
 #define DRIVER_LICENSE "GPL"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -133,6 +136,8 @@ extern void input_dev_i4s(struct input_d
 extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern __u16 wacom_le16_to_cpu(unsigned char *data);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_sys.c linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_sys.c
--- linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_sys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_sys.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * drivers/input/tablet/wacom_sys.c
  *
- *  USB Wacom Graphire and Wacom Intuos tablet support - system specific code
+ *  USB Wacom tablet support - system specific code
  */
 
 /*
@@ -209,6 +209,7 @@ void input_dev_g(struct input_dev *input
 	input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
 		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
 	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+		BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
 		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
 	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
 }
@@ -256,6 +257,7 @@ void input_dev_i(struct input_dev *input
 		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
 		BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
 	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+		BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
 		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
 		BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
 		BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
@@ -269,7 +271,8 @@ void input_dev_i(struct input_dev *input
 
 void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+		BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2);
 }
 
 void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -277,12 +280,32 @@ void input_dev_pt(struct input_dev *inpu
 	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
 }
 
+void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+	if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP ||
+	    wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
+		input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0);
+		input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0);
+		input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+	}
+}
+
+void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+	if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
+		input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
+		input_dev->evbit[0] |= BIT_MASK(EV_MSC);
+		input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+	}
+}
+
 static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
-			   struct wacom_wac *wacom_wac)
+			   struct wacom_features *features)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
-	struct wacom_features *features = wacom_wac->features;
-	char limit = 0, result = 0;
+	char limit = 0;
+	/* result has to be defined as int for some devices */
+	int result = 0;
 	int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
 	unsigned char *report;
 
@@ -328,13 +351,24 @@ static int wacom_parse_hid(struct usb_in
 			case HID_USAGE_X:
 				if (usage == WCM_DESKTOP) {
 					if (finger) {
-						features->touch_x_max =
-							features->touch_y_max =
-							wacom_le16_to_cpu(&report[i + 3]);
+						features->device_type = BTN_TOOL_DOUBLETAP;
+						if (features->type == TABLETPC2FG) {
+							/* need to reset back */
+							features->pktlen = WACOM_PKGLEN_TPC2FG;
+							features->device_type = BTN_TOOL_TRIPLETAP;
+						}
 						features->x_max =
+							wacom_le16_to_cpu(&report[i + 3]);
+						features->x_phy =
 							wacom_le16_to_cpu(&report[i + 6]);
-						i += 7;
+						features->unit = report[i + 9];
+						features->unitExpo = report[i + 11];
+						i += 12;
 					} else if (pen) {
+						/* penabled only accepts exact bytes of data */
+						if (features->type == TABLETPC2FG)
+							features->pktlen = WACOM_PKGLEN_PENABLED;
+						features->device_type = BTN_TOOL_PEN;
 						features->x_max =
 							wacom_le16_to_cpu(&report[i + 3]);
 						i += 4;
@@ -350,10 +384,35 @@ static int wacom_parse_hid(struct usb_in
 				break;
 
 			case HID_USAGE_Y:
-				if (usage == WCM_DESKTOP)
-					features->y_max =
-						wacom_le16_to_cpu(&report[i + 3]);
-				i += 4;
+				if (usage == WCM_DESKTOP) {
+					if (finger) {
+						features->device_type = BTN_TOOL_DOUBLETAP;
+						if (features->type == TABLETPC2FG) {
+							/* need to reset back */
+							features->pktlen = WACOM_PKGLEN_TPC2FG;
+							features->device_type = BTN_TOOL_TRIPLETAP;
+							features->y_max =
+								wacom_le16_to_cpu(&report[i + 3]);
+							features->y_phy =
+								wacom_le16_to_cpu(&report[i + 6]);
+							i += 7;
+						} else {
+							features->y_max =
+								features->x_max;
+							features->y_phy =
+								wacom_le16_to_cpu(&report[i + 3]);
+							i += 4;
+						}
+					} else if (pen) {
+						/* penabled only accepts exact bytes of data */
+						if (features->type == TABLETPC2FG)
+							features->pktlen = WACOM_PKGLEN_PENABLED;
+						features->device_type = BTN_TOOL_PEN;
+						features->y_max =
+							wacom_le16_to_cpu(&report[i + 3]);
+						i += 4;
+					}
+				}
 				break;
 
 			case HID_USAGE_FINGER:
@@ -376,7 +435,7 @@ static int wacom_parse_hid(struct usb_in
 			break;
 
 		case HID_COLLECTION:
-			/* reset UsagePage ans Finger */
+			/* reset UsagePage and Finger */
 			finger = usage = 0;
 			break;
 		}
@@ -388,43 +447,92 @@ static int wacom_parse_hid(struct usb_in
 	return result;
 }
 
-static int wacom_query_tablet_data(struct usb_interface *intf)
+static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features)
 {
 	unsigned char *rep_data;
-	int limit = 0;
-	int error;
+	int limit = 0, report_id = 2;
+	int error = -ENOMEM;
 
 	rep_data = kmalloc(2, GFP_KERNEL);
 	if (!rep_data)
-		return -ENOMEM;
+		return error;
 
-	do {
-		rep_data[0] = 2;
-		rep_data[1] = 2;
-		error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
-					2, rep_data, 2);
-		if (error >= 0)
-			error = usb_get_report(intf,
-						WAC_HID_FEATURE_REPORT, 2,
-						rep_data, 2);
-	} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
+	/* ask to report tablet data if it is 2FGT or not a Tablet PC */
+	if (features->device_type == BTN_TOOL_TRIPLETAP) {
+		do {
+			rep_data[0] = 3;
+			rep_data[1] = 4;
+			report_id = 3;
+			error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+				report_id, rep_data, 2);
+			if (error >= 0)
+				error = usb_get_report(intf,
+					WAC_HID_FEATURE_REPORT, report_id,
+					rep_data, 3);
+		} while ((error < 0 || rep_data[1] != 4) && limit++ < 5);
+	} else if (features->type != TABLETPC && features->type != TABLETPC2FG) {
+		do {
+			rep_data[0] = 2;
+			rep_data[1] = 2;
+			error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+				report_id, rep_data, 2);
+			if (error >= 0)
+				error = usb_get_report(intf,
+					WAC_HID_FEATURE_REPORT, report_id,
+					rep_data, 2);
+		} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
+	}
 
 	kfree(rep_data);
 
 	return error < 0 ? error : 0;
 }
 
+static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+		struct wacom_features *features)
+{
+	int error = 0;
+	struct usb_host_interface *interface = intf->cur_altsetting;
+	struct hid_descriptor *hid_desc;
+
+	/* default device to penabled */
+	features->device_type = BTN_TOOL_PEN;
+
+	/* only Tablet PCs need to retrieve the info */
+	if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+		goto out;
+
+	if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+		if (usb_get_extra_descriptor(&interface->endpoint[0],
+				HID_DEVICET_REPORT, &hid_desc)) {
+			printk("wacom: can not retrieve extra class descriptor\n");
+			error = 1;
+			goto out;
+		}
+	}
+	error = wacom_parse_hid(intf, hid_desc, features);
+	if (error)
+		goto out;
+
+	/* touch device found but size is not defined. use default */
+	if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+		features->x_max = 1023;
+		features->y_max = 1023;
+	}
+
+ out:
+	return error;
+}
+
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
-	struct usb_host_interface *interface = intf->cur_altsetting;
 	struct usb_endpoint_descriptor *endpoint;
 	struct wacom *wacom;
 	struct wacom_wac *wacom_wac;
 	struct wacom_features *features;
 	struct input_dev *input_dev;
 	int error = -ENOMEM;
-	struct hid_descriptor *hid_desc;
 
 	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
 	wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
@@ -432,7 +540,7 @@ static int wacom_probe(struct usb_interf
 	if (!wacom || !input_dev || !wacom_wac)
 		goto fail1;
 
-	wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
+	wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma);
 	if (!wacom_wac->data)
 		goto fail1;
 
@@ -448,7 +556,7 @@ static int wacom_probe(struct usb_interf
 	strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
 
 	wacom_wac->features = features = get_wacom_feature(id);
-	BUG_ON(features->pktlen > 10);
+	BUG_ON(features->pktlen > WACOM_PKGLEN_MAX);
 
 	input_dev->name = wacom_wac->features->name;
 	wacom->wacom_wac = wacom_wac;
@@ -463,47 +571,24 @@ static int wacom_probe(struct usb_interf
 
 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
 
-	/* Initialize touch_x_max and touch_y_max in case it is not defined */
-	if (wacom_wac->features->type == TABLETPC) {
-		features->touch_x_max = 1023;
-		features->touch_y_max = 1023;
-	} else {
-		features->touch_x_max = 0;
-		features->touch_y_max = 0;
-	}
-
-	/* TabletPC need to retrieve the physical and logical maximum from report descriptor */
-	if (wacom_wac->features->type == TABLETPC) {
-		if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
-			if (usb_get_extra_descriptor(&interface->endpoint[0],
-						     HID_DEVICET_REPORT, &hid_desc)) {
-				printk("wacom: can not retrive extra class descriptor\n");
-				goto fail2;
-			}
-		}
-		error = wacom_parse_hid(intf, hid_desc, wacom_wac);
-		if (error)
-			goto fail2;
-	}
+	/* Retrieve the physical and logical size for OEM devices */
+	error = wacom_retrieve_hid_descriptor(intf, features);
+	if (error)
+		goto fail2;
 
 	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
-		BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
+
 	input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0);
-	if (features->type == TABLETPC) {
-		input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
-		input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0);
-		input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0);
-	}
 	input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
 
 	wacom_init_input_dev(input_dev, wacom_wac);
 
 	usb_fill_int_urb(wacom->irq, dev,
 			 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
-			 wacom_wac->data, wacom_wac->features->pktlen,
+			 wacom_wac->data, features->pktlen,
 			 wacom_sys_irq, wacom, endpoint->bInterval);
 	wacom->irq->transfer_dma = wacom->data_dma;
 	wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -512,18 +597,14 @@ static int wacom_probe(struct usb_interf
 	if (error)
 		goto fail3;
 
-	/*
-	 * Ask the tablet to report tablet data if it is not a Tablet PC.
-	 * Note that if query fails it is not a hard failure.
-	 */
-	if (wacom_wac->features->type != TABLETPC)
-		wacom_query_tablet_data(intf);
+	/* Note that if query fails it is not a hard failure */
+	wacom_query_tablet_data(intf, features);
 
 	usb_set_intfdata(intf, wacom);
 	return 0;
 
  fail3:	usb_free_urb(wacom->irq);
- fail2:	usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
+ fail2:	usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
  fail1:	input_free_device(input_dev);
 	kfree(wacom);
 	kfree(wacom_wac);
@@ -539,7 +620,7 @@ static void wacom_disconnect(struct usb_
 	usb_kill_urb(wacom->irq);
 	input_unregister_device(wacom->dev);
 	usb_free_urb(wacom->irq);
-	usb_buffer_free(interface_to_usbdev(intf), 10,
+	usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
 			wacom->wacom_wac->data, wacom->data_dma);
 	kfree(wacom->wacom_wac);
 	kfree(wacom);
@@ -559,12 +640,16 @@ static int wacom_suspend(struct usb_inte
 static int wacom_resume(struct usb_interface *intf)
 {
 	struct wacom *wacom = usb_get_intfdata(intf);
+	struct wacom_features *features = wacom->wacom_wac->features;
 	int rv;
 
 	mutex_lock(&wacom->lock);
-	if (wacom->open)
+	if (wacom->open) {
 		rv = usb_submit_urb(wacom->irq, GFP_NOIO);
-	else
+		/* switch to wacom mode if needed */
+		if (!wacom_retrieve_hid_descriptor(intf, features))
+			wacom_query_tablet_data(intf, features);
+	} else
 		rv = 0;
 	mutex_unlock(&wacom->lock);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_wac.c linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.c
--- linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_wac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * drivers/input/tablet/wacom_wac.c
  *
- *  USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
+ *  USB Wacom tablet support - Wacom specific code
  *
  */
 
@@ -58,16 +58,15 @@ static int wacom_pl_irq(struct wacom_wac
 	unsigned char *data = wacom->data;
 	int prox, pressure;
 
-	if (data[0] != 2) {
+	if (data[0] != WACOM_REPORT_PENABLED) {
 		dbg("wacom_pl_irq: received unknown report #%d", data[0]);
 		return 0;
 	}
 
 	prox = data[1] & 0x40;
 
-	wacom->id[0] = ERASER_DEVICE_ID;
 	if (prox) {
-
+		wacom->id[0] = ERASER_DEVICE_ID;
 		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
 		if (wacom->features->pressure_max > 255)
 			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
@@ -128,7 +127,7 @@ static int wacom_ptu_irq(struct wacom_wa
 {
 	unsigned char *data = wacom->data;
 
-	if (data[0] != 2) {
+	if (data[0] != WACOM_REPORT_PENABLED) {
 		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
 		return 0;
 	}
@@ -155,14 +154,16 @@ static int wacom_graphire_irq(struct wac
 {
 	unsigned char *data = wacom->data;
 	int x, y, rw;
+	static int penData = 0;
 
-	if (data[0] != 2) {
+	if (data[0] != WACOM_REPORT_PENABLED) {
 		dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
 		return 0;
 	}
 
 	if (data[1] & 0x80) {
 		/* in prox and not a pad data */
+		penData = 1;
 
 		switch ((data[1] >> 5) & 3) {
 
@@ -232,7 +233,11 @@ static int wacom_graphire_irq(struct wac
 	switch (wacom->features->type) {
 	    case WACOM_G4:
 		if (data[7] & 0xf8) {
-			wacom_input_sync(wcombo); /* sync last event */
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
 			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -242,10 +247,15 @@ static int wacom_graphire_irq(struct wac
 			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		} else if (wacom->id[1]) {
-			wacom_input_sync(wcombo); /* sync last event */
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = 0;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
 			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+			wacom_report_rel(wcombo, REL_WHEEL, 0);
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
 			wacom_report_abs(wcombo, ABS_MISC, 0);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
@@ -253,7 +263,11 @@ static int wacom_graphire_irq(struct wac
 		break;
 	    case WACOM_MO:
 		if ((data[7] & 0xf8) || (data[8] & 0xff)) {
-			wacom_input_sync(wcombo); /* sync last event */
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
 			wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -264,7 +278,11 @@ static int wacom_graphire_irq(struct wac
 			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		} else if (wacom->id[1]) {
-			wacom_input_sync(wcombo); /* sync last event */
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = 0;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
 			wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -432,7 +450,8 @@ static int wacom_intuos_irq(struct wacom
 	unsigned int t;
 	int idx = 0, result;
 
-	if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
+	if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD
+		&& data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) {
 		dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
                 return 0;
 	}
@@ -442,7 +461,7 @@ static int wacom_intuos_irq(struct wacom
 		idx = data[1] & 0x01;
 
 	/* pad packets. Works as a second tool and is always in prox */
-	if (data[0] == 12) {
+	if (data[0] == WACOM_REPORT_INTUOSPAD) {
 		/* initiate the pad as a device */
 		if (wacom->tool[1] != BTN_TOOL_FINGER)
 			wacom->tool[1] = BTN_TOOL_FINGER;
@@ -608,95 +627,163 @@ static int wacom_intuos_irq(struct wacom
 	return 1;
 }
 
+
+static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
+{
+	wacom_report_abs(wcombo, ABS_X,
+		(data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
+	wacom_report_abs(wcombo, ABS_Y,
+		(data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
+	wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+	wacom_report_key(wcombo, wacom->tool[idx], 1);
+	if (idx)
+		wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+	else
+		wacom_report_key(wcombo, BTN_TOUCH, 1);
+}
+
+static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx)
+{
+	wacom_report_abs(wcombo, ABS_X, 0);
+	wacom_report_abs(wcombo, ABS_Y, 0);
+	wacom_report_abs(wcombo, ABS_MISC, 0);
+	wacom_report_key(wcombo, wacom->tool[idx], 0);
+	if (idx)
+		wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+	else
+		wacom_report_key(wcombo, BTN_TOUCH, 0);
+	return;
+}
+
+static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo)
+{
+	char *data = wacom->data;
+	struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
+	static int firstFinger = 0;
+	static int secondFinger = 0;
+
+	wacom->tool[0] = BTN_TOOL_DOUBLETAP;
+	wacom->id[0] = TOUCH_DEVICE_ID;
+	wacom->tool[1] = BTN_TOOL_TRIPLETAP;
+
+	if (urb->actual_length != WACOM_PKGLEN_TPC1FG) {
+		switch (data[0]) {
+			case WACOM_REPORT_TPC1FG:
+				wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+				wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+				wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
+				wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6]));
+				wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+				wacom_report_key(wcombo, wacom->tool[0], 1);
+				break;
+			case WACOM_REPORT_TPC2FG:
+				/* keep this byte to send proper out-prox event */
+				wacom->id[1] = data[1] & 0x03;
+
+				if (data[1] & 0x01) {
+					wacom_tpc_finger_in(wacom, wcombo, data, 0);
+					firstFinger = 1;
+				} else if (firstFinger) {
+					wacom_tpc_touch_out(wacom, wcombo, 0);
+				}
+
+				if (data[1] & 0x02) {
+					/* sync first finger data */
+					if (firstFinger)
+						wacom_input_sync(wcombo);
+
+					wacom_tpc_finger_in(wacom, wcombo, data, 1);
+					secondFinger = 1;
+				} else if (secondFinger) {
+					/* sync first finger data */
+					if (firstFinger)
+						wacom_input_sync(wcombo);
+
+					wacom_tpc_touch_out(wacom, wcombo, 1);
+					secondFinger = 0;
+				}
+				if (!(data[1] & 0x01))
+					firstFinger = 0;
+				break;
+		}
+	} else {
+		wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
+		wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
+		wacom_report_key(wcombo, BTN_TOUCH, 1);
+		wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+		wacom_report_key(wcombo, wacom->tool[0], 1);
+	}
+	return;
+}
+
 static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 {
 	char *data = wacom->data;
-	int prox = 0, pressure;
+	int prox = 0, pressure, idx = -1;
 	static int stylusInProx, touchInProx = 1, touchOut;
 	struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
 
 	dbg("wacom_tpc_irq: received report #%d", data[0]);
 
-	if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */
-		if (urb->actual_length == 5) {  /* with touch */
-			prox = data[0] & 0x03;
+	if (urb->actual_length == WACOM_PKGLEN_TPC1FG || /* single touch */
+	    data[0] == WACOM_REPORT_TPC1FG ||		 /* single touch */
+	    data[0] == WACOM_REPORT_TPC2FG) {		 /* 2FG touch */
+		if (urb->actual_length == WACOM_PKGLEN_TPC1FG) {  /* with touch */
+			prox = data[0] & 0x01;
 		} else {  /* with capacity */
-			prox = data[1] & 0x03;
+			if (data[0] == WACOM_REPORT_TPC1FG)
+				/* single touch */
+				prox = data[1] & 0x01;
+			else
+				/* 2FG touch data */
+				prox = data[1] & 0x03;
 		}
 
 		if (!stylusInProx) { /* stylus not in prox */
 			if (prox) {
 				if (touchInProx) {
-					wacom->tool[1] = BTN_TOOL_DOUBLETAP;
-					wacom->id[0] = TOUCH_DEVICE_ID;
-					if (urb->actual_length != 5) {
-						wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-						wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-						wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
-						wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6]));
-					} else {
-						wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
-						wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
-						wacom_report_key(wcombo, BTN_TOUCH, 1);
-					}
-					wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
-					wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
+					wacom_tpc_touch_in(wacom, wcombo);
 					touchOut = 1;
 					return 1;
 				}
 			} else {
-				wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
-				wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
-				wacom_report_key(wcombo, BTN_TOUCH, 0);
+				/* 2FGT out-prox */
+				if (data[0] == WACOM_REPORT_TPC2FG) {
+					idx = (wacom->id[1] & 0x01) - 1;
+					if (idx == 0) {
+						wacom_tpc_touch_out(wacom, wcombo, idx);
+						/* sync first finger event */
+						if (wacom->id[1] & 0x02)
+							wacom_input_sync(wcombo);
+					}
+					idx = (wacom->id[1] & 0x02) - 1;
+					if (idx == 1)
+						wacom_tpc_touch_out(wacom, wcombo, idx);
+				} else /* one finger touch */
+					wacom_tpc_touch_out(wacom, wcombo, 0);
 				touchOut = 0;
 				touchInProx = 1;
 				return 1;
 			}
 		} else if (touchOut || !prox) { /* force touch out-prox */
-			wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID);
-			wacom_report_key(wcombo, wacom->tool[1], 0);
-			wacom_report_key(wcombo, BTN_TOUCH, 0);
+			wacom_tpc_touch_out(wacom, wcombo, 0);
 			touchOut = 0;
 			touchInProx = 1;
 			return 1;
 		}
-	} else if (data[0] == 2) { /* Penabled */
+	} else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */
 		prox = data[1] & 0x20;
 
 		touchInProx = 0;
 
-		wacom->id[0] = ERASER_DEVICE_ID;
-
-		/*
-		 * if going from out of proximity into proximity select between the eraser
-		 * and the pen based on the state of the stylus2 button, choose eraser if
-		 * pressed else choose pen. if not a proximity change from out to in, send
-		 * an out of proximity for previous tool then a in for new tool.
-		 */
 		if (prox) { /* in prox */
-			if (!wacom->tool[0]) {
+			if (!wacom->id[0]) {
 				/* Going into proximity select tool */
-				wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-				if (wacom->tool[1] == BTN_TOOL_PEN)
+				wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+				if (wacom->tool[0] == BTN_TOOL_PEN)
 					wacom->id[0] = STYLUS_DEVICE_ID;
-			} else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) {
-				/*
-				 * was entered with stylus2 pressed
-				 * report out proximity for previous tool
-				*/
-				wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
-				wacom_report_key(wcombo, wacom->tool[1], 0);
-				wacom_input_sync(wcombo);
-
-				/* set new tool */
-				wacom->tool[1] = BTN_TOOL_PEN;
-				wacom->id[0] = STYLUS_DEVICE_ID;
-				return 0;
-			}
-			if (wacom->tool[1] != BTN_TOOL_RUBBER) {
-				/* Unknown tool selected default to pen tool */
-				wacom->tool[1] = BTN_TOOL_PEN;
-				wacom->id[0] = STYLUS_DEVICE_ID;
+				else
+					wacom->id[0] = ERASER_DEVICE_ID;
 			}
 			wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
 			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
@@ -706,17 +793,21 @@ static int wacom_tpc_irq(struct wacom_wa
 			if (pressure < 0)
 				pressure = wacom->features->pressure_max + pressure + 1;
 			wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-			wacom_report_key(wcombo, BTN_TOUCH, pressure);
+			wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
 		} else {
+			wacom_report_abs(wcombo, ABS_X, 0);
+			wacom_report_abs(wcombo, ABS_Y, 0);
 			wacom_report_abs(wcombo, ABS_PRESSURE, 0);
 			wacom_report_key(wcombo, BTN_STYLUS, 0);
 			wacom_report_key(wcombo, BTN_STYLUS2, 0);
 			wacom_report_key(wcombo, BTN_TOUCH, 0);
+			wacom->id[0] = 0;
+			/* pen is out so touch can be enabled now */
+			touchInProx = 1;
 		}
-		wacom_report_key(wcombo, wacom->tool[1], prox);
+		wacom_report_key(wcombo, wacom->tool[0], prox);
 		wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
 		stylusInProx = prox;
-		wacom->tool[0] = prox;
 		return 1;
 	}
 	return 0;
@@ -751,6 +842,7 @@ int wacom_wac_irq(struct wacom_wac *waco
 			return wacom_intuos_irq(wacom_wac, wcombo);
 
 		case TABLETPC:
+		case TABLETPC2FG:
 			return wacom_tpc_irq(wacom_wac, wcombo);
 
 		default:
@@ -791,9 +883,17 @@ void wacom_init_input_dev(struct input_d
 			input_dev_i4s(input_dev, wacom_wac);
 			input_dev_i(input_dev, wacom_wac);
 			break;
+		case TABLETPC2FG:
+			input_dev_tpc2fg(input_dev, wacom_wac);
+			/* fall through */
+		case TABLETPC:
+			input_dev_tpc(input_dev, wacom_wac);
+			if (wacom_wac->features->device_type != BTN_TOOL_PEN)
+				break;  /* no need to process stylus stuff */
+
+			/* fall through */
 		case PL:
 		case PTU:
-		case TABLETPC:
 			input_dev_pl(input_dev, wacom_wac);
 			/* fall through */
 		case PENPARTNER:
@@ -804,66 +904,69 @@ void wacom_init_input_dev(struct input_d
 }
 
 static struct wacom_features wacom_features[] = {
-	{ "Wacom Penpartner",    7,   5040,  3780,  255,  0, PENPARTNER },
-        { "Wacom Graphire",      8,  10206,  7422,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire3",     8,  10208,  7424,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 63, GRAPHIRE },
-	{ "Wacom Graphire4 4x5", 8,  10208,  7424,  511, 63, WACOM_G4 },
-	{ "Wacom Graphire4 6x8", 8,  16704, 12064,  511, 63, WACOM_G4 },
-	{ "Wacom BambooFun 4x5", 9,  14760,  9225,  511, 63, WACOM_MO },
-	{ "Wacom BambooFun 6x8", 9,  21648, 13530,  511, 63, WACOM_MO },
-	{ "Wacom Bamboo1 Medium",8,  16704, 12064,  511, 63, GRAPHIRE },
-	{ "Wacom Volito",        8,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom PenStation2",   8,   3250,  2320,  255, 63, GRAPHIRE },
-	{ "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom Volito2 2x3",   8,   3248,  2320,  511, 63, GRAPHIRE },
-	{ "Wacom PenPartner2",   8,   3250,  2320,  511, 63, GRAPHIRE },
-	{ "Wacom Bamboo",        9,  14760,  9225,  511, 63, WACOM_MO },
-	{ "Wacom Bamboo1",       8,   5104,  3712,  511, 63, GRAPHIRE },
-	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 31, INTUOS },
-	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 31, INTUOS },
-	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 31, INTUOS },
-	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 31, INTUOS },
-	{ "Wacom PL400",         8,   5408,  4056,  255,  0, PL },
-	{ "Wacom PL500",         8,   6144,  4608,  255,  0, PL },
-	{ "Wacom PL600",         8,   6126,  4604,  255,  0, PL },
-	{ "Wacom PL600SX",       8,   6260,  5016,  255,  0, PL },
-	{ "Wacom PL550",         8,   6144,  4608,  511,  0, PL },
-	{ "Wacom PL800",         8,   7220,  5780,  511,  0, PL },
-	{ "Wacom PL700",         8,   6758,  5406,  511,  0, PL },
-	{ "Wacom PL510",         8,   6282,  4762,  511,  0, PL },
-	{ "Wacom DTU710",        8,  34080, 27660,  511,  0, PL },
-	{ "Wacom DTF521",        8,   6282,  4762,  511,  0, PL },
-	{ "Wacom DTF720",        8,   6858,  5506,  511,  0, PL },
-	{ "Wacom DTF720a",       8,   6858,  5506,  511,  0, PL },
-	{ "Wacom Cintiq Partner",8,  20480, 15360,  511,  0, PTU },
-	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
-	{ "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 63, INTUOS3S },
-	{ "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L },
-	{ "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
-	{ "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 63, INTUOS3 },
-	{ "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 63, INTUOS3S },
-	{ "Wacom Intuos4 4x6",   10, 31496, 19685, 2047, 63, INTUOS4S },
-	{ "Wacom Intuos4 6x9",   10, 44704, 27940, 2047, 63, INTUOS4 },
-	{ "Wacom Intuos4 8x13",  10, 65024, 40640, 2047, 63, INTUOS4L },
-	{ "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L },
-	{ "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
-	{ "Wacom Cintiq 20WSX",  10, 86680, 54180, 1023, 63, WACOM_BEE },
-	{ "Wacom Cintiq 12WX",   10, 53020, 33440, 1023, 63, WACOM_BEE },
-	{ "Wacom DTU1931",        8, 37832, 30305,  511,  0, PL },
-	{ "Wacom ISDv4 90",       8, 26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 93",       8, 26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom ISDv4 9A",       8, 26202, 16325,  255,  0, TABLETPC },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
+	{ "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,  0, PENPARTNER },
+	{ "Wacom Graphire",       WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE },
+	{ "Wacom Graphire2 4x5",  WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511, 63, GRAPHIRE },
+	{ "Wacom Graphire2 5x7",  WACOM_PKGLEN_GRAPHIRE,  13918, 10206,  511, 63, GRAPHIRE },
+	{ "Wacom Graphire3",      WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, GRAPHIRE },
+	{ "Wacom Graphire3 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE },
+	{ "Wacom Graphire4 4x5",  WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511, 63, WACOM_G4 },
+	{ "Wacom Graphire4 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, WACOM_G4 },
+	{ "Wacom BambooFun 4x5",  WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO },
+	{ "Wacom BambooFun 6x8",  WACOM_PKGLEN_BBFUN,     21648, 13530,  511, 63, WACOM_MO },
+	{ "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511, 63, GRAPHIRE },
+	{ "Wacom Volito",         WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
+	{ "Wacom PenStation2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  255, 63, GRAPHIRE },
+	{ "Wacom Volito2 4x5",    WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
+	{ "Wacom Volito2 2x3",    WACOM_PKGLEN_GRAPHIRE,   3248,  2320,  511, 63, GRAPHIRE },
+	{ "Wacom PenPartner2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  511, 63, GRAPHIRE },
+	{ "Wacom Bamboo",         WACOM_PKGLEN_BBFUN,     14760,  9225,  511, 63, WACOM_MO },
+	{ "Wacom Bamboo1",        WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511, 63, GRAPHIRE },
+	{ "Wacom Intuos 4x5",     WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS },
+	{ "Wacom Intuos 6x8",     WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
+	{ "Wacom Intuos 9x12",    WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS },
+	{ "Wacom Intuos 12x12",   WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS },
+	{ "Wacom Intuos 12x18",   WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS },
+	{ "Wacom PL400",          WACOM_PKGLEN_GRAPHIRE,   5408,  4056,  255,  0, PL },
+	{ "Wacom PL500",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  255,  0, PL },
+	{ "Wacom PL600",          WACOM_PKGLEN_GRAPHIRE,   6126,  4604,  255,  0, PL },
+	{ "Wacom PL600SX",        WACOM_PKGLEN_GRAPHIRE,   6260,  5016,  255,  0, PL },
+	{ "Wacom PL550",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  511,  0, PL },
+	{ "Wacom PL800",          WACOM_PKGLEN_GRAPHIRE,   7220,  5780,  511,  0, PL },
+	{ "Wacom PL700",          WACOM_PKGLEN_GRAPHIRE,   6758,  5406,  511,  0, PL },
+	{ "Wacom PL510",          WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL },
+	{ "Wacom DTU710",         WACOM_PKGLEN_GRAPHIRE,  34080, 27660,  511,  0, PL },
+	{ "Wacom DTF521",         WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,  0, PL },
+	{ "Wacom DTF720",         WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL },
+	{ "Wacom DTF720a",        WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,  0, PL },
+	{ "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE,  20480, 15360,  511,  0, PTU },
+	{ "Wacom Intuos2 4x5",    WACOM_PKGLEN_INTUOS,    12700, 10600, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 9x12",   WACOM_PKGLEN_INTUOS,    30480, 24060, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 12x12",  WACOM_PKGLEN_INTUOS,    30480, 31680, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 12x18",  WACOM_PKGLEN_INTUOS,    45720, 31680, 1023, 31, INTUOS },
+	{ "Wacom Intuos3 4x5",    WACOM_PKGLEN_INTUOS,    25400, 20320, 1023, 63, INTUOS3S },
+	{ "Wacom Intuos3 6x8",    WACOM_PKGLEN_INTUOS,    40640, 30480, 1023, 63, INTUOS3 },
+	{ "Wacom Intuos3 9x12",   WACOM_PKGLEN_INTUOS,    60960, 45720, 1023, 63, INTUOS3 },
+	{ "Wacom Intuos3 12x12",  WACOM_PKGLEN_INTUOS,    60960, 60960, 1023, 63, INTUOS3L },
+	{ "Wacom Intuos3 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 1023, 63, INTUOS3L },
+	{ "Wacom Intuos3 6x11",   WACOM_PKGLEN_INTUOS,    54204, 31750, 1023, 63, INTUOS3 },
+	{ "Wacom Intuos3 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 1023, 63, INTUOS3S },
+	{ "Wacom Intuos4 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 2047, 63, INTUOS4S },
+	{ "Wacom Intuos4 6x9",    WACOM_PKGLEN_INTUOS,    44704, 27940, 2047, 63, INTUOS4 },
+	{ "Wacom Intuos4 8x13",   WACOM_PKGLEN_INTUOS,    65024, 40640, 2047, 63, INTUOS4L },
+	{ "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047, 63, INTUOS4L },
+	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023, 63, CINTIQ },
+	{ "Wacom Cintiq 20WSX",   WACOM_PKGLEN_INTUOS,    86680, 54180, 1023, 63, WACOM_BEE },
+	{ "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023, 63, WACOM_BEE },
+	{ "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,  0, PL },
+	{ "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
+	{ "Wacom ISDv4 93",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
+	{ "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC },
+	{ "Wacom ISDv4 9F",       WACOM_PKGLEN_PENABLED,  26202, 16325,  255,  0, TABLETPC },
+	{ "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG },
+	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG },
+	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS },
 	{ }
 };
 
@@ -927,6 +1030,9 @@ static struct usb_device_id wacom_ids[]
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
 	{ }
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_wac.h linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.h
--- linux-libre-2.6.32-gnu1/drivers/input/tablet/wacom_wac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/tablet/wacom_wac.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,12 +9,33 @@
 #ifndef WACOM_WAC_H
 #define WACOM_WAC_H
 
+/* maximum packet length for USB devices */
+#define WACOM_PKGLEN_MAX	32
+
+/* packet length for individual models */
+#define WACOM_PKGLEN_PENPRTN	 7
+#define WACOM_PKGLEN_GRAPHIRE	 8
+#define WACOM_PKGLEN_BBFUN 	 9
+#define WACOM_PKGLEN_INTUOS 	10
+#define WACOM_PKGLEN_PENABLED	 8
+#define WACOM_PKGLEN_TPC1FG	 5
+#define WACOM_PKGLEN_TPC2FG 	14
+
+/* device IDs */
 #define STYLUS_DEVICE_ID	0x02
 #define TOUCH_DEVICE_ID		0x03
 #define CURSOR_DEVICE_ID	0x06
 #define ERASER_DEVICE_ID	0x0A
 #define PAD_DEVICE_ID		0x0F
 
+/* wacom data packet report IDs */
+#define WACOM_REPORT_PENABLED		2
+#define WACOM_REPORT_INTUOSREAD		5
+#define WACOM_REPORT_INTUOSWRITE	6
+#define WACOM_REPORT_INTUOSPAD		12
+#define WACOM_REPORT_TPC1FG		6
+#define WACOM_REPORT_TPC2FG		13
+
 enum {
 	PENPARTNER = 0,
 	GRAPHIRE,
@@ -32,6 +53,7 @@ enum {
 	WACOM_BEE,
 	WACOM_MO,
 	TABLETPC,
+	TABLETPC2FG,
 	MAX_TYPE
 };
 
@@ -43,8 +65,11 @@ struct wacom_features {
 	int pressure_max;
 	int distance_max;
 	int type;
-	int touch_x_max;
-	int touch_y_max;
+	int device_type;
+	int x_phy;
+	int y_phy;
+	unsigned char unit;
+	unsigned char unitExpo;
 };
 
 struct wacom_wac {
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ad7879.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ad7879.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ad7879.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ad7879.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,7 @@
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c.h>
+#include <linux/gpio.h>
 
 #include <linux/spi/ad7879.h>
 
@@ -132,7 +133,9 @@ struct ad7879 {
 	struct input_dev	*input;
 	struct work_struct	work;
 	struct timer_list	timer;
-
+#ifdef CONFIG_GPIOLIB
+	struct gpio_chip	gc;
+#endif
 	struct mutex		mutex;
 	unsigned		disabled:1;	/* P: mutex */
 
@@ -150,11 +153,9 @@ struct ad7879 {
 	u8			median;
 	u16			x_plate_ohms;
 	u16			pressure_max;
-	u16			gpio_init;
 	u16			cmd_crtl1;
 	u16			cmd_crtl2;
 	u16			cmd_crtl3;
-	unsigned		gpio:1;
 };
 
 static int ad7879_read(bus_device *, u8);
@@ -237,24 +238,6 @@ static irqreturn_t ad7879_irq(int irq, v
 
 static void ad7879_setup(struct ad7879 *ts)
 {
-	ts->cmd_crtl3 = AD7879_YPLUS_BIT |
-			AD7879_XPLUS_BIT |
-			AD7879_Z2_BIT |
-			AD7879_Z1_BIT |
-			AD7879_TEMPMASK_BIT |
-			AD7879_AUXVBATMASK_BIT |
-			AD7879_GPIOALERTMASK_BIT;
-
-	ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
-			AD7879_AVG(ts->averaging) |
-			AD7879_MFS(ts->median) |
-			AD7879_FCD(ts->first_conversion_delay) |
-			ts->gpio_init;
-
-	ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
-			AD7879_ACQ(ts->acquisition_time) |
-			AD7879_TMR(ts->pen_down_acc_interval);
-
 	ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
 	ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3);
 	ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1);
@@ -324,48 +307,132 @@ static ssize_t ad7879_disable_store(stru
 
 static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store);
 
-static ssize_t ad7879_gpio_show(struct device *dev,
-				     struct device_attribute *attr, char *buf)
+static struct attribute *ad7879_attributes[] = {
+	&dev_attr_disable.attr,
+	NULL
+};
+
+static const struct attribute_group ad7879_attr_group = {
+	.attrs = ad7879_attributes,
+};
+
+#ifdef CONFIG_GPIOLIB
+static int ad7879_gpio_direction_input(struct gpio_chip *chip,
+					unsigned gpio)
 {
-	struct ad7879 *ts = dev_get_drvdata(dev);
+	struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+	int err;
 
-	return sprintf(buf, "%u\n", ts->gpio);
+	mutex_lock(&ts->mutex);
+	ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL;
+	err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+	mutex_unlock(&ts->mutex);
+
+	return err;
 }
 
-static ssize_t ad7879_gpio_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
+static int ad7879_gpio_direction_output(struct gpio_chip *chip,
+					unsigned gpio, int level)
 {
-	struct ad7879 *ts = dev_get_drvdata(dev);
-	unsigned long val;
-	int error;
+	struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+	int err;
 
-	error = strict_strtoul(buf, 10, &val);
-	if (error)
-		return error;
+	mutex_lock(&ts->mutex);
+	ts->cmd_crtl2 &= ~AD7879_GPIODIR;
+	ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIOPOL;
+	if (level)
+		ts->cmd_crtl2 |= AD7879_GPIO_DATA;
+	else
+		ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
+
+	err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+	mutex_unlock(&ts->mutex);
+
+	return err;
+}
+
+static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct ad7879 *ts = container_of(chip, struct ad7879, gc);
+	u16 val;
 
 	mutex_lock(&ts->mutex);
-	ts->gpio = !!val;
-	error = ad7879_write(ts->bus, AD7879_REG_CTRL2,
-			   ts->gpio ?
-				ts->cmd_crtl2 & ~AD7879_GPIO_DATA :
-				ts->cmd_crtl2 | AD7879_GPIO_DATA);
+	val = ad7879_read(ts->bus, AD7879_REG_CTRL2);
 	mutex_unlock(&ts->mutex);
 
-	return error ? : count;
+	return !!(val & AD7879_GPIO_DATA);
 }
 
-static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
+static void ad7879_gpio_set_value(struct gpio_chip *chip,
+				  unsigned gpio, int value)
+{
+	struct ad7879 *ts = container_of(chip, struct ad7879, gc);
 
-static struct attribute *ad7879_attributes[] = {
-	&dev_attr_disable.attr,
-	&dev_attr_gpio.attr,
-	NULL
-};
+	mutex_lock(&ts->mutex);
+	if (value)
+		ts->cmd_crtl2 |= AD7879_GPIO_DATA;
+	else
+		ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
 
-static const struct attribute_group ad7879_attr_group = {
-	.attrs = ad7879_attributes,
-};
+	ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+	mutex_unlock(&ts->mutex);
+}
+
+static int __devinit ad7879_gpio_add(struct device *dev)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	struct ad7879_platform_data *pdata = dev->platform_data;
+	int ret = 0;
+
+	if (pdata->gpio_export) {
+		ts->gc.direction_input = ad7879_gpio_direction_input;
+		ts->gc.direction_output = ad7879_gpio_direction_output;
+		ts->gc.get = ad7879_gpio_get_value;
+		ts->gc.set = ad7879_gpio_set_value;
+		ts->gc.can_sleep = 1;
+		ts->gc.base = pdata->gpio_base;
+		ts->gc.ngpio = 1;
+		ts->gc.label = "AD7879-GPIO";
+		ts->gc.owner = THIS_MODULE;
+		ts->gc.dev = dev;
+
+		ret = gpiochip_add(&ts->gc);
+		if (ret)
+			dev_err(dev, "failed to register gpio %d\n",
+				ts->gc.base);
+	}
+
+	return ret;
+}
+
+/*
+ * We mark ad7879_gpio_remove inline so there is a chance the code
+ * gets discarded when not needed. We can't do __devinit/__devexit
+ * markup since it is used in both probe and remove methods.
+ */
+static inline void ad7879_gpio_remove(struct device *dev)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	struct ad7879_platform_data *pdata = dev->platform_data;
+	int ret;
+
+	if (pdata->gpio_export) {
+		ret = gpiochip_remove(&ts->gc);
+		if (ret)
+			dev_err(dev, "failed to remove gpio %d\n",
+				ts->gc.base);
+	}
+}
+#else
+static inline int ad7879_gpio_add(struct device *dev)
+{
+	return 0;
+}
+
+static inline void ad7879_gpio_remove(struct device *dev)
+{
+}
+#endif
 
 static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
 {
@@ -403,12 +470,6 @@ static int __devinit ad7879_construct(bu
 	ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
 	ts->median = pdata->median;
 
-	if (pdata->gpio_output)
-		ts->gpio_init = AD7879_GPIO_EN |
-				(pdata->gpio_default ? 0 : AD7879_GPIO_DATA);
-	else
-		ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR;
-
 	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev));
 
 	input_dev->name = "AD7879 Touchscreen";
@@ -446,6 +507,23 @@ static int __devinit ad7879_construct(bu
 		goto err_free_mem;
 	}
 
+	ts->cmd_crtl3 = AD7879_YPLUS_BIT |
+			AD7879_XPLUS_BIT |
+			AD7879_Z2_BIT |
+			AD7879_Z1_BIT |
+			AD7879_TEMPMASK_BIT |
+			AD7879_AUXVBATMASK_BIT |
+			AD7879_GPIOALERTMASK_BIT;
+
+	ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
+			AD7879_AVG(ts->averaging) |
+			AD7879_MFS(ts->median) |
+			AD7879_FCD(ts->first_conversion_delay);
+
+	ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
+			AD7879_ACQ(ts->acquisition_time) |
+			AD7879_TMR(ts->pen_down_acc_interval);
+
 	ad7879_setup(ts);
 
 	err = request_irq(bus->irq, ad7879_irq,
@@ -460,15 +538,21 @@ static int __devinit ad7879_construct(bu
 	if (err)
 		goto err_free_irq;
 
-	err = input_register_device(input_dev);
+	err = ad7879_gpio_add(&bus->dev);
 	if (err)
 		goto err_remove_attr;
 
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_remove_gpio;
+
 	dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n",
 		 revid >> 8, bus->irq);
 
 	return 0;
 
+err_remove_gpio:
+	ad7879_gpio_remove(&bus->dev);
 err_remove_attr:
 	sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group);
 err_free_irq:
@@ -481,6 +565,7 @@ err_free_mem:
 
 static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
 {
+	ad7879_gpio_remove(&bus->dev);
 	ad7879_disable(ts);
 	sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
 	free_irq(ts->bus->irq, ts);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ads7846.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ads7846.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ads7846.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ads7846.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,10 +29,9 @@
 #include <linux/spi/ads7846.h>
 #include <asm/irq.h>
 
-
 /*
  * This code has been heavily tested on a Nokia 770, and lightly
- * tested on other ads7846 devices (OSK/Mistral, Lubbock).
+ * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz).
  * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
@@ -43,7 +42,7 @@
  * have to maintain our own SW IRQ disabled status. This should be
  * removed as soon as the affected platform's IRQ handling is fixed.
  *
- * app note sbaa036 talks in more detail about accurate sampling...
+ * App note sbaa036 talks in more detail about accurate sampling...
  * that ought to help in situations like LCDs inducing noise (which
  * can also be helped by using synch signals) and more generally.
  * This driver tries to utilize the measures described in the app
@@ -566,10 +565,8 @@ static void ads7846_rx(void *ads)
 	 * once more the measurement
 	 */
 	if (packet->tc.ignore || Rt > ts->pressure_max) {
-#ifdef VERBOSE
-		pr_debug("%s: ignored %d pressure %d\n",
-			dev_name(&ts->spi->dev), packet->tc.ignore, Rt);
-#endif
+		dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
+			 packet->tc.ignore, Rt);
 		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
 			      HRTIMER_MODE_REL);
 		return;
@@ -598,9 +595,7 @@ static void ads7846_rx(void *ads)
 		if (!ts->pendown) {
 			input_report_key(input, BTN_TOUCH, 1);
 			ts->pendown = 1;
-#ifdef VERBOSE
-			dev_dbg(&ts->spi->dev, "DOWN\n");
-#endif
+			dev_vdbg(&ts->spi->dev, "DOWN\n");
 		}
 
 		if (ts->swap_xy)
@@ -608,12 +603,10 @@ static void ads7846_rx(void *ads)
 
 		input_report_abs(input, ABS_X, x);
 		input_report_abs(input, ABS_Y, y);
-		input_report_abs(input, ABS_PRESSURE, Rt);
+		input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);
 
 		input_sync(input);
-#ifdef VERBOSE
-		dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
-#endif
+		dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
 	}
 
 	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
@@ -723,9 +716,7 @@ static enum hrtimer_restart ads7846_time
 			input_sync(input);
 
 			ts->pendown = 0;
-#ifdef VERBOSE
-			dev_dbg(&ts->spi->dev, "UP\n");
-#endif
+			dev_vdbg(&ts->spi->dev, "UP\n");
 		}
 
 		/* measurement cycle ended */
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/atmel_tsadcc.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel_tsadcc.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/atmel_tsadcc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel_tsadcc.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,8 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <mach/board.h>
+#include <mach/cpu.h>
 
 /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
 
@@ -36,7 +38,9 @@
 #define	  ATMEL_TSADCC_LOWRES	(1    <<  4)	/* Resolution selection */
 #define	  ATMEL_TSADCC_SLEEP	(1    <<  5)	/* Sleep mode */
 #define	  ATMEL_TSADCC_PENDET	(1    <<  6)	/* Pen Detect selection */
+#define	  ATMEL_TSADCC_PRES	(1    <<  7)	/* Pressure Measurement Selection */
 #define	  ATMEL_TSADCC_PRESCAL	(0x3f <<  8)	/* Prescalar Rate Selection */
+#define	  ATMEL_TSADCC_EPRESCAL	(0xff <<  8)	/* Prescalar Rate Selection (Extended) */
 #define	  ATMEL_TSADCC_STARTUP	(0x7f << 16)	/* Start Up time */
 #define	  ATMEL_TSADCC_SHTIM	(0xf  << 24)	/* Sample & Hold time */
 #define	  ATMEL_TSADCC_PENDBC	(0xf  << 28)	/* Pen Detect debouncing time */
@@ -84,7 +88,13 @@
 #define ATMEL_TSADCC_CDR4	0x40	/* Channel Data 4 */
 #define ATMEL_TSADCC_CDR5	0x44	/* Channel Data 5 */
 
-#define ADC_CLOCK	1000000
+#define ATMEL_TSADCC_XPOS	0x50
+#define ATMEL_TSADCC_Z1DAT	0x54
+#define ATMEL_TSADCC_Z2DAT	0x58
+
+#define PRESCALER_VAL(x)	((x) >> 8)
+
+#define ADC_DEFAULT_CLOCK	100000
 
 struct atmel_tsadcc {
 	struct input_dev	*input;
@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(
 	struct atmel_tsadcc	*ts_dev;
 	struct input_dev	*input_dev;
 	struct resource		*res;
+	struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
 	int		err = 0;
 	unsigned int	prsc;
 	unsigned int	reg;
@@ -242,31 +253,49 @@ static int __devinit atmel_tsadcc_probe(
 	input_dev->phys = ts_dev->phys;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
+	__set_bit(EV_ABS, input_dev->evbit);
 	input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
 
+	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
 	/* clk_enable() always returns 0, no need to check it */
 	clk_enable(ts_dev->clk);
 
 	prsc = clk_get_rate(ts_dev->clk);
 	dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 
-	prsc = prsc / ADC_CLOCK / 2 - 1;
+	if (!pdata)
+		goto err_fail;
+
+	if (!pdata->adc_clock)
+		pdata->adc_clock = ADC_DEFAULT_CLOCK;
+
+	prsc = (prsc / (2 * pdata->adc_clock)) - 1;
+
+	/* saturate if this value is too high */
+	if (cpu_is_at91sam9rl()) {
+		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL))
+			prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL);
+	} else {
+		if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL))
+			prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL);
+	}
+
+	dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc);
 
 	reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE		|
 		((0x00 << 5) & ATMEL_TSADCC_SLEEP)	|	/* Normal Mode */
 		((0x01 << 6) & ATMEL_TSADCC_PENDET)	|	/* Enable Pen Detect */
-		((prsc << 8) & ATMEL_TSADCC_PRESCAL)	|	/* PRESCAL */
-		((0x13 << 16) & ATMEL_TSADCC_STARTUP)	|	/* STARTUP */
-		((0x0F << 28) & ATMEL_TSADCC_PENDBC);		/* PENDBC */
+		(prsc << 8)				|
+		((0x26 << 16) & ATMEL_TSADCC_STARTUP)	|
+		((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC);
 
 	atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
 	atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
 	atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
-	atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM);
+	atmel_tsadcc_write(ATMEL_TSADCC_TSR,
+		(pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM);
 
 	atmel_tsadcc_read(ATMEL_TSADCC_SR);
 	atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/atmel-wm97xx.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel-wm97xx.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/atmel-wm97xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/atmel-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@
 #define ATMEL_WM97XX_AC97C_IRQ		(29)
 #define ATMEL_WM97XX_GPIO_DEFAULT	(32+16) /* Pin 16 on port B. */
 #else
-#error Unkown CPU, this driver only supports AT32AP700X CPUs.
+#error Unknown CPU, this driver only supports AT32AP700X CPUs.
 #endif
 
 struct continuous {
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/dynapro.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/dynapro.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/dynapro.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/dynapro.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,206 @@
+/*
+ * Dynapro serial touchscreen driver
+ *
+ * Copyright (c) 2009 Tias Guns
+ * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and
+ * Richard Lemon
+ *
+ */
+
+/*
+ * This 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.
+ */
+
+/*
+ * 2009/09/19 Tias Guns <tias@ulyssis.org>
+ *   Copied inexio.c and edited for Dynapro protocol (from retired Xorg module)
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Dynapro serial touchscreen driver"
+
+MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define DYNAPRO_FORMAT_TOUCH_BIT 0x40
+#define DYNAPRO_FORMAT_LENGTH 3
+#define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80
+
+#define DYNAPRO_MIN_XC 0
+#define DYNAPRO_MAX_XC 0x3ff
+#define DYNAPRO_MIN_YC 0
+#define DYNAPRO_MAX_YC 0x3ff
+
+#define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4))
+#define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7))
+#define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0])
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct dynapro {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char data[DYNAPRO_FORMAT_LENGTH];
+	char phys[32];
+};
+
+static void dynapro_process_data(struct dynapro *pdynapro)
+{
+	struct input_dev *dev = pdynapro->dev;
+
+	if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) {
+		input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data));
+		input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data));
+		input_report_key(dev, BTN_TOUCH,
+				 DYNAPRO_GET_TOUCHED(pdynapro->data));
+		input_sync(dev);
+
+		pdynapro->idx = 0;
+	}
+}
+
+static irqreturn_t dynapro_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags)
+{
+	struct dynapro *pdynapro = serio_get_drvdata(serio);
+
+	pdynapro->data[pdynapro->idx] = data;
+
+	if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0])
+		dynapro_process_data(pdynapro);
+	else
+		dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",
+			pdynapro->data[0]);
+
+	return IRQ_HANDLED;
+}
+
+static void dynapro_disconnect(struct serio *serio)
+{
+	struct dynapro *pdynapro = serio_get_drvdata(serio);
+
+	input_get_device(pdynapro->dev);
+	input_unregister_device(pdynapro->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(pdynapro->dev);
+	kfree(pdynapro);
+}
+
+/*
+ * dynapro_connect() is the routine that is called when someone adds a
+ * new serio device that supports dynapro protocol and registers it as
+ * an input device. This is usually accomplished using inputattach.
+ */
+
+static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct dynapro *pdynapro;
+	struct input_dev *input_dev;
+	int err;
+
+	pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!pdynapro || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	pdynapro->serio = serio;
+	pdynapro->dev = input_dev;
+	snprintf(pdynapro->phys, sizeof(pdynapro->phys),
+		 "%s/input0", serio->phys);
+
+	input_dev->name = "Dynapro Serial TouchScreen";
+	input_dev->phys = pdynapro->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_DYNAPRO;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0001;
+	input_dev->dev.parent = &serio->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(pdynapro->dev, ABS_X,
+			     DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0);
+	input_set_abs_params(pdynapro->dev, ABS_Y,
+			     DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, pdynapro);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(pdynapro->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(pdynapro);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id dynapro_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_DYNAPRO,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, dynapro_serio_ids);
+
+static struct serio_driver dynapro_drv = {
+	.driver		= {
+		.name	= "dynapro",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= dynapro_serio_ids,
+	.interrupt	= dynapro_interrupt,
+	.connect	= dynapro_connect,
+	.disconnect	= dynapro_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init dynapro_init(void)
+{
+	return serio_register_driver(&dynapro_drv);
+}
+
+static void __exit dynapro_exit(void)
+{
+	serio_unregister_driver(&dynapro_drv);
+}
+
+module_init(dynapro_init);
+module_exit(dynapro_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/Kconfig linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -111,6 +111,18 @@ config TOUCHSCREEN_DA9034
 	  Say Y here to enable the support for the touchscreen found
 	  on Dialog Semiconductor DA9034 PMIC.
 
+config TOUCHSCREEN_DYNAPRO
+	tristate "Dynapro serial touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Dynapro serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called dynapro.
+
 config TOUCHSCREEN_EETI
 	tristate "EETI touchscreen panel support"
 	depends on I2C
@@ -133,6 +145,18 @@ config TOUCHSCREEN_FUJITSU
 	  To compile this driver as a module, choose M here: the
 	  module will be called fujitsu-ts.
 
+config TOUCHSCREEN_S3C2410
+	tristate "Samsung S3C2410 touchscreen input driver"
+	depends on ARCH_S3C2410
+	select S3C24XX_ADC
+	help
+	  Say Y here if you have the s3c2410 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s3c2410_ts.
+
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
 	select SERIO
@@ -297,7 +321,7 @@ config TOUCHSCREEN_TOUCHWIN
 
 config TOUCHSCREEN_ATMEL_TSADCC
 	tristate "Atmel Touchscreen Interface"
-	depends on ARCH_AT91SAM9RL
+	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
 	help
 	  Say Y here if you have a 4-wire touchscreen connected to the
           ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
@@ -418,6 +442,7 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  - IdealTEK URTC1000
 	  - GoTop Super_Q2/GogoPen/PenPower tablets
 	  - JASTEC USB Touch Controller/DigiTech DTR-02U
+	  - Zytronic controllers
 
 	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
@@ -425,6 +450,18 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbtouchscreen.
 
+config TOUCHSCREEN_MC13783
+	tristate "Freescale MC13783 touchscreen input driver"
+	depends on MFD_MC13783
+	help
+	  Say Y here if you have an Freescale MC13783 PMIC on your
+	  board and want to use its touchscreen
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mc13783_ts.
+
 config TOUCHSCREEN_USB_EGALAX
 	default y
 	bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
@@ -490,6 +527,16 @@ config TOUCHSCREEN_USB_E2I
 	bool "e2i Touchscreen controller (e.g. from Mimo 740)"
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_ZYTRONIC
+	default y
+	bool "Zytronic controller" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ETT_TC5UH
+	default y
+	bool "ET&T TC5UH touchscreen controler support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  *
  * Notes:
  *     This is a wm97xx extended touch driver to capture touch
- *     data in a continuous manner on the Intel XScale archictecture
+ *     data in a continuous manner on the Intel XScale architecture
  *
  *  Features:
  *       - codecs supported:- WM9705, WM9712, WM9713
@@ -131,7 +131,7 @@ static int wm97xx_acc_pen_down(struct wm
 	/* When the AC97 queue has been drained we need to allow time
 	 * to buffer up samples otherwise we end up spinning polling
 	 * for samples.  The controller can't have a suitably low
-	 * threashold set to use the notifications it gives.
+	 * threshold set to use the notifications it gives.
 	 */
 	schedule_timeout_uninterruptible(1);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/Makefile linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Makefile
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -12,11 +12,13 @@ obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_CORGI)		+= corgi_ts.o
+obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
+obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MCS5000)	+= mcs5000_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)		+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)	+= mtouch.o
@@ -25,7 +27,9 @@ obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp68
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)	+= usbtouchscreen.o
+obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
+obj-$(CONFIG_TOUCHSCREEN_S3C2410)	+= s3c2410_ts.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
@@ -41,4 +45,3 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL)	+
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
-obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/mc13783_ts.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mc13783_ts.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/mc13783_ts.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/mc13783_ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,258 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 touchscreen.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.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/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_TS_NAME	"mc13783-ts"
+
+#define DEFAULT_SAMPLE_TOLERANCE 300
+
+static unsigned int sample_tolerance = DEFAULT_SAMPLE_TOLERANCE;
+module_param(sample_tolerance, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(sample_tolerance,
+		"If the minimal and maximal value read out for one axis (out "
+		"of three) differ by this value (default: "
+		__stringify(DEFAULT_SAMPLE_TOLERANCE) ") or more, the reading "
+		"is supposed to be wrong and is discarded.  Set to 0 to "
+		"disable this check.");
+
+struct mc13783_ts_priv {
+	struct input_dev *idev;
+	struct mc13783 *mc13783;
+	struct delayed_work work;
+	struct workqueue_struct *workq;
+	unsigned int sample[4];
+};
+
+static irqreturn_t mc13783_ts_handler(int irq, void *data)
+{
+	struct mc13783_ts_priv *priv = data;
+
+	mc13783_ackirq(priv->mc13783, irq);
+
+	/*
+	 * Kick off reading coordinates. Note that if work happens already
+	 * be queued for future execution (it rearms itself) it will not
+	 * be rescheduled for immediate execution here. However the rearm
+	 * delay is HZ / 50 which is acceptable.
+	 */
+	queue_delayed_work(priv->workq, &priv->work, 0);
+
+	return IRQ_HANDLED;
+}
+
+#define sort3(a0, a1, a2) ({						\
+		if (a0 > a1)						\
+			swap(a0, a1);					\
+		if (a1 > a2)						\
+			swap(a1, a2);					\
+		if (a0 > a1)						\
+			swap(a0, a1);					\
+		})
+
+static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
+{
+	struct input_dev *idev = priv->idev;
+	int x0, x1, x2, y0, y1, y2;
+	int cr0, cr1;
+
+	/*
+	 * the values are 10-bit wide only, but the two least significant
+	 * bits are for future 12 bit use and reading yields 0
+	 */
+	x0 = priv->sample[0] & 0xfff;
+	x1 = priv->sample[1] & 0xfff;
+	x2 = priv->sample[2] & 0xfff;
+	y0 = priv->sample[3] & 0xfff;
+	y1 = (priv->sample[0] >> 12) & 0xfff;
+	y2 = (priv->sample[1] >> 12) & 0xfff;
+	cr0 = (priv->sample[2] >> 12) & 0xfff;
+	cr1 = (priv->sample[3] >> 12) & 0xfff;
+
+	dev_dbg(&idev->dev,
+		"x: (% 4d,% 4d,% 4d) y: (% 4d, % 4d,% 4d) cr: (% 4d, % 4d)\n",
+		x0, x1, x2, y0, y1, y2, cr0, cr1);
+
+	sort3(x0, x1, x2);
+	sort3(y0, y1, y2);
+
+	cr0 = (cr0 + cr1) / 2;
+
+	if (!cr0 || !sample_tolerance ||
+			(x2 - x0 < sample_tolerance &&
+			 y2 - y0 < sample_tolerance)) {
+		/* report the median coordinate and average pressure */
+		if (cr0) {
+			input_report_abs(idev, ABS_X, x1);
+			input_report_abs(idev, ABS_Y, y1);
+
+			dev_dbg(&idev->dev, "report (%d, %d, %d)\n",
+					x1, y1, 0x1000 - cr0);
+			queue_delayed_work(priv->workq, &priv->work, HZ / 50);
+		} else
+			dev_dbg(&idev->dev, "report release\n");
+
+		input_report_abs(idev, ABS_PRESSURE,
+				cr0 ? 0x1000 - cr0 : cr0);
+		input_report_key(idev, BTN_TOUCH, cr0);
+		input_sync(idev);
+	} else
+		dev_dbg(&idev->dev, "discard event\n");
+}
+
+static void mc13783_ts_work(struct work_struct *work)
+{
+	struct mc13783_ts_priv *priv =
+		container_of(work, struct mc13783_ts_priv, work.work);
+	unsigned int mode = MC13783_ADC_MODE_TS;
+	unsigned int channel = 12;
+
+	if (mc13783_adc_do_conversion(priv->mc13783,
+				mode, channel, priv->sample) == 0)
+		mc13783_ts_report_sample(priv);
+}
+
+static int mc13783_ts_open(struct input_dev *dev)
+{
+	struct mc13783_ts_priv *priv = input_get_drvdata(dev);
+	int ret;
+
+	mc13783_lock(priv->mc13783);
+
+	mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS);
+
+	ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
+		mc13783_ts_handler, MC13783_TS_NAME, priv);
+	if (ret)
+		goto out;
+
+	ret = mc13783_reg_rmw(priv->mc13783, MC13783_ADC0,
+			MC13783_ADC0_TSMOD_MASK, MC13783_ADC0_TSMOD0);
+	if (ret)
+		mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv);
+out:
+	mc13783_unlock(priv->mc13783);
+	return ret;
+}
+
+static void mc13783_ts_close(struct input_dev *dev)
+{
+	struct mc13783_ts_priv *priv = input_get_drvdata(dev);
+
+	mc13783_lock(priv->mc13783);
+	mc13783_reg_rmw(priv->mc13783, MC13783_ADC0,
+			MC13783_ADC0_TSMOD_MASK, 0);
+	mc13783_irq_free(priv->mc13783, MC13783_IRQ_TS, priv);
+	mc13783_unlock(priv->mc13783);
+
+	cancel_delayed_work_sync(&priv->work);
+}
+
+static int __init mc13783_ts_probe(struct platform_device *pdev)
+{
+	struct mc13783_ts_priv *priv;
+	struct input_dev *idev;
+	int ret = -ENOMEM;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	idev = input_allocate_device();
+	if (!priv || !idev)
+		goto err_free_mem;
+
+	INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
+	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+	priv->idev = idev;
+
+	/*
+	 * We need separate workqueue because mc13783_adc_do_conversion
+	 * uses keventd and thus would deadlock.
+	 */
+	priv->workq = create_singlethread_workqueue("mc13783_ts");
+	if (!priv->workq)
+		goto err_free_mem;
+
+	idev->name = MC13783_TS_NAME;
+	idev->dev.parent = &pdev->dev;
+
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(idev, ABS_X, 0, 0xfff, 0, 0);
+	input_set_abs_params(idev, ABS_Y, 0, 0xfff, 0, 0);
+	input_set_abs_params(idev, ABS_PRESSURE, 0, 0xfff, 0, 0);
+
+	idev->open = mc13783_ts_open;
+	idev->close = mc13783_ts_close;
+
+	input_set_drvdata(idev, priv);
+
+	ret = input_register_device(priv->idev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"register input device failed with %d\n", ret);
+		goto err_destroy_wq;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	return 0;
+
+err_destroy_wq:
+	destroy_workqueue(priv->workq);
+err_free_mem:
+	input_free_device(idev);
+	kfree(priv);
+	return ret;
+}
+
+static int __devexit mc13783_ts_remove(struct platform_device *pdev)
+{
+	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);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_ts_driver = {
+	.remove		= __devexit_p(mc13783_ts_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_TS_NAME,
+	},
+};
+
+static int __init mc13783_ts_init(void)
+{
+	return platform_driver_probe(&mc13783_ts_driver, &mc13783_ts_probe);
+}
+module_init(mc13783_ts_init);
+
+static void __exit mc13783_ts_exit(void)
+{
+	platform_driver_unregister(&mc13783_ts_driver);
+}
+module_exit(mc13783_ts_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" MC13783_TS_NAME);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/pcap_ts.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/pcap_ts.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/pcap_ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/pcap_ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -233,7 +233,7 @@ static int pcap_ts_resume(struct device
 	return 0;
 }
 
-static struct dev_pm_ops pcap_ts_pm_ops = {
+static const struct dev_pm_ops pcap_ts_pm_ops = {
 	.suspend	= pcap_ts_suspend,
 	.resume		= pcap_ts_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/s3c2410_ts.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/s3c2410_ts.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/s3c2410_ts.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/s3c2410_ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,457 @@
+/*
+ * Samsung S3C24XX touchscreen driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the term 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 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Copyright 2008 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Simtec Electronics <linux@simtec.co.uk>
+ *
+ * Additional work by Herbert Pötzl <herbert@13thfloor.at> and
+ * Harald Welte <laforge@openmoko.org>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/adc.h>
+#include <plat/regs-adc.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/ts.h>
+
+#define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
+
+#define INT_DOWN	(0)
+#define INT_UP		(1 << 8)
+
+#define WAIT4INT	(S3C2410_ADCTSC_YM_SEN | \
+			 S3C2410_ADCTSC_YP_SEN | \
+			 S3C2410_ADCTSC_XP_SEN | \
+			 S3C2410_ADCTSC_XY_PST(3))
+
+#define AUTOPST		(S3C2410_ADCTSC_YM_SEN | \
+			 S3C2410_ADCTSC_YP_SEN | \
+			 S3C2410_ADCTSC_XP_SEN | \
+			 S3C2410_ADCTSC_AUTO_PST | \
+			 S3C2410_ADCTSC_XY_PST(0))
+
+/* Per-touchscreen data. */
+
+/**
+ * struct s3c2410ts - driver touchscreen state.
+ * @client: The ADC client we registered with the core driver.
+ * @dev: The device we are bound to.
+ * @input: The input device we registered with the input subsystem.
+ * @clock: The clock for the adc.
+ * @io: Pointer to the IO base.
+ * @xp: The accumulated X position data.
+ * @yp: The accumulated Y position data.
+ * @irq_tc: The interrupt number for pen up/down interrupt
+ * @count: The number of samples collected.
+ * @shift: The log2 of the maximum count to read in one go.
+ */
+struct s3c2410ts {
+	struct s3c_adc_client *client;
+	struct device *dev;
+	struct input_dev *input;
+	struct clk *clock;
+	void __iomem *io;
+	unsigned long xp;
+	unsigned long yp;
+	int irq_tc;
+	int count;
+	int shift;
+};
+
+static struct s3c2410ts ts;
+
+/**
+ * s3c2410_ts_connect - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+*/
+static inline void s3c2410_ts_connect(void)
+{
+	s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+	s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
+
+/**
+ * get_down - return the down state of the pen
+ * @data0: The data read from ADCDAT0 register.
+ * @data1: The data read from ADCDAT1 register.
+ *
+ * Return non-zero if both readings show that the pen is down.
+ */
+static inline bool get_down(unsigned long data0, unsigned long data1)
+{
+	/* returns true if both data values show stylus down */
+	return (!(data0 & S3C2410_ADCDAT0_UPDOWN) &&
+		!(data1 & S3C2410_ADCDAT0_UPDOWN));
+}
+
+static void touch_timer_fire(unsigned long data)
+{
+	unsigned long data0;
+	unsigned long data1;
+	bool down;
+
+	data0 = readl(ts.io + S3C2410_ADCDAT0);
+	data1 = readl(ts.io + S3C2410_ADCDAT1);
+
+	down = get_down(data0, data1);
+
+	if (ts.count == (1 << ts.shift)) {
+		ts.xp >>= ts.shift;
+		ts.yp >>= ts.shift;
+
+		dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
+			__func__, ts.xp, ts.yp, ts.count);
+
+		input_report_abs(ts.input, ABS_X, ts.xp);
+		input_report_abs(ts.input, ABS_Y, ts.yp);
+
+		input_report_key(ts.input, BTN_TOUCH, 1);
+		input_sync(ts.input);
+
+		ts.xp = 0;
+		ts.yp = 0;
+		ts.count = 0;
+	}
+
+	if (down) {
+		s3c_adc_start(ts.client, 0, 1 << ts.shift);
+	} else {
+		ts.count = 0;
+
+		input_report_key(ts.input, BTN_TOUCH, 0);
+		input_sync(ts.input);
+
+		writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+	}
+}
+
+static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0);
+
+/**
+ * stylus_irq - touchscreen stylus event interrupt
+ * @irq: The interrupt number
+ * @dev_id: The device ID.
+ *
+ * Called when the IRQ_TC is fired for a pen up or down event.
+ */
+static irqreturn_t stylus_irq(int irq, void *dev_id)
+{
+	unsigned long data0;
+	unsigned long data1;
+	bool down;
+
+	data0 = readl(ts.io + S3C2410_ADCDAT0);
+	data1 = readl(ts.io + S3C2410_ADCDAT1);
+
+	down = get_down(data0, data1);
+
+	/* TODO we should never get an interrupt with down set while
+	 * the timer is running, but maybe we ought to verify that the
+	 * timer isn't running anyways. */
+
+	if (down)
+		s3c_adc_start(ts.client, 0, 1 << ts.shift);
+	else
+		dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * s3c24xx_ts_conversion - ADC conversion callback
+ * @client: The client that was registered with the ADC core.
+ * @data0: The reading from ADCDAT0.
+ * @data1: The reading from ADCDAT1.
+ * @left: The number of samples left.
+ *
+ * Called when a conversion has finished.
+ */
+static void s3c24xx_ts_conversion(struct s3c_adc_client *client,
+				  unsigned data0, unsigned data1,
+				  unsigned *left)
+{
+	dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1);
+
+	ts.xp += data0;
+	ts.yp += data1;
+
+	ts.count++;
+
+	/* From tests, it seems that it is unlikely to get a pen-up
+	 * event during the conversion process which means we can
+	 * ignore any pen-up events with less than the requisite
+	 * count done.
+	 *
+	 * In several thousand conversions, no pen-ups where detected
+	 * before count completed.
+	 */
+}
+
+/**
+ * s3c24xx_ts_select - ADC selection callback.
+ * @client: The client that was registered with the ADC core.
+ * @select: The reason for select.
+ *
+ * Called when the ADC core selects (or deslects) us as a client.
+ */
+static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select)
+{
+	if (select) {
+		writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
+		       ts.io + S3C2410_ADCTSC);
+	} else {
+		mod_timer(&touch_timer, jiffies+1);
+		writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
+	}
+}
+
+/**
+ * s3c2410ts_probe - device core probe entry point
+ * @pdev: The device we are being bound to.
+ *
+ * Initialise, find and allocate any resources we need to run and then
+ * register with the ADC and input systems.
+ */
+static int __devinit s3c2410ts_probe(struct platform_device *pdev)
+{
+	struct s3c2410_ts_mach_info *info;
+	struct device *dev = &pdev->dev;
+	struct input_dev *input_dev;
+	struct resource *res;
+	int ret = -EINVAL;
+
+	/* Initialise input stuff */
+	memset(&ts, 0, sizeof(struct s3c2410ts));
+
+	ts.dev = dev;
+
+	info = pdev->dev.platform_data;
+	if (!info) {
+		dev_err(dev, "no platform data, cannot attach\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "initialising touchscreen\n");
+
+	ts.clock = clk_get(dev, "adc");
+	if (IS_ERR(ts.clock)) {
+		dev_err(dev, "cannot get adc clock source\n");
+		return -ENOENT;
+	}
+
+	clk_enable(ts.clock);
+	dev_dbg(dev, "got and enabled clocks\n");
+
+	ts.irq_tc = ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
+		dev_err(dev, "no resource for interrupt\n");
+		goto err_clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "no resource for registers\n");
+		ret = -ENOENT;
+		goto err_clk;
+	}
+
+	ts.io = ioremap(res->start, resource_size(res));
+	if (ts.io == NULL) {
+		dev_err(dev, "cannot map registers\n");
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	/* Configure the touchscreen external FETs on the S3C2410 */
+	if (!platform_get_device_id(pdev)->driver_data)
+		s3c2410_ts_connect();
+
+	ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
+				     s3c24xx_ts_conversion, 1);
+	if (IS_ERR(ts.client)) {
+		dev_err(dev, "failed to register adc client\n");
+		ret = PTR_ERR(ts.client);
+		goto err_iomap;
+	}
+
+	/* Initialise registers */
+	if ((info->delay & 0xffff) > 0)
+		writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
+
+	writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		dev_err(dev, "Unable to allocate the input device !!\n");
+		ret = -ENOMEM;
+		goto err_iomap;
+	}
+
+	ts.input = input_dev;
+	ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
+	input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
+
+	ts.input->name = "S3C24XX TouchScreen";
+	ts.input->id.bustype = BUS_HOST;
+	ts.input->id.vendor = 0xDEAD;
+	ts.input->id.product = 0xBEEF;
+	ts.input->id.version = 0x0102;
+
+	ts.shift = info->oversampling_shift;
+
+	ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
+			  "s3c2410_ts_pen", ts.input);
+	if (ret) {
+		dev_err(dev, "cannot get TC interrupt\n");
+		goto err_inputdev;
+	}
+
+	dev_info(dev, "driver attached, registering input device\n");
+
+	/* All went ok, so register to the input system */
+	ret = input_register_device(ts.input);
+	if (ret < 0) {
+		dev_err(dev, "failed to register input device\n");
+		ret = -EIO;
+		goto err_tcirq;
+	}
+
+	return 0;
+
+ err_tcirq:
+	free_irq(ts.irq_tc, ts.input);
+ err_inputdev:
+	input_unregister_device(ts.input);
+ err_iomap:
+	iounmap(ts.io);
+ err_clk:
+	del_timer_sync(&touch_timer);
+	clk_put(ts.clock);
+	return ret;
+}
+
+/**
+ * s3c2410ts_remove - device core removal entry point
+ * @pdev: The device we are being removed from.
+ *
+ * Free up our state ready to be removed.
+ */
+static int __devexit s3c2410ts_remove(struct platform_device *pdev)
+{
+	free_irq(ts.irq_tc, ts.input);
+	del_timer_sync(&touch_timer);
+
+	clk_disable(ts.clock);
+	clk_put(ts.clock);
+
+	input_unregister_device(ts.input);
+	iounmap(ts.io);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c2410ts_suspend(struct device *dev)
+{
+	writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC);
+	disable_irq(ts.irq_tc);
+	clk_disable(ts.clock);
+
+	return 0;
+}
+
+static int s3c2410ts_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c2410_ts_mach_info *info = pdev->dev.platform_data;
+
+	clk_enable(ts.clock);
+
+	/* Initialise registers */
+	if ((info->delay & 0xffff) > 0)
+		writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY);
+
+	writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
+
+	return 0;
+}
+
+static struct dev_pm_ops s3c_ts_pmops = {
+	.suspend	= s3c2410ts_suspend,
+	.resume		= s3c2410ts_resume,
+};
+#endif
+
+static struct platform_device_id s3cts_driver_ids[] = {
+	{ "s3c2410-ts", 0 },
+	{ "s3c2440-ts", 1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
+
+static struct platform_driver s3c_ts_driver = {
+	.driver         = {
+		.name   = "s3c24xx-ts",
+		.owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &s3c_ts_pmops,
+#endif
+	},
+	.id_table	= s3cts_driver_ids,
+	.probe		= s3c2410ts_probe,
+	.remove		= __devexit_p(s3c2410ts_remove),
+};
+
+static int __init s3c2410ts_init(void)
+{
+	return platform_driver_register(&s3c_ts_driver);
+}
+
+static void __exit s3c2410ts_exit(void)
+{
+	platform_driver_unregister(&s3c_ts_driver);
+}
+
+module_init(s3c2410ts_init);
+module_exit(s3c2410ts_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
+	      "Ben Dooks <ben@simtec.co.uk>, "
+	      "Simtec Electronics <linux@simtec.co.uk>");
+MODULE_DESCRIPTION("S3C24XX Touchscreen driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ucb1400_ts.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ucb1400_ts.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -355,10 +355,13 @@ static int ucb1400_ts_probe(struct platf
 		goto err;
 	}
 
-	error = ucb1400_ts_detect_irq(ucb);
-	if (error) {
-		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
-		goto err_free_devs;
+	/* Only in case the IRQ line wasn't supplied, try detecting it */
+	if (ucb->irq < 0) {
+		error = ucb1400_ts_detect_irq(ucb);
+		if (error) {
+			printk(KERN_ERR "UCB1400: IRQ probe failed\n");
+			goto err_free_devs;
+		}
 	}
 
 	init_waitqueue_head(&ucb->ts_wait);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/usbtouchscreen.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/usbtouchscreen.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/usbtouchscreen.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/usbtouchscreen.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
  *  - General Touch
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *  - JASTEC USB touch controller/DigiTech DTR-02U
+ *  - Zytronic capacitive touchscreen
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -73,6 +74,15 @@ struct usbtouch_device_info {
 	int min_press, max_press;
 	int rept_size;
 
+	/*
+	 * Always service the USB devices irq not just when the input device is
+	 * open. This is useful when devices have a watchdog which prevents us
+	 * from periodically polling the device. Leave this unset unless your
+	 * touchscreen device requires it, as it does consume more of the USB
+	 * bandwidth.
+	 */
+	bool irq_always;
+
 	void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
 
 	/*
@@ -121,6 +131,8 @@ enum {
 	DEVTYPE_GOTOP,
 	DEVTYPE_JASTEC,
 	DEVTYPE_E2I,
+	DEVTYPE_ZYTRONIC,
+	DEVTYPE_TC5UH,
 };
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -201,6 +213,15 @@ static struct usb_device_id usbtouch_dev
 #ifdef CONFIG_TOUCHSCREEN_USB_E2I
 	{USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+	{USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+	{USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH},
+#endif
+
 	{}
 };
 
@@ -538,6 +559,19 @@ static int irtouch_read_data(struct usbt
 }
 #endif
 
+/*****************************************************************************
+ * ET&T TC5UH part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
+	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
+	dev->touch = pkt[0] & 0x01;
+
+	return 1;
+}
+#endif
 
 /*****************************************************************************
  * IdealTEK URTC1000 Part
@@ -584,8 +618,8 @@ static int idealtek_read_data(struct usb
 #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
 static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
-	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ;
-	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ;
+	dev->x = (pkt[2] << 8) | pkt[1];
+	dev->y = (pkt[4] << 8) | pkt[3];
 	dev->press = pkt[5] & 0xff;
 	dev->touch = pkt[0] & 0x01;
 
@@ -621,6 +655,39 @@ static int jastec_read_data(struct usbto
 }
 #endif
 
+/*****************************************************************************
+ * Zytronic Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	switch (pkt[0]) {
+	case 0x3A: /* command response */
+		dbg("%s: Command response %d", __func__, pkt[1]);
+		break;
+
+	case 0xC0: /* down */
+		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+		dev->touch = 1;
+		dbg("%s: down %d,%d", __func__, dev->x, dev->y);
+		return 1;
+
+	case 0x80: /* up */
+		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+		dev->touch = 0;
+		dbg("%s: up %d,%d", __func__, dev->x, dev->y);
+		return 1;
+
+	default:
+		dbg("%s: Unknown return %d", __func__, pkt[0]);
+		break;
+	}
+
+	return 0;
+}
+#endif
 
 /*****************************************************************************
  * the different device descriptors
@@ -742,9 +809,9 @@ static struct usbtouch_device_info usbto
 #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
 	[DEVTYPE_GENERAL_TOUCH] = {
 		.min_xc		= 0x0,
-		.max_xc		= 0x0500,
+		.max_xc		= 0x7fff,
 		.min_yc		= 0x0,
-		.max_yc		= 0x0500,
+		.max_yc		= 0x7fff,
 		.rept_size	= 7,
 		.read_data	= general_touch_read_data,
 	},
@@ -783,6 +850,29 @@ static struct usbtouch_device_info usbto
 		.read_data	= e2i_read_data,
 	},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+	[DEVTYPE_ZYTRONIC] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x03ff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x03ff,
+		.rept_size	= 5,
+		.read_data	= zytronic_read_data,
+		.irq_always     = true,
+	},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+	[DEVTYPE_TC5UH] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x0fff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x0fff,
+		.rept_size	= 5,
+		.read_data	= tc5uh_read_data,
+	},
+#endif
 };
 
 
@@ -933,8 +1023,10 @@ static int usbtouch_open(struct input_de
 
 	usbtouch->irq->dev = usbtouch->udev;
 
-	if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
-		return -EIO;
+	if (!usbtouch->type->irq_always) {
+		if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
+		  return -EIO;
+	}
 
 	return 0;
 }
@@ -943,7 +1035,8 @@ static void usbtouch_close(struct input_
 {
 	struct usbtouch_usb *usbtouch = input_get_drvdata(input);
 
-	usb_kill_urb(usbtouch->irq);
+	if (!usbtouch->type->irq_always)
+		usb_kill_urb(usbtouch->irq);
 }
 
 
@@ -1066,6 +1159,9 @@ static int usbtouch_probe(struct usb_int
 
 	usb_set_intfdata(intf, usbtouch);
 
+	if (usbtouch->type->irq_always)
+		usb_submit_urb(usbtouch->irq, GFP_KERNEL);
+
 	return 0;
 
 out_free_buffers:
@@ -1087,7 +1183,7 @@ static void usbtouch_disconnect(struct u
 
 	dbg("%s - usbtouch is initialized, cleaning up", __func__);
 	usb_set_intfdata(intf, NULL);
-	usb_kill_urb(usbtouch->irq);
+	/* this will stop IO via close */
 	input_unregister_device(usbtouch->input);
 	usb_free_urb(usbtouch->irq);
 	usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c linux-libre-2.6.33-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c
--- linux-libre-2.6.32-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@ static int wm97xx_acc_pen_down(struct wm
 	/* When the AC97 queue has been drained we need to allow time
 	 * to buffer up samples otherwise we end up spinning polling
 	 * for samples.  The controller can't have a suitably low
-	 * threashold set to use the notifications it gives.
+	 * threshold set to use the notifications it gives.
 	 */
 	msleep(1);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/input/xen-kbdfront.c linux-libre-2.6.33-gnu1/drivers/input/xen-kbdfront.c
--- linux-libre-2.6.32-gnu1/drivers/input/xen-kbdfront.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/input/xen-kbdfront.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,10 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/input.h>
+
 #include <asm/xen/hypervisor.h>
+
+#include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/page.h>
 #include <xen/interface/io/fbif.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/act2000/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/act2000/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/act2000/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/act2000/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for IBM Active 2000 ISDN driver
-#
 config ISDN_DRV_ACT2000
 	tristate "IBM Active 2000 support"
 	depends on ISA
@@ -10,4 +7,3 @@ config ISDN_DRV_ACT2000
 	  into the card using a utility which is part of the latest
 	  isdn4k-utils package. Please read the file
 	  <file:Documentation/isdn/README.act2000> for more information.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/capi/capidrv.c linux-libre-2.6.33-gnu1/drivers/isdn/capi/capidrv.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/capi/capidrv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/capi/capidrv.c	2010-02-24 13:52:17.000000000 -0500
@@ -830,7 +830,7 @@ static void handle_controller(_cmsg * cm
 		      case 0: break;
 		      case 1: s = "unknown class"; break;
 		      case 2: s = "unknown function"; break;
-		      default: s = "unkown error"; break;
+		      default: s = "unknown error"; break;
 		   }
 		   if (s)
 	           printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/capi/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/capi/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/capi/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/capi/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for the CAPI subsystem
-#
 config ISDN_DRV_AVMB1_VERBOSE_REASON
 	bool "Verbose reason code reporting"
 	default y
@@ -59,4 +56,3 @@ config ISDN_CAPI_CAPIDRV
 	  the legacy isdn4linux link layer.  If you have a card which is
 	  supported by a CAPI driver, but still want to use old features like
 	  ippp interfaces or ttyI emulation, say Y/M here.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/asyncdata.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/asyncdata.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/asyncdata.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/asyncdata.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@
 
 /* check if byte must be stuffed/escaped
  * I'm not sure which data should be encoded.
- * Therefore I will go the hard way and decode every value
+ * Therefore I will go the hard way and encode every value
  * less than 0x20, the flag sequence and the control escape char.
  */
 static inline int muststuff(unsigned char c)
@@ -35,303 +35,383 @@ static inline int muststuff(unsigned cha
 
 /* == data input =========================================================== */
 
-/* process a block of received bytes in command mode (modem response)
+/* process a block of received bytes in command mode
+ * (mstate != MS_LOCKED && (inputstate & INS_command))
+ * Append received bytes to the command response buffer and forward them
+ * line by line to the response handler. Exit whenever a mode/state change
+ * might have occurred.
  * Return value:
  *	number of processed bytes
  */
-static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
-			   struct inbuf_t *inbuf)
+static unsigned cmd_loop(unsigned numbytes, struct inbuf_t *inbuf)
 {
+	unsigned char *src = inbuf->data + inbuf->head;
 	struct cardstate *cs = inbuf->cs;
-	unsigned cbytes      = cs->cbytes;
-	int inputstate = inbuf->inputstate;
-	int startbytes = numbytes;
+	unsigned cbytes = cs->cbytes;
+	unsigned procbytes = 0;
+	unsigned char c;
 
-	for (;;) {
-		cs->respdata[cbytes] = c;
-		if (c == 10 || c == 13) {
-			gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
+	while (procbytes < numbytes) {
+		c = *src++;
+		procbytes++;
+
+		switch (c) {
+		case '\n':
+			if (cbytes == 0 && cs->respdata[0] == '\r') {
+				/* collapse LF with preceding CR */
+				cs->respdata[0] = 0;
+				break;
+			}
+			/* --v-- fall through --v-- */
+		case '\r':
+			/* end of message line, pass to response handler */
+			gig_dbg(DEBUG_TRANSCMD, "%s: End of Message (%d Bytes)",
 				__func__, cbytes);
+			if (cbytes >= MAX_RESP_SIZE) {
+				dev_warn(cs->dev, "response too large (%d)\n",
+					 cbytes);
+				cbytes = MAX_RESP_SIZE;
+			}
 			cs->cbytes = cbytes;
-			gigaset_handle_modem_response(cs); /* can change
-							      cs->dle */
+			gigaset_handle_modem_response(cs);
 			cbytes = 0;
 
-			if (cs->dle &&
-			    !(inputstate & INS_DLE_command)) {
-				inputstate &= ~INS_command;
-				break;
-			}
-		} else {
-			/* advance in line buffer, checking for overflow */
-			if (cbytes < MAX_RESP_SIZE - 1)
-				cbytes++;
-			else
-				dev_warn(cs->dev, "response too large\n");
-		}
+			/* store EOL byte for CRLF collapsing */
+			cs->respdata[0] = c;
 
-		if (!numbytes)
-			break;
-		c = *src++;
-		--numbytes;
-		if (c == DLE_FLAG &&
-		    (cs->dle || inputstate & INS_DLE_command)) {
-			inputstate |= INS_DLE_char;
-			break;
+			/* cs->dle may have changed */
+			if (cs->dle && !(inbuf->inputstate & INS_DLE_command))
+				inbuf->inputstate &= ~INS_command;
+
+			/* return for reevaluating state */
+			goto exit;
+
+		case DLE_FLAG:
+			if (inbuf->inputstate & INS_DLE_char) {
+				/* quoted DLE: clear quote flag */
+				inbuf->inputstate &= ~INS_DLE_char;
+			} else if (cs->dle ||
+				   (inbuf->inputstate & INS_DLE_command)) {
+				/* DLE escape, pass up for handling */
+				inbuf->inputstate |= INS_DLE_char;
+				goto exit;
+			}
+			/* quoted or not in DLE mode: treat as regular data */
+			/* --v-- fall through --v-- */
+		default:
+			/* append to line buffer if possible */
+			if (cbytes < MAX_RESP_SIZE)
+				cs->respdata[cbytes] = c;
+			cbytes++;
 		}
 	}
-
+exit:
 	cs->cbytes = cbytes;
-	inbuf->inputstate = inputstate;
-
-	return startbytes - numbytes;
+	return procbytes;
 }
 
-/* process a block of received bytes in lock mode (tty i/f)
+/* process a block of received bytes in lock mode
+ * All received bytes are passed unmodified to the tty i/f.
  * Return value:
  *	number of processed bytes
  */
-static inline int lock_loop(unsigned char *src, int numbytes,
-			    struct inbuf_t *inbuf)
+static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf)
 {
-	struct cardstate *cs = inbuf->cs;
-
-	gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
-			   numbytes, src);
-	gigaset_if_receive(cs, src, numbytes);
+	unsigned char *src = inbuf->data + inbuf->head;
 
+	gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src);
+	gigaset_if_receive(inbuf->cs, src, numbytes);
 	return numbytes;
 }
 
+/* set up next receive skb for data mode
+ */
+static void new_rcv_skb(struct bc_state *bcs)
+{
+	struct cardstate *cs = bcs->cs;
+	unsigned short hw_hdr_len = cs->hw_hdr_len;
+
+	if (bcs->ignore) {
+		bcs->skb = NULL;
+		return;
+	}
+
+	bcs->skb = dev_alloc_skb(SBUFSIZE + hw_hdr_len);
+	if (bcs->skb == NULL) {
+		dev_warn(cs->dev, "could not allocate new skb\n");
+		return;
+	}
+	skb_reserve(bcs->skb, hw_hdr_len);
+}
+
 /* process a block of received bytes in HDLC data mode
+ * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC)
  * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
  * When a frame is complete, check the FCS and pass valid frames to the LL.
  * If DLE is encountered, return immediately to let the caller handle it.
  * Return value:
  *	number of processed bytes
- *	numbytes (all bytes processed) on error --FIXME
  */
-static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
-			    struct inbuf_t *inbuf)
+static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf)
 {
 	struct cardstate *cs = inbuf->cs;
-	struct bc_state *bcs = inbuf->bcs;
+	struct bc_state *bcs = cs->bcs;
 	int inputstate = bcs->inputstate;
 	__u16 fcs = bcs->fcs;
 	struct sk_buff *skb = bcs->skb;
-	unsigned char error;
-	struct sk_buff *compskb;
-	int startbytes = numbytes;
-	int l;
+	unsigned char *src = inbuf->data + inbuf->head;
+	unsigned procbytes = 0;
+	unsigned char c;
 
-	if (unlikely(inputstate & INS_byte_stuff)) {
+	if (inputstate & INS_byte_stuff) {
+		if (!numbytes)
+			return 0;
 		inputstate &= ~INS_byte_stuff;
 		goto byte_stuff;
 	}
-	for (;;) {
-		if (unlikely(c == PPP_ESCAPE)) {
-			if (unlikely(!numbytes)) {
-				inputstate |= INS_byte_stuff;
+
+	while (procbytes < numbytes) {
+		c = *src++;
+		procbytes++;
+		if (c == DLE_FLAG) {
+			if (inputstate & INS_DLE_char) {
+				/* quoted DLE: clear quote flag */
+				inputstate &= ~INS_DLE_char;
+			} else if (cs->dle || (inputstate & INS_DLE_command)) {
+				/* DLE escape, pass up for handling */
+				inputstate |= INS_DLE_char;
 				break;
 			}
-			c = *src++;
-			--numbytes;
-			if (unlikely(c == DLE_FLAG &&
-				     (cs->dle ||
-				      inbuf->inputstate & INS_DLE_command))) {
-				inbuf->inputstate |= INS_DLE_char;
+		}
+
+		if (c == PPP_ESCAPE) {
+			/* byte stuffing indicator: pull in next byte */
+			if (procbytes >= numbytes) {
+				/* end of buffer, save for later processing */
 				inputstate |= INS_byte_stuff;
 				break;
 			}
 byte_stuff:
+			c = *src++;
+			procbytes++;
+			if (c == DLE_FLAG) {
+				if (inputstate & INS_DLE_char) {
+					/* quoted DLE: clear quote flag */
+					inputstate &= ~INS_DLE_char;
+				} else if (cs->dle ||
+					   (inputstate & INS_DLE_command)) {
+					/* DLE escape, pass up for handling */
+					inputstate |=
+						INS_DLE_char | INS_byte_stuff;
+					break;
+				}
+			}
 			c ^= PPP_TRANS;
-			if (unlikely(!muststuff(c)))
-				gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
-		} else if (unlikely(c == PPP_FLAG)) {
-			if (unlikely(inputstate & INS_skip_frame)) {
-#ifdef CONFIG_GIGASET_DEBUG
-				if (!(inputstate & INS_have_data)) { /* 7E 7E */
-					++bcs->emptycount;
-				} else
-					gig_dbg(DEBUG_HDLC,
-					    "7e----------------------------");
-#endif
-
-				/* end of frame */
-				error = 1;
-				gigaset_rcv_error(NULL, cs, bcs);
-			} else if (!(inputstate & INS_have_data)) { /* 7E 7E */
 #ifdef CONFIG_GIGASET_DEBUG
-				++bcs->emptycount;
+			if (!muststuff(c))
+				gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
 #endif
-				break;
-			} else {
+		} else if (c == PPP_FLAG) {
+			/* end of frame: process content if any */
+			if (inputstate & INS_have_data) {
 				gig_dbg(DEBUG_HDLC,
 					"7e----------------------------");
 
-				/* end of frame */
-				error = 0;
-
-				if (unlikely(fcs != PPP_GOODFCS)) {
+				/* check and pass received frame */
+				if (!skb) {
+					/* skipped frame */
+					gigaset_isdn_rcv_err(bcs);
+				} else if (skb->len < 2) {
+					/* frame too short for FCS */
+					dev_warn(cs->dev,
+						 "short frame (%d)\n",
+						 skb->len);
+					gigaset_isdn_rcv_err(bcs);
+					dev_kfree_skb_any(skb);
+				} else if (fcs != PPP_GOODFCS) {
+					/* frame check error */
 					dev_err(cs->dev,
 				"Checksum failed, %u bytes corrupted!\n",
 						skb->len);
-					compskb = NULL;
-					gigaset_rcv_error(compskb, cs, bcs);
-					error = 1;
+					gigaset_isdn_rcv_err(bcs);
+					dev_kfree_skb_any(skb);
 				} else {
-					if (likely((l = skb->len) > 2)) {
-						skb->tail -= 2;
-						skb->len -= 2;
-					} else {
-						dev_kfree_skb(skb);
-						skb = NULL;
-						inputstate |= INS_skip_frame;
-						if (l == 1) {
-							dev_err(cs->dev,
-						  "invalid packet size (1)!\n");
-							error = 1;
-							gigaset_rcv_error(NULL,
-								cs, bcs);
-						}
-					}
-					if (likely(!(error ||
-						     (inputstate &
-						      INS_skip_frame)))) {
-						gigaset_rcv_skb(skb, cs, bcs);
-					}
+					/* good frame */
+					__skb_trim(skb, skb->len - 2);
+					gigaset_skb_rcvd(bcs, skb);
 				}
-			}
-
-			if (unlikely(error))
-				if (skb)
-					dev_kfree_skb(skb);
 
-			fcs = PPP_INITFCS;
-			inputstate &= ~(INS_have_data | INS_skip_frame);
-			if (unlikely(bcs->ignore)) {
-				inputstate |= INS_skip_frame;
-				skb = NULL;
-			} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
-				skb_reserve(skb, HW_HDR_LEN);
+				/* prepare reception of next frame */
+				inputstate &= ~INS_have_data;
+				new_rcv_skb(bcs);
+				skb = bcs->skb;
 			} else {
-				dev_warn(cs->dev,
-					 "could not allocate new skb\n");
-				inputstate |= INS_skip_frame;
+				/* empty frame (7E 7E) */
+#ifdef CONFIG_GIGASET_DEBUG
+				++bcs->emptycount;
+#endif
+				if (!skb) {
+					/* skipped (?) */
+					gigaset_isdn_rcv_err(bcs);
+					new_rcv_skb(bcs);
+					skb = bcs->skb;
+				}
 			}
 
-			break;
-		} else if (unlikely(muststuff(c))) {
+			fcs = PPP_INITFCS;
+			continue;
+#ifdef CONFIG_GIGASET_DEBUG
+		} else if (muststuff(c)) {
 			/* Should not happen. Possible after ZDLE=1<CR><LF>. */
 			gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
+#endif
 		}
 
-		/* add character */
-
+		/* regular data byte, append to skb */
 #ifdef CONFIG_GIGASET_DEBUG
-		if (unlikely(!(inputstate & INS_have_data))) {
+		if (!(inputstate & INS_have_data)) {
 			gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
 				bcs->emptycount);
 			bcs->emptycount = 0;
 		}
 #endif
-
 		inputstate |= INS_have_data;
-
-		if (likely(!(inputstate & INS_skip_frame))) {
-			if (unlikely(skb->len == SBUFSIZE)) {
+		if (skb) {
+			if (skb->len == SBUFSIZE) {
 				dev_warn(cs->dev, "received packet too long\n");
 				dev_kfree_skb_any(skb);
-				skb = NULL;
-				inputstate |= INS_skip_frame;
-				break;
+				/* skip remainder of packet */
+				bcs->skb = skb = NULL;
+			} else {
+				*__skb_put(skb, 1) = c;
+				fcs = crc_ccitt_byte(fcs, c);
 			}
-			*__skb_put(skb, 1) = c;
-			fcs = crc_ccitt_byte(fcs, c);
-		}
-
-		if (unlikely(!numbytes))
-			break;
-		c = *src++;
-		--numbytes;
-		if (unlikely(c == DLE_FLAG &&
-			     (cs->dle ||
-			      inbuf->inputstate & INS_DLE_command))) {
-			inbuf->inputstate |= INS_DLE_char;
-			break;
 		}
 	}
+
 	bcs->inputstate = inputstate;
 	bcs->fcs = fcs;
-	bcs->skb = skb;
-	return startbytes - numbytes;
+	return procbytes;
 }
 
 /* process a block of received bytes in transparent data mode
+ * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 != L2_HDLC)
  * Invert bytes, undoing byte stuffing and watching for DLE escapes.
  * If DLE is encountered, return immediately to let the caller handle it.
  * Return value:
  *	number of processed bytes
- *	numbytes (all bytes processed) on error --FIXME
  */
-static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
-			    struct inbuf_t *inbuf)
+static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf)
 {
 	struct cardstate *cs = inbuf->cs;
-	struct bc_state *bcs = inbuf->bcs;
+	struct bc_state *bcs = cs->bcs;
 	int inputstate = bcs->inputstate;
 	struct sk_buff *skb = bcs->skb;
-	int startbytes = numbytes;
+	unsigned char *src = inbuf->data + inbuf->head;
+	unsigned procbytes = 0;
+	unsigned char c;
 
-	for (;;) {
-		/* add character */
-		inputstate |= INS_have_data;
+	if (!skb) {
+		/* skip this block */
+		new_rcv_skb(bcs);
+		return numbytes;
+	}
 
-		if (likely(!(inputstate & INS_skip_frame))) {
-			if (unlikely(skb->len == SBUFSIZE)) {
-				//FIXME just pass skb up and allocate a new one
-				dev_warn(cs->dev, "received packet too long\n");
-				dev_kfree_skb_any(skb);
-				skb = NULL;
-				inputstate |= INS_skip_frame;
+	while (procbytes < numbytes && skb->len < SBUFSIZE) {
+		c = *src++;
+		procbytes++;
+
+		if (c == DLE_FLAG) {
+			if (inputstate & INS_DLE_char) {
+				/* quoted DLE: clear quote flag */
+				inputstate &= ~INS_DLE_char;
+			} else if (cs->dle || (inputstate & INS_DLE_command)) {
+				/* DLE escape, pass up for handling */
+				inputstate |= INS_DLE_char;
 				break;
 			}
-			*__skb_put(skb, 1) = bitrev8(c);
 		}
 
-		if (unlikely(!numbytes))
-			break;
-		c = *src++;
-		--numbytes;
-		if (unlikely(c == DLE_FLAG &&
-			     (cs->dle ||
-			      inbuf->inputstate & INS_DLE_command))) {
-			inbuf->inputstate |= INS_DLE_char;
-			break;
-		}
+		/* regular data byte: append to current skb */
+		inputstate |= INS_have_data;
+		*__skb_put(skb, 1) = bitrev8(c);
 	}
 
 	/* pass data up */
-	if (likely(inputstate & INS_have_data)) {
-		if (likely(!(inputstate & INS_skip_frame))) {
-			gigaset_rcv_skb(skb, cs, bcs);
-		}
-		inputstate &= ~(INS_have_data | INS_skip_frame);
-		if (unlikely(bcs->ignore)) {
-			inputstate |= INS_skip_frame;
-			skb = NULL;
-		} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN))
-				  != NULL)) {
-			skb_reserve(skb, HW_HDR_LEN);
+	if (inputstate & INS_have_data) {
+		gigaset_skb_rcvd(bcs, skb);
+		inputstate &= ~INS_have_data;
+		new_rcv_skb(bcs);
+	}
+
+	bcs->inputstate = inputstate;
+	return procbytes;
+}
+
+/* process DLE escapes
+ * Called whenever a DLE sequence might be encountered in the input stream.
+ * Either processes the entire DLE sequence or, if that isn't possible,
+ * notes the fact that an initial DLE has been received in the INS_DLE_char
+ * inputstate flag and resumes processing of the sequence on the next call.
+ */
+static void handle_dle(struct inbuf_t *inbuf)
+{
+	struct cardstate *cs = inbuf->cs;
+
+	if (cs->mstate == MS_LOCKED)
+		return;		/* no DLE processing in lock mode */
+
+	if (!(inbuf->inputstate & INS_DLE_char)) {
+		/* no DLE pending */
+		if (inbuf->data[inbuf->head] == DLE_FLAG &&
+		    (cs->dle || inbuf->inputstate & INS_DLE_command)) {
+			/* start of DLE sequence */
+			inbuf->head++;
+			if (inbuf->head == inbuf->tail ||
+			    inbuf->head == RBUFSIZE) {
+				/* end of buffer, save for later processing */
+				inbuf->inputstate |= INS_DLE_char;
+				return;
+			}
 		} else {
-			dev_warn(cs->dev, "could not allocate new skb\n");
-			inputstate |= INS_skip_frame;
+			/* regular data byte */
+			return;
 		}
 	}
 
-	bcs->inputstate = inputstate;
-	bcs->skb = skb;
-	return startbytes - numbytes;
+	/* consume pending DLE */
+	inbuf->inputstate &= ~INS_DLE_char;
+
+	switch (inbuf->data[inbuf->head]) {
+	case 'X':	/* begin of event message */
+		if (inbuf->inputstate & INS_command)
+			dev_notice(cs->dev,
+				   "received <DLE>X in command mode\n");
+		inbuf->inputstate |= INS_command | INS_DLE_command;
+		inbuf->head++;	/* byte consumed */
+		break;
+	case '.':	/* end of event message */
+		if (!(inbuf->inputstate & INS_DLE_command))
+			dev_notice(cs->dev,
+				   "received <DLE>. without <DLE>X\n");
+		inbuf->inputstate &= ~INS_DLE_command;
+		/* return to data mode if in DLE mode */
+		if (cs->dle)
+			inbuf->inputstate &= ~INS_command;
+		inbuf->head++;	/* byte consumed */
+		break;
+	case DLE_FLAG:	/* DLE in data stream */
+		/* mark as quoted */
+		inbuf->inputstate |= INS_DLE_char;
+		if (!(cs->dle || inbuf->inputstate & INS_DLE_command))
+			dev_notice(cs->dev,
+				   "received <DLE><DLE> not in DLE mode\n");
+		break;	/* quoted byte left in buffer */
+	default:
+		dev_notice(cs->dev, "received <DLE><%02x>\n",
+			   inbuf->data[inbuf->head]);
+		/* quoted byte left in buffer */
+	}
 }
 
 /**
@@ -345,94 +425,39 @@ static inline int iraw_loop(unsigned cha
  */
 void gigaset_m10x_input(struct inbuf_t *inbuf)
 {
-	struct cardstate *cs;
-	unsigned tail, head, numbytes;
-	unsigned char *src, c;
-	int procbytes;
-
-	head = inbuf->head;
-	tail = inbuf->tail;
-	gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
+	struct cardstate *cs = inbuf->cs;
+	unsigned numbytes, procbytes;
 
-	if (head != tail) {
-		cs = inbuf->cs;
-		src = inbuf->data + head;
-		numbytes = (head > tail ? RBUFSIZE : tail) - head;
-		gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
+	gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", inbuf->head, inbuf->tail);
 
-		while (numbytes) {
-			if (cs->mstate == MS_LOCKED) {
-				procbytes = lock_loop(src, numbytes, inbuf);
-				src += procbytes;
-				numbytes -= procbytes;
-			} else {
-				c = *src++;
-				--numbytes;
-				if (c == DLE_FLAG && (cs->dle ||
-				    inbuf->inputstate & INS_DLE_command)) {
-					if (!(inbuf->inputstate & INS_DLE_char)) {
-						inbuf->inputstate |= INS_DLE_char;
-						goto nextbyte;
-					}
-					/* <DLE> <DLE> => <DLE> in data stream */
-					inbuf->inputstate &= ~INS_DLE_char;
-				}
+	while (inbuf->head != inbuf->tail) {
+		/* check for DLE escape */
+		handle_dle(inbuf);
 
-				if (!(inbuf->inputstate & INS_DLE_char)) {
+		/* process a contiguous block of bytes */
+		numbytes = (inbuf->head > inbuf->tail ?
+			    RBUFSIZE : inbuf->tail) - inbuf->head;
+		gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
+		/*
+		 * numbytes may be 0 if handle_dle() ate the last byte.
+		 * This does no harm, *_loop() will just return 0 immediately.
+		 */
 
-					/* FIXME use function pointers?  */
-					if (inbuf->inputstate & INS_command)
-						procbytes = cmd_loop(c, src, numbytes, inbuf);
-					else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
-						procbytes = hdlc_loop(c, src, numbytes, inbuf);
-					else
-						procbytes = iraw_loop(c, src, numbytes, inbuf);
+		if (cs->mstate == MS_LOCKED)
+			procbytes = lock_loop(numbytes, inbuf);
+		else if (inbuf->inputstate & INS_command)
+			procbytes = cmd_loop(numbytes, inbuf);
+		else if (cs->bcs->proto2 == L2_HDLC)
+			procbytes = hdlc_loop(numbytes, inbuf);
+		else
+			procbytes = iraw_loop(numbytes, inbuf);
+		inbuf->head += procbytes;
 
-					src += procbytes;
-					numbytes -= procbytes;
-				} else {  /* DLE char */
-					inbuf->inputstate &= ~INS_DLE_char;
-					switch (c) {
-					case 'X': /*begin of command*/
-						if (inbuf->inputstate & INS_command)
-							dev_warn(cs->dev,
-					"received <DLE> 'X' in command mode\n");
-						inbuf->inputstate |=
-							INS_command | INS_DLE_command;
-						break;
-					case '.': /*end of command*/
-						if (!(inbuf->inputstate & INS_command))
-							dev_warn(cs->dev,
-					"received <DLE> '.' in hdlc mode\n");
-						inbuf->inputstate &= cs->dle ?
-							~(INS_DLE_command|INS_command)
-							: ~INS_DLE_command;
-						break;
-					//case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */
-					default:
-						dev_err(cs->dev,
-						      "received 0x10 0x%02x!\n",
-							(int) c);
-						/* FIXME: reset driver?? */
-					}
-				}
-			}
-nextbyte:
-			if (!numbytes) {
-				/* end of buffer, check for wrap */
-				if (head > tail) {
-					head = 0;
-					src = inbuf->data;
-					numbytes = tail;
-				} else {
-					head = tail;
-					break;
-				}
-			}
-		}
+		/* check for buffer wraparound */
+		if (inbuf->head >= RBUFSIZE)
+			inbuf->head = 0;
 
-		gig_dbg(DEBUG_INTR, "setting head to %u", head);
-		inbuf->head = head;
+		gig_dbg(DEBUG_INTR, "head set to %u", inbuf->head);
 	}
 }
 EXPORT_SYMBOL_GPL(gigaset_m10x_input);
@@ -440,16 +465,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);
 
 /* == data output ========================================================== */
 
-/* Encoding of a PPP packet into an octet stuffed HDLC frame
- * with FCS, opening and closing flags.
+/*
+ * Encode a data packet into an octet stuffed HDLC frame with FCS,
+ * opening and closing flags, preserving headroom data.
  * parameters:
- *	skb	skb containing original packet (freed upon return)
- *	head	number of headroom bytes to allocate in result skb
- *	tail	number of tailroom bytes to allocate in result skb
+ *	skb		skb containing original packet (freed upon return)
  * Return value:
  *	pointer to newly allocated skb containing the result frame
+ *	and the original link layer header, NULL on error
  */
-static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
+static struct sk_buff *HDLC_Encode(struct sk_buff *skb)
 {
 	struct sk_buff *hdlc_skb;
 	__u16 fcs;
@@ -471,16 +496,19 @@ static struct sk_buff *HDLC_Encode(struc
 
 	/* size of new buffer: original size + number of stuffing bytes
 	 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
+	 * + room for link layer header
 	 */
-	hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head);
+	hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + skb->mac_len);
 	if (!hdlc_skb) {
-		dev_kfree_skb(skb);
+		dev_kfree_skb_any(skb);
 		return NULL;
 	}
-	skb_reserve(hdlc_skb, head);
 
-	/* Copy acknowledge request into new skb */
-	memcpy(hdlc_skb->head, skb->head, 2);
+	/* Copy link layer header into new skb */
+	skb_reset_mac_header(hdlc_skb);
+	skb_reserve(hdlc_skb, skb->mac_len);
+	memcpy(skb_mac_header(hdlc_skb), skb_mac_header(skb), skb->mac_len);
+	hdlc_skb->mac_len = skb->mac_len;
 
 	/* Add flag sequence in front of everything.. */
 	*(skb_put(hdlc_skb, 1)) = PPP_FLAG;
@@ -511,33 +539,42 @@ static struct sk_buff *HDLC_Encode(struc
 
 	*(skb_put(hdlc_skb, 1)) = PPP_FLAG;
 
-	dev_kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	return hdlc_skb;
 }
 
-/* Encoding of a raw packet into an octet stuffed bit inverted frame
+/*
+ * Encode a data packet into an octet stuffed raw bit inverted frame,
+ * preserving headroom data.
  * parameters:
- *	skb	skb containing original packet (freed upon return)
- *	head	number of headroom bytes to allocate in result skb
- *	tail	number of tailroom bytes to allocate in result skb
+ *	skb		skb containing original packet (freed upon return)
  * Return value:
  *	pointer to newly allocated skb containing the result frame
+ *	and the original link layer header, NULL on error
  */
-static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
+static struct sk_buff *iraw_encode(struct sk_buff *skb)
 {
 	struct sk_buff *iraw_skb;
 	unsigned char c;
 	unsigned char *cp;
 	int len;
 
-	/* worst case: every byte must be stuffed */
-	iraw_skb = dev_alloc_skb(2*skb->len + tail + head);
+	/* size of new buffer (worst case = every byte must be stuffed):
+	 * 2 * original size + room for link layer header
+	 */
+	iraw_skb = dev_alloc_skb(2*skb->len + skb->mac_len);
 	if (!iraw_skb) {
-		dev_kfree_skb(skb);
+		dev_kfree_skb_any(skb);
 		return NULL;
 	}
-	skb_reserve(iraw_skb, head);
 
+	/* copy link layer header into new skb */
+	skb_reset_mac_header(iraw_skb);
+	skb_reserve(iraw_skb, skb->mac_len);
+	memcpy(skb_mac_header(iraw_skb), skb_mac_header(skb), skb->mac_len);
+	iraw_skb->mac_len = skb->mac_len;
+
+	/* copy and stuff data */
 	cp = skb->data;
 	len = skb->len;
 	while (len--) {
@@ -546,7 +583,7 @@ static struct sk_buff *iraw_encode(struc
 			*(skb_put(iraw_skb, 1)) = c;
 		*(skb_put(iraw_skb, 1)) = c;
 	}
-	dev_kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	return iraw_skb;
 }
 
@@ -555,8 +592,10 @@ static struct sk_buff *iraw_encode(struc
  * @bcs:	B channel descriptor structure.
  * @skb:	data to send.
  *
- * Called by i4l.c to encode and queue an skb for sending, and start
+ * Called by LL to encode and queue an skb for sending, and start
  * transmission if necessary.
+ * Once the payload data has been transmitted completely, gigaset_skb_sent()
+ * will be called with the skb's link layer header preserved.
  *
  * Return value:
  *	number of bytes accepted for sending (skb->len) if ok,
@@ -564,24 +603,25 @@ static struct sk_buff *iraw_encode(struc
  */
 int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
 {
+	struct cardstate *cs = bcs->cs;
 	unsigned len = skb->len;
 	unsigned long flags;
 
-	if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
-		skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
+	if (bcs->proto2 == L2_HDLC)
+		skb = HDLC_Encode(skb);
 	else
-		skb = iraw_encode(skb, HW_HDR_LEN, 0);
+		skb = iraw_encode(skb);
 	if (!skb) {
-		dev_err(bcs->cs->dev,
+		dev_err(cs->dev,
 			"unable to allocate memory for encoding!\n");
 		return -ENOMEM;
 	}
 
 	skb_queue_tail(&bcs->squeue, skb);
-	spin_lock_irqsave(&bcs->cs->lock, flags);
-	if (bcs->cs->connected)
-		tasklet_schedule(&bcs->cs->write_tasklet);
-	spin_unlock_irqrestore(&bcs->cs->lock, flags);
+	spin_lock_irqsave(&cs->lock, flags);
+	if (cs->connected)
+		tasklet_schedule(&cs->write_tasklet);
+	spin_unlock_irqrestore(&cs->lock, flags);
 
 	return len;	/* ok so far */
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/bas-gigaset.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/bas-gigaset.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,7 +57,7 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"
 #define USB_SX353_PRODUCT_ID    0x0022
 
 /* table of devices that work with this driver */
-static const struct usb_device_id gigaset_table [] = {
+static const struct usb_device_id gigaset_table[] = {
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
@@ -137,7 +137,7 @@ struct bas_cardstate {
 #define BS_RESETTING	0x200	/* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
 
 
-static struct gigaset_driver *driver = NULL;
+static struct gigaset_driver *driver;
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver gigaset_usb_driver = {
@@ -601,11 +601,12 @@ static int atread_submit(struct cardstat
 	ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size);
 	usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev,
 			     usb_rcvctrlpipe(ucs->udev, 0),
-			     (unsigned char*) & ucs->dr_cmd_in,
+			     (unsigned char *) &ucs->dr_cmd_in,
 			     ucs->rcvbuf, ucs->rcvbuf_size,
 			     read_ctrl_callback, cs->inbuf);
 
-	if ((ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC)) != 0) {
+	ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC);
+	if (ret != 0) {
 		update_basstate(ucs, 0, BS_ATRDPEND);
 		dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
 			get_usb_rcmsg(ret));
@@ -652,13 +653,11 @@ static void read_int_callback(struct urb
 		return;
 	case -ENODEV:			/* device removed */
 	case -ESHUTDOWN:		/* device shut down */
-		//FIXME use this as disconnect indicator?
 		gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__);
 		return;
 	default:		/* severe trouble */
 		dev_warn(cs->dev, "interrupt read: %s\n",
 			 get_usb_statmsg(status));
-		//FIXME corrective action? resubmission always ok?
 		goto resubmit;
 	}
 
@@ -742,7 +741,8 @@ static void read_int_callback(struct urb
 			kfree(ucs->rcvbuf);
 			ucs->rcvbuf_size = 0;
 		}
-		if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) {
+		ucs->rcvbuf = kmalloc(l, GFP_ATOMIC);
+		if (ucs->rcvbuf == NULL) {
 			spin_unlock_irqrestore(&cs->lock, flags);
 			dev_err(cs->dev, "out of memory receiving AT data\n");
 			error_reset(cs);
@@ -750,12 +750,12 @@ static void read_int_callback(struct urb
 		}
 		ucs->rcvbuf_size = l;
 		ucs->retry_cmd_in = 0;
-		if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) {
+		rc = atread_submit(cs, BAS_TIMEOUT);
+		if (rc < 0) {
 			kfree(ucs->rcvbuf);
 			ucs->rcvbuf = NULL;
 			ucs->rcvbuf_size = 0;
 			if (rc != -ENODEV) {
-				//FIXME corrective action?
 				spin_unlock_irqrestore(&cs->lock, flags);
 				error_reset(cs);
 				break;
@@ -911,7 +911,7 @@ static int starturbs(struct bc_state *bc
 	int rc;
 
 	/* initialize L2 reception */
-	if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
+	if (bcs->proto2 == L2_HDLC)
 		bcs->inputstate |= INS_flag_hunt;
 
 	/* submit all isochronous input URBs */
@@ -940,7 +940,8 @@ static int starturbs(struct bc_state *bc
 		}
 
 		dump_urb(DEBUG_ISO, "Initial isoc read", urb);
-		if ((rc = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
+		rc = usb_submit_urb(urb, GFP_ATOMIC);
+		if (rc != 0)
 			goto error;
 	}
 
@@ -1045,7 +1046,8 @@ static int submit_iso_write_urb(struct i
 
 		/* compute frame length according to flow control */
 		ifd->length = BAS_NORMFRAME;
-		if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) {
+		corrbytes = atomic_read(&ubc->corrbytes);
+		if (corrbytes != 0) {
 			gig_dbg(DEBUG_ISO, "%s: corrbytes=%d",
 				__func__, corrbytes);
 			if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME)
@@ -1064,7 +1066,7 @@ static int submit_iso_write_urb(struct i
 					"%s: buffer busy at frame %d",
 					__func__, nframe);
 				/* tasklet will be restarted from
-				   gigaset_send_skb() */
+				   gigaset_isoc_send_skb() */
 			} else {
 				dev_err(ucx->bcs->cs->dev,
 					"%s: buffer error %d at frame %d\n",
@@ -1284,7 +1286,8 @@ static void read_iso_tasklet(unsigned lo
 	for (;;) {
 		/* retrieve URB */
 		spin_lock_irqsave(&ubc->isoinlock, flags);
-		if (!(urb = ubc->isoindone)) {
+		urb = ubc->isoindone;
+		if (!urb) {
 			spin_unlock_irqrestore(&ubc->isoinlock, flags);
 			return;
 		}
@@ -1371,7 +1374,7 @@ static void read_iso_tasklet(unsigned lo
 				 "isochronous read: %d data bytes missing\n",
 				 totleft);
 
-	error:
+error:
 		/* URB processed, resubmit */
 		for (frame = 0; frame < BAS_NUMFRAMES; frame++) {
 			urb->iso_frame_desc[frame].status = 0;
@@ -1568,7 +1571,7 @@ static int req_submit(struct bc_state *b
 	ucs->dr_ctrl.wLength = 0;
 	usb_fill_control_urb(ucs->urb_ctrl, ucs->udev,
 			     usb_sndctrlpipe(ucs->udev, 0),
-			     (unsigned char*) &ucs->dr_ctrl, NULL, 0,
+			     (unsigned char *) &ucs->dr_ctrl, NULL, 0,
 			     write_ctrl_callback, ucs);
 	ucs->retry_ctrl = 0;
 	ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC);
@@ -1621,7 +1624,8 @@ static int gigaset_init_bchannel(struct
 		return -EHOSTUNREACH;
 	}
 
-	if ((ret = starturbs(bcs)) < 0) {
+	ret = starturbs(bcs);
+	if (ret < 0) {
 		dev_err(cs->dev,
 			"could not start isochronous I/O for channel B%d: %s\n",
 			bcs->channel + 1,
@@ -1633,7 +1637,8 @@ static int gigaset_init_bchannel(struct
 	}
 
 	req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
-	if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) {
+	ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
+	if (ret < 0) {
 		dev_err(cs->dev, "could not open channel B%d\n",
 			bcs->channel + 1);
 		stopurbs(bcs->hw.bas);
@@ -1677,7 +1682,8 @@ static int gigaset_close_bchannel(struct
 
 	/* channel running: tell device to close it */
 	req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
-	if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0)
+	ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
+	if (ret < 0)
 		dev_err(cs->dev, "closing channel B%d failed\n",
 			bcs->channel + 1);
 
@@ -1703,10 +1709,12 @@ static void complete_cb(struct cardstate
 	gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD,
 		"write_command: sent %u bytes, %u left",
 		cs->curlen, cs->cmdbytes);
-	if ((cs->cmdbuf = cb->next) != NULL) {
+	if (cb->next != NULL) {
+		cs->cmdbuf = cb->next;
 		cs->cmdbuf->prev = NULL;
 		cs->curlen = cs->cmdbuf->len;
 	} else {
+		cs->cmdbuf = NULL;
 		cs->lastcmdbuf = NULL;
 		cs->curlen = 0;
 	}
@@ -1833,7 +1841,7 @@ static int atwrite_submit(struct cardsta
 	ucs->dr_cmd_out.wLength = cpu_to_le16(len);
 	usb_fill_control_urb(ucs->urb_cmd_out, ucs->udev,
 			     usb_sndctrlpipe(ucs->udev, 0),
-			     (unsigned char*) &ucs->dr_cmd_out, buf, len,
+			     (unsigned char *) &ucs->dr_cmd_out, buf, len,
 			     write_command_callback, cs);
 	rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC);
 	if (unlikely(rc)) {
@@ -1953,7 +1961,8 @@ static int gigaset_write_cmd(struct card
 
 	if (len > IF_WRITEBUF)
 		len = IF_WRITEBUF;
-	if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
+	cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
+	if (!cb) {
 		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		rc = -ENOMEM;
 		goto notqueued;
@@ -2100,14 +2109,15 @@ static int gigaset_initbcshw(struct bc_s
 	}
 	ubc->isooutdone = ubc->isooutfree = ubc->isooutovfl = NULL;
 	ubc->numsub = 0;
-	if (!(ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL))) {
+	ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL);
+	if (!ubc->isooutbuf) {
 		pr_err("out of memory\n");
 		kfree(ubc);
 		bcs->hw.bas = NULL;
 		return 0;
 	}
 	tasklet_init(&ubc->sent_tasklet,
-		     &write_iso_tasklet, (unsigned long) bcs);
+		     write_iso_tasklet, (unsigned long) bcs);
 
 	spin_lock_init(&ubc->isoinlock);
 	for (i = 0; i < BAS_INURBS; ++i)
@@ -2128,7 +2138,7 @@ static int gigaset_initbcshw(struct bc_s
 	ubc->shared0s = 0;
 	ubc->stolen0s = 0;
 	tasklet_init(&ubc->rcvd_tasklet,
-		     &read_iso_tasklet, (unsigned long) bcs);
+		     read_iso_tasklet, (unsigned long) bcs);
 	return 1;
 }
 
@@ -2252,7 +2262,8 @@ static int gigaset_probe(struct usb_inte
 		gig_dbg(DEBUG_ANY,
 			"%s: wrong alternate setting %d - trying to switch",
 			__func__, hostif->desc.bAlternateSetting);
-		if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) {
+		if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3)
+		    < 0) {
 			dev_warn(&udev->dev, "usb_set_interface failed, "
 				 "device %d interface %d altsetting %d\n",
 				 udev->devnum, hostif->desc.bInterfaceNumber,
@@ -2321,14 +2332,16 @@ static int gigaset_probe(struct usb_inte
 					(endpoint->bEndpointAddress) & 0x0f),
 			 ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
 			 endpoint->bInterval);
-	if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) {
+	rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
+	if (rc != 0) {
 		dev_err(cs->dev, "could not submit interrupt URB: %s\n",
 			get_usb_rcmsg(rc));
 		goto error;
 	}
 
 	/* tell the device that the driver is ready */
-	if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0)
+	rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0);
+	if (rc != 0)
 		goto error;
 
 	/* tell common part that the device is ready */
@@ -2524,9 +2537,10 @@ static int __init bas_gigaset_init(void)
 	int result;
 
 	/* allocate memory for our driver state and intialize it */
-	if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
-				       GIGASET_MODULENAME, GIGASET_DEVNAME,
-				       &gigops, THIS_MODULE)) == NULL)
+	driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
+				    GIGASET_MODULENAME, GIGASET_DEVNAME,
+				    &gigops, THIS_MODULE);
+	if (driver == NULL)
 		goto error;
 
 	/* register this driver with the USB subsystem */
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/capi.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/capi.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/capi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/capi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2292 @@
+/*
+ * Kernel CAPI interface for the Gigaset driver
+ *
+ * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
+ *
+ * =====================================================================
+ *	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 "gigaset.h"
+#include <linux/ctype.h>
+#include <linux/isdn/capilli.h>
+#include <linux/isdn/capicmd.h>
+#include <linux/isdn/capiutil.h>
+
+/* missing from kernelcapi.h */
+#define CapiNcpiNotSupportedByProtocol	0x0001
+#define CapiFlagsNotSupportedByProtocol	0x0002
+#define CapiAlertAlreadySent		0x0003
+#define CapiFacilitySpecificFunctionNotSupported	0x3011
+
+/* missing from capicmd.h */
+#define CAPI_CONNECT_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+8*1)
+#define CAPI_CONNECT_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+3*1)
+#define CAPI_CONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
+#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
+#define CAPI_DATA_B3_REQ_LEN64		(CAPI_MSG_BASELEN+4+4+2+2+2+8)
+#define CAPI_DATA_B3_CONF_LEN		(CAPI_MSG_BASELEN+4+2+2)
+#define CAPI_DISCONNECT_IND_LEN		(CAPI_MSG_BASELEN+4+2)
+#define CAPI_DISCONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+1)
+#define CAPI_FACILITY_CONF_BASELEN	(CAPI_MSG_BASELEN+4+2+2+1)
+/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
+#define CAPI_STDCONF_LEN		(CAPI_MSG_BASELEN+4+2)
+
+#define CAPI_FACILITY_HANDSET	0x0000
+#define CAPI_FACILITY_DTMF	0x0001
+#define CAPI_FACILITY_V42BIS	0x0002
+#define CAPI_FACILITY_SUPPSVC	0x0003
+#define CAPI_FACILITY_WAKEUP	0x0004
+#define CAPI_FACILITY_LI	0x0005
+
+#define CAPI_SUPPSVC_GETSUPPORTED	0x0000
+
+/* missing from capiutil.h */
+#define CAPIMSG_PLCI_PART(m)	CAPIMSG_U8(m, 9)
+#define CAPIMSG_NCCI_PART(m)	CAPIMSG_U16(m, 10)
+#define CAPIMSG_HANDLE_REQ(m)	CAPIMSG_U16(m, 18) /* DATA_B3_REQ/_IND only! */
+#define CAPIMSG_FLAGS(m)	CAPIMSG_U16(m, 20)
+#define CAPIMSG_SETCONTROLLER(m, contr)	capimsg_setu8(m, 8, contr)
+#define CAPIMSG_SETPLCI_PART(m, plci)	capimsg_setu8(m, 9, plci)
+#define CAPIMSG_SETNCCI_PART(m, ncci)	capimsg_setu16(m, 10, ncci)
+#define CAPIMSG_SETFLAGS(m, flags)	capimsg_setu16(m, 20, flags)
+
+/* parameters with differing location in DATA_B3_CONF/_RESP: */
+#define CAPIMSG_SETHANDLE_CONF(m, handle)	capimsg_setu16(m, 12, handle)
+#define	CAPIMSG_SETINFO_CONF(m, info)		capimsg_setu16(m, 14, info)
+
+/* Flags (DATA_B3_REQ/_IND) */
+#define CAPI_FLAGS_DELIVERY_CONFIRMATION	0x04
+#define CAPI_FLAGS_RESERVED			(~0x1f)
+
+/* buffer sizes */
+#define MAX_BC_OCTETS 11
+#define MAX_HLC_OCTETS 3
+#define MAX_NUMBER_DIGITS 20
+#define MAX_FMT_IE_LEN 20
+
+/* values for gigaset_capi_appl.connected */
+#define APCONN_NONE	0	/* inactive/listening */
+#define APCONN_SETUP	1	/* connecting */
+#define APCONN_ACTIVE	2	/* B channel up */
+
+/* registered application data structure */
+struct gigaset_capi_appl {
+	struct list_head ctrlist;
+	struct gigaset_capi_appl *bcnext;
+	u16 id;
+	u16 nextMessageNumber;
+	u32 listenInfoMask;
+	u32 listenCIPmask;
+	int connected;
+};
+
+/* CAPI specific controller data structure */
+struct gigaset_capi_ctr {
+	struct capi_ctr ctr;
+	struct list_head appls;
+	struct sk_buff_head sendqueue;
+	atomic_t sendqlen;
+	/* two _cmsg structures possibly used concurrently: */
+	_cmsg hcmsg;	/* for message composition triggered from hardware */
+	_cmsg acmsg;	/* for dissection of messages sent from application */
+	u8 bc_buf[MAX_BC_OCTETS+1];
+	u8 hlc_buf[MAX_HLC_OCTETS+1];
+	u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
+	u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
+};
+
+/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
+static struct {
+	u8 *bc;
+	u8 *hlc;
+} cip2bchlc[] = {
+	[1] = { "8090A3", NULL },
+		/* Speech (A-law) */
+	[2] = { "8890", NULL },
+		/* Unrestricted digital information */
+	[3] = { "8990", NULL },
+		/* Restricted digital information */
+	[4] = { "9090A3", NULL },
+		/* 3,1 kHz audio (A-law) */
+	[5] = { "9190", NULL },
+		/* 7 kHz audio */
+	[6] = { "9890", NULL },
+		/* Video */
+	[7] = { "88C0C6E6", NULL },
+		/* Packet mode */
+	[8] = { "8890218F", NULL },
+		/* 56 kbit/s rate adaptation */
+	[9] = { "9190A5", NULL },
+		/* Unrestricted digital information with tones/announcements */
+	[16] = { "8090A3", "9181" },
+		/* Telephony */
+	[17] = { "9090A3", "9184" },
+		/* Group 2/3 facsimile */
+	[18] = { "8890", "91A1" },
+		/* Group 4 facsimile Class 1 */
+	[19] = { "8890", "91A4" },
+		/* Teletex service basic and mixed mode
+		   and Group 4 facsimile service Classes II and III */
+	[20] = { "8890", "91A8" },
+		/* Teletex service basic and processable mode */
+	[21] = { "8890", "91B1" },
+		/* Teletex service basic mode */
+	[22] = { "8890", "91B2" },
+		/* International interworking for Videotex */
+	[23] = { "8890", "91B5" },
+		/* Telex */
+	[24] = { "8890", "91B8" },
+		/* Message Handling Systems in accordance with X.400 */
+	[25] = { "8890", "91C1" },
+		/* OSI application in accordance with X.200 */
+	[26] = { "9190A5", "9181" },
+		/* 7 kHz telephony */
+	[27] = { "9190A5", "916001" },
+		/* Video telephony, first connection */
+	[28] = { "8890", "916002" },
+		/* Video telephony, second connection */
+};
+
+/*
+ * helper functions
+ * ================
+ */
+
+/*
+ * emit unsupported parameter warning
+ */
+static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
+				       char *msgname, char *paramname)
+{
+	if (param && *param)
+		dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
+			 msgname, paramname);
+}
+
+/*
+ * check for legal hex digit
+ */
+static inline int ishexdigit(char c)
+{
+	if (c >= '0' && c <= '9')
+		return 1;
+	if (c >= 'A' && c <= 'F')
+		return 1;
+	if (c >= 'a' && c <= 'f')
+		return 1;
+	return 0;
+}
+
+/*
+ * convert hex to binary
+ */
+static inline u8 hex2bin(char c)
+{
+	int result = c & 0x0f;
+	if (c & 0x40)
+		result += 9;
+	return result;
+}
+
+/*
+ * convert an IE from Gigaset hex string to ETSI binary representation
+ * including length byte
+ * return value: result length, -1 on error
+ */
+static int encode_ie(char *in, u8 *out, int maxlen)
+{
+	int l = 0;
+	while (*in) {
+		if (!ishexdigit(in[0]) || !ishexdigit(in[1]) || l >= maxlen)
+			return -1;
+		out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]);
+		in += 2;
+	}
+	out[0] = l;
+	return l;
+}
+
+/*
+ * convert an IE from ETSI binary representation including length byte
+ * to Gigaset hex string
+ */
+static void decode_ie(u8 *in, char *out)
+{
+	int i = *in;
+	while (i-- > 0) {
+		/* ToDo: conversion to upper case necessary? */
+		*out++ = toupper(hex_asc_hi(*++in));
+		*out++ = toupper(hex_asc_lo(*in));
+	}
+}
+
+/*
+ * retrieve application data structure for an application ID
+ */
+static inline struct gigaset_capi_appl *
+get_appl(struct gigaset_capi_ctr *iif, u16 appl)
+{
+	struct gigaset_capi_appl *ap;
+
+	list_for_each_entry(ap, &iif->appls, ctrlist)
+		if (ap->id == appl)
+			return ap;
+	return NULL;
+}
+
+/*
+ * dump CAPI message to kernel messages for debugging
+ */
+static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
+{
+#ifdef CONFIG_GIGASET_DEBUG
+	_cdebbuf *cdb;
+
+	if (!(gigaset_debuglevel & level))
+		return;
+
+	cdb = capi_cmsg2str(p);
+	if (cdb) {
+		gig_dbg(level, "%s: [%d] %s", tag, p->ApplId, cdb->buf);
+		cdebbuf_free(cdb);
+	} else {
+		gig_dbg(level, "%s: [%d] %s", tag, p->ApplId,
+			capi_cmd2str(p->Command, p->Subcommand));
+	}
+#endif
+}
+
+static inline void dump_rawmsg(enum debuglevel level, const char *tag,
+			       unsigned char *data)
+{
+#ifdef CONFIG_GIGASET_DEBUG
+	char *dbgline;
+	int i, l;
+
+	if (!(gigaset_debuglevel & level))
+		return;
+
+	l = CAPIMSG_LEN(data);
+	if (l < 12) {
+		gig_dbg(level, "%s: ??? LEN=%04d", tag, l);
+		return;
+	}
+	gig_dbg(level, "%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
+		tag, CAPIMSG_COMMAND(data), CAPIMSG_SUBCOMMAND(data),
+		CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
+		CAPIMSG_CONTROL(data));
+	l -= 12;
+	dbgline = kmalloc(3*l, GFP_ATOMIC);
+	if (!dbgline)
+		return;
+	for (i = 0; i < l; i++) {
+		dbgline[3*i] = hex_asc_hi(data[12+i]);
+		dbgline[3*i+1] = hex_asc_lo(data[12+i]);
+		dbgline[3*i+2] = ' ';
+	}
+	dbgline[3*l-1] = '\0';
+	gig_dbg(level, "  %s", dbgline);
+	kfree(dbgline);
+	if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
+	    (CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
+	     CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
+	    CAPIMSG_DATALEN(data) > 0) {
+		l = CAPIMSG_DATALEN(data);
+		dbgline = kmalloc(3*l, GFP_ATOMIC);
+		if (!dbgline)
+			return;
+		data += CAPIMSG_LEN(data);
+		for (i = 0; i < l; i++) {
+			dbgline[3*i] = hex_asc_hi(data[i]);
+			dbgline[3*i+1] = hex_asc_lo(data[i]);
+			dbgline[3*i+2] = ' ';
+		}
+		dbgline[3*l-1] = '\0';
+		gig_dbg(level, "  %s", dbgline);
+		kfree(dbgline);
+	}
+#endif
+}
+
+/*
+ * format CAPI IE as string
+ */
+
+static const char *format_ie(const char *ie)
+{
+	static char result[3*MAX_FMT_IE_LEN];
+	int len, count;
+	char *pout = result;
+
+	if (!ie)
+		return "NULL";
+
+	count = len = ie[0];
+	if (count > MAX_FMT_IE_LEN)
+		count = MAX_FMT_IE_LEN-1;
+	while (count--) {
+		*pout++ = hex_asc_hi(*++ie);
+		*pout++ = hex_asc_lo(*ie);
+		*pout++ = ' ';
+	}
+	if (len > MAX_FMT_IE_LEN) {
+		*pout++ = '.';
+		*pout++ = '.';
+		*pout++ = '.';
+	}
+	*--pout = 0;
+	return result;
+}
+
+
+/*
+ * driver interface functions
+ * ==========================
+ */
+
+/**
+ * gigaset_skb_sent() - acknowledge transmission of outgoing skb
+ * @bcs:	B channel descriptor structure.
+ * @skb:	sent data.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when the data in a
+ * skb has been successfully sent, for signalling completion to the LL.
+ */
+void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct gigaset_capi_appl *ap = bcs->ap;
+	unsigned char *req = skb_mac_header(dskb);
+	struct sk_buff *cskb;
+	u16 flags;
+
+	/* update statistics */
+	++bcs->trans_up;
+
+	if (!ap) {
+		dev_err(cs->dev, "%s: no application\n", __func__);
+		return;
+	}
+
+	/* don't send further B3 messages if disconnected */
+	if (ap->connected < APCONN_ACTIVE) {
+		gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
+		return;
+	}
+
+	/* ToDo: honor unset "delivery confirmation" bit */
+	flags = CAPIMSG_FLAGS(req);
+
+	/* build DATA_B3_CONF message */
+	cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
+	if (!cskb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	/* frequent message, avoid _cmsg overhead */
+	CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN);
+	CAPIMSG_SETAPPID(cskb->data, ap->id);
+	CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
+	CAPIMSG_SETSUBCOMMAND(cskb->data,  CAPI_CONF);
+	CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req));
+	CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
+	CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
+	CAPIMSG_SETNCCI_PART(cskb->data, 1);
+	CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req));
+	if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
+		CAPIMSG_SETINFO_CONF(cskb->data,
+				     CapiFlagsNotSupportedByProtocol);
+	else
+		CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR);
+
+	/* emit message */
+	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data);
+	capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_sent);
+
+/**
+ * gigaset_skb_rcvd() - pass received skb to LL
+ * @bcs:	B channel descriptor structure.
+ * @skb:	received data.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when user data has
+ * been successfully received, for passing to the LL.
+ * Warning: skb must not be accessed anymore!
+ */
+void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct gigaset_capi_appl *ap = bcs->ap;
+	int len = skb->len;
+
+	/* update statistics */
+	bcs->trans_down++;
+
+	if (!ap) {
+		dev_err(cs->dev, "%s: no application\n", __func__);
+		return;
+	}
+
+	/* don't send further B3 messages if disconnected */
+	if (ap->connected < APCONN_ACTIVE) {
+		gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	/*
+	 * prepend DATA_B3_IND message to payload
+	 * Parameters: NCCI = 1, all others 0/unused
+	 * frequent message, avoid _cmsg overhead
+	 */
+	skb_push(skb, CAPI_DATA_B3_REQ_LEN);
+	CAPIMSG_SETLEN(skb->data, CAPI_DATA_B3_REQ_LEN);
+	CAPIMSG_SETAPPID(skb->data, ap->id);
+	CAPIMSG_SETCOMMAND(skb->data, CAPI_DATA_B3);
+	CAPIMSG_SETSUBCOMMAND(skb->data,  CAPI_IND);
+	CAPIMSG_SETMSGID(skb->data, ap->nextMessageNumber++);
+	CAPIMSG_SETCONTROLLER(skb->data, iif->ctr.cnr);
+	CAPIMSG_SETPLCI_PART(skb->data, bcs->channel + 1);
+	CAPIMSG_SETNCCI_PART(skb->data, 1);
+	/* Data parameter not used */
+	CAPIMSG_SETDATALEN(skb->data, len);
+	/* Data handle parameter not used */
+	CAPIMSG_SETFLAGS(skb->data, 0);
+	/* Data64 parameter not present */
+
+	/* emit message */
+	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
+
+/**
+ * gigaset_isdn_rcv_err() - signal receive error
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when a receive error
+ * has occurred, for signalling to the LL.
+ */
+void gigaset_isdn_rcv_err(struct bc_state *bcs)
+{
+	/* if currently ignoring packets, just count down */
+	if (bcs->ignore) {
+		bcs->ignore--;
+		return;
+	}
+
+	/* update statistics */
+	bcs->corrupted++;
+
+	/* ToDo: signal error -> LL */
+}
+EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
+
+/**
+ * gigaset_isdn_icall() - signal incoming call
+ * @at_state:	connection state structure.
+ *
+ * Called by main module at tasklet level to notify the LL that an incoming
+ * call has been received. @at_state contains the parameters of the call.
+ *
+ * Return value: call disposition (ICALL_*)
+ */
+int gigaset_isdn_icall(struct at_state_t *at_state)
+{
+	struct cardstate *cs = at_state->cs;
+	struct bc_state *bcs = at_state->bcs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct gigaset_capi_appl *ap;
+	u32 actCIPmask;
+	struct sk_buff *skb;
+	unsigned int msgsize;
+	int i;
+
+	/*
+	 * ToDo: signal calls without a free B channel, too
+	 * (requires a u8 handle for the at_state structure that can
+	 * be stored in the PLCI and used in the CONNECT_RESP message
+	 * handler to retrieve it)
+	 */
+	if (!bcs)
+		return ICALL_IGNORE;
+
+	/* prepare CONNECT_IND message, using B channel number as PLCI */
+	capi_cmsg_header(&iif->hcmsg, 0, CAPI_CONNECT, CAPI_IND, 0,
+			 iif->ctr.cnr | ((bcs->channel + 1) << 8));
+
+	/* minimum size, all structs empty */
+	msgsize = CAPI_CONNECT_IND_BASELEN;
+
+	/* Bearer Capability (mandatory) */
+	if (at_state->str_var[STR_ZBC]) {
+		/* pass on BC from Gigaset */
+		if (encode_ie(at_state->str_var[STR_ZBC], iif->bc_buf,
+			      MAX_BC_OCTETS) < 0) {
+			dev_warn(cs->dev, "RING ignored - bad BC %s\n",
+				 at_state->str_var[STR_ZBC]);
+			return ICALL_IGNORE;
+		}
+
+		/* look up corresponding CIP value */
+		iif->hcmsg.CIPValue = 0;	/* default if nothing found */
+		for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
+			if (cip2bchlc[i].bc != NULL &&
+			    cip2bchlc[i].hlc == NULL &&
+			    !strcmp(cip2bchlc[i].bc,
+				    at_state->str_var[STR_ZBC])) {
+				iif->hcmsg.CIPValue = i;
+				break;
+			}
+	} else {
+		/* no BC (internal call): assume CIP 1 (speech, A-law) */
+		iif->hcmsg.CIPValue = 1;
+		encode_ie(cip2bchlc[1].bc, iif->bc_buf, MAX_BC_OCTETS);
+	}
+	iif->hcmsg.BC = iif->bc_buf;
+	msgsize += iif->hcmsg.BC[0];
+
+	/* High Layer Compatibility (optional) */
+	if (at_state->str_var[STR_ZHLC]) {
+		/* pass on HLC from Gigaset */
+		if (encode_ie(at_state->str_var[STR_ZHLC], iif->hlc_buf,
+			      MAX_HLC_OCTETS) < 0) {
+			dev_warn(cs->dev, "RING ignored - bad HLC %s\n",
+				 at_state->str_var[STR_ZHLC]);
+			return ICALL_IGNORE;
+		}
+		iif->hcmsg.HLC = iif->hlc_buf;
+		msgsize += iif->hcmsg.HLC[0];
+
+		/* look up corresponding CIP value */
+		/* keep BC based CIP value if none found */
+		if (at_state->str_var[STR_ZBC])
+			for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
+				if (cip2bchlc[i].hlc != NULL &&
+				    !strcmp(cip2bchlc[i].hlc,
+					    at_state->str_var[STR_ZHLC]) &&
+				    !strcmp(cip2bchlc[i].bc,
+					    at_state->str_var[STR_ZBC])) {
+					iif->hcmsg.CIPValue = i;
+					break;
+				}
+	}
+
+	/* Called Party Number (optional) */
+	if (at_state->str_var[STR_ZCPN]) {
+		i = strlen(at_state->str_var[STR_ZCPN]);
+		if (i > MAX_NUMBER_DIGITS) {
+			dev_warn(cs->dev, "RING ignored - bad number %s\n",
+				 at_state->str_var[STR_ZBC]);
+			return ICALL_IGNORE;
+		}
+		iif->cdpty_buf[0] = i + 1;
+		iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
+		memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
+		iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
+		msgsize += iif->hcmsg.CalledPartyNumber[0];
+	}
+
+	/* Calling Party Number (optional) */
+	if (at_state->str_var[STR_NMBR]) {
+		i = strlen(at_state->str_var[STR_NMBR]);
+		if (i > MAX_NUMBER_DIGITS) {
+			dev_warn(cs->dev, "RING ignored - bad number %s\n",
+				 at_state->str_var[STR_ZBC]);
+			return ICALL_IGNORE;
+		}
+		iif->cgpty_buf[0] = i + 2;
+		iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
+		iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
+		memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
+		iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
+		msgsize += iif->hcmsg.CallingPartyNumber[0];
+	}
+
+	/* remaining parameters (not supported, always left NULL):
+	 * - CalledPartySubaddress
+	 * - CallingPartySubaddress
+	 * - AdditionalInfo
+	 *   - BChannelinformation
+	 *   - Keypadfacility
+	 *   - Useruserdata
+	 *   - Facilitydataarray
+	 */
+
+	gig_dbg(DEBUG_CMD, "icall: PLCI %x CIP %d BC %s",
+		iif->hcmsg.adr.adrPLCI, iif->hcmsg.CIPValue,
+		format_ie(iif->hcmsg.BC));
+	gig_dbg(DEBUG_CMD, "icall: HLC %s",
+		format_ie(iif->hcmsg.HLC));
+	gig_dbg(DEBUG_CMD, "icall: CgPty %s",
+		format_ie(iif->hcmsg.CallingPartyNumber));
+	gig_dbg(DEBUG_CMD, "icall: CdPty %s",
+		format_ie(iif->hcmsg.CalledPartyNumber));
+
+	/* scan application list for matching listeners */
+	bcs->ap = NULL;
+	actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
+	list_for_each_entry(ap, &iif->appls, ctrlist)
+		if (actCIPmask & ap->listenCIPmask) {
+			/* build CONNECT_IND message for this application */
+			iif->hcmsg.ApplId = ap->id;
+			iif->hcmsg.Messagenumber = ap->nextMessageNumber++;
+
+			skb = alloc_skb(msgsize, GFP_ATOMIC);
+			if (!skb) {
+				dev_err(cs->dev, "%s: out of memory\n",
+					__func__);
+				break;
+			}
+			capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+			dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
+
+			/* add to listeners on this B channel, update state */
+			ap->bcnext = bcs->ap;
+			bcs->ap = ap;
+			bcs->chstate |= CHS_NOTIFY_LL;
+			ap->connected = APCONN_SETUP;
+
+			/* emit message */
+			capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+		}
+
+	/*
+	 * Return "accept" if any listeners.
+	 * Gigaset will send ALERTING.
+	 * There doesn't seem to be a way to avoid this.
+	 */
+	return bcs->ap ? ICALL_ACCEPT : ICALL_IGNORE;
+}
+
+/*
+ * send a DISCONNECT_IND message to an application
+ * does not sleep, clobbers the controller's hcmsg structure
+ */
+static void send_disconnect_ind(struct bc_state *bcs,
+				struct gigaset_capi_appl *ap, u16 reason)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct sk_buff *skb;
+
+	if (ap->connected == APCONN_NONE)
+		return;
+
+	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
+			 ap->nextMessageNumber++,
+			 iif->ctr.cnr | ((bcs->channel + 1) << 8));
+	iif->hcmsg.Reason = reason;
+	skb = alloc_skb(CAPI_DISCONNECT_IND_LEN, GFP_ATOMIC);
+	if (!skb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
+	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
+	ap->connected = APCONN_NONE;
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/*
+ * send a DISCONNECT_B3_IND message to an application
+ * Parameters: NCCI = 1, NCPI empty, Reason_B3 = 0
+ * does not sleep, clobbers the controller's hcmsg structure
+ */
+static void send_disconnect_b3_ind(struct bc_state *bcs,
+				   struct gigaset_capi_appl *ap)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct sk_buff *skb;
+
+	/* nothing to do if no logical connection active */
+	if (ap->connected < APCONN_ACTIVE)
+		return;
+	ap->connected = APCONN_SETUP;
+
+	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
+			 ap->nextMessageNumber++,
+			 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
+	skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_ATOMIC);
+	if (!skb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	capi_cmsg2message(&iif->hcmsg,
+			  __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/**
+ * gigaset_isdn_connD() - signal D channel connect
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module at tasklet level to notify the LL that the D channel
+ * connection has been established.
+ */
+void gigaset_isdn_connD(struct bc_state *bcs)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct gigaset_capi_appl *ap = bcs->ap;
+	struct sk_buff *skb;
+	unsigned int msgsize;
+
+	if (!ap) {
+		dev_err(cs->dev, "%s: no application\n", __func__);
+		return;
+	}
+	while (ap->bcnext) {
+		/* this should never happen */
+		dev_warn(cs->dev, "%s: dropping extra application %u\n",
+			 __func__, ap->bcnext->id);
+		send_disconnect_ind(bcs, ap->bcnext,
+				    CapiCallGivenToOtherApplication);
+		ap->bcnext = ap->bcnext->bcnext;
+	}
+	if (ap->connected == APCONN_NONE) {
+		dev_warn(cs->dev, "%s: application %u not connected\n",
+			 __func__, ap->id);
+		return;
+	}
+
+	/* prepare CONNECT_ACTIVE_IND message
+	 * Note: LLC not supported by device
+	 */
+	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_CONNECT_ACTIVE, CAPI_IND,
+			 ap->nextMessageNumber++,
+			 iif->ctr.cnr | ((bcs->channel + 1) << 8));
+
+	/* minimum size, all structs empty */
+	msgsize = CAPI_CONNECT_ACTIVE_IND_BASELEN;
+
+	/* ToDo: set parameter: Connected number
+	 * (requires ev-layer state machine extension to collect
+	 * ZCON device reply)
+	 */
+
+	/* build and emit CONNECT_ACTIVE_IND message */
+	skb = alloc_skb(msgsize, GFP_ATOMIC);
+	if (!skb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/**
+ * gigaset_isdn_hupD() - signal D channel hangup
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module at tasklet level to notify the LL that the D channel
+ * connection has been shut down.
+ */
+void gigaset_isdn_hupD(struct bc_state *bcs)
+{
+	struct gigaset_capi_appl *ap;
+
+	/*
+	 * ToDo: pass on reason code reported by device
+	 * (requires ev-layer state machine extension to collect
+	 * ZCAU device reply)
+	 */
+	for (ap = bcs->ap; ap != NULL; ap = ap->bcnext) {
+		send_disconnect_b3_ind(bcs, ap);
+		send_disconnect_ind(bcs, ap, 0);
+	}
+	bcs->ap = NULL;
+}
+
+/**
+ * gigaset_isdn_connB() - signal B channel connect
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module at tasklet level to notify the LL that the B channel
+ * connection has been established.
+ */
+void gigaset_isdn_connB(struct bc_state *bcs)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_ctr *iif = cs->iif;
+	struct gigaset_capi_appl *ap = bcs->ap;
+	struct sk_buff *skb;
+	unsigned int msgsize;
+	u8 command;
+
+	if (!ap) {
+		dev_err(cs->dev, "%s: no application\n", __func__);
+		return;
+	}
+	while (ap->bcnext) {
+		/* this should never happen */
+		dev_warn(cs->dev, "%s: dropping extra application %u\n",
+			 __func__, ap->bcnext->id);
+		send_disconnect_ind(bcs, ap->bcnext,
+				    CapiCallGivenToOtherApplication);
+		ap->bcnext = ap->bcnext->bcnext;
+	}
+	if (!ap->connected) {
+		dev_warn(cs->dev, "%s: application %u not connected\n",
+			 __func__, ap->id);
+		return;
+	}
+
+	/*
+	 * emit CONNECT_B3_ACTIVE_IND if we already got CONNECT_B3_REQ;
+	 * otherwise we have to emit CONNECT_B3_IND first, and follow up with
+	 * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
+	 * Parameters in both cases always: NCCI = 1, NCPI empty
+	 */
+	if (ap->connected >= APCONN_ACTIVE) {
+		command = CAPI_CONNECT_B3_ACTIVE;
+		msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
+	} else {
+		command = CAPI_CONNECT_B3;
+		msgsize = CAPI_CONNECT_B3_IND_BASELEN;
+	}
+	capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
+			 ap->nextMessageNumber++,
+			 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
+	skb = alloc_skb(msgsize, GFP_ATOMIC);
+	if (!skb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
+	ap->connected = APCONN_ACTIVE;
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/**
+ * gigaset_isdn_hupB() - signal B channel hangup
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module to notify the LL that the B channel connection has
+ * been shut down.
+ */
+void gigaset_isdn_hupB(struct bc_state *bcs)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_appl *ap = bcs->ap;
+
+	/* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */
+
+	if (!ap) {
+		dev_err(cs->dev, "%s: no application\n", __func__);
+		return;
+	}
+
+	send_disconnect_b3_ind(bcs, ap);
+}
+
+/**
+ * gigaset_isdn_start() - signal device availability
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to notify the LL that the device is available for
+ * use.
+ */
+void gigaset_isdn_start(struct cardstate *cs)
+{
+	struct gigaset_capi_ctr *iif = cs->iif;
+
+	/* fill profile data: manufacturer name */
+	strcpy(iif->ctr.manu, "Siemens");
+	/* CAPI and device version */
+	iif->ctr.version.majorversion = 2;		/* CAPI 2.0 */
+	iif->ctr.version.minorversion = 0;
+	/* ToDo: check/assert cs->gotfwver? */
+	iif->ctr.version.majormanuversion = cs->fwver[0];
+	iif->ctr.version.minormanuversion = cs->fwver[1];
+	/* number of B channels supported */
+	iif->ctr.profile.nbchannel = cs->channels;
+	/* global options: internal controller, supplementary services */
+	iif->ctr.profile.goptions = 0x11;
+	/* B1 protocols: 64 kbit/s HDLC or transparent */
+	iif->ctr.profile.support1 =  0x03;
+	/* B2 protocols: transparent only */
+	/* ToDo: X.75 SLP ? */
+	iif->ctr.profile.support2 =  0x02;
+	/* B3 protocols: transparent only */
+	iif->ctr.profile.support3 =  0x01;
+	/* no serial number */
+	strcpy(iif->ctr.serial, "0");
+	capi_ctr_ready(&iif->ctr);
+}
+
+/**
+ * gigaset_isdn_stop() - signal device unavailability
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to notify the LL that the device is no longer
+ * available for use.
+ */
+void gigaset_isdn_stop(struct cardstate *cs)
+{
+	struct gigaset_capi_ctr *iif = cs->iif;
+	capi_ctr_down(&iif->ctr);
+}
+
+/*
+ * kernel CAPI callback methods
+ * ============================
+ */
+
+/*
+ * load firmware
+ */
+static int gigaset_load_firmware(struct capi_ctr *ctr, capiloaddata *data)
+{
+	struct cardstate *cs = ctr->driverdata;
+
+	/* AVM specific operation, not needed for Gigaset -- ignore */
+	dev_notice(cs->dev, "load_firmware ignored\n");
+
+	return 0;
+}
+
+/*
+ * reset (deactivate) controller
+ */
+static void gigaset_reset_ctr(struct capi_ctr *ctr)
+{
+	struct cardstate *cs = ctr->driverdata;
+
+	/* AVM specific operation, not needed for Gigaset -- ignore */
+	dev_notice(cs->dev, "reset_ctr ignored\n");
+}
+
+/*
+ * register CAPI application
+ */
+static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
+			   capi_register_params *rp)
+{
+	struct gigaset_capi_ctr *iif
+		= container_of(ctr, struct gigaset_capi_ctr, ctr);
+	struct cardstate *cs = ctr->driverdata;
+	struct gigaset_capi_appl *ap;
+
+	list_for_each_entry(ap, &iif->appls, ctrlist)
+		if (ap->id == appl) {
+			dev_notice(cs->dev,
+				   "application %u already registered\n", appl);
+			return;
+		}
+
+	ap = kzalloc(sizeof(*ap), GFP_KERNEL);
+	if (!ap) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	ap->id = appl;
+
+	list_add(&ap->ctrlist, &iif->appls);
+}
+
+/*
+ * release CAPI application
+ */
+static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
+{
+	struct gigaset_capi_ctr *iif
+		= container_of(ctr, struct gigaset_capi_ctr, ctr);
+	struct cardstate *cs = iif->ctr.driverdata;
+	struct gigaset_capi_appl *ap, *tmp;
+
+	list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
+		if (ap->id == appl) {
+			if (ap->connected != APCONN_NONE) {
+				dev_err(cs->dev,
+					"%s: application %u still connected\n",
+					__func__, ap->id);
+				/* ToDo: clear active connection */
+			}
+			list_del(&ap->ctrlist);
+			kfree(ap);
+		}
+
+}
+
+/*
+ * =====================================================================
+ * outgoing CAPI message handler
+ * =====================================================================
+ */
+
+/*
+ * helper function: emit reply message with given Info value
+ */
+static void send_conf(struct gigaset_capi_ctr *iif,
+		      struct gigaset_capi_appl *ap,
+		      struct sk_buff *skb,
+		      u16 info)
+{
+	/*
+	 * _CONF replies always only have NCCI and Info parameters
+	 * so they'll fit into the _REQ message skb
+	 */
+	capi_cmsg_answer(&iif->acmsg);
+	iif->acmsg.Info = info;
+	capi_cmsg2message(&iif->acmsg, skb->data);
+	__skb_trim(skb, CAPI_STDCONF_LEN);
+	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/*
+ * process FACILITY_REQ message
+ */
+static void do_facility_req(struct gigaset_capi_ctr *iif,
+			    struct gigaset_capi_appl *ap,
+			    struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	struct sk_buff *cskb;
+	u8 *pparam;
+	unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
+	u16 function, info;
+	static u8 confparam[10];	/* max. 9 octets + length byte */
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/*
+	 * Facility Request Parameter is not decoded by capi_message2cmsg()
+	 * encoding depends on Facility Selector
+	 */
+	switch (cmsg->FacilitySelector) {
+	case CAPI_FACILITY_DTMF:	/* ToDo */
+		info = CapiFacilityNotSupported;
+		confparam[0] = 2;	/* length */
+		/* DTMF information: Unknown DTMF request */
+		capimsg_setu16(confparam, 1, 2);
+		break;
+
+	case CAPI_FACILITY_V42BIS:	/* not supported */
+		info = CapiFacilityNotSupported;
+		confparam[0] = 2;	/* length */
+		/* V.42 bis information: not available */
+		capimsg_setu16(confparam, 1, 1);
+		break;
+
+	case CAPI_FACILITY_SUPPSVC:
+		/* decode Function parameter */
+		pparam = cmsg->FacilityRequestParameter;
+		if (pparam == NULL || *pparam < 2) {
+			dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
+				   "Facility Request Parameter");
+			send_conf(iif, ap, skb, CapiIllMessageParmCoding);
+			return;
+		}
+		function = CAPIMSG_U16(pparam, 1);
+		switch (function) {
+		case CAPI_SUPPSVC_GETSUPPORTED:
+			info = CapiSuccess;
+			/* Supplementary Service specific parameter */
+			confparam[3] = 6;	/* length */
+			/* Supplementary services info: Success */
+			capimsg_setu16(confparam, 4, CapiSuccess);
+			/* Supported Services: none */
+			capimsg_setu32(confparam, 6, 0);
+			break;
+		/* ToDo: add supported services */
+		default:
+			info = CapiFacilitySpecificFunctionNotSupported;
+			/* Supplementary Service specific parameter */
+			confparam[3] = 2;	/* length */
+			/* Supplementary services info: not supported */
+			capimsg_setu16(confparam, 4,
+				       CapiSupplementaryServiceNotSupported);
+		}
+
+		/* Facility confirmation parameter */
+		confparam[0] = confparam[3] + 3;	/* total length */
+		/* Function: copy from _REQ message */
+		capimsg_setu16(confparam, 1, function);
+		/* Supplementary Service specific parameter already set above */
+		break;
+
+	case CAPI_FACILITY_WAKEUP:	/* ToDo */
+		info = CapiFacilityNotSupported;
+		confparam[0] = 2;	/* length */
+		/* Number of accepted awake request parameters: 0 */
+		capimsg_setu16(confparam, 1, 0);
+		break;
+
+	default:
+		info = CapiFacilityNotSupported;
+		confparam[0] = 0;	/* empty struct */
+	}
+
+	/* send FACILITY_CONF with given Info and confirmation parameter */
+	capi_cmsg_answer(cmsg);
+	cmsg->Info = info;
+	cmsg->FacilityConfirmationParameter = confparam;
+	msgsize += confparam[0];	/* length */
+	cskb = alloc_skb(msgsize, GFP_ATOMIC);
+	if (!cskb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	capi_cmsg2message(cmsg, __skb_put(cskb, msgsize));
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+	capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
+}
+
+
+/*
+ * process LISTEN_REQ message
+ * just store the masks in the application data structure
+ */
+static void do_listen_req(struct gigaset_capi_ctr *iif,
+			  struct gigaset_capi_appl *ap,
+			  struct sk_buff *skb)
+{
+	/* decode message */
+	capi_message2cmsg(&iif->acmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+
+	/* store listening parameters */
+	ap->listenInfoMask = iif->acmsg.InfoMask;
+	ap->listenCIPmask = iif->acmsg.CIPmask;
+	send_conf(iif, ap, skb, CapiSuccess);
+}
+
+/*
+ * process ALERT_REQ message
+ * nothing to do, Gigaset always alerts anyway
+ */
+static void do_alert_req(struct gigaset_capi_ctr *iif,
+			 struct gigaset_capi_appl *ap,
+			 struct sk_buff *skb)
+{
+	/* decode message */
+	capi_message2cmsg(&iif->acmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+	send_conf(iif, ap, skb, CapiAlertAlreadySent);
+}
+
+/*
+ * process CONNECT_REQ message
+ * allocate a B channel, prepare dial commands, queue a DIAL event,
+ * emit CONNECT_CONF reply
+ */
+static void do_connect_req(struct gigaset_capi_ctr *iif,
+			   struct gigaset_capi_appl *ap,
+			   struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
+	char **commands;
+	char *s;
+	u8 *pp;
+	int i, l;
+	u16 info;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/* get free B channel & construct PLCI */
+	bcs = gigaset_get_free_channel(cs);
+	if (!bcs) {
+		dev_notice(cs->dev, "%s: no B channel available\n",
+			   "CONNECT_REQ");
+		send_conf(iif, ap, skb, CapiNoPlciAvailable);
+		return;
+	}
+	ap->bcnext = NULL;
+	bcs->ap = ap;
+	cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
+
+	/* build command table */
+	commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
+	if (!commands)
+		goto oom;
+
+	/* encode parameter: Called party number */
+	pp = cmsg->CalledPartyNumber;
+	if (pp == NULL || *pp == 0) {
+		dev_notice(cs->dev, "%s: %s missing\n",
+			   "CONNECT_REQ", "Called party number");
+		info = CapiIllMessageParmCoding;
+		goto error;
+	}
+	l = *pp++;
+	/* check type of number/numbering plan byte */
+	switch (*pp) {
+	case 0x80:	/* unknown type / unknown numbering plan */
+	case 0x81:	/* unknown type / ISDN/Telephony numbering plan */
+		break;
+	default:	/* others: warn about potential misinterpretation */
+		dev_notice(cs->dev, "%s: %s type/plan 0x%02x unsupported\n",
+			   "CONNECT_REQ", "Called party number", *pp);
+	}
+	pp++;
+	l--;
+	/* translate "**" internal call prefix to CTP value */
+	if (l >= 2 && pp[0] == '*' && pp[1] == '*') {
+		s = "^SCTP=0\r";
+		pp += 2;
+		l -= 2;
+	} else {
+		s = "^SCTP=1\r";
+	}
+	commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
+	if (!commands[AT_TYPE])
+		goto oom;
+	commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
+	if (!commands[AT_DIAL])
+		goto oom;
+	snprintf(commands[AT_DIAL], l+3, "D%.*s\r", l, pp);
+
+	/* encode parameter: Calling party number */
+	pp = cmsg->CallingPartyNumber;
+	if (pp != NULL && *pp > 0) {
+		l = *pp++;
+
+		/* check type of number/numbering plan byte */
+		/* ToDo: allow for/handle Ext=1? */
+		switch (*pp) {
+		case 0x00:	/* unknown type / unknown numbering plan */
+		case 0x01:	/* unknown type / ISDN/Telephony num. plan */
+			break;
+		default:
+			dev_notice(cs->dev,
+				   "%s: %s type/plan 0x%02x unsupported\n",
+				   "CONNECT_REQ", "Calling party number", *pp);
+		}
+		pp++;
+		l--;
+
+		/* check presentation indicator */
+		if (!l) {
+			dev_notice(cs->dev, "%s: %s IE truncated\n",
+				   "CONNECT_REQ", "Calling party number");
+			info = CapiIllMessageParmCoding;
+			goto error;
+		}
+		switch (*pp & 0xfc) { /* ignore Screening indicator */
+		case 0x80:	/* Presentation allowed */
+			s = "^SCLIP=1\r";
+			break;
+		case 0xa0:	/* Presentation restricted */
+			s = "^SCLIP=0\r";
+			break;
+		default:
+			dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+				   "CONNECT_REQ",
+				   "Presentation/Screening indicator",
+				   *pp);
+			s = "^SCLIP=1\r";
+		}
+		commands[AT_CLIP] = kstrdup(s, GFP_KERNEL);
+		if (!commands[AT_CLIP])
+			goto oom;
+		pp++;
+		l--;
+
+		if (l) {
+			/* number */
+			commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
+			if (!commands[AT_MSN])
+				goto oom;
+			snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
+		}
+	}
+
+	/* check parameter: CIP Value */
+	if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
+	    (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
+		dev_notice(cs->dev, "%s: unknown CIP value %d\n",
+			   "CONNECT_REQ", cmsg->CIPValue);
+		info = CapiCipValueUnknown;
+		goto error;
+	}
+
+	/* check/encode parameter: BC */
+	if (cmsg->BC && cmsg->BC[0]) {
+		/* explicit BC overrides CIP */
+		l = 2*cmsg->BC[0] + 7;
+		commands[AT_BC] = kmalloc(l, GFP_KERNEL);
+		if (!commands[AT_BC])
+			goto oom;
+		strcpy(commands[AT_BC], "^SBC=");
+		decode_ie(cmsg->BC, commands[AT_BC]+5);
+		strcpy(commands[AT_BC] + l - 2, "\r");
+	} else if (cip2bchlc[cmsg->CIPValue].bc) {
+		l = strlen(cip2bchlc[cmsg->CIPValue].bc) + 7;
+		commands[AT_BC] = kmalloc(l, GFP_KERNEL);
+		if (!commands[AT_BC])
+			goto oom;
+		snprintf(commands[AT_BC], l, "^SBC=%s\r",
+			 cip2bchlc[cmsg->CIPValue].bc);
+	}
+
+	/* check/encode parameter: HLC */
+	if (cmsg->HLC && cmsg->HLC[0]) {
+		/* explicit HLC overrides CIP */
+		l = 2*cmsg->HLC[0] + 7;
+		commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
+		if (!commands[AT_HLC])
+			goto oom;
+		strcpy(commands[AT_HLC], "^SHLC=");
+		decode_ie(cmsg->HLC, commands[AT_HLC]+5);
+		strcpy(commands[AT_HLC] + l - 2, "\r");
+	} else if (cip2bchlc[cmsg->CIPValue].hlc) {
+		l = strlen(cip2bchlc[cmsg->CIPValue].hlc) + 7;
+		commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
+		if (!commands[AT_HLC])
+			goto oom;
+		snprintf(commands[AT_HLC], l, "^SHLC=%s\r",
+			 cip2bchlc[cmsg->CIPValue].hlc);
+	}
+
+	/* check/encode parameter: B Protocol */
+	if (cmsg->BProtocol == CAPI_DEFAULT) {
+		bcs->proto2 = L2_HDLC;
+		dev_warn(cs->dev,
+		    "B2 Protocol X.75 SLP unsupported, using Transparent\n");
+	} else {
+		switch (cmsg->B1protocol) {
+		case 0:
+			bcs->proto2 = L2_HDLC;
+			break;
+		case 1:
+			bcs->proto2 = L2_BITSYNC;
+			break;
+		default:
+			dev_warn(cs->dev,
+			    "B1 Protocol %u unsupported, using Transparent\n",
+				 cmsg->B1protocol);
+			bcs->proto2 = L2_BITSYNC;
+		}
+		if (cmsg->B2protocol != 1)
+			dev_warn(cs->dev,
+			    "B2 Protocol %u unsupported, using Transparent\n",
+				 cmsg->B2protocol);
+		if (cmsg->B3protocol != 0)
+			dev_warn(cs->dev,
+			    "B3 Protocol %u unsupported, using Transparent\n",
+				 cmsg->B3protocol);
+		ignore_cstruct_param(cs, cmsg->B1configuration,
+					"CONNECT_REQ", "B1 Configuration");
+		ignore_cstruct_param(cs, cmsg->B2configuration,
+					"CONNECT_REQ", "B2 Configuration");
+		ignore_cstruct_param(cs, cmsg->B3configuration,
+					"CONNECT_REQ", "B3 Configuration");
+	}
+	commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
+	if (!commands[AT_PROTO])
+		goto oom;
+	snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
+
+	/* ToDo: check/encode remaining parameters */
+	ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
+					"CONNECT_REQ", "Called pty subaddr");
+	ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
+					"CONNECT_REQ", "Calling pty subaddr");
+	ignore_cstruct_param(cs, cmsg->LLC,
+					"CONNECT_REQ", "LLC");
+	if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
+		ignore_cstruct_param(cs, cmsg->BChannelinformation,
+					"CONNECT_REQ", "B Channel Information");
+		ignore_cstruct_param(cs, cmsg->Keypadfacility,
+					"CONNECT_REQ", "Keypad Facility");
+		ignore_cstruct_param(cs, cmsg->Useruserdata,
+					"CONNECT_REQ", "User-User Data");
+		ignore_cstruct_param(cs, cmsg->Facilitydataarray,
+					"CONNECT_REQ", "Facility Data Array");
+	}
+
+	/* encode parameter: B channel to use */
+	commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
+	if (!commands[AT_ISO])
+		goto oom;
+	snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
+		 (unsigned) bcs->channel + 1);
+
+	/* queue & schedule EV_DIAL event */
+	if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
+			       bcs->at_state.seq_index, NULL))
+		goto oom;
+	gig_dbg(DEBUG_CMD, "scheduling DIAL");
+	gigaset_schedule_event(cs);
+	ap->connected = APCONN_SETUP;
+	send_conf(iif, ap, skb, CapiSuccess);
+	return;
+
+oom:
+	dev_err(cs->dev, "%s: out of memory\n", __func__);
+	info = CAPI_MSGOSRESOURCEERR;
+error:
+	if (commands)
+		for (i = 0; i < AT_NUM; i++)
+			kfree(commands[i]);
+	kfree(commands);
+	gigaset_free_channel(bcs);
+	send_conf(iif, ap, skb, info);
+}
+
+/*
+ * process CONNECT_RESP message
+ * checks protocol parameters and queues an ACCEPT or HUP event
+ */
+static void do_connect_resp(struct gigaset_capi_ctr *iif,
+			    struct gigaset_capi_appl *ap,
+			    struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
+	struct gigaset_capi_appl *oap;
+	int channel;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+	dev_kfree_skb_any(skb);
+
+	/* extract and check channel number from PLCI */
+	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
+	if (!channel || channel > cs->channels) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "CONNECT_RESP", "PLCI", cmsg->adr.adrPLCI);
+		return;
+	}
+	bcs = cs->bcs + channel - 1;
+
+	switch (cmsg->Reject) {
+	case 0:		/* Accept */
+		/* drop all competing applications, keep only this one */
+		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
+			if (oap != ap)
+				send_disconnect_ind(bcs, oap,
+					CapiCallGivenToOtherApplication);
+		ap->bcnext = NULL;
+		bcs->ap = ap;
+		bcs->chstate |= CHS_NOTIFY_LL;
+
+		/* check/encode B channel protocol */
+		if (cmsg->BProtocol == CAPI_DEFAULT) {
+			bcs->proto2 = L2_HDLC;
+			dev_warn(cs->dev,
+		"B2 Protocol X.75 SLP unsupported, using Transparent\n");
+		} else {
+			switch (cmsg->B1protocol) {
+			case 0:
+				bcs->proto2 = L2_HDLC;
+				break;
+			case 1:
+				bcs->proto2 = L2_BITSYNC;
+				break;
+			default:
+				dev_warn(cs->dev,
+			"B1 Protocol %u unsupported, using Transparent\n",
+					 cmsg->B1protocol);
+				bcs->proto2 = L2_BITSYNC;
+			}
+			if (cmsg->B2protocol != 1)
+				dev_warn(cs->dev,
+			"B2 Protocol %u unsupported, using Transparent\n",
+					 cmsg->B2protocol);
+			if (cmsg->B3protocol != 0)
+				dev_warn(cs->dev,
+			"B3 Protocol %u unsupported, using Transparent\n",
+					 cmsg->B3protocol);
+			ignore_cstruct_param(cs, cmsg->B1configuration,
+					"CONNECT_RESP", "B1 Configuration");
+			ignore_cstruct_param(cs, cmsg->B2configuration,
+					"CONNECT_RESP", "B2 Configuration");
+			ignore_cstruct_param(cs, cmsg->B3configuration,
+					"CONNECT_RESP", "B3 Configuration");
+		}
+
+		/* ToDo: check/encode remaining parameters */
+		ignore_cstruct_param(cs, cmsg->ConnectedNumber,
+					"CONNECT_RESP", "Connected Number");
+		ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
+					"CONNECT_RESP", "Connected Subaddress");
+		ignore_cstruct_param(cs, cmsg->LLC,
+					"CONNECT_RESP", "LLC");
+		if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
+			ignore_cstruct_param(cs, cmsg->BChannelinformation,
+					"CONNECT_RESP", "BChannel Information");
+			ignore_cstruct_param(cs, cmsg->Keypadfacility,
+					"CONNECT_RESP", "Keypad Facility");
+			ignore_cstruct_param(cs, cmsg->Useruserdata,
+					"CONNECT_RESP", "User-User Data");
+			ignore_cstruct_param(cs, cmsg->Facilitydataarray,
+					"CONNECT_RESP", "Facility Data Array");
+		}
+
+		/* Accept call */
+		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+				       EV_ACCEPT, NULL, 0, NULL))
+			return;
+		gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
+		gigaset_schedule_event(cs);
+		return;
+
+	case 1:			/* Ignore */
+		/* send DISCONNECT_IND to this application */
+		send_disconnect_ind(bcs, ap, 0);
+
+		/* remove it from the list of listening apps */
+		if (bcs->ap == ap) {
+			bcs->ap = ap->bcnext;
+			if (bcs->ap == NULL)
+				/* last one: stop ev-layer hupD notifications */
+				bcs->chstate &= ~CHS_NOTIFY_LL;
+			return;
+		}
+		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
+			if (oap->bcnext == ap) {
+				oap->bcnext = oap->bcnext->bcnext;
+				return;
+			}
+		}
+		dev_err(cs->dev, "%s: application %u not found\n",
+			__func__, ap->id);
+		return;
+
+	default:		/* Reject */
+		/* drop all competing applications, keep only this one */
+		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
+			if (oap != ap)
+				send_disconnect_ind(bcs, oap,
+					CapiCallGivenToOtherApplication);
+		ap->bcnext = NULL;
+		bcs->ap = ap;
+
+		/* reject call - will trigger DISCONNECT_IND for this app */
+		dev_info(cs->dev, "%s: Reject=%x\n",
+			 "CONNECT_RESP", cmsg->Reject);
+		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+				       EV_HUP, NULL, 0, NULL))
+			return;
+		gig_dbg(DEBUG_CMD, "scheduling HUP");
+		gigaset_schedule_event(cs);
+		return;
+	}
+}
+
+/*
+ * process CONNECT_B3_REQ message
+ * build NCCI and emit CONNECT_B3_CONF reply
+ */
+static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
+			      struct gigaset_capi_appl *ap,
+			      struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	int channel;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/* extract and check channel number from PLCI */
+	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
+	if (!channel || channel > cs->channels) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "CONNECT_B3_REQ", "PLCI", cmsg->adr.adrPLCI);
+		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
+		return;
+	}
+
+	/* mark logical connection active */
+	ap->connected = APCONN_ACTIVE;
+
+	/* build NCCI: always 1 (one B3 connection only) */
+	cmsg->adr.adrNCCI |= 1 << 16;
+
+	/* NCPI parameter: not applicable for B3 Transparent */
+	ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
+	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
+				CapiNcpiNotSupportedByProtocol : CapiSuccess);
+}
+
+/*
+ * process CONNECT_B3_RESP message
+ * Depending on the Reject parameter, either emit CONNECT_B3_ACTIVE_IND
+ * or queue EV_HUP and emit DISCONNECT_B3_IND.
+ * The emitted message is always shorter than the received one,
+ * allowing to reuse the skb.
+ */
+static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
+			       struct gigaset_capi_appl *ap,
+			       struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
+	int channel;
+	unsigned int msgsize;
+	u8 command;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/* extract and check channel number and NCCI */
+	channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
+	if (!channel || channel > cs->channels ||
+	    ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
+		dev_kfree_skb_any(skb);
+		return;
+	}
+	bcs = &cs->bcs[channel-1];
+
+	if (cmsg->Reject) {
+		/* Reject: clear B3 connect received flag */
+		ap->connected = APCONN_SETUP;
+
+		/* trigger hangup, causing eventual DISCONNECT_IND */
+		if (!gigaset_add_event(cs, &bcs->at_state,
+				       EV_HUP, NULL, 0, NULL)) {
+			dev_err(cs->dev, "%s: out of memory\n", __func__);
+			dev_kfree_skb_any(skb);
+			return;
+		}
+		gig_dbg(DEBUG_CMD, "scheduling HUP");
+		gigaset_schedule_event(cs);
+
+		/* emit DISCONNECT_B3_IND */
+		command = CAPI_DISCONNECT_B3;
+		msgsize = CAPI_DISCONNECT_B3_IND_BASELEN;
+	} else {
+		/*
+		 * Accept: emit CONNECT_B3_ACTIVE_IND immediately, as
+		 * we only send CONNECT_B3_IND if the B channel is up
+		 */
+		command = CAPI_CONNECT_B3_ACTIVE;
+		msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
+	}
+	capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
+			 ap->nextMessageNumber++, cmsg->adr.adrNCCI);
+	__skb_trim(skb, msgsize);
+	capi_cmsg2message(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
+}
+
+/*
+ * process DISCONNECT_REQ message
+ * schedule EV_HUP and emit DISCONNECT_B3_IND if necessary,
+ * emit DISCONNECT_CONF reply
+ */
+static void do_disconnect_req(struct gigaset_capi_ctr *iif,
+			      struct gigaset_capi_appl *ap,
+			      struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
+	_cmsg *b3cmsg;
+	struct sk_buff *b3skb;
+	int channel;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/* extract and check channel number from PLCI */
+	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
+	if (!channel || channel > cs->channels) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "DISCONNECT_REQ", "PLCI", cmsg->adr.adrPLCI);
+		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
+		return;
+	}
+	bcs = cs->bcs + channel - 1;
+
+	/* ToDo: process parameter: Additional info */
+	if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
+		ignore_cstruct_param(cs, cmsg->BChannelinformation,
+				     "DISCONNECT_REQ", "B Channel Information");
+		ignore_cstruct_param(cs, cmsg->Keypadfacility,
+				     "DISCONNECT_REQ", "Keypad Facility");
+		ignore_cstruct_param(cs, cmsg->Useruserdata,
+				     "DISCONNECT_REQ", "User-User Data");
+		ignore_cstruct_param(cs, cmsg->Facilitydataarray,
+				     "DISCONNECT_REQ", "Facility Data Array");
+	}
+
+	/* skip if DISCONNECT_IND already sent */
+	if (!ap->connected)
+		return;
+
+	/* check for active logical connection */
+	if (ap->connected >= APCONN_ACTIVE) {
+		/*
+		 * emit DISCONNECT_B3_IND with cause 0x3301
+		 * use separate cmsg structure, as the content of iif->acmsg
+		 * is still needed for creating the _CONF message
+		 */
+		b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
+		if (!b3cmsg) {
+			dev_err(cs->dev, "%s: out of memory\n", __func__);
+			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+			return;
+		}
+		capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
+				 ap->nextMessageNumber++,
+				 cmsg->adr.adrPLCI | (1 << 16));
+		b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
+		b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
+		if (b3skb == NULL) {
+			dev_err(cs->dev, "%s: out of memory\n", __func__);
+			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+			return;
+		}
+		capi_cmsg2message(b3cmsg,
+			__skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+		kfree(b3cmsg);
+		capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
+	}
+
+	/* trigger hangup, causing eventual DISCONNECT_IND */
+	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+		return;
+	}
+	gig_dbg(DEBUG_CMD, "scheduling HUP");
+	gigaset_schedule_event(cs);
+
+	/* emit reply */
+	send_conf(iif, ap, skb, CapiSuccess);
+}
+
+/*
+ * process DISCONNECT_B3_REQ message
+ * schedule EV_HUP and emit DISCONNECT_B3_CONF reply
+ */
+static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
+				 struct gigaset_capi_appl *ap,
+				 struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	_cmsg *cmsg = &iif->acmsg;
+	int channel;
+
+	/* decode message */
+	capi_message2cmsg(cmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, cmsg);
+
+	/* extract and check channel number and NCCI */
+	channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
+	if (!channel || channel > cs->channels ||
+	    ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "DISCONNECT_B3_REQ", "NCCI", cmsg->adr.adrNCCI);
+		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
+		return;
+	}
+
+	/* reject if logical connection not active */
+	if (ap->connected < APCONN_ACTIVE) {
+		send_conf(iif, ap, skb,
+			  CapiMessageNotSupportedInCurrentState);
+		return;
+	}
+
+	/* trigger hangup, causing eventual DISCONNECT_B3_IND */
+	if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+			       EV_HUP, NULL, 0, NULL)) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+		return;
+	}
+	gig_dbg(DEBUG_CMD, "scheduling HUP");
+	gigaset_schedule_event(cs);
+
+	/* NCPI parameter: not applicable for B3 Transparent */
+	ignore_cstruct_param(cs, cmsg->NCPI,
+				"DISCONNECT_B3_REQ", "NCPI");
+	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
+				CapiNcpiNotSupportedByProtocol : CapiSuccess);
+}
+
+/*
+ * process DATA_B3_REQ message
+ */
+static void do_data_b3_req(struct gigaset_capi_ctr *iif,
+			   struct gigaset_capi_appl *ap,
+			   struct sk_buff *skb)
+{
+	struct cardstate *cs = iif->ctr.driverdata;
+	int channel = CAPIMSG_PLCI_PART(skb->data);
+	u16 ncci = CAPIMSG_NCCI_PART(skb->data);
+	u16 msglen = CAPIMSG_LEN(skb->data);
+	u16 datalen = CAPIMSG_DATALEN(skb->data);
+	u16 flags = CAPIMSG_FLAGS(skb->data);
+
+	/* frequent message, avoid _cmsg overhead */
+	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
+
+	gig_dbg(DEBUG_LLDATA,
+		"Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
+		channel, flags, msglen, datalen);
+
+	/* check parameters */
+	if (channel == 0 || channel > cs->channels || ncci != 1) {
+		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
+			   "DATA_B3_REQ", "NCCI", CAPIMSG_NCCI(skb->data));
+		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
+		return;
+	}
+	if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
+		dev_notice(cs->dev, "%s: unexpected length %d\n",
+			   "DATA_B3_REQ", msglen);
+	if (msglen + datalen != skb->len)
+		dev_notice(cs->dev, "%s: length mismatch (%d+%d!=%d)\n",
+			   "DATA_B3_REQ", msglen, datalen, skb->len);
+	if (msglen + datalen > skb->len) {
+		/* message too short for announced data length */
+		send_conf(iif, ap, skb, CapiIllMessageParmCoding); /* ? */
+		return;
+	}
+	if (flags & CAPI_FLAGS_RESERVED) {
+		dev_notice(cs->dev, "%s: reserved flags set (%x)\n",
+			   "DATA_B3_REQ", flags);
+		send_conf(iif, ap, skb, CapiIllMessageParmCoding);
+		return;
+	}
+
+	/* reject if logical connection not active */
+	if (ap->connected < APCONN_ACTIVE) {
+		send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
+		return;
+	}
+
+	/* pull CAPI message into link layer header */
+	skb_reset_mac_header(skb);
+	skb->mac_len = msglen;
+	skb_pull(skb, msglen);
+
+	/* pass to device-specific module */
+	if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) {
+		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+		return;
+	}
+
+	/* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */
+
+	/*
+	 * ToDo: honor unset "delivery confirmation" bit
+	 * (send DATA_B3_CONF immediately?)
+	 */
+}
+
+/*
+ * process RESET_B3_REQ message
+ * just always reply "not supported by current protocol"
+ */
+static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
+			    struct gigaset_capi_appl *ap,
+			    struct sk_buff *skb)
+{
+	/* decode message */
+	capi_message2cmsg(&iif->acmsg, skb->data);
+	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+	send_conf(iif, ap, skb,
+		  CapiResetProcedureNotSupportedByCurrentProtocol);
+}
+
+/*
+ * dump unsupported/ignored messages at most twice per minute,
+ * some apps send those very frequently
+ */
+static unsigned long ignored_msg_dump_time;
+
+/*
+ * unsupported CAPI message handler
+ */
+static void do_unsupported(struct gigaset_capi_ctr *iif,
+			   struct gigaset_capi_appl *ap,
+			   struct sk_buff *skb)
+{
+	/* decode message */
+	capi_message2cmsg(&iif->acmsg, skb->data);
+	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
+		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+	send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
+}
+
+/*
+ * CAPI message handler: no-op
+ */
+static void do_nothing(struct gigaset_capi_ctr *iif,
+		       struct gigaset_capi_appl *ap,
+		       struct sk_buff *skb)
+{
+	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
+		/* decode message */
+		capi_message2cmsg(&iif->acmsg, skb->data);
+		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
+	}
+	dev_kfree_skb_any(skb);
+}
+
+static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
+			    struct gigaset_capi_appl *ap,
+			    struct sk_buff *skb)
+{
+	dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
+	dev_kfree_skb_any(skb);
+}
+
+/* table of outgoing CAPI message handlers with lookup function */
+typedef void (*capi_send_handler_t)(struct gigaset_capi_ctr *,
+				    struct gigaset_capi_appl *,
+				    struct sk_buff *);
+
+static struct {
+	u16 cmd;
+	capi_send_handler_t handler;
+} capi_send_handler_table[] = {
+	/* most frequent messages first for faster lookup */
+	{ CAPI_DATA_B3_REQ, do_data_b3_req },
+	{ CAPI_DATA_B3_RESP, do_data_b3_resp },
+
+	{ CAPI_ALERT_REQ, do_alert_req },
+	{ CAPI_CONNECT_ACTIVE_RESP, do_nothing },
+	{ CAPI_CONNECT_B3_ACTIVE_RESP, do_nothing },
+	{ CAPI_CONNECT_B3_REQ, do_connect_b3_req },
+	{ CAPI_CONNECT_B3_RESP, do_connect_b3_resp },
+	{ CAPI_CONNECT_B3_T90_ACTIVE_RESP, do_nothing },
+	{ CAPI_CONNECT_REQ, do_connect_req },
+	{ CAPI_CONNECT_RESP, do_connect_resp },
+	{ CAPI_DISCONNECT_B3_REQ, do_disconnect_b3_req },
+	{ CAPI_DISCONNECT_B3_RESP, do_nothing },
+	{ CAPI_DISCONNECT_REQ, do_disconnect_req },
+	{ CAPI_DISCONNECT_RESP, do_nothing },
+	{ CAPI_FACILITY_REQ, do_facility_req },
+	{ CAPI_FACILITY_RESP, do_nothing },
+	{ CAPI_LISTEN_REQ, do_listen_req },
+	{ CAPI_SELECT_B_PROTOCOL_REQ, do_unsupported },
+	{ CAPI_RESET_B3_REQ, do_reset_b3_req },
+	{ CAPI_RESET_B3_RESP, do_nothing },
+
+	/*
+	 * ToDo: support overlap sending (requires ev-layer state
+	 * machine extension to generate additional ATD commands)
+	 */
+	{ CAPI_INFO_REQ, do_unsupported },
+	{ CAPI_INFO_RESP, do_nothing },
+
+	/*
+	 * ToDo: what's the proper response for these?
+	 */
+	{ CAPI_MANUFACTURER_REQ, do_nothing },
+	{ CAPI_MANUFACTURER_RESP, do_nothing },
+};
+
+/* look up handler */
+static inline capi_send_handler_t lookup_capi_send_handler(const u16 cmd)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(capi_send_handler_table); i++)
+		if (capi_send_handler_table[i].cmd == cmd)
+			return capi_send_handler_table[i].handler;
+	return NULL;
+}
+
+
+/**
+ * gigaset_send_message() - accept a CAPI message from an application
+ * @ctr:	controller descriptor structure.
+ * @skb:	CAPI message.
+ *
+ * Return value: CAPI error code
+ * Note: capidrv (and probably others, too) only uses the return value to
+ * decide whether it has to free the skb (only if result != CAPI_NOERROR (0))
+ */
+static u16 gigaset_send_message(struct capi_ctr *ctr, struct sk_buff *skb)
+{
+	struct gigaset_capi_ctr *iif
+		= container_of(ctr, struct gigaset_capi_ctr, ctr);
+	struct cardstate *cs = ctr->driverdata;
+	struct gigaset_capi_appl *ap;
+	capi_send_handler_t handler;
+
+	/* can only handle linear sk_buffs */
+	if (skb_linearize(skb) < 0) {
+		dev_warn(cs->dev, "%s: skb_linearize failed\n", __func__);
+		return CAPI_MSGOSRESOURCEERR;
+	}
+
+	/* retrieve application data structure */
+	ap = get_appl(iif, CAPIMSG_APPID(skb->data));
+	if (!ap) {
+		dev_notice(cs->dev, "%s: application %u not registered\n",
+			   __func__, CAPIMSG_APPID(skb->data));
+		return CAPI_ILLAPPNR;
+	}
+
+	/* look up command */
+	handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
+	if (!handler) {
+		/* unknown/unsupported message type */
+		if (printk_ratelimit())
+			dev_notice(cs->dev, "%s: unsupported message %u\n",
+				   __func__, CAPIMSG_CMD(skb->data));
+		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
+	}
+
+	/* serialize */
+	if (atomic_add_return(1, &iif->sendqlen) > 1) {
+		/* queue behind other messages */
+		skb_queue_tail(&iif->sendqueue, skb);
+		return CAPI_NOERROR;
+	}
+
+	/* process message */
+	handler(iif, ap, skb);
+
+	/* process other messages arrived in the meantime */
+	while (atomic_sub_return(1, &iif->sendqlen) > 0) {
+		skb = skb_dequeue(&iif->sendqueue);
+		if (!skb) {
+			/* should never happen */
+			dev_err(cs->dev, "%s: send queue empty\n", __func__);
+			continue;
+		}
+		ap = get_appl(iif, CAPIMSG_APPID(skb->data));
+		if (!ap) {
+			/* could that happen? */
+			dev_warn(cs->dev, "%s: application %u vanished\n",
+				 __func__, CAPIMSG_APPID(skb->data));
+			continue;
+		}
+		handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
+		if (!handler) {
+			/* should never happen */
+			dev_err(cs->dev, "%s: handler %x vanished\n",
+				__func__, CAPIMSG_CMD(skb->data));
+			continue;
+		}
+		handler(iif, ap, skb);
+	}
+
+	return CAPI_NOERROR;
+}
+
+/**
+ * gigaset_procinfo() - build single line description for controller
+ * @ctr:	controller descriptor structure.
+ *
+ * Return value: pointer to generated string (null terminated)
+ */
+static char *gigaset_procinfo(struct capi_ctr *ctr)
+{
+	return ctr->name;	/* ToDo: more? */
+}
+
+/**
+ * gigaset_ctr_read_proc() - build controller proc file entry
+ * @page:	buffer of PAGE_SIZE bytes for receiving the entry.
+ * @start:	unused.
+ * @off:	unused.
+ * @count:	unused.
+ * @eof:	unused.
+ * @ctr:	controller descriptor structure.
+ *
+ * Return value: length of generated entry
+ */
+static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
+			  int count, int *eof, struct capi_ctr *ctr)
+{
+	struct cardstate *cs = ctr->driverdata;
+	char *s;
+	int i;
+	int len = 0;
+	len += sprintf(page+len, "%-16s %s\n", "name", ctr->name);
+	len += sprintf(page+len, "%-16s %s %s\n", "dev",
+			dev_driver_string(cs->dev), dev_name(cs->dev));
+	len += sprintf(page+len, "%-16s %d\n", "id", cs->myid);
+	if (cs->gotfwver)
+		len += sprintf(page+len, "%-16s %d.%d.%d.%d\n", "firmware",
+			cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
+	len += sprintf(page+len, "%-16s %d\n", "channels",
+			cs->channels);
+	len += sprintf(page+len, "%-16s %s\n", "onechannel",
+			cs->onechannel ? "yes" : "no");
+
+	switch (cs->mode) {
+	case M_UNKNOWN:
+		s = "unknown";
+		break;
+	case M_CONFIG:
+		s = "config";
+		break;
+	case M_UNIMODEM:
+		s = "Unimodem";
+		break;
+	case M_CID:
+		s = "CID";
+		break;
+	default:
+		s = "??";
+	}
+	len += sprintf(page+len, "%-16s %s\n", "mode", s);
+
+	switch (cs->mstate) {
+	case MS_UNINITIALIZED:
+		s = "uninitialized";
+		break;
+	case MS_INIT:
+		s = "init";
+		break;
+	case MS_LOCKED:
+		s = "locked";
+		break;
+	case MS_SHUTDOWN:
+		s = "shutdown";
+		break;
+	case MS_RECOVER:
+		s = "recover";
+		break;
+	case MS_READY:
+		s = "ready";
+		break;
+	default:
+		s = "??";
+	}
+	len += sprintf(page+len, "%-16s %s\n", "mstate", s);
+
+	len += sprintf(page+len, "%-16s %s\n", "running",
+			cs->running ? "yes" : "no");
+	len += sprintf(page+len, "%-16s %s\n", "connected",
+			cs->connected ? "yes" : "no");
+	len += sprintf(page+len, "%-16s %s\n", "isdn_up",
+			cs->isdn_up ? "yes" : "no");
+	len += sprintf(page+len, "%-16s %s\n", "cidmode",
+			cs->cidmode ? "yes" : "no");
+
+	for (i = 0; i < cs->channels; i++) {
+		len += sprintf(page+len, "[%d]%-13s %d\n", i, "corrupted",
+				cs->bcs[i].corrupted);
+		len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_down",
+				cs->bcs[i].trans_down);
+		len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_up",
+				cs->bcs[i].trans_up);
+		len += sprintf(page+len, "[%d]%-13s %d\n", i, "chstate",
+				cs->bcs[i].chstate);
+		switch (cs->bcs[i].proto2) {
+		case L2_BITSYNC:
+			s = "bitsync";
+			break;
+		case L2_HDLC:
+			s = "HDLC";
+			break;
+		case L2_VOICE:
+			s = "voice";
+			break;
+		default:
+			s = "??";
+		}
+		len += sprintf(page+len, "[%d]%-13s %s\n", i, "proto2", s);
+	}
+	return len;
+}
+
+
+static struct capi_driver capi_driver_gigaset = {
+	.name		= "gigaset",
+	.revision	= "1.0",
+};
+
+/**
+ * gigaset_isdn_register() - register to LL
+ * @cs:		device descriptor structure.
+ * @isdnid:	device name.
+ *
+ * Called by main module to register the device with the LL.
+ *
+ * Return value: 1 for success, 0 for failure
+ */
+int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+{
+	struct gigaset_capi_ctr *iif;
+	int rc;
+
+	pr_info("Kernel CAPI interface\n");
+
+	iif = kmalloc(sizeof(*iif), GFP_KERNEL);
+	if (!iif) {
+		pr_err("%s: out of memory\n", __func__);
+		return 0;
+	}
+
+	/* register driver with CAPI (ToDo: what for?) */
+	register_capi_driver(&capi_driver_gigaset);
+
+	/* prepare controller structure */
+	iif->ctr.owner         = THIS_MODULE;
+	iif->ctr.driverdata    = cs;
+	strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
+	iif->ctr.driver_name   = "gigaset";
+	iif->ctr.load_firmware = gigaset_load_firmware;
+	iif->ctr.reset_ctr     = gigaset_reset_ctr;
+	iif->ctr.register_appl = gigaset_register_appl;
+	iif->ctr.release_appl  = gigaset_release_appl;
+	iif->ctr.send_message  = gigaset_send_message;
+	iif->ctr.procinfo      = gigaset_procinfo;
+	iif->ctr.ctr_read_proc = gigaset_ctr_read_proc;
+	INIT_LIST_HEAD(&iif->appls);
+	skb_queue_head_init(&iif->sendqueue);
+	atomic_set(&iif->sendqlen, 0);
+
+	/* register controller with CAPI */
+	rc = attach_capi_ctr(&iif->ctr);
+	if (rc) {
+		pr_err("attach_capi_ctr failed (%d)\n", rc);
+		unregister_capi_driver(&capi_driver_gigaset);
+		kfree(iif);
+		return 0;
+	}
+
+	cs->iif = iif;
+	cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
+	return 1;
+}
+
+/**
+ * gigaset_isdn_unregister() - unregister from LL
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to unregister the device from the LL.
+ */
+void gigaset_isdn_unregister(struct cardstate *cs)
+{
+	struct gigaset_capi_ctr *iif = cs->iif;
+
+	detach_capi_ctr(&iif->ctr);
+	kfree(iif);
+	cs->iif = NULL;
+	unregister_capi_driver(&capi_driver_gigaset);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/common.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/common.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,7 @@
 #endif
 
 /* Module parameters */
-int gigaset_debuglevel = DEBUG_DEFAULT;
+int gigaset_debuglevel;
 EXPORT_SYMBOL_GPL(gigaset_debuglevel);
 module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(debug, "debug level");
@@ -108,7 +108,7 @@ int gigaset_enterconfigmode(struct cards
 {
 	int i, r;
 
-	cs->control_state = TIOCM_RTS; //FIXME
+	cs->control_state = TIOCM_RTS;
 
 	r = setflags(cs, TIOCM_DTR, 200);
 	if (r < 0)
@@ -132,10 +132,10 @@ int gigaset_enterconfigmode(struct cards
 
 error:
 	dev_err(cs->dev, "error %d on setuartbits\n", -r);
-	cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value?
+	cs->control_state = TIOCM_RTS|TIOCM_DTR;
 	cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR);
 
-	return -1; //r
+	return -1;
 }
 
 static int test_timeout(struct at_state_t *at_state)
@@ -150,10 +150,9 @@ static int test_timeout(struct at_state_
 	}
 
 	if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
-			       at_state->timer_index, NULL)) {
-		//FIXME what should we do?
-	}
-
+			       at_state->timer_index, NULL))
+			dev_err(at_state->cs->dev, "%s: out of memory\n",
+				__func__);
 	return 1;
 }
 
@@ -207,6 +206,32 @@ int gigaset_get_channel(struct bc_state
 	return 1;
 }
 
+struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
+{
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&cs->lock, flags);
+	if (!try_module_get(cs->driver->owner)) {
+		gig_dbg(DEBUG_ANY,
+			"could not get module for allocating channel");
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return NULL;
+	}
+	for (i = 0; i < cs->channels; ++i)
+		if (!cs->bcs[i].use_count) {
+			++cs->bcs[i].use_count;
+			cs->bcs[i].busy = 1;
+			spin_unlock_irqrestore(&cs->lock, flags);
+			gig_dbg(DEBUG_ANY, "allocated channel %d", i);
+			return cs->bcs + i;
+		}
+	module_put(cs->driver->owner);
+	spin_unlock_irqrestore(&cs->lock, flags);
+	gig_dbg(DEBUG_ANY, "no free channel");
+	return NULL;
+}
+
 void gigaset_free_channel(struct bc_state *bcs)
 {
 	unsigned long flags;
@@ -367,16 +392,15 @@ static void gigaset_freebcs(struct bc_st
 	int i;
 
 	gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel);
-	if (!bcs->cs->ops->freebcshw(bcs)) {
+	if (!bcs->cs->ops->freebcshw(bcs))
 		gig_dbg(DEBUG_INIT, "failed");
-	}
 
 	gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel);
 	clear_at_state(&bcs->at_state);
 	gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel);
+	dev_kfree_skb(bcs->skb);
+	bcs->skb = NULL;
 
-	if (bcs->skb)
-		dev_kfree_skb(bcs->skb);
 	for (i = 0; i < AT_NUM; ++i) {
 		kfree(bcs->commands[i]);
 		bcs->commands[i] = NULL;
@@ -463,6 +487,12 @@ void gigaset_freecs(struct cardstate *cs
 
 	switch (cs->cs_init) {
 	default:
+		/* clear B channel structures */
+		for (i = 0; i < cs->channels; ++i) {
+			gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
+			gigaset_freebcs(cs->bcs + i);
+		}
+
 		/* clear device sysfs */
 		gigaset_free_dev_sysfs(cs);
 
@@ -471,28 +501,20 @@ void gigaset_freecs(struct cardstate *cs
 		gig_dbg(DEBUG_INIT, "clearing hw");
 		cs->ops->freecshw(cs);
 
-		//FIXME cmdbuf
-
 		/* fall through */
 	case 2: /* error in initcshw */
 		/* Deregister from LL */
 		make_invalid(cs, VALID_ID);
-		gig_dbg(DEBUG_INIT, "clearing iif");
-		gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
+		gigaset_isdn_unregister(cs);
 
 		/* fall through */
-	case 1: /* error when regestering to LL */
+	case 1: /* error when registering to LL */
 		gig_dbg(DEBUG_INIT, "clearing at_state");
 		clear_at_state(&cs->at_state);
 		dealloc_at_states(cs);
 
 		/* fall through */
-	case 0: /* error in one call to initbcs */
-		for (i = 0; i < cs->channels; ++i) {
-			gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
-			gigaset_freebcs(cs->bcs + i);
-		}
-
+	case 0:	/* error in basic setup */
 		clear_events(cs);
 		gig_dbg(DEBUG_INIT, "freeing inbuf");
 		kfree(cs->inbuf);
@@ -534,16 +556,13 @@ void gigaset_at_init(struct at_state_t *
 }
 
 
-static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs,
-			       struct cardstate *cs, int inputstate)
+static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct cardstate *cs)
 /* inbuf->read must be allocated before! */
 {
 	inbuf->head = 0;
 	inbuf->tail = 0;
 	inbuf->cs = cs;
-	inbuf->bcs = bcs; /*base driver: NULL*/
-	inbuf->rcvbuf = NULL;
-	inbuf->inputstate = inputstate;
+	inbuf->inputstate = INS_command;
 }
 
 /**
@@ -599,7 +618,7 @@ static struct bc_state *gigaset_initbcs(
 {
 	int i;
 
-	bcs->tx_skb = NULL; //FIXME -> hw part
+	bcs->tx_skb = NULL;
 
 	skb_queue_head_init(&bcs->squeue);
 
@@ -618,13 +637,13 @@ static struct bc_state *gigaset_initbcs(
 	bcs->fcs = PPP_INITFCS;
 	bcs->inputstate = 0;
 	if (cs->ignoreframes) {
-		bcs->inputstate |= INS_skip_frame;
 		bcs->skb = NULL;
-	} else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
-		skb_reserve(bcs->skb, HW_HDR_LEN);
-	else {
-		pr_err("out of memory\n");
-		bcs->inputstate |= INS_skip_frame;
+	} else {
+		bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
+		if (bcs->skb != NULL)
+			skb_reserve(bcs->skb, cs->hw_hdr_len);
+		else
+			pr_err("out of memory\n");
 	}
 
 	bcs->channel = channel;
@@ -645,8 +664,8 @@ static struct bc_state *gigaset_initbcs(
 	gig_dbg(DEBUG_INIT, "  failed");
 
 	gig_dbg(DEBUG_INIT, "  freeing bcs[%d]->skb", channel);
-	if (bcs->skb)
-		dev_kfree_skb(bcs->skb);
+	dev_kfree_skb(bcs->skb);
+	bcs->skb = NULL;
 
 	return NULL;
 }
@@ -673,12 +692,13 @@ struct cardstate *gigaset_initcs(struct
 				 int onechannel, int ignoreframes,
 				 int cidmode, const char *modulename)
 {
-	struct cardstate *cs = NULL;
+	struct cardstate *cs;
 	unsigned long flags;
 	int i;
 
 	gig_dbg(DEBUG_INIT, "allocating cs");
-	if (!(cs = alloc_cs(drv))) {
+	cs = alloc_cs(drv);
+	if (!cs) {
 		pr_err("maximum number of devices exceeded\n");
 		return NULL;
 	}
@@ -707,7 +727,7 @@ struct cardstate *gigaset_initcs(struct
 	cs->ev_tail = 0;
 	cs->ev_head = 0;
 
-	tasklet_init(&cs->event_tasklet, &gigaset_handle_event,
+	tasklet_init(&cs->event_tasklet, gigaset_handle_event,
 		     (unsigned long) cs);
 	cs->commands_pending = 0;
 	cs->cur_at_seq = 0;
@@ -726,14 +746,6 @@ struct cardstate *gigaset_initcs(struct
 	cs->mode = M_UNKNOWN;
 	cs->mstate = MS_UNINITIALIZED;
 
-	for (i = 0; i < channels; ++i) {
-		gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i);
-		if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
-			pr_err("could not allocate channel %d data\n", i);
-			goto error;
-		}
-	}
-
 	++cs->cs_init;
 
 	gig_dbg(DEBUG_INIT, "setting up at_state");
@@ -743,10 +755,7 @@ struct cardstate *gigaset_initcs(struct
 	cs->cbytes = 0;
 
 	gig_dbg(DEBUG_INIT, "setting up inbuf");
-	if (onechannel) {			//FIXME distinction necessary?
-		gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command);
-	} else
-		gigaset_inbuf_init(cs->inbuf, NULL,    cs, INS_command);
+	gigaset_inbuf_init(cs->inbuf, cs);
 
 	cs->connected = 0;
 	cs->isdn_up = 0;
@@ -758,7 +767,7 @@ struct cardstate *gigaset_initcs(struct
 	cs->cmdbytes = 0;
 
 	gig_dbg(DEBUG_INIT, "setting up iif");
-	if (!gigaset_register_to_LL(cs, modulename)) {
+	if (!gigaset_isdn_register(cs, modulename)) {
 		pr_err("error registering ISDN device\n");
 		goto error;
 	}
@@ -777,6 +786,15 @@ struct cardstate *gigaset_initcs(struct
 	/* set up device sysfs */
 	gigaset_init_dev_sysfs(cs);
 
+	/* set up channel data structures */
+	for (i = 0; i < channels; ++i) {
+		gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i);
+		if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
+			pr_err("could not allocate channel %d data\n", i);
+			goto error;
+		}
+	}
+
 	spin_lock_irqsave(&cs->lock, flags);
 	cs->running = 1;
 	spin_unlock_irqrestore(&cs->lock, flags);
@@ -824,9 +842,10 @@ void gigaset_bcs_reinit(struct bc_state
 	bcs->chstate = 0;
 
 	bcs->ignore = cs->ignoreframes;
-	if (bcs->ignore)
-		bcs->inputstate |= INS_skip_frame;
-
+	if (bcs->ignore) {
+		dev_kfree_skb(bcs->skb);
+		bcs->skb = NULL;
+	}
 
 	cs->ops->reinitbcshw(bcs);
 }
@@ -847,8 +866,6 @@ static void cleanup_cs(struct cardstate
 	free_strings(&cs->at_state);
 	gigaset_at_init(&cs->at_state, NULL, cs, 0);
 
-	kfree(cs->inbuf->rcvbuf);
-	cs->inbuf->rcvbuf = NULL;
 	cs->inbuf->inputstate = INS_command;
 	cs->inbuf->head = 0;
 	cs->inbuf->tail = 0;
@@ -911,15 +928,13 @@ int gigaset_start(struct cardstate *cs)
 		cs->ops->baud_rate(cs, B115200);
 		cs->ops->set_line_ctrl(cs, CS8);
 		cs->control_state = TIOCM_DTR|TIOCM_RTS;
-	} else {
-		//FIXME use some saved values?
 	}
 
 	cs->waiting = 1;
 
 	if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
 		cs->waiting = 0;
-		//FIXME what should we do?
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		goto error;
 	}
 
@@ -959,7 +974,7 @@ int gigaset_shutdown(struct cardstate *c
 	cs->waiting = 1;
 
 	if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) {
-		//FIXME what should we do?
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		goto exit;
 	}
 
@@ -990,7 +1005,7 @@ void gigaset_stop(struct cardstate *cs)
 	cs->waiting = 1;
 
 	if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) {
-		//FIXME what should we do?
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		goto exit;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/dummyll.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/dummyll.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/dummyll.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/dummyll.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,68 @@
+/*
+ * Dummy LL interface for the Gigaset driver
+ *
+ * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
+ *
+ * =====================================================================
+ *	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 "gigaset.h"
+
+void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_sent);
+
+void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
+
+void gigaset_isdn_rcv_err(struct bc_state *bcs)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
+
+int gigaset_isdn_icall(struct at_state_t *at_state)
+{
+	return ICALL_IGNORE;
+}
+
+void gigaset_isdn_connD(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_hupD(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_connB(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_hupB(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_start(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_stop(struct cardstate *cs)
+{
+}
+
+int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+{
+	pr_info("no ISDN subsystem interface\n");
+	return 1;
+}
+
+void gigaset_isdn_unregister(struct cardstate *cs)
+{
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/ev-layer.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ev-layer.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/ev-layer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ev-layer.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,8 +40,8 @@
 
 /* Possible ASCII responses */
 #define RSP_OK		0
-//#define RSP_BUSY	1
-//#define RSP_CONNECT	2
+#define RSP_BUSY	1
+#define RSP_CONNECT	2
 #define RSP_ZGCI	3
 #define RSP_RING	4
 #define RSP_ZAOC	5
@@ -68,7 +68,6 @@
 #define RSP_ZHLC	(RSP_STR + STR_ZHLC)
 #define RSP_ERROR	-1	/* ERROR              */
 #define RSP_WRONG_CID	-2	/* unknown cid in cmd */
-//#define RSP_EMPTY	-3
 #define RSP_UNKNOWN	-4	/* unknown response   */
 #define RSP_FAIL	-5	/* internal error     */
 #define RSP_INVAL	-6	/* invalid response   */
@@ -76,9 +75,9 @@
 #define RSP_NONE	-19
 #define RSP_STRING	-20
 #define RSP_NULL	-21
-//#define RSP_RETRYFAIL	-22
-//#define RSP_RETRY	-23
-//#define RSP_SKIP	-24
+#define RSP_RETRYFAIL	-22
+#define RSP_RETRY	-23
+#define RSP_SKIP	-24
 #define RSP_INIT	-27
 #define RSP_ANY		-26
 #define RSP_LAST	-28
@@ -127,7 +126,6 @@
 #define ACT_NOTIFY_BC_UP	39
 #define ACT_DIAL		40
 #define ACT_ACCEPT		41
-#define ACT_PROTO_L2		42
 #define ACT_HUP			43
 #define ACT_IF_LOCK		44
 #define ACT_START		45
@@ -159,229 +157,229 @@
 #define SEQ_UMMODE	11
 
 
-// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring
+/* 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid),
+ * 400: hup, 500: reset, 600: dial, 700: ring */
 struct reply_t gigaset_tab_nocid[] =
 {
-	/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
-
-	/* initialize device, set cid mode if possible */
-	//{RSP_INIT,     -1, -1,100,                900, 0, {ACT_TEST}},
-	//{RSP_ERROR,   900,900, -1,                  0, 0, {ACT_FAILINIT}},
-	//{RSP_OK,      900,900, -1,                100, INIT_TIMEOUT,
-	//                                                  {ACT_TIMEOUT}},
-
-	{RSP_INIT,     -1, -1,SEQ_INIT,           100, INIT_TIMEOUT,
-							  {ACT_TIMEOUT}},                /* wait until device is ready */
+/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
+ * action, command */
 
-	{EV_TIMEOUT,  100,100, -1,                101, 3, {0},             "Z\r"},       /* device in transparent mode? try to initialize it. */
-	{RSP_OK,      101,103, -1,                120, 5, {ACT_GETSTRING}, "+GMR\r"},    /* get version */
+/* initialize device, set cid mode if possible */
+{RSP_INIT,	 -1,  -1, SEQ_INIT,		100,  1, {ACT_TIMEOUT} },
 
-	{EV_TIMEOUT,  101,101, -1,                102, 5, {0},             "Z\r"},       /* timeout => try once again. */
-	{RSP_ERROR,   101,101, -1,                102, 5, {0},             "Z\r"},       /* error => try once again. */
+{EV_TIMEOUT,	100, 100, -1,			101,  3, {0},	"Z\r"},
+{RSP_OK,	101, 103, -1,			120,  5, {ACT_GETSTRING},
+								"+GMR\r"},
 
-	{EV_TIMEOUT,  102,102, -1,                108, 5, {ACT_SETDLE1},   "^SDLE=0\r"}, /* timeout => try again in DLE mode. */
-	{RSP_OK,      108,108, -1,                104,-1},
-	{RSP_ZDLE,    104,104,  0,                103, 5, {0},             "Z\r"},
-	{EV_TIMEOUT,  104,104, -1,                  0, 0, {ACT_FAILINIT}},
-	{RSP_ERROR,   108,108, -1,                  0, 0, {ACT_FAILINIT}},
+{EV_TIMEOUT,	101, 101, -1,			102,  5, {0},	"Z\r"},
+{RSP_ERROR,	101, 101, -1,			102,  5, {0},	"Z\r"},
 
-	{EV_TIMEOUT,  108,108, -1,                105, 2, {ACT_SETDLE0,
-							   ACT_HUPMODEM,
-							   ACT_TIMEOUT}},                /* still timeout => connection in unimodem mode? */
-	{EV_TIMEOUT,  105,105, -1,                103, 5, {0},             "Z\r"},
+{EV_TIMEOUT,	102, 102, -1,			108,  5, {ACT_SETDLE1},
+								"^SDLE=0\r"},
+{RSP_OK,	108, 108, -1,			104, -1},
+{RSP_ZDLE,	104, 104,  0,			103,  5, {0},	"Z\r"},
+{EV_TIMEOUT,	104, 104, -1,			  0,  0, {ACT_FAILINIT} },
+{RSP_ERROR,	108, 108, -1,			  0,  0, {ACT_FAILINIT} },
 
-	{RSP_ERROR,   102,102, -1,                107, 5, {0},             "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */
-	{RSP_OK,      107,107, -1,                  0, 0, {ACT_CONFIGMODE}},
-	{RSP_ERROR,   107,107, -1,                  0, 0, {ACT_FAILINIT}},
-	{EV_TIMEOUT,  107,107, -1,                  0, 0, {ACT_FAILINIT}},
+{EV_TIMEOUT,	108, 108, -1,			105,  2, {ACT_SETDLE0,
+							  ACT_HUPMODEM,
+							  ACT_TIMEOUT} },
+{EV_TIMEOUT,	105, 105, -1,			103,  5, {0},	"Z\r"},
 
-	{RSP_ERROR,   103,103, -1,                  0, 0, {ACT_FAILINIT}},
-	{EV_TIMEOUT,  103,103, -1,                  0, 0, {ACT_FAILINIT}},
+{RSP_ERROR,	102, 102, -1,			107,  5, {0},	"^GETPRE\r"},
+{RSP_OK,	107, 107, -1,			  0,  0, {ACT_CONFIGMODE} },
+{RSP_ERROR,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
+{EV_TIMEOUT,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
 
-	{RSP_STRING,  120,120, -1,                121,-1, {ACT_SETVER}},
+{RSP_ERROR,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
+{EV_TIMEOUT,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
 
-	{EV_TIMEOUT,  120,121, -1,                  0, 0, {ACT_FAILVER, ACT_INIT}},
-	{RSP_ERROR,   120,121, -1,                  0, 0, {ACT_FAILVER, ACT_INIT}},
-	{RSP_OK,      121,121, -1,                  0, 0, {ACT_GOTVER,  ACT_INIT}},
+{RSP_STRING,	120, 120, -1,			121, -1, {ACT_SETVER} },
 
-	/* leave dle mode */
-	{RSP_INIT,      0,  0,SEQ_DLE0,           201, 5, {0},             "^SDLE=0\r"},
-	{RSP_OK,      201,201, -1,                202,-1},
-	{RSP_ZDLE,    202,202,  0,                  0, 0, {ACT_DLE0}},
-	{RSP_NODEV,   200,249, -1,                  0, 0, {ACT_FAKEDLE0}},
-	{RSP_ERROR,   200,249, -1,                  0, 0, {ACT_FAILDLE0}},
-	{EV_TIMEOUT,  200,249, -1,                  0, 0, {ACT_FAILDLE0}},
+{EV_TIMEOUT,	120, 121, -1,			  0,  0, {ACT_FAILVER,
+							  ACT_INIT} },
+{RSP_ERROR,	120, 121, -1,			  0,  0, {ACT_FAILVER,
+							  ACT_INIT} },
+{RSP_OK,	121, 121, -1,			  0,  0, {ACT_GOTVER,
+							  ACT_INIT} },
 
-	/* enter dle mode */
-	{RSP_INIT,      0,  0,SEQ_DLE1,           251, 5, {0},             "^SDLE=1\r"},
-	{RSP_OK,      251,251, -1,                252,-1},
-	{RSP_ZDLE,    252,252,  1,                  0, 0, {ACT_DLE1}},
-	{RSP_ERROR,   250,299, -1,                  0, 0, {ACT_FAILDLE1}},
-	{EV_TIMEOUT,  250,299, -1,                  0, 0, {ACT_FAILDLE1}},
+/* leave dle mode */
+{RSP_INIT,	  0,   0, SEQ_DLE0,		201,  5, {0},	"^SDLE=0\r"},
+{RSP_OK,	201, 201, -1,			202, -1},
+{RSP_ZDLE,	202, 202,  0,			  0,  0, {ACT_DLE0} },
+{RSP_NODEV,	200, 249, -1,			  0,  0, {ACT_FAKEDLE0} },
+{RSP_ERROR,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
+{EV_TIMEOUT,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
 
-	/* incoming call */
-	{RSP_RING,     -1, -1, -1,                 -1,-1, {ACT_RING}},
+/* enter dle mode */
+{RSP_INIT,	  0,   0, SEQ_DLE1,		251,  5, {0},	"^SDLE=1\r"},
+{RSP_OK,	251, 251, -1,			252, -1},
+{RSP_ZDLE,	252, 252,  1,			  0,  0, {ACT_DLE1} },
+{RSP_ERROR,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
+{EV_TIMEOUT,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
 
-	/* get cid */
-	//{RSP_INIT,      0,  0,300,                901, 0, {ACT_TEST}},
-	//{RSP_ERROR,   901,901, -1,                  0, 0, {ACT_FAILCID}},
-	//{RSP_OK,      901,901, -1,                301, 5, {0},             "^SGCI?\r"},
+/* incoming call */
+{RSP_RING,	 -1,  -1, -1,			 -1, -1, {ACT_RING} },
 
-	{RSP_INIT,      0,  0,SEQ_CID,            301, 5, {0},             "^SGCI?\r"},
-	{RSP_OK,      301,301, -1,                302,-1},
-	{RSP_ZGCI,    302,302, -1,                  0, 0, {ACT_CID}},
-	{RSP_ERROR,   301,349, -1,                  0, 0, {ACT_FAILCID}},
-	{EV_TIMEOUT,  301,349, -1,                  0, 0, {ACT_FAILCID}},
+/* get cid */
+{RSP_INIT,	  0,   0, SEQ_CID,		301,  5, {0},	"^SGCI?\r"},
+{RSP_OK,	301, 301, -1,			302, -1},
+{RSP_ZGCI,	302, 302, -1,			  0,  0, {ACT_CID} },
+{RSP_ERROR,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
+{EV_TIMEOUT,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
 
-	/* enter cid mode */
-	{RSP_INIT,      0,  0,SEQ_CIDMODE,        150, 5, {0},             "^SGCI=1\r"},
-	{RSP_OK,      150,150, -1,                  0, 0, {ACT_CMODESET}},
-	{RSP_ERROR,   150,150, -1,                  0, 0, {ACT_FAILCMODE}},
-	{EV_TIMEOUT,  150,150, -1,                  0, 0, {ACT_FAILCMODE}},
+/* enter cid mode */
+{RSP_INIT,	  0,   0, SEQ_CIDMODE,		150,  5, {0},	"^SGCI=1\r"},
+{RSP_OK,	150, 150, -1,			  0,  0, {ACT_CMODESET} },
+{RSP_ERROR,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
+{EV_TIMEOUT,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
 
-	/* leave cid mode */
-	//{RSP_INIT,      0,  0,SEQ_UMMODE,         160, 5, {0},             "^SGCI=0\r"},
-	{RSP_INIT,      0,  0,SEQ_UMMODE,         160, 5, {0},             "Z\r"},
-	{RSP_OK,      160,160, -1,                  0, 0, {ACT_UMODESET}},
-	{RSP_ERROR,   160,160, -1,                  0, 0, {ACT_FAILUMODE}},
-	{EV_TIMEOUT,  160,160, -1,                  0, 0, {ACT_FAILUMODE}},
+/* leave cid mode */
+{RSP_INIT,	  0,   0, SEQ_UMMODE,		160,  5, {0},	"Z\r"},
+{RSP_OK,	160, 160, -1,			  0,  0, {ACT_UMODESET} },
+{RSP_ERROR,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
+{EV_TIMEOUT,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
 
-	/* abort getting cid */
-	{RSP_INIT,      0,  0,SEQ_NOCID,            0, 0, {ACT_ABORTCID}},
+/* abort getting cid */
+{RSP_INIT,	  0,   0, SEQ_NOCID,		  0,  0, {ACT_ABORTCID} },
 
-	/* reset */
-	{RSP_INIT,      0,  0,SEQ_SHUTDOWN,       504, 5, {0},             "Z\r"},
-	{RSP_OK,      504,504, -1,                  0, 0, {ACT_SDOWN}},
-	{RSP_ERROR,   501,599, -1,                  0, 0, {ACT_FAILSDOWN}},
-	{EV_TIMEOUT,  501,599, -1,                  0, 0, {ACT_FAILSDOWN}},
-	{RSP_NODEV,   501,599, -1,                  0, 0, {ACT_FAKESDOWN}},
+/* reset */
+{RSP_INIT,	  0,   0, SEQ_SHUTDOWN,		504,  5, {0},	"Z\r"},
+{RSP_OK,	504, 504, -1,			  0,  0, {ACT_SDOWN} },
+{RSP_ERROR,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
+{EV_TIMEOUT,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
+{RSP_NODEV,	501, 599, -1,			  0,  0, {ACT_FAKESDOWN} },
 
-	{EV_PROC_CIDMODE,-1, -1, -1,               -1,-1, {ACT_PROC_CIDMODE}}, //FIXME
-	{EV_IF_LOCK,   -1, -1, -1,                 -1,-1, {ACT_IF_LOCK}}, //FIXME
-	{EV_IF_VER,    -1, -1, -1,                 -1,-1, {ACT_IF_VER}}, //FIXME
-	{EV_START,     -1, -1, -1,                 -1,-1, {ACT_START}}, //FIXME
-	{EV_STOP,      -1, -1, -1,                 -1,-1, {ACT_STOP}}, //FIXME
-	{EV_SHUTDOWN,  -1, -1, -1,                 -1,-1, {ACT_SHUTDOWN}}, //FIXME
+{EV_PROC_CIDMODE, -1, -1, -1,			 -1, -1, {ACT_PROC_CIDMODE} },
+{EV_IF_LOCK,	 -1,  -1, -1,			 -1, -1, {ACT_IF_LOCK} },
+{EV_IF_VER,	 -1,  -1, -1,			 -1, -1, {ACT_IF_VER} },
+{EV_START,	 -1,  -1, -1,			 -1, -1, {ACT_START} },
+{EV_STOP,	 -1,  -1, -1,			 -1, -1, {ACT_STOP} },
+{EV_SHUTDOWN,	 -1,  -1, -1,			 -1, -1, {ACT_SHUTDOWN} },
 
-	/* misc. */
-	{RSP_ERROR,    -1, -1, -1,                 -1, -1, {ACT_ERROR} },
-	{RSP_EMPTY,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZCFGT,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZCFG,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZLOG,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZMWI,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZABINFO,  -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZSMLSTCHG,-1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
+/* misc. */
+{RSP_ERROR,	 -1,  -1, -1,			 -1, -1, {ACT_ERROR} },
+{RSP_ZCFGT,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZCFG,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZLOG,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZMWI,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZABINFO,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZSMLSTCHG,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
 
-	{RSP_ZCAU,     -1, -1, -1,                 -1,-1, {ACT_ZCAU}},
-	{RSP_NONE,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ANY,      -1, -1, -1,                 -1,-1, {ACT_WARN}},
-	{RSP_LAST}
+{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
+{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
+{RSP_LAST}
 };
 
-// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall
+/* 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring,
+ * 400: hup, 750: accepted icall */
 struct reply_t gigaset_tab_cid[] =
 {
-	/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
-
-	/* dial */
-	{EV_DIAL,      -1, -1, -1,                 -1,-1, {ACT_DIAL}}, //FIXME
-	{RSP_INIT,      0,  0,SEQ_DIAL,           601, 5, {ACT_CMD+AT_BC}},
-	{RSP_OK,      601,601, -1,                602, 5, {ACT_CMD+AT_HLC}},
-	{RSP_NULL,    602,602, -1,                603, 5, {ACT_CMD+AT_PROTO}},
-	{RSP_OK,      602,602, -1,                603, 5, {ACT_CMD+AT_PROTO}},
-	{RSP_OK,      603,603, -1,                604, 5, {ACT_CMD+AT_TYPE}},
-	{RSP_OK,      604,604, -1,                605, 5, {ACT_CMD+AT_MSN}},
-	{RSP_OK,      605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
-	{RSP_NULL,    605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
-	{RSP_OK,      606,606, -1,                607, 5, {0}, "+VLS=17\r"},
-	{RSP_OK,      607,607, -1,                608,-1},
-	{RSP_ZSAU,    608,608,ZSAU_PROCEEDING,    609, 5, {ACT_CMD+AT_DIAL}},
-	{RSP_OK,      609,609, -1,                650, 0, {ACT_DIALING}},
+/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
+ * action, command */
 
-	{RSP_ERROR,   601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
-	{EV_TIMEOUT,  601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
+/* dial */
+{EV_DIAL,	 -1,  -1, -1,			 -1, -1, {ACT_DIAL} },
+{RSP_INIT,	  0,   0, SEQ_DIAL,		601,  5, {ACT_CMD+AT_BC} },
+{RSP_OK,	601, 601, -1,			602,  5, {ACT_CMD+AT_HLC} },
+{RSP_NULL,	602, 602, -1,			603,  5, {ACT_CMD+AT_PROTO} },
+{RSP_OK,	602, 602, -1,			603,  5, {ACT_CMD+AT_PROTO} },
+{RSP_OK,	603, 603, -1,			604,  5, {ACT_CMD+AT_TYPE} },
+{RSP_OK,	604, 604, -1,			605,  5, {ACT_CMD+AT_MSN} },
+{RSP_NULL,	605, 605, -1,			606,  5, {ACT_CMD+AT_CLIP} },
+{RSP_OK,	605, 605, -1,			606,  5, {ACT_CMD+AT_CLIP} },
+{RSP_NULL,	606, 606, -1,			607,  5, {ACT_CMD+AT_ISO} },
+{RSP_OK,	606, 606, -1,			607,  5, {ACT_CMD+AT_ISO} },
+{RSP_OK,	607, 607, -1,			608,  5, {0},	"+VLS=17\r"},
+{RSP_OK,	608, 608, -1,			609, -1},
+{RSP_ZSAU,	609, 609, ZSAU_PROCEEDING,	610,  5, {ACT_CMD+AT_DIAL} },
+{RSP_OK,	610, 610, -1,			650,  0, {ACT_DIALING} },
 
-	/* optional dialing responses */
-	{EV_BC_OPEN,  650,650, -1,                651,-1},
-	{RSP_ZVLS,    608,651, 17,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZCTP,    609,651, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZCPN,    609,651, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZSAU,    650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
+{RSP_ERROR,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
+{EV_TIMEOUT,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
 
-	/* connect */
-	{RSP_ZSAU,    650,650,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}},
-	{RSP_ZSAU,    651,651,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT,
-							   ACT_NOTIFY_BC_UP}},
-	{RSP_ZSAU,    750,750,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}},
-	{RSP_ZSAU,    751,751,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT,
-							   ACT_NOTIFY_BC_UP}},
-	{EV_BC_OPEN,  800,800, -1,                800,-1, {ACT_NOTIFY_BC_UP}},
+/* optional dialing responses */
+{EV_BC_OPEN,	650, 650, -1,			651, -1},
+{RSP_ZVLS,	609, 651, 17,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZCTP,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZCPN,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZSAU,	650, 651, ZSAU_CALL_DELIVERED,	 -1, -1, {ACT_DEBUG} },
 
-	/* remote hangup */
-	{RSP_ZSAU,    650,651,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEREJECT}},
-	{RSP_ZSAU,    750,751,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
-	{RSP_ZSAU,    800,800,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
+/* connect */
+{RSP_ZSAU,	650, 650, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
+{RSP_ZSAU,	651, 651, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
+							  ACT_NOTIFY_BC_UP} },
+{RSP_ZSAU,	750, 750, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
+{RSP_ZSAU,	751, 751, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
+							  ACT_NOTIFY_BC_UP} },
+{EV_BC_OPEN,	800, 800, -1,			800, -1, {ACT_NOTIFY_BC_UP} },
 
-	/* hangup */
-	{EV_HUP,       -1, -1, -1,                 -1,-1, {ACT_HUP}}, //FIXME
-	{RSP_INIT,     -1, -1,SEQ_HUP,            401, 5, {0},             "+VLS=0\r"}, /* hang up */ //-1,-1?
-	{RSP_OK,      401,401, -1,                402, 5},
-	{RSP_ZVLS,    402,402,  0,                403, 5},
-	{RSP_ZSAU,    403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
-	{RSP_ZSAU,    403, 403, ZSAU_NULL,            0,  0, {ACT_DISCONNECT} },
-	{RSP_NODEV,   401, 403, -1,                   0,  0, {ACT_FAKEHUP} },
-	{RSP_ERROR,   401,401, -1,                  0, 0, {ACT_ABORTHUP}},
-	{EV_TIMEOUT,  401,403, -1,                  0, 0, {ACT_ABORTHUP}},
+/* remote hangup */
+{RSP_ZSAU,	650, 651, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEREJECT} },
+{RSP_ZSAU,	750, 751, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
+{RSP_ZSAU,	800, 800, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
 
-	{EV_BC_CLOSED,  0,  0, -1,                  0,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME new constate + timeout
+/* hangup */
+{EV_HUP,	 -1,  -1, -1,			 -1, -1, {ACT_HUP} },
+{RSP_INIT,	 -1,  -1, SEQ_HUP,		401,  5, {0},	"+VLS=0\r"},
+{RSP_OK,	401, 401, -1,			402,  5},
+{RSP_ZVLS,	402, 402,  0,			403,  5},
+{RSP_ZSAU,	403, 403, ZSAU_DISCONNECT_REQ,	 -1, -1, {ACT_DEBUG} },
+{RSP_ZSAU,	403, 403, ZSAU_NULL,		  0,  0, {ACT_DISCONNECT} },
+{RSP_NODEV,	401, 403, -1,			  0,  0, {ACT_FAKEHUP} },
+{RSP_ERROR,	401, 401, -1,			  0,  0, {ACT_ABORTHUP} },
+{EV_TIMEOUT,	401, 403, -1,			  0,  0, {ACT_ABORTHUP} },
 
-	/* ring */
-	{RSP_ZBC,     700,700, -1,                 -1,-1, {0}},
-	{RSP_ZHLC,    700,700, -1,                 -1,-1, {0}},
-	{RSP_NMBR,    700,700, -1,                 -1,-1, {0}},
-	{RSP_ZCPN,    700,700, -1,                 -1,-1, {0}},
-	{RSP_ZCTP,    700,700, -1,                 -1,-1, {0}},
-	{EV_TIMEOUT,  700,700, -1,               720,720, {ACT_ICALL}},
-	{EV_BC_CLOSED,720,720, -1,                  0,-1, {ACT_NOTIFY_BC_DOWN}},
+{EV_BC_CLOSED,	  0,   0, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
 
-	/*accept icall*/
-	{EV_ACCEPT,    -1, -1, -1,                 -1,-1, {ACT_ACCEPT}}, //FIXME
-	{RSP_INIT,    720,720,SEQ_ACCEPT,         721, 5, {ACT_CMD+AT_PROTO}},
-	{RSP_OK,      721,721, -1,                722, 5, {ACT_CMD+AT_ISO}},
-	{RSP_OK,      722,722, -1,                723, 5, {0},             "+VLS=17\r"}, /* set "Endgeraetemodus" */
-	{RSP_OK,      723,723, -1,                724, 5, {0}},
-	{RSP_ZVLS,    724,724, 17,                750,50, {ACT_ACCEPTED}},
-	{RSP_ERROR,   721,729, -1,                  0, 0, {ACT_ABORTACCEPT}},
-	{EV_TIMEOUT,  721,729, -1,                  0, 0, {ACT_ABORTACCEPT}},
-	{RSP_ZSAU,    700,729,ZSAU_NULL,            0, 0, {ACT_ABORTACCEPT}},
-	{RSP_ZSAU,    700,729,ZSAU_ACTIVE,          0, 0, {ACT_ABORTACCEPT}},
-	{RSP_ZSAU,    700,729,ZSAU_DISCONNECT_IND,  0, 0, {ACT_ABORTACCEPT}},
+/* ring */
+{RSP_ZBC,	700, 700, -1,			 -1, -1, {0} },
+{RSP_ZHLC,	700, 700, -1,			 -1, -1, {0} },
+{RSP_NMBR,	700, 700, -1,			 -1, -1, {0} },
+{RSP_ZCPN,	700, 700, -1,			 -1, -1, {0} },
+{RSP_ZCTP,	700, 700, -1,			 -1, -1, {0} },
+{EV_TIMEOUT,	700, 700, -1,			720, 720, {ACT_ICALL} },
+{EV_BC_CLOSED,	720, 720, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
 
-	{EV_BC_OPEN,  750,750, -1,                751,-1},
-	{EV_TIMEOUT,  750,751, -1,                  0, 0, {ACT_CONNTIMEOUT}},
+/*accept icall*/
+{EV_ACCEPT,	 -1,  -1, -1,			 -1, -1, {ACT_ACCEPT} },
+{RSP_INIT,	720, 720, SEQ_ACCEPT,		721,  5, {ACT_CMD+AT_PROTO} },
+{RSP_OK,	721, 721, -1,			722,  5, {ACT_CMD+AT_ISO} },
+{RSP_OK,	722, 722, -1,			723,  5, {0},	"+VLS=17\r"},
+{RSP_OK,	723, 723, -1,			724,  5, {0} },
+{RSP_ZVLS,	724, 724, 17,			750, 50, {ACT_ACCEPTED} },
+{RSP_ERROR,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
+{EV_TIMEOUT,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
+{RSP_ZSAU,	700, 729, ZSAU_NULL,		  0,  0, {ACT_ABORTACCEPT} },
+{RSP_ZSAU,	700, 729, ZSAU_ACTIVE,		  0,  0, {ACT_ABORTACCEPT} },
+{RSP_ZSAU,	700, 729, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_ABORTACCEPT} },
 
-	/* B channel closed (general case) */
-	{EV_BC_CLOSED, -1, -1, -1,                 -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
+{EV_BC_OPEN,	750, 750, -1,			751, -1},
+{EV_TIMEOUT,	750, 751, -1,			  0,  0, {ACT_CONNTIMEOUT} },
 
-	/* misc. */
-	{EV_PROTO_L2,  -1, -1, -1,                 -1,-1, {ACT_PROTO_L2}}, //FIXME
+/* B channel closed (general case) */
+{EV_BC_CLOSED,	 -1,  -1, -1,			 -1, -1, {ACT_NOTIFY_BC_DOWN} },
 
-	{RSP_ZCON,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZCCR,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZAOC,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
-	{RSP_ZCSTR,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
+/* misc. */
+{RSP_ZCON,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZCCR,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZAOC,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ZCSTR,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
 
-	{RSP_ZCAU,     -1, -1, -1,                 -1,-1, {ACT_ZCAU}},
-	{RSP_NONE,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ANY,      -1, -1, -1,                 -1,-1, {ACT_WARN}},
-	{RSP_LAST}
+{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
+{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
+{RSP_LAST}
 };
 
 
-static const struct resp_type_t resp_type[] =
+static const struct resp_type_t {
+	unsigned char	*response;
+	int		resp_code;
+	int		type;
+} resp_type[] =
 {
-	/*{"",		RSP_EMPTY,	RT_NOTHING},*/
 	{"OK",		RSP_OK,		RT_NOTHING},
 	{"ERROR",	RSP_ERROR,	RT_NOTHING},
 	{"ZSAU",	RSP_ZSAU,	RT_ZSAU},
@@ -405,7 +403,21 @@ static const struct resp_type_t resp_typ
 	{"ZLOG",	RSP_ZLOG,	RT_NOTHING},
 	{"ZABINFO",	RSP_ZABINFO,	RT_NOTHING},
 	{"ZSMLSTCHG",	RSP_ZSMLSTCHG,	RT_NOTHING},
-	{NULL,0,0}
+	{NULL,		0,		0}
+};
+
+static const struct zsau_resp_t {
+	unsigned char	*str;
+	int		code;
+} zsau_resp[] =
+{
+	{"OUTGOING_CALL_PROCEEDING",	ZSAU_OUTGOING_CALL_PROCEEDING},
+	{"CALL_DELIVERED",		ZSAU_CALL_DELIVERED},
+	{"ACTIVE",			ZSAU_ACTIVE},
+	{"DISCONNECT_IND",		ZSAU_DISCONNECT_IND},
+	{"NULL",			ZSAU_NULL},
+	{"DISCONNECT_REQ",		ZSAU_DISCONNECT_REQ},
+	{NULL,				ZSAU_UNKNOWN}
 };
 
 /*
@@ -470,7 +482,6 @@ static int cid_of_response(char *s)
 	if (cid < 1 || cid > 65535)
 		return -1;	/* CID out of range */
 	return cid;
-	//FIXME is ;<digit>+ at end of non-CID response really impossible?
 }
 
 /**
@@ -487,6 +498,7 @@ void gigaset_handle_modem_response(struc
 	int params;
 	int i, j;
 	const struct resp_type_t *rt;
+	const struct zsau_resp_t *zr;
 	int curarg;
 	unsigned long flags;
 	unsigned next, tail, head;
@@ -613,24 +625,14 @@ void gigaset_handle_modem_response(struc
 				event->parameter = ZSAU_NONE;
 				break;
 			}
-			if (!strcmp(argv[curarg], "OUTGOING_CALL_PROCEEDING"))
-				event->parameter = ZSAU_OUTGOING_CALL_PROCEEDING;
-			else if (!strcmp(argv[curarg], "CALL_DELIVERED"))
-				event->parameter = ZSAU_CALL_DELIVERED;
-			else if (!strcmp(argv[curarg], "ACTIVE"))
-				event->parameter = ZSAU_ACTIVE;
-			else if (!strcmp(argv[curarg], "DISCONNECT_IND"))
-				event->parameter = ZSAU_DISCONNECT_IND;
-			else if (!strcmp(argv[curarg], "NULL"))
-				event->parameter = ZSAU_NULL;
-			else if (!strcmp(argv[curarg], "DISCONNECT_REQ"))
-				event->parameter = ZSAU_DISCONNECT_REQ;
-			else {
-				event->parameter = ZSAU_UNKNOWN;
+			for (zr = zsau_resp; zr->str; ++zr)
+				if (!strcmp(argv[curarg], zr->str))
+					break;
+			event->parameter = zr->code;
+			if (!zr->str)
 				dev_warn(cs->dev,
 					"%s: unknown parameter %s after ZSAU\n",
 					 __func__, argv[curarg]);
-			}
 			++curarg;
 			break;
 		case RT_STRING:
@@ -714,7 +716,7 @@ static void disconnect(struct at_state_t
 		/* notify LL */
 		if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
 			bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
-			gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
+			gigaset_isdn_hupD(bcs);
 		}
 	} else {
 		/* no B channel assigned: just deallocate */
@@ -872,12 +874,12 @@ static void bchannel_down(struct bc_stat
 {
 	if (bcs->chstate & CHS_B_UP) {
 		bcs->chstate &= ~CHS_B_UP;
-		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
+		gigaset_isdn_hupB(bcs);
 	}
 
 	if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
 		bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
-		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
+		gigaset_isdn_hupD(bcs);
 	}
 
 	gigaset_free_channel(bcs);
@@ -894,15 +896,17 @@ static void bchannel_up(struct bc_state
 	}
 
 	bcs->chstate |= CHS_B_UP;
-	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
+	gigaset_isdn_connB(bcs);
 }
 
-static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index)
+static void start_dial(struct at_state_t *at_state, void *data,
+			unsigned seq_index)
 {
 	struct bc_state *bcs = at_state->bcs;
 	struct cardstate *cs = at_state->cs;
-	int retval;
+	char **commands = data;
 	unsigned long flags;
+	int i;
 
 	bcs->chstate |= CHS_NOTIFY_LL;
 
@@ -913,10 +917,10 @@ static void start_dial(struct at_state_t
 	}
 	spin_unlock_irqrestore(&cs->lock, flags);
 
-	retval = gigaset_isdn_setup_dial(at_state, data);
-	if (retval != 0)
-		goto error;
-
+	for (i = 0; i < AT_NUM; ++i) {
+		kfree(bcs->commands[i]);
+		bcs->commands[i] = commands[i];
+	}
 
 	at_state->pending_commands |= PC_CID;
 	gig_dbg(DEBUG_CMD, "Scheduling PC_CID");
@@ -924,6 +928,10 @@ static void start_dial(struct at_state_t
 	return;
 
 error:
+	for (i = 0; i < AT_NUM; ++i) {
+		kfree(commands[i]);
+		commands[i] = NULL;
+	}
 	at_state->pending_commands |= PC_NOCID;
 	gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID");
 	cs->commands_pending = 1;
@@ -933,20 +941,31 @@ error:
 static void start_accept(struct at_state_t *at_state)
 {
 	struct cardstate *cs = at_state->cs;
-	int retval;
+	struct bc_state *bcs = at_state->bcs;
+	int i;
 
-	retval = gigaset_isdn_setup_accept(at_state);
+	for (i = 0; i < AT_NUM; ++i) {
+		kfree(bcs->commands[i]);
+		bcs->commands[i] = NULL;
+	}
 
-	if (retval == 0) {
-		at_state->pending_commands |= PC_ACCEPT;
-		gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
-		cs->commands_pending = 1;
-	} else {
+	bcs->commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
+	bcs->commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
+	if (!bcs->commands[AT_PROTO] || !bcs->commands[AT_ISO]) {
+		dev_err(at_state->cs->dev, "out of memory\n");
 		/* error reset */
 		at_state->pending_commands |= PC_HUP;
 		gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
 		cs->commands_pending = 1;
+		return;
 	}
+
+	snprintf(bcs->commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
+	snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);
+
+	at_state->pending_commands |= PC_ACCEPT;
+	gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
+	cs->commands_pending = 1;
 }
 
 static void do_start(struct cardstate *cs)
@@ -957,9 +976,7 @@ static void do_start(struct cardstate *c
 		schedule_init(cs, MS_INIT);
 
 	cs->isdn_up = 1;
-	gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
-					// FIXME: not in locked mode
-					// FIXME 2: only after init sequence
+	gigaset_isdn_start(cs);
 
 	cs->waiting = 0;
 	wake_up(&cs->waitqueue);
@@ -975,7 +992,7 @@ static void finish_shutdown(struct cards
 	/* Tell the LL that the device is not available .. */
 	if (cs->isdn_up) {
 		cs->isdn_up = 0;
-		gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
+		gigaset_isdn_stop(cs);
 	}
 
 	/* The rest is done by cleanup_cs () in user mode. */
@@ -1113,7 +1130,6 @@ static int do_lock(struct cardstate *cs)
 
 		break;
 	case MS_LOCKED:
-		//retval = -EACCES;
 		break;
 	default:
 		return -EBUSY;
@@ -1276,7 +1292,7 @@ static void do_action(int action, struct
 			break;
 		}
 		bcs->chstate |= CHS_D_UP;
-		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
+		gigaset_isdn_connD(bcs);
 		cs->ops->init_bchannel(bcs);
 		break;
 	case ACT_DLE1:
@@ -1284,7 +1300,7 @@ static void do_action(int action, struct
 		bcs = cs->bcs + cs->curchannel;
 
 		bcs->chstate |= CHS_D_UP;
-		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
+		gigaset_isdn_connD(bcs);
 		cs->ops->init_bchannel(bcs);
 		break;
 	case ACT_FAKEHUP:
@@ -1369,7 +1385,7 @@ static void do_action(int action, struct
 		cs->cur_at_seq = SEQ_NONE;
 		break;
 
-	case ACT_ABORTACCEPT:	/* hangup/error/timeout during ICALL processing */
+	case ACT_ABORTACCEPT:	/* hangup/error/timeout during ICALL procssng */
 		disconnect(p_at_state);
 		break;
 
@@ -1443,17 +1459,6 @@ static void do_action(int action, struct
 			__func__, at_state->ConState);
 		cs->cur_at_seq = SEQ_NONE;
 		break;
-#ifdef CONFIG_GIGASET_DEBUG
-	case ACT_TEST:
-		{
-			static int count = 3; //2; //1;
-			*p_genresp = 1;
-			*p_resp_code = count ? RSP_ERROR : RSP_OK;
-			if (count > 0)
-				--count;
-		}
-		break;
-#endif
 	case ACT_DEBUG:
 		gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d",
 			__func__, ev->type, at_state->ConState);
@@ -1474,11 +1479,6 @@ static void do_action(int action, struct
 	case ACT_ACCEPT:
 		start_accept(at_state);
 		break;
-	case ACT_PROTO_L2:
-		gig_dbg(DEBUG_CMD, "set protocol to %u",
-			(unsigned) ev->parameter);
-		at_state->bcs->proto2 = ev->parameter;
-		break;
 	case ACT_HUP:
 		at_state->pending_commands |= PC_HUP;
 		cs->commands_pending = 1;
@@ -1493,7 +1493,7 @@ static void do_action(int action, struct
 		do_start(cs);
 		break;
 
-	/* events from the interface */ // FIXME without ACT_xxxx?
+	/* events from the interface */
 	case ACT_IF_LOCK:
 		cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs);
 		cs->waiting = 0;
@@ -1512,7 +1512,7 @@ static void do_action(int action, struct
 		wake_up(&cs->waitqueue);
 		break;
 
-	/* events from the proc file system */ // FIXME without ACT_xxxx?
+	/* events from the proc file system */
 	case ACT_PROC_CIDMODE:
 		spin_lock_irqsave(&cs->lock, flags);
 		if (ev->parameter != cs->cidmode) {
@@ -1649,7 +1649,8 @@ static void process_event(struct cardsta
 	for (curact = 0; curact < MAXACT; ++curact) {
 		/* The row tells us what we should do  ..
 		 */
-		do_action(rep->action[curact], cs, bcs, &at_state, &p_command, &genresp, &resp_code, ev);
+		do_action(rep->action[curact], cs, bcs, &at_state, &p_command,
+			  &genresp, &resp_code, ev);
 		if (!at_state)
 			break; /* may be freed after disconnect */
 	}
@@ -1661,13 +1662,14 @@ static void process_event(struct cardsta
 
 		if (genresp) {
 			spin_lock_irqsave(&cs->lock, flags);
-			at_state->timer_expires = 0; //FIXME
-			at_state->timer_active = 0; //FIXME
+			at_state->timer_expires = 0;
+			at_state->timer_active = 0;
 			spin_unlock_irqrestore(&cs->lock, flags);
-			gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL);
+			gigaset_add_event(cs, at_state, resp_code,
+					  NULL, 0, NULL);
 		} else {
 			/* Send command to modem if not NULL... */
-			if (p_command/*rep->command*/) {
+			if (p_command) {
 				if (cs->connected)
 					send_command(cs, p_command,
 						     sendcid, cs->dle,
@@ -1754,7 +1756,8 @@ static void process_command_flags(struct
 		}
 	}
 
-	/* only switch back to unimodem mode, if no commands are pending and no channels are up */
+	/* only switch back to unimodem mode if no commands are pending and
+	 * no channels are up */
 	spin_lock_irqsave(&cs->lock, flags);
 	if (cs->at_state.pending_commands == PC_UMMODE
 	    && !cs->cidmode
@@ -1813,9 +1816,8 @@ static void process_command_flags(struct
 
 	if (cs->at_state.pending_commands & PC_INIT) {
 		cs->at_state.pending_commands &= ~PC_INIT;
-		cs->dle = 0; //FIXME
+		cs->dle = 0;
 		cs->inbuf->inputstate = INS_command;
-		//FIXME reset card state (or -> LOCK0)?
 		schedule_sequence(cs, &cs->at_state, SEQ_INIT);
 		return;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/gigaset.h linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/gigaset.h
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/gigaset.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/gigaset.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/isdnif.h>
 #include <linux/usb.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
@@ -35,12 +34,11 @@
 #include <linux/list.h>
 #include <asm/atomic.h>
 
-#define GIG_VERSION {0,5,0,0}
-#define GIG_COMPAT  {0,4,0,0}
+#define GIG_VERSION {0, 5, 0, 0}
+#define GIG_COMPAT  {0, 4, 0, 0}
 
 #define MAX_REC_PARAMS 10	/* Max. number of params in response string */
 #define MAX_RESP_SIZE 512	/* Max. size of a response string */
-#define HW_HDR_LEN 2		/* Header size used to store ack info */
 
 #define MAX_EVENTS 64		/* size of event queue */
 
@@ -135,35 +133,32 @@ void gigaset_dbg_buffer(enum debuglevel
 #define OUT_VENDOR_REQ	(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
 #define IN_VENDOR_REQ	(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
 
-/* int-in-events 3070 */
+/* interrupt pipe messages */
 #define HD_B1_FLOW_CONTROL		0x80
 #define HD_B2_FLOW_CONTROL		0x81
-#define HD_RECEIVEATDATA_ACK		(0x35)		// 3070
-						// att: HD_RECEIVE>>AT<<DATA_ACK
-#define HD_READY_SEND_ATDATA		(0x36)		// 3070
-#define HD_OPEN_ATCHANNEL_ACK		(0x37)		// 3070
-#define HD_CLOSE_ATCHANNEL_ACK		(0x38)		// 3070
-#define HD_DEVICE_INIT_OK		(0x11)		// ISurf USB + 3070
-#define HD_OPEN_B1CHANNEL_ACK		(0x51)		// ISurf USB + 3070
-#define HD_OPEN_B2CHANNEL_ACK		(0x52)		// ISurf USB + 3070
-#define HD_CLOSE_B1CHANNEL_ACK		(0x53)		// ISurf USB + 3070
-#define HD_CLOSE_B2CHANNEL_ACK		(0x54)		// ISurf USB + 3070
-// 	 Powermangment
-#define HD_SUSPEND_END			(0x61)		// ISurf USB
-//   Configuration
-#define HD_RESET_INTERRUPT_PIPE_ACK	(0xFF)		// ISurf USB + 3070
+#define HD_RECEIVEATDATA_ACK		(0x35)		/* 3070 */
+#define HD_READY_SEND_ATDATA		(0x36)		/* 3070 */
+#define HD_OPEN_ATCHANNEL_ACK		(0x37)		/* 3070 */
+#define HD_CLOSE_ATCHANNEL_ACK		(0x38)		/* 3070 */
+#define HD_DEVICE_INIT_OK		(0x11)		/* ISurf USB + 3070 */
+#define HD_OPEN_B1CHANNEL_ACK		(0x51)		/* ISurf USB + 3070 */
+#define HD_OPEN_B2CHANNEL_ACK		(0x52)		/* ISurf USB + 3070 */
+#define HD_CLOSE_B1CHANNEL_ACK		(0x53)		/* ISurf USB + 3070 */
+#define HD_CLOSE_B2CHANNEL_ACK		(0x54)		/* ISurf USB + 3070 */
+#define HD_SUSPEND_END			(0x61)		/* ISurf USB */
+#define HD_RESET_INTERRUPT_PIPE_ACK	(0xFF)		/* ISurf USB + 3070 */
 
-/* control requests 3070 */
-#define	HD_OPEN_B1CHANNEL		(0x23)		// ISurf USB + 3070
-#define	HD_CLOSE_B1CHANNEL		(0x24)		// ISurf USB + 3070
-#define	HD_OPEN_B2CHANNEL		(0x25)		// ISurf USB + 3070
-#define	HD_CLOSE_B2CHANNEL		(0x26)		// ISurf USB + 3070
-#define HD_RESET_INTERRUPT_PIPE		(0x27)		// ISurf USB + 3070
-#define	HD_DEVICE_INIT_ACK		(0x34)		// ISurf USB + 3070
-#define	HD_WRITE_ATMESSAGE		(0x12)		// 3070
-#define	HD_READ_ATMESSAGE		(0x13)		// 3070
-#define	HD_OPEN_ATCHANNEL		(0x28)		// 3070
-#define	HD_CLOSE_ATCHANNEL		(0x29)		// 3070
+/* control requests */
+#define	HD_OPEN_B1CHANNEL		(0x23)		/* ISurf USB + 3070 */
+#define	HD_CLOSE_B1CHANNEL		(0x24)		/* ISurf USB + 3070 */
+#define	HD_OPEN_B2CHANNEL		(0x25)		/* ISurf USB + 3070 */
+#define	HD_CLOSE_B2CHANNEL		(0x26)		/* ISurf USB + 3070 */
+#define HD_RESET_INTERRUPT_PIPE		(0x27)		/* ISurf USB + 3070 */
+#define	HD_DEVICE_INIT_ACK		(0x34)		/* ISurf USB + 3070 */
+#define	HD_WRITE_ATMESSAGE		(0x12)		/* 3070 */
+#define	HD_READ_ATMESSAGE		(0x13)		/* 3070 */
+#define	HD_OPEN_ATCHANNEL		(0x28)		/* 3070 */
+#define	HD_CLOSE_ATCHANNEL		(0x29)		/* 3070 */
 
 /* number of B channels supported by base driver */
 #define BAS_CHANNELS	2
@@ -193,7 +188,9 @@ void gigaset_dbg_buffer(enum debuglevel
 #define AT_PROTO	4
 #define AT_TYPE		5
 #define AT_HLC		6
-#define AT_NUM		7
+#define AT_CLIP		7
+/* total number */
+#define AT_NUM		8
 
 /* variables in struct at_state_t */
 #define VAR_ZSAU	0
@@ -216,7 +213,6 @@ void gigaset_dbg_buffer(enum debuglevel
 #define EV_START	-110
 #define EV_STOP		-111
 #define EV_IF_LOCK	-112
-#define EV_PROTO_L2	-113
 #define EV_ACCEPT	-114
 #define EV_DIAL		-115
 #define EV_HUP		-116
@@ -224,12 +220,11 @@ void gigaset_dbg_buffer(enum debuglevel
 #define EV_BC_CLOSED	-118
 
 /* input state */
-#define INS_command	0x0001
-#define INS_DLE_char	0x0002
+#define INS_command	0x0001	/* receiving messages (not payload data) */
+#define INS_DLE_char	0x0002	/* DLE flag received (in DLE mode) */
 #define INS_byte_stuff	0x0004
 #define INS_have_data	0x0008
-#define INS_skip_frame	0x0010
-#define INS_DLE_command	0x0020
+#define INS_DLE_command	0x0020	/* DLE message start (<DLE> X) received */
 #define INS_flag_hunt	0x0040
 
 /* channel state */
@@ -259,6 +254,11 @@ void gigaset_dbg_buffer(enum debuglevel
 #define SM_LOCKED	0
 #define SM_ISDN		1 /* default */
 
+/* layer 2 protocols (AT^SBPR=...) */
+#define L2_BITSYNC	0
+#define L2_HDLC		1
+#define L2_VOICE	2
+
 struct gigaset_ops;
 struct gigaset_driver;
 
@@ -286,8 +286,6 @@ extern struct reply_t gigaset_tab_cid[];
 extern struct reply_t gigaset_tab_nocid[];
 
 struct inbuf_t {
-	unsigned char		*rcvbuf;	/* usb-gigaset receive buffer */
-	struct bc_state		*bcs;
 	struct cardstate	*cs;
 	int			inputstate;
 	int			head, tail;
@@ -359,12 +357,6 @@ struct at_state_t {
 	struct bc_state		*bcs;
 };
 
-struct resp_type_t {
-	unsigned char	*response;
-	int		resp_code;	/* RSP_XXXX */
-	int		type;		/* RT_XXXX */
-};
-
 struct event_t {
 	int type;
 	void *ptr, *arg;
@@ -395,7 +387,7 @@ struct bc_state {
 
 	unsigned chstate;		/* bitmap (CHS_*) */
 	int ignore;
-	unsigned proto2;		/* Layer 2 protocol (ISDN_PROTO_L2_*) */
+	unsigned proto2;		/* layer 2 protocol (L2_*) */
 	char *commands[AT_NUM];		/* see AT_XXXX */
 
 #ifdef CONFIG_GIGASET_DEBUG
@@ -410,6 +402,8 @@ struct bc_state {
 		struct usb_bc_state *usb;	/* usb hardware driver (m105) */
 		struct bas_bc_state *bas;	/* usb hardware driver (base) */
 	} hw;
+
+	void *ap;			/* LL application structure */
 };
 
 struct cardstate {
@@ -456,12 +450,13 @@ struct cardstate {
 
 	unsigned running;		/* !=0 if events are handled */
 	unsigned connected;		/* !=0 if hardware is connected */
-	unsigned isdn_up;		/* !=0 after ISDN_STAT_RUN */
+	unsigned isdn_up;		/* !=0 after gigaset_isdn_start() */
 
 	unsigned cidmode;
 
 	int myid;			/* id for communication with LL */
-	isdn_if iif;
+	void *iif;			/* LL interface structure */
+	unsigned short hw_hdr_len;	/* headroom needed in data skbs */
 
 	struct reply_t *tabnocid;
 	struct reply_t *tabcid;
@@ -476,8 +471,8 @@ struct cardstate {
 
 	struct timer_list timer;
 	int retry_count;
-	int dle;			/* !=0 if modem commands/responses are
-					   dle encoded */
+	int dle;			/* !=0 if DLE mode is active
+					   (ZDLE=1 received -- M10x only) */
 	int cur_at_seq;			/* sequence of AT commands being
 					   processed */
 	int curchannel;			/* channel those commands are meant
@@ -616,7 +611,9 @@ struct gigaset_ops {
 	int (*baud_rate)(struct cardstate *cs, unsigned cflag);
 	int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag);
 
-	/* Called from i4l.c to put an skb into the send-queue. */
+	/* Called from LL interface to put an skb into the send-queue.
+	 * After sending is completed, gigaset_skb_sent() must be called
+	 * with the skb's link layer header preserved. */
 	int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb);
 
 	/* Called from ev-layer.c to process a block of data
@@ -625,7 +622,8 @@ struct gigaset_ops {
 
 };
 
-/* = Common structures and definitions ======================================= */
+/* = Common structures and definitions =======================================
+ */
 
 /* Parser states for DLE-Event:
  * <DLE-EVENT>: <DLE_FLAG> "X" <EVENT> <DLE_FLAG> "."
@@ -638,8 +636,7 @@ struct gigaset_ops {
  *  Functions implemented in asyncdata.c
  */
 
-/* Called from i4l.c to put an skb into the send-queue.
- * After sending gigaset_skb_sent() should be called. */
+/* Called from LL interface to put an skb into the send queue. */
 int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb);
 
 /* Called from ev-layer.c to process a block of data
@@ -650,8 +647,7 @@ void gigaset_m10x_input(struct inbuf_t *
  *  Functions implemented in isocdata.c
  */
 
-/* Called from i4l.c to put an skb into the send-queue.
- * After sending gigaset_skb_sent() should be called. */
+/* Called from LL interface to put an skb into the send queue. */
 int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb);
 
 /* Called from ev-layer.c to process a block of data
@@ -674,36 +670,26 @@ void gigaset_isowbuf_init(struct isowbuf
 int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
 
 /* ===========================================================================
- *  Functions implemented in i4l.c/gigaset.h
+ *  Functions implemented in LL interface
  */
 
-/* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */
-int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid);
+/* Called from common.c for setting up/shutting down with the ISDN subsystem */
+int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
+void gigaset_isdn_unregister(struct cardstate *cs);
 
-/* Called from xxx-gigaset.c to indicate completion of sending an skb */
+/* Called from hardware module to indicate completion of an skb */
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
+void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb);
+void gigaset_isdn_rcv_err(struct bc_state *bcs);
 
 /* Called from common.c/ev-layer.c to indicate events relevant to the LL */
+void gigaset_isdn_start(struct cardstate *cs);
+void gigaset_isdn_stop(struct cardstate *cs);
 int gigaset_isdn_icall(struct at_state_t *at_state);
-int gigaset_isdn_setup_accept(struct at_state_t *at_state);
-int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data);
-
-void gigaset_i4l_cmd(struct cardstate *cs, int cmd);
-void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd);
-
-
-static inline void gigaset_isdn_rcv_err(struct bc_state *bcs)
-{
-	isdn_ctrl response;
-
-	/* error -> LL */
-	gig_dbg(DEBUG_CMD, "sending L1ERR");
-	response.driver = bcs->cs->myid;
-	response.command = ISDN_STAT_L1ERR;
-	response.arg = bcs->channel;
-	response.parm.errcode = ISDN_STAT_L1ERR_RECV;
-	bcs->cs->iif.statcallb(&response);
-}
+void gigaset_isdn_connD(struct bc_state *bcs);
+void gigaset_isdn_hupD(struct bc_state *bcs);
+void gigaset_isdn_connB(struct bc_state *bcs);
+void gigaset_isdn_hupB(struct bc_state *bcs);
 
 /* ===========================================================================
  *  Functions implemented in ev-layer.c
@@ -732,6 +718,7 @@ void gigaset_bcs_reinit(struct bc_state
 void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
 		     struct cardstate *cs, int cid);
 int gigaset_get_channel(struct bc_state *bcs);
+struct bc_state *gigaset_get_free_channel(struct cardstate *cs);
 void gigaset_free_channel(struct bc_state *bcs);
 int gigaset_get_channels(struct cardstate *cs);
 void gigaset_free_channels(struct cardstate *cs);
@@ -781,7 +768,7 @@ struct event_t *gigaset_add_event(struct
 				  void *ptr, int parameter, void *arg);
 
 /* Called on CONFIG1 command from frontend. */
-int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode
+int gigaset_enterconfigmode(struct cardstate *cs);
 
 /* cs->lock must not be locked */
 static inline void gigaset_schedule_event(struct cardstate *cs)
@@ -816,35 +803,6 @@ static inline void gigaset_bchannel_up(s
 /* handling routines for sk_buff */
 /* ============================= */
 
-/* pass received skb to LL
- * Warning: skb must not be accessed anymore!
- */
-static inline void gigaset_rcv_skb(struct sk_buff *skb,
-				   struct cardstate *cs,
-				   struct bc_state *bcs)
-{
-	cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb);
-	bcs->trans_down++;
-}
-
-/* handle reception of corrupted skb
- * Warning: skb must not be accessed anymore!
- */
-static inline void gigaset_rcv_error(struct sk_buff *procskb,
-				     struct cardstate *cs,
-				     struct bc_state *bcs)
-{
-	if (procskb)
-		dev_kfree_skb(procskb);
-
-	if (bcs->ignore)
-		--bcs->ignore;
-	else {
-		++bcs->corrupted;
-		gigaset_isdn_rcv_err(bcs);
-	}
-}
-
 /* append received bytes to inbuf */
 int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
 		       unsigned numbytes);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/i4l.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/i4l.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/i4l.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/i4l.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,9 @@
  */
 
 #include "gigaset.h"
+#include <linux/isdnif.h>
+
+#define HW_HDR_LEN	2	/* Header size used to store ack info */
 
 /* == Handling of I4L IO =====================================================*/
 
@@ -36,12 +39,12 @@
 static int writebuf_from_LL(int driverID, int channel, int ack,
 			    struct sk_buff *skb)
 {
-	struct cardstate *cs;
+	struct cardstate *cs = gigaset_get_cs_by_id(driverID);
 	struct bc_state *bcs;
+	unsigned char *ack_header;
 	unsigned len;
-	unsigned skblen;
 
-	if (!(cs = gigaset_get_cs_by_id(driverID))) {
+	if (!cs) {
 		pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
 		return -ENODEV;
 	}
@@ -75,11 +78,23 @@ static int writebuf_from_LL(int driverID
 		return -EINVAL;
 	}
 
-	skblen = ack ? len : 0;
-	skb->head[0] = skblen & 0xff;
-	skb->head[1] = skblen >> 8;
-	gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x",
-		len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
+	/* set up acknowledgement header */
+	if (skb_headroom(skb) < HW_HDR_LEN) {
+		/* should never happen */
+		dev_err(cs->dev, "%s: insufficient skb headroom\n", __func__);
+		return -ENOMEM;
+	}
+	skb_set_mac_header(skb, -HW_HDR_LEN);
+	skb->mac_len = HW_HDR_LEN;
+	ack_header = skb_mac_header(skb);
+	if (ack) {
+		ack_header[0] = len & 0xff;
+		ack_header[1] = len >> 8;
+	} else {
+		ack_header[0] = ack_header[1] = 0;
+	}
+	gig_dbg(DEBUG_MCMD, "skb: len=%u, ack=%d: %02x %02x",
+		len, ack, ack_header[0], ack_header[1]);
 
 	/* pass to device-specific module */
 	return cs->ops->send_skb(bcs, skb);
@@ -95,6 +110,8 @@ static int writebuf_from_LL(int driverID
  */
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
 {
+	isdn_if *iif = bcs->cs->iif;
+	unsigned char *ack_header = skb_mac_header(skb);
 	unsigned len;
 	isdn_ctrl response;
 
@@ -104,8 +121,7 @@ void gigaset_skb_sent(struct bc_state *b
 		dev_warn(bcs->cs->dev, "%s: skb->len==%d\n",
 			 __func__, skb->len);
 
-	len = (unsigned char) skb->head[0] |
-	      (unsigned) (unsigned char) skb->head[1] << 8;
+	len = ack_header[0] + ((unsigned) ack_header[1] << 8);
 	if (len) {
 		gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)",
 			bcs->cs->myid, bcs->channel, len);
@@ -114,71 +130,177 @@ void gigaset_skb_sent(struct bc_state *b
 		response.command = ISDN_STAT_BSENT;
 		response.arg = bcs->channel;
 		response.parm.length = len;
-		bcs->cs->iif.statcallb(&response);
+		iif->statcallb(&response);
 	}
 }
 EXPORT_SYMBOL_GPL(gigaset_skb_sent);
 
+/**
+ * gigaset_skb_rcvd() - pass received skb to LL
+ * @bcs:	B channel descriptor structure.
+ * @skb:	received data.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when user data has
+ * been successfully received, for passing to the LL.
+ * Warning: skb must not be accessed anymore!
+ */
+void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
+{
+	isdn_if *iif = bcs->cs->iif;
+
+	iif->rcvcallb_skb(bcs->cs->myid, bcs->channel, skb);
+	bcs->trans_down++;
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
+
+/**
+ * gigaset_isdn_rcv_err() - signal receive error
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when a receive error
+ * has occurred, for signalling to the LL.
+ */
+void gigaset_isdn_rcv_err(struct bc_state *bcs)
+{
+	isdn_if *iif = bcs->cs->iif;
+	isdn_ctrl response;
+
+	/* if currently ignoring packets, just count down */
+	if (bcs->ignore) {
+		bcs->ignore--;
+		return;
+	}
+
+	/* update statistics */
+	bcs->corrupted++;
+
+	/* error -> LL */
+	gig_dbg(DEBUG_CMD, "sending L1ERR");
+	response.driver = bcs->cs->myid;
+	response.command = ISDN_STAT_L1ERR;
+	response.arg = bcs->channel;
+	response.parm.errcode = ISDN_STAT_L1ERR_RECV;
+	iif->statcallb(&response);
+}
+EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
+
 /* This function will be called by LL to send commands
  * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL,
  * so don't put too much effort into it.
  */
 static int command_from_LL(isdn_ctrl *cntrl)
 {
-	struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver);
+	struct cardstate *cs;
 	struct bc_state *bcs;
 	int retval = 0;
-	struct setup_parm *sp;
+	char **commands;
+	int ch;
+	int i;
+	size_t l;
 
 	gigaset_debugdrivers();
 
-	if (!cs) {
+	gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx",
+		cntrl->driver, cntrl->command, cntrl->arg);
+
+	cs = gigaset_get_cs_by_id(cntrl->driver);
+	if (cs == NULL) {
 		pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver);
 		return -ENODEV;
 	}
+	ch = cntrl->arg & 0xff;
 
 	switch (cntrl->command) {
 	case ISDN_CMD_IOCTL:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)",
-			cntrl->driver, cntrl->arg);
-
 		dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n");
 		return -EINVAL;
 
 	case ISDN_CMD_DIAL:
 		gig_dbg(DEBUG_ANY,
-			"ISDN_CMD_DIAL (driver: %d, ch: %ld, "
-			"phone: %s, ownmsn: %s, si1: %d, si2: %d)",
-			cntrl->driver, cntrl->arg,
+			"ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)",
 			cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
 			cntrl->parm.setup.si1, cntrl->parm.setup.si2);
 
-		if (cntrl->arg >= cs->channels) {
+		if (ch >= cs->channels) {
 			dev_err(cs->dev,
-				"ISDN_CMD_DIAL: invalid channel (%d)\n",
-				(int) cntrl->arg);
+				"ISDN_CMD_DIAL: invalid channel (%d)\n", ch);
 			return -EINVAL;
 		}
-
-		bcs = cs->bcs + cntrl->arg;
-
+		bcs = cs->bcs + ch;
 		if (!gigaset_get_channel(bcs)) {
 			dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
 			return -EBUSY;
 		}
 
-		sp = kmalloc(sizeof *sp, GFP_ATOMIC);
-		if (!sp) {
+		commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC);
+		if (!commands) {
 			gigaset_free_channel(bcs);
 			dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
 			return -ENOMEM;
 		}
-		*sp = cntrl->parm.setup;
 
-		if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp,
+		l = 3 + strlen(cntrl->parm.setup.phone);
+		commands[AT_DIAL] = kmalloc(l, GFP_ATOMIC);
+		if (!commands[AT_DIAL])
+			goto oom;
+		if (cntrl->parm.setup.phone[0] == '*' &&
+		    cntrl->parm.setup.phone[1] == '*') {
+			/* internal call: translate ** prefix to CTP value */
+			commands[AT_TYPE] = kstrdup("^SCTP=0\r", GFP_ATOMIC);
+			if (!commands[AT_TYPE])
+				goto oom;
+			snprintf(commands[AT_DIAL], l,
+				 "D%s\r", cntrl->parm.setup.phone+2);
+		} else {
+			commands[AT_TYPE] = kstrdup("^SCTP=1\r", GFP_ATOMIC);
+			if (!commands[AT_TYPE])
+				goto oom;
+			snprintf(commands[AT_DIAL], l,
+				 "D%s\r", cntrl->parm.setup.phone);
+		}
+
+		l = strlen(cntrl->parm.setup.eazmsn);
+		if (l) {
+			l += 8;
+			commands[AT_MSN] = kmalloc(l, GFP_ATOMIC);
+			if (!commands[AT_MSN])
+				goto oom;
+			snprintf(commands[AT_MSN], l, "^SMSN=%s\r",
+				 cntrl->parm.setup.eazmsn);
+		}
+
+		switch (cntrl->parm.setup.si1) {
+		case 1:		/* audio */
+			/* BC = 9090A3: 3.1 kHz audio, A-law */
+			commands[AT_BC] = kstrdup("^SBC=9090A3\r", GFP_ATOMIC);
+			if (!commands[AT_BC])
+				goto oom;
+			break;
+		case 7:		/* data */
+		default:	/* hope the app knows what it is doing */
+			/* BC = 8890: unrestricted digital information */
+			commands[AT_BC] = kstrdup("^SBC=8890\r", GFP_ATOMIC);
+			if (!commands[AT_BC])
+				goto oom;
+		}
+		/* ToDo: other si1 values, inspect si2, set HLC/LLC */
+
+		commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
+		if (!commands[AT_PROTO])
+			goto oom;
+		snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
+
+		commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
+		if (!commands[AT_ISO])
+			goto oom;
+		snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
+			 (unsigned) bcs->channel + 1);
+
+		if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
 				       bcs->at_state.seq_index, NULL)) {
-			//FIXME what should we do?
-			kfree(sp);
+			for (i = 0; i < AT_NUM; ++i)
+				kfree(commands[i]);
+			kfree(commands);
 			gigaset_free_channel(bcs);
 			return -ENOMEM;
 		}
@@ -186,115 +308,102 @@ static int command_from_LL(isdn_ctrl *cn
 		gig_dbg(DEBUG_CMD, "scheduling DIAL");
 		gigaset_schedule_event(cs);
 		break;
-	case ISDN_CMD_ACCEPTD: //FIXME
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD");
-
-		if (cntrl->arg >= cs->channels) {
+	case ISDN_CMD_ACCEPTD:
+		if (ch >= cs->channels) {
 			dev_err(cs->dev,
-				"ISDN_CMD_ACCEPTD: invalid channel (%d)\n",
-				(int) cntrl->arg);
+				"ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch);
 			return -EINVAL;
 		}
-
-		if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state,
-				       EV_ACCEPT, NULL, 0, NULL)) {
-			//FIXME what should we do?
+		bcs = cs->bcs + ch;
+		if (!gigaset_add_event(cs, &bcs->at_state,
+				       EV_ACCEPT, NULL, 0, NULL))
 			return -ENOMEM;
-		}
 
 		gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
 		gigaset_schedule_event(cs);
 
 		break;
 	case ISDN_CMD_ACCEPTB:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB");
 		break;
 	case ISDN_CMD_HANGUP:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)",
-			(int) cntrl->arg);
-
-		if (cntrl->arg >= cs->channels) {
+		if (ch >= cs->channels) {
 			dev_err(cs->dev,
-				"ISDN_CMD_HANGUP: invalid channel (%d)\n",
-				(int) cntrl->arg);
+				"ISDN_CMD_HANGUP: invalid channel (%d)\n", ch);
 			return -EINVAL;
 		}
-
-		if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state,
-				       EV_HUP, NULL, 0, NULL)) {
-			//FIXME what should we do?
+		bcs = cs->bcs + ch;
+		if (!gigaset_add_event(cs, &bcs->at_state,
+				       EV_HUP, NULL, 0, NULL))
 			return -ENOMEM;
-		}
 
 		gig_dbg(DEBUG_CMD, "scheduling HUP");
 		gigaset_schedule_event(cs);
 
 		break;
-	case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ");
+	case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */
+		dev_info(cs->dev, "ignoring ISDN_CMD_CLREAZ\n");
 		break;
-	case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME
-		gig_dbg(DEBUG_ANY,
-			"ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)",
-			cntrl->driver, cntrl->arg, cntrl->parm.num);
+	case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */
+		dev_info(cs->dev, "ignoring ISDN_CMD_SETEAZ (%s)\n",
+			 cntrl->parm.num);
 		break;
 	case ISDN_CMD_SETL2: /* Set L2 to given protocol */
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)",
-			cntrl->arg & 0xff, (cntrl->arg >> 8));
-
-		if ((cntrl->arg & 0xff) >= cs->channels) {
+		if (ch >= cs->channels) {
 			dev_err(cs->dev,
-				"ISDN_CMD_SETL2: invalid channel (%d)\n",
-				(int) cntrl->arg & 0xff);
+				"ISDN_CMD_SETL2: invalid channel (%d)\n", ch);
 			return -EINVAL;
 		}
-
-		if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state,
-				       EV_PROTO_L2, NULL, cntrl->arg >> 8,
-				       NULL)) {
-			//FIXME what should we do?
-			return -ENOMEM;
+		bcs = cs->bcs + ch;
+		if (bcs->chstate & CHS_D_UP) {
+			dev_err(cs->dev,
+				"ISDN_CMD_SETL2: channel active (%d)\n", ch);
+			return -EINVAL;
+		}
+		switch (cntrl->arg >> 8) {
+		case ISDN_PROTO_L2_HDLC:
+			gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_HDLC");
+			bcs->proto2 = L2_HDLC;
+			break;
+		case ISDN_PROTO_L2_TRANS:
+			gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_VOICE");
+			bcs->proto2 = L2_VOICE;
+			break;
+		default:
+			dev_err(cs->dev,
+				"ISDN_CMD_SETL2: unsupported protocol (%lu)\n",
+				cntrl->arg >> 8);
+			return -EINVAL;
 		}
-
-		gig_dbg(DEBUG_CMD, "scheduling PROTO_L2");
-		gigaset_schedule_event(cs);
 		break;
 	case ISDN_CMD_SETL3: /* Set L3 to given protocol */
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)",
-			cntrl->arg & 0xff, (cntrl->arg >> 8));
-
-		if ((cntrl->arg & 0xff) >= cs->channels) {
+		if (ch >= cs->channels) {
 			dev_err(cs->dev,
-				"ISDN_CMD_SETL3: invalid channel (%d)\n",
-				(int) cntrl->arg & 0xff);
+				"ISDN_CMD_SETL3: invalid channel (%d)\n", ch);
 			return -EINVAL;
 		}
 
 		if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) {
 			dev_err(cs->dev,
-				"ISDN_CMD_SETL3: invalid protocol %lu\n",
+				"ISDN_CMD_SETL3: unsupported protocol (%lu)\n",
 				cntrl->arg >> 8);
 			return -EINVAL;
 		}
 
 		break;
 	case ISDN_CMD_PROCEED:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME
+		gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED");
 		break;
 	case ISDN_CMD_ALERT:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME
+		gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT");
 		if (cntrl->arg >= cs->channels) {
 			dev_err(cs->dev,
 				"ISDN_CMD_ALERT: invalid channel (%d)\n",
 				(int) cntrl->arg);
 			return -EINVAL;
 		}
-		//bcs = cs->bcs + cntrl->arg;
-		//bcs->proto2 = -1;
-		// FIXME
 		break;
 	case ISDN_CMD_REDIR:
-		gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME
+		gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR");
 		break;
 	case ISDN_CMD_PROT_IO:
 		gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
@@ -324,149 +433,34 @@ static int command_from_LL(isdn_ctrl *cn
 	}
 
 	return retval;
+
+oom:
+	dev_err(bcs->cs->dev, "out of memory\n");
+	for (i = 0; i < AT_NUM; ++i)
+		kfree(commands[i]);
+	return -ENOMEM;
 }
 
-void gigaset_i4l_cmd(struct cardstate *cs, int cmd)
+static void gigaset_i4l_cmd(struct cardstate *cs, int cmd)
 {
+	isdn_if *iif = cs->iif;
 	isdn_ctrl command;
 
 	command.driver = cs->myid;
 	command.command = cmd;
 	command.arg = 0;
-	cs->iif.statcallb(&command);
+	iif->statcallb(&command);
 }
 
-void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd)
+static void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd)
 {
+	isdn_if *iif = bcs->cs->iif;
 	isdn_ctrl command;
 
 	command.driver = bcs->cs->myid;
 	command.command = cmd;
 	command.arg = bcs->channel;
-	bcs->cs->iif.statcallb(&command);
-}
-
-int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data)
-{
-	struct bc_state *bcs = at_state->bcs;
-	unsigned proto;
-	const char *bc;
-	size_t length[AT_NUM];
-	size_t l;
-	int i;
-	struct setup_parm *sp = data;
-
-	switch (bcs->proto2) {
-	case ISDN_PROTO_L2_HDLC:
-		proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
-		break;
-	case ISDN_PROTO_L2_TRANS:
-		proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
-		break;
-	default:
-		dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n",
-			__func__, bcs->proto2);
-		return -EINVAL;
-	}
-
-	switch (sp->si1) {
-	case 1:		/* audio */
-		bc = "9090A3";	/* 3.1 kHz audio, A-law */
-		break;
-	case 7:		/* data */
-	default:	/* hope the app knows what it is doing */
-		bc = "8890";	/* unrestricted digital information */
-	}
-	//FIXME add missing si1 values from 1TR6, inspect si2, set HLC/LLC
-
-	length[AT_DIAL ] = 1 + strlen(sp->phone) + 1 + 1;
-	l = strlen(sp->eazmsn);
-	length[AT_MSN  ] = l ? 6 + l + 1 + 1 : 0;
-	length[AT_BC   ] = 5 + strlen(bc) + 1 + 1;
-	length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
-	length[AT_ISO  ] = 6 + 1 + 1 + 1; /* channel: 1 character */
-	length[AT_TYPE ] = 6 + 1 + 1 + 1; /* call type: 1 character */
-	length[AT_HLC  ] = 0;
-
-	for (i = 0; i < AT_NUM; ++i) {
-		kfree(bcs->commands[i]);
-		bcs->commands[i] = NULL;
-		if (length[i] &&
-		    !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
-			dev_err(bcs->cs->dev, "out of memory\n");
-			return -ENOMEM;
-		}
-	}
-
-	/* type = 1: extern, 0: intern, 2: recall, 3: door, 4: centrex */
-	if (sp->phone[0] == '*' && sp->phone[1] == '*') {
-		/* internal call: translate ** prefix to CTP value */
-		snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
-			 "D%s\r", sp->phone+2);
-		strncpy(bcs->commands[AT_TYPE], "^SCTP=0\r", length[AT_TYPE]);
-	} else {
-		snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
-			 "D%s\r", sp->phone);
-		strncpy(bcs->commands[AT_TYPE], "^SCTP=1\r", length[AT_TYPE]);
-	}
-
-	if (bcs->commands[AT_MSN])
-		snprintf(bcs->commands[AT_MSN], length[AT_MSN],
-			 "^SMSN=%s\r", sp->eazmsn);
-	snprintf(bcs->commands[AT_BC   ], length[AT_BC   ],
-		 "^SBC=%s\r", bc);
-	snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
-		 "^SBPR=%u\r", proto);
-	snprintf(bcs->commands[AT_ISO  ], length[AT_ISO  ],
-		 "^SISO=%u\r", (unsigned)bcs->channel + 1);
-
-	return 0;
-}
-
-int gigaset_isdn_setup_accept(struct at_state_t *at_state)
-{
-	unsigned proto;
-	size_t length[AT_NUM];
-	int i;
-	struct bc_state *bcs = at_state->bcs;
-
-	switch (bcs->proto2) {
-	case ISDN_PROTO_L2_HDLC:
-		proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
-		break;
-	case ISDN_PROTO_L2_TRANS:
-		proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
-		break;
-	default:
-		dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n",
-			__func__, bcs->proto2);
-		return -EINVAL;
-	}
-
-	length[AT_DIAL ] = 0;
-	length[AT_MSN  ] = 0;
-	length[AT_BC   ] = 0;
-	length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
-	length[AT_ISO  ] = 6 + 1 + 1 + 1; /* channel: 1 character */
-	length[AT_TYPE ] = 0;
-	length[AT_HLC  ] = 0;
-
-	for (i = 0; i < AT_NUM; ++i) {
-		kfree(bcs->commands[i]);
-		bcs->commands[i] = NULL;
-		if (length[i] &&
-		    !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
-			dev_err(at_state->cs->dev, "out of memory\n");
-			return -ENOMEM;
-		}
-	}
-
-	snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
-		 "^SBPR=%u\r", proto);
-	snprintf(bcs->commands[AT_ISO  ], length[AT_ISO  ],
-		 "^SISO=%u\r", (unsigned) bcs->channel + 1);
-
-	return 0;
+	iif->statcallb(&command);
 }
 
 /**
@@ -482,13 +476,14 @@ int gigaset_isdn_icall(struct at_state_t
 {
 	struct cardstate *cs = at_state->cs;
 	struct bc_state *bcs = at_state->bcs;
+	isdn_if *iif = cs->iif;
 	isdn_ctrl response;
 	int retval;
 
 	/* fill ICALL structure */
 	response.parm.setup.si1 = 0;	/* default: unknown */
 	response.parm.setup.si2 = 0;
-	response.parm.setup.screen = 0;	//FIXME how to set these?
+	response.parm.setup.screen = 0;
 	response.parm.setup.plan = 0;
 	if (!at_state->str_var[STR_ZBC]) {
 		/* no BC (internal call): assume speech, A-law */
@@ -509,29 +504,27 @@ int gigaset_isdn_icall(struct at_state_t
 		return ICALL_IGNORE;
 	}
 	if (at_state->str_var[STR_NMBR]) {
-		strncpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
-			sizeof response.parm.setup.phone - 1);
-		response.parm.setup.phone[sizeof response.parm.setup.phone - 1] = 0;
+		strlcpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
+			sizeof response.parm.setup.phone);
 	} else
 		response.parm.setup.phone[0] = 0;
 	if (at_state->str_var[STR_ZCPN]) {
-		strncpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
-			sizeof response.parm.setup.eazmsn - 1);
-		response.parm.setup.eazmsn[sizeof response.parm.setup.eazmsn - 1] = 0;
+		strlcpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
+			sizeof response.parm.setup.eazmsn);
 	} else
 		response.parm.setup.eazmsn[0] = 0;
 
 	if (!bcs) {
 		dev_notice(cs->dev, "no channel for incoming call\n");
 		response.command = ISDN_STAT_ICALLW;
-		response.arg = 0; //FIXME
+		response.arg = 0;
 	} else {
 		gig_dbg(DEBUG_CMD, "Sending ICALL");
 		response.command = ISDN_STAT_ICALL;
-		response.arg = bcs->channel; //FIXME
+		response.arg = bcs->channel;
 	}
 	response.driver = cs->myid;
-	retval = cs->iif.statcallb(&response);
+	retval = iif->statcallb(&response);
 	gig_dbg(DEBUG_CMD, "Response: %d", retval);
 	switch (retval) {
 	case 0:	/* no takers */
@@ -560,16 +553,109 @@ int gigaset_isdn_icall(struct at_state_t
 	}
 }
 
-/* Set Callback function pointer */
-int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
+/**
+ * gigaset_isdn_connD() - signal D channel connect
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module to notify the LL that the D channel connection has
+ * been established.
+ */
+void gigaset_isdn_connD(struct bc_state *bcs)
 {
-	isdn_if *iif = &cs->iif;
+	gig_dbg(DEBUG_CMD, "sending DCONN");
+	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
+}
 
-	gig_dbg(DEBUG_ANY, "Register driver capabilities to LL");
+/**
+ * gigaset_isdn_hupD() - signal D channel hangup
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module to notify the LL that the D channel connection has
+ * been shut down.
+ */
+void gigaset_isdn_hupD(struct bc_state *bcs)
+{
+	gig_dbg(DEBUG_CMD, "sending DHUP");
+	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
+}
+
+/**
+ * gigaset_isdn_connB() - signal B channel connect
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module to notify the LL that the B channel connection has
+ * been established.
+ */
+void gigaset_isdn_connB(struct bc_state *bcs)
+{
+	gig_dbg(DEBUG_CMD, "sending BCONN");
+	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
+}
+
+/**
+ * gigaset_isdn_hupB() - signal B channel hangup
+ * @bcs:	B channel descriptor structure.
+ *
+ * Called by main module to notify the LL that the B channel connection has
+ * been shut down.
+ */
+void gigaset_isdn_hupB(struct bc_state *bcs)
+{
+	gig_dbg(DEBUG_CMD, "sending BHUP");
+	gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
+}
+
+/**
+ * gigaset_isdn_start() - signal device availability
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to notify the LL that the device is available for
+ * use.
+ */
+void gigaset_isdn_start(struct cardstate *cs)
+{
+	gig_dbg(DEBUG_CMD, "sending RUN");
+	gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
+}
+
+/**
+ * gigaset_isdn_stop() - signal device unavailability
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to notify the LL that the device is no longer
+ * available for use.
+ */
+void gigaset_isdn_stop(struct cardstate *cs)
+{
+	gig_dbg(DEBUG_CMD, "sending STOP");
+	gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
+}
+
+/**
+ * gigaset_isdn_register() - register to LL
+ * @cs:		device descriptor structure.
+ * @isdnid:	device name.
+ *
+ * Called by main module to register the device with the LL.
+ *
+ * Return value: 1 for success, 0 for failure
+ */
+int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+{
+	isdn_if *iif;
+
+	pr_info("ISDN4Linux interface\n");
+
+	iif = kmalloc(sizeof *iif, GFP_KERNEL);
+	if (!iif) {
+		pr_err("out of memory\n");
+		return 0;
+	}
 
 	if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
 	    >= sizeof iif->id) {
 		pr_err("ID too long: %s\n", isdnid);
+		kfree(iif);
 		return 0;
 	}
 
@@ -593,9 +679,26 @@ int gigaset_register_to_LL(struct cardst
 
 	if (!register_isdn(iif)) {
 		pr_err("register_isdn failed\n");
+		kfree(iif);
 		return 0;
 	}
 
+	cs->iif = iif;
 	cs->myid = iif->channels;		/* Set my device id */
+	cs->hw_hdr_len = HW_HDR_LEN;
 	return 1;
 }
+
+/**
+ * gigaset_isdn_unregister() - unregister from LL
+ * @cs:		device descriptor structure.
+ *
+ * Called by main module to unregister the device from the LL.
+ */
+void gigaset_isdn_unregister(struct cardstate *cs)
+{
+	gig_dbg(DEBUG_CMD, "sending UNLOAD");
+	gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
+	kfree(cs->iif);
+	cs->iif = NULL;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/interface.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/interface.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/interface.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/interface.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,7 +162,7 @@ static int if_open(struct tty_struct *tt
 		return -ENODEV;
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 	tty->driver_data = cs;
 
 	++cs->open_count;
@@ -171,7 +171,7 @@ static int if_open(struct tty_struct *tt
 		spin_lock_irqsave(&cs->lock, flags);
 		cs->tty = tty;
 		spin_unlock_irqrestore(&cs->lock, flags);
-		tty->low_latency = 1; //FIXME test
+		tty->low_latency = 1;
 	}
 
 	mutex_unlock(&cs->mutex);
@@ -228,7 +228,7 @@ static int if_ioctl(struct tty_struct *t
 	gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd);
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
 	if (!cs->connected) {
 		gig_dbg(DEBUG_IF, "not connected");
@@ -299,9 +299,8 @@ static int if_tiocmget(struct tty_struct
 	gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
-	// FIXME read from device?
 	retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR);
 
 	mutex_unlock(&cs->mutex);
@@ -326,7 +325,7 @@ static int if_tiocmset(struct tty_struct
 		cs->minor_index, __func__, set, clear);
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
 	if (!cs->connected) {
 		gig_dbg(DEBUG_IF, "not connected");
@@ -356,7 +355,7 @@ static int if_write(struct tty_struct *t
 	gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
 	if (!cs->connected) {
 		gig_dbg(DEBUG_IF, "not connected");
@@ -390,7 +389,7 @@ static int if_write_room(struct tty_stru
 	gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
 	if (!cs->connected) {
 		gig_dbg(DEBUG_IF, "not connected");
@@ -455,9 +454,8 @@ static void if_throttle(struct tty_struc
 		gig_dbg(DEBUG_IF, "not connected");	/* nothing to do */
 	else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
-	else {
-		//FIXME
-	}
+	else
+		gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__);
 
 	mutex_unlock(&cs->mutex);
 }
@@ -480,9 +478,8 @@ static void if_unthrottle(struct tty_str
 		gig_dbg(DEBUG_IF, "not connected");	/* nothing to do */
 	else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
-	else {
-		//FIXME
-	}
+	else
+		gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__);
 
 	mutex_unlock(&cs->mutex);
 }
@@ -515,10 +512,9 @@ static void if_set_termios(struct tty_st
 		goto out;
 	}
 
-	// stolen from mct_u232.c
 	iflag = tty->termios->c_iflag;
 	cflag = tty->termios->c_cflag;
-	old_cflag = old ? old->c_cflag : cflag; //FIXME?
+	old_cflag = old ? old->c_cflag : cflag;
 	gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x",
 		cs->minor_index, iflag, cflag, old_cflag);
 
@@ -588,7 +584,7 @@ void gigaset_if_init(struct cardstate *c
 	if (!drv->have_tty)
 		return;
 
-	tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs);
+	tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs);
 
 	mutex_lock(&cs->mutex);
 	cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL);
@@ -632,7 +628,8 @@ void gigaset_if_receive(struct cardstate
 	struct tty_struct *tty;
 
 	spin_lock_irqsave(&cs->lock, flags);
-	if ((tty = cs->tty) == NULL)
+	tty = cs->tty;
+	if (tty == NULL)
 		gig_dbg(DEBUG_ANY, "receive on closed device");
 	else {
 		tty_buffer_request_room(tty, len);
@@ -659,9 +656,9 @@ void gigaset_if_initdriver(struct gigase
 
 	drv->have_tty = 0;
 
-	if ((drv->tty = alloc_tty_driver(minors)) == NULL)
+	drv->tty = tty = alloc_tty_driver(minors);
+	if (tty == NULL)
 		goto enomem;
-	tty = drv->tty;
 
 	tty->magic =		TTY_DRIVER_MAGIC,
 	tty->major =		GIG_MAJOR,
@@ -676,8 +673,8 @@ void gigaset_if_initdriver(struct gigase
 
 	tty->owner =		THIS_MODULE;
 
-	tty->init_termios          = tty_std_termios; //FIXME
-	tty->init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME
+	tty->init_termios          = tty_std_termios;
+	tty->init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 	tty_set_operations(tty, &if_ops);
 
 	ret = tty_register_driver(tty);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/isocdata.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/isocdata.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/isocdata.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/isocdata.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,7 +41,8 @@ static inline int isowbuf_freebytes(stru
 
 	read = iwb->read;
 	write = iwb->write;
-	if ((freebytes = read - write) > 0) {
+	freebytes = read - write;
+	if (freebytes > 0) {
 		/* no wraparound: need padding space within regular area */
 		return freebytes - BAS_OUTBUFPAD;
 	} else if (read < BAS_OUTBUFPAD) {
@@ -53,29 +54,6 @@ static inline int isowbuf_freebytes(stru
 	}
 }
 
-/* compare two offsets within the buffer
- * The buffer is seen as circular, with the read position as start
- * returns -1/0/1 if position a </=/> position b without crossing 'read'
- */
-static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b)
-{
-	int read;
-	if (a == b)
-		return 0;
-	read = iwb->read;
-	if (a < b) {
-		if (a < read && read <= b)
-			return +1;
-		else
-			return -1;
-	} else {
-		if (b < read && read <= a)
-			return -1;
-		else
-			return +1;
-	}
-}
-
 /* start writing
  * acquire the write semaphore
  * return true if acquired, false if busy
@@ -271,7 +249,7 @@ static inline void dump_bytes(enum debug
  *        bit 14..13 = number of bits added by stuffing
  */
 static const u16 stufftab[5 * 256] = {
-// previous 1s = 0:
+/* previous 1s = 0: */
  0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
  0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
  0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
@@ -289,7 +267,7 @@ static const u16 stufftab[5 * 256] = {
  0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
  0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
 
-// previous 1s = 1:
+/* previous 1s = 1: */
  0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
  0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
  0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
@@ -307,7 +285,7 @@ static const u16 stufftab[5 * 256] = {
  0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
  0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
 
-// previous 1s = 2:
+/* previous 1s = 2: */
  0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
  0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
  0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
@@ -325,7 +303,7 @@ static const u16 stufftab[5 * 256] = {
  0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
  0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
 
-// previous 1s = 3:
+/* previous 1s = 3: */
  0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
  0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
  0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
@@ -343,7 +321,7 @@ static const u16 stufftab[5 * 256] = {
  0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
  0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
 
-// previous 1s = 4:
+/* previous 1s = 4: */
  0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
  0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
  0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
@@ -367,7 +345,8 @@ static const u16 stufftab[5 * 256] = {
  * parameters:
  *	cin	input byte
  *	ones	number of trailing '1' bits in result before this step
- *	iwb	pointer to output buffer structure (write semaphore must be held)
+ *	iwb	pointer to output buffer structure
+ *		(write semaphore must be held)
  * return value:
  *	number of trailing '1' bits in result after this step
  */
@@ -408,7 +387,8 @@ static inline int hdlc_bitstuff_byte(str
  * parameters:
  *	in	input buffer
  *	count	number of bytes in input buffer
- *	iwb	pointer to output buffer structure (write semaphore must be held)
+ *	iwb	pointer to output buffer structure
+ *		(write semaphore must be held)
  * return value:
  *	position of end of packet in output buffer on success,
  *	-EAGAIN if write semaphore busy or buffer full
@@ -440,7 +420,8 @@ static inline int hdlc_buildframe(struct
 		fcs = crc_ccitt_byte(fcs, c);
 	}
 
-	/* bitstuff and append FCS (complemented, least significant byte first) */
+	/* bitstuff and append FCS
+	 * (complemented, least significant byte first) */
 	fcs ^= 0xffff;
 	ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
 	ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
@@ -459,7 +440,8 @@ static inline int hdlc_buildframe(struct
  * parameters:
  *	in	input buffer
  *	count	number of bytes in input buffer
- *	iwb	pointer to output buffer structure (write semaphore must be held)
+ *	iwb	pointer to output buffer structure
+ *		(write semaphore must be held)
  * return value:
  *	position of end of packet in output buffer on success,
  *	-EAGAIN if write semaphore busy or buffer full
@@ -500,7 +482,7 @@ int gigaset_isoc_buildframe(struct bc_st
 	int result;
 
 	switch (bcs->proto2) {
-	case ISDN_PROTO_L2_HDLC:
+	case L2_HDLC:
 		result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
 		gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
 			__func__, len, result);
@@ -542,8 +524,9 @@ static inline void hdlc_flush(struct bc_
 	if (likely(bcs->skb != NULL))
 		skb_trim(bcs->skb, 0);
 	else if (!bcs->ignore) {
-		if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
-			skb_reserve(bcs->skb, HW_HDR_LEN);
+		bcs->skb = dev_alloc_skb(SBUFSIZE + bcs->cs->hw_hdr_len);
+		if (bcs->skb)
+			skb_reserve(bcs->skb, bcs->cs->hw_hdr_len);
 		else
 			dev_err(bcs->cs->dev, "could not allocate skb\n");
 	}
@@ -557,43 +540,46 @@ static inline void hdlc_flush(struct bc_
  */
 static inline void hdlc_done(struct bc_state *bcs)
 {
+	struct cardstate *cs = bcs->cs;
 	struct sk_buff *procskb;
+	unsigned int len;
 
 	if (unlikely(bcs->ignore)) {
 		bcs->ignore--;
 		hdlc_flush(bcs);
 		return;
 	}
-
-	if ((procskb = bcs->skb) == NULL) {
+	procskb = bcs->skb;
+	if (procskb == NULL) {
 		/* previous error */
 		gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
-		gigaset_rcv_error(NULL, bcs->cs, bcs);
+		gigaset_isdn_rcv_err(bcs);
 	} else if (procskb->len < 2) {
-		dev_notice(bcs->cs->dev, "received short frame (%d octets)\n",
+		dev_notice(cs->dev, "received short frame (%d octets)\n",
 			   procskb->len);
 		bcs->hw.bas->runts++;
-		gigaset_rcv_error(procskb, bcs->cs, bcs);
+		dev_kfree_skb_any(procskb);
+		gigaset_isdn_rcv_err(bcs);
 	} else if (bcs->fcs != PPP_GOODFCS) {
-		dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n",
-			   bcs->fcs);
+		dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs);
 		bcs->hw.bas->fcserrs++;
-		gigaset_rcv_error(procskb, bcs->cs, bcs);
+		dev_kfree_skb_any(procskb);
+		gigaset_isdn_rcv_err(bcs);
 	} else {
-		procskb->len -= 2;		/* subtract FCS */
-		procskb->tail -= 2;
-		gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",
-			__func__, procskb->len);
+		len = procskb->len;
+		__skb_trim(procskb, len -= 2);	/* subtract FCS */
+		gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len);
 		dump_bytes(DEBUG_STREAM_DUMP,
-			   "rcv data", procskb->data, procskb->len);
-		bcs->hw.bas->goodbytes += procskb->len;
-		gigaset_rcv_skb(procskb, bcs->cs, bcs);
+			   "rcv data", procskb->data, len);
+		bcs->hw.bas->goodbytes += len;
+		gigaset_skb_rcvd(bcs, procskb);
 	}
 
-	if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
-		skb_reserve(bcs->skb, HW_HDR_LEN);
+	bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
+	if (bcs->skb)
+		skb_reserve(bcs->skb, cs->hw_hdr_len);
 	else
-		dev_err(bcs->cs->dev, "could not allocate skb\n");
+		dev_err(cs->dev, "could not allocate skb\n");
 	bcs->fcs = PPP_INITFCS;
 }
 
@@ -610,12 +596,8 @@ static inline void hdlc_frag(struct bc_s
 
 	dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
 	bcs->hw.bas->alignerrs++;
-	gigaset_rcv_error(bcs->skb, bcs->cs, bcs);
-
-	if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
-		skb_reserve(bcs->skb, HW_HDR_LEN);
-	else
-		dev_err(bcs->cs->dev, "could not allocate skb\n");
+	gigaset_isdn_rcv_err(bcs);
+	__skb_trim(bcs->skb, 0);
 	bcs->fcs = PPP_INITFCS;
 }
 
@@ -646,10 +628,10 @@ static const unsigned char bitcounts[256
 };
 
 /* hdlc_unpack
- * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation)
- * on a sequence of received data bytes (8 bits each, LSB first)
- * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb
- * notify of errors via gigaset_rcv_error
+ * perform HDLC frame processing (bit unstuffing, flag detection, FCS
+ * calculation) on a sequence of received data bytes (8 bits each, LSB first)
+ * pass on successfully received, complete frames as SKBs via gigaset_skb_rcvd
+ * notify of errors via gigaset_isdn_rcv_err
  * tally frames, errors etc. in BC structure counters
  * parameters:
  *	src	received data
@@ -665,9 +647,12 @@ static inline void hdlc_unpack(unsigned
 
 	/* load previous state:
 	 * inputstate = set of flag bits:
-	 * - INS_flag_hunt: no complete opening flag received since connection setup or last abort
-	 * - INS_have_data: at least one complete data byte received since last flag
-	 * seqlen = number of consecutive '1' bits in last 7 input stream bits (0..7)
+	 * - INS_flag_hunt: no complete opening flag received since connection
+	 *                  setup or last abort
+	 * - INS_have_data: at least one complete data byte received since last
+	 *                  flag
+	 * seqlen = number of consecutive '1' bits in last 7 input stream bits
+	 *          (0..7)
 	 * inbyte = accumulated partial data byte (if !INS_flag_hunt)
 	 * inbits = number of valid bits in inbyte, starting at LSB (0..6)
 	 */
@@ -701,9 +686,11 @@ static inline void hdlc_unpack(unsigned
 				inbyte = c >> (lead1 + 1);
 				inbits = 7 - lead1;
 				if (trail1 >= 8) {
-					/* interior stuffing: omitting the MSB handles most cases */
+					/* interior stuffing:
+					 * omitting the MSB handles most cases,
+					 * correct the incorrectly handled
+					 * cases individually */
 					inbits--;
-					/* correct the incorrectly handled cases individually */
 					switch (c) {
 					case 0xbe:
 						inbyte = 0x3f;
@@ -729,13 +716,14 @@ static inline void hdlc_unpack(unsigned
 			hdlc_flush(bcs);
 			inputstate |= INS_flag_hunt;
 		} else if (seqlen == 6) {
-			/* closing flag, including (6 - lead1) '1's and one '0' from inbits */
+			/* closing flag, including (6 - lead1) '1's
+			 * and one '0' from inbits */
 			if (inbits > 7 - lead1) {
 				hdlc_frag(bcs, inbits + lead1 - 7);
 				inputstate &= ~INS_have_data;
 			} else {
 				if (inbits < 7 - lead1)
-					ubc->stolen0s ++;
+					ubc->stolen0s++;
 				if (inputstate & INS_have_data) {
 					hdlc_done(bcs);
 					inputstate &= ~INS_have_data;
@@ -744,7 +732,7 @@ static inline void hdlc_unpack(unsigned
 
 			if (c == PPP_FLAG) {
 				/* complete flag, LSB overlaps preceding flag */
-				ubc->shared0s ++;
+				ubc->shared0s++;
 				inbits = 0;
 				inbyte = 0;
 			} else if (trail1 != 7) {
@@ -752,9 +740,11 @@ static inline void hdlc_unpack(unsigned
 				inbyte = c >> (lead1 + 1);
 				inbits = 7 - lead1;
 				if (trail1 >= 8) {
-					/* interior stuffing: omitting the MSB handles most cases */
+					/* interior stuffing:
+					 * omitting the MSB handles most cases,
+					 * correct the incorrectly handled
+					 * cases individually */
 					inbits--;
-					/* correct the incorrectly handled cases individually */
 					switch (c) {
 					case 0xbe:
 						inbyte = 0x3f;
@@ -762,7 +752,8 @@ static inline void hdlc_unpack(unsigned
 					}
 				}
 			} else {
-				/* abort sequence follows, skb already empty anyway */
+				/* abort sequence follows,
+				 * skb already empty anyway */
 				ubc->aborts++;
 				inputstate |= INS_flag_hunt;
 			}
@@ -787,14 +778,17 @@ static inline void hdlc_unpack(unsigned
 			} else {
 				/* stuffed data */
 				if (trail1 < 7) { /* => seqlen == 5 */
-					/* stuff bit at position lead1, no interior stuffing */
+					/* stuff bit at position lead1,
+					 * no interior stuffing */
 					unsigned char mask = (1 << lead1) - 1;
 					c = (c & mask) | ((c & ~mask) >> 1);
 					inbyte |= c << inbits;
 					inbits += 7;
 				} else if (seqlen < 5) { /* trail1 >= 8 */
-					/* interior stuffing: omitting the MSB handles most cases */
-					/* correct the incorrectly handled cases individually */
+					/* interior stuffing:
+					 * omitting the MSB handles most cases,
+					 * correct the incorrectly handled
+					 * cases individually */
 					switch (c) {
 					case 0xbe:
 						c = 0x7e;
@@ -804,8 +798,9 @@ static inline void hdlc_unpack(unsigned
 					inbits += 7;
 				} else { /* seqlen == 5 && trail1 >= 8 */
 
-					/* stuff bit at lead1 *and* interior stuffing */
-					switch (c) {	/* unstuff individually */
+					/* stuff bit at lead1 *and* interior
+					 * stuffing -- unstuff individually */
+					switch (c) {
 					case 0x7d:
 						c = 0x3f;
 						break;
@@ -841,7 +836,7 @@ static inline void hdlc_unpack(unsigned
 }
 
 /* trans_receive
- * pass on received USB frame transparently as SKB via gigaset_rcv_skb
+ * pass on received USB frame transparently as SKB via gigaset_skb_rcvd
  * invert bytes
  * tally frames, errors etc. in BC structure counters
  * parameters:
@@ -852,6 +847,7 @@ static inline void hdlc_unpack(unsigned
 static inline void trans_receive(unsigned char *src, unsigned count,
 				 struct bc_state *bcs)
 {
+	struct cardstate *cs = bcs->cs;
 	struct sk_buff *skb;
 	int dobytes;
 	unsigned char *dst;
@@ -861,13 +857,14 @@ static inline void trans_receive(unsigne
 		hdlc_flush(bcs);
 		return;
 	}
-	if (unlikely((skb = bcs->skb) == NULL)) {
-		bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
+	skb = bcs->skb;
+	if (unlikely(skb == NULL)) {
+		bcs->skb = skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
 		if (!skb) {
-			dev_err(bcs->cs->dev, "could not allocate skb\n");
+			dev_err(cs->dev, "could not allocate skb\n");
 			return;
 		}
-		skb_reserve(skb, HW_HDR_LEN);
+		skb_reserve(skb, cs->hw_hdr_len);
 	}
 	bcs->hw.bas->goodbytes += skb->len;
 	dobytes = TRANSBUFSIZE - skb->len;
@@ -881,23 +878,24 @@ static inline void trans_receive(unsigne
 		if (dobytes == 0) {
 			dump_bytes(DEBUG_STREAM_DUMP,
 				   "rcv data", skb->data, skb->len);
-			gigaset_rcv_skb(skb, bcs->cs, bcs);
-			bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
+			gigaset_skb_rcvd(bcs, skb);
+			bcs->skb = skb =
+				dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
 			if (!skb) {
-				dev_err(bcs->cs->dev,
-					"could not allocate skb\n");
+				dev_err(cs->dev, "could not allocate skb\n");
 				return;
 			}
-			skb_reserve(bcs->skb, HW_HDR_LEN);
+			skb_reserve(skb, cs->hw_hdr_len);
 			dobytes = TRANSBUFSIZE;
 		}
 	}
 }
 
-void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs)
+void gigaset_isoc_receive(unsigned char *src, unsigned count,
+			  struct bc_state *bcs)
 {
 	switch (bcs->proto2) {
-	case ISDN_PROTO_L2_HDLC:
+	case L2_HDLC:
 		hdlc_unpack(src, count, bcs);
 		break;
 	default:		/* assume transparent */
@@ -981,8 +979,10 @@ void gigaset_isoc_input(struct inbuf_t *
  * @bcs:	B channel descriptor structure.
  * @skb:	data to send.
  *
- * Called by i4l.c to queue an skb for sending, and start transmission if
+ * Called by LL to queue an skb for sending, and start transmission if
  * necessary.
+ * Once the payload data has been transmitted completely, gigaset_skb_sent()
+ * will be called with the skb's link layer header preserved.
  *
  * Return value:
  *	number of bytes accepted for sending (skb->len) if ok,
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
 menuconfig ISDN_DRV_GIGASET
 	tristate "Siemens Gigaset support"
-	depends on ISDN_I4L
 	select CRC_CCITT
 	select BITREVERSE
 	help
@@ -11,9 +10,33 @@ menuconfig ISDN_DRV_GIGASET
 	  If you have one of these devices, say M here and for at least
 	  one of the connection specific parts that follow.
 	  This will build a module called "gigaset".
+	  Note: If you build your ISDN subsystem (ISDN_CAPI or ISDN_I4L)
+	  as a module, you have to build this driver as a module too,
+	  otherwise the Gigaset device won't show up as an ISDN device.
 
 if ISDN_DRV_GIGASET
 
+config GIGASET_CAPI
+	bool "Gigaset CAPI support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m')
+	default ISDN_I4L='n'
+	help
+	  Build the Gigaset driver as a CAPI 2.0 driver interfacing with
+	  the Kernel CAPI subsystem. To use it with the old ISDN4Linux
+	  subsystem you'll have to enable the capidrv glue driver.
+	  (select ISDN_CAPI_CAPIDRV.)
+	  Say N to build the old native ISDN4Linux variant.
+
+config GIGASET_I4L
+	bool
+	depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m')
+	default !GIGASET_CAPI
+
+config GIGASET_DUMMYLL
+	bool
+	default !GIGASET_CAPI&&!GIGASET_I4L
+
 config GIGASET_BASE
 	tristate "Gigaset base station support"
 	depends on USB
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/Makefile linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/Makefile
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,7 @@
-gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o asyncdata.o
+gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o
+gigaset-$(CONFIG_GIGASET_CAPI) += capi.o
+gigaset-$(CONFIG_GIGASET_I4L) += i4l.o
+gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o
 usb_gigaset-y := usb-gigaset.o
 ser_gigaset-y := ser-gigaset.o
 bas_gigaset-y := bas-gigaset.o isocdata.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/proc.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/proc.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,7 @@ static ssize_t set_cidmode(struct device
 			return -EINVAL;
 
 	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+		return -ERESTARTSYS;
 
 	cs->waiting = 1;
 	if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE,
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/ser-gigaset.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ser-gigaset.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,9 +164,15 @@ static void gigaset_modem_fill(unsigned
 {
 	struct cardstate *cs = (struct cardstate *) data;
 	struct bc_state *bcs;
+	struct sk_buff *nextskb;
 	int sent = 0;
 
-	if (!cs || !(bcs = cs->bcs)) {
+	if (!cs) {
+		gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
+		return;
+	}
+	bcs = cs->bcs;
+	if (!bcs) {
 		gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
 		return;
 	}
@@ -179,9 +185,11 @@ static void gigaset_modem_fill(unsigned
 			return;
 
 		/* no command to send; get skb */
-		if (!(bcs->tx_skb = skb_dequeue(&bcs->squeue)))
+		nextskb = skb_dequeue(&bcs->squeue);
+		if (!nextskb)
 			/* no skb either, nothing to do */
 			return;
+		bcs->tx_skb = nextskb;
 
 		gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)",
 			(unsigned long) bcs->tx_skb);
@@ -236,19 +244,20 @@ static void flush_send_queue(struct card
  *	number of bytes queued, or error code < 0
  */
 static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
-                             int len, struct tasklet_struct *wake_tasklet)
+			     int len, struct tasklet_struct *wake_tasklet)
 {
 	struct cmdbuf_t *cb;
 	unsigned long flags;
 
 	gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
-	                     DEBUG_TRANSCMD : DEBUG_LOCKCMD,
-	                   "CMD Transmit", len, buf);
+				DEBUG_TRANSCMD : DEBUG_LOCKCMD,
+			   "CMD Transmit", len, buf);
 
 	if (len <= 0)
 		return 0;
 
-	if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
+	cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
+	if (!cb) {
 		dev_err(cs->dev, "%s: out of memory!\n", __func__);
 		return -ENOMEM;
 	}
@@ -392,7 +401,6 @@ static void gigaset_device_release(struc
 	struct platform_device *pdev = to_platform_device(dev);
 
 	/* adapted from platform_device_release() in drivers/base/platform.c */
-	//FIXME is this actually necessary?
 	kfree(dev->platform_data);
 	kfree(pdev->resource);
 }
@@ -404,16 +412,20 @@ static void gigaset_device_release(struc
 static int gigaset_initcshw(struct cardstate *cs)
 {
 	int rc;
+	struct ser_cardstate *scs;
 
-	if (!(cs->hw.ser = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL))) {
+	scs = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL);
+	if (!scs) {
 		pr_err("out of memory\n");
 		return 0;
 	}
+	cs->hw.ser = scs;
 
 	cs->hw.ser->dev.name = GIGASET_MODULENAME;
 	cs->hw.ser->dev.id = cs->minor_index;
 	cs->hw.ser->dev.dev.release = gigaset_device_release;
-	if ((rc = platform_device_register(&cs->hw.ser->dev)) != 0) {
+	rc = platform_device_register(&cs->hw.ser->dev);
+	if (rc != 0) {
 		pr_err("error %d registering platform device\n", rc);
 		kfree(cs->hw.ser);
 		cs->hw.ser = NULL;
@@ -422,7 +434,7 @@ static int gigaset_initcshw(struct cards
 	dev_set_drvdata(&cs->hw.ser->dev.dev, cs);
 
 	tasklet_init(&cs->write_tasklet,
-	             &gigaset_modem_fill, (unsigned long) cs);
+		     gigaset_modem_fill, (unsigned long) cs);
 	return 1;
 }
 
@@ -434,7 +446,8 @@ static int gigaset_initcshw(struct cards
  * Called by "gigaset_start" and "gigaset_enterconfigmode" in common.c
  * and by "if_lock" and "if_termios" in interface.c
  */
-static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, unsigned new_state)
+static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
+				  unsigned new_state)
 {
 	struct tty_struct *tty = cs->hw.ser->tty;
 	unsigned int set, clear;
@@ -520,8 +533,8 @@ gigaset_tty_open(struct tty_struct *tty)
 	}
 
 	/* allocate memory for our device state and intialize it */
-	if (!(cs = gigaset_initcs(driver, 1, 1, 0, cidmode,
-				  GIGASET_MODULENAME)))
+	cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
+	if (!cs)
 		goto error;
 
 	cs->dev = &cs->hw.ser->dev.dev;
@@ -690,7 +703,8 @@ gigaset_tty_receive(struct tty_struct *t
 
 	if (!cs)
 		return;
-	if (!(inbuf = cs->inbuf)) {
+	inbuf = cs->inbuf;
+	if (!inbuf) {
 		dev_err(cs->dev, "%s: no inbuf\n", __func__);
 		cs_put(cs);
 		return;
@@ -770,18 +784,21 @@ static int __init ser_gigaset_init(void)
 	int rc;
 
 	gig_dbg(DEBUG_INIT, "%s", __func__);
-	if ((rc = platform_driver_register(&device_driver)) != 0) {
+	rc = platform_driver_register(&device_driver);
+	if (rc != 0) {
 		pr_err("error %d registering platform driver\n", rc);
 		return rc;
 	}
 
 	/* allocate memory for our driver state and intialize it */
-	if (!(driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
+	driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
 					  GIGASET_MODULENAME, GIGASET_DEVNAME,
-					  &ops, THIS_MODULE)))
+					  &ops, THIS_MODULE);
+	if (!driver)
 		goto error;
 
-	if ((rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc)) != 0) {
+	rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
+	if (rc != 0) {
 		pr_err("error %d registering line discipline\n", rc);
 		goto error;
 	}
@@ -808,7 +825,8 @@ static void __exit ser_gigaset_exit(void
 		driver = NULL;
 	}
 
-	if ((rc = tty_unregister_ldisc(N_GIGASET_M101)) != 0)
+	rc = tty_unregister_ldisc(N_GIGASET_M101);
+	if (rc != 0)
 		pr_err("error %d unregistering line discipline\n", rc);
 
 	platform_driver_unregister(&device_driver);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/usb-gigaset.c linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/usb-gigaset.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,14 +43,14 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"
 #define GIGASET_MODULENAME "usb_gigaset"
 #define GIGASET_DEVNAME    "ttyGU"
 
-#define IF_WRITEBUF 2000 //FIXME  // WAKEUP_CHARS: 256
+#define IF_WRITEBUF 2000	/* arbitrary limit */
 
 /* Values for the Gigaset M105 Data */
 #define USB_M105_VENDOR_ID	0x0681
 #define USB_M105_PRODUCT_ID	0x0009
 
 /* table of devices that work with this driver */
-static const struct usb_device_id gigaset_table [] = {
+static const struct usb_device_id gigaset_table[] = {
 	{ USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -97,8 +97,8 @@ MODULE_DEVICE_TABLE(usb, gigaset_table);
  *       41 19 -- -- -- -- 06 00 00 00 00 xx 11 13
  *            Used after every "configuration sequence" (RQ 12, RQs 01/03/13).
  *            xx is usually 0x00 but was 0x7e before starting data transfer
- *            in unimodem mode. So, this might be an array of characters that need
- *            special treatment ("commit all bufferd data"?), 11=^Q, 13=^S.
+ *            in unimodem mode. So, this might be an array of characters that
+ *            need special treatment ("commit all bufferd data"?), 11=^Q, 13=^S.
  *
  * Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two
  * flags per packet.
@@ -114,7 +114,7 @@ static int gigaset_suspend(struct usb_in
 static int gigaset_resume(struct usb_interface *intf);
 static int gigaset_pre_reset(struct usb_interface *intf);
 
-static struct gigaset_driver *driver = NULL;
+static struct gigaset_driver *driver;
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver gigaset_usb_driver = {
@@ -141,6 +141,7 @@ struct usb_cardstate {
 	struct urb		*bulk_out_urb;
 
 	/* Input buffer */
+	unsigned char		*rcvbuf;
 	int			rcvbuf_size;
 	struct urb		*read_urb;
 	__u8			int_in_endpointAddr;
@@ -164,13 +165,11 @@ static int gigaset_set_modem_ctrl(struct
 	val = tiocm_to_gigaset(new_state);
 
 	gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask);
-	// don't use this in an interrupt/BH
 	r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41,
 			    (val & 0xff) | ((mask & 0xff) << 8), 0,
 			    NULL, 0, 2000 /* timeout? */);
 	if (r < 0)
 		return r;
-	//..
 	return 0;
 }
 
@@ -220,7 +219,6 @@ static int gigaset_baud_rate(struct card
 	cflag &= CBAUD;
 
 	switch (cflag) {
-	//FIXME more values?
 	case    B300: rate =     300; break;
 	case    B600: rate =     600; break;
 	case   B1200: rate =    1200; break;
@@ -273,7 +271,7 @@ static int gigaset_set_line_ctrl(struct
 	/* set the number of stop bits */
 	if (cflag & CSTOPB) {
 		if ((cflag & CSIZE) == CS5)
-			val |= 1; /* 1.5 stop bits */ //FIXME is this okay?
+			val |= 1; /* 1.5 stop bits */
 		else
 			val |= 2; /* 2 stop bits */
 	}
@@ -282,7 +280,7 @@ static int gigaset_set_line_ctrl(struct
 }
 
 
- /*================================================================================================================*/
+/*============================================================================*/
 static int gigaset_init_bchannel(struct bc_state *bcs)
 {
 	/* nothing to do for M10x */
@@ -344,7 +342,6 @@ static void gigaset_modem_fill(unsigned
 			if (write_modem(cs) < 0) {
 				gig_dbg(DEBUG_OUTPUT,
 					"modem_fill: write_modem failed");
-				// FIXME should we tell the LL?
 				again = 1; /* no callback will be called! */
 			}
 		}
@@ -356,8 +353,8 @@ static void gigaset_modem_fill(unsigned
  */
 static void gigaset_read_int_callback(struct urb *urb)
 {
-	struct inbuf_t *inbuf = urb->context;
-	struct cardstate *cs = inbuf->cs;
+	struct cardstate *cs = urb->context;
+	struct inbuf_t *inbuf = cs->inbuf;
 	int status = urb->status;
 	int r;
 	unsigned numbytes;
@@ -368,7 +365,7 @@ static void gigaset_read_int_callback(st
 		numbytes = urb->actual_length;
 
 		if (numbytes) {
-			src = inbuf->rcvbuf;
+			src = cs->hw.usb->rcvbuf;
 			if (unlikely(*src))
 				dev_warn(cs->dev,
 				    "%s: There was no leading 0, but 0x%02x!\n",
@@ -440,7 +437,7 @@ static int send_cb(struct cardstate *cs,
 	struct cmdbuf_t *tcb;
 	unsigned long flags;
 	int count;
-	int status = -ENOENT; // FIXME
+	int status = -ENOENT;
 	struct usb_cardstate *ucs = cs->hw.usb;
 
 	do {
@@ -480,7 +477,9 @@ static int send_cb(struct cardstate *cs,
 			ucs->busy = 1;
 
 			spin_lock_irqsave(&cs->lock, flags);
-			status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV;
+			status = cs->connected ?
+				usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) :
+				-ENODEV;
 			spin_unlock_irqrestore(&cs->lock, flags);
 
 			if (status) {
@@ -510,8 +509,8 @@ static int gigaset_write_cmd(struct card
 
 	if (len <= 0)
 		return 0;
-
-	if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
+	cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
+	if (!cb) {
 		dev_err(cs->dev, "%s: out of memory\n", __func__);
 		return -ENOMEM;
 	}
@@ -615,7 +614,7 @@ static int gigaset_initcshw(struct cards
 	ucs->bulk_out_urb = NULL;
 	ucs->read_urb = NULL;
 	tasklet_init(&cs->write_tasklet,
-		     &gigaset_modem_fill, (unsigned long) cs);
+		     gigaset_modem_fill, (unsigned long) cs);
 
 	return 1;
 }
@@ -637,9 +636,7 @@ static int write_modem(struct cardstate
 		return -EINVAL;
 	}
 
-	/* Copy data to bulk out buffer and  // FIXME copying not necessary
-	 * transmit data
-	 */
+	/* Copy data to bulk out buffer and transmit data */
 	count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
 	skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);
 	skb_pull(bcs->tx_skb, count);
@@ -650,7 +647,8 @@ static int write_modem(struct cardstate
 	if (cs->connected) {
 		usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
 				  usb_sndbulkpipe(ucs->udev,
-						  ucs->bulk_out_endpointAddr & 0x0f),
+						  ucs->bulk_out_endpointAddr &
+						  0x0f),
 				  ucs->bulk_out_buffer, count,
 				  gigaset_write_bulk_callback, cs);
 		ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);
@@ -666,7 +664,7 @@ static int write_modem(struct cardstate
 
 	if (!bcs->tx_skb->len) {
 		/* skb sent completely */
-		gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0?
+		gigaset_skb_sent(bcs, bcs->tx_skb);
 
 		gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",
 			(unsigned long) bcs->tx_skb);
@@ -763,8 +761,8 @@ static int gigaset_probe(struct usb_inte
 	buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 	ucs->rcvbuf_size = buffer_size;
 	ucs->int_in_endpointAddr = endpoint->bEndpointAddress;
-	cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL);
-	if (!cs->inbuf[0].rcvbuf) {
+	ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL);
+	if (!ucs->rcvbuf) {
 		dev_err(cs->dev, "Couldn't allocate rcvbuf\n");
 		retval = -ENOMEM;
 		goto error;
@@ -773,9 +771,9 @@ static int gigaset_probe(struct usb_inte
 	usb_fill_int_urb(ucs->read_urb, udev,
 			 usb_rcvintpipe(udev,
 					endpoint->bEndpointAddress & 0x0f),
-			 cs->inbuf[0].rcvbuf, buffer_size,
+			 ucs->rcvbuf, buffer_size,
 			 gigaset_read_int_callback,
-			 cs->inbuf + 0, endpoint->bInterval);
+			 cs, endpoint->bInterval);
 
 	retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL);
 	if (retval) {
@@ -789,7 +787,7 @@ static int gigaset_probe(struct usb_inte
 
 	if (!gigaset_start(cs)) {
 		tasklet_kill(&cs->write_tasklet);
-		retval = -ENODEV; //FIXME
+		retval = -ENODEV;
 		goto error;
 	}
 	return 0;
@@ -798,11 +796,11 @@ error:
 	usb_kill_urb(ucs->read_urb);
 	kfree(ucs->bulk_out_buffer);
 	usb_free_urb(ucs->bulk_out_urb);
-	kfree(cs->inbuf[0].rcvbuf);
+	kfree(ucs->rcvbuf);
 	usb_free_urb(ucs->read_urb);
 	usb_set_intfdata(interface, NULL);
 	ucs->read_urb = ucs->bulk_out_urb = NULL;
-	cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL;
+	ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
 	usb_put_dev(ucs->udev);
 	ucs->udev = NULL;
 	ucs->interface = NULL;
@@ -831,10 +829,10 @@ static void gigaset_disconnect(struct us
 
 	kfree(ucs->bulk_out_buffer);
 	usb_free_urb(ucs->bulk_out_urb);
-	kfree(cs->inbuf[0].rcvbuf);
+	kfree(ucs->rcvbuf);
 	usb_free_urb(ucs->read_urb);
 	ucs->read_urb = ucs->bulk_out_urb = NULL;
-	cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL;
+	ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
 
 	usb_put_dev(ucs->udev);
 	ucs->interface = NULL;
@@ -916,9 +914,10 @@ static int __init usb_gigaset_init(void)
 	int result;
 
 	/* allocate memory for our driver state and intialize it */
-	if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
-				       GIGASET_MODULENAME, GIGASET_DEVNAME,
-				       &ops, THIS_MODULE)) == NULL)
+	driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
+				    GIGASET_MODULENAME, GIGASET_DEVNAME,
+				    &ops, THIS_MODULE);
+	if (driver == NULL)
 		goto error;
 
 	/* register this driver with the USB subsystem */
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/avm/avm_cs.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/avm_cs.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/avm/avm_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/avm/avm_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -108,10 +108,7 @@ static int avmcs_probe(struct pcmcia_dev
     p_dev->io.NumPorts2 = 0;
 
     /* Interrupt setup */
-    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -198,7 +195,6 @@ static int avmcs_config(struct pcmcia_de
 	 */
 	i = pcmcia_request_irq(link, &link->irq);
 	if (i != 0) {
-	    cs_error(link, RequestIRQ, i);
 	    /* undo */
 	    pcmcia_disable_device(link);
 	    break;
@@ -209,7 +205,6 @@ static int avmcs_config(struct pcmcia_de
 	  */
 	i = pcmcia_request_configuration(link, &link->conf);
 	if (i != 0) {
-	    cs_error(link, RequestConfiguration, i);
 	    pcmcia_disable_device(link);
 	    break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/eicon/di.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/di.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/eicon/di.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/di.c	2010-02-24 13:52:17.000000000 -0500
@@ -806,7 +806,7 @@ static void xdi_xlog_request (byte Adapt
           DELIVERY - indication entered isdn_rc function
           RNR=...  - application had returned RNR=... after the
                      look ahead callback
-          RNum=0   - aplication had not returned any buffer to copy
+          RNum=0   - application had not returned any buffer to copy
                      this indication and will copy it self
           COMPLETE - XDI had copied the data to the buffers provided
                      bu the application and is about to issue the
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/eicon/maintidi.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/maintidi.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/eicon/maintidi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/eicon/maintidi.c	2010-02-24 13:52:17.000000000 -0500
@@ -385,7 +385,7 @@ static int SuperTraceMessageInput (void*
                   }
                   break;
                 default:
-                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind);
+                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
               }
               p += (this_ind_length+1);
               total_length -= (4 + this_ind_length);
@@ -420,7 +420,7 @@ static int SuperTraceMessageInput (void*
             }
             break;
           default:
-            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind);
+            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
         }
       }
     }
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcmulti.c	2010-02-24 13:52:17.000000000 -0500
@@ -3152,7 +3152,7 @@ static void
 hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
     int slot_rx, int bank_rx)
 {
-	if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
+	if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
 		/* disable PCM */
 		mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
 		return;
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2010-02-24 13:52:17.000000000 -0500
@@ -721,7 +721,7 @@ hfcsusb_setup_bch(struct bchannel *bch,
 	switch (protocol) {
 	case (-1):	/* used for init */
 		bch->state = -1;
-		/* fall trough */
+		/* fall through */
 	case (ISDN_P_NONE):
 		if (bch->state == ISDN_P_NONE)
 			return 0; /* already in idle state */
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h	2010-02-24 13:52:17.000000000 -0500
@@ -150,7 +150,7 @@ symbolic(struct hfcusb_symbolic_list lis
 	for (i = 0; list[i].name != NULL; i++)
 		if (list[i].num == num)
 			return list[i].name;
-	return "<unkown USB Error>";
+	return "<unknown USB Error>";
 }
 
 /* USB descriptor need to contain one of the following EndPoint combination: */
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/mISDNisar.c	2010-02-24 13:52:17.000000000 -0500
@@ -860,7 +860,7 @@ isar_pump_statev_modem(struct isar_ch *c
 		pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
 		break;
 	default:
-		pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt);
+		pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/speedfax.c linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/speedfax.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hardware/mISDN/speedfax.c	2013-05-03 14:04:39.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hardware/mISDN/speedfax.c	2013-05-03 12:12:14.000000000 -0400
@@ -110,6 +110,7 @@ set_debug(const char *val, struct kernel
 MODULE_AUTHOR("Karsten Keil");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION(SPEEDFAX_REV);
+/*(DEBLOBBED)*/
 module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Speedfax debug mask");
 module_param(irqloops, uint, S_IRUGO | S_IWUSR);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hisax/avma1_cs.c linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avma1_cs.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hisax/avma1_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hisax/avma1_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA c
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -119,7 +103,7 @@ static int avma1cs_probe(struct pcmcia_d
 {
     local_info_t *local;
 
-    DEBUG(0, "avma1cs_attach()\n");
+    dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -136,10 +120,7 @@ static int avma1cs_probe(struct pcmcia_d
     p_dev->io.IOAddrLines = 5;
 
     /* Interrupt setup */
-    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -161,7 +142,7 @@ static int avma1cs_probe(struct pcmcia_d
 
 static void avma1cs_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "avma1cs_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
 	avma1cs_release(link);
 	kfree(link->priv);
 } /* avma1cs_detach */
@@ -203,7 +184,7 @@ static int avma1cs_config(struct pcmcia_
 
     dev = link->priv;
 
-    DEBUG(0, "avma1cs_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
 
     devname[0] = 0;
     if (link->prod_id[1])
@@ -218,7 +199,6 @@ static int avma1cs_config(struct pcmcia_
 	 */
 	i = pcmcia_request_irq(link, &link->irq);
 	if (i != 0) {
-	    cs_error(link, RequestIRQ, i);
 	    /* undo */
 	    pcmcia_disable_device(link);
 	    break;
@@ -229,7 +209,6 @@ static int avma1cs_config(struct pcmcia_
 	 */
 	i = pcmcia_request_configuration(link, &link->conf);
 	if (i != 0) {
-	    cs_error(link, RequestConfiguration, i);
 	    pcmcia_disable_device(link);
 	    break;
 	}
@@ -281,7 +260,7 @@ static void avma1cs_release(struct pcmci
 {
 	local_info_t *local = link->priv;
 
-	DEBUG(0, "avma1cs_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
 
 	/* now unregister function with hisax */
 	HiSax_closecard(local->node.minor);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hisax/elsa_cs.c linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_cs.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hisax/elsa_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hisax/elsa_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA c
 MODULE_AUTHOR("Klaus Lichtenwalder");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -142,7 +125,7 @@ static int elsa_cs_probe(struct pcmcia_d
 {
     local_info_t *local;
 
-    DEBUG(0, "elsa_cs_attach()\n");
+    dev_dbg(&link->dev, "elsa_cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -154,8 +137,7 @@ static int elsa_cs_probe(struct pcmcia_d
     local->cardnr = -1;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = NULL;
 
     /*
@@ -188,7 +170,7 @@ static void elsa_cs_detach(struct pcmcia
 {
 	local_info_t *info = link->priv;
 
-	DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
 
 	info->busy = 1;
 	elsa_cs_release(link);
@@ -231,30 +213,25 @@ static int elsa_cs_configcheck(struct pc
 static int elsa_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i, last_fn;
+    int i;
     IsdnCard_t icard;
 
-    DEBUG(0, "elsa_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
     dev = link->priv;
 
     i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
-    if (i != 0) {
-	last_fn = RequestIO;
-	goto cs_failed;
-    }
+    if (i != 0)
+	goto failed;
 
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0) {
         link->irq.AssignedIRQ = 0;
-	last_fn = RequestIRQ;
-        goto cs_failed;
+	goto failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != 0) {
-      last_fn = RequestConfiguration;
-      goto cs_failed;
-    }
+    if (i != 0)
+	goto failed;
 
     /* At this point, the dev_node_t structure(s) should be
        initialized and arranged in a linked list at link->dev. *//*  */
@@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_
     	((local_info_t*)link->priv)->cardnr = i;
 
     return 0;
-cs_failed:
-    cs_error(link, last_fn, i);
+failed:
     elsa_cs_release(link);
     return -ENODEV;
 } /* elsa_cs_config */
@@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmci
 {
     local_info_t *local = link->priv;
 
-    DEBUG(0, "elsa_cs_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
 
     if (local) {
     	if (local->cardnr >= 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hisax/hfc_usb.c linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_usb.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hisax/hfc_usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hisax/hfc_usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -1086,7 +1086,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_i
 			break;
 		default:
 			DBG(HFCUSB_DBG_STATES,
-			       "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr);
+			       "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr);
 			break;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hisax/sedlbauer_cs.c linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer_cs.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hisax/sedlbauer_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hisax/sedlbauer_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA c
 MODULE_AUTHOR("Marcus Niemann");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); 
-static char *version =
-"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 
 /*====================================================================*/
 
@@ -151,7 +133,7 @@ static int sedlbauer_probe(struct pcmcia
 {
     local_info_t *local;
 
-    DEBUG(0, "sedlbauer_attach()\n");
+    dev_dbg(&link->dev, "sedlbauer_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -162,8 +144,7 @@ static int sedlbauer_probe(struct pcmcia
     link->priv = local;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = NULL;
 
     /*
@@ -198,7 +179,7 @@ static int sedlbauer_probe(struct pcmcia
 
 static void sedlbauer_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
 
 	((local_info_t *)link->priv)->stop = 1;
 	sedlbauer_release(link);
@@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmc
     device available to the system.
     
 ======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int sedlbauer_config_check(struct pcmcia_device *p_dev,
 				  cistpl_cftable_entry_t *cfg,
 				  cistpl_cftable_entry_t *dflt,
@@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct
 		req->Base = mem->win[0].host_addr;
 		req->Size = mem->win[0].len;
 		req->AccessSpeed = 0;
-		if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+		if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
 			return -ENODEV;
 		map.Page = 0;
 		map.CardOffset = mem->win[0].card_addr;
-		if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+		if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
 			return -ENODEV;
 	}
 	return 0;
@@ -309,10 +287,10 @@ static int sedlbauer_config(struct pcmci
 {
     local_info_t *dev = link->priv;
     win_req_t *req;
-    int last_fn, last_ret;
+    int ret;
     IsdnCard_t  icard;
 
-    DEBUG(0, "sedlbauer_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
 
     req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
     if (!req)
@@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmci
       these things without consulting the CIS, and most client drivers
       will only use the CIS to fill in implementation-defined details.
     */
-    last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
-    if (last_ret)
+    ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
+    if (ret)
 	    goto failed;
 
     /*
@@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmci
        handler to the interrupt, unless the 'Handler' member of the
        irq structure is initialized.
     */
-    if (link->conf.Attributes & CONF_ENABLE_IRQ)
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+	    ret = pcmcia_request_irq(link, &link->irq);
+	    if (ret)
+		    goto failed;
+    }
 	
     /*
        This actually configures the PCMCIA socket -- setting up
        the I/O windows and the interrupt mapping, and putting the
        card and host interface into "Memory and IO" mode.
     */
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     /*
       At this point, the dev_node_t structure(s) need to be
@@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmci
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
     
-    last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
-    if (last_ret < 0) {
-    	printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
-    		last_ret, link->io.BasePort1);
+    ret = hisax_init_pcmcia(link, 
+			    &(((local_info_t *)link->priv)->stop), &icard);
+    if (ret < 0) {
+	printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
+		ret, link->io.BasePort1);
     	sedlbauer_release(link);
 	return -ENODEV;
     } else
-    	((local_info_t*)link->priv)->cardnr = last_ret;
+	((local_info_t *)link->priv)->cardnr = ret;
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     sedlbauer_release(link);
     return -ENODEV;
@@ -410,7 +392,7 @@ failed:
 static void sedlbauer_release(struct pcmcia_device *link)
 {
     local_info_t *local = link->priv;
-    DEBUG(0, "sedlbauer_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
 
     if (local) {
     	if (local->cardnr >= 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hisax/teles_cs.c linux-libre-2.6.33-gnu1/drivers/isdn/hisax/teles_cs.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/hisax/teles_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hisax/teles_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA c
 MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
 MODULE_LICENSE("GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -133,7 +116,7 @@ static int teles_probe(struct pcmcia_dev
 {
     local_info_t *local;
 
-    DEBUG(0, "teles_attach()\n");
+    dev_dbg(&link->dev, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -144,8 +127,7 @@ static int teles_probe(struct pcmcia_dev
     link->priv = local;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = NULL;
 
     /*
@@ -178,7 +160,7 @@ static void teles_detach(struct pcmcia_d
 {
 	local_info_t *info = link->priv;
 
-	DEBUG(0, "teles_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
 
 	info->busy = 1;
 	teles_cs_release(link);
@@ -221,30 +203,25 @@ static int teles_cs_configcheck(struct p
 static int teles_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i, last_fn;
+    int i;
     IsdnCard_t icard;
 
-    DEBUG(0, "teles_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
     dev = link->priv;
 
     i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
-    if (i != 0) {
-	last_fn = RequestIO;
+    if (i != 0)
 	goto cs_failed;
-    }
 
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0) {
         link->irq.AssignedIRQ = 0;
-	last_fn = RequestIRQ;
         goto cs_failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != 0) {
-      last_fn = RequestConfiguration;
+    if (i != 0)
       goto cs_failed;
-    }
 
     /* At this point, the dev_node_t structure(s) should be
        initialized and arranged in a linked list at link->dev. *//*  */
@@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia
     return 0;
 
 cs_failed:
-    cs_error(link, last_fn, i);
     teles_cs_release(link);
     return -ENODEV;
 } /* teles_cs_config */
@@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmc
 {
     local_info_t *local = link->priv;
 
-    DEBUG(0, "teles_cs_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
 
     if (local) {
     	if (local->cardnr >= 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/hysdn/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/hysdn/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/hysdn/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for HYSDN ISDN driver
-#
 config HYSDN
 	tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
 	depends on m && PROC_FS && PCI
@@ -15,4 +12,3 @@ config HYSDN_CAPI
 	depends on HYSDN && ISDN_CAPI
 	help
 	  Say Y here if you like to use Hypercope's CAPI 2.0 interface.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_net.c linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_net.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_net.c	2010-02-24 13:52:17.000000000 -0500
@@ -1563,7 +1563,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive
 	*(__be32 *)(p +  4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
 	*(__be32 *)(p +  8) = cpu_to_be32(lp->cisco_myseq);
 	*(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
-	*(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliablity, always 0xffff
+	*(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliability, always 0xffff
 	p += 18;
 
 	isdn_net_write_super(lp, skb);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_ppp.c linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ppp.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_ppp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ppp.c	2010-02-24 13:52:17.000000000 -0500
@@ -836,7 +836,7 @@ isdn_ppp_write(int min, struct file *fil
 			unsigned short hl;
 			struct sk_buff *skb;
 			/*
-			 * we need to reserve enought space in front of
+			 * we need to reserve enough space in front of
 			 * sk_buff. old call to dev_alloc_skb only reserved
 			 * 16 bytes, now we are looking what the driver want
 			 */
@@ -1326,7 +1326,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struc
 		struct sk_buff *new_skb;
 	        unsigned short hl;
 		/*
-		 * we need to reserve enought space in front of
+		 * we need to reserve enough space in front of
 		 * sk_buff. old call to dev_alloc_skb only reserved
 		 * 16 bytes, now we are looking what the driver want.
 		 */
@@ -1674,7 +1674,7 @@ static void isdn_ppp_mp_receive(isdn_net
 	 * - insert new fragment into the proper sequence slot (once that's done
 	 *   newfrag will be set to NULL)
 	 * - reassemble any complete fragment sequence (non-null 'start'
-	 *   indicates there is a continguous sequence present)
+	 *   indicates there is a contiguous sequence present)
 	 * - discard any incomplete sequences that are below minseq -- due
 	 *   to the fact that sender always increment sequence number, if there
 	 *   is an incomplete sequence below minseq, no new fragments would
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_ttyfax.c linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ttyfax.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/i4l/isdn_ttyfax.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/i4l/isdn_ttyfax.c	2010-02-24 13:52:17.000000000 -0500
@@ -470,7 +470,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_inf
 		}
 		return 0;
 	}
-	/* BADMUL=value - dummy 0=disable errorchk disabled (treshold multiplier) */
+	/* BADMUL=value - dummy 0=disable errorchk disabled (threshold multiplier) */
 	if (!strncmp(p[0], "BADMUL", 6)) {
 		p[0] += 6;
 		switch (*p[0]) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/icn/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/icn/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/icn/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/icn/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for ICN ISDN driver
-#
 config ISDN_DRV_ICN
 	tristate "ICN 2B and 4B support"
 	depends on ISA
@@ -13,4 +10,3 @@ config ISDN_DRV_ICN
 	  separately.  See <file:Documentation/isdn/README> and
 	  <file:Documentation/isdn/README.icn> for more
 	  information.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/dsp_core.c linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_core.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/dsp_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/dsp_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,7 @@
  * crossconnections and conferences via software if not possible through
  * hardware. If hardware capability is available, hardware is used.
  *
- * Echo: Is generated by CMX and is used to check performane of hard and
+ * Echo: Is generated by CMX and is used to check performance of hard and
  * software CMX.
  *
  * The CMX has special functions for conferences with one, two and more
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/l1oip_core.c linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/l1oip_core.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/l1oip_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/l1oip_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -661,7 +661,7 @@ l1oip_socket_thread(void *data)
 	size_t recvbuf_size = 1500;
 	int recvlen;
 	struct socket *socket = NULL;
-	DECLARE_COMPLETION(wait);
+	DECLARE_COMPLETION_ONSTACK(wait);
 
 	/* allocate buffer memory */
 	recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/socket.c linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/socket.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/socket.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/socket.c	2010-02-24 13:52:17.000000000 -0500
@@ -779,7 +779,7 @@ base_sock_create(struct net *net, struct
 }
 
 static int
-mISDN_sock_create(struct net *net, struct socket *sock, int proto)
+mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
 {
 	int err = -EPROTONOSUPPORT;
 
@@ -808,8 +808,7 @@ mISDN_sock_create(struct net *net, struc
 	return err;
 }
 
-static struct
-net_proto_family mISDN_sock_family_ops = {
+static const struct net_proto_family mISDN_sock_family_ops = {
 	.owner  = THIS_MODULE,
 	.family = PF_ISDN,
 	.create = mISDN_sock_create,
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/tei.c linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/tei.c
--- linux-libre-2.6.32-gnu1/drivers/isdn/mISDN/tei.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/mISDN/tei.c	2010-02-24 13:52:17.000000000 -0500
@@ -725,7 +725,7 @@ tei_id_ver_tout_net(struct FsmInst *fi,
 	if (tm->rcnt == 1) {
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi,
-			    "check req for tei %d sucessful\n", tm->l2->tei);
+			    "check req for tei %d successful\n", tm->l2->tei);
 		mISDN_FsmChangeState(fi, ST_TEI_NOP);
 	} else if (tm->rcnt > 1) {
 		/* duplicate assignment; remove */
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/pcbit/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/pcbit/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/pcbit/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for PCBIT ISDN driver
-#
 config ISDN_DRV_PCBIT
 	tristate "PCBIT-D support"
 	depends on ISA && (BROKEN || X86)
@@ -11,4 +8,3 @@ config ISDN_DRV_PCBIT
 	  the card using a utility which is distributed separately.  See
 	  <file:Documentation/isdn/README> and
 	  <file:Documentation/isdn/README.pcbit> for more information.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/isdn/sc/Kconfig linux-libre-2.6.33-gnu1/drivers/isdn/sc/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/isdn/sc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/isdn/sc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,3 @@
-#
-# Config.in for Spellcaster ISDN driver
-#
 config ISDN_DRV_SC
 	tristate "Spellcaster support"
 	depends on ISA
@@ -9,4 +6,3 @@ config ISDN_DRV_SC
 	  driver currently builds only in a modularized version.
 	  To build it, choose M here: the module will be called sc.
 	  See <file:Documentation/isdn/README.sc> for more information.
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/Kconfig linux-libre-2.6.33-gnu1/drivers/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/Kconfig
-
 menu "Device Drivers"
 
 source "drivers/base/Kconfig"
@@ -30,7 +28,7 @@ source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
 
-source "drivers/ieee1394/Kconfig"
+source "drivers/firewire/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
 
@@ -98,6 +96,8 @@ source "drivers/edac/Kconfig"
 
 source "drivers/rtc/Kconfig"
 
+source "drivers/clocksource/Kconfig"
+
 source "drivers/dma/Kconfig"
 
 source "drivers/dca/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/Kconfig linux-libre-2.6.33-gnu1/drivers/leds/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/leds/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -229,6 +229,12 @@ config LEDS_PWM
 	help
 	  This option enables support for pwm driven LEDs
 
+config LEDS_REGULATOR
+	tristate "REGULATOR driven LED support"
+	depends on LEDS_CLASS && REGULATOR
+	help
+	  This option enables support for regulator driven LEDs.
+
 config LEDS_BD2802
 	tristate "LED driver for BD2802 RGB LED"
 	depends on LEDS_CLASS && I2C
@@ -236,6 +242,33 @@ config LEDS_BD2802
 	  This option enables support for BD2802GU RGB LED driver chips
 	  accessed via the I2C bus.
 
+config LEDS_INTEL_SS4200
+	tristate "LED driver for Intel NAS SS4200 series"
+	depends on LEDS_CLASS && PCI && DMI
+	help
+	  This option enables support for the Intel SS4200 series of
+	  Network Attached Storage servers.  You may control the hard
+	  drive or power LEDs on the front panel.  Using this driver
+	  can stop the front LED from blinking after startup.
+
+config LEDS_LT3593
+	tristate "LED driver for LT3593 controllers"
+	depends on LEDS_CLASS && GENERIC_GPIO
+	help
+	  This option enables support for LEDs driven by a Linear Technology
+	  LT3593 controller. This controller uses a special one-wire pulse
+	  coding protocol to set the brightness.
+
+config LEDS_ADP5520
+	tristate "LED Support for ADP5520/ADP5501 PMIC"
+	depends on LEDS_CLASS && PMIC_ADP5520
+	help
+	  This option enables support for on-chip LED drivers found
+	  on Analog Devices ADP5520/ADP5501 PMICs.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called leds-adp5520.
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/led-class.c linux-libre-2.6.33-gnu1/drivers/leds/led-class.c
--- linux-libre-2.6.32-gnu1/drivers/leds/led-class.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/led-class.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,7 @@ static ssize_t led_brightness_store(stru
 	unsigned long state = simple_strtoul(buf, &after, 10);
 	size_t count = after - buf;
 
-	if (*after && isspace(*after))
+	if (isspace(*after))
 		count++;
 
 	if (count == size) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-adp5520.c linux-libre-2.6.33-gnu1/drivers/leds/leds-adp5520.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-adp5520.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-adp5520.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,230 @@
+/*
+ * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Loosely derived from leds-da903x:
+ * Copyright (C) 2008 Compulab, Ltd.
+ * 	Mike Rapoport <mike@compulab.co.il>
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.com>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/workqueue.h>
+#include <linux/mfd/adp5520.h>
+
+struct adp5520_led {
+	struct led_classdev	cdev;
+	struct work_struct	work;
+	struct device		*master;
+	enum led_brightness	new_brightness;
+	int			id;
+	int			flags;
+};
+
+static void adp5520_led_work(struct work_struct *work)
+{
+	struct adp5520_led *led = container_of(work, struct adp5520_led, work);
+	adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1,
+			 led->new_brightness >> 2);
+}
+
+static void adp5520_led_set(struct led_classdev *led_cdev,
+			   enum led_brightness value)
+{
+	struct adp5520_led *led;
+
+	led = container_of(led_cdev, struct adp5520_led, cdev);
+	led->new_brightness = value;
+	schedule_work(&led->work);
+}
+
+static int adp5520_led_setup(struct adp5520_led *led)
+{
+	struct device *dev = led->master;
+	int flags = led->flags;
+	int ret = 0;
+
+	switch (led->id) {
+	case FLAG_ID_ADP5520_LED1_ADP5501_LED0:
+		ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
+					(flags >> ADP5520_FLAG_OFFT_SHIFT) &
+					ADP5520_FLAG_OFFT_MASK);
+		ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
+					ADP5520_LED1_EN);
+		break;
+	case FLAG_ID_ADP5520_LED2_ADP5501_LED1:
+		ret |= adp5520_set_bits(dev,  ADP5520_LED_TIME,
+					((flags >> ADP5520_FLAG_OFFT_SHIFT) &
+					ADP5520_FLAG_OFFT_MASK) << 2);
+		ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
+					 ADP5520_R3_MODE);
+		ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
+					ADP5520_LED2_EN);
+		break;
+	case FLAG_ID_ADP5520_LED3_ADP5501_LED2:
+		ret |= adp5520_set_bits(dev,  ADP5520_LED_TIME,
+					((flags >> ADP5520_FLAG_OFFT_SHIFT) &
+					ADP5520_FLAG_OFFT_MASK) << 4);
+		ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
+					ADP5520_C3_MODE);
+		ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
+					ADP5520_LED3_EN);
+		break;
+	}
+
+	return ret;
+}
+
+static int __devinit adp5520_led_prepare(struct platform_device *pdev)
+{
+	struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
+	struct device *dev = pdev->dev.parent;
+	int ret = 0;
+
+	ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0);
+	ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0);
+	ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0);
+	ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6);
+	ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in,
+		 pdata->fade_out));
+
+	return ret;
+}
+
+static int __devinit adp5520_led_probe(struct platform_device *pdev)
+{
+	struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
+	struct adp5520_led *led, *led_dat;
+	struct led_info *cur_led;
+	int ret, i;
+
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "missing platform data\n");
+		return -ENODEV;
+	}
+
+	if (pdata->num_leds > ADP5520_01_MAXLEDS) {
+		dev_err(&pdev->dev, "can't handle more than %d LEDS\n",
+				 ADP5520_01_MAXLEDS);
+		return -EFAULT;
+	}
+
+	led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
+	if (led == NULL) {
+		dev_err(&pdev->dev, "failed to alloc memory\n");
+		return -ENOMEM;
+	}
+
+	ret = adp5520_led_prepare(pdev);
+
+	if (ret) {
+		dev_err(&pdev->dev, "failed to write\n");
+		goto err_free;
+	}
+
+	for (i = 0; i < pdata->num_leds; ++i) {
+		cur_led = &pdata->leds[i];
+		led_dat = &led[i];
+
+		led_dat->cdev.name = cur_led->name;
+		led_dat->cdev.default_trigger = cur_led->default_trigger;
+		led_dat->cdev.brightness_set = adp5520_led_set;
+		led_dat->cdev.brightness = LED_OFF;
+
+		if (cur_led->flags & ADP5520_FLAG_LED_MASK)
+			led_dat->flags = cur_led->flags;
+		else
+			led_dat->flags = i + 1;
+
+		led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK;
+
+		led_dat->master = pdev->dev.parent;
+		led_dat->new_brightness = LED_OFF;
+
+		INIT_WORK(&led_dat->work, adp5520_led_work);
+
+		ret = led_classdev_register(led_dat->master, &led_dat->cdev);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register LED %d\n",
+				led_dat->id);
+			goto err;
+		}
+
+		ret = adp5520_led_setup(led_dat);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to write\n");
+			i++;
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, led);
+	return 0;
+
+err:
+	if (i > 0) {
+		for (i = i - 1; i >= 0; i--) {
+			led_classdev_unregister(&led[i].cdev);
+			cancel_work_sync(&led[i].work);
+		}
+	}
+
+err_free:
+	kfree(led);
+	return ret;
+}
+
+static int __devexit adp5520_led_remove(struct platform_device *pdev)
+{
+	struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data;
+	struct adp5520_led *led;
+	int i;
+
+	led = platform_get_drvdata(pdev);
+
+	adp5520_clr_bits(led->master, ADP5520_LED_CONTROL,
+		 ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN);
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		led_classdev_unregister(&led[i].cdev);
+		cancel_work_sync(&led[i].work);
+	}
+
+	kfree(led);
+	return 0;
+}
+
+static struct platform_driver adp5520_led_driver = {
+	.driver	= {
+		.name	= "adp5520-led",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= adp5520_led_probe,
+	.remove		= __devexit_p(adp5520_led_remove),
+};
+
+static int __init adp5520_led_init(void)
+{
+	return platform_driver_register(&adp5520_led_driver);
+}
+module_init(adp5520_led_init);
+
+static void __exit adp5520_led_exit(void)
+{
+	platform_driver_unregister(&adp5520_led_driver);
+}
+module_exit(adp5520_led_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:adp5520-led");
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-alix2.c linux-libre-2.6.33-gnu1/drivers/leds/leds-alix2.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-alix2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-alix2.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,11 +11,24 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/string.h>
+#include <linux/pci.h>
 
 static int force = 0;
 module_param(force, bool, 0444);
 MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs");
 
+#define MSR_LBAR_GPIO		0x5140000C
+#define CS5535_GPIO_SIZE	256
+
+static u32 gpio_base;
+
+static struct pci_device_id divil_pci[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS,  PCI_DEVICE_ID_NS_CS5535_ISA) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
+	{ } /* NULL entry */
+};
+MODULE_DEVICE_TABLE(pci, divil_pci);
+
 struct alix_led {
 	struct led_classdev cdev;
 	unsigned short port;
@@ -30,9 +43,9 @@ static void alix_led_set(struct led_clas
 		container_of(led_cdev, struct alix_led, cdev);
 
 	if (brightness)
-		outl(led_dev->on_value, led_dev->port);
+		outl(led_dev->on_value, gpio_base + led_dev->port);
 	else
-		outl(led_dev->off_value, led_dev->port);
+		outl(led_dev->off_value, gpio_base + led_dev->port);
 }
 
 static struct alix_led alix_leds[] = {
@@ -41,7 +54,7 @@ static struct alix_led alix_leds[] = {
 			.name = "alix:1",
 			.brightness_set = alix_led_set,
 		},
-		.port = 0x6100,
+		.port = 0x00,
 		.on_value = 1 << 22,
 		.off_value = 1 << 6,
 	},
@@ -50,7 +63,7 @@ static struct alix_led alix_leds[] = {
 			.name = "alix:2",
 			.brightness_set = alix_led_set,
 		},
-		.port = 0x6180,
+		.port = 0x80,
 		.on_value = 1 << 25,
 		.off_value = 1 << 9,
 	},
@@ -59,7 +72,7 @@ static struct alix_led alix_leds[] = {
 			.name = "alix:3",
 			.brightness_set = alix_led_set,
 		},
-		.port = 0x6180,
+		.port = 0x80,
 		.on_value = 1 << 27,
 		.off_value = 1 << 11,
 	},
@@ -101,64 +114,104 @@ static struct platform_driver alix_led_d
 	},
 };
 
-static int __init alix_present(void)
+static int __init alix_present(unsigned long bios_phys,
+				const char *alix_sig,
+				size_t alix_sig_len)
 {
-	const unsigned long bios_phys = 0x000f0000;
 	const size_t bios_len = 0x00010000;
-	const char alix_sig[] = "PC Engines ALIX.";
-	const size_t alix_sig_len = sizeof(alix_sig) - 1;
-
 	const char *bios_virt;
 	const char *scan_end;
 	const char *p;
-	int ret = 0;
+	char name[64];
 
 	if (force) {
 		printk(KERN_NOTICE "%s: forced to skip BIOS test, "
 		       "assume system has ALIX.2 style LEDs\n",
 		       KBUILD_MODNAME);
-		ret = 1;
-		goto out;
+		return 1;
 	}
 
 	bios_virt = phys_to_virt(bios_phys);
 	scan_end = bios_virt + bios_len - (alix_sig_len + 2);
 	for (p = bios_virt; p < scan_end; p++) {
 		const char *tail;
+		char *a;
 
-		if (memcmp(p, alix_sig, alix_sig_len) != 0) {
+		if (memcmp(p, alix_sig, alix_sig_len) != 0)
 			continue;
-		}
+
+		memcpy(name, p, sizeof(name));
+
+		/* remove the first \0 character from string */
+		a = strchr(name, '\0');
+		if (a)
+			*a = ' ';
+
+		/* cut the string at a newline */
+		a = strchr(name, '\r');
+		if (a)
+			*a = '\0';
 
 		tail = p + alix_sig_len;
-		if ((tail[0] == '2' || tail[0] == '3') && tail[1] == '\0') {
+		if ((tail[0] == '2' || tail[0] == '3')) {
 			printk(KERN_INFO
 			       "%s: system is recognized as \"%s\"\n",
-			       KBUILD_MODNAME, p);
-			ret = 1;
-			break;
+			       KBUILD_MODNAME, name);
+			return 1;
 		}
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 static struct platform_device *pdev;
 
-static int __init alix_led_init(void)
+static int __init alix_pci_led_init(void)
 {
-	int ret;
+	u32 low, hi;
 
-	if (!alix_present()) {
-		ret = -ENODEV;
-		goto out;
+	if (pci_dev_present(divil_pci) == 0) {
+		printk(KERN_WARNING KBUILD_MODNAME": DIVIL not found\n");
+		return -ENODEV;
 	}
 
-	/* enable output on GPIO for LED 1,2,3 */
-	outl(1 << 6, 0x6104);
-	outl(1 << 9, 0x6184);
-	outl(1 << 11, 0x6184);
+	/* Grab the GPIO I/O range */
+	rdmsr(MSR_LBAR_GPIO, low, hi);
+
+	/* Check the mask and whether GPIO is enabled (sanity check) */
+	if (hi != 0x0000f001) {
+		printk(KERN_WARNING KBUILD_MODNAME": GPIO not enabled\n");
+		return -ENODEV;
+	}
+
+	/* Mask off the IO base address */
+	gpio_base = low & 0x0000ff00;
+
+	if (!request_region(gpio_base, CS5535_GPIO_SIZE, KBUILD_MODNAME)) {
+		printk(KERN_ERR KBUILD_MODNAME": can't allocate I/O for GPIO\n");
+		return -ENODEV;
+	}
+
+	/* Set GPIO function to output */
+	outl(1 << 6, gpio_base + 0x04);
+	outl(1 << 9, gpio_base + 0x84);
+	outl(1 << 11, gpio_base + 0x84);
+
+	return 0;
+}
+
+static int __init alix_led_init(void)
+{
+	int ret = -ENODEV;
+	const char tinybios_sig[] = "PC Engines ALIX.";
+	const char coreboot_sig[] = "PC Engines\0ALIX.";
+
+	if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) ||
+	    alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1))
+		ret = alix_pci_led_init();
+
+	if (ret < 0)
+		return ret;
 
 	pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0);
 	if (!IS_ERR(pdev)) {
@@ -168,7 +221,6 @@ static int __init alix_led_init(void)
 	} else
 		ret = PTR_ERR(pdev);
 
-out:
 	return ret;
 }
 
@@ -176,6 +228,7 @@ static void __exit alix_led_exit(void)
 {
 	platform_device_unregister(pdev);
 	platform_driver_unregister(&alix_led_driver);
+	release_region(gpio_base, CS5535_GPIO_SIZE);
 }
 
 module_init(alix_led_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-ams-delta.c linux-libre-2.6.33-gnu1/drivers/leds/leds-ams-delta.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-ams-delta.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-ams-delta.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
-#include <mach/board-ams-delta.h>
+#include <plat/board-ams-delta.h>
 
 /*
  * Our context
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-cobalt-qube.c linux-libre-2.6.33-gnu1/drivers/leds/leds-cobalt-qube.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-cobalt-qube.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-cobalt-qube.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@ static struct led_classdev qube_front_le
 	.name			= "qube::front",
 	.brightness		= LED_FULL,
 	.brightness_set		= qube_front_led_set,
-	.default_trigger	= "ide-disk",
+	.default_trigger	= "default-on",
 };
 
 static int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
@@ -43,7 +43,7 @@ static int __devinit cobalt_qube_led_pro
 	if (!res)
 		return -EBUSY;
 
-	led_port = ioremap(res->start, res->end - res->start + 1);
+	led_port = ioremap(res->start, resource_size(res));
 	if (!led_port)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-cobalt-raq.c linux-libre-2.6.33-gnu1/drivers/leds/leds-cobalt-raq.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-cobalt-raq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-cobalt-raq.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,7 +84,7 @@ static int __devinit cobalt_raq_led_prob
 	if (!res)
 		return -EBUSY;
 
-	led_port = ioremap(res->start, res->end - res->start + 1);
+	led_port = ioremap(res->start, resource_size(res));
 	if (!led_port)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-fsg.c linux-libre-2.6.33-gnu1/drivers/leds/leds-fsg.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-fsg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-fsg.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,13 @@
 #include <mach/hardware.h>
 #include <asm/io.h>
 
+#define FSG_LED_WLAN_BIT	0
+#define FSG_LED_WAN_BIT		1
+#define FSG_LED_SATA_BIT	2
+#define FSG_LED_USB_BIT		4
+#define FSG_LED_RING_BIT	5
+#define FSG_LED_SYNC_BIT	7
+
 static short __iomem *latch_address;
 static unsigned short latch_value;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-locomo.c linux-libre-2.6.33-gnu1/drivers/leds/leds-locomo.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-locomo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-locomo.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@ static void locomoled_brightness_set1(st
 
 static struct led_classdev locomo_led0 = {
 	.name			= "locomo:amber:charge",
-	.default_trigger	= "sharpsl-charge",
+	.default_trigger	= "main-battery-charging",
 	.brightness_set		= locomoled_brightness_set0,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-lt3593.c linux-libre-2.6.33-gnu1/drivers/leds/leds-lt3593.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-lt3593.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-lt3593.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,217 @@
+/*
+ * LEDs driver for LT3593 controllers
+ *
+ * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on leds-gpio.c,
+ *
+ *   Copyright (C) 2007 8D Technologies inc.
+ *   Raphael Assenat <raph@8d.com>
+ *   Copyright (C) 2008 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+struct lt3593_led_data {
+	struct led_classdev cdev;
+	unsigned gpio;
+	struct work_struct work;
+	u8 new_level;
+};
+
+static void lt3593_led_work(struct work_struct *work)
+{
+	int pulses;
+	struct lt3593_led_data *led_dat =
+		container_of(work, struct lt3593_led_data, work);
+
+	/*
+	 * The LT3593 resets its internal current level register to the maximum
+	 * level on the first falling edge on the control pin. Each following
+	 * falling edge decreases the current level by 625uA. Up to 32 pulses
+	 * can be sent, so the maximum power reduction is 20mA.
+	 * After a timeout of 128us, the value is taken from the register and
+	 * applied is to the output driver.
+	 */
+
+	if (led_dat->new_level == 0) {
+		gpio_set_value_cansleep(led_dat->gpio, 0);
+		return;
+	}
+
+	pulses = 32 - (led_dat->new_level * 32) / 255;
+
+	if (pulses == 0) {
+		gpio_set_value_cansleep(led_dat->gpio, 0);
+		mdelay(1);
+		gpio_set_value_cansleep(led_dat->gpio, 1);
+		return;
+	}
+
+	gpio_set_value_cansleep(led_dat->gpio, 1);
+
+	while (pulses--) {
+		gpio_set_value_cansleep(led_dat->gpio, 0);
+		udelay(1);
+		gpio_set_value_cansleep(led_dat->gpio, 1);
+		udelay(1);
+	}
+}
+
+static void lt3593_led_set(struct led_classdev *led_cdev,
+	enum led_brightness value)
+{
+	struct lt3593_led_data *led_dat =
+		container_of(led_cdev, struct lt3593_led_data, cdev);
+
+	led_dat->new_level = value;
+	schedule_work(&led_dat->work);
+}
+
+static int __devinit create_lt3593_led(const struct gpio_led *template,
+	struct lt3593_led_data *led_dat, struct device *parent)
+{
+	int ret, state;
+
+	/* skip leds on GPIOs that aren't available */
+	if (!gpio_is_valid(template->gpio)) {
+		printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n",
+				KBUILD_MODNAME, template->gpio, template->name);
+		return 0;
+	}
+
+	ret = gpio_request(template->gpio, template->name);
+	if (ret < 0)
+		return ret;
+
+	led_dat->cdev.name = template->name;
+	led_dat->cdev.default_trigger = template->default_trigger;
+	led_dat->gpio = template->gpio;
+
+	led_dat->cdev.brightness_set = lt3593_led_set;
+
+	state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
+	led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
+
+	if (!template->retain_state_suspended)
+		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = gpio_direction_output(led_dat->gpio, state);
+	if (ret < 0)
+		goto err;
+
+	INIT_WORK(&led_dat->work, lt3593_led_work);
+
+	ret = led_classdev_register(parent, &led_dat->cdev);
+	if (ret < 0)
+		goto err;
+
+	printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n",
+		KBUILD_MODNAME, template->name, template->gpio);
+
+	return 0;
+
+err:
+	gpio_free(led_dat->gpio);
+	return ret;
+}
+
+static void delete_lt3593_led(struct lt3593_led_data *led)
+{
+	if (!gpio_is_valid(led->gpio))
+		return;
+
+	led_classdev_unregister(&led->cdev);
+	cancel_work_sync(&led->work);
+	gpio_free(led->gpio);
+}
+
+static int __devinit lt3593_led_probe(struct platform_device *pdev)
+{
+	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+	struct lt3593_led_data *leds_data;
+	int i, ret = 0;
+
+	if (!pdata)
+		return -EBUSY;
+
+	leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds,
+				GFP_KERNEL);
+	if (!leds_data)
+		return -ENOMEM;
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		ret = create_lt3593_led(&pdata->leds[i], &leds_data[i],
+				      &pdev->dev);
+		if (ret < 0)
+			goto err;
+	}
+
+	platform_set_drvdata(pdev, leds_data);
+
+	return 0;
+
+err:
+	for (i = i - 1; i >= 0; i--)
+		delete_lt3593_led(&leds_data[i]);
+
+	kfree(leds_data);
+
+	return ret;
+}
+
+static int __devexit lt3593_led_remove(struct platform_device *pdev)
+{
+	int i;
+	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+	struct lt3593_led_data *leds_data;
+
+	leds_data = platform_get_drvdata(pdev);
+
+	for (i = 0; i < pdata->num_leds; i++)
+		delete_lt3593_led(&leds_data[i]);
+
+	kfree(leds_data);
+
+	return 0;
+}
+
+static struct platform_driver lt3593_led_driver = {
+	.probe		= lt3593_led_probe,
+	.remove		= __devexit_p(lt3593_led_remove),
+	.driver		= {
+		.name	= "leds-lt3593",
+		.owner	= THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS("platform:leds-lt3593");
+
+static int __init lt3593_led_init(void)
+{
+	return platform_driver_register(&lt3593_led_driver);
+}
+
+static void __exit lt3593_led_exit(void)
+{
+	platform_driver_unregister(&lt3593_led_driver);
+}
+
+module_init(lt3593_led_init);
+module_exit(lt3593_led_exit);
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("LED driver for LT3593 controllers");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-pwm.c linux-libre-2.6.33-gnu1/drivers/leds/leds-pwm.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-pwm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-pwm.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,6 @@ struct led_pwm_data {
 	struct pwm_device	*pwm;
 	unsigned int 		active_low;
 	unsigned int		period;
-	unsigned int		max_brightness;
 };
 
 static void led_pwm_set(struct led_classdev *led_cdev,
@@ -35,7 +34,7 @@ static void led_pwm_set(struct led_class
 {
 	struct led_pwm_data *led_dat =
 		container_of(led_cdev, struct led_pwm_data, cdev);
-	unsigned int max = led_dat->max_brightness;
+	unsigned int max = led_dat->cdev.max_brightness;
 	unsigned int period =  led_dat->period;
 
 	if (brightness == 0) {
@@ -77,10 +76,10 @@ static int led_pwm_probe(struct platform
 		led_dat->cdev.name = cur_led->name;
 		led_dat->cdev.default_trigger = cur_led->default_trigger;
 		led_dat->active_low = cur_led->active_low;
-		led_dat->max_brightness = cur_led->max_brightness;
 		led_dat->period = cur_led->pwm_period_ns;
 		led_dat->cdev.brightness_set = led_pwm_set;
 		led_dat->cdev.brightness = LED_OFF;
+		led_dat->cdev.max_brightness = cur_led->max_brightness;
 		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 
 		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-regulator.c linux-libre-2.6.33-gnu1/drivers/leds/leds-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,242 @@
+/*
+ * leds-regulator.c - LED class driver for regulator driven LEDs.
+ *
+ * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * Inspired by leds-wm8350 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include <linux/leds-regulator.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#define to_regulator_led(led_cdev) \
+	container_of(led_cdev, struct regulator_led, cdev)
+
+struct regulator_led {
+	struct led_classdev cdev;
+	enum led_brightness value;
+	int enabled;
+	struct mutex mutex;
+	struct work_struct work;
+
+	struct regulator *vcc;
+};
+
+static inline int led_regulator_get_max_brightness(struct regulator *supply)
+{
+	int ret;
+	int voltage = regulator_list_voltage(supply, 0);
+
+	if (voltage <= 0)
+		return 1;
+
+	/* even if regulator can't change voltages,
+	 * we still assume it can change status
+	 * and the LED can be turned on and off.
+	 */
+	ret = regulator_set_voltage(supply, voltage, voltage);
+	if (ret < 0)
+		return 1;
+
+	return regulator_count_voltages(supply);
+}
+
+static int led_regulator_get_voltage(struct regulator *supply,
+		enum led_brightness brightness)
+{
+	if (brightness == 0)
+		return -EINVAL;
+
+	return regulator_list_voltage(supply, brightness - 1);
+}
+
+
+static void regulator_led_enable(struct regulator_led *led)
+{
+	int ret;
+
+	if (led->enabled)
+		return;
+
+	ret = regulator_enable(led->vcc);
+	if (ret != 0) {
+		dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret);
+		return;
+	}
+
+	led->enabled = 1;
+}
+
+static void regulator_led_disable(struct regulator_led *led)
+{
+	int ret;
+
+	if (!led->enabled)
+		return;
+
+	ret = regulator_disable(led->vcc);
+	if (ret != 0) {
+		dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret);
+		return;
+	}
+
+	led->enabled = 0;
+}
+
+static void regulator_led_set_value(struct regulator_led *led)
+{
+	int voltage;
+	int ret;
+
+	mutex_lock(&led->mutex);
+
+	if (led->value == LED_OFF) {
+		regulator_led_disable(led);
+		goto out;
+	}
+
+	if (led->cdev.max_brightness > 1) {
+		voltage = led_regulator_get_voltage(led->vcc, led->value);
+		dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n",
+				led->value, voltage);
+
+		ret = regulator_set_voltage(led->vcc, voltage, voltage);
+		if (ret != 0)
+			dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n",
+				voltage, ret);
+	}
+
+	regulator_led_enable(led);
+
+out:
+	mutex_unlock(&led->mutex);
+}
+
+static void led_work(struct work_struct *work)
+{
+	struct regulator_led *led;
+
+	led = container_of(work, struct regulator_led, work);
+	regulator_led_set_value(led);
+}
+
+static void regulator_led_brightness_set(struct led_classdev *led_cdev,
+			   enum led_brightness value)
+{
+	struct regulator_led *led = to_regulator_led(led_cdev);
+
+	led->value = value;
+	schedule_work(&led->work);
+}
+
+static int __devinit regulator_led_probe(struct platform_device *pdev)
+{
+	struct led_regulator_platform_data *pdata = pdev->dev.platform_data;
+	struct regulator_led *led;
+	struct regulator *vcc;
+	int ret = 0;
+
+	if (pdata == NULL) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -ENODEV;
+	}
+
+	vcc = regulator_get_exclusive(&pdev->dev, "vled");
+	if (IS_ERR(vcc)) {
+		dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
+		return PTR_ERR(vcc);
+	}
+
+	led = kzalloc(sizeof(*led), GFP_KERNEL);
+	if (led == NULL) {
+		ret = -ENOMEM;
+		goto err_vcc;
+	}
+
+	led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
+	if (pdata->brightness > led->cdev.max_brightness) {
+		dev_err(&pdev->dev, "Invalid default brightness %d\n",
+				pdata->brightness);
+		ret = -EINVAL;
+		goto err_led;
+	}
+	led->value = pdata->brightness;
+
+	led->cdev.brightness_set = regulator_led_brightness_set;
+	led->cdev.name = pdata->name;
+	led->cdev.flags |= LED_CORE_SUSPENDRESUME;
+	led->vcc = vcc;
+
+	mutex_init(&led->mutex);
+	INIT_WORK(&led->work, led_work);
+
+	platform_set_drvdata(pdev, led);
+
+	ret = led_classdev_register(&pdev->dev, &led->cdev);
+	if (ret < 0) {
+		cancel_work_sync(&led->work);
+		goto err_led;
+	}
+
+	/* to expose the default value to userspace */
+	led->cdev.brightness = led->value;
+
+	/* Set the default led status */
+	regulator_led_set_value(led);
+
+	return 0;
+
+err_led:
+	kfree(led);
+err_vcc:
+	regulator_put(vcc);
+	return ret;
+}
+
+static int __devexit regulator_led_remove(struct platform_device *pdev)
+{
+	struct regulator_led *led = platform_get_drvdata(pdev);
+
+	led_classdev_unregister(&led->cdev);
+	cancel_work_sync(&led->work);
+	regulator_led_disable(led);
+	regulator_put(led->vcc);
+	kfree(led);
+	return 0;
+}
+
+static struct platform_driver regulator_led_driver = {
+	.driver = {
+		   .name  = "leds-regulator",
+		   .owner = THIS_MODULE,
+		   },
+	.probe  = regulator_led_probe,
+	.remove = __devexit_p(regulator_led_remove),
+};
+
+static int __init regulator_led_init(void)
+{
+	return platform_driver_register(&regulator_led_driver);
+}
+module_init(regulator_led_init);
+
+static void __exit regulator_led_exit(void)
+{
+	platform_driver_unregister(&regulator_led_driver);
+}
+module_exit(regulator_led_exit);
+
+MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
+MODULE_DESCRIPTION("Regulator driven LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-regulator");
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/leds-ss4200.c linux-libre-2.6.33-gnu1/drivers/leds/leds-ss4200.c
--- linux-libre-2.6.32-gnu1/drivers/leds/leds-ss4200.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/leds-ss4200.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,556 @@
+/*
+ * SS4200-E Hardware API
+ * Copyright (c) 2009, Intel Corporation.
+ * Copyright IBM Corporation, 2009
+ *
+ * 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.
+ *
+ * Author: Dave Hansen <dave@sr71.net>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/dmi.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
+MODULE_AUTHOR("Rodney Girod <rgirod@confocus.com>, Dave Hansen <dave@sr71.net>");
+MODULE_DESCRIPTION("Intel NAS/Home Server ICH7 GPIO Driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * ICH7 LPC/GPIO PCI Config register offsets
+ */
+#define PMBASE		0x040
+#define GPIO_BASE	0x048
+#define GPIO_CTRL	0x04c
+#define GPIO_EN		0x010
+
+/*
+ * The ICH7 GPIO register block is 64 bytes in size.
+ */
+#define ICH7_GPIO_SIZE	64
+
+/*
+ * Define register offsets within the ICH7 register block.
+ */
+#define GPIO_USE_SEL	0x000
+#define GP_IO_SEL	0x004
+#define GP_LVL		0x00c
+#define GPO_BLINK	0x018
+#define GPI_INV		0x030
+#define GPIO_USE_SEL2	0x034
+#define GP_IO_SEL2	0x038
+#define GP_LVL2		0x03c
+
+/*
+ * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
+ */
+static struct pci_device_id ich7_lpc_pci_id[] =
+{
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) },
+	{ } /* NULL entry */
+};
+
+MODULE_DEVICE_TABLE(pci, ich7_lpc_pci_id);
+
+static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id)
+{
+	pr_info("detected '%s'\n", id->ident);
+	return 1;
+}
+
+static unsigned int __initdata nodetect;
+module_param_named(nodetect, nodetect, bool, 0);
+MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
+
+/*
+ * struct nas_led_whitelist - List of known good models
+ *
+ * Contains the known good models this driver is compatible with.
+ * When adding a new model try to be as strict as possible. This
+ * makes it possible to keep the false positives (the model is
+ * detected as working, but in reality it is not) as low as
+ * possible.
+ */
+static struct dmi_system_id __initdata nas_led_whitelist[] = {
+	{
+		.callback = ss4200_led_dmi_callback,
+		.ident = "Intel SS4200-E",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "SS4200-E"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
+		}
+	},
+};
+
+/*
+ * Base I/O address assigned to the Power Management register block
+ */
+static u32 g_pm_io_base;
+
+/*
+ * Base I/O address assigned to the ICH7 GPIO register block
+ */
+static u32 nas_gpio_io_base;
+
+/*
+ * When we successfully register a region, we are returned a resource.
+ * We use these to identify which regions we need to release on our way
+ * back out.
+ */
+static struct resource *gp_gpio_resource;
+
+struct nasgpio_led {
+	char *name;
+	u32 gpio_bit;
+	struct led_classdev led_cdev;
+};
+
+/*
+ * gpio_bit(s) are the ICH7 GPIO bit assignments
+ */
+static struct nasgpio_led nasgpio_leds[] = {
+	{ .name = "hdd1:blue:sata",	.gpio_bit = 0 },
+	{ .name = "hdd1:amber:sata",	.gpio_bit = 1 },
+	{ .name = "hdd2:blue:sata",	.gpio_bit = 2 },
+	{ .name = "hdd2:amber:sata",	.gpio_bit = 3 },
+	{ .name = "hdd3:blue:sata",	.gpio_bit = 4 },
+	{ .name = "hdd3:amber:sata",	.gpio_bit = 5 },
+	{ .name = "hdd4:blue:sata",	.gpio_bit = 6 },
+	{ .name = "hdd4:amber:sata",	.gpio_bit = 7 },
+	{ .name = "power:blue:power",	.gpio_bit = 27},
+	{ .name = "power:amber:power",  .gpio_bit = 28},
+};
+
+#define NAS_RECOVERY	0x00000400	/* GPIO10 */
+
+static struct nasgpio_led *
+led_classdev_to_nasgpio_led(struct led_classdev *led_cdev)
+{
+	return container_of(led_cdev, struct nasgpio_led, led_cdev);
+}
+
+static struct nasgpio_led *get_led_named(char *name)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) {
+		if (strcmp(nasgpio_leds[i].name, name))
+			continue;
+		return &nasgpio_leds[i];
+	}
+	return NULL;
+}
+
+/*
+ * This protects access to the gpio ports.
+ */
+static DEFINE_SPINLOCK(nasgpio_gpio_lock);
+
+/*
+ * There are two gpio ports, one for blinking and the other
+ * for power.  @port tells us if we're doing blinking or
+ * power control.
+ *
+ * Caller must hold nasgpio_gpio_lock
+ */
+static void __nasgpio_led_set_attr(struct led_classdev *led_cdev,
+				   u32 port, u32 value)
+{
+	struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev);
+	u32 gpio_out;
+
+	gpio_out = inl(nas_gpio_io_base + port);
+	if (value)
+		gpio_out |= (1<<led->gpio_bit);
+	else
+		gpio_out &= ~(1<<led->gpio_bit);
+
+	outl(gpio_out, nas_gpio_io_base + port);
+}
+
+static void nasgpio_led_set_attr(struct led_classdev *led_cdev,
+				 u32 port, u32 value)
+{
+	spin_lock(&nasgpio_gpio_lock);
+	__nasgpio_led_set_attr(led_cdev, port, value);
+	spin_unlock(&nasgpio_gpio_lock);
+}
+
+u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port)
+{
+	struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev);
+	u32 gpio_in;
+
+	spin_lock(&nasgpio_gpio_lock);
+	gpio_in = inl(nas_gpio_io_base + port);
+	spin_unlock(&nasgpio_gpio_lock);
+	if (gpio_in & (1<<led->gpio_bit))
+		return 1;
+	return 0;
+}
+
+/*
+ * There is actual brightness control in the hardware,
+ * but it is via smbus commands and not implemented
+ * in this driver.
+ */
+static void nasgpio_led_set_brightness(struct led_classdev *led_cdev,
+				       enum led_brightness brightness)
+{
+	u32 setting = 0;
+	if (brightness >= LED_HALF)
+		setting = 1;
+	/*
+	 * Hold the lock across both operations.  This ensures
+	 * consistency so that both the "turn off blinking"
+	 * and "turn light off" operations complete as a set.
+	 */
+	spin_lock(&nasgpio_gpio_lock);
+	/*
+	 * LED class documentation asks that past blink state
+	 * be disabled when brightness is turned to zero.
+	 */
+	if (brightness == 0)
+		__nasgpio_led_set_attr(led_cdev, GPO_BLINK, 0);
+	__nasgpio_led_set_attr(led_cdev, GP_LVL, setting);
+	spin_unlock(&nasgpio_gpio_lock);
+}
+
+static int nasgpio_led_set_blink(struct led_classdev *led_cdev,
+				 unsigned long *delay_on,
+				 unsigned long *delay_off)
+{
+	u32 setting = 1;
+	if (!(*delay_on == 0 && *delay_off == 0) &&
+	    !(*delay_on == 500 && *delay_off == 500))
+		return -EINVAL;
+	/*
+	 * These are very approximate.
+	 */
+	*delay_on = 500;
+	*delay_off = 500;
+
+	nasgpio_led_set_attr(led_cdev, GPO_BLINK, setting);
+
+	return 0;
+}
+
+
+/*
+ * Initialize the ICH7 GPIO registers for NAS usage.  The BIOS should have
+ * already taken care of this, but we will do so in a non destructive manner
+ * so that we have what we need whether the BIOS did it or not.
+ */
+static int __devinit ich7_gpio_init(struct device *dev)
+{
+	int i;
+	u32 config_data = 0;
+	u32 all_nas_led = 0;
+
+	for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++)
+		all_nas_led |= (1<<nasgpio_leds[i].gpio_bit);
+
+	spin_lock(&nasgpio_gpio_lock);
+	/*
+	 * We need to enable all of the GPIO lines used by the NAS box,
+	 * so we will read the current Use Selection and add our usage
+	 * to it.  This should be benign with regard to the original
+	 * BIOS configuration.
+	 */
+	config_data = inl(nas_gpio_io_base + GPIO_USE_SEL);
+	dev_dbg(dev, ": Data read from GPIO_USE_SEL = 0x%08x\n", config_data);
+	config_data |= all_nas_led + NAS_RECOVERY;
+	outl(config_data, nas_gpio_io_base + GPIO_USE_SEL);
+	config_data = inl(nas_gpio_io_base + GPIO_USE_SEL);
+	dev_dbg(dev, ": GPIO_USE_SEL = 0x%08x\n\n", config_data);
+
+	/*
+	 * The LED GPIO outputs need to be configured for output, so we
+	 * will ensure that all LED lines are cleared for output and the
+	 * RECOVERY line ready for input.  This too should be benign with
+	 * regard to BIOS configuration.
+	 */
+	config_data = inl(nas_gpio_io_base + GP_IO_SEL);
+	dev_dbg(dev, ": Data read from GP_IO_SEL = 0x%08x\n",
+					config_data);
+	config_data &= ~all_nas_led;
+	config_data |= NAS_RECOVERY;
+	outl(config_data, nas_gpio_io_base + GP_IO_SEL);
+	config_data = inl(nas_gpio_io_base + GP_IO_SEL);
+	dev_dbg(dev, ": GP_IO_SEL = 0x%08x\n", config_data);
+
+	/*
+	 * In our final system, the BIOS will initialize the state of all
+	 * of the LEDs.  For now, we turn them all off (or Low).
+	 */
+	config_data = inl(nas_gpio_io_base + GP_LVL);
+	dev_dbg(dev, ": Data read from GP_LVL = 0x%08x\n", config_data);
+	/*
+	 * In our final system, the BIOS will initialize the blink state of all
+	 * of the LEDs.  For now, we turn blink off for all of them.
+	 */
+	config_data = inl(nas_gpio_io_base + GPO_BLINK);
+	dev_dbg(dev, ": Data read from GPO_BLINK = 0x%08x\n", config_data);
+
+	/*
+	 * At this moment, I am unsure if anything needs to happen with GPI_INV
+	 */
+	config_data = inl(nas_gpio_io_base + GPI_INV);
+	dev_dbg(dev, ": Data read from GPI_INV = 0x%08x\n", config_data);
+
+	spin_unlock(&nasgpio_gpio_lock);
+	return 0;
+}
+
+static void ich7_lpc_cleanup(struct device *dev)
+{
+	/*
+	 * If we were given exclusive use of the GPIO
+	 * I/O Address range, we must return it.
+	 */
+	if (gp_gpio_resource) {
+		dev_dbg(dev, ": Releasing GPIO I/O addresses\n");
+		release_region(nas_gpio_io_base, ICH7_GPIO_SIZE);
+		gp_gpio_resource = NULL;
+	}
+}
+
+/*
+ * The OS has determined that the LPC of the Intel ICH7 Southbridge is present
+ * so we can retrive the required operational information and prepare the GPIO.
+ */
+static struct pci_dev *nas_gpio_pci_dev;
+static int __devinit ich7_lpc_probe(struct pci_dev *dev,
+				    const struct pci_device_id *id)
+{
+	int status;
+	u32 gc = 0;
+
+	status = pci_enable_device(dev);
+	if (status) {
+		dev_err(&dev->dev, "pci_enable_device failed\n");
+		return -EIO;
+	}
+
+	nas_gpio_pci_dev = dev;
+	status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base);
+	if (status)
+		goto out;
+	g_pm_io_base &= 0x00000ff80;
+
+	status = pci_read_config_dword(dev, GPIO_CTRL, &gc);
+	if (!(GPIO_EN & gc)) {
+		status = -EEXIST;
+		dev_info(&dev->dev,
+			   "ERROR: The LPC GPIO Block has not been enabled.\n");
+		goto out;
+	}
+
+	status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base);
+	if (0 > status) {
+		dev_info(&dev->dev, "Unable to read GPIOBASE.\n");
+		goto out;
+	}
+	dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base);
+	nas_gpio_io_base &= 0x00000ffc0;
+
+	/*
+	 * Insure that we have exclusive access to the GPIO I/O address range.
+	 */
+	gp_gpio_resource = request_region(nas_gpio_io_base, ICH7_GPIO_SIZE,
+					  KBUILD_MODNAME);
+	if (NULL == gp_gpio_resource) {
+		dev_info(&dev->dev,
+			 "ERROR Unable to register GPIO I/O addresses.\n");
+		status = -1;
+		goto out;
+	}
+
+	/*
+	 * Initialize the GPIO for NAS/Home Server Use
+	 */
+	ich7_gpio_init(&dev->dev);
+
+out:
+	if (status) {
+		ich7_lpc_cleanup(&dev->dev);
+		pci_disable_device(dev);
+	}
+	return status;
+}
+
+static void ich7_lpc_remove(struct pci_dev *dev)
+{
+	ich7_lpc_cleanup(&dev->dev);
+	pci_disable_device(dev);
+}
+
+/*
+ * pci_driver structure passed to the PCI modules
+ */
+static struct pci_driver nas_gpio_pci_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = ich7_lpc_pci_id,
+	.probe = ich7_lpc_probe,
+	.remove = ich7_lpc_remove,
+};
+
+static struct led_classdev *get_classdev_for_led_nr(int nr)
+{
+	struct nasgpio_led *nas_led = &nasgpio_leds[nr];
+	struct led_classdev *led = &nas_led->led_cdev;
+	return led;
+}
+
+
+static void set_power_light_amber_noblink(void)
+{
+	struct nasgpio_led *amber = get_led_named("power:amber:power");
+	struct nasgpio_led *blue = get_led_named("power:blue:power");
+
+	if (!amber || !blue)
+		return;
+	/*
+	 * LED_OFF implies disabling future blinking
+	 */
+	pr_debug("setting blue off and amber on\n");
+
+	nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF);
+	nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL);
+}
+
+static ssize_t nas_led_blink_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	int blinking = 0;
+	if (nasgpio_led_get_attr(led, GPO_BLINK))
+		blinking = 1;
+	return sprintf(buf, "%u\n", blinking);
+}
+
+static ssize_t nas_led_blink_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t size)
+{
+	int ret;
+	struct led_classdev *led = dev_get_drvdata(dev);
+	unsigned long blink_state;
+
+	ret = strict_strtoul(buf, 10, &blink_state);
+	if (ret)
+		return ret;
+
+	nasgpio_led_set_attr(led, GPO_BLINK, blink_state);
+
+	return size;
+}
+
+static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store);
+
+static int register_nasgpio_led(int led_nr)
+{
+	int ret;
+	struct nasgpio_led *nas_led = &nasgpio_leds[led_nr];
+	struct led_classdev *led = get_classdev_for_led_nr(led_nr);
+
+	led->name = nas_led->name;
+	led->brightness = LED_OFF;
+	if (nasgpio_led_get_attr(led, GP_LVL))
+		led->brightness = LED_FULL;
+	led->brightness_set = nasgpio_led_set_brightness;
+	led->blink_set = nasgpio_led_set_blink;
+	ret = led_classdev_register(&nas_gpio_pci_dev->dev, led);
+	if (ret)
+		return ret;
+	ret = device_create_file(led->dev, &dev_attr_blink);
+	if (ret)
+		led_classdev_unregister(led);
+	return ret;
+}
+
+static void unregister_nasgpio_led(int led_nr)
+{
+	struct led_classdev *led = get_classdev_for_led_nr(led_nr);
+	led_classdev_unregister(led);
+	device_remove_file(led->dev, &dev_attr_blink);
+}
+/*
+ * module load/initialization
+ */
+static int __init nas_gpio_init(void)
+{
+	int i;
+	int ret = 0;
+	int nr_devices = 0;
+
+	nr_devices = dmi_check_system(nas_led_whitelist);
+	if (nodetect) {
+		pr_info("skipping hardware autodetection\n");
+		pr_info("Please send 'dmidecode' output to dave@sr71.net\n");
+		nr_devices++;
+	}
+
+	if (nr_devices <= 0) {
+		pr_info("no LED devices found\n");
+		return -ENODEV;
+	}
+
+	pr_info("registering PCI driver\n");
+	ret = pci_register_driver(&nas_gpio_pci_driver);
+	if (ret)
+		return ret;
+	for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) {
+		ret = register_nasgpio_led(i);
+		if (ret)
+			goto out_err;
+	}
+	/*
+	 * When the system powers on, the BIOS leaves the power
+	 * light blue and blinking.  This will turn it solid
+	 * amber once the driver is loaded.
+	 */
+	set_power_light_amber_noblink();
+	return 0;
+out_err:
+	for (; i >= 0; i--)
+		unregister_nasgpio_led(i);
+	pci_unregister_driver(&nas_gpio_pci_driver);
+	return ret;
+}
+
+/*
+ * module unload
+ */
+static void __exit nas_gpio_exit(void)
+{
+	int i;
+	pr_info("Unregistering driver\n");
+	for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++)
+		unregister_nasgpio_led(i);
+	pci_unregister_driver(&nas_gpio_pci_driver);
+}
+
+module_init(nas_gpio_init);
+module_exit(nas_gpio_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/ledtrig-timer.c linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-timer.c
--- linux-libre-2.6.32-gnu1/drivers/leds/ledtrig-timer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/ledtrig-timer.c	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,7 @@ static ssize_t led_delay_on_store(struct
 	unsigned long state = simple_strtoul(buf, &after, 10);
 	size_t count = after - buf;
 
-	if (*after && isspace(*after))
+	if (isspace(*after))
 		count++;
 
 	if (count == size) {
@@ -127,7 +127,7 @@ static ssize_t led_delay_off_store(struc
 	unsigned long state = simple_strtoul(buf, &after, 10);
 	size_t count = after - buf;
 
-	if (*after && isspace(*after))
+	if (isspace(*after))
 		count++;
 
 	if (count == size) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/leds/Makefile linux-libre-2.6.33-gnu1/drivers/leds/Makefile
--- linux-libre-2.6.32-gnu1/drivers/leds/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/leds/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,10 @@ obj-$(CONFIG_LEDS_DA903X)		+= leds-da903
 obj-$(CONFIG_LEDS_WM831X_STATUS)	+= leds-wm831x-status.o
 obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
 obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
+obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
+obj-$(CONFIG_LEDS_INTEL_SS4200)		+= leds-ss4200.o
+obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
+obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/lguest/segments.c linux-libre-2.6.33-gnu1/drivers/lguest/segments.c
--- linux-libre-2.6.32-gnu1/drivers/lguest/segments.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/lguest/segments.c	2010-02-24 13:52:17.000000000 -0500
@@ -179,8 +179,10 @@ void load_guest_gdt_entry(struct lg_cpu
 	 * We assume the Guest has the same number of GDT entries as the
 	 * Host, otherwise we'd have to dynamically allocate the Guest GDT.
 	 */
-	if (num >= ARRAY_SIZE(cpu->arch.gdt))
+	if (num >= ARRAY_SIZE(cpu->arch.gdt)) {
 		kill_guest(cpu, "too many gdt entries %i", num);
+		return;
+	}
 
 	/* Set it up, then fix it. */
 	cpu->arch.gdt[num].a = lo;
diff -druNp linux-libre-2.6.32-gnu1/drivers/lguest/x86/core.c linux-libre-2.6.33-gnu1/drivers/lguest/x86/core.c
--- linux-libre-2.6.32-gnu1/drivers/lguest/x86/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/lguest/x86/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,7 +69,7 @@ static struct lguest_pages *lguest_pages
 		  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
 }
 
-static DEFINE_PER_CPU(struct lg_cpu *, last_cpu);
+static DEFINE_PER_CPU(struct lg_cpu *, lg_last_cpu);
 
 /*S:010
  * We approach the Switcher.
@@ -90,8 +90,8 @@ static void copy_in_guest_info(struct lg
 	 * meanwhile).  If that's not the case, we pretend everything in the
 	 * Guest has changed.
 	 */
-	if (__get_cpu_var(last_cpu) != cpu || cpu->last_pages != pages) {
-		__get_cpu_var(last_cpu) = cpu;
+	if (__get_cpu_var(lg_last_cpu) != cpu || cpu->last_pages != pages) {
+		__get_cpu_var(lg_last_cpu) = cpu;
 		cpu->last_pages = pages;
 		cpu->changed = CHANGED_ALL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/ans-lcd.c linux-libre-2.6.33-gnu1/drivers/macintosh/ans-lcd.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/ans-lcd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/ans-lcd.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -26,6 +25,7 @@
 static unsigned long anslcd_short_delay = 80;
 static unsigned long anslcd_long_delay = 3280;
 static volatile unsigned char __iomem *anslcd_ptr;
+static DEFINE_MUTEX(anslcd_mutex);
 
 #undef DEBUG
 
@@ -65,26 +65,31 @@ anslcd_write( struct file * file, const
 
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
+
+	mutex_lock(&anslcd_mutex);
 	for ( i = *ppos; count > 0; ++i, ++p, --count ) 
 	{
 		char c;
 		__get_user(c, p);
 		anslcd_write_byte_data( c );
 	}
+	mutex_unlock(&anslcd_mutex);
 	*ppos = i;
 	return p - buf;
 }
 
-static int
-anslcd_ioctl( struct inode * inode, struct file * file,
-				unsigned int cmd, unsigned long arg )
+static long
+anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	char ch, __user *temp;
+	long ret = 0;
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
 #endif
 
+	mutex_lock(&anslcd_mutex);
+
 	switch ( cmd )
 	{
 	case ANSLCD_CLEAR:
@@ -93,7 +98,7 @@ anslcd_ioctl( struct inode * inode, stru
 		anslcd_write_byte_ctrl ( 0x06 );
 		anslcd_write_byte_ctrl ( 0x01 );
 		anslcd_write_byte_ctrl ( 0x02 );
-		return 0;
+		break;
 	case ANSLCD_SENDCTRL:
 		temp = (char __user *) arg;
 		__get_user(ch, temp);
@@ -101,33 +106,37 @@ anslcd_ioctl( struct inode * inode, stru
 			anslcd_write_byte_ctrl ( ch );
 			__get_user(ch, temp);
 		}
-		return 0;
+		break;
 	case ANSLCD_SETSHORTDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_short_delay=arg;
-		return 0;
+			ret =-EACCES;
+		else
+			anslcd_short_delay=arg;
+		break;
 	case ANSLCD_SETLONGDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_long_delay=arg;
-		return 0;
+			ret = -EACCES;
+		else
+			anslcd_long_delay=arg;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	mutex_unlock(&anslcd_mutex);
+	return ret;
 }
 
 static int
 anslcd_open( struct inode * inode, struct file * file )
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
 const struct file_operations anslcd_fops = {
-	.write	= anslcd_write,
-	.ioctl	= anslcd_ioctl,
-	.open	= anslcd_open,
+	.write		= anslcd_write,
+	.unlocked_ioctl	= anslcd_ioctl,
+	.open		= anslcd_open,
 };
 
 static struct miscdevice anslcd_dev = {
@@ -168,6 +177,7 @@ anslcd_init(void)
 	printk(KERN_DEBUG "LCD: init\n");
 #endif
 
+	mutex_lock(&anslcd_mutex);
 	anslcd_write_byte_ctrl ( 0x38 );
 	anslcd_write_byte_ctrl ( 0x0c );
 	anslcd_write_byte_ctrl ( 0x06 );
@@ -176,6 +186,7 @@ anslcd_init(void)
 	for(a=0;a<80;a++) {
 		anslcd_write_byte_data(anslcd_logo[a]);
 	}
+	mutex_unlock(&anslcd_mutex);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/mac_hid.c linux-libre-2.6.33-gnu1/drivers/macintosh/mac_hid.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/mac_hid.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/mac_hid.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,54 +27,49 @@ static int mouse_last_keycode;
 /* file(s) in /proc/sys/dev/mac_hid */
 static ctl_table mac_hid_files[] = {
 	{
-		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
 		.procname	= "mouse_button_emulation",
 		.data		= &mouse_emulate_buttons,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
 		.procname	= "mouse_button2_keycode",
 		.data		= &mouse_button2_keycode,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
 		.procname	= "mouse_button3_keycode",
 		.data		= &mouse_button3_keycode,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 /* dir in /proc/sys/dev */
 static ctl_table mac_hid_dir[] = {
 	{
-		.ctl_name	= DEV_MAC_HID,
 		.procname	= "mac_hid",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= mac_hid_files,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 /* /proc/sys/dev itself, in case that is not there yet */
 static ctl_table mac_hid_root_dir[] = {
 	{
-		.ctl_name	= CTL_DEV,
 		.procname	= "dev",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= mac_hid_dir,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static struct ctl_table_header *mac_hid_sysctl_header;
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/macio_asic.c linux-libre-2.6.33-gnu1/drivers/macintosh/macio_asic.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/macio_asic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/macio_asic.c	2010-02-24 13:52:17.000000000 -0500
@@ -379,6 +379,11 @@ static struct macio_dev * macio_add_one_
 	dev->ofdev.dev.parent = parent;
 	dev->ofdev.dev.bus = &macio_bus_type;
 	dev->ofdev.dev.release = macio_release_dev;
+	dev->ofdev.dev.dma_parms = &dev->dma_parms;
+
+	/* Standard DMA paremeters */
+	dma_set_max_seg_size(&dev->ofdev.dev, 65536);
+	dma_set_seg_boundary(&dev->ofdev.dev, 0xffffffff);
 
 #ifdef CONFIG_PCI
 	/* Set the DMA ops to the ones from the PCI device, this could be
@@ -538,6 +543,42 @@ void macio_unregister_driver(struct maci
 	driver_unregister(&drv->driver);
 }
 
+/* Managed MacIO resources */
+struct macio_devres {
+	u32	res_mask;
+};
+
+static void maciom_release(struct device *gendev, void *res)
+{
+	struct macio_dev *dev = to_macio_device(gendev);
+	struct macio_devres *dr = res;
+	int i, max;
+
+	max = min(dev->n_resources, 32);
+	for (i = 0; i < max; i++) {
+		if (dr->res_mask & (1 << i))
+			macio_release_resource(dev, i);
+	}
+}
+
+int macio_enable_devres(struct macio_dev *dev)
+{
+	struct macio_devres *dr;
+
+	dr = devres_find(&dev->ofdev.dev, maciom_release, NULL, NULL);
+	if (!dr) {
+		dr = devres_alloc(maciom_release, sizeof(*dr), GFP_KERNEL);
+		if (!dr)
+			return -ENOMEM;
+	}
+	return devres_get(&dev->ofdev.dev, dr, NULL, NULL) != NULL;
+}
+
+static struct macio_devres * find_macio_dr(struct macio_dev *dev)
+{
+	return devres_find(&dev->ofdev.dev, maciom_release, NULL, NULL);
+}
+
 /**
  *	macio_request_resource - Request an MMIO resource
  * 	@dev: pointer to the device holding the resource
@@ -555,6 +596,8 @@ void macio_unregister_driver(struct maci
 int macio_request_resource(struct macio_dev *dev, int resource_no,
 			   const char *name)
 {
+	struct macio_devres *dr = find_macio_dr(dev);
+
 	if (macio_resource_len(dev, resource_no) == 0)
 		return 0;
 		
@@ -562,6 +605,9 @@ int macio_request_resource(struct macio_
 				macio_resource_len(dev, resource_no),
 				name))
 		goto err_out;
+
+	if (dr && resource_no < 32)
+		dr->res_mask |= 1 << resource_no;
 	
 	return 0;
 
@@ -582,10 +628,14 @@ err_out:
  */
 void macio_release_resource(struct macio_dev *dev, int resource_no)
 {
+	struct macio_devres *dr = find_macio_dr(dev);
+
 	if (macio_resource_len(dev, resource_no) == 0)
 		return;
 	release_mem_region(macio_resource_start(dev, resource_no),
 			   macio_resource_len(dev, resource_no));
+	if (dr && resource_no < 32)
+		dr->res_mask &= ~(1 << resource_no);
 }
 
 /**
@@ -744,3 +794,5 @@ EXPORT_SYMBOL(macio_request_resource);
 EXPORT_SYMBOL(macio_release_resource);
 EXPORT_SYMBOL(macio_request_resources);
 EXPORT_SYMBOL(macio_release_resources);
+EXPORT_SYMBOL(macio_enable_devres);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/mediabay.c linux-libre-2.6.33-gnu1/drivers/macintosh/mediabay.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/mediabay.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/mediabay.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,15 +33,6 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
-
-#define MB_DEBUG
-
-#ifdef MB_DEBUG
-#define MBDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
-#else
-#define MBDBG(fmt, arg...)	do { } while (0)
-#endif
-
 #define MB_FCR32(bay, r)	((bay)->base + ((r) >> 2))
 #define MB_FCR8(bay, r)		(((volatile u8 __iomem *)((bay)->base)) + (r))
 
@@ -76,28 +67,14 @@ struct media_bay_info {
 	int				index;
 	int				cached_gpio;
 	int				sleeping;
+	int				user_lock;
 	struct mutex			lock;
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-	ide_hwif_t			*cd_port;
-	void __iomem			*cd_base;
-	int				cd_irq;
-	int				cd_retry;
-#endif
-#if defined(CONFIG_BLK_DEV_IDE_PMAC)
-	int 				cd_index;
-#endif
 };
 
 #define MAX_BAYS	2
 
 static struct media_bay_info media_bays[MAX_BAYS];
-int media_bay_count = 0;
-
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-/* check the busy bit in the media-bay ide interface
-   (assumes the media-bay contains an ide device) */
-#define MB_IDE_READY(i)	((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
-#endif
+static int media_bay_count = 0;
 
 /*
  * Wait that number of ms between each step in normal polling mode
@@ -130,21 +107,11 @@ int media_bay_count = 0;
 
 /*
  * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted
- * (or until the device is ready) before waiting for busy bit to disappear
+ * (or until the device is ready) before calling into the driver
  */
 #define MB_IDE_WAIT	1000
 
 /*
- * Timeout waiting for busy bit of an IDE device to go down
- */
-#define MB_IDE_TIMEOUT	5000
-
-/*
- * Max retries of the full power up/down sequence for an IDE device
- */
-#define MAX_CD_RETRIES	3
-
-/*
  * States of a media bay
  */
 enum {
@@ -153,7 +120,6 @@ enum {
 	mb_enabling_bay,	/* enable bits set, waiting MB_RESET_DELAY */
 	mb_resetting,		/* reset bit unset, waiting MB_SETUP_DELAY */
 	mb_ide_resetting,	/* IDE reset bit unser, waiting MB_IDE_WAIT */
-	mb_ide_waiting,		/* Waiting for BUSY bit to go away until MB_IDE_TIMEOUT */
 	mb_up,			/* Media bay full */
 	mb_powering_down	/* Powering down (avoid too fast down/up) */
 };
@@ -373,12 +339,12 @@ static inline void set_mb_power(struct m
 	if (onoff) {
 		bay->ops->power(bay, 1);
 		bay->state = mb_powering_up;
-		MBDBG("mediabay%d: powering up\n", bay->index);
+		pr_debug("mediabay%d: powering up\n", bay->index);
 	} else { 
 		/* Make sure everything is powered down & disabled */
 		bay->ops->power(bay, 0);
 		bay->state = mb_powering_down;
-		MBDBG("mediabay%d: powering down\n", bay->index);
+		pr_debug("mediabay%d: powering down\n", bay->index);
 	}
 	bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
 }
@@ -387,107 +353,118 @@ static void poll_media_bay(struct media_
 {
 	int id = bay->ops->content(bay);
 
-	if (id == bay->last_value) {
-		if (id != bay->content_id) {
-			bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
-			if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
-				/* If the device type changes without going thru
-				 * "MB_NO", we force a pass by "MB_NO" to make sure
-				 * things are properly reset
-				 */
-				if ((id != MB_NO) && (bay->content_id != MB_NO)) {
-					id = MB_NO;
-					MBDBG("mediabay%d: forcing MB_NO\n", bay->index);
-				}
-				MBDBG("mediabay%d: switching to %d\n", bay->index, id);
-				set_mb_power(bay, id != MB_NO);
-				bay->content_id = id;
-				if (id == MB_NO) {
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-					bay->cd_retry = 0;
-#endif
-					printk(KERN_INFO "media bay %d is empty\n", bay->index);
-				}
-			}
-		}
-	} else {
+	static char *mb_content_types[] = {
+		"a floppy drive",
+		"a floppy drive",
+		"an unsuported audio device",
+		"an ATA device",
+		"an unsupported PCI device",
+		"an unknown device",
+	};
+
+	if (id != bay->last_value) {
 		bay->last_value = id;
 		bay->value_count = 0;
+		return;
 	}
-}
-
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-int check_media_bay(struct device_node *which_bay, int what)
-{
-	int	i;
+	if (id == bay->content_id)
+		return;
 
-	for (i=0; i<media_bay_count; i++)
-		if (media_bays[i].mdev && which_bay == media_bays[i].mdev->ofdev.node) {
-			if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
-				return 0;
-			media_bays[i].cd_index = -1;
-			return -EINVAL;
+	bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
+	if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
+		/* If the device type changes without going thru
+		 * "MB_NO", we force a pass by "MB_NO" to make sure
+		 * things are properly reset
+		 */
+		if ((id != MB_NO) && (bay->content_id != MB_NO)) {
+			id = MB_NO;
+			pr_debug("mediabay%d: forcing MB_NO\n", bay->index);
 		}
-	return -ENODEV;
+		pr_debug("mediabay%d: switching to %d\n", bay->index, id);
+		set_mb_power(bay, id != MB_NO);
+		bay->content_id = id;
+		if (id >= MB_NO || id < 0)
+			printk(KERN_INFO "mediabay%d: Bay is now empty\n", bay->index);
+		else
+			printk(KERN_INFO "mediabay%d: Bay contains %s\n",
+			       bay->index, mb_content_types[id]);
+	}
 }
-EXPORT_SYMBOL(check_media_bay);
 
-int check_media_bay_by_base(unsigned long base, int what)
+int check_media_bay(struct macio_dev *baydev)
 {
-	int	i;
+	struct media_bay_info* bay;
+	int id;
 
-	for (i=0; i<media_bay_count; i++)
-		if (media_bays[i].mdev && base == (unsigned long) media_bays[i].cd_base) {
-			if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
-				return 0;
-			media_bays[i].cd_index = -1;
-			return -EINVAL;
-		} 
+	if (baydev == NULL)
+		return MB_NO;
 
-	return -ENODEV;
+	/* This returns an instant snapshot, not locking, sine
+	 * we may be called with the bay lock held. The resulting
+	 * fuzzyness of the result if called at the wrong time is
+	 * not actually a huge deal
+	 */
+	bay = macio_get_drvdata(baydev);
+	if (bay == NULL)
+		return MB_NO;
+	id = bay->content_id;
+	if (bay->state != mb_up)
+		return MB_NO;
+	if (id == MB_FD1)
+		return MB_FD;
+	return id;
 }
-EXPORT_SYMBOL_GPL(check_media_bay_by_base);
+EXPORT_SYMBOL_GPL(check_media_bay);
 
-int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
-			    int irq, ide_hwif_t *hwif)
+void lock_media_bay(struct macio_dev *baydev)
 {
-	int	i;
-
-	for (i=0; i<media_bay_count; i++) {
-		struct media_bay_info* bay = &media_bays[i];
+	struct media_bay_info* bay;
 
-		if (bay->mdev && which_bay == bay->mdev->ofdev.node) {
-			int timeout = 5000, index = hwif->index;
-			
-			mutex_lock(&bay->lock);
+	if (baydev == NULL)
+		return;
+	bay = macio_get_drvdata(baydev);
+	if (bay == NULL)
+		return;
+	mutex_lock(&bay->lock);
+	bay->user_lock = 1;
+}
+EXPORT_SYMBOL_GPL(lock_media_bay);
 
-			bay->cd_port	= hwif;
- 			bay->cd_base	= (void __iomem *) base;
-			bay->cd_irq	= irq;
+void unlock_media_bay(struct macio_dev *baydev)
+{
+	struct media_bay_info* bay;
 
-			if ((MB_CD != bay->content_id) || bay->state != mb_up) {
-				mutex_unlock(&bay->lock);
-				return 0;
-			}
-			printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i);
-			do {
-				if (MB_IDE_READY(i)) {
-					bay->cd_index	= index;
-					mutex_unlock(&bay->lock);
-					return 0;
-				}
-				mdelay(1);
-			} while(--timeout);
-			printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
-			mutex_unlock(&bay->lock);
-			return -ENODEV;
-		}
+	if (baydev == NULL)
+		return;
+	bay = macio_get_drvdata(baydev);
+	if (bay == NULL)
+		return;
+	if (bay->user_lock) {
+		bay->user_lock = 0;
+		mutex_unlock(&bay->lock);
 	}
+}
+EXPORT_SYMBOL_GPL(unlock_media_bay);
 
-	return -ENODEV;
+static int mb_broadcast_hotplug(struct device *dev, void *data)
+{
+	struct media_bay_info* bay = data;
+	struct macio_dev *mdev;
+	struct macio_driver *drv;
+	int state;
+
+	if (dev->bus != &macio_bus_type)
+		return 0;
+
+	state = bay->state == mb_up ? bay->content_id : MB_NO;
+	if (state == MB_FD1)
+		state = MB_FD;
+	mdev = to_macio_device(dev);
+	drv = to_macio_driver(dev->driver);
+	if (dev->driver && drv->mediabay_event)
+		drv->mediabay_event(mdev, state);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
 
 static void media_bay_step(int i)
 {
@@ -497,8 +474,8 @@ static void media_bay_step(int i)
 	if (bay->state != mb_powering_down)
 	    poll_media_bay(bay);
 
-	/* If timer expired or polling IDE busy, run state machine */
-	if ((bay->state != mb_ide_waiting) && (bay->timer != 0)) {
+	/* If timer expired run state machine */
+	if (bay->timer != 0) {
 		bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
 		if (bay->timer > 0)
 			return;
@@ -508,100 +485,50 @@ static void media_bay_step(int i)
 	switch(bay->state) {
 	case mb_powering_up:
 	    	if (bay->ops->setup_bus(bay, bay->last_value) < 0) {
-			MBDBG("mediabay%d: device not supported (kind:%d)\n", i, bay->content_id);
+			pr_debug("mediabay%d: device not supported (kind:%d)\n",
+				 i, bay->content_id);
 	    		set_mb_power(bay, 0);
 	    		break;
 	    	}
 	    	bay->timer = msecs_to_jiffies(MB_RESET_DELAY);
 	    	bay->state = mb_enabling_bay;
-		MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
+		pr_debug("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
 		break;
 	case mb_enabling_bay:
 		bay->ops->un_reset(bay);
 	    	bay->timer = msecs_to_jiffies(MB_SETUP_DELAY);
 	    	bay->state = mb_resetting;
-		MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
+		pr_debug("mediabay%d: releasing bay reset (kind:%d)\n",
+			 i, bay->content_id);
 	    	break;
 	case mb_resetting:
 		if (bay->content_id != MB_CD) {
-			MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
+			pr_debug("mediabay%d: bay is up (kind:%d)\n", i,
+				 bay->content_id);
 			bay->state = mb_up;
+			device_for_each_child(&bay->mdev->ofdev.dev,
+					      bay, mb_broadcast_hotplug);
 			break;
 	    	}
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-		MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
+		pr_debug("mediabay%d: releasing ATA reset (kind:%d)\n",
+			 i, bay->content_id);
 		bay->ops->un_reset_ide(bay);
 	    	bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
 	    	bay->state = mb_ide_resetting;
-#else
-		printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
-		set_mb_power(bay, 0);
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
 	    	break;
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
+
 	case mb_ide_resetting:
-	    	bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT);
-	    	bay->state = mb_ide_waiting;
-		MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
+		pr_debug("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
+		bay->state = mb_up;
+		device_for_each_child(&bay->mdev->ofdev.dev,
+				      bay, mb_broadcast_hotplug);
 	    	break;
-	case mb_ide_waiting:
-		if (bay->cd_base == NULL) {
-			bay->timer = 0;
-			bay->state = mb_up;
-			MBDBG("mediabay%d: up before IDE init\n", i);
-			break;
-		} else if (MB_IDE_READY(i)) {
-			bay->timer = 0;
-			bay->state = mb_up;
-			if (bay->cd_index < 0) {
-				printk("mediabay %d, registering IDE...\n", i);
-				pmu_suspend();
-				ide_port_scan(bay->cd_port);
-				if (bay->cd_port->present)
-					bay->cd_index = bay->cd_port->index;
-				pmu_resume();
-			}
-			if (bay->cd_index == -1) {
-				/* We eventually do a retry */
-				bay->cd_retry++;
-				printk("IDE register error\n");
-				set_mb_power(bay, 0);
-			} else {
-				printk(KERN_DEBUG "media-bay %d is ide%d\n", i, bay->cd_index);
-				MBDBG("mediabay %d IDE ready\n", i);
-			}
-			break;
-	    	} else if (bay->timer > 0)
-			bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
-	    	if (bay->timer <= 0) {
-			printk("\nIDE Timeout in bay %d !, IDE state is: 0x%02x\n",
-			       i, readb(bay->cd_base + 0x70));
-			MBDBG("mediabay%d: nIDE Timeout !\n", i);
-			set_mb_power(bay, 0);
-			bay->timer = 0;
-	    	}
-		break;
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+
 	case mb_powering_down:
 	    	bay->state = mb_empty;
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-    	        if (bay->cd_index >= 0) {
-			printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
-			       bay->cd_index);
-			ide_port_unregister_devices(bay->cd_port);
-			bay->cd_index = -1;
-		}
-	    	if (bay->cd_retry) {
-			if (bay->cd_retry > MAX_CD_RETRIES) {
-				/* Should add an error sound (sort of beep in dmasound) */
-				printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i);
-			} else {
-				/* Force a new power down/up sequence */
-				bay->content_id = MB_NO;
-			}
-	    	}
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
-		MBDBG("mediabay%d: end of power down\n", i);
+		device_for_each_child(&bay->mdev->ofdev.dev,
+				      bay, mb_broadcast_hotplug);
+		pr_debug("mediabay%d: end of power down\n", i);
 	    	break;
 	}
 }
@@ -676,11 +603,6 @@ static int __devinit media_bay_attach(st
 	bay->last_value = bay->ops->content(bay);
 	bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
 	bay->state = mb_empty;
-	do {
-		msleep(MB_POLL_DELAY);
-		media_bay_step(i);
-	} while((bay->state != mb_empty) &&
-		(bay->state != mb_up));
 
 	/* Mark us ready by filling our mdev data */
 	macio_set_drvdata(mdev, bay);
@@ -725,7 +647,7 @@ static int media_bay_resume(struct macio
 	       	set_mb_power(bay, 0);
 		msleep(MB_POWER_DELAY);
 	       	if (bay->ops->content(bay) != bay->content_id) {
-			printk("mediabay%d: content changed during sleep...\n", bay->index);
+			printk("mediabay%d: Content changed during sleep...\n", bay->index);
 			mutex_unlock(&bay->lock);
 	       		return 0;
 		}
@@ -733,9 +655,6 @@ static int media_bay_resume(struct macio
 	       	bay->last_value = bay->content_id;
 	       	bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
 	       	bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-	       	bay->cd_retry = 0;
-#endif
 	       	do {
 			msleep(MB_POLL_DELAY);
 	       		media_bay_step(bay->index);
@@ -823,9 +742,6 @@ static int __init media_bay_init(void)
 	for (i=0; i<MAX_BAYS; i++) {
 		memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
 		media_bays[i].content_id	= -1;
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-		media_bays[i].cd_index		= -1;
-#endif
 	}
 	if (!machine_is(powermac))
 		return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/nvram.c linux-libre-2.6.33-gnu1/drivers/macintosh/nvram.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/nvram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/nvram.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,6 @@
 #include <linux/fcntl.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 
@@ -21,7 +20,6 @@
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-	lock_kernel();
 	switch (origin) {
 	case 1:
 		offset += file->f_pos;
@@ -30,12 +28,10 @@ static loff_t nvram_llseek(struct file *
 		offset += NVRAM_SIZE;
 		break;
 	}
-	if (offset < 0) {
-		unlock_kernel();
+	if (offset < 0)
 		return -EINVAL;
-	}
+
 	file->f_pos = offset;
-	unlock_kernel();
 	return file->f_pos;
 }
 
@@ -76,8 +72,7 @@ static ssize_t write_nvram(struct file *
 	return p - buf;
 }
 
-static int nvram_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg)
+static long nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	switch(cmd) {
 		case PMAC_NVRAM_GET_OFFSET:
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/smu.c linux-libre-2.6.33-gnu1/drivers/macintosh/smu.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/smu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/smu.c	2010-02-24 13:52:17.000000000 -0500
@@ -660,7 +660,7 @@ static int smu_platform_probe(struct of_
 	return 0;
 }
 
-static struct of_device_id smu_platform_match[] =
+static const struct of_device_id smu_platform_match[] =
 {
 	{
 		.type		= "smu",
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/therm_adt746x.c linux-libre-2.6.33-gnu1/drivers/macintosh/therm_adt746x.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/therm_adt746x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/therm_adt746x.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,7 @@ struct thermostat {
 	u8			limits[3];
 	int			last_speed[2];
 	int			last_var[2];
+	int			pwm_inv[2];
 };
 
 static enum {ADT7460, ADT7467} therm_type;
@@ -229,19 +230,23 @@ static void write_fan_speed(struct therm
 	
 	if (speed >= 0) {
 		manual = read_reg(th, MANUAL_MODE[fan]);
+		manual &= ~INVERT_MASK;
 		write_reg(th, MANUAL_MODE[fan],
-			(manual|MANUAL_MASK) & (~INVERT_MASK));
+			manual | MANUAL_MASK | th->pwm_inv[fan]);
 		write_reg(th, FAN_SPD_SET[fan], speed);
 	} else {
 		/* back to automatic */
 		if(therm_type == ADT7460) {
 			manual = read_reg(th,
 				MANUAL_MODE[fan]) & (~MANUAL_MASK);
-
+			manual &= ~INVERT_MASK;
+			manual |= th->pwm_inv[fan];
 			write_reg(th,
 				MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
 		} else {
 			manual = read_reg(th, MANUAL_MODE[fan]);
+			manual &= ~INVERT_MASK;
+			manual |= th->pwm_inv[fan];
 			write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
 		}
 	}
@@ -387,7 +392,7 @@ static int probe_thermostat(struct i2c_c
 	i2c_set_clientdata(client, th);
 	th->clt = client;
 
-	rc = read_reg(th, 0);
+	rc = read_reg(th, CONFIG_REG);
 	if (rc < 0) {
 		dev_err(&client->dev, "Thermostat failed to read config!\n");
 		kfree(th);
@@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_c
 
 	thermostat = th;
 
+	/* record invert bit status because fw can corrupt it after suspend */
+	th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
+	th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
+
 	/* be sure to really write fan speed the first time */
 	th->last_speed[0] = -2;
 	th->last_speed[1] = -2;
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/therm_pm72.c linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/therm_pm72.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/therm_pm72.c	2010-02-24 13:52:17.000000000 -0500
@@ -2211,7 +2211,7 @@ static int fcu_of_remove(struct of_devic
 	return 0;
 }
 
-static struct of_device_id fcu_match[] = 
+static const struct of_device_id fcu_match[] = 
 {
 	{
 	.type		= "fcu",
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/therm_windtunnel.c linux-libre-2.6.33-gnu1/drivers/macintosh/therm_windtunnel.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/therm_windtunnel.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/therm_windtunnel.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,7 +15,7 @@
  *
  *	WARNING: This driver has only been testen on Apple's
  *	1.25 MHz Dual G4 (March 03). It is tuned for a CPU
- *	temperatur around 57 C.
+ *	temperature around 57 C.
  *
  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
  *
@@ -457,7 +457,7 @@ therm_of_remove( struct of_device *dev )
 	return 0;
 }
 
-static struct of_device_id therm_of_match[] = {{
+static const struct of_device_id therm_of_match[] = {{
 	.name		= "fan",
 	.compatible	= "adm1030"
     }, {}
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/via-pmu.c linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/via-pmu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/via-pmu.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,7 @@
 #include <linux/spinlock.h>
 #include <linux/pm.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
@@ -186,17 +187,11 @@ static int init_pmu(void);
 static void pmu_start(void);
 static irqreturn_t via_pmu_interrupt(int irq, void *arg);
 static irqreturn_t gpio1_interrupt(int irq, void *arg);
-static int proc_get_info(char *page, char **start, off_t off,
-			  int count, int *eof, void *data);
-static int proc_get_irqstats(char *page, char **start, off_t off,
-			  int count, int *eof, void *data);
+static const struct file_operations pmu_info_proc_fops;
+static const struct file_operations pmu_irqstats_proc_fops;
 static void pmu_pass_intr(unsigned char *data, int len);
-static int proc_get_batt(char *page, char **start, off_t off,
-			int count, int *eof, void *data);
-static int proc_read_options(char *page, char **start, off_t off,
-			int count, int *eof, void *data);
-static int proc_write_options(struct file *file, const char __user *buffer,
-			unsigned long count, void *data);
+static const struct file_operations pmu_battery_proc_fops;
+static const struct file_operations pmu_options_proc_fops;
 
 #ifdef CONFIG_ADB
 struct adb_driver via_pmu_driver = {
@@ -507,19 +502,15 @@ static int __init via_pmu_dev_init(void)
 		for (i=0; i<pmu_battery_count; i++) {
 			char title[16];
 			sprintf(title, "battery_%ld", i);
-			proc_pmu_batt[i] = create_proc_read_entry(title, 0, proc_pmu_root,
-						proc_get_batt, (void *)i);
+			proc_pmu_batt[i] = proc_create_data(title, 0, proc_pmu_root,
+					&pmu_battery_proc_fops, (void *)i);
 		}
 
-		proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root,
-					proc_get_info, NULL);
-		proc_pmu_irqstats = create_proc_read_entry("interrupts", 0, proc_pmu_root,
-					proc_get_irqstats, NULL);
-		proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root);
-		if (proc_pmu_options) {
-			proc_pmu_options->read_proc = proc_read_options;
-			proc_pmu_options->write_proc = proc_write_options;
-		}
+		proc_pmu_info = proc_create("info", 0, proc_pmu_root, &pmu_info_proc_fops);
+		proc_pmu_irqstats = proc_create("interrupts", 0, proc_pmu_root,
+						&pmu_irqstats_proc_fops);
+		proc_pmu_options = proc_create("options", 0600, proc_pmu_root,
+						&pmu_options_proc_fops);
 	}
 	return 0;
 }
@@ -799,27 +790,33 @@ query_battery_state(void)
 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
 
-static int
-proc_get_info(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int pmu_info_proc_show(struct seq_file *m, void *v)
 {
-	char* p = page;
-
-	p += sprintf(p, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
-	p += sprintf(p, "PMU firmware version   : %02x\n", pmu_version);
-	p += sprintf(p, "AC Power               : %d\n",
+	seq_printf(m, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
+	seq_printf(m, "PMU firmware version   : %02x\n", pmu_version);
+	seq_printf(m, "AC Power               : %d\n",
 		((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0);
-	p += sprintf(p, "Battery count          : %d\n", pmu_battery_count);
+	seq_printf(m, "Battery count          : %d\n", pmu_battery_count);
 
-	return p - page;
+	return 0;
 }
 
-static int
-proc_get_irqstats(char *page, char **start, off_t off,
-		  int count, int *eof, void *data)
+static int pmu_info_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pmu_info_proc_show, NULL);
+}
+
+static const struct file_operations pmu_info_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pmu_info_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pmu_irqstats_proc_show(struct seq_file *m, void *v)
 {
 	int i;
-	char* p = page;
 	static const char *irq_names[] = {
 		"Total CB1 triggered events",
 		"Total GPIO1 triggered events",
@@ -835,60 +832,76 @@ proc_get_irqstats(char *page, char **sta
         };
 
 	for (i=0; i<11; i++) {
-		p += sprintf(p, " %2u: %10u (%s)\n",
+		seq_printf(m, " %2u: %10u (%s)\n",
 			     i, pmu_irq_stats[i], irq_names[i]);
 	}
-	return p - page;
+	return 0;
 }
 
-static int
-proc_get_batt(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int pmu_irqstats_proc_open(struct inode *inode, struct file *file)
 {
-	long batnum = (long)data;
-	char *p = page;
-	
-	p += sprintf(p, "\n");
-	p += sprintf(p, "flags      : %08x\n",
-		pmu_batteries[batnum].flags);
-	p += sprintf(p, "charge     : %d\n",
-		pmu_batteries[batnum].charge);
-	p += sprintf(p, "max_charge : %d\n",
-		pmu_batteries[batnum].max_charge);
-	p += sprintf(p, "current    : %d\n",
-		pmu_batteries[batnum].amperage);
-	p += sprintf(p, "voltage    : %d\n",
-		pmu_batteries[batnum].voltage);
-	p += sprintf(p, "time rem.  : %d\n",
-		pmu_batteries[batnum].time_remaining);
+	return single_open(file, pmu_irqstats_proc_show, NULL);
+}
 
-	return p - page;
+static const struct file_operations pmu_irqstats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pmu_irqstats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pmu_battery_proc_show(struct seq_file *m, void *v)
+{
+	long batnum = (long)m->private;
+	
+	seq_putc(m, '\n');
+	seq_printf(m, "flags      : %08x\n", pmu_batteries[batnum].flags);
+	seq_printf(m, "charge     : %d\n", pmu_batteries[batnum].charge);
+	seq_printf(m, "max_charge : %d\n", pmu_batteries[batnum].max_charge);
+	seq_printf(m, "current    : %d\n", pmu_batteries[batnum].amperage);
+	seq_printf(m, "voltage    : %d\n", pmu_batteries[batnum].voltage);
+	seq_printf(m, "time rem.  : %d\n", pmu_batteries[batnum].time_remaining);
+	return 0;
 }
 
-static int
-proc_read_options(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
+static int pmu_battery_proc_open(struct inode *inode, struct file *file)
 {
-	char *p = page;
+	return single_open(file, pmu_battery_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations pmu_battery_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pmu_battery_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
+static int pmu_options_proc_show(struct seq_file *m, void *v)
+{
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
 	if (pmu_kind == PMU_KEYLARGO_BASED &&
 	    pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
-		p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
+		seq_printf(m, "lid_wakeup=%d\n", option_lid_wakeup);
 #endif
 	if (pmu_kind == PMU_KEYLARGO_BASED)
-		p += sprintf(p, "server_mode=%d\n", option_server_mode);
+		seq_printf(m, "server_mode=%d\n", option_server_mode);
 
-	return p - page;
+	return 0;
 }
-			
-static int
-proc_write_options(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
+
+static int pmu_options_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pmu_options_proc_show, NULL);
+}
+
+static ssize_t pmu_options_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	char tmp[33];
 	char *label, *val;
-	unsigned long fcount = count;
+	size_t fcount = count;
 	
 	if (!count)
 		return -EINVAL;
@@ -927,6 +940,15 @@ proc_write_options(struct file *file, co
 	return fcount;
 }
 
+static const struct file_operations pmu_options_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pmu_options_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= pmu_options_proc_write,
+};
+
 #ifdef CONFIG_ADB
 /* Send an ADB command */
 static int pmu_send_request(struct adb_request *req, int sync)
diff -druNp linux-libre-2.6.32-gnu1/drivers/macintosh/windfarm_smu_controls.c linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_controls.c
--- linux-libre-2.6.32-gnu1/drivers/macintosh/windfarm_smu_controls.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/macintosh/windfarm_smu_controls.c	2010-02-24 13:52:17.000000000 -0500
@@ -202,6 +202,8 @@ static struct smu_fan_control *smu_fan_c
 		fct->ctrl.name = "cpu-front-fan-1";
 	else if (!strcmp(l, "CPU A PUMP"))
 		fct->ctrl.name = "cpu-pump-0";
+	else if (!strcmp(l, "CPU B PUMP"))
+		fct->ctrl.name = "cpu-pump-1";
 	else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
 		 !strcmp(l, "EXPANSION SLOTS INTAKE"))
 		fct->ctrl.name = "slots-fan";
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/bitmap.c linux-libre-2.6.33-gnu1/drivers/md/bitmap.c
--- linux-libre-2.6.32-gnu1/drivers/md/bitmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/bitmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,7 +212,7 @@ static void bitmap_checkfree(struct bitm
  */
 
 /* IO operations when bitmap is stored near all superblocks */
-static struct page *read_sb_page(mddev_t *mddev, long offset,
+static struct page *read_sb_page(mddev_t *mddev, loff_t offset,
 				 struct page *page,
 				 unsigned long index, int size)
 {
@@ -287,27 +287,36 @@ static int write_sb_page(struct bitmap *
 
 	while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
 			int size = PAGE_SIZE;
+			loff_t offset = mddev->bitmap_info.offset;
 			if (page->index == bitmap->file_pages-1)
 				size = roundup(bitmap->last_page_size,
 					       bdev_logical_block_size(rdev->bdev));
 			/* Just make sure we aren't corrupting data or
 			 * metadata
 			 */
-			if (bitmap->offset < 0) {
+			if (mddev->external) {
+				/* Bitmap could be anywhere. */
+				if (rdev->sb_start + offset + (page->index *(PAGE_SIZE/512)) >
+				    rdev->data_offset &&
+				    rdev->sb_start + offset < 
+				    rdev->data_offset + mddev->dev_sectors +
+				    (PAGE_SIZE/512))
+					goto bad_alignment;
+			} else if (offset < 0) {
 				/* DATA  BITMAP METADATA  */
-				if (bitmap->offset
+				if (offset
 				    + (long)(page->index * (PAGE_SIZE/512))
 				    + size/512 > 0)
 					/* bitmap runs in to metadata */
 					goto bad_alignment;
 				if (rdev->data_offset + mddev->dev_sectors
-				    > rdev->sb_start + bitmap->offset)
+				    > rdev->sb_start + offset)
 					/* data runs in to bitmap */
 					goto bad_alignment;
 			} else if (rdev->sb_start < rdev->data_offset) {
 				/* METADATA BITMAP DATA */
 				if (rdev->sb_start
-				    + bitmap->offset
+				    + offset
 				    + page->index*(PAGE_SIZE/512) + size/512
 				    > rdev->data_offset)
 					/* bitmap runs in to data */
@@ -316,7 +325,7 @@ static int write_sb_page(struct bitmap *
 				/* DATA METADATA BITMAP - no problems */
 			}
 			md_super_write(mddev, rdev,
-				       rdev->sb_start + bitmap->offset
+				       rdev->sb_start + offset
 				       + page->index * (PAGE_SIZE/512),
 				       size,
 				       page);
@@ -488,6 +497,8 @@ void bitmap_update_sb(struct bitmap *bit
 
 	if (!bitmap || !bitmap->mddev) /* no bitmap for this array */
 		return;
+	if (bitmap->mddev->bitmap_info.external)
+		return;
 	spin_lock_irqsave(&bitmap->lock, flags);
 	if (!bitmap->sb_page) { /* no superblock */
 		spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -501,6 +512,9 @@ void bitmap_update_sb(struct bitmap *bit
 		bitmap->events_cleared = bitmap->mddev->events;
 		sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
 	}
+	/* Just in case these have been changed via sysfs: */
+	sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
+	sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
 	kunmap_atomic(sb, KM_USER0);
 	write_page(bitmap, bitmap->sb_page, 1);
 }
@@ -550,7 +564,8 @@ static int bitmap_read_sb(struct bitmap
 
 		bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes);
 	} else {
-		bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset,
+		bitmap->sb_page = read_sb_page(bitmap->mddev,
+					       bitmap->mddev->bitmap_info.offset,
 					       NULL,
 					       0, sizeof(bitmap_super_t));
 	}
@@ -563,7 +578,7 @@ static int bitmap_read_sb(struct bitmap
 	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 
 	chunksize = le32_to_cpu(sb->chunksize);
-	daemon_sleep = le32_to_cpu(sb->daemon_sleep);
+	daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
 	write_behind = le32_to_cpu(sb->write_behind);
 
 	/* verify that the bitmap-specific fields are valid */
@@ -576,7 +591,7 @@ static int bitmap_read_sb(struct bitmap
 		reason = "bitmap chunksize too small";
 	else if ((1 << ffz(~chunksize)) != chunksize)
 		reason = "bitmap chunksize not a power of 2";
-	else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT / HZ)
+	else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT)
 		reason = "daemon sleep period out of range";
 	else if (write_behind > COUNTER_MAX)
 		reason = "write-behind limit out of range (0 - 16383)";
@@ -610,10 +625,9 @@ static int bitmap_read_sb(struct bitmap
 	}
 success:
 	/* assign fields using values from superblock */
-	bitmap->chunksize = chunksize;
-	bitmap->daemon_sleep = daemon_sleep;
-	bitmap->daemon_lastrun = jiffies;
-	bitmap->max_write_behind = write_behind;
+	bitmap->mddev->bitmap_info.chunksize = chunksize;
+	bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
+	bitmap->mddev->bitmap_info.max_write_behind = write_behind;
 	bitmap->flags |= le32_to_cpu(sb->state);
 	if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
 		bitmap->flags |= BITMAP_HOSTENDIAN;
@@ -664,16 +678,26 @@ static int bitmap_mask_state(struct bitm
  * general bitmap file operations
  */
 
+/*
+ * on-disk bitmap:
+ *
+ * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
+ * file a page at a time. There's a superblock at the start of the file.
+ */
 /* calculate the index of the page that contains this bit */
-static inline unsigned long file_page_index(unsigned long chunk)
+static inline unsigned long file_page_index(struct bitmap *bitmap, unsigned long chunk)
 {
-	return CHUNK_BIT_OFFSET(chunk) >> PAGE_BIT_SHIFT;
+	if (!bitmap->mddev->bitmap_info.external)
+		chunk += sizeof(bitmap_super_t) << 3;
+	return chunk >> PAGE_BIT_SHIFT;
 }
 
 /* calculate the (bit) offset of this bit within a page */
-static inline unsigned long file_page_offset(unsigned long chunk)
+static inline unsigned long file_page_offset(struct bitmap *bitmap, unsigned long chunk)
 {
-	return CHUNK_BIT_OFFSET(chunk) & (PAGE_BITS - 1);
+	if (!bitmap->mddev->bitmap_info.external)
+		chunk += sizeof(bitmap_super_t) << 3;
+	return chunk & (PAGE_BITS - 1);
 }
 
 /*
@@ -686,8 +710,9 @@ static inline unsigned long file_page_of
 static inline struct page *filemap_get_page(struct bitmap *bitmap,
 					unsigned long chunk)
 {
-	if (file_page_index(chunk) >= bitmap->file_pages) return NULL;
-	return bitmap->filemap[file_page_index(chunk) - file_page_index(0)];
+	if (file_page_index(bitmap, chunk) >= bitmap->file_pages) return NULL;
+	return bitmap->filemap[file_page_index(bitmap, chunk)
+			       - file_page_index(bitmap, 0)];
 }
 
 
@@ -710,7 +735,7 @@ static void bitmap_file_unmap(struct bit
 	spin_unlock_irqrestore(&bitmap->lock, flags);
 
 	while (pages--)
-		if (map[pages]->index != 0) /* 0 is sb_page, release it below */
+		if (map[pages] != sb_page) /* 0 is sb_page, release it below */
 			free_buffers(map[pages]);
 	kfree(map);
 	kfree(attr);
@@ -821,7 +846,7 @@ static void bitmap_file_set_bit(struct b
 
 	page = filemap_get_page(bitmap, chunk);
 	if (!page) return;
-	bit = file_page_offset(chunk);
+	bit = file_page_offset(bitmap, chunk);
 
  	/* set the bit */
 	kaddr = kmap_atomic(page, KM_USER0);
@@ -907,7 +932,7 @@ static int bitmap_init_from_disk(struct
 	chunks = bitmap->chunks;
 	file = bitmap->file;
 
-	BUG_ON(!file && !bitmap->offset);
+	BUG_ON(!file && !bitmap->mddev->bitmap_info.offset);
 
 #ifdef INJECT_FAULTS_3
 	outofdate = 1;
@@ -919,14 +944,17 @@ static int bitmap_init_from_disk(struct
 			"recovery\n", bmname(bitmap));
 
 	bytes = (chunks + 7) / 8;
+	if (!bitmap->mddev->bitmap_info.external)
+		bytes += sizeof(bitmap_super_t);
 
-	num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE;
+	
+	num_pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
 
-	if (file && i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) {
+	if (file && i_size_read(file->f_mapping->host) < bytes) {
 		printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n",
 			bmname(bitmap),
 			(unsigned long) i_size_read(file->f_mapping->host),
-			bytes + sizeof(bitmap_super_t));
+			bytes);
 		goto err;
 	}
 
@@ -947,17 +975,16 @@ static int bitmap_init_from_disk(struct
 
 	for (i = 0; i < chunks; i++) {
 		int b;
-		index = file_page_index(i);
-		bit = file_page_offset(i);
+		index = file_page_index(bitmap, i);
+		bit = file_page_offset(bitmap, i);
 		if (index != oldindex) { /* this is a new page, read it in */
 			int count;
 			/* unmap the old page, we're done with it */
 			if (index == num_pages-1)
-				count = bytes + sizeof(bitmap_super_t)
-					- index * PAGE_SIZE;
+				count = bytes - index * PAGE_SIZE;
 			else
 				count = PAGE_SIZE;
-			if (index == 0) {
+			if (index == 0 && bitmap->sb_page) {
 				/*
 				 * if we're here then the superblock page
 				 * contains some bits (PAGE_SIZE != sizeof sb)
@@ -967,14 +994,15 @@ static int bitmap_init_from_disk(struct
 				offset = sizeof(bitmap_super_t);
 				if (!file)
 					read_sb_page(bitmap->mddev,
-						     bitmap->offset,
+						     bitmap->mddev->bitmap_info.offset,
 						     page,
 						     index, count);
 			} else if (file) {
 				page = read_page(file, index, bitmap, count);
 				offset = 0;
 			} else {
-				page = read_sb_page(bitmap->mddev, bitmap->offset,
+				page = read_sb_page(bitmap->mddev,
+						    bitmap->mddev->bitmap_info.offset,
 						    NULL,
 						    index, count);
 				offset = 0;
@@ -1078,23 +1106,32 @@ static bitmap_counter_t *bitmap_get_coun
  *			out to disk
  */
 
-void bitmap_daemon_work(struct bitmap *bitmap)
+void bitmap_daemon_work(mddev_t *mddev)
 {
+	struct bitmap *bitmap;
 	unsigned long j;
 	unsigned long flags;
 	struct page *page = NULL, *lastpage = NULL;
 	int blocks;
 	void *paddr;
 
-	if (bitmap == NULL)
+	/* Use a mutex to guard daemon_work against
+	 * bitmap_destroy.
+	 */
+	mutex_lock(&mddev->bitmap_info.mutex);
+	bitmap = mddev->bitmap;
+	if (bitmap == NULL) {
+		mutex_unlock(&mddev->bitmap_info.mutex);
 		return;
-	if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
+	}
+	if (time_before(jiffies, bitmap->daemon_lastrun
+			+ bitmap->mddev->bitmap_info.daemon_sleep))
 		goto done;
 
 	bitmap->daemon_lastrun = jiffies;
 	if (bitmap->allclean) {
 		bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
-		return;
+		goto done;
 	}
 	bitmap->allclean = 1;
 
@@ -1142,7 +1179,8 @@ void bitmap_daemon_work(struct bitmap *b
 			/* We are possibly going to clear some bits, so make
 			 * sure that events_cleared is up-to-date.
 			 */
-			if (bitmap->need_sync) {
+			if (bitmap->need_sync &&
+			    bitmap->mddev->bitmap_info.external == 0) {
 				bitmap_super_t *sb;
 				bitmap->need_sync = 0;
 				sb = kmap_atomic(bitmap->sb_page, KM_USER0);
@@ -1152,7 +1190,8 @@ void bitmap_daemon_work(struct bitmap *b
 				write_page(bitmap, bitmap->sb_page, 1);
 			}
 			spin_lock_irqsave(&bitmap->lock, flags);
-			clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
+			if (!bitmap->need_sync)
+				clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
 		}
 		bmc = bitmap_get_counter(bitmap,
 					 (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
@@ -1167,7 +1206,7 @@ void bitmap_daemon_work(struct bitmap *b
 			if (*bmc == 2) {
 				*bmc=1; /* maybe clear the bit next time */
 				set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
-			} else if (*bmc == 1) {
+			} else if (*bmc == 1 && !bitmap->need_sync) {
 				/* we can clear the bit */
 				*bmc = 0;
 				bitmap_count_page(bitmap,
@@ -1177,9 +1216,11 @@ void bitmap_daemon_work(struct bitmap *b
 				/* clear the bit */
 				paddr = kmap_atomic(page, KM_USER0);
 				if (bitmap->flags & BITMAP_HOSTENDIAN)
-					clear_bit(file_page_offset(j), paddr);
+					clear_bit(file_page_offset(bitmap, j),
+						  paddr);
 				else
-					ext2_clear_bit(file_page_offset(j), paddr);
+					ext2_clear_bit(file_page_offset(bitmap, j),
+						       paddr);
 				kunmap_atomic(paddr, KM_USER0);
 			}
 		} else
@@ -1202,7 +1243,9 @@ void bitmap_daemon_work(struct bitmap *b
 
  done:
 	if (bitmap->allclean == 0)
-		bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ;
+		bitmap->mddev->thread->timeout = 
+			bitmap->mddev->bitmap_info.daemon_sleep;
+	mutex_unlock(&mddev->bitmap_info.mutex);
 }
 
 static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1332,6 +1375,7 @@ void bitmap_endwrite(struct bitmap *bitm
 		    bitmap->events_cleared < bitmap->mddev->events) {
 			bitmap->events_cleared = bitmap->mddev->events;
 			bitmap->need_sync = 1;
+			sysfs_notify_dirent(bitmap->sysfs_can_clear);
 		}
 
 		if (!success && ! (*bmc & NEEDED_MASK))
@@ -1470,7 +1514,7 @@ void bitmap_cond_end_sync(struct bitmap
 		return;
 	}
 	if (time_before(jiffies, (bitmap->last_end_sync
-				  + bitmap->daemon_sleep * HZ)))
+				  + bitmap->mddev->bitmap_info.daemon_sleep)))
 		return;
 	wait_event(bitmap->mddev->recovery_wait,
 		   atomic_read(&bitmap->mddev->recovery_active) == 0);
@@ -1522,6 +1566,12 @@ void bitmap_dirty_bits(struct bitmap *bi
 		sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap);
 		bitmap_set_memory_bits(bitmap, sec, 1);
 		bitmap_file_set_bit(bitmap, sec);
+		if (sec < bitmap->mddev->recovery_cp)
+			/* We are asserting that the array is dirty,
+			 * so move the recovery_cp address back so
+			 * that it is obvious that it is dirty
+			 */
+			bitmap->mddev->recovery_cp = sec;
 	}
 }
 
@@ -1531,7 +1581,7 @@ void bitmap_dirty_bits(struct bitmap *bi
 void bitmap_flush(mddev_t *mddev)
 {
 	struct bitmap *bitmap = mddev->bitmap;
-	int sleep;
+	long sleep;
 
 	if (!bitmap) /* there was no bitmap */
 		return;
@@ -1539,12 +1589,13 @@ void bitmap_flush(mddev_t *mddev)
 	/* run the daemon_work three time to ensure everything is flushed
 	 * that can be
 	 */
-	sleep = bitmap->daemon_sleep;
-	bitmap->daemon_sleep = 0;
-	bitmap_daemon_work(bitmap);
-	bitmap_daemon_work(bitmap);
-	bitmap_daemon_work(bitmap);
-	bitmap->daemon_sleep = sleep;
+	sleep = mddev->bitmap_info.daemon_sleep * 2;
+	bitmap->daemon_lastrun -= sleep;
+	bitmap_daemon_work(mddev);
+	bitmap->daemon_lastrun -= sleep;
+	bitmap_daemon_work(mddev);
+	bitmap->daemon_lastrun -= sleep;
+	bitmap_daemon_work(mddev);
 	bitmap_update_sb(bitmap);
 }
 
@@ -1574,6 +1625,7 @@ static void bitmap_free(struct bitmap *b
 	kfree(bp);
 	kfree(bitmap);
 }
+
 void bitmap_destroy(mddev_t *mddev)
 {
 	struct bitmap *bitmap = mddev->bitmap;
@@ -1581,10 +1633,15 @@ void bitmap_destroy(mddev_t *mddev)
 	if (!bitmap) /* there was no bitmap */
 		return;
 
+	mutex_lock(&mddev->bitmap_info.mutex);
 	mddev->bitmap = NULL; /* disconnect from the md device */
+	mutex_unlock(&mddev->bitmap_info.mutex);
 	if (mddev->thread)
 		mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
 
+	if (bitmap->sysfs_can_clear)
+		sysfs_put(bitmap->sysfs_can_clear);
+
 	bitmap_free(bitmap);
 }
 
@@ -1598,16 +1655,17 @@ int bitmap_create(mddev_t *mddev)
 	sector_t blocks = mddev->resync_max_sectors;
 	unsigned long chunks;
 	unsigned long pages;
-	struct file *file = mddev->bitmap_file;
+	struct file *file = mddev->bitmap_info.file;
 	int err;
 	sector_t start;
+	struct sysfs_dirent *bm;
 
 	BUILD_BUG_ON(sizeof(bitmap_super_t) != 256);
 
-	if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */
+	if (!file && !mddev->bitmap_info.offset) /* bitmap disabled, nothing to do */
 		return 0;
 
-	BUG_ON(file && mddev->bitmap_offset);
+	BUG_ON(file && mddev->bitmap_info.offset);
 
 	bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
 	if (!bitmap)
@@ -1620,8 +1678,14 @@ int bitmap_create(mddev_t *mddev)
 
 	bitmap->mddev = mddev;
 
+	bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
+	if (bm) {
+		bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear");
+		sysfs_put(bm);
+	} else
+		bitmap->sysfs_can_clear = NULL;
+
 	bitmap->file = file;
-	bitmap->offset = mddev->bitmap_offset;
 	if (file) {
 		get_file(file);
 		/* As future accesses to this file will use bmap,
@@ -1630,12 +1694,22 @@ int bitmap_create(mddev_t *mddev)
 		 */
 		vfs_fsync(file, file->f_dentry, 1);
 	}
-	/* read superblock from bitmap file (this sets bitmap->chunksize) */
-	err = bitmap_read_sb(bitmap);
+	/* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */
+	if (!mddev->bitmap_info.external)
+		err = bitmap_read_sb(bitmap);
+	else {
+		err = 0;
+		if (mddev->bitmap_info.chunksize == 0 ||
+		    mddev->bitmap_info.daemon_sleep == 0)
+			/* chunksize and time_base need to be
+			 * set first. */
+			err = -EINVAL;
+	}
 	if (err)
 		goto error;
 
-	bitmap->chunkshift = ffz(~bitmap->chunksize);
+	bitmap->daemon_lastrun = jiffies;
+	bitmap->chunkshift = ffz(~mddev->bitmap_info.chunksize);
 
 	/* now that chunksize and chunkshift are set, we can use these macros */
  	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
@@ -1677,7 +1751,8 @@ int bitmap_create(mddev_t *mddev)
 
 	mddev->bitmap = bitmap;
 
-	mddev->thread->timeout = bitmap->daemon_sleep * HZ;
+	mddev->thread->timeout = mddev->bitmap_info.daemon_sleep;
+	md_wakeup_thread(mddev->thread);
 
 	bitmap_update_sb(bitmap);
 
@@ -1688,6 +1763,264 @@ int bitmap_create(mddev_t *mddev)
 	return err;
 }
 
+static ssize_t
+location_show(mddev_t *mddev, char *page)
+{
+	ssize_t len;
+	if (mddev->bitmap_info.file) {
+		len = sprintf(page, "file");
+	} else if (mddev->bitmap_info.offset) {
+		len = sprintf(page, "%+lld", (long long)mddev->bitmap_info.offset);
+	} else
+		len = sprintf(page, "none");
+	len += sprintf(page+len, "\n");
+	return len;
+}
+
+static ssize_t
+location_store(mddev_t *mddev, const char *buf, size_t len)
+{
+
+	if (mddev->pers) {
+		if (!mddev->pers->quiesce)
+			return -EBUSY;
+		if (mddev->recovery || mddev->sync_thread)
+			return -EBUSY;
+	}
+
+	if (mddev->bitmap || mddev->bitmap_info.file ||
+	    mddev->bitmap_info.offset) {
+		/* bitmap already configured.  Only option is to clear it */
+		if (strncmp(buf, "none", 4) != 0)
+			return -EBUSY;
+		if (mddev->pers) {
+			mddev->pers->quiesce(mddev, 1);
+			bitmap_destroy(mddev);
+			mddev->pers->quiesce(mddev, 0);
+		}
+		mddev->bitmap_info.offset = 0;
+		if (mddev->bitmap_info.file) {
+			struct file *f = mddev->bitmap_info.file;
+			mddev->bitmap_info.file = NULL;
+			restore_bitmap_write_access(f);
+			fput(f);
+		}
+	} else {
+		/* No bitmap, OK to set a location */
+		long long offset;
+		if (strncmp(buf, "none", 4) == 0)
+			/* nothing to be done */;
+		else if (strncmp(buf, "file:", 5) == 0) {
+			/* Not supported yet */
+			return -EINVAL;
+		} else {
+			int rv;
+			if (buf[0] == '+')
+				rv = strict_strtoll(buf+1, 10, &offset);
+			else
+				rv = strict_strtoll(buf, 10, &offset);
+			if (rv)
+				return rv;
+			if (offset == 0)
+				return -EINVAL;
+			if (mddev->bitmap_info.external == 0 &&
+			    mddev->major_version == 0 &&
+			    offset != mddev->bitmap_info.default_offset)
+				return -EINVAL;
+			mddev->bitmap_info.offset = offset;
+			if (mddev->pers) {
+				mddev->pers->quiesce(mddev, 1);
+				rv = bitmap_create(mddev);
+				if (rv) {
+					bitmap_destroy(mddev);
+					mddev->bitmap_info.offset = 0;
+				}
+				mddev->pers->quiesce(mddev, 0);
+				if (rv)
+					return rv;
+			}
+		}
+	}
+	if (!mddev->external) {
+		/* Ensure new bitmap info is stored in
+		 * metadata promptly.
+		 */
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
+		md_wakeup_thread(mddev->thread);
+	}
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_location =
+__ATTR(location, S_IRUGO|S_IWUSR, location_show, location_store);
+
+static ssize_t
+timeout_show(mddev_t *mddev, char *page)
+{
+	ssize_t len;
+	unsigned long secs = mddev->bitmap_info.daemon_sleep / HZ;
+	unsigned long jifs = mddev->bitmap_info.daemon_sleep % HZ;
+	
+	len = sprintf(page, "%lu", secs);
+	if (jifs)
+		len += sprintf(page+len, ".%03u", jiffies_to_msecs(jifs));
+	len += sprintf(page+len, "\n");
+	return len;
+}
+
+static ssize_t
+timeout_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* timeout can be set at any time */
+	unsigned long timeout;
+	int rv = strict_strtoul_scaled(buf, &timeout, 4);
+	if (rv)
+		return rv;
+
+	/* just to make sure we don't overflow... */
+	if (timeout >= LONG_MAX / HZ)
+		return -EINVAL;
+
+	timeout = timeout * HZ / 10000;
+
+	if (timeout >= MAX_SCHEDULE_TIMEOUT)
+		timeout = MAX_SCHEDULE_TIMEOUT-1;
+	if (timeout < 1)
+		timeout = 1;
+	mddev->bitmap_info.daemon_sleep = timeout;
+	if (mddev->thread) {
+		/* if thread->timeout is MAX_SCHEDULE_TIMEOUT, then
+		 * the bitmap is all clean and we don't need to
+		 * adjust the timeout right now
+		 */
+		if (mddev->thread->timeout < MAX_SCHEDULE_TIMEOUT) {
+			mddev->thread->timeout = timeout;
+			md_wakeup_thread(mddev->thread);
+		}
+	}
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_timeout =
+__ATTR(time_base, S_IRUGO|S_IWUSR, timeout_show, timeout_store);
+
+static ssize_t
+backlog_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%lu\n", mddev->bitmap_info.max_write_behind);
+}
+
+static ssize_t
+backlog_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	unsigned long backlog;
+	int rv = strict_strtoul(buf, 10, &backlog);
+	if (rv)
+		return rv;
+	if (backlog > COUNTER_MAX)
+		return -EINVAL;
+	mddev->bitmap_info.max_write_behind = backlog;
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_backlog =
+__ATTR(backlog, S_IRUGO|S_IWUSR, backlog_show, backlog_store);
+
+static ssize_t
+chunksize_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%lu\n", mddev->bitmap_info.chunksize);
+}
+
+static ssize_t
+chunksize_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* Can only be changed when no bitmap is active */
+	int rv;
+	unsigned long csize;
+	if (mddev->bitmap)
+		return -EBUSY;
+	rv = strict_strtoul(buf, 10, &csize);
+	if (rv)
+		return rv;
+	if (csize < 512 ||
+	    !is_power_of_2(csize))
+		return -EINVAL;
+	mddev->bitmap_info.chunksize = csize;
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_chunksize =
+__ATTR(chunksize, S_IRUGO|S_IWUSR, chunksize_show, chunksize_store);
+
+static ssize_t metadata_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%s\n", (mddev->bitmap_info.external
+				      ? "external" : "internal"));
+}
+
+static ssize_t metadata_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	if (mddev->bitmap ||
+	    mddev->bitmap_info.file ||
+	    mddev->bitmap_info.offset)
+		return -EBUSY;
+	if (strncmp(buf, "external", 8) == 0)
+		mddev->bitmap_info.external = 1;
+	else if (strncmp(buf, "internal", 8) == 0)
+		mddev->bitmap_info.external = 0;
+	else
+		return -EINVAL;
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_metadata =
+__ATTR(metadata, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
+
+static ssize_t can_clear_show(mddev_t *mddev, char *page)
+{
+	int len;
+	if (mddev->bitmap)
+		len = sprintf(page, "%s\n", (mddev->bitmap->need_sync ?
+					     "false" : "true"));
+	else
+		len = sprintf(page, "\n");
+	return len;
+}
+
+static ssize_t can_clear_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	if (mddev->bitmap == NULL)
+		return -ENOENT;
+	if (strncmp(buf, "false", 5) == 0)
+		mddev->bitmap->need_sync = 1;
+	else if (strncmp(buf, "true", 4) == 0) {
+		if (mddev->degraded)
+			return -EBUSY;
+		mddev->bitmap->need_sync = 0;
+	} else
+		return -EINVAL;
+	return len;
+}
+
+static struct md_sysfs_entry bitmap_can_clear =
+__ATTR(can_clear, S_IRUGO|S_IWUSR, can_clear_show, can_clear_store);
+
+static struct attribute *md_bitmap_attrs[] = {
+	&bitmap_location.attr,
+	&bitmap_timeout.attr,
+	&bitmap_backlog.attr,
+	&bitmap_chunksize.attr,
+	&bitmap_metadata.attr,
+	&bitmap_can_clear.attr,
+	NULL
+};
+struct attribute_group md_bitmap_group = {
+	.name = "bitmap",
+	.attrs = md_bitmap_attrs,
+};
+
+
 /* the bitmap API -- for raid personalities */
 EXPORT_SYMBOL(bitmap_startwrite);
 EXPORT_SYMBOL(bitmap_endwrite);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/bitmap.h linux-libre-2.6.33-gnu1/drivers/md/bitmap.h
--- linux-libre-2.6.32-gnu1/drivers/md/bitmap.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/bitmap.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,7 +106,7 @@ typedef __u16 bitmap_counter_t;
 #define BITMAP_BLOCK_SHIFT 9
 
 /* how many blocks per chunk? (this is variable) */
-#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT)
 #define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT)
 #define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1)
 
@@ -118,16 +118,6 @@ typedef __u16 bitmap_counter_t;
 			(CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1)
 #define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1)
 
-/*
- * on-disk bitmap:
- *
- * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
- * file a page at a time. There's a superblock at the start of the file.
- */
-
-/* map chunks (bits) to file pages - offset by the size of the superblock */
-#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3))
-
 #endif
 
 /*
@@ -209,7 +199,6 @@ struct bitmap {
 	int counter_bits; /* how many bits per block counter */
 
 	/* bitmap chunksize -- how much data does each bit represent? */
-	unsigned long chunksize;
 	unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */
 	unsigned long chunks; /* total number of data chunks for the array */
 
@@ -226,7 +215,6 @@ struct bitmap {
 	/* bitmap spinlock */
 	spinlock_t lock;
 
-	long offset; /* offset from superblock if file is NULL */
 	struct file *file; /* backing disk file */
 	struct page *sb_page; /* cached copy of the bitmap file superblock */
 	struct page **filemap; /* list of cache pages for the file */
@@ -238,7 +226,6 @@ struct bitmap {
 
 	int allclean;
 
-	unsigned long max_write_behind; /* write-behind mode */
 	atomic_t behind_writes;
 
 	/*
@@ -246,7 +233,6 @@ struct bitmap {
 	 * file, cleaning up bits and flushing out pages to disk as necessary
 	 */
 	unsigned long daemon_lastrun; /* jiffies of last run */
-	unsigned long daemon_sleep; /* how many seconds between updates? */
 	unsigned long last_end_sync; /* when we lasted called end_sync to
 				      * update bitmap with resync progress */
 
@@ -254,6 +240,7 @@ struct bitmap {
 	wait_queue_head_t write_wait;
 	wait_queue_head_t overflow_wait;
 
+	struct sysfs_dirent *sysfs_can_clear;
 };
 
 /* the bitmap API */
@@ -282,7 +269,7 @@ void bitmap_close_sync(struct bitmap *bi
 void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
 
 void bitmap_unplug(struct bitmap *bitmap);
-void bitmap_daemon_work(struct bitmap *bitmap);
+void bitmap_daemon_work(mddev_t *mddev);
 #endif
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm.c linux-libre-2.6.33-gnu1/drivers/md/dm.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm.c	2010-02-24 13:52:17.000000000 -0500
@@ -143,9 +143,19 @@ struct mapped_device {
 	int barrier_error;
 
 	/*
+	 * Protect barrier_error from concurrent endio processing
+	 * in request-based dm.
+	 */
+	spinlock_t barrier_error_lock;
+
+	/*
 	 * Processing queue (flush/barriers)
 	 */
 	struct workqueue_struct *wq;
+	struct work_struct barrier_work;
+
+	/* A pointer to the currently processing pre/post flush request */
+	struct request *flush_request;
 
 	/*
 	 * The current mapping.
@@ -178,9 +188,6 @@ struct mapped_device {
 	/* forced geometry settings */
 	struct hd_geometry geometry;
 
-	/* marker of flush suspend for request-based dm */
-	struct request suspend_rq;
-
 	/* For saving the address of __make_request for request based dm */
 	make_request_fn *saved_make_request_fn;
 
@@ -275,6 +282,7 @@ static int (*_inits[])(void) __initdata
 	dm_target_init,
 	dm_linear_init,
 	dm_stripe_init,
+	dm_io_init,
 	dm_kcopyd_init,
 	dm_interface_init,
 };
@@ -284,6 +292,7 @@ static void (*_exits[])(void) = {
 	dm_target_exit,
 	dm_linear_exit,
 	dm_stripe_exit,
+	dm_io_exit,
 	dm_kcopyd_exit,
 	dm_interface_exit,
 };
@@ -320,6 +329,11 @@ static void __exit dm_exit(void)
 /*
  * Block device functions
  */
+int dm_deleting_md(struct mapped_device *md)
+{
+	return test_bit(DMF_DELETING, &md->flags);
+}
+
 static int dm_blk_open(struct block_device *bdev, fmode_t mode)
 {
 	struct mapped_device *md;
@@ -331,7 +345,7 @@ static int dm_blk_open(struct block_devi
 		goto out;
 
 	if (test_bit(DMF_FREEING, &md->flags) ||
-	    test_bit(DMF_DELETING, &md->flags)) {
+	    dm_deleting_md(md)) {
 		md = NULL;
 		goto out;
 	}
@@ -388,7 +402,7 @@ 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_table(md);
+	struct dm_table *map = dm_get_live_table(md);
 	struct dm_target *tgt;
 	int r = -ENOTTY;
 
@@ -401,7 +415,7 @@ static int dm_blk_ioctl(struct block_dev
 
 	tgt = dm_table_get_target(map, 0);
 
-	if (dm_suspended(md)) {
+	if (dm_suspended_md(md)) {
 		r = -EAGAIN;
 		goto out;
 	}
@@ -430,9 +444,10 @@ static void free_tio(struct mapped_devic
 	mempool_free(tio, md->tio_pool);
 }
 
-static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md)
+static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md,
+					    gfp_t gfp_mask)
 {
-	return mempool_alloc(md->tio_pool, GFP_ATOMIC);
+	return mempool_alloc(md->tio_pool, gfp_mask);
 }
 
 static void free_rq_tio(struct dm_rq_target_io *tio)
@@ -450,6 +465,12 @@ static void free_bio_info(struct dm_rq_c
 	mempool_free(info, info->tio->md->io_pool);
 }
 
+static int md_in_flight(struct mapped_device *md)
+{
+	return atomic_read(&md->pending[READ]) +
+	       atomic_read(&md->pending[WRITE]);
+}
+
 static void start_io_acct(struct dm_io *io)
 {
 	struct mapped_device *md = io->md;
@@ -512,7 +533,7 @@ static void queue_io(struct mapped_devic
  * function to access the md->map field, and make sure they call
  * dm_table_put() when finished.
  */
-struct dm_table *dm_get_table(struct mapped_device *md)
+struct dm_table *dm_get_live_table(struct mapped_device *md)
 {
 	struct dm_table *t;
 	unsigned long flags;
@@ -716,28 +737,38 @@ static void end_clone_bio(struct bio *cl
 	blk_update_request(tio->orig, 0, nr_bytes);
 }
 
+static void store_barrier_error(struct mapped_device *md, int error)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&md->barrier_error_lock, flags);
+	/*
+	 * Basically, the first error is taken, but:
+	 *   -EOPNOTSUPP supersedes any I/O error.
+	 *   Requeue request supersedes any I/O error but -EOPNOTSUPP.
+	 */
+	if (!md->barrier_error || error == -EOPNOTSUPP ||
+	    (md->barrier_error != -EOPNOTSUPP &&
+	     error == DM_ENDIO_REQUEUE))
+		md->barrier_error = error;
+	spin_unlock_irqrestore(&md->barrier_error_lock, flags);
+}
+
 /*
  * Don't touch any member of the md after calling this function because
  * the md may be freed in dm_put() at the end of this function.
  * Or do dm_get() before calling this function and dm_put() later.
  */
-static void rq_completed(struct mapped_device *md, int run_queue)
+static void rq_completed(struct mapped_device *md, int rw, int run_queue)
 {
-	int wakeup_waiters = 0;
-	struct request_queue *q = md->queue;
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	if (!queue_in_flight(q))
-		wakeup_waiters = 1;
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	atomic_dec(&md->pending[rw]);
 
 	/* nudge anyone waiting on suspend queue */
-	if (wakeup_waiters)
+	if (!md_in_flight(md))
 		wake_up(&md->wait);
 
 	if (run_queue)
-		blk_run_queue(q);
+		blk_run_queue(md->queue);
 
 	/*
 	 * dm_put() must be at the end of this function. See the comment above
@@ -753,6 +784,44 @@ static void free_rq_clone(struct request
 	free_rq_tio(tio);
 }
 
+/*
+ * Complete the clone and the original request.
+ * Must be called without queue lock.
+ */
+static void dm_end_request(struct request *clone, int error)
+{
+	int rw = rq_data_dir(clone);
+	int run_queue = 1;
+	bool is_barrier = blk_barrier_rq(clone);
+	struct dm_rq_target_io *tio = clone->end_io_data;
+	struct mapped_device *md = tio->md;
+	struct request *rq = tio->orig;
+
+	if (blk_pc_request(rq) && !is_barrier) {
+		rq->errors = clone->errors;
+		rq->resid_len = clone->resid_len;
+
+		if (rq->sense)
+			/*
+			 * We are using the sense buffer of the original
+			 * request.
+			 * So setting the length of the sense data is enough.
+			 */
+			rq->sense_len = clone->sense_len;
+	}
+
+	free_rq_clone(clone);
+
+	if (unlikely(is_barrier)) {
+		if (unlikely(error))
+			store_barrier_error(md, error);
+		run_queue = 0;
+	} else
+		blk_end_request_all(rq, error);
+
+	rq_completed(md, rw, run_queue);
+}
+
 static void dm_unprep_request(struct request *rq)
 {
 	struct request *clone = rq->special;
@@ -768,12 +837,23 @@ static void dm_unprep_request(struct req
  */
 void dm_requeue_unmapped_request(struct request *clone)
 {
+	int rw = rq_data_dir(clone);
 	struct dm_rq_target_io *tio = clone->end_io_data;
 	struct mapped_device *md = tio->md;
 	struct request *rq = tio->orig;
 	struct request_queue *q = rq->q;
 	unsigned long flags;
 
+	if (unlikely(blk_barrier_rq(clone))) {
+		/*
+		 * Barrier clones share an original request.
+		 * Leave it to dm_end_request(), which handles this special
+		 * case.
+		 */
+		dm_end_request(clone, DM_ENDIO_REQUEUE);
+		return;
+	}
+
 	dm_unprep_request(rq);
 
 	spin_lock_irqsave(q->queue_lock, flags);
@@ -782,7 +862,7 @@ void dm_requeue_unmapped_request(struct
 	blk_requeue_request(q, rq);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 
-	rq_completed(md, 0);
+	rq_completed(md, rw, 0);
 }
 EXPORT_SYMBOL_GPL(dm_requeue_unmapped_request);
 
@@ -815,34 +895,28 @@ static void start_queue(struct request_q
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
-/*
- * Complete the clone and the original request.
- * Must be called without queue lock.
- */
-static void dm_end_request(struct request *clone, int error)
+static void dm_done(struct request *clone, int error, bool mapped)
 {
+	int r = error;
 	struct dm_rq_target_io *tio = clone->end_io_data;
-	struct mapped_device *md = tio->md;
-	struct request *rq = tio->orig;
+	dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io;
 
-	if (blk_pc_request(rq)) {
-		rq->errors = clone->errors;
-		rq->resid_len = clone->resid_len;
+	if (mapped && rq_end_io)
+		r = rq_end_io(tio->ti, clone, error, &tio->info);
 
-		if (rq->sense)
-			/*
-			 * We are using the sense buffer of the original
-			 * request.
-			 * So setting the length of the sense data is enough.
-			 */
-			rq->sense_len = clone->sense_len;
+	if (r <= 0)
+		/* The target wants to complete the I/O */
+		dm_end_request(clone, r);
+	else if (r == DM_ENDIO_INCOMPLETE)
+		/* The target will handle the I/O */
+		return;
+	else if (r == DM_ENDIO_REQUEUE)
+		/* The target wants to requeue the I/O */
+		dm_requeue_unmapped_request(clone);
+	else {
+		DMWARN("unimplemented target endio return value: %d", r);
+		BUG();
 	}
-
-	free_rq_clone(clone);
-
-	blk_end_request_all(rq, error);
-
-	rq_completed(md, 1);
 }
 
 /*
@@ -850,27 +924,14 @@ static void dm_end_request(struct reques
  */
 static void dm_softirq_done(struct request *rq)
 {
+	bool mapped = true;
 	struct request *clone = rq->completion_data;
 	struct dm_rq_target_io *tio = clone->end_io_data;
-	dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io;
-	int error = tio->error;
 
-	if (!(rq->cmd_flags & REQ_FAILED) && rq_end_io)
-		error = rq_end_io(tio->ti, clone, error, &tio->info);
+	if (rq->cmd_flags & REQ_FAILED)
+		mapped = false;
 
-	if (error <= 0)
-		/* The target wants to complete the I/O */
-		dm_end_request(clone, error);
-	else if (error == DM_ENDIO_INCOMPLETE)
-		/* The target will handle the I/O */
-		return;
-	else if (error == DM_ENDIO_REQUEUE)
-		/* The target wants to requeue the I/O */
-		dm_requeue_unmapped_request(clone);
-	else {
-		DMWARN("unimplemented target endio return value: %d", error);
-		BUG();
-	}
+	dm_done(clone, tio->error, mapped);
 }
 
 /*
@@ -882,6 +943,19 @@ static void dm_complete_request(struct r
 	struct dm_rq_target_io *tio = clone->end_io_data;
 	struct request *rq = tio->orig;
 
+	if (unlikely(blk_barrier_rq(clone))) {
+		/*
+		 * Barrier clones share an original request.  So can't use
+		 * softirq_done with the original.
+		 * Pass the clone to dm_done() directly in this special case.
+		 * It is safe (even if clone->q->queue_lock is held here)
+		 * because there is no I/O dispatching during the completion
+		 * of barrier clone.
+		 */
+		dm_done(clone, error, true);
+		return;
+	}
+
 	tio->error = error;
 	rq->completion_data = clone;
 	blk_complete_request(rq);
@@ -898,6 +972,17 @@ void dm_kill_unmapped_request(struct req
 	struct dm_rq_target_io *tio = clone->end_io_data;
 	struct request *rq = tio->orig;
 
+	if (unlikely(blk_barrier_rq(clone))) {
+		/*
+		 * Barrier clones share an original request.
+		 * Leave it to dm_end_request(), which handles this special
+		 * case.
+		 */
+		BUG_ON(error > 0);
+		dm_end_request(clone, error);
+		return;
+	}
+
 	rq->cmd_flags |= REQ_FAILED;
 	dm_complete_request(clone, error);
 }
@@ -1214,7 +1299,7 @@ static void __split_and_process_bio(stru
 	struct clone_info ci;
 	int error = 0;
 
-	ci.map = dm_get_table(md);
+	ci.map = dm_get_live_table(md);
 	if (unlikely(!ci.map)) {
 		if (!bio_rw_flagged(bio, BIO_RW_BARRIER))
 			bio_io_error(bio);
@@ -1255,7 +1340,7 @@ static int dm_merge_bvec(struct request_
 			 struct bio_vec *biovec)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_table(md);
+	struct dm_table *map = dm_get_live_table(md);
 	struct dm_target *ti;
 	sector_t max_sectors;
 	int max_size = 0;
@@ -1352,11 +1437,6 @@ static int dm_make_request(struct reques
 {
 	struct mapped_device *md = q->queuedata;
 
-	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
-		bio_endio(bio, -EOPNOTSUPP);
-		return 0;
-	}
-
 	return md->saved_make_request_fn(q, bio); /* call __make_request() */
 }
 
@@ -1375,6 +1455,25 @@ static int dm_request(struct request_que
 	return _dm_request(q, bio);
 }
 
+/*
+ * Mark this request as flush request, so that dm_request_fn() can
+ * recognize.
+ */
+static void dm_rq_prepare_flush(struct request_queue *q, struct request *rq)
+{
+	rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
+	rq->cmd[0] = REQ_LB_OP_FLUSH;
+}
+
+static bool dm_rq_is_flush_request(struct request *rq)
+{
+	if (rq->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+	    rq->cmd[0] == REQ_LB_OP_FLUSH)
+		return true;
+	else
+		return false;
+}
+
 void dm_dispatch_request(struct request *rq)
 {
 	int r;
@@ -1420,25 +1519,54 @@ static int dm_rq_bio_constructor(struct
 static int setup_clone(struct request *clone, struct request *rq,
 		       struct dm_rq_target_io *tio)
 {
-	int r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC,
-				  dm_rq_bio_constructor, tio);
+	int r;
 
-	if (r)
-		return r;
+	if (dm_rq_is_flush_request(rq)) {
+		blk_rq_init(NULL, clone);
+		clone->cmd_type = REQ_TYPE_FS;
+		clone->cmd_flags |= (REQ_HARDBARRIER | WRITE);
+	} else {
+		r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC,
+				      dm_rq_bio_constructor, tio);
+		if (r)
+			return r;
+
+		clone->cmd = rq->cmd;
+		clone->cmd_len = rq->cmd_len;
+		clone->sense = rq->sense;
+		clone->buffer = rq->buffer;
+	}
 
-	clone->cmd = rq->cmd;
-	clone->cmd_len = rq->cmd_len;
-	clone->sense = rq->sense;
-	clone->buffer = rq->buffer;
 	clone->end_io = end_clone_request;
 	clone->end_io_data = tio;
 
 	return 0;
 }
 
-static int dm_rq_flush_suspending(struct mapped_device *md)
+static struct request *clone_rq(struct request *rq, struct mapped_device *md,
+				gfp_t gfp_mask)
 {
-	return !md->suspend_rq.special;
+	struct request *clone;
+	struct dm_rq_target_io *tio;
+
+	tio = alloc_rq_tio(md, gfp_mask);
+	if (!tio)
+		return NULL;
+
+	tio->md = md;
+	tio->ti = NULL;
+	tio->orig = rq;
+	tio->error = 0;
+	memset(&tio->info, 0, sizeof(tio->info));
+
+	clone = &tio->clone;
+	if (setup_clone(clone, rq, tio)) {
+		/* -ENOMEM */
+		free_rq_tio(tio);
+		return NULL;
+	}
+
+	return clone;
 }
 
 /*
@@ -1447,39 +1575,19 @@ static int dm_rq_flush_suspending(struct
 static int dm_prep_fn(struct request_queue *q, struct request *rq)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_rq_target_io *tio;
 	struct request *clone;
 
-	if (unlikely(rq == &md->suspend_rq)) {
-		if (dm_rq_flush_suspending(md))
-			return BLKPREP_OK;
-		else
-			/* The flush suspend was interrupted */
-			return BLKPREP_KILL;
-	}
+	if (unlikely(dm_rq_is_flush_request(rq)))
+		return BLKPREP_OK;
 
 	if (unlikely(rq->special)) {
 		DMWARN("Already has something in rq->special.");
 		return BLKPREP_KILL;
 	}
 
-	tio = alloc_rq_tio(md); /* Only one for each original request */
-	if (!tio)
-		/* -ENOMEM */
-		return BLKPREP_DEFER;
-
-	tio->md = md;
-	tio->ti = NULL;
-	tio->orig = rq;
-	tio->error = 0;
-	memset(&tio->info, 0, sizeof(tio->info));
-
-	clone = &tio->clone;
-	if (setup_clone(clone, rq, tio)) {
-		/* -ENOMEM */
-		free_rq_tio(tio);
+	clone = clone_rq(rq, md, GFP_ATOMIC);
+	if (!clone)
 		return BLKPREP_DEFER;
-	}
 
 	rq->special = clone;
 	rq->cmd_flags |= REQ_DONTPREP;
@@ -1487,11 +1595,15 @@ static int dm_prep_fn(struct request_que
 	return BLKPREP_OK;
 }
 
-static void map_request(struct dm_target *ti, struct request *rq,
-			struct mapped_device *md)
+/*
+ * Returns:
+ * 0  : the request has been processed (not requeued)
+ * !0 : the request has been requeued
+ */
+static int map_request(struct dm_target *ti, struct request *clone,
+		       struct mapped_device *md)
 {
-	int r;
-	struct request *clone = rq->special;
+	int r, requeued = 0;
 	struct dm_rq_target_io *tio = clone->end_io_data;
 
 	/*
@@ -1511,11 +1623,14 @@ static void map_request(struct dm_target
 		break;
 	case DM_MAPIO_REMAPPED:
 		/* The target has remapped the I/O so dispatch it */
+		trace_block_rq_remap(clone->q, clone, disk_devt(dm_disk(md)),
+				     blk_rq_pos(tio->orig));
 		dm_dispatch_request(clone);
 		break;
 	case DM_MAPIO_REQUEUE:
 		/* The target wants to requeue the I/O */
 		dm_requeue_unmapped_request(clone);
+		requeued = 1;
 		break;
 	default:
 		if (r > 0) {
@@ -1527,6 +1642,8 @@ static void map_request(struct dm_target
 		dm_kill_unmapped_request(clone, r);
 		break;
 	}
+
+	return requeued;
 }
 
 /*
@@ -1536,29 +1653,26 @@ static void map_request(struct dm_target
 static void dm_request_fn(struct request_queue *q)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_table(md);
+	struct dm_table *map = dm_get_live_table(md);
 	struct dm_target *ti;
-	struct request *rq;
+	struct request *rq, *clone;
 
 	/*
-	 * For noflush suspend, check blk_queue_stopped() to immediately
-	 * quit I/O dispatching.
+	 * For suspend, check blk_queue_stopped() and increment
+	 * ->pending within a single queue_lock not to increment the
+	 * number of in-flight I/Os after the queue is stopped in
+	 * dm_suspend().
 	 */
 	while (!blk_queue_plugged(q) && !blk_queue_stopped(q)) {
 		rq = blk_peek_request(q);
 		if (!rq)
 			goto plug_and_out;
 
-		if (unlikely(rq == &md->suspend_rq)) { /* Flush suspend maker */
-			if (queue_in_flight(q))
-				/* Not quiet yet.  Wait more */
-				goto plug_and_out;
-
-			/* This device should be quiet now */
-			__stop_queue(q);
+		if (unlikely(dm_rq_is_flush_request(rq))) {
+			BUG_ON(md->flush_request);
+			md->flush_request = rq;
 			blk_start_request(rq);
-			__blk_end_request_all(rq, 0);
-			wake_up(&md->wait);
+			queue_work(md->wq, &md->barrier_work);
 			goto out;
 		}
 
@@ -1567,13 +1681,21 @@ static void dm_request_fn(struct request
 			goto plug_and_out;
 
 		blk_start_request(rq);
+		clone = rq->special;
+		atomic_inc(&md->pending[rq_data_dir(clone)]);
+
 		spin_unlock(q->queue_lock);
-		map_request(ti, rq, md);
+		if (map_request(ti, clone, md))
+			goto requeued;
+
 		spin_lock_irq(q->queue_lock);
 	}
 
 	goto out;
 
+requeued:
+	spin_lock_irq(q->queue_lock);
+
 plug_and_out:
 	if (!elv_queue_empty(q))
 		/* Some requests still remain, retry later */
@@ -1595,7 +1717,7 @@ static int dm_lld_busy(struct request_qu
 {
 	int r;
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_table(md);
+	struct dm_table *map = dm_get_live_table(md);
 
 	if (!map || test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))
 		r = 1;
@@ -1610,7 +1732,7 @@ static int dm_lld_busy(struct request_qu
 static void dm_unplug_all(struct request_queue *q)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_table(md);
+	struct dm_table *map = dm_get_live_table(md);
 
 	if (map) {
 		if (dm_request_based(md))
@@ -1628,7 +1750,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_table(md);
+		map = dm_get_live_table(md);
 		if (map) {
 			/*
 			 * Request-based dm cares about only own queue for
@@ -1725,6 +1847,7 @@ out:
 static const struct block_device_operations dm_blk_dops;
 
 static void dm_wq_work(struct work_struct *work);
+static void dm_rq_barrier_work(struct work_struct *work);
 
 /*
  * Allocate and initialise a blank device with a given minor.
@@ -1754,6 +1877,7 @@ static struct mapped_device *alloc_dev(i
 	init_rwsem(&md->io_lock);
 	mutex_init(&md->suspend_lock);
 	spin_lock_init(&md->deferred_lock);
+	spin_lock_init(&md->barrier_error_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
@@ -1788,6 +1912,8 @@ static struct mapped_device *alloc_dev(i
 	blk_queue_softirq_done(md->queue, dm_softirq_done);
 	blk_queue_prep_rq(md->queue, dm_prep_fn);
 	blk_queue_lld_busy(md->queue, dm_lld_busy);
+	blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+			  dm_rq_prepare_flush);
 
 	md->disk = alloc_disk(1);
 	if (!md->disk)
@@ -1797,6 +1923,7 @@ static struct mapped_device *alloc_dev(i
 	atomic_set(&md->pending[1], 0);
 	init_waitqueue_head(&md->wait);
 	INIT_WORK(&md->work, dm_wq_work);
+	INIT_WORK(&md->barrier_work, dm_rq_barrier_work);
 	init_waitqueue_head(&md->eventq);
 
 	md->disk->major = _major;
@@ -1921,9 +2048,13 @@ static void __set_size(struct mapped_dev
 	mutex_unlock(&md->bdev->bd_inode->i_mutex);
 }
 
-static int __bind(struct mapped_device *md, struct dm_table *t,
-		  struct queue_limits *limits)
+/*
+ * Returns old map, which caller must destroy.
+ */
+static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+			       struct queue_limits *limits)
 {
+	struct dm_table *old_map;
 	struct request_queue *q = md->queue;
 	sector_t size;
 	unsigned long flags;
@@ -1938,11 +2069,6 @@ static int __bind(struct mapped_device *
 
 	__set_size(md, size);
 
-	if (!size) {
-		dm_table_destroy(t);
-		return 0;
-	}
-
 	dm_table_event_callback(t, event_callback, md);
 
 	/*
@@ -1958,26 +2084,31 @@ static int __bind(struct mapped_device *
 	__bind_mempools(md, t);
 
 	write_lock_irqsave(&md->map_lock, flags);
+	old_map = md->map;
 	md->map = t;
 	dm_table_set_restrictions(t, q, limits);
 	write_unlock_irqrestore(&md->map_lock, flags);
 
-	return 0;
+	return old_map;
 }
 
-static void __unbind(struct mapped_device *md)
+/*
+ * Returns unbound table for the caller to free.
+ */
+static struct dm_table *__unbind(struct mapped_device *md)
 {
 	struct dm_table *map = md->map;
 	unsigned long flags;
 
 	if (!map)
-		return;
+		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);
-	dm_table_destroy(map);
+
+	return map;
 }
 
 /*
@@ -2059,18 +2190,18 @@ void dm_put(struct mapped_device *md)
 	BUG_ON(test_bit(DMF_FREEING, &md->flags));
 
 	if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
-		map = dm_get_table(md);
+		map = dm_get_live_table(md);
 		idr_replace(&_minor_idr, MINOR_ALLOCED,
 			    MINOR(disk_devt(dm_disk(md))));
 		set_bit(DMF_FREEING, &md->flags);
 		spin_unlock(&_minor_lock);
-		if (!dm_suspended(md)) {
+		if (!dm_suspended_md(md)) {
 			dm_table_presuspend_targets(map);
 			dm_table_postsuspend_targets(map);
 		}
 		dm_sysfs_exit(md);
 		dm_table_put(map);
-		__unbind(md);
+		dm_table_destroy(__unbind(md));
 		free_dev(md);
 	}
 }
@@ -2080,8 +2211,6 @@ static int dm_wait_for_completion(struct
 {
 	int r = 0;
 	DECLARE_WAITQUEUE(wait, current);
-	struct request_queue *q = md->queue;
-	unsigned long flags;
 
 	dm_unplug_all(md->queue);
 
@@ -2091,15 +2220,7 @@ static int dm_wait_for_completion(struct
 		set_current_state(interruptible);
 
 		smp_mb();
-		if (dm_request_based(md)) {
-			spin_lock_irqsave(q->queue_lock, flags);
-			if (!queue_in_flight(q) && blk_queue_stopped(q)) {
-				spin_unlock_irqrestore(q->queue_lock, flags);
-				break;
-			}
-			spin_unlock_irqrestore(q->queue_lock, flags);
-		} else if (!atomic_read(&md->pending[0]) &&
-					!atomic_read(&md->pending[1]))
+		if (!md_in_flight(md))
 			break;
 
 		if (interruptible == TASK_INTERRUPTIBLE &&
@@ -2194,98 +2315,106 @@ static void dm_queue_flush(struct mapped
 	queue_work(md->wq, &md->work);
 }
 
-/*
- * Swap in a new table (destroying old one).
- */
-int dm_swap_table(struct mapped_device *md, struct dm_table *table)
+static void dm_rq_set_flush_nr(struct request *clone, unsigned flush_nr)
 {
-	struct queue_limits limits;
-	int r = -EINVAL;
+	struct dm_rq_target_io *tio = clone->end_io_data;
 
-	mutex_lock(&md->suspend_lock);
+	tio->info.flush_request = flush_nr;
+}
 
-	/* device must be suspended */
-	if (!dm_suspended(md))
-		goto out;
+/* Issue barrier requests to targets and wait for their completion. */
+static int dm_rq_barrier(struct mapped_device *md)
+{
+	int i, j;
+	struct dm_table *map = dm_get_live_table(md);
+	unsigned num_targets = dm_table_get_num_targets(map);
+	struct dm_target *ti;
+	struct request *clone;
 
-	r = dm_calculate_queue_limits(table, &limits);
-	if (r)
-		goto out;
+	md->barrier_error = 0;
 
-	/* cannot change the device type, once a table is bound */
-	if (md->map &&
-	    (dm_table_get_type(md->map) != dm_table_get_type(table))) {
-		DMWARN("can't change the device type after a table is bound");
-		goto out;
+	for (i = 0; i < num_targets; i++) {
+		ti = dm_table_get_target(map, i);
+		for (j = 0; j < ti->num_flush_requests; j++) {
+			clone = clone_rq(md->flush_request, md, GFP_NOIO);
+			dm_rq_set_flush_nr(clone, j);
+			atomic_inc(&md->pending[rq_data_dir(clone)]);
+			map_request(ti, clone, md);
+		}
 	}
 
-	__unbind(md);
-	r = __bind(md, table, &limits);
-
-out:
-	mutex_unlock(&md->suspend_lock);
-	return r;
-}
+	dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
+	dm_table_put(map);
 
-static void dm_rq_invalidate_suspend_marker(struct mapped_device *md)
-{
-	md->suspend_rq.special = (void *)0x1;
+	return md->barrier_error;
 }
 
-static void dm_rq_abort_suspend(struct mapped_device *md, int noflush)
+static void dm_rq_barrier_work(struct work_struct *work)
 {
+	int error;
+	struct mapped_device *md = container_of(work, struct mapped_device,
+						barrier_work);
 	struct request_queue *q = md->queue;
+	struct request *rq;
 	unsigned long flags;
 
-	spin_lock_irqsave(q->queue_lock, flags);
-	if (!noflush)
-		dm_rq_invalidate_suspend_marker(md);
-	__start_queue(q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
-}
+	/*
+	 * Hold the md reference here and leave it at the last part so that
+	 * the md can't be deleted by device opener when the barrier request
+	 * completes.
+	 */
+	dm_get(md);
 
-static void dm_rq_start_suspend(struct mapped_device *md, int noflush)
-{
-	struct request *rq = &md->suspend_rq;
-	struct request_queue *q = md->queue;
+	error = dm_rq_barrier(md);
 
-	if (noflush)
-		stop_queue(q);
-	else {
-		blk_rq_init(q, rq);
-		blk_insert_request(q, rq, 0, NULL);
-	}
+	rq = md->flush_request;
+	md->flush_request = NULL;
+
+	if (error == DM_ENDIO_REQUEUE) {
+		spin_lock_irqsave(q->queue_lock, flags);
+		blk_requeue_request(q, rq);
+		spin_unlock_irqrestore(q->queue_lock, flags);
+	} else
+		blk_end_request_all(rq, error);
+
+	blk_run_queue(q);
+
+	dm_put(md);
 }
 
-static int dm_rq_suspend_available(struct mapped_device *md, int noflush)
+/*
+ * Swap in a new table, returning the old one for the caller to destroy.
+ */
+struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
 {
-	int r = 1;
-	struct request *rq = &md->suspend_rq;
-	struct request_queue *q = md->queue;
-	unsigned long flags;
+	struct dm_table *map = ERR_PTR(-EINVAL);
+	struct queue_limits limits;
+	int r;
 
-	if (noflush)
-		return r;
+	mutex_lock(&md->suspend_lock);
 
-	/* The marker must be protected by queue lock if it is in use */
-	spin_lock_irqsave(q->queue_lock, flags);
-	if (unlikely(rq->ref_count)) {
-		/*
-		 * This can happen, when the previous flush suspend was
-		 * interrupted, the marker is still in the queue and
-		 * this flush suspend has been invoked, because we don't
-		 * remove the marker at the time of suspend interruption.
-		 * We have only one marker per mapped_device, so we can't
-		 * start another flush suspend while it is in use.
-		 */
-		BUG_ON(!rq->special); /* The marker should be invalidated */
-		DMWARN("Invalidating the previous flush suspend is still in"
-		       " progress.  Please retry later.");
-		r = 0;
+	/* device must be suspended */
+	if (!dm_suspended_md(md))
+		goto out;
+
+	r = dm_calculate_queue_limits(table, &limits);
+	if (r) {
+		map = ERR_PTR(r);
+		goto out;
 	}
-	spin_unlock_irqrestore(q->queue_lock, flags);
 
-	return r;
+	/* cannot change the device type, once a table is bound */
+	if (md->map &&
+	    (dm_table_get_type(md->map) != dm_table_get_type(table))) {
+		DMWARN("can't change the device type after a table is bound");
+		goto out;
+	}
+
+	map = __bind(md, table, &limits);
+
+out:
+	mutex_unlock(&md->suspend_lock);
+	return map;
 }
 
 /*
@@ -2330,49 +2459,11 @@ static void unlock_fs(struct mapped_devi
 /*
  * Suspend mechanism in request-based dm.
  *
- * After the suspend starts, further incoming requests are kept in
- * the request_queue and deferred.
- * Remaining requests in the request_queue at the start of suspend are flushed
- * if it is flush suspend.
- * The suspend completes when the following conditions have been satisfied,
- * so wait for it:
- *    1. q->in_flight is 0 (which means no in_flight request)
- *    2. queue has been stopped (which means no request dispatching)
- *
- *
- * Noflush suspend
- * ---------------
- * Noflush suspend doesn't need to dispatch remaining requests.
- * So stop the queue immediately.  Then, wait for all in_flight requests
- * to be completed or requeued.
- *
- * To abort noflush suspend, start the queue.
- *
- *
- * Flush suspend
- * -------------
- * Flush suspend needs to dispatch remaining requests.  So stop the queue
- * after the remaining requests are completed. (Requeued request must be also
- * re-dispatched and completed.  Until then, we can't stop the queue.)
- *
- * During flushing the remaining requests, further incoming requests are also
- * inserted to the same queue.  To distinguish which requests are to be
- * flushed, we insert a marker request to the queue at the time of starting
- * flush suspend, like a barrier.
- * The dispatching is blocked when the marker is found on the top of the queue.
- * And the queue is stopped when all in_flight requests are completed, since
- * that means the remaining requests are completely flushed.
- * Then, the marker is removed from the queue.
+ * 1. Flush all I/Os by lock_fs() if needed.
+ * 2. Stop dispatching any I/O by stopping the request_queue.
+ * 3. Wait for all in-flight I/Os to be completed or requeued.
  *
- * To abort flush suspend, we also need to take care of the marker, not only
- * starting the queue.
- * We don't remove the marker forcibly from the queue since it's against
- * the block-layer manner.  Instead, we put a invalidated mark on the marker.
- * When the invalidated marker is found on the top of the queue, it is
- * immediately removed from the queue, so it doesn't block dispatching.
- * Because we have only one marker per mapped_device, we can't start another
- * flush suspend until the invalidated marker is removed from the queue.
- * So fail and return with -EBUSY in such a case.
+ * To abort suspend, start the request_queue.
  */
 int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 {
@@ -2383,17 +2474,12 @@ int dm_suspend(struct mapped_device *md,
 
 	mutex_lock(&md->suspend_lock);
 
-	if (dm_suspended(md)) {
+	if (dm_suspended_md(md)) {
 		r = -EINVAL;
 		goto out_unlock;
 	}
 
-	if (dm_request_based(md) && !dm_rq_suspend_available(md, noflush)) {
-		r = -EBUSY;
-		goto out_unlock;
-	}
-
-	map = dm_get_table(md);
+	map = dm_get_live_table(md);
 
 	/*
 	 * DMF_NOFLUSH_SUSPENDING must be set before presuspend.
@@ -2406,8 +2492,10 @@ int dm_suspend(struct mapped_device *md,
 	dm_table_presuspend_targets(map);
 
 	/*
-	 * Flush I/O to the device. noflush supersedes do_lockfs,
-	 * because lock_fs() needs to flush I/Os.
+	 * Flush I/O to the device.
+	 * Any I/O submitted after lock_fs() may not be flushed.
+	 * noflush takes precedence over do_lockfs.
+	 * (lock_fs() flushes I/Os and waits for them to complete.)
 	 */
 	if (!noflush && do_lockfs) {
 		r = lock_fs(md);
@@ -2436,10 +2524,15 @@ int dm_suspend(struct mapped_device *md,
 	set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
 	up_write(&md->io_lock);
 
-	flush_workqueue(md->wq);
-
+	/*
+	 * Request-based dm uses md->wq for barrier (dm_rq_barrier_work) which
+	 * can be kicked until md->queue is stopped.  So stop md->queue before
+	 * flushing md->wq.
+	 */
 	if (dm_request_based(md))
-		dm_rq_start_suspend(md, noflush);
+		stop_queue(md->queue);
+
+	flush_workqueue(md->wq);
 
 	/*
 	 * At this point no more requests are entering target request routines.
@@ -2458,7 +2551,7 @@ int dm_suspend(struct mapped_device *md,
 		dm_queue_flush(md);
 
 		if (dm_request_based(md))
-			dm_rq_abort_suspend(md, noflush);
+			start_queue(md->queue);
 
 		unlock_fs(md);
 		goto out; /* pushback list is already flushed, so skip flush */
@@ -2470,10 +2563,10 @@ int dm_suspend(struct mapped_device *md,
 	 * requests are being added to md->deferred list.
 	 */
 
-	dm_table_postsuspend_targets(map);
-
 	set_bit(DMF_SUSPENDED, &md->flags);
 
+	dm_table_postsuspend_targets(map);
+
 out:
 	dm_table_put(map);
 
@@ -2488,10 +2581,10 @@ int dm_resume(struct mapped_device *md)
 	struct dm_table *map = NULL;
 
 	mutex_lock(&md->suspend_lock);
-	if (!dm_suspended(md))
+	if (!dm_suspended_md(md))
 		goto out;
 
-	map = dm_get_table(md);
+	map = dm_get_live_table(md);
 	if (!map || !dm_table_get_size(map))
 		goto out;
 
@@ -2592,18 +2685,29 @@ struct mapped_device *dm_get_from_kobjec
 		return NULL;
 
 	if (test_bit(DMF_FREEING, &md->flags) ||
-	    test_bit(DMF_DELETING, &md->flags))
+	    dm_deleting_md(md))
 		return NULL;
 
 	dm_get(md);
 	return md;
 }
 
-int dm_suspended(struct mapped_device *md)
+int dm_suspended_md(struct mapped_device *md)
 {
 	return test_bit(DMF_SUSPENDED, &md->flags);
 }
 
+int dm_suspended(struct dm_target *ti)
+{
+	struct mapped_device *md = dm_table_get_md(ti->table);
+	int r = dm_suspended_md(md);
+
+	dm_put(md);
+
+	return r;
+}
+EXPORT_SYMBOL_GPL(dm_suspended);
+
 int dm_noflush_suspending(struct dm_target *ti)
 {
 	struct mapped_device *md = dm_table_get_md(ti->table);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-crypt.c linux-libre-2.6.33-gnu1/drivers/md/dm-crypt.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-crypt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-crypt.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
  * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
@@ -71,10 +71,21 @@ struct crypt_iv_operations {
 	int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
 		   const char *opts);
 	void (*dtr)(struct crypt_config *cc);
-	const char *(*status)(struct crypt_config *cc);
+	int (*init)(struct crypt_config *cc);
+	int (*wipe)(struct crypt_config *cc);
 	int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
 };
 
+struct iv_essiv_private {
+	struct crypto_cipher *tfm;
+	struct crypto_hash *hash_tfm;
+	u8 *salt;
+};
+
+struct iv_benbi_private {
+	int shift;
+};
+
 /*
  * Crypt: maps a linear range of a block device
  * and encrypts / decrypts at the same time.
@@ -102,8 +113,8 @@ struct crypt_config {
 	struct crypt_iv_operations *iv_gen_ops;
 	char *iv_mode;
 	union {
-		struct crypto_cipher *essiv_tfm;
-		int benbi_shift;
+		struct iv_essiv_private essiv;
+		struct iv_benbi_private benbi;
 	} iv_gen_private;
 	sector_t iv_offset;
 	unsigned int iv_size;
@@ -147,6 +158,9 @@ static void kcryptd_queue_crypt(struct d
  * plain: the initial vector is the 32-bit little-endian version of the sector
  *        number, padded with zeros if necessary.
  *
+ * plain64: the initial vector is the 64-bit little-endian version of the sector
+ *        number, padded with zeros if necessary.
+ *
  * essiv: "encrypted sector|salt initial vector", the sector number is
  *        encrypted with the bulk cipher using a salt as key. The salt
  *        should be derived from the bulk cipher's key via hashing.
@@ -169,88 +183,123 @@ static int crypt_iv_plain_gen(struct cry
 	return 0;
 }
 
-static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
-			      const char *opts)
+static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv,
+				sector_t sector)
 {
-	struct crypto_cipher *essiv_tfm;
-	struct crypto_hash *hash_tfm;
+	memset(iv, 0, cc->iv_size);
+	*(u64 *)iv = cpu_to_le64(sector);
+
+	return 0;
+}
+
+/* Initialise ESSIV - compute salt but no local memory allocations */
+static int crypt_iv_essiv_init(struct crypt_config *cc)
+{
+	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
 	struct hash_desc desc;
 	struct scatterlist sg;
-	unsigned int saltsize;
-	u8 *salt;
 	int err;
 
-	if (opts == NULL) {
+	sg_init_one(&sg, cc->key, cc->key_size);
+	desc.tfm = essiv->hash_tfm;
+	desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+	err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt);
+	if (err)
+		return err;
+
+	return crypto_cipher_setkey(essiv->tfm, essiv->salt,
+				    crypto_hash_digestsize(essiv->hash_tfm));
+}
+
+/* Wipe salt and reset key derived from volume key */
+static int crypt_iv_essiv_wipe(struct crypt_config *cc)
+{
+	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
+	unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm);
+
+	memset(essiv->salt, 0, salt_size);
+
+	return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size);
+}
+
+static void crypt_iv_essiv_dtr(struct crypt_config *cc)
+{
+	struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
+
+	crypto_free_cipher(essiv->tfm);
+	essiv->tfm = NULL;
+
+	crypto_free_hash(essiv->hash_tfm);
+	essiv->hash_tfm = NULL;
+
+	kzfree(essiv->salt);
+	essiv->salt = NULL;
+}
+
+static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
+			      const char *opts)
+{
+	struct crypto_cipher *essiv_tfm = NULL;
+	struct crypto_hash *hash_tfm = NULL;
+	u8 *salt = NULL;
+	int err;
+
+	if (!opts) {
 		ti->error = "Digest algorithm missing for ESSIV mode";
 		return -EINVAL;
 	}
 
-	/* Hash the cipher key with the given hash algorithm */
+	/* Allocate hash algorithm */
 	hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(hash_tfm)) {
 		ti->error = "Error initializing ESSIV hash";
-		return PTR_ERR(hash_tfm);
+		err = PTR_ERR(hash_tfm);
+		goto bad;
 	}
 
-	saltsize = crypto_hash_digestsize(hash_tfm);
-	salt = kmalloc(saltsize, GFP_KERNEL);
-	if (salt == NULL) {
+	salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL);
+	if (!salt) {
 		ti->error = "Error kmallocing salt storage in ESSIV";
-		crypto_free_hash(hash_tfm);
-		return -ENOMEM;
-	}
-
-	sg_init_one(&sg, cc->key, cc->key_size);
-	desc.tfm = hash_tfm;
-	desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-	err = crypto_hash_digest(&desc, &sg, cc->key_size, salt);
-	crypto_free_hash(hash_tfm);
-
-	if (err) {
-		ti->error = "Error calculating hash in ESSIV";
-		kfree(salt);
-		return err;
+		err = -ENOMEM;
+		goto bad;
 	}
 
-	/* Setup the essiv_tfm with the given salt */
+	/* Allocate essiv_tfm */
 	essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(essiv_tfm)) {
 		ti->error = "Error allocating crypto tfm for ESSIV";
-		kfree(salt);
-		return PTR_ERR(essiv_tfm);
+		err = PTR_ERR(essiv_tfm);
+		goto bad;
 	}
 	if (crypto_cipher_blocksize(essiv_tfm) !=
 	    crypto_ablkcipher_ivsize(cc->tfm)) {
 		ti->error = "Block size of ESSIV cipher does "
 			    "not match IV size of block cipher";
-		crypto_free_cipher(essiv_tfm);
-		kfree(salt);
-		return -EINVAL;
-	}
-	err = crypto_cipher_setkey(essiv_tfm, salt, saltsize);
-	if (err) {
-		ti->error = "Failed to set key for ESSIV cipher";
-		crypto_free_cipher(essiv_tfm);
-		kfree(salt);
-		return err;
+		err = -EINVAL;
+		goto bad;
 	}
-	kfree(salt);
 
-	cc->iv_gen_private.essiv_tfm = essiv_tfm;
+	cc->iv_gen_private.essiv.salt = salt;
+	cc->iv_gen_private.essiv.tfm = essiv_tfm;
+	cc->iv_gen_private.essiv.hash_tfm = hash_tfm;
+
 	return 0;
-}
 
-static void crypt_iv_essiv_dtr(struct crypt_config *cc)
-{
-	crypto_free_cipher(cc->iv_gen_private.essiv_tfm);
-	cc->iv_gen_private.essiv_tfm = NULL;
+bad:
+	if (essiv_tfm && !IS_ERR(essiv_tfm))
+		crypto_free_cipher(essiv_tfm);
+	if (hash_tfm && !IS_ERR(hash_tfm))
+		crypto_free_hash(hash_tfm);
+	kfree(salt);
+	return err;
 }
 
 static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
 {
 	memset(iv, 0, cc->iv_size);
 	*(u64 *)iv = cpu_to_le64(sector);
-	crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv);
+	crypto_cipher_encrypt_one(cc->iv_gen_private.essiv.tfm, iv, iv);
 	return 0;
 }
 
@@ -273,7 +322,7 @@ static int crypt_iv_benbi_ctr(struct cry
 		return -EINVAL;
 	}
 
-	cc->iv_gen_private.benbi_shift = 9 - log;
+	cc->iv_gen_private.benbi.shift = 9 - log;
 
 	return 0;
 }
@@ -288,7 +337,7 @@ static int crypt_iv_benbi_gen(struct cry
 
 	memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */
 
-	val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1);
+	val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi.shift) + 1);
 	put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64)));
 
 	return 0;
@@ -305,9 +354,15 @@ static struct crypt_iv_operations crypt_
 	.generator = crypt_iv_plain_gen
 };
 
+static struct crypt_iv_operations crypt_iv_plain64_ops = {
+	.generator = crypt_iv_plain64_gen
+};
+
 static struct crypt_iv_operations crypt_iv_essiv_ops = {
 	.ctr       = crypt_iv_essiv_ctr,
 	.dtr       = crypt_iv_essiv_dtr,
+	.init      = crypt_iv_essiv_init,
+	.wipe      = crypt_iv_essiv_wipe,
 	.generator = crypt_iv_essiv_gen
 };
 
@@ -934,14 +989,14 @@ static int crypt_set_key(struct crypt_co
 
 	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
 
-	return 0;
+	return crypto_ablkcipher_setkey(cc->tfm, cc->key, cc->key_size);
 }
 
 static int crypt_wipe_key(struct crypt_config *cc)
 {
 	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
 	memset(&cc->key, 0, cc->key_size * sizeof(u8));
-	return 0;
+	return crypto_ablkcipher_setkey(cc->tfm, cc->key, cc->key_size);
 }
 
 /*
@@ -983,12 +1038,7 @@ static int crypt_ctr(struct dm_target *t
 		return -ENOMEM;
 	}
 
- 	if (crypt_set_key(cc, argv[1])) {
-		ti->error = "Error decoding key";
-		goto bad_cipher;
-	}
-
-	/* Compatiblity mode for old dm-crypt cipher strings */
+	/* Compatibility mode for old dm-crypt cipher strings */
 	if (!chainmode || (strcmp(chainmode, "plain") == 0 && !ivmode)) {
 		chainmode = "cbc";
 		ivmode = "plain";
@@ -1015,6 +1065,11 @@ static int crypt_ctr(struct dm_target *t
 	strcpy(cc->chainmode, chainmode);
 	cc->tfm = tfm;
 
+	if (crypt_set_key(cc, argv[1]) < 0) {
+		ti->error = "Error decoding and setting key";
+		goto bad_ivmode;
+	}
+
 	/*
 	 * Choose ivmode. Valid modes: "plain", "essiv:<esshash>", "benbi".
 	 * See comments at iv code
@@ -1024,6 +1079,8 @@ static int crypt_ctr(struct dm_target *t
 		cc->iv_gen_ops = NULL;
 	else if (strcmp(ivmode, "plain") == 0)
 		cc->iv_gen_ops = &crypt_iv_plain_ops;
+	else if (strcmp(ivmode, "plain64") == 0)
+		cc->iv_gen_ops = &crypt_iv_plain64_ops;
 	else if (strcmp(ivmode, "essiv") == 0)
 		cc->iv_gen_ops = &crypt_iv_essiv_ops;
 	else if (strcmp(ivmode, "benbi") == 0)
@@ -1039,6 +1096,12 @@ static int crypt_ctr(struct dm_target *t
 	    cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
 		goto bad_ivmode;
 
+	if (cc->iv_gen_ops && cc->iv_gen_ops->init &&
+	    cc->iv_gen_ops->init(cc) < 0) {
+		ti->error = "Error initialising IV";
+		goto bad_slab_pool;
+	}
+
 	cc->iv_size = crypto_ablkcipher_ivsize(tfm);
 	if (cc->iv_size)
 		/* at least a 64 bit sector number should fit in our buffer */
@@ -1085,11 +1148,6 @@ static int crypt_ctr(struct dm_target *t
 		goto bad_bs;
 	}
 
-	if (crypto_ablkcipher_setkey(tfm, cc->key, key_size) < 0) {
-		ti->error = "Error setting key";
-		goto bad_device;
-	}
-
 	if (sscanf(argv[2], "%llu", &tmpll) != 1) {
 		ti->error = "Invalid iv_offset sector";
 		goto bad_device;
@@ -1278,6 +1336,7 @@ static void crypt_resume(struct dm_targe
 static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
 {
 	struct crypt_config *cc = ti->private;
+	int ret = -EINVAL;
 
 	if (argc < 2)
 		goto error;
@@ -1287,10 +1346,22 @@ static int crypt_message(struct dm_targe
 			DMWARN("not suspended during key manipulation.");
 			return -EINVAL;
 		}
-		if (argc == 3 && !strnicmp(argv[1], MESG_STR("set")))
-			return crypt_set_key(cc, argv[2]);
-		if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe")))
+		if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) {
+			ret = crypt_set_key(cc, argv[2]);
+			if (ret)
+				return ret;
+			if (cc->iv_gen_ops && cc->iv_gen_ops->init)
+				ret = cc->iv_gen_ops->init(cc);
+			return ret;
+		}
+		if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) {
+			if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
+				ret = cc->iv_gen_ops->wipe(cc);
+				if (ret)
+					return ret;
+			}
 			return crypt_wipe_key(cc);
+		}
 	}
 
 error:
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-exception-store.c linux-libre-2.6.33-gnu1/drivers/md/dm-exception-store.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-exception-store.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-exception-store.c	2010-02-24 13:52:17.000000000 -0500
@@ -172,7 +172,8 @@ int dm_exception_store_set_chunk_size(st
 	}
 
 	/* Validate the chunk size against the device block size */
-	if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
+	if (chunk_size %
+	    (bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9)) {
 		*error = "Chunk size is not a multiple of device blocksize";
 		return -EINVAL;
 	}
@@ -190,6 +191,7 @@ int dm_exception_store_set_chunk_size(st
 }
 
 int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      struct dm_snapshot *snap,
 			      unsigned *args_used,
 			      struct dm_exception_store **store)
 {
@@ -198,7 +200,7 @@ int dm_exception_store_create(struct dm_
 	struct dm_exception_store *tmp_store;
 	char persistent;
 
-	if (argc < 3) {
+	if (argc < 2) {
 		ti->error = "Insufficient exception store arguments";
 		return -EINVAL;
 	}
@@ -209,14 +211,15 @@ int dm_exception_store_create(struct dm_
 		return -ENOMEM;
 	}
 
-	persistent = toupper(*argv[1]);
+	persistent = toupper(*argv[0]);
 	if (persistent == 'P')
 		type = get_type("P");
 	else if (persistent == 'N')
 		type = get_type("N");
 	else {
 		ti->error = "Persistent flag is not P or N";
-		return -EINVAL;
+		r = -EINVAL;
+		goto bad_type;
 	}
 
 	if (!type) {
@@ -226,32 +229,23 @@ int dm_exception_store_create(struct dm_
 	}
 
 	tmp_store->type = type;
-	tmp_store->ti = ti;
-
-	r = dm_get_device(ti, argv[0], 0, 0,
-			  FMODE_READ | FMODE_WRITE, &tmp_store->cow);
-	if (r) {
-		ti->error = "Cannot get COW device";
-		goto bad_cow;
-	}
+	tmp_store->snap = snap;
 
-	r = set_chunk_size(tmp_store, argv[2], &ti->error);
+	r = set_chunk_size(tmp_store, argv[1], &ti->error);
 	if (r)
-		goto bad_ctr;
+		goto bad;
 
 	r = type->ctr(tmp_store, 0, NULL);
 	if (r) {
 		ti->error = "Exception store type constructor failed";
-		goto bad_ctr;
+		goto bad;
 	}
 
-	*args_used = 3;
+	*args_used = 2;
 	*store = tmp_store;
 	return 0;
 
-bad_ctr:
-	dm_put_device(ti, tmp_store->cow);
-bad_cow:
+bad:
 	put_type(type);
 bad_type:
 	kfree(tmp_store);
@@ -262,7 +256,6 @@ EXPORT_SYMBOL(dm_exception_store_create)
 void dm_exception_store_destroy(struct dm_exception_store *store)
 {
 	store->type->dtr(store);
-	dm_put_device(store->ti, store->cow);
 	put_type(store->type);
 	kfree(store);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-exception-store.h linux-libre-2.6.33-gnu1/drivers/md/dm-exception-store.h
--- linux-libre-2.6.32-gnu1/drivers/md/dm-exception-store.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-exception-store.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,7 @@ typedef sector_t chunk_t;
  * of chunks that follow contiguously.  Remaining bits hold the number of the
  * chunk within the device.
  */
-struct dm_snap_exception {
+struct dm_exception {
 	struct list_head hash_list;
 
 	chunk_t old_chunk;
@@ -64,17 +64,34 @@ struct dm_exception_store_type {
 	 * Find somewhere to store the next exception.
 	 */
 	int (*prepare_exception) (struct dm_exception_store *store,
-				  struct dm_snap_exception *e);
+				  struct dm_exception *e);
 
 	/*
 	 * Update the metadata with this exception.
 	 */
 	void (*commit_exception) (struct dm_exception_store *store,
-				  struct dm_snap_exception *e,
+				  struct dm_exception *e,
 				  void (*callback) (void *, int success),
 				  void *callback_context);
 
 	/*
+	 * Returns 0 if the exception store is empty.
+	 *
+	 * If there are exceptions still to be merged, sets
+	 * *last_old_chunk and *last_new_chunk to the most recent
+	 * still-to-be-merged chunk and returns the number of
+	 * consecutive previous ones.
+	 */
+	int (*prepare_merge) (struct dm_exception_store *store,
+			      chunk_t *last_old_chunk, chunk_t *last_new_chunk);
+
+	/*
+	 * Clear the last n exceptions.
+	 * nr_merged must be <= the value returned by prepare_merge.
+	 */
+	int (*commit_merge) (struct dm_exception_store *store, int nr_merged);
+
+	/*
 	 * The snapshot is invalid, note this in the metadata.
 	 */
 	void (*drop_snapshot) (struct dm_exception_store *store);
@@ -86,19 +103,19 @@ struct dm_exception_store_type {
 	/*
 	 * Return how full the snapshot is.
 	 */
-	void (*fraction_full) (struct dm_exception_store *store,
-			       sector_t *numerator,
-			       sector_t *denominator);
+	void (*usage) (struct dm_exception_store *store,
+		       sector_t *total_sectors, sector_t *sectors_allocated,
+		       sector_t *metadata_sectors);
 
 	/* For internal device-mapper use only. */
 	struct list_head list;
 };
 
+struct dm_snapshot;
+
 struct dm_exception_store {
 	struct dm_exception_store_type *type;
-	struct dm_target *ti;
-
-	struct dm_dev *cow;
+	struct dm_snapshot *snap;
 
 	/* Size of data blocks saved - must be a power of 2 */
 	unsigned chunk_size;
@@ -109,6 +126,11 @@ struct dm_exception_store {
 };
 
 /*
+ * Obtain the cow device used by a given snapshot.
+ */
+struct dm_dev *dm_snap_cow(struct dm_snapshot *snap);
+
+/*
  * Funtions to manipulate consecutive chunks
  */
 #  if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64)
@@ -120,18 +142,25 @@ static inline chunk_t dm_chunk_number(ch
 	return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL);
 }
 
-static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e)
+static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
 {
 	return e->new_chunk >> DM_CHUNK_NUMBER_BITS;
 }
 
-static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
+static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
 {
 	e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS);
 
 	BUG_ON(!dm_consecutive_chunk_count(e));
 }
 
+static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
+{
+	BUG_ON(!dm_consecutive_chunk_count(e));
+
+	e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS);
+}
+
 #  else
 #    define DM_CHUNK_CONSECUTIVE_BITS 0
 
@@ -140,12 +169,16 @@ static inline chunk_t dm_chunk_number(ch
 	return chunk;
 }
 
-static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e)
+static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
 {
 	return 0;
 }
 
-static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
+static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
+{
+}
+
+static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
 {
 }
 
@@ -162,7 +195,7 @@ static inline sector_t get_dev_size(stru
 static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
 				      sector_t sector)
 {
-	return (sector & ~store->chunk_mask) >> store->chunk_shift;
+	return sector >> store->chunk_shift;
 }
 
 int dm_exception_store_type_register(struct dm_exception_store_type *type);
@@ -173,6 +206,7 @@ int dm_exception_store_set_chunk_size(st
 				      char **error);
 
 int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      struct dm_snapshot *snap,
 			      unsigned *args_used,
 			      struct dm_exception_store **store);
 void dm_exception_store_destroy(struct dm_exception_store *store);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm.h linux-libre-2.6.33-gnu1/drivers/md/dm.h
--- linux-libre-2.6.32-gnu1/drivers/md/dm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm.h	2010-02-24 13:52:17.000000000 -0500
@@ -89,6 +89,16 @@ int dm_target_iterate(void (*iter_func)(
 int dm_split_args(int *argc, char ***argvp, char *input);
 
 /*
+ * Is this mapped_device being deleted?
+ */
+int dm_deleting_md(struct mapped_device *md);
+
+/*
+ * Is this mapped_device suspended?
+ */
+int dm_suspended_md(struct mapped_device *md);
+
+/*
  * The device-mapper can be driven through one of two interfaces;
  * ioctl or filesystem, depending which patch you have applied.
  */
@@ -118,6 +128,9 @@ int dm_lock_for_deletion(struct mapped_d
 void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
 		       unsigned cookie);
 
+int dm_io_init(void);
+void dm_io_exit(void);
+
 int dm_kcopyd_init(void);
 void dm_kcopyd_exit(void);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-io.c linux-libre-2.6.33-gnu1/drivers/md/dm-io.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-io.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,8 @@
  * This file is released under the GPL.
  */
 
+#include "dm.h"
+
 #include <linux/device-mapper.h>
 
 #include <linux/bio.h>
@@ -14,12 +16,19 @@
 #include <linux/slab.h>
 #include <linux/dm-io.h>
 
+#define DM_MSG_PREFIX "io"
+
+#define DM_IO_MAX_REGIONS	BITS_PER_LONG
+
 struct dm_io_client {
 	mempool_t *pool;
 	struct bio_set *bios;
 };
 
-/* FIXME: can we shrink this ? */
+/*
+ * Aligning 'struct io' reduces the number of bits required to store
+ * its address.  Refer to store_io_and_region_in_bio() below.
+ */
 struct io {
 	unsigned long error_bits;
 	unsigned long eopnotsupp_bits;
@@ -28,7 +37,9 @@ struct io {
 	struct dm_io_client *client;
 	io_notify_fn callback;
 	void *context;
-};
+} __attribute__((aligned(DM_IO_MAX_REGIONS)));
+
+static struct kmem_cache *_dm_io_cache;
 
 /*
  * io contexts are only dynamically allocated for asynchronous
@@ -53,7 +64,7 @@ struct dm_io_client *dm_io_client_create
 	if (!client)
 		return ERR_PTR(-ENOMEM);
 
-	client->pool = mempool_create_kmalloc_pool(ios, sizeof(struct io));
+	client->pool = mempool_create_slab_pool(ios, _dm_io_cache);
 	if (!client->pool)
 		goto bad;
 
@@ -88,18 +99,29 @@ EXPORT_SYMBOL(dm_io_client_destroy);
 
 /*-----------------------------------------------------------------
  * We need to keep track of which region a bio is doing io for.
- * In order to save a memory allocation we store this the last
- * bvec which we know is unused (blech).
- * XXX This is ugly and can OOPS with some configs... find another way.
+ * To avoid a memory allocation to store just 5 or 6 bits, we
+ * ensure the 'struct io' pointer is aligned so enough low bits are
+ * always zero and then combine it with the region number directly in
+ * bi_private.
  *---------------------------------------------------------------*/
-static inline void bio_set_region(struct bio *bio, unsigned region)
+static void store_io_and_region_in_bio(struct bio *bio, struct io *io,
+				       unsigned region)
 {
-	bio->bi_io_vec[bio->bi_max_vecs].bv_len = region;
+	if (unlikely(!IS_ALIGNED((unsigned long)io, DM_IO_MAX_REGIONS))) {
+		DMCRIT("Unaligned struct io pointer %p", io);
+		BUG();
+	}
+
+	bio->bi_private = (void *)((unsigned long)io | region);
 }
 
-static inline unsigned bio_get_region(struct bio *bio)
+static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io,
+				       unsigned *region)
 {
-	return bio->bi_io_vec[bio->bi_max_vecs].bv_len;
+	unsigned long val = (unsigned long)bio->bi_private;
+
+	*io = (void *)(val & -(unsigned long)DM_IO_MAX_REGIONS);
+	*region = val & (DM_IO_MAX_REGIONS - 1);
 }
 
 /*-----------------------------------------------------------------
@@ -140,10 +162,8 @@ static void endio(struct bio *bio, int e
 	/*
 	 * The bio destructor in bio_put() may use the io object.
 	 */
-	io = bio->bi_private;
-	region = bio_get_region(bio);
+	retrieve_io_and_region_from_bio(bio, &io, &region);
 
-	bio->bi_max_vecs++;
 	bio_put(bio);
 
 	dec_count(io, region, error);
@@ -243,7 +263,10 @@ static void vm_dp_init(struct dpages *dp
 
 static void dm_bio_destructor(struct bio *bio)
 {
-	struct io *io = bio->bi_private;
+	unsigned region;
+	struct io *io;
+
+	retrieve_io_and_region_from_bio(bio, &io, &region);
 
 	bio_free(bio, io->client->bios);
 }
@@ -286,26 +309,23 @@ static void do_region(int rw, unsigned r
 	unsigned num_bvecs;
 	sector_t remaining = where->count;
 
-	while (remaining) {
+	/*
+	 * where->count may be zero if rw holds a write barrier and we
+	 * need to send a zero-sized barrier.
+	 */
+	do {
 		/*
-		 * Allocate a suitably sized-bio: we add an extra
-		 * bvec for bio_get/set_region() and decrement bi_max_vecs
-		 * to hide it from bio_add_page().
+		 * Allocate a suitably sized-bio.
 		 */
 		num_bvecs = dm_sector_div_up(remaining,
 					     (PAGE_SIZE >> SECTOR_SHIFT));
-		num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
-				      num_bvecs);
-		if (unlikely(num_bvecs > BIO_MAX_PAGES))
-			num_bvecs = BIO_MAX_PAGES;
+		num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs);
 		bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
 		bio->bi_sector = where->sector + (where->count - remaining);
 		bio->bi_bdev = where->bdev;
 		bio->bi_end_io = endio;
-		bio->bi_private = io;
 		bio->bi_destructor = dm_bio_destructor;
-		bio->bi_max_vecs--;
-		bio_set_region(bio, region);
+		store_io_and_region_in_bio(bio, io, region);
 
 		/*
 		 * Try and add as many pages as possible.
@@ -323,7 +343,7 @@ static void do_region(int rw, unsigned r
 
 		atomic_inc(&io->count);
 		submit_bio(rw, bio);
-	}
+	} while (remaining);
 }
 
 static void dispatch_io(int rw, unsigned int num_regions,
@@ -333,6 +353,8 @@ static void dispatch_io(int rw, unsigned
 	int i;
 	struct dpages old_pages = *dp;
 
+	BUG_ON(num_regions > DM_IO_MAX_REGIONS);
+
 	if (sync)
 		rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
 
@@ -342,7 +364,7 @@ static void dispatch_io(int rw, unsigned
 	 */
 	for (i = 0; i < num_regions; i++) {
 		*dp = old_pages;
-		if (where[i].count)
+		if (where[i].count || (rw & (1 << BIO_RW_BARRIER)))
 			do_region(rw, i, where + i, dp, io);
 	}
 
@@ -357,7 +379,14 @@ static int sync_io(struct dm_io_client *
 		   struct dm_io_region *where, int rw, struct dpages *dp,
 		   unsigned long *error_bits)
 {
-	struct io io;
+	/*
+	 * gcc <= 4.3 can't do the alignment for stack variables, so we must
+	 * align it on our own.
+	 * volatile prevents the optimizer from removing or reusing
+	 * "io_" field from the stack frame (allowed in ANSI C).
+	 */
+	volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1];
+	struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io));
 
 	if (num_regions > 1 && (rw & RW_MASK) != WRITE) {
 		WARN_ON(1);
@@ -365,33 +394,33 @@ static int sync_io(struct dm_io_client *
 	}
 
 retry:
-	io.error_bits = 0;
-	io.eopnotsupp_bits = 0;
-	atomic_set(&io.count, 1); /* see dispatch_io() */
-	io.sleeper = current;
-	io.client = client;
+	io->error_bits = 0;
+	io->eopnotsupp_bits = 0;
+	atomic_set(&io->count, 1); /* see dispatch_io() */
+	io->sleeper = current;
+	io->client = client;
 
-	dispatch_io(rw, num_regions, where, dp, &io, 1);
+	dispatch_io(rw, num_regions, where, dp, io, 1);
 
 	while (1) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 
-		if (!atomic_read(&io.count))
+		if (!atomic_read(&io->count))
 			break;
 
 		io_schedule();
 	}
 	set_current_state(TASK_RUNNING);
 
-	if (io.eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) {
+	if (io->eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) {
 		rw &= ~(1 << BIO_RW_BARRIER);
 		goto retry;
 	}
 
 	if (error_bits)
-		*error_bits = io.error_bits;
+		*error_bits = io->error_bits;
 
-	return io.error_bits ? -EIO : 0;
+	return io->error_bits ? -EIO : 0;
 }
 
 static int async_io(struct dm_io_client *client, unsigned int num_regions,
@@ -472,3 +501,18 @@ int dm_io(struct dm_io_request *io_req,
 			&dp, io_req->notify.fn, io_req->notify.context);
 }
 EXPORT_SYMBOL(dm_io);
+
+int __init dm_io_init(void)
+{
+	_dm_io_cache = KMEM_CACHE(io, 0);
+	if (!_dm_io_cache)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void dm_io_exit(void)
+{
+	kmem_cache_destroy(_dm_io_cache);
+	_dm_io_cache = NULL;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-ioctl.c linux-libre-2.6.33-gnu1/drivers/md/dm-ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,11 @@ static void dm_hash_remove_all(int keep_
  */
 static DECLARE_RWSEM(_hash_lock);
 
+/*
+ * Protects use of mdptr to obtain hash cell name and uuid from mapped device.
+ */
+static DEFINE_MUTEX(dm_hash_cells_mutex);
+
 static void init_buckets(struct list_head *buckets)
 {
 	unsigned int i;
@@ -206,7 +211,9 @@ static int dm_hash_insert(const char *na
 		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
 	}
 	dm_get(md);
+	mutex_lock(&dm_hash_cells_mutex);
 	dm_set_mdptr(md, cell);
+	mutex_unlock(&dm_hash_cells_mutex);
 	up_write(&_hash_lock);
 
 	return 0;
@@ -224,9 +231,11 @@ static void __hash_remove(struct hash_ce
 	/* remove from the dev hash */
 	list_del(&hc->uuid_list);
 	list_del(&hc->name_list);
+	mutex_lock(&dm_hash_cells_mutex);
 	dm_set_mdptr(hc->md, NULL);
+	mutex_unlock(&dm_hash_cells_mutex);
 
-	table = dm_get_table(hc->md);
+	table = dm_get_live_table(hc->md);
 	if (table) {
 		dm_table_event(table);
 		dm_table_put(table);
@@ -321,13 +330,15 @@ static int dm_hash_rename(uint32_t cooki
 	 */
 	list_del(&hc->name_list);
 	old_name = hc->name;
+	mutex_lock(&dm_hash_cells_mutex);
 	hc->name = new_name;
+	mutex_unlock(&dm_hash_cells_mutex);
 	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
 
 	/*
 	 * Wake up any dm event waiters.
 	 */
-	table = dm_get_table(hc->md);
+	table = dm_get_live_table(hc->md);
 	if (table) {
 		dm_table_event(table);
 		dm_table_put(table);
@@ -512,8 +523,6 @@ static int list_versions(struct dm_ioctl
 	return 0;
 }
 
-
-
 static int check_name(const char *name)
 {
 	if (strchr(name, '/')) {
@@ -525,6 +534,40 @@ static int check_name(const char *name)
 }
 
 /*
+ * On successful return, the caller must not attempt to acquire
+ * _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)
+{
+	struct hash_cell *hc;
+	struct dm_table *table = NULL;
+
+	down_read(&_hash_lock);
+	hc = dm_get_mdptr(md);
+	if (!hc || hc->md != md) {
+		DMWARN("device has been removed from the dev hash table.");
+		goto out;
+	}
+
+	table = hc->new_map;
+	if (table)
+		dm_table_get(table);
+
+out:
+	up_read(&_hash_lock);
+
+	return table;
+}
+
+static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
+						      struct dm_ioctl *param)
+{
+	return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ?
+		dm_get_inactive_table(md) : dm_get_live_table(md);
+}
+
+/*
  * Fills in a dm_ioctl structure, ready for sending back to
  * userland.
  */
@@ -536,7 +579,7 @@ static int __dev_status(struct mapped_de
 	param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG |
 			  DM_ACTIVE_PRESENT_FLAG);
 
-	if (dm_suspended(md))
+	if (dm_suspended_md(md))
 		param->flags |= DM_SUSPEND_FLAG;
 
 	param->dev = huge_encode_dev(disk_devt(disk));
@@ -548,18 +591,30 @@ static int __dev_status(struct mapped_de
 	 */
 	param->open_count = dm_open_count(md);
 
-	if (get_disk_ro(disk))
-		param->flags |= DM_READONLY_FLAG;
-
 	param->event_nr = dm_get_event_nr(md);
+	param->target_count = 0;
 
-	table = dm_get_table(md);
+	table = dm_get_live_table(md);
 	if (table) {
-		param->flags |= DM_ACTIVE_PRESENT_FLAG;
-		param->target_count = dm_table_get_num_targets(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);
-	} else
-		param->target_count = 0;
+
+		param->flags |= DM_ACTIVE_PRESENT_FLAG;
+	}
+
+	if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) {
+		table = dm_get_inactive_table(md);
+		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);
+		}
+	}
 
 	return 0;
 }
@@ -634,9 +689,9 @@ static struct mapped_device *find_device
 		 * Sneakily write in both the name and the uuid
 		 * while we have the cell.
 		 */
-		strncpy(param->name, hc->name, sizeof(param->name));
+		strlcpy(param->name, hc->name, sizeof(param->name));
 		if (hc->uuid)
-			strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1);
+			strlcpy(param->uuid, hc->uuid, sizeof(param->uuid));
 		else
 			param->uuid[0] = '\0';
 
@@ -784,7 +839,7 @@ static int do_suspend(struct dm_ioctl *p
 	if (param->flags & DM_NOFLUSH_FLAG)
 		suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
 
-	if (!dm_suspended(md))
+	if (!dm_suspended_md(md))
 		r = dm_suspend(md, suspend_flags);
 
 	if (!r)
@@ -800,7 +855,7 @@ static int do_resume(struct dm_ioctl *pa
 	unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG;
 	struct hash_cell *hc;
 	struct mapped_device *md;
-	struct dm_table *new_map;
+	struct dm_table *new_map, *old_map = NULL;
 
 	down_write(&_hash_lock);
 
@@ -826,14 +881,14 @@ static int do_resume(struct dm_ioctl *pa
 			suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
 		if (param->flags & DM_NOFLUSH_FLAG)
 			suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
-		if (!dm_suspended(md))
+		if (!dm_suspended_md(md))
 			dm_suspend(md, suspend_flags);
 
-		r = dm_swap_table(md, new_map);
-		if (r) {
+		old_map = dm_swap_table(md, new_map);
+		if (IS_ERR(old_map)) {
 			dm_table_destroy(new_map);
 			dm_put(md);
-			return r;
+			return PTR_ERR(old_map);
 		}
 
 		if (dm_table_get_mode(new_map) & FMODE_WRITE)
@@ -842,9 +897,11 @@ static int do_resume(struct dm_ioctl *pa
 			set_disk_ro(dm_disk(md), 1);
 	}
 
-	if (dm_suspended(md))
+	if (dm_suspended_md(md))
 		r = dm_resume(md);
 
+	if (old_map)
+		dm_table_destroy(old_map);
 
 	if (!r) {
 		dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
@@ -982,7 +1039,7 @@ static int dev_wait(struct dm_ioctl *par
 	if (r)
 		goto out;
 
-	table = dm_get_table(md);
+	table = dm_get_live_or_inactive_table(md, param);
 	if (table) {
 		retrieve_status(table, param, param_size);
 		dm_table_put(table);
@@ -1215,7 +1272,7 @@ static int table_deps(struct dm_ioctl *p
 	if (r)
 		goto out;
 
-	table = dm_get_table(md);
+	table = dm_get_live_or_inactive_table(md, param);
 	if (table) {
 		retrieve_deps(table, param, param_size);
 		dm_table_put(table);
@@ -1244,13 +1301,13 @@ static int table_status(struct dm_ioctl
 	if (r)
 		goto out;
 
-	table = dm_get_table(md);
+	table = dm_get_live_or_inactive_table(md, param);
 	if (table) {
 		retrieve_status(table, param, param_size);
 		dm_table_put(table);
 	}
 
- out:
+out:
 	dm_put(md);
 	return r;
 }
@@ -1288,10 +1345,15 @@ static int target_message(struct dm_ioct
 		goto out;
 	}
 
-	table = dm_get_table(md);
+	table = dm_get_live_table(md);
 	if (!table)
 		goto out_argv;
 
+	if (dm_deleting_md(md)) {
+		r = -ENXIO;
+		goto out_table;
+	}
+
 	ti = dm_table_find_target(table, tmsg->sector);
 	if (!dm_target_is_valid(ti)) {
 		DMWARN("Target message sector outside device.");
@@ -1303,6 +1365,7 @@ static int target_message(struct dm_ioct
 		r = -EINVAL;
 	}
 
+ out_table:
 	dm_table_put(table);
  out_argv:
 	kfree(argv);
@@ -1582,8 +1645,7 @@ int dm_copy_name_and_uuid(struct mapped_
 	if (!md)
 		return -ENXIO;
 
-	dm_get(md);
-	down_read(&_hash_lock);
+	mutex_lock(&dm_hash_cells_mutex);
 	hc = dm_get_mdptr(md);
 	if (!hc || hc->md != md) {
 		r = -ENXIO;
@@ -1596,8 +1658,7 @@ int dm_copy_name_and_uuid(struct mapped_
 		strcpy(uuid, hc->uuid ? : "");
 
 out:
-	up_read(&_hash_lock);
-	dm_put(md);
+	mutex_unlock(&dm_hash_cells_mutex);
 
 	return r;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-kcopyd.c linux-libre-2.6.33-gnu1/drivers/md/dm-kcopyd.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-kcopyd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-kcopyd.c	2010-02-24 13:52:17.000000000 -0500
@@ -450,7 +450,10 @@ static void dispatch_job(struct kcopyd_j
 {
 	struct dm_kcopyd_client *kc = job->kc;
 	atomic_inc(&kc->nr_jobs);
-	push(&kc->pages_jobs, job);
+	if (unlikely(!job->source.count))
+		push(&kc->complete_jobs, job);
+	else
+		push(&kc->pages_jobs, job);
 	wake(kc);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-log.c linux-libre-2.6.33-gnu1/drivers/md/dm-log.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-log.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-log.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,8 +145,9 @@ int dm_dirty_log_type_unregister(struct
 EXPORT_SYMBOL(dm_dirty_log_type_unregister);
 
 struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
-					 struct dm_target *ti,
-					 unsigned int argc, char **argv)
+			struct dm_target *ti,
+			int (*flush_callback_fn)(struct dm_target *ti),
+			unsigned int argc, char **argv)
 {
 	struct dm_dirty_log_type *type;
 	struct dm_dirty_log *log;
@@ -161,6 +162,7 @@ struct dm_dirty_log *dm_dirty_log_create
 		return NULL;
 	}
 
+	log->flush_callback_fn = flush_callback_fn;
 	log->type = type;
 	if (type->ctr(log, ti, argc, argv)) {
 		kfree(log);
@@ -208,7 +210,9 @@ struct log_header {
 
 struct log_c {
 	struct dm_target *ti;
-	int touched;
+	int touched_dirtied;
+	int touched_cleaned;
+	int flush_failed;
 	uint32_t region_size;
 	unsigned int region_count;
 	region_t sync_count;
@@ -233,6 +237,7 @@ struct log_c {
 	 * Disk log fields
 	 */
 	int log_dev_failed;
+	int log_dev_flush_failed;
 	struct dm_dev *log_dev;
 	struct log_header header;
 
@@ -253,14 +258,14 @@ static inline void log_set_bit(struct lo
 			       uint32_t *bs, unsigned bit)
 {
 	ext2_set_bit(bit, (unsigned long *) bs);
-	l->touched = 1;
+	l->touched_cleaned = 1;
 }
 
 static inline void log_clear_bit(struct log_c *l,
 				 uint32_t *bs, unsigned bit)
 {
 	ext2_clear_bit(bit, (unsigned long *) bs);
-	l->touched = 1;
+	l->touched_dirtied = 1;
 }
 
 /*----------------------------------------------------------------
@@ -287,6 +292,19 @@ static int rw_header(struct log_c *lc, i
 	return dm_io(&lc->io_req, 1, &lc->header_location, NULL);
 }
 
+static int flush_header(struct log_c *lc)
+{
+	struct dm_io_region null_location = {
+		.bdev = lc->header_location.bdev,
+		.sector = 0,
+		.count = 0,
+	};
+
+	lc->io_req.bi_rw = WRITE_BARRIER;
+
+	return dm_io(&lc->io_req, 1, &null_location, NULL);
+}
+
 static int read_header(struct log_c *log)
 {
 	int r;
@@ -378,7 +396,9 @@ static int create_log_context(struct dm_
 	}
 
 	lc->ti = ti;
-	lc->touched = 0;
+	lc->touched_dirtied = 0;
+	lc->touched_cleaned = 0;
+	lc->flush_failed = 0;
 	lc->region_size = region_size;
 	lc->region_count = region_count;
 	lc->sync = sync;
@@ -406,6 +426,7 @@ static int create_log_context(struct dm_
 	} else {
 		lc->log_dev = dev;
 		lc->log_dev_failed = 0;
+		lc->log_dev_flush_failed = 0;
 		lc->header_location.bdev = lc->log_dev->bdev;
 		lc->header_location.sector = 0;
 
@@ -614,6 +635,11 @@ static int disk_resume(struct dm_dirty_l
 
 	/* write the new header */
 	r = rw_header(lc, WRITE);
+	if (!r) {
+		r = flush_header(lc);
+		if (r)
+			lc->log_dev_flush_failed = 1;
+	}
 	if (r) {
 		DMWARN("%s: Failed to write header on dirty region log device",
 		       lc->log_dev->name);
@@ -656,18 +682,40 @@ static int core_flush(struct dm_dirty_lo
 
 static int disk_flush(struct dm_dirty_log *log)
 {
-	int r;
-	struct log_c *lc = (struct log_c *) log->context;
+	int r, i;
+	struct log_c *lc = log->context;
 
 	/* only write if the log has changed */
-	if (!lc->touched)
+	if (!lc->touched_cleaned && !lc->touched_dirtied)
 		return 0;
 
+	if (lc->touched_cleaned && log->flush_callback_fn &&
+	    log->flush_callback_fn(lc->ti)) {
+		/*
+		 * At this point it is impossible to determine which
+		 * regions are clean and which are dirty (without
+		 * re-reading the log off disk). So mark all of them
+		 * dirty.
+		 */
+		lc->flush_failed = 1;
+		for (i = 0; i < lc->region_count; i++)
+			log_clear_bit(lc, lc->clean_bits, i);
+	}
+
 	r = rw_header(lc, WRITE);
 	if (r)
 		fail_log_device(lc);
-	else
-		lc->touched = 0;
+	else {
+		if (lc->touched_dirtied) {
+			r = flush_header(lc);
+			if (r) {
+				lc->log_dev_flush_failed = 1;
+				fail_log_device(lc);
+			} else
+				lc->touched_dirtied = 0;
+		}
+		lc->touched_cleaned = 0;
+	}
 
 	return r;
 }
@@ -681,7 +729,8 @@ static void core_mark_region(struct dm_d
 static void core_clear_region(struct dm_dirty_log *log, region_t region)
 {
 	struct log_c *lc = (struct log_c *) log->context;
-	log_set_bit(lc, lc->clean_bits, region);
+	if (likely(!lc->flush_failed))
+		log_set_bit(lc, lc->clean_bits, region);
 }
 
 static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
@@ -762,7 +811,9 @@ static int disk_status(struct dm_dirty_l
 	switch(status) {
 	case STATUSTYPE_INFO:
 		DMEMIT("3 %s %s %c", log->type->name, lc->log_dev->name,
-		       lc->log_dev_failed ? 'D' : 'A');
+		       lc->log_dev_flush_failed ? 'F' :
+		       lc->log_dev_failed ? 'D' :
+		       'A');
 		break;
 
 	case STATUSTYPE_TABLE:
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-log-userspace-transfer.c linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-transfer.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-log-userspace-transfer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-log-userspace-transfer.c	2010-02-24 13:52:17.000000000 -0500
@@ -172,11 +172,15 @@ int dm_consult_userspace(const char *uui
 {
 	int r = 0;
 	size_t dummy = 0;
-	int overhead_size =
-		sizeof(struct dm_ulog_request *) + sizeof(struct cn_msg);
+	int overhead_size = sizeof(struct dm_ulog_request) + sizeof(struct cn_msg);
 	struct dm_ulog_request *tfr = prealloced_ulog_tfr;
 	struct receiving_pkg pkg;
 
+	/*
+	 * Given the space needed to hold the 'struct cn_msg' and
+	 * 'struct dm_ulog_request' - do we have enough payload
+	 * space remaining?
+	 */
 	if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) {
 		DMINFO("Size of tfr exceeds preallocated size");
 		return -EINVAL;
@@ -191,7 +195,7 @@ resend:
 	 */
 	mutex_lock(&dm_ulog_lock);
 
-	memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size);
+	memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - sizeof(struct cn_msg));
 	memcpy(tfr->uuid, uuid, DM_UUID_LEN);
 	tfr->luid = luid;
 	tfr->seq = dm_ulog_seq++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-mpath.c linux-libre-2.6.33-gnu1/drivers/md/dm-mpath.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-mpath.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-mpath.c	2010-02-24 13:52:17.000000000 -0500
@@ -93,6 +93,10 @@ struct multipath {
 	 * can resubmit bios on error.
 	 */
 	mempool_t *mpio_pool;
+
+	struct mutex work_mutex;
+
+	unsigned suspended;	/* Don't create new I/O internally when set. */
 };
 
 /*
@@ -198,6 +202,7 @@ static struct multipath *alloc_multipath
 		m->queue_io = 1;
 		INIT_WORK(&m->process_queued_ios, process_queued_ios);
 		INIT_WORK(&m->trigger_event, trigger_event);
+		mutex_init(&m->work_mutex);
 		m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
 		if (!m->mpio_pool) {
 			kfree(m);
@@ -885,13 +890,18 @@ static int multipath_ctr(struct dm_targe
 	return r;
 }
 
-static void multipath_dtr(struct dm_target *ti)
+static void flush_multipath_work(void)
 {
-	struct multipath *m = (struct multipath *) ti->private;
-
 	flush_workqueue(kmpath_handlerd);
 	flush_workqueue(kmultipathd);
 	flush_scheduled_work();
+}
+
+static void multipath_dtr(struct dm_target *ti)
+{
+	struct multipath *m = ti->private;
+
+	flush_multipath_work();
 	free_multipath(m);
 }
 
@@ -1116,8 +1126,9 @@ static int pg_init_limit_reached(struct
 	return limit_reached;
 }
 
-static void pg_init_done(struct dm_path *path, int errors)
+static void pg_init_done(void *data, int errors)
 {
+	struct dm_path *path = data;
 	struct pgpath *pgpath = path_to_pgpath(path);
 	struct priority_group *pg = pgpath->pg;
 	struct multipath *m = pg->m;
@@ -1183,12 +1194,11 @@ static void pg_init_done(struct dm_path
 
 static void activate_path(struct work_struct *work)
 {
-	int ret;
 	struct pgpath *pgpath =
 		container_of(work, struct pgpath, activate_path);
 
-	ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev));
-	pg_init_done(&pgpath->path, ret);
+	scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
+				pg_init_done, &pgpath->path);
 }
 
 /*
@@ -1261,6 +1271,16 @@ static void multipath_presuspend(struct
 	queue_if_no_path(m, 0, 1);
 }
 
+static void multipath_postsuspend(struct dm_target *ti)
+{
+	struct multipath *m = ti->private;
+
+	mutex_lock(&m->work_mutex);
+	m->suspended = 1;
+	flush_multipath_work();
+	mutex_unlock(&m->work_mutex);
+}
+
 /*
  * Restore the queue_if_no_path setting.
  */
@@ -1269,6 +1289,10 @@ static void multipath_resume(struct dm_t
 	struct multipath *m = (struct multipath *) ti->private;
 	unsigned long flags;
 
+	mutex_lock(&m->work_mutex);
+	m->suspended = 0;
+	mutex_unlock(&m->work_mutex);
+
 	spin_lock_irqsave(&m->lock, flags);
 	m->queue_if_no_path = m->saved_queue_if_no_path;
 	spin_unlock_irqrestore(&m->lock, flags);
@@ -1397,51 +1421,71 @@ static int multipath_status(struct dm_ta
 
 static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
 {
-	int r;
+	int r = -EINVAL;
 	struct dm_dev *dev;
 	struct multipath *m = (struct multipath *) ti->private;
 	action_fn action;
 
+	mutex_lock(&m->work_mutex);
+
+	if (m->suspended) {
+		r = -EBUSY;
+		goto out;
+	}
+
+	if (dm_suspended(ti)) {
+		r = -EBUSY;
+		goto out;
+	}
+
 	if (argc == 1) {
-		if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
-			return queue_if_no_path(m, 1, 0);
-		else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
-			return queue_if_no_path(m, 0, 0);
+		if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) {
+			r = queue_if_no_path(m, 1, 0);
+			goto out;
+		} else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) {
+			r = queue_if_no_path(m, 0, 0);
+			goto out;
+		}
 	}
 
-	if (argc != 2)
-		goto error;
+	if (argc != 2) {
+		DMWARN("Unrecognised multipath message received.");
+		goto out;
+	}
 
-	if (!strnicmp(argv[0], MESG_STR("disable_group")))
-		return bypass_pg_num(m, argv[1], 1);
-	else if (!strnicmp(argv[0], MESG_STR("enable_group")))
-		return bypass_pg_num(m, argv[1], 0);
-	else if (!strnicmp(argv[0], MESG_STR("switch_group")))
-		return switch_pg_num(m, argv[1]);
-	else if (!strnicmp(argv[0], MESG_STR("reinstate_path")))
+	if (!strnicmp(argv[0], MESG_STR("disable_group"))) {
+		r = bypass_pg_num(m, argv[1], 1);
+		goto out;
+	} else if (!strnicmp(argv[0], MESG_STR("enable_group"))) {
+		r = bypass_pg_num(m, argv[1], 0);
+		goto out;
+	} else if (!strnicmp(argv[0], MESG_STR("switch_group"))) {
+		r = switch_pg_num(m, argv[1]);
+		goto out;
+	} else if (!strnicmp(argv[0], MESG_STR("reinstate_path")))
 		action = reinstate_path;
 	else if (!strnicmp(argv[0], MESG_STR("fail_path")))
 		action = fail_path;
-	else
-		goto error;
+	else {
+		DMWARN("Unrecognised multipath message received.");
+		goto out;
+	}
 
 	r = dm_get_device(ti, argv[1], ti->begin, ti->len,
 			  dm_table_get_mode(ti->table), &dev);
 	if (r) {
 		DMWARN("message: error getting device %s",
 		       argv[1]);
-		return -EINVAL;
+		goto out;
 	}
 
 	r = action_dev(m, dev, action);
 
 	dm_put_device(ti, dev);
 
+out:
+	mutex_unlock(&m->work_mutex);
 	return r;
-
-error:
-	DMWARN("Unrecognised multipath message received.");
-	return -EINVAL;
 }
 
 static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
@@ -1567,13 +1611,14 @@ out:
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
 	.name = "multipath",
-	.version = {1, 1, 0},
+	.version = {1, 1, 1},
 	.module = THIS_MODULE,
 	.ctr = multipath_ctr,
 	.dtr = multipath_dtr,
 	.map_rq = multipath_map,
 	.rq_end_io = multipath_end_io,
 	.presuspend = multipath_presuspend,
+	.postsuspend = multipath_postsuspend,
 	.resume = multipath_resume,
 	.status = multipath_status,
 	.message = multipath_message,
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-raid1.c linux-libre-2.6.33-gnu1/drivers/md/dm-raid1.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-raid1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-raid1.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@ static DECLARE_WAIT_QUEUE_HEAD(_kmirrord
  *---------------------------------------------------------------*/
 enum dm_raid1_error {
 	DM_RAID1_WRITE_ERROR,
+	DM_RAID1_FLUSH_ERROR,
 	DM_RAID1_SYNC_ERROR,
 	DM_RAID1_READ_ERROR
 };
@@ -57,6 +58,7 @@ struct mirror_set {
 	struct bio_list reads;
 	struct bio_list writes;
 	struct bio_list failures;
+	struct bio_list holds;	/* bios are waiting until suspend */
 
 	struct dm_region_hash *rh;
 	struct dm_kcopyd_client *kcopyd_client;
@@ -67,6 +69,7 @@ struct mirror_set {
 	region_t nr_regions;
 	int in_sync;
 	int log_failure;
+	int leg_failure;
 	atomic_t suspend;
 
 	atomic_t default_mirror;	/* Default mirror */
@@ -179,6 +182,17 @@ static void set_default_mirror(struct mi
 	atomic_set(&ms->default_mirror, m - m0);
 }
 
+static struct mirror *get_valid_mirror(struct mirror_set *ms)
+{
+	struct mirror *m;
+
+	for (m = ms->mirror; m < ms->mirror + ms->nr_mirrors; m++)
+		if (!atomic_read(&m->error_count))
+			return m;
+
+	return NULL;
+}
+
 /* fail_mirror
  * @m: mirror device to fail
  * @error_type: one of the enum's, DM_RAID1_*_ERROR
@@ -198,6 +212,8 @@ static void fail_mirror(struct mirror *m
 	struct mirror_set *ms = m->ms;
 	struct mirror *new;
 
+	ms->leg_failure = 1;
+
 	/*
 	 * error_count is used for nothing more than a
 	 * simple way to tell if a device has encountered
@@ -224,19 +240,50 @@ static void fail_mirror(struct mirror *m
 		goto out;
 	}
 
-	for (new = ms->mirror; new < ms->mirror + ms->nr_mirrors; new++)
-		if (!atomic_read(&new->error_count)) {
-			set_default_mirror(new);
-			break;
-		}
-
-	if (unlikely(new == ms->mirror + ms->nr_mirrors))
+	new = get_valid_mirror(ms);
+	if (new)
+		set_default_mirror(new);
+	else
 		DMWARN("All sides of mirror have failed.");
 
 out:
 	schedule_work(&ms->trigger_event);
 }
 
+static int mirror_flush(struct dm_target *ti)
+{
+	struct mirror_set *ms = ti->private;
+	unsigned long error_bits;
+
+	unsigned int i;
+	struct dm_io_region io[ms->nr_mirrors];
+	struct mirror *m;
+	struct dm_io_request io_req = {
+		.bi_rw = WRITE_BARRIER,
+		.mem.type = DM_IO_KMEM,
+		.mem.ptr.bvec = NULL,
+		.client = ms->io_client,
+	};
+
+	for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) {
+		io[i].bdev = m->dev->bdev;
+		io[i].sector = 0;
+		io[i].count = 0;
+	}
+
+	error_bits = -1;
+	dm_io(&io_req, ms->nr_mirrors, io, &error_bits);
+	if (unlikely(error_bits != 0)) {
+		for (i = 0; i < ms->nr_mirrors; i++)
+			if (test_bit(i, &error_bits))
+				fail_mirror(ms->mirror + i,
+					    DM_RAID1_FLUSH_ERROR);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*-----------------------------------------------------------------
  * Recovery.
  *
@@ -396,6 +443,8 @@ static int mirror_available(struct mirro
  */
 static sector_t map_sector(struct mirror *m, struct bio *bio)
 {
+	if (unlikely(!bio->bi_size))
+		return 0;
 	return m->offset + (bio->bi_sector - m->ms->ti->begin);
 }
 
@@ -413,6 +462,27 @@ static void map_region(struct dm_io_regi
 	io->count = bio->bi_size >> 9;
 }
 
+static void hold_bio(struct mirror_set *ms, struct bio *bio)
+{
+	/*
+	 * If device is suspended, complete the bio.
+	 */
+	if (atomic_read(&ms->suspend)) {
+		if (dm_noflush_suspending(ms->ti))
+			bio_endio(bio, DM_ENDIO_REQUEUE);
+		else
+			bio_endio(bio, -EIO);
+		return;
+	}
+
+	/*
+	 * Hold bio until the suspend is complete.
+	 */
+	spin_lock_irq(&ms->lock);
+	bio_list_add(&ms->holds, bio);
+	spin_unlock_irq(&ms->lock);
+}
+
 /*-----------------------------------------------------------------
  * Reads
  *---------------------------------------------------------------*/
@@ -511,7 +581,6 @@ static void write_callback(unsigned long
 	unsigned i, ret = 0;
 	struct bio *bio = (struct bio *) context;
 	struct mirror_set *ms;
-	int uptodate = 0;
 	int should_wake = 0;
 	unsigned long flags;
 
@@ -524,36 +593,27 @@ static void write_callback(unsigned long
 	 * This way we handle both writes to SYNC and NOSYNC
 	 * regions with the same code.
 	 */
-	if (likely(!error))
-		goto out;
+	if (likely(!error)) {
+		bio_endio(bio, ret);
+		return;
+	}
 
 	for (i = 0; i < ms->nr_mirrors; i++)
 		if (test_bit(i, &error))
 			fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR);
-		else
-			uptodate = 1;
 
-	if (unlikely(!uptodate)) {
-		DMERR("All replicated volumes dead, failing I/O");
-		/* None of the writes succeeded, fail the I/O. */
-		ret = -EIO;
-	} else if (errors_handled(ms)) {
-		/*
-		 * Need to raise event.  Since raising
-		 * events can block, we need to do it in
-		 * the main thread.
-		 */
-		spin_lock_irqsave(&ms->lock, flags);
-		if (!ms->failures.head)
-			should_wake = 1;
-		bio_list_add(&ms->failures, bio);
-		spin_unlock_irqrestore(&ms->lock, flags);
-		if (should_wake)
-			wakeup_mirrord(ms);
-		return;
-	}
-out:
-	bio_endio(bio, ret);
+	/*
+	 * Need to raise event.  Since raising
+	 * events can block, we need to do it in
+	 * the main thread.
+	 */
+	spin_lock_irqsave(&ms->lock, flags);
+	if (!ms->failures.head)
+		should_wake = 1;
+	bio_list_add(&ms->failures, bio);
+	spin_unlock_irqrestore(&ms->lock, flags);
+	if (should_wake)
+		wakeup_mirrord(ms);
 }
 
 static void do_write(struct mirror_set *ms, struct bio *bio)
@@ -562,7 +622,7 @@ static void do_write(struct mirror_set *
 	struct dm_io_region io[ms->nr_mirrors], *dest = io;
 	struct mirror *m;
 	struct dm_io_request io_req = {
-		.bi_rw = WRITE,
+		.bi_rw = WRITE | (bio->bi_rw & WRITE_BARRIER),
 		.mem.type = DM_IO_BVEC,
 		.mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx,
 		.notify.fn = write_callback,
@@ -603,6 +663,11 @@ static void do_writes(struct mirror_set
 	bio_list_init(&requeue);
 
 	while ((bio = bio_list_pop(writes))) {
+		if (unlikely(bio_empty_barrier(bio))) {
+			bio_list_add(&sync, bio);
+			continue;
+		}
+
 		region = dm_rh_bio_to_region(ms->rh, bio);
 
 		if (log->type->is_remote_recovering &&
@@ -659,7 +724,7 @@ static void do_writes(struct mirror_set
 	/*
 	 * Dispatch io.
 	 */
-	if (unlikely(ms->log_failure)) {
+	if (unlikely(ms->log_failure) && errors_handled(ms)) {
 		spin_lock_irq(&ms->lock);
 		bio_list_merge(&ms->failures, &sync);
 		spin_unlock_irq(&ms->lock);
@@ -672,8 +737,12 @@ static void do_writes(struct mirror_set
 		dm_rh_delay(ms->rh, bio);
 
 	while ((bio = bio_list_pop(&nosync))) {
-		map_bio(get_default_mirror(ms), bio);
-		generic_make_request(bio);
+		if (unlikely(ms->leg_failure) && errors_handled(ms))
+			hold_bio(ms, bio);
+		else {
+			map_bio(get_default_mirror(ms), bio);
+			generic_make_request(bio);
+		}
 	}
 }
 
@@ -681,20 +750,12 @@ static void do_failures(struct mirror_se
 {
 	struct bio *bio;
 
-	if (!failures->head)
-		return;
-
-	if (!ms->log_failure) {
-		while ((bio = bio_list_pop(failures))) {
-			ms->in_sync = 0;
-			dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0);
-		}
+	if (likely(!failures->head))
 		return;
-	}
 
 	/*
 	 * If the log has failed, unattempted writes are being
-	 * put on the failures list.  We can't issue those writes
+	 * put on the holds list.  We can't issue those writes
 	 * until a log has been marked, so we must store them.
 	 *
 	 * If a 'noflush' suspend is in progress, we can requeue
@@ -709,23 +770,27 @@ static void do_failures(struct mirror_se
 	 * for us to treat them the same and requeue them
 	 * as well.
 	 */
-	if (dm_noflush_suspending(ms->ti)) {
-		while ((bio = bio_list_pop(failures)))
-			bio_endio(bio, DM_ENDIO_REQUEUE);
-		return;
-	}
+	while ((bio = bio_list_pop(failures))) {
+		if (!ms->log_failure) {
+			ms->in_sync = 0;
+			dm_rh_mark_nosync(ms->rh, bio);
+		}
 
-	if (atomic_read(&ms->suspend)) {
-		while ((bio = bio_list_pop(failures)))
+		/*
+		 * If all the legs are dead, fail the I/O.
+		 * If we have been told to handle errors, hold the bio
+		 * and wait for userspace to deal with the problem.
+		 * Otherwise pretend that the I/O succeeded. (This would
+		 * be wrong if the failed leg returned after reboot and
+		 * got replicated back to the good legs.)
+		 */
+		if (!get_valid_mirror(ms))
 			bio_endio(bio, -EIO);
-		return;
+		else if (errors_handled(ms))
+			hold_bio(ms, bio);
+		else
+			bio_endio(bio, 0);
 	}
-
-	spin_lock_irq(&ms->lock);
-	bio_list_merge(&ms->failures, failures);
-	spin_unlock_irq(&ms->lock);
-
-	delayed_wake(ms);
 }
 
 static void trigger_event(struct work_struct *work)
@@ -784,12 +849,17 @@ static struct mirror_set *alloc_context(
 	}
 
 	spin_lock_init(&ms->lock);
+	bio_list_init(&ms->reads);
+	bio_list_init(&ms->writes);
+	bio_list_init(&ms->failures);
+	bio_list_init(&ms->holds);
 
 	ms->ti = ti;
 	ms->nr_mirrors = nr_mirrors;
 	ms->nr_regions = dm_sector_div_up(ti->len, region_size);
 	ms->in_sync = 0;
 	ms->log_failure = 0;
+	ms->leg_failure = 0;
 	atomic_set(&ms->suspend, 0);
 	atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
 
@@ -889,7 +959,8 @@ static struct dm_dirty_log *create_dirty
 		return NULL;
 	}
 
-	dl = dm_dirty_log_create(argv[0], ti, param_count, argv + 2);
+	dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
+				 argv + 2);
 	if (!dl) {
 		ti->error = "Error creating mirror dirty log";
 		return NULL;
@@ -995,6 +1066,7 @@ static int mirror_ctr(struct dm_target *
 
 	ti->private = ms;
 	ti->split_io = dm_rh_get_region_size(ms->rh);
+	ti->num_flush_requests = 1;
 
 	ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
 	if (!ms->kmirrord_wq) {
@@ -1122,7 +1194,8 @@ static int mirror_end_io(struct dm_targe
 	 * We need to dec pending if this was a write.
 	 */
 	if (rw == WRITE) {
-		dm_rh_dec(ms->rh, map_context->ll);
+		if (likely(!bio_empty_barrier(bio)))
+			dm_rh_dec(ms->rh, map_context->ll);
 		return error;
 	}
 
@@ -1180,6 +1253,9 @@ static void mirror_presuspend(struct dm_
 	struct mirror_set *ms = (struct mirror_set *) ti->private;
 	struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
 
+	struct bio_list holds;
+	struct bio *bio;
+
 	atomic_set(&ms->suspend, 1);
 
 	/*
@@ -1202,6 +1278,22 @@ static void mirror_presuspend(struct dm_
 	 * we know that all of our I/O has been pushed.
 	 */
 	flush_workqueue(ms->kmirrord_wq);
+
+	/*
+	 * Now set ms->suspend is set and the workqueue flushed, no more
+	 * entries can be added to ms->hold list, so process it.
+	 *
+	 * Bios can still arrive concurrently with or after this
+	 * presuspend function, but they cannot join the hold list
+	 * because ms->suspend is set.
+	 */
+	spin_lock_irq(&ms->lock);
+	holds = ms->holds;
+	bio_list_init(&ms->holds);
+	spin_unlock_irq(&ms->lock);
+
+	while ((bio = bio_list_pop(&holds)))
+		hold_bio(ms, bio);
 }
 
 static void mirror_postsuspend(struct dm_target *ti)
@@ -1244,7 +1336,8 @@ static char device_status_char(struct mi
 	if (!atomic_read(&(m->error_count)))
 		return 'A';
 
-	return (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
+	return (test_bit(DM_RAID1_FLUSH_ERROR, &(m->error_type))) ? 'F' :
+		(test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
 		(test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' :
 		(test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U';
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-region-hash.c linux-libre-2.6.33-gnu1/drivers/md/dm-region-hash.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-region-hash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-region-hash.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,11 @@ struct dm_region_hash {
 	struct list_head recovered_regions;
 	struct list_head failed_recovered_regions;
 
+	/*
+	 * If there was a barrier failure no regions can be marked clean.
+	 */
+	int barrier_failure;
+
 	void *context;
 	sector_t target_begin;
 
@@ -211,6 +216,7 @@ struct dm_region_hash *dm_region_hash_cr
 	INIT_LIST_HEAD(&rh->quiesced_regions);
 	INIT_LIST_HEAD(&rh->recovered_regions);
 	INIT_LIST_HEAD(&rh->failed_recovered_regions);
+	rh->barrier_failure = 0;
 
 	rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
 						      sizeof(struct dm_region));
@@ -377,8 +383,6 @@ static void complete_resync_work(struct
 /* dm_rh_mark_nosync
  * @ms
  * @bio
- * @done
- * @error
  *
  * The bio was written on some mirror(s) but failed on other mirror(s).
  * We can successfully endio the bio but should avoid the region being
@@ -386,8 +390,7 @@ static void complete_resync_work(struct
  *
  * This function is _not_ safe in interrupt context!
  */
-void dm_rh_mark_nosync(struct dm_region_hash *rh,
-		       struct bio *bio, unsigned done, int error)
+void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
 {
 	unsigned long flags;
 	struct dm_dirty_log *log = rh->log;
@@ -395,6 +398,11 @@ void dm_rh_mark_nosync(struct dm_region_
 	region_t region = dm_rh_bio_to_region(rh, bio);
 	int recovering = 0;
 
+	if (bio_empty_barrier(bio)) {
+		rh->barrier_failure = 1;
+		return;
+	}
+
 	/* We must inform the log that the sync count has changed. */
 	log->type->set_region_sync(log, region, 0);
 
@@ -419,7 +427,6 @@ void dm_rh_mark_nosync(struct dm_region_
 	BUG_ON(!list_empty(&reg->list));
 	spin_unlock_irqrestore(&rh->region_lock, flags);
 
-	bio_endio(bio, error);
 	if (recovering)
 		complete_resync_work(reg, 0);
 }
@@ -515,8 +522,11 @@ void dm_rh_inc_pending(struct dm_region_
 {
 	struct bio *bio;
 
-	for (bio = bios->head; bio; bio = bio->bi_next)
+	for (bio = bios->head; bio; bio = bio->bi_next) {
+		if (bio_empty_barrier(bio))
+			continue;
 		rh_inc(rh, dm_rh_bio_to_region(rh, bio));
+	}
 }
 EXPORT_SYMBOL_GPL(dm_rh_inc_pending);
 
@@ -544,7 +554,14 @@ void dm_rh_dec(struct dm_region_hash *rh
 		 */
 
 		/* do nothing for DM_RH_NOSYNC */
-		if (reg->state == DM_RH_RECOVERING) {
+		if (unlikely(rh->barrier_failure)) {
+			/*
+			 * If a write barrier failed some time ago, we
+			 * don't know whether or not this write made it
+			 * to the disk, so we must resync the device.
+			 */
+			reg->state = DM_RH_NOSYNC;
+		} else if (reg->state == DM_RH_RECOVERING) {
 			list_add_tail(&reg->list, &rh->quiesced_regions);
 		} else if (reg->state == DM_RH_DIRTY) {
 			reg->state = DM_RH_CLEAN;
@@ -643,10 +660,9 @@ void dm_rh_recovery_end(struct dm_region
 	spin_lock_irq(&rh->region_lock);
 	if (success)
 		list_add(&reg->list, &reg->rh->recovered_regions);
-	else {
-		reg->state = DM_RH_NOSYNC;
+	else
 		list_add(&reg->list, &reg->rh->failed_recovered_regions);
-	}
+
 	spin_unlock_irq(&rh->region_lock);
 
 	rh->wakeup_workers(rh->context);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-snap.c linux-libre-2.6.33-gnu1/drivers/md/dm-snap.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-snap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-snap.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,11 @@
 
 #define DM_MSG_PREFIX "snapshots"
 
+static const char dm_snapshot_merge_target_name[] = "snapshot-merge";
+
+#define dm_target_is_snapshot_merge(ti) \
+	((ti)->type->name == dm_snapshot_merge_target_name)
+
 /*
  * The percentage increment we will wake up users at
  */
@@ -49,7 +54,7 @@
 #define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
 					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
 
-struct exception_table {
+struct dm_exception_table {
 	uint32_t hash_mask;
 	unsigned hash_shift;
 	struct list_head *table;
@@ -59,22 +64,31 @@ struct dm_snapshot {
 	struct rw_semaphore lock;
 
 	struct dm_dev *origin;
+	struct dm_dev *cow;
+
+	struct dm_target *ti;
 
 	/* List of snapshots per Origin */
 	struct list_head list;
 
-	/* You can't use a snapshot if this is 0 (e.g. if full) */
+	/*
+	 * You can't use a snapshot if this is 0 (e.g. if full).
+	 * A snapshot-merge target never clears this.
+	 */
 	int valid;
 
 	/* Origin writes don't trigger exceptions until this is set */
 	int active;
 
+	/* Whether or not owning mapped_device is suspended */
+	int suspended;
+
 	mempool_t *pending_pool;
 
 	atomic_t pending_exceptions_count;
 
-	struct exception_table pending;
-	struct exception_table complete;
+	struct dm_exception_table pending;
+	struct dm_exception_table complete;
 
 	/*
 	 * pe_lock protects all pending_exception operations and access
@@ -95,8 +109,51 @@ struct dm_snapshot {
 	mempool_t *tracked_chunk_pool;
 	spinlock_t tracked_chunk_lock;
 	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+
+	/*
+	 * The merge operation failed if this flag is set.
+	 * Failure modes are handled as follows:
+	 * - I/O error reading the header
+	 *   	=> don't load the target; abort.
+	 * - Header does not have "valid" flag set
+	 *   	=> use the origin; forget about the snapshot.
+	 * - I/O error when reading exceptions
+	 *   	=> don't load the target; abort.
+	 *         (We can't use the intermediate origin state.)
+	 * - I/O error while merging
+	 *	=> stop merging; set merge_failed; process I/O normally.
+	 */
+	int merge_failed;
+
+	/* Wait for events based on state_bits */
+	unsigned long state_bits;
+
+	/* Range of chunks currently being merged. */
+	chunk_t first_merging_chunk;
+	int num_merging_chunks;
+
+	/*
+	 * Incoming bios that overlap with chunks being merged must wait
+	 * for them to be committed.
+	 */
+	struct bio_list bios_queued_during_merge;
 };
 
+/*
+ * state_bits:
+ *   RUNNING_MERGE  - Merge operation is in progress.
+ *   SHUTDOWN_MERGE - Set to signal that merge needs to be stopped;
+ *                    cleared afterwards.
+ */
+#define RUNNING_MERGE          0
+#define SHUTDOWN_MERGE         1
+
+struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
+{
+	return s->cow;
+}
+EXPORT_SYMBOL(dm_snap_cow);
+
 static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
@@ -116,7 +173,7 @@ static int bdev_equal(struct block_devic
 }
 
 struct dm_snap_pending_exception {
-	struct dm_snap_exception e;
+	struct dm_exception e;
 
 	/*
 	 * Origin buffers waiting for this to complete are held
@@ -125,28 +182,6 @@ struct dm_snap_pending_exception {
 	struct bio_list origin_bios;
 	struct bio_list snapshot_bios;
 
-	/*
-	 * Short-term queue of pending exceptions prior to submission.
-	 */
-	struct list_head list;
-
-	/*
-	 * The primary pending_exception is the one that holds
-	 * the ref_count and the list of origin_bios for a
-	 * group of pending_exceptions.  It is always last to get freed.
-	 * These fields get set up when writing to the origin.
-	 */
-	struct dm_snap_pending_exception *primary_pe;
-
-	/*
-	 * Number of pending_exceptions processing this chunk.
-	 * When this drops to zero we must complete the origin bios.
-	 * If incrementing or decrementing this, hold pe->snap->lock for
-	 * the sibling concerned and not pe->primary_pe->snap->lock unless
-	 * they are the same.
-	 */
-	atomic_t ref_count;
-
 	/* Pointer back to snapshot context */
 	struct dm_snapshot *snap;
 
@@ -222,6 +257,16 @@ static int __chunk_is_tracked(struct dm_
 }
 
 /*
+ * This conflicting I/O is extremely improbable in the caller,
+ * so msleep(1) is sufficient and there is no need for a wait queue.
+ */
+static void __check_for_conflicting_io(struct dm_snapshot *s, chunk_t chunk)
+{
+	while (__chunk_is_tracked(s, chunk))
+		msleep(1);
+}
+
+/*
  * One of these per registered origin, held in the snapshot_origins hash
  */
 struct origin {
@@ -243,6 +288,10 @@ struct origin {
 static struct list_head *_origins;
 static struct rw_semaphore _origins_lock;
 
+static DECLARE_WAIT_QUEUE_HEAD(_pending_exceptions_done);
+static DEFINE_SPINLOCK(_pending_exceptions_done_spinlock);
+static uint64_t _pending_exceptions_done_count;
+
 static int init_origin_hash(void)
 {
 	int i;
@@ -291,22 +340,144 @@ static void __insert_origin(struct origi
 }
 
 /*
+ * _origins_lock must be held when calling this function.
+ * Returns number of snapshots registered using the supplied cow device, plus:
+ * snap_src - a snapshot suitable for use as a source of exception handover
+ * snap_dest - a snapshot capable of receiving exception handover.
+ * snap_merge - an existing snapshot-merge target linked to the same origin.
+ *   There can be at most one snapshot-merge target. The parameter is optional.
+ *
+ * Possible return values and states of snap_src and snap_dest.
+ *   0: NULL, NULL  - first new snapshot
+ *   1: snap_src, NULL - normal snapshot
+ *   2: snap_src, snap_dest  - waiting for handover
+ *   2: snap_src, NULL - handed over, waiting for old to be deleted
+ *   1: NULL, snap_dest - source got destroyed without handover
+ */
+static int __find_snapshots_sharing_cow(struct dm_snapshot *snap,
+					struct dm_snapshot **snap_src,
+					struct dm_snapshot **snap_dest,
+					struct dm_snapshot **snap_merge)
+{
+	struct dm_snapshot *s;
+	struct origin *o;
+	int count = 0;
+	int active;
+
+	o = __lookup_origin(snap->origin->bdev);
+	if (!o)
+		goto out;
+
+	list_for_each_entry(s, &o->snapshots, list) {
+		if (dm_target_is_snapshot_merge(s->ti) && snap_merge)
+			*snap_merge = s;
+		if (!bdev_equal(s->cow->bdev, snap->cow->bdev))
+			continue;
+
+		down_read(&s->lock);
+		active = s->active;
+		up_read(&s->lock);
+
+		if (active) {
+			if (snap_src)
+				*snap_src = s;
+		} else if (snap_dest)
+			*snap_dest = s;
+
+		count++;
+	}
+
+out:
+	return count;
+}
+
+/*
+ * On success, returns 1 if this snapshot is a handover destination,
+ * otherwise returns 0.
+ */
+static int __validate_exception_handover(struct dm_snapshot *snap)
+{
+	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
+	struct dm_snapshot *snap_merge = NULL;
+
+	/* Does snapshot need exceptions handed over to it? */
+	if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest,
+					  &snap_merge) == 2) ||
+	    snap_dest) {
+		snap->ti->error = "Snapshot cow pairing for exception "
+				  "table handover failed";
+		return -EINVAL;
+	}
+
+	/*
+	 * If no snap_src was found, snap cannot become a handover
+	 * destination.
+	 */
+	if (!snap_src)
+		return 0;
+
+	/*
+	 * Non-snapshot-merge handover?
+	 */
+	if (!dm_target_is_snapshot_merge(snap->ti))
+		return 1;
+
+	/*
+	 * Do not allow more than one merging snapshot.
+	 */
+	if (snap_merge) {
+		snap->ti->error = "A snapshot is already merging.";
+		return -EINVAL;
+	}
+
+	if (!snap_src->store->type->prepare_merge ||
+	    !snap_src->store->type->commit_merge) {
+		snap->ti->error = "Snapshot exception store does not "
+				  "support snapshot-merge.";
+		return -EINVAL;
+	}
+
+	return 1;
+}
+
+static void __insert_snapshot(struct origin *o, struct dm_snapshot *s)
+{
+	struct dm_snapshot *l;
+
+	/* Sort the list according to chunk size, largest-first smallest-last */
+	list_for_each_entry(l, &o->snapshots, list)
+		if (l->store->chunk_size < s->store->chunk_size)
+			break;
+	list_add_tail(&s->list, &l->list);
+}
+
+/*
  * Make a note of the snapshot and its origin so we can look it
  * up when the origin has a write on it.
+ *
+ * Also validate snapshot exception store handovers.
+ * On success, returns 1 if this registration is a handover destination,
+ * otherwise returns 0.
  */
 static int register_snapshot(struct dm_snapshot *snap)
 {
-	struct dm_snapshot *l;
-	struct origin *o, *new_o;
+	struct origin *o, *new_o = NULL;
 	struct block_device *bdev = snap->origin->bdev;
+	int r = 0;
 
 	new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
 	if (!new_o)
 		return -ENOMEM;
 
 	down_write(&_origins_lock);
-	o = __lookup_origin(bdev);
 
+	r = __validate_exception_handover(snap);
+	if (r < 0) {
+		kfree(new_o);
+		goto out;
+	}
+
+	o = __lookup_origin(bdev);
 	if (o)
 		kfree(new_o);
 	else {
@@ -320,14 +491,27 @@ static int register_snapshot(struct dm_s
 		__insert_origin(o);
 	}
 
-	/* Sort the list according to chunk size, largest-first smallest-last */
-	list_for_each_entry(l, &o->snapshots, list)
-		if (l->store->chunk_size < snap->store->chunk_size)
-			break;
-	list_add_tail(&snap->list, &l->list);
+	__insert_snapshot(o, snap);
+
+out:
+	up_write(&_origins_lock);
+
+	return r;
+}
+
+/*
+ * Move snapshot to correct place in list according to chunk size.
+ */
+static void reregister_snapshot(struct dm_snapshot *s)
+{
+	struct block_device *bdev = s->origin->bdev;
+
+	down_write(&_origins_lock);
+
+	list_del(&s->list);
+	__insert_snapshot(__lookup_origin(bdev), s);
 
 	up_write(&_origins_lock);
-	return 0;
 }
 
 static void unregister_snapshot(struct dm_snapshot *s)
@@ -338,7 +522,7 @@ static void unregister_snapshot(struct d
 	o = __lookup_origin(s->origin->bdev);
 
 	list_del(&s->list);
-	if (list_empty(&o->snapshots)) {
+	if (o && list_empty(&o->snapshots)) {
 		list_del(&o->hash_list);
 		kfree(o);
 	}
@@ -351,8 +535,8 @@ static void unregister_snapshot(struct d
  * The lowest hash_shift bits of the chunk number are ignored, allowing
  * some consecutive chunks to be grouped together.
  */
-static int init_exception_table(struct exception_table *et, uint32_t size,
-				unsigned hash_shift)
+static int dm_exception_table_init(struct dm_exception_table *et,
+				   uint32_t size, unsigned hash_shift)
 {
 	unsigned int i;
 
@@ -368,10 +552,11 @@ static int init_exception_table(struct e
 	return 0;
 }
 
-static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem)
+static void dm_exception_table_exit(struct dm_exception_table *et,
+				    struct kmem_cache *mem)
 {
 	struct list_head *slot;
-	struct dm_snap_exception *ex, *next;
+	struct dm_exception *ex, *next;
 	int i, size;
 
 	size = et->hash_mask + 1;
@@ -385,19 +570,12 @@ static void exit_exception_table(struct
 	vfree(et->table);
 }
 
-static uint32_t exception_hash(struct exception_table *et, chunk_t chunk)
+static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk)
 {
 	return (chunk >> et->hash_shift) & et->hash_mask;
 }
 
-static void insert_exception(struct exception_table *eh,
-			     struct dm_snap_exception *e)
-{
-	struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)];
-	list_add(&e->hash_list, l);
-}
-
-static void remove_exception(struct dm_snap_exception *e)
+static void dm_remove_exception(struct dm_exception *e)
 {
 	list_del(&e->hash_list);
 }
@@ -406,11 +584,11 @@ static void remove_exception(struct dm_s
  * Return the exception data for a sector, or NULL if not
  * remapped.
  */
-static struct dm_snap_exception *lookup_exception(struct exception_table *et,
-						  chunk_t chunk)
+static struct dm_exception *dm_lookup_exception(struct dm_exception_table *et,
+						chunk_t chunk)
 {
 	struct list_head *slot;
-	struct dm_snap_exception *e;
+	struct dm_exception *e;
 
 	slot = &et->table[exception_hash(et, chunk)];
 	list_for_each_entry (e, slot, hash_list)
@@ -421,9 +599,9 @@ static struct dm_snap_exception *lookup_
 	return NULL;
 }
 
-static struct dm_snap_exception *alloc_exception(void)
+static struct dm_exception *alloc_completed_exception(void)
 {
-	struct dm_snap_exception *e;
+	struct dm_exception *e;
 
 	e = kmem_cache_alloc(exception_cache, GFP_NOIO);
 	if (!e)
@@ -432,7 +610,7 @@ static struct dm_snap_exception *alloc_e
 	return e;
 }
 
-static void free_exception(struct dm_snap_exception *e)
+static void free_completed_exception(struct dm_exception *e)
 {
 	kmem_cache_free(exception_cache, e);
 }
@@ -457,12 +635,11 @@ static void free_pending_exception(struc
 	atomic_dec(&s->pending_exceptions_count);
 }
 
-static void insert_completed_exception(struct dm_snapshot *s,
-				       struct dm_snap_exception *new_e)
+static void dm_insert_exception(struct dm_exception_table *eh,
+				struct dm_exception *new_e)
 {
-	struct exception_table *eh = &s->complete;
 	struct list_head *l;
-	struct dm_snap_exception *e = NULL;
+	struct dm_exception *e = NULL;
 
 	l = &eh->table[exception_hash(eh, new_e->old_chunk)];
 
@@ -478,7 +655,7 @@ static void insert_completed_exception(s
 		    new_e->new_chunk == (dm_chunk_number(e->new_chunk) +
 					 dm_consecutive_chunk_count(e) + 1)) {
 			dm_consecutive_chunk_count_inc(e);
-			free_exception(new_e);
+			free_completed_exception(new_e);
 			return;
 		}
 
@@ -488,7 +665,7 @@ static void insert_completed_exception(s
 			dm_consecutive_chunk_count_inc(e);
 			e->old_chunk--;
 			e->new_chunk--;
-			free_exception(new_e);
+			free_completed_exception(new_e);
 			return;
 		}
 
@@ -507,9 +684,9 @@ out:
 static int dm_add_exception(void *context, chunk_t old, chunk_t new)
 {
 	struct dm_snapshot *s = context;
-	struct dm_snap_exception *e;
+	struct dm_exception *e;
 
-	e = alloc_exception();
+	e = alloc_completed_exception();
 	if (!e)
 		return -ENOMEM;
 
@@ -518,11 +695,30 @@ static int dm_add_exception(void *contex
 	/* Consecutive_count is implicitly initialised to zero */
 	e->new_chunk = new;
 
-	insert_completed_exception(s, e);
+	dm_insert_exception(&s->complete, e);
 
 	return 0;
 }
 
+#define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r)))
+
+/*
+ * Return a minimum chunk size of all snapshots that have the specified origin.
+ * Return zero if the origin has no snapshots.
+ */
+static sector_t __minimum_chunk_size(struct origin *o)
+{
+	struct dm_snapshot *snap;
+	unsigned chunk_size = 0;
+
+	if (o)
+		list_for_each_entry(snap, &o->snapshots, list)
+			chunk_size = min_not_zero(chunk_size,
+						  snap->store->chunk_size);
+
+	return chunk_size;
+}
+
 /*
  * Hard coded magic.
  */
@@ -546,16 +742,18 @@ static int init_hash_tables(struct dm_sn
 	 * Calculate based on the size of the original volume or
 	 * the COW volume...
 	 */
-	cow_dev_size = get_dev_size(s->store->cow->bdev);
+	cow_dev_size = get_dev_size(s->cow->bdev);
 	origin_dev_size = get_dev_size(s->origin->bdev);
 	max_buckets = calc_max_buckets();
 
 	hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
 	hash_size = min(hash_size, max_buckets);
 
+	if (hash_size < 64)
+		hash_size = 64;
 	hash_size = rounddown_pow_of_two(hash_size);
-	if (init_exception_table(&s->complete, hash_size,
-				 DM_CHUNK_CONSECUTIVE_BITS))
+	if (dm_exception_table_init(&s->complete, hash_size,
+				    DM_CHUNK_CONSECUTIVE_BITS))
 		return -ENOMEM;
 
 	/*
@@ -566,14 +764,284 @@ static int init_hash_tables(struct dm_sn
 	if (hash_size < 64)
 		hash_size = 64;
 
-	if (init_exception_table(&s->pending, hash_size, 0)) {
-		exit_exception_table(&s->complete, exception_cache);
+	if (dm_exception_table_init(&s->pending, hash_size, 0)) {
+		dm_exception_table_exit(&s->complete, exception_cache);
 		return -ENOMEM;
 	}
 
 	return 0;
 }
 
+static void merge_shutdown(struct dm_snapshot *s)
+{
+	clear_bit_unlock(RUNNING_MERGE, &s->state_bits);
+	smp_mb__after_clear_bit();
+	wake_up_bit(&s->state_bits, RUNNING_MERGE);
+}
+
+static struct bio *__release_queued_bios_after_merge(struct dm_snapshot *s)
+{
+	s->first_merging_chunk = 0;
+	s->num_merging_chunks = 0;
+
+	return bio_list_get(&s->bios_queued_during_merge);
+}
+
+/*
+ * Remove one chunk from the index of completed exceptions.
+ */
+static int __remove_single_exception_chunk(struct dm_snapshot *s,
+					   chunk_t old_chunk)
+{
+	struct dm_exception *e;
+
+	e = dm_lookup_exception(&s->complete, old_chunk);
+	if (!e) {
+		DMERR("Corruption detected: exception for block %llu is "
+		      "on disk but not in memory",
+		      (unsigned long long)old_chunk);
+		return -EINVAL;
+	}
+
+	/*
+	 * If this is the only chunk using this exception, remove exception.
+	 */
+	if (!dm_consecutive_chunk_count(e)) {
+		dm_remove_exception(e);
+		free_completed_exception(e);
+		return 0;
+	}
+
+	/*
+	 * The chunk may be either at the beginning or the end of a
+	 * group of consecutive chunks - never in the middle.  We are
+	 * removing chunks in the opposite order to that in which they
+	 * were added, so this should always be true.
+	 * Decrement the consecutive chunk counter and adjust the
+	 * starting point if necessary.
+	 */
+	if (old_chunk == e->old_chunk) {
+		e->old_chunk++;
+		e->new_chunk++;
+	} else if (old_chunk != e->old_chunk +
+		   dm_consecutive_chunk_count(e)) {
+		DMERR("Attempt to merge block %llu from the "
+		      "middle of a chunk range [%llu - %llu]",
+		      (unsigned long long)old_chunk,
+		      (unsigned long long)e->old_chunk,
+		      (unsigned long long)
+		      e->old_chunk + dm_consecutive_chunk_count(e));
+		return -EINVAL;
+	}
+
+	dm_consecutive_chunk_count_dec(e);
+
+	return 0;
+}
+
+static void flush_bios(struct bio *bio);
+
+static int remove_single_exception_chunk(struct dm_snapshot *s)
+{
+	struct bio *b = NULL;
+	int r;
+	chunk_t old_chunk = s->first_merging_chunk + s->num_merging_chunks - 1;
+
+	down_write(&s->lock);
+
+	/*
+	 * Process chunks (and associated exceptions) in reverse order
+	 * so that dm_consecutive_chunk_count_dec() accounting works.
+	 */
+	do {
+		r = __remove_single_exception_chunk(s, old_chunk);
+		if (r)
+			goto out;
+	} while (old_chunk-- > s->first_merging_chunk);
+
+	b = __release_queued_bios_after_merge(s);
+
+out:
+	up_write(&s->lock);
+	if (b)
+		flush_bios(b);
+
+	return r;
+}
+
+static int origin_write_extent(struct dm_snapshot *merging_snap,
+			       sector_t sector, unsigned chunk_size);
+
+static void merge_callback(int read_err, unsigned long write_err,
+			   void *context);
+
+static uint64_t read_pending_exceptions_done_count(void)
+{
+	uint64_t pending_exceptions_done;
+
+	spin_lock(&_pending_exceptions_done_spinlock);
+	pending_exceptions_done = _pending_exceptions_done_count;
+	spin_unlock(&_pending_exceptions_done_spinlock);
+
+	return pending_exceptions_done;
+}
+
+static void increment_pending_exceptions_done_count(void)
+{
+	spin_lock(&_pending_exceptions_done_spinlock);
+	_pending_exceptions_done_count++;
+	spin_unlock(&_pending_exceptions_done_spinlock);
+
+	wake_up_all(&_pending_exceptions_done);
+}
+
+static void snapshot_merge_next_chunks(struct dm_snapshot *s)
+{
+	int i, linear_chunks;
+	chunk_t old_chunk, new_chunk;
+	struct dm_io_region src, dest;
+	sector_t io_size;
+	uint64_t previous_count;
+
+	BUG_ON(!test_bit(RUNNING_MERGE, &s->state_bits));
+	if (unlikely(test_bit(SHUTDOWN_MERGE, &s->state_bits)))
+		goto shut;
+
+	/*
+	 * valid flag never changes during merge, so no lock required.
+	 */
+	if (!s->valid) {
+		DMERR("Snapshot is invalid: can't merge");
+		goto shut;
+	}
+
+	linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk,
+						      &new_chunk);
+	if (linear_chunks <= 0) {
+		if (linear_chunks < 0) {
+			DMERR("Read error in exception store: "
+			      "shutting down merge");
+			down_write(&s->lock);
+			s->merge_failed = 1;
+			up_write(&s->lock);
+		}
+		goto shut;
+	}
+
+	/* Adjust old_chunk and new_chunk to reflect start of linear region */
+	old_chunk = old_chunk + 1 - linear_chunks;
+	new_chunk = new_chunk + 1 - linear_chunks;
+
+	/*
+	 * Use one (potentially large) I/O to copy all 'linear_chunks'
+	 * from the exception store to the origin
+	 */
+	io_size = linear_chunks * s->store->chunk_size;
+
+	dest.bdev = s->origin->bdev;
+	dest.sector = chunk_to_sector(s->store, old_chunk);
+	dest.count = min(io_size, get_dev_size(dest.bdev) - dest.sector);
+
+	src.bdev = s->cow->bdev;
+	src.sector = chunk_to_sector(s->store, new_chunk);
+	src.count = dest.count;
+
+	/*
+	 * Reallocate any exceptions needed in other snapshots then
+	 * wait for the pending exceptions to complete.
+	 * Each time any pending exception (globally on the system)
+	 * completes we are woken and repeat the process to find out
+	 * if we can proceed.  While this may not seem a particularly
+	 * efficient algorithm, it is not expected to have any
+	 * significant impact on performance.
+	 */
+	previous_count = read_pending_exceptions_done_count();
+	while (origin_write_extent(s, dest.sector, io_size)) {
+		wait_event(_pending_exceptions_done,
+			   (read_pending_exceptions_done_count() !=
+			    previous_count));
+		/* Retry after the wait, until all exceptions are done. */
+		previous_count = read_pending_exceptions_done_count();
+	}
+
+	down_write(&s->lock);
+	s->first_merging_chunk = old_chunk;
+	s->num_merging_chunks = linear_chunks;
+	up_write(&s->lock);
+
+	/* Wait until writes to all 'linear_chunks' drain */
+	for (i = 0; i < linear_chunks; i++)
+		__check_for_conflicting_io(s, old_chunk + i);
+
+	dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s);
+	return;
+
+shut:
+	merge_shutdown(s);
+}
+
+static void error_bios(struct bio *bio);
+
+static void merge_callback(int read_err, unsigned long write_err, void *context)
+{
+	struct dm_snapshot *s = context;
+	struct bio *b = NULL;
+
+	if (read_err || write_err) {
+		if (read_err)
+			DMERR("Read error: shutting down merge.");
+		else
+			DMERR("Write error: shutting down merge.");
+		goto shut;
+	}
+
+	if (s->store->type->commit_merge(s->store,
+					 s->num_merging_chunks) < 0) {
+		DMERR("Write error in exception store: shutting down merge");
+		goto shut;
+	}
+
+	if (remove_single_exception_chunk(s) < 0)
+		goto shut;
+
+	snapshot_merge_next_chunks(s);
+
+	return;
+
+shut:
+	down_write(&s->lock);
+	s->merge_failed = 1;
+	b = __release_queued_bios_after_merge(s);
+	up_write(&s->lock);
+	error_bios(b);
+
+	merge_shutdown(s);
+}
+
+static void start_merge(struct dm_snapshot *s)
+{
+	if (!test_and_set_bit(RUNNING_MERGE, &s->state_bits))
+		snapshot_merge_next_chunks(s);
+}
+
+static int wait_schedule(void *ptr)
+{
+	schedule();
+
+	return 0;
+}
+
+/*
+ * Stop the merging process and wait until it finishes.
+ */
+static void stop_merge(struct dm_snapshot *s)
+{
+	set_bit(SHUTDOWN_MERGE, &s->state_bits);
+	wait_on_bit(&s->state_bits, RUNNING_MERGE, wait_schedule,
+		    TASK_UNINTERRUPTIBLE);
+	clear_bit(SHUTDOWN_MERGE, &s->state_bits);
+}
+
 /*
  * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
  */
@@ -582,50 +1050,73 @@ static int snapshot_ctr(struct dm_target
 	struct dm_snapshot *s;
 	int i;
 	int r = -EINVAL;
-	char *origin_path;
-	struct dm_exception_store *store;
-	unsigned args_used;
+	char *origin_path, *cow_path;
+	unsigned args_used, num_flush_requests = 1;
+	fmode_t origin_mode = FMODE_READ;
 
 	if (argc != 4) {
 		ti->error = "requires exactly 4 arguments";
 		r = -EINVAL;
-		goto bad_args;
+		goto bad;
+	}
+
+	if (dm_target_is_snapshot_merge(ti)) {
+		num_flush_requests = 2;
+		origin_mode = FMODE_WRITE;
 	}
 
 	origin_path = argv[0];
 	argv++;
 	argc--;
 
-	r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (!s) {
+		ti->error = "Cannot allocate snapshot context private "
+		    "structure";
+		r = -ENOMEM;
+		goto bad;
+	}
+
+	cow_path = argv[0];
+	argv++;
+	argc--;
+
+	r = dm_get_device(ti, cow_path, 0, 0,
+			  FMODE_READ | FMODE_WRITE, &s->cow);
+	if (r) {
+		ti->error = "Cannot get COW device";
+		goto bad_cow;
+	}
+
+	r = dm_exception_store_create(ti, argc, argv, s, &args_used, &s->store);
 	if (r) {
 		ti->error = "Couldn't create exception store";
 		r = -EINVAL;
-		goto bad_args;
+		goto bad_store;
 	}
 
 	argv += args_used;
 	argc -= args_used;
 
-	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (!s) {
-		ti->error = "Cannot allocate snapshot context private "
-		    "structure";
-		r = -ENOMEM;
-		goto bad_snap;
-	}
-
-	r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
+	r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin);
 	if (r) {
 		ti->error = "Cannot get origin device";
 		goto bad_origin;
 	}
 
-	s->store = store;
+	s->ti = ti;
 	s->valid = 1;
 	s->active = 0;
+	s->suspended = 0;
 	atomic_set(&s->pending_exceptions_count, 0);
 	init_rwsem(&s->lock);
+	INIT_LIST_HEAD(&s->list);
 	spin_lock_init(&s->pe_lock);
+	s->state_bits = 0;
+	s->merge_failed = 0;
+	s->first_merging_chunk = 0;
+	s->num_merging_chunks = 0;
+	bio_list_init(&s->bios_queued_during_merge);
 
 	/* Allocate hash table for COW data */
 	if (init_hash_tables(s)) {
@@ -659,39 +1150,55 @@ static int snapshot_ctr(struct dm_target
 
 	spin_lock_init(&s->tracked_chunk_lock);
 
-	/* Metadata must only be loaded into one table at once */
+	bio_list_init(&s->queued_bios);
+	INIT_WORK(&s->queued_bios_work, flush_queued_bios);
+
+	ti->private = s;
+	ti->num_flush_requests = num_flush_requests;
+
+	/* Add snapshot to the list of snapshots for this origin */
+	/* Exceptions aren't triggered till snapshot_resume() is called */
+	r = register_snapshot(s);
+	if (r == -ENOMEM) {
+		ti->error = "Snapshot origin struct allocation failed";
+		goto bad_load_and_register;
+	} else if (r < 0) {
+		/* invalid handover, register_snapshot has set ti->error */
+		goto bad_load_and_register;
+	}
+
+	/*
+	 * Metadata must only be loaded into one table at once, so skip this
+	 * if metadata will be handed over during resume.
+	 * Chunk size will be set during the handover - set it to zero to
+	 * ensure it's ignored.
+	 */
+	if (r > 0) {
+		s->store->chunk_size = 0;
+		return 0;
+	}
+
 	r = s->store->type->read_metadata(s->store, dm_add_exception,
 					  (void *)s);
 	if (r < 0) {
 		ti->error = "Failed to read snapshot metadata";
-		goto bad_load_and_register;
+		goto bad_read_metadata;
 	} else if (r > 0) {
 		s->valid = 0;
 		DMWARN("Snapshot is marked invalid.");
 	}
 
-	bio_list_init(&s->queued_bios);
-	INIT_WORK(&s->queued_bios_work, flush_queued_bios);
-
 	if (!s->store->chunk_size) {
 		ti->error = "Chunk size not set";
-		goto bad_load_and_register;
-	}
-
-	/* Add snapshot to the list of snapshots for this origin */
-	/* Exceptions aren't triggered till snapshot_resume() is called */
-	if (register_snapshot(s)) {
-		r = -EINVAL;
-		ti->error = "Cannot register snapshot origin";
-		goto bad_load_and_register;
+		goto bad_read_metadata;
 	}
-
-	ti->private = s;
 	ti->split_io = s->store->chunk_size;
-	ti->num_flush_requests = 1;
 
 	return 0;
 
+bad_read_metadata:
+	unregister_snapshot(s);
+
 bad_load_and_register:
 	mempool_destroy(s->tracked_chunk_pool);
 
@@ -702,19 +1209,22 @@ bad_pending_pool:
 	dm_kcopyd_client_destroy(s->kcopyd_client);
 
 bad_kcopyd:
-	exit_exception_table(&s->pending, pending_cache);
-	exit_exception_table(&s->complete, exception_cache);
+	dm_exception_table_exit(&s->pending, pending_cache);
+	dm_exception_table_exit(&s->complete, exception_cache);
 
 bad_hash_tables:
 	dm_put_device(ti, s->origin);
 
 bad_origin:
-	kfree(s);
+	dm_exception_store_destroy(s->store);
 
-bad_snap:
-	dm_exception_store_destroy(store);
+bad_store:
+	dm_put_device(ti, s->cow);
 
-bad_args:
+bad_cow:
+	kfree(s);
+
+bad:
 	return r;
 }
 
@@ -723,8 +1233,39 @@ static void __free_exceptions(struct dm_
 	dm_kcopyd_client_destroy(s->kcopyd_client);
 	s->kcopyd_client = NULL;
 
-	exit_exception_table(&s->pending, pending_cache);
-	exit_exception_table(&s->complete, exception_cache);
+	dm_exception_table_exit(&s->pending, pending_cache);
+	dm_exception_table_exit(&s->complete, exception_cache);
+}
+
+static void __handover_exceptions(struct dm_snapshot *snap_src,
+				  struct dm_snapshot *snap_dest)
+{
+	union {
+		struct dm_exception_table table_swap;
+		struct dm_exception_store *store_swap;
+	} u;
+
+	/*
+	 * Swap all snapshot context information between the two instances.
+	 */
+	u.table_swap = snap_dest->complete;
+	snap_dest->complete = snap_src->complete;
+	snap_src->complete = u.table_swap;
+
+	u.store_swap = snap_dest->store;
+	snap_dest->store = snap_src->store;
+	snap_src->store = u.store_swap;
+
+	snap_dest->store->snap = snap_dest;
+	snap_src->store->snap = snap_src;
+
+	snap_dest->ti->split_io = snap_dest->store->chunk_size;
+	snap_dest->valid = snap_src->valid;
+
+	/*
+	 * Set source invalid to ensure it receives no further I/O.
+	 */
+	snap_src->valid = 0;
 }
 
 static void snapshot_dtr(struct dm_target *ti)
@@ -733,9 +1274,24 @@ static void snapshot_dtr(struct dm_targe
 	int i;
 #endif
 	struct dm_snapshot *s = ti->private;
+	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
 
 	flush_workqueue(ksnapd);
 
+	down_read(&_origins_lock);
+	/* Check whether exception handover must be cancelled */
+	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
+	if (snap_src && snap_dest && (s == snap_src)) {
+		down_write(&snap_dest->lock);
+		snap_dest->valid = 0;
+		up_write(&snap_dest->lock);
+		DMERR("Cancelling snapshot handover.");
+	}
+	up_read(&_origins_lock);
+
+	if (dm_target_is_snapshot_merge(ti))
+		stop_merge(s);
+
 	/* Prevent further origin writes from using this snapshot. */
 	/* After this returns there can be no new kcopyd jobs. */
 	unregister_snapshot(s);
@@ -763,6 +1319,8 @@ static void snapshot_dtr(struct dm_targe
 
 	dm_exception_store_destroy(s->store);
 
+	dm_put_device(ti, s->cow);
+
 	kfree(s);
 }
 
@@ -795,6 +1353,26 @@ static void flush_queued_bios(struct wor
 	flush_bios(queued_bios);
 }
 
+static int do_origin(struct dm_dev *origin, struct bio *bio);
+
+/*
+ * Flush a list of buffers.
+ */
+static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio)
+{
+	struct bio *n;
+	int r;
+
+	while (bio) {
+		n = bio->bi_next;
+		bio->bi_next = NULL;
+		r = do_origin(s->origin, bio);
+		if (r == DM_MAPIO_REMAPPED)
+			generic_make_request(bio);
+		bio = n;
+	}
+}
+
 /*
  * Error a list of buffers.
  */
@@ -825,45 +1403,12 @@ static void __invalidate_snapshot(struct
 
 	s->valid = 0;
 
-	dm_table_event(s->store->ti->table);
-}
-
-static void get_pending_exception(struct dm_snap_pending_exception *pe)
-{
-	atomic_inc(&pe->ref_count);
-}
-
-static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
-{
-	struct dm_snap_pending_exception *primary_pe;
-	struct bio *origin_bios = NULL;
-
-	primary_pe = pe->primary_pe;
-
-	/*
-	 * If this pe is involved in a write to the origin and
-	 * it is the last sibling to complete then release
-	 * the bios for the original write to the origin.
-	 */
-	if (primary_pe &&
-	    atomic_dec_and_test(&primary_pe->ref_count)) {
-		origin_bios = bio_list_get(&primary_pe->origin_bios);
-		free_pending_exception(primary_pe);
-	}
-
-	/*
-	 * Free the pe if it's not linked to an origin write or if
-	 * it's not itself a primary pe.
-	 */
-	if (!primary_pe || primary_pe != pe)
-		free_pending_exception(pe);
-
-	return origin_bios;
+	dm_table_event(s->ti->table);
 }
 
 static void pending_complete(struct dm_snap_pending_exception *pe, int success)
 {
-	struct dm_snap_exception *e;
+	struct dm_exception *e;
 	struct dm_snapshot *s = pe->snap;
 	struct bio *origin_bios = NULL;
 	struct bio *snapshot_bios = NULL;
@@ -877,7 +1422,7 @@ static void pending_complete(struct dm_s
 		goto out;
 	}
 
-	e = alloc_exception();
+	e = alloc_completed_exception();
 	if (!e) {
 		down_write(&s->lock);
 		__invalidate_snapshot(s, -ENOMEM);
@@ -888,28 +1433,27 @@ static void pending_complete(struct dm_s
 
 	down_write(&s->lock);
 	if (!s->valid) {
-		free_exception(e);
+		free_completed_exception(e);
 		error = 1;
 		goto out;
 	}
 
-	/*
-	 * Check for conflicting reads. This is extremely improbable,
-	 * so msleep(1) is sufficient and there is no need for a wait queue.
-	 */
-	while (__chunk_is_tracked(s, pe->e.old_chunk))
-		msleep(1);
+	/* Check for conflicting reads */
+	__check_for_conflicting_io(s, pe->e.old_chunk);
 
 	/*
 	 * Add a proper exception, and remove the
 	 * in-flight exception from the list.
 	 */
-	insert_completed_exception(s, e);
+	dm_insert_exception(&s->complete, e);
 
  out:
-	remove_exception(&pe->e);
+	dm_remove_exception(&pe->e);
 	snapshot_bios = bio_list_get(&pe->snapshot_bios);
-	origin_bios = put_pending_exception(pe);
+	origin_bios = bio_list_get(&pe->origin_bios);
+	free_pending_exception(pe);
+
+	increment_pending_exceptions_done_count();
 
 	up_write(&s->lock);
 
@@ -919,7 +1463,7 @@ static void pending_complete(struct dm_s
 	else
 		flush_bios(snapshot_bios);
 
-	flush_bios(origin_bios);
+	retry_origin_bios(s, origin_bios);
 }
 
 static void commit_callback(void *context, int success)
@@ -963,7 +1507,7 @@ static void start_copy(struct dm_snap_pe
 	src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
 	src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);
 
-	dest.bdev = s->store->cow->bdev;
+	dest.bdev = s->cow->bdev;
 	dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
 	dest.count = src.count;
 
@@ -975,7 +1519,7 @@ static void start_copy(struct dm_snap_pe
 static struct dm_snap_pending_exception *
 __lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
 {
-	struct dm_snap_exception *e = lookup_exception(&s->pending, chunk);
+	struct dm_exception *e = dm_lookup_exception(&s->pending, chunk);
 
 	if (!e)
 		return NULL;
@@ -1006,8 +1550,6 @@ __find_pending_exception(struct dm_snaps
 	pe->e.old_chunk = chunk;
 	bio_list_init(&pe->origin_bios);
 	bio_list_init(&pe->snapshot_bios);
-	pe->primary_pe = NULL;
-	atomic_set(&pe->ref_count, 0);
 	pe->started = 0;
 
 	if (s->store->type->prepare_exception(s->store, &pe->e)) {
@@ -1015,16 +1557,15 @@ __find_pending_exception(struct dm_snaps
 		return NULL;
 	}
 
-	get_pending_exception(pe);
-	insert_exception(&s->pending, &pe->e);
+	dm_insert_exception(&s->pending, &pe->e);
 
 	return pe;
 }
 
-static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
+static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
 			    struct bio *bio, chunk_t chunk)
 {
-	bio->bi_bdev = s->store->cow->bdev;
+	bio->bi_bdev = s->cow->bdev;
 	bio->bi_sector = chunk_to_sector(s->store,
 					 dm_chunk_number(e->new_chunk) +
 					 (chunk - e->old_chunk)) +
@@ -1035,14 +1576,14 @@ static void remap_exception(struct dm_sn
 static int snapshot_map(struct dm_target *ti, struct bio *bio,
 			union map_info *map_context)
 {
-	struct dm_snap_exception *e;
+	struct dm_exception *e;
 	struct dm_snapshot *s = ti->private;
 	int r = DM_MAPIO_REMAPPED;
 	chunk_t chunk;
 	struct dm_snap_pending_exception *pe = NULL;
 
 	if (unlikely(bio_empty_barrier(bio))) {
-		bio->bi_bdev = s->store->cow->bdev;
+		bio->bi_bdev = s->cow->bdev;
 		return DM_MAPIO_REMAPPED;
 	}
 
@@ -1063,7 +1604,7 @@ static int snapshot_map(struct dm_target
 	}
 
 	/* If the block is already remapped - use that, else remap it */
-	e = lookup_exception(&s->complete, chunk);
+	e = dm_lookup_exception(&s->complete, chunk);
 	if (e) {
 		remap_exception(s, e, bio, chunk);
 		goto out_unlock;
@@ -1087,7 +1628,7 @@ static int snapshot_map(struct dm_target
 				goto out_unlock;
 			}
 
-			e = lookup_exception(&s->complete, chunk);
+			e = dm_lookup_exception(&s->complete, chunk);
 			if (e) {
 				free_pending_exception(pe);
 				remap_exception(s, e, bio, chunk);
@@ -1125,6 +1666,78 @@ static int snapshot_map(struct dm_target
 	return r;
 }
 
+/*
+ * A snapshot-merge target behaves like a combination of a snapshot
+ * target and a snapshot-origin target.  It only generates new
+ * exceptions in other snapshots and not in the one that is being
+ * merged.
+ *
+ * For each chunk, if there is an existing exception, it is used to
+ * redirect I/O to the cow device.  Otherwise I/O is sent to the origin,
+ * which in turn might generate exceptions in other snapshots.
+ * If merging is currently taking place on the chunk in question, the
+ * I/O is deferred by adding it to s->bios_queued_during_merge.
+ */
+static int snapshot_merge_map(struct dm_target *ti, struct bio *bio,
+			      union map_info *map_context)
+{
+	struct dm_exception *e;
+	struct dm_snapshot *s = ti->private;
+	int r = DM_MAPIO_REMAPPED;
+	chunk_t chunk;
+
+	if (unlikely(bio_empty_barrier(bio))) {
+		if (!map_context->flush_request)
+			bio->bi_bdev = s->origin->bdev;
+		else
+			bio->bi_bdev = s->cow->bdev;
+		map_context->ptr = NULL;
+		return DM_MAPIO_REMAPPED;
+	}
+
+	chunk = sector_to_chunk(s->store, bio->bi_sector);
+
+	down_write(&s->lock);
+
+	/* Full merging snapshots are redirected to the origin */
+	if (!s->valid)
+		goto redirect_to_origin;
+
+	/* If the block is already remapped - use that */
+	e = dm_lookup_exception(&s->complete, chunk);
+	if (e) {
+		/* Queue writes overlapping with chunks being merged */
+		if (bio_rw(bio) == WRITE &&
+		    chunk >= s->first_merging_chunk &&
+		    chunk < (s->first_merging_chunk +
+			     s->num_merging_chunks)) {
+			bio->bi_bdev = s->origin->bdev;
+			bio_list_add(&s->bios_queued_during_merge, bio);
+			r = DM_MAPIO_SUBMITTED;
+			goto out_unlock;
+		}
+
+		remap_exception(s, e, bio, chunk);
+
+		if (bio_rw(bio) == WRITE)
+			map_context->ptr = track_chunk(s, chunk);
+		goto out_unlock;
+	}
+
+redirect_to_origin:
+	bio->bi_bdev = s->origin->bdev;
+
+	if (bio_rw(bio) == WRITE) {
+		up_write(&s->lock);
+		return do_origin(s->origin, bio);
+	}
+
+out_unlock:
+	up_write(&s->lock);
+
+	return r;
+}
+
 static int snapshot_end_io(struct dm_target *ti, struct bio *bio,
 			   int error, union map_info *map_context)
 {
@@ -1137,40 +1750,135 @@ static int snapshot_end_io(struct dm_tar
 	return 0;
 }
 
+static void snapshot_merge_presuspend(struct dm_target *ti)
+{
+	struct dm_snapshot *s = ti->private;
+
+	stop_merge(s);
+}
+
+static void snapshot_postsuspend(struct dm_target *ti)
+{
+	struct dm_snapshot *s = ti->private;
+
+	down_write(&s->lock);
+	s->suspended = 1;
+	up_write(&s->lock);
+}
+
+static int snapshot_preresume(struct dm_target *ti)
+{
+	int r = 0;
+	struct dm_snapshot *s = ti->private;
+	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
+
+	down_read(&_origins_lock);
+	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
+	if (snap_src && snap_dest) {
+		down_read(&snap_src->lock);
+		if (s == snap_src) {
+			DMERR("Unable to resume snapshot source until "
+			      "handover completes.");
+			r = -EINVAL;
+		} else if (!snap_src->suspended) {
+			DMERR("Unable to perform snapshot handover until "
+			      "source is suspended.");
+			r = -EINVAL;
+		}
+		up_read(&snap_src->lock);
+	}
+	up_read(&_origins_lock);
+
+	return r;
+}
+
 static void snapshot_resume(struct dm_target *ti)
 {
 	struct dm_snapshot *s = ti->private;
+	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
+
+	down_read(&_origins_lock);
+	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
+	if (snap_src && snap_dest) {
+		down_write(&snap_src->lock);
+		down_write_nested(&snap_dest->lock, SINGLE_DEPTH_NESTING);
+		__handover_exceptions(snap_src, snap_dest);
+		up_write(&snap_dest->lock);
+		up_write(&snap_src->lock);
+	}
+	up_read(&_origins_lock);
+
+	/* Now we have correct chunk size, reregister */
+	reregister_snapshot(s);
 
 	down_write(&s->lock);
 	s->active = 1;
+	s->suspended = 0;
 	up_write(&s->lock);
 }
 
+static sector_t get_origin_minimum_chunksize(struct block_device *bdev)
+{
+	sector_t min_chunksize;
+
+	down_read(&_origins_lock);
+	min_chunksize = __minimum_chunk_size(__lookup_origin(bdev));
+	up_read(&_origins_lock);
+
+	return min_chunksize;
+}
+
+static void snapshot_merge_resume(struct dm_target *ti)
+{
+	struct dm_snapshot *s = ti->private;
+
+	/*
+	 * Handover exceptions from existing snapshot.
+	 */
+	snapshot_resume(ti);
+
+	/*
+	 * snapshot-merge acts as an origin, so set ti->split_io
+	 */
+	ti->split_io = get_origin_minimum_chunksize(s->origin->bdev);
+
+	start_merge(s);
+}
+
 static int snapshot_status(struct dm_target *ti, status_type_t type,
 			   char *result, unsigned int maxlen)
 {
 	unsigned sz = 0;
 	struct dm_snapshot *snap = ti->private;
 
-	down_write(&snap->lock);
-
 	switch (type) {
 	case STATUSTYPE_INFO:
+
+		down_write(&snap->lock);
+
 		if (!snap->valid)
 			DMEMIT("Invalid");
+		else if (snap->merge_failed)
+			DMEMIT("Merge failed");
 		else {
-			if (snap->store->type->fraction_full) {
-				sector_t numerator, denominator;
-				snap->store->type->fraction_full(snap->store,
-								 &numerator,
-								 &denominator);
-				DMEMIT("%llu/%llu",
-				       (unsigned long long)numerator,
-				       (unsigned long long)denominator);
+			if (snap->store->type->usage) {
+				sector_t total_sectors, sectors_allocated,
+					 metadata_sectors;
+				snap->store->type->usage(snap->store,
+							 &total_sectors,
+							 &sectors_allocated,
+							 &metadata_sectors);
+				DMEMIT("%llu/%llu %llu",
+				       (unsigned long long)sectors_allocated,
+				       (unsigned long long)total_sectors,
+				       (unsigned long long)metadata_sectors);
 			}
 			else
 				DMEMIT("Unknown");
 		}
+
+		up_write(&snap->lock);
+
 		break;
 
 	case STATUSTYPE_TABLE:
@@ -1179,14 +1887,12 @@ static int snapshot_status(struct dm_tar
 		 * to make private copies if the output is to
 		 * make sense.
 		 */
-		DMEMIT("%s", snap->origin->name);
+		DMEMIT("%s %s", snap->origin->name, snap->cow->name);
 		snap->store->type->status(snap->store, type, result + sz,
 					  maxlen - sz);
 		break;
 	}
 
-	up_write(&snap->lock);
-
 	return 0;
 }
 
@@ -1202,17 +1908,36 @@ static int snapshot_iterate_devices(stru
 /*-----------------------------------------------------------------
  * Origin methods
  *---------------------------------------------------------------*/
-static int __origin_write(struct list_head *snapshots, struct bio *bio)
+
+/*
+ * If no exceptions need creating, DM_MAPIO_REMAPPED is returned and any
+ * supplied bio was ignored.  The caller may submit it immediately.
+ * (No remapping actually occurs as the origin is always a direct linear
+ * map.)
+ *
+ * If further exceptions are required, DM_MAPIO_SUBMITTED is returned
+ * and any supplied bio is added to a list to be submitted once all
+ * the necessary exceptions exist.
+ */
+static int __origin_write(struct list_head *snapshots, sector_t sector,
+			  struct bio *bio)
 {
-	int r = DM_MAPIO_REMAPPED, first = 0;
+	int r = DM_MAPIO_REMAPPED;
 	struct dm_snapshot *snap;
-	struct dm_snap_exception *e;
-	struct dm_snap_pending_exception *pe, *next_pe, *primary_pe = NULL;
+	struct dm_exception *e;
+	struct dm_snap_pending_exception *pe;
+	struct dm_snap_pending_exception *pe_to_start_now = NULL;
+	struct dm_snap_pending_exception *pe_to_start_last = NULL;
 	chunk_t chunk;
-	LIST_HEAD(pe_queue);
 
 	/* Do all the snapshots on this origin */
 	list_for_each_entry (snap, snapshots, list) {
+		/*
+		 * Don't make new exceptions in a merging snapshot
+		 * because it has effectively been deleted
+		 */
+		if (dm_target_is_snapshot_merge(snap->ti))
+			continue;
 
 		down_write(&snap->lock);
 
@@ -1221,24 +1946,21 @@ static int __origin_write(struct list_he
 			goto next_snapshot;
 
 		/* Nothing to do if writing beyond end of snapshot */
-		if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
+		if (sector >= dm_table_get_size(snap->ti->table))
 			goto next_snapshot;
 
 		/*
 		 * Remember, different snapshots can have
 		 * different chunk sizes.
 		 */
-		chunk = sector_to_chunk(snap->store, bio->bi_sector);
+		chunk = sector_to_chunk(snap->store, sector);
 
 		/*
 		 * Check exception table to see if block
 		 * is already remapped in this snapshot
 		 * and trigger an exception if not.
-		 *
-		 * ref_count is initialised to 1 so pending_complete()
-		 * won't destroy the primary_pe while we're inside this loop.
 		 */
-		e = lookup_exception(&snap->complete, chunk);
+		e = dm_lookup_exception(&snap->complete, chunk);
 		if (e)
 			goto next_snapshot;
 
@@ -1253,7 +1975,7 @@ static int __origin_write(struct list_he
 				goto next_snapshot;
 			}
 
-			e = lookup_exception(&snap->complete, chunk);
+			e = dm_lookup_exception(&snap->complete, chunk);
 			if (e) {
 				free_pending_exception(pe);
 				goto next_snapshot;
@@ -1266,59 +1988,43 @@ static int __origin_write(struct list_he
 			}
 		}
 
-		if (!primary_pe) {
-			/*
-			 * Either every pe here has same
-			 * primary_pe or none has one yet.
-			 */
-			if (pe->primary_pe)
-				primary_pe = pe->primary_pe;
-			else {
-				primary_pe = pe;
-				first = 1;
-			}
-
-			bio_list_add(&primary_pe->origin_bios, bio);
+		r = DM_MAPIO_SUBMITTED;
 
-			r = DM_MAPIO_SUBMITTED;
-		}
+		/*
+		 * If an origin bio was supplied, queue it to wait for the
+		 * completion of this exception, and start this one last,
+		 * at the end of the function.
+		 */
+		if (bio) {
+			bio_list_add(&pe->origin_bios, bio);
+			bio = NULL;
 
-		if (!pe->primary_pe) {
-			pe->primary_pe = primary_pe;
-			get_pending_exception(primary_pe);
+			if (!pe->started) {
+				pe->started = 1;
+				pe_to_start_last = pe;
+			}
 		}
 
 		if (!pe->started) {
 			pe->started = 1;
-			list_add_tail(&pe->list, &pe_queue);
+			pe_to_start_now = pe;
 		}
 
  next_snapshot:
 		up_write(&snap->lock);
-	}
-
-	if (!primary_pe)
-		return r;
-
-	/*
-	 * If this is the first time we're processing this chunk and
-	 * ref_count is now 1 it means all the pending exceptions
-	 * got completed while we were in the loop above, so it falls to
-	 * us here to remove the primary_pe and submit any origin_bios.
-	 */
 
-	if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
-		flush_bios(bio_list_get(&primary_pe->origin_bios));
-		free_pending_exception(primary_pe);
-		/* If we got here, pe_queue is necessarily empty. */
-		return r;
+		if (pe_to_start_now) {
+			start_copy(pe_to_start_now);
+			pe_to_start_now = NULL;
+		}
 	}
 
 	/*
-	 * Now that we have a complete pe list we can start the copying.
+	 * Submit the exception against which the bio is queued last,
+	 * to give the other exceptions a head start.
 	 */
-	list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
-		start_copy(pe);
+	if (pe_to_start_last)
+		start_copy(pe_to_start_last);
 
 	return r;
 }
@@ -1334,13 +2040,48 @@ static int do_origin(struct dm_dev *orig
 	down_read(&_origins_lock);
 	o = __lookup_origin(origin->bdev);
 	if (o)
-		r = __origin_write(&o->snapshots, bio);
+		r = __origin_write(&o->snapshots, bio->bi_sector, bio);
 	up_read(&_origins_lock);
 
 	return r;
 }
 
 /*
+ * Trigger exceptions in all non-merging snapshots.
+ *
+ * The chunk size of the merging snapshot may be larger than the chunk
+ * size of some other snapshot so we may need to reallocate multiple
+ * chunks in other snapshots.
+ *
+ * We scan all the overlapping exceptions in the other snapshots.
+ * Returns 1 if anything was reallocated and must be waited for,
+ * otherwise returns 0.
+ *
+ * size must be a multiple of merging_snap's chunk_size.
+ */
+static int origin_write_extent(struct dm_snapshot *merging_snap,
+			       sector_t sector, unsigned size)
+{
+	int must_wait = 0;
+	sector_t n;
+	struct origin *o;
+
+	/*
+	 * The origin's __minimum_chunk_size() got stored in split_io
+	 * by snapshot_merge_resume().
+	 */
+	down_read(&_origins_lock);
+	o = __lookup_origin(merging_snap->origin->bdev);
+	for (n = 0; n < size; n += merging_snap->ti->split_io)
+		if (__origin_write(&o->snapshots, sector + n, NULL) ==
+		    DM_MAPIO_SUBMITTED)
+			must_wait = 1;
+	up_read(&_origins_lock);
+
+	return must_wait;
+}
+
+/*
  * Origin: maps a linear range of a device, with hooks for snapshotting.
  */
 
@@ -1391,8 +2132,6 @@ static int origin_map(struct dm_target *
 	return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
 }
 
-#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
-
 /*
  * Set the target "split_io" field to the minimum of all the snapshots'
  * chunk sizes.
@@ -1400,19 +2139,8 @@ static int origin_map(struct dm_target *
 static void origin_resume(struct dm_target *ti)
 {
 	struct dm_dev *dev = ti->private;
-	struct dm_snapshot *snap;
-	struct origin *o;
-	unsigned chunk_size = 0;
-
-	down_read(&_origins_lock);
-	o = __lookup_origin(dev->bdev);
-	if (o)
-		list_for_each_entry (snap, &o->snapshots, list)
-			chunk_size = min_not_zero(chunk_size,
-						  snap->store->chunk_size);
-	up_read(&_origins_lock);
 
-	ti->split_io = chunk_size;
+	ti->split_io = get_origin_minimum_chunksize(dev->bdev);
 }
 
 static int origin_status(struct dm_target *ti, status_type_t type, char *result,
@@ -1455,17 +2183,35 @@ static struct target_type origin_target
 
 static struct target_type snapshot_target = {
 	.name    = "snapshot",
-	.version = {1, 7, 0},
+	.version = {1, 9, 0},
 	.module  = THIS_MODULE,
 	.ctr     = snapshot_ctr,
 	.dtr     = snapshot_dtr,
 	.map     = snapshot_map,
 	.end_io  = snapshot_end_io,
+	.postsuspend = snapshot_postsuspend,
+	.preresume  = snapshot_preresume,
 	.resume  = snapshot_resume,
 	.status  = snapshot_status,
 	.iterate_devices = snapshot_iterate_devices,
 };
 
+static struct target_type merge_target = {
+	.name    = dm_snapshot_merge_target_name,
+	.version = {1, 0, 0},
+	.module  = THIS_MODULE,
+	.ctr     = snapshot_ctr,
+	.dtr     = snapshot_dtr,
+	.map     = snapshot_merge_map,
+	.end_io  = snapshot_end_io,
+	.presuspend = snapshot_merge_presuspend,
+	.postsuspend = snapshot_postsuspend,
+	.preresume  = snapshot_preresume,
+	.resume  = snapshot_merge_resume,
+	.status  = snapshot_status,
+	.iterate_devices = snapshot_iterate_devices,
+};
+
 static int __init dm_snapshot_init(void)
 {
 	int r;
@@ -1477,7 +2223,7 @@ static int __init dm_snapshot_init(void)
 	}
 
 	r = dm_register_target(&snapshot_target);
-	if (r) {
+	if (r < 0) {
 		DMERR("snapshot target register failed %d", r);
 		goto bad_register_snapshot_target;
 	}
@@ -1485,34 +2231,40 @@ static int __init dm_snapshot_init(void)
 	r = dm_register_target(&origin_target);
 	if (r < 0) {
 		DMERR("Origin target register failed %d", r);
-		goto bad1;
+		goto bad_register_origin_target;
+	}
+
+	r = dm_register_target(&merge_target);
+	if (r < 0) {
+		DMERR("Merge target register failed %d", r);
+		goto bad_register_merge_target;
 	}
 
 	r = init_origin_hash();
 	if (r) {
 		DMERR("init_origin_hash failed.");
-		goto bad2;
+		goto bad_origin_hash;
 	}
 
-	exception_cache = KMEM_CACHE(dm_snap_exception, 0);
+	exception_cache = KMEM_CACHE(dm_exception, 0);
 	if (!exception_cache) {
 		DMERR("Couldn't create exception cache.");
 		r = -ENOMEM;
-		goto bad3;
+		goto bad_exception_cache;
 	}
 
 	pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0);
 	if (!pending_cache) {
 		DMERR("Couldn't create pending cache.");
 		r = -ENOMEM;
-		goto bad4;
+		goto bad_pending_cache;
 	}
 
 	tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0);
 	if (!tracked_chunk_cache) {
 		DMERR("Couldn't create cache to track chunks in use.");
 		r = -ENOMEM;
-		goto bad5;
+		goto bad_tracked_chunk_cache;
 	}
 
 	ksnapd = create_singlethread_workqueue("ksnapd");
@@ -1526,19 +2278,21 @@ static int __init dm_snapshot_init(void)
 
 bad_pending_pool:
 	kmem_cache_destroy(tracked_chunk_cache);
-bad5:
+bad_tracked_chunk_cache:
 	kmem_cache_destroy(pending_cache);
-bad4:
+bad_pending_cache:
 	kmem_cache_destroy(exception_cache);
-bad3:
+bad_exception_cache:
 	exit_origin_hash();
-bad2:
+bad_origin_hash:
+	dm_unregister_target(&merge_target);
+bad_register_merge_target:
 	dm_unregister_target(&origin_target);
-bad1:
+bad_register_origin_target:
 	dm_unregister_target(&snapshot_target);
-
 bad_register_snapshot_target:
 	dm_exception_store_exit();
+
 	return r;
 }
 
@@ -1548,6 +2302,7 @@ static void __exit dm_snapshot_exit(void
 
 	dm_unregister_target(&snapshot_target);
 	dm_unregister_target(&origin_target);
+	dm_unregister_target(&merge_target);
 
 	exit_origin_hash();
 	kmem_cache_destroy(pending_cache);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-snap-persistent.c linux-libre-2.6.33-gnu1/drivers/md/dm-snap-persistent.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-snap-persistent.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-snap-persistent.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,6 +55,8 @@
  */
 #define SNAPSHOT_DISK_VERSION 1
 
+#define NUM_SNAPSHOT_HDR_CHUNKS 1
+
 struct disk_header {
 	uint32_t magic;
 
@@ -120,7 +122,22 @@ struct pstore {
 
 	/*
 	 * The next free chunk for an exception.
+	 *
+	 * When creating exceptions, all the chunks here and above are
+	 * free.  It holds the next chunk to be allocated.  On rare
+	 * occasions (e.g. after a system crash) holes can be left in
+	 * the exception store because chunks can be committed out of
+	 * order.
+	 *
+	 * When merging exceptions, it does not necessarily mean all the
+	 * chunks here and above are free.  It holds the value it would
+	 * have held if all chunks had been committed in order of
+	 * allocation.  Consequently the value may occasionally be
+	 * slightly too low, but since it's only used for 'status' and
+	 * it can never reach its minimum value too early this doesn't
+	 * matter.
 	 */
+
 	chunk_t next_free;
 
 	/*
@@ -214,7 +231,7 @@ static int chunk_io(struct pstore *ps, v
 		    int metadata)
 {
 	struct dm_io_region where = {
-		.bdev = ps->store->cow->bdev,
+		.bdev = dm_snap_cow(ps->store->snap)->bdev,
 		.sector = ps->store->chunk_size * chunk,
 		.count = ps->store->chunk_size,
 	};
@@ -237,7 +254,7 @@ static int chunk_io(struct pstore *ps, v
 	 * Issue the synchronous I/O from a different thread
 	 * to avoid generic_make_request recursion.
 	 */
-	INIT_WORK(&req.work, do_metadata);
+	INIT_WORK_ON_STACK(&req.work, do_metadata);
 	queue_work(ps->metadata_wq, &req.work);
 	flush_workqueue(ps->metadata_wq);
 
@@ -294,7 +311,8 @@ static int read_header(struct pstore *ps
 	 */
 	if (!ps->store->chunk_size) {
 		ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
-		    bdev_logical_block_size(ps->store->cow->bdev) >> 9);
+		    bdev_logical_block_size(dm_snap_cow(ps->store->snap)->
+					    bdev) >> 9);
 		ps->store->chunk_mask = ps->store->chunk_size - 1;
 		ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
 		chunk_size_supplied = 0;
@@ -408,6 +426,15 @@ static void write_exception(struct pstor
 	e->new_chunk = cpu_to_le64(de->new_chunk);
 }
 
+static void clear_exception(struct pstore *ps, uint32_t index)
+{
+	struct disk_exception *e = get_exception(ps, index);
+
+	/* clear it */
+	e->old_chunk = 0;
+	e->new_chunk = 0;
+}
+
 /*
  * Registers the exceptions that are present in the current area.
  * 'full' is filled in to indicate if the area has been
@@ -489,11 +516,23 @@ static struct pstore *get_info(struct dm
 	return (struct pstore *) store->context;
 }
 
-static void persistent_fraction_full(struct dm_exception_store *store,
-				     sector_t *numerator, sector_t *denominator)
+static void persistent_usage(struct dm_exception_store *store,
+			     sector_t *total_sectors,
+			     sector_t *sectors_allocated,
+			     sector_t *metadata_sectors)
 {
-	*numerator = get_info(store)->next_free * store->chunk_size;
-	*denominator = get_dev_size(store->cow->bdev);
+	struct pstore *ps = get_info(store);
+
+	*sectors_allocated = ps->next_free * store->chunk_size;
+	*total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev);
+
+	/*
+	 * First chunk is the fixed header.
+	 * Then there are (ps->current_area + 1) metadata chunks, each one
+	 * separated from the next by ps->exceptions_per_area data chunks.
+	 */
+	*metadata_sectors = (ps->current_area + 1 + NUM_SNAPSHOT_HDR_CHUNKS) *
+			    store->chunk_size;
 }
 
 static void persistent_dtr(struct dm_exception_store *store)
@@ -552,44 +591,40 @@ static int persistent_read_metadata(stru
 		ps->current_area = 0;
 		zero_memory_area(ps);
 		r = zero_disk_area(ps, 0);
-		if (r) {
+		if (r)
 			DMWARN("zero_disk_area(0) failed");
-			return r;
-		}
-	} else {
-		/*
-		 * Sanity checks.
-		 */
-		if (ps->version != SNAPSHOT_DISK_VERSION) {
-			DMWARN("unable to handle snapshot disk version %d",
-			       ps->version);
-			return -EINVAL;
-		}
+		return r;
+	}
+	/*
+	 * Sanity checks.
+	 */
+	if (ps->version != SNAPSHOT_DISK_VERSION) {
+		DMWARN("unable to handle snapshot disk version %d",
+		       ps->version);
+		return -EINVAL;
+	}
 
-		/*
-		 * Metadata are valid, but snapshot is invalidated
-		 */
-		if (!ps->valid)
-			return 1;
+	/*
+	 * Metadata are valid, but snapshot is invalidated
+	 */
+	if (!ps->valid)
+		return 1;
 
-		/*
-		 * Read the metadata.
-		 */
-		r = read_exceptions(ps, callback, callback_context);
-		if (r)
-			return r;
-	}
+	/*
+	 * Read the metadata.
+	 */
+	r = read_exceptions(ps, callback, callback_context);
 
-	return 0;
+	return r;
 }
 
 static int persistent_prepare_exception(struct dm_exception_store *store,
-					struct dm_snap_exception *e)
+					struct dm_exception *e)
 {
 	struct pstore *ps = get_info(store);
 	uint32_t stride;
 	chunk_t next_free;
-	sector_t size = get_dev_size(store->cow->bdev);
+	sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);
 
 	/* Is there enough room ? */
 	if (size < ((ps->next_free + 1) * store->chunk_size))
@@ -611,7 +646,7 @@ static int persistent_prepare_exception(
 }
 
 static void persistent_commit_exception(struct dm_exception_store *store,
-					struct dm_snap_exception *e,
+					struct dm_exception *e,
 					void (*callback) (void *, int success),
 					void *callback_context)
 {
@@ -672,6 +707,85 @@ static void persistent_commit_exception(
 	ps->callback_count = 0;
 }
 
+static int persistent_prepare_merge(struct dm_exception_store *store,
+				    chunk_t *last_old_chunk,
+				    chunk_t *last_new_chunk)
+{
+	struct pstore *ps = get_info(store);
+	struct disk_exception de;
+	int nr_consecutive;
+	int r;
+
+	/*
+	 * When current area is empty, move back to preceding area.
+	 */
+	if (!ps->current_committed) {
+		/*
+		 * Have we finished?
+		 */
+		if (!ps->current_area)
+			return 0;
+
+		ps->current_area--;
+		r = area_io(ps, READ);
+		if (r < 0)
+			return r;
+		ps->current_committed = ps->exceptions_per_area;
+	}
+
+	read_exception(ps, ps->current_committed - 1, &de);
+	*last_old_chunk = de.old_chunk;
+	*last_new_chunk = de.new_chunk;
+
+	/*
+	 * Find number of consecutive chunks within the current area,
+	 * working backwards.
+	 */
+	for (nr_consecutive = 1; nr_consecutive < ps->current_committed;
+	     nr_consecutive++) {
+		read_exception(ps, ps->current_committed - 1 - nr_consecutive,
+			       &de);
+		if (de.old_chunk != *last_old_chunk - nr_consecutive ||
+		    de.new_chunk != *last_new_chunk - nr_consecutive)
+			break;
+	}
+
+	return nr_consecutive;
+}
+
+static int persistent_commit_merge(struct dm_exception_store *store,
+				   int nr_merged)
+{
+	int r, i;
+	struct pstore *ps = get_info(store);
+
+	BUG_ON(nr_merged > ps->current_committed);
+
+	for (i = 0; i < nr_merged; i++)
+		clear_exception(ps, ps->current_committed - 1 - i);
+
+	r = area_io(ps, WRITE);
+	if (r < 0)
+		return r;
+
+	ps->current_committed -= nr_merged;
+
+	/*
+	 * At this stage, only persistent_usage() uses ps->next_free, so
+	 * we make no attempt to keep ps->next_free strictly accurate
+	 * as exceptions may have been committed out-of-order originally.
+	 * Once a snapshot has become merging, we set it to the value it
+	 * would have held had all the exceptions been committed in order.
+	 *
+	 * ps->current_area does not get reduced by prepare_merge() until
+	 * after commit_merge() has removed the nr_merged previous exceptions.
+	 */
+	ps->next_free = (area_location(ps, ps->current_area) - 1) +
+			(ps->current_committed + 1) + NUM_SNAPSHOT_HDR_CHUNKS;
+
+	return 0;
+}
+
 static void persistent_drop_snapshot(struct dm_exception_store *store)
 {
 	struct pstore *ps = get_info(store);
@@ -697,7 +811,7 @@ static int persistent_ctr(struct dm_exce
 	ps->area = NULL;
 	ps->zero_area = NULL;
 	ps->header_area = NULL;
-	ps->next_free = 2;	/* skipping the header and first area */
+	ps->next_free = NUM_SNAPSHOT_HDR_CHUNKS + 1; /* header and 1st area */
 	ps->current_committed = 0;
 
 	ps->callback_count = 0;
@@ -726,8 +840,7 @@ static unsigned persistent_status(struct
 	case STATUSTYPE_INFO:
 		break;
 	case STATUSTYPE_TABLE:
-		DMEMIT(" %s P %llu", store->cow->name,
-		       (unsigned long long)store->chunk_size);
+		DMEMIT(" P %llu", (unsigned long long)store->chunk_size);
 	}
 
 	return sz;
@@ -741,8 +854,10 @@ static struct dm_exception_store_type _p
 	.read_metadata = persistent_read_metadata,
 	.prepare_exception = persistent_prepare_exception,
 	.commit_exception = persistent_commit_exception,
+	.prepare_merge = persistent_prepare_merge,
+	.commit_merge = persistent_commit_merge,
 	.drop_snapshot = persistent_drop_snapshot,
-	.fraction_full = persistent_fraction_full,
+	.usage = persistent_usage,
 	.status = persistent_status,
 };
 
@@ -754,8 +869,10 @@ static struct dm_exception_store_type _p
 	.read_metadata = persistent_read_metadata,
 	.prepare_exception = persistent_prepare_exception,
 	.commit_exception = persistent_commit_exception,
+	.prepare_merge = persistent_prepare_merge,
+	.commit_merge = persistent_commit_merge,
 	.drop_snapshot = persistent_drop_snapshot,
-	.fraction_full = persistent_fraction_full,
+	.usage = persistent_usage,
 	.status = persistent_status,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-snap-transient.c linux-libre-2.6.33-gnu1/drivers/md/dm-snap-transient.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-snap-transient.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-snap-transient.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,10 +36,10 @@ static int transient_read_metadata(struc
 }
 
 static int transient_prepare_exception(struct dm_exception_store *store,
-				       struct dm_snap_exception *e)
+				       struct dm_exception *e)
 {
 	struct transient_c *tc = store->context;
-	sector_t size = get_dev_size(store->cow->bdev);
+	sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);
 
 	if (size < (tc->next_free + store->chunk_size))
 		return -1;
@@ -51,7 +51,7 @@ static int transient_prepare_exception(s
 }
 
 static void transient_commit_exception(struct dm_exception_store *store,
-				       struct dm_snap_exception *e,
+				       struct dm_exception *e,
 				       void (*callback) (void *, int success),
 				       void *callback_context)
 {
@@ -59,11 +59,14 @@ static void transient_commit_exception(s
 	callback(callback_context, 1);
 }
 
-static void transient_fraction_full(struct dm_exception_store *store,
-				    sector_t *numerator, sector_t *denominator)
+static void transient_usage(struct dm_exception_store *store,
+			    sector_t *total_sectors,
+			    sector_t *sectors_allocated,
+			    sector_t *metadata_sectors)
 {
-	*numerator = ((struct transient_c *) store->context)->next_free;
-	*denominator = get_dev_size(store->cow->bdev);
+	*sectors_allocated = ((struct transient_c *) store->context)->next_free;
+	*total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev);
+	*metadata_sectors = 0;
 }
 
 static int transient_ctr(struct dm_exception_store *store,
@@ -91,8 +94,7 @@ static unsigned transient_status(struct
 	case STATUSTYPE_INFO:
 		break;
 	case STATUSTYPE_TABLE:
-		DMEMIT(" %s N %llu", store->cow->name,
-		       (unsigned long long)store->chunk_size);
+		DMEMIT(" N %llu", (unsigned long long)store->chunk_size);
 	}
 
 	return sz;
@@ -106,7 +108,7 @@ static struct dm_exception_store_type _t
 	.read_metadata = transient_read_metadata,
 	.prepare_exception = transient_prepare_exception,
 	.commit_exception = transient_commit_exception,
-	.fraction_full = transient_fraction_full,
+	.usage = transient_usage,
 	.status = transient_status,
 };
 
@@ -118,7 +120,7 @@ static struct dm_exception_store_type _t
 	.read_metadata = transient_read_metadata,
 	.prepare_exception = transient_prepare_exception,
 	.commit_exception = transient_commit_exception,
-	.fraction_full = transient_fraction_full,
+	.usage = transient_usage,
 	.status = transient_status,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-stripe.c linux-libre-2.6.33-gnu1/drivers/md/dm-stripe.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-stripe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-stripe.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,7 @@ static int stripe_ctr(struct dm_target *
 	}
 
 	stripes = simple_strtoul(argv[0], &end, 10);
-	if (*end) {
+	if (!stripes || *end) {
 		ti->error = "Invalid stripe count";
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-sysfs.c linux-libre-2.6.33-gnu1/drivers/md/dm-sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@ static ssize_t dm_attr_uuid_show(struct
 
 static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
 {
-	sprintf(buf, "%d\n", dm_suspended(md));
+	sprintf(buf, "%d\n", dm_suspended_md(md));
 
 	return strlen(buf);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-table.c linux-libre-2.6.33-gnu1/drivers/md/dm-table.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-table.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-table.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #include <linux/blkdev.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
@@ -237,6 +238,9 @@ void dm_table_destroy(struct dm_table *t
 {
 	unsigned int i;
 
+	if (!t)
+		return;
+
 	while (atomic_read(&t->holders))
 		msleep(1);
 	smp_mb();
@@ -499,16 +503,15 @@ int dm_set_device_limits(struct dm_targe
 		return 0;
 	}
 
-	if (blk_stack_limits(limits, &q->limits, start << 9) < 0)
-		DMWARN("%s: target device %s is misaligned: "
+	if (bdev_stack_limits(limits, bdev, start) < 0)
+		DMWARN("%s: adding target device %s caused an alignment inconsistency: "
 		       "physical_block_size=%u, logical_block_size=%u, "
 		       "alignment_offset=%u, start=%llu",
 		       dm_device_name(ti->table->md), bdevname(bdev, b),
 		       q->limits.physical_block_size,
 		       q->limits.logical_block_size,
 		       q->limits.alignment_offset,
-		       (unsigned long long) start << 9);
-
+		       (unsigned long long) start << SECTOR_SHIFT);
 
 	/*
 	 * Check if merge fn is supported.
@@ -600,11 +603,8 @@ int dm_split_args(int *argc, char ***arg
 		return -ENOMEM;
 
 	while (1) {
-		start = end;
-
 		/* Skip whitespace */
-		while (*start && isspace(*start))
-			start++;
+		start = skip_spaces(end);
 
 		if (!*start)
 			break;	/* success, we hit the end */
@@ -1025,9 +1025,9 @@ combine_limits:
 		 * for the table.
 		 */
 		if (blk_stack_limits(limits, &ti_limits, 0) < 0)
-			DMWARN("%s: target device "
+			DMWARN("%s: adding target device "
 			       "(start sect %llu len %llu) "
-			       "is misaligned",
+			       "caused an alignment inconsistency",
 			       dm_device_name(table->md),
 			       (unsigned long long) ti->begin,
 			       (unsigned long long) ti->len);
@@ -1079,15 +1079,6 @@ void dm_table_set_restrictions(struct dm
 			       struct queue_limits *limits)
 {
 	/*
-	 * Each target device in the table has a data area that should normally
-	 * be aligned such that the DM device's alignment_offset is 0.
-	 * FIXME: Propagate alignment_offsets up the stack and warn of
-	 *	  sub-optimal or inconsistent settings.
-	 */
-	limits->alignment_offset = 0;
-	limits->misaligned = 0;
-
-	/*
 	 * Copy table's limits to the DM device's request_queue
 	 */
 	q->limits = *limits;
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/dm-uevent.c linux-libre-2.6.33-gnu1/drivers/md/dm-uevent.c
--- linux-libre-2.6.32-gnu1/drivers/md/dm-uevent.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/dm-uevent.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,14 +139,13 @@ void dm_send_uevents(struct list_head *e
 		list_del_init(&event->elist);
 
 		/*
-		 * Need to call dm_copy_name_and_uuid from here for now.
-		 * Context of previous var adds and locking used for
-		 * hash_cell not compatable.
+		 * When a device is being removed this copy fails and we
+		 * discard these unsent events.
 		 */
 		if (dm_copy_name_and_uuid(event->md, event->name,
 					  event->uuid)) {
-			DMERR("%s: dm_copy_name_and_uuid() failed",
-			      __func__);
+			DMINFO("%s: skipping sending uevent for lost device",
+			       __func__);
 			goto uevent_free;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/faulty.c linux-libre-2.6.33-gnu1/drivers/md/faulty.c
--- linux-libre-2.6.32-gnu1/drivers/md/faulty.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/faulty.c	2010-02-24 13:52:17.000000000 -0500
@@ -360,6 +360,7 @@ static void raid_exit(void)
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Fault injection personality for MD");
 MODULE_ALIAS("md-personality-10"); /* faulty */
 MODULE_ALIAS("md-faulty");
 MODULE_ALIAS("md-level--5");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/Kconfig linux-libre-2.6.33-gnu1/drivers/md/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/md/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -185,11 +185,10 @@ config MD_MULTIPATH
 	tristate "Multipath I/O support"
 	depends on BLK_DEV_MD
 	help
-	  Multipath-IO is the ability of certain devices to address the same
-	  physical disk over multiple 'IO paths'. The code ensures that such
-	  paths can be defined and handled at runtime, and ensures that a
-	  transparent failover to the backup path(s) happens if a IO errors
-	  arrives on the primary path.
+	  MD_MULTIPATH provides a simple multi-path personality for use
+	  the MD framework.  It is not under active development.  New
+	  projects should consider using DM_MULTIPATH which has more
+	  features and more testing.
 
 	  If unsure, say N.
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/linear.c linux-libre-2.6.33-gnu1/drivers/md/linear.c
--- linux-libre-2.6.32-gnu1/drivers/md/linear.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/linear.c	2010-02-24 13:52:17.000000000 -0500
@@ -292,7 +292,7 @@ static int linear_make_request (struct r
 	int cpu;
 
 	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
-		bio_endio(bio, -EOPNOTSUPP);
+		md_barrier_request(mddev, bio);
 		return 0;
 	}
 
@@ -383,6 +383,7 @@ static void linear_exit (void)
 module_init(linear_init);
 module_exit(linear_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Linear device concatenation personality for MD");
 MODULE_ALIAS("md-personality-1"); /* LINEAR - deprecated*/
 MODULE_ALIAS("md-linear");
 MODULE_ALIAS("md-level--1");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/md.c linux-libre-2.6.33-gnu1/drivers/md/md.c
--- linux-libre-2.6.32-gnu1/drivers/md/md.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/md.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,11 +39,13 @@
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/poll.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/hdreg.h>
 #include <linux/proc_fs.h>
 #include <linux/random.h>
 #include <linux/reboot.h>
 #include <linux/file.h>
+#include <linux/compat.h>
 #include <linux/delay.h>
 #include <linux/raid/md_p.h>
 #include <linux/raid/md_u.h>
@@ -68,6 +70,12 @@ static DECLARE_WAIT_QUEUE_HEAD(resync_wa
 #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); }
 
 /*
+ * Default number of read corrections we'll attempt on an rdev
+ * before ejecting it from the array. We divide the read error
+ * count by 2 for every hour elapsed between read errors.
+ */
+#define MD_DEFAULT_MAX_CORRECTED_READ_ERRORS 20
+/*
  * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
  * is 1000 KB/sec, so the extra system load does not show up that much.
  * Increase it if you want to have more _guaranteed_ speed. Note that
@@ -98,44 +106,40 @@ static struct ctl_table_header *raid_tab
 
 static ctl_table raid_table[] = {
 	{
-		.ctl_name	= DEV_RAID_SPEED_LIMIT_MIN,
 		.procname	= "speed_limit_min",
 		.data		= &sysctl_speed_limit_min,
 		.maxlen		= sizeof(int),
 		.mode		= S_IRUGO|S_IWUSR,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
 	{
-		.ctl_name	= DEV_RAID_SPEED_LIMIT_MAX,
 		.procname	= "speed_limit_max",
 		.data		= &sysctl_speed_limit_max,
 		.maxlen		= sizeof(int),
 		.mode		= S_IRUGO|S_IWUSR,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= proc_dointvec,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table raid_dir_table[] = {
 	{
-		.ctl_name	= DEV_RAID,
 		.procname	= "raid",
 		.maxlen		= 0,
 		.mode		= S_IRUGO|S_IXUGO,
 		.child		= raid_table,
 	},
-	{ .ctl_name = 0 }
+	{ }
 };
 
 static ctl_table raid_root_table[] = {
 	{
-		.ctl_name	= CTL_DEV,
 		.procname	= "dev",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= raid_dir_table,
 	},
-	{ .ctl_name = 0 }
+	{  }
 };
 
 static const struct block_device_operations md_fops;
@@ -217,12 +221,12 @@ static int md_make_request(struct reques
 		return 0;
 	}
 	rcu_read_lock();
-	if (mddev->suspended) {
+	if (mddev->suspended || mddev->barrier) {
 		DEFINE_WAIT(__wait);
 		for (;;) {
 			prepare_to_wait(&mddev->sb_wait, &__wait,
 					TASK_UNINTERRUPTIBLE);
-			if (!mddev->suspended)
+			if (!mddev->suspended && !mddev->barrier)
 				break;
 			rcu_read_unlock();
 			schedule();
@@ -264,10 +268,110 @@ static void mddev_resume(mddev_t *mddev)
 
 int mddev_congested(mddev_t *mddev, int bits)
 {
+	if (mddev->barrier)
+		return 1;
 	return mddev->suspended;
 }
 EXPORT_SYMBOL(mddev_congested);
 
+/*
+ * Generic barrier handling for md
+ */
+
+#define POST_REQUEST_BARRIER ((void*)1)
+
+static void md_end_barrier(struct bio *bio, int err)
+{
+	mdk_rdev_t *rdev = bio->bi_private;
+	mddev_t *mddev = rdev->mddev;
+	if (err == -EOPNOTSUPP && mddev->barrier != POST_REQUEST_BARRIER)
+		set_bit(BIO_EOPNOTSUPP, &mddev->barrier->bi_flags);
+
+	rdev_dec_pending(rdev, mddev);
+
+	if (atomic_dec_and_test(&mddev->flush_pending)) {
+		if (mddev->barrier == POST_REQUEST_BARRIER) {
+			/* This was a post-request barrier */
+			mddev->barrier = NULL;
+			wake_up(&mddev->sb_wait);
+		} else
+			/* The pre-request barrier has finished */
+			schedule_work(&mddev->barrier_work);
+	}
+	bio_put(bio);
+}
+
+static void submit_barriers(mddev_t *mddev)
+{
+	mdk_rdev_t *rdev;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
+		if (rdev->raid_disk >= 0 &&
+		    !test_bit(Faulty, &rdev->flags)) {
+			/* Take two references, one is dropped
+			 * when request finishes, one after
+			 * we reclaim rcu_read_lock
+			 */
+			struct bio *bi;
+			atomic_inc(&rdev->nr_pending);
+			atomic_inc(&rdev->nr_pending);
+			rcu_read_unlock();
+			bi = bio_alloc(GFP_KERNEL, 0);
+			bi->bi_end_io = md_end_barrier;
+			bi->bi_private = rdev;
+			bi->bi_bdev = rdev->bdev;
+			atomic_inc(&mddev->flush_pending);
+			submit_bio(WRITE_BARRIER, bi);
+			rcu_read_lock();
+			rdev_dec_pending(rdev, mddev);
+		}
+	rcu_read_unlock();
+}
+
+static void md_submit_barrier(struct work_struct *ws)
+{
+	mddev_t *mddev = container_of(ws, mddev_t, barrier_work);
+	struct bio *bio = mddev->barrier;
+
+	atomic_set(&mddev->flush_pending, 1);
+
+	if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags))
+		bio_endio(bio, -EOPNOTSUPP);
+	else if (bio->bi_size == 0)
+		/* an empty barrier - all done */
+		bio_endio(bio, 0);
+	else {
+		bio->bi_rw &= ~(1<<BIO_RW_BARRIER);
+		if (mddev->pers->make_request(mddev->queue, bio))
+			generic_make_request(bio);
+		mddev->barrier = POST_REQUEST_BARRIER;
+		submit_barriers(mddev);
+	}
+	if (atomic_dec_and_test(&mddev->flush_pending)) {
+		mddev->barrier = NULL;
+		wake_up(&mddev->sb_wait);
+	}
+}
+
+void md_barrier_request(mddev_t *mddev, struct bio *bio)
+{
+	spin_lock_irq(&mddev->write_lock);
+	wait_event_lock_irq(mddev->sb_wait,
+			    !mddev->barrier,
+			    mddev->write_lock, /*nothing*/);
+	mddev->barrier = bio;
+	spin_unlock_irq(&mddev->write_lock);
+
+	atomic_set(&mddev->flush_pending, 1);
+	INIT_WORK(&mddev->barrier_work, md_submit_barrier);
+
+	submit_barriers(mddev);
+
+	if (atomic_dec_and_test(&mddev->flush_pending))
+		schedule_work(&mddev->barrier_work);
+}
+EXPORT_SYMBOL(md_barrier_request);
 
 static inline mddev_t *mddev_get(mddev_t *mddev)
 {
@@ -282,7 +386,9 @@ static void mddev_put(mddev_t *mddev)
 	if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
 		return;
 	if (!mddev->raid_disks && list_empty(&mddev->disks) &&
-	    !mddev->hold_active) {
+	    mddev->ctime == 0 && !mddev->hold_active) {
+		/* Array is not configured at all, and not held active,
+		 * so destroy it */
 		list_del(&mddev->all_mddevs);
 		if (mddev->gendisk) {
 			/* we did a probe so need to clean up.
@@ -367,6 +473,7 @@ static mddev_t * mddev_find(dev_t unit)
 
 	mutex_init(&new->open_mutex);
 	mutex_init(&new->reconfig_mutex);
+	mutex_init(&new->bitmap_info.mutex);
 	INIT_LIST_HEAD(&new->disks);
 	INIT_LIST_HEAD(&new->all_mddevs);
 	init_timer(&new->safemode_timer);
@@ -374,6 +481,7 @@ static mddev_t * mddev_find(dev_t unit)
 	atomic_set(&new->openers, 0);
 	atomic_set(&new->active_io, 0);
 	spin_lock_init(&new->write_lock);
+	atomic_set(&new->flush_pending, 0);
 	init_waitqueue_head(&new->sb_wait);
 	init_waitqueue_head(&new->recovery_wait);
 	new->reshape_position = MaxSector;
@@ -752,7 +860,7 @@ struct super_type  {
  */
 int md_check_no_bitmap(mddev_t *mddev)
 {
-	if (!mddev->bitmap_file && !mddev->bitmap_offset)
+	if (!mddev->bitmap_info.file && !mddev->bitmap_info.offset)
 		return 0;
 	printk(KERN_ERR "%s: bitmaps are not supported for %s\n",
 		mdname(mddev), mddev->pers->name);
@@ -880,8 +988,8 @@ static int super_90_validate(mddev_t *md
 		mddev->raid_disks = sb->raid_disks;
 		mddev->dev_sectors = sb->size * 2;
 		mddev->events = ev1;
-		mddev->bitmap_offset = 0;
-		mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
+		mddev->bitmap_info.offset = 0;
+		mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
 
 		if (mddev->minor_version >= 91) {
 			mddev->reshape_position = sb->reshape_position;
@@ -915,8 +1023,9 @@ static int super_90_validate(mddev_t *md
 		mddev->max_disks = MD_SB_DISKS;
 
 		if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
-		    mddev->bitmap_file == NULL)
-			mddev->bitmap_offset = mddev->default_bitmap_offset;
+		    mddev->bitmap_info.file == NULL)
+			mddev->bitmap_info.offset =
+				mddev->bitmap_info.default_offset;
 
 	} else if (mddev->pers == NULL) {
 		/* Insist on good event counter while assembling */
@@ -1033,7 +1142,7 @@ static void super_90_sync(mddev_t *mddev
 	sb->layout = mddev->layout;
 	sb->chunk_size = mddev->chunk_sectors << 9;
 
-	if (mddev->bitmap && mddev->bitmap_file == NULL)
+	if (mddev->bitmap && mddev->bitmap_info.file == NULL)
 		sb->state |= (1<<MD_SB_BITMAP_PRESENT);
 
 	sb->disks[0].state = (1<<MD_DISK_REMOVED);
@@ -1111,7 +1220,7 @@ super_90_rdev_size_change(mdk_rdev_t *rd
 {
 	if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
 		return 0; /* component must fit device */
-	if (rdev->mddev->bitmap_offset)
+	if (rdev->mddev->bitmap_info.offset)
 		return 0; /* can't move bitmap */
 	rdev->sb_start = calc_dev_sboffset(rdev->bdev);
 	if (!num_sectors || num_sectors > rdev->sb_start)
@@ -1290,8 +1399,8 @@ static int super_1_validate(mddev_t *mdd
 		mddev->raid_disks = le32_to_cpu(sb->raid_disks);
 		mddev->dev_sectors = le64_to_cpu(sb->size);
 		mddev->events = ev1;
-		mddev->bitmap_offset = 0;
-		mddev->default_bitmap_offset = 1024 >> 9;
+		mddev->bitmap_info.offset = 0;
+		mddev->bitmap_info.default_offset = 1024 >> 9;
 		
 		mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
 		memcpy(mddev->uuid, sb->set_uuid, 16);
@@ -1299,8 +1408,9 @@ static int super_1_validate(mddev_t *mdd
 		mddev->max_disks =  (4096-256)/2;
 
 		if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) &&
-		    mddev->bitmap_file == NULL )
-			mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset);
+		    mddev->bitmap_info.file == NULL )
+			mddev->bitmap_info.offset =
+				(__s32)le32_to_cpu(sb->bitmap_offset);
 
 		if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) {
 			mddev->reshape_position = le64_to_cpu(sb->reshape_position);
@@ -1394,19 +1504,17 @@ static void super_1_sync(mddev_t *mddev,
 	sb->level = cpu_to_le32(mddev->level);
 	sb->layout = cpu_to_le32(mddev->layout);
 
-	if (mddev->bitmap && mddev->bitmap_file == NULL) {
-		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
+	if (mddev->bitmap && mddev->bitmap_info.file == NULL) {
+		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset);
 		sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
 	}
 
 	if (rdev->raid_disk >= 0 &&
 	    !test_bit(In_sync, &rdev->flags)) {
-		if (rdev->recovery_offset > 0) {
-			sb->feature_map |=
-				cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
-			sb->recovery_offset =
-				cpu_to_le64(rdev->recovery_offset);
-		}
+		sb->feature_map |=
+			cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+		sb->recovery_offset =
+			cpu_to_le64(rdev->recovery_offset);
 	}
 
 	if (mddev->reshape_position != MaxSector) {
@@ -1440,7 +1548,7 @@ static void super_1_sync(mddev_t *mddev,
 			sb->dev_roles[i] = cpu_to_le16(0xfffe);
 		else if (test_bit(In_sync, &rdev2->flags))
 			sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
-		else if (rdev2->raid_disk >= 0 && rdev2->recovery_offset > 0)
+		else if (rdev2->raid_disk >= 0)
 			sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
 		else
 			sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1462,7 +1570,7 @@ super_1_rdev_size_change(mdk_rdev_t *rde
 		max_sectors -= rdev->data_offset;
 		if (!num_sectors || num_sectors > max_sectors)
 			num_sectors = max_sectors;
-	} else if (rdev->mddev->bitmap_offset) {
+	} else if (rdev->mddev->bitmap_info.offset) {
 		/* minor version 0 with bitmap we can't move */
 		return 0;
 	} else {
@@ -1830,15 +1938,11 @@ static void print_sb_1(struct mdp_superb
 
 	uuid = sb->set_uuid;
 	printk(KERN_INFO
-	       "md:  SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x"
-	       ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n"
+	       "md:  SB: (V:%u) (F:0x%08x) Array-ID:<%pU>\n"
 	       "md:    Name: \"%s\" CT:%llu\n",
 		le32_to_cpu(sb->major_version),
 		le32_to_cpu(sb->feature_map),
-		uuid[0], uuid[1], uuid[2], uuid[3],
-		uuid[4], uuid[5], uuid[6], uuid[7],
-		uuid[8], uuid[9], uuid[10], uuid[11],
-		uuid[12], uuid[13], uuid[14], uuid[15],
+		uuid,
 		sb->set_name,
 		(unsigned long long)le64_to_cpu(sb->ctime)
 		       & MD_SUPERBLOCK_1_TIME_SEC_MASK);
@@ -1847,8 +1951,7 @@ static void print_sb_1(struct mdp_superb
 	printk(KERN_INFO
 	       "md:       L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu"
 			" RO:%llu\n"
-	       "md:     Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x"
-	                ":%02x%02x%02x%02x%02x%02x\n"
+	       "md:     Dev:%08x UUID: %pU\n"
 	       "md:       (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n"
 	       "md:         (MaxDev:%u) \n",
 		le32_to_cpu(sb->level),
@@ -1861,10 +1964,7 @@ static void print_sb_1(struct mdp_superb
 		(unsigned long long)le64_to_cpu(sb->super_offset),
 		(unsigned long long)le64_to_cpu(sb->recovery_offset),
 		le32_to_cpu(sb->dev_number),
-		uuid[0], uuid[1], uuid[2], uuid[3],
-		uuid[4], uuid[5], uuid[6], uuid[7],
-		uuid[8], uuid[9], uuid[10], uuid[11],
-		uuid[12], uuid[13], uuid[14], uuid[15],
+		uuid,
 		sb->devflags,
 		(unsigned long long)le64_to_cpu(sb->utime) & MD_SUPERBLOCK_1_TIME_SEC_MASK,
 		(unsigned long long)le64_to_cpu(sb->events),
@@ -2446,12 +2546,49 @@ rdev_size_store(mdk_rdev_t *rdev, const
 static struct rdev_sysfs_entry rdev_size =
 __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
 
+
+static ssize_t recovery_start_show(mdk_rdev_t *rdev, char *page)
+{
+	unsigned long long recovery_start = rdev->recovery_offset;
+
+	if (test_bit(In_sync, &rdev->flags) ||
+	    recovery_start == MaxSector)
+		return sprintf(page, "none\n");
+
+	return sprintf(page, "%llu\n", recovery_start);
+}
+
+static ssize_t recovery_start_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+{
+	unsigned long long recovery_start;
+
+	if (cmd_match(buf, "none"))
+		recovery_start = MaxSector;
+	else if (strict_strtoull(buf, 10, &recovery_start))
+		return -EINVAL;
+
+	if (rdev->mddev->pers &&
+	    rdev->raid_disk >= 0)
+		return -EBUSY;
+
+	rdev->recovery_offset = recovery_start;
+	if (recovery_start == MaxSector)
+		set_bit(In_sync, &rdev->flags);
+	else
+		clear_bit(In_sync, &rdev->flags);
+	return len;
+}
+
+static struct rdev_sysfs_entry rdev_recovery_start =
+__ATTR(recovery_start, S_IRUGO|S_IWUSR, recovery_start_show, recovery_start_store);
+
 static struct attribute *rdev_default_attrs[] = {
 	&rdev_state.attr,
 	&rdev_errors.attr,
 	&rdev_slot.attr,
 	&rdev_offset.attr,
 	&rdev_size.attr,
+	&rdev_recovery_start.attr,
 	NULL,
 };
 static ssize_t
@@ -2553,6 +2690,8 @@ static mdk_rdev_t *md_import_device(dev_
 	rdev->flags = 0;
 	rdev->data_offset = 0;
 	rdev->sb_events = 0;
+	rdev->last_read_error.tv_sec  = 0;
+	rdev->last_read_error.tv_nsec = 0;
 	atomic_set(&rdev->nr_pending, 0);
 	atomic_set(&rdev->read_errors, 0);
 	atomic_set(&rdev->corrected_errors, 0);
@@ -2663,6 +2802,47 @@ static void analyze_sbs(mddev_t * mddev)
 	}
 }
 
+/* Read a fixed-point number.
+ * Numbers in sysfs attributes should be in "standard" units where
+ * possible, so time should be in seconds.
+ * However we internally use a a much smaller unit such as 
+ * milliseconds or jiffies.
+ * This function takes a decimal number with a possible fractional
+ * component, and produces an integer which is the result of
+ * multiplying that number by 10^'scale'.
+ * all without any floating-point arithmetic.
+ */
+int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale)
+{
+	unsigned long result = 0;
+	long decimals = -1;
+	while (isdigit(*cp) || (*cp == '.' && decimals < 0)) {
+		if (*cp == '.')
+			decimals = 0;
+		else if (decimals < scale) {
+			unsigned int value;
+			value = *cp - '0';
+			result = result * 10 + value;
+			if (decimals >= 0)
+				decimals++;
+		}
+		cp++;
+	}
+	if (*cp == '\n')
+		cp++;
+	if (*cp)
+		return -EINVAL;
+	if (decimals < 0)
+		decimals = 0;
+	while (decimals < scale) {
+		result *= 10;
+		decimals ++;
+	}
+	*res = result;
+	return 0;
+}
+
+
 static void md_safemode_timeout(unsigned long data);
 
 static ssize_t
@@ -2674,31 +2854,10 @@ safe_delay_show(mddev_t *mddev, char *pa
 static ssize_t
 safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
 {
-	int scale=1;
-	int dot=0;
-	int i;
 	unsigned long msec;
-	char buf[30];
 
-	/* remove a period, and count digits after it */
-	if (len >= sizeof(buf))
-		return -EINVAL;
-	strlcpy(buf, cbuf, sizeof(buf));
-	for (i=0; i<len; i++) {
-		if (dot) {
-			if (isdigit(buf[i])) {
-				buf[i-1] = buf[i];
-				scale *= 10;
-			}
-			buf[i] = 0;
-		} else if (buf[i] == '.') {
-			dot=1;
-			buf[i] = 0;
-		}
-	}
-	if (strict_strtoul(buf, 10, &msec) < 0)
+	if (strict_strtoul_scaled(cbuf, &msec, 3) < 0)
 		return -EINVAL;
-	msec = (msec * 1000) / scale;
 	if (msec == 0)
 		mddev->safemode_delay = 0;
 	else {
@@ -2974,7 +3133,9 @@ resync_start_store(mddev_t *mddev, const
 
 	if (mddev->pers)
 		return -EBUSY;
-	if (!*buf || (*e && *e != '\n'))
+	if (cmd_match(buf, "none"))
+		n = MaxSector;
+	else if (!*buf || (*e && *e != '\n'))
 		return -EINVAL;
 
 	mddev->recovery_cp = n;
@@ -3170,6 +3331,29 @@ static struct md_sysfs_entry md_array_st
 __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
 
 static ssize_t
+max_corrected_read_errors_show(mddev_t *mddev, char *page) {
+	return sprintf(page, "%d\n",
+		       atomic_read(&mddev->max_corr_read_errors));
+}
+
+static ssize_t
+max_corrected_read_errors_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	char *e;
+	unsigned long n = simple_strtoul(buf, &e, 10);
+
+	if (*buf && (*e == 0 || *e == '\n')) {
+		atomic_set(&mddev->max_corr_read_errors, n);
+		return len;
+	}
+	return -EINVAL;
+}
+
+static struct md_sysfs_entry max_corr_read_errors =
+__ATTR(max_read_errors, S_IRUGO|S_IWUSR, max_corrected_read_errors_show,
+	max_corrected_read_errors_store);
+
+static ssize_t
 null_show(mddev_t *mddev, char *page)
 {
 	return -EINVAL;
@@ -3250,8 +3434,7 @@ bitmap_store(mddev_t *mddev, const char
 		}
 		if (*end && !isspace(*end)) break;
 		bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
-		buf = end;
-		while (isspace(*buf)) buf++;
+		buf = skip_spaces(end);
 	}
 	bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
 out:
@@ -3794,6 +3977,7 @@ static struct attribute *md_default_attr
 	&md_array_state.attr,
 	&md_reshape_position.attr,
 	&md_array_size.attr,
+	&max_corr_read_errors.attr,
 	NULL,
 };
 
@@ -3891,13 +4075,16 @@ static void mddev_delayed_delete(struct
 {
 	mddev_t *mddev = container_of(ws, mddev_t, del_work);
 
-	if (mddev->private == &md_redundancy_group) {
+	if (mddev->private) {
 		sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
+		if (mddev->private != (void*)1)
+			sysfs_remove_group(&mddev->kobj, mddev->private);
 		if (mddev->sysfs_action)
 			sysfs_put(mddev->sysfs_action);
 		mddev->sysfs_action = NULL;
 		mddev->private = NULL;
 	}
+	sysfs_remove_group(&mddev->kobj, &md_bitmap_group);
 	kobject_del(&mddev->kobj);
 	kobject_put(&mddev->kobj);
 }
@@ -3989,6 +4176,8 @@ static int md_alloc(dev_t dev, char *nam
 		       disk->disk_name);
 		error = 0;
 	}
+	if (sysfs_create_group(&mddev->kobj, &md_bitmap_group))
+		printk(KERN_DEBUG "pointless warning\n");
  abort:
 	mutex_unlock(&disks_mutex);
 	if (!error) {
@@ -4100,10 +4289,7 @@ static int do_md_run(mddev_t * mddev)
 		sysfs_notify_dirent(rdev->sysfs_state);
 	}
 
-	md_probe(mddev->unit, NULL, NULL);
 	disk = mddev->gendisk;
-	if (!disk)
-		return -ENOMEM;
 
 	spin_lock(&pers_lock);
 	pers = find_pers(mddev->level, mddev->clevel);
@@ -4170,7 +4356,7 @@ static int do_md_run(mddev_t * mddev)
 	mddev->barriers_work = 1;
 	mddev->ok_start_degraded = start_dirty_degraded;
 
-	if (start_readonly)
+	if (start_readonly && mddev->ro == 0)
 		mddev->ro = 2; /* read-only, but switch on first write */
 
 	err = mddev->pers->run(mddev);
@@ -4210,6 +4396,8 @@ static int do_md_run(mddev_t * mddev)
 		mddev->ro = 0;
 
  	atomic_set(&mddev->writes_pending,0);
+	atomic_set(&mddev->max_corr_read_errors,
+		   MD_DEFAULT_MAX_CORRECTED_READ_ERRORS);
 	mddev->safemode = 0;
 	mddev->safemode_timer.function = md_safemode_timeout;
 	mddev->safemode_timer.data = (unsigned long) mddev;
@@ -4232,33 +4420,6 @@ static int do_md_run(mddev_t * mddev)
 
 	set_capacity(disk, mddev->array_sectors);
 
-	/* If there is a partially-recovered drive we need to
-	 * start recovery here.  If we leave it to md_check_recovery,
-	 * it will remove the drives and not do the right thing
-	 */
-	if (mddev->degraded && !mddev->sync_thread) {
-		int spares = 0;
-		list_for_each_entry(rdev, &mddev->disks, same_set)
-			if (rdev->raid_disk >= 0 &&
-			    !test_bit(In_sync, &rdev->flags) &&
-			    !test_bit(Faulty, &rdev->flags))
-				/* complete an interrupted recovery */
-				spares++;
-		if (spares && mddev->pers->sync_request) {
-			mddev->recovery = 0;
-			set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
-			mddev->sync_thread = md_register_thread(md_do_sync,
-								mddev,
-								"resync");
-			if (!mddev->sync_thread) {
-				printk(KERN_ERR "%s: could not start resync"
-				       " thread...\n",
-				       mdname(mddev));
-				/* leave the spares where they are, it shouldn't hurt */
-				mddev->recovery = 0;
-			}
-		}
-	}
 	md_wakeup_thread(mddev->thread);
 	md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 
@@ -4314,7 +4475,7 @@ static int deny_bitmap_write_access(stru
 	return 0;
 }
 
-static void restore_bitmap_write_access(struct file *file)
+void restore_bitmap_write_access(struct file *file)
 {
 	struct inode *inode = file->f_mapping->host;
 
@@ -4368,8 +4529,8 @@ static int do_md_stop(mddev_t * mddev, i
 			mddev->queue->unplug_fn = NULL;
 			mddev->queue->backing_dev_info.congested_fn = NULL;
 			module_put(mddev->pers->owner);
-			if (mddev->pers->sync_request)
-				mddev->private = &md_redundancy_group;
+			if (mddev->pers->sync_request && mddev->private == NULL)
+				mddev->private = (void*)1;
 			mddev->pers = NULL;
 			/* tell userspace to handle 'inactive' */
 			sysfs_notify_dirent(mddev->sysfs_state);
@@ -4409,15 +4570,12 @@ out:
 		printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
 
 		bitmap_destroy(mddev);
-		if (mddev->bitmap_file) {
-			restore_bitmap_write_access(mddev->bitmap_file);
-			fput(mddev->bitmap_file);
-			mddev->bitmap_file = NULL;
+		if (mddev->bitmap_info.file) {
+			restore_bitmap_write_access(mddev->bitmap_info.file);
+			fput(mddev->bitmap_info.file);
+			mddev->bitmap_info.file = NULL;
 		}
-		mddev->bitmap_offset = 0;
-
-		/* make sure all md_delayed_delete calls have finished */
-		flush_scheduled_work();
+		mddev->bitmap_info.offset = 0;
 
 		export_array(mddev);
 
@@ -4455,6 +4613,11 @@ out:
 		mddev->degraded = 0;
 		mddev->barriers_work = 0;
 		mddev->safemode = 0;
+		mddev->bitmap_info.offset = 0;
+		mddev->bitmap_info.default_offset = 0;
+		mddev->bitmap_info.chunksize = 0;
+		mddev->bitmap_info.daemon_sleep = 0;
+		mddev->bitmap_info.max_write_behind = 0;
 		kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
 		if (mddev->hold_active == UNTIL_STOP)
 			mddev->hold_active = 0;
@@ -4640,7 +4803,7 @@ static int get_array_info(mddev_t * mdde
 	info.state         = 0;
 	if (mddev->in_sync)
 		info.state = (1<<MD_SB_CLEAN);
-	if (mddev->bitmap && mddev->bitmap_offset)
+	if (mddev->bitmap && mddev->bitmap_info.offset)
 		info.state = (1<<MD_SB_BITMAP_PRESENT);
 	info.active_disks  = insync;
 	info.working_disks = working;
@@ -4998,23 +5161,23 @@ static int set_bitmap_file(mddev_t *mdde
 	if (fd >= 0) {
 		if (mddev->bitmap)
 			return -EEXIST; /* cannot add when bitmap is present */
-		mddev->bitmap_file = fget(fd);
+		mddev->bitmap_info.file = fget(fd);
 
-		if (mddev->bitmap_file == NULL) {
+		if (mddev->bitmap_info.file == NULL) {
 			printk(KERN_ERR "%s: error: failed to get bitmap file\n",
 			       mdname(mddev));
 			return -EBADF;
 		}
 
-		err = deny_bitmap_write_access(mddev->bitmap_file);
+		err = deny_bitmap_write_access(mddev->bitmap_info.file);
 		if (err) {
 			printk(KERN_ERR "%s: error: bitmap file is already in use\n",
 			       mdname(mddev));
-			fput(mddev->bitmap_file);
-			mddev->bitmap_file = NULL;
+			fput(mddev->bitmap_info.file);
+			mddev->bitmap_info.file = NULL;
 			return err;
 		}
-		mddev->bitmap_offset = 0; /* file overrides offset */
+		mddev->bitmap_info.offset = 0; /* file overrides offset */
 	} else if (mddev->bitmap == NULL)
 		return -ENOENT; /* cannot remove what isn't there */
 	err = 0;
@@ -5029,11 +5192,11 @@ static int set_bitmap_file(mddev_t *mdde
 		mddev->pers->quiesce(mddev, 0);
 	}
 	if (fd < 0) {
-		if (mddev->bitmap_file) {
-			restore_bitmap_write_access(mddev->bitmap_file);
-			fput(mddev->bitmap_file);
+		if (mddev->bitmap_info.file) {
+			restore_bitmap_write_access(mddev->bitmap_info.file);
+			fput(mddev->bitmap_info.file);
 		}
-		mddev->bitmap_file = NULL;
+		mddev->bitmap_info.file = NULL;
 	}
 
 	return err;
@@ -5070,6 +5233,10 @@ static int set_array_info(mddev_t * mdde
 		mddev->minor_version = info->minor_version;
 		mddev->patch_version = info->patch_version;
 		mddev->persistent = !info->not_persistent;
+		/* ensure mddev_put doesn't delete this now that there
+		 * is some minimal configuration.
+		 */
+		mddev->ctime         = get_seconds();
 		return 0;
 	}
 	mddev->major_version = MD_MAJOR_VERSION;
@@ -5100,8 +5267,8 @@ static int set_array_info(mddev_t * mdde
 		mddev->flags         = 0;
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
-	mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
-	mddev->bitmap_offset = 0;
+	mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
+	mddev->bitmap_info.offset = 0;
 
 	mddev->reshape_position = MaxSector;
 
@@ -5201,7 +5368,7 @@ static int update_array_info(mddev_t *md
 	int state = 0;
 
 	/* calculate expected state,ignoring low bits */
-	if (mddev->bitmap && mddev->bitmap_offset)
+	if (mddev->bitmap && mddev->bitmap_info.offset)
 		state |= (1 << MD_SB_BITMAP_PRESENT);
 
 	if (mddev->major_version != info->major_version ||
@@ -5260,9 +5427,10 @@ static int update_array_info(mddev_t *md
 			/* add the bitmap */
 			if (mddev->bitmap)
 				return -EEXIST;
-			if (mddev->default_bitmap_offset == 0)
+			if (mddev->bitmap_info.default_offset == 0)
 				return -EINVAL;
-			mddev->bitmap_offset = mddev->default_bitmap_offset;
+			mddev->bitmap_info.offset =
+				mddev->bitmap_info.default_offset;
 			mddev->pers->quiesce(mddev, 1);
 			rv = bitmap_create(mddev);
 			if (rv)
@@ -5277,7 +5445,7 @@ static int update_array_info(mddev_t *md
 			mddev->pers->quiesce(mddev, 1);
 			bitmap_destroy(mddev);
 			mddev->pers->quiesce(mddev, 0);
-			mddev->bitmap_offset = 0;
+			mddev->bitmap_info.offset = 0;
 		}
 	}
 	md_update_sb(mddev, 1);
@@ -5528,6 +5696,25 @@ done:
 abort:
 	return err;
 }
+#ifdef CONFIG_COMPAT
+static int md_compat_ioctl(struct block_device *bdev, fmode_t mode,
+		    unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case HOT_REMOVE_DISK:
+	case HOT_ADD_DISK:
+	case SET_DISK_FAULTY:
+	case SET_BITMAP_FILE:
+		/* These take in integer arg, do not convert */
+		break;
+	default:
+		arg = (unsigned long)compat_ptr(arg);
+		break;
+	}
+
+	return md_ioctl(bdev, mode, cmd, arg);
+}
+#endif /* CONFIG_COMPAT */
 
 static int md_open(struct block_device *bdev, fmode_t mode)
 {
@@ -5593,6 +5780,9 @@ static const struct block_device_operati
 	.open		= md_open,
 	.release	= md_release,
 	.ioctl		= md_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= md_compat_ioctl,
+#endif
 	.getgeo		= md_getgeo,
 	.media_changed	= md_media_changed,
 	.revalidate_disk= md_revalidate,
@@ -5986,14 +6176,14 @@ static int md_seq_show(struct seq_file *
 			unsigned long chunk_kb;
 			unsigned long flags;
 			spin_lock_irqsave(&bitmap->lock, flags);
-			chunk_kb = bitmap->chunksize >> 10;
+			chunk_kb = mddev->bitmap_info.chunksize >> 10;
 			seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], "
 				"%lu%s chunk",
 				bitmap->pages - bitmap->missing_pages,
 				bitmap->pages,
 				(bitmap->pages - bitmap->missing_pages)
 					<< (PAGE_SHIFT - 10),
-				chunk_kb ? chunk_kb : bitmap->chunksize,
+				chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize,
 				chunk_kb ? "KB" : "B");
 			if (bitmap->file) {
 				seq_printf(seq, ", file: ");
@@ -6279,10 +6469,11 @@ void md_do_sync(mddev_t *mddev)
 		mddev->curr_resync = 2;
 
 	try_again:
-		if (kthread_should_stop()) {
+		if (kthread_should_stop())
 			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+
+		if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
 			goto skip;
-		}
 		for_each_mddev(mddev2, tmp) {
 			if (mddev2 == mddev)
 				continue;
@@ -6342,12 +6533,14 @@ void md_do_sync(mddev_t *mddev)
 		/* recovery follows the physical size of devices */
 		max_sectors = mddev->dev_sectors;
 		j = MaxSector;
-		list_for_each_entry(rdev, &mddev->disks, same_set)
+		rcu_read_lock();
+		list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
 			if (rdev->raid_disk >= 0 &&
 			    !test_bit(Faulty, &rdev->flags) &&
 			    !test_bit(In_sync, &rdev->flags) &&
 			    rdev->recovery_offset < j)
 				j = rdev->recovery_offset;
+		rcu_read_unlock();
 	}
 
 	printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
@@ -6384,6 +6577,7 @@ void md_do_sync(mddev_t *mddev)
 		       desc, mdname(mddev));
 		mddev->curr_resync = j;
 	}
+	mddev->curr_resync_completed = mddev->curr_resync;
 
 	while (j < max_sectors) {
 		sector_t sectors;
@@ -6516,22 +6710,29 @@ void md_do_sync(mddev_t *mddev)
 		} else {
 			if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
 				mddev->curr_resync = MaxSector;
-			list_for_each_entry(rdev, &mddev->disks, same_set)
+			rcu_read_lock();
+			list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
 				if (rdev->raid_disk >= 0 &&
 				    !test_bit(Faulty, &rdev->flags) &&
 				    !test_bit(In_sync, &rdev->flags) &&
 				    rdev->recovery_offset < mddev->curr_resync)
 					rdev->recovery_offset = mddev->curr_resync;
+			rcu_read_unlock();
 		}
 	}
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
  skip:
+	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+		/* We completed so min/max setting can be forgotten if used. */
+		if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+			mddev->resync_min = 0;
+		mddev->resync_max = MaxSector;
+	} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+		mddev->resync_min = mddev->curr_resync_completed;
 	mddev->curr_resync = 0;
-	mddev->curr_resync_completed = 0;
 	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
-		/* We completed so max setting can be forgotten. */
-		mddev->resync_max = MaxSector;
+		mddev->curr_resync_completed = 0;
 	sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	wake_up(&resync_wait);
 	set_bit(MD_RECOVERY_DONE, &mddev->recovery);
@@ -6594,6 +6795,7 @@ static int remove_and_add_spares(mddev_t
 						       nm, mdname(mddev));
 					spares++;
 					md_new_event(mddev);
+					set_bit(MD_CHANGE_DEVS, &mddev->flags);
 				} else
 					break;
 			}
@@ -6629,7 +6831,7 @@ void md_check_recovery(mddev_t *mddev)
 
 
 	if (mddev->bitmap)
-		bitmap_daemon_work(mddev->bitmap);
+		bitmap_daemon_work(mddev);
 
 	if (mddev->ro)
 		return;
@@ -6999,5 +7201,6 @@ EXPORT_SYMBOL(md_unregister_thread);
 EXPORT_SYMBOL(md_wakeup_thread);
 EXPORT_SYMBOL(md_check_recovery);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MD RAID framework");
 MODULE_ALIAS("md");
 MODULE_ALIAS_BLOCKDEV_MAJOR(MD_MAJOR);
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/md.h linux-libre-2.6.33-gnu1/drivers/md/md.h
--- linux-libre-2.6.32-gnu1/drivers/md/md.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/md.h	2010-02-24 13:52:17.000000000 -0500
@@ -97,6 +97,9 @@ struct mdk_rdev_s
 	atomic_t	read_errors;	/* number of consecutive read errors that
 					 * we have tried to ignore.
 					 */
+	struct timespec last_read_error;	/* monotonic time since our
+						 * last read error
+						 */
 	atomic_t	corrected_errors; /* number of corrected read errors,
 					   * for reporting to userspace and storing
 					   * in superblock.
@@ -280,17 +283,38 @@ struct mddev_s
 	unsigned int                    max_write_behind; /* 0 = sync */
 
 	struct bitmap                   *bitmap; /* the bitmap for the device */
-	struct file			*bitmap_file; /* the bitmap file */
-	long				bitmap_offset; /* offset from superblock of
-							* start of bitmap. May be
-							* negative, but not '0'
-							*/
-	long				default_bitmap_offset; /* this is the offset to use when
-								* hot-adding a bitmap.  It should
-								* eventually be settable by sysfs.
-								*/
+	struct {
+		struct file		*file; /* the bitmap file */
+		loff_t			offset; /* offset from superblock of
+						 * start of bitmap. May be
+						 * negative, but not '0'
+						 * For external metadata, offset
+						 * from start of device. 
+						 */
+		loff_t			default_offset; /* this is the offset to use when
+							 * hot-adding a bitmap.  It should
+							 * eventually be settable by sysfs.
+							 */
+		struct mutex		mutex;
+		unsigned long		chunksize;
+		unsigned long		daemon_sleep; /* how many seconds between updates? */
+		unsigned long		max_write_behind; /* write-behind mode */
+		int			external;
+	} bitmap_info;
 
+	atomic_t 			max_corr_read_errors; /* max read retries */
 	struct list_head		all_mddevs;
+
+	/* Generic barrier handling.
+	 * If there is a pending barrier request, all other
+	 * writes are blocked while the devices are flushed.
+	 * The last to finish a flush schedules a worker to
+	 * submit the barrier request (without the barrier flag),
+	 * then submit more flush requests.
+	 */
+	struct bio *barrier;
+	atomic_t flush_pending;
+	struct work_struct barrier_work;
 };
 
 
@@ -353,7 +377,7 @@ struct md_sysfs_entry {
 	ssize_t (*show)(mddev_t *, char *);
 	ssize_t (*store)(mddev_t *, const char *, size_t);
 };
-
+extern struct attribute_group md_bitmap_group;
 
 static inline char * mdname (mddev_t * mddev)
 {
@@ -431,6 +455,7 @@ extern void md_done_sync(mddev_t *mddev,
 extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
 
 extern int mddev_congested(mddev_t *mddev, int bits);
+extern void md_barrier_request(mddev_t *mddev, struct bio *bio);
 extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
 			   sector_t sector, int size, struct page *page);
 extern void md_super_wait(mddev_t *mddev);
@@ -443,6 +468,8 @@ extern void md_wait_for_blocked_rdev(mdk
 extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
 extern int md_check_no_bitmap(mddev_t *mddev);
 extern int md_integrity_register(mddev_t *mddev);
-void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
+extern void restore_bitmap_write_access(struct file *file);
 
 #endif /* _MD_MD_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/multipath.c linux-libre-2.6.33-gnu1/drivers/md/multipath.c
--- linux-libre-2.6.32-gnu1/drivers/md/multipath.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/multipath.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,7 @@ static int multipath_make_request (struc
 	int cpu;
 
 	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
-		bio_endio(bio, -EOPNOTSUPP);
+		md_barrier_request(mddev, bio);
 		return 0;
 	}
 
@@ -581,6 +581,7 @@ static void __exit multipath_exit (void)
 module_init(multipath_init);
 module_exit(multipath_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("simple multi-path personality for MD");
 MODULE_ALIAS("md-personality-7"); /* MULTIPATH */
 MODULE_ALIAS("md-multipath");
 MODULE_ALIAS("md-level--4");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid0.c linux-libre-2.6.33-gnu1/drivers/md/raid0.c
--- linux-libre-2.6.32-gnu1/drivers/md/raid0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid0.c	2010-02-24 13:52:17.000000000 -0500
@@ -453,7 +453,7 @@ static int raid0_make_request(struct req
 	int cpu;
 
 	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
-		bio_endio(bio, -EOPNOTSUPP);
+		md_barrier_request(mddev, bio);
 		return 0;
 	}
 
@@ -567,6 +567,7 @@ static void raid0_exit (void)
 module_init(raid0_init);
 module_exit(raid0_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RAID0 (striping) personality for MD");
 MODULE_ALIAS("md-personality-2"); /* RAID0 */
 MODULE_ALIAS("md-raid0");
 MODULE_ALIAS("md-level-0");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid10.c linux-libre-2.6.33-gnu1/drivers/md/raid10.c
--- linux-libre-2.6.32-gnu1/drivers/md/raid10.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid10.c	2010-02-24 13:52:17.000000000 -0500
@@ -804,7 +804,7 @@ static int make_request(struct request_q
 	mdk_rdev_t *blocked_rdev;
 
 	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
-		bio_endio(bio, -EOPNOTSUPP);
+		md_barrier_request(mddev, bio);
 		return 0;
 	}
 
@@ -1432,6 +1432,43 @@ static void recovery_request_write(mddev
 
 
 /*
+ * Used by fix_read_error() to decay the per rdev read_errors.
+ * We halve the read error count for every hour that has elapsed
+ * since the last recorded read error.
+ *
+ */
+static void check_decay_read_errors(mddev_t *mddev, mdk_rdev_t *rdev)
+{
+	struct timespec cur_time_mon;
+	unsigned long hours_since_last;
+	unsigned int read_errors = atomic_read(&rdev->read_errors);
+
+	ktime_get_ts(&cur_time_mon);
+
+	if (rdev->last_read_error.tv_sec == 0 &&
+	    rdev->last_read_error.tv_nsec == 0) {
+		/* first time we've seen a read error */
+		rdev->last_read_error = cur_time_mon;
+		return;
+	}
+
+	hours_since_last = (cur_time_mon.tv_sec -
+			    rdev->last_read_error.tv_sec) / 3600;
+
+	rdev->last_read_error = cur_time_mon;
+
+	/*
+	 * if hours_since_last is > the number of bits in read_errors
+	 * just set read errors to 0. We do this to avoid
+	 * overflowing the shift of read_errors by hours_since_last.
+	 */
+	if (hours_since_last >= 8 * sizeof(read_errors))
+		atomic_set(&rdev->read_errors, 0);
+	else
+		atomic_set(&rdev->read_errors, read_errors >> hours_since_last);
+}
+
+/*
  * This is a kernel thread which:
  *
  *	1.	Retries failed read operations on working mirrors.
@@ -1444,6 +1481,43 @@ static void fix_read_error(conf_t *conf,
 	int sect = 0; /* Offset from r10_bio->sector */
 	int sectors = r10_bio->sectors;
 	mdk_rdev_t*rdev;
+	int max_read_errors = atomic_read(&mddev->max_corr_read_errors);
+
+	rcu_read_lock();
+	{
+		int d = r10_bio->devs[r10_bio->read_slot].devnum;
+		char b[BDEVNAME_SIZE];
+		int cur_read_error_count = 0;
+
+		rdev = rcu_dereference(conf->mirrors[d].rdev);
+		bdevname(rdev->bdev, b);
+
+		if (test_bit(Faulty, &rdev->flags)) {
+			rcu_read_unlock();
+			/* drive has already been failed, just ignore any
+			   more fix_read_error() attempts */
+			return;
+		}
+
+		check_decay_read_errors(mddev, rdev);
+		atomic_inc(&rdev->read_errors);
+		cur_read_error_count = atomic_read(&rdev->read_errors);
+		if (cur_read_error_count > max_read_errors) {
+			rcu_read_unlock();
+			printk(KERN_NOTICE
+			       "raid10: %s: Raid device exceeded "
+			       "read_error threshold "
+			       "[cur %d:max %d]\n",
+			       b, cur_read_error_count, max_read_errors);
+			printk(KERN_NOTICE
+			       "raid10: %s: Failing raid "
+			       "device\n", b);
+			md_error(mddev, conf->mirrors[d].rdev);
+			return;
+		}
+	}
+	rcu_read_unlock();
+
 	while(sectors) {
 		int s = sectors;
 		int sl = r10_bio->read_slot;
@@ -1488,6 +1562,7 @@ static void fix_read_error(conf_t *conf,
 		/* write it back and re-read */
 		rcu_read_lock();
 		while (sl != r10_bio->read_slot) {
+			char b[BDEVNAME_SIZE];
 			int d;
 			if (sl==0)
 				sl = conf->copies;
@@ -1503,9 +1578,21 @@ static void fix_read_error(conf_t *conf,
 						 r10_bio->devs[sl].addr +
 						 sect + rdev->data_offset,
 						 s<<9, conf->tmppage, WRITE)
-				    == 0)
+				    == 0) {
 					/* Well, this device is dead */
+					printk(KERN_NOTICE
+					       "raid10:%s: read correction "
+					       "write failed"
+					       " (%d sectors at %llu on %s)\n",
+					       mdname(mddev), s,
+					       (unsigned long long)(sect+
+					       rdev->data_offset),
+					       bdevname(rdev->bdev, b));
+					printk(KERN_NOTICE "raid10:%s: failing "
+					       "drive\n",
+					       bdevname(rdev->bdev, b));
 					md_error(mddev, rdev);
+				}
 				rdev_dec_pending(rdev, mddev);
 				rcu_read_lock();
 			}
@@ -1526,10 +1613,22 @@ static void fix_read_error(conf_t *conf,
 				if (sync_page_io(rdev->bdev,
 						 r10_bio->devs[sl].addr +
 						 sect + rdev->data_offset,
-						 s<<9, conf->tmppage, READ) == 0)
+						 s<<9, conf->tmppage,
+						 READ) == 0) {
 					/* Well, this device is dead */
+					printk(KERN_NOTICE
+					       "raid10:%s: unable to read back "
+					       "corrected sectors"
+					       " (%d sectors at %llu on %s)\n",
+					       mdname(mddev), s,
+					       (unsigned long long)(sect+
+						    rdev->data_offset),
+					       bdevname(rdev->bdev, b));
+					printk(KERN_NOTICE "raid10:%s: failing drive\n",
+					       bdevname(rdev->bdev, b));
+
 					md_error(mddev, rdev);
-				else
+				} else {
 					printk(KERN_INFO
 					       "raid10:%s: read error corrected"
 					       " (%d sectors at %llu on %s)\n",
@@ -1537,6 +1636,7 @@ static void fix_read_error(conf_t *conf,
 					       (unsigned long long)(sect+
 					            rdev->data_offset),
 					       bdevname(rdev->bdev, b));
+				}
 
 				rdev_dec_pending(rdev, mddev);
 				rcu_read_lock();
@@ -2275,13 +2375,6 @@ static void raid10_quiesce(mddev_t *mdde
 		lower_barrier(conf);
 		break;
 	}
-	if (mddev->thread) {
-		if (mddev->bitmap)
-			mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-		else
-			mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
-		md_wakeup_thread(mddev->thread);
-	}
 }
 
 static struct mdk_personality raid10_personality =
@@ -2315,6 +2408,7 @@ static void raid_exit(void)
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RAID10 (striped mirror) personality for MD");
 MODULE_ALIAS("md-personality-9"); /* RAID10 */
 MODULE_ALIAS("md-raid10");
 MODULE_ALIAS("md-level-10");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid1.c linux-libre-2.6.33-gnu1/drivers/md/raid1.c
--- linux-libre-2.6.32-gnu1/drivers/md/raid1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid1.c	2010-02-24 13:52:17.000000000 -0500
@@ -677,6 +677,7 @@ static void raise_barrier(conf_t *conf)
 static void lower_barrier(conf_t *conf)
 {
 	unsigned long flags;
+	BUG_ON(conf->barrier <= 0);
 	spin_lock_irqsave(&conf->resync_lock, flags);
 	conf->barrier--;
 	spin_unlock_irqrestore(&conf->resync_lock, flags);
@@ -801,6 +802,25 @@ static int make_request(struct request_q
 
 	md_write_start(mddev, bio); /* wait on superblock update early */
 
+	if (bio_data_dir(bio) == WRITE &&
+	    bio->bi_sector + bio->bi_size/512 > mddev->suspend_lo &&
+	    bio->bi_sector < mddev->suspend_hi) {
+		/* As the suspend_* range is controlled by
+		 * userspace, we want an interruptible
+		 * wait.
+		 */
+		DEFINE_WAIT(w);
+		for (;;) {
+			flush_signals(current);
+			prepare_to_wait(&conf->wait_barrier,
+					&w, TASK_INTERRUPTIBLE);
+			if (bio->bi_sector + bio->bi_size/512 <= mddev->suspend_lo ||
+			    bio->bi_sector >= mddev->suspend_hi)
+				break;
+			schedule();
+		}
+		finish_wait(&conf->wait_barrier, &w);
+	}
 	if (unlikely(!mddev->barriers_work &&
 		     bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		if (rw == WRITE)
@@ -923,7 +943,8 @@ static int make_request(struct request_q
 
 	/* do behind I/O ? */
 	if (bitmap &&
-	    atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind &&
+	    (atomic_read(&bitmap->behind_writes)
+	     < mddev->bitmap_info.max_write_behind) &&
 	    (behind_pages = alloc_behind_pages(bio)) != NULL)
 		set_bit(R1BIO_BehindIO, &r1_bio->state);
 
@@ -1941,74 +1962,48 @@ static sector_t raid1_size(mddev_t *mdde
 	return mddev->dev_sectors;
 }
 
-static int run(mddev_t *mddev)
+static conf_t *setup_conf(mddev_t *mddev)
 {
 	conf_t *conf;
-	int i, j, disk_idx;
+	int i;
 	mirror_info_t *disk;
 	mdk_rdev_t *rdev;
+	int err = -ENOMEM;
 
-	if (mddev->level != 1) {
-		printk("raid1: %s: raid level not set to mirroring (%d)\n",
-		       mdname(mddev), mddev->level);
-		goto out;
-	}
-	if (mddev->reshape_position != MaxSector) {
-		printk("raid1: %s: reshape_position set but not supported\n",
-		       mdname(mddev));
-		goto out;
-	}
-	/*
-	 * copy the already verified devices into our private RAID1
-	 * bookkeeping area. [whatever we allocate in run(),
-	 * should be freed in stop()]
-	 */
 	conf = kzalloc(sizeof(conf_t), GFP_KERNEL);
-	mddev->private = conf;
 	if (!conf)
-		goto out_no_mem;
+		goto abort;
 
 	conf->mirrors = kzalloc(sizeof(struct mirror_info)*mddev->raid_disks,
 				 GFP_KERNEL);
 	if (!conf->mirrors)
-		goto out_no_mem;
+		goto abort;
 
 	conf->tmppage = alloc_page(GFP_KERNEL);
 	if (!conf->tmppage)
-		goto out_no_mem;
+		goto abort;
 
-	conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
+	conf->poolinfo = kzalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
 	if (!conf->poolinfo)
-		goto out_no_mem;
-	conf->poolinfo->mddev = NULL;
+		goto abort;
 	conf->poolinfo->raid_disks = mddev->raid_disks;
 	conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
 					  r1bio_pool_free,
 					  conf->poolinfo);
 	if (!conf->r1bio_pool)
-		goto out_no_mem;
+		goto abort;
+
 	conf->poolinfo->mddev = mddev;
 
 	spin_lock_init(&conf->device_lock);
-	mddev->queue->queue_lock = &conf->device_lock;
-
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
-		disk_idx = rdev->raid_disk;
+		int disk_idx = rdev->raid_disk;
 		if (disk_idx >= mddev->raid_disks
 		    || disk_idx < 0)
 			continue;
 		disk = conf->mirrors + disk_idx;
 
 		disk->rdev = rdev;
-		disk_stack_limits(mddev->gendisk, rdev->bdev,
-				  rdev->data_offset << 9);
-		/* as we don't honour merge_bvec_fn, we must never risk
-		 * violating it, so limit ->max_sector to one PAGE, as
-		 * a one page request is never in violation.
-		 */
-		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
 		disk->head_position = 0;
 	}
@@ -2022,8 +2017,7 @@ static int run(mddev_t *mddev)
 	bio_list_init(&conf->pending_bio_list);
 	bio_list_init(&conf->flushing_bio_list);
 
-
-	mddev->degraded = 0;
+	conf->last_used = -1;
 	for (i = 0; i < conf->raid_disks; i++) {
 
 		disk = conf->mirrors + i;
@@ -2031,38 +2025,97 @@ static int run(mddev_t *mddev)
 		if (!disk->rdev ||
 		    !test_bit(In_sync, &disk->rdev->flags)) {
 			disk->head_position = 0;
-			mddev->degraded++;
 			if (disk->rdev)
 				conf->fullsync = 1;
-		}
+		} else if (conf->last_used < 0)
+			/*
+			 * The first working device is used as a
+			 * starting point to read balancing.
+			 */
+			conf->last_used = i;
 	}
-	if (mddev->degraded == conf->raid_disks) {
+
+	err = -EIO;
+	if (conf->last_used < 0) {
 		printk(KERN_ERR "raid1: no operational mirrors for %s\n",
-			mdname(mddev));
-		goto out_free_conf;
+		       mdname(mddev));
+		goto abort;
+	}
+	err = -ENOMEM;
+	conf->thread = md_register_thread(raid1d, mddev, NULL);
+	if (!conf->thread) {
+		printk(KERN_ERR
+		       "raid1: couldn't allocate thread for %s\n",
+		       mdname(mddev));
+		goto abort;
 	}
-	if (conf->raid_disks - mddev->degraded == 1)
-		mddev->recovery_cp = MaxSector;
 
+	return conf;
+
+ abort:
+	if (conf) {
+		if (conf->r1bio_pool)
+			mempool_destroy(conf->r1bio_pool);
+		kfree(conf->mirrors);
+		safe_put_page(conf->tmppage);
+		kfree(conf->poolinfo);
+		kfree(conf);
+	}
+	return ERR_PTR(err);
+}
+
+static int run(mddev_t *mddev)
+{
+	conf_t *conf;
+	int i;
+	mdk_rdev_t *rdev;
+
+	if (mddev->level != 1) {
+		printk("raid1: %s: raid level not set to mirroring (%d)\n",
+		       mdname(mddev), mddev->level);
+		return -EIO;
+	}
+	if (mddev->reshape_position != MaxSector) {
+		printk("raid1: %s: reshape_position set but not supported\n",
+		       mdname(mddev));
+		return -EIO;
+	}
 	/*
-	 * find the first working one and use it as a starting point
-	 * to read balancing.
+	 * copy the already verified devices into our private RAID1
+	 * bookkeeping area. [whatever we allocate in run(),
+	 * should be freed in stop()]
 	 */
-	for (j = 0; j < conf->raid_disks &&
-		     (!conf->mirrors[j].rdev ||
-		      !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
-		/* nothing */;
-	conf->last_used = j;
+	if (mddev->private == NULL)
+		conf = setup_conf(mddev);
+	else
+		conf = mddev->private;
 
+	if (IS_ERR(conf))
+		return PTR_ERR(conf);
 
-	mddev->thread = md_register_thread(raid1d, mddev, NULL);
-	if (!mddev->thread) {
-		printk(KERN_ERR
-		       "raid1: couldn't allocate thread for %s\n",
-		       mdname(mddev));
-		goto out_free_conf;
+	mddev->queue->queue_lock = &conf->device_lock;
+	list_for_each_entry(rdev, &mddev->disks, same_set) {
+		disk_stack_limits(mddev->gendisk, rdev->bdev,
+				  rdev->data_offset << 9);
+		/* as we don't honour merge_bvec_fn, we must never risk
+		 * violating it, so limit ->max_sector to one PAGE, as
+		 * a one page request is never in violation.
+		 */
+		if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+		    queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
+			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 	}
 
+	mddev->degraded = 0;
+	for (i=0; i < conf->raid_disks; i++)
+		if (conf->mirrors[i].rdev == NULL ||
+		    !test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
+		    test_bit(Faulty, &conf->mirrors[i].rdev->flags))
+			mddev->degraded++;
+
+	if (conf->raid_disks - mddev->degraded == 1)
+		mddev->recovery_cp = MaxSector;
+
 	if (mddev->recovery_cp != MaxSector)
 		printk(KERN_NOTICE "raid1: %s is not clean"
 		       " -- starting background reconstruction\n",
@@ -2071,9 +2124,14 @@ static int run(mddev_t *mddev)
 		"raid1: raid set %s active with %d out of %d mirrors\n",
 		mdname(mddev), mddev->raid_disks - mddev->degraded, 
 		mddev->raid_disks);
+
 	/*
 	 * Ok, everything is just fine now
 	 */
+	mddev->thread = conf->thread;
+	conf->thread = NULL;
+	mddev->private = conf;
+
 	md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
 
 	mddev->queue->unplug_fn = raid1_unplug;
@@ -2081,23 +2139,6 @@ static int run(mddev_t *mddev)
 	mddev->queue->backing_dev_info.congested_data = mddev;
 	md_integrity_register(mddev);
 	return 0;
-
-out_no_mem:
-	printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
-	       mdname(mddev));
-
-out_free_conf:
-	if (conf) {
-		if (conf->r1bio_pool)
-			mempool_destroy(conf->r1bio_pool);
-		kfree(conf->mirrors);
-		safe_put_page(conf->tmppage);
-		kfree(conf->poolinfo);
-		kfree(conf);
-		mddev->private = NULL;
-	}
-out:
-	return -EIO;
 }
 
 static int stop(mddev_t *mddev)
@@ -2271,6 +2312,9 @@ static void raid1_quiesce(mddev_t *mddev
 	conf_t *conf = mddev->private;
 
 	switch(state) {
+	case 2: /* wake for suspend */
+		wake_up(&conf->wait_barrier);
+		break;
 	case 1:
 		raise_barrier(conf);
 		break;
@@ -2280,6 +2324,23 @@ static void raid1_quiesce(mddev_t *mddev
 	}
 }
 
+static void *raid1_takeover(mddev_t *mddev)
+{
+	/* raid1 can take over:
+	 *  raid5 with 2 devices, any layout or chunk size
+	 */
+	if (mddev->level == 5 && mddev->raid_disks == 2) {
+		conf_t *conf;
+		mddev->new_level = 1;
+		mddev->new_layout = 0;
+		mddev->new_chunk_sectors = 0;
+		conf = setup_conf(mddev);
+		if (!IS_ERR(conf))
+			conf->barrier = 1;
+		return conf;
+	}
+	return ERR_PTR(-EINVAL);
+}
 
 static struct mdk_personality raid1_personality =
 {
@@ -2299,6 +2360,7 @@ static struct mdk_personality raid1_pers
 	.size		= raid1_size,
 	.check_reshape	= raid1_reshape,
 	.quiesce	= raid1_quiesce,
+	.takeover	= raid1_takeover,
 };
 
 static int __init raid_init(void)
@@ -2314,6 +2376,7 @@ static void raid_exit(void)
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RAID1 (mirroring) personality for MD");
 MODULE_ALIAS("md-personality-3"); /* RAID1 */
 MODULE_ALIAS("md-raid1");
 MODULE_ALIAS("md-level-1");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid1.h linux-libre-2.6.33-gnu1/drivers/md/raid1.h
--- linux-libre-2.6.32-gnu1/drivers/md/raid1.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid1.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,11 @@ struct r1_private_data_s {
 
 	mempool_t *r1bio_pool;
 	mempool_t *r1buf_pool;
+
+	/* When taking over an array from a different personality, we store
+	 * the new thread here until we fully activate the array.
+	 */
+	struct mdk_thread_s	*thread;
 };
 
 typedef struct r1_private_data_s conf_t;
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid5.c linux-libre-2.6.33-gnu1/drivers/md/raid5.c
--- linux-libre-2.6.32-gnu1/drivers/md/raid5.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid5.c	2010-02-24 13:52:17.000000000 -0500
@@ -2947,6 +2947,7 @@ static void handle_stripe5(struct stripe
 	struct r5dev *dev;
 	mdk_rdev_t *blocked_rdev = NULL;
 	int prexor;
+	int dec_preread_active = 0;
 
 	memset(&s, 0, sizeof(s));
 	pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d check:%d "
@@ -3096,12 +3097,8 @@ static void handle_stripe5(struct stripe
 					set_bit(STRIPE_INSYNC, &sh->state);
 			}
 		}
-		if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
-			atomic_dec(&conf->preread_active_stripes);
-			if (atomic_read(&conf->preread_active_stripes) <
-				IO_THRESHOLD)
-				md_wakeup_thread(conf->mddev->thread);
-		}
+		if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+			dec_preread_active = 1;
 	}
 
 	/* Now to consider new write requests and what else, if anything
@@ -3208,6 +3205,16 @@ static void handle_stripe5(struct stripe
 
 	ops_run_io(sh, &s);
 
+	if (dec_preread_active) {
+		/* We delay this until after ops_run_io so that if make_request
+		 * is waiting on a barrier, it won't continue until the writes
+		 * have actually been submitted.
+		 */
+		atomic_dec(&conf->preread_active_stripes);
+		if (atomic_read(&conf->preread_active_stripes) <
+		    IO_THRESHOLD)
+			md_wakeup_thread(conf->mddev->thread);
+	}
 	return_io(return_bi);
 }
 
@@ -3221,6 +3228,7 @@ static void handle_stripe6(struct stripe
 	struct r6_state r6s;
 	struct r5dev *dev, *pdev, *qdev;
 	mdk_rdev_t *blocked_rdev = NULL;
+	int dec_preread_active = 0;
 
 	pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
 		"pd_idx=%d, qd_idx=%d\n, check:%d, reconstruct:%d\n",
@@ -3358,7 +3366,6 @@ static void handle_stripe6(struct stripe
 	 * completed
 	 */
 	if (sh->reconstruct_state == reconstruct_state_drain_result) {
-		int qd_idx = sh->qd_idx;
 
 		sh->reconstruct_state = reconstruct_state_idle;
 		/* All the 'written' buffers and the parity blocks are ready to
@@ -3380,12 +3387,8 @@ static void handle_stripe6(struct stripe
 					set_bit(STRIPE_INSYNC, &sh->state);
 			}
 		}
-		if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
-			atomic_dec(&conf->preread_active_stripes);
-			if (atomic_read(&conf->preread_active_stripes) <
-				IO_THRESHOLD)
-				md_wakeup_thread(conf->mddev->thread);
-		}
+		if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+			dec_preread_active = 1;
 	}
 
 	/* Now to consider new write requests and what else, if anything
@@ -3494,6 +3497,18 @@ static void handle_stripe6(struct stripe
 
 	ops_run_io(sh, &s);
 
+
+	if (dec_preread_active) {
+		/* We delay this until after ops_run_io so that if make_request
+		 * is waiting on a barrier, it won't continue until the writes
+		 * have actually been submitted.
+		 */
+		atomic_dec(&conf->preread_active_stripes);
+		if (atomic_read(&conf->preread_active_stripes) <
+		    IO_THRESHOLD)
+			md_wakeup_thread(conf->mddev->thread);
+	}
+
 	return_io(return_bi);
 }
 
@@ -3741,7 +3756,7 @@ static int chunk_aligned_read(struct req
 {
 	mddev_t *mddev = q->queuedata;
 	raid5_conf_t *conf = mddev->private;
-	unsigned int dd_idx;
+	int dd_idx;
 	struct bio* align_bi;
 	mdk_rdev_t *rdev;
 
@@ -3866,7 +3881,13 @@ static int make_request(struct request_q
 	int cpu, remaining;
 
 	if (unlikely(bio_rw_flagged(bi, BIO_RW_BARRIER))) {
-		bio_endio(bi, -EOPNOTSUPP);
+		/* Drain all pending writes.  We only really need
+		 * to ensure they have been submitted, but this is
+		 * easier.
+		 */
+		mddev->pers->quiesce(mddev, 1);
+		mddev->pers->quiesce(mddev, 0);
+		md_barrier_request(mddev, bi);
 		return 0;
 	}
 
@@ -3990,6 +4011,9 @@ static int make_request(struct request_q
 			finish_wait(&conf->wait_for_overlap, &w);
 			set_bit(STRIPE_HANDLE, &sh->state);
 			clear_bit(STRIPE_DELAYED, &sh->state);
+			if (mddev->barrier && 
+			    !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+				atomic_inc(&conf->preread_active_stripes);
 			release_stripe(sh);
 		} else {
 			/* cannot get stripe for read-ahead, just give-up */
@@ -4009,6 +4033,14 @@ static int make_request(struct request_q
 
 		bio_endio(bi, 0);
 	}
+
+	if (mddev->barrier) {
+		/* We need to wait for the stripes to all be handled.
+		 * So: wait for preread_active_stripes to drop to 0.
+		 */
+		wait_event(mddev->thread->wqueue,
+			   atomic_read(&conf->preread_active_stripes) == 0);
+	}
 	return 0;
 }
 
@@ -5104,9 +5136,8 @@ static int stop(mddev_t *mddev)
 	mddev->thread = NULL;
 	mddev->queue->backing_dev_info.congested_fn = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
-	sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
 	free_conf(conf);
-	mddev->private = NULL;
+	mddev->private = &raid5_attrs_group;
 	return 0;
 }
 
@@ -5432,11 +5463,11 @@ static int raid5_start_reshape(mddev_t *
 		    !test_bit(Faulty, &rdev->flags)) {
 			if (raid5_add_disk(mddev, rdev) == 0) {
 				char nm[20];
-				if (rdev->raid_disk >= conf->previous_raid_disks)
+				if (rdev->raid_disk >= conf->previous_raid_disks) {
 					set_bit(In_sync, &rdev->flags);
-				else
+					added_devices++;
+				} else
 					rdev->recovery_offset = 0;
-				added_devices++;
 				sprintf(nm, "rd%d", rdev->raid_disk);
 				if (sysfs_create_link(&mddev->kobj,
 						      &rdev->kobj, nm))
@@ -5448,9 +5479,12 @@ static int raid5_start_reshape(mddev_t *
 				break;
 		}
 
+	/* When a reshape changes the number of devices, ->degraded
+	 * is measured against the large of the pre and post number of
+	 * devices.*/
 	if (mddev->delta_disks > 0) {
 		spin_lock_irqsave(&conf->device_lock, flags);
-		mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+		mddev->degraded += (conf->raid_disks - conf->previous_raid_disks)
 			- added_devices;
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 	}
@@ -5860,6 +5894,7 @@ static void raid5_exit(void)
 module_init(raid5_init);
 module_exit(raid5_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RAID4/5/6 (striping with parity) personality for MD");
 MODULE_ALIAS("md-personality-4"); /* RAID5 */
 MODULE_ALIAS("md-raid5");
 MODULE_ALIAS("md-raid4");
diff -druNp linux-libre-2.6.32-gnu1/drivers/md/raid6algos.c linux-libre-2.6.33-gnu1/drivers/md/raid6algos.c
--- linux-libre-2.6.32-gnu1/drivers/md/raid6algos.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/md/raid6algos.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,25 +31,6 @@ EXPORT_SYMBOL(raid6_empty_zero_page);
 struct raid6_calls raid6_call;
 EXPORT_SYMBOL_GPL(raid6_call);
 
-/* Various routine sets */
-extern const struct raid6_calls raid6_intx1;
-extern const struct raid6_calls raid6_intx2;
-extern const struct raid6_calls raid6_intx4;
-extern const struct raid6_calls raid6_intx8;
-extern const struct raid6_calls raid6_intx16;
-extern const struct raid6_calls raid6_intx32;
-extern const struct raid6_calls raid6_mmxx1;
-extern const struct raid6_calls raid6_mmxx2;
-extern const struct raid6_calls raid6_sse1x1;
-extern const struct raid6_calls raid6_sse1x2;
-extern const struct raid6_calls raid6_sse2x1;
-extern const struct raid6_calls raid6_sse2x2;
-extern const struct raid6_calls raid6_sse2x4;
-extern const struct raid6_calls raid6_altivec1;
-extern const struct raid6_calls raid6_altivec2;
-extern const struct raid6_calls raid6_altivec4;
-extern const struct raid6_calls raid6_altivec8;
-
 const struct raid6_calls * const raid6_algos[] = {
 	&raid6_intx1,
 	&raid6_intx2,
@@ -169,3 +150,4 @@ static void raid6_exit(void)
 subsys_initcall(raid6_select_algo);
 module_exit(raid6_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RAID6 Q-syndrome calculations");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/ir-functions.c linux-libre-2.6.33-gnu1/drivers/media/common/ir-functions.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/ir-functions.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/ir-functions.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,382 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- *  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/module.h>
-#include <linux/string.h>
-#include <linux/jiffies.h>
-#include <media/ir-common.h>
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static int repeat = 1;
-module_param(repeat, int, 0444);
-MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
-
-static int debug;    /* debug level (0,1,2) */
-module_param(debug, int, 0644);
-
-#define dprintk(level, fmt, arg...)	if (debug >= level) \
-	printk(KERN_DEBUG fmt , ## arg)
-
-/* -------------------------------------------------------------------------- */
-
-static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
-{
-	if (KEY_RESERVED == ir->keycode) {
-		printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
-		       dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
-		return;
-	}
-	dprintk(1,"%s: key event code=%d down=%d\n",
-		dev->name,ir->keycode,ir->keypressed);
-	input_report_key(dev,ir->keycode,ir->keypressed);
-	input_sync(dev);
-}
-
-/* -------------------------------------------------------------------------- */
-
-void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type, struct ir_scancode_table *ir_codes)
-{
-	int i;
-
-	ir->ir_type = ir_type;
-
-	memset(ir->ir_codes, 0, sizeof(ir->ir_codes));
-
-	/*
-	 * FIXME: This is a temporary workaround to use the new IR tables
-	 * with the old approach. Later patches will replace this to a
-	 * proper method
-	 */
-
-	if (ir_codes)
-		for (i = 0; i < ir_codes->size; i++)
-			if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
-				ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
-
-	dev->keycode     = ir->ir_codes;
-	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
-	dev->keycodemax  = IR_KEYTAB_SIZE;
-	for (i = 0; i < IR_KEYTAB_SIZE; i++)
-		set_bit(ir->ir_codes[i], dev->keybit);
-	clear_bit(0, dev->keybit);
-
-	set_bit(EV_KEY, dev->evbit);
-	if (repeat)
-		set_bit(EV_REP, dev->evbit);
-}
-EXPORT_SYMBOL_GPL(ir_input_init);
-
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
-{
-	if (ir->keypressed) {
-		ir->keypressed = 0;
-		ir_input_key_event(dev,ir);
-	}
-}
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
-		      u32 ir_key, u32 ir_raw)
-{
-	u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
-
-	if (ir->keypressed && ir->keycode != keycode) {
-		ir->keypressed = 0;
-		ir_input_key_event(dev,ir);
-	}
-	if (!ir->keypressed) {
-		ir->ir_key  = ir_key;
-		ir->ir_raw  = ir_raw;
-		ir->keycode = keycode;
-		ir->keypressed = 1;
-		ir_input_key_event(dev,ir);
-	}
-}
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-/* -------------------------------------------------------------------------- */
-/* extract mask bits out of data and pack them into the result */
-u32 ir_extract_bits(u32 data, u32 mask)
-{
-	u32 vbit = 1, value = 0;
-
-	do {
-	    if (mask&1) {
-		if (data&1)
-			value |= vbit;
-		vbit<<=1;
-	    }
-	    data>>=1;
-	} while (mask>>=1);
-
-	return value;
-}
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-
-static int inline getbit(u32 *samples, int bit)
-{
-	return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
-}
-
-/* sump raw samples for visual debugging ;) */
-int ir_dump_samples(u32 *samples, int count)
-{
-	int i, bit, start;
-
-	printk(KERN_DEBUG "ir samples: ");
-	start = 0;
-	for (i = 0; i < count * 32; i++) {
-		bit = getbit(samples,i);
-		if (bit)
-			start = 1;
-		if (0 == start)
-			continue;
-		printk("%s", bit ? "#" : "_");
-	}
-	printk("\n");
-	return 0;
-}
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-
-/* decode raw samples, pulse distance coding used by NEC remotes */
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
-{
-	int i,last,bit,len;
-	u32 curBit;
-	u32 value;
-
-	/* find start burst */
-	for (i = len = 0; i < count * 32; i++) {
-		bit = getbit(samples,i);
-		if (bit) {
-			len++;
-		} else {
-			if (len >= 29)
-				break;
-			len = 0;
-		}
-	}
-
-	/* start burst to short */
-	if (len < 29)
-		return 0xffffffff;
-
-	/* find start silence */
-	for (len = 0; i < count * 32; i++) {
-		bit = getbit(samples,i);
-		if (bit) {
-			break;
-		} else {
-			len++;
-		}
-	}
-
-	/* silence to short */
-	if (len < 7)
-		return 0xffffffff;
-
-	/* go decoding */
-	len   = 0;
-	last = 1;
-	value = 0; curBit = 1;
-	for (; i < count * 32; i++) {
-		bit  = getbit(samples,i);
-		if (last) {
-			if(bit) {
-				continue;
-			} else {
-				len = 1;
-			}
-		} else {
-			if (bit) {
-				if (len > (low + high) /2)
-					value |= curBit;
-				curBit <<= 1;
-				if (curBit == 1)
-					break;
-			} else {
-				len++;
-			}
-		}
-		last = bit;
-	}
-
-	return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-/* decode raw samples, biphase coding, used by rc5 for example */
-int ir_decode_biphase(u32 *samples, int count, int low, int high)
-{
-	int i,last,bit,len,flips;
-	u32 value;
-
-	/* find start bit (1) */
-	for (i = 0; i < 32; i++) {
-		bit = getbit(samples,i);
-		if (bit)
-			break;
-	}
-
-	/* go decoding */
-	len   = 0;
-	flips = 0;
-	value = 1;
-	for (; i < count * 32; i++) {
-		if (len > high)
-			break;
-		if (flips > 1)
-			break;
-		last = bit;
-		bit  = getbit(samples,i);
-		if (last == bit) {
-			len++;
-			continue;
-		}
-		if (len < low) {
-			len++;
-			flips++;
-			continue;
-		}
-		value <<= 1;
-		value |= bit;
-		flips = 0;
-		len   = 1;
-	}
-	return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-
-/* RC5 decoding stuff, moved from bttv-input.c to share it with
- * saa7134 */
-
-/* decode raw bit pattern to RC5 code */
-static u32 ir_rc5_decode(unsigned int code)
-{
-	unsigned int org_code = code;
-	unsigned int pair;
-	unsigned int rc5 = 0;
-	int i;
-
-	for (i = 0; i < 14; ++i) {
-		pair = code & 0x3;
-		code >>= 2;
-
-		rc5 <<= 1;
-		switch (pair) {
-		case 0:
-		case 2:
-			break;
-		case 1:
-			rc5 |= 1;
-			break;
-		case 3:
-			dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
-			return 0;
-		}
-	}
-	dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
-		"instr=%x\n", rc5, org_code, RC5_START(rc5),
-		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
-	return rc5;
-}
-
-void ir_rc5_timer_end(unsigned long data)
-{
-	struct card_ir *ir = (struct card_ir *)data;
-	struct timeval tv;
-	unsigned long current_jiffies, timeout;
-	u32 gap;
-	u32 rc5 = 0;
-
-	/* get time */
-	current_jiffies = jiffies;
-	do_gettimeofday(&tv);
-
-	/* avoid overflow with gap >1s */
-	if (tv.tv_sec - ir->base_time.tv_sec > 1) {
-		gap = 200000;
-	} else {
-		gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
-		    tv.tv_usec - ir->base_time.tv_usec;
-	}
-
-	/* signal we're ready to start a new code */
-	ir->active = 0;
-
-	/* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
-	if (gap < 28000) {
-		dprintk(1, "ir-common: spurious timer_end\n");
-		return;
-	}
-
-	if (ir->last_bit < 20) {
-		/* ignore spurious codes (caused by light/other remotes) */
-		dprintk(1, "ir-common: short code: %x\n", ir->code);
-	} else {
-		ir->code = (ir->code << ir->shift_by) | 1;
-		rc5 = ir_rc5_decode(ir->code);
-
-		/* two start bits? */
-		if (RC5_START(rc5) != ir->start) {
-			dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
-
-			/* right address? */
-		} else if (RC5_ADDR(rc5) == ir->addr) {
-			u32 toggle = RC5_TOGGLE(rc5);
-			u32 instr = RC5_INSTR(rc5);
-
-			/* Good code, decide if repeat/repress */
-			if (toggle != RC5_TOGGLE(ir->last_rc5) ||
-			    instr != RC5_INSTR(ir->last_rc5)) {
-				dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
-					toggle);
-				ir_input_nokey(ir->dev, &ir->ir);
-				ir_input_keydown(ir->dev, &ir->ir, instr,
-						 instr);
-			}
-
-			/* Set/reset key-up timer */
-			timeout = current_jiffies +
-				  msecs_to_jiffies(ir->rc5_key_timeout);
-			mod_timer(&ir->timer_keyup, timeout);
-
-			/* Save code for repeat test */
-			ir->last_rc5 = rc5;
-		}
-	}
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
-
-void ir_rc5_timer_keyup(unsigned long data)
-{
-	struct card_ir *ir = (struct card_ir *)data;
-
-	dprintk(1, "ir-common: key released\n");
-	ir_input_nokey(ir->dev, &ir->ir);
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/ir-keymaps.c linux-libre-2.6.33-gnu1/drivers/media/common/ir-keymaps.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/ir-keymaps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/ir-keymaps.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3149 +0,0 @@
-/*
-    Keytables for supported remote controls, used on drivers/media
-    devices.
-
-    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.
-*/
-
-/*
- * NOTICE FOR DEVELOPERS:
- *   The IR mappings should be as close as possible to what's
- *   specified at:
- *      http://linuxtv.org/wiki/index.php/Remote_Controllers
- */
-#include <linux/module.h>
-
-#include <linux/input.h>
-#include <media/ir-common.h>
-
-/* empty keytable, can be used as placeholder for not-yet created keytables */
-static struct ir_scancode ir_codes_empty[] = {
-	{ 0x2a, KEY_COFFEE },
-};
-
-struct ir_scancode_table ir_codes_empty_table = {
-	.scan = ir_codes_empty,
-	.size = ARRAY_SIZE(ir_codes_empty),
-};
-EXPORT_SYMBOL_GPL(ir_codes_empty_table);
-
-/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
-static struct ir_scancode ir_codes_proteus_2309[] = {
-	/* numeric */
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x5c, KEY_POWER },		/* power       */
-	{ 0x20, KEY_ZOOM },		/* full screen */
-	{ 0x0f, KEY_BACKSPACE },	/* recall      */
-	{ 0x1b, KEY_ENTER },		/* mute        */
-	{ 0x41, KEY_RECORD },		/* record      */
-	{ 0x43, KEY_STOP },		/* stop        */
-	{ 0x16, KEY_S },
-	{ 0x1a, KEY_POWER2 },		/* off         */
-	{ 0x2e, KEY_RED },
-	{ 0x1f, KEY_CHANNELDOWN },	/* channel -   */
-	{ 0x1c, KEY_CHANNELUP },	/* channel +   */
-	{ 0x10, KEY_VOLUMEDOWN },	/* volume -    */
-	{ 0x1e, KEY_VOLUMEUP },		/* volume +    */
-	{ 0x14, KEY_F1 },
-};
-
-struct ir_scancode_table ir_codes_proteus_2309_table = {
-	.scan = ir_codes_proteus_2309,
-	.size = ARRAY_SIZE(ir_codes_proteus_2309),
-};
-EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
-
-/* Matt Jesson <dvb@jesson.eclipse.co.uk */
-static struct ir_scancode ir_codes_avermedia_dvbt[] = {
-	{ 0x28, KEY_0 },		/* '0' / 'enter' */
-	{ 0x22, KEY_1 },		/* '1' */
-	{ 0x12, KEY_2 },		/* '2' / 'up arrow' */
-	{ 0x32, KEY_3 },		/* '3' */
-	{ 0x24, KEY_4 },		/* '4' / 'left arrow' */
-	{ 0x14, KEY_5 },		/* '5' */
-	{ 0x34, KEY_6 },		/* '6' / 'right arrow' */
-	{ 0x26, KEY_7 },		/* '7' */
-	{ 0x16, KEY_8 },		/* '8' / 'down arrow' */
-	{ 0x36, KEY_9 },		/* '9' */
-
-	{ 0x20, KEY_LIST },		/* 'source' */
-	{ 0x10, KEY_TEXT },		/* 'teletext' */
-	{ 0x00, KEY_POWER },		/* 'power' */
-	{ 0x04, KEY_AUDIO },		/* 'audio' */
-	{ 0x06, KEY_ZOOM },		/* 'full screen' */
-	{ 0x18, KEY_VIDEO },		/* 'display' */
-	{ 0x38, KEY_SEARCH },		/* 'loop' */
-	{ 0x08, KEY_INFO },		/* 'preview' */
-	{ 0x2a, KEY_REWIND },		/* 'backward <<' */
-	{ 0x1a, KEY_FASTFORWARD },	/* 'forward >>' */
-	{ 0x3a, KEY_RECORD },		/* 'capture' */
-	{ 0x0a, KEY_MUTE },		/* 'mute' */
-	{ 0x2c, KEY_RECORD },		/* 'record' */
-	{ 0x1c, KEY_PAUSE },		/* 'pause' */
-	{ 0x3c, KEY_STOP },		/* 'stop' */
-	{ 0x0c, KEY_PLAY },		/* 'play' */
-	{ 0x2e, KEY_RED },		/* 'red' */
-	{ 0x01, KEY_BLUE },		/* 'blue' / 'cancel' */
-	{ 0x0e, KEY_YELLOW },		/* 'yellow' / 'ok' */
-	{ 0x21, KEY_GREEN },		/* 'green' */
-	{ 0x11, KEY_CHANNELDOWN },	/* 'channel -' */
-	{ 0x31, KEY_CHANNELUP },	/* 'channel +' */
-	{ 0x1e, KEY_VOLUMEDOWN },	/* 'volume -' */
-	{ 0x3e, KEY_VOLUMEUP },		/* 'volume +' */
-};
-
-struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
-	.scan = ir_codes_avermedia_dvbt,
-	.size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
-
-/* Mauro Carvalho Chehab <mchehab@infradead.org> */
-static struct ir_scancode ir_codes_avermedia_m135a[] = {
-	{ 0x00, KEY_POWER2 },
-	{ 0x2e, KEY_DOT },		/* '.' */
-	{ 0x01, KEY_MODE },		/* TV/FM */
-
-	{ 0x05, KEY_1 },
-	{ 0x06, KEY_2 },
-	{ 0x07, KEY_3 },
-	{ 0x09, KEY_4 },
-	{ 0x0a, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x0d, KEY_7 },
-	{ 0x0e, KEY_8 },
-	{ 0x0f, KEY_9 },
-	{ 0x11, KEY_0 },
-
-	{ 0x13, KEY_RIGHT },		/* -> */
-	{ 0x12, KEY_LEFT },		/* <- */
-
-	{ 0x17, KEY_SLEEP },		/* Capturar Imagem */
-	{ 0x10, KEY_SHUFFLE },		/* Amostra */
-
-	/* FIXME: The keys bellow aren't ok */
-
-	{ 0x43, KEY_CHANNELUP },
-	{ 0x42, KEY_CHANNELDOWN },
-	{ 0x1f, KEY_VOLUMEUP },
-	{ 0x1e, KEY_VOLUMEDOWN },
-	{ 0x0c, KEY_ENTER },
-
-	{ 0x14, KEY_MUTE },
-	{ 0x08, KEY_AUDIO },
-
-	{ 0x03, KEY_TEXT },
-	{ 0x04, KEY_EPG },
-	{ 0x2b, KEY_TV2 },		/* TV2 */
-
-	{ 0x1d, KEY_RED },
-	{ 0x1c, KEY_YELLOW },
-	{ 0x41, KEY_GREEN },
-	{ 0x40, KEY_BLUE },
-
-	{ 0x1a, KEY_PLAYPAUSE },
-	{ 0x19, KEY_RECORD },
-	{ 0x18, KEY_PLAY },
-	{ 0x1b, KEY_STOP },
-};
-
-struct ir_scancode_table ir_codes_avermedia_m135a_table = {
-	.scan = ir_codes_avermedia_m135a,
-	.size = ARRAY_SIZE(ir_codes_avermedia_m135a),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
-
-/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
-static struct ir_scancode ir_codes_avermedia_cardbus[] = {
-	{ 0x00, KEY_POWER },
-	{ 0x01, KEY_TUNER },		/* TV/FM */
-	{ 0x03, KEY_TEXT },		/* Teletext */
-	{ 0x04, KEY_EPG },
-	{ 0x05, KEY_1 },
-	{ 0x06, KEY_2 },
-	{ 0x07, KEY_3 },
-	{ 0x08, KEY_AUDIO },
-	{ 0x09, KEY_4 },
-	{ 0x0a, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x0c, KEY_ZOOM },		/* Full screen */
-	{ 0x0d, KEY_7 },
-	{ 0x0e, KEY_8 },
-	{ 0x0f, KEY_9 },
-	{ 0x10, KEY_PAGEUP },		/* 16-CH PREV */
-	{ 0x11, KEY_0 },
-	{ 0x12, KEY_INFO },
-	{ 0x13, KEY_AGAIN },		/* CH RTN - channel return */
-	{ 0x14, KEY_MUTE },
-	{ 0x15, KEY_EDIT },		/* Autoscan */
-	{ 0x17, KEY_SAVE },		/* Screenshot */
-	{ 0x18, KEY_PLAYPAUSE },
-	{ 0x19, KEY_RECORD },
-	{ 0x1a, KEY_PLAY },
-	{ 0x1b, KEY_STOP },
-	{ 0x1c, KEY_FASTFORWARD },
-	{ 0x1d, KEY_REWIND },
-	{ 0x1e, KEY_VOLUMEDOWN },
-	{ 0x1f, KEY_VOLUMEUP },
-	{ 0x22, KEY_SLEEP },		/* Sleep */
-	{ 0x23, KEY_ZOOM },		/* Aspect */
-	{ 0x26, KEY_SCREEN },		/* Pos */
-	{ 0x27, KEY_ANGLE },		/* Size */
-	{ 0x28, KEY_SELECT },		/* Select */
-	{ 0x29, KEY_BLUE },		/* Blue/Picture */
-	{ 0x2a, KEY_BACKSPACE },	/* Back */
-	{ 0x2b, KEY_MEDIA },		/* PIP (Picture-in-picture) */
-	{ 0x2c, KEY_DOWN },
-	{ 0x2e, KEY_DOT },
-	{ 0x2f, KEY_TV },		/* Live TV */
-	{ 0x32, KEY_LEFT },
-	{ 0x33, KEY_CLEAR },		/* Clear */
-	{ 0x35, KEY_RED },		/* Red/TV */
-	{ 0x36, KEY_UP },
-	{ 0x37, KEY_HOME },		/* Home */
-	{ 0x39, KEY_GREEN },		/* Green/Video */
-	{ 0x3d, KEY_YELLOW },		/* Yellow/Music */
-	{ 0x3e, KEY_OK },		/* Ok */
-	{ 0x3f, KEY_RIGHT },
-	{ 0x40, KEY_NEXT },		/* Next */
-	{ 0x41, KEY_PREVIOUS },		/* Previous */
-	{ 0x42, KEY_CHANNELDOWN },	/* Channel down */
-	{ 0x43, KEY_CHANNELUP },	/* Channel up */
-};
-
-struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
-	.scan = ir_codes_avermedia_cardbus,
-	.size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
-
-/* Attila Kondoros <attila.kondoros@chello.hu> */
-static struct ir_scancode ir_codes_apac_viewcomp[] = {
-
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-	{ 0x00, KEY_0 },
-	{ 0x17, KEY_LAST },		/* +100 */
-	{ 0x0a, KEY_LIST },		/* recall */
-
-
-	{ 0x1c, KEY_TUNER },		/* TV/FM */
-	{ 0x15, KEY_SEARCH },		/* scan */
-	{ 0x12, KEY_POWER },		/* power */
-	{ 0x1f, KEY_VOLUMEDOWN },	/* vol up */
-	{ 0x1b, KEY_VOLUMEUP },		/* vol down */
-	{ 0x1e, KEY_CHANNELDOWN },	/* chn up */
-	{ 0x1a, KEY_CHANNELUP },	/* chn down */
-
-	{ 0x11, KEY_VIDEO },		/* video */
-	{ 0x0f, KEY_ZOOM },		/* full screen */
-	{ 0x13, KEY_MUTE },		/* mute/unmute */
-	{ 0x10, KEY_TEXT },		/* min */
-
-	{ 0x0d, KEY_STOP },		/* freeze */
-	{ 0x0e, KEY_RECORD },		/* record */
-	{ 0x1d, KEY_PLAYPAUSE },	/* stop */
-	{ 0x19, KEY_PLAY },		/* play */
-
-	{ 0x16, KEY_GOTO },		/* osd */
-	{ 0x14, KEY_REFRESH },		/* default */
-	{ 0x0c, KEY_KPPLUS },		/* fine tune >>>> */
-	{ 0x18, KEY_KPMINUS },		/* fine tune <<<< */
-};
-
-struct ir_scancode_table ir_codes_apac_viewcomp_table = {
-	.scan = ir_codes_apac_viewcomp,
-	.size = ARRAY_SIZE(ir_codes_apac_viewcomp),
-};
-EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
-
-/* ---------------------------------------------------------------------- */
-
-static struct ir_scancode ir_codes_pixelview[] = {
-
-	{ 0x1e, KEY_POWER },	/* power */
-	{ 0x07, KEY_MEDIA },	/* source */
-	{ 0x1c, KEY_SEARCH },	/* scan */
-
-
-	{ 0x03, KEY_TUNER },		/* TV/FM */
-
-	{ 0x00, KEY_RECORD },
-	{ 0x08, KEY_STOP },
-	{ 0x11, KEY_PLAY },
-
-	{ 0x1a, KEY_PLAYPAUSE },	/* freeze */
-	{ 0x19, KEY_ZOOM },		/* zoom */
-	{ 0x0f, KEY_TEXT },		/* min */
-
-	{ 0x01, KEY_1 },
-	{ 0x0b, KEY_2 },
-	{ 0x1b, KEY_3 },
-	{ 0x05, KEY_4 },
-	{ 0x09, KEY_5 },
-	{ 0x15, KEY_6 },
-	{ 0x06, KEY_7 },
-	{ 0x0a, KEY_8 },
-	{ 0x12, KEY_9 },
-	{ 0x02, KEY_0 },
-	{ 0x10, KEY_LAST },		/* +100 */
-	{ 0x13, KEY_LIST },		/* recall */
-
-	{ 0x1f, KEY_CHANNELUP },	/* chn down */
-	{ 0x17, KEY_CHANNELDOWN },	/* chn up */
-	{ 0x16, KEY_VOLUMEUP },		/* vol down */
-	{ 0x14, KEY_VOLUMEDOWN },	/* vol up */
-
-	{ 0x04, KEY_KPMINUS },		/* <<< */
-	{ 0x0e, KEY_SETUP },		/* function */
-	{ 0x0c, KEY_KPPLUS },		/* >>> */
-
-	{ 0x0d, KEY_GOTO },		/* mts */
-	{ 0x1d, KEY_REFRESH },		/* reset */
-	{ 0x18, KEY_MUTE },		/* mute/unmute */
-};
-
-struct ir_scancode_table ir_codes_pixelview_table = {
-	.scan = ir_codes_pixelview,
-	.size = ARRAY_SIZE(ir_codes_pixelview),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
-
-/*
-   Mauro Carvalho Chehab <mchehab@infradead.org>
-   present on PV MPEG 8000GT
- */
-static struct ir_scancode ir_codes_pixelview_new[] = {
-	{ 0x3c, KEY_TIME },		/* Timeshift */
-	{ 0x12, KEY_POWER },
-
-	{ 0x3d, KEY_1 },
-	{ 0x38, KEY_2 },
-	{ 0x18, KEY_3 },
-	{ 0x35, KEY_4 },
-	{ 0x39, KEY_5 },
-	{ 0x15, KEY_6 },
-	{ 0x36, KEY_7 },
-	{ 0x3a, KEY_8 },
-	{ 0x1e, KEY_9 },
-	{ 0x3e, KEY_0 },
-
-	{ 0x1c, KEY_AGAIN },		/* LOOP	*/
-	{ 0x3f, KEY_MEDIA },		/* Source */
-	{ 0x1f, KEY_LAST },		/* +100 */
-	{ 0x1b, KEY_MUTE },
-
-	{ 0x17, KEY_CHANNELDOWN },
-	{ 0x16, KEY_CHANNELUP },
-	{ 0x10, KEY_VOLUMEUP },
-	{ 0x14, KEY_VOLUMEDOWN },
-	{ 0x13, KEY_ZOOM },
-
-	{ 0x19, KEY_CAMERA },		/* SNAPSHOT */
-	{ 0x1a, KEY_SEARCH },		/* scan */
-
-	{ 0x37, KEY_REWIND },		/* << */
-	{ 0x32, KEY_RECORD },		/* o (red) */
-	{ 0x33, KEY_FORWARD },		/* >> */
-	{ 0x11, KEY_STOP },		/* square */
-	{ 0x3b, KEY_PLAY },		/* > */
-	{ 0x30, KEY_PLAYPAUSE },	/* || */
-
-	{ 0x31, KEY_TV },
-	{ 0x34, KEY_RADIO },
-};
-
-struct ir_scancode_table ir_codes_pixelview_new_table = {
-	.scan = ir_codes_pixelview_new,
-	.size = ARRAY_SIZE(ir_codes_pixelview_new),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
-
-static struct ir_scancode ir_codes_nebula[] = {
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-	{ 0x0a, KEY_TV },
-	{ 0x0b, KEY_AUX },
-	{ 0x0c, KEY_DVD },
-	{ 0x0d, KEY_POWER },
-	{ 0x0e, KEY_MHP },	/* labelled 'Picture' */
-	{ 0x0f, KEY_AUDIO },
-	{ 0x10, KEY_INFO },
-	{ 0x11, KEY_F13 },	/* 16:9 */
-	{ 0x12, KEY_F14 },	/* 14:9 */
-	{ 0x13, KEY_EPG },
-	{ 0x14, KEY_EXIT },
-	{ 0x15, KEY_MENU },
-	{ 0x16, KEY_UP },
-	{ 0x17, KEY_DOWN },
-	{ 0x18, KEY_LEFT },
-	{ 0x19, KEY_RIGHT },
-	{ 0x1a, KEY_ENTER },
-	{ 0x1b, KEY_CHANNELUP },
-	{ 0x1c, KEY_CHANNELDOWN },
-	{ 0x1d, KEY_VOLUMEUP },
-	{ 0x1e, KEY_VOLUMEDOWN },
-	{ 0x1f, KEY_RED },
-	{ 0x20, KEY_GREEN },
-	{ 0x21, KEY_YELLOW },
-	{ 0x22, KEY_BLUE },
-	{ 0x23, KEY_SUBTITLE },
-	{ 0x24, KEY_F15 },	/* AD */
-	{ 0x25, KEY_TEXT },
-	{ 0x26, KEY_MUTE },
-	{ 0x27, KEY_REWIND },
-	{ 0x28, KEY_STOP },
-	{ 0x29, KEY_PLAY },
-	{ 0x2a, KEY_FASTFORWARD },
-	{ 0x2b, KEY_F16 },	/* chapter */
-	{ 0x2c, KEY_PAUSE },
-	{ 0x2d, KEY_PLAY },
-	{ 0x2e, KEY_RECORD },
-	{ 0x2f, KEY_F17 },	/* picture in picture */
-	{ 0x30, KEY_KPPLUS },	/* zoom in */
-	{ 0x31, KEY_KPMINUS },	/* zoom out */
-	{ 0x32, KEY_F18 },	/* capture */
-	{ 0x33, KEY_F19 },	/* web */
-	{ 0x34, KEY_EMAIL },
-	{ 0x35, KEY_PHONE },
-	{ 0x36, KEY_PC },
-};
-
-struct ir_scancode_table ir_codes_nebula_table = {
-	.scan = ir_codes_nebula,
-	.size = ARRAY_SIZE(ir_codes_nebula),
-};
-EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
-
-/* DigitalNow DNTV Live DVB-T Remote */
-static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
-	{ 0x00, KEY_ESC },		/* 'go up a level?' */
-	/* Keys 0 to 9 */
-	{ 0x0a, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0b, KEY_TUNER },		/* tv/fm */
-	{ 0x0c, KEY_SEARCH },		/* scan */
-	{ 0x0d, KEY_STOP },
-	{ 0x0e, KEY_PAUSE },
-	{ 0x0f, KEY_LIST },		/* source */
-
-	{ 0x10, KEY_MUTE },
-	{ 0x11, KEY_REWIND },		/* backward << */
-	{ 0x12, KEY_POWER },
-	{ 0x13, KEY_CAMERA },		/* snap */
-	{ 0x14, KEY_AUDIO },		/* stereo */
-	{ 0x15, KEY_CLEAR },		/* reset */
-	{ 0x16, KEY_PLAY },
-	{ 0x17, KEY_ENTER },
-	{ 0x18, KEY_ZOOM },		/* full screen */
-	{ 0x19, KEY_FASTFORWARD },	/* forward >> */
-	{ 0x1a, KEY_CHANNELUP },
-	{ 0x1b, KEY_VOLUMEUP },
-	{ 0x1c, KEY_INFO },		/* preview */
-	{ 0x1d, KEY_RECORD },		/* record */
-	{ 0x1e, KEY_CHANNELDOWN },
-	{ 0x1f, KEY_VOLUMEDOWN },
-};
-
-struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
-	.scan = ir_codes_dntv_live_dvb_t,
-	.size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
-};
-EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* IO-DATA BCTV7E Remote */
-static struct ir_scancode ir_codes_iodata_bctv7e[] = {
-	{ 0x40, KEY_TV },
-	{ 0x20, KEY_RADIO },		/* FM */
-	{ 0x60, KEY_EPG },
-	{ 0x00, KEY_POWER },
-
-	/* Keys 0 to 9 */
-	{ 0x44, KEY_0 },		/* 10 */
-	{ 0x50, KEY_1 },
-	{ 0x30, KEY_2 },
-	{ 0x70, KEY_3 },
-	{ 0x48, KEY_4 },
-	{ 0x28, KEY_5 },
-	{ 0x68, KEY_6 },
-	{ 0x58, KEY_7 },
-	{ 0x38, KEY_8 },
-	{ 0x78, KEY_9 },
-
-	{ 0x10, KEY_L },		/* Live */
-	{ 0x08, KEY_TIME },		/* Time Shift */
-
-	{ 0x18, KEY_PLAYPAUSE },	/* Play */
-
-	{ 0x24, KEY_ENTER },		/* 11 */
-	{ 0x64, KEY_ESC },		/* 12 */
-	{ 0x04, KEY_M },		/* Multi */
-
-	{ 0x54, KEY_VIDEO },
-	{ 0x34, KEY_CHANNELUP },
-	{ 0x74, KEY_VOLUMEUP },
-	{ 0x14, KEY_MUTE },
-
-	{ 0x4c, KEY_VCR },		/* SVIDEO */
-	{ 0x2c, KEY_CHANNELDOWN },
-	{ 0x6c, KEY_VOLUMEDOWN },
-	{ 0x0c, KEY_ZOOM },
-
-	{ 0x5c, KEY_PAUSE },
-	{ 0x3c, KEY_RED },		/* || (red) */
-	{ 0x7c, KEY_RECORD },		/* recording */
-	{ 0x1c, KEY_STOP },
-
-	{ 0x41, KEY_REWIND },		/* backward << */
-	{ 0x21, KEY_PLAY },
-	{ 0x61, KEY_FASTFORWARD },	/* forward >> */
-	{ 0x01, KEY_NEXT },		/* skip >| */
-};
-
-struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
-	.scan = ir_codes_iodata_bctv7e,
-	.size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
-};
-EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* ADS Tech Instant TV DVB-T PCI Remote */
-static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
-	/* Keys 0 to 9 */
-	{ 0x4d, KEY_0 },
-	{ 0x57, KEY_1 },
-	{ 0x4f, KEY_2 },
-	{ 0x53, KEY_3 },
-	{ 0x56, KEY_4 },
-	{ 0x4e, KEY_5 },
-	{ 0x5e, KEY_6 },
-	{ 0x54, KEY_7 },
-	{ 0x4c, KEY_8 },
-	{ 0x5c, KEY_9 },
-
-	{ 0x5b, KEY_POWER },
-	{ 0x5f, KEY_MUTE },
-	{ 0x55, KEY_GOTO },
-	{ 0x5d, KEY_SEARCH },
-	{ 0x17, KEY_EPG },		/* Guide */
-	{ 0x1f, KEY_MENU },
-	{ 0x0f, KEY_UP },
-	{ 0x46, KEY_DOWN },
-	{ 0x16, KEY_LEFT },
-	{ 0x1e, KEY_RIGHT },
-	{ 0x0e, KEY_SELECT },		/* Enter */
-	{ 0x5a, KEY_INFO },
-	{ 0x52, KEY_EXIT },
-	{ 0x59, KEY_PREVIOUS },
-	{ 0x51, KEY_NEXT },
-	{ 0x58, KEY_REWIND },
-	{ 0x50, KEY_FORWARD },
-	{ 0x44, KEY_PLAYPAUSE },
-	{ 0x07, KEY_STOP },
-	{ 0x1b, KEY_RECORD },
-	{ 0x13, KEY_TUNER },		/* Live */
-	{ 0x0a, KEY_A },
-	{ 0x12, KEY_B },
-	{ 0x03, KEY_PROG1 },		/* 1 */
-	{ 0x01, KEY_PROG2 },		/* 2 */
-	{ 0x00, KEY_PROG3 },		/* 3 */
-	{ 0x06, KEY_DVD },
-	{ 0x48, KEY_AUX },		/* Photo */
-	{ 0x40, KEY_VIDEO },
-	{ 0x19, KEY_AUDIO },		/* Music */
-	{ 0x0b, KEY_CHANNELUP },
-	{ 0x08, KEY_CHANNELDOWN },
-	{ 0x15, KEY_VOLUMEUP },
-	{ 0x1c, KEY_VOLUMEDOWN },
-};
-
-struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
-	.scan = ir_codes_adstech_dvb_t_pci,
-	.size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
-};
-EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* MSI TV@nywhere MASTER remote */
-
-static struct ir_scancode ir_codes_msi_tvanywhere[] = {
-	/* Keys 0 to 9 */
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0c, KEY_MUTE },
-	{ 0x0f, KEY_SCREEN },		/* Full Screen */
-	{ 0x10, KEY_FN },		/* Funtion */
-	{ 0x11, KEY_TIME },		/* Time shift */
-	{ 0x12, KEY_POWER },
-	{ 0x13, KEY_MEDIA },		/* MTS */
-	{ 0x14, KEY_SLOW },
-	{ 0x16, KEY_REWIND },		/* backward << */
-	{ 0x17, KEY_ENTER },		/* Return */
-	{ 0x18, KEY_FASTFORWARD },	/* forward >> */
-	{ 0x1a, KEY_CHANNELUP },
-	{ 0x1b, KEY_VOLUMEUP },
-	{ 0x1e, KEY_CHANNELDOWN },
-	{ 0x1f, KEY_VOLUMEDOWN },
-};
-
-struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
-	.scan = ir_codes_msi_tvanywhere,
-	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
-};
-EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
-
-/* ---------------------------------------------------------------------- */
-
-/*
-  Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
-  is marked "KS003". The controller is I2C at address 0x30, but does not seem
-  to respond to probes until a read is performed from a valid device.
-  I don't know why...
-
-  Note: This remote may be of similar or identical design to the
-  Pixelview remote (?).  The raw codes and duplicate button codes
-  appear to be the same.
-
-  Henry Wong <henry@stuffedcow.net>
-  Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
-
-*/
-
-static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
-
-/*  ---- Remote Button Layout ----
-
-    POWER   SOURCE  SCAN    MUTE
-    TV/FM   1       2       3
-    |>      4       5       6
-    <|      7       8       9
-    ^^UP    0       +       RECALL
-    vvDN    RECORD  STOP    PLAY
-
-	MINIMIZE          ZOOM
-
-		  CH+
-      VOL-                   VOL+
-		  CH-
-
-	SNAPSHOT           MTS
-
-     <<      FUNC    >>     RESET
-*/
-
-	{ 0x01, KEY_1 },		/* 1 */
-	{ 0x0b, KEY_2 },		/* 2 */
-	{ 0x1b, KEY_3 },		/* 3 */
-	{ 0x05, KEY_4 },		/* 4 */
-	{ 0x09, KEY_5 },		/* 5 */
-	{ 0x15, KEY_6 },		/* 6 */
-	{ 0x06, KEY_7 },		/* 7 */
-	{ 0x0a, KEY_8 },		/* 8 */
-	{ 0x12, KEY_9 },		/* 9 */
-	{ 0x02, KEY_0 },		/* 0 */
-	{ 0x10, KEY_KPPLUS },		/* + */
-	{ 0x13, KEY_AGAIN },		/* Recall */
-
-	{ 0x1e, KEY_POWER },		/* Power */
-	{ 0x07, KEY_TUNER },		/* Source */
-	{ 0x1c, KEY_SEARCH },		/* Scan */
-	{ 0x18, KEY_MUTE },		/* Mute */
-
-	{ 0x03, KEY_RADIO },		/* TV/FM */
-	/* The next four keys are duplicates that appear to send the
-	   same IR code as Ch+, Ch-, >>, and << .  The raw code assigned
-	   to them is the actual code + 0x20 - they will never be
-	   detected as such unless some way is discovered to distinguish
-	   these buttons from those that have the same code. */
-	{ 0x3f, KEY_RIGHT },		/* |> and Ch+ */
-	{ 0x37, KEY_LEFT },		/* <| and Ch- */
-	{ 0x2c, KEY_UP },		/* ^^Up and >> */
-	{ 0x24, KEY_DOWN },		/* vvDn and << */
-
-	{ 0x00, KEY_RECORD },		/* Record */
-	{ 0x08, KEY_STOP },		/* Stop */
-	{ 0x11, KEY_PLAY },		/* Play */
-
-	{ 0x0f, KEY_CLOSE },		/* Minimize */
-	{ 0x19, KEY_ZOOM },		/* Zoom */
-	{ 0x1a, KEY_CAMERA },		/* Snapshot */
-	{ 0x0d, KEY_LANGUAGE },		/* MTS */
-
-	{ 0x14, KEY_VOLUMEDOWN },	/* Vol- */
-	{ 0x16, KEY_VOLUMEUP },		/* Vol+ */
-	{ 0x17, KEY_CHANNELDOWN },	/* Ch- */
-	{ 0x1f, KEY_CHANNELUP },	/* Ch+ */
-
-	{ 0x04, KEY_REWIND },		/* << */
-	{ 0x0e, KEY_MENU },		/* Function */
-	{ 0x0c, KEY_FASTFORWARD },	/* >> */
-	{ 0x1d, KEY_RESTART },		/* Reset */
-};
-
-struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
-	.scan = ir_codes_msi_tvanywhere_plus,
-	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
-};
-EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* Cinergy 1400 DVB-T */
-static struct ir_scancode ir_codes_cinergy_1400[] = {
-	{ 0x01, KEY_POWER },
-	{ 0x02, KEY_1 },
-	{ 0x03, KEY_2 },
-	{ 0x04, KEY_3 },
-	{ 0x05, KEY_4 },
-	{ 0x06, KEY_5 },
-	{ 0x07, KEY_6 },
-	{ 0x08, KEY_7 },
-	{ 0x09, KEY_8 },
-	{ 0x0a, KEY_9 },
-	{ 0x0c, KEY_0 },
-
-	{ 0x0b, KEY_VIDEO },
-	{ 0x0d, KEY_REFRESH },
-	{ 0x0e, KEY_SELECT },
-	{ 0x0f, KEY_EPG },
-	{ 0x10, KEY_UP },
-	{ 0x11, KEY_LEFT },
-	{ 0x12, KEY_OK },
-	{ 0x13, KEY_RIGHT },
-	{ 0x14, KEY_DOWN },
-	{ 0x15, KEY_TEXT },
-	{ 0x16, KEY_INFO },
-
-	{ 0x17, KEY_RED },
-	{ 0x18, KEY_GREEN },
-	{ 0x19, KEY_YELLOW },
-	{ 0x1a, KEY_BLUE },
-
-	{ 0x1b, KEY_CHANNELUP },
-	{ 0x1c, KEY_VOLUMEUP },
-	{ 0x1d, KEY_MUTE },
-	{ 0x1e, KEY_VOLUMEDOWN },
-	{ 0x1f, KEY_CHANNELDOWN },
-
-	{ 0x40, KEY_PAUSE },
-	{ 0x4c, KEY_PLAY },
-	{ 0x58, KEY_RECORD },
-	{ 0x54, KEY_PREVIOUS },
-	{ 0x48, KEY_STOP },
-	{ 0x5c, KEY_NEXT },
-};
-
-struct ir_scancode_table ir_codes_cinergy_1400_table = {
-	.scan = ir_codes_cinergy_1400,
-	.size = ARRAY_SIZE(ir_codes_cinergy_1400),
-};
-EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* AVERTV STUDIO 303 Remote */
-static struct ir_scancode ir_codes_avertv_303[] = {
-	{ 0x2a, KEY_1 },
-	{ 0x32, KEY_2 },
-	{ 0x3a, KEY_3 },
-	{ 0x4a, KEY_4 },
-	{ 0x52, KEY_5 },
-	{ 0x5a, KEY_6 },
-	{ 0x6a, KEY_7 },
-	{ 0x72, KEY_8 },
-	{ 0x7a, KEY_9 },
-	{ 0x0e, KEY_0 },
-
-	{ 0x02, KEY_POWER },
-	{ 0x22, KEY_VIDEO },
-	{ 0x42, KEY_AUDIO },
-	{ 0x62, KEY_ZOOM },
-	{ 0x0a, KEY_TV },
-	{ 0x12, KEY_CD },
-	{ 0x1a, KEY_TEXT },
-
-	{ 0x16, KEY_SUBTITLE },
-	{ 0x1e, KEY_REWIND },
-	{ 0x06, KEY_PRINT },
-
-	{ 0x2e, KEY_SEARCH },
-	{ 0x36, KEY_SLEEP },
-	{ 0x3e, KEY_SHUFFLE },
-	{ 0x26, KEY_MUTE },
-
-	{ 0x4e, KEY_RECORD },
-	{ 0x56, KEY_PAUSE },
-	{ 0x5e, KEY_STOP },
-	{ 0x46, KEY_PLAY },
-
-	{ 0x6e, KEY_RED },
-	{ 0x0b, KEY_GREEN },
-	{ 0x66, KEY_YELLOW },
-	{ 0x03, KEY_BLUE },
-
-	{ 0x76, KEY_LEFT },
-	{ 0x7e, KEY_RIGHT },
-	{ 0x13, KEY_DOWN },
-	{ 0x1b, KEY_UP },
-};
-
-struct ir_scancode_table ir_codes_avertv_303_table = {
-	.scan = ir_codes_avertv_303,
-	.size = ARRAY_SIZE(ir_codes_avertv_303),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
-
-/* ---------------------------------------------------------------------- */
-
-/* DigitalNow DNTV Live! DVB-T Pro Remote */
-static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
-	{ 0x16, KEY_POWER },
-	{ 0x5b, KEY_HOME },
-
-	{ 0x55, KEY_TV },		/* live tv */
-	{ 0x58, KEY_TUNER },		/* digital Radio */
-	{ 0x5a, KEY_RADIO },		/* FM radio */
-	{ 0x59, KEY_DVD },		/* dvd menu */
-	{ 0x03, KEY_1 },
-	{ 0x01, KEY_2 },
-	{ 0x06, KEY_3 },
-	{ 0x09, KEY_4 },
-	{ 0x1d, KEY_5 },
-	{ 0x1f, KEY_6 },
-	{ 0x0d, KEY_7 },
-	{ 0x19, KEY_8 },
-	{ 0x1b, KEY_9 },
-	{ 0x0c, KEY_CANCEL },
-	{ 0x15, KEY_0 },
-	{ 0x4a, KEY_CLEAR },
-	{ 0x13, KEY_BACK },
-	{ 0x00, KEY_TAB },
-	{ 0x4b, KEY_UP },
-	{ 0x4e, KEY_LEFT },
-	{ 0x4f, KEY_OK },
-	{ 0x52, KEY_RIGHT },
-	{ 0x51, KEY_DOWN },
-	{ 0x1e, KEY_VOLUMEUP },
-	{ 0x0a, KEY_VOLUMEDOWN },
-	{ 0x02, KEY_CHANNELDOWN },
-	{ 0x05, KEY_CHANNELUP },
-	{ 0x11, KEY_RECORD },
-	{ 0x14, KEY_PLAY },
-	{ 0x4c, KEY_PAUSE },
-	{ 0x1a, KEY_STOP },
-	{ 0x40, KEY_REWIND },
-	{ 0x12, KEY_FASTFORWARD },
-	{ 0x41, KEY_PREVIOUSSONG },	/* replay |< */
-	{ 0x42, KEY_NEXTSONG },		/* skip >| */
-	{ 0x54, KEY_CAMERA },		/* capture */
-	{ 0x50, KEY_LANGUAGE },		/* sap */
-	{ 0x47, KEY_TV2 },		/* pip */
-	{ 0x4d, KEY_SCREEN },
-	{ 0x43, KEY_SUBTITLE },
-	{ 0x10, KEY_MUTE },
-	{ 0x49, KEY_AUDIO },		/* l/r */
-	{ 0x07, KEY_SLEEP },
-	{ 0x08, KEY_VIDEO },		/* a/v */
-	{ 0x0e, KEY_PREVIOUS },		/* recall */
-	{ 0x45, KEY_ZOOM },		/* zoom + */
-	{ 0x46, KEY_ANGLE },		/* zoom - */
-	{ 0x56, KEY_RED },
-	{ 0x57, KEY_GREEN },
-	{ 0x5c, KEY_YELLOW },
-	{ 0x5d, KEY_BLUE },
-};
-
-struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
-	.scan = ir_codes_dntv_live_dvbt_pro,
-	.size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
-};
-EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
-
-static struct ir_scancode ir_codes_em_terratec[] = {
-	{ 0x01, KEY_CHANNEL },
-	{ 0x02, KEY_SELECT },
-	{ 0x03, KEY_MUTE },
-	{ 0x04, KEY_POWER },
-	{ 0x05, KEY_1 },
-	{ 0x06, KEY_2 },
-	{ 0x07, KEY_3 },
-	{ 0x08, KEY_CHANNELUP },
-	{ 0x09, KEY_4 },
-	{ 0x0a, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x0c, KEY_CHANNELDOWN },
-	{ 0x0d, KEY_7 },
-	{ 0x0e, KEY_8 },
-	{ 0x0f, KEY_9 },
-	{ 0x10, KEY_VOLUMEUP },
-	{ 0x11, KEY_0 },
-	{ 0x12, KEY_MENU },
-	{ 0x13, KEY_PRINT },
-	{ 0x14, KEY_VOLUMEDOWN },
-	{ 0x16, KEY_PAUSE },
-	{ 0x18, KEY_RECORD },
-	{ 0x19, KEY_REWIND },
-	{ 0x1a, KEY_PLAY },
-	{ 0x1b, KEY_FORWARD },
-	{ 0x1c, KEY_BACKSPACE },
-	{ 0x1e, KEY_STOP },
-	{ 0x40, KEY_ZOOM },
-};
-
-struct ir_scancode_table ir_codes_em_terratec_table = {
-	.scan = ir_codes_em_terratec,
-	.size = ARRAY_SIZE(ir_codes_em_terratec),
-};
-EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
-
-static struct ir_scancode ir_codes_pinnacle_grey[] = {
-	{ 0x3a, KEY_0 },
-	{ 0x31, KEY_1 },
-	{ 0x32, KEY_2 },
-	{ 0x33, KEY_3 },
-	{ 0x34, KEY_4 },
-	{ 0x35, KEY_5 },
-	{ 0x36, KEY_6 },
-	{ 0x37, KEY_7 },
-	{ 0x38, KEY_8 },
-	{ 0x39, KEY_9 },
-
-	{ 0x2f, KEY_POWER },
-
-	{ 0x2e, KEY_P },
-	{ 0x1f, KEY_L },
-	{ 0x2b, KEY_I },
-
-	{ 0x2d, KEY_SCREEN },
-	{ 0x1e, KEY_ZOOM },
-	{ 0x1b, KEY_VOLUMEUP },
-	{ 0x0f, KEY_VOLUMEDOWN },
-	{ 0x17, KEY_CHANNELUP },
-	{ 0x1c, KEY_CHANNELDOWN },
-	{ 0x25, KEY_INFO },
-
-	{ 0x3c, KEY_MUTE },
-
-	{ 0x3d, KEY_LEFT },
-	{ 0x3b, KEY_RIGHT },
-
-	{ 0x3f, KEY_UP },
-	{ 0x3e, KEY_DOWN },
-	{ 0x1a, KEY_ENTER },
-
-	{ 0x1d, KEY_MENU },
-	{ 0x19, KEY_AGAIN },
-	{ 0x16, KEY_PREVIOUSSONG },
-	{ 0x13, KEY_NEXTSONG },
-	{ 0x15, KEY_PAUSE },
-	{ 0x0e, KEY_REWIND },
-	{ 0x0d, KEY_PLAY },
-	{ 0x0b, KEY_STOP },
-	{ 0x07, KEY_FORWARD },
-	{ 0x27, KEY_RECORD },
-	{ 0x26, KEY_TUNER },
-	{ 0x29, KEY_TEXT },
-	{ 0x2a, KEY_MEDIA },
-	{ 0x18, KEY_EPG },
-};
-
-struct ir_scancode_table ir_codes_pinnacle_grey_table = {
-	.scan = ir_codes_pinnacle_grey,
-	.size = ARRAY_SIZE(ir_codes_pinnacle_grey),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
-
-static struct ir_scancode ir_codes_flyvideo[] = {
-	{ 0x0f, KEY_0 },
-	{ 0x03, KEY_1 },
-	{ 0x04, KEY_2 },
-	{ 0x05, KEY_3 },
-	{ 0x07, KEY_4 },
-	{ 0x08, KEY_5 },
-	{ 0x09, KEY_6 },
-	{ 0x0b, KEY_7 },
-	{ 0x0c, KEY_8 },
-	{ 0x0d, KEY_9 },
-
-	{ 0x0e, KEY_MODE },	/* Air/Cable */
-	{ 0x11, KEY_VIDEO },	/* Video */
-	{ 0x15, KEY_AUDIO },	/* Audio */
-	{ 0x00, KEY_POWER },	/* Power */
-	{ 0x18, KEY_TUNER },	/* AV Source */
-	{ 0x02, KEY_ZOOM },	/* Fullscreen */
-	{ 0x1a, KEY_LANGUAGE },	/* Stereo */
-	{ 0x1b, KEY_MUTE },	/* Mute */
-	{ 0x14, KEY_VOLUMEUP },	/* Volume + */
-	{ 0x17, KEY_VOLUMEDOWN },/* Volume - */
-	{ 0x12, KEY_CHANNELUP },/* Channel + */
-	{ 0x13, KEY_CHANNELDOWN },/* Channel - */
-	{ 0x06, KEY_AGAIN },	/* Recall */
-	{ 0x10, KEY_ENTER },	/* Enter */
-
-	{ 0x19, KEY_BACK },	/* Rewind  ( <<< ) */
-	{ 0x1f, KEY_FORWARD },	/* Forward ( >>> ) */
-	{ 0x0a, KEY_ANGLE },	/* no label, may be used as the PAUSE button */
-};
-
-struct ir_scancode_table ir_codes_flyvideo_table = {
-	.scan = ir_codes_flyvideo,
-	.size = ARRAY_SIZE(ir_codes_flyvideo),
-};
-EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
-
-static struct ir_scancode ir_codes_flydvb[] = {
-	{ 0x01, KEY_ZOOM },		/* Full Screen */
-	{ 0x00, KEY_POWER },		/* Power */
-
-	{ 0x03, KEY_1 },
-	{ 0x04, KEY_2 },
-	{ 0x05, KEY_3 },
-	{ 0x07, KEY_4 },
-	{ 0x08, KEY_5 },
-	{ 0x09, KEY_6 },
-	{ 0x0b, KEY_7 },
-	{ 0x0c, KEY_8 },
-	{ 0x0d, KEY_9 },
-	{ 0x06, KEY_AGAIN },		/* Recall */
-	{ 0x0f, KEY_0 },
-	{ 0x10, KEY_MUTE },		/* Mute */
-	{ 0x02, KEY_RADIO },		/* TV/Radio */
-	{ 0x1b, KEY_LANGUAGE },		/* SAP (Second Audio Program) */
-
-	{ 0x14, KEY_VOLUMEUP },		/* VOL+ */
-	{ 0x17, KEY_VOLUMEDOWN },	/* VOL- */
-	{ 0x12, KEY_CHANNELUP },	/* CH+ */
-	{ 0x13, KEY_CHANNELDOWN },	/* CH- */
-	{ 0x1d, KEY_ENTER },		/* Enter */
-
-	{ 0x1a, KEY_MODE },		/* PIP */
-	{ 0x18, KEY_TUNER },		/* Source */
-
-	{ 0x1e, KEY_RECORD },		/* Record/Pause */
-	{ 0x15, KEY_ANGLE },		/* Swap (no label on key) */
-	{ 0x1c, KEY_PAUSE },		/* Timeshift/Pause */
-	{ 0x19, KEY_BACK },		/* Rewind << */
-	{ 0x0a, KEY_PLAYPAUSE },	/* Play/Pause */
-	{ 0x1f, KEY_FORWARD },		/* Forward >> */
-	{ 0x16, KEY_PREVIOUS },		/* Back |<< */
-	{ 0x11, KEY_STOP },		/* Stop */
-	{ 0x0e, KEY_NEXT },		/* End >>| */
-};
-
-struct ir_scancode_table ir_codes_flydvb_table = {
-	.scan = ir_codes_flydvb,
-	.size = ARRAY_SIZE(ir_codes_flydvb),
-};
-EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
-
-static struct ir_scancode ir_codes_cinergy[] = {
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0a, KEY_POWER },
-	{ 0x0b, KEY_PROG1 },		/* app */
-	{ 0x0c, KEY_ZOOM },		/* zoom/fullscreen */
-	{ 0x0d, KEY_CHANNELUP },	/* channel */
-	{ 0x0e, KEY_CHANNELDOWN },	/* channel- */
-	{ 0x0f, KEY_VOLUMEUP },
-	{ 0x10, KEY_VOLUMEDOWN },
-	{ 0x11, KEY_TUNER },		/* AV */
-	{ 0x12, KEY_NUMLOCK },		/* -/-- */
-	{ 0x13, KEY_AUDIO },		/* audio */
-	{ 0x14, KEY_MUTE },
-	{ 0x15, KEY_UP },
-	{ 0x16, KEY_DOWN },
-	{ 0x17, KEY_LEFT },
-	{ 0x18, KEY_RIGHT },
-	{ 0x19, BTN_LEFT, },
-	{ 0x1a, BTN_RIGHT, },
-	{ 0x1b, KEY_WWW },		/* text */
-	{ 0x1c, KEY_REWIND },
-	{ 0x1d, KEY_FORWARD },
-	{ 0x1e, KEY_RECORD },
-	{ 0x1f, KEY_PLAY },
-	{ 0x20, KEY_PREVIOUSSONG },
-	{ 0x21, KEY_NEXTSONG },
-	{ 0x22, KEY_PAUSE },
-	{ 0x23, KEY_STOP },
-};
-
-struct ir_scancode_table ir_codes_cinergy_table = {
-	.scan = ir_codes_cinergy,
-	.size = ARRAY_SIZE(ir_codes_cinergy),
-};
-EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
-
-/* Alfons Geser <a.geser@cox.net>
- * updates from Job D. R. Borges <jobdrb@ig.com.br> */
-static struct ir_scancode ir_codes_eztv[] = {
-	{ 0x12, KEY_POWER },
-	{ 0x01, KEY_TV },	/* DVR */
-	{ 0x15, KEY_DVD },	/* DVD */
-	{ 0x17, KEY_AUDIO },	/* music */
-				/* DVR mode / DVD mode / music mode */
-
-	{ 0x1b, KEY_MUTE },	/* mute */
-	{ 0x02, KEY_LANGUAGE },	/* MTS/SAP / audio / autoseek */
-	{ 0x1e, KEY_SUBTITLE },	/* closed captioning / subtitle / seek */
-	{ 0x16, KEY_ZOOM },	/* full screen */
-	{ 0x1c, KEY_VIDEO },	/* video source / eject / delall */
-	{ 0x1d, KEY_RESTART },	/* playback / angle / del */
-	{ 0x2f, KEY_SEARCH },	/* scan / menu / playlist */
-	{ 0x30, KEY_CHANNEL },	/* CH surfing / bookmark / memo */
-
-	{ 0x31, KEY_HELP },	/* help */
-	{ 0x32, KEY_MODE },	/* num/memo */
-	{ 0x33, KEY_ESC },	/* cancel */
-
-	{ 0x0c, KEY_UP },	/* up */
-	{ 0x10, KEY_DOWN },	/* down */
-	{ 0x08, KEY_LEFT },	/* left */
-	{ 0x04, KEY_RIGHT },	/* right */
-	{ 0x03, KEY_SELECT },	/* select */
-
-	{ 0x1f, KEY_REWIND },	/* rewind */
-	{ 0x20, KEY_PLAYPAUSE },/* play/pause */
-	{ 0x29, KEY_FORWARD },	/* forward */
-	{ 0x14, KEY_AGAIN },	/* repeat */
-	{ 0x2b, KEY_RECORD },	/* recording */
-	{ 0x2c, KEY_STOP },	/* stop */
-	{ 0x2d, KEY_PLAY },	/* play */
-	{ 0x2e, KEY_CAMERA },	/* snapshot / shuffle */
-
-	{ 0x00, KEY_0 },
-	{ 0x05, KEY_1 },
-	{ 0x06, KEY_2 },
-	{ 0x07, KEY_3 },
-	{ 0x09, KEY_4 },
-	{ 0x0a, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x0d, KEY_7 },
-	{ 0x0e, KEY_8 },
-	{ 0x0f, KEY_9 },
-
-	{ 0x2a, KEY_VOLUMEUP },
-	{ 0x11, KEY_VOLUMEDOWN },
-	{ 0x18, KEY_CHANNELUP },/* CH.tracking up */
-	{ 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
-
-	{ 0x13, KEY_ENTER },	/* enter */
-	{ 0x21, KEY_DOT },	/* . (decimal dot) */
-};
-
-struct ir_scancode_table ir_codes_eztv_table = {
-	.scan = ir_codes_eztv,
-	.size = ARRAY_SIZE(ir_codes_eztv),
-};
-EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
-
-/* Alex Hermann <gaaf@gmx.net> */
-static struct ir_scancode ir_codes_avermedia[] = {
-	{ 0x28, KEY_1 },
-	{ 0x18, KEY_2 },
-	{ 0x38, KEY_3 },
-	{ 0x24, KEY_4 },
-	{ 0x14, KEY_5 },
-	{ 0x34, KEY_6 },
-	{ 0x2c, KEY_7 },
-	{ 0x1c, KEY_8 },
-	{ 0x3c, KEY_9 },
-	{ 0x22, KEY_0 },
-
-	{ 0x20, KEY_TV },		/* TV/FM */
-	{ 0x10, KEY_CD },		/* CD */
-	{ 0x30, KEY_TEXT },		/* TELETEXT */
-	{ 0x00, KEY_POWER },		/* POWER */
-
-	{ 0x08, KEY_VIDEO },		/* VIDEO */
-	{ 0x04, KEY_AUDIO },		/* AUDIO */
-	{ 0x0c, KEY_ZOOM },		/* FULL SCREEN */
-
-	{ 0x12, KEY_SUBTITLE },		/* DISPLAY */
-	{ 0x32, KEY_REWIND },		/* LOOP	*/
-	{ 0x02, KEY_PRINT },		/* PREVIEW */
-
-	{ 0x2a, KEY_SEARCH },		/* AUTOSCAN */
-	{ 0x1a, KEY_SLEEP },		/* FREEZE */
-	{ 0x3a, KEY_CAMERA },		/* SNAPSHOT */
-	{ 0x0a, KEY_MUTE },		/* MUTE */
-
-	{ 0x26, KEY_RECORD },		/* RECORD */
-	{ 0x16, KEY_PAUSE },		/* PAUSE */
-	{ 0x36, KEY_STOP },		/* STOP */
-	{ 0x06, KEY_PLAY },		/* PLAY */
-
-	{ 0x2e, KEY_RED },		/* RED */
-	{ 0x21, KEY_GREEN },		/* GREEN */
-	{ 0x0e, KEY_YELLOW },		/* YELLOW */
-	{ 0x01, KEY_BLUE },		/* BLUE */
-
-	{ 0x1e, KEY_VOLUMEDOWN },	/* VOLUME- */
-	{ 0x3e, KEY_VOLUMEUP },		/* VOLUME+ */
-	{ 0x11, KEY_CHANNELDOWN },	/* CHANNEL/PAGE- */
-	{ 0x31, KEY_CHANNELUP }		/* CHANNEL/PAGE+ */
-};
-
-struct ir_scancode_table ir_codes_avermedia_table = {
-	.scan = ir_codes_avermedia,
-	.size = ARRAY_SIZE(ir_codes_avermedia),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
-
-static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
-	{ 0x14, KEY_MUTE },
-	{ 0x24, KEY_ZOOM },
-
-	{ 0x01, KEY_DVD },
-	{ 0x23, KEY_RADIO },
-	{ 0x00, KEY_TV },
-
-	{ 0x0a, KEY_REWIND },
-	{ 0x08, KEY_PLAYPAUSE },
-	{ 0x0f, KEY_FORWARD },
-
-	{ 0x02, KEY_PREVIOUS },
-	{ 0x07, KEY_STOP },
-	{ 0x06, KEY_NEXT },
-
-	{ 0x0c, KEY_UP },
-	{ 0x0e, KEY_DOWN },
-	{ 0x0b, KEY_LEFT },
-	{ 0x0d, KEY_RIGHT },
-	{ 0x11, KEY_OK },
-
-	{ 0x03, KEY_MENU },
-	{ 0x09, KEY_SETUP },
-	{ 0x05, KEY_VIDEO },
-	{ 0x22, KEY_CHANNEL },
-
-	{ 0x12, KEY_VOLUMEUP },
-	{ 0x15, KEY_VOLUMEDOWN },
-	{ 0x10, KEY_CHANNELUP },
-	{ 0x13, KEY_CHANNELDOWN },
-
-	{ 0x04, KEY_RECORD },
-
-	{ 0x16, KEY_1 },
-	{ 0x17, KEY_2 },
-	{ 0x18, KEY_3 },
-	{ 0x19, KEY_4 },
-	{ 0x1a, KEY_5 },
-	{ 0x1b, KEY_6 },
-	{ 0x1c, KEY_7 },
-	{ 0x1d, KEY_8 },
-	{ 0x1e, KEY_9 },
-	{ 0x1f, KEY_0 },
-
-	{ 0x20, KEY_LANGUAGE },
-	{ 0x21, KEY_SLEEP },
-};
-
-struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
-	.scan = ir_codes_videomate_tv_pvr,
-	.size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
-};
-EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
-
-/* Michael Tokarev <mjt@tls.msk.ru>
-   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
-   keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
-   least, and probably other cards too.
-   The "ascii-art picture" below (in comments, first row
-   is the keycode in hex, and subsequent row(s) shows
-   the button labels (several variants when appropriate)
-   helps to descide which keycodes to assign to the buttons.
- */
-static struct ir_scancode ir_codes_manli[] = {
-
-	/*  0x1c            0x12  *
-	 * FUNCTION         POWER *
-	 *   FM              (|)  *
-	 *                        */
-	{ 0x1c, KEY_RADIO },	/*XXX*/
-	{ 0x12, KEY_POWER },
-
-	/*  0x01    0x02    0x03  *
-	 *   1       2       3    *
-	 *                        *
-	 *  0x04    0x05    0x06  *
-	 *   4       5       6    *
-	 *                        *
-	 *  0x07    0x08    0x09  *
-	 *   7       8       9    *
-	 *                        */
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	/*  0x0a    0x00    0x17  *
-	 * RECALL    0      +100  *
-	 *                  PLUS  *
-	 *                        */
-	{ 0x0a, KEY_AGAIN },	/*XXX KEY_REWIND? */
-	{ 0x00, KEY_0 },
-	{ 0x17, KEY_DIGITS },	/*XXX*/
-
-	/*  0x14            0x10  *
-	 *  MENU            INFO  *
-	 *  OSD                   */
-	{ 0x14, KEY_MENU },
-	{ 0x10, KEY_INFO },
-
-	/*          0x0b          *
-	 *           Up           *
-	 *                        *
-	 *  0x18    0x16    0x0c  *
-	 *  Left     Ok     Right *
-	 *                        *
-	 *         0x015          *
-	 *         Down           *
-	 *                        */
-	{ 0x0b, KEY_UP },
-	{ 0x18, KEY_LEFT },
-	{ 0x16, KEY_OK },	/*XXX KEY_SELECT? KEY_ENTER? */
-	{ 0x0c, KEY_RIGHT },
-	{ 0x15, KEY_DOWN },
-
-	/*  0x11            0x0d  *
-	 *  TV/AV           MODE  *
-	 *  SOURCE         STEREO *
-	 *                        */
-	{ 0x11, KEY_TV },	/*XXX*/
-	{ 0x0d, KEY_MODE },	/*XXX there's no KEY_STEREO	*/
-
-	/*  0x0f    0x1b    0x1a  *
-	 *  AUDIO   Vol+    Chan+ *
-	 *        TIMESHIFT???    *
-	 *                        *
-	 *  0x0e    0x1f    0x1e  *
-	 *  SLEEP   Vol-    Chan- *
-	 *                        */
-	{ 0x0f, KEY_AUDIO },
-	{ 0x1b, KEY_VOLUMEUP },
-	{ 0x1a, KEY_CHANNELUP },
-	{ 0x0e, KEY_TIME },
-	{ 0x1f, KEY_VOLUMEDOWN },
-	{ 0x1e, KEY_CHANNELDOWN },
-
-	/*         0x13     0x19  *
-	 *         MUTE   SNAPSHOT*
-	 *                        */
-	{ 0x13, KEY_MUTE },
-	{ 0x19, KEY_CAMERA },
-
-	/* 0x1d unused ? */
-};
-
-struct ir_scancode_table ir_codes_manli_table = {
-	.scan = ir_codes_manli,
-	.size = ARRAY_SIZE(ir_codes_manli),
-};
-EXPORT_SYMBOL_GPL(ir_codes_manli_table);
-
-/* Mike Baikov <mike@baikov.com> */
-static struct ir_scancode ir_codes_gotview7135[] = {
-
-	{ 0x11, KEY_POWER },
-	{ 0x35, KEY_TV },
-	{ 0x1b, KEY_0 },
-	{ 0x29, KEY_1 },
-	{ 0x19, KEY_2 },
-	{ 0x39, KEY_3 },
-	{ 0x1f, KEY_4 },
-	{ 0x2c, KEY_5 },
-	{ 0x21, KEY_6 },
-	{ 0x24, KEY_7 },
-	{ 0x18, KEY_8 },
-	{ 0x2b, KEY_9 },
-	{ 0x3b, KEY_AGAIN },	/* LOOP */
-	{ 0x06, KEY_AUDIO },
-	{ 0x31, KEY_PRINT },	/* PREVIEW */
-	{ 0x3e, KEY_VIDEO },
-	{ 0x10, KEY_CHANNELUP },
-	{ 0x20, KEY_CHANNELDOWN },
-	{ 0x0c, KEY_VOLUMEDOWN },
-	{ 0x28, KEY_VOLUMEUP },
-	{ 0x08, KEY_MUTE },
-	{ 0x26, KEY_SEARCH },	/* SCAN */
-	{ 0x3f, KEY_CAMERA },	/* SNAPSHOT */
-	{ 0x12, KEY_RECORD },
-	{ 0x32, KEY_STOP },
-	{ 0x3c, KEY_PLAY },
-	{ 0x1d, KEY_REWIND },
-	{ 0x2d, KEY_PAUSE },
-	{ 0x0d, KEY_FORWARD },
-	{ 0x05, KEY_ZOOM },	/*FULL*/
-
-	{ 0x2a, KEY_F21 },	/* LIVE TIMESHIFT */
-	{ 0x0e, KEY_F22 },	/* MIN TIMESHIFT */
-	{ 0x1e, KEY_TIME },	/* TIMESHIFT */
-	{ 0x38, KEY_F24 },	/* NORMAL TIMESHIFT */
-};
-
-struct ir_scancode_table ir_codes_gotview7135_table = {
-	.scan = ir_codes_gotview7135,
-	.size = ARRAY_SIZE(ir_codes_gotview7135),
-};
-EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
-
-static struct ir_scancode ir_codes_purpletv[] = {
-	{ 0x03, KEY_POWER },
-	{ 0x6f, KEY_MUTE },
-	{ 0x10, KEY_BACKSPACE },	/* Recall */
-
-	{ 0x11, KEY_0 },
-	{ 0x04, KEY_1 },
-	{ 0x05, KEY_2 },
-	{ 0x06, KEY_3 },
-	{ 0x08, KEY_4 },
-	{ 0x09, KEY_5 },
-	{ 0x0a, KEY_6 },
-	{ 0x0c, KEY_7 },
-	{ 0x0d, KEY_8 },
-	{ 0x0e, KEY_9 },
-	{ 0x12, KEY_DOT },	/* 100+ */
-
-	{ 0x07, KEY_VOLUMEUP },
-	{ 0x0b, KEY_VOLUMEDOWN },
-	{ 0x1a, KEY_KPPLUS },
-	{ 0x18, KEY_KPMINUS },
-	{ 0x15, KEY_UP },
-	{ 0x1d, KEY_DOWN },
-	{ 0x0f, KEY_CHANNELUP },
-	{ 0x13, KEY_CHANNELDOWN },
-	{ 0x48, KEY_ZOOM },
-
-	{ 0x1b, KEY_VIDEO },	/* Video source */
-	{ 0x1f, KEY_CAMERA },	/* Snapshot */
-	{ 0x49, KEY_LANGUAGE },	/* MTS Select */
-	{ 0x19, KEY_SEARCH },	/* Auto Scan */
-
-	{ 0x4b, KEY_RECORD },
-	{ 0x46, KEY_PLAY },
-	{ 0x45, KEY_PAUSE },	/* Pause */
-	{ 0x44, KEY_STOP },
-	{ 0x43, KEY_TIME },	/* Time Shift */
-	{ 0x17, KEY_CHANNEL },	/* SURF CH */
-	{ 0x40, KEY_FORWARD },	/* Forward ? */
-	{ 0x42, KEY_REWIND },	/* Backward ? */
-
-};
-
-struct ir_scancode_table ir_codes_purpletv_table = {
-	.scan = ir_codes_purpletv,
-	.size = ARRAY_SIZE(ir_codes_purpletv),
-};
-EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
-
-/* Mapping for the 28 key remote control as seen at
-   http://www.sednacomputer.com/photo/cardbus-tv.jpg
-   Pavel Mihaylov <bin@bash.info>
-   Also for the remote bundled with Kozumi KTV-01C card */
-static struct ir_scancode ir_codes_pctv_sedna[] = {
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0a, KEY_AGAIN },	/* Recall */
-	{ 0x0b, KEY_CHANNELUP },
-	{ 0x0c, KEY_VOLUMEUP },
-	{ 0x0d, KEY_MODE },	/* Stereo */
-	{ 0x0e, KEY_STOP },
-	{ 0x0f, KEY_PREVIOUSSONG },
-	{ 0x10, KEY_ZOOM },
-	{ 0x11, KEY_TUNER },	/* Source */
-	{ 0x12, KEY_POWER },
-	{ 0x13, KEY_MUTE },
-	{ 0x15, KEY_CHANNELDOWN },
-	{ 0x18, KEY_VOLUMEDOWN },
-	{ 0x19, KEY_CAMERA },	/* Snapshot */
-	{ 0x1a, KEY_NEXTSONG },
-	{ 0x1b, KEY_TIME },	/* Time Shift */
-	{ 0x1c, KEY_RADIO },	/* FM Radio */
-	{ 0x1d, KEY_RECORD },
-	{ 0x1e, KEY_PAUSE },
-	/* additional codes for Kozumi's remote */
-	{ 0x14, KEY_INFO },	/* OSD */
-	{ 0x16, KEY_OK },	/* OK */
-	{ 0x17, KEY_DIGITS },	/* Plus */
-	{ 0x1f, KEY_PLAY },	/* Play */
-};
-
-struct ir_scancode_table ir_codes_pctv_sedna_table = {
-	.scan = ir_codes_pctv_sedna,
-	.size = ARRAY_SIZE(ir_codes_pctv_sedna),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
-
-/* Mark Phalan <phalanm@o2.ie> */
-static struct ir_scancode ir_codes_pv951[] = {
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x12, KEY_POWER },
-	{ 0x10, KEY_MUTE },
-	{ 0x1f, KEY_VOLUMEDOWN },
-	{ 0x1b, KEY_VOLUMEUP },
-	{ 0x1a, KEY_CHANNELUP },
-	{ 0x1e, KEY_CHANNELDOWN },
-	{ 0x0e, KEY_PAGEUP },
-	{ 0x1d, KEY_PAGEDOWN },
-	{ 0x13, KEY_SOUND },
-
-	{ 0x18, KEY_KPPLUSMINUS },	/* CH +/- */
-	{ 0x16, KEY_SUBTITLE },		/* CC */
-	{ 0x0d, KEY_TEXT },		/* TTX */
-	{ 0x0b, KEY_TV },		/* AIR/CBL */
-	{ 0x11, KEY_PC },		/* PC/TV */
-	{ 0x17, KEY_OK },		/* CH RTN */
-	{ 0x19, KEY_MODE },		/* FUNC */
-	{ 0x0c, KEY_SEARCH },		/* AUTOSCAN */
-
-	/* Not sure what to do with these ones! */
-	{ 0x0f, KEY_SELECT },		/* SOURCE */
-	{ 0x0a, KEY_KPPLUS },		/* +100 */
-	{ 0x14, KEY_EQUAL },		/* SYNC */
-	{ 0x1c, KEY_MEDIA },		/* PC/TV */
-};
-
-struct ir_scancode_table ir_codes_pv951_table = {
-	.scan = ir_codes_pv951,
-	.size = ARRAY_SIZE(ir_codes_pv951),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
-
-/* generic RC5 keytable                                          */
-/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
-/* used by old (black) Hauppauge remotes                         */
-static struct ir_scancode ir_codes_rc5_tv[] = {
-	/* Keys 0 to 9 */
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0b, KEY_CHANNEL },		/* channel / program (japan: 11) */
-	{ 0x0c, KEY_POWER },		/* standby */
-	{ 0x0d, KEY_MUTE },		/* mute / demute */
-	{ 0x0f, KEY_TV },		/* display */
-	{ 0x10, KEY_VOLUMEUP },
-	{ 0x11, KEY_VOLUMEDOWN },
-	{ 0x12, KEY_BRIGHTNESSUP },
-	{ 0x13, KEY_BRIGHTNESSDOWN },
-	{ 0x1e, KEY_SEARCH },		/* search + */
-	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
-	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
-	{ 0x22, KEY_CHANNEL },		/* alt / channel */
-	{ 0x23, KEY_LANGUAGE },		/* 1st / 2nd language */
-	{ 0x26, KEY_SLEEP },		/* sleeptimer */
-	{ 0x2e, KEY_MENU },		/* 2nd controls (USA: menu) */
-	{ 0x30, KEY_PAUSE },
-	{ 0x32, KEY_REWIND },
-	{ 0x33, KEY_GOTO },
-	{ 0x35, KEY_PLAY },
-	{ 0x36, KEY_STOP },
-	{ 0x37, KEY_RECORD },		/* recording */
-	{ 0x3c, KEY_TEXT },		/* teletext submode (Japan: 12) */
-	{ 0x3d, KEY_SUSPEND },		/* system standby */
-
-};
-
-struct ir_scancode_table ir_codes_rc5_tv_table = {
-	.scan = ir_codes_rc5_tv,
-	.size = ARRAY_SIZE(ir_codes_rc5_tv),
-};
-EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
-
-/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-static struct ir_scancode ir_codes_winfast[] = {
-	/* Keys 0 to 9 */
-	{ 0x12, KEY_0 },
-	{ 0x05, KEY_1 },
-	{ 0x06, KEY_2 },
-	{ 0x07, KEY_3 },
-	{ 0x09, KEY_4 },
-	{ 0x0a, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x0d, KEY_7 },
-	{ 0x0e, KEY_8 },
-	{ 0x0f, KEY_9 },
-
-	{ 0x00, KEY_POWER },
-	{ 0x1b, KEY_AUDIO },		/* Audio Source */
-	{ 0x02, KEY_TUNER },		/* TV/FM, not on Y0400052 */
-	{ 0x1e, KEY_VIDEO },		/* Video Source */
-	{ 0x16, KEY_INFO },		/* Display information */
-	{ 0x04, KEY_VOLUMEUP },
-	{ 0x08, KEY_VOLUMEDOWN },
-	{ 0x0c, KEY_CHANNELUP },
-	{ 0x10, KEY_CHANNELDOWN },
-	{ 0x03, KEY_ZOOM },		/* fullscreen */
-	{ 0x1f, KEY_TEXT },		/* closed caption/teletext */
-	{ 0x20, KEY_SLEEP },
-	{ 0x29, KEY_CLEAR },		/* boss key */
-	{ 0x14, KEY_MUTE },
-	{ 0x2b, KEY_RED },
-	{ 0x2c, KEY_GREEN },
-	{ 0x2d, KEY_YELLOW },
-	{ 0x2e, KEY_BLUE },
-	{ 0x18, KEY_KPPLUS },		/* fine tune + , not on Y040052 */
-	{ 0x19, KEY_KPMINUS },		/* fine tune - , not on Y040052 */
-	{ 0x2a, KEY_MEDIA },		/* PIP (Picture in picture */
-	{ 0x21, KEY_DOT },
-	{ 0x13, KEY_ENTER },
-	{ 0x11, KEY_LAST },		/* Recall (last channel */
-	{ 0x22, KEY_PREVIOUS },
-	{ 0x23, KEY_PLAYPAUSE },
-	{ 0x24, KEY_NEXT },
-	{ 0x25, KEY_TIME },		/* Time Shifting */
-	{ 0x26, KEY_STOP },
-	{ 0x27, KEY_RECORD },
-	{ 0x28, KEY_SAVE },		/* Screenshot */
-	{ 0x2f, KEY_MENU },
-	{ 0x30, KEY_CANCEL },
-	{ 0x31, KEY_CHANNEL },		/* Channel Surf */
-	{ 0x32, KEY_SUBTITLE },
-	{ 0x33, KEY_LANGUAGE },
-	{ 0x34, KEY_REWIND },
-	{ 0x35, KEY_FASTFORWARD },
-	{ 0x36, KEY_TV },
-	{ 0x37, KEY_RADIO },		/* FM */
-	{ 0x38, KEY_DVD },
-
-	{ 0x3e, KEY_F21 },		/* MCE +VOL, on Y04G0033 */
-	{ 0x3a, KEY_F22 },		/* MCE -VOL, on Y04G0033 */
-	{ 0x3b, KEY_F23 },		/* MCE +CH,  on Y04G0033 */
-	{ 0x3f, KEY_F24 }		/* MCE -CH,  on Y04G0033 */
-};
-
-struct ir_scancode_table ir_codes_winfast_table = {
-	.scan = ir_codes_winfast,
-	.size = ARRAY_SIZE(ir_codes_winfast),
-};
-EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
-
-static struct ir_scancode ir_codes_pinnacle_color[] = {
-	{ 0x59, KEY_MUTE },
-	{ 0x4a, KEY_POWER },
-
-	{ 0x18, KEY_TEXT },
-	{ 0x26, KEY_TV },
-	{ 0x3d, KEY_PRINT },
-
-	{ 0x48, KEY_RED },
-	{ 0x04, KEY_GREEN },
-	{ 0x11, KEY_YELLOW },
-	{ 0x00, KEY_BLUE },
-
-	{ 0x2d, KEY_VOLUMEUP },
-	{ 0x1e, KEY_VOLUMEDOWN },
-
-	{ 0x49, KEY_MENU },
-
-	{ 0x16, KEY_CHANNELUP },
-	{ 0x17, KEY_CHANNELDOWN },
-
-	{ 0x20, KEY_UP },
-	{ 0x21, KEY_DOWN },
-	{ 0x22, KEY_LEFT },
-	{ 0x23, KEY_RIGHT },
-	{ 0x0d, KEY_SELECT },
-
-	{ 0x08, KEY_BACK },
-	{ 0x07, KEY_REFRESH },
-
-	{ 0x2f, KEY_ZOOM },
-	{ 0x29, KEY_RECORD },
-
-	{ 0x4b, KEY_PAUSE },
-	{ 0x4d, KEY_REWIND },
-	{ 0x2e, KEY_PLAY },
-	{ 0x4e, KEY_FORWARD },
-	{ 0x53, KEY_PREVIOUS },
-	{ 0x4c, KEY_STOP },
-	{ 0x54, KEY_NEXT },
-
-	{ 0x69, KEY_0 },
-	{ 0x6a, KEY_1 },
-	{ 0x6b, KEY_2 },
-	{ 0x6c, KEY_3 },
-	{ 0x6d, KEY_4 },
-	{ 0x6e, KEY_5 },
-	{ 0x6f, KEY_6 },
-	{ 0x70, KEY_7 },
-	{ 0x71, KEY_8 },
-	{ 0x72, KEY_9 },
-
-	{ 0x74, KEY_CHANNEL },
-	{ 0x0a, KEY_BACKSPACE },
-};
-
-struct ir_scancode_table ir_codes_pinnacle_color_table = {
-	.scan = ir_codes_pinnacle_color,
-	.size = ARRAY_SIZE(ir_codes_pinnacle_color),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
-
-/* Hauppauge: the newer, gray remotes (seems there are multiple
- * slightly different versions), shipped with cx88+ivtv cards.
- * almost rc5 coding, but some non-standard keys */
-static struct ir_scancode ir_codes_hauppauge_new[] = {
-	/* Keys 0 to 9 */
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	{ 0x0a, KEY_TEXT },		/* keypad asterisk as well */
-	{ 0x0b, KEY_RED },		/* red button */
-	{ 0x0c, KEY_RADIO },
-	{ 0x0d, KEY_MENU },
-	{ 0x0e, KEY_SUBTITLE },		/* also the # key */
-	{ 0x0f, KEY_MUTE },
-	{ 0x10, KEY_VOLUMEUP },
-	{ 0x11, KEY_VOLUMEDOWN },
-	{ 0x12, KEY_PREVIOUS },		/* previous channel */
-	{ 0x14, KEY_UP },
-	{ 0x15, KEY_DOWN },
-	{ 0x16, KEY_LEFT },
-	{ 0x17, KEY_RIGHT },
-	{ 0x18, KEY_VIDEO },		/* Videos */
-	{ 0x19, KEY_AUDIO },		/* Music */
-	/* 0x1a: Pictures - presume this means
-	   "Multimedia Home Platform" -
-	   no "PICTURES" key in input.h
-	 */
-	{ 0x1a, KEY_MHP },
-
-	{ 0x1b, KEY_EPG },		/* Guide */
-	{ 0x1c, KEY_TV },
-	{ 0x1e, KEY_NEXTSONG },		/* skip >| */
-	{ 0x1f, KEY_EXIT },		/* back/exit */
-	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
-	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
-	{ 0x22, KEY_CHANNEL },		/* source (old black remote) */
-	{ 0x24, KEY_PREVIOUSSONG },	/* replay |< */
-	{ 0x25, KEY_ENTER },		/* OK */
-	{ 0x26, KEY_SLEEP },		/* minimize (old black remote) */
-	{ 0x29, KEY_BLUE },		/* blue key */
-	{ 0x2e, KEY_GREEN },		/* green button */
-	{ 0x30, KEY_PAUSE },		/* pause */
-	{ 0x32, KEY_REWIND },		/* backward << */
-	{ 0x34, KEY_FASTFORWARD },	/* forward >> */
-	{ 0x35, KEY_PLAY },
-	{ 0x36, KEY_STOP },
-	{ 0x37, KEY_RECORD },		/* recording */
-	{ 0x38, KEY_YELLOW },		/* yellow key */
-	{ 0x3b, KEY_SELECT },		/* top right button */
-	{ 0x3c, KEY_ZOOM },		/* full */
-	{ 0x3d, KEY_POWER },		/* system power (green button) */
-};
-
-struct ir_scancode_table ir_codes_hauppauge_new_table = {
-	.scan = ir_codes_hauppauge_new,
-	.size = ARRAY_SIZE(ir_codes_hauppauge_new),
-};
-EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
-
-static struct ir_scancode ir_codes_npgtech[] = {
-	{ 0x1d, KEY_SWITCHVIDEOMODE },	/* switch inputs */
-	{ 0x2a, KEY_FRONT },
-
-	{ 0x3e, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x06, KEY_3 },
-	{ 0x0a, KEY_4 },
-	{ 0x0e, KEY_5 },
-	{ 0x12, KEY_6 },
-	{ 0x16, KEY_7 },
-	{ 0x1a, KEY_8 },
-	{ 0x1e, KEY_9 },
-	{ 0x3a, KEY_0 },
-	{ 0x22, KEY_NUMLOCK },		/* -/-- */
-	{ 0x20, KEY_REFRESH },
-
-	{ 0x03, KEY_BRIGHTNESSDOWN },
-	{ 0x28, KEY_AUDIO },
-	{ 0x3c, KEY_CHANNELUP },
-	{ 0x3f, KEY_VOLUMEDOWN },
-	{ 0x2e, KEY_MUTE },
-	{ 0x3b, KEY_VOLUMEUP },
-	{ 0x00, KEY_CHANNELDOWN },
-	{ 0x07, KEY_BRIGHTNESSUP },
-	{ 0x2c, KEY_TEXT },
-
-	{ 0x37, KEY_RECORD },
-	{ 0x17, KEY_PLAY },
-	{ 0x13, KEY_PAUSE },
-	{ 0x26, KEY_STOP },
-	{ 0x18, KEY_FASTFORWARD },
-	{ 0x14, KEY_REWIND },
-	{ 0x33, KEY_ZOOM },
-	{ 0x32, KEY_KEYBOARD },
-	{ 0x30, KEY_GOTO },		/* Pointing arrow */
-	{ 0x36, KEY_MACRO },		/* Maximize/Minimize (yellow) */
-	{ 0x0b, KEY_RADIO },
-	{ 0x10, KEY_POWER },
-
-};
-
-struct ir_scancode_table ir_codes_npgtech_table = {
-	.scan = ir_codes_npgtech,
-	.size = ARRAY_SIZE(ir_codes_npgtech),
-};
-EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
-
-/* Norwood Micro (non-Pro) TV Tuner
-   By Peter Naulls <peter@chocky.org>
-   Key comments are the functions given in the manual */
-static struct ir_scancode ir_codes_norwood[] = {
-	/* Keys 0 to 9 */
-	{ 0x20, KEY_0 },
-	{ 0x21, KEY_1 },
-	{ 0x22, KEY_2 },
-	{ 0x23, KEY_3 },
-	{ 0x24, KEY_4 },
-	{ 0x25, KEY_5 },
-	{ 0x26, KEY_6 },
-	{ 0x27, KEY_7 },
-	{ 0x28, KEY_8 },
-	{ 0x29, KEY_9 },
-
-	{ 0x78, KEY_TUNER },		/* Video Source        */
-	{ 0x2c, KEY_EXIT },		/* Open/Close software */
-	{ 0x2a, KEY_SELECT },		/* 2 Digit Select      */
-	{ 0x69, KEY_AGAIN },		/* Recall              */
-
-	{ 0x32, KEY_BRIGHTNESSUP },	/* Brightness increase */
-	{ 0x33, KEY_BRIGHTNESSDOWN },	/* Brightness decrease */
-	{ 0x6b, KEY_KPPLUS },		/* (not named >>>>>)   */
-	{ 0x6c, KEY_KPMINUS },		/* (not named <<<<<)   */
-
-	{ 0x2d, KEY_MUTE },		/* Mute                */
-	{ 0x30, KEY_VOLUMEUP },		/* Volume up           */
-	{ 0x31, KEY_VOLUMEDOWN },	/* Volume down         */
-	{ 0x60, KEY_CHANNELUP },	/* Channel up          */
-	{ 0x61, KEY_CHANNELDOWN },	/* Channel down        */
-
-	{ 0x3f, KEY_RECORD },		/* Record              */
-	{ 0x37, KEY_PLAY },		/* Play                */
-	{ 0x36, KEY_PAUSE },		/* Pause               */
-	{ 0x2b, KEY_STOP },		/* Stop                */
-	{ 0x67, KEY_FASTFORWARD },	/* Foward              */
-	{ 0x66, KEY_REWIND },		/* Rewind              */
-	{ 0x3e, KEY_SEARCH },		/* Auto Scan           */
-	{ 0x2e, KEY_CAMERA },		/* Capture Video       */
-	{ 0x6d, KEY_MENU },		/* Show/Hide Control   */
-	{ 0x2f, KEY_ZOOM },		/* Full Screen         */
-	{ 0x34, KEY_RADIO },		/* FM                  */
-	{ 0x65, KEY_POWER },		/* Computer power      */
-};
-
-struct ir_scancode_table ir_codes_norwood_table = {
-	.scan = ir_codes_norwood,
-	.size = ARRAY_SIZE(ir_codes_norwood),
-};
-EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
-
-/* From reading the following remotes:
- * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
- * Hauppauge (from NOVA-CI-s box product)
- * This is a "middle of the road" approach, differences are noted
- */
-static struct ir_scancode ir_codes_budget_ci_old[] = {
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-	{ 0x0a, KEY_ENTER },
-	{ 0x0b, KEY_RED },
-	{ 0x0c, KEY_POWER },		/* RADIO on Hauppauge */
-	{ 0x0d, KEY_MUTE },
-	{ 0x0f, KEY_A },		/* TV on Hauppauge */
-	{ 0x10, KEY_VOLUMEUP },
-	{ 0x11, KEY_VOLUMEDOWN },
-	{ 0x14, KEY_B },
-	{ 0x1c, KEY_UP },
-	{ 0x1d, KEY_DOWN },
-	{ 0x1e, KEY_OPTION },		/* RESERVED on Hauppauge */
-	{ 0x1f, KEY_BREAK },
-	{ 0x20, KEY_CHANNELUP },
-	{ 0x21, KEY_CHANNELDOWN },
-	{ 0x22, KEY_PREVIOUS },		/* Prev Ch on Zenith, SOURCE on Hauppauge */
-	{ 0x24, KEY_RESTART },
-	{ 0x25, KEY_OK },
-	{ 0x26, KEY_CYCLEWINDOWS },	/* MINIMIZE on Hauppauge */
-	{ 0x28, KEY_ENTER },		/* VCR mode on Zenith */
-	{ 0x29, KEY_PAUSE },
-	{ 0x2b, KEY_RIGHT },
-	{ 0x2c, KEY_LEFT },
-	{ 0x2e, KEY_MENU },		/* FULL SCREEN on Hauppauge */
-	{ 0x30, KEY_SLOW },
-	{ 0x31, KEY_PREVIOUS },		/* VCR mode on Zenith */
-	{ 0x32, KEY_REWIND },
-	{ 0x34, KEY_FASTFORWARD },
-	{ 0x35, KEY_PLAY },
-	{ 0x36, KEY_STOP },
-	{ 0x37, KEY_RECORD },
-	{ 0x38, KEY_TUNER },		/* TV/VCR on Zenith */
-	{ 0x3a, KEY_C },
-	{ 0x3c, KEY_EXIT },
-	{ 0x3d, KEY_POWER2 },
-	{ 0x3e, KEY_TUNER },
-};
-
-struct ir_scancode_table ir_codes_budget_ci_old_table = {
-	.scan = ir_codes_budget_ci_old,
-	.size = ARRAY_SIZE(ir_codes_budget_ci_old),
-};
-EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
-
-/*
- * Marc Fargas <telenieko@telenieko.com>
- * this is the remote control that comes with the asus p7131
- * which has a label saying is "Model PC-39"
- */
-static struct ir_scancode ir_codes_asus_pc39[] = {
-	/* Keys 0 to 9 */
-	{ 0x15, KEY_0 },
-	{ 0x29, KEY_1 },
-	{ 0x2d, KEY_2 },
-	{ 0x2b, KEY_3 },
-	{ 0x09, KEY_4 },
-	{ 0x0d, KEY_5 },
-	{ 0x0b, KEY_6 },
-	{ 0x31, KEY_7 },
-	{ 0x35, KEY_8 },
-	{ 0x33, KEY_9 },
-
-	{ 0x3e, KEY_RADIO },		/* radio */
-	{ 0x03, KEY_MENU },		/* dvd/menu */
-	{ 0x2a, KEY_VOLUMEUP },
-	{ 0x19, KEY_VOLUMEDOWN },
-	{ 0x37, KEY_UP },
-	{ 0x3b, KEY_DOWN },
-	{ 0x27, KEY_LEFT },
-	{ 0x2f, KEY_RIGHT },
-	{ 0x25, KEY_VIDEO },		/* video */
-	{ 0x39, KEY_AUDIO },		/* music */
-
-	{ 0x21, KEY_TV },		/* tv */
-	{ 0x1d, KEY_EXIT },		/* back */
-	{ 0x0a, KEY_CHANNELUP },	/* channel / program + */
-	{ 0x1b, KEY_CHANNELDOWN },	/* channel / program - */
-	{ 0x1a, KEY_ENTER },		/* enter */
-
-	{ 0x06, KEY_PAUSE },		/* play/pause */
-	{ 0x1e, KEY_PREVIOUS },		/* rew */
-	{ 0x26, KEY_NEXT },		/* forward */
-	{ 0x0e, KEY_REWIND },		/* backward << */
-	{ 0x3a, KEY_FASTFORWARD },	/* forward >> */
-	{ 0x36, KEY_STOP },
-	{ 0x2e, KEY_RECORD },		/* recording */
-	{ 0x16, KEY_POWER },		/* the button that reads "close" */
-
-	{ 0x11, KEY_ZOOM },		/* full screen */
-	{ 0x13, KEY_MACRO },		/* recall */
-	{ 0x23, KEY_HOME },		/* home */
-	{ 0x05, KEY_PVR },		/* picture */
-	{ 0x3d, KEY_MUTE },		/* mute */
-	{ 0x01, KEY_DVD },		/* dvd */
-};
-
-struct ir_scancode_table ir_codes_asus_pc39_table = {
-	.scan = ir_codes_asus_pc39,
-	.size = ARRAY_SIZE(ir_codes_asus_pc39),
-};
-EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
-
-
-/* Encore ENLTV-FM  - black plastic, white front cover with white glowing buttons
-    Juan Pablo Sormani <sorman@gmail.com> */
-static struct ir_scancode ir_codes_encore_enltv[] = {
-
-	/* Power button does nothing, neither in Windows app,
-	 although it sends data (used for BIOS wakeup?) */
-	{ 0x0d, KEY_MUTE },
-
-	{ 0x1e, KEY_TV },
-	{ 0x00, KEY_VIDEO },
-	{ 0x01, KEY_AUDIO },		/* music */
-	{ 0x02, KEY_MHP },		/* picture */
-
-	{ 0x1f, KEY_1 },
-	{ 0x03, KEY_2 },
-	{ 0x04, KEY_3 },
-	{ 0x05, KEY_4 },
-	{ 0x1c, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x1d, KEY_9 },
-	{ 0x0a, KEY_0 },
-
-	{ 0x09, KEY_LIST },		/* -/-- */
-	{ 0x0b, KEY_LAST },		/* recall */
-
-	{ 0x14, KEY_HOME },		/* win start menu */
-	{ 0x15, KEY_EXIT },		/* exit */
-	{ 0x16, KEY_CHANNELUP },	/* UP */
-	{ 0x12, KEY_CHANNELDOWN },	/* DOWN */
-	{ 0x0c, KEY_VOLUMEUP },		/* RIGHT */
-	{ 0x17, KEY_VOLUMEDOWN },	/* LEFT */
-
-	{ 0x18, KEY_ENTER },		/* OK */
-
-	{ 0x0e, KEY_ESC },
-	{ 0x13, KEY_CYCLEWINDOWS },	/* desktop */
-	{ 0x11, KEY_TAB },
-	{ 0x19, KEY_SWITCHVIDEOMODE },	/* switch */
-
-	{ 0x1a, KEY_MENU },
-	{ 0x1b, KEY_ZOOM },		/* fullscreen */
-	{ 0x44, KEY_TIME },		/* time shift */
-	{ 0x40, KEY_MODE },		/* source */
-
-	{ 0x5a, KEY_RECORD },
-	{ 0x42, KEY_PLAY },		/* play/pause */
-	{ 0x45, KEY_STOP },
-	{ 0x43, KEY_CAMERA },		/* camera icon */
-
-	{ 0x48, KEY_REWIND },
-	{ 0x4a, KEY_FASTFORWARD },
-	{ 0x49, KEY_PREVIOUS },
-	{ 0x4b, KEY_NEXT },
-
-	{ 0x4c, KEY_FAVORITES },	/* tv wall */
-	{ 0x4d, KEY_SOUND },		/* DVD sound */
-	{ 0x4e, KEY_LANGUAGE },		/* DVD lang */
-	{ 0x4f, KEY_TEXT },		/* DVD text */
-
-	{ 0x50, KEY_SLEEP },		/* shutdown */
-	{ 0x51, KEY_MODE },		/* stereo > main */
-	{ 0x52, KEY_SELECT },		/* stereo > sap */
-	{ 0x53, KEY_PROG1 },		/* teletext */
-
-
-	{ 0x59, KEY_RED },		/* AP1 */
-	{ 0x41, KEY_GREEN },		/* AP2 */
-	{ 0x47, KEY_YELLOW },		/* AP3 */
-	{ 0x57, KEY_BLUE },		/* AP4 */
-};
-
-struct ir_scancode_table ir_codes_encore_enltv_table = {
-	.scan = ir_codes_encore_enltv,
-	.size = ARRAY_SIZE(ir_codes_encore_enltv),
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
-
-/* Encore ENLTV2-FM  - silver plastic - "Wand Media" written at the botton
-    Mauro Carvalho Chehab <mchehab@infradead.org> */
-static struct ir_scancode ir_codes_encore_enltv2[] = {
-	{ 0x4c, KEY_POWER2 },
-	{ 0x4a, KEY_TUNER },
-	{ 0x40, KEY_1 },
-	{ 0x60, KEY_2 },
-	{ 0x50, KEY_3 },
-	{ 0x70, KEY_4 },
-	{ 0x48, KEY_5 },
-	{ 0x68, KEY_6 },
-	{ 0x58, KEY_7 },
-	{ 0x78, KEY_8 },
-	{ 0x44, KEY_9 },
-	{ 0x54, KEY_0 },
-
-	{ 0x64, KEY_LAST },		/* +100 */
-	{ 0x4e, KEY_AGAIN },		/* Recall */
-
-	{ 0x6c, KEY_SWITCHVIDEOMODE },	/* Video Source */
-	{ 0x5e, KEY_MENU },
-	{ 0x56, KEY_SCREEN },
-	{ 0x7a, KEY_SETUP },
-
-	{ 0x46, KEY_MUTE },
-	{ 0x5c, KEY_MODE },		/* Stereo */
-	{ 0x74, KEY_INFO },
-	{ 0x7c, KEY_CLEAR },
-
-	{ 0x55, KEY_UP },
-	{ 0x49, KEY_DOWN },
-	{ 0x7e, KEY_LEFT },
-	{ 0x59, KEY_RIGHT },
-	{ 0x6a, KEY_ENTER },
-
-	{ 0x42, KEY_VOLUMEUP },
-	{ 0x62, KEY_VOLUMEDOWN },
-	{ 0x52, KEY_CHANNELUP },
-	{ 0x72, KEY_CHANNELDOWN },
-
-	{ 0x41, KEY_RECORD },
-	{ 0x51, KEY_CAMERA },		/* Snapshot */
-	{ 0x75, KEY_TIME },		/* Timeshift */
-	{ 0x71, KEY_TV2 },		/* PIP */
-
-	{ 0x45, KEY_REWIND },
-	{ 0x6f, KEY_PAUSE },
-	{ 0x7d, KEY_FORWARD },
-	{ 0x79, KEY_STOP },
-};
-
-struct ir_scancode_table ir_codes_encore_enltv2_table = {
-	.scan = ir_codes_encore_enltv2,
-	.size = ARRAY_SIZE(ir_codes_encore_enltv2),
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
-
-/* for the Technotrend 1500 bundled remotes (grey and black): */
-static struct ir_scancode ir_codes_tt_1500[] = {
-	{ 0x01, KEY_POWER },
-	{ 0x02, KEY_SHUFFLE },		/* ? double-arrow key */
-	{ 0x03, KEY_1 },
-	{ 0x04, KEY_2 },
-	{ 0x05, KEY_3 },
-	{ 0x06, KEY_4 },
-	{ 0x07, KEY_5 },
-	{ 0x08, KEY_6 },
-	{ 0x09, KEY_7 },
-	{ 0x0a, KEY_8 },
-	{ 0x0b, KEY_9 },
-	{ 0x0c, KEY_0 },
-	{ 0x0d, KEY_UP },
-	{ 0x0e, KEY_LEFT },
-	{ 0x0f, KEY_OK },
-	{ 0x10, KEY_RIGHT },
-	{ 0x11, KEY_DOWN },
-	{ 0x12, KEY_INFO },
-	{ 0x13, KEY_EXIT },
-	{ 0x14, KEY_RED },
-	{ 0x15, KEY_GREEN },
-	{ 0x16, KEY_YELLOW },
-	{ 0x17, KEY_BLUE },
-	{ 0x18, KEY_MUTE },
-	{ 0x19, KEY_TEXT },
-	{ 0x1a, KEY_MODE },		/* ? TV/Radio */
-	{ 0x21, KEY_OPTION },
-	{ 0x22, KEY_EPG },
-	{ 0x23, KEY_CHANNELUP },
-	{ 0x24, KEY_CHANNELDOWN },
-	{ 0x25, KEY_VOLUMEUP },
-	{ 0x26, KEY_VOLUMEDOWN },
-	{ 0x27, KEY_SETUP },
-	{ 0x3a, KEY_RECORD },		/* these keys are only in the black remote */
-	{ 0x3b, KEY_PLAY },
-	{ 0x3c, KEY_STOP },
-	{ 0x3d, KEY_REWIND },
-	{ 0x3e, KEY_PAUSE },
-	{ 0x3f, KEY_FORWARD },
-};
-
-struct ir_scancode_table ir_codes_tt_1500_table = {
-	.scan = ir_codes_tt_1500,
-	.size = ARRAY_SIZE(ir_codes_tt_1500),
-};
-EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
-
-/* DViCO FUSION HDTV MCE remote */
-static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
-
-	{ 0x0b, KEY_1 },
-	{ 0x17, KEY_2 },
-	{ 0x1b, KEY_3 },
-	{ 0x07, KEY_4 },
-	{ 0x50, KEY_5 },
-	{ 0x54, KEY_6 },
-	{ 0x48, KEY_7 },
-	{ 0x4c, KEY_8 },
-	{ 0x58, KEY_9 },
-	{ 0x03, KEY_0 },
-
-	{ 0x5e, KEY_OK },
-	{ 0x51, KEY_UP },
-	{ 0x53, KEY_DOWN },
-	{ 0x5b, KEY_LEFT },
-	{ 0x5f, KEY_RIGHT },
-
-	{ 0x02, KEY_TV },		/* Labeled DTV on remote */
-	{ 0x0e, KEY_MP3 },
-	{ 0x1a, KEY_DVD },
-	{ 0x1e, KEY_FAVORITES },	/* Labeled CPF on remote */
-	{ 0x16, KEY_SETUP },
-	{ 0x46, KEY_POWER2 },		/* TV On/Off button on remote */
-	{ 0x0a, KEY_EPG },		/* Labeled Guide on remote */
-
-	{ 0x49, KEY_BACK },
-	{ 0x59, KEY_INFO },		/* Labeled MORE on remote */
-	{ 0x4d, KEY_MENU },		/* Labeled DVDMENU on remote */
-	{ 0x55, KEY_CYCLEWINDOWS },	/* Labeled ALT-TAB on remote */
-
-	{ 0x0f, KEY_PREVIOUSSONG },	/* Labeled |<< REPLAY on remote */
-	{ 0x12, KEY_NEXTSONG },		/* Labeled >>| SKIP on remote */
-	{ 0x42, KEY_ENTER },		/* Labeled START with a green
-					   MS windows logo on remote */
-
-	{ 0x15, KEY_VOLUMEUP },
-	{ 0x05, KEY_VOLUMEDOWN },
-	{ 0x11, KEY_CHANNELUP },
-	{ 0x09, KEY_CHANNELDOWN },
-
-	{ 0x52, KEY_CAMERA },
-	{ 0x5a, KEY_TUNER },
-	{ 0x19, KEY_OPEN },
-
-	{ 0x13, KEY_MODE },		/* 4:3 16:9 select */
-	{ 0x1f, KEY_ZOOM },
-
-	{ 0x43, KEY_REWIND },
-	{ 0x47, KEY_PLAYPAUSE },
-	{ 0x4f, KEY_FASTFORWARD },
-	{ 0x57, KEY_MUTE },
-	{ 0x0d, KEY_STOP },
-	{ 0x01, KEY_RECORD },
-	{ 0x4e, KEY_POWER },
-};
-
-struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
-	.scan = ir_codes_fusionhdtv_mce,
-	.size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
-};
-EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
-
-/* Pinnacle PCTV HD 800i mini remote */
-static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
-
-	{ 0x0f, KEY_1 },
-	{ 0x15, KEY_2 },
-	{ 0x10, KEY_3 },
-	{ 0x18, KEY_4 },
-	{ 0x1b, KEY_5 },
-	{ 0x1e, KEY_6 },
-	{ 0x11, KEY_7 },
-	{ 0x21, KEY_8 },
-	{ 0x12, KEY_9 },
-	{ 0x27, KEY_0 },
-
-	{ 0x24, KEY_ZOOM },
-	{ 0x2a, KEY_SUBTITLE },
-
-	{ 0x00, KEY_MUTE },
-	{ 0x01, KEY_ENTER },	/* Pinnacle Logo */
-	{ 0x39, KEY_POWER },
-
-	{ 0x03, KEY_VOLUMEUP },
-	{ 0x09, KEY_VOLUMEDOWN },
-	{ 0x06, KEY_CHANNELUP },
-	{ 0x0c, KEY_CHANNELDOWN },
-
-	{ 0x2d, KEY_REWIND },
-	{ 0x30, KEY_PLAYPAUSE },
-	{ 0x33, KEY_FASTFORWARD },
-	{ 0x3c, KEY_STOP },
-	{ 0x36, KEY_RECORD },
-	{ 0x3f, KEY_EPG },	/* Labeled "?" */
-};
-
-struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
-	.scan = ir_codes_pinnacle_pctv_hd,
-	.size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
-};
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
-
-/*
- * Igor Kuznetsov <igk72@ya.ru>
- * Andrey J. Melnikov <temnota@kmv.ru>
- *
- * Keytable is used by BeholdTV 60x series, M6 series at
- * least, and probably other cards too.
- * The "ascii-art picture" below (in comments, first row
- * is the keycode in hex, and subsequent row(s) shows
- * the button labels (several variants when appropriate)
- * helps to descide which keycodes to assign to the buttons.
- */
-static struct ir_scancode ir_codes_behold[] = {
-
-	/*  0x1c            0x12  *
-	 *  TV/FM          POWER  *
-	 *                        */
-	{ 0x1c, KEY_TUNER },	/* XXX KEY_TV / KEY_RADIO */
-	{ 0x12, KEY_POWER },
-
-	/*  0x01    0x02    0x03  *
-	 *   1       2       3    *
-	 *                        *
-	 *  0x04    0x05    0x06  *
-	 *   4       5       6    *
-	 *                        *
-	 *  0x07    0x08    0x09  *
-	 *   7       8       9    *
-	 *                        */
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-
-	/*  0x0a    0x00    0x17  *
-	 * RECALL    0      MODE  *
-	 *                        */
-	{ 0x0a, KEY_AGAIN },
-	{ 0x00, KEY_0 },
-	{ 0x17, KEY_MODE },
-
-	/*  0x14          0x10    *
-	 * ASPECT      FULLSCREEN *
-	 *                        */
-	{ 0x14, KEY_SCREEN },
-	{ 0x10, KEY_ZOOM },
-
-	/*          0x0b          *
-	 *           Up           *
-	 *                        *
-	 *  0x18    0x16    0x0c  *
-	 *  Left     Ok     Right *
-	 *                        *
-	 *         0x015          *
-	 *         Down           *
-	 *                        */
-	{ 0x0b, KEY_CHANNELUP },
-	{ 0x18, KEY_VOLUMEDOWN },
-	{ 0x16, KEY_OK },		/* XXX KEY_ENTER */
-	{ 0x0c, KEY_VOLUMEUP },
-	{ 0x15, KEY_CHANNELDOWN },
-
-	/*  0x11            0x0d  *
-	 *  MUTE            INFO  *
-	 *                        */
-	{ 0x11, KEY_MUTE },
-	{ 0x0d, KEY_INFO },
-
-	/*  0x0f    0x1b    0x1a  *
-	 * RECORD PLAY/PAUSE STOP *
-	 *                        *
-	 *  0x0e    0x1f    0x1e  *
-	 *TELETEXT  AUDIO  SOURCE *
-	 *           RED   YELLOW *
-	 *                        */
-	{ 0x0f, KEY_RECORD },
-	{ 0x1b, KEY_PLAYPAUSE },
-	{ 0x1a, KEY_STOP },
-	{ 0x0e, KEY_TEXT },
-	{ 0x1f, KEY_RED },	/*XXX KEY_AUDIO	*/
-	{ 0x1e, KEY_YELLOW },	/*XXX KEY_SOURCE	*/
-
-	/*  0x1d   0x13     0x19  *
-	 * SLEEP  PREVIEW   DVB   *
-	 *         GREEN    BLUE  *
-	 *                        */
-	{ 0x1d, KEY_SLEEP },
-	{ 0x13, KEY_GREEN },
-	{ 0x19, KEY_BLUE },	/* XXX KEY_SAT	*/
-
-	/*  0x58           0x5c   *
-	 * FREEZE        SNAPSHOT *
-	 *                        */
-	{ 0x58, KEY_SLOW },
-	{ 0x5c, KEY_CAMERA },
-
-};
-
-struct ir_scancode_table ir_codes_behold_table = {
-	.scan = ir_codes_behold,
-	.size = ARRAY_SIZE(ir_codes_behold),
-};
-EXPORT_SYMBOL_GPL(ir_codes_behold_table);
-
-/* Beholder Intl. Ltd. 2008
- * Dmitry Belimov d.belimov@google.com
- * Keytable is used by BeholdTV Columbus
- * The "ascii-art picture" below (in comments, first row
- * is the keycode in hex, and subsequent row(s) shows
- * the button labels (several variants when appropriate)
- * helps to descide which keycodes to assign to the buttons.
- */
-static struct ir_scancode ir_codes_behold_columbus[] = {
-
-	/*  0x13   0x11   0x1C   0x12  *
-	 *  Mute  Source  TV/FM  Power *
-	 *                             */
-
-	{ 0x13, KEY_MUTE },
-	{ 0x11, KEY_PROPS },
-	{ 0x1C, KEY_TUNER },	/* KEY_TV/KEY_RADIO	*/
-	{ 0x12, KEY_POWER },
-
-	/*  0x01    0x02    0x03  0x0D    *
-	 *   1       2       3   Stereo   *
-	 *                        	  *
-	 *  0x04    0x05    0x06  0x19    *
-	 *   4       5       6   Snapshot *
-	 *                        	  *
-	 *  0x07    0x08    0x09  0x10    *
-	 *   7       8       9    Zoom 	  *
-	 *                                */
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x0D, KEY_SETUP },	  /* Setup key */
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x19, KEY_CAMERA },	/* Snapshot key */
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-	{ 0x10, KEY_ZOOM },
-
-	/*  0x0A    0x00    0x0B       0x0C   *
-	 * RECALL    0    ChannelUp  VolumeUp *
-	 *                                    */
-	{ 0x0A, KEY_AGAIN },
-	{ 0x00, KEY_0 },
-	{ 0x0B, KEY_CHANNELUP },
-	{ 0x0C, KEY_VOLUMEUP },
-
-	/*   0x1B      0x1D      0x15        0x18     *
-	 * Timeshift  Record  ChannelDown  VolumeDown *
-	 *                                            */
-
-	{ 0x1B, KEY_TIME },
-	{ 0x1D, KEY_RECORD },
-	{ 0x15, KEY_CHANNELDOWN },
-	{ 0x18, KEY_VOLUMEDOWN },
-
-	/*   0x0E   0x1E     0x0F     0x1A  *
-	 *   Stop   Pause  Previouse  Next  *
-	 *                                  */
-
-	{ 0x0E, KEY_STOP },
-	{ 0x1E, KEY_PAUSE },
-	{ 0x0F, KEY_PREVIOUS },
-	{ 0x1A, KEY_NEXT },
-
-};
-
-struct ir_scancode_table ir_codes_behold_columbus_table = {
-	.scan = ir_codes_behold_columbus,
-	.size = ARRAY_SIZE(ir_codes_behold_columbus),
-};
-EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
-
-/*
- * Remote control for the Genius TVGO A11MCE
- * Adrian Pardini <pardo.bsso@gmail.com>
- */
-static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
-	/* Keys 0 to 9 */
-	{ 0x48, KEY_0 },
-	{ 0x09, KEY_1 },
-	{ 0x1d, KEY_2 },
-	{ 0x1f, KEY_3 },
-	{ 0x19, KEY_4 },
-	{ 0x1b, KEY_5 },
-	{ 0x11, KEY_6 },
-	{ 0x17, KEY_7 },
-	{ 0x12, KEY_8 },
-	{ 0x16, KEY_9 },
-
-	{ 0x54, KEY_RECORD },		/* recording */
-	{ 0x06, KEY_MUTE },		/* mute */
-	{ 0x10, KEY_POWER },
-	{ 0x40, KEY_LAST },		/* recall */
-	{ 0x4c, KEY_CHANNELUP },	/* channel / program + */
-	{ 0x00, KEY_CHANNELDOWN },	/* channel / program - */
-	{ 0x0d, KEY_VOLUMEUP },
-	{ 0x15, KEY_VOLUMEDOWN },
-	{ 0x4d, KEY_OK },		/* also labeled as Pause */
-	{ 0x1c, KEY_ZOOM },		/* full screen and Stop*/
-	{ 0x02, KEY_MODE },		/* AV Source or Rewind*/
-	{ 0x04, KEY_LIST },		/* -/-- */
-	/* small arrows above numbers */
-	{ 0x1a, KEY_NEXT },		/* also Fast Forward */
-	{ 0x0e, KEY_PREVIOUS },		/* also Rewind */
-	/* these are in a rather non standard layout and have
-	an alternate name written */
-	{ 0x1e, KEY_UP },		/* Video Setting */
-	{ 0x0a, KEY_DOWN },		/* Video Default */
-	{ 0x05, KEY_CAMERA },		/* Snapshot */
-	{ 0x0c, KEY_RIGHT },		/* Hide Panel */
-	/* Four buttons without label */
-	{ 0x49, KEY_RED },
-	{ 0x0b, KEY_GREEN },
-	{ 0x13, KEY_YELLOW },
-	{ 0x50, KEY_BLUE },
-};
-
-struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
-	.scan = ir_codes_genius_tvgo_a11mce,
-	.size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
-};
-EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
-
-/*
- * Remote control for Powercolor Real Angel 330
- * Daniel Fraga <fragabr@gmail.com>
- */
-static struct ir_scancode ir_codes_powercolor_real_angel[] = {
-	{ 0x38, KEY_SWITCHVIDEOMODE },	/* switch inputs */
-	{ 0x0c, KEY_MEDIA },		/* Turn ON/OFF App */
-	{ 0x00, KEY_0 },
-	{ 0x01, KEY_1 },
-	{ 0x02, KEY_2 },
-	{ 0x03, KEY_3 },
-	{ 0x04, KEY_4 },
-	{ 0x05, KEY_5 },
-	{ 0x06, KEY_6 },
-	{ 0x07, KEY_7 },
-	{ 0x08, KEY_8 },
-	{ 0x09, KEY_9 },
-	{ 0x0a, KEY_DIGITS },		/* single, double, tripple digit */
-	{ 0x29, KEY_PREVIOUS },		/* previous channel */
-	{ 0x12, KEY_BRIGHTNESSUP },
-	{ 0x13, KEY_BRIGHTNESSDOWN },
-	{ 0x2b, KEY_MODE },		/* stereo/mono */
-	{ 0x2c, KEY_TEXT },		/* teletext */
-	{ 0x20, KEY_CHANNELUP },	/* channel up */
-	{ 0x21, KEY_CHANNELDOWN },	/* channel down */
-	{ 0x10, KEY_VOLUMEUP },		/* volume up */
-	{ 0x11, KEY_VOLUMEDOWN },	/* volume down */
-	{ 0x0d, KEY_MUTE },
-	{ 0x1f, KEY_RECORD },
-	{ 0x17, KEY_PLAY },
-	{ 0x16, KEY_PAUSE },
-	{ 0x0b, KEY_STOP },
-	{ 0x27, KEY_FASTFORWARD },
-	{ 0x26, KEY_REWIND },
-	{ 0x1e, KEY_SEARCH },		/* autoscan */
-	{ 0x0e, KEY_CAMERA },		/* snapshot */
-	{ 0x2d, KEY_SETUP },
-	{ 0x0f, KEY_SCREEN },		/* full screen */
-	{ 0x14, KEY_RADIO },		/* FM radio */
-	{ 0x25, KEY_POWER },		/* power */
-};
-
-struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
-	.scan = ir_codes_powercolor_real_angel,
-	.size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
-};
-EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
-
-/* Kworld Plus TV Analog Lite PCI IR
-   Mauro Carvalho Chehab <mchehab@infradead.org>
- */
-static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
-	{ 0x0c, KEY_PROG1 },		/* Kworld key */
-	{ 0x16, KEY_CLOSECD },		/* -> ) */
-	{ 0x1d, KEY_POWER2 },
-
-	{ 0x00, KEY_1 },
-	{ 0x01, KEY_2 },
-	{ 0x02, KEY_3 },		/* Two keys have the same code: 3 and left */
-	{ 0x03, KEY_4 },		/* Two keys have the same code: 3 and right */
-	{ 0x04, KEY_5 },
-	{ 0x05, KEY_6 },
-	{ 0x06, KEY_7 },
-	{ 0x07, KEY_8 },
-	{ 0x08, KEY_9 },
-	{ 0x0a, KEY_0 },
-
-	{ 0x09, KEY_AGAIN },
-	{ 0x14, KEY_MUTE },
-
-	{ 0x20, KEY_UP },
-	{ 0x21, KEY_DOWN },
-	{ 0x0b, KEY_ENTER },
-
-	{ 0x10, KEY_CHANNELUP },
-	{ 0x11, KEY_CHANNELDOWN },
-
-	/* Couldn't map key left/key right since those
-	   conflict with '3' and '4' scancodes
-	   I dunno what the original driver does
-	 */
-
-	{ 0x13, KEY_VOLUMEUP },
-	{ 0x12, KEY_VOLUMEDOWN },
-
-	/* The lower part of the IR
-	   There are several duplicated keycodes there.
-	   Most of them conflict with digits.
-	   Add mappings just to the unused scancodes.
-	   Somehow, the original driver has a way to know,
-	   but this doesn't seem to be on some GPIO.
-	   Also, it is not related to the time between keyup
-	   and keydown.
-	 */
-	{ 0x19, KEY_TIME},		/* Timeshift */
-	{ 0x1a, KEY_STOP},
-	{ 0x1b, KEY_RECORD},
-
-	{ 0x22, KEY_TEXT},
-
-	{ 0x15, KEY_AUDIO},		/* ((*)) */
-	{ 0x0f, KEY_ZOOM},
-	{ 0x1c, KEY_CAMERA},		/* snapshot */
-
-	{ 0x18, KEY_RED},		/* B */
-	{ 0x23, KEY_GREEN},		/* C */
-};
-struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
-	.scan = ir_codes_kworld_plus_tv_analog,
-	.size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
-};
-EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
-
-/* Kaiomy TVnPC U2
-   Mauro Carvalho Chehab <mchehab@infradead.org>
- */
-static struct ir_scancode ir_codes_kaiomy[] = {
-	{ 0x43, KEY_POWER2},
-	{ 0x01, KEY_LIST},
-	{ 0x0b, KEY_ZOOM},
-	{ 0x03, KEY_POWER},
-
-	{ 0x04, KEY_1},
-	{ 0x08, KEY_2},
-	{ 0x02, KEY_3},
-
-	{ 0x0f, KEY_4},
-	{ 0x05, KEY_5},
-	{ 0x06, KEY_6},
-
-	{ 0x0c, KEY_7},
-	{ 0x0d, KEY_8},
-	{ 0x0a, KEY_9},
-
-	{ 0x11, KEY_0},
-
-	{ 0x09, KEY_CHANNELUP},
-	{ 0x07, KEY_CHANNELDOWN},
-
-	{ 0x0e, KEY_VOLUMEUP},
-	{ 0x13, KEY_VOLUMEDOWN},
-
-	{ 0x10, KEY_HOME},
-	{ 0x12, KEY_ENTER},
-
-	{ 0x14, KEY_RECORD},
-	{ 0x15, KEY_STOP},
-	{ 0x16, KEY_PLAY},
-	{ 0x17, KEY_MUTE},
-
-	{ 0x18, KEY_UP},
-	{ 0x19, KEY_DOWN},
-	{ 0x1a, KEY_LEFT},
-	{ 0x1b, KEY_RIGHT},
-
-	{ 0x1c, KEY_RED},
-	{ 0x1d, KEY_GREEN},
-	{ 0x1e, KEY_YELLOW},
-	{ 0x1f, KEY_BLUE},
-};
-struct ir_scancode_table ir_codes_kaiomy_table = {
-	.scan = ir_codes_kaiomy,
-	.size = ARRAY_SIZE(ir_codes_kaiomy),
-};
-EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
-
-static struct ir_scancode ir_codes_avermedia_a16d[] = {
-	{ 0x20, KEY_LIST},
-	{ 0x00, KEY_POWER},
-	{ 0x28, KEY_1},
-	{ 0x18, KEY_2},
-	{ 0x38, KEY_3},
-	{ 0x24, KEY_4},
-	{ 0x14, KEY_5},
-	{ 0x34, KEY_6},
-	{ 0x2c, KEY_7},
-	{ 0x1c, KEY_8},
-	{ 0x3c, KEY_9},
-	{ 0x12, KEY_SUBTITLE},
-	{ 0x22, KEY_0},
-	{ 0x32, KEY_REWIND},
-	{ 0x3a, KEY_SHUFFLE},
-	{ 0x02, KEY_PRINT},
-	{ 0x11, KEY_CHANNELDOWN},
-	{ 0x31, KEY_CHANNELUP},
-	{ 0x0c, KEY_ZOOM},
-	{ 0x1e, KEY_VOLUMEDOWN},
-	{ 0x3e, KEY_VOLUMEUP},
-	{ 0x0a, KEY_MUTE},
-	{ 0x04, KEY_AUDIO},
-	{ 0x26, KEY_RECORD},
-	{ 0x06, KEY_PLAY},
-	{ 0x36, KEY_STOP},
-	{ 0x16, KEY_PAUSE},
-	{ 0x2e, KEY_REWIND},
-	{ 0x0e, KEY_FASTFORWARD},
-	{ 0x30, KEY_TEXT},
-	{ 0x21, KEY_GREEN},
-	{ 0x01, KEY_BLUE},
-	{ 0x08, KEY_EPG},
-	{ 0x2a, KEY_MENU},
-};
-struct ir_scancode_table ir_codes_avermedia_a16d_table = {
-	.scan = ir_codes_avermedia_a16d,
-	.size = ARRAY_SIZE(ir_codes_avermedia_a16d),
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
-
-/* Encore ENLTV-FM v5.3
-   Mauro Carvalho Chehab <mchehab@infradead.org>
- */
-static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
-	{ 0x10, KEY_POWER2},
-	{ 0x06, KEY_MUTE},
-
-	{ 0x09, KEY_1},
-	{ 0x1d, KEY_2},
-	{ 0x1f, KEY_3},
-	{ 0x19, KEY_4},
-	{ 0x1b, KEY_5},
-	{ 0x11, KEY_6},
-	{ 0x17, KEY_7},
-	{ 0x12, KEY_8},
-	{ 0x16, KEY_9},
-	{ 0x48, KEY_0},
-
-	{ 0x04, KEY_LIST},		/* -/-- */
-	{ 0x40, KEY_LAST},		/* recall */
-
-	{ 0x02, KEY_MODE},		/* TV/AV */
-	{ 0x05, KEY_CAMERA},		/* SNAPSHOT */
-
-	{ 0x4c, KEY_CHANNELUP},		/* UP */
-	{ 0x00, KEY_CHANNELDOWN},	/* DOWN */
-	{ 0x0d, KEY_VOLUMEUP},		/* RIGHT */
-	{ 0x15, KEY_VOLUMEDOWN},	/* LEFT */
-	{ 0x49, KEY_ENTER},		/* OK */
-
-	{ 0x54, KEY_RECORD},
-	{ 0x4d, KEY_PLAY},		/* pause */
-
-	{ 0x1e, KEY_MENU},		/* video setting */
-	{ 0x0e, KEY_RIGHT},		/* <- */
-	{ 0x1a, KEY_LEFT},		/* -> */
-
-	{ 0x0a, KEY_CLEAR},		/* video default */
-	{ 0x0c, KEY_ZOOM},		/* hide pannel */
-	{ 0x47, KEY_SLEEP},		/* shutdown */
-};
-struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
-	.scan = ir_codes_encore_enltv_fm53,
-	.size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
-
-/* Zogis Real Audio 220 - 32 keys IR */
-static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
-	{ 0x1c, KEY_RADIO},
-	{ 0x12, KEY_POWER2},
-
-	{ 0x01, KEY_1},
-	{ 0x02, KEY_2},
-	{ 0x03, KEY_3},
-	{ 0x04, KEY_4},
-	{ 0x05, KEY_5},
-	{ 0x06, KEY_6},
-	{ 0x07, KEY_7},
-	{ 0x08, KEY_8},
-	{ 0x09, KEY_9},
-	{ 0x00, KEY_0},
-
-	{ 0x0c, KEY_VOLUMEUP},
-	{ 0x18, KEY_VOLUMEDOWN},
-	{ 0x0b, KEY_CHANNELUP},
-	{ 0x15, KEY_CHANNELDOWN},
-	{ 0x16, KEY_ENTER},
-
-	{ 0x11, KEY_LIST},		/* Source */
-	{ 0x0d, KEY_AUDIO},		/* stereo */
-
-	{ 0x0f, KEY_PREVIOUS},		/* Prev */
-	{ 0x1b, KEY_TIME},		/* Timeshift */
-	{ 0x1a, KEY_NEXT},		/* Next */
-
-	{ 0x0e, KEY_STOP},
-	{ 0x1f, KEY_PLAY},
-	{ 0x1e, KEY_PLAYPAUSE},		/* Pause */
-
-	{ 0x1d, KEY_RECORD},
-	{ 0x13, KEY_MUTE},
-	{ 0x19, KEY_CAMERA},		/* Snapshot */
-
-};
-struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
-	.scan = ir_codes_real_audio_220_32_keys,
-	.size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
-};
-EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
-
-/* ATI TV Wonder HD 600 USB
-   Devin Heitmueller <devin.heitmueller@gmail.com>
- */
-static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
-	{ 0x00, KEY_RECORD},		/* Row 1 */
-	{ 0x01, KEY_PLAYPAUSE},
-	{ 0x02, KEY_STOP},
-	{ 0x03, KEY_POWER},
-	{ 0x04, KEY_PREVIOUS},	/* Row 2 */
-	{ 0x05, KEY_REWIND},
-	{ 0x06, KEY_FORWARD},
-	{ 0x07, KEY_NEXT},
-	{ 0x08, KEY_EPG},		/* Row 3 */
-	{ 0x09, KEY_HOME},
-	{ 0x0a, KEY_MENU},
-	{ 0x0b, KEY_CHANNELUP},
-	{ 0x0c, KEY_BACK},		/* Row 4 */
-	{ 0x0d, KEY_UP},
-	{ 0x0e, KEY_INFO},
-	{ 0x0f, KEY_CHANNELDOWN},
-	{ 0x10, KEY_LEFT},		/* Row 5 */
-	{ 0x11, KEY_SELECT},
-	{ 0x12, KEY_RIGHT},
-	{ 0x13, KEY_VOLUMEUP},
-	{ 0x14, KEY_LAST},		/* Row 6 */
-	{ 0x15, KEY_DOWN},
-	{ 0x16, KEY_MUTE},
-	{ 0x17, KEY_VOLUMEDOWN},
-};
-struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
-	.scan = ir_codes_ati_tv_wonder_hd_600,
-	.size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
-};
-EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
-
-/* DVBWorld remotes
-   Igor M. Liplianin <liplianin@me.by>
- */
-static struct ir_scancode ir_codes_dm1105_nec[] = {
-	{ 0x0a, KEY_POWER2},		/* power */
-	{ 0x0c, KEY_MUTE},		/* mute */
-	{ 0x11, KEY_1},
-	{ 0x12, KEY_2},
-	{ 0x13, KEY_3},
-	{ 0x14, KEY_4},
-	{ 0x15, KEY_5},
-	{ 0x16, KEY_6},
-	{ 0x17, KEY_7},
-	{ 0x18, KEY_8},
-	{ 0x19, KEY_9},
-	{ 0x10, KEY_0},
-	{ 0x1c, KEY_CHANNELUP},		/* ch+ */
-	{ 0x0f, KEY_CHANNELDOWN},	/* ch- */
-	{ 0x1a, KEY_VOLUMEUP},		/* vol+ */
-	{ 0x0e, KEY_VOLUMEDOWN},	/* vol- */
-	{ 0x04, KEY_RECORD},		/* rec */
-	{ 0x09, KEY_CHANNEL},		/* fav */
-	{ 0x08, KEY_BACKSPACE},		/* rewind */
-	{ 0x07, KEY_FASTFORWARD},	/* fast */
-	{ 0x0b, KEY_PAUSE},		/* pause */
-	{ 0x02, KEY_ESC},		/* cancel */
-	{ 0x03, KEY_TAB},		/* tab */
-	{ 0x00, KEY_UP},		/* up */
-	{ 0x1f, KEY_ENTER},		/* ok */
-	{ 0x01, KEY_DOWN},		/* down */
-	{ 0x05, KEY_RECORD},		/* cap */
-	{ 0x06, KEY_STOP},		/* stop */
-	{ 0x40, KEY_ZOOM},		/* full */
-	{ 0x1e, KEY_TV},		/* tvmode */
-	{ 0x1b, KEY_B},			/* recall */
-};
-struct ir_scancode_table ir_codes_dm1105_nec_table = {
-	.scan = ir_codes_dm1105_nec,
-	.size = ARRAY_SIZE(ir_codes_dm1105_nec),
-};
-EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
-
-/* Terratec Cinergy Hybrid T USB XS
-   Devin Heitmueller <dheitmueller@linuxtv.org>
- */
-static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
-	{ 0x41, KEY_HOME},
-	{ 0x01, KEY_POWER},
-	{ 0x42, KEY_MENU},
-	{ 0x02, KEY_1},
-	{ 0x03, KEY_2},
-	{ 0x04, KEY_3},
-	{ 0x43, KEY_SUBTITLE},
-	{ 0x05, KEY_4},
-	{ 0x06, KEY_5},
-	{ 0x07, KEY_6},
-	{ 0x44, KEY_TEXT},
-	{ 0x08, KEY_7},
-	{ 0x09, KEY_8},
-	{ 0x0a, KEY_9},
-	{ 0x45, KEY_DELETE},
-	{ 0x0b, KEY_TUNER},
-	{ 0x0c, KEY_0},
-	{ 0x0d, KEY_MODE},
-	{ 0x46, KEY_TV},
-	{ 0x47, KEY_DVD},
-	{ 0x49, KEY_VIDEO},
-	{ 0x4b, KEY_AUX},
-	{ 0x10, KEY_UP},
-	{ 0x11, KEY_LEFT},
-	{ 0x12, KEY_OK},
-	{ 0x13, KEY_RIGHT},
-	{ 0x14, KEY_DOWN},
-	{ 0x0f, KEY_EPG},
-	{ 0x16, KEY_INFO},
-	{ 0x4d, KEY_BACKSPACE},
-	{ 0x1c, KEY_VOLUMEUP},
-	{ 0x4c, KEY_PLAY},
-	{ 0x1b, KEY_CHANNELUP},
-	{ 0x1e, KEY_VOLUMEDOWN},
-	{ 0x1d, KEY_MUTE},
-	{ 0x1f, KEY_CHANNELDOWN},
-	{ 0x17, KEY_RED},
-	{ 0x18, KEY_GREEN},
-	{ 0x19, KEY_YELLOW},
-	{ 0x1a, KEY_BLUE},
-	{ 0x58, KEY_RECORD},
-	{ 0x48, KEY_STOP},
-	{ 0x40, KEY_PAUSE},
-	{ 0x54, KEY_LAST},
-	{ 0x4e, KEY_REWIND},
-	{ 0x4f, KEY_FASTFORWARD},
-	{ 0x5c, KEY_NEXT},
-};
-struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
-	.scan = ir_codes_terratec_cinergy_xs,
-	.size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
-};
-EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
-
-/* EVGA inDtube
-   Devin Heitmueller <devin.heitmueller@gmail.com>
- */
-static struct ir_scancode ir_codes_evga_indtube[] = {
-	{ 0x12, KEY_POWER},
-	{ 0x02, KEY_MODE},	/* TV */
-	{ 0x14, KEY_MUTE},
-	{ 0x1a, KEY_CHANNELUP},
-	{ 0x16, KEY_TV2},	/* PIP */
-	{ 0x1d, KEY_VOLUMEUP},
-	{ 0x05, KEY_CHANNELDOWN},
-	{ 0x0f, KEY_PLAYPAUSE},
-	{ 0x19, KEY_VOLUMEDOWN},
-	{ 0x1c, KEY_REWIND},
-	{ 0x0d, KEY_RECORD},
-	{ 0x18, KEY_FORWARD},
-	{ 0x1e, KEY_PREVIOUS},
-	{ 0x1b, KEY_STOP},
-	{ 0x1f, KEY_NEXT},
-	{ 0x13, KEY_CAMERA},
-};
-struct ir_scancode_table ir_codes_evga_indtube_table = {
-	.scan = ir_codes_evga_indtube,
-	.size = ARRAY_SIZE(ir_codes_evga_indtube),
-};
-EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
-
-static struct ir_scancode ir_codes_videomate_s350[] = {
-	{ 0x00, KEY_TV},
-	{ 0x01, KEY_DVD},
-	{ 0x04, KEY_RECORD},
-	{ 0x05, KEY_VIDEO},	/* TV/Video */
-	{ 0x07, KEY_STOP},
-	{ 0x08, KEY_PLAYPAUSE},
-	{ 0x0a, KEY_REWIND},
-	{ 0x0f, KEY_FASTFORWARD},
-	{ 0x10, KEY_CHANNELUP},
-	{ 0x12, KEY_VOLUMEUP},
-	{ 0x13, KEY_CHANNELDOWN},
-	{ 0x14, KEY_MUTE},
-	{ 0x15, KEY_VOLUMEDOWN},
-	{ 0x16, KEY_1},
-	{ 0x17, KEY_2},
-	{ 0x18, KEY_3},
-	{ 0x19, KEY_4},
-	{ 0x1a, KEY_5},
-	{ 0x1b, KEY_6},
-	{ 0x1c, KEY_7},
-	{ 0x1d, KEY_8},
-	{ 0x1e, KEY_9},
-	{ 0x1f, KEY_0},
-	{ 0x21, KEY_SLEEP},
-	{ 0x24, KEY_ZOOM},
-	{ 0x25, KEY_LAST},	/* Recall */
-	{ 0x26, KEY_SUBTITLE},	/* CC */
-	{ 0x27, KEY_LANGUAGE},	/* MTS */
-	{ 0x29, KEY_CHANNEL},	/* SURF */
-	{ 0x2b, KEY_A},
-	{ 0x2c, KEY_B},
-	{ 0x2f, KEY_CAMERA},	/* Snapshot */
-	{ 0x23, KEY_RADIO},
-	{ 0x02, KEY_PREVIOUSSONG},
-	{ 0x06, KEY_NEXTSONG},
-	{ 0x03, KEY_EPG},
-	{ 0x09, KEY_SETUP},
-	{ 0x22, KEY_BACKSPACE},
-	{ 0x0c, KEY_UP},
-	{ 0x0e, KEY_DOWN},
-	{ 0x0b, KEY_LEFT},
-	{ 0x0d, KEY_RIGHT},
-	{ 0x11, KEY_ENTER},
-	{ 0x20, KEY_TEXT},
-};
-struct ir_scancode_table ir_codes_videomate_s350_table = {
-	.scan = ir_codes_videomate_s350,
-	.size = ARRAY_SIZE(ir_codes_videomate_s350),
-};
-EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
-
-/* GADMEI UTV330+ RM008Z remote
-   Shine Liu <shinel@foxmail.com>
- */
-static struct ir_scancode ir_codes_gadmei_rm008z[] = {
-	{ 0x14, KEY_POWER2},		/* POWER OFF */
-	{ 0x0c, KEY_MUTE},		/* MUTE */
-
-	{ 0x18, KEY_TV},		/* TV */
-	{ 0x0e, KEY_VIDEO},		/* AV */
-	{ 0x0b, KEY_AUDIO},		/* SV */
-	{ 0x0f, KEY_RADIO},		/* FM */
-
-	{ 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},
-	{ 0x0a, KEY_INFO},		/* OSD */
-	{ 0x1c, KEY_BACKSPACE},		/* LAST */
-
-	{ 0x0d, KEY_PLAY},		/* PLAY */
-	{ 0x1e, KEY_CAMERA},		/* SNAPSHOT */
-	{ 0x1a, KEY_RECORD},		/* RECORD */
-	{ 0x17, KEY_STOP},		/* STOP */
-
-	{ 0x1f, KEY_UP},		/* UP */
-	{ 0x44, KEY_DOWN},		/* DOWN */
-	{ 0x46, KEY_TAB},		/* BACK */
-	{ 0x4a, KEY_ZOOM},		/* FULLSECREEN */
-
-	{ 0x10, KEY_VOLUMEUP},		/* VOLUMEUP */
-	{ 0x11, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
-	{ 0x12, KEY_CHANNELUP},		/* CHANNELUP */
-	{ 0x13, KEY_CHANNELDOWN},	/* CHANNELDOWN */
-	{ 0x15, KEY_ENTER},		/* OK */
-};
-struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
-	.scan = ir_codes_gadmei_rm008z,
-	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
-};
-EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/Makefile linux-libre-2.6.33-gnu1/drivers/media/common/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/common/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
-ir-common-objs  := ir-functions.o ir-keymaps.o
 
 obj-y += tuners/
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
-obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_fops.c linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_fops.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_fops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_fops.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,5 @@
 #include <media/saa7146_vv.h>
 
-#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
-
 /****************************************************************************/
 /* resource management functions, shamelessly stolen from saa7134 driver */
 
@@ -194,43 +192,24 @@ void saa7146_buffer_timeout(unsigned lon
 
 static int fops_open(struct file *file)
 {
-	unsigned int minor = video_devdata(file)->minor;
-	struct saa7146_dev *h = NULL, *dev = NULL;
-	struct list_head *list;
+	struct video_device *vdev = video_devdata(file);
+	struct saa7146_dev *dev = video_drvdata(file);
 	struct saa7146_fh *fh = NULL;
 	int result = 0;
 
-	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	enum v4l2_buf_type type;
 
-	DEB_EE(("file:%p, minor:%d\n", file, minor));
+	DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev)));
 
 	if (mutex_lock_interruptible(&saa7146_devices_lock))
 		return -ERESTARTSYS;
 
-	list_for_each(list,&saa7146_devices) {
-		h = list_entry(list, struct saa7146_dev, item);
-		if( NULL == h->vv_data ) {
-			DEB_D(("device %p has not registered video devices.\n",h));
-			continue;
-		}
-		DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
-
-		if (h->vv_data->video_minor == minor) {
-			dev = h;
-		}
-		if (h->vv_data->vbi_minor == minor) {
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-			dev = h;
-		}
-	}
-	if (NULL == dev) {
-		DEB_S(("no such video device.\n"));
-		result = -ENODEV;
-		goto out;
-	}
-
 	DEB_D(("using: %p\n",dev));
 
+	type = vdev->vfl_type == VFL_TYPE_GRABBER
+	     ? V4L2_BUF_TYPE_VIDEO_CAPTURE
+	     : V4L2_BUF_TYPE_VBI_CAPTURE;
+
 	/* check if an extension is registered */
 	if( NULL == dev->ext ) {
 		DEB_S(("no extension registered for this device.\n"));
@@ -474,9 +453,6 @@ int saa7146_vv_init(struct saa7146_dev*
 	   configuration data) */
 	dev->ext_vv_data = ext_vv;
 
-	vv->video_minor = -1;
-	vv->vbi_minor = -1;
-
 	vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
 	if( NULL == vv->d_clipping.cpu_addr ) {
 		ERR(("out of memory. aborting.\n"));
@@ -515,7 +491,6 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release);
 int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
 			    char *name, int type)
 {
-	struct saa7146_vv *vv = dev->vv_data;
 	struct video_device *vfd;
 	int err;
 	int i;
@@ -543,15 +518,8 @@ int saa7146_register_device(struct video
 		return err;
 	}
 
-	if( VFL_TYPE_GRABBER == type ) {
-		vv->video_minor = vfd->minor;
-		INFO(("%s: registered device video%d [v4l2]\n",
-			dev->name, vfd->num));
-	} else {
-		vv->vbi_minor = vfd->minor;
-		INFO(("%s: registered device vbi%d [v4l2]\n",
-			dev->name, vfd->num));
-	}
+	INFO(("%s: registered device %s [v4l2]\n",
+		dev->name, video_device_node_name(vfd)));
 
 	*vid = vfd;
 	return 0;
@@ -560,16 +528,8 @@ EXPORT_SYMBOL_GPL(saa7146_register_devic
 
 int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
 {
-	struct saa7146_vv *vv = dev->vv_data;
-
 	DEB_EE(("dev:%p\n",dev));
 
-	if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
-		vv->video_minor = -1;
-	} else {
-		vv->vbi_minor = -1;
-	}
-
 	video_unregister_device(*vid);
 	*vid = NULL;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_i2c.c linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,7 +98,7 @@ static int saa7146_i2c_msg_cleanup(const
 
 		op_count++;
 
-		/* loop throgh all bytes of message i */
+		/* loop through all bytes of message i */
 		for(j = 0; j < m[i].len; j++) {
 			/* write back all bytes that could have been read */
 			m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8));
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_video.c linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_video.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/saa7146_video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/saa7146_video.c	2010-02-24 13:52:17.000000000 -0500
@@ -1205,6 +1205,13 @@ static int buffer_activate (struct saa71
 	return 0;
 }
 
+static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
+{
+	saa7146_pgtable_free(dev->pci, &buf->pt[0]);
+	saa7146_pgtable_free(dev->pci, &buf->pt[1]);
+	saa7146_pgtable_free(dev->pci, &buf->pt[2]);
+}
+
 static int buffer_prepare(struct videobuf_queue *q,
 			  struct videobuf_buffer *vb, enum v4l2_field field)
 {
@@ -1257,16 +1264,12 @@ static int buffer_prepare(struct videobu
 
 		sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
 
+		release_all_pagetables(dev, buf);
 		if( 0 != IS_PLANAR(sfmt->trans)) {
-			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
-			saa7146_pgtable_free(dev->pci, &buf->pt[1]);
-			saa7146_pgtable_free(dev->pci, &buf->pt[2]);
-
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
 		} else {
-			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
 			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
 		}
 
@@ -1329,7 +1332,10 @@ static void buffer_release(struct videob
 	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
 
 	DEB_CAP(("vbuf:%p\n",vb));
+
 	saa7146_dma_free(dev,q,buf);
+
+	release_all_pagetables(dev, buf);
 }
 
 static struct videobuf_queue_ops video_qops = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/Kconfig linux-libre-2.6.33-gnu1/drivers/media/common/tuners/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -172,4 +172,11 @@ config MEDIA_TUNER_MC44S803
 	help
 	  Say Y here to support the Freescale MC44S803 based tuners
 
+config MEDIA_TUNER_MAX2165
+	tristate "Maxim MAX2165 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  A driver for the silicon tuner MAX2165 from Maxim.
+
 endif # MEDIA_TUNER_CUSTOMISE
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/Makefile linux-libre-2.6.33-gnu1/drivers/media/common/tuners/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt21
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
 obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
+obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,442 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You 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>
+#include <linux/moduleparam.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "max2165.h"
+#include "max2165_priv.h"
+#include "tuner-i2c.h"
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG "max2165: " args); \
+	} while (0)
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
+{
+	int ret;
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+	msg.addr = priv->config->i2c_address;
+
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+			__func__, reg, data);
+
+	ret = i2c_transfer(priv->i2c, &msg, 1);
+
+	if (ret != 1)
+		dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+			__func__, reg, data, ret);
+
+	return (ret != 1) ? -EIO : 0;
+}
+
+static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
+{
+	int ret;
+	u8 dev_addr = priv->config->i2c_address;
+
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{ .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
+		{ .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
+	};
+
+	ret = i2c_transfer(priv->i2c, msg, 2);
+	if (ret != 2) {
+		dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
+			__func__, reg, ret);
+		return -EIO;
+	}
+
+	*p_data = b1[0];
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+			__func__, reg, b1[0]);
+	return 0;
+}
+
+static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
+	u8 mask, u8 data)
+{
+	int ret;
+	u8 v;
+
+	data &= mask;
+	ret = max2165_read_reg(priv, reg, &v);
+	if (ret != 0)
+		return ret;
+	v &= ~mask;
+	v |= data;
+	ret = max2165_write_reg(priv, reg, v);
+
+	return ret;
+}
+
+static int max2165_read_rom_table(struct max2165_priv *priv)
+{
+	u8 dat[3];
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
+		max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
+	}
+
+	priv->tf_ntch_low_cfg = dat[0] >> 4;
+	priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
+	priv->tf_balun_low_ref = dat[1] & 0x0F;
+	priv->tf_balun_hi_ref = dat[1] >> 4;
+	priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
+	priv->bb_filter_8mhz_cfg = dat[2] >> 4;
+
+	dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
+	dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
+	dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
+	dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
+	dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
+	dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
+
+	return 0;
+}
+
+static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
+{
+	u8 v;
+
+	v = (osc / 2);
+	if (v == 2)
+		v = 0x7;
+	else
+		v -= 8;
+
+	max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
+
+	return 0;
+}
+
+static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
+{
+	u8 val;
+
+	if (bw == BANDWIDTH_8_MHZ)
+		val = priv->bb_filter_8mhz_cfg;
+	else
+		val = priv->bb_filter_7mhz_cfg;
+
+	max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
+
+	return 0;
+}
+
+int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
+{
+	u32 remainder;
+	u32 q, f = 0;
+	int i;
+
+	if (0 == divisor)
+		return -1;
+
+	q = dividend / divisor;
+	remainder = dividend - q * divisor;
+
+	for (i = 0; i < 31; i++) {
+		remainder <<= 1;
+		if (remainder >= divisor) {
+			f += 1;
+			remainder -= divisor;
+		}
+		f <<= 1;
+	}
+
+	*quotient = q;
+	*fraction = f;
+
+	return 0;
+}
+
+static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
+{
+	u8 tf;
+	u8 tf_ntch;
+	u32 t;
+	u32 quotient, fraction;
+
+	/* Set PLL divider according to RF frequency */
+	fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
+		&quotient, &fraction);
+
+	/* 20-bit fraction */
+	fraction >>= 12;
+
+	max2165_write_reg(priv, REG_NDIV_INT, quotient);
+	max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
+	max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
+	max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
+
+	/* Norch Filter */
+	tf_ntch = (freq < 725000000) ?
+		priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
+
+	/* Tracking filter balun */
+	t = priv->tf_balun_low_ref;
+	t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
+		* (freq / 1000 - 470000) / (780000 - 470000);
+
+	tf = t;
+	dprintk("tf = %X\n", tf);
+	tf |= tf_ntch << 4;
+
+	max2165_write_reg(priv, REG_TRACK_FILTER, tf);
+
+	return 0;
+}
+
+static void max2165_debug_status(struct max2165_priv *priv)
+{
+	u8 status, autotune;
+	u8 auto_vco_success, auto_vco_active;
+	u8 pll_locked;
+	u8 dc_offset_low, dc_offset_hi;
+	u8 signal_lv_over_threshold;
+	u8 vco, vco_sub_band, adc;
+
+	max2165_read_reg(priv, REG_STATUS, &status);
+	max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
+
+	auto_vco_success = (status >> 6) & 0x01;
+	auto_vco_active = (status >> 5) & 0x01;
+	pll_locked = (status >> 4) & 0x01;
+	dc_offset_low = (status >> 3) & 0x01;
+	dc_offset_hi = (status >> 2) & 0x01;
+	signal_lv_over_threshold = status & 0x01;
+
+	vco = autotune >> 6;
+	vco_sub_band = (autotune >> 3) & 0x7;
+	adc = autotune & 0x7;
+
+	dprintk("auto VCO active: %d, auto VCO success: %d\n",
+		auto_vco_active, auto_vco_success);
+	dprintk("PLL locked: %d\n", pll_locked);
+	dprintk("DC offset low: %d, DC offset high: %d\n",
+		dc_offset_low, dc_offset_hi);
+	dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
+	dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
+}
+
+static int max2165_set_params(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	int ret;
+
+	dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency);
+	if (fe->ops.info.type == FE_ATSC) {
+			return -EINVAL;
+	} else if (fe->ops.info.type == FE_OFDM) {
+		dprintk("%s() OFDM\n", __func__);
+		switch (params->u.ofdm.bandwidth) {
+		case BANDWIDTH_6_MHZ:
+			return -EINVAL;
+		case BANDWIDTH_7_MHZ:
+		case BANDWIDTH_8_MHZ:
+			priv->frequency = params->frequency;
+			priv->bandwidth = params->u.ofdm.bandwidth;
+			break;
+		default:
+			printk(KERN_ERR "MAX2165 bandwidth not set!\n");
+			return -EINVAL;
+		}
+	} else {
+		printk(KERN_ERR "MAX2165 modulation type not supported!\n");
+		return -EINVAL;
+	}
+
+	dprintk("%s() frequency=%d\n", __func__, priv->frequency);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	max2165_set_bandwidth(priv, priv->bandwidth);
+	ret = max2165_set_rf(priv, priv->frequency);
+	mdelay(50);
+	max2165_debug_status(priv);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	if (ret != 0)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+	*freq = priv->frequency;
+	return 0;
+}
+
+static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	*bw = priv->bandwidth;
+	return 0;
+}
+
+static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	u16 lock_status = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+
+	max2165_debug_status(priv);
+	*status = lock_status;
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int max2165_sleep(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+static int max2165_init(struct dvb_frontend *fe)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	/* Setup initial values */
+	/* Fractional Mode on */
+	max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
+	/* LNA on */
+	max2165_write_reg(priv, REG_LNA, 0x01);
+	max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
+	max2165_write_reg(priv, REG_TEST, 0x08);
+	max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
+	max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
+	max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
+	max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
+	max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
+	max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
+
+	max2165_set_osc(priv, priv->config->osc_clk);
+
+	max2165_read_rom_table(priv);
+
+	max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ);
+
+	if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int max2165_release(struct dvb_frontend *fe)
+{
+	struct max2165_priv *priv = fe->tuner_priv;
+	dprintk("%s()\n", __func__);
+
+	kfree(priv);
+	fe->tuner_priv = NULL;
+
+	return 0;
+}
+
+static const struct dvb_tuner_ops max2165_tuner_ops = {
+	.info = {
+		.name           = "Maxim MAX2165",
+		.frequency_min  = 470000000,
+		.frequency_max  = 780000000,
+		.frequency_step =     50000,
+	},
+
+	.release	   = max2165_release,
+	.init		   = max2165_init,
+	.sleep		   = max2165_sleep,
+
+	.set_params	   = max2165_set_params,
+	.set_analog_params = NULL,
+	.get_frequency	   = max2165_get_frequency,
+	.get_bandwidth	   = max2165_get_bandwidth,
+	.get_status	   = max2165_get_status
+};
+
+struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   struct max2165_config *cfg)
+{
+	struct max2165_priv *priv = NULL;
+
+	dprintk("%s(%d-%04x)\n", __func__,
+		i2c ? i2c_adapter_id(i2c) : -1,
+		cfg ? cfg->i2c_address : -1);
+
+	priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return NULL;
+
+	memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+
+	priv->config = cfg;
+	priv->i2c = i2c;
+	fe->tuner_priv = priv;
+
+	max2165_init(fe);
+	max2165_debug_status(priv);
+
+	return fe;
+}
+EXPORT_SYMBOL(max2165_attach);
+
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,48 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You 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 __MAX2165_H__
+#define __MAX2165_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct max2165_config {
+	u8 i2c_address;
+	u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
+    (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
+extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c,
+	struct max2165_config *cfg);
+#else
+static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c,
+	struct max2165_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165_priv.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/max2165_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/max2165_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,60 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You 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 __MAX2165_PRIV_H__
+#define __MAX2165_PRIV_H__
+
+#define REG_NDIV_INT 0x00
+#define REG_NDIV_FRAC2 0x01
+#define REG_NDIV_FRAC1 0x02
+#define REG_NDIV_FRAC0 0x03
+#define REG_TRACK_FILTER 0x04
+#define REG_LNA 0x05
+#define REG_PLL_CFG 0x06
+#define REG_TEST 0x07
+#define REG_SHUTDOWN 0x08
+#define REG_VCO_CTRL 0x09
+#define REG_BASEBAND_CTRL 0x0A
+#define REG_DC_OFFSET_CTRL 0x0B
+#define REG_DC_OFFSET_DAC 0x0C
+#define REG_ROM_TABLE_ADDR 0x0D
+
+/* Read Only Registers */
+#define REG_ROM_TABLE_DATA 0x10
+#define REG_STATUS 0x11
+#define REG_AUTOTUNE 0x12
+
+struct max2165_priv {
+	struct max2165_config *config;
+	struct i2c_adapter *i2c;
+
+	u32 frequency;
+	u32 bandwidth;
+
+	u8 tf_ntch_low_cfg;
+	u8 tf_ntch_hi_cfg;
+	u8 tf_balun_low_ref;
+	u8 tf_balun_hi_ref;
+	u8 bb_filter_7mhz_cfg;
+	u8 bb_filter_8mhz_cfg;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5005s.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5005s.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5005s.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5005s.c	2010-02-24 13:52:17.000000000 -0500
@@ -2789,7 +2789,10 @@ static u16 MXL_TuneRF(struct dvb_fronten
 
 	/* add for 2.6.5 Special setting for QAM */
 	if (state->Mod_Type == MXL_QAM) {
-		if (state->RF_IN < 680000000)
+		if (state->config->qam_gain != 0)
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
+						   state->config->qam_gain);
+		else if (state->RF_IN < 680000000)
 			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
 		else
 			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5005s.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5005s.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5005s.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5005s.h	2010-02-24 13:52:17.000000000 -0500
@@ -108,6 +108,10 @@ struct mxl5005s_config {
 #define MXL_LOW_IF  1
 	u8 if_mode;
 
+	/* Some boards need to override the built-in logic for determining
+	   the gain when in QAM mode (the HVR-1600 is one such case) */
+	u8 qam_gain;
+
 	/* Stuff I don't know what to do with */
 	u8 AgcMasterByte;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5007t.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5007t.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/mxl5007t.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/mxl5007t.c	2010-02-24 13:52:17.000000000 -0500
@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pai
 	i = j = 0;
 
 	while (reg_pair1[i].reg || reg_pair1[i].val) {
-		while (reg_pair2[j].reg || reg_pair2[j].reg) {
+		while (reg_pair2[j].reg || reg_pair2[j].val) {
 			if (reg_pair1[i].reg != reg_pair2[j].reg) {
 				j++;
 				continue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-common.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-common.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -326,12 +326,24 @@ int tda18271_init_regs(struct dvb_fronte
 	regs[R_EB22] = 0x48;
 	regs[R_EB23] = 0xb0;
 
-	if (priv->small_i2c) {
+	switch (priv->small_i2c) {
+	case TDA18271_08_BYTE_CHUNK_INIT:
+		tda18271_write_regs(fe, 0x00, 0x08);
+		tda18271_write_regs(fe, 0x08, 0x08);
+		tda18271_write_regs(fe, 0x10, 0x08);
+		tda18271_write_regs(fe, 0x18, 0x08);
+		tda18271_write_regs(fe, 0x20, 0x07);
+		break;
+	case TDA18271_16_BYTE_CHUNK_INIT:
 		tda18271_write_regs(fe, 0x00, 0x10);
 		tda18271_write_regs(fe, 0x10, 0x10);
 		tda18271_write_regs(fe, 0x20, 0x07);
-	} else
+		break;
+	case TDA18271_39_BYTE_CHUNK_INIT:
+	default:
 		tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
+		break;
+	}
 
 	/* setup agc1 gain */
 	regs[R_EB17] = 0x00;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-fe.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-fe.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-fe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-fe.c	2010-02-24 13:52:17.000000000 -0500
@@ -256,8 +256,9 @@ static int tda18271c2_rf_tracking_filter
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
-	int tm_current, rfcal_comp, approx, i, ret;
-	u8 dc_over_dt, rf_tab;
+	int i, ret;
+	u8 tm_current, dc_over_dt, rf_tab;
+	s32 rfcal_comp, approx;
 
 	/* power up */
 	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
@@ -277,11 +278,11 @@ static int tda18271c2_rf_tracking_filter
 		return i;
 
 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
-		approx = map[i].rf_a1 *
-			(freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab;
+		approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
+			map[i].rf_b1 + rf_tab;
 	} else {
-		approx = map[i].rf_a2 *
-			(freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab;
+		approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
+			map[i].rf_b2 + rf_tab;
 	}
 
 	if (approx < 0)
@@ -292,9 +293,9 @@ static int tda18271c2_rf_tracking_filter
 	tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
 
 	/* calculate temperature compensation */
-	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
+	rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
 
-	regs[R_EB14] = approx + rfcal_comp;
+	regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
 	ret = tda18271_write_regs(fe, R_EB14, 1);
 fail:
 	return ret;
@@ -572,6 +573,7 @@ static int tda18271_rf_tracking_filters_
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
 	int bcal, rf, i;
+	s32 divisor, dividend;
 #define RF1 0
 #define RF2 1
 #define RF3 2
@@ -610,20 +612,22 @@ static int tda18271_rf_tracking_filters_
 		switch (rf) {
 		case RF1:
 			map[i].rf_a1 = 0;
-			map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1];
+			map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
 			map[i].rf1   = rf_freq[RF1] / 1000;
 			break;
 		case RF2:
-			map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] -
-					prog_cal[RF1] + prog_tab[RF1]) /
-				(s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000);
+			dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
+				   (s32)(prog_cal[RF1] + prog_tab[RF1]);
+			divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
+			map[i].rf_a1 = (dividend / divisor);
 			map[i].rf2   = rf_freq[RF2] / 1000;
 			break;
 		case RF3:
-			map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] -
-					prog_cal[RF2] + prog_tab[RF2]) /
-				(s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000);
-			map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2];
+			dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
+				   (s32)(prog_cal[RF2] + prog_tab[RF2]);
+			divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
+			map[i].rf_a2 = (dividend / divisor);
+			map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
 			map[i].rf3   = rf_freq[RF3] / 1000;
 			break;
 		default:
@@ -1181,6 +1185,48 @@ static int tda18271_get_id(struct dvb_fr
 	return ret;
 }
 
+static int tda18271_setup_configuration(struct dvb_frontend *fe,
+					struct tda18271_config *cfg)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+
+	priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
+	priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+	priv->config = (cfg) ? cfg->config : 0;
+	priv->small_i2c = (cfg) ?
+		cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
+	priv->output_opt = (cfg) ?
+		cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
+
+	return 0;
+}
+
+static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
+{
+	/* tda18271_cal_on_startup == -1 when cal module option is unset */
+	return ((tda18271_cal_on_startup == -1) ?
+		/* honor configuration setting */
+		((cfg) && (cfg->rf_cal_on_startup)) :
+		/* module option overrides configuration setting */
+		(tda18271_cal_on_startup)) ? 1 : 0;
+}
+
+static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+	struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
+
+	tda18271_setup_configuration(fe, cfg);
+
+	if (tda18271_need_cal_on_startup(cfg))
+		tda18271_init(fe);
+
+	/* override default std map with values in config struct */
+	if ((cfg) && (cfg->std_map))
+		tda18271_update_std_map(fe, cfg->std_map);
+
+	return 0;
+}
+
 static struct dvb_tuner_ops tda18271_tuner_ops = {
 	.info = {
 		.name = "NXP TDA18271HD",
@@ -1193,6 +1239,7 @@ static struct dvb_tuner_ops tda18271_tun
 	.set_params        = tda18271_set_params,
 	.set_analog_params = tda18271_set_analog_params,
 	.release           = tda18271_release,
+	.set_config        = tda18271_set_config,
 	.get_frequency     = tda18271_get_frequency,
 	.get_bandwidth     = tda18271_get_bandwidth,
 };
@@ -1213,33 +1260,14 @@ struct dvb_frontend *tda18271_attach(str
 	case 0:
 		goto fail;
 	case 1:
-	{
 		/* new tuner instance */
-		int rf_cal_on_startup;
-
-		priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
-		priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
-		priv->config = (cfg) ? cfg->config : 0;
-		priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
-		priv->output_opt = (cfg) ?
-			cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
+		fe->tuner_priv = priv;
 
-		/* tda18271_cal_on_startup == -1 when cal
-		 * module option is unset */
-		if (tda18271_cal_on_startup == -1) {
-			/* honor attach-time configuration */
-			rf_cal_on_startup =
-				((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
-		} else {
-			/* module option overrides attach configuration */
-			rf_cal_on_startup = tda18271_cal_on_startup;
-		}
+		tda18271_setup_configuration(fe, cfg);
 
 		priv->cal_initialized = false;
 		mutex_init(&priv->lock);
 
-		fe->tuner_priv = priv;
-
 		if (tda_fail(tda18271_get_id(fe)))
 			goto fail;
 
@@ -1249,12 +1277,12 @@ struct dvb_frontend *tda18271_attach(str
 		mutex_lock(&priv->lock);
 		tda18271_init_regs(fe);
 
-		if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
+		if ((tda18271_need_cal_on_startup(cfg)) &&
+		    (priv->id == TDA18271HDC2))
 			tda18271c2_rf_cal_init(fe);
 
 		mutex_unlock(&priv->lock);
 		break;
-	}
 	default:
 		/* existing tuner instance */
 		fe->tuner_priv = priv;
@@ -1271,7 +1299,11 @@ struct dvb_frontend *tda18271_attach(str
 				priv->small_i2c = cfg->small_i2c;
 			if (cfg->output_opt)
 				priv->output_opt = cfg->output_opt;
+			if (cfg->std_map)
+				tda18271_update_std_map(fe, cfg->std_map);
 		}
+		if (tda18271_need_cal_on_startup(cfg))
+			tda18271_init(fe);
 		break;
 	}
 
@@ -1298,7 +1330,7 @@ EXPORT_SYMBOL_GPL(tda18271_attach);
 MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.3");
+MODULE_VERSION("0.4");
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271.h	2010-02-24 13:52:17.000000000 -0500
@@ -78,6 +78,12 @@ enum tda18271_output_options {
 	TDA18271_OUTPUT_XT_OFF = 2,
 };
 
+enum tda18271_small_i2c {
+	TDA18271_39_BYTE_CHUNK_INIT = 0,
+	TDA18271_16_BYTE_CHUNK_INIT = 1,
+	TDA18271_08_BYTE_CHUNK_INIT = 2,
+};
+
 struct tda18271_config {
 	/* override default if freq / std settings (optional) */
 	struct tda18271_std_map *std_map;
@@ -91,12 +97,12 @@ struct tda18271_config {
 	/* output options that can be disabled */
 	enum tda18271_output_options output_opt;
 
+	/* some i2c providers cant write all 39 registers at once */
+	enum tda18271_small_i2c small_i2c;
+
 	/* force rf tracking filter calibration on startup */
 	unsigned int rf_cal_on_startup:1;
 
-	/* some i2c providers cant write all 39 registers at once */
-	unsigned int small_i2c:1;
-
 	/* interface to saa713x / tda829x */
 	unsigned int config;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-maps.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-maps.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-maps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-maps.c	2010-02-24 13:52:17.000000000 -0500
@@ -978,6 +978,7 @@ static struct tda18271_cid_target_map td
 int tda18271_lookup_cid_target(struct dvb_frontend *fe,
 			       u32 *freq, u8 *cid_target, u16 *count_limit)
 {
+	struct tda18271_priv *priv = fe->tuner_priv;
 	int i = 0;
 
 	while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-priv.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda18271-priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda18271-priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -80,10 +80,10 @@ struct tda18271_rf_tracking_filter_cal {
 	u32 rf1;
 	u32 rf2;
 	u32 rf3;
-	int rf_a1;
-	int rf_b1;
-	int rf_a2;
-	int rf_b2;
+	s32 rf_a1;
+	s32 rf_b1;
+	s32 rf_a2;
+	s32 rf_b2;
 };
 
 enum tda18271_pll {
@@ -109,11 +109,12 @@ struct tda18271_priv {
 	enum tda18271_i2c_gate gate;
 	enum tda18271_ver id;
 	enum tda18271_output_options output_opt;
+	enum tda18271_small_i2c small_i2c;
 
 	unsigned int config; /* interface to saa713x / tda829x */
-	unsigned int tm_rfcal;
 	unsigned int cal_initialized:1;
-	unsigned int small_i2c:1;
+
+	u8 tm_rfcal;
 
 	struct tda18271_map_layout *maps;
 	struct tda18271_std_map std;
@@ -135,27 +136,37 @@ extern int tda18271_debug;
 #define DBG_ADV  8
 #define DBG_CAL  16
 
-#define tda_printk(kern, fmt, arg...) \
-	printk(kern "%s: " fmt, __func__, ##arg)
+#define tda_printk(st, kern, fmt, arg...) do {\
+	if (st) { \
+		struct tda18271_priv *state = st; \
+		printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \
+			i2c_adapter_id(state->i2c_props.adap), \
+			state->i2c_props.addr, \
+			(state->role == TDA18271_MASTER) \
+			? "M" : "S", ##arg); \
+	} else \
+		printk(kern "%s: " fmt, __func__, ##arg); \
+} while (0)
 
-#define tda_dprintk(lvl, fmt, arg...) do {\
+#define tda_dprintk(st, lvl, fmt, arg...) do {\
 	if (tda18271_debug & lvl) \
-		tda_printk(KERN_DEBUG, fmt, ##arg); } while (0)
+		tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0)
 
 #define tda_info(fmt, arg...)     printk(KERN_INFO     fmt, ##arg)
-#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
-#define tda_err(fmt, arg...)  tda_printk(KERN_ERR,     fmt, ##arg)
-#define tda_dbg(fmt, arg...)  tda_dprintk(DBG_INFO,    fmt, ##arg)
-#define tda_map(fmt, arg...)  tda_dprintk(DBG_MAP,     fmt, ##arg)
-#define tda_reg(fmt, arg...)  tda_dprintk(DBG_REG,     fmt, ##arg)
-#define tda_cal(fmt, arg...)  tda_dprintk(DBG_CAL,     fmt, ##arg)
+#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
+#define tda_err(fmt, arg...)  tda_printk(priv, KERN_ERR,     fmt, ##arg)
+#define tda_dbg(fmt, arg...)  tda_dprintk(priv, DBG_INFO,    fmt, ##arg)
+#define tda_map(fmt, arg...)  tda_dprintk(priv, DBG_MAP,     fmt, ##arg)
+#define tda_reg(fmt, arg...)  tda_dprintk(priv, DBG_REG,     fmt, ##arg)
+#define tda_cal(fmt, arg...)  tda_dprintk(priv, DBG_CAL,     fmt, ##arg)
 
 #define tda_fail(ret)							     \
 ({									     \
 	int __ret;							     \
 	__ret = (ret < 0);						     \
 	if (__ret)							     \
-		tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
+		tda_printk(priv, KERN_ERR,				     \
+			   "error %d on line %d\n", ret, __LINE__);	     \
 	__ret;								     \
 })
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda8290.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda8290.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda8290.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda8290.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
 static int deemphasis_50;
+module_param(deemphasis_50, int, 0644);
 MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
 
 /* ---------------------------------------------------------------------- */
@@ -143,7 +144,8 @@ static void set_audio(struct dvb_fronten
 	}
 
 	if (params->mode == V4L2_TUNER_RADIO) {
-		priv->tda8290_easy_mode = 0x01;		/* Start with MN values */
+		/* Set TDA8295 to FM radio; Start TDA8290 with MN values */
+		priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01;
 		tuner_dbg("setting to radio FM\n");
 	} else {
 		tuner_dbg("setting tda829x to system %s\n", mode);
@@ -671,16 +673,19 @@ static int tda8290_probe(struct tuner_i2
 static int tda8295_probe(struct tuner_i2c_props *i2c_props)
 {
 #define TDA8295_ID 0x8a
+#define TDA8295C2_ID 0x8b
 	unsigned char tda8295_id[] = { 0x2f, 0x00 };
 
 	/* detect tda8295 */
 	tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
 	tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
 
-	if (tda8295_id[1] == TDA8295_ID) {
+	if ((tda8295_id[1] & 0xfe) == TDA8295_ID) {
 		if (debug)
-			printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n",
-			       __func__, i2c_adapter_id(i2c_props->adap),
+			printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
+			       __func__, (tda8295_id[1] == TDA8295_ID) ?
+			       "tda8295c1" : "tda8295c2",
+			       i2c_adapter_id(i2c_props->adap),
 			       i2c_props->addr);
 		return 0;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda9887.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda9887.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/tda9887.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/tda9887.c	2010-02-24 13:52:17.000000000 -0500
@@ -463,7 +463,7 @@ static int tda9887_set_insmod(struct dvb
 			buf[1] &= ~cQSS;
 	}
 
-	if (adjust >= 0x00 && adjust < 0x20) {
+	if (adjust < 0x20) {
 		buf[2] &= ~cTopMask;
 		buf[2] |= adjust;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/xc5000.c linux-libre-2.6.33-gnu1/drivers/media/common/tuners/xc5000.c
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/xc5000.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/xc5000.c	2013-05-03 12:03:50.000000000 -0400
@@ -61,6 +61,7 @@ struct xc5000_priv {
 	u32 bandwidth;
 	u8  video_standard;
 	u8  rf_mode;
+	u8  radio_input;
 };
 
 /* Misc Defines */
@@ -632,8 +633,12 @@ static int xc5000_set_params(struct dvb_
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret;
 
-	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
-		xc_load_fw_and_init_tuner(fe);
+	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+		if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+			dprintk(1, "Unable to load firmware and init tuner\n");
+			return -EINVAL;
+		}
+	}
 
 	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
 
@@ -739,15 +744,12 @@ static int xc5000_is_firmware_loaded(str
 	return ret;
 }
 
-static int xc5000_set_analog_params(struct dvb_frontend *fe,
+static int xc5000_set_tv_freq(struct dvb_frontend *fe,
 	struct analog_parameters *params)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 	int ret;
 
-	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
-		xc_load_fw_and_init_tuner(fe);
-
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
 
@@ -827,6 +829,86 @@ tune_channel:
 	return 0;
 }
 
+static int xc5000_set_radio_freq(struct dvb_frontend *fe,
+	struct analog_parameters *params)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret = -EINVAL;
+	u8 radio_input;
+
+	dprintk(1, "%s() frequency=%d (in units of khz)\n",
+		__func__, params->frequency);
+
+	if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
+		dprintk(1, "%s() radio input not configured\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->radio_input == XC5000_RADIO_FM1)
+		radio_input = FM_Radio_INPUT1;
+	else if  (priv->radio_input == XC5000_RADIO_FM2)
+		radio_input = FM_Radio_INPUT2;
+	else {
+		dprintk(1, "%s() unknown radio input %d\n", __func__,
+			priv->radio_input);
+		return -EINVAL;
+	}
+
+	priv->freq_hz = params->frequency * 125 / 2;
+
+	priv->rf_mode = XC_RF_MODE_AIR;
+
+	ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
+			       XC5000_Standard[radio_input].AudioMode);
+
+	if (ret != XC_RESULT_SUCCESS) {
+		printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+		return -EREMOTEIO;
+	}
+
+	ret = xc_SetSignalSource(priv, priv->rf_mode);
+	if (ret != XC_RESULT_SUCCESS) {
+		printk(KERN_ERR
+			"xc5000: xc_SetSignalSource(%d) failed\n",
+			priv->rf_mode);
+		return -EREMOTEIO;
+	}
+
+	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+
+	return 0;
+}
+
+static int xc5000_set_analog_params(struct dvb_frontend *fe,
+			     struct analog_parameters *params)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret = -EINVAL;
+
+	if (priv->i2c_props.adap == NULL)
+		return -EINVAL;
+
+	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+		if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+			dprintk(1, "Unable to load firmware and init tuner\n");
+			return -EINVAL;
+		}
+	}
+
+	switch (params->mode) {
+	case V4L2_TUNER_RADIO:
+		ret = xc5000_set_radio_freq(fe, params);
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+	case V4L2_TUNER_DIGITAL_TV:
+		ret = xc5000_set_tv_freq(fe, params);
+		break;
+	}
+
+	return ret;
+}
+
+
 static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@ struct dvb_frontend *xc5000_attach(struc
 		priv->if_khz = cfg->if_khz;
 	}
 
+	if (priv->radio_input == 0)
+		priv->radio_input = cfg->radio_input;
+
 	/* Check if firmware has been loaded. It is possible that another
 	   instance of the driver has loaded the firmware.
 	 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/common/tuners/xc5000.h linux-libre-2.6.33-gnu1/drivers/media/common/tuners/xc5000.h
--- linux-libre-2.6.32-gnu1/drivers/media/common/tuners/xc5000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/common/tuners/xc5000.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,11 +30,17 @@ struct i2c_adapter;
 struct xc5000_config {
 	u8   i2c_address;
 	u32  if_khz;
+	u8   radio_input;
 };
 
 /* xc5000 callback command */
 #define XC5000_TUNER_RESET		0
 
+/* Possible Radio inputs */
+#define XC5000_RADIO_NOT_CONFIGURED		0
+#define XC5000_RADIO_FM1			1
+#define XC5000_RADIO_FM2			2
+
 /* For each bridge framework, when it attaches either analog or digital,
  * it has to store a reference back to its _core equivalent structure,
  * so that it can service the hardware by steering gpio's etc.
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2013-05-03 12:03:50.000000000 -0400
@@ -215,7 +215,7 @@ static int cx24108_tuner_set_params(stru
 		freq = 2150000; /* satellite IF is 950..2150MHz */
 
 	/* decide which VCO to use for the input frequency */
-	for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++);
+	for(i = 1; (i < ARRAY_SIZE(osci) - 1) && (osci[i] < freq); i++);
 	printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
 	band=bandsel[i];
 	/* the gain values must be set by SetSymbolrate */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dm1105/dm1105.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/dm1105.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dm1105/dm1105.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dm1105/dm1105.c	2010-02-24 13:52:17.000000000 -0500
@@ -510,7 +510,7 @@ static void dm1105_emit_key(struct work_
 
 	data = (ircom >> 8) & 0x7f;
 
-	ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+	ir_input_keydown(ir->input_dev, &ir->ir, data);
 	ir_input_nokey(ir->input_dev, &ir->ir);
 }
 
@@ -589,7 +589,12 @@ int __devinit dm1105_ir_init(struct dm11
 	snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
 		"pci-%s/ir0", pci_name(dm1105->pdev));
 
-	ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
+	if (err < 0) {
+		input_free_device(input_dev);
+		return err;
+	}
+
 	input_dev->name = "DVB on-card IR receiver";
 	input_dev->phys = dm1105->ir.input_phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -606,19 +611,14 @@ int __devinit dm1105_ir_init(struct dm11
 
 	INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
-	err = input_register_device(input_dev);
-	if (err) {
-		input_free_device(input_dev);
-		return err;
-	}
+	err = ir_input_register(input_dev, ir_codes);
 
-	return 0;
+	return err;
 }
 
 void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
 {
-	input_unregister_device(dm1105->ir.input_dev);
-
+	ir_input_unregister(dm1105->ir.input_dev);
 }
 
 static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dmxdev.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dmxdev.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dmxdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dmxdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -761,7 +761,6 @@ static int dvb_demux_open(struct inode *
 	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
-	INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
 	init_timer(&dmxdevfilter->timer);
 
 	dvbdev->users++;
@@ -887,6 +886,7 @@ static int dvb_dmxdev_pes_filter_set(str
 	dmxdevfilter->type = DMXDEV_TYPE_PES;
 	memcpy(&dmxdevfilter->params, params,
 	       sizeof(struct dmx_pes_filter_params));
+	INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
 
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_demux.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_demux.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_demux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_demux.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/crc32.h>
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 
 #include "dvb_demux.h"
 
@@ -44,6 +45,11 @@ module_param(dvb_demux_tscheck, int, 064
 MODULE_PARM_DESC(dvb_demux_tscheck,
 		"enable transport stream continuity and TEI check");
 
+static int dvb_demux_speedcheck;
+module_param(dvb_demux_speedcheck, int, 0644);
+MODULE_PARM_DESC(dvb_demux_speedcheck,
+		"enable transport stream speed check");
+
 #define dprintk_tscheck(x...) do {                              \
 		if (dvb_demux_tscheck && printk_ratelimit())    \
 			printk(x);                              \
@@ -387,16 +393,40 @@ static void dvb_dmx_swfilter_packet(stru
 	u16 pid = ts_pid(buf);
 	int dvr_done = 0;
 
-	if (dvb_demux_tscheck) {
-		if (!demux->cnt_storage)
-			demux->cnt_storage = vmalloc(MAX_PID + 1);
+	if (dvb_demux_speedcheck) {
+		struct timespec cur_time, delta_time;
+		u64 speed_bytes, speed_timedelta;
 
-		if (!demux->cnt_storage) {
-			printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
-			dvb_demux_tscheck = 0;
-			goto no_dvb_demux_tscheck;
-		}
+		demux->speed_pkts_cnt++;
+
+		/* show speed every SPEED_PKTS_INTERVAL packets */
+		if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) {
+			cur_time = current_kernel_time();
 
+			if (demux->speed_last_time.tv_sec != 0 &&
+					demux->speed_last_time.tv_nsec != 0) {
+				delta_time = timespec_sub(cur_time,
+						demux->speed_last_time);
+				speed_bytes = (u64)demux->speed_pkts_cnt
+					* 188 * 8;
+				/* convert to 1024 basis */
+				speed_bytes = 1000 * div64_u64(speed_bytes,
+						1024);
+				speed_timedelta =
+					(u64)timespec_to_ns(&delta_time);
+				speed_timedelta = div64_u64(speed_timedelta,
+						1000000); /* nsec -> usec */
+				printk(KERN_INFO "TS speed %llu Kbits/sec \n",
+						div64_u64(speed_bytes,
+							speed_timedelta));
+			};
+
+			demux->speed_last_time = cur_time;
+			demux->speed_pkts_cnt = 0;
+		};
+	};
+
+	if (demux->cnt_storage) {
 		/* check pkt counter */
 		if (pid < MAX_PID) {
 			if (buf[1] & 0x80)
@@ -415,7 +445,6 @@ static void dvb_dmx_swfilter_packet(stru
 		};
 		/* end check */
 	};
-no_dvb_demux_tscheck:
 
 	list_for_each_entry(feed, &demux->feed_list, list_head) {
 		if ((feed->pid != pid) && (feed->pid != 0x2000))
@@ -1207,6 +1236,7 @@ int dvb_dmx_init(struct dvb_demux *dvbde
 	dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed));
 	if (!dvbdemux->feed) {
 		vfree(dvbdemux->filter);
+		dvbdemux->filter = NULL;
 		return -ENOMEM;
 	}
 	for (i = 0; i < dvbdemux->filternum; i++) {
@@ -1218,6 +1248,13 @@ int dvb_dmx_init(struct dvb_demux *dvbde
 		dvbdemux->feed[i].index = i;
 	}
 
+	if (dvb_demux_tscheck) {
+		dvbdemux->cnt_storage = vmalloc(MAX_PID + 1);
+
+		if (!dvbdemux->cnt_storage)
+			printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
+	}
+
 	INIT_LIST_HEAD(&dvbdemux->frontend_list);
 
 	for (i = 0; i < DMX_TS_PES_OTHER; i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_demux.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_demux.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_demux.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_demux.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,8 @@
 
 #define MAX_PID 0x1fff
 
+#define SPEED_PKTS_INTERVAL 50000
+
 struct dvb_demux_filter {
 	struct dmx_section_filter filter;
 	u8 maskandmode[DMX_MAX_FILTER_SIZE];
@@ -131,6 +133,9 @@ struct dvb_demux {
 	spinlock_t lock;
 
 	uint8_t *cnt_storage; /* for TS continuity check */
+
+	struct timespec speed_last_time; /* for TS speed check */
+	uint32_t speed_pkts_cnt; /* for TS speed check */
 };
 
 int dvb_dmx_init(struct dvb_demux *dvbdemux);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvbdev.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvbdev.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvbdev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvbdev.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,6 +54,8 @@
 	module_param_array(adapter_nr, short, NULL, 0444); \
 	MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
 
+struct dvb_frontend;
+
 struct dvb_adapter {
 	int num;
 	struct list_head list_head;
@@ -69,6 +71,32 @@ struct dvb_adapter {
 	int mfe_shared;			/* indicates mutually exclusive frontends */
 	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
 	struct mutex mfe_lock;		/* access lock for thread creation */
+
+	/* Allow the adapter/bridge driver to perform an action before and/or
+	 * after the core handles an ioctl:
+	 *
+	 * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
+	 * DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
+	 *
+	 * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
+	 *
+	 * return 0 to allow dvb-core to handle the ioctl.
+	 * return a positive int to prevent dvb-core from handling the ioctl,
+	 * 	and exit without error.
+	 * return a negative int to prevent dvb-core from handling the ioctl,
+	 * 	and return that value as an error.
+	 *
+	 * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
+	 *
+	 * return 0 to allow the dvb_frontend ioctl handler to exit normally.
+	 * return a negative int to cause the dvb_frontend ioctl handler to
+	 * 	return that value as an error.
+	 */
+#define DVB_FE_IOCTL_PRE 0
+#define DVB_FE_IOCTL_POST 1
+	int (*fe_ioctl_override)(struct dvb_frontend *fe,
+				 unsigned int cmd, void *parg,
+				 unsigned int stage);
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2010-02-24 13:52:17.000000000 -0500
@@ -895,104 +895,27 @@ static int dvb_frontend_clear_cache(stru
 }
 
 static struct dtv_cmds_h dtv_cmds[] = {
-	[DTV_TUNE] = {
-		.name	= "DTV_TUNE",
-		.cmd	= DTV_TUNE,
-		.set	= 1,
-	},
-	[DTV_CLEAR] = {
-		.name	= "DTV_CLEAR",
-		.cmd	= DTV_CLEAR,
-		.set	= 1,
-	},
+	_DTV_CMD(DTV_TUNE, 1, 0),
+	_DTV_CMD(DTV_CLEAR, 1, 0),
 
 	/* Set */
-	[DTV_FREQUENCY] = {
-		.name	= "DTV_FREQUENCY",
-		.cmd	= DTV_FREQUENCY,
-		.set	= 1,
-	},
-	[DTV_BANDWIDTH_HZ] = {
-		.name	= "DTV_BANDWIDTH_HZ",
-		.cmd	= DTV_BANDWIDTH_HZ,
-		.set	= 1,
-	},
-	[DTV_MODULATION] = {
-		.name	= "DTV_MODULATION",
-		.cmd	= DTV_MODULATION,
-		.set	= 1,
-	},
-	[DTV_INVERSION] = {
-		.name	= "DTV_INVERSION",
-		.cmd	= DTV_INVERSION,
-		.set	= 1,
-	},
-	[DTV_DISEQC_MASTER] = {
-		.name	= "DTV_DISEQC_MASTER",
-		.cmd	= DTV_DISEQC_MASTER,
-		.set	= 1,
-		.buffer	= 1,
-	},
-	[DTV_SYMBOL_RATE] = {
-		.name	= "DTV_SYMBOL_RATE",
-		.cmd	= DTV_SYMBOL_RATE,
-		.set	= 1,
-	},
-	[DTV_INNER_FEC] = {
-		.name	= "DTV_INNER_FEC",
-		.cmd	= DTV_INNER_FEC,
-		.set	= 1,
-	},
-	[DTV_VOLTAGE] = {
-		.name	= "DTV_VOLTAGE",
-		.cmd	= DTV_VOLTAGE,
-		.set	= 1,
-	},
-	[DTV_TONE] = {
-		.name	= "DTV_TONE",
-		.cmd	= DTV_TONE,
-		.set	= 1,
-	},
-	[DTV_PILOT] = {
-		.name	= "DTV_PILOT",
-		.cmd	= DTV_PILOT,
-		.set	= 1,
-	},
-	[DTV_ROLLOFF] = {
-		.name	= "DTV_ROLLOFF",
-		.cmd	= DTV_ROLLOFF,
-		.set	= 1,
-	},
-	[DTV_DELIVERY_SYSTEM] = {
-		.name	= "DTV_DELIVERY_SYSTEM",
-		.cmd	= DTV_DELIVERY_SYSTEM,
-		.set	= 1,
-	},
-	[DTV_HIERARCHY] = {
-		.name	= "DTV_HIERARCHY",
-		.cmd	= DTV_HIERARCHY,
-		.set	= 1,
-	},
-	[DTV_CODE_RATE_HP] = {
-		.name	= "DTV_CODE_RATE_HP",
-		.cmd	= DTV_CODE_RATE_HP,
-		.set	= 1,
-	},
-	[DTV_CODE_RATE_LP] = {
-		.name	= "DTV_CODE_RATE_LP",
-		.cmd	= DTV_CODE_RATE_LP,
-		.set	= 1,
-	},
-	[DTV_GUARD_INTERVAL] = {
-		.name	= "DTV_GUARD_INTERVAL",
-		.cmd	= DTV_GUARD_INTERVAL,
-		.set	= 1,
-	},
-	[DTV_TRANSMISSION_MODE] = {
-		.name	= "DTV_TRANSMISSION_MODE",
-		.cmd	= DTV_TRANSMISSION_MODE,
-		.set	= 1,
-	},
+	_DTV_CMD(DTV_FREQUENCY, 1, 0),
+	_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
+	_DTV_CMD(DTV_MODULATION, 1, 0),
+	_DTV_CMD(DTV_INVERSION, 1, 0),
+	_DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
+	_DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
+	_DTV_CMD(DTV_INNER_FEC, 1, 0),
+	_DTV_CMD(DTV_VOLTAGE, 1, 0),
+	_DTV_CMD(DTV_TONE, 1, 0),
+	_DTV_CMD(DTV_PILOT, 1, 0),
+	_DTV_CMD(DTV_ROLLOFF, 1, 0),
+	_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
+	_DTV_CMD(DTV_HIERARCHY, 1, 0),
+	_DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
+	_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
+	_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
+	_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
 
 	_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
 	_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
@@ -1035,43 +958,13 @@ static struct dtv_cmds_h dtv_cmds[] = {
 	_DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
 
 	/* Get */
-	[DTV_DISEQC_SLAVE_REPLY] = {
-		.name	= "DTV_DISEQC_SLAVE_REPLY",
-		.cmd	= DTV_DISEQC_SLAVE_REPLY,
-		.set	= 0,
-		.buffer	= 1,
-	},
-
-	[DTV_API_VERSION] = {
-		.name	= "DTV_API_VERSION",
-		.cmd	= DTV_API_VERSION,
-		.set	= 0,
-	},
-	[DTV_CODE_RATE_HP] = {
-		.name	= "DTV_CODE_RATE_HP",
-		.cmd	= DTV_CODE_RATE_HP,
-		.set	= 0,
-	},
-	[DTV_CODE_RATE_LP] = {
-		.name	= "DTV_CODE_RATE_LP",
-		.cmd	= DTV_CODE_RATE_LP,
-		.set	= 0,
-	},
-	[DTV_GUARD_INTERVAL] = {
-		.name	= "DTV_GUARD_INTERVAL",
-		.cmd	= DTV_GUARD_INTERVAL,
-		.set	= 0,
-	},
-	[DTV_TRANSMISSION_MODE] = {
-		.name	= "DTV_TRANSMISSION_MODE",
-		.cmd	= DTV_TRANSMISSION_MODE,
-		.set	= 0,
-	},
-	[DTV_HIERARCHY] = {
-		.name	= "DTV_HIERARCHY",
-		.cmd	= DTV_HIERARCHY,
-		.set	= 0,
-	},
+	_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
+	_DTV_CMD(DTV_API_VERSION, 0, 0),
+	_DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
+	_DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
+	_DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
+	_DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
+	_DTV_CMD(DTV_HIERARCHY, 0, 0),
 };
 
 static void dtv_property_dump(struct dtv_property *tvp)
@@ -1712,7 +1605,18 @@ static int dvb_frontend_ioctl_legacy(str
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	int err = -EOPNOTSUPP;
+	int cb_err, err = -EOPNOTSUPP;
+
+	if (fe->dvb->fe_ioctl_override) {
+		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
+						    DVB_FE_IOCTL_PRE);
+		if (cb_err < 0)
+			return cb_err;
+		if (cb_err > 0)
+			return 0;
+		/* fe_ioctl_override returning 0 allows
+		 * dvb-core to continue handling the ioctl */
+	}
 
 	switch (cmd) {
 	case FE_GET_INFO: {
@@ -1978,6 +1882,13 @@ static int dvb_frontend_ioctl_legacy(str
 		break;
 	};
 
+	if (fe->dvb->fe_ioctl_override) {
+		cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
+						    DVB_FE_IOCTL_POST);
+		if (cb_err < 0)
+			return cb_err;
+	}
+
 	return err;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.h	2010-02-24 13:52:17.000000000 -0500
@@ -160,7 +160,7 @@ struct tuner_state {
  * search callback possible return status
  *
  * DVBFE_ALGO_SEARCH_SUCCESS
- * The frontend search algorithm completed and returned succesfully
+ * The frontend search algorithm completed and returned successfully
  *
  * DVBFE_ALGO_SEARCH_ASLEEP
  * The frontend search algorithm is sleeping
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_net.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_net.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2010-02-24 13:52:17.000000000 -0500
@@ -1396,7 +1396,7 @@ static int dvb_net_do_ioctl(struct inode
 		return ret;
 	}
 
-	/* binary compatiblity cruft */
+	/* binary compatibility cruft */
 	case __NET_ADD_IF_OLD:
 	{
 		struct __dvb_net_if_old *dvbnetif = parg;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/af9015.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 13:56:57.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 12:03:58.000000000 -0400
@@ -730,7 +730,7 @@ static int af9015_read_config(struct usb
 		goto error;
 	deb_info("%s: IR mode:%d\n", __func__, val);
 	for (i = 0; i < af9015_properties_count; i++) {
-		if (val == AF9015_IR_MODE_DISABLED || val == 0x04) {
+		if (val == AF9015_IR_MODE_DISABLED) {
 			af9015_properties[i].rc_key_map = NULL;
 			af9015_properties[i].rc_key_map_size  = 0;
 		} else if (dvb_usb_af9015_remote) {
@@ -868,6 +868,16 @@ static int af9015_read_config(struct usb
 				af9015_config.ir_table_size =
 				  ARRAY_SIZE(af9015_ir_table_avermedia);
 				break;
+			case USB_VID_MSI_2:
+				af9015_properties[i].rc_key_map =
+				  af9015_rc_keys_msi_digivox_iii;
+				af9015_properties[i].rc_key_map_size =
+				  ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii);
+				af9015_config.ir_table =
+				  af9015_ir_table_msi_digivox_iii;
+				af9015_config.ir_table_size =
+				  ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
+				break;
 			}
 		}
 	}
@@ -1283,6 +1293,8 @@ static struct usb_device_id af9015_usb_t
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_MC810)},
 	{USB_DEVICE(USB_VID_KYE,       USB_PID_GENIUS_TVGO_DVB_T03)},
 /* 25 */{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_399U_2)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_PC160_T)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_SVEON_STV20)},
 	{0},
 };
 MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1296,7 +1308,7 @@ static struct dvb_usb_device_properties
 		.firmware = "/*(DEBLOBBED)*/",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1402,7 +1414,7 @@ static struct dvb_usb_device_properties
 		.firmware = "/*(DEBLOBBED)*/",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1508,7 +1520,7 @@ static struct dvb_usb_device_properties
 		.firmware = "/*(DEBLOBBED)*/",
 		.no_reconnect = 1,
 
-		.size_of_priv = sizeof(struct af9015_state), \
+		.size_of_priv = sizeof(struct af9015_state),
 
 		.num_adapters = 2,
 		.adapter = {
@@ -1554,7 +1566,7 @@ static struct dvb_usb_device_properties
 
 		.i2c_algo = &af9015_i2c_algo,
 
-		.num_device_descs = 4, /* max 9 */
+		.num_device_descs = 6, /* max 9 */
 		.devices = {
 			{
 				.name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1577,6 +1589,17 @@ static struct dvb_usb_device_properties
 				.cold_ids = {&af9015_usb_table[24], NULL},
 				.warm_ids = {NULL},
 			},
+			{
+				.name = "KWorld PlusTV DVB-T PCI Pro Card " \
+					"(DVB-T PC160-T)",
+				.cold_ids = {&af9015_usb_table[26], NULL},
+				.warm_ids = {NULL},
+			},
+			{
+				.name = "Sveon STV20 Tuner USB DVB-T HDTV",
+				.cold_ids = {&af9015_usb_table[27], NULL},
+				.warm_ids = {NULL},
+			},
 		}
 	},
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/af9015.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2010-02-24 13:52:17.000000000 -0500
@@ -95,6 +95,7 @@ enum af9015_ir_mode {
 	AF9015_IR_MODE_HID,
 	AF9015_IR_MODE_RLC,
 	AF9015_IR_MODE_RC6,
+	AF9015_IR_MODE_POLLING, /* just guess */
 };
 
 struct af9015_state {
@@ -119,6 +120,7 @@ enum af9015_remote {
 /* 5 */	AF9015_REMOTE_AVERMEDIA_KS,
 };
 
+/* LeadTek - Y04G0051 */
 /* Leadtek WinFast DTV Dongle Gold */
 static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
 	{ 0x001e, KEY_1 },
@@ -131,64 +133,96 @@ static struct dvb_usb_rc_key af9015_rc_k
 	{ 0x0025, KEY_8 },
 	{ 0x0026, KEY_9 },
 	{ 0x0027, KEY_0 },
-	{ 0x0028, KEY_ENTER },
-	{ 0x004f, KEY_VOLUMEUP },
-	{ 0x0050, KEY_VOLUMEDOWN },
-	{ 0x0051, KEY_CHANNELDOWN },
-	{ 0x0052, KEY_CHANNELUP },
+	{ 0x0028, KEY_OK },
+	{ 0x004f, KEY_RIGHT },
+	{ 0x0050, KEY_LEFT },
+	{ 0x0051, KEY_DOWN },
+	{ 0x0052, KEY_UP },
+	{ 0x011a, KEY_POWER2 },
+	{ 0x04b4, KEY_TV },
+	{ 0x04b3, KEY_RED },
+	{ 0x04b2, KEY_GREEN },
+	{ 0x04b1, KEY_YELLOW },
+	{ 0x04b0, KEY_BLUE },
+	{ 0x003d, KEY_TEXT },
+	{ 0x0113, KEY_SLEEP },
+	{ 0x0010, KEY_MUTE },
+	{ 0x0105, KEY_ESC },
+	{ 0x0009, KEY_SCREEN },
+	{ 0x010f, KEY_MENU },
+	{ 0x003f, KEY_CHANNEL },
+	{ 0x0013, KEY_REWIND },
+	{ 0x0012, KEY_PLAY },
+	{ 0x0011, KEY_FASTFORWARD },
+	{ 0x0005, KEY_PREVIOUS },
+	{ 0x0029, KEY_STOP },
+	{ 0x002b, KEY_NEXT },
+	{ 0x0041, KEY_EPG },
+	{ 0x0019, KEY_VIDEO },
+	{ 0x0016, KEY_AUDIO },
+	{ 0x0037, KEY_DOT },
+	{ 0x002a, KEY_AGAIN },
+	{ 0x002c, KEY_CAMERA },
+	{ 0x003c, KEY_NEW },
+	{ 0x0115, KEY_RECORD },
+	{ 0x010b, KEY_TIME },
+	{ 0x0043, KEY_VOLUMEUP },
+	{ 0x0042, KEY_VOLUMEDOWN },
+	{ 0x004b, KEY_CHANNELUP },
+	{ 0x004e, KEY_CHANNELDOWN },
 };
 
 static u8 af9015_ir_table_leadtek[] = {
-	0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00,
-	0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00,
-	0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00,
-	0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00,
-	0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00,
-	0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00,
-	0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00,
-	0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00,
-	0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00,
-	0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00,
-	0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00,
-	0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00,
-	0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00,
-	0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00,
-	0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00,
-	0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00,
-	0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00,
-	0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00,
-	0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00,
-	0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00,
-	0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00,
-	0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00,
-	0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00,
-	0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00,
-	0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00,
-	0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00,
-	0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00,
-	0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00,
-	0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00,
-	0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00,
-	0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00,
-	0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00,
-	0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00,
-	0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00,
-	0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00,
-	0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00,
-	0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00,
-	0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00,
-	0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00,
-	0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00,
-	0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00,
-	0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00,
-	0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00,
-	0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00,
-	0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00,
-	0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00,
+	0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */
+	0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */
+	0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */
+	0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */
+	0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */
+	0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */
+	0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */
+	0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */
+	0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */
+	0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */
+	0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/
+	0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */
+	0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */
+	0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */
+	0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */
+	0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */
+	0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */
+	0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */
+	0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */
+	0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */
+	0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */
+	0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */
+	0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */
+	0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */
+	0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */
+	0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */
+	0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */
+	0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */
+	0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */
+	0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */
+	0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */
+	0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */
+	0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */
+	0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */
+	0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */
+	0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */
+	0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */
+	0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */
+	0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */
+	0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */
+	0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */
+	0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */
+	0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */
+	0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */
+	0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */
+	0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */
+	0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */
+	0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */
+	0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */
+	0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */
 };
 
 /* TwinHan AzureWave AD-TU700(704J) */
@@ -746,4 +780,75 @@ static u8 af9015_ir_table_trekstor[] = {
 	0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
 };
 
+/* MSI DIGIVOX mini III */
+static struct dvb_usb_rc_key af9015_rc_keys_msi_digivox_iii[] = {
+	{ 0x0713, KEY_POWER },       /* [red power button] */
+	{ 0x073b, KEY_VIDEO },       /* Source */
+	{ 0x073e, KEY_ZOOM },        /* Zoom */
+	{ 0x070b, KEY_POWER2 },      /* ShutDown */
+	{ 0x071e, KEY_1 },
+	{ 0x071f, KEY_2 },
+	{ 0x0720, KEY_3 },
+	{ 0x0721, KEY_4 },
+	{ 0x0722, KEY_5 },
+	{ 0x0723, KEY_6 },
+	{ 0x0724, KEY_7 },
+	{ 0x0725, KEY_8 },
+	{ 0x0726, KEY_9 },
+	{ 0x0727, KEY_0 },
+	{ 0x0752, KEY_CHANNELUP },   /* CH+ */
+	{ 0x0751, KEY_CHANNELDOWN }, /* CH- */
+	{ 0x0750, KEY_VOLUMEUP },    /* Vol+ */
+	{ 0x074f, KEY_VOLUMEDOWN },  /* Vol- */
+	{ 0x0705, KEY_ESC },         /* [back up arrow] */
+	{ 0x0708, KEY_OK },          /* [enter arrow] */
+	{ 0x073f, KEY_RECORD },      /* Rec */
+	{ 0x0716, KEY_STOP },        /* Stop */
+	{ 0x072a, KEY_PLAY },        /* Play */
+	{ 0x073c, KEY_MUTE },        /* Mute */
+	{ 0x0718, KEY_UP },
+	{ 0x0707, KEY_DOWN },
+	{ 0x070f, KEY_LEFT },
+	{ 0x0715, KEY_RIGHT },
+	{ 0x0736, KEY_RED },
+	{ 0x0737, KEY_GREEN },
+	{ 0x072d, KEY_YELLOW },
+	{ 0x072e, KEY_BLUE },
+};
+
+static u8 af9015_ir_table_msi_digivox_iii[] = {
+	0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */
+	0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */
+	0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */
+	0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */
+	0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */
+	0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */
+	0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */
+	0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */
+	0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */
+	0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */
+	0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */
+	0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */
+	0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */
+	0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */
+	0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */
+	0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */
+	0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */
+	0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */
+	0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */
+	0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */
+	0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */
+	0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */
+	0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */
+	0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */
+	0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */
+	0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */
+	0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */
+	0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */
+	0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */
+	0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */
+	0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */
+	0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */
+};
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/anysee.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/anysee.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/anysee.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/anysee.c	2010-02-24 13:52:17.000000000 -0500
@@ -344,7 +344,7 @@ static int anysee_frontend_attach(struct
 	if (ret)
 		return ret;
 
-	err("Unkown Anysee version: %02x %02x %02x. "\
+	err("Unknown Anysee version: %02x %02x %02x. "\
 	    "Please report the <linux-dvb@linuxtv.org>.",
 	    hw_info[0], hw_info[1], hw_info[2]);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/cxusb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/cxusb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/cxusb.c	2013-05-03 13:56:59.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/cxusb.c	2013-05-03 12:04:01.000000000 -0400
@@ -36,9 +36,11 @@
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
 #include "mxl5005s.h"
+#include "max2165.h"
 #include "dib7000p.h"
 #include "dib0070.h"
 #include "lgs8gxx.h"
+#include "atbm8830.h"
 
 /* debug */
 static int dvb_usb_cxusb_debug;
@@ -714,6 +716,11 @@ static struct mxl5005s_config d680_dmb_t
 	.AgcMasterByte   = 0x00,
 };
 
+static struct max2165_config mygica_d689_max2165_cfg = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
 /* Callbacks for DVB USB */
 static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
@@ -813,6 +820,14 @@ static int cxusb_d680_dmb_tuner_attach(s
 	return (fe == NULL) ? -EIO : 0;
 }
 
+static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_frontend *fe;
+	fe = dvb_attach(max2165_attach, adap->fe,
+			&adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
+	return (fe == NULL) ? -EIO : 0;
+}
+
 static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	u8 b;
@@ -1160,6 +1175,55 @@ static int cxusb_d680_dmb_frontend_attac
 	return 0;
 }
 
+static struct atbm8830_config mygica_d689_atbm8830_cfg = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x40,
+	.serial_ts = 0,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_usb_device *d = adap->dev;
+
+	/* Select required USB configuration */
+	if (usb_set_interface(d->udev, 0, 0) < 0)
+		err("set interface failed");
+
+	/* Unblock all USB pipes */
+	usb_clear_halt(d->udev,
+		usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+	usb_clear_halt(d->udev,
+		usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+	usb_clear_halt(d->udev,
+		usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
+
+
+	/* Reset the tuner */
+	if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
+		err("clear tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+	if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
+		err("set tuner gpio failed");
+		return -EIO;
+	}
+	msleep(100);
+
+	/* Attach frontend */
+	adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
+		&d->i2c_adap);
+	if (adap->fe == NULL)
+		return -EIO;
+
+	return 0;
+}
+
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1240,6 +1304,7 @@ static struct dvb_usb_device_properties
 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
 static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
@@ -1268,6 +1333,8 @@ static int cxusb_probe(struct usb_interf
 				     THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
 				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
 	    0)
 		return 0;
 
@@ -1294,6 +1361,7 @@ static struct usb_device_id cxusb_table
 	{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
 	{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
 	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
+	{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
 	{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1836,6 +1904,55 @@ static struct dvb_usb_device_properties
 		},
 	}
 };
+
+static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl         = CYPRESS_FX2,
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = cxusb_d680_dmb_streaming_ctrl,
+			.frontend_attach  = cxusb_mygica_d689_frontend_attach,
+			.tuner_attach     = cxusb_mygica_d689_tuner_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 5,
+				.endpoint = 0x02,
+				.u = {
+					.bulk = {
+						.buffersize = 8192,
+					}
+				}
+			},
+		},
+	},
+
+	.power_ctrl       = cxusb_d680_dmb_power_ctrl,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	.rc_interval      = 100,
+	.rc_key_map       = d680_dmb_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(d680_dmb_rc_keys),
+	.rc_query         = cxusb_d680_dmb_rc_query,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			"Mygica D689 DMB-TH",
+			{ NULL },
+			{ &cxusb_table[19], NULL },
+		},
+	}
+};
 
 static struct usb_driver cxusb_driver = {
 	.name		= "dvb_usb_cxusb",
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1;
 module_param(dvb_usb_dib0700_ir_proto, int, 0644);
 MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
 
+static int nb_packet_buffer_size = 21;
+module_param(nb_packet_buffer_size, int, 0644);
+MODULE_PARM_DESC(nb_packet_buffer_size,
+	"Set the dib0700 driver data buffer size. This parameter "
+	"corresponds to the number of TS packets. The actual size of "
+	"the data buffer corresponds to this parameter "
+	"multiplied by 188 (default: 21)");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
@@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_d
 				  REQUEST_GET_VERSION,
 				  USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
 				  b, sizeof(b), USB_CTRL_GET_TIMEOUT);
-	*hwversion  = (b[0] << 24)  | (b[1] << 16)  | (b[2] << 8)  | b[3];
-	*romversion = (b[4] << 24)  | (b[5] << 16)  | (b[6] << 8)  | b[7];
-	*ramversion = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
-	*fwtype     = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
+	if (hwversion != NULL)
+		*hwversion  = (b[0] << 24)  | (b[1] << 16)  | (b[2] << 8)  | b[3];
+	if (romversion != NULL)
+		*romversion = (b[4] << 24)  | (b[5] << 16)  | (b[6] << 8)  | b[7];
+	if (ramversion != NULL)
+		*ramversion = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
+	if (fwtype != NULL)
+		*fwtype     = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
 	return ret;
 }
 
@@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_devi
 	return dib0700_ctrl_wr(d,buf,3);
 }
 
+static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
+{
+    struct dib0700_state *st = d->priv;
+    u8 b[3];
+    int ret;
+
+    if (st->fw_version >= 0x10201) {
+	b[0] = REQUEST_SET_USB_XFER_LEN;
+	b[1] = (nb_ts_packets >> 8)&0xff;
+	b[2] = nb_ts_packets & 0xff;
+
+	deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
+
+	ret = dib0700_ctrl_wr(d, b, 3);
+    } else {
+	deb_info("this firmware does not allow to change the USB xfer len\n");
+	ret = -EIO;
+    }
+    return ret;
+}
+
 /*
  * I2C master xfer function (supported in 1.20 firmware)
  */
@@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_de
 int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
 {
 	struct hexline hx;
-	int pos = 0, ret, act_len;
+	int pos = 0, ret, act_len, i, adap_num;
+	u8 b[16];
+	u32 fw_version;
 
 	u8 buf[260];
 
@@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb
 	} else
 		ret = -EIO;
 
+	/* the number of ts packet has to be at least 1 */
+	if (nb_packet_buffer_size < 1)
+		nb_packet_buffer_size = 1;
+
+	/* get the fimware version */
+	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+				  REQUEST_GET_VERSION,
+				  USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+				  b, sizeof(b), USB_CTRL_GET_TIMEOUT);
+	fw_version = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
+
+	/* set the buffer size - DVB-USB is allocating URB buffers
+	 * only after the firwmare download was successful */
+	for (i = 0; i < dib0700_device_count; i++) {
+		for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
+				adap_num++) {
+			if (fw_version >= 0x10201)
+				dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
+			else {
+				/* for fw version older than 1.20.1,
+				 * the buffersize has to be n times 512 */
+				dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
+				if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
+					dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
+			}
+		}
+	}
+
 	return ret;
 }
 
@@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_us
 {
 	struct dib0700_state *st = adap->dev->priv;
 	u8 b[4];
+	int ret;
+
+	if ((onoff != 0) && (st->fw_version >= 0x10201)) {
+		/* for firmware later than 1.20.1,
+		 * the USB xfer length can be set  */
+		ret = dib0700_set_usb_xfer_len(adap->dev,
+			st->nb_packet_buffer_size);
+		if (ret < 0) {
+			deb_info("can not set the USB xfer len\n");
+			return ret;
+		}
+	}
 
 	b[0] = REQUEST_ENABLE_VIDEO;
 	b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
@@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_inte
 
 	for (i = 0; i < dib0700_device_count; i++)
 		if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
-					&dev, adapter_nr) == 0)
-		{
+		    &dev, adapter_nr) == 0) {
+			struct dib0700_state *st = dev->priv;
+			u32 hwversion, romversion, fw_version, fwtype;
+
+			dib0700_get_version(dev, &hwversion, &romversion,
+				&fw_version, &fwtype);
+
+			deb_info("Firmware version: %x, %d, 0x%x, %d\n",
+				hwversion, romversion, fw_version, fwtype);
+
+			st->fw_version = fw_version;
+			st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
+
 			dib0700_rc_setup(dev);
+
 			return 0;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 13:57:03.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 12:04:04.000000000 -0400
@@ -18,6 +18,7 @@
 #include "xc5000.h"
 #include "s5h1411.h"
 #include "dib0070.h"
+#include "dib0090.h"
 #include "lgdt3305.h"
 #include "mxl5007t.h"
 
@@ -130,93 +131,95 @@ static int bristol_tuner_attach(struct d
 /* MT226x */
 static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
 	{
-		BAND_UHF, // band_caps
+		BAND_UHF,
 
 		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
 		* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+	    | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
 
-		1130,  // inv_gain
-		21,  // time_stabiliz
+		1130,
+		21,
 
-		0,  // alpha_level
-		118,  // thlock
+		0,
+		118,
 
-		0,     // wbd_inv
-		3530,  // wbd_ref
-		1,     // wbd_sel
-		0,     // wbd_alpha
+		0,
+		3530,
+		1,
+		0,
 
-		65535,  // agc1_max
-		33770,  // agc1_min
-		65535,  // agc2_max
-		23592,  // agc2_min
+		65535,
+		33770,
+		65535,
+		23592,
 
-		0,    // agc1_pt1
-		62,   // agc1_pt2
-		255,  // agc1_pt3
-		64,   // agc1_slope1
-		64,   // agc1_slope2
-		132,  // agc2_pt1
-		192,  // agc2_pt2
-		80,   // agc2_slope1
-		80,   // agc2_slope2
+		0,
+		62,
+		255,
+		64,
+		64,
+		132,
+		192,
+		80,
+		80,
 
-		17,  // alpha_mant
-		27,  // alpha_exp
-		23,  // beta_mant
-		51,  // beta_exp
+		17,
+		27,
+		23,
+		51,
 
-		1,  // perform_agc_softsplit
+		1,
 	}, {
-		BAND_VHF | BAND_LBAND, // band_caps
+		BAND_VHF | BAND_LBAND,
 
 		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
 		* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+		(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
+	    | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
 
-		2372, // inv_gain
-		21,   // time_stabiliz
+		2372,
+		21,
 
-		0,    // alpha_level
-		118,  // thlock
+		0,
+		118,
 
-		0,    // wbd_inv
-		3530, // wbd_ref
-		1,     // wbd_sel
-		0,    // wbd_alpha
+		0,
+		3530,
+		1,
+		0,
 
-		65535, // agc1_max
-		0,     // agc1_min
-		65535, // agc2_max
-		23592, // agc2_min
+		65535,
+		0,
+		65535,
+		23592,
 
-		0,    // agc1_pt1
-		128,  // agc1_pt2
-		128,  // agc1_pt3
-		128,  // agc1_slope1
-		0,    // agc1_slope2
-		128,  // agc2_pt1
-		253,  // agc2_pt2
-		81,   // agc2_slope1
-		0,    // agc2_slope2
+		0,
+		128,
+		128,
+		128,
+		0,
+		128,
+		253,
+		81,
+		0,
 
-		17,  // alpha_mant
-		27,  // alpha_exp
-		23,  // beta_mant
-		51,  // beta_exp
+		17,
+		27,
+		23,
+		51,
 
-		1,  // perform_agc_softsplit
+		1,
 	}
 };
 
 static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
-	60000, 30000, // internal, sampling
-	1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-	0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-	(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-	0, // ifreq
-	20452225, // timf
+	60000, 30000,
+	1, 8, 3, 1, 0,
+	0, 0, 1, 1, 2,
+	(3 << 14) | (1 << 12) | (524 << 0),
+	0,
+	20452225,
 };
 
 static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
@@ -558,8 +561,7 @@ static int dib0700_rc_query_legacy(struc
 struct dib0700_rc_response {
 	u8 report_id;
 	u8 data_state;
-	u8 system_msb;
-	u8 system_lsb;
+	u16 system;
 	u8 data;
 	u8 not_data;
 };
@@ -589,6 +591,23 @@ static int dib0700_rc_query_v1_20(struct
 		return 0;
 	}
 
+
+	switch (dvb_usb_dib0700_ir_proto) {
+	case 0:
+		poll_reply.report_id  = 0;
+		poll_reply.data_state = 1;
+		poll_reply.system     = buf[2];
+		poll_reply.data       = buf[4];
+		poll_reply.not_data   = buf[5];
+
+		/* NEC protocol sends repeat code as 0 0 0 FF */
+		if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
+		    && (poll_reply.not_data == 0xff)) {
+			poll_reply.data_state = 2;
+			break;
+		}
+		break;
+	default:
 	if (actlen != sizeof(buf)) {
 		/* We didn't get back the 6 byte message we expected */
 		err("Unexpected RC response size [%d]", actlen);
@@ -597,30 +616,26 @@ static int dib0700_rc_query_v1_20(struct
 
 	poll_reply.report_id  = buf[0];
 	poll_reply.data_state = buf[1];
-	poll_reply.system_msb = buf[2];
-	poll_reply.system_lsb = buf[3];
+		poll_reply.system     = (buf[2] << 8) | buf[3];
 	poll_reply.data       = buf[4];
 	poll_reply.not_data   = buf[5];
 
-	/*
-	info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
-	     poll_reply.report_id, poll_reply.data_state,
-	     poll_reply.system_msb, poll_reply.system_lsb,
-	     poll_reply.data, poll_reply.not_data);
-	*/
+		break;
+	}
 
 	if ((poll_reply.data + poll_reply.not_data) != 0xff) {
 		/* Key failed integrity check */
-		err("key failed integrity check: %02x %02x %02x %02x",
-		    poll_reply.system_msb, poll_reply.system_lsb,
+		err("key failed integrity check: %04x %02x %02x",
+		    poll_reply.system,
 		    poll_reply.data, poll_reply.not_data);
 		return -1;
 	}
 
+
 	/* Find the key in the map */
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
-		    rc5_data(&keymap[i]) == poll_reply.data) {
+		if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
+			rc5_data(&keymap[i]) == poll_reply.data) {
 			*event = keymap[i].event;
 			found = 1;
 			break;
@@ -628,9 +643,9 @@ static int dib0700_rc_query_v1_20(struct
 	}
 
 	if (found == 0) {
-		err("Unknown remote controller key: %02x %02x %02x %02x",
-		    poll_reply.system_msb, poll_reply.system_lsb,
-		    poll_reply.data, poll_reply.not_data);
+		err("Unknown remote controller key: %04x %02x %02x",
+			poll_reply.system,
+			poll_reply.data, poll_reply.not_data);
 		d->last_event = 0;
 		return 0;
 	}
@@ -874,51 +889,95 @@ static struct dvb_usb_rc_key dib0700_rc_
 	{ 0x1d37, KEY_RECORD },
 	{ 0x1d3b, KEY_GOTO },
 	{ 0x1d3d, KEY_POWER },
+
+	/* Key codes for the Pixelview SBTVD remote (proto NEC) */
+	{ 0x8613, KEY_MUTE },
+	{ 0x8612, KEY_POWER },
+	{ 0x8601, KEY_1 },
+	{ 0x8602, KEY_2 },
+	{ 0x8603, KEY_3 },
+	{ 0x8604, KEY_4 },
+	{ 0x8605, KEY_5 },
+	{ 0x8606, KEY_6 },
+	{ 0x8607, KEY_7 },
+	{ 0x8608, KEY_8 },
+	{ 0x8609, KEY_9 },
+	{ 0x8600, KEY_0 },
+	{ 0x860d, KEY_CHANNELUP },
+	{ 0x8619, KEY_CHANNELDOWN },
+	{ 0x8610, KEY_VOLUMEUP },
+	{ 0x860c, KEY_VOLUMEDOWN },
+
+	{ 0x860a, KEY_CAMERA },
+	{ 0x860b, KEY_ZOOM },
+	{ 0x861b, KEY_BACKSPACE },
+	{ 0x8615, KEY_ENTER },
+
+	{ 0x861d, KEY_UP },
+	{ 0x861e, KEY_DOWN },
+	{ 0x860e, KEY_LEFT },
+	{ 0x860f, KEY_RIGHT },
+
+	{ 0x8618, KEY_RECORD },
+	{ 0x861a, KEY_STOP },
+
+	/* Key codes for the EvolutePC TVWay+ remote (proto NEC) */
+	{ 0x7a00, KEY_MENU },
+	{ 0x7a01, KEY_RECORD },
+	{ 0x7a02, KEY_PLAY },
+	{ 0x7a03, KEY_STOP },
+	{ 0x7a10, KEY_CHANNELUP },
+	{ 0x7a11, KEY_CHANNELDOWN },
+	{ 0x7a12, KEY_VOLUMEUP },
+	{ 0x7a13, KEY_VOLUMEDOWN },
+	{ 0x7a40, KEY_POWER },
+	{ 0x7a41, KEY_MUTE },
 };
 
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
-	BAND_UHF | BAND_VHF,       // band_caps
+	BAND_UHF | BAND_VHF,
 
 	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
 	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+	| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
 
-	712,  // inv_gain
-	41,  // time_stabiliz
+	712,
+	41,
 
-	0,  // alpha_level
-	118,  // thlock
+	0,
+	118,
 
-	0,     // wbd_inv
-	4095,  // wbd_ref
-	0,     // wbd_sel
-	0,     // wbd_alpha
+	0,
+	4095,
+	0,
+	0,
 
-	42598,  // agc1_max
-	17694,  // agc1_min
-	45875,  // agc2_max
-	2621,  // agc2_min
-	0,  // agc1_pt1
-	76,  // agc1_pt2
-	139,  // agc1_pt3
-	52,  // agc1_slope1
-	59,  // agc1_slope2
-	107,  // agc2_pt1
-	172,  // agc2_pt2
-	57,  // agc2_slope1
-	70,  // agc2_slope2
+	42598,
+	17694,
+	45875,
+	2621,
+	0,
+	76,
+	139,
+	52,
+	59,
+	107,
+	172,
+	57,
+	70,
 
-	21,  // alpha_mant
-	25,  // alpha_exp
-	28,  // beta_mant
-	48,  // beta_exp
+	21,
+	25,
+	28,
+	48,
 
-	1,  // perform_agc_softsplit
-	{  0,     // split_min
-	   107,   // split_max
-	   51800, // global_split_min
-	   24700  // global_split_max
+	1,
+	{  0,
+	   107,
+	   51800,
+	   24700
 	},
 };
 
@@ -927,54 +986,55 @@ static struct dibx000_agc_config stk7700
 
 	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
 	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
-	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+	| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
 
-	712, // inv_gain
-	41,  // time_stabiliz
+	712,
+	41,
 
-	0,   // alpha_level
-	118, // thlock
+	0,
+	118,
 
-	0,    // wbd_inv
-	4095, // wbd_ref
-	0,    // wbd_sel
-	0,    // wbd_alpha
+	0,
+	4095,
+	0,
+	0,
 
-	42598, // agc1_max
-	16384, // agc1_min
-	42598, // agc2_max
-	    0, // agc2_min
+	42598,
+	16384,
+	42598,
+	    0,
 
-	  0,   // agc1_pt1
-	137,   // agc1_pt2
-	255,   // agc1_pt3
+	  0,
+	137,
+	255,
 
-	  0,   // agc1_slope1
-	255,   // agc1_slope2
+	  0,
+	255,
 
-	0,     // agc2_pt1
-	0,     // agc2_pt2
+	0,
+	0,
 
-	 0,    // agc2_slope1
-	41,    // agc2_slope2
+	 0,
+	41,
 
-	15, // alpha_mant
-	25, // alpha_exp
+	15,
+	25,
 
-	28, // beta_mant
-	48, // beta_exp
+	28,
+	48,
 
-	0, // perform_agc_softsplit
+	0,
 };
 
 static struct dibx000_bandwidth_config stk7700p_pll_config = {
-	60000, 30000, // internal, sampling
-	1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-	0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-	(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-	60258167, // ifreq
-	20452225, // timf
-	30000000, // xtal
+	60000, 30000,
+	1, 8, 3, 1, 0,
+	0, 0, 1, 1, 0,
+	(3 << 14) | (1 << 12) | (524 << 0),
+	60258167,
+	20452225,
+	30000000,
 };
 
 static struct dib7000m_config stk7700p_dib7000m_config = {
@@ -1060,41 +1120,42 @@ static struct dibx000_agc_config dib7070
 	BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
 	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
 	 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
-	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
 
-	600, // inv_gain
-	10,  // time_stabiliz
+	600,
+	10,
 
-	0,  // alpha_level
-	118,  // thlock
+	0,
+	118,
 
-	0,     // wbd_inv
-	3530,  // wbd_ref
-	1,     // wbd_sel
-	5,     // wbd_alpha
+	0,
+	3530,
+	1,
+	5,
 
-	65535,  // agc1_max
-		0,  // agc1_min
+	65535,
+		0,
 
-	65535,  // agc2_max
-	0,      // agc2_min
+	65535,
+	0,
 
-	0,      // agc1_pt1
-	40,     // agc1_pt2
-	183,    // agc1_pt3
-	206,    // agc1_slope1
-	255,    // agc1_slope2
-	72,     // agc2_pt1
-	152,    // agc2_pt2
-	88,     // agc2_slope1
-	90,     // agc2_slope2
+	0,
+	40,
+	183,
+	206,
+	255,
+	72,
+	152,
+	88,
+	90,
 
-	17,  // alpha_mant
-	27,  // alpha_exp
-	23,  // beta_mant
-	51,  // beta_exp
+	17,
+	27,
+	23,
+	51,
 
-	0,  // perform_agc_softsplit
+	0,
 };
 
 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
@@ -1133,6 +1194,7 @@ static struct dib0070_config dib7770p_di
 	 .clock_khz = 12000,
 	 .clock_pad_drive = 0,
 	 .flip_chip = 1,
+	 .charge_pump = 2,
 };
 
 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
@@ -1209,14 +1271,24 @@ static int dib7070p_tuner_attach(struct
 	return 0;
 }
 
+static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
+{
+    return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
+}
+
+static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+    return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
+}
+
 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
-	60000, 15000, // internal, sampling
-	1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
-	0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
-	(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
-	(0 << 25) | 0, // ifreq = 0.000000 MHz
-	20452225, // timf
-	12000000, // xtal_hz
+	60000, 15000,
+	1, 20, 3, 1, 0,
+	0, 0, 1, 1, 2,
+	(3 << 14) | (1 << 12) | (524 << 0),
+	(0 << 25) | 0,
+	20452225,
+	12000000,
 };
 
 static struct dib7000p_config dib7070p_dib7000p_config = {
@@ -1410,12 +1482,12 @@ static struct dib8000_config dib807x_dib
 	}
 };
 
-static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
 {
 	return dib8000_set_gpio(fe, 5, 0, !onoff);
 }
 
-static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
 {
 	return dib8000_set_gpio(fe, 0, 0, onoff);
 }
@@ -1428,8 +1500,8 @@ static const struct dib0070_wbd_gain_cfg
 static struct dib0070_config dib807x_dib0070_config[2] = {
 	{
 		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-		.reset = dib807x_tuner_reset,
-		.sleep = dib807x_tuner_sleep,
+		.reset = dib80xx_tuner_reset,
+		.sleep = dib80xx_tuner_sleep,
 		.clock_khz = 12000,
 		.clock_pad_drive = 4,
 		.vga_filter = 1,
@@ -1442,8 +1514,8 @@ static struct dib0070_config dib807x_dib
 		.freq_offset_khz_vhf = -100,
 	}, {
 		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
-		.reset = dib807x_tuner_reset,
-		.sleep = dib807x_tuner_sleep,
+		.reset = dib80xx_tuner_reset,
+		.sleep = dib80xx_tuner_sleep,
 		.clock_khz = 12000,
 		.clock_pad_drive = 2,
 		.vga_filter = 1,
@@ -1500,6 +1572,17 @@ static int dib807x_tuner_attach(struct d
 	return 0;
 }
 
+static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
+	u16 pid, int onoff)
+{
+    return dib8000_pid_filter(adapter->fe, index, pid, onoff);
+}
+
+static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
+	int onoff)
+{
+    return dib8000_pid_filter_ctrl(adapter->fe, onoff);
+}
 
 /* STK807x */
 static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1549,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(s
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
 	/* initialize IC 0 */
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
 
 	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
 			      &dib807x_dib8000_config[0]);
@@ -1560,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(s
 static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
 {
 	/* initialize IC 1 */
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
 
 	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
 			      &dib807x_dib8000_config[1]);
@@ -1568,6 +1651,245 @@ static int stk807xpvr_frontend_attach1(s
 	return adap->fe == NULL ? -ENODEV : 0;
 }
 
+/* STK8096GP */
+struct dibx000_agc_config dib8090_agc_config[2] = {
+    {
+	BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+     * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+     * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+	787,
+	10,
+
+	0,
+	118,
+
+	0,
+	3530,
+	1,
+	5,
+
+	65535,
+	0,
+
+	65535,
+	0,
+
+	0,
+	32,
+	114,
+	143,
+	144,
+	114,
+	227,
+	116,
+	117,
+
+	28,
+	26,
+	31,
+	51,
+
+	0,
+    },
+    {
+	BAND_CBAND,
+	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
+     * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+     * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+	(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+	| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+
+	787,
+	10,
+
+	0,
+	118,
+
+	0,
+	3530,
+	1,
+	5,
+
+	0,
+	0,
+
+	65535,
+	0,
+
+	0,
+	32,
+	114,
+	143,
+	144,
+	114,
+	227,
+	116,
+	117,
+
+	28,
+	26,
+	31,
+	51,
+
+	0,
+    }
+};
+
+static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
+    54000, 13500,
+    1, 18, 3, 1, 0,
+    0, 0, 1, 1, 2,
+    (3 << 14) | (1 << 12) | (599 << 0),
+    (0 << 25) | 0,
+    20199727,
+    12000000,
+};
+
+static int dib8090_get_adc_power(struct dvb_frontend *fe)
+{
+    return dib8000_get_adc_power(fe, 1);
+}
+
+static struct dib8000_config dib809x_dib8000_config = {
+    .output_mpeg2_in_188_bytes = 1,
+
+    .agc_config_count = 2,
+    .agc = dib8090_agc_config,
+    .agc_control = dib0090_dcc_freq,
+    .pll = &dib8090_pll_config_12mhz,
+    .tuner_is_baseband = 1,
+
+    .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+    .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+    .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+    .hostbus_diversity = 1,
+    .div_cfg = 0x31,
+    .output_mode = OUTMODE_MPEG2_FIFO,
+    .drives = 0x2d98,
+    .diversity_delay = 144,
+    .refclksel = 3,
+};
+
+static struct dib0090_config dib809x_dib0090_config = {
+    .io.pll_bypass = 1,
+    .io.pll_range = 1,
+    .io.pll_prediv = 1,
+    .io.pll_loopdiv = 20,
+    .io.adc_clock_ratio = 8,
+    .io.pll_int_loop_filt = 0,
+    .io.clock_khz = 12000,
+    .reset = dib80xx_tuner_reset,
+    .sleep = dib80xx_tuner_sleep,
+    .clkouttobamse = 1,
+    .analog_output = 1,
+    .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
+    .wbd_vhf_offset = 100,
+    .wbd_cband_offset = 450,
+    .use_pwm_agc = 1,
+    .clkoutdrive = 1,
+    .get_adc_power = dib8090_get_adc_power,
+	.freq_offset_khz_uhf = 0,
+	.freq_offset_khz_vhf = -143,
+};
+
+static int dib8096_set_param_override(struct dvb_frontend *fe,
+		struct dvb_frontend_parameters *fep)
+{
+    struct dvb_usb_adapter *adap = fe->dvb->priv;
+    struct dib0700_adapter_state *state = adap->priv;
+    u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+    u16 offset;
+    int ret = 0;
+    enum frontend_tune_state tune_state = CT_SHUTDOWN;
+    u16 ltgain, rf_gain_limit;
+
+    ret = state->set_param_save(fe, fep);
+    if (ret < 0)
+	return ret;
+
+    switch (band) {
+    case BAND_VHF:
+	    offset = 100;
+	    break;
+    case BAND_UHF:
+	    offset = 550;
+	    break;
+    default:
+	    offset = 0;
+	    break;
+    }
+    offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
+    dib8000_set_wbd_ref(fe, offset);
+
+
+    if (band == BAND_CBAND) {
+	deb_info("tuning in CBAND - soft-AGC startup\n");
+	/* TODO specific wbd target for dib0090 - needed for startup ? */
+	dib0090_set_tune_state(fe, CT_AGC_START);
+	do {
+		ret = dib0090_gain_control(fe);
+		msleep(ret);
+		tune_state = dib0090_get_tune_state(fe);
+		if (tune_state == CT_AGC_STEP_0)
+			dib8000_set_gpio(fe, 6, 0, 1);
+		else if (tune_state == CT_AGC_STEP_1) {
+			dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
+			if (rf_gain_limit == 0)
+				dib8000_set_gpio(fe, 6, 0, 0);
+		}
+	} while (tune_state < CT_AGC_STOP);
+	dib0090_pwm_gain_reset(fe);
+	dib8000_pwm_agc_reset(fe);
+	dib8000_set_tune_state(fe, CT_DEMOD_START);
+    } else {
+	deb_info("not tuning in CBAND - standard AGC startup\n");
+	dib0090_pwm_gain_reset(fe);
+    }
+
+    return 0;
+}
+
+static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+    struct dib0700_adapter_state *st = adap->priv;
+    struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+    if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+	return -ENODEV;
+
+    st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+    adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
+    return 0;
+}
+
+static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
+
+	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
+
+	return adap->fe == NULL ?  -ENODEV : 0;
+}
 
 /* STK7070PD */
 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
@@ -1854,13 +2176,17 @@ struct usb_device_id dib0700_usb_id_tabl
 	{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
 /* 55 */{ USB_DEVICE(USB_VID_YUAN,	USB_PID_YUAN_STK7700D_2) },
 	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73A) },
-	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73ESE) },
-	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV282E) },
+	{ USB_DEVICE(USB_VID_PCTV,	USB_PID_PINNACLE_PCTV73ESE) },
+	{ USB_DEVICE(USB_VID_PCTV,	USB_PID_PINNACLE_PCTV282E) },
 	{ USB_DEVICE(USB_VID_DIBCOM,	USB_PID_DIBCOM_STK7770P) },
 /* 60 */{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_XXS_2) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
 	{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
+	{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
+/* 65 */{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73ESE) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV282E) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096GP) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1895,6 +2221,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700p_frontend_attach,
 				.tuner_attach     = stk7700p_tuner_attach,
 
@@ -1976,11 +2306,19 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700d_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
 				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
 			}, {
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700d_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
@@ -2023,6 +2361,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700P2_frontend_attach,
 				.tuner_attach     = stk7700d_tuner_attach,
 
@@ -2055,6 +2397,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2122,6 +2468,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2138,11 +2488,11 @@ struct dvb_usb_device_properties dib0700
 				{ NULL },
 			},
 			{   "Pinnacle PCTV 73e SE",
-				{ &dib0700_usb_id_table[57], NULL },
+				{ &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
 				{ NULL },
 			},
 			{   "Pinnacle PCTV 282e",
-				{ &dib0700_usb_id_table[58], NULL },
+				{ &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
 				{ NULL },
 			},
 		},
@@ -2157,6 +2507,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070pd_frontend_attach0,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2164,6 +2518,10 @@ struct dvb_usb_device_properties dib0700
 
 				.size_of_priv     = sizeof(struct dib0700_adapter_state),
 			}, {
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070pd_frontend_attach1,
 				.tuner_attach     = dib7070p_tuner_attach,
 
@@ -2210,6 +2568,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7700ph_frontend_attach,
 				.tuner_attach     = stk7700ph_tuner_attach,
 
@@ -2322,6 +2684,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
 				.frontend_attach  = stk7070p_frontend_attach,
 				.tuner_attach     = dib7770p_tuner_attach,
 
@@ -2353,6 +2719,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 1,
 		.adapter = {
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk80xx_pid_filter,
+				.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
 				.frontend_attach  = stk807x_frontend_attach,
 				.tuner_attach     = dib807x_tuner_attach,
 
@@ -2363,7 +2733,7 @@ struct dvb_usb_device_properties dib0700
 			},
 		},
 
-		.num_device_descs = 2,
+		.num_device_descs = 3,
 		.devices = {
 			{   "DiBcom STK807xP reference design",
 				{ &dib0700_usb_id_table[62], NULL },
@@ -2373,6 +2743,10 @@ struct dvb_usb_device_properties dib0700
 				{ &dib0700_usb_id_table[63], NULL },
 				{ NULL },
 			},
+			{   "EvolutePC TVWay+",
+				{ &dib0700_usb_id_table[64], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -2384,6 +2758,10 @@ struct dvb_usb_device_properties dib0700
 		.num_adapters = 2,
 		.adapter = {
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk80xx_pid_filter,
+				.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
 				.frontend_attach  = stk807xpvr_frontend_attach0,
 				.tuner_attach     = dib807x_tuner_attach,
 
@@ -2393,6 +2771,10 @@ struct dvb_usb_device_properties dib0700
 					sizeof(struct dib0700_adapter_state),
 			},
 			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk80xx_pid_filter,
+				.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
 				.frontend_attach  = stk807xpvr_frontend_attach1,
 				.tuner_attach     = dib807x_tuner_attach,
 
@@ -2410,6 +2792,37 @@ struct dvb_usb_device_properties dib0700
 				{ NULL },
 			},
 		},
+
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+					DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk80xx_pid_filter,
+				.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+				.frontend_attach  = stk809x_frontend_attach,
+				.tuner_attach     = dib809x_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom STK8096GP reference design",
+				{ &dib0700_usb_id_table[67], NULL },
+				{ NULL },
+			},
+		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
 		.rc_key_map       = dib0700_rc_keys,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dib0700.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dib0700.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug;
 #define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
 #define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
 
-#define REQUEST_I2C_READ     0x2
-#define REQUEST_I2C_WRITE    0x3
-#define REQUEST_POLL_RC      0x4 /* deprecated in firmware v1.20 */
-#define REQUEST_JUMPRAM      0x8
-#define REQUEST_SET_CLOCK    0xB
-#define REQUEST_SET_GPIO     0xC
-#define REQUEST_ENABLE_VIDEO 0xF
+#define REQUEST_SET_USB_XFER_LEN    0x0 /* valid only for firmware version */
+					/* higher than 1.21 */
+#define REQUEST_I2C_READ            0x2
+#define REQUEST_I2C_WRITE           0x3
+#define REQUEST_POLL_RC             0x4 /* deprecated in firmware v1.20 */
+#define REQUEST_JUMPRAM             0x8
+#define REQUEST_SET_CLOCK           0xB
+#define REQUEST_SET_GPIO            0xC
+#define REQUEST_ENABLE_VIDEO        0xF
 	// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
 	// 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
 	// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
-#define REQUEST_SET_RC       0x11
-#define REQUEST_NEW_I2C_READ 0x12
-#define REQUEST_NEW_I2C_WRITE 0x13
-#define REQUEST_GET_VERSION  0x15
+#define REQUEST_SET_RC              0x11
+#define REQUEST_NEW_I2C_READ        0x12
+#define REQUEST_NEW_I2C_WRITE       0x13
+#define REQUEST_GET_VERSION         0x15
 
 struct dib0700_state {
 	u8 channel_state;
@@ -44,6 +46,8 @@ struct dib0700_state {
 	u8 is_dib7000pc;
 	u8 fw_use_new_i2c_api;
 	u8 disable_streaming_master_mode;
+    u32 fw_version;
+    u32 nb_packet_buffer_size;
 };
 
 extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dibusb-common.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dibusb-common.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dibusb-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dibusb-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_ad
 		} else if ((msg[i].flags & I2C_M_RD) == 0) {
 			if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
 				break;
-		} else
-			break;
+		} else if (msg[i].addr != 0x50) {
+			/* 0x50 is the address of the eeprom - we need to protect it
+			 * from dibusb's bad i2c implementation: reads without
+			 * writing the offset before are forbidden */
+			if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
+				break;
+		}
 	}
 
 	mutex_unlock(&d->i2c_mutex);
@@ -243,6 +248,12 @@ static struct dib3000mc_config mod3000p_
 
 int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
 {
+	if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+			adap->dev->udev->descriptor.idProduct ==
+			USB_PID_LITEON_DVB_T_WARM) {
+		msleep(1000);
+	}
+
 	if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS,  &mod3000p_dib3000p_config)) != NULL ||
 		(adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
 		if (adap->priv != NULL) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dibusb-mb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dibusb-mb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dibusb-mb.c	2013-05-03 13:57:05.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dibusb-mb.c	2013-05-03 12:04:06.000000000 -0400
@@ -242,7 +242,7 @@ static struct dvb_usb_device_properties
 			{ &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
 			{ &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
 		},
-		{	"Unkown USB1.1 DVB-T device ???? please report the name to the author",
+		{	"Unknown USB1.1 DVB-T device ???? please report the name to the author",
 			{ &dibusb_dib3000mb_table[13], NULL },
 			{ &dibusb_dib3000mb_table[14], NULL },
 		},
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -88,6 +88,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_
 		goto err;
 	}
 	adap->dvb_adap.priv = adap;
+	adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override;
 
 	if (adap->dev->props.read_mac_address) {
 		if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -162,6 +162,9 @@ struct dvb_usb_adapter_properties {
 	struct usb_data_stream_properties stream;
 
 	int size_of_priv;
+
+	int (*fe_ioctl_override) (struct dvb_frontend *,
+				  unsigned int, void *, unsigned int);
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
 #define USB_VID_DIBCOM				0x10b8
 #define USB_VID_DPOSH				0x1498
 #define USB_VID_DVICO				0x0fe9
+#define USB_VID_E3C				0x18b4
 #define USB_VID_ELGATO				0x0fd9
 #define USB_VID_EMPIA				0xeb1a
 #define USB_VID_GENPIX				0x09c0
@@ -46,6 +47,7 @@
 #define USB_VID_MSI_2				0x1462
 #define USB_VID_OPERA1				0x695c
 #define USB_VID_PINNACLE			0x2304
+#define USB_VID_PCTV				0x2013
 #define USB_VID_PIXELVIEW			0x1554
 #define USB_VID_TECHNOTREND			0x0b48
 #define USB_VID_TERRATEC			0x0ccd
@@ -61,6 +63,7 @@
 #define USB_VID_XTENSIONS			0x1ae7
 #define USB_VID_HUMAX_COEX			0x10b9
 #define USB_VID_774				0x7a69
+#define USB_VID_EVOLUTEPC			0x1e59
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -99,10 +102,16 @@
 #define USB_PID_DIBCOM_STK7070PD			0x1ebe
 #define USB_PID_DIBCOM_STK807XP				0x1f90
 #define USB_PID_DIBCOM_STK807XPVR			0x1f98
+#define USB_PID_DIBCOM_STK8096GP                        0x1fa0
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
 #define USB_PID_DIBCOM_STK7770P				0x1e80
 #define USB_PID_DPOSH_M9206_COLD			0x9206
 #define USB_PID_DPOSH_M9206_WARM			0xa090
+#define USB_PID_E3C_EC168				0x1689
+#define USB_PID_E3C_EC168_2				0xfffa
+#define USB_PID_E3C_EC168_3				0xfffb
+#define USB_PID_E3C_EC168_4				0x1001
+#define USB_PID_E3C_EC168_5				0x1002
 #define USB_PID_UNIWILL_STK7700P			0x6003
 #define USB_PID_GENIUS_TVGO_DVB_T03			0x4012
 #define USB_PID_GRANDTEC_DVBT_USB_COLD			0x0fa0
@@ -115,6 +124,7 @@
 #define USB_PID_KWORLD_395U_3				0xe395
 #define USB_PID_KWORLD_MC810				0xc810
 #define USB_PID_KWORLD_PC160_2T				0xc160
+#define USB_PID_KWORLD_PC160_T				0xc161
 #define USB_PID_KWORLD_VSTREAM_COLD			0x17de
 #define USB_PID_KWORLD_VSTREAM_WARM			0x17df
 #define USB_PID_TERRATEC_CINERGY_T_USB_XE		0x0055
@@ -203,6 +213,7 @@
 #define USB_PID_PINNACLE_PCTV801E_SE			0x023b
 #define USB_PID_PINNACLE_PCTV73A			0x0243
 #define USB_PID_PINNACLE_PCTV73ESE			0x0245
+#define USB_PID_PINNACLE_PCTV74E			0x0246
 #define USB_PID_PINNACLE_PCTV282E			0x0248
 #define USB_PID_PIXELVIEW_SBTVD				0x5010
 #define USB_PID_PCTV_200E				0x020e
@@ -271,10 +282,13 @@
 #define USB_PID_TELESTAR_STARSTICK_2			0x8000
 #define USB_PID_MSI_DIGI_VOX_MINI_III                   0x8807
 #define USB_PID_SONY_PLAYTV				0x0003
+#define USB_PID_MYGICA_D689				0xd811
 #define USB_PID_ELGATO_EYETV_DTT			0x0021
 #define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
 #define USB_PID_FRIIO_WHITE				0x0001
+#define USB_PID_TVWAY_PLUS				0x0002
+#define USB_PID_SVEON_STV20				0xe39d
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-remote.c	2010-02-24 13:52:17.000000000 -0500
@@ -259,7 +259,7 @@ int dvb_usb_nec_rc_key_to_event(struct d
 			*state = REMOTE_KEY_REPEAT;
 			break;
 		default:
-			deb_err("unkown type of remote status: %d\n",keybuf[0]);
+			deb_err("unknown type of remote status: %d\n",keybuf[0]);
 			break;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dw2102.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dw2102.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2013-05-03 13:57:14.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2013-05-03 12:04:18.000000000 -0400
@@ -20,6 +20,11 @@
 #include "tda1002x.h"
 #include "mt312.h"
 #include "zl10039.h"
+#include "ds3000.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
 
 #ifndef USB_PID_DW2102
 #define USB_PID_DW2102 0x2102
@@ -37,12 +42,20 @@
 #define USB_PID_CINERGY_S 0x0064
 #endif
 
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
+#endif
+
 #ifndef USB_PID_TEVII_S650
 #define USB_PID_TEVII_S650 0xd650
 #endif
 
-#ifndef USB_PID_TEVII_S630
-#define USB_PID_TEVII_S630 0xd630
+#ifndef USB_PID_TEVII_S660
+#define USB_PID_TEVII_S660 0xd660
+#endif
+
+#ifndef USB_PID_PROF_1100
+#define USB_PID_PROF_1100 0xb012
 #endif
 
 #define DW210X_READ_MSG 0
@@ -55,6 +68,10 @@
 #define DW2102_VOLTAGE_CTRL (0x1800)
 #define DW2102_RC_QUERY (0x1a00)
 
+#define	err_str "did not find the firmware file. (%s) " \
+		"Please see linux/Documentation/dvb/ for more details " \
+		"on firmware-problems."
+
 struct dvb_usb_rc_keys_table {
 	struct dvb_usb_rc_key *rc_keys;
 	int rc_keys_size;
@@ -71,6 +88,12 @@ static int ir_keymap;
 module_param_named(keymap, ir_keymap, int, 0644);
 MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ...");
 
+/* demod probe */
+static int demod_probe = 1;
+module_param_named(demod, demod_probe, int, 0644);
+MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
+			"4=stv0903+stb6100(or-able)).");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(str
 	switch (num) {
 	case 2:
 		/* read si2109 register by number */
-		buf6[0] = 0xd0;
+		buf6[0] = msg[0].addr << 1;
 		buf6[1] = msg[0].len;
 		buf6[2] = msg[0].buf[0];
 		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(str
 		switch (msg[0].addr) {
 		case 0x68:
 			/* write to si2109 register */
-			buf6[0] = 0xd0;
+			buf6[0] = msg[0].addr << 1;
 			buf6[1] = msg[0].len;
 			memcpy(buf6 + 2, msg[0].buf, msg[0].len);
 			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(str
 		/* read */
 		/* first write first register number */
 		u8 ibuf[msg[1].len + 2], obuf[3];
-		obuf[0] = 0xd0;
+		obuf[0] = msg[0].addr << 1;
 		obuf[1] = msg[0].len;
 		obuf[2] = msg[0].buf[0];
 		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(str
 		case 0x68: {
 			/* write to register */
 			u8 obuf[msg[0].len + 2];
-			obuf[0] = 0xd0;
+			obuf[0] = msg[0].addr << 1;
 			obuf[1] = msg[0].len;
 			memcpy(obuf + 2, msg[0].buf, msg[0].len);
 			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(str
 		case 0x61: {
 			/* write to tuner */
 			u8 obuf[msg[0].len + 2];
-			obuf[0] = 0xc2;
+			obuf[0] = msg[0].addr << 1;
 			obuf[1] = msg[0].len;
 			memcpy(obuf + 2, msg[0].buf, msg[0].len);
 			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	int ret = 0;
-	int len, i;
+	int len, i, j;
 
 	if (!d)
 		return -ENODEV;
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
 
-	switch (num) {
-	case 2: {
-		/* read */
-		/* first write first register number */
-		u8 ibuf[msg[1].len + 2], obuf[3];
-		obuf[0] = 0xaa;
-		obuf[1] = msg[0].len;
-		obuf[2] = msg[0].buf[0];
-		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-		/* second read registers */
-		ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
-				ibuf, msg[1].len + 2, DW210X_READ_MSG);
-		memcpy(msg[1].buf, ibuf + 2, msg[1].len);
-
-		break;
-	}
-	case 1:
-		switch (msg[0].addr) {
-		case 0x55: {
-			if (msg[0].buf[0] == 0xf7) {
-				/* firmware */
-				/* Write in small blocks */
-				u8 obuf[19];
-				obuf[0] = 0xaa;
-				obuf[1] = 0x11;
-				obuf[2] = 0xf7;
-				len = msg[0].len - 1;
-				i = 1;
-				do {
-					memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
-					ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-						obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
-					i += 16;
-					len -= 16;
-				} while (len > 0);
-			} else {
-				/* write to register */
-				u8 obuf[msg[0].len + 2];
-				obuf[0] = 0xaa;
-				obuf[1] = msg[0].len;
-				memcpy(obuf + 2, msg[0].buf, msg[0].len);
-				ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
-						obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-			}
-			break;
-		}
+	for (j = 0; j < num; j++) {
+		switch (msg[j].addr) {
 		case(DW2102_RC_QUERY): {
 			u8 ibuf[2];
 			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 					ibuf, 2, DW210X_READ_MSG);
-			memcpy(msg[0].buf, ibuf , 2);
+			memcpy(msg[j].buf, ibuf , 2);
 			break;
 		}
 		case(DW2102_VOLTAGE_CTRL): {
 			u8 obuf[2];
 			obuf[0] = 0x30;
-			obuf[1] = msg[0].buf[0];
+			obuf[1] = msg[j].buf[0];
 			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
 					obuf, 2, DW210X_WRITE_MSG);
 			break;
 		}
+		/*case 0x55: cx24116
+		case 0x6a: stv0903
+		case 0x68: ds3000, stv0903
+		case 0x60: ts2020, stv6110, stb6100 */
+		default: {
+			if (msg[j].flags == I2C_M_RD) {
+				/* read registers */
+				u8  ibuf[msg[j].len + 2];
+				ret = dw210x_op_rw(d->udev, 0xc3,
+						(msg[j].addr << 1) + 1, 0,
+						ibuf, msg[j].len + 2,
+						DW210X_READ_MSG);
+				memcpy(msg[j].buf, ibuf + 2, msg[j].len);
+			mdelay(10);
+			} else if (((msg[j].buf[0] == 0xb0) &&
+						(msg[j].addr == 0x68)) ||
+						((msg[j].buf[0] == 0xf7) &&
+						(msg[j].addr == 0x55))) {
+				/* write firmware */
+				u8 obuf[19];
+				obuf[0] = msg[j].addr << 1;
+				obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
+				obuf[2] = msg[j].buf[0];
+				len = msg[j].len - 1;
+				i = 1;
+				do {
+					memcpy(obuf + 3, msg[j].buf + i,
+							(len > 16 ? 16 : len));
+					ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+						obuf, (len > 16 ? 16 : len) + 3,
+						DW210X_WRITE_MSG);
+					i += 16;
+					len -= 16;
+				} while (len > 0);
+			} else {
+				/* write registers */
+				u8 obuf[msg[j].len + 2];
+				obuf[0] = msg[j].addr << 1;
+				obuf[1] = msg[j].len;
+				memcpy(obuf + 2, msg[j].buf, msg[j].len);
+				ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
+						obuf, msg[j].len + 2,
+						DW210X_WRITE_MSG);
+			}
+			break;
+		}
 		}
 
-		break;
 	}
 
 	mutex_unlock(&d->i2c_mutex);
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2
 	return num;
 }
 
-static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 								int num)
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	int ret = 0;
+	int len, i, j;
 
 	if (!d)
 		return -ENODEV;
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
 
-	switch (num) {
-	case 2: { /* read */
-		u8 ibuf[msg[1].len], obuf[3];
-		obuf[0] = msg[1].len;
-		obuf[1] = (msg[0].addr << 1);
-		obuf[2] = msg[0].buf[0];
-
-		ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
-					obuf, 3, DW210X_WRITE_MSG);
-		msleep(5);
-		ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
-					ibuf, msg[1].len, DW210X_READ_MSG);
-		memcpy(msg[1].buf, ibuf, msg[1].len);
-		break;
-	}
-	case 1:
-		switch (msg[0].addr) {
-		case 0x60:
-		case 0x0e: {
-			/* write to zl10313, zl10039 register, */
-			u8 obuf[msg[0].len + 2];
-			obuf[0] = msg[0].len + 1;
-			obuf[1] = (msg[0].addr << 1);
-			memcpy(obuf + 2, msg[0].buf, msg[0].len);
-			ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
-					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
-			break;
-		}
+	for (j = 0; j < num; j++) {
+		switch (msg[j].addr) {
 		case (DW2102_RC_QUERY): {
 			u8 ibuf[4];
 			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
 					ibuf, 4, DW210X_READ_MSG);
-			msg[0].buf[0] = ibuf[3];
+			memcpy(msg[j].buf, ibuf + 1, 2);
 			break;
 		}
 		case (DW2102_VOLTAGE_CTRL): {
 			u8 obuf[2];
-			obuf[0] = 0x03;
-			obuf[1] = msg[0].buf[0];
+			obuf[0] = 3;
+			obuf[1] = msg[j].buf[0];
 			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
 					obuf, 2, DW210X_WRITE_MSG);
 			break;
 		}
+		/*case 0x55: cx24116
+		case 0x6a: stv0903
+		case 0x68: ds3000, stv0903
+		case 0x60: ts2020, stv6110, stb6100
+		case 0xa0: eeprom */
+		default: {
+			if (msg[j].flags == I2C_M_RD) {
+				/* read registers */
+				u8 ibuf[msg[j].len];
+				ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+						ibuf, msg[j].len,
+						DW210X_READ_MSG);
+				memcpy(msg[j].buf, ibuf, msg[j].len);
+				break;
+			} else if ((msg[j].buf[0] == 0xb0) &&
+						(msg[j].addr == 0x68)) {
+				/* write firmware */
+				u8 obuf[19];
+				obuf[0] = (msg[j].len > 16 ?
+						18 : msg[j].len + 1);
+				obuf[1] = msg[j].addr << 1;
+				obuf[2] = msg[j].buf[0];
+				len = msg[j].len - 1;
+				i = 1;
+				do {
+					memcpy(obuf + 3, msg[j].buf + i,
+							(len > 16 ? 16 : len));
+					ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
+						obuf, (len > 16 ? 16 : len) + 3,
+						DW210X_WRITE_MSG);
+					i += 16;
+					len -= 16;
+				} while (len > 0);
+			} else {
+				/* write registers */
+				u8 obuf[msg[j].len + 2];
+				obuf[0] = msg[j].len + 1;
+				obuf[1] = (msg[j].addr << 1);
+				memcpy(obuf + 2, msg[j].buf, msg[j].len);
+				ret = dw210x_op_rw(d->udev,
+						(num > 1 ? 0x90 : 0x80), 0, 0,
+						obuf, msg[j].len + 2,
+						DW210X_WRITE_MSG);
+				break;
+			}
+			break;
+		}
 		}
 
-		break;
+		msleep(3);
 	}
 
 	mutex_unlock(&d->i2c_mutex);
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_a
 	.functionality = dw210x_i2c_func,
 };
 
-static struct i2c_algorithm s630_i2c_algo = {
-	.master_xfer = s630_i2c_transfer,
+static struct i2c_algorithm s6x0_i2c_algo = {
+	.master_xfer = s6x0_i2c_transfer,
 	.functionality = dw210x_i2c_func,
 };
 
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struc
 	return 0;
 };
 
-static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 {
 	int i, ret;
-	u8 buf[3], eeprom[256], eepromline[16];
+	u8 ibuf[] = { 0 }, obuf[] = { 0 };
+	u8 eeprom[256], eepromline[16];
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0xa0 >> 1,
+			.flags = 0,
+			.buf = obuf,
+			.len = 1,
+		}, {
+			.addr = 0xa0 >> 1,
+			.flags = I2C_M_RD,
+			.buf = ibuf,
+			.len = 1,
+		}
+	};
 
 	for (i = 0; i < 256; i++) {
-		buf[0] = 1;
-		buf[1] = 0xa0;
-		buf[2] = i;
-		ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
-					buf, 3, DW210X_WRITE_MSG);
-		ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
-					buf, 1, DW210X_READ_MSG);
-		if (ret < 0) {
+		obuf[0] = i;
+		ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
+		if (ret != 2) {
 			err("read eeprom failed.");
 			return -1;
 		} else {
-			eepromline[i % 16] = buf[0];
-			eeprom[i] = buf[0];
+			eepromline[i % 16] = ibuf[0];
+			eeprom[i] = ibuf[0];
 		}
 
 		if ((i % 16) == 15) {
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config
 	.demod_address = 0x0e,
 };
 
+static struct ds3000_config dw2104_ds3000_config = {
+	.demod_address = 0x68,
+};
+
+static struct stv0900_config dw2104a_stv0900_config = {
+	.demod_address = 0x6a,
+	.demod_mode = 0,
+	.xtal = 27000000,
+	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+	.diseqc_mode = 2,/* 2/3 PWM */
+	.tun1_maddress = 0,/* 0x60 */
+	.tun1_adc = 0,/* 2 Vpp */
+	.path1_mode = 3,
+};
+
+static struct stb6100_config dw2104a_stb6100_config = {
+	.tuner_address = 0x60,
+	.refclock = 27000000,
+};
+
+static struct stv0900_config dw2104_stv0900_config = {
+	.demod_address = 0x68,
+	.demod_mode = 0,
+	.xtal = 8000000,
+	.clkmode = 3,
+	.diseqc_mode = 2,
+	.tun1_maddress = 0,
+	.tun1_adc = 1,/* 1 Vpp */
+	.path1_mode = 3,
+};
+
+static struct stv6110_config dw2104_stv6110_config = {
+	.i2c_address = 0x60,
+	.mclk = 16000000,
+	.clk_div = 1,
+};
+
 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
 {
-	if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
-			&d->dev->i2c_adap)) != NULL) {
+	struct dvb_tuner_ops *tuner_ops = NULL;
+
+	if (demod_probe & 4) {
+		d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
+				&d->dev->i2c_adap, 0);
+		if (d->fe != NULL) {
+			if (dvb_attach(stb6100_attach, d->fe,
+					&dw2104a_stb6100_config,
+					&d->dev->i2c_adap)) {
+				tuner_ops = &d->fe->ops.tuner_ops;
+				tuner_ops->set_frequency = stb6100_set_freq;
+				tuner_ops->get_frequency = stb6100_get_freq;
+				tuner_ops->set_bandwidth = stb6100_set_bandw;
+				tuner_ops->get_bandwidth = stb6100_get_bandw;
+				d->fe->ops.set_voltage = dw210x_set_voltage;
+				info("Attached STV0900+STB6100!\n");
+				return 0;
+			}
+		}
+	}
+
+	if (demod_probe & 2) {
+		d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
+				&d->dev->i2c_adap, 0);
+		if (d->fe != NULL) {
+			if (dvb_attach(stv6110_attach, d->fe,
+					&dw2104_stv6110_config,
+					&d->dev->i2c_adap)) {
+				d->fe->ops.set_voltage = dw210x_set_voltage;
+				info("Attached STV0900+STV6110A!\n");
+				return 0;
+			}
+		}
+	}
+
+	if (demod_probe & 1) {
+		d->fe = dvb_attach(cx24116_attach, &dw2104_config,
+				&d->dev->i2c_adap);
+		if (d->fe != NULL) {
+			d->fe->ops.set_voltage = dw210x_set_voltage;
+			info("Attached cx24116!\n");
+			return 0;
+		}
+	}
+
+	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+			&d->dev->i2c_adap);
+	if (d->fe != NULL) {
 		d->fe->ops.set_voltage = dw210x_set_voltage;
-		info("Attached cx24116!\n");
+		info("Attached DS3000!\n");
 		return 0;
 	}
+
 	return -EIO;
 }
 
 static struct dvb_usb_device_properties dw2102_properties;
 static struct dvb_usb_device_properties dw2104_properties;
+static struct dvb_usb_device_properties s6x0_properties;
 
 static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
 {
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct
 			return 0;
 		}
 	}
+
 	if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
-		/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
 		d->fe = dvb_attach(stv0288_attach, &earda_config,
 					&d->dev->i2c_adap);
 		if (d->fe != NULL) {
-			d->fe->ops.set_voltage = dw210x_set_voltage;
-			info("Attached stv0288!\n");
-			return 0;
+			if (dvb_attach(stb6000_attach, d->fe, 0x61,
+					&d->dev->i2c_adap)) {
+				d->fe->ops.set_voltage = dw210x_set_voltage;
+				info("Attached stv0288!\n");
+				return 0;
+			}
 		}
 	}
 
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct
 	return -EIO;
 }
 
-static int s630_frontend_attach(struct dvb_usb_adapter *d)
+static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
 {
 	d->fe = dvb_attach(mt312_attach, &zl313_config,
-				&d->dev->i2c_adap);
+			&d->dev->i2c_adap);
+	if (d->fe != NULL) {
+		if (dvb_attach(zl10039_attach, d->fe, 0x60,
+				&d->dev->i2c_adap)) {
+			d->fe->ops.set_voltage = dw210x_set_voltage;
+			info("Attached zl100313+zl10039!\n");
+			return 0;
+		}
+	}
+
+	d->fe = dvb_attach(stv0288_attach, &earda_config,
+			&d->dev->i2c_adap);
+	if (d->fe != NULL) {
+		if (dvb_attach(stb6000_attach, d->fe, 0x61,
+				&d->dev->i2c_adap)) {
+			d->fe->ops.set_voltage = dw210x_set_voltage;
+			info("Attached stv0288+stb6000!\n");
+			return 0;
+		}
+	}
+
+	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
+			&d->dev->i2c_adap);
 	if (d->fe != NULL) {
 		d->fe->ops.set_voltage = dw210x_set_voltage;
-		info("Attached zl10313!\n");
+		info("Attached ds3000+ds2020!\n");
 		return 0;
 	}
+
 	return -EIO;
 }
 
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dv
 	return 0;
 }
 
-static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
-{
-	dvb_attach(stb6000_attach, adap->fe, 0x61,
-		&adap->dev->i2c_adap);
-
-	return 0;
-}
-
 static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dv
 	return 0;
 }
 
-static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
-{
-	dvb_attach(zl10039_attach, adap->fe, 0x60,
-		&adap->dev->i2c_adap);
-
-	return 0;
-}
-
 static struct dvb_usb_rc_key dw210x_rc_keys[] = {
 	{ 0xf80a, KEY_Q },		/*power*/
 	{ 0xf80c, KEY_M },		/*mute*/
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table
 	{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
 	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
 	{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
+	{USB_DEVICE(0x3011, USB_PID_PROF_1100)},
+	{USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
 	{ }
 };
 
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct u
 	u8 reset;
 	u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
 	const struct firmware *fw;
-	const char *filename = "/*(DEBLOBBED)*/";
+	const char *fw_2101 = "/*(DEBLOBBED)*/";
 
 	switch (dev->descriptor.idProduct) {
 	case 0x2101:
-		ret = reject_firmware(&fw, filename, &dev->dev);
+		ret = reject_firmware(&fw, fw_2101, &dev->dev);
 		if (ret != 0) {
-			err("did not find the firmware file. (%s) "
-			"Please see linux/Documentation/dvb/ for more details "
-			"on firmware-problems.", filename);
+			err(err_str, fw_2101);
 			return ret;
 		}
 		break;
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct u
 		}
 		/* init registers */
 		switch (dev->descriptor.idProduct) {
+		case USB_PID_PROF_1100:
+			s6x0_properties.rc_key_map = tbs_rc_keys;
+			s6x0_properties.rc_key_map_size =
+					ARRAY_SIZE(tbs_rc_keys);
+			break;
 		case USB_PID_TEVII_S650:
 			dw2104_properties.rc_key_map = tevii_rc_keys;
 			dw2104_properties.rc_key_map_size =
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct u
 						DW210X_READ_MSG);
 				if (reset16[2] == 0x11) {
 					dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
-					dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
 					break;
 				}
 			}
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties
 	}
 };
 
-static struct dvb_usb_device_properties s630_properties = {
+static struct dvb_usb_device_properties s6x0_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 	.usb_ctrl = DEVICE_SPECIFIC,
 	.firmware = "/*(DEBLOBBED)*/",
 	.no_reconnect = 1,
 
-	.i2c_algo = &s630_i2c_algo,
+	.i2c_algo = &s6x0_i2c_algo,
 	.rc_key_map = tevii_rc_keys,
 	.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
 	.rc_interval = 150,
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties
 	.generic_bulk_ctrl_endpoint = 0x81,
 	.num_adapters = 1,
 	.download_firmware = dw2102_load_firmware,
-	.read_mac_address = s630_read_mac_address,
+	.read_mac_address = s6x0_read_mac_address,
 	.adapter = {
 		{
-			.frontend_attach = s630_frontend_attach,
+			.frontend_attach = s6x0_frontend_attach,
 			.streaming_ctrl = NULL,
-			.tuner_attach = s630_zl10039_tuner_attach,
+			.tuner_attach = NULL,
 			.stream = {
 				.type = USB_BULK,
 				.count = 8,
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties
 			},
 		}
 	},
-	.num_device_descs = 1,
+	.num_device_descs = 3,
 	.devices = {
 		{"TeVii S630 USB",
 			{&dw2102_table[6], NULL},
 			{NULL},
 		},
+		{"Prof 1100 USB ",
+			{&dw2102_table[7], NULL},
+			{NULL},
+		},
+		{"TeVii S660 USB",
+			{&dw2102_table[8], NULL},
+			{NULL},
+		},
 	}
 };
 
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_inter
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &dw3101_properties,
 			THIS_MODULE, NULL, adapter_nr) ||
-	    0 == dvb_usb_device_init(intf, &s630_properties,
-			THIS_MODULE, NULL, adapter_nr)) {
+	    0 == dvb_usb_device_init(intf, &s6x0_properties,
+			THIS_MODULE, NULL, adapter_nr))
 		return 0;
-	}
+
 	return -ENODEV;
 }
 
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit);
 MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
 MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
 				" DVB-C 3101 USB2.0,"
-				" TeVii S600, S630, S650 USB2.0 devices");
+				" TeVii S600, S630, S650, S660 USB2.0,"
+				" Prof 1100 USB2.0 devices");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/ec168.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/ec168.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/ec168.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/ec168.c	2013-05-03 12:04:20.000000000 -0400
@@ -0,0 +1,440 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 "ec168.h"
+#include "ec100.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ec168_debug;
+module_param_named(debug, dvb_usb_ec168_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct ec100_config ec168_ec100_config;
+
+static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
+{
+	int ret;
+	unsigned int pipe;
+	u8 request, requesttype;
+	u8 buf[req->size];
+
+	switch (req->cmd) {
+	case DOWNLOAD_FIRMWARE:
+	case GPIO:
+	case WRITE_I2C:
+	case STREAMING_CTRL:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = req->cmd;
+		break;
+	case READ_I2C:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = req->cmd;
+		break;
+	case GET_CONFIG:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = CONFIG;
+		break;
+	case SET_CONFIG:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = CONFIG;
+		break;
+	case WRITE_DEMOD:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		request = DEMOD_RW;
+		break;
+	case READ_DEMOD:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		request = DEMOD_RW;
+		break;
+	default:
+		err("unknown command:%02x", req->cmd);
+		ret = -EPERM;
+		goto error;
+	}
+
+	if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+		/* write */
+		memcpy(buf, req->data, req->size);
+		pipe = usb_sndctrlpipe(udev, 0);
+	} else {
+		/* read */
+		pipe = usb_rcvctrlpipe(udev, 0);
+	}
+
+	msleep(1); /* avoid I2C errors */
+
+	ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
+		req->index, buf, sizeof(buf), EC168_USB_TIMEOUT);
+
+	ec168_debug_dump(request, requesttype, req->value, req->index, buf,
+		req->size, deb_xfer);
+
+	if (ret < 0)
+		goto error;
+	else
+		ret = 0;
+
+	/* read request, copy returned data to return buf */
+	if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+		memcpy(req->data, buf, req->size);
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
+{
+	return ec168_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+	int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct ec168_req req;
+	int i = 0;
+	int ret;
+
+	if (num > 2)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	while (i < num) {
+		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				req.cmd = READ_DEMOD;
+				req.value = 0;
+				req.index = 0xff00 + msg[i].buf[0]; /* reg */
+				req.size = msg[i+1].len; /* bytes to read */
+				req.data = &msg[i+1].buf[0];
+				ret = ec168_ctrl_msg(d, &req);
+				i += 2;
+			} else {
+				err("I2C read not implemented");
+				ret = -ENOSYS;
+				i += 2;
+			}
+		} else {
+			if (msg[i].addr == ec168_ec100_config.demod_address) {
+				req.cmd = WRITE_DEMOD;
+				req.value = msg[i].buf[1]; /* val */
+				req.index = 0xff00 + msg[i].buf[0]; /* reg */
+				req.size = 0;
+				req.data = NULL;
+				ret = ec168_ctrl_msg(d, &req);
+				i += 1;
+			} else {
+				req.cmd = WRITE_I2C;
+				req.value = msg[i].buf[0]; /* val */
+				req.index = 0x0100 + msg[i].addr; /* I2C addr */
+				req.size = msg[i].len-1;
+				req.data = &msg[i].buf[1];
+				ret = ec168_ctrl_msg(d, &req);
+				i += 1;
+			}
+		}
+		if (ret)
+			goto error;
+
+	}
+	ret = i;
+
+error:
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+
+static u32 ec168_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ec168_i2c_algo = {
+	.master_xfer   = ec168_i2c_xfer,
+	.functionality = ec168_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct ec100_config ec168_ec100_config = {
+	.demod_address = 0xff, /* not real address, demod is integrated */
+};
+
+static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("%s:\n", __func__);
+	adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config,
+		&adap->dev->i2c_adap);
+	if (adap->fe == NULL)
+		return -ENODEV;
+
+	return 0;
+}
+
+static struct mxl5005s_config ec168_mxl5003s_config = {
+	.i2c_address     = 0xc6,
+	.if_freq         = IF_FREQ_4570000HZ,
+	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+	.agc_mode        = MXL_SINGLE_AGC,
+	.tracking_filter = MXL_TF_OFF,
+	.rssi_enable     = MXL_RSSI_ENABLE,
+	.cap_select      = MXL_CAP_SEL_ENABLE,
+	.div_out         = MXL_DIV_OUT_4,
+	.clock_out       = MXL_CLOCK_OUT_DISABLE,
+	.output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+	.top		 = MXL5005S_TOP_25P2,
+	.mod_mode        = MXL_DIGITAL_MODE,
+	.if_mode         = MXL_ZERO_IF,
+	.AgcMasterByte   = 0x00,
+};
+
+static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("%s:\n", __func__);
+	return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+		&ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
+}
+
+static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
+	deb_info("%s: onoff:%d\n", __func__, onoff);
+	if (onoff)
+		req.index = 0x0102;
+	return ec168_ctrl_msg(adap->dev, &req);
+}
+
+static int ec168_download_firmware(struct usb_device *udev,
+	const struct firmware *fw)
+{
+	int i, len, packets, remainder, ret;
+	u16 addr = 0x0000; /* firmware start address */
+	struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
+	deb_info("%s:\n", __func__);
+
+	#define FW_PACKET_MAX_DATA  2048
+	packets = fw->size / FW_PACKET_MAX_DATA;
+	remainder = fw->size % FW_PACKET_MAX_DATA;
+	len = FW_PACKET_MAX_DATA;
+	for (i = 0; i <= packets; i++) {
+		if (i == packets)  /* set size of the last packet */
+			len = remainder;
+
+		req.size = len;
+		req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
+		req.index = addr;
+		addr += FW_PACKET_MAX_DATA;
+
+		ret = ec168_rw_udev(udev, &req);
+		if (ret) {
+			err("firmware download failed:%d packet:%d", ret, i);
+			goto error;
+		}
+	}
+	req.size = 0;
+
+	/* set "warm"? */
+	req.cmd = SET_CONFIG;
+	req.value = 0;
+	req.index = 0x0001;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	/* really needed - no idea what does */
+	req.cmd = GPIO;
+	req.value = 0;
+	req.index = 0x0206;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	/* activate tuner I2C? */
+	req.cmd = WRITE_I2C;
+	req.value = 0;
+	req.index = 0x00c6;
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec168_identify_state(struct usb_device *udev,
+	struct dvb_usb_device_properties *props,
+	struct dvb_usb_device_description **desc, int *cold)
+{
+	int ret;
+	u8 reply;
+	struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
+	deb_info("%s:\n", __func__);
+
+	ret = ec168_rw_udev(udev, &req);
+	if (ret)
+		goto error;
+
+	deb_info("%s: reply:%02x\n", __func__, reply);
+
+	if (reply == 0x01)
+		*cold = 0;
+	else
+		*cold = 1;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ec168_properties;
+
+static int ec168_probe(struct usb_interface *intf,
+	const struct usb_device_id *id)
+{
+	int ret;
+	deb_info("%s: interface:%d\n", __func__,
+		intf->cur_altsetting->desc.bInterfaceNumber);
+
+	ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL,
+		adapter_nr);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+#define E3C_EC168_1689                          0
+#define E3C_EC168_FFFA                          1
+#define E3C_EC168_FFFB                          2
+#define E3C_EC168_1001                          3
+#define E3C_EC168_1002                          4
+
+static struct usb_device_id ec168_id[] = {
+	[E3C_EC168_1689] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)},
+	[E3C_EC168_FFFA] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)},
+	[E3C_EC168_FFFB] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)},
+	[E3C_EC168_1001] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)},
+	[E3C_EC168_1002] =
+		{USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)},
+	{} /* terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, ec168_id);
+
+static struct dvb_usb_device_properties ec168_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.download_firmware = ec168_download_firmware,
+	.firmware = "/*(DEBLOBBED)*/",
+	.no_reconnect = 1,
+
+	.size_of_priv = 0,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = ec168_streaming_ctrl,
+			.frontend_attach  = ec168_ec100_frontend_attach,
+			.tuner_attach     = ec168_mxl5003s_tuner_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 6,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = (32*512),
+					}
+				}
+			},
+		}
+	},
+
+	.identify_state = ec168_identify_state,
+
+	.i2c_algo = &ec168_i2c_algo,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			.name = "E3C EC168 DVB-T USB2.0 reference design",
+			.cold_ids = {
+				&ec168_id[E3C_EC168_1689],
+				&ec168_id[E3C_EC168_FFFA],
+				&ec168_id[E3C_EC168_FFFB],
+				&ec168_id[E3C_EC168_1001],
+				&ec168_id[E3C_EC168_1002],
+				NULL},
+			.warm_ids = {NULL},
+		},
+	}
+};
+
+static struct usb_driver ec168_driver = {
+	.name       = "dvb_usb_ec168",
+	.probe      = ec168_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table   = ec168_id,
+};
+
+/* module stuff */
+static int __init ec168_module_init(void)
+{
+	int ret;
+	deb_info("%s:\n", __func__);
+	ret = usb_register(&ec168_driver);
+	if (ret)
+		err("module init failed:%d", ret);
+
+	return ret;
+}
+
+static void __exit ec168_module_exit(void)
+{
+	deb_info("%s:\n", __func__);
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&ec168_driver);
+}
+
+module_init(ec168_module_init);
+module_exit(ec168_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/ec168.h linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/ec168.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/ec168.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/ec168.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,73 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 EC168_H
+#define EC168_H
+
+#define DVB_USB_LOG_PREFIX "ec168"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args)
+#define deb_rc(args...)   dprintk(dvb_usb_ec168_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args)
+#define deb_reg(args...)  dprintk(dvb_usb_ec168_debug, 0x08, args)
+#define deb_i2c(args...)  dprintk(dvb_usb_ec168_debug, 0x10, args)
+#define deb_fw(args...)   dprintk(dvb_usb_ec168_debug, 0x20, args)
+
+#define ec168_debug_dump(r, t, v, i, b, l, func) { \
+	int loop_; \
+	func("%02x %02x %02x %02x %02x %02x %02x %02x", \
+		t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
+	if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+		func(" >>> "); \
+	else \
+		func(" <<< "); \
+	for (loop_ = 0; loop_ < l; loop_++) \
+		func("%02x ", b[loop_]); \
+	func("\n");\
+}
+
+#define EC168_USB_TIMEOUT 1000
+
+struct ec168_req {
+	u8  cmd;       /* [1] */
+	u16 value;     /* [2|3] */
+	u16 index;     /* [4|5] */
+	u16 size;      /* [6|7] */
+	u8  *data;
+};
+
+enum ec168_cmd {
+	DOWNLOAD_FIRMWARE    = 0x00,
+	CONFIG               = 0x01,
+	DEMOD_RW             = 0x03,
+	GPIO                 = 0x04,
+	STREAMING_CTRL       = 0x10,
+	READ_I2C             = 0x20,
+	WRITE_I2C            = 0x21,
+	HID_DOWNLOAD         = 0x30,
+	GET_CONFIG,
+	SET_CONFIG,
+	READ_DEMOD,
+	WRITE_DEMOD,
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/friio-fe.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struc
 	deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
 	       state->frontend.ops.info.frequency_stepsize);
 	/* freq -> oscilator frequency conversion. */
-	/* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
-	/* add 400[1/7 MHZ] = 57.142857MHz.   57MHz for the IF,  */
-	/*                                   1/7MHz for center freq shift */
+	/* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
 	f = freq / state->frontend.ops.info.frequency_stepsize;
-	f += 400;
+	/* add 399[1/7 MHZ] = 57MHz for the IF  */
+	f += 399;
+	/* add center frequency shift if necessary */
+	if (f % 7 == 0)
+		f++;
 	pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
 	pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
 	pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
@@ -232,12 +234,6 @@ static int jdvbt90502_read_status(struct
 	return 0;
 }
 
-static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-	*ber = 0;
-	return 0;
-}
-
 static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
 					   u16 *strength)
 {
@@ -264,26 +260,26 @@ static int jdvbt90502_read_signal_streng
 	return 0;
 }
 
-static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-	*snr = 0x0101;
-	return 0;
-}
-
-static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-	*ucblocks = 0;
-	return 0;
-}
 
-static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe,
-					struct dvb_frontend_tune_settings *fs)
+/* filter out un-supported properties to notify users */
+static int jdvbt90502_set_property(struct dvb_frontend *fe,
+				   struct dtv_property *tvp)
 {
-	fs->min_delay_ms = 500;
-	fs->step_size = 0;
-	fs->max_drift = 0;
+	int r = 0;
 
-	return 0;
+	switch (tvp->cmd) {
+	case DTV_DELIVERY_SYSTEM:
+		if (tvp->u.data != SYS_ISDBT)
+			r = -EINVAL;
+		break;
+	case DTV_CLEAR:
+	case DTV_TUNE:
+	case DTV_FREQUENCY:
+		break;
+	default:
+		r = -EINVAL;
+	}
+	return r;
 }
 
 static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
@@ -314,6 +310,9 @@ static int jdvbt90502_set_frontend(struc
 
 	deb_fe("%s: Freq:%d\n", __func__, p->frequency);
 
+	/* for recovery from DTV_CLEAN */
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
 	ret = jdvbt90502_pll_set_freq(state, p->frequency);
 	if (ret) {
 		deb_fe("%s:ret == %d\n", __func__, ret);
@@ -323,12 +322,6 @@ static int jdvbt90502_set_frontend(struc
 	return 0;
 }
 
-static int jdvbt90502_sleep(struct dvb_frontend *fe)
-{
-	deb_fe("%s called.\n", __func__);
-	return 0;
-}
-
 
 /**
  * (reg, val) commad list to initialize this module.
@@ -394,6 +387,7 @@ static int jdvbt90502_init(struct dvb_fr
 		if (ret != 1)
 			goto error;
 	}
+	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
 	msleep(100);
 
 	return 0;
@@ -468,16 +462,13 @@ static struct dvb_frontend_ops jdvbt9050
 	.release = jdvbt90502_release,
 
 	.init = jdvbt90502_init,
-	.sleep = jdvbt90502_sleep,
 	.write = _jdvbt90502_write,
 
+	.set_property = jdvbt90502_set_property,
+
 	.set_frontend = jdvbt90502_set_frontend,
 	.get_frontend = jdvbt90502_get_frontend,
-	.get_tune_settings = jdvbt90502_get_tune_settings,
 
 	.read_status = jdvbt90502_read_status,
-	.read_ber = jdvbt90502_read_ber,
 	.read_signal_strength = jdvbt90502_read_signal_strength,
-	.read_snr = jdvbt90502_read_snr,
-	.read_ucblocks = jdvbt90502_read_ucblocks,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/gp8psk-fe.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/gp8psk-fe.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/gp8psk-fe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/gp8psk-fe.c	2010-02-24 13:52:17.000000000 -0500
@@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct
 
 	switch (c->delivery_system) {
 	case SYS_DVBS:
-		/* Only QPSK is supported for DVB-S */
-		if (c->modulation != QPSK) {
+		/* Allow QPSK and 8PSK (even for DVB-S) */
+		if (c->modulation != QPSK && c->modulation != PSK_8) {
 			deb_fe("%s: unsupported modulation selected (%d)\n",
 				__func__, c->modulation);
 			return -EOPNOTSUPP;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/Kconfig linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -112,11 +112,13 @@ config DVB_USB_CXUSB
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
-	select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE
 	select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+	select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
+	select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Conexant USB2.0 hybrid reference design.
 	  Currently, only DVB and ATSC modes are supported, analog mode
@@ -265,9 +267,13 @@ config DVB_USB_DW2102
 	select DVB_TDA10021 if !DVB_FE_CUSTOMISE
 	select DVB_MT312 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10039 if !DVB_FE_CUSTOMISE
+	select DVB_DS3000 if !DVB_FE_CUSTOMISE
+	select DVB_STB6100 if !DVB_FE_CUSTOMISE
+	select DVB_STV6110 if !DVB_FE_CUSTOMISE
+	select DVB_STV0900 if !DVB_FE_CUSTOMISE
 	help
-	  Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
-	  and the TeVii S650, S630.
+	  Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
+	  receivers.
 
 config DVB_USB_CINERGY_T2
 	tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
@@ -322,3 +328,11 @@ config DVB_USB_FRIIO
 	depends on DVB_USB
 	help
 	  Say Y here to support the Japanese DTV receiver Friio.
+
+config DVB_USB_EC168
+	tristate "E3C EC168 DVB-T USB2.0 support"
+	depends on DVB_USB && EXPERIMENTAL
+	select DVB_EC100
+	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	help
+	  Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/Makefile linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -82,6 +82,9 @@ obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-
 dvb-usb-friio-objs = friio.o friio-fe.o
 obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
 
+dvb-usb-ec168-objs = ec168.o
+obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/usb-urb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/usb-urb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/dvb-usb/usb-urb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/dvb-usb/usb-urb.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@ static void usb_urb_complete(struct urb
 				stream->complete(stream, b, urb->actual_length);
 			break;
 		default:
-			err("unkown endpoint type in completition handler.");
+			err("unknown endpoint type in completition handler.");
 			return;
 	}
 	usb_submit_urb(urb,GFP_ATOMIC);
@@ -228,7 +228,7 @@ int usb_urb_init(struct usb_data_stream
 		case USB_ISOC:
 			return usb_isoc_urb_init(stream);
 		default:
-			err("unkown URB-type for data transfer.");
+			err("unknown URB-type for data transfer.");
 			return -EINVAL;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-1394.c linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-1394.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-1394.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-1394.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * FireDTV driver (formerly known as FireSAT)
+ * FireDTV driver -- ieee1394 I/O backend
  *
  * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
  * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
@@ -26,13 +26,16 @@
 #include <iso.h>
 #include <nodemgr.h>
 
+#include <dvb_demux.h>
+
 #include "firedtv.h"
 
 static LIST_HEAD(node_list);
 static DEFINE_SPINLOCK(node_list_lock);
 
-#define FIREWIRE_HEADER_SIZE	4
-#define CIP_HEADER_SIZE		8
+#define CIP_HEADER_SIZE			8
+#define MPEG2_TS_HEADER_SIZE		4
+#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)
 
 static void rawiso_activity_cb(struct hpsb_iso *iso)
 {
@@ -62,20 +65,20 @@ static void rawiso_activity_cb(struct hp
 		buf = dma_region_i(&iso->data_buf, unsigned char,
 			iso->infos[packet].offset + CIP_HEADER_SIZE);
 		count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
-			(188 + FIREWIRE_HEADER_SIZE);
+			MPEG2_TS_SOURCE_PACKET_SIZE;
 
 		/* ignore empty packet */
 		if (iso->infos[packet].len <= CIP_HEADER_SIZE)
 			continue;
 
 		while (count--) {
-			if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
+			if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
 				dvb_dmx_swfilter_packets(&fdtv->demux,
-						&buf[FIREWIRE_HEADER_SIZE], 1);
+						&buf[MPEG2_TS_HEADER_SIZE], 1);
 			else
 				dev_err(fdtv->device,
 					"skipping invalid packet\n");
-			buf += 188 + FIREWIRE_HEADER_SIZE;
+			buf += MPEG2_TS_SOURCE_PACKET_SIZE;
 		}
 	}
 out:
@@ -87,15 +90,20 @@ static inline struct node_entry *node_of
 	return container_of(fdtv->device, struct unit_directory, device)->ne;
 }
 
-static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
+static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
 {
-	return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
-			      (__force quadlet_t)arg);
+	int ret;
+
+	ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
+		(__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
+	data[0] = data[1];
+
+	return ret;
 }
 
-static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+static int node_read(struct firedtv *fdtv, u64 addr, void *data)
 {
-	return hpsb_node_read(node_of(fdtv), addr, data, len);
+	return hpsb_node_read(node_of(fdtv), addr, data, 4);
 }
 
 static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
@@ -212,6 +220,7 @@ static int node_probe(struct device *dev
 		goto fail;
 
 	avc_register_remote_control(fdtv);
+
 	return 0;
 fail:
 	spin_lock_irq(&node_list_lock);
@@ -220,6 +229,7 @@ fail:
 	fdtv_unregister_rc(fdtv);
 fail_free:
 	kfree(fdtv);
+
 	return err;
 }
 
@@ -233,10 +243,9 @@ static int node_remove(struct device *de
 	list_del(&fdtv->list);
 	spin_unlock_irq(&node_list_lock);
 
-	cancel_work_sync(&fdtv->remote_ctrl_work);
 	fdtv_unregister_rc(fdtv);
-
 	kfree(fdtv);
+
 	return 0;
 }
 
@@ -252,6 +261,7 @@ static int node_update(struct unit_direc
 
 static struct hpsb_protocol_driver fdtv_driver = {
 	.name		= "firedtv",
+	.id_table	= fdtv_id_table,
 	.update		= node_update,
 	.driver         = {
 		.probe  = node_probe,
@@ -264,12 +274,11 @@ static struct hpsb_highlevel fdtv_highle
 	.fcp_request	= fcp_request,
 };
 
-int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
+int __init fdtv_1394_init(void)
 {
 	int ret;
 
 	hpsb_register_highlevel(&fdtv_highlevel);
-	fdtv_driver.id_table = id_table;
 	ret = hpsb_register_protocol(&fdtv_driver);
 	if (ret) {
 		printk(KERN_ERR "firedtv: failed to register protocol\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-avc.c linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-avc.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2010-02-24 13:52:17.000000000 -0500
@@ -1236,14 +1236,14 @@ int avc_ca_get_mmi(struct firedtv *fdtv,
 
 #define CMP_OUTPUT_PLUG_CONTROL_REG_0	0xfffff0000904ULL
 
-static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
+static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
 {
 	int ret;
 
 	if (mutex_lock_interruptible(&fdtv->avc_mutex))
 		return -EINTR;
 
-	ret = fdtv->backend->read(fdtv, addr, buf, len);
+	ret = fdtv->backend->read(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: read I/O error\n");
 
@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv
 	return ret;
 }
 
-static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
+static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
 {
 	int ret;
 
 	if (mutex_lock_interruptible(&fdtv->avc_mutex))
 		return -EINTR;
 
-	ret = fdtv->backend->lock(fdtv, addr, data, arg);
+	ret = fdtv->backend->lock(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: lock I/O error\n");
 
@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr
 
 int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
 {
-	__be32 old_opcr, opcr;
+	__be32 old_opcr, opcr[2];
 	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
 	int attempts = 0;
 	int ret;
 
-	ret = cmp_read(fdtv, &opcr, opcr_address, 4);
+	ret = cmp_read(fdtv, opcr_address, opcr);
 	if (ret < 0)
 		return ret;
 
 repeat:
-	if (!get_opcr_online(opcr)) {
+	if (!get_opcr_online(*opcr)) {
 		dev_err(fdtv->device, "CMP: output offline\n");
 		return -EBUSY;
 	}
 
-	old_opcr = opcr;
+	old_opcr = *opcr;
 
-	if (get_opcr_p2p_connections(opcr)) {
-		if (get_opcr_channel(opcr) != channel) {
+	if (get_opcr_p2p_connections(*opcr)) {
+		if (get_opcr_channel(*opcr) != channel) {
 			dev_err(fdtv->device, "CMP: cannot change channel\n");
 			return -EBUSY;
 		}
@@ -1314,11 +1314,11 @@ repeat:
 
 		/* We don't allocate isochronous resources. */
 	} else {
-		set_opcr_channel(&opcr, channel);
-		set_opcr_data_rate(&opcr, 2); /* S400 */
+		set_opcr_channel(opcr, channel);
+		set_opcr_data_rate(opcr, 2); /* S400 */
 
 		/* FIXME: this is for the worst case - optimize */
-		set_opcr_overhead_id(&opcr, 0);
+		set_opcr_overhead_id(opcr, 0);
 
 		/*
 		 * FIXME: allocate isochronous channel and bandwidth at IRM
@@ -1326,13 +1326,16 @@ repeat:
 		 */
 	}
 
-	set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
+	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
 
-	ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
+	opcr[1] = *opcr;
+	opcr[0] = old_opcr;
+
+	ret = cmp_lock(fdtv, opcr_address, opcr);
 	if (ret < 0)
 		return ret;
 
-	if (old_opcr != opcr) {
+	if (old_opcr != *opcr) {
 		/*
 		 * FIXME: if old_opcr.P2P_Connections > 0,
 		 * deallocate isochronous channel and bandwidth at IRM
@@ -1350,27 +1353,30 @@ repeat:
 
 void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
 {
-	__be32 old_opcr, opcr;
+	__be32 old_opcr, opcr[2];
 	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
 	int attempts = 0;
 
-	if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
+	if (cmp_read(fdtv, opcr_address, opcr) < 0)
 		return;
 
 repeat:
-	if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
-	    get_opcr_channel(opcr) != channel) {
+	if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
+	    get_opcr_channel(*opcr) != channel) {
 		dev_err(fdtv->device, "CMP: no connection to break\n");
 		return;
 	}
 
-	old_opcr = opcr;
-	set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
+	old_opcr = *opcr;
+	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
 
-	if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
+	opcr[1] = *opcr;
+	opcr[0] = old_opcr;
+
+	if (cmp_lock(fdtv, opcr_address, opcr) < 0)
 		return;
 
-	if (old_opcr != opcr) {
+	if (old_opcr != *opcr) {
 		/*
 		 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
 		 * owner, deallocate isochronous channel and bandwidth at IRM
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -297,7 +297,7 @@ struct firedtv *fdtv_alloc(struct device
 #define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d
 #define AVC_SW_VERSION_ENTRY	0x010001
 
-static struct ieee1394_device_id fdtv_id_table[] = {
+const struct ieee1394_device_id fdtv_id_table[] = {
 	{
 		/* FloppyDTV S/CI and FloppyDTV S2 */
 		.match_flags	= MATCH_FLAGS,
@@ -346,12 +346,23 @@ MODULE_DEVICE_TABLE(ieee1394, fdtv_id_ta
 
 static int __init fdtv_init(void)
 {
-	return fdtv_1394_init(fdtv_id_table);
+	int ret;
+
+	ret = fdtv_fw_init();
+	if (ret < 0)
+		return ret;
+
+	ret = fdtv_1394_init();
+	if (ret < 0)
+		fdtv_fw_exit();
+
+	return ret;
 }
 
 static void __exit fdtv_exit(void)
 {
 	fdtv_1394_exit();
+	fdtv_fw_exit();
 }
 
 module_init(fdtv_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-fw.c linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-fw.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-fw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-fw.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,368 @@
+/*
+ * FireDTV driver -- firewire I/O backend
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/firewire.h>
+#include <linux/firewire-constants.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/page.h>
+
+#include <dvb_demux.h>
+
+#include "firedtv.h"
+
+static LIST_HEAD(node_list);
+static DEFINE_SPINLOCK(node_list_lock);
+
+static inline struct fw_device *device_of(struct firedtv *fdtv)
+{
+	return fw_device(fdtv->device->parent);
+}
+
+static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
+		    int tcode)
+{
+	struct fw_device *device = device_of(fdtv);
+	int rcode, generation = device->generation;
+
+	smp_rmb(); /* node_id vs. generation */
+
+	rcode = fw_run_transaction(device->card, tcode, device->node_id,
+			generation, device->max_speed, addr, data, len);
+
+	return rcode != RCODE_COMPLETE ? -EIO : 0;
+}
+
+static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
+{
+	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
+}
+
+static int node_read(struct firedtv *fdtv, u64 addr, void *data)
+{
+	return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
+}
+
+static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+	return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
+}
+
+#define ISO_HEADER_SIZE			4
+#define CIP_HEADER_SIZE			8
+#define MPEG2_TS_HEADER_SIZE		4
+#define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188)
+
+#define MAX_PACKET_SIZE		1024  /* 776, rounded up to 2^n */
+#define PACKETS_PER_PAGE	(PAGE_SIZE / MAX_PACKET_SIZE)
+#define N_PACKETS		64    /* buffer size */
+#define N_PAGES			DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
+#define IRQ_INTERVAL		16
+
+struct firedtv_receive_context {
+	struct fw_iso_context *context;
+	struct fw_iso_buffer buffer;
+	int interrupt_packet;
+	int current_packet;
+	char *pages[N_PAGES];
+};
+
+static int queue_iso(struct firedtv_receive_context *ctx, int index)
+{
+	struct fw_iso_packet p;
+
+	p.payload_length = MAX_PACKET_SIZE;
+	p.interrupt = !(++ctx->interrupt_packet & (IRQ_INTERVAL - 1));
+	p.skip = 0;
+	p.header_length = ISO_HEADER_SIZE;
+
+	return fw_iso_context_queue(ctx->context, &p, &ctx->buffer,
+				    index * MAX_PACKET_SIZE);
+}
+
+static void handle_iso(struct fw_iso_context *context, u32 cycle,
+		       size_t header_length, void *header, void *data)
+{
+	struct firedtv *fdtv = data;
+	struct firedtv_receive_context *ctx = fdtv->backend_data;
+	__be32 *h, *h_end;
+	int length, err, i = ctx->current_packet;
+	char *p, *p_end;
+
+	for (h = header, h_end = h + header_length / 4; h < h_end; h++) {
+		length = be32_to_cpup(h) >> 16;
+		if (unlikely(length > MAX_PACKET_SIZE)) {
+			dev_err(fdtv->device, "length = %d\n", length);
+			length = MAX_PACKET_SIZE;
+		}
+
+		p = ctx->pages[i / PACKETS_PER_PAGE]
+				+ (i % PACKETS_PER_PAGE) * MAX_PACKET_SIZE;
+		p_end = p + length;
+
+		for (p += CIP_HEADER_SIZE + MPEG2_TS_HEADER_SIZE; p < p_end;
+		     p += MPEG2_TS_SOURCE_PACKET_SIZE)
+			dvb_dmx_swfilter_packets(&fdtv->demux, p, 1);
+
+		err = queue_iso(ctx, i);
+		if (unlikely(err))
+			dev_err(fdtv->device, "requeue failed\n");
+
+		i = (i + 1) & (N_PACKETS - 1);
+	}
+	ctx->current_packet = i;
+}
+
+static int start_iso(struct firedtv *fdtv)
+{
+	struct firedtv_receive_context *ctx;
+	struct fw_device *device = device_of(fdtv);
+	int i, err;
+
+	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->context = fw_iso_context_create(device->card,
+			FW_ISO_CONTEXT_RECEIVE, fdtv->isochannel,
+			device->max_speed, ISO_HEADER_SIZE, handle_iso, fdtv);
+	if (IS_ERR(ctx->context)) {
+		err = PTR_ERR(ctx->context);
+		goto fail_free;
+	}
+
+	err = fw_iso_buffer_init(&ctx->buffer, device->card,
+				 N_PAGES, DMA_FROM_DEVICE);
+	if (err)
+		goto fail_context_destroy;
+
+	ctx->interrupt_packet = 0;
+	ctx->current_packet = 0;
+
+	for (i = 0; i < N_PAGES; i++)
+		ctx->pages[i] = page_address(ctx->buffer.pages[i]);
+
+	for (i = 0; i < N_PACKETS; i++) {
+		err = queue_iso(ctx, i);
+		if (err)
+			goto fail;
+	}
+
+	err = fw_iso_context_start(ctx->context, -1, 0,
+				   FW_ISO_CONTEXT_MATCH_ALL_TAGS);
+	if (err)
+		goto fail;
+
+	fdtv->backend_data = ctx;
+
+	return 0;
+fail:
+	fw_iso_buffer_destroy(&ctx->buffer, device->card);
+fail_context_destroy:
+	fw_iso_context_destroy(ctx->context);
+fail_free:
+	kfree(ctx);
+
+	return err;
+}
+
+static void stop_iso(struct firedtv *fdtv)
+{
+	struct firedtv_receive_context *ctx = fdtv->backend_data;
+
+	fw_iso_context_stop(ctx->context);
+	fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
+	fw_iso_context_destroy(ctx->context);
+	kfree(ctx);
+}
+
+static const struct firedtv_backend backend = {
+	.lock		= node_lock,
+	.read		= node_read,
+	.write		= node_write,
+	.start_iso	= start_iso,
+	.stop_iso	= stop_iso,
+};
+
+static void handle_fcp(struct fw_card *card, struct fw_request *request,
+		       int tcode, int destination, int source, int generation,
+		       int speed, unsigned long long offset,
+		       void *payload, size_t length, void *callback_data)
+{
+	struct firedtv *f, *fdtv = NULL;
+	struct fw_device *device;
+	unsigned long flags;
+	int su;
+
+	if (length < 2 || (((u8 *)payload)[0] & 0xf0) != 0)
+		return;
+
+	su = ((u8 *)payload)[1] & 0x7;
+
+	spin_lock_irqsave(&node_list_lock, flags);
+	list_for_each_entry(f, &node_list, list) {
+		device = device_of(f);
+		if (device->generation != generation)
+			continue;
+
+		smp_rmb(); /* node_id vs. generation */
+
+		if (device->card == card &&
+		    device->node_id == source &&
+		    (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
+			fdtv = f;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&node_list_lock, flags);
+
+	if (fdtv)
+		avc_recv(fdtv, payload, length);
+}
+
+static struct fw_address_handler fcp_handler = {
+	.length           = CSR_FCP_END - CSR_FCP_RESPONSE,
+	.address_callback = handle_fcp,
+};
+
+static const struct fw_address_region fcp_region = {
+	.start	= CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
+	.end	= CSR_REGISTER_BASE + CSR_FCP_END,
+};
+
+/* Adjust the template string if models with longer names appear. */
+#define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4))
+
+static size_t model_name(u32 *directory, __be32 *buffer)
+{
+	struct fw_csr_iterator ci;
+	int i, length, key, value, last_key = 0;
+	u32 *block = NULL;
+
+	fw_csr_iterator_init(&ci, directory);
+	while (fw_csr_iterator_next(&ci, &key, &value)) {
+		if (last_key == CSR_MODEL &&
+		    key == (CSR_DESCRIPTOR | CSR_LEAF))
+			block = ci.p - 1 + value;
+		last_key = key;
+	}
+
+	if (block == NULL)
+		return 0;
+
+	length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN);
+	if (length <= 0)
+		return 0;
+
+	/* fast-forward to text string */
+	block += 3;
+
+	for (i = 0; i < length; i++)
+		buffer[i] = cpu_to_be32(block[i]);
+
+	return length * 4;
+}
+
+static int node_probe(struct device *dev)
+{
+	struct firedtv *fdtv;
+	__be32 name[MAX_MODEL_NAME_LEN];
+	int name_len, err;
+
+	name_len = model_name(fw_unit(dev)->directory, name);
+
+	fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len);
+	if (!fdtv)
+		return -ENOMEM;
+
+	err = fdtv_register_rc(fdtv, dev);
+	if (err)
+		goto fail_free;
+
+	spin_lock_irq(&node_list_lock);
+	list_add_tail(&fdtv->list, &node_list);
+	spin_unlock_irq(&node_list_lock);
+
+	err = avc_identify_subunit(fdtv);
+	if (err)
+		goto fail;
+
+	err = fdtv_dvb_register(fdtv);
+	if (err)
+		goto fail;
+
+	avc_register_remote_control(fdtv);
+
+	return 0;
+fail:
+	spin_lock_irq(&node_list_lock);
+	list_del(&fdtv->list);
+	spin_unlock_irq(&node_list_lock);
+	fdtv_unregister_rc(fdtv);
+fail_free:
+	kfree(fdtv);
+
+	return err;
+}
+
+static int node_remove(struct device *dev)
+{
+	struct firedtv *fdtv = dev_get_drvdata(dev);
+
+	fdtv_dvb_unregister(fdtv);
+
+	spin_lock_irq(&node_list_lock);
+	list_del(&fdtv->list);
+	spin_unlock_irq(&node_list_lock);
+
+	fdtv_unregister_rc(fdtv);
+
+	kfree(fdtv);
+	return 0;
+}
+
+static void node_update(struct fw_unit *unit)
+{
+	struct firedtv *fdtv = dev_get_drvdata(&unit->device);
+
+	if (fdtv->isochannel >= 0)
+		cmp_establish_pp_connection(fdtv, fdtv->subunit,
+					    fdtv->isochannel);
+}
+
+static struct fw_driver fdtv_driver = {
+	.driver   = {
+		.owner  = THIS_MODULE,
+		.name   = "firedtv",
+		.bus    = &fw_bus_type,
+		.probe  = node_probe,
+		.remove = node_remove,
+	},
+	.update   = node_update,
+	.id_table = fdtv_id_table,
+};
+
+int __init fdtv_fw_init(void)
+{
+	int ret;
+
+	ret = fw_core_add_address_handler(&fcp_handler, &fcp_region);
+	if (ret < 0)
+		return ret;
+
+	return driver_register(&fdtv_driver.driver);
+}
+
+void fdtv_fw_exit(void)
+{
+	driver_unregister(&fdtv_driver.driver);
+	fw_core_remove_address_handler(&fcp_handler);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 #include <linux/dvb/dmx.h>
 #include <linux/dvb/frontend.h>
 #include <linux/list.h>
+#include <linux/mod_devicetable.h>
 #include <linux/mutex.h>
 #include <linux/spinlock_types.h>
 #include <linux/types.h>
@@ -72,8 +73,8 @@ struct input_dev;
 struct firedtv;
 
 struct firedtv_backend {
-	int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg);
-	int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+	int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
+	int (*read)(struct firedtv *fdtv, u64 addr, void *data);
 	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
 	int (*start_iso)(struct firedtv *fdtv);
 	void (*stop_iso)(struct firedtv *fdtv);
@@ -119,10 +120,10 @@ struct firedtv {
 
 /* firedtv-1394.c */
 #ifdef CONFIG_DVB_FIREDTV_IEEE1394
-int fdtv_1394_init(struct ieee1394_device_id id_table[]);
+int fdtv_1394_init(void);
 void fdtv_1394_exit(void);
 #else
-static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; }
+static inline int fdtv_1394_init(void) { return 0; }
 static inline void fdtv_1394_exit(void) {}
 #endif
 
@@ -163,10 +164,20 @@ struct firedtv *fdtv_alloc(struct device
 			   const struct firedtv_backend *backend,
 			   const char *name, size_t name_len);
 extern const char *fdtv_model_names[];
+extern const struct ieee1394_device_id fdtv_id_table[];
 
 /* firedtv-fe.c */
 void fdtv_frontend_init(struct firedtv *fdtv);
 
+/* firedtv-fw.c */
+#ifdef CONFIG_DVB_FIREDTV_FIREWIRE
+int fdtv_fw_init(void);
+void fdtv_fw_exit(void);
+#else
+static inline int fdtv_fw_init(void) { return 0; }
+static inline void fdtv_fw_exit(void) {}
+#endif
+
 /* firedtv-rc.c */
 #ifdef CONFIG_DVB_FIREDTV_INPUT
 int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-rc.c linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-rc.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/firedtv-rc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/firedtv-rc.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 #include "firedtv.h"
 
@@ -163,6 +164,7 @@ fail:
 
 void fdtv_unregister_rc(struct firedtv *fdtv)
 {
+	cancel_work_sync(&fdtv->remote_ctrl_work);
 	kfree(fdtv->remote_ctrl_dev->keycode);
 	input_unregister_device(fdtv->remote_ctrl_dev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/Kconfig linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config DVB_FIREDTV
 	tristate "FireDTV and FloppyDTV"
-	depends on DVB_CORE && IEEE1394
+	depends on DVB_CORE && (FIREWIRE || IEEE1394)
 	help
 	  Support for DVB receivers from Digital Everywhere
 	  which are connected via IEEE 1394 (FireWire).
@@ -13,8 +13,11 @@ config DVB_FIREDTV
 
 if DVB_FIREDTV
 
+config DVB_FIREDTV_FIREWIRE
+	def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
+
 config DVB_FIREDTV_IEEE1394
-	def_bool IEEE1394
+	def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
 
 config DVB_FIREDTV_INPUT
 	def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/Makefile linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/firewire/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/firewire/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
 obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
 
 firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
+firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
 firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
 firedtv-$(CONFIG_DVB_FIREDTV_INPUT)    += firedtv-rc.o
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,495 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 <asm/div64.h>
+#include "dvb_frontend.h"
+
+#include "atbm8830.h"
+#include "atbm8830_priv.h"
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG "atbm8830: " args); \
+	} while (0)
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
+{
+	int ret = 0;
+	u8 dev_addr;
+	u8 buf1[] = { reg >> 8, reg & 0xFF };
+	u8 buf2[] = { data };
+	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+	struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
+
+	dev_addr = priv->config->demod_address;
+	msg1.addr = dev_addr;
+	msg2.addr = dev_addr;
+
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+			__func__, reg, data);
+
+	ret = i2c_transfer(priv->i2c, &msg1, 1);
+	if (ret != 1)
+		return -EIO;
+
+	ret = i2c_transfer(priv->i2c, &msg2, 1);
+	return (ret != 1) ? -EIO : 0;
+}
+
+static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
+{
+	int ret;
+	u8 dev_addr;
+
+	u8 buf1[] = { reg >> 8, reg & 0xFF };
+	u8 buf2[] = { 0 };
+	struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+	struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
+
+	dev_addr = priv->config->demod_address;
+	msg1.addr = dev_addr;
+	msg2.addr = dev_addr;
+
+	ret = i2c_transfer(priv->i2c, &msg1, 1);
+	if (ret != 1) {
+		dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
+			__func__, reg, ret);
+		return -EIO;
+	}
+
+	ret = i2c_transfer(priv->i2c, &msg2, 1);
+	if (ret != 1)
+		return -EIO;
+
+	*p_data = buf2[0];
+	if (debug >= 2)
+		printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+			__func__, reg, buf2[0]);
+
+	return 0;
+}
+
+/* Lock register latch so that multi-register read is atomic */
+static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
+{
+	return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
+}
+
+static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+	u32 val;
+	u64 t;
+
+	/* 0x100000 * freq / 30.4MHz */
+	t = (u64)0x100000 * freq;
+	do_div(t, 30400);
+	val = t;
+
+	atbm8830_write_reg(priv, REG_OSC_CLK, val);
+	atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
+	atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
+
+	return 0;
+}
+
+static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+
+	u32 fs = priv->config->osc_clk_freq;
+	u64 t;
+	u32 val;
+	u8 dat;
+
+	if (freq != 0) {
+		/* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
+		t = (u64) 2 * 31416 * (freq - fs);
+		t <<= 22;
+		do_div(t, fs);
+		do_div(t, 1000);
+		val = t;
+
+		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
+		atbm8830_write_reg(priv, REG_IF_FREQ, val);
+		atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
+		atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
+
+		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+		dat &= 0xFC;
+		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+	} else {
+		/* Zero IF */
+		atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
+
+		atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+		dat &= 0xFC;
+		dat |= 0x02;
+		atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+
+		if (priv->config->zif_swap_iq)
+			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
+		else
+			atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
+	}
+
+	return 0;
+}
+
+static int is_locked(struct atbm_state *priv, u8 *locked)
+{
+	u8 status;
+
+	atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
+
+	if (locked != NULL)
+		*locked = (status == 1);
+	return 0;
+}
+
+
+static int set_static_channel_mode(struct atbm_state *priv)
+{
+	int i;
+
+	for (i = 0; i < 5; i++)
+		atbm8830_write_reg(priv, 0x099B + i, 0x08);
+
+	atbm8830_write_reg(priv, 0x095B, 0x7F);
+	atbm8830_write_reg(priv, 0x09CB, 0x01);
+	atbm8830_write_reg(priv, 0x09CC, 0x7F);
+	atbm8830_write_reg(priv, 0x09CD, 0x7F);
+	atbm8830_write_reg(priv, 0x0E01, 0x20);
+
+	/* For single carrier */
+	atbm8830_write_reg(priv, 0x0B03, 0x0A);
+	atbm8830_write_reg(priv, 0x0935, 0x10);
+	atbm8830_write_reg(priv, 0x0936, 0x08);
+	atbm8830_write_reg(priv, 0x093E, 0x08);
+	atbm8830_write_reg(priv, 0x096E, 0x06);
+
+	/* frame_count_max0 */
+	atbm8830_write_reg(priv, 0x0B09, 0x00);
+	/* frame_count_max1 */
+	atbm8830_write_reg(priv, 0x0B0A, 0x08);
+
+	return 0;
+}
+
+static int set_ts_config(struct atbm_state *priv)
+{
+	const struct atbm8830_config *cfg = priv->config;
+
+	/*Set parallel/serial ts mode*/
+	atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
+	atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
+	/*Set ts sampling edge*/
+	atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
+		cfg->ts_sampling_edge ? 1 : 0);
+	/*Set ts clock freerun*/
+	atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
+		cfg->ts_clk_gated ? 0 : 1);
+
+	return 0;
+}
+
+static int atbm8830_init(struct dvb_frontend *fe)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	const struct atbm8830_config *cfg = priv->config;
+
+	/*Set oscillator frequency*/
+	set_osc_freq(priv, cfg->osc_clk_freq);
+
+	/*Set IF frequency*/
+	set_if_freq(priv, cfg->if_freq);
+
+
+	/*Set static channel mode*/
+	set_static_channel_mode(priv);
+
+	set_ts_config(priv);
+	/*Turn off DSP reset*/
+	atbm8830_write_reg(priv, 0x000A, 0);
+
+	/*SW version test*/
+	atbm8830_write_reg(priv, 0x020C, 11);
+
+	/* Run */
+	atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
+
+	return 0;
+}
+
+
+static void atbm8830_release(struct dvb_frontend *fe)
+{
+	struct atbm_state *state = fe->demodulator_priv;
+	dprintk("%s\n", __func__);
+
+	kfree(state);
+}
+
+static int atbm8830_set_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	int i;
+	u8 locked = 0;
+	dprintk("%s\n", __func__);
+
+	/* set frequency */
+	if (fe->ops.tuner_ops.set_params) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		fe->ops.tuner_ops.set_params(fe, fe_params);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	/* start auto lock */
+	for (i = 0; i < 10; i++) {
+		mdelay(100);
+		dprintk("Try %d\n", i);
+		is_locked(priv, &locked);
+		if (locked != 0) {
+			dprintk("ATBM8830 locked!\n");
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int atbm8830_get_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	dprintk("%s\n", __func__);
+
+	/* TODO: get real readings from device */
+	/* inversion status */
+	fe_params->inversion = INVERSION_OFF;
+
+	/* bandwidth */
+	fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+
+	fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
+	fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
+
+	fe_params->u.ofdm.constellation = QAM_AUTO;
+
+	/* transmission mode */
+	fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+
+	/* guard interval */
+	fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+
+	/* hierarchy */
+	fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
+
+	return 0;
+}
+
+static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *fesettings)
+{
+	fesettings->min_delay_ms = 0;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
+}
+
+static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u8 locked = 0;
+	u8 agc_locked = 0;
+
+	dprintk("%s\n", __func__);
+	*fe_status = 0;
+
+	is_locked(priv, &locked);
+	if (locked) {
+		*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+			FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+	}
+	dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+
+	atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
+	dprintk("AGC Lock: %d\n", agc_locked);
+
+	return 0;
+}
+
+static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u32 frame_err;
+	u8 t;
+
+	dprintk("%s\n", __func__);
+
+	atbm8830_reglatch_lock(priv, 1);
+
+	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
+	frame_err = t & 0x7F;
+	frame_err <<= 8;
+	atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
+	frame_err |= t;
+
+	atbm8830_reglatch_lock(priv, 0);
+
+	*ber = frame_err * 100 / 32767;
+
+	dprintk("%s: ber=0x%x\n", __func__, *ber);
+	return 0;
+}
+
+static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+	u32 pwm;
+	u8 t;
+
+	dprintk("%s\n", __func__);
+	atbm8830_reglatch_lock(priv, 1);
+
+	atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
+	pwm = t & 0x03;
+	pwm <<= 8;
+	atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
+	pwm |= t;
+
+	atbm8830_reglatch_lock(priv, 0);
+
+	dprintk("AGC PWM = 0x%02X\n", pwm);
+	pwm = 0x400 - pwm;
+
+	*signal = pwm * 0x10000 / 0x400;
+
+	return 0;
+}
+
+static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	dprintk("%s\n", __func__);
+	*snr = 0;
+	return 0;
+}
+
+static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	dprintk("%s\n", __func__);
+	*ucblocks = 0;
+	return 0;
+}
+
+static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct atbm_state *priv = fe->demodulator_priv;
+
+	return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
+}
+
+static struct dvb_frontend_ops atbm8830_ops = {
+	.info = {
+		.name = "AltoBeam ATBM8830/8831 DMB-TH",
+		.type = FE_OFDM,
+		.frequency_min = 474000000,
+		.frequency_max = 858000000,
+		.frequency_stepsize = 10000,
+		.caps =
+			FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO
+	},
+
+	.release = atbm8830_release,
+
+	.init = atbm8830_init,
+	.sleep = NULL,
+	.write = NULL,
+	.i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
+
+	.set_frontend = atbm8830_set_fe,
+	.get_frontend = atbm8830_get_fe,
+	.get_tune_settings = atbm8830_get_tune_settings,
+
+	.read_status = atbm8830_read_status,
+	.read_ber = atbm8830_read_ber,
+	.read_signal_strength = atbm8830_read_signal_strength,
+	.read_snr = atbm8830_read_snr,
+	.read_ucblocks = atbm8830_read_ucblocks,
+};
+
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+	struct i2c_adapter *i2c)
+{
+	struct atbm_state *priv = NULL;
+	u8 data = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (config == NULL || i2c == NULL)
+		return NULL;
+
+	priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
+	if (priv == NULL)
+		goto error_out;
+
+	priv->config = config;
+	priv->i2c = i2c;
+
+	/* check if the demod is there */
+	if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
+		dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
+			__func__, priv->config->demod_address);
+		goto error_out;
+	}
+	dprintk("atbm8830 chip id: 0x%02X\n", data);
+
+	memcpy(&priv->frontend.ops, &atbm8830_ops,
+	       sizeof(struct dvb_frontend_ops));
+	priv->frontend.demodulator_priv = priv;
+
+	atbm8830_init(&priv->frontend);
+
+	atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
+
+	return &priv->frontend;
+
+error_out:
+	dprintk("%s() error_out\n", __func__);
+	kfree(priv);
+	return NULL;
+
+}
+EXPORT_SYMBOL(atbm8830_attach);
+
+MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,76 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 __ATBM8830_H__
+#define __ATBM8830_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define ATBM8830_PROD_8830 0
+#define ATBM8830_PROD_8831 1
+
+struct atbm8830_config {
+
+	/* product type */
+	u8 prod;
+
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* parallel or serial transport stream */
+	u8 serial_ts;
+
+	/* transport stream clock output only when receving valid stream */
+	u8 ts_clk_gated;
+
+	/* Decoder sample TS data at rising edge of clock */
+	u8 ts_sampling_edge;
+
+	/* Oscillator clock frequency */
+	u32 osc_clk_freq; /* in kHz */
+
+	/* IF frequency */
+	u32 if_freq; /* in kHz */
+
+	/* Swap I/Q for zero IF */
+	u8 zif_swap_iq;
+
+	/* Tuner AGC settings */
+	u8 agc_min;
+	u8 agc_max;
+	u8 agc_hold_loop;
+};
+
+#if defined(CONFIG_DVB_ATBM8830) || \
+	(defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
+extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+		struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+		struct i2c_adapter *i2c) {
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_ATBM8830 */
+
+#endif /* __ATBM8830_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/atbm8830_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/atbm8830_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,75 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 __ATBM8830_PRIV_H
+#define __ATBM8830_PRIV_H
+
+struct atbm_state {
+	struct i2c_adapter *i2c;
+	/* configuration settings */
+	const struct atbm8830_config *config;
+	struct dvb_frontend frontend;
+};
+
+#define REG_CHIP_ID	0x0000
+#define REG_TUNER_BASEBAND	0x0001
+#define REG_DEMOD_RUN	0x0004
+#define REG_DSP_RESET	0x0005
+#define REG_RAM_RESET	0x0006
+#define REG_ADC_RESET	0x0007
+#define REG_TSPORT_RESET	0x0008
+#define REG_BLKERR_POL	0x000C
+#define REG_I2C_GATE	0x0103
+#define REG_TS_SAMPLE_EDGE	0x0301
+#define REG_TS_PKT_LEN_204	0x0302
+#define REG_TS_PKT_LEN_AUTO	0x0303
+#define REG_TS_SERIAL	0x0305
+#define REG_TS_CLK_FREERUN	0x0306
+#define REG_TS_VALID_MODE	0x0307
+#define REG_TS_CLK_MODE	0x030B /* 1 for serial, 0 for parallel */
+
+#define REG_TS_ERRBIT_USE	0x030C
+#define REG_LOCK_STATUS	0x030D
+#define REG_ADC_CONFIG	0x0602
+#define REG_CARRIER_OFFSET	0x0827 /* 0x0827-0x0829 little endian */
+#define REG_DETECTED_PN_MODE	0x082D
+#define REG_READ_LATCH	0x084D
+#define REG_IF_FREQ	0x0A00 /* 0x0A00-0x0A02 little endian */
+#define REG_OSC_CLK	0x0A03 /* 0x0A03-0x0A05 little endian */
+#define REG_BYPASS_CCI	0x0A06
+#define REG_ANALOG_LUMA_DETECTED	0x0A25
+#define REG_ANALOG_AUDIO_DETECTED	0x0A26
+#define REG_ANALOG_CHROMA_DETECTED	0x0A39
+#define REG_FRAME_ERR_CNT	0x0B04
+#define REG_USE_EXT_ADC	0x0C00
+#define REG_SWAP_I_Q	0x0C01
+#define REG_TPS_MANUAL	0x0D01
+#define REG_TPS_CONFIG	0x0D02
+#define REG_BYPASS_DEINTERLEAVER	0x0E00
+#define REG_AGC_TARGET	0x1003 /* 0x1003-0x1005 little endian */
+#define REG_AGC_MIN	0x1020
+#define REG_AGC_MAX	0x1023
+#define REG_AGC_LOCK	0x1027
+#define REG_AGC_PWM_VAL	0x1028 /* 0x1028-0x1029 little endian */
+#define REG_AGC_HOLD_LOOP	0x1031
+
+#endif
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/au8522_decoder.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_decoder.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/au8522_decoder.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_decoder.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,6 @@
 /* Developer notes:
  *
  * VBI support is not yet working
- * Saturation and hue setting are not yet working
  * Enough is implemented here for CVBS and S-Video inputs, but the actual
  *  analog demodulator code isn't implemented (not needed for xc5000 since it
  *  has its own demodulator and outputs CVBS)
@@ -63,7 +62,7 @@ struct au8522_register_config {
    The values are as follows from left to right
    0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
 */
-struct au8522_register_config filter_coef[] = {
+static const struct au8522_register_config filter_coef[] = {
 	{AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
 	{AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
 	{AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
@@ -105,7 +104,7 @@ struct au8522_register_config filter_coe
    0="SIF" 1="ATVRF/ATVRF13"
    Note: the "ATVRF/ATVRF13" mode has never been tested
 */
-struct au8522_register_config lpfilter_coef[] = {
+static const struct au8522_register_config lpfilter_coef[] = {
 	{0x060b, {0x21, 0x0b} },
 	{0x060c, {0xad, 0xad} },
 	{0x060d, {0x70, 0xf0} },
@@ -236,8 +235,10 @@ static void setup_decoder_defaults(struc
 	state->contrast = 0x79;
 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+	state->saturation = 0x80;
 	au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
 	au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+	state->hue = 0x00;
 
 	/* Other decoder registers */
 	au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
@@ -315,7 +316,7 @@ static void setup_decoder_defaults(struc
 	if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
 	    input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
 		/* Despite what the table says, for the HVR-950q we still need
-		   to be in CVBS mode for the S-Video input (reason uknown). */
+		   to be in CVBS mode for the S-Video input (reason unknown). */
 		/* filter_coef_type = 3; */
 		filter_coef_type = 5;
 	} else {
@@ -504,7 +505,19 @@ static int au8522_s_ctrl(struct v4l2_sub
 				ctrl->value);
 		break;
 	case V4L2_CID_SATURATION:
+		state->saturation = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
+				ctrl->value);
+		au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
+				ctrl->value);
+		break;
 	case V4L2_CID_HUE:
+		state->hue = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
+				ctrl->value >> 8);
+		au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
+				ctrl->value & 0xFF);
+		break;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
@@ -534,7 +547,11 @@ static int au8522_g_ctrl(struct v4l2_sub
 		ctrl->value = state->contrast;
 		break;
 	case V4L2_CID_SATURATION:
+		ctrl->value = state->saturation;
+		break;
 	case V4L2_CID_HUE:
+		ctrl->value = state->hue;
+		break;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
@@ -632,8 +649,9 @@ static int au8522_queryctrl(struct v4l2_
 	case V4L2_CID_BRIGHTNESS:
 		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_HUE:
-		/* Not yet implemented */
+		return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
 	default:
 		break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/au8522_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/au8522_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/au8522_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,8 @@ struct au8522_state {
 	u32 rev;
 	u8 brightness;
 	u8 contrast;
+	u8 saturation;
+	s16 hue;
 };
 
 /* These are routines shared by both the VSB/QAM demodulator and the analog
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/cx24110.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/cx24110.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/cx24110.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/cx24110.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,4 @@
-	/*
+/*
     cx24110 - Single Chip Satellite Channel Receiver driver module
 
     Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
@@ -96,7 +96,7 @@ static struct {u8 reg; u8 data;} cx24110
 	 {0x42,0x00}, /* @ middle bytes " */
 	 {0x43,0x00}, /* @ LSB          " */
 		      /* leave the carrier tracking loop parameters on default */
-		      /* leave the bit timing loop parameters at gefault */
+		      /* leave the bit timing loop parameters at default */
 	 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
 		      /* the cx24108 data sheet for symbol rates above 15MS/s */
 	 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/cx24113.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/cx24113.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/cx24113.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/cx24113.c	2010-02-24 13:52:17.000000000 -0500
@@ -589,7 +589,7 @@ struct dvb_frontend *cx24113_attach(stru
 		info("detected CX24113 variant\n");
 		break;
 	case REV_CX24113:
-		info("sucessfully detected\n");
+		info("successfully detected\n");
 		break;
 	default:
 		err("unsupported device id: %x\n", state->rev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0070.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0070.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debuggi
 #define DIB0070_P1G  0x03
 #define DIB0070S_P1A 0x02
 
-enum frontend_tune_state {
-	CT_TUNER_START = 10,
-	CT_TUNER_STEP_0,
-	CT_TUNER_STEP_1,
-	CT_TUNER_STEP_2,
-	CT_TUNER_STEP_3,
-	CT_TUNER_STEP_4,
-	CT_TUNER_STEP_5,
-	CT_TUNER_STEP_6,
-	CT_TUNER_STEP_7,
-	CT_TUNER_STOP,
-};
-
-#define FE_CALLBACK_TIME_NEVER 0xffffffff
-
 struct dib0070_state {
 	struct i2c_adapter *i2c;
 	struct dvb_frontend *fe;
@@ -71,10 +56,10 @@ struct dib0070_state {
 	u16 wbd_ff_offset;
 	u8 revision;
 
-	enum frontend_tune_state tune_state;
-	u32 current_rf;
+    enum frontend_tune_state tune_state;
+    u32 current_rf;
 
-	/* for the captrim binary search */
+    /* for the captrim binary search */
 	s8 step;
 	u16 adc_diff;
 
@@ -85,7 +70,7 @@ struct dib0070_state {
 	const struct dib0070_tuning *current_tune_table_index;
 	const struct dib0070_lna_match *lna_match;
 
-	u8 wbd_gain_current;
+    u8  wbd_gain_current;
 	u16 wbd_offset_3_3[2];
 };
 
@@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct
 {
 	u8 b[2];
 	struct i2c_msg msg[2] = {
-		{.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
-		{.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
+		{ .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+		{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
 	};
 	if (i2c_transfer(state->i2c, msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct
 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 {
 	u8 b[3] = { reg, val >> 8, val & 0xff };
-	struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
+	struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
 	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0070 I2C write failed\n");
 		return -EREMOTEIO;
@@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0
 
 static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
 {
-	struct dib0070_state *state = fe->tuner_priv;
-	u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+    struct dib0070_state *state = fe->tuner_priv;
+    u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
 
-	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
-		tmp |= (0 << 14);
-	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
-		tmp |= (1 << 14);
-	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
-		tmp |= (2 << 14);
-	else
-		tmp |= (3 << 14);
+    if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
+	tmp |= (0 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
+	tmp |= (1 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
+	tmp |= (2 << 14);
+    else
+	tmp |= (3 << 14);
 
-	dib0070_write_reg(state, 0x02, tmp);
+    dib0070_write_reg(state, 0x02, tmp);
 
-	/* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
-	if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
-		u16 value = dib0070_read_reg(state, 0x17);
+    /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+	u16 value = dib0070_read_reg(state, 0x17);
 
-		dib0070_write_reg(state, 0x17, value & 0xfffc);
-		tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
-		dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+	dib0070_write_reg(state, 0x17, value & 0xfffc);
+	tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+	dib0070_write_reg(state, 0x01, tmp | (60 << 9));
 
-		dib0070_write_reg(state, 0x17, value);
-	}
+	dib0070_write_reg(state, 0x17, value);
+    }
 	return 0;
 }
 
@@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib007
 	if (*tune_state == CT_TUNER_STEP_0) {
 
 		dib0070_write_reg(state, 0x0f, 0xed10);
-		dib0070_write_reg(state, 0x17, 0x0034);
+		dib0070_write_reg(state, 0x17,    0x0034);
 
 		dib0070_write_reg(state, 0x18, 0x0032);
 		state->step = state->captrim = state->fcaptrim = 64;
 		state->adc_diff = 3000;
 		ret = 20;
 
-		*tune_state = CT_TUNER_STEP_1;
+	*tune_state = CT_TUNER_STEP_1;
 	} else if (*tune_state == CT_TUNER_STEP_1) {
 		state->step /= 2;
 		dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
@@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib007
 
 		adc = dib0070_read_reg(state, 0x19);
 
-		dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
+		dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
 
 		if (adc >= 400) {
 			adc -= 400;
@@ -193,6 +178,8 @@ static int dib0070_captrim(struct dib007
 			state->adc_diff = adc;
 			state->fcaptrim = state->captrim;
 
+
+
 		}
 		state->captrim += (step_sign * state->step);
 
@@ -213,7 +200,7 @@ static int dib0070_captrim(struct dib007
 static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
 {
 	struct dib0070_state *state = fe->tuner_priv;
-	u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
 	dprintk("CTRL_LO5: 0x%x", lo5);
 	return dib0070_write_reg(state, 0x15, lo5);
 }
@@ -227,99 +214,99 @@ void dib0070_ctrl_agc_filter(struct dvb_
 		dib0070_write_reg(state, 0x1a, 0x0000);
 	} else {
 		dib0070_write_reg(state, 0x1b, 0x4112);
-		if (state->cfg->vga_filter != 0) {
-			dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
-			dprintk("vga filter register is set to %x", state->cfg->vga_filter);
-		} else
-			dib0070_write_reg(state, 0x1a, 0x0009);
+	if (state->cfg->vga_filter != 0) {
+		dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+		dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+	} else
+		dib0070_write_reg(state, 0x1a, 0x0009);
 	}
 }
 
 EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
 struct dib0070_tuning {
-	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
-	u8 switch_trim;
-	u8 vco_band;
-	u8 hfdiv;
-	u8 vco_multi;
-	u8 presc;
-	u8 wbdmux;
-	u16 tuner_enable;
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 switch_trim;
+    u8 vco_band;
+    u8 hfdiv;
+    u8 vco_multi;
+    u8 presc;
+    u8 wbdmux;
+    u16 tuner_enable;
 };
 
 struct dib0070_lna_match {
-	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
-	u8 lna_band;
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 lna_band;
 };
 
 static const struct dib0070_tuning dib0070s_tuning_table[] = {
-	{570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800},	/* UHF */
-	{700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
-	{863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
-	{1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},	/* LBAND */
-	{1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
-	{2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
-	{0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000},	/* SBAND */
+    {     570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {    1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
+    {    1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    {    2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
 };
 
 static const struct dib0070_tuning dib0070_tuning_table[] = {
-	{115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000},	/* FM below 92MHz cannot be tuned */
-	{179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000},	/* VHF */
-	{189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
-	{250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
-	{569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800},	/* UHF */
-	{699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
-	{863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
-	{0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400},	/* LBAND or everything higher than UHF */
+    {     115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
+    {     179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
+    {     189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
+    {     250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
+    {     569999, 2, 1, 5,  6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     699999, 2, 0, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    { 0xffffffff, 0, 1, 0,  2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
 };
 
 static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
-	{180000, 0},		/* VHF */
-	{188000, 1},
-	{196400, 2},
-	{250000, 3},
-	{550000, 0},		/* UHF */
-	{590000, 1},
-	{666000, 3},
-	{864000, 5},
-	{1500000, 0},		/* LBAND or everything higher than UHF */
-	{1600000, 1},
-	{2000000, 3},
-	{0xffffffff, 7},
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 0 }, /* UHF */
+    {     590000, 1 },
+    {     666000, 3 },
+    {     864000, 5 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
 };
 
 static const struct dib0070_lna_match dib0070_lna[] = {
-	{180000, 0},		/* VHF */
-	{188000, 1},
-	{196400, 2},
-	{250000, 3},
-	{550000, 2},		/* UHF */
-	{650000, 3},
-	{750000, 5},
-	{850000, 6},
-	{864000, 7},
-	{1500000, 0},		/* LBAND or everything higher than UHF */
-	{1600000, 1},
-	{2000000, 3},
-	{0xffffffff, 7},
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 2 }, /* UHF */
+    {     650000, 3 },
+    {     750000, 5 },
+    {     850000, 6 },
+    {     864000, 7 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
 };
 
-#define LPF	100		// define for the loop filter 100kHz by default 16-07-06
+#define LPF	100
 static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
 {
-	struct dib0070_state *state = fe->tuner_priv;
+    struct dib0070_state *state = fe->tuner_priv;
 
-	const struct dib0070_tuning *tune;
-	const struct dib0070_lna_match *lna_match;
+    const struct dib0070_tuning *tune;
+    const struct dib0070_lna_match *lna_match;
 
-	enum frontend_tune_state *tune_state = &state->tune_state;
-	int ret = 10;		/* 1ms is the default delay most of the time */
+    enum frontend_tune_state *tune_state = &state->tune_state;
+    int ret = 10; /* 1ms is the default delay most of the time */
 
-	u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
-	u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
+    u8  band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
+    u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
 
 #ifdef CONFIG_SYS_ISDBT
-	if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
 		if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
 		     && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
 		    || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
@@ -328,172 +315,180 @@ static int dib0070_tune_digital(struct d
 			&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
 			freq += 850;
 #endif
+    if (state->current_rf != freq) {
+
+	switch (state->revision) {
+	case DIB0070S_P1A:
+	    tune = dib0070s_tuning_table;
+	    lna_match = dib0070_lna;
+	    break;
+	default:
+	    tune = dib0070_tuning_table;
+	    if (state->cfg->flip_chip)
+		lna_match = dib0070_lna_flip_chip;
+	    else
+		lna_match = dib0070_lna;
+	    break;
+	}
+	while (freq > tune->max_freq) /* find the right one */
+	    tune++;
+	while (freq > lna_match->max_freq) /* find the right one */
+	    lna_match++;
+
+	state->current_tune_table_index = tune;
+	state->lna_match = lna_match;
+    }
+
+    if (*tune_state == CT_TUNER_START) {
+	dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
 	if (state->current_rf != freq) {
+		u8 REFDIV;
+		u32 FBDiv, Rest, FREF, VCOF_kHz;
+		u8 Den;
 
-		switch (state->revision) {
-		case DIB0070S_P1A:
-			tune = dib0070s_tuning_table;
-			lna_match = dib0070_lna;
+		state->current_rf = freq;
+		state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+
+
+		dib0070_write_reg(state, 0x17, 0x30);
+
+
+		VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
+
+		switch (band) {
+		case BAND_VHF:
+			REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+			break;
+		case BAND_FM:
+			REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
 			break;
 		default:
-			tune = dib0070_tuning_table;
-			if (state->cfg->flip_chip)
-				lna_match = dib0070_lna_flip_chip;
-			else
-				lna_match = dib0070_lna;
+			REFDIV = (u8) (state->cfg->clock_khz  / 10000);
 			break;
 		}
-		while (freq > tune->max_freq)	/* find the right one */
-			tune++;
-		while (freq > lna_match->max_freq)	/* find the right one */
-			lna_match++;
-
-		state->current_tune_table_index = tune;
-		state->lna_match = lna_match;
-	}
-
-	if (*tune_state == CT_TUNER_START) {
-		dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
-		if (state->current_rf != freq) {
-			u8 REFDIV;
-			u32 FBDiv, Rest, FREF, VCOF_kHz;
-			u8 Den;
-
-			state->current_rf = freq;
-			state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+		FREF = state->cfg->clock_khz / REFDIV;
 
-			dib0070_write_reg(state, 0x17, 0x30);
 
-			VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
 
-			switch (band) {
-			case BAND_VHF:
-				REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
-				break;
-			case BAND_FM:
-				REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
-				break;
-			default:
-				REFDIV = (u8) (state->cfg->clock_khz / 10000);
-				break;
-			}
-			FREF = state->cfg->clock_khz / REFDIV;
+		switch (state->revision) {
+		case DIB0070S_P1A:
+			FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+			Rest  = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+			break;
 
-			switch (state->revision) {
-			case DIB0070S_P1A:
-				FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
-				Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
-				break;
+		case DIB0070_P1G:
+		case DIB0070_P1F:
+		default:
+			FBDiv = (freq / (FREF / 2));
+			Rest  = 2 * freq - FBDiv * FREF;
+			break;
+		}
 
-			case DIB0070_P1G:
-			case DIB0070_P1F:
-			default:
-				FBDiv = (freq / (FREF / 2));
-				Rest = 2 * freq - FBDiv * FREF;
-				break;
-			}
+		if (Rest < LPF)
+			Rest = 0;
+		else if (Rest < 2 * LPF)
+			Rest = 2 * LPF;
+		else if (Rest > (FREF - LPF)) {
+			Rest = 0;
+			FBDiv += 1;
+		} else if (Rest > (FREF - 2 * LPF))
+			Rest = FREF - 2 * LPF;
+		Rest = (Rest * 6528) / (FREF / 10);
 
-			if (Rest < LPF)
-				Rest = 0;
-			else if (Rest < 2 * LPF)
-				Rest = 2 * LPF;
-			else if (Rest > (FREF - LPF)) {
-				Rest = 0;
-				FBDiv += 1;
-			} else if (Rest > (FREF - 2 * LPF))
-				Rest = FREF - 2 * LPF;
-			Rest = (Rest * 6528) / (FREF / 10);
+		Den = 1;
+		if (Rest > 0) {
+			state->lo4 |= (1 << 14) | (1 << 12);
+			Den = 255;
+		}
 
-			Den = 1;
-			if (Rest > 0) {
-				state->lo4 |= (1 << 14) | (1 << 12);
-				Den = 255;
-			}
 
-			dib0070_write_reg(state, 0x11, (u16) FBDiv);
-			dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
-			dib0070_write_reg(state, 0x13, (u16) Rest);
+		dib0070_write_reg(state, 0x11, (u16)FBDiv);
+		dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+		dib0070_write_reg(state, 0x13, (u16) Rest);
 
-			if (state->revision == DIB0070S_P1A) {
+		if (state->revision == DIB0070S_P1A) {
 
-				if (band == BAND_SBAND) {
-					dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-					dib0070_write_reg(state, 0x1d, 0xFFFF);
-				} else
-					dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
-			}
+			if (band == BAND_SBAND) {
+				dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+				dib0070_write_reg(state, 0x1d, 0xFFFF);
+			} else
+				dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+		}
 
-			dib0070_write_reg(state, 0x20,
-					  0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
+		dib0070_write_reg(state, 0x20,
+			0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
 
-			dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
-			dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
-			dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
-			dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
-			dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
-			dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
+		dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+		dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+		dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+		dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+		dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+		dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
 
-			*tune_state = CT_TUNER_STEP_0;
-		} else {	/* we are already tuned to this frequency - the configuration is correct  */
-			ret = 50;	/* wakeup time */
-			*tune_state = CT_TUNER_STEP_5;
-		}
-	} else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+		*tune_state = CT_TUNER_STEP_0;
+	} else { /* we are already tuned to this frequency - the configuration is correct  */
+		ret = 50; /* wakeup time */
+		*tune_state = CT_TUNER_STEP_5;
+	}
+    } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
 
-		ret = dib0070_captrim(state, tune_state);
+	ret = dib0070_captrim(state, tune_state);
 
-	} else if (*tune_state == CT_TUNER_STEP_4) {
-		const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-		if (tmp != NULL) {
-			while (freq / 1000 > tmp->freq)	/* find the right one */
-				tmp++;
-			dib0070_write_reg(state, 0x0f,
-					  (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
-																current_tune_table_index->
-																wbdmux << 0));
-			state->wbd_gain_current = tmp->wbd_gain_val;
-		} else {
+    } else if (*tune_state == CT_TUNER_STEP_4) {
+	const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+	if (tmp != NULL) {
+		while (freq/1000 > tmp->freq) /* find the right one */
+			tmp++;
+		dib0070_write_reg(state, 0x0f,
+			(0 << 15) | (1 << 14) | (3 << 12)
+			| (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
+			| (state->current_tune_table_index->wbdmux << 0));
+		state->wbd_gain_current = tmp->wbd_gain_val;
+	} else {
 			dib0070_write_reg(state, 0x0f,
 					  (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
 														wbdmux << 0));
-			state->wbd_gain_current = 6;
-		}
+	    state->wbd_gain_current = 6;
+	}
 
-		dib0070_write_reg(state, 0x06, 0x3fff);
+	dib0070_write_reg(state, 0x06, 0x3fff);
 		dib0070_write_reg(state, 0x07,
 				  (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
-		dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
-		dib0070_write_reg(state, 0x0d, 0x0d80);
+	dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+	dib0070_write_reg(state, 0x0d, 0x0d80);
 
-		dib0070_write_reg(state, 0x18, 0x07ff);
-		dib0070_write_reg(state, 0x17, 0x0033);
 
-		*tune_state = CT_TUNER_STEP_5;
-	} else if (*tune_state == CT_TUNER_STEP_5) {
-		dib0070_set_bandwidth(fe, ch);
-		*tune_state = CT_TUNER_STOP;
-	} else {
-		ret = FE_CALLBACK_TIME_NEVER;	/* tuner finished, time to call again infinite */
-	}
-	return ret;
+	dib0070_write_reg(state, 0x18,   0x07ff);
+	dib0070_write_reg(state, 0x17, 0x0033);
+
+
+	*tune_state = CT_TUNER_STEP_5;
+    } else if (*tune_state == CT_TUNER_STEP_5) {
+	dib0070_set_bandwidth(fe, ch);
+	*tune_state = CT_TUNER_STOP;
+    } else {
+	ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
+    }
+    return ret;
 }
 
+
 static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
 {
-	struct dib0070_state *state = fe->tuner_priv;
-	uint32_t ret;
+    struct dib0070_state *state = fe->tuner_priv;
+    uint32_t ret;
 
-	state->tune_state = CT_TUNER_START;
+    state->tune_state = CT_TUNER_START;
 
-	do {
-		ret = dib0070_tune_digital(fe, p);
-		if (ret != FE_CALLBACK_TIME_NEVER)
-			msleep(ret / 10);
-		else
-			break;
-	} while (state->tune_state != CT_TUNER_STOP);
+    do {
+	ret = dib0070_tune_digital(fe, p);
+	if (ret != FE_CALLBACK_TIME_NEVER)
+		msleep(ret/10);
+	else
+	    break;
+    } while (state->tune_state != CT_TUNER_STOP);
 
-	return 0;
+    return 0;
 }
 
 static int dib0070_wakeup(struct dvb_frontend *fe)
@@ -512,92 +507,113 @@ static int dib0070_sleep(struct dvb_fron
 	return 0;
 }
 
-static const u16 dib0070_p1f_defaults[] = {
+u8 dib0070_get_rf_output(struct dvb_frontend *fe)
+{
+	struct dib0070_state *state = fe->tuner_priv;
+	return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
+}
+EXPORT_SYMBOL(dib0070_get_rf_output);
+
+int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
+{
+	struct dib0070_state *state = fe->tuner_priv;
+	u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
+	if (no > 3)
+		no = 3;
+	if (no < 1)
+		no = 1;
+	return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
+}
+EXPORT_SYMBOL(dib0070_set_rf_output);
+
+static const u16 dib0070_p1f_defaults[] =
+
+{
 	7, 0x02,
-	0x0008,
-	0x0000,
-	0x0000,
-	0x0000,
-	0x0000,
-	0x0002,
-	0x0100,
+		0x0008,
+		0x0000,
+		0x0000,
+		0x0000,
+		0x0000,
+		0x0002,
+		0x0100,
 
 	3, 0x0d,
-	0x0d80,
-	0x0001,
-	0x0000,
+		0x0d80,
+		0x0001,
+		0x0000,
 
 	4, 0x11,
-	0x0000,
-	0x0103,
-	0x0000,
-	0x0000,
+		0x0000,
+		0x0103,
+		0x0000,
+		0x0000,
 
 	3, 0x16,
-	0x0004 | 0x0040,
-	0x0030,
-	0x07ff,
+		0x0004 | 0x0040,
+		0x0030,
+		0x07ff,
 
 	6, 0x1b,
-	0x4112,
-	0xff00,
-	0xc07f,
-	0x0000,
-	0x0180,
-	0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+		0x4112,
+		0xff00,
+		0xc07f,
+		0x0000,
+		0x0180,
+		0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
 
 	0,
 };
 
 static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
 {
-	u16 tuner_en = dib0070_read_reg(state, 0x20);
-	u16 offset;
+    u16 tuner_en = dib0070_read_reg(state, 0x20);
+    u16 offset;
 
-	dib0070_write_reg(state, 0x18, 0x07ff);
-	dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
-	dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
-	msleep(9);
-	offset = dib0070_read_reg(state, 0x19);
-	dib0070_write_reg(state, 0x20, tuner_en);
-	return offset;
+    dib0070_write_reg(state, 0x18, 0x07ff);
+    dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+    dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
+    msleep(9);
+    offset = dib0070_read_reg(state, 0x19);
+    dib0070_write_reg(state, 0x20, tuner_en);
+    return offset;
 }
 
 static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
 {
-	u8 gain;
-	for (gain = 6; gain < 8; gain++) {
-		state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
-		dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
-	}
+    u8 gain;
+    for (gain = 6; gain < 8; gain++) {
+	state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+	dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
+    }
 }
 
 u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 {
-	struct dib0070_state *state = fe->tuner_priv;
-	const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-	u32 freq = fe->dtv_property_cache.frequency / 1000;
+    struct dib0070_state *state = fe->tuner_priv;
+    const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+    u32 freq = fe->dtv_property_cache.frequency/1000;
 
-	if (tmp != NULL) {
-		while (freq / 1000 > tmp->freq)	/* find the right one */
-			tmp++;
-		state->wbd_gain_current = tmp->wbd_gain_val;
+    if (tmp != NULL) {
+	while (freq/1000 > tmp->freq) /* find the right one */
+	    tmp++;
+	state->wbd_gain_current = tmp->wbd_gain_val;
 	} else
-		state->wbd_gain_current = 6;
+	state->wbd_gain_current = 6;
 
-	return state->wbd_offset_3_3[state->wbd_gain_current - 6];
+    return state->wbd_offset_3_3[state->wbd_gain_current - 6];
 }
-
 EXPORT_SYMBOL(dib0070_wbd_offset);
 
 #define pgm_read_word(w) (*w)
 static int dib0070_reset(struct dvb_frontend *fe)
 {
-	struct dib0070_state *state = fe->tuner_priv;
+    struct dib0070_state *state = fe->tuner_priv;
 	u16 l, r, *n;
 
 	HARD_RESET(state);
 
+
 #ifndef FORCE_SBAND_TUNER
 	if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
 		state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
@@ -605,7 +621,7 @@ static int dib0070_reset(struct dvb_fron
 #else
 #warning forcing SBAND
 #endif
-	state->revision = DIB0070S_P1A;
+		state->revision = DIB0070S_P1A;
 
 	/* P1F or not */
 	dprintk("Revision: %x", state->revision);
@@ -620,7 +636,7 @@ static int dib0070_reset(struct dvb_fron
 	while (l) {
 		r = pgm_read_word(n++);
 		do {
-			dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
+			dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
 			r++;
 		} while (--l);
 		l = pgm_read_word(n++);
@@ -633,6 +649,7 @@ static int dib0070_reset(struct dvb_fron
 	else
 		r = 2;
 
+
 	r |= state->cfg->osc_buffer_state << 3;
 
 	dib0070_write_reg(state, 0x10, r);
@@ -643,16 +660,24 @@ static int dib0070_reset(struct dvb_fron
 		dib0070_write_reg(state, 0x02, r | (1 << 5));
 	}
 
-	if (state->revision == DIB0070S_P1A)
-		dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-	else
+    if (state->revision == DIB0070S_P1A)
+	dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+    else
 		dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
 
 	dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
 
-	dib0070_wbd_offset_calibration(state);
+    dib0070_wbd_offset_calibration(state);
 
-	return 0;
+    return 0;
+}
+
+static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+
+    *frequency = 1000 * state->current_rf;
+    return 0;
 }
 
 static int dib0070_release(struct dvb_frontend *fe)
@@ -664,18 +689,18 @@ static int dib0070_release(struct dvb_fr
 
 static const struct dvb_tuner_ops dib0070_ops = {
 	.info = {
-		 .name = "DiBcom DiB0070",
-		 .frequency_min = 45000000,
-		 .frequency_max = 860000000,
-		 .frequency_step = 1000,
-		 },
-	.release = dib0070_release,
+		.name           = "DiBcom DiB0070",
+		.frequency_min  =  45000000,
+		.frequency_max  = 860000000,
+		.frequency_step =      1000,
+	},
+	.release       = dib0070_release,
 
-	.init = dib0070_wakeup,
-	.sleep = dib0070_sleep,
-	.set_params = dib0070_tune,
+	.init          = dib0070_wakeup,
+	.sleep         = dib0070_sleep,
+	.set_params    = dib0070_tune,
 
-//      .get_frequency = dib0070_get_frequency,
+	.get_frequency = dib0070_get_frequency,
 //      .get_bandwidth = dib0070_get_bandwidth
 };
 
@@ -687,7 +712,7 @@ struct dvb_frontend *dib0070_attach(stru
 
 	state->cfg = cfg;
 	state->i2c = i2c;
-	state->fe = fe;
+	state->fe  = fe;
 	fe->tuner_priv = state;
 
 	if (dib0070_reset(fe) != 0)
@@ -699,12 +724,11 @@ struct dvb_frontend *dib0070_attach(stru
 	fe->tuner_priv = state;
 	return fe;
 
- free_mem:
+free_mem:
 	kfree(state);
 	fe->tuner_priv = NULL;
 	return NULL;
 }
-
 EXPORT_SYMBOL(dib0070_attach);
 
 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0070.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0070.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0070.h	2010-02-24 13:52:17.000000000 -0500
@@ -52,6 +52,8 @@ struct dib0070_config {
 extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
 extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
+extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
+extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
 #else
 static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
 {
@@ -62,7 +64,7 @@ static inline struct dvb_frontend *dib00
 static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-	return -ENODEV;
+	return 0;
 }
 
 static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0090.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0090.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1522 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
+ *
+ * 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.
+ *
+ *
+ * This code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "dib0090.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { \
+	if (debug) { \
+		printk(KERN_DEBUG "DiB0090: "); \
+		printk(args); \
+		printk("\n"); \
+	} \
+} while (0)
+
+#define CONFIG_SYS_ISDBT
+#define CONFIG_BAND_CBAND
+#define CONFIG_BAND_VHF
+#define CONFIG_BAND_UHF
+#define CONFIG_DIB0090_USE_PWM_AGC
+
+#define EN_LNA0      0x8000
+#define EN_LNA1      0x4000
+#define EN_LNA2      0x2000
+#define EN_LNA3      0x1000
+#define EN_MIX0      0x0800
+#define EN_MIX1      0x0400
+#define EN_MIX2      0x0200
+#define EN_MIX3      0x0100
+#define EN_IQADC     0x0040
+#define EN_PLL       0x0020
+#define EN_TX        0x0010
+#define EN_BB        0x0008
+#define EN_LO        0x0004
+#define EN_BIAS      0x0001
+
+#define EN_IQANA     0x0002
+#define EN_DIGCLK    0x0080	/* not in the 0x24 reg, only in 0x1b */
+#define EN_CRYSTAL   0x0002
+
+#define EN_UHF		 0x22E9
+#define EN_VHF		 0x44E9
+#define EN_LBD		 0x11E9
+#define EN_SBD		 0x44E9
+#define EN_CAB		 0x88E9
+
+#define pgm_read_word(w) (*w)
+
+struct dc_calibration;
+
+struct dib0090_tuning {
+	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
+	u8 switch_trim;
+	u8 lna_tune;
+	u8 lna_bias;
+	u16 v2i;
+	u16 mix;
+	u16 load;
+	u16 tuner_enable;
+};
+
+struct dib0090_pll {
+	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
+	u8 vco_band;
+	u8 hfdiv_code;
+	u8 hfdiv;
+	u8 topresc;
+};
+
+struct dib0090_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend *fe;
+	const struct dib0090_config *config;
+
+	u8 current_band;
+	u16 revision;
+	enum frontend_tune_state tune_state;
+	u32 current_rf;
+
+	u16 wbd_offset;
+	s16 wbd_target;		/* in dB */
+
+	s16 rf_gain_limit;	/* take-over-point: where to split between bb and rf gain */
+	s16 current_gain;	/* keeps the currently programmed gain */
+	u8 agc_step;		/* new binary search */
+
+	u16 gain[2];		/* for channel monitoring */
+
+	const u16 *rf_ramp;
+	const u16 *bb_ramp;
+
+	/* for the software AGC ramps */
+	u16 bb_1_def;
+	u16 rf_lt_def;
+	u16 gain_reg[4];
+
+	/* for the captrim/dc-offset search */
+	s8 step;
+	s16 adc_diff;
+	s16 min_adc_diff;
+
+	s8 captrim;
+	s8 fcaptrim;
+
+	const struct dc_calibration *dc;
+	u16 bb6, bb7;
+
+	const struct dib0090_tuning *current_tune_table_index;
+	const struct dib0090_pll *current_pll_table_index;
+
+	u8 tuner_is_tuned;
+	u8 agc_freeze;
+
+	u8 reset;
+};
+
+static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
+{
+	u8 b[2];
+	struct i2c_msg msg[2] = {
+		{.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1},
+		{.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
+	};
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+		printk(KERN_WARNING "DiB0090 I2C read failed\n");
+		return 0;
+	}
+	return (b[0] << 8) | b[1];
+}
+
+static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
+{
+	u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
+	struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "DiB0090 I2C write failed\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+#define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
+#define ADC_TARGET -220
+#define GAIN_ALPHA 5
+#define WBD_ALPHA 6
+#define LPF	100
+static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
+{
+	do {
+		dib0090_write_reg(state, r++, *b++);
+	} while (--c);
+}
+
+static u16 dib0090_identify(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	u16 v;
+
+	v = dib0090_read_reg(state, 0x1a);
+
+#ifdef FIRMWARE_FIREFLY
+	/* pll is not locked locked */
+	if (!(v & 0x800))
+		dprintk("FE%d : Identification : pll is not yet locked", fe->id);
+#endif
+
+	/* without PLL lock info */
+	v &= 0x3ff;
+	dprintk("P/V: %04x:", v);
+
+	if ((v >> 8) & 0xf)
+		dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf);
+	else
+		return 0xff;
+
+	v &= 0xff;
+	if (((v >> 5) & 0x7) == 0x1)
+		dprintk("FE%d : MP001 : 9090/8096", fe->id);
+	else if (((v >> 5) & 0x7) == 0x4)
+		dprintk("FE%d : MP005 : Single Sband", fe->id);
+	else if (((v >> 5) & 0x7) == 0x6)
+		dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id);
+	else if (((v >> 5) & 0x7) == 0x7)
+		dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id);
+	else
+		return 0xff;
+
+	/* revision only */
+	if ((v & 0x1f) == 0x3)
+		dprintk("FE%d : P1-D/E/F detected", fe->id);
+	else if ((v & 0x1f) == 0x1)
+		dprintk("FE%d : P1C detected", fe->id);
+	else if ((v & 0x1f) == 0x0) {
+#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
+		dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id);
+		dib0090_p1b_register(fe);
+#else
+		dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id);
+		return 0xff;
+#endif
+	}
+
+	return v;
+}
+
+static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	HARD_RESET(state);
+
+	dib0090_write_reg(state, 0x24, EN_PLL);
+	dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
+
+	/* adcClkOutRatio=8->7, release reset */
+	dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
+	if (cfg->clkoutdrive != 0)
+		dib0090_write_reg(state, 0x23,
+				  (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
+																	   clkouttobamse
+																	   << 4) | (0
+																		    <<
+																		    2)
+				  | (0));
+	else
+		dib0090_write_reg(state, 0x23,
+				  (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg->
+															    clkouttobamse << 4) | (0
+																		   <<
+																		   2)
+				  | (0));
+
+	/* enable pll, de-activate reset, ratio: 2/1 = 60MHz */
+	dib0090_write_reg(state, 0x21,
+			  (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv));
+
+}
+
+static int dib0090_wakeup(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	if (state->config->sleep)
+		state->config->sleep(fe, 0);
+	return 0;
+}
+
+static int dib0090_sleep(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	if (state->config->sleep)
+		state->config->sleep(fe, 1);
+	return 0;
+}
+
+extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	if (fast)
+		dib0090_write_reg(state, 0x04, 0);
+	else
+		dib0090_write_reg(state, 0x04, 1);
+}
+EXPORT_SYMBOL(dib0090_dcc_freq);
+
+static const u16 rf_ramp_pwm_cband[] = {
+	0,			/* max RF gain in 10th of dB */
+	0,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+	0,			/* ramp_max = maximum X used on the ramp */
+	(0 << 10) | 0,		/* 0x2c, LNA 1 = 0dB */
+	(0 << 10) | 0,		/* 0x2d, LNA 1 */
+	(0 << 10) | 0,		/* 0x2e, LNA 2 = 0dB */
+	(0 << 10) | 0,		/* 0x2f, LNA 2 */
+	(0 << 10) | 0,		/* 0x30, LNA 3 = 0dB */
+	(0 << 10) | 0,		/* 0x31, LNA 3 */
+	(0 << 10) | 0,		/* GAIN_4_1, LNA 4 = 0dB */
+	(0 << 10) | 0,		/* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_vhf[] = {
+	412,			/* max RF gain in 10th of dB */
+	132, 307, 127,		/* LNA1,  13.2dB */
+	105, 412, 255,		/* LNA2,  10.5dB */
+	50, 50, 127,		/* LNA3,  5dB */
+	125, 175, 127,		/* LNA4,  12.5dB */
+	0, 0, 127,		/* CBAND, 0dB */
+};
+
+static const u16 rf_ramp_uhf[] = {
+	412,			/* max RF gain in 10th of dB */
+	132, 307, 127,		/* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
+	105, 412, 255,		/* LNA2  : 10.5 dB */
+	50, 50, 127,		/* LNA3  :  5.0 dB */
+	125, 175, 127,		/* LNA4  : 12.5 dB */
+	0, 0, 127,		/* CBAND :  0.0 dB */
+};
+
+static const u16 rf_ramp_cband[] = {
+	332,			/* max RF gain in 10th of dB */
+	132, 252, 127,		/* LNA1,  dB */
+	80, 332, 255,		/* LNA2,  dB */
+	0, 0, 127,		/* LNA3,  dB */
+	0, 0, 127,		/* LNA4,  dB */
+	120, 120, 127,		/* LT1 CBAND */
+};
+
+static const u16 rf_ramp_pwm_vhf[] = {
+	404,			/* max RF gain in 10th of dB */
+	25,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+	1011,			/* ramp_max = maximum X used on the ramp */
+	(6 << 10) | 417,	/* 0x2c, LNA 1 = 13.2dB */
+	(0 << 10) | 756,	/* 0x2d, LNA 1 */
+	(16 << 10) | 756,	/* 0x2e, LNA 2 = 10.5dB */
+	(0 << 10) | 1011,	/* 0x2f, LNA 2 */
+	(16 << 10) | 290,	/* 0x30, LNA 3 = 5dB */
+	(0 << 10) | 417,	/* 0x31, LNA 3 */
+	(7 << 10) | 0,		/* GAIN_4_1, LNA 4 = 12.5dB */
+	(0 << 10) | 290,	/* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_uhf[] = {
+	404,			/* max RF gain in 10th of dB */
+	25,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+	1011,			/* ramp_max = maximum X used on the ramp */
+	(6 << 10) | 417,	/* 0x2c, LNA 1 = 13.2dB */
+	(0 << 10) | 756,	/* 0x2d, LNA 1 */
+	(16 << 10) | 756,	/* 0x2e, LNA 2 = 10.5dB */
+	(0 << 10) | 1011,	/* 0x2f, LNA 2 */
+	(16 << 10) | 0,		/* 0x30, LNA 3 = 5dB */
+	(0 << 10) | 127,	/* 0x31, LNA 3 */
+	(7 << 10) | 127,	/* GAIN_4_1, LNA 4 = 12.5dB */
+	(0 << 10) | 417,	/* GAIN_4_2, LNA 4 */
+};
+
+static const u16 bb_ramp_boost[] = {
+	550,			/* max BB gain in 10th of dB */
+	260, 260, 26,		/* BB1, 26dB */
+	290, 550, 29,		/* BB2, 29dB */
+};
+
+static const u16 bb_ramp_pwm_normal[] = {
+	500,			/* max RF gain in 10th of dB */
+	8,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
+	400,
+	(2 << 9) | 0,		/* 0x35 = 21dB */
+	(0 << 9) | 168,		/* 0x36 */
+	(2 << 9) | 168,		/* 0x37 = 29dB */
+	(0 << 9) | 400,		/* 0x38 */
+};
+
+struct slope {
+	int16_t range;
+	int16_t slope;
+};
+static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
+{
+	u8 i;
+	u16 rest;
+	u16 ret = 0;
+	for (i = 0; i < num; i++) {
+		if (val > slopes[i].range)
+			rest = slopes[i].range;
+		else
+			rest = val;
+		ret += (rest * slopes[i].slope) / slopes[i].range;
+		val -= rest;
+	}
+	return ret;
+}
+
+static const struct slope dib0090_wbd_slopes[3] = {
+	{66, 120},		/* -64,-52: offset -   65 */
+	{600, 170},		/* -52,-35: 65     -  665 */
+	{170, 250},		/* -45,-10: 665    - 835 */
+};
+
+static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
+{
+	wbd &= 0x3ff;
+	if (wbd < state->wbd_offset)
+		wbd = 0;
+	else
+		wbd -= state->wbd_offset;
+	/* -64dB is the floor */
+	return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
+}
+
+static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
+{
+	u16 offset = 250;
+
+	/* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
+
+	if (state->current_band == BAND_VHF)
+		offset = 650;
+#ifndef FIRMWARE_FIREFLY
+	if (state->current_band == BAND_VHF)
+		offset = state->config->wbd_vhf_offset;
+	if (state->current_band == BAND_CBAND)
+		offset = state->config->wbd_cband_offset;
+#endif
+
+	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
+	dprintk("wbd-target: %d dB", (u32) state->wbd_target);
+}
+
+static const int gain_reg_addr[4] = {
+	0x08, 0x0a, 0x0f, 0x01
+};
+
+static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
+{
+	u16 rf, bb, ref;
+	u16 i, v, gain_reg[4] = { 0 }, gain;
+	const u16 *g;
+
+	if (top_delta < -511)
+		top_delta = -511;
+	if (top_delta > 511)
+		top_delta = 511;
+
+	if (force) {
+		top_delta *= (1 << WBD_ALPHA);
+		gain_delta *= (1 << GAIN_ALPHA);
+	}
+
+	if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))	/* overflow */
+		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
+	else
+		state->rf_gain_limit += top_delta;
+
+	if (state->rf_gain_limit < 0)	/*underflow */
+		state->rf_gain_limit = 0;
+
+	/* use gain as a temporary variable and correct current_gain */
+	gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
+	if (gain_delta >= ((s16) gain - state->current_gain))	/* overflow */
+		state->current_gain = gain;
+	else
+		state->current_gain += gain_delta;
+	/* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
+	if (state->current_gain < 0)
+		state->current_gain = 0;
+
+	/* now split total gain to rf and bb gain */
+	gain = state->current_gain >> GAIN_ALPHA;
+
+	/* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
+	if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
+		rf = state->rf_gain_limit >> WBD_ALPHA;
+		bb = gain - rf;
+		if (bb > state->bb_ramp[0])
+			bb = state->bb_ramp[0];
+	} else {		/* high signal level -> all gains put on RF */
+		rf = gain;
+		bb = 0;
+	}
+
+	state->gain[0] = rf;
+	state->gain[1] = bb;
+
+	/* software ramp */
+	/* Start with RF gains */
+	g = state->rf_ramp + 1;	/* point on RF LNA1 max gain */
+	ref = rf;
+	for (i = 0; i < 7; i++) {	/* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
+		if (g[0] == 0 || ref < (g[1] - g[0]))	/* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
+			v = 0;	/* force the gain to write for the current amp to be null */
+		else if (ref >= g[1])	/* Gain to set is higher than the high working point of this amp */
+			v = g[2];	/* force this amp to be full gain */
+		else		/* compute the value to set to this amp because we are somewhere in his range */
+			v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
+
+		if (i == 0)	/* LNA 1 reg mapping */
+			gain_reg[0] = v;
+		else if (i == 1)	/* LNA 2 reg mapping */
+			gain_reg[0] |= v << 7;
+		else if (i == 2)	/* LNA 3 reg mapping */
+			gain_reg[1] = v;
+		else if (i == 3)	/* LNA 4 reg mapping */
+			gain_reg[1] |= v << 7;
+		else if (i == 4)	/* CBAND LNA reg mapping */
+			gain_reg[2] = v | state->rf_lt_def;
+		else if (i == 5)	/* BB gain 1 reg mapping */
+			gain_reg[3] = v << 3;
+		else if (i == 6)	/* BB gain 2 reg mapping */
+			gain_reg[3] |= v << 8;
+
+		g += 3;		/* go to next gain bloc */
+
+		/* When RF is finished, start with BB */
+		if (i == 4) {
+			g = state->bb_ramp + 1;	/* point on BB gain 1 max gain */
+			ref = bb;
+		}
+	}
+	gain_reg[3] |= state->bb_1_def;
+	gain_reg[3] |= ((bb % 10) * 100) / 125;
+
+#ifdef DEBUG_AGC
+	dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
+		gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
+#endif
+
+	/* Write the amplifier regs */
+	for (i = 0; i < 4; i++) {
+		v = gain_reg[i];
+		if (force || state->gain_reg[i] != v) {
+			state->gain_reg[i] = v;
+			dib0090_write_reg(state, gain_reg_addr[i], v);
+		}
+	}
+}
+
+static void dib0090_set_boost(struct dib0090_state *state, int onoff)
+{
+	state->bb_1_def &= 0xdfff;
+	state->bb_1_def |= onoff << 13;
+}
+
+static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
+{
+	state->rf_ramp = cfg;
+}
+
+static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
+{
+	state->rf_ramp = cfg;
+
+	dib0090_write_reg(state, 0x2a, 0xffff);
+
+	dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
+
+	dib0090_write_regs(state, 0x2c, cfg + 3, 6);
+	dib0090_write_regs(state, 0x3e, cfg + 9, 2);
+}
+
+static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
+{
+	state->bb_ramp = cfg;
+	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
+}
+
+static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
+{
+	state->bb_ramp = cfg;
+
+	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
+
+	dib0090_write_reg(state, 0x33, 0xffff);
+	dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
+	dib0090_write_regs(state, 0x35, cfg + 3, 4);
+}
+
+void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	/* reset the AGC */
+
+	if (state->config->use_pwm_agc) {
+#ifdef CONFIG_BAND_SBAND
+		if (state->current_band == BAND_SBAND) {
+			dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
+			dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
+		} else
+#endif
+#ifdef CONFIG_BAND_CBAND
+		if (state->current_band == BAND_CBAND) {
+			dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
+			dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+		} else
+#endif
+#ifdef CONFIG_BAND_VHF
+		if (state->current_band == BAND_VHF) {
+			dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
+			dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+		} else
+#endif
+		{
+			dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
+			dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+		}
+
+		if (state->rf_ramp[0] != 0)
+			dib0090_write_reg(state, 0x32, (3 << 11));
+		else
+			dib0090_write_reg(state, 0x32, (0 << 11));
+
+		dib0090_write_reg(state, 0x39, (1 << 10));
+	}
+}
+EXPORT_SYMBOL(dib0090_pwm_gain_reset);
+
+int dib0090_gain_control(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	enum frontend_tune_state *tune_state = &state->tune_state;
+	int ret = 10;
+
+	u16 wbd_val = 0;
+	u8 apply_gain_immediatly = 1;
+	s16 wbd_error = 0, adc_error = 0;
+
+	if (*tune_state == CT_AGC_START) {
+		state->agc_freeze = 0;
+		dib0090_write_reg(state, 0x04, 0x0);
+
+#ifdef CONFIG_BAND_SBAND
+		if (state->current_band == BAND_SBAND) {
+			dib0090_set_rframp(state, rf_ramp_sband);
+			dib0090_set_bbramp(state, bb_ramp_boost);
+		} else
+#endif
+#ifdef CONFIG_BAND_VHF
+		if (state->current_band == BAND_VHF) {
+			dib0090_set_rframp(state, rf_ramp_vhf);
+			dib0090_set_bbramp(state, bb_ramp_boost);
+		} else
+#endif
+#ifdef CONFIG_BAND_CBAND
+		if (state->current_band == BAND_CBAND) {
+			dib0090_set_rframp(state, rf_ramp_cband);
+			dib0090_set_bbramp(state, bb_ramp_boost);
+		} else
+#endif
+		{
+			dib0090_set_rframp(state, rf_ramp_uhf);
+			dib0090_set_bbramp(state, bb_ramp_boost);
+		}
+
+		dib0090_write_reg(state, 0x32, 0);
+		dib0090_write_reg(state, 0x39, 0);
+
+		dib0090_wbd_target(state, state->current_rf);
+
+		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
+		state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
+
+		*tune_state = CT_AGC_STEP_0;
+	} else if (!state->agc_freeze) {
+		s16 wbd;
+
+		int adc;
+		wbd_val = dib0090_read_reg(state, 0x1d);
+
+		/* read and calc the wbd power */
+		wbd = dib0090_wbd_to_db(state, wbd_val);
+		wbd_error = state->wbd_target - wbd;
+
+		if (*tune_state == CT_AGC_STEP_0) {
+			if (wbd_error < 0 && state->rf_gain_limit > 0) {
+#ifdef CONFIG_BAND_CBAND
+				/* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
+				u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
+				if (state->current_band == BAND_CBAND && ltg2) {
+					ltg2 >>= 1;
+					state->rf_lt_def &= ltg2 << 10;	/* reduce in 3 steps from 7 to 0 */
+				}
+#endif
+			} else {
+				state->agc_step = 0;
+				*tune_state = CT_AGC_STEP_1;
+			}
+		} else {
+			/* calc the adc power */
+			adc = state->config->get_adc_power(fe);
+			adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;	/* included in [0:-700] */
+
+			adc_error = (s16) (((s32) ADC_TARGET) - adc);
+#ifdef CONFIG_STANDARD_DAB
+			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
+				adc_error += 130;
+#endif
+#ifdef CONFIG_STANDARD_DVBT
+			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
+			    (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
+				adc_error += 60;
+#endif
+#ifdef CONFIG_SYS_ISDBT
+			if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
+											       0)
+											      &&
+											      ((state->fe->dtv_property_cache.layer[0].modulation ==
+												QAM_64)
+											       || (state->fe->dtv_property_cache.layer[0].
+												   modulation == QAM_16)))
+											     ||
+											     ((state->fe->dtv_property_cache.layer[1].segment_count >
+											       0)
+											      &&
+											      ((state->fe->dtv_property_cache.layer[1].modulation ==
+												QAM_64)
+											       || (state->fe->dtv_property_cache.layer[1].
+												   modulation == QAM_16)))
+											     ||
+											     ((state->fe->dtv_property_cache.layer[2].segment_count >
+											       0)
+											      &&
+											      ((state->fe->dtv_property_cache.layer[2].modulation ==
+												QAM_64)
+											       || (state->fe->dtv_property_cache.layer[2].
+												   modulation == QAM_16)))
+			    )
+			    )
+				adc_error += 60;
+#endif
+
+			if (*tune_state == CT_AGC_STEP_1) {	/* quickly go to the correct range of the ADC power */
+				if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
+
+#ifdef CONFIG_STANDARD_DAB
+					if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
+						dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));	/* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
+						dib0090_write_reg(state, 0x04, 0x0);
+					} else
+#endif
+					{
+						dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
+						dib0090_write_reg(state, 0x04, 0x01);	/*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
+					}
+
+					*tune_state = CT_AGC_STOP;
+				}
+			} else {
+				/* everything higher than or equal to CT_AGC_STOP means tracking */
+				ret = 100;	/* 10ms interval */
+				apply_gain_immediatly = 0;
+			}
+		}
+#ifdef DEBUG_AGC
+		dprintk
+		    ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
+		     (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
+		     (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
+#endif
+	}
+
+	/* apply gain */
+	if (!state->agc_freeze)
+		dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
+	return ret;
+}
+EXPORT_SYMBOL(dib0090_gain_control);
+
+void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	if (rf)
+		*rf = state->gain[0];
+	if (bb)
+		*bb = state->gain[1];
+	if (rf_gain_limit)
+		*rf_gain_limit = state->rf_gain_limit;
+	if (rflt)
+		*rflt = (state->rf_lt_def >> 10) & 0x7;
+}
+EXPORT_SYMBOL(dib0090_get_current_gain);
+
+u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
+{
+	struct dib0090_state *st = tuner->tuner_priv;
+	return st->wbd_offset;
+}
+EXPORT_SYMBOL(dib0090_get_wbd_offset);
+
+static const u16 dib0090_defaults[] = {
+
+	25, 0x01,
+	0x0000,
+	0x99a0,
+	0x6008,
+	0x0000,
+	0x8acb,
+	0x0000,
+	0x0405,
+	0x0000,
+	0x0000,
+	0x0000,
+	0xb802,
+	0x0300,
+	0x2d12,
+	0xbac0,
+	0x7c00,
+	0xdbb9,
+	0x0954,
+	0x0743,
+	0x8000,
+	0x0001,
+	0x0040,
+	0x0100,
+	0x0000,
+	0xe910,
+	0x149e,
+
+	1, 0x1c,
+	0xff2d,
+
+	1, 0x39,
+	0x0000,
+
+	1, 0x1b,
+	EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL,
+	2, 0x1e,
+	0x07FF,
+	0x0007,
+
+	1, 0x24,
+	EN_UHF | EN_CRYSTAL,
+
+	2, 0x3c,
+	0x3ff,
+	0x111,
+	0
+};
+
+static int dib0090_reset(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	u16 l, r, *n;
+
+	dib0090_reset_digital(fe, state->config);
+	state->revision = dib0090_identify(fe);
+
+	/* Revision definition */
+	if (state->revision == 0xff)
+		return -EINVAL;
+#ifdef EFUSE
+	else if ((state->revision & 0x1f) >= 3)	/* Update the efuse : Only available for KROSUS > P1C */
+		dib0090_set_EFUSE(state);
+#endif
+
+#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
+	if (!(state->revision & 0x1))	/* it is P1B - reset is already done */
+		return 0;
+#endif
+
+	/* Upload the default values */
+	n = (u16 *) dib0090_defaults;
+	l = pgm_read_word(n++);
+	while (l) {
+		r = pgm_read_word(n++);
+		do {
+			/* DEBUG_TUNER */
+			/* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */
+			dib0090_write_reg(state, r, pgm_read_word(n++));
+			r++;
+		} while (--l);
+		l = pgm_read_word(n++);
+	}
+
+	/* Congigure in function of the crystal */
+	if (state->config->io.clock_khz >= 24000)
+		l = 1;
+	else
+		l = 2;
+	dib0090_write_reg(state, 0x14, l);
+	dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
+
+	state->reset = 3;	/* enable iq-offset-calibration and wbd-calibration when tuning next time */
+
+	return 0;
+}
+
+#define steps(u) (((u) > 15) ? ((u)-16) : (u))
+#define INTERN_WAIT 10
+static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+	int ret = INTERN_WAIT * 10;
+
+	switch (*tune_state) {
+	case CT_TUNER_STEP_2:
+		/* Turns to positive */
+		dib0090_write_reg(state, 0x1f, 0x7);
+		*tune_state = CT_TUNER_STEP_3;
+		break;
+
+	case CT_TUNER_STEP_3:
+		state->adc_diff = dib0090_read_reg(state, 0x1d);
+
+		/* Turns to negative */
+		dib0090_write_reg(state, 0x1f, 0x4);
+		*tune_state = CT_TUNER_STEP_4;
+		break;
+
+	case CT_TUNER_STEP_4:
+		state->adc_diff -= dib0090_read_reg(state, 0x1d);
+		*tune_state = CT_TUNER_STEP_5;
+		ret = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+struct dc_calibration {
+	uint8_t addr;
+	uint8_t offset;
+	uint8_t pga:1;
+	uint16_t bb1;
+	uint8_t i:1;
+};
+
+static const struct dc_calibration dc_table[] = {
+	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
+	{0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
+	{0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
+	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
+	{0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
+	{0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
+	{0},
+};
+
+static void dib0090_set_trim(struct dib0090_state *state)
+{
+	u16 *val;
+
+	if (state->dc->addr == 0x07)
+		val = &state->bb7;
+	else
+		val = &state->bb6;
+
+	*val &= ~(0x1f << state->dc->offset);
+	*val |= state->step << state->dc->offset;
+
+	dib0090_write_reg(state, state->dc->addr, *val);
+}
+
+static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+	int ret = 0;
+
+	switch (*tune_state) {
+
+	case CT_TUNER_START:
+		/* init */
+		dprintk("Internal DC calibration");
+
+		/* the LNA is off */
+		dib0090_write_reg(state, 0x24, 0x02ed);
+
+		/* force vcm2 = 0.8V */
+		state->bb6 = 0;
+		state->bb7 = 0x040d;
+
+		state->dc = dc_table;
+
+		*tune_state = CT_TUNER_STEP_0;
+
+		/* fall through */
+
+	case CT_TUNER_STEP_0:
+		dib0090_write_reg(state, 0x01, state->dc->bb1);
+		dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
+
+		state->step = 0;
+
+		state->min_adc_diff = 1023;
+
+		*tune_state = CT_TUNER_STEP_1;
+		ret = 50;
+		break;
+
+	case CT_TUNER_STEP_1:
+		dib0090_set_trim(state);
+
+		*tune_state = CT_TUNER_STEP_2;
+		break;
+
+	case CT_TUNER_STEP_2:
+	case CT_TUNER_STEP_3:
+	case CT_TUNER_STEP_4:
+		ret = dib0090_get_offset(state, tune_state);
+		break;
+
+	case CT_TUNER_STEP_5:	/* found an offset */
+		dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step);
+
+		/* first turn for this frequency */
+		if (state->step == 0) {
+			if (state->dc->pga && state->adc_diff < 0)
+				state->step = 0x10;
+			if (state->dc->pga == 0 && state->adc_diff > 0)
+				state->step = 0x10;
+		}
+
+		state->adc_diff = ABS(state->adc_diff);
+
+		if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) {	/* stop search when the delta to 0 is increasing */
+			state->step++;
+			state->min_adc_diff = state->adc_diff;
+			*tune_state = CT_TUNER_STEP_1;
+		} else {
+
+			/* the minimum was what we have seen in the step before */
+			state->step--;
+			dib0090_set_trim(state);
+
+			dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff,
+				state->step);
+
+			state->dc++;
+			if (state->dc->addr == 0)	/* done */
+				*tune_state = CT_TUNER_STEP_6;
+			else
+				*tune_state = CT_TUNER_STEP_0;
+
+		}
+		break;
+
+	case CT_TUNER_STEP_6:
+		dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
+		dib0090_write_reg(state, 0x1f, 0x7);
+		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
+		state->reset &= ~0x1;
+	default:
+		break;
+	}
+	return ret;
+}
+
+static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+	switch (*tune_state) {
+	case CT_TUNER_START:
+		/* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */
+		dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10));
+		dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff);
+
+		*tune_state = CT_TUNER_STEP_0;
+		return 90;	/* wait for the WBDMUX to switch and for the ADC to sample */
+	case CT_TUNER_STEP_0:
+		state->wbd_offset = dib0090_read_reg(state, 0x1d);
+		dprintk("WBD calibration offset = %d", state->wbd_offset);
+
+		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
+		state->reset &= ~0x2;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void dib0090_set_bandwidth(struct dib0090_state *state)
+{
+	u16 tmp;
+
+	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
+		tmp = (3 << 14);
+	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
+		tmp = (2 << 14);
+	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
+		tmp = (1 << 14);
+	else
+		tmp = (0 << 14);
+
+	state->bb_1_def &= 0x3fff;
+	state->bb_1_def |= tmp;
+
+	dib0090_write_reg(state, 0x01, state->bb_1_def);	/* be sure that we have the right bb-filter */
+}
+
+static const struct dib0090_pll dib0090_pll_table[] = {
+#ifdef CONFIG_BAND_CBAND
+	{56000, 0, 9, 48, 6},
+	{70000, 1, 9, 48, 6},
+	{87000, 0, 8, 32, 4},
+	{105000, 1, 8, 32, 4},
+	{115000, 0, 7, 24, 6},
+	{140000, 1, 7, 24, 6},
+	{170000, 0, 6, 16, 4},
+#endif
+#ifdef CONFIG_BAND_VHF
+	{200000, 1, 6, 16, 4},
+	{230000, 0, 5, 12, 6},
+	{280000, 1, 5, 12, 6},
+	{340000, 0, 4, 8, 4},
+	{380000, 1, 4, 8, 4},
+	{450000, 0, 3, 6, 6},
+#endif
+#ifdef CONFIG_BAND_UHF
+	{580000, 1, 3, 6, 6},
+	{700000, 0, 2, 4, 4},
+	{860000, 1, 2, 4, 4},
+#endif
+#ifdef CONFIG_BAND_LBAND
+	{1800000, 1, 0, 2, 4},
+#endif
+#ifdef CONFIG_BAND_SBAND
+	{2900000, 0, 14, 1, 4},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
+
+#ifdef CONFIG_BAND_CBAND
+	{184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+	{227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+	{380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_UHF
+	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table[] = {
+
+#ifdef CONFIG_BAND_CBAND
+	{170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_VHF
+	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+#endif
+#ifdef CONFIG_BAND_UHF
+	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+#define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
+static int dib0090_tune(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	const struct dib0090_tuning *tune = state->current_tune_table_index;
+	const struct dib0090_pll *pll = state->current_pll_table_index;
+	enum frontend_tune_state *tune_state = &state->tune_state;
+
+	u32 rf;
+	u16 lo4 = 0xe900, lo5, lo6, Den;
+	u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
+	u16 tmp, adc;
+	int8_t step_sign;
+	int ret = 10;		/* 1ms is the default delay most of the time */
+	u8 c, i;
+
+	state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
+	rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
+							BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf);
+	/* in any case we first need to do a reset if needed */
+	if (state->reset & 0x1)
+		return dib0090_dc_offset_calibration(state, tune_state);
+	else if (state->reset & 0x2)
+		return dib0090_wbd_calibration(state, tune_state);
+
+    /************************* VCO ***************************/
+	/* Default values for FG                                 */
+	/* from these are needed :                               */
+	/* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
+
+#ifdef CONFIG_SYS_ISDBT
+	if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+		rf += 850;
+#endif
+
+	if (state->current_rf != rf) {
+		state->tuner_is_tuned = 0;
+
+		tune = dib0090_tuning_table;
+
+		tmp = (state->revision >> 5) & 0x7;
+		if (tmp == 0x4 || tmp == 0x7) {
+			/* CBAND tuner version for VHF */
+			if (state->current_band == BAND_FM || state->current_band == BAND_VHF) {
+				/* Force CBAND */
+				state->current_band = BAND_CBAND;
+				tune = dib0090_tuning_table_fm_vhf_on_cband;
+			}
+		}
+
+		pll = dib0090_pll_table;
+		/* Look for the interval */
+		while (rf > tune->max_freq)
+			tune++;
+		while (rf > pll->max_freq)
+			pll++;
+		state->current_tune_table_index = tune;
+		state->current_pll_table_index = pll;
+	}
+
+	if (*tune_state == CT_TUNER_START) {
+
+		if (state->tuner_is_tuned == 0)
+			state->current_rf = 0;
+
+		if (state->current_rf != rf) {
+
+			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
+
+			/* external loop filter, otherwise:
+			 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
+			 * lo6 = 0x0e34 */
+			if (pll->vco_band)
+				lo5 = 0x049e;
+			else if (state->config->analog_output)
+				lo5 = 0x041d;
+			else
+				lo5 = 0x041c;
+
+			lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);	/* bit 15 is the split to the slave, we do not do it here */
+
+			if (!state->config->io.pll_int_loop_filt)
+				lo6 = 0xff28;
+			else
+				lo6 = (state->config->io.pll_int_loop_filt << 3);
+
+			VCOF_kHz = (pll->hfdiv * rf) * 2;
+
+			FREF = state->config->io.clock_khz;
+
+			FBDiv = (VCOF_kHz / pll->topresc / FREF);
+			Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
+
+			if (Rest < LPF)
+				Rest = 0;
+			else if (Rest < 2 * LPF)
+				Rest = 2 * LPF;
+			else if (Rest > (FREF - LPF)) {
+				Rest = 0;
+				FBDiv += 1;
+			} else if (Rest > (FREF - 2 * LPF))
+				Rest = FREF - 2 * LPF;
+			Rest = (Rest * 6528) / (FREF / 10);
+
+			Den = 1;
+
+			dprintk(" *****  ******* Rest value = %d", Rest);
+
+			if (Rest > 0) {
+				if (state->config->analog_output)
+					lo6 |= (1 << 2) | 2;
+				else
+					lo6 |= (1 << 2) | 1;
+				Den = 255;
+			}
+#ifdef CONFIG_BAND_SBAND
+			if (state->current_band == BAND_SBAND)
+				lo6 &= 0xfffb;
+#endif
+
+			dib0090_write_reg(state, 0x15, (u16) FBDiv);
+
+			dib0090_write_reg(state, 0x16, (Den << 8) | 1);
+
+			dib0090_write_reg(state, 0x17, (u16) Rest);
+
+			dib0090_write_reg(state, 0x19, lo5);
+
+			dib0090_write_reg(state, 0x1c, lo6);
+
+			lo6 = tune->tuner_enable;
+			if (state->config->analog_output)
+				lo6 = (lo6 & 0xff9f) | 0x2;
+
+			dib0090_write_reg(state, 0x24, lo6 | EN_LO
+#ifdef CONFIG_DIB0090_USE_PWM_AGC
+					  | state->config->use_pwm_agc * EN_CRYSTAL
+#endif
+			    );
+
+			state->current_rf = rf;
+
+			/* prepare a complete captrim */
+			state->step = state->captrim = state->fcaptrim = 64;
+
+		} else {	/* we are already tuned to this frequency - the configuration is correct  */
+
+			/* do a minimal captrim even if the frequency has not changed */
+			state->step = 4;
+			state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
+		}
+		state->adc_diff = 3000;
+
+		dib0090_write_reg(state, 0x10, 0x2B1);
+
+		dib0090_write_reg(state, 0x1e, 0x0032);
+
+		ret = 20;
+		*tune_state = CT_TUNER_STEP_1;
+	} else if (*tune_state == CT_TUNER_STEP_0) {
+		/* nothing */
+	} else if (*tune_state == CT_TUNER_STEP_1) {
+		state->step /= 2;
+		dib0090_write_reg(state, 0x18, lo4 | state->captrim);
+		*tune_state = CT_TUNER_STEP_2;
+	} else if (*tune_state == CT_TUNER_STEP_2) {
+
+		adc = dib0090_read_reg(state, 0x1d);
+		dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc,
+			(u32) (adc) * (u32) 1800 / (u32) 1024);
+
+		if (adc >= 400) {
+			adc -= 400;
+			step_sign = -1;
+		} else {
+			adc = 400 - adc;
+			step_sign = 1;
+		}
+
+		if (adc < state->adc_diff) {
+			dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
+			state->adc_diff = adc;
+			state->fcaptrim = state->captrim;
+
+		}
+
+		state->captrim += step_sign * state->step;
+		if (state->step >= 1)
+			*tune_state = CT_TUNER_STEP_1;
+		else
+			*tune_state = CT_TUNER_STEP_3;
+
+		ret = 15;
+	} else if (*tune_state == CT_TUNER_STEP_3) {
+		/*write the final cptrim config */
+		dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
+
+#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY
+		state->memory[state->memory_index].cap = state->fcaptrim;
+#endif
+
+		*tune_state = CT_TUNER_STEP_4;
+	} else if (*tune_state == CT_TUNER_STEP_4) {
+		dib0090_write_reg(state, 0x1e, 0x07ff);
+
+		dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim);
+		dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code);
+		dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band);
+		dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf);
+		dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz);
+		dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
+		dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17),
+			(u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3);
+
+		c = 4;
+		i = 3;
+#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
+		if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) {
+			c = 2;
+			i = 2;
+		}
+#endif
+		dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD
+#ifdef CONFIG_DIB0090_USE_PWM_AGC
+									| (state->config->use_pwm_agc << 1)
+#endif
+				  ));
+		dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0));
+		dib0090_write_reg(state, 0x0c, tune->v2i);
+		dib0090_write_reg(state, 0x0d, tune->mix);
+		dib0090_write_reg(state, 0x0e, tune->load);
+
+		*tune_state = CT_TUNER_STEP_5;
+	} else if (*tune_state == CT_TUNER_STEP_5) {
+
+		/* initialize the lt gain register */
+		state->rf_lt_def = 0x7c00;
+		dib0090_write_reg(state, 0x0f, state->rf_lt_def);
+
+		dib0090_set_bandwidth(state);
+		state->tuner_is_tuned = 1;
+		*tune_state = CT_TUNER_STOP;
+	} else
+		ret = FE_CALLBACK_TIME_NEVER;
+	return ret;
+}
+
+static int dib0090_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	return state->tune_state;
+}
+EXPORT_SYMBOL(dib0090_get_tune_state);
+
+int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	state->tune_state = tune_state;
+	return 0;
+}
+EXPORT_SYMBOL(dib0090_set_tune_state);
+
+static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	*frequency = 1000 * state->current_rf;
+	return 0;
+}
+
+static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	uint32_t ret;
+
+	state->tune_state = CT_TUNER_START;
+
+	do {
+		ret = dib0090_tune(fe);
+		if (ret != FE_CALLBACK_TIME_NEVER)
+			msleep(ret / 10);
+		else
+			break;
+	} while (state->tune_state != CT_TUNER_STOP);
+
+	return 0;
+}
+
+static const struct dvb_tuner_ops dib0090_ops = {
+	.info = {
+		 .name = "DiBcom DiB0090",
+		 .frequency_min = 45000000,
+		 .frequency_max = 860000000,
+		 .frequency_step = 1000,
+		 },
+	.release = dib0090_release,
+
+	.init = dib0090_wakeup,
+	.sleep = dib0090_sleep,
+	.set_params = dib0090_set_params,
+	.get_frequency = dib0090_get_frequency,
+};
+
+struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
+{
+	struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
+	if (st == NULL)
+		return NULL;
+
+	st->config = config;
+	st->i2c = i2c;
+	st->fe = fe;
+	fe->tuner_priv = st;
+
+	if (dib0090_reset(fe) != 0)
+		goto free_mem;
+
+	printk(KERN_INFO "DiB0090: successfully identified\n");
+	memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
+
+	return fe;
+ free_mem:
+	kfree(st);
+	fe->tuner_priv = NULL;
+	return NULL;
+}
+EXPORT_SYMBOL(dib0090_register);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0090.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib0090.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib0090.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,108 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ */
+#ifndef DIB0090_H
+#define DIB0090_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
+
+struct dib0090_io_config {
+	u32 clock_khz;
+
+	u8 pll_bypass:1;
+	u8 pll_range:1;
+	u8 pll_prediv:6;
+	u8 pll_loopdiv:6;
+
+	u8 adc_clock_ratio;	/* valid is 8, 7 ,6 */
+	u16 pll_int_loop_filt;
+};
+
+struct dib0090_config {
+	struct dib0090_io_config io;
+	int (*reset) (struct dvb_frontend *, int);
+	int (*sleep) (struct dvb_frontend *, int);
+
+	/*  offset in kHz */
+	int freq_offset_khz_uhf;
+	int freq_offset_khz_vhf;
+
+	int (*get_adc_power) (struct dvb_frontend *);
+
+	u8 clkouttobamse:1;	/* activate or deactivate clock output */
+	u8 analog_output;
+
+	u8 i2c_address;
+	/* add drives and other things if necessary */
+	u16 wbd_vhf_offset;
+	u16 wbd_cband_offset;
+	u8 use_pwm_agc;
+	u8 clkoutdrive;
+};
+
+#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
+extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
+extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
+extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
+extern int dib0090_gain_control(struct dvb_frontend *fe);
+extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
+extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
+extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
+#else
+static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
+
+static inline int dib0090_gain_control(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return CT_DONE;
+}
+
+static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib3000mb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib3000mb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib3000mb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib3000mb.c	2010-02-24 13:52:17.000000000 -0500
@@ -154,7 +154,7 @@ static int dib3000mb_set_frontend(struct
 			case BANDWIDTH_AUTO:
 				return -EOPNOTSUPP;
 			default:
-				err("unkown bandwidth value.");
+				err("unknown bandwidth value.");
 				return -EINVAL;
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib7000p.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib7000p.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.c	2010-02-24 13:52:17.000000000 -0500
@@ -108,7 +108,7 @@ static int dib7000p_set_output_mode(stru
 
 	outreg = 0;
 	fifo_threshold = 1792;
-	smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
+	smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
 
 	dprintk( "setting output mode for demod %p to %d",
 			&state->demod, mode);
@@ -162,18 +162,19 @@ static int dib7000p_set_diversity_in(str
 	if (state->div_force_off) {
 		dprintk( "diversity combination deactivated - forced by COFDM parameters");
 		onoff = 0;
-	}
+		dib7000p_write_word(state, 207, 0);
+	} else
+		dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+
 	state->div_state = (u8)onoff;
 
 	if (onoff) {
 		dib7000p_write_word(state, 204, 6);
 		dib7000p_write_word(state, 205, 16);
 		/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-		dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 	} else {
 		dib7000p_write_word(state, 204, 1);
 		dib7000p_write_word(state, 205, 0);
-		dib7000p_write_word(state, 207, 0);
 	}
 
 	return 0;
@@ -1188,7 +1189,7 @@ static int dib7000p_read_status(struct d
 		*stat |= FE_HAS_VITERBI;
 	if (lock & 0x0010)
 		*stat |= FE_HAS_SYNC;
-	if (lock & 0x0008)
+    if ((lock & 0x0038) == 0x38)
 		*stat |= FE_HAS_LOCK;
 
 	return 0;
@@ -1302,6 +1303,24 @@ struct i2c_adapter * dib7000p_get_i2c_ma
 }
 EXPORT_SYMBOL(dib7000p_get_i2c_master);
 
+int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+    struct dib7000p_state *state = fe->demodulator_priv;
+    u16 val = dib7000p_read_word(state, 235) & 0xffef;
+    val |= (onoff & 0x1) << 4;
+    dprintk("PID filter enabled %d", onoff);
+    return dib7000p_write_word(state, 235, val);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
+
+int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+    struct dib7000p_state *state = fe->demodulator_priv;
+    dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
+    return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter);
+
 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
 {
 	struct dib7000p_state st = { .i2c_adap = i2c };
@@ -1314,8 +1333,10 @@ int dib7000p_i2c_enumeration(struct i2c_
 		/* designated i2c address */
 		new_addr          = (0x40 + k) << 1;
 		st.i2c_addr = new_addr;
+		dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
 		if (dib7000p_identify(&st) != 0) {
 			st.i2c_addr = default_addr;
+			dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */
 			if (dib7000p_identify(&st) != 0) {
 				dprintk("DiB7000P #%d: not identified\n", k);
 				return -EIO;
@@ -1372,6 +1393,8 @@ struct dvb_frontend * dib7000p_attach(st
 	demod->demodulator_priv = st;
 	memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
 
+    dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
+
 	if (dib7000p_identify(st) != 0)
 		goto error;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib7000p.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib7000p.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib7000p.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,8 @@ extern int dib7000p_i2c_enumeration(stru
 extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
 extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
 #else
 static inline
 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
@@ -95,6 +97,17 @@ static inline int dib7000pc_detection(st
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+    printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+    return -ENODEV;
+}
+
+static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
+{
+    printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+    return -ENODEV;
+}
 #endif
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib8000.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib8000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,18 +28,6 @@ MODULE_PARM_DESC(debug, "turn on debuggi
 
 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
 
-enum frontend_tune_state {
-	CT_AGC_START = 20,
-	CT_AGC_STEP_0,
-	CT_AGC_STEP_1,
-	CT_AGC_STEP_2,
-	CT_AGC_STEP_3,
-	CT_AGC_STEP_4,
-	CT_AGC_STOP,
-
-	CT_DEMOD_START = 30,
-};
-
 #define FE_STATUS_TUNE_FAILED 0
 
 struct i2c_device {
@@ -133,104 +121,104 @@ static int dib8000_write_word(struct dib
 	return dib8000_i2c_write16(&state->i2c, reg, val);
 }
 
-const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
+static const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
 	(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
 	    (920 << 5) | 0x09
 };
 
-const int16_t coeff_2k_sb_1seg[8] = {
+static const int16_t coeff_2k_sb_1seg[8] = {
 	(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
 };
 
-const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
+static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
 	(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
 	    (-931 << 5) | 0x0f
 };
 
-const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
+static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
 	(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
 	    (982 << 5) | 0x0c
 };
 
-const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
+static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
 	(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
 	    (-720 << 5) | 0x0d
 };
 
-const int16_t coeff_2k_sb_3seg[8] = {
+static const int16_t coeff_2k_sb_3seg[8] = {
 	(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
 	    (-610 << 5) | 0x0a
 };
 
-const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
+static const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
 	(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
 	    (-922 << 5) | 0x0d
 };
 
-const int16_t coeff_4k_sb_1seg[8] = {
+static const int16_t coeff_4k_sb_1seg[8] = {
 	(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
 	    (-655 << 5) | 0x0a
 };
 
-const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
+static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
 	(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
 	    (-958 << 5) | 0x13
 };
 
-const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
+static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
 	(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
 	    (-568 << 5) | 0x0f
 };
 
-const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
+static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
 	(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
 	    (-848 << 5) | 0x13
 };
 
-const int16_t coeff_4k_sb_3seg[8] = {
+static const int16_t coeff_4k_sb_3seg[8] = {
 	(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
 	    (-869 << 5) | 0x13
 };
 
-const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
+static const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
 	(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
 	    (-598 << 5) | 0x10
 };
 
-const int16_t coeff_8k_sb_1seg[8] = {
+static const int16_t coeff_8k_sb_1seg[8] = {
 	(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
 	    (585 << 5) | 0x0f
 };
 
-const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
+static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
 	(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
 	    (0 << 5) | 0x14
 };
 
-const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
+static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
 	(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
 	    (-877 << 5) | 0x15
 };
 
-const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
+static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
 	(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
 	    (-921 << 5) | 0x14
 };
 
-const int16_t coeff_8k_sb_3seg[8] = {
+static const int16_t coeff_8k_sb_3seg[8] = {
 	(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
 	    (690 << 5) | 0x14
 };
 
-const int16_t ana_fe_coeff_3seg[24] = {
+static const int16_t ana_fe_coeff_3seg[24] = {
 	81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
 };
 
-const int16_t ana_fe_coeff_1seg[24] = {
+static const int16_t ana_fe_coeff_1seg[24] = {
 	249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
 };
 
-const int16_t ana_fe_coeff_13seg[24] = {
+static const int16_t ana_fe_coeff_13seg[24] = {
 	396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
 };
 
@@ -852,6 +840,14 @@ static int dib8000_set_agc_config(struct
 	return 0;
 }
 
+void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	dib8000_set_adc_state(state, DIBX000_ADC_ON);
+	dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
+}
+EXPORT_SYMBOL(dib8000_pwm_agc_reset);
+
 static int dib8000_agc_soft_split(struct dib8000_state *state)
 {
 	u16 agc, split_offset;
@@ -939,6 +935,32 @@ static int dib8000_agc_startup(struct dv
 
 }
 
+static const int32_t lut_1000ln_mant[] =
+{
+	908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
+};
+
+int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode)
+{
+    struct dib8000_state *state = fe->demodulator_priv;
+    uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0;
+    int32_t val;
+
+    val = dib8000_read32(state, 384);
+    /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */
+    if (mode) {
+	tmp_val = val;
+	while (tmp_val >>= 1)
+		exp++;
+	mant = (val * 1000 / (1<<exp));
+	ix = (uint8_t)((mant-1000)/100); /* index of the LUT */
+	val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */
+	val = (val*256)/1000;
+    }
+    return val;
+}
+EXPORT_SYMBOL(dib8000_get_adc_power);
+
 static void dib8000_update_timf(struct dib8000_state *state)
 {
 	u32 timf = state->timf = dib8000_read32(state, 435);
@@ -954,7 +976,7 @@ static void dib8000_set_channel(struct d
 	u8 guard, crate, constellation, timeI;
 	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
 	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
-	const s16 *ncoeff, *ana_fe;
+	const s16 *ncoeff = NULL, *ana_fe;
 	u16 tmcc_pow = 0;
 	u16 coff_pow = 0x2800;
 	u16 init_prbs = 0xfff;
@@ -1401,10 +1423,9 @@ static void dib8000_set_channel(struct d
 			}
 			break;
 		}
-	}
-	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
 		for (i = 0; i < 8; i++)
 			dib8000_write_word(state, 343 + i, ncoeff[i]);
+	}
 
 	// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
 	dib8000_write_word(state, 351,
@@ -1854,6 +1875,24 @@ static int dib8000_sleep(struct dvb_fron
 	}
 }
 
+enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	return state->tune_state;
+}
+EXPORT_SYMBOL(dib8000_get_tune_state);
+
+int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	state->tune_state = tune_state;
+	return 0;
+}
+EXPORT_SYMBOL(dib8000_set_tune_state);
+
+
+
+
 static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
 	struct dib8000_state *state = fe->demodulator_priv;
@@ -2043,29 +2082,31 @@ static int dib8000_read_status(struct dv
 
 	*stat = 0;
 
-	if ((lock >> 14) & 1)	// AGC
+	if ((lock >> 13) & 1)
 		*stat |= FE_HAS_SIGNAL;
 
-	if ((lock >> 8) & 1)	// Equal
+	if ((lock >> 8) & 1) /* Equal */
 		*stat |= FE_HAS_CARRIER;
 
-	if ((lock >> 3) & 1)	// TMCC_SYNC
+	if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */
 		*stat |= FE_HAS_SYNC;
 
-	if ((lock >> 5) & 7)	// FEC MPEG
+	if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */
 		*stat |= FE_HAS_LOCK;
 
-	lock = dib8000_read_word(state, 554);	// Viterbi Layer A
-	if (lock & 0x01)
-		*stat |= FE_HAS_VITERBI;
+	if ((lock >> 12) & 1) {
+		lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
+		if (lock & 0x01)
+			*stat |= FE_HAS_VITERBI;
 
-	lock = dib8000_read_word(state, 555);	// Viterbi Layer B
-	if (lock & 0x01)
-		*stat |= FE_HAS_VITERBI;
+		lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
+		if (lock & 0x01)
+			*stat |= FE_HAS_VITERBI;
 
-	lock = dib8000_read_word(state, 556);	// Viterbi Layer C
-	if (lock & 0x01)
-		*stat |= FE_HAS_VITERBI;
+		lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
+		if (lock & 0x01)
+			*stat |= FE_HAS_VITERBI;
+	}
 
 	return 0;
 }
@@ -2121,7 +2162,7 @@ static int dib8000_read_snr(struct dvb_f
 	else
 		result -= intlog10(2) * 10 * noise_exp - 100;
 
-	*snr = result / (1 << 24);
+	*snr = result / ((1 << 24) / 10);
 	return 0;
 }
 
@@ -2195,6 +2236,25 @@ struct i2c_adapter *dib8000_get_i2c_mast
 
 EXPORT_SYMBOL(dib8000_get_i2c_master);
 
+int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+    u16 val = dib8000_read_word(st, 299) & 0xffef;
+    val |= (onoff & 0x1) << 4;
+
+    dprintk("pid filter enabled %d", onoff);
+    return dib8000_write_word(st, 299, val);
+}
+EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
+
+int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+    dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
+    return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib8000_pid_filter);
+
 static const struct dvb_frontend_ops dib8000_ops = {
 	.info = {
 		 .name = "DiBcom 8000 ISDB-T",
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib8000.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dib8000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dib8000.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,12 @@ extern int dib8000_i2c_enumeration(struc
 
 extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
+extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
+extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
+extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
+extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
 #else
 static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
 {
@@ -57,23 +63,53 @@ static inline struct i2c_adapter *dib800
 	return NULL;
 }
 
-int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
 
-int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
 
-int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return CT_SHUTDOWN;
+}
+static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
 #endif
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dibx000_common.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dibx000_common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
 
 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
 {
@@ -25,7 +25,7 @@ static int dibx000_i2c_select_interface(
 					enum dibx000_i2c_interface intf)
 {
 	if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
-		dprintk("selecting interface: %d\n", intf);
+		dprintk("selecting interface: %d", intf);
 		mst->selected_interface = intf;
 		return dibx000_write_word(mst, mst->base_reg + 4, intf);
 	}
@@ -171,9 +171,18 @@ void dibx000_exit_i2c_master(struct dibx
 {
 	i2c_del_adapter(&mst->gated_tuner_i2c_adap);
 }
-
 EXPORT_SYMBOL(dibx000_exit_i2c_master);
 
+
+u32 systime()
+{
+    struct timespec t;
+
+    t = current_kernel_time();
+    return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
+}
+EXPORT_SYMBOL(systime);
+
 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
 MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dibx000_common.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/dibx000_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/dibx000_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,13 +36,17 @@ extern struct i2c_adapter *dibx000_get_i
 extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
 extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
 
+extern u32 systime(void);
+
 #define BAND_LBAND 0x01
 #define BAND_UHF   0x02
 #define BAND_VHF   0x04
 #define BAND_SBAND 0x08
-#define BAND_FM	   0x10
+#define BAND_FM    0x10
+#define BAND_CBAND 0x20
 
-#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \
+#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
+									(freq_kHz) <= 115000 ? BAND_FM : \
 									(freq_kHz) <= 250000 ? BAND_VHF : \
 									(freq_kHz) <= 863000 ? BAND_UHF : \
 									(freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
@@ -149,4 +153,67 @@ enum dibx000_adc_states {
 #define OUTMODE_MPEG2_FIFO          5
 #define OUTMODE_ANALOG_ADC          6
 
+enum frontend_tune_state {
+    CT_TUNER_START = 10,
+    CT_TUNER_STEP_0,
+    CT_TUNER_STEP_1,
+    CT_TUNER_STEP_2,
+    CT_TUNER_STEP_3,
+    CT_TUNER_STEP_4,
+    CT_TUNER_STEP_5,
+    CT_TUNER_STEP_6,
+    CT_TUNER_STEP_7,
+    CT_TUNER_STOP,
+
+    CT_AGC_START = 20,
+    CT_AGC_STEP_0,
+    CT_AGC_STEP_1,
+    CT_AGC_STEP_2,
+    CT_AGC_STEP_3,
+    CT_AGC_STEP_4,
+    CT_AGC_STOP,
+
+	CT_DEMOD_START = 30,
+    CT_DEMOD_STEP_1,
+    CT_DEMOD_STEP_2,
+    CT_DEMOD_STEP_3,
+    CT_DEMOD_STEP_4,
+    CT_DEMOD_STEP_5,
+    CT_DEMOD_STEP_6,
+    CT_DEMOD_STEP_7,
+    CT_DEMOD_STEP_8,
+    CT_DEMOD_STEP_9,
+    CT_DEMOD_STEP_10,
+    CT_DEMOD_SEARCH_NEXT = 41,
+    CT_DEMOD_STEP_LOCKED,
+    CT_DEMOD_STOP,
+
+    CT_DONE = 100,
+    CT_SHUTDOWN,
+
+};
+
+struct dvb_frontend_parametersContext {
+#define CHANNEL_STATUS_PARAMETERS_UNKNOWN   0x01
+#define CHANNEL_STATUS_PARAMETERS_SET       0x02
+    u8 status;
+    u32 tune_time_estimation[2];
+    s32 tps_available;
+    u16 tps[9];
+};
+
+#define FE_STATUS_TUNE_FAILED          0
+#define FE_STATUS_TUNE_TIMED_OUT      -1
+#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
+#define FE_STATUS_TUNE_PENDING        -3
+#define FE_STATUS_STD_SUCCESS         -4
+#define FE_STATUS_FFT_SUCCESS         -5
+#define FE_STATUS_DEMOD_SUCCESS       -6
+#define FE_STATUS_LOCKED              -7
+#define FE_STATUS_DATA_LOCKED         -8
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
+#define ABS(x) ((x < 0) ? (-x) : (x))
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/drx397xD.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/drx397xD.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 13:57:48.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 12:04:57.000000000 -0400
@@ -81,7 +81,7 @@ static struct {
 #include "drx397xD_fw.h"
 };
 
-/* use only with writer lock aquired */
+/* use only with writer lock acquired */
 static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
 {
 	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ds3000.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ds3000.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ds3000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ds3000.c	2013-05-03 12:04:39.000000000 -0400
@@ -0,0 +1,1365 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.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/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "ds3000.h"
+
+static int debug;
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(args); \
+	} while (0)
+
+/*(DEBLOBBED)*/
+
+#define DS3000_SAMPLE_RATE 96000 /* in kHz */
+#define DS3000_XTAL_FREQ   27000 /* in kHz */
+
+/* Register values to initialise the demod in DVB-S mode */
+static u8 ds3000_dvbs_init_tab[] = {
+	0x23, 0x05,
+	0x08, 0x03,
+	0x0c, 0x00,
+	0x21, 0x54,
+	0x25, 0x82,
+	0x27, 0x31,
+	0x30, 0x08,
+	0x31, 0x40,
+	0x32, 0x32,
+	0x33, 0x35,
+	0x35, 0xff,
+	0x3a, 0x00,
+	0x37, 0x10,
+	0x38, 0x10,
+	0x39, 0x02,
+	0x42, 0x60,
+	0x4a, 0x40,
+	0x4b, 0x04,
+	0x4d, 0x91,
+	0x5d, 0xc8,
+	0x50, 0x77,
+	0x51, 0x77,
+	0x52, 0x36,
+	0x53, 0x36,
+	0x56, 0x01,
+	0x63, 0x43,
+	0x64, 0x30,
+	0x65, 0x40,
+	0x68, 0x26,
+	0x69, 0x4c,
+	0x70, 0x20,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x40,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x60,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x80,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0xa0,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x1f,
+	0x76, 0x00,
+	0x77, 0xd1,
+	0x78, 0x0c,
+	0x79, 0x80,
+	0x7f, 0x04,
+	0x7c, 0x00,
+	0x80, 0x86,
+	0x81, 0xa6,
+	0x85, 0x04,
+	0xcd, 0xf4,
+	0x90, 0x33,
+	0xa0, 0x44,
+	0xc0, 0x18,
+	0xc3, 0x10,
+	0xc4, 0x08,
+	0xc5, 0x80,
+	0xc6, 0x80,
+	0xc7, 0x0a,
+	0xc8, 0x1a,
+	0xc9, 0x80,
+	0xfe, 0x92,
+	0xe0, 0xf8,
+	0xe6, 0x8b,
+	0xd0, 0x40,
+	0xf8, 0x20,
+	0xfa, 0x0f,
+	0xfd, 0x20,
+	0xad, 0x20,
+	0xae, 0x07,
+	0xb8, 0x00,
+};
+
+/* Register values to initialise the demod in DVB-S2 mode */
+static u8 ds3000_dvbs2_init_tab[] = {
+	0x23, 0x0f,
+	0x08, 0x07,
+	0x0c, 0x00,
+	0x21, 0x54,
+	0x25, 0x82,
+	0x27, 0x31,
+	0x30, 0x08,
+	0x31, 0x32,
+	0x32, 0x32,
+	0x33, 0x35,
+	0x35, 0xff,
+	0x3a, 0x00,
+	0x37, 0x10,
+	0x38, 0x10,
+	0x39, 0x02,
+	0x42, 0x60,
+	0x4a, 0x80,
+	0x4b, 0x04,
+	0x4d, 0x81,
+	0x5d, 0x88,
+	0x50, 0x36,
+	0x51, 0x36,
+	0x52, 0x36,
+	0x53, 0x36,
+	0x63, 0x60,
+	0x64, 0x10,
+	0x65, 0x10,
+	0x68, 0x04,
+	0x69, 0x29,
+	0x70, 0x20,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x40,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x60,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x80,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0xa0,
+	0x71, 0x70,
+	0x72, 0x04,
+	0x73, 0x00,
+	0x70, 0x1f,
+	0xa0, 0x44,
+	0xc0, 0x08,
+	0xc1, 0x10,
+	0xc2, 0x08,
+	0xc3, 0x10,
+	0xc4, 0x08,
+	0xc5, 0xf0,
+	0xc6, 0xf0,
+	0xc7, 0x0a,
+	0xc8, 0x1a,
+	0xc9, 0x80,
+	0xca, 0x23,
+	0xcb, 0x24,
+	0xce, 0x74,
+	0x90, 0x03,
+	0x76, 0x80,
+	0x77, 0x42,
+	0x78, 0x0a,
+	0x79, 0x80,
+	0xad, 0x40,
+	0xae, 0x07,
+	0x7f, 0xd4,
+	0x7c, 0x00,
+	0x80, 0xa8,
+	0x81, 0xda,
+	0x7c, 0x01,
+	0x80, 0xda,
+	0x81, 0xec,
+	0x7c, 0x02,
+	0x80, 0xca,
+	0x81, 0xeb,
+	0x7c, 0x03,
+	0x80, 0xba,
+	0x81, 0xdb,
+	0x85, 0x08,
+	0x86, 0x00,
+	0x87, 0x02,
+	0x89, 0x80,
+	0x8b, 0x44,
+	0x8c, 0xaa,
+	0x8a, 0x10,
+	0xba, 0x00,
+	0xf5, 0x04,
+	0xfe, 0x44,
+	0xd2, 0x32,
+	0xb8, 0x00,
+};
+
+/* DS3000 doesn't need some parameters as input and auto-detects them */
+/* save input from the application of those parameters */
+struct ds3000_tuning {
+	u32 frequency;
+	u32 symbol_rate;
+	fe_spectral_inversion_t inversion;
+	enum fe_code_rate fec;
+
+	/* input values */
+	u8 inversion_val;
+	fe_modulation_t delivery;
+	u8 rolloff;
+};
+
+struct ds3000_state {
+	struct i2c_adapter *i2c;
+	const struct ds3000_config *config;
+
+	struct dvb_frontend frontend;
+
+	struct ds3000_tuning dcur;
+	struct ds3000_tuning dnxt;
+
+	u8 skip_fw_load;
+
+	/* previous uncorrected block counter for DVB-S2 */
+	u16 prevUCBS2;
+};
+
+static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .addr = state->config->demod_address,
+		.flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1) {
+		printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
+			 " value == 0x%02x)\n", __func__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .addr = 0x60,
+		.flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+	ds3000_writereg(state, 0x03, 0x11);
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1) {
+		printk("%s: writereg error(err == %i, reg == 0x%02x,"
+			 " value == 0x%02x)\n", __func__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+/* I2C write for 8k firmware load */
+static int ds3000_writeFW(struct ds3000_state *state, int reg,
+				const u8 *data, u16 len)
+{
+	int i, ret = -EREMOTEIO;
+	struct i2c_msg msg;
+	u8 *buf;
+
+	buf = kmalloc(3, GFP_KERNEL);
+	if (buf == NULL) {
+		printk(KERN_ERR "Unable to kmalloc\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	*(buf) = reg;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.buf = buf;
+	msg.len = 3;
+
+	for (i = 0; i < len; i += 2) {
+		memcpy(buf + 1, data + i, 2);
+
+		dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
+
+		ret = i2c_transfer(state->i2c, &msg, 1);
+		if (ret != 1) {
+			printk(KERN_ERR "%s: write error(err == %i, "
+				"reg == 0x%02x\n", __func__, ret, reg);
+			ret = -EREMOTEIO;
+		}
+	}
+
+error:
+	kfree(buf);
+
+	return ret;
+}
+
+static int ds3000_readreg(struct ds3000_state *state, u8 reg)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{
+			.addr = state->config->demod_address,
+			.flags = 0,
+			.buf = b0,
+			.len = 1
+		}, {
+			.addr = state->config->demod_address,
+			.flags = I2C_M_RD,
+			.buf = b1,
+			.len = 1
+		}
+	};
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2) {
+		printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+		return ret;
+	}
+
+	dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+	return b1[0];
+}
+
+static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x60,
+			.flags = 0,
+			.buf = b0,
+			.len = 1
+		}, {
+			.addr = 0x60,
+			.flags = I2C_M_RD,
+			.buf = b1,
+			.len = 1
+		}
+	};
+
+	ds3000_writereg(state, 0x03, 0x12);
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2) {
+		printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+		return ret;
+	}
+
+	dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+	return b1[0];
+}
+
+static int ds3000_set_inversion(struct ds3000_state *state,
+					fe_spectral_inversion_t inversion)
+{
+	dprintk("%s(%d)\n", __func__, inversion);
+
+	switch (inversion) {
+	case INVERSION_OFF:
+	case INVERSION_ON:
+	case INVERSION_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	state->dnxt.inversion = inversion;
+
+	return 0;
+}
+
+static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
+{
+	int ret = 0;
+
+	dprintk("%s()\n", __func__);
+
+	dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
+
+	/*  check if symbol rate is within limits */
+	if ((state->dnxt.symbol_rate >
+				state->frontend.ops.info.symbol_rate_max) ||
+	    (state->dnxt.symbol_rate <
+				state->frontend.ops.info.symbol_rate_min))
+		ret = -EOPNOTSUPP;
+
+	state->dnxt.symbol_rate = rate;
+
+	return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+					const struct firmware *fw);
+
+static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	const struct firmware *fw;
+	int ret = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (ds3000_readreg(state, 0xb2) <= 0)
+		return ret;
+
+	if (state->skip_fw_load)
+		return 0;
+	/* Load firmware */
+	/* request the firmware, this will block until someone uploads it */
+	printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
+				"/*(DEBLOBBED)*/");
+	ret = reject_firmware(&fw, "/*(DEBLOBBED)*/",
+				state->i2c->dev.parent);
+	printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+	if (ret) {
+		printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
+				"found?)\n", __func__);
+		return ret;
+	}
+
+	/* Make sure we don't recurse back through here during loading */
+	state->skip_fw_load = 1;
+
+	ret = ds3000_load_firmware(fe, fw);
+	if (ret)
+		printk("%s: Writing firmware to device failed\n", __func__);
+
+	release_firmware(fw);
+
+	dprintk("%s: Firmware upload %s\n", __func__,
+			ret == 0 ? "complete" : "failed");
+
+	/* Ensure firmware is always loaded if required */
+	state->skip_fw_load = 0;
+
+	return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+					const struct firmware *fw)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+
+	dprintk("%s\n", __func__);
+	dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+			fw->size,
+			fw->data[0],
+			fw->data[1],
+			fw->data[fw->size - 2],
+			fw->data[fw->size - 1]);
+
+	/* Begin the firmware load process */
+	ds3000_writereg(state, 0xb2, 0x01);
+	/* write the entire firmware */
+	ds3000_writeFW(state, 0xb0, fw->data, fw->size);
+	ds3000_writereg(state, 0xb2, 0x00);
+
+	return 0;
+}
+
+static void ds3000_dump_registers(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int x, y, reg = 0, val;
+
+	for (y = 0; y < 16; y++) {
+		dprintk("%s: %02x: ", __func__, y);
+		for (x = 0; x < 16; x++) {
+			reg = (y << 4) + x;
+			val = ds3000_readreg(state, reg);
+			if (x != 15)
+				dprintk("%02x ",  val);
+			else
+				dprintk("%02x\n", val);
+		}
+	}
+	dprintk("%s: -- DS3000 DUMP DONE --\n", __func__);
+}
+
+static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int lock;
+
+	*status = 0;
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		lock = ds3000_readreg(state, 0xd1);
+		if ((lock & 0x07) == 0x07)
+			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC |
+				FE_HAS_LOCK;
+
+		break;
+	case SYS_DVBS2:
+		lock = ds3000_readreg(state, 0x0d);
+		if ((lock & 0x8f) == 0x8f)
+			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC |
+				FE_HAS_LOCK;
+
+		break;
+	default:
+		return 1;
+	}
+
+	dprintk("%s: status = 0x%02x\n", __func__, lock);
+
+	return 0;
+}
+
+#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
+static int ds3000_is_tuned(struct dvb_frontend *fe)
+{
+	fe_status_t tunerstat;
+
+	ds3000_read_status(fe, &tunerstat);
+
+	return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
+}
+
+/* read DS3000 BER value */
+static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 data;
+	u32 ber_reading, lpdc_frames;
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		/* set the number of bytes checked during
+		BER estimation */
+		ds3000_writereg(state, 0xf9, 0x04);
+		/* read BER estimation status */
+		data = ds3000_readreg(state, 0xf8);
+		/* check if BER estimation is ready */
+		if ((data & 0x10) == 0) {
+			/* this is the number of error bits,
+			to calculate the bit error rate
+			divide to 8388608 */
+			*ber = (ds3000_readreg(state, 0xf7) << 8) |
+				ds3000_readreg(state, 0xf6);
+			/* start counting error bits */
+			/* need to be set twice
+			otherwise it fails sometimes */
+			data |= 0x10;
+			ds3000_writereg(state, 0xf8, data);
+			ds3000_writereg(state, 0xf8, data);
+		} else
+			/* used to indicate that BER estimation
+			is not ready, i.e. BER is unknown */
+			*ber = 0xffffffff;
+		break;
+	case SYS_DVBS2:
+		/* read the number of LPDC decoded frames */
+		lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
+				(ds3000_readreg(state, 0xd6) << 8) |
+				ds3000_readreg(state, 0xd5);
+		/* read the number of packets with bad CRC */
+		ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
+				ds3000_readreg(state, 0xf7);
+		if (lpdc_frames > 750) {
+			/* clear LPDC frame counters */
+			ds3000_writereg(state, 0xd1, 0x01);
+			/* clear bad packets counter */
+			ds3000_writereg(state, 0xf9, 0x01);
+			/* enable bad packets counter */
+			ds3000_writereg(state, 0xf9, 0x00);
+			/* enable LPDC frame counters */
+			ds3000_writereg(state, 0xd1, 0x00);
+			*ber = ber_reading;
+		} else
+			/* used to indicate that BER estimation is not ready,
+			i.e. BER is unknown */
+			*ber = 0xffffffff;
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* read TS2020 signal strength */
+static int ds3000_read_signal_strength(struct dvb_frontend *fe,
+						u16 *signal_strength)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	u16 sig_reading, sig_strength;
+	u8 rfgain, bbgain;
+
+	dprintk("%s()\n", __func__);
+
+	rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
+	bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
+
+	if (rfgain > 15)
+		rfgain = 15;
+	if (bbgain > 13)
+		bbgain = 13;
+
+	sig_reading = rfgain * 2 + bbgain * 3;
+
+	sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
+
+	/* cook the value to be suitable for szap-s2 human readable output */
+	*signal_strength = sig_strength * 1000;
+
+	dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
+			sig_reading, *signal_strength);
+
+	return 0;
+}
+
+/* calculate DS3000 snr value in dB */
+static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 snr_reading, snr_value;
+	u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
+	static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
+		0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
+		0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
+		0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
+	};
+	static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
+		0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
+		0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
+		0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
+		0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
+		0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
+		0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
+		0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
+		0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
+		0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
+		0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
+		0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
+		0x49e9, 0x4a20, 0x4a57
+	};
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		snr_reading = ds3000_readreg(state, 0xff);
+		snr_reading /= 8;
+		if (snr_reading == 0)
+			*snr = 0x0000;
+		else {
+			if (snr_reading > 20)
+				snr_reading = 20;
+			snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = snr_value * 8 * 655;
+		}
+		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+				snr_reading, *snr);
+		break;
+	case SYS_DVBS2:
+		dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
+				(ds3000_readreg(state, 0x8d) << 4);
+		dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
+		tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
+		if (dvbs2_signal_reading == 0) {
+			*snr = 0x0000;
+			return 0;
+		}
+		if (dvbs2_noise_reading == 0) {
+			snr_value = 0x0013;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = 0xffff;
+			return 0;
+		}
+		if (tmp > dvbs2_noise_reading) {
+			snr_reading = tmp / dvbs2_noise_reading;
+			if (snr_reading > 80)
+				snr_reading = 80;
+			snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
+			/* cook the value to be suitable for szap-s2
+			human readable output */
+			*snr = snr_value * 5 * 655;
+		} else {
+			snr_reading = dvbs2_noise_reading / tmp;
+			if (snr_reading > 80)
+				snr_reading = 80;
+			*snr = -(dvbs2_snr_tab[snr_reading] / 1000);
+		}
+		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+				snr_reading, *snr);
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* read DS3000 uncorrected blocks */
+static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u8 data;
+	u16 _ucblocks;
+
+	dprintk("%s()\n", __func__);
+
+	switch (c->delivery_system) {
+	case SYS_DVBS:
+		*ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
+				ds3000_readreg(state, 0xf4);
+		data = ds3000_readreg(state, 0xf8);
+		/* clear packet counters */
+		data &= ~0x20;
+		ds3000_writereg(state, 0xf8, data);
+		/* enable packet counters */
+		data |= 0x20;
+		ds3000_writereg(state, 0xf8, data);
+		break;
+	case SYS_DVBS2:
+		_ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
+				ds3000_readreg(state, 0xe1);
+		if (_ucblocks > state->prevUCBS2)
+			*ucblocks = _ucblocks - state->prevUCBS2;
+		else
+			*ucblocks = state->prevUCBS2 - _ucblocks;
+		state->prevUCBS2 = _ucblocks;
+		break;
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Overwrite the current tuning params, we are about to tune */
+static void ds3000_clone_params(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
+}
+
+static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	u8 data;
+
+	dprintk("%s(%d)\n", __func__, tone);
+	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
+		printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
+		return -EINVAL;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		dprintk("%s: setting tone on\n", __func__);
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x43;
+		data |= 0x04;
+		ds3000_writereg(state, 0xa1, data);
+		break;
+	case SEC_TONE_OFF:
+		dprintk("%s: setting tone off\n", __func__);
+		data = ds3000_readreg(state, 0xa2);
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+		break;
+	}
+
+	return 0;
+}
+
+static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
+				struct dvb_diseqc_master_cmd *d)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int i;
+	u8 data;
+
+	/* Dump DiSEqC message */
+	dprintk("%s(", __func__);
+	for (i = 0 ; i < d->msg_len;) {
+		dprintk("0x%02x", d->msg[i]);
+		if (++i < d->msg_len)
+			dprintk(", ");
+	}
+
+	/* enable DiSEqC message send pin */
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	/* DiSEqC message */
+	for (i = 0; i < d->msg_len; i++)
+		ds3000_writereg(state, 0xa3 + i, d->msg[i]);
+
+	data = ds3000_readreg(state, 0xa1);
+	/* clear DiSEqC message length and status,
+	enable DiSEqC message send */
+	data &= ~0xf8;
+	/* set DiSEqC mode, modulation active during 33 pulses,
+	set DiSEqC message length */
+	data |= ((d->msg_len - 1) << 3) | 0x07;
+	ds3000_writereg(state, 0xa1, data);
+
+	/* wait up to 150ms for DiSEqC transmission to complete */
+	for (i = 0; i < 15; i++) {
+		data = ds3000_readreg(state, 0xa1);
+		if ((data & 0x40) == 0)
+			break;
+		msleep(10);
+	}
+
+	/* DiSEqC timeout after 150ms */
+	if (i == 15) {
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x80;
+		data |= 0x40;
+		ds3000_writereg(state, 0xa1, data);
+
+		data = ds3000_readreg(state, 0xa2);
+		data &= ~0xc0;
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+
+		return 1;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	data |= 0x80;
+	ds3000_writereg(state, 0xa2, data);
+
+	return 0;
+}
+
+/* Send DiSEqC burst */
+static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
+					fe_sec_mini_cmd_t burst)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	int i;
+	u8 data;
+
+	dprintk("%s()\n", __func__);
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	ds3000_writereg(state, 0xa2, data);
+
+	/* DiSEqC burst */
+	if (burst == SEC_MINI_A)
+		/* Unmodulated tone burst */
+		ds3000_writereg(state, 0xa1, 0x02);
+	else if (burst == SEC_MINI_B)
+		/* Modulated tone burst */
+		ds3000_writereg(state, 0xa1, 0x01);
+	else
+		return -EINVAL;
+
+	msleep(13);
+	for (i = 0; i < 5; i++) {
+		data = ds3000_readreg(state, 0xa1);
+		if ((data & 0x40) == 0)
+			break;
+		msleep(1);
+	}
+
+	if (i == 5) {
+		data = ds3000_readreg(state, 0xa1);
+		data &= ~0x80;
+		data |= 0x40;
+		ds3000_writereg(state, 0xa1, data);
+
+		data = ds3000_readreg(state, 0xa2);
+		data &= ~0xc0;
+		data |= 0x80;
+		ds3000_writereg(state, 0xa2, data);
+
+		return 1;
+	}
+
+	data = ds3000_readreg(state, 0xa2);
+	data &= ~0xc0;
+	data |= 0x80;
+	ds3000_writereg(state, 0xa2, data);
+
+	return 0;
+}
+
+static void ds3000_release(struct dvb_frontend *fe)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	dprintk("%s\n", __func__);
+	kfree(state);
+}
+
+static struct dvb_frontend_ops ds3000_ops;
+
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+				    struct i2c_adapter *i2c)
+{
+	struct ds3000_state *state = NULL;
+	int ret;
+
+	dprintk("%s\n", __func__);
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL);
+	if (state == NULL) {
+		printk(KERN_ERR "Unable to kmalloc\n");
+		goto error2;
+	}
+
+	/* setup the state */
+	memset(state, 0, sizeof(struct ds3000_state));
+
+	state->config = config;
+	state->i2c = i2c;
+	state->prevUCBS2 = 0;
+
+	/* check if the demod is present */
+	ret = ds3000_readreg(state, 0x00) & 0xfe;
+	if (ret != 0xe0) {
+		printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
+		goto error3;
+	}
+
+	printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
+			ds3000_readreg(state, 0x02),
+			ds3000_readreg(state, 0x01));
+
+	memcpy(&state->frontend.ops, &ds3000_ops,
+			sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error3:
+	kfree(state);
+error2:
+	return NULL;
+}
+EXPORT_SYMBOL(ds3000_attach);
+
+static int ds3000_set_property(struct dvb_frontend *fe,
+	struct dtv_property *tvp)
+{
+	dprintk("%s(..)\n", __func__);
+	return 0;
+}
+
+static int ds3000_get_property(struct dvb_frontend *fe,
+	struct dtv_property *tvp)
+{
+	dprintk("%s(..)\n", __func__);
+	return 0;
+}
+
+static int ds3000_tune(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *p)
+{
+	struct ds3000_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	int ret = 0, retune, i;
+	u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf;
+	u16 value, ndiv;
+	u32 f3db;
+
+	dprintk("%s() ", __func__);
+
+	/* Load the firmware if required */
+	ret = ds3000_firmware_ondemand(fe);
+	if (ret != 0) {
+		printk(KERN_ERR "%s: Unable initialise the firmware\n",
+								__func__);
+		return ret;
+	}
+
+	state->dnxt.delivery = c->modulation;
+	state->dnxt.frequency = c->frequency;
+	state->dnxt.rolloff = 2; /* fixme */
+	state->dnxt.fec = c->fec_inner;
+
+	ret = ds3000_set_inversion(state, p->inversion);
+	if (ret !=  0)
+		return ret;
+
+	ret = ds3000_set_symbolrate(state, c->symbol_rate);
+	if (ret !=  0)
+		return ret;
+
+	/* discard the 'current' tuning parameters and prepare to tune */
+	ds3000_clone_params(fe);
+
+	retune = 1;	/* try 1 times */
+	dprintk("%s:   retune = %d\n", __func__, retune);
+	dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
+	dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
+	dprintk("%s:   FEC	 = %d \n", __func__,
+		state->dcur.fec);
+	dprintk("%s:   Inversion   = %d\n", __func__, state->dcur.inversion);
+
+	do {
+		/* Reset status register */
+		status = 0;
+		/* Tune */
+		/* TS2020 init */
+		ds3000_tuner_writereg(state, 0x42, 0x73);
+		ds3000_tuner_writereg(state, 0x05, 0x01);
+		ds3000_tuner_writereg(state, 0x62, 0xf5);
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x07, 0x02);
+		ds3000_tuner_writereg(state, 0x10, 0x00);
+		ds3000_tuner_writereg(state, 0x60, 0x79);
+		ds3000_tuner_writereg(state, 0x08, 0x01);
+		ds3000_tuner_writereg(state, 0x00, 0x01);
+		/* calculate and set freq divider */
+		if (state->dcur.frequency < 1146000) {
+			ds3000_tuner_writereg(state, 0x10, 0x11);
+			ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
+					(DS3000_XTAL_FREQ / 2)) /
+					DS3000_XTAL_FREQ - 1024;
+		} else {
+			ds3000_tuner_writereg(state, 0x10, 0x01);
+			ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
+					(DS3000_XTAL_FREQ / 2)) /
+					DS3000_XTAL_FREQ - 1024;
+		}
+
+		ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
+		ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
+
+		/* set pll */
+		ds3000_tuner_writereg(state, 0x03, 0x06);
+		ds3000_tuner_writereg(state, 0x51, 0x0f);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x10);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x51, 0x17);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x08);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		value = ds3000_tuner_readreg(state, 0x3d);
+		value &= 0x0f;
+		if ((value > 4) && (value < 15)) {
+			value -= 3;
+			if (value < 4)
+				value = 4;
+			value = ((value << 3) | 0x01) & 0x79;
+		}
+
+		ds3000_tuner_writereg(state, 0x60, value);
+		ds3000_tuner_writereg(state, 0x51, 0x17);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x08);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+
+		/* set low-pass filter period */
+		ds3000_tuner_writereg(state, 0x04, 0x2e);
+		ds3000_tuner_writereg(state, 0x51, 0x1b);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x04);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
+		if ((state->dcur.symbol_rate / 1000) < 5000)
+			f3db += 3000;
+		if (f3db < 7000)
+			f3db = 7000;
+		if (f3db > 40000)
+			f3db = 40000;
+
+		/* set low-pass filter baseband */
+		value = ds3000_tuner_readreg(state, 0x26);
+		mlpf = 0x2e * 207 / ((value << 1) + 151);
+		mlpf_max = mlpf * 135 / 100;
+		mlpf_min = mlpf * 78 / 100;
+		if (mlpf_max > 63)
+			mlpf_max = 63;
+
+		/* rounded to the closest integer */
+		nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
+				/ (2766 * DS3000_XTAL_FREQ);
+		if (nlpf > 23)
+			nlpf = 23;
+		if (nlpf < 1)
+			nlpf = 1;
+
+		/* rounded to the closest integer */
+		mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+				(1000 * f3db / 2)) / (1000 * f3db);
+
+		if (mlpf_new < mlpf_min) {
+			nlpf++;
+			mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+					(1000 * f3db / 2)) / (1000 * f3db);
+		}
+
+		if (mlpf_new > mlpf_max)
+			mlpf_new = mlpf_max;
+
+		ds3000_tuner_writereg(state, 0x04, mlpf_new);
+		ds3000_tuner_writereg(state, 0x06, nlpf);
+		ds3000_tuner_writereg(state, 0x51, 0x1b);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x04);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(5);
+
+		/* unknown */
+		ds3000_tuner_writereg(state, 0x51, 0x1e);
+		ds3000_tuner_writereg(state, 0x51, 0x1f);
+		ds3000_tuner_writereg(state, 0x50, 0x01);
+		ds3000_tuner_writereg(state, 0x50, 0x00);
+		msleep(60);
+
+		/* ds3000 global reset */
+		ds3000_writereg(state, 0x07, 0x80);
+		ds3000_writereg(state, 0x07, 0x00);
+		/* ds3000 build-in uC reset */
+		ds3000_writereg(state, 0xb2, 0x01);
+		/* ds3000 software reset */
+		ds3000_writereg(state, 0x00, 0x01);
+
+		switch (c->delivery_system) {
+		case SYS_DVBS:
+			/* initialise the demod in DVB-S mode */
+			for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
+				ds3000_writereg(state,
+					ds3000_dvbs_init_tab[i],
+					ds3000_dvbs_init_tab[i + 1]);
+			value = ds3000_readreg(state, 0xfe);
+			value &= 0xc0;
+			value |= 0x1b;
+			ds3000_writereg(state, 0xfe, value);
+			break;
+		case SYS_DVBS2:
+			/* initialise the demod in DVB-S2 mode */
+			for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
+				ds3000_writereg(state,
+					ds3000_dvbs2_init_tab[i],
+					ds3000_dvbs2_init_tab[i + 1]);
+			ds3000_writereg(state, 0xfe, 0x54);
+			break;
+		default:
+			return 1;
+		}
+
+		/* enable 27MHz clock output */
+		ds3000_writereg(state, 0x29, 0x80);
+		/* enable ac coupling */
+		ds3000_writereg(state, 0x25, 0x8a);
+
+		/* enhance symbol rate performance */
+		if ((state->dcur.symbol_rate / 1000) <= 5000) {
+			value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
+			if (value % 2 != 0)
+				value++;
+			ds3000_writereg(state, 0xc3, 0x0d);
+			ds3000_writereg(state, 0xc8, value);
+			ds3000_writereg(state, 0xc4, 0x10);
+			ds3000_writereg(state, 0xc7, 0x0e);
+		} else if ((state->dcur.symbol_rate / 1000) <= 10000) {
+			value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
+			if (value % 2 != 0)
+				value++;
+			ds3000_writereg(state, 0xc3, 0x07);
+			ds3000_writereg(state, 0xc8, value);
+			ds3000_writereg(state, 0xc4, 0x09);
+			ds3000_writereg(state, 0xc7, 0x12);
+		} else if ((state->dcur.symbol_rate / 1000) <= 20000) {
+			value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
+			ds3000_writereg(state, 0xc3, value);
+			ds3000_writereg(state, 0xc8, 0x0e);
+			ds3000_writereg(state, 0xc4, 0x07);
+			ds3000_writereg(state, 0xc7, 0x18);
+		} else {
+			value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
+			ds3000_writereg(state, 0xc3, value);
+			ds3000_writereg(state, 0xc8, 0x0a);
+			ds3000_writereg(state, 0xc4, 0x05);
+			ds3000_writereg(state, 0xc7, 0x24);
+		}
+
+		/* normalized symbol rate rounded to the closest integer */
+		value = (((state->dcur.symbol_rate / 1000) << 16) +
+				(DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
+		ds3000_writereg(state, 0x61, value & 0x00ff);
+		ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
+
+		/* co-channel interference cancellation disabled */
+		ds3000_writereg(state, 0x56, 0x00);
+
+		/* equalizer disabled */
+		ds3000_writereg(state, 0x76, 0x00);
+
+		/*ds3000_writereg(state, 0x08, 0x03);
+		ds3000_writereg(state, 0xfd, 0x22);
+		ds3000_writereg(state, 0x08, 0x07);
+		ds3000_writereg(state, 0xfd, 0x42);
+		ds3000_writereg(state, 0x08, 0x07);*/
+
+		/* ds3000 out of software reset */
+		ds3000_writereg(state, 0x00, 0x00);
+		/* start ds3000 build-in uC */
+		ds3000_writereg(state, 0xb2, 0x00);
+
+		/* TODO: calculate and set carrier offset */
+
+		/* wait before retrying */
+		for (i = 0; i < 30 ; i++) {
+			if (ds3000_is_tuned(fe)) {
+				dprintk("%s: Tuned\n", __func__);
+				ds3000_dump_registers(fe);
+				goto tuned;
+			}
+			msleep(1);
+		}
+
+		dprintk("%s: Not tuned\n", __func__);
+		ds3000_dump_registers(fe);
+
+	} while (--retune);
+
+tuned:
+	return ret;
+}
+
+static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return DVBFE_ALGO_SW;
+}
+
+/*
+ * Initialise or wake up device
+ *
+ * Power config will reset and load initial firmware if required
+ */
+static int ds3000_initfe(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+/* Put device to sleep */
+static int ds3000_sleep(struct dvb_frontend *fe)
+{
+	dprintk("%s()\n", __func__);
+	return 0;
+}
+
+static struct dvb_frontend_ops ds3000_ops = {
+
+	.info = {
+		.name = "Montage Technology DS3000/TS2020",
+		.type = FE_QPSK,
+		.frequency_min = 950000,
+		.frequency_max = 2150000,
+		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
+		.frequency_tolerance = 5000,
+		.symbol_rate_min = 1000000,
+		.symbol_rate_max = 45000000,
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_2G_MODULATION |
+			FE_CAN_QPSK | FE_CAN_RECOVER
+	},
+
+	.release = ds3000_release,
+
+	.init = ds3000_initfe,
+	.sleep = ds3000_sleep,
+	.read_status = ds3000_read_status,
+	.read_ber = ds3000_read_ber,
+	.read_signal_strength = ds3000_read_signal_strength,
+	.read_snr = ds3000_read_snr,
+	.read_ucblocks = ds3000_read_ucblocks,
+	.set_tone = ds3000_set_tone,
+	.diseqc_send_master_cmd = ds3000_send_diseqc_msg,
+	.diseqc_send_burst = ds3000_diseqc_send_burst,
+	.get_frontend_algo = ds3000_get_algo,
+
+	.set_property = ds3000_set_property,
+	.get_property = ds3000_get_property,
+	.set_frontend = ds3000_tune,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
+			"DS3000/TS2020 hardware");
+MODULE_AUTHOR("Konstantin Dimitrov");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ds3000.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ds3000.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ds3000.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ds3000.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.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.
+*/
+
+#ifndef DS3000_H
+#define DS3000_H
+
+#include <linux/dvb/frontend.h>
+
+struct ds3000_config {
+	/* the demodulator's i2c address */
+	u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_DS3000) || \
+			(defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+					struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+					struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_DS3000 */
+#endif /* DS3000_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,335 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 "dvb_frontend.h"
+#include "ec100_priv.h"
+#include "ec100.h"
+
+int ec100_debug;
+module_param_named(debug, ec100_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+struct ec100_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend frontend;
+	struct ec100_config config;
+
+	u16 ber;
+};
+
+/* write single register */
+static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
+{
+	u8 buf[2] = {reg, val};
+	struct i2c_msg msg = {
+		.addr = state->config.demod_address,
+		.flags = 0,
+		.len = 2,
+		.buf = buf};
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		warn("I2C write failed reg:%02x", reg);
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+/* read single register */
+static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[2] = {
+		{
+			.addr = state->config.demod_address,
+			.flags = 0,
+			.len = 1,
+			.buf = &reg
+		}, {
+			.addr = state->config.demod_address,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = val
+		}
+	};
+
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+		warn("I2C read failed reg:%02x", reg);
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int ec100_set_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp, tmp2;
+
+	deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
+		params->u.ofdm.bandwidth);
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, params);
+
+	ret = ec100_write_reg(state, 0x04, 0x06);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x67, 0x58);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x05, 0x18);
+	if (ret)
+		goto error;
+
+	/* reg/bw |   6  |   7  |   8
+	   -------+------+------+------
+	   A 0x1b | 0xa1 | 0xe7 | 0x2c
+	   A 0x1c | 0x55 | 0x63 | 0x72
+	   -------+------+------+------
+	   B 0x1b | 0xb7 | 0x00 | 0x49
+	   B 0x1c | 0x55 | 0x64 | 0x72 */
+
+	switch (params->u.ofdm.bandwidth) {
+	case BANDWIDTH_6_MHZ:
+		tmp = 0xb7;
+		tmp2 = 0x55;
+		break;
+	case BANDWIDTH_7_MHZ:
+		tmp = 0x00;
+		tmp2 = 0x64;
+		break;
+	case BANDWIDTH_8_MHZ:
+	default:
+		tmp = 0x49;
+		tmp2 = 0x72;
+	}
+
+	ret = ec100_write_reg(state, 0x1b, tmp);
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x1c, tmp2);
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x08, 0x24);
+	if (ret)
+		goto error;
+
+	ret = ec100_write_reg(state, 0x00, 0x00); /* go */
+	if (ret)
+		goto error;
+	ret = ec100_write_reg(state, 0x00, 0x20); /* go */
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *fesettings)
+{
+	fesettings->min_delay_ms = 300;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+
+	return 0;
+}
+
+static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp;
+	*status = 0;
+
+	ret = ec100_read_reg(state, 0x42, &tmp);
+	if (ret)
+		goto error;
+
+	if (tmp & 0x80) {
+		/* bit7 set - have lock */
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+			FE_HAS_SYNC | FE_HAS_LOCK;
+	} else {
+		ret = ec100_read_reg(state, 0x01, &tmp);
+		if (ret)
+			goto error;
+
+		if (tmp & 0x10) {
+			/* bit4 set - have signal */
+			*status |= FE_HAS_SIGNAL;
+			if (!(tmp & 0x01)) {
+				/* bit0 clear - have ~valid signal */
+				*status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
+			}
+		}
+	}
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp, tmp2;
+	u16 ber2;
+
+	*ber = 0;
+
+	ret = ec100_read_reg(state, 0x65, &tmp);
+	if (ret)
+		goto error;
+	ret = ec100_read_reg(state, 0x66, &tmp2);
+	if (ret)
+		goto error;
+
+	ber2 = (tmp2 << 8) | tmp;
+
+	/* if counter overflow or clear */
+	if (ber2 < state->ber)
+		*ber = ber2;
+	else
+		*ber = ber2 - state->ber;
+
+	state->ber = ber2;
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	int ret;
+	u8 tmp;
+
+	ret = ec100_read_reg(state, 0x24, &tmp);
+	if (ret) {
+		*strength = 0;
+		goto error;
+	}
+
+	*strength = ((tmp << 8) | tmp);
+
+	return ret;
+error:
+	deb_info("%s: failed:%d\n", __func__, ret);
+	return ret;
+}
+
+static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	*snr = 0;
+	return 0;
+}
+
+static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+static void ec100_release(struct dvb_frontend *fe)
+{
+	struct ec100_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops ec100_ops;
+
+struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+	struct i2c_adapter *i2c)
+{
+	int ret;
+	struct ec100_state *state = NULL;
+	u8 tmp;
+
+	/* allocate memory for the internal state */
+	state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	/* setup the state */
+	state->i2c = i2c;
+	memcpy(&state->config, config, sizeof(struct ec100_config));
+
+	/* check if the demod is there */
+	ret = ec100_read_reg(state, 0x33, &tmp);
+	if (ret || tmp != 0x0b)
+		goto error;
+
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops, &ec100_ops,
+		sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	return &state->frontend;
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(ec100_attach);
+
+static struct dvb_frontend_ops ec100_ops = {
+	.info = {
+		.name = "E3C EC100 DVB-T",
+		.type = FE_OFDM,
+		.caps =
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK | FE_CAN_QAM_16 |
+			FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_HIERARCHY_AUTO |
+			FE_CAN_MUTE_TS
+	},
+
+	.release = ec100_release,
+	.set_frontend = ec100_set_frontend,
+	.get_tune_settings = ec100_get_tune_settings,
+	.read_status = ec100_read_status,
+	.read_ber = ec100_read_ber,
+	.read_signal_strength = ec100_read_signal_strength,
+	.read_snr = ec100_read_snr,
+	.read_ucblocks = ec100_read_ucblocks,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,46 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 EC100_H
+#define EC100_H
+
+#include <linux/dvb/frontend.h>
+
+struct ec100_config {
+	/* demodulator's I2C address */
+	u8 demod_address;
+};
+
+
+#if defined(CONFIG_DVB_EC100) || \
+	(defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+	struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *ec100_attach(
+	const struct ec100_config *config, struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif /* EC100_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/ec100_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/ec100_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@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.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You 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 EC100_PRIV
+#define EC100_PRIV
+
+#define LOG_PREFIX "ec100"
+
+#define dprintk(var, level, args...) \
+	do { if ((var & level)) printk(args); } while (0)
+
+#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
+
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#endif /* EC100_PRIV */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/Kconfig linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -201,6 +201,21 @@ config DVB_SI21XX
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_DS3000
+	tristate "Montage Tehnology DS3000 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
+
+config DVB_MB86A16
+	tristate "Fujitsu MB86A16 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S/DSS Direct Conversion reveiver.
+	  Say Y when you want to support this frontend.
+
 comment "DVB-T (terrestrial) frontends"
 	depends on DVB_CORE
 
@@ -342,6 +357,13 @@ config DVB_AF9013
 	help
 	  Say Y when you want to support this frontend.
 
+config DVB_EC100
+	tristate "E3C EC100"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
@@ -512,6 +534,15 @@ config DVB_TUNER_DIB0070
 	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
+config DVB_TUNER_DIB0090
+	tristate "DiBcom DiB0090 silicon base-band tuner"
+	depends on I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A driver for the silicon baseband tuner DiB0090 from DiBcom.
+	  This device is only used inside a SiP called together with a
+	  demodulator for now.
+
 comment "SEC control devices for DVB-S"
 	depends on DVB_CORE
 
@@ -557,6 +588,24 @@ config DVB_LGS8GXX
 	help
 	  A DMB-TH tuner module. Say Y when you want to support this frontend.
 
+config DVB_ATBM8830
+	tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DMB-TH tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA665x
+	tristate "TDA665x tuner"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  Support for tuner modules based on Philips TDA6650/TDA6651 chips.
+	  Say Y when you want to support this chip.
+
+	  Currently supported tuners:
+	  * Panasonic ENV57H12D5 (ET-50DT)
+
 comment "Tools to develop new frontends"
 
 config DVB_DUMMY_FE
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/l64781.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/l64781.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/l64781.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/l64781.c	2010-02-24 13:52:17.000000000 -0500
@@ -192,8 +192,8 @@ static int apply_frontend_param (struct
 	spi_bias *= qam_tab[p->constellation];
 	spi_bias /= p->code_rate_HP + 1;
 	spi_bias /= (guard_tab[p->guard_interval] + 32);
-	spi_bias *= 1000ULL;
-	spi_bias /= 1000ULL + ppm/1000;
+	spi_bias *= 1000;
+	spi_bias /= 1000 + ppm/1000;
 	spi_bias *= p->code_rate_HP;
 
 	val0x04 = (p->transmission_mode << 2) | p->guard_interval;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgdt3305.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3305.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgdt3305.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt3305.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,13 +54,13 @@ struct lgdt3305_config {
 	u16 usref_qam256; /* default: 0x2a80 */
 
 	/* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
-	int deny_i2c_rptr:1;
+	unsigned int deny_i2c_rptr:1;
 
 	/* spectral inversion - 0:disabled 1:enabled */
-	int spectral_inversion:1;
+	unsigned int spectral_inversion:1;
 
 	/* use RF AGC loop - 0:disabled 1:enabled */
-	int rf_agc_loop:1;
+	unsigned int rf_agc_loop:1;
 
 	enum lgdt3305_mpeg_mode mpeg_mode;
 	enum lgdt3305_tp_clock_edge tpclk_edge;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgdt330x.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt330x.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgdt330x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgdt330x.c	2010-02-24 13:52:17.000000000 -0500
@@ -479,7 +479,7 @@ static int lgdt3302_read_status(struct d
 	switch (state->current_modulation) {
 	case QAM_256:
 	case QAM_64:
-		/* Need to undestand why there are 3 lock levels here */
+		/* Need to understand why there are 3 lock levels here */
 		if ((buf[0] & 0x07) == 0x07)
 			*status |= FE_HAS_CARRIER;
 		break;
@@ -520,7 +520,7 @@ static int lgdt3303_read_status(struct d
 	switch (state->current_modulation) {
 	case QAM_256:
 	case QAM_64:
-		/* Need to undestand why there are 3 lock levels here */
+		/* Need to understand why there are 3 lock levels here */
 		if ((buf[0] & 0x07) == 0x07)
 			*status |= FE_HAS_CARRIER;
 		else
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgs8gxx.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgs8gxx.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lgs8gxx.c	2013-05-03 13:57:32.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lgs8gxx.c	2013-05-03 12:04:41.000000000 -0400
@@ -165,7 +165,7 @@ static int lgs8gxx_set_if_freq(struct lg
 
 	val = freq;
 	if (freq != 0) {
-		val *= (u64)1 << 32;
+		val <<= 32;
 		if (if_clk != 0)
 			do_div(val, if_clk);
 		v32 = val & 0xFFFFFFFF;
@@ -212,7 +212,7 @@ static int lgs8gxx_get_afc_phase(struct
 
 	val = v32;
 	val *= priv->config->if_clk_freq;
-	val /= (u64)1 << 32;
+	val >>= 32;
 	dprintk("AFC = %u kHz\n", (u32)val);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lnbp21.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lnbp21.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/lnbp21.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/lnbp21.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
  * lnbp21.c - driver for lnb supply and control ic lnbp21
  *
- * Copyright (C) 2006 Oliver Endriss
+ * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
  * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
  *
  * This program is free software; you can redistribute it and/or
@@ -91,6 +91,31 @@ static int lnbp21_enable_high_lnb_voltag
 	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
 }
 
+static int lnbp21_set_tone(struct dvb_frontend *fe,
+				fe_sec_tone_mode_t tone)
+{
+	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
+	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0,
+				.buf = &lnbp21->config,
+				.len = sizeof(lnbp21->config) };
+
+	switch (tone) {
+	case SEC_TONE_OFF:
+		lnbp21->config &= ~LNBP21_TEN;
+		break;
+	case SEC_TONE_ON:
+		lnbp21->config |= LNBP21_TEN;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	lnbp21->config |= lnbp21->override_or;
+	lnbp21->config &= lnbp21->override_and;
+
+	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
 static void lnbp21_release(struct dvb_frontend *fe)
 {
 	/* LNBP power off */
@@ -133,6 +158,7 @@ static struct dvb_frontend *lnbx2x_attac
 	/* override frontend ops */
 	fe->ops.set_voltage = lnbp21_set_voltage;
 	fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+	fe->ops.set_tone = lnbp21_set_tone;
 	printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
 
 	return fe;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/Makefile linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -55,6 +55,7 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
 obj-$(CONFIG_DVB_TDA8261) += tda8261.o
 obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
+obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
 obj-$(CONFIG_DVB_TUA6100) += tua6100.o
 obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
 obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
@@ -63,7 +64,9 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o
 obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
 obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
 obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
+obj-$(CONFIG_DVB_TDA665x) += tda665x.o
 obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
+obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
 obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
 obj-$(CONFIG_DVB_AF9013) += af9013.o
 obj-$(CONFIG_DVB_CX24116) += cx24116.o
@@ -76,3 +79,6 @@ obj-$(CONFIG_DVB_STV0900) += stv0900.o
 obj-$(CONFIG_DVB_STV090x) += stv090x.o
 obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
 obj-$(CONFIG_DVB_ISL6423) += isl6423.o
+obj-$(CONFIG_DVB_EC100) += ec100.o
+obj-$(CONFIG_DVB_DS3000) += ds3000.o
+obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1878 @@
+/*
+	Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include "dvb_frontend.h"
+#include "mb86a16.h"
+#include "mb86a16_priv.h"
+
+unsigned int verbose = 5;
+module_param(verbose, int, 0644);
+
+#define ABS(x)		((x) < 0 ? (-x) : (x))
+
+struct mb86a16_state {
+	struct i2c_adapter		*i2c_adap;
+	const struct mb86a16_config	*config;
+	struct dvb_frontend		frontend;
+
+	/* tuning parameters */
+	int				frequency;
+	int				srate;
+
+	/* Internal stuff */
+	int				master_clk;
+	int				deci;
+	int				csel;
+	int				rsel;
+};
+
+#define MB86A16_ERROR		0
+#define MB86A16_NOTICE		1
+#define MB86A16_INFO		2
+#define MB86A16_DEBUG		3
+
+#define dprintk(x, y, z, format, arg...) do {						\
+	if (z) {									\
+		if	((x > MB86A16_ERROR) && (x > y))				\
+			printk(KERN_ERR "%s: " format "\n", __func__, ##arg);		\
+		else if ((x > MB86A16_NOTICE) && (x > y))				\
+			printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg);	\
+		else if ((x > MB86A16_INFO) && (x > y))					\
+			printk(KERN_INFO "%s: " format "\n", __func__, ##arg);		\
+		else if ((x > MB86A16_DEBUG) && (x > y))				\
+			printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg);		\
+	} else {									\
+		if (x > y)								\
+			printk(format, ##arg);						\
+	}										\
+} while (0)
+
+#define TRACE_IN	dprintk(verbose, MB86A16_DEBUG, 1, "-->()")
+#define TRACE_OUT	dprintk(verbose, MB86A16_DEBUG, 1, "()-->")
+
+static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val)
+{
+	int ret;
+	u8 buf[] = { reg, val };
+
+	struct i2c_msg msg = {
+		.addr = state->config->demod_address,
+		.flags = 0,
+		.buf = buf,
+		.len = 2
+	};
+
+	dprintk(verbose, MB86A16_DEBUG, 1,
+		"writing to [0x%02x],Reg[0x%02x],Data[0x%02x]",
+		state->config->demod_address, buf[0], buf[1]);
+
+	ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+	return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+
+	struct i2c_msg msg[] = {
+		{
+			.addr = state->config->demod_address,
+			.flags = 0,
+			.buf = b0,
+			.len = 1
+		}, {
+			.addr = state->config->demod_address,
+			.flags = I2C_M_RD,
+			.buf = b1,
+			.len = 1
+		}
+	};
+	ret = i2c_transfer(state->i2c_adap, msg, 2);
+	if (ret != 2) {
+		dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
+			reg, ret);
+
+		return -EREMOTEIO;
+	}
+	*val = b1[0];
+
+	return ret;
+}
+
+static int CNTM_set(struct mb86a16_state *state,
+		    unsigned char timint1,
+		    unsigned char timint2,
+		    unsigned char cnext)
+{
+	unsigned char val;
+
+	val = (timint1 << 4) | (timint2 << 2) | cnext;
+	if (mb86a16_write(state, MB86A16_CNTMR, val) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int smrt_set(struct mb86a16_state *state, int rate)
+{
+	int tmp ;
+	int m ;
+	unsigned char STOFS0, STOFS1;
+
+	m = 1 << state->deci;
+	tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk;
+
+	STOFS0 = tmp & 0x0ff;
+	STOFS1 = (tmp & 0xf00) >> 8;
+
+	if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) |
+				       (state->csel << 1) |
+					state->rsel) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -1;
+}
+
+static int srst(struct mb86a16_state *state)
+{
+	if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+
+}
+
+static int afcex_data_set(struct mb86a16_state *state,
+			  unsigned char AFCEX_L,
+			  unsigned char AFCEX_H)
+{
+	if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+
+	return -1;
+}
+
+static int afcofs_data_set(struct mb86a16_state *state,
+			   unsigned char AFCEX_L,
+			   unsigned char AFCEX_H)
+{
+	if (mb86a16_write(state, 0x58, AFCEX_L) < 0)
+		goto err;
+	if (mb86a16_write(state, 0x59, AFCEX_H) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int stlp_set(struct mb86a16_state *state,
+		    unsigned char STRAS,
+		    unsigned char STRBS)
+{
+	if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA)
+{
+	if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int initial_set(struct mb86a16_state *state)
+{
+	if (stlp_set(state, 5, 7))
+		goto err;
+
+	udelay(100);
+	if (afcex_data_set(state, 0, 0))
+		goto err;
+
+	udelay(100);
+	if (afcofs_data_set(state, 0, 0))
+		goto err;
+
+	udelay(100);
+	if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0)
+		goto err;
+	if (mb86a16_write(state, 0x2f, 0x21) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0)
+		goto err;
+	if (mb86a16_write(state, 0x54, 0xff) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int S01T_set(struct mb86a16_state *state,
+		    unsigned char s1t,
+		    unsigned s0t)
+{
+	if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+
+static int EN_set(struct mb86a16_state *state,
+		  int cren,
+		  int afcen)
+{
+	unsigned char val;
+
+	val = 0x7a | (cren << 7) | (afcen << 2);
+	if (mb86a16_write(state, 0x49, val) < 0)
+		goto err;
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int AFCEXEN_set(struct mb86a16_state *state,
+		       int afcexen,
+		       int smrt)
+{
+	unsigned char AFCA ;
+
+	if (smrt > 18875)
+		AFCA = 4;
+	else if (smrt > 9375)
+		AFCA = 3;
+	else if (smrt > 2250)
+		AFCA = 2;
+	else
+		AFCA = 1;
+
+	if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int DAGC_data_set(struct mb86a16_state *state,
+			 unsigned char DAGCA,
+			 unsigned char DAGCW)
+{
+	if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static void smrt_info_get(struct mb86a16_state *state, int rate)
+{
+	if (rate >= 37501) {
+		state->deci = 0; state->csel = 0; state->rsel = 0;
+	} else if (rate >= 30001) {
+		state->deci = 0; state->csel = 0; state->rsel = 1;
+	} else if (rate >= 26251) {
+		state->deci = 0; state->csel = 1; state->rsel = 0;
+	} else if (rate >= 22501) {
+		state->deci = 0; state->csel = 1; state->rsel = 1;
+	} else if (rate >= 18751) {
+		state->deci = 1; state->csel = 0; state->rsel = 0;
+	} else if (rate >= 15001) {
+		state->deci = 1; state->csel = 0; state->rsel = 1;
+	} else if (rate >= 13126) {
+		state->deci = 1; state->csel = 1; state->rsel = 0;
+	} else if (rate >= 11251) {
+		state->deci = 1; state->csel = 1; state->rsel = 1;
+	} else if (rate >= 9376) {
+		state->deci = 2; state->csel = 0; state->rsel = 0;
+	} else if (rate >= 7501) {
+		state->deci = 2; state->csel = 0; state->rsel = 1;
+	} else if (rate >= 6563) {
+		state->deci = 2; state->csel = 1; state->rsel = 0;
+	} else if (rate >= 5626) {
+		state->deci = 2; state->csel = 1; state->rsel = 1;
+	} else if (rate >= 4688) {
+		state->deci = 3; state->csel = 0; state->rsel = 0;
+	} else if (rate >= 3751) {
+		state->deci = 3; state->csel = 0; state->rsel = 1;
+	} else if (rate >= 3282) {
+		state->deci = 3; state->csel = 1; state->rsel = 0;
+	} else if (rate >= 2814) {
+		state->deci = 3; state->csel = 1; state->rsel = 1;
+	} else if (rate >= 2344) {
+		state->deci = 4; state->csel = 0; state->rsel = 0;
+	} else if (rate >= 1876) {
+		state->deci = 4; state->csel = 0; state->rsel = 1;
+	} else if (rate >= 1641) {
+		state->deci = 4; state->csel = 1; state->rsel = 0;
+	} else if (rate >= 1407) {
+		state->deci = 4; state->csel = 1; state->rsel = 1;
+	} else if (rate >= 1172) {
+		state->deci = 5; state->csel = 0; state->rsel = 0;
+	} else if (rate >=  939) {
+		state->deci = 5; state->csel = 0; state->rsel = 1;
+	} else if (rate >=  821) {
+		state->deci = 5; state->csel = 1; state->rsel = 0;
+	} else {
+		state->deci = 5; state->csel = 1; state->rsel = 1;
+	}
+
+	if (state->csel == 0)
+		state->master_clk = 92000;
+	else
+		state->master_clk = 61333;
+
+}
+
+static int signal_det(struct mb86a16_state *state,
+		      int smrt,
+		      unsigned char *SIG)
+{
+
+	int ret ;
+	int smrtd ;
+	int wait_sym ;
+
+	u32 wait_t;
+	unsigned char S[3] ;
+	int i ;
+
+	if (*SIG > 45) {
+		if (CNTM_set(state, 2, 1, 2) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+			return -1;
+		}
+		wait_sym = 40000;
+	} else {
+		if (CNTM_set(state, 3, 1, 2) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+			return -1;
+		}
+		wait_sym = 80000;
+	}
+	for (i = 0; i < 3; i++) {
+		if (i == 0)
+			smrtd = smrt * 98 / 100;
+		else if (i == 1)
+			smrtd = smrt;
+		else
+			smrtd = smrt * 102 / 100;
+		smrt_info_get(state, smrtd);
+		smrt_set(state, smrtd);
+		srst(state);
+		wait_t = (wait_sym + 99 * smrtd / 100) / smrtd;
+		if (wait_t == 0)
+			wait_t = 1;
+		msleep_interruptible(10);
+		if (mb86a16_read(state, 0x37, &(S[i])) != 2) {
+			dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+			return -EREMOTEIO;
+		}
+	}
+	if ((S[1] > S[0] * 112 / 100) &&
+	    (S[1] > S[2] * 112 / 100)) {
+
+		ret = 1;
+	} else {
+		ret = 0;
+	}
+	*SIG = S[1];
+
+	if (CNTM_set(state, 0, 1, 2) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+		return -1;
+	}
+
+	return ret;
+}
+
+static int rf_val_set(struct mb86a16_state *state,
+		      int f,
+		      int smrt,
+		      unsigned char R)
+{
+	unsigned char C, F, B;
+	int M;
+	unsigned char rf_val[5];
+	int ack = -1;
+
+	if (smrt > 37750)
+		C = 1;
+	else if (smrt > 18875)
+		C = 2;
+	else if (smrt > 5500)
+		C = 3;
+	else
+		C = 4;
+
+	if (smrt > 30500)
+		F = 3;
+	else if (smrt > 9375)
+		F = 1;
+	else if (smrt > 4625)
+		F = 0;
+	else
+		F = 2;
+
+	if (f < 1060)
+		B = 0;
+	else if (f < 1175)
+		B = 1;
+	else if (f < 1305)
+		B = 2;
+	else if (f < 1435)
+		B = 3;
+	else if (f < 1570)
+		B = 4;
+	else if (f < 1715)
+		B = 5;
+	else if (f < 1845)
+		B = 6;
+	else if (f < 1980)
+		B = 7;
+	else if (f < 2080)
+		B = 8;
+	else
+		B = 9;
+
+	M = f * (1 << R) / 2;
+
+	rf_val[0] = 0x01 | (C << 3) | (F << 1);
+	rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12);
+	rf_val[2] = (M & 0x00ff0) >> 4;
+	rf_val[3] = ((M & 0x0000f) << 4) | B;
+
+	/* Frequency Set */
+	if (mb86a16_write(state, 0x21, rf_val[0]) < 0)
+		ack = 0;
+	if (mb86a16_write(state, 0x22, rf_val[1]) < 0)
+		ack = 0;
+	if (mb86a16_write(state, 0x23, rf_val[2]) < 0)
+		ack = 0;
+	if (mb86a16_write(state, 0x24, rf_val[3]) < 0)
+		ack = 0;
+	if (mb86a16_write(state, 0x25, 0x01) < 0)
+		ack = 0;
+	if (ack == 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int afcerr_chk(struct mb86a16_state *state)
+{
+	unsigned char AFCM_L, AFCM_H ;
+	int AFCM ;
+	int afcm, afcerr ;
+
+	if (mb86a16_read(state, 0x0e, &AFCM_L) != 2)
+		goto err;
+	if (mb86a16_read(state, 0x0f, &AFCM_H) != 2)
+		goto err;
+
+	AFCM = (AFCM_H << 8) + AFCM_L;
+
+	if (AFCM > 2048)
+		afcm = AFCM - 4096;
+	else
+		afcm = AFCM;
+	afcerr = afcm * state->master_clk / 8192;
+
+	return afcerr;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int dagcm_val_get(struct mb86a16_state *state)
+{
+	int DAGCM;
+	unsigned char DAGCM_H, DAGCM_L;
+
+	if (mb86a16_read(state, 0x45, &DAGCM_L) != 2)
+		goto err;
+	if (mb86a16_read(state, 0x46, &DAGCM_H) != 2)
+		goto err;
+
+	DAGCM = (DAGCM_H << 8) + DAGCM_L;
+
+	return DAGCM;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	u8 stat, stat2;
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	*status = 0;
+
+	if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2)
+		goto err;
+	if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2)
+		goto err;
+	if ((stat > 25) && (stat2 > 25))
+		*status |= FE_HAS_SIGNAL;
+	if ((stat > 45) && (stat2 > 45))
+		*status |= FE_HAS_CARRIER;
+
+	if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2)
+		goto err;
+
+	if (stat & 0x01)
+		*status |= FE_HAS_SYNC;
+	if (stat & 0x01)
+		*status |= FE_HAS_VITERBI;
+
+	if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2)
+		goto err;
+
+	if ((stat & 0x0f) && (*status & FE_HAS_VITERBI))
+		*status |= FE_HAS_LOCK;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int sync_chk(struct mb86a16_state *state,
+		    unsigned char *VIRM)
+{
+	unsigned char val;
+	int sync;
+
+	if (mb86a16_read(state, 0x0d, &val) != 2)
+		goto err;
+
+	dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val);
+	sync = val & 0x01;
+	*VIRM = (val & 0x1c) >> 2;
+
+	return sync;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+
+}
+
+static int freqerr_chk(struct mb86a16_state *state,
+		       int fTP,
+		       int smrt,
+		       int unit)
+{
+	unsigned char CRM, AFCML, AFCMH;
+	unsigned char temp1, temp2, temp3;
+	int crm, afcm, AFCM;
+	int crrerr, afcerr;		/* kHz */
+	int frqerr;			/* MHz */
+	int afcen, afcexen = 0;
+	int R, M, fOSC, fOSC_OFS;
+
+	if (mb86a16_read(state, 0x43, &CRM) != 2)
+		goto err;
+
+	if (CRM > 127)
+		crm = CRM - 256;
+	else
+		crm = CRM;
+
+	crrerr = smrt * crm / 256;
+	if (mb86a16_read(state, 0x49, &temp1) != 2)
+		goto err;
+
+	afcen = (temp1 & 0x04) >> 2;
+	if (afcen == 0) {
+		if (mb86a16_read(state, 0x2a, &temp1) != 2)
+			goto err;
+		afcexen = (temp1 & 0x20) >> 5;
+	}
+
+	if (afcen == 1) {
+		if (mb86a16_read(state, 0x0e, &AFCML) != 2)
+			goto err;
+		if (mb86a16_read(state, 0x0f, &AFCMH) != 2)
+			goto err;
+	} else if (afcexen == 1) {
+		if (mb86a16_read(state, 0x2b, &AFCML) != 2)
+			goto err;
+		if (mb86a16_read(state, 0x2c, &AFCMH) != 2)
+			goto err;
+	}
+	if ((afcen == 1) || (afcexen == 1)) {
+		smrt_info_get(state, smrt);
+		AFCM = ((AFCMH & 0x01) << 8) + AFCML;
+		if (AFCM > 255)
+			afcm = AFCM - 512;
+		else
+			afcm = AFCM;
+
+		afcerr = afcm * state->master_clk / 8192;
+	} else
+		afcerr = 0;
+
+	if (mb86a16_read(state, 0x22, &temp1) != 2)
+		goto err;
+	if (mb86a16_read(state, 0x23, &temp2) != 2)
+		goto err;
+	if (mb86a16_read(state, 0x24, &temp3) != 2)
+		goto err;
+
+	R = (temp1 & 0xe0) >> 5;
+	M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4);
+	if (R == 0)
+		fOSC = 2 * M;
+	else
+		fOSC = M;
+
+	fOSC_OFS = fOSC - fTP;
+
+	if (unit == 0) {	/* MHz */
+		if (crrerr + afcerr + fOSC_OFS * 1000 >= 0)
+			frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000;
+		else
+			frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000;
+	} else {	/* kHz */
+		frqerr = crrerr + afcerr + fOSC_OFS * 1000;
+	}
+
+	return frqerr;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt)
+{
+	unsigned char R;
+
+	if (smrt > 9375)
+		R = 0;
+	else
+		R = 1;
+
+	return R;
+}
+
+static void swp_info_get(struct mb86a16_state *state,
+			 int fOSC_start,
+			 int smrt,
+			 int v, int R,
+			 int swp_ofs,
+			 int *fOSC,
+			 int *afcex_freq,
+			 unsigned char *AFCEX_L,
+			 unsigned char *AFCEX_H)
+{
+	int AFCEX ;
+	int crnt_swp_freq ;
+
+	crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs;
+
+	if (R == 0)
+		*fOSC = (crnt_swp_freq + 1000) / 2000 * 2;
+	else
+		*fOSC = (crnt_swp_freq + 500) / 1000;
+
+	if (*fOSC >= crnt_swp_freq)
+		*afcex_freq = *fOSC * 1000 - crnt_swp_freq;
+	else
+		*afcex_freq = crnt_swp_freq - *fOSC * 1000;
+
+	AFCEX = *afcex_freq * 8192 / state->master_clk;
+	*AFCEX_L =  AFCEX & 0x00ff;
+	*AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+
+static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V,  int vmax, int vmin,
+			       int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1)
+{
+	int swp_freq ;
+
+	if ((i % 2 == 1) && (v <= vmax)) {
+		/* positive v (case 1) */
+		if ((v - 1 == vmin)				&&
+		    (*(V + 30 + v) >= 0)			&&
+		    (*(V + 30 + v - 1) >= 0)			&&
+		    (*(V + 30 + v - 1) > *(V + 30 + v))		&&
+		    (*(V + 30 + v - 1) > SIGMIN)) {
+
+			swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+			*SIG1 = *(V + 30 + v - 1);
+		} else if ((v == vmax)				&&
+			   (*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v - 1) >= 0)		&&
+			   (*(V + 30 + v) > *(V + 30 + v - 1))	&&
+			   (*(V + 30 + v) > SIGMIN)) {
+			/* (case 2) */
+			swp_freq = fOSC * 1000 + afcex_freq;
+			*SIG1 = *(V + 30 + v);
+		} else if ((*(V + 30 + v) > 0)			&&
+			   (*(V + 30 + v - 1) > 0)		&&
+			   (*(V + 30 + v - 2) > 0)		&&
+			   (*(V + 30 + v - 3) > 0)		&&
+			   (*(V + 30 + v - 1) > *(V + 30 + v))	&&
+			   (*(V + 30 + v - 2) > *(V + 30 + v - 3)) &&
+			   ((*(V + 30 + v - 1) > SIGMIN)	||
+			   (*(V + 30 + v - 2) > SIGMIN))) {
+			/* (case 3) */
+			if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) {
+				swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+				*SIG1 = *(V + 30 + v - 1);
+			} else {
+				swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2;
+				*SIG1 = *(V + 30 + v - 2);
+			}
+		} else if ((v == vmax)				&&
+			   (*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v - 1) >= 0)		&&
+			   (*(V + 30 + v - 2) >= 0)		&&
+			   (*(V + 30 + v) > *(V + 30 + v - 2))	&&
+			   (*(V + 30 + v - 1) > *(V + 30 + v - 2)) &&
+			   ((*(V + 30 + v) > SIGMIN)		||
+			   (*(V + 30 + v - 1) > SIGMIN))) {
+			/* (case 4) */
+			if (*(V + 30 + v) >= *(V + 30 + v - 1)) {
+				swp_freq = fOSC * 1000 + afcex_freq;
+				*SIG1 = *(V + 30 + v);
+			} else {
+				swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+				*SIG1 = *(V + 30 + v - 1);
+			}
+		} else  {
+			swp_freq = -1 ;
+		}
+	} else if ((i % 2 == 0) && (v >= vmin)) {
+		/* Negative v (case 1) */
+		if ((*(V + 30 + v) > 0)				&&
+		    (*(V + 30 + v + 1) > 0)			&&
+		    (*(V + 30 + v + 2) > 0)			&&
+		    (*(V + 30 + v + 1) > *(V + 30 + v))		&&
+		    (*(V + 30 + v + 1) > *(V + 30 + v + 2))	&&
+		    (*(V + 30 + v + 1) > SIGMIN)) {
+
+			swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+			*SIG1 = *(V + 30 + v + 1);
+		} else if ((v + 1 == vmax)			&&
+			   (*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v + 1) >= 0)		&&
+			   (*(V + 30 + v + 1) > *(V + 30 + v))	&&
+			   (*(V + 30 + v + 1) > SIGMIN)) {
+			/* (case 2) */
+			swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+			*SIG1 = *(V + 30 + v);
+		} else if ((v == vmin)				&&
+			   (*(V + 30 + v) > 0)			&&
+			   (*(V + 30 + v + 1) > 0)		&&
+			   (*(V + 30 + v + 2) > 0)		&&
+			   (*(V + 30 + v) > *(V + 30 + v + 1))	&&
+			   (*(V + 30 + v) > *(V + 30 + v + 2))	&&
+			   (*(V + 30 + v) > SIGMIN)) {
+			/* (case 3) */
+			swp_freq = fOSC * 1000 + afcex_freq;
+			*SIG1 = *(V + 30 + v);
+		} else if ((*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v + 1) >= 0)		&&
+			   (*(V + 30 + v + 2) >= 0)		&&
+			   (*(V + 30 + v + 3) >= 0)		&&
+			   (*(V + 30 + v + 1) > *(V + 30 + v))	&&
+			   (*(V + 30 + v + 2) > *(V + 30 + v + 3)) &&
+			   ((*(V + 30 + v + 1) > SIGMIN)	||
+			    (*(V + 30 + v + 2) > SIGMIN))) {
+			/* (case 4) */
+			if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
+				swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+				*SIG1 = *(V + 30 + v + 1);
+			} else {
+				swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
+				*SIG1 = *(V + 30 + v + 2);
+			}
+		} else if ((*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v + 1) >= 0)		&&
+			   (*(V + 30 + v + 2) >= 0)		&&
+			   (*(V + 30 + v + 3) >= 0)		&&
+			   (*(V + 30 + v) > *(V + 30 + v + 2))	&&
+			   (*(V + 30 + v + 1) > *(V + 30 + v + 2)) &&
+			   (*(V + 30 + v) > *(V + 30 + v + 3))	&&
+			   (*(V + 30 + v + 1) > *(V + 30 + v + 3)) &&
+			   ((*(V + 30 + v) > SIGMIN)		||
+			    (*(V + 30 + v + 1) > SIGMIN))) {
+			/* (case 5) */
+			if (*(V + 30 + v) >= *(V + 30 + v + 1)) {
+				swp_freq = fOSC * 1000 + afcex_freq;
+				*SIG1 = *(V + 30 + v);
+			} else {
+				swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+				*SIG1 = *(V + 30 + v + 1);
+			}
+		} else if ((v + 2 == vmin)			&&
+			   (*(V + 30 + v) >= 0)			&&
+			   (*(V + 30 + v + 1) >= 0)		&&
+			   (*(V + 30 + v + 2) >= 0)		&&
+			   (*(V + 30 + v + 1) > *(V + 30 + v))	&&
+			   (*(V + 30 + v + 2) > *(V + 30 + v))	&&
+			   ((*(V + 30 + v + 1) > SIGMIN)	||
+			    (*(V + 30 + v + 2) > SIGMIN))) {
+			/* (case 6) */
+			if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
+				swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+				*SIG1 = *(V + 30 + v + 1);
+			} else {
+				swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
+				*SIG1 = *(V + 30 + v + 2);
+			}
+		} else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) {
+			swp_freq = fOSC * 1000;
+			*SIG1 = *(V + 30 + v);
+		} else
+			swp_freq = -1;
+	} else
+		swp_freq = -1;
+
+	return swp_freq;
+}
+
+static void swp_info_get2(struct mb86a16_state *state,
+			  int smrt,
+			  int R,
+			  int swp_freq,
+			  int *afcex_freq,
+			  int *fOSC,
+			  unsigned char *AFCEX_L,
+			  unsigned char *AFCEX_H)
+{
+	int AFCEX ;
+
+	if (R == 0)
+		*fOSC = (swp_freq + 1000) / 2000 * 2;
+	else
+		*fOSC = (swp_freq + 500) / 1000;
+
+	if (*fOSC >= swp_freq)
+		*afcex_freq = *fOSC * 1000 - swp_freq;
+	else
+		*afcex_freq = swp_freq - *fOSC * 1000;
+
+	AFCEX = *afcex_freq * 8192 / state->master_clk;
+	*AFCEX_L =  AFCEX & 0x00ff;
+	*AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+static void afcex_info_get(struct mb86a16_state *state,
+			   int afcex_freq,
+			   unsigned char *AFCEX_L,
+			   unsigned char *AFCEX_H)
+{
+	int AFCEX ;
+
+	AFCEX = afcex_freq * 8192 / state->master_clk;
+	*AFCEX_L =  AFCEX & 0x00ff;
+	*AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+static int SEQ_set(struct mb86a16_state *state, unsigned char loop)
+{
+	/* SLOCK0 = 0 */
+	if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV)
+{
+	/* Viterbi Rate, IQ Settings */
+	if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int FEC_srst(struct mb86a16_state *state)
+{
+	if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int S2T_set(struct mb86a16_state *state, unsigned char S2T)
+{
+	if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T)
+{
+	if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+
+static int mb86a16_set_fe(struct mb86a16_state *state)
+{
+	u8 agcval, cnmval;
+
+	int i, j;
+	int fOSC = 0;
+	int fOSC_start = 0;
+	int wait_t;
+	int fcp;
+	int swp_ofs;
+	int V[60];
+	u8 SIG1MIN;
+
+	unsigned char CREN, AFCEN, AFCEXEN;
+	unsigned char SIG1;
+	unsigned char TIMINT1, TIMINT2, TIMEXT;
+	unsigned char S0T, S1T;
+	unsigned char S2T;
+/*	unsigned char S2T, S3T; */
+	unsigned char S4T, S5T;
+	unsigned char AFCEX_L, AFCEX_H;
+	unsigned char R;
+	unsigned char VIRM;
+	unsigned char ETH, VIA;
+	unsigned char junk;
+
+	int loop;
+	int ftemp;
+	int v, vmax, vmin;
+	int vmax_his, vmin_his;
+	int swp_freq, prev_swp_freq[20];
+	int prev_freq_num;
+	int signal_dupl;
+	int afcex_freq;
+	int signal;
+	int afcerr;
+	int temp_freq, delta_freq;
+	int dagcm[4];
+	int smrt_d;
+/*	int freq_err; */
+	int n;
+	int ret = -1;
+	int sync;
+
+	dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate);
+
+	fcp = 3000;
+	swp_ofs = state->srate / 4;
+
+	for (i = 0; i < 60; i++)
+		V[i] = -1;
+
+	for (i = 0; i < 20; i++)
+		prev_swp_freq[i] = 0;
+
+	SIG1MIN = 25;
+
+	for (n = 0; ((n < 3) && (ret == -1)); n++) {
+		SEQ_set(state, 0);
+		iq_vt_set(state, 0);
+
+		CREN = 0;
+		AFCEN = 0;
+		AFCEXEN = 1;
+		TIMINT1 = 0;
+		TIMINT2 = 1;
+		TIMEXT = 2;
+		S1T = 0;
+		S0T = 0;
+
+		if (initial_set(state) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "initial set failed");
+			return -1;
+		}
+		if (DAGC_data_set(state, 3, 2) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+			return -1;
+		}
+		if (EN_set(state, CREN, AFCEN) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+			return -1; /* (0, 0) */
+		}
+		if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+			return -1; /* (1, smrt) = (1, symbolrate) */
+		}
+		if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error");
+			return -1; /* (0, 1, 2) */
+		}
+		if (S01T_set(state, S1T, S0T) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+			return -1; /* (0, 0) */
+		}
+		smrt_info_get(state, state->srate);
+		if (smrt_set(state, state->srate) < 0) {
+			dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error");
+			return -1;
+		}
+
+		R = vco_dev_get(state, state->srate);
+		if (R == 1)
+			fOSC_start = state->frequency;
+
+		else if (R == 0) {
+			if (state->frequency % 2 == 0) {
+				fOSC_start = state->frequency;
+			} else {
+				fOSC_start = state->frequency + 1;
+				if (fOSC_start > 2150)
+					fOSC_start = state->frequency - 1;
+			}
+		}
+		loop = 1;
+		ftemp = fOSC_start * 1000;
+		vmax = 0 ;
+		while (loop == 1) {
+			ftemp = ftemp + swp_ofs;
+			vmax++;
+
+			/* Upper bound */
+			if (ftemp > 2150000) {
+				loop = 0;
+				vmax--;
+			} else {
+				if ((ftemp == 2150000) ||
+				    (ftemp - state->frequency * 1000 >= fcp + state->srate / 4))
+					loop = 0;
+			}
+		}
+
+		loop = 1;
+		ftemp = fOSC_start * 1000;
+		vmin = 0 ;
+		while (loop == 1) {
+			ftemp = ftemp - swp_ofs;
+			vmin--;
+
+			/* Lower bound */
+			if (ftemp < 950000) {
+				loop = 0;
+				vmin++;
+			} else {
+				if ((ftemp == 950000) ||
+				    (state->frequency * 1000 - ftemp >= fcp + state->srate / 4))
+					loop = 0;
+			}
+		}
+
+		wait_t = (8000 + state->srate / 2) / state->srate;
+		if (wait_t == 0)
+			wait_t = 1;
+
+		i = 0;
+		j = 0;
+		prev_freq_num = 0;
+		loop = 1;
+		signal = 0;
+		vmax_his = 0;
+		vmin_his = 0;
+		v = 0;
+
+		while (loop == 1) {
+			swp_info_get(state, fOSC_start, state->srate,
+				     v, R, swp_ofs, &fOSC,
+				     &afcex_freq, &AFCEX_L, &AFCEX_H);
+
+			udelay(100);
+			if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+				return -1;
+			}
+			udelay(100);
+			if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+				return -1;
+			}
+			if (srst(state) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+				return -1;
+			}
+			msleep_interruptible(wait_t);
+
+			if (mb86a16_read(state, 0x37, &SIG1) != 2) {
+				dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+				return -1;
+			}
+			V[30 + v] = SIG1 ;
+			swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin,
+						      SIG1MIN, fOSC, afcex_freq,
+						      swp_ofs, &SIG1);	/* changed */
+
+			signal_dupl = 0;
+			for (j = 0; j < prev_freq_num; j++) {
+				if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) {
+					signal_dupl = 1;
+					dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j);
+				}
+			}
+			if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) {
+				dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate);
+				prev_swp_freq[prev_freq_num] = swp_freq;
+				prev_freq_num++;
+				swp_info_get2(state, state->srate, R, swp_freq,
+					      &afcex_freq, &fOSC,
+					      &AFCEX_L, &AFCEX_H);
+
+				if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+					return -1;
+				}
+				if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+					return -1;
+				}
+				signal = signal_det(state, state->srate, &SIG1);
+				if (signal == 1) {
+					dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****");
+					loop = 0;
+				} else {
+					dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again...");
+					smrt_info_get(state, state->srate);
+					if (smrt_set(state, state->srate) < 0) {
+						dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+						return -1;
+					}
+				}
+			}
+			if (v > vmax)
+				vmax_his = 1 ;
+			if (v < vmin)
+				vmin_his = 1 ;
+			i++;
+
+			if ((i % 2 == 1) && (vmax_his == 1))
+				i++;
+			if ((i % 2 == 0) && (vmin_his == 1))
+				i++;
+
+			if (i % 2 == 1)
+				v = (i + 1) / 2;
+			else
+				v = -i / 2;
+
+			if ((vmax_his == 1) && (vmin_his == 1))
+				loop = 0 ;
+		}
+
+		if (signal == 1) {
+			dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check");
+			S1T = 7 ;
+			S0T = 1 ;
+			CREN = 0 ;
+			AFCEN = 1 ;
+			AFCEXEN = 0 ;
+
+			if (S01T_set(state, S1T, S0T) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+				return -1;
+			}
+			smrt_info_get(state, state->srate);
+			if (smrt_set(state, state->srate) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+				return -1;
+			}
+			if (EN_set(state, CREN, AFCEN) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+				return -1;
+			}
+			if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+				return -1;
+			}
+			afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H);
+			if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error");
+				return -1;
+			}
+			if (srst(state) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+				return -1;
+			}
+			/* delay 4~200 */
+			wait_t = 200000 / state->master_clk + 200000 / state->srate;
+			msleep(wait_t);
+			afcerr = afcerr_chk(state);
+			if (afcerr == -1)
+				return -1;
+
+			swp_freq = fOSC * 1000 + afcerr ;
+			AFCEXEN = 1 ;
+			if (state->srate >= 1500)
+				smrt_d = state->srate / 3;
+			else
+				smrt_d = state->srate / 2;
+			smrt_info_get(state, smrt_d);
+			if (smrt_set(state, smrt_d) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+				return -1;
+			}
+			if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+				return -1;
+			}
+			R = vco_dev_get(state, smrt_d);
+			if (DAGC_data_set(state, 2, 0) < 0) {
+				dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+				return -1;
+			}
+			for (i = 0; i < 3; i++) {
+				temp_freq = swp_freq + (i - 1) * state->srate / 8;
+				swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+				if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+					return -1;
+				}
+				if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+					return -1;
+				}
+				wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+				msleep(wait_t);
+				dagcm[i] = dagcm_val_get(state);
+			}
+			if ((dagcm[0] > dagcm[1]) &&
+			    (dagcm[0] > dagcm[2]) &&
+			    (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) {
+
+				temp_freq = swp_freq - 2 * state->srate / 8;
+				swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+				if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+					return -1;
+				}
+				if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
+					return -1;
+				}
+				wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+				msleep(wait_t);
+				dagcm[3] = dagcm_val_get(state);
+				if (dagcm[3] > dagcm[1])
+					delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300;
+				else
+					delta_freq = 0;
+			} else if ((dagcm[2] > dagcm[1]) &&
+				   (dagcm[2] > dagcm[0]) &&
+				   (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) {
+
+				temp_freq = swp_freq + 2 * state->srate / 8;
+				swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+				if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "rf val set");
+					return -1;
+				}
+				if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
+					return -1;
+				}
+				wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+				msleep(wait_t);
+				dagcm[3] = dagcm_val_get(state);
+				if (dagcm[3] > dagcm[1])
+					delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300;
+				else
+					delta_freq = 0 ;
+
+			} else {
+				delta_freq = 0 ;
+			}
+			dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq);
+			swp_freq += delta_freq;
+			dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq);
+			if (ABS(state->frequency * 1000 - swp_freq) > 3800) {
+				dprintk(verbose, MB86A16_INFO, 1, "NO  --  SIGNAL !");
+			} else {
+
+				S1T = 0;
+				S0T = 3;
+				CREN = 1;
+				AFCEN = 0;
+				AFCEXEN = 1;
+
+				if (S01T_set(state, S1T, S0T) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+					return -1;
+				}
+				if (DAGC_data_set(state, 0, 0) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+					return -1;
+				}
+				R = vco_dev_get(state, state->srate);
+				smrt_info_get(state, state->srate);
+				if (smrt_set(state, state->srate) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+					return -1;
+				}
+				if (EN_set(state, CREN, AFCEN) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+					return -1;
+				}
+				if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+					return -1;
+				}
+				swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+				if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+					return -1;
+				}
+				if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+					return -1;
+				}
+				if (srst(state) < 0) {
+					dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+					return -1;
+				}
+				wait_t = 7 + (10000 + state->srate / 2) / state->srate;
+				if (wait_t == 0)
+					wait_t = 1;
+				msleep_interruptible(wait_t);
+				if (mb86a16_read(state, 0x37, &SIG1) != 2) {
+					dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+					return -EREMOTEIO;
+				}
+
+				if (SIG1 > 110) {
+					S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6;
+					wait_t = 7 + (917504 + state->srate / 2) / state->srate;
+				} else if (SIG1 > 105) {
+					S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+					wait_t = 7 + (1048576 + state->srate / 2) / state->srate;
+				} else if (SIG1 > 85) {
+					S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+					wait_t = 7 + (1310720 + state->srate / 2) / state->srate;
+				} else if (SIG1 > 65) {
+					S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+					wait_t = 7 + (1572864 + state->srate / 2) / state->srate;
+				} else {
+					S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+					wait_t = 7 + (2097152 + state->srate / 2) / state->srate;
+				}
+				wait_t *= 2; /* FOS */
+				S2T_set(state, S2T);
+				S45T_set(state, S4T, S5T);
+				Vi_set(state, ETH, VIA);
+				srst(state);
+				msleep_interruptible(wait_t);
+				sync = sync_chk(state, &VIRM);
+				dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync);
+				if (VIRM) {
+					if (VIRM == 4) {
+						/* 5/6 */
+						if (SIG1 > 110)
+							wait_t = (786432 + state->srate / 2) / state->srate;
+						else
+							wait_t = (1572864 + state->srate / 2) / state->srate;
+						if (state->srate < 5000)
+							/* FIXME ! , should be a long wait ! */
+							msleep_interruptible(wait_t);
+						else
+							msleep_interruptible(wait_t);
+
+						if (sync_chk(state, &junk) == 0) {
+							iq_vt_set(state, 1);
+							FEC_srst(state);
+						}
+					}
+					/* 1/2, 2/3, 3/4, 7/8 */
+					if (SIG1 > 110)
+						wait_t = (786432 + state->srate / 2) / state->srate;
+					else
+						wait_t = (1572864 + state->srate / 2) / state->srate;
+					msleep_interruptible(wait_t);
+					SEQ_set(state, 1);
+				} else {
+					dprintk(verbose, MB86A16_INFO, 1, "NO  -- SYNC");
+					SEQ_set(state, 1);
+					ret = -1;
+				}
+			}
+		} else {
+			dprintk(verbose, MB86A16_INFO, 1, "NO  -- SIGNAL");
+			ret = -1;
+		}
+
+		sync = sync_chk(state, &junk);
+		if (sync) {
+			dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******");
+			freqerr_chk(state, state->frequency, state->srate, 1);
+			ret = 0;
+			break;
+		}
+	}
+
+	mb86a16_read(state, 0x15, &agcval);
+	mb86a16_read(state, 0x26, &cnmval);
+	dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval);
+
+	return ret;
+}
+
+static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
+				   struct dvb_diseqc_master_cmd *cmd)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+	int i;
+	u8 regs;
+
+	if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
+		goto err;
+
+	regs = 0x18;
+
+	if (cmd->msg_len > 5 || cmd->msg_len < 4)
+		return -EINVAL;
+
+	for (i = 0; i < cmd->msg_len; i++) {
+		if (mb86a16_write(state, regs, cmd->msg[i]) < 0)
+			goto err;
+
+		regs++;
+	}
+	i += 0x90;
+
+	msleep_interruptible(10);
+
+	if (mb86a16_write(state, MB86A16_DCC1, i) < 0)
+		goto err;
+	if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	switch (burst) {
+	case SEC_MINI_A:
+		if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+						       MB86A16_DCC1_TBEN  |
+						       MB86A16_DCC1_TBO) < 0)
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+			goto err;
+		break;
+	case SEC_MINI_B:
+		if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+						       MB86A16_DCC1_TBEN) < 0)
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+			goto err;
+		break;
+	}
+
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	switch (tone) {
+	case SEC_TONE_ON:
+		if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0)
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+						       MB86A16_DCC1_CTOE) < 0)
+
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+			goto err;
+		break;
+	case SEC_TONE_OFF:
+		if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
+			goto err;
+		if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
+			goto err;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe,
+					struct dvb_frontend_parameters *p)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	state->frequency = p->frequency / 1000;
+	state->srate = p->u.qpsk.symbol_rate / 1000;
+
+	if (!mb86a16_set_fe(state)) {
+		dprintk(verbose, MB86A16_ERROR, 1, "Succesfully acquired LOCK");
+		return DVBFE_ALGO_SEARCH_SUCCESS;
+	}
+
+	dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!");
+	return DVBFE_ALGO_SEARCH_FAILED;
+}
+
+static void mb86a16_release(struct dvb_frontend *fe)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static int mb86a16_init(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static int mb86a16_sleep(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst;
+	u32 timer;
+
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	*ber = 0;
+	if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2)
+		goto err;
+	if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2)
+		goto err;
+	if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2)
+		goto err;
+	if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2)
+		goto err;
+	if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2)
+		goto err;
+	/* BER monitor invalid when BER_EN = 0	*/
+	if (ber_mon & 0x04) {
+		/* coarse, fast calculation	*/
+		*ber = ber_tab & 0x1f;
+		dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber);
+		if (ber_mon & 0x01) {
+			/*
+			 * BER_SEL = 1, The monitored BER is the estimated
+			 * value with a Reed-Solomon decoder error amount at
+			 * the deinterleaver output.
+			 * monitored BER is expressed as a 20 bit output in total
+			 */
+			ber_rst = ber_mon >> 3;
+			*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
+			if (ber_rst == 0)
+				timer =  12500000;
+			if (ber_rst == 1)
+				timer =  25000000;
+			if (ber_rst == 2)
+				timer =  50000000;
+			if (ber_rst == 3)
+				timer = 100000000;
+
+			*ber /= timer;
+			dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
+		} else {
+			/*
+			 * BER_SEL = 0, The monitored BER is the estimated
+			 * value with a Viterbi decoder error amount at the
+			 * QPSK demodulator output.
+			 * monitored BER is expressed as a 24 bit output in total
+			 */
+			ber_tim = ber_mon >> 1;
+			*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
+			if (ber_tim == 0)
+				timer = 16;
+			if (ber_tim == 1)
+				timer = 24;
+
+			*ber /= 2 ^ timer;
+			dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
+		}
+	}
+	return 0;
+err:
+	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	return -EREMOTEIO;
+}
+
+static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	u8 agcm = 0;
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	*strength = 0;
+	if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	*strength = ((0xff - agcm) * 100) / 256;
+	dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength);
+	*strength = (0xffff - 0xff) + agcm;
+
+	return 0;
+}
+
+struct cnr {
+	u8 cn_reg;
+	u8 cn_val;
+};
+
+static const struct cnr cnr_tab[] = {
+	{  35,  2 },
+	{  40,  3 },
+	{  50,  4 },
+	{  60,  5 },
+	{  70,  6 },
+	{  80,  7 },
+	{  92,  8 },
+	{ 103,  9 },
+	{ 115, 10 },
+	{ 138, 12 },
+	{ 162, 15 },
+	{ 180, 18 },
+	{ 185, 19 },
+	{ 189, 20 },
+	{ 195, 22 },
+	{ 199, 24 },
+	{ 201, 25 },
+	{ 202, 26 },
+	{ 203, 27 },
+	{ 205, 28 },
+	{ 208, 30 }
+};
+
+static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct mb86a16_state *state = fe->demodulator_priv;
+	int i = 0;
+	int low_tide = 2, high_tide = 30, q_level;
+	u8  cn;
+
+	*snr = 0;
+	if (mb86a16_read(state, 0x26, &cn) != 2) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) {
+		if (cn < cnr_tab[i].cn_reg) {
+			*snr = cnr_tab[i].cn_val;
+			break;
+		}
+	}
+	q_level = (*snr * 100) / (high_tide - low_tide);
+	dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level);
+	*snr = (0xffff - 0xff) + *snr;
+
+	return 0;
+}
+
+static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	u8 dist;
+	struct mb86a16_state *state = fe->demodulator_priv;
+
+	if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) {
+		dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+		return -EREMOTEIO;
+	}
+	*ucblocks = dist;
+
+	return 0;
+}
+
+static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_CUSTOM;
+}
+
+static struct dvb_frontend_ops mb86a16_ops = {
+	.info = {
+		.name			= "Fujitsu MB86A16 DVB-S",
+		.type			= FE_QPSK,
+		.frequency_min		= 950000,
+		.frequency_max		= 2150000,
+		.frequency_stepsize	= 3000,
+		.frequency_tolerance	= 0,
+		.symbol_rate_min	= 1000000,
+		.symbol_rate_max	= 45000000,
+		.symbol_rate_tolerance	= 500,
+		.caps			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+					  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+					  FE_CAN_FEC_7_8 | FE_CAN_QPSK    |
+					  FE_CAN_FEC_AUTO
+	},
+	.release			= mb86a16_release,
+
+	.get_frontend_algo		= mb86a16_frontend_algo,
+	.search				= mb86a16_search,
+	.read_status			= mb86a16_read_status,
+	.init				= mb86a16_init,
+	.sleep				= mb86a16_sleep,
+	.read_status			= mb86a16_read_status,
+
+	.read_ber			= mb86a16_read_ber,
+	.read_signal_strength		= mb86a16_read_signal_strength,
+	.read_snr			= mb86a16_read_snr,
+	.read_ucblocks			= mb86a16_read_ucblocks,
+
+	.diseqc_send_master_cmd		= mb86a16_send_diseqc_msg,
+	.diseqc_send_burst		= mb86a16_send_diseqc_burst,
+	.set_tone			= mb86a16_set_tone,
+};
+
+struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+				    struct i2c_adapter *i2c_adap)
+{
+	u8 dev_id = 0;
+	struct mb86a16_state *state = NULL;
+
+	state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	state->config = config;
+	state->i2c_adap = i2c_adap;
+
+	mb86a16_read(state, 0x7f, &dev_id);
+	if (dev_id != 0xfe)
+		goto error;
+
+	memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+	state->frontend.ops.set_voltage = state->config->set_voltage;
+
+	return &state->frontend;
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(mb86a16_attach);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Manu Abraham");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+	Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MB86A16_H
+#define __MB86A16_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+
+struct mb86a16_config {
+	u8 demod_address;
+
+	int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
+};
+
+
+
+#if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+					   struct i2c_adapter *i2c_adap);
+
+#else
+
+static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+					   struct i2c_adapter *i2c_adap)
+{
+	printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+#endif /* CONFIG_DVB_MB86A16 */
+
+#endif /* __MB86A16_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/mb86a16_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/mb86a16_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,151 @@
+/*
+	Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MB86A16_PRIV_H
+#define __MB86A16_PRIV_H
+
+#define MB86A16_TSOUT		0x00
+#define MB86A16_TSOUT_HIZSEL	(0x01 << 5)
+#define MB86A16_TSOUT_HIZCNTI	(0x01 << 4)
+#define MB86A16_TSOUT_MODE	(0x01 << 3)
+#define MB86A16_TSOUT_ORDER	(0x01 << 2)
+#define MB86A16_TSOUT_ERROR	(0x01 << 1)
+#define Mb86A16_TSOUT_EDGE	(0x01 << 0)
+
+#define MB86A16_FEC		0x01
+#define MB86A16_FEC_FSYNC	(0x01 << 5)
+#define MB86A16_FEC_PCKB8	(0x01 << 4)
+#define MB86A16_FEC_DVDS	(0x01 << 3)
+#define MB86A16_FEC_EREN	(0x01 << 2)
+#define Mb86A16_FEC_RSEN	(0x01 << 1)
+#define MB86A16_FEC_DIEN	(0x01 << 0)
+
+#define MB86A16_AGC		0x02
+#define MB86A16_AGC_AGMD	(0x01 << 6)
+#define MB86A16_AGC_AGCW	(0x0f << 2)
+#define MB86A16_AGC_AGCP	(0x01 << 1)
+#define MB86A16_AGC_AGCR	(0x01 << 0)
+
+#define MB86A16_SRATE1		0x03
+#define MB86A16_SRATE1_DECI	(0x07 << 2)
+#define MB86A16_SRATE1_CSEL	(0x01 << 1)
+#define MB86A16_SRATE1_RSEL	(0x01 << 0)
+
+#define MB86A16_SRATE2		0x04
+#define MB86A16_SRATE2_STOFSL	(0xff << 0)
+
+#define MB86A16_SRATE3		0x05
+#define MB86A16_SRATE2_STOFSH	(0xff << 0)
+
+#define MB86A16_VITERBI		0x06
+#define MB86A16_FRAMESYNC	0x07
+#define MB86A16_CRLFILTCOEF1	0x08
+#define MB86A16_CRLFILTCOEF2	0x09
+#define MB86A16_STRFILTCOEF1	0x0a
+#define MB86A16_STRFILTCOEF2	0x0b
+#define MB86A16_RESET		0x0c
+#define MB86A16_STATUS		0x0d
+#define MB86A16_AFCML		0x0e
+#define MB86A16_AFCMH		0x0f
+#define MB86A16_BERMON		0x10
+#define MB86A16_BERTAB		0x11
+#define MB86A16_BERLSB		0x12
+#define MB86A16_BERMID		0x13
+#define MB86A16_BERMSB		0x14
+#define MB86A16_AGCM		0x15
+
+#define MB86A16_DCC1		0x16
+#define MB86A16_DCC1_DISTA	(0x01 << 7)
+#define MB86A16_DCC1_PRTY	(0x01 << 6)
+#define MB86A16_DCC1_CTOE	(0x01 << 5)
+#define MB86A16_DCC1_TBEN	(0x01 << 4)
+#define MB86A16_DCC1_TBO	(0x01 << 3)
+#define MB86A16_DCC1_NUM	(0x07 << 0)
+
+#define MB86A16_DCC2		0x17
+#define MB86A16_DCC2_DCBST	(0x01 << 0)
+
+#define MB86A16_DCC3		0x18
+#define MB86A16_DCC3_CODE0	(0xff << 0)
+
+#define MB86A16_DCC4		0x19
+#define MB86A16_DCC4_CODE1	(0xff << 0)
+
+#define MB86A16_DCC5		0x1a
+#define MB86A16_DCC5_CODE2	(0xff << 0)
+
+#define MB86A16_DCC6		0x1b
+#define MB86A16_DCC6_CODE3	(0xff << 0)
+
+#define MB86A16_DCC7		0x1c
+#define MB86A16_DCC7_CODE4	(0xff << 0)
+
+#define MB86A16_DCC8		0x1d
+#define MB86A16_DCC8_CODE5	(0xff << 0)
+
+#define MB86A16_DCCOUT		0x1e
+#define MB86A16_DCCOUT_DISEN	(0x01 << 0)
+
+#define MB86A16_TONEOUT1	0x1f
+#define MB86A16_TONE_TDIVL	(0xff << 0)
+
+#define MB86A16_TONEOUT2	0x20
+#define MB86A16_TONE_TMD	(0x03 << 2)
+#define MB86A16_TONE_TDIVH	(0x03 << 0)
+
+#define MB86A16_FREQ1		0x21
+#define MB86A16_FREQ2		0x22
+#define MB86A16_FREQ3		0x23
+#define MB86A16_FREQ4		0x24
+#define MB86A16_FREQSET		0x25
+#define MB86A16_CNM		0x26
+#define MB86A16_PORT0		0x27
+#define MB86A16_PORT1		0x28
+#define MB86A16_DRCFILT		0x29
+#define MB86A16_AFC		0x2a
+#define MB86A16_AFCEXL		0x2b
+#define MB86A16_AFCEXH		0x2c
+#define MB86A16_DAGC		0x2d
+#define MB86A16_SEQMODE		0x32
+#define MB86A16_S0S1T		0x33
+#define MB86A16_S2S3T		0x34
+#define MB86A16_S4S5T		0x35
+#define MB86A16_CNTMR		0x36
+#define MB86A16_SIG1		0x37
+#define MB86A16_SIG2		0x38
+#define MB86A16_VIMAG		0x39
+#define MB86A16_VISET1		0x3a
+#define MB86A16_VISET2		0x3b
+#define MB86A16_VISET3		0x3c
+#define MB86A16_FAGCS1		0x3d
+#define MB86A16_FAGCS2		0x3e
+#define MB86A16_FAGCS3		0x3f
+#define MB86A16_FAGCS4		0x40
+#define MB86A16_FAGCS5		0x41
+#define MB86A16_FAGCS6		0x42
+#define MB86A16_CRM		0x43
+#define MB86A16_STRM		0x44
+#define MB86A16_DAGCML		0x45
+#define MB86A16_DAGCMH		0x46
+#define MB86A16_QPSKTST		0x49
+#define MB86A16_DISTMON		0x52
+#define MB86A16_VERSION		0x7f
+
+#endif /* __MB86A16_PRIV_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/s5h1409.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s5h1409.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/s5h1409.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s5h1409.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,15 @@ struct s5h1409_state {
 	int if_freq;
 
 	u32 is_qam_locked;
-	u32 qam_state;
+
+	/* QAM tuning state goes through the following state transitions */
+#define QAM_STATE_UNTUNED 0
+#define QAM_STATE_TUNING_STARTED 1
+#define QAM_STATE_INTERLEAVE_SET 2
+#define QAM_STATE_QAM_OPTIMIZED_L1 3
+#define QAM_STATE_QAM_OPTIMIZED_L2 4
+#define QAM_STATE_QAM_OPTIMIZED_L3 5
+	u8  qam_state;
 };
 
 static int debug;
@@ -347,7 +355,7 @@ static int s5h1409_softreset(struct dvb_
 	s5h1409_writereg(state, 0xf5, 0);
 	s5h1409_writereg(state, 0xf5, 1);
 	state->is_qam_locked = 0;
-	state->qam_state = 0;
+	state->qam_state = QAM_STATE_UNTUNED;
 	return 0;
 }
 
@@ -474,6 +482,59 @@ static void s5h1409_set_qam_amhum_mode(s
 	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg;
 
+	if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
+		/* We should not perform amhum optimization until
+		   the interleave mode has been configured */
+		return;
+	}
+
+	if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
+		/* We've already reached the maximum optimization level, so
+		   dont bother banging on the status registers */
+		return;
+	}
+
+	/* QAM EQ lock check */
+	reg = s5h1409_readreg(state, 0xf0);
+
+	if ((reg >> 13) & 0x1) {
+		reg &= 0xff;
+
+		s5h1409_writereg(state, 0x96, 0x000c);
+		if (reg < 0x68) {
+			if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
+				dprintk("%s() setting QAM state to OPT_L3\n",
+					__func__);
+				s5h1409_writereg(state, 0x93, 0x3130);
+				s5h1409_writereg(state, 0x9e, 0x2836);
+				state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
+			}
+		} else {
+			if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
+				dprintk("%s() setting QAM state to OPT_L2\n",
+					__func__);
+				s5h1409_writereg(state, 0x93, 0x3332);
+				s5h1409_writereg(state, 0x9e, 0x2c37);
+				state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
+			}
+		}
+
+	} else {
+		if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
+			dprintk("%s() setting QAM state to OPT_L1\n", __func__);
+			s5h1409_writereg(state, 0x96, 0x0008);
+			s5h1409_writereg(state, 0x93, 0x3332);
+			s5h1409_writereg(state, 0x9e, 0x2c37);
+			state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
+		}
+	}
+}
+
+static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
+{
+	struct s5h1409_state *state = fe->demodulator_priv;
+	u16 reg;
+
 	if (state->is_qam_locked)
 		return;
 
@@ -506,6 +567,44 @@ static void s5h1409_set_qam_interleave_m
 	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg, reg1, reg2;
 
+	if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
+		/* We've done the optimization already */
+		return;
+	}
+
+	reg = s5h1409_readreg(state, 0xf1);
+
+	/* Master lock */
+	if ((reg >> 15) & 0x1) {
+		if (state->qam_state == QAM_STATE_UNTUNED ||
+		    state->qam_state == QAM_STATE_TUNING_STARTED) {
+			dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
+				__func__);
+			reg1 = s5h1409_readreg(state, 0xb2);
+			reg2 = s5h1409_readreg(state, 0xad);
+
+			s5h1409_writereg(state, 0x96, 0x0020);
+			s5h1409_writereg(state, 0xad,
+				(((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
+			state->qam_state = QAM_STATE_INTERLEAVE_SET;
+		}
+	} else {
+		if (state->qam_state == QAM_STATE_UNTUNED) {
+			dprintk("%s() setting QAM state to TUNING_STARTED\n",
+				__func__);
+			s5h1409_writereg(state, 0x96, 0x08);
+			s5h1409_writereg(state, 0xab,
+				s5h1409_readreg(state, 0xab) | 0x1001);
+			state->qam_state = QAM_STATE_TUNING_STARTED;
+		}
+	}
+}
+
+static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
+{
+	struct s5h1409_state *state = fe->demodulator_priv;
+	u16 reg, reg1, reg2;
+
 	reg = s5h1409_readreg(state, 0xf1);
 
 	/* Master lock */
@@ -553,16 +652,24 @@ static int s5h1409_set_frontend(struct d
 			fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
-	/* Optimize the demod for QAM */
-	if (p->u.vsb.modulation != VSB_8) {
-		s5h1409_set_qam_amhum_mode(fe);
-		s5h1409_set_qam_interleave_mode(fe);
-	}
-
 	/* Issue a reset to the demod so it knows to resync against the
 	   newly tuned frequency */
 	s5h1409_softreset(fe);
 
+	/* Optimize the demod for QAM */
+	if (state->current_modulation != VSB_8) {
+		/* This almost certainly applies to all boards, but for now
+		   only do it for the HVR-1600.  Once the other boards are
+		   tested, the "legacy" versions can just go away */
+		if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+			s5h1409_set_qam_interleave_mode(fe);
+			s5h1409_set_qam_amhum_mode(fe);
+		} else {
+			s5h1409_set_qam_amhum_mode_legacy(fe);
+			s5h1409_set_qam_interleave_mode_legacy(fe);
+		}
+	}
+
 	return 0;
 }
 
@@ -614,6 +721,21 @@ static int s5h1409_init(struct dvb_front
 	/* The datasheet says that after initialisation, VSB is default */
 	state->current_modulation = VSB_8;
 
+	/* Optimize for the HVR-1600 if appropriate.  Note that some of these
+	   may get folded into the generic case after testing with other
+	   devices */
+	if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+		/* VSB AGC REF */
+		s5h1409_writereg(state, 0x09, 0x0050);
+
+		/* Unknown but Windows driver does it... */
+		s5h1409_writereg(state, 0x21, 0x0001);
+		s5h1409_writereg(state, 0x50, 0x030e);
+
+		/* QAM AGC REF */
+		s5h1409_writereg(state, 0x82, 0x0800);
+	}
+
 	if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
 		s5h1409_writereg(state, 0xab,
 			s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
@@ -641,6 +763,17 @@ static int s5h1409_read_status(struct dv
 
 	*status = 0;
 
+	/* Optimize the demod for QAM */
+	if (state->current_modulation != VSB_8) {
+		/* This almost certainly applies to all boards, but for now
+		   only do it for the HVR-1600.  Once the other boards are
+		   tested, the "legacy" versions can just go away */
+		if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+			s5h1409_set_qam_interleave_mode(fe);
+			s5h1409_set_qam_amhum_mode(fe);
+		}
+	}
+
 	/* Get the demodulator status */
 	reg = s5h1409_readreg(state, 0xf1);
 	if (reg & 0x1000)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/s5h1409.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s5h1409.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/s5h1409.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/s5h1409.h	2010-02-24 13:52:17.000000000 -0500
@@ -57,6 +57,13 @@ struct s5h1409_config {
 #define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
 #define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
 	u16 mpeg_timing;
+
+	/* HVR-1600 optimizations (to better work with MXL5005s)
+	   Note: some of these are likely to be folded into the generic driver
+	   after being regression tested with other boards */
+#define S5H1409_HVR1600_NOOPTIMIZE 0
+#define S5H1409_HVR1600_OPTIMIZE   1
+	u8 hvr1600_opt;
 };
 
 #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stb0899_drv.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb0899_drv.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stb0899_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb0899_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -1571,7 +1571,7 @@ static enum dvbfe_search stb0899_search(
  * stb0899_track
  * periodically check the signal level against a specified
  * threshold level and perform derotator centering.
- * called once we have a lock from a succesful search
+ * called once we have a lock from a successful search
  * event.
  *
  * Will be called periodically called to maintain the
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stb6100_proc.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6100_proc.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stb6100_proc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stb6100_proc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,138 @@
+/*
+	STB6100 Silicon Tuner wrapper
+	Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
+
+	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.
+*/
+
+static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->get_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+		*frequency = state.frequency;
+	}
+
+	return 0;
+}
+
+static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	state.frequency = frequency;
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->set_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+	}
+
+	return 0;
+}
+
+static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->get_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+		*bandwidth = state.bandwidth;
+	}
+
+	return 0;
+}
+
+static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops	*tuner_ops = NULL;
+	struct tuner_state	state;
+	int err = 0;
+
+	state.bandwidth = bandwidth;
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+	if (tuner_ops->set_state) {
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 1);
+
+		err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+			return err;
+		}
+
+		if (frontend_ops->i2c_gate_ctrl)
+			frontend_ops->i2c_gate_ctrl(fe, 0);
+
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_core.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@
 #include "stv0900_priv.h"
 #include "stv0900_init.h"
 
-static int stvdebug = 1;
+int stvdebug = 1;
 module_param_named(debug, stvdebug, int, 0644);
 
 /* internal params node */
@@ -105,7 +105,8 @@ static struct stv0900_inode *append_inte
 		while (new_node->next_inode != NULL)
 			new_node = new_node->next_inode;
 
-		new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+		new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
+								GFP_KERNEL);
 		if (new_node->next_inode != NULL)
 			new_node = new_node->next_inode;
 		else
@@ -128,13 +129,13 @@ s32 ge2comp(s32 a, s32 width)
 		return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
 }
 
-void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
 								u8 reg_data)
 {
 	u8 data[3];
 	int ret;
 	struct i2c_msg i2cmsg = {
-		.addr  = i_params->i2c_addr,
+		.addr  = intp->i2c_addr,
 		.flags = 0,
 		.len   = 3,
 		.buf   = data,
@@ -144,33 +145,33 @@ void stv0900_write_reg(struct stv0900_in
 	data[1] = LSB(reg_addr);
 	data[2] = reg_data;
 
-	ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+	ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
 	if (ret != 1)
-		dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+		dprintk("%s: i2c error %d\n", __func__, ret);
 }
 
-u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg)
+u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
 {
 	int ret;
 	u8 b0[] = { MSB(reg), LSB(reg) };
 	u8 buf = 0;
 	struct i2c_msg msg[] = {
 		{
-			.addr	= i_params->i2c_addr,
+			.addr	= intp->i2c_addr,
 			.flags	= 0,
 			.buf = b0,
 			.len = 2,
 		}, {
-			.addr	= i_params->i2c_addr,
+			.addr	= intp->i2c_addr,
 			.flags	= I2C_M_RD,
 			.buf = &buf,
 			.len = 1,
 		},
 	};
 
-	ret = i2c_transfer(i_params->i2c_adap, msg, 2);
+	ret = i2c_transfer(intp->i2c_adap, msg, 2);
 	if (ret != 2)
-		dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n",
+		dprintk("%s: i2c error %d, reg[0x%02x]\n",
 				__func__, ret, reg);
 
 	return buf;
@@ -190,169 +191,165 @@ void extract_mask_pos(u32 label, u8 *mas
 	(*pos) = (i - 1);
 }
 
-void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
 {
 	u8 reg, mask, pos;
 
-	reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff);
+	reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
 	extract_mask_pos(label, &mask, &pos);
 
 	val = mask & (val << pos);
 
 	reg = (reg & (~mask)) | val;
-	stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg);
+	stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
 
 }
 
-u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
 {
 	u8 val = 0xff;
 	u8 mask, pos;
 
 	extract_mask_pos(label, &mask, &pos);
 
-	val = stv0900_read_reg(i_params, label >> 16);
+	val = stv0900_read_reg(intp, label >> 16);
 	val = (val & mask) >> pos;
 
 	return val;
 }
 
-enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
 {
 	s32 i;
-	enum fe_stv0900_error error;
 
-	if (i_params != NULL) {
-		i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
-		if (i_params->errs == STV0900_NO_ERROR) {
-			/*Startup sequence*/
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
-			stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
-			stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20);
-			stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
-			msleep(3);
-			stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+	if (intp == NULL)
+		return STV0900_INVALID_HANDLE;
 
-			switch (i_params->clkmode) {
-			case 0:
-			case 2:
-				stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
-						| i_params->clkmode);
-				break;
-			default:
-				/* preserve SELOSCI bit */
-				i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
-				stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
-				break;
-			}
+	intp->chip_id = stv0900_read_reg(intp, R0900_MID);
 
-			msleep(3);
-			for (i = 0; i < 182; i++)
-				stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+	if (intp->errs != STV0900_NO_ERROR)
+		return intp->errs;
 
-			if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) {
-				stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
-				for (i = 0; i < 32; i++)
-					stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
-			}
+	/*Startup sequence*/
+	stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
+	stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
+	msleep(3);
+	stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
+	stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
+	stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
+	stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
+	stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
+	msleep(3);
+	stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
 
-			stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c);
-			stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
-			stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
-		}
-		error = i_params->errs;
-	} else
-		error = STV0900_INVALID_HANDLE;
+	switch (intp->clkmode) {
+	case 0:
+	case 2:
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
+				| intp->clkmode);
+		break;
+	default:
+		/* preserve SELOSCI bit */
+		i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
+		break;
+	}
 
-	return error;
+	msleep(3);
+	for (i = 0; i < 181; i++)
+		stv0900_write_reg(intp, STV0900_InitVal[i][0],
+				STV0900_InitVal[i][1]);
+
+	if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
+		stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
+		for (i = 0; i < 32; i++)
+			stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
+					STV0900_Cut20_AddOnVal[i][1]);
+	}
+
+	stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
+	stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
 
+	stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
+	stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
+
+	stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
+	stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
+
+	stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
+	stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
+
+	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk)
+u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
 {
 	u32 mclk = 90000000, div = 0, ad_div = 0;
 
-	div = stv0900_get_bits(i_params, F0900_M_DIV);
-	ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+	div = stv0900_get_bits(intp, F0900_M_DIV);
+	ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
 
 	mclk = (div + 1) * ext_clk / ad_div;
 
-	dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk);
+	dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
 
 	return mclk;
 }
 
-enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk)
+enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
 {
-	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	u32 m_div, clk_sel;
 
-	dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
-			i_params->quartz);
+	dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+			intp->quartz);
 
-	if (i_params == NULL)
-		error = STV0900_INVALID_HANDLE;
-	else {
-		if (i_params->errs)
-			error = STV0900_I2C_ERROR;
-		else {
-			clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
-			m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
-			stv0900_write_bits(i_params, F0900_M_DIV, m_div);
-			i_params->mclk = stv0900_get_mclk_freq(i_params,
-							i_params->quartz);
+	if (intp == NULL)
+		return STV0900_INVALID_HANDLE;
 
-			/*Set the DiseqC frequency to 22KHz */
-			/*
-				Formula:
-				DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
-				DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
-			*/
-			m_div = i_params->mclk / 704000;
-			stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
-			stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
+	if (intp->errs)
+		return STV0900_I2C_ERROR;
 
-			stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
-			stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+	clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
+	m_div = ((clk_sel * mclk) / intp->quartz) - 1;
+	stv0900_write_bits(intp, F0900_M_DIV, m_div);
+	intp->mclk = stv0900_get_mclk_freq(intp,
+					intp->quartz);
 
-			if ((i_params->errs))
-				error = STV0900_I2C_ERROR;
-		}
-	}
+	/*Set the DiseqC frequency to 22KHz */
+	/*
+		Formula:
+		DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+		DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+	*/
+	m_div = intp->mclk / 704000;
+	stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
+	stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
 
-	return error;
+	stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
+	stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
+
+	if ((intp->errs))
+		return STV0900_I2C_ERROR;
+
+	return STV0900_NO_ERROR;
 }
 
-u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
+u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 lsb, msb, hsb, err_val;
-	s32 err1field_hsb, err1field_msb, err1field_lsb;
-	s32 err2field_hsb, err2field_msb, err2field_lsb;
-
-	dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
-	dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
-	dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
-
-	dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
-	dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
-	dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
 
 	switch (cntr) {
 	case 0:
 	default:
-		hsb = stv0900_get_bits(i_params, err1field_hsb);
-		msb = stv0900_get_bits(i_params, err1field_msb);
-		lsb = stv0900_get_bits(i_params, err1field_lsb);
+		hsb = stv0900_get_bits(intp, ERR_CNT12);
+		msb = stv0900_get_bits(intp, ERR_CNT11);
+		lsb = stv0900_get_bits(intp, ERR_CNT10);
 		break;
 	case 1:
-		hsb = stv0900_get_bits(i_params, err2field_hsb);
-		msb = stv0900_get_bits(i_params, err2field_msb);
-		lsb = stv0900_get_bits(i_params, err2field_lsb);
+		hsb = stv0900_get_bits(intp, ERR_CNT22);
+		msb = stv0900_get_bits(intp, ERR_CNT21);
+		lsb = stv0900_get_bits(intp, ERR_CNT20);
 		break;
 	}
 
@@ -364,26 +361,22 @@ u32 stv0900_get_err_count(struct stv0900
 static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	u32 fi2c;
-
-	dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
-
-	stv0900_write_bits(i_params, fi2c, enable);
+	stv0900_write_bits(intp, I2CT_ON, enable);
 
 	return 0;
 }
 
-static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
 					enum fe_stv0900_clock_type path1_ts,
 					enum fe_stv0900_clock_type path2_ts)
 {
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id >= 0x20) {
+	if (intp->chip_id >= 0x20) {
 		switch (path1_ts) {
 		case STV0900_PARALLEL_PUNCT_CLOCK:
 		case STV0900_DVBCI_CLOCK:
@@ -391,20 +384,20 @@ static void stv0900_set_ts_parallel_seri
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL,
+				stv0900_write_reg(intp, R0900_TSGENERAL,
 							0x00);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL,
+				stv0900_write_reg(intp, R0900_TSGENERAL,
 							0x06);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P1_TSFIFO_MANSPEED, 3);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P2_TSFIFO_MANSPEED, 0);
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_P1_TSSPEED, 0x14);
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_P2_TSSPEED, 0x28);
 				break;
 			}
@@ -416,14 +409,14 @@ static void stv0900_set_ts_parallel_seri
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_TSGENERAL, 0x0C);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params,
+				stv0900_write_reg(intp,
 						R0900_TSGENERAL, 0x0A);
-				dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+				dprintk("%s: 0x0a\n", __func__);
 				break;
 			}
 			break;
@@ -436,20 +429,20 @@ static void stv0900_set_ts_parallel_seri
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x10);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x16);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P1_TSFIFO_MANSPEED, 3);
-				stv0900_write_bits(i_params,
+				stv0900_write_bits(intp,
 						F0900_P2_TSFIFO_MANSPEED, 0);
-				stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+				stv0900_write_reg(intp, R0900_P1_TSSPEED,
 							0x14);
-				stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+				stv0900_write_reg(intp, R0900_P2_TSSPEED,
 							0x28);
 				break;
 			}
@@ -462,14 +455,14 @@ static void stv0900_set_ts_parallel_seri
 			case STV0900_SERIAL_PUNCT_CLOCK:
 			case STV0900_SERIAL_CONT_CLOCK:
 			default:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x14);
 				break;
 			case STV0900_PARALLEL_PUNCT_CLOCK:
 			case STV0900_DVBCI_CLOCK:
-				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+				stv0900_write_reg(intp, R0900_TSGENERAL1X,
 							0x12);
-				dprintk(KERN_INFO "%s: 0x12\n", __func__);
+				dprintk("%s: 0x12\n", __func__);
 				break;
 			}
 
@@ -479,20 +472,20 @@ static void stv0900_set_ts_parallel_seri
 
 	switch (path1_ts) {
 	case STV0900_PARALLEL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_DVBCI_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
 		break;
 	case STV0900_SERIAL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_SERIAL_CONT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
 		break;
 	default:
 		break;
@@ -500,29 +493,29 @@ static void stv0900_set_ts_parallel_seri
 
 	switch (path2_ts) {
 	case STV0900_PARALLEL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_DVBCI_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
 		break;
 	case STV0900_SERIAL_PUNCT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
 		break;
 	case STV0900_SERIAL_CONT_CLOCK:
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
-		stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+		stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
 		break;
 	default:
 		break;
 	}
 
-	stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
-	stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0);
-	stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
-	stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0);
+	stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+	stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+	stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+	stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
 }
 
 void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
@@ -574,7 +567,7 @@ void stv0900_set_bandwidth(struct dvb_fr
 	}
 }
 
-static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
 				const struct stv0900_table *lookup,
 				enum fe_stv0900_demod_num demod)
 {
@@ -584,45 +577,41 @@ static s32 stv0900_get_rf_level(struct s
 		i,
 		rf_lvl = 0;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if ((lookup != NULL) && lookup->size) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
-						stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
-			break;
-		case STV0900_DEMOD_2:
-			agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
-						stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
-			break;
-		}
+	if ((lookup == NULL) || (lookup->size <= 0))
+		return 0;
 
-		imin = 0;
-		imax = lookup->size - 1;
-		if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
-			while ((imax - imin) > 1) {
-				i = (imax + imin) >> 1;
+	agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+				stv0900_get_bits(intp, AGCIQ_VALUE0));
 
-				if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval))
-					imax = i;
-				else
-					imin = i;
-			}
+	imin = 0;
+	imax = lookup->size - 1;
+	if (INRANGE(lookup->table[imin].regval, agc_gain,
+					lookup->table[imax].regval)) {
+		while ((imax - imin) > 1) {
+			i = (imax + imin) >> 1;
 
-			rf_lvl = (((s32)agc_gain - lookup->table[imin].regval)
-					* (lookup->table[imax].realval - lookup->table[imin].realval)
-					/ (lookup->table[imax].regval - lookup->table[imin].regval))
-					+ lookup->table[imin].realval;
-		} else if (agc_gain > lookup->table[0].regval)
-			rf_lvl = 5;
-		else if (agc_gain < lookup->table[lookup->size-1].regval)
-			rf_lvl = -100;
+			if (INRANGE(lookup->table[imin].regval,
+					agc_gain,
+					lookup->table[i].regval))
+				imax = i;
+			else
+				imin = i;
+		}
 
-	}
+		rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
+		rf_lvl *= (lookup->table[imax].realval -
+				lookup->table[imin].realval);
+		rf_lvl /= (lookup->table[imax].regval -
+				lookup->table[imin].regval);
+		rf_lvl += lookup->table[imin].realval;
+	} else if (agc_gain > lookup->table[0].regval)
+		rf_lvl = 5;
+	else if (agc_gain < lookup->table[lookup->size-1].regval)
+		rf_lvl = -100;
 
-	dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+	dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
 
 	return rf_lvl;
 }
@@ -634,50 +623,51 @@ static int stv0900_read_signal_strength(
 	s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
 								state->demod);
 
-	*strength = (rflevel + 100) * (16383 / 105);
+	rflevel = (rflevel + 100) * (65535 / 70);
+	if (rflevel < 0)
+		rflevel = 0;
+
+	if (rflevel > 65535)
+		rflevel = 65535;
+
+	*strength = rflevel;
 
 	return 0;
 }
 
-
 static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
 					const struct stv0900_table *lookup)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	s32 c_n = -100,
-		regval, imin, imax,
+	s32	c_n = -100,
+		regval,
+		imin,
+		imax,
 		i,
-		lock_flag_field,
 		noise_field1,
 		noise_field0;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
-					F0900_P2_LOCK_DEFINITIF);
 	if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
-		dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1,
-					F0900_P2_NOSPLHT_NORMED1);
-		dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
-					F0900_P2_NOSPLHT_NORMED0);
+		noise_field1 = NOSPLHT_NORMED1;
+		noise_field0 = NOSPLHT_NORMED0;
 	} else {
-		dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1,
-					F0900_P2_NOSDATAT_NORMED1);
-		dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
-					F0900_P2_NOSDATAT_NORMED0);
+		noise_field1 = NOSDATAT_NORMED1;
+		noise_field0 = NOSDATAT_NORMED0;
 	}
 
-	if (stv0900_get_bits(i_params, lock_flag_field)) {
+	if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
 		if ((lookup != NULL) && lookup->size) {
 			regval = 0;
 			msleep(5);
 			for (i = 0; i < 16; i++) {
-				regval += MAKEWORD(stv0900_get_bits(i_params,
+				regval += MAKEWORD(stv0900_get_bits(intp,
 								noise_field1),
-						stv0900_get_bits(i_params,
+						stv0900_get_bits(intp,
 								noise_field0));
 				msleep(1);
 			}
@@ -715,10 +705,9 @@ static s32 stv0900_carr_get_quality(stru
 static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 	u8 err_val1, err_val0;
-	s32 err_field1, err_field0;
 	u32 header_err_val = 0;
 
 	*ucblocks = 0x0;
@@ -726,24 +715,14 @@ static int stv0900_read_ucblocks(struct
 		/* DVB-S2 delineator errors count */
 
 		/* retreiving number for errnous headers */
-		dmd_reg(err_field0, R0900_P1_BBFCRCKO0,
-					R0900_P2_BBFCRCKO0);
-		dmd_reg(err_field1, R0900_P1_BBFCRCKO1,
-					R0900_P2_BBFCRCKO1);
-
-		err_val1 = stv0900_read_reg(i_params, err_field1);
-		err_val0 = stv0900_read_reg(i_params, err_field0);
-		header_err_val = (err_val1<<8) | err_val0;
+		err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
+		err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
+		header_err_val = (err_val1 << 8) | err_val0;
 
 		/* retreiving number for errnous packets */
-		dmd_reg(err_field0, R0900_P1_UPCRCKO0,
-					R0900_P2_UPCRCKO0);
-		dmd_reg(err_field1, R0900_P1_UPCRCKO1,
-					R0900_P2_UPCRCKO1);
-
-		err_val1 = stv0900_read_reg(i_params, err_field1);
-		err_val0 = stv0900_read_reg(i_params, err_field0);
-		*ucblocks = (err_val1<<8) | err_val0;
+		err_val1 = stv0900_read_reg(intp, UPCRCKO1);
+		err_val0 = stv0900_read_reg(intp, UPCRCKO0);
+		*ucblocks = (err_val1 << 8) | err_val0;
 		*ucblocks += header_err_val;
 	}
 
@@ -752,33 +731,27 @@ static int stv0900_read_ucblocks(struct
 
 static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	*snr = stv0900_carr_get_quality(fe,
+	s32 snrlcl = stv0900_carr_get_quality(fe,
 			(const struct stv0900_table *)&stv0900_s2_cn);
-	*snr += 30;
-	*snr *= (16383 / 1030);
+	snrlcl = (snrlcl + 30) * 384;
+	if (snrlcl < 0)
+		snrlcl = 0;
+
+	if (snrlcl > 65535)
+		snrlcl = 65535;
+
+	*snr = snrlcl;
 
 	return 0;
 }
 
-static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+static u32 stv0900_get_ber(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	u32 ber = 10000000, i;
-	s32 dmd_state_reg;
 	s32 demod_state;
-	s32 vstatus_reg;
-	s32 prvit_field;
-	s32 pdel_status_reg;
-	s32 pdel_lock_field;
-
-	dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
-	dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
-	dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
-	dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
-				F0900_P2_PKTDELIN_LOCK);
 
-	demod_state = stv0900_get_bits(i_params, dmd_state_reg);
+	demod_state = stv0900_get_bits(intp, HEADER_MODE);
 
 	switch (demod_state) {
 	case STV0900_SEARCH:
@@ -790,11 +763,11 @@ static u32 stv0900_get_ber(struct stv090
 		ber = 0;
 		for (i = 0; i < 5; i++) {
 			msleep(5);
-			ber += stv0900_get_err_count(i_params, 0, demod);
+			ber += stv0900_get_err_count(intp, 0, demod);
 		}
 
 		ber /= 5;
-		if (stv0900_get_bits(i_params, prvit_field)) {
+		if (stv0900_get_bits(intp, PRFVIT)) {
 			ber *= 9766;
 			ber = ber >> 13;
 		}
@@ -804,11 +777,11 @@ static u32 stv0900_get_ber(struct stv090
 		ber = 0;
 		for (i = 0; i < 5; i++) {
 			msleep(5);
-			ber += stv0900_get_err_count(i_params, 0, demod);
+			ber += stv0900_get_err_count(intp, 0, demod);
 		}
 
 		ber /= 5;
-		if (stv0900_get_bits(i_params, pdel_lock_field)) {
+		if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
 			ber *= 9766;
 			ber = ber >> 13;
 		}
@@ -829,20 +802,16 @@ static int stv0900_read_ber(struct dvb_f
 	return 0;
 }
 
-int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+int stv0900_get_demod_lock(struct stv0900_internal *intp,
 			enum fe_stv0900_demod_num demod, s32 time_out)
 {
 	s32 timer = 0,
-		lock = 0,
-		header_field,
-		lock_field;
+		lock = 0;
 
 	enum fe_stv0900_search_state	dmd_state;
 
-	dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
 	while ((timer < time_out) && (lock == 0)) {
-		dmd_state = stv0900_get_bits(i_params, header_field);
+		dmd_state = stv0900_get_bits(intp, HEADER_MODE);
 		dprintk("Demod State = %d\n", dmd_state);
 		switch (dmd_state) {
 		case STV0900_SEARCH:
@@ -852,7 +821,7 @@ int stv0900_get_demod_lock(struct stv090
 			break;
 		case STV0900_DVBS2_FOUND:
 		case STV0900_DVBS_FOUND:
-			lock = stv0900_get_bits(i_params, lock_field);
+			lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
 			break;
 		}
 
@@ -870,56 +839,40 @@ int stv0900_get_demod_lock(struct stv090
 	return lock;
 }
 
-void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	s32 regflist,
 	i;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+	regflist = MODCODLST0;
 
 	for (i = 0; i < 16; i++)
-		stv0900_write_reg(i_params, regflist + i, 0xff);
+		stv0900_write_reg(intp, regflist + i, 0xff);
 }
 
-void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	u32 matype,
-	mod_code,
-	fmod,
-	reg_index,
-	field_index;
+		mod_code,
+		fmod,
+		reg_index,
+		field_index;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id <= 0x11) {
+	if (intp->chip_id <= 0x11) {
 		msleep(5);
 
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			mod_code = stv0900_read_reg(i_params,
-							R0900_P1_PLHMODCOD);
-			matype = mod_code & 0x3;
-			mod_code = (mod_code & 0x7f) >> 2;
-
-			reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
-			field_index = mod_code % 2;
-			break;
-		case STV0900_DEMOD_2:
-			mod_code = stv0900_read_reg(i_params,
-							R0900_P2_PLHMODCOD);
-			matype = mod_code & 0x3;
-			mod_code = (mod_code & 0x7f) >> 2;
-
-			reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
-			field_index = mod_code % 2;
-			break;
-		}
+		mod_code = stv0900_read_reg(intp, PLHMODCOD);
+		matype = mod_code & 0x3;
+		mod_code = (mod_code & 0x7f) >> 2;
 
+		reg_index = MODCODLSTF - mod_code / 2;
+		field_index = mod_code % 2;
 
 		switch (matype) {
 		case 0:
@@ -938,70 +891,41 @@ void stv0900_activate_s2_modcode(struct
 		}
 
 		if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
-							&& (matype <= 1)) {
+						&& (matype <= 1)) {
 			if (field_index == 0)
-				stv0900_write_reg(i_params, reg_index,
+				stv0900_write_reg(intp, reg_index,
 							0xf0 | fmod);
 			else
-				stv0900_write_reg(i_params, reg_index,
+				stv0900_write_reg(intp, reg_index,
 							(fmod << 4) | 0xf);
 		}
-	} else if (i_params->chip_id >= 0x12) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			for (reg_index = 0; reg_index < 7; reg_index++)
-				stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
-
-			stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff);
-			stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf);
-			for (reg_index = 0; reg_index < 8; reg_index++)
-				stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
 
-			break;
-		case STV0900_DEMOD_2:
-			for (reg_index = 0; reg_index < 7; reg_index++)
-				stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff);
+	} else if (intp->chip_id >= 0x12) {
+		for (reg_index = 0; reg_index < 7; reg_index++)
+			stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
 
-			stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
-			stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
-			for (reg_index = 0; reg_index < 8; reg_index++)
-				stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
+		stv0900_write_reg(intp, MODCODLSTE, 0xff);
+		stv0900_write_reg(intp, MODCODLSTF, 0xcf);
+		for (reg_index = 0; reg_index < 8; reg_index++)
+			stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
 
-			break;
-		}
 
 	}
 }
 
-void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 reg_index;
 
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
-		stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
-		stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
-		for (reg_index = 0; reg_index < 13; reg_index++)
-			stv0900_write_reg(i_params,
-					R0900_P1_MODCODLST2 + reg_index, 0);
+	dprintk("%s\n", __func__);
 
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff);
-		stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0);
-		stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f);
-		for (reg_index = 0; reg_index < 13; reg_index++)
-			stv0900_write_reg(i_params,
-					R0900_P2_MODCODLST2 + reg_index, 0);
+	stv0900_write_reg(intp, MODCODLST0, 0xff);
+	stv0900_write_reg(intp, MODCODLST1, 0xf0);
+	stv0900_write_reg(intp, MODCODLSTF, 0x0f);
+	for (reg_index = 0; reg_index < 13; reg_index++)
+		stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
 
-		break;
-	}
 }
 
 static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
@@ -1012,7 +936,7 @@ static enum dvbfe_algo stv0900_frontend_
 static int stb0900_set_property(struct dvb_frontend *fe,
 				struct dtv_property *tvp)
 {
-	dprintk(KERN_INFO "%s(..)\n", __func__);
+	dprintk("%s(..)\n", __func__);
 
 	return 0;
 }
@@ -1020,166 +944,123 @@ static int stb0900_set_property(struct d
 static int stb0900_get_property(struct dvb_frontend *fe,
 				struct dtv_property *tvp)
 {
-	dprintk(KERN_INFO "%s(..)\n", __func__);
+	dprintk("%s(..)\n", __func__);
 
 	return 0;
 }
 
-void stv0900_start_search(struct stv0900_internal *i_params,
+void stv0900_start_search(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
+	u32 freq;
+	s16 freq_s16 ;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f);
-
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa);
+	stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0xaa);
 
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x55);
 
-		if (i_params->dmd1_symbol_rate <= 5000000) {
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44);
-			stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f);
-			stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0);
-			stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+	if (intp->chip_id <= 0x20) {
+		if (intp->symbol_rate[0] <= 5000000) {
+			stv0900_write_reg(intp, CARCFG, 0x44);
+			stv0900_write_reg(intp, CFRUP1, 0x0f);
+			stv0900_write_reg(intp, CFRUP0, 0xff);
+			stv0900_write_reg(intp, CFRLOW1, 0xf0);
+			stv0900_write_reg(intp, CFRLOW0, 0x00);
+			stv0900_write_reg(intp, RTCS2, 0x68);
 		} else {
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
-		}
-
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
-
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
-			stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
-
-			if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
-			}
+			stv0900_write_reg(intp, CARCFG, 0xc4);
+			stv0900_write_reg(intp, RTCS2, 0x44);
 		}
 
-		stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-		stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
-		if (i_params->chip_id >= 0x20) {
-			if (i_params->dmd1_symbol_rate < 2000000) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
-			}
-
-			if (i_params->dmd1_symbol_rate < 10000000) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
-			}
+	} else { /*cut 3.0 above*/
+		if (intp->symbol_rate[demod] <= 5000000)
+			stv0900_write_reg(intp, RTCS2, 0x68);
+		else
+			stv0900_write_reg(intp, RTCS2, 0x44);
 
+		stv0900_write_reg(intp, CARCFG, 0x46);
+		if (intp->srch_algo[demod] == STV0900_WARM_START) {
+			freq = 1000 << 16;
+			freq /= (intp->mclk / 1000);
+			freq_s16 = (s16)freq;
 		} else {
-			if (i_params->dmd1_symbol_rate < 10000000)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+			freq = (intp->srch_range[demod] / 2000);
+			if (intp->symbol_rate[demod] <= 5000000)
+				freq += 80;
 			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
-		}
+				freq += 600;
 
-		switch (i_params->dmd1_srch_algo) {
-		case STV0900_WARM_START:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			break;
-		case STV0900_COLD_START:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-			break;
-		default:
-			break;
+			freq = freq << 16;
+			freq /= (intp->mclk / 1000);
+			freq_s16 = (s16)freq;
 		}
 
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
-
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+		stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
+		stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
+		freq_s16 *= (-1);
+		stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
+		stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
+	}
 
-		if (i_params->dmd2_symbol_rate <= 5000000) {
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
-			stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
-			stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
-			stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
-		} else {
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
-		}
+	stv0900_write_reg(intp, CFRINIT1, 0);
+	stv0900_write_reg(intp, CFRINIT0, 0);
 
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+	if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, EQUALCFG, 0x41);
+		stv0900_write_reg(intp, FFECFG, 0x41);
 
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
-			stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
-			if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
-			}
+		if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+			(intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
+			(intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
+			stv0900_write_reg(intp, VITSCALE,
+								0x82);
+			stv0900_write_reg(intp, VAVSRVIT, 0x0);
 		}
+	}
 
-		stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-		stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
-		if (i_params->chip_id >= 0x20) {
-			if (i_params->dmd2_symbol_rate < 2000000) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
-			}
-
-			if (i_params->dmd2_symbol_rate < 10000000) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
-			} else {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b);
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
-			}
+	stv0900_write_reg(intp, SFRSTEP, 0x00);
+	stv0900_write_reg(intp, TMGTHRISE, 0xe0);
+	stv0900_write_reg(intp, TMGTHFALL, 0xc0);
+	stv0900_write_bits(intp, SCAN_ENABLE, 0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+	stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
+	stv0900_write_reg(intp, RTC, 0x88);
+	if (intp->chip_id >= 0x20) {
+		if (intp->symbol_rate[demod] < 2000000) {
+			if (intp->chip_id <= 0x20)
+				stv0900_write_reg(intp, CARFREQ, 0x39);
+			else  /*cut 3.0*/
+				stv0900_write_reg(intp, CARFREQ, 0x89);
 
+			stv0900_write_reg(intp, CARHDR, 0x40);
+		} else if (intp->symbol_rate[demod] < 10000000) {
+			stv0900_write_reg(intp, CARFREQ, 0x4c);
+			stv0900_write_reg(intp, CARHDR, 0x20);
 		} else {
-			if (i_params->dmd2_symbol_rate < 10000000)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+			stv0900_write_reg(intp, CARFREQ, 0x4b);
+			stv0900_write_reg(intp, CARHDR, 0x20);
 		}
 
-		switch (i_params->dmd2_srch_algo) {
-		case STV0900_WARM_START:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-			break;
-		case STV0900_COLD_START:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-			break;
-		default:
-			break;
-		}
+	} else {
+		if (intp->symbol_rate[demod] < 10000000)
+			stv0900_write_reg(intp, CARFREQ, 0xef);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xed);
+	}
 
+	switch (intp->srch_algo[demod]) {
+	case STV0900_WARM_START:
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
+		break;
+	case STV0900_COLD_START:
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, DMDISTATE, 0x15);
+		break;
+	default:
 		break;
 	}
 }
@@ -1188,33 +1069,40 @@ u8 stv0900_get_optim_carr_loop(s32 srate
 							s32 pilot, u8 chip_id)
 {
 	u8 aclc_value = 0x29;
-	s32	i;
-	const struct stv0900_car_loop_optim *car_loop_s2;
+	s32 i;
+	const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (chip_id <= 0x12)
-		car_loop_s2 = FE_STV0900_S2CarLoop;
-	else if (chip_id == 0x20)
-		car_loop_s2 = FE_STV0900_S2CarLoopCut20;
-	else
-		car_loop_s2 = FE_STV0900_S2CarLoop;
+	if (chip_id <= 0x12) {
+		cls2 = FE_STV0900_S2CarLoop;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+	} else if (chip_id == 0x20) {
+		cls2 = FE_STV0900_S2CarLoopCut20;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut20;
+	} else {
+		cls2 = FE_STV0900_S2CarLoopCut30;
+		cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+		cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+	}
 
 	if (modcode < STV0900_QPSK_12) {
 		i = 0;
-		while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+		while ((i < 3) && (modcode != cllqs2[i].modcode))
 			i++;
 
 		if (i >= 3)
 			i = 2;
 	} else {
 		i = 0;
-		while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+		while ((i < 14) && (modcode != cls2[i].modcode))
 			i++;
 
 		if (i >= 14) {
 			i = 0;
-			while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+			while ((i < 11) && (modcode != cllas2[i].modcode))
 				i++;
 
 			if (i >= 11)
@@ -1225,76 +1113,82 @@ u8 stv0900_get_optim_carr_loop(s32 srate
 	if (modcode <= STV0900_QPSK_25) {
 		if (pilot) {
 			if (srate <= 3000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+				aclc_value = cllqs2[i].car_loop_pilots_on_2;
 			else if (srate <= 7000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+				aclc_value = cllqs2[i].car_loop_pilots_on_5;
 			else if (srate <= 15000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+				aclc_value = cllqs2[i].car_loop_pilots_on_10;
 			else if (srate <= 25000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+				aclc_value = cllqs2[i].car_loop_pilots_on_20;
 			else
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+				aclc_value = cllqs2[i].car_loop_pilots_on_30;
 		} else {
 			if (srate <= 3000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+				aclc_value = cllqs2[i].car_loop_pilots_off_2;
 			else if (srate <= 7000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+				aclc_value = cllqs2[i].car_loop_pilots_off_5;
 			else if (srate <= 15000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+				aclc_value = cllqs2[i].car_loop_pilots_off_10;
 			else if (srate <= 25000000)
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+				aclc_value = cllqs2[i].car_loop_pilots_off_20;
 			else
-				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30;
+				aclc_value = cllqs2[i].car_loop_pilots_off_30;
 		}
 
 	} else if (modcode <= STV0900_8PSK_910) {
 		if (pilot) {
 			if (srate <= 3000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_2;
+				aclc_value = cls2[i].car_loop_pilots_on_2;
 			else if (srate <= 7000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+				aclc_value = cls2[i].car_loop_pilots_on_5;
 			else if (srate <= 15000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+				aclc_value = cls2[i].car_loop_pilots_on_10;
 			else if (srate <= 25000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+				aclc_value = cls2[i].car_loop_pilots_on_20;
 			else
-				aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+				aclc_value = cls2[i].car_loop_pilots_on_30;
 		} else {
 			if (srate <= 3000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+				aclc_value = cls2[i].car_loop_pilots_off_2;
 			else if (srate <= 7000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+				aclc_value = cls2[i].car_loop_pilots_off_5;
 			else if (srate <= 15000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+				aclc_value = cls2[i].car_loop_pilots_off_10;
 			else if (srate <= 25000000)
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+				aclc_value = cls2[i].car_loop_pilots_off_20;
 			else
-				aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+				aclc_value = cls2[i].car_loop_pilots_off_30;
 		}
 
 	} else {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+			aclc_value = cllas2[i].car_loop_pilots_on_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+			aclc_value = cllas2[i].car_loop_pilots_on_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+			aclc_value = cllas2[i].car_loop_pilots_on_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+			aclc_value = cllas2[i].car_loop_pilots_on_20;
 		else
-			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30;
+			aclc_value = cllas2[i].car_loop_pilots_on_30;
 	}
 
 	return aclc_value;
 }
 
-u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id)
+u8 stv0900_get_optim_short_carr_loop(s32 srate,
+				enum fe_stv0900_modulation modulation,
+				u8 chip_id)
 {
+	const struct stv0900_short_frames_car_loop_optim *s2scl;
+	const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
 	s32 mod_index = 0;
-
 	u8 aclc_value = 0x0b;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
+
+	s2scl = FE_STV0900_S2ShortCarLoop;
+	s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
 
 	switch (modulation) {
 	case STV0900_QPSK:
@@ -1312,75 +1206,116 @@ u8 stv0900_get_optim_short_carr_loop(s32
 		break;
 	}
 
-	switch (chip_id) {
-	case 0x20:
+	if (chip_id >= 0x30) {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+			aclc_value = s2sclc30[mod_index].car_loop_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+			aclc_value = s2sclc30[mod_index].car_loop_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+			aclc_value = s2sclc30[mod_index].car_loop_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+			aclc_value = s2sclc30[mod_index].car_loop_20;
 		else
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+			aclc_value = s2sclc30[mod_index].car_loop_30;
 
-		break;
-	case 0x12:
-	default:
+	} else if (chip_id >= 0x20) {
 		if (srate <= 3000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+			aclc_value = s2scl[mod_index].car_loop_cut20_2;
 		else if (srate <= 7000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+			aclc_value = s2scl[mod_index].car_loop_cut20_5;
 		else if (srate <= 15000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+			aclc_value = s2scl[mod_index].car_loop_cut20_10;
 		else if (srate <= 25000000)
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+			aclc_value = s2scl[mod_index].car_loop_cut20_20;
 		else
-			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+			aclc_value = s2scl[mod_index].car_loop_cut20_30;
+
+	} else {
+		if (srate <= 3000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_2;
+		else if (srate <= 7000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_5;
+		else if (srate <= 15000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_10;
+		else if (srate <= 25000000)
+			aclc_value = s2scl[mod_index].car_loop_cut12_20;
+		else
+			aclc_value = s2scl[mod_index].car_loop_cut12_30;
 
-		break;
 	}
 
 	return aclc_value;
 }
 
-static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+static
+enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_mode LDPC_Mode,
 					enum fe_stv0900_demod_num demod)
 {
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
+	s32 reg_ind;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	switch (LDPC_Mode) {
 	case STV0900_DUAL:
 	default:
-		if ((i_params->demod_mode != STV0900_DUAL)
-			|| (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) {
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x1d);
+		if ((intp->demod_mode != STV0900_DUAL)
+			|| (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
+			stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
 
-			i_params->demod_mode = STV0900_DUAL;
+			intp->demod_mode = STV0900_DUAL;
 
-			stv0900_write_bits(i_params, F0900_FRESFEC, 1);
-			stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+			stv0900_write_bits(intp, F0900_FRESFEC, 1);
+			stv0900_write_bits(intp, F0900_FRESFEC, 0);
+
+			for (reg_ind = 0; reg_ind < 7; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P1_MODCODLST0 + reg_ind,
+						0xff);
+			for (reg_ind = 0; reg_ind < 8; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P1_MODCODLST7 + reg_ind,
+						0xcc);
+
+			stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
+			stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
+
+			for (reg_ind = 0; reg_ind < 7; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P2_MODCODLST0 + reg_ind,
+						0xff);
+			for (reg_ind = 0; reg_ind < 8; reg_ind++)
+				stv0900_write_reg(intp,
+						R0900_P2_MODCODLST7 + reg_ind,
+						0xcc);
+
+			stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
+			stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
 		}
 
 		break;
 	case STV0900_SINGLE:
-		if (demod == STV0900_DEMOD_2)
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x06);
-		else
-			stv0900_write_reg(i_params, R0900_GENCFG, 0x04);
+		if (demod == STV0900_DEMOD_2) {
+			stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
+			stv0900_activate_s2_modcod_single(intp,
+							STV0900_DEMOD_2);
+			stv0900_write_reg(intp, R0900_GENCFG, 0x06);
+		} else {
+			stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
+			stv0900_activate_s2_modcod_single(intp,
+							STV0900_DEMOD_1);
+			stv0900_write_reg(intp, R0900_GENCFG, 0x04);
+		}
 
-		i_params->demod_mode = STV0900_SINGLE;
+		intp->demod_mode = STV0900_SINGLE;
 
-		stv0900_write_bits(i_params, F0900_FRESFEC, 1);
-		stv0900_write_bits(i_params, F0900_FRESFEC, 0);
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+		stv0900_write_bits(intp, F0900_FRESFEC, 1);
+		stv0900_write_bits(intp, F0900_FRESFEC, 0);
+		stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
+		stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
+		stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
+		stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
 		break;
 	}
 
@@ -1393,131 +1328,133 @@ static enum fe_stv0900_error stv0900_ini
 	struct stv0900_state *state = fe->demodulator_priv;
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+	struct stv0900_internal *intp = NULL;
+
 	int selosci, i;
 
 	struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
 						state->config->demod_address);
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (temp_int != NULL) {
+	if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
 		state->internal = temp_int->internal;
 		(state->internal->dmds_used)++;
-		dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+		dprintk("%s: Find Internal Structure!\n", __func__);
 		return STV0900_NO_ERROR;
 	} else {
-		state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL);
+		state->internal = kmalloc(sizeof(struct stv0900_internal),
+								GFP_KERNEL);
 		temp_int = append_internal(state->internal);
 		state->internal->dmds_used = 1;
 		state->internal->i2c_adap = state->i2c_adap;
 		state->internal->i2c_addr = state->config->demod_address;
 		state->internal->clkmode = state->config->clkmode;
 		state->internal->errs = STV0900_NO_ERROR;
-		dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__);
+		dprintk("%s: Create New Internal Structure!\n", __func__);
 	}
 
-	if (state->internal != NULL) {
-		demodError = stv0900_initialize(state->internal);
-		if (demodError == STV0900_NO_ERROR) {
-				error = STV0900_NO_ERROR;
-		} else {
-			if (demodError == STV0900_INVALID_HANDLE)
-				error = STV0900_INVALID_HANDLE;
-			else
-				error = STV0900_I2C_ERROR;
-		}
+	if (state->internal == NULL) {
+		error = STV0900_INVALID_HANDLE;
+		return error;
+	}
 
-		if (state->internal != NULL) {
-			if (error == STV0900_NO_ERROR) {
-				state->internal->demod_mode = p_init->demod_mode;
+	demodError = stv0900_initialize(state->internal);
+	if (demodError == STV0900_NO_ERROR) {
+			error = STV0900_NO_ERROR;
+	} else {
+		if (demodError == STV0900_INVALID_HANDLE)
+			error = STV0900_INVALID_HANDLE;
+		else
+			error = STV0900_I2C_ERROR;
 
-				stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
+		return error;
+	}
 
-				state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID);
-				state->internal->rolloff = p_init->rolloff;
-				state->internal->quartz = p_init->dmd_ref_clk;
+	if (state->internal == NULL) {
+		error = STV0900_INVALID_HANDLE;
+		return error;
+	}
 
-				stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
-				stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+	intp = state->internal;
 
-				state->internal->ts_config = p_init->ts_config;
-				if (state->internal->ts_config == NULL)
-					stv0900_set_ts_parallel_serial(state->internal,
-							p_init->path1_ts_clock,
-							p_init->path2_ts_clock);
-				else {
-					for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++)
-						stv0900_write_reg(state->internal,
-								state->internal->ts_config[i].addr,
-								state->internal->ts_config[i].val);
+	intp->demod_mode = p_init->demod_mode;
+	stv0900_st_dvbs2_single(intp, intp->demod_mode,	STV0900_DEMOD_1);
+	intp->chip_id = stv0900_read_reg(intp, R0900_MID);
+	intp->rolloff = p_init->rolloff;
+	intp->quartz = p_init->dmd_ref_clk;
 
-					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1);
-					stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0);
-					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1);
-					stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0);
-				}
+	stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+	stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
 
-				stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
-				switch (p_init->tuner1_adc) {
-				case 1:
-					stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
-					break;
-				default:
-					break;
-				}
+	intp->ts_config = p_init->ts_config;
+	if (intp->ts_config == NULL)
+		stv0900_set_ts_parallel_serial(intp,
+				p_init->path1_ts_clock,
+				p_init->path2_ts_clock);
+	else {
+		for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
+			stv0900_write_reg(intp,
+					intp->ts_config[i].addr,
+					intp->ts_config[i].val);
 
-				stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
-				switch (p_init->tuner2_adc) {
-				case 1:
-					stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26);
-					break;
-				default:
-					break;
-				}
+		stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+		stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+		stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+		stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
+	}
 
-				stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion);
-				stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
-				stv0900_set_mclk(state->internal, 135000000);
-				msleep(3);
+	stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+	switch (p_init->tuner1_adc) {
+	case 1:
+		stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
+		break;
+	default:
+		break;
+	}
 
-				switch (state->internal->clkmode) {
-				case 0:
-				case 2:
-					stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
-					break;
-				default:
-					selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
-					stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
-					break;
-				}
-				msleep(3);
+	stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+	switch (p_init->tuner2_adc) {
+	case 1:
+		stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
+		break;
+	default:
+		break;
+	}
 
-				state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz);
-				if (state->internal->errs)
-					error = STV0900_I2C_ERROR;
-			}
-		} else {
-			error = STV0900_INVALID_HANDLE;
-		}
+	stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
+	stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
+	stv0900_set_mclk(intp, 135000000);
+	msleep(3);
+
+	switch (intp->clkmode) {
+	case 0:
+	case 2:
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
+		break;
+	default:
+		selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+		stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
+		break;
 	}
+	msleep(3);
+
+	intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
+	if (intp->errs)
+		error = STV0900_I2C_ERROR;
 
 	return error;
 }
 
-static int stv0900_status(struct stv0900_internal *i_params,
+static int stv0900_status(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	enum fe_stv0900_search_state demod_state;
-	s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
 	int locked = FALSE;
+	u8 tsbitrate0_val, tsbitrate1_val;
+	s32 bitrate;
 
-	dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
-	dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
-	dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
-	dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
-
-	demod_state = stv0900_get_bits(i_params, mode_field);
+	demod_state = stv0900_get_bits(intp, HEADER_MODE);
 	switch (demod_state) {
 	case STV0900_SEARCH:
 	case STV0900_PLH_DETECTED:
@@ -1525,17 +1462,30 @@ static int stv0900_status(struct stv0900
 		locked = FALSE;
 		break;
 	case STV0900_DVBS2_FOUND:
-		locked = stv0900_get_bits(i_params, lock_field) &&
-				stv0900_get_bits(i_params, delin_field) &&
-				stv0900_get_bits(i_params, fifo_field);
+		locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+				stv0900_get_bits(intp, PKTDELIN_LOCK) &&
+				stv0900_get_bits(intp, TSFIFO_LINEOK);
 		break;
 	case STV0900_DVBS_FOUND:
-		locked = stv0900_get_bits(i_params, lock_field) &&
-				stv0900_get_bits(i_params, lockedvit_field) &&
-				stv0900_get_bits(i_params, fifo_field);
+		locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+				stv0900_get_bits(intp, LOCKEDVIT) &&
+				stv0900_get_bits(intp, TSFIFO_LINEOK);
 		break;
 	}
 
+	dprintk("%s: locked = %d\n", __func__, locked);
+
+	if (stvdebug) {
+		/* Print TS bitrate */
+		tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
+		tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
+		/* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
+		bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
+			* (tsbitrate1_val << 8 | tsbitrate0_val);
+		bitrate /= 16384;
+		dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
+	};
+
 	return locked;
 }
 
@@ -1543,7 +1493,8 @@ static enum dvbfe_search stv0900_search(
 					struct dvb_frontend_parameters *params)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
 	struct stv0900_search_params p_search;
@@ -1551,10 +1502,16 @@ static enum dvbfe_search stv0900_search(
 
 	enum fe_stv0900_error error = STV0900_NO_ERROR;
 
-	dprintk(KERN_INFO "%s: ", __func__);
+	dprintk("%s: ", __func__);
+
+	if (!(INRANGE(100000, c->symbol_rate, 70000000)))
+		return DVBFE_ALGO_SEARCH_FAILED;
+
+	if (state->config->set_ts_params)
+		state->config->set_ts_params(fe, 0);
 
 	p_result.locked = FALSE;
-	p_search.path = state->demod;
+	p_search.path = demod;
 	p_search.frequency = c->frequency;
 	p_search.symbol_rate = c->symbol_rate;
 	p_search.search_range = 10000000;
@@ -1563,103 +1520,47 @@ static enum dvbfe_search stv0900_search(
 	p_search.iq_inversion = STV0900_IQ_AUTO;
 	p_search.search_algo = STV0900_BLIND_SEARCH;
 
-	if ((INRANGE(100000, p_search.symbol_rate, 70000000)) &&
-			(INRANGE(100000, p_search.search_range, 50000000))) {
-		switch (p_search.path) {
-		case STV0900_DEMOD_1:
-		default:
-			i_params->dmd1_srch_standard = p_search.standard;
-			i_params->dmd1_symbol_rate = p_search.symbol_rate;
-			i_params->dmd1_srch_range = p_search.search_range;
-			i_params->tuner1_freq = p_search.frequency;
-			i_params->dmd1_srch_algo = p_search.search_algo;
-			i_params->dmd1_srch_iq_inv = p_search.iq_inversion;
-			i_params->dmd1_fec = p_search.fec;
+	intp->srch_standard[demod] = p_search.standard;
+	intp->symbol_rate[demod] = p_search.symbol_rate;
+	intp->srch_range[demod] = p_search.search_range;
+	intp->freq[demod] = p_search.frequency;
+	intp->srch_algo[demod] = p_search.search_algo;
+	intp->srch_iq_inv[demod] = p_search.iq_inversion;
+	intp->fec[demod] = p_search.fec;
+	if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+				(intp->errs == STV0900_NO_ERROR)) {
+		p_result.locked = intp->result[demod].locked;
+		p_result.standard = intp->result[demod].standard;
+		p_result.frequency = intp->result[demod].frequency;
+		p_result.symbol_rate = intp->result[demod].symbol_rate;
+		p_result.fec = intp->result[demod].fec;
+		p_result.modcode = intp->result[demod].modcode;
+		p_result.pilot = intp->result[demod].pilot;
+		p_result.frame_len = intp->result[demod].frame_len;
+		p_result.spectrum = intp->result[demod].spectrum;
+		p_result.rolloff = intp->result[demod].rolloff;
+		p_result.modulation = intp->result[demod].modulation;
+	} else {
+		p_result.locked = FALSE;
+		switch (intp->err[demod]) {
+		case STV0900_I2C_ERROR:
+			error = STV0900_I2C_ERROR;
 			break;
-
-		case STV0900_DEMOD_2:
-			i_params->dmd2_srch_stndrd = p_search.standard;
-			i_params->dmd2_symbol_rate = p_search.symbol_rate;
-			i_params->dmd2_srch_range = p_search.search_range;
-			i_params->tuner2_freq = p_search.frequency;
-			i_params->dmd2_srch_algo = p_search.search_algo;
-			i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
-			i_params->dmd2_fec = p_search.fec;
+		case STV0900_NO_ERROR:
+		default:
+			error = STV0900_SEARCH_FAILED;
 			break;
 		}
-
-		if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
-					(i_params->errs == STV0900_NO_ERROR)) {
-			switch (p_search.path) {
-			case STV0900_DEMOD_1:
-			default:
-				p_result.locked = i_params->dmd1_rslts.locked;
-				p_result.standard = i_params->dmd1_rslts.standard;
-				p_result.frequency = i_params->dmd1_rslts.frequency;
-				p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
-				p_result.fec = i_params->dmd1_rslts.fec;
-				p_result.modcode = i_params->dmd1_rslts.modcode;
-				p_result.pilot = i_params->dmd1_rslts.pilot;
-				p_result.frame_length = i_params->dmd1_rslts.frame_length;
-				p_result.spectrum = i_params->dmd1_rslts.spectrum;
-				p_result.rolloff = i_params->dmd1_rslts.rolloff;
-				p_result.modulation = i_params->dmd1_rslts.modulation;
-				break;
-			case STV0900_DEMOD_2:
-				p_result.locked = i_params->dmd2_rslts.locked;
-				p_result.standard = i_params->dmd2_rslts.standard;
-				p_result.frequency = i_params->dmd2_rslts.frequency;
-				p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
-				p_result.fec = i_params->dmd2_rslts.fec;
-				p_result.modcode = i_params->dmd2_rslts.modcode;
-				p_result.pilot = i_params->dmd2_rslts.pilot;
-				p_result.frame_length = i_params->dmd2_rslts.frame_length;
-				p_result.spectrum = i_params->dmd2_rslts.spectrum;
-				p_result.rolloff = i_params->dmd2_rslts.rolloff;
-				p_result.modulation = i_params->dmd2_rslts.modulation;
-				break;
-			}
-
-		} else {
-			p_result.locked = FALSE;
-			switch (p_search.path) {
-			case STV0900_DEMOD_1:
-				switch (i_params->dmd1_err) {
-				case STV0900_I2C_ERROR:
-					error = STV0900_I2C_ERROR;
-					break;
-				case STV0900_NO_ERROR:
-				default:
-					error = STV0900_SEARCH_FAILED;
-					break;
-				}
-				break;
-			case STV0900_DEMOD_2:
-				switch (i_params->dmd2_err) {
-				case STV0900_I2C_ERROR:
-					error = STV0900_I2C_ERROR;
-					break;
-				case STV0900_NO_ERROR:
-				default:
-					error = STV0900_SEARCH_FAILED;
-					break;
-				}
-				break;
-			}
-		}
-
-	} else
-		error = STV0900_BAD_PARAMETER;
+	}
 
 	if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
-		dprintk(KERN_INFO "Search Success\n");
+		dprintk("Search Success\n");
 		return DVBFE_ALGO_SEARCH_SUCCESS;
 	} else {
-		dprintk(KERN_INFO "Search Fail\n");
+		dprintk("Search Fail\n");
 		return DVBFE_ALGO_SEARCH_FAILED;
 	}
 
-	return DVBFE_ALGO_SEARCH_ERROR;
 }
 
 static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
@@ -1690,16 +1591,13 @@ static int stv0900_stop_ts(struct dvb_fr
 {
 
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 rst_field;
-
-	dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
 
 	if (stop_ts == TRUE)
-		stv0900_write_bits(i_params, rst_field, 1);
+		stv0900_write_bits(intp, RST_HWARE, 1);
 	else
-		stv0900_write_bits(i_params, rst_field, 0);
+		stv0900_write_bits(intp, RST_HWARE, 0);
 
 	return 0;
 }
@@ -1707,23 +1605,19 @@ static int stv0900_stop_ts(struct dvb_fr
 static int stv0900_diseqc_init(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field, reset_field;
-
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
 
-	stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
-	stv0900_write_bits(i_params, reset_field, 1);
-	stv0900_write_bits(i_params, reset_field, 0);
+	stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
+	stv0900_write_bits(intp, DISEQC_RESET, 1);
+	stv0900_write_bits(intp, DISEQC_RESET, 0);
 
 	return 0;
 }
 
 static int stv0900_init(struct dvb_frontend *fe)
 {
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	stv0900_stop_ts(fe, 1);
 	stv0900_diseqc_init(fe);
@@ -1731,48 +1625,24 @@ static int stv0900_init(struct dvb_front
 	return 0;
 }
 
-static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data,
+static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
 				u32 NbData, enum fe_stv0900_demod_num demod)
 {
 	s32 i = 0;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1);
-		while (i < NbData) {
-			while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL))
-				;/* checkpatch complains */
-			stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
-			i++;
-		}
-
-		stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
-		i = 0;
-		while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
-
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
-
-		while (i < NbData) {
-			while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
-				;/* checkpatch complains */
-			stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
-			i++;
-		}
-
-		stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
-		i = 0;
-		while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
+	stv0900_write_bits(intp, DIS_PRECHARGE, 1);
+	while (i < NbData) {
+		while (stv0900_get_bits(intp, FIFO_FULL))
+			;/* checkpatch complains */
+		stv0900_write_reg(intp, DISTXDATA, data[i]);
+		i++;
+	}
 
-		break;
+	stv0900_write_bits(intp, DIS_PRECHARGE, 0);
+	i = 0;
+	while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
+		msleep(10);
+		i++;
 	}
 
 	return 0;
@@ -1792,22 +1662,21 @@ static int stv0900_send_master_cmd(struc
 static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field;
-	u32 diseqc_fifo;
+	u8 data;
 
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
 
 	switch (burst) {
 	case SEC_MINI_A:
-		stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */
-		stv0900_write_reg(i_params, diseqc_fifo, 0x00);
+		stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
+		data = 0x00;
+		stv0900_diseqc_send(intp, &data, 1, state->demod);
 		break;
 	case SEC_MINI_B:
-		stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
-		stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+		stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
+		data = 0xff;
+		stv0900_diseqc_send(intp, &data, 1, state->demod);
 		break;
 	}
 
@@ -1818,68 +1687,54 @@ static int stv0900_recv_slave_reply(stru
 				struct dvb_diseqc_slave_reply *reply)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
 	s32 i = 0;
 
-	switch (state->demod) {
-	case STV0900_DEMOD_1:
-	default:
-		reply->msg_len = 0;
-
-		while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
-
-		if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
-			reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
-
-			for (i = 0; i < reply->msg_len; i++)
-				reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
-		}
-		break;
-	case STV0900_DEMOD_2:
-		reply->msg_len = 0;
+	reply->msg_len = 0;
 
-		while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) {
-			msleep(10);
-			i++;
-		}
+	while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
+		msleep(10);
+		i++;
+	}
 
-		if (stv0900_get_bits(i_params, F0900_P2_RX_END)) {
-			reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR);
+	if (stv0900_get_bits(intp, RX_END)) {
+		reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
 
-			for (i = 0; i < reply->msg_len; i++)
-				reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
-		}
-		break;
+		for (i = 0; i < reply->msg_len; i++)
+			reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
 	}
 
 	return 0;
 }
 
-static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	s32 mode_field, reset_field;
-
-	dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
 
-	dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
-	dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+	dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
 
-	if (tone) {
-		/*Set the DiseqC mode to 22Khz continues tone*/
-		stv0900_write_bits(i_params, mode_field, 0);
-		stv0900_write_bits(i_params, reset_field, 1);
+	switch (toneoff) {
+	case SEC_TONE_ON:
+		/*Set the DiseqC mode to 22Khz _continues_ tone*/
+		stv0900_write_bits(intp, DISTX_MODE, 0);
+		stv0900_write_bits(intp, DISEQC_RESET, 1);
 		/*release DiseqC reset to enable the 22KHz tone*/
-		stv0900_write_bits(i_params, reset_field, 0);
-	} else {
-		stv0900_write_bits(i_params, mode_field, 0);
+		stv0900_write_bits(intp, DISEQC_RESET, 0);
+		break;
+	case SEC_TONE_OFF:
+		/*return diseqc mode to config->diseqc_mode.
+		Usually it's without _continues_ tone */
+		stv0900_write_bits(intp, DISTX_MODE,
+				state->config->diseqc_mode);
 		/*maintain the DiseqC reset to disable the 22KHz tone*/
-		stv0900_write_bits(i_params, reset_field, 1);
+		stv0900_write_bits(intp, DISEQC_RESET, 1);
+		stv0900_write_bits(intp, DISEQC_RESET, 0);
+		break;
+	default:
+		return -EINVAL;
 	}
 
 	return 0;
@@ -1889,11 +1744,11 @@ static void stv0900_release(struct dvb_f
 {
 	struct stv0900_state *state = fe->demodulator_priv;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
 	if ((--(state->internal->dmds_used)) <= 0) {
 
-		dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+		dprintk("%s: Actually removing\n", __func__);
 
 		remove_inode(state->internal);
 		kfree(state->internal);
@@ -1963,17 +1818,17 @@ struct dvb_frontend *stv0900_attach(cons
 	case 0:
 	case 1:
 		init_params.dmd_ref_clk  	= config->xtal;
-		init_params.demod_mode		= STV0900_DUAL;
+		init_params.demod_mode		= config->demod_mode;
 		init_params.rolloff		= STV0900_35;
 		init_params.path1_ts_clock	= config->path1_mode;
 		init_params.tun1_maddress	= config->tun1_maddress;
-		init_params.tun1_iq_inversion	= STV0900_IQ_NORMAL;
+		init_params.tun1_iq_inv		= STV0900_IQ_NORMAL;
 		init_params.tuner1_adc		= config->tun1_adc;
 		init_params.path2_ts_clock	= config->path2_mode;
 		init_params.ts_config		= config->ts_config_regs;
 		init_params.tun2_maddress	= config->tun2_maddress;
 		init_params.tuner2_adc		= config->tun2_adc;
-		init_params.tun2_iq_inversion	= STV0900_IQ_SWAPPED;
+		init_params.tun2_iq_inv		= STV0900_IQ_SWAPPED;
 
 		err_stv0900 = stv0900_init_internal(&state->frontend,
 							&init_params);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,7 @@ struct stv0900_reg {
 
 struct stv0900_config {
 	u8 demod_address;
+	u8 demod_mode;
 	u32 xtal;
 	u8 clkmode;/* 0 for CLKI,  2 for XTALI */
 
@@ -48,6 +49,8 @@ struct stv0900_config {
 	u8 tun2_maddress;
 	u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
 	u8 tun2_adc;
+	/* Set device param to start dma */
+	int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
 };
 
 #if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_init.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_init.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_init.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_init.h	2010-02-24 13:52:17.000000000 -0500
@@ -141,85 +141,228 @@ struct stv0900_short_frames_car_loop_opt
 
 };
 
+struct stv0900_short_frames_car_loop_optim_vs_mod {
+	enum fe_stv0900_modulation modulation;
+	u8 car_loop_2;	  /* SR<3msps      */
+	u8 car_loop_5;	  /* 3<SR<=7msps   */
+	u8 car_loop_10;   /* 7<SR<=15msps  */
+	u8 car_loop_20;   /* 10<SR<=25msps */
+	u8 car_loop_30;   /* 10<SR<=45msps */
+};
+
 /* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim	FE_STV0900_S2CarLoop[14] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_12,	0x1C,	0x0D,	0x1B,	0x2C,	0x3A,	0x1C,	0x2A,	0x3B,	0x2A,	0x1B },
-	{ STV0900_QPSK_35,	0x2C,	0x0D,	0x2B,	0x2C,	0x3A,	0x0C,	0x3A,	0x2B,	0x2A,	0x0B },
-	{ STV0900_QPSK_23,	0x2C,	0x0D,	0x2B,	0x2C,	0x0B,	0x0C,	0x3A,	0x1B,	0x2A,	0x3A },
-	{ STV0900_QPSK_34,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_45,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_56,	0x0D,	0x0D,	0x3B,	0x1C,	0x0B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_89,	0x0D,	0x0D,	0x3B,	0x1C,	0x1B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_QPSK_910,	0x1D,	0x0D,	0x3B,	0x1C,	0x1B,	0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
-	{ STV0900_8PSK_35,	0x29,	0x3B,	0x09,	0x2B,	0x38,	0x0B,	0x18,	0x1A,	0x08,	0x0A },
-	{ STV0900_8PSK_23,	0x0A,	0x3B,	0x29,	0x2B,	0x19,	0x0B,	0x38,	0x1A,	0x18,	0x0A },
-	{ STV0900_8PSK_34,	0x3A,	0x3B,	0x2A,	0x2B,	0x39,	0x0B,	0x19,	0x1A,	0x38,	0x0A },
-	{ STV0900_8PSK_56,	0x1B,	0x3B,	0x0B,	0x2B,	0x1A,	0x0B,	0x39,	0x1A,	0x19,	0x0A },
-	{ STV0900_8PSK_89,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,	0x0B,	0x39,	0x1A,	0x29,	0x39 },
-	{ STV0900_8PSK_910,	0x3B,	0x3B, 	0x0B,	0x2B, 	0x2A,	0x0B,	0x39,	0x1A,	0x29,	0x39 }
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_12,	0x1C,	0x0D,	0x1B,	0x2C,	0x3A,
+				0x1C,	0x2A,	0x3B,	0x2A,	0x1B },
+	{ STV0900_QPSK_35,	0x2C,	0x0D,	0x2B,	0x2C,	0x3A,
+				0x0C,	0x3A,	0x2B,	0x2A,	0x0B },
+	{ STV0900_QPSK_23,	0x2C,	0x0D,	0x2B,	0x2C,	0x0B,
+				0x0C,	0x3A,	0x1B,	0x2A,	0x3A },
+	{ STV0900_QPSK_34,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_45,	0x3C,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_56,	0x0D,	0x0D,	0x3B,	0x1C,	0x0B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_89,	0x0D,	0x0D,	0x3B,	0x1C,	0x1B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_QPSK_910,	0x1D,	0x0D,	0x3B,	0x1C,	0x1B,
+				0x3B,	0x3A,	0x0B,	0x2A,	0x3A },
+	{ STV0900_8PSK_35,	0x29,	0x3B,	0x09,	0x2B,	0x38,
+				0x0B,	0x18,	0x1A,	0x08,	0x0A },
+	{ STV0900_8PSK_23,	0x0A,	0x3B,	0x29,	0x2B,	0x19,
+				0x0B,	0x38,	0x1A,	0x18,	0x0A },
+	{ STV0900_8PSK_34,	0x3A,	0x3B,	0x2A,	0x2B,	0x39,
+				0x0B,	0x19,	0x1A,	0x38,	0x0A },
+	{ STV0900_8PSK_56,	0x1B,	0x3B,	0x0B,	0x2B,	0x1A,
+				0x0B,	0x39,	0x1A,	0x19,	0x0A },
+	{ STV0900_8PSK_89,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,
+				0x0B,	0x39,	0x1A,	0x29,	0x39 },
+	{ STV0900_8PSK_910,	0x3B,	0x3B, 	0x0B,	0x2B, 	0x2A,
+				0x0B,	0x39,	0x1A,	0x29,	0x39 }
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim	FE_STV0900_S2CarLoopCut20[14]	= {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_12,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,	0x1F,	0x3D,	0x3E,	0x3D,	0x1E },
-	{ STV0900_QPSK_35,	0x2F,	0x3F,	0x2E,	0x2F,	0x3D,	0x0F,	0x0E,	0x2E,	0x3D,	0x0E },
-	{ STV0900_QPSK_23,	0x2F,	0x3F,	0x2E,	0x2F,	0x0E,	0x0F,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_34,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_45,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_56,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_89,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_QPSK_910,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,	0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
-	{ STV0900_8PSK_35,	0x3c,	0x0c,	0x1c,	0x3b,	0x0c,	0x3b,	0x2b,	0x2b,	0x1b,	0x2b },
-	{ STV0900_8PSK_23,	0x1d,	0x0c,	0x3c,	0x0c,	0x2c,	0x3b,	0x0c,	0x2b,	0x2b,	0x2b },
-	{ STV0900_8PSK_34,	0x0e,	0x1c,	0x3d,	0x0c,	0x0d,	0x3b,	0x2c,	0x3b,	0x0c,	0x2b },
-	{ STV0900_8PSK_56,	0x2e,	0x3e,	0x1e,	0x2e,	0x2d,	0x1e,	0x3c,	0x2d,	0x2c,	0x1d },
-	{ STV0900_8PSK_89,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,	0x1e,	0x0d,	0x2d,	0x3c,	0x1d },
-	{ STV0900_8PSK_910,	0x3e,	0x3e, 	0x1e,	0x2e, 	0x3d,	0x1e,	0x1d,	0x2d,	0x0d,	0x1d }
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_12,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,
+				0x1F,	0x3D,	0x3E,	0x3D,	0x1E },
+	{ STV0900_QPSK_35,	0x2F,	0x3F,	0x2E,	0x2F,	0x3D,
+				0x0F,	0x0E,	0x2E,	0x3D,	0x0E },
+	{ STV0900_QPSK_23,	0x2F,	0x3F,	0x2E,	0x2F,	0x0E,
+				0x0F,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_34,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_45,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_56,	0x3F,	0x3F,	0x3E,	0x1F,	0x0E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_89,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_QPSK_910,	0x3F,	0x3F,	0x3E,	0x1F,	0x1E,
+				0x3E,	0x0E,	0x1E,	0x3D,	0x3D },
+	{ STV0900_8PSK_35,	0x3c,	0x0c,	0x1c,	0x3b,	0x0c,
+				0x3b,	0x2b,	0x2b,	0x1b,	0x2b },
+	{ STV0900_8PSK_23,	0x1d,	0x0c,	0x3c,	0x0c,	0x2c,
+				0x3b,	0x0c,	0x2b,	0x2b,	0x2b },
+	{ STV0900_8PSK_34,	0x0e,	0x1c,	0x3d,	0x0c,	0x0d,
+				0x3b,	0x2c,	0x3b,	0x0c,	0x2b },
+	{ STV0900_8PSK_56,	0x2e,	0x3e,	0x1e,	0x2e,	0x2d,
+				0x1e,	0x3c,	0x2d,	0x2c,	0x1d },
+	{ STV0900_8PSK_89,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,
+				0x1e,	0x0d,	0x2d,	0x3c,	0x1d },
+	{ STV0900_8PSK_910,	0x3e,	0x3e, 	0x1e,	0x2e, 	0x3d,
+				0x1e,	0x1d,	0x2d,	0x0d,	0x1d },
 };
 
 
 
 /* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_16APSK_23,	0x0C,	0x0C,	0x0C,	0x0C,	0x1D,	0x0C,	0x3C,	0x0C,	0x2C,	0x0C },
-	{ STV0900_16APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0E,	0x0C,	0x2D,	0x0C,	0x1D,	0x0C },
-	{ STV0900_16APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,	0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
-	{ STV0900_16APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,	0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
-	{ STV0900_16APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,	0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
-	{ STV0900_16APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,	0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
-	{ STV0900_32APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
-	{ STV0900_32APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C }
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_16APSK_23,	0x0C,	0x0C,	0x0C,	0x0C,	0x1D,
+				0x0C,	0x3C,	0x0C,	0x2C,	0x0C },
+	{ STV0900_16APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0E,
+				0x0C,	0x2D,	0x0C,	0x1D,	0x0C },
+	{ STV0900_16APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,
+				0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
+	{ STV0900_16APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x1E,
+				0x0C,	0x3D,	0x0C,	0x2D,	0x0C },
+	{ STV0900_16APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,
+				0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
+	{ STV0900_16APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x2E,
+				0x0C,	0x0E,	0x0C,	0x3D,	0x0C },
+	{ STV0900_32APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_45,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_56,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_89,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
+	{ STV0900_32APSK_910,	0x0C,	0x0C,	0x0C,	0x0C,	0x0C,
+				0x0C,	0x0C,	0x0C,	0x0C,	0x0C },
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon 	10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
-	{ STV0900_QPSK_14,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,	0x2F,	0x2D,	0x1F,	0x3D,	0x3E },
-	{ STV0900_QPSK_13,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,	0x2F,	0x3D,	0x0F,	0x3D,	0x2E },
-	{ STV0900_QPSK_25,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,	0x1F,	0x3D,	0x3E,	0x3D,	0x2E }
+	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	{ STV0900_QPSK_14,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
+				0x2F,	0x2D,	0x1F,	0x3D,	0x3E },
+	{ STV0900_QPSK_13,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
+				0x2F,	0x3D,	0x0F,	0x3D,	0x2E },
+	{ STV0900_QPSK_25,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,
+				0x1F,	0x3D,	0x3E,	0x3D,	0x2E }
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier  short Frame, cut 1.2 and 2.0 */
-static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4]	= {
-	/*Mod	2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */
-	{ STV0900_QPSK,		0x3C,	0x2F,	0x2B,	0x2E,	0x0B,	0x0E,	0x3A,	0x0E,	0x2A,	0x3D },
-	{ STV0900_8PSK,		0x0B,	0x3E,	0x2A,	0x0E,	0x0A,	0x2D,	0x19,	0x0D,	0x09,	0x3C },
-	{ STV0900_16APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,	0x1E,	0x3A,	0x3D,	0x2A,	0x2D },
-	{ STV0900_32APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,	0x1E,	0x3A,	0x3D,	0x2A,	0x2D }
+static const
+struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+	/*Mod		2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
+			10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
+	{ STV0900_QPSK,		0x3C,	0x2F,	0x2B,	0x2E,	0x0B,
+				0x0E,	0x3A,	0x0E,	0x2A,	0x3D },
+	{ STV0900_8PSK,		0x0B,	0x3E,	0x2A,	0x0E,	0x0A,
+				0x2D,	0x19,	0x0D,	0x09,	0x3C },
+	{ STV0900_16APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,
+				0x1E,	0x3A,	0x3D,	0x2A,	0x2D },
+	{ STV0900_32APSK,	0x1B,	0x1E,	0x1B,	0x1E,	0x1B,
+				0x1E,	0x3A,	0x3D,	0x2A,	0x2D }
 };
 
-static const u16 STV0900_InitVal[182][2] = {
+static	const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	{ STV0900_QPSK_12,	0x3C,	0x2C,	0x0C,	0x2C,	0x1B,
+				0x2C,	0x1B,	0x1C,	0x0B, 	0x3B },
+	{ STV0900_QPSK_35,	0x0D,	0x0D,	0x0C,	0x0D,	0x1B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_23,	0x1D,	0x0D,	0x0C,	0x1D,	0x2B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_34,	0x1D,	0x1D,	0x0C,	0x1D,	0x2B,
+				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
+	{ STV0900_QPSK_45,	0x2D,	0x1D,	0x1C,	0x1D,	0x2B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_56,	0x2D,	0x1D,	0x1C,	0x1D,	0x2B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_89,	0x3D,	0x2D,	0x1C,	0x1D,	0x3B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_QPSK_910,	0x3D,	0x2D,	0x1C,	0x1D,	0x3B,
+				0x3C,	0x2B,	0x0C,	0x1B,	0x3B },
+	{ STV0900_8PSK_35,	0x39,	0x19,	0x39,	0x19,	0x19,
+				0x19,	0x19,	0x19,	0x09,	0x19 },
+	{ STV0900_8PSK_23,	0x2A,	0x39,	0x1A,	0x0A,	0x39,
+				0x0A,	0x29,	0x39,	0x29,	0x0A },
+	{ STV0900_8PSK_34,	0x0B,	0x3A,	0x0B,	0x0B,	0x3A,
+				0x1B,	0x1A,	0x0B,	0x1A,	0x3A },
+	{ STV0900_8PSK_56,	0x0C,	0x1B,	0x3B,	0x2B,	0x1B,
+				0x3B,	0x3A,	0x3B,	0x3A,	0x1B },
+	{ STV0900_8PSK_89,	0x2C,	0x2C,	0x2C,	0x1C,	0x2B,
+				0x0C,	0x0B,	0x3B,	0x0B,	0x1B },
+	{ STV0900_8PSK_910,	0x2C,	0x3C,	0x2C,	0x1C,	0x3B,
+				0x1C,	0x0B,	0x3B,	0x0B,	0x1B }
+};
+
+static	const
+struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	{ STV0900_16APSK_23,	0x0A,	0x0A,	0x0A,	0x0A,	0x1A,
+				0x0A,	0x3A,	0x0A,	0x2A,	0x0A },
+	{ STV0900_16APSK_34,	0x0A,	0x0A,	0x0A,	0x0A,	0x0B,
+				0x0A,	0x3B,	0x0A,	0x1B,	0x0A },
+	{ STV0900_16APSK_45,	0x0A,	0x0A,	0x0A,	0x0A,	0x1B,
+				0x0A,	0x3B,	0x0A,	0x2B,	0x0A },
+	{ STV0900_16APSK_56,	0x0A,	0x0A,	0x0A,	0x0A,	0x1B,
+				0x0A,	0x3B,	0x0A,	0x2B,	0x0A },
+	{ STV0900_16APSK_89,	0x0A,	0x0A,	0x0A,	0x0A,	0x2B,
+				0x0A,	0x0C,	0x0A,	0x3B,	0x0A },
+	{ STV0900_16APSK_910,	0x0A,	0x0A,	0x0A,	0x0A,	0x2B,
+				0x0A,	0x0C,	0x0A,	0x3B,	0x0A },
+	{ STV0900_32APSK_34,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_45,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_56,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_89,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A },
+	{ STV0900_32APSK_910,	0x0A,	0x0A,	0x0A,	0x0A,	0x0A,
+				0x0A,	0x0A,	0x0A,	0x0A,	0x0A }
+};
+
+static	const
+struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
+	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
+				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff*/
+	{ STV0900_QPSK_14,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
+				0x2C,	0x2A,	0x1C,	0x3A,	0x3B },
+	{ STV0900_QPSK_13,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
+				0x2C,	0x3A,	0x0C,	0x3A,	0x2B },
+	{ STV0900_QPSK_25,	0x1C,	0x3C,	0x1B,	0x3C,	0x3A,
+				0x1C,	0x3A,	0x3B,	0x3A,	0x2B }
+};
+
+static	const struct stv0900_short_frames_car_loop_optim_vs_mod
+FE_STV0900_S2ShortCarLoopCut30[4] = {
+	/*Mod		2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
+	{ STV0900_QPSK,		0x2C,	0x2B,	0x0B,	0x0B,	0x3A },
+	{ STV0900_8PSK,		0x3B,	0x0B,	0x2A,	0x0A,	0x39 },
+	{ STV0900_16APSK,	0x1B,	0x1B,	0x1B,	0x3A,	0x2A },
+	{ STV0900_32APSK,	0x1B,	0x1B,	0x1B,	0x3A,	0x2A },
+
+};
+
+static const u16 STV0900_InitVal[181][2] = {
 	{ R0900_OUTCFG		, 0x00	},
-	{ R0900_MODECFG		, 0xff	},
 	{ R0900_AGCRF1CFG	, 0x11	},
 	{ R0900_AGCRF2CFG	, 0x13	},
 	{ R0900_TSGENERAL1X	, 0x14	},
@@ -381,7 +524,7 @@ static const u16 STV0900_InitVal[182][2]
 	{ R0900_GAINLLR_NF15	, 0x1A	},
 	{ R0900_GAINLLR_NF16	, 0x1F	},
 	{ R0900_GAINLLR_NF17	, 0x21	},
-	{ R0900_RCCFGH		, 0x20	},
+	{ R0900_RCCFG2		, 0x20	},
 	{ R0900_P1_FECM		, 0x01	}, /*disable DSS modes*/
 	{ R0900_P2_FECM		, 0x01	}, /*disable DSS modes*/
 	{ R0900_P1_PRVIT	, 0x2F	}, /*disable puncture rate 6/7*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -46,22 +46,6 @@
 #define FALSE (!TRUE)
 #endif
 
-#define	dmd_reg(a, b, c) \
-	do { \
-		a = 0; \
-		switch (demod) { \
-		case STV0900_DEMOD_1: \
-		default: \
-			a = b; \
-			break; \
-		case STV0900_DEMOD_2: \
-			a = c; \
-			break; \
-		} \
-	} while (0)
-
-static int stvdebug;
-
 #define dprintk(args...) \
 	do { \
 		if (stvdebug) \
@@ -70,6 +54,8 @@ static int stvdebug;
 
 #define STV0900_MAXLOOKUPSIZE 500
 #define STV0900_BLIND_SEARCH_AGC2_TH 700
+#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
+#define IQPOWER_THRESHOLD  30
 
 /* One point of the lookup table */
 struct stv000_lookpoint {
@@ -263,14 +249,14 @@ struct stv0900_init_params{
 	int	tuner1_adc;
 
 	/* IQ from the tuner1 to the demod */
-	enum stv0900_iq_inversion	tun1_iq_inversion;
+	enum stv0900_iq_inversion	tun1_iq_inv;
 	enum fe_stv0900_clock_type	path2_ts_clock;
 
 	u8	tun2_maddress;
 	int	tuner2_adc;
 
 	/* IQ from the tuner2 to the demod */
-	enum stv0900_iq_inversion	tun2_iq_inversion;
+	enum stv0900_iq_inversion	tun2_iq_inv;
 	struct stv0900_reg		*ts_config;
 };
 
@@ -300,7 +286,7 @@ struct stv0900_signal_info {
 	enum fe_stv0900_modcode			modcode;
 	enum fe_stv0900_modulation		modulation;
 	enum fe_stv0900_pilot			pilot;
-	enum fe_stv0900_frame_length		frame_length;
+	enum fe_stv0900_frame_length		frame_len;
 	enum stv0900_iq_inversion		spectrum;
 	enum fe_stv0900_rolloff			rolloff;
 
@@ -318,47 +304,25 @@ struct stv0900_internal{
 	/* Demodulator use for single demod or for dual demod) */
 	enum fe_stv0900_demod_mode	demod_mode;
 
-	/*Demod 1*/
-	s32	tuner1_freq;
-	s32	tuner1_bw;
-	s32	dmd1_symbol_rate;
-	s32	dmd1_srch_range;
+	/*Demods */
+	s32	freq[2];
+	s32	bw[2];
+	s32	symbol_rate[2];
+	s32	srch_range[2];
 
 	/* algorithm for search Blind, Cold or Warm*/
-	enum fe_stv0900_search_algo	dmd1_srch_algo;
+	enum fe_stv0900_search_algo	srch_algo[2];
 	/* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
-	enum fe_stv0900_search_standard	dmd1_srch_standard;
+	enum fe_stv0900_search_standard	srch_standard[2];
 	/* inversion search : auto, auto norma first, normal or inverted */
-	enum fe_stv0900_search_iq	dmd1_srch_iq_inv;
-	enum fe_stv0900_modcode		dmd1_modcode;
-	enum fe_stv0900_modulation	dmd1_modulation;
-	enum fe_stv0900_fec		dmd1_fec;
-
-	struct stv0900_signal_info	dmd1_rslts;
-	enum fe_stv0900_signal_type	dmd1_state;
-
-	enum fe_stv0900_error		dmd1_err;
-
-	/*Demod 2*/
-	s32	tuner2_freq;
-	s32	tuner2_bw;
-	s32	dmd2_symbol_rate;
-	s32	dmd2_srch_range;
-
-	enum fe_stv0900_search_algo	dmd2_srch_algo;
-	enum fe_stv0900_search_standard	dmd2_srch_stndrd;
-	/* inversion search : auto, auto normal first, normal or inverted */
-	enum fe_stv0900_search_iq	dmd2_srch_iq_inv;
-	enum fe_stv0900_modcode		dmd2_modcode;
-	enum fe_stv0900_modulation	dmd2_modulation;
-	enum fe_stv0900_fec		dmd2_fec;
+	enum fe_stv0900_search_iq	srch_iq_inv[2];
+	enum fe_stv0900_modcode		modcode[2];
+	enum fe_stv0900_modulation	modulation[2];
+	enum fe_stv0900_fec		fec[2];
 
-	/* results of the search*/
-	struct stv0900_signal_info	dmd2_rslts;
-	/* current state of the search algorithm */
-	enum fe_stv0900_signal_type	dmd2_state;
+	struct stv0900_signal_info	result[2];
+	enum fe_stv0900_error		err[2];
 
-	enum fe_stv0900_error		dmd2_err;
 
 	struct i2c_adapter	*i2c_adap;
 	u8			i2c_addr;
@@ -379,6 +343,8 @@ struct stv0900_state {
 	int demod;
 };
 
+extern int stvdebug;
+
 extern s32 ge2comp(s32 a, s32 width);
 
 extern void stv0900_write_reg(struct stv0900_internal *i_params,
@@ -418,13 +384,14 @@ extern u8 stv0900_get_optim_short_carr_l
 extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
 				enum fe_stv0900_demod_num demod);
 
-extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+extern enum
+fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
 				enum fe_stv0900_demod_num demod);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_reg.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_reg.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *
  * GNU General Public License for more details.
  *
@@ -26,3762 +26,3950 @@
 #ifndef STV0900_REG_H
 #define STV0900_REG_H
 
+extern s32 shiftx(s32 x, int demod, s32 shift);
+
+#define REGx(x) shiftx(x, demod, 0x200)
+#define FLDx(x) shiftx(x, demod, 0x2000000)
+
 /*MID*/
-#define R0900_MID  0xf100
-#define F0900_MCHIP_IDENT  0xf10000f0
-#define F0900_MRELEASE  0xf100000f
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
 
 /*DACR1*/
-#define R0900_DACR1  0xf113
-#define F0900_DAC_MODE  0xf11300e0
-#define F0900_DAC_VALUE1  0xf113000f
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
 
 /*DACR2*/
-#define R0900_DACR2  0xf114
-#define F0900_DAC_VALUE0  0xf11400ff
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
 
 /*OUTCFG*/
-#define R0900_OUTCFG  0xf11c
-#define F0900_INV_DATA6  0xf11c0080
-#define F0900_OUTSERRS1_HZ  0xf11c0040
-#define F0900_OUTSERRS2_HZ  0xf11c0020
-#define F0900_OUTSERRS3_HZ  0xf11c0010
-#define F0900_OUTPARRS3_HZ  0xf11c0008
-#define F0900_OUTHZ3_CONTROL  0xf11c0007
-
-/*MODECFG*/
-#define R0900_MODECFG  0xf11d
-#define F0900_FECSPY_SEL_2  0xf11d0020
-#define F0900_HWARE_SEL_2  0xf11d0010
-#define F0900_PKTDEL_SEL_2  0xf11d0008
-#define F0900_DISEQC_SEL_2  0xf11d0004
-#define F0900_VIT_SEL_2  0xf11d0002
-#define F0900_DEMOD_SEL_2  0xf11d0001
+#define R0900_OUTCFG 0xf11c
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
 
 /*IRQSTATUS3*/
-#define R0900_IRQSTATUS3  0xf120
-#define F0900_SPLL_LOCK  0xf1200020
-#define F0900_SSTREAM_LCK_3  0xf1200010
-#define F0900_SSTREAM_LCK_2  0xf1200008
-#define F0900_SSTREAM_LCK_1  0xf1200004
-#define F0900_SDVBS1_PRF_2  0xf1200002
-#define F0900_SDVBS1_PRF_1  0xf1200001
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
 
 /*IRQSTATUS2*/
-#define R0900_IRQSTATUS2  0xf121
-#define F0900_SSPY_ENDSIM_3  0xf1210080
-#define F0900_SSPY_ENDSIM_2  0xf1210040
-#define F0900_SSPY_ENDSIM_1  0xf1210020
-#define F0900_SPKTDEL_ERROR_2  0xf1210010
-#define F0900_SPKTDEL_LOCKB_2  0xf1210008
-#define F0900_SPKTDEL_LOCK_2  0xf1210004
-#define F0900_SPKTDEL_ERROR_1  0xf1210002
-#define F0900_SPKTDEL_LOCKB_1  0xf1210001
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
 
 /*IRQSTATUS1*/
-#define R0900_IRQSTATUS1  0xf122
-#define F0900_SPKTDEL_LOCK_1  0xf1220080
-#define F0900_SEXTPINB2  0xf1220040
-#define F0900_SEXTPIN2  0xf1220020
-#define F0900_SEXTPINB1  0xf1220010
-#define F0900_SEXTPIN1  0xf1220008
-#define F0900_SDEMOD_LOCKB_2  0xf1220004
-#define F0900_SDEMOD_LOCK_2  0xf1220002
-#define F0900_SDEMOD_IRQ_2  0xf1220001
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
 
 /*IRQSTATUS0*/
-#define R0900_IRQSTATUS0  0xf123
-#define F0900_SDEMOD_LOCKB_1  0xf1230080
-#define F0900_SDEMOD_LOCK_1  0xf1230040
-#define F0900_SDEMOD_IRQ_1  0xf1230020
-#define F0900_SBCH_ERRFLAG  0xf1230010
-#define F0900_SDISEQC2RX_IRQ  0xf1230008
-#define F0900_SDISEQC2TX_IRQ  0xf1230004
-#define F0900_SDISEQC1RX_IRQ  0xf1230002
-#define F0900_SDISEQC1TX_IRQ  0xf1230001
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
 
 /*IRQMASK3*/
-#define R0900_IRQMASK3  0xf124
-#define F0900_MPLL_LOCK  0xf1240020
-#define F0900_MSTREAM_LCK_3  0xf1240010
-#define F0900_MSTREAM_LCK_2  0xf1240008
-#define F0900_MSTREAM_LCK_1  0xf1240004
-#define F0900_MDVBS1_PRF_2  0xf1240002
-#define F0900_MDVBS1_PRF_1  0xf1240001
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
 
 /*IRQMASK2*/
-#define R0900_IRQMASK2  0xf125
-#define F0900_MSPY_ENDSIM_3  0xf1250080
-#define F0900_MSPY_ENDSIM_2  0xf1250040
-#define F0900_MSPY_ENDSIM_1  0xf1250020
-#define F0900_MPKTDEL_ERROR_2  0xf1250010
-#define F0900_MPKTDEL_LOCKB_2  0xf1250008
-#define F0900_MPKTDEL_LOCK_2  0xf1250004
-#define F0900_MPKTDEL_ERROR_1  0xf1250002
-#define F0900_MPKTDEL_LOCKB_1  0xf1250001
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
 
 /*IRQMASK1*/
-#define R0900_IRQMASK1  0xf126
-#define F0900_MPKTDEL_LOCK_1  0xf1260080
-#define F0900_MEXTPINB2  0xf1260040
-#define F0900_MEXTPIN2  0xf1260020
-#define F0900_MEXTPINB1  0xf1260010
-#define F0900_MEXTPIN1  0xf1260008
-#define F0900_MDEMOD_LOCKB_2  0xf1260004
-#define F0900_MDEMOD_LOCK_2  0xf1260002
-#define F0900_MDEMOD_IRQ_2  0xf1260001
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
 
 /*IRQMASK0*/
-#define R0900_IRQMASK0  0xf127
-#define F0900_MDEMOD_LOCKB_1  0xf1270080
-#define F0900_MDEMOD_LOCK_1  0xf1270040
-#define F0900_MDEMOD_IRQ_1  0xf1270020
-#define F0900_MBCH_ERRFLAG  0xf1270010
-#define F0900_MDISEQC2RX_IRQ  0xf1270008
-#define F0900_MDISEQC2TX_IRQ  0xf1270004
-#define F0900_MDISEQC1RX_IRQ  0xf1270002
-#define F0900_MDISEQC1TX_IRQ  0xf1270001
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
 
 /*I2CCFG*/
-#define R0900_I2CCFG  0xf129
-#define F0900_I2C2_FASTMODE  0xf1290080
-#define F0900_STATUS_WR2  0xf1290040
-#define F0900_I2C2ADDR_INC  0xf1290030
-#define F0900_I2C_FASTMODE  0xf1290008
-#define F0900_STATUS_WR  0xf1290004
-#define F0900_I2CADDR_INC  0xf1290003
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_I2CADDR_INC 0xf1290003
 
 /*P1_I2CRPT*/
-#define R0900_P1_I2CRPT  0xf12a
-#define F0900_P1_I2CT_ON  0xf12a0080
-#define F0900_P1_ENARPT_LEVEL  0xf12a0070
-#define F0900_P1_SCLT_DELAY  0xf12a0008
-#define F0900_P1_STOP_ENABLE  0xf12a0004
-#define F0900_P1_STOP_SDAT2SDA  0xf12a0002
+#define R0900_P1_I2CRPT 0xf12a
+#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
 
 /*P2_I2CRPT*/
-#define R0900_P2_I2CRPT  0xf12b
-#define F0900_P2_I2CT_ON  0xf12b0080
-#define F0900_P2_ENARPT_LEVEL  0xf12b0070
-#define F0900_P2_SCLT_DELAY  0xf12b0008
-#define F0900_P2_STOP_ENABLE  0xf12b0004
-#define F0900_P2_STOP_SDAT2SDA  0xf12b0002
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*IOPVALUE6*/
+#define R0900_IOPVALUE6 0xf138
+#define F0900_VSCL 0xf1380004
+#define F0900_VSDA 0xf1380002
+#define F0900_VDATA3_0 0xf1380001
+
+/*IOPVALUE5*/
+#define R0900_IOPVALUE5 0xf139
+#define F0900_VDATA3_1 0xf1390080
+#define F0900_VDATA3_2 0xf1390040
+#define F0900_VDATA3_3 0xf1390020
+#define F0900_VDATA3_4 0xf1390010
+#define F0900_VDATA3_5 0xf1390008
+#define F0900_VDATA3_6 0xf1390004
+#define F0900_VDATA3_7 0xf1390002
+#define F0900_VCLKOUT3 0xf1390001
+
+/*IOPVALUE4*/
+#define R0900_IOPVALUE4 0xf13a
+#define F0900_VSTROUT3 0xf13a0080
+#define F0900_VDPN3 0xf13a0040
+#define F0900_VERROR3 0xf13a0020
+#define F0900_VDATA2_7 0xf13a0010
+#define F0900_VCLKOUT2 0xf13a0008
+#define F0900_VSTROUT2 0xf13a0004
+#define F0900_VDPN2 0xf13a0002
+#define F0900_VERROR2 0xf13a0001
+
+/*IOPVALUE3*/
+#define R0900_IOPVALUE3 0xf13b
+#define F0900_VDATA1_7 0xf13b0080
+#define F0900_VCLKOUT1 0xf13b0040
+#define F0900_VSTROUT1 0xf13b0020
+#define F0900_VDPN1 0xf13b0010
+#define F0900_VERROR1 0xf13b0008
+#define F0900_VCLKOUT27 0xf13b0004
+#define F0900_VDISEQCOUT2 0xf13b0002
+#define F0900_VSCLT2 0xf13b0001
+
+/*IOPVALUE2*/
+#define R0900_IOPVALUE2 0xf13c
+#define F0900_VSDAT2 0xf13c0080
+#define F0900_VAGCRF2 0xf13c0040
+#define F0900_VDISEQCOUT1 0xf13c0020
+#define F0900_VSCLT1 0xf13c0010
+#define F0900_VSDAT1 0xf13c0008
+#define F0900_VAGCRF1 0xf13c0004
+#define F0900_VDIRCLK 0xf13c0002
+#define F0900_VSTDBY 0xf13c0001
+
+/*IOPVALUE1*/
+#define R0900_IOPVALUE1 0xf13d
+#define F0900_VCS1 0xf13d0080
+#define F0900_VCS0 0xf13d0040
+#define F0900_VGPIO13 0xf13d0020
+#define F0900_VGPIO12 0xf13d0010
+#define F0900_VGPIO11 0xf13d0008
+#define F0900_VGPIO10 0xf13d0004
+#define F0900_VGPIO9 0xf13d0002
+#define F0900_VGPIO8 0xf13d0001
+
+/*IOPVALUE0*/
+#define R0900_IOPVALUE0 0xf13e
+#define F0900_VGPIO7 0xf13e0080
+#define F0900_VGPIO6 0xf13e0040
+#define F0900_VGPIO5 0xf13e0020
+#define F0900_VGPIO4 0xf13e0010
+#define F0900_VGPIO3 0xf13e0008
+#define F0900_VGPIO2 0xf13e0004
+#define F0900_VGPIO1 0xf13e0002
+#define F0900_VCLKI2 0xf13e0001
 
 /*CLKI2CFG*/
-#define R0900_CLKI2CFG  0xf140
-#define F0900_CLKI2_OPD  0xf1400080
-#define F0900_CLKI2_CONFIG  0xf140007e
-#define F0900_CLKI2_XOR  0xf1400001
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
 
 /*GPIO1CFG*/
-#define R0900_GPIO1CFG  0xf141
-#define F0900_GPIO1_OPD  0xf1410080
-#define F0900_GPIO1_CONFIG  0xf141007e
-#define F0900_GPIO1_XOR  0xf1410001
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
 
 /*GPIO2CFG*/
-#define R0900_GPIO2CFG  0xf142
-#define F0900_GPIO2_OPD  0xf1420080
-#define F0900_GPIO2_CONFIG  0xf142007e
-#define F0900_GPIO2_XOR  0xf1420001
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
 
 /*GPIO3CFG*/
-#define R0900_GPIO3CFG  0xf143
-#define F0900_GPIO3_OPD  0xf1430080
-#define F0900_GPIO3_CONFIG  0xf143007e
-#define F0900_GPIO3_XOR  0xf1430001
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
 
 /*GPIO4CFG*/
-#define R0900_GPIO4CFG  0xf144
-#define F0900_GPIO4_OPD  0xf1440080
-#define F0900_GPIO4_CONFIG  0xf144007e
-#define F0900_GPIO4_XOR  0xf1440001
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
 
 /*GPIO5CFG*/
-#define R0900_GPIO5CFG  0xf145
-#define F0900_GPIO5_OPD  0xf1450080
-#define F0900_GPIO5_CONFIG  0xf145007e
-#define F0900_GPIO5_XOR  0xf1450001
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
 
 /*GPIO6CFG*/
-#define R0900_GPIO6CFG  0xf146
-#define F0900_GPIO6_OPD  0xf1460080
-#define F0900_GPIO6_CONFIG  0xf146007e
-#define F0900_GPIO6_XOR  0xf1460001
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
 
 /*GPIO7CFG*/
-#define R0900_GPIO7CFG  0xf147
-#define F0900_GPIO7_OPD  0xf1470080
-#define F0900_GPIO7_CONFIG  0xf147007e
-#define F0900_GPIO7_XOR  0xf1470001
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
 
 /*GPIO8CFG*/
-#define R0900_GPIO8CFG  0xf148
-#define F0900_GPIO8_OPD  0xf1480080
-#define F0900_GPIO8_CONFIG  0xf148007e
-#define F0900_GPIO8_XOR  0xf1480001
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
 
 /*GPIO9CFG*/
-#define R0900_GPIO9CFG  0xf149
-#define F0900_GPIO9_OPD  0xf1490080
-#define F0900_GPIO9_CONFIG  0xf149007e
-#define F0900_GPIO9_XOR  0xf1490001
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
 
 /*GPIO10CFG*/
-#define R0900_GPIO10CFG  0xf14a
-#define F0900_GPIO10_OPD  0xf14a0080
-#define F0900_GPIO10_CONFIG  0xf14a007e
-#define F0900_GPIO10_XOR  0xf14a0001
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
 
 /*GPIO11CFG*/
-#define R0900_GPIO11CFG  0xf14b
-#define F0900_GPIO11_OPD  0xf14b0080
-#define F0900_GPIO11_CONFIG  0xf14b007e
-#define F0900_GPIO11_XOR  0xf14b0001
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
 
 /*GPIO12CFG*/
-#define R0900_GPIO12CFG  0xf14c
-#define F0900_GPIO12_OPD  0xf14c0080
-#define F0900_GPIO12_CONFIG  0xf14c007e
-#define F0900_GPIO12_XOR  0xf14c0001
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
 
 /*GPIO13CFG*/
-#define R0900_GPIO13CFG  0xf14d
-#define F0900_GPIO13_OPD  0xf14d0080
-#define F0900_GPIO13_CONFIG  0xf14d007e
-#define F0900_GPIO13_XOR  0xf14d0001
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
 
 /*CS0CFG*/
-#define R0900_CS0CFG  0xf14e
-#define F0900_CS0_OPD  0xf14e0080
-#define F0900_CS0_CONFIG  0xf14e007e
-#define F0900_CS0_XOR  0xf14e0001
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
 
 /*CS1CFG*/
-#define R0900_CS1CFG  0xf14f
-#define F0900_CS1_OPD  0xf14f0080
-#define F0900_CS1_CONFIG  0xf14f007e
-#define F0900_CS1_XOR  0xf14f0001
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
 
 /*STDBYCFG*/
-#define R0900_STDBYCFG  0xf150
-#define F0900_STDBY_OPD  0xf1500080
-#define F0900_STDBY_CONFIG  0xf150007e
-#define F0900_STBDY_XOR  0xf1500001
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
 
 /*DIRCLKCFG*/
-#define R0900_DIRCLKCFG  0xf151
-#define F0900_DIRCLK_OPD  0xf1510080
-#define F0900_DIRCLK_CONFIG  0xf151007e
-#define F0900_DIRCLK_XOR  0xf1510001
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
 
 /*AGCRF1CFG*/
-#define R0900_AGCRF1CFG  0xf152
-#define F0900_AGCRF1_OPD  0xf1520080
-#define F0900_AGCRF1_CONFIG  0xf152007e
-#define F0900_AGCRF1_XOR  0xf1520001
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
 
 /*SDAT1CFG*/
-#define R0900_SDAT1CFG  0xf153
-#define F0900_SDAT1_OPD  0xf1530080
-#define F0900_SDAT1_CONFIG  0xf153007e
-#define F0900_SDAT1_XOR  0xf1530001
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
 
 /*SCLT1CFG*/
-#define R0900_SCLT1CFG  0xf154
-#define F0900_SCLT1_OPD  0xf1540080
-#define F0900_SCLT1_CONFIG  0xf154007e
-#define F0900_SCLT1_XOR  0xf1540001
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
 
 /*DISEQCO1CFG*/
-#define R0900_DISEQCO1CFG  0xf155
-#define F0900_DISEQCO1_OPD  0xf1550080
-#define F0900_DISEQCO1_CONFIG  0xf155007e
-#define F0900_DISEQC1_XOR  0xf1550001
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
 
 /*AGCRF2CFG*/
-#define R0900_AGCRF2CFG  0xf156
-#define F0900_AGCRF2_OPD  0xf1560080
-#define F0900_AGCRF2_CONFIG  0xf156007e
-#define F0900_AGCRF2_XOR  0xf1560001
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
 
 /*SDAT2CFG*/
-#define R0900_SDAT2CFG  0xf157
-#define F0900_SDAT2_OPD  0xf1570080
-#define F0900_SDAT2_CONFIG  0xf157007e
-#define F0900_SDAT2_XOR  0xf1570001
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
 
 /*SCLT2CFG*/
-#define R0900_SCLT2CFG  0xf158
-#define F0900_SCLT2_OPD  0xf1580080
-#define F0900_SCLT2_CONFIG  0xf158007e
-#define F0900_SCLT2_XOR  0xf1580001
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
 
 /*DISEQCO2CFG*/
-#define R0900_DISEQCO2CFG  0xf159
-#define F0900_DISEQCO2_OPD  0xf1590080
-#define F0900_DISEQCO2_CONFIG  0xf159007e
-#define F0900_DISEQC2_XOR  0xf1590001
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
 
 /*CLKOUT27CFG*/
-#define R0900_CLKOUT27CFG  0xf15a
-#define F0900_CLKOUT27_OPD  0xf15a0080
-#define F0900_CLKOUT27_CONFIG  0xf15a007e
-#define F0900_CLKOUT27_XOR  0xf15a0001
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
 
 /*ERROR1CFG*/
-#define R0900_ERROR1CFG  0xf15b
-#define F0900_ERROR1_OPD  0xf15b0080
-#define F0900_ERROR1_CONFIG  0xf15b007e
-#define F0900_ERROR1_XOR  0xf15b0001
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
 
 /*DPN1CFG*/
-#define R0900_DPN1CFG  0xf15c
-#define F0900_DPN1_OPD  0xf15c0080
-#define F0900_DPN1_CONFIG  0xf15c007e
-#define F0900_DPN1_XOR  0xf15c0001
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
 
 /*STROUT1CFG*/
-#define R0900_STROUT1CFG  0xf15d
-#define F0900_STROUT1_OPD  0xf15d0080
-#define F0900_STROUT1_CONFIG  0xf15d007e
-#define F0900_STROUT1_XOR  0xf15d0001
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
 
 /*CLKOUT1CFG*/
-#define R0900_CLKOUT1CFG  0xf15e
-#define F0900_CLKOUT1_OPD  0xf15e0080
-#define F0900_CLKOUT1_CONFIG  0xf15e007e
-#define F0900_CLKOUT1_XOR  0xf15e0001
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
 
 /*DATA71CFG*/
-#define R0900_DATA71CFG  0xf15f
-#define F0900_DATA71_OPD  0xf15f0080
-#define F0900_DATA71_CONFIG  0xf15f007e
-#define F0900_DATA71_XOR  0xf15f0001
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
 
 /*ERROR2CFG*/
-#define R0900_ERROR2CFG  0xf160
-#define F0900_ERROR2_OPD  0xf1600080
-#define F0900_ERROR2_CONFIG  0xf160007e
-#define F0900_ERROR2_XOR  0xf1600001
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
 
 /*DPN2CFG*/
-#define R0900_DPN2CFG  0xf161
-#define F0900_DPN2_OPD  0xf1610080
-#define F0900_DPN2_CONFIG  0xf161007e
-#define F0900_DPN2_XOR  0xf1610001
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
 
 /*STROUT2CFG*/
-#define R0900_STROUT2CFG  0xf162
-#define F0900_STROUT2_OPD  0xf1620080
-#define F0900_STROUT2_CONFIG  0xf162007e
-#define F0900_STROUT2_XOR  0xf1620001
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
 
 /*CLKOUT2CFG*/
-#define R0900_CLKOUT2CFG  0xf163
-#define F0900_CLKOUT2_OPD  0xf1630080
-#define F0900_CLKOUT2_CONFIG  0xf163007e
-#define F0900_CLKOUT2_XOR  0xf1630001
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
 
 /*DATA72CFG*/
-#define R0900_DATA72CFG  0xf164
-#define F0900_DATA72_OPD  0xf1640080
-#define F0900_DATA72_CONFIG  0xf164007e
-#define F0900_DATA72_XOR  0xf1640001
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
 
 /*ERROR3CFG*/
-#define R0900_ERROR3CFG  0xf165
-#define F0900_ERROR3_OPD  0xf1650080
-#define F0900_ERROR3_CONFIG  0xf165007e
-#define F0900_ERROR3_XOR  0xf1650001
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
 
 /*DPN3CFG*/
-#define R0900_DPN3CFG  0xf166
-#define F0900_DPN3_OPD  0xf1660080
-#define F0900_DPN3_CONFIG  0xf166007e
-#define F0900_DPN3_XOR  0xf1660001
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
 
 /*STROUT3CFG*/
-#define R0900_STROUT3CFG  0xf167
-#define F0900_STROUT3_OPD  0xf1670080
-#define F0900_STROUT3_CONFIG  0xf167007e
-#define F0900_STROUT3_XOR  0xf1670001
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
 
 /*CLKOUT3CFG*/
-#define R0900_CLKOUT3CFG  0xf168
-#define F0900_CLKOUT3_OPD  0xf1680080
-#define F0900_CLKOUT3_CONFIG  0xf168007e
-#define F0900_CLKOUT3_XOR  0xf1680001
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
 
 /*DATA73CFG*/
-#define R0900_DATA73CFG  0xf169
-#define F0900_DATA73_OPD  0xf1690080
-#define F0900_DATA73_CONFIG  0xf169007e
-#define F0900_DATA73_XOR  0xf1690001
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*STRSTATUS1*/
+#define R0900_STRSTATUS1 0xf16a
+#define F0900_STRSTATUS_SEL2 0xf16a00f0
+#define F0900_STRSTATUS_SEL1 0xf16a000f
+
+/*STRSTATUS2*/
+#define R0900_STRSTATUS2 0xf16b
+#define F0900_STRSTATUS_SEL4 0xf16b00f0
+#define F0900_STRSTATUS_SEL3 0xf16b000f
+
+/*STRSTATUS3*/
+#define R0900_STRSTATUS3 0xf16c
+#define F0900_STRSTATUS_SEL6 0xf16c00f0
+#define F0900_STRSTATUS_SEL5 0xf16c000f
 
 /*FSKTFC2*/
-#define R0900_FSKTFC2  0xf170
-#define F0900_FSKT_KMOD  0xf17000fc
-#define F0900_FSKT_CAR2  0xf1700003
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
 
 /*FSKTFC1*/
-#define R0900_FSKTFC1  0xf171
-#define F0900_FSKT_CAR1  0xf17100ff
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
 
 /*FSKTFC0*/
-#define R0900_FSKTFC0  0xf172
-#define F0900_FSKT_CAR0  0xf17200ff
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
 
 /*FSKTDELTAF1*/
-#define R0900_FSKTDELTAF1  0xf173
-#define F0900_FSKT_DELTAF1  0xf173000f
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
 
 /*FSKTDELTAF0*/
-#define R0900_FSKTDELTAF0  0xf174
-#define F0900_FSKT_DELTAF0  0xf17400ff
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
 
 /*FSKTCTRL*/
-#define R0900_FSKTCTRL  0xf175
-#define F0900_FSKT_EN_SGN  0xf1750040
-#define F0900_FSKT_MOD_SGN  0xf1750020
-#define F0900_FSKT_MOD_EN  0xf175001c
-#define F0900_FSKT_DACMODE  0xf1750003
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
 
 /*FSKRFC2*/
-#define R0900_FSKRFC2  0xf176
-#define F0900_FSKR_DETSGN  0xf1760040
-#define F0900_FSKR_OUTSGN  0xf1760020
-#define F0900_FSKR_KAGC  0xf176001c
-#define F0900_FSKR_CAR2  0xf1760003
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
 
 /*FSKRFC1*/
-#define R0900_FSKRFC1  0xf177
-#define F0900_FSKR_CAR1  0xf17700ff
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
 
 /*FSKRFC0*/
-#define R0900_FSKRFC0  0xf178
-#define F0900_FSKR_CAR0  0xf17800ff
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
 
 /*FSKRK1*/
-#define R0900_FSKRK1  0xf179
-#define F0900_FSKR_K1_EXP  0xf17900e0
-#define F0900_FSKR_K1_MANT  0xf179001f
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
 
 /*FSKRK2*/
-#define R0900_FSKRK2  0xf17a
-#define F0900_FSKR_K2_EXP  0xf17a00e0
-#define F0900_FSKR_K2_MANT  0xf17a001f
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
 
 /*FSKRAGCR*/
-#define R0900_FSKRAGCR  0xf17b
-#define F0900_FSKR_OUTCTL  0xf17b00c0
-#define F0900_FSKR_AGC_REF  0xf17b003f
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
 
 /*FSKRAGC*/
-#define R0900_FSKRAGC  0xf17c
-#define F0900_FSKR_AGC_ACCU  0xf17c00ff
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
 
 /*FSKRALPHA*/
-#define R0900_FSKRALPHA  0xf17d
-#define F0900_FSKR_ALPHA_EXP  0xf17d001c
-#define F0900_FSKR_ALPHA_M  0xf17d0003
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
 
 /*FSKRPLTH1*/
-#define R0900_FSKRPLTH1  0xf17e
-#define F0900_FSKR_BETA  0xf17e00f0
-#define F0900_FSKR_PLL_TRESH1  0xf17e000f
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
 
 /*FSKRPLTH0*/
-#define R0900_FSKRPLTH0  0xf17f
-#define F0900_FSKR_PLL_TRESH0  0xf17f00ff
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
 
 /*FSKRDF1*/
-#define R0900_FSKRDF1  0xf180
-#define F0900_FSKR_OUT  0xf1800080
-#define F0900_FSKR_DELTAF1  0xf180001f
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
 
 /*FSKRDF0*/
-#define R0900_FSKRDF0  0xf181
-#define F0900_FSKR_DELTAF0  0xf18100ff
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
 
 /*FSKRSTEPP*/
-#define R0900_FSKRSTEPP  0xf182
-#define F0900_FSKR_STEP_PLUS  0xf18200ff
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
 
 /*FSKRSTEPM*/
-#define R0900_FSKRSTEPM  0xf183
-#define F0900_FSKR_STEP_MINUS  0xf18300ff
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
 
 /*FSKRDET1*/
-#define R0900_FSKRDET1  0xf184
-#define F0900_FSKR_DETECT  0xf1840080
-#define F0900_FSKR_CARDET_ACCU1  0xf184000f
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
 
 /*FSKRDET0*/
-#define R0900_FSKRDET0  0xf185
-#define F0900_FSKR_CARDET_ACCU0  0xf18500ff
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
 
 /*FSKRDTH1*/
-#define R0900_FSKRDTH1  0xf186
-#define F0900_FSKR_CARLOSS_THRESH1  0xf18600f0
-#define F0900_FSKR_CARDET_THRESH1  0xf186000f
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
 
 /*FSKRDTH0*/
-#define R0900_FSKRDTH0  0xf187
-#define F0900_FSKR_CARDET_THRESH0  0xf18700ff
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
 
 /*FSKRLOSS*/
-#define R0900_FSKRLOSS  0xf188
-#define F0900_FSKR_CARLOSS_THRESH0  0xf18800ff
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
 
 /*P2_DISTXCTL*/
-#define R0900_P2_DISTXCTL  0xf190
-#define F0900_P2_TIM_OFF  0xf1900080
-#define F0900_P2_DISEQC_RESET  0xf1900040
-#define F0900_P2_TIM_CMD  0xf1900030
-#define F0900_P2_DIS_PRECHARGE  0xf1900008
-#define F0900_P2_DISTX_MODE  0xf1900007
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
 
 /*P2_DISRXCTL*/
-#define R0900_P2_DISRXCTL  0xf191
-#define F0900_P2_RECEIVER_ON  0xf1910080
-#define F0900_P2_IGNO_SHORT22K  0xf1910040
-#define F0900_P2_ONECHIP_TRX  0xf1910020
-#define F0900_P2_EXT_ENVELOP  0xf1910010
-#define F0900_P2_PIN_SELECT  0xf191000c
-#define F0900_P2_IRQ_RXEND  0xf1910002
-#define F0900_P2_IRQ_4NBYTES  0xf1910001
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT0 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
 
 /*P2_DISRX_ST0*/
-#define R0900_P2_DISRX_ST0  0xf194
-#define F0900_P2_RX_END  0xf1940080
-#define F0900_P2_RX_ACTIVE  0xf1940040
-#define F0900_P2_SHORT_22KHZ  0xf1940020
-#define F0900_P2_CONT_TONE  0xf1940010
-#define F0900_P2_FIFO_4BREADY  0xf1940008
-#define F0900_P2_FIFO_EMPTY  0xf1940004
-#define F0900_P2_ABORT_DISRX  0xf1940001
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
 
 /*P2_DISRX_ST1*/
-#define R0900_P2_DISRX_ST1  0xf195
-#define F0900_P2_RX_FAIL  0xf1950080
-#define F0900_P2_FIFO_PARITYFAIL  0xf1950040
-#define F0900_P2_RX_NONBYTE  0xf1950020
-#define F0900_P2_FIFO_OVERFLOW  0xf1950010
-#define F0900_P2_FIFO_BYTENBR  0xf195000f
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
 
 /*P2_DISRXDATA*/
-#define R0900_P2_DISRXDATA  0xf196
-#define F0900_P2_DISRX_DATA  0xf19600ff
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
 
 /*P2_DISTXDATA*/
-#define R0900_P2_DISTXDATA  0xf197
-#define F0900_P2_DISEQC_FIFO  0xf19700ff
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
 
 /*P2_DISTXSTATUS*/
-#define R0900_P2_DISTXSTATUS  0xf198
-#define F0900_P2_TX_FAIL  0xf1980080
-#define F0900_P2_FIFO_FULL  0xf1980040
-#define F0900_P2_TX_IDLE  0xf1980020
-#define F0900_P2_GAP_BURST  0xf1980010
-#define F0900_P2_TXFIFO_BYTES  0xf198000f
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
 
 /*P2_F22TX*/
-#define R0900_P2_F22TX  0xf199
-#define F0900_P2_F22_REG  0xf19900ff
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
 
 /*P2_F22RX*/
-#define R0900_P2_F22RX  0xf19a
-#define F0900_P2_F22RX_REG  0xf19a00ff
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
 
 /*P2_ACRPRESC*/
-#define R0900_P2_ACRPRESC  0xf19c
-#define F0900_P2_ACR_CODFRDY  0xf19c0008
-#define F0900_P2_ACR_PRESC  0xf19c0007
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_PRESC 0xf19c0007
 
 /*P2_ACRDIV*/
-#define R0900_P2_ACRDIV  0xf19d
-#define F0900_P2_ACR_DIV  0xf19d00ff
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
 
 /*P1_DISTXCTL*/
-#define R0900_P1_DISTXCTL  0xf1a0
-#define F0900_P1_TIM_OFF  0xf1a00080
-#define F0900_P1_DISEQC_RESET  0xf1a00040
-#define F0900_P1_TIM_CMD  0xf1a00030
-#define F0900_P1_DIS_PRECHARGE  0xf1a00008
-#define F0900_P1_DISTX_MODE  0xf1a00007
+#define R0900_P1_DISTXCTL 0xf1a0
+#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
+#define F0900_P1_DISTX_MODE 0xf1a00007
+#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
 
 /*P1_DISRXCTL*/
-#define R0900_P1_DISRXCTL  0xf1a1
-#define F0900_P1_RECEIVER_ON  0xf1a10080
-#define F0900_P1_IGNO_SHORT22K  0xf1a10040
-#define F0900_P1_ONECHIP_TRX  0xf1a10020
-#define F0900_P1_EXT_ENVELOP  0xf1a10010
-#define F0900_P1_PIN_SELECT  0xf1a1000c
-#define F0900_P1_IRQ_RXEND  0xf1a10002
-#define F0900_P1_IRQ_4NBYTES  0xf1a10001
+#define R0900_P1_DISRXCTL 0xf1a1
+#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT0 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
 
 /*P1_DISRX_ST0*/
-#define R0900_P1_DISRX_ST0  0xf1a4
-#define F0900_P1_RX_END  0xf1a40080
-#define F0900_P1_RX_ACTIVE  0xf1a40040
-#define F0900_P1_SHORT_22KHZ  0xf1a40020
-#define F0900_P1_CONT_TONE  0xf1a40010
-#define F0900_P1_FIFO_4BREADY  0xf1a40008
-#define F0900_P1_FIFO_EMPTY  0xf1a40004
-#define F0900_P1_ABORT_DISRX  0xf1a40001
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
+#define F0900_P1_RX_END 0xf1a40080
+#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
 
 /*P1_DISRX_ST1*/
-#define R0900_P1_DISRX_ST1  0xf1a5
-#define F0900_P1_RX_FAIL  0xf1a50080
-#define F0900_P1_FIFO_PARITYFAIL  0xf1a50040
-#define F0900_P1_RX_NONBYTE  0xf1a50020
-#define F0900_P1_FIFO_OVERFLOW  0xf1a50010
-#define F0900_P1_FIFO_BYTENBR  0xf1a5000f
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
 
 /*P1_DISRXDATA*/
-#define R0900_P1_DISRXDATA  0xf1a6
-#define F0900_P1_DISRX_DATA  0xf1a600ff
+#define R0900_P1_DISRXDATA 0xf1a6
+#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
+#define F0900_P1_DISRX_DATA 0xf1a600ff
 
 /*P1_DISTXDATA*/
-#define R0900_P1_DISTXDATA  0xf1a7
-#define F0900_P1_DISEQC_FIFO  0xf1a700ff
+#define R0900_P1_DISTXDATA 0xf1a7
+#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
 
 /*P1_DISTXSTATUS*/
-#define R0900_P1_DISTXSTATUS  0xf1a8
-#define F0900_P1_TX_FAIL  0xf1a80080
-#define F0900_P1_FIFO_FULL  0xf1a80040
-#define F0900_P1_TX_IDLE  0xf1a80020
-#define F0900_P1_GAP_BURST  0xf1a80010
-#define F0900_P1_TXFIFO_BYTES  0xf1a8000f
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
 
 /*P1_F22TX*/
-#define R0900_P1_F22TX  0xf1a9
-#define F0900_P1_F22_REG  0xf1a900ff
+#define R0900_P1_F22TX 0xf1a9
+#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
+#define F0900_P1_F22_REG 0xf1a900ff
 
 /*P1_F22RX*/
-#define R0900_P1_F22RX  0xf1aa
-#define F0900_P1_F22RX_REG  0xf1aa00ff
+#define R0900_P1_F22RX 0xf1aa
+#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
+#define F0900_P1_F22RX_REG 0xf1aa00ff
 
 /*P1_ACRPRESC*/
-#define R0900_P1_ACRPRESC  0xf1ac
-#define F0900_P1_ACR_CODFRDY  0xf1ac0008
-#define F0900_P1_ACR_PRESC  0xf1ac0007
+#define R0900_P1_ACRPRESC 0xf1ac
+#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
+#define F0900_P1_ACR_PRESC 0xf1ac0007
 
 /*P1_ACRDIV*/
-#define R0900_P1_ACRDIV  0xf1ad
-#define F0900_P1_ACR_DIV  0xf1ad00ff
+#define R0900_P1_ACRDIV 0xf1ad
+#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
+#define F0900_P1_ACR_DIV 0xf1ad00ff
 
 /*NCOARSE*/
-#define R0900_NCOARSE  0xf1b3
-#define F0900_M_DIV  0xf1b300ff
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
 
 /*SYNTCTRL*/
-#define R0900_SYNTCTRL  0xf1b6
-#define F0900_STANDBY  0xf1b60080
-#define F0900_BYPASSPLLCORE  0xf1b60040
-#define F0900_SELX1RATIO  0xf1b60020
-#define F0900_I2C_TUD  0xf1b60010
-#define F0900_STOP_PLL  0xf1b60008
-#define F0900_BYPASSPLLFSK  0xf1b60004
-#define F0900_SELOSCI  0xf1b60002
-#define F0900_BYPASSPLLADC  0xf1b60001
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
 
 /*FILTCTRL*/
-#define R0900_FILTCTRL  0xf1b7
-#define F0900_INV_CLK135  0xf1b70080
-#define F0900_PERM_BYPDIS  0xf1b70040
-#define F0900_SEL_FSKCKDIV  0xf1b70004
-#define F0900_INV_CLKFSK  0xf1b70002
-#define F0900_BYPASS_APPLI  0xf1b70001
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
 
 /*PLLSTAT*/
-#define R0900_PLLSTAT  0xf1b8
-#define F0900_ACM_SEL  0xf1b80080
-#define F0900_DTV_SEL  0xf1b80040
-#define F0900_PLLLOCK  0xf1b80001
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_PLLLOCK 0xf1b80001
 
 /*STOPCLK1*/
-#define R0900_STOPCLK1  0xf1c2
-#define F0900_STOP_CLKPKDT2  0xf1c20040
-#define F0900_STOP_CLKPKDT1  0xf1c20020
-#define F0900_STOP_CLKFEC  0xf1c20010
-#define F0900_STOP_CLKADCI2  0xf1c20008
-#define F0900_INV_CLKADCI2  0xf1c20004
-#define F0900_STOP_CLKADCI1  0xf1c20002
-#define F0900_INV_CLKADCI1  0xf1c20001
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
 
 /*STOPCLK2*/
-#define R0900_STOPCLK2  0xf1c3
-#define F0900_STOP_CLKSAMP2  0xf1c30010
-#define F0900_STOP_CLKSAMP1  0xf1c30008
-#define F0900_STOP_CLKVIT2  0xf1c30004
-#define F0900_STOP_CLKVIT1  0xf1c30002
-#define F0900_STOP_CLKTS  0xf1c30001
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
+#define F0900_STOP_CLKTS 0xf1c30001
 
 /*TSTTNR0*/
-#define R0900_TSTTNR0  0xf1df
-#define F0900_SEL_FSK  0xf1df0080
-#define F0900_FSK_PON  0xf1df0004
-#define F0900_FSK_OPENLOOP  0xf1df0002
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
 
 /*TSTTNR1*/
-#define R0900_TSTTNR1  0xf1e0
-#define F0900_BYPASS_ADC1  0xf1e00080
-#define F0900_INVADC1_CKOUT  0xf1e00040
-#define F0900_SELIQSRC1  0xf1e00030
-#define F0900_ADC1_PON  0xf1e00002
-#define F0900_ADC1_INMODE  0xf1e00001
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
 
 /*TSTTNR2*/
-#define R0900_TSTTNR2  0xf1e1
-#define F0900_DISEQC1_PON  0xf1e10020
-#define F0900_DISEQC1_TEST  0xf1e1001f
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
 
 /*TSTTNR3*/
-#define R0900_TSTTNR3  0xf1e2
-#define F0900_BYPASS_ADC2  0xf1e20080
-#define F0900_INVADC2_CKOUT  0xf1e20040
-#define F0900_SELIQSRC2  0xf1e20030
-#define F0900_ADC2_PON  0xf1e20002
-#define F0900_ADC2_INMODE  0xf1e20001
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
 
 /*TSTTNR4*/
-#define R0900_TSTTNR4  0xf1e3
-#define F0900_DISEQC2_PON  0xf1e30020
-#define F0900_DISEQC2_TEST  0xf1e3001f
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
 
 /*P2_IQCONST*/
-#define R0900_P2_IQCONST  0xf200
-#define F0900_P2_CONSTEL_SELECT  0xf2000060
-#define F0900_P2_IQSYMB_SEL  0xf200001f
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
 
 /*P2_NOSCFG*/
-#define R0900_P2_NOSCFG  0xf201
-#define F0900_P2_DUMMYPL_NOSDATA  0xf2010020
-#define F0900_P2_NOSPLH_BETA  0xf2010018
-#define F0900_P2_NOSDATA_BETA  0xf2010007
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
 
 /*P2_ISYMB*/
-#define R0900_P2_ISYMB  0xf202
-#define F0900_P2_I_SYMBOL  0xf20201ff
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
 
 /*P2_QSYMB*/
-#define R0900_P2_QSYMB  0xf203
-#define F0900_P2_Q_SYMBOL  0xf20301ff
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
 
 /*P2_AGC1CFG*/
-#define R0900_P2_AGC1CFG  0xf204
-#define F0900_P2_DC_FROZEN  0xf2040080
-#define F0900_P2_DC_CORRECT  0xf2040040
-#define F0900_P2_AMM_FROZEN  0xf2040020
-#define F0900_P2_AMM_CORRECT  0xf2040010
-#define F0900_P2_QUAD_FROZEN  0xf2040008
-#define F0900_P2_QUAD_CORRECT  0xf2040004
-#define F0900_P2_DCCOMP_SLOW  0xf2040002
-#define F0900_P2_IQMISM_SLOW  0xf2040001
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
 
 /*P2_AGC1CN*/
-#define R0900_P2_AGC1CN  0xf206
-#define F0900_P2_AGC1_LOCKED  0xf2060080
-#define F0900_P2_AGC1_OVERFLOW  0xf2060040
-#define F0900_P2_AGC1_NOSLOWLK  0xf2060020
-#define F0900_P2_AGC1_MINPOWER  0xf2060010
-#define F0900_P2_AGCOUT_FAST  0xf2060008
-#define F0900_P2_AGCIQ_BETA  0xf2060007
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
 
 /*P2_AGC1REF*/
-#define R0900_P2_AGC1REF  0xf207
-#define F0900_P2_AGCIQ_REF  0xf20700ff
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
 
 /*P2_IDCCOMP*/
-#define R0900_P2_IDCCOMP  0xf208
-#define F0900_P2_IAVERAGE_ADJ  0xf20801ff
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
 
 /*P2_QDCCOMP*/
-#define R0900_P2_QDCCOMP  0xf209
-#define F0900_P2_QAVERAGE_ADJ  0xf20901ff
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
 
 /*P2_POWERI*/
-#define R0900_P2_POWERI  0xf20a
-#define F0900_P2_POWER_I  0xf20a00ff
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
 
 /*P2_POWERQ*/
-#define R0900_P2_POWERQ  0xf20b
-#define F0900_P2_POWER_Q  0xf20b00ff
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
 
 /*P2_AGC1AMM*/
-#define R0900_P2_AGC1AMM  0xf20c
-#define F0900_P2_AMM_VALUE  0xf20c00ff
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
 
 /*P2_AGC1QUAD*/
-#define R0900_P2_AGC1QUAD  0xf20d
-#define F0900_P2_QUAD_VALUE  0xf20d01ff
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
 
 /*P2_AGCIQIN1*/
-#define R0900_P2_AGCIQIN1  0xf20e
-#define F0900_P2_AGCIQ_VALUE1  0xf20e00ff
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
 
 /*P2_AGCIQIN0*/
-#define R0900_P2_AGCIQIN0  0xf20f
-#define F0900_P2_AGCIQ_VALUE0  0xf20f00ff
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
 
 /*P2_DEMOD*/
-#define R0900_P2_DEMOD  0xf210
-#define F0900_P2_DEMOD_STOP  0xf2100040
-#define F0900_P2_SPECINV_CONTROL  0xf2100030
-#define F0900_P2_FORCE_ENASAMP  0xf2100008
-#define F0900_P2_MANUAL_ROLLOFF  0xf2100004
-#define F0900_P2_ROLLOFF_CONTROL  0xf2100003
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
 
 /*P2_DMDMODCOD*/
-#define R0900_P2_DMDMODCOD  0xf211
-#define F0900_P2_MANUAL_MODCOD  0xf2110080
-#define F0900_P2_DEMOD_MODCOD  0xf211007c
-#define F0900_P2_DEMOD_TYPE  0xf2110003
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
 
 /*P2_DSTATUS*/
-#define R0900_P2_DSTATUS  0xf212
-#define F0900_P2_CAR_LOCK  0xf2120080
-#define F0900_P2_TMGLOCK_QUALITY  0xf2120060
-#define F0900_P2_SDVBS1_ENABLE  0xf2120010
-#define F0900_P2_LOCK_DEFINITIF  0xf2120008
-#define F0900_P2_TIMING_IS_LOCKED  0xf2120004
-#define F0900_P2_COARSE_TMGLOCK  0xf2120002
-#define F0900_P2_COARSE_CARLOCK  0xf2120001
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_OVADC_DETECT 0xf2120001
 
 /*P2_DSTATUS2*/
-#define R0900_P2_DSTATUS2  0xf213
-#define F0900_P2_DEMOD_DELOCK  0xf2130080
-#define F0900_P2_DEMOD_TIMEOUT  0xf2130040
-#define F0900_P2_MODCODRQ_SYNCTAG  0xf2130020
-#define F0900_P2_POLYPH_SATEVENT  0xf2130010
-#define F0900_P2_AGC1_NOSIGNALACK  0xf2130008
-#define F0900_P2_AGC2_OVERFLOW  0xf2130004
-#define F0900_P2_CFR_OVERFLOW  0xf2130002
-#define F0900_P2_GAMMA_OVERUNDER  0xf2130001
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
 
 /*P2_DMDCFGMD*/
-#define R0900_P2_DMDCFGMD  0xf214
-#define F0900_P2_DVBS2_ENABLE  0xf2140080
-#define F0900_P2_DVBS1_ENABLE  0xf2140040
-#define F0900_P2_CFR_AUTOSCAN  0xf2140020
-#define F0900_P2_SCAN_ENABLE  0xf2140010
-#define F0900_P2_TUN_AUTOSCAN  0xf2140008
-#define F0900_P2_NOFORCE_RELOCK  0xf2140004
-#define F0900_P2_TUN_RNG  0xf2140003
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_CFR_AUTOSCAN 0xf2140008
+#define F0900_P2_TUN_RNG 0xf2140003
 
 /*P2_DMDCFG2*/
-#define R0900_P2_DMDCFG2  0xf215
-#define F0900_P2_AGC1_WAITLOCK  0xf2150080
-#define F0900_P2_S1S2_SEQUENTIAL  0xf2150040
-#define F0900_P2_OVERFLOW_TIMEOUT  0xf2150020
-#define F0900_P2_SCANFAIL_TIMEOUT  0xf2150010
-#define F0900_P2_DMDTOUT_BACK  0xf2150008
-#define F0900_P2_CARLOCK_S1ENABLE  0xf2150004
-#define F0900_P2_COARSE_LK3MODE  0xf2150002
-#define F0900_P2_COARSE_LK2MODE  0xf2150001
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_INFINITE_RELOCK 0xf2150010
 
 /*P2_DMDISTATE*/
-#define R0900_P2_DMDISTATE  0xf216
-#define F0900_P2_I2C_NORESETDMODE  0xf2160080
-#define F0900_P2_FORCE_ETAPED  0xf2160040
-#define F0900_P2_SDMDRST_DIRCLK  0xf2160020
-#define F0900_P2_I2C_DEMOD_MODE  0xf216001f
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
 
 /*P2_DMDT0M*/
-#define R0900_P2_DMDT0M  0xf217
-#define F0900_P2_DMDT0_MIN  0xf21700ff
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
 
 /*P2_DMDSTATE*/
-#define R0900_P2_DMDSTATE  0xf21b
-#define F0900_P2_DEMOD_LOCKED  0xf21b0080
-#define F0900_P2_HEADER_MODE  0xf21b0060
-#define F0900_P2_DEMOD_MODE  0xf21b001f
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_HEADER_MODE 0xf21b0060
 
 /*P2_DMDFLYW*/
-#define R0900_P2_DMDFLYW  0xf21c
-#define F0900_P2_I2C_IRQVAL  0xf21c00f0
-#define F0900_P2_FLYWHEEL_CPT  0xf21c000f
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
 
 /*P2_DSTATUS3*/
-#define R0900_P2_DSTATUS3  0xf21d
-#define F0900_P2_CFR_ZIGZAG  0xf21d0080
-#define F0900_P2_DEMOD_CFGMODE  0xf21d0060
-#define F0900_P2_GAMMA_LOWBAUDRATE  0xf21d0010
-#define F0900_P2_RELOCK_MODE  0xf21d0008
-#define F0900_P2_DEMOD_FAIL  0xf21d0004
-#define F0900_P2_ETAPE1A_DVBXMEM  0xf21d0003
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
 
 /*P2_DMDCFG3*/
-#define R0900_P2_DMDCFG3  0xf21e
-#define F0900_P2_DVBS1_TMGWAIT  0xf21e0080
-#define F0900_P2_NO_BWCENTERING  0xf21e0040
-#define F0900_P2_INV_SEQSRCH  0xf21e0020
-#define F0900_P2_DIS_SFRUPLOW_TRK  0xf21e0010
-#define F0900_P2_NOSTOP_FIFOFULL  0xf21e0008
-#define F0900_P2_LOCKTIME_MODE  0xf21e0007
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
 
 /*P2_DMDCFG4*/
-#define R0900_P2_DMDCFG4  0xf21f
-#define F0900_P2_TUNER_NRELAUNCH  0xf21f0008
-#define F0900_P2_DIS_CLKENABLE  0xf21f0004
-#define F0900_P2_DIS_HDRDIVLOCK  0xf21f0002
-#define F0900_P2_NO_TNRWBINIT  0xf21f0001
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
 
 /*P2_CORRELMANT*/
-#define R0900_P2_CORRELMANT  0xf220
-#define F0900_P2_CORREL_MANT  0xf22000ff
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
 
 /*P2_CORRELABS*/
-#define R0900_P2_CORRELABS  0xf221
-#define F0900_P2_CORREL_ABS  0xf22100ff
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
 
 /*P2_CORRELEXP*/
-#define R0900_P2_CORRELEXP  0xf222
-#define F0900_P2_CORREL_ABSEXP  0xf22200f0
-#define F0900_P2_CORREL_EXP  0xf222000f
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
 
 /*P2_PLHMODCOD*/
-#define R0900_P2_PLHMODCOD  0xf224
-#define F0900_P2_SPECINV_DEMOD  0xf2240080
-#define F0900_P2_PLH_MODCOD  0xf224007c
-#define F0900_P2_PLH_TYPE  0xf2240003
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
 
-/*P2_AGCK32*/
-#define R0900_P2_AGCK32  0xf22b
-#define F0900_P2_R3ADJOFF_32APSK  0xf22b0080
-#define F0900_P2_R2ADJOFF_32APSK  0xf22b0040
-#define F0900_P2_R1ADJOFF_32APSK  0xf22b0020
-#define F0900_P2_RADJ_32APSK  0xf22b001f
+/*P2_DMDREG*/
+#define R0900_P2_DMDREG 0xf225
+#define F0900_P2_DECIM_PLFRAMES 0xf2250001
 
 /*P2_AGC2O*/
-#define R0900_P2_AGC2O  0xf22c
-#define F0900_P2_AGC2REF_ADJUSTING  0xf22c0080
-#define F0900_P2_AGC2_COARSEFAST  0xf22c0040
-#define F0900_P2_AGC2_LKSQRT  0xf22c0020
-#define F0900_P2_AGC2_LKMODE  0xf22c0010
-#define F0900_P2_AGC2_LKEQUA  0xf22c0008
-#define F0900_P2_AGC2_COEF  0xf22c0007
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2_COEF 0xf22c0007
 
 /*P2_AGC2REF*/
-#define R0900_P2_AGC2REF  0xf22d
-#define F0900_P2_AGC2_REF  0xf22d00ff
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
 
 /*P2_AGC1ADJ*/
-#define R0900_P2_AGC1ADJ  0xf22e
-#define F0900_P2_AGC1ADJ_MANUAL  0xf22e0080
-#define F0900_P2_AGC1_ADJUSTED  0xf22e017f
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
 
 /*P2_AGC2I1*/
-#define R0900_P2_AGC2I1  0xf236
-#define F0900_P2_AGC2_INTEGRATOR1  0xf23600ff
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
 
 /*P2_AGC2I0*/
-#define R0900_P2_AGC2I0  0xf237
-#define F0900_P2_AGC2_INTEGRATOR0  0xf23700ff
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
 
 /*P2_CARCFG*/
-#define R0900_P2_CARCFG  0xf238
-#define F0900_P2_CFRUPLOW_AUTO  0xf2380080
-#define F0900_P2_CFRUPLOW_TEST  0xf2380040
-#define F0900_P2_EN_CAR2CENTER  0xf2380020
-#define F0900_P2_CARHDR_NODIV8  0xf2380010
-#define F0900_P2_I2C_ROTA  0xf2380008
-#define F0900_P2_ROTAON  0xf2380004
-#define F0900_P2_PH_DET_ALGO  0xf2380003
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
 
 /*P2_ACLC*/
-#define R0900_P2_ACLC  0xf239
-#define F0900_P2_STOP_S2ALPHA  0xf23900c0
-#define F0900_P2_CAR_ALPHA_MANT  0xf2390030
-#define F0900_P2_CAR_ALPHA_EXP  0xf239000f
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
 
 /*P2_BCLC*/
-#define R0900_P2_BCLC  0xf23a
-#define F0900_P2_STOP_S2BETA  0xf23a00c0
-#define F0900_P2_CAR_BETA_MANT  0xf23a0030
-#define F0900_P2_CAR_BETA_EXP  0xf23a000f
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
 
 /*P2_CARFREQ*/
-#define R0900_P2_CARFREQ  0xf23d
-#define F0900_P2_KC_COARSE_EXP  0xf23d00f0
-#define F0900_P2_BETA_FREQ  0xf23d000f
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
 
 /*P2_CARHDR*/
-#define R0900_P2_CARHDR  0xf23e
-#define F0900_P2_K_FREQ_HDR  0xf23e00ff
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
 
 /*P2_LDT*/
-#define R0900_P2_LDT  0xf23f
-#define F0900_P2_CARLOCK_THRES  0xf23f01ff
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
 
 /*P2_LDT2*/
-#define R0900_P2_LDT2  0xf240
-#define F0900_P2_CARLOCK_THRES2  0xf24001ff
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
 
 /*P2_CFRICFG*/
-#define R0900_P2_CFRICFG  0xf241
-#define F0900_P2_CFRINIT_UNVALRNG  0xf2410080
-#define F0900_P2_CFRINIT_LUNVALCPT  0xf2410040
-#define F0900_P2_CFRINIT_ABORTDBL  0xf2410020
-#define F0900_P2_CFRINIT_ABORTPRED  0xf2410010
-#define F0900_P2_CFRINIT_UNVALSKIP  0xf2410008
-#define F0900_P2_CFRINIT_CSTINC  0xf2410004
-#define F0900_P2_NEG_CFRSTEP  0xf2410001
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
 
 /*P2_CFRUP1*/
-#define R0900_P2_CFRUP1  0xf242
-#define F0900_P2_CFR_UP1  0xf24201ff
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
 
 /*P2_CFRUP0*/
-#define R0900_P2_CFRUP0  0xf243
-#define F0900_P2_CFR_UP0  0xf24300ff
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
 
 /*P2_CFRLOW1*/
-#define R0900_P2_CFRLOW1  0xf246
-#define F0900_P2_CFR_LOW1  0xf24601ff
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
 
 /*P2_CFRLOW0*/
-#define R0900_P2_CFRLOW0  0xf247
-#define F0900_P2_CFR_LOW0  0xf24700ff
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
 
 /*P2_CFRINIT1*/
-#define R0900_P2_CFRINIT1  0xf248
-#define F0900_P2_CFR_INIT1  0xf24801ff
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
 
 /*P2_CFRINIT0*/
-#define R0900_P2_CFRINIT0  0xf249
-#define F0900_P2_CFR_INIT0  0xf24900ff
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
 
 /*P2_CFRINC1*/
-#define R0900_P2_CFRINC1  0xf24a
-#define F0900_P2_MANUAL_CFRINC  0xf24a0080
-#define F0900_P2_CFR_INC1  0xf24a017f
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a003f
 
 /*P2_CFRINC0*/
-#define R0900_P2_CFRINC0  0xf24b
-#define F0900_P2_CFR_INC0  0xf24b00f0
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f8
 
 /*P2_CFR2*/
-#define R0900_P2_CFR2  0xf24c
-#define F0900_P2_CAR_FREQ2  0xf24c01ff
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
 
 /*P2_CFR1*/
-#define R0900_P2_CFR1  0xf24d
-#define F0900_P2_CAR_FREQ1  0xf24d00ff
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
 
 /*P2_CFR0*/
-#define R0900_P2_CFR0  0xf24e
-#define F0900_P2_CAR_FREQ0  0xf24e00ff
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
 
 /*P2_LDI*/
-#define R0900_P2_LDI  0xf24f
-#define F0900_P2_LOCK_DET_INTEGR  0xf24f01ff
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
 
 /*P2_TMGCFG*/
-#define R0900_P2_TMGCFG  0xf250
-#define F0900_P2_TMGLOCK_BETA  0xf25000c0
-#define F0900_P2_NOTMG_GROUPDELAY  0xf2500020
-#define F0900_P2_DO_TIMING_CORR  0xf2500010
-#define F0900_P2_MANUAL_SCAN  0xf250000c
-#define F0900_P2_TMG_MINFREQ  0xf2500003
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_TMG_MINFREQ 0xf2500003
 
 /*P2_RTC*/
-#define R0900_P2_RTC  0xf251
-#define F0900_P2_TMGALPHA_EXP  0xf25100f0
-#define F0900_P2_TMGBETA_EXP  0xf251000f
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
 
 /*P2_RTCS2*/
-#define R0900_P2_RTCS2  0xf252
-#define F0900_P2_TMGALPHAS2_EXP  0xf25200f0
-#define F0900_P2_TMGBETAS2_EXP  0xf252000f
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
 
 /*P2_TMGTHRISE*/
-#define R0900_P2_TMGTHRISE  0xf253
-#define F0900_P2_TMGLOCK_THRISE  0xf25300ff
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
 
 /*P2_TMGTHFALL*/
-#define R0900_P2_TMGTHFALL  0xf254
-#define F0900_P2_TMGLOCK_THFALL  0xf25400ff
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
 
 /*P2_SFRUPRATIO*/
-#define R0900_P2_SFRUPRATIO  0xf255
-#define F0900_P2_SFR_UPRATIO  0xf25500ff
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
 
 /*P2_SFRLOWRATIO*/
-#define R0900_P2_SFRLOWRATIO  0xf256
-#define F0900_P2_SFR_LOWRATIO  0xf25600ff
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
 
 /*P2_KREFTMG*/
-#define R0900_P2_KREFTMG  0xf258
-#define F0900_P2_KREF_TMG  0xf25800ff
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
 
 /*P2_SFRSTEP*/
-#define R0900_P2_SFRSTEP  0xf259
-#define F0900_P2_SFR_SCANSTEP  0xf25900f0
-#define F0900_P2_SFR_CENTERSTEP  0xf259000f
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
 
 /*P2_TMGCFG2*/
-#define R0900_P2_TMGCFG2  0xf25a
-#define F0900_P2_DIS_AUTOSAMP  0xf25a0008
-#define F0900_P2_SCANINIT_QUART  0xf25a0004
-#define F0900_P2_NOTMG_DVBS1DERAT  0xf25a0002
-#define F0900_P2_SFRRATIO_FINE  0xf25a0001
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_KREFTMG2*/
+#define R0900_P2_KREFTMG2 0xf25b
+#define F0900_P2_KREF_TMG2 0xf25b00ff
 
 /*P2_SFRINIT1*/
-#define R0900_P2_SFRINIT1  0xf25e
-#define F0900_P2_SFR_INIT1  0xf25e00ff
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e007f
 
 /*P2_SFRINIT0*/
-#define R0900_P2_SFRINIT0  0xf25f
-#define F0900_P2_SFR_INIT0  0xf25f00ff
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
 
 /*P2_SFRUP1*/
-#define R0900_P2_SFRUP1  0xf260
-#define F0900_P2_AUTO_GUP  0xf2600080
-#define F0900_P2_SYMB_FREQ_UP1  0xf260007f
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
 
 /*P2_SFRUP0*/
-#define R0900_P2_SFRUP0  0xf261
-#define F0900_P2_SYMB_FREQ_UP0  0xf26100ff
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
 
 /*P2_SFRLOW1*/
-#define R0900_P2_SFRLOW1  0xf262
-#define F0900_P2_AUTO_GLOW  0xf2620080
-#define F0900_P2_SYMB_FREQ_LOW1  0xf262007f
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
 
 /*P2_SFRLOW0*/
-#define R0900_P2_SFRLOW0  0xf263
-#define F0900_P2_SYMB_FREQ_LOW0  0xf26300ff
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
 
 /*P2_SFR3*/
-#define R0900_P2_SFR3  0xf264
-#define F0900_P2_SYMB_FREQ3  0xf26400ff
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
 
 /*P2_SFR2*/
-#define R0900_P2_SFR2  0xf265
-#define F0900_P2_SYMB_FREQ2  0xf26500ff
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
 
 /*P2_SFR1*/
-#define R0900_P2_SFR1  0xf266
-#define F0900_P2_SYMB_FREQ1  0xf26600ff
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
 
 /*P2_SFR0*/
-#define R0900_P2_SFR0  0xf267
-#define F0900_P2_SYMB_FREQ0  0xf26700ff
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
 
 /*P2_TMGREG2*/
-#define R0900_P2_TMGREG2  0xf268
-#define F0900_P2_TMGREG2  0xf26800ff
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
 
 /*P2_TMGREG1*/
-#define R0900_P2_TMGREG1  0xf269
-#define F0900_P2_TMGREG1  0xf26900ff
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
 
 /*P2_TMGREG0*/
-#define R0900_P2_TMGREG0  0xf26a
-#define F0900_P2_TMGREG0  0xf26a00ff
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
 
 /*P2_TMGLOCK1*/
-#define R0900_P2_TMGLOCK1  0xf26b
-#define F0900_P2_TMGLOCK_LEVEL1  0xf26b01ff
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
 
 /*P2_TMGLOCK0*/
-#define R0900_P2_TMGLOCK0  0xf26c
-#define F0900_P2_TMGLOCK_LEVEL0  0xf26c00ff
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
 
 /*P2_TMGOBS*/
-#define R0900_P2_TMGOBS  0xf26d
-#define F0900_P2_ROLLOFF_STATUS  0xf26d00c0
-#define F0900_P2_SCAN_SIGN  0xf26d0030
-#define F0900_P2_TMG_SCANNING  0xf26d0008
-#define F0900_P2_CHCENTERING_MODE  0xf26d0004
-#define F0900_P2_TMG_SCANFAIL  0xf26d0002
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
 
 /*P2_EQUALCFG*/
-#define R0900_P2_EQUALCFG  0xf26f
-#define F0900_P2_NOTMG_NEGALWAIT  0xf26f0080
-#define F0900_P2_EQUAL_ON  0xf26f0040
-#define F0900_P2_SEL_EQUALCOR  0xf26f0038
-#define F0900_P2_MU_EQUALDFE  0xf26f0007
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
 
 /*P2_EQUAI1*/
-#define R0900_P2_EQUAI1  0xf270
-#define F0900_P2_EQUA_ACCI1  0xf27001ff
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
 
 /*P2_EQUAQ1*/
-#define R0900_P2_EQUAQ1  0xf271
-#define F0900_P2_EQUA_ACCQ1  0xf27101ff
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
 
 /*P2_EQUAI2*/
-#define R0900_P2_EQUAI2  0xf272
-#define F0900_P2_EQUA_ACCI2  0xf27201ff
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
 
 /*P2_EQUAQ2*/
-#define R0900_P2_EQUAQ2  0xf273
-#define F0900_P2_EQUA_ACCQ2  0xf27301ff
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
 
 /*P2_EQUAI3*/
-#define R0900_P2_EQUAI3  0xf274
-#define F0900_P2_EQUA_ACCI3  0xf27401ff
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
 
 /*P2_EQUAQ3*/
-#define R0900_P2_EQUAQ3  0xf275
-#define F0900_P2_EQUA_ACCQ3  0xf27501ff
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
 
 /*P2_EQUAI4*/
-#define R0900_P2_EQUAI4  0xf276
-#define F0900_P2_EQUA_ACCI4  0xf27601ff
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
 
 /*P2_EQUAQ4*/
-#define R0900_P2_EQUAQ4  0xf277
-#define F0900_P2_EQUA_ACCQ4  0xf27701ff
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
 
 /*P2_EQUAI5*/
-#define R0900_P2_EQUAI5  0xf278
-#define F0900_P2_EQUA_ACCI5  0xf27801ff
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
 
 /*P2_EQUAQ5*/
-#define R0900_P2_EQUAQ5  0xf279
-#define F0900_P2_EQUA_ACCQ5  0xf27901ff
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
 
 /*P2_EQUAI6*/
-#define R0900_P2_EQUAI6  0xf27a
-#define F0900_P2_EQUA_ACCI6  0xf27a01ff
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
 
 /*P2_EQUAQ6*/
-#define R0900_P2_EQUAQ6  0xf27b
-#define F0900_P2_EQUA_ACCQ6  0xf27b01ff
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
 
 /*P2_EQUAI7*/
-#define R0900_P2_EQUAI7  0xf27c
-#define F0900_P2_EQUA_ACCI7  0xf27c01ff
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
 
 /*P2_EQUAQ7*/
-#define R0900_P2_EQUAQ7  0xf27d
-#define F0900_P2_EQUA_ACCQ7  0xf27d01ff
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
 
 /*P2_EQUAI8*/
-#define R0900_P2_EQUAI8  0xf27e
-#define F0900_P2_EQUA_ACCI8  0xf27e01ff
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
 
 /*P2_EQUAQ8*/
-#define R0900_P2_EQUAQ8  0xf27f
-#define F0900_P2_EQUA_ACCQ8  0xf27f01ff
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
 
 /*P2_NNOSDATAT1*/
-#define R0900_P2_NNOSDATAT1  0xf280
-#define F0900_P2_NOSDATAT_NORMED1  0xf28000ff
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
 
 /*P2_NNOSDATAT0*/
-#define R0900_P2_NNOSDATAT0  0xf281
-#define F0900_P2_NOSDATAT_NORMED0  0xf28100ff
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
 
 /*P2_NNOSDATA1*/
-#define R0900_P2_NNOSDATA1  0xf282
-#define F0900_P2_NOSDATA_NORMED1  0xf28200ff
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
 
 /*P2_NNOSDATA0*/
-#define R0900_P2_NNOSDATA0  0xf283
-#define F0900_P2_NOSDATA_NORMED0  0xf28300ff
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
 
 /*P2_NNOSPLHT1*/
-#define R0900_P2_NNOSPLHT1  0xf284
-#define F0900_P2_NOSPLHT_NORMED1  0xf28400ff
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
 
 /*P2_NNOSPLHT0*/
-#define R0900_P2_NNOSPLHT0  0xf285
-#define F0900_P2_NOSPLHT_NORMED0  0xf28500ff
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
 
 /*P2_NNOSPLH1*/
-#define R0900_P2_NNOSPLH1  0xf286
-#define F0900_P2_NOSPLH_NORMED1  0xf28600ff
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
 
 /*P2_NNOSPLH0*/
-#define R0900_P2_NNOSPLH0  0xf287
-#define F0900_P2_NOSPLH_NORMED0  0xf28700ff
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
 
 /*P2_NOSDATAT1*/
-#define R0900_P2_NOSDATAT1  0xf288
-#define F0900_P2_NOSDATAT_UNNORMED1  0xf28800ff
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
 
 /*P2_NOSDATAT0*/
-#define R0900_P2_NOSDATAT0  0xf289
-#define F0900_P2_NOSDATAT_UNNORMED0  0xf28900ff
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
 
 /*P2_NOSDATA1*/
-#define R0900_P2_NOSDATA1  0xf28a
-#define F0900_P2_NOSDATA_UNNORMED1  0xf28a00ff
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
 
 /*P2_NOSDATA0*/
-#define R0900_P2_NOSDATA0  0xf28b
-#define F0900_P2_NOSDATA_UNNORMED0  0xf28b00ff
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
 
 /*P2_NOSPLHT1*/
-#define R0900_P2_NOSPLHT1  0xf28c
-#define F0900_P2_NOSPLHT_UNNORMED1  0xf28c00ff
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
 
 /*P2_NOSPLHT0*/
-#define R0900_P2_NOSPLHT0  0xf28d
-#define F0900_P2_NOSPLHT_UNNORMED0  0xf28d00ff
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
 
 /*P2_NOSPLH1*/
-#define R0900_P2_NOSPLH1  0xf28e
-#define F0900_P2_NOSPLH_UNNORMED1  0xf28e00ff
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
 
 /*P2_NOSPLH0*/
-#define R0900_P2_NOSPLH0  0xf28f
-#define F0900_P2_NOSPLH_UNNORMED0  0xf28f00ff
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
 
 /*P2_CAR2CFG*/
-#define R0900_P2_CAR2CFG  0xf290
-#define F0900_P2_DESCRAMB_OFF  0xf2900080
-#define F0900_P2_PN4_SELECT  0xf2900040
-#define F0900_P2_CFR2_STOPDVBS1  0xf2900020
-#define F0900_P2_STOP_CFR2UPDATE  0xf2900010
-#define F0900_P2_STOP_NCO2UPDATE  0xf2900008
-#define F0900_P2_ROTA2ON  0xf2900004
-#define F0900_P2_PH_DET_ALGO2  0xf2900003
-
-/*P2_ACLC2*/
-#define R0900_P2_ACLC2  0xf291
-#define F0900_P2_CAR2_PUNCT_ADERAT  0xf2910040
-#define F0900_P2_CAR2_ALPHA_MANT  0xf2910030
-#define F0900_P2_CAR2_ALPHA_EXP  0xf291000f
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_CARRIER3_DISABLE 0xf2900040
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
 
-/*P2_BCLC2*/
-#define R0900_P2_BCLC2  0xf292
-#define F0900_P2_DVBS2_NIP  0xf2920080
-#define F0900_P2_CAR2_PUNCT_BDERAT  0xf2920040
-#define F0900_P2_CAR2_BETA_MANT  0xf2920030
-#define F0900_P2_CAR2_BETA_EXP  0xf292000f
+/*P2_CFR2CFR1*/
+#define R0900_P2_CFR2CFR1 0xf291
+#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
+#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
+#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
+#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
 
 /*P2_CFR22*/
-#define R0900_P2_CFR22  0xf293
-#define F0900_P2_CAR2_FREQ2  0xf29301ff
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
 
 /*P2_CFR21*/
-#define R0900_P2_CFR21  0xf294
-#define F0900_P2_CAR2_FREQ1  0xf29400ff
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
 
 /*P2_CFR20*/
-#define R0900_P2_CFR20  0xf295
-#define F0900_P2_CAR2_FREQ0  0xf29500ff
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
 
 /*P2_ACLC2S2Q*/
-#define R0900_P2_ACLC2S2Q  0xf297
-#define F0900_P2_ENAB_SPSKSYMB  0xf2970080
-#define F0900_P2_CAR2S2_QADERAT  0xf2970040
-#define F0900_P2_CAR2S2_Q_ALPH_M  0xf2970030
-#define F0900_P2_CAR2S2_Q_ALPH_E  0xf297000f
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
 
 /*P2_ACLC2S28*/
-#define R0900_P2_ACLC2S28  0xf298
-#define F0900_P2_OLDI3Q_MODE  0xf2980080
-#define F0900_P2_CAR2S2_8ADERAT  0xf2980040
-#define F0900_P2_CAR2S2_8_ALPH_M  0xf2980030
-#define F0900_P2_CAR2S2_8_ALPH_E  0xf298000f
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
 
 /*P2_ACLC2S216A*/
-#define R0900_P2_ACLC2S216A  0xf299
-#define F0900_P2_CAR2S2_16ADERAT  0xf2990040
-#define F0900_P2_CAR2S2_16A_ALPH_M  0xf2990030
-#define F0900_P2_CAR2S2_16A_ALPH_E  0xf299000f
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_DIS_C3STOPA2 0xf2990080
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
 
 /*P2_ACLC2S232A*/
-#define R0900_P2_ACLC2S232A  0xf29a
-#define F0900_P2_CAR2S2_32ADERAT  0xf29a0040
-#define F0900_P2_CAR2S2_32A_ALPH_M  0xf29a0030
-#define F0900_P2_CAR2S2_32A_ALPH_E  0xf29a000f
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
 
 /*P2_BCLC2S2Q*/
-#define R0900_P2_BCLC2S2Q  0xf29c
-#define F0900_P2_DVBS2S2Q_NIP  0xf29c0080
-#define F0900_P2_CAR2S2_QBDERAT  0xf29c0040
-#define F0900_P2_CAR2S2_Q_BETA_M  0xf29c0030
-#define F0900_P2_CAR2S2_Q_BETA_E  0xf29c000f
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
 
 /*P2_BCLC2S28*/
-#define R0900_P2_BCLC2S28  0xf29d
-#define F0900_P2_DVBS2S28_NIP  0xf29d0080
-#define F0900_P2_CAR2S2_8BDERAT  0xf29d0040
-#define F0900_P2_CAR2S2_8_BETA_M  0xf29d0030
-#define F0900_P2_CAR2S2_8_BETA_E  0xf29d000f
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
 
 /*P2_BCLC2S216A*/
-#define R0900_P2_BCLC2S216A  0xf29e
-#define F0900_P2_DVBS2S216A_NIP  0xf29e0080
-#define F0900_P2_CAR2S2_16BDERAT  0xf29e0040
-#define F0900_P2_CAR2S2_16A_BETA_M  0xf29e0030
-#define F0900_P2_CAR2S2_16A_BETA_E  0xf29e000f
+#define R0900_P2_BCLC2S216A 0xf29e
 
 /*P2_BCLC2S232A*/
-#define R0900_P2_BCLC2S232A  0xf29f
-#define F0900_P2_DVBS2S232A_NIP  0xf29f0080
-#define F0900_P2_CAR2S2_32BDERAT  0xf29f0040
-#define F0900_P2_CAR2S2_32A_BETA_M  0xf29f0030
-#define F0900_P2_CAR2S2_32A_BETA_E  0xf29f000f
+#define R0900_P2_BCLC2S232A 0xf29f
 
 /*P2_PLROOT2*/
-#define R0900_P2_PLROOT2  0xf2ac
-#define F0900_P2_SHORTFR_DISABLE  0xf2ac0080
-#define F0900_P2_LONGFR_DISABLE  0xf2ac0040
-#define F0900_P2_DUMMYPL_DISABLE  0xf2ac0020
-#define F0900_P2_SHORTFR_AVOID  0xf2ac0010
-#define F0900_P2_PLSCRAMB_MODE  0xf2ac000c
-#define F0900_P2_PLSCRAMB_ROOT2  0xf2ac0003
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
 
 /*P2_PLROOT1*/
-#define R0900_P2_PLROOT1  0xf2ad
-#define F0900_P2_PLSCRAMB_ROOT1  0xf2ad00ff
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
 
 /*P2_PLROOT0*/
-#define R0900_P2_PLROOT0  0xf2ae
-#define F0900_P2_PLSCRAMB_ROOT0  0xf2ae00ff
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
 
 /*P2_MODCODLST0*/
-#define R0900_P2_MODCODLST0  0xf2b0
-#define F0900_P2_EN_TOKEN31  0xf2b00080
-#define F0900_P2_SYNCTAG_SELECT  0xf2b00040
-#define F0900_P2_MODCODRQ_MODE  0xf2b00030
+#define R0900_P2_MODCODLST0 0xf2b0
 
 /*P2_MODCODLST1*/
-#define R0900_P2_MODCODLST1  0xf2b1
-#define F0900_P2_DIS_MODCOD29  0xf2b100f0
-#define F0900_P2_DIS_32PSK_9_10  0xf2b1000f
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
 
 /*P2_MODCODLST2*/
-#define R0900_P2_MODCODLST2  0xf2b2
-#define F0900_P2_DIS_32PSK_8_9  0xf2b200f0
-#define F0900_P2_DIS_32PSK_5_6  0xf2b2000f
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
 
 /*P2_MODCODLST3*/
-#define R0900_P2_MODCODLST3  0xf2b3
-#define F0900_P2_DIS_32PSK_4_5  0xf2b300f0
-#define F0900_P2_DIS_32PSK_3_4  0xf2b3000f
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
 
 /*P2_MODCODLST4*/
-#define R0900_P2_MODCODLST4  0xf2b4
-#define F0900_P2_DIS_16PSK_9_10  0xf2b400f0
-#define F0900_P2_DIS_16PSK_8_9  0xf2b4000f
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
 
 /*P2_MODCODLST5*/
-#define R0900_P2_MODCODLST5  0xf2b5
-#define F0900_P2_DIS_16PSK_5_6  0xf2b500f0
-#define F0900_P2_DIS_16PSK_4_5  0xf2b5000f
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
 
 /*P2_MODCODLST6*/
-#define R0900_P2_MODCODLST6  0xf2b6
-#define F0900_P2_DIS_16PSK_3_4  0xf2b600f0
-#define F0900_P2_DIS_16PSK_2_3  0xf2b6000f
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
 
 /*P2_MODCODLST7*/
-#define R0900_P2_MODCODLST7  0xf2b7
-#define F0900_P2_DIS_8P_9_10  0xf2b700f0
-#define F0900_P2_DIS_8P_8_9  0xf2b7000f
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
 
 /*P2_MODCODLST8*/
-#define R0900_P2_MODCODLST8  0xf2b8
-#define F0900_P2_DIS_8P_5_6  0xf2b800f0
-#define F0900_P2_DIS_8P_3_4  0xf2b8000f
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
 
 /*P2_MODCODLST9*/
-#define R0900_P2_MODCODLST9  0xf2b9
-#define F0900_P2_DIS_8P_2_3  0xf2b900f0
-#define F0900_P2_DIS_8P_3_5  0xf2b9000f
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
 
 /*P2_MODCODLSTA*/
-#define R0900_P2_MODCODLSTA  0xf2ba
-#define F0900_P2_DIS_QP_9_10  0xf2ba00f0
-#define F0900_P2_DIS_QP_8_9  0xf2ba000f
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
 
 /*P2_MODCODLSTB*/
-#define R0900_P2_MODCODLSTB  0xf2bb
-#define F0900_P2_DIS_QP_5_6  0xf2bb00f0
-#define F0900_P2_DIS_QP_4_5  0xf2bb000f
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
 
 /*P2_MODCODLSTC*/
-#define R0900_P2_MODCODLSTC  0xf2bc
-#define F0900_P2_DIS_QP_3_4  0xf2bc00f0
-#define F0900_P2_DIS_QP_2_3  0xf2bc000f
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
 
 /*P2_MODCODLSTD*/
-#define R0900_P2_MODCODLSTD  0xf2bd
-#define F0900_P2_DIS_QP_3_5  0xf2bd00f0
-#define F0900_P2_DIS_QP_1_2  0xf2bd000f
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
 
 /*P2_MODCODLSTE*/
-#define R0900_P2_MODCODLSTE  0xf2be
-#define F0900_P2_DIS_QP_2_5  0xf2be00f0
-#define F0900_P2_DIS_QP_1_3  0xf2be000f
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
 
 /*P2_MODCODLSTF*/
-#define R0900_P2_MODCODLSTF  0xf2bf
-#define F0900_P2_DIS_QP_1_4  0xf2bf00f0
-#define F0900_P2_DDEMOD_SET  0xf2bf0002
-#define F0900_P2_DDEMOD_MASK  0xf2bf0001
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+
+/*P2_GAUSSR0*/
+#define R0900_P2_GAUSSR0 0xf2c0
+#define F0900_P2_EN_CCIMODE 0xf2c00080
+#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
+
+/*P2_CCIR0*/
+#define R0900_P2_CCIR0 0xf2c1
+#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
+#define F0900_P2_R0_CCI 0xf2c1007f
+
+/*P2_CCIQUANT*/
+#define R0900_P2_CCIQUANT 0xf2c2
+#define F0900_P2_CCI_BETA 0xf2c200e0
+#define F0900_P2_CCI_QUANT 0xf2c2001f
+
+/*P2_CCITHRES*/
+#define R0900_P2_CCITHRES 0xf2c3
+#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
+
+/*P2_CCIACC*/
+#define R0900_P2_CCIACC 0xf2c4
+#define F0900_P2_CCI_VALUE 0xf2c400ff
 
 /*P2_DMDRESCFG*/
-#define R0900_P2_DMDRESCFG  0xf2c6
-#define F0900_P2_DMDRES_RESET  0xf2c60080
-#define F0900_P2_DMDRES_NOISESQR  0xf2c60010
-#define F0900_P2_DMDRES_STRALL  0xf2c60008
-#define F0900_P2_DMDRES_NEWONLY  0xf2c60004
-#define F0900_P2_DMDRES_NOSTORE  0xf2c60002
-#define F0900_P2_DMDRES_AGC2MEM  0xf2c60001
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
 
 /*P2_DMDRESADR*/
-#define R0900_P2_DMDRESADR  0xf2c7
-#define F0900_P2_SUSP_PREDCANAL  0xf2c70080
-#define F0900_P2_DMDRES_VALIDCFR  0xf2c70040
-#define F0900_P2_DMDRES_MEMFULL  0xf2c70030
-#define F0900_P2_DMDRES_RESNBR  0xf2c7000f
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
 
 /*P2_DMDRESDATA7*/
-#define R0900_P2_DMDRESDATA7  0xf2c8
-#define F0900_P2_DMDRES_DATA7  0xf2c800ff
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
 
 /*P2_DMDRESDATA6*/
-#define R0900_P2_DMDRESDATA6  0xf2c9
-#define F0900_P2_DMDRES_DATA6  0xf2c900ff
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
 
 /*P2_DMDRESDATA5*/
-#define R0900_P2_DMDRESDATA5  0xf2ca
-#define F0900_P2_DMDRES_DATA5  0xf2ca00ff
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
 
 /*P2_DMDRESDATA4*/
-#define R0900_P2_DMDRESDATA4  0xf2cb
-#define F0900_P2_DMDRES_DATA4  0xf2cb00ff
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
 
 /*P2_DMDRESDATA3*/
-#define R0900_P2_DMDRESDATA3  0xf2cc
-#define F0900_P2_DMDRES_DATA3  0xf2cc00ff
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
 
 /*P2_DMDRESDATA2*/
-#define R0900_P2_DMDRESDATA2  0xf2cd
-#define F0900_P2_DMDRES_DATA2  0xf2cd00ff
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
 
 /*P2_DMDRESDATA1*/
-#define R0900_P2_DMDRESDATA1  0xf2ce
-#define F0900_P2_DMDRES_DATA1  0xf2ce00ff
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
 
 /*P2_DMDRESDATA0*/
-#define R0900_P2_DMDRESDATA0  0xf2cf
-#define F0900_P2_DMDRES_DATA0  0xf2cf00ff
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
 
 /*P2_FFEI1*/
-#define R0900_P2_FFEI1  0xf2d0
-#define F0900_P2_FFE_ACCI1  0xf2d001ff
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
 
 /*P2_FFEQ1*/
-#define R0900_P2_FFEQ1  0xf2d1
-#define F0900_P2_FFE_ACCQ1  0xf2d101ff
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
 
 /*P2_FFEI2*/
-#define R0900_P2_FFEI2  0xf2d2
-#define F0900_P2_FFE_ACCI2  0xf2d201ff
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
 
 /*P2_FFEQ2*/
-#define R0900_P2_FFEQ2  0xf2d3
-#define F0900_P2_FFE_ACCQ2  0xf2d301ff
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
 
 /*P2_FFEI3*/
-#define R0900_P2_FFEI3  0xf2d4
-#define F0900_P2_FFE_ACCI3  0xf2d401ff
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
 
 /*P2_FFEQ3*/
-#define R0900_P2_FFEQ3  0xf2d5
-#define F0900_P2_FFE_ACCQ3  0xf2d501ff
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
 
 /*P2_FFEI4*/
-#define R0900_P2_FFEI4  0xf2d6
-#define F0900_P2_FFE_ACCI4  0xf2d601ff
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
 
 /*P2_FFEQ4*/
-#define R0900_P2_FFEQ4  0xf2d7
-#define F0900_P2_FFE_ACCQ4  0xf2d701ff
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
 
 /*P2_FFECFG*/
-#define R0900_P2_FFECFG  0xf2d8
-#define F0900_P2_EQUALFFE_ON  0xf2d80040
-#define F0900_P2_EQUAL_USEDSYMB  0xf2d80030
-#define F0900_P2_MU_EQUALFFE  0xf2d80007
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
 
 /*P2_TNRCFG*/
-#define R0900_P2_TNRCFG  0xf2e0
-#define F0900_P2_TUN_ACKFAIL  0xf2e00080
-#define F0900_P2_TUN_TYPE  0xf2e00070
-#define F0900_P2_TUN_SECSTOP  0xf2e00008
-#define F0900_P2_TUN_VCOSRCH  0xf2e00004
-#define F0900_P2_TUN_MADDRESS  0xf2e00003
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
 
 /*P2_TNRCFG2*/
-#define R0900_P2_TNRCFG2  0xf2e1
-#define F0900_P2_TUN_IQSWAP  0xf2e10080
-#define F0900_P2_STB6110_STEP2MHZ  0xf2e10040
-#define F0900_P2_STB6120_DBLI2C  0xf2e10020
-#define F0900_P2_DIS_FCCK  0xf2e10010
-#define F0900_P2_DIS_LPEN  0xf2e10008
-#define F0900_P2_DIS_BWCALC  0xf2e10004
-#define F0900_P2_SHORT_WAITSTATES  0xf2e10002
-#define F0900_P2_DIS_2BWAGC1  0xf2e10001
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
 
 /*P2_TNRXTAL*/
-#define R0900_P2_TNRXTAL  0xf2e4
-#define F0900_P2_TUN_MCLKDECIMAL  0xf2e400e0
-#define F0900_P2_TUN_XTALFREQ  0xf2e4001f
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
 
 /*P2_TNRSTEPS*/
-#define R0900_P2_TNRSTEPS  0xf2e7
-#define F0900_P2_TUNER_BW1P6  0xf2e70080
-#define F0900_P2_BWINC_OFFSET  0xf2e70070
-#define F0900_P2_SOFTSTEP_RNG  0xf2e70008
-#define F0900_P2_TUN_BWOFFSET  0xf2e70107
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW0P125 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70170
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70007
 
 /*P2_TNRGAIN*/
-#define R0900_P2_TNRGAIN  0xf2e8
-#define F0900_P2_TUN_KDIVEN  0xf2e800c0
-#define F0900_P2_STB6X00_OCK  0xf2e80030
-#define F0900_P2_TUN_GAIN  0xf2e8000f
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
 
 /*P2_TNRRF1*/
-#define R0900_P2_TNRRF1  0xf2e9
-#define F0900_P2_TUN_RFFREQ2  0xf2e900ff
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
 
 /*P2_TNRRF0*/
-#define R0900_P2_TNRRF0  0xf2ea
-#define F0900_P2_TUN_RFFREQ1  0xf2ea00ff
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
 
 /*P2_TNRBW*/
-#define R0900_P2_TNRBW  0xf2eb
-#define F0900_P2_TUN_RFFREQ0  0xf2eb00c0
-#define F0900_P2_TUN_BW  0xf2eb003f
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
 
 /*P2_TNRADJ*/
-#define R0900_P2_TNRADJ  0xf2ec
-#define F0900_P2_STB61X0_RCLK  0xf2ec0080
-#define F0900_P2_STB61X0_CALTIME  0xf2ec0040
-#define F0900_P2_STB6X00_DLB  0xf2ec0038
-#define F0900_P2_STB6000_FCL  0xf2ec0007
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
 
 /*P2_TNRCTL2*/
-#define R0900_P2_TNRCTL2  0xf2ed
-#define F0900_P2_STB61X0_LCP1_RCCKOFF  0xf2ed0080
-#define F0900_P2_STB61X0_LCP0  0xf2ed0040
-#define F0900_P2_STB61X0_XTOUT_RFOUTS  0xf2ed0020
-#define F0900_P2_STB61X0_XTON_MCKDV  0xf2ed0010
-#define F0900_P2_STB61X0_CALOFF_DCOFF  0xf2ed0008
-#define F0900_P2_STB6110_LPT  0xf2ed0004
-#define F0900_P2_STB6110_RX  0xf2ed0002
-#define F0900_P2_STB6110_SYN  0xf2ed0001
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
+#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
+#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
+#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
+#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
+#define F0900_P2_STB6XX0_SYN 0xf2ed0001
 
 /*P2_TNRCFG3*/
-#define R0900_P2_TNRCFG3  0xf2ee
-#define F0900_P2_STB6120_DISCTRL1  0xf2ee0080
-#define F0900_P2_STB6120_INVORDER  0xf2ee0040
-#define F0900_P2_STB6120_ENCTRL6  0xf2ee0020
-#define F0900_P2_TUN_PLLFREQ  0xf2ee001c
-#define F0900_P2_TUN_I2CFREQ_MODE  0xf2ee0003
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
 
 /*P2_TNRLAUNCH*/
-#define R0900_P2_TNRLAUNCH  0xf2f0
+#define R0900_P2_TNRLAUNCH 0xf2f0
 
 /*P2_TNRLD*/
-#define R0900_P2_TNRLD  0xf2f0
-#define F0900_P2_TUNLD_VCOING  0xf2f00080
-#define F0900_P2_TUN_REG1FAIL  0xf2f00040
-#define F0900_P2_TUN_REG2FAIL  0xf2f00020
-#define F0900_P2_TUN_REG3FAIL  0xf2f00010
-#define F0900_P2_TUN_REG4FAIL  0xf2f00008
-#define F0900_P2_TUN_REG5FAIL  0xf2f00004
-#define F0900_P2_TUN_BWING  0xf2f00002
-#define F0900_P2_TUN_LOCKED  0xf2f00001
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
 
 /*P2_TNROBSL*/
-#define R0900_P2_TNROBSL  0xf2f6
-#define F0900_P2_TUN_I2CABORTED  0xf2f60080
-#define F0900_P2_TUN_LPEN  0xf2f60040
-#define F0900_P2_TUN_FCCK  0xf2f60020
-#define F0900_P2_TUN_I2CLOCKED  0xf2f60010
-#define F0900_P2_TUN_PROGDONE  0xf2f6000c
-#define F0900_P2_TUN_RFRESTE1  0xf2f60003
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
 
 /*P2_TNRRESTE*/
-#define R0900_P2_TNRRESTE  0xf2f7
-#define F0900_P2_TUN_RFRESTE0  0xf2f700ff
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
 
 /*P2_SMAPCOEF7*/
-#define R0900_P2_SMAPCOEF7  0xf300
-#define F0900_P2_DIS_QSCALE  0xf3000080
-#define F0900_P2_SMAPCOEF_Q_LLR12  0xf300017f
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
 
 /*P2_SMAPCOEF6*/
-#define R0900_P2_SMAPCOEF6  0xf301
-#define F0900_P2_DIS_NEWSCALE  0xf3010008
-#define F0900_P2_ADJ_8PSKLLR1  0xf3010004
-#define F0900_P2_OLD_8PSKLLR1  0xf3010002
-#define F0900_P2_DIS_AB8PSK  0xf3010001
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
 
 /*P2_SMAPCOEF5*/
-#define R0900_P2_SMAPCOEF5  0xf302
-#define F0900_P2_DIS_8SCALE  0xf3020080
-#define F0900_P2_SMAPCOEF_8P_LLR23  0xf302017f
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_NCO2MAX1*/
+#define R0900_P2_NCO2MAX1 0xf314
+#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
+
+/*P2_NCO2MAX0*/
+#define R0900_P2_NCO2MAX0 0xf315
+#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
+
+/*P2_NCO2FR1*/
+#define R0900_P2_NCO2FR1 0xf316
+#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
+
+/*P2_NCO2FR0*/
+#define R0900_P2_NCO2FR0 0xf317
+#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
+
+/*P2_CFR2AVRGE1*/
+#define R0900_P2_CFR2AVRGE1 0xf318
+#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
+
+/*P2_CFR2AVRGE0*/
+#define R0900_P2_CFR2AVRGE0 0xf319
+#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
 
 /*P2_DMDPLHSTAT*/
-#define R0900_P2_DMDPLHSTAT  0xf320
-#define F0900_P2_PLH_STATISTIC  0xf32000ff
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
 
 /*P2_LOCKTIME3*/
-#define R0900_P2_LOCKTIME3  0xf322
-#define F0900_P2_DEMOD_LOCKTIME3  0xf32200ff
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
 
 /*P2_LOCKTIME2*/
-#define R0900_P2_LOCKTIME2  0xf323
-#define F0900_P2_DEMOD_LOCKTIME2  0xf32300ff
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
 
 /*P2_LOCKTIME1*/
-#define R0900_P2_LOCKTIME1  0xf324
-#define F0900_P2_DEMOD_LOCKTIME1  0xf32400ff
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
 
 /*P2_LOCKTIME0*/
-#define R0900_P2_LOCKTIME0  0xf325
-#define F0900_P2_DEMOD_LOCKTIME0  0xf32500ff
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
 
 /*P2_VITSCALE*/
-#define R0900_P2_VITSCALE  0xf332
-#define F0900_P2_NVTH_NOSRANGE  0xf3320080
-#define F0900_P2_VERROR_MAXMODE  0xf3320040
-#define F0900_P2_KDIV_MODE  0xf3320030
-#define F0900_P2_NSLOWSN_LOCKED  0xf3320008
-#define F0900_P2_DELOCK_PRFLOSS  0xf3320004
-#define F0900_P2_DIS_RSFLOCK  0xf3320002
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
 
 /*P2_FECM*/
-#define R0900_P2_FECM  0xf333
-#define F0900_P2_DSS_DVB  0xf3330080
-#define F0900_P2_DEMOD_BYPASS  0xf3330040
-#define F0900_P2_CMP_SLOWMODE  0xf3330020
-#define F0900_P2_DSS_SRCH  0xf3330010
-#define F0900_P2_DIFF_MODEVIT  0xf3330004
-#define F0900_P2_SYNCVIT  0xf3330002
-#define F0900_P2_IQINV  0xf3330001
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
 
 /*P2_VTH12*/
-#define R0900_P2_VTH12  0xf334
-#define F0900_P2_VTH12  0xf33400ff
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
 
 /*P2_VTH23*/
-#define R0900_P2_VTH23  0xf335
-#define F0900_P2_VTH23  0xf33500ff
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
 
 /*P2_VTH34*/
-#define R0900_P2_VTH34  0xf336
-#define F0900_P2_VTH34  0xf33600ff
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
 
 /*P2_VTH56*/
-#define R0900_P2_VTH56  0xf337
-#define F0900_P2_VTH56  0xf33700ff
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
 
 /*P2_VTH67*/
-#define R0900_P2_VTH67  0xf338
-#define F0900_P2_VTH67  0xf33800ff
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
 
 /*P2_VTH78*/
-#define R0900_P2_VTH78  0xf339
-#define F0900_P2_VTH78  0xf33900ff
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
 
 /*P2_VITCURPUN*/
-#define R0900_P2_VITCURPUN  0xf33a
-#define F0900_P2_VIT_MAPPING  0xf33a00e0
-#define F0900_P2_VIT_CURPUN  0xf33a001f
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_CURPUN 0xf33a001f
 
 /*P2_VERROR*/
-#define R0900_P2_VERROR  0xf33b
-#define F0900_P2_REGERR_VIT  0xf33b00ff
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
 
 /*P2_PRVIT*/
-#define R0900_P2_PRVIT  0xf33c
-#define F0900_P2_DIS_VTHLOCK  0xf33c0040
-#define F0900_P2_E7_8VIT  0xf33c0020
-#define F0900_P2_E6_7VIT  0xf33c0010
-#define F0900_P2_E5_6VIT  0xf33c0008
-#define F0900_P2_E3_4VIT  0xf33c0004
-#define F0900_P2_E2_3VIT  0xf33c0002
-#define F0900_P2_E1_2VIT  0xf33c0001
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
 
 /*P2_VAVSRVIT*/
-#define R0900_P2_VAVSRVIT  0xf33d
-#define F0900_P2_AMVIT  0xf33d0080
-#define F0900_P2_FROZENVIT  0xf33d0040
-#define F0900_P2_SNVIT  0xf33d0030
-#define F0900_P2_TOVVIT  0xf33d000c
-#define F0900_P2_HYPVIT  0xf33d0003
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
 
 /*P2_VSTATUSVIT*/
-#define R0900_P2_VSTATUSVIT  0xf33e
-#define F0900_P2_VITERBI_ON  0xf33e0080
-#define F0900_P2_END_LOOPVIT  0xf33e0040
-#define F0900_P2_VITERBI_DEPRF  0xf33e0020
-#define F0900_P2_PRFVIT  0xf33e0010
-#define F0900_P2_LOCKEDVIT  0xf33e0008
-#define F0900_P2_VITERBI_DELOCK  0xf33e0004
-#define F0900_P2_VIT_DEMODSEL  0xf33e0002
-#define F0900_P2_VITERBI_COMPOUT  0xf33e0001
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
 
 /*P2_VTHINUSE*/
-#define R0900_P2_VTHINUSE  0xf33f
-#define F0900_P2_VIT_INUSE  0xf33f00ff
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
 
 /*P2_KDIV12*/
-#define R0900_P2_KDIV12  0xf340
-#define F0900_P2_KDIV12_MANUAL  0xf3400080
-#define F0900_P2_K_DIVIDER_12  0xf340007f
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_K_DIVIDER_12 0xf340007f
 
 /*P2_KDIV23*/
-#define R0900_P2_KDIV23  0xf341
-#define F0900_P2_KDIV23_MANUAL  0xf3410080
-#define F0900_P2_K_DIVIDER_23  0xf341007f
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_K_DIVIDER_23 0xf341007f
 
 /*P2_KDIV34*/
-#define R0900_P2_KDIV34  0xf342
-#define F0900_P2_KDIV34_MANUAL  0xf3420080
-#define F0900_P2_K_DIVIDER_34  0xf342007f
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_K_DIVIDER_34 0xf342007f
 
 /*P2_KDIV56*/
-#define R0900_P2_KDIV56  0xf343
-#define F0900_P2_KDIV56_MANUAL  0xf3430080
-#define F0900_P2_K_DIVIDER_56  0xf343007f
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_K_DIVIDER_56 0xf343007f
 
 /*P2_KDIV67*/
-#define R0900_P2_KDIV67  0xf344
-#define F0900_P2_KDIV67_MANUAL  0xf3440080
-#define F0900_P2_K_DIVIDER_67  0xf344007f
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_K_DIVIDER_67 0xf344007f
 
 /*P2_KDIV78*/
-#define R0900_P2_KDIV78  0xf345
-#define F0900_P2_KDIV78_MANUAL  0xf3450080
-#define F0900_P2_K_DIVIDER_78  0xf345007f
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_K_DIVIDER_78 0xf345007f
 
 /*P2_PDELCTRL1*/
-#define R0900_P2_PDELCTRL1  0xf350
-#define F0900_P2_INV_MISMASK  0xf3500080
-#define F0900_P2_FORCE_ACCEPTED  0xf3500040
-#define F0900_P2_FILTER_EN  0xf3500020
-#define F0900_P2_FORCE_PKTDELINUSE  0xf3500010
-#define F0900_P2_HYSTEN  0xf3500008
-#define F0900_P2_HYSTSWRST  0xf3500004
-#define F0900_P2_EN_MIS00  0xf3500002
-#define F0900_P2_ALGOSWRST  0xf3500001
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
 
 /*P2_PDELCTRL2*/
-#define R0900_P2_PDELCTRL2  0xf351
-#define F0900_P2_FORCE_CONTINUOUS  0xf3510080
-#define F0900_P2_RESET_UPKO_COUNT  0xf3510040
-#define F0900_P2_USER_PKTDELIN_NB  0xf3510020
-#define F0900_P2_FORCE_LOCKED  0xf3510010
-#define F0900_P2_DATA_UNBBSCRAM  0xf3510008
-#define F0900_P2_FORCE_LONGPKT  0xf3510004
-#define F0900_P2_FRAME_MODE  0xf3510002
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_FRAME_MODE 0xf3510002
+#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
 
 /*P2_HYSTTHRESH*/
-#define R0900_P2_HYSTTHRESH  0xf354
-#define F0900_P2_UNLCK_THRESH  0xf35400f0
-#define F0900_P2_DELIN_LCK_THRESH  0xf354000f
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
 
 /*P2_ISIENTRY*/
-#define R0900_P2_ISIENTRY  0xf35e
-#define F0900_P2_ISI_ENTRY  0xf35e00ff
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
 
 /*P2_ISIBITENA*/
-#define R0900_P2_ISIBITENA  0xf35f
-#define F0900_P2_ISI_BIT_EN  0xf35f00ff
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
 
 /*P2_MATSTR1*/
-#define R0900_P2_MATSTR1  0xf360
-#define F0900_P2_MATYPE_CURRENT1  0xf36000ff
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
 
 /*P2_MATSTR0*/
-#define R0900_P2_MATSTR0  0xf361
-#define F0900_P2_MATYPE_CURRENT0  0xf36100ff
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
 
 /*P2_UPLSTR1*/
-#define R0900_P2_UPLSTR1  0xf362
-#define F0900_P2_UPL_CURRENT1  0xf36200ff
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
 
 /*P2_UPLSTR0*/
-#define R0900_P2_UPLSTR0  0xf363
-#define F0900_P2_UPL_CURRENT0  0xf36300ff
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
 
 /*P2_DFLSTR1*/
-#define R0900_P2_DFLSTR1  0xf364
-#define F0900_P2_DFL_CURRENT1  0xf36400ff
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
 
 /*P2_DFLSTR0*/
-#define R0900_P2_DFLSTR0  0xf365
-#define F0900_P2_DFL_CURRENT0  0xf36500ff
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
 
 /*P2_SYNCSTR*/
-#define R0900_P2_SYNCSTR  0xf366
-#define F0900_P2_SYNC_CURRENT  0xf36600ff
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
 
 /*P2_SYNCDSTR1*/
-#define R0900_P2_SYNCDSTR1  0xf367
-#define F0900_P2_SYNCD_CURRENT1  0xf36700ff
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
 
 /*P2_SYNCDSTR0*/
-#define R0900_P2_SYNCDSTR0  0xf368
-#define F0900_P2_SYNCD_CURRENT0  0xf36800ff
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
 
 /*P2_PDELSTATUS1*/
-#define R0900_P2_PDELSTATUS1  0xf369
-#define F0900_P2_PKTDELIN_DELOCK  0xf3690080
-#define F0900_P2_SYNCDUPDFL_BADDFL  0xf3690040
-#define F0900_P2_CONTINUOUS_STREAM  0xf3690020
-#define F0900_P2_UNACCEPTED_STREAM  0xf3690010
-#define F0900_P2_BCH_ERROR_FLAG  0xf3690008
-#define F0900_P2_BBHCRCKO  0xf3690004
-#define F0900_P2_PKTDELIN_LOCK  0xf3690002
-#define F0900_P2_FIRST_LOCK  0xf3690001
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
 
 /*P2_PDELSTATUS2*/
-#define R0900_P2_PDELSTATUS2  0xf36a
-#define F0900_P2_PKTDEL_DEMODSEL  0xf36a0080
-#define F0900_P2_FRAME_MODCOD  0xf36a007c
-#define F0900_P2_FRAME_TYPE  0xf36a0003
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
 
 /*P2_BBFCRCKO1*/
-#define R0900_P2_BBFCRCKO1  0xf36b
-#define F0900_P2_BBHCRC_KOCNT1  0xf36b00ff
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
 
 /*P2_BBFCRCKO0*/
-#define R0900_P2_BBFCRCKO0  0xf36c
-#define F0900_P2_BBHCRC_KOCNT0  0xf36c00ff
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
 
 /*P2_UPCRCKO1*/
-#define R0900_P2_UPCRCKO1  0xf36d
-#define F0900_P2_PKTCRC_KOCNT1  0xf36d00ff
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
 
 /*P2_UPCRCKO0*/
-#define R0900_P2_UPCRCKO0  0xf36e
-#define F0900_P2_PKTCRC_KOCNT0  0xf36e00ff
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_PDELCTRL3*/
+#define R0900_P2_PDELCTRL3 0xf36f
+#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
+#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
 
 /*P2_TSSTATEM*/
-#define R0900_P2_TSSTATEM  0xf370
-#define F0900_P2_TSDIL_ON  0xf3700080
-#define F0900_P2_TSSKIPRS_ON  0xf3700040
-#define F0900_P2_TSRS_ON  0xf3700020
-#define F0900_P2_TSDESCRAMB_ON  0xf3700010
-#define F0900_P2_TSFRAME_MODE  0xf3700008
-#define F0900_P2_TS_DISABLE  0xf3700004
-#define F0900_P2_TSACM_MODE  0xf3700002
-#define F0900_P2_TSOUT_NOSYNC  0xf3700001
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
 
 /*P2_TSCFGH*/
-#define R0900_P2_TSCFGH  0xf372
-#define F0900_P2_TSFIFO_DVBCI  0xf3720080
-#define F0900_P2_TSFIFO_SERIAL  0xf3720040
-#define F0900_P2_TSFIFO_TEIUPDATE  0xf3720020
-#define F0900_P2_TSFIFO_DUTY50  0xf3720010
-#define F0900_P2_TSFIFO_HSGNLOUT  0xf3720008
-#define F0900_P2_TSFIFO_ERRMODE  0xf3720006
-#define F0900_P2_RST_HWARE  0xf3720001
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
 
 /*P2_TSCFGM*/
-#define R0900_P2_TSCFGM  0xf373
-#define F0900_P2_TSFIFO_MANSPEED  0xf37300c0
-#define F0900_P2_TSFIFO_PERMDATA  0xf3730020
-#define F0900_P2_TSFIFO_NONEWSGNL  0xf3730010
-#define F0900_P2_TSFIFO_BITSPEED  0xf3730008
-#define F0900_P2_NPD_SPECDVBS2  0xf3730004
-#define F0900_P2_TSFIFO_STOPCKDIS  0xf3730002
-#define F0900_P2_TSFIFO_INVDATA  0xf3730001
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
 
 /*P2_TSCFGL*/
-#define R0900_P2_TSCFGL  0xf374
-#define F0900_P2_TSFIFO_BCLKDEL1CK  0xf37400c0
-#define F0900_P2_BCHERROR_MODE  0xf3740030
-#define F0900_P2_TSFIFO_NSGNL2DATA  0xf3740008
-#define F0900_P2_TSFIFO_EMBINDVB  0xf3740004
-#define F0900_P2_TSFIFO_DPUNACT  0xf3740002
-#define F0900_P2_TSFIFO_NPDOFF  0xf3740001
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
 
 /*P2_TSINSDELH*/
-#define R0900_P2_TSINSDELH  0xf376
-#define F0900_P2_TSDEL_SYNCBYTE  0xf3760080
-#define F0900_P2_TSDEL_XXHEADER  0xf3760040
-#define F0900_P2_TSDEL_BBHEADER  0xf3760020
-#define F0900_P2_TSDEL_DATAFIELD  0xf3760010
-#define F0900_P2_TSINSDEL_ISCR  0xf3760008
-#define F0900_P2_TSINSDEL_NPD  0xf3760004
-#define F0900_P2_TSINSDEL_RSPARITY  0xf3760002
-#define F0900_P2_TSINSDEL_CRC8  0xf3760001
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSDIVN*/
+#define R0900_P2_TSDIVN 0xf379
+#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
+
+/*P2_TSCFG4*/
+#define R0900_P2_TSCFG4 0xf37a
+#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
 
 /*P2_TSSPEED*/
-#define R0900_P2_TSSPEED  0xf380
-#define F0900_P2_TSFIFO_OUTSPEED  0xf38000ff
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
 
 /*P2_TSSTATUS*/
-#define R0900_P2_TSSTATUS  0xf381
-#define F0900_P2_TSFIFO_LINEOK  0xf3810080
-#define F0900_P2_TSFIFO_ERROR  0xf3810040
-#define F0900_P2_TSFIFO_DATA7  0xf3810020
-#define F0900_P2_TSFIFO_NOSYNC  0xf3810010
-#define F0900_P2_ISCR_INITIALIZED  0xf3810008
-#define F0900_P2_ISCR_UPDATED  0xf3810004
-#define F0900_P2_SOFFIFO_UNREGUL  0xf3810002
-#define F0900_P2_DIL_READY  0xf3810001
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_DIL_READY 0xf3810001
 
 /*P2_TSSTATUS2*/
-#define R0900_P2_TSSTATUS2  0xf382
-#define F0900_P2_TSFIFO_DEMODSEL  0xf3820080
-#define F0900_P2_TSFIFOSPEED_STORE  0xf3820040
-#define F0900_P2_DILXX_RESET  0xf3820020
-#define F0900_P2_TSSERIAL_IMPOS  0xf3820010
-#define F0900_P2_TSFIFO_LINENOK  0xf3820008
-#define F0900_P2_BITSPEED_EVENT  0xf3820004
-#define F0900_P2_SCRAMBDETECT  0xf3820002
-#define F0900_P2_ULDTV67_FALSELOCK  0xf3820001
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_SCRAMBDETECT 0xf3820002
 
 /*P2_TSBITRATE1*/
-#define R0900_P2_TSBITRATE1  0xf383
-#define F0900_P2_TSFIFO_BITRATE1  0xf38300ff
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
 
 /*P2_TSBITRATE0*/
-#define R0900_P2_TSBITRATE0  0xf384
-#define F0900_P2_TSFIFO_BITRATE0  0xf38400ff
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
 
 /*P2_ERRCTRL1*/
-#define R0900_P2_ERRCTRL1  0xf398
-#define F0900_P2_ERR_SOURCE1  0xf39800f0
-#define F0900_P2_NUM_EVENT1  0xf3980007
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
 
 /*P2_ERRCNT12*/
-#define R0900_P2_ERRCNT12  0xf399
-#define F0900_P2_ERRCNT1_OLDVALUE  0xf3990080
-#define F0900_P2_ERR_CNT12  0xf399007f
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
 
 /*P2_ERRCNT11*/
-#define R0900_P2_ERRCNT11  0xf39a
-#define F0900_P2_ERR_CNT11  0xf39a00ff
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
 
 /*P2_ERRCNT10*/
-#define R0900_P2_ERRCNT10  0xf39b
-#define F0900_P2_ERR_CNT10  0xf39b00ff
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
 
 /*P2_ERRCTRL2*/
-#define R0900_P2_ERRCTRL2  0xf39c
-#define F0900_P2_ERR_SOURCE2  0xf39c00f0
-#define F0900_P2_NUM_EVENT2  0xf39c0007
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
 
 /*P2_ERRCNT22*/
-#define R0900_P2_ERRCNT22  0xf39d
-#define F0900_P2_ERRCNT2_OLDVALUE  0xf39d0080
-#define F0900_P2_ERR_CNT22  0xf39d007f
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
 
 /*P2_ERRCNT21*/
-#define R0900_P2_ERRCNT21  0xf39e
-#define F0900_P2_ERR_CNT21  0xf39e00ff
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
 
 /*P2_ERRCNT20*/
-#define R0900_P2_ERRCNT20  0xf39f
-#define F0900_P2_ERR_CNT20  0xf39f00ff
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
 
 /*P2_FECSPY*/
-#define R0900_P2_FECSPY  0xf3a0
-#define F0900_P2_SPY_ENABLE  0xf3a00080
-#define F0900_P2_NO_SYNCBYTE  0xf3a00040
-#define F0900_P2_SERIAL_MODE  0xf3a00020
-#define F0900_P2_UNUSUAL_PACKET  0xf3a00010
-#define F0900_P2_BER_PACKMODE  0xf3a00008
-#define F0900_P2_BERMETER_LMODE  0xf3a00002
-#define F0900_P2_BERMETER_RESET  0xf3a00001
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
 
 /*P2_FSPYCFG*/
-#define R0900_P2_FSPYCFG  0xf3a1
-#define F0900_P2_FECSPY_INPUT  0xf3a100c0
-#define F0900_P2_RST_ON_ERROR  0xf3a10020
-#define F0900_P2_ONE_SHOT  0xf3a10010
-#define F0900_P2_I2C_MODE  0xf3a1000c
-#define F0900_P2_SPY_HYSTERESIS  0xf3a10003
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
 
 /*P2_FSPYDATA*/
-#define R0900_P2_FSPYDATA  0xf3a2
-#define F0900_P2_SPY_STUFFING  0xf3a20080
-#define F0900_P2_NOERROR_PKTJITTER  0xf3a20040
-#define F0900_P2_SPY_CNULLPKT  0xf3a20020
-#define F0900_P2_SPY_OUTDATA_MODE  0xf3a2001f
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
 
 /*P2_FSPYOUT*/
-#define R0900_P2_FSPYOUT  0xf3a3
-#define F0900_P2_FSPY_DIRECT  0xf3a30080
-#define F0900_P2_SPY_OUTDATA_BUS  0xf3a30038
-#define F0900_P2_STUFF_MODE  0xf3a30007
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_STUFF_MODE 0xf3a30007
 
 /*P2_FSTATUS*/
-#define R0900_P2_FSTATUS  0xf3a4
-#define F0900_P2_SPY_ENDSIM  0xf3a40080
-#define F0900_P2_VALID_SIM  0xf3a40040
-#define F0900_P2_FOUND_SIGNAL  0xf3a40020
-#define F0900_P2_DSS_SYNCBYTE  0xf3a40010
-#define F0900_P2_RESULT_STATE  0xf3a4000f
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
 
 /*P2_FBERCPT4*/
-#define R0900_P2_FBERCPT4  0xf3a8
-#define F0900_P2_FBERMETER_CPT4  0xf3a800ff
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
 
 /*P2_FBERCPT3*/
-#define R0900_P2_FBERCPT3  0xf3a9
-#define F0900_P2_FBERMETER_CPT3  0xf3a900ff
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
 
 /*P2_FBERCPT2*/
-#define R0900_P2_FBERCPT2  0xf3aa
-#define F0900_P2_FBERMETER_CPT2  0xf3aa00ff
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
 
 /*P2_FBERCPT1*/
-#define R0900_P2_FBERCPT1  0xf3ab
-#define F0900_P2_FBERMETER_CPT1  0xf3ab00ff
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
 
 /*P2_FBERCPT0*/
-#define R0900_P2_FBERCPT0  0xf3ac
-#define F0900_P2_FBERMETER_CPT0  0xf3ac00ff
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
 
 /*P2_FBERERR2*/
-#define R0900_P2_FBERERR2  0xf3ad
-#define F0900_P2_FBERMETER_ERR2  0xf3ad00ff
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
 
 /*P2_FBERERR1*/
-#define R0900_P2_FBERERR1  0xf3ae
-#define F0900_P2_FBERMETER_ERR1  0xf3ae00ff
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
 
 /*P2_FBERERR0*/
-#define R0900_P2_FBERERR0  0xf3af
-#define F0900_P2_FBERMETER_ERR0  0xf3af00ff
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
 
 /*P2_FSPYBER*/
-#define R0900_P2_FSPYBER  0xf3b2
-#define F0900_P2_FSPYOBS_XORREAD  0xf3b20040
-#define F0900_P2_FSPYBER_OBSMODE  0xf3b20020
-#define F0900_P2_FSPYBER_SYNCBYTE  0xf3b20010
-#define F0900_P2_FSPYBER_UNSYNC  0xf3b20008
-#define F0900_P2_FSPYBER_CTIME  0xf3b20007
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
 
 /*P1_IQCONST*/
-#define R0900_P1_IQCONST  0xf400
-#define F0900_P1_CONSTEL_SELECT  0xf4000060
-#define F0900_P1_IQSYMB_SEL  0xf400001f
+#define R0900_P1_IQCONST 0xf400
+#define IQCONST REGx(R0900_P1_IQCONST)
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
 
 /*P1_NOSCFG*/
-#define R0900_P1_NOSCFG  0xf401
-#define F0900_P1_DUMMYPL_NOSDATA  0xf4010020
-#define F0900_P1_NOSPLH_BETA  0xf4010018
-#define F0900_P1_NOSDATA_BETA  0xf4010007
+#define R0900_P1_NOSCFG 0xf401
+#define NOSCFG REGx(R0900_P1_NOSCFG)
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
 
 /*P1_ISYMB*/
-#define R0900_P1_ISYMB  0xf402
-#define F0900_P1_I_SYMBOL  0xf40201ff
+#define R0900_P1_ISYMB 0xf402
+#define ISYMB REGx(R0900_P1_ISYMB)
+#define F0900_P1_I_SYMBOL 0xf40201ff
 
 /*P1_QSYMB*/
-#define R0900_P1_QSYMB  0xf403
-#define F0900_P1_Q_SYMBOL  0xf40301ff
+#define R0900_P1_QSYMB 0xf403
+#define QSYMB REGx(R0900_P1_QSYMB)
+#define F0900_P1_Q_SYMBOL 0xf40301ff
 
 /*P1_AGC1CFG*/
-#define R0900_P1_AGC1CFG  0xf404
-#define F0900_P1_DC_FROZEN  0xf4040080
-#define F0900_P1_DC_CORRECT  0xf4040040
-#define F0900_P1_AMM_FROZEN  0xf4040020
-#define F0900_P1_AMM_CORRECT  0xf4040010
-#define F0900_P1_QUAD_FROZEN  0xf4040008
-#define F0900_P1_QUAD_CORRECT  0xf4040004
-#define F0900_P1_DCCOMP_SLOW  0xf4040002
-#define F0900_P1_IQMISM_SLOW  0xf4040001
+#define R0900_P1_AGC1CFG 0xf404
+#define AGC1CFG REGx(R0900_P1_AGC1CFG)
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
 
 /*P1_AGC1CN*/
-#define R0900_P1_AGC1CN  0xf406
-#define F0900_P1_AGC1_LOCKED  0xf4060080
-#define F0900_P1_AGC1_OVERFLOW  0xf4060040
-#define F0900_P1_AGC1_NOSLOWLK  0xf4060020
-#define F0900_P1_AGC1_MINPOWER  0xf4060010
-#define F0900_P1_AGCOUT_FAST  0xf4060008
-#define F0900_P1_AGCIQ_BETA  0xf4060007
+#define R0900_P1_AGC1CN 0xf406
+#define AGC1CN REGx(R0900_P1_AGC1CN)
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
 
 /*P1_AGC1REF*/
-#define R0900_P1_AGC1REF  0xf407
-#define F0900_P1_AGCIQ_REF  0xf40700ff
+#define R0900_P1_AGC1REF 0xf407
+#define AGC1REF REGx(R0900_P1_AGC1REF)
+#define F0900_P1_AGCIQ_REF 0xf40700ff
 
 /*P1_IDCCOMP*/
-#define R0900_P1_IDCCOMP  0xf408
-#define F0900_P1_IAVERAGE_ADJ  0xf40801ff
+#define R0900_P1_IDCCOMP 0xf408
+#define IDCCOMP REGx(R0900_P1_IDCCOMP)
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
 
 /*P1_QDCCOMP*/
-#define R0900_P1_QDCCOMP  0xf409
-#define F0900_P1_QAVERAGE_ADJ  0xf40901ff
+#define R0900_P1_QDCCOMP 0xf409
+#define QDCCOMP REGx(R0900_P1_QDCCOMP)
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
 
 /*P1_POWERI*/
-#define R0900_P1_POWERI  0xf40a
-#define F0900_P1_POWER_I  0xf40a00ff
+#define R0900_P1_POWERI 0xf40a
+#define POWERI REGx(R0900_P1_POWERI)
+#define F0900_P1_POWER_I 0xf40a00ff
+#define POWER_I FLDx(F0900_P1_POWER_I)
 
 /*P1_POWERQ*/
-#define R0900_P1_POWERQ  0xf40b
-#define F0900_P1_POWER_Q  0xf40b00ff
+#define R0900_P1_POWERQ 0xf40b
+#define POWERQ REGx(R0900_P1_POWERQ)
+#define F0900_P1_POWER_Q 0xf40b00ff
+#define POWER_Q FLDx(F0900_P1_POWER_Q)
 
 /*P1_AGC1AMM*/
-#define R0900_P1_AGC1AMM  0xf40c
-#define F0900_P1_AMM_VALUE  0xf40c00ff
+#define R0900_P1_AGC1AMM 0xf40c
+#define AGC1AMM REGx(R0900_P1_AGC1AMM)
+#define F0900_P1_AMM_VALUE 0xf40c00ff
 
 /*P1_AGC1QUAD*/
-#define R0900_P1_AGC1QUAD  0xf40d
-#define F0900_P1_QUAD_VALUE  0xf40d01ff
+#define R0900_P1_AGC1QUAD 0xf40d
+#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
 
 /*P1_AGCIQIN1*/
-#define R0900_P1_AGCIQIN1  0xf40e
-#define F0900_P1_AGCIQ_VALUE1  0xf40e00ff
+#define R0900_P1_AGCIQIN1 0xf40e
+#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
 
 /*P1_AGCIQIN0*/
-#define R0900_P1_AGCIQIN0  0xf40f
-#define F0900_P1_AGCIQ_VALUE0  0xf40f00ff
+#define R0900_P1_AGCIQIN0 0xf40f
+#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
 
 /*P1_DEMOD*/
-#define R0900_P1_DEMOD  0xf410
-#define F0900_P1_DEMOD_STOP  0xf4100040
-#define F0900_P1_SPECINV_CONTROL  0xf4100030
-#define F0900_P1_FORCE_ENASAMP  0xf4100008
-#define F0900_P1_MANUAL_ROLLOFF  0xf4100004
-#define F0900_P1_ROLLOFF_CONTROL  0xf4100003
+#define R0900_P1_DEMOD 0xf410
+#define DEMOD REGx(R0900_P1_DEMOD)
+#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
+#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
+
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
+#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
 
 /*P1_DMDMODCOD*/
-#define R0900_P1_DMDMODCOD  0xf411
-#define F0900_P1_MANUAL_MODCOD  0xf4110080
-#define F0900_P1_DEMOD_MODCOD  0xf411007c
-#define F0900_P1_DEMOD_TYPE  0xf4110003
+#define R0900_P1_DMDMODCOD 0xf411
+#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
 
 /*P1_DSTATUS*/
-#define R0900_P1_DSTATUS  0xf412
-#define F0900_P1_CAR_LOCK  0xf4120080
-#define F0900_P1_TMGLOCK_QUALITY  0xf4120060
-#define F0900_P1_SDVBS1_ENABLE  0xf4120010
-#define F0900_P1_LOCK_DEFINITIF  0xf4120008
-#define F0900_P1_TIMING_IS_LOCKED  0xf4120004
-#define F0900_P1_COARSE_TMGLOCK  0xf4120002
-#define F0900_P1_COARSE_CARLOCK  0xf4120001
+#define R0900_P1_DSTATUS 0xf412
+#define DSTATUS REGx(R0900_P1_DSTATUS)
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
+#define F0900_P1_OVADC_DETECT 0xf4120001
 
 /*P1_DSTATUS2*/
-#define R0900_P1_DSTATUS2  0xf413
-#define F0900_P1_DEMOD_DELOCK  0xf4130080
-#define F0900_P1_DEMOD_TIMEOUT  0xf4130040
-#define F0900_P1_MODCODRQ_SYNCTAG  0xf4130020
-#define F0900_P1_POLYPH_SATEVENT  0xf4130010
-#define F0900_P1_AGC1_NOSIGNALACK  0xf4130008
-#define F0900_P1_AGC2_OVERFLOW  0xf4130004
-#define F0900_P1_CFR_OVERFLOW  0xf4130002
-#define F0900_P1_GAMMA_OVERUNDER  0xf4130001
+#define R0900_P1_DSTATUS2 0xf413
+#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
 
 /*P1_DMDCFGMD*/
-#define R0900_P1_DMDCFGMD  0xf414
-#define F0900_P1_DVBS2_ENABLE  0xf4140080
-#define F0900_P1_DVBS1_ENABLE  0xf4140040
-#define F0900_P1_CFR_AUTOSCAN  0xf4140020
-#define F0900_P1_SCAN_ENABLE  0xf4140010
-#define F0900_P1_TUN_AUTOSCAN  0xf4140008
-#define F0900_P1_NOFORCE_RELOCK  0xf4140004
-#define F0900_P1_TUN_RNG  0xf4140003
+#define R0900_P1_DMDCFGMD 0xf414
+#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
+#define F0900_P1_CFR_AUTOSCAN 0xf4140008
+#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
+#define F0900_P1_TUN_RNG 0xf4140003
 
 /*P1_DMDCFG2*/
-#define R0900_P1_DMDCFG2  0xf415
-#define F0900_P1_AGC1_WAITLOCK  0xf4150080
-#define F0900_P1_S1S2_SEQUENTIAL  0xf4150040
-#define F0900_P1_OVERFLOW_TIMEOUT  0xf4150020
-#define F0900_P1_SCANFAIL_TIMEOUT  0xf4150010
-#define F0900_P1_DMDTOUT_BACK  0xf4150008
-#define F0900_P1_CARLOCK_S1ENABLE  0xf4150004
-#define F0900_P1_COARSE_LK3MODE  0xf4150002
-#define F0900_P1_COARSE_LK2MODE  0xf4150001
+#define R0900_P1_DMDCFG2 0xf415
+#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
+#define F0900_P1_INFINITE_RELOCK 0xf4150010
 
 /*P1_DMDISTATE*/
-#define R0900_P1_DMDISTATE  0xf416
-#define F0900_P1_I2C_NORESETDMODE  0xf4160080
-#define F0900_P1_FORCE_ETAPED  0xf4160040
-#define F0900_P1_SDMDRST_DIRCLK  0xf4160020
-#define F0900_P1_I2C_DEMOD_MODE  0xf416001f
+#define R0900_P1_DMDISTATE 0xf416
+#define DMDISTATE REGx(R0900_P1_DMDISTATE)
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
 
 /*P1_DMDT0M*/
-#define R0900_P1_DMDT0M  0xf417
-#define F0900_P1_DMDT0_MIN  0xf41700ff
+#define R0900_P1_DMDT0M 0xf417
+#define DMDT0M REGx(R0900_P1_DMDT0M)
+#define F0900_P1_DMDT0_MIN 0xf41700ff
 
 /*P1_DMDSTATE*/
-#define R0900_P1_DMDSTATE  0xf41b
-#define F0900_P1_DEMOD_LOCKED  0xf41b0080
-#define F0900_P1_HEADER_MODE  0xf41b0060
-#define F0900_P1_DEMOD_MODE  0xf41b001f
+#define R0900_P1_DMDSTATE 0xf41b
+#define DMDSTATE REGx(R0900_P1_DMDSTATE)
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
 
 /*P1_DMDFLYW*/
-#define R0900_P1_DMDFLYW  0xf41c
-#define F0900_P1_I2C_IRQVAL  0xf41c00f0
-#define F0900_P1_FLYWHEEL_CPT  0xf41c000f
+#define R0900_P1_DMDFLYW 0xf41c
+#define DMDFLYW REGx(R0900_P1_DMDFLYW)
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
 
 /*P1_DSTATUS3*/
-#define R0900_P1_DSTATUS3  0xf41d
-#define F0900_P1_CFR_ZIGZAG  0xf41d0080
-#define F0900_P1_DEMOD_CFGMODE  0xf41d0060
-#define F0900_P1_GAMMA_LOWBAUDRATE  0xf41d0010
-#define F0900_P1_RELOCK_MODE  0xf41d0008
-#define F0900_P1_DEMOD_FAIL  0xf41d0004
-#define F0900_P1_ETAPE1A_DVBXMEM  0xf41d0003
+#define R0900_P1_DSTATUS3 0xf41d
+#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
 
 /*P1_DMDCFG3*/
-#define R0900_P1_DMDCFG3  0xf41e
-#define F0900_P1_DVBS1_TMGWAIT  0xf41e0080
-#define F0900_P1_NO_BWCENTERING  0xf41e0040
-#define F0900_P1_INV_SEQSRCH  0xf41e0020
-#define F0900_P1_DIS_SFRUPLOW_TRK  0xf41e0010
-#define F0900_P1_NOSTOP_FIFOFULL  0xf41e0008
-#define F0900_P1_LOCKTIME_MODE  0xf41e0007
+#define R0900_P1_DMDCFG3 0xf41e
+#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
 
 /*P1_DMDCFG4*/
-#define R0900_P1_DMDCFG4  0xf41f
-#define F0900_P1_TUNER_NRELAUNCH  0xf41f0008
-#define F0900_P1_DIS_CLKENABLE  0xf41f0004
-#define F0900_P1_DIS_HDRDIVLOCK  0xf41f0002
-#define F0900_P1_NO_TNRWBINIT  0xf41f0001
+#define R0900_P1_DMDCFG4 0xf41f
+#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
 
 /*P1_CORRELMANT*/
-#define R0900_P1_CORRELMANT  0xf420
-#define F0900_P1_CORREL_MANT  0xf42000ff
+#define R0900_P1_CORRELMANT 0xf420
+#define CORRELMANT REGx(R0900_P1_CORRELMANT)
+#define F0900_P1_CORREL_MANT 0xf42000ff
 
 /*P1_CORRELABS*/
-#define R0900_P1_CORRELABS  0xf421
-#define F0900_P1_CORREL_ABS  0xf42100ff
+#define R0900_P1_CORRELABS 0xf421
+#define CORRELABS REGx(R0900_P1_CORRELABS)
+#define F0900_P1_CORREL_ABS 0xf42100ff
 
 /*P1_CORRELEXP*/
-#define R0900_P1_CORRELEXP  0xf422
-#define F0900_P1_CORREL_ABSEXP  0xf42200f0
-#define F0900_P1_CORREL_EXP  0xf422000f
+#define R0900_P1_CORRELEXP 0xf422
+#define CORRELEXP REGx(R0900_P1_CORRELEXP)
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
 
 /*P1_PLHMODCOD*/
-#define R0900_P1_PLHMODCOD  0xf424
-#define F0900_P1_SPECINV_DEMOD  0xf4240080
-#define F0900_P1_PLH_MODCOD  0xf424007c
-#define F0900_P1_PLH_TYPE  0xf4240003
+#define R0900_P1_PLHMODCOD 0xf424
+#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
 
-/*P1_AGCK32*/
-#define R0900_P1_AGCK32  0xf42b
-#define F0900_P1_R3ADJOFF_32APSK  0xf42b0080
-#define F0900_P1_R2ADJOFF_32APSK  0xf42b0040
-#define F0900_P1_R1ADJOFF_32APSK  0xf42b0020
-#define F0900_P1_RADJ_32APSK  0xf42b001f
+/*P1_DMDREG*/
+#define R0900_P1_DMDREG 0xf425
+#define DMDREG REGx(R0900_P1_DMDREG)
+#define F0900_P1_DECIM_PLFRAMES 0xf4250001
 
 /*P1_AGC2O*/
-#define R0900_P1_AGC2O  0xf42c
-#define F0900_P1_AGC2REF_ADJUSTING  0xf42c0080
-#define F0900_P1_AGC2_COARSEFAST  0xf42c0040
-#define F0900_P1_AGC2_LKSQRT  0xf42c0020
-#define F0900_P1_AGC2_LKMODE  0xf42c0010
-#define F0900_P1_AGC2_LKEQUA  0xf42c0008
-#define F0900_P1_AGC2_COEF  0xf42c0007
+#define R0900_P1_AGC2O 0xf42c
+#define AGC2O REGx(R0900_P1_AGC2O)
+#define F0900_P1_AGC2_COEF 0xf42c0007
 
 /*P1_AGC2REF*/
-#define R0900_P1_AGC2REF  0xf42d
-#define F0900_P1_AGC2_REF  0xf42d00ff
+#define R0900_P1_AGC2REF 0xf42d
+#define AGC2REF REGx(R0900_P1_AGC2REF)
+#define F0900_P1_AGC2_REF 0xf42d00ff
 
 /*P1_AGC1ADJ*/
-#define R0900_P1_AGC1ADJ  0xf42e
-#define F0900_P1_AGC1ADJ_MANUAL  0xf42e0080
-#define F0900_P1_AGC1_ADJUSTED  0xf42e017f
+#define R0900_P1_AGC1ADJ 0xf42e
+#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
+#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
 
 /*P1_AGC2I1*/
-#define R0900_P1_AGC2I1  0xf436
-#define F0900_P1_AGC2_INTEGRATOR1  0xf43600ff
+#define R0900_P1_AGC2I1 0xf436
+#define AGC2I1 REGx(R0900_P1_AGC2I1)
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
 
 /*P1_AGC2I0*/
-#define R0900_P1_AGC2I0  0xf437
-#define F0900_P1_AGC2_INTEGRATOR0  0xf43700ff
+#define R0900_P1_AGC2I0 0xf437
+#define AGC2I0 REGx(R0900_P1_AGC2I0)
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
 
 /*P1_CARCFG*/
-#define R0900_P1_CARCFG  0xf438
-#define F0900_P1_CFRUPLOW_AUTO  0xf4380080
-#define F0900_P1_CFRUPLOW_TEST  0xf4380040
-#define F0900_P1_EN_CAR2CENTER  0xf4380020
-#define F0900_P1_CARHDR_NODIV8  0xf4380010
-#define F0900_P1_I2C_ROTA  0xf4380008
-#define F0900_P1_ROTAON  0xf4380004
-#define F0900_P1_PH_DET_ALGO  0xf4380003
+#define R0900_P1_CARCFG 0xf438
+#define CARCFG REGx(R0900_P1_CARCFG)
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
 
 /*P1_ACLC*/
-#define R0900_P1_ACLC  0xf439
-#define F0900_P1_STOP_S2ALPHA  0xf43900c0
-#define F0900_P1_CAR_ALPHA_MANT  0xf4390030
-#define F0900_P1_CAR_ALPHA_EXP  0xf439000f
+#define R0900_P1_ACLC 0xf439
+#define ACLC REGx(R0900_P1_ACLC)
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
 
 /*P1_BCLC*/
-#define R0900_P1_BCLC  0xf43a
-#define F0900_P1_STOP_S2BETA  0xf43a00c0
-#define F0900_P1_CAR_BETA_MANT  0xf43a0030
-#define F0900_P1_CAR_BETA_EXP  0xf43a000f
+#define R0900_P1_BCLC 0xf43a
+#define BCLC REGx(R0900_P1_BCLC)
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
 
 /*P1_CARFREQ*/
-#define R0900_P1_CARFREQ  0xf43d
-#define F0900_P1_KC_COARSE_EXP  0xf43d00f0
-#define F0900_P1_BETA_FREQ  0xf43d000f
+#define R0900_P1_CARFREQ 0xf43d
+#define CARFREQ REGx(R0900_P1_CARFREQ)
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
 
 /*P1_CARHDR*/
-#define R0900_P1_CARHDR  0xf43e
-#define F0900_P1_K_FREQ_HDR  0xf43e00ff
+#define R0900_P1_CARHDR 0xf43e
+#define CARHDR REGx(R0900_P1_CARHDR)
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
 
 /*P1_LDT*/
-#define R0900_P1_LDT  0xf43f
-#define F0900_P1_CARLOCK_THRES  0xf43f01ff
+#define R0900_P1_LDT 0xf43f
+#define LDT REGx(R0900_P1_LDT)
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
 
 /*P1_LDT2*/
-#define R0900_P1_LDT2  0xf440
-#define F0900_P1_CARLOCK_THRES2  0xf44001ff
+#define R0900_P1_LDT2 0xf440
+#define LDT2 REGx(R0900_P1_LDT2)
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
 
 /*P1_CFRICFG*/
-#define R0900_P1_CFRICFG  0xf441
-#define F0900_P1_CFRINIT_UNVALRNG  0xf4410080
-#define F0900_P1_CFRINIT_LUNVALCPT  0xf4410040
-#define F0900_P1_CFRINIT_ABORTDBL  0xf4410020
-#define F0900_P1_CFRINIT_ABORTPRED  0xf4410010
-#define F0900_P1_CFRINIT_UNVALSKIP  0xf4410008
-#define F0900_P1_CFRINIT_CSTINC  0xf4410004
-#define F0900_P1_NEG_CFRSTEP  0xf4410001
+#define R0900_P1_CFRICFG 0xf441
+#define CFRICFG REGx(R0900_P1_CFRICFG)
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
 
 /*P1_CFRUP1*/
-#define R0900_P1_CFRUP1  0xf442
-#define F0900_P1_CFR_UP1  0xf44201ff
+#define R0900_P1_CFRUP1 0xf442
+#define CFRUP1 REGx(R0900_P1_CFRUP1)
+#define F0900_P1_CFR_UP1 0xf44201ff
+#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
 
 /*P1_CFRUP0*/
-#define R0900_P1_CFRUP0  0xf443
-#define F0900_P1_CFR_UP0  0xf44300ff
+#define R0900_P1_CFRUP0 0xf443
+#define CFRUP0 REGx(R0900_P1_CFRUP0)
+#define F0900_P1_CFR_UP0 0xf44300ff
+#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
 
 /*P1_CFRLOW1*/
-#define R0900_P1_CFRLOW1  0xf446
-#define F0900_P1_CFR_LOW1  0xf44601ff
+#define R0900_P1_CFRLOW1 0xf446
+#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
+#define F0900_P1_CFR_LOW1 0xf44601ff
+#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
 
 /*P1_CFRLOW0*/
-#define R0900_P1_CFRLOW0  0xf447
-#define F0900_P1_CFR_LOW0  0xf44700ff
+#define R0900_P1_CFRLOW0 0xf447
+#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
+#define F0900_P1_CFR_LOW0 0xf44700ff
+#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
 
 /*P1_CFRINIT1*/
-#define R0900_P1_CFRINIT1  0xf448
-#define F0900_P1_CFR_INIT1  0xf44801ff
+#define R0900_P1_CFRINIT1 0xf448
+#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
+#define F0900_P1_CFR_INIT1 0xf44801ff
+#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
 
 /*P1_CFRINIT0*/
-#define R0900_P1_CFRINIT0  0xf449
-#define F0900_P1_CFR_INIT0  0xf44900ff
+#define R0900_P1_CFRINIT0 0xf449
+#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
+#define F0900_P1_CFR_INIT0 0xf44900ff
+#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
 
 /*P1_CFRINC1*/
-#define R0900_P1_CFRINC1  0xf44a
-#define F0900_P1_MANUAL_CFRINC  0xf44a0080
-#define F0900_P1_CFR_INC1  0xf44a017f
+#define R0900_P1_CFRINC1 0xf44a
+#define CFRINC1 REGx(R0900_P1_CFRINC1)
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a003f
 
 /*P1_CFRINC0*/
-#define R0900_P1_CFRINC0  0xf44b
-#define F0900_P1_CFR_INC0  0xf44b00f0
+#define R0900_P1_CFRINC0 0xf44b
+#define CFRINC0 REGx(R0900_P1_CFRINC0)
+#define F0900_P1_CFR_INC0 0xf44b00f8
 
 /*P1_CFR2*/
-#define R0900_P1_CFR2  0xf44c
-#define F0900_P1_CAR_FREQ2  0xf44c01ff
+#define R0900_P1_CFR2 0xf44c
+#define CFR2 REGx(R0900_P1_CFR2)
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
 
 /*P1_CFR1*/
-#define R0900_P1_CFR1  0xf44d
-#define F0900_P1_CAR_FREQ1  0xf44d00ff
+#define R0900_P1_CFR1 0xf44d
+#define CFR1 REGx(R0900_P1_CFR1)
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
 
 /*P1_CFR0*/
-#define R0900_P1_CFR0  0xf44e
-#define F0900_P1_CAR_FREQ0  0xf44e00ff
+#define R0900_P1_CFR0 0xf44e
+#define CFR0 REGx(R0900_P1_CFR0)
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
 
 /*P1_LDI*/
-#define R0900_P1_LDI  0xf44f
-#define F0900_P1_LOCK_DET_INTEGR  0xf44f01ff
+#define R0900_P1_LDI 0xf44f
+#define LDI REGx(R0900_P1_LDI)
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
 
 /*P1_TMGCFG*/
-#define R0900_P1_TMGCFG  0xf450
-#define F0900_P1_TMGLOCK_BETA  0xf45000c0
-#define F0900_P1_NOTMG_GROUPDELAY  0xf4500020
-#define F0900_P1_DO_TIMING_CORR  0xf4500010
-#define F0900_P1_MANUAL_SCAN  0xf450000c
-#define F0900_P1_TMG_MINFREQ  0xf4500003
+#define R0900_P1_TMGCFG 0xf450
+#define TMGCFG REGx(R0900_P1_TMGCFG)
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_TMG_MINFREQ 0xf4500003
 
 /*P1_RTC*/
-#define R0900_P1_RTC  0xf451
-#define F0900_P1_TMGALPHA_EXP  0xf45100f0
-#define F0900_P1_TMGBETA_EXP  0xf451000f
+#define R0900_P1_RTC 0xf451
+#define RTC REGx(R0900_P1_RTC)
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
 
 /*P1_RTCS2*/
-#define R0900_P1_RTCS2  0xf452
-#define F0900_P1_TMGALPHAS2_EXP  0xf45200f0
-#define F0900_P1_TMGBETAS2_EXP  0xf452000f
+#define R0900_P1_RTCS2 0xf452
+#define RTCS2 REGx(R0900_P1_RTCS2)
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
 
 /*P1_TMGTHRISE*/
-#define R0900_P1_TMGTHRISE  0xf453
-#define F0900_P1_TMGLOCK_THRISE  0xf45300ff
+#define R0900_P1_TMGTHRISE 0xf453
+#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
 
 /*P1_TMGTHFALL*/
-#define R0900_P1_TMGTHFALL  0xf454
-#define F0900_P1_TMGLOCK_THFALL  0xf45400ff
+#define R0900_P1_TMGTHFALL 0xf454
+#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
 
 /*P1_SFRUPRATIO*/
-#define R0900_P1_SFRUPRATIO  0xf455
-#define F0900_P1_SFR_UPRATIO  0xf45500ff
+#define R0900_P1_SFRUPRATIO 0xf455
+#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
 
 /*P1_SFRLOWRATIO*/
-#define R0900_P1_SFRLOWRATIO  0xf456
-#define F0900_P1_SFR_LOWRATIO  0xf45600ff
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
 
 /*P1_KREFTMG*/
-#define R0900_P1_KREFTMG  0xf458
-#define F0900_P1_KREF_TMG  0xf45800ff
+#define R0900_P1_KREFTMG 0xf458
+#define KREFTMG REGx(R0900_P1_KREFTMG)
+#define F0900_P1_KREF_TMG 0xf45800ff
 
 /*P1_SFRSTEP*/
-#define R0900_P1_SFRSTEP  0xf459
-#define F0900_P1_SFR_SCANSTEP  0xf45900f0
-#define F0900_P1_SFR_CENTERSTEP  0xf459000f
+#define R0900_P1_SFRSTEP 0xf459
+#define SFRSTEP REGx(R0900_P1_SFRSTEP)
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
 
 /*P1_TMGCFG2*/
-#define R0900_P1_TMGCFG2  0xf45a
-#define F0900_P1_DIS_AUTOSAMP  0xf45a0008
-#define F0900_P1_SCANINIT_QUART  0xf45a0004
-#define F0900_P1_NOTMG_DVBS1DERAT  0xf45a0002
-#define F0900_P1_SFRRATIO_FINE  0xf45a0001
+#define R0900_P1_TMGCFG2 0xf45a
+#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_KREFTMG2*/
+#define R0900_P1_KREFTMG2 0xf45b
+#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
+#define F0900_P1_KREF_TMG2 0xf45b00ff
 
 /*P1_SFRINIT1*/
-#define R0900_P1_SFRINIT1  0xf45e
-#define F0900_P1_SFR_INIT1  0xf45e00ff
+#define R0900_P1_SFRINIT1 0xf45e
+#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
+#define F0900_P1_SFR_INIT1 0xf45e007f
 
 /*P1_SFRINIT0*/
-#define R0900_P1_SFRINIT0  0xf45f
-#define F0900_P1_SFR_INIT0  0xf45f00ff
+#define R0900_P1_SFRINIT0 0xf45f
+#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
+#define F0900_P1_SFR_INIT0 0xf45f00ff
 
 /*P1_SFRUP1*/
-#define R0900_P1_SFRUP1  0xf460
-#define F0900_P1_AUTO_GUP  0xf4600080
-#define F0900_P1_SYMB_FREQ_UP1  0xf460007f
+#define R0900_P1_SFRUP1 0xf460
+#define SFRUP1 REGx(R0900_P1_SFRUP1)
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
 
 /*P1_SFRUP0*/
-#define R0900_P1_SFRUP0  0xf461
-#define F0900_P1_SYMB_FREQ_UP0  0xf46100ff
+#define R0900_P1_SFRUP0 0xf461
+#define SFRUP0 REGx(R0900_P1_SFRUP0)
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
 
 /*P1_SFRLOW1*/
-#define R0900_P1_SFRLOW1  0xf462
-#define F0900_P1_AUTO_GLOW  0xf4620080
-#define F0900_P1_SYMB_FREQ_LOW1  0xf462007f
+#define R0900_P1_SFRLOW1 0xf462
+#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
 
 /*P1_SFRLOW0*/
-#define R0900_P1_SFRLOW0  0xf463
-#define F0900_P1_SYMB_FREQ_LOW0  0xf46300ff
+#define R0900_P1_SFRLOW0 0xf463
+#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
 
 /*P1_SFR3*/
-#define R0900_P1_SFR3  0xf464
-#define F0900_P1_SYMB_FREQ3  0xf46400ff
+#define R0900_P1_SFR3 0xf464
+#define SFR3 REGx(R0900_P1_SFR3)
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
 
 /*P1_SFR2*/
-#define R0900_P1_SFR2  0xf465
-#define F0900_P1_SYMB_FREQ2  0xf46500ff
+#define R0900_P1_SFR2 0xf465
+#define SFR2 REGx(R0900_P1_SFR2)
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
 
 /*P1_SFR1*/
-#define R0900_P1_SFR1  0xf466
-#define F0900_P1_SYMB_FREQ1  0xf46600ff
+#define R0900_P1_SFR1 0xf466
+#define SFR1 REGx(R0900_P1_SFR1)
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
 
 /*P1_SFR0*/
-#define R0900_P1_SFR0  0xf467
-#define F0900_P1_SYMB_FREQ0  0xf46700ff
+#define R0900_P1_SFR0 0xf467
+#define SFR0 REGx(R0900_P1_SFR0)
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
 
 /*P1_TMGREG2*/
-#define R0900_P1_TMGREG2  0xf468
-#define F0900_P1_TMGREG2  0xf46800ff
+#define R0900_P1_TMGREG2 0xf468
+#define TMGREG2 REGx(R0900_P1_TMGREG2)
+#define F0900_P1_TMGREG2 0xf46800ff
 
 /*P1_TMGREG1*/
-#define R0900_P1_TMGREG1  0xf469
-#define F0900_P1_TMGREG1  0xf46900ff
+#define R0900_P1_TMGREG1 0xf469
+#define TMGREG1 REGx(R0900_P1_TMGREG1)
+#define F0900_P1_TMGREG1 0xf46900ff
 
 /*P1_TMGREG0*/
-#define R0900_P1_TMGREG0  0xf46a
-#define F0900_P1_TMGREG0  0xf46a00ff
+#define R0900_P1_TMGREG0 0xf46a
+#define TMGREG0 REGx(R0900_P1_TMGREG0)
+#define F0900_P1_TMGREG0 0xf46a00ff
 
 /*P1_TMGLOCK1*/
-#define R0900_P1_TMGLOCK1  0xf46b
-#define F0900_P1_TMGLOCK_LEVEL1  0xf46b01ff
+#define R0900_P1_TMGLOCK1 0xf46b
+#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
 
 /*P1_TMGLOCK0*/
-#define R0900_P1_TMGLOCK0  0xf46c
-#define F0900_P1_TMGLOCK_LEVEL0  0xf46c00ff
+#define R0900_P1_TMGLOCK0 0xf46c
+#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
 
 /*P1_TMGOBS*/
-#define R0900_P1_TMGOBS  0xf46d
-#define F0900_P1_ROLLOFF_STATUS  0xf46d00c0
-#define F0900_P1_SCAN_SIGN  0xf46d0030
-#define F0900_P1_TMG_SCANNING  0xf46d0008
-#define F0900_P1_CHCENTERING_MODE  0xf46d0004
-#define F0900_P1_TMG_SCANFAIL  0xf46d0002
+#define R0900_P1_TMGOBS 0xf46d
+#define TMGOBS REGx(R0900_P1_TMGOBS)
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
 
 /*P1_EQUALCFG*/
-#define R0900_P1_EQUALCFG  0xf46f
-#define F0900_P1_NOTMG_NEGALWAIT  0xf46f0080
-#define F0900_P1_EQUAL_ON  0xf46f0040
-#define F0900_P1_SEL_EQUALCOR  0xf46f0038
-#define F0900_P1_MU_EQUALDFE  0xf46f0007
+#define R0900_P1_EQUALCFG 0xf46f
+#define EQUALCFG REGx(R0900_P1_EQUALCFG)
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
 
 /*P1_EQUAI1*/
-#define R0900_P1_EQUAI1  0xf470
-#define F0900_P1_EQUA_ACCI1  0xf47001ff
+#define R0900_P1_EQUAI1 0xf470
+#define EQUAI1 REGx(R0900_P1_EQUAI1)
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
 
 /*P1_EQUAQ1*/
-#define R0900_P1_EQUAQ1  0xf471
-#define F0900_P1_EQUA_ACCQ1  0xf47101ff
+#define R0900_P1_EQUAQ1 0xf471
+#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
 
 /*P1_EQUAI2*/
-#define R0900_P1_EQUAI2  0xf472
-#define F0900_P1_EQUA_ACCI2  0xf47201ff
+#define R0900_P1_EQUAI2 0xf472
+#define EQUAI2 REGx(R0900_P1_EQUAI2)
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
 
 /*P1_EQUAQ2*/
-#define R0900_P1_EQUAQ2  0xf473
-#define F0900_P1_EQUA_ACCQ2  0xf47301ff
+#define R0900_P1_EQUAQ2 0xf473
+#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
 
 /*P1_EQUAI3*/
-#define R0900_P1_EQUAI3  0xf474
-#define F0900_P1_EQUA_ACCI3  0xf47401ff
+#define R0900_P1_EQUAI3 0xf474
+#define EQUAI3 REGx(R0900_P1_EQUAI3)
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
 
 /*P1_EQUAQ3*/
-#define R0900_P1_EQUAQ3  0xf475
-#define F0900_P1_EQUA_ACCQ3  0xf47501ff
+#define R0900_P1_EQUAQ3 0xf475
+#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
 
 /*P1_EQUAI4*/
-#define R0900_P1_EQUAI4  0xf476
-#define F0900_P1_EQUA_ACCI4  0xf47601ff
+#define R0900_P1_EQUAI4 0xf476
+#define EQUAI4 REGx(R0900_P1_EQUAI4)
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
 
 /*P1_EQUAQ4*/
-#define R0900_P1_EQUAQ4  0xf477
-#define F0900_P1_EQUA_ACCQ4  0xf47701ff
+#define R0900_P1_EQUAQ4 0xf477
+#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
 
 /*P1_EQUAI5*/
-#define R0900_P1_EQUAI5  0xf478
-#define F0900_P1_EQUA_ACCI5  0xf47801ff
+#define R0900_P1_EQUAI5 0xf478
+#define EQUAI5 REGx(R0900_P1_EQUAI5)
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
 
 /*P1_EQUAQ5*/
-#define R0900_P1_EQUAQ5  0xf479
-#define F0900_P1_EQUA_ACCQ5  0xf47901ff
+#define R0900_P1_EQUAQ5 0xf479
+#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
 
 /*P1_EQUAI6*/
-#define R0900_P1_EQUAI6  0xf47a
-#define F0900_P1_EQUA_ACCI6  0xf47a01ff
+#define R0900_P1_EQUAI6 0xf47a
+#define EQUAI6 REGx(R0900_P1_EQUAI6)
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
 
 /*P1_EQUAQ6*/
-#define R0900_P1_EQUAQ6  0xf47b
-#define F0900_P1_EQUA_ACCQ6  0xf47b01ff
+#define R0900_P1_EQUAQ6 0xf47b
+#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
 
 /*P1_EQUAI7*/
-#define R0900_P1_EQUAI7  0xf47c
-#define F0900_P1_EQUA_ACCI7  0xf47c01ff
+#define R0900_P1_EQUAI7 0xf47c
+#define EQUAI7 REGx(R0900_P1_EQUAI7)
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
 
 /*P1_EQUAQ7*/
-#define R0900_P1_EQUAQ7  0xf47d
-#define F0900_P1_EQUA_ACCQ7  0xf47d01ff
+#define R0900_P1_EQUAQ7 0xf47d
+#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
 
 /*P1_EQUAI8*/
-#define R0900_P1_EQUAI8  0xf47e
-#define F0900_P1_EQUA_ACCI8  0xf47e01ff
+#define R0900_P1_EQUAI8 0xf47e
+#define EQUAI8 REGx(R0900_P1_EQUAI8)
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
 
 /*P1_EQUAQ8*/
-#define R0900_P1_EQUAQ8  0xf47f
-#define F0900_P1_EQUA_ACCQ8  0xf47f01ff
+#define R0900_P1_EQUAQ8 0xf47f
+#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
 
 /*P1_NNOSDATAT1*/
-#define R0900_P1_NNOSDATAT1  0xf480
-#define F0900_P1_NOSDATAT_NORMED1  0xf48000ff
+#define R0900_P1_NNOSDATAT1 0xf480
+#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
 
 /*P1_NNOSDATAT0*/
-#define R0900_P1_NNOSDATAT0  0xf481
-#define F0900_P1_NOSDATAT_NORMED0  0xf48100ff
+#define R0900_P1_NNOSDATAT0 0xf481
+#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
 
 /*P1_NNOSDATA1*/
-#define R0900_P1_NNOSDATA1  0xf482
-#define F0900_P1_NOSDATA_NORMED1  0xf48200ff
+#define R0900_P1_NNOSDATA1 0xf482
+#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
 
 /*P1_NNOSDATA0*/
-#define R0900_P1_NNOSDATA0  0xf483
-#define F0900_P1_NOSDATA_NORMED0  0xf48300ff
+#define R0900_P1_NNOSDATA0 0xf483
+#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
 
 /*P1_NNOSPLHT1*/
-#define R0900_P1_NNOSPLHT1  0xf484
-#define F0900_P1_NOSPLHT_NORMED1  0xf48400ff
+#define R0900_P1_NNOSPLHT1 0xf484
+#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
 
 /*P1_NNOSPLHT0*/
-#define R0900_P1_NNOSPLHT0  0xf485
-#define F0900_P1_NOSPLHT_NORMED0  0xf48500ff
+#define R0900_P1_NNOSPLHT0 0xf485
+#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
 
 /*P1_NNOSPLH1*/
-#define R0900_P1_NNOSPLH1  0xf486
-#define F0900_P1_NOSPLH_NORMED1  0xf48600ff
+#define R0900_P1_NNOSPLH1 0xf486
+#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
 
 /*P1_NNOSPLH0*/
-#define R0900_P1_NNOSPLH0  0xf487
-#define F0900_P1_NOSPLH_NORMED0  0xf48700ff
+#define R0900_P1_NNOSPLH0 0xf487
+#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
 
 /*P1_NOSDATAT1*/
-#define R0900_P1_NOSDATAT1  0xf488
-#define F0900_P1_NOSDATAT_UNNORMED1  0xf48800ff
+#define R0900_P1_NOSDATAT1 0xf488
+#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
 
 /*P1_NOSDATAT0*/
-#define R0900_P1_NOSDATAT0  0xf489
-#define F0900_P1_NOSDATAT_UNNORMED0  0xf48900ff
+#define R0900_P1_NOSDATAT0 0xf489
+#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
 
 /*P1_NOSDATA1*/
-#define R0900_P1_NOSDATA1  0xf48a
-#define F0900_P1_NOSDATA_UNNORMED1  0xf48a00ff
+#define R0900_P1_NOSDATA1 0xf48a
+#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
 
 /*P1_NOSDATA0*/
-#define R0900_P1_NOSDATA0  0xf48b
-#define F0900_P1_NOSDATA_UNNORMED0  0xf48b00ff
+#define R0900_P1_NOSDATA0 0xf48b
+#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
 
 /*P1_NOSPLHT1*/
-#define R0900_P1_NOSPLHT1  0xf48c
-#define F0900_P1_NOSPLHT_UNNORMED1  0xf48c00ff
+#define R0900_P1_NOSPLHT1 0xf48c
+#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
 
 /*P1_NOSPLHT0*/
-#define R0900_P1_NOSPLHT0  0xf48d
-#define F0900_P1_NOSPLHT_UNNORMED0  0xf48d00ff
+#define R0900_P1_NOSPLHT0 0xf48d
+#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
 
 /*P1_NOSPLH1*/
-#define R0900_P1_NOSPLH1  0xf48e
-#define F0900_P1_NOSPLH_UNNORMED1  0xf48e00ff
+#define R0900_P1_NOSPLH1 0xf48e
+#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
 
 /*P1_NOSPLH0*/
-#define R0900_P1_NOSPLH0  0xf48f
-#define F0900_P1_NOSPLH_UNNORMED0  0xf48f00ff
+#define R0900_P1_NOSPLH0 0xf48f
+#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
 
 /*P1_CAR2CFG*/
-#define R0900_P1_CAR2CFG  0xf490
-#define F0900_P1_DESCRAMB_OFF  0xf4900080
-#define F0900_P1_PN4_SELECT  0xf4900040
-#define F0900_P1_CFR2_STOPDVBS1  0xf4900020
-#define F0900_P1_STOP_CFR2UPDATE  0xf4900010
-#define F0900_P1_STOP_NCO2UPDATE  0xf4900008
-#define F0900_P1_ROTA2ON  0xf4900004
-#define F0900_P1_PH_DET_ALGO2  0xf4900003
-
-/*P1_ACLC2*/
-#define R0900_P1_ACLC2  0xf491
-#define F0900_P1_CAR2_PUNCT_ADERAT  0xf4910040
-#define F0900_P1_CAR2_ALPHA_MANT  0xf4910030
-#define F0900_P1_CAR2_ALPHA_EXP  0xf491000f
+#define R0900_P1_CAR2CFG 0xf490
+#define CAR2CFG REGx(R0900_P1_CAR2CFG)
+#define F0900_P1_CARRIER3_DISABLE 0xf4900040
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
 
-/*P1_BCLC2*/
-#define R0900_P1_BCLC2  0xf492
-#define F0900_P1_DVBS2_NIP  0xf4920080
-#define F0900_P1_CAR2_PUNCT_BDERAT  0xf4920040
-#define F0900_P1_CAR2_BETA_MANT  0xf4920030
-#define F0900_P1_CAR2_BETA_EXP  0xf492000f
+/*P1_CFR2CFR1*/
+#define R0900_P1_CFR2CFR1 0xf491
+#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
+#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
+#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
+#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
+#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
 
 /*P1_CFR22*/
-#define R0900_P1_CFR22  0xf493
-#define F0900_P1_CAR2_FREQ2  0xf49301ff
+#define R0900_P1_CFR22 0xf493
+#define CFR22 REGx(R0900_P1_CFR22)
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
 
 /*P1_CFR21*/
-#define R0900_P1_CFR21  0xf494
-#define F0900_P1_CAR2_FREQ1  0xf49400ff
+#define R0900_P1_CFR21 0xf494
+#define CFR21 REGx(R0900_P1_CFR21)
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
 
 /*P1_CFR20*/
-#define R0900_P1_CFR20  0xf495
-#define F0900_P1_CAR2_FREQ0  0xf49500ff
+#define R0900_P1_CFR20 0xf495
+#define CFR20 REGx(R0900_P1_CFR20)
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
 
 /*P1_ACLC2S2Q*/
-#define R0900_P1_ACLC2S2Q  0xf497
-#define F0900_P1_ENAB_SPSKSYMB  0xf4970080
-#define F0900_P1_CAR2S2_QADERAT  0xf4970040
-#define F0900_P1_CAR2S2_Q_ALPH_M  0xf4970030
-#define F0900_P1_CAR2S2_Q_ALPH_E  0xf497000f
+#define R0900_P1_ACLC2S2Q 0xf497
+#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
 
 /*P1_ACLC2S28*/
-#define R0900_P1_ACLC2S28  0xf498
-#define F0900_P1_OLDI3Q_MODE  0xf4980080
-#define F0900_P1_CAR2S2_8ADERAT  0xf4980040
-#define F0900_P1_CAR2S2_8_ALPH_M  0xf4980030
-#define F0900_P1_CAR2S2_8_ALPH_E  0xf498000f
+#define R0900_P1_ACLC2S28 0xf498
+#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
 
 /*P1_ACLC2S216A*/
-#define R0900_P1_ACLC2S216A  0xf499
-#define F0900_P1_CAR2S2_16ADERAT  0xf4990040
-#define F0900_P1_CAR2S2_16A_ALPH_M  0xf4990030
-#define F0900_P1_CAR2S2_16A_ALPH_E  0xf499000f
+#define R0900_P1_ACLC2S216A 0xf499
+#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
+#define F0900_P1_DIS_C3STOPA2 0xf4990080
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
 
 /*P1_ACLC2S232A*/
-#define R0900_P1_ACLC2S232A  0xf49a
-#define F0900_P1_CAR2S2_32ADERAT  0xf49a0040
-#define F0900_P1_CAR2S2_32A_ALPH_M  0xf49a0030
-#define F0900_P1_CAR2S2_32A_ALPH_E  0xf49a000f
+#define R0900_P1_ACLC2S232A 0xf49a
+#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
 
 /*P1_BCLC2S2Q*/
-#define R0900_P1_BCLC2S2Q  0xf49c
-#define F0900_P1_DVBS2S2Q_NIP  0xf49c0080
-#define F0900_P1_CAR2S2_QBDERAT  0xf49c0040
-#define F0900_P1_CAR2S2_Q_BETA_M  0xf49c0030
-#define F0900_P1_CAR2S2_Q_BETA_E  0xf49c000f
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
 
 /*P1_BCLC2S28*/
-#define R0900_P1_BCLC2S28  0xf49d
-#define F0900_P1_DVBS2S28_NIP  0xf49d0080
-#define F0900_P1_CAR2S2_8BDERAT  0xf49d0040
-#define F0900_P1_CAR2S2_8_BETA_M  0xf49d0030
-#define F0900_P1_CAR2S2_8_BETA_E  0xf49d000f
+#define R0900_P1_BCLC2S28 0xf49d
+#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
 
 /*P1_BCLC2S216A*/
-#define R0900_P1_BCLC2S216A  0xf49e
-#define F0900_P1_DVBS2S216A_NIP  0xf49e0080
-#define F0900_P1_CAR2S2_16BDERAT  0xf49e0040
-#define F0900_P1_CAR2S2_16A_BETA_M  0xf49e0030
-#define F0900_P1_CAR2S2_16A_BETA_E  0xf49e000f
+#define R0900_P1_BCLC2S216A 0xf49e
+#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
 
 /*P1_BCLC2S232A*/
-#define R0900_P1_BCLC2S232A  0xf49f
-#define F0900_P1_DVBS2S232A_NIP  0xf49f0080
-#define F0900_P1_CAR2S2_32BDERAT  0xf49f0040
-#define F0900_P1_CAR2S2_32A_BETA_M  0xf49f0030
-#define F0900_P1_CAR2S2_32A_BETA_E  0xf49f000f
+#define R0900_P1_BCLC2S232A 0xf49f
+#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
 
 /*P1_PLROOT2*/
-#define R0900_P1_PLROOT2  0xf4ac
-#define F0900_P1_SHORTFR_DISABLE  0xf4ac0080
-#define F0900_P1_LONGFR_DISABLE  0xf4ac0040
-#define F0900_P1_DUMMYPL_DISABLE  0xf4ac0020
-#define F0900_P1_SHORTFR_AVOID  0xf4ac0010
-#define F0900_P1_PLSCRAMB_MODE  0xf4ac000c
-#define F0900_P1_PLSCRAMB_ROOT2  0xf4ac0003
+#define R0900_P1_PLROOT2 0xf4ac
+#define PLROOT2 REGx(R0900_P1_PLROOT2)
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
 
 /*P1_PLROOT1*/
-#define R0900_P1_PLROOT1  0xf4ad
-#define F0900_P1_PLSCRAMB_ROOT1  0xf4ad00ff
+#define R0900_P1_PLROOT1 0xf4ad
+#define PLROOT1 REGx(R0900_P1_PLROOT1)
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
 
 /*P1_PLROOT0*/
-#define R0900_P1_PLROOT0  0xf4ae
-#define F0900_P1_PLSCRAMB_ROOT0  0xf4ae00ff
+#define R0900_P1_PLROOT0 0xf4ae
+#define PLROOT0 REGx(R0900_P1_PLROOT0)
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
 
 /*P1_MODCODLST0*/
-#define R0900_P1_MODCODLST0  0xf4b0
-#define F0900_P1_EN_TOKEN31  0xf4b00080
-#define F0900_P1_SYNCTAG_SELECT  0xf4b00040
-#define F0900_P1_MODCODRQ_MODE  0xf4b00030
+#define R0900_P1_MODCODLST0 0xf4b0
+#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
 
 /*P1_MODCODLST1*/
-#define R0900_P1_MODCODLST1  0xf4b1
-#define F0900_P1_DIS_MODCOD29  0xf4b100f0
-#define F0900_P1_DIS_32PSK_9_10  0xf4b1000f
+#define R0900_P1_MODCODLST1 0xf4b1
+#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
 
 /*P1_MODCODLST2*/
-#define R0900_P1_MODCODLST2  0xf4b2
-#define F0900_P1_DIS_32PSK_8_9  0xf4b200f0
-#define F0900_P1_DIS_32PSK_5_6  0xf4b2000f
+#define R0900_P1_MODCODLST2 0xf4b2
+#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
 
 /*P1_MODCODLST3*/
-#define R0900_P1_MODCODLST3  0xf4b3
-#define F0900_P1_DIS_32PSK_4_5  0xf4b300f0
-#define F0900_P1_DIS_32PSK_3_4  0xf4b3000f
+#define R0900_P1_MODCODLST3 0xf4b3
+#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
 
 /*P1_MODCODLST4*/
-#define R0900_P1_MODCODLST4  0xf4b4
-#define F0900_P1_DIS_16PSK_9_10  0xf4b400f0
-#define F0900_P1_DIS_16PSK_8_9  0xf4b4000f
+#define R0900_P1_MODCODLST4 0xf4b4
+#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
 
 /*P1_MODCODLST5*/
-#define R0900_P1_MODCODLST5  0xf4b5
-#define F0900_P1_DIS_16PSK_5_6  0xf4b500f0
-#define F0900_P1_DIS_16PSK_4_5  0xf4b5000f
+#define R0900_P1_MODCODLST5 0xf4b5
+#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
 
 /*P1_MODCODLST6*/
-#define R0900_P1_MODCODLST6  0xf4b6
-#define F0900_P1_DIS_16PSK_3_4  0xf4b600f0
-#define F0900_P1_DIS_16PSK_2_3  0xf4b6000f
+#define R0900_P1_MODCODLST6 0xf4b6
+#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
 
 /*P1_MODCODLST7*/
-#define R0900_P1_MODCODLST7  0xf4b7
-#define F0900_P1_DIS_8P_9_10  0xf4b700f0
-#define F0900_P1_DIS_8P_8_9  0xf4b7000f
+#define R0900_P1_MODCODLST7 0xf4b7
+#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
 
 /*P1_MODCODLST8*/
-#define R0900_P1_MODCODLST8  0xf4b8
-#define F0900_P1_DIS_8P_5_6  0xf4b800f0
-#define F0900_P1_DIS_8P_3_4  0xf4b8000f
+#define R0900_P1_MODCODLST8 0xf4b8
+#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
 
 /*P1_MODCODLST9*/
-#define R0900_P1_MODCODLST9  0xf4b9
-#define F0900_P1_DIS_8P_2_3  0xf4b900f0
-#define F0900_P1_DIS_8P_3_5  0xf4b9000f
+#define R0900_P1_MODCODLST9 0xf4b9
+#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
 
 /*P1_MODCODLSTA*/
-#define R0900_P1_MODCODLSTA  0xf4ba
-#define F0900_P1_DIS_QP_9_10  0xf4ba00f0
-#define F0900_P1_DIS_QP_8_9  0xf4ba000f
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
 
 /*P1_MODCODLSTB*/
-#define R0900_P1_MODCODLSTB  0xf4bb
-#define F0900_P1_DIS_QP_5_6  0xf4bb00f0
-#define F0900_P1_DIS_QP_4_5  0xf4bb000f
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
 
 /*P1_MODCODLSTC*/
-#define R0900_P1_MODCODLSTC  0xf4bc
-#define F0900_P1_DIS_QP_3_4  0xf4bc00f0
-#define F0900_P1_DIS_QP_2_3  0xf4bc000f
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
 
 /*P1_MODCODLSTD*/
-#define R0900_P1_MODCODLSTD  0xf4bd
-#define F0900_P1_DIS_QP_3_5  0xf4bd00f0
-#define F0900_P1_DIS_QP_1_2  0xf4bd000f
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
 
 /*P1_MODCODLSTE*/
-#define R0900_P1_MODCODLSTE  0xf4be
-#define F0900_P1_DIS_QP_2_5  0xf4be00f0
-#define F0900_P1_DIS_QP_1_3  0xf4be000f
+#define R0900_P1_MODCODLSTE 0xf4be
+#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
 
 /*P1_MODCODLSTF*/
-#define R0900_P1_MODCODLSTF  0xf4bf
-#define F0900_P1_DIS_QP_1_4  0xf4bf00f0
-#define F0900_P1_DDEMOD_SET  0xf4bf0002
-#define F0900_P1_DDEMOD_MASK  0xf4bf0001
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+
+/*P1_GAUSSR0*/
+#define R0900_P1_GAUSSR0 0xf4c0
+#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
+#define F0900_P1_EN_CCIMODE 0xf4c00080
+#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
+
+/*P1_CCIR0*/
+#define R0900_P1_CCIR0 0xf4c1
+#define CCIR0 REGx(R0900_P1_CCIR0)
+#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
+#define F0900_P1_R0_CCI 0xf4c1007f
+
+/*P1_CCIQUANT*/
+#define R0900_P1_CCIQUANT 0xf4c2
+#define CCIQUANT REGx(R0900_P1_CCIQUANT)
+#define F0900_P1_CCI_BETA 0xf4c200e0
+#define F0900_P1_CCI_QUANT 0xf4c2001f
+
+/*P1_CCITHRES*/
+#define R0900_P1_CCITHRES 0xf4c3
+#define CCITHRES REGx(R0900_P1_CCITHRES)
+#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
+
+/*P1_CCIACC*/
+#define R0900_P1_CCIACC 0xf4c4
+#define CCIACC REGx(R0900_P1_CCIACC)
+#define F0900_P1_CCI_VALUE 0xf4c400ff
 
 /*P1_DMDRESCFG*/
-#define R0900_P1_DMDRESCFG  0xf4c6
-#define F0900_P1_DMDRES_RESET  0xf4c60080
-#define F0900_P1_DMDRES_NOISESQR  0xf4c60010
-#define F0900_P1_DMDRES_STRALL  0xf4c60008
-#define F0900_P1_DMDRES_NEWONLY  0xf4c60004
-#define F0900_P1_DMDRES_NOSTORE  0xf4c60002
-#define F0900_P1_DMDRES_AGC2MEM  0xf4c60001
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
 
 /*P1_DMDRESADR*/
-#define R0900_P1_DMDRESADR  0xf4c7
-#define F0900_P1_SUSP_PREDCANAL  0xf4c70080
-#define F0900_P1_DMDRES_VALIDCFR  0xf4c70040
-#define F0900_P1_DMDRES_MEMFULL  0xf4c70030
-#define F0900_P1_DMDRES_RESNBR  0xf4c7000f
+#define R0900_P1_DMDRESADR 0xf4c7
+#define DMDRESADR REGx(R0900_P1_DMDRESADR)
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
 
 /*P1_DMDRESDATA7*/
-#define R0900_P1_DMDRESDATA7  0xf4c8
-#define F0900_P1_DMDRES_DATA7  0xf4c800ff
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
 
 /*P1_DMDRESDATA6*/
-#define R0900_P1_DMDRESDATA6  0xf4c9
-#define F0900_P1_DMDRES_DATA6  0xf4c900ff
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
 
 /*P1_DMDRESDATA5*/
-#define R0900_P1_DMDRESDATA5  0xf4ca
-#define F0900_P1_DMDRES_DATA5  0xf4ca00ff
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
 
 /*P1_DMDRESDATA4*/
-#define R0900_P1_DMDRESDATA4  0xf4cb
-#define F0900_P1_DMDRES_DATA4  0xf4cb00ff
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
 
 /*P1_DMDRESDATA3*/
-#define R0900_P1_DMDRESDATA3  0xf4cc
-#define F0900_P1_DMDRES_DATA3  0xf4cc00ff
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
 
 /*P1_DMDRESDATA2*/
-#define R0900_P1_DMDRESDATA2  0xf4cd
-#define F0900_P1_DMDRES_DATA2  0xf4cd00ff
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
 
 /*P1_DMDRESDATA1*/
-#define R0900_P1_DMDRESDATA1  0xf4ce
-#define F0900_P1_DMDRES_DATA1  0xf4ce00ff
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
 
 /*P1_DMDRESDATA0*/
-#define R0900_P1_DMDRESDATA0  0xf4cf
-#define F0900_P1_DMDRES_DATA0  0xf4cf00ff
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
 
 /*P1_FFEI1*/
-#define R0900_P1_FFEI1  0xf4d0
-#define F0900_P1_FFE_ACCI1  0xf4d001ff
+#define R0900_P1_FFEI1 0xf4d0
+#define FFEI1 REGx(R0900_P1_FFEI1)
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
 
 /*P1_FFEQ1*/
-#define R0900_P1_FFEQ1  0xf4d1
-#define F0900_P1_FFE_ACCQ1  0xf4d101ff
+#define R0900_P1_FFEQ1 0xf4d1
+#define FFEQ1 REGx(R0900_P1_FFEQ1)
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
 
 /*P1_FFEI2*/
-#define R0900_P1_FFEI2  0xf4d2
-#define F0900_P1_FFE_ACCI2  0xf4d201ff
+#define R0900_P1_FFEI2 0xf4d2
+#define FFEI2 REGx(R0900_P1_FFEI2)
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
 
 /*P1_FFEQ2*/
-#define R0900_P1_FFEQ2  0xf4d3
-#define F0900_P1_FFE_ACCQ2  0xf4d301ff
+#define R0900_P1_FFEQ2 0xf4d3
+#define FFEQ2 REGx(R0900_P1_FFEQ2)
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
 
 /*P1_FFEI3*/
-#define R0900_P1_FFEI3  0xf4d4
-#define F0900_P1_FFE_ACCI3  0xf4d401ff
+#define R0900_P1_FFEI3 0xf4d4
+#define FFEI3 REGx(R0900_P1_FFEI3)
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
 
 /*P1_FFEQ3*/
-#define R0900_P1_FFEQ3  0xf4d5
-#define F0900_P1_FFE_ACCQ3  0xf4d501ff
+#define R0900_P1_FFEQ3 0xf4d5
+#define FFEQ3 REGx(R0900_P1_FFEQ3)
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
 
 /*P1_FFEI4*/
-#define R0900_P1_FFEI4  0xf4d6
-#define F0900_P1_FFE_ACCI4  0xf4d601ff
+#define R0900_P1_FFEI4 0xf4d6
+#define FFEI4 REGx(R0900_P1_FFEI4)
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
 
 /*P1_FFEQ4*/
-#define R0900_P1_FFEQ4  0xf4d7
-#define F0900_P1_FFE_ACCQ4  0xf4d701ff
+#define R0900_P1_FFEQ4 0xf4d7
+#define FFEQ4 REGx(R0900_P1_FFEQ4)
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
 
 /*P1_FFECFG*/
-#define R0900_P1_FFECFG  0xf4d8
-#define F0900_P1_EQUALFFE_ON  0xf4d80040
-#define F0900_P1_EQUAL_USEDSYMB  0xf4d80030
-#define F0900_P1_MU_EQUALFFE  0xf4d80007
+#define R0900_P1_FFECFG 0xf4d8
+#define FFECFG REGx(R0900_P1_FFECFG)
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
 
 /*P1_TNRCFG*/
-#define R0900_P1_TNRCFG  0xf4e0
-#define F0900_P1_TUN_ACKFAIL  0xf4e00080
-#define F0900_P1_TUN_TYPE  0xf4e00070
-#define F0900_P1_TUN_SECSTOP  0xf4e00008
-#define F0900_P1_TUN_VCOSRCH  0xf4e00004
-#define F0900_P1_TUN_MADDRESS  0xf4e00003
+#define R0900_P1_TNRCFG 0xf4e0
+#define TNRCFG REGx(R0900_P1_TNRCFG)
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
 
 /*P1_TNRCFG2*/
-#define R0900_P1_TNRCFG2  0xf4e1
-#define F0900_P1_TUN_IQSWAP  0xf4e10080
-#define F0900_P1_STB6110_STEP2MHZ  0xf4e10040
-#define F0900_P1_STB6120_DBLI2C  0xf4e10020
-#define F0900_P1_DIS_FCCK  0xf4e10010
-#define F0900_P1_DIS_LPEN  0xf4e10008
-#define F0900_P1_DIS_BWCALC  0xf4e10004
-#define F0900_P1_SHORT_WAITSTATES  0xf4e10002
-#define F0900_P1_DIS_2BWAGC1  0xf4e10001
+#define R0900_P1_TNRCFG2 0xf4e1
+#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
 
 /*P1_TNRXTAL*/
-#define R0900_P1_TNRXTAL  0xf4e4
-#define F0900_P1_TUN_MCLKDECIMAL  0xf4e400e0
-#define F0900_P1_TUN_XTALFREQ  0xf4e4001f
+#define R0900_P1_TNRXTAL 0xf4e4
+#define TNRXTAL REGx(R0900_P1_TNRXTAL)
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
 
 /*P1_TNRSTEPS*/
-#define R0900_P1_TNRSTEPS  0xf4e7
-#define F0900_P1_TUNER_BW1P6  0xf4e70080
-#define F0900_P1_BWINC_OFFSET  0xf4e70070
-#define F0900_P1_SOFTSTEP_RNG  0xf4e70008
-#define F0900_P1_TUN_BWOFFSET  0xf4e70107
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
+#define F0900_P1_TUNER_BW0P125 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70170
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70007
 
 /*P1_TNRGAIN*/
-#define R0900_P1_TNRGAIN  0xf4e8
-#define F0900_P1_TUN_KDIVEN  0xf4e800c0
-#define F0900_P1_STB6X00_OCK  0xf4e80030
-#define F0900_P1_TUN_GAIN  0xf4e8000f
+#define R0900_P1_TNRGAIN 0xf4e8
+#define TNRGAIN REGx(R0900_P1_TNRGAIN)
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
 
 /*P1_TNRRF1*/
-#define R0900_P1_TNRRF1  0xf4e9
-#define F0900_P1_TUN_RFFREQ2  0xf4e900ff
+#define R0900_P1_TNRRF1 0xf4e9
+#define TNRRF1 REGx(R0900_P1_TNRRF1)
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
 
 /*P1_TNRRF0*/
-#define R0900_P1_TNRRF0  0xf4ea
-#define F0900_P1_TUN_RFFREQ1  0xf4ea00ff
+#define R0900_P1_TNRRF0 0xf4ea
+#define TNRRF0 REGx(R0900_P1_TNRRF0)
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
 
 /*P1_TNRBW*/
-#define R0900_P1_TNRBW  0xf4eb
-#define F0900_P1_TUN_RFFREQ0  0xf4eb00c0
-#define F0900_P1_TUN_BW  0xf4eb003f
+#define R0900_P1_TNRBW 0xf4eb
+#define TNRBW REGx(R0900_P1_TNRBW)
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define F0900_P1_TUN_BW 0xf4eb003f
 
 /*P1_TNRADJ*/
-#define R0900_P1_TNRADJ  0xf4ec
-#define F0900_P1_STB61X0_RCLK  0xf4ec0080
-#define F0900_P1_STB61X0_CALTIME  0xf4ec0040
-#define F0900_P1_STB6X00_DLB  0xf4ec0038
-#define F0900_P1_STB6000_FCL  0xf4ec0007
+#define R0900_P1_TNRADJ 0xf4ec
+#define TNRADJ REGx(R0900_P1_TNRADJ)
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
 
 /*P1_TNRCTL2*/
-#define R0900_P1_TNRCTL2  0xf4ed
-#define F0900_P1_STB61X0_LCP1_RCCKOFF  0xf4ed0080
-#define F0900_P1_STB61X0_LCP0  0xf4ed0040
-#define F0900_P1_STB61X0_XTOUT_RFOUTS  0xf4ed0020
-#define F0900_P1_STB61X0_XTON_MCKDV  0xf4ed0010
-#define F0900_P1_STB61X0_CALOFF_DCOFF  0xf4ed0008
-#define F0900_P1_STB6110_LPT  0xf4ed0004
-#define F0900_P1_STB6110_RX  0xf4ed0002
-#define F0900_P1_STB6110_SYN  0xf4ed0001
+#define R0900_P1_TNRCTL2 0xf4ed
+#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
+#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
+#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
+#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
+#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
+#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
+#define F0900_P1_STB6XX0_SYN 0xf4ed0001
 
 /*P1_TNRCFG3*/
-#define R0900_P1_TNRCFG3  0xf4ee
-#define F0900_P1_STB6120_DISCTRL1  0xf4ee0080
-#define F0900_P1_STB6120_INVORDER  0xf4ee0040
-#define F0900_P1_STB6120_ENCTRL6  0xf4ee0020
-#define F0900_P1_TUN_PLLFREQ  0xf4ee001c
-#define F0900_P1_TUN_I2CFREQ_MODE  0xf4ee0003
+#define R0900_P1_TNRCFG3 0xf4ee
+#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
 
 /*P1_TNRLAUNCH*/
-#define R0900_P1_TNRLAUNCH  0xf4f0
+#define R0900_P1_TNRLAUNCH 0xf4f0
+#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
 
 /*P1_TNRLD*/
-#define R0900_P1_TNRLD  0xf4f0
-#define F0900_P1_TUNLD_VCOING  0xf4f00080
-#define F0900_P1_TUN_REG1FAIL  0xf4f00040
-#define F0900_P1_TUN_REG2FAIL  0xf4f00020
-#define F0900_P1_TUN_REG3FAIL  0xf4f00010
-#define F0900_P1_TUN_REG4FAIL  0xf4f00008
-#define F0900_P1_TUN_REG5FAIL  0xf4f00004
-#define F0900_P1_TUN_BWING  0xf4f00002
-#define F0900_P1_TUN_LOCKED  0xf4f00001
+#define R0900_P1_TNRLD 0xf4f0
+#define TNRLD REGx(R0900_P1_TNRLD)
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
 
 /*P1_TNROBSL*/
-#define R0900_P1_TNROBSL  0xf4f6
-#define F0900_P1_TUN_I2CABORTED  0xf4f60080
-#define F0900_P1_TUN_LPEN  0xf4f60040
-#define F0900_P1_TUN_FCCK  0xf4f60020
-#define F0900_P1_TUN_I2CLOCKED  0xf4f60010
-#define F0900_P1_TUN_PROGDONE  0xf4f6000c
-#define F0900_P1_TUN_RFRESTE1  0xf4f60003
+#define R0900_P1_TNROBSL 0xf4f6
+#define TNROBSL REGx(R0900_P1_TNROBSL)
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
 
 /*P1_TNRRESTE*/
-#define R0900_P1_TNRRESTE  0xf4f7
-#define F0900_P1_TUN_RFRESTE0  0xf4f700ff
+#define R0900_P1_TNRRESTE 0xf4f7
+#define TNRRESTE REGx(R0900_P1_TNRRESTE)
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
 
 /*P1_SMAPCOEF7*/
-#define R0900_P1_SMAPCOEF7  0xf500
-#define F0900_P1_DIS_QSCALE  0xf5000080
-#define F0900_P1_SMAPCOEF_Q_LLR12  0xf500017f
+#define R0900_P1_SMAPCOEF7 0xf500
+#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
 
 /*P1_SMAPCOEF6*/
-#define R0900_P1_SMAPCOEF6  0xf501
-#define F0900_P1_DIS_NEWSCALE  0xf5010008
-#define F0900_P1_ADJ_8PSKLLR1  0xf5010004
-#define F0900_P1_OLD_8PSKLLR1  0xf5010002
-#define F0900_P1_DIS_AB8PSK  0xf5010001
+#define R0900_P1_SMAPCOEF6 0xf501
+#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
 
 /*P1_SMAPCOEF5*/
-#define R0900_P1_SMAPCOEF5  0xf502
-#define F0900_P1_DIS_8SCALE  0xf5020080
-#define F0900_P1_SMAPCOEF_8P_LLR23  0xf502017f
+#define R0900_P1_SMAPCOEF5 0xf502
+#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_NCO2MAX1*/
+#define R0900_P1_NCO2MAX1 0xf514
+#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
+#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
+
+/*P1_NCO2MAX0*/
+#define R0900_P1_NCO2MAX0 0xf515
+#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
+#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
+
+/*P1_NCO2FR1*/
+#define R0900_P1_NCO2FR1 0xf516
+#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
+#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
+
+/*P1_NCO2FR0*/
+#define R0900_P1_NCO2FR0 0xf517
+#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
+#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
+
+/*P1_CFR2AVRGE1*/
+#define R0900_P1_CFR2AVRGE1 0xf518
+#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
+#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
+
+/*P1_CFR2AVRGE0*/
+#define R0900_P1_CFR2AVRGE0 0xf519
+#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
+#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
 
 /*P1_DMDPLHSTAT*/
-#define R0900_P1_DMDPLHSTAT  0xf520
-#define F0900_P1_PLH_STATISTIC  0xf52000ff
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
 
 /*P1_LOCKTIME3*/
-#define R0900_P1_LOCKTIME3  0xf522
-#define F0900_P1_DEMOD_LOCKTIME3  0xf52200ff
+#define R0900_P1_LOCKTIME3 0xf522
+#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
 
 /*P1_LOCKTIME2*/
-#define R0900_P1_LOCKTIME2  0xf523
-#define F0900_P1_DEMOD_LOCKTIME2  0xf52300ff
+#define R0900_P1_LOCKTIME2 0xf523
+#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
 
 /*P1_LOCKTIME1*/
-#define R0900_P1_LOCKTIME1  0xf524
-#define F0900_P1_DEMOD_LOCKTIME1  0xf52400ff
+#define R0900_P1_LOCKTIME1 0xf524
+#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
 
 /*P1_LOCKTIME0*/
-#define R0900_P1_LOCKTIME0  0xf525
-#define F0900_P1_DEMOD_LOCKTIME0  0xf52500ff
+#define R0900_P1_LOCKTIME0 0xf525
+#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
 
 /*P1_VITSCALE*/
-#define R0900_P1_VITSCALE  0xf532
-#define F0900_P1_NVTH_NOSRANGE  0xf5320080
-#define F0900_P1_VERROR_MAXMODE  0xf5320040
-#define F0900_P1_KDIV_MODE  0xf5320030
-#define F0900_P1_NSLOWSN_LOCKED  0xf5320008
-#define F0900_P1_DELOCK_PRFLOSS  0xf5320004
-#define F0900_P1_DIS_RSFLOCK  0xf5320002
+#define R0900_P1_VITSCALE 0xf532
+#define VITSCALE REGx(R0900_P1_VITSCALE)
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
 
 /*P1_FECM*/
-#define R0900_P1_FECM  0xf533
-#define F0900_P1_DSS_DVB  0xf5330080
-#define F0900_P1_DEMOD_BYPASS  0xf5330040
-#define F0900_P1_CMP_SLOWMODE  0xf5330020
-#define F0900_P1_DSS_SRCH  0xf5330010
-#define F0900_P1_DIFF_MODEVIT  0xf5330004
-#define F0900_P1_SYNCVIT  0xf5330002
-#define F0900_P1_IQINV  0xf5330001
+#define R0900_P1_FECM 0xf533
+#define FECM REGx(R0900_P1_FECM)
+#define F0900_P1_DSS_DVB 0xf5330080
+#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+#define IQINV FLDx(F0900_P1_IQINV)
 
 /*P1_VTH12*/
-#define R0900_P1_VTH12  0xf534
-#define F0900_P1_VTH12  0xf53400ff
+#define R0900_P1_VTH12 0xf534
+#define VTH12 REGx(R0900_P1_VTH12)
+#define F0900_P1_VTH12 0xf53400ff
 
 /*P1_VTH23*/
-#define R0900_P1_VTH23  0xf535
-#define F0900_P1_VTH23  0xf53500ff
+#define R0900_P1_VTH23 0xf535
+#define VTH23 REGx(R0900_P1_VTH23)
+#define F0900_P1_VTH23 0xf53500ff
 
 /*P1_VTH34*/
-#define R0900_P1_VTH34  0xf536
-#define F0900_P1_VTH34  0xf53600ff
+#define R0900_P1_VTH34 0xf536
+#define VTH34 REGx(R0900_P1_VTH34)
+#define F0900_P1_VTH34 0xf53600ff
 
 /*P1_VTH56*/
-#define R0900_P1_VTH56  0xf537
-#define F0900_P1_VTH56  0xf53700ff
+#define R0900_P1_VTH56 0xf537
+#define VTH56 REGx(R0900_P1_VTH56)
+#define F0900_P1_VTH56 0xf53700ff
 
 /*P1_VTH67*/
-#define R0900_P1_VTH67  0xf538
-#define F0900_P1_VTH67  0xf53800ff
+#define R0900_P1_VTH67 0xf538
+#define VTH67 REGx(R0900_P1_VTH67)
+#define F0900_P1_VTH67 0xf53800ff
 
 /*P1_VTH78*/
-#define R0900_P1_VTH78  0xf539
-#define F0900_P1_VTH78  0xf53900ff
+#define R0900_P1_VTH78 0xf539
+#define VTH78 REGx(R0900_P1_VTH78)
+#define F0900_P1_VTH78 0xf53900ff
 
 /*P1_VITCURPUN*/
-#define R0900_P1_VITCURPUN  0xf53a
-#define F0900_P1_VIT_MAPPING  0xf53a00e0
-#define F0900_P1_VIT_CURPUN  0xf53a001f
+#define R0900_P1_VITCURPUN 0xf53a
+#define VITCURPUN REGx(R0900_P1_VITCURPUN)
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
 
 /*P1_VERROR*/
-#define R0900_P1_VERROR  0xf53b
-#define F0900_P1_REGERR_VIT  0xf53b00ff
+#define R0900_P1_VERROR 0xf53b
+#define VERROR REGx(R0900_P1_VERROR)
+#define F0900_P1_REGERR_VIT 0xf53b00ff
 
 /*P1_PRVIT*/
-#define R0900_P1_PRVIT  0xf53c
-#define F0900_P1_DIS_VTHLOCK  0xf53c0040
-#define F0900_P1_E7_8VIT  0xf53c0020
-#define F0900_P1_E6_7VIT  0xf53c0010
-#define F0900_P1_E5_6VIT  0xf53c0008
-#define F0900_P1_E3_4VIT  0xf53c0004
-#define F0900_P1_E2_3VIT  0xf53c0002
-#define F0900_P1_E1_2VIT  0xf53c0001
+#define R0900_P1_PRVIT 0xf53c
+#define PRVIT REGx(R0900_P1_PRVIT)
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
 
 /*P1_VAVSRVIT*/
-#define R0900_P1_VAVSRVIT  0xf53d
-#define F0900_P1_AMVIT  0xf53d0080
-#define F0900_P1_FROZENVIT  0xf53d0040
-#define F0900_P1_SNVIT  0xf53d0030
-#define F0900_P1_TOVVIT  0xf53d000c
-#define F0900_P1_HYPVIT  0xf53d0003
+#define R0900_P1_VAVSRVIT 0xf53d
+#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
 
 /*P1_VSTATUSVIT*/
-#define R0900_P1_VSTATUSVIT  0xf53e
-#define F0900_P1_VITERBI_ON  0xf53e0080
-#define F0900_P1_END_LOOPVIT  0xf53e0040
-#define F0900_P1_VITERBI_DEPRF  0xf53e0020
-#define F0900_P1_PRFVIT  0xf53e0010
-#define F0900_P1_LOCKEDVIT  0xf53e0008
-#define F0900_P1_VITERBI_DELOCK  0xf53e0004
-#define F0900_P1_VIT_DEMODSEL  0xf53e0002
-#define F0900_P1_VITERBI_COMPOUT  0xf53e0001
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
+#define F0900_P1_PRFVIT 0xf53e0010
+#define PRFVIT FLDx(F0900_P1_PRFVIT)
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
 
 /*P1_VTHINUSE*/
-#define R0900_P1_VTHINUSE  0xf53f
-#define F0900_P1_VIT_INUSE  0xf53f00ff
+#define R0900_P1_VTHINUSE 0xf53f
+#define VTHINUSE REGx(R0900_P1_VTHINUSE)
+#define F0900_P1_VIT_INUSE 0xf53f00ff
 
 /*P1_KDIV12*/
-#define R0900_P1_KDIV12  0xf540
-#define F0900_P1_KDIV12_MANUAL  0xf5400080
-#define F0900_P1_K_DIVIDER_12  0xf540007f
+#define R0900_P1_KDIV12 0xf540
+#define KDIV12 REGx(R0900_P1_KDIV12)
+#define F0900_P1_K_DIVIDER_12 0xf540007f
 
 /*P1_KDIV23*/
-#define R0900_P1_KDIV23  0xf541
-#define F0900_P1_KDIV23_MANUAL  0xf5410080
-#define F0900_P1_K_DIVIDER_23  0xf541007f
+#define R0900_P1_KDIV23 0xf541
+#define KDIV23 REGx(R0900_P1_KDIV23)
+#define F0900_P1_K_DIVIDER_23 0xf541007f
 
 /*P1_KDIV34*/
-#define R0900_P1_KDIV34  0xf542
-#define F0900_P1_KDIV34_MANUAL  0xf5420080
-#define F0900_P1_K_DIVIDER_34  0xf542007f
+#define R0900_P1_KDIV34 0xf542
+#define KDIV34 REGx(R0900_P1_KDIV34)
+#define F0900_P1_K_DIVIDER_34 0xf542007f
 
 /*P1_KDIV56*/
-#define R0900_P1_KDIV56  0xf543
-#define F0900_P1_KDIV56_MANUAL  0xf5430080
-#define F0900_P1_K_DIVIDER_56  0xf543007f
+#define R0900_P1_KDIV56 0xf543
+#define KDIV56 REGx(R0900_P1_KDIV56)
+#define F0900_P1_K_DIVIDER_56 0xf543007f
 
 /*P1_KDIV67*/
-#define R0900_P1_KDIV67  0xf544
-#define F0900_P1_KDIV67_MANUAL  0xf5440080
-#define F0900_P1_K_DIVIDER_67  0xf544007f
+#define R0900_P1_KDIV67 0xf544
+#define KDIV67 REGx(R0900_P1_KDIV67)
+#define F0900_P1_K_DIVIDER_67 0xf544007f
 
 /*P1_KDIV78*/
-#define R0900_P1_KDIV78  0xf545
-#define F0900_P1_KDIV78_MANUAL  0xf5450080
-#define F0900_P1_K_DIVIDER_78  0xf545007f
+#define R0900_P1_KDIV78 0xf545
+#define KDIV78 REGx(R0900_P1_KDIV78)
+#define F0900_P1_K_DIVIDER_78 0xf545007f
 
 /*P1_PDELCTRL1*/
-#define R0900_P1_PDELCTRL1  0xf550
-#define F0900_P1_INV_MISMASK  0xf5500080
-#define F0900_P1_FORCE_ACCEPTED  0xf5500040
-#define F0900_P1_FILTER_EN  0xf5500020
-#define F0900_P1_FORCE_PKTDELINUSE  0xf5500010
-#define F0900_P1_HYSTEN  0xf5500008
-#define F0900_P1_HYSTSWRST  0xf5500004
-#define F0900_P1_EN_MIS00  0xf5500002
-#define F0900_P1_ALGOSWRST  0xf5500001
+#define R0900_P1_PDELCTRL1 0xf550
+#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
 
 /*P1_PDELCTRL2*/
-#define R0900_P1_PDELCTRL2  0xf551
-#define F0900_P1_FORCE_CONTINUOUS  0xf5510080
-#define F0900_P1_RESET_UPKO_COUNT  0xf5510040
-#define F0900_P1_USER_PKTDELIN_NB  0xf5510020
-#define F0900_P1_FORCE_LOCKED  0xf5510010
-#define F0900_P1_DATA_UNBBSCRAM  0xf5510008
-#define F0900_P1_FORCE_LONGPKT  0xf5510004
-#define F0900_P1_FRAME_MODE  0xf5510002
+#define R0900_P1_PDELCTRL2 0xf551
+#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
+#define F0900_P1_FRAME_MODE 0xf5510002
+#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
 
 /*P1_HYSTTHRESH*/
-#define R0900_P1_HYSTTHRESH  0xf554
-#define F0900_P1_UNLCK_THRESH  0xf55400f0
-#define F0900_P1_DELIN_LCK_THRESH  0xf554000f
+#define R0900_P1_HYSTTHRESH 0xf554
+#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
 
 /*P1_ISIENTRY*/
-#define R0900_P1_ISIENTRY  0xf55e
-#define F0900_P1_ISI_ENTRY  0xf55e00ff
+#define R0900_P1_ISIENTRY 0xf55e
+#define ISIENTRY REGx(R0900_P1_ISIENTRY)
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
 
 /*P1_ISIBITENA*/
-#define R0900_P1_ISIBITENA  0xf55f
-#define F0900_P1_ISI_BIT_EN  0xf55f00ff
+#define R0900_P1_ISIBITENA 0xf55f
+#define ISIBITENA REGx(R0900_P1_ISIBITENA)
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
 
 /*P1_MATSTR1*/
-#define R0900_P1_MATSTR1  0xf560
-#define F0900_P1_MATYPE_CURRENT1  0xf56000ff
+#define R0900_P1_MATSTR1 0xf560
+#define MATSTR1 REGx(R0900_P1_MATSTR1)
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
 
 /*P1_MATSTR0*/
-#define R0900_P1_MATSTR0  0xf561
-#define F0900_P1_MATYPE_CURRENT0  0xf56100ff
+#define R0900_P1_MATSTR0 0xf561
+#define MATSTR0 REGx(R0900_P1_MATSTR0)
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
 
 /*P1_UPLSTR1*/
-#define R0900_P1_UPLSTR1  0xf562
-#define F0900_P1_UPL_CURRENT1  0xf56200ff
+#define R0900_P1_UPLSTR1 0xf562
+#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
 
 /*P1_UPLSTR0*/
-#define R0900_P1_UPLSTR0  0xf563
-#define F0900_P1_UPL_CURRENT0  0xf56300ff
+#define R0900_P1_UPLSTR0 0xf563
+#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
 
 /*P1_DFLSTR1*/
-#define R0900_P1_DFLSTR1  0xf564
-#define F0900_P1_DFL_CURRENT1  0xf56400ff
+#define R0900_P1_DFLSTR1 0xf564
+#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
 
 /*P1_DFLSTR0*/
-#define R0900_P1_DFLSTR0  0xf565
-#define F0900_P1_DFL_CURRENT0  0xf56500ff
+#define R0900_P1_DFLSTR0 0xf565
+#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
 
 /*P1_SYNCSTR*/
-#define R0900_P1_SYNCSTR  0xf566
-#define F0900_P1_SYNC_CURRENT  0xf56600ff
+#define R0900_P1_SYNCSTR 0xf566
+#define SYNCSTR REGx(R0900_P1_SYNCSTR)
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
 
 /*P1_SYNCDSTR1*/
-#define R0900_P1_SYNCDSTR1  0xf567
-#define F0900_P1_SYNCD_CURRENT1  0xf56700ff
+#define R0900_P1_SYNCDSTR1 0xf567
+#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
 
 /*P1_SYNCDSTR0*/
-#define R0900_P1_SYNCDSTR0  0xf568
-#define F0900_P1_SYNCD_CURRENT0  0xf56800ff
+#define R0900_P1_SYNCDSTR0 0xf568
+#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
 
 /*P1_PDELSTATUS1*/
-#define R0900_P1_PDELSTATUS1  0xf569
-#define F0900_P1_PKTDELIN_DELOCK  0xf5690080
-#define F0900_P1_SYNCDUPDFL_BADDFL  0xf5690040
-#define F0900_P1_CONTINUOUS_STREAM  0xf5690020
-#define F0900_P1_UNACCEPTED_STREAM  0xf5690010
-#define F0900_P1_BCH_ERROR_FLAG  0xf5690008
-#define F0900_P1_BBHCRCKO  0xf5690004
-#define F0900_P1_PKTDELIN_LOCK  0xf5690002
-#define F0900_P1_FIRST_LOCK  0xf5690001
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
+#define F0900_P1_FIRST_LOCK 0xf5690001
 
 /*P1_PDELSTATUS2*/
-#define R0900_P1_PDELSTATUS2  0xf56a
-#define F0900_P1_PKTDEL_DEMODSEL  0xf56a0080
-#define F0900_P1_FRAME_MODCOD  0xf56a007c
-#define F0900_P1_FRAME_TYPE  0xf56a0003
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
 
 /*P1_BBFCRCKO1*/
-#define R0900_P1_BBFCRCKO1  0xf56b
-#define F0900_P1_BBHCRC_KOCNT1  0xf56b00ff
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
 
 /*P1_BBFCRCKO0*/
-#define R0900_P1_BBFCRCKO0  0xf56c
-#define F0900_P1_BBHCRC_KOCNT0  0xf56c00ff
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
 
 /*P1_UPCRCKO1*/
-#define R0900_P1_UPCRCKO1  0xf56d
-#define F0900_P1_PKTCRC_KOCNT1  0xf56d00ff
+#define R0900_P1_UPCRCKO1 0xf56d
+#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
 
 /*P1_UPCRCKO0*/
-#define R0900_P1_UPCRCKO0  0xf56e
-#define F0900_P1_PKTCRC_KOCNT0  0xf56e00ff
+#define R0900_P1_UPCRCKO0 0xf56e
+#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_PDELCTRL3*/
+#define R0900_P1_PDELCTRL3 0xf56f
+#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
+#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
+#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
 
 /*P1_TSSTATEM*/
-#define R0900_P1_TSSTATEM  0xf570
-#define F0900_P1_TSDIL_ON  0xf5700080
-#define F0900_P1_TSSKIPRS_ON  0xf5700040
-#define F0900_P1_TSRS_ON  0xf5700020
-#define F0900_P1_TSDESCRAMB_ON  0xf5700010
-#define F0900_P1_TSFRAME_MODE  0xf5700008
-#define F0900_P1_TS_DISABLE  0xf5700004
-#define F0900_P1_TSACM_MODE  0xf5700002
-#define F0900_P1_TSOUT_NOSYNC  0xf5700001
+#define R0900_P1_TSSTATEM 0xf570
+#define TSSTATEM REGx(R0900_P1_TSSTATEM)
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
 
 /*P1_TSCFGH*/
-#define R0900_P1_TSCFGH  0xf572
-#define F0900_P1_TSFIFO_DVBCI  0xf5720080
-#define F0900_P1_TSFIFO_SERIAL  0xf5720040
-#define F0900_P1_TSFIFO_TEIUPDATE  0xf5720020
-#define F0900_P1_TSFIFO_DUTY50  0xf5720010
-#define F0900_P1_TSFIFO_HSGNLOUT  0xf5720008
-#define F0900_P1_TSFIFO_ERRMODE  0xf5720006
-#define F0900_P1_RST_HWARE  0xf5720001
+#define R0900_P1_TSCFGH 0xf572
+#define TSCFGH REGx(R0900_P1_TSCFGH)
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
 
 /*P1_TSCFGM*/
-#define R0900_P1_TSCFGM  0xf573
-#define F0900_P1_TSFIFO_MANSPEED  0xf57300c0
-#define F0900_P1_TSFIFO_PERMDATA  0xf5730020
-#define F0900_P1_TSFIFO_NONEWSGNL  0xf5730010
-#define F0900_P1_TSFIFO_BITSPEED  0xf5730008
-#define F0900_P1_NPD_SPECDVBS2  0xf5730004
-#define F0900_P1_TSFIFO_STOPCKDIS  0xf5730002
-#define F0900_P1_TSFIFO_INVDATA  0xf5730001
+#define R0900_P1_TSCFGM 0xf573
+#define TSCFGM REGx(R0900_P1_TSCFGM)
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
 
 /*P1_TSCFGL*/
-#define R0900_P1_TSCFGL  0xf574
-#define F0900_P1_TSFIFO_BCLKDEL1CK  0xf57400c0
-#define F0900_P1_BCHERROR_MODE  0xf5740030
-#define F0900_P1_TSFIFO_NSGNL2DATA  0xf5740008
-#define F0900_P1_TSFIFO_EMBINDVB  0xf5740004
-#define F0900_P1_TSFIFO_DPUNACT  0xf5740002
-#define F0900_P1_TSFIFO_NPDOFF  0xf5740001
+#define R0900_P1_TSCFGL 0xf574
+#define TSCFGL REGx(R0900_P1_TSCFGL)
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
 
 /*P1_TSINSDELH*/
-#define R0900_P1_TSINSDELH  0xf576
-#define F0900_P1_TSDEL_SYNCBYTE  0xf5760080
-#define F0900_P1_TSDEL_XXHEADER  0xf5760040
-#define F0900_P1_TSDEL_BBHEADER  0xf5760020
-#define F0900_P1_TSDEL_DATAFIELD  0xf5760010
-#define F0900_P1_TSINSDEL_ISCR  0xf5760008
-#define F0900_P1_TSINSDEL_NPD  0xf5760004
-#define F0900_P1_TSINSDEL_RSPARITY  0xf5760002
-#define F0900_P1_TSINSDEL_CRC8  0xf5760001
+#define R0900_P1_TSINSDELH 0xf576
+#define TSINSDELH REGx(R0900_P1_TSINSDELH)
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSDIVN*/
+#define R0900_P1_TSDIVN 0xf579
+#define TSDIVN REGx(R0900_P1_TSDIVN)
+#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
+
+/*P1_TSCFG4*/
+#define R0900_P1_TSCFG4 0xf57a
+#define TSCFG4 REGx(R0900_P1_TSCFG4)
+#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
 
 /*P1_TSSPEED*/
-#define R0900_P1_TSSPEED  0xf580
-#define F0900_P1_TSFIFO_OUTSPEED  0xf58000ff
+#define R0900_P1_TSSPEED 0xf580
+#define TSSPEED REGx(R0900_P1_TSSPEED)
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
 
 /*P1_TSSTATUS*/
-#define R0900_P1_TSSTATUS  0xf581
-#define F0900_P1_TSFIFO_LINEOK  0xf5810080
-#define F0900_P1_TSFIFO_ERROR  0xf5810040
-#define F0900_P1_TSFIFO_DATA7  0xf5810020
-#define F0900_P1_TSFIFO_NOSYNC  0xf5810010
-#define F0900_P1_ISCR_INITIALIZED  0xf5810008
-#define F0900_P1_ISCR_UPDATED  0xf5810004
-#define F0900_P1_SOFFIFO_UNREGUL  0xf5810002
-#define F0900_P1_DIL_READY  0xf5810001
+#define R0900_P1_TSSTATUS 0xf581
+#define TSSTATUS REGx(R0900_P1_TSSTATUS)
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_DIL_READY 0xf5810001
 
 /*P1_TSSTATUS2*/
-#define R0900_P1_TSSTATUS2  0xf582
-#define F0900_P1_TSFIFO_DEMODSEL  0xf5820080
-#define F0900_P1_TSFIFOSPEED_STORE  0xf5820040
-#define F0900_P1_DILXX_RESET  0xf5820020
-#define F0900_P1_TSSERIAL_IMPOS  0xf5820010
-#define F0900_P1_TSFIFO_LINENOK  0xf5820008
-#define F0900_P1_BITSPEED_EVENT  0xf5820004
-#define F0900_P1_SCRAMBDETECT  0xf5820002
-#define F0900_P1_ULDTV67_FALSELOCK  0xf5820001
+#define R0900_P1_TSSTATUS2 0xf582
+#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_SCRAMBDETECT 0xf5820002
 
 /*P1_TSBITRATE1*/
-#define R0900_P1_TSBITRATE1  0xf583
-#define F0900_P1_TSFIFO_BITRATE1  0xf58300ff
+#define R0900_P1_TSBITRATE1 0xf583
+#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
 
 /*P1_TSBITRATE0*/
-#define R0900_P1_TSBITRATE0  0xf584
-#define F0900_P1_TSFIFO_BITRATE0  0xf58400ff
+#define R0900_P1_TSBITRATE0 0xf584
+#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
 
 /*P1_ERRCTRL1*/
-#define R0900_P1_ERRCTRL1  0xf598
-#define F0900_P1_ERR_SOURCE1  0xf59800f0
-#define F0900_P1_NUM_EVENT1  0xf5980007
+#define R0900_P1_ERRCTRL1 0xf598
+#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
 
 /*P1_ERRCNT12*/
-#define R0900_P1_ERRCNT12  0xf599
-#define F0900_P1_ERRCNT1_OLDVALUE  0xf5990080
-#define F0900_P1_ERR_CNT12  0xf599007f
+#define R0900_P1_ERRCNT12 0xf599
+#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
 
 /*P1_ERRCNT11*/
-#define R0900_P1_ERRCNT11  0xf59a
-#define F0900_P1_ERR_CNT11  0xf59a00ff
+#define R0900_P1_ERRCNT11 0xf59a
+#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
 
 /*P1_ERRCNT10*/
-#define R0900_P1_ERRCNT10  0xf59b
-#define F0900_P1_ERR_CNT10  0xf59b00ff
+#define R0900_P1_ERRCNT10 0xf59b
+#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
 
 /*P1_ERRCTRL2*/
-#define R0900_P1_ERRCTRL2  0xf59c
-#define F0900_P1_ERR_SOURCE2  0xf59c00f0
-#define F0900_P1_NUM_EVENT2  0xf59c0007
+#define R0900_P1_ERRCTRL2 0xf59c
+#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
 
 /*P1_ERRCNT22*/
-#define R0900_P1_ERRCNT22  0xf59d
-#define F0900_P1_ERRCNT2_OLDVALUE  0xf59d0080
-#define F0900_P1_ERR_CNT22  0xf59d007f
+#define R0900_P1_ERRCNT22 0xf59d
+#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
 
 /*P1_ERRCNT21*/
-#define R0900_P1_ERRCNT21  0xf59e
-#define F0900_P1_ERR_CNT21  0xf59e00ff
+#define R0900_P1_ERRCNT21 0xf59e
+#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
 
 /*P1_ERRCNT20*/
-#define R0900_P1_ERRCNT20  0xf59f
-#define F0900_P1_ERR_CNT20  0xf59f00ff
+#define R0900_P1_ERRCNT20 0xf59f
+#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
 
 /*P1_FECSPY*/
-#define R0900_P1_FECSPY  0xf5a0
-#define F0900_P1_SPY_ENABLE  0xf5a00080
-#define F0900_P1_NO_SYNCBYTE  0xf5a00040
-#define F0900_P1_SERIAL_MODE  0xf5a00020
-#define F0900_P1_UNUSUAL_PACKET  0xf5a00010
-#define F0900_P1_BER_PACKMODE  0xf5a00008
-#define F0900_P1_BERMETER_LMODE  0xf5a00002
-#define F0900_P1_BERMETER_RESET  0xf5a00001
+#define R0900_P1_FECSPY 0xf5a0
+#define FECSPY REGx(R0900_P1_FECSPY)
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
 
 /*P1_FSPYCFG*/
-#define R0900_P1_FSPYCFG  0xf5a1
-#define F0900_P1_FECSPY_INPUT  0xf5a100c0
-#define F0900_P1_RST_ON_ERROR  0xf5a10020
-#define F0900_P1_ONE_SHOT  0xf5a10010
-#define F0900_P1_I2C_MODE  0xf5a1000c
-#define F0900_P1_SPY_HYSTERESIS  0xf5a10003
+#define R0900_P1_FSPYCFG 0xf5a1
+#define FSPYCFG REGx(R0900_P1_FSPYCFG)
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
 
 /*P1_FSPYDATA*/
-#define R0900_P1_FSPYDATA  0xf5a2
-#define F0900_P1_SPY_STUFFING  0xf5a20080
-#define F0900_P1_NOERROR_PKTJITTER  0xf5a20040
-#define F0900_P1_SPY_CNULLPKT  0xf5a20020
-#define F0900_P1_SPY_OUTDATA_MODE  0xf5a2001f
+#define R0900_P1_FSPYDATA 0xf5a2
+#define FSPYDATA REGx(R0900_P1_FSPYDATA)
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
 
 /*P1_FSPYOUT*/
-#define R0900_P1_FSPYOUT  0xf5a3
-#define F0900_P1_FSPY_DIRECT  0xf5a30080
-#define F0900_P1_SPY_OUTDATA_BUS  0xf5a30038
-#define F0900_P1_STUFF_MODE  0xf5a30007
+#define R0900_P1_FSPYOUT 0xf5a3
+#define FSPYOUT REGx(R0900_P1_FSPYOUT)
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_STUFF_MODE 0xf5a30007
 
 /*P1_FSTATUS*/
-#define R0900_P1_FSTATUS  0xf5a4
-#define F0900_P1_SPY_ENDSIM  0xf5a40080
-#define F0900_P1_VALID_SIM  0xf5a40040
-#define F0900_P1_FOUND_SIGNAL  0xf5a40020
-#define F0900_P1_DSS_SYNCBYTE  0xf5a40010
-#define F0900_P1_RESULT_STATE  0xf5a4000f
+#define R0900_P1_FSTATUS 0xf5a4
+#define FSTATUS REGx(R0900_P1_FSTATUS)
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
 
 /*P1_FBERCPT4*/
-#define R0900_P1_FBERCPT4  0xf5a8
-#define F0900_P1_FBERMETER_CPT4  0xf5a800ff
+#define R0900_P1_FBERCPT4 0xf5a8
+#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
 
 /*P1_FBERCPT3*/
-#define R0900_P1_FBERCPT3  0xf5a9
-#define F0900_P1_FBERMETER_CPT3  0xf5a900ff
+#define R0900_P1_FBERCPT3 0xf5a9
+#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
 
 /*P1_FBERCPT2*/
-#define R0900_P1_FBERCPT2  0xf5aa
-#define F0900_P1_FBERMETER_CPT2  0xf5aa00ff
+#define R0900_P1_FBERCPT2 0xf5aa
+#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
 
 /*P1_FBERCPT1*/
-#define R0900_P1_FBERCPT1  0xf5ab
-#define F0900_P1_FBERMETER_CPT1  0xf5ab00ff
+#define R0900_P1_FBERCPT1 0xf5ab
+#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
 
 /*P1_FBERCPT0*/
-#define R0900_P1_FBERCPT0  0xf5ac
-#define F0900_P1_FBERMETER_CPT0  0xf5ac00ff
+#define R0900_P1_FBERCPT0 0xf5ac
+#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
 
 /*P1_FBERERR2*/
-#define R0900_P1_FBERERR2  0xf5ad
-#define F0900_P1_FBERMETER_ERR2  0xf5ad00ff
+#define R0900_P1_FBERERR2 0xf5ad
+#define FBERERR2 REGx(R0900_P1_FBERERR2)
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
 
 /*P1_FBERERR1*/
-#define R0900_P1_FBERERR1  0xf5ae
-#define F0900_P1_FBERMETER_ERR1  0xf5ae00ff
+#define R0900_P1_FBERERR1 0xf5ae
+#define FBERERR1 REGx(R0900_P1_FBERERR1)
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
 
 /*P1_FBERERR0*/
-#define R0900_P1_FBERERR0  0xf5af
-#define F0900_P1_FBERMETER_ERR0  0xf5af00ff
+#define R0900_P1_FBERERR0 0xf5af
+#define FBERERR0 REGx(R0900_P1_FBERERR0)
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
 
 /*P1_FSPYBER*/
-#define R0900_P1_FSPYBER  0xf5b2
-#define F0900_P1_FSPYOBS_XORREAD  0xf5b20040
-#define F0900_P1_FSPYBER_OBSMODE  0xf5b20020
-#define F0900_P1_FSPYBER_SYNCBYTE  0xf5b20010
-#define F0900_P1_FSPYBER_UNSYNC  0xf5b20008
-#define F0900_P1_FSPYBER_CTIME  0xf5b20007
+#define R0900_P1_FSPYBER 0xf5b2
+#define FSPYBER REGx(R0900_P1_FSPYBER)
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
 
-/*RCCFGH*/
-#define R0900_RCCFGH  0xf600
-#define F0900_TSRCFIFO_DVBCI  0xf6000080
-#define F0900_TSRCFIFO_SERIAL  0xf6000040
-#define F0900_TSRCFIFO_DISABLE  0xf6000020
-#define F0900_TSFIFO_2TORC  0xf6000010
-#define F0900_TSRCFIFO_HSGNLOUT  0xf6000008
-#define F0900_TSRCFIFO_ERRMODE  0xf6000006
+/*RCCFG2*/
+#define R0900_RCCFG2 0xf600
 
 /*TSGENERAL*/
-#define R0900_TSGENERAL  0xf630
-#define F0900_TSFIFO_BCLK1ALL  0xf6300020
-#define F0900_MUXSTREAM_OUTMODE  0xf6300008
-#define F0900_TSFIFO_PERMPARAL  0xf6300006
-#define F0900_RST_REEDSOLO  0xf6300001
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_DISTS2PAR 0xf6300040
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
 
 /*TSGENERAL1X*/
-#define R0900_TSGENERAL1X  0xf670
-#define F0900_TSFIFO1X_BCLK1ALL  0xf6700020
-#define F0900_MUXSTREAM1X_OUTMODE  0xf6700008
-#define F0900_TSFIFO1X_PERMPARAL  0xf6700006
-#define F0900_RST1X_REEDSOLO  0xf6700001
+#define R0900_TSGENERAL1X 0xf670
 
 /*NBITER_NF4*/
-#define R0900_NBITER_NF4  0xfa03
-#define F0900_NBITER_NF_QP_1_2  0xfa0300ff
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
 
 /*NBITER_NF5*/
-#define R0900_NBITER_NF5  0xfa04
-#define F0900_NBITER_NF_QP_3_5  0xfa0400ff
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
 
 /*NBITER_NF6*/
-#define R0900_NBITER_NF6  0xfa05
-#define F0900_NBITER_NF_QP_2_3  0xfa0500ff
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
 
 /*NBITER_NF7*/
-#define R0900_NBITER_NF7  0xfa06
-#define F0900_NBITER_NF_QP_3_4  0xfa0600ff
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
 
 /*NBITER_NF8*/
-#define R0900_NBITER_NF8  0xfa07
-#define F0900_NBITER_NF_QP_4_5  0xfa0700ff
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
 
 /*NBITER_NF9*/
-#define R0900_NBITER_NF9  0xfa08
-#define F0900_NBITER_NF_QP_5_6  0xfa0800ff
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
 
 /*NBITER_NF10*/
-#define R0900_NBITER_NF10  0xfa09
-#define F0900_NBITER_NF_QP_8_9  0xfa0900ff
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
 
 /*NBITER_NF11*/
-#define R0900_NBITER_NF11  0xfa0a
-#define F0900_NBITER_NF_QP_9_10  0xfa0a00ff
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
 
 /*NBITER_NF12*/
-#define R0900_NBITER_NF12  0xfa0b
-#define F0900_NBITER_NF_8P_3_5  0xfa0b00ff
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
 
 /*NBITER_NF13*/
-#define R0900_NBITER_NF13  0xfa0c
-#define F0900_NBITER_NF_8P_2_3  0xfa0c00ff
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
 
 /*NBITER_NF14*/
-#define R0900_NBITER_NF14  0xfa0d
-#define F0900_NBITER_NF_8P_3_4  0xfa0d00ff
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
 
 /*NBITER_NF15*/
-#define R0900_NBITER_NF15  0xfa0e
-#define F0900_NBITER_NF_8P_5_6  0xfa0e00ff
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
 
 /*NBITER_NF16*/
-#define R0900_NBITER_NF16  0xfa0f
-#define F0900_NBITER_NF_8P_8_9  0xfa0f00ff
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
 
 /*NBITER_NF17*/
-#define R0900_NBITER_NF17  0xfa10
-#define F0900_NBITER_NF_8P_9_10  0xfa1000ff
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
 
 /*NBITERNOERR*/
-#define R0900_NBITERNOERR  0xfa3f
-#define F0900_NBITER_STOP_CRIT  0xfa3f000f
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
 
 /*GAINLLR_NF4*/
-#define R0900_GAINLLR_NF4  0xfa43
-#define F0900_GAINLLR_NF_QP_1_2  0xfa43007f
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
 
 /*GAINLLR_NF5*/
-#define R0900_GAINLLR_NF5  0xfa44
-#define F0900_GAINLLR_NF_QP_3_5  0xfa44007f
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
 
 /*GAINLLR_NF6*/
-#define R0900_GAINLLR_NF6  0xfa45
-#define F0900_GAINLLR_NF_QP_2_3  0xfa45007f
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
 
 /*GAINLLR_NF7*/
-#define R0900_GAINLLR_NF7  0xfa46
-#define F0900_GAINLLR_NF_QP_3_4  0xfa46007f
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
 
 /*GAINLLR_NF8*/
-#define R0900_GAINLLR_NF8  0xfa47
-#define F0900_GAINLLR_NF_QP_4_5  0xfa47007f
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
 
 /*GAINLLR_NF9*/
-#define R0900_GAINLLR_NF9  0xfa48
-#define F0900_GAINLLR_NF_QP_5_6  0xfa48007f
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
 
 /*GAINLLR_NF10*/
-#define R0900_GAINLLR_NF10  0xfa49
-#define F0900_GAINLLR_NF_QP_8_9  0xfa49007f
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
 
 /*GAINLLR_NF11*/
-#define R0900_GAINLLR_NF11  0xfa4a
-#define F0900_GAINLLR_NF_QP_9_10  0xfa4a007f
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
 
 /*GAINLLR_NF12*/
-#define R0900_GAINLLR_NF12  0xfa4b
-#define F0900_GAINLLR_NF_8P_3_5  0xfa4b007f
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
 
 /*GAINLLR_NF13*/
-#define R0900_GAINLLR_NF13  0xfa4c
-#define F0900_GAINLLR_NF_8P_2_3  0xfa4c007f
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
 
 /*GAINLLR_NF14*/
-#define R0900_GAINLLR_NF14  0xfa4d
-#define F0900_GAINLLR_NF_8P_3_4  0xfa4d007f
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
 
 /*GAINLLR_NF15*/
-#define R0900_GAINLLR_NF15  0xfa4e
-#define F0900_GAINLLR_NF_8P_5_6  0xfa4e007f
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
 
 /*GAINLLR_NF16*/
-#define R0900_GAINLLR_NF16  0xfa4f
-#define F0900_GAINLLR_NF_8P_8_9  0xfa4f007f
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
 
 /*GAINLLR_NF17*/
-#define R0900_GAINLLR_NF17  0xfa50
-#define F0900_GAINLLR_NF_8P_9_10  0xfa50007f
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
 
 /*CFGEXT*/
-#define R0900_CFGEXT  0xfa80
-#define F0900_STAGMODE  0xfa800080
-#define F0900_BYPBCH  0xfa800040
-#define F0900_BYPLDPC  0xfa800020
-#define F0900_LDPCMODE  0xfa800010
-#define F0900_INVLLRSIGN  0xfa800008
-#define F0900_SHORTMULT  0xfa800004
-#define F0900_EXTERNTX  0xfa800001
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
 
 /*GENCFG*/
-#define R0900_GENCFG  0xfa86
-#define F0900_BROADCAST  0xfa860010
-#define F0900_NOSHFRD2  0xfa860008
-#define F0900_BCHERRFLAG  0xfa860004
-#define F0900_PRIORITY  0xfa860002
-#define F0900_DDEMOD  0xfa860001
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
 
 /*LDPCERR1*/
-#define R0900_LDPCERR1  0xfa96
-#define F0900_LDPC_ERRORS_COUNTER1  0xfa9600ff
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
 
 /*LDPCERR0*/
-#define R0900_LDPCERR0  0xfa97
-#define F0900_LDPC_ERRORS_COUNTER0  0xfa9700ff
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
 
 /*BCHERR*/
-#define R0900_BCHERR  0xfa98
-#define F0900_ERRORFLAG  0xfa980010
-#define F0900_BCH_ERRORS_COUNTER  0xfa98000f
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
 
 /*TSTRES0*/
-#define R0900_TSTRES0  0xff11
-#define F0900_FRESFEC  0xff110080
-#define F0900_FRESTS  0xff110040
-#define F0900_FRESVIT1  0xff110020
-#define F0900_FRESVIT2  0xff110010
-#define F0900_FRESSYM1  0xff110008
-#define F0900_FRESSYM2  0xff110004
-#define F0900_FRESMAS  0xff110002
-#define F0900_FRESINT  0xff110001
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+
+/*P2_TCTL4*/
+#define R0900_P2_TCTL4 0xff28
+#define F0900_P2_PN4_SELECT 0xff280020
+
+/*P1_TCTL4*/
+#define R0900_P1_TCTL4 0xff48
+#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
+#define F0900_P1_PN4_SELECT 0xff480020
 
 /*P2_TSTDISRX*/
-#define R0900_P2_TSTDISRX  0xff65
-#define F0900_P2_EN_DISRX  0xff650080
-#define F0900_P2_TST_CURRSRC  0xff650040
-#define F0900_P2_IN_DIGSIGNAL  0xff650020
-#define F0900_P2_HIZ_CURRENTSRC  0xff650010
-#define F0900_TST_P2_PIN_SELECT  0xff650008
-#define F0900_P2_TST_DISRX  0xff650007
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_PIN_SELECT1 0xff650008
 
 /*P1_TSTDISRX*/
-#define R0900_P1_TSTDISRX  0xff67
-#define F0900_P1_EN_DISRX  0xff670080
-#define F0900_P1_TST_CURRSRC  0xff670040
-#define F0900_P1_IN_DIGSIGNAL  0xff670020
-#define F0900_P1_HIZ_CURRENTSRC  0xff670010
-#define F0900_TST_P1_PIN_SELECT  0xff670008
-#define F0900_P1_TST_DISRX  0xff670007
+#define R0900_P1_TSTDISRX 0xff67
+#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
+#define F0900_P1_PIN_SELECT1 0xff670008
+#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
 
-#define STV0900_NBREGS		684
-#define STV0900_NBFIELDS		1702
+#define STV0900_NBREGS 723
+#define STV0900_NBFIELDS 1420
 
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_sw.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_sw.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,56 +27,45 @@
 #include "stv0900_reg.h"
 #include "stv0900_priv.h"
 
-int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+s32 shiftx(s32 x, int demod, s32 shift)
+{
+	if (demod == 1)
+		return x - shift;
+
+	return x;
+}
+
+int stv0900_check_signal_presence(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 carr_offset,
-	agc2_integr,
-	max_carrier;
+	s32	carr_offset,
+		agc2_integr,
+		max_carrier;
 
-	int no_signal;
+	int no_signal = FALSE;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P1_CFR1);
-		carr_offset = ge2comp(carr_offset, 16);
-		agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P1_AGC2I0);
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		break;
-	case STV0900_DEMOD_2:
-		carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P2_CFR1);
-		carr_offset = ge2comp(carr_offset, 16);
-		agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-						| stv0900_read_reg(i_params,
-						R0900_P2_AGC2I0);
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		break;
-	}
+	carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
+					| stv0900_read_reg(intp, CFR1);
+	carr_offset = ge2comp(carr_offset, 16);
+	agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
+	max_carrier = intp->srch_range[demod] / 1000;
 
 	max_carrier += (max_carrier / 10);
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
 
 	if ((agc2_integr > 0x2000)
-			|| (carr_offset > + 2*max_carrier)
-			|| (carr_offset < -2*max_carrier))
+			|| (carr_offset > (2 * max_carrier))
+			|| (carr_offset < (-2 * max_carrier)))
 		no_signal = TRUE;
-	else
-		no_signal = FALSE;
 
 	return no_signal;
 }
 
-static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
+static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
 				s32 *frequency_inc, s32 *sw_timeout,
 				s32 *steps,
 				enum fe_stv0900_demod_num demod)
@@ -85,30 +74,19 @@ static void stv0900_get_sw_loop_params(s
 
 	enum fe_stv0900_search_standard	standard;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		srate = i_params->dmd1_symbol_rate;
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		max_carrier += max_carrier / 10;
-		standard = i_params->dmd1_srch_standard;
-		break;
-	case STV0900_DEMOD_2:
-		srate = i_params->dmd2_symbol_rate;
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		max_carrier += max_carrier / 10;
-		standard = i_params->dmd2_srch_stndrd;
-		break;
-	}
+	srate = intp->symbol_rate[demod];
+	max_carrier = intp->srch_range[demod] / 1000;
+	max_carrier += max_carrier / 10;
+	standard = intp->srch_standard[demod];
 
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
 
 	freq_inc = srate;
-	freq_inc /= i_params->mclk >> 10;
+	freq_inc /= intp->mclk >> 10;
 	freq_inc = freq_inc << 6;
 
 	switch (standard) {
@@ -154,7 +132,7 @@ static void stv0900_get_sw_loop_params(s
 
 }
 
-static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
 				s32 FreqIncr, s32 Timeout, int zigzag,
 				s32 MaxStep, enum fe_stv0900_demod_num demod)
 {
@@ -164,20 +142,11 @@ static int stv0900_search_carr_sw_loop(s
 		freqOffset,
 		max_carrier;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		max_carrier = i_params->dmd1_srch_range / 1000;
-		max_carrier += (max_carrier / 10);
-		break;
-	case STV0900_DEMOD_2:
-		max_carrier = i_params->dmd2_srch_range / 1000;
-		max_carrier += (max_carrier / 10);
-		break;
-	}
+	max_carrier = intp->srch_range[demod] / 1000;
+	max_carrier += (max_carrier / 10);
 
 	max_carrier = 65536 * (max_carrier / 2);
-	max_carrier /= i_params->mclk / 1000;
+	max_carrier /= intp->mclk / 1000;
 
 	if (max_carrier > 0x4000)
 		max_carrier = 0x4000;
@@ -190,40 +159,15 @@ static int stv0900_search_carr_sw_loop(s
 	stepCpt = 0;
 
 	do {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1,
-					(freqOffset / 256) & 0xFF);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0,
-					 freqOffset & 0xFF);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
-
-			if (i_params->chip_id == 0x12) {
-				stv0900_write_bits(i_params,
-						F0900_P1_RST_HWARE, 1);
-				stv0900_write_bits(i_params,
-						F0900_P1_RST_HWARE, 0);
-			}
-			break;
-		case STV0900_DEMOD_2:
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
-					(freqOffset / 256) & 0xFF);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
-					freqOffset & 0xFF);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-			stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+		stv0900_write_reg(intp, DMDISTATE, 0x1c);
+		stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
+		stv0900_write_bits(intp, ALGOSWRST, 1);
 
-			if (i_params->chip_id == 0x12) {
-				stv0900_write_bits(i_params,
-						F0900_P2_RST_HWARE, 1);
-				stv0900_write_bits(i_params,
-						F0900_P2_RST_HWARE, 0);
-			}
-			break;
+		if (intp->chip_id == 0x12) {
+			stv0900_write_bits(intp, RST_HWARE, 1);
+			stv0900_write_bits(intp, RST_HWARE, 0);
 		}
 
 		if (zigzag == TRUE) {
@@ -235,8 +179,8 @@ static int stv0900_search_carr_sw_loop(s
 			freqOffset += + 2 * FreqIncr;
 
 		stepCpt++;
-		lock = stv0900_get_demod_lock(i_params, demod, Timeout);
-		no_signal = stv0900_check_signal_presence(i_params, demod);
+		lock = stv0900_get_demod_lock(intp, demod, Timeout);
+		no_signal = stv0900_check_signal_presence(intp, demod);
 
 	} while ((lock == FALSE)
 			&& (no_signal == FALSE)
@@ -244,269 +188,138 @@ static int stv0900_search_carr_sw_loop(s
 			&& ((freqOffset + FreqIncr) > -max_carrier)
 			&& (stepCpt < MaxStep));
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
-		break;
-	}
+	stv0900_write_bits(intp, ALGOSWRST, 0);
 
 	return lock;
 }
 
-int stv0900_sw_algo(struct stv0900_internal *i_params,
+int stv0900_sw_algo(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
-	int lock = FALSE;
-
-	int no_signal,
-	zigzag;
-	s32 dvbs2_fly_wheel;
-
-	s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
+	int	lock = FALSE,
+		no_signal,
+		zigzag;
+	s32	s2fw,
+		fqc_inc,
+		sft_stp_tout,
+		trial_cntr,
+		max_steps;
 
-	stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+	stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
 					&max_steps, demod);
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_srch_standard) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-						0x3B);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-						0xef);
-
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
-			zigzag = FALSE;
-			break;
-		case STV0900_SEARCH_DVBS2:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-						0x79);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-						0x68);
+	switch (intp->srch_standard[demod]) {
+	case STV0900_SEARCH_DVBS1:
+	case STV0900_SEARCH_DSS:
+		if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CARFREQ, 0x3b);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xef);
 
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
-						0x89);
+		stv0900_write_reg(intp, DMDCFGMD, 0x49);
+		zigzag = FALSE;
+		break;
+	case STV0900_SEARCH_DVBS2:
+		if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CORRELABS, 0x79);
+		else
+			stv0900_write_reg(intp, CORRELABS, 0x68);
 
-			zigzag = TRUE;
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-							0x3B);
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-							0x79);
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ,
-							0xef);
-				stv0900_write_reg(i_params, R0900_P1_CORRELABS,
-							0x68);
-			}
+		stv0900_write_reg(intp, DMDCFGMD, 0x89);
 
-			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
-							0xc9);
-			zigzag = FALSE;
-			break;
+		zigzag = TRUE;
+		break;
+	case STV0900_AUTO_SEARCH:
+	default:
+		if (intp->chip_id >= 0x20) {
+			stv0900_write_reg(intp, CARFREQ, 0x3b);
+			stv0900_write_reg(intp, CORRELABS, 0x79);
+		} else {
+			stv0900_write_reg(intp, CARFREQ, 0xef);
+			stv0900_write_reg(intp, CORRELABS, 0x68);
 		}
 
-		trialCounter = 0;
-		do {
-			lock = stv0900_search_carr_sw_loop(i_params,
-							freqIncrement,
-							softStepTimeout,
-							zigzag,
-							max_steps,
-							demod);
-			no_signal = stv0900_check_signal_presence(i_params,
-								demod);
-			trialCounter++;
-			if ((lock == TRUE)
-					|| (no_signal == TRUE)
-					|| (trialCounter == 2)) {
-
-				if (i_params->chip_id >= 0x20) {
-					stv0900_write_reg(i_params,
-							R0900_P1_CARFREQ,
-							0x49);
-					stv0900_write_reg(i_params,
-							R0900_P1_CORRELABS,
-							0x9e);
-				} else {
-					stv0900_write_reg(i_params,
-							R0900_P1_CARFREQ,
-							0xed);
-					stv0900_write_reg(i_params,
-							R0900_P1_CORRELABS,
-							0x88);
-				}
-
-				if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
-					msleep(softStepTimeout);
-					dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
-
-					if (dvbs2_fly_wheel < 0xd) {
-						msleep(softStepTimeout);
-						dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
-					}
-
-					if (dvbs2_fly_wheel < 0xd) {
-						lock = FALSE;
-
-						if (trialCounter < 2) {
-							if (i_params->chip_id >= 0x20)
-								stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
-							else
-								stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
-
-							stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
-						}
-					}
-				}
-			}
-
-		} while ((lock == FALSE)
-			&& (trialCounter < 2)
-			&& (no_signal == FALSE));
-
+		stv0900_write_reg(intp, DMDCFGMD, 0xc9);
+		zigzag = FALSE;
 		break;
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_srch_stndrd) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0x3b);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0xef);
+	}
 
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
-						0x49);
-			zigzag = FALSE;
-			break;
-		case STV0900_SEARCH_DVBS2:
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x79);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x68);
+	trial_cntr = 0;
+	do {
+		lock = stv0900_search_carr_sw_loop(intp,
+						fqc_inc,
+						sft_stp_tout,
+						zigzag,
+						max_steps,
+						demod);
+		no_signal = stv0900_check_signal_presence(intp, demod);
+		trial_cntr++;
+		if ((lock == TRUE)
+				|| (no_signal == TRUE)
+				|| (trial_cntr == 2)) {
 
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
-			zigzag = TRUE;
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0x3b);
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x79);
+			if (intp->chip_id >= 0x20) {
+				stv0900_write_reg(intp, CARFREQ, 0x49);
+				stv0900_write_reg(intp, CORRELABS, 0x9e);
 			} else {
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
-						0xef);
-				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
-						0x68);
+				stv0900_write_reg(intp, CARFREQ, 0xed);
+				stv0900_write_reg(intp, CORRELABS, 0x88);
 			}
 
-			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
-
-			zigzag = FALSE;
-			break;
-		}
-
-		trialCounter = 0;
+			if ((stv0900_get_bits(intp, HEADER_MODE) ==
+						STV0900_DVBS2_FOUND) &&
+							(lock == TRUE)) {
+				msleep(sft_stp_tout);
+				s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
 
-		do {
-			lock = stv0900_search_carr_sw_loop(i_params,
-							freqIncrement,
-							softStepTimeout,
-							zigzag,
-							max_steps,
-							demod);
-			no_signal = stv0900_check_signal_presence(i_params,
-								demod);
-			trialCounter++;
-			if ((lock == TRUE)
-					|| (no_signal == TRUE)
-					|| (trialCounter == 2)) {
-				if (i_params->chip_id >= 0x20) {
-					stv0900_write_reg(i_params,
-							R0900_P2_CARFREQ,
-							0x49);
-					stv0900_write_reg(i_params,
-							R0900_P2_CORRELABS,
-							0x9e);
-				} else {
-					stv0900_write_reg(i_params,
-							R0900_P2_CARFREQ,
-							0xed);
-					stv0900_write_reg(i_params,
-							R0900_P2_CORRELABS,
-							0x88);
+				if (s2fw < 0xd) {
+					msleep(sft_stp_tout);
+					s2fw = stv0900_get_bits(intp,
+								FLYWHEEL_CPT);
 				}
 
-				if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
-					msleep(softStepTimeout);
-					dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
-					if (dvbs2_fly_wheel < 0xd) {
-						msleep(softStepTimeout);
-						dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
-					}
+				if (s2fw < 0xd) {
+					lock = FALSE;
 
-					if (dvbs2_fly_wheel < 0xd) {
-						lock = FALSE;
-						if (trialCounter < 2) {
-							if (i_params->chip_id >= 0x20)
-								stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79);
-							else
-								stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68);
+					if (trial_cntr < 2) {
+						if (intp->chip_id >= 0x20)
+							stv0900_write_reg(intp,
+								CORRELABS,
+								0x79);
+						else
+							stv0900_write_reg(intp,
+								CORRELABS,
+								0x68);
 
-							stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
-						}
+						stv0900_write_reg(intp,
+								DMDCFGMD,
+								0x89);
 					}
 				}
 			}
+		}
 
-		} while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
-
-		break;
-	}
+	} while ((lock == FALSE)
+		&& (trial_cntr < 2)
+		&& (no_signal == FALSE));
 
 	return lock;
 }
 
-static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0,
-	rem1, rem2, intval1, intval2, srate;
-
-	dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3);
-	dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2);
-	dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1);
-	dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
+	s32	rem1, rem2, intval1, intval2, srate;
 
-	srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
-		(stv0900_get_bits(i_params, sfr_field2) << 16) +
-		(stv0900_get_bits(i_params, sfr_field1) << 8) +
-		(stv0900_get_bits(i_params, sfr_field0));
+	srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
+		(stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
+		(stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
+		(stv0900_get_bits(intp, SYMB_FREQ0));
 	dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
-		srate, stv0900_get_bits(i_params, sfr_field0),
-		stv0900_get_bits(i_params, sfr_field1),
-		stv0900_get_bits(i_params, sfr_field2),
-		stv0900_get_bits(i_params, sfr_field3));
+		srate, stv0900_get_bits(intp, SYMB_FREQ0),
+		stv0900_get_bits(intp, SYMB_FREQ1),
+		stv0900_get_bits(intp, SYMB_FREQ2),
+		stv0900_get_bits(intp, SYMB_FREQ3));
 
 	intval1 = (mclk) >> 16;
 	intval2 = (srate) >> 16;
@@ -520,18 +333,15 @@ static u32 stv0900_get_symbol_rate(struc
 	return srate;
 }
 
-static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_init_reg;
 	u32 symb;
 
-	dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+	dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
 							srate, demod);
 
-	dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
-
 	if (srate > 60000000) {
 		symb = srate << 4;
 		symb /= (mclk >> 12);
@@ -543,19 +353,16 @@ static void stv0900_set_symbol_rate(stru
 		symb /= (mclk >> 7);
 	}
 
-	stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F);
-	stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF));
+	stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
+	stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
 }
 
-static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_max_reg;
 	u32 symb;
 
-	dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
-
 	srate = 105 * (srate / 100);
 
 	if (srate > 60000000) {
@@ -570,23 +377,20 @@ static void stv0900_set_max_symbol_rate(
 	}
 
 	if (symb < 0x7fff) {
-		stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F);
-		stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF));
+		stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
 	} else {
-		stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
-		stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+		stv0900_write_reg(intp, SFRUP1, 0x7f);
+		stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
 	}
 }
 
-static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
 					u32 mclk, u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 sfr_min_reg;
 	u32	symb;
 
-	dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
-
 	srate = 95 * (srate / 100);
 	if (srate > 60000000) {
 		symb = srate << 4;
@@ -601,22 +405,20 @@ static void stv0900_set_min_symbol_rate(
 		symb /= (mclk >> 7);
 	}
 
-	stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF);
-	stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF));
+	stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
+	stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
 }
 
-static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
 					u32 srate,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 tmgreg,
-	timingoffset;
+	s32 timingoffset;
 
-	dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
 
-	timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) +
-		       (stv0900_read_reg(i_params, tmgreg + 1) << 8) +
-		       (stv0900_read_reg(i_params, tmgreg + 2));
+	timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
+		       (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
+		       (stv0900_read_reg(intp, TMGREG2 + 2));
 
 	timingoffset = ge2comp(timingoffset, 24);
 
@@ -630,22 +432,19 @@ static s32 stv0900_get_timing_offst(stru
 	return timingoffset;
 }
 
-static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld;
-
-	dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF);
-	dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1);
-	dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL,
-				F0900_P2_ROLLOFF_CONTROL);
+	s32 rolloff;
 
-	if (i_params->chip_id == 0x10) {
-		stv0900_write_bits(i_params, man_fld, 1);
-		rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03;
-		stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
-	} else
-		stv0900_write_bits(i_params, man_fld, 0);
+	if (intp->chip_id == 0x10) {
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+		rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
+		stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
+	} else if (intp->chip_id <= 0x20)
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
+	else /* cut 3.0 */
+		stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
 }
 
 static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
@@ -668,84 +467,47 @@ static u32 stv0900_carrier_width(u32 sra
 	return srate  + (srate * rolloff) / 100;
 }
 
-static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+static int stv0900_check_timing_lock(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod)
 {
 	int timingLock = FALSE;
-	s32 i,
-	timingcpt = 0;
-	u8 carFreq,
-	tmgTHhigh,
-	tmgTHLow;
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ);
-		tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE);
-		tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x80);
-		stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40);
-		stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65);
-		stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-		msleep(7);
-
-		for (i = 0; i < 10; i++) {
-			if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
-				timingcpt++;
-
-			msleep(1);
-		}
+	s32	i,
+		timingcpt = 0;
+	u8	car_freq,
+		tmg_th_high,
+		tmg_th_low;
 
-		if (timingcpt >= 3)
-			timingLock = TRUE;
+	car_freq = stv0900_read_reg(intp, CARFREQ);
+	tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
+	tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
+	stv0900_write_reg(intp, TMGTHRISE, 0x20);
+	stv0900_write_reg(intp, TMGTHFALL, 0x0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+	stv0900_write_reg(intp, RTC, 0x80);
+	stv0900_write_reg(intp, RTCS2, 0x40);
+	stv0900_write_reg(intp, CARFREQ, 0x0);
+	stv0900_write_reg(intp, CFRINIT1, 0x0);
+	stv0900_write_reg(intp, CFRINIT0, 0x0);
+	stv0900_write_reg(intp, AGC2REF, 0x65);
+	stv0900_write_reg(intp, DMDISTATE, 0x18);
+	msleep(7);
 
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-		stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
-		stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
-		stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
-		break;
-	case STV0900_DEMOD_2:
-		carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
-		tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
-		tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
-		stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
-		stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
-		stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-		msleep(5);
-		for (i = 0; i < 10; i++) {
-			if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
-				timingcpt++;
+	for (i = 0; i < 10; i++) {
+		if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+			timingcpt++;
 
-			msleep(1);
-		}
+		msleep(1);
+	}
 
-		if (timingcpt >= 3)
-			timingLock = TRUE;
+	if (timingcpt >= 3)
+		timingLock = TRUE;
 
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
-		stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
-		stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
-		break;
-	}
+	stv0900_write_reg(intp, AGC2REF, 0x38);
+	stv0900_write_reg(intp, RTC, 0x88);
+	stv0900_write_reg(intp, RTCS2, 0x68);
+	stv0900_write_reg(intp, CARFREQ, car_freq);
+	stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
+	stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
 
 	return	timingLock;
 }
@@ -754,142 +516,114 @@ static int stv0900_get_demod_cold_lock(s
 					s32 demod_timeout)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
+	int	lock = FALSE,
+		d = demod;
+	s32	srate,
+		search_range,
+		locktimeout,
+		currier_step,
+		nb_steps,
+		current_step,
+		direction,
+		tuner_freq,
+		timeout,
+		freq;
 
-	int lock = FALSE;
-	s32 srate, search_range, locktimeout,
-		currier_step, nb_steps, current_step,
-		direction, tuner_freq, timeout;
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		srate = i_params->dmd1_symbol_rate;
-		search_range = i_params->dmd1_srch_range;
-		break;
-
-	case STV0900_DEMOD_2:
-		srate = i_params->dmd2_symbol_rate;
-		search_range = i_params->dmd2_srch_range;
-		break;
-	}
+	srate = intp->symbol_rate[d];
+	search_range = intp->srch_range[d];
 
 	if (srate >= 10000000)
 		locktimeout = demod_timeout / 3;
 	else
 		locktimeout = demod_timeout / 2;
 
-	lock = stv0900_get_demod_lock(i_params, demod, locktimeout);
+	lock = stv0900_get_demod_lock(intp, d, locktimeout);
 
-	if (lock == FALSE) {
-		if (srate >= 10000000) {
-			if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
-				switch (demod) {
-				case STV0900_DEMOD_1:
-				default:
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-					break;
-				case STV0900_DEMOD_2:
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-					break;
-				}
+	if (lock != FALSE)
+		return lock;
 
-				lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
-			} else
-				lock = FALSE;
-		} else {
-			if (srate <= 4000000)
-				currier_step = 1000;
-			else if (srate <= 7000000)
-				currier_step = 2000;
-			else if (srate <= 10000000)
-				currier_step = 3000;
-			else
-				currier_step = 5000;
+	if (srate >= 10000000) {
+		if (stv0900_check_timing_lock(intp, d) == TRUE) {
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x15);
+			lock = stv0900_get_demod_lock(intp, d, demod_timeout);
+		} else
+			lock = FALSE;
 
-			nb_steps = ((search_range / 1000) / currier_step);
-			nb_steps /= 2;
-			nb_steps = (2 * (nb_steps + 1));
-			if (nb_steps < 0)
-				nb_steps = 2;
-			else if (nb_steps > 12)
-				nb_steps = 12;
+		return lock;
+	}
 
-			current_step = 1;
-			direction = 1;
+	if (intp->chip_id <= 0x20) {
+		if (srate <= 1000000)
+			currier_step = 500;
+		else if (srate <= 4000000)
+			currier_step = 1000;
+		else if (srate <= 7000000)
+			currier_step = 2000;
+		else if (srate <= 10000000)
+			currier_step = 3000;
+		else
+			currier_step = 5000;
+
+		if (srate >= 2000000) {
 			timeout = (demod_timeout / 3);
 			if (timeout > 1000)
 				timeout = 1000;
+		} else
+			timeout = (demod_timeout / 2);
+	} else {
+		/*cut 3.0 */
+		currier_step = srate / 4000;
+		timeout = (demod_timeout * 3) / 4;
+	}
 
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				if (lock == FALSE) {
-					tuner_freq = i_params->tuner1_freq;
-					i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
-
-					while ((current_step <= nb_steps) && (lock == FALSE)) {
-
-						if (direction > 0)
-							tuner_freq += (current_step * currier_step);
-						else
-							tuner_freq -= (current_step * currier_step);
+	nb_steps = ((search_range / 1000) / currier_step);
 
-						stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-						if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
-							stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-							stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-						}
+	if ((nb_steps % 2) != 0)
+		nb_steps += 1;
 
-						stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
-						stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-						stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-						lock = stv0900_get_demod_lock(i_params, demod, timeout);
-						direction *= -1;
-						current_step++;
-					}
-				}
-				break;
-			case STV0900_DEMOD_2:
-				if (lock == FALSE) {
-					tuner_freq = i_params->tuner2_freq;
-					i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
+	if (nb_steps <= 0)
+		nb_steps = 2;
+	else if (nb_steps > 12)
+		nb_steps = 12;
 
-					while ((current_step <= nb_steps) && (lock == FALSE)) {
+	current_step = 1;
+	direction = 1;
 
-						if (direction > 0)
-							tuner_freq += (current_step * currier_step);
-						else
-							tuner_freq -= (current_step * currier_step);
+	if (intp->chip_id <= 0x20) {
+		tuner_freq = intp->freq[d];
+		intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
+				intp->rolloff) + intp->symbol_rate[d];
+	} else
+		tuner_freq = 0;
 
-						stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-						if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) {
-							stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-							stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-							stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-						}
+	while ((current_step <= nb_steps) && (lock == FALSE)) {
+		if (direction > 0)
+			tuner_freq += (current_step * currier_step);
+		else
+			tuner_freq -= (current_step * currier_step);
 
-						stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
-						stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-						stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-						lock = stv0900_get_demod_lock(i_params, demod, timeout);
-						direction *= -1;
-						current_step++;
-					}
-				}
-				break;
-			}
+		if (intp->chip_id <= 0x20) {
+			stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			stv0900_write_reg(intp, CFRINIT1, 0);
+			stv0900_write_reg(intp, CFRINIT0, 0);
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x15);
+		} else {
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			freq = (tuner_freq * 65536) / (intp->mclk / 1000);
+			stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
+			stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, DMDISTATE, 0x05);
 		}
+
+		lock = stv0900_get_demod_lock(intp, d, timeout);
+		direction *= -1;
+		current_step++;
 	}
 
 	return	lock;
@@ -931,9 +665,7 @@ static void stv0900_get_lock_timeout(s32
 		} else if (srate <= 20000000) {
 			(*demod_timeout) = 400;
 			(*fec_timeout) = 130;
-		}
-
-		else {
+		} else {
 			(*demod_timeout) = 300;
 			(*fec_timeout) = 100;
 		}
@@ -946,95 +678,77 @@ static void stv0900_get_lock_timeout(s32
 		(*demod_timeout) /= 2;
 }
 
-static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 
-	s32 vth_reg;
-
-	dprintk(KERN_INFO "%s\n", __func__);
+	s32 vth_reg = VTH12;
 
-	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+	dprintk("%s\n", __func__);
 
-	stv0900_write_reg(i_params, vth_reg++, 0xd0);
-	stv0900_write_reg(i_params, vth_reg++, 0x7d);
-	stv0900_write_reg(i_params, vth_reg++, 0x53);
-	stv0900_write_reg(i_params, vth_reg++, 0x2F);
-	stv0900_write_reg(i_params, vth_reg++, 0x24);
-	stv0900_write_reg(i_params, vth_reg++, 0x1F);
+	stv0900_write_reg(intp, vth_reg++, 0xd0);
+	stv0900_write_reg(intp, vth_reg++, 0x7d);
+	stv0900_write_reg(intp, vth_reg++, 0x53);
+	stv0900_write_reg(intp, vth_reg++, 0x2f);
+	stv0900_write_reg(intp, vth_reg++, 0x24);
+	stv0900_write_reg(intp, vth_reg++, 0x1f);
 }
 
-static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
-				   enum fe_stv0900_search_standard Standard,
-				   enum fe_stv0900_fec PunctureRate,
+static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
+				   enum fe_stv0900_search_standard standard,
+				   enum fe_stv0900_fec fec,
 				   enum fe_stv0900_demod_num demod)
 {
+	dprintk("%s: ViterbiStandard = ", __func__);
 
-	s32 fecmReg,
-	prvitReg;
-
-	dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		fecmReg = R0900_P1_FECM;
-		prvitReg = R0900_P1_PRVIT;
-		break;
-	case STV0900_DEMOD_2:
-		fecmReg = R0900_P2_FECM;
-		prvitReg = R0900_P2_PRVIT;
-		break;
-	}
-
-	switch (Standard) {
+	switch (standard) {
 	case STV0900_AUTO_SEARCH:
 		dprintk("Auto\n");
-		stv0900_write_reg(i_params, fecmReg, 0x10);
-		stv0900_write_reg(i_params, prvitReg, 0x3F);
+		stv0900_write_reg(intp, FECM, 0x10);
+		stv0900_write_reg(intp, PRVIT, 0x3f);
 		break;
 	case STV0900_SEARCH_DVBS1:
 		dprintk("DVBS1\n");
-		stv0900_write_reg(i_params, fecmReg, 0x00);
-		switch (PunctureRate) {
+		stv0900_write_reg(intp, FECM, 0x00);
+		switch (fec) {
 		case STV0900_FEC_UNKNOWN:
 		default:
-			stv0900_write_reg(i_params, prvitReg, 0x2F);
+			stv0900_write_reg(intp, PRVIT, 0x2f);
 			break;
 		case STV0900_FEC_1_2:
-			stv0900_write_reg(i_params, prvitReg, 0x01);
+			stv0900_write_reg(intp, PRVIT, 0x01);
 			break;
 		case STV0900_FEC_2_3:
-			stv0900_write_reg(i_params, prvitReg, 0x02);
+			stv0900_write_reg(intp, PRVIT, 0x02);
 			break;
 		case STV0900_FEC_3_4:
-			stv0900_write_reg(i_params, prvitReg, 0x04);
+			stv0900_write_reg(intp, PRVIT, 0x04);
 			break;
 		case STV0900_FEC_5_6:
-			stv0900_write_reg(i_params, prvitReg, 0x08);
+			stv0900_write_reg(intp, PRVIT, 0x08);
 			break;
 		case STV0900_FEC_7_8:
-			stv0900_write_reg(i_params, prvitReg, 0x20);
+			stv0900_write_reg(intp, PRVIT, 0x20);
 			break;
 		}
 
 		break;
 	case STV0900_SEARCH_DSS:
 		dprintk("DSS\n");
-		stv0900_write_reg(i_params, fecmReg, 0x80);
-		switch (PunctureRate) {
+		stv0900_write_reg(intp, FECM, 0x80);
+		switch (fec) {
 		case STV0900_FEC_UNKNOWN:
 		default:
-			stv0900_write_reg(i_params, prvitReg, 0x13);
+			stv0900_write_reg(intp, PRVIT, 0x13);
 			break;
 		case STV0900_FEC_1_2:
-			stv0900_write_reg(i_params, prvitReg, 0x01);
+			stv0900_write_reg(intp, PRVIT, 0x01);
 			break;
 		case STV0900_FEC_2_3:
-			stv0900_write_reg(i_params, prvitReg, 0x02);
+			stv0900_write_reg(intp, PRVIT, 0x02);
 			break;
 		case STV0900_FEC_6_7:
-			stv0900_write_reg(i_params, prvitReg, 0x10);
+			stv0900_write_reg(intp, PRVIT, 0x10);
 			break;
 		}
 		break;
@@ -1043,340 +757,277 @@ static void stv0900_set_viterbi_standard
 	}
 }
 
-static void stv0900_track_optimization(struct dvb_frontend *fe)
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
+						enum fe_stv0900_demod_num demod)
 {
-	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
-	enum fe_stv0900_demod_num demod = state->demod;
-
-	s32 srate, pilots, aclc, freq1, freq0,
-		i = 0, timed, timef, blindTunSw = 0;
+	enum fe_stv0900_fec prate;
+	s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
 
-	enum fe_stv0900_rolloff rolloff;
-	enum fe_stv0900_modcode foundModcod;
+	switch (rate_fld) {
+	case 13:
+		prate = STV0900_FEC_1_2;
+		break;
+	case 18:
+		prate = STV0900_FEC_2_3;
+		break;
+	case 21:
+		prate = STV0900_FEC_3_4;
+		break;
+	case 24:
+		prate = STV0900_FEC_5_6;
+		break;
+	case 25:
+		prate = STV0900_FEC_6_7;
+		break;
+	case 26:
+		prate = STV0900_FEC_7_8;
+		break;
+	default:
+		prate = STV0900_FEC_UNKNOWN;
+		break;
+	}
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	return prate;
+}
 
-	srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-	srate += stv0900_get_timing_offst(i_params, srate, demod);
+void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
+					enum fe_stv0900_demod_num demod,
+					u32 srate)
+{
+	if (intp->chip_id >= 0x30) {
+		if (srate >= 15000000) {
+			stv0900_write_reg(intp, ACLC, 0x2b);
+			stv0900_write_reg(intp, BCLC, 0x1a);
+		} else if ((srate >= 7000000) && (15000000 > srate)) {
+			stv0900_write_reg(intp, ACLC, 0x0c);
+			stv0900_write_reg(intp, BCLC, 0x1b);
+		} else if (srate < 7000000) {
+			stv0900_write_reg(intp, ACLC, 0x2c);
+			stv0900_write_reg(intp, BCLC, 0x1c);
+		}
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_rslts.standard) {
-		case STV0900_DVBS1_STANDARD:
-			if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			}
+	} else { /*cut 2.0 and 1.x*/
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+	}
 
-			stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DSS_STANDARD:
-			if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			}
+}
 
-			stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DVBS2_STANDARD:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0);
-			if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) {
-				foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
-				pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
-				aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
-				if (foundModcod <= STV0900_QPSK_910)
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
-				else if (foundModcod <= STV0900_8PSK_910) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
-				}
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *intp = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
 
-				if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
-					if (foundModcod <= STV0900_16APSK_910) {
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
-					} else if (foundModcod <= STV0900_32APSK_910) {
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
-					}
-				}
+	s32	srate,
+		pilots,
+		aclc,
+		freq1,
+		freq0,
+		i = 0,
+		timed,
+		timef,
+		blind_tun_sw = 0,
+		modulation;
 
-			} else {
-				aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
-				if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+	enum fe_stv0900_rolloff rolloff;
+	enum fe_stv0900_modcode foundModcod;
 
-				else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
-				} else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
-				} else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
-				}
+	dprintk("%s\n", __func__);
 
-			}
+	srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+	srate += stv0900_get_timing_offst(intp, srate, demod);
 
-			if (i_params->chip_id <= 0x11) {
-				if (i_params->demod_mode != STV0900_SINGLE)
-					stv0900_activate_s2_modcode(i_params, demod);
+	switch (intp->result[demod].standard) {
+	case STV0900_DVBS1_STANDARD:
+	case STV0900_DSS_STANDARD:
+		dprintk("%s: found DVB-S or DSS\n", __func__);
+		if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
+			stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+			stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+		}
 
-			}
+		stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
+		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
 
-			stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
-			break;
-		case STV0900_UNKNOWN_STANDARD:
-		default:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+		if (intp->chip_id < 0x30) {
+			stv0900_write_reg(intp, ERRCTRL1, 0x75);
 			break;
 		}
 
-		freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
-		freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
-		rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
-			stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-			stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
-			blindTunSw = 1;
+		if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
+			stv0900_write_reg(intp, GAUSSR0, 0x98);
+			stv0900_write_reg(intp, CCIR0, 0x18);
+		} else {
+			stv0900_write_reg(intp, GAUSSR0, 0x18);
+			stv0900_write_reg(intp, CCIR0, 0x18);
 		}
 
-		if (i_params->chip_id >= 0x20) {
-			if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a);
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0);
+		stv0900_write_reg(intp, ERRCTRL1, 0x75);
+		break;
+	case STV0900_DVBS2_STANDARD:
+		dprintk("%s: found DVB-S2\n", __func__);
+		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_reg(intp, ACLC, 0);
+		stv0900_write_reg(intp, BCLC, 0);
+		if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
+			foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
+			pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+			aclc = stv0900_get_optim_carr_loop(srate,
+							foundModcod,
+							pilots,
+							intp->chip_id);
+			if (foundModcod <= STV0900_QPSK_910)
+				stv0900_write_reg(intp, ACLC2S2Q, aclc);
+			else if (foundModcod <= STV0900_8PSK_910) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S28, aclc);
 			}
-		}
-
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
-
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
-
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-
-		if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) {
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-			i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
 
-			if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
-				if (i_params->dmd1_srch_algo != STV0900_WARM_START)
-					stv0900_set_bandwidth(fe, i_params->tuner1_bw);
+			if ((intp->demod_mode == STV0900_SINGLE) &&
+					(foundModcod > STV0900_8PSK_910)) {
+				if (foundModcod <= STV0900_16APSK_910) {
+					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+					stv0900_write_reg(intp, ACLC2S216A,
+									aclc);
+				} else if (foundModcod <= STV0900_32APSK_910) {
+					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+					stv0900_write_reg(intp,	ACLC2S232A,
+									aclc);
+				}
 			}
 
-			if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000))
-				msleep(50);
-			else
-				msleep(5);
-
-			stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
-
-			if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-				i = 0;
-				while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-					stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-					stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-					stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-					i++;
-				}
+		} else {
+			modulation = intp->result[demod].modulation;
+			aclc = stv0900_get_optim_short_carr_loop(srate,
+					modulation, intp->chip_id);
+			if (modulation == STV0900_QPSK)
+				stv0900_write_reg(intp, ACLC2S2Q, aclc);
+			else if (modulation == STV0900_8PSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S28, aclc);
+			} else if (modulation == STV0900_16APSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S216A, aclc);
+			} else if (modulation == STV0900_32APSK) {
+				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+				stv0900_write_reg(intp, ACLC2S232A, aclc);
 			}
 
 		}
 
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+		if (intp->chip_id <= 0x11) {
+			if (intp->demod_mode != STV0900_SINGLE)
+				stv0900_activate_s2_modcod(intp, demod);
 
-		if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
-			stv0900_set_viterbi_tracq(i_params, demod);
+		}
 
+		stv0900_write_reg(intp, ERRCTRL1, 0x67);
 		break;
+	case STV0900_UNKNOWN_STANDARD:
+	default:
+		dprintk("%s: found unknown standard\n", __func__);
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		break;
+	}
 
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_rslts.standard) {
-		case STV0900_DVBS1_STANDARD:
-
-			if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DSS_STANDARD:
-			if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
-				stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-				stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			}
-
-			stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
-			stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-			break;
-		case STV0900_DVBS2_STANDARD:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
-			if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
-				foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
-				pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
-				aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
-				if (foundModcod <= STV0900_QPSK_910)
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
-				else if (foundModcod <= STV0900_8PSK_910) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
-				}
-
-				if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
-					if (foundModcod <= STV0900_16APSK_910) {
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
-					} else if (foundModcod <= STV0900_32APSK_910) {
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-						stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
-					}
-
-				}
-
-			} else {
-				aclc = stv0900_get_optim_short_carr_loop(srate,
-									i_params->dmd2_rslts.modulation,
-									i_params->chip_id);
-
-				if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
-
-				else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
-				} else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
-				} else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
-					stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
-				}
-			}
+	freq1 = stv0900_read_reg(intp, CFR2);
+	freq0 = stv0900_read_reg(intp, CFR1);
+	rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+		stv0900_write_reg(intp, SFRSTEP, 0x00);
+		stv0900_write_bits(intp, SCAN_ENABLE, 0);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
+		stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
+		blind_tun_sw = 1;
+		if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
+			stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
 
-			stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+	}
 
-			break;
-		case STV0900_UNKNOWN_STANDARD:
-		default:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			break;
+	if (intp->chip_id >= 0x20) {
+		if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+				(intp->srch_standard[demod] ==
+							STV0900_SEARCH_DSS) ||
+				(intp->srch_standard[demod] ==
+							STV0900_AUTO_SEARCH)) {
+			stv0900_write_reg(intp, VAVSRVIT, 0x0a);
+			stv0900_write_reg(intp, VITSCALE, 0x0);
 		}
+	}
 
-		freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
-		freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
-		rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
-			stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
-			stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
-			blindTunSw = 1;
-		}
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x08);
 
-		if (i_params->chip_id >= 0x20) {
-			if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a);
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
-			}
-		}
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0x0a);
 
-		if (i_params->chip_id < 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
+	stv0900_write_reg(intp, AGC2REF, 0x38);
 
-		if (i_params->chip_id == 0x10)
-			stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
+	if ((intp->chip_id >= 0x20) ||
+			(blind_tun_sw == 1) ||
+			(intp->symbol_rate[demod] < 10000000)) {
+		stv0900_write_reg(intp, CFRINIT1, freq1);
+		stv0900_write_reg(intp, CFRINIT0, freq0);
+		intp->bw[demod] = stv0900_carrier_width(srate,
+					intp->rolloff) + 10000000;
 
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-			i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+		if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
+			if (intp->srch_algo[demod] != STV0900_WARM_START)
+				stv0900_set_bandwidth(fe, intp->bw[demod]);
+		}
 
-			if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
-				if (i_params->dmd2_srch_algo != STV0900_WARM_START)
-					stv0900_set_bandwidth(fe, i_params->tuner2_bw);
-			}
+		if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
+				(intp->symbol_rate[demod] < 10000000))
+			msleep(50);
+		else
+			msleep(5);
 
-			if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000))
-				msleep(50);
-			else
-				msleep(5);
+		stv0900_get_lock_timeout(&timed, &timef, srate,
+						STV0900_WARM_START);
 
-			stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
-			if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-				i = 0;
-				while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-					stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-					stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-					stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-					i++;
-				}
+		if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
+			stv0900_write_reg(intp, DMDISTATE, 0x1f);
+			stv0900_write_reg(intp, CFRINIT1, freq1);
+			stv0900_write_reg(intp, CFRINIT0, freq0);
+			stv0900_write_reg(intp, DMDISTATE, 0x18);
+			i = 0;
+			while ((stv0900_get_demod_lock(intp,
+							demod,
+							timed / 2) == FALSE) &&
+						(i <= 2)) {
+				stv0900_write_reg(intp, DMDISTATE, 0x1f);
+				stv0900_write_reg(intp, CFRINIT1, freq1);
+				stv0900_write_reg(intp, CFRINIT0, freq0);
+				stv0900_write_reg(intp, DMDISTATE, 0x18);
+				i++;
 			}
 		}
 
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+	}
 
-		if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD))
-			stv0900_set_viterbi_tracq(i_params, demod);
+	if (intp->chip_id >= 0x20)
+		stv0900_write_reg(intp, CARFREQ, 0x49);
+
+	if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
+			(intp->result[demod].standard == STV0900_DSS_STANDARD))
+		stv0900_set_viterbi_tracq(intp, demod);
 
-		break;
-	}
 }
 
-static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
+static int stv0900_get_fec_lock(struct stv0900_internal *intp,
+				enum fe_stv0900_demod_num demod, s32 time_out)
 {
-	s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
+	s32 timer = 0, lock = 0;
 
 	enum fe_stv0900_search_state dmd_state;
 
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
-	dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+	dprintk("%s\n", __func__);
 
-	dmd_state = stv0900_get_bits(i_params, header_field);
+	dmd_state = stv0900_get_bits(intp, HEADER_MODE);
 
 	while ((timer < time_out) && (lock == 0)) {
 		switch (dmd_state) {
@@ -1386,10 +1037,10 @@ static int stv0900_get_fec_lock(struct s
 			lock = 0;
 			break;
 		case STV0900_DVBS2_FOUND:
-			lock = stv0900_get_bits(i_params, pktdelin_field);
+			lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
 			break;
 		case STV0900_DVBS_FOUND:
-			lock = stv0900_get_bits(i_params, lock_vit_field);
+			lock = stv0900_get_bits(intp, LOCKEDVIT);
 			break;
 		}
 
@@ -1400,46 +1051,44 @@ static int stv0900_get_fec_lock(struct s
 	}
 
 	if (lock)
-		dprintk("DEMOD FEC LOCK OK\n");
+		dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
 	else
-		dprintk("DEMOD FEC LOCK FAIL\n");
+		dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
 
 	return lock;
 }
 
-static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
+static int stv0900_wait_for_lock(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod,
 				s32 dmd_timeout, s32 fec_timeout)
 {
 
-	s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld;
-
-	dprintk(KERN_INFO "%s\n", __func__);
+	s32 timer = 0, lock = 0;
 
-	dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
-	dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+	dprintk("%s\n", __func__);
 
-	lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
+	lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
 
 	if (lock)
-		lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
+		lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
 
 	if (lock) {
 		lock = 0;
 
-		dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout);
+		dprintk("%s: Timer = %d, time_out = %d\n",
+				__func__, timer, fec_timeout);
 
 		while ((timer < fec_timeout) && (lock == 0)) {
-			lock = stv0900_get_bits(i_params, str_merg_lock_fld);
+			lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
 			msleep(1);
 			timer++;
 		}
 	}
 
 	if (lock)
-		dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
+		dprintk("%s: DEMOD LOCK OK\n", __func__);
 	else
-		dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
+		dprintk("%s: DEMOD LOCK FAIL\n", __func__);
 
 	if (lock)
 		return TRUE;
@@ -1451,43 +1100,43 @@ enum fe_stv0900_tracking_standard stv090
 						enum fe_stv0900_demod_num demod)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_tracking_standard fnd_standard;
-	s32 state_field,
-	dss_dvb_field;
-
-	dprintk(KERN_INFO "%s\n", __func__);
 
-	dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
-	dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB);
+	int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
 
-	if (stv0900_get_bits(i_params, state_field) == 2)
+	switch (hdr_mode) {
+	case 2:
 		fnd_standard = STV0900_DVBS2_STANDARD;
-
-	else if (stv0900_get_bits(i_params, state_field) == 3) {
-		if (stv0900_get_bits(i_params, dss_dvb_field) == 1)
+		break;
+	case 3:
+		if (stv0900_get_bits(intp, DSS_DVB) == 1)
 			fnd_standard = STV0900_DSS_STANDARD;
 		else
 			fnd_standard = STV0900_DVBS1_STANDARD;
-	} else
+
+		break;
+	default:
 		fnd_standard = STV0900_UNKNOWN_STANDARD;
+	}
+
+	dprintk("%s: standard %d\n", __func__, fnd_standard);
 
 	return fnd_standard;
 }
 
-static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk,
+static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 cfr_field2, cfr_field1, cfr_field0,
-		derot, rem1, rem2, intval1, intval2;
-
-	dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2);
-	dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1);
-	dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0);
+	s32	derot,
+		rem1,
+		rem2,
+		intval1,
+		intval2;
 
-	derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
-		(stv0900_get_bits(i_params, cfr_field1) << 8) +
-		(stv0900_get_bits(i_params, cfr_field0));
+	derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
+		(stv0900_get_bits(intp, CAR_FREQ1) << 8) +
+		(stv0900_get_bits(intp, CAR_FREQ0));
 
 	derot = ge2comp(derot, 24);
 	intval1 = mclk >> 12;
@@ -1505,7 +1154,7 @@ static u32 stv0900_get_tuner_freq(struct
 {
 	struct dvb_frontend_ops	*frontend_ops = NULL;
 	struct dvb_tuner_ops *tuner_ops = NULL;
-	u32 frequency = 0;
+	u32 freq = 0;
 
 	if (&fe->ops)
 		frontend_ops = &fe->ops;
@@ -1514,304 +1163,159 @@ static u32 stv0900_get_tuner_freq(struct
 		tuner_ops = &frontend_ops->tuner_ops;
 
 	if (tuner_ops->get_frequency) {
-		if ((tuner_ops->get_frequency(fe, &frequency)) < 0)
+		if ((tuner_ops->get_frequency(fe, &freq)) < 0)
 			dprintk("%s: Invalid parameter\n", __func__);
 		else
-			dprintk("%s: Frequency=%d\n", __func__, frequency);
-
-	}
-
-	return frequency;
-}
-
-static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
-						enum fe_stv0900_demod_num demod)
-{
-	s32 rate_fld, vit_curpun_fld;
-	enum fe_stv0900_fec prate;
-
-	dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
-	rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
+			dprintk("%s: Frequency=%d\n", __func__, freq);
 
-	switch (rate_fld) {
-	case 13:
-		prate = STV0900_FEC_1_2;
-		break;
-	case 18:
-		prate = STV0900_FEC_2_3;
-		break;
-	case 21:
-		prate = STV0900_FEC_3_4;
-		break;
-	case 24:
-		prate = STV0900_FEC_5_6;
-		break;
-	case 25:
-		prate = STV0900_FEC_6_7;
-		break;
-	case 26:
-		prate = STV0900_FEC_7_8;
-		break;
-	default:
-		prate = STV0900_FEC_UNKNOWN;
-		break;
 	}
 
-	return prate;
+	return freq;
 }
 
-static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+static enum
+fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 	enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
-	s32 offsetFreq,
-	srate_offset,
-	i = 0;
+	struct stv0900_signal_info *result = &intp->result[demod];
+	s32	offsetFreq,
+		srate_offset;
+	int	i = 0,
+		d = demod;
 
 	u8 timing;
 
 	msleep(5);
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
-			i = 0;
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c);
-
-			while ((i <= 50) && (timing != 0) && (timing != 0xFF)) {
-				timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
-				msleep(5);
-				i += 5;
-			}
-		}
+	if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
+		timing = stv0900_read_reg(intp, TMGREG2);
+		i = 0;
+		stv0900_write_reg(intp, SFRSTEP, 0x5c);
 
-		i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod);
-		i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe);
-		offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
-		i_params->dmd1_rslts.frequency += offsetFreq;
-		i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod);
-		i_params->dmd1_rslts.symbol_rate += srate_offset;
-		i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod);
-		i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
-		i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
-		i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1;
-		i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
-		switch (i_params->dmd1_rslts.standard) {
-		case STV0900_DVBS2_STANDARD:
-			i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD);
-			if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_QPSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_8PSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_16APSK;
-			else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910)
-				i_params->dmd1_rslts.modulation = STV0900_32APSK;
-			else
-				i_params->dmd1_rslts.modulation = STV0900_UNKNOWN;
-			break;
-		case STV0900_DVBS1_STANDARD:
-		case STV0900_DSS_STANDARD:
-			i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
-			i_params->dmd1_rslts.modulation = STV0900_QPSK;
-			break;
-		default:
-			break;
+		while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+			timing = stv0900_read_reg(intp, TMGREG2);
+			msleep(5);
+			i += 5;
 		}
+	}
 
-		if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
-			offsetFreq =	i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
-			i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
-			if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
-					range = STV0900_RANGEOK;
-				else
-					range = STV0900_OUTOFRANGE;
-
-		} else {
-			if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				range = STV0900_OUTOFRANGE;
-		}
+	result->standard = stv0900_get_standard(fe, d);
+	result->frequency = stv0900_get_tuner_freq(fe);
+	offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
+	result->frequency += offsetFreq;
+	result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
+	srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
+	result->symbol_rate += srate_offset;
+	result->fec = stv0900_get_vit_fec(intp, d);
+	result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
+	result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+	result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
+	result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+	switch (result->standard) {
+	case STV0900_DVBS2_STANDARD:
+		result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
+		if (result->modcode <= STV0900_QPSK_910)
+			result->modulation = STV0900_QPSK;
+		else if (result->modcode <= STV0900_8PSK_910)
+			result->modulation = STV0900_8PSK;
+		else if (result->modcode <= STV0900_16APSK_910)
+			result->modulation = STV0900_16APSK;
+		else if (result->modcode <= STV0900_32APSK_910)
+			result->modulation = STV0900_32APSK;
+		else
+			result->modulation = STV0900_UNKNOWN;
 		break;
-	case STV0900_DEMOD_2:
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
-			i = 0;
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c);
-
-			while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
-				timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
-				msleep(5);
-				i += 5;
-			}
-		}
-
-		i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
-		i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
-		offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
-		i_params->dmd2_rslts.frequency += offsetFreq;
-		i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
-		i_params->dmd2_rslts.symbol_rate += srate_offset;
-		i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
-		i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
-		i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
-		i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
-		i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
-		switch (i_params->dmd2_rslts.standard) {
-		case STV0900_DVBS2_STANDARD:
-			i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
-			if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_QPSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_8PSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_16APSK;
-			else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
-				i_params->dmd2_rslts.modulation = STV0900_32APSK;
-			else
-				i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
-			break;
-		case STV0900_DVBS1_STANDARD:
-		case STV0900_DSS_STANDARD:
-			i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
-			i_params->dmd2_rslts.modulation = STV0900_QPSK;
-			break;
-		default:
-			break;
-		}
+	case STV0900_DVBS1_STANDARD:
+	case STV0900_DSS_STANDARD:
+		result->spectrum = stv0900_get_bits(intp, IQINV);
+		result->modulation = STV0900_QPSK;
+		break;
+	default:
+		break;
+	}
 
-		if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) {
-			offsetFreq =	i_params->dmd2_rslts.frequency - i_params->tuner2_freq;
-			i_params->tuner2_freq = stv0900_get_tuner_freq(fe);
+	if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
+				(intp->symbol_rate[d] < 10000000)) {
+		offsetFreq = result->frequency - intp->freq[d];
+		intp->freq[d] = stv0900_get_tuner_freq(fe);
+		if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+			range = STV0900_RANGEOK;
+		else if (ABS(offsetFreq) <=
+				(stv0900_carrier_width(result->symbol_rate,
+						result->rolloff) / 2000))
+			range = STV0900_RANGEOK;
 
-			if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
-					range = STV0900_RANGEOK;
-				else
-					range = STV0900_OUTOFRANGE;
-		} else {
-			if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
-				range = STV0900_RANGEOK;
-			else
-				range = STV0900_OUTOFRANGE;
-		}
+	} else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+		range = STV0900_RANGEOK;
 
-		break;
-	}
+	dprintk("%s: range %d\n", __func__, range);
 
 	return range;
 }
 
-static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+static enum
+fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-
-	s32 srate, demod_timeout,
-		fec_timeout, freq1, freq0;
 	enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		i_params->dmd1_rslts.locked = FALSE;
-		if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) {
-			srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			srate += stv0900_get_timing_offst(i_params, srate, demod);
-			if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH)
-				stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
-
-			stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
-			freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
-			freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-			stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-			if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-				i_params->dmd1_rslts.locked = TRUE;
-				signal_type = stv0900_get_signal_params(fe);
-				stv0900_track_optimization(fe);
-			} else {
-				stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
-				if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-					i_params->dmd1_rslts.locked = TRUE;
-					signal_type = stv0900_get_signal_params(fe);
-					stv0900_track_optimization(fe);
-				}
-
-			}
-
-		} else
-			i_params->dmd1_rslts.locked = FALSE;
-
-		break;
-	case STV0900_DEMOD_2:
-		i_params->dmd2_rslts.locked = FALSE;
-		if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
-			srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			srate += stv0900_get_timing_offst(i_params, srate, demod);
+	s32	srate,
+		demod_timeout,
+		fec_timeout,
+		freq1,
+		freq0;
 
-			if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
-				stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+	intp->result[demod].locked = FALSE;
 
-			stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
-			freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
-			freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
-			stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+	if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
+		srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+		srate += stv0900_get_timing_offst(intp, srate, demod);
+		if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
+			stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
 
-			if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-				i_params->dmd2_rslts.locked = TRUE;
+		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+					srate, STV0900_WARM_START);
+		freq1 = stv0900_read_reg(intp, CFR2);
+		freq0 = stv0900_read_reg(intp, CFR1);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_bits(intp, SPECINV_CONTROL,
+					STV0900_IQ_FORCE_SWAPPED);
+		stv0900_write_reg(intp, DMDISTATE, 0x1c);
+		stv0900_write_reg(intp, CFRINIT1, freq1);
+		stv0900_write_reg(intp, CFRINIT0, freq0);
+		stv0900_write_reg(intp, DMDISTATE, 0x18);
+		if (stv0900_wait_for_lock(intp, demod,
+				demod_timeout, fec_timeout) == TRUE) {
+			intp->result[demod].locked = TRUE;
+			signal_type = stv0900_get_signal_params(fe);
+			stv0900_track_optimization(fe);
+		} else {
+			stv0900_write_bits(intp, SPECINV_CONTROL,
+					STV0900_IQ_FORCE_NORMAL);
+			stv0900_write_reg(intp, DMDISTATE, 0x1c);
+			stv0900_write_reg(intp, CFRINIT1, freq1);
+			stv0900_write_reg(intp, CFRINIT0, freq0);
+			stv0900_write_reg(intp, DMDISTATE, 0x18);
+			if (stv0900_wait_for_lock(intp, demod,
+					demod_timeout, fec_timeout) == TRUE) {
+				intp->result[demod].locked = TRUE;
 				signal_type = stv0900_get_signal_params(fe);
 				stv0900_track_optimization(fe);
-			} else {
-				stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
-				stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
-				stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
-
-				if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
-					i_params->dmd2_rslts.locked = TRUE;
-					signal_type = stv0900_get_signal_params(fe);
-					stv0900_track_optimization(fe);
-				}
-
 			}
 
-		} else
-			i_params->dmd1_rslts.locked = FALSE;
+		}
 
-		break;
-	}
+	} else
+		intp->result[demod].locked = FALSE;
 
 	return signal_type;
 }
 
-static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 	u32 minagc2level = 0xffff,
@@ -1820,105 +1324,54 @@ static u16 stv0900_blind_check_agc2_min_
 
 	s32 i, j, nb_steps, direction;
 
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
-
-		stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
-
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
-
-		stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		nb_steps = -1 + (i_params->dmd1_srch_range / 1000000);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
-
-		if (nb_steps < 0)
-			nb_steps = 1;
-
-		direction = 1;
+	dprintk("%s\n", __func__);
 
-		freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+	stv0900_write_reg(intp, AGC2REF, 0x38);
+	stv0900_write_bits(intp, SCAN_ENABLE, 0);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
 
-		init_freq = 0;
+	stv0900_write_bits(intp, AUTO_GUP, 1);
+	stv0900_write_bits(intp, AUTO_GLOW, 1);
 
-		for (i = 0; i < nb_steps; i++) {
-			if (direction > 0)
-				init_freq = init_freq + (freq_step * i);
-			else
-				init_freq = init_freq - (freq_step * i);
+	stv0900_write_reg(intp, DMDT0M, 0x0);
 
-			direction *= -1;
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
-			msleep(10);
-			agc2level = 0;
+	stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+	nb_steps = -1 + (intp->srch_range[demod] / 1000000);
+	nb_steps /= 2;
+	nb_steps = (2 * nb_steps) + 1;
 
-			for (j = 0; j < 10; j++)
-				agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-						| stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+	if (nb_steps < 0)
+		nb_steps = 1;
 
-			agc2level /= 10;
+	direction = 1;
 
-			if (agc2level < minagc2level)
-				minagc2level = agc2level;
-		}
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
-		stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
+	freq_step = (1000000 << 8) / (intp->mclk >> 8);
 
-		if (nb_steps < 0)
-			nb_steps = 1;
+	init_freq = 0;
 
-		direction = 1;
-		freq_step = (1000000 << 8) / (i_params->mclk >> 8);
-		init_freq = 0;
-		for (i = 0; i < nb_steps; i++) {
-			if (direction > 0)
-				init_freq = init_freq + (freq_step * i);
-			else
-				init_freq = init_freq - (freq_step * i);
+	for (i = 0; i < nb_steps; i++) {
+		if (direction > 0)
+			init_freq = init_freq + (freq_step * i);
+		else
+			init_freq = init_freq - (freq_step * i);
 
-			direction *= -1;
+		direction *= -1;
+		stv0900_write_reg(intp, DMDISTATE, 0x5C);
+		stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, init_freq  & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x58);
+		msleep(10);
+		agc2level = 0;
 
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
+		for (j = 0; j < 10; j++)
+			agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
 
-			msleep(10);
-			agc2level = 0;
-			for (j = 0; j < 10; j++)
-				agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-						| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+		agc2level /= 10;
 
-			agc2level /= 10;
+		if (agc2level < minagc2level)
+			minagc2level = agc2level;
 
-			if (agc2level < minagc2level)
-				minagc2level = agc2level;
-		}
-		break;
 	}
 
 	return (u16)minagc2level;
@@ -1927,336 +1380,192 @@ static u16 stv0900_blind_check_agc2_min_
 static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	int timingLock = FALSE;
+	int timing_lck = FALSE;
 	s32 i, timingcpt = 0,
 		direction = 1,
 		nb_steps,
 		current_step = 0,
 		tuner_freq;
+	u32 agc2_th,
+		coarse_srate = 0,
+		agc2_integr = 0,
+		currier_step = 1200;
 
-	u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+	if (intp->chip_id >= 0x30)
+		agc2_th = 0x2e00;
+	else
+		agc2_th = 0x1f00;
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F);
-		stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0);
-		stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0);
-		stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
-		stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50);
+	stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+	stv0900_write_reg(intp, TMGCFG, 0x12);
+	stv0900_write_reg(intp, TMGTHRISE, 0xf0);
+	stv0900_write_reg(intp, TMGTHFALL, 0xe0);
+	stv0900_write_bits(intp, SCAN_ENABLE, 1);
+	stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
+	stv0900_write_reg(intp, SFRUP1, 0x83);
+	stv0900_write_reg(intp, SFRUP0, 0xc0);
+	stv0900_write_reg(intp, SFRLOW1, 0x82);
+	stv0900_write_reg(intp, SFRLOW0, 0xa0);
+	stv0900_write_reg(intp, DMDT0M, 0x0);
+	stv0900_write_reg(intp, AGC2REF, 0x50);
 
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a);
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95);
-		} else {
-			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
-			stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73);
-		}
+	if (intp->chip_id >= 0x30) {
+		stv0900_write_reg(intp, CARFREQ, 0x99);
+		stv0900_write_reg(intp, SFRSTEP, 0x98);
+	} else if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, CARFREQ, 0x6a);
+		stv0900_write_reg(intp, SFRSTEP, 0x95);
+	} else {
+		stv0900_write_reg(intp, CARFREQ, 0xed);
+		stv0900_write_reg(intp, SFRSTEP, 0x73);
+	}
 
-		if (i_params->dmd1_symbol_rate <= 2000000)
-			currier_step = 1000;
-		else if (i_params->dmd1_symbol_rate <= 5000000)
-			currier_step = 2000;
-		else if (i_params->dmd1_symbol_rate <= 12000000)
-			currier_step = 3000;
-		else
+	if (intp->symbol_rate[demod] <= 2000000)
+		currier_step = 1000;
+	else if (intp->symbol_rate[demod] <= 5000000)
+		currier_step = 2000;
+	else if (intp->symbol_rate[demod] <= 12000000)
+		currier_step = 3000;
+	else
 			currier_step = 5000;
 
-		nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
-
-		if (nb_steps < 0)
-			nb_steps = 1;
-
-		else if (nb_steps > 10) {
-			nb_steps = 11;
-			currier_step = (i_params->dmd1_srch_range / 1000) / 10;
-		}
-
-		current_step = 0;
-
-		direction = 1;
-		tuner_freq = i_params->tuner1_freq;
-
-		while ((timingLock == FALSE) && (current_step < nb_steps)) {
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
-			stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
-
-			msleep(50);
-
-			for (i = 0; i < 10; i++) {
-				if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
-					timingcpt++;
-
-				agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
-
-			}
-
-			agc2_integr /= 10;
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			current_step++;
-			direction *= -1;
-
-			dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt);
-
-			if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) {
-				timingLock = TRUE;
-			}
-
-			else if (current_step < nb_steps) {
-				if (direction > 0)
-					tuner_freq += (current_step * currier_step);
-				else
-					tuner_freq -= (current_step * currier_step);
+	nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
+	nb_steps /= 2;
+	nb_steps = (2 * nb_steps) + 1;
 
-				stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
-			}
-		}
+	if (nb_steps < 0)
+		nb_steps = 1;
+	else if (nb_steps > 10) {
+		nb_steps = 11;
+		currier_step = (intp->srch_range[demod] / 1000) / 10;
+	}
 
-		if (timingLock == FALSE)
-			coarse_srate = 0;
-		else
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		break;
-	case STV0900_DEMOD_2:
-		stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
-		stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
-		stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
-		stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
-		stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
-		stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
-		stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
-		stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
-		stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
+	current_step = 0;
+	direction = 1;
 
-		if (i_params->chip_id >= 0x20) {
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
-		} else {
-			stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
-			stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
-		}
+	tuner_freq = intp->freq[demod];
 
-		if (i_params->dmd2_symbol_rate <= 2000000)
-			currier_step = 1000;
-		else if (i_params->dmd2_symbol_rate <= 5000000)
-			currier_step = 2000;
-		else if (i_params->dmd2_symbol_rate <= 12000000)
-			currier_step = 3000;
-		else
-			currier_step = 5000;
+	while ((timing_lck == FALSE) && (current_step < nb_steps)) {
+		stv0900_write_reg(intp, DMDISTATE, 0x5f);
+		stv0900_write_bits(intp, DEMOD_MODE, 0);
 
+		msleep(50);
 
-		nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
-		nb_steps /= 2;
-		nb_steps = (2 * nb_steps) + 1;
+		for (i = 0; i < 10; i++) {
+			if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+				timingcpt++;
 
-		if (nb_steps < 0)
-			nb_steps = 1;
-		else if (nb_steps > 10) {
-			nb_steps = 11;
-			currier_step = (i_params->dmd2_srch_range / 1000) / 10;
+			agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
+					stv0900_read_reg(intp, AGC2I0);
 		}
 
-		current_step = 0;
-		direction = 1;
-		tuner_freq = i_params->tuner2_freq;
-
-		while ((timingLock == FALSE) && (current_step < nb_steps)) {
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F);
-			stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0);
-
-			msleep(50);
-			timingcpt = 0;
-
-			for (i = 0; i < 20; i++) {
-				if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
-					timingcpt++;
-				agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
-			}
+		agc2_integr /= 10;
+		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+		current_step++;
+		direction *= -1;
 
-			agc2_integr /= 20;
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-			if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
-				timingLock = TRUE;
-			else {
-				current_step++;
-				direction *= -1;
+		dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
+			" tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
+			tuner_freq, agc2_integr, coarse_srate, timingcpt);
 
-				if (direction > 0)
-					tuner_freq += (current_step * currier_step);
-				else
-					tuner_freq -= (current_step * currier_step);
+		if ((timingcpt >= 5) &&
+				(agc2_integr < agc2_th) &&
+				(coarse_srate < 55000000) &&
+				(coarse_srate > 850000))
+			timing_lck = TRUE;
+		else if (current_step < nb_steps) {
+			if (direction > 0)
+				tuner_freq += (current_step * currier_step);
+			else
+				tuner_freq -= (current_step * currier_step);
 
-				stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
-			}
+			stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]);
 		}
-
-		if (timingLock == FALSE)
-			coarse_srate = 0;
-		else
-			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-		break;
 	}
 
+	if (timing_lck == FALSE)
+		coarse_srate = 0;
+	else
+		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+
 	return coarse_srate;
 }
 
 static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	u32 coarse_srate,
-	coarse_freq,
-	symb;
-
-	coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
-						| stv0900_read_reg(i_params, R0900_P1_CFR1);
-		symb = 13 * (coarse_srate / 10);
-
-		if (symb < i_params->dmd1_symbol_rate)
-			coarse_srate = 0;
-		else {
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-			stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
-			stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
-
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
-
-			if (coarse_srate > 3000000) {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
-
-				symb = 10 * (coarse_srate / 13);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
-
-				symb = (coarse_srate / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
-			} else {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
-
-				symb = 10 * (coarse_srate / 14);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+	u32	coarse_srate,
+		coarse_freq,
+		symb,
+		symbmax,
+		symbmin,
+		symbcomp;
 
-				symb = (coarse_srate / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
-			}
+	coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
 
-			stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
-		}
-		break;
-	case STV0900_DEMOD_2:
-		coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
-						| stv0900_read_reg(i_params, R0900_P2_CFR1);
+	if (coarse_srate > 3000000) {
+		symbmax = 13 * (coarse_srate / 10);
+		symbmax = (symbmax / 1000) * 65536;
+		symbmax /= (intp->mclk / 1000);
 
-		symb = 13 * (coarse_srate / 10);
+		symbmin = 10 * (coarse_srate / 13);
+		symbmin = (symbmin / 1000)*65536;
+		symbmin /= (intp->mclk / 1000);
 
-		if (symb < i_params->dmd2_symbol_rate)
-			coarse_srate = 0;
-		else {
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
-			stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
-			stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+		symb = (coarse_srate / 1000) * 65536;
+		symb /= (intp->mclk / 1000);
+	} else {
+		symbmax = 13 * (coarse_srate / 10);
+		symbmax = (symbmax / 100) * 65536;
+		symbmax /= (intp->mclk / 100);
 
-			if (i_params->chip_id >= 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+		symbmin = 10 * (coarse_srate / 14);
+		symbmin = (symbmin / 100) * 65536;
+		symbmin /= (intp->mclk / 100);
 
-			if (coarse_srate > 3000000) {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+		symb = (coarse_srate / 100) * 65536;
+		symb /= (intp->mclk / 100);
+	}
 
-				symb = 10 * (coarse_srate / 13);
-				symb = (symb / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
+	symbcomp = 13 * (coarse_srate / 10);
+		coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
+					| stv0900_read_reg(intp, CFR1);
 
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+	if (symbcomp < intp->symbol_rate[demod])
+		coarse_srate = 0;
+	else {
+		stv0900_write_reg(intp, DMDISTATE, 0x1f);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
+		stv0900_write_reg(intp, TMGTHRISE, 0x20);
+		stv0900_write_reg(intp, TMGTHFALL, 0x00);
+		stv0900_write_reg(intp, TMGCFG, 0xd2);
+		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+		stv0900_write_reg(intp, AGC2REF, 0x38);
 
-				symb = (coarse_srate / 1000) * 65536;
-				symb /= (i_params->mclk / 1000);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
-			} else {
-				symb = 13 * (coarse_srate / 10);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+		if (intp->chip_id >= 0x30)
+			stv0900_write_reg(intp, CARFREQ, 0x79);
+		else if (intp->chip_id >= 0x20)
+			stv0900_write_reg(intp, CARFREQ, 0x49);
+		else
+			stv0900_write_reg(intp, CARFREQ, 0xed);
 
-				symb = 10 * (coarse_srate / 14);
-				symb = (symb / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
-				stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+		stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
 
-				symb = (coarse_srate / 100) * 65536;
-				symb /= (i_params->mclk / 100);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
-				stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
-			}
+		stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
+		stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
 
-			stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq  & 0xff);
-			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
-		}
+		stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
+		stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
 
-		break;
+		stv0900_write_reg(intp, DMDT0M, 0x20);
+		stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
+		stv0900_write_reg(intp, CFRINIT0, coarse_freq  & 0xff);
+		stv0900_write_reg(intp, DMDISTATE, 0x15);
 	}
 
 	return coarse_srate;
@@ -2265,163 +1574,135 @@ static u32 stv0900_search_srate_fine(str
 static int stv0900_blind_search_algo(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
-	u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min;
-	u32 coarse_srate;
-	int lock = FALSE, coarse_fail = FALSE;
-	s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow;
-	u16 agc2_integr;
-	u8 dstatus2;
+	u8	k_ref_tmg,
+		k_ref_tmg_max,
+		k_ref_tmg_min;
+	u32	coarse_srate,
+		agc2_th;
+	int	lock = FALSE,
+		coarse_fail = FALSE;
+	s32	demod_timeout = 500,
+		fec_timeout = 50,
+		fail_cpt,
+		i,
+		agc2_overflow;
+	u16	agc2_int;
+	u8	dstatus2;
 
-	dprintk(KERN_INFO "%s\n", __func__);
+	dprintk("%s\n", __func__);
 
-	if (i_params->chip_id < 0x20) {
+	if (intp->chip_id < 0x20) {
 		k_ref_tmg_max = 233;
 		k_ref_tmg_min = 143;
 	} else {
-		k_ref_tmg_max = 120;
-		k_ref_tmg_min = 30;
+		k_ref_tmg_max = 110;
+		k_ref_tmg_min = 10;
 	}
 
-	agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod);
-
-	if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) {
-		lock = FALSE;
-
-	} else {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			if (i_params->chip_id == 0x10)
-				stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
-
-			if (i_params->chip_id < 0x20)
-				stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
-
-			stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
-			stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
-
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
-			}
-
-			kref_tmg_reg = R0900_P1_KREFTMG;
-			break;
-		case STV0900_DEMOD_2:
-			if (i_params->chip_id == 0x10)
-				stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
+	if (intp->chip_id <= 0x20)
+		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
+	else
+		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
 
-			if (i_params->chip_id < 0x20)
-				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+	agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
 
-			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
-			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+	if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH)
+		return FALSE;
 
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
-				stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
-				stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
-			}
+	if (intp->chip_id == 0x10)
+		stv0900_write_reg(intp, CORRELEXP, 0xaa);
 
-			kref_tmg_reg = R0900_P2_KREFTMG;
-			break;
-		}
+	if (intp->chip_id < 0x20)
+		stv0900_write_reg(intp, CARHDR, 0x55);
+	else
+		stv0900_write_reg(intp, CARHDR, 0x20);
 
-		k_ref_tmg = k_ref_tmg_max;
+	if (intp->chip_id <= 0x20)
+		stv0900_write_reg(intp, CARCFG, 0xc4);
+	else
+		stv0900_write_reg(intp, CARCFG, 0x6);
 
-		do {
-			stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg);
-			if (stv0900_search_srate_coarse(fe) != 0) {
-				coarse_srate = stv0900_search_srate_fine(fe);
+	stv0900_write_reg(intp, RTCS2, 0x44);
 
-				if (coarse_srate != 0) {
-					stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
-					lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
-				} else
-					lock = FALSE;
-			} else {
-				fail_cpt = 0;
-				agc2_overflow = 0;
+	if (intp->chip_id >= 0x20) {
+		stv0900_write_reg(intp, EQUALCFG, 0x41);
+		stv0900_write_reg(intp, FFECFG, 0x41);
+		stv0900_write_reg(intp, VITSCALE, 0x82);
+		stv0900_write_reg(intp, VAVSRVIT, 0x0);
+	}
 
-				switch (demod) {
-				case STV0900_DEMOD_1:
-				default:
-					for (i = 0; i < 10; i++) {
-						agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+	k_ref_tmg = k_ref_tmg_max;
 
-						if (agc2_integr >= 0xff00)
-							agc2_overflow++;
+	do {
+		stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
+		if (stv0900_search_srate_coarse(fe) != 0) {
+			coarse_srate = stv0900_search_srate_fine(fe);
 
-						dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
+			if (coarse_srate != 0) {
+				stv0900_get_lock_timeout(&demod_timeout,
+							&fec_timeout,
+							coarse_srate,
+							STV0900_BLIND_SEARCH);
+				lock = stv0900_get_demod_lock(intp,
+							demod,
+							demod_timeout);
+			} else
+				lock = FALSE;
+		} else {
+			fail_cpt = 0;
+			agc2_overflow = 0;
 
-						if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
-							fail_cpt++;
-					}
-					break;
-				case STV0900_DEMOD_2:
-					for (i = 0; i < 10; i++) {
-						agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
-								| stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+			for (i = 0; i < 10; i++) {
+				agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
+					| stv0900_read_reg(intp, AGC2I0);
 
-						if (agc2_integr >= 0xff00)
-							agc2_overflow++;
+				if (agc2_int >= 0xff00)
+					agc2_overflow++;
 
-						dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
+				dstatus2 = stv0900_read_reg(intp, DSTATUS2);
 
-						if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
-							fail_cpt++;
-					}
-					break;
-				}
+				if (((dstatus2 & 0x1) == 0x1) &&
+						((dstatus2 >> 7) == 1))
+					fail_cpt++;
+			}
 
-				if ((fail_cpt > 7) || (agc2_overflow > 7))
-					coarse_fail = TRUE;
+			if ((fail_cpt > 7) || (agc2_overflow > 7))
+				coarse_fail = TRUE;
 
-				lock = FALSE;
-			}
-			k_ref_tmg -= 30;
-		} while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE));
-	}
+			lock = FALSE;
+		}
+		k_ref_tmg -= 30;
+	} while ((k_ref_tmg >= k_ref_tmg_min) &&
+				(lock == FALSE) &&
+				(coarse_fail == FALSE));
 
 	return lock;
 }
 
-static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
-	s32 vth_reg;
-
-	dprintk(KERN_INFO "%s\n", __func__);
+	s32 vth_reg = VTH12;
 
-	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+	dprintk("%s\n", __func__);
 
-	stv0900_write_reg(i_params, vth_reg++, 0x96);
-	stv0900_write_reg(i_params, vth_reg++, 0x64);
-	stv0900_write_reg(i_params, vth_reg++, 0x36);
-	stv0900_write_reg(i_params, vth_reg++, 0x23);
-	stv0900_write_reg(i_params, vth_reg++, 0x1E);
-	stv0900_write_reg(i_params, vth_reg++, 0x19);
+	stv0900_write_reg(intp, vth_reg++, 0x96);
+	stv0900_write_reg(intp, vth_reg++, 0x64);
+	stv0900_write_reg(intp, vth_reg++, 0x36);
+	stv0900_write_reg(intp, vth_reg++, 0x23);
+	stv0900_write_reg(intp, vth_reg++, 0x1e);
+	stv0900_write_reg(intp, vth_reg++, 0x19);
 }
 
-static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+static void stv0900_set_search_standard(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_num demod)
 {
 
-	int sstndrd;
-
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	sstndrd = i_params->dmd1_srch_standard;
-	if (demod == 1)
-		sstndrd = i_params->dmd2_srch_stndrd;
+	dprintk("%s\n", __func__);
 
-	switch (sstndrd) {
+	switch (intp->srch_standard[demod]) {
 	case STV0900_SEARCH_DVBS1:
 		dprintk("Search Standard = DVBS1\n");
 		break;
@@ -2436,129 +1717,74 @@ static void stv0900_set_search_standard(
 		break;
 	}
 
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		switch (i_params->dmd1_srch_standard) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22);
-
-			stv0900_set_viterbi_acq(i_params, demod);
-			stv0900_set_viterbi_standard(i_params,
-						i_params->dmd1_srch_standard,
-						i_params->dmd1_fec, demod);
-
-			break;
-		case STV0900_SEARCH_DVBS2:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE) {
-				if (i_params->chip_id <= 0x11)
-					stv0900_stop_all_s2_modcod(i_params, demod);
-				else
-					stv0900_activate_s2_modcode(i_params, demod);
-
-			} else
-				stv0900_activate_s2_modcode_single(i_params, demod);
-
-			stv0900_set_viterbi_tracq(i_params, demod);
+	switch (intp->srch_standard[demod]) {
+	case STV0900_SEARCH_DVBS1:
+	case STV0900_SEARCH_DSS:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+		stv0900_write_bits(intp, STOP_CLKVIT, 0);
+		stv0900_set_dvbs1_track_car_loop(intp,
+						demod,
+						intp->symbol_rate[demod]);
+		stv0900_write_reg(intp, CAR2CFG, 0x22);
 
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
-			stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE) {
-				if (i_params->chip_id <= 0x11)
-					stv0900_stop_all_s2_modcod(i_params, demod);
-				else
-					stv0900_activate_s2_modcode(i_params, demod);
+		stv0900_set_viterbi_acq(intp, demod);
+		stv0900_set_viterbi_standard(intp,
+					intp->srch_standard[demod],
+					intp->fec[demod], demod);
 
-			} else
-				stv0900_activate_s2_modcode_single(i_params, demod);
+		break;
+	case STV0900_SEARCH_DVBS2:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_bits(intp, STOP_CLKVIT, 1);
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+			stv0900_write_reg(intp, CAR2CFG, 0x26);
+		else
+			stv0900_write_reg(intp, CAR2CFG, 0x66);
 
-			if (i_params->dmd1_symbol_rate >= 2000000)
-				stv0900_set_viterbi_acq(i_params, demod);
+		if (intp->demod_mode != STV0900_SINGLE) {
+			if (intp->chip_id <= 0x11)
+				stv0900_stop_all_s2_modcod(intp, demod);
 			else
-				stv0900_set_viterbi_tracq(i_params, demod);
+				stv0900_activate_s2_modcod(intp, demod);
 
-			stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod);
+		} else
+			stv0900_activate_s2_modcod_single(intp, demod);
 
-			break;
-		}
-		break;
-	case STV0900_DEMOD_2:
-		switch (i_params->dmd2_srch_stndrd) {
-		case STV0900_SEARCH_DVBS1:
-		case STV0900_SEARCH_DSS:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
-			stv0900_set_viterbi_acq(i_params, demod);
-			stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
-			break;
-		case STV0900_SEARCH_DVBS2:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE)
-				stv0900_activate_s2_modcode(i_params, demod);
-			else
-				stv0900_activate_s2_modcode_single(i_params, demod);
+		stv0900_set_viterbi_tracq(intp, demod);
 
-			stv0900_set_viterbi_tracq(i_params, demod);
-			break;
-		case STV0900_AUTO_SEARCH:
-		default:
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
-			stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
-			stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
-			stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
-			stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
-			stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
-			if (i_params->demod_mode != STV0900_SINGLE)
-				stv0900_activate_s2_modcode(i_params, demod);
-			else
-				stv0900_activate_s2_modcode_single(i_params, demod);
+		break;
+	case STV0900_AUTO_SEARCH:
+	default:
+		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+		stv0900_write_bits(intp, STOP_CLKVIT, 0);
+		stv0900_write_reg(intp, ACLC, 0x1a);
+		stv0900_write_reg(intp, BCLC, 0x09);
+		stv0900_set_dvbs1_track_car_loop(intp,
+						demod,
+						intp->symbol_rate[demod]);
+		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+			stv0900_write_reg(intp, CAR2CFG, 0x26);
+		else
+			stv0900_write_reg(intp, CAR2CFG, 0x66);
 
-			if (i_params->dmd2_symbol_rate >= 2000000)
-				stv0900_set_viterbi_acq(i_params, demod);
+		if (intp->demod_mode != STV0900_SINGLE) {
+			if (intp->chip_id <= 0x11)
+				stv0900_stop_all_s2_modcod(intp, demod);
 			else
-				stv0900_set_viterbi_tracq(i_params, demod);
+				stv0900_activate_s2_modcod(intp, demod);
 
-			stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+		} else
+			stv0900_activate_s2_modcod_single(intp, demod);
 
-			break;
-		}
+		stv0900_set_viterbi_tracq(intp, demod);
+		stv0900_set_viterbi_standard(intp,
+						intp->srch_standard[demod],
+						intp->fec[demod], demod);
 
 		break;
 	}
@@ -2567,10 +1793,11 @@ static void stv0900_set_search_standard(
 enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
 {
 	struct stv0900_state *state = fe->demodulator_priv;
-	struct stv0900_internal *i_params = state->internal;
+	struct stv0900_internal *intp = state->internal;
 	enum fe_stv0900_demod_num demod = state->demod;
 
-	s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+	s32 demod_timeout = 500, fec_timeout = 50;
+	s32 aq_power, agc1_power, i;
 
 	int lock = FALSE, low_sr = FALSE;
 
@@ -2578,157 +1805,117 @@ enum fe_stv0900_signal_type stv0900_algo
 	enum fe_stv0900_search_algo algo;
 	int no_signal = FALSE;
 
-	dprintk(KERN_INFO "%s\n", __func__);
-
-	switch (demod) {
-	case STV0900_DEMOD_1:
-	default:
-		algo = i_params->dmd1_srch_algo;
-
-		stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
-		stream_merger_field = F0900_P1_RST_HWARE;
-
-		stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+	dprintk("%s\n", __func__);
 
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
+	algo = intp->srch_algo[demod];
+	stv0900_write_bits(intp, RST_HWARE, 1);
+	stv0900_write_reg(intp, DMDISTATE, 0x5c);
+	if (intp->chip_id >= 0x20) {
+		if (intp->symbol_rate[demod] > 5000000)
+			stv0900_write_reg(intp, CORRELABS, 0x9e);
 		else
-			stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88);
-
-		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo);
-
-		if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
-			i_params->tuner1_bw = 2 * 36000000;
-
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
-			stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
-
-			stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
-		} else {
-			stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
-
-			if (i_params->dmd1_symbol_rate < 2000000)
-				stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
-			else
-				stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
-
-			stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
-
-				if (i_params->dmd1_srch_algo == STV0900_COLD_START)
-					i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
-				else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
-					i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
-			} else {
-				stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
-				i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
-			}
-
-			stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
-
-			stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
-			if (i_params->dmd1_symbol_rate >= 10000000)
-				low_sr = FALSE;
-			else
-				low_sr = TRUE;
-
-		}
-
-		stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
-
-		stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
-		stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
-
-		stv0900_set_search_standard(i_params, demod);
+			stv0900_write_reg(intp, CORRELABS, 0x82);
+	} else
+		stv0900_write_reg(intp, CORRELABS, 0x88);
 
-		if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH)
-			stv0900_start_search(i_params, demod);
-		break;
-	case STV0900_DEMOD_2:
-		algo = i_params->dmd2_srch_algo;
+	stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+				intp->symbol_rate[demod],
+				intp->srch_algo[demod]);
 
-		stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+		intp->bw[demod] = 2 * 36000000;
 
-		stream_merger_field = F0900_P2_RST_HWARE;
+		stv0900_write_reg(intp, TMGCFG2, 0xc0);
+		stv0900_write_reg(intp, CORRELMANT, 0x70);
 
-		stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+		stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+	} else {
+		stv0900_write_reg(intp, DMDT0M, 0x20);
+		stv0900_write_reg(intp, TMGCFG, 0xd2);
 
-		if (i_params->chip_id >= 0x20)
-			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+		if (intp->symbol_rate[demod] < 2000000)
+			stv0900_write_reg(intp, CORRELMANT, 0x63);
 		else
-			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+			stv0900_write_reg(intp, CORRELMANT, 0x70);
 
-		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
+		stv0900_write_reg(intp, AGC2REF, 0x38);
 
-		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
-			i_params->tuner2_bw = 2 * 36000000;
+		intp->bw[demod] =
+				stv0900_carrier_width(intp->symbol_rate[demod],
+								intp->rolloff);
+		if (intp->chip_id >= 0x20) {
+			stv0900_write_reg(intp, KREFTMG, 0x5a);
 
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
-			stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+			if (intp->srch_algo[demod] == STV0900_COLD_START) {
+				intp->bw[demod] += 10000000;
+				intp->bw[demod] *= 15;
+				intp->bw[demod] /= 10;
+			} else if (intp->srch_algo[demod] == STV0900_WARM_START)
+				intp->bw[demod] += 10000000;
 
-			stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
 		} else {
-			stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+			stv0900_write_reg(intp, KREFTMG, 0xc1);
+			intp->bw[demod] += 10000000;
+			intp->bw[demod] *= 15;
+			intp->bw[demod] /= 10;
+		}
 
-			if (i_params->dmd2_symbol_rate < 2000000)
-				stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
-			else
-				stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+		stv0900_write_reg(intp, TMGCFG2, 0xc1);
 
-			if (i_params->dmd2_symbol_rate >= 10000000)
-				stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
-			else
-				stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60);
+		stv0900_set_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		stv0900_set_max_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		stv0900_set_min_symbol_rate(intp, intp->mclk,
+					intp->symbol_rate[demod], demod);
+		if (intp->symbol_rate[demod] >= 10000000)
+			low_sr = FALSE;
+		else
+			low_sr = TRUE;
 
-			if (i_params->chip_id >= 0x20) {
-				stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
+	}
 
-				if (i_params->dmd2_srch_algo == STV0900_COLD_START)
-					i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
-							i_params->rolloff) + 10000000)) / 10;
-				else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
-					i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
-							i_params->rolloff) + 10000000;
-			} else {
-				stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
-				i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
-									i_params->rolloff) + 10000000)) / 10;
-			}
+	stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
 
-			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+	agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+				stv0900_get_bits(intp, AGCIQ_VALUE0));
 
-			stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
-			if (i_params->dmd2_symbol_rate >= 10000000)
-				low_sr = FALSE;
-			else
-				low_sr = TRUE;
+	aq_power = 0;
 
-		}
+	if (agc1_power == 0) {
+		for (i = 0; i < 5; i++)
+			aq_power += (stv0900_get_bits(intp, POWER_I) +
+					stv0900_get_bits(intp, POWER_Q)) / 2;
 
-		stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
+		aq_power /= 5;
+	}
 
-		stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv);
-		stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+	if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
+		intp->result[demod].locked = FALSE;
+		signal_type = STV0900_NOAGC1;
+		dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
+	} else {
+		stv0900_write_bits(intp, SPECINV_CONTROL,
+					intp->srch_iq_inv[demod]);
+		if (intp->chip_id <= 0x20) /*cut 2.0*/
+			stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+		else /*cut 3.0*/
+			stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
 
-		stv0900_set_search_standard(i_params, demod);
+		stv0900_set_search_standard(intp, demod);
 
-		if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
-			stv0900_start_search(i_params, demod);
-		break;
+		if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
+			stv0900_start_search(intp, demod);
 	}
 
-	if (i_params->chip_id == 0x12) {
-		stv0900_write_bits(i_params, stream_merger_field, 0);
+	if (signal_type == STV0900_NOAGC1)
+		return signal_type;
+
+	if (intp->chip_id == 0x12) {
+		stv0900_write_bits(intp, RST_HWARE, 0);
 		msleep(3);
-		stv0900_write_bits(i_params, stream_merger_field, 1);
-		stv0900_write_bits(i_params, stream_merger_field, 0);
+		stv0900_write_bits(intp, RST_HWARE, 1);
+		stv0900_write_bits(intp, RST_HWARE, 0);
 	}
 
 	if (algo == STV0900_BLIND_SEARCH)
@@ -2736,12 +1923,12 @@ enum fe_stv0900_signal_type stv0900_algo
 	else if (algo == STV0900_COLD_START)
 		lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
 	else if (algo == STV0900_WARM_START)
-		lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+		lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
 
 	if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
 		if (low_sr == FALSE) {
-			if (stv0900_check_timing_lock(i_params, demod) == TRUE)
-				lock = stv0900_sw_algo(i_params, demod);
+			if (stv0900_check_timing_lock(intp, demod) == TRUE)
+				lock = stv0900_sw_algo(intp, demod);
 		}
 	}
 
@@ -2750,98 +1937,64 @@ enum fe_stv0900_signal_type stv0900_algo
 
 	if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
 		stv0900_track_optimization(fe);
-		if (i_params->chip_id <= 0x11) {
-			if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) {
+		if (intp->chip_id <= 0x11) {
+			if ((stv0900_get_standard(fe, 0) ==
+						STV0900_DVBS1_STANDARD) &&
+			   (stv0900_get_standard(fe, 1) ==
+						STV0900_DVBS1_STANDARD)) {
 				msleep(20);
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 			} else {
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 				msleep(3);
-				stv0900_write_bits(i_params, stream_merger_field, 1);
-				stv0900_write_bits(i_params, stream_merger_field, 0);
+				stv0900_write_bits(intp, RST_HWARE, 1);
+				stv0900_write_bits(intp, RST_HWARE, 0);
 			}
-		} else if (i_params->chip_id == 0x20) {
-			stv0900_write_bits(i_params, stream_merger_field, 0);
+
+		} else if (intp->chip_id >= 0x20) {
+			stv0900_write_bits(intp, RST_HWARE, 0);
 			msleep(3);
-			stv0900_write_bits(i_params, stream_merger_field, 1);
-			stv0900_write_bits(i_params, stream_merger_field, 0);
+			stv0900_write_bits(intp, RST_HWARE, 1);
+			stv0900_write_bits(intp, RST_HWARE, 0);
 		}
 
-		if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) {
+		if (stv0900_wait_for_lock(intp, demod,
+					fec_timeout, fec_timeout) == TRUE) {
 			lock = TRUE;
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				i_params->dmd1_rslts.locked = TRUE;
-				if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) {
-					stv0900_set_dvbs2_rolloff(i_params, demod);
-					stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40);
-					stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0);
-					stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
-				} else {
-					stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
-				}
-
-				stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
-				stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
-				break;
-			case STV0900_DEMOD_2:
-				i_params->dmd2_rslts.locked = TRUE;
-
-				if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
-					stv0900_set_dvbs2_rolloff(i_params, demod);
-					stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
-					stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
-					stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
-				} else {
-					stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
-				}
-
-				stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
-
-				stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
-				break;
+			intp->result[demod].locked = TRUE;
+			if (intp->result[demod].standard ==
+						STV0900_DVBS2_STANDARD) {
+				stv0900_set_dvbs2_rolloff(intp, demod);
+				stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
+				stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
+				stv0900_write_reg(intp, ERRCTRL1, 0x67);
+			} else {
+				stv0900_write_reg(intp, ERRCTRL1, 0x75);
 			}
+
+			stv0900_write_reg(intp, FBERCPT4, 0);
+			stv0900_write_reg(intp, ERRCTRL2, 0xc1);
 		} else {
 			lock = FALSE;
 			signal_type = STV0900_NODATA;
-			no_signal = stv0900_check_signal_presence(i_params, demod);
+			no_signal = stv0900_check_signal_presence(intp, demod);
 
-			switch (demod) {
-			case STV0900_DEMOD_1:
-			default:
-				i_params->dmd1_rslts.locked = FALSE;
-				break;
-			case STV0900_DEMOD_2:
-				i_params->dmd2_rslts.locked = FALSE;
-				break;
-			}
+				intp->result[demod].locked = FALSE;
 		}
 	}
 
-	if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) {
-		switch (demod) {
-		case STV0900_DEMOD_1:
-		default:
-			if (i_params->chip_id <= 0x11) {
-				if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
-						(i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
-					signal_type = stv0900_dvbs1_acq_workaround(fe);
-			} else
-				i_params->dmd1_rslts.locked = FALSE;
+	if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
+		return signal_type;
 
-			break;
-		case STV0900_DEMOD_2:
-			if (i_params->chip_id <= 0x11) {
-				if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
-						(i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
-					signal_type = stv0900_dvbs1_acq_workaround(fe);
-			} else
-				i_params->dmd2_rslts.locked = FALSE;
-			break;
-		}
+	if (intp->chip_id > 0x11) {
+		intp->result[demod].locked = FALSE;
+		return signal_type;
 	}
 
+	if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
+	   (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
+		signal_type = stv0900_dvbs1_acq_workaround(fe);
+
 	return signal_type;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.c	2010-02-24 13:52:17.000000000 -0500
@@ -825,7 +825,7 @@ static int stv090x_set_min_srate(struct
 		sym /= (state->mclk >> 7);
 	}
 
-	if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */
+	if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
 		goto err;
@@ -1238,6 +1238,8 @@ static int stv090x_delivery_search(struc
 				goto err;
 		}
 
+		if (stv090x_set_vit_thtracq(state) < 0)
+			goto err;
 		break;
 
 	case STV090x_SEARCH_AUTO:
@@ -1278,17 +1280,8 @@ static int stv090x_delivery_search(struc
 				goto err;
 		}
 
-		if (state->srate >= 2000000) {
-			/* Srate >= 2MSPS, Viterbi threshold to acquire */
-			if (stv090x_set_vit_thacq(state) < 0)
-				goto err;
-		} else {
-			/* Srate < 2MSPS, Reset Viterbi thresholdto track
-			 * and then re-acquire
-			 */
-			if (stv090x_set_vit_thtracq(state) < 0)
-				goto err;
-		}
+		if (stv090x_set_vit_thacq(state) < 0)
+			goto err;
 
 		if (stv090x_set_viterbi(state) < 0)
 			goto err;
@@ -1317,7 +1310,7 @@ static int stv090x_start_search(struct s
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
 				goto err;
-			if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0)
+			if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
 				goto err;
 			if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
 				goto err;
@@ -1371,7 +1364,7 @@ static int stv090x_start_search(struct s
 
 		if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0)
+		if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
 			goto err;
 
 		freq *= -1;
@@ -1422,6 +1415,9 @@ static int stv090x_start_search(struct s
 	if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
 		goto err;
 
+	if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
+		goto err;
+
 	if (state->dev_ver >= 0x20) {
 		/*Frequency offset detector setting*/
 		if (state->srate < 2000000) {
@@ -1430,20 +1426,22 @@ static int stv090x_start_search(struct s
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
 					goto err;
 			} else {
-				/* Cut 2 */
+				/* Cut 3 */
 				if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
 					goto err;
 			}
 			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
 				goto err;
-		}
-
-		if (state->srate < 10000000) {
+		} else if (state->srate < 10000000) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
 				goto err;
+			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+				goto err;
 		} else {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
 				goto err;
+			if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+				goto err;
 		}
 	} else {
 		if (state->srate < 10000000) {
@@ -1485,14 +1483,14 @@ err:
 
 static int stv090x_get_agc2_min_level(struct stv090x_state *state)
 {
-	u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg;
+	u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
 	s32 i, j, steps, dir;
 
 	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
 		goto err;
 	reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
-	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
+	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
 	if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 		goto err;
 
@@ -1509,10 +1507,8 @@ static int stv090x_get_agc2_min_level(st
 	if (stv090x_set_srate(state, 1000000) < 0)
 		goto err;
 
-	steps  = -1 + state->search_range / 1000000;
-	steps /= 2;
-	steps  = (2 * steps) + 1;
-	if (steps < 0)
+	steps  = state->search_range / 1000000;
+	if (steps <= 0)
 		steps = 1;
 
 	dir = 1;
@@ -1525,7 +1521,7 @@ static int stv090x_get_agc2_min_level(st
 		else
 			freq_init = freq_init - (freq_step * i);
 
-		dir = -1;
+		dir *= -1;
 
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
 			goto err;
@@ -1536,13 +1532,14 @@ static int stv090x_get_agc2_min_level(st
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
 			goto err;
 		msleep(10);
+
+		agc2 = 0;
 		for (j = 0; j < 10; j++) {
-			agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
-			agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+			agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+				STV090x_READ_DEMOD(state, AGC2I0);
 		}
 		agc2 /= 10;
-		agc2_min = 0xffff;
-		if (agc2 < 0xffff)
+		if (agc2 < agc2_min)
 			agc2_min = agc2;
 	}
 
@@ -1584,6 +1581,12 @@ static u32 stv090x_srate_srch_coarse(str
 	int tmg_lock = 0, i;
 	s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
 	u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
+	u32 agc2th;
+
+	if (state->dev_ver >= 0x30)
+		agc2th = 0x2e00;
+	else
+		agc2th = 0x1f00;
 
 	reg = STV090x_READ_DEMOD(state, DMDISTATE);
 	STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
@@ -1591,13 +1594,15 @@ static u32 stv090x_srate_srch_coarse(str
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
 		goto err;
+	if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
+		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
 		goto err;
 	reg = STV090x_READ_DEMOD(state, DMDCFGMD);
 	STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
-	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
+	STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
 	if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 		goto err;
 
@@ -1611,13 +1616,13 @@ static u32 stv090x_srate_srch_coarse(str
 		goto err;
 	if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
 		goto err;
-	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0)
+	if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
 		goto err;
 
 	if (state->dev_ver >= 0x30) {
 		if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
+		if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
 			goto err;
 
 	} else if (state->dev_ver >= 0x20) {
@@ -1652,23 +1657,31 @@ static u32 stv090x_srate_srch_coarse(str
 	while ((!tmg_lock) && (cur_step < steps)) {
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
 			goto err;
-		reg = STV090x_READ_DEMOD(state, DMDISTATE);
-		STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */
-		if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+		if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
+			goto err;
+		if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
+			goto err;
+		/* trigger acquisition */
+		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
 			goto err;
 		msleep(50);
 		for (i = 0; i < 10; i++) {
 			reg = STV090x_READ_DEMOD(state, DSTATUS);
 			if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
 				tmg_cpt++;
-			agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
-			agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+			agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+				STV090x_READ_DEMOD(state, AGC2I0);
 		}
 		agc2 /= 10;
 		srate_coarse = stv090x_get_srate(state, state->mclk);
 		cur_step++;
 		dir *= -1;
-		if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000))
+		if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
+		    (srate_coarse < 50000000) && (srate_coarse > 850000))
 			tmg_lock = 1;
 		else if (cur_step < steps) {
 			if (dir > 0)
@@ -1681,7 +1694,7 @@ static u32 stv090x_srate_srch_coarse(str
 				goto err;
 
 			if (state->config->tuner_set_frequency) {
-				if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+				if (state->config->tuner_set_frequency(fe, freq) < 0)
 					goto err;
 			}
 
@@ -1738,7 +1751,7 @@ static u32 stv090x_srate_srch_fine(struc
 	else {
 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
 			goto err;
-		if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0)
+		if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
 			goto err;
 		if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
 			goto err;
@@ -1751,6 +1764,9 @@ static u32 stv090x_srate_srch_fine(struc
 		if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
 			goto err;
 
+		if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+			goto err;
+
 		if (state->dev_ver >= 0x30) {
 			if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
 				goto err;
@@ -1856,12 +1872,12 @@ static int stv090x_get_dmdlock(struct st
 static int stv090x_blind_search(struct stv090x_state *state)
 {
 	u32 agc2, reg, srate_coarse;
-	s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i;
+	s32 cpt_fail, agc2_ovflw, i;
 	u8 k_ref, k_max, k_min;
 	int coarse_fail, lock;
 
-	k_max = 120;
-	k_min = 30;
+	k_max = 110;
+	k_min = 10;
 
 	agc2 = stv090x_get_agc2_min_level(state);
 
@@ -1900,7 +1916,8 @@ static int stv090x_blind_search(struct s
 				srate_coarse = stv090x_srate_srch_fine(state);
 				if (srate_coarse != 0) {
 					stv090x_get_lock_tmg(state);
-					lock = stv090x_get_dmdlock(state, timeout_dmd);
+					lock = stv090x_get_dmdlock(state,
+							state->DemodTimeout);
 				} else {
 					lock = 0;
 				}
@@ -1908,8 +1925,8 @@ static int stv090x_blind_search(struct s
 				cpt_fail = 0;
 				agc2_ovflw = 0;
 				for (i = 0; i < 10; i++) {
-					agc2  = STV090x_READ_DEMOD(state, AGC2I1) << 8;
-					agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+					agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+						STV090x_READ_DEMOD(state, AGC2I0);
 					if (agc2 >= 0xff00)
 						agc2_ovflw++;
 					reg = STV090x_READ_DEMOD(state, DSTATUS2);
@@ -1923,7 +1940,7 @@ static int stv090x_blind_search(struct s
 
 				lock = 0;
 			}
-			k_ref -= 30;
+			k_ref -= 20;
 		} while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
 	}
 
@@ -2062,7 +2079,7 @@ static int stv090x_get_coldlock(struct s
 						goto err;
 
 					if (state->config->tuner_set_frequency) {
-						if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+						if (state->config->tuner_set_frequency(fe, freq) < 0)
 							goto err;
 					}
 
@@ -2093,17 +2110,6 @@ static int stv090x_get_coldlock(struct s
 						goto err;
 
 					STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
-					if (state->delsys == STV090x_DVBS2) {
-						reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-						STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
-						STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-						if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-							goto err;
-						STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-						STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-						if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-							goto err;
-					}
 					if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
 						goto err;
 					if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
@@ -2425,7 +2431,7 @@ static s32 stv090x_get_car_freq(struct s
 
 	derot = (int_1 * int_2) +
 		((int_1 * tmp_2) >> 12) +
-		((int_1 * tmp_1) >> 12);
+		((int_2 * tmp_1) >> 12);
 
 	return derot;
 }
@@ -2732,7 +2738,7 @@ static int stv090x_optimize_track(struct
 	switch (state->delsys) {
 	case STV090x_DVBS1:
 	case STV090x_DSS:
-		if (state->algo == STV090x_SEARCH_AUTO) {
+		if (state->search_mode == STV090x_SEARCH_AUTO) {
 			reg = STV090x_READ_DEMOD(state, DMDCFGMD);
 			STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
 			STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
@@ -2857,6 +2863,9 @@ static int stv090x_optimize_track(struct
 		if (stv090x_set_srate(state, srate) < 0)
 			goto err;
 		blind_tune = 1;
+
+		if (stv090x_dvbs_track_crl(state) < 0)
+			goto err;
 	}
 
 	if (state->dev_ver >= 0x20) {
@@ -3042,7 +3051,7 @@ static enum stv090x_signal_state stv090x
 	struct dvb_frontend *fe = &state->frontend;
 	enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
 	u32 reg;
-	s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i;
+	s32 agc1_power, power_iq = 0, i;
 	int lock = 0, low_sr = 0, no_signal = 0;
 
 	reg = STV090x_READ_DEMOD(state, TSCFGH);
@@ -3054,8 +3063,13 @@ static enum stv090x_signal_state stv090x
 		goto err;
 
 	if (state->dev_ver >= 0x20) {
-		if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */
-			goto err;
+		if (state->srate > 5000000) {
+			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
+				goto err;
+		} else {
+			if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
+				goto err;
+		}
 	}
 
 	stv090x_get_lock_tmg(state);
@@ -3175,7 +3189,7 @@ static enum stv090x_signal_state stv090x
 	if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
 		dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
 		lock = 0;
-
+		signal_state = STV090x_NOAGC1;
 	} else {
 		reg = STV090x_READ_DEMOD(state, DEMOD);
 		STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
@@ -3199,18 +3213,17 @@ static enum stv090x_signal_state stv090x
 		}
 	}
 
-	/* need to check for AGC1 state */
-
-
+	if (signal_state == STV090x_NOAGC1)
+		return signal_state;
 
 	if (state->algo == STV090x_BLIND_SEARCH)
 		lock = stv090x_blind_search(state);
 
 	else if (state->algo == STV090x_COLD_SEARCH)
-		lock = stv090x_get_coldlock(state, timeout_dmd);
+		lock = stv090x_get_coldlock(state, state->DemodTimeout);
 
 	else if (state->algo == STV090x_WARM_SEARCH)
-		lock = stv090x_get_dmdlock(state, timeout_dmd);
+		lock = stv090x_get_dmdlock(state, state->DemodTimeout);
 
 	if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
 		if (!low_sr) {
@@ -3245,8 +3258,9 @@ static enum stv090x_signal_state stv090x
 				goto err;
 		}
 
-		if (stv090x_get_lock(state, timeout_fec, timeout_fec)) {
-			lock = 1;
+		lock = stv090x_get_lock(state, state->FecTimeout,
+				state->FecTimeout);
+		if (lock) {
 			if (state->delsys == STV090x_DVBS2) {
 				stv090x_set_s2rolloff(state);
 
@@ -3273,7 +3287,6 @@ static enum stv090x_signal_state stv090x
 			if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
 				goto err;
 		} else {
-			lock = 0;
 			signal_state = STV090x_NODATA;
 			no_signal = stv090x_chk_signal(state);
 		}
@@ -3296,7 +3309,13 @@ static enum dvbfe_search stv090x_search(
 	state->search_mode = STV090x_SEARCH_AUTO;
 	state->algo = STV090x_COLD_SEARCH;
 	state->fec = STV090x_PRERR;
-	state->search_range = 2000000;
+	if (state->srate > 10000000) {
+		dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
+		state->search_range = 10000000;
+	} else {
+		dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
+		state->search_range = 5000000;
+	}
 
 	if (stv090x_algo(state) == STV090x_RANGEOK) {
 		dprintk(FE_DEBUG, 1, "Search success!");
@@ -3309,7 +3328,6 @@ static enum dvbfe_search stv090x_search(
 	return DVBFE_ALGO_SEARCH_ERROR;
 }
 
-/* FIXME! */
 static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
 	struct stv090x_state *state = fe->demodulator_priv;
@@ -3331,9 +3349,15 @@ static int stv090x_read_status(struct dv
 		dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
 		reg = STV090x_READ_DEMOD(state, DSTATUS);
 		if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
-			reg = STV090x_READ_DEMOD(state, TSSTATUS);
-			if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
-				*status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+			reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
+			if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
+				reg = STV090x_READ_DEMOD(state, TSSTATUS);
+				if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
+					*status = FE_HAS_CARRIER |
+						  FE_HAS_VITERBI |
+						  FE_HAS_SYNC |
+						  FE_HAS_LOCK;
+				}
 			}
 		}
 		break;
@@ -3412,14 +3436,12 @@ static int stv090x_table_lookup(const st
 	int res = 0;
 	int min = 0, med;
 
-	if (val < tab[min].read)
-		res = tab[min].real;
-	else if (val >= tab[max].read)
-		res = tab[max].real;
-	else {
+	if ((val >= tab[min].read && val < tab[max].read) ||
+	    (val >= tab[max].read && val < tab[min].read)) {
 		while ((max - min) > 1) {
 			med = (max + min) / 2;
-			if (val >= tab[min].read && val < tab[med].read)
+			if ((val >= tab[min].read && val < tab[med].read) ||
+			    (val >= tab[med].read && val < tab[min].read))
 				max = med;
 			else
 				min = med;
@@ -3428,6 +3450,18 @@ static int stv090x_table_lookup(const st
 		       (tab[max].real - tab[min].real) /
 		       (tab[max].read - tab[min].read)) +
 			tab[min].real;
+	} else {
+		if (tab[min].read < tab[max].read) {
+			if (val < tab[min].read)
+				res = tab[min].real;
+			else if (val >= tab[max].read)
+				res = tab[max].real;
+		} else {
+			if (val >= tab[min].read)
+				res = tab[min].real;
+			else if (val < tab[max].read)
+				res = tab[max].real;
+		}
 	}
 
 	return res;
@@ -3437,16 +3471,22 @@ static int stv090x_read_signal_strength(
 {
 	struct stv090x_state *state = fe->demodulator_priv;
 	u32 reg;
-	s32 agc;
+	s32 agc_0, agc_1, agc;
+	s32 str;
 
 	reg = STV090x_READ_DEMOD(state, AGCIQIN1);
-	agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	reg = STV090x_READ_DEMOD(state, AGCIQIN0);
+	agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+	agc = MAKEWORD16(agc_1, agc_0);
 
-	*strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
+	str = stv090x_table_lookup(stv090x_rf_tab,
+		ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
 	if (agc > stv090x_rf_tab[0].read)
-		*strength = 5;
+		str = 0;
 	else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
-		*strength = -100;
+		str = -100;
+	*strength = (str + 100) * 0xFFFF / 100;
 
 	return 0;
 }
@@ -3457,6 +3497,8 @@ static int stv090x_read_cnr(struct dvb_f
 	u32 reg_0, reg_1, reg, i;
 	s32 val_0, val_1, val = 0;
 	u8 lock_f;
+	s32 div;
+	u32 last;
 
 	switch (state->delsys) {
 	case STV090x_DVBS2:
@@ -3468,14 +3510,15 @@ static int stv090x_read_cnr(struct dvb_f
 				reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
-				val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
+				val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
 			val /= 16;
-			*cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
-			if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read)
-				*cnr = 1000;
+			last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
+			div = stv090x_s2cn_tab[0].read -
+			      stv090x_s2cn_tab[last].read;
+			*cnr = 0xFFFF - ((val * 0xFFFF) / div);
 		}
 		break;
 
@@ -3489,14 +3532,15 @@ static int stv090x_read_cnr(struct dvb_f
 				reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
 				val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
 				reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
-				val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
+				val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
 				val  += MAKEWORD16(val_1, val_0);
 				msleep(1);
 			}
 			val /= 16;
-			*cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
-			if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read)
-				*cnr = 1000;
+			last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
+			div = stv090x_s1cn_tab[0].read -
+			      stv090x_s1cn_tab[last].read;
+			*cnr = 0xFFFF - ((val * 0xFFFF) / div);
 		}
 		break;
 	default:
@@ -3553,7 +3597,8 @@ static int stv090x_send_diseqc_msg(struc
 
 	reg = STV090x_READ_DEMOD(state, DISTXCTL);
 
-	STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2);
+	STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
+		(state->config->diseqc_envelope_mode) ? 4 : 2);
 	STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
 	if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
 		goto err;
@@ -3605,10 +3650,10 @@ static int stv090x_send_diseqc_burst(str
 	reg = STV090x_READ_DEMOD(state, DISTXCTL);
 
 	if (burst == SEC_MINI_A) {
-		mode = 3;
+		mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
 		value = 0x00;
 	} else {
-		mode = 2;
+		mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
 		value = 0xFF;
 	}
 
@@ -3732,6 +3777,8 @@ static int stv090x_ldpc_mode(struct stv0
 {
 	u32 reg = 0;
 
+	reg = stv090x_read_reg(state, STV090x_GENCFG);
+
 	switch (ldpc_mode) {
 	case STV090x_DUAL:
 	default:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x.h	2010-02-24 13:52:17.000000000 -0500
@@ -75,6 +75,8 @@ struct stv090x_config {
 
 	enum stv090x_i2crpt	repeater_level;
 
+	bool diseqc_envelope_mode;
+
 	int (*tuner_init) (struct dvb_frontend *fe);
 	int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
 	int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x_priv.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_priv.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,7 @@
 
 #define STV090x_IQPOWER_THRESHOLD	  30
 #define STV090x_SEARCH_AGC2_TH_CUT20	 700
-#define STV090x_SEARCH_AGC2_TH_CUT30	1200
+#define STV090x_SEARCH_AGC2_TH_CUT30	1400
 
 #define STV090x_SEARCH_AGC2_TH(__ver)	\
 	((__ver <= 0x20) ?		\
@@ -91,6 +91,7 @@
 	STV090x_SEARCH_AGC2_TH_CUT30)
 
 enum stv090x_signal_state {
+	STV090x_NOAGC1,
 	STV090x_NOCARRIER,
 	STV090x_NODATA,
 	STV090x_DATAOK,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x_reg.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_reg.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv090x_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv090x_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@
 #define STV090x_OFFST_OUTSERRS2_HZ_FIELD	5
 #define STV090x_WIDTH_OUTSERRS2_HZ_FIELD	1
 #define STV090x_OFFST_OUTSERRS3_HZ_FIELD	4
-#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD	1
+#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD	1
 #define STV090x_OFFST_OUTPARRS3_HZ_FIELD	3
 #define STV090x_WIDTH_OUTPARRS3_HZ_FIELD	1
 
@@ -113,24 +113,24 @@
 #define STV090x_IRQMASK3			0xf124
 #define STV090x_OFFST_MPLL_LOCK_FIELD		5
 #define STV090x_WIDTH_MPLL_LOCK_FIELD		1
-#define STV090x_OFFST_MSTREAM_LCK_3_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD	3
-#define STV090x_OFFST_MSTREAM_LCK_2_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD	3
+#define STV090x_OFFST_MSTREAM_LCK_3_FIELD	4
+#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD	1
+#define STV090x_OFFST_MSTREAM_LCK_2_FIELD	3
+#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD	1
 #define STV090x_OFFST_MSTREAM_LCK_1_FIELD	2
-#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD	3
+#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD	1
 #define STV090x_OFFST_MDVBS1_PRF_2_FIELD	1
 #define STV090x_WIDTH_MDVBS1_PRF_2_FIELD	1
 #define STV090x_OFFST_MDVBS1_PRF_1_FIELD	0
 #define STV090x_WIDTH_MDVBS1_PRF_1_FIELD	1
 
 #define STV090x_IRQMASK2			0xf125
-#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD	3
-#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD	3
+#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD	7
+#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD	1
+#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD	6
+#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD	1
 #define STV090x_OFFST_MSPY_ENDSIM_1_FIELD	5
-#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD	3
+#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD	1
 #define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD	4
 #define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD	1
 #define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD	3
@@ -370,7 +370,7 @@
 #define STV090x_OFFST_SELX1RATIO_FIELD		5
 #define STV090x_WIDTH_SELX1RATIO_FIELD		1
 #define STV090x_OFFST_STOP_PLL_FIELD		3
-#define STV090x_WIDTH_SELX1RATIO_FIELD		1
+#define STV090x_WIDTH_STOP_PLL_FIELD		1
 #define STV090x_OFFST_BYPASSPLLFSK_FIELD	2
 #define STV090x_WIDTH_BYPASSPLLFSK_FIELD	1
 #define STV090x_OFFST_SELOSCI_FIELD		1
@@ -616,7 +616,7 @@
 #define STV090x_OFFST_Px_CONT_TONE_FIELD	4
 #define STV090x_WIDTH_Px_CONT_TONE_FIELD	1
 #define STV090x_OFFST_Px_FIFO_4BREADY_FIELD	3
-#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD	2
+#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD	1
 #define STV090x_OFFST_Px_FIFO_EMPTY_FIELD	2
 #define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD	1
 #define STV090x_OFFST_Px_ABORT_DISRX_FIELD	0
@@ -847,12 +847,10 @@
 #define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD	1
 #define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD	6
 #define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD	1
-#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD	5 /* check */
-#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD	1
-#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD	4 /* check */
+#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD	4
 #define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD	1
-#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD	3
-#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD	1
+#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD	3
+#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD	1
 #define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD	2
 #define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD	1
 #define STV090x_OFFST_Px_TUN_RNG_FIELD		0
@@ -885,7 +883,7 @@
 #define STV090x_P2_DMDFLYW			STV090x_Px_DMDFLYW(2)
 #define STV090x_OFFST_Px_I2C_IRQVAL_FIELD	4
 #define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD	4
-#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD	0 /* check */
+#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD	0
 #define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD	4
 
 #define STV090x_Px_DSTATUS3(__x)		(0xF41D - (__x - 1) * 0x200)
@@ -1048,12 +1046,12 @@
 #define STV090x_P1_CFRINC1			STV090x_Px_CFRINC1(1)
 #define STV090x_P2_CFRINC1			STV090x_Px_CFRINC1(2)
 #define STV090x_OFFST_Px_CFR_INC1_FIELD		0
-#define STV090x_WIDTH_Px_CFR_INC1_FIELD		7
+#define STV090x_WIDTH_Px_CFR_INC1_FIELD		7 /* check */
 
 #define STV090x_Px_CFRINC0(__x)			(0xF44B - (__x - 1) * 0x200)
 #define STV090x_P1_CFRINC0			STV090x_Px_CFRINC0(1)
 #define STV090x_P2_CFRINC0			STV090x_Px_CFRINC0(2)
-#define STV090x_OFFST_Px_CFR_INC0_FIELD		4
+#define STV090x_OFFST_Px_CFR_INC0_FIELD		4 /* check */
 #define STV090x_WIDTH_Px_CFR_INC0_FIELD		4
 
 #define STV090x_Pn_CFRy(__x, __y)		(0xF44E - (__x - 1) * 0x200 - __y * 0x1)
@@ -1145,14 +1143,14 @@
 #define STV090x_Px_SFRINIT1(__x)		(0xF45E - (__x - 1) * 0x200)
 #define STV090x_P1_SFRINIT1			STV090x_Px_SFRINIT1(1)
 #define STV090x_P2_SFRINIT1			STV090x_Px_SFRINIT1(2)
-#define STV090x_OFFST_Px_SFR_INIT_FIELD		0
-#define STV090x_WIDTH_Px_SFR_INIT_FIELD		8
+#define STV090x_OFFST_Px_SFR_INIT1_FIELD	0
+#define STV090x_WIDTH_Px_SFR_INIT1_FIELD	7
 
 #define STV090x_Px_SFRINIT0(__x)		(0xF45F - (__x - 1) * 0x200)
 #define STV090x_P1_SFRINIT0			STV090x_Px_SFRINIT0(1)
 #define STV090x_P2_SFRINIT0			STV090x_Px_SFRINIT0(2)
-#define STV090x_OFFST_Px_SFR_INIT_FIELD		0
-#define STV090x_WIDTH_Px_SFR_INIT_FIELD		8
+#define STV090x_OFFST_Px_SFR_INIT0_FIELD	0
+#define STV090x_WIDTH_Px_SFR_INIT0_FIELD	8
 
 #define STV090x_Px_SFRUP1(__x)			(0xF460 - (__x - 1) * 0x200)
 #define STV090x_P1_SFRUP1			STV090x_Px_SFRUP1(1)
@@ -1178,7 +1176,7 @@
 #define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD	0
 #define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD	8
 
-#define STV090x_Px_SFRy(__x, __y)		(0xF464 - (__x-1) * 0x200 + (3 - __y))
+#define STV090x_Px_SFRy(__x, __y)		(0xF467 - (__x-1) * 0x200 - __y)
 #define STV090x_P1_SFR0				STV090x_Px_SFRy(1, 0)
 #define STV090x_P1_SFR1				STV090x_Px_SFRy(1, 1)
 #define STV090x_P1_SFR2				STV090x_Px_SFRy(1, 2)
@@ -1188,7 +1186,7 @@
 #define STV090x_P2_SFR2				STV090x_Px_SFRy(2, 2)
 #define STV090x_P2_SFR3				STV090x_Px_SFRy(2, 3)
 #define STV090x_OFFST_Px_SYMB_FREQ_FIELD	0
-#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD	32
+#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD	8
 
 #define STV090x_Px_TMGREG2(__x)			(0xF468 - (__x - 1) * 0x200)
 #define STV090x_P1_TMGREG2			STV090x_Px_TMGREG2(1)
@@ -1198,7 +1196,7 @@
 
 #define STV090x_Px_TMGREG1(__x)			(0xF469 - (__x - 1) * 0x200)
 #define STV090x_P1_TMGREG1			STV090x_Px_TMGREG1(1)
-#define STV090x_P2_TMGREG1				STV090x_Px_TMGREG1(2)
+#define STV090x_P2_TMGREG1			STV090x_Px_TMGREG1(2)
 #define STV090x_OFFST_Px_TMGREG_FIELD		0
 #define STV090x_WIDTH_Px_TMGREG_FIELD		8
 
@@ -1230,7 +1228,7 @@
 #define STV090x_OFFST_Px_MU_EQUALDFE_FIELD	0
 #define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD	3
 
-#define STV090x_Px_EQUAIy(__x, __y)		(0xf470 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_Px_EQUAIy(__x, __y)	(0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
 #define STV090x_P1_EQUAI1			STV090x_Px_EQUAIy(1, 1)
 #define STV090x_P1_EQUAI2			STV090x_Px_EQUAIy(1, 2)
 #define STV090x_P1_EQUAI3			STV090x_Px_EQUAIy(1, 3)
@@ -1251,7 +1249,7 @@
 #define STV090x_OFFST_Px_EQUA_ACCIy_FIELD	0
 #define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD	8
 
-#define STV090x_Px_EQUAQy(__x, __y)		(0xf471 - (__x - 1) * 0x200 + (__y - 1))
+#define STV090x_Px_EQUAQy(__x, __y)	(0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
 #define STV090x_P1_EQUAQ1			STV090x_Px_EQUAQy(1, 1)
 #define STV090x_P1_EQUAQ2			STV090x_Px_EQUAQy(1, 2)
 #define STV090x_P1_EQUAQ3			STV090x_Px_EQUAQy(1, 3)
@@ -1390,7 +1388,7 @@
 #define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD	4
 
-#define STV090x_Px_ACLC2S232A(__x)		(0xf499 - (__x - 1) * 0x200)
+#define STV090x_Px_ACLC2S232A(__x)		(0xf49A - (__x - 1) * 0x200)
 #define STV090x_P1_ACLC2S232A			STV090x_Px_ACLC2S232A(1)
 #define STV090x_P2_ACLC2S232A			STV090x_Px_ACLC2S232A(2)
 #define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD	4
@@ -1414,7 +1412,7 @@
 #define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD	4
 
-#define STV090x_Px_BCLC2S216A(__x)		(0xf49d - (__x - 1) * 0x200)
+#define STV090x_Px_BCLC2S216A(__x)		(0xf49e - (__x - 1) * 0x200)
 #define STV090x_P1_BCLC2S216A			STV090x_Px_BCLC2S216A(1)
 #define STV090x_P2_BCLC2S216A			STV090x_Px_BCLC2S216A(1)
 #define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD	4
@@ -1422,7 +1420,7 @@
 #define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD	0
 #define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD	4
 
-#define STV090x_Px_BCLC2S232A(__x)		(0xf49d - (__x - 1) * 0x200)
+#define STV090x_Px_BCLC2S232A(__x)		(0xf49f - (__x - 1) * 0x200)
 #define STV090x_P1_BCLC2S232A			STV090x_Px_BCLC2S232A(1)
 #define STV090x_P2_BCLC2S232A			STV090x_Px_BCLC2S232A(1)
 #define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD	4
@@ -1458,7 +1456,7 @@
 #define STV090x_P1_MODCODLST1			STV090x_Px_MODCODLST1(1)
 #define STV090x_P2_MODCODLST1			STV090x_Px_MODCODLST1(2)
 #define STV090x_OFFST_Px_DIS_MODCOD29_FIELD	4
-#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD	4
+#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD	4
 #define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD	0
 #define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD	4
 
@@ -2180,7 +2178,7 @@
 #define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD	1
 #define STV090x_OFFST_Px_DILXX_RESET_FIELD		5
 #define STV090x_WIDTH_Px_DILXX_RESET_FIELD		1
-#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD		5
+#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD		4
 #define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD		1
 #define STV090x_OFFST_Px_SCRAMBDETECT_FIELD		1
 #define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD		1
@@ -2190,7 +2188,7 @@
 #define STV090x_P1_TSBITRATE1				STV090x_Px_TSBITRATEy(1, 1)
 #define STV090x_P2_TSBITRATE0				STV090x_Px_TSBITRATEy(2, 0)
 #define STV090x_P2_TSBITRATE1				STV090x_Px_TSBITRATEy(2, 1)
-#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD		7
+#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD		0
 #define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD		8
 
 #define STV090x_Px_ERRCTRL1(__x)			(0xF598 - (__x - 1) * 0x200)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,7 @@ struct stv6110_priv {
 
 	u32 mclk;
 	u8 clk_div;
+	u8 gain;
 	u8 regs[8];
 };
 
@@ -255,7 +256,7 @@ static int stv6110_set_frequency(struct
 	u8 ret = 0x04;
 	u32 divider, ref, p, presc, i, result_freq, vco_freq;
 	s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
-	s32 srate; u8 gain;
+	s32 srate;
 
 	dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
 						frequency, priv->mclk);
@@ -273,15 +274,8 @@ static int stv6110_set_frequency(struct
 	} else
 		srate = 15000000;
 
-	if (srate >= 15000000)
-		gain = 3; /* +6 dB */
-	else if (srate >= 5000000)
-		gain = 3; /* +6 dB */
-	else
-		gain = 3; /* +6 dB */
-
 	priv->regs[RSTV6110_CTRL2] &= ~0x0f;
-	priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f);
+	priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
 
 	if (frequency <= 1023000) {
 		p = 1;
@@ -436,6 +430,7 @@ struct dvb_frontend *stv6110_attach(stru
 	priv->i2c = i2c;
 	priv->mclk = config->mclk;
 	priv->clk_div = config->clk_div;
+	priv->gain = config->gain;
 
 	memcpy(&priv->regs, &reg0[1], 8);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110.h	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,7 @@
 struct stv6110_config {
 	u8 i2c_address;
 	u32 mclk;
+	u8 gain;
 	u8 clk_div;	/* divisor value for the output clock */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110x.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/stv6110x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/stv6110x.c	2010-02-24 13:52:17.000000000 -0500
@@ -95,7 +95,7 @@ static int stv6110x_set_frequency(struct
 {
 	struct stv6110x_state *stv6110x = fe->tuner_priv;
 	u32 rDiv, divider;
-	s32 pVal, pCalc, rDivOpt = 0;
+	s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
 	u8 i;
 
 	STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
@@ -121,8 +121,10 @@ static int stv6110x_set_frequency(struct
 	for (rDiv = 0; rDiv <= 3; rDiv++) {
 		pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
 
-		if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal))))
+		if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
 			rDivOpt = rDiv;
+
+		pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
 	}
 
 	divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda10021.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda10021.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda10021.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda10021.c	2010-02-24 13:52:17.000000000 -0500
@@ -426,6 +426,10 @@ struct dvb_frontend* tda10021_attach(con
 	id = tda10021_readreg(state, 0x1a);
 	if ((id & 0xf0) != 0x70) goto error;
 
+	/* Don't claim TDA10023 */
+	if (id == 0x7d)
+		goto error;
+
 	printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
 	       state->config->demod_address, id);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda665x.c linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda665x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,257 @@
+/*
+	TDA665x tuner driver
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "dvb_frontend.h"
+#include "tda665x.h"
+
+struct tda665x_state {
+	struct dvb_frontend		*fe;
+	struct i2c_adapter		*i2c;
+	const struct tda665x_config	*config;
+
+	u32 frequency;
+	u32 bandwidth;
+};
+
+static int tda665x_read(struct tda665x_state *state, u8 *buf)
+{
+	const struct tda665x_config *config = state->config;
+	int err = 0;
+	struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
+
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1)
+		goto exit;
+
+	return err;
+exit:
+	printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
+	return err;
+}
+
+static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
+{
+	const struct tda665x_config *config = state->config;
+	int err = 0;
+	struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
+
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1)
+		goto exit;
+
+	return err;
+exit:
+	printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
+	return err;
+}
+
+static int tda665x_get_state(struct dvb_frontend *fe,
+			     enum tuner_param param,
+			     struct tuner_state *tstate)
+{
+	struct tda665x_state *state = fe->tuner_priv;
+	int err = 0;
+
+	switch (param) {
+	case DVBFE_TUNER_FREQUENCY:
+		tstate->frequency = state->frequency;
+		break;
+	case DVBFE_TUNER_BANDWIDTH:
+		break;
+	default:
+		printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
+{
+	struct tda665x_state *state = fe->tuner_priv;
+	u8 result = 0;
+	int err = 0;
+
+	*status = 0;
+
+	err = tda665x_read(state, &result);
+	if (err < 0)
+		goto exit;
+
+	if ((result >> 6) & 0x01) {
+		printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
+		*status = 1;
+	}
+
+	return err;
+exit:
+	printk(KERN_ERR "%s: I/O Error\n", __func__);
+	return err;
+}
+
+static int tda665x_set_state(struct dvb_frontend *fe,
+			     enum tuner_param param,
+			     struct tuner_state *tstate)
+{
+	struct tda665x_state *state = fe->tuner_priv;
+	const struct tda665x_config *config = state->config;
+	u32 frequency, status = 0;
+	u8 buf[4];
+	int err = 0;
+
+	if (param & DVBFE_TUNER_FREQUENCY) {
+
+		frequency = tstate->frequency;
+		if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
+			printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
+			return -EINVAL;
+		}
+
+		frequency += config->frequency_offst;
+		frequency *= config->ref_multiplier;
+		frequency += config->ref_divider >> 1;
+		frequency /= config->ref_divider;
+
+		buf[0] = (u8) (frequency & 0x7f00) >> 8;
+		buf[1] = (u8) (frequency & 0x00ff) >> 0;
+		buf[2] = 0x80 | 0x40 | 0x02;
+		buf[3] = 0x00;
+
+		/* restore frequency */
+		frequency = tstate->frequency;
+
+		if (frequency < 153000000) {
+			/* VHF-L */
+			buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
+			if (frequency < 68000000)
+				buf[3] |= 0x40; /* 83uA */
+			if (frequency < 1040000000)
+				buf[3] |= 0x60; /* 122uA */
+			if (frequency < 1250000000)
+				buf[3] |= 0x80; /* 163uA */
+			else
+				buf[3] |= 0xa0; /* 254uA */
+		} else if (frequency < 438000000) {
+			/* VHF-H */
+			buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
+			if (frequency < 230000000)
+				buf[3] |= 0x40;
+			if (frequency < 300000000)
+				buf[3] |= 0x60;
+			else
+				buf[3] |= 0x80;
+		} else {
+			/* UHF */
+			buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
+			if (frequency < 470000000)
+				buf[3] |= 0x60;
+			if (frequency < 526000000)
+				buf[3] |= 0x80;
+			else
+				buf[3] |= 0xa0;
+		}
+
+		/* Set params */
+		err = tda665x_write(state, buf, 5);
+		if (err < 0)
+			goto exit;
+
+		/* sleep for some time */
+		printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
+		msleep(20);
+		/* check status */
+		err = tda665x_get_status(fe, &status);
+		if (err < 0)
+			goto exit;
+
+		if (status == 1) {
+			printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
+			state->frequency = frequency; /* cache successful state */
+		} else {
+			printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
+		}
+	} else {
+		printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
+		return -EINVAL;
+	}
+
+	return 0;
+exit:
+	printk(KERN_ERR "%s: I/O Error\n", __func__);
+	return err;
+}
+
+static int tda665x_release(struct dvb_frontend *fe)
+{
+	struct tda665x_state *state = fe->tuner_priv;
+
+	fe->tuner_priv = NULL;
+	kfree(state);
+	return 0;
+}
+
+static struct dvb_tuner_ops tda665x_ops = {
+
+	.set_state	= tda665x_set_state,
+	.get_state	= tda665x_get_state,
+	.get_status	= tda665x_get_status,
+	.release	= tda665x_release
+};
+
+struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+				    const struct tda665x_config *config,
+				    struct i2c_adapter *i2c)
+{
+	struct tda665x_state *state = NULL;
+	struct dvb_tuner_info *info;
+
+	state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
+	if (state == NULL)
+		goto exit;
+
+	state->config		= config;
+	state->i2c		= i2c;
+	state->fe		= fe;
+	fe->tuner_priv		= state;
+	fe->ops.tuner_ops	= tda665x_ops;
+	info			 = &fe->ops.tuner_ops.info;
+
+	memcpy(info->name, config->name, sizeof(config->name));
+	info->frequency_min	= config->frequency_min;
+	info->frequency_max	= config->frequency_max;
+	info->frequency_step	= config->frequency_offst;
+
+	printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
+
+	return fe;
+
+exit:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(tda665x_attach);
+
+MODULE_DESCRIPTION("TDA665x driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda665x.h linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/frontends/tda665x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/frontends/tda665x.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+	TDA665x tuner driver
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __TDA665x_H
+#define __TDA665x_H
+
+struct tda665x_config {
+	char name[128];
+
+	u8	addr;
+	u32	frequency_min;
+	u32	frequency_max;
+	u32	frequency_offst;
+	u32	ref_multiplier;
+	u32	ref_divider;
+};
+
+#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+					   const struct tda665x_config *config,
+					   struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+						  const struct tda665x_config *config,
+						  struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+#endif /* CONFIG_DVB_TDA665x */
+
+#endif /* __TDA665x_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/Kconfig linux-libre-2.6.33-gnu1/drivers/media/dvb/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -72,6 +72,10 @@ comment "Supported Earthsoft PT1 Adapter
 	depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/pt1/Kconfig"
 
+comment "Supported Mantis Adapters"
+	depends on DVB_CORE && PCI && I2C
+	source "drivers/media/dvb/mantis/Kconfig"
+
 comment "Supported DVB Frontends"
 	depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/Makefile linux-libre-2.6.33-gnu1/drivers/media/dvb/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,18 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/
+obj-y        := dvb-core/	\
+		frontends/	\
+		ttpci/		\
+		ttusb-dec/	\
+		ttusb-budget/	\
+		b2c2/		\
+		bt8xx/		\
+		dvb-usb/	\
+		pluto2/		\
+		siano/		\
+		dm1105/		\
+		pt1/		\
+		mantis/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_cards.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_cards.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_cards.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,275 @@
+/*
+	Hopper PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/irq.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "hopper_vp3028.h"
+#include "mantis_dma.h"
+#include "mantis_dvb.h"
+#include "mantis_uart.h"
+#include "mantis_ioc.h"
+#include "mantis_pci.h"
+#include "mantis_i2c.h"
+#include "mantis_reg.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+
+#define DRIVER_NAME	"Hopper"
+
+static char *label[10] = {
+	"DMA",
+	"IRQ-0",
+	"IRQ-1",
+	"OCERR",
+	"PABRT",
+	"RIPRR",
+	"PPERR",
+	"FTRGT",
+	"RISCI",
+	"RACK"
+};
+
+static int devs;
+
+static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
+{
+	u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
+	u32 rst_stat = 0, rst_mask = 0;
+
+	struct mantis_pci *mantis;
+	struct mantis_ca *ca;
+
+	mantis = (struct mantis_pci *) dev_id;
+	if (unlikely(mantis == NULL)) {
+		dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
+		return IRQ_NONE;
+	}
+	ca = mantis->mantis_ca;
+
+	stat = mmread(MANTIS_INT_STAT);
+	mask = mmread(MANTIS_INT_MASK);
+	mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
+	if (!(stat & mask))
+		return IRQ_NONE;
+
+	rst_mask  = MANTIS_GPIF_WRACK  |
+		    MANTIS_GPIF_OTHERR |
+		    MANTIS_SBUF_WSTO   |
+		    MANTIS_GPIF_EXTIRQ;
+
+	rst_stat  = mmread(MANTIS_GPIF_STATUS);
+	rst_stat &= rst_mask;
+	mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
+	mantis->mantis_int_stat = stat;
+	mantis->mantis_int_mask = mask;
+	dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
+	if (stat & MANTIS_INT_RISCEN) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
+	}
+	if (stat & MANTIS_INT_IRQ0) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
+		mantis->gpif_status = rst_stat;
+		wake_up(&ca->hif_write_wq);
+		schedule_work(&ca->hif_evm_work);
+	}
+	if (stat & MANTIS_INT_IRQ1) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
+		schedule_work(&mantis->uart_work);
+	}
+	if (stat & MANTIS_INT_OCERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
+	}
+	if (stat & MANTIS_INT_PABORT) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
+	}
+	if (stat & MANTIS_INT_RIPERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
+	}
+	if (stat & MANTIS_INT_PPERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
+	}
+	if (stat & MANTIS_INT_FTRGT) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
+	}
+	if (stat & MANTIS_INT_RISCI) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
+		mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+		tasklet_schedule(&mantis->tasklet);
+	}
+	if (stat & MANTIS_INT_I2CDONE) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+		wake_up(&mantis->i2c_wq);
+	}
+	mmwrite(stat, MANTIS_INT_STAT);
+	stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
+		  MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
+		  MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
+		  MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
+		  MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
+		  MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1	   |
+		  MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
+		  MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
+		  MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
+		  MANTIS_INT_RISCI);
+
+	if (stat)
+		dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
+
+	dprintk(MANTIS_DEBUG, 0, "\n");
+	return IRQ_HANDLED;
+}
+
+static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+	struct mantis_pci *mantis;
+	struct mantis_hwconfig *config;
+	int err = 0;
+
+	mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
+	if (mantis == NULL) {
+		printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+		err = -ENOMEM;
+		goto fail0;
+	}
+
+	mantis->num		= devs;
+	mantis->verbose		= verbose;
+	mantis->pdev		= pdev;
+	config			= (struct mantis_hwconfig *) pci_id->driver_data;
+	config->irq_handler	= &hopper_irq_handler;
+	mantis->hwconfig	= config;
+
+	err = mantis_pci_init(mantis);
+	if (err) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
+		goto fail1;
+	}
+
+	err = mantis_stream_control(mantis, STREAM_TO_HIF);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
+		goto fail1;
+	}
+
+	err = mantis_i2c_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
+		goto fail2;
+	}
+
+	err = mantis_get_mac(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
+		goto fail2;
+	}
+
+	err = mantis_dma_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
+		goto fail3;
+	}
+
+	err = mantis_dvb_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
+		goto fail4;
+	}
+	devs++;
+
+	return err;
+
+fail4:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
+	mantis_dma_exit(mantis);
+
+fail3:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
+	mantis_i2c_exit(mantis);
+
+fail2:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
+	mantis_pci_exit(mantis);
+
+fail1:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
+	kfree(mantis);
+
+fail0:
+	return err;
+}
+
+static void __devexit hopper_pci_remove(struct pci_dev *pdev)
+{
+	struct mantis_pci *mantis = pci_get_drvdata(pdev);
+
+	if (mantis) {
+		mantis_dvb_exit(mantis);
+		mantis_dma_exit(mantis);
+		mantis_i2c_exit(mantis);
+		mantis_pci_exit(mantis);
+		kfree(mantis);
+	}
+	return;
+
+}
+
+static struct pci_device_id hopper_pci_table[] = {
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
+	{ }
+};
+
+static struct pci_driver hopper_pci_driver = {
+	.name		= DRIVER_NAME,
+	.id_table	= hopper_pci_table,
+	.probe		= hopper_pci_probe,
+	.remove		= hopper_pci_remove,
+};
+
+static int __devinit hopper_init(void)
+{
+	return pci_register_driver(&hopper_pci_driver);
+}
+
+static void __devexit hopper_exit(void)
+{
+	return pci_unregister_driver(&hopper_pci_driver);
+}
+
+module_init(hopper_init);
+module_exit(hopper_exit);
+
+MODULE_DESCRIPTION("HOPPER driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_vp3028.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_vp3028.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_vp3028.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_vp3028.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,88 @@
+/*
+	Hopper VP-3028 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "zl10353.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "hopper_vp3028.h"
+
+struct zl10353_config hopper_vp3028_config = {
+	.demod_address	= 0x0f,
+};
+
+#define MANTIS_MODEL_NAME	"VP-3028"
+#define MANTIS_DEV_TYPE		"DVB-T"
+
+static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter	= &mantis->adapter;
+	struct mantis_hwconfig *config	= mantis->hwconfig;
+	int err = 0;
+
+	gpio_set_bits(mantis, config->reset, 0);
+	msleep(100);
+	err = mantis_frontend_power(mantis, POWER_ON);
+	msleep(100);
+	gpio_set_bits(mantis, config->reset, 1);
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		msleep(250);
+		dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
+		fe = zl10353_attach(&hopper_vp3028_config, adapter);
+
+		if (!fe)
+			return -1;
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+	dprintk(MANTIS_ERROR, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp3028_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_188,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp3028_frontend_init,
+	.power		= GPIF_A00,
+	.reset		= GPIF_A03,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_vp3028.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_vp3028.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/hopper_vp3028.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/hopper_vp3028.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Hopper VP-3028 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP3028_H
+#define __MANTIS_VP3028_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_3028_DVB_T	0x0028
+
+extern struct mantis_hwconfig vp3028_config;
+
+#endif /* __MANTIS_VP3028_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/Kconfig linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+config MANTIS_CORE
+	tristate "Mantis/Hopper PCI bridge based devices"
+	depends on PCI && I2C && INPUT
+
+	help
+	  Support for PCI cards based on the Mantis and Hopper PCi bridge.
+
+	  Say Y if you own such a device and want to use it.
+
+config DVB_MANTIS
+	tristate "MANTIS based cards"
+	depends on MANTIS_CORE && DVB_CORE && PCI && I2C
+	select DVB_MB86A16
+	select DVB_ZL10353
+	select DVB_STV0299
+	select DVB_PLL
+	help
+	  Support for PCI cards based on the Mantis PCI bridge.
+	  Say Y when you have a Mantis based DVB card and want to use it.
+
+	  If unsure say N.
+
+config DVB_HOPPER
+	tristate "HOPPER based cards"
+	depends on MANTIS_CORE && DVB_CORE && PCI && I2C
+	select DVB_ZL10353
+	select DVB_PLL
+	help
+	  Support for PCI cards based on the Hopper  PCI bridge.
+	  Say Y when you have a Hopper based DVB card and want to use it.
+
+	  If unsure say N
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/Makefile linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+mantis_core-objs :=	mantis_ioc.o	\
+			mantis_uart.o	\
+			mantis_dma.o	\
+			mantis_pci.o	\
+			mantis_i2c.o	\
+			mantis_dvb.o	\
+			mantis_evm.o	\
+			mantis_hif.o	\
+			mantis_ca.o	\
+			mantis_pcmcia.o	\
+			mantis_input.o
+
+mantis-objs	:=	mantis_cards.o	\
+			mantis_vp1033.o	\
+			mantis_vp1034.o	\
+			mantis_vp1041.o	\
+			mantis_vp2033.o	\
+			mantis_vp2040.o	\
+			mantis_vp3030.o
+
+hopper-objs	:=	hopper_cards.o	\
+			hopper_vp3028.o
+
+obj-$(CONFIG_MANTIS_CORE)	+= mantis_core.o
+obj-$(CONFIG_DVB_MANTIS)	+= mantis.o
+obj-$(CONFIG_DVB_HOPPER)	+= hopper.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ca.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ca.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,207 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h"
+#include "mantis_hif.h"
+#include "mantis_reg.h"
+
+#include "mantis_ca.h"
+
+static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	return mantis_hif_read_mem(ca, addr);
+}
+
+static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	return mantis_hif_write_mem(ca, addr, data);
+}
+
+static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	return mantis_hif_read_iom(ca, addr);
+}
+
+static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	return mantis_hif_write_iom(ca, addr, data);
+}
+
+static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
+	udelay(500); /* Wait.. */
+	mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
+	udelay(500);
+	mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
+	msleep(1000);
+	dvb_ca_en50221_camready_irq(&ca->en50221, 0);
+
+	return 0;
+}
+
+static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
+
+	return 0;
+}
+
+static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
+/*	mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */
+
+	return 0;
+}
+
+static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+{
+	struct mantis_ca *ca = en50221->data;
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
+
+	if (ca->slot_state == MODULE_INSERTED) {
+		dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
+		return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+	} else {
+		dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
+	}
+
+	return 0;
+}
+
+int mantis_ca_init(struct mantis_pci *mantis)
+{
+	struct dvb_adapter *dvb_adapter	= &mantis->dvb_adapter;
+	struct mantis_ca *ca;
+	int ca_flags = 0, result;
+
+	dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
+	ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
+	if (!ca) {
+		dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
+		result = -ENOMEM;
+		goto err;
+	}
+
+	ca->ca_priv		= mantis;
+	mantis->mantis_ca	= ca;
+	ca_flags		= DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
+	/* register CA interface */
+	ca->en50221.owner		= THIS_MODULE;
+	ca->en50221.read_attribute_mem	= mantis_ca_read_attr_mem;
+	ca->en50221.write_attribute_mem	= mantis_ca_write_attr_mem;
+	ca->en50221.read_cam_control	= mantis_ca_read_cam_ctl;
+	ca->en50221.write_cam_control	= mantis_ca_write_cam_ctl;
+	ca->en50221.slot_reset		= mantis_ca_slot_reset;
+	ca->en50221.slot_shutdown	= mantis_ca_slot_shutdown;
+	ca->en50221.slot_ts_enable	= mantis_ts_control;
+	ca->en50221.poll_slot_status	= mantis_slot_status;
+	ca->en50221.data		= ca;
+
+	mutex_init(&ca->ca_lock);
+
+	init_waitqueue_head(&ca->hif_data_wq);
+	init_waitqueue_head(&ca->hif_opdone_wq);
+	init_waitqueue_head(&ca->hif_write_wq);
+
+	dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
+	result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
+	if (result != 0) {
+		dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
+		goto err;
+	}
+	dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
+	mantis_evmgr_init(ca);
+	return 0;
+err:
+	kfree(ca);
+	return result;
+}
+EXPORT_SYMBOL_GPL(mantis_ca_init);
+
+void mantis_ca_exit(struct mantis_pci *mantis)
+{
+	struct mantis_ca *ca = mantis->mantis_ca;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
+
+	mantis_evmgr_exit(ca);
+	dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
+	if (ca)
+		dvb_ca_en50221_release(&ca->en50221);
+
+	kfree(ca);
+}
+EXPORT_SYMBOL_GPL(mantis_ca_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ca.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ca.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ca.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,27 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_CA_H
+#define __MANTIS_CA_H
+
+extern int mantis_ca_init(struct mantis_pci *mantis);
+extern void mantis_ca_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_CA_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_cards.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_cards.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_cards.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,305 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/irq.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+
+#include "mantis_vp1033.h"
+#include "mantis_vp1034.h"
+#include "mantis_vp1041.h"
+#include "mantis_vp2033.h"
+#include "mantis_vp2040.h"
+#include "mantis_vp3030.h"
+
+#include "mantis_dma.h"
+#include "mantis_ca.h"
+#include "mantis_dvb.h"
+#include "mantis_uart.h"
+#include "mantis_ioc.h"
+#include "mantis_pci.h"
+#include "mantis_i2c.h"
+#include "mantis_reg.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+
+static int devs;
+
+#define DRIVER_NAME	"Mantis"
+
+static char *label[10] = {
+	"DMA",
+	"IRQ-0",
+	"IRQ-1",
+	"OCERR",
+	"PABRT",
+	"RIPRR",
+	"PPERR",
+	"FTRGT",
+	"RISCI",
+	"RACK"
+};
+
+static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
+{
+	u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
+	u32 rst_stat = 0, rst_mask = 0;
+
+	struct mantis_pci *mantis;
+	struct mantis_ca *ca;
+
+	mantis = (struct mantis_pci *) dev_id;
+	if (unlikely(mantis == NULL)) {
+		dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
+		return IRQ_NONE;
+	}
+	ca = mantis->mantis_ca;
+
+	stat = mmread(MANTIS_INT_STAT);
+	mask = mmread(MANTIS_INT_MASK);
+	mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
+	if (!(stat & mask))
+		return IRQ_NONE;
+
+	rst_mask  = MANTIS_GPIF_WRACK  |
+		    MANTIS_GPIF_OTHERR |
+		    MANTIS_SBUF_WSTO   |
+		    MANTIS_GPIF_EXTIRQ;
+
+	rst_stat  = mmread(MANTIS_GPIF_STATUS);
+	rst_stat &= rst_mask;
+	mmwrite(rst_stat, MANTIS_GPIF_STATUS);
+
+	mantis->mantis_int_stat = stat;
+	mantis->mantis_int_mask = mask;
+	dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
+	if (stat & MANTIS_INT_RISCEN) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
+	}
+	if (stat & MANTIS_INT_IRQ0) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
+		mantis->gpif_status = rst_stat;
+		wake_up(&ca->hif_write_wq);
+		schedule_work(&ca->hif_evm_work);
+	}
+	if (stat & MANTIS_INT_IRQ1) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
+		schedule_work(&mantis->uart_work);
+	}
+	if (stat & MANTIS_INT_OCERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
+	}
+	if (stat & MANTIS_INT_PABORT) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
+	}
+	if (stat & MANTIS_INT_RIPERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
+	}
+	if (stat & MANTIS_INT_PPERR) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
+	}
+	if (stat & MANTIS_INT_FTRGT) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
+	}
+	if (stat & MANTIS_INT_RISCI) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
+		mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
+		tasklet_schedule(&mantis->tasklet);
+	}
+	if (stat & MANTIS_INT_I2CDONE) {
+		dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
+		wake_up(&mantis->i2c_wq);
+	}
+	mmwrite(stat, MANTIS_INT_STAT);
+	stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
+		  MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
+		  MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
+		  MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
+		  MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
+		  MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1	   |
+		  MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
+		  MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
+		  MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
+		  MANTIS_INT_RISCI);
+
+	if (stat)
+		dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
+
+	dprintk(MANTIS_DEBUG, 0, "\n");
+	return IRQ_HANDLED;
+}
+
+static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+	struct mantis_pci *mantis;
+	struct mantis_hwconfig *config;
+	int err = 0;
+
+	mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
+	if (mantis == NULL) {
+		printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+		err = -ENOMEM;
+		goto fail0;
+	}
+
+	mantis->num		= devs;
+	mantis->verbose		= verbose;
+	mantis->pdev		= pdev;
+	config			= (struct mantis_hwconfig *) pci_id->driver_data;
+	config->irq_handler	= &mantis_irq_handler;
+	mantis->hwconfig	= config;
+
+	err = mantis_pci_init(mantis);
+	if (err) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
+		goto fail1;
+	}
+
+	err = mantis_stream_control(mantis, STREAM_TO_HIF);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
+		goto fail1;
+	}
+
+	err = mantis_i2c_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
+		goto fail2;
+	}
+
+	err = mantis_get_mac(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
+		goto fail2;
+	}
+
+	err = mantis_dma_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
+		goto fail3;
+	}
+
+	err = mantis_dvb_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
+		goto fail4;
+	}
+	err = mantis_uart_init(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err);
+		goto fail6;
+	}
+
+	devs++;
+
+	return err;
+
+
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
+	mantis_uart_exit(mantis);
+
+fail6:
+fail4:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
+	mantis_dma_exit(mantis);
+
+fail3:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
+	mantis_i2c_exit(mantis);
+
+fail2:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
+	mantis_pci_exit(mantis);
+
+fail1:
+	dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
+	kfree(mantis);
+
+fail0:
+	return err;
+}
+
+static void __devexit mantis_pci_remove(struct pci_dev *pdev)
+{
+	struct mantis_pci *mantis = pci_get_drvdata(pdev);
+
+	if (mantis) {
+
+		mantis_uart_exit(mantis);
+		mantis_dvb_exit(mantis);
+		mantis_dma_exit(mantis);
+		mantis_i2c_exit(mantis);
+		mantis_pci_exit(mantis);
+		kfree(mantis);
+	}
+	return;
+}
+
+static struct pci_device_id mantis_pci_table[] = {
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config),
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config),
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config),
+	MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config),
+	MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config),
+	MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config),
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config),
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config),
+	MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config),
+	MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config),
+	MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config),
+	{ }
+};
+
+static struct pci_driver mantis_pci_driver = {
+	.name		= DRIVER_NAME,
+	.id_table	= mantis_pci_table,
+	.probe		= mantis_pci_probe,
+	.remove		= mantis_pci_remove,
+};
+
+static int __devinit mantis_init(void)
+{
+	return pci_register_driver(&mantis_pci_driver);
+}
+
+static void __devexit mantis_exit(void)
+{
+	return pci_unregister_driver(&mantis_pci_driver);
+}
+
+module_init(mantis_init);
+module_exit(mantis_exit);
+
+MODULE_DESCRIPTION("MANTIS driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_common.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_common.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,179 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_COMMON_H
+#define __MANTIS_COMMON_H
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include "mantis_uart.h"
+
+#include "mantis_link.h"
+
+#define MANTIS_ERROR		0
+#define MANTIS_NOTICE		1
+#define MANTIS_INFO		2
+#define MANTIS_DEBUG		3
+#define MANTIS_TMG		9
+
+#define dprintk(y, z, format, arg...) do {								\
+	if (z) {											\
+		if	((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y))			\
+			printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if	((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y))			\
+			printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y))			\
+			printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y))			\
+			printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y))			\
+			printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+	} else {											\
+		if (mantis->verbose > y)								\
+			printk(format , ##arg);								\
+	}												\
+} while(0)
+
+#define mwrite(dat, addr)	writel((dat), addr)
+#define mread(addr)		readl(addr)
+
+#define mmwrite(dat, addr)	mwrite((dat), (mantis->mmio + (addr)))
+#define mmread(addr)		mread(mantis->mmio + (addr))
+
+#define MANTIS_TS_188		0
+#define MANTIS_TS_204		1
+
+#define TWINHAN_TECHNOLOGIES	0x1822
+#define MANTIS			0x4e35
+
+#define TECHNISAT		0x1ae4
+#define TERRATEC		0x153b
+
+#define MAKE_ENTRY(__subven, __subdev, __configptr) {			\
+		.vendor		= TWINHAN_TECHNOLOGIES,			\
+		.device		= MANTIS,				\
+		.subvendor	= (__subven),				\
+		.subdevice	= (__subdev),				\
+		.driver_data	= (unsigned long) (__configptr)		\
+}
+
+enum mantis_i2c_mode {
+	MANTIS_PAGE_MODE = 0,
+	MANTIS_BYTE_MODE,
+};
+
+struct mantis_pci;
+
+struct mantis_hwconfig {
+	char			*model_name;
+	char			*dev_type;
+	u32			ts_size;
+
+	enum mantis_baud	baud_rate;
+	enum mantis_parity	parity;
+	u32			bytes;
+
+	irqreturn_t (*irq_handler)(int irq, void *dev_id);
+	int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe);
+
+	u8			power;
+	u8			reset;
+
+	enum mantis_i2c_mode	i2c_mode;
+};
+
+struct mantis_pci {
+	unsigned int		verbose;
+
+	/*	PCI stuff		*/
+	u16			vendor_id;
+	u16			device_id;
+	u16			subsystem_vendor;
+	u16			subsystem_device;
+
+	u8			latency;
+
+	struct pci_dev		*pdev;
+
+	unsigned long		mantis_addr;
+	void __iomem		*mmio;
+
+	u8			irq;
+	u8			revision;
+
+	unsigned int		num;
+
+	/*	RISC Core		*/
+	u32			finished_block;
+	u32			last_block;
+	u32			line_bytes;
+	u32			line_count;
+	u32			risc_pos;
+	u8			*buf_cpu;
+	dma_addr_t		buf_dma;
+	u32			*risc_cpu;
+	dma_addr_t		risc_dma;
+
+	struct tasklet_struct	tasklet;
+
+	struct i2c_adapter	adapter;
+	int			i2c_rc;
+	wait_queue_head_t	i2c_wq;
+	struct mutex		i2c_lock;
+
+	/*	DVB stuff		*/
+	struct dvb_adapter	dvb_adapter;
+	struct dvb_frontend	*fe;
+	struct dvb_demux	demux;
+	struct dmxdev		dmxdev;
+	struct dmx_frontend	fe_hw;
+	struct dmx_frontend	fe_mem;
+	struct dvb_net		dvbnet;
+
+	u8			feeds;
+
+	struct mantis_hwconfig	*hwconfig;
+
+	u32			mantis_int_stat;
+	u32			mantis_int_mask;
+
+	/*	board specific		*/
+	u8			mac_address[8];
+	u32			sub_vendor_id;
+	u32			sub_device_id;
+
+	 /*	A12 A13 A14		*/
+	u32			gpio_status;
+
+	u32			gpif_status;
+
+	struct mantis_ca	*mantis_ca;
+
+	wait_queue_head_t	uart_wq;
+	struct work_struct	uart_work;
+	spinlock_t		uart_lock;
+
+	struct input_dev	*rc;
+};
+
+#define MANTIS_HIF_STATUS	(mantis->gpio_status)
+
+#endif /* __MANTIS_COMMON_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_core.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,238 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 "mantis_common.h"
+#include "mantis_core.h"
+#include "mantis_vp1033.h"
+#include "mantis_vp1034.h"
+#include "mantis_vp1041.h"
+#include "mantis_vp2033.h"
+#include "mantis_vp2040.h"
+#include "mantis_vp3030.h"
+
+static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
+{
+	int err;
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x50,
+			.flags = 0,
+			.buf = data,
+			.len = 1
+		}, {
+			.addr = 0x50,
+			.flags = I2C_M_RD,
+			.buf = data,
+			.len = length
+		},
+	};
+
+	err = i2c_transfer(&mantis->adapter, msg, 2);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
+			err, data[0], data[1]);
+
+		return err;
+	}
+
+	return 0;
+}
+
+static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
+{
+	int err;
+
+	struct i2c_msg msg = {
+		.addr = 0x50,
+		.flags = 0,
+		.buf = data,
+		.len = length
+	};
+
+	err = i2c_transfer(&mantis->adapter, &msg, 1);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
+			err, length, data[0], data[1]);
+
+		return err;
+	}
+
+	return 0;
+}
+
+static int get_mac_address(struct mantis_pci *mantis)
+{
+	int err;
+
+	mantis->mac_address[0] = 0x08;
+	err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
+
+		return err;
+	}
+	dprintk(verbose, MANTIS_ERROR, 0,
+		"    MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
+		mantis->mac_address[0], mantis->mac_address[1],
+		mantis->mac_address[2],	mantis->mac_address[3],
+		mantis->mac_address[4], mantis->mac_address[5]);
+
+	return 0;
+}
+
+#define MANTIS_MODEL_UNKNOWN	"UNKNOWN"
+#define MANTIS_DEV_UNKNOWN	"UNKNOWN"
+
+struct mantis_hwconfig unknown_device = {
+	.model_name	= MANTIS_MODEL_UNKNOWN,
+	.dev_type	= MANTIS_DEV_UNKNOWN,
+};
+
+static void mantis_load_config(struct mantis_pci *mantis)
+{
+	switch (mantis->subsystem_device) {
+	case MANTIS_VP_1033_DVB_S:	/* VP-1033 */
+		mantis->hwconfig = &vp1033_mantis_config;
+		break;
+	case MANTIS_VP_1034_DVB_S:	/* VP-1034 */
+		mantis->hwconfig = &vp1034_mantis_config;
+		break;
+	case MANTIS_VP_1041_DVB_S2:	/* VP-1041 */
+	case TECHNISAT_SKYSTAR_HD2:
+		mantis->hwconfig = &vp1041_mantis_config;
+		break;
+	case MANTIS_VP_2033_DVB_C:	/* VP-2033 */
+		mantis->hwconfig = &vp2033_mantis_config;
+		break;
+	case MANTIS_VP_2040_DVB_C:	/* VP-2040 */
+	case TERRATEC_CINERGY_C_PCI:	/* VP-2040 clone */
+	case TECHNISAT_CABLESTAR_HD2:
+		mantis->hwconfig = &vp2040_mantis_config;
+		break;
+	case MANTIS_VP_3030_DVB_T:	/* VP-3030 */
+		mantis->hwconfig = &vp3030_mantis_config;
+		break;
+	default:
+		mantis->hwconfig = &unknown_device;
+		break;
+	}
+}
+
+int mantis_core_init(struct mantis_pci *mantis)
+{
+	int err = 0;
+
+	mantis_load_config(mantis);
+	dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
+		mantis->hwconfig->model_name, mantis->hwconfig->dev_type,
+		mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));
+	dprintk(verbose, MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
+		mantis->revision,
+		mantis->subsystem_vendor, mantis->subsystem_device);
+	dprintk(verbose, MANTIS_ERROR, 0,
+		"irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
+		mantis->pdev->irq, mantis->latency,
+		mantis->mantis_addr, mantis->mantis_mmio);
+
+	err = mantis_i2c_init(mantis);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
+		return err;
+	}
+	err = get_mac_address(mantis);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
+		return err;
+	}
+	err = mantis_dma_init(mantis);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
+		return err;
+	}
+	err = mantis_dvb_init(mantis);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
+		return err;
+	}
+	err = mantis_uart_init(mantis);
+	if (err < 0) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed");
+		return err;
+	}
+
+	return 0;
+}
+
+int mantis_core_exit(struct mantis_pci *mantis)
+{
+	mantis_dma_stop(mantis);
+	dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");
+
+	mantis_uart_exit(mantis);
+	dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");
+
+	if (mantis_dma_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");
+	if (mantis_dvb_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed");
+	if (mantis_i2c_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed");
+
+	return 0;
+}
+
+/* Turn the given bit on or off. */
+void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+{
+	u32 cur;
+
+	cur = mmread(MANTIS_GPIF_ADDR);
+	if (value)
+		mantis->gpio_status = cur | (1 << bitpos);
+	else
+		mantis->gpio_status = cur & (~(1 << bitpos));
+
+	mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+	udelay(100);
+}
+
+/* direction = 0 , no CI passthrough ; 1 , CI passthrough */
+void mantis_set_direction(struct mantis_pci *mantis, int direction)
+{
+	u32 reg;
+
+	reg = mmread(0x28);
+	dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup");
+	if (direction == 0x01) {
+		/* to CI */
+		reg |= 0x04;
+		mmwrite(reg, 0x28);
+		reg &= 0xff - 0x04;
+		mmwrite(reg, 0x28);
+	} else {
+		reg &= 0xff - 0x04;
+		mmwrite(reg, 0x28);
+		reg |= 0x04;
+		mmwrite(reg, 0x28);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_core.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_core.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_core.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_CORE_H
+#define __MANTIS_CORE_H
+
+#include "mantis_common.h"
+
+
+#define FE_TYPE_SAT	0
+#define FE_TYPE_CAB	1
+#define FE_TYPE_TER	2
+
+#define FE_TYPE_TS204	0
+#define FE_TYPE_TS188	1
+
+
+struct vendorname {
+	u8  *sub_vendor_name;
+	u32 sub_vendor_id;
+};
+
+struct devicetype {
+	u8  *sub_device_name;
+	u32 sub_device_id;
+	u8  device_type;
+	u32 type_flags;
+};
+
+
+extern int mantis_dma_init(struct mantis_pci *mantis);
+extern int mantis_dma_exit(struct mantis_pci *mantis);
+extern void mantis_dma_start(struct mantis_pci *mantis);
+extern void mantis_dma_stop(struct mantis_pci *mantis);
+extern int mantis_i2c_init(struct mantis_pci *mantis);
+extern int mantis_i2c_exit(struct mantis_pci *mantis);
+extern int mantis_core_init(struct mantis_pci *mantis);
+extern int mantis_core_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_CORE_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dma.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dma.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,256 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 <asm/page.h>
+#include <linux/vmalloc.h>
+#include <linux/pci.h>
+
+#include <asm/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_dma.h"
+
+#define RISC_WRITE		(0x01 << 28)
+#define RISC_JUMP		(0x07 << 28)
+#define RISC_IRQ		(0x01 << 24)
+
+#define RISC_STATUS(status)	((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
+#define RISC_FLUSH()		(mantis->risc_pos = 0)
+#define RISC_INSTR(opcode)	(mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode))
+
+#define MANTIS_BUF_SIZE		(64 * 1024)
+#define MANTIS_BLOCK_BYTES	(MANTIS_BUF_SIZE >> 4)
+#define MANTIS_BLOCK_COUNT	(1 << 4)
+#define MANTIS_RISC_SIZE	PAGE_SIZE
+
+int mantis_dma_exit(struct mantis_pci *mantis)
+{
+	if (mantis->buf_cpu) {
+		dprintk(MANTIS_ERROR, 1,
+			"DMA=0x%lx cpu=0x%p size=%d",
+			(unsigned long) mantis->buf_dma,
+			 mantis->buf_cpu,
+			 MANTIS_BUF_SIZE);
+
+		pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE,
+				    mantis->buf_cpu, mantis->buf_dma);
+
+		mantis->buf_cpu = NULL;
+	}
+	if (mantis->risc_cpu) {
+		dprintk(MANTIS_ERROR, 1,
+			"RISC=0x%lx cpu=0x%p size=%lx",
+			(unsigned long) mantis->risc_dma,
+			mantis->risc_cpu,
+			MANTIS_RISC_SIZE);
+
+		pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE,
+				    mantis->risc_cpu, mantis->risc_dma);
+
+		mantis->risc_cpu = NULL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_dma_exit);
+
+static inline int mantis_alloc_buffers(struct mantis_pci *mantis)
+{
+	if (!mantis->buf_cpu) {
+		mantis->buf_cpu = pci_alloc_consistent(mantis->pdev,
+						       MANTIS_BUF_SIZE,
+						       &mantis->buf_dma);
+		if (!mantis->buf_cpu) {
+			dprintk(MANTIS_ERROR, 1,
+				"DMA buffer allocation failed");
+
+			goto err;
+		}
+		dprintk(MANTIS_ERROR, 1,
+			"DMA=0x%lx cpu=0x%p size=%d",
+			(unsigned long) mantis->buf_dma,
+			mantis->buf_cpu, MANTIS_BUF_SIZE);
+	}
+	if (!mantis->risc_cpu) {
+		mantis->risc_cpu = pci_alloc_consistent(mantis->pdev,
+							MANTIS_RISC_SIZE,
+							&mantis->risc_dma);
+
+		if (!mantis->risc_cpu) {
+			dprintk(MANTIS_ERROR, 1,
+				"RISC program allocation failed");
+
+			mantis_dma_exit(mantis);
+
+			goto err;
+		}
+		dprintk(MANTIS_ERROR, 1,
+			"RISC=0x%lx cpu=0x%p size=%lx",
+			(unsigned long) mantis->risc_dma,
+			mantis->risc_cpu, MANTIS_RISC_SIZE);
+	}
+
+	return 0;
+err:
+	dprintk(MANTIS_ERROR, 1, "Out of memory (?) .....");
+	return -ENOMEM;
+}
+
+static inline int mantis_calc_lines(struct mantis_pci *mantis)
+{
+	mantis->line_bytes = MANTIS_BLOCK_BYTES;
+	mantis->line_count = MANTIS_BLOCK_COUNT;
+
+	while (mantis->line_bytes > 4095) {
+		mantis->line_bytes >>= 1;
+		mantis->line_count <<= 1;
+	}
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]",
+		MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count);
+
+	if (mantis->line_count > 255) {
+		dprintk(MANTIS_ERROR, 1, "Buffer size error");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int mantis_dma_init(struct mantis_pci *mantis)
+{
+	int err = 0;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis DMA init");
+	if (mantis_alloc_buffers(mantis) < 0) {
+		dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
+
+		/* Stop RISC Engine */
+		mmwrite(0, MANTIS_DMA_CTL);
+
+		goto err;
+	}
+	err = mantis_calc_lines(mantis);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed");
+
+		goto err;
+	}
+
+	return 0;
+err:
+	return err;
+}
+EXPORT_SYMBOL_GPL(mantis_dma_init);
+
+static inline void mantis_risc_program(struct mantis_pci *mantis)
+{
+	u32 buf_pos = 0;
+	u32 line;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
+	RISC_FLUSH();
+
+	dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u",
+		mantis->line_count, mantis->line_bytes);
+
+	for (line = 0; line < mantis->line_count; line++) {
+		dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line);
+		if (!(buf_pos % MANTIS_BLOCK_BYTES)) {
+			RISC_INSTR(RISC_WRITE	|
+				   RISC_IRQ	|
+				   RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) +
+				   (MANTIS_BLOCK_COUNT - 1)) %
+				    MANTIS_BLOCK_COUNT) |
+				    mantis->line_bytes);
+		} else {
+			RISC_INSTR(RISC_WRITE	| mantis->line_bytes);
+		}
+		RISC_INSTR(mantis->buf_dma + buf_pos);
+		buf_pos += mantis->line_bytes;
+	}
+	RISC_INSTR(RISC_JUMP);
+	RISC_INSTR(mantis->risc_dma);
+}
+
+void mantis_dma_start(struct mantis_pci *mantis)
+{
+	dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine");
+
+	mantis_risc_program(mantis);
+	mmwrite(mantis->risc_dma, MANTIS_RISC_START);
+	mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+	mmwrite(0, MANTIS_DMA_CTL);
+	mantis->last_block = mantis->finished_block = 0;
+
+	mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK);
+
+	mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN
+			       | MANTIS_RISC_EN, MANTIS_DMA_CTL);
+
+}
+
+void mantis_dma_stop(struct mantis_pci *mantis)
+{
+	u32 stat = 0, mask = 0;
+
+	stat = mmread(MANTIS_INT_STAT);
+	mask = mmread(MANTIS_INT_MASK);
+	dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
+
+	mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR);
+
+	mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN |
+					    MANTIS_DCAP_EN |
+					    MANTIS_RISC_EN)), MANTIS_DMA_CTL);
+
+	mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT);
+
+	mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI |
+					    MANTIS_INT_RISCEN), MANTIS_INT_MASK);
+}
+
+
+void mantis_dma_xfer(unsigned long data)
+{
+	struct mantis_pci *mantis = (struct mantis_pci *) data;
+	struct mantis_hwconfig *config = mantis->hwconfig;
+
+	while (mantis->last_block != mantis->finished_block) {
+		dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
+			mantis->last_block, mantis->finished_block);
+
+		(config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
+		(&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);
+		mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT;
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dma.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dma.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_DMA_H
+#define __MANTIS_DMA_H
+
+extern int mantis_dma_init(struct mantis_pci *mantis);
+extern int mantis_dma_exit(struct mantis_pci *mantis);
+extern void mantis_dma_start(struct mantis_pci *mantis);
+extern void mantis_dma_stop(struct mantis_pci *mantis);
+extern void mantis_dma_xfer(unsigned long data);
+
+#endif /* __MANTIS_DMA_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dvb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dvb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,296 @@
+/*
+	Mantis PCI bridge driver
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/bitops.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_dma.h"
+#include "mantis_ca.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
+{
+	struct mantis_hwconfig *config = mantis->hwconfig;
+
+	switch (power) {
+	case POWER_ON:
+		dprintk(MANTIS_DEBUG, 1, "Power ON");
+		gpio_set_bits(mantis, config->power, POWER_ON);
+		msleep(100);
+		gpio_set_bits(mantis, config->power, POWER_ON);
+		msleep(100);
+		break;
+
+	case POWER_OFF:
+		dprintk(MANTIS_DEBUG, 1, "Power OFF");
+		gpio_set_bits(mantis, config->power, POWER_OFF);
+		msleep(100);
+		break;
+
+	default:
+		dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
+		return -1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_frontend_power);
+
+void mantis_frontend_soft_reset(struct mantis_pci *mantis)
+{
+	struct mantis_hwconfig *config = mantis->hwconfig;
+
+	dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
+	gpio_set_bits(mantis, config->reset, 0);
+	msleep(100);
+	gpio_set_bits(mantis, config->reset, 0);
+	msleep(100);
+	gpio_set_bits(mantis, config->reset, 1);
+	msleep(100);
+	gpio_set_bits(mantis, config->reset, 1);
+	msleep(100);
+
+	return;
+}
+EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
+
+static int mantis_frontend_shutdown(struct mantis_pci *mantis)
+{
+	int err;
+
+	mantis_frontend_soft_reset(mantis);
+	err = mantis_frontend_power(mantis, POWER_OFF);
+	if (err != 0) {
+		dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct mantis_pci *mantis = dvbdmx->priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
+	if (!dvbdmx->dmx.frontend) {
+		dprintk(MANTIS_DEBUG, 1, "no frontend ?");
+		return -EINVAL;
+	}
+
+	mantis->feeds++;
+	dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d",	mantis->feeds);
+
+	if (mantis->feeds == 1)	 {
+		dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
+		mantis_dma_start(mantis);
+	}
+
+	return mantis->feeds;
+}
+
+static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct mantis_pci *mantis = dvbdmx->priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
+	if (!dvbdmx->dmx.frontend) {
+		dprintk(MANTIS_DEBUG, 1, "no frontend ?");
+		return -EINVAL;
+	}
+
+	mantis->feeds--;
+	if (mantis->feeds == 0) {
+		dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
+		mantis_dma_stop(mantis);
+	}
+
+	return 0;
+}
+
+int __devinit mantis_dvb_init(struct mantis_pci *mantis)
+{
+	struct mantis_hwconfig *config = mantis->hwconfig;
+	int result = -1;
+
+	dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
+
+	result = dvb_register_adapter(&mantis->dvb_adapter,
+				      "Mantis DVB adapter",
+				      THIS_MODULE,
+				      &mantis->pdev->dev,
+				      adapter_nr);
+
+	if (result < 0) {
+
+		dprintk(MANTIS_ERROR, 1, "Error registering adapter");
+		return -ENODEV;
+	}
+
+	mantis->dvb_adapter.priv	= mantis;
+	mantis->demux.dmx.capabilities	= DMX_TS_FILTERING	|
+					 DMX_SECTION_FILTERING	|
+					 DMX_MEMORY_BASED_FILTERING;
+
+	mantis->demux.priv		= mantis;
+	mantis->demux.filternum		= 256;
+	mantis->demux.feednum		= 256;
+	mantis->demux.start_feed	= mantis_dvb_start_feed;
+	mantis->demux.stop_feed		= mantis_dvb_stop_feed;
+	mantis->demux.write_to_decoder	= NULL;
+
+	dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
+	result = dvb_dmx_init(&mantis->demux);
+	if (result < 0) {
+		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+
+		goto err0;
+	}
+
+	mantis->dmxdev.filternum	= 256;
+	mantis->dmxdev.demux		= &mantis->demux.dmx;
+	mantis->dmxdev.capabilities	= 0;
+	dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
+
+	result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
+	if (result < 0) {
+
+		dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
+		goto err1;
+	}
+
+	mantis->fe_hw.source		= DMX_FRONTEND_0;
+	result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+	if (result < 0) {
+
+		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+		goto err2;
+	}
+
+	mantis->fe_mem.source		= DMX_MEMORY_FE;
+	result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+	if (result < 0) {
+		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+		goto err3;
+	}
+
+	result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+	if (result < 0) {
+		dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
+		goto err4;
+	}
+
+	dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
+	tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
+	if (mantis->hwconfig) {
+		result = config->frontend_init(mantis, mantis->fe);
+		if (result < 0) {
+			dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
+			goto err5;
+		} else {
+			if (mantis->fe == NULL) {
+				dprintk(MANTIS_ERROR, 1, "FE <NULL>");
+				goto err5;
+			}
+
+			if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
+				dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
+
+				if (mantis->fe->ops.release)
+					mantis->fe->ops.release(mantis->fe);
+
+				mantis->fe = NULL;
+				goto err5;
+			}
+		}
+	}
+
+	return 0;
+
+	/* Error conditions ..	*/
+err5:
+	tasklet_kill(&mantis->tasklet);
+	dvb_net_release(&mantis->dvbnet);
+	dvb_unregister_frontend(mantis->fe);
+	dvb_frontend_detach(mantis->fe);
+err4:
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+
+err3:
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+
+err2:
+	dvb_dmxdev_release(&mantis->dmxdev);
+
+err1:
+	dvb_dmx_release(&mantis->demux);
+
+err0:
+	dvb_unregister_adapter(&mantis->dvb_adapter);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(mantis_dvb_init);
+
+int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
+{
+	int err;
+
+	if (mantis->fe) {
+		/* mantis_ca_exit(mantis); */
+		err = mantis_frontend_shutdown(mantis);
+		if (err != 0)
+			dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
+		dvb_unregister_frontend(mantis->fe);
+		dvb_frontend_detach(mantis->fe);
+	}
+
+	tasklet_kill(&mantis->tasklet);
+	dvb_net_release(&mantis->dvbnet);
+
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+
+	dvb_dmxdev_release(&mantis->dmxdev);
+	dvb_dmx_release(&mantis->demux);
+
+	dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
+	dvb_unregister_adapter(&mantis->dvb_adapter);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_dvb_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dvb.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dvb.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_dvb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_dvb.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_DVB_H
+#define __MANTIS_DVB_H
+
+enum mantis_power {
+	POWER_OFF	= 0,
+	POWER_ON	= 1
+};
+
+extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power);
+extern void mantis_frontend_soft_reset(struct mantis_pci *mantis);
+
+extern int mantis_dvb_init(struct mantis_pci *mantis);
+extern int mantis_dvb_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_DVB_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_evm.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_evm.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_evm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_evm.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,117 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h"
+#include "mantis_hif.h"
+#include "mantis_reg.h"
+
+static void mantis_hifevm_work(struct work_struct *work)
+{
+	struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	u32 gpif_stat, gpif_mask;
+
+	gpif_stat = mmread(MANTIS_GPIF_STATUS);
+	gpif_mask = mmread(MANTIS_GPIF_IRQCFG);
+
+	if (gpif_stat & MANTIS_GPIF_DETSTAT) {
+		if (gpif_stat & MANTIS_CARD_PLUGIN) {
+			dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num);
+			mmwrite(0xdada0000, MANTIS_CARD_RESET);
+			mantis_event_cam_plugin(ca);
+			dvb_ca_en50221_camchange_irq(&ca->en50221,
+						     0,
+						     DVB_CA_EN50221_CAMCHANGE_INSERTED);
+		}
+	} else {
+		if (gpif_stat & MANTIS_CARD_PLUGOUT) {
+			dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num);
+			mmwrite(0xdada0000, MANTIS_CARD_RESET);
+			mantis_event_cam_unplug(ca);
+			dvb_ca_en50221_camchange_irq(&ca->en50221,
+						     0,
+						     DVB_CA_EN50221_CAMCHANGE_REMOVED);
+		}
+	}
+
+	if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num);
+
+	if (mantis->gpif_status & MANTIS_SBUF_WSTO)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num);
+
+	if (mantis->gpif_status & MANTIS_GPIF_OTHERR)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num);
+
+	if (gpif_stat & MANTIS_SBUF_OVFLW)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num);
+
+	if (gpif_stat & MANTIS_GPIF_BRRDY)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num);
+
+	if (gpif_stat & MANTIS_GPIF_INTSTAT)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num);
+
+	if (gpif_stat & MANTIS_SBUF_EMPTY)
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
+
+	if (gpif_stat & MANTIS_SBUF_OPDONE) {
+		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
+		ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
+		ca->hif_event = MANTIS_SBUF_OPDONE;
+		wake_up(&ca->hif_opdone_wq);
+	}
+}
+
+int mantis_evmgr_init(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager");
+	INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work);
+	mantis_pcmcia_init(ca);
+	schedule_work(&ca->hif_evm_work);
+	mantis_hif_init(ca);
+	return 0;
+}
+
+void mantis_evmgr_exit(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
+	flush_scheduled_work();
+	mantis_hif_exit(ca);
+	mantis_pcmcia_exit(ca);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_hif.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_hif.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,240 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+
+#include "mantis_hif.h"
+#include "mantis_link.h" /* temporary due to physical layer stuff */
+
+#include "mantis_reg.h"
+
+
+static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	int rc = 0;
+
+	if (wait_event_timeout(ca->hif_opdone_wq,
+			       ca->hif_event & MANTIS_SBUF_OPDONE,
+			       msecs_to_jiffies(500)) == -ERESTARTSYS) {
+
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
+		rc = -EREMOTEIO;
+	}
+	dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
+	ca->hif_event &= ~MANTIS_SBUF_OPDONE;
+	return rc;
+}
+
+static int mantis_hif_write_wait(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 opdone = 0, timeout = 0;
+	int rc = 0;
+
+	if (wait_event_timeout(ca->hif_write_wq,
+			       mantis->gpif_status & MANTIS_GPIF_WRACK,
+			       msecs_to_jiffies(500)) == -ERESTARTSYS) {
+
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
+		rc = -EREMOTEIO;
+	}
+	dprintk(MANTIS_DEBUG, 1, "Write Acknowledged");
+	mantis->gpif_status &= ~MANTIS_GPIF_WRACK;
+	while (!opdone) {
+		opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE);
+		udelay(500);
+		timeout++;
+		if (timeout > 100) {
+			dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num);
+			rc = -ETIMEDOUT;
+			break;
+		}
+	}
+	dprintk(MANTIS_DEBUG, 1, "HIF Write success");
+	return rc;
+}
+
+
+int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 hif_addr = 0, data, count = 4;
+
+	dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num);
+	mutex_lock(&ca->ca_lock);
+	hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+	hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
+	hif_addr |=  MANTIS_HIF_STATUS;
+	hif_addr |=  addr;
+
+	mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
+	mmwrite(count, MANTIS_GPIF_BRBYTES);
+	udelay(20);
+	mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+	if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num);
+		mutex_unlock(&ca->ca_lock);
+		return -EREMOTEIO;
+	}
+	data = mmread(MANTIS_GPIF_DIN);
+	mutex_unlock(&ca->ca_lock);
+	dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data);
+	return (data >> 24) & 0xff;
+}
+
+int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
+{
+	struct mantis_slot *slot = ca->slot;
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 hif_addr = 0;
+
+	dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
+	mutex_lock(&ca->ca_lock);
+	hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
+	hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+	hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
+	hif_addr |=  MANTIS_HIF_STATUS;
+	hif_addr |=  addr;
+
+	mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */
+	mmwrite(hif_addr, MANTIS_GPIF_ADDR);
+	mmwrite(data, MANTIS_GPIF_DOUT);
+
+	if (mantis_hif_write_wait(ca) != 0) {
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+		mutex_unlock(&ca->ca_lock);
+		return -EREMOTEIO;
+	}
+	dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr);
+	mutex_unlock(&ca->ca_lock);
+
+	return 0;
+}
+
+int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 data, hif_addr = 0;
+
+	dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num);
+	mutex_lock(&ca->ca_lock);
+	hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+	hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
+	hif_addr |=  MANTIS_HIF_STATUS;
+	hif_addr |=  addr;
+
+	mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
+	mmwrite(1, MANTIS_GPIF_BRBYTES);
+	udelay(20);
+	mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
+
+	if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+		mutex_unlock(&ca->ca_lock);
+		return -EREMOTEIO;
+	}
+	data = mmread(MANTIS_GPIF_DIN);
+	dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data);
+	udelay(50);
+	mutex_unlock(&ca->ca_lock);
+
+	return (u8) data;
+}
+
+int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 hif_addr = 0;
+
+	dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
+	mutex_lock(&ca->ca_lock);
+	hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
+	hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
+	hif_addr |=  MANTIS_GPIF_PCMCIAIOM;
+	hif_addr |=  MANTIS_HIF_STATUS;
+	hif_addr |=  addr;
+
+	mmwrite(hif_addr, MANTIS_GPIF_ADDR);
+	mmwrite(data, MANTIS_GPIF_DOUT);
+
+	if (mantis_hif_write_wait(ca) != 0) {
+		dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
+		mutex_unlock(&ca->ca_lock);
+		return -EREMOTEIO;
+	}
+	dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr);
+	mutex_unlock(&ca->ca_lock);
+	udelay(50);
+
+	return 0;
+}
+
+int mantis_hif_init(struct mantis_ca *ca)
+{
+	struct mantis_slot *slot = ca->slot;
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 irqcfg;
+
+	slot[0].slave_cfg = 0x70773028;
+	dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num);
+
+	mutex_lock(&ca->ca_lock);
+	irqcfg = mmread(MANTIS_GPIF_IRQCFG);
+	irqcfg = MANTIS_MASK_BRRDY	|
+		 MANTIS_MASK_WRACK	|
+		 MANTIS_MASK_EXTIRQ	|
+		 MANTIS_MASK_WSTO	|
+		 MANTIS_MASK_OTHERR	|
+		 MANTIS_MASK_OVFLW;
+
+	mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
+	mutex_unlock(&ca->ca_lock);
+
+	return 0;
+}
+
+void mantis_hif_exit(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+	u32 irqcfg;
+
+	dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num);
+	mutex_lock(&ca->ca_lock);
+	irqcfg = mmread(MANTIS_GPIF_IRQCFG);
+	irqcfg &= ~MANTIS_MASK_BRRDY;
+	mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
+	mutex_unlock(&ca->ca_lock);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_hif.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_hif.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_hif.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_HIF_H
+#define __MANTIS_HIF_H
+
+#define MANTIS_HIF_MEMRD		1
+#define MANTIS_HIF_MEMWR		2
+#define MANTIS_HIF_IOMRD		3
+#define MANTIS_HIF_IOMWR		4
+
+#endif /* __MANTIS_HIF_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_i2c.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,267 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 <asm/io.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_i2c.h"
+
+#define TRIALS			10000
+
+static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+	u32 rxd, i, stat, trials;
+
+	dprintk(MANTIS_INFO, 0, "        %s:  Address=[0x%02x] <R>[ ",
+		__func__, msg->addr);
+
+	for (i = 0; i < msg->len; i++) {
+		rxd = (msg->addr << 25) | (1 << 24)
+					| MANTIS_I2C_RATE_3
+					| MANTIS_I2C_STOP
+					| MANTIS_I2C_PGMODE;
+
+		if (i == (msg->len - 1))
+			rxd &= ~MANTIS_I2C_STOP;
+
+		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
+		mmwrite(rxd, MANTIS_I2CDATA_CTL);
+
+		/* wait for xfer completion */
+		for (trials = 0; trials < TRIALS; trials++) {
+			stat = mmread(MANTIS_INT_STAT);
+			if (stat & MANTIS_INT_I2CDONE)
+				break;
+		}
+
+		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
+
+		/* wait for xfer completion */
+		for (trials = 0; trials < TRIALS; trials++) {
+			stat = mmread(MANTIS_INT_STAT);
+			if (stat & MANTIS_INT_I2CRACK)
+				break;
+		}
+
+		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
+
+		rxd = mmread(MANTIS_I2CDATA_CTL);
+		msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
+		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
+	}
+	dprintk(MANTIS_INFO, 0, "]\n");
+
+	return 0;
+}
+
+static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+	int i;
+	u32 txd = 0, stat, trials;
+
+	dprintk(MANTIS_INFO, 0, "        %s: Address=[0x%02x] <W>[ ",
+		__func__, msg->addr);
+
+	for (i = 0; i < msg->len; i++) {
+		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
+		txd = (msg->addr << 25) | (msg->buf[i] << 8)
+					| MANTIS_I2C_RATE_3
+					| MANTIS_I2C_STOP
+					| MANTIS_I2C_PGMODE;
+
+		if (i == (msg->len - 1))
+			txd &= ~MANTIS_I2C_STOP;
+
+		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
+		mmwrite(txd, MANTIS_I2CDATA_CTL);
+
+		/* wait for xfer completion */
+		for (trials = 0; trials < TRIALS; trials++) {
+			stat = mmread(MANTIS_INT_STAT);
+			if (stat & MANTIS_INT_I2CDONE)
+				break;
+		}
+
+		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
+
+		/* wait for xfer completion */
+		for (trials = 0; trials < TRIALS; trials++) {
+			stat = mmread(MANTIS_INT_STAT);
+			if (stat & MANTIS_INT_I2CRACK)
+				break;
+		}
+
+		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
+	}
+	dprintk(MANTIS_INFO, 0, "]\n");
+
+	return 0;
+}
+
+static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	int ret = 0, i = 0, trials;
+	u32 stat, data, txd;
+	struct mantis_pci *mantis;
+	struct mantis_hwconfig *config;
+
+	mantis = i2c_get_adapdata(adapter);
+	BUG_ON(!mantis);
+	config = mantis->hwconfig;
+	BUG_ON(!config);
+
+	dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
+	mutex_lock(&mantis->i2c_lock);
+
+	while (i < num) {
+		/* Byte MODE */
+		if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
+		    ((i + 1) < num)			&&
+		    (msgs[i].len < 2)			&&
+		    (msgs[i + 1].len < 2)		&&
+		    (msgs[i + 1].flags & I2C_M_RD)) {
+
+			dprintk(MANTIS_DEBUG, 0, "        Byte MODE:\n");
+
+			/* Read operation */
+			txd = msgs[i].addr << 25 | (0x1 << 24)
+						 | (msgs[i].buf[0] << 16)
+						 | MANTIS_I2C_RATE_3;
+
+			mmwrite(txd, MANTIS_I2CDATA_CTL);
+			/* wait for xfer completion */
+			for (trials = 0; trials < TRIALS; trials++) {
+				stat = mmread(MANTIS_INT_STAT);
+				if (stat & MANTIS_INT_I2CDONE)
+					break;
+			}
+
+			/* check for xfer completion */
+			if (stat & MANTIS_INT_I2CDONE) {
+				/* check xfer was acknowledged */
+				if (stat & MANTIS_INT_I2CRACK) {
+					data = mmread(MANTIS_I2CDATA_CTL);
+					msgs[i + 1].buf[0] = (data >> 8) & 0xff;
+					dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
+				} else {
+					/* I/O error */
+					dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
+					ret = -EIO;
+					break;
+				}
+			} else {
+				/* I/O error */
+				dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
+				ret = -EIO;
+				break;
+			}
+			i += 2; /* Write/Read operation in one go */
+		}
+
+		if (i < num) {
+			if (msgs[i].flags & I2C_M_RD)
+				ret = mantis_i2c_read(mantis, &msgs[i]);
+			else
+				ret = mantis_i2c_write(mantis, &msgs[i]);
+
+			i++;
+			if (ret < 0)
+				goto bail_out;
+		}
+
+	}
+
+	mutex_unlock(&mantis->i2c_lock);
+
+	return num;
+
+bail_out:
+	mutex_unlock(&mantis->i2c_lock);
+	return ret;
+}
+
+static u32 mantis_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm mantis_algo = {
+	.master_xfer		= mantis_i2c_xfer,
+	.functionality		= mantis_i2c_func,
+};
+
+int __devinit mantis_i2c_init(struct mantis_pci *mantis)
+{
+	u32 intstat, intmask;
+	struct i2c_adapter *i2c_adapter = &mantis->adapter;
+	struct pci_dev *pdev		= mantis->pdev;
+
+	init_waitqueue_head(&mantis->i2c_wq);
+	mutex_init(&mantis->i2c_lock);
+	strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
+	i2c_set_adapdata(i2c_adapter, mantis);
+
+	i2c_adapter->owner	= THIS_MODULE;
+	i2c_adapter->class	= I2C_CLASS_TV_DIGITAL;
+	i2c_adapter->algo	= &mantis_algo;
+	i2c_adapter->algo_data	= NULL;
+	i2c_adapter->timeout	= 500;
+	i2c_adapter->retries	= 3;
+	i2c_adapter->dev.parent	= &pdev->dev;
+
+	mantis->i2c_rc		= i2c_add_adapter(i2c_adapter);
+	if (mantis->i2c_rc < 0)
+		return mantis->i2c_rc;
+
+	dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
+
+	intstat = mmread(MANTIS_INT_STAT);
+	intmask = mmread(MANTIS_INT_MASK);
+	mmwrite(intstat, MANTIS_INT_STAT);
+	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+	intmask = mmread(MANTIS_INT_MASK);
+	mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_i2c_init);
+
+int mantis_i2c_exit(struct mantis_pci *mantis)
+{
+	u32 intmask;
+
+	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
+	intmask = mmread(MANTIS_INT_MASK);
+	mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
+
+	dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
+	return i2c_del_adapter(&mantis->adapter);
+}
+EXPORT_SYMBOL_GPL(mantis_i2c_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_i2c.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_i2c.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_i2c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_i2c.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_I2C_H
+#define __MANTIS_I2C_H
+
+#define I2C_STOP		(1 <<  0)
+#define I2C_READ		(1 <<  1)
+
+extern int mantis_i2c_init(struct mantis_pci *mantis);
+extern int mantis_i2c_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_I2C_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_input.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_input.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_input.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_input.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,148 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/input.h>
+#include <media/ir-common.h>
+#include <linux/pci.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_uart.h"
+
+static struct ir_scancode mantis_ir_table[] = {
+	{ 0x29, KEY_POWER	},
+	{ 0x28, KEY_FAVORITES	},
+	{ 0x30, KEY_TEXT	},
+	{ 0x17, KEY_INFO	}, /* Preview */
+	{ 0x23, KEY_EPG		},
+	{ 0x3b, KEY_F22		}, /* Record List */
+	{ 0x3c, KEY_1		},
+	{ 0x3e, KEY_2		},
+	{ 0x39, KEY_3		},
+	{ 0x36, KEY_4		},
+	{ 0x22, KEY_5		},
+	{ 0x20, KEY_6		},
+	{ 0x32, KEY_7		},
+	{ 0x26, KEY_8		},
+	{ 0x24, KEY_9		},
+	{ 0x2a, KEY_0		},
+
+	{ 0x33, KEY_CANCEL	},
+	{ 0x2c, KEY_BACK	},
+	{ 0x15, KEY_CLEAR	},
+	{ 0x3f, KEY_TAB		},
+	{ 0x10, KEY_ENTER	},
+	{ 0x14, KEY_UP		},
+	{ 0x0d, KEY_RIGHT	},
+	{ 0x0e, KEY_DOWN	},
+	{ 0x11, KEY_LEFT	},
+
+	{ 0x21, KEY_VOLUMEUP	},
+	{ 0x35, KEY_VOLUMEDOWN	},
+	{ 0x3d, KEY_CHANNELDOWN	},
+	{ 0x3a, KEY_CHANNELUP	},
+	{ 0x2e, KEY_RECORD	},
+	{ 0x2b, KEY_PLAY	},
+	{ 0x13, KEY_PAUSE	},
+	{ 0x25, KEY_STOP	},
+
+	{ 0x1f, KEY_REWIND	},
+	{ 0x2d, KEY_FASTFORWARD	},
+	{ 0x1e, KEY_PREVIOUS	}, /* Replay |< */
+	{ 0x1d, KEY_NEXT	}, /* Skip   >| */
+
+	{ 0x0b, KEY_CAMERA	}, /* Capture */
+	{ 0x0f, KEY_LANGUAGE	}, /* SAP */
+	{ 0x18, KEY_MODE	}, /* PIP */
+	{ 0x12, KEY_ZOOM	}, /* Full screen */
+	{ 0x1c, KEY_SUBTITLE	},
+	{ 0x2f, KEY_MUTE	},
+	{ 0x16, KEY_F20		}, /* L/R */
+	{ 0x38, KEY_F21		}, /* Hibernate */
+
+	{ 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */
+	{ 0x31, KEY_AGAIN	}, /* Recall */
+	{ 0x1a, KEY_KPPLUS	}, /* Zoom+ */
+	{ 0x19, KEY_KPMINUS	}, /* Zoom- */
+	{ 0x27, KEY_RED		},
+	{ 0x0C, KEY_GREEN	},
+	{ 0x01, KEY_YELLOW	},
+	{ 0x00, KEY_BLUE	},
+};
+
+struct ir_scancode_table ir_mantis = {
+	.scan = mantis_ir_table,
+	.size = ARRAY_SIZE(mantis_ir_table),
+};
+EXPORT_SYMBOL_GPL(ir_mantis);
+
+int mantis_input_init(struct mantis_pci *mantis)
+{
+	struct input_dev *rc;
+	struct ir_input_state rc_state;
+	char name[80], dev[80];
+	int err;
+
+	rc = input_allocate_device();
+	if (!rc) {
+		dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
+		return -ENOMEM;
+	}
+
+	sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
+	sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
+
+	rc->name = name;
+	rc->phys = dev;
+
+	ir_input_init(rc, &rc_state, IR_TYPE_OTHER);
+
+	rc->id.bustype	= BUS_PCI;
+	rc->id.vendor	= mantis->vendor_id;
+	rc->id.product	= mantis->device_id;
+	rc->id.version	= 1;
+	rc->dev		= mantis->pdev->dev;
+
+	err = ir_input_register(rc, &ir_mantis);
+	if (err) {
+		dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
+		input_free_device(rc);
+		return -ENODEV;
+	}
+
+	mantis->rc = rc;
+
+	return 0;
+}
+
+int mantis_exit(struct mantis_pci *mantis)
+{
+	struct input_dev *rc = mantis->rc;
+
+	ir_input_unregister(rc);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ioc.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ioc.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ioc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ioc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,130 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/i2c.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_ioc.h"
+
+static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
+{
+	struct i2c_adapter *adapter = &mantis->adapter;
+	int err;
+	u8 buf = reg;
+
+	struct i2c_msg msg[] = {
+		{ .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
+		{ .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
+	};
+
+	err = i2c_transfer(adapter, msg, 2);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
+			err, data[0], data[1]);
+
+		return err;
+	}
+
+	return 0;
+}
+int mantis_get_mac(struct mantis_pci *mantis)
+{
+	int err;
+	u8 mac_addr[6] = {0};
+
+	err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
+	if (err < 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
+
+		return err;
+	}
+
+	dprintk(MANTIS_ERROR, 0,
+		"    MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
+		mac_addr[0],
+		mac_addr[1],
+		mac_addr[2],
+		mac_addr[3],
+		mac_addr[4],
+		mac_addr[5]);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_get_mac);
+
+/* Turn the given bit on or off. */
+void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+{
+	u32 cur;
+
+	dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
+	cur = mmread(MANTIS_GPIF_ADDR);
+	if (value)
+		mantis->gpio_status = cur | (1 << bitpos);
+	else
+		mantis->gpio_status = cur & (~(1 << bitpos));
+
+	dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
+	mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+}
+EXPORT_SYMBOL_GPL(gpio_set_bits);
+
+int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
+{
+	u32 reg;
+
+	reg = mmread(MANTIS_CONTROL);
+	switch (stream_ctl) {
+	case STREAM_TO_HIF:
+		dprintk(MANTIS_DEBUG, 1, "Set stream to HIF");
+		reg &= 0xff - MANTIS_BYPASS;
+		mmwrite(reg, MANTIS_CONTROL);
+		reg |= MANTIS_BYPASS;
+		mmwrite(reg, MANTIS_CONTROL);
+		break;
+
+	case STREAM_TO_CAM:
+		dprintk(MANTIS_DEBUG, 1, "Set stream to CAM");
+		reg |= MANTIS_BYPASS;
+		mmwrite(reg, MANTIS_CONTROL);
+		reg &= 0xff - MANTIS_BYPASS;
+		mmwrite(reg, MANTIS_CONTROL);
+		break;
+	default:
+		dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl);
+		return -1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_stream_control);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ioc.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ioc.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_ioc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_ioc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,51 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_IOC_H
+#define __MANTIS_IOC_H
+
+#define GPIF_A00		0x00
+#define GPIF_A01		0x01
+#define GPIF_A02		0x02
+#define GPIF_A03		0x03
+#define GPIF_A04		0x04
+#define GPIF_A05		0x05
+#define GPIF_A06		0x06
+#define GPIF_A07		0x07
+#define GPIF_A08		0x08
+#define GPIF_A09		0x09
+#define GPIF_A10		0x0a
+#define GPIF_A11		0x0b
+
+#define GPIF_A12		0x0c
+#define GPIF_A13		0x0d
+#define GPIF_A14		0x0e
+
+enum mantis_stream_control {
+	STREAM_TO_HIF = 0,
+	STREAM_TO_CAM
+};
+
+extern int mantis_get_mac(struct mantis_pci *mantis);
+extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
+
+extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
+
+#endif /* __MANTIS_IOC_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_link.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_link.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_link.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_link.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,83 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_LINK_H
+#define __MANTIS_LINK_H
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include "dvb_ca_en50221.h"
+
+enum mantis_sbuf_status {
+	MANTIS_SBUF_DATA_AVAIL		= 1,
+	MANTIS_SBUF_DATA_EMPTY		= 2,
+	MANTIS_SBUF_DATA_OVFLW		= 3
+};
+
+struct mantis_slot {
+	u32				timeout;
+	u32				slave_cfg;
+	u32				bar;
+};
+
+/* Physical layer */
+enum mantis_slot_state {
+	MODULE_INSERTED			= 3,
+	MODULE_XTRACTED			= 4
+};
+
+struct mantis_ca {
+	struct mantis_slot		slot[4];
+
+	struct work_struct		hif_evm_work;
+
+	u32				hif_event;
+	wait_queue_head_t		hif_opdone_wq;
+	wait_queue_head_t		hif_brrdyw_wq;
+	wait_queue_head_t		hif_data_wq;
+	wait_queue_head_t		hif_write_wq; /* HIF Write op */
+
+	enum mantis_sbuf_status		sbuf_status;
+
+	enum mantis_slot_state		slot_state;
+
+	void				*ca_priv;
+
+	struct dvb_ca_en50221		en50221;
+	struct mutex			ca_lock;
+};
+
+/* CA */
+extern void mantis_event_cam_plugin(struct mantis_ca *ca);
+extern void mantis_event_cam_unplug(struct mantis_ca *ca);
+extern int mantis_pcmcia_init(struct mantis_ca *ca);
+extern void mantis_pcmcia_exit(struct mantis_ca *ca);
+extern int mantis_evmgr_init(struct mantis_ca *ca);
+extern void mantis_evmgr_exit(struct mantis_ca *ca);
+
+/* HIF */
+extern int mantis_hif_init(struct mantis_ca *ca);
+extern void mantis_hif_exit(struct mantis_ca *ca);
+extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr);
+extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data);
+extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr);
+extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data);
+
+#endif /* __MANTIS_LINK_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pci.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,177 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+
+#include <asm/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include <asm/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_pci.h"
+
+#define DRIVER_NAME		"Mantis Core"
+
+int __devinit mantis_pci_init(struct mantis_pci *mantis)
+{
+	u8 revision, latency;
+	struct mantis_hwconfig *config	= mantis->hwconfig;
+	struct pci_dev *pdev		= mantis->pdev;
+	int err, ret = 0;
+
+	dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
+		config->model_name,
+		config->dev_type,
+		mantis->pdev->bus->number,
+		PCI_SLOT(mantis->pdev->devfn),
+		PCI_FUNC(mantis->pdev->devfn));
+
+	err = pci_enable_device(pdev);
+	if (err != 0) {
+		ret = -ENODEV;
+		dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err);
+		goto fail0;
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err != 0) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err);
+		ret = -ENOMEM;
+		goto fail1;
+	}
+
+	pci_set_master(pdev);
+
+	if (!request_mem_region(pci_resource_start(pdev, 0),
+				pci_resource_len(pdev, 0),
+				DRIVER_NAME)) {
+
+		dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !");
+		ret = -ENODEV;
+		goto fail1;
+	}
+
+	mantis->mmio = ioremap(pci_resource_start(pdev, 0),
+			       pci_resource_len(pdev, 0));
+
+	if (!mantis->mmio) {
+		dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !");
+		ret = -ENODEV;
+		goto fail2;
+	}
+
+	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
+	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+	mantis->latency = latency;
+	mantis->revision = revision;
+
+	dprintk(MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
+		mantis->revision,
+		mantis->pdev->subsystem_vendor,
+		mantis->pdev->subsystem_device);
+
+	dprintk(MANTIS_ERROR, 0,
+		"irq: %d, latency: %d\n    memory: 0x%lx, mmio: 0x%p\n",
+		mantis->pdev->irq,
+		mantis->latency,
+		mantis->mantis_addr,
+		mantis->mmio);
+
+	err = request_irq(pdev->irq,
+			  config->irq_handler,
+			  IRQF_SHARED,
+			  DRIVER_NAME,
+			  mantis);
+
+	if (err != 0) {
+
+		dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err);
+		ret = -ENODEV;
+		goto fail3;
+	}
+
+	pci_set_drvdata(pdev, mantis);
+	return ret;
+
+	/* Error conditions */
+fail3:
+	dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret);
+	if (mantis->mmio)
+		iounmap(mantis->mmio);
+
+fail2:
+	dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret);
+	release_mem_region(pci_resource_start(pdev, 0),
+			   pci_resource_len(pdev, 0));
+
+fail1:
+	dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret);
+	pci_disable_device(pdev);
+
+fail0:
+	dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
+	pci_set_drvdata(pdev, NULL);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mantis_pci_init);
+
+void mantis_pci_exit(struct mantis_pci *mantis)
+{
+	struct pci_dev *pdev = mantis->pdev;
+
+	dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
+	free_irq(pdev->irq, mantis);
+	if (mantis->mmio) {
+		iounmap(mantis->mmio);
+		release_mem_region(pci_resource_start(pdev, 0),
+				   pci_resource_len(pdev, 0));
+	}
+
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+EXPORT_SYMBOL_GPL(mantis_pci_exit);
+
+MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pci.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,27 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_PCI_H
+#define __MANTIS_PCI_H
+
+extern int mantis_pci_init(struct mantis_pci *mantis);
+extern void mantis_pci_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_PCI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pcmcia.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pcmcia.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_pcmcia.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,120 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_link.h" /* temporary due to physical layer stuff */
+#include "mantis_reg.h"
+
+/*
+ * If Slot state is already PLUG_IN event and we are called
+ * again, definitely it is jitter alone
+ */
+void mantis_event_cam_plugin(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	u32 gpif_irqcfg;
+
+	if (ca->slot_state == MODULE_XTRACTED) {
+		dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num);
+		udelay(50);
+		mmwrite(0xda000000, MANTIS_CARD_RESET);
+		gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
+		gpif_irqcfg |= MANTIS_MASK_PLUGOUT;
+		gpif_irqcfg &= ~MANTIS_MASK_PLUGIN;
+		mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
+		udelay(500);
+		ca->slot_state = MODULE_INSERTED;
+	}
+	udelay(100);
+}
+
+/*
+ * If Slot state is already UN_PLUG event and we are called
+ * again, definitely it is jitter alone
+ */
+void mantis_event_cam_unplug(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	u32 gpif_irqcfg;
+
+	if (ca->slot_state == MODULE_INSERTED) {
+		dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num);
+		udelay(50);
+		mmwrite(0x00da0000, MANTIS_CARD_RESET);
+		gpif_irqcfg  = mmread(MANTIS_GPIF_IRQCFG);
+		gpif_irqcfg |= MANTIS_MASK_PLUGIN;
+		gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT;
+		mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
+		udelay(500);
+		ca->slot_state = MODULE_XTRACTED;
+	}
+	udelay(100);
+}
+
+int mantis_pcmcia_init(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	u32 gpif_stat, card_stat;
+
+	mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK);
+	gpif_stat = mmread(MANTIS_GPIF_STATUS);
+	card_stat = mmread(MANTIS_GPIF_IRQCFG);
+
+	if (gpif_stat & MANTIS_GPIF_DETSTAT) {
+		dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num);
+		mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG);
+		ca->slot_state = MODULE_INSERTED;
+		dvb_ca_en50221_camchange_irq(&ca->en50221,
+					     0,
+					     DVB_CA_EN50221_CAMCHANGE_INSERTED);
+	} else {
+		dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num);
+		mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG);
+		ca->slot_state = MODULE_XTRACTED;
+		dvb_ca_en50221_camchange_irq(&ca->en50221,
+					     0,
+					     DVB_CA_EN50221_CAMCHANGE_REMOVED);
+	}
+
+	return 0;
+}
+
+void mantis_pcmcia_exit(struct mantis_ca *ca)
+{
+	struct mantis_pci *mantis = ca->ca_priv;
+
+	mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS);
+	mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_reg.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_reg.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,197 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_REG_H
+#define __MANTIS_REG_H
+
+/* Interrupts */
+#define MANTIS_INT_STAT			0x00
+#define MANTIS_INT_MASK			0x04
+
+#define MANTIS_INT_RISCSTAT		(0x0f << 28)
+#define MANTIS_INT_RISCEN		(0x01 << 27)
+#define MANTIS_INT_I2CRACK		(0x01 << 26)
+
+/* #define MANTIS_INT_GPIF			(0xff << 12) */
+
+#define MANTIS_INT_PCMCIA7		(0x01 << 19)
+#define MANTIS_INT_PCMCIA6		(0x01 << 18)
+#define MANTIS_INT_PCMCIA5		(0x01 << 17)
+#define MANTIS_INT_PCMCIA4		(0x01 << 16)
+#define MANTIS_INT_PCMCIA3		(0x01 << 15)
+#define MANTIS_INT_PCMCIA2		(0x01 << 14)
+#define MANTIS_INT_PCMCIA1		(0x01 << 13)
+#define MANTIS_INT_PCMCIA0		(0x01 << 12)
+#define MANTIS_INT_IRQ1			(0x01 << 11)
+#define MANTIS_INT_IRQ0			(0x01 << 10)
+#define MANTIS_INT_OCERR		(0x01 <<  8)
+#define MANTIS_INT_PABORT		(0x01 <<  7)
+#define MANTIS_INT_RIPERR		(0x01 <<  6)
+#define MANTIS_INT_PPERR		(0x01 <<  5)
+#define MANTIS_INT_FTRGT		(0x01 <<  3)
+#define MANTIS_INT_RISCI		(0x01 <<  1)
+#define MANTIS_INT_I2CDONE		(0x01 <<  0)
+
+/* DMA */
+#define MANTIS_DMA_CTL			0x08
+#define MANTIS_GPIF_RD			(0xff << 24)
+#define MANTIS_GPIF_WR			(0xff << 16)
+#define MANTIS_CPU_DO			(0x01 << 10)
+#define MANTIS_DRV_DO			(0x01 <<  9)
+#define	MANTIS_I2C_RD			(0x01 <<  7)
+#define MANTIS_I2C_WR			(0x01 <<  6)
+#define MANTIS_DCAP_MODE		(0x01 <<  5)
+#define MANTIS_FIFO_TP_4		(0x00 <<  3)
+#define MANTIS_FIFO_TP_8		(0x01 <<  3)
+#define MANTIS_FIFO_TP_16		(0x02 <<  3)
+#define MANTIS_FIFO_EN			(0x01 <<  2)
+#define MANTIS_DCAP_EN			(0x01 <<  1)
+#define MANTIS_RISC_EN			(0x01 <<  0)
+
+/* DEBUG */
+#define MANTIS_DEBUGREG			0x0c
+#define MANTIS_DATINV			(0x0e <<  7)
+#define MANTIS_TOP_DEBUGSEL		(0x07 <<  4)
+#define MANTIS_PCMCIA_DEBUGSEL		(0x0f <<  0)
+
+#define MANTIS_RISC_START		0x10
+#define MANTIS_RISC_PC			0x14
+
+/* I2C */
+#define MANTIS_I2CDATA_CTL		0x18
+#define MANTIS_I2C_RATE_1		(0x00 <<  6)
+#define MANTIS_I2C_RATE_2		(0x01 <<  6)
+#define MANTIS_I2C_RATE_3		(0x02 <<  6)
+#define MANTIS_I2C_RATE_4		(0x03 <<  6)
+#define MANTIS_I2C_STOP			(0x01 <<  5)
+#define MANTIS_I2C_PGMODE		(0x01 <<  3)
+
+/* DATA */
+#define MANTIS_CMD_DATA_R1		0x20
+#define MANTIS_CMD_DATA_3		(0xff << 24)
+#define MANTIS_CMD_DATA_2		(0xff << 16)
+#define MANTIS_CMD_DATA_1		(0xff <<  8)
+#define MANTIS_CMD_DATA_0		(0xff <<  0)
+
+#define MANTIS_CMD_DATA_R2		0x24
+#define MANTIS_CMD_DATA_7		(0xff << 24)
+#define MANTIS_CMD_DATA_6		(0xff << 16)
+#define MANTIS_CMD_DATA_5		(0xff <<  8)
+#define MANTIS_CMD_DATA_4		(0xff <<  0)
+
+#define MANTIS_CONTROL			0x28
+#define MANTIS_DET			(0x01 <<  7)
+#define MANTIS_DAT_CF_EN		(0x01 <<  6)
+#define MANTIS_ACS			(0x03 <<  4)
+#define MANTIS_VCCEN			(0x01 <<  3)
+#define MANTIS_BYPASS			(0x01 <<  2)
+#define MANTIS_MRST			(0x01 <<  1)
+#define MANTIS_CRST_INT			(0x01 <<  0)
+
+#define MANTIS_GPIF_CFGSLA		0x84
+#define MANTIS_GPIF_WAITSMPL		(0x07 << 28)
+#define MANTIS_GPIF_BYTEADDRSUB		(0x01 << 25)
+#define MANTIS_GPIF_WAITPOL		(0x01 << 24)
+#define MANTIS_GPIF_NCDELAY		(0x07 << 20)
+#define MANTIS_GPIF_RW2CSDELAY		(0x07 << 16)
+#define MANTIS_GPIF_SLFTIMEDMODE	(0x01 << 15)
+#define MANTIS_GPIF_SLFTIMEDDELY	(0x7f <<  8)
+#define MANTIS_GPIF_DEVTYPE		(0x07 <<  4)
+#define MANTIS_GPIF_BIGENDIAN		(0x01 <<  3)
+#define MANTIS_GPIF_FETCHCMD		(0x03 <<  1)
+#define MANTIS_GPIF_HWORDDEV		(0x01 <<  0)
+
+#define MANTIS_GPIF_WSTOPER		0x90
+#define MANTIS_GPIF_WSTOPERWREN3	(0x01 << 31)
+#define MANTIS_GPIF_PARBOOTN		(0x01 << 29)
+#define MANTIS_GPIF_WSTOPERSLID3	(0x1f << 24)
+#define MANTIS_GPIF_WSTOPERWREN2	(0x01 << 23)
+#define MANTIS_GPIF_WSTOPERSLID2	(0x1f << 16)
+#define MANTIS_GPIF_WSTOPERWREN1	(0x01 << 15)
+#define MANTIS_GPIF_WSTOPERSLID1	(0x1f <<  8)
+#define MANTIS_GPIF_WSTOPERWREN0	(0x01 <<  7)
+#define MANTIS_GPIF_WSTOPERSLID0	(0x1f <<  0)
+
+#define MANTIS_GPIF_CS2RW		0x94
+#define MANTIS_GPIF_CS2RWWREN3		(0x01 << 31)
+#define MANTIS_GPIF_CS2RWDELY3		(0x3f << 24)
+#define MANTIS_GPIF_CS2RWWREN2		(0x01 << 23)
+#define MANTIS_GPIF_CS2RWDELY2		(0x3f << 16)
+#define MANTIS_GPIF_CS2RWWREN1		(0x01 << 15)
+#define MANTIS_GPIF_CS2RWDELY1		(0x3f <<  8)
+#define MANTIS_GPIF_CS2RWWREN0		(0x01 <<  7)
+#define MANTIS_GPIF_CS2RWDELY0		(0x3f <<  0)
+
+#define MANTIS_GPIF_IRQCFG		0x98
+#define MANTIS_GPIF_IRQPOL		(0x01 <<  8)
+#define MANTIS_MASK_WRACK		(0x01 <<  7)
+#define MANTIS_MASK_BRRDY		(0x01 <<  6)
+#define MANTIS_MASK_OVFLW		(0x01 <<  5)
+#define MANTIS_MASK_OTHERR		(0x01 <<  4)
+#define MANTIS_MASK_WSTO		(0x01 <<  3)
+#define MANTIS_MASK_EXTIRQ		(0x01 <<  2)
+#define MANTIS_MASK_PLUGIN		(0x01 <<  1)
+#define MANTIS_MASK_PLUGOUT		(0x01 <<  0)
+
+#define MANTIS_GPIF_STATUS		0x9c
+#define MANTIS_SBUF_KILLOP		(0x01 << 15)
+#define MANTIS_SBUF_OPDONE		(0x01 << 14)
+#define MANTIS_SBUF_EMPTY		(0x01 << 13)
+#define MANTIS_GPIF_DETSTAT		(0x01 <<  9)
+#define MANTIS_GPIF_INTSTAT		(0x01 <<  8)
+#define MANTIS_GPIF_WRACK		(0x01 <<  7)
+#define MANTIS_GPIF_BRRDY		(0x01 <<  6)
+#define MANTIS_SBUF_OVFLW		(0x01 <<  5)
+#define MANTIS_GPIF_OTHERR		(0x01 <<  4)
+#define MANTIS_SBUF_WSTO		(0x01 <<  3)
+#define MANTIS_GPIF_EXTIRQ		(0x01 <<  2)
+#define MANTIS_CARD_PLUGIN		(0x01 <<  1)
+#define MANTIS_CARD_PLUGOUT		(0x01 <<  0)
+
+#define MANTIS_GPIF_BRADDR		0xa0
+#define MANTIS_GPIF_PCMCIAREG		(0x01 		<< 27)
+#define MANTIS_GPIF_PCMCIAIOM		(0x01 		<< 26)
+#define MANTIS_GPIF_BR_ADDR		(0xfffffff	<<  0)
+
+#define MANTIS_GPIF_BRBYTES		0xa4
+#define MANTIS_GPIF_BRCNT		(0xfff 		<<  0)
+
+#define MANTIS_PCMCIA_RESET		0xa8
+#define MANTIS_PCMCIA_RSTVAL		(0xff << 0)
+
+#define MANTIS_CARD_RESET		0xac
+
+#define MANTIS_GPIF_ADDR		0xb0
+#define MANTIS_GPIF_HIFRDWRN		(0x01		<< 31)
+#define MANTIS_GPIF_PCMCIAREG		(0x01		<< 27)
+#define MANTIS_GPIF_PCMCIAIOM		(0x01		<< 26)
+#define MANTIS_GPIF_HIFADDR		(0xfffffff	<<  0)
+
+#define MANTIS_GPIF_DOUT		0xb4
+#define MANTIS_GPIF_HIFDOUT		(0xfffffff	<<  0)
+
+#define MANTIS_GPIF_DIN			0xb8
+#define MANTIS_GPIF_HIFDIN		(0xfffffff	<<  0)
+
+#define MANTIS_GPIF_SPARE		0xbc
+#define MANTIS_GPIF_LOGICRD		(0xffff		<< 16)
+#define MANTIS_GPIF_LOGICRW		(0xffff		<<  0)
+
+#endif /* __MANTIS_REG_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_uart.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_uart.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_uart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_uart.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,186 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/spinlock.h>
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_reg.h"
+#include "mantis_uart.h"
+
+struct mantis_uart_params {
+	enum mantis_baud	baud_rate;
+	enum mantis_parity	parity;
+};
+
+static struct {
+	char string[7];
+} rates[5] = {
+	{ "9600" },
+	{ "19200" },
+	{ "38400" },
+	{ "57600" },
+	{ "115200" }
+};
+
+static struct {
+	char string[5];
+} parity[3] = {
+	{ "NONE" },
+	{ "ODD" },
+	{ "EVEN" }
+};
+
+#define UART_MAX_BUF			16
+
+int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
+{
+	struct mantis_hwconfig *config = mantis->hwconfig;
+	u32 stat = 0, i;
+
+	/* get data */
+	for (i = 0; i < (config->bytes + 1); i++) {
+
+		stat = mmread(MANTIS_UART_STAT);
+
+		if (stat & MANTIS_UART_RXFIFO_FULL) {
+			dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
+		}
+		data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
+
+		dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
+
+		if (data[i] & (1 << 7)) {
+			dprintk(MANTIS_ERROR, 1, "UART framing error");
+			return -EINVAL;
+		}
+		if (data[i] & (1 << 6)) {
+			dprintk(MANTIS_ERROR, 1, "UART parity error");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void mantis_uart_work(struct work_struct *work)
+{
+	struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
+	struct mantis_hwconfig *config = mantis->hwconfig;
+	u8 buf[16];
+	int i;
+
+	mantis_uart_read(mantis, buf);
+
+	for (i = 0; i < (config->bytes + 1); i++)
+		dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
+
+	dprintk(MANTIS_DEBUG, 0, "\n");
+}
+
+static int mantis_uart_setup(struct mantis_pci *mantis,
+			     struct mantis_uart_params *params)
+{
+	u32 reg;
+
+	mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
+
+	reg = mmread(MANTIS_UART_BAUD);
+
+	switch (params->baud_rate) {
+	case MANTIS_BAUD_9600:
+		reg |= 0xd8;
+		break;
+	case MANTIS_BAUD_19200:
+		reg |= 0x6c;
+		break;
+	case MANTIS_BAUD_38400:
+		reg |= 0x36;
+		break;
+	case MANTIS_BAUD_57600:
+		reg |= 0x23;
+		break;
+	case MANTIS_BAUD_115200:
+		reg |= 0x11;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mmwrite(reg, MANTIS_UART_BAUD);
+
+	return 0;
+}
+
+int mantis_uart_init(struct mantis_pci *mantis)
+{
+	struct mantis_hwconfig *config = mantis->hwconfig;
+	struct mantis_uart_params params;
+
+	/* default parity: */
+	params.baud_rate = config->baud_rate;
+	params.parity = config->parity;
+	dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
+		rates[params.baud_rate].string,
+		parity[params.parity].string);
+
+	init_waitqueue_head(&mantis->uart_wq);
+	spin_lock_init(&mantis->uart_lock);
+
+	INIT_WORK(&mantis->uart_work, mantis_uart_work);
+
+	/* disable interrupt */
+	mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
+
+	mantis_uart_setup(mantis, &params);
+
+	/* default 1 byte */
+	mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
+
+	/* flush buffer */
+	mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
+
+	/* enable interrupt */
+	mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
+	mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
+
+	schedule_work(&mantis->uart_work);
+	dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized");
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mantis_uart_init);
+
+void mantis_uart_exit(struct mantis_pci *mantis)
+{
+	/* disable interrupt */
+	mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
+}
+EXPORT_SYMBOL_GPL(mantis_uart_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_uart.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_uart.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_uart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_uart.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_UART_H
+#define __MANTIS_UART_H
+
+#define MANTIS_UART_CTL			0xe0
+#define MANTIS_UART_RXINT		(1 << 4)
+#define MANTIS_UART_RXFLUSH		(1 << 2)
+
+#define MANTIS_UART_RXD			0xe8
+#define MANTIS_UART_BAUD		0xec
+
+#define MANTIS_UART_STAT		0xf0
+#define MANTIS_UART_RXFIFO_DATA		(1 << 7)
+#define MANTIS_UART_RXFIFO_EMPTY	(1 << 6)
+#define MANTIS_UART_RXFIFO_FULL		(1 << 3)
+#define MANTIS_UART_FRAME_ERR		(1 << 2)
+#define MANTIS_UART_PARITY_ERR		(1 << 1)
+#define MANTIS_UART_RXTHRESH_INT	(1 << 0)
+
+enum mantis_baud {
+	MANTIS_BAUD_9600	= 0,
+	MANTIS_BAUD_19200,
+	MANTIS_BAUD_38400,
+	MANTIS_BAUD_57600,
+	MANTIS_BAUD_115200
+};
+
+enum mantis_parity {
+	MANTIS_PARITY_NONE	= 0,
+	MANTIS_PARITY_EVEN,
+	MANTIS_PARITY_ODD,
+};
+
+struct mantis_pci;
+
+extern int mantis_uart_init(struct mantis_pci *mantis);
+extern void mantis_uart_exit(struct mantis_pci *mantis);
+
+#endif /* __MANTIS_UART_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1033.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1033.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1033.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1033.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,212 @@
+/*
+	Mantis VP-1033 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "stv0299.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1033.h"
+#include "mantis_reg.h"
+
+u8 lgtdqcs001f_inittab[] = {
+	0x01, 0x15,
+	0x02, 0x00,
+	0x03, 0x00,
+	0x04, 0x2a,
+	0x05, 0x85,
+	0x06, 0x02,
+	0x07, 0x00,
+	0x08, 0x00,
+	0x0c, 0x01,
+	0x0d, 0x81,
+	0x0e, 0x44,
+	0x0f, 0x94,
+	0x10, 0x3c,
+	0x11, 0x84,
+	0x12, 0xb9,
+	0x13, 0xb5,
+	0x14, 0x4f,
+	0x15, 0xc9,
+	0x16, 0x80,
+	0x17, 0x36,
+	0x18, 0xfb,
+	0x19, 0xcf,
+	0x1a, 0xbc,
+	0x1c, 0x2b,
+	0x1d, 0x27,
+	0x1e, 0x00,
+	0x1f, 0x0b,
+	0x20, 0xa1,
+	0x21, 0x60,
+	0x22, 0x00,
+	0x23, 0x00,
+	0x28, 0x00,
+	0x29, 0x28,
+	0x2a, 0x14,
+	0x2b, 0x0f,
+	0x2c, 0x09,
+	0x2d, 0x05,
+	0x31, 0x1f,
+	0x32, 0x19,
+	0x33, 0xfc,
+	0x34, 0x13,
+	0xff, 0xff,
+};
+
+#define MANTIS_MODEL_NAME	"VP-1033"
+#define MANTIS_DEV_TYPE		"DVB-S/DSS"
+
+int lgtdqcs001f_tuner_set(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *params)
+{
+	struct mantis_pci *mantis	= fe->dvb->priv;
+	struct i2c_adapter *adapter	= &mantis->adapter;
+
+	u8 buf[4];
+	u32 div;
+
+
+	struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
+
+	div = params->frequency / 250;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] =  div & 0xff;
+	buf[2] =  0x83;
+	buf[3] =  0xc0;
+
+	if (params->frequency < 1531000)
+		buf[3] |= 0x04;
+	else
+		buf[3] &= ~0x04;
+	if (i2c_transfer(adapter, &msg, 1) < 0) {
+		dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed");
+		return -EIO;
+	}
+	msleep_interruptible(100);
+
+	return 0;
+}
+
+int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
+				u32 srate, u32 ratio)
+{
+	u8 aclk = 0;
+	u8 bclk = 0;
+
+	if (srate < 1500000) {
+		aclk = 0xb7;
+		bclk = 0x47;
+	} else if (srate < 3000000) {
+		aclk = 0xb7;
+		bclk = 0x4b;
+	} else if (srate < 7000000) {
+		aclk = 0xb7;
+		bclk = 0x4f;
+	} else if (srate < 14000000) {
+		aclk = 0xb7;
+		bclk = 0x53;
+	} else if (srate < 30000000) {
+		aclk = 0xb6;
+		bclk = 0x53;
+	} else if (srate < 45000000) {
+		aclk = 0xb4;
+		bclk = 0x51;
+	}
+	stv0299_writereg(fe, 0x13, aclk);
+	stv0299_writereg(fe, 0x14, bclk);
+
+	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+	stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
+	stv0299_writereg(fe, 0x21,  ratio & 0xf0);
+
+	return 0;
+}
+
+struct stv0299_config lgtdqcs001f_config = {
+	.demod_address		= 0x68,
+	.inittab		= lgtdqcs001f_inittab,
+	.mclk			= 88000000UL,
+	.invert			= 0,
+	.skip_reinit		= 0,
+	.volt13_op0_op1		= STV0299_VOLT13_OP0,
+	.min_delay_ms		= 100,
+	.set_symbol_rate	= lgtdqcs001f_set_symbol_rate,
+};
+
+static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter	= &mantis->adapter;
+
+	int err = 0;
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		mantis_frontend_soft_reset(mantis);
+		msleep(250);
+
+		dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
+		fe = stv0299_attach(&lgtdqcs001f_config, adapter);
+
+		if (fe) {
+			fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
+			dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
+				lgtdqcs001f_config.demod_address);
+
+			dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
+		} else {
+			return -1;
+		}
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+	mantis->fe = fe;
+	dprintk(MANTIS_ERROR, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp1033_config = {
+	.model_name		= MANTIS_MODEL_NAME,
+	.dev_type		= MANTIS_DEV_TYPE,
+	.ts_size		= MANTIS_TS_204,
+
+	.baud_rate		= MANTIS_BAUD_9600,
+	.parity			= MANTIS_PARITY_NONE,
+	.bytes			= 0,
+
+	.frontend_init		= vp1033_frontend_init,
+	.power			= GPIF_A12,
+	.reset			= GPIF_A13,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1033.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1033.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1033.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1033.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Mantis VP-1033 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP1033_H
+#define __MANTIS_VP1033_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_1033_DVB_S	0x0016
+
+extern struct mantis_hwconfig vp1033_config;
+
+#endif /* __MANTIS_VP1033_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1034.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1034.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1034.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1034.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,119 @@
+/*
+	Mantis VP-1034 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mb86a16.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1034.h"
+#include "mantis_reg.h"
+
+struct mb86a16_config vp1034_mb86a16_config = {
+	.demod_address	= 0x08,
+	.set_voltage	= vp1034_set_voltage,
+};
+
+#define MANTIS_MODEL_NAME	"VP-1034"
+#define MANTIS_DEV_TYPE		"DVB-S/DSS"
+
+int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
+		gpio_set_bits(mantis, 13, 1);
+		gpio_set_bits(mantis, 14, 0);
+		break;
+	case SEC_VOLTAGE_18:
+		dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
+		gpio_set_bits(mantis, 13, 1);
+		gpio_set_bits(mantis, 14, 1);
+		break;
+	case SEC_VOLTAGE_OFF:
+		dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
+		break;
+	default:
+		dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage);
+		return -EINVAL;
+	}
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+
+	return 0;
+}
+
+static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter	= &mantis->adapter;
+
+	int err = 0;
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		mantis_frontend_soft_reset(mantis);
+		msleep(250);
+
+		dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
+		fe = mb86a16_attach(&vp1034_mb86a16_config, adapter);
+		if (fe) {
+			dprintk(MANTIS_ERROR, 1,
+			"found MB86A16 DVB-S/DSS frontend @0x%02x",
+			vp1034_mb86a16_config.demod_address);
+
+		} else {
+			return -1;
+		}
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+	mantis->fe = fe;
+	dprintk(MANTIS_ERROR, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp1034_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_204,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp1034_frontend_init,
+	.power		= GPIF_A12,
+	.reset		= GPIF_A13,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1034.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1034.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1034.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1034.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+/*
+	Mantis VP-1034 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP1034_H
+#define __MANTIS_VP1034_H
+
+#include "dvb_frontend.h"
+#include "mantis_common.h"
+
+
+#define MANTIS_VP_1034_DVB_S	0x0014
+
+extern struct mantis_hwconfig vp1034_config;
+extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
+
+#endif /* __MANTIS_VP1034_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1041.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1041.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1041.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1041.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,358 @@
+/*
+	Mantis VP-1041 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp1041.h"
+#include "stb0899_reg.h"
+#include "stb0899_drv.h"
+#include "stb0899_cfg.h"
+#include "stb6100_cfg.h"
+#include "stb6100.h"
+#include "lnbp21.h"
+
+#define MANTIS_MODEL_NAME	"VP-1041"
+#define MANTIS_DEV_TYPE		"DSS/DVB-S/DVB-S2"
+
+static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
+
+	/* 0x0000000b, *//* SYSREG */
+	{ STB0899_DEV_ID		, 0x30 },
+	{ STB0899_DISCNTRL1		, 0x32 },
+	{ STB0899_DISCNTRL2     	, 0x80 },
+	{ STB0899_DISRX_ST0     	, 0x04 },
+	{ STB0899_DISRX_ST1     	, 0x00 },
+	{ STB0899_DISPARITY     	, 0x00 },
+	{ STB0899_DISFIFO       	, 0x00 },
+	{ STB0899_DISSTATUS		, 0x20 },
+	{ STB0899_DISF22        	, 0x99 },
+	{ STB0899_DISF22RX      	, 0xa8 },
+	/* SYSREG ? */
+	{ STB0899_ACRPRESC      	, 0x11 },
+	{ STB0899_ACRDIV1       	, 0x0a },
+	{ STB0899_ACRDIV2       	, 0x05 },
+	{ STB0899_DACR1         	, 0x00 },
+	{ STB0899_DACR2         	, 0x00 },
+	{ STB0899_OUTCFG        	, 0x00 },
+	{ STB0899_MODECFG       	, 0x00 },
+	{ STB0899_IRQSTATUS_3		, 0xfe },
+	{ STB0899_IRQSTATUS_2		, 0x03 },
+	{ STB0899_IRQSTATUS_1		, 0x7c },
+	{ STB0899_IRQSTATUS_0		, 0xf4 },
+	{ STB0899_IRQMSK_3      	, 0xf3 },
+	{ STB0899_IRQMSK_2      	, 0xfc },
+	{ STB0899_IRQMSK_1      	, 0xff },
+	{ STB0899_IRQMSK_0		, 0xff },
+	{ STB0899_IRQCFG		, 0x00 },
+	{ STB0899_I2CCFG        	, 0x88 },
+	{ STB0899_I2CRPT        	, 0x58 },
+	{ STB0899_IOPVALUE5		, 0x00 },
+	{ STB0899_IOPVALUE4		, 0x33 },
+	{ STB0899_IOPVALUE3		, 0x6d },
+	{ STB0899_IOPVALUE2		, 0x90 },
+	{ STB0899_IOPVALUE1		, 0x60 },
+	{ STB0899_IOPVALUE0		, 0x00 },
+	{ STB0899_GPIO00CFG     	, 0x82 },
+	{ STB0899_GPIO01CFG     	, 0x82 },
+	{ STB0899_GPIO02CFG     	, 0x82 },
+	{ STB0899_GPIO03CFG     	, 0x82 },
+	{ STB0899_GPIO04CFG     	, 0x82 },
+	{ STB0899_GPIO05CFG     	, 0x82 },
+	{ STB0899_GPIO06CFG     	, 0x82 },
+	{ STB0899_GPIO07CFG     	, 0x82 },
+	{ STB0899_GPIO08CFG     	, 0x82 },
+	{ STB0899_GPIO09CFG     	, 0x82 },
+	{ STB0899_GPIO10CFG     	, 0x82 },
+	{ STB0899_GPIO11CFG     	, 0x82 },
+	{ STB0899_GPIO12CFG     	, 0x82 },
+	{ STB0899_GPIO13CFG     	, 0x82 },
+	{ STB0899_GPIO14CFG     	, 0x82 },
+	{ STB0899_GPIO15CFG     	, 0x82 },
+	{ STB0899_GPIO16CFG     	, 0x82 },
+	{ STB0899_GPIO17CFG     	, 0x82 },
+	{ STB0899_GPIO18CFG     	, 0x82 },
+	{ STB0899_GPIO19CFG     	, 0x82 },
+	{ STB0899_GPIO20CFG     	, 0x82 },
+	{ STB0899_SDATCFG       	, 0xb8 },
+	{ STB0899_SCLTCFG       	, 0xba },
+	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
+	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
+	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
+	{ STB0899_DIRCLKCFG     	, 0x82 },
+	{ STB0899_CLKOUT27CFG   	, 0x7e },
+	{ STB0899_STDBYCFG      	, 0x82 },
+	{ STB0899_CS0CFG        	, 0x82 },
+	{ STB0899_CS1CFG        	, 0x82 },
+	{ STB0899_DISEQCOCFG    	, 0x20 },
+	{ STB0899_GPIO32CFG		, 0x82 },
+	{ STB0899_GPIO33CFG		, 0x82 },
+	{ STB0899_GPIO34CFG		, 0x82 },
+	{ STB0899_GPIO35CFG		, 0x82 },
+	{ STB0899_GPIO36CFG		, 0x82 },
+	{ STB0899_GPIO37CFG		, 0x82 },
+	{ STB0899_GPIO38CFG		, 0x82 },
+	{ STB0899_GPIO39CFG		, 0x82 },
+	{ STB0899_NCOARSE       	, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+	{ STB0899_FILTCTRL      	, 0x00 },
+	{ STB0899_SYSCTRL       	, 0x01 },
+	{ STB0899_STOPCLK1      	, 0x20 },
+	{ STB0899_STOPCLK2      	, 0x00 },
+	{ STB0899_INTBUFSTATUS		, 0x00 },
+	{ STB0899_INTBUFCTRL    	, 0x0a },
+	{ 0xffff			, 0xff },
+};
+
+static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
+	{ STB0899_DEMOD         	, 0x00 },
+	{ STB0899_RCOMPC        	, 0xc9 },
+	{ STB0899_AGC1CN        	, 0x01 },
+	{ STB0899_AGC1REF       	, 0x10 },
+	{ STB0899_RTC	        	, 0x23 },
+	{ STB0899_TMGCFG        	, 0x4e },
+	{ STB0899_AGC2REF       	, 0x34 },
+	{ STB0899_TLSR          	, 0x84 },
+	{ STB0899_CFD           	, 0xf7 },
+	{ STB0899_ACLC	        	, 0x87 },
+	{ STB0899_BCLC          	, 0x94 },
+	{ STB0899_EQON          	, 0x41 },
+	{ STB0899_LDT           	, 0xf1 },
+	{ STB0899_LDT2          	, 0xe3 },
+	{ STB0899_EQUALREF      	, 0xb4 },
+	{ STB0899_TMGRAMP       	, 0x10 },
+	{ STB0899_TMGTHD        	, 0x30 },
+	{ STB0899_IDCCOMP		, 0xfd },
+	{ STB0899_QDCCOMP		, 0xff },
+	{ STB0899_POWERI		, 0x0c },
+	{ STB0899_POWERQ		, 0x0f },
+	{ STB0899_RCOMP			, 0x6c },
+	{ STB0899_AGCIQIN		, 0x80 },
+	{ STB0899_AGC2I1		, 0x06 },
+	{ STB0899_AGC2I2		, 0x00 },
+	{ STB0899_TLIR			, 0x30 },
+	{ STB0899_RTF			, 0x7f },
+	{ STB0899_DSTATUS		, 0x00 },
+	{ STB0899_LDI			, 0xbc },
+	{ STB0899_CFRM			, 0xea },
+	{ STB0899_CFRL			, 0x31 },
+	{ STB0899_NIRM			, 0x2b },
+	{ STB0899_NIRL			, 0x80 },
+	{ STB0899_ISYMB			, 0x1d },
+	{ STB0899_QSYMB			, 0xa6 },
+	{ STB0899_SFRH          	, 0x2f },
+	{ STB0899_SFRM          	, 0x68 },
+	{ STB0899_SFRL          	, 0x40 },
+	{ STB0899_SFRUPH        	, 0x2f },
+	{ STB0899_SFRUPM        	, 0x68 },
+	{ STB0899_SFRUPL        	, 0x40 },
+	{ STB0899_EQUAI1		, 0x02 },
+	{ STB0899_EQUAQ1		, 0xff },
+	{ STB0899_EQUAI2		, 0x04 },
+	{ STB0899_EQUAQ2		, 0x05 },
+	{ STB0899_EQUAI3		, 0x02 },
+	{ STB0899_EQUAQ3		, 0xfd },
+	{ STB0899_EQUAI4		, 0x03 },
+	{ STB0899_EQUAQ4		, 0x07 },
+	{ STB0899_EQUAI5		, 0x08 },
+	{ STB0899_EQUAQ5		, 0xf5 },
+	{ STB0899_DSTATUS2		, 0x00 },
+	{ STB0899_VSTATUS       	, 0x00 },
+	{ STB0899_VERROR		, 0x86 },
+	{ STB0899_IQSWAP		, 0x2a },
+	{ STB0899_ECNT1M		, 0x00 },
+	{ STB0899_ECNT1L		, 0x00 },
+	{ STB0899_ECNT2M		, 0x00 },
+	{ STB0899_ECNT2L		, 0x00 },
+	{ STB0899_ECNT3M		, 0x0a },
+	{ STB0899_ECNT3L		, 0xad },
+	{ STB0899_FECAUTO1      	, 0x06 },
+	{ STB0899_FECM	        	, 0x01 },
+	{ STB0899_VTH12         	, 0xb0 },
+	{ STB0899_VTH23         	, 0x7a },
+	{ STB0899_VTH34	        	, 0x58 },
+	{ STB0899_VTH56         	, 0x38 },
+	{ STB0899_VTH67         	, 0x34 },
+	{ STB0899_VTH78         	, 0x24 },
+	{ STB0899_PRVIT         	, 0xff },
+	{ STB0899_VITSYNC       	, 0x19 },
+	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+	{ STB0899_TSULC         	, 0x42 },
+	{ STB0899_RSLLC         	, 0x41 },
+	{ STB0899_TSLPL	        	, 0x12 },
+	{ STB0899_TSCFGH        	, 0x0c },
+	{ STB0899_TSCFGM        	, 0x00 },
+	{ STB0899_TSCFGL        	, 0x00 },
+	{ STB0899_TSOUT			, 0x69 }, /* 0x0d for CAM */
+	{ STB0899_RSSYNCDEL     	, 0x00 },
+	{ STB0899_TSINHDELH     	, 0x02 },
+	{ STB0899_TSINHDELM		, 0x00 },
+	{ STB0899_TSINHDELL		, 0x00 },
+	{ STB0899_TSLLSTKM		, 0x1b },
+	{ STB0899_TSLLSTKL		, 0xb3 },
+	{ STB0899_TSULSTKM		, 0x00 },
+	{ STB0899_TSULSTKL		, 0x00 },
+	{ STB0899_PCKLENUL		, 0xbc },
+	{ STB0899_PCKLENLL		, 0xcc },
+	{ STB0899_RSPCKLEN		, 0xbd },
+	{ STB0899_TSSTATUS		, 0x90 },
+	{ STB0899_ERRCTRL1      	, 0xb6 },
+	{ STB0899_ERRCTRL2      	, 0x95 },
+	{ STB0899_ERRCTRL3      	, 0x8d },
+	{ STB0899_DMONMSK1		, 0x27 },
+	{ STB0899_DMONMSK0		, 0x03 },
+	{ STB0899_DEMAPVIT      	, 0x5c },
+	{ STB0899_PLPARM		, 0x19 },
+	{ STB0899_PDELCTRL      	, 0x48 },
+	{ STB0899_PDELCTRL2     	, 0x00 },
+	{ STB0899_BBHCTRL1      	, 0x00 },
+	{ STB0899_BBHCTRL2      	, 0x00 },
+	{ STB0899_HYSTTHRESH    	, 0x77 },
+	{ STB0899_MATCSTM		, 0x00 },
+	{ STB0899_MATCSTL		, 0x00 },
+	{ STB0899_UPLCSTM		, 0x00 },
+	{ STB0899_UPLCSTL		, 0x00 },
+	{ STB0899_DFLCSTM		, 0x00 },
+	{ STB0899_DFLCSTL		, 0x00 },
+	{ STB0899_SYNCCST		, 0x00 },
+	{ STB0899_SYNCDCSTM		, 0x00 },
+	{ STB0899_SYNCDCSTL		, 0x00 },
+	{ STB0899_ISI_ENTRY		, 0x00 },
+	{ STB0899_ISI_BIT_EN		, 0x00 },
+	{ STB0899_MATSTRM		, 0xf0 },
+	{ STB0899_MATSTRL		, 0x02 },
+	{ STB0899_UPLSTRM		, 0x45 },
+	{ STB0899_UPLSTRL		, 0x60 },
+	{ STB0899_DFLSTRM		, 0xe3 },
+	{ STB0899_DFLSTRL		, 0x00 },
+	{ STB0899_SYNCSTR		, 0x47 },
+	{ STB0899_SYNCDSTRM		, 0x05 },
+	{ STB0899_SYNCDSTRL		, 0x18 },
+	{ STB0899_CFGPDELSTATUS1	, 0x19 },
+	{ STB0899_CFGPDELSTATUS2	, 0x2b },
+	{ STB0899_BBFERRORM		, 0x00 },
+	{ STB0899_BBFERRORL		, 0x01 },
+	{ STB0899_UPKTERRORM		, 0x00 },
+	{ STB0899_UPKTERRORL		, 0x00 },
+	{ 0xffff			, 0xff },
+};
+
+struct stb0899_config vp1041_stb0899_config = {
+	.init_dev		= vp1041_stb0899_s1_init_1,
+	.init_s2_demod		= stb0899_s2_init_2,
+	.init_s1_demod		= vp1041_stb0899_s1_init_3,
+	.init_s2_fec		= stb0899_s2_init_4,
+	.init_tst		= stb0899_s1_init_5,
+
+	.demod_address 		= 0x68, /*  0xd0 >> 1 */
+
+	.xtal_freq		= 27000000,
+	.inversion		= IQ_SWAP_ON, /* 1 */
+
+	.lo_clk			= 76500000,
+	.hi_clk			= 99000000,
+
+	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
+	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
+	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
+	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
+	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
+	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
+	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
+	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
+	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
+
+	.tuner_get_frequency	= stb6100_get_frequency,
+	.tuner_set_frequency	= stb6100_set_frequency,
+	.tuner_set_bandwidth	= stb6100_set_bandwidth,
+	.tuner_get_bandwidth	= stb6100_get_bandwidth,
+	.tuner_set_rfsiggain	= NULL,
+};
+
+struct stb6100_config vp1041_stb6100_config = {
+	.tuner_address	= 0x60,
+	.refclock	= 27000000,
+};
+
+static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter	= &mantis->adapter;
+
+	int err = 0;
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		mantis_frontend_soft_reset(mantis);
+		msleep(250);
+		mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter);
+		if (mantis->fe) {
+			dprintk(MANTIS_ERROR, 1,
+				"found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
+				vp1041_stb0899_config.demod_address);
+
+			if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) {
+				if (!lnbp21_attach(mantis->fe, adapter, 0, 0))
+					dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
+			}
+		} else {
+			return -EREMOTEIO;
+		}
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+
+
+	dprintk(MANTIS_ERROR, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp1041_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_188,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp1041_frontend_init,
+	.power		= GPIF_A12,
+	.reset		= GPIF_A13,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1041.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1041.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp1041.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp1041.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+/*
+	Mantis VP-1041 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP1041_H
+#define __MANTIS_VP1041_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_1041_DVB_S2	0x0031
+#define SKYSTAR_HD2_10		0x0001
+#define SKYSTAR_HD2_20		0x0003
+#define CINERGY_S2_PCI_HD	0x1179
+
+extern struct mantis_hwconfig vp1041_config;
+
+#endif /* __MANTIS_VP1041_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2033.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2033.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2033.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2033.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,187 @@
+/*
+	Mantis VP-2033 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "tda1002x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp2033.h"
+
+#define MANTIS_MODEL_NAME	"VP-2033"
+#define MANTIS_DEV_TYPE		"DVB-C"
+
+struct tda1002x_config vp2033_tda1002x_cu1216_config = {
+	.demod_address = 0x18 >> 1,
+	.invert = 1,
+};
+
+struct tda10023_config vp2033_tda10023_cu1216_config = {
+	.demod_address = 0x18 >> 1,
+	.invert = 1,
+};
+
+static u8 read_pwm(struct mantis_pci *mantis)
+{
+	struct i2c_adapter *adapter = &mantis->adapter;
+
+	u8 b = 0xff;
+	u8 pwm;
+	struct i2c_msg msg[] = {
+		{.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
+		{.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
+	};
+
+	if ((i2c_transfer(adapter, msg, 2) != 2)
+	    || (pwm == 0xff))
+		pwm = 0x48;
+
+	return pwm;
+}
+
+static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+	struct mantis_pci *mantis = fe->dvb->priv;
+	struct i2c_adapter *adapter = &mantis->adapter;
+
+	u8 buf[6];
+	struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
+	int i;
+
+#define CU1216_IF 36125000
+#define TUNER_MUL 62500
+
+	u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = div & 0xff;
+	buf[2] = 0xce;
+	buf[3] = (params->frequency < 150000000 ? 0x01 :
+		  params->frequency < 445000000 ? 0x02 : 0x04);
+	buf[4] = 0xde;
+	buf[5] = 0x20;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(adapter, &msg, 1) != 1)
+		return -EIO;
+
+	/* wait for the pll lock */
+	msg.flags = I2C_M_RD;
+	msg.len = 1;
+	for (i = 0; i < 20; i++) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+
+		if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
+			break;
+
+		msleep(10);
+	}
+
+	/* switch the charge pump to the lower current */
+	msg.flags = 0;
+	msg.len = 2;
+	msg.buf = &buf[2];
+	buf[2] &= ~0x40;
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(adapter, &msg, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
+static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter = &mantis->adapter;
+
+	int err = 0;
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		mantis_frontend_soft_reset(mantis);
+		msleep(250);
+
+		dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
+		fe = tda10021_attach(&vp2033_tda1002x_cu1216_config,
+				     adapter,
+				     read_pwm(mantis));
+
+		if (fe) {
+			dprintk(MANTIS_ERROR, 1,
+				"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
+				vp2033_tda1002x_cu1216_config.demod_address);
+		} else {
+			fe = tda10023_attach(&vp2033_tda10023_cu1216_config,
+					     adapter,
+					     read_pwm(mantis));
+
+			if (fe) {
+				dprintk(MANTIS_ERROR, 1,
+					"found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
+					vp2033_tda1002x_cu1216_config.demod_address);
+			}
+		}
+
+		if (fe) {
+			fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
+			dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
+		} else {
+			return -1;
+		}
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+
+	mantis->fe = fe;
+	dprintk(MANTIS_DEBUG, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp2033_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_204,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp2033_frontend_init,
+	.power		= GPIF_A12,
+	.reset		= GPIF_A13,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2033.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2033.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2033.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2033.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Mantis VP-2033 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP2033_H
+#define __MANTIS_VP2033_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_2033_DVB_C	0x0008
+
+extern struct mantis_hwconfig vp2033_config;
+
+#endif /* __MANTIS_VP2033_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2040.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2040.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2040.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2040.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,186 @@
+/*
+	Mantis VP-2040 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "tda1002x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp2040.h"
+
+#define MANTIS_MODEL_NAME	"VP-2040"
+#define MANTIS_DEV_TYPE		"DVB-C"
+
+struct tda1002x_config vp2040_tda1002x_cu1216_config = {
+	.demod_address	= 0x18 >> 1,
+	.invert		= 1,
+};
+
+struct tda10023_config vp2040_tda10023_cu1216_config = {
+	.demod_address	= 0x18 >> 1,
+	.invert		= 1,
+};
+
+static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+	struct mantis_pci *mantis	= fe->dvb->priv;
+	struct i2c_adapter *adapter	= &mantis->adapter;
+
+	u8 buf[6];
+	struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
+	int i;
+
+#define CU1216_IF 36125000
+#define TUNER_MUL 62500
+
+	u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = div & 0xff;
+	buf[2] = 0xce;
+	buf[3] = (params->frequency < 150000000 ? 0x01 :
+		  params->frequency < 445000000 ? 0x02 : 0x04);
+	buf[4] = 0xde;
+	buf[5] = 0x20;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(adapter, &msg, 1) != 1)
+		return -EIO;
+
+	/* wait for the pll lock */
+	msg.flags = I2C_M_RD;
+	msg.len = 1;
+	for (i = 0; i < 20; i++) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+
+		if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
+			break;
+
+		msleep(10);
+	}
+
+	/* switch the charge pump to the lower current */
+	msg.flags = 0;
+	msg.len = 2;
+	msg.buf = &buf[2];
+	buf[2] &= ~0x40;
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(adapter, &msg, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
+static u8 read_pwm(struct mantis_pci *mantis)
+{
+	struct i2c_adapter *adapter = &mantis->adapter;
+
+	u8 b = 0xff;
+	u8 pwm;
+	struct i2c_msg msg[] = {
+		{.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
+		{.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
+	};
+
+	if ((i2c_transfer(adapter, msg, 2) != 2)
+	    || (pwm == 0xff))
+		pwm = 0x48;
+
+	return pwm;
+}
+
+static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter = &mantis->adapter;
+
+	int err = 0;
+
+	err = mantis_frontend_power(mantis, POWER_ON);
+	if (err == 0) {
+		mantis_frontend_soft_reset(mantis);
+		msleep(250);
+
+		dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
+		fe = tda10021_attach(&vp2040_tda1002x_cu1216_config,
+				     adapter,
+				     read_pwm(mantis));
+
+		if (fe) {
+			dprintk(MANTIS_ERROR, 1,
+				"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
+				vp2040_tda1002x_cu1216_config.demod_address);
+		} else {
+			fe = tda10023_attach(&vp2040_tda10023_cu1216_config,
+					     adapter,
+					     read_pwm(mantis));
+
+			if (fe) {
+				dprintk(MANTIS_ERROR, 1,
+					"found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
+					vp2040_tda1002x_cu1216_config.demod_address);
+			}
+		}
+
+		if (fe) {
+			fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
+			dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
+		} else {
+			return -1;
+		}
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+	}
+	mantis->fe = fe;
+	dprintk(MANTIS_DEBUG, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp2040_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_204,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp2040_frontend_init,
+	.power		= GPIF_A12,
+	.reset		= GPIF_A13,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2040.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2040.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp2040.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp2040.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/*
+	Mantis VP-2040 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP2040_H
+#define __MANTIS_VP2040_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_2040_DVB_C	0x0043
+#define CINERGY_C		0x1178
+#define CABLESTAR_HD2		0x0002
+
+extern struct mantis_hwconfig vp2040_config;
+
+#endif /* __MANTIS_VP2040_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3028.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3028.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3028.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3028.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,38 @@
+/*
+	Mantis VP-3028 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 "mantis_common.h"
+#include "mantis_vp3028.h"
+
+struct zl10353_config mantis_vp3028_config = {
+	.demod_address	= 0x0f,
+};
+
+#define MANTIS_MODEL_NAME	"VP-3028"
+#define MANTIS_DEV_TYPE		"DVB-T"
+
+struct mantis_hwconfig vp3028_mantis_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_188,
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3028.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3028.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3028.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3028.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,33 @@
+/*
+	Mantis VP-3028 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP3028_H
+#define __MANTIS_VP3028_H
+
+#include "dvb_frontend.h"
+#include "mantis_common.h"
+#include "zl10353.h"
+
+#define MANTIS_VP_3028_DVB_T	0x0028
+
+extern struct zl10353_config mantis_vp3028_config;
+extern struct mantis_hwconfig vp3028_mantis_config;
+
+#endif /* __MANTIS_VP3028_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3030.c linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3030.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3030.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3030.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,105 @@
+/*
+	Mantis VP-3030 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+
+#include "zl10353.h"
+#include "tda665x.h"
+#include "mantis_common.h"
+#include "mantis_ioc.h"
+#include "mantis_dvb.h"
+#include "mantis_vp3030.h"
+
+struct zl10353_config mantis_vp3030_config = {
+	.demod_address		= 0x0f,
+};
+
+struct tda665x_config env57h12d5_config = {
+	.name			= "ENV57H12D5 (ET-50DT)",
+	.addr			= 0x60,
+	.frequency_min		=  47000000,
+	.frequency_max		= 862000000,
+	.frequency_offst	=   3616667,
+	.ref_multiplier		= 6, /* 1/6 MHz */
+	.ref_divider		= 100000, /* 1/6 MHz */
+};
+
+#define MANTIS_MODEL_NAME	"VP-3030"
+#define MANTIS_DEV_TYPE		"DVB-T"
+
+
+static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
+{
+	struct i2c_adapter *adapter	= &mantis->adapter;
+	struct mantis_hwconfig *config	= mantis->hwconfig;
+	int err = 0;
+
+	gpio_set_bits(mantis, config->reset, 0);
+	msleep(100);
+	err = mantis_frontend_power(mantis, POWER_ON);
+	msleep(100);
+	gpio_set_bits(mantis, config->reset, 1);
+
+	if (err == 0) {
+		msleep(250);
+		dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
+		fe = zl10353_attach(&mantis_vp3030_config, adapter);
+
+		if (!fe)
+			return -1;
+
+		tda665x_attach(fe, &env57h12d5_config, adapter);
+	} else {
+		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
+			adapter->name,
+			err);
+
+		return -EIO;
+
+	}
+	mantis->fe = fe;
+	dprintk(MANTIS_ERROR, 1, "Done!");
+
+	return 0;
+}
+
+struct mantis_hwconfig vp3030_config = {
+	.model_name	= MANTIS_MODEL_NAME,
+	.dev_type	= MANTIS_DEV_TYPE,
+	.ts_size	= MANTIS_TS_188,
+
+	.baud_rate	= MANTIS_BAUD_9600,
+	.parity		= MANTIS_PARITY_NONE,
+	.bytes		= 0,
+
+	.frontend_init	= vp3030_frontend_init,
+	.power		= GPIF_A12,
+	.reset		= GPIF_A13,
+
+	.i2c_mode	= MANTIS_BYTE_MODE
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3030.h linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3030.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/mantis/mantis_vp3030.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/mantis/mantis_vp3030.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+	Mantis VP-3030 driver
+
+	Copyright (C) Manu Abraham (abraham.manu@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.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You 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 __MANTIS_VP3030_H
+#define __MANTIS_VP3030_H
+
+#include "mantis_common.h"
+
+#define MANTIS_VP_3030_DVB_T	0x0024
+
+extern struct mantis_hwconfig vp3030_config;
+
+#endif /* __MANTIS_VP3030_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/pt1.c linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/pt1.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/pt1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/pt1.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
-#include <linux/vmalloc.h>
 
 #include "dvbdev.h"
 #include "dvb_demux.h"
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/va1j5jf8007s.c linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/va1j5jf8007s.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/va1j5jf8007s.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/va1j5jf8007s.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,60 @@ struct va1j5jf8007s_state {
 	enum va1j5jf8007s_tune_state tune_state;
 };
 
+static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct va1j5jf8007s_state *state;
+	u8 addr;
+	int i;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+	s32 word, x1, x2, x3, x4, x5, y;
+
+	state = fe->demodulator_priv;
+	addr = state->config->demod_address;
+
+	word = 0;
+	for (i = 0; i < 2; i++) {
+		write_buf[0] = 0xbc + i;
+
+		msgs[0].addr = addr;
+		msgs[0].flags = 0;
+		msgs[0].len = sizeof(write_buf);
+		msgs[0].buf = write_buf;
+
+		msgs[1].addr = addr;
+		msgs[1].flags = I2C_M_RD;
+		msgs[1].len = sizeof(read_buf);
+		msgs[1].buf = read_buf;
+
+		if (i2c_transfer(state->adap, msgs, 2) != 2)
+			return -EREMOTEIO;
+
+		word <<= 8;
+		word |= read_buf[0];
+	}
+
+	word -= 3000;
+	if (word < 0)
+		word = 0;
+
+	x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
+	x2 = (s64)x1 * x1 >> 31;
+	x3 = (s64)x2 * x1 >> 31;
+	x4 = (s64)x2 * x2 >> 31;
+	x5 = (s64)x4 * x1 >> 31;
+
+	y = (58857ll << 23) / 1000;
+	y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
+	y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
+	y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
+	y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
+	y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
+
+	*snr = y < 0 ? 0 : y >> 15;
+	return 0;
+}
+
 static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
 {
 	return DVBFE_ALGO_HW;
@@ -337,7 +391,7 @@ va1j5jf8007s_tune(struct dvb_frontend *f
 {
 	struct va1j5jf8007s_state *state;
 	int ret;
-	int lock;
+	int lock = 0;
 
 	state = fe->demodulator_priv;
 
@@ -536,6 +590,7 @@ static struct dvb_frontend_ops va1j5jf80
 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
 	},
 
+	.read_snr = va1j5jf8007s_read_snr,
 	.get_frontend_algo = va1j5jf8007s_get_frontend_algo,
 	.read_status = va1j5jf8007s_read_status,
 	.tune = va1j5jf8007s_tune,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/va1j5jf8007t.c linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/va1j5jf8007t.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/pt1/va1j5jf8007t.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/pt1/va1j5jf8007t.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,52 @@ struct va1j5jf8007t_state {
 	enum va1j5jf8007t_tune_state tune_state;
 };
 
+static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct va1j5jf8007t_state *state;
+	u8 addr;
+	int i;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+	s32 word, x, y;
+
+	state = fe->demodulator_priv;
+	addr = state->config->demod_address;
+
+	word = 0;
+	for (i = 0; i < 3; i++) {
+		write_buf[0] = 0x8b + i;
+
+		msgs[0].addr = addr;
+		msgs[0].flags = 0;
+		msgs[0].len = sizeof(write_buf);
+		msgs[0].buf = write_buf;
+
+		msgs[1].addr = addr;
+		msgs[1].flags = I2C_M_RD;
+		msgs[1].len = sizeof(read_buf);
+		msgs[1].buf = read_buf;
+
+		if (i2c_transfer(state->adap, msgs, 2) != 2)
+			return -EREMOTEIO;
+
+		word <<= 8;
+		word |= read_buf[0];
+	}
+
+	if (!word)
+		return -EIO;
+
+	x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
+	y = (24ll << 46) / 1000000;
+	y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
+	y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
+	y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
+	y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
+	*snr = y >> 15;
+	return 0;
+}
+
 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
 {
 	return DVBFE_ALGO_HW;
@@ -224,7 +270,7 @@ va1j5jf8007t_tune(struct dvb_frontend *f
 {
 	struct va1j5jf8007t_state *state;
 	int ret;
-	int lock, retry;
+	int lock = 0, retry = 0;
 
 	state = fe->demodulator_priv;
 
@@ -393,6 +439,7 @@ static struct dvb_frontend_ops va1j5jf80
 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
 	},
 
+	.read_snr = va1j5jf8007t_read_snr,
 	.get_frontend_algo = va1j5jf8007t_get_frontend_algo,
 	.read_status = va1j5jf8007t_read_status,
 	.tune = va1j5jf8007t_tune,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/sms-cards.c linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 13:57:54.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 12:05:03.000000000 -0400
@@ -97,7 +97,7 @@ static struct sms_board sms_boards[] = {
 	},
 };
 
-struct sms_board *sms_get_board(int id)
+struct sms_board *sms_get_board(unsigned id)
 {
 	BUG_ON(id >= ARRAY_SIZE(sms_boards));
 
@@ -294,6 +294,8 @@ int sms_board_load_modules(int id)
 	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
 	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
 	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
 		request_module("smsdvb");
 		break;
 	default:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/sms-cards.h linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.h
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/sms-cards.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/sms-cards.h	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ struct sms_board {
 	int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
 };
 
-struct sms_board *sms_get_board(int id);
+struct sms_board *sms_get_board(unsigned id);
 
 extern struct smscore_device_t *coredev;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smscoreapi.c linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 13:57:52.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 12:05:01.000000000 -0400
@@ -1373,7 +1373,7 @@ static int GetGpioPinParams(u32 PinNum,
 
 	*pGroupCfg = 1;
 
-	if (PinNum >= 0 && PinNum <= 1)	{
+	if (PinNum <= 1)	{
 		*pTranslatedPinNum = 0;
 		*pGroupNum = 9;
 		*pGroupCfg = 2;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smsdvb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsdvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smsdvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsdvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -662,7 +662,7 @@ adapter_error:
 	return rc;
 }
 
-int smsdvb_module_init(void)
+static int __init smsdvb_module_init(void)
 {
 	int rc;
 
@@ -676,7 +676,7 @@ int smsdvb_module_init(void)
 	return rc;
 }
 
-void smsdvb_module_exit(void)
+static void __exit smsdvb_module_exit(void)
 {
 	smscore_unregister_hotplug(smsdvb_hotplug);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smssdio.c linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smssdio.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smssdio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smssdio.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,7 @@
 #define SMSSDIO_INT		0x04
 #define SMSSDIO_BLOCK_SIZE	128
 
-static const struct sdio_device_id smssdio_ids[] = {
+static const struct sdio_device_id smssdio_ids[] __devinitconst = {
 	{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
 	 .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
 	{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
@@ -78,7 +78,7 @@ struct smssdio_device {
 
 static int smssdio_sendrequest(void *context, void *buffer, size_t size)
 {
-	int ret;
+	int ret = 0;
 	struct smssdio_device *smsdev;
 
 	smsdev = context;
@@ -222,7 +222,7 @@ static void smssdio_interrupt(struct sdi
 	smscore_onresponse(smsdev->coredev, cb);
 }
 
-static int smssdio_probe(struct sdio_func *func,
+static int __devinit smssdio_probe(struct sdio_func *func,
 			 const struct sdio_device_id *id)
 {
 	int ret;
@@ -338,7 +338,7 @@ static struct sdio_driver smssdio_driver
 /* Module functions                                                */
 /*******************************************************************/
 
-int smssdio_module_init(void)
+static int __init smssdio_module_init(void)
 {
 	int ret = 0;
 
@@ -350,7 +350,7 @@ int smssdio_module_init(void)
 	return ret;
 }
 
-void smssdio_module_exit(void)
+static void __exit smssdio_module_exit(void)
 {
 	sdio_unregister_driver(&smssdio_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smsusb.c linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsusb.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 13:57:56.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 12:05:05.000000000 -0400
@@ -390,7 +390,7 @@ static int smsusb_init_device(struct usb
 	return rc;
 }
 
-static int smsusb_probe(struct usb_interface *intf,
+static int __devinit smsusb_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
@@ -484,7 +484,7 @@ static int smsusb_resume(struct usb_inte
 	return 0;
 }
 
-struct usb_device_id smsusb_id_table[] = {
+static const struct usb_device_id smsusb_id_table[] __devinitconst = {
 	{ USB_DEVICE(0x187f, 0x0010),
 		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
 	{ USB_DEVICE(0x187f, 0x0100),
@@ -533,8 +533,18 @@ struct usb_device_id smsusb_id_table[] =
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0xb910),
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xb980),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xb990),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0xc000),
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xc010),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xc080),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0xc090),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ } /* Terminating entry */
 	};
 
@@ -550,7 +560,7 @@ static struct usb_driver smsusb_driver =
 	.resume			= smsusb_resume,
 };
 
-int smsusb_module_init(void)
+static int __init smsusb_module_init(void)
 {
 	int rc = usb_register(&smsusb_driver);
 	if (rc)
@@ -561,7 +571,7 @@ int smsusb_module_init(void)
 	return rc;
 }
 
-void smsusb_module_exit(void)
+static void __exit smsusb_module_exit(void)
 {
 	/* Regular USB Cleanup */
 	usb_deregister(&smsusb_driver);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/av7110.c linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 13:57:48.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 12:04:57.000000000 -0400
@@ -2425,7 +2425,7 @@ static int __devinit av7110_attach(struc
 		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 		 */
 		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		/* set event counter 1 threshold to maximum allowed value        (rEC p55) */
 		saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 		/* Set RPS1 Address register to point to RPS code               (r108 p42) */
@@ -2559,7 +2559,7 @@ static int __devinit av7110_attach(struc
 		 * use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 		 */
 		saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-		/* set event counter 1 treshold to maximum allowed value        (rEC p55) */
+		/* set event counter 1 threshold to maximum allowed value        (rEC p55) */
 		saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 		/* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-av.c linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-av.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-av.c	2013-05-03 13:57:48.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-av.c	2013-05-03 12:04:57.000000000 -0400
@@ -1055,7 +1055,7 @@ static const struct stb0899_s1_reg knc1_
 	{ STB0899_TSCFGH		, 0x0c },
 	{ STB0899_TSCFGM		, 0x00 },
 	{ STB0899_TSCFGL		, 0x0c },
-	{ STB0899_TSOUT			, 0x0d }, /* 0x0d for CAM */
+	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
 	{ STB0899_RSSYNCDEL		, 0x00 },
 	{ STB0899_TSINHDELH		, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-ci.c linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-ci.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 13:57:48.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 12:04:57.000000000 -0400
@@ -178,7 +178,7 @@ static void msp430_ir_interrupt(unsigned
 	if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
 		ir_input_nokey(dev, &budget_ci->ir.state);
 		ir_input_keydown(dev, &budget_ci->ir.state,
-				 budget_ci->ir.ir_key, raw);
+				 budget_ci->ir.ir_key);
 		budget_ci->ir.last_raw = raw;
 	}
 
@@ -190,12 +190,13 @@ static int msp430_ir_init(struct budget_
 	struct saa7146_dev *saa = budget_ci->budget.dev;
 	struct input_dev *input_dev = budget_ci->ir.dev;
 	int error;
+	struct ir_scancode_table *ir_codes;
+
 
 	budget_ci->ir.dev = input_dev = input_allocate_device();
 	if (!input_dev) {
 		printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
-		error = -ENOMEM;
-		goto out1;
+		return -ENOMEM;
 	}
 
 	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
@@ -217,6 +218,11 @@ static int msp430_ir_init(struct budget_
 	}
 	input_dev->dev.parent = &saa->pci->dev;
 
+	if (rc5_device < 0)
+		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+	else
+		budget_ci->ir.rc5_device = rc5_device;
+
 	/* Select keymap and address */
 	switch (budget_ci->budget.dev->pci->subsystem_device) {
 	case 0x100c:
@@ -224,47 +230,34 @@ static int msp430_ir_init(struct budget_
 	case 0x1011:
 	case 0x1012:
 		/* The hauppauge keymap is a superset of these remotes */
-		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
+		ir_codes = &ir_codes_hauppauge_new_table;
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = 0x1f;
-		else
-			budget_ci->ir.rc5_device = rc5_device;
 		break;
 	case 0x1010:
 	case 0x1017:
 	case 0x101a:
 		/* for the Technotrend 1500 bundled remote */
-		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, &ir_codes_tt_1500_table);
-
-		if (rc5_device < 0)
-			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
-		else
-			budget_ci->ir.rc5_device = rc5_device;
+		ir_codes = &ir_codes_tt_1500_table;
 		break;
 	default:
 		/* unknown remote */
-		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
-
-		if (rc5_device < 0)
-			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
-		else
-			budget_ci->ir.rc5_device = rc5_device;
+		ir_codes = &ir_codes_budget_ci_old_table;
 		break;
 	}
 
+	ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5);
+
 	/* initialise the key-up timeout handler */
 	init_timer(&budget_ci->ir.timer_keyup);
 	budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
 	budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
 	budget_ci->ir.last_raw = 0xffff; /* An impossible value */
-	error = input_register_device(input_dev);
+	error = ir_input_register(input_dev, ir_codes);
 	if (error) {
 		printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
-		goto out2;
+		return error;
 	}
 
 	/* note: these must be after input_register_device */
@@ -278,11 +271,6 @@ static int msp430_ir_init(struct budget_
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
 
 	return 0;
-
-out2:
-	input_free_device(input_dev);
-out1:
-	return error;
 }
 
 static void msp430_ir_deinit(struct budget_ci *budget_ci)
@@ -297,7 +285,7 @@ static void msp430_ir_deinit(struct budg
 	del_timer_sync(&dev->timer);
 	ir_input_nokey(dev, &budget_ci->ir.state);
 
-	input_unregister_device(dev);
+	ir_input_unregister(dev);
 }
 
 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
@@ -1248,7 +1236,7 @@ static const struct stb0899_s1_reg tt320
 	{ STB0899_TSCFGH        	, 0x0c },
 	{ STB0899_TSCFGM        	, 0x00 },
 	{ STB0899_TSCFGL        	, 0x0c },
-	{ STB0899_TSOUT			, 0x0d }, /* 0x0d for CAM */
+	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
 	{ STB0899_RSSYNCDEL     	, 0x00 },
 	{ STB0899_TSINHDELH     	, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-patch.c linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-patch.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/ttpci/budget-patch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/ttpci/budget-patch.c	2010-02-24 13:52:17.000000000 -0500
@@ -456,7 +456,7 @@ static int budget_patch_attach (struct s
 	// use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
 	// use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
 	saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-	// set event counter 1 treshold to maximum allowed value        (rEC p55)
+	// set event counter 1 threshold to maximum allowed value        (rEC p55)
 	saa7146_write(dev, ECT1R,  0x3fff );
 #endif
 	// Fix VSYNC level
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/dvb/ttusb-dec/ttusb_dec.c linux-libre-2.6.33-gnu1/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- linux-libre-2.6.32-gnu1/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2013-05-03 13:58:01.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2013-05-03 12:05:10.000000000 -0400
@@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_d
 	int err;
 
 	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
-	strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
+	strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
 
 	input_dev = input_allocate_device();
 	if (!input_dev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/IR/ir-functions.c linux-libre-2.6.33-gnu1/drivers/media/IR/ir-functions.c
--- linux-libre-2.6.32-gnu1/drivers/media/IR/ir-functions.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/IR/ir-functions.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,355 @@
+/*
+ *
+ * some common structs and functions to handle infrared remotes via
+ * input layer ...
+ *
+ * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  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/module.h>
+#include <linux/string.h>
+#include <linux/jiffies.h>
+#include <media/ir-common.h>
+
+/* -------------------------------------------------------------------------- */
+
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_LICENSE("GPL");
+
+static int repeat = 1;
+module_param(repeat, int, 0444);
+MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
+
+/* -------------------------------------------------------------------------- */
+
+static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
+{
+	if (KEY_RESERVED == ir->keycode) {
+		printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
+		       dev->name, ir->ir_key, ir->keypressed);
+		return;
+	}
+	IR_dprintk(1,"%s: key event code=%d down=%d\n",
+		dev->name,ir->keycode,ir->keypressed);
+	input_report_key(dev,ir->keycode,ir->keypressed);
+	input_sync(dev);
+}
+
+/* -------------------------------------------------------------------------- */
+
+int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
+		   int ir_type)
+{
+	ir->ir_type = ir_type;
+
+	if (repeat)
+		set_bit(EV_REP, dev->evbit);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ir_input_init);
+
+
+void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
+{
+	if (ir->keypressed) {
+		ir->keypressed = 0;
+		ir_input_key_event(dev,ir);
+	}
+}
+EXPORT_SYMBOL_GPL(ir_input_nokey);
+
+void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
+		      u32 ir_key)
+{
+	u32 keycode = ir_g_keycode_from_table(dev, ir_key);
+
+	if (ir->keypressed && ir->keycode != keycode) {
+		ir->keypressed = 0;
+		ir_input_key_event(dev,ir);
+	}
+	if (!ir->keypressed) {
+		ir->ir_key  = ir_key;
+		ir->keycode = keycode;
+		ir->keypressed = 1;
+		ir_input_key_event(dev,ir);
+	}
+}
+EXPORT_SYMBOL_GPL(ir_input_keydown);
+
+/* -------------------------------------------------------------------------- */
+/* extract mask bits out of data and pack them into the result */
+u32 ir_extract_bits(u32 data, u32 mask)
+{
+	u32 vbit = 1, value = 0;
+
+	do {
+	    if (mask&1) {
+		if (data&1)
+			value |= vbit;
+		vbit<<=1;
+	    }
+	    data>>=1;
+	} while (mask>>=1);
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(ir_extract_bits);
+
+static int inline getbit(u32 *samples, int bit)
+{
+	return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
+}
+
+/* sump raw samples for visual debugging ;) */
+int ir_dump_samples(u32 *samples, int count)
+{
+	int i, bit, start;
+
+	printk(KERN_DEBUG "ir samples: ");
+	start = 0;
+	for (i = 0; i < count * 32; i++) {
+		bit = getbit(samples,i);
+		if (bit)
+			start = 1;
+		if (0 == start)
+			continue;
+		printk("%s", bit ? "#" : "_");
+	}
+	printk("\n");
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ir_dump_samples);
+
+/* decode raw samples, pulse distance coding used by NEC remotes */
+int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
+{
+	int i,last,bit,len;
+	u32 curBit;
+	u32 value;
+
+	/* find start burst */
+	for (i = len = 0; i < count * 32; i++) {
+		bit = getbit(samples,i);
+		if (bit) {
+			len++;
+		} else {
+			if (len >= 29)
+				break;
+			len = 0;
+		}
+	}
+
+	/* start burst to short */
+	if (len < 29)
+		return 0xffffffff;
+
+	/* find start silence */
+	for (len = 0; i < count * 32; i++) {
+		bit = getbit(samples,i);
+		if (bit) {
+			break;
+		} else {
+			len++;
+		}
+	}
+
+	/* silence to short */
+	if (len < 7)
+		return 0xffffffff;
+
+	/* go decoding */
+	len   = 0;
+	last = 1;
+	value = 0; curBit = 1;
+	for (; i < count * 32; i++) {
+		bit  = getbit(samples,i);
+		if (last) {
+			if(bit) {
+				continue;
+			} else {
+				len = 1;
+			}
+		} else {
+			if (bit) {
+				if (len > (low + high) /2)
+					value |= curBit;
+				curBit <<= 1;
+				if (curBit == 1)
+					break;
+			} else {
+				len++;
+			}
+		}
+		last = bit;
+	}
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
+
+/* decode raw samples, biphase coding, used by rc5 for example */
+int ir_decode_biphase(u32 *samples, int count, int low, int high)
+{
+	int i,last,bit,len,flips;
+	u32 value;
+
+	/* find start bit (1) */
+	for (i = 0; i < 32; i++) {
+		bit = getbit(samples,i);
+		if (bit)
+			break;
+	}
+
+	/* go decoding */
+	len   = 0;
+	flips = 0;
+	value = 1;
+	for (; i < count * 32; i++) {
+		if (len > high)
+			break;
+		if (flips > 1)
+			break;
+		last = bit;
+		bit  = getbit(samples,i);
+		if (last == bit) {
+			len++;
+			continue;
+		}
+		if (len < low) {
+			len++;
+			flips++;
+			continue;
+		}
+		value <<= 1;
+		value |= bit;
+		flips = 0;
+		len   = 1;
+	}
+	return value;
+}
+EXPORT_SYMBOL_GPL(ir_decode_biphase);
+
+/* RC5 decoding stuff, moved from bttv-input.c to share it with
+ * saa7134 */
+
+/* decode raw bit pattern to RC5 code */
+u32 ir_rc5_decode(unsigned int code)
+{
+	unsigned int org_code = code;
+	unsigned int pair;
+	unsigned int rc5 = 0;
+	int i;
+
+	for (i = 0; i < 14; ++i) {
+		pair = code & 0x3;
+		code >>= 2;
+
+		rc5 <<= 1;
+		switch (pair) {
+		case 0:
+		case 2:
+			break;
+		case 1:
+			rc5 |= 1;
+			break;
+		case 3:
+			IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
+			return 0;
+		}
+	}
+	IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+		"instr=%x\n", rc5, org_code, RC5_START(rc5),
+		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+	return rc5;
+}
+EXPORT_SYMBOL_GPL(ir_rc5_decode);
+
+void ir_rc5_timer_end(unsigned long data)
+{
+	struct card_ir *ir = (struct card_ir *)data;
+	struct timeval tv;
+	unsigned long current_jiffies, timeout;
+	u32 gap;
+	u32 rc5 = 0;
+
+	/* get time */
+	current_jiffies = jiffies;
+	do_gettimeofday(&tv);
+
+	/* avoid overflow with gap >1s */
+	if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+		gap = 200000;
+	} else {
+		gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+		    tv.tv_usec - ir->base_time.tv_usec;
+	}
+
+	/* signal we're ready to start a new code */
+	ir->active = 0;
+
+	/* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
+	if (gap < 28000) {
+		IR_dprintk(1, "ir-common: spurious timer_end\n");
+		return;
+	}
+
+	if (ir->last_bit < 20) {
+		/* ignore spurious codes (caused by light/other remotes) */
+		IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
+	} else {
+		ir->code = (ir->code << ir->shift_by) | 1;
+		rc5 = ir_rc5_decode(ir->code);
+
+		/* two start bits? */
+		if (RC5_START(rc5) != ir->start) {
+			IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+			/* right address? */
+		} else if (RC5_ADDR(rc5) == ir->addr) {
+			u32 toggle = RC5_TOGGLE(rc5);
+			u32 instr = RC5_INSTR(rc5);
+
+			/* Good code, decide if repeat/repress */
+			if (toggle != RC5_TOGGLE(ir->last_rc5) ||
+			    instr != RC5_INSTR(ir->last_rc5)) {
+				IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
+					toggle);
+				ir_input_nokey(ir->dev, &ir->ir);
+				ir_input_keydown(ir->dev, &ir->ir, instr);
+			}
+
+			/* Set/reset key-up timer */
+			timeout = current_jiffies +
+				  msecs_to_jiffies(ir->rc5_key_timeout);
+			mod_timer(&ir->timer_keyup, timeout);
+
+			/* Save code for repeat test */
+			ir->last_rc5 = rc5;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
+
+void ir_rc5_timer_keyup(unsigned long data)
+{
+	struct card_ir *ir = (struct card_ir *)data;
+
+	IR_dprintk(1, "ir-common: key released\n");
+	ir_input_nokey(ir->dev, &ir->ir);
+}
+EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/IR/ir-keymaps.c linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keymaps.c
--- linux-libre-2.6.32-gnu1/drivers/media/IR/ir-keymaps.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keymaps.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3395 @@
+/*
+    Keytables for supported remote controls, used on drivers/media
+    devices.
+
+    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.
+*/
+
+/*
+ * NOTICE FOR DEVELOPERS:
+ *   The IR mappings should be as close as possible to what's
+ *   specified at:
+ *      http://linuxtv.org/wiki/index.php/Remote_Controllers
+ */
+#include <linux/module.h>
+
+#include <linux/input.h>
+#include <media/ir-common.h>
+
+/* empty keytable, can be used as placeholder for not-yet created keytables */
+static struct ir_scancode ir_codes_empty[] = {
+	{ 0x2a, KEY_COFFEE },
+};
+
+struct ir_scancode_table ir_codes_empty_table = {
+	.scan = ir_codes_empty,
+	.size = ARRAY_SIZE(ir_codes_empty),
+};
+EXPORT_SYMBOL_GPL(ir_codes_empty_table);
+
+/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
+static struct ir_scancode ir_codes_proteus_2309[] = {
+	/* numeric */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x5c, KEY_POWER },		/* power       */
+	{ 0x20, KEY_ZOOM },		/* full screen */
+	{ 0x0f, KEY_BACKSPACE },	/* recall      */
+	{ 0x1b, KEY_ENTER },		/* mute        */
+	{ 0x41, KEY_RECORD },		/* record      */
+	{ 0x43, KEY_STOP },		/* stop        */
+	{ 0x16, KEY_S },
+	{ 0x1a, KEY_POWER2 },		/* off         */
+	{ 0x2e, KEY_RED },
+	{ 0x1f, KEY_CHANNELDOWN },	/* channel -   */
+	{ 0x1c, KEY_CHANNELUP },	/* channel +   */
+	{ 0x10, KEY_VOLUMEDOWN },	/* volume -    */
+	{ 0x1e, KEY_VOLUMEUP },		/* volume +    */
+	{ 0x14, KEY_F1 },
+};
+
+struct ir_scancode_table ir_codes_proteus_2309_table = {
+	.scan = ir_codes_proteus_2309,
+	.size = ARRAY_SIZE(ir_codes_proteus_2309),
+};
+EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
+
+/* Matt Jesson <dvb@jesson.eclipse.co.uk */
+static struct ir_scancode ir_codes_avermedia_dvbt[] = {
+	{ 0x28, KEY_0 },		/* '0' / 'enter' */
+	{ 0x22, KEY_1 },		/* '1' */
+	{ 0x12, KEY_2 },		/* '2' / 'up arrow' */
+	{ 0x32, KEY_3 },		/* '3' */
+	{ 0x24, KEY_4 },		/* '4' / 'left arrow' */
+	{ 0x14, KEY_5 },		/* '5' */
+	{ 0x34, KEY_6 },		/* '6' / 'right arrow' */
+	{ 0x26, KEY_7 },		/* '7' */
+	{ 0x16, KEY_8 },		/* '8' / 'down arrow' */
+	{ 0x36, KEY_9 },		/* '9' */
+
+	{ 0x20, KEY_LIST },		/* 'source' */
+	{ 0x10, KEY_TEXT },		/* 'teletext' */
+	{ 0x00, KEY_POWER },		/* 'power' */
+	{ 0x04, KEY_AUDIO },		/* 'audio' */
+	{ 0x06, KEY_ZOOM },		/* 'full screen' */
+	{ 0x18, KEY_VIDEO },		/* 'display' */
+	{ 0x38, KEY_SEARCH },		/* 'loop' */
+	{ 0x08, KEY_INFO },		/* 'preview' */
+	{ 0x2a, KEY_REWIND },		/* 'backward <<' */
+	{ 0x1a, KEY_FASTFORWARD },	/* 'forward >>' */
+	{ 0x3a, KEY_RECORD },		/* 'capture' */
+	{ 0x0a, KEY_MUTE },		/* 'mute' */
+	{ 0x2c, KEY_RECORD },		/* 'record' */
+	{ 0x1c, KEY_PAUSE },		/* 'pause' */
+	{ 0x3c, KEY_STOP },		/* 'stop' */
+	{ 0x0c, KEY_PLAY },		/* 'play' */
+	{ 0x2e, KEY_RED },		/* 'red' */
+	{ 0x01, KEY_BLUE },		/* 'blue' / 'cancel' */
+	{ 0x0e, KEY_YELLOW },		/* 'yellow' / 'ok' */
+	{ 0x21, KEY_GREEN },		/* 'green' */
+	{ 0x11, KEY_CHANNELDOWN },	/* 'channel -' */
+	{ 0x31, KEY_CHANNELUP },	/* 'channel +' */
+	{ 0x1e, KEY_VOLUMEDOWN },	/* 'volume -' */
+	{ 0x3e, KEY_VOLUMEUP },		/* 'volume +' */
+};
+
+struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
+	.scan = ir_codes_avermedia_dvbt,
+	.size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
+
+/* Mauro Carvalho Chehab <mchehab@infradead.org> */
+static struct ir_scancode ir_codes_avermedia_m135a[] = {
+	{ 0x00, KEY_POWER2 },
+	{ 0x2e, KEY_DOT },		/* '.' */
+	{ 0x01, KEY_MODE },		/* TV/FM */
+
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x11, KEY_0 },
+
+	{ 0x13, KEY_RIGHT },		/* -> */
+	{ 0x12, KEY_LEFT },		/* <- */
+
+	{ 0x17, KEY_SLEEP },		/* Capturar Imagem */
+	{ 0x10, KEY_SHUFFLE },		/* Amostra */
+
+	/* FIXME: The keys bellow aren't ok */
+
+	{ 0x43, KEY_CHANNELUP },
+	{ 0x42, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_ENTER },
+
+	{ 0x14, KEY_MUTE },
+	{ 0x08, KEY_AUDIO },
+
+	{ 0x03, KEY_TEXT },
+	{ 0x04, KEY_EPG },
+	{ 0x2b, KEY_TV2 },		/* TV2 */
+
+	{ 0x1d, KEY_RED },
+	{ 0x1c, KEY_YELLOW },
+	{ 0x41, KEY_GREEN },
+	{ 0x40, KEY_BLUE },
+
+	{ 0x1a, KEY_PLAYPAUSE },
+	{ 0x19, KEY_RECORD },
+	{ 0x18, KEY_PLAY },
+	{ 0x1b, KEY_STOP },
+};
+
+struct ir_scancode_table ir_codes_avermedia_m135a_table = {
+	.scan = ir_codes_avermedia_m135a,
+	.size = ARRAY_SIZE(ir_codes_avermedia_m135a),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
+
+/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+static struct ir_scancode ir_codes_avermedia_cardbus[] = {
+	{ 0x00, KEY_POWER },
+	{ 0x01, KEY_TUNER },		/* TV/FM */
+	{ 0x03, KEY_TEXT },		/* Teletext */
+	{ 0x04, KEY_EPG },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x08, KEY_AUDIO },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0c, KEY_ZOOM },		/* Full screen */
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x10, KEY_PAGEUP },		/* 16-CH PREV */
+	{ 0x11, KEY_0 },
+	{ 0x12, KEY_INFO },
+	{ 0x13, KEY_AGAIN },		/* CH RTN - channel return */
+	{ 0x14, KEY_MUTE },
+	{ 0x15, KEY_EDIT },		/* Autoscan */
+	{ 0x17, KEY_SAVE },		/* Screenshot */
+	{ 0x18, KEY_PLAYPAUSE },
+	{ 0x19, KEY_RECORD },
+	{ 0x1a, KEY_PLAY },
+	{ 0x1b, KEY_STOP },
+	{ 0x1c, KEY_FASTFORWARD },
+	{ 0x1d, KEY_REWIND },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_VOLUMEUP },
+	{ 0x22, KEY_SLEEP },		/* Sleep */
+	{ 0x23, KEY_ZOOM },		/* Aspect */
+	{ 0x26, KEY_SCREEN },		/* Pos */
+	{ 0x27, KEY_ANGLE },		/* Size */
+	{ 0x28, KEY_SELECT },		/* Select */
+	{ 0x29, KEY_BLUE },		/* Blue/Picture */
+	{ 0x2a, KEY_BACKSPACE },	/* Back */
+	{ 0x2b, KEY_MEDIA },		/* PIP (Picture-in-picture) */
+	{ 0x2c, KEY_DOWN },
+	{ 0x2e, KEY_DOT },
+	{ 0x2f, KEY_TV },		/* Live TV */
+	{ 0x32, KEY_LEFT },
+	{ 0x33, KEY_CLEAR },		/* Clear */
+	{ 0x35, KEY_RED },		/* Red/TV */
+	{ 0x36, KEY_UP },
+	{ 0x37, KEY_HOME },		/* Home */
+	{ 0x39, KEY_GREEN },		/* Green/Video */
+	{ 0x3d, KEY_YELLOW },		/* Yellow/Music */
+	{ 0x3e, KEY_OK },		/* Ok */
+	{ 0x3f, KEY_RIGHT },
+	{ 0x40, KEY_NEXT },		/* Next */
+	{ 0x41, KEY_PREVIOUS },		/* Previous */
+	{ 0x42, KEY_CHANNELDOWN },	/* Channel down */
+	{ 0x43, KEY_CHANNELUP },	/* Channel up */
+};
+
+struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
+	.scan = ir_codes_avermedia_cardbus,
+	.size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
+
+/* Attila Kondoros <attila.kondoros@chello.hu> */
+static struct ir_scancode ir_codes_apac_viewcomp[] = {
+
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_LAST },		/* +100 */
+	{ 0x0a, KEY_LIST },		/* recall */
+
+
+	{ 0x1c, KEY_TUNER },		/* TV/FM */
+	{ 0x15, KEY_SEARCH },		/* scan */
+	{ 0x12, KEY_POWER },		/* power */
+	{ 0x1f, KEY_VOLUMEDOWN },	/* vol up */
+	{ 0x1b, KEY_VOLUMEUP },		/* vol down */
+	{ 0x1e, KEY_CHANNELDOWN },	/* chn up */
+	{ 0x1a, KEY_CHANNELUP },	/* chn down */
+
+	{ 0x11, KEY_VIDEO },		/* video */
+	{ 0x0f, KEY_ZOOM },		/* full screen */
+	{ 0x13, KEY_MUTE },		/* mute/unmute */
+	{ 0x10, KEY_TEXT },		/* min */
+
+	{ 0x0d, KEY_STOP },		/* freeze */
+	{ 0x0e, KEY_RECORD },		/* record */
+	{ 0x1d, KEY_PLAYPAUSE },	/* stop */
+	{ 0x19, KEY_PLAY },		/* play */
+
+	{ 0x16, KEY_GOTO },		/* osd */
+	{ 0x14, KEY_REFRESH },		/* default */
+	{ 0x0c, KEY_KPPLUS },		/* fine tune >>>> */
+	{ 0x18, KEY_KPMINUS },		/* fine tune <<<< */
+};
+
+struct ir_scancode_table ir_codes_apac_viewcomp_table = {
+	.scan = ir_codes_apac_viewcomp,
+	.size = ARRAY_SIZE(ir_codes_apac_viewcomp),
+};
+EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
+
+/* ---------------------------------------------------------------------- */
+
+static struct ir_scancode ir_codes_pixelview[] = {
+
+	{ 0x1e, KEY_POWER },	/* power */
+	{ 0x07, KEY_MEDIA },	/* source */
+	{ 0x1c, KEY_SEARCH },	/* scan */
+
+
+	{ 0x03, KEY_TUNER },		/* TV/FM */
+
+	{ 0x00, KEY_RECORD },
+	{ 0x08, KEY_STOP },
+	{ 0x11, KEY_PLAY },
+
+	{ 0x1a, KEY_PLAYPAUSE },	/* freeze */
+	{ 0x19, KEY_ZOOM },		/* zoom */
+	{ 0x0f, KEY_TEXT },		/* min */
+
+	{ 0x01, KEY_1 },
+	{ 0x0b, KEY_2 },
+	{ 0x1b, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x09, KEY_5 },
+	{ 0x15, KEY_6 },
+	{ 0x06, KEY_7 },
+	{ 0x0a, KEY_8 },
+	{ 0x12, KEY_9 },
+	{ 0x02, KEY_0 },
+	{ 0x10, KEY_LAST },		/* +100 */
+	{ 0x13, KEY_LIST },		/* recall */
+
+	{ 0x1f, KEY_CHANNELUP },	/* chn down */
+	{ 0x17, KEY_CHANNELDOWN },	/* chn up */
+	{ 0x16, KEY_VOLUMEUP },		/* vol down */
+	{ 0x14, KEY_VOLUMEDOWN },	/* vol up */
+
+	{ 0x04, KEY_KPMINUS },		/* <<< */
+	{ 0x0e, KEY_SETUP },		/* function */
+	{ 0x0c, KEY_KPPLUS },		/* >>> */
+
+	{ 0x0d, KEY_GOTO },		/* mts */
+	{ 0x1d, KEY_REFRESH },		/* reset */
+	{ 0x18, KEY_MUTE },		/* mute/unmute */
+};
+
+struct ir_scancode_table ir_codes_pixelview_table = {
+	.scan = ir_codes_pixelview,
+	.size = ARRAY_SIZE(ir_codes_pixelview),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
+
+/*
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+   present on PV MPEG 8000GT
+ */
+static struct ir_scancode ir_codes_pixelview_new[] = {
+	{ 0x3c, KEY_TIME },		/* Timeshift */
+	{ 0x12, KEY_POWER },
+
+	{ 0x3d, KEY_1 },
+	{ 0x38, KEY_2 },
+	{ 0x18, KEY_3 },
+	{ 0x35, KEY_4 },
+	{ 0x39, KEY_5 },
+	{ 0x15, KEY_6 },
+	{ 0x36, KEY_7 },
+	{ 0x3a, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x3e, KEY_0 },
+
+	{ 0x1c, KEY_AGAIN },		/* LOOP	*/
+	{ 0x3f, KEY_MEDIA },		/* Source */
+	{ 0x1f, KEY_LAST },		/* +100 */
+	{ 0x1b, KEY_MUTE },
+
+	{ 0x17, KEY_CHANNELDOWN },
+	{ 0x16, KEY_CHANNELUP },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x14, KEY_VOLUMEDOWN },
+	{ 0x13, KEY_ZOOM },
+
+	{ 0x19, KEY_CAMERA },		/* SNAPSHOT */
+	{ 0x1a, KEY_SEARCH },		/* scan */
+
+	{ 0x37, KEY_REWIND },		/* << */
+	{ 0x32, KEY_RECORD },		/* o (red) */
+	{ 0x33, KEY_FORWARD },		/* >> */
+	{ 0x11, KEY_STOP },		/* square */
+	{ 0x3b, KEY_PLAY },		/* > */
+	{ 0x30, KEY_PLAYPAUSE },	/* || */
+
+	{ 0x31, KEY_TV },
+	{ 0x34, KEY_RADIO },
+};
+
+struct ir_scancode_table ir_codes_pixelview_new_table = {
+	.scan = ir_codes_pixelview_new,
+	.size = ARRAY_SIZE(ir_codes_pixelview_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
+
+static struct ir_scancode ir_codes_nebula[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_TV },
+	{ 0x0b, KEY_AUX },
+	{ 0x0c, KEY_DVD },
+	{ 0x0d, KEY_POWER },
+	{ 0x0e, KEY_MHP },	/* labelled 'Picture' */
+	{ 0x0f, KEY_AUDIO },
+	{ 0x10, KEY_INFO },
+	{ 0x11, KEY_F13 },	/* 16:9 */
+	{ 0x12, KEY_F14 },	/* 14:9 */
+	{ 0x13, KEY_EPG },
+	{ 0x14, KEY_EXIT },
+	{ 0x15, KEY_MENU },
+	{ 0x16, KEY_UP },
+	{ 0x17, KEY_DOWN },
+	{ 0x18, KEY_LEFT },
+	{ 0x19, KEY_RIGHT },
+	{ 0x1a, KEY_ENTER },
+	{ 0x1b, KEY_CHANNELUP },
+	{ 0x1c, KEY_CHANNELDOWN },
+	{ 0x1d, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_RED },
+	{ 0x20, KEY_GREEN },
+	{ 0x21, KEY_YELLOW },
+	{ 0x22, KEY_BLUE },
+	{ 0x23, KEY_SUBTITLE },
+	{ 0x24, KEY_F15 },	/* AD */
+	{ 0x25, KEY_TEXT },
+	{ 0x26, KEY_MUTE },
+	{ 0x27, KEY_REWIND },
+	{ 0x28, KEY_STOP },
+	{ 0x29, KEY_PLAY },
+	{ 0x2a, KEY_FASTFORWARD },
+	{ 0x2b, KEY_F16 },	/* chapter */
+	{ 0x2c, KEY_PAUSE },
+	{ 0x2d, KEY_PLAY },
+	{ 0x2e, KEY_RECORD },
+	{ 0x2f, KEY_F17 },	/* picture in picture */
+	{ 0x30, KEY_KPPLUS },	/* zoom in */
+	{ 0x31, KEY_KPMINUS },	/* zoom out */
+	{ 0x32, KEY_F18 },	/* capture */
+	{ 0x33, KEY_F19 },	/* web */
+	{ 0x34, KEY_EMAIL },
+	{ 0x35, KEY_PHONE },
+	{ 0x36, KEY_PC },
+};
+
+struct ir_scancode_table ir_codes_nebula_table = {
+	.scan = ir_codes_nebula,
+	.size = ARRAY_SIZE(ir_codes_nebula),
+};
+EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
+
+/* DigitalNow DNTV Live DVB-T Remote */
+static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
+	{ 0x00, KEY_ESC },		/* 'go up a level?' */
+	/* Keys 0 to 9 */
+	{ 0x0a, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0b, KEY_TUNER },		/* tv/fm */
+	{ 0x0c, KEY_SEARCH },		/* scan */
+	{ 0x0d, KEY_STOP },
+	{ 0x0e, KEY_PAUSE },
+	{ 0x0f, KEY_LIST },		/* source */
+
+	{ 0x10, KEY_MUTE },
+	{ 0x11, KEY_REWIND },		/* backward << */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_CAMERA },		/* snap */
+	{ 0x14, KEY_AUDIO },		/* stereo */
+	{ 0x15, KEY_CLEAR },		/* reset */
+	{ 0x16, KEY_PLAY },
+	{ 0x17, KEY_ENTER },
+	{ 0x18, KEY_ZOOM },		/* full screen */
+	{ 0x19, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1c, KEY_INFO },		/* preview */
+	{ 0x1d, KEY_RECORD },		/* record */
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
+	.scan = ir_codes_dntv_live_dvb_t,
+	.size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* IO-DATA BCTV7E Remote */
+static struct ir_scancode ir_codes_iodata_bctv7e[] = {
+	{ 0x40, KEY_TV },
+	{ 0x20, KEY_RADIO },		/* FM */
+	{ 0x60, KEY_EPG },
+	{ 0x00, KEY_POWER },
+
+	/* Keys 0 to 9 */
+	{ 0x44, KEY_0 },		/* 10 */
+	{ 0x50, KEY_1 },
+	{ 0x30, KEY_2 },
+	{ 0x70, KEY_3 },
+	{ 0x48, KEY_4 },
+	{ 0x28, KEY_5 },
+	{ 0x68, KEY_6 },
+	{ 0x58, KEY_7 },
+	{ 0x38, KEY_8 },
+	{ 0x78, KEY_9 },
+
+	{ 0x10, KEY_L },		/* Live */
+	{ 0x08, KEY_TIME },		/* Time Shift */
+
+	{ 0x18, KEY_PLAYPAUSE },	/* Play */
+
+	{ 0x24, KEY_ENTER },		/* 11 */
+	{ 0x64, KEY_ESC },		/* 12 */
+	{ 0x04, KEY_M },		/* Multi */
+
+	{ 0x54, KEY_VIDEO },
+	{ 0x34, KEY_CHANNELUP },
+	{ 0x74, KEY_VOLUMEUP },
+	{ 0x14, KEY_MUTE },
+
+	{ 0x4c, KEY_VCR },		/* SVIDEO */
+	{ 0x2c, KEY_CHANNELDOWN },
+	{ 0x6c, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_ZOOM },
+
+	{ 0x5c, KEY_PAUSE },
+	{ 0x3c, KEY_RED },		/* || (red) */
+	{ 0x7c, KEY_RECORD },		/* recording */
+	{ 0x1c, KEY_STOP },
+
+	{ 0x41, KEY_REWIND },		/* backward << */
+	{ 0x21, KEY_PLAY },
+	{ 0x61, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x01, KEY_NEXT },		/* skip >| */
+};
+
+struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
+	.scan = ir_codes_iodata_bctv7e,
+	.size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
+};
+EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* ADS Tech Instant TV DVB-T PCI Remote */
+static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
+	/* Keys 0 to 9 */
+	{ 0x4d, KEY_0 },
+	{ 0x57, KEY_1 },
+	{ 0x4f, KEY_2 },
+	{ 0x53, KEY_3 },
+	{ 0x56, KEY_4 },
+	{ 0x4e, KEY_5 },
+	{ 0x5e, KEY_6 },
+	{ 0x54, KEY_7 },
+	{ 0x4c, KEY_8 },
+	{ 0x5c, KEY_9 },
+
+	{ 0x5b, KEY_POWER },
+	{ 0x5f, KEY_MUTE },
+	{ 0x55, KEY_GOTO },
+	{ 0x5d, KEY_SEARCH },
+	{ 0x17, KEY_EPG },		/* Guide */
+	{ 0x1f, KEY_MENU },
+	{ 0x0f, KEY_UP },
+	{ 0x46, KEY_DOWN },
+	{ 0x16, KEY_LEFT },
+	{ 0x1e, KEY_RIGHT },
+	{ 0x0e, KEY_SELECT },		/* Enter */
+	{ 0x5a, KEY_INFO },
+	{ 0x52, KEY_EXIT },
+	{ 0x59, KEY_PREVIOUS },
+	{ 0x51, KEY_NEXT },
+	{ 0x58, KEY_REWIND },
+	{ 0x50, KEY_FORWARD },
+	{ 0x44, KEY_PLAYPAUSE },
+	{ 0x07, KEY_STOP },
+	{ 0x1b, KEY_RECORD },
+	{ 0x13, KEY_TUNER },		/* Live */
+	{ 0x0a, KEY_A },
+	{ 0x12, KEY_B },
+	{ 0x03, KEY_PROG1 },		/* 1 */
+	{ 0x01, KEY_PROG2 },		/* 2 */
+	{ 0x00, KEY_PROG3 },		/* 3 */
+	{ 0x06, KEY_DVD },
+	{ 0x48, KEY_AUX },		/* Photo */
+	{ 0x40, KEY_VIDEO },
+	{ 0x19, KEY_AUDIO },		/* Music */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x08, KEY_CHANNELDOWN },
+	{ 0x15, KEY_VOLUMEUP },
+	{ 0x1c, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
+	.scan = ir_codes_adstech_dvb_t_pci,
+	.size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
+};
+EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* MSI TV@nywhere MASTER remote */
+
+static struct ir_scancode ir_codes_msi_tvanywhere[] = {
+	/* Keys 0 to 9 */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0c, KEY_MUTE },
+	{ 0x0f, KEY_SCREEN },		/* Full Screen */
+	{ 0x10, KEY_FN },		/* Funtion */
+	{ 0x11, KEY_TIME },		/* Time shift */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_MEDIA },		/* MTS */
+	{ 0x14, KEY_SLOW },
+	{ 0x16, KEY_REWIND },		/* backward << */
+	{ 0x17, KEY_ENTER },		/* Return */
+	{ 0x18, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
+	.scan = ir_codes_msi_tvanywhere,
+	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
+};
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
+
+/* ---------------------------------------------------------------------- */
+
+/*
+  Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
+  is marked "KS003". The controller is I2C at address 0x30, but does not seem
+  to respond to probes until a read is performed from a valid device.
+  I don't know why...
+
+  Note: This remote may be of similar or identical design to the
+  Pixelview remote (?).  The raw codes and duplicate button codes
+  appear to be the same.
+
+  Henry Wong <henry@stuffedcow.net>
+  Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
+
+*/
+
+static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
+
+/*  ---- Remote Button Layout ----
+
+    POWER   SOURCE  SCAN    MUTE
+    TV/FM   1       2       3
+    |>      4       5       6
+    <|      7       8       9
+    ^^UP    0       +       RECALL
+    vvDN    RECORD  STOP    PLAY
+
+	MINIMIZE          ZOOM
+
+		  CH+
+      VOL-                   VOL+
+		  CH-
+
+	SNAPSHOT           MTS
+
+     <<      FUNC    >>     RESET
+*/
+
+	{ 0x01, KEY_1 },		/* 1 */
+	{ 0x0b, KEY_2 },		/* 2 */
+	{ 0x1b, KEY_3 },		/* 3 */
+	{ 0x05, KEY_4 },		/* 4 */
+	{ 0x09, KEY_5 },		/* 5 */
+	{ 0x15, KEY_6 },		/* 6 */
+	{ 0x06, KEY_7 },		/* 7 */
+	{ 0x0a, KEY_8 },		/* 8 */
+	{ 0x12, KEY_9 },		/* 9 */
+	{ 0x02, KEY_0 },		/* 0 */
+	{ 0x10, KEY_KPPLUS },		/* + */
+	{ 0x13, KEY_AGAIN },		/* Recall */
+
+	{ 0x1e, KEY_POWER },		/* Power */
+	{ 0x07, KEY_TUNER },		/* Source */
+	{ 0x1c, KEY_SEARCH },		/* Scan */
+	{ 0x18, KEY_MUTE },		/* Mute */
+
+	{ 0x03, KEY_RADIO },		/* TV/FM */
+	/* The next four keys are duplicates that appear to send the
+	   same IR code as Ch+, Ch-, >>, and << .  The raw code assigned
+	   to them is the actual code + 0x20 - they will never be
+	   detected as such unless some way is discovered to distinguish
+	   these buttons from those that have the same code. */
+	{ 0x3f, KEY_RIGHT },		/* |> and Ch+ */
+	{ 0x37, KEY_LEFT },		/* <| and Ch- */
+	{ 0x2c, KEY_UP },		/* ^^Up and >> */
+	{ 0x24, KEY_DOWN },		/* vvDn and << */
+
+	{ 0x00, KEY_RECORD },		/* Record */
+	{ 0x08, KEY_STOP },		/* Stop */
+	{ 0x11, KEY_PLAY },		/* Play */
+
+	{ 0x0f, KEY_CLOSE },		/* Minimize */
+	{ 0x19, KEY_ZOOM },		/* Zoom */
+	{ 0x1a, KEY_CAMERA },		/* Snapshot */
+	{ 0x0d, KEY_LANGUAGE },		/* MTS */
+
+	{ 0x14, KEY_VOLUMEDOWN },	/* Vol- */
+	{ 0x16, KEY_VOLUMEUP },		/* Vol+ */
+	{ 0x17, KEY_CHANNELDOWN },	/* Ch- */
+	{ 0x1f, KEY_CHANNELUP },	/* Ch+ */
+
+	{ 0x04, KEY_REWIND },		/* << */
+	{ 0x0e, KEY_MENU },		/* Function */
+	{ 0x0c, KEY_FASTFORWARD },	/* >> */
+	{ 0x1d, KEY_RESTART },		/* Reset */
+};
+
+struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
+	.scan = ir_codes_msi_tvanywhere_plus,
+	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
+};
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* Cinergy 1400 DVB-T */
+static struct ir_scancode ir_codes_cinergy_1400[] = {
+	{ 0x01, KEY_POWER },
+	{ 0x02, KEY_1 },
+	{ 0x03, KEY_2 },
+	{ 0x04, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x06, KEY_5 },
+	{ 0x07, KEY_6 },
+	{ 0x08, KEY_7 },
+	{ 0x09, KEY_8 },
+	{ 0x0a, KEY_9 },
+	{ 0x0c, KEY_0 },
+
+	{ 0x0b, KEY_VIDEO },
+	{ 0x0d, KEY_REFRESH },
+	{ 0x0e, KEY_SELECT },
+	{ 0x0f, KEY_EPG },
+	{ 0x10, KEY_UP },
+	{ 0x11, KEY_LEFT },
+	{ 0x12, KEY_OK },
+	{ 0x13, KEY_RIGHT },
+	{ 0x14, KEY_DOWN },
+	{ 0x15, KEY_TEXT },
+	{ 0x16, KEY_INFO },
+
+	{ 0x17, KEY_RED },
+	{ 0x18, KEY_GREEN },
+	{ 0x19, KEY_YELLOW },
+	{ 0x1a, KEY_BLUE },
+
+	{ 0x1b, KEY_CHANNELUP },
+	{ 0x1c, KEY_VOLUMEUP },
+	{ 0x1d, KEY_MUTE },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_CHANNELDOWN },
+
+	{ 0x40, KEY_PAUSE },
+	{ 0x4c, KEY_PLAY },
+	{ 0x58, KEY_RECORD },
+	{ 0x54, KEY_PREVIOUS },
+	{ 0x48, KEY_STOP },
+	{ 0x5c, KEY_NEXT },
+};
+
+struct ir_scancode_table ir_codes_cinergy_1400_table = {
+	.scan = ir_codes_cinergy_1400,
+	.size = ARRAY_SIZE(ir_codes_cinergy_1400),
+};
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* AVERTV STUDIO 303 Remote */
+static struct ir_scancode ir_codes_avertv_303[] = {
+	{ 0x2a, KEY_1 },
+	{ 0x32, KEY_2 },
+	{ 0x3a, KEY_3 },
+	{ 0x4a, KEY_4 },
+	{ 0x52, KEY_5 },
+	{ 0x5a, KEY_6 },
+	{ 0x6a, KEY_7 },
+	{ 0x72, KEY_8 },
+	{ 0x7a, KEY_9 },
+	{ 0x0e, KEY_0 },
+
+	{ 0x02, KEY_POWER },
+	{ 0x22, KEY_VIDEO },
+	{ 0x42, KEY_AUDIO },
+	{ 0x62, KEY_ZOOM },
+	{ 0x0a, KEY_TV },
+	{ 0x12, KEY_CD },
+	{ 0x1a, KEY_TEXT },
+
+	{ 0x16, KEY_SUBTITLE },
+	{ 0x1e, KEY_REWIND },
+	{ 0x06, KEY_PRINT },
+
+	{ 0x2e, KEY_SEARCH },
+	{ 0x36, KEY_SLEEP },
+	{ 0x3e, KEY_SHUFFLE },
+	{ 0x26, KEY_MUTE },
+
+	{ 0x4e, KEY_RECORD },
+	{ 0x56, KEY_PAUSE },
+	{ 0x5e, KEY_STOP },
+	{ 0x46, KEY_PLAY },
+
+	{ 0x6e, KEY_RED },
+	{ 0x0b, KEY_GREEN },
+	{ 0x66, KEY_YELLOW },
+	{ 0x03, KEY_BLUE },
+
+	{ 0x76, KEY_LEFT },
+	{ 0x7e, KEY_RIGHT },
+	{ 0x13, KEY_DOWN },
+	{ 0x1b, KEY_UP },
+};
+
+struct ir_scancode_table ir_codes_avertv_303_table = {
+	.scan = ir_codes_avertv_303,
+	.size = ARRAY_SIZE(ir_codes_avertv_303),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
+
+/* ---------------------------------------------------------------------- */
+
+/* DigitalNow DNTV Live! DVB-T Pro Remote */
+static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
+	{ 0x16, KEY_POWER },
+	{ 0x5b, KEY_HOME },
+
+	{ 0x55, KEY_TV },		/* live tv */
+	{ 0x58, KEY_TUNER },		/* digital Radio */
+	{ 0x5a, KEY_RADIO },		/* FM radio */
+	{ 0x59, KEY_DVD },		/* dvd menu */
+	{ 0x03, KEY_1 },
+	{ 0x01, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x1d, KEY_5 },
+	{ 0x1f, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x19, KEY_8 },
+	{ 0x1b, KEY_9 },
+	{ 0x0c, KEY_CANCEL },
+	{ 0x15, KEY_0 },
+	{ 0x4a, KEY_CLEAR },
+	{ 0x13, KEY_BACK },
+	{ 0x00, KEY_TAB },
+	{ 0x4b, KEY_UP },
+	{ 0x4e, KEY_LEFT },
+	{ 0x4f, KEY_OK },
+	{ 0x52, KEY_RIGHT },
+	{ 0x51, KEY_DOWN },
+	{ 0x1e, KEY_VOLUMEUP },
+	{ 0x0a, KEY_VOLUMEDOWN },
+	{ 0x02, KEY_CHANNELDOWN },
+	{ 0x05, KEY_CHANNELUP },
+	{ 0x11, KEY_RECORD },
+	{ 0x14, KEY_PLAY },
+	{ 0x4c, KEY_PAUSE },
+	{ 0x1a, KEY_STOP },
+	{ 0x40, KEY_REWIND },
+	{ 0x12, KEY_FASTFORWARD },
+	{ 0x41, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x42, KEY_NEXTSONG },		/* skip >| */
+	{ 0x54, KEY_CAMERA },		/* capture */
+	{ 0x50, KEY_LANGUAGE },		/* sap */
+	{ 0x47, KEY_TV2 },		/* pip */
+	{ 0x4d, KEY_SCREEN },
+	{ 0x43, KEY_SUBTITLE },
+	{ 0x10, KEY_MUTE },
+	{ 0x49, KEY_AUDIO },		/* l/r */
+	{ 0x07, KEY_SLEEP },
+	{ 0x08, KEY_VIDEO },		/* a/v */
+	{ 0x0e, KEY_PREVIOUS },		/* recall */
+	{ 0x45, KEY_ZOOM },		/* zoom + */
+	{ 0x46, KEY_ANGLE },		/* zoom - */
+	{ 0x56, KEY_RED },
+	{ 0x57, KEY_GREEN },
+	{ 0x5c, KEY_YELLOW },
+	{ 0x5d, KEY_BLUE },
+};
+
+struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
+	.scan = ir_codes_dntv_live_dvbt_pro,
+	.size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
+
+static struct ir_scancode ir_codes_em_terratec[] = {
+	{ 0x01, KEY_CHANNEL },
+	{ 0x02, KEY_SELECT },
+	{ 0x03, KEY_MUTE },
+	{ 0x04, KEY_POWER },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x08, KEY_CHANNELUP },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0c, KEY_CHANNELDOWN },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_0 },
+	{ 0x12, KEY_MENU },
+	{ 0x13, KEY_PRINT },
+	{ 0x14, KEY_VOLUMEDOWN },
+	{ 0x16, KEY_PAUSE },
+	{ 0x18, KEY_RECORD },
+	{ 0x19, KEY_REWIND },
+	{ 0x1a, KEY_PLAY },
+	{ 0x1b, KEY_FORWARD },
+	{ 0x1c, KEY_BACKSPACE },
+	{ 0x1e, KEY_STOP },
+	{ 0x40, KEY_ZOOM },
+};
+
+struct ir_scancode_table ir_codes_em_terratec_table = {
+	.scan = ir_codes_em_terratec,
+	.size = ARRAY_SIZE(ir_codes_em_terratec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
+
+static struct ir_scancode ir_codes_pinnacle_grey[] = {
+	{ 0x3a, KEY_0 },
+	{ 0x31, KEY_1 },
+	{ 0x32, KEY_2 },
+	{ 0x33, KEY_3 },
+	{ 0x34, KEY_4 },
+	{ 0x35, KEY_5 },
+	{ 0x36, KEY_6 },
+	{ 0x37, KEY_7 },
+	{ 0x38, KEY_8 },
+	{ 0x39, KEY_9 },
+
+	{ 0x2f, KEY_POWER },
+
+	{ 0x2e, KEY_P },
+	{ 0x1f, KEY_L },
+	{ 0x2b, KEY_I },
+
+	{ 0x2d, KEY_SCREEN },
+	{ 0x1e, KEY_ZOOM },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x0f, KEY_VOLUMEDOWN },
+	{ 0x17, KEY_CHANNELUP },
+	{ 0x1c, KEY_CHANNELDOWN },
+	{ 0x25, KEY_INFO },
+
+	{ 0x3c, KEY_MUTE },
+
+	{ 0x3d, KEY_LEFT },
+	{ 0x3b, KEY_RIGHT },
+
+	{ 0x3f, KEY_UP },
+	{ 0x3e, KEY_DOWN },
+	{ 0x1a, KEY_ENTER },
+
+	{ 0x1d, KEY_MENU },
+	{ 0x19, KEY_AGAIN },
+	{ 0x16, KEY_PREVIOUSSONG },
+	{ 0x13, KEY_NEXTSONG },
+	{ 0x15, KEY_PAUSE },
+	{ 0x0e, KEY_REWIND },
+	{ 0x0d, KEY_PLAY },
+	{ 0x0b, KEY_STOP },
+	{ 0x07, KEY_FORWARD },
+	{ 0x27, KEY_RECORD },
+	{ 0x26, KEY_TUNER },
+	{ 0x29, KEY_TEXT },
+	{ 0x2a, KEY_MEDIA },
+	{ 0x18, KEY_EPG },
+};
+
+struct ir_scancode_table ir_codes_pinnacle_grey_table = {
+	.scan = ir_codes_pinnacle_grey,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_grey),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
+
+static struct ir_scancode ir_codes_flyvideo[] = {
+	{ 0x0f, KEY_0 },
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x08, KEY_5 },
+	{ 0x09, KEY_6 },
+	{ 0x0b, KEY_7 },
+	{ 0x0c, KEY_8 },
+	{ 0x0d, KEY_9 },
+
+	{ 0x0e, KEY_MODE },	/* Air/Cable */
+	{ 0x11, KEY_VIDEO },	/* Video */
+	{ 0x15, KEY_AUDIO },	/* Audio */
+	{ 0x00, KEY_POWER },	/* Power */
+	{ 0x18, KEY_TUNER },	/* AV Source */
+	{ 0x02, KEY_ZOOM },	/* Fullscreen */
+	{ 0x1a, KEY_LANGUAGE },	/* Stereo */
+	{ 0x1b, KEY_MUTE },	/* Mute */
+	{ 0x14, KEY_VOLUMEUP },	/* Volume + */
+	{ 0x17, KEY_VOLUMEDOWN },/* Volume - */
+	{ 0x12, KEY_CHANNELUP },/* Channel + */
+	{ 0x13, KEY_CHANNELDOWN },/* Channel - */
+	{ 0x06, KEY_AGAIN },	/* Recall */
+	{ 0x10, KEY_ENTER },	/* Enter */
+
+	{ 0x19, KEY_BACK },	/* Rewind  ( <<< ) */
+	{ 0x1f, KEY_FORWARD },	/* Forward ( >>> ) */
+	{ 0x0a, KEY_ANGLE },	/* no label, may be used as the PAUSE button */
+};
+
+struct ir_scancode_table ir_codes_flyvideo_table = {
+	.scan = ir_codes_flyvideo,
+	.size = ARRAY_SIZE(ir_codes_flyvideo),
+};
+EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
+
+static struct ir_scancode ir_codes_flydvb[] = {
+	{ 0x01, KEY_ZOOM },		/* Full Screen */
+	{ 0x00, KEY_POWER },		/* Power */
+
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x08, KEY_5 },
+	{ 0x09, KEY_6 },
+	{ 0x0b, KEY_7 },
+	{ 0x0c, KEY_8 },
+	{ 0x0d, KEY_9 },
+	{ 0x06, KEY_AGAIN },		/* Recall */
+	{ 0x0f, KEY_0 },
+	{ 0x10, KEY_MUTE },		/* Mute */
+	{ 0x02, KEY_RADIO },		/* TV/Radio */
+	{ 0x1b, KEY_LANGUAGE },		/* SAP (Second Audio Program) */
+
+	{ 0x14, KEY_VOLUMEUP },		/* VOL+ */
+	{ 0x17, KEY_VOLUMEDOWN },	/* VOL- */
+	{ 0x12, KEY_CHANNELUP },	/* CH+ */
+	{ 0x13, KEY_CHANNELDOWN },	/* CH- */
+	{ 0x1d, KEY_ENTER },		/* Enter */
+
+	{ 0x1a, KEY_MODE },		/* PIP */
+	{ 0x18, KEY_TUNER },		/* Source */
+
+	{ 0x1e, KEY_RECORD },		/* Record/Pause */
+	{ 0x15, KEY_ANGLE },		/* Swap (no label on key) */
+	{ 0x1c, KEY_PAUSE },		/* Timeshift/Pause */
+	{ 0x19, KEY_BACK },		/* Rewind << */
+	{ 0x0a, KEY_PLAYPAUSE },	/* Play/Pause */
+	{ 0x1f, KEY_FORWARD },		/* Forward >> */
+	{ 0x16, KEY_PREVIOUS },		/* Back |<< */
+	{ 0x11, KEY_STOP },		/* Stop */
+	{ 0x0e, KEY_NEXT },		/* End >>| */
+};
+
+struct ir_scancode_table ir_codes_flydvb_table = {
+	.scan = ir_codes_flydvb,
+	.size = ARRAY_SIZE(ir_codes_flydvb),
+};
+EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
+
+static struct ir_scancode ir_codes_cinergy[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_POWER },
+	{ 0x0b, KEY_PROG1 },		/* app */
+	{ 0x0c, KEY_ZOOM },		/* zoom/fullscreen */
+	{ 0x0d, KEY_CHANNELUP },	/* channel */
+	{ 0x0e, KEY_CHANNELDOWN },	/* channel- */
+	{ 0x0f, KEY_VOLUMEUP },
+	{ 0x10, KEY_VOLUMEDOWN },
+	{ 0x11, KEY_TUNER },		/* AV */
+	{ 0x12, KEY_NUMLOCK },		/* -/-- */
+	{ 0x13, KEY_AUDIO },		/* audio */
+	{ 0x14, KEY_MUTE },
+	{ 0x15, KEY_UP },
+	{ 0x16, KEY_DOWN },
+	{ 0x17, KEY_LEFT },
+	{ 0x18, KEY_RIGHT },
+	{ 0x19, BTN_LEFT, },
+	{ 0x1a, BTN_RIGHT, },
+	{ 0x1b, KEY_WWW },		/* text */
+	{ 0x1c, KEY_REWIND },
+	{ 0x1d, KEY_FORWARD },
+	{ 0x1e, KEY_RECORD },
+	{ 0x1f, KEY_PLAY },
+	{ 0x20, KEY_PREVIOUSSONG },
+	{ 0x21, KEY_NEXTSONG },
+	{ 0x22, KEY_PAUSE },
+	{ 0x23, KEY_STOP },
+};
+
+struct ir_scancode_table ir_codes_cinergy_table = {
+	.scan = ir_codes_cinergy,
+	.size = ARRAY_SIZE(ir_codes_cinergy),
+};
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
+
+/* Alfons Geser <a.geser@cox.net>
+ * updates from Job D. R. Borges <jobdrb@ig.com.br> */
+static struct ir_scancode ir_codes_eztv[] = {
+	{ 0x12, KEY_POWER },
+	{ 0x01, KEY_TV },	/* DVR */
+	{ 0x15, KEY_DVD },	/* DVD */
+	{ 0x17, KEY_AUDIO },	/* music */
+				/* DVR mode / DVD mode / music mode */
+
+	{ 0x1b, KEY_MUTE },	/* mute */
+	{ 0x02, KEY_LANGUAGE },	/* MTS/SAP / audio / autoseek */
+	{ 0x1e, KEY_SUBTITLE },	/* closed captioning / subtitle / seek */
+	{ 0x16, KEY_ZOOM },	/* full screen */
+	{ 0x1c, KEY_VIDEO },	/* video source / eject / delall */
+	{ 0x1d, KEY_RESTART },	/* playback / angle / del */
+	{ 0x2f, KEY_SEARCH },	/* scan / menu / playlist */
+	{ 0x30, KEY_CHANNEL },	/* CH surfing / bookmark / memo */
+
+	{ 0x31, KEY_HELP },	/* help */
+	{ 0x32, KEY_MODE },	/* num/memo */
+	{ 0x33, KEY_ESC },	/* cancel */
+
+	{ 0x0c, KEY_UP },	/* up */
+	{ 0x10, KEY_DOWN },	/* down */
+	{ 0x08, KEY_LEFT },	/* left */
+	{ 0x04, KEY_RIGHT },	/* right */
+	{ 0x03, KEY_SELECT },	/* select */
+
+	{ 0x1f, KEY_REWIND },	/* rewind */
+	{ 0x20, KEY_PLAYPAUSE },/* play/pause */
+	{ 0x29, KEY_FORWARD },	/* forward */
+	{ 0x14, KEY_AGAIN },	/* repeat */
+	{ 0x2b, KEY_RECORD },	/* recording */
+	{ 0x2c, KEY_STOP },	/* stop */
+	{ 0x2d, KEY_PLAY },	/* play */
+	{ 0x2e, KEY_CAMERA },	/* snapshot / shuffle */
+
+	{ 0x00, KEY_0 },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+
+	{ 0x2a, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x18, KEY_CHANNELUP },/* CH.tracking up */
+	{ 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
+
+	{ 0x13, KEY_ENTER },	/* enter */
+	{ 0x21, KEY_DOT },	/* . (decimal dot) */
+};
+
+struct ir_scancode_table ir_codes_eztv_table = {
+	.scan = ir_codes_eztv,
+	.size = ARRAY_SIZE(ir_codes_eztv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
+
+/* Alex Hermann <gaaf@gmx.net> */
+static struct ir_scancode ir_codes_avermedia[] = {
+	{ 0x28, KEY_1 },
+	{ 0x18, KEY_2 },
+	{ 0x38, KEY_3 },
+	{ 0x24, KEY_4 },
+	{ 0x14, KEY_5 },
+	{ 0x34, KEY_6 },
+	{ 0x2c, KEY_7 },
+	{ 0x1c, KEY_8 },
+	{ 0x3c, KEY_9 },
+	{ 0x22, KEY_0 },
+
+	{ 0x20, KEY_TV },		/* TV/FM */
+	{ 0x10, KEY_CD },		/* CD */
+	{ 0x30, KEY_TEXT },		/* TELETEXT */
+	{ 0x00, KEY_POWER },		/* POWER */
+
+	{ 0x08, KEY_VIDEO },		/* VIDEO */
+	{ 0x04, KEY_AUDIO },		/* AUDIO */
+	{ 0x0c, KEY_ZOOM },		/* FULL SCREEN */
+
+	{ 0x12, KEY_SUBTITLE },		/* DISPLAY */
+	{ 0x32, KEY_REWIND },		/* LOOP	*/
+	{ 0x02, KEY_PRINT },		/* PREVIEW */
+
+	{ 0x2a, KEY_SEARCH },		/* AUTOSCAN */
+	{ 0x1a, KEY_SLEEP },		/* FREEZE */
+	{ 0x3a, KEY_CAMERA },		/* SNAPSHOT */
+	{ 0x0a, KEY_MUTE },		/* MUTE */
+
+	{ 0x26, KEY_RECORD },		/* RECORD */
+	{ 0x16, KEY_PAUSE },		/* PAUSE */
+	{ 0x36, KEY_STOP },		/* STOP */
+	{ 0x06, KEY_PLAY },		/* PLAY */
+
+	{ 0x2e, KEY_RED },		/* RED */
+	{ 0x21, KEY_GREEN },		/* GREEN */
+	{ 0x0e, KEY_YELLOW },		/* YELLOW */
+	{ 0x01, KEY_BLUE },		/* BLUE */
+
+	{ 0x1e, KEY_VOLUMEDOWN },	/* VOLUME- */
+	{ 0x3e, KEY_VOLUMEUP },		/* VOLUME+ */
+	{ 0x11, KEY_CHANNELDOWN },	/* CHANNEL/PAGE- */
+	{ 0x31, KEY_CHANNELUP }		/* CHANNEL/PAGE+ */
+};
+
+struct ir_scancode_table ir_codes_avermedia_table = {
+	.scan = ir_codes_avermedia,
+	.size = ARRAY_SIZE(ir_codes_avermedia),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
+
+static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
+	{ 0x14, KEY_MUTE },
+	{ 0x24, KEY_ZOOM },
+
+	{ 0x01, KEY_DVD },
+	{ 0x23, KEY_RADIO },
+	{ 0x00, KEY_TV },
+
+	{ 0x0a, KEY_REWIND },
+	{ 0x08, KEY_PLAYPAUSE },
+	{ 0x0f, KEY_FORWARD },
+
+	{ 0x02, KEY_PREVIOUS },
+	{ 0x07, KEY_STOP },
+	{ 0x06, KEY_NEXT },
+
+	{ 0x0c, KEY_UP },
+	{ 0x0e, KEY_DOWN },
+	{ 0x0b, KEY_LEFT },
+	{ 0x0d, KEY_RIGHT },
+	{ 0x11, KEY_OK },
+
+	{ 0x03, KEY_MENU },
+	{ 0x09, KEY_SETUP },
+	{ 0x05, KEY_VIDEO },
+	{ 0x22, KEY_CHANNEL },
+
+	{ 0x12, KEY_VOLUMEUP },
+	{ 0x15, KEY_VOLUMEDOWN },
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x13, KEY_CHANNELDOWN },
+
+	{ 0x04, KEY_RECORD },
+
+	{ 0x16, KEY_1 },
+	{ 0x17, KEY_2 },
+	{ 0x18, KEY_3 },
+	{ 0x19, KEY_4 },
+	{ 0x1a, KEY_5 },
+	{ 0x1b, KEY_6 },
+	{ 0x1c, KEY_7 },
+	{ 0x1d, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x1f, KEY_0 },
+
+	{ 0x20, KEY_LANGUAGE },
+	{ 0x21, KEY_SLEEP },
+};
+
+struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
+	.scan = ir_codes_videomate_tv_pvr,
+	.size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
+};
+EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
+
+/* Michael Tokarev <mjt@tls.msk.ru>
+   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
+   keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
+   least, and probably other cards too.
+   The "ascii-art picture" below (in comments, first row
+   is the keycode in hex, and subsequent row(s) shows
+   the button labels (several variants when appropriate)
+   helps to descide which keycodes to assign to the buttons.
+ */
+static struct ir_scancode ir_codes_manli[] = {
+
+	/*  0x1c            0x12  *
+	 * FUNCTION         POWER *
+	 *   FM              (|)  *
+	 *                        */
+	{ 0x1c, KEY_RADIO },	/*XXX*/
+	{ 0x12, KEY_POWER },
+
+	/*  0x01    0x02    0x03  *
+	 *   1       2       3    *
+	 *                        *
+	 *  0x04    0x05    0x06  *
+	 *   4       5       6    *
+	 *                        *
+	 *  0x07    0x08    0x09  *
+	 *   7       8       9    *
+	 *                        */
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	/*  0x0a    0x00    0x17  *
+	 * RECALL    0      +100  *
+	 *                  PLUS  *
+	 *                        */
+	{ 0x0a, KEY_AGAIN },	/*XXX KEY_REWIND? */
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_DIGITS },	/*XXX*/
+
+	/*  0x14            0x10  *
+	 *  MENU            INFO  *
+	 *  OSD                   */
+	{ 0x14, KEY_MENU },
+	{ 0x10, KEY_INFO },
+
+	/*          0x0b          *
+	 *           Up           *
+	 *                        *
+	 *  0x18    0x16    0x0c  *
+	 *  Left     Ok     Right *
+	 *                        *
+	 *         0x015          *
+	 *         Down           *
+	 *                        */
+	{ 0x0b, KEY_UP },
+	{ 0x18, KEY_LEFT },
+	{ 0x16, KEY_OK },	/*XXX KEY_SELECT? KEY_ENTER? */
+	{ 0x0c, KEY_RIGHT },
+	{ 0x15, KEY_DOWN },
+
+	/*  0x11            0x0d  *
+	 *  TV/AV           MODE  *
+	 *  SOURCE         STEREO *
+	 *                        */
+	{ 0x11, KEY_TV },	/*XXX*/
+	{ 0x0d, KEY_MODE },	/*XXX there's no KEY_STEREO	*/
+
+	/*  0x0f    0x1b    0x1a  *
+	 *  AUDIO   Vol+    Chan+ *
+	 *        TIMESHIFT???    *
+	 *                        *
+	 *  0x0e    0x1f    0x1e  *
+	 *  SLEEP   Vol-    Chan- *
+	 *                        */
+	{ 0x0f, KEY_AUDIO },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x0e, KEY_TIME },
+	{ 0x1f, KEY_VOLUMEDOWN },
+	{ 0x1e, KEY_CHANNELDOWN },
+
+	/*         0x13     0x19  *
+	 *         MUTE   SNAPSHOT*
+	 *                        */
+	{ 0x13, KEY_MUTE },
+	{ 0x19, KEY_CAMERA },
+
+	/* 0x1d unused ? */
+};
+
+struct ir_scancode_table ir_codes_manli_table = {
+	.scan = ir_codes_manli,
+	.size = ARRAY_SIZE(ir_codes_manli),
+};
+EXPORT_SYMBOL_GPL(ir_codes_manli_table);
+
+/* Mike Baikov <mike@baikov.com> */
+static struct ir_scancode ir_codes_gotview7135[] = {
+
+	{ 0x11, KEY_POWER },
+	{ 0x35, KEY_TV },
+	{ 0x1b, KEY_0 },
+	{ 0x29, KEY_1 },
+	{ 0x19, KEY_2 },
+	{ 0x39, KEY_3 },
+	{ 0x1f, KEY_4 },
+	{ 0x2c, KEY_5 },
+	{ 0x21, KEY_6 },
+	{ 0x24, KEY_7 },
+	{ 0x18, KEY_8 },
+	{ 0x2b, KEY_9 },
+	{ 0x3b, KEY_AGAIN },	/* LOOP */
+	{ 0x06, KEY_AUDIO },
+	{ 0x31, KEY_PRINT },	/* PREVIEW */
+	{ 0x3e, KEY_VIDEO },
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x20, KEY_CHANNELDOWN },
+	{ 0x0c, KEY_VOLUMEDOWN },
+	{ 0x28, KEY_VOLUMEUP },
+	{ 0x08, KEY_MUTE },
+	{ 0x26, KEY_SEARCH },	/* SCAN */
+	{ 0x3f, KEY_CAMERA },	/* SNAPSHOT */
+	{ 0x12, KEY_RECORD },
+	{ 0x32, KEY_STOP },
+	{ 0x3c, KEY_PLAY },
+	{ 0x1d, KEY_REWIND },
+	{ 0x2d, KEY_PAUSE },
+	{ 0x0d, KEY_FORWARD },
+	{ 0x05, KEY_ZOOM },	/*FULL*/
+
+	{ 0x2a, KEY_F21 },	/* LIVE TIMESHIFT */
+	{ 0x0e, KEY_F22 },	/* MIN TIMESHIFT */
+	{ 0x1e, KEY_TIME },	/* TIMESHIFT */
+	{ 0x38, KEY_F24 },	/* NORMAL TIMESHIFT */
+};
+
+struct ir_scancode_table ir_codes_gotview7135_table = {
+	.scan = ir_codes_gotview7135,
+	.size = ARRAY_SIZE(ir_codes_gotview7135),
+};
+EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
+
+static struct ir_scancode ir_codes_purpletv[] = {
+	{ 0x03, KEY_POWER },
+	{ 0x6f, KEY_MUTE },
+	{ 0x10, KEY_BACKSPACE },	/* Recall */
+
+	{ 0x11, KEY_0 },
+	{ 0x04, KEY_1 },
+	{ 0x05, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x08, KEY_4 },
+	{ 0x09, KEY_5 },
+	{ 0x0a, KEY_6 },
+	{ 0x0c, KEY_7 },
+	{ 0x0d, KEY_8 },
+	{ 0x0e, KEY_9 },
+	{ 0x12, KEY_DOT },	/* 100+ */
+
+	{ 0x07, KEY_VOLUMEUP },
+	{ 0x0b, KEY_VOLUMEDOWN },
+	{ 0x1a, KEY_KPPLUS },
+	{ 0x18, KEY_KPMINUS },
+	{ 0x15, KEY_UP },
+	{ 0x1d, KEY_DOWN },
+	{ 0x0f, KEY_CHANNELUP },
+	{ 0x13, KEY_CHANNELDOWN },
+	{ 0x48, KEY_ZOOM },
+
+	{ 0x1b, KEY_VIDEO },	/* Video source */
+	{ 0x1f, KEY_CAMERA },	/* Snapshot */
+	{ 0x49, KEY_LANGUAGE },	/* MTS Select */
+	{ 0x19, KEY_SEARCH },	/* Auto Scan */
+
+	{ 0x4b, KEY_RECORD },
+	{ 0x46, KEY_PLAY },
+	{ 0x45, KEY_PAUSE },	/* Pause */
+	{ 0x44, KEY_STOP },
+	{ 0x43, KEY_TIME },	/* Time Shift */
+	{ 0x17, KEY_CHANNEL },	/* SURF CH */
+	{ 0x40, KEY_FORWARD },	/* Forward ? */
+	{ 0x42, KEY_REWIND },	/* Backward ? */
+
+};
+
+struct ir_scancode_table ir_codes_purpletv_table = {
+	.scan = ir_codes_purpletv,
+	.size = ARRAY_SIZE(ir_codes_purpletv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
+
+/* Mapping for the 28 key remote control as seen at
+   http://www.sednacomputer.com/photo/cardbus-tv.jpg
+   Pavel Mihaylov <bin@bash.info>
+   Also for the remote bundled with Kozumi KTV-01C card */
+static struct ir_scancode ir_codes_pctv_sedna[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_AGAIN },	/* Recall */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x0c, KEY_VOLUMEUP },
+	{ 0x0d, KEY_MODE },	/* Stereo */
+	{ 0x0e, KEY_STOP },
+	{ 0x0f, KEY_PREVIOUSSONG },
+	{ 0x10, KEY_ZOOM },
+	{ 0x11, KEY_TUNER },	/* Source */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_MUTE },
+	{ 0x15, KEY_CHANNELDOWN },
+	{ 0x18, KEY_VOLUMEDOWN },
+	{ 0x19, KEY_CAMERA },	/* Snapshot */
+	{ 0x1a, KEY_NEXTSONG },
+	{ 0x1b, KEY_TIME },	/* Time Shift */
+	{ 0x1c, KEY_RADIO },	/* FM Radio */
+	{ 0x1d, KEY_RECORD },
+	{ 0x1e, KEY_PAUSE },
+	/* additional codes for Kozumi's remote */
+	{ 0x14, KEY_INFO },	/* OSD */
+	{ 0x16, KEY_OK },	/* OK */
+	{ 0x17, KEY_DIGITS },	/* Plus */
+	{ 0x1f, KEY_PLAY },	/* Play */
+};
+
+struct ir_scancode_table ir_codes_pctv_sedna_table = {
+	.scan = ir_codes_pctv_sedna,
+	.size = ARRAY_SIZE(ir_codes_pctv_sedna),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
+
+/* Mark Phalan <phalanm@o2.ie> */
+static struct ir_scancode ir_codes_pv951[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x12, KEY_POWER },
+	{ 0x10, KEY_MUTE },
+	{ 0x1f, KEY_VOLUMEDOWN },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x0e, KEY_PAGEUP },
+	{ 0x1d, KEY_PAGEDOWN },
+	{ 0x13, KEY_SOUND },
+
+	{ 0x18, KEY_KPPLUSMINUS },	/* CH +/- */
+	{ 0x16, KEY_SUBTITLE },		/* CC */
+	{ 0x0d, KEY_TEXT },		/* TTX */
+	{ 0x0b, KEY_TV },		/* AIR/CBL */
+	{ 0x11, KEY_PC },		/* PC/TV */
+	{ 0x17, KEY_OK },		/* CH RTN */
+	{ 0x19, KEY_MODE },		/* FUNC */
+	{ 0x0c, KEY_SEARCH },		/* AUTOSCAN */
+
+	/* Not sure what to do with these ones! */
+	{ 0x0f, KEY_SELECT },		/* SOURCE */
+	{ 0x0a, KEY_KPPLUS },		/* +100 */
+	{ 0x14, KEY_EQUAL },		/* SYNC */
+	{ 0x1c, KEY_MEDIA },		/* PC/TV */
+};
+
+struct ir_scancode_table ir_codes_pv951_table = {
+	.scan = ir_codes_pv951,
+	.size = ARRAY_SIZE(ir_codes_pv951),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
+
+/* generic RC5 keytable                                          */
+/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
+/* used by old (black) Hauppauge remotes                         */
+static struct ir_scancode ir_codes_rc5_tv[] = {
+	/* Keys 0 to 9 */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0b, KEY_CHANNEL },		/* channel / program (japan: 11) */
+	{ 0x0c, KEY_POWER },		/* standby */
+	{ 0x0d, KEY_MUTE },		/* mute / demute */
+	{ 0x0f, KEY_TV },		/* display */
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x12, KEY_BRIGHTNESSUP },
+	{ 0x13, KEY_BRIGHTNESSDOWN },
+	{ 0x1e, KEY_SEARCH },		/* search + */
+	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x22, KEY_CHANNEL },		/* alt / channel */
+	{ 0x23, KEY_LANGUAGE },		/* 1st / 2nd language */
+	{ 0x26, KEY_SLEEP },		/* sleeptimer */
+	{ 0x2e, KEY_MENU },		/* 2nd controls (USA: menu) */
+	{ 0x30, KEY_PAUSE },
+	{ 0x32, KEY_REWIND },
+	{ 0x33, KEY_GOTO },
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },		/* recording */
+	{ 0x3c, KEY_TEXT },		/* teletext submode (Japan: 12) */
+	{ 0x3d, KEY_SUSPEND },		/* system standby */
+
+};
+
+struct ir_scancode_table ir_codes_rc5_tv_table = {
+	.scan = ir_codes_rc5_tv,
+	.size = ARRAY_SIZE(ir_codes_rc5_tv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
+
+/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
+static struct ir_scancode ir_codes_winfast[] = {
+	/* Keys 0 to 9 */
+	{ 0x12, KEY_0 },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+
+	{ 0x00, KEY_POWER },
+	{ 0x1b, KEY_AUDIO },		/* Audio Source */
+	{ 0x02, KEY_TUNER },		/* TV/FM, not on Y0400052 */
+	{ 0x1e, KEY_VIDEO },		/* Video Source */
+	{ 0x16, KEY_INFO },		/* Display information */
+	{ 0x04, KEY_VOLUMEUP },
+	{ 0x08, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_CHANNELUP },
+	{ 0x10, KEY_CHANNELDOWN },
+	{ 0x03, KEY_ZOOM },		/* fullscreen */
+	{ 0x1f, KEY_TEXT },		/* closed caption/teletext */
+	{ 0x20, KEY_SLEEP },
+	{ 0x29, KEY_CLEAR },		/* boss key */
+	{ 0x14, KEY_MUTE },
+	{ 0x2b, KEY_RED },
+	{ 0x2c, KEY_GREEN },
+	{ 0x2d, KEY_YELLOW },
+	{ 0x2e, KEY_BLUE },
+	{ 0x18, KEY_KPPLUS },		/* fine tune + , not on Y040052 */
+	{ 0x19, KEY_KPMINUS },		/* fine tune - , not on Y040052 */
+	{ 0x2a, KEY_MEDIA },		/* PIP (Picture in picture */
+	{ 0x21, KEY_DOT },
+	{ 0x13, KEY_ENTER },
+	{ 0x11, KEY_LAST },		/* Recall (last channel */
+	{ 0x22, KEY_PREVIOUS },
+	{ 0x23, KEY_PLAYPAUSE },
+	{ 0x24, KEY_NEXT },
+	{ 0x25, KEY_TIME },		/* Time Shifting */
+	{ 0x26, KEY_STOP },
+	{ 0x27, KEY_RECORD },
+	{ 0x28, KEY_SAVE },		/* Screenshot */
+	{ 0x2f, KEY_MENU },
+	{ 0x30, KEY_CANCEL },
+	{ 0x31, KEY_CHANNEL },		/* Channel Surf */
+	{ 0x32, KEY_SUBTITLE },
+	{ 0x33, KEY_LANGUAGE },
+	{ 0x34, KEY_REWIND },
+	{ 0x35, KEY_FASTFORWARD },
+	{ 0x36, KEY_TV },
+	{ 0x37, KEY_RADIO },		/* FM */
+	{ 0x38, KEY_DVD },
+
+	{ 0x1a, KEY_MODE},		/* change to MCE mode on Y04G0051 */
+	{ 0x3e, KEY_F21 },		/* MCE +VOL, on Y04G0033 */
+	{ 0x3a, KEY_F22 },		/* MCE -VOL, on Y04G0033 */
+	{ 0x3b, KEY_F23 },		/* MCE +CH,  on Y04G0033 */
+	{ 0x3f, KEY_F24 }		/* MCE -CH,  on Y04G0033 */
+};
+
+struct ir_scancode_table ir_codes_winfast_table = {
+	.scan = ir_codes_winfast,
+	.size = ARRAY_SIZE(ir_codes_winfast),
+};
+EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
+
+static struct ir_scancode ir_codes_pinnacle_color[] = {
+	{ 0x59, KEY_MUTE },
+	{ 0x4a, KEY_POWER },
+
+	{ 0x18, KEY_TEXT },
+	{ 0x26, KEY_TV },
+	{ 0x3d, KEY_PRINT },
+
+	{ 0x48, KEY_RED },
+	{ 0x04, KEY_GREEN },
+	{ 0x11, KEY_YELLOW },
+	{ 0x00, KEY_BLUE },
+
+	{ 0x2d, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+
+	{ 0x49, KEY_MENU },
+
+	{ 0x16, KEY_CHANNELUP },
+	{ 0x17, KEY_CHANNELDOWN },
+
+	{ 0x20, KEY_UP },
+	{ 0x21, KEY_DOWN },
+	{ 0x22, KEY_LEFT },
+	{ 0x23, KEY_RIGHT },
+	{ 0x0d, KEY_SELECT },
+
+	{ 0x08, KEY_BACK },
+	{ 0x07, KEY_REFRESH },
+
+	{ 0x2f, KEY_ZOOM },
+	{ 0x29, KEY_RECORD },
+
+	{ 0x4b, KEY_PAUSE },
+	{ 0x4d, KEY_REWIND },
+	{ 0x2e, KEY_PLAY },
+	{ 0x4e, KEY_FORWARD },
+	{ 0x53, KEY_PREVIOUS },
+	{ 0x4c, KEY_STOP },
+	{ 0x54, KEY_NEXT },
+
+	{ 0x69, KEY_0 },
+	{ 0x6a, KEY_1 },
+	{ 0x6b, KEY_2 },
+	{ 0x6c, KEY_3 },
+	{ 0x6d, KEY_4 },
+	{ 0x6e, KEY_5 },
+	{ 0x6f, KEY_6 },
+	{ 0x70, KEY_7 },
+	{ 0x71, KEY_8 },
+	{ 0x72, KEY_9 },
+
+	{ 0x74, KEY_CHANNEL },
+	{ 0x0a, KEY_BACKSPACE },
+};
+
+struct ir_scancode_table ir_codes_pinnacle_color_table = {
+	.scan = ir_codes_pinnacle_color,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_color),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
+
+/* Hauppauge: the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ * almost rc5 coding, but some non-standard keys */
+static struct ir_scancode ir_codes_hauppauge_new[] = {
+	/* Keys 0 to 9 */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_TEXT },		/* keypad asterisk as well */
+	{ 0x0b, KEY_RED },		/* red button */
+	{ 0x0c, KEY_RADIO },
+	{ 0x0d, KEY_MENU },
+	{ 0x0e, KEY_SUBTITLE },		/* also the # key */
+	{ 0x0f, KEY_MUTE },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x12, KEY_PREVIOUS },		/* previous channel */
+	{ 0x14, KEY_UP },
+	{ 0x15, KEY_DOWN },
+	{ 0x16, KEY_LEFT },
+	{ 0x17, KEY_RIGHT },
+	{ 0x18, KEY_VIDEO },		/* Videos */
+	{ 0x19, KEY_AUDIO },		/* Music */
+	/* 0x1a: Pictures - presume this means
+	   "Multimedia Home Platform" -
+	   no "PICTURES" key in input.h
+	 */
+	{ 0x1a, KEY_MHP },
+
+	{ 0x1b, KEY_EPG },		/* Guide */
+	{ 0x1c, KEY_TV },
+	{ 0x1e, KEY_NEXTSONG },		/* skip >| */
+	{ 0x1f, KEY_EXIT },		/* back/exit */
+	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x22, KEY_CHANNEL },		/* source (old black remote) */
+	{ 0x24, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x25, KEY_ENTER },		/* OK */
+	{ 0x26, KEY_SLEEP },		/* minimize (old black remote) */
+	{ 0x29, KEY_BLUE },		/* blue key */
+	{ 0x2e, KEY_GREEN },		/* green button */
+	{ 0x30, KEY_PAUSE },		/* pause */
+	{ 0x32, KEY_REWIND },		/* backward << */
+	{ 0x34, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },		/* recording */
+	{ 0x38, KEY_YELLOW },		/* yellow key */
+	{ 0x3b, KEY_SELECT },		/* top right button */
+	{ 0x3c, KEY_ZOOM },		/* full */
+	{ 0x3d, KEY_POWER },		/* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_hauppauge_new_table = {
+	.scan = ir_codes_hauppauge_new,
+	.size = ARRAY_SIZE(ir_codes_hauppauge_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
+
+static struct ir_scancode ir_codes_npgtech[] = {
+	{ 0x1d, KEY_SWITCHVIDEOMODE },	/* switch inputs */
+	{ 0x2a, KEY_FRONT },
+
+	{ 0x3e, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x0a, KEY_4 },
+	{ 0x0e, KEY_5 },
+	{ 0x12, KEY_6 },
+	{ 0x16, KEY_7 },
+	{ 0x1a, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x3a, KEY_0 },
+	{ 0x22, KEY_NUMLOCK },		/* -/-- */
+	{ 0x20, KEY_REFRESH },
+
+	{ 0x03, KEY_BRIGHTNESSDOWN },
+	{ 0x28, KEY_AUDIO },
+	{ 0x3c, KEY_CHANNELUP },
+	{ 0x3f, KEY_VOLUMEDOWN },
+	{ 0x2e, KEY_MUTE },
+	{ 0x3b, KEY_VOLUMEUP },
+	{ 0x00, KEY_CHANNELDOWN },
+	{ 0x07, KEY_BRIGHTNESSUP },
+	{ 0x2c, KEY_TEXT },
+
+	{ 0x37, KEY_RECORD },
+	{ 0x17, KEY_PLAY },
+	{ 0x13, KEY_PAUSE },
+	{ 0x26, KEY_STOP },
+	{ 0x18, KEY_FASTFORWARD },
+	{ 0x14, KEY_REWIND },
+	{ 0x33, KEY_ZOOM },
+	{ 0x32, KEY_KEYBOARD },
+	{ 0x30, KEY_GOTO },		/* Pointing arrow */
+	{ 0x36, KEY_MACRO },		/* Maximize/Minimize (yellow) */
+	{ 0x0b, KEY_RADIO },
+	{ 0x10, KEY_POWER },
+
+};
+
+struct ir_scancode_table ir_codes_npgtech_table = {
+	.scan = ir_codes_npgtech,
+	.size = ARRAY_SIZE(ir_codes_npgtech),
+};
+EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
+
+/* Norwood Micro (non-Pro) TV Tuner
+   By Peter Naulls <peter@chocky.org>
+   Key comments are the functions given in the manual */
+static struct ir_scancode ir_codes_norwood[] = {
+	/* Keys 0 to 9 */
+	{ 0x20, KEY_0 },
+	{ 0x21, KEY_1 },
+	{ 0x22, KEY_2 },
+	{ 0x23, KEY_3 },
+	{ 0x24, KEY_4 },
+	{ 0x25, KEY_5 },
+	{ 0x26, KEY_6 },
+	{ 0x27, KEY_7 },
+	{ 0x28, KEY_8 },
+	{ 0x29, KEY_9 },
+
+	{ 0x78, KEY_TUNER },		/* Video Source        */
+	{ 0x2c, KEY_EXIT },		/* Open/Close software */
+	{ 0x2a, KEY_SELECT },		/* 2 Digit Select      */
+	{ 0x69, KEY_AGAIN },		/* Recall              */
+
+	{ 0x32, KEY_BRIGHTNESSUP },	/* Brightness increase */
+	{ 0x33, KEY_BRIGHTNESSDOWN },	/* Brightness decrease */
+	{ 0x6b, KEY_KPPLUS },		/* (not named >>>>>)   */
+	{ 0x6c, KEY_KPMINUS },		/* (not named <<<<<)   */
+
+	{ 0x2d, KEY_MUTE },		/* Mute                */
+	{ 0x30, KEY_VOLUMEUP },		/* Volume up           */
+	{ 0x31, KEY_VOLUMEDOWN },	/* Volume down         */
+	{ 0x60, KEY_CHANNELUP },	/* Channel up          */
+	{ 0x61, KEY_CHANNELDOWN },	/* Channel down        */
+
+	{ 0x3f, KEY_RECORD },		/* Record              */
+	{ 0x37, KEY_PLAY },		/* Play                */
+	{ 0x36, KEY_PAUSE },		/* Pause               */
+	{ 0x2b, KEY_STOP },		/* Stop                */
+	{ 0x67, KEY_FASTFORWARD },	/* Foward              */
+	{ 0x66, KEY_REWIND },		/* Rewind              */
+	{ 0x3e, KEY_SEARCH },		/* Auto Scan           */
+	{ 0x2e, KEY_CAMERA },		/* Capture Video       */
+	{ 0x6d, KEY_MENU },		/* Show/Hide Control   */
+	{ 0x2f, KEY_ZOOM },		/* Full Screen         */
+	{ 0x34, KEY_RADIO },		/* FM                  */
+	{ 0x65, KEY_POWER },		/* Computer power      */
+};
+
+struct ir_scancode_table ir_codes_norwood_table = {
+	.scan = ir_codes_norwood,
+	.size = ARRAY_SIZE(ir_codes_norwood),
+};
+EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
+
+/* From reading the following remotes:
+ * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
+ * Hauppauge (from NOVA-CI-s box product)
+ * This is a "middle of the road" approach, differences are noted
+ */
+static struct ir_scancode ir_codes_budget_ci_old[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_ENTER },
+	{ 0x0b, KEY_RED },
+	{ 0x0c, KEY_POWER },		/* RADIO on Hauppauge */
+	{ 0x0d, KEY_MUTE },
+	{ 0x0f, KEY_A },		/* TV on Hauppauge */
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x14, KEY_B },
+	{ 0x1c, KEY_UP },
+	{ 0x1d, KEY_DOWN },
+	{ 0x1e, KEY_OPTION },		/* RESERVED on Hauppauge */
+	{ 0x1f, KEY_BREAK },
+	{ 0x20, KEY_CHANNELUP },
+	{ 0x21, KEY_CHANNELDOWN },
+	{ 0x22, KEY_PREVIOUS },		/* Prev Ch on Zenith, SOURCE on Hauppauge */
+	{ 0x24, KEY_RESTART },
+	{ 0x25, KEY_OK },
+	{ 0x26, KEY_CYCLEWINDOWS },	/* MINIMIZE on Hauppauge */
+	{ 0x28, KEY_ENTER },		/* VCR mode on Zenith */
+	{ 0x29, KEY_PAUSE },
+	{ 0x2b, KEY_RIGHT },
+	{ 0x2c, KEY_LEFT },
+	{ 0x2e, KEY_MENU },		/* FULL SCREEN on Hauppauge */
+	{ 0x30, KEY_SLOW },
+	{ 0x31, KEY_PREVIOUS },		/* VCR mode on Zenith */
+	{ 0x32, KEY_REWIND },
+	{ 0x34, KEY_FASTFORWARD },
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },
+	{ 0x38, KEY_TUNER },		/* TV/VCR on Zenith */
+	{ 0x3a, KEY_C },
+	{ 0x3c, KEY_EXIT },
+	{ 0x3d, KEY_POWER2 },
+	{ 0x3e, KEY_TUNER },
+};
+
+struct ir_scancode_table ir_codes_budget_ci_old_table = {
+	.scan = ir_codes_budget_ci_old,
+	.size = ARRAY_SIZE(ir_codes_budget_ci_old),
+};
+EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
+
+/*
+ * Marc Fargas <telenieko@telenieko.com>
+ * this is the remote control that comes with the asus p7131
+ * which has a label saying is "Model PC-39"
+ */
+static struct ir_scancode ir_codes_asus_pc39[] = {
+	/* Keys 0 to 9 */
+	{ 0x15, KEY_0 },
+	{ 0x29, KEY_1 },
+	{ 0x2d, KEY_2 },
+	{ 0x2b, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0d, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x31, KEY_7 },
+	{ 0x35, KEY_8 },
+	{ 0x33, KEY_9 },
+
+	{ 0x3e, KEY_RADIO },		/* radio */
+	{ 0x03, KEY_MENU },		/* dvd/menu */
+	{ 0x2a, KEY_VOLUMEUP },
+	{ 0x19, KEY_VOLUMEDOWN },
+	{ 0x37, KEY_UP },
+	{ 0x3b, KEY_DOWN },
+	{ 0x27, KEY_LEFT },
+	{ 0x2f, KEY_RIGHT },
+	{ 0x25, KEY_VIDEO },		/* video */
+	{ 0x39, KEY_AUDIO },		/* music */
+
+	{ 0x21, KEY_TV },		/* tv */
+	{ 0x1d, KEY_EXIT },		/* back */
+	{ 0x0a, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x1b, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x1a, KEY_ENTER },		/* enter */
+
+	{ 0x06, KEY_PAUSE },		/* play/pause */
+	{ 0x1e, KEY_PREVIOUS },		/* rew */
+	{ 0x26, KEY_NEXT },		/* forward */
+	{ 0x0e, KEY_REWIND },		/* backward << */
+	{ 0x3a, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x36, KEY_STOP },
+	{ 0x2e, KEY_RECORD },		/* recording */
+	{ 0x16, KEY_POWER },		/* the button that reads "close" */
+
+	{ 0x11, KEY_ZOOM },		/* full screen */
+	{ 0x13, KEY_MACRO },		/* recall */
+	{ 0x23, KEY_HOME },		/* home */
+	{ 0x05, KEY_PVR },		/* picture */
+	{ 0x3d, KEY_MUTE },		/* mute */
+	{ 0x01, KEY_DVD },		/* dvd */
+};
+
+struct ir_scancode_table ir_codes_asus_pc39_table = {
+	.scan = ir_codes_asus_pc39,
+	.size = ARRAY_SIZE(ir_codes_asus_pc39),
+};
+EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
+
+
+/* Encore ENLTV-FM  - black plastic, white front cover with white glowing buttons
+    Juan Pablo Sormani <sorman@gmail.com> */
+static struct ir_scancode ir_codes_encore_enltv[] = {
+
+	/* Power button does nothing, neither in Windows app,
+	 although it sends data (used for BIOS wakeup?) */
+	{ 0x0d, KEY_MUTE },
+
+	{ 0x1e, KEY_TV },
+	{ 0x00, KEY_VIDEO },
+	{ 0x01, KEY_AUDIO },		/* music */
+	{ 0x02, KEY_MHP },		/* picture */
+
+	{ 0x1f, KEY_1 },
+	{ 0x03, KEY_2 },
+	{ 0x04, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x1c, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x1d, KEY_9 },
+	{ 0x0a, KEY_0 },
+
+	{ 0x09, KEY_LIST },		/* -/-- */
+	{ 0x0b, KEY_LAST },		/* recall */
+
+	{ 0x14, KEY_HOME },		/* win start menu */
+	{ 0x15, KEY_EXIT },		/* exit */
+	{ 0x16, KEY_CHANNELUP },	/* UP */
+	{ 0x12, KEY_CHANNELDOWN },	/* DOWN */
+	{ 0x0c, KEY_VOLUMEUP },		/* RIGHT */
+	{ 0x17, KEY_VOLUMEDOWN },	/* LEFT */
+
+	{ 0x18, KEY_ENTER },		/* OK */
+
+	{ 0x0e, KEY_ESC },
+	{ 0x13, KEY_CYCLEWINDOWS },	/* desktop */
+	{ 0x11, KEY_TAB },
+	{ 0x19, KEY_SWITCHVIDEOMODE },	/* switch */
+
+	{ 0x1a, KEY_MENU },
+	{ 0x1b, KEY_ZOOM },		/* fullscreen */
+	{ 0x44, KEY_TIME },		/* time shift */
+	{ 0x40, KEY_MODE },		/* source */
+
+	{ 0x5a, KEY_RECORD },
+	{ 0x42, KEY_PLAY },		/* play/pause */
+	{ 0x45, KEY_STOP },
+	{ 0x43, KEY_CAMERA },		/* camera icon */
+
+	{ 0x48, KEY_REWIND },
+	{ 0x4a, KEY_FASTFORWARD },
+	{ 0x49, KEY_PREVIOUS },
+	{ 0x4b, KEY_NEXT },
+
+	{ 0x4c, KEY_FAVORITES },	/* tv wall */
+	{ 0x4d, KEY_SOUND },		/* DVD sound */
+	{ 0x4e, KEY_LANGUAGE },		/* DVD lang */
+	{ 0x4f, KEY_TEXT },		/* DVD text */
+
+	{ 0x50, KEY_SLEEP },		/* shutdown */
+	{ 0x51, KEY_MODE },		/* stereo > main */
+	{ 0x52, KEY_SELECT },		/* stereo > sap */
+	{ 0x53, KEY_PROG1 },		/* teletext */
+
+
+	{ 0x59, KEY_RED },		/* AP1 */
+	{ 0x41, KEY_GREEN },		/* AP2 */
+	{ 0x47, KEY_YELLOW },		/* AP3 */
+	{ 0x57, KEY_BLUE },		/* AP4 */
+};
+
+struct ir_scancode_table ir_codes_encore_enltv_table = {
+	.scan = ir_codes_encore_enltv,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
+
+/* Encore ENLTV2-FM  - silver plastic - "Wand Media" written at the botton
+    Mauro Carvalho Chehab <mchehab@infradead.org> */
+static struct ir_scancode ir_codes_encore_enltv2[] = {
+	{ 0x4c, KEY_POWER2 },
+	{ 0x4a, KEY_TUNER },
+	{ 0x40, KEY_1 },
+	{ 0x60, KEY_2 },
+	{ 0x50, KEY_3 },
+	{ 0x70, KEY_4 },
+	{ 0x48, KEY_5 },
+	{ 0x68, KEY_6 },
+	{ 0x58, KEY_7 },
+	{ 0x78, KEY_8 },
+	{ 0x44, KEY_9 },
+	{ 0x54, KEY_0 },
+
+	{ 0x64, KEY_LAST },		/* +100 */
+	{ 0x4e, KEY_AGAIN },		/* Recall */
+
+	{ 0x6c, KEY_SWITCHVIDEOMODE },	/* Video Source */
+	{ 0x5e, KEY_MENU },
+	{ 0x56, KEY_SCREEN },
+	{ 0x7a, KEY_SETUP },
+
+	{ 0x46, KEY_MUTE },
+	{ 0x5c, KEY_MODE },		/* Stereo */
+	{ 0x74, KEY_INFO },
+	{ 0x7c, KEY_CLEAR },
+
+	{ 0x55, KEY_UP },
+	{ 0x49, KEY_DOWN },
+	{ 0x7e, KEY_LEFT },
+	{ 0x59, KEY_RIGHT },
+	{ 0x6a, KEY_ENTER },
+
+	{ 0x42, KEY_VOLUMEUP },
+	{ 0x62, KEY_VOLUMEDOWN },
+	{ 0x52, KEY_CHANNELUP },
+	{ 0x72, KEY_CHANNELDOWN },
+
+	{ 0x41, KEY_RECORD },
+	{ 0x51, KEY_CAMERA },		/* Snapshot */
+	{ 0x75, KEY_TIME },		/* Timeshift */
+	{ 0x71, KEY_TV2 },		/* PIP */
+
+	{ 0x45, KEY_REWIND },
+	{ 0x6f, KEY_PAUSE },
+	{ 0x7d, KEY_FORWARD },
+	{ 0x79, KEY_STOP },
+};
+
+struct ir_scancode_table ir_codes_encore_enltv2_table = {
+	.scan = ir_codes_encore_enltv2,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv2),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
+
+/* for the Technotrend 1500 bundled remotes (grey and black): */
+static struct ir_scancode ir_codes_tt_1500[] = {
+	{ 0x01, KEY_POWER },
+	{ 0x02, KEY_SHUFFLE },		/* ? double-arrow key */
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x06, KEY_4 },
+	{ 0x07, KEY_5 },
+	{ 0x08, KEY_6 },
+	{ 0x09, KEY_7 },
+	{ 0x0a, KEY_8 },
+	{ 0x0b, KEY_9 },
+	{ 0x0c, KEY_0 },
+	{ 0x0d, KEY_UP },
+	{ 0x0e, KEY_LEFT },
+	{ 0x0f, KEY_OK },
+	{ 0x10, KEY_RIGHT },
+	{ 0x11, KEY_DOWN },
+	{ 0x12, KEY_INFO },
+	{ 0x13, KEY_EXIT },
+	{ 0x14, KEY_RED },
+	{ 0x15, KEY_GREEN },
+	{ 0x16, KEY_YELLOW },
+	{ 0x17, KEY_BLUE },
+	{ 0x18, KEY_MUTE },
+	{ 0x19, KEY_TEXT },
+	{ 0x1a, KEY_MODE },		/* ? TV/Radio */
+	{ 0x21, KEY_OPTION },
+	{ 0x22, KEY_EPG },
+	{ 0x23, KEY_CHANNELUP },
+	{ 0x24, KEY_CHANNELDOWN },
+	{ 0x25, KEY_VOLUMEUP },
+	{ 0x26, KEY_VOLUMEDOWN },
+	{ 0x27, KEY_SETUP },
+	{ 0x3a, KEY_RECORD },		/* these keys are only in the black remote */
+	{ 0x3b, KEY_PLAY },
+	{ 0x3c, KEY_STOP },
+	{ 0x3d, KEY_REWIND },
+	{ 0x3e, KEY_PAUSE },
+	{ 0x3f, KEY_FORWARD },
+};
+
+struct ir_scancode_table ir_codes_tt_1500_table = {
+	.scan = ir_codes_tt_1500,
+	.size = ARRAY_SIZE(ir_codes_tt_1500),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
+
+/* DViCO FUSION HDTV MCE remote */
+static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
+
+	{ 0x0b, KEY_1 },
+	{ 0x17, KEY_2 },
+	{ 0x1b, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x50, KEY_5 },
+	{ 0x54, KEY_6 },
+	{ 0x48, KEY_7 },
+	{ 0x4c, KEY_8 },
+	{ 0x58, KEY_9 },
+	{ 0x03, KEY_0 },
+
+	{ 0x5e, KEY_OK },
+	{ 0x51, KEY_UP },
+	{ 0x53, KEY_DOWN },
+	{ 0x5b, KEY_LEFT },
+	{ 0x5f, KEY_RIGHT },
+
+	{ 0x02, KEY_TV },		/* Labeled DTV on remote */
+	{ 0x0e, KEY_MP3 },
+	{ 0x1a, KEY_DVD },
+	{ 0x1e, KEY_FAVORITES },	/* Labeled CPF on remote */
+	{ 0x16, KEY_SETUP },
+	{ 0x46, KEY_POWER2 },		/* TV On/Off button on remote */
+	{ 0x0a, KEY_EPG },		/* Labeled Guide on remote */
+
+	{ 0x49, KEY_BACK },
+	{ 0x59, KEY_INFO },		/* Labeled MORE on remote */
+	{ 0x4d, KEY_MENU },		/* Labeled DVDMENU on remote */
+	{ 0x55, KEY_CYCLEWINDOWS },	/* Labeled ALT-TAB on remote */
+
+	{ 0x0f, KEY_PREVIOUSSONG },	/* Labeled |<< REPLAY on remote */
+	{ 0x12, KEY_NEXTSONG },		/* Labeled >>| SKIP on remote */
+	{ 0x42, KEY_ENTER },		/* Labeled START with a green
+					   MS windows logo on remote */
+
+	{ 0x15, KEY_VOLUMEUP },
+	{ 0x05, KEY_VOLUMEDOWN },
+	{ 0x11, KEY_CHANNELUP },
+	{ 0x09, KEY_CHANNELDOWN },
+
+	{ 0x52, KEY_CAMERA },
+	{ 0x5a, KEY_TUNER },
+	{ 0x19, KEY_OPEN },
+
+	{ 0x13, KEY_MODE },		/* 4:3 16:9 select */
+	{ 0x1f, KEY_ZOOM },
+
+	{ 0x43, KEY_REWIND },
+	{ 0x47, KEY_PLAYPAUSE },
+	{ 0x4f, KEY_FASTFORWARD },
+	{ 0x57, KEY_MUTE },
+	{ 0x0d, KEY_STOP },
+	{ 0x01, KEY_RECORD },
+	{ 0x4e, KEY_POWER },
+};
+
+struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
+	.scan = ir_codes_fusionhdtv_mce,
+	.size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
+};
+EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
+
+/* Pinnacle PCTV HD 800i mini remote */
+static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
+
+	{ 0x0f, KEY_1 },
+	{ 0x15, KEY_2 },
+	{ 0x10, KEY_3 },
+	{ 0x18, KEY_4 },
+	{ 0x1b, KEY_5 },
+	{ 0x1e, KEY_6 },
+	{ 0x11, KEY_7 },
+	{ 0x21, KEY_8 },
+	{ 0x12, KEY_9 },
+	{ 0x27, KEY_0 },
+
+	{ 0x24, KEY_ZOOM },
+	{ 0x2a, KEY_SUBTITLE },
+
+	{ 0x00, KEY_MUTE },
+	{ 0x01, KEY_ENTER },	/* Pinnacle Logo */
+	{ 0x39, KEY_POWER },
+
+	{ 0x03, KEY_VOLUMEUP },
+	{ 0x09, KEY_VOLUMEDOWN },
+	{ 0x06, KEY_CHANNELUP },
+	{ 0x0c, KEY_CHANNELDOWN },
+
+	{ 0x2d, KEY_REWIND },
+	{ 0x30, KEY_PLAYPAUSE },
+	{ 0x33, KEY_FASTFORWARD },
+	{ 0x3c, KEY_STOP },
+	{ 0x36, KEY_RECORD },
+	{ 0x3f, KEY_EPG },	/* Labeled "?" */
+};
+
+struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
+	.scan = ir_codes_pinnacle_pctv_hd,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
+
+/*
+ * Igor Kuznetsov <igk72@ya.ru>
+ * Andrey J. Melnikov <temnota@kmv.ru>
+ *
+ * Keytable is used by BeholdTV 60x series, M6 series at
+ * least, and probably other cards too.
+ * The "ascii-art picture" below (in comments, first row
+ * is the keycode in hex, and subsequent row(s) shows
+ * the button labels (several variants when appropriate)
+ * helps to descide which keycodes to assign to the buttons.
+ */
+static struct ir_scancode ir_codes_behold[] = {
+
+	/*  0x1c            0x12  *
+	 *  TV/FM          POWER  *
+	 *                        */
+	{ 0x1c, KEY_TUNER },	/* XXX KEY_TV / KEY_RADIO */
+	{ 0x12, KEY_POWER },
+
+	/*  0x01    0x02    0x03  *
+	 *   1       2       3    *
+	 *                        *
+	 *  0x04    0x05    0x06  *
+	 *   4       5       6    *
+	 *                        *
+	 *  0x07    0x08    0x09  *
+	 *   7       8       9    *
+	 *                        */
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	/*  0x0a    0x00    0x17  *
+	 * RECALL    0      MODE  *
+	 *                        */
+	{ 0x0a, KEY_AGAIN },
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_MODE },
+
+	/*  0x14          0x10    *
+	 * ASPECT      FULLSCREEN *
+	 *                        */
+	{ 0x14, KEY_SCREEN },
+	{ 0x10, KEY_ZOOM },
+
+	/*          0x0b          *
+	 *           Up           *
+	 *                        *
+	 *  0x18    0x16    0x0c  *
+	 *  Left     Ok     Right *
+	 *                        *
+	 *         0x015          *
+	 *         Down           *
+	 *                        */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x18, KEY_VOLUMEDOWN },
+	{ 0x16, KEY_OK },		/* XXX KEY_ENTER */
+	{ 0x0c, KEY_VOLUMEUP },
+	{ 0x15, KEY_CHANNELDOWN },
+
+	/*  0x11            0x0d  *
+	 *  MUTE            INFO  *
+	 *                        */
+	{ 0x11, KEY_MUTE },
+	{ 0x0d, KEY_INFO },
+
+	/*  0x0f    0x1b    0x1a  *
+	 * RECORD PLAY/PAUSE STOP *
+	 *                        *
+	 *  0x0e    0x1f    0x1e  *
+	 *TELETEXT  AUDIO  SOURCE *
+	 *           RED   YELLOW *
+	 *                        */
+	{ 0x0f, KEY_RECORD },
+	{ 0x1b, KEY_PLAYPAUSE },
+	{ 0x1a, KEY_STOP },
+	{ 0x0e, KEY_TEXT },
+	{ 0x1f, KEY_RED },	/*XXX KEY_AUDIO	*/
+	{ 0x1e, KEY_YELLOW },	/*XXX KEY_SOURCE	*/
+
+	/*  0x1d   0x13     0x19  *
+	 * SLEEP  PREVIEW   DVB   *
+	 *         GREEN    BLUE  *
+	 *                        */
+	{ 0x1d, KEY_SLEEP },
+	{ 0x13, KEY_GREEN },
+	{ 0x19, KEY_BLUE },	/* XXX KEY_SAT	*/
+
+	/*  0x58           0x5c   *
+	 * FREEZE        SNAPSHOT *
+	 *                        */
+	{ 0x58, KEY_SLOW },
+	{ 0x5c, KEY_CAMERA },
+
+};
+
+struct ir_scancode_table ir_codes_behold_table = {
+	.scan = ir_codes_behold,
+	.size = ARRAY_SIZE(ir_codes_behold),
+};
+EXPORT_SYMBOL_GPL(ir_codes_behold_table);
+
+/* Beholder Intl. Ltd. 2008
+ * Dmitry Belimov d.belimov@google.com
+ * Keytable is used by BeholdTV Columbus
+ * The "ascii-art picture" below (in comments, first row
+ * is the keycode in hex, and subsequent row(s) shows
+ * the button labels (several variants when appropriate)
+ * helps to descide which keycodes to assign to the buttons.
+ */
+static struct ir_scancode ir_codes_behold_columbus[] = {
+
+	/*  0x13   0x11   0x1C   0x12  *
+	 *  Mute  Source  TV/FM  Power *
+	 *                             */
+
+	{ 0x13, KEY_MUTE },
+	{ 0x11, KEY_PROPS },
+	{ 0x1C, KEY_TUNER },	/* KEY_TV/KEY_RADIO	*/
+	{ 0x12, KEY_POWER },
+
+	/*  0x01    0x02    0x03  0x0D    *
+	 *   1       2       3   Stereo   *
+	 *                        	  *
+	 *  0x04    0x05    0x06  0x19    *
+	 *   4       5       6   Snapshot *
+	 *                        	  *
+	 *  0x07    0x08    0x09  0x10    *
+	 *   7       8       9    Zoom 	  *
+	 *                                */
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x0D, KEY_SETUP },	  /* Setup key */
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x19, KEY_CAMERA },	/* Snapshot key */
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x10, KEY_ZOOM },
+
+	/*  0x0A    0x00    0x0B       0x0C   *
+	 * RECALL    0    ChannelUp  VolumeUp *
+	 *                                    */
+	{ 0x0A, KEY_AGAIN },
+	{ 0x00, KEY_0 },
+	{ 0x0B, KEY_CHANNELUP },
+	{ 0x0C, KEY_VOLUMEUP },
+
+	/*   0x1B      0x1D      0x15        0x18     *
+	 * Timeshift  Record  ChannelDown  VolumeDown *
+	 *                                            */
+
+	{ 0x1B, KEY_TIME },
+	{ 0x1D, KEY_RECORD },
+	{ 0x15, KEY_CHANNELDOWN },
+	{ 0x18, KEY_VOLUMEDOWN },
+
+	/*   0x0E   0x1E     0x0F     0x1A  *
+	 *   Stop   Pause  Previouse  Next  *
+	 *                                  */
+
+	{ 0x0E, KEY_STOP },
+	{ 0x1E, KEY_PAUSE },
+	{ 0x0F, KEY_PREVIOUS },
+	{ 0x1A, KEY_NEXT },
+
+};
+
+struct ir_scancode_table ir_codes_behold_columbus_table = {
+	.scan = ir_codes_behold_columbus,
+	.size = ARRAY_SIZE(ir_codes_behold_columbus),
+};
+EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
+
+/*
+ * Remote control for the Genius TVGO A11MCE
+ * Adrian Pardini <pardo.bsso@gmail.com>
+ */
+static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
+	/* Keys 0 to 9 */
+	{ 0x48, KEY_0 },
+	{ 0x09, KEY_1 },
+	{ 0x1d, KEY_2 },
+	{ 0x1f, KEY_3 },
+	{ 0x19, KEY_4 },
+	{ 0x1b, KEY_5 },
+	{ 0x11, KEY_6 },
+	{ 0x17, KEY_7 },
+	{ 0x12, KEY_8 },
+	{ 0x16, KEY_9 },
+
+	{ 0x54, KEY_RECORD },		/* recording */
+	{ 0x06, KEY_MUTE },		/* mute */
+	{ 0x10, KEY_POWER },
+	{ 0x40, KEY_LAST },		/* recall */
+	{ 0x4c, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x00, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x0d, KEY_VOLUMEUP },
+	{ 0x15, KEY_VOLUMEDOWN },
+	{ 0x4d, KEY_OK },		/* also labeled as Pause */
+	{ 0x1c, KEY_ZOOM },		/* full screen and Stop*/
+	{ 0x02, KEY_MODE },		/* AV Source or Rewind*/
+	{ 0x04, KEY_LIST },		/* -/-- */
+	/* small arrows above numbers */
+	{ 0x1a, KEY_NEXT },		/* also Fast Forward */
+	{ 0x0e, KEY_PREVIOUS },		/* also Rewind */
+	/* these are in a rather non standard layout and have
+	an alternate name written */
+	{ 0x1e, KEY_UP },		/* Video Setting */
+	{ 0x0a, KEY_DOWN },		/* Video Default */
+	{ 0x05, KEY_CAMERA },		/* Snapshot */
+	{ 0x0c, KEY_RIGHT },		/* Hide Panel */
+	/* Four buttons without label */
+	{ 0x49, KEY_RED },
+	{ 0x0b, KEY_GREEN },
+	{ 0x13, KEY_YELLOW },
+	{ 0x50, KEY_BLUE },
+};
+
+struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
+	.scan = ir_codes_genius_tvgo_a11mce,
+	.size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
+};
+EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
+
+/*
+ * Remote control for Powercolor Real Angel 330
+ * Daniel Fraga <fragabr@gmail.com>
+ */
+static struct ir_scancode ir_codes_powercolor_real_angel[] = {
+	{ 0x38, KEY_SWITCHVIDEOMODE },	/* switch inputs */
+	{ 0x0c, KEY_MEDIA },		/* Turn ON/OFF App */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_DIGITS },		/* single, double, tripple digit */
+	{ 0x29, KEY_PREVIOUS },		/* previous channel */
+	{ 0x12, KEY_BRIGHTNESSUP },
+	{ 0x13, KEY_BRIGHTNESSDOWN },
+	{ 0x2b, KEY_MODE },		/* stereo/mono */
+	{ 0x2c, KEY_TEXT },		/* teletext */
+	{ 0x20, KEY_CHANNELUP },	/* channel up */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel down */
+	{ 0x10, KEY_VOLUMEUP },		/* volume up */
+	{ 0x11, KEY_VOLUMEDOWN },	/* volume down */
+	{ 0x0d, KEY_MUTE },
+	{ 0x1f, KEY_RECORD },
+	{ 0x17, KEY_PLAY },
+	{ 0x16, KEY_PAUSE },
+	{ 0x0b, KEY_STOP },
+	{ 0x27, KEY_FASTFORWARD },
+	{ 0x26, KEY_REWIND },
+	{ 0x1e, KEY_SEARCH },		/* autoscan */
+	{ 0x0e, KEY_CAMERA },		/* snapshot */
+	{ 0x2d, KEY_SETUP },
+	{ 0x0f, KEY_SCREEN },		/* full screen */
+	{ 0x14, KEY_RADIO },		/* FM radio */
+	{ 0x25, KEY_POWER },		/* power */
+};
+
+struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
+	.scan = ir_codes_powercolor_real_angel,
+	.size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
+};
+EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
+
+/* Kworld Plus TV Analog Lite PCI IR
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
+	{ 0x0c, KEY_PROG1 },		/* Kworld key */
+	{ 0x16, KEY_CLOSECD },		/* -> ) */
+	{ 0x1d, KEY_POWER2 },
+
+	{ 0x00, KEY_1 },
+	{ 0x01, KEY_2 },
+	{ 0x02, KEY_3 },		/* Two keys have the same code: 3 and left */
+	{ 0x03, KEY_4 },		/* Two keys have the same code: 3 and right */
+	{ 0x04, KEY_5 },
+	{ 0x05, KEY_6 },
+	{ 0x06, KEY_7 },
+	{ 0x07, KEY_8 },
+	{ 0x08, KEY_9 },
+	{ 0x0a, KEY_0 },
+
+	{ 0x09, KEY_AGAIN },
+	{ 0x14, KEY_MUTE },
+
+	{ 0x20, KEY_UP },
+	{ 0x21, KEY_DOWN },
+	{ 0x0b, KEY_ENTER },
+
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x11, KEY_CHANNELDOWN },
+
+	/* Couldn't map key left/key right since those
+	   conflict with '3' and '4' scancodes
+	   I dunno what the original driver does
+	 */
+
+	{ 0x13, KEY_VOLUMEUP },
+	{ 0x12, KEY_VOLUMEDOWN },
+
+	/* The lower part of the IR
+	   There are several duplicated keycodes there.
+	   Most of them conflict with digits.
+	   Add mappings just to the unused scancodes.
+	   Somehow, the original driver has a way to know,
+	   but this doesn't seem to be on some GPIO.
+	   Also, it is not related to the time between keyup
+	   and keydown.
+	 */
+	{ 0x19, KEY_TIME},		/* Timeshift */
+	{ 0x1a, KEY_STOP},
+	{ 0x1b, KEY_RECORD},
+
+	{ 0x22, KEY_TEXT},
+
+	{ 0x15, KEY_AUDIO},		/* ((*)) */
+	{ 0x0f, KEY_ZOOM},
+	{ 0x1c, KEY_CAMERA},		/* snapshot */
+
+	{ 0x18, KEY_RED},		/* B */
+	{ 0x23, KEY_GREEN},		/* C */
+};
+struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
+	.scan = ir_codes_kworld_plus_tv_analog,
+	.size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
+};
+EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
+
+/* Kaiomy TVnPC U2
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+static struct ir_scancode ir_codes_kaiomy[] = {
+	{ 0x43, KEY_POWER2},
+	{ 0x01, KEY_LIST},
+	{ 0x0b, KEY_ZOOM},
+	{ 0x03, KEY_POWER},
+
+	{ 0x04, KEY_1},
+	{ 0x08, KEY_2},
+	{ 0x02, KEY_3},
+
+	{ 0x0f, KEY_4},
+	{ 0x05, KEY_5},
+	{ 0x06, KEY_6},
+
+	{ 0x0c, KEY_7},
+	{ 0x0d, KEY_8},
+	{ 0x0a, KEY_9},
+
+	{ 0x11, KEY_0},
+
+	{ 0x09, KEY_CHANNELUP},
+	{ 0x07, KEY_CHANNELDOWN},
+
+	{ 0x0e, KEY_VOLUMEUP},
+	{ 0x13, KEY_VOLUMEDOWN},
+
+	{ 0x10, KEY_HOME},
+	{ 0x12, KEY_ENTER},
+
+	{ 0x14, KEY_RECORD},
+	{ 0x15, KEY_STOP},
+	{ 0x16, KEY_PLAY},
+	{ 0x17, KEY_MUTE},
+
+	{ 0x18, KEY_UP},
+	{ 0x19, KEY_DOWN},
+	{ 0x1a, KEY_LEFT},
+	{ 0x1b, KEY_RIGHT},
+
+	{ 0x1c, KEY_RED},
+	{ 0x1d, KEY_GREEN},
+	{ 0x1e, KEY_YELLOW},
+	{ 0x1f, KEY_BLUE},
+};
+struct ir_scancode_table ir_codes_kaiomy_table = {
+	.scan = ir_codes_kaiomy,
+	.size = ARRAY_SIZE(ir_codes_kaiomy),
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
+
+static struct ir_scancode ir_codes_avermedia_a16d[] = {
+	{ 0x20, KEY_LIST},
+	{ 0x00, KEY_POWER},
+	{ 0x28, KEY_1},
+	{ 0x18, KEY_2},
+	{ 0x38, KEY_3},
+	{ 0x24, KEY_4},
+	{ 0x14, KEY_5},
+	{ 0x34, KEY_6},
+	{ 0x2c, KEY_7},
+	{ 0x1c, KEY_8},
+	{ 0x3c, KEY_9},
+	{ 0x12, KEY_SUBTITLE},
+	{ 0x22, KEY_0},
+	{ 0x32, KEY_REWIND},
+	{ 0x3a, KEY_SHUFFLE},
+	{ 0x02, KEY_PRINT},
+	{ 0x11, KEY_CHANNELDOWN},
+	{ 0x31, KEY_CHANNELUP},
+	{ 0x0c, KEY_ZOOM},
+	{ 0x1e, KEY_VOLUMEDOWN},
+	{ 0x3e, KEY_VOLUMEUP},
+	{ 0x0a, KEY_MUTE},
+	{ 0x04, KEY_AUDIO},
+	{ 0x26, KEY_RECORD},
+	{ 0x06, KEY_PLAY},
+	{ 0x36, KEY_STOP},
+	{ 0x16, KEY_PAUSE},
+	{ 0x2e, KEY_REWIND},
+	{ 0x0e, KEY_FASTFORWARD},
+	{ 0x30, KEY_TEXT},
+	{ 0x21, KEY_GREEN},
+	{ 0x01, KEY_BLUE},
+	{ 0x08, KEY_EPG},
+	{ 0x2a, KEY_MENU},
+};
+struct ir_scancode_table ir_codes_avermedia_a16d_table = {
+	.scan = ir_codes_avermedia_a16d,
+	.size = ARRAY_SIZE(ir_codes_avermedia_a16d),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
+
+/* Encore ENLTV-FM v5.3
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
+	{ 0x10, KEY_POWER2},
+	{ 0x06, KEY_MUTE},
+
+	{ 0x09, KEY_1},
+	{ 0x1d, KEY_2},
+	{ 0x1f, KEY_3},
+	{ 0x19, KEY_4},
+	{ 0x1b, KEY_5},
+	{ 0x11, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x12, KEY_8},
+	{ 0x16, KEY_9},
+	{ 0x48, KEY_0},
+
+	{ 0x04, KEY_LIST},		/* -/-- */
+	{ 0x40, KEY_LAST},		/* recall */
+
+	{ 0x02, KEY_MODE},		/* TV/AV */
+	{ 0x05, KEY_CAMERA},		/* SNAPSHOT */
+
+	{ 0x4c, KEY_CHANNELUP},		/* UP */
+	{ 0x00, KEY_CHANNELDOWN},	/* DOWN */
+	{ 0x0d, KEY_VOLUMEUP},		/* RIGHT */
+	{ 0x15, KEY_VOLUMEDOWN},	/* LEFT */
+	{ 0x49, KEY_ENTER},		/* OK */
+
+	{ 0x54, KEY_RECORD},
+	{ 0x4d, KEY_PLAY},		/* pause */
+
+	{ 0x1e, KEY_MENU},		/* video setting */
+	{ 0x0e, KEY_RIGHT},		/* <- */
+	{ 0x1a, KEY_LEFT},		/* -> */
+
+	{ 0x0a, KEY_CLEAR},		/* video default */
+	{ 0x0c, KEY_ZOOM},		/* hide pannel */
+	{ 0x47, KEY_SLEEP},		/* shutdown */
+};
+struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
+	.scan = ir_codes_encore_enltv_fm53,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
+
+/* Zogis Real Audio 220 - 32 keys IR */
+static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
+	{ 0x1c, KEY_RADIO},
+	{ 0x12, KEY_POWER2},
+
+	{ 0x01, KEY_1},
+	{ 0x02, KEY_2},
+	{ 0x03, KEY_3},
+	{ 0x04, KEY_4},
+	{ 0x05, KEY_5},
+	{ 0x06, KEY_6},
+	{ 0x07, KEY_7},
+	{ 0x08, KEY_8},
+	{ 0x09, KEY_9},
+	{ 0x00, KEY_0},
+
+	{ 0x0c, KEY_VOLUMEUP},
+	{ 0x18, KEY_VOLUMEDOWN},
+	{ 0x0b, KEY_CHANNELUP},
+	{ 0x15, KEY_CHANNELDOWN},
+	{ 0x16, KEY_ENTER},
+
+	{ 0x11, KEY_LIST},		/* Source */
+	{ 0x0d, KEY_AUDIO},		/* stereo */
+
+	{ 0x0f, KEY_PREVIOUS},		/* Prev */
+	{ 0x1b, KEY_TIME},		/* Timeshift */
+	{ 0x1a, KEY_NEXT},		/* Next */
+
+	{ 0x0e, KEY_STOP},
+	{ 0x1f, KEY_PLAY},
+	{ 0x1e, KEY_PLAYPAUSE},		/* Pause */
+
+	{ 0x1d, KEY_RECORD},
+	{ 0x13, KEY_MUTE},
+	{ 0x19, KEY_CAMERA},		/* Snapshot */
+
+};
+struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
+	.scan = ir_codes_real_audio_220_32_keys,
+	.size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
+};
+EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
+
+/* ATI TV Wonder HD 600 USB
+   Devin Heitmueller <devin.heitmueller@gmail.com>
+ */
+static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
+	{ 0x00, KEY_RECORD},		/* Row 1 */
+	{ 0x01, KEY_PLAYPAUSE},
+	{ 0x02, KEY_STOP},
+	{ 0x03, KEY_POWER},
+	{ 0x04, KEY_PREVIOUS},	/* Row 2 */
+	{ 0x05, KEY_REWIND},
+	{ 0x06, KEY_FORWARD},
+	{ 0x07, KEY_NEXT},
+	{ 0x08, KEY_EPG},		/* Row 3 */
+	{ 0x09, KEY_HOME},
+	{ 0x0a, KEY_MENU},
+	{ 0x0b, KEY_CHANNELUP},
+	{ 0x0c, KEY_BACK},		/* Row 4 */
+	{ 0x0d, KEY_UP},
+	{ 0x0e, KEY_INFO},
+	{ 0x0f, KEY_CHANNELDOWN},
+	{ 0x10, KEY_LEFT},		/* Row 5 */
+	{ 0x11, KEY_SELECT},
+	{ 0x12, KEY_RIGHT},
+	{ 0x13, KEY_VOLUMEUP},
+	{ 0x14, KEY_LAST},		/* Row 6 */
+	{ 0x15, KEY_DOWN},
+	{ 0x16, KEY_MUTE},
+	{ 0x17, KEY_VOLUMEDOWN},
+};
+struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
+	.scan = ir_codes_ati_tv_wonder_hd_600,
+	.size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
+};
+EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
+
+/* DVBWorld remotes
+   Igor M. Liplianin <liplianin@me.by>
+ */
+static struct ir_scancode ir_codes_dm1105_nec[] = {
+	{ 0x0a, KEY_POWER2},		/* power */
+	{ 0x0c, KEY_MUTE},		/* mute */
+	{ 0x11, KEY_1},
+	{ 0x12, KEY_2},
+	{ 0x13, KEY_3},
+	{ 0x14, KEY_4},
+	{ 0x15, KEY_5},
+	{ 0x16, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x18, KEY_8},
+	{ 0x19, KEY_9},
+	{ 0x10, KEY_0},
+	{ 0x1c, KEY_CHANNELUP},		/* ch+ */
+	{ 0x0f, KEY_CHANNELDOWN},	/* ch- */
+	{ 0x1a, KEY_VOLUMEUP},		/* vol+ */
+	{ 0x0e, KEY_VOLUMEDOWN},	/* vol- */
+	{ 0x04, KEY_RECORD},		/* rec */
+	{ 0x09, KEY_CHANNEL},		/* fav */
+	{ 0x08, KEY_BACKSPACE},		/* rewind */
+	{ 0x07, KEY_FASTFORWARD},	/* fast */
+	{ 0x0b, KEY_PAUSE},		/* pause */
+	{ 0x02, KEY_ESC},		/* cancel */
+	{ 0x03, KEY_TAB},		/* tab */
+	{ 0x00, KEY_UP},		/* up */
+	{ 0x1f, KEY_ENTER},		/* ok */
+	{ 0x01, KEY_DOWN},		/* down */
+	{ 0x05, KEY_RECORD},		/* cap */
+	{ 0x06, KEY_STOP},		/* stop */
+	{ 0x40, KEY_ZOOM},		/* full */
+	{ 0x1e, KEY_TV},		/* tvmode */
+	{ 0x1b, KEY_B},			/* recall */
+};
+struct ir_scancode_table ir_codes_dm1105_nec_table = {
+	.scan = ir_codes_dm1105_nec,
+	.size = ARRAY_SIZE(ir_codes_dm1105_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
+
+static struct ir_scancode ir_codes_tevii_nec[] = {
+	{ 0x0a, KEY_POWER2},
+	{ 0x0c, KEY_MUTE},
+	{ 0x11, KEY_1},
+	{ 0x12, KEY_2},
+	{ 0x13, KEY_3},
+	{ 0x14, KEY_4},
+	{ 0x15, KEY_5},
+	{ 0x16, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x18, KEY_8},
+	{ 0x19, KEY_9},
+	{ 0x10, KEY_0},
+	{ 0x1c, KEY_MENU},
+	{ 0x0f, KEY_VOLUMEDOWN},
+	{ 0x1a, KEY_LAST},
+	{ 0x0e, KEY_OPEN},
+	{ 0x04, KEY_RECORD},
+	{ 0x09, KEY_VOLUMEUP},
+	{ 0x08, KEY_CHANNELUP},
+	{ 0x07, KEY_PVR},
+	{ 0x0b, KEY_TIME},
+	{ 0x02, KEY_RIGHT},
+	{ 0x03, KEY_LEFT},
+	{ 0x00, KEY_UP},
+	{ 0x1f, KEY_OK},
+	{ 0x01, KEY_DOWN},
+	{ 0x05, KEY_TUNER},
+	{ 0x06, KEY_CHANNELDOWN},
+	{ 0x40, KEY_PLAYPAUSE},
+	{ 0x1e, KEY_REWIND},
+	{ 0x1b, KEY_FAVORITES},
+	{ 0x1d, KEY_BACK},
+	{ 0x4d, KEY_FASTFORWARD},
+	{ 0x44, KEY_EPG},
+	{ 0x4c, KEY_INFO},
+	{ 0x41, KEY_AB},
+	{ 0x43, KEY_AUDIO},
+	{ 0x45, KEY_SUBTITLE},
+	{ 0x4a, KEY_LIST},
+	{ 0x46, KEY_F1},
+	{ 0x47, KEY_F2},
+	{ 0x5e, KEY_F3},
+	{ 0x5c, KEY_F4},
+	{ 0x52, KEY_F5},
+	{ 0x5a, KEY_F6},
+	{ 0x56, KEY_MODE},
+	{ 0x58, KEY_SWITCHVIDEOMODE},
+};
+struct ir_scancode_table ir_codes_tevii_nec_table = {
+	.scan = ir_codes_tevii_nec,
+	.size = ARRAY_SIZE(ir_codes_tevii_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
+
+static struct ir_scancode ir_codes_tbs_nec[] = {
+	{ 0x04, KEY_POWER2},	/*power*/
+	{ 0x14, KEY_MUTE},	/*mute*/
+	{ 0x07, KEY_1},
+	{ 0x06, KEY_2},
+	{ 0x05, KEY_3},
+	{ 0x0b, KEY_4},
+	{ 0x0a, KEY_5},
+	{ 0x09, KEY_6},
+	{ 0x0f, KEY_7},
+	{ 0x0e, KEY_8},
+	{ 0x0d, KEY_9},
+	{ 0x12, KEY_0},
+	{ 0x16, KEY_CHANNELUP},	/*ch+*/
+	{ 0x11, KEY_CHANNELDOWN},/*ch-*/
+	{ 0x13, KEY_VOLUMEUP},	/*vol+*/
+	{ 0x0c, KEY_VOLUMEDOWN},/*vol-*/
+	{ 0x03, KEY_RECORD},	/*rec*/
+	{ 0x18, KEY_PAUSE},	/*pause*/
+	{ 0x19, KEY_OK},	/*ok*/
+	{ 0x1a, KEY_CAMERA},	/* snapshot */
+	{ 0x01, KEY_UP},
+	{ 0x10, KEY_LEFT},
+	{ 0x02, KEY_RIGHT},
+	{ 0x08, KEY_DOWN},
+	{ 0x15, KEY_FAVORITES},
+	{ 0x17, KEY_SUBTITLE},
+	{ 0x1d, KEY_ZOOM},
+	{ 0x1f, KEY_EXIT},
+	{ 0x1e, KEY_MENU},
+	{ 0x1c, KEY_EPG},
+	{ 0x00, KEY_PREVIOUS},
+	{ 0x1b, KEY_MODE},
+};
+struct ir_scancode_table ir_codes_tbs_nec_table = {
+	.scan = ir_codes_tbs_nec,
+	.size = ARRAY_SIZE(ir_codes_tbs_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
+
+/* Terratec Cinergy Hybrid T USB XS
+   Devin Heitmueller <dheitmueller@linuxtv.org>
+ */
+static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
+	{ 0x41, KEY_HOME},
+	{ 0x01, KEY_POWER},
+	{ 0x42, KEY_MENU},
+	{ 0x02, KEY_1},
+	{ 0x03, KEY_2},
+	{ 0x04, KEY_3},
+	{ 0x43, KEY_SUBTITLE},
+	{ 0x05, KEY_4},
+	{ 0x06, KEY_5},
+	{ 0x07, KEY_6},
+	{ 0x44, KEY_TEXT},
+	{ 0x08, KEY_7},
+	{ 0x09, KEY_8},
+	{ 0x0a, KEY_9},
+	{ 0x45, KEY_DELETE},
+	{ 0x0b, KEY_TUNER},
+	{ 0x0c, KEY_0},
+	{ 0x0d, KEY_MODE},
+	{ 0x46, KEY_TV},
+	{ 0x47, KEY_DVD},
+	{ 0x49, KEY_VIDEO},
+	{ 0x4b, KEY_AUX},
+	{ 0x10, KEY_UP},
+	{ 0x11, KEY_LEFT},
+	{ 0x12, KEY_OK},
+	{ 0x13, KEY_RIGHT},
+	{ 0x14, KEY_DOWN},
+	{ 0x0f, KEY_EPG},
+	{ 0x16, KEY_INFO},
+	{ 0x4d, KEY_BACKSPACE},
+	{ 0x1c, KEY_VOLUMEUP},
+	{ 0x4c, KEY_PLAY},
+	{ 0x1b, KEY_CHANNELUP},
+	{ 0x1e, KEY_VOLUMEDOWN},
+	{ 0x1d, KEY_MUTE},
+	{ 0x1f, KEY_CHANNELDOWN},
+	{ 0x17, KEY_RED},
+	{ 0x18, KEY_GREEN},
+	{ 0x19, KEY_YELLOW},
+	{ 0x1a, KEY_BLUE},
+	{ 0x58, KEY_RECORD},
+	{ 0x48, KEY_STOP},
+	{ 0x40, KEY_PAUSE},
+	{ 0x54, KEY_LAST},
+	{ 0x4e, KEY_REWIND},
+	{ 0x4f, KEY_FASTFORWARD},
+	{ 0x5c, KEY_NEXT},
+};
+struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
+	.scan = ir_codes_terratec_cinergy_xs,
+	.size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
+};
+EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
+
+/* EVGA inDtube
+   Devin Heitmueller <devin.heitmueller@gmail.com>
+ */
+static struct ir_scancode ir_codes_evga_indtube[] = {
+	{ 0x12, KEY_POWER},
+	{ 0x02, KEY_MODE},	/* TV */
+	{ 0x14, KEY_MUTE},
+	{ 0x1a, KEY_CHANNELUP},
+	{ 0x16, KEY_TV2},	/* PIP */
+	{ 0x1d, KEY_VOLUMEUP},
+	{ 0x05, KEY_CHANNELDOWN},
+	{ 0x0f, KEY_PLAYPAUSE},
+	{ 0x19, KEY_VOLUMEDOWN},
+	{ 0x1c, KEY_REWIND},
+	{ 0x0d, KEY_RECORD},
+	{ 0x18, KEY_FORWARD},
+	{ 0x1e, KEY_PREVIOUS},
+	{ 0x1b, KEY_STOP},
+	{ 0x1f, KEY_NEXT},
+	{ 0x13, KEY_CAMERA},
+};
+struct ir_scancode_table ir_codes_evga_indtube_table = {
+	.scan = ir_codes_evga_indtube,
+	.size = ARRAY_SIZE(ir_codes_evga_indtube),
+};
+EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
+
+static struct ir_scancode ir_codes_videomate_s350[] = {
+	{ 0x00, KEY_TV},
+	{ 0x01, KEY_DVD},
+	{ 0x04, KEY_RECORD},
+	{ 0x05, KEY_VIDEO},	/* TV/Video */
+	{ 0x07, KEY_STOP},
+	{ 0x08, KEY_PLAYPAUSE},
+	{ 0x0a, KEY_REWIND},
+	{ 0x0f, KEY_FASTFORWARD},
+	{ 0x10, KEY_CHANNELUP},
+	{ 0x12, KEY_VOLUMEUP},
+	{ 0x13, KEY_CHANNELDOWN},
+	{ 0x14, KEY_MUTE},
+	{ 0x15, KEY_VOLUMEDOWN},
+	{ 0x16, KEY_1},
+	{ 0x17, KEY_2},
+	{ 0x18, KEY_3},
+	{ 0x19, KEY_4},
+	{ 0x1a, KEY_5},
+	{ 0x1b, KEY_6},
+	{ 0x1c, KEY_7},
+	{ 0x1d, KEY_8},
+	{ 0x1e, KEY_9},
+	{ 0x1f, KEY_0},
+	{ 0x21, KEY_SLEEP},
+	{ 0x24, KEY_ZOOM},
+	{ 0x25, KEY_LAST},	/* Recall */
+	{ 0x26, KEY_SUBTITLE},	/* CC */
+	{ 0x27, KEY_LANGUAGE},	/* MTS */
+	{ 0x29, KEY_CHANNEL},	/* SURF */
+	{ 0x2b, KEY_A},
+	{ 0x2c, KEY_B},
+	{ 0x2f, KEY_CAMERA},	/* Snapshot */
+	{ 0x23, KEY_RADIO},
+	{ 0x02, KEY_PREVIOUSSONG},
+	{ 0x06, KEY_NEXTSONG},
+	{ 0x03, KEY_EPG},
+	{ 0x09, KEY_SETUP},
+	{ 0x22, KEY_BACKSPACE},
+	{ 0x0c, KEY_UP},
+	{ 0x0e, KEY_DOWN},
+	{ 0x0b, KEY_LEFT},
+	{ 0x0d, KEY_RIGHT},
+	{ 0x11, KEY_ENTER},
+	{ 0x20, KEY_TEXT},
+};
+struct ir_scancode_table ir_codes_videomate_s350_table = {
+	.scan = ir_codes_videomate_s350,
+	.size = ARRAY_SIZE(ir_codes_videomate_s350),
+};
+EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
+
+/* GADMEI UTV330+ RM008Z remote
+   Shine Liu <shinel@foxmail.com>
+ */
+static struct ir_scancode ir_codes_gadmei_rm008z[] = {
+	{ 0x14, KEY_POWER2},		/* POWER OFF */
+	{ 0x0c, KEY_MUTE},		/* MUTE */
+
+	{ 0x18, KEY_TV},		/* TV */
+	{ 0x0e, KEY_VIDEO},		/* AV */
+	{ 0x0b, KEY_AUDIO},		/* SV */
+	{ 0x0f, KEY_RADIO},		/* FM */
+
+	{ 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},
+	{ 0x0a, KEY_INFO},		/* OSD */
+	{ 0x1c, KEY_BACKSPACE},		/* LAST */
+
+	{ 0x0d, KEY_PLAY},		/* PLAY */
+	{ 0x1e, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x1a, KEY_RECORD},		/* RECORD */
+	{ 0x17, KEY_STOP},		/* STOP */
+
+	{ 0x1f, KEY_UP},		/* UP */
+	{ 0x44, KEY_DOWN},		/* DOWN */
+	{ 0x46, KEY_TAB},		/* BACK */
+	{ 0x4a, KEY_ZOOM},		/* FULLSECREEN */
+
+	{ 0x10, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x11, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x12, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x13, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+	{ 0x15, KEY_ENTER},		/* OK */
+};
+struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
+	.scan = ir_codes_gadmei_rm008z,
+	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
+};
+EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
+
+/*************************************************************
+ *		COMPLETE SCANCODE TABLES
+ * Instead of just a partial scancode, the tables bellow
+ * contains the complete scancode and the receiver protocol
+ *************************************************************/
+
+/*
+ * Hauppauge:the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ *
+ * This table contains the complete RC5 code, instead of just the data part
+ */
+static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
+	/* Keys 0 to 9 */
+	{ 0x1e00, KEY_0 },
+	{ 0x1e01, KEY_1 },
+	{ 0x1e02, KEY_2 },
+	{ 0x1e03, KEY_3 },
+	{ 0x1e04, KEY_4 },
+	{ 0x1e05, KEY_5 },
+	{ 0x1e06, KEY_6 },
+	{ 0x1e07, KEY_7 },
+	{ 0x1e08, KEY_8 },
+	{ 0x1e09, KEY_9 },
+
+	{ 0x1e0a, KEY_TEXT },		/* keypad asterisk as well */
+	{ 0x1e0b, KEY_RED },		/* red button */
+	{ 0x1e0c, KEY_RADIO },
+	{ 0x1e0d, KEY_MENU },
+	{ 0x1e0e, KEY_SUBTITLE },		/* also the # key */
+	{ 0x1e0f, KEY_MUTE },
+	{ 0x1e10, KEY_VOLUMEUP },
+	{ 0x1e11, KEY_VOLUMEDOWN },
+	{ 0x1e12, KEY_PREVIOUS },		/* previous channel */
+	{ 0x1e14, KEY_UP },
+	{ 0x1e15, KEY_DOWN },
+	{ 0x1e16, KEY_LEFT },
+	{ 0x1e17, KEY_RIGHT },
+	{ 0x1e18, KEY_VIDEO },		/* Videos */
+	{ 0x1e19, KEY_AUDIO },		/* Music */
+	/* 0x1e1a: Pictures - presume this means
+	   "Multimedia Home Platform" -
+	   no "PICTURES" key in input.h
+	 */
+	{ 0x1e1a, KEY_MHP },
+
+	{ 0x1e1b, KEY_EPG },		/* Guide */
+	{ 0x1e1c, KEY_TV },
+	{ 0x1e1e, KEY_NEXTSONG },		/* skip >| */
+	{ 0x1e1f, KEY_EXIT },		/* back/exit */
+	{ 0x1e20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x1e21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x1e22, KEY_CHANNEL },		/* source (old black remote) */
+	{ 0x1e24, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x1e25, KEY_ENTER },		/* OK */
+	{ 0x1e26, KEY_SLEEP },		/* minimize (old black remote) */
+	{ 0x1e29, KEY_BLUE },		/* blue key */
+	{ 0x1e2e, KEY_GREEN },		/* green button */
+	{ 0x1e30, KEY_PAUSE },		/* pause */
+	{ 0x1e32, KEY_REWIND },		/* backward << */
+	{ 0x1e34, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1e35, KEY_PLAY },
+	{ 0x1e36, KEY_STOP },
+	{ 0x1e37, KEY_RECORD },		/* recording */
+	{ 0x1e38, KEY_YELLOW },		/* yellow key */
+	{ 0x1e3b, KEY_SELECT },		/* top right button */
+	{ 0x1e3c, KEY_ZOOM },		/* full */
+	{ 0x1e3d, KEY_POWER },		/* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
+	.scan = ir_codes_rc5_hauppauge_new,
+	.size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
+	.ir_type = IR_TYPE_RC5,
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
+
+/* Terratec Cinergy Hybrid T USB XS FM
+   Mauro Carvalho Chehab <mchehab@redhat.com>
+ */
+static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
+	{ 0x1441, KEY_HOME},
+	{ 0x1401, KEY_POWER2},
+
+	{ 0x1442, KEY_MENU},		/* DVD menu */
+	{ 0x1443, KEY_SUBTITLE},
+	{ 0x1444, KEY_TEXT},		/* Teletext */
+	{ 0x1445, KEY_DELETE},
+
+	{ 0x1402, KEY_1},
+	{ 0x1403, KEY_2},
+	{ 0x1404, KEY_3},
+	{ 0x1405, KEY_4},
+	{ 0x1406, KEY_5},
+	{ 0x1407, KEY_6},
+	{ 0x1408, KEY_7},
+	{ 0x1409, KEY_8},
+	{ 0x140a, KEY_9},
+	{ 0x140c, KEY_0},
+
+	{ 0x140b, KEY_TUNER},		/* AV */
+	{ 0x140d, KEY_MODE},		/* A.B */
+
+	{ 0x1446, KEY_TV},
+	{ 0x1447, KEY_DVD},
+	{ 0x1449, KEY_VIDEO},
+	{ 0x144a, KEY_RADIO},		/* Music */
+	{ 0x144b, KEY_CAMERA},		/* PIC */
+
+	{ 0x1410, KEY_UP},
+	{ 0x1411, KEY_LEFT},
+	{ 0x1412, KEY_OK},
+	{ 0x1413, KEY_RIGHT},
+	{ 0x1414, KEY_DOWN},
+
+	{ 0x140f, KEY_EPG},
+	{ 0x1416, KEY_INFO},
+	{ 0x144d, KEY_BACKSPACE},
+
+	{ 0x141c, KEY_VOLUMEUP},
+	{ 0x141e, KEY_VOLUMEDOWN},
+
+	{ 0x144c, KEY_PLAY},
+	{ 0x141d, KEY_MUTE},
+
+	{ 0x141b, KEY_CHANNELUP},
+	{ 0x141f, KEY_CHANNELDOWN},
+
+	{ 0x1417, KEY_RED},
+	{ 0x1418, KEY_GREEN},
+	{ 0x1419, KEY_YELLOW},
+	{ 0x141a, KEY_BLUE},
+
+	{ 0x1458, KEY_RECORD},
+	{ 0x1448, KEY_STOP},
+	{ 0x1440, KEY_PAUSE},
+
+	{ 0x1454, KEY_LAST},
+	{ 0x144e, KEY_REWIND},
+	{ 0x144f, KEY_FASTFORWARD},
+	{ 0x145c, KEY_NEXT},
+};
+struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
+	.scan = ir_codes_nec_terratec_cinergy_xs,
+	.size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
+	.ir_type = IR_TYPE_NEC,
+};
+EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/IR/ir-keytable.c linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keytable.c
--- linux-libre-2.6.32-gnu1/drivers/media/IR/ir-keytable.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/IR/ir-keytable.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,485 @@
+/* ir-register.c - handle IR scancode->keycode tables
+ *
+ * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.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.
+ */
+
+
+#include <linux/input.h>
+#include <media/ir-common.h>
+
+#define IR_TAB_MIN_SIZE	32
+#define IR_TAB_MAX_SIZE	1024
+
+/**
+ * ir_seek_table() - returns the element order on the table
+ * @rc_tab:	the ir_scancode_table with the keymap to be used
+ * @scancode:	the scancode that we're seeking
+ *
+ * This routine is used by the input routines when a key is pressed at the
+ * IR. The scancode is received and needs to be converted into a keycode.
+ * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
+ * corresponding keycode from the table.
+ */
+static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
+{
+	int rc;
+	unsigned long flags;
+	struct ir_scancode *keymap = rc_tab->scan;
+
+	spin_lock_irqsave(&rc_tab->lock, flags);
+
+	/* FIXME: replace it by a binary search */
+
+	for (rc = 0; rc < rc_tab->size; rc++)
+		if (keymap[rc].scancode == scancode)
+			goto exit;
+
+	/* Not found */
+	rc = -EINVAL;
+
+exit:
+	spin_unlock_irqrestore(&rc_tab->lock, flags);
+	return rc;
+}
+
+/**
+ * ir_roundup_tablesize() - gets an optimum value for the table size
+ * @n_elems:		minimum number of entries to store keycodes
+ *
+ * This routine is used to choose the keycode table size.
+ *
+ * In order to have some empty space for new keycodes,
+ * and knowing in advance that kmalloc allocates only power of two
+ * segments, it optimizes the allocated space to have some spare space
+ * for those new keycodes by using the maximum number of entries that
+ * will be effectively be allocated by kmalloc.
+ * In order to reduce the quantity of table resizes, it has a minimum
+ * table size of IR_TAB_MIN_SIZE.
+ */
+int ir_roundup_tablesize(int n_elems)
+{
+	size_t size;
+
+	if (n_elems < IR_TAB_MIN_SIZE)
+		n_elems = IR_TAB_MIN_SIZE;
+
+	/*
+	 * As kmalloc only allocates sizes of power of two, get as
+	 * much entries as possible for the allocated memory segment
+	 */
+	size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
+	n_elems = size / sizeof(struct ir_scancode);
+
+	return n_elems;
+}
+EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
+
+/**
+ * ir_copy_table() - copies a keytable, discarding the unused entries
+ * @destin:	destin table
+ * @origin:	origin table
+ *
+ * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
+ */
+
+int ir_copy_table(struct ir_scancode_table *destin,
+		 const struct ir_scancode_table *origin)
+{
+	int i, j = 0;
+
+	for (i = 0; i < origin->size; i++) {
+		if (origin->scan[i].keycode == KEY_UNKNOWN ||
+		   origin->scan[i].keycode == KEY_RESERVED)
+			continue;
+
+		memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
+		j++;
+	}
+	destin->size = j;
+
+	IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ir_copy_table);
+
+/**
+ * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
+ * @dev:	the struct input_dev device descriptor
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ * This routine is used to handle evdev EVIOCGKEY ioctl.
+ * If the key is not found, returns -EINVAL, otherwise, returns 0.
+ */
+static int ir_getkeycode(struct input_dev *dev,
+			 int scancode, int *keycode)
+{
+	int elem;
+	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+	struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+
+	elem = ir_seek_table(rc_tab, scancode);
+	if (elem >= 0) {
+		*keycode = rc_tab->scan[elem].keycode;
+		return 0;
+	}
+
+	/*
+	 * Scancode not found and table can't be expanded
+	 */
+	if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
+		return -EINVAL;
+
+	/*
+	 * If is there extra space, returns KEY_RESERVED,
+	 * otherwise, input core won't let ir_setkeycode to work
+	 */
+	*keycode = KEY_RESERVED;
+	return 0;
+}
+
+/**
+ * ir_is_resize_needed() - Check if the table needs rezise
+ * @table:		keycode table that may need to resize
+ * @n_elems:		minimum number of entries to store keycodes
+ *
+ * Considering that kmalloc uses power of two storage areas, this
+ * routine detects if the real alloced size will change. If not, it
+ * just returns without doing nothing. Otherwise, it will extend or
+ * reduce the table size to meet the new needs.
+ *
+ * It returns 0 if no resize is needed, 1 otherwise.
+ */
+static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
+{
+	int cur_size = ir_roundup_tablesize(table->size);
+	int new_size = ir_roundup_tablesize(n_elems);
+
+	if (cur_size == new_size)
+		return 0;
+
+	/* Resize is needed */
+	return 1;
+}
+
+/**
+ * ir_delete_key() - remove a keycode from the table
+ * @rc_tab:		keycode table
+ * @elem:		element to be removed
+ *
+ */
+static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
+{
+	unsigned long flags = 0;
+	int newsize = rc_tab->size - 1;
+	int resize = ir_is_resize_needed(rc_tab, newsize);
+	struct ir_scancode *oldkeymap = rc_tab->scan;
+	struct ir_scancode *newkeymap;
+
+	if (resize) {
+		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
+				    sizeof(*newkeymap), GFP_ATOMIC);
+
+		/* There's no memory for resize. Keep the old table */
+		if (!newkeymap)
+			resize = 0;
+	}
+
+	if (!resize) {
+		newkeymap = oldkeymap;
+
+		/* We'll modify the live table. Lock it */
+		spin_lock_irqsave(&rc_tab->lock, flags);
+	}
+
+	/*
+	 * Copy the elements before the one that will be deleted
+	 * if (!resize), both oldkeymap and newkeymap points
+	 * to the same place, so, there's no need to copy
+	 */
+	if (resize && elem > 0)
+		memcpy(newkeymap, oldkeymap,
+		       elem * sizeof(*newkeymap));
+
+	/*
+	 * Copy the other elements overwriting the element to be removed
+	 * This operation applies to both resize and non-resize case
+	 */
+	if (elem < newsize)
+		memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
+		       (newsize - elem) * sizeof(*newkeymap));
+
+	if (resize) {
+		/*
+		 * As the copy happened to a temporary table, only here
+		 * it needs to lock while replacing the table pointers
+		 * to use the new table
+		 */
+		spin_lock_irqsave(&rc_tab->lock, flags);
+		rc_tab->size = newsize;
+		rc_tab->scan = newkeymap;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+		/* Frees the old keytable */
+		kfree(oldkeymap);
+	} else {
+		rc_tab->size = newsize;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+	}
+}
+
+/**
+ * ir_insert_key() - insert a keycode at the table
+ * @rc_tab:		keycode table
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ */
+static int ir_insert_key(struct ir_scancode_table *rc_tab,
+			  int scancode, int keycode)
+{
+	unsigned long flags;
+	int elem = rc_tab->size;
+	int newsize = rc_tab->size + 1;
+	int resize = ir_is_resize_needed(rc_tab, newsize);
+	struct ir_scancode *oldkeymap = rc_tab->scan;
+	struct ir_scancode *newkeymap;
+
+	if (resize) {
+		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
+				    sizeof(*newkeymap), GFP_ATOMIC);
+		if (!newkeymap)
+			return -ENOMEM;
+
+		memcpy(newkeymap, oldkeymap,
+		       rc_tab->size * sizeof(*newkeymap));
+	} else
+		newkeymap  = oldkeymap;
+
+	/* Stores the new code at the table */
+	IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
+		   rc_tab->size, scancode, keycode);
+
+	spin_lock_irqsave(&rc_tab->lock, flags);
+	rc_tab->size = newsize;
+	if (resize) {
+		rc_tab->scan = newkeymap;
+		kfree(oldkeymap);
+	}
+	newkeymap[elem].scancode = scancode;
+	newkeymap[elem].keycode  = keycode;
+	spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+	return 0;
+}
+
+/**
+ * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
+ * @dev:	the struct input_dev device descriptor
+ * @scancode:	the desired scancode
+ * @keycode:	the keycode to be retorned.
+ *
+ * This routine is used to handle evdev EVIOCSKEY ioctl.
+ * There's one caveat here: how can we increase the size of the table?
+ * If the key is not found, returns -EINVAL, otherwise, returns 0.
+ */
+static int ir_setkeycode(struct input_dev *dev,
+			 int scancode, int keycode)
+{
+	int rc = 0;
+	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+	struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+	struct ir_scancode *keymap = rc_tab->scan;
+	unsigned long flags;
+
+	/*
+	 * Handle keycode table deletions
+	 *
+	 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
+	 * deal as a trial to remove an existing scancode attribution
+	 * if table become too big, reduce it to save space
+	 */
+	if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
+		rc = ir_seek_table(rc_tab, scancode);
+		if (rc < 0)
+			return 0;
+
+		IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
+		clear_bit(keymap[rc].keycode, dev->keybit);
+		ir_delete_key(rc_tab, rc);
+
+		return 0;
+	}
+
+	/*
+	 * Handle keycode replacements
+	 *
+	 * If the scancode exists, just replace by the new value
+	 */
+	rc = ir_seek_table(rc_tab, scancode);
+	if (rc >= 0) {
+		IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
+			rc, scancode, keycode);
+
+		clear_bit(keymap[rc].keycode, dev->keybit);
+
+		spin_lock_irqsave(&rc_tab->lock, flags);
+		keymap[rc].keycode = keycode;
+		spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+		set_bit(keycode, dev->keybit);
+
+		return 0;
+	}
+
+	/*
+	 * Handle new scancode inserts
+	 *
+	 * reallocate table if needed and insert a new keycode
+	 */
+
+	/* Avoid growing the table indefinitely */
+	if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
+		return -EINVAL;
+
+	rc = ir_insert_key(rc_tab, scancode, keycode);
+	if (rc < 0)
+		return rc;
+	set_bit(keycode, dev->keybit);
+
+	return 0;
+}
+
+/**
+ * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @scancode:	the scancode that we're seeking
+ *
+ * This routine is used by the input routines when a key is pressed at the
+ * IR. The scancode is received and needs to be converted into a keycode.
+ * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
+ * corresponding keycode from the table.
+ */
+u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+	struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+	struct ir_scancode *keymap = rc_tab->scan;
+	int elem;
+
+	elem = ir_seek_table(rc_tab, scancode);
+	if (elem >= 0) {
+		IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
+			   dev->name, scancode, keymap[elem].keycode);
+
+		return rc_tab->scan[elem].keycode;
+	}
+
+	printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
+	       dev->name, scancode);
+
+	/* Reports userspace that an unknown keycode were got */
+	return KEY_RESERVED;
+}
+EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
+
+/**
+ * ir_input_register() - sets the IR keycode table and add the handlers
+ *			    for keymap table get/set
+ * @input_dev:	the struct input_dev descriptor of the device
+ * @rc_tab:	the struct ir_scancode_table table of scancode/keymap
+ *
+ * This routine is used to initialize the input infrastructure to work with
+ * an IR.
+ * It should be called before registering the IR device.
+ */
+int ir_input_register(struct input_dev *input_dev,
+		      struct ir_scancode_table *rc_tab)
+{
+	struct ir_input_dev *ir_dev;
+	struct ir_scancode  *keymap    = rc_tab->scan;
+	int i, rc;
+
+	if (rc_tab->scan == NULL || !rc_tab->size)
+		return -EINVAL;
+
+	ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
+	if (!ir_dev)
+		return -ENOMEM;
+
+	spin_lock_init(&rc_tab->lock);
+
+	ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
+	ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
+				    sizeof(struct ir_scancode), GFP_KERNEL);
+	if (!ir_dev->rc_tab.scan)
+		return -ENOMEM;
+
+	IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
+		ir_dev->rc_tab.size,
+		ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
+
+	ir_copy_table(&ir_dev->rc_tab, rc_tab);
+
+	/* set the bits for the keys */
+	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
+	for (i = 0; i < rc_tab->size; i++) {
+		IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
+			i, keymap[i].keycode);
+		set_bit(keymap[i].keycode, input_dev->keybit);
+	}
+	clear_bit(0, input_dev->keybit);
+
+	set_bit(EV_KEY, input_dev->evbit);
+
+	input_dev->getkeycode = ir_getkeycode;
+	input_dev->setkeycode = ir_setkeycode;
+	input_set_drvdata(input_dev, ir_dev);
+
+	rc = input_register_device(input_dev);
+	if (rc < 0) {
+		kfree(rc_tab->scan);
+		kfree(ir_dev);
+		input_set_drvdata(input_dev, NULL);
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ir_input_register);
+
+void ir_input_unregister(struct input_dev *dev)
+{
+	struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+	struct ir_scancode_table *rc_tab;
+
+	if (!ir_dev)
+		return;
+
+	IR_dprintk(1, "Freed keycode table\n");
+
+	rc_tab = &ir_dev->rc_tab;
+	rc_tab->size = 0;
+	kfree(rc_tab->scan);
+	rc_tab->scan = NULL;
+
+	kfree(ir_dev);
+	input_unregister_device(dev);
+}
+EXPORT_SYMBOL_GPL(ir_input_unregister);
+
+int ir_core_debug;    /* ir_debug level (0,1,2) */
+EXPORT_SYMBOL_GPL(ir_core_debug);
+module_param_named(debug, ir_core_debug, int, 0644);
+
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/IR/Kconfig linux-libre-2.6.33-gnu1/drivers/media/IR/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/IR/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/IR/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,9 @@
+config IR_CORE
+	tristate
+	depends on INPUT
+	default INPUT
+
+config VIDEO_IR
+	tristate
+	depends on IR_CORE
+	default IR_CORE
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/IR/Makefile linux-libre-2.6.33-gnu1/drivers/media/IR/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/IR/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/IR/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+ir-common-objs  := ir-functions.o ir-keymaps.o
+ir-core-objs	:= ir-keytable.o
+
+obj-$(CONFIG_IR_CORE) += ir-core.o
+obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/Kconfig linux-libre-2.6.33-gnu1/drivers/media/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -99,6 +99,7 @@ config VIDEO_MEDIA
 comment "Multimedia drivers"
 
 source "drivers/media/common/Kconfig"
+source "drivers/media/IR/Kconfig"
 
 #
 # Tuner drivers for DVB and V4L
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/Makefile linux-libre-2.6.33-gnu1/drivers/media/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y += common/ video/
+obj-y += common/ IR/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
 obj-$(CONFIG_DVB_CORE)  += dvb/
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/Kconfig linux-libre-2.6.33-gnu1/drivers/media/radio/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/radio/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -195,14 +195,30 @@ config RADIO_MAESTRO
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-maestro.
 
+config RADIO_MIROPCM20
+	tristate "miroSOUND PCM20 radio"
+	depends on ISA && VIDEO_V4L2 && SND
+	select SND_ISA
+	select SND_MIRO
+	---help---
+	  Choose Y here if you have this FM radio card. You also need to enable
+	  the ALSA sound system. This choice automatically selects the ALSA
+	  sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
+	  is required for the radio-miropcm20.
+
+	  In order to control your radio card, you will need to use programs
+	  that are compatible with the Video For Linux API.  Information on
+	  this API and pointers to "v4l" programs may be found at
+	  <file:Documentation/video4linux/API.html>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-miropcm20.
+
 config RADIO_SF16FMI
-	tristate "SF16FMI Radio"
+	tristate "SF16-FMI/SF16-FMP Radio"
 	depends on ISA && VIDEO_V4L2
 	---help---
-	  Choose Y here if you have one of these FM radio cards.  If you
-	  compile the driver into the kernel and your card is not PnP one, you
-	  have to add "sf16fm=<io>" to the kernel command line (I/O address is
-	  0x284 or 0x384).
+	  Choose Y here if you have one of these FM radio cards.
 
 	  In order to control your radio card, you will need to use programs
 	  that are compatible with the Video For Linux API.  Information on
@@ -401,4 +417,16 @@ config RADIO_TEA5764_XTAL
 	  Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
 	  here if TEA5764 reference frequency is connected in FREQIN.
 
+config RADIO_TEF6862
+	tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the TEF6862 Car Radio Enhanced
+	  Selectivity Tuner, found for instance on the Russellville development
+	  board. On the russellville the device is connected to internal
+	  timberdale I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called TEF6862.
+
 endif # RADIO_ADAPTERS
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/Makefile linux-libre-2.6.33-gnu1/drivers/media/radio/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/radio/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -18,9 +18,11 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust
 obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
 obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
 obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
+obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
 obj-$(CONFIG_USB_DSBR) += dsbr100.o
 obj-$(CONFIG_RADIO_SI470X) += si470x/
 obj-$(CONFIG_USB_MR800) += radio-mr800.o
 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
+obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
 
 EXTRA_CFLAGS += -Isound
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-aimslab.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-aimslab.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-aimslab.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-aimslab.c	2010-02-24 13:52:17.000000000 -0500
@@ -268,6 +268,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct rtrack *rt = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	rt_setfreq(rt, f->frequency);
 	return 0;
 }
@@ -277,6 +279,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct rtrack *rt = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = rt->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-aztech.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-aztech.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-aztech.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-aztech.c	2010-02-24 13:52:17.000000000 -0500
@@ -254,6 +254,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct aztech *az = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	az_setfreq(az, f->frequency);
 	return 0;
 }
@@ -263,6 +265,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct aztech *az = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = az->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-gemtek-pci.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-gemtek-pci.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-gemtek-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-gemtek-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct gemtek_pci *card = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
 	    f->frequency > GEMTEK_PCI_RANGE_HIGH)
 		return -EINVAL;
@@ -253,6 +255,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct gemtek_pci *card = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = card->current_frequency;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-maestro.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maestro.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-maestro.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maestro.c	2010-02-24 13:52:17.000000000 -0500
@@ -200,6 +200,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct maestro *dev = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
 		return -EINVAL;
 	mutex_lock(&dev->lock);
@@ -213,6 +215,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct maestro *dev = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	mutex_lock(&dev->lock);
 	f->frequency = BITS2FREQ(radio_bits_get(dev));
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-maxiradio.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maxiradio.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-maxiradio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-maxiradio.c	2010-02-24 13:52:17.000000000 -0500
@@ -262,6 +262,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct maxiradio *dev = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
 		dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
 					f->frequency / 16000,
@@ -285,6 +287,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct maxiradio *dev = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = dev->freq;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-miropcm20.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-miropcm20.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-miropcm20.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-miropcm20.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,270 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer provided by the snd-miro
+ * ALSA driver.
+ * Look there for further info...
+ */
+
+/* What ever you think about the ACI, version 0x07 is not very well!
+ * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * conditions...                Robert
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <sound/aci.h>
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX).  Default: -1 (autodetect)");
+
+static int mono;
+module_param(mono, bool, 0);
+MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
+
+struct pcm20 {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	unsigned long freq;
+	int muted;
+	struct snd_miro_aci *aci;
+};
+
+static struct pcm20 pcm20_card = {
+	.freq   = 87*16000,
+	.muted  = 1,
+};
+
+static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
+{
+	dev->muted = mute;
+	return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
+}
+
+static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
+{
+	return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
+}
+
+static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
+{
+	unsigned char freql;
+	unsigned char freqh;
+	struct snd_miro_aci *aci = dev->aci;
+
+	dev->freq = freq;
+
+	freq /= 160;
+	if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
+		freq /= 10;  /* I don't know exactly which version
+			      * needs this hack */
+	freql = freq & 0xff;
+	freqh = freq >> 8;
+
+	pcm20_stereo(dev, !mono);
+	return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
+}
+
+static const struct v4l2_file_operations pcm20_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= video_ioctl2,
+};
+
+static int vidioc_querycap(struct file *file, void *priv,
+				struct v4l2_capability *v)
+{
+	strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
+	strlcpy(v->card, "Miro PCM20", sizeof(v->card));
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
+	v->version = 0x1;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+				struct v4l2_tuner *v)
+{
+	if (v->index)	/* Only 1 tuner */
+		return -EINVAL;
+	strlcpy(v->name, "FM", sizeof(v->name));
+	v->type = V4L2_TUNER_RADIO;
+	v->rangelow = 87*16000;
+	v->rangehigh = 108*16000;
+	v->signal = 0xffff;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	v->audmode = V4L2_TUNER_MODE_MONO;
+	return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+				struct v4l2_tuner *v)
+{
+	return v->index ? -EINVAL : 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct pcm20 *dev = video_drvdata(file);
+
+	if (f->tuner != 0)
+		return -EINVAL;
+
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = dev->freq;
+	return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct pcm20 *dev = video_drvdata(file);
+
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+
+	dev->freq = f->frequency;
+	pcm20_setfreq(dev, f->frequency);
+	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 pcm20 *dev = video_drvdata(file);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = dev->muted;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+				struct v4l2_control *ctrl)
+{
+	struct pcm20 *dev = video_drvdata(file);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		pcm20_mute(dev, ctrl->value);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+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,
+				struct v4l2_audio *a)
+{
+	return a->index ? -EINVAL : 0;
+}
+
+static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
+	.vidioc_querycap    = vidioc_querycap,
+	.vidioc_g_tuner     = vidioc_g_tuner,
+	.vidioc_s_tuner     = vidioc_s_tuner,
+	.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_g_audio     = vidioc_g_audio,
+	.vidioc_s_audio     = vidioc_s_audio,
+	.vidioc_g_input     = vidioc_g_input,
+	.vidioc_s_input     = vidioc_s_input,
+};
+
+static int __init pcm20_init(void)
+{
+	struct pcm20 *dev = &pcm20_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
+
+	dev->aci = snd_aci_get_aci();
+	if (dev->aci == NULL) {
+		v4l2_err(v4l2_dev,
+			 "you must load the snd-miro driver first!\n");
+		return -ENODEV;
+	}
+	strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
+
+
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+		return -EINVAL;
+	}
+
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &pcm20_fops;
+	dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
+
+	if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
+		goto fail;
+
+	v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
+	return 0;
+fail:
+	v4l2_device_unregister(v4l2_dev);
+	return -EINVAL;
+}
+
+MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+MODULE_LICENSE("GPL");
+
+static void __exit pcm20_cleanup(void)
+{
+	struct pcm20 *dev = &pcm20_card;
+
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+}
+
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-mr800.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-mr800.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-mr800.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-mr800.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@
  * http://av-usbradio.sourceforge.net/index.php
  * http://sourceforge.net/projects/av-usbradio/
  * Latest release of theirs project was in 2005.
- * Probably, this driver could be improved trough using their
+ * Probably, this driver could be improved through using their
  * achievements (specifications given).
  * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
  * in 2007. He allowed to use his driver to improve current mr800 radio driver.
@@ -85,6 +85,9 @@ MODULE_LICENSE("GPL");
 #define amradio_dev_warn(dev, fmt, arg...)				\
 		dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
 
+#define amradio_dev_err(dev, fmt, arg...) \
+		dev_err(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
+
 /* Probably USB_TIMEOUT should be modified in module parameter */
 #define BUFFER_LENGTH 8
 #define USB_TIMEOUT 500
@@ -129,18 +132,20 @@ static int usb_amradio_resume(struct usb
 struct amradio_device {
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
-	struct video_device *videodev;
+	struct usb_interface *intf;
+	struct video_device videodev;
 	struct v4l2_device v4l2_dev;
 
 	unsigned char *buffer;
 	struct mutex lock;	/* buffer locking */
 	int curfreq;
 	int stereo;
-	int users;
-	int removed;
 	int muted;
+	int initialized;
 };
 
+#define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev)
+
 /* USB Device ID List */
 static struct usb_device_id usb_amradio_device_table[] = {
 	{USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
@@ -159,7 +164,7 @@ static struct usb_driver usb_amradio_dri
 	.resume			= usb_amradio_resume,
 	.reset_resume		= usb_amradio_resume,
 	.id_table		= usb_amradio_device_table,
-	.supports_autosuspend	= 0,
+	.supports_autosuspend	= 1,
 };
 
 /* switch on/off the radio. Send 8 bytes to device */
@@ -168,11 +173,7 @@ static int amradio_set_mute(struct amrad
 	int retval;
 	int size;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -187,14 +188,12 @@ static int amradio_set_mute(struct amrad
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
 	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
+		amradio_dev_warn(&radio->videodev.dev, "set mute failed\n");
 		return retval;
 	}
 
 	radio->muted = argument;
 
-	mutex_unlock(&radio->lock);
-
 	return retval;
 }
 
@@ -205,11 +204,7 @@ static int amradio_setfreq(struct amradi
 	int size;
 	unsigned short freq_send = 0x10 + (freq >> 3) / 25;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -223,10 +218,8 @@ static int amradio_setfreq(struct amradi
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
-		return retval;
-	}
+	if (retval < 0 || size != BUFFER_LENGTH)
+		goto out_err;
 
 	/* frequency is calculated from freq_send and placed in first 2 bytes */
 	radio->buffer[0] = (freq_send >> 8) & 0xff;
@@ -240,13 +233,15 @@ static int amradio_setfreq(struct amradi
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval < 0 || size != BUFFER_LENGTH) {
-		mutex_unlock(&radio->lock);
-		return retval;
-	}
+	if (retval < 0 || size != BUFFER_LENGTH)
+		goto out_err;
 
-	mutex_unlock(&radio->lock);
+	radio->curfreq = freq;
+	goto out;
 
+out_err:
+	amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n");
+out:
 	return retval;
 }
 
@@ -255,11 +250,7 @@ static int amradio_set_stereo(struct amr
 	int retval;
 	int size;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
+	BUG_ON(!mutex_is_locked(&radio->lock));
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
@@ -274,14 +265,14 @@ static int amradio_set_stereo(struct amr
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
 	if (retval < 0 || size != BUFFER_LENGTH) {
-		radio->stereo = -1;
-		mutex_unlock(&radio->lock);
+		amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n");
 		return retval;
 	}
 
-	radio->stereo = 1;
-
-	mutex_unlock(&radio->lock);
+	if (argument == WANT_STEREO)
+		radio->stereo = 1;
+	else
+		radio->stereo = 0;
 
 	return retval;
 }
@@ -296,19 +287,19 @@ static void usb_amradio_disconnect(struc
 	struct amradio_device *radio = usb_get_intfdata(intf);
 
 	mutex_lock(&radio->lock);
-	radio->removed = 1;
+	radio->usbdev = NULL;
 	mutex_unlock(&radio->lock);
 
 	usb_set_intfdata(intf, NULL);
-	video_unregister_device(radio->videodev);
 	v4l2_device_disconnect(&radio->v4l2_dev);
+	video_unregister_device(&radio->videodev);
 }
 
 /* vidioc_querycap - query device capabilities */
 static int vidioc_querycap(struct file *file, void *priv,
 					struct v4l2_capability *v)
 {
-	struct amradio_device *radio = video_drvdata(file);
+	struct amradio_device *radio = file->private_data;
 
 	strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
 	strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
@@ -322,13 +313,9 @@ static int vidioc_querycap(struct file *
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	struct amradio_device *radio = file->private_data;
 	int retval;
 
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
 	if (v->index > 0)
 		return -EINVAL;
 
@@ -341,9 +328,6 @@ static int vidioc_g_tuner(struct file *f
  * amradio_set_stereo shouldn't be here
  */
 	retval = amradio_set_stereo(radio, WANT_STEREO);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set stereo failed\n");
 
 	strcpy(v->name, "FM");
 	v->type = V4L2_TUNER_RADIO;
@@ -357,19 +341,16 @@ static int vidioc_g_tuner(struct file *f
 		v->audmode = V4L2_TUNER_MODE_MONO;
 	v->signal = 0xffff;     /* Can't get the signal strength, sad.. */
 	v->afc = 0; /* Don't know what is this */
-	return 0;
+
+	return retval;
 }
 
 /* vidioc_s_tuner - set tuner attributes */
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
+	int retval = -EINVAL;
 
 	if (v->index > 0)
 		return -EINVAL;
@@ -378,57 +359,37 @@ static int vidioc_s_tuner(struct file *f
 	switch (v->audmode) {
 	case V4L2_TUNER_MODE_MONO:
 		retval = amradio_set_stereo(radio, WANT_MONO);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"set mono failed\n");
 		break;
 	case V4L2_TUNER_MODE_STEREO:
 		retval = amradio_set_stereo(radio, WANT_STEREO);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"set stereo failed\n");
 		break;
-	default:
-		return -EINVAL;
 	}
 
-	return 0;
+	return retval;
 }
 
 /* vidioc_s_frequency - set tuner radio frequency */
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
-
-	mutex_lock(&radio->lock);
-	radio->curfreq = f->frequency;
-	mutex_unlock(&radio->lock);
+	struct amradio_device *radio = file->private_data;
 
-	retval = amradio_setfreq(radio, radio->curfreq);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set frequency failed\n");
-	return 0;
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+	return amradio_setfreq(radio, f->frequency);
 }
 
 /* vidioc_g_frequency - get tuner radio frequency */
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = radio->curfreq;
+
 	return 0;
 }
 
@@ -448,17 +409,14 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		ctrl->value = radio->muted;
 		return 0;
 	}
+
 	return -EINVAL;
 }
 
@@ -466,33 +424,20 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	/* safety check */
-	if (radio->removed)
-		return -EIO;
+	struct amradio_device *radio = file->private_data;
+	int retval = -EINVAL;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value) {
+		if (ctrl->value)
 			retval = amradio_set_mute(radio, AMRADIO_STOP);
-			if (retval < 0) {
-				amradio_dev_warn(&radio->videodev->dev,
-					"amradio_stop failed\n");
-				return -1;
-			}
-		} else {
+		else
 			retval = amradio_set_mute(radio, AMRADIO_START);
-			if (retval < 0) {
-				amradio_dev_warn(&radio->videodev->dev,
-					"amradio_start failed\n");
-				return -1;
-			}
-		}
-		return 0;
+
+		break;
 	}
-	return -EINVAL;
+
+	return retval;
 }
 
 /* vidioc_g_audio - get audio attributes */
@@ -531,75 +476,108 @@ static int vidioc_s_input(struct file *f
 	return 0;
 }
 
-/* open device - amradio_start() and amradio_setfreq() */
-static int usb_amradio_open(struct file *file)
+static int usb_amradio_init(struct amradio_device *radio)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
 	int retval;
 
-	lock_kernel();
+	retval = amradio_set_mute(radio, AMRADIO_STOP);
+	if (retval)
+		goto out_err;
 
-	radio->users = 1;
-	radio->muted = 1;
+	retval = amradio_set_stereo(radio, WANT_STEREO);
+	if (retval)
+		goto out_err;
 
-	retval = amradio_set_mute(radio, AMRADIO_START);
-	if (retval < 0) {
-		amradio_dev_warn(&radio->videodev->dev,
-			"radio did not start up properly\n");
-		radio->users = 0;
-		unlock_kernel();
-		return -EIO;
+	radio->initialized = 1;
+	goto out;
+
+out_err:
+	amradio_dev_err(&radio->videodev.dev, "initialization failed\n");
+out:
+	return retval;
+}
+
+/* open device - amradio_start() and amradio_setfreq() */
+static int usb_amradio_open(struct file *file)
+{
+	struct amradio_device *radio = vdev_to_amradio(video_devdata(file));
+	int retval = 0;
+
+	mutex_lock(&radio->lock);
+
+	if (!radio->usbdev) {
+		retval = -EIO;
+		goto unlock;
 	}
 
-	retval = amradio_set_stereo(radio, WANT_STEREO);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set stereo failed\n");
+	file->private_data = radio;
+	retval = usb_autopm_get_interface(radio->intf);
+	if (retval)
+		goto unlock;
 
-	retval = amradio_setfreq(radio, radio->curfreq);
-	if (retval < 0)
-		amradio_dev_warn(&radio->videodev->dev,
-			"set frequency failed\n");
+	if (unlikely(!radio->initialized)) {
+		retval = usb_amradio_init(radio);
+		if (retval)
+			usb_autopm_put_interface(radio->intf);
+	}
 
-	unlock_kernel();
-	return 0;
+unlock:
+	mutex_unlock(&radio->lock);
+	return retval;
 }
 
 /*close device */
 static int usb_amradio_close(struct file *file)
 {
-	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
-	int retval;
-
-	if (!radio)
-		return -ENODEV;
+	struct amradio_device *radio = file->private_data;
+	int retval = 0;
 
 	mutex_lock(&radio->lock);
-	radio->users = 0;
+
+	if (!radio->usbdev)
+		retval = -EIO;
+	else
+		usb_autopm_put_interface(radio->intf);
+
 	mutex_unlock(&radio->lock);
+	return retval;
+}
 
-	if (!radio->removed) {
-		retval = amradio_set_mute(radio, AMRADIO_STOP);
-		if (retval < 0)
-			amradio_dev_warn(&radio->videodev->dev,
-				"amradio_stop failed\n");
+static long usb_amradio_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	struct amradio_device *radio = file->private_data;
+	long retval = 0;
+
+	mutex_lock(&radio->lock);
+
+	if (!radio->usbdev) {
+		retval = -EIO;
+		goto unlock;
 	}
 
-	return 0;
+	retval = video_ioctl2(file, cmd, arg);
+
+unlock:
+	mutex_unlock(&radio->lock);
+	return retval;
 }
 
 /* Suspend device - stop device. Need to be checked and fixed */
 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
 
-	retval = amradio_set_mute(radio, AMRADIO_STOP);
-	if (retval < 0)
-		dev_warn(&intf->dev, "amradio_stop failed\n");
+	mutex_lock(&radio->lock);
+
+	if (!radio->muted && radio->initialized) {
+		amradio_set_mute(radio, AMRADIO_STOP);
+		radio->muted = 0;
+	}
 
 	dev_info(&intf->dev, "going into suspend..\n");
 
+	mutex_unlock(&radio->lock);
 	return 0;
 }
 
@@ -607,14 +585,26 @@ static int usb_amradio_suspend(struct us
 static int usb_amradio_resume(struct usb_interface *intf)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
-	int retval;
 
-	retval = amradio_set_mute(radio, AMRADIO_START);
-	if (retval < 0)
-		dev_warn(&intf->dev, "amradio_start failed\n");
+	mutex_lock(&radio->lock);
+
+	if (unlikely(!radio->initialized))
+		goto unlock;
 
+	if (radio->stereo)
+		amradio_set_stereo(radio, WANT_STEREO);
+	else
+		amradio_set_stereo(radio, WANT_MONO);
+
+	amradio_setfreq(radio, radio->curfreq);
+
+	if (!radio->muted)
+		amradio_set_mute(radio, AMRADIO_START);
+
+unlock:
 	dev_info(&intf->dev, "coming out of suspend..\n");
 
+	mutex_unlock(&radio->lock);
 	return 0;
 }
 
@@ -623,7 +613,7 @@ static const struct v4l2_file_operations
 	.owner		= THIS_MODULE,
 	.open		= usb_amradio_open,
 	.release	= usb_amradio_close,
-	.ioctl		= video_ioctl2,
+	.ioctl		= usb_amradio_ioctl,
 };
 
 static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
@@ -643,10 +633,7 @@ static const struct v4l2_ioctl_ops usb_a
 
 static void usb_amradio_video_device_release(struct video_device *videodev)
 {
-	struct amradio_device *radio = video_get_drvdata(videodev);
-
-	/* we call v4l to free radio->videodev */
-	video_device_release(videodev);
+	struct amradio_device *radio = vdev_to_amradio(videodev);
 
 	v4l2_device_unregister(&radio->v4l2_dev);
 
@@ -660,70 +647,63 @@ static int usb_amradio_probe(struct usb_
 				const struct usb_device_id *id)
 {
 	struct amradio_device *radio;
-	struct v4l2_device *v4l2_dev;
-	int retval;
+	int retval = 0;
 
 	radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
 
 	if (!radio) {
 		dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err;
 	}
 
 	radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
 
 	if (!radio->buffer) {
 		dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
-		kfree(radio);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_nobuf;
 	}
 
-	v4l2_dev = &radio->v4l2_dev;
-	retval = v4l2_device_register(&intf->dev, v4l2_dev);
+	retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
 	if (retval < 0) {
 		dev_err(&intf->dev, "couldn't register v4l2_device\n");
-		kfree(radio->buffer);
-		kfree(radio);
-		return retval;
-	}
-
-	radio->videodev = video_device_alloc();
-
-	if (!radio->videodev) {
-		dev_err(&intf->dev, "video_device_alloc failed\n");
-		kfree(radio->buffer);
-		kfree(radio);
-		return -ENOMEM;
+		goto err_v4l2;
 	}
 
-	strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
-	radio->videodev->v4l2_dev = v4l2_dev;
-	radio->videodev->fops = &usb_amradio_fops;
-	radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
-	radio->videodev->release = usb_amradio_video_device_release;
+	strlcpy(radio->videodev.name, radio->v4l2_dev.name,
+		sizeof(radio->videodev.name));
+	radio->videodev.v4l2_dev = &radio->v4l2_dev;
+	radio->videodev.fops = &usb_amradio_fops;
+	radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops;
+	radio->videodev.release = usb_amradio_video_device_release;
 
-	radio->removed = 0;
-	radio->users = 0;
 	radio->usbdev = interface_to_usbdev(intf);
+	radio->intf = intf;
 	radio->curfreq = 95.16 * FREQ_MUL;
-	radio->stereo = -1;
 
 	mutex_init(&radio->lock);
 
-	video_set_drvdata(radio->videodev, radio);
+	video_set_drvdata(&radio->videodev, radio);
 
-	retval = video_register_device(radio->videodev,	VFL_TYPE_RADIO,	radio_nr);
+	retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
+					radio_nr);
 	if (retval < 0) {
 		dev_err(&intf->dev, "could not register video device\n");
-		video_device_release(radio->videodev);
-		v4l2_device_unregister(v4l2_dev);
-		kfree(radio->buffer);
-		kfree(radio);
-		return -EIO;
+		goto err_vdev;
 	}
 
 	usb_set_intfdata(intf, radio);
 	return 0;
+
+err_vdev:
+	v4l2_device_unregister(&radio->v4l2_dev);
+err_v4l2:
+	kfree(radio->buffer);
+err_nobuf:
+	kfree(radio);
+err:
+	return retval;
 }
 
 static int __init amradio_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-rtrack2.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-rtrack2.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-rtrack2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-rtrack2.c	2010-02-24 13:52:17.000000000 -0500
@@ -167,6 +167,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct rtrack2 *rt = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	rt_setfreq(rt, f->frequency);
 	return 0;
 }
@@ -176,6 +178,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct rtrack2 *rt = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = rt->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-sf16fmi.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-sf16fmi.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-sf16fmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-sf16fmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,4 @@
-/* SF16FMI radio driver for Linux radio support
+/* SF16-FMI and SF16-FMP radio driver for Linux radio support
  * heavily based on rtrack driver...
  * (c) 1997 M. Kirkwood
  * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
@@ -11,7 +11,7 @@
  *
  *  Frequency control is done digitally -- ie out(port,encodefreq(95.8));
  *  No volume control - only mute/unmute - you have to use line volume
- *  control on SB-part of SF16FMI
+ *  control on SB-part of SF16-FMI/SF16-FMP
  *
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  */
@@ -30,14 +30,14 @@
 #include <media/v4l2-ioctl.h>
 
 MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio.");
 MODULE_LICENSE("GPL");
 
 static int io = -1;
 static int radio_nr = -1;
 
 module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)");
 module_param(radio_nr, int, 0);
 
 #define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
@@ -47,13 +47,14 @@ struct fmi
 	struct v4l2_device v4l2_dev;
 	struct video_device vdev;
 	int io;
-	int curvol; /* 1 or 0 */
+	bool mute;
 	unsigned long curfreq; /* freq in kHz */
 	struct mutex lock;
 };
 
 static struct fmi fmi_card;
 static struct pnp_dev *dev;
+bool pnp_attached;
 
 /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
 /* It is only useful to give freq in interval of 800 (=0.05Mhz),
@@ -105,7 +106,7 @@ static inline int fmi_setfreq(struct fmi
 	outbits(8, 0xC0, fmi->io);
 	msleep(143);		/* was schedule_timeout(HZ/7) */
 	mutex_unlock(&fmi->lock);
-	if (fmi->curvol)
+	if (!fmi->mute)
 		fmi_unmute(fmi);
 	return 0;
 }
@@ -116,7 +117,7 @@ static inline int fmi_getsigstr(struct f
 	int res;
 
 	mutex_lock(&fmi->lock);
-	val = fmi->curvol ? 0x08 : 0x00;	/* unmute/mute */
+	val = fmi->mute ? 0x00 : 0x08;	/* mute/unmute */
 	outb(val, fmi->io);
 	outb(val | 0x10, fmi->io);
 	msleep(143); 		/* was schedule_timeout(HZ/7) */
@@ -168,6 +169,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct fmi *fmi = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (f->frequency < RSF16_MINFREQ ||
 			f->frequency > RSF16_MAXFREQ)
 		return -EINVAL;
@@ -182,6 +185,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct fmi *fmi = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = fmi->curfreq;
 	return 0;
@@ -204,7 +209,7 @@ static int vidioc_g_ctrl(struct file *fi
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = fmi->curvol;
+		ctrl->value = fmi->mute;
 		return 0;
 	}
 	return -EINVAL;
@@ -221,7 +226,7 @@ static int vidioc_s_ctrl(struct file *fi
 			fmi_mute(fmi);
 		else
 			fmi_unmute(fmi);
-		fmi->curvol = ctrl->value;
+		fmi->mute = ctrl->value;
 		return 0;
 	}
 	return -EINVAL;
@@ -316,26 +321,54 @@ static int __init fmi_init(void)
 {
 	struct fmi *fmi = &fmi_card;
 	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
-	int res;
+	int res, i;
+	int probe_ports[] = { 0, 0x284, 0x384 };
 
-	if (io < 0)
-		io = isapnp_fmi_probe();
-	strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
-	fmi->io = io;
-	if (fmi->io < 0) {
-		v4l2_err(v4l2_dev, "No PnP card found.\n");
-		return fmi->io;
+	if (io < 0) {
+		for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
+			io = probe_ports[i];
+			if (io == 0) {
+				io = isapnp_fmi_probe();
+				if (io < 0)
+					continue;
+				pnp_attached = 1;
+			}
+			if (!request_region(io, 2, "radio-sf16fmi")) {
+				if (pnp_attached)
+					pnp_device_detach(dev);
+				io = -1;
+				continue;
+			}
+			if (pnp_attached ||
+			    ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
+				break;
+			release_region(io, 2);
+			io = -1;
+		}
+	} else {
+		if (!request_region(io, 2, "radio-sf16fmi")) {
+			printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
+			return -EBUSY;
+		}
+		if (inb(io) == 0xff) {
+			printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
+			release_region(io, 2);
+			return -ENODEV;
+		}
 	}
-	if (!request_region(io, 2, "radio-sf16fmi")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
-		pnp_device_detach(dev);
-		return -EBUSY;
+	if (io < 0) {
+		printk(KERN_ERR "radio-sf16fmi: no cards found\n");
+		return -ENODEV;
 	}
 
+	strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
+	fmi->io = io;
+
 	res = v4l2_device_register(NULL, v4l2_dev);
 	if (res < 0) {
 		release_region(fmi->io, 2);
-		pnp_device_detach(dev);
+		if (pnp_attached)
+			pnp_device_detach(dev);
 		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
 		return res;
 	}
@@ -352,7 +385,8 @@ static int __init fmi_init(void)
 	if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
 		v4l2_device_unregister(v4l2_dev);
 		release_region(fmi->io, 2);
-		pnp_device_detach(dev);
+		if (pnp_attached)
+			pnp_device_detach(dev);
 		return -EINVAL;
 	}
 
@@ -369,7 +403,7 @@ static void __exit fmi_exit(void)
 	video_unregister_device(&fmi->vdev);
 	v4l2_device_unregister(&fmi->v4l2_dev);
 	release_region(fmi->io, 2);
-	if (dev)
+	if (dev && pnp_attached)
 		pnp_device_detach(dev);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-sf16fmr2.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-sf16fmr2.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-sf16fmr2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-sf16fmr2.c	2010-02-24 13:52:17.000000000 -0500
@@ -251,6 +251,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct fmr2 *fmr2 = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (f->frequency < RSF16_MINFREQ ||
 			f->frequency > RSF16_MAXFREQ)
 		return -EINVAL;
@@ -272,6 +274,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct fmr2 *fmr2 = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = fmr2->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-tea5764.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-tea5764.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-tea5764.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-tea5764.c	2010-02-24 13:52:17.000000000 -0500
@@ -314,7 +314,7 @@ static int vidioc_g_tuner(struct file *f
 	if (v->index > 0)
 		return -EINVAL;
 
-	memset(v, 0, sizeof(v));
+	memset(v, 0, sizeof(*v));
 	strcpy(v->name, "FM");
 	v->type = V4L2_TUNER_RADIO;
 	tea5764_i2c_read(radio);
@@ -349,7 +349,7 @@ static int vidioc_s_frequency(struct fil
 {
 	struct tea5764_device *radio = video_drvdata(file);
 
-	if (f->tuner != 0)
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
 	if (f->frequency == 0) {
 		/* We special case this as a power down control. */
@@ -370,8 +370,10 @@ static int vidioc_g_frequency(struct fil
 	struct tea5764_device *radio = video_drvdata(file);
 	struct tea5764_regs *r = &radio->regs;
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	tea5764_i2c_read(radio);
-	memset(f, 0, sizeof(f));
+	memset(f, 0, sizeof(*f));
 	f->type = V4L2_TUNER_RADIO;
 	if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
 		f->frequency = (tea5764_get_freq(radio) * 2) / 125;
@@ -458,12 +460,8 @@ static int vidioc_s_audio(struct file *f
 static int tea5764_open(struct file *file)
 {
 	/* Currently we support only one device */
-	int minor = video_devdata(file)->minor;
 	struct tea5764_device *radio = video_drvdata(file);
 
-	if (radio->videodev->minor != minor)
-		return -ENODEV;
-
 	mutex_lock(&radio->mutex);
 	/* Only exclusive access */
 	if (radio->users) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-terratec.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-terratec.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-terratec.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-terratec.c	2010-02-24 13:52:17.000000000 -0500
@@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct terratec *tt = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	tt_setfreq(tt, f->frequency);
 	return 0;
 }
@@ -249,6 +251,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct terratec *tt = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = tt->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-trust.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-trust.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-trust.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-trust.c	2010-02-24 13:52:17.000000000 -0500
@@ -239,6 +239,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct trust *tr = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	tr_setfreq(tr, f->frequency);
 	return 0;
 }
@@ -248,6 +250,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct trust *tr = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = tr->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-typhoon.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-typhoon.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-typhoon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-typhoon.c	2010-02-24 13:52:17.000000000 -0500
@@ -207,6 +207,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct typhoon *dev = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = dev->curfreq;
 	return 0;
@@ -217,6 +219,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct typhoon *dev = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	dev->curfreq = f->frequency;
 	typhoon_setfreq(dev, dev->curfreq);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/radio-zoltrix.c linux-libre-2.6.33-gnu1/drivers/media/radio/radio-zoltrix.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/radio-zoltrix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/radio-zoltrix.c	2010-02-24 13:52:17.000000000 -0500
@@ -266,6 +266,8 @@ static int vidioc_s_frequency(struct fil
 {
 	struct zoltrix *zol = video_drvdata(file);
 
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
 	if (zol_setfreq(zol, f->frequency) != 0)
 		return -EINVAL;
 	return 0;
@@ -276,6 +278,8 @@ static int vidioc_g_frequency(struct fil
 {
 	struct zoltrix *zol = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = zol->curfreq;
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-common.c linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-common.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -426,6 +426,104 @@ int si470x_rds_on(struct si470x_device *
 
 
 /**************************************************************************
+ * File Operations Interface
+ **************************************************************************/
+
+/*
+ * si470x_fops_read - read RDS data
+ */
+static ssize_t si470x_fops_read(struct file *file, char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+	unsigned int block_count = 0;
+
+	/* switch on rds reception */
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		si470x_rds_on(radio);
+
+	/* block if no new data available */
+	while (radio->wr_index == radio->rd_index) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EWOULDBLOCK;
+			goto done;
+		}
+		if (wait_event_interruptible(radio->read_queue,
+			radio->wr_index != radio->rd_index) < 0) {
+			retval = -EINTR;
+			goto done;
+		}
+	}
+
+	/* calculate block count from byte count */
+	count /= 3;
+
+	/* copy RDS block out of internal buffer and to user buffer */
+	mutex_lock(&radio->lock);
+	while (block_count < count) {
+		if (radio->rd_index == radio->wr_index)
+			break;
+
+		/* always transfer rds complete blocks */
+		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
+			/* retval = -EFAULT; */
+			break;
+
+		/* increment and wrap read pointer */
+		radio->rd_index += 3;
+		if (radio->rd_index >= radio->buf_size)
+			radio->rd_index = 0;
+
+		/* increment counters */
+		block_count++;
+		buf += 3;
+		retval += 3;
+	}
+	mutex_unlock(&radio->lock);
+
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_fops_poll - poll RDS data
+ */
+static unsigned int si470x_fops_poll(struct file *file,
+		struct poll_table_struct *pts)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* switch on rds reception */
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		si470x_rds_on(radio);
+
+	poll_wait(file, &radio->read_queue, pts);
+
+	if (radio->rd_index != radio->wr_index)
+		retval = POLLIN | POLLRDNORM;
+
+	return retval;
+}
+
+
+/*
+ * si470x_fops - file operations interface
+ */
+static const struct v4l2_file_operations si470x_fops = {
+	.owner			= THIS_MODULE,
+	.read			= si470x_fops_read,
+	.poll			= si470x_fops_poll,
+	.ioctl			= video_ioctl2,
+	.open			= si470x_fops_open,
+	.release		= si470x_fops_release,
+};
+
+
+
+/**************************************************************************
  * Video4Linux Interface
  **************************************************************************/
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x.h linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x.h
--- linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/input.h>
@@ -181,6 +182,7 @@ struct si470x_device {
 
 #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
 	struct i2c_client *client;
+	struct work_struct radio_work;
 #endif
 };
 
@@ -212,7 +214,6 @@ struct si470x_device {
 /**************************************************************************
  * Common Functions
  **************************************************************************/
-extern const struct v4l2_file_operations si470x_fops;
 extern struct video_device si470x_viddev_template;
 int si470x_get_register(struct si470x_device *radio, int regnr);
 int si470x_set_register(struct si470x_device *radio, int regnr);
@@ -221,5 +222,7 @@ int si470x_set_freq(struct si470x_device
 int si470x_start(struct si470x_device *radio);
 int si470x_stop(struct si470x_device *radio);
 int si470x_rds_on(struct si470x_device *radio);
+int si470x_fops_open(struct file *file);
+int si470x_fops_release(struct file *file);
 int si470x_vidioc_querycap(struct file *file, void *priv,
 		struct v4l2_capability *capability);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,22 +22,17 @@
  */
 
 
-/*
- * ToDo:
- * - RDS support
- */
-
-
 /* driver definitions */
 #define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1)
 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
 #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.0"
+#define DRIVER_VERSION "1.0.1"
 
 /* kernel includes */
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 
 #include "radio-si470x.h"
 
@@ -62,6 +57,20 @@ static int radio_nr = -1;
 module_param(radio_nr, int, 0444);
 MODULE_PARM_DESC(radio_nr, "Radio Nr");
 
+/* RDS buffer blocks */
+static unsigned int rds_buf = 100;
+module_param(rds_buf, uint, 0444);
+MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
+
+/* RDS maximum block errors */
+static unsigned short max_rds_errors = 1;
+/* 0 means   0  errors requiring correction */
+/* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
+/* 2 means 3-5  errors requiring correction */
+/* 3 means   6+ errors or errors in checkword, correction not possible */
+module_param(max_rds_errors, ushort, 0644);
+MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
+
 
 
 /**************************************************************************
@@ -173,7 +182,7 @@ int si470x_disconnect_check(struct si470
 /*
  * si470x_fops_open - file open
  */
-static int si470x_fops_open(struct file *file)
+int si470x_fops_open(struct file *file)
 {
 	struct si470x_device *radio = video_drvdata(file);
 	int retval = 0;
@@ -181,12 +190,21 @@ static int si470x_fops_open(struct file
 	mutex_lock(&radio->lock);
 	radio->users++;
 
-	if (radio->users == 1)
+	if (radio->users == 1) {
 		/* start radio */
 		retval = si470x_start(radio);
+		if (retval < 0)
+			goto done;
 
-	mutex_unlock(&radio->lock);
+		/* enable RDS interrupt */
+		radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
+		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
+		radio->registers[SYSCONFIG1] |= 0x1 << 2;
+		retval = si470x_set_register(radio, SYSCONFIG1);
+	}
 
+done:
+	mutex_unlock(&radio->lock);
 	return retval;
 }
 
@@ -194,7 +212,7 @@ static int si470x_fops_open(struct file
 /*
  * si470x_fops_release - file release
  */
-static int si470x_fops_release(struct file *file)
+int si470x_fops_release(struct file *file)
 {
 	struct si470x_device *radio = video_drvdata(file);
 	int retval = 0;
@@ -215,17 +233,6 @@ static int si470x_fops_release(struct fi
 }
 
 
-/*
- * si470x_fops - file operations interface
- */
-const struct v4l2_file_operations si470x_fops = {
-	.owner		= THIS_MODULE,
-	.ioctl		= video_ioctl2,
-	.open		= si470x_fops_open,
-	.release	= si470x_fops_release,
-};
-
-
 
 /**************************************************************************
  * Video4Linux Interface
@@ -253,6 +260,105 @@ int si470x_vidioc_querycap(struct file *
  **************************************************************************/
 
 /*
+ * si470x_i2c_interrupt_work - rds processing function
+ */
+static void si470x_i2c_interrupt_work(struct work_struct *work)
+{
+	struct si470x_device *radio = container_of(work,
+			struct si470x_device, radio_work);
+	unsigned char regnr;
+	unsigned char blocknum;
+	unsigned short bler; /* rds block errors */
+	unsigned short rds;
+	unsigned char tmpbuf[3];
+	int retval = 0;
+
+	/* safety checks */
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		return;
+
+	/* Update RDS registers */
+	for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
+		retval = si470x_get_register(radio, STATUSRSSI + regnr);
+		if (retval < 0)
+			return;
+	}
+
+	/* get rds blocks */
+	if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
+		/* No RDS group ready, better luck next time */
+		return;
+
+	for (blocknum = 0; blocknum < 4; blocknum++) {
+		switch (blocknum) {
+		default:
+			bler = (radio->registers[STATUSRSSI] &
+					STATUSRSSI_BLERA) >> 9;
+			rds = radio->registers[RDSA];
+			break;
+		case 1:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERB) >> 14;
+			rds = radio->registers[RDSB];
+			break;
+		case 2:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERC) >> 12;
+			rds = radio->registers[RDSC];
+			break;
+		case 3:
+			bler = (radio->registers[READCHAN] &
+					READCHAN_BLERD) >> 10;
+			rds = radio->registers[RDSD];
+			break;
+		};
+
+		/* Fill the V4L2 RDS buffer */
+		put_unaligned_le16(rds, &tmpbuf);
+		tmpbuf[2] = blocknum;		/* offset name */
+		tmpbuf[2] |= blocknum << 3;	/* received offset */
+		if (bler > max_rds_errors)
+			tmpbuf[2] |= 0x80;	/* uncorrectable errors */
+		else if (bler > 0)
+			tmpbuf[2] |= 0x40;	/* corrected error(s) */
+
+		/* copy RDS block to internal buffer */
+		memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
+		radio->wr_index += 3;
+
+		/* wrap write pointer */
+		if (radio->wr_index >= radio->buf_size)
+			radio->wr_index = 0;
+
+		/* check for overflow */
+		if (radio->wr_index == radio->rd_index) {
+			/* increment and wrap read pointer */
+			radio->rd_index += 3;
+			if (radio->rd_index >= radio->buf_size)
+				radio->rd_index = 0;
+		}
+	}
+
+	if (radio->wr_index != radio->rd_index)
+		wake_up_interruptible(&radio->read_queue);
+}
+
+
+/*
+ * si470x_i2c_interrupt - interrupt handler
+ */
+static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
+{
+	struct si470x_device *radio = dev_id;
+
+	if (!work_pending(&radio->radio_work))
+		schedule_work(&radio->radio_work);
+
+	return IRQ_HANDLED;
+}
+
+
+/*
  * si470x_i2c_probe - probe for the device
  */
 static int __devinit si470x_i2c_probe(struct i2c_client *client,
@@ -268,6 +374,8 @@ static int __devinit si470x_i2c_probe(st
 		retval = -ENOMEM;
 		goto err_initial;
 	}
+
+	INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
 	radio->users = 0;
 	radio->client = client;
 	mutex_init(&radio->lock);
@@ -319,6 +427,26 @@ static int __devinit si470x_i2c_probe(st
 	/* set initial frequency */
 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
 
+	/* rds buffer allocation */
+	radio->buf_size = rds_buf * 3;
+	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
+	if (!radio->buffer) {
+		retval = -EIO;
+		goto err_video;
+	}
+
+	/* rds buffer configuration */
+	radio->wr_index = 0;
+	radio->rd_index = 0;
+	init_waitqueue_head(&radio->read_queue);
+
+	retval = request_irq(client->irq, si470x_i2c_interrupt,
+			IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
+	if (retval) {
+		dev_err(&client->dev, "Failed to register interrupt\n");
+		goto err_rds;
+	}
+
 	/* register video device */
 	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
 			radio_nr);
@@ -330,6 +458,9 @@ static int __devinit si470x_i2c_probe(st
 
 	return 0;
 err_all:
+	free_irq(client->irq, radio);
+err_rds:
+	kfree(radio->buffer);
 err_video:
 	video_device_release(radio->videodev);
 err_radio:
@@ -346,6 +477,8 @@ static __devexit int si470x_i2c_remove(s
 {
 	struct si470x_device *radio = i2c_get_clientdata(client);
 
+	free_irq(client->irq, radio);
+	cancel_work_sync(&radio->radio_work);
 	video_unregister_device(radio->videodev);
 	kfree(radio);
 	i2c_set_clientdata(client, NULL);
@@ -354,6 +487,44 @@ static __devexit int si470x_i2c_remove(s
 }
 
 
+#ifdef CONFIG_PM
+/*
+ * si470x_i2c_suspend - suspend the device
+ */
+static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct si470x_device *radio = i2c_get_clientdata(client);
+
+	/* power down */
+	radio->registers[POWERCFG] |= POWERCFG_DISABLE;
+	if (si470x_set_register(radio, POWERCFG) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+
+/*
+ * si470x_i2c_resume - resume the device
+ */
+static int si470x_i2c_resume(struct i2c_client *client)
+{
+	struct si470x_device *radio = i2c_get_clientdata(client);
+
+	/* power up : need 110ms */
+	radio->registers[POWERCFG] |= POWERCFG_ENABLE;
+	if (si470x_set_register(radio, POWERCFG) < 0)
+		return -EIO;
+	msleep(110);
+
+	return 0;
+}
+#else
+#define si470x_i2c_suspend	NULL
+#define si470x_i2c_resume	NULL
+#endif
+
+
 /*
  * si470x_i2c_driver - i2c driver interface
  */
@@ -364,6 +535,8 @@ static struct i2c_driver si470x_i2c_driv
 	},
 	.probe			= si470x_i2c_probe,
 	.remove			= __devexit_p(si470x_i2c_remove),
+	.suspend		= si470x_i2c_suspend,
+	.resume			= si470x_i2c_resume,
 	.id_table		= si470x_i2c_id,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/si470x/radio-si470x-usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -509,89 +509,9 @@ resubmit:
  **************************************************************************/
 
 /*
- * si470x_fops_read - read RDS data
- */
-static ssize_t si470x_fops_read(struct file *file, char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-	unsigned int block_count = 0;
-
-	/* switch on rds reception */
-	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
-		si470x_rds_on(radio);
-
-	/* block if no new data available */
-	while (radio->wr_index == radio->rd_index) {
-		if (file->f_flags & O_NONBLOCK) {
-			retval = -EWOULDBLOCK;
-			goto done;
-		}
-		if (wait_event_interruptible(radio->read_queue,
-			radio->wr_index != radio->rd_index) < 0) {
-			retval = -EINTR;
-			goto done;
-		}
-	}
-
-	/* calculate block count from byte count */
-	count /= 3;
-
-	/* copy RDS block out of internal buffer and to user buffer */
-	mutex_lock(&radio->lock);
-	while (block_count < count) {
-		if (radio->rd_index == radio->wr_index)
-			break;
-
-		/* always transfer rds complete blocks */
-		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
-			/* retval = -EFAULT; */
-			break;
-
-		/* increment and wrap read pointer */
-		radio->rd_index += 3;
-		if (radio->rd_index >= radio->buf_size)
-			radio->rd_index = 0;
-
-		/* increment counters */
-		block_count++;
-		buf += 3;
-		retval += 3;
-	}
-	mutex_unlock(&radio->lock);
-
-done:
-	return retval;
-}
-
-
-/*
- * si470x_fops_poll - poll RDS data
- */
-static unsigned int si470x_fops_poll(struct file *file,
-		struct poll_table_struct *pts)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* switch on rds reception */
-	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
-		si470x_rds_on(radio);
-
-	poll_wait(file, &radio->read_queue, pts);
-
-	if (radio->rd_index != radio->wr_index)
-		retval = POLLIN | POLLRDNORM;
-
-	return retval;
-}
-
-
-/*
  * si470x_fops_open - file open
  */
-static int si470x_fops_open(struct file *file)
+int si470x_fops_open(struct file *file)
 {
 	struct si470x_device *radio = video_drvdata(file);
 	int retval;
@@ -645,7 +565,7 @@ done:
 /*
  * si470x_fops_release - file release
  */
-static int si470x_fops_release(struct file *file)
+int si470x_fops_release(struct file *file)
 {
 	struct si470x_device *radio = video_drvdata(file);
 	int retval = 0;
@@ -688,19 +608,6 @@ done:
 }
 
 
-/*
- * si470x_fops - file operations interface
- */
-const struct v4l2_file_operations si470x_fops = {
-	.owner		= THIS_MODULE,
-	.read		= si470x_fops_read,
-	.poll		= si470x_fops_poll,
-	.ioctl		= video_ioctl2,
-	.open		= si470x_fops_open,
-	.release	= si470x_fops_release,
-};
-
-
 
 /**************************************************************************
  * Video4Linux Interface
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/radio/tef6862.c linux-libre-2.6.33-gnu1/drivers/media/radio/tef6862.c
--- linux-libre-2.6.32-gnu1/drivers/media/radio/tef6862.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/radio/tef6862.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,232 @@
+/*
+ * tef6862.c Philips TEF6862 Car Radio Enhanced Selectivity Tuner
+ * Copyright (c) 2009 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.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)
+
+/* Write mode sub addresses */
+#define WM_SUB_BANDWIDTH	0x0
+#define WM_SUB_PLLM		0x1
+#define WM_SUB_PLLL		0x2
+#define WM_SUB_DAA		0x3
+#define WM_SUB_AGC		0x4
+#define WM_SUB_BAND		0x5
+#define WM_SUB_CONTROL		0x6
+#define WM_SUB_LEVEL		0x7
+#define WM_SUB_IFCF		0x8
+#define WM_SUB_IFCAP		0x9
+#define WM_SUB_ACD		0xA
+#define WM_SUB_TEST		0xF
+
+/* Different modes of the MSA register */
+#define MODE_BUFFER		0x0
+#define MODE_PRESET		0x1
+#define MODE_SEARCH		0x2
+#define MODE_AF_UPDATE		0x3
+#define MODE_JUMP		0x4
+#define MODE_CHECK		0x5
+#define MODE_LOAD		0x6
+#define MODE_END		0x7
+#define MODE_SHIFT		5
+
+struct tef6862_state {
+	struct v4l2_subdev sd;
+	unsigned long freq;
+};
+
+static inline struct tef6862_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tef6862_state, sd);
+}
+
+static u16 tef6862_sigstr(struct i2c_client *client)
+{
+	u8 buf[4];
+	int err = i2c_master_recv(client, buf, sizeof(buf));
+	if (err == sizeof(buf))
+		return buf[3] << 8;
+	return 0;
+}
+
+static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
+{
+	if (v->index > 0)
+		return -EINVAL;
+
+	/* only support FM for now */
+	strlcpy(v->name, "FM", sizeof(v->name));
+	v->type = V4L2_TUNER_RADIO;
+	v->rangelow = TEF6862_LO_FREQ;
+	v->rangehigh = TEF6862_HI_FREQ;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	v->audmode = V4L2_TUNER_MODE_STEREO;
+	v->signal = tef6862_sigstr(v4l2_get_subdevdata(sd));
+
+	return 0;
+}
+
+static int tef6862_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
+{
+	return v->index ? -EINVAL : 0;
+}
+
+static int tef6862_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct tef6862_state *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u16 pll;
+	u8 i2cmsg[3];
+	int err;
+
+	if (f->tuner != 0)
+		return -EINVAL;
+
+	pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
+	i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
+	i2cmsg[1] = (pll >> 8) & 0xff;
+	i2cmsg[2] = pll & 0xff;
+
+	err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg));
+	if (!err)
+		state->freq = f->frequency;
+	return err;
+}
+
+static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct tef6862_state *state = to_state(sd);
+
+	if (f->tuner != 0)
+		return -EINVAL;
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = state->freq;
+	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,
+	.s_frequency = tef6862_s_frequency,
+	.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,
+};
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static int __devinit tef6862_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct tef6862_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;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+	state->freq = TEF6862_LO_FREQ;
+
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &tef6862_ops);
+
+	return 0;
+}
+
+static int __devexit tef6862_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+	return 0;
+}
+
+static const struct i2c_device_id tef6862_id[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tef6862_id);
+
+static struct i2c_driver tef6862_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRIVER_NAME,
+	},
+	.probe		= tef6862_probe,
+	.remove		= tef6862_remove,
+	.id_table	= tef6862_id,
+};
+
+static __init int tef6862_init(void)
+{
+	return i2c_add_driver(&tef6862_driver);
+}
+
+static __exit void tef6862_exit(void)
+{
+	i2c_del_driver(&tef6862_driver);
+}
+
+module_init(tef6862_init);
+module_exit(tef6862_exit);
+
+MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner");
+MODULE_AUTHOR("Mocean Laboratories");
+MODULE_LICENSE("GPL v2");
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/adv7180.c linux-libre-2.6.33-gnu1/drivers/media/video/adv7180.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/adv7180.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/adv7180.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,17 +27,40 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
+#include <linux/mutex.h>
 
 #define DRIVER_NAME "adv7180"
 
-#define ADV7180_INPUT_CONTROL_REG	0x00
-#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM	0x00
-#define ADV7180_AUTODETECT_ENABLE_REG	0x07
-#define ADV7180_AUTODETECT_DEFAULT	0x7f
+#define ADV7180_INPUT_CONTROL_REG			0x00
+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM	0x00
+#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM	0x20
+#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM	0x30
+#define ADV7180_INPUT_CONTROL_NTSC_J			0x40
+#define ADV7180_INPUT_CONTROL_NTSC_M			0x50
+#define ADV7180_INPUT_CONTROL_PAL60			0x60
+#define ADV7180_INPUT_CONTROL_NTSC_443			0x70
+#define ADV7180_INPUT_CONTROL_PAL_BG			0x80
+#define ADV7180_INPUT_CONTROL_PAL_N			0x90
+#define ADV7180_INPUT_CONTROL_PAL_M			0xa0
+#define ADV7180_INPUT_CONTROL_PAL_M_PED			0xb0
+#define ADV7180_INPUT_CONTROL_PAL_COMB_N		0xc0
+#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED		0xd0
+#define ADV7180_INPUT_CONTROL_PAL_SECAM			0xe0
+#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED		0xf0
 
+#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG		0x04
+#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS		0xC5
 
-#define ADV7180_STATUS1_REG 0x10
-#define ADV7180_STATUS1_AUTOD_MASK 0x70
+#define ADV7180_AUTODETECT_ENABLE_REG			0x07
+#define ADV7180_AUTODETECT_DEFAULT			0x7f
+
+#define ADV7180_ADI_CTRL_REG				0x0e
+#define ADV7180_ADI_CTRL_IRQ_SPACE			0x20
+
+#define ADV7180_STATUS1_REG				0x10
+#define ADV7180_STATUS1_IN_LOCK		0x01
+#define ADV7180_STATUS1_AUTOD_MASK	0x70
 #define ADV7180_STATUS1_AUTOD_NTSM_M_J	0x00
 #define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
 #define ADV7180_STATUS1_AUTOD_PAL_M	0x20
@@ -50,18 +73,37 @@
 #define ADV7180_IDENT_REG 0x11
 #define ADV7180_ID_7180 0x18
 
+#define ADV7180_ICONF1_ADI		0x40
+#define ADV7180_ICONF1_ACTIVE_LOW	0x01
+#define ADV7180_ICONF1_PSYNC_ONLY	0x10
+#define ADV7180_ICONF1_ACTIVE_TO_CLR	0xC0
+
+#define ADV7180_IRQ1_LOCK	0x01
+#define ADV7180_IRQ1_UNLOCK	0x02
+#define ADV7180_ISR1_ADI	0x42
+#define ADV7180_ICR1_ADI	0x43
+#define ADV7180_IMR1_ADI	0x44
+#define ADV7180_IMR2_ADI	0x48
+#define ADV7180_IRQ3_AD_CHANGE	0x08
+#define ADV7180_ISR3_ADI	0x4A
+#define ADV7180_ICR3_ADI	0x4B
+#define ADV7180_IMR3_ADI	0x4C
+#define ADV7180_IMR4_ADI	0x50
 
 struct adv7180_state {
-	struct v4l2_subdev sd;
+	struct v4l2_subdev	sd;
+	struct work_struct	work;
+	struct mutex		mutex; /* mutual excl. when accessing chip */
+	int			irq;
+	v4l2_std_id		curr_norm;
+	bool			autodetect;
 };
 
-static v4l2_std_id determine_norm(struct i2c_client *client)
+static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
 {
-	u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
-
 	switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
 	case ADV7180_STATUS1_AUTOD_NTSM_M_J:
-		return V4L2_STD_NTSC_M_JP;
+		return V4L2_STD_NTSC;
 	case ADV7180_STATUS1_AUTOD_NTSC_4_43:
 		return V4L2_STD_NTSC_443;
 	case ADV7180_STATUS1_AUTOD_PAL_M:
@@ -81,6 +123,53 @@ static v4l2_std_id determine_norm(struct
 	}
 }
 
+static int v4l2_std_to_adv7180(v4l2_std_id std)
+{
+	if (std == V4L2_STD_PAL_60)
+		return ADV7180_INPUT_CONTROL_PAL60;
+	if (std == V4L2_STD_NTSC_443)
+		return ADV7180_INPUT_CONTROL_NTSC_443;
+	if (std == V4L2_STD_PAL_N)
+		return ADV7180_INPUT_CONTROL_PAL_N;
+	if (std == V4L2_STD_PAL_M)
+		return ADV7180_INPUT_CONTROL_PAL_M;
+	if (std == V4L2_STD_PAL_Nc)
+		return ADV7180_INPUT_CONTROL_PAL_COMB_N;
+
+	if (std & V4L2_STD_PAL)
+		return ADV7180_INPUT_CONTROL_PAL_BG;
+	if (std & V4L2_STD_NTSC)
+		return ADV7180_INPUT_CONTROL_NTSC_M;
+	if (std & V4L2_STD_SECAM)
+		return ADV7180_INPUT_CONTROL_PAL_SECAM;
+
+	return -EINVAL;
+}
+
+static u32 adv7180_status_to_v4l2(u8 status1)
+{
+	if (!(status1 & ADV7180_STATUS1_IN_LOCK))
+		return V4L2_IN_ST_NO_SIGNAL;
+
+	return 0;
+}
+
+static int __adv7180_status(struct i2c_client *client, u32 *status,
+	v4l2_std_id *std)
+{
+	int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
+
+	if (status1 < 0)
+		return status1;
+
+	if (status)
+		*status = adv7180_status_to_v4l2(status1);
+	if (std)
+		*std = adv7180_std_to_v4l2(status1);
+
+	return 0;
+}
+
 static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct adv7180_state, sd);
@@ -88,10 +177,31 @@ static inline struct adv7180_state *to_s
 
 static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct adv7180_state *state = to_state(sd);
+	int err = mutex_lock_interruptible(&state->mutex);
+	if (err)
+		return err;
 
-	*std = determine_norm(client);
-	return 0;
+	/* when we are interrupt driven we know the state */
+	if (!state->autodetect || state->irq > 0)
+		*std = state->curr_norm;
+	else
+		err = __adv7180_status(v4l2_get_subdevdata(sd), NULL, std);
+
+	mutex_unlock(&state->mutex);
+	return err;
+}
+
+static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct adv7180_state *state = to_state(sd);
+	int ret = mutex_lock_interruptible(&state->mutex);
+	if (ret)
+		return ret;
+
+	ret = __adv7180_status(v4l2_get_subdevdata(sd), status, NULL);
+	mutex_unlock(&state->mutex);
+	return ret;
 }
 
 static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
@@ -102,12 +212,51 @@ static int adv7180_g_chip_ident(struct v
 	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);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = mutex_lock_interruptible(&state->mutex);
+	if (ret)
+		return ret;
+
+	/* all standards -> autodetect */
+	if (std == V4L2_STD_ALL) {
+		ret = i2c_smbus_write_byte_data(client,
+			ADV7180_INPUT_CONTROL_REG,
+			ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
+		if (ret < 0)
+			goto out;
+
+		__adv7180_status(client, NULL, &state->curr_norm);
+		state->autodetect = true;
+	} else {
+		ret = v4l2_std_to_adv7180(std);
+		if (ret < 0)
+			goto out;
+
+		ret = i2c_smbus_write_byte_data(client,
+			ADV7180_INPUT_CONTROL_REG, ret);
+		if (ret < 0)
+			goto out;
+
+		state->curr_norm = std;
+		state->autodetect = false;
+	}
+	ret = 0;
+out:
+	mutex_unlock(&state->mutex);
+	return ret;
+}
+
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 	.querystd = adv7180_querystd,
+	.g_input_status = adv7180_g_input_status,
 };
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
 	.g_chip_ident = adv7180_g_chip_ident,
+	.s_std = adv7180_s_std,
 };
 
 static const struct v4l2_subdev_ops adv7180_ops = {
@@ -115,12 +264,45 @@ static const struct v4l2_subdev_ops adv7
 	.video = &adv7180_video_ops,
 };
 
+static void adv7180_work(struct work_struct *work)
+{
+	struct adv7180_state *state = container_of(work, struct adv7180_state,
+		work);
+	struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
+	u8 isr3;
+
+	mutex_lock(&state->mutex);
+	i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+		ADV7180_ADI_CTRL_IRQ_SPACE);
+	isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
+	/* clear */
+	i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
+	i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 0);
+
+	if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
+		__adv7180_status(client, NULL, &state->curr_norm);
+	mutex_unlock(&state->mutex);
+
+	enable_irq(state->irq);
+}
+
+static irqreturn_t adv7180_irq(int irq, void *devid)
+{
+	struct adv7180_state *state = devid;
+
+	schedule_work(&state->work);
+
+	disable_irq_nosync(state->irq);
+
+	return IRQ_HANDLED;
+}
+
 /*
  * Generic i2c probe
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 
-static int adv7180_probe(struct i2c_client *client,
+static __devinit int adv7180_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct adv7180_state *state;
@@ -135,32 +317,111 @@ static int adv7180_probe(struct i2c_clie
 			client->addr << 1, client->adapter->name);
 
 	state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
-	if (state == NULL)
-		return -ENOMEM;
+	if (state == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	state->irq = client->irq;
+	INIT_WORK(&state->work, adv7180_work);
+	mutex_init(&state->mutex);
+	state->autodetect = true;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
 
 	/* Initialize adv7180 */
-	/* enable autodetection */
+	/* Enable autodetection */
 	ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
-		ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM);
-	if (ret > 0)
-		ret = i2c_smbus_write_byte_data(client,
-			ADV7180_AUTODETECT_ENABLE_REG,
-			ADV7180_AUTODETECT_DEFAULT);
-	if (ret < 0) {
-		printk(KERN_ERR DRIVER_NAME
-			": Failed to communicate to chip: %d\n", ret);
-		return ret;
+		ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG,
+		ADV7180_AUTODETECT_DEFAULT);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	/* ITU-R BT.656-4 compatible */
+	ret = i2c_smbus_write_byte_data(client,
+		ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
+		ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
+	if (ret < 0)
+		goto err_unreg_subdev;
+
+	/* read current norm */
+	__adv7180_status(client, NULL, &state->curr_norm);
+
+	/* register for interrupts */
+	if (state->irq > 0) {
+		ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
+			state);
+		if (ret)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+			ADV7180_ADI_CTRL_IRQ_SPACE);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		/* config the Interrupt pin to be active low */
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
+			ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		/* enable AD change interrupts interrupts */
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
+			ADV7180_IRQ3_AD_CHANGE);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
+		if (ret < 0)
+			goto err_unreg_subdev;
+
+		ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
+			0);
+		if (ret < 0)
+			goto err_unreg_subdev;
 	}
 
 	return 0;
+
+err_unreg_subdev:
+	mutex_destroy(&state->mutex);
+	v4l2_device_unregister_subdev(sd);
+	kfree(state);
+err:
+	printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
+	return ret;
 }
 
-static int adv7180_remove(struct i2c_client *client)
+static __devexit int adv7180_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct adv7180_state *state = to_state(sd);
 
+	if (state->irq > 0) {
+		free_irq(client->irq, state);
+		if (cancel_work_sync(&state->work)) {
+			/*
+			 * Work was pending, therefore we need to enable
+			 * IRQ here to balance the disable_irq() done in the
+			 * interrupt handler.
+			 */
+			enable_irq(state->irq);
+		}
+	}
+
+	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
 	kfree(to_state(sd));
 	return 0;
@@ -179,7 +440,7 @@ static struct i2c_driver adv7180_driver
 		.name	= DRIVER_NAME,
 	},
 	.probe		= adv7180_probe,
-	.remove		= adv7180_remove,
+	.remove		= __devexit_p(adv7180_remove),
 	.id_table	= adv7180_id,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/arv.c linux-libre-2.6.33-gnu1/drivers/media/video/arv.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/arv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/arv.c	2010-02-24 13:52:17.000000000 -0500
@@ -767,7 +767,6 @@ static struct video_device ar_template =
 	.name		= "Colour AR VGA",
 	.fops		= &ar_fops,
 	.release	= ar_release,
-	.minor		= -1,
 };
 
 #define ALIGN4(x)	((((int)(x)) & 0x3) == 0)
@@ -860,8 +859,8 @@ static int __init ar_init(void)
 		goto out_dev;
 	}
 
-	printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
-		ar->vdev->num, M32R_IRQ_INT3, freq);
+	printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
+		video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq);
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/au0828/au0828.h linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/au0828/au0828.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828.h	2010-02-24 13:52:17.000000000 -0500
@@ -192,7 +192,6 @@ struct au0828_dev {
 	struct au0828_dvb		dvb;
 
 	/* Analog */
-	struct list_head au0828list;
 	struct v4l2_device v4l2_dev;
 	int users;
 	unsigned int stream_on:1;	/* Locks streams */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/au0828/au0828-video.c linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/au0828/au0828-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/au0828/au0828-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,6 @@
 #include "au0828.h"
 #include "au0828-reg.h"
 
-static LIST_HEAD(au0828_devlist);
 static DEFINE_MUTEX(au0828_sysfs_lock);
 
 #define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
@@ -693,10 +692,8 @@ void au0828_analog_unregister(struct au0
 	dprintk(1, "au0828_release_resources called\n");
 	mutex_lock(&au0828_sysfs_lock);
 
-	if (dev->vdev) {
-		list_del(&dev->au0828list);
+	if (dev->vdev)
 		video_unregister_device(dev->vdev);
-	}
 	if (dev->vbi_dev)
 		video_unregister_device(dev->vbi_dev);
 
@@ -737,29 +734,15 @@ static void res_free(struct au0828_fh *f
 
 static int au0828_v4l2_open(struct file *filp)
 {
-	int minor = video_devdata(filp)->minor;
 	int ret = 0;
-	struct au0828_dev *h, *dev = NULL;
+	struct au0828_dev *dev = video_drvdata(filp);
 	struct au0828_fh *fh;
-	int type = 0;
-	struct list_head *list;
+	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-	list_for_each(list, &au0828_devlist) {
-		h = list_entry(list, struct au0828_dev, au0828list);
-		if (h->vdev->minor == minor) {
-			dev = h;
-			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		}
 #ifdef VBI_IS_WORKING
-		if (h->vbi_dev->minor == minor) {
-			dev = h;
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		}
+	if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER)
+		type = V4L2_BUF_TYPE_VBI_CAPTURE;
 #endif
-	}
-
-	if (NULL == dev)
-		return -ENODEV;
 
 	fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
 	if (NULL == fh) {
@@ -830,7 +813,7 @@ static int au0828_v4l2_close(struct file
 		au0828_uninit_isoc(dev);
 
 		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 		/* When close the device, set the usb intf0 into alt0 to free
 		   USB bandwidth */
@@ -1587,7 +1570,6 @@ static const struct video_device au0828_
 	.fops                       = &au0828_v4l_fops,
 	.release                    = video_device_release,
 	.ioctl_ops 		    = &video_ioctl_ops,
-	.minor                      = -1,
 	.tvnorms                    = V4L2_STD_NTSC_M,
 	.current_norm               = V4L2_STD_NTSC_M,
 };
@@ -1676,25 +1658,23 @@ int au0828_analog_register(struct au0828
 	strcpy(dev->vbi_dev->name, "au0828a vbi");
 #endif
 
-	list_add_tail(&dev->au0828list, &au0828_devlist);
-
 	/* Register the v4l2 device */
+	video_set_drvdata(dev->vdev, dev);
 	retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
 	if (retval != 0) {
 		dprintk(1, "unable to register video device (error = %d).\n",
 			retval);
-		list_del(&dev->au0828list);
 		video_device_release(dev->vdev);
 		return -ENODEV;
 	}
 
 #ifdef VBI_IS_WORKING
 	/* Register the vbi device */
+	video_set_drvdata(dev->vbi_dev, dev);
 	retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
 	if (retval != 0) {
 		dprintk(1, "unable to register vbi device (error = %d).\n",
 			retval);
-		list_del(&dev->au0828list);
 		video_device_release(dev->vbi_dev);
 		video_device_release(dev->vdev);
 		return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/bt819.c linux-libre-2.6.33-gnu1/drivers/media/video/bt819.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/bt819.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/bt819.c	2010-02-24 13:52:17.000000000 -0500
@@ -299,7 +299,7 @@ static int bt819_s_routing(struct v4l2_s
 
 	v4l2_dbg(1, debug, sd, "set input %x\n", input);
 
-	if (input < 0 || input > 7)
+	if (input > 7)
 		return -EINVAL;
 
 	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-driver.c linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-driver.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -3206,24 +3206,24 @@ err:
 
 static int bttv_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
+	struct video_device *vdev = video_devdata(file);
 	struct bttv *btv = video_drvdata(file);
 	struct bttv_fh *fh;
 	enum v4l2_buf_type type = 0;
 
-	dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
+	dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev));
 
-	lock_kernel();
-	if (btv->video_dev->minor == minor) {
+	if (vdev->vfl_type == VFL_TYPE_GRABBER) {
 		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	} else if (btv->vbi_dev->minor == minor) {
+	} else if (vdev->vfl_type == VFL_TYPE_VBI) {
 		type = V4L2_BUF_TYPE_VBI_CAPTURE;
 	} else {
 		WARN_ON(1);
-		unlock_kernel();
 		return -ENODEV;
 	}
 
+	lock_kernel();
+
 	dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
 		btv->c.nr,v4l2_type_names[type]);
 
@@ -3397,7 +3397,6 @@ static const struct v4l2_ioctl_ops bttv_
 
 static struct video_device bttv_video_template = {
 	.fops         = &bttv_fops,
-	.minor        = -1,
 	.ioctl_ops    = &bttv_ioctl_ops,
 	.tvnorms      = BTTV_NORMS,
 	.current_norm = V4L2_STD_PAL,
@@ -3408,18 +3407,13 @@ static struct video_device bttv_video_te
 
 static int radio_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
+	struct video_device *vdev = video_devdata(file);
 	struct bttv *btv = video_drvdata(file);
 	struct bttv_fh *fh;
 
-	dprintk("bttv: open minor=%d\n",minor);
+	dprintk("bttv: open dev=%s\n", video_device_node_name(vdev));
 
 	lock_kernel();
-	WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
-	if (!btv->radio_dev || btv->radio_dev->minor != minor) {
-		unlock_kernel();
-		return -ENODEV;
-	}
 
 	dprintk("bttv%d: open called (radio)\n",btv->c.nr);
 
@@ -3640,7 +3634,6 @@ static const struct v4l2_ioctl_ops radio
 
 static struct video_device radio_template = {
 	.fops      = &radio_fops,
-	.minor     = -1,
 	.ioctl_ops = &radio_ioctl_ops,
 };
 
@@ -4208,21 +4201,21 @@ static struct video_device *vdev_init(st
 static void bttv_unregister_video(struct bttv *btv)
 {
 	if (btv->video_dev) {
-		if (-1 != btv->video_dev->minor)
+		if (video_is_registered(btv->video_dev))
 			video_unregister_device(btv->video_dev);
 		else
 			video_device_release(btv->video_dev);
 		btv->video_dev = NULL;
 	}
 	if (btv->vbi_dev) {
-		if (-1 != btv->vbi_dev->minor)
+		if (video_is_registered(btv->vbi_dev))
 			video_unregister_device(btv->vbi_dev);
 		else
 			video_device_release(btv->vbi_dev);
 		btv->vbi_dev = NULL;
 	}
 	if (btv->radio_dev) {
-		if (-1 != btv->radio_dev->minor)
+		if (video_is_registered(btv->radio_dev))
 			video_unregister_device(btv->radio_dev);
 		else
 			video_device_release(btv->radio_dev);
@@ -4244,8 +4237,8 @@ static int __devinit bttv_register_video
 	if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER,
 				  video_nr[btv->c.nr]) < 0)
 		goto err;
-	printk(KERN_INFO "bttv%d: registered device video%d\n",
-	       btv->c.nr, btv->video_dev->num);
+	printk(KERN_INFO "bttv%d: registered device %s\n",
+	       btv->c.nr, video_device_node_name(btv->video_dev));
 	if (device_create_file(&btv->video_dev->dev,
 				     &dev_attr_card)<0) {
 		printk(KERN_ERR "bttv%d: device_create_file 'card' "
@@ -4261,8 +4254,8 @@ static int __devinit bttv_register_video
 	if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI,
 				  vbi_nr[btv->c.nr]) < 0)
 		goto err;
-	printk(KERN_INFO "bttv%d: registered device vbi%d\n",
-	       btv->c.nr, btv->vbi_dev->num);
+	printk(KERN_INFO "bttv%d: registered device %s\n",
+	       btv->c.nr, video_device_node_name(btv->vbi_dev));
 
 	if (!btv->has_radio)
 		return 0;
@@ -4273,8 +4266,8 @@ static int __devinit bttv_register_video
 	if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,
 				  radio_nr[btv->c.nr]) < 0)
 		goto err;
-	printk(KERN_INFO "bttv%d: registered device radio%d\n",
-	       btv->c.nr, btv->radio_dev->num);
+	printk(KERN_INFO "bttv%d: registered device %s\n",
+	       btv->c.nr, video_device_node_name(btv->radio_dev));
 
 	/* all done */
 	return 0;
@@ -4468,6 +4461,7 @@ static int __devinit bttv_probe(struct p
 		request_modules(btv);
 	}
 
+	init_bttv_i2c_ir(btv);
 	bttv_input_init(btv);
 
 	/* everything is fine */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-i2c.c linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@ static int i2c_debug;
 static int i2c_hw;
 static int i2c_scan;
 module_param(i2c_debug, int, 0644);
-MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
+MODULE_PARM_DESC(i2c_debug, "configure i2c debug level");
 module_param(i2c_hw,    int, 0444);
 MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
 			"instead of software bitbang");
@@ -388,7 +388,12 @@ int __devinit init_bttv_i2c(struct bttv
 	if (0 == btv->i2c_rc && i2c_scan)
 		do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
 
-	/* Instantiate the IR receiver device, if present */
+	return btv->i2c_rc;
+}
+
+/* Instantiate the I2C IR receiver device, if present */
+void __devinit init_bttv_i2c_ir(struct bttv *btv)
+{
 	if (0 == btv->i2c_rc) {
 		struct i2c_board_info info;
 		/* The external IR receiver is at i2c address 0x34 (0x35 for
@@ -400,7 +405,7 @@ int __devinit init_bttv_i2c(struct bttv
 		   That's why we probe 0x1a (~0x34) first. CB
 		*/
 		const unsigned short addr_list[] = {
-			0x1a, 0x18, 0x4b, 0x64, 0x30,
+			0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71,
 			I2C_CLIENT_END
 		};
 
@@ -408,7 +413,6 @@ int __devinit init_bttv_i2c(struct bttv
 		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
 		i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
 	}
-	return btv->i2c_rc;
 }
 
 int __devexit fini_bttv_i2c(struct bttv *btv)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-input.c linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttv-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttv-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,12 +73,12 @@ static void ir_handle_key(struct bttv *b
 
 	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-		ir_input_keydown(ir->dev,&ir->ir,data,data);
+		ir_input_keydown(ir->dev, &ir->ir, data);
 	} else {
 		/* HACK: Probably, ir->mask_keydown is missing
 		   for this board */
 		if (btv->c.type == BTTV_BOARD_WINFAST2000)
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 
 		ir_input_nokey(ir->dev,&ir->ir);
 	}
@@ -104,7 +104,7 @@ static void ir_enltv_handle_key(struct b
 			gpio, data,
 			(gpio & ir->mask_keyup) ? " up" : "up/down");
 
-		ir_input_keydown(ir->dev, &ir->ir, data, data);
+		ir_input_keydown(ir->dev, &ir->ir, data);
 		if (keyup)
 			ir_input_nokey(ir->dev, &ir->ir);
 	} else {
@@ -118,7 +118,7 @@ static void ir_enltv_handle_key(struct b
 		if (keyup)
 			ir_input_nokey(ir->dev, &ir->ir);
 		else
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 	}
 
 	ir->last_gpio = data | keyup;
@@ -368,7 +368,10 @@ int bttv_input_init(struct bttv *btv)
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(btv->c.pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -386,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
 	bttv_ir_start(btv, ir);
 
 	/* all done */
-	err = input_register_device(btv->remote->dev);
+	err = ir_input_register(btv->remote->dev, ir_codes);
 	if (err)
 		goto err_out_stop;
 
@@ -400,7 +403,6 @@ int bttv_input_init(struct bttv *btv)
 	bttv_ir_stop(btv);
 	btv->remote = NULL;
  err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -411,7 +413,7 @@ void bttv_input_fini(struct bttv *btv)
 		return;
 
 	bttv_ir_stop(btv);
-	input_unregister_device(btv->remote->dev);
+	ir_input_unregister(btv->remote->dev);
 	kfree(btv->remote);
 	btv->remote = NULL;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttvp.h linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttvp.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/bt8xx/bttvp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/bt8xx/bttvp.h	2010-02-24 13:52:17.000000000 -0500
@@ -279,6 +279,7 @@ extern unsigned int bttv_debug;
 extern unsigned int bttv_gpio;
 extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
 extern int init_bttv_i2c(struct bttv *btv);
+extern void init_bttv_i2c_ir(struct bttv *btv);
 extern int fini_bttv_i2c(struct bttv *btv);
 
 #define bttv_printk if (bttv_verbose) printk
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cafe_ccic.c linux-libre-2.6.33-gnu1/drivers/media/video/cafe_ccic.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cafe_ccic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cafe_ccic.c	2010-02-24 13:52:17.000000000 -0500
@@ -1723,7 +1723,6 @@ static const struct v4l2_ioctl_ops cafe_
 
 static struct video_device cafe_v4l_template = {
 	.name = "cafe",
-	.minor = -1, /* Get one dynamically */
 	.tvnorms = V4L2_STD_NTSC_M,
 	.current_norm = V4L2_STD_NTSC_M,  /* make mplayer happy */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cpia2/cpia2_v4l.c linux-libre-2.6.33-gnu1/drivers/media/video/cpia2/cpia2_v4l.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cpia2/cpia2_v4l.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cpia2/cpia2_v4l.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,17 +38,12 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/videodev.h>
+#include <linux/stringify.h>
 #include <media/v4l2-ioctl.h>
 
 #include "cpia2.h"
 #include "cpia2dev.h"
 
-
-//#define _CPIA2_DEBUG_
-
-#define MAKE_STRING_1(x)	#x
-#define MAKE_STRING(x)	MAKE_STRING_1(x)
-
 static int video_nr = -1;
 module_param(video_nr, int, 0);
 MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
@@ -60,26 +55,26 @@ MODULE_PARM_DESC(buffer_size, "Size for
 static int num_buffers = 3;
 module_param(num_buffers, int, 0);
 MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
-		 MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");
+		 __stringify(VIDEO_MAX_FRAME) ", default 3)");
 
 static int alternate = DEFAULT_ALT;
 module_param(alternate, int, 0);
-MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"
-		 MAKE_STRING(USBIF_ISO_6) ", default "
-		 MAKE_STRING(DEFAULT_ALT) ")");
+MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
+		 __stringify(USBIF_ISO_6) ", default "
+		 __stringify(DEFAULT_ALT) ")");
 
 static int flicker_freq = 60;
 module_param(flicker_freq, int, 0);
-MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"
-		 MAKE_STRING(60) ", default "
-		 MAKE_STRING(60) ")");
+MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
+		 __stringify(60) ", default "
+		 __stringify(60) ")");
 
 static int flicker_mode = NEVER_FLICKER;
 module_param(flicker_mode, int, 0);
 MODULE_PARM_DESC(flicker_mode,
-		 "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"
-		 MAKE_STRING(ANTI_FLICKER_ON) ", default "
-		 MAKE_STRING(NEVER_FLICKER) ")");
+		 "Flicker supression (" __stringify(NEVER_FLICKER) "or"
+		 __stringify(ANTI_FLICKER_ON) ", default "
+		 __stringify(NEVER_FLICKER) ")");
 
 MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
 MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
@@ -1926,7 +1921,6 @@ static const struct v4l2_file_operations
 static struct video_device cpia2_template = {
 	/* I could not find any place for the old .initialize initializer?? */
 	.name=		"CPiA2 Camera",
-	.minor=		-1,
 	.fops=		&fops_template,
 	.release=	video_device_release,
 };
@@ -1967,9 +1961,9 @@ void cpia2_unregister_camera(struct came
 	if (!cam->open_count) {
 		video_unregister_device(cam->vdev);
 	} else {
-		LOG("/dev/video%d removed while open, "
-		    "deferring video_unregister_device\n",
-		    cam->vdev->num);
+		LOG("%s removed while open, deferring "
+		    "video_unregister_device\n",
+		    video_device_node_name(cam->vdev));
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cpia.c linux-libre-2.6.33-gnu1/drivers/media/video/cpia.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cpia.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cpia.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/ctype.h>
@@ -244,72 +245,67 @@ static void rvfree(void *mem, unsigned l
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *cpia_proc_root=NULL;
 
-static int cpia_read_proc(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int cpia_proc_show(struct seq_file *m, void *v)
 {
-	char *out = page;
-	int len, tmp;
-	struct cam_data *cam = data;
+	struct cam_data *cam = m->private;
+	int tmp;
 	char tmpstr[29];
 
-	/* IMPORTANT: This output MUST be kept under PAGE_SIZE
-	 *            or we need to get more sophisticated. */
-
-	out += sprintf(out, "read-only\n-----------------------\n");
-	out += sprintf(out, "V4L Driver version:       %d.%d.%d\n",
+	seq_printf(m, "read-only\n-----------------------\n");
+	seq_printf(m, "V4L Driver version:       %d.%d.%d\n",
 		       CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
-	out += sprintf(out, "CPIA Version:             %d.%02d (%d.%d)\n",
+	seq_printf(m, "CPIA Version:             %d.%02d (%d.%d)\n",
 		       cam->params.version.firmwareVersion,
 		       cam->params.version.firmwareRevision,
 		       cam->params.version.vcVersion,
 		       cam->params.version.vcRevision);
-	out += sprintf(out, "CPIA PnP-ID:              %04x:%04x:%04x\n",
+	seq_printf(m, "CPIA PnP-ID:              %04x:%04x:%04x\n",
 		       cam->params.pnpID.vendor, cam->params.pnpID.product,
 		       cam->params.pnpID.deviceRevision);
-	out += sprintf(out, "VP-Version:               %d.%d %04x\n",
+	seq_printf(m, "VP-Version:               %d.%d %04x\n",
 		       cam->params.vpVersion.vpVersion,
 		       cam->params.vpVersion.vpRevision,
 		       cam->params.vpVersion.cameraHeadID);
 
-	out += sprintf(out, "system_state:             %#04x\n",
+	seq_printf(m, "system_state:             %#04x\n",
 		       cam->params.status.systemState);
-	out += sprintf(out, "grab_state:               %#04x\n",
+	seq_printf(m, "grab_state:               %#04x\n",
 		       cam->params.status.grabState);
-	out += sprintf(out, "stream_state:             %#04x\n",
+	seq_printf(m, "stream_state:             %#04x\n",
 		       cam->params.status.streamState);
-	out += sprintf(out, "fatal_error:              %#04x\n",
+	seq_printf(m, "fatal_error:              %#04x\n",
 		       cam->params.status.fatalError);
-	out += sprintf(out, "cmd_error:                %#04x\n",
+	seq_printf(m, "cmd_error:                %#04x\n",
 		       cam->params.status.cmdError);
-	out += sprintf(out, "debug_flags:              %#04x\n",
+	seq_printf(m, "debug_flags:              %#04x\n",
 		       cam->params.status.debugFlags);
-	out += sprintf(out, "vp_status:                %#04x\n",
+	seq_printf(m, "vp_status:                %#04x\n",
 		       cam->params.status.vpStatus);
-	out += sprintf(out, "error_code:               %#04x\n",
+	seq_printf(m, "error_code:               %#04x\n",
 		       cam->params.status.errorCode);
 	/* QX3 specific entries */
 	if (cam->params.qx3.qx3_detected) {
-		out += sprintf(out, "button:                   %4d\n",
+		seq_printf(m, "button:                   %4d\n",
 			       cam->params.qx3.button);
-		out += sprintf(out, "cradled:                  %4d\n",
+		seq_printf(m, "cradled:                  %4d\n",
 			       cam->params.qx3.cradled);
 	}
-	out += sprintf(out, "video_size:               %s\n",
+	seq_printf(m, "video_size:               %s\n",
 		       cam->params.format.videoSize == VIDEOSIZE_CIF ?
 		       "CIF " : "QCIF");
-	out += sprintf(out, "roi:                      (%3d, %3d) to (%3d, %3d)\n",
+	seq_printf(m, "roi:                      (%3d, %3d) to (%3d, %3d)\n",
 		       cam->params.roi.colStart*8,
 		       cam->params.roi.rowStart*4,
 		       cam->params.roi.colEnd*8,
 		       cam->params.roi.rowEnd*4);
-	out += sprintf(out, "actual_fps:               %3d\n", cam->fps);
-	out += sprintf(out, "transfer_rate:            %4dkB/s\n",
+	seq_printf(m, "actual_fps:               %3d\n", cam->fps);
+	seq_printf(m, "transfer_rate:            %4dkB/s\n",
 		       cam->transfer_rate);
 
-	out += sprintf(out, "\nread-write\n");
-	out += sprintf(out, "-----------------------  current       min"
+	seq_printf(m, "\nread-write\n");
+	seq_printf(m, "-----------------------  current       min"
 		       "       max   default  comment\n");
-	out += sprintf(out, "brightness:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "brightness:             %8d  %8d  %8d  %8d\n",
 		       cam->params.colourParams.brightness, 0, 100, 50);
 	if (cam->params.version.firmwareVersion == 1 &&
 	   cam->params.version.firmwareRevision == 2)
@@ -318,26 +314,26 @@ static int cpia_read_proc(char *page, ch
 	else
 		tmp = 96;
 
-	out += sprintf(out, "contrast:               %8d  %8d  %8d  %8d"
+	seq_printf(m, "contrast:               %8d  %8d  %8d  %8d"
 		       "  steps of 8\n",
 		       cam->params.colourParams.contrast, 0, tmp, 48);
-	out += sprintf(out, "saturation:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "saturation:             %8d  %8d  %8d  %8d\n",
 		       cam->params.colourParams.saturation, 0, 100, 50);
 	tmp = (25000+5000*cam->params.sensorFps.baserate)/
 	      (1<<cam->params.sensorFps.divisor);
-	out += sprintf(out, "sensor_fps:             %4d.%03d  %8d  %8d  %8d\n",
+	seq_printf(m, "sensor_fps:             %4d.%03d  %8d  %8d  %8d\n",
 		       tmp/1000, tmp%1000, 3, 30, 15);
-	out += sprintf(out, "stream_start_line:      %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "stream_start_line:      %8d  %8d  %8d  %8d\n",
 		       2*cam->params.streamStartLine, 0,
 		       cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
 		       cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
-	out += sprintf(out, "sub_sample:             %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "sub_sample:             %8s  %8s  %8s  %8s\n",
 		       cam->params.format.subSample == SUBSAMPLE_420 ?
 		       "420" : "422", "420", "422", "422");
-	out += sprintf(out, "yuv_order:              %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "yuv_order:              %8s  %8s  %8s  %8s\n",
 		       cam->params.format.yuvOrder == YUVORDER_YUYV ?
 		       "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
-	out += sprintf(out, "ecp_timing:             %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "ecp_timing:             %8s  %8s  %8s  %8s\n",
 		       cam->params.ecpTiming ? "slow" : "normal", "slow",
 		       "normal", "normal");
 
@@ -346,13 +342,13 @@ static int cpia_read_proc(char *page, ch
 	} else {
 		sprintf(tmpstr, "manual");
 	}
-	out += sprintf(out, "color_balance_mode:     %8s  %8s  %8s"
+	seq_printf(m, "color_balance_mode:     %8s  %8s  %8s"
 		       "  %8s\n",  tmpstr, "manual", "auto", "auto");
-	out += sprintf(out, "red_gain:               %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "red_gain:               %8d  %8d  %8d  %8d\n",
 		       cam->params.colourBalance.redGain, 0, 212, 32);
-	out += sprintf(out, "green_gain:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "green_gain:             %8d  %8d  %8d  %8d\n",
 		       cam->params.colourBalance.greenGain, 0, 212, 6);
-	out += sprintf(out, "blue_gain:              %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "blue_gain:              %8d  %8d  %8d  %8d\n",
 		       cam->params.colourBalance.blueGain, 0, 212, 92);
 
 	if (cam->params.version.firmwareVersion == 1 &&
@@ -363,10 +359,10 @@ static int cpia_read_proc(char *page, ch
 		sprintf(tmpstr, "%8d  %8d  %8d", 1, 8, 2);
 
 	if (cam->params.exposure.gainMode == 0)
-		out += sprintf(out, "max_gain:                unknown  %28s"
+		seq_printf(m, "max_gain:                unknown  %28s"
 			       "  powers of 2\n", tmpstr);
 	else
-		out += sprintf(out, "max_gain:               %8d  %28s"
+		seq_printf(m, "max_gain:               %8d  %28s"
 			       "  1,2,4 or 8 \n",
 			       1<<(cam->params.exposure.gainMode-1), tmpstr);
 
@@ -382,12 +378,12 @@ static int cpia_read_proc(char *page, ch
 		sprintf(tmpstr, "unknown");
 		break;
 	}
-	out += sprintf(out, "exposure_mode:          %8s  %8s  %8s"
+	seq_printf(m, "exposure_mode:          %8s  %8s  %8s"
 		       "  %8s\n",  tmpstr, "manual", "auto", "auto");
-	out += sprintf(out, "centre_weight:          %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "centre_weight:          %8s  %8s  %8s  %8s\n",
 		       (2-cam->params.exposure.centreWeight) ? "on" : "off",
 		       "off", "on", "on");
-	out += sprintf(out, "gain:                   %8d  %8d  max_gain  %8d  1,2,4,8 possible\n",
+	seq_printf(m, "gain:                   %8d  %8d  max_gain  %8d  1,2,4,8 possible\n",
 		       1<<cam->params.exposure.gain, 1, 1);
 	if (cam->params.version.firmwareVersion == 1 &&
 	   cam->params.version.firmwareRevision == 2)
@@ -396,7 +392,7 @@ static int cpia_read_proc(char *page, ch
 	else
 		tmp = 510;
 
-	out += sprintf(out, "fine_exp:               %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "fine_exp:               %8d  %8d  %8d  %8d\n",
 		       cam->params.exposure.fineExp*2, 0, tmp, 0);
 	if (cam->params.version.firmwareVersion == 1 &&
 	   cam->params.version.firmwareRevision == 2)
@@ -405,127 +401,122 @@ static int cpia_read_proc(char *page, ch
 	else
 		tmp = MAX_EXP;
 
-	out += sprintf(out, "coarse_exp:             %8d  %8d  %8d"
+	seq_printf(m, "coarse_exp:             %8d  %8d  %8d"
 		       "  %8d\n", cam->params.exposure.coarseExpLo+
 		       256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
-	out += sprintf(out, "red_comp:               %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "red_comp:               %8d  %8d  %8d  %8d\n",
 		       cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
-	out += sprintf(out, "green1_comp:            %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "green1_comp:            %8d  %8d  %8d  %8d\n",
 		       cam->params.exposure.green1Comp, COMP_GREEN1, 255,
 		       COMP_GREEN1);
-	out += sprintf(out, "green2_comp:            %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "green2_comp:            %8d  %8d  %8d  %8d\n",
 		       cam->params.exposure.green2Comp, COMP_GREEN2, 255,
 		       COMP_GREEN2);
-	out += sprintf(out, "blue_comp:              %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "blue_comp:              %8d  %8d  %8d  %8d\n",
 		       cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
 
-	out += sprintf(out, "apcor_gain1:            %#8x  %#8x  %#8x  %#8x\n",
+	seq_printf(m, "apcor_gain1:            %#8x  %#8x  %#8x  %#8x\n",
 		       cam->params.apcor.gain1, 0, 0xff, 0x1c);
-	out += sprintf(out, "apcor_gain2:            %#8x  %#8x  %#8x  %#8x\n",
+	seq_printf(m, "apcor_gain2:            %#8x  %#8x  %#8x  %#8x\n",
 		       cam->params.apcor.gain2, 0, 0xff, 0x1a);
-	out += sprintf(out, "apcor_gain4:            %#8x  %#8x  %#8x  %#8x\n",
+	seq_printf(m, "apcor_gain4:            %#8x  %#8x  %#8x  %#8x\n",
 		       cam->params.apcor.gain4, 0, 0xff, 0x2d);
-	out += sprintf(out, "apcor_gain8:            %#8x  %#8x  %#8x  %#8x\n",
+	seq_printf(m, "apcor_gain8:            %#8x  %#8x  %#8x  %#8x\n",
 		       cam->params.apcor.gain8, 0, 0xff, 0x2a);
-	out += sprintf(out, "vl_offset_gain1:        %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "vl_offset_gain1:        %8d  %8d  %8d  %8d\n",
 		       cam->params.vlOffset.gain1, 0, 255, 24);
-	out += sprintf(out, "vl_offset_gain2:        %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "vl_offset_gain2:        %8d  %8d  %8d  %8d\n",
 		       cam->params.vlOffset.gain2, 0, 255, 28);
-	out += sprintf(out, "vl_offset_gain4:        %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "vl_offset_gain4:        %8d  %8d  %8d  %8d\n",
 		       cam->params.vlOffset.gain4, 0, 255, 30);
-	out += sprintf(out, "vl_offset_gain8:        %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "vl_offset_gain8:        %8d  %8d  %8d  %8d\n",
 		       cam->params.vlOffset.gain8, 0, 255, 30);
-	out += sprintf(out, "flicker_control:        %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "flicker_control:        %8s  %8s  %8s  %8s\n",
 		       cam->params.flickerControl.flickerMode ? "on" : "off",
 		       "off", "on", "off");
-	out += sprintf(out, "mains_frequency:        %8d  %8d  %8d  %8d"
+	seq_printf(m, "mains_frequency:        %8d  %8d  %8d  %8d"
 		       " only 50/60\n",
 		       cam->mainsFreq ? 60 : 50, 50, 60, 50);
 	if(cam->params.flickerControl.allowableOverExposure < 0)
-		out += sprintf(out, "allowable_overexposure: %4dauto      auto  %8d      auto\n",
+		seq_printf(m, "allowable_overexposure: %4dauto      auto  %8d      auto\n",
 			       -cam->params.flickerControl.allowableOverExposure,
 			       255);
 	else
-		out += sprintf(out, "allowable_overexposure: %8d      auto  %8d      auto\n",
+		seq_printf(m, "allowable_overexposure: %8d      auto  %8d      auto\n",
 			       cam->params.flickerControl.allowableOverExposure,
 			       255);
-	out += sprintf(out, "compression_mode:       ");
+	seq_printf(m, "compression_mode:       ");
 	switch(cam->params.compression.mode) {
 	case CPIA_COMPRESSION_NONE:
-		out += sprintf(out, "%8s", "none");
+		seq_printf(m, "%8s", "none");
 		break;
 	case CPIA_COMPRESSION_AUTO:
-		out += sprintf(out, "%8s", "auto");
+		seq_printf(m, "%8s", "auto");
 		break;
 	case CPIA_COMPRESSION_MANUAL:
-		out += sprintf(out, "%8s", "manual");
+		seq_printf(m, "%8s", "manual");
 		break;
 	default:
-		out += sprintf(out, "%8s", "unknown");
+		seq_printf(m, "%8s", "unknown");
 		break;
 	}
-	out += sprintf(out, "    none,auto,manual      auto\n");
-	out += sprintf(out, "decimation_enable:      %8s  %8s  %8s  %8s\n",
+	seq_printf(m, "    none,auto,manual      auto\n");
+	seq_printf(m, "decimation_enable:      %8s  %8s  %8s  %8s\n",
 		       cam->params.compression.decimation ==
 		       DECIMATION_ENAB ? "on":"off", "off", "on",
 		       "off");
-	out += sprintf(out, "compression_target:    %9s %9s %9s %9s\n",
+	seq_printf(m, "compression_target:    %9s %9s %9s %9s\n",
 		       cam->params.compressionTarget.frTargeting  ==
 		       CPIA_COMPRESSION_TARGET_FRAMERATE ?
 		       "framerate":"quality",
 		       "framerate", "quality", "quality");
-	out += sprintf(out, "target_framerate:       %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "target_framerate:       %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionTarget.targetFR, 1, 30, 15);
-	out += sprintf(out, "target_quality:         %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "target_quality:         %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionTarget.targetQ, 1, 64, 5);
-	out += sprintf(out, "y_threshold:            %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "y_threshold:            %8d  %8d  %8d  %8d\n",
 		       cam->params.yuvThreshold.yThreshold, 0, 31, 6);
-	out += sprintf(out, "uv_threshold:           %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "uv_threshold:           %8d  %8d  %8d  %8d\n",
 		       cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
-	out += sprintf(out, "hysteresis:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "hysteresis:             %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.hysteresis, 0, 255, 3);
-	out += sprintf(out, "threshold_max:          %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "threshold_max:          %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.threshMax, 0, 255, 11);
-	out += sprintf(out, "small_step:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "small_step:             %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.smallStep, 0, 255, 1);
-	out += sprintf(out, "large_step:             %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "large_step:             %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.largeStep, 0, 255, 3);
-	out += sprintf(out, "decimation_hysteresis:  %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "decimation_hysteresis:  %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.decimationHysteresis,
 		       0, 255, 2);
-	out += sprintf(out, "fr_diff_step_thresh:    %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "fr_diff_step_thresh:    %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.frDiffStepThresh,
 		       0, 255, 5);
-	out += sprintf(out, "q_diff_step_thresh:     %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "q_diff_step_thresh:     %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.qDiffStepThresh,
 		       0, 255, 3);
-	out += sprintf(out, "decimation_thresh_mod:  %8d  %8d  %8d  %8d\n",
+	seq_printf(m, "decimation_thresh_mod:  %8d  %8d  %8d  %8d\n",
 		       cam->params.compressionParams.decimationThreshMod,
 		       0, 255, 2);
 	/* QX3 specific entries */
 	if (cam->params.qx3.qx3_detected) {
-		out += sprintf(out, "toplight:               %8s  %8s  %8s  %8s\n",
+		seq_printf(m, "toplight:               %8s  %8s  %8s  %8s\n",
 			       cam->params.qx3.toplight ? "on" : "off",
 			       "off", "on", "off");
-		out += sprintf(out, "bottomlight:            %8s  %8s  %8s  %8s\n",
+		seq_printf(m, "bottomlight:            %8s  %8s  %8s  %8s\n",
 			       cam->params.qx3.bottomlight ? "on" : "off",
 			       "off", "on", "off");
 	}
 
-	len = out - page;
-	len -= off;
-	if (len < count) {
-		*eof = 1;
-		if (len <= 0) return 0;
-	} else
-		len = count;
-
-	*start = page + off;
-	return len;
+	return 0;
 }
 
+static int cpia_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cpia_proc_show, PDE(inode)->data);
+}
 
-static int match(char *checkstr, char **buffer, unsigned long *count,
+static int match(char *checkstr, char **buffer, size_t *count,
 		 int *find_colon, int *err)
 {
 	int ret, colon_found = 1;
@@ -551,7 +542,7 @@ static int match(char *checkstr, char **
 	return ret;
 }
 
-static unsigned long int value(char **buffer, unsigned long *count, int *err)
+static unsigned long int value(char **buffer, size_t *count, int *err)
 {
 	char *p;
 	unsigned long int ret;
@@ -565,10 +556,10 @@ static unsigned long int value(char **bu
 	return ret;
 }
 
-static int cpia_write_proc(struct file *file, const char __user *buf,
-			   unsigned long count, void *data)
+static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
+			       size_t count, loff_t *pos)
 {
-	struct cam_data *cam = data;
+	struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
 	struct cam_params new_params;
 	char *page, *buffer;
 	int retval, find_colon;
@@ -582,7 +573,7 @@ static int cpia_write_proc(struct file *
 	 * from the comx driver
 	 */
 	if (count > PAGE_SIZE) {
-		printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
+		printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
 		return -ENOSPC;
 	}
 
@@ -1340,23 +1331,28 @@ out:
 	return retval;
 }
 
+static const struct file_operations cpia_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= cpia_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= cpia_proc_write,
+};
+
 static void create_proc_cpia_cam(struct cam_data *cam)
 {
-	char name[5 + 1 + 10 + 1];
 	struct proc_dir_entry *ent;
 
 	if (!cpia_proc_root || !cam)
 		return;
 
-	snprintf(name, sizeof(name), "video%d", cam->vdev.num);
-
-	ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
+	ent = proc_create_data(video_device_node_name(&cam->vdev),
+			       S_IRUGO|S_IWUSR, cpia_proc_root,
+			       &cpia_proc_fops, cam);
 	if (!ent)
 		return;
 
-	ent->data = cam;
-	ent->read_proc = cpia_read_proc;
-	ent->write_proc = cpia_write_proc;
 	/*
 	   size of the proc entry is 3736 bytes for the standard webcam;
 	   the extra features of the QX3 microscope add 189 bytes.
@@ -1368,13 +1364,10 @@ static void create_proc_cpia_cam(struct
 
 static void destroy_proc_cpia_cam(struct cam_data *cam)
 {
-	char name[5 + 1 + 10 + 1];
-
 	if (!cam || !cam->proc_entry)
 		return;
 
-	snprintf(name, sizeof(name), "video%d", cam->vdev.num);
-	remove_proc_entry(name, cpia_proc_root);
+	remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root);
 	cam->proc_entry = NULL;
 }
 
@@ -3999,7 +3992,7 @@ void cpia_unregister_camera(struct cam_d
 	}
 
 #ifdef CONFIG_PROC_FS
-	DBG("destroying /proc/cpia/video%d\n", cam->vdev.num);
+	DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev));
 	destroy_proc_cpia_cam(cam);
 #endif
 	if (!cam->open_count) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/c-qcam.c linux-libre-2.6.33-gnu1/drivers/media/video/c-qcam.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/c-qcam.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/c-qcam.c	2010-02-24 13:52:17.000000000 -0500
@@ -809,8 +809,8 @@ static int init_cqcam(struct parport *po
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
-	       qcam->vdev.num, qcam->pport->name);
+	printk(KERN_INFO "%s: Colour QuickCam found on %s\n",
+	       video_device_node_name(&qcam->vdev), qcam->pport->name);
 
 	qcams[num_cams++] = qcam;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-av-core.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-av-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-av-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-av-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,10 +99,8 @@ int cx18_av_and_or4(struct cx18 *cx, u16
 			     or_value);
 }
 
-static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
+static void cx18_av_init(struct cx18 *cx)
 {
-	struct cx18 *cx = v4l2_get_subdevdata(sd);
-
 	/*
 	 * The crystal freq used in calculations in this driver will be
 	 * 28.636360 MHz.
@@ -125,7 +123,6 @@ static int cx18_av_init(struct v4l2_subd
 
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
 	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-	return 0;
 }
 
 static void cx18_av_initialize(struct v4l2_subdev *sd)
@@ -198,7 +195,7 @@ static void cx18_av_initialize(struct v4
 	cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
 
 	/* Setup the Video and and Aux/Audio PLLs */
-	cx18_av_init(sd, 0);
+	cx18_av_init(cx);
 
 	/* set video to auto-detect */
 	/* Clear bits 11-12 to enable slow locking mode.  Set autodetect mode */
@@ -1355,7 +1352,6 @@ static int cx18_av_s_register(struct v4l
 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,
-	.init = cx18_av_init,
 	.load_fw = cx18_av_load_fw,
 	.reset = cx18_av_reset,
 	.queryctrl = cx18_av_queryctrl,
@@ -1399,6 +1395,7 @@ int cx18_av_probe(struct cx18 *cx)
 {
 	struct cx18_av_state *state = &cx->av_state;
 	struct v4l2_subdev *sd;
+	int err;
 
 	state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
 	state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
@@ -1417,5 +1414,8 @@ int cx18_av_probe(struct cx18 *cx)
 	snprintf(sd->name, sizeof(sd->name),
 		 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
 	sd->grp_id = CX18_HW_418_AV;
-	return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+	err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+	if (!err)
+		cx18_av_init(cx);
+	return err;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-av-core.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-av-core.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-av-core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-av-core.h	2010-02-24 13:52:17.000000000 -0500
@@ -294,7 +294,7 @@ struct cx18_av_state {
 #define CXADEC_QAM_CONST_DEC       0x924
 #define CXADEC_QAM_ROTATOR_FREQ    0x948
 
-/* Bit defintions / settings used in Mako Audio */
+/* Bit definitions / settings used in Mako Audio */
 #define CXADEC_PREF_MODE_MONO_LANGA        0
 #define CXADEC_PREF_MODE_MONO_LANGB        1
 #define CXADEC_PREF_MODE_MONO_LANGC        2
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-cards.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-cards.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-cards.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-cards.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,9 @@
 #define CX18_HW_Z8F0811_IR_HAUP	(CX18_HW_Z8F0811_IR_RX_HAUP | \
 				 CX18_HW_Z8F0811_IR_TX_HAUP)
 
+#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
+			CX18_HW_Z8F0811_IR_TX_HAUP)
+
 /* video inputs */
 #define	CX18_CARD_INPUT_VID_TUNER	1
 #define	CX18_CARD_INPUT_SVIDEO1 	2
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-driver.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 12:03:49.000000000 -0400
@@ -87,7 +87,6 @@ static int enc_ts_bufsize = CX18_DEFAULT
 static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
 static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
 static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
-/* VBI bufsize based on standards supported by card tuner for now */
 static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
 
 static int enc_ts_bufs = -1;
@@ -128,7 +127,6 @@ module_param(enc_ts_bufsize, int, 0644);
 module_param(enc_mpg_bufsize, int, 0644);
 module_param(enc_idx_bufsize, int, 0644);
 module_param(enc_yuv_bufsize, int, 0644);
-/* VBI bufsize based on standards supported by card tuner for now */
 module_param(enc_pcm_bufsize, int, 0644);
 
 module_param(enc_ts_bufs, int, 0644);
@@ -211,7 +209,9 @@ MODULE_PARM_DESC(enc_yuv_buffers,
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
 MODULE_PARM_DESC(enc_yuv_bufsize,
 		 "Size of an encoder YUV buffer (kB)\n"
-		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
+		 "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
+		 "\t\t\t(multiples of size required for 32 screen lines)\n"
+		 "\t\t\tDefault: 102");
 MODULE_PARM_DESC(enc_yuv_bufs,
 		 "Number of encoder YUV buffers\n"
 		 "\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -220,7 +220,7 @@ MODULE_PARM_DESC(enc_vbi_buffers,
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
 MODULE_PARM_DESC(enc_vbi_bufs,
 		 "Number of encoder VBI buffers\n"
-		 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std");
+		 "\t\t\tDefault is computed from enc_vbi_buffers");
 MODULE_PARM_DESC(enc_pcm_buffers,
 		 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
 		 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
@@ -499,10 +499,27 @@ static void cx18_process_options(struct
 			continue;
 		}
 		/*
+		 * YUV is a special case where the stream_buf_size needs to be
+		 * an integral multiple of 33.75 kB (storage for 32 screens
+		 * lines to maintain alignment in case of lost buffers
+		 */
+		if (i == CX18_ENC_STREAM_TYPE_YUV) {
+			cx->stream_buf_size[i] *= 1024;
+			cx->stream_buf_size[i] -=
+			   (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
+
+			if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
+				cx->stream_buf_size[i] =
+						CX18_UNIT_ENC_YUV_BUFSIZE;
+		}
+		/*
+		 * YUV is a special case where the stream_buf_size is
+		 * now in bytes.
 		 * VBI is a special case where the stream_buf_size is fixed
 		 * and already in bytes
 		 */
-		if (i == CX18_ENC_STREAM_TYPE_VBI) {
+		if (i == CX18_ENC_STREAM_TYPE_VBI ||
+		    i == CX18_ENC_STREAM_TYPE_YUV) {
 			if (cx->stream_buffers[i] < 0) {
 				cx->stream_buffers[i] =
 					cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +530,24 @@ static void cx18_process_options(struct
 					cx->stream_buffers[i]
 					* cx->stream_buf_size[i]/(1024 * 1024);
 			}
-			continue;
-		}
-		/* All other streams have stream_buf_size in kB at this point */
-		if (cx->stream_buffers[i] < 0) {
-			cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
-						/ cx->stream_buf_size[i];
 		} else {
-			/* N.B. This might round down to 0 */
-			cx->options.megabytes[i] =
-			  cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
+			/* All other streams have stream_buf_size in kB here */
+			if (cx->stream_buffers[i] < 0) {
+				cx->stream_buffers[i] =
+						cx->options.megabytes[i] * 1024
+						/ cx->stream_buf_size[i];
+			} else {
+				/* N.B. This might round down to 0 */
+				cx->options.megabytes[i] =
+						cx->stream_buffers[i]
+						* cx->stream_buf_size[i] / 1024;
+			}
+			/* convert from kB to bytes */
+			cx->stream_buf_size[i] *= 1024;
 		}
-		cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
+		CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
+				"%d bytes\n", i, cx->options.megabytes[i],
+				cx->stream_buffers[i], cx->stream_buf_size[i]);
 	}
 
 	cx->options.cardtype = cardtype[cx->instance];
@@ -669,6 +692,12 @@ static int __devinit cx18_init_struct1(s
 	cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
 	cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
 
+	/* IVTV style VBI insertion into MPEG streams */
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_buf.list);
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.list);
+	INIT_LIST_HEAD(&cx->vbi.sliced_mpeg_mdl.buf_list);
+	list_add(&cx->vbi.sliced_mpeg_buf.list,
+		 &cx->vbi.sliced_mpeg_mdl.buf_list);
 	return 0;
 }
 
@@ -883,7 +912,6 @@ static int __devinit cx18_probe(struct p
 		CX18_ERR("Could not register A/V decoder subdevice\n");
 		goto free_map;
 	}
-	cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
 
 	/* Initialize GPIO Reset Controller to do chip resets during i2c init */
 	if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
@@ -1200,7 +1228,7 @@ static struct pci_driver cx18_pci_driver
       .remove =   cx18_remove,
 };
 
-static int module_start(void)
+static int __init module_start(void)
 {
 	printk(KERN_INFO "cx18:  Start initialization, version %s\n", CX18_VERSION);
 
@@ -1224,7 +1252,7 @@ static int module_start(void)
 	return 0;
 }
 
-static void module_cleanup(void)
+static void __exit module_cleanup(void)
 {
 	pci_unregister_driver(&cx18_pci_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-driver.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-driver.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-driver.h	2010-02-24 13:52:17.000000000 -0500
@@ -50,6 +50,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
+#include <media/ir-kbd-i2c.h>
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
 #include "cx23418.h"
@@ -120,12 +121,16 @@
 /* Maximum firmware DMA buffers per stream */
 #define CX18_MAX_FW_MDLS_PER_STREAM 63
 
+/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
+#define CX18_UNIT_ENC_YUV_BUFSIZE	(720 *  32 * 3 / 2) /* bytes */
+#define CX18_625_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
+#define CX18_525_LINE_ENC_YUV_BUFSIZE	(CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
+
 /* DMA buffer, default size in kB allocated */
 #define CX18_DEFAULT_ENC_TS_BUFSIZE   32
 #define CX18_DEFAULT_ENC_MPG_BUFSIZE  32
 #define CX18_DEFAULT_ENC_IDX_BUFSIZE  32
-#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128
-/* Default VBI bufsize based on standards supported by card tuner for now */
+#define CX18_DEFAULT_ENC_YUV_BUFSIZE  (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
 #define CX18_DEFAULT_ENC_PCM_BUFSIZE   4
 
 /* i2c stuff */
@@ -246,8 +251,8 @@ struct cx18_options {
 	int radio;		/* enable/disable radio */
 };
 
-/* per-buffer bit flags */
-#define CX18_F_B_NEED_BUF_SWAP  0	/* this buffer should be byte swapped */
+/* per-mdl bit flags */
+#define CX18_F_M_NEED_SWAP  0	/* mdl buffer data must be endianess swapped */
 
 /* per-stream, s_flags */
 #define CX18_F_S_CLAIMED 	3	/* this stream is claimed */
@@ -274,18 +279,29 @@ struct cx18_options {
 struct cx18_buffer {
 	struct list_head list;
 	dma_addr_t dma_handle;
-	u32 id;
-	unsigned long b_flags;
-	unsigned skipped;
 	char *buf;
 
 	u32 bytesused;
 	u32 readpos;
 };
 
+struct cx18_mdl {
+	struct list_head list;
+	u32 id;		/* index into cx->scb->cpu_mdl[] of 1st cx18_mdl_ent */
+
+	unsigned int skipped;
+	unsigned long m_flags;
+
+	struct list_head buf_list;
+	struct cx18_buffer *curr_buf; /* current buffer in list for reading */
+
+	u32 bytesused;
+	u32 readpos;
+};
+
 struct cx18_queue {
 	struct list_head list;
-	atomic_t buffers;
+	atomic_t depth;
 	u32 bytesused;
 	spinlock_t lock;
 };
@@ -337,7 +353,7 @@ struct cx18_stream {
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
 	u32 handle;			/* task handle */
-	unsigned mdl_offset;
+	unsigned int mdl_base_idx;
 
 	u32 id;
 	unsigned long s_flags;	/* status flags, see above */
@@ -346,14 +362,20 @@ struct cx18_stream {
 				   PCI_DMA_NONE */
 	wait_queue_head_t waitq;
 
-	/* Buffer Stats */
-	u32 buffers;
-	u32 buf_size;
+	/* Buffers */
+	struct list_head buf_pool;	/* buffers not attached to an MDL */
+	u32 buffers;			/* total buffers owned by this stream */
+	u32 buf_size;			/* size in bytes of a single buffer */
 
-	/* Buffer Queues */
-	struct cx18_queue q_free;	/* free buffers */
-	struct cx18_queue q_busy;	/* busy buffers - in use by firmware */
-	struct cx18_queue q_full;	/* full buffers - data for user apps */
+	/* MDL sizes - all stream MDLs are the same size */
+	u32 bufs_per_mdl;
+	u32 mdl_size;		/* total bytes in all buffers in a mdl */
+
+	/* MDL Queues */
+	struct cx18_queue q_free;	/* free - in rotation, not committed */
+	struct cx18_queue q_busy;	/* busy - in use by firmware */
+	struct cx18_queue q_full;	/* full - data for user apps */
+	struct cx18_queue q_idle;	/* idle - not in rotation */
 
 	struct work_struct out_work_order;
 
@@ -481,10 +503,11 @@ struct vbi_info {
 	u32 inserted_frame;
 
 	/*
-	 * A dummy driver stream transfer buffer with a copy of the next
+	 * A dummy driver stream transfer mdl & buffer with a copy of the next
 	 * sliced_mpeg_data[] buffer for output to userland apps.
 	 * Only used in cx18-fileops.c, but its state needs to persist at times.
 	 */
+	struct cx18_mdl sliced_mpeg_mdl;
 	struct cx18_buffer sliced_mpeg_buf;
 };
 
@@ -511,10 +534,9 @@ struct cx18 {
 	u8 is_60hz;
 	u8 nof_inputs;		/* number of video inputs */
 	u8 nof_audio_inputs;	/* number of audio inputs */
-	u16 buffer_id;		/* buffer ID counter */
 	u32 v4l2_cap;		/* V4L2 capabilities of card */
 	u32 hw_flags; 		/* Hardware description of the board */
-	unsigned mdl_offset;
+	unsigned int free_mdl_idx;
 	struct cx18_scb __iomem *scb; /* pointer to SCB */
 	struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
 	struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -585,6 +607,8 @@ struct cx18 {
 	struct i2c_algo_bit_data i2c_algo[2];
 	struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
 
+	struct IR_i2c_init_data ir_i2c_init_data;
+
 	/* gpio */
 	u32 gpio_dir;
 	u32 gpio_val;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-dvb.c	2013-05-03 13:58:17.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-dvb.c	2013-05-03 12:06:58.000000000 -0400
@@ -61,6 +61,7 @@ static struct mxl5005s_config hauppauge_
 	.top		 = MXL5005S_TOP_25P2,
 	.mod_mode        = MXL_DIGITAL_MODE,
 	.if_mode         = MXL_ZERO_IF,
+	.qam_gain        = 0x02,
 	.AgcMasterByte   = 0x00,
 };
 
@@ -71,7 +72,8 @@ static struct s5h1409_config hauppauge_h
 	.qam_if        = 44000,
 	.inversion     = S5H1409_INVERSION_OFF,
 	.status_mode   = S5H1409_DEMODLOCKING,
-	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+	.hvr1600_opt   = S5H1409_HVR1600_OPTIMIZE
 };
 
 /*
@@ -360,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream
 	dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
 
 	CX18_INFO("DVB Frontend registered\n");
-	CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n",
+	CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
 		  stream->dvb.dvb_adapter.num, stream->name,
-		  stream->buffers, stream->buf_size/1024);
+		  stream->buffers, stream->buf_size/1024,
+		  (stream->buf_size * 100 / 1024) % 100);
 
 	mutex_init(&dvb->feedlock);
 	dvb->enabled = 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-fileops.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-fileops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-fileops.c	2010-02-24 13:52:17.000000000 -0500
@@ -166,11 +166,12 @@ static void cx18_dualwatch(struct cx18 *
 }
 
 
-static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err)
+static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
+				     int *err)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 	DEFINE_WAIT(wait);
 
 	*err = 0;
@@ -185,32 +186,33 @@ static struct cx18_buffer *cx18_get_buff
 			}
 			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
-				while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
+				while ((mdl = cx18_dequeue(s_vbi,
+							   &s_vbi->q_full))) {
 					/* byteswap and process VBI data */
-					cx18_process_vbi_data(cx, buf,
+					cx18_process_vbi_data(cx, mdl,
 							      s_vbi->type);
-					cx18_stream_put_buf_fw(s_vbi, buf);
+					cx18_stream_put_mdl_fw(s_vbi, mdl);
 				}
 			}
-			buf = &cx->vbi.sliced_mpeg_buf;
-			if (buf->readpos != buf->bytesused)
-				return buf;
+			mdl = &cx->vbi.sliced_mpeg_mdl;
+			if (mdl->readpos != mdl->bytesused)
+				return mdl;
 		}
 
 		/* do we have new data? */
-		buf = cx18_dequeue(s, &s->q_full);
-		if (buf) {
-			if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP,
-						&buf->b_flags))
-				return buf;
+		mdl = cx18_dequeue(s, &s->q_full);
+		if (mdl) {
+			if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
+						&mdl->m_flags))
+				return mdl;
 			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 				/* byteswap MPG data */
-				cx18_buf_swap(buf);
+				cx18_mdl_swap(mdl);
 			else {
 				/* byteswap and process VBI data */
-				cx18_process_vbi_data(cx, buf, s->type);
+				cx18_process_vbi_data(cx, mdl, s->type);
 			}
-			return buf;
+			return mdl;
 		}
 
 		/* return if end of stream */
@@ -229,7 +231,7 @@ static struct cx18_buffer *cx18_get_buff
 		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
 		/* New buffers might have become available before we were added
 		   to the waitqueue */
-		if (!atomic_read(&s->q_full.buffers))
+		if (!atomic_read(&s->q_full.depth))
 			schedule();
 		finish_wait(&s->waitq, &wait);
 		if (signal_pending(current)) {
@@ -241,21 +243,28 @@ static struct cx18_buffer *cx18_get_buff
 	}
 }
 
-static void cx18_setup_sliced_vbi_buf(struct cx18 *cx)
+static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
 {
+	struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
+	struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
 	int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 
-	cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx];
-	cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx];
-	cx->vbi.sliced_mpeg_buf.readpos = 0;
+	buf->buf = cx->vbi.sliced_mpeg_data[idx];
+	buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
+	buf->readpos = 0;
+
+	mdl->curr_buf = NULL;
+	mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
+	mdl->readpos = 0;
 }
 
 static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
-		struct cx18_buffer *buf, char __user *ubuf, size_t ucount)
+	struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
 {
 	struct cx18 *cx = s->cx;
 	size_t len = buf->bytesused - buf->readpos;
 
+	*stop = false;
 	if (len > ucount)
 		len = ucount;
 	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
@@ -335,7 +344,8 @@ static size_t cx18_copy_buf_to_user(stru
 				/* We declare we actually found a Program Pack*/
 				cx->search_pack_header = 0; /* expect vid PES */
 				len = (char *)q - start;
-				cx18_setup_sliced_vbi_buf(cx);
+				cx18_setup_sliced_vbi_mdl(cx);
+				*stop = true;
 				break;
 			}
 		}
@@ -352,6 +362,60 @@ static size_t cx18_copy_buf_to_user(stru
 	return len;
 }
 
+/**
+ * list_entry_is_past_end - check if a previous loop cursor is off list end
+ * @pos:	the type * previously used as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Check if the entry's list_head is the head of the list, thus it's not a
+ * real entry but was the loop cursor that walked past the end
+ */
+#define list_entry_is_past_end(pos, head, member) \
+	(&pos->member == (head))
+
+static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
+		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
+{
+	size_t tot_written = 0;
+	int rc;
+	bool stop = false;
+
+	if (mdl->curr_buf == NULL)
+		mdl->curr_buf = list_first_entry(&mdl->buf_list,
+						 struct cx18_buffer, list);
+
+	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
+		/*
+		 * For some reason we've exhausted the buffers, but the MDL
+		 * object still said some data was unread.
+		 * Fix that and bail out.
+		 */
+		mdl->readpos = mdl->bytesused;
+		return 0;
+	}
+
+	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
+
+		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
+			continue;
+
+		rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
+					   ucount - tot_written, &stop);
+		if (rc < 0)
+			return rc;
+		mdl->readpos += rc;
+		tot_written += rc;
+
+		if (stop ||	/* Forced stopping point for VBI insertion */
+		    tot_written >= ucount ||	/* Reader request statisfied */
+		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
+		    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
+			break;
+	}
+	return tot_written;
+}
+
 static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
 		size_t tot_count, int non_block)
 {
@@ -373,12 +437,12 @@ static ssize_t cx18_read(struct cx18_str
 		single_frame = 1;
 
 	for (;;) {
-		struct cx18_buffer *buf;
+		struct cx18_mdl *mdl;
 		int rc;
 
-		buf = cx18_get_buffer(s, non_block, &rc);
+		mdl = cx18_get_mdl(s, non_block, &rc);
 		/* if there is no data available... */
-		if (buf == NULL) {
+		if (mdl == NULL) {
 			/* if we got data, then return that regardless */
 			if (tot_written)
 				break;
@@ -392,20 +456,20 @@ static ssize_t cx18_read(struct cx18_str
 			return rc;
 		}
 
-		rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written,
+		rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
 				tot_count - tot_written);
 
-		if (buf != &cx->vbi.sliced_mpeg_buf) {
-			if (buf->readpos == buf->bytesused)
-				cx18_stream_put_buf_fw(s, buf);
+		if (mdl != &cx->vbi.sliced_mpeg_mdl) {
+			if (mdl->readpos == mdl->bytesused)
+				cx18_stream_put_mdl_fw(s, mdl);
 			else
-				cx18_push(s, buf, &s->q_full);
-		} else if (buf->readpos == buf->bytesused) {
+				cx18_push(s, mdl, &s->q_full);
+		} else if (mdl->readpos == mdl->bytesused) {
 			int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 
 			cx->vbi.sliced_mpeg_size[idx] = 0;
 			cx->vbi.inserted_frame++;
-			cx->vbi_data_inserted += buf->bytesused;
+			cx->vbi_data_inserted += mdl->bytesused;
 		}
 		if (rc < 0)
 			return rc;
@@ -543,7 +607,7 @@ unsigned int cx18_v4l2_enc_poll(struct f
 	CX18_DEBUG_HI_FILE("Encoder poll\n");
 	poll_wait(filp, &s->waitq, wait);
 
-	if (atomic_read(&s->q_full.buffers))
+	if (atomic_read(&s->q_full.depth))
 		return POLLIN | POLLRDNORM;
 	if (eof)
 		return POLLHUP;
@@ -694,8 +758,8 @@ int cx18_v4l2_open(struct file *filp)
 
 	mutex_lock(&cx->serialize_lock);
 	if (cx18_init_on_first_open(cx)) {
-		CX18_ERR("Failed to initialize on minor %d\n",
-			 video_dev->minor);
+		CX18_ERR("Failed to initialize on %s\n",
+			 video_device_node_name(video_dev));
 		mutex_unlock(&cx->serialize_lock);
 		return -ENXIO;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-i2c.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,6 @@
 #include "cx18-gpio.h"
 #include "cx18-i2c.h"
 #include "cx18-irq.h"
-#include <media/ir-kbd-i2c.h>
 
 #define CX18_REG_I2C_1_WR   0xf15000
 #define CX18_REG_I2C_1_RD   0xf15008
@@ -97,17 +96,11 @@ static const char * const hw_devicenames
 	"ir_rx_z8f0811_haup",
 };
 
-static const struct IR_i2c_init_data z8f0811_ir_init_data = {
-	.ir_codes = &ir_codes_hauppauge_new_table,
-	.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
-	.type = IR_TYPE_RC5,
-	.name = "CX23418 Z8F0811 Hauppauge",
-};
-
-static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
-			   u8 addr)
+static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
+			   const char *type, u8 addr)
 {
 	struct i2c_board_info info;
+	struct IR_i2c_init_data *init_data = &cx->ir_i2c_init_data;
 	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
 
 	memset(&info, 0, sizeof(struct i2c_board_info));
@@ -116,9 +109,11 @@ static int cx18_i2c_new_ir(struct i2c_ad
 	/* Our default information for ir-kbd-i2c.c to use */
 	switch (hw) {
 	case CX18_HW_Z8F0811_IR_RX_HAUP:
-		info.platform_data = (void *) &z8f0811_ir_init_data;
-		break;
-	default:
+		init_data->ir_codes = &ir_codes_hauppauge_new_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = cx->card_name;
+		info.platform_data = init_data;
 		break;
 	}
 
@@ -154,8 +149,8 @@ int cx18_i2c_register(struct cx18 *cx, u
 		return sd != NULL ? 0 : -1;
 	}
 
-	if (hw & CX18_HW_Z8F0811_IR_HAUP)
-		return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]);
+	if (hw & CX18_HW_IR_ANY)
+		return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
 
 	/* Is it not an I2C device or one we do not wish to register? */
 	if (!hw_addrs[idx])
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-ioctl.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -910,7 +910,8 @@ static int cx18_log_status(struct file *
 			continue;
 		CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
 			  s->name, s->s_flags,
-			  atomic_read(&s->q_full.buffers) * 100 / s->buffers,
+			  atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
+			   / s->buffers,
 			  (s->buffers * s->buf_size) / 1024, s->buffers);
 	}
 	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-mailbox.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,13 +131,39 @@ static void dump_mb(struct cx18 *cx, str
  * Functions that run in a work_queue work handling context
  */
 
+static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	if (!s->dvb.enabled || mdl->bytesused == 0)
+		return;
+
+	/* We ignore mdl and buf readpos accounting here - it doesn't matter */
+
+	/* The likely case */
+	if (list_is_singular(&mdl->buf_list)) {
+		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
+				       list);
+		if (buf->bytesused)
+			dvb_dmx_swfilter(&s->dvb.demux,
+					 buf->buf, buf->bytesused);
+		return;
+	}
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+		dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
+	}
+}
+
 static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
 {
 	u32 handle, mdl_ack_count, id;
 	struct cx18_mailbox *mb;
 	struct cx18_mdl_ack *mdl_ack;
 	struct cx18_stream *s;
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 	int i;
 
 	mb = &order->mb;
@@ -158,7 +184,7 @@ static void epu_dma_done(struct cx18 *cx
 		id = mdl_ack->id;
 		/*
 		 * Simple integrity check for processing a stale (and possibly
-		 * inconsistent mailbox): make sure the buffer id is in the
+		 * inconsistent mailbox): make sure the MDL id is in the
 		 * valid range for the stream.
 		 *
 		 * We go through the trouble of dealing with stale mailboxes
@@ -169,44 +195,42 @@ static void epu_dma_done(struct cx18 *cx
 		 * There are occasions when we get a half changed mailbox,
 		 * which this check catches for a handle & id mismatch.  If the
 		 * handle and id do correspond, the worst case is that we
-		 * completely lost the old buffer, but pick up the new buffer
+		 * completely lost the old MDL, but pick up the new MDL
 		 * early (but the new mdl_ack is guaranteed to be good in this
 		 * case as the firmware wouldn't point us to a new mdl_ack until
 		 * it's filled in).
 		 *
-		 * cx18_queue_get buf() will detect the lost buffers
+		 * cx18_queue_get_mdl() will detect the lost MDLs
 		 * and send them back to q_free for fw rotation eventually.
 		 */
 		if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
-		    !(id >= s->mdl_offset &&
-		      id < (s->mdl_offset + s->buffers))) {
+		    !(id >= s->mdl_base_idx &&
+		      id < (s->mdl_base_idx + s->buffers))) {
 			CX18_WARN("Fell behind! Ignoring stale mailbox with "
-				  " inconsistent data. Lost buffer for mailbox "
+				  " inconsistent data. Lost MDL for mailbox "
 				  "seq no %d\n", mb->request);
 			break;
 		}
-		buf = cx18_queue_get_buf(s, id, mdl_ack->data_used);
+		mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
 
-		CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
-		if (buf == NULL) {
-			CX18_WARN("Could not find buf %d for stream %s\n",
+		CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
+		if (mdl == NULL) {
+			CX18_WARN("Could not find MDL %d for stream %s\n",
 				  id, s->name);
 			continue;
 		}
 
 		CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
-				  s->name, buf->bytesused);
+				  s->name, mdl->bytesused);
 
 		if (s->type != CX18_ENC_STREAM_TYPE_TS)
-			cx18_enqueue(s, buf, &s->q_full);
+			cx18_enqueue(s, mdl, &s->q_full);
 		else {
-			if (s->dvb.enabled)
-				dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
-						 buf->bytesused);
-			cx18_enqueue(s, buf, &s->q_free);
+			cx18_mdl_send_to_dvb(s, mdl);
+			cx18_enqueue(s, mdl, &s->q_free);
 		}
 	}
-	/* Put as many buffers as possible back into fw use */
+	/* Put as many MDLs as possible back into fw use */
 	cx18_stream_load_fw_queue(s);
 
 	wake_up(&cx->dma_waitq);
@@ -616,7 +640,7 @@ static int cx18_api_call(struct cx18 *cx
 
 	/*
 	 * Wait for XPU to perform extra actions for the caller in some cases.
-	 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers
+	 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
 	 * back in a burst shortly thereafter
 	 */
 	if (info->flags & API_SLOW)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-mailbox.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-mailbox.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-mailbox.h	2010-02-24 13:52:17.000000000 -0500
@@ -39,14 +39,14 @@
 struct cx18;
 
 /*
- * This structure is used by CPU to provide completed buffers information
- * Its structure is dictrated by the layout of the SCB, required by the
- * firmware, but its defintion needs to be here, instead of in cx18-scb.h,
+ * This structure is used by CPU to provide completed MDL & buffers information.
+ * Its structure is dictated by the layout of the SCB, required by the
+ * firmware, but its definition needs to be here, instead of in cx18-scb.h,
  * for mailbox work order scheduling
  */
 struct cx18_mdl_ack {
     u32 id;        /* ID of a completed MDL */
-    u32 data_used; /* Total data filled in the MDL for buffer 'id' */
+    u32 data_used; /* Total data filled in the MDL with 'id' */
 };
 
 /* The cx18_mailbox struct is the mailbox structure which is used for passing
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-queue.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-queue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include "cx18-queue.h"
 #include "cx18-streams.h"
 #include "cx18-scb.h"
+#include "cx18-io.h"
 
 void cx18_buf_swap(struct cx18_buffer *buf)
 {
@@ -35,151 +36,312 @@ void cx18_buf_swap(struct cx18_buffer *b
 		swab32s((u32 *)(buf->buf + i));
 }
 
+void _cx18_mdl_swap(struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+		cx18_buf_swap(buf);
+	}
+}
+
 void cx18_queue_init(struct cx18_queue *q)
 {
 	INIT_LIST_HEAD(&q->list);
-	atomic_set(&q->buffers, 0);
+	atomic_set(&q->depth, 0);
 	q->bytesused = 0;
 }
 
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				 struct cx18_queue *q, int to_front)
 {
-	/* clear the buffer if it is not to be enqueued to the full queue */
+	/* clear the mdl if it is not to be enqueued to the full queue */
 	if (q != &s->q_full) {
-		buf->bytesused = 0;
-		buf->readpos = 0;
-		buf->b_flags = 0;
-		buf->skipped = 0;
+		mdl->bytesused = 0;
+		mdl->readpos = 0;
+		mdl->m_flags = 0;
+		mdl->skipped = 0;
+		mdl->curr_buf = NULL;
 	}
 
 	/* q_busy is restricted to a max buffer count imposed by firmware */
 	if (q == &s->q_busy &&
-	    atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
+	    atomic_read(&q->depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
 		q = &s->q_free;
 
 	spin_lock(&q->lock);
 
 	if (to_front)
-		list_add(&buf->list, &q->list); /* LIFO */
+		list_add(&mdl->list, &q->list); /* LIFO */
 	else
-		list_add_tail(&buf->list, &q->list); /* FIFO */
-	q->bytesused += buf->bytesused - buf->readpos;
-	atomic_inc(&q->buffers);
+		list_add_tail(&mdl->list, &q->list); /* FIFO */
+	q->bytesused += mdl->bytesused - mdl->readpos;
+	atomic_inc(&q->depth);
 
 	spin_unlock(&q->lock);
 	return q;
 }
 
-struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
+struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
 {
-	struct cx18_buffer *buf = NULL;
+	struct cx18_mdl *mdl = NULL;
 
 	spin_lock(&q->lock);
 	if (!list_empty(&q->list)) {
-		buf = list_first_entry(&q->list, struct cx18_buffer, list);
-		list_del_init(&buf->list);
-		q->bytesused -= buf->bytesused - buf->readpos;
-		buf->skipped = 0;
-		atomic_dec(&q->buffers);
+		mdl = list_first_entry(&q->list, struct cx18_mdl, list);
+		list_del_init(&mdl->list);
+		q->bytesused -= mdl->bytesused - mdl->readpos;
+		mdl->skipped = 0;
+		atomic_dec(&q->depth);
 	}
 	spin_unlock(&q->lock);
-	return buf;
+	return mdl;
 }
 
-struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
+static void _cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
+					  struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+	u32 buf_size = s->buf_size;
+	u32 bytesused = mdl->bytesused;
+
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		buf->readpos = 0;
+		if (bytesused >= buf_size) {
+			buf->bytesused = buf_size;
+			bytesused -= buf_size;
+		} else {
+			buf->bytesused = bytesused;
+			bytesused = 0;
+		}
+		cx18_buf_sync_for_cpu(s, buf);
+	}
+}
+
+static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
+						struct cx18_mdl *mdl)
+{
+	struct cx18_buffer *buf;
+
+	if (list_is_singular(&mdl->buf_list)) {
+		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
+				       list);
+		buf->bytesused = mdl->bytesused;
+		buf->readpos = 0;
+		cx18_buf_sync_for_cpu(s, buf);
+	} else {
+		_cx18_mdl_update_bufs_for_cpu(s, mdl);
+	}
+}
+
+struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
 	u32 bytesused)
 {
 	struct cx18 *cx = s->cx;
-	struct cx18_buffer *buf;
-	struct cx18_buffer *tmp;
-	struct cx18_buffer *ret = NULL;
+	struct cx18_mdl *mdl;
+	struct cx18_mdl *tmp;
+	struct cx18_mdl *ret = NULL;
 	LIST_HEAD(sweep_up);
 
 	/*
 	 * We don't have to acquire multiple q locks here, because we are
 	 * serialized by the single threaded work handler.
-	 * Buffers from the firmware will thus remain in order as
+	 * MDLs from the firmware will thus remain in order as
 	 * they are moved from q_busy to q_full or to the dvb ring buffer.
 	 */
 	spin_lock(&s->q_busy.lock);
-	list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
+	list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
 		/*
 		 * We should find what the firmware told us is done,
 		 * right at the front of the queue.  If we don't, we likely have
-		 * missed a buffer done message from the firmware.
-		 * Once we skip a buffer repeatedly, relative to the size of
+		 * missed an mdl done message from the firmware.
+		 * Once we skip an mdl repeatedly, relative to the size of
 		 * q_busy, we have high confidence we've missed it.
 		 */
-		if (buf->id != id) {
-			buf->skipped++;
-			if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
-				/* buffer must have fallen out of rotation */
-				CX18_WARN("Skipped %s, buffer %d, %d "
+		if (mdl->id != id) {
+			mdl->skipped++;
+			if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
+				/* mdl must have fallen out of rotation */
+				CX18_WARN("Skipped %s, MDL %d, %d "
 					  "times - it must have dropped out of "
-					  "rotation\n", s->name, buf->id,
-					  buf->skipped);
+					  "rotation\n", s->name, mdl->id,
+					  mdl->skipped);
 				/* Sweep it up to put it back into rotation */
-				list_move_tail(&buf->list, &sweep_up);
-				atomic_dec(&s->q_busy.buffers);
+				list_move_tail(&mdl->list, &sweep_up);
+				atomic_dec(&s->q_busy.depth);
 			}
 			continue;
 		}
 		/*
-		 * We pull the desired buffer off of the queue here.  Something
+		 * We pull the desired mdl off of the queue here.  Something
 		 * will have to put it back on a queue later.
 		 */
-		list_del_init(&buf->list);
-		atomic_dec(&s->q_busy.buffers);
-		ret = buf;
+		list_del_init(&mdl->list);
+		atomic_dec(&s->q_busy.depth);
+		ret = mdl;
 		break;
 	}
 	spin_unlock(&s->q_busy.lock);
 
 	/*
-	 * We found the buffer for which we were looking.  Get it ready for
+	 * We found the mdl for which we were looking.  Get it ready for
 	 * the caller to put on q_full or in the dvb ring buffer.
 	 */
 	if (ret != NULL) {
 		ret->bytesused = bytesused;
 		ret->skipped = 0;
-		/* readpos and b_flags were 0'ed when the buf went on q_busy */
-		cx18_buf_sync_for_cpu(s, ret);
+		/* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
+		cx18_mdl_update_bufs_for_cpu(s, ret);
 		if (s->type != CX18_ENC_STREAM_TYPE_TS)
-			set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
+			set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
 	}
 
-	/* Put any buffers the firmware is ignoring back into normal rotation */
-	list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
-		list_del_init(&buf->list);
-		cx18_enqueue(s, buf, &s->q_free);
+	/* Put any mdls the firmware is ignoring back into normal rotation */
+	list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
+		list_del_init(&mdl->list);
+		cx18_enqueue(s, mdl, &s->q_free);
 	}
 	return ret;
 }
 
-/* Move all buffers of a queue to q_free, while flushing the buffers */
-static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
+/* Move all mdls of a queue, while flushing the mdl */
+static void cx18_queue_flush(struct cx18_stream *s,
+			     struct cx18_queue *q_src, struct cx18_queue *q_dst)
 {
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 
-	if (q == &s->q_free)
+	/* It only makes sense to flush to q_free or q_idle */
+	if (q_src == q_dst || q_dst == &s->q_full || q_dst == &s->q_busy)
 		return;
 
-	spin_lock(&q->lock);
-	while (!list_empty(&q->list)) {
-		buf = list_first_entry(&q->list, struct cx18_buffer, list);
-		list_move_tail(&buf->list, &s->q_free.list);
-		buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0;
-		atomic_inc(&s->q_free.buffers);
+	spin_lock(&q_src->lock);
+	spin_lock(&q_dst->lock);
+	while (!list_empty(&q_src->list)) {
+		mdl = list_first_entry(&q_src->list, struct cx18_mdl, list);
+		list_move_tail(&mdl->list, &q_dst->list);
+		mdl->bytesused = 0;
+		mdl->readpos = 0;
+		mdl->m_flags = 0;
+		mdl->skipped = 0;
+		mdl->curr_buf = NULL;
+		atomic_inc(&q_dst->depth);
 	}
-	cx18_queue_init(q);
-	spin_unlock(&q->lock);
+	cx18_queue_init(q_src);
+	spin_unlock(&q_src->lock);
+	spin_unlock(&q_dst->lock);
 }
 
 void cx18_flush_queues(struct cx18_stream *s)
 {
-	cx18_queue_flush(s, &s->q_busy);
-	cx18_queue_flush(s, &s->q_full);
+	cx18_queue_flush(s, &s->q_busy, &s->q_free);
+	cx18_queue_flush(s, &s->q_full, &s->q_free);
+}
+
+/*
+ * Note, s->buf_pool is not protected by a lock,
+ * the stream better not have *anything* going on when calling this
+ */
+void cx18_unload_queues(struct cx18_stream *s)
+{
+	struct cx18_queue *q_idle = &s->q_idle;
+	struct cx18_mdl *mdl;
+	struct cx18_buffer *buf;
+
+	/* Move all MDLS to q_idle */
+	cx18_queue_flush(s, &s->q_busy, q_idle);
+	cx18_queue_flush(s, &s->q_full, q_idle);
+	cx18_queue_flush(s, &s->q_free, q_idle);
+
+	/* Reset MDL id's and move all buffers back to the stream's buf_pool */
+	spin_lock(&q_idle->lock);
+	list_for_each_entry(mdl, &q_idle->list, list) {
+		while (!list_empty(&mdl->buf_list)) {
+			buf = list_first_entry(&mdl->buf_list,
+					       struct cx18_buffer, list);
+			list_move_tail(&buf->list, &s->buf_pool);
+			buf->bytesused = 0;
+			buf->readpos = 0;
+		}
+		mdl->id = s->mdl_base_idx; /* reset id to a "safe" value */
+		/* all other mdl fields were cleared by cx18_queue_flush() */
+	}
+	spin_unlock(&q_idle->lock);
+}
+
+/*
+ * Note, s->buf_pool is not protected by a lock,
+ * the stream better not have *anything* going on when calling this
+ */
+void cx18_load_queues(struct cx18_stream *s)
+{
+	struct cx18 *cx = s->cx;
+	struct cx18_mdl *mdl;
+	struct cx18_buffer *buf;
+	int mdl_id;
+	int i;
+	u32 partial_buf_size;
+
+	/*
+	 * Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
+	 * Excess MDLs are left on q_idle
+	 * Excess buffers are left in buf_pool and/or on an MDL in q_idle
+	 */
+	mdl_id = s->mdl_base_idx;
+	for (mdl = cx18_dequeue(s, &s->q_idle), i = s->bufs_per_mdl;
+	     mdl != NULL && i == s->bufs_per_mdl;
+	     mdl = cx18_dequeue(s, &s->q_idle)) {
+
+		mdl->id = mdl_id;
+
+		for (i = 0; i < s->bufs_per_mdl; i++) {
+			if (list_empty(&s->buf_pool))
+				break;
+
+			buf = list_first_entry(&s->buf_pool, struct cx18_buffer,
+					       list);
+			list_move_tail(&buf->list, &mdl->buf_list);
+
+			/* update the firmware's MDL array with this buffer */
+			cx18_writel(cx, buf->dma_handle,
+				    &cx->scb->cpu_mdl[mdl_id + i].paddr);
+			cx18_writel(cx, s->buf_size,
+				    &cx->scb->cpu_mdl[mdl_id + i].length);
+		}
+
+		if (i == s->bufs_per_mdl) {
+			/*
+			 * The encoder doesn't honor s->mdl_size.  So in the
+			 * case of a non-integral number of buffers to meet
+			 * mdl_size, we lie about the size of the last buffer
+			 * in the MDL to get the encoder to really only send
+			 * us mdl_size bytes per MDL transfer.
+			 */
+			partial_buf_size = s->mdl_size % s->buf_size;
+			if (partial_buf_size) {
+				cx18_writel(cx, partial_buf_size,
+				      &cx->scb->cpu_mdl[mdl_id + i - 1].length);
+			}
+			cx18_enqueue(s, mdl, &s->q_free);
+		} else {
+			/* Not enough buffers for this MDL; we won't use it */
+			cx18_push(s, mdl, &s->q_idle);
+		}
+		mdl_id += i;
+	}
+}
+
+void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl)
+{
+	int dma = s->dma;
+	u32 buf_size = s->buf_size;
+	struct pci_dev *pci_dev = s->cx->pci_dev;
+	struct cx18_buffer *buf;
+
+	list_for_each_entry(buf, &mdl->buf_list, list)
+		pci_dma_sync_single_for_device(pci_dev, buf->dma_handle,
+					       buf_size, dma);
 }
 
 int cx18_stream_alloc(struct cx18_stream *s)
@@ -190,44 +352,62 @@ int cx18_stream_alloc(struct cx18_stream
 	if (s->buffers == 0)
 		return 0;
 
-	CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
+	CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
+			"(%d.%02d kB total)\n",
 		s->name, s->buffers, s->buf_size,
-		s->buffers * s->buf_size / 1024);
+		s->buffers * s->buf_size / 1024,
+		(s->buffers * s->buf_size * 100 / 1024) % 100);
 
-	if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
+	if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
 				(char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
 		unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
 					((char __iomem *)cx->scb->cpu_mdl));
 
 		CX18_ERR("Too many buffers, cannot fit in SCB area\n");
 		CX18_ERR("Max buffers = %zd\n",
-			bufsz / sizeof(struct cx18_mdl));
+			bufsz / sizeof(struct cx18_mdl_ent));
 		return -ENOMEM;
 	}
 
-	s->mdl_offset = cx->mdl_offset;
+	s->mdl_base_idx = cx->free_mdl_idx;
 
-	/* allocate stream buffers. Initially all buffers are in q_free. */
+	/* allocate stream buffers and MDLs */
 	for (i = 0; i < s->buffers; i++) {
-		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
-						GFP_KERNEL|__GFP_NOWARN);
+		struct cx18_mdl *mdl;
+		struct cx18_buffer *buf;
 
-		if (buf == NULL)
+		/* 1 MDL per buffer to handle the worst & also default case */
+		mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN);
+		if (mdl == NULL)
+			break;
+
+		buf = kzalloc(sizeof(struct cx18_buffer),
+				GFP_KERNEL|__GFP_NOWARN);
+		if (buf == NULL) {
+			kfree(mdl);
 			break;
+		}
+
 		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
+			kfree(mdl);
 			kfree(buf);
 			break;
 		}
-		buf->id = cx->buffer_id++;
+
+		INIT_LIST_HEAD(&mdl->list);
+		INIT_LIST_HEAD(&mdl->buf_list);
+		mdl->id = s->mdl_base_idx; /* a somewhat safe value */
+		cx18_enqueue(s, mdl, &s->q_idle);
+
 		INIT_LIST_HEAD(&buf->list);
 		buf->dma_handle = pci_map_single(s->cx->pci_dev,
 				buf->buf, s->buf_size, s->dma);
 		cx18_buf_sync_for_cpu(s, buf);
-		cx18_enqueue(s, buf, &s->q_free);
+		list_add_tail(&buf->list, &s->buf_pool);
 	}
 	if (i == s->buffers) {
-		cx->mdl_offset += s->buffers;
+		cx->free_mdl_idx += s->buffers;
 		return 0;
 	}
 	CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
@@ -237,13 +417,21 @@ int cx18_stream_alloc(struct cx18_stream
 
 void cx18_stream_free(struct cx18_stream *s)
 {
+	struct cx18_mdl *mdl;
 	struct cx18_buffer *buf;
 
-	/* move all buffers to q_free */
-	cx18_flush_queues(s);
+	/* move all buffers to buf_pool and all MDLs to q_idle */
+	cx18_unload_queues(s);
+
+	/* empty q_idle */
+	while ((mdl = cx18_dequeue(s, &s->q_idle)))
+		kfree(mdl);
+
+	/* empty buf_pool */
+	while (!list_empty(&s->buf_pool)) {
+		buf = list_first_entry(&s->buf_pool, struct cx18_buffer, list);
+		list_del_init(&buf->list);
 
-	/* empty q_free */
-	while ((buf = cx18_dequeue(s, &s->q_free))) {
 		pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
 				s->buf_size, s->dma);
 		kfree(buf->buf);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-queue.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-queue.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-queue.h	2010-02-24 13:52:17.000000000 -0500
@@ -40,32 +40,59 @@ static inline void cx18_buf_sync_for_dev
 				s->buf_size, s->dma);
 }
 
+void _cx18_mdl_sync_for_device(struct cx18_stream *s, struct cx18_mdl *mdl);
+
+static inline void cx18_mdl_sync_for_device(struct cx18_stream *s,
+					    struct cx18_mdl *mdl)
+{
+	if (list_is_singular(&mdl->buf_list))
+		cx18_buf_sync_for_device(s, list_first_entry(&mdl->buf_list,
+							     struct cx18_buffer,
+							     list));
+	else
+		_cx18_mdl_sync_for_device(s, mdl);
+}
+
 void cx18_buf_swap(struct cx18_buffer *buf);
+void _cx18_mdl_swap(struct cx18_mdl *mdl);
+
+static inline void cx18_mdl_swap(struct cx18_mdl *mdl)
+{
+	if (list_is_singular(&mdl->buf_list))
+		cx18_buf_swap(list_first_entry(&mdl->buf_list,
+					       struct cx18_buffer, list));
+	else
+		_cx18_mdl_swap(mdl);
+}
 
 /* cx18_queue utility functions */
-struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				 struct cx18_queue *q, int to_front);
 
 static inline
-struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_mdl *mdl,
 				struct cx18_queue *q)
 {
-	return _cx18_enqueue(s, buf, q, 0); /* FIFO */
+	return _cx18_enqueue(s, mdl, q, 0); /* FIFO */
 }
 
 static inline
-struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf,
+struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_mdl *mdl,
 			     struct cx18_queue *q)
 {
-	return _cx18_enqueue(s, buf, q, 1); /* LIFO */
+	return _cx18_enqueue(s, mdl, q, 1); /* LIFO */
 }
 
 void cx18_queue_init(struct cx18_queue *q);
-struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
+struct cx18_mdl *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
+struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
 	u32 bytesused);
 void cx18_flush_queues(struct cx18_stream *s);
 
+/* queue MDL reconfiguration helpers */
+void cx18_unload_queues(struct cx18_stream *s);
+void cx18_load_queues(struct cx18_stream *s);
+
 /* cx18_stream utility functions */
 int cx18_stream_alloc(struct cx18_stream *s);
 void cx18_stream_free(struct cx18_stream *s);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-scb.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-scb.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-scb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-scb.h	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@
 
 
 /* This structure is used by EPU to provide memory descriptors in its memory */
-struct cx18_mdl {
+struct cx18_mdl_ent {
     u32 paddr;  /* Physical address of a buffer segment */
     u32 length; /* Length of the buffer segment */
 };
@@ -272,7 +272,7 @@ struct cx18_scb {
 	struct cx18_mailbox  ppu2epu_mb;
 
 	struct cx18_mdl_ack  cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
-	struct cx18_mdl      cpu_mdl[1];
+	struct cx18_mdl_ent  cpu_mdl[1];
 };
 
 void cx18_init_scb(struct cx18 *cx);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-streams.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-streams.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,6 +115,9 @@ static void cx18_stream_init(struct cx18
 	s->dma = cx18_stream_info[type].dma;
 	s->buffers = cx->stream_buffers[type];
 	s->buf_size = cx->stream_buf_size[type];
+	INIT_LIST_HEAD(&s->buf_pool);
+	s->bufs_per_mdl = 1;
+	s->mdl_size = s->buf_size * s->bufs_per_mdl;
 
 	init_waitqueue_head(&s->waitq);
 	s->id = -1;
@@ -124,6 +127,8 @@ static void cx18_stream_init(struct cx18
 	cx18_queue_init(&s->q_busy);
 	spin_lock_init(&s->q_full.lock);
 	cx18_queue_init(&s->q_full);
+	spin_lock_init(&s->q_idle.lock);
+	cx18_queue_init(&s->q_idle);
 
 	INIT_WORK(&s->out_work_order, cx18_out_work_handler);
 }
@@ -214,6 +219,7 @@ static int cx18_reg_dev(struct cx18 *cx,
 {
 	struct cx18_stream *s = &cx->streams[type];
 	int vfl_type = cx18_stream_info[type].vfl_type;
+	const char *name;
 	int num, ret;
 
 	/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
@@ -253,29 +259,30 @@ static int cx18_reg_dev(struct cx18 *cx,
 		s->video_dev = NULL;
 		return ret;
 	}
-	num = s->video_dev->num;
+
+	name = video_device_node_name(s->video_dev);
 
 	switch (vfl_type) {
 	case VFL_TYPE_GRABBER:
-		CX18_INFO("Registered device video%d for %s (%d x %d kB)\n",
-			  num, s->name, cx->stream_buffers[type],
-			  cx->stream_buf_size[type]/1024);
+		CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
+			  name, s->name, cx->stream_buffers[type],
+			  cx->stream_buf_size[type] / 1024,
+			  (cx->stream_buf_size[type] * 100 / 1024) % 100);
 		break;
 
 	case VFL_TYPE_RADIO:
-		CX18_INFO("Registered device radio%d for %s\n",
-			num, s->name);
+		CX18_INFO("Registered device %s for %s\n", name, s->name);
 		break;
 
 	case VFL_TYPE_VBI:
 		if (cx->stream_buffers[type])
-			CX18_INFO("Registered device vbi%d for %s "
+			CX18_INFO("Registered device %s for %s "
 				  "(%d x %d bytes)\n",
-				  num, s->name, cx->stream_buffers[type],
+				  name, s->name, cx->stream_buffers[type],
 				  cx->stream_buf_size[type]);
 		else
-			CX18_INFO("Registered device vbi%d for %s\n",
-				num, s->name);
+			CX18_INFO("Registered device %s for %s\n",
+				name, s->name);
 		break;
 	}
 
@@ -441,8 +448,8 @@ static void cx18_vbi_setup(struct cx18_s
 }
 
 static
-struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
-					   struct cx18_buffer *buf)
+struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
+					   struct cx18_mdl *mdl)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_queue *q;
@@ -451,16 +458,16 @@ struct cx18_queue *_cx18_stream_put_buf_
 	if (s->handle == CX18_INVALID_TASK_HANDLE ||
 	    test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
 	    !test_bit(CX18_F_S_STREAMING, &s->s_flags))
-		return cx18_enqueue(s, buf, &s->q_free);
+		return cx18_enqueue(s, mdl, &s->q_free);
 
-	q = cx18_enqueue(s, buf, &s->q_busy);
+	q = cx18_enqueue(s, mdl, &s->q_busy);
 	if (q != &s->q_busy)
-		return q; /* The firmware has the max buffers it can handle */
+		return q; /* The firmware has the max MDLs it can handle */
 
-	cx18_buf_sync_for_device(s, buf);
+	cx18_mdl_sync_for_device(s, mdl);
 	cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
-		  (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
-		  1, buf->id, s->buf_size);
+		  (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
+		  s->bufs_per_mdl, mdl->id, s->mdl_size);
 	return q;
 }
 
@@ -468,19 +475,19 @@ static
 void _cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 	struct cx18_queue *q;
-	struct cx18_buffer *buf;
+	struct cx18_mdl *mdl;
 
-	if (atomic_read(&s->q_free.buffers) == 0 ||
-	    atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
+	if (atomic_read(&s->q_free.depth) == 0 ||
+	    atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
 		return;
 
 	/* Move from q_free to q_busy notifying the firmware, until the limit */
 	do {
-		buf = cx18_dequeue(s, &s->q_free);
-		if (buf == NULL)
+		mdl = cx18_dequeue(s, &s->q_free);
+		if (mdl == NULL)
 			break;
-		q = _cx18_stream_put_buf_fw(s, buf);
-	} while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
+		q = _cx18_stream_put_mdl_fw(s, mdl);
+	} while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
 		 && q == &s->q_busy);
 }
 
@@ -492,11 +499,51 @@ void cx18_out_work_handler(struct work_s
 	_cx18_stream_load_fw_queue(s);
 }
 
+static void cx18_stream_configure_mdls(struct cx18_stream *s)
+{
+	cx18_unload_queues(s);
+
+	switch (s->type) {
+	case CX18_ENC_STREAM_TYPE_YUV:
+		/*
+		 * Height should be a multiple of 32 lines.
+		 * Set the MDL size to the exact size needed for one frame.
+		 * Use enough buffers per MDL to cover the MDL size
+		 */
+		s->mdl_size = 720 * s->cx->params.height * 3 / 2;
+		s->bufs_per_mdl = s->mdl_size / s->buf_size;
+		if (s->mdl_size % s->buf_size)
+			s->bufs_per_mdl++;
+		break;
+	case CX18_ENC_STREAM_TYPE_VBI:
+		s->bufs_per_mdl = 1;
+		if  (cx18_raw_vbi(s->cx)) {
+			s->mdl_size = (s->cx->is_60hz ? 12 : 18)
+						       * 2 * vbi_active_samples;
+		} else {
+			/*
+			 * See comment in cx18_vbi_setup() below about the
+			 * extra lines we capture in sliced VBI mode due to
+			 * the lines on which EAV RP codes toggle.
+			*/
+			s->mdl_size = s->cx->is_60hz
+				   ? (21 - 4 + 1) * 2 * vbi_hblank_samples_60Hz
+				   : (23 - 2 + 1) * 2 * vbi_hblank_samples_50Hz;
+		}
+		break;
+	default:
+		s->bufs_per_mdl = 1;
+		s->mdl_size = s->buf_size * s->bufs_per_mdl;
+		break;
+	}
+
+	cx18_load_queues(s);
+}
+
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
 {
 	u32 data[MAX_MB_ARGUMENTS];
 	struct cx18 *cx = s->cx;
-	struct cx18_buffer *buf;
 	int captype = 0;
 	struct cx18_api_func_private priv;
 
@@ -619,14 +666,7 @@ int cx18_start_v4l2_encode_stream(struct
 		(void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
 
 	/* Init all the cpu_mdls for this stream */
-	cx18_flush_queues(s);
-	spin_lock(&s->q_free.lock);
-	list_for_each_entry(buf, &s->q_free.list, list) {
-		cx18_writel(cx, buf->dma_handle,
-					&cx->scb->cpu_mdl[buf->id].paddr);
-		cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
-	}
-	spin_unlock(&s->q_free.lock);
+	cx18_stream_configure_mdls(s);
 	_cx18_stream_load_fw_queue(s);
 
 	/* begin_capture */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-streams.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-streams.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-streams.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,18 +28,18 @@ int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
 void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
-/* Related to submission of buffers to firmware */
+/* Related to submission of mdls to firmware */
 static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 	struct cx18 *cx = s->cx;
 	queue_work(cx->out_work_queue, &s->out_work_order);
 }
 
-static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
-					  struct cx18_buffer *buf)
+static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
+					  struct cx18_mdl *mdl)
 {
-	/* Put buf on q_free; the out work handler will move buf(s) to q_busy */
-	cx18_enqueue(s, buf, &s->q_free);
+	/* Put mdl on q_free; the out work handler will move mdl(s) to q_busy */
+	cx18_enqueue(s, mdl, &s->q_free);
 	cx18_stream_load_fw_queue(s);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-vbi.c linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-vbi.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-vbi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-vbi.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,6 +105,7 @@ static void copy_vbi_data(struct cx18 *c
 
 /* Compress raw VBI format, removes leading SAV codes and surplus space
    after the frame.  Returns new compressed size. */
+/* FIXME - this function ignores the input size. */
 static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
 {
 	u32 line_size = vbi_active_samples;
@@ -185,8 +186,7 @@ static u32 compress_sliced_buf(struct cx
 	return line;
 }
 
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
-			   int streamtype)
+static void _cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf)
 {
 	/*
 	 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
@@ -203,9 +203,6 @@ void cx18_process_vbi_data(struct cx18 *
 	u32 pts;
 	int lines;
 
-	if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
-		return;
-
 	/*
 	 * The CX23418 sends us data that is 32 bit little-endian swapped,
 	 * but we want the raw VBI bytes in the order they were in the raster
@@ -250,3 +247,31 @@ void cx18_process_vbi_data(struct cx18 *
 		copy_vbi_data(cx, lines, pts);
 	cx->vbi.frame++;
 }
+
+void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
+			   int streamtype)
+{
+	struct cx18_buffer *buf;
+	u32 orig_used;
+
+	if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
+		return;
+
+	/*
+	 * Big assumption here:
+	 * Every buffer hooked to the MDL's buf_list is a complete VBI frame
+	 * that ends at the end of the buffer.
+	 *
+	 * To assume anything else would make the code in this file
+	 * more complex, or require extra memcpy()'s to make the
+	 * buffers satisfy the above assumption.  It's just simpler to set
+	 * up the encoder buffer transfers to make the assumption true.
+	 */
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		orig_used = buf->bytesused;
+		if (orig_used == 0)
+			break;
+		_cx18_process_vbi_data(cx, buf);
+		mdl->bytesused -= (orig_used - buf->bytesused);
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-vbi.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-vbi.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-vbi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-vbi.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,6 @@
  *  02111-1307  USA
  */
 
-void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
+void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
 			   int streamtype);
 int cx18_used_line(struct cx18 *cx, int line, int field);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-version.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-version.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx18-version.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx18-version.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 2
+#define CX18_DRIVER_VERSION_MINOR 3
 #define CX18_DRIVER_VERSION_PATCHLEVEL 0
 
 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx23418.h linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx23418.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx18/cx23418.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx18/cx23418.h	2010-02-24 13:52:17.000000000 -0500
@@ -363,7 +363,7 @@
 /* Description: This command provides the offset to a Memory Descriptor List
    IN[0] - Task handle. Handle of the task to start
    IN[1] - Offset of the MDL from the beginning of the local DDR.
-   IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1]
+   IN[2] - Number of cx18_mdl_ent structures in the array pointed to by IN[1]
    IN[3] - Buffer ID
    IN[4] - Total buffer length
    ReturnCode - One of the ERR_DE_... */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c	2010-02-24 13:52:17.000000000 -0500
@@ -2414,9 +2414,11 @@ int cx231xx_gpio_i2c_read_ack(struct cx2
 		cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
 			     nInit * 10);
 
-	/* readAck
-	   throuth clock stretch ,slave has given a SCL signal,
-	   so the SDA data can be directly read.  */
+	/*
+	 * readAck
+	 * through clock stretch, slave has given a SCL signal,
+	 * so the SDA data can be directly read.
+	 */
 	status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
 
 	if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2013-05-03 12:03:50.000000000 -0400
@@ -68,19 +68,19 @@ struct cx231xx_board cx231xx_boards[] =
 				.type = CX231XX_VMUX_TELEVISION,
 				.vmux = CX231XX_VIN_3_1,
 				.amux = CX231XX_AMUX_VIDEO,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_COMPOSITE1,
 				.vmux = CX231XX_VIN_2_1,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_SVIDEO,
 				.vmux = CX231XX_VIN_1_1 |
 					(CX231XX_VIN_1_2 << 8) |
 					CX25840_SVIDEO_ON,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}
 		},
 	},
@@ -107,19 +107,19 @@ struct cx231xx_board cx231xx_boards[] =
 				.type = CX231XX_VMUX_TELEVISION,
 				.vmux = CX231XX_VIN_3_1,
 				.amux = CX231XX_AMUX_VIDEO,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_COMPOSITE1,
 				.vmux = CX231XX_VIN_2_1,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_SVIDEO,
 				.vmux = CX231XX_VIN_1_1 |
 					(CX231XX_VIN_1_2 << 8) |
 					CX25840_SVIDEO_ON,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}
 		},
 	},
@@ -147,19 +147,19 @@ struct cx231xx_board cx231xx_boards[] =
 				.type = CX231XX_VMUX_TELEVISION,
 				.vmux = CX231XX_VIN_3_1,
 				.amux = CX231XX_AMUX_VIDEO,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_COMPOSITE1,
 				.vmux = CX231XX_VIN_2_1,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}, {
 				.type = CX231XX_VMUX_SVIDEO,
 				.vmux = CX231XX_VIN_1_1 |
 					(CX231XX_VIN_1_2 << 8) |
 					CX25840_SVIDEO_ON,
 				.amux = CX231XX_AMUX_LINE_IN,
-				.gpio = 0,
+				.gpio = NULL,
 			}
 		},
 	},
@@ -856,8 +856,9 @@ static void cx231xx_usb_disconnect(struc
 
 	if (dev->users) {
 		cx231xx_warn
-		    ("device /dev/video%d is open! Deregistration and memory "
-		     "deallocation are deferred on close.\n", dev->vdev->num);
+		    ("device %s is open! Deregistration and memory "
+		     "deallocation are deferred on close.\n",
+		     video_device_node_name(dev->vdev));
 
 		dev->state |= DEV_MISCONFIGURED;
 		cx231xx_uninit_isoc(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-core.c linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,32 +66,6 @@ MODULE_PARM_DESC(alt, "alternate setting
 static LIST_HEAD(cx231xx_devlist);
 static DEFINE_MUTEX(cx231xx_devlist_mutex);
 
-struct cx231xx *cx231xx_get_device(int minor,
-				   enum v4l2_buf_type *fh_type, int *has_radio)
-{
-	struct cx231xx *h, *dev = NULL;
-
-	*fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	*has_radio = 0;
-
-	mutex_lock(&cx231xx_devlist_mutex);
-	list_for_each_entry(h, &cx231xx_devlist, devlist) {
-		if (h->vdev->minor == minor)
-			dev = h;
-		if (h->vbi_dev->minor == minor) {
-			dev = h;
-			*fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		}
-		if (h->radio_dev && h->radio_dev->minor == minor) {
-			dev = h;
-			*has_radio = 1;
-		}
-	}
-	mutex_unlock(&cx231xx_devlist_mutex);
-
-	return dev;
-}
-
 /*
  * cx231xx_realease_resources()
  * unregisters the v4l2,i2c and usb devices
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx.h linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -689,8 +689,6 @@ void cx231xx_release_analog_resources(st
 int cx231xx_register_analog_devices(struct cx231xx *dev);
 void cx231xx_remove_from_devlist(struct cx231xx *dev);
 void cx231xx_add_into_devlist(struct cx231xx *dev);
-struct cx231xx *cx231xx_get_device(int minor,
-				   enum v4l2_buf_type *fh_type, int *has_radio);
 void cx231xx_init_extension(struct cx231xx *dev);
 void cx231xx_close_extension(struct cx231xx *dev);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-input.c linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,8 +126,7 @@ static void cx231xx_ir_handle_key(struct
 
 	if (do_sendkey) {
 		dprintk("sending keypress\n");
-		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
-				 poll_result.rc_data[0]);
+		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 
@@ -198,7 +197,10 @@ int cx231xx_ir_init(struct cx231xx *dev)
 	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
 	strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-	ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_USB;
@@ -214,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 	cx231xx_ir_start(ir);
 
 	/* all done */
-	err = input_register_device(ir->input);
+	err = ir_input_register(ir->input, dev->board.ir_codes);
 	if (err)
 		goto err_out_stop;
 
@@ -223,7 +225,6 @@ err_out_stop:
 	cx231xx_ir_stop(ir);
 	dev->ir = NULL;
 err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -237,7 +238,7 @@ int cx231xx_ir_fini(struct cx231xx *dev)
 		return 0;
 
 	cx231xx_ir_stop(ir);
-	input_unregister_device(ir->input);
+	ir_input_unregister(ir->input);
 	kfree(ir);
 
 	/* done */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-video.c linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -1916,20 +1916,29 @@ static int radio_queryctrl(struct file *
  */
 static int cx231xx_v4l2_open(struct file *filp)
 {
-	int minor = video_devdata(filp)->minor;
 	int errCode = 0, radio = 0;
-	struct cx231xx *dev = NULL;
+	struct video_device *vdev = video_devdata(filp);
+	struct cx231xx *dev = video_drvdata(filp);
 	struct cx231xx_fh *fh;
 	enum v4l2_buf_type fh_type = 0;
 
-	dev = cx231xx_get_device(minor, &fh_type, &radio);
-	if (NULL == dev)
-		return -ENODEV;
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
+		fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		break;
+	case VFL_TYPE_VBI:
+		fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
+		break;
+	case VFL_TYPE_RADIO:
+		radio = 1;
+		break;
+	}
 
 	mutex_lock(&dev->lock);
 
-	cx231xx_videodbg("open minor=%d type=%s users=%d\n",
-			 minor, v4l2_type_names[fh_type], dev->users);
+	cx231xx_videodbg("open dev=%s type=%s users=%d\n",
+			 video_device_node_name(vdev), v4l2_type_names[fh_type],
+			 dev->users);
 
 #if 0
 	errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
@@ -2020,25 +2029,25 @@ void cx231xx_release_analog_resources(st
 	/*FIXME: I2C IR should be disconnected */
 
 	if (dev->radio_dev) {
-		if (-1 != dev->radio_dev->minor)
+		if (video_is_registered(dev->radio_dev))
 			video_unregister_device(dev->radio_dev);
 		else
 			video_device_release(dev->radio_dev);
 		dev->radio_dev = NULL;
 	}
 	if (dev->vbi_dev) {
-		cx231xx_info("V4L2 device /dev/vbi%d deregistered\n",
-			     dev->vbi_dev->num);
-		if (-1 != dev->vbi_dev->minor)
+		cx231xx_info("V4L2 device %s deregistered\n",
+			     video_device_node_name(dev->vbi_dev));
+		if (video_is_registered(dev->vbi_dev))
 			video_unregister_device(dev->vbi_dev);
 		else
 			video_device_release(dev->vbi_dev);
 		dev->vbi_dev = NULL;
 	}
 	if (dev->vdev) {
-		cx231xx_info("V4L2 device /dev/video%d deregistered\n",
-			     dev->vdev->num);
-		if (-1 != dev->vdev->minor)
+		cx231xx_info("V4L2 device %s deregistered\n",
+			     video_device_node_name(dev->vdev));
+		if (video_is_registered(dev->vdev))
 			video_unregister_device(dev->vdev);
 		else
 			video_device_release(dev->vdev);
@@ -2106,7 +2115,7 @@ static int cx231xx_v4l2_close(struct fil
 		}
 
 		/* Save some power by putting tuner to sleep */
-		call_all(dev, tuner, s_standby);
+		call_all(dev, core, s_power, 0);
 
 		/* do this before setting alternate! */
 		cx231xx_uninit_isoc(dev);
@@ -2268,7 +2277,6 @@ static const struct video_device cx231xx
 	.fops         = &cx231xx_v4l_fops,
 	.release      = video_device_release,
 	.ioctl_ops    = &video_ioctl_ops,
-	.minor        = -1,
 	.tvnorms      = V4L2_STD_ALL,
 	.current_norm = V4L2_STD_PAL,
 };
@@ -2303,7 +2311,6 @@ static struct video_device cx231xx_radio
 	.name      = "cx231xx-radio",
 	.fops      = &radio_fops,
 	.ioctl_ops = &radio_ioctl_ops,
-	.minor     = -1,
 };
 
 /******************************** usb interface ******************************/
@@ -2319,13 +2326,13 @@ static struct video_device *cx231xx_vdev
 		return NULL;
 
 	*vfd = *template;
-	vfd->minor = -1;
 	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	vfd->debug = video_debug;
 
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
 
+	video_set_drvdata(vfd, dev);
 	return vfd;
 }
 
@@ -2374,8 +2381,8 @@ int cx231xx_register_analog_devices(stru
 		return ret;
 	}
 
-	cx231xx_info("%s/0: registered device video%d [v4l2]\n",
-		     dev->name, dev->vdev->num);
+	cx231xx_info("%s/0: registered device %s [v4l2]\n",
+		     dev->name, video_device_node_name(dev->vdev));
 
 	/* Initialize VBI template */
 	memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
@@ -2393,8 +2400,8 @@ int cx231xx_register_analog_devices(stru
 		return ret;
 	}
 
-	cx231xx_info("%s/0: registered device vbi%d\n",
-		     dev->name, dev->vbi_dev->num);
+	cx231xx_info("%s/0: registered device %s\n",
+		     dev->name, video_device_node_name(dev->vbi_dev));
 
 	if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
 		dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
@@ -2409,12 +2416,13 @@ int cx231xx_register_analog_devices(stru
 			cx231xx_errdev("can't register radio device\n");
 			return ret;
 		}
-		cx231xx_info("Registered radio device as /dev/radio%d\n",
-			     dev->radio_dev->num);
+		cx231xx_info("Registered radio device as %s\n",
+			     video_device_node_name(dev->radio_dev));
 	}
 
-	cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
-		     dev->vdev->num, dev->vbi_dev->num);
+	cx231xx_info("V4L2 device registered as %s and %s\n",
+		     video_device_node_name(dev->vdev),
+		     video_device_node_name(dev->vbi_dev));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cimax2.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cimax2.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cimax2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cimax2.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,6 +53,8 @@
 #define NETUP_CI_CTL		0x04
 #define NETUP_CI_RD		1
 
+#define NETUP_IRQ_DETAM 	0x1
+#define NETUP_IRQ_IRQAM		0x4
 
 static unsigned int ci_dbg;
 module_param(ci_dbg, int, 0644);
@@ -73,6 +75,9 @@ struct netup_ci_state {
 	int status;
 	struct work_struct work;
 	void *priv;
+	u8 current_irq_mode;
+	int current_ci_flag;
+	unsigned long next_status_checked_time;
 };
 
 
@@ -169,24 +174,26 @@ int netup_ci_op_cam(struct dvb_ca_en5022
 	if (0 != slot)
 		return -EINVAL;
 
-	ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
-							0, &store, 1);
-	if (ret != 0)
-		return ret;
+	if (state->current_ci_flag != flag) {
+		ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+				0, &store, 1);
+		if (ret != 0)
+			return ret;
 
-	store &= ~0x0c;
-	store |= flag;
+		store &= ~0x0c;
+		store |= flag;
 
-	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
-							0, &store, 1);
-	if (ret != 0)
-		return ret;
+		ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+				0, &store, 1);
+		if (ret != 0)
+			return ret;
+	};
+	state->current_ci_flag = flag;
 
 	mutex_lock(&dev->gpio_lock);
 
 	/* write addr */
 	cx_write(MC417_OEN, NETUP_EN_ALL);
-	msleep(2);
 	cx_write(MC417_RWD, NETUP_CTRL_OFF |
 				NETUP_ADLO | (0xff & addr));
 	cx_clear(MC417_RWD, NETUP_ADLO);
@@ -196,7 +203,6 @@ int netup_ci_op_cam(struct dvb_ca_en5022
 
 	if (read) { /* data in */
 		cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
-		msleep(2);
 	} else /* data out */
 		cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
 
@@ -213,8 +219,8 @@ int netup_ci_op_cam(struct dvb_ca_en5022
 		if (mem < 0)
 			return -EREMOTEIO;
 
-	ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
-			(read) ? "read" : "write", addr,
+	ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__,
+			(read) ? "read" : "write", state->ci_i2c_addr, addr,
 			(flag == NETUP_CI_CTL) ? "ctl" : "mem",
 			(read) ? mem : data);
 
@@ -283,14 +289,39 @@ int netup_ci_slot_shutdown(struct dvb_ca
 	return 0;
 }
 
+int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
+{
+	struct netup_ci_state *state = en50221->data;
+	int ret;
+
+	if (irq_mode == state->current_irq_mode)
+		return 0;
+
+	ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n",
+			__func__, state->ci_i2c_addr, irq_mode);
+	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0x1b, &irq_mode, 1);
+
+	if (ret != 0)
+		return ret;
+
+	state->current_irq_mode = irq_mode;
+
+	return 0;
+}
+
 int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
 {
 	struct netup_ci_state *state = en50221->data;
-	u8 buf = 0x60;
+	u8 buf;
 
 	if (0 != slot)
 		return -EINVAL;
 
+	netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+			0, &buf, 1);
+	buf |= 0x60;
+
 	return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
 							0, &buf, 1);
 }
@@ -303,21 +334,35 @@ static void netup_read_ci_status(struct
 	u8 buf[33];
 	int ret;
 
-	ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
-							0, &buf[0], 33);
+	/* CAM module IRQ processing. fast operation */
+	dvb_ca_en50221_frda_irq(&state->ca, 0);
 
-	if (ret != 0)
-		return;
+	/* CAM module INSERT/REMOVE processing. slow operation because of i2c
+	 * transfers */
+	if (time_after(jiffies, state->next_status_checked_time)
+			|| !state->status) {
+		ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+				0, &buf[0], 33);
 
-	ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, "
-		"TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
-		buf[32]);
+		state->next_status_checked_time = jiffies
+			+ msecs_to_jiffies(1000);
 
-	if (buf[0] & 1)
-		state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
-			DVB_CA_EN50221_POLL_CAM_READY;
-	else
-		state->status = 0;
+		if (ret != 0)
+			return;
+
+		ci_dbg_print("%s: Slot Status Addr=[0x%04x], "
+				"Reg=[0x%02x], data=%02x, "
+				"TS config = %02x\n", __func__,
+				state->ci_i2c_addr, 0, buf[0],
+				buf[0]);
+
+
+		if (buf[0] & 1)
+			state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+				DVB_CA_EN50221_POLL_CAM_READY;
+		else
+			state->status = 0;
+	};
 }
 
 /* CI irq handler */
@@ -347,6 +392,9 @@ int netup_poll_ci_slot_status(struct dvb
 	if (0 != slot)
 		return -EINVAL;
 
+	netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | NETUP_IRQ_IRQAM)
+			: NETUP_IRQ_DETAM);
+
 	return state->status;
 }
 
@@ -381,8 +429,8 @@ int netup_ci_init(struct cx23885_tsport
 		0x01, /* power on (use it like store place) */
 		0x00, /* RFU */
 		0x00, /* int status read only */
-		0x01, /* all int unmasked */
-		0x04, /* int config */
+		NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
+		0x05, /* EXTINT=active-high, INT=push-pull */
 		0x00, /* USCG1 */
 		0x04, /* ack active low */
 		0x00, /* LOCK = 0 */
@@ -422,6 +470,7 @@ int netup_ci_init(struct cx23885_tsport
 	state->ca.poll_slot_status = netup_poll_ci_slot_status;
 	state->ca.data = state;
 	state->priv = port;
+	state->current_irq_mode = NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM;
 
 	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
 						0, &cimax_init[0], 34);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-417.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-417.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 13:58:27.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 12:07:03.000000000 -0400
@@ -37,6 +37,7 @@
 #include <media/cx2341x.h>
 
 #include "cx23885.h"
+#include "cx23885-ioctl.h"
 
 #define CX23885_FIRM_IMAGE_SIZE 376836
 #define CX23885_FIRM_IMAGE_NAME "/*(DEBLOBBED)*/"
@@ -318,7 +319,7 @@ static int mc417_wait_ready(struct cx238
 	}
 }
 
-static int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
+int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
 {
 	u32 regval;
 
@@ -382,7 +383,7 @@ static int mc417_register_write(struct c
 	return mc417_wait_ready(dev);
 }
 
-static int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
+int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
 {
 	int retval;
 	u32 regval;
@@ -1567,28 +1568,11 @@ static int vidioc_queryctrl(struct file
 
 static int mpeg_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct cx23885_dev *h, *dev = NULL;
-	struct list_head *list;
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh;
 
 	dprintk(2, "%s()\n", __func__);
 
-	lock_kernel();
-	list_for_each(list, &cx23885_devlist) {
-		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->v4l_device &&
-		    h->v4l_device->minor == minor) {
-			dev = h;
-			break;
-		}
-	}
-
-	if (dev == NULL) {
-		unlock_kernel();
-		return -ENODEV;
-	}
-
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
 	if (NULL == fh) {
@@ -1596,6 +1580,8 @@ static int mpeg_open(struct file *file)
 		return -ENOMEM;
 	}
 
+	lock_kernel();
+
 	file->private_data = fh;
 	fh->dev      = dev;
 
@@ -1724,13 +1710,17 @@ 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_register	 = cx23885_g_register,
+	.vidioc_s_register	 = cx23885_s_register,
+#endif
 };
 
 static struct video_device cx23885_mpeg_template = {
 	.name          = "cx23885",
 	.fops          = &mpeg_fops,
 	.ioctl_ops     = &mpeg_ioctl_ops,
-	.minor         = -1,
 	.tvnorms       = CX23885_NORMS,
 	.current_norm  = V4L2_STD_NTSC_M,
 };
@@ -1740,7 +1730,7 @@ void cx23885_417_unregister(struct cx238
 	dprintk(1, "%s()\n", __func__);
 
 	if (dev->v4l_device) {
-		if (-1 != dev->v4l_device->minor)
+		if (video_is_registered(dev->v4l_device))
 			video_unregister_device(dev->v4l_device);
 		else
 			video_device_release(dev->v4l_device);
@@ -1797,6 +1787,7 @@ int cx23885_417_register(struct cx23885_
 	/* Allocate and initialize V4L video device */
 	dev->v4l_device = cx23885_video_dev_alloc(tsport,
 		dev->pci, &cx23885_mpeg_template, "mpeg");
+	video_set_drvdata(dev->v4l_device, dev);
 	err = video_register_device(dev->v4l_device,
 		VFL_TYPE_GRABBER, -1);
 	if (err < 0) {
@@ -1804,8 +1795,8 @@ int cx23885_417_register(struct cx23885_
 		return err;
 	}
 
-	printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
-	       dev->name, dev->v4l_device->num);
+	printk(KERN_INFO "%s: registered device %s [mpeg]\n",
+	       dev->name, video_device_node_name(dev->v4l_device));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #include "cx23885.h"
 #include "tuner-xc2028.h"
 #include "netup-init.h"
+#include "cx23888-ir.h"
 
 /* ------------------------------------------------------------------ */
 /* board config info                                                  */
@@ -199,11 +200,61 @@ struct cx23885_board cx23885_boards[] =
 	},
 	[CX23885_BOARD_MYGICA_X8506] = {
 		.name		= "Mygica X8506 DMB-TH",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.porta		= CX23885_ANALOG_VIDEO,
 		.portb		= CX23885_MPEG_DVB,
+		.input		= {
+			{
+				.type   = CX23885_VMUX_TELEVISION,
+				.vmux   = CX25840_COMPOSITE2,
+			},
+			{
+				.type   = CX23885_VMUX_COMPOSITE1,
+				.vmux   = CX25840_COMPOSITE8,
+			},
+			{
+				.type   = CX23885_VMUX_SVIDEO,
+				.vmux   = CX25840_SVIDEO_LUMA3 |
+						CX25840_SVIDEO_CHROMA4,
+			},
+			{
+				.type   = CX23885_VMUX_COMPONENT,
+				.vmux   = CX25840_COMPONENT_ON |
+					CX25840_VIN1_CH1 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN7_CH3,
+			},
+		},
 	},
 	[CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
 		.name		= "Magic-Pro ProHDTV Extreme 2",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.porta		= CX23885_ANALOG_VIDEO,
 		.portb		= CX23885_MPEG_DVB,
+		.input		= {
+			{
+				.type   = CX23885_VMUX_TELEVISION,
+				.vmux   = CX25840_COMPOSITE2,
+			},
+			{
+				.type   = CX23885_VMUX_COMPOSITE1,
+				.vmux   = CX25840_COMPOSITE8,
+			},
+			{
+				.type   = CX23885_VMUX_SVIDEO,
+				.vmux   = CX25840_SVIDEO_LUMA3 |
+						CX25840_SVIDEO_CHROMA4,
+			},
+			{
+				.type   = CX23885_VMUX_COMPONENT,
+				.vmux   = CX25840_COMPONENT_ON |
+					CX25840_VIN1_CH1 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN7_CH3,
+			},
+		},
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1850] = {
 		.name		= "Hauppauge WinTV-HVR1850",
@@ -214,6 +265,15 @@ struct cx23885_board cx23885_boards[] =
 		.name		= "Compro VideoMate E800",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1290] = {
+		.name		= "Hauppauge WinTV-HVR1290",
+		.portc		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_MYGICA_X8558PRO] = {
+		.name		= "Mygica X8558 PRO DMB-TH",
+		.portb		= CX23885_MPEG_DVB,
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -349,6 +409,14 @@ struct cx23885_subid cx23885_subids[] =
 		.subvendor = 0x1858,
 		.subdevice = 0xe800,
 		.card      = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8551,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1290,
+	}, {
+		.subvendor = 0x14f1,
+		.subdevice = 0x8578,
+		.card      = CX23885_BOARD_MYGICA_X8558PRO,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -509,9 +577,13 @@ static void hauppauge_eeprom(struct cx23
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
 	case 85021:
-		/* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM,
+		/* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM,
 			Dual channel ATSC and MPEG2 HW Encoder */
 		break;
+	case 85721:
+		/* WinTV-HVR1290 (PCIe, OEM, RCA in, IR,
+			Dual channel ATSC and Basic analog */
+		break;
 	default:
 		printk(KERN_WARNING "%s: warning: "
 			"unknown hauppauge model #%d\n",
@@ -710,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_d
 		cx_set(GP0_IO, 0x00040004);
 		break;
 	case CX23885_BOARD_TBS_6920:
-	case CX23885_BOARD_TEVII_S470:
 		cx_write(MC417_CTL, 0x00000036);
 		cx_write(MC417_OEN, 0x00001000);
-		cx_write(MC417_RWD, 0x00001800);
+		cx_set(MC417_RWD, 0x00000002);
+		mdelay(200);
+		cx_clear(MC417_RWD, 0x00000800);
+		mdelay(200);
+		cx_set(MC417_RWD, 0x00000800);
+		mdelay(200);
 		break;
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
 		/* GPIO-0 INTA from CiMax1
@@ -758,15 +834,26 @@ void cx23885_gpio_setup(struct cx23885_d
 		break;
 	case CX23885_BOARD_MYGICA_X8506:
 	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+		/* GPIO-0 (0)Analog / (1)Digital TV */
 		/* GPIO-1 reset XC5000 */
 		/* GPIO-2 reset LGS8GL5 / LGS8G75 */
-		cx_set(GP0_IO, 0x00060000);
-		cx_clear(GP0_IO, 0x00000006);
+		cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1);
+		cx23885_gpio_clear(dev, GPIO_1 | GPIO_2);
 		mdelay(100);
-		cx_set(GP0_IO, 0x00060006);
+		cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2);
+		mdelay(100);
+		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		/* GPIO-0 reset first ATBM8830 */
+		/* GPIO-1 reset second ATBM8830 */
+		cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
+		cx23885_gpio_clear(dev, GPIO_0 | GPIO_1);
+		mdelay(100);
+		cx23885_gpio_set(dev, GPIO_0 | GPIO_1);
 		mdelay(100);
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		/* GPIO-0 656_CLK */
 		/* GPIO-1 656_D0 */
 		/* GPIO-2 Wake# */
@@ -801,6 +888,7 @@ void cx23885_gpio_setup(struct cx23885_d
 
 int cx23885_ir_init(struct cx23885_dev *dev)
 {
+	int ret = 0;
 	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
@@ -812,15 +900,46 @@ int cx23885_ir_init(struct cx23885_dev *
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
-	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 		/* FIXME: Implement me */
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		ret = cx23888_ir_probe(dev);
+		if (ret)
+			break;
+		dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR);
+		dev->pci_irqmask |= PCI_MSK_IR;
+		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
 		request_module("ir-kbd-i2c");
 		break;
 	}
 
-	return 0;
+	return ret;
+}
+
+void cx23885_ir_fini(struct cx23885_dev *dev)
+{
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		dev->pci_irqmask &= ~PCI_MSK_IR;
+		cx_clear(PCI_INT_MSK, PCI_MSK_IR);
+		cx23888_ir_remove(dev);
+		dev->sd_ir = NULL;
+		break;
+	}
+}
+
+void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
+{
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		if (dev->sd_ir && (dev->pci_irqmask & PCI_MSK_IR))
+			cx_set(PCI_INT_MSK, PCI_MSK_IR);
+		break;
+	}
 }
 
 void cx23885_card_setup(struct cx23885_dev *dev)
@@ -853,6 +972,7 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -886,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_d
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
-	case CX23885_BOARD_TEVII_S470:
 	case CX23885_BOARD_TBS_6920:
+		ts1->gen_ctrl_val  = 0x4; /* Parallel */
+		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		break;
+	case CX23885_BOARD_TEVII_S470:
 	case CX23885_BOARD_DVBWORLD_2005:
 		ts1->gen_ctrl_val  = 0x5; /* Parallel */
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -907,6 +1031,14 @@ void cx23885_card_setup(struct cx23885_d
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		ts1->gen_ctrl_val  = 0x5; /* Parallel */
+		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
+		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -922,6 +1054,7 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -939,6 +1072,10 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", "cx25840", 0x88 >> 1, NULL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-core.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,9 @@
 
 #include "cx23885.h"
 #include "cimax2.h"
+#include "cx23888-ir.h"
+#include "cx23885-ir.h"
+#include "cx23885-input.h"
 
 MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -52,9 +55,6 @@ MODULE_PARM_DESC(card, "card type");
 
 static unsigned int cx23885_devcount;
 
-static DEFINE_MUTEX(devlist);
-LIST_HEAD(cx23885_devlist);
-
 #define NO_SYNC_LINE (-1U)
 
 /* FIXME, these allocations will change when
@@ -753,6 +753,23 @@ static void cx23885_dev_checkrevision(st
 			__func__, dev->hwrevision);
 }
 
+/* Find the first v4l2_subdev member of the group id in hw */
+struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw)
+{
+	struct v4l2_subdev *result = NULL;
+	struct v4l2_subdev *sd;
+
+	spin_lock(&dev->v4l2_dev.lock);
+	v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) {
+		if (sd->grp_id == hw) {
+			result = sd;
+			break;
+		}
+	}
+	spin_unlock(&dev->v4l2_dev.lock);
+	return result;
+}
+
 static int cx23885_dev_setup(struct cx23885_dev *dev)
 {
 	int i;
@@ -765,10 +782,6 @@ static int cx23885_dev_setup(struct cx23
 	dev->nr = cx23885_devcount++;
 	sprintf(dev->name, "cx23885[%d]", dev->nr);
 
-	mutex_lock(&devlist);
-	list_add_tail(&dev->devlist, &cx23885_devlist);
-	mutex_unlock(&devlist);
-
 	/* Configure the internal memory */
 	if (dev->pci->device == 0x8880) {
 		/* Could be 887 or 888, assume a default */
@@ -899,7 +912,7 @@ static int cx23885_dev_setup(struct cx23
 	cx23885_i2c_register(&dev->i2c_bus[1]);
 	cx23885_i2c_register(&dev->i2c_bus[2]);
 	cx23885_card_setup(dev);
-	call_all(dev, tuner, s_standby);
+	call_all(dev, core, s_power, 0);
 	cx23885_ir_init(dev);
 
 	if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1637,6 +1650,7 @@ static irqreturn_t cx23885_irq(int irq,
 	u32 ts1_status, ts1_mask;
 	u32 ts2_status, ts2_mask;
 	int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
+	bool ir_handled = false;
 
 	pci_status = cx_read(PCI_INT_STAT);
 	pci_mask = cx_read(PCI_INT_MSK);
@@ -1662,18 +1676,12 @@ static irqreturn_t cx23885_irq(int irq,
 	dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n",
 		ts2_status, ts2_mask, ts2_count);
 
-	if ((pci_status & PCI_MSK_RISC_RD) ||
-	    (pci_status & PCI_MSK_RISC_WR) ||
-	    (pci_status & PCI_MSK_AL_RD) ||
-	    (pci_status & PCI_MSK_AL_WR) ||
-	    (pci_status & PCI_MSK_APB_DMA) ||
-	    (pci_status & PCI_MSK_VID_C) ||
-	    (pci_status & PCI_MSK_VID_B) ||
-	    (pci_status & PCI_MSK_VID_A) ||
-	    (pci_status & PCI_MSK_AUD_INT) ||
-	    (pci_status & PCI_MSK_AUD_EXT) ||
-	    (pci_status & PCI_MSK_GPIO0) ||
-	    (pci_status & PCI_MSK_GPIO1)) {
+	if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
+			  PCI_MSK_AL_RD   | PCI_MSK_AL_WR   | PCI_MSK_APB_DMA |
+			  PCI_MSK_VID_C   | PCI_MSK_VID_B   | PCI_MSK_VID_A   |
+			  PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
+			  PCI_MSK_GPIO0   | PCI_MSK_GPIO1   |
+			  PCI_MSK_IR)) {
 
 		if (pci_status & PCI_MSK_RISC_RD)
 			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n",
@@ -1722,6 +1730,10 @@ static irqreturn_t cx23885_irq(int irq,
 		if (pci_status & PCI_MSK_GPIO1)
 			dprintk(7, " (PCI_MSK_GPIO1     0x%08x)\n",
 				PCI_MSK_GPIO1);
+
+		if (pci_status & PCI_MSK_IR)
+			dprintk(7, " (PCI_MSK_IR        0x%08x)\n",
+				PCI_MSK_IR);
 	}
 
 	if (cx23885_boards[dev->board].cimax > 0 &&
@@ -1752,12 +1764,48 @@ static irqreturn_t cx23885_irq(int irq,
 	if (vida_status)
 		handled += cx23885_video_irq(dev, vida_status);
 
+	if (pci_status & PCI_MSK_IR) {
+		v4l2_subdev_call(dev->sd_ir, ir, interrupt_service_routine,
+				 pci_status, &ir_handled);
+		if (ir_handled)
+			handled++;
+	}
+
 	if (handled)
 		cx_write(PCI_INT_STAT, pci_status);
 out:
 	return IRQ_RETVAL(handled);
 }
 
+static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd,
+				    unsigned int notification, void *arg)
+{
+	struct cx23885_dev *dev;
+
+	if (sd == NULL)
+		return;
+
+	dev = to_cx23885(sd->v4l2_dev);
+
+	switch (notification) {
+	case V4L2_SUBDEV_IR_RX_NOTIFY: /* Called in an IRQ context */
+		if (sd == dev->sd_ir)
+			cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg);
+		break;
+	case V4L2_SUBDEV_IR_TX_NOTIFY: /* Called in an IRQ context */
+		if (sd == dev->sd_ir)
+			cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg);
+		break;
+	}
+}
+
+static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
+{
+	INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler);
+	INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
+	dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
+}
+
 static inline int encoder_on_portb(struct cx23885_dev *dev)
 {
 	return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
@@ -1816,6 +1864,26 @@ void cx23885_gpio_clear(struct cx23885_d
 		printk(KERN_INFO "%s: Unsupported\n", dev->name);
 }
 
+u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
+{
+	if (mask & 0x00000007)
+		return (cx_read(GP0_IO) >> 8) & mask & 0x7;
+
+	if (mask & 0x0007fff8) {
+		if (encoder_on_portb(dev) || encoder_on_portc(dev))
+			printk(KERN_ERR
+				"%s: Reading GPIO moving on encoder ports\n",
+				dev->name);
+		return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
+	}
+
+	/* TODO: 23-19 */
+	if (mask & 0x00f80000)
+		printk(KERN_INFO "%s: Unsupported\n", dev->name);
+
+	return 0;
+}
+
 void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
 {
 	if ((mask & 0x00000007) && asoutput)
@@ -1854,6 +1922,9 @@ static int __devinit cx23885_initdev(str
 	if (err < 0)
 		goto fail_free;
 
+	/* Prepare to handle notifications from subdevices */
+	cx23885_v4l2_dev_notify_init(dev);
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
@@ -1896,6 +1967,14 @@ static int __devinit cx23885_initdev(str
 		break;
 	}
 
+	/*
+	 * The CX2388[58] IR controller can start firing interrupts when
+	 * enabled, so these have to take place after the cx23885_irq() handler
+	 * is hooked up by the call to request_irq() above.
+	 */
+	cx23885_ir_pci_int_enable(dev);
+	cx23885_input_init(dev);
+
 	return 0;
 
 fail_irq:
@@ -1912,6 +1991,9 @@ static void __devexit cx23885_finidev(st
 	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
 	struct cx23885_dev *dev = to_cx23885(v4l2_dev);
 
+	cx23885_input_fini(dev);
+	cx23885_ir_fini(dev);
+
 	cx23885_shutdown(dev);
 
 	pci_disable_device(pci_dev);
@@ -1919,10 +2001,6 @@ static void __devexit cx23885_finidev(st
 	/* unregister stuff */
 	free_irq(pci_dev->irq, dev);
 
-	mutex_lock(&devlist);
-	list_del(&dev->devlist);
-	mutex_unlock(&devlist);
-
 	cx23885_dev_unregister(dev);
 	v4l2_device_unregister(v4l2_dev);
 	kfree(dev);
@@ -1957,7 +2035,7 @@ static struct pci_driver cx23885_pci_dri
 	.resume   = NULL,
 };
 
-static int cx23885_init(void)
+static int __init cx23885_init(void)
 {
 	printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n",
 	       (CX23885_VERSION_CODE >> 16) & 0xff,
@@ -1970,7 +2048,7 @@ static int cx23885_init(void)
 	return pci_register_driver(&cx23885_pci_driver);
 }
 
-static void cx23885_fini(void)
+static void __exit cx23885_fini(void)
 {
 	pci_unregister_driver(&cx23885_pci_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 12:03:50.000000000 -0400
@@ -38,6 +38,7 @@
 #include "tda18271.h"
 #include "lgdt330x.h"
 #include "xc5000.h"
+#include "max2165.h"
 #include "tda10048.h"
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
@@ -54,6 +55,9 @@
 #include "netup-eeprom.h"
 #include "netup-init.h"
 #include "lgdt3305.h"
+#include "atbm8830.h"
+#include "ds3000.h"
+#include "cx23885-f300.h"
 
 static unsigned int debug;
 
@@ -400,6 +404,7 @@ static struct stv0900_reg stv0900_ts_reg
 
 static struct stv0900_config netup_stv0900_config = {
 	.demod_address = 0x68,
+	.demod_mode = 1, /* dual */
 	.xtal = 8000000,
 	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
 	.diseqc_mode = 2,/* 2/3 PWM */
@@ -414,34 +419,22 @@ static struct stv6110_config netup_stv61
 	.i2c_address = 0x60,
 	.mclk = 16000000,
 	.clk_div = 1,
+	.gain = 8, /* +16 dB  - maximum gain */
 };
 
 static struct stv6110_config netup_stv6110_tunerconfig_b = {
 	.i2c_address = 0x63,
 	.mclk = 16000000,
 	.clk_div = 1,
+	.gain = 8, /* +16 dB  - maximum gain */
 };
 
-static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-	struct cx23885_tsport *port = fe->dvb->priv;
-	struct cx23885_dev *dev = port->dev;
-
-	if (voltage == SEC_VOLTAGE_18)
-		cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
-	else if (voltage == SEC_VOLTAGE_13)
-		cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
-	else
-		cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
-	return 0;
-}
-
 static struct cx24116_config tbs_cx24116_config = {
-	.demod_address = 0x05,
+	.demod_address = 0x55,
 };
 
-static struct cx24116_config tevii_cx24116_config = {
-	.demod_address = 0x55,
+static struct ds3000_config tevii_ds3000_config = {
+	.demod_address = 0x68,
 };
 
 static struct cx24116_config dvbworld_cx24116_config = {
@@ -486,11 +479,40 @@ static int cx23885_dvb_set_frontend(stru
 			break;
 		}
 		break;
+	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+		/* Select Digital TV */
+		cx23885_gpio_set(dev, GPIO_0);
+		break;
 	}
-	return (port->set_frontend_save) ?
-		port->set_frontend_save(fe, param) : -ENODEV;
+	return 0;
 }
 
+static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe,
+					 unsigned int cmd, void *parg,
+					 unsigned int stage)
+{
+	int err = 0;
+
+	switch (stage) {
+	case DVB_FE_IOCTL_PRE:
+
+		switch (cmd) {
+		case FE_SET_FRONTEND:
+			err = cx23885_dvb_set_frontend(fe,
+				(struct dvb_frontend_parameters *) parg);
+			break;
+		}
+		break;
+
+	case DVB_FE_IOCTL_POST:
+		/* no post-ioctl handling required */
+		break;
+	}
+	return err;
+};
+
+
 static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
 	.prod = LGS8GXX_PROD_LGS8G75,
 	.demod_address = 0x19,
@@ -511,6 +533,38 @@ static struct xc5000_config magicpro_pro
 	.if_khz = 6500,
 };
 
+static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x44,
+	.serial_ts = 0,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
+static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
+	.prod = ATBM8830_PROD_8830,
+	.demod_address = 0x44,
+	.serial_ts = 1,
+	.ts_sampling_edge = 1,
+	.ts_clk_gated = 0,
+	.osc_clk_freq = 30400, /* in kHz */
+	.if_freq = 0, /* zero IF */
+	.zif_swap_iq = 1,
+};
+
+static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
+	.i2c_address = 0x60,
+	.osc_clk = 20
+};
+
 static int dvb_register(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
@@ -550,12 +604,6 @@ static int dvb_register(struct cx23885_t
 				   0x60, &dev->i2c_bus[1].i2c_adap,
 				   &hauppauge_hvr127x_config);
 		}
-
-		/* FIXME: temporary hack */
-		/* define bridge override to set_frontend */
-		port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend;
-		fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend;
-
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 		i2c_bus = &dev->i2c_bus[0];
@@ -772,23 +820,23 @@ static int dvb_register(struct cx23885_t
 		}
 		break;
 	case CX23885_BOARD_TBS_6920:
-		i2c_bus = &dev->i2c_bus[0];
+		i2c_bus = &dev->i2c_bus[1];
 
 		fe0->dvb.frontend = dvb_attach(cx24116_attach,
-			&tbs_cx24116_config,
-			&i2c_bus->i2c_adap);
+					&tbs_cx24116_config,
+					&i2c_bus->i2c_adap);
 		if (fe0->dvb.frontend != NULL)
-			fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
 
 		break;
 	case CX23885_BOARD_TEVII_S470:
 		i2c_bus = &dev->i2c_bus[1];
 
-		fe0->dvb.frontend = dvb_attach(cx24116_attach,
-			&tevii_cx24116_config,
-			&i2c_bus->i2c_adap);
+		fe0->dvb.frontend = dvb_attach(ds3000_attach,
+					&tevii_ds3000_config,
+					&i2c_bus->i2c_adap);
 		if (fe0->dvb.frontend != NULL)
-			fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
 
 		break;
 	case CX23885_BOARD_DVBWORLD_2005:
@@ -814,8 +862,8 @@ static int dvb_register(struct cx23885_t
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL,
-							LNBH24_TTX, 0x09))
+							LNBH24_PCL | LNBH24_TTX,
+							LNBH24_TEN, 0x09))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
@@ -835,8 +883,8 @@ static int dvb_register(struct cx23885_t
 					if (!dvb_attach(lnbh24_attach,
 							fe0->dvb.frontend,
 							&i2c_bus->i2c_adap,
-							LNBH24_PCL,
-							LNBH24_TTX, 0x0a))
+							LNBH24_PCL | LNBH24_TTX,
+							LNBH24_TEN, 0x0a))
 						printk(KERN_ERR
 							"No LNBH24 found!\n");
 
@@ -872,6 +920,7 @@ static int dvb_register(struct cx23885_t
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
 		i2c_bus = &dev->i2c_bus[0];
 		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
 			&hcw_s5h1411_config,
@@ -881,6 +930,36 @@ static int dvb_register(struct cx23885_t
 				0x60, &dev->i2c_bus[0].i2c_adap,
 				&hauppauge_tda18271_config);
 		break;
+	case CX23885_BOARD_MYGICA_X8558PRO:
+		switch (port->nr) {
+		/* port B */
+		case 1:
+			i2c_bus = &dev->i2c_bus[0];
+			fe0->dvb.frontend = dvb_attach(atbm8830_attach,
+				&mygica_x8558pro_atbm8830_cfg1,
+				&i2c_bus->i2c_adap);
+			if (fe0->dvb.frontend != NULL) {
+				dvb_attach(max2165_attach,
+					fe0->dvb.frontend,
+					&i2c_bus->i2c_adap,
+					&mygic_x8558pro_max2165_cfg1);
+			}
+			break;
+		/* port C */
+		case 2:
+			i2c_bus = &dev->i2c_bus[1];
+			fe0->dvb.frontend = dvb_attach(atbm8830_attach,
+				&mygica_x8558pro_atbm8830_cfg2,
+				&i2c_bus->i2c_adap);
+			if (fe0->dvb.frontend != NULL) {
+				dvb_attach(max2165_attach,
+					fe0->dvb.frontend,
+					&i2c_bus->i2c_adap,
+					&mygic_x8558pro_max2165_cfg2);
+			}
+			break;
+		}
+		break;
 
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
@@ -897,14 +976,15 @@ static int dvb_register(struct cx23885_t
 	fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	call_all(dev, tuner, s_standby);
+	call_all(dev, core, s_power, 0);
 
 	if (fe0->dvb.frontend->ops.analog_ops.standby)
 		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
 	/* register everything */
 	ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
-		&dev->pci->dev, adapter_nr, 0);
+					&dev->pci->dev, adapter_nr, 0,
+					cx23885_dvb_fe_ioctl_override);
 
 	/* init CI & MAC */
 	switch (dev->board) {
@@ -940,7 +1020,7 @@ int cx23885_dvb_register(struct cx23885_
 	int err, i;
 
 	/* Here we need to allocate the correct number of frontends,
-	 * as reflected in the cards struct. The reality is that currrently
+	 * as reflected in the cards struct. The reality is that currently
 	 * no cx23885 boards support this - yet. But, if we don't modify this
 	 * code then the second frontend would never be allocated (later)
 	 * and fail with error before the attach in dvb_register().
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-f300.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-f300.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-f300.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-f300.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,177 @@
+/*
+ * Driver for Silicon Labs C8051F300 microcontroller.
+ *
+ * It is used for LNB power control in TeVii S470,
+ * TBS 6920 PCIe DVB-S2 cards.
+ *
+ * Microcontroller connected to cx23885 GPIO pins:
+ * GPIO0 - data		- P0.3 F300
+ * GPIO1 - reset	- P0.2 F300
+ * GPIO2 - clk		- P0.1 F300
+ * GPIO3 - busy		- P0.0 F300
+ *
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
+ *
+ * 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 "cx23885.h"
+
+#define F300_DATA	GPIO_0
+#define F300_RESET	GPIO_1
+#define F300_CLK	GPIO_2
+#define F300_BUSY	GPIO_3
+
+static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
+{
+	cx23885_gpio_enable(dev, line, 1);
+	if (lvl == 1)
+		cx23885_gpio_set(dev, line);
+	else
+		cx23885_gpio_clear(dev, line);
+}
+
+static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
+{
+	cx23885_gpio_enable(dev, line, 0);
+
+	return cx23885_gpio_get(dev, line);
+}
+
+static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
+{
+	u8 i;
+
+	for (i = 0; i < 8; i++) {
+		f300_set_line(dev, F300_CLK, 0);
+		udelay(30);
+		f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
+		udelay(30);
+		dta <<= 1;
+		f300_set_line(dev, F300_CLK, 1);
+		udelay(30);
+	}
+}
+
+static u8 f300_get_byte(struct cx23885_dev *dev)
+{
+	u8 i, dta = 0;
+
+	for (i = 0; i < 8; i++) {
+		f300_set_line(dev, F300_CLK, 0);
+		udelay(30);
+		dta <<= 1;
+		f300_set_line(dev, F300_CLK, 1);
+		udelay(30);
+		dta |= f300_get_line(dev, F300_DATA);/* msb first */
+
+	}
+
+	return dta;
+}
+
+static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
+{
+	struct cx23885_tsport *port = fe->dvb->priv;
+	struct cx23885_dev *dev = port->dev;
+	u8 i, temp, ret = 0;
+
+	temp = buf[0];
+	for (i = 0; i < buf[0]; i++)
+		temp += buf[i + 1];
+	temp = (~temp + 1);/* get check sum */
+	buf[1 + buf[0]] = temp;
+
+	f300_set_line(dev, F300_RESET, 1);
+	f300_set_line(dev, F300_CLK, 1);
+	udelay(30);
+	f300_set_line(dev, F300_DATA, 1);
+	msleep(1);
+
+	/* question: */
+	f300_set_line(dev, F300_RESET, 0);/* begin to send data */
+	msleep(1);
+
+	f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
+	msleep(1);
+
+	temp = buf[0];
+	temp += 2;
+	for (i = 0; i < temp; i++)
+		f300_send_byte(dev, buf[i]);
+
+	f300_set_line(dev, F300_RESET, 1);/* sent data over */
+	f300_set_line(dev, F300_DATA, 1);
+
+	/* answer: */
+	temp = 0;
+	for (i = 0; ((i < 8) & (temp == 0)); i++) {
+		msleep(1);
+		if (f300_get_line(dev, F300_BUSY) == 0)
+			temp = 1;
+	}
+
+	if (i > 7) {
+		printk(KERN_ERR "%s: timeout, the slave no response\n",
+								__func__);
+		ret = 1; /* timeout, the slave no response */
+	} else { /* the slave not busy, prepare for getting data */
+		f300_set_line(dev, F300_RESET, 0);/*ready...*/
+		msleep(1);
+		f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
+		msleep(1);
+		temp = f300_get_byte(dev);/*get the data length */
+		if (temp > 14)
+			temp = 14;
+
+		for (i = 0; i < (temp + 1); i++)
+			f300_get_byte(dev);/* get data to empty buffer */
+
+		f300_set_line(dev, F300_RESET, 1);/* received data over */
+		f300_set_line(dev, F300_DATA, 1);
+	}
+
+	return ret;
+}
+
+int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	u8 buf[16];
+
+	buf[0] = 0x05;
+	buf[1] = 0x38;/* write port */
+	buf[2] = 0x01;/* A port, lnb power */
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		buf[3] = 0x01;/* power on */
+		buf[4] = 0x02;/* B port, H/V */
+		buf[5] = 0x00;/*13V v*/
+		break;
+	case SEC_VOLTAGE_18:
+		buf[3] = 0x01;
+		buf[4] = 0x02;
+		buf[5] = 0x01;/* 18V h*/
+		break;
+	case SEC_VOLTAGE_OFF:
+		buf[3] = 0x00;/* power off */
+		buf[4] = 0x00;
+		buf[5] = 0x00;
+		break;
+	}
+
+	return f300_xfer(fe, buf);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-f300.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-f300.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-f300.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-f300.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2 @@
+extern int f300_set_voltage(struct dvb_frontend *fe,
+				fe_sec_voltage_t voltage);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885.h	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,8 @@
 #define CX23885_BOARD_MAGICPRO_PROHDTVE2       23
 #define CX23885_BOARD_HAUPPAUGE_HVR1850        24
 #define CX23885_BOARD_COMPRO_VIDEOMATE_E800    25
+#define CX23885_BOARD_HAUPPAUGE_HVR1290        26
+#define CX23885_BOARD_MYGICA_X8558PRO          27
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
@@ -157,6 +159,7 @@ enum cx23885_itype {
 	CX23885_VMUX_COMPOSITE3,
 	CX23885_VMUX_COMPOSITE4,
 	CX23885_VMUX_SVIDEO,
+	CX23885_VMUX_COMPONENT,
 	CX23885_VMUX_TELEVISION,
 	CX23885_VMUX_CABLE,
 	CX23885_VMUX_DVB,
@@ -297,14 +300,9 @@ struct cx23885_tsport {
 	/* Allow a single tsport to have multiple frontends */
 	u32                        num_frontends;
 	void                       *port_priv;
-
-	/* FIXME: temporary hack */
-	int (*set_frontend_save) (struct dvb_frontend *,
-				  struct dvb_frontend_parameters *);
 };
 
 struct cx23885_dev {
-	struct list_head           devlist;
 	atomic_t                   refcount;
 	struct v4l2_device 	   v4l2_dev;
 
@@ -356,6 +354,16 @@ struct cx23885_dev {
 	unsigned int               has_radio;
 	struct v4l2_subdev 	   *sd_cx25840;
 
+	/* Infrared */
+	struct v4l2_subdev         *sd_ir;
+	struct work_struct	   ir_rx_work;
+	unsigned long		   ir_rx_notifications;
+	struct work_struct	   ir_tx_work;
+	unsigned long		   ir_tx_notifications;
+
+	struct card_ir		   *ir_input;
+	atomic_t		   ir_input_stopping;
+
 	/* V4l */
 	u32                        freq;
 	struct video_device        *video_dev;
@@ -383,7 +391,12 @@ static inline struct cx23885_dev *to_cx2
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
 
-extern struct list_head cx23885_devlist;
+#define CX23885_HW_888_IR (1 << 0)
+
+#define call_hw(dev, grpid, o, f, args...) \
+	v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args)
+
+extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw);
 
 #define SRAM_CH01  0 /* Video A */
 #define SRAM_CH02  1 /* VBI A */
@@ -455,6 +468,7 @@ extern void cx23885_wakeup(struct cx2388
 
 extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
 extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
 extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
 	int asoutput);
 
@@ -471,6 +485,8 @@ extern int cx23885_tuner_callback(void *
 	int command, int arg);
 extern void cx23885_card_list(struct cx23885_dev *dev);
 extern int  cx23885_ir_init(struct cx23885_dev *dev);
+extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev);
+extern void cx23885_ir_fini(struct cx23885_dev *dev);
 extern void cx23885_gpio_setup(struct cx23885_dev *dev);
 extern void cx23885_card_setup(struct cx23885_dev *dev);
 extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
@@ -515,6 +531,10 @@ extern void cx23885_417_check_encoder(st
 extern void cx23885_mc417_init(struct cx23885_dev *dev);
 extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
 extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
+extern int mc417_register_read(struct cx23885_dev *dev,
+				u16 address, u32 *value);
+extern int mc417_register_write(struct cx23885_dev *dev,
+				u16 address, u32 value);
 extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
 extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
 extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-input.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-input.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,424 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared remote control input device
+ *
+ *  Most of this file is
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.net>
+ *
+ *  However, the cx23885_input_{init,fini} functions contained herein are
+ *  derived from Linux kernel files linux/media/video/.../...-input.c marked as:
+ *
+ *  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ *  Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
+ *		       Markus Rechberger <mrechberger@gmail.com>
+ *		       Mauro Carvalho Chehab <mchehab@infradead.org>
+ *		       Sascha Sommer <saschasommer@freenet.de>
+ *  Copyright (C) 2004, 2005 Chris Pascoe
+ *  Copyright (C) 2003, 2004 Gerd Knorr
+ *  Copyright (C) 2003 Pavel Machek
+ *
+ *  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/input.h>
+#include <media/ir-common.h>
+#include <media/v4l2-subdev.h>
+
+#include "cx23885.h"
+
+#define RC5_BITS		14
+#define RC5_HALF_BITS		(2*RC5_BITS)
+#define RC5_HALF_BITS_MASK	((1 << RC5_HALF_BITS) - 1)
+
+#define RC5_START_BITS_NORMAL	0x3 /* Command range  0 -  63 */
+#define RC5_START_BITS_EXTENDED	0x2 /* Command range 64 - 127 */
+
+#define RC5_EXTENDED_COMMAND_OFFSET	64
+
+static inline unsigned int rc5_command(u32 rc5_baseband)
+{
+	return RC5_INSTR(rc5_baseband) +
+		((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
+			? RC5_EXTENDED_COMMAND_OFFSET : 0);
+}
+
+static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	unsigned int code, command;
+	u32 rc5;
+
+	/* Ignore codes that are too short to be valid RC-5 */
+	if (ir_input->last_bit < (RC5_HALF_BITS - 1))
+		return;
+
+	/* The library has the manchester coding backwards; XOR to adapt. */
+	code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
+	rc5 = ir_rc5_decode(code);
+
+	switch (RC5_START(rc5)) {
+	case RC5_START_BITS_NORMAL:
+		break;
+	case RC5_START_BITS_EXTENDED:
+		/* Don't allow if the remote only emits standard commands */
+		if (ir_input->start == RC5_START_BITS_NORMAL)
+			return;
+		break;
+	default:
+		return;
+	}
+
+	if (ir_input->addr != RC5_ADDR(rc5))
+		return;
+
+	/* Don't generate a keypress for RC-5 auto-repeated keypresses */
+	command = rc5_command(rc5);
+	if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
+	    command != rc5_command(ir_input->last_rc5) ||
+	    /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
+	    RC5_START(ir_input->last_rc5) == 0) {
+		/* This keypress is differnet: not an auto repeat */
+		ir_input_nokey(ir_input->dev, &ir_input->ir);
+		ir_input_keydown(ir_input->dev, &ir_input->ir, command);
+	}
+	ir_input->last_rc5 = rc5;
+
+	/* Schedule when we should do the key up event: ir_input_nokey() */
+	mod_timer(&ir_input->timer_keyup,
+		  jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
+}
+
+static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
+					       u32 ns_pulse)
+{
+	const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
+	struct card_ir *ir_input = dev->ir_input;
+	int i, level, quarterbits, halfbits;
+
+	if (!ir_input->active) {
+		ir_input->active = 1;
+		/* assume an initial space that we may not detect or measure */
+		ir_input->code = 0;
+		ir_input->last_bit = 0;
+	}
+
+	if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
+		ir_input->last_bit++; /* Account for the final space */
+		ir_input->active = 0;
+		cx23885_input_process_raw_rc5(dev);
+		return;
+	}
+
+	level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
+
+	/* Skip any leading space to sync to the start bit */
+	if (ir_input->last_bit == 0 && level == 0)
+		return;
+
+	/*
+	 * With valid RC-5 we can get up to two consecutive half-bits in a
+	 * single pulse measurment.  Experiments have shown that the duration
+	 * of a half-bit can vary.  Make sure we always end up with an even
+	 * number of quarter bits at the same level (mark or space).
+	 */
+	ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	quarterbits = ns_pulse / rc5_quarterbit_ns;
+	if (quarterbits & 1)
+		quarterbits++;
+	halfbits = quarterbits / 2;
+
+	for (i = 0; i < halfbits; i++) {
+		ir_input->last_bit++;
+		ir_input->code |= (level << ir_input->last_bit);
+
+		if (ir_input->last_bit >= RC5_HALF_BITS-1) {
+			ir_input->active = 0;
+			cx23885_input_process_raw_rc5(dev);
+			/*
+			 * If level is 1, a leading mark is invalid for RC5.
+			 * If level is 0, we scan past extra intial space.
+			 * Either way we don't want to reactivate collecting
+			 * marks or spaces here with any left over half-bits.
+			 */
+			break;
+		}
+	}
+}
+
+static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
+						   bool add_eom)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct ir_input_state *ir_input_state = &ir_input->ir;
+
+	u32 ns_pulse[RC5_HALF_BITS+1];
+	ssize_t num = 0;
+	int count, i;
+
+	do {
+		v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
+				 sizeof(ns_pulse), &num);
+
+		count = num / sizeof(u32);
+
+		/* Append an end of Rx seq, if the caller requested */
+		if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
+			ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
+			count++;
+		}
+
+		/* Just drain the Rx FIFO, if we're called, but not RC-5 */
+		if (ir_input_state->ir_type != IR_TYPE_RC5)
+			continue;
+
+		for (i = 0; i < count; i++)
+			cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
+	} while (num != 0);
+}
+
+void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
+{
+	struct v4l2_subdev_ir_parameters params;
+	int overrun, data_available;
+
+	if (dev->sd_ir == NULL || events == 0)
+		return;
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/*
+		 * The only board we handle right now.  However other boards
+		 * using the CX2388x integrated IR controller should be similar
+		 */
+		break;
+	default:
+		return;
+	}
+
+	overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN |
+			    V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN);
+
+	data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED |
+				   V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ);
+
+	if (overrun) {
+		/* If there was a FIFO overrun, stop the device */
+		v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+		params.enable = false;
+		/* Mitigate race with cx23885_input_ir_stop() */
+		params.shutdown = atomic_read(&dev->ir_input_stopping);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+	}
+
+	if (data_available)
+		cx23885_input_process_pulse_widths_rc5(dev, overrun);
+
+	if (overrun) {
+		/* If there was a FIFO overrun, clear & restart the device */
+		params.enable = true;
+		/* Mitigate race with cx23885_input_ir_stop() */
+		params.shutdown = atomic_read(&dev->ir_input_stopping);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+	}
+}
+
+static void cx23885_input_ir_start(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct ir_input_state *ir_input_state = &ir_input->ir;
+	struct v4l2_subdev_ir_parameters params;
+
+	if (dev->sd_ir == NULL)
+		return;
+
+	atomic_set(&dev->ir_input_stopping, 0);
+
+	/* keyup timer set up, if needed */
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		setup_timer(&ir_input->timer_keyup,
+			    ir_rc5_timer_keyup,	/* Not actually RC-5 specific */
+			    (unsigned long) ir_input);
+		if (ir_input_state->ir_type == IR_TYPE_RC5) {
+			/*
+			 * RC-5 repeats a held key every
+			 * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
+			 */
+			ir_input->rc5_key_timeout = 115;
+		}
+		break;
+	}
+
+	v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/*
+		 * The IR controller on this board only returns pulse widths.
+		 * Any other mode setting will fail to set up the device.
+		*/
+		params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+		params.enable = true;
+		params.interrupt_enable = true;
+		params.shutdown = false;
+
+		/* Setup for baseband compatible with both RC-5 and RC-6A */
+		params.modulation = false;
+		/* RC-5:  2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/
+		/* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/
+		params.max_pulse_width = 3333333; /* ns */
+		/* RC-5:    666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
+		/* RC-6A:   333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
+		params.noise_filter_min_width = 333333; /* ns */
+		/*
+		 * This board has inverted receive sense:
+		 * mark is received as low logic level;
+		 * falling edges are detected as rising edges; etc.
+		 */
+		params.invert = true;
+		break;
+	}
+	v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+}
+
+static void cx23885_input_ir_stop(struct cx23885_dev *dev)
+{
+	struct card_ir *ir_input = dev->ir_input;
+	struct v4l2_subdev_ir_parameters params;
+
+	if (dev->sd_ir == NULL)
+		return;
+
+	/*
+	 * Stop the sd_ir subdevice from generating notifications and
+	 * scheduling work.
+	 * It is shutdown this way in order to mitigate a race with
+	 * cx23885_input_rx_work_handler() in the overrun case, which could
+	 * re-enable the subdevice.
+	 */
+	atomic_set(&dev->ir_input_stopping, 1);
+	v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	while (params.shutdown == false) {
+		params.enable = false;
+		params.interrupt_enable = false;
+		params.shutdown = true;
+		v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+		v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
+	}
+
+	flush_scheduled_work();
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		del_timer_sync(&ir_input->timer_keyup);
+		break;
+	}
+}
+
+int cx23885_input_init(struct cx23885_dev *dev)
+{
+	struct card_ir *ir;
+	struct input_dev *input_dev;
+	struct ir_scancode_table *ir_codes = NULL;
+	int ir_type, ir_addr, ir_start;
+	int ret;
+
+	/*
+	 * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't
+	 * encapsulated in a v4l2_subdev, then I'm not going to deal with it.
+	 */
+	if (dev->sd_ir == NULL)
+		return -ENODEV;
+
+	switch (dev->board) {
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_HAUPPAUGE_HVR1290:
+		/* Parameters for the grey Hauppauge remote for the HVR-1850 */
+		ir_codes = &ir_codes_hauppauge_new_table;
+		ir_type = IR_TYPE_RC5;
+		ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
+		ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
+		break;
+	}
+	if (ir_codes == NULL)
+		return -ENODEV;
+
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		ret = -ENOMEM;
+		goto err_out_free;
+	}
+
+	ir->dev = input_dev;
+	ir->addr = ir_addr;
+	ir->start = ir_start;
+
+	/* init input device */
+	snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
+		 cx23885_boards[dev->board].name);
+	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
+
+	ret = ir_input_init(input_dev, &ir->ir, ir_type);
+	if (ret < 0)
+		goto err_out_free;
+
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_PCI;
+	input_dev->id.version = 1;
+	if (dev->pci->subsystem_vendor) {
+		input_dev->id.vendor  = dev->pci->subsystem_vendor;
+		input_dev->id.product = dev->pci->subsystem_device;
+	} else {
+		input_dev->id.vendor  = dev->pci->vendor;
+		input_dev->id.product = dev->pci->device;
+	}
+	input_dev->dev.parent = &dev->pci->dev;
+
+	dev->ir_input = ir;
+	cx23885_input_ir_start(dev);
+
+	ret = ir_input_register(ir->dev, ir_codes);
+	if (ret)
+		goto err_out_stop;
+
+	return 0;
+
+err_out_stop:
+	cx23885_input_ir_stop(dev);
+	dev->ir_input = NULL;
+err_out_free:
+	kfree(ir);
+	return ret;
+}
+
+void cx23885_input_fini(struct cx23885_dev *dev)
+{
+	/* Always stop the IR hardware from generating interrupts */
+	cx23885_input_ir_stop(dev);
+
+	if (dev->ir_input == NULL)
+		return;
+	ir_input_unregister(dev->ir_input->dev);
+	kfree(dev->ir_input);
+	dev->ir_input = NULL;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-input.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-input.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-input.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,30 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared remote control input device
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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 _CX23885_INPUT_H_
+#define _CX23885_INPUT_H_
+int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
+
+int cx23885_input_init(struct cx23885_dev *dev);
+void cx23885_input_fini(struct cx23885_dev *dev);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ioctl.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ioctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,208 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Various common ioctl() support functions
+ *
+ *  Copyright (c) 2009 Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You 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 "cx23885.h"
+#include <media/v4l2-chip-ident.h>
+
+int cx23885_g_chip_ident(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_ident *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))
+		return -EINVAL;
+
+	reg->size = 4;
+	reg->val = cx_read(reg->reg);
+	return 0;
+}
+
+static int cx23417_g_register(struct cx23885_dev *dev,
+			      struct v4l2_dbg_register *reg)
+{
+	u32 value;
+
+	if (dev->v4l_device == NULL)
+		return -EINVAL;
+
+	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
+		return -EINVAL;
+
+	if (mc417_register_read(dev, (u16) reg->reg, &value))
+		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
+
+	reg->size = 4;
+	reg->val = value;
+	return 0;
+}
+
+int cx23885_g_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg)
+{
+	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;
+}
+
+static int cx23885_s_host_register(struct cx23885_dev *dev,
+				   struct v4l2_dbg_register *reg)
+{
+	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+		return -EINVAL;
+
+	reg->size = 4;
+	cx_write(reg->reg, reg->val);
+	return 0;
+}
+
+static int cx23417_s_register(struct cx23885_dev *dev,
+			      struct v4l2_dbg_register *reg)
+{
+	if (dev->v4l_device == NULL)
+		return -EINVAL;
+
+	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
+		return -EINVAL;
+
+	if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
+		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
+
+	reg->size = 4;
+	return 0;
+}
+
+int cx23885_s_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg)
+{
+	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_s_host_register(dev, reg);
+		case 1:
+			return cx23417_s_register(dev, reg);
+		default:
+			break;
+		}
+	}
+
+	/* FIXME - any error returns should not be ignored */
+	call_all(dev, core, s_register, reg);
+	return 0;
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ioctl.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ioctl.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ioctl.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Various common ioctl() support functions
+ *
+ *  Copyright (c) 2009 Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You 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 _CX23885_IOCTL_H_
+#define _CX23885_IOCTL_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_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg);
+
+
+int cx23885_s_register(struct file *file, void *fh,
+		       struct v4l2_dbg_register *reg);
+
+#endif
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ir.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ir.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ir.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared device support routines - non-input, non-vl42_subdev routines
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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 <media/v4l2-device.h>
+
+#include "cx23885.h"
+#include "cx23885-input.h"
+
+#define CX23885_IR_RX_FIFO_SERVICE_REQ		0
+#define CX23885_IR_RX_END_OF_RX_DETECTED	1
+#define CX23885_IR_RX_HW_FIFO_OVERRUN		2
+#define CX23885_IR_RX_SW_FIFO_OVERRUN		3
+
+#define CX23885_IR_TX_FIFO_SERVICE_REQ		0
+
+
+void cx23885_ir_rx_work_handler(struct work_struct *work)
+{
+	struct cx23885_dev *dev =
+			     container_of(work, struct cx23885_dev, ir_rx_work);
+	u32 events = 0;
+	unsigned long *notifications = &dev->ir_rx_notifications;
+
+	if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications))
+		events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
+	if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications))
+		events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
+	if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications))
+		events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
+	if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications))
+		events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+
+	if (events == 0)
+		return;
+
+	if (dev->ir_input)
+		cx23885_input_rx_work_handler(dev, events);
+}
+
+void cx23885_ir_tx_work_handler(struct work_struct *work)
+{
+	struct cx23885_dev *dev =
+			     container_of(work, struct cx23885_dev, ir_tx_work);
+	u32 events = 0;
+	unsigned long *notifications = &dev->ir_tx_notifications;
+
+	if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications))
+		events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
+
+	if (events == 0)
+		return;
+
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+	struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+	unsigned long *notifications = &dev->ir_rx_notifications;
+
+	if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ)
+		set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED)
+		set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN)
+		set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications);
+	if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN)
+		set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications);
+	schedule_work(&dev->ir_rx_work);
+}
+
+/* Called in an IRQ context */
+void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events)
+{
+	struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev);
+	unsigned long *notifications = &dev->ir_tx_notifications;
+
+	if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ)
+		set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications);
+	schedule_work(&dev->ir_tx_work);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ir.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ir.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-ir.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-ir.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,31 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  Infrared device support routines - non-input, non-vl42_subdev routines
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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 _CX23885_IR_H_
+#define _CX23885_IR_H_
+void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
+void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events);
+
+void cx23885_ir_rx_work_handler(struct work_struct *work);
+void cx23885_ir_tx_work_handler(struct work_struct *work);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-reg.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-reg.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -212,8 +212,9 @@ Channel manager Data Structure entry = 2
 
 #define DEV_CNTRL2	0x00040000
 
-#define PCI_MSK_GPIO1   (1 << 24)
-#define PCI_MSK_GPIO0   (1 << 23)
+#define PCI_MSK_IR        (1 << 28)
+#define PCI_MSK_GPIO1     (1 << 24)
+#define PCI_MSK_GPIO0     (1 << 23)
 #define PCI_MSK_APB_DMA   (1 << 12)
 #define PCI_MSK_AL_WR     (1 << 11)
 #define PCI_MSK_AL_RD     (1 << 10)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-video.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23885-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23885-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
 #include "cx23885.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include "cx23885-ioctl.h"
 
 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -317,11 +318,11 @@ static struct video_device *cx23885_vdev
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor = -1;
 	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 dev->name, type, cx23885_boards[dev->board].name);
+	video_set_drvdata(vfd, dev);
 	return vfd;
 }
 
@@ -401,6 +402,13 @@ static int cx23885_video_mux(struct cx23
 		INPUT(input)->gpio2, INPUT(input)->gpio3);
 	dev->input = input;
 
+	if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
+		dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) {
+		/* Select Analog TV */
+		if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
+			cx23885_gpio_clear(dev, GPIO_0);
+	}
+
 	/* Tell the internal A/V decoder */
 	v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
 			INPUT(input)->vmux, 0, 0);
@@ -708,46 +716,34 @@ static int get_resource(struct cx23885_f
 
 static int video_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct cx23885_dev *h, *dev = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh;
-	struct list_head *list;
 	enum v4l2_buf_type type = 0;
 	int radio = 0;
 
-	lock_kernel();
-	list_for_each(list, &cx23885_devlist) {
-		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->video_dev &&
-		    h->video_dev->minor == minor) {
-			dev  = h;
-			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		}
-		if (h->vbi_dev &&
-		    h->vbi_dev->minor == minor) {
-			dev  = h;
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		}
-		if (h->radio_dev &&
-		    h->radio_dev->minor == minor) {
-			radio = 1;
-			dev   = h;
-		}
-	}
-	if (NULL == dev) {
-		unlock_kernel();
-		return -ENODEV;
+	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(1, "open minor=%d radio=%d type=%s\n",
-		minor, radio, v4l2_type_names[type]);
+	dprintk(1, "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);
-	if (NULL == fh) {
-		unlock_kernel();
+	if (NULL == fh)
 		return -ENOMEM;
-	}
+
+	lock_kernel();
+
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
@@ -1144,6 +1140,7 @@ static int cx23885_enum_input(struct cx2
 		[CX23885_VMUX_COMPOSITE3] = "Composite3",
 		[CX23885_VMUX_COMPOSITE4] = "Composite4",
 		[CX23885_VMUX_SVIDEO]     = "S-Video",
+		[CX23885_VMUX_COMPONENT]  = "Component",
 		[CX23885_VMUX_TELEVISION] = "Television",
 		[CX23885_VMUX_CABLE]      = "Cable TV",
 		[CX23885_VMUX_DVB]        = "DVB",
@@ -1312,34 +1309,6 @@ static int vidioc_s_frequency(struct fil
 		cx23885_set_freq(dev, f);
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *fh,
-				struct v4l2_dbg_register *reg)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-
-	call_all(dev, core, g_register, reg);
-
-	return 0;
-}
-
-static int vidioc_s_register(struct file *file, void *fh,
-				struct v4l2_dbg_register *reg)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-
-	call_all(dev, core, s_register, reg);
-
-	return 0;
-}
-#endif
-
 /* ----------------------------------------------------------- */
 
 static void cx23885_vid_timeout(unsigned long data)
@@ -1449,9 +1418,10 @@ 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_register    = vidioc_g_register,
-	.vidioc_s_register    = vidioc_s_register,
+	.vidioc_g_register    = cx23885_g_register,
+	.vidioc_s_register    = cx23885_s_register,
 #endif
 };
 
@@ -1459,7 +1429,6 @@ static struct video_device cx23885_vbi_t
 static struct video_device cx23885_video_template = {
 	.name                 = "cx23885-video",
 	.fops                 = &video_fops,
-	.minor                = -1,
 	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX23885_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
@@ -1479,7 +1448,7 @@ void cx23885_video_unregister(struct cx2
 	cx_clear(PCI_INT_MSK, 1);
 
 	if (dev->video_dev) {
-		if (-1 != dev->video_dev->minor)
+		if (video_is_registered(dev->video_dev))
 			video_unregister_device(dev->video_dev);
 		else
 			video_device_release(dev->video_dev);
@@ -1529,9 +1498,11 @@ int cx23885_video_register(struct cx2388
 		if (sd) {
 			struct tuner_setup tun_setup;
 
+			memset(&tun_setup, 0, sizeof(tun_setup));
 			tun_setup.mode_mask = T_ANALOG_TV;
 			tun_setup.type = dev->tuner_type;
 			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+			tun_setup.tuner_callback = cx23885_tuner_callback;
 
 			v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
 		}
@@ -1548,8 +1519,8 @@ int cx23885_video_register(struct cx2388
 			dev->name);
 		goto fail_unreg;
 	}
-	printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
-	       dev->name, dev->video_dev->num);
+	printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
+	       dev->name, video_device_node_name(dev->video_dev));
 	/* initial device configuration */
 	mutex_lock(&dev->lock);
 	cx23885_set_tvnorm(dev, dev->tvnorm);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23888-ir.c linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23888-ir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1233 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  CX23888 Integrated Consumer Infrared Controller
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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/kfifo.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "cx23885.h"
+
+static unsigned int ir_888_debug;
+module_param(ir_888_debug, int, 0644);
+MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
+
+#define CX23888_IR_REG_BASE 	0x170000
+/*
+ * These CX23888 register offsets have a straightforward one to one mapping
+ * to the CX23885 register offsets of 0x200 through 0x218
+ */
+#define CX23888_IR_CNTRL_REG	0x170000
+#define CNTRL_WIN_3_3	0x00000000
+#define CNTRL_WIN_4_3	0x00000001
+#define CNTRL_WIN_3_4	0x00000002
+#define CNTRL_WIN_4_4	0x00000003
+#define CNTRL_WIN	0x00000003
+#define CNTRL_EDG_NONE	0x00000000
+#define CNTRL_EDG_FALL	0x00000004
+#define CNTRL_EDG_RISE	0x00000008
+#define CNTRL_EDG_BOTH	0x0000000C
+#define CNTRL_EDG	0x0000000C
+#define CNTRL_DMD	0x00000010
+#define CNTRL_MOD	0x00000020
+#define CNTRL_RFE	0x00000040
+#define CNTRL_TFE	0x00000080
+#define CNTRL_RXE	0x00000100
+#define CNTRL_TXE	0x00000200
+#define CNTRL_RIC	0x00000400
+#define CNTRL_TIC	0x00000800
+#define CNTRL_CPL	0x00001000
+#define CNTRL_LBM	0x00002000
+#define CNTRL_R		0x00004000
+
+#define CX23888_IR_TXCLK_REG	0x170004
+#define TXCLK_TCD	0x0000FFFF
+
+#define CX23888_IR_RXCLK_REG	0x170008
+#define RXCLK_RCD	0x0000FFFF
+
+#define CX23888_IR_CDUTY_REG	0x17000C
+#define CDUTY_CDC	0x0000000F
+
+#define CX23888_IR_STATS_REG	0x170010
+#define STATS_RTO	0x00000001
+#define STATS_ROR	0x00000002
+#define STATS_RBY	0x00000004
+#define STATS_TBY	0x00000008
+#define STATS_RSR	0x00000010
+#define STATS_TSR	0x00000020
+
+#define CX23888_IR_IRQEN_REG	0x170014
+#define IRQEN_RTE	0x00000001
+#define IRQEN_ROE	0x00000002
+#define IRQEN_RSE	0x00000010
+#define IRQEN_TSE	0x00000020
+
+#define CX23888_IR_FILTR_REG	0x170018
+#define FILTR_LPF	0x0000FFFF
+
+/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */
+#define CX23888_IR_FIFO_REG	0x170040
+#define FIFO_RXTX	0x0000FFFF
+#define FIFO_RXTX_LVL	0x00010000
+#define FIFO_RXTX_RTO	0x0001FFFF
+#define FIFO_RX_NDV	0x00020000
+#define FIFO_RX_DEPTH	8
+#define FIFO_TX_DEPTH	8
+
+/* CX23888 unique registers */
+#define CX23888_IR_SEEDP_REG	0x17001C
+#define CX23888_IR_TIMOL_REG	0x170020
+#define CX23888_IR_WAKE0_REG	0x170024
+#define CX23888_IR_WAKE1_REG	0x170028
+#define CX23888_IR_WAKE2_REG	0x17002C
+#define CX23888_IR_MASK0_REG	0x170030
+#define CX23888_IR_MASK1_REG	0x170034
+#define CX23888_IR_MAKS2_REG	0x170038
+#define CX23888_IR_DPIPG_REG	0x17003C
+#define CX23888_IR_LEARN_REG	0x170044
+
+#define CX23888_VIDCLK_FREQ	108000000 /* 108 MHz, BT.656 */
+#define CX23888_IR_REFCLK_FREQ	(CX23888_VIDCLK_FREQ / 2)
+
+#define CX23888_IR_RX_KFIFO_SIZE	(512 * sizeof(u32))
+#define CX23888_IR_TX_KFIFO_SIZE	(512 * sizeof(u32))
+
+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;
+	atomic_t rxclk_divider;
+	atomic_t rx_invert;
+
+	struct kfifo rx_kfifo;
+	spinlock_t rx_kfifo_lock;
+
+	struct v4l2_subdev_ir_parameters tx_params;
+	struct mutex tx_params_lock;
+	atomic_t txclk_divider;
+};
+
+static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
+{
+	return v4l2_get_subdevdata(sd);
+}
+
+/*
+ * IR register block read and write functions
+ */
+static
+inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value)
+{
+	cx_write(addr, value);
+	return 0;
+}
+
+static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr)
+{
+	return cx_read(addr);
+}
+
+static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
+				     u32 and_mask, u32 or_value)
+{
+	cx_andor(addr, ~and_mask, or_value);
+	return 0;
+}
+
+/*
+ * Rx and Tx Clock Divider register computations
+ *
+ * Note the largest clock divider value of 0xffff corresponds to:
+ * 	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ * which fits in 21 bits, so we'll use unsigned int for time arguments.
+ */
+static inline u16 count_to_clock_divider(unsigned int d)
+{
+	if (d > RXCLK_RCD + 1)
+		d = RXCLK_RCD;
+	else if (d < 2)
+		d = 1;
+	else
+		d--;
+	return (u16) d;
+}
+
+static inline u16 ns_to_clock_divider(unsigned int ns)
+{
+	return count_to_clock_divider(
+		DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
+}
+
+static inline unsigned int clock_divider_to_ns(unsigned int divider)
+{
+	/* Period of the Rx or Tx clock in ns */
+	return DIV_ROUND_CLOSEST((divider + 1) * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
+{
+	return count_to_clock_divider(
+			  DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16));
+}
+
+static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
+{
+	return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
+}
+
+static inline u16 freq_to_clock_divider(unsigned int freq,
+					unsigned int rollovers)
+{
+	return count_to_clock_divider(
+		   DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
+}
+
+static inline unsigned int clock_divider_to_freq(unsigned int divider,
+						 unsigned int rollovers)
+{
+	return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ,
+				 (divider + 1) * rollovers);
+}
+
+/*
+ * Low Pass Filter register calculations
+ *
+ * Note the largest count value of 0xffff corresponds to:
+ * 	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ * which fits in 21 bits, so we'll use unsigned int for time arguments.
+ */
+static inline u16 count_to_lpf_count(unsigned int d)
+{
+	if (d > FILTR_LPF)
+		d = FILTR_LPF;
+	else if (d < 4)
+		d = 0;
+	return (u16) d;
+}
+
+static inline u16 ns_to_lpf_count(unsigned int ns)
+{
+	return count_to_lpf_count(
+		DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
+}
+
+static inline unsigned int lpf_count_to_ns(unsigned int count)
+{
+	/* Duration of the Low Pass Filter rejection window in ns */
+	return DIV_ROUND_CLOSEST(count * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static inline unsigned int lpf_count_to_us(unsigned int count)
+{
+	/* Duration of the Low Pass Filter rejection window in us */
+	return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+/*
+ * FIFO register pulse width count compuations
+ */
+static u32 clock_divider_to_resolution(u16 divider)
+{
+	/*
+	 * Resolution is the duration of 1 tick of the readable portion of
+	 * of the pulse width counter as read from the FIFO.  The two lsb's are
+	 * not readable, hence the << 2.  This function returns ns.
+	 */
+	return DIV_ROUND_CLOSEST((1 << 2)  * ((u32) divider + 1) * 1000,
+				 CX23888_IR_REFCLK_FREQ / 1000000);
+}
+
+static u64 pulse_width_count_to_ns(u16 count, u16 divider)
+{
+	u64 n;
+	u32 rem;
+
+	/*
+	 * The 2 lsb's of the pulse width timer count are not readable, hence
+	 * the (count << 2) | 0x3
+	 */
+	n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */
+	rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000);     /* / MHz => ns */
+	if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
+		n++;
+	return n;
+}
+
+static unsigned int pulse_width_count_to_us(u16 count, u16 divider)
+{
+	u64 n;
+	u32 rem;
+
+	/*
+	 * The 2 lsb's of the pulse width timer count are not readable, hence
+	 * the (count << 2) | 0x3
+	 */
+	n = (((u64) count << 2) | 0x3) * (divider + 1);    /* cycles      */
+	rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */
+	if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2)
+		n++;
+	return (unsigned int) n;
+}
+
+/*
+ * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts
+ *
+ * The total pulse clock count is an 18 bit pulse width timer count as the most
+ * significant part and (up to) 16 bit clock divider count as a modulus.
+ * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse
+ * width timer count's least significant bit.
+ */
+static u64 ns_to_pulse_clocks(u32 ns)
+{
+	u64 clocks;
+	u32 rem;
+	clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles  */
+	rem = do_div(clocks, 1000);                         /* /1000 = cycles */
+	if (rem >= 1000 / 2)
+		clocks++;
+	return clocks;
+}
+
+static u16 pulse_clocks_to_clock_divider(u64 count)
+{
+	u32 rem;
+
+	rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
+
+	/* net result needs to be rounded down and decremented by 1 */
+	if (count > RXCLK_RCD + 1)
+		count = RXCLK_RCD;
+	else if (count < 2)
+		count = 1;
+	else
+		count--;
+	return (u16) count;
+}
+
+/*
+ * IR Control Register helpers
+ */
+enum tx_fifo_watermark {
+	TX_FIFO_HALF_EMPTY = 0,
+	TX_FIFO_EMPTY      = CNTRL_TIC,
+};
+
+enum rx_fifo_watermark {
+	RX_FIFO_HALF_FULL = 0,
+	RX_FIFO_NOT_EMPTY = CNTRL_RIC,
+};
+
+static inline void control_tx_irq_watermark(struct cx23885_dev *dev,
+					    enum tx_fifo_watermark level)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level);
+}
+
+static inline void control_rx_irq_watermark(struct cx23885_dev *dev,
+					    enum rx_fifo_watermark level)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level);
+}
+
+static inline void control_tx_enable(struct cx23885_dev *dev, bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE),
+			   enable ? (CNTRL_TXE | CNTRL_TFE) : 0);
+}
+
+static inline void control_rx_enable(struct cx23885_dev *dev, bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE),
+			   enable ? (CNTRL_RXE | CNTRL_RFE) : 0);
+}
+
+static inline void control_tx_modulation_enable(struct cx23885_dev *dev,
+						bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD,
+			   enable ? CNTRL_MOD : 0);
+}
+
+static inline void control_rx_demodulation_enable(struct cx23885_dev *dev,
+						  bool enable)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD,
+			   enable ? CNTRL_DMD : 0);
+}
+
+static inline void control_rx_s_edge_detection(struct cx23885_dev *dev,
+					       u32 edge_types)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH,
+			   edge_types & CNTRL_EDG_BOTH);
+}
+
+static void control_rx_s_carrier_window(struct cx23885_dev *dev,
+					unsigned int carrier,
+					unsigned int *carrier_range_low,
+					unsigned int *carrier_range_high)
+{
+	u32 v;
+	unsigned int c16 = carrier * 16;
+
+	if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) {
+		v = CNTRL_WIN_3_4;
+		*carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4);
+	} else {
+		v = CNTRL_WIN_3_3;
+		*carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3);
+	}
+
+	if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) {
+		v |= CNTRL_WIN_4_3;
+		*carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4);
+	} else {
+		v |= CNTRL_WIN_3_3;
+		*carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3);
+	}
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v);
+}
+
+static inline void control_tx_polarity_invert(struct cx23885_dev *dev,
+					      bool invert)
+{
+	cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL,
+			   invert ? CNTRL_CPL : 0);
+}
+
+/*
+ * IR Rx & Tx Clock Register helpers
+ */
+static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev,
+				       unsigned int freq,
+				       u16 *divider)
+{
+	*divider = carrier_freq_to_clock_divider(freq);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
+	return clock_divider_to_carrier_freq(*divider);
+}
+
+static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev,
+				       unsigned int freq,
+				       u16 *divider)
+{
+	*divider = carrier_freq_to_clock_divider(freq);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
+	return clock_divider_to_carrier_freq(*divider);
+}
+
+static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
+				      u16 *divider)
+{
+	u64 pulse_clocks;
+
+	if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+		ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	pulse_clocks = ns_to_pulse_clocks(ns);
+	*divider = pulse_clocks_to_clock_divider(pulse_clocks);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider);
+	return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
+}
+
+static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns,
+				      u16 *divider)
+{
+	u64 pulse_clocks;
+
+	if (ns > V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+		ns = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
+	pulse_clocks = ns_to_pulse_clocks(ns);
+	*divider = pulse_clocks_to_clock_divider(pulse_clocks);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider);
+	return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider);
+}
+
+/*
+ * IR Tx Carrier Duty Cycle register helpers
+ */
+static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev,
+					  unsigned int duty_cycle)
+{
+	u32 n;
+	n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */
+	if (n != 0)
+		n--;
+	if (n > 15)
+		n = 15;
+	cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n);
+	return DIV_ROUND_CLOSEST((n + 1) * 100, 16);
+}
+
+/*
+ * IR Filter Register helpers
+ */
+static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns)
+{
+	u32 count = ns_to_lpf_count(min_width_ns);
+	cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count);
+	return lpf_count_to_ns(count);
+}
+
+/*
+ * IR IRQ Enable Register helpers
+ */
+static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask)
+{
+	mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE);
+	cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG,
+			   ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask);
+}
+
+static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask)
+{
+	mask &= IRQEN_TSE;
+	cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask);
+}
+
+/*
+ * V4L2 Subdevice IR Ops
+ */
+static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
+				  bool *handled)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	unsigned long flags;
+
+	u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
+	u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
+	u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
+
+	u32 rx_data[FIFO_RX_DEPTH];
+	int i, j, k;
+	u32 events, v;
+	int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;
+
+	tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
+	rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
+	rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
+	ror = stats & STATS_ROR; /* Rx FIFO Over Run */
+
+	tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
+	rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
+	rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
+	roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */
+
+	*handled = false;
+	v4l2_dbg(2, ir_888_debug, sd, "IRQ Status:  %s %s %s %s %s %s\n",
+		 tsr ? "tsr" : "   ", rsr ? "rsr" : "   ",
+		 rto ? "rto" : "   ", ror ? "ror" : "   ",
+		 stats & STATS_TBY ? "tby" : "   ",
+		 stats & STATS_RBY ? "rby" : "   ");
+
+	v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
+		 tse ? "tse" : "   ", rse ? "rse" : "   ",
+		 rte ? "rte" : "   ", roe ? "roe" : "   ");
+
+	/*
+	 * Transmitter interrupt service
+	 */
+	if (tse && tsr) {
+		/*
+		 * TODO:
+		 * Check the watermark threshold setting
+		 * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
+		 * Push the data to the hardware FIFO.
+		 * If there was nothing more to send in the tx_kfifo, disable
+		 *	the TSR IRQ and notify the v4l2_device.
+		 * If there was something in the tx_kfifo, check the tx_kfifo
+		 *      level and notify the v4l2_device, if it is low.
+		 */
+		/* For now, inhibit TSR interrupt until Tx is implemented */
+		irqenable_tx(dev, 0);
+		events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
+		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
+		*handled = true;
+	}
+
+	/*
+	 * Receiver interrupt service
+	 */
+	kror = 0;
+	if ((rse && rsr) || (rte && rto)) {
+		/*
+		 * Receive data on RSR to clear the STATS_RSR.
+		 * Receive data on RTO, since we may not have yet hit the RSR
+		 * watermark when we receive the RTO.
+		 */
+		for (i = 0, v = FIFO_RX_NDV;
+		     (v & FIFO_RX_NDV) && !kror; i = 0) {
+			for (j = 0;
+			     (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
+				v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
+				rx_data[i++] = v & ~FIFO_RX_NDV;
+			}
+			if (i == 0)
+				break;
+			j = i * sizeof(u32);
+			k = kfifo_in_locked(&state->rx_kfifo,
+				      (unsigned char *) rx_data, j,
+				      &state->rx_kfifo_lock);
+			if (k != j)
+				kror++; /* rx_kfifo over run */
+		}
+		*handled = true;
+	}
+
+	events = 0;
+	v = 0;
+	if (kror) {
+		events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
+		v4l2_err(sd, "IR receiver software FIFO overrun\n");
+	}
+	if (roe && ror) {
+		/*
+		 * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
+		 * the Rx FIFO Over Run status (STATS_ROR)
+		 */
+		v |= CNTRL_RFE;
+		events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
+		v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
+	}
+	if (rte && rto) {
+		/*
+		 * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
+		 * the Rx Pulse Width Timer Time Out (STATS_RTO)
+		 */
+		v |= CNTRL_RXE;
+		events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
+	}
+	if (v) {
+		/* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
+		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
+		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
+		*handled = true;
+	}
+
+	spin_lock_irqsave(&state->rx_kfifo_lock, flags);
+	if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
+		events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+	spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
+
+	if (events)
+		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
+	return 0;
+}
+
+/* Receiver */
+static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
+			      ssize_t *num)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	bool invert = (bool) atomic_read(&state->rx_invert);
+	u16 divider = (u16) atomic_read(&state->rxclk_divider);
+
+	unsigned int i, n;
+	u32 *p;
+	u32 u, v;
+
+	n = count / sizeof(u32) * sizeof(u32);
+	if (n == 0) {
+		*num = 0;
+		return 0;
+	}
+
+	n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
+
+	n /= sizeof(u32);
+	*num = n * sizeof(u32);
+
+	for (p = (u32 *) buf, i = 0; i < n; p++, i++) {
+		if ((*p & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) {
+			*p = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
+			v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n");
+			continue;
+		}
+
+		u = (*p & FIFO_RXTX_LVL) ? V4L2_SUBDEV_IR_PULSE_LEVEL_MASK : 0;
+		if (invert)
+			u = u ? 0 : V4L2_SUBDEV_IR_PULSE_LEVEL_MASK;
+
+		v = (u32) pulse_width_count_to_ns((u16) (*p & FIFO_RXTX),
+						  divider);
+		if (v >= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS)
+			v = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS - 1;
+
+		*p = u | v;
+
+		v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns  %s\n",
+			 v, u ? "mark" : "space");
+	}
+	return 0;
+}
+
+static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	mutex_lock(&state->rx_params_lock);
+	memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters));
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+
+	mutex_lock(&state->rx_params_lock);
+
+	/* Disable or slow down all IR Rx circuits and counters */
+	irqenable_rx(dev, 0);
+	control_rx_enable(dev, false);
+	control_rx_demodulation_enable(dev, false);
+	control_rx_s_edge_detection(dev, CNTRL_EDG_NONE);
+	filter_rx_s_min_width(dev, 0);
+	cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD);
+
+	state->rx_params.shutdown = true;
+
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	struct v4l2_subdev_ir_parameters *o = &state->rx_params;
+	u16 rxclk_divider;
+
+	if (p->shutdown)
+		return cx23888_ir_rx_shutdown(sd);
+
+	if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
+		return -ENOSYS;
+
+	mutex_lock(&state->rx_params_lock);
+
+	o->shutdown = p->shutdown;
+
+	o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+
+	o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+
+	/* Before we tweak the hardware, we have to disable the receiver */
+	irqenable_rx(dev, 0);
+	control_rx_enable(dev, false);
+
+	control_rx_demodulation_enable(dev, p->modulation);
+	o->modulation = p->modulation;
+
+	if (p->modulation) {
+		p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq,
+						     &rxclk_divider);
+
+		o->carrier_freq = p->carrier_freq;
+
+		o->duty_cycle = p->duty_cycle = 50;
+
+		control_rx_s_carrier_window(dev, p->carrier_freq,
+					    &p->carrier_range_lower,
+					    &p->carrier_range_upper);
+		o->carrier_range_lower = p->carrier_range_lower;
+		o->carrier_range_upper = p->carrier_range_upper;
+	} else {
+		p->max_pulse_width =
+			    rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width,
+						       &rxclk_divider);
+		o->max_pulse_width = p->max_pulse_width;
+	}
+	atomic_set(&state->rxclk_divider, rxclk_divider);
+
+	p->noise_filter_min_width =
+			  filter_rx_s_min_width(dev, p->noise_filter_min_width);
+	o->noise_filter_min_width = p->noise_filter_min_width;
+
+	p->resolution = clock_divider_to_resolution(rxclk_divider);
+	o->resolution = p->resolution;
+
+	/* FIXME - make this dependent on resolution for better performance */
+	control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL);
+
+	control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH);
+
+	o->invert = p->invert;
+	atomic_set(&state->rx_invert, p->invert);
+
+	o->interrupt_enable = p->interrupt_enable;
+	o->enable = p->enable;
+	if (p->enable) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&state->rx_kfifo_lock, flags);
+		kfifo_reset(&state->rx_kfifo);
+		/* reset tx_fifo too if there is one... */
+		spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
+		if (p->interrupt_enable)
+			irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
+		control_rx_enable(dev, p->enable);
+	}
+
+	mutex_unlock(&state->rx_params_lock);
+	return 0;
+}
+
+/* Transmitter */
+static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
+			       ssize_t *num)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	/* For now enable the Tx FIFO Service interrupt & pretend we did work */
+	irqenable_tx(dev, IRQEN_TSE);
+	*num = count;
+	return 0;
+}
+
+static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	mutex_lock(&state->tx_params_lock);
+	memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters));
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+
+	mutex_lock(&state->tx_params_lock);
+
+	/* Disable or slow down all IR Tx circuits and counters */
+	irqenable_tx(dev, 0);
+	control_tx_enable(dev, false);
+	control_tx_modulation_enable(dev, false);
+	cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD);
+
+	state->tx_params.shutdown = true;
+
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_ir_parameters *p)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	struct v4l2_subdev_ir_parameters *o = &state->tx_params;
+	u16 txclk_divider;
+
+	if (p->shutdown)
+		return cx23888_ir_tx_shutdown(sd);
+
+	if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH)
+		return -ENOSYS;
+
+	mutex_lock(&state->tx_params_lock);
+
+	o->shutdown = p->shutdown;
+
+	o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH;
+
+	o->bytes_per_data_element = p->bytes_per_data_element = sizeof(u32);
+
+	/* Before we tweak the hardware, we have to disable the transmitter */
+	irqenable_tx(dev, 0);
+	control_tx_enable(dev, false);
+
+	control_tx_modulation_enable(dev, p->modulation);
+	o->modulation = p->modulation;
+
+	if (p->modulation) {
+		p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq,
+						     &txclk_divider);
+		o->carrier_freq = p->carrier_freq;
+
+		p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle);
+		o->duty_cycle = p->duty_cycle;
+	} else {
+		p->max_pulse_width =
+			    txclk_tx_s_max_pulse_width(dev, p->max_pulse_width,
+						       &txclk_divider);
+		o->max_pulse_width = p->max_pulse_width;
+	}
+	atomic_set(&state->txclk_divider, txclk_divider);
+
+	p->resolution = clock_divider_to_resolution(txclk_divider);
+	o->resolution = p->resolution;
+
+	/* FIXME - make this dependent on resolution for better performance */
+	control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY);
+
+	control_tx_polarity_invert(dev, p->invert);
+	o->invert = p->invert;
+
+	o->interrupt_enable = p->interrupt_enable;
+	o->enable = p->enable;
+	if (p->enable) {
+		if (p->interrupt_enable)
+			irqenable_tx(dev, IRQEN_TSE);
+		control_tx_enable(dev, p->enable);
+	}
+
+	mutex_unlock(&state->tx_params_lock);
+	return 0;
+}
+
+
+/*
+ * V4L2 Subdevice Core Ops
+ */
+static int cx23888_ir_log_status(struct v4l2_subdev *sd)
+{
+	struct cx23888_ir_state *state = to_state(sd);
+	struct cx23885_dev *dev = state->dev;
+	char *s;
+	int i, j;
+
+	u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
+	u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD;
+	u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD;
+	u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC;
+	u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);
+	u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
+	u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF;
+
+	v4l2_info(sd, "IR Receiver:\n");
+	v4l2_info(sd, "\tEnabled:                           %s\n",
+		  cntrl & CNTRL_RXE ? "yes" : "no");
+	v4l2_info(sd, "\tDemodulation from a carrier:       %s\n",
+		  cntrl & CNTRL_DMD ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO:                              %s\n",
+		  cntrl & CNTRL_RFE ? "enabled" : "disabled");
+	switch (cntrl & CNTRL_EDG) {
+	case CNTRL_EDG_NONE:
+		s = "disabled";
+		break;
+	case CNTRL_EDG_FALL:
+		s = "falling edge";
+		break;
+	case CNTRL_EDG_RISE:
+		s = "rising edge";
+		break;
+	case CNTRL_EDG_BOTH:
+		s = "rising & falling edges";
+		break;
+	default:
+		s = "??? edge";
+		break;
+	}
+	v4l2_info(sd, "\tPulse timers' start/stop trigger:  %s\n", s);
+	v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n",
+		  cntrl & CNTRL_R ? "not loaded" : "overflow marker");
+	v4l2_info(sd, "\tFIFO interrupt watermark:          %s\n",
+		  cntrl & CNTRL_RIC ? "not empty" : "half full or greater");
+	v4l2_info(sd, "\tLoopback mode:                     %s\n",
+		  cntrl & CNTRL_LBM ? "loopback active" : "normal receive");
+	if (cntrl & CNTRL_DMD) {
+		v4l2_info(sd, "\tExpected carrier (16 clocks):      %u Hz\n",
+			  clock_divider_to_carrier_freq(rxclk));
+		switch (cntrl & CNTRL_WIN) {
+		case CNTRL_WIN_3_3:
+			i = 3;
+			j = 3;
+			break;
+		case CNTRL_WIN_4_3:
+			i = 4;
+			j = 3;
+			break;
+		case CNTRL_WIN_3_4:
+			i = 3;
+			j = 4;
+			break;
+		case CNTRL_WIN_4_4:
+			i = 4;
+			j = 4;
+			break;
+		default:
+			i = 0;
+			j = 0;
+			break;
+		}
+		v4l2_info(sd, "\tNext carrier edge window:          16 clocks "
+			  "-%1d/+%1d, %u to %u Hz\n", i, j,
+			  clock_divider_to_freq(rxclk, 16 + j),
+			  clock_divider_to_freq(rxclk, 16 - i));
+	} else {
+		v4l2_info(sd, "\tMax measurable pulse width:        %u us, "
+			  "%llu ns\n",
+			  pulse_width_count_to_us(FIFO_RXTX, rxclk),
+			  pulse_width_count_to_ns(FIFO_RXTX, rxclk));
+	}
+	v4l2_info(sd, "\tLow pass filter:                   %s\n",
+		  filtr ? "enabled" : "disabled");
+	if (filtr)
+		v4l2_info(sd, "\tMin acceptable pulse width (LPF):  %u us, "
+			  "%u ns\n",
+			  lpf_count_to_us(filtr),
+			  lpf_count_to_ns(filtr));
+	v4l2_info(sd, "\tPulse width timer timed-out:       %s\n",
+		  stats & STATS_RTO ? "yes" : "no");
+	v4l2_info(sd, "\tPulse width timer time-out intr:   %s\n",
+		  irqen & IRQEN_RTE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO overrun:                      %s\n",
+		  stats & STATS_ROR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO overrun interrupt:            %s\n",
+		  irqen & IRQEN_ROE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tBusy:                              %s\n",
+		  stats & STATS_RBY ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service requested:            %s\n",
+		  stats & STATS_RSR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service request interrupt:    %s\n",
+		  irqen & IRQEN_RSE ? "enabled" : "disabled");
+
+	v4l2_info(sd, "IR Transmitter:\n");
+	v4l2_info(sd, "\tEnabled:                           %s\n",
+		  cntrl & CNTRL_TXE ? "yes" : "no");
+	v4l2_info(sd, "\tModulation onto a carrier:         %s\n",
+		  cntrl & CNTRL_MOD ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO:                              %s\n",
+		  cntrl & CNTRL_TFE ? "enabled" : "disabled");
+	v4l2_info(sd, "\tFIFO interrupt watermark:          %s\n",
+		  cntrl & CNTRL_TIC ? "not empty" : "half full or less");
+	v4l2_info(sd, "\tSignal polarity:                   %s\n",
+		  cntrl & CNTRL_CPL ? "0:mark 1:space" : "0:space 1:mark");
+	if (cntrl & CNTRL_MOD) {
+		v4l2_info(sd, "\tCarrier (16 clocks):               %u Hz\n",
+			  clock_divider_to_carrier_freq(txclk));
+		v4l2_info(sd, "\tCarrier duty cycle:                %2u/16\n",
+			  cduty + 1);
+	} else {
+		v4l2_info(sd, "\tMax pulse width:                   %u us, "
+			  "%llu ns\n",
+			  pulse_width_count_to_us(FIFO_RXTX, txclk),
+			  pulse_width_count_to_ns(FIFO_RXTX, txclk));
+	}
+	v4l2_info(sd, "\tBusy:                              %s\n",
+		  stats & STATS_TBY ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service requested:            %s\n",
+		  stats & STATS_TSR ? "yes" : "no");
+	v4l2_info(sd, "\tFIFO service request interrupt:    %s\n",
+		  irqen & IRQEN_TSE ? "enabled" : "disabled");
+
+	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)
+{
+	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;
+}
+
+static int cx23888_ir_s_register(struct v4l2_subdev *sd,
+				 struct v4l2_dbg_register *reg)
+{
+	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,
+	.s_register = cx23888_ir_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = {
+	.interrupt_service_routine = cx23888_ir_irq_handler,
+
+	.rx_read = cx23888_ir_rx_read,
+	.rx_g_parameters = cx23888_ir_rx_g_parameters,
+	.rx_s_parameters = cx23888_ir_rx_s_parameters,
+
+	.tx_write = cx23888_ir_tx_write,
+	.tx_g_parameters = cx23888_ir_tx_g_parameters,
+	.tx_s_parameters = cx23888_ir_tx_s_parameters,
+};
+
+static const struct v4l2_subdev_ops cx23888_ir_controller_ops = {
+	.core = &cx23888_ir_core_ops,
+	.ir = &cx23888_ir_ir_ops,
+};
+
+static const struct v4l2_subdev_ir_parameters default_rx_params = {
+	.bytes_per_data_element = sizeof(u32),
+	.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
+
+	.enable = false,
+	.interrupt_enable = false,
+	.shutdown = true,
+
+	.modulation = true,
+	.carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */
+
+	/* RC-5:    666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */
+	/* RC-6A:   333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */
+	.noise_filter_min_width = 333333, /* ns */
+	.carrier_range_lower = 35000,
+	.carrier_range_upper = 37000,
+	.invert = false,
+};
+
+static const struct v4l2_subdev_ir_parameters default_tx_params = {
+	.bytes_per_data_element = sizeof(u32),
+	.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
+
+	.enable = false,
+	.interrupt_enable = false,
+	.shutdown = true,
+
+	.modulation = true,
+	.carrier_freq = 36000, /* 36 kHz - RC-5 carrier */
+	.duty_cycle = 25,      /* 25 %   - RC-5 carrier */
+	.invert = false,
+};
+
+int cx23888_ir_probe(struct cx23885_dev *dev)
+{
+	struct cx23888_ir_state *state;
+	struct v4l2_subdev *sd;
+	struct v4l2_subdev_ir_parameters default_params;
+	int ret;
+
+	state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+
+	spin_lock_init(&state->rx_kfifo_lock);
+	if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL))
+		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);
+	v4l2_set_subdevdata(sd, state);
+	/* FIXME - fix the formatting of dev->v4l2_dev.name and use it */
+	snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name);
+	sd->grp_id = CX23885_HW_888_IR;
+
+	ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd);
+	if (ret == 0) {
+		/*
+		 * Ensure no interrupts arrive from '888 specific conditions,
+		 * since we ignore them in this driver to have commonality with
+		 * similar IR controller cores.
+		 */
+		cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0);
+
+		mutex_init(&state->rx_params_lock);
+		memcpy(&default_params, &default_rx_params,
+		       sizeof(struct v4l2_subdev_ir_parameters));
+		v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params);
+
+		mutex_init(&state->tx_params_lock);
+		memcpy(&default_params, &default_tx_params,
+		       sizeof(struct v4l2_subdev_ir_parameters));
+		v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
+	} else {
+		kfifo_free(&state->rx_kfifo);
+	}
+	return ret;
+}
+
+int cx23888_ir_remove(struct cx23885_dev *dev)
+{
+	struct v4l2_subdev *sd;
+	struct cx23888_ir_state *state;
+
+	sd = cx23885_find_hw(dev, CX23885_HW_888_IR);
+	if (sd == NULL)
+		return -ENODEV;
+
+	cx23888_ir_rx_shutdown(sd);
+	cx23888_ir_tx_shutdown(sd);
+
+	state = to_state(sd);
+	v4l2_device_unregister_subdev(sd);
+	kfifo_free(&state->rx_kfifo);
+	kfree(state);
+	/* Nothing more to free() as state held the actual v4l2_subdev object */
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23888-ir.h linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/cx23888-ir.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/cx23888-ir.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ *  Driver for the Conexant CX23885/7/8 PCIe bridge
+ *
+ *  CX23888 Integrated Consumer Infrared Controller
+ *
+ *  Copyright (C) 2009  Andy Walls <awalls@radix.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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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 _CX23888_IR_H_
+#define _CX23888_IR_H_
+int cx23888_ir_probe(struct cx23885_dev *dev);
+int cx23888_ir_remove(struct cx23885_dev *dev);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/Kconfig linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,9 @@ config VIDEO_CX23885
 	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
 	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
 	select DVB_STV6110 if !DVB_FE_CUSTOMISE
+	select DVB_CX24116 if !DVB_FE_CUSTOMISE
 	select DVB_STV0900 if !DVB_FE_CUSTOMISE
+	select DVB_DS3000 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/Makefile linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx23885/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx23885/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
 cx23885-objs	:= cx23885-cards.o cx23885-video.o cx23885-vbi.o \
 		    cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
-		    netup-init.o cimax2.o netup-eeprom.o
+		    cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
+		    netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
 
 obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-audio.c linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-audio.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-audio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-audio.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,87 +23,137 @@
 
 #include "cx25840-core.h"
 
-static int set_audclk_freq(struct i2c_client *client, u32 freq)
+/*
+ * Note: The PLL and SRC parameters are based on a reference frequency that
+ * would ideally be:
+ *
+ * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+ *
+ * However, it's not the exact reference frequency that matters, only that the
+ * firmware and modules that comprise the driver for a particular board all
+ * use the same value (close to the ideal value).
+ *
+ * Comments below will note which reference frequency is assumed for various
+ * parameters.  They will usually be one of
+ *
+ *	ref_freq = 28.636360 MHz
+ *		or
+ *	ref_freq = 28.636363 MHz
+ */
+
+static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 
-	if (freq != 32000 && freq != 44100 && freq != 48000)
-		return -EINVAL;
-
-	/* common for all inputs and rates */
-	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
-	if (!state->is_cx23885 && !state->is_cx231xx)
-		cx25840_write(client, 0x127, 0x50);
-
 	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		switch (freq) {
 		case 32000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x1006040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1006040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x01bb39ee);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x1bb39ee
+			 * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384
+			 * 196.6 MHz pre-postdivide
+			 * FIXME < 200 MHz is out of specified valid range
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x01bb39ee);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x0801f77f */
+			/* src3/4/6_ctl */
+			/* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
 			cx25840_write4(client, 0x900, 0x0801f77f);
 			cx25840_write4(client, 0x904, 0x0801f77f);
 			cx25840_write4(client, 0x90c, 0x0801f77f);
 			break;
 
 		case 44100:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x1009040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1009040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x00ec6bd6);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x0ec6bd6
+			 * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384
+			 * 271 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x00ec6bd6);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x08016d59 */
+			/* src3/4/6_ctl */
+			/* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
 			cx25840_write4(client, 0x900, 0x08016d59);
 			cx25840_write4(client, 0x904, 0x08016d59);
 			cx25840_write4(client, 0x90c, 0x08016d59);
 			break;
 
 		case 48000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10
+			 */
+			cx25840_write4(client, 0x108, 0x100a040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x100a040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x0098d6e5);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x098d6e5
+			 * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384
+			 * 295 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x0098d6e5);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src3/4/6_ctl = 0x08014faa */
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
 			cx25840_write4(client, 0x900, 0x08014faa);
 			cx25840_write4(client, 0x904, 0x08014faa);
 			cx25840_write4(client, 0x90c, 0x08014faa);
@@ -112,91 +162,173 @@ static int set_audclk_freq(struct i2c_cl
 	} else {
 		switch (freq) {
 		case 32000:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e
+			 */
+			cx25840_write4(client, 0x108, 0x1e08040f);
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1e08040f);
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x012a0869);
-			}
+			/*
+			 * AUX_PLL Fraction = 0x12a0869
+			 * 28636363 * 0x8.9504348/0x1e = 32000 * 256
+			 * 246 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x012a0869);
 
-			if (state->is_cx25836)
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x54);
+
+			if (is_cx2583x(state))
 				break;
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.0000 = 32000/32000 */
 			cx25840_write4(client, 0x8f8, 0x08010000);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
 			cx25840_write4(client, 0x900, 0x08020000);
 			cx25840_write4(client, 0x904, 0x08020000);
 			cx25840_write4(client, 0x90c, 0x08020000);
-
-			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
-			cx25840_write(client, 0x127, 0x54);
 			break;
 
 		case 44100:
-			if (state->is_cx23885) {
-				/* We don't have register values
-				 * so avoid destroying registers. */
-				break;
-			}
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18
+			 */
+			cx25840_write4(client, 0x108, 0x1809040f);
 
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-			if (!state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x1809040f);
+			/*
+			 * AUX_PLL Fraction = 0x0ec6bd6
+			 * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256
+			 * 271 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x00ec6bd6);
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x00ec6bd6);
-			}
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
 
-			if (state->is_cx25836)
+			if (is_cx2583x(state))
 				break;
 
-			/* src1_ctl = 0x08010000 */
+			/* src1_ctl */
+			/* 0x1.60cd = 44100/32000 */
 			cx25840_write4(client, 0x8f8, 0x080160cd);
 
-			/* src3/4/6_ctl = 0x08020000 */
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
 			cx25840_write4(client, 0x900, 0x08017385);
 			cx25840_write4(client, 0x904, 0x08017385);
 			cx25840_write4(client, 0x90c, 0x08017385);
 			break;
 
 		case 48000:
-			if (!state->is_cx23885 && !state->is_cx231xx) {
-				/* VID_PLL and AUX_PLL */
-				cx25840_write4(client, 0x108, 0x180a040f);
+			/*
+			 * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04
+			 * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18
+			 */
+			cx25840_write4(client, 0x108, 0x180a040f);
 
-				/* AUX_PLL_FRAC */
-				cx25840_write4(client, 0x110, 0x0098d6e5);
-			}
+			/*
+			 * VID_PLL Fraction (register 0x10c) = 0x2be2fe
+			 * 28636360 * 0xf.15f17f0/4 = 108 MHz
+			 * 432 MHz pre-postdivide
+			 */
 
-			if (state->is_cx25836)
+			/*
+			 * AUX_PLL Fraction = 0x098d6e5
+			 * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256
+			 * 295 MHz pre-postdivide
+			 * FIXME 28636363 ref_freq doesn't match VID PLL ref
+			 */
+			cx25840_write4(client, 0x110, 0x0098d6e5);
+
+			/*
+			 * SA_MCLK_SEL = 1
+			 * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider
+			 */
+			cx25840_write(client, 0x127, 0x50);
+
+			if (is_cx2583x(state))
 				break;
 
-			if (!state->is_cx23885 && !state->is_cx231xx) {
-				/* src1_ctl */
-				cx25840_write4(client, 0x8f8, 0x08018000);
+			/* src1_ctl */
+			/* 0x1.8000 = 48000/32000 */
+			cx25840_write4(client, 0x8f8, 0x08018000);
 
-				/* src3/4/6_ctl */
-				cx25840_write4(client, 0x900, 0x08015555);
-				cx25840_write4(client, 0x904, 0x08015555);
-				cx25840_write4(client, 0x90c, 0x08015555);
-			} else {
+			/* src3/4/6_ctl */
+			/* 0x1.5555 = 2 * (32000/48000) */
+			cx25840_write4(client, 0x900, 0x08015555);
+			cx25840_write4(client, 0x904, 0x08015555);
+			cx25840_write4(client, 0x90c, 0x08015555);
+			break;
+		}
+	}
 
-				cx25840_write4(client, 0x8f8, 0x0801867c);
+	state->audclk_freq = freq;
 
-				cx25840_write4(client, 0x900, 0x08014faa);
-				cx25840_write4(client, 0x904, 0x08014faa);
-				cx25840_write4(client, 0x90c, 0x08014faa);
-			}
+	return 0;
+}
+
+static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	return cx25840_set_audclk_freq(client, freq);
+}
+
+static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
+		switch (freq) {
+		case 32000:
+		case 44100:
+		case 48000:
+			/* We don't have register values
+			 * so avoid destroying registers. */
+			/* FIXME return -EINVAL; */
+			break;
+		}
+	} else {
+		switch (freq) {
+		case 32000:
+		case 44100:
+			/* We don't have register values
+			 * so avoid destroying registers. */
+			/* FIXME return -EINVAL; */
+			break;
+
+		case 48000:
+			/* src1_ctl */
+			/* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
+			cx25840_write4(client, 0x8f8, 0x0801867c);
+
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
 			break;
 		}
 	}
@@ -206,6 +338,101 @@ static int set_audclk_freq(struct i2c_cl
 	return 0;
 }
 
+static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
+		switch (freq) {
+		case 32000:
+			/* src3/4/6_ctl */
+			/* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */
+			cx25840_write4(client, 0x900, 0x0801f77f);
+			cx25840_write4(client, 0x904, 0x0801f77f);
+			cx25840_write4(client, 0x90c, 0x0801f77f);
+			break;
+
+		case 44100:
+			/* src3/4/6_ctl */
+			/* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */
+			cx25840_write4(client, 0x900, 0x08016d59);
+			cx25840_write4(client, 0x904, 0x08016d59);
+			cx25840_write4(client, 0x90c, 0x08016d59);
+			break;
+
+		case 48000:
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
+			break;
+		}
+	} else {
+		switch (freq) {
+		/* FIXME These cases make different assumptions about audclk */
+		case 32000:
+			/* src1_ctl */
+			/* 0x1.0000 = 32000/32000 */
+			cx25840_write4(client, 0x8f8, 0x08010000);
+
+			/* src3/4/6_ctl */
+			/* 0x2.0000 = 2 * (32000/32000) */
+			cx25840_write4(client, 0x900, 0x08020000);
+			cx25840_write4(client, 0x904, 0x08020000);
+			cx25840_write4(client, 0x90c, 0x08020000);
+			break;
+
+		case 44100:
+			/* src1_ctl */
+			/* 0x1.60cd = 44100/32000 */
+			cx25840_write4(client, 0x8f8, 0x080160cd);
+
+			/* src3/4/6_ctl */
+			/* 0x1.7385 = 2 * (32000/44100) */
+			cx25840_write4(client, 0x900, 0x08017385);
+			cx25840_write4(client, 0x904, 0x08017385);
+			cx25840_write4(client, 0x90c, 0x08017385);
+			break;
+
+		case 48000:
+			/* src1_ctl */
+			/* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */
+			cx25840_write4(client, 0x8f8, 0x0801867c);
+
+			/* src3/4/6_ctl */
+			/* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */
+			cx25840_write4(client, 0x900, 0x08014faa);
+			cx25840_write4(client, 0x904, 0x08014faa);
+			cx25840_write4(client, 0x90c, 0x08014faa);
+			break;
+		}
+	}
+
+	state->audclk_freq = freq;
+
+	return 0;
+}
+
+static int set_audclk_freq(struct i2c_client *client, u32 freq)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (freq != 32000 && freq != 44100 && freq != 48000)
+		return -EINVAL;
+
+	if (is_cx231xx(state))
+		return cx231xx_set_audclk_freq(client, freq);
+
+	if (is_cx2388x(state))
+		return cx23885_set_audclk_freq(client, freq);
+
+	if (is_cx2583x(state))
+		return cx25836_set_audclk_freq(client, freq);
+
+	return cx25840_set_audclk_freq(client, freq);
+}
+
 void cx25840_audio_set_path(struct i2c_client *client)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -243,7 +470,7 @@ void cx25840_audio_set_path(struct i2c_c
 	cx25840_and_or(client, 0x810, ~0x1, 0x00);
 
 	/* Ensure the controller is running when we exit */
-	if (state->is_cx23885 || state->is_cx231xx)
+	if (is_cx2388x(state) || is_cx231xx(state))
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
 }
 
@@ -383,7 +610,7 @@ int cx25840_s_clock_freq(struct v4l2_sub
 	struct cx25840_state *state = to_state(sd);
 	int retval;
 
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		cx25840_and_or(client, 0x810, ~0x1, 1);
 	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		cx25840_and_or(client, 0x803, ~0x10, 0);
@@ -392,7 +619,7 @@ int cx25840_s_clock_freq(struct v4l2_sub
 	retval = set_audclk_freq(client, freq);
 	if (state->aud_input != CX25840_AUDIO_SERIAL)
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		cx25840_and_or(client, 0x810, ~0x1, 0);
 	return retval;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-core.c linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -259,6 +259,13 @@ static void cx23885_initialize(struct i2
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 	struct workqueue_struct *q;
 
+	/*
+	 * Come out of digital power down
+	 * The CX23888, at least, needs this, otherwise registers aside from
+	 * 0x0-0x2 can't be read or written.
+	 */
+	cx25840_write(client, 0x000, 0);
+
 	/* Internal Reset */
 	cx25840_and_or(client, 0x102, ~0x01, 0x01);
 	cx25840_and_or(client, 0x102, ~0x01, 0x00);
@@ -269,18 +276,45 @@ static void cx23885_initialize(struct i2
 	/* DIF in reset? */
 	cx25840_write(client, 0x398, 0);
 
-	/* Trust the default xtal, no division */
-	/* This changes for the cx23888 products */
+	/*
+	 * Trust the default xtal, no division
+	 * '885: 28.636363... MHz
+	 * '887: 25.000000 MHz
+	 * '888: 50.000000 MHz
+	 */
 	cx25840_write(client, 0x2, 0x76);
 
-	/* Bring down the regulator for AUX clk */
+	/* Power up all the PLL's and DLL */
 	cx25840_write(client, 0x1, 0x40);
 
-	/* Sys PLL frac */
-	cx25840_write4(client, 0x11c, 0x01d1744c);
-
-	/* Sys PLL int */
-	cx25840_write4(client, 0x118, 0x00000416);
+	/* Sys PLL */
+	switch (state->id) {
+	case V4L2_IDENT_CX23888_AV:
+		/*
+		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x00e8ba26);
+		cx25840_write4(client, 0x118, 0x0000040b);
+		break;
+	case V4L2_IDENT_CX23887_AV:
+		/*
+		 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x01d1744c);
+		cx25840_write4(client, 0x118, 0x00000416);
+		break;
+	case V4L2_IDENT_CX23885_AV:
+	default:
+		/*
+		 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
+		 * 572.73 MHz before post divide
+		 */
+		cx25840_write4(client, 0x11c, 0x00000000);
+		cx25840_write4(client, 0x118, 0x00000414);
+		break;
+	}
 
 	/* Disable DIF bypass */
 	cx25840_write4(client, 0x33c, 0x00000001);
@@ -288,11 +322,15 @@ static void cx23885_initialize(struct i2
 	/* DIF Src phase inc */
 	cx25840_write4(client, 0x340, 0x0df7df83);
 
-	/* Vid PLL frac */
-	cx25840_write4(client, 0x10c, 0x01b6db7b);
-
-	/* Vid PLL int */
-	cx25840_write4(client, 0x108, 0x00000512);
+	/*
+	 * Vid PLL
+	 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
+	 *
+	 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
+	 * 432.0 MHz before post divide
+	 */
+	cx25840_write4(client, 0x10c, 0x002be2c9);
+	cx25840_write4(client, 0x108, 0x0000040f);
 
 	/* Luma */
 	cx25840_write4(client, 0x414, 0x00107d12);
@@ -300,11 +338,43 @@ static void cx23885_initialize(struct i2
 	/* Chroma */
 	cx25840_write4(client, 0x420, 0x3d008282);
 
-	/* Aux PLL frac */
-	cx25840_write4(client, 0x114, 0x017dbf48);
-
-	/* Aux PLL int */
-	cx25840_write4(client, 0x110, 0x000a030e);
+	/*
+	 * Aux PLL
+	 * Initial setup for audio sample clock:
+	 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
+	 * Intial I2S output/master clock(?):
+	 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
+	 */
+	switch (state->id) {
+	case V4L2_IDENT_CX23888_AV:
+		/*
+		 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x00bedfa4);
+		cx25840_write4(client, 0x110, 0x000a0307);
+		break;
+	case V4L2_IDENT_CX23887_AV:
+		/*
+		 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x017dbf48);
+		cx25840_write4(client, 0x110, 0x000a030e);
+		break;
+	case V4L2_IDENT_CX23885_AV:
+	default:
+		/*
+		 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
+		 * 368.64 MHz before post divide
+		 * 122.88 MHz / 0xa = 12.288 MHz
+		 */
+		cx25840_write4(client, 0x114, 0x01bf0c9e);
+		cx25840_write4(client, 0x110, 0x000a030c);
+		break;
+	};
 
 	/* ADC2 input select */
 	cx25840_write(client, 0x102, 0x10);
@@ -494,7 +564,7 @@ void cx25840_std_setup(struct i2c_client
 	}
 
 	/* DEBUG: Displays configured PLL frequency */
-	if (!state->is_cx231xx) {
+	if (!is_cx231xx(state)) {
 		pll_int = cx25840_read(client, 0x108);
 		pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
 		pll_post = cx25840_read(client, 0x109);
@@ -615,13 +685,30 @@ static void input_change(struct i2c_clie
 		}
 		cx25840_write(client, 0x80b, 0x00);
 	} else if (std & V4L2_STD_PAL) {
-		/* Follow tuner change procedure for PAL */
+		/* Autodetect audio standard and audio system */
 		cx25840_write(client, 0x808, 0xff);
-		cx25840_write(client, 0x80b, 0x10);
+		/* Since system PAL-L is pretty much non-existant and
+		   not used by any public broadcast network, force
+		   6.5 MHz carrier to be interpreted as System DK,
+		   this avoids DK audio detection instability */
+	       cx25840_write(client, 0x80b, 0x00);
 	} else if (std & V4L2_STD_SECAM) {
-		/* Select autodetect for SECAM */
+		/* Autodetect audio standard and audio system */
 		cx25840_write(client, 0x808, 0xff);
-		cx25840_write(client, 0x80b, 0x10);
+		/* If only one of SECAM-DK / SECAM-L is required, then force
+		  6.5MHz carrier, else autodetect it */
+		if ((std & V4L2_STD_SECAM_DK) &&
+		    !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
+			/* 6.5 MHz carrier to be interpreted as System DK */
+			cx25840_write(client, 0x80b, 0x00);
+	       } else if (!(std & V4L2_STD_SECAM_DK) &&
+			  (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
+			/* 6.5 MHz carrier to be interpreted as System L */
+			cx25840_write(client, 0x80b, 0x08);
+	       } else {
+			/* 6.5 MHz carrier to be autodetected */
+			cx25840_write(client, 0x80b, 0x10);
+	       }
 	}
 
 	cx25840_and_or(client, 0x810, ~0x01, 0);
@@ -633,6 +720,10 @@ static int set_input(struct i2c_client *
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
 	u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
 			   vid_input <= CX25840_COMPOSITE8);
+	u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
+			CX25840_COMPONENT_ON;
+	int luma = vid_input & 0xf0;
+	int chroma = vid_input & 0xf00;
 	u8 reg;
 
 	v4l_dbg(1, cx25840_debug, client,
@@ -645,18 +736,14 @@ static int set_input(struct i2c_client *
 		reg = vid_input & 0xff;
 		if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON)
 			is_composite = 0;
-		else
+		else if ((vid_input & CX25840_COMPONENT_ON) == 0)
 			is_composite = 1;
 
 		v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
 			reg, is_composite);
-	} else
-	if (is_composite) {
+	} else if (is_composite) {
 		reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
 	} else {
-		int luma = vid_input & 0xf0;
-		int chroma = vid_input & 0xf00;
-
 		if ((vid_input & ~0xff0) ||
 		    luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
 		    chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
@@ -678,7 +765,7 @@ static int set_input(struct i2c_client *
 	 * configuration in reg (for the cx23885) so we have no
 	 * need to attempt to flip bits for earlier av decoders.
 	 */
-	if (!state->is_cx23885 && !state->is_cx231xx) {
+	if (!is_cx2388x(state) && !is_cx231xx(state)) {
 		switch (aud_input) {
 		case CX25840_AUDIO_SERIAL:
 			/* do nothing, use serial audio input */
@@ -698,10 +785,13 @@ static int set_input(struct i2c_client *
 
 	cx25840_write(client, 0x103, reg);
 
-	/* Set INPUT_MODE to Composite (0) or S-Video (1) */
-	cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
+	/* Set INPUT_MODE to Composite, S-Video or Component */
+	if (is_component)
+		cx25840_and_or(client, 0x401, ~0x6, 0x6);
+	else
+		cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
 
-	if (!state->is_cx23885 && !state->is_cx231xx) {
+	if (!is_cx2388x(state) && !is_cx231xx(state)) {
 		/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
 		cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
 		/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -710,22 +800,31 @@ static int set_input(struct i2c_client *
 		else
 			cx25840_and_or(client, 0x102, ~0x4, 0);
 	} else {
-		if (is_composite)
+		/* Set DUAL_MODE_ADC2 to 1 if component*/
+		cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
+		if (is_composite) {
 			/* ADC2 input select channel 2 */
 			cx25840_and_or(client, 0x102, ~0x2, 0);
-		else
-			/* ADC2 input select channel 3 */
-			cx25840_and_or(client, 0x102, ~0x2, 2);
+		} else if (!is_component) {
+			/* S-Video */
+			if (chroma >= CX25840_SVIDEO_CHROMA7) {
+				/* ADC2 input select channel 3 */
+				cx25840_and_or(client, 0x102, ~0x2, 2);
+			} else {
+				/* ADC2 input select channel 2 */
+				cx25840_and_or(client, 0x102, ~0x2, 0);
+			}
+		}
 	}
 
 	state->vid_input = vid_input;
 	state->aud_input = aud_input;
-	if (!state->is_cx25836) {
+	if (!is_cx2583x(state)) {
 		cx25840_audio_set_path(client);
 		input_change(client);
 	}
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Audio channel 1 src : Parallel 1 */
 		cx25840_write(client, 0x124, 0x03);
 
@@ -741,7 +840,7 @@ static int set_input(struct i2c_client *
 		 */
 		cx25840_write(client, 0x918, 0xa0);
 		cx25840_write(client, 0x919, 0x01);
-	} else if (state->is_cx231xx) {
+	} else if (is_cx231xx(state)) {
 		/* Audio channel 1 src : Parallel 1 */
 		cx25840_write(client, 0x124, 0x03);
 
@@ -805,7 +904,7 @@ static int set_v4lstd(struct i2c_client
 	cx25840_and_or(client, 0x400, ~0xf, fmt);
 	cx25840_and_or(client, 0x403, ~0x3, pal_m);
 	cx25840_std_setup(client);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		input_change(client);
 	return 0;
 }
@@ -868,7 +967,7 @@ static int cx25840_s_ctrl(struct v4l2_su
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			return -EINVAL;
 		return cx25840_audio_s_ctrl(sd, ctrl);
 
@@ -905,7 +1004,7 @@ static int cx25840_g_ctrl(struct v4l2_su
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			return -EINVAL;
 		return cx25840_audio_g_ctrl(sd, ctrl);
 	default:
@@ -1209,11 +1308,11 @@ static int cx25840_load_fw(struct v4l2_s
 	if (!state->is_initialized) {
 		/* initialize and load firmware */
 		state->is_initialized = 1;
-		if (state->is_cx25836)
+		if (is_cx2583x(state))
 			cx25836_initialize(client);
-		else if (state->is_cx23885)
+		else if (is_cx2388x(state))
 			cx23885_initialize(client);
-		else if (state->is_cx231xx)
+		else if (is_cx231xx(state))
 			cx231xx_initialize(client);
 		else
 			cx25840_initialize(client);
@@ -1256,17 +1355,17 @@ static int cx25840_s_stream(struct v4l2_
 	v4l_dbg(1, cx25840_debug, client, "%s output\n",
 			enable ? "enable" : "disable");
 	if (enable) {
-		if (state->is_cx23885 || state->is_cx231xx) {
+		if (is_cx2388x(state) || is_cx231xx(state)) {
 			u8 v = (cx25840_read(client, 0x421) | 0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
 			cx25840_write(client, 0x115,
-					state->is_cx25836 ? 0x0c : 0x8c);
+					is_cx2583x(state) ? 0x0c : 0x8c);
 			cx25840_write(client, 0x116,
-					state->is_cx25836 ? 0x04 : 0x07);
+					is_cx2583x(state) ? 0x04 : 0x07);
 		}
 	} else {
-		if (state->is_cx23885 || state->is_cx231xx) {
+		if (is_cx2388x(state) || is_cx231xx(state)) {
 			u8 v = cx25840_read(client, 0x421) & ~(0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
@@ -1292,7 +1391,7 @@ static int cx25840_queryctrl(struct v4l2
 	default:
 		break;
 	}
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return -EINVAL;
 
 	switch (qc->id) {
@@ -1346,7 +1445,7 @@ static int cx25840_s_audio_routing(struc
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return -EINVAL;
 	return set_input(client, state->vid_input, input);
 }
@@ -1356,7 +1455,7 @@ static int cx25840_s_frequency(struct v4
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		input_change(client);
 	return 0;
 }
@@ -1373,7 +1472,7 @@ static int cx25840_g_tuner(struct v4l2_s
 		return 0;
 
 	vt->signal = vpres ? 0xffff : 0x0;
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		return 0;
 
 	vt->capability |=
@@ -1404,7 +1503,7 @@ static int cx25840_s_tuner(struct v4l2_s
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->radio || state->is_cx25836)
+	if (state->radio || is_cx2583x(state))
 		return 0;
 
 	switch (vt->audmode) {
@@ -1445,11 +1544,11 @@ static int cx25840_reset(struct v4l2_sub
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->is_cx25836)
+	if (is_cx2583x(state))
 		cx25836_initialize(client);
-	else if (state->is_cx23885)
+	else if (is_cx2388x(state))
 		cx23885_initialize(client);
-	else if (state->is_cx231xx)
+	else if (is_cx231xx(state))
 		cx231xx_initialize(client);
 	else
 		cx25840_initialize(client);
@@ -1470,7 +1569,7 @@ static int cx25840_log_status(struct v4l
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	log_video_status(client);
-	if (!state->is_cx25836)
+	if (!is_cx2583x(state))
 		log_audio_status(client);
 	return 0;
 }
@@ -1521,12 +1620,50 @@ static const struct v4l2_subdev_ops cx25
 
 /* ----------------------------------------------------------------------- */
 
+static u32 get_cx2388x_ident(struct i2c_client *client)
+{
+	u32 ret;
+
+	/* Come out of digital power down */
+	cx25840_write(client, 0x000, 0);
+
+	/* Detecting whether the part is cx23885/7/8 is more
+	 * difficult than it needs to be. No ID register. Instead we
+	 * probe certain registers indicated in the datasheets to look
+	 * for specific defaults that differ between the silicon designs. */
+
+	/* It's either 885/7 if the IR Tx Clk Divider register exists */
+	if (cx25840_read4(client, 0x204) & 0xffff) {
+		/* CX23885 returns bogus repetitive byte values for the DIF,
+		 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
+		ret = cx25840_read4(client, 0x300);
+		if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
+			/* No DIF */
+			ret = V4L2_IDENT_CX23885_AV;
+		} else {
+			/* CX23887 has a broken DIF, but the registers
+			 * appear valid (but unsed), good enough to detect. */
+			ret = V4L2_IDENT_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;
+	} else {
+		v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
+		ret = V4L2_IDENT_CX23887_AV;
+	}
+
+	/* Back into digital power down */
+	cx25840_write(client, 0x000, 2);
+	return ret;
+}
+
 static int cx25840_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct cx25840_state *state;
 	struct v4l2_subdev *sd;
-	u32 id;
+	u32 id = V4L2_IDENT_NONE;
 	u16 device_id;
 
 	/* Check if the adapter supports the needed features */
@@ -1543,17 +1680,22 @@ static int cx25840_probe(struct i2c_clie
 	 * 0x83 for the cx2583x and 0x84 for the cx2584x */
 	if ((device_id & 0xff00) == 0x8300) {
 		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
-	}
-	else if ((device_id & 0xff00) == 0x8400) {
+	} else if ((device_id & 0xff00) == 0x8400) {
 		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
 	} else if (device_id == 0x0000) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
-	} else if (device_id == 0x1313) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+		id = get_cx2388x_ident(client);
 	} else if ((device_id & 0xfff0) == 0x5A30) {
-		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
-	}
-	else {
+		/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
+		id = V4L2_IDENT_CX2310X_AV;
+	} else if ((device_id & 0xff) == (device_id >> 8)) {
+		v4l_err(client,
+			"likely a confused/unresponsive cx2388[578] A/V decoder"
+			" found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+		v4l_err(client, "A method to reset it from the cx25840 driver"
+			" software is not known at this time\n");
+		return -ENODEV;
+	} else {
 		v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
 		return -ENODEV;
 	}
@@ -1564,17 +1706,45 @@ static int cx25840_probe(struct i2c_clie
 
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
-	/* 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",
-		    (device_id & 0xfff0) >> 4,
-		    (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
-		    client->addr << 1, client->adapter->name);
+	switch (id) {
+	case V4L2_IDENT_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:
+		v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_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:
+		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:
+		/* 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",
+			 (device_id & 0xfff0) >> 4,
+			 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
+						: (device_id & 0x0f),
+			 client->addr << 1, client->adapter->name);
+		break;
+	case V4L2_IDENT_CX25836:
+	case V4L2_IDENT_CX25837:
+	default:
+		v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
+			 (device_id & 0xfff0) >> 4, device_id & 0x0f,
+			 client->addr << 1, client->adapter->name);
+		break;
+	}
 
 	state->c = client;
-	state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
-	state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
-	state->is_cx231xx = (device_id == 0x5a3e);
 	state->vid_input = CX25840_COMPOSITE7;
 	state->aud_input = CX25840_AUDIO8;
 	state->audclk_freq = 48000;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-core.h linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-core.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
 #include <linux/i2c.h>
 
 /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -48,9 +49,6 @@ struct cx25840_state {
 	int vbi_line_offset;
 	u32 id;
 	u32 rev;
-	int is_cx25836;
-	int is_cx23885;
-	int is_cx231xx;
 	int is_initialized;
 	wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
 	struct work_struct fw_work;   /* work entry for fw load */
@@ -61,6 +59,24 @@ static inline struct cx25840_state *to_s
 	return container_of(sd, struct cx25840_state, sd);
 }
 
+static inline bool is_cx2583x(struct cx25840_state *state)
+{
+	return state->id == V4L2_IDENT_CX25836 ||
+	       state->id == V4L2_IDENT_CX25837;
+}
+
+static inline bool is_cx231xx(struct cx25840_state *state)
+{
+	return state->id == V4L2_IDENT_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;
+}
+
 /* ----------------------------------------------------------------------- */
 /* cx25850-core.c 							   */
 int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-firmware.c linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-firmware.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx25840/cx25840-firmware.c	2013-05-03 13:58:33.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx25840/cx25840-firmware.c	2013-05-03 12:07:04.000000000 -0400
@@ -67,9 +67,9 @@ static const char *get_fw_name(struct i2
 
 	if (firmware[0])
 		return firmware;
-	if (state->is_cx23885)
+	if (is_cx2388x(state))
 		return "/*(DEBLOBBED)*/";
-	if (state->is_cx231xx)
+	if (is_cx231xx(state))
 		return "/*(DEBLOBBED)*/";
 	return "/*(DEBLOBBED)*/";
 }
@@ -112,13 +112,13 @@ int cx25840_loadfw(struct i2c_client *cl
 	int MAX_BUF_SIZE = FWSEND;
 	u32 gpio_oe = 0, gpio_da = 0;
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Preserve the GPIO OE and output bits */
 		gpio_oe = cx25840_read(client, 0x160);
 		gpio_da = cx25840_read(client, 0x164);
 	}
 
-	if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
+	if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
 		v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
 		MAX_BUF_SIZE = 16;  /* cx231xx cannot accept more than 16 bytes at a time */
 	}
@@ -156,7 +156,7 @@ int cx25840_loadfw(struct i2c_client *cl
 	size = fw->size;
 	release_firmware(fw);
 
-	if (state->is_cx23885) {
+	if (is_cx2388x(state)) {
 		/* Restore GPIO configuration after f/w load */
 		cx25840_write(client, 0x160, gpio_oe);
 		cx25840_write(client, 0x164, gpio_da);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-blackbird.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-blackbird.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 13:58:33.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 12:07:05.000000000 -0400
@@ -1048,21 +1048,15 @@ static int vidioc_s_std (struct file *fi
 
 static int mpeg_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct cx8802_dev *dev = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct cx8802_dev *dev = video_drvdata(file);
 	struct cx8802_fh *fh;
 	struct cx8802_driver *drv = NULL;
 	int err;
 
-	lock_kernel();
-	dev = cx8802_get_device(minor);
-
 	dprintk( 1, "%s\n", __func__);
 
-	if (dev == NULL) {
-		unlock_kernel();
-		return -ENODEV;
-	}
+	lock_kernel();
 
 	/* Make sure we can acquire the hardware */
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
@@ -1081,7 +1075,7 @@ static int mpeg_open(struct file *file)
 		unlock_kernel();
 		return -EINVAL;
 	}
-	dprintk(1,"open minor=%d\n",minor);
+	dprintk(1, "open dev=%s\n", video_device_node_name(vdev));
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1129,10 +1123,6 @@ static int mpeg_release(struct file *fil
 	kfree(fh);
 
 	/* Make sure we release the hardware */
-	dev = cx8802_get_device(video_devdata(file)->minor);
-	if (dev == NULL)
-		return -ENODEV;
-
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
 	if (drv)
 		drv->request_release(drv);
@@ -1220,7 +1210,6 @@ static struct video_device cx8802_mpeg_t
 	.name                 = "cx8802",
 	.fops                 = &mpeg_fops,
 	.ioctl_ops 	      = &mpeg_ioctl_ops,
-	.minor                = -1,
 	.tvnorms              = CX88_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
@@ -1276,7 +1265,7 @@ static int cx8802_blackbird_advise_relea
 static void blackbird_unregister_video(struct cx8802_dev *dev)
 {
 	if (dev->mpeg_dev) {
-		if (-1 != dev->mpeg_dev->minor)
+		if (video_is_registered(dev->mpeg_dev))
 			video_unregister_device(dev->mpeg_dev);
 		else
 			video_device_release(dev->mpeg_dev);
@@ -1290,14 +1279,15 @@ static int blackbird_register_video(stru
 
 	dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
 				       &cx8802_mpeg_template,"mpeg");
+	video_set_drvdata(dev->mpeg_dev, dev);
 	err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
 	if (err < 0) {
 		printk(KERN_INFO "%s/2: can't register mpeg device\n",
 		       dev->core->name);
 		return err;
 	}
-	printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n",
-	       dev->core->name, dev->mpeg_dev->num);
+	printk(KERN_INFO "%s/2: registered device %s [mpeg]\n",
+	       dev->core->name, video_device_node_name(dev->mpeg_dev));
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 12:03:50.000000000 -0400
@@ -2075,6 +2075,18 @@ static const struct cx88_board cx88_boar
 		},
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	[CX88_BOARD_PROF_7301] = {
+		.name           = "Prof 7301 DVB-S/S2",
+		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.input          = { {
+			.type   = CX88_VMUX_DVB,
+			.vmux   = 0,
+		} },
+		.mpeg           = CX88_MPEG_DVB,
+	},
 };
 
 /* ------------------------------------------------------------------ */
@@ -2535,6 +2547,10 @@ static const struct cx88_subid cx88_subi
 		.subvendor = 0x107d,
 		.subdevice = 0x6618,
 		.card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
+	}, {
+		.subvendor = 0xb034,
+		.subdevice = 0x3034,
+		.card      = CX88_BOARD_PROF_7301,
 	},
 };
 
@@ -3211,6 +3227,7 @@ static void cx88_card_setup(struct cx88_
 	case  CX88_BOARD_TBS_8920:
 	case  CX88_BOARD_PROF_6200:
 	case  CX88_BOARD_PROF_7300:
+	case  CX88_BOARD_PROF_7301:
 	case  CX88_BOARD_SATTRADE_ST4200:
 		cx_write(MO_GP0_IO, 0x8000);
 		msleep(100);
@@ -3267,7 +3284,7 @@ static void cx88_card_setup(struct cx88_
 			    ctl.fname);
 		call_all(core, tuner, s_config, &xc2028_cfg);
 	}
-	call_all(core, tuner, s_standby);
+	call_all(core, core, s_power, 0);
 }
 
 /* ------------------------------------------------------------------ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-core.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -624,7 +624,7 @@ int cx88_reset(struct cx88_core *core)
 	/* setup image format */
 	cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
 
-	/* setup FIFO Threshholds */
+	/* setup FIFO Thresholds */
 	cx_write(MO_PDMA_STHRSH,   0x0807);
 	cx_write(MO_PDMA_DTHRSH,   0x0807);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 12:03:50.000000000 -0400
@@ -53,6 +53,9 @@
 #include "stv0288.h"
 #include "stb6000.h"
 #include "cx24116.h"
+#include "stv0900.h"
+#include "stb6100.h"
+#include "stb6100_proc.h"
 
 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -573,6 +576,15 @@ static int cx24116_set_ts_param(struct d
 	return 0;
 }
 
+static int stv0900_set_ts_param(struct dvb_frontend *fe,
+	int is_punctured)
+{
+	struct cx8802_dev *dev = fe->dvb->priv;
+	dev->ts_gen_cntrl = 0;
+
+	return 0;
+}
+
 static int cx24116_reset_device(struct dvb_frontend *fe)
 {
 	struct cx8802_dev *dev = fe->dvb->priv;
@@ -601,6 +613,23 @@ static struct cx24116_config tevii_s460_
 	.reset_device  = cx24116_reset_device,
 };
 
+static struct stv0900_config prof_7301_stv0900_config = {
+	.demod_address = 0x6a,
+/*	demod_mode = 0,*/
+	.xtal = 27000000,
+	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+	.diseqc_mode = 2,/* 2/3 PWM */
+	.tun1_maddress = 0,/* 0x60 */
+	.tun1_adc = 0,/* 2 Vpp */
+	.path1_mode = 3,
+	.set_ts_params = stv0900_set_ts_param,
+};
+
+static struct stb6100_config prof_7301_stb6100_config = {
+	.tuner_address = 0x60,
+	.refclock = 27000000,
+};
+
 static struct stv0299_config tevii_tuner_sharp_config = {
 	.demod_address = 0x68,
 	.inittab = sharp_z0194a_inittab,
@@ -1149,6 +1178,31 @@ static int dvb_register(struct cx8802_de
 				goto frontend_detach;
 		}
 		break;
+	case CX88_BOARD_PROF_7301:{
+		struct dvb_tuner_ops *tuner_ops = NULL;
+
+		fe0->dvb.frontend = dvb_attach(stv0900_attach,
+						&prof_7301_stv0900_config,
+						&core->i2c_adap, 0);
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
+					&prof_7301_stb6100_config,
+					&core->i2c_adap))
+				goto frontend_detach;
+
+			tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
+			tuner_ops->set_frequency = stb6100_set_freq;
+			tuner_ops->get_frequency = stb6100_get_freq;
+			tuner_ops->set_bandwidth = stb6100_set_bandw;
+			tuner_ops->get_bandwidth = stb6100_get_bandw;
+
+			core->prev_set_voltage =
+					fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage =
+					tevii_dvbs_set_voltage;
+		}
+		break;
+		}
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       core->name);
@@ -1170,11 +1224,11 @@ static int dvb_register(struct cx8802_de
 		fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	call_all(core, tuner, s_standby);
+	call_all(core, core, s_power, 0);
 
 	/* register everything */
 	return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
-		&dev->pci->dev, adapter_nr, mfe_shared);
+					 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
 
 frontend_detach:
 	core->gate_ctrl = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88.h linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88.h	2010-02-24 13:52:17.000000000 -0500
@@ -238,6 +238,7 @@ extern struct sram_channel cx88_sram_cha
 #define CX88_BOARD_HAUPPAUGE_IRONLY        80
 #define CX88_BOARD_WINFAST_DTV1800H        81
 #define CX88_BOARD_WINFAST_DTV2000H_J      82
+#define CX88_BOARD_PROF_7301               83
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
@@ -422,7 +423,6 @@ struct cx8800_suspend_state {
 
 struct cx8800_dev {
 	struct cx88_core           *core;
-	struct list_head           devlist;
 	spinlock_t                 slock;
 
 	/* various device info */
@@ -669,7 +669,6 @@ int cx88_audio_thread(void *data);
 
 int cx8802_register_driver(struct cx8802_driver *drv);
 int cx8802_unregister_driver(struct cx8802_driver *drv);
-struct cx8802_dev *cx8802_get_device(int minor);
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
 
 /* ----------------------------------------------------------- */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-input.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,13 +118,13 @@ static void cx88_ir_handle_key(struct cx
 
 		data = (data << 4) | ((gpio_key & 0xf0) >> 4);
 
-		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_keydown(ir->input, &ir->ir, data);
 		ir_input_nokey(ir->input, &ir->ir);
 
 	} else if (ir->mask_keydown) {
 		/* bit set on keydown */
 		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->input, &ir->ir);
 		}
@@ -132,14 +132,14 @@ static void cx88_ir_handle_key(struct cx
 	} else if (ir->mask_keyup) {
 		/* bit cleared on keydown */
 		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else {
 		/* can't distinguish keydown/up :-/ */
-		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_keydown(ir->input, &ir->ir, data);
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 }
@@ -303,6 +303,23 @@ int cx88_ir_init(struct cx88_core *core,
 		ir->mask_keydown = 0x02;
 		ir->polling      = 50; /* ms */
 		break;
+	case CX88_BOARD_OMICOM_SS4_PCI:
+	case CX88_BOARD_SATTRADE_ST4200:
+	case CX88_BOARD_TBS_8920:
+	case CX88_BOARD_TBS_8910:
+	case CX88_BOARD_PROF_7300:
+	case CX88_BOARD_PROF_7301:
+	case CX88_BOARD_PROF_6200:
+		ir_codes = &ir_codes_tbs_nec_table;
+		ir_type = IR_TYPE_PD;
+		ir->sampling = 0xff00; /* address */
+		break;
+	case CX88_BOARD_TEVII_S460:
+	case CX88_BOARD_TEVII_S420:
+		ir_codes = &ir_codes_tevii_nec_table;
+		ir_type = IR_TYPE_PD;
+		ir->sampling = 0xff00; /* address */
+		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 		ir_codes         = &ir_codes_dntv_live_dvbt_pro_table;
 		ir_type          = IR_TYPE_PD;
@@ -343,7 +360,10 @@ int cx88_ir_init(struct cx88_core *core,
 	snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -363,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core,
 	cx88_ir_start(core, ir);
 
 	/* all done */
-	err = input_register_device(ir->input);
+	err = ir_input_register(ir->input, ir_codes);
 	if (err)
 		goto err_out_stop;
 
@@ -373,7 +393,6 @@ int cx88_ir_init(struct cx88_core *core,
 	cx88_ir_stop(core, ir);
 	core->ir = NULL;
  err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -387,7 +406,7 @@ int cx88_ir_fini(struct cx88_core *core)
 		return 0;
 
 	cx88_ir_stop(core, ir);
-	input_unregister_device(ir->input);
+	ir_input_unregister(ir->input);
 	kfree(ir);
 
 	/* done */
@@ -432,8 +451,17 @@ void cx88_ir_irq(struct cx88_core *core)
 
 	/* decode it */
 	switch (core->boardnr) {
+	case CX88_BOARD_TEVII_S460:
+	case CX88_BOARD_TEVII_S420:
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+	case CX88_BOARD_OMICOM_SS4_PCI:
+	case CX88_BOARD_SATTRADE_ST4200:
+	case CX88_BOARD_TBS_8920:
+	case CX88_BOARD_TBS_8910:
+	case CX88_BOARD_PROF_7300:
+	case CX88_BOARD_PROF_7301:
+	case CX88_BOARD_PROF_6200:
 		ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
 
 		if (ircode == 0xffffffff) { /* decoding error */
@@ -461,7 +489,7 @@ void cx88_ir_irq(struct cx88_core *core)
 
 		ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
 
-		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	case CX88_BOARD_HAUPPAUGE:
@@ -498,7 +526,7 @@ void cx88_ir_irq(struct cx88_core *core)
 		if ( dev != 0x1e && dev != 0x1f )
 			/* not a hauppauge remote */
 			break;
-		ir_input_keydown(ir->input, &ir->ir, code, ircode);
+		ir_input_keydown(ir->input, &ir->ir, code);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
@@ -506,7 +534,7 @@ void cx88_ir_irq(struct cx88_core *core)
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		if ((ircode & 0xfffff000) != 0x3000)
 			break;
-		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
+		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-mpeg.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-mpeg.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2010-02-24 13:52:17.000000000 -0500
@@ -580,21 +580,6 @@ static int cx8802_resume_common(struct p
 	return 0;
 }
 
-#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
-    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
-struct cx8802_dev *cx8802_get_device(int minor)
-{
-	struct cx8802_dev *dev;
-
-	list_for_each_entry(dev, &cx8802_devlist, devlist)
-		if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
-			return dev;
-
-	return NULL;
-}
-EXPORT_SYMBOL(cx8802_get_device);
-#endif
-
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
 {
 	struct cx8802_driver *d;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-video.c linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/cx88-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/cx88-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,10 +75,6 @@ MODULE_PARM_DESC(vid_limit,"capture memo
 #define dprintk(level,fmt, arg...)	if (video_debug >= level) \
 	printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
 
-/* ------------------------------------------------------------------ */
-
-static LIST_HEAD(cx8800_devlist);
-
 /* ------------------------------------------------------------------- */
 /* static data                                                         */
 
@@ -753,38 +749,31 @@ static int get_ressource(struct cx8800_f
 
 static int video_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct cx8800_dev *h,*dev = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct cx8800_dev *dev = video_drvdata(file);
 	struct cx88_core *core;
 	struct cx8800_fh *fh;
 	enum v4l2_buf_type type = 0;
 	int radio = 0;
 
-	lock_kernel();
-	list_for_each_entry(h, &cx8800_devlist, devlist) {
-		if (h->video_dev->minor == minor) {
-			dev  = h;
-			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		}
-		if (h->vbi_dev->minor == minor) {
-			dev  = h;
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		}
-		if (h->radio_dev &&
-		    h->radio_dev->minor == minor) {
-			radio = 1;
-			dev   = h;
-		}
-	}
-	if (NULL == dev) {
-		unlock_kernel();
-		return -ENODEV;
+	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;
 	}
 
+	lock_kernel();
+
 	core = dev->core;
 
-	dprintk(1,"open minor=%d radio=%d type=%s\n",
-		minor,radio,v4l2_type_names[type]);
+	dprintk(1, "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);
@@ -935,7 +924,7 @@ static int video_release(struct file *fi
 
 	mutex_lock(&dev->core->lock);
 	if(atomic_dec_and_test(&dev->core->users))
-		call_all(dev->core, tuner, s_standby);
+		call_all(dev->core, core, s_power, 0);
 	mutex_unlock(&dev->core->lock);
 
 	return 0;
@@ -1733,7 +1722,6 @@ static struct video_device cx8800_vbi_te
 static struct video_device cx8800_video_template = {
 	.name                 = "cx8800-video",
 	.fops                 = &video_fops,
-	.minor                = -1,
 	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX88_NORMS,
 	.current_norm         = V4L2_STD_NTSC_M,
@@ -1769,7 +1757,6 @@ static const struct v4l2_ioctl_ops radio
 static struct video_device cx8800_radio_template = {
 	.name                 = "cx8800-radio",
 	.fops                 = &radio_fops,
-	.minor                = -1,
 	.ioctl_ops 	      = &radio_ioctl_ops,
 };
 
@@ -1778,21 +1765,21 @@ static struct video_device cx8800_radio_
 static void cx8800_unregister_video(struct cx8800_dev *dev)
 {
 	if (dev->radio_dev) {
-		if (-1 != dev->radio_dev->minor)
+		if (video_is_registered(dev->radio_dev))
 			video_unregister_device(dev->radio_dev);
 		else
 			video_device_release(dev->radio_dev);
 		dev->radio_dev = NULL;
 	}
 	if (dev->vbi_dev) {
-		if (-1 != dev->vbi_dev->minor)
+		if (video_is_registered(dev->vbi_dev))
 			video_unregister_device(dev->vbi_dev);
 		else
 			video_device_release(dev->vbi_dev);
 		dev->vbi_dev = NULL;
 	}
 	if (dev->video_dev) {
-		if (-1 != dev->video_dev->minor)
+		if (video_is_registered(dev->video_dev))
 			video_unregister_device(dev->video_dev);
 		else
 			video_device_release(dev->video_dev);
@@ -1909,6 +1896,7 @@ static int __devinit cx8800_initdev(stru
 	/* register v4l devices */
 	dev->video_dev = cx88_vdev_init(core,dev->pci,
 					&cx8800_video_template,"video");
+	video_set_drvdata(dev->video_dev, dev);
 	err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
 				    video_nr[core->nr]);
 	if (err < 0) {
@@ -1916,10 +1904,11 @@ static int __devinit cx8800_initdev(stru
 		       core->name);
 		goto fail_unreg;
 	}
-	printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
-	       core->name, dev->video_dev->num);
+	printk(KERN_INFO "%s/0: registered device %s [v4l2]\n",
+	       core->name, video_device_node_name(dev->video_dev));
 
 	dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
+	video_set_drvdata(dev->vbi_dev, dev);
 	err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
 				    vbi_nr[core->nr]);
 	if (err < 0) {
@@ -1927,12 +1916,13 @@ static int __devinit cx8800_initdev(stru
 		       core->name);
 		goto fail_unreg;
 	}
-	printk(KERN_INFO "%s/0: registered device vbi%d\n",
-	       core->name, dev->vbi_dev->num);
+	printk(KERN_INFO "%s/0: registered device %s\n",
+	       core->name, video_device_node_name(dev->vbi_dev));
 
 	if (core->board.radio.type == CX88_RADIO) {
 		dev->radio_dev = cx88_vdev_init(core,dev->pci,
 						&cx8800_radio_template,"radio");
+		video_set_drvdata(dev->radio_dev, dev);
 		err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
 					    radio_nr[core->nr]);
 		if (err < 0) {
@@ -1940,12 +1930,11 @@ static int __devinit cx8800_initdev(stru
 			       core->name);
 			goto fail_unreg;
 		}
-		printk(KERN_INFO "%s/0: registered device radio%d\n",
-		       core->name, dev->radio_dev->num);
+		printk(KERN_INFO "%s/0: registered device %s\n",
+		       core->name, video_device_node_name(dev->radio_dev));
 	}
 
 	/* everything worked */
-	list_add_tail(&dev->devlist,&cx8800_devlist);
 	pci_set_drvdata(pci_dev,dev);
 
 	/* initial device configuration */
@@ -2001,7 +1990,6 @@ static void __devexit cx8800_finidev(str
 
 	/* free memory */
 	btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
-	list_del(&dev->devlist);
 	cx88_core_put(core,dev->pci);
 	kfree(dev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/cx88/Kconfig linux-libre-2.6.33-gnu1/drivers/media/video/cx88/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/video/cx88/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/cx88/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -61,6 +61,8 @@ config VIDEO_CX88_DVB
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_STV0288 if !DVB_FE_CUSTOMISE
 	select DVB_STB6000 if !DVB_FE_CUSTOMISE
+	select DVB_STV0900 if !DVB_FE_CUSTOMISE
+	select DVB_STB6100 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This adds support for DVB/ATSC cards based on the
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/dm355_ccdc.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm355_ccdc.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/dm355_ccdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm355_ccdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -285,7 +285,7 @@ static int validate_ccdc_param(struct cc
 
 	if ((ccdcparam->med_filt_thres < 0) ||
 	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
-		dev_dbg(dev, "Invalid value of median filter thresold\n");
+		dev_dbg(dev, "Invalid value of median filter threshold\n");
 		return -EINVAL;
 	}
 
@@ -959,7 +959,7 @@ static struct ccdc_hw_device ccdc_hw_dev
 	},
 };
 
-static int dm355_ccdc_init(void)
+static int __init dm355_ccdc_init(void)
 {
 	printk(KERN_NOTICE "dm355_ccdc_init\n");
 	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
@@ -969,7 +969,7 @@ static int dm355_ccdc_init(void)
 	return 0;
 }
 
-static void dm355_ccdc_exit(void)
+static void __exit dm355_ccdc_exit(void)
 {
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/dm644x_ccdc.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm644x_ccdc.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/dm644x_ccdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/dm644x_ccdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -859,7 +859,7 @@ static struct ccdc_hw_device ccdc_hw_dev
 	},
 };
 
-static int dm644x_ccdc_init(void)
+static int __init dm644x_ccdc_init(void)
 {
 	printk(KERN_NOTICE "dm644x_ccdc_init\n");
 	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
@@ -869,7 +869,7 @@ static int dm644x_ccdc_init(void)
 	return 0;
 }
 
-static void dm644x_ccdc_exit(void)
+static void __exit dm644x_ccdc_exit(void)
 {
 	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpfe_capture.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpfe_capture.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpfe_capture.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpfe_capture.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,7 +70,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
 #include <media/v4l2-common.h>
 #include <linux/io.h>
 #include <media/davinci/vpfe_capture.h>
@@ -660,7 +659,7 @@ static void vpfe_detach_irq(struct vpfe_
 
 	frame_format = ccdc_dev->hw_ops.get_frame_format();
 	if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
-		free_irq(IRQ_VDINT1, vpfe_dev);
+		free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
 }
 
 static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
@@ -1338,7 +1337,7 @@ static int vpfe_reqbufs(struct file *fil
 	vpfe_dev->memory = req_buf->memory;
 	videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
 				&vpfe_videobuf_qops,
-				NULL,
+				vpfe_dev->pdev,
 				&vpfe_dev->irqlock,
 				req_buf->type,
 				vpfe_dev->fmt.fmt.pix.field,
@@ -1413,6 +1412,41 @@ static int vpfe_dqbuf(struct file *file,
 				      buf, file->f_flags & O_NONBLOCK);
 }
 
+static int vpfe_queryctrl(struct file *file, void *priv,
+		struct v4l2_queryctrl *qctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, queryctrl, qctrl);
+
+}
+
+static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, g_ctrl, ctrl);
+}
+
+static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+
+	sdinfo = vpfe_dev->current_subdev;
+
+	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, s_ctrl, ctrl);
+}
+
 /*
  * vpfe_calculate_offsets : This function calculates buffers offset
  * for top and bottom field
@@ -1577,7 +1611,7 @@ static int vpfe_cropcap(struct file *fil
 
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
 
-	if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards))
+	if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
 		return -EINVAL;
 
 	memset(crop, 0, sizeof(struct v4l2_cropcap));
@@ -1710,6 +1744,9 @@ static const struct v4l2_ioctl_ops vpfe_
 	.vidioc_querystd	 = vpfe_querystd,
 	.vidioc_s_std		 = vpfe_s_std,
 	.vidioc_g_std		 = vpfe_g_std,
+	.vidioc_queryctrl	 = vpfe_queryctrl,
+	.vidioc_g_ctrl		 = vpfe_g_ctrl,
+	.vidioc_s_ctrl		 = vpfe_s_ctrl,
 	.vidioc_reqbufs		 = vpfe_reqbufs,
 	.vidioc_querybuf	 = vpfe_querybuf,
 	.vidioc_qbuf		 = vpfe_qbuf,
@@ -1929,7 +1966,6 @@ static __init int vpfe_probe(struct plat
 	vfd->release		= video_device_release;
 	vfd->fops		= &vpfe_fops;
 	vfd->ioctl_ops		= &vpfe_ioctl_ops;
-	vfd->minor		= -1;
 	vfd->tvnorms		= 0;
 	vfd->current_norm	= V4L2_STD_PAL;
 	vfd->v4l2_dev 		= &vpfe_dev->v4l2_dev;
@@ -1978,8 +2014,7 @@ static __init int vpfe_probe(struct plat
 	platform_set_drvdata(pdev, vpfe_dev);
 	/* set driver private data */
 	video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
-	i2c_adap = i2c_get_adapter(1);
-	vpfe_cfg = pdev->dev.platform_data;
+	i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
 	num_subdevs = vpfe_cfg->num_subdevs;
 	vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
 				GFP_KERNEL);
@@ -2034,7 +2069,7 @@ probe_out_video_unregister:
 probe_out_v4l2_unregister:
 	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
 probe_out_video_release:
-	if (vpfe_dev->video_dev->minor == -1)
+	if (!video_is_registered(vpfe_dev->video_dev))
 		video_device_release(vpfe_dev->video_dev);
 probe_out_release_irq:
 	free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
@@ -2054,7 +2089,7 @@ probe_free_dev_mem:
 /*
  * vpfe_remove : It un-register device from V4L2 driver
  */
-static int vpfe_remove(struct platform_device *pdev)
+static int __devexit vpfe_remove(struct platform_device *pdev)
 {
 	struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
 	struct resource *res;
@@ -2090,7 +2125,7 @@ vpfe_resume(struct device *dev)
 	return -1;
 }
 
-static struct dev_pm_ops vpfe_dev_pm_ops = {
+static const struct dev_pm_ops vpfe_dev_pm_ops = {
 	.suspend = vpfe_suspend,
 	.resume = vpfe_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif.c	2010-02-24 13:52:17.000000000 -0500
@@ -266,7 +266,7 @@ fail:
 	return status;
 }
 
-static int vpif_remove(struct platform_device *pdev)
+static int __devexit vpif_remove(struct platform_device *pdev)
 {
 	iounmap(vpif_base);
 	release_mem_region(res->start, res_len);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif_capture.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_capture.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif_capture.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_capture.c	2010-02-24 13:52:17.000000000 -0500
@@ -2107,7 +2107,7 @@ vpif_resume(struct device *dev)
 	return -1;
 }
 
-static struct dev_pm_ops vpif_dev_pm_ops = {
+static const struct dev_pm_ops vpif_dev_pm_ops = {
 	.suspend = vpif_suspend,
 	.resume = vpif_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif_display.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_display.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpif_display.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpif_display.c	2010-02-24 13:52:17.000000000 -0500
@@ -1347,7 +1347,6 @@ static const struct v4l2_file_operations
 static struct video_device vpif_video_template = {
 	.name		= "vpif",
 	.fops		= &vpif_fops,
-	.minor		= -1,
 	.ioctl_ops	= &vpif_ioctl_ops,
 	.tvnorms	= DM646X_V4L2_STD,
 	.current_norm	= V4L2_STD_625_50,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpss.c linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpss.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/davinci/vpss.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/davinci/vpss.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,7 @@ struct vpss_hw_ops {
 	int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
 	/* select input to ccdc */
 	void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
-	/* clear wbl overlflow bit */
+	/* clear wbl overflow bit */
 	int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
 };
 
@@ -268,7 +268,7 @@ fail1:
 	return status;
 }
 
-static int vpss_remove(struct platform_device *pdev)
+static int __devexit vpss_remove(struct platform_device *pdev)
 {
 	iounmap(oper_cfg.vpss_bl_regs_base);
 	release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-audio.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-audio.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-audio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-audio.c	2010-02-24 13:52:17.000000000 -0500
@@ -293,7 +293,7 @@ static int snd_em28xx_capture_open(struc
 	dprintk("opening device and trying to acquire exclusive lock\n");
 
 	if (!dev) {
-		printk(KERN_ERR "BUG: em28xx can't find device struct."
+		em28xx_err("BUG: em28xx can't find device struct."
 				" Can't proceed with open\n");
 		return -ENODEV;
 	}
@@ -325,7 +325,7 @@ static int snd_em28xx_capture_open(struc
 
 	return 0;
 err:
-	printk(KERN_ERR "Error while configuring em28xx mixer\n");
+	em28xx_err("Error while configuring em28xx mixer\n");
 	return ret;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 12:03:50.000000000 -0400
@@ -225,6 +225,14 @@ static struct em28xx_reg_seq silvercrest
 	{	-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},
+	{	-1,		-1,	-1,		-1},
+};
+
+
 /*
  *  Board definitions
  */
@@ -829,7 +837,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = &ir_codes_hauppauge_new_table,
+		.ir_codes       = &ir_codes_rc5_hauppauge_new_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -1009,6 +1017,23 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 	},
+	[EM2800_BOARD_VC211A] = {
+		.name         = "Actionmaster/LinXcel/Digitus VC211A",
+		.is_em2800    = 1,
+		.tuner_type   = TUNER_ABSENT,	/* Capture-only board */
+		.decoder      = EM28XX_SAA711X,
+		.input        = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = vc211a_enable,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = vc211a_enable,
+		} },
+	},
 	[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
 		.name         = "Leadtek Winfast USB II",
 		.is_em2800    = 1,
@@ -1381,10 +1406,14 @@ struct em28xx_board em28xx_boards[] = {
 	},
 	[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
 		.name         = "Terratec Hybrid XS (em2882)",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
+		.mts_firmware = 1,
 		.decoder      = EM28XX_TVP5150,
+		.has_dvb      = 1,
+		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
+		.ir_codes     = &ir_codes_terratec_cinergy_xs_table,
+		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1608,6 +1637,8 @@ struct usb_device_id em28xx_id_table[] =
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2861),
 			.driver_info = EM2820_BOARD_UNKNOWN },
+	{ USB_DEVICE(0xeb1a, 0x2862),
+			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2870),
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2881),
@@ -2050,6 +2081,7 @@ static void em28xx_setup_xc3028(struct e
 	switch (dev->model) {
 	case EM2880_BOARD_EMPIRE_DUAL_TV:
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+	case EM2882_BOARD_TERRATEC_HYBRID_XS:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
 	case EM2880_BOARD_TERRATEC_HYBRID_XS:
@@ -2227,6 +2259,7 @@ static int em28xx_hint_board(struct em28
 /* ----------------------------------------------------------------------- */
 void em28xx_register_i2c_ir(struct em28xx *dev)
 {
+	struct i2c_board_info info;
 	const unsigned short addr_list[] = {
 		 0x30, 0x47, I2C_CLIENT_END
 	};
@@ -2234,9 +2267,9 @@ void em28xx_register_i2c_ir(struct em28x
 	if (disable_ir)
 		return;
 
-	memset(&dev->info, 0, sizeof(&dev->info));
+	memset(&info, 0, sizeof(struct i2c_board_info));
 	memset(&dev->init_data, 0, sizeof(dev->init_data));
-	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
 
 	/* detect & configure */
 	switch (dev->model) {
@@ -2252,15 +2285,15 @@ void em28xx_register_i2c_ir(struct em28x
 		dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
 		break;
 	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
-		dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
+		dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table;
 		dev->init_data.get_key = em28xx_get_key_em_haup;
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
 		break;
 	}
 
 	if (dev->init_data.name)
-		dev->info.platform_data = &dev->init_data;
-	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+		info.platform_data = &dev->init_data;
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
 }
 
 void em28xx_card_setup(struct em28xx *dev)
@@ -2524,6 +2557,9 @@ static int em28xx_init_dev(struct em28xx
 		dev->chip_id = retval;
 
 		switch (dev->chip_id) {
+		case CHIP_ID_EM2800:
+			em28xx_info("chip ID is em2800\n");
+			break;
 		case CHIP_ID_EM2710:
 			em28xx_info("chip ID is em2710\n");
 			break;
@@ -2617,7 +2653,6 @@ static int em28xx_init_dev(struct em28xx
 	INIT_LIST_HEAD(&dev->vbiq.active);
 	INIT_LIST_HEAD(&dev->vbiq.queued);
 
-
 	if (dev->board.has_msp34xx) {
 		/* Send a reset to other chips via gpio */
 		errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
@@ -2650,7 +2685,7 @@ static int em28xx_init_dev(struct em28xx
 	em28xx_init_extension(dev);
 
 	/* Save some power by putting tuner to sleep */
-	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 	return 0;
 
@@ -2887,9 +2922,9 @@ static void em28xx_usb_disconnect(struct
 
 	if (dev->users) {
 		em28xx_warn
-		    ("device /dev/video%d is open! Deregistration and memory "
+		    ("device %s is open! Deregistration and memory "
 		     "deallocation are deferred on close.\n",
-				dev->vdev->num);
+		     video_device_node_name(dev->vdev));
 
 		dev->state |= DEV_MISCONFIGURED;
 		em28xx_uninit_isoc(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-core.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug, "enable debu
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __func__ , ##arg); } while (0)
 
-static int alt = EM28XX_PINOUT;
+static int alt;
 module_param(alt, int, 0644);
 MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
 
@@ -216,7 +216,7 @@ int em28xx_write_reg(struct em28xx *dev,
  * sets only some bits (specified by bitmask) of a register, by first reading
  * the actual value
  */
-static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
 				 u8 bitmask)
 {
 	int oldval;
@@ -533,8 +533,15 @@ int em28xx_audio_setup(struct em28xx *de
 
 	vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1);
 	if (vid1 < 0) {
-		/* Device likely doesn't support AC97 */
+		/*
+		 * Device likely doesn't support AC97
+		 * Note: (some) em2800 devices without eeprom reports 0x91 on
+		 *	 CHIPCFG register, even not having an AC97 chip
+		 */
 		em28xx_warn("AC97 chip type couldn't be determined\n");
+		dev->audio_mode.ac97 = EM28XX_NO_AC97;
+		dev->has_alsa_audio = 0;
+		dev->audio_mode.has_audio = 0;
 		goto init_audio;
 	}
 
@@ -778,6 +785,16 @@ int em28xx_set_alternate(struct em28xx *
 	int i;
 	unsigned int min_pkt_size = dev->width * 2 + 4;
 
+	/*
+	 * alt = 0 is used only for control messages, so, only values
+	 * greater than 0 can be used for streaming.
+	 */
+	if (alt && alt < dev->num_alt) {
+		em28xx_coredbg("alternate forced to %d\n", dev->alt);
+		dev->alt = alt;
+		goto set_alt;
+	}
+
 	/* When image size is bigger than a certain value,
 	   the frame size should be increased, otherwise, only
 	   green screen will be received.
@@ -798,6 +815,7 @@ int em28xx_set_alternate(struct em28xx *
 			dev->alt = i;
 	}
 
+set_alt:
 	if (dev->alt != prev_alt) {
 		em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
 				min_pkt_size, dev->alt);
@@ -1118,34 +1136,6 @@ void em28xx_wake_i2c(struct em28xx *dev)
 static LIST_HEAD(em28xx_devlist);
 static DEFINE_MUTEX(em28xx_devlist_mutex);
 
-struct em28xx *em28xx_get_device(int minor,
-				 enum v4l2_buf_type *fh_type,
-				 int *has_radio)
-{
-	struct em28xx *h, *dev = NULL;
-
-	*fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	*has_radio = 0;
-
-	mutex_lock(&em28xx_devlist_mutex);
-	list_for_each_entry(h, &em28xx_devlist, devlist) {
-		if (h->vdev->minor == minor)
-			dev = h;
-		if (h->vbi_dev && h->vbi_dev->minor == minor) {
-			dev = h;
-			*fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		}
-		if (h->radio_dev &&
-		    h->radio_dev->minor == minor) {
-			dev = h;
-			*has_radio = 1;
-		}
-	}
-	mutex_unlock(&em28xx_devlist_mutex);
-
-	return dev;
-}
-
 /*
  * em28xx_realease_resources()
  * unregisters the v4l2,i2c and usb devices
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -313,22 +313,20 @@ static int attach_xc3028(u8 addr, struct
 	cfg.i2c_addr  = addr;
 
 	if (!dev->dvb->frontend) {
-		printk(KERN_ERR "%s/2: dvb frontend not attached. "
-				"Can't attach xc3028\n",
-		       dev->name);
+		em28xx_errdev("/2: dvb frontend not attached. "
+				"Can't attach xc3028\n");
 		return -EINVAL;
 	}
 
 	fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
 	if (!fe) {
-		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
-		       dev->name);
+		em28xx_errdev("/2: xc3028 attach failed\n");
 		dvb_frontend_detach(dev->dvb->frontend);
 		dev->dvb->frontend = NULL;
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name);
+	em28xx_info("%s/2: xc3028 attached\n", dev->name);
 
 	return 0;
 }
@@ -463,7 +461,7 @@ static int dvb_init(struct em28xx *dev)
 	dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
 
 	if (dvb == NULL) {
-		printk(KERN_INFO "em28xx_dvb: memory allocation failed\n");
+		em28xx_info("em28xx_dvb: memory allocation failed\n");
 		return -ENOMEM;
 	}
 	dev->dvb = dvb;
@@ -493,6 +491,7 @@ static int dvb_init(struct em28xx *dev)
 		}
 		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+	case EM2882_BOARD_TERRATEC_HYBRID_XS:
 	case EM2880_BOARD_EMPIRE_DUAL_TV:
 		dvb->frontend = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_xc3028_no_i2c_gate,
@@ -569,15 +568,12 @@ static int dvb_init(struct em28xx *dev)
 		}
 		break;
 	default:
-		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
-				" isn't supported yet\n",
-		       dev->name);
+		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
+				" isn't supported yet\n");
 		break;
 	}
 	if (NULL == dvb->frontend) {
-		printk(KERN_ERR
-		       "%s/2: frontend initialization failed\n",
-		       dev->name);
+		em28xx_errdev("/2: frontend initialization failed\n");
 		result = -EINVAL;
 		goto out_free;
 	}
@@ -591,7 +587,7 @@ static int dvb_init(struct em28xx *dev)
 		goto out_free;
 
 	em28xx_set_mode(dev, EM28XX_SUSPEND);
-	printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
+	em28xx_info("Successfully loaded em28xx-dvb\n");
 	return 0;
 
 out_free:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx.h linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx.h	2010-02-24 13:52:17.000000000 -0500
@@ -110,6 +110,7 @@
 #define EM2820_BOARD_SILVERCREST_WEBCAM           71
 #define EM2861_BOARD_GADMEI_UTV330PLUS           72
 #define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
+#define EM2800_BOARD_VC211A			  74
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -143,9 +144,6 @@
  */
 #define EM28XX_NUM_PACKETS 40
 
-/* default alternate; 0 means choose the best */
-#define EM28XX_PINOUT 0
-
 #define EM28XX_INTERLACED_DEFAULT 1
 
 /*
@@ -615,7 +613,6 @@ struct em28xx {
 	struct em28xx_dvb *dvb;
 
 	/* I2C keyboard data */
-	struct i2c_board_info info;
 	struct IR_i2c_init_data init_data;
 };
 
@@ -646,6 +643,8 @@ int em28xx_write_regs_req(struct em28xx
 			  int len);
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
 int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
+int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+				 u8 bitmask);
 
 int em28xx_read_ac97(struct em28xx *dev, u8 reg);
 int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
@@ -669,9 +668,6 @@ int em28xx_gpio_set(struct em28xx *dev,
 void em28xx_wake_i2c(struct em28xx *dev);
 void em28xx_remove_from_devlist(struct em28xx *dev);
 void em28xx_add_into_devlist(struct em28xx *dev);
-struct em28xx *em28xx_get_device(int minor,
-				 enum v4l2_buf_type *fh_type,
-				 int *has_radio);
 int em28xx_register_extension(struct em28xx_ops *dev);
 void em28xx_unregister_extension(struct em28xx_ops *dev);
 void em28xx_init_extension(struct em28xx *dev);
@@ -800,7 +796,7 @@ static inline unsigned int norm_maxw(str
 	if (dev->board.is_webcam)
 		return dev->sensor_xres;
 
-	if (dev->board.max_range_640_480)
+	if (dev->board.max_range_640_480 || dev->board.is_em2800)
 		return 640;
 
 	return 720;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-input.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,7 @@ struct em28xx_IR {
 	int polling;
 	struct delayed_work work;
 	unsigned int last_toggle:1;
+	unsigned int full_code:1;
 	unsigned int last_readcount;
 	unsigned int repeat_interval;
 
@@ -111,10 +112,13 @@ int em28xx_get_key_terratec(struct IR_i2
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
 	unsigned char buf[2];
-	unsigned char code;
+	u16 code;
+	int size;
 
 	/* poll IR chip */
-	if (2 != i2c_master_recv(ir->c, buf, 2))
+	size = i2c_master_recv(ir->c, buf, sizeof(buf));
+
+	if (size != 2)
 		return -EIO;
 
 	/* Does eliminate repeated parity code */
@@ -123,16 +127,30 @@ int em28xx_get_key_em_haup(struct IR_i2c
 
 	ir->old = buf[1];
 
-	/* Rearranges bits to the right order */
-	code =   ((buf[0]&0x01)<<5) | /* 0010 0000 */
-		 ((buf[0]&0x02)<<3) | /* 0001 0000 */
-		 ((buf[0]&0x04)<<1) | /* 0000 1000 */
-		 ((buf[0]&0x08)>>1) | /* 0000 0100 */
-		 ((buf[0]&0x10)>>3) | /* 0000 0010 */
-		 ((buf[0]&0x20)>>5);  /* 0000 0001 */
+	/*
+	 * Rearranges bits to the right order.
+	 * The bit order were determined experimentally by using
+	 * The original Hauppauge Grey IR and another RC5 that uses addr=0x08
+	 * The RC5 code has 14 bits, but we've experimentally determined
+	 * the meaning for only 11 bits.
+	 * So, the code translation is not complete. Yet, it is enough to
+	 * work with the provided RC5 IR.
+	 */
+	code =
+		 ((buf[0] & 0x01) ? 0x0020 : 0) | /* 		0010 0000 */
+		 ((buf[0] & 0x02) ? 0x0010 : 0) | /* 		0001 0000 */
+		 ((buf[0] & 0x04) ? 0x0008 : 0) | /* 		0000 1000 */
+		 ((buf[0] & 0x08) ? 0x0004 : 0) | /* 		0000 0100 */
+		 ((buf[0] & 0x10) ? 0x0002 : 0) | /* 		0000 0010 */
+		 ((buf[0] & 0x20) ? 0x0001 : 0) | /* 		0000 0001 */
+		 ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000		  */
+		 ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000		  */
+		 ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100		  */
+		 ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010		  */
+		 ((buf[1] & 0x80) ? 0x0100 : 0);  /* 0000 0001		  */
 
-	i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",
-			code, buf[0]);
+	i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n",
+			code, buf[1], buf[0]);
 
 	/* return key */
 	*ir_key = code;
@@ -246,9 +264,10 @@ static void em28xx_ir_handle_key(struct
 		return;
 	}
 
-	dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n",
+	dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
 		poll_result.toggle_bit, poll_result.read_count,
-		ir->last_readcount, poll_result.rc_data[0]);
+		ir->last_readcount, poll_result.rc_address,
+		poll_result.rc_data[0]);
 
 	if (ir->dev->chip_id == CHIP_ID_EM2874) {
 		/* The em2874 clears the readcount field every time the
@@ -282,8 +301,15 @@ static void em28xx_ir_handle_key(struct
 
 	if (do_sendkey) {
 		dprintk("sending keypress\n");
-		ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
-				 poll_result.rc_data[0]);
+
+		if (ir->full_code)
+			ir_input_keydown(ir->input, &ir->ir,
+					 poll_result.rc_address << 8 |
+					 poll_result.rc_data[0]);
+		else
+			ir_input_keydown(ir->input, &ir->ir,
+					 poll_result.rc_data[0]);
+
 		ir_input_nokey(ir->input, &ir->ir);
 	}
 
@@ -328,6 +354,19 @@ int em28xx_ir_init(struct em28xx *dev)
 		goto err_out_free;
 
 	ir->input = input_dev;
+	ir_config = EM2874_IR_RC5;
+
+	/* Adjust xclk based o IR table for RC5/NEC tables */
+	if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) {
+		dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
+		ir->full_code = 1;
+	} else  if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) {
+		dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
+		ir_config = EM2874_IR_NEC;
+		ir->full_code = 1;
+	}
+	em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
+			      EM28XX_XCLK_IR_RC5_MODE);
 
 	/* Setup the proper handler based on the chip */
 	switch (dev->chip_id) {
@@ -337,8 +376,6 @@ int em28xx_ir_init(struct em28xx *dev)
 		break;
 	case CHIP_ID_EM2874:
 		ir->get_key = em2874_polling_getkey;
-		/* For now we only support RC5, so enable it */
-		ir_config = EM2874_IR_RC5;
 		em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
 		break;
 	default:
@@ -356,7 +393,10 @@ int em28xx_ir_init(struct em28xx *dev)
 	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
 	strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-	ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_USB;
@@ -372,7 +412,7 @@ int em28xx_ir_init(struct em28xx *dev)
 	em28xx_ir_start(ir);
 
 	/* all done */
-	err = input_register_device(ir->input);
+	err = ir_input_register(ir->input, dev->board.ir_codes);
 	if (err)
 		goto err_out_stop;
 
@@ -381,7 +421,6 @@ int em28xx_ir_init(struct em28xx *dev)
 	em28xx_ir_stop(ir);
 	dev->ir = NULL;
  err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -395,7 +434,7 @@ int em28xx_ir_fini(struct em28xx *dev)
 		return 0;
 
 	em28xx_ir_stop(ir);
-	input_unregister_device(ir->input);
+	ir_input_unregister(ir->input);
 	kfree(ir);
 
 	/* done */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-reg.h linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-reg.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -192,6 +192,7 @@
 
 /* FIXME: Need to be populated with the other chip ID's */
 enum em28xx_chip_id {
+	CHIP_ID_EM2800 = 7,
 	CHIP_ID_EM2710 = 17,
 	CHIP_ID_EM2820 = 18,	/* Also used by some em2710 */
 	CHIP_ID_EM2840 = 20,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-video.c linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/em28xx/em28xx-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/em28xx/em28xx-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -1060,12 +1060,6 @@ static int vidioc_try_fmt_vid_cap(struct
 		/* the em2800 can only scale down to 50% */
 		height = height > (3 * maxh / 4) ? maxh : maxh / 2;
 		width = width > (3 * maxw / 4) ? maxw : maxw / 2;
-		/* According to empiatech support the MaxPacketSize is too small
-		 * to support framesizes larger than 640x480 @ 30 fps or 640x576
-		 * @ 25 fps.  As this would cut of a part of the image we prefer
-		 * 360x576 or 360x480 for now */
-		if (width == maxw && height == maxh)
-			width /= 2;
 	} else {
 		/* width must even because of the YUYV format
 		   height must be even because of interlacing */
@@ -2087,22 +2081,30 @@ static int radio_queryctrl(struct file *
  */
 static int em28xx_v4l2_open(struct file *filp)
 {
-	int minor = video_devdata(filp)->minor;
-	int errCode = 0, radio;
-	struct em28xx *dev;
-	enum v4l2_buf_type fh_type;
+	int errCode = 0, radio = 0;
+	struct video_device *vdev = video_devdata(filp);
+	struct em28xx *dev = video_drvdata(filp);
+	enum v4l2_buf_type fh_type = 0;
 	struct em28xx_fh *fh;
 	enum v4l2_field field;
 
-	dev = em28xx_get_device(minor, &fh_type, &radio);
-
-	if (NULL == dev)
-		return -ENODEV;
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
+		fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		break;
+	case VFL_TYPE_VBI:
+		fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
+		break;
+	case VFL_TYPE_RADIO:
+		radio = 1;
+		break;
+	}
 
 	mutex_lock(&dev->lock);
 
-	em28xx_videodbg("open minor=%d type=%s users=%d\n",
-				minor, v4l2_type_names[fh_type], dev->users);
+	em28xx_videodbg("open dev=%s type=%s users=%d\n",
+			video_device_node_name(vdev), v4l2_type_names[fh_type],
+			dev->users);
 
 
 	fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
@@ -2166,25 +2168,25 @@ void em28xx_release_analog_resources(str
 	/*FIXME: I2C IR should be disconnected */
 
 	if (dev->radio_dev) {
-		if (-1 != dev->radio_dev->minor)
+		if (video_is_registered(dev->radio_dev))
 			video_unregister_device(dev->radio_dev);
 		else
 			video_device_release(dev->radio_dev);
 		dev->radio_dev = NULL;
 	}
 	if (dev->vbi_dev) {
-		em28xx_info("V4L2 device /dev/vbi%d deregistered\n",
-			    dev->vbi_dev->num);
-		if (-1 != dev->vbi_dev->minor)
+		em28xx_info("V4L2 device %s deregistered\n",
+			    video_device_node_name(dev->vbi_dev));
+		if (video_is_registered(dev->vbi_dev))
 			video_unregister_device(dev->vbi_dev);
 		else
 			video_device_release(dev->vbi_dev);
 		dev->vbi_dev = NULL;
 	}
 	if (dev->vdev) {
-		em28xx_info("V4L2 device /dev/video%d deregistered\n",
-			    dev->vdev->num);
-		if (-1 != dev->vdev->minor)
+		em28xx_info("V4L2 device %s deregistered\n",
+			    video_device_node_name(dev->vdev));
+		if (video_is_registered(dev->vdev))
 			video_unregister_device(dev->vdev);
 		else
 			video_device_release(dev->vdev);
@@ -2225,7 +2227,7 @@ static int em28xx_v4l2_close(struct file
 		}
 
 		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
 
 		/* do this before setting alternate! */
 		em28xx_uninit_isoc(dev);
@@ -2403,8 +2405,6 @@ static const struct video_device em28xx_
 	.release                    = video_device_release,
 	.ioctl_ops 		    = &video_ioctl_ops,
 
-	.minor                      = -1,
-
 	.tvnorms                    = V4L2_STD_ALL,
 	.current_norm               = V4L2_STD_PAL,
 };
@@ -2439,7 +2439,6 @@ static struct video_device em28xx_radio_
 	.name                 = "em28xx-radio",
 	.fops                 = &radio_fops,
 	.ioctl_ops 	      = &radio_ioctl_ops,
-	.minor                = -1,
 };
 
 /******************************** usb interface ******************************/
@@ -2457,7 +2456,6 @@ static struct video_device *em28xx_vdev_
 		return NULL;
 
 	*vfd		= *template;
-	vfd->minor	= -1;
 	vfd->v4l2_dev	= &dev->v4l2_dev;
 	vfd->release	= video_device_release;
 	vfd->debug	= video_debug;
@@ -2465,6 +2463,7 @@ static struct video_device *em28xx_vdev_
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s",
 		 dev->name, type_name);
 
+	video_set_drvdata(vfd, dev);
 	return vfd;
 }
 
@@ -2546,16 +2545,16 @@ int em28xx_register_analog_devices(struc
 			em28xx_errdev("can't register radio device\n");
 			return ret;
 		}
-		em28xx_info("Registered radio device as /dev/radio%d\n",
-			    dev->radio_dev->num);
+		em28xx_info("Registered radio device as %s\n",
+			    video_device_node_name(dev->radio_dev));
 	}
 
-	em28xx_info("V4L2 video device registered as /dev/video%d\n",
-				dev->vdev->num);
+	em28xx_info("V4L2 video device registered as %s\n",
+		    video_device_node_name(dev->vdev));
 
 	if (dev->vbi_dev)
-		em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n",
-			    dev->vbi_dev->num);
+		em28xx_info("V4L2 VBI device registered as %s\n",
+			    video_device_node_name(dev->vbi_dev));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/et61x251/et61x251_core.c linux-libre-2.6.33-gnu1/drivers/media/video/et61x251/et61x251_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/et61x251/et61x251_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/et61x251/et61x251_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -587,8 +587,8 @@ static int et61x251_stream_interrupt(str
 	else if (cam->stream != STREAM_OFF) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "URB timeout reached. The camera is misconfigured. To "
-		       "use it, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use it, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1195,7 +1195,8 @@ static void et61x251_release_resources(s
 
 	cam = container_of(kref, struct et61x251_device, kref);
 
-	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
+	DBG(2, "V4L2 device %s deregistered",
+	    video_device_node_name(cam->v4ldev));
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 	usb_put_dev(cam->usbdev);
@@ -1236,8 +1237,8 @@ static int et61x251_open(struct file *fi
 	}
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is already in use",
-		       cam->v4ldev->num);
+		DBG(2, "Device %s is already in use",
+		       video_device_node_name(cam->v4ldev));
 		DBG(3, "Simultaneous opens are not supported");
 		if ((filp->f_flags & O_NONBLOCK) ||
 		    (filp->f_flags & O_NDELAY)) {
@@ -1280,7 +1281,8 @@ static int et61x251_open(struct file *fi
 	cam->frame_count = 0;
 	et61x251_empty_framequeues(cam);
 
-	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
+	DBG(3, "Video device %s is open",
+	    video_device_node_name(cam->v4ldev));
 
 out:
 	mutex_unlock(&cam->open_mutex);
@@ -1304,7 +1306,8 @@ static int et61x251_release(struct file
 	cam->users--;
 	wake_up_interruptible_nr(&cam->wait_open, 1);
 
-	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
+	DBG(3, "Video device %s closed",
+	    video_device_node_name(cam->v4ldev));
 
 	kref_put(&cam->kref, et61x251_release_resources);
 
@@ -1846,8 +1849,8 @@ et61x251_vidioc_s_crop(struct et61x251_d
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1859,8 +1862,8 @@ et61x251_vidioc_s_crop(struct et61x251_d
 	    nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -2069,8 +2072,8 @@ et61x251_vidioc_try_s_fmt(struct et61x25
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -2081,8 +2084,8 @@ et61x251_vidioc_try_s_fmt(struct et61x25
 	    nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -2130,7 +2133,7 @@ et61x251_vidioc_s_jpegcomp(struct et61x2
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
 		       "problems. To use the camera, close and open "
-		       "/dev/video%d again.", cam->v4ldev->num);
+		       "%s again.", video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -2584,7 +2587,6 @@ et61x251_usb_probe(struct usb_interface*
 
 	strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
 	cam->v4ldev->fops = &et61x251_fops;
-	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	cam->v4ldev->parent = &udev->dev;
 	video_set_drvdata(cam->v4ldev, cam);
@@ -2603,7 +2605,8 @@ et61x251_usb_probe(struct usb_interface*
 		goto fail;
 	}
 
-	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
+	DBG(2, "V4L2 device registered as %s",
+	    video_device_node_name(cam->v4ldev));
 
 	cam->module_param.force_munmap = force_munmap[dev_nr];
 	cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2654,9 +2657,9 @@ static void et61x251_usb_disconnect(stru
 	DBG(2, "Disconnecting %s...", cam->v4ldev->name);
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is open! Deregistration and "
-		       "memory deallocation are deferred.",
-		    cam->v4ldev->num);
+		DBG(2, "Device %s is open! Deregistration and memory "
+		       "deallocation are deferred.",
+		    video_device_node_name(cam->v4ldev));
 		cam->state |= DEV_MISCONFIGURED;
 		et61x251_stop_transfer(cam);
 		cam->state |= DEV_DISCONNECTED;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/conex.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/conex.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/conex.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/conex.c	2010-02-24 13:52:17.000000000 -0500
@@ -888,8 +888,7 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -897,16 +896,15 @@ static void sd_pkt_scan(struct gspca_dev
 	if (data[0] == 0xff && data[1] == 0xd8) {
 
 		/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-			sd->jpeg_hdr, JPEG_HDR_SZ);
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
+				sd->jpeg_hdr, JPEG_HDR_SZ);
 		data += 2;
 		len -= 2;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev*gspca_dev)
@@ -1048,14 +1046,14 @@ static struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] __devinitconst = {
 	{USB_DEVICE(0x0572, 0x0041)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 
 /* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
+static int __devinit sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/etoms.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/etoms.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/etoms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/etoms.c	2010-02-24 13:52:17.000000000 -0500
@@ -752,8 +752,7 @@ static void do_autogain(struct gspca_dev
 #undef LIMIT
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	int seqframe;
@@ -767,14 +766,13 @@ static void sd_pkt_scan(struct gspca_dev
 		       data[2], data[3], data[4], data[5]);
 		data += 30;
 		/* don't change datalength as the chips provided it */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 	if (len) {
 		data += 8;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 	} else {			/* Drop Packet */
 		gspca_dev->last_packet_type = DISCARD_PACKET;
 	}
@@ -866,7 +864,7 @@ static struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] __devinitconst = {
 	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
 #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
 	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
@@ -877,7 +875,7 @@ static __devinitdata struct usb_device_i
 MODULE_DEVICE_TABLE(usb, device_table);
 
 /* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
+static int __devinit sd_probe(struct usb_interface *intf,
 		    const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/finepix.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/finepix.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/finepix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/finepix.c	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,6 @@ static void dostream(struct work_struct
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
 	struct urb *urb = gspca_dev->urb[0];
 	u8 *data = urb->transfer_buffer;
-	struct gspca_frame *frame;
 	int ret = 0;
 	int len;
 
@@ -118,10 +117,6 @@ again:
 			}
 			if (!gspca_dev->present || !gspca_dev->streaming)
 				goto out;
-			frame = gspca_get_i_frame(&dev->gspca_dev);
-			if (frame == NULL)
-				gspca_dev->last_packet_type = DISCARD_PACKET;
-
 			if (len < FPIX_MAX_TRANSFER ||
 				(data[len - 2] == 0xff &&
 					data[len - 1] == 0xd9)) {
@@ -132,21 +127,17 @@ again:
 				 * but there's nothing we can do. We also end
 				 * here if the the jpeg ends right at the end
 				 * of the frame. */
-				if (frame)
-					frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET,
-							frame,
-							data, len);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						data, len);
 				break;
 			}
 
 			/* got a partial image */
-			if (frame)
-				gspca_frame_add(gspca_dev,
-						gspca_dev->last_packet_type
-							== LAST_PACKET
-						? FIRST_PACKET : INTER_PACKET,
-						frame, data, len);
+			gspca_frame_add(gspca_dev,
+					gspca_dev->last_packet_type
+						== LAST_PACKET
+					? FIRST_PACKET : INTER_PACKET,
+					data, len);
 		}
 
 		/* We must wait before trying reading the next
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,7 @@
-/* @file gl860.c
- * @date 2009-08-27
- *
- * Genesys Logic webcam with gl860 subdrivers
+/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
+ * Subdriver core
  *
- * Driver by Olivier Lorin <o.lorin@laposte.net>
+ * 2009/09/24 Olivier Lorin <o.lorin@laposte.net>
  * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
  * Thanks BUGabundo and Malmostoso for your amazing help!
  *
@@ -23,8 +21,8 @@
 #include "gspca.h"
 #include "gl860.h"
 
-MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>");
-MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver");
+MODULE_AUTHOR("Olivier Lorin <o.lorin@laposte.net>");
+MODULE_DESCRIPTION("Genesys Logic USB PC Camera Driver");
 MODULE_LICENSE("GPL");
 
 /*======================== static function declarations ====================*/
@@ -38,11 +36,11 @@ static int  sd_isoc_init(struct gspca_de
 static int  sd_start(struct gspca_dev *gspca_dev);
 static void sd_stop0(struct gspca_dev *gspca_dev);
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, u8 *data, s32 len);
+			u8 *data, int len);
 static void sd_callback(struct gspca_dev *gspca_dev);
 
 static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
-				s32 vendor_id, s32 product_id);
+				u16 vendor_id, u16 product_id);
 
 /*============================ driver options ==============================*/
 
@@ -53,7 +51,7 @@ MODULE_PARM_DESC(AC50Hz, " Does AC power
 static char sensor[7];
 module_param_string(sensor, sensor, sizeof(sensor), 0644);
 MODULE_PARM_DESC(sensor,
-		" Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')");
+		" Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640')");
 
 /*============================ webcam controls =============================*/
 
@@ -156,7 +154,7 @@ static int gl860_build_control_table(str
 	SET_MY_CTRL(V4L2_CID_VFLIP,
 		V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
 	SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
-		V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz)
+		V4L2_CTRL_TYPE_BOOLEAN, "AC power 50Hz", AC50Hz)
 
 	return nCtrls;
 }
@@ -328,11 +326,11 @@ static int sd_config(struct gspca_dev *g
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	s32 vendor_id, product_id;
+	u16 vendor_id, product_id;
 
 	/* Get USB VendorID and ProductID */
-	vendor_id  = le16_to_cpu(id->idVendor);
-	product_id = le16_to_cpu(id->idProduct);
+	vendor_id  = id->idVendor;
+	product_id = id->idProduct;
 
 	sd->nbRightUp = 1;
 	sd->nbIm = -1;
@@ -435,7 +433,7 @@ static void sd_stop0(struct gspca_dev *g
 
 /* This function is called when an image is being received */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, u8 *data, s32 len)
+			u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	static s32 nSkipped;
@@ -447,11 +445,11 @@ static void sd_pkt_scan(struct gspca_dev
 	/* Test only against 0202h, so endianess does not matter */
 	switch (*(s16 *) data) {
 	case 0x0202:		/* End of frame, start a new one */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		nSkipped = 0;
 		if (sd->nbIm >= 0 && sd->nbIm < 10)
 			sd->nbIm++;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		break;
 
 	default:
@@ -466,7 +464,7 @@ static void sd_pkt_scan(struct gspca_dev
 				nSkipped = nToSkip + 1;
 			}
 			gspca_frame_add(gspca_dev,
-				INTER_PACKET, frame, data, len);
+				INTER_PACKET, data, len);
 		}
 		break;
 	}
@@ -536,8 +534,8 @@ static int sd_probe(struct usb_interface
 		gspca_dev = usb_get_intfdata(intf);
 
 		PDEBUG(D_PROBE,
-			"Camera is now controlling video device /dev/video%d",
-			gspca_dev->vdev.minor);
+			"Camera is now controlling video device %s",
+			video_device_node_name(&gspca_dev->vdev));
 	}
 
 	return ret;
@@ -675,7 +673,7 @@ void fetch_idxdata(struct gspca_dev *gsp
 }
 
 static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
-				s32 vendor_id, s32 product_id)
+				u16 vendor_id, u16 product_id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 probe, nb26, nb96, nOV, ntry;
@@ -702,6 +700,7 @@ static int gl860_guess_sensor(struct gsp
 		ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
 		msleep(56);
 
+		PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
 		nOV = 0;
 		for (ntry = 0; ntry < 4; ntry++) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -711,14 +710,14 @@ static int gl860_guess_sensor(struct gsp
 			ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
 			msleep(10);
 			ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
-			PDEBUG(D_PROBE, "1st probe=%02x", probe);
+			PDEBUG(D_PROBE, "probe=0x%02x", probe);
 			if (probe == 0xff)
 				nOV++;
 		}
 
 		if (nOV) {
-			PDEBUG(D_PROBE, "0xff -> sensor OVXXXX");
-			PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655");
+			PDEBUG(D_PROBE, "0xff -> OVXXXX");
+			PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
 
 			nb26 = nb96 = 0;
 			for (ntry = 0; ntry < 4; ntry++) {
@@ -728,40 +727,38 @@ static int gl860_guess_sensor(struct gsp
 				ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
 						0, NULL);
 				msleep(10);
+
 				/* Wait for 26(OV2640) or 96(OV9655) */
 				ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
 						1, &probe);
 
-				PDEBUG(D_PROBE, "2nd probe=%02x", probe);
-				if (probe == 0x00)
-					nb26++;
 				if (probe == 0x26 || probe == 0x40) {
+					PDEBUG(D_PROBE,
+						"probe=0x%02x -> OV2640",
+						probe);
 					sd->sensor = ID_OV2640;
 					nb26 += 4;
 					break;
 				}
 				if (probe == 0x96 || probe == 0x55) {
+					PDEBUG(D_PROBE,
+						"probe=0x%02x -> OV9655",
+						probe);
 					sd->sensor = ID_OV9655;
 					nb96 += 4;
 					break;
 				}
+				PDEBUG(D_PROBE, "probe=0x%02x", probe);
+				if (probe == 0x00)
+					nb26++;
 				if (probe == 0xff)
 					nb96++;
 				msleep(3);
 			}
-			if (nb26 < 4 && nb96 < 4) {
-				PDEBUG(D_PROBE, "No relevant answer ");
-				PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
-				PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
-				PDEBUG(D_PROBE,
-					"To force a sensor, add that line to "
-					"/etc/modprobe.d/options.conf:");
-				PDEBUG(D_PROBE, "options gspca_gl860 "
-					"sensor=\"OV2640\" or \"OV9655\"");
+			if (nb26 < 4 && nb96 < 4)
 				return -1;
-			}
-		} else { /* probe = 0 */
-			PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
+		} else {
+			PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
 			sd->sensor = ID_MI2020;
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860.h linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
-/* @file gl860.h
- * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN
- * @date 2009-08-27
+/* GSPCA subdrivers for Genesys Logic webcams with the GL860 chip
+ * Subdriver declarations
+ *
+ * 2009/10/14 Olivier LORIN <o.lorin@laposte.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
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-mi1320.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-mi1320.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-mi1320.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-mi1320.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
-/* @file gl860-mi1320.c
- * @author Olivier LORIN from my logs
- * @date 2009-08-27
+/* Subdriver for the GL860 chip with the MI1320 sensor
+ * Author Olivier LORIN from own logs
  *
  * 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
@@ -127,49 +126,49 @@ static u8 dat_wbalBL[] =
 
 static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
 
-static u8 s000[] =
+static u8 dat_common00[] =
 	"\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
 	"\xd8\x04\x58\x00\x04\x02";
-static u8 s001[] =
+static u8 dat_common01[] =
 	"\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
 	"\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
-static u8 s002[] =
+static u8 dat_common02[] =
 	"\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
 	"\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
 	"\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
-static u8 s003[] =
+static u8 dat_common03[] =
 	"\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
 	"\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
 	"\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
-static u8 s004[] =
+static u8 dat_common04[] =
 	"\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
-static u8 s005[] =
+static u8 dat_common05[] =
 	"\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
 	"\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
 	"\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
-static u8 s006[] =
+static u8 dat_common06[] =
 	"\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
 	"\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
 	"\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
-static u8 s007[] =
+static u8 dat_common07[] =
 	"\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
 	"\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
 	"\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
 	"\xe1\xff\xf1\x00";
-static u8 s008[] =
+static u8 dat_common08[] =
 	"\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
 	"\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
 	"\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
-static u8 s009[] =
+static u8 dat_common09[] =
 	"\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
 	"\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
 	"\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
-static u8 s010[] =
+static u8 dat_common10[] =
 	"\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
 	"\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
 	"\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
 	"\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
-static u8 s011[] =
+static u8 dat_common11[] =
 	"\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
 	"\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
 	"\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
@@ -222,26 +221,26 @@ void mi1320_init_settings(struct gspca_d
 
 static void common(struct gspca_dev *gspca_dev)
 {
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00);
 	ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01);
 	n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11);
 	keep_on_fetching_validx(gspca_dev, tbl_common,
 					ARRAY_SIZE(tbl_common), n);
 }
@@ -346,7 +345,7 @@ static int mi1320_configure_alt(struct g
 	return 0;
 }
 
-int mi1320_camera_settings(struct gspca_dev *gspca_dev)
+static int mi1320_camera_settings(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-mi2020.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-mi2020.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-mi2020.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-mi2020.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,6 @@
-/* @file gl860-mi2020.c
- * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
+/* Subdriver for the GL860 chip with the MI2020 sensor
+ * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
  * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
- * @date 2009-08-27
  *
  * 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
@@ -41,7 +40,7 @@ static u8 dat_freq1[] = { 0x8c, 0xa4, 0x
 static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
 static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
 
-static struct validx tbl_common_a[] = {
+static struct validx tbl_common1[] = {
 	{0x0000, 0x0000},
 	{1, 0xffff}, /* msleep(35); */
 	{0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
@@ -49,7 +48,7 @@ static struct validx tbl_common_a[] = {
 	{0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
 };
 
-static struct validx tbl_common_b[] = {
+static struct validx tbl_common2[] = {
 	{0x006a, 0x0007},
 	{35, 0xffff},
 	{0x00ef, 0x0006},
@@ -60,7 +59,7 @@ static struct validx tbl_common_b[] = {
 	{0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
 };
 
-static struct idxdata tbl_common_c[] = {
+static struct idxdata tbl_common3[] = {
 	{0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
 	{6, "\xff\xff\xff"}, /* 12 */
 	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
@@ -109,7 +108,7 @@ static struct idxdata tbl_common_c[] = {
 	{0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
 };
 
-static struct idxdata tbl_common_d[] = {
+static struct idxdata tbl_common4[] = {
 	{0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
 	{0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
 	{0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
@@ -118,7 +117,7 @@ static struct idxdata tbl_common_d[] = {
 	{0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
 };
 
-static struct idxdata tbl_common_e[] = {
+static struct idxdata tbl_common5[] = {
 	{0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
 	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
 	{0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
@@ -180,7 +179,7 @@ static struct validx tbl_init_at_startup
 	{53, 0xffff},
 };
 
-static struct idxdata tbl_init_post_alt_low_a[] = {
+static struct idxdata tbl_init_post_alt_low1[] = {
 	{0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
 	{0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
 	{0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
@@ -189,7 +188,7 @@ static struct idxdata tbl_init_post_alt_
 	{0x33, "\x90\x00\x9b"},
 };
 
-static struct idxdata tbl_init_post_alt_low_b[] = {
+static struct idxdata tbl_init_post_alt_low2[] = {
 	{0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
 	{0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
 	{2, "\xff\xff\xff"},
@@ -197,7 +196,7 @@ static struct idxdata tbl_init_post_alt_
 	{2, "\xff\xff\xff"},
 };
 
-static struct idxdata tbl_init_post_alt_low_c[] = {
+static struct idxdata tbl_init_post_alt_low3[] = {
 	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
 	{2, "\xff\xff\xff"},
 	{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
@@ -221,7 +220,7 @@ static struct idxdata tbl_init_post_alt_
 	{1, "\xff\xff\xff"},
 };
 
-static struct idxdata tbl_init_post_alt_low_d[] = {
+static struct idxdata tbl_init_post_alt_low4[] = {
 	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
 	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
 	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -267,7 +266,7 @@ static struct idxdata tbl_init_post_alt_
 	{0x32, "\x6c\x14\x08"},
 };
 
-static struct idxdata tbl_init_post_alt_big_a[] = {
+static struct idxdata tbl_init_post_alt_big1[] = {
 	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
 	{2, "\xff\xff\xff"},
 	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
@@ -288,7 +287,7 @@ static struct idxdata tbl_init_post_alt_
 	{0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
 };
 
-static struct idxdata tbl_init_post_alt_big_b[] = {
+static struct idxdata tbl_init_post_alt_big2[] = {
 	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
 	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
 	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -317,7 +316,7 @@ static struct idxdata tbl_init_post_alt_
 	{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
 };
 
-static struct idxdata tbl_init_post_alt_big_c[] = {
+static struct idxdata tbl_init_post_alt_big3[] = {
 	{0x33, "\x8c\xa1\x02"},
 	{0x33, "\x90\x00\x1f"},
 	{0x33, "\x8c\xa1\x02"},
@@ -388,14 +387,14 @@ static void common(struct gspca_dev *gsp
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
 
 	if (_MI2020b_) {
-		fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
+		fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1));
 	} else {
 		if (_MI2020_)
 			ctrl_out(gspca_dev, 0x40,  1, 0x0008, 0x0004,  0, NULL);
 		else
 			ctrl_out(gspca_dev, 0x40,  1, 0x0002, 0x0004,  0, NULL);
 		msleep(35);
-		fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
+		fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2));
 	}
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x01");
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x00");
@@ -403,13 +402,13 @@ static void common(struct gspca_dev *gsp
 	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0030,  3, "\x1a\x0a\xcc");
 	if (reso == IMAGE_1600)
 		msleep(2); /* 1600 */
-	fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
+	fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3));
 
 	if (_MI2020b_ || _MI2020_)
-		fetch_idxdata(gspca_dev, tbl_common_d,
-				ARRAY_SIZE(tbl_common_d));
+		fetch_idxdata(gspca_dev, tbl_common4,
+				ARRAY_SIZE(tbl_common4));
 
-	fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
+	fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5));
 	if (_MI2020b_ || _MI2020_) {
 		/* Different from fret */
 		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
@@ -525,15 +524,15 @@ static int mi2020_init_post_alt(struct g
 				12, dat_800);
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
-					ARRAY_SIZE(tbl_init_post_alt_low_a));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
+					ARRAY_SIZE(tbl_init_post_alt_low1));
 
 		if (reso == IMAGE_800)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
-					ARRAY_SIZE(tbl_init_post_alt_low_b));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low2,
+					ARRAY_SIZE(tbl_init_post_alt_low2));
 
-		fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
-				ARRAY_SIZE(tbl_init_post_alt_low_c));
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
+				ARRAY_SIZE(tbl_init_post_alt_low3));
 
 		if (_MI2020b_) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
@@ -574,8 +573,8 @@ static int mi2020_init_post_alt(struct g
 		msleep(5);/* " */
 
 		if (_MI2020c_) {
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
-					ARRAY_SIZE(tbl_init_post_alt_low_d));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low4,
+					ARRAY_SIZE(tbl_init_post_alt_low4));
 		} else {
 			ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
 			msleep(14); /* 0xd8 */
@@ -644,8 +643,8 @@ static int mi2020_init_post_alt(struct g
 					3, "\x90\x04\xb0");
 		}
 
-		fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
-				ARRAY_SIZE(tbl_init_post_alt_big_a));
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_big1,
+				ARRAY_SIZE(tbl_init_post_alt_big1));
 
 		if (reso == IMAGE_1600)
 			msleep(13); /* 1600 */
@@ -708,8 +707,8 @@ static int mi2020_init_post_alt(struct g
 		msleep(14);
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
-					ARRAY_SIZE(tbl_init_post_alt_big_b));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big2,
+					ARRAY_SIZE(tbl_init_post_alt_big2));
 
 		/* flip/mirror */
 		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
@@ -738,8 +737,8 @@ static int mi2020_init_post_alt(struct g
 		sd->nbIm = 0;
 
 		if (_MI2020c_)
-			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
-					ARRAY_SIZE(tbl_init_post_alt_big_c));
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big3,
+					ARRAY_SIZE(tbl_init_post_alt_big3));
 	}
 
 	sd->vold.mirror    = mirror;
@@ -770,7 +769,7 @@ static int mi2020_configure_alt(struct g
 	return 0;
 }
 
-int mi2020_camera_settings(struct gspca_dev *gspca_dev)
+static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-ov2640.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-ov2640.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-ov2640.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-ov2640.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
-/* @file gl860-ov2640.c
- * @author Olivier LORIN, from Malmostoso's logs
- * @date 2009-08-27
+/* Subdriver for the GL860 chip with the OV2640 sensor
+ * Author Olivier LORIN, from Malmostoso's logs
  *
  * 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
@@ -21,8 +20,12 @@
 #include "gl860.h"
 
 static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
-static u8 dat_init2[] = {0x61}; /* expected */
-static u8 dat_init3[] = {0x51}; /* expected */
+
+static u8 c61[] = {0x61}; /* expected */
+static u8 c51[] = {0x51}; /* expected */
+static u8 c50[] = {0x50}; /* expected */
+static u8 c28[] = {0x28}; /* expected */
+static u8 ca8[] = {0xa8}; /* expected */
 
 static u8 dat_post[] =
 	"\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
@@ -32,10 +35,6 @@ static u8 dat_800[]  = "\xd0\x01\xd1\x10
 static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
 static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
 
-static u8 c50[] = {0x50}; /* expected */
-static u8 c28[] = {0x28}; /* expected */
-static u8 ca8[] = {0xa8}; /* expected */
-
 static struct validx tbl_init_at_startup[] = {
 	{0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
 	{0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
@@ -92,7 +91,7 @@ static struct validx tbl_common[] = {
 	{0x6000, 0x0010},
 };
 
-static struct validx tbl_sensor_settings_common_a[] = {
+static struct validx tbl_sensor_settings_common1[] = {
 	{0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
 	{0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
 	{0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
@@ -104,40 +103,10 @@ static struct validx tbl_sensor_settings
 	{0x0040, 0x0000},
 };
 
-static struct validx tbl_sensor_settings_common_b[] = {
+static struct validx tbl_sensor_settings_common2[] = {
 	{0x6001, 0x00ff}, {0x6038, 0x000c},
 	{10, 0xffff},
 	{0x6000, 0x0011},
-	/* backlight=31/64 */
-	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
-	/* bright=0/256 */
-	{0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
-	/* wbal=64/128 */
-	{0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
-	/* cntr=0/256 */
-	{0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
-	/* sat=128/256 */
-	{0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
-	/* sharpness=0/32 */
-	{0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
-	/* hue=0/256 */
-	{0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
-	/* gam=32/64 */
-	{0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
-	/* image right up */
-	{0xffff, 0xffff},
-	{15, 0xffff},
-	{0x6001, 0x00ff}, {0x6000, 0x8004},
-	{0xffff, 0xffff},
-	{0x60a8, 0x0004},
-	{15, 0xffff},
-	{0x6001, 0x00ff}, {0x6000, 0x8004},
-	{0xffff, 0xffff},
-	{0x60f8, 0x0004},
-	/* image right up */
-	{0xffff, 0xffff},
-	/* backlight=31/64 */
-	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
 };
 
 static struct validx tbl_640[] = {
@@ -166,7 +135,7 @@ static struct validx tbl_800[] = {
 	{0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
 };
 
-static struct validx tbl_big_a[] = {
+static struct validx tbl_big1[] = {
 	{0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
 	{0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
 	{0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
@@ -176,14 +145,14 @@ static struct validx tbl_big_a[] = {
 	{0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
 };
 
-static struct validx tbl_big_b[] = {
+static struct validx tbl_big2[] = {
 	{0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
 	{0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
 	{0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
 	{0x6000, 0x008e},
 };
 
-static struct validx tbl_big_c[] = {
+static struct validx tbl_big3[] = {
 	{0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
 	{0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
 	{0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
@@ -223,17 +192,19 @@ void ov2640_init_settings(struct gspca_d
 	sd->vcur.hue        =   0;
 	sd->vcur.saturation = 128;
 	sd->vcur.whitebal   =  64;
+	sd->vcur.mirror     =   0;
+	sd->vcur.flip       =   0;
 
 	sd->vmax.backlight  =  64;
 	sd->vmax.brightness = 255;
 	sd->vmax.sharpness  =  31;
 	sd->vmax.contrast   = 255;
 	sd->vmax.gamma      =  64;
-	sd->vmax.hue        = 255 + 1;
+	sd->vmax.hue        = 254 + 2;
 	sd->vmax.saturation = 255;
 	sd->vmax.whitebal   = 128;
-	sd->vmax.mirror     = 0;
-	sd->vmax.flip       = 0;
+	sd->vmax.mirror     = 1;
+	sd->vmax.flip       = 1;
 	sd->vmax.AC50Hz     = 0;
 
 	sd->dev_camera_settings = ov2640_camera_settings;
@@ -259,11 +230,11 @@ static int ov2640_init_at_startup(struct
 
 	common(gspca_dev);
 
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
 
 	ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
 
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
 
 	ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
 /*	ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
@@ -275,6 +246,8 @@ static int ov2640_init_pre_alt(struct gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	sd->mirrorMask = 0;
+
 	sd->vold.backlight  = -1;
 	sd->vold.brightness = -1;
 	sd->vold.sharpness  = -1;
@@ -283,6 +256,8 @@ static int ov2640_init_pre_alt(struct gs
 	sd->vold.gamma    = -1;
 	sd->vold.hue      = -1;
 	sd->vold.whitebal = -1;
+	sd->vold.mirror = -1;
+	sd->vold.flip   = -1;
 
 	ov2640_init_post_alt(gspca_dev);
 
@@ -292,16 +267,16 @@ static int ov2640_init_pre_alt(struct gs
 static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
 {
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 
 	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
 
-	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a,
-			ARRAY_SIZE(tbl_sensor_settings_common_a));
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common1,
+			ARRAY_SIZE(tbl_sensor_settings_common1));
 	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
 	common(gspca_dev);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a,
-				ARRAY_SIZE(tbl_sensor_settings_common_a), n);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common1,
+				ARRAY_SIZE(tbl_sensor_settings_common1), n);
 
 	switch (reso) {
 	case IMAGE_640:
@@ -316,18 +291,18 @@ static int ov2640_init_post_alt(struct g
 
 	case IMAGE_1600:
 	case IMAGE_1280:
-		n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a));
+		n = fetch_validx(gspca_dev, tbl_big1, ARRAY_SIZE(tbl_big1));
 
 		if (reso == IMAGE_1280) {
-			n = fetch_validx(gspca_dev, tbl_big_b,
-					ARRAY_SIZE(tbl_big_b));
+			n = fetch_validx(gspca_dev, tbl_big2,
+					ARRAY_SIZE(tbl_big2));
 		} else {
 			ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
 			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
 			ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
 		}
 
-		n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c));
+		n = fetch_validx(gspca_dev, tbl_big3, ARRAY_SIZE(tbl_big3));
 
 		if (reso == IMAGE_1280) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
@@ -343,20 +318,8 @@ static int ov2640_init_post_alt(struct g
 		break;
 	}
 
-	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b,
-			ARRAY_SIZE(tbl_sensor_settings_common_b));
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
-	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
-	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
-				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
+			ARRAY_SIZE(tbl_sensor_settings_common2));
 
 	ov2640_camera_settings(gspca_dev);
 
@@ -393,18 +356,20 @@ static int ov2640_camera_settings(struct
 	s32 sat    = sd->vcur.saturation;
 	s32 hue    = sd->vcur.hue;
 	s32 wbal   = sd->vcur.whitebal;
+	s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
+	s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) == 0);
 
 	if (backlight != sd->vold.backlight) {
+		/* No sd->vold.backlight=backlight; (to be done again later) */
 		if (backlight < 0 || backlight > sd->vmax.backlight)
 			backlight = 0;
 
 		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight     , 0x0024,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
 				0, NULL);
-		/* No sd->vold.backlight=backlight; (to be done again later) */
 	}
 
 	if (bright != sd->vold.brightness) {
@@ -466,7 +431,7 @@ static int ov2640_camera_settings(struct
 		ctrl_out(gspca_dev, 0x40, 1, 0x6002     , 0x007c, 0, NULL);
 		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
 				0, NULL);
-		if (hue >= sd->vmax.hue)
+		if (hue >= 255)
 			sd->swapRB = 1;
 		else
 			sd->swapRB = 0;
@@ -482,14 +447,33 @@ static int ov2640_camera_settings(struct
 		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
 	}
 
+	if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
+		sd->vold.mirror = mirror;
+		sd->vold.flip   = flip;
+
+		mirror = 0x80 * mirror;
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
+		ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
+
+		flip = 0x50 * flip + mirror;
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
+		ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
+
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
+	}
+
 	if (backlight != sd->vold.backlight) {
 		sd->vold.backlight = backlight;
 
 		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight     , 0x0024,
 				0, NULL);
-		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+		ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
 				0, NULL);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-ov9655.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-ov9655.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gl860/gl860-ov9655.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gl860/gl860-ov9655.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,6 @@
-/* @file gl860-ov9655.c
- * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
+/* Subdriver for the GL860 chip with the OV9655 sensor
+ * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
  * on dsd's weblog
- * @date 2009-08-27
  *
  * 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
@@ -104,14 +103,14 @@ static u8 *tbl_800[] = {
 };
 
 static u8 c04[] = {0x04};
-static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
-static u8 dat_post_2[] = "\x10\x10\xc1\x02";
-static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
-static u8 dat_post_4[] = "\x10\x02\xc1\x06";
-static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
-static u8 dat_post_6[] = "\x10\x10\xc1\x05";
-static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
-static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
+static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
+static u8 dat_post2[] = "\x10\x10\xc1\x02";
+static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
+static u8 dat_post4[] = "\x10\x02\xc1\x06";
+static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
+static u8 dat_post6[] = "\x10\x10\xc1\x05";
+static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
+static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
 
 static struct validx tbl_init_post_alt[] = {
 	{0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
@@ -212,7 +211,7 @@ static int ov9655_init_pre_alt(struct gs
 static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
 {
 	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-	s32 n; /* reserved for FETCH macros */
+	s32 n; /* reserved for FETCH functions */
 	s32 i;
 	u8 **tbl;
 
@@ -243,7 +242,7 @@ static int ov9655_init_post_alt(struct g
 	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
@@ -259,7 +258,7 @@ static int ov9655_init_post_alt(struct g
 	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
@@ -270,18 +269,18 @@ static int ov9655_init_post_alt(struct g
 	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
 					ARRAY_SIZE(tbl_init_post_alt), n);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6);
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
 
-	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
 
 	ov9655_camera_settings(gspca_dev);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gspca.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gspca.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 7, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 8, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -74,7 +74,7 @@ static void PDEBUG_MODE(char *txt, __u32
 #define PDEBUG_MODE(txt, pixfmt, w, h)
 #endif
 
-/* specific memory types - !! should different from V4L2_MEMORY_xxx */
+/* specific memory types - !! should be different from V4L2_MEMORY_xxx */
 #define GSPCA_MEMORY_NO 0	/* V4L2_MEMORY_xxx starts from 1 */
 #define GSPCA_MEMORY_READ 7
 
@@ -126,7 +126,6 @@ EXPORT_SYMBOL(gspca_get_i_frame);
 static void fill_frame(struct gspca_dev *gspca_dev,
 			struct urb *urb)
 {
-	struct gspca_frame *frame;
 	u8 *data;		/* address of data in the iso message */
 	int i, len, st;
 	cam_pkt_op pkt_scan;
@@ -135,21 +134,16 @@ static void fill_frame(struct gspca_dev
 		if (urb->status == -ESHUTDOWN)
 			return;		/* disconnection */
 #ifdef CONFIG_PM
-		if (!gspca_dev->frozen)
+		if (gspca_dev->frozen)
+			return;
 #endif
-			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;
+		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+		urb->status = 0;
+		goto resubmit;
 	}
 	pkt_scan = gspca_dev->sd_desc->pkt_scan;
 	for (i = 0; i < urb->number_of_packets; i++) {
 
-		/* check the availability of the frame buffer */
-		frame = gspca_get_i_frame(gspca_dev);
-		if (!frame) {
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-			break;
-		}
-
 		/* check the packet status and length */
 		len = urb->iso_frame_desc[i].actual_length;
 		if (len == 0) {
@@ -171,9 +165,10 @@ static void fill_frame(struct gspca_dev
 			i, urb->iso_frame_desc[i].offset, len);
 		data = (u8 *) urb->transfer_buffer
 					+ urb->iso_frame_desc[i].offset;
-		pkt_scan(gspca_dev, frame, data, len);
+		pkt_scan(gspca_dev, data, len);
 	}
 
+resubmit:
 	/* resubmit the URB */
 	st = usb_submit_urb(urb, GFP_ATOMIC);
 	if (st < 0)
@@ -201,7 +196,6 @@ static void isoc_irq(struct urb *urb)
 static void bulk_irq(struct urb *urb)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
-	struct gspca_frame *frame;
 	int st;
 
 	PDEBUG(D_PACK, "bulk irq");
@@ -212,29 +206,22 @@ static void bulk_irq(struct urb *urb)
 		break;
 	case -ESHUTDOWN:
 		return;		/* disconnection */
-	case -ECONNRESET:
-		urb->status = 0;
-		break;
 	default:
 #ifdef CONFIG_PM
-		if (!gspca_dev->frozen)
+		if (gspca_dev->frozen)
+			return;
 #endif
-			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;
+		PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+		urb->status = 0;
+		goto resubmit;
 	}
 
-	/* check the availability of the frame buffer */
-	frame = gspca_get_i_frame(gspca_dev);
-	if (!frame) {
-		gspca_dev->last_packet_type = DISCARD_PACKET;
-	} else {
-		PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
-		gspca_dev->sd_desc->pkt_scan(gspca_dev,
-					frame,
-					urb->transfer_buffer,
-					urb->actual_length);
-	}
+	PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
+	gspca_dev->sd_desc->pkt_scan(gspca_dev,
+				urb->transfer_buffer,
+				urb->actual_length);
 
+resubmit:
 	/* resubmit the URB */
 	if (gspca_dev->cam.bulk_nurbs != 0) {
 		st = usb_submit_urb(urb, GFP_ATOMIC);
@@ -255,24 +242,27 @@ static void bulk_irq(struct urb *urb)
  * DISCARD_PACKET invalidates the whole frame.
  * On LAST_PACKET, a new frame is returned.
  */
-struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
-				    enum gspca_packet_type packet_type,
-				    struct gspca_frame *frame,
-				    const __u8 *data,
-				    int len)
+void gspca_frame_add(struct gspca_dev *gspca_dev,
+			enum gspca_packet_type packet_type,
+			const u8 *data,
+			int len)
 {
+	struct gspca_frame *frame;
 	int i, j;
 
 	PDEBUG(D_PACK, "add t:%d l:%d",	packet_type, len);
 
+	/* check the availability of the frame buffer */
+	frame = gspca_dev->cur_frame;
+	if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
+					!= V4L2_BUF_FLAG_QUEUED) {
+		gspca_dev->last_packet_type = DISCARD_PACKET;
+		return;
+	}
+
 	/* when start of a new frame, if the current frame buffer
 	 * is not queued, discard the whole frame */
 	if (packet_type == FIRST_PACKET) {
-		if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
-						!= V4L2_BUF_FLAG_QUEUED) {
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-			return frame;
-		}
 		frame->data_end = frame->data;
 		jiffies_to_timeval(get_jiffies_64(),
 				   &frame->v4l2_buf.timestamp);
@@ -280,7 +270,7 @@ struct gspca_frame *gspca_frame_add(stru
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
 		if (packet_type == LAST_PACKET)
 			gspca_dev->last_packet_type = packet_type;
-		return frame;
+		return;
 	}
 
 	/* append the packet to the frame buffer */
@@ -312,9 +302,8 @@ struct gspca_frame *gspca_frame_add(stru
 			i,
 			gspca_dev->fr_o);
 		j = gspca_dev->fr_queue[i];
-		frame = &gspca_dev->frame[j];
+		gspca_dev->cur_frame = &gspca_dev->frame[j];
 	}
-	return frame;
 }
 EXPORT_SYMBOL(gspca_frame_add);
 
@@ -331,7 +320,7 @@ static int gspca_is_compressed(__u32 for
 	return 0;
 }
 
-static void *rvmalloc(unsigned long size)
+static void *rvmalloc(long size)
 {
 	void *mem;
 	unsigned long adr;
@@ -339,7 +328,7 @@ static void *rvmalloc(unsigned long size
 	mem = vmalloc_32(size);
 	if (mem != NULL) {
 		adr = (unsigned long) mem;
-		while ((long) size > 0) {
+		while (size > 0) {
 			SetPageReserved(vmalloc_to_page((void *) adr));
 			adr += PAGE_SIZE;
 			size -= PAGE_SIZE;
@@ -395,6 +384,7 @@ static int frame_alloc(struct gspca_dev
 		frame->v4l2_buf.m.offset = i * frsz;
 	}
 	gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
+	gspca_dev->cur_frame = &gspca_dev->frame[0];
 	gspca_dev->last_packet_type = DISCARD_PACKET;
 	gspca_dev->sequence = 0;
 	return 0;
@@ -475,10 +465,18 @@ static struct usb_host_endpoint *get_ep(
 	xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
 				   : USB_ENDPOINT_XFER_ISOC;
 	i = gspca_dev->alt;			/* previous alt setting */
-	while (--i >= 0) {
-		ep = alt_xfer(&intf->altsetting[i], xfer);
-		if (ep)
-			break;
+	if (gspca_dev->cam.reverse_alts) {
+		while (++i < gspca_dev->nbalt) {
+			ep = alt_xfer(&intf->altsetting[i], xfer);
+			if (ep)
+				break;
+		}
+	} else {
+		while (--i >= 0) {
+			ep = alt_xfer(&intf->altsetting[i], xfer);
+			if (ep)
+				break;
+		}
 	}
 	if (ep == NULL) {
 		err("no transfer endpoint found");
@@ -599,7 +597,11 @@ static int gspca_init_transfer(struct gs
 
 	/* set the higher alternate setting and
 	 * loop until urb submit succeeds */
-	gspca_dev->alt = gspca_dev->nbalt;
+	if (gspca_dev->cam.reverse_alts)
+		gspca_dev->alt = 0;
+	else
+		gspca_dev->alt = gspca_dev->nbalt;
+
 	if (gspca_dev->sd_desc->isoc_init) {
 		ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
 		if (ret < 0)
@@ -641,15 +643,19 @@ static int gspca_init_transfer(struct gs
 		}
 		if (ret >= 0)
 			break;
-		PDEBUG(D_ERR|D_STREAM,
-			"usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
 		gspca_dev->streaming = 0;
 		destroy_urbs(gspca_dev);
-		if (ret != -ENOSPC)
+		if (ret != -ENOSPC) {
+			PDEBUG(D_ERR|D_STREAM,
+				"usb_submit_urb alt %d err %d",
+				gspca_dev->alt, ret);
 			goto out;
+		}
 
 		/* the bandwidth is not wide enough
 		 * negociate or try a lower alternate setting */
+		PDEBUG(D_ERR|D_STREAM,
+			"bandwidth not wide enough - trying again");
 		msleep(20);	/* wait for kill complete */
 		if (gspca_dev->sd_desc->isoc_nego) {
 			ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -761,6 +767,7 @@ static int vidioc_g_register(struct file
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);
 	else
@@ -784,6 +791,7 @@ static int vidioc_s_register(struct file
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);
 	else
@@ -805,6 +813,7 @@ static int vidioc_g_chip_ident(struct fi
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
 	else
@@ -976,11 +985,40 @@ static int vidioc_enum_framesizes(struct
 	return -EINVAL;
 }
 
+static int vidioc_enum_frameintervals(struct file *filp, void *priv,
+				      struct v4l2_frmivalenum *fival)
+{
+	struct gspca_dev *gspca_dev = priv;
+	int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
+	__u32 i;
+
+	if (gspca_dev->cam.mode_framerates == NULL ||
+			gspca_dev->cam.mode_framerates[mode].nrates == 0)
+		return -EINVAL;
+
+	if (fival->pixel_format !=
+			gspca_dev->cam.cam_mode[mode].pixelformat)
+		return -EINVAL;
+
+	for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {
+		if (fival->index == i) {
+			fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+			fival->discrete.numerator = 1;
+			fival->discrete.denominator =
+				gspca_dev->cam.mode_framerates[mode].rates[i];
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 static void gspca_release(struct video_device *vfd)
 {
 	struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
 
-	PDEBUG(D_STREAM, "device released");
+	PDEBUG(D_PROBE, "%s released",
+		video_device_node_name(&gspca_dev->vdev));
 
 	kfree(gspca_dev->usb_buf);
 	kfree(gspca_dev);
@@ -991,7 +1029,7 @@ static int dev_open(struct file *file)
 	struct gspca_dev *gspca_dev;
 	int ret;
 
-	PDEBUG(D_STREAM, "%s open", current->comm);
+	PDEBUG(D_STREAM, "[%s] open", current->comm);
 	gspca_dev = (struct gspca_dev *) video_devdata(file);
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
@@ -1037,7 +1075,7 @@ static int dev_close(struct file *file)
 {
 	struct gspca_dev *gspca_dev = file->private_data;
 
-	PDEBUG(D_STREAM, "%s close", current->comm);
+	PDEBUG(D_STREAM, "[%s] close", current->comm);
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
 	gspca_dev->users--;
@@ -1046,6 +1084,7 @@ static int dev_close(struct file *file)
 	if (gspca_dev->capt_file == file) {
 		if (gspca_dev->streaming) {
 			mutex_lock(&gspca_dev->usb_lock);
+			gspca_dev->usb_err = 0;
 			gspca_stream_off(gspca_dev);
 			mutex_unlock(&gspca_dev->usb_lock);
 		}
@@ -1136,12 +1175,17 @@ static int vidioc_queryctrl(struct file
 				continue;
 			ctrls = &gspca_dev->sd_desc->ctrls[i];
 		}
+		if (ctrls == NULL)
+			return -EINVAL;
 	} else {
 		ctrls = get_ctrl(gspca_dev, id);
+		if (ctrls == NULL)
+			return -EINVAL;
+		i = ctrls - gspca_dev->sd_desc->ctrls;
 	}
-	if (ctrls == NULL)
-		return -EINVAL;
 	memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
+	if (gspca_dev->ctrl_inac & (1 << i))
+		q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 	return 0;
 }
 
@@ -1162,6 +1206,7 @@ static int vidioc_s_ctrl(struct file *fi
 	PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = ctrls->set(gspca_dev, ctrl->value);
 	else
@@ -1183,6 +1228,7 @@ static int vidioc_g_ctrl(struct file *fi
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = ctrls->get(gspca_dev, &ctrl->value);
 	else
@@ -1297,6 +1343,7 @@ static int vidioc_reqbufs(struct file *f
 	/* stop streaming */
 	if (gspca_dev->streaming) {
 		mutex_lock(&gspca_dev->usb_lock);
+		gspca_dev->usb_err = 0;
 		gspca_stream_off(gspca_dev);
 		mutex_unlock(&gspca_dev->usb_lock);
 	}
@@ -1388,6 +1435,7 @@ static int vidioc_streamoff(struct file
 		ret = -ERESTARTSYS;
 		goto out;
 	}
+	gspca_dev->usb_err = 0;
 	gspca_stream_off(gspca_dev);
 	mutex_unlock(&gspca_dev->usb_lock);
 
@@ -1413,6 +1461,7 @@ static int vidioc_g_jpegcomp(struct file
 		return -EINVAL;
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
 	else
@@ -1431,6 +1480,7 @@ static int vidioc_s_jpegcomp(struct file
 		return -EINVAL;
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
+	gspca_dev->usb_err = 0;
 	if (gspca_dev->present)
 		ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
 	else
@@ -1451,6 +1501,7 @@ static int vidioc_g_parm(struct file *fi
 
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
+		gspca_dev->usb_err = 0;
 		if (gspca_dev->present)
 			ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
 								 parm);
@@ -1480,6 +1531,7 @@ static int vidioc_s_parm(struct file *fi
 
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
+		gspca_dev->usb_err = 0;
 		if (gspca_dev->present)
 			ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
 								 parm);
@@ -1651,6 +1703,7 @@ static int frame_wait(struct gspca_dev *
 
 	if (gspca_dev->sd_desc->dq_callback) {
 		mutex_lock(&gspca_dev->usb_lock);
+		gspca_dev->usb_err = 0;
 		if (gspca_dev->present)
 			gspca_dev->sd_desc->dq_callback(gspca_dev);
 		mutex_unlock(&gspca_dev->usb_lock);
@@ -1762,6 +1815,8 @@ static int vidioc_qbuf(struct file *file
 	/* put the buffer in the 'queued' queue */
 	i = gspca_dev->fr_q;
 	gspca_dev->fr_queue[i] = index;
+	if (gspca_dev->fr_i == i)
+		gspca_dev->cur_frame = frame;
 	gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
 	PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
 		gspca_dev->fr_q,
@@ -1963,6 +2018,7 @@ static const struct v4l2_ioctl_ops dev_i
 	.vidioc_g_parm		= vidioc_g_parm,
 	.vidioc_s_parm		= vidioc_s_parm,
 	.vidioc_enum_framesizes = vidioc_enum_framesizes,
+	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	= vidioc_g_register,
 	.vidioc_s_register	= vidioc_s_register,
@@ -1978,7 +2034,6 @@ static struct video_device gspca_templat
 	.fops = &dev_fops,
 	.ioctl_ops = &dev_ioctl_ops,
 	.release = gspca_release,
-	.minor = -1,
 };
 
 /*
@@ -2001,11 +2056,15 @@ int gspca_dev_probe(struct usb_interface
 	PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
 
 	/* we don't handle multi-config cameras */
-	if (dev->descriptor.bNumConfigurations != 1)
+	if (dev->descriptor.bNumConfigurations != 1) {
+		PDEBUG(D_ERR, "Too many config");
 		return -ENODEV;
+	}
 	interface = &intf->cur_altsetting->desc;
-	if (interface->bInterfaceNumber > 0)
+	if (interface->bInterfaceNumber > 0) {
+		PDEBUG(D_ERR, "intf != 0");
 		return -ENODEV;
+	}
 
 	/* create the device */
 	if (dev_size < sizeof *gspca_dev)
@@ -2035,9 +2094,6 @@ int gspca_dev_probe(struct usb_interface
 	ret = sd_desc->init(gspca_dev);
 	if (ret < 0)
 		goto out;
-	ret = gspca_set_alt0(gspca_dev);
-	if (ret < 0)
-		goto out;
 	gspca_set_default_mode(gspca_dev);
 
 	mutex_init(&gspca_dev->usb_lock);
@@ -2059,7 +2115,7 @@ int gspca_dev_probe(struct usb_interface
 	}
 
 	usb_set_intfdata(intf, gspca_dev);
-	PDEBUG(D_PROBE, "probe ok");
+	PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
 	return 0;
 out:
 	kfree(gspca_dev->usb_buf);
@@ -2078,6 +2134,8 @@ void gspca_disconnect(struct usb_interfa
 {
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 
+	PDEBUG(D_PROBE, "%s disconnect",
+		video_device_node_name(&gspca_dev->vdev));
 	mutex_lock(&gspca_dev->usb_lock);
 	gspca_dev->present = 0;
 
@@ -2096,7 +2154,7 @@ void gspca_disconnect(struct usb_interfa
 	/* (this will call gspca_release() immediatly or on last close) */
 	video_unregister_device(&gspca_dev->vdev);
 
-	PDEBUG(D_PROBE, "disconnect complete");
+/*	PDEBUG(D_PROBE, "disconnect complete"); */
 }
 EXPORT_SYMBOL(gspca_disconnect);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gspca.h linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/gspca.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/gspca.h	2010-02-24 13:52:17.000000000 -0500
@@ -45,11 +45,20 @@ extern int gspca_debug;
 /* image transfers */
 #define MAX_NURBS 4		/* max number of URBs */
 
+
+/* used to list framerates supported by a camera mode (resolution) */
+struct framerates {
+	int *rates;
+	int nrates;
+};
+
 /* device information - set at probe time */
 struct cam {
 	int bulk_size;		/* buffer size when image transfer by bulk */
 	const struct v4l2_pix_format *cam_mode;	/* size nmodes */
 	char nmodes;
+	const struct framerates *mode_framerates; /* must have size nmode,
+						   * just like cam_mode */
 	__u8 bulk_nurbs;	/* number of URBs in bulk mode
 				 * - cannot be > MAX_NURBS
 				 * - when 0 and bulk_size != 0 means
@@ -58,6 +67,7 @@ struct cam {
 	u8 npkt;		/* number of packets in an ISOC message
 				 * 0 is the default value: 32 packets */
 	u32 input_flags;	/* value for ENUM_INPUT status flags */
+	char reverse_alts;	/* Alt settings are in high to low order */
 };
 
 struct gspca_dev;
@@ -78,8 +88,7 @@ typedef int (*cam_streamparm_op) (struct
 typedef int (*cam_qmnu_op) (struct gspca_dev *,
 			struct v4l2_querymenu *);
 typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
-				struct gspca_frame *frame,
-				__u8 *data,
+				u8 *data,
 				int len);
 
 struct ctrl {
@@ -142,6 +151,7 @@ struct gspca_dev {
 	struct cam cam;				/* device information */
 	const struct sd_desc *sd_desc;		/* subdriver description */
 	unsigned ctrl_dis;		/* disabled controls (bit map) */
+	unsigned ctrl_inac;		/* inactive controls (bit map) */
 
 #define USB_BUF_SZ 64
 	__u8 *usb_buf;				/* buffer for USB exchanges */
@@ -149,6 +159,7 @@ struct gspca_dev {
 
 	__u8 *frbuf;				/* buffer for nframes */
 	struct gspca_frame frame[GSPCA_MAX_FRAMES];
+	struct gspca_frame *cur_frame;		/* frame beeing filled */
 	__u32 frsz;				/* frame size */
 	char nframes;				/* number of frames */
 	char fr_i;				/* frame being filled */
@@ -169,6 +180,7 @@ struct gspca_dev {
 	struct mutex usb_lock;		/* usb exchange protection */
 	struct mutex read_lock;		/* read protection */
 	struct mutex queue_lock;	/* ISOC queue protection */
+	int usb_err;			/* USB error - protected by usb_lock */
 #ifdef CONFIG_PM
 	char frozen;			/* suspend - resume */
 #endif
@@ -189,11 +201,10 @@ int gspca_dev_probe(struct usb_interface
 		int dev_size,
 		struct module *module);
 void gspca_disconnect(struct usb_interface *intf);
-struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
-				    enum gspca_packet_type packet_type,
-				    struct gspca_frame *frame,
-				    const __u8 *data,
-				    int len);
+void gspca_frame_add(struct gspca_dev *gspca_dev,
+			enum gspca_packet_type packet_type,
+			const u8 *data,
+			int len);
 struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
 #ifdef CONFIG_PM
 int gspca_suspend(struct usb_interface *intf, pm_message_t message);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/jeilinj.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/jeilinj.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/jeilinj.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/jeilinj.c	2010-02-24 13:52:17.000000000 -0500
@@ -181,11 +181,9 @@ static void jlj_dostream(struct work_str
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int blocks_left; /* 0x200-sized blocks remaining in current frame. */
 	int size_in_blocks;
 	int act_len;
-	int discarding = 0; /* true if we failed to get space for frame. */
 	int packet_type;
 	int ret;
 	u8 *buffer;
@@ -196,15 +194,6 @@ static void jlj_dostream(struct work_str
 		goto quit_stream;
 	}
 	while (gspca_dev->present && gspca_dev->streaming) {
-		if (!gspca_dev->present)
-			goto quit_stream;
-		/* Start a new frame, and add the JPEG header, first thing */
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame && !discarding)
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-					dev->jpeg_hdr, JPEG_HDR_SZ);
-		 else
-			discarding = 1;
 		/*
 		 * Now request data block 0. Line 0 reports the size
 		 * to download, in blocks of size 0x200, and also tells the
@@ -222,14 +211,15 @@ static void jlj_dostream(struct work_str
 		size_in_blocks = buffer[0x0a];
 		blocks_left = buffer[0x0a] - 1;
 		PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
-		packet_type = INTER_PACKET;
-		if (frame && !discarding)
-			/* Toss line 0 of data block 0, keep the rest. */
-			gspca_frame_add(gspca_dev, packet_type,
-				frame, buffer + FRAME_HEADER_LEN,
+
+		/* Start a new frame, and add the JPEG header, first thing */
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
+				dev->jpeg_hdr, JPEG_HDR_SZ);
+		/* Toss line 0 of data block 0, keep the rest. */
+		gspca_frame_add(gspca_dev, INTER_PACKET,
+				buffer + FRAME_HEADER_LEN,
 				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
-			else
-				discarding = 1;
+
 		while (blocks_left > 0) {
 			if (!gspca_dev->present)
 				goto quit_stream;
@@ -246,12 +236,8 @@ static void jlj_dostream(struct work_str
 				packet_type = LAST_PACKET;
 			else
 				packet_type = INTER_PACKET;
-			if (frame && !discarding)
-				gspca_frame_add(gspca_dev, packet_type,
-						frame, buffer,
-						JEILINJ_MAX_TRANSFER);
-			else
-				discarding = 1;
+			gspca_frame_add(gspca_dev, packet_type,
+					buffer, JEILINJ_MAX_TRANSFER);
 		}
 	}
 quit_stream:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/Kconfig linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A
 	  module will be called gspca_mr97310a.
 
 config USB_GSPCA_OV519
-	tristate "OV519 USB Camera Driver"
+	tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
 	help
-	  Say Y here if you want support for cameras based on the OV519 chip.
+	  Say Y here if you want support for cameras based on one of these:
+	  OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_ov519.
@@ -103,6 +104,15 @@ config USB_GSPCA_PAC207
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_pac207.
 
+config USB_GSPCA_PAC7302
+	tristate "Pixart PAC7302 USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the PAC7302 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_pac7302.
+
 config USB_GSPCA_PAC7311
 	tristate "Pixart PAC7311 USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -229,6 +239,15 @@ config USB_GSPCA_STK014
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_stk014.
 
+config USB_GSPCA_STV0680
+	tristate "STV0680 USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the STV0680 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_stv0680.
+
 config USB_GSPCA_SUNPLUS
 	tristate "SUNPLUS USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_core.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ int m5602_write_bridge(struct sd *sd, co
 	return (err < 0) ? err : 0;
 }
 
-int m5602_wait_for_i2c(struct sd *sd)
+static int m5602_wait_for_i2c(struct sd *sd)
 {
 	int err;
 	u8 data;
@@ -274,8 +274,7 @@ static int m5602_start_transfer(struct g
 }
 
 static void m5602_urb_complete(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data, int len)
+				u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -295,19 +294,27 @@ static void m5602_urb_complete(struct gs
 		len -= 6;
 
 		/* Complete the last frame (if any) */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-					frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				NULL, 0);
 		sd->frame_count++;
 
 		/* Create a new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 
 		PDEBUG(D_FRAM, "Starting new frame %d",
 		       sd->frame_count);
 
 	} else {
-		int cur_frame_len = frame->data_end - frame->data;
+		struct gspca_frame *frame;
+		int cur_frame_len;
 
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+
+		cur_frame_len = frame->data_end - frame->data;
 		/* Remove urb header */
 		data += 4;
 		len -= 4;
@@ -316,12 +323,12 @@ static void m5602_urb_complete(struct gs
 			PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
 			       sd->frame_count, len);
 
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, len);
 		} else if (frame->v4l2_buf.length - cur_frame_len > 0) {
 			/* Add the remaining data up to frame size */
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame, data,
-					frame->v4l2_buf.length - cur_frame_len);
+			gspca_frame_add(gspca_dev, INTER_PACKET, data,
+				    frame->v4l2_buf.length - cur_frame_len);
 		}
 	}
 }
@@ -381,7 +388,7 @@ static int m5602_probe(struct usb_interf
 			       THIS_MODULE);
 }
 
-void m5602_disconnect(struct usb_interface *intf)
+static void m5602_disconnect(struct usb_interface *intf)
 {
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 	struct sd *sd = (struct sd *) gspca_dev;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2010-02-24 13:52:17.000000000 -0500
@@ -439,7 +439,7 @@ int ov9650_start(struct sd *sd)
 			err = m5602_write_bridge(sd, res_init_ov9650[i][1],
 				res_init_ov9650[i][2]);
 		else if (res_init_ov9650[i][0] == SENSOR) {
-			u8 data = res_init_ov9650[i][2];
+			data = res_init_ov9650[i][2];
 			err = m5602_write_sensor(sd,
 				res_init_ov9650[i][1], &data, 1);
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,12 @@ static
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
 		}
 	}, {
+		.ident = "Fujitsu-Siemens Amilo Xi 2428",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428")
+		}
+	}, {
 		.ident = "Fujitsu-Siemens Amilo Xi 2528",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -525,7 +531,10 @@ static int s5k4aa_set_vflip(struct gspca
 	err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	if (err < 0)
 		return err;
-	data = (data & 0xfe) | !val;
+	if (val)
+		data &= 0xfe;
+	else
+		data |= 0x01;
 	err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	return err;
 }
@@ -570,7 +579,10 @@ static int s5k4aa_set_hflip(struct gspca
 	err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 	if (err < 0)
 		return err;
-	data = (data & 0xfe) | !val;
+	if (val)
+		data &= 0xfe;
+	else
+		data |= 0x01;
 	err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 	return err;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/Makefile linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_MR97310A) += gspc
 obj-$(CONFIG_USB_GSPCA_OV519)    += gspca_ov519.o
 obj-$(CONFIG_USB_GSPCA_OV534)    += gspca_ov534.o
 obj-$(CONFIG_USB_GSPCA_PAC207)   += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7302)  += gspca_pac7302.o
 obj-$(CONFIG_USB_GSPCA_PAC7311)  += gspca_pac7311.o
 obj-$(CONFIG_USB_GSPCA_SN9C20X)  += gspca_sn9c20x.o
 obj-$(CONFIG_USB_GSPCA_SONIXB)   += gspca_sonixb.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_USB_GSPCA_SQ905)    += gspc
 obj-$(CONFIG_USB_GSPCA_SQ905C)   += gspca_sq905c.o
 obj-$(CONFIG_USB_GSPCA_SUNPLUS)  += gspca_sunplus.o
 obj-$(CONFIG_USB_GSPCA_STK014)   += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_STV0680)  += gspca_stv0680.o
 obj-$(CONFIG_USB_GSPCA_T613)     += gspca_t613.o
 obj-$(CONFIG_USB_GSPCA_TV8532)   += gspca_tv8532.o
 obj-$(CONFIG_USB_GSPCA_VC032X)   += gspca_vc032x.o
@@ -37,6 +39,7 @@ gspca_mr97310a-objs := mr97310a.o
 gspca_ov519-objs    := ov519.o
 gspca_ov534-objs    := ov534.o
 gspca_pac207-objs   := pac207.o
+gspca_pac7302-objs  := pac7302.o
 gspca_pac7311-objs  := pac7311.o
 gspca_sn9c20x-objs  := sn9c20x.o
 gspca_sonixb-objs   := sonixb.o
@@ -50,6 +53,7 @@ gspca_spca561-objs  := spca561.o
 gspca_sq905-objs    := sq905.o
 gspca_sq905c-objs   := sq905c.o
 gspca_stk014-objs   := stk014.o
+gspca_stv0680-objs  := stv0680.o
 gspca_sunplus-objs  := sunplus.o
 gspca_t613-objs     := t613.o
 gspca_tv8532-objs   := tv8532.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/mars.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mars.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/mars.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mars.c	2010-02-24 13:52:17.000000000 -0500
@@ -325,8 +325,7 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -348,11 +347,11 @@ static void sd_pkt_scan(struct gspca_dev
 			    || data[5 + p] == 0x67) {
 				PDEBUG(D_PACK, "sof offset: %d len: %d",
 					p, len);
-				frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-							frame, data, p);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						data, p);
 
 				/* put the JPEG header */
-				gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				gspca_frame_add(gspca_dev, FIRST_PACKET,
 					sd->jpeg_hdr, JPEG_HDR_SZ);
 				data += p + 16;
 				len -= p + 16;
@@ -360,7 +359,7 @@ static void sd_pkt_scan(struct gspca_dev
 			}
 		}
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/mr97310a.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mr97310a.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/mr97310a.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/mr97310a.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,23 +1,30 @@
 /*
  * Mars MR97310A library
  *
+ * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
  * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
  *
  * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
  * and for the routines for detecting and classifying these various cameras,
+ * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
+ *
+ * Support for the control settings for the CIF cameras is
+ * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li>
  *
+ * Support for the control settings for the VGA cameras is
  * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
  *
- * Acknowledgements:
+ * Several previously unsupported cameras are owned and have been tested by
+ * Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li> and
+ * Theodore Kilgore <kilgota@auburn.edu> and
+ * Edmond Rodriguez <erodrig_97@yahoo.com> and
+ * Aurelien Jacobs <aurel@gnuage.org>
  *
  * The MR97311A support in gspca/mars.c has been helpful in understanding some
  * of the registers in these cameras.
  *
- * Hans de Goede <hdgoede@redhat.com> and
- * Thomas Kaiser <thomas@kaiser-linux.li>
- * have assisted with their experience. Each of them has also helped by
- * testing a previously unsupported camera.
- *
  * 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
@@ -40,11 +47,9 @@
 #define CAM_TYPE_CIF			0
 #define CAM_TYPE_VGA			1
 
-#define MR97310A_BRIGHTNESS_MIN		-254
-#define MR97310A_BRIGHTNESS_MAX		255
 #define MR97310A_BRIGHTNESS_DEFAULT	0
 
-#define MR97310A_EXPOSURE_MIN		300
+#define MR97310A_EXPOSURE_MIN		0
 #define MR97310A_EXPOSURE_MAX		4095
 #define MR97310A_EXPOSURE_DEFAULT	1000
 
@@ -52,13 +57,17 @@
 #define MR97310A_GAIN_MAX		31
 #define MR97310A_GAIN_DEFAULT		25
 
+#define MR97310A_MIN_CLOCKDIV_MIN	3
+#define MR97310A_MIN_CLOCKDIV_MAX	8
+#define MR97310A_MIN_CLOCKDIV_DEFAULT	3
+
 MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
 	      "Theodore Kilgore <kilgota@auburn.edu>");
 MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
 MODULE_LICENSE("GPL");
 
 /* global parameters */
-int force_sensor_type = -1;
+static int force_sensor_type = -1;
 module_param(force_sensor_type, int, 0644);
 MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
 
@@ -69,10 +78,12 @@ struct sd {
 	u8 cam_type;	/* 0 is CIF and 1 is VGA */
 	u8 sensor_type;	/* We use 0 and 1 here, too. */
 	u8 do_lcd_stop;
+	u8 adj_colors;
 
 	int brightness;
 	u16 exposure;
 	u8 gain;
+	u8 min_clockdiv;
 };
 
 struct sensor_w_data {
@@ -82,26 +93,31 @@ struct sensor_w_data {
 	int len;
 };
 
+static void sd_stopN(struct gspca_dev *gspca_dev);
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
 static void setbrightness(struct gspca_dev *gspca_dev);
 static void setexposure(struct gspca_dev *gspca_dev);
 static void setgain(struct gspca_dev *gspca_dev);
 
 /* V4L2 controls supported by the driver */
 static struct ctrl sd_ctrls[] = {
+/* Separate brightness control description for Argus QuickClix as it has
+   different limits from the other mr97310a cameras */
 	{
-#define BRIGHTNESS_IDX 0
+#define NORM_BRIGHTNESS_IDX 0
 		{
 			.id = V4L2_CID_BRIGHTNESS,
 			.type = V4L2_CTRL_TYPE_INTEGER,
 			.name = "Brightness",
-			.minimum = MR97310A_BRIGHTNESS_MIN,
-			.maximum = MR97310A_BRIGHTNESS_MAX,
+			.minimum = -254,
+			.maximum = 255,
 			.step = 1,
 			.default_value = MR97310A_BRIGHTNESS_DEFAULT,
 			.flags = 0,
@@ -110,7 +126,22 @@ static struct ctrl sd_ctrls[] = {
 		.get = sd_getbrightness,
 	},
 	{
-#define EXPOSURE_IDX 1
+#define ARGUS_QC_BRIGHTNESS_IDX 1
+		{
+			.id = V4L2_CID_BRIGHTNESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Brightness",
+			.minimum = 0,
+			.maximum = 15,
+			.step = 1,
+			.default_value = MR97310A_BRIGHTNESS_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setbrightness,
+		.get = sd_getbrightness,
+	},
+	{
+#define EXPOSURE_IDX 2
 		{
 			.id = V4L2_CID_EXPOSURE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -125,7 +156,7 @@ static struct ctrl sd_ctrls[] = {
 		.get = sd_getexposure,
 	},
 	{
-#define GAIN_IDX 2
+#define GAIN_IDX 3
 		{
 			.id = V4L2_CID_GAIN,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -139,6 +170,21 @@ static struct ctrl sd_ctrls[] = {
 		.set = sd_setgain,
 		.get = sd_getgain,
 	},
+	{
+#define MIN_CLOCKDIV_IDX 4
+		{
+			.id = V4L2_CID_PRIVATE_BASE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Minimum Clock Divider",
+			.minimum = MR97310A_MIN_CLOCKDIV_MIN,
+			.maximum = MR97310A_MIN_CLOCKDIV_MAX,
+			.step = 1,
+			.default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setmin_clockdiv,
+		.get = sd_getmin_clockdiv,
+	},
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -230,12 +276,17 @@ static int sensor_write1(struct gspca_de
 	int rc;
 
 	buf = data;
-	rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+	if (sd->cam_type == CAM_TYPE_CIF) {
+		rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+		confirm_reg = sd->sensor_type ? 0x13 : 0x11;
+	} else {
+		rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
+		confirm_reg = 0x11;
+	}
 	if (rc < 0)
 		return rc;
 
 	buf = 0x01;
-	confirm_reg = sd->sensor_type ? 0x13 : 0x11;
 	rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
 	if (rc < 0)
 		return rc;
@@ -243,18 +294,26 @@ static int sensor_write1(struct gspca_de
 	return 0;
 }
 
-static int cam_get_response16(struct gspca_dev *gspca_dev)
+static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
 {
-	__u8 *data = gspca_dev->usb_buf;
 	int err_code;
 
-	data[0] = 0x21;
+	gspca_dev->usb_buf[0] = reg;
 	err_code = mr_write(gspca_dev, 1);
 	if (err_code < 0)
 		return err_code;
 
 	err_code = mr_read(gspca_dev, 16);
-	return err_code;
+	if (err_code < 0)
+		return err_code;
+
+	if (verbose)
+		PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
+		       gspca_dev->usb_buf[0],
+		       gspca_dev->usb_buf[1],
+		       gspca_dev->usb_buf[2]);
+
+	return 0;
 }
 
 static int zero_the_pointer(struct gspca_dev *gspca_dev)
@@ -264,7 +323,7 @@ static int zero_the_pointer(struct gspca
 	u8 status = 0;
 	int tries = 0;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -275,7 +334,7 @@ static int zero_the_pointer(struct gspca
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -285,7 +344,7 @@ static int zero_the_pointer(struct gspca
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -295,7 +354,7 @@ static int zero_the_pointer(struct gspca
 	if (err_code < 0)
 		return err_code;
 
-	err_code = cam_get_response16(gspca_dev);
+	err_code = cam_get_response16(gspca_dev, 0x21, 0);
 	if (err_code < 0)
 		return err_code;
 
@@ -306,7 +365,7 @@ static int zero_the_pointer(struct gspca
 		return err_code;
 
 	while (status != 0x0a && tries < 256) {
-		err_code = cam_get_response16(gspca_dev);
+		err_code = cam_get_response16(gspca_dev, 0x21, 0);
 		status = data[0];
 		tries++;
 		if (err_code < 0)
@@ -323,7 +382,7 @@ static int zero_the_pointer(struct gspca
 		if (err_code < 0)
 			return err_code;
 
-		err_code = cam_get_response16(gspca_dev);
+		err_code = cam_get_response16(gspca_dev, 0x21, 0);
 		status = data[0];
 		tries++;
 		if (err_code < 0)
@@ -342,89 +401,202 @@ static int zero_the_pointer(struct gspca
 	return 0;
 }
 
-static u8 get_sensor_id(struct gspca_dev *gspca_dev)
+static int stream_start(struct gspca_dev *gspca_dev)
 {
-	int err_code;
-
-	gspca_dev->usb_buf[0] = 0x1e;
-	err_code = mr_write(gspca_dev, 1);
-	if (err_code < 0)
-		return err_code;
+	gspca_dev->usb_buf[0] = 0x01;
+	gspca_dev->usb_buf[1] = 0x01;
+	return mr_write(gspca_dev, 2);
+}
 
-	err_code = mr_read(gspca_dev, 16);
-	if (err_code < 0)
-		return err_code;
+static void stream_stop(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x01;
+	gspca_dev->usb_buf[1] = 0x00;
+	if (mr_write(gspca_dev, 2) < 0)
+		PDEBUG(D_ERR, "Stream Stop failed");
+}
 
-	PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
+static void lcd_stop(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x19;
+	gspca_dev->usb_buf[1] = 0x54;
+	if (mr_write(gspca_dev, 2) < 0)
+		PDEBUG(D_ERR, "LCD Stop failed");
+}
 
-	return gspca_dev->usb_buf[0];
+static int isoc_enable(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->usb_buf[0] = 0x00;
+	gspca_dev->usb_buf[1] = 0x4d;  /* ISOC transfering enable... */
+	return mr_write(gspca_dev, 2);
 }
 
-/* this function is called at probe time */
+/* This function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 		     const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	__u8 *data = gspca_dev->usb_buf;
 	int err_code;
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
+	sd->do_lcd_stop = 0;
 
-	if (id->idProduct == 0x010e) {
+	/* Several of the supported CIF cameras share the same USB ID but
+	 * require different initializations and different control settings.
+	 * The same is true of the VGA cameras. Therefore, we are forced
+	 * to start the initialization process in order to determine which
+	 * camera is present. Some of the supported cameras require the
+	 * memory pointer to be set to 0 as the very first item of business
+	 * or else they will not stream. So we do that immediately.
+	 */
+	err_code = zero_the_pointer(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = stream_start(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
 		sd->cam_type = CAM_TYPE_CIF;
 		cam->nmodes--;
-
-		data[0] = 0x01;
-		data[1] = 0x01;
-		err_code = mr_write(gspca_dev, 2);
+		err_code = cam_get_response16(gspca_dev, 0x06, 1);
 		if (err_code < 0)
 			return err_code;
-
-		msleep(200);
-		data[0] = get_sensor_id(gspca_dev);
 		/*
-		 * Known CIF cameras. If you have another to report, please do
+		 * All but one of the known CIF cameras share the same USB ID,
+		 * but two different init routines are in use, and the control
+		 * settings are different, too. We need to detect which camera
+		 * of the two known varieties is connected!
 		 *
-		 * Name			byte just read		sd->sensor_type
-		 *					reported by
-		 * Sakar Spy-shot	0x28		T. Kilgore	0
-		 * Innovage		0xf5 (unstable)	T. Kilgore	0
-		 * Vivitar Mini		0x53		H. De Goede	0
-		 * Vivitar Mini		0x04 / 0x24	E. Rodriguez	0
-		 * Vivitar Mini		0x08		T. Kilgore	1
-		 * Elta-Media 8212dc	0x23		T. Kaiser	1
-		 * Philips dig. keych.	0x37		T. Kilgore	1
+		 * A list of known CIF cameras follows. They all report either
+		 * 0002 for type 0 or 0003 for type 1.
+		 * If you have another to report, please do
+		 *
+		 * Name		sd->sensor_type		reported by
+		 *
+		 * Sakar Spy-shot	0		T. Kilgore
+		 * Innovage		0		T. Kilgore
+		 * Vivitar Mini		0		H. De Goede
+		 * Vivitar Mini		0		E. Rodriguez
+		 * Vivitar Mini		1		T. Kilgore
+		 * Elta-Media 8212dc	1		T. Kaiser
+		 * Philips dig. keych.	1		T. Kilgore
+		 * Trust Spyc@m 100	1		A. Jacobs
 		 */
-		if ((data[0] & 0x78) == 8 ||
-		    ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
-			sd->sensor_type = 1;
-		else
+		switch (gspca_dev->usb_buf[1]) {
+		case 2:
 			sd->sensor_type = 0;
-
+			break;
+		case 3:
+			sd->sensor_type = 1;
+			break;
+		default:
+			PDEBUG(D_ERR, "Unknown CIF Sensor id : %02x",
+			       gspca_dev->usb_buf[1]);
+			return -ENODEV;
+		}
 		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
 		       sd->sensor_type);
+	} else {
+		sd->cam_type = CAM_TYPE_VGA;
 
-		if (force_sensor_type != -1) {
-			sd->sensor_type = !! force_sensor_type;
-			PDEBUG(D_PROBE, "Forcing sensor type to: %d",
-			       sd->sensor_type);
+		err_code = cam_get_response16(gspca_dev, 0x07, 1);
+		if (err_code < 0)
+			return err_code;
+
+		/*
+		 * Here is a table of the responses to the previous command
+		 * from the known MR97310A VGA cameras.
+		 *
+		 * Name			gspca_dev->usb_buf[]	sd->sensor_type
+		 *				sd->do_lcd_stop
+		 * Aiptek Pencam VGA+	0300		0		1
+		 * ION digital		0350		0		1
+		 * Argus DC-1620	0450		1		0
+		 * Argus QuickClix	0420		1		1
+		 *
+		 * Based upon these results, we assume default settings
+		 * and then correct as necessary, as follows.
+		 *
+		 */
+
+		sd->sensor_type = 1;
+		sd->do_lcd_stop = 0;
+		sd->adj_colors = 0;
+		if ((gspca_dev->usb_buf[0] != 0x03) &&
+					(gspca_dev->usb_buf[0] != 0x04)) {
+			PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
+					gspca_dev->usb_buf[1]);
+			PDEBUG(D_ERR, "Defaults assumed, may not work");
+			PDEBUG(D_ERR, "Please report this");
 		}
+		/* Sakar Digital color needs to be adjusted. */
+		if ((gspca_dev->usb_buf[0] == 0x03) &&
+					(gspca_dev->usb_buf[1] == 0x50))
+			sd->adj_colors = 1;
+		if (gspca_dev->usb_buf[0] == 0x04) {
+			sd->do_lcd_stop = 1;
+			switch (gspca_dev->usb_buf[1]) {
+			case 0x50:
+				sd->sensor_type = 0;
+				PDEBUG(D_PROBE, "sensor_type corrected to 0");
+				break;
+			case 0x20:
+				/* Nothing to do here. */
+				break;
+			default:
+				PDEBUG(D_ERR,
+					"Unknown VGA Sensor id Byte 1: %02x",
+					gspca_dev->usb_buf[1]);
+				PDEBUG(D_ERR,
+					"Defaults assumed, may not work");
+				PDEBUG(D_ERR, "Please report this");
+			}
+		}
+		PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
+		       sd->sensor_type);
+	}
+	/* Stop streaming as we've started it to probe the sensor type. */
+	sd_stopN(gspca_dev);
 
+	if (force_sensor_type != -1) {
+		sd->sensor_type = !!force_sensor_type;
+		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+		       sd->sensor_type);
+	}
+
+	/* Setup controls depending on camera type */
+	if (sd->cam_type == CAM_TYPE_CIF) {
+		/* No brightness for sensor_type 0 */
 		if (sd->sensor_type == 0)
-			gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX);
+		else
+			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << MIN_CLOCKDIV_IDX);
 	} else {
-		sd->cam_type = CAM_TYPE_VGA;
-		PDEBUG(D_PROBE, "MR97310A VGA camera detected");
-		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
-				      (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
+		/* All controls need to be disabled if VGA sensor_type is 0 */
+		if (sd->sensor_type == 0)
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
+					      (1 << ARGUS_QC_BRIGHTNESS_IDX) |
+					      (1 << EXPOSURE_IDX) |
+					      (1 << GAIN_IDX) |
+					      (1 << MIN_CLOCKDIV_IDX);
+		else if (sd->do_lcd_stop)
+			/* Argus QuickClix has different brightness limits */
+			gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX);
+		else
+			gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX);
 	}
 
 	sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
 	sd->exposure = MR97310A_EXPOSURE_DEFAULT;
 	sd->gain = MR97310A_GAIN_DEFAULT;
+	sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
 
 	return 0;
 }
@@ -455,11 +627,6 @@ static int start_cif_cam(struct gspca_de
 	};
 
 	/* Note: Some of the above descriptions guessed from MR97113A driver */
-	data[0] = 0x01;
-	data[1] = 0x01;
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
 
 	memcpy(data, startup_string, 11);
 	if (sd->sensor_type)
@@ -533,22 +700,7 @@ static int start_cif_cam(struct gspca_de
 		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
 					 ARRAY_SIZE(cif_sensor1_init_data));
 	}
-	if (err_code < 0)
-		return err_code;
-
-	setbrightness(gspca_dev);
-	setexposure(gspca_dev);
-	setgain(gspca_dev);
-
-	msleep(200);
-
-	data[0] = 0x00;
-	data[1] = 0x4d;  /* ISOC transfering enable... */
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
-
-	return 0;
+	return err_code;
 }
 
 static int start_vga_cam(struct gspca_dev *gspca_dev)
@@ -558,84 +710,8 @@ static int start_vga_cam(struct gspca_de
 	int err_code;
 	const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
 				       0x00, 0x00, 0x00, 0x50, 0xc0};
-
 	/* What some of these mean is explained in start_cif_cam(), above */
-	sd->sof_read = 0;
-
-	/*
-	 * We have to know which camera we have, because the register writes
-	 * depend upon the camera. This test, run before we actually enter
-	 * the initialization routine, distinguishes most of the cameras, If
-	 * needed, another routine is done later, too.
-	 */
-	memset(data, 0, 16);
-	data[0] = 0x20;
-	err_code = mr_write(gspca_dev, 1);
-	if (err_code < 0)
-		return err_code;
-
-	err_code = mr_read(gspca_dev, 16);
-	if (err_code < 0)
-		return err_code;
-
-	PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
-
-	msleep(200);
-	/*
-	 * Known VGA cameras. If you have another to report, please do
-	 *
-	 * Name			byte just read		sd->sensor_type
-	 *				sd->do_lcd_stop
-	 * Aiptek Pencam VGA+	0x31		0	1
-	 * ION digital		0x31		0	1
-	 * Argus DC-1620	0x30		1	0
-	 * Argus QuickClix	0x30		1	1 (not caught here)
-	 */
-	sd->sensor_type = data[0] & 1;
-	sd->do_lcd_stop = (~data[0]) & 1;
-
-
-
-	/* Streaming setup begins here. */
 
-
-	data[0] = 0x01;
-	data[1] = 0x01;
-	err_code = mr_write(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
-
-	/*
-	 * A second test can now resolve any remaining ambiguity in the
-	 * identification of the camera type,
-	 */
-	if (!sd->sensor_type) {
-		data[0] = get_sensor_id(gspca_dev);
-		if (data[0] == 0x7f) {
-			sd->sensor_type = 1;
-			PDEBUG(D_PROBE, "sensor_type corrected to 1");
-		}
-		msleep(200);
-	}
-
-	if (force_sensor_type != -1) {
-		sd->sensor_type = !! force_sensor_type;
-		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
-		       sd->sensor_type);
-	}
-
-	/*
-	 * Known VGA cameras.
-	 * This test is only run if the previous test returned 0x30, but
-	 * here is the information for all others, too, just for reference.
-	 *
-	 * Name			byte just read		sd->sensor_type
-	 *
-	 * Aiptek Pencam VGA+	0xfb	(this test not run)	1
-	 * ION digital		0xbd	(this test not run)	1
-	 * Argus DC-1620	0xe5	(no change)		0
-	 * Argus QuickClix	0x7f	(reclassified)		1
-	 */
 	memcpy(data, startup_string, 11);
 	if (!sd->sensor_type) {
 		data[5]  = 0x00;
@@ -689,29 +765,44 @@ static int start_vga_cam(struct gspca_de
 		err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
 					 ARRAY_SIZE(vga_sensor0_init_data));
 	} else {	/* sd->sensor_type = 1 */
-		const struct sensor_w_data vga_sensor1_init_data[] = {
+		const struct sensor_w_data color_adj[] = {
 			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
-				0x07, 0x00, 0x01}, 8},
+				/* adjusted blue, green, red gain correct
+				   too much blue from the Sakar Digital */
+				0x05, 0x01, 0x04}, 8}
+		};
+
+		const struct sensor_w_data color_no_adj[] = {
+			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
+				/* default blue, green, red gain settings */
+				0x07, 0x00, 0x01}, 8}
+		};
+
+		const struct sensor_w_data vga_sensor1_init_data[] = {
 			{0x11, 0x04, {0x01}, 1},
-			/*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
-			{0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
+			{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
+			/* These settings may be better for some cameras */
+			/* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
 				0x00, 0x0a}, 7},
 			{0x11, 0x04, {0x01}, 1},
 			{0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
 			{0x11, 0x04, {0x01}, 1},
 			{0, 0, {0}, 0}
 		};
+
+		if (sd->adj_colors)
+			err_code = sensor_write_regs(gspca_dev, color_adj,
+					 ARRAY_SIZE(color_adj));
+		else
+			err_code = sensor_write_regs(gspca_dev, color_no_adj,
+					 ARRAY_SIZE(color_no_adj));
+
+		if (err_code < 0)
+			return err_code;
+
 		err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
 					 ARRAY_SIZE(vga_sensor1_init_data));
 	}
-	if (err_code < 0)
-		return err_code;
-
-	msleep(200);
-	data[0] = 0x00;
-	data[1] = 0x4d;  /* ISOC transfering enable... */
-	err_code = mr_write(gspca_dev, 2);
-
 	return err_code;
 }
 
@@ -719,97 +810,120 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int err_code;
-	struct cam *cam;
 
-	cam = &gspca_dev->cam;
 	sd->sof_read = 0;
-	/*
-	 * Some of the supported cameras require the memory pointer to be
-	 * set to 0, or else they will not stream.
-	 */
-	zero_the_pointer(gspca_dev);
-	msleep(200);
+
+	/* Some of the VGA cameras require the memory pointer
+	 * to be set to 0 again. We have been forced to start the
+	 * stream in sd_config() to detect the hardware, and closed it.
+	 * Thus, we need here to do a completely fresh and clean start. */
+	err_code = zero_the_pointer(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = stream_start(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
 	if (sd->cam_type == CAM_TYPE_CIF) {
 		err_code = start_cif_cam(gspca_dev);
 	} else {
 		err_code = start_vga_cam(gspca_dev);
 	}
-	return err_code;
+	if (err_code < 0)
+		return err_code;
+
+	setbrightness(gspca_dev);
+	setexposure(gspca_dev);
+	setgain(gspca_dev);
+
+	return isoc_enable(gspca_dev);
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int result;
-
-	gspca_dev->usb_buf[0] = 1;
-	gspca_dev->usb_buf[1] = 0;
-	result = mr_write(gspca_dev, 2);
-	if (result < 0)
-		PDEBUG(D_ERR, "Camera Stop failed");
 
+	stream_stop(gspca_dev);
 	/* Not all the cams need this, but even if not, probably a good idea */
 	zero_the_pointer(gspca_dev);
-	if (sd->do_lcd_stop) {
-		gspca_dev->usb_buf[0] = 0x19;
-		gspca_dev->usb_buf[1] = 0x54;
-		result = mr_write(gspca_dev, 2);
-		if (result < 0)
-			PDEBUG(D_ERR, "Camera Stop failed");
-	}
+	if (sd->do_lcd_stop)
+		lcd_stop(gspca_dev);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
-
-	if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+	u8 sign_reg = 7;  /* This reg and the next one used on CIF cams. */
+	u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
+	const u8 quick_clix_table[] =
+	/*	  0  1  2   3  4  5  6  7  8  9  10  11  12  13  14  15 */
+		{ 0, 4, 8, 12, 1, 2, 3, 5, 6, 9,  7, 10, 13, 11, 14, 15};
+	/*
+	 * This control is disabled for CIF type 1 and VGA type 0 cameras.
+	 * It does not quite act linearly for the Argus QuickClix camera,
+	 * but it does control brightness. The values are 0 - 15 only, and
+	 * the table above makes them act consecutively.
+	 */
+	if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
+	    (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
 		return;
 
-	/* Note register 7 is also seen as 0x8x or 0xCx in dumps */
+	if (sd->cam_type == CAM_TYPE_VGA) {
+		sign_reg += 4;
+		value_reg += 4;
+	}
+
+	/* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
 	if (sd->brightness > 0) {
-		sensor_write1(gspca_dev, 7, 0x00);
+		sensor_write1(gspca_dev, sign_reg, 0x00);
 		val = sd->brightness;
 	} else {
-		sensor_write1(gspca_dev, 7, 0x01);
-		val = 257 - sd->brightness;
+		sensor_write1(gspca_dev, sign_reg, 0x01);
+		val = (257 - sd->brightness);
 	}
-	sensor_write1(gspca_dev, 8, val);
+	/* Use lookup table for funky Argus QuickClix brightness */
+	if (sd->do_lcd_stop)
+		val = quick_clix_table[val];
+
+	sensor_write1(gspca_dev, value_reg, val);
 }
 
 static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 val;
+	int exposure;
+	u8 buf[2];
 
 	if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
 		return;
 
-	if (sd->sensor_type) {
-		val = sd->exposure >> 4;
-		sensor_write1(gspca_dev, 3, val);
-		val = sd->exposure & 0xf;
-		sensor_write1(gspca_dev, 4, val);
+	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
+		/* This cam does not like exposure settings < 300,
+		   so scale 0 - 4095 to 300 - 4095 */
+		exposure = (sd->exposure * 9267) / 10000 + 300;
+		sensor_write1(gspca_dev, 3, exposure >> 4);
+		sensor_write1(gspca_dev, 4, exposure & 0x0f);
 	} else {
-		u8 clockdiv;
-		int exposure;
-
 		/* We have both a clock divider and an exposure register.
 		   We first calculate the clock divider, as that determines
-		   the maximum exposure and then we calculayte the exposure
+		   the maximum exposure and then we calculate the exposure
 		   register setting (which goes from 0 - 511).
 
 		   Note our 0 - 4095 exposure is mapped to 0 - 511
 		   milliseconds exposure time */
-		clockdiv = (60 * sd->exposure + 7999) / 8000;
+		u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
 
 		/* Limit framerate to not exceed usb bandwidth */
-		if (clockdiv < 3 && gspca_dev->width >= 320)
-			clockdiv = 3;
+		if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
+			clockdiv = sd->min_clockdiv;
 		else if (clockdiv < 2)
 			clockdiv = 2;
 
+		if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
+			clockdiv = 4;
+
 		/* Frame exposure time in ms = 1000 * clockdiv / 60 ->
 		exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
 		exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
@@ -819,9 +933,10 @@ static void setexposure(struct gspca_dev
 		/* exposure register value is reversed! */
 		exposure = 511 - exposure;
 
+		buf[0] = exposure & 0xff;
+		buf[1] = exposure >> 8;
+		sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
 		sensor_write1(gspca_dev, 0x02, clockdiv);
-		sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
-		sensor_write1(gspca_dev, 0x0f, exposure >> 8);
 	}
 }
 
@@ -832,7 +947,7 @@ static void setgain(struct gspca_dev *gs
 	if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
 		return;
 
-	if (sd->sensor_type) {
+	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
 		sensor_write1(gspca_dev, 0x0e, sd->gain);
 	} else {
 		sensor_write1(gspca_dev, 0x10, sd->gain);
@@ -893,17 +1008,35 @@ static int sd_getgain(struct gspca_dev *
 	return 0;
 }
 
+static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->min_clockdiv = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->min_clockdiv;
+	return 0;
+}
+
 /* Include pac common sof detection functions */
 #include "pac_common.h"
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,    /* target */
-			__u8 *data,                   /* isoc packet */
-			int len)                      /* iso packet length */
+			u8 *data,		/* isoc packet */
+			int len)		/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n;
 
@@ -913,15 +1046,15 @@ static void sd_pkt_scan(struct gspca_dev
 			n -= sizeof pac_sof_marker;
 		else
 			n = 0;
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					data, n);
 		/* Start next frame. */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			pac_sof_marker, sizeof pac_sof_marker);
 		len -= sof - data;
 		data = sof;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 /* sub-driver description */
@@ -938,6 +1071,7 @@ static const struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x08ca, 0x0110)},	/* Trust Spyc@m 100 */
 	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
 	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */
 	{USB_DEVICE(0x093a, 0x010e)},	/* All known MR97310A CIF cams */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/ov519.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov519.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/ov519.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov519.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,14 +2,19 @@
  * OV519 driver
  *
  * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
  *
  * This module is adapted from the ov51x-jpeg package, which itself
  * was adapted from the ov511 driver.
  *
  * Original copyright for the ov511 driver is:
  *
- * Copyright (c) 1999-2004 Mark W. McClelland
+ * Copyright (c) 1999-2006 Mark W. McClelland
  * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
+ * Many improvements by Bret Wallach <bwallac1@san.rr.com>
+ * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
+ * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
+ * Changes by Claudio Matsuoka <claudio@conectiva.com>
  *
  * ov51x-jpeg original copyright is:
  *
@@ -58,6 +63,8 @@ struct sd {
 #define BRIDGE_OV518		2
 #define BRIDGE_OV518PLUS	3
 #define BRIDGE_OV519		4
+#define BRIDGE_OVFX2		5
+#define BRIDGE_W9968CF		6
 #define BRIDGE_MASK		7
 
 	char invert_led;
@@ -73,6 +80,10 @@ struct sd {
 	__u8 vflip;
 	__u8 autobrightness;
 	__u8 freq;
+	__u8 quality;
+#define QUALITY_MIN 50
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
 
 	__u8 stopped;		/* Streaming is temporarily paused */
 
@@ -81,17 +92,31 @@ struct sd {
 
 	char sensor;		/* Type of image sensor chip (SEN_*) */
 #define SEN_UNKNOWN 0
-#define SEN_OV6620 1
-#define SEN_OV6630 2
-#define SEN_OV66308AF 3
-#define SEN_OV7610 4
-#define SEN_OV7620 5
-#define SEN_OV7640 6
-#define SEN_OV7670 7
-#define SEN_OV76BE 8
-#define SEN_OV8610 9
+#define SEN_OV2610 1
+#define SEN_OV3610 2
+#define SEN_OV6620 3
+#define SEN_OV6630 4
+#define SEN_OV66308AF 5
+#define SEN_OV7610 6
+#define SEN_OV7620 7
+#define SEN_OV7640 8
+#define SEN_OV7670 9
+#define SEN_OV76BE 10
+#define SEN_OV8610 11
+
+	u8 sensor_addr;
+	int sensor_width;
+	int sensor_height;
+	int sensor_reg_cache[256];
+
+	u8 *jpeg_hdr;
 };
 
+/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
+   the ov sensors which is already present here. When we have the time we
+   really should move the sensor drivers to v4l2 sub drivers. */
+#include "w996Xcf.c"
+
 /* V4L2 controls supported by the driver */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -345,6 +370,75 @@ static const struct v4l2_pix_format ov51
 		.priv = 0},
 };
 
+static const struct v4l2_pix_format ovfx2_vga_mode[] = {
+	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ovfx2_cif_mode[] = {
+	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3},
+	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 176 * 144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
+	{1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB},
+};
+static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
+	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1024,
+		.sizeimage = 1024 * 768,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+	{2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 2048,
+		.sizeimage = 2048 * 1536,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+
 /* Registers common to OV511 / OV518 */
 #define R51x_FIFO_PSIZE			0x30	/* 2 bytes wide w/ OV518(+) */
 #define R51x_SYS_RESET          	0x50
@@ -406,6 +500,30 @@ static const struct v4l2_pix_format ov51
 
 #define OV511_ENDPOINT_ADDRESS  1	/* Isoc endpoint number */
 
+/*
+ * The FX2 chip does not give us a zero length read at end of frame.
+ * It does, however, give a short read at the end of a frame, if
+ * neccessary, rather than run two frames together.
+ *
+ * By choosing the right bulk transfer size, we are guaranteed to always
+ * get a short read for the last read of each frame.  Frame sizes are
+ * always a composite number (width * height, or a multiple) so if we
+ * choose a prime number, we are guaranteed that the last read of a
+ * frame will be short.
+ *
+ * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
+ * otherwise EOVERFLOW "babbling" errors occur.  I have not been able
+ * to figure out why.  [PMiller]
+ *
+ * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
+ *
+ * It isn't enough to know the number of bytes per frame, in case we
+ * have data dropouts or buffer overruns (even though the FX2 double
+ * buffers, there are some pretty strict real time constraints for
+ * isochronous transfer for larger frame sizes).
+ */
+#define OVFX2_BULK_SIZE (13 * 4096)
+
 /* I2C registers */
 #define R51x_I2C_W_SID		0x41
 #define R51x_I2C_SADDR_3	0x42
@@ -413,9 +531,11 @@ static const struct v4l2_pix_format ov51
 #define R51x_I2C_R_SID		0x44
 #define R51x_I2C_DATA		0x45
 #define R518_I2C_CTL		0x47	/* OV518(+) only */
+#define OVFX2_I2C_ADDR		0x00
 
 /* I2C ADDRESSES */
 #define OV7xx0_SID   0x42
+#define OV_HIRES_SID 0x60		/* OV9xxx / OV2xxx / OV3xxx */
 #define OV8xx0_SID   0xa0
 #define OV6xx0_SID   0xc0
 
@@ -508,6 +628,696 @@ struct ov_i2c_regvals {
 	__u8 val;
 };
 
+/* Settings for OV2610 camera chip */
+static const struct ov_i2c_regvals norm_2610[] =
+{
+	{ 0x12, 0x80 },	/* reset */
+};
+
+static const struct ov_i2c_regvals norm_3620b[] =
+{
+	/*
+	 * From the datasheet: "Note that after writing to register COMH
+	 * (0x12) to change the sensor mode, registers related to the
+	 * sensor’s cropping window will be reset back to their default
+	 * values."
+	 *
+	 * "wait 4096 external clock ... to make sure the sensor is
+	 * stable and ready to access registers" i.e. 160us at 24MHz
+	 */
+
+	{ 0x12, 0x80 }, /* COMH reset */
+	{ 0x12, 0x00 }, /* QXGA, master */
+
+	/*
+	 * 11 CLKRC "Clock Rate Control"
+	 * [7] internal frequency doublers: on
+	 * [6] video port mode: master
+	 * [5:0] clock divider: 1
+	 */
+	{ 0x11, 0x80 },
+
+	/*
+	 * 13 COMI "Common Control I"
+	 *                  = 192 (0xC0) 11000000
+	 *    COMI[7] "AEC speed selection"
+	 *                  =   1 (0x01) 1....... "Faster AEC correction"
+	 *    COMI[6] "AEC speed step selection"
+	 *                  =   1 (0x01) .1...... "Big steps, fast"
+	 *    COMI[5] "Banding filter on off"
+	 *                  =   0 (0x00) ..0..... "Off"
+	 *    COMI[4] "Banding filter option"
+	 *                  =   0 (0x00) ...0.... "Main clock is 48 MHz and
+	 *                                         the PLL is ON"
+	 *    COMI[3] "Reserved"
+	 *                  =   0 (0x00) ....0...
+	 *    COMI[2] "AGC auto manual control selection"
+	 *                  =   0 (0x00) .....0.. "Manual"
+	 *    COMI[1] "AWB auto manual control selection"
+	 *                  =   0 (0x00) ......0. "Manual"
+	 *    COMI[0] "Exposure control"
+	 *                  =   0 (0x00) .......0 "Manual"
+	 */
+	{ 0x13, 0xC0 },
+
+	/*
+	 * 09 COMC "Common Control C"
+	 *                  =   8 (0x08) 00001000
+	 *    COMC[7:5] "Reserved"
+	 *                  =   0 (0x00) 000.....
+	 *    COMC[4] "Sleep Mode Enable"
+	 *                  =   0 (0x00) ...0.... "Normal mode"
+	 *    COMC[3:2] "Sensor sampling reset timing selection"
+	 *                  =   2 (0x02) ....10.. "Longer reset time"
+	 *    COMC[1:0] "Output drive current select"
+	 *                  =   0 (0x00) ......00 "Weakest"
+	 */
+	{ 0x09, 0x08 },
+
+	/*
+	 * 0C COMD "Common Control D"
+	 *                  =   8 (0x08) 00001000
+	 *    COMD[7] "Reserved"
+	 *                  =   0 (0x00) 0.......
+	 *    COMD[6] "Swap MSB and LSB at the output port"
+	 *                  =   0 (0x00) .0...... "False"
+	 *    COMD[5:3] "Reserved"
+	 *                  =   1 (0x01) ..001...
+	 *    COMD[2] "Output Average On Off"
+	 *                  =   0 (0x00) .....0.. "Output Normal"
+	 *    COMD[1] "Sensor precharge voltage selection"
+	 *                  =   0 (0x00) ......0. "Selects internal
+	 *                                         reference precharge
+	 *                                         voltage"
+	 *    COMD[0] "Snapshot option"
+	 *                  =   0 (0x00) .......0 "Enable live video output
+	 *                                         after snapshot sequence"
+	 */
+	{ 0x0c, 0x08 },
+
+	/*
+	 * 0D COME "Common Control E"
+	 *                  = 161 (0xA1) 10100001
+	 *    COME[7] "Output average option"
+	 *                  =   1 (0x01) 1....... "Output average of 4 pixels"
+	 *    COME[6] "Anti-blooming control"
+	 *                  =   0 (0x00) .0...... "Off"
+	 *    COME[5:3] "Reserved"
+	 *                  =   4 (0x04) ..100...
+	 *    COME[2] "Clock output power down pin status"
+	 *                  =   0 (0x00) .....0.. "Tri-state data output pin
+	 *                                         on power down"
+	 *    COME[1] "Data output pin status selection at power down"
+	 *                  =   0 (0x00) ......0. "Tri-state VSYNC, PCLK,
+	 *                                         HREF, and CHSYNC pins on
+	 *                                         power down"
+	 *    COME[0] "Auto zero circuit select"
+	 *                  =   1 (0x01) .......1 "On"
+	 */
+	{ 0x0d, 0xA1 },
+
+	/*
+	 * 0E COMF "Common Control F"
+	 *                  = 112 (0x70) 01110000
+	 *    COMF[7] "System clock selection"
+	 *                  =   0 (0x00) 0....... "Use 24 MHz system clock"
+	 *    COMF[6:4] "Reserved"
+	 *                  =   7 (0x07) .111....
+	 *    COMF[3] "Manual auto negative offset canceling selection"
+	 *                  =   0 (0x00) ....0... "Auto detect negative
+	 *                                         offset and cancel it"
+	 *    COMF[2:0] "Reserved"
+	 *                  =   0 (0x00) .....000
+	 */
+	{ 0x0e, 0x70 },
+
+	/*
+	 * 0F COMG "Common Control G"
+	 *                  =  66 (0x42) 01000010
+	 *    COMG[7] "Optical black output selection"
+	 *                  =   0 (0x00) 0....... "Disable"
+	 *    COMG[6] "Black level calibrate selection"
+	 *                  =   1 (0x01) .1...... "Use optical black pixels
+	 *                                         to calibrate"
+	 *    COMG[5:4] "Reserved"
+	 *                  =   0 (0x00) ..00....
+	 *    COMG[3] "Channel offset adjustment"
+	 *                  =   0 (0x00) ....0... "Disable offset adjustment"
+	 *    COMG[2] "ADC black level calibration option"
+	 *                  =   0 (0x00) .....0.. "Use B/G line and G/R
+	 *                                         line to calibrate each
+	 *                                         channel's black level"
+	 *    COMG[1] "Reserved"
+	 *                  =   1 (0x01) ......1.
+	 *    COMG[0] "ADC black level calibration enable"
+	 *                  =   0 (0x00) .......0 "Disable"
+	 */
+	{ 0x0f, 0x42 },
+
+	/*
+	 * 14 COMJ "Common Control J"
+	 *                  = 198 (0xC6) 11000110
+	 *    COMJ[7:6] "AGC gain ceiling"
+	 *                  =   3 (0x03) 11...... "8x"
+	 *    COMJ[5:4] "Reserved"
+	 *                  =   0 (0x00) ..00....
+	 *    COMJ[3] "Auto banding filter"
+	 *                  =   0 (0x00) ....0... "Banding filter is always
+	 *                                         on off depending on
+	 *                                         COMI[5] setting"
+	 *    COMJ[2] "VSYNC drop option"
+	 *                  =   1 (0x01) .....1.. "SYNC is dropped if frame
+	 *                                         data is dropped"
+	 *    COMJ[1] "Frame data drop"
+	 *                  =   1 (0x01) ......1. "Drop frame data if
+	 *                                         exposure is not within
+	 *                                         tolerance.  In AEC mode,
+	 *                                         data is normally dropped
+	 *                                         when data is out of
+	 *                                         range."
+	 *    COMJ[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x14, 0xC6 },
+
+	/*
+	 * 15 COMK "Common Control K"
+	 *                  =   2 (0x02) 00000010
+	 *    COMK[7] "CHSYNC pin output swap"
+	 *                  =   0 (0x00) 0....... "CHSYNC"
+	 *    COMK[6] "HREF pin output swap"
+	 *                  =   0 (0x00) .0...... "HREF"
+	 *    COMK[5] "PCLK output selection"
+	 *                  =   0 (0x00) ..0..... "PCLK always output"
+	 *    COMK[4] "PCLK edge selection"
+	 *                  =   0 (0x00) ...0.... "Data valid on falling edge"
+	 *    COMK[3] "HREF output polarity"
+	 *                  =   0 (0x00) ....0... "positive"
+	 *    COMK[2] "Reserved"
+	 *                  =   0 (0x00) .....0..
+	 *    COMK[1] "VSYNC polarity"
+	 *                  =   1 (0x01) ......1. "negative"
+	 *    COMK[0] "HSYNC polarity"
+	 *                  =   0 (0x00) .......0 "positive"
+	 */
+	{ 0x15, 0x02 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =   9 (0x09) 00001001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   0 (0x00) ...0.... "normal current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x09 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  80 (0x50) 01010000
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x34, 0x50 },
+
+	/*
+	 * 36 VCHG "Sensor Precharge Voltage Control"
+	 *                  =   0 (0x00) 00000000
+	 *    VCHG[7] "Reserved"
+	 *                  =   0 (0x00) 0.......
+	 *    VCHG[6:4] "Sensor precharge voltage control"
+	 *                  =   0 (0x00) .000....
+	 *    VCHG[3:0] "Sensor array common reference"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x36, 0x00 },
+
+	/*
+	 * 37 ADC "ADC Reference Control"
+	 *                  =   4 (0x04) 00000100
+	 *    ADC[7:4] "Reserved"
+	 *                  =   0 (0x00) 0000....
+	 *    ADC[3] "ADC input signal range"
+	 *                  =   0 (0x00) ....0... "Input signal 1.0x"
+	 *    ADC[2:0] "ADC range control"
+	 *                  =   4 (0x04) .....100
+	 */
+	{ 0x37, 0x04 },
+
+	/*
+	 * 38 ACOM "Analog Common Ground"
+	 *                  =  82 (0x52) 01010010
+	 *    ACOM[7] "Analog gain control"
+	 *                  =   0 (0x00) 0....... "Gain 1x"
+	 *    ACOM[6] "Analog black level calibration"
+	 *                  =   1 (0x01) .1...... "On"
+	 *    ACOM[5:0] "Reserved"
+	 *                  =  18 (0x12) ..010010
+	 */
+	{ 0x38, 0x52 },
+
+	/*
+	 * 3A FREFA "Internal Reference Adjustment"
+	 *                  =   0 (0x00) 00000000
+	 *    FREFA[7:0] "Range"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3a, 0x00 },
+
+	/*
+	 * 3C FVOPT "Internal Reference Adjustment"
+	 *                  =  31 (0x1F) 00011111
+	 *    FVOPT[7:0] "Range"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x3c, 0x1F },
+
+	/*
+	 * 44 Undocumented  =   0 (0x00) 00000000
+	 *    44[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x44, 0x00 },
+
+	/*
+	 * 40 Undocumented  =   0 (0x00) 00000000
+	 *    40[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x40, 0x00 },
+
+	/*
+	 * 41 Undocumented  =   0 (0x00) 00000000
+	 *    41[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x41, 0x00 },
+
+	/*
+	 * 42 Undocumented  =   0 (0x00) 00000000
+	 *    42[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x42, 0x00 },
+
+	/*
+	 * 43 Undocumented  =   0 (0x00) 00000000
+	 *    43[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x43, 0x00 },
+
+	/*
+	 * 45 Undocumented  = 128 (0x80) 10000000
+	 *    45[7:0] "It's a secret"
+	 *                  = 128 (0x80) 10000000
+	 */
+	{ 0x45, 0x80 },
+
+	/*
+	 * 48 Undocumented  = 192 (0xC0) 11000000
+	 *    48[7:0] "It's a secret"
+	 *                  = 192 (0xC0) 11000000
+	 */
+	{ 0x48, 0xC0 },
+
+	/*
+	 * 49 Undocumented  =  25 (0x19) 00011001
+	 *    49[7:0] "It's a secret"
+	 *                  =  25 (0x19) 00011001
+	 */
+	{ 0x49, 0x19 },
+
+	/*
+	 * 4B Undocumented  = 128 (0x80) 10000000
+	 *    4B[7:0] "It's a secret"
+	 *                  = 128 (0x80) 10000000
+	 */
+	{ 0x4B, 0x80 },
+
+	/*
+	 * 4D Undocumented  = 196 (0xC4) 11000100
+	 *    4D[7:0] "It's a secret"
+	 *                  = 196 (0xC4) 11000100
+	 */
+	{ 0x4D, 0xC4 },
+
+	/*
+	 * 35 VREF "Reference Voltage Control"
+	 *                  =  76 (0x4C) 01001100
+	 *    VREF[7:5] "Column high reference control"
+	 *                  =   2 (0x02) 010..... "higher voltage"
+	 *    VREF[4:2] "Column low reference control"
+	 *                  =   3 (0x03) ...011.. "Highest voltage"
+	 *    VREF[1:0] "Reserved"
+	 *                  =   0 (0x00) ......00
+	 */
+	{ 0x35, 0x4C },
+
+	/*
+	 * 3D Undocumented  =   0 (0x00) 00000000
+	 *    3D[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3D, 0x00 },
+
+	/*
+	 * 3E Undocumented  =   0 (0x00) 00000000
+	 *    3E[7:0] "It's a secret"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3E, 0x00 },
+
+	/*
+	 * 3B FREFB "Internal Reference Adjustment"
+	 *                  =  24 (0x18) 00011000
+	 *    FREFB[7:0] "Range"
+	 *                  =  24 (0x18) 00011000
+	 */
+	{ 0x3b, 0x18 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =  25 (0x19) 00011001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   1 (0x01) ...1.... "double current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x19 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  90 (0x5A) 01011010
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =  10 (0x0A) ....1010
+	 */
+	{ 0x34, 0x5A },
+
+	/*
+	 * 3B FREFB "Internal Reference Adjustment"
+	 *                  =   0 (0x00) 00000000
+	 *    FREFB[7:0] "Range"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x3b, 0x00 },
+
+	/*
+	 * 33 CHLF "Current Control"
+	 *                  =   9 (0x09) 00001001
+	 *    CHLF[7:6] "Sensor current control"
+	 *                  =   0 (0x00) 00......
+	 *    CHLF[5] "Sensor current range control"
+	 *                  =   0 (0x00) ..0..... "normal range"
+	 *    CHLF[4] "Sensor current"
+	 *                  =   0 (0x00) ...0.... "normal current"
+	 *    CHLF[3] "Sensor buffer current control"
+	 *                  =   1 (0x01) ....1... "half current"
+	 *    CHLF[2] "Column buffer current control"
+	 *                  =   0 (0x00) .....0.. "normal current"
+	 *    CHLF[1] "Analog DSP current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 *    CHLF[1] "ADC current control"
+	 *                  =   0 (0x00) ......0. "normal current"
+	 */
+	{ 0x33, 0x09 },
+
+	/*
+	 * 34 VBLM "Blooming Control"
+	 *                  =  80 (0x50) 01010000
+	 *    VBLM[7] "Hard soft reset switch"
+	 *                  =   0 (0x00) 0....... "Hard reset"
+	 *    VBLM[6:4] "Blooming voltage selection"
+	 *                  =   5 (0x05) .101....
+	 *    VBLM[3:0] "Sensor current control"
+	 *                  =   0 (0x00) ....0000
+	 */
+	{ 0x34, 0x50 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =  64 (0x40) 01000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   4 (0x04) .100.... "XGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x40 },
+
+	/*
+	 * 17 HREFST "Horizontal window start"
+	 *                  =  31 (0x1F) 00011111
+	 *    HREFST[7:0] "Horizontal window start, 8 MSBs"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x17, 0x1F },
+
+	/*
+	 * 18 HREFEND "Horizontal window end"
+	 *                  =  95 (0x5F) 01011111
+	 *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
+	 *                  =  95 (0x5F) 01011111
+	 */
+	{ 0x18, 0x5F },
+
+	/*
+	 * 19 VSTRT "Vertical window start"
+	 *                  =   0 (0x00) 00000000
+	 *    VSTRT[7:0] "Vertical Window Start, 8 MSBs"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x19, 0x00 },
+
+	/*
+	 * 1A VEND "Vertical window end"
+	 *                  =  96 (0x60) 01100000
+	 *    VEND[7:0] "Vertical Window End, 8 MSBs"
+	 *                  =  96 (0x60) 01100000
+	 */
+	{ 0x1a, 0x60 },
+
+	/*
+	 * 32 COMM "Common Control M"
+	 *                  =  18 (0x12) 00010010
+	 *    COMM[7:6] "Pixel clock divide option"
+	 *                  =   0 (0x00) 00...... "/1"
+	 *    COMM[5:3] "Horizontal window end position, 3 LSBs"
+	 *                  =   2 (0x02) ..010...
+	 *    COMM[2:0] "Horizontal window start position, 3 LSBs"
+	 *                  =   2 (0x02) .....010
+	 */
+	{ 0x32, 0x12 },
+
+	/*
+	 * 03 COMA "Common Control A"
+	 *                  =  74 (0x4A) 01001010
+	 *    COMA[7:4] "AWB Update Threshold"
+	 *                  =   4 (0x04) 0100....
+	 *    COMA[3:2] "Vertical window end line control 2 LSBs"
+	 *                  =   2 (0x02) ....10..
+	 *    COMA[1:0] "Vertical window start line control 2 LSBs"
+	 *                  =   2 (0x02) ......10
+	 */
+	{ 0x03, 0x4A },
+
+	/*
+	 * 11 CLKRC "Clock Rate Control"
+	 *                  = 128 (0x80) 10000000
+	 *    CLKRC[7] "Internal frequency doublers on off seclection"
+	 *                  =   1 (0x01) 1....... "On"
+	 *    CLKRC[6] "Digital video master slave selection"
+	 *                  =   0 (0x00) .0...... "Master mode, sensor
+	 *                                         provides PCLK"
+	 *    CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
+	 *                  =   0 (0x00) ..000000
+	 */
+	{ 0x11, 0x80 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =   0 (0x00) 00000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   0 (0x00) .000.... "QXGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x00 },
+
+	/*
+	 * 12 COMH "Common Control H"
+	 *                  =  64 (0x40) 01000000
+	 *    COMH[7] "SRST"
+	 *                  =   0 (0x00) 0....... "No-op"
+	 *    COMH[6:4] "Resolution selection"
+	 *                  =   4 (0x04) .100.... "XGA"
+	 *    COMH[3] "Master slave selection"
+	 *                  =   0 (0x00) ....0... "Master mode"
+	 *    COMH[2] "Internal B/R channel option"
+	 *                  =   0 (0x00) .....0.. "B/R use same channel"
+	 *    COMH[1] "Color bar test pattern"
+	 *                  =   0 (0x00) ......0. "Off"
+	 *    COMH[0] "Reserved"
+	 *                  =   0 (0x00) .......0
+	 */
+	{ 0x12, 0x40 },
+
+	/*
+	 * 17 HREFST "Horizontal window start"
+	 *                  =  31 (0x1F) 00011111
+	 *    HREFST[7:0] "Horizontal window start, 8 MSBs"
+	 *                  =  31 (0x1F) 00011111
+	 */
+	{ 0x17, 0x1F },
+
+	/*
+	 * 18 HREFEND "Horizontal window end"
+	 *                  =  95 (0x5F) 01011111
+	 *    HREFEND[7:0] "Horizontal Window End, 8 MSBs"
+	 *                  =  95 (0x5F) 01011111
+	 */
+	{ 0x18, 0x5F },
+
+	/*
+	 * 19 VSTRT "Vertical window start"
+	 *                  =   0 (0x00) 00000000
+	 *    VSTRT[7:0] "Vertical Window Start, 8 MSBs"
+	 *                  =   0 (0x00) 00000000
+	 */
+	{ 0x19, 0x00 },
+
+	/*
+	 * 1A VEND "Vertical window end"
+	 *                  =  96 (0x60) 01100000
+	 *    VEND[7:0] "Vertical Window End, 8 MSBs"
+	 *                  =  96 (0x60) 01100000
+	 */
+	{ 0x1a, 0x60 },
+
+	/*
+	 * 32 COMM "Common Control M"
+	 *                  =  18 (0x12) 00010010
+	 *    COMM[7:6] "Pixel clock divide option"
+	 *                  =   0 (0x00) 00...... "/1"
+	 *    COMM[5:3] "Horizontal window end position, 3 LSBs"
+	 *                  =   2 (0x02) ..010...
+	 *    COMM[2:0] "Horizontal window start position, 3 LSBs"
+	 *                  =   2 (0x02) .....010
+	 */
+	{ 0x32, 0x12 },
+
+	/*
+	 * 03 COMA "Common Control A"
+	 *                  =  74 (0x4A) 01001010
+	 *    COMA[7:4] "AWB Update Threshold"
+	 *                  =   4 (0x04) 0100....
+	 *    COMA[3:2] "Vertical window end line control 2 LSBs"
+	 *                  =   2 (0x02) ....10..
+	 *    COMA[1:0] "Vertical window start line control 2 LSBs"
+	 *                  =   2 (0x02) ......10
+	 */
+	{ 0x03, 0x4A },
+
+	/*
+	 * 02 RED "Red Gain Control"
+	 *                  = 175 (0xAF) 10101111
+	 *    RED[7] "Action"
+	 *                  =   1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
+	 *    RED[6:0] "Value"
+	 *                  =  47 (0x2F) .0101111
+	 */
+	{ 0x02, 0xAF },
+
+	/*
+	 * 2D ADDVSL "VSYNC Pulse Width"
+	 *                  = 210 (0xD2) 11010010
+	 *    ADDVSL[7:0] "VSYNC pulse width, LSB"
+	 *                  = 210 (0xD2) 11010010
+	 */
+	{ 0x2d, 0xD2 },
+
+	/*
+	 * 00 GAIN          =  24 (0x18) 00011000
+	 *    GAIN[7:6] "Reserved"
+	 *                  =   0 (0x00) 00......
+	 *    GAIN[5] "Double"
+	 *                  =   0 (0x00) ..0..... "False"
+	 *    GAIN[4] "Double"
+	 *                  =   1 (0x01) ...1.... "True"
+	 *    GAIN[3:0] "Range"
+	 *                  =   8 (0x08) ....1000
+	 */
+	{ 0x00, 0x18 },
+
+	/*
+	 * 01 BLUE "Blue Gain Control"
+	 *                  = 240 (0xF0) 11110000
+	 *    BLUE[7] "Action"
+	 *                  =   1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
+	 *    BLUE[6:0] "Value"
+	 *                  = 112 (0x70) .1110000
+	 */
+	{ 0x01, 0xF0 },
+
+	/*
+	 * 10 AEC "Automatic Exposure Control"
+	 *                  =  10 (0x0A) 00001010
+	 *    AEC[7:0] "Automatic Exposure Control, 8 MSBs"
+	 *                  =  10 (0x0A) 00001010
+	 */
+	{ 0x10, 0x0A },
+
+	{ 0xE1, 0x67 },
+	{ 0xE3, 0x03 },
+	{ 0xE4, 0x26 },
+	{ 0xE5, 0x3E },
+	{ 0xF8, 0x01 },
+	{ 0xFF, 0x01 },
+};
+
 static const struct ov_i2c_regvals norm_6x20[] = {
 	{ 0x12, 0x80 }, /* reset */
 	{ 0x11, 0x01 },
@@ -678,6 +1488,7 @@ static const struct ov_i2c_regvals norm_
 };
 
 static const struct ov_i2c_regvals norm_7620[] = {
+	{ 0x12, 0x80 },		/* reset */
 	{ 0x00, 0x00 },		/* gain */
 	{ 0x01, 0x80 },		/* blue gain */
 	{ 0x02, 0x80 },		/* red gain */
@@ -1042,10 +1853,28 @@ static unsigned char ov7670_abs_to_sm(un
 }
 
 /* Write a OV519 register */
-static int reg_w(struct sd *sd, __u16 index, __u8 value)
+static int reg_w(struct sd *sd, __u16 index, __u16 value)
 {
-	int ret;
-	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
+	int ret, req = 0;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		req = 2;
+		break;
+	case BRIDGE_OVFX2:
+		req = 0x0a;
+		/* fall through */
+	case BRIDGE_W9968CF:
+		ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+			req,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, index, NULL, 0, 500);
+		goto leave;
+	default:
+		req = 1;
+	}
 
 	sd->gspca_dev.usb_buf[0] = value;
 	ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1054,17 +1883,35 @@ static int reg_w(struct sd *sd, __u16 in
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			sd->gspca_dev.usb_buf, 1, 500);
-	if (ret < 0)
-		PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
-	return ret;
+leave:
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
+		       value, index);
+		return ret;
+	}
+
+	PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
+	return 0;
 }
 
-/* Read from a OV519 register */
+/* Read from a OV519 register, note not valid for the w9968cf!! */
 /* returns: negative is error, pos or zero is data */
 static int reg_r(struct sd *sd, __u16 index)
 {
 	int ret;
-	int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
+	int req;
+
+	switch (sd->bridge) {
+	case BRIDGE_OV511:
+	case BRIDGE_OV511PLUS:
+		req = 3;
+		break;
+	case BRIDGE_OVFX2:
+		req = 0x0b;
+		break;
+	default:
+		req = 1;
+	}
 
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
@@ -1072,10 +1919,12 @@ static int reg_r(struct sd *sd, __u16 in
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, sd->gspca_dev.usb_buf, 1, 500);
 
-	if (ret >= 0)
+	if (ret >= 0) {
 		ret = sd->gspca_dev.usb_buf[0];
-	else
+		PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
+	} else
 		PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
+
 	return ret;
 }
 
@@ -1095,6 +1944,7 @@ static int reg_r8(struct sd *sd,
 		ret = sd->gspca_dev.usb_buf[0];
 	else
 		PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
+
 	return ret;
 }
 
@@ -1132,7 +1982,7 @@ static int ov518_reg_w32(struct sd *sd,
 {
 	int ret;
 
-	*((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
+	*((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
 
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -1140,9 +1990,12 @@ static int ov518_reg_w32(struct sd *sd,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			sd->gspca_dev.usb_buf, n, 500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
-	return ret;
+		return ret;
+	}
+
+	return 0;
 }
 
 static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
@@ -1168,9 +2021,9 @@ static int ov511_i2c_w(struct sd *sd, __
 		if (rc < 0)
 			return rc;
 
-		do
+		do {
 			rc = reg_r(sd, R511_I2C_CTL);
-		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+		} while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
 
 		if (rc < 0)
 			return rc;
@@ -1202,9 +2055,9 @@ static int ov511_i2c_r(struct sd *sd, __
 		if (rc < 0)
 			return rc;
 
-		do
+		do {
 			rc = reg_r(sd, R511_I2C_CTL);
-		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+		} while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
 
 		if (rc < 0)
 			return rc;
@@ -1228,9 +2081,9 @@ static int ov511_i2c_r(struct sd *sd, __
 		if (rc < 0)
 			return rc;
 
-		do
+		do {
 			rc = reg_r(sd, R511_I2C_CTL);
-		while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
+		} while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
 
 		if (rc < 0)
 			return rc;
@@ -1324,32 +2177,110 @@ static int ov518_i2c_r(struct sd *sd, __
 	return value;
 }
 
+static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+{
+	int ret;
+
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+			0x02,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			(__u16)value, (__u16)reg, NULL, 0, 500);
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
+		return ret;
+	}
+
+	PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+	return 0;
+}
+
+static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
+{
+	int ret;
+
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+			0x03,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
+
+	if (ret >= 0) {
+		ret = sd->gspca_dev.usb_buf[0];
+		PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
+	} else
+		PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
+
+	return ret;
+}
+
 static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
 {
+	int ret = -1;
+
+	if (sd->sensor_reg_cache[reg] == value)
+		return 0;
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		return ov511_i2c_w(sd, reg, value);
+		ret = ov511_i2c_w(sd, reg, value);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 	case BRIDGE_OV519:
-		return ov518_i2c_w(sd, reg, value);
+		ret = ov518_i2c_w(sd, reg, value);
+		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_i2c_w(sd, reg, value);
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_i2c_w(sd, reg, value);
+		break;
 	}
-	return -1; /* Should never happen */
+
+	if (ret >= 0) {
+		/* Up on sensor reset empty the register cache */
+		if (reg == 0x12 && (value & 0x80))
+			memset(sd->sensor_reg_cache, -1,
+			       sizeof(sd->sensor_reg_cache));
+		else
+			sd->sensor_reg_cache[reg] = value;
+	}
+
+	return ret;
 }
 
 static int i2c_r(struct sd *sd, __u8 reg)
 {
+	int ret = -1;
+
+	if (sd->sensor_reg_cache[reg] != -1)
+		return sd->sensor_reg_cache[reg];
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		return ov511_i2c_r(sd, reg);
+		ret = ov511_i2c_r(sd, reg);
+		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
 	case BRIDGE_OV519:
-		return ov518_i2c_r(sd, reg);
+		ret = ov518_i2c_r(sd, reg);
+		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_i2c_r(sd, reg);
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_i2c_r(sd, reg);
+		break;
 	}
-	return -1; /* Should never happen */
+
+	if (ret >= 0)
+		sd->sensor_reg_cache[reg] = ret;
+
+	return ret;
 }
 
 /* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1389,6 +2320,10 @@ static inline int ov51x_stop(struct sd *
 		return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
 	case BRIDGE_OV519:
 		return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+	case BRIDGE_OVFX2:
+		return reg_w_mask(sd, 0x0f, 0x00, 0x02);
+	case BRIDGE_W9968CF:
+		return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
 	}
 
 	return 0;
@@ -1418,18 +2353,27 @@ static inline int ov51x_restart(struct s
 		return reg_w(sd, R51x_SYS_RESET, 0x00);
 	case BRIDGE_OV519:
 		return reg_w(sd, OV519_SYS_RESET1, 0x00);
+	case BRIDGE_OVFX2:
+		return reg_w_mask(sd, 0x0f, 0x02, 0x02);
+	case BRIDGE_W9968CF:
+		return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
 	}
 
 	return 0;
 }
 
+static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
+
 /* This does an initial reset of an OmniVision sensor and ensures that I2C
  * is synchronized. Returns <0 on failure.
  */
-static int init_ov_sensor(struct sd *sd)
+static int init_ov_sensor(struct sd *sd, __u8 slave)
 {
 	int i;
 
+	if (ov51x_set_slave_ids(sd, slave) < 0)
+		return -EIO;
+
 	/* Reset the sensor */
 	if (i2c_w(sd, 0x12, 0x80) < 0)
 		return -EIO;
@@ -1466,6 +2410,14 @@ static int ov51x_set_slave_ids(struct sd
 {
 	int rc;
 
+	switch (sd->bridge) {
+	case BRIDGE_OVFX2:
+		return reg_w(sd, OVFX2_I2C_ADDR, slave);
+	case BRIDGE_W9968CF:
+		sd->sensor_addr = slave;
+		return 0;
+	}
+
 	rc = reg_w(sd, R51x_I2C_W_SID, slave);
 	if (rc < 0)
 		return rc;
@@ -1508,6 +2460,39 @@ static int write_i2c_regvals(struct sd *
  *
  ***************************************************************************/
 
+/* This initializes the OV2x10 / OV3610 / OV3620 */
+static int ov_hires_configure(struct sd *sd)
+{
+	int high, low;
+
+	if (sd->bridge != BRIDGE_OVFX2) {
+		PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
+		return -1;
+	}
+
+	PDEBUG(D_PROBE, "starting ov hires configuration");
+
+	/* Detect sensor (sub)type */
+	high = i2c_r(sd, 0x0a);
+	low = i2c_r(sd, 0x0b);
+	/* info("%x, %x", high, low); */
+	if (high == 0x96 && low == 0x40) {
+		PDEBUG(D_PROBE, "Sensor is an OV2610");
+		sd->sensor = SEN_OV2610;
+	} else if (high == 0x36 && (low & 0x0f) == 0x00) {
+		PDEBUG(D_PROBE, "Sensor is an OV3610");
+		sd->sensor = SEN_OV3610;
+	} else {
+		PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
+		       high, low);
+		return -1;
+	}
+
+	/* Set sensor-specific vars */
+	return 0;
+}
+
+
 /* This initializes the OV8110, OV8610 sensor. The OV8110 uses
  * the same register settings as the OV8610, since they are very similar.
  */
@@ -1966,12 +2951,29 @@ static int ov519_configure(struct sd *sd
 	return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
 }
 
+static int ovfx2_configure(struct sd *sd)
+{
+	static const struct ov_regvals init_fx2[] = {
+		{ 0x00, 0x60 },
+		{ 0x02, 0x01 },
+		{ 0x0f, 0x1d },
+		{ 0xe9, 0x82 },
+		{ 0xea, 0xc7 },
+		{ 0xeb, 0x10 },
+		{ 0xec, 0xf6 },
+	};
+
+	sd->stopped = 1;
+
+	return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+}
+
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct cam *cam;
+	struct cam *cam = &gspca_dev->cam;
 	int ret = 0;
 
 	sd->bridge = id->driver_info & BRIDGE_MASK;
@@ -1989,6 +2991,16 @@ static int sd_config(struct gspca_dev *g
 	case BRIDGE_OV519:
 		ret = ov519_configure(sd);
 		break;
+	case BRIDGE_OVFX2:
+		ret = ovfx2_configure(sd);
+		cam->bulk_size = OVFX2_BULK_SIZE;
+		cam->bulk_nurbs = MAX_NURBS;
+		cam->bulk = 1;
+		break;
+	case BRIDGE_W9968CF:
+		ret = w9968cf_configure(sd);
+		cam->reverse_alts = 1;
+		break;
 	}
 
 	if (ret)
@@ -1996,49 +3008,39 @@ static int sd_config(struct gspca_dev *g
 
 	ov51x_led_control(sd, 0);	/* turn LED off */
 
-	/* Test for 76xx */
-	if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
-		goto error;
-
 	/* The OV519 must be more aggressive about sensor detection since
 	 * I2C write will never fail if the sensor is not present. We have
 	 * to try to initialize the sensor to detect its presence */
-	if (init_ov_sensor(sd) >= 0) {
+
+	/* Test for 76xx */
+	if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
 		if (ov7xx0_configure(sd) < 0) {
 			PDEBUG(D_ERR, "Failed to configure OV7xx0");
 			goto error;
 		}
-	} else {
-
-		/* Test for 6xx0 */
-		if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
+	/* Test for 6xx0 */
+	} else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
+		if (ov6xx0_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure OV6xx0");
+			goto error;
+		}
+	/* Test for 8xx0 */
+	} else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
+		if (ov8xx0_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure OV8xx0");
+			goto error;
+		}
+	/* Test for 3xxx / 2xxx */
+	} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
+		if (ov_hires_configure(sd) < 0) {
+			PDEBUG(D_ERR, "Failed to configure high res OV");
 			goto error;
-
-		if (init_ov_sensor(sd) >= 0) {
-			if (ov6xx0_configure(sd) < 0) {
-				PDEBUG(D_ERR, "Failed to configure OV6xx0");
-				goto error;
-			}
-		} else {
-
-			/* Test for 8xx0 */
-			if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
-				goto error;
-
-			if (init_ov_sensor(sd) < 0) {
-				PDEBUG(D_ERR,
-					"Can't determine sensor slave IDs");
-				goto error;
-			}
-			if (ov8xx0_configure(sd) < 0) {
-				PDEBUG(D_ERR,
-					"Failed to configure OV8xx0 sensor");
-				goto error;
-			}
 		}
+	} else {
+		PDEBUG(D_ERR, "Can't determine sensor slave IDs");
+		goto error;
 	}
 
-	cam = &gspca_dev->cam;
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
@@ -2069,6 +3071,31 @@ static int sd_config(struct gspca_dev *g
 			cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
 		}
 		break;
+	case BRIDGE_OVFX2:
+		if (sd->sensor == SEN_OV2610) {
+			cam->cam_mode = ovfx2_ov2610_mode;
+			cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
+		} else if (sd->sensor == SEN_OV3610) {
+			cam->cam_mode = ovfx2_ov3610_mode;
+			cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
+		} else if (!sd->sif) {
+			cam->cam_mode = ov519_vga_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+		} else {
+			cam->cam_mode = ov519_sif_mode;
+			cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
+		}
+		break;
+	case BRIDGE_W9968CF:
+		cam->cam_mode = w9968cf_vga_mode;
+		cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
+		if (sd->sif)
+			cam->nmodes--;
+
+		/* w9968cf needs initialisation once the sensor is known */
+		if (w9968cf_init(sd) < 0)
+			goto error;
+		break;
 	}
 	sd->brightness = BRIGHTNESS_DEF;
 	if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
@@ -2087,11 +3114,15 @@ static int sd_config(struct gspca_dev *g
 		gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
 				      (1 << OV7670_FREQ_IDX);
 	}
+	sd->quality = QUALITY_DEF;
 	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
 		gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
 	/* OV8610 Frequency filter control should work but needs testing */
 	if (sd->sensor == SEN_OV8610)
 		gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
+	/* No controls for the OV2610/OV3610 */
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
+		gspca_dev->ctrl_dis |= 0xFF;
 
 	return 0;
 error:
@@ -2106,6 +3137,20 @@ static int sd_init(struct gspca_dev *gsp
 
 	/* initialize the sensor */
 	switch (sd->sensor) {
+	case SEN_OV2610:
+		if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
+			return -EIO;
+		/* Enable autogain, autoexpo, awb, bandfilter */
+		if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
+			return -EIO;
+		break;
+	case SEN_OV3610:
+		if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
+			return -EIO;
+		/* Enable autogain, autoexpo, awb, bandfilter */
+		if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
+			return -EIO;
+		break;
 	case SEN_OV6620:
 		if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
 			return -EIO;
@@ -2548,19 +3593,60 @@ static int ov519_mode_init_regs(struct s
 static int mode_init_ov_sensor_regs(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev;
-	int qvga;
+	int qvga, xstart, xend, ystart, yend;
+	__u8 v;
 
 	gspca_dev = &sd->gspca_dev;
 	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
 
 	/******** Mode (VGA/QVGA) and sensor specific regs ********/
 	switch (sd->sensor) {
+	case SEN_OV2610:
+		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
+		i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
+		i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
+		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
+		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
+		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
+		return 0;
+	case SEN_OV3610:
+		if (qvga) {
+			xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
+			ystart = (776 - gspca_dev->height) / 2;
+		} else {
+			xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
+			ystart = (1544 - gspca_dev->height) / 2;
+		}
+		xend = xstart + gspca_dev->width;
+		yend = ystart + gspca_dev->height;
+		/* Writing to the COMH register resets the other windowing regs
+		   to their default values, so we must do this first. */
+		i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
+		i2c_w_mask(sd, 0x32,
+			   (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
+			   0x3f);
+		i2c_w_mask(sd, 0x03,
+			   (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
+			   0x0f);
+		i2c_w(sd, 0x17, xstart >> 4);
+		i2c_w(sd, 0x18, xend >> 4);
+		i2c_w(sd, 0x19, ystart >> 3);
+		i2c_w(sd, 0x1a, yend >> 3);
+		return 0;
 	case SEN_OV8610:
 		/* For OV8610 qvga means qsvga */
 		i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
+		i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
 		break;
 	case SEN_OV7610:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w(sd, 0x35, qvga?0x1e:0x9e);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
 		break;
 	case SEN_OV7620:
 	case SEN_OV76BE:
@@ -2571,6 +3657,10 @@ static int mode_init_ov_sensor_regs(stru
 		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
 		i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
 		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		if (sd->sensor == SEN_OV76BE)
+			i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
 		break;
 	case SEN_OV7640:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -2580,6 +3670,7 @@ static int mode_init_ov_sensor_regs(stru
 /*		i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
 /*		i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
 /*		i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
+		i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
 		break;
 	case SEN_OV7670:
 		/* set COM7_FMT_VGA or COM7_FMT_QVGA
@@ -2588,55 +3679,56 @@ static int mode_init_ov_sensor_regs(stru
 		i2c_w_mask(sd, OV7670_REG_COM7,
 			 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
 			 OV7670_COM7_FMT_MASK);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+				OV7670_COM8_AWB);
+		if (qvga) {		/* QVGA from ov7670.c by
+					 * Jonathan Corbet */
+			xstart = 164;
+			xend = 28;
+			ystart = 14;
+			yend = 494;
+		} else {		/* VGA */
+			xstart = 158;
+			xend = 14;
+			ystart = 10;
+			yend = 490;
+		}
+		/* OV7670 hardware window registers are split across
+		 * multiple locations */
+		i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
+		i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
+		v = i2c_r(sd, OV7670_REG_HREF);
+		v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
+		msleep(10);	/* need to sleep between read and write to
+				 * same reg! */
+		i2c_w(sd, OV7670_REG_HREF, v);
+
+		i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
+		i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
+		v = i2c_r(sd, OV7670_REG_VREF);
+		v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
+		msleep(10);	/* need to sleep between read and write to
+				 * same reg! */
+		i2c_w(sd, OV7670_REG_VREF, v);
 		break;
 	case SEN_OV6620:
+		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
+		break;
 	case SEN_OV6630:
 	case SEN_OV66308AF:
 		i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+		i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	/******** Palette-specific regs ********/
-
-	/* The OV518 needs special treatment. Although both the OV518
-	 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
-	 * bus is actually used. The UV bus is tied to ground.
-	 * Therefore, the OV6630 needs to be in 8-bit multiplexed
-	 * output mode */
-
-	/* OV7640 is 8-bit only */
-
-	if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF &&
-					sd->sensor != SEN_OV7640)
-		i2c_w_mask(sd, 0x13, 0x00, 0x20);
-
 	/******** Clock programming ********/
 	i2c_w(sd, 0x11, sd->clockdiv);
 
-	/******** Special Features ********/
-/* no evidence this is possible with OV7670, either */
-	/* Test Pattern */
-	if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
-		i2c_w_mask(sd, 0x12, 0x00, 0x02);
-
-	/* Enable auto white balance */
-	if (sd->sensor == SEN_OV7670)
-		i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
-				OV7670_COM8_AWB);
-	else
-		i2c_w_mask(sd, 0x12, 0x04, 0x04);
-
-	/* This will go away as soon as ov51x_mode_init_sensor_regs() */
-	/* is fully tested. */
-	/* 7620/6620/6630? don't have register 0x35, so play it safe */
-	if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
-		if (!qvga)
-			i2c_w(sd, 0x35, 0x9e);
-		else
-			i2c_w(sd, 0x35, 0x1e);
-	}
 	return 0;
 }
 
@@ -2659,8 +3751,12 @@ static int set_ov_sensor_window(struct s
 	struct gspca_dev *gspca_dev;
 	int qvga, crop;
 	int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
-	int ret, hstart, hstop, vstop, vstart;
-	__u8 v;
+	int ret;
+
+	/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
+	    sd->sensor == SEN_OV7670)
+		return mode_init_ov_sensor_regs(sd);
 
 	gspca_dev = &sd->gspca_dev;
 	qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
@@ -2708,11 +3804,6 @@ static int set_ov_sensor_window(struct s
 		hwebase = 0x1a;
 		vwsbase = vwebase = 0x03;
 		break;
-	case SEN_OV7670:
-		/*handling of OV7670 hardware sensor start and stop values
-		 * is very odd, compared to the other OV sensors */
-		vwsbase = vwebase = hwebase = hwsbase = 0x00;
-		break;
 	default:
 		return -EINVAL;
 	}
@@ -2753,58 +3844,11 @@ static int set_ov_sensor_window(struct s
 	if (ret < 0)
 		return ret;
 
-	if (sd->sensor == SEN_OV8610) {
-		i2c_w_mask(sd, 0x2d, 0x05, 0x40);
-				/* old 0x95, new 0x05 from windrv 090403 */
-						/* bits 5-7: reserved */
-		i2c_w_mask(sd, 0x28, 0x20, 0x20);
-					/* bit 5: progressive mode on */
-	}
-
-	/* The below is wrong for OV7670s because their window registers
-	 * only store the high bits in 0x17 to 0x1a */
-
-	/* SRH Use sd->max values instead of requested win values */
-	/* SCS Since we're sticking with only the max hardware widths
-	 * for a given mode */
-	/* I can hard code this for OV7670s */
-	/* Yes, these numbers do look odd, but they're tested and work! */
-	if (sd->sensor == SEN_OV7670) {
-		if (qvga) {		/* QVGA from ov7670.c by
-					 * Jonathan Corbet */
-			hstart = 164;
-			hstop = 28;
-			vstart = 14;
-			vstop = 494;
-		} else {		/* VGA */
-			hstart = 158;
-			hstop = 14;
-			vstart = 10;
-			vstop = 490;
-		}
-		/* OV7670 hardware window registers are split across
-		 * multiple locations */
-		i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
-		i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
-		v = i2c_r(sd, OV7670_REG_HREF);
-		v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
-		msleep(10);	/* need to sleep between read and write to
-				 * same reg! */
-		i2c_w(sd, OV7670_REG_HREF, v);
+	i2c_w(sd, 0x17, hwsbase);
+	i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
+	i2c_w(sd, 0x19, vwsbase);
+	i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
 
-		i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
-		i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
-		v = i2c_r(sd, OV7670_REG_VREF);
-		v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
-		msleep(10);	/* need to sleep between read and write to
-				 * same reg! */
-		i2c_w(sd, OV7670_REG_VREF, v);
-	} else {
-		i2c_w(sd, 0x17, hwsbase);
-		i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
-		i2c_w(sd, 0x19, vwsbase);
-		i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
-	}
 	return 0;
 }
 
@@ -2814,6 +3858,10 @@ static int sd_start(struct gspca_dev *gs
 	struct sd *sd = (struct sd *) gspca_dev;
 	int ret = 0;
 
+	/* Default for most bridges, allow bridge_mode_init_regs to override */
+	sd->sensor_width = sd->gspca_dev.width;
+	sd->sensor_height = sd->gspca_dev.height;
+
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
@@ -2826,6 +3874,10 @@ static int sd_start(struct gspca_dev *gs
 	case BRIDGE_OV519:
 		ret = ov519_mode_init_regs(sd);
 		break;
+	/* case BRIDGE_OVFX2: nothing to do */
+	case BRIDGE_W9968CF:
+		ret = w9968cf_mode_init_regs(sd);
+		break;
 	}
 	if (ret < 0)
 		goto out;
@@ -2859,10 +3911,17 @@ static void sd_stopN(struct gspca_dev *g
 	ov51x_led_control(sd, 0);
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge == BRIDGE_W9968CF)
+		w9968cf_stop0(sd);
+}
+
 static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *in,			/* isoc packet */
-			int len)			/* iso packet length */
+			u8 *in,			/* isoc packet */
+			int len)		/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -2893,11 +3952,11 @@ static void ov511_pkt_scan(struct gspca_
 				return;
 			}
 			/* Add 11 byte footer to frame, might be usefull */
-			gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11);
+			gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
 			return;
 		} else {
 			/* Frame start */
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
 			sd->packet_nr = 0;
 		}
 	}
@@ -2906,12 +3965,11 @@ static void ov511_pkt_scan(struct gspca_
 	len--;
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
 }
 
 static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2919,8 +3977,8 @@ static void ov518_pkt_scan(struct gspca_
 	/* A false positive here is likely, until OVT gives me
 	 * the definitive SOF/EOF format */
 	if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		sd->packet_nr = 0;
 	}
 
@@ -2944,12 +4002,11 @@ static void ov518_pkt_scan(struct gspca_
 	}
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	/* Header of ov519 is 16 bytes:
@@ -2972,7 +4029,7 @@ static void ov519_pkt_scan(struct gspca_
 			len -= HDRSZ;
 #undef HDRSZ
 			if (data[0] == 0xff || data[1] == 0xd8)
-				gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+				gspca_frame_add(gspca_dev, FIRST_PACKET,
 						data, len);
 			else
 				gspca_dev->last_packet_type = DISCARD_PACKET;
@@ -2980,20 +4037,31 @@ static void ov519_pkt_scan(struct gspca_
 		case 0x51:		/* end of frame */
 			if (data[9] != 0)
 				gspca_dev->last_packet_type = DISCARD_PACKET;
-			gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 			return;
 		}
 	}
 
 	/* intermediate packet */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	/* A short read signals EOF */
+	if (len < OVFX2_BULK_SIZE) {
+		gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
+		return;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -3001,14 +4069,20 @@ static void sd_pkt_scan(struct gspca_dev
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
 	case BRIDGE_OV511PLUS:
-		ov511_pkt_scan(gspca_dev, frame, data, len);
+		ov511_pkt_scan(gspca_dev, data, len);
 		break;
 	case BRIDGE_OV518:
 	case BRIDGE_OV518PLUS:
-		ov518_pkt_scan(gspca_dev, frame, data, len);
+		ov518_pkt_scan(gspca_dev, data, len);
 		break;
 	case BRIDGE_OV519:
-		ov519_pkt_scan(gspca_dev, frame, data, len);
+		ov519_pkt_scan(gspca_dev, data, len);
+		break;
+	case BRIDGE_OVFX2:
+		ovfx2_pkt_scan(gspca_dev, data, len);
+		break;
+	case BRIDGE_W9968CF:
+		w9968cf_pkt_scan(gspca_dev, data, len);
 		break;
 	}
 }
@@ -3124,7 +4198,8 @@ static void setcolors(struct gspca_dev *
 
 static void setautobrightness(struct sd *sd)
 {
-	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
+	if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
+	    sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
 		return;
 
 	i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
@@ -3132,6 +4207,9 @@ static void setautobrightness(struct sd
 
 static void setfreq(struct sd *sd)
 {
+	if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
+		return;
+
 	if (sd->sensor == SEN_OV7670) {
 		switch (sd->freq) {
 		case 0: /* Banding filter disabled */
@@ -3301,8 +4379,12 @@ static int sd_setfreq(struct gspca_dev *
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	sd->freq = val;
-	if (gspca_dev->streaming)
+	if (gspca_dev->streaming) {
 		setfreq(sd);
+		/* Ugly but necessary */
+		if (sd->bridge == BRIDGE_W9968CF)
+			w9968cf_set_crop_window(sd);
+	}
 	return 0;
 }
 
@@ -3343,6 +4425,45 @@ static int sd_querymenu(struct gspca_dev
 	return -EINVAL;
 }
 
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge != BRIDGE_W9968CF)
+		return -EINVAL;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
+			      V4L2_JPEG_MARKER_DRI;
+	return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->bridge != BRIDGE_W9968CF)
+		return -EINVAL;
+
+	if (gspca_dev->streaming)
+		return -EBUSY;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+
+	/* Return resulting jcomp params to app */
+	sd_get_jcomp(gspca_dev, jcomp);
+
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -3352,18 +4473,23 @@ static const struct sd_desc sd_desc = {
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
 	{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4064),
 	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+	{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4068),
 	 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
 	{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
@@ -3373,11 +4499,16 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
 	{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
+	{USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
 	{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
 	{USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
 	{USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
+	{USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
+	{USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
+	{USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
+	{USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
 	{}
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/ov534.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/ov534.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/ov534.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 /*
  * ov534 gspca driver
+ *
  * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
  * Copyright (C) 2008 Jim Paris <jim@jtan.com>
  * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,10 @@
  * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
  * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
  *
+ * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
+ * PS3 Eye camera, brightness, contrast, hue, AWB control added
+ *	by Max Thrun <bear24rw@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
@@ -51,16 +56,335 @@ struct sd {
 	u16 last_fid;
 	u8 frame_rate;
 
+	u8 brightness;
+	u8 contrast;
+	u8 gain;
+	u8 exposure;
+	u8 redblc;
+	u8 blueblc;
+	u8 hue;
+	u8 autogain;
+	u8 awb;
+	s8 sharpness;
+	u8 hflip;
+	u8 vflip;
+	u8 satur;
+	u8 lightfreq;
+
 	u8 sensor;
 #define SENSOR_OV772X 0
 #define SENSOR_OV965X 1
 };
 
 /* V4L2 controls supported by the driver */
-static struct ctrl sd_ctrls[] = {
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls_ov772x[] = {
+    {							/* 0 */
+	{
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define BRIGHTNESS_77_DEF 20
+		.default_value = BRIGHTNESS_77_DEF,
+	},
+	.set = sd_setbrightness,
+	.get = sd_getbrightness,
+    },
+    {							/* 1 */
+	{
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define CONTRAST_77_DEF 37
+		.default_value = CONTRAST_77_DEF,
+	},
+	.set = sd_setcontrast,
+	.get = sd_getcontrast,
+    },
+    {							/* 2 */
+	{
+	    .id      = V4L2_CID_GAIN,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Main Gain",
+	    .minimum = 0,
+	    .maximum = 63,
+	    .step    = 1,
+#define GAIN_DEF 20
+	    .default_value = GAIN_DEF,
+	},
+	.set = sd_setgain,
+	.get = sd_getgain,
+    },
+    {							/* 3 */
+	{
+	    .id      = V4L2_CID_EXPOSURE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Exposure",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define EXPO_77_DEF 120
+	    .default_value = EXPO_77_DEF,
+	},
+	.set = sd_setexposure,
+	.get = sd_getexposure,
+    },
+    {							/* 4 */
+	{
+	    .id      = V4L2_CID_RED_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Red Balance",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define RED_BALANCE_DEF 128
+	    .default_value = RED_BALANCE_DEF,
+	},
+	.set = sd_setredblc,
+	.get = sd_getredblc,
+    },
+    {							/* 5 */
+	{
+	    .id      = V4L2_CID_BLUE_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Blue Balance",
+	    .minimum = 0,
+	    .maximum = 255,
+	    .step    = 1,
+#define BLUE_BALANCE_DEF 128
+	    .default_value = BLUE_BALANCE_DEF,
+	},
+	.set = sd_setblueblc,
+	.get = sd_getblueblc,
+    },
+    {							/* 6 */
+	{
+		.id      = V4L2_CID_HUE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Hue",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define HUE_DEF 143
+		.default_value = HUE_DEF,
+	},
+	.set = sd_sethue,
+	.get = sd_gethue,
+    },
+    {							/* 7 */
+	{
+	    .id      = V4L2_CID_AUTOGAIN,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Autogain",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define AUTOGAIN_77_DEF 0
+	    .default_value = AUTOGAIN_77_DEF,
+	},
+	.set = sd_setautogain,
+	.get = sd_getautogain,
+    },
+#define AWB_77_IDX 8
+    {							/* 8 */
+	{
+		.id      = V4L2_CID_AUTO_WHITE_BALANCE,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Auto White Balance",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AWB_DEF 0
+		.default_value = AWB_DEF,
+	},
+	.set = sd_setawb,
+	.get = sd_getawb,
+    },
+    {							/* 9 */
+	{
+	    .id      = V4L2_CID_SHARPNESS,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Sharpness",
+	    .minimum = 0,
+	    .maximum = 63,
+	    .step    = 1,
+#define SHARPNESS_77_DEF 0
+	    .default_value = SHARPNESS_77_DEF,
+	},
+	.set = sd_setsharpness,
+	.get = sd_getsharpness,
+    },
+    {							/* 10 */
+	{
+	    .id      = V4L2_CID_HFLIP,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "HFlip",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define HFLIP_DEF 0
+	    .default_value = HFLIP_DEF,
+	},
+	.set = sd_sethflip,
+	.get = sd_gethflip,
+    },
+    {							/* 11 */
+	{
+	    .id      = V4L2_CID_VFLIP,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "VFlip",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define VFLIP_DEF 0
+	    .default_value = VFLIP_DEF,
+	},
+	.set = sd_setvflip,
+	.get = sd_getvflip,
+    },
+};
+static struct ctrl sd_ctrls_ov965x[] = {
+    {							/* 0 */
+	{
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define BRIGHTNESS_96_DEF 7
+		.default_value = BRIGHTNESS_96_DEF,
+	},
+	.set = sd_setbrightness,
+	.get = sd_getbrightness,
+    },
+    {							/* 1 */
+	{
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+		.maximum = 15,
+		.step    = 1,
+#define CONTRAST_96_DEF 3
+		.default_value = CONTRAST_96_DEF,
+	},
+	.set = sd_setcontrast,
+	.get = sd_getcontrast,
+    },
+    {							/* 2 */
+	{
+	    .id      = V4L2_CID_AUTOGAIN,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Autogain",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+#define AUTOGAIN_96_DEF 1
+	    .default_value = AUTOGAIN_96_DEF,
+	},
+	.set = sd_setautogain,
+	.get = sd_getautogain,
+    },
+#define EXPO_96_IDX 3
+    {							/* 3 */
+	{
+	    .id      = V4L2_CID_EXPOSURE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Exposure",
+	    .minimum = 0,
+	    .maximum = 3,
+	    .step    = 1,
+#define EXPO_96_DEF 0
+	    .default_value = EXPO_96_DEF,
+	},
+	.set = sd_setexposure,
+	.get = sd_getexposure,
+    },
+    {							/* 4 */
+	{
+	    .id      = V4L2_CID_SHARPNESS,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Sharpness",
+	    .minimum = -1,		/* -1 = auto */
+	    .maximum = 4,
+	    .step    = 1,
+#define SHARPNESS_96_DEF -1
+	    .default_value = SHARPNESS_96_DEF,
+	},
+	.set = sd_setsharpness,
+	.get = sd_getsharpness,
+    },
+    {							/* 5 */
+	{
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+		.maximum = 4,
+		.step    = 1,
+#define SATUR_DEF 2
+		.default_value = SATUR_DEF,
+	},
+	.set = sd_setsatur,
+	.get = sd_getsatur,
+    },
+    {
+	{
+		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = 0,
+		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
+		.step    = 1,
+#define FREQ_DEF 0
+		.default_value = FREQ_DEF,
+	},
+	.set = sd_setfreq,
+	.get = sd_getfreq,
+    },
 };
 
-static const struct v4l2_pix_format vga_yuyv_mode[] = {
+static const struct v4l2_pix_format ov772x_mode[] = {
+	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+	 .bytesperline = 320 * 2,
+	 .sizeimage = 320 * 240 * 2,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = 1},
 	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
 	 .bytesperline = 640 * 2,
 	 .sizeimage = 640 * 480 * 2,
@@ -68,20 +392,35 @@ static const struct v4l2_pix_format vga_
 	 .priv = 0},
 };
 
-static const struct v4l2_pix_format vga_jpeg_mode[] = {
+static const struct v4l2_pix_format ov965x_mode[] = {
 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 	 .bytesperline = 320,
 	 .sizeimage = 320 * 240 * 3 / 8 + 590,
 	 .colorspace = V4L2_COLORSPACE_JPEG,
-	 .priv = 1},
+	 .priv = 4},
 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 	 .bytesperline = 640,
 	 .sizeimage = 640 * 480 * 3 / 8 + 590,
 	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 3},
+	{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 800,
+	 .sizeimage = 800 * 600 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 2},
+	{1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 1024,
+	 .sizeimage = 1024 * 768 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
+	 .priv = 1},
+	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+	 .bytesperline = 1280,
+	 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
+	 .colorspace = V4L2_COLORSPACE_JPEG,
 	 .priv = 0},
 };
 
-static const u8 bridge_init_ov722x[][2] = {
+static const u8 bridge_init_ov772x[][2] = {
 	{ 0xc2, 0x0c },
 	{ 0x88, 0xf8 },
 	{ 0xc3, 0x69 },
@@ -122,6 +461,7 @@ static const u8 bridge_init_ov722x[][2]
 	{ 0x1d, 0x40 },
 	{ 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
 	{ 0x1d, 0x00 }, /* payload size */
+
 	{ 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
 	{ 0x1d, 0x58 }, /* frame size */
 	{ 0x1d, 0x00 }, /* frame size */
@@ -138,10 +478,20 @@ static const u8 bridge_init_ov722x[][2]
 	{ 0xc1, 0x3c },
 	{ 0xc2, 0x0c },
 };
-
-static const u8 sensor_init_ov722x[][2] = {
+static const u8 sensor_init_ov772x[][2] = {
 	{ 0x12, 0x80 },
 	{ 0x11, 0x01 },
+/*fixme: better have a delay?*/
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
+	{ 0x11, 0x01 },
 
 	{ 0x3d, 0x03 },
 	{ 0x17, 0x26 },
@@ -154,10 +504,10 @@ static const u8 sensor_init_ov722x[][2]
 	{ 0x65, 0x20 },
 	{ 0x11, 0x01 },
 	{ 0x42, 0x7f },
-	{ 0x63, 0xe0 },
+	{ 0x63, 0xaa },		/* AWB - was e0 */
 	{ 0x64, 0xff },
 	{ 0x66, 0x00 },
-	{ 0x13, 0xf0 },
+	{ 0x13, 0xf0 },		/* com8 */
 	{ 0x0d, 0x41 },
 	{ 0x0f, 0xc5 },
 	{ 0x14, 0x11 },
@@ -170,7 +520,7 @@ static const u8 sensor_init_ov722x[][2]
 	{ 0x2a, 0x00 },
 	{ 0x2b, 0x00 },
 	{ 0x6b, 0xaa },
-	{ 0x13, 0xff },
+	{ 0x13, 0xff },		/* AWB */
 
 	{ 0x90, 0x05 },
 	{ 0x91, 0x01 },
@@ -218,9 +568,51 @@ static const u8 sensor_init_ov722x[][2]
 	{ 0x14, 0x41 },
 	{ 0x0e, 0xcd },
 	{ 0xac, 0xbf },
-	{ 0x8e, 0x00 },
+	{ 0x8e, 0x00 },		/* De-noise threshold */
 	{ 0x0c, 0xd0 }
 };
+static const u8 bridge_start_ov772x_vga[][2] = {
+	{0x1c, 0x00},
+	{0x1d, 0x40},
+	{0x1d, 0x02},
+	{0x1d, 0x00},
+	{0x1d, 0x02},
+	{0x1d, 0x58},
+	{0x1d, 0x00},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+};
+static const u8 sensor_start_ov772x_vga[][2] = {
+	{0x12, 0x00},
+	{0x17, 0x26},
+	{0x18, 0xa0},
+	{0x19, 0x07},
+	{0x1a, 0xf0},
+	{0x29, 0xa0},
+	{0x2c, 0xf0},
+	{0x65, 0x20},
+};
+static const u8 bridge_start_ov772x_qvga[][2] = {
+	{0x1c, 0x00},
+	{0x1d, 0x40},
+	{0x1d, 0x02},
+	{0x1d, 0x00},
+	{0x1d, 0x01},
+	{0x1d, 0x4b},
+	{0x1d, 0x00},
+	{0xc0, 0x28},
+	{0xc1, 0x1e},
+};
+static const u8 sensor_start_ov772x_qvga[][2] = {
+	{0x12, 0x40},
+	{0x17, 0x3f},
+	{0x18, 0x50},
+	{0x19, 0x03},
+	{0x1a, 0x78},
+	{0x29, 0x50},
+	{0x2c, 0x78},
+	{0x65, 0x2f},
+};
 
 static const u8 bridge_init_ov965x[][2] = {
 	{0x88, 0xf8},
@@ -403,7 +795,7 @@ static const u8 sensor_init_ov965x[][2]
 	{0xcb, 0xf0},
 	{0xcc, 0xd8},
 	{0xcd, 0xf1},
-	{0x4f, 0x98},
+	{0x4f, 0x98},	/* matrix */
 	{0x50, 0x98},
 	{0x51, 0x00},
 	{0x52, 0x28},
@@ -412,6 +804,7 @@ static const u8 sensor_init_ov965x[][2]
 	{0x58, 0x1a},
 	{0xff, 0x41},	/* read 41, write ff 00 */
 	{0x41, 0x40},	/* com16 */
+
 	{0xc5, 0x03},	/* 60 Hz banding filter */
 	{0x6a, 0x02},	/* 50 Hz banding filter */
 
@@ -455,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2
 	{0x52, 0x3c},
 	{0x53, 0x00},
 	{0x54, 0x00},
-	{0x55, 0x00},	/* brightness */
-	{0x57, 0x00},	/* contrast 2 */
+	{0x55, 0x00},
+	{0x57, 0x00},
 	{0x5c, 0x00},
 	{0x5a, 0xa0},
 	{0x5b, 0x78},
@@ -479,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2
 	{0xa3, 0x3e},
 	{0x2d, 0x00},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc0},
+	{0x42, 0xc0},	/* com17 */
 	{0x2d, 0x00},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},
+	{0x42, 0xc1},	/* com17 */
+/* sharpness */
 	{0x3f, 0x01},
 	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},
-	{0x4f, 0x98},
+	{0x42, 0xc1},	/* com17 */
+/* saturation */
+	{0x4f, 0x98},	/* matrix */
 	{0x50, 0x98},
 	{0x51, 0x00},
 	{0x52, 0x28},
@@ -495,14 +890,17 @@ static const u8 sensor_init_ov965x_2[][2
 	{0x58, 0x1a},
 	{0xff, 0x41},	/* read 41, write ff 00 */
 	{0x41, 0x40},	/* com16 */
+/* contrast */
 	{0x56, 0x40},
+/* brightness */
 	{0x55, 0x8f},
+/* expo */
 	{0x10, 0x25},	/* aech - exposure high bits */
 	{0xff, 0x13},	/* read 13, write ff 00 */
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 };
 
-static const u8 sensor_start_ov965x[][2] = {
+static const u8 sensor_start_ov965x_1_vga[][2] = {	/* same for qvga */
 	{0x12, 0x62},	/* com7 - 30fps VGA YUV */
 	{0x36, 0xfa},	/* aref3 */
 	{0x69, 0x0a},	/* hv */
@@ -523,10 +921,77 @@ static const u8 sensor_start_ov965x[][2]
 	{0x1a, 0x3d},	/* vstop */
 	{0x32, 0xff},	/* href */
 	{0xc0, 0xaa},
-	{}
 };
 
-static const u8 bridge_start_ov965x[][2] = {
+static const u8 sensor_start_ov965x_1_svga[][2] = {
+	{0x12, 0x02},	/* com7 - YUYV - VGA 15 full resolution */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x0d},	/* com22 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_ov965x_1_xga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 sensor_start_ov965x_1_sxga[][2] = {
+	{0x12, 0x02},	/* com7 */
+	{0x36, 0xf8},	/* aref3 */
+	{0x69, 0x02},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},	/* com14 */
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},	/* com24 */
+	{0x03, 0x1b},	/* vref */
+	{0x17, 0x1d},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xe2},
+};
+
+static const u8 bridge_start_ov965x_qvga[][2] = {
 	{0x94, 0xaa},
 	{0xf1, 0x60},
 	{0xe5, 0x04},
@@ -535,10 +1000,34 @@ static const u8 bridge_start_ov965x[][2]
 	{0x8c, 0x00},
 	{0x8d, 0x1c},
 	{0x34, 0x05},
-	{}
+
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0xda, 0x00},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x78},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0x50},
+	{0x5b, 0x3c},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
 };
 
 static const u8 bridge_start_ov965x_vga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
 	{0xc2, 0x0c},
 	{0xc3, 0xf9},
 	{0xda, 0x01},
@@ -555,30 +1044,98 @@ static const u8 bridge_start_ov965x_vga[
 	{0x35, 0x02},
 	{0xd9, 0x10},
 	{0x94, 0x11},
-	{}
 };
 
-static const u8 bridge_start_ov965x_cif[][2] = {
+static const u8 bridge_start_ov965x_svga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
 	{0xc2, 0x4c},
 	{0xc3, 0xf9},
-	{0xda, 0x00},
 	{0x50, 0x00},
-	{0x51, 0xa0},
-	{0x52, 0x78},
+	{0x51, 0x40},
+	{0x52, 0x00},
 	{0x53, 0x00},
 	{0x54, 0x00},
-	{0x55, 0x00},
+	{0x55, 0x88},
 	{0x57, 0x00},
 	{0x5c, 0x00},
-	{0x5a, 0x50},
-	{0x5b, 0x3c},
+	{0x5a, 0xc8},
+	{0x5b, 0x96},
 	{0x35, 0x02},
 	{0xd9, 0x10},
+	{0xda, 0x00},
 	{0x94, 0x11},
-	{}
 };
 
-static const u8 sensor_start_ov965x_vga[][2] = {
+static const u8 bridge_start_ov965x_xga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0x40},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x88},
+	{0x57, 0x00},
+	{0x5c, 0x01},
+	{0x5a, 0x00},
+	{0x5b, 0xc0},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0xda, 0x01},
+	{0x94, 0x11},
+};
+
+static const u8 bridge_start_ov965x_sxga[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0xa0},
+	{0xc1, 0x80},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x00},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x_2_qvga[][2] = {
+	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x02},	/* 50 Hz banding filter */
+	{0xc5, 0x03},	/* 60 Hz banding filter */
+	{0xa2, 0x96},	/* bd50 */
+	{0xa3, 0x7d},	/* bd60 */
+
+	{0xff, 0x13},	/* read 13, write ff 00 */
+	{0x13, 0xe7},
+	{0x3a, 0x80},	/* tslb - yuyv */
+};
+
+static const u8 sensor_start_ov965x_2_vga[][2] = {
 	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
 	{0x1e, 0x04},	/* mvfp */
 	{0x13, 0xe0},	/* com8 */
@@ -592,35 +1149,36 @@ static const u8 sensor_start_ov965x_vga[
 	{0xa3, 0x3e},	/* bd60 */
 
 	{0x2d, 0x00},	/* advfl */
-	{}
 };
 
-static const u8 sensor_start_ov965x_cif[][2] = {
-	{0x3b, 0xe4},	/* com11 - night mode 1/4 frame rate */
+static const u8 sensor_start_ov965x_2_svga[][2] = {	/* same for xga */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
 	{0x1e, 0x04},	/* mvfp */
 	{0x13, 0xe0},	/* com8 */
 	{0x00, 0x00},
 	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
 	{0x11, 0x01},	/* clkrc */
 	{0x6b, 0x5a},	/* dblv */
-	{0x6a, 0x02},	/* 50 Hz banding filter */
-	{0xc5, 0x03},	/* 60 Hz banding filter */
-	{0xa2, 0x96},	/* bd50 */
-	{0xa3, 0x7d},	/* bd60 */
-
-	{0xff, 0x13},	/* read 13, write ff 00 */
-	{0x13, 0xe7},
-	{0x3a, 0x80},	/* tslb - yuyv */
-	{}
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
 };
 
-static const u8 sensor_start_ov965x_2[][2] = {
-	{0xff, 0x42},	/* read 42, write ff 00 */
-	{0x42, 0xc1},	/* com17 - 50 Hz filter */
-	{}
+static const u8 sensor_start_ov965x_2_sxga[][2] = {
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x3b, 0xc4},	/* com11 - night mode 1/4 frame rate */
+	{0x1e, 0x04},	/* mvfp */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x0c},	/* 50 Hz banding filter */
+	{0xc5, 0x0f},	/* 60 Hz banding filter */
+	{0xa2, 0x4e},	/* bd50 */
+	{0xa3, 0x41},	/* bd60 */
 };
 
-
 static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 {
 	struct usb_device *udev = gspca_dev->dev;
@@ -753,39 +1311,310 @@ static void sccb_w_array(struct gspca_de
 	}
 }
 
-/* set framerate */
-static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
+/* ov772x specific controls */
+static void set_frame_rate(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int fr = sd->frame_rate;
+	int i;
+	struct rate_s {
+		u8 fps;
+		u8 r11;
+		u8 r0d;
+		u8 re5;
+	};
+	const struct rate_s *r;
+	static const struct rate_s rate_0[] = {	/* 640x480 */
+		{60, 0x01, 0xc1, 0x04},
+		{50, 0x01, 0x41, 0x02},
+		{40, 0x02, 0xc1, 0x04},
+		{30, 0x04, 0x81, 0x02},
+		{15, 0x03, 0x41, 0x04},
+	};
+	static const struct rate_s rate_1[] = {	/* 320x240 */
+		{125, 0x02, 0x81, 0x02},
+		{100, 0x02, 0xc1, 0x04},
+		{75, 0x03, 0xc1, 0x04},
+		{60, 0x04, 0xc1, 0x04},
+		{50, 0x02, 0x41, 0x04},
+		{40, 0x03, 0x41, 0x04},
+		{30, 0x04, 0x41, 0x04},
+	};
 
-	switch (fr) {
-	case 50:
-		sccb_reg_write(gspca_dev, 0x11, 0x01);
-		sccb_reg_write(gspca_dev, 0x0d, 0x41);
-		ov534_reg_write(gspca_dev, 0xe5, 0x02);
+	if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
+		r = rate_0;
+		i = ARRAY_SIZE(rate_0);
+	} else {
+		r = rate_1;
+		i = ARRAY_SIZE(rate_1);
+	}
+	while (--i > 0) {
+		if (sd->frame_rate >= r->fps)
+			break;
+		r++;
+	}
+
+	sccb_reg_write(gspca_dev, 0x11, r->r11);
+	sccb_reg_write(gspca_dev, 0x0d, r->r0d);
+	ov534_reg_write(gspca_dev, 0xe5, r->re5);
+
+	PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
+}
+
+static void setbrightness_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
+}
+
+static void setcontrast_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->gain;
+	switch (val & 0x30) {
+	case 0x00:
+		val &= 0x0f;
 		break;
-	case 40:
-		sccb_reg_write(gspca_dev, 0x11, 0x02);
-		sccb_reg_write(gspca_dev, 0x0d, 0xc1);
-		ov534_reg_write(gspca_dev, 0xe5, 0x04);
+	case 0x10:
+		val &= 0x0f;
+		val |= 0x30;
 		break;
-/*	case 30: */
-	default:
-		fr = 30;
-		sccb_reg_write(gspca_dev, 0x11, 0x04);
-		sccb_reg_write(gspca_dev, 0x0d, 0x81);
-		ov534_reg_write(gspca_dev, 0xe5, 0x02);
+	case 0x20:
+		val &= 0x0f;
+		val |= 0x70;
 		break;
-	case 15:
-		sccb_reg_write(gspca_dev, 0x11, 0x03);
-		sccb_reg_write(gspca_dev, 0x0d, 0x41);
-		ov534_reg_write(gspca_dev, 0xe5, 0x04);
+	default:
+/*	case 0x30: */
+		val &= 0x0f;
+		val |= 0xf0;
 		break;
 	}
+	sccb_reg_write(gspca_dev, 0x00, val);
+}
 
-	sd->frame_rate = fr;
-	PDEBUG(D_PROBE, "frame_rate: %d", fr);
+static void setexposure_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->exposure;
+	sccb_reg_write(gspca_dev, 0x08, val >> 7);
+	sccb_reg_write(gspca_dev, 0x10, val << 1);
+}
+
+static void setredblc(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x43, sd->redblc);
+}
+
+static void setblueblc(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x01, sd->hue);
+}
+
+static void setautogain_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->autogain) {
+		sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */
+		sccb_reg_write(gspca_dev, 0x64,
+				sccb_reg_read(gspca_dev, 0x64) | 0x03);
+	} else {
+		sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
+		sccb_reg_write(gspca_dev, 0x64,
+				sccb_reg_read(gspca_dev, 0x64) & 0xfc);
+	}
+}
+
+static void setawb(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->awb)
+		sccb_reg_write(gspca_dev, 0x63, 0xe0);	/* AWB on */
+	else
+		sccb_reg_write(gspca_dev, 0x63, 0xaa);	/* AWB off */
+}
+
+static void setsharpness_77(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->sharpness;
+	sccb_reg_write(gspca_dev, 0x91, val);	/* vga noise */
+	sccb_reg_write(gspca_dev, 0x8e, val);	/* qvga noise */
+}
+
+static void sethflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->hflip == 0)
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) | 0x40);
+	else
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
+}
+
+static void setvflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->vflip == 0)
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) | 0x80);
+	else
+		sccb_reg_write(gspca_dev, 0x0c,
+				sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
+}
+
+/* ov965x specific controls */
+static void setbrightness_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sd->brightness;
+	if (val < 8)
+		val = 15 - val;		/* f .. 8 */
+	else
+		val = val - 8;		/* 0 .. 7 */
+	sccb_reg_write(gspca_dev, 0x55,	/* brtn - brightness adjustment */
+			0x0f | (val << 4));
+}
+
+static void setcontrast_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sccb_reg_write(gspca_dev, 0x56,	/* cnst1 - contrast 1 ctrl coeff */
+			sd->contrast << 4);
+}
+
+static void setexposure_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+	static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
+
+	sccb_reg_write(gspca_dev, 0x10,			/* aec[9:2] */
+			expo[sd->exposure]);
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x13, val);
+	val = sccb_reg_read(gspca_dev, 0xa1);		/* aech */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0xa1, val & 0xe0);	/* aec[15:10] = 0 */
+}
+
+static void setsharpness_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s8 val;
+
+	val = sd->sharpness;
+	if (val < 0) {				/* auto */
+		val = sccb_reg_read(gspca_dev, 0x42);	/* com17 */
+		sccb_reg_write(gspca_dev, 0xff, 0x00);
+		sccb_reg_write(gspca_dev, 0x42, val | 0x40);
+				/* Edge enhancement strength auto adjust */
+		return;
+	}
+	if (val != 0)
+		val = 1 << (val - 1);
+	sccb_reg_write(gspca_dev, 0x3f,	/* edge - edge enhance. factor */
+			val);
+	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
+}
+
+static void setautogain_96(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+/*fixme: should adjust agc/awb/aec by different controls */
+	val = sd->autogain;
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->autogain)
+		val |= 0x05;		/* agc & aec */
+	else
+		val &= 0xfa;
+	sccb_reg_write(gspca_dev, 0x13, val);
+}
+
+static void setsatur(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val1, val2, val3;
+	static const u8 matrix[5][2] = {
+		{0x14, 0x38},
+		{0x1e, 0x54},
+		{0x28, 0x70},
+		{0x32, 0x8c},
+		{0x48, 0x90}
+	};
+
+	val1 = matrix[sd->satur][0];
+	val2 = matrix[sd->satur][1];
+	val3 = val1 + val2;
+	sccb_reg_write(gspca_dev, 0x4f, val3);	/* matrix coeff */
+	sccb_reg_write(gspca_dev, 0x50, val3);
+	sccb_reg_write(gspca_dev, 0x51, 0x00);
+	sccb_reg_write(gspca_dev, 0x52, val1);
+	sccb_reg_write(gspca_dev, 0x53, val2);
+	sccb_reg_write(gspca_dev, 0x54, val3);
+	sccb_reg_write(gspca_dev, 0x58, 0x1a);	/* mtxs - coeff signs */
+	val1 = sccb_reg_read(gspca_dev, 0x41);	/* com16 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	sccb_reg_write(gspca_dev, 0x41, val1);
+}
+
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	val = sccb_reg_read(gspca_dev, 0x13);		/* com8 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->lightfreq == 0) {
+		sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
+		return;
+	}
+	sccb_reg_write(gspca_dev, 0x13, val | 0x20);
+
+	val = sccb_reg_read(gspca_dev, 0x42);		/* com17 */
+	sccb_reg_write(gspca_dev, 0xff, 0x00);
+	if (sd->lightfreq == 1)
+		val |= 0x01;
+	else
+		val &= 0xfe;
+	sccb_reg_write(gspca_dev, 0x42, val);
 }
 
 /* this function is called at probe time */
@@ -800,17 +1629,60 @@ static int sd_config(struct gspca_dev *g
 	cam = &gspca_dev->cam;
 
 	if (sd->sensor == SENSOR_OV772X) {
-		cam->cam_mode = vga_yuyv_mode;
-		cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
+		cam->cam_mode = ov772x_mode;
+		cam->nmodes = ARRAY_SIZE(ov772x_mode);
 
 		cam->bulk = 1;
 		cam->bulk_size = 16384;
 		cam->bulk_nurbs = 2;
 	} else {		/* ov965x */
-		cam->cam_mode = vga_jpeg_mode;
-		cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
+		cam->cam_mode = ov965x_mode;
+		cam->nmodes = ARRAY_SIZE(ov965x_mode);
 	}
 
+	sd->frame_rate = 30;
+
+	if (sd->sensor == SENSOR_OV772X) {
+		sd->brightness = BRIGHTNESS_77_DEF;
+		sd->contrast = CONTRAST_77_DEF;
+		sd->gain = GAIN_DEF;
+		sd->exposure = EXPO_77_DEF;
+		sd->redblc = RED_BALANCE_DEF;
+		sd->blueblc = BLUE_BALANCE_DEF;
+		sd->hue = HUE_DEF;
+#if AUTOGAIN_77_DEF != 0
+		sd->autogain = AUTOGAIN_77_DEF;
+#else
+		gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
+#endif
+#if AWB_DEF != 0
+		sd->awb = AWB_DEF
+#endif
+#if SHARPNESS_77_DEF != 0
+		sd->sharpness = SHARPNESS_77_DEF;
+#endif
+#if HFLIP_DEF != 0
+		sd->hflip = HFLIP_DEF;
+#endif
+#if VFLIP_DEF != 0
+		sd->vflip = VFLIP_DEF;
+#endif
+	} else {
+		sd->brightness = BRIGHTNESS_96_DEF;
+		sd->contrast = CONTRAST_96_DEF;
+#if AUTOGAIN_96_DEF != 0
+		sd->autogain = AUTOGAIN_96_DEF;
+		gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
+#endif
+#if EXPO_96_DEF != 0
+		sd->exposure = EXPO_96_DEF;
+#endif
+#if SHARPNESS_96_DEF != 0
+		sd->sharpness = SHARPNESS_96_DEF;
+#endif
+		sd->satur = SATUR_DEF;
+		sd->lightfreq = FREQ_DEF;
+	}
 	return 0;
 }
 
@@ -847,14 +1719,14 @@ static int sd_init(struct gspca_dev *gsp
 	/* initialize */
 	switch (sd->sensor) {
 	case SENSOR_OV772X:
-		reg_w_array(gspca_dev, bridge_init_ov722x,
-				ARRAY_SIZE(bridge_init_ov722x));
+		reg_w_array(gspca_dev, bridge_init_ov772x,
+				ARRAY_SIZE(bridge_init_ov772x));
 		ov534_set_led(gspca_dev, 1);
-		sccb_w_array(gspca_dev, sensor_init_ov722x,
-				ARRAY_SIZE(sensor_init_ov722x));
+		sccb_w_array(gspca_dev, sensor_init_ov772x,
+				ARRAY_SIZE(sensor_init_ov772x));
 		ov534_reg_write(gspca_dev, 0xe0, 0x09);
 		ov534_set_led(gspca_dev, 0);
-		ov534_set_frame_rate(gspca_dev);
+		set_frame_rate(gspca_dev);
 		break;
 	default:
 /*	case SENSOR_OV965X: */
@@ -875,60 +1747,115 @@ static int sd_init(struct gspca_dev *gsp
 	return 0;
 }
 
-static int sd_start(struct gspca_dev *gspca_dev)
+static int sd_start_ov772x(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	int mode;
 
-	switch (sd->sensor) {
-	case SENSOR_OV772X:
-		ov534_set_led(gspca_dev, 1);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		break;
-	default:
-/*	case SENSOR_OV965X: */
-
-		sccb_w_array(gspca_dev, sensor_start_ov965x,
-				ARRAY_SIZE(sensor_start_ov965x));
-		reg_w_array(gspca_dev, bridge_start_ov965x,
-				ARRAY_SIZE(bridge_start_ov965x));
-		mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-		if (mode != 0) {	/* 320x240 */
-			reg_w_array(gspca_dev, bridge_start_ov965x_cif,
-					ARRAY_SIZE(bridge_start_ov965x_cif));
-			sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
-					ARRAY_SIZE(sensor_start_ov965x_cif));
-		} else {		/* 640x480 */
-			reg_w_array(gspca_dev, bridge_start_ov965x_vga,
-					ARRAY_SIZE(bridge_start_ov965x_vga));
-			sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
-					ARRAY_SIZE(sensor_start_ov965x_vga));
-		}
-		sccb_w_array(gspca_dev, sensor_start_ov965x_2,
-				ARRAY_SIZE(sensor_start_ov965x_2));
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
-		ov534_set_led(gspca_dev, 1);
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	if (mode != 0) {	/* 320x240 */
+		reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
+				ARRAY_SIZE(bridge_start_ov772x_qvga));
+		sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
+				ARRAY_SIZE(sensor_start_ov772x_qvga));
+	} else {		/* 640x480 */
+		reg_w_array(gspca_dev, bridge_start_ov772x_vga,
+				ARRAY_SIZE(bridge_start_ov772x_vga));
+		sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
+				ARRAY_SIZE(sensor_start_ov772x_vga));
 	}
+	set_frame_rate(gspca_dev);
+
+	setautogain_77(gspca_dev);
+	setawb(gspca_dev);
+	setgain(gspca_dev);
+	setredblc(gspca_dev);
+	setblueblc(gspca_dev);
+	sethue(gspca_dev);
+	setexposure_77(gspca_dev);
+	setbrightness_77(gspca_dev);
+	setcontrast_77(gspca_dev);
+	setsharpness_77(gspca_dev);
+	setvflip(gspca_dev);
+	sethflip(gspca_dev);
+
+	ov534_set_led(gspca_dev, 1);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
 	return 0;
 }
 
-static void sd_stopN(struct gspca_dev *gspca_dev)
+static int sd_start_ov965x(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	int mode;
 
-	switch (sd->sensor) {
-	case SENSOR_OV772X:
-		ov534_reg_write(gspca_dev, 0xe0, 0x09);
-		ov534_set_led(gspca_dev, 0);
-		break;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	switch (mode) {
 	default:
-/*	case SENSOR_OV965X: */
-		ov534_reg_write(gspca_dev, 0xe0, 0x01);
-		ov534_set_led(gspca_dev, 0);
-		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+/*	case 4:			 * 320x240 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
+				ARRAY_SIZE(sensor_start_ov965x_1_vga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
+				ARRAY_SIZE(bridge_start_ov965x_qvga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
+				ARRAY_SIZE(sensor_start_ov965x_2_qvga));
+		break;
+	case 3:			/* 640x480 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
+				ARRAY_SIZE(sensor_start_ov965x_1_vga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_vga,
+				ARRAY_SIZE(bridge_start_ov965x_vga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
+				ARRAY_SIZE(sensor_start_ov965x_2_vga));
+		break;
+	case 2:			/* 800x600 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
+				ARRAY_SIZE(sensor_start_ov965x_1_svga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_svga,
+				ARRAY_SIZE(bridge_start_ov965x_svga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
+				ARRAY_SIZE(sensor_start_ov965x_2_svga));
+		break;
+	case 1:			/* 1024x768 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
+				ARRAY_SIZE(sensor_start_ov965x_1_xga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_xga,
+				ARRAY_SIZE(bridge_start_ov965x_xga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
+				ARRAY_SIZE(sensor_start_ov965x_2_svga));
+		break;
+	case 0:			/* 1280x1024 */
+		sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
+				ARRAY_SIZE(sensor_start_ov965x_1_sxga));
+		reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
+				ARRAY_SIZE(bridge_start_ov965x_sxga));
+		sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
+				ARRAY_SIZE(sensor_start_ov965x_2_sxga));
 		break;
 	}
+	setfreq(gspca_dev);
+	setautogain_96(gspca_dev);
+	setbrightness_96(gspca_dev);
+	setcontrast_96(gspca_dev);
+	setexposure_96(gspca_dev);
+	setsharpness_96(gspca_dev);
+	setsatur(gspca_dev);
+
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	ov534_set_led(gspca_dev, 1);
+	return 0;
+}
+
+static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
+{
+	ov534_reg_write(gspca_dev, 0xe0, 0x09);
+	ov534_set_led(gspca_dev, 0);
+}
+
+static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
+{
+	ov534_reg_write(gspca_dev, 0xe0, 0x01);
+	ov534_set_led(gspca_dev, 0);
+	ov534_reg_write(gspca_dev, 0xe0, 0x00);
 }
 
 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -941,8 +1868,8 @@ static void sd_stopN(struct gspca_dev *g
 #define UVC_STREAM_EOF	(1 << 1)
 #define UVC_STREAM_FID	(1 << 0)
 
-static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
-			__u8 *data, int len)
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u32 this_pts;
@@ -983,32 +1910,30 @@ static void sd_pkt_scan(struct gspca_dev
 		/* If PTS or FID has changed, start a new frame. */
 		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
 			if (gspca_dev->last_packet_type == INTER_PACKET)
-				frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET, frame,
-							NULL, 0);
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
 			sd->last_pts = this_pts;
 			sd->last_fid = this_fid;
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 					data + 12, len - 12);
 		/* If this packet is marked as EOF, end the frame */
 		} else if (data[1] & UVC_STREAM_EOF) {
 			sd->last_pts = 0;
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						data + 12, len - 12);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					data + 12, len - 12);
 		} else {
 
 			/* Add the data from this payload */
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-						data + 12, len - 12);
+			gspca_frame_add(gspca_dev, INTER_PACKET,
+					data + 12, len - 12);
 		}
 
-
 		/* Done this payload */
 		goto scan_next;
 
 discard:
 		/* Discard data until a new frame starts. */
-		gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+		gspca_dev->last_packet_type = DISCARD_PACKET;
 
 scan_next:
 		remaining_len -= len;
@@ -1016,6 +1941,291 @@ scan_next:
 	} while (remaining_len > 0);
 }
 
+/* controls */
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setexposure_77(gspca_dev);
+		else
+			setexposure_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setbrightness_77(gspca_dev);
+		else
+			setbrightness_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setcontrast_77(gspca_dev);
+		else
+			setcontrast_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
+static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->satur = val;
+	if (gspca_dev->streaming)
+		setsatur(gspca_dev);
+	return 0;
+}
+
+static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->satur;
+	return 0;
+}
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->lightfreq = val;
+	if (gspca_dev->streaming)
+		setfreq(gspca_dev);
+	return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->lightfreq;
+	return 0;
+}
+
+static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->redblc = val;
+	if (gspca_dev->streaming)
+		setredblc(gspca_dev);
+	return 0;
+}
+
+static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->redblc;
+	return 0;
+}
+
+static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->blueblc = val;
+	if (gspca_dev->streaming)
+		setblueblc(gspca_dev);
+	return 0;
+}
+
+static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->blueblc;
+	return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hue = val;
+	if (gspca_dev->streaming)
+		sethue(gspca_dev);
+	return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hue;
+	return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autogain = val;
+
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X) {
+
+			/* the auto white balance control works only
+			 * when auto gain is set */
+			if (val)
+				gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
+			else
+				gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
+			setautogain_77(gspca_dev);
+		} else {
+			if (val)
+				gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
+			else
+				gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
+			setautogain_96(gspca_dev);
+		}
+	}
+	return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autogain;
+	return 0;
+}
+
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->awb = val;
+	if (gspca_dev->streaming)
+		setawb(gspca_dev);
+	return 0;
+}
+
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->awb;
+	return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->sharpness = val;
+	if (gspca_dev->streaming) {
+		if (sd->sensor == SENSOR_OV772X)
+			setsharpness_77(gspca_dev);
+		else
+			setsharpness_96(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->sharpness;
+	return 0;
+}
+
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hflip = val;
+	if (gspca_dev->streaming)
+		sethflip(gspca_dev);
+	return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hflip;
+	return 0;
+}
+
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vflip = val;
+	if (gspca_dev->streaming)
+		setvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->vflip;
+	return 0;
+}
+
 /* get stream parameters (framerate) */
 static int sd_get_streamparm(struct gspca_dev *gspca_dev,
 			     struct v4l2_streamparm *parm)
@@ -1047,7 +2257,8 @@ static int sd_set_streamparm(struct gspc
 
 	/* Set requested framerate */
 	sd->frame_rate = tpf->denominator / tpf->numerator;
-	ov534_set_frame_rate(gspca_dev);
+	if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
+		set_frame_rate(gspca_dev);
 
 	/* Return the actual framerate */
 	tpf->numerator = 1;
@@ -1056,20 +2267,53 @@ static int sd_set_streamparm(struct gspc
 	return 0;
 }
 
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+			struct v4l2_querymenu *menu)
+{
+	switch (menu->id) {
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		switch (menu->index) {
+		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+			strcpy((char *) menu->name, "NoFliker");
+			return 0;
+		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+			strcpy((char *) menu->name, "50 Hz");
+			return 0;
+		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+			strcpy((char *) menu->name, "60 Hz");
+			return 0;
+		}
+		break;
+	}
+	return -EINVAL;
+}
+
 /* sub-driver description */
-static const struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc_ov772x = {
 	.name     = MODULE_NAME,
-	.ctrls    = sd_ctrls,
-	.nctrls   = ARRAY_SIZE(sd_ctrls),
+	.ctrls    = sd_ctrls_ov772x,
+	.nctrls   = ARRAY_SIZE(sd_ctrls_ov772x),
 	.config   = sd_config,
 	.init     = sd_init,
-	.start    = sd_start,
-	.stopN    = sd_stopN,
+	.start    = sd_start_ov772x,
+	.stopN    = sd_stopN_ov772x,
 	.pkt_scan = sd_pkt_scan,
 	.get_streamparm = sd_get_streamparm,
 	.set_streamparm = sd_set_streamparm,
 };
 
+static const struct sd_desc sd_desc_ov965x = {
+	.name     = MODULE_NAME,
+	.ctrls    = sd_ctrls_ov965x,
+	.nctrls   = ARRAY_SIZE(sd_ctrls_ov965x),
+	.config   = sd_config,
+	.init     = sd_init,
+	.start    = sd_start_ov965x,
+	.stopN    = sd_stopN_ov965x,
+	.pkt_scan = sd_pkt_scan,
+	.querymenu = sd_querymenu,
+};
+
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
@@ -1082,8 +2326,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
 /* -- device connect -- */
 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
-			       THIS_MODULE);
+	return gspca_dev_probe(intf, id,
+				id->driver_info == SENSOR_OV772X
+					? &sd_desc_ov772x
+					: &sd_desc_ov965x,
+				sizeof(struct sd),
+				THIS_MODULE);
 }
 
 static struct usb_driver sd_driver = {
@@ -1101,6 +2349,7 @@ static struct usb_driver sd_driver = {
 static int __init sd_mod_init(void)
 {
 	int ret;
+
 	ret = usb_register(&sd_driver);
 	if (ret < 0)
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac207.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac207.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac207.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac207.c	2010-02-24 13:52:17.000000000 -0500
@@ -337,14 +337,13 @@ static void pac207_do_auto_gain(struct g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data,
+			u8 *data,
 			int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n;
 
@@ -354,10 +353,10 @@ static void sd_pkt_scan(struct gspca_dev
 			n -= sizeof pac_sof_marker;
 		else
 			n = 0;
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, n);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				data, n);
 		sd->header_read = 0;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
 		len -= sof - data;
 		data = sof;
 	}
@@ -381,7 +380,7 @@ static void sd_pkt_scan(struct gspca_dev
 		sd->header_read = 11;
 	}
 
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac7302.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7302.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac7302.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7302.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1283 @@
+/*
+ *		Pixart PAC7302 library
+ *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * Separated from Pixart PAC7311 library by M�rton N�meth <nm127@freemail.hu>
+ *
+ * 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
+ * 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
+ */
+
+/* Some documentation about various registers as determined by trial and error.
+   When the register addresses differ between the 7202 and the 7311 the 2
+   different addresses are written as 7302addr/7311addr, when one of the 2
+   addresses is a - sign that register description is not valid for the
+   matching IC.
+
+   Register page 1:
+
+   Address	Description
+   -/0x08	Unknown compressor related, must always be 8 except when not
+		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
+   -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
+		bits 345 seem to toggle per color gains on/off (inverted)
+   0x78		Global control, bit 6 controls the LED (inverted)
+   -/0x80	JPEG compression ratio ? Best not touched
+
+   Register page 3/4:
+
+   Address	Description
+   0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
+		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
+   -/0x0f	Master gain 1-245, low value = high gain
+   0x10/-	Master gain 0-31
+   -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
+   0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
+   -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
+		completely disable the analog amplification block. Set to 0x68
+		for max gain, 0x14 for minimal gain.
+
+   The registers are accessed in the following functions:
+
+   Page | Register   | Function
+   -----+------------+---------------------------------------------------
+    0   | 0x0f..0x20 | setcolors()
+    0   | 0xa2..0xab | setbrightcont()
+    0   | 0xc5       | setredbalance()
+    0   | 0xc6       | setwhitebalance()
+    0   | 0xc7       | setbluebalance()
+    0   | 0xdc       | setbrightcont(), setcolors()
+    3   | 0x02       | setexposure()
+    3   | 0x10       | setgain()
+    3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
+    3   | 0x21       | sethvflip()
+*/
+
+#define MODULE_NAME "pac7302"
+
+#include <media/v4l2-chip-ident.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
+MODULE_DESCRIPTION("Pixart PAC7302");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor for pac7302 */
+struct sd {
+	struct gspca_dev gspca_dev;		/* !! must be the first item */
+
+	unsigned char brightness;
+	unsigned char contrast;
+	unsigned char colors;
+	unsigned char white_balance;
+	unsigned char red_balance;
+	unsigned char blue_balance;
+	unsigned char gain;
+	unsigned char exposure;
+	unsigned char autogain;
+	__u8 hflip;
+	__u8 vflip;
+	u8 flags;
+#define FL_HFLIP 0x01		/* mirrored by default */
+#define FL_VFLIP 0x02		/* vertical flipped by default */
+
+	u8 sof_read;
+	u8 autogain_ignore_frames;
+
+	atomic_t avg_lum;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+/* This control is pac7302 only */
+	{
+	    {
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+#define BRIGHTNESS_MAX 0x20
+		.maximum = BRIGHTNESS_MAX,
+		.step    = 1,
+#define BRIGHTNESS_DEF 0x10
+		.default_value = BRIGHTNESS_DEF,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+/* This control is for both the 7302 and the 7311 */
+	{
+	    {
+		.id      = V4L2_CID_CONTRAST,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Contrast",
+		.minimum = 0,
+#define CONTRAST_MAX 255
+		.maximum = CONTRAST_MAX,
+		.step    = 1,
+#define CONTRAST_DEF 127
+		.default_value = CONTRAST_DEF,
+	    },
+	    .set = sd_setcontrast,
+	    .get = sd_getcontrast,
+	},
+/* This control is pac7302 only */
+	{
+	    {
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Saturation",
+		.minimum = 0,
+#define COLOR_MAX 255
+		.maximum = COLOR_MAX,
+		.step    = 1,
+#define COLOR_DEF 127
+		.default_value = COLOR_DEF,
+	    },
+	    .set = sd_setcolors,
+	    .get = sd_getcolors,
+	},
+	{
+	    {
+		.id      = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "White Balance",
+		.minimum = 0,
+		.maximum = 255,
+		.step    = 1,
+#define WHITEBALANCE_DEF 4
+		.default_value = WHITEBALANCE_DEF,
+	    },
+	    .set = sd_setwhitebalance,
+	    .get = sd_getwhitebalance,
+	},
+	{
+	    {
+		.id      = V4L2_CID_RED_BALANCE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Red",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define REDBALANCE_DEF 1
+		.default_value = REDBALANCE_DEF,
+	    },
+	    .set = sd_setredbalance,
+	    .get = sd_getredbalance,
+	},
+	{
+	    {
+		.id      = V4L2_CID_BLUE_BALANCE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Blue",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define BLUEBALANCE_DEF 1
+		.default_value = BLUEBALANCE_DEF,
+	    },
+	    .set = sd_setbluebalance,
+	    .get = sd_getbluebalance,
+	},
+/* All controls below are for both the 7302 and the 7311 */
+	{
+	    {
+		.id      = V4L2_CID_GAIN,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Gain",
+		.minimum = 0,
+#define GAIN_MAX 255
+		.maximum = GAIN_MAX,
+		.step    = 1,
+#define GAIN_DEF 127
+#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
+		.default_value = GAIN_DEF,
+	    },
+	    .set = sd_setgain,
+	    .get = sd_getgain,
+	},
+	{
+	    {
+		.id      = V4L2_CID_EXPOSURE,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Exposure",
+		.minimum = 0,
+#define EXPOSURE_MAX 255
+		.maximum = EXPOSURE_MAX,
+		.step    = 1,
+#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
+#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+		.default_value = EXPOSURE_DEF,
+	    },
+	    .set = sd_setexposure,
+	    .get = sd_getexposure,
+	},
+	{
+	    {
+		.id      = V4L2_CID_AUTOGAIN,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Auto Gain",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
+	    },
+	    .set = sd_setautogain,
+	    .get = sd_getautogain,
+	},
+	{
+	    {
+		.id      = V4L2_CID_HFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Mirror",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define HFLIP_DEF 0
+		.default_value = HFLIP_DEF,
+	    },
+	    .set = sd_sethflip,
+	    .get = sd_gethflip,
+	},
+	{
+	    {
+		.id      = V4L2_CID_VFLIP,
+		.type    = V4L2_CTRL_TYPE_BOOLEAN,
+		.name    = "Vflip",
+		.minimum = 0,
+		.maximum = 1,
+		.step    = 1,
+#define VFLIP_DEF 0
+		.default_value = VFLIP_DEF,
+	    },
+	    .set = sd_setvflip,
+	    .get = sd_getvflip,
+	},
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 3 / 8 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+};
+
+#define LOAD_PAGE3		255
+#define LOAD_PAGE4		254
+#define END_OF_SEQUENCE		0
+
+/* pac 7302 */
+static const __u8 init_7302[] = {
+/*	index,value */
+	0xff, 0x01,		/* page 1 */
+	0x78, 0x00,		/* deactivate */
+	0xff, 0x01,
+	0x78, 0x40,		/* led off */
+};
+static const __u8 start_7302[] = {
+/*	index, len, [value]* */
+	0xff, 1,	0x00,		/* page 0 */
+	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
+			0x00, 0x00, 0x00, 0x00,
+	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
+			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
+			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
+	0x26, 2,	0xaa, 0xaa,
+	0x2e, 1,	0x31,
+	0x38, 1,	0x01,
+	0x3a, 3,	0x14, 0xff, 0x5a,
+	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
+			0x00, 0x54, 0x11,
+	0x55, 1,	0x00,
+	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
+	0x6b, 1,	0x00,
+	0x6e, 3,	0x08, 0x06, 0x00,
+	0x72, 3,	0x00, 0xff, 0x00,
+	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
+			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
+			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
+	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
+			0xd2, 0xeb,
+	0xaf, 1,	0x02,
+	0xb5, 2,	0x08, 0x08,
+	0xb8, 2,	0x08, 0x88,
+	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
+	0xcc, 1,	0x00,
+	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
+			0xc1, 0xd7, 0xec,
+	0xdc, 1,	0x01,
+	0xff, 1,	0x01,		/* page 1 */
+	0x12, 3,	0x02, 0x00, 0x01,
+	0x3e, 2,	0x00, 0x00,
+	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
+	0x7c, 1,	0x00,
+	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
+			0x02, 0x00,
+	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
+	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
+	0xd8, 1,	0x01,
+	0xdb, 2,	0x00, 0x01,
+	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
+	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
+	0xeb, 1,	0x00,
+	0xff, 1,	0x02,		/* page 2 */
+	0x22, 1,	0x00,
+	0xff, 1,	0x03,		/* page 3 */
+	0, LOAD_PAGE3,			/* load the page 3 */
+	0x11, 1,	0x01,
+	0xff, 1,	0x02,		/* page 2 */
+	0x13, 1,	0x00,
+	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
+	0x27, 2,	0x14, 0x0c,
+	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
+	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
+	0x6e, 1,	0x08,
+	0xff, 1,	0x01,		/* page 1 */
+	0x78, 1,	0x00,
+	0, END_OF_SEQUENCE		/* end of sequence */
+};
+
+#define SKIP		0xaa
+/* page 3 - the value SKIP says skip the index - see reg_w_page() */
+static const __u8 page3_7302[] = {
+	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
+	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
+	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
+	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
+	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
+	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
+	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
+	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
+	0x00
+};
+
+static int reg_w_buf(struct gspca_dev *gspca_dev,
+		  __u8 index,
+		  const char *buffer, int len)
+{
+	int ret;
+
+	memcpy(gspca_dev->usb_buf, buffer, len);
+	ret = usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			1,		/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0,		/* value */
+			index, gspca_dev->usb_buf, len,
+			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w_buf(): "
+		"Failed to write registers to index 0x%x, error %i",
+		index, ret);
+	return ret;
+}
+
+
+static int reg_w(struct gspca_dev *gspca_dev,
+		  __u8 index,
+		  __u8 value)
+{
+	int ret;
+
+	gspca_dev->usb_buf[0] = value;
+	ret = usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0,			/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, index, gspca_dev->usb_buf, 1,
+			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w(): "
+		"Failed to write register to index 0x%x, value 0x%x, error %i",
+		index, value, ret);
+	return ret;
+}
+
+static int reg_w_seq(struct gspca_dev *gspca_dev,
+		const __u8 *seq, int len)
+{
+	int ret = 0;
+	while (--len >= 0) {
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, seq[0], seq[1]);
+		seq += 2;
+	}
+	return ret;
+}
+
+/* load the beginning of a page */
+static int reg_w_page(struct gspca_dev *gspca_dev,
+			const __u8 *page, int len)
+{
+	int index;
+	int ret = 0;
+
+	for (index = 0; index < len; index++) {
+		if (page[index] == SKIP)		/* skip this index */
+			continue;
+		gspca_dev->usb_buf[0] = page[index];
+		ret = usb_control_msg(gspca_dev->dev,
+				usb_sndctrlpipe(gspca_dev->dev, 0),
+				0,			/* request */
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0, index, gspca_dev->usb_buf, 1,
+				500);
+		if (ret < 0) {
+			PDEBUG(D_ERR, "reg_w_page(): "
+			"Failed to write register to index 0x%x, "
+			"value 0x%x, error %i",
+			index, page[index], ret);
+			break;
+		}
+	}
+	return ret;
+}
+
+/* output a variable sequence */
+static int reg_w_var(struct gspca_dev *gspca_dev,
+			const __u8 *seq,
+			const __u8 *page3, unsigned int page3_len,
+			const __u8 *page4, unsigned int page4_len)
+{
+	int index, len;
+	int ret = 0;
+
+	for (;;) {
+		index = *seq++;
+		len = *seq++;
+		switch (len) {
+		case END_OF_SEQUENCE:
+			return ret;
+		case LOAD_PAGE4:
+			ret = reg_w_page(gspca_dev, page4, page4_len);
+			break;
+		case LOAD_PAGE3:
+			ret = reg_w_page(gspca_dev, page3, page3_len);
+			break;
+		default:
+			if (len > USB_BUF_SZ) {
+				PDEBUG(D_ERR|D_STREAM,
+					"Incorrect variable sequence");
+				return -EINVAL;
+			}
+			while (len > 0) {
+				if (len < 8) {
+					ret = reg_w_buf(gspca_dev,
+						index, seq, len);
+					if (ret < 0)
+						return ret;
+					seq += len;
+					break;
+				}
+				ret = reg_w_buf(gspca_dev, index, seq, 8);
+				seq += 8;
+				index += 8;
+				len -= 8;
+			}
+		}
+		if (ret < 0)
+			return ret;
+	}
+	/* not reached */
+}
+
+/* this function is called at probe time for pac7302 */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam;
+
+	cam = &gspca_dev->cam;
+
+	PDEBUG(D_CONF, "Find Sensor PAC7302");
+	cam->cam_mode = vga_mode;	/* only 640x480 */
+	cam->nmodes = ARRAY_SIZE(vga_mode);
+
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->colors = COLOR_DEF;
+	sd->white_balance = WHITEBALANCE_DEF;
+	sd->red_balance = REDBALANCE_DEF;
+	sd->blue_balance = BLUEBALANCE_DEF;
+	sd->gain = GAIN_DEF;
+	sd->exposure = EXPOSURE_DEF;
+	sd->autogain = AUTOGAIN_DEF;
+	sd->hflip = HFLIP_DEF;
+	sd->vflip = VFLIP_DEF;
+	sd->flags = id->driver_info;
+	return 0;
+}
+
+/* This function is used by pac7302 only */
+static int setbrightcont(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, v;
+	int ret;
+	static const __u8 max[10] =
+		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
+		 0xd4, 0xec};
+	static const __u8 delta[10] =
+		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
+		 0x11, 0x0b};
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 10; i++) {
+		v = max[i];
+		v += (sd->brightness - BRIGHTNESS_MAX)
+			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
+		v -= delta[i] * sd->contrast / CONTRAST_MAX;
+		if (v < 0)
+			v = 0;
+		else if (v > 0xff)
+			v = 0xff;
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xa2 + i, v);
+	}
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	return ret;
+}
+
+/* This function is used by pac7302 only */
+static int setcolors(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, v;
+	int ret;
+	static const int a[9] =
+		{217, -212, 0, -101, 170, -67, -38, -315, 355};
+	static const int b[9] =
+		{19, 106, 0, 19, 106, 1, 19, 106, 1};
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	for (i = 0; i < 9; i++) {
+		v = a[i] * sd->colors / COLOR_MAX + b[i];
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
+	}
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
+	return ret;
+}
+
+static int setwhitebalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
+	return ret;
+}
+
+static int setredbalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
+	return ret;
+}
+
+static int setbluebalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
+
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xdc, 0x01);
+	PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
+	return ret;
+}
+
+static int setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
+
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+static int setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+	__u8 reg;
+
+	/* register 2 of frame 3/4 contains the clock divider configuring the
+	   no fps according to the formula: 60 / reg. sd->exposure is the
+	   desired exposure time in ms. */
+	reg = 120 * sd->exposure / 1000;
+	if (reg < 2)
+		reg = 2;
+	else if (reg > 63)
+		reg = 63;
+
+	/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
+	   the nearest multiple of 3, except when between 6 and 12? */
+	if (reg < 6 || reg > 12)
+		reg = ((reg + 1) / 3) * 3;
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x02, reg);
+
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+static int sethvflip(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
+	u8 data, hflip, vflip;
+
+	hflip = sd->hflip;
+	if (sd->flags & FL_HFLIP)
+		hflip = !hflip;
+	vflip = sd->vflip;
+	if (sd->flags & FL_VFLIP)
+		vflip = !vflip;
+
+	ret = reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
+	data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x21, data);
+	/* load registers to sensor (Bit 0, auto clear) */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
+}
+
+/* this function is called at probe and resume time for pac7302 */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->sof_read = 0;
+
+	ret = reg_w_var(gspca_dev, start_7302,
+		page3_7302, sizeof(page3_7302),
+		NULL, 0);
+	if (0 <= ret)
+		ret = setbrightcont(gspca_dev);
+	if (0 <= ret)
+		ret = setcolors(gspca_dev);
+	if (0 <= ret)
+		ret = setwhitebalance(gspca_dev);
+	if (0 <= ret)
+		ret = setredbalance(gspca_dev);
+	if (0 <= ret)
+		ret = setbluebalance(gspca_dev);
+	if (0 <= ret)
+		ret = setgain(gspca_dev);
+	if (0 <= ret)
+		ret = setexposure(gspca_dev);
+	if (0 <= ret)
+		ret = sethvflip(gspca_dev);
+
+	/* only resolution 640x480 is supported for pac7302 */
+
+	sd->sof_read = 0;
+	sd->autogain_ignore_frames = 0;
+	atomic_set(&sd->avg_lum, -1);
+
+	/* start stream */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x01);
+
+	return ret;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	/* stop stream */
+	ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x00);
+}
+
+/* called on streamoff with alt 0 and on disconnect for pac7302 */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	if (!gspca_dev->present)
+		return;
+	ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x40);
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void do_autogain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int avg_lum = atomic_read(&sd->avg_lum);
+	int desired_lum, deadzone;
+
+	if (avg_lum == -1)
+		return;
+
+	desired_lum = 270 + sd->brightness * 4;
+	/* Hack hack, with the 7202 the first exposure step is
+	   pretty large, so if we're about to make the first
+	   exposure increase make the deadzone large to avoid
+	   oscilating */
+	if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
+			sd->exposure > EXPOSURE_DEF &&
+			sd->exposure < 42)
+		deadzone = 90;
+	else
+		deadzone = 30;
+
+	if (sd->autogain_ignore_frames > 0)
+		sd->autogain_ignore_frames--;
+	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
+			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
+		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
+}
+
+/* JPEG header, part 1 */
+static const unsigned char pac_jpeg_header1[] = {
+  0xff, 0xd8,		/* SOI: Start of Image */
+
+  0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
+  0x00, 0x11,		/* length = 17 bytes (including this length field) */
+  0x08			/* Precision: 8 */
+  /* 2 bytes is placed here: number of image lines */
+  /* 2 bytes is placed here: samples per line */
+};
+
+/* JPEG header, continued */
+static const unsigned char pac_jpeg_header2[] = {
+  0x03,			/* Number of image components: 3 */
+  0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
+  0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
+  0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
+
+  0xff, 0xda,		/* SOS: Start Of Scan */
+  0x00, 0x0c,		/* length = 12 bytes (including this length field) */
+  0x03,			/* number of components: 3 */
+  0x01, 0x00,		/* selector 1, table 0x00 */
+  0x02, 0x11,		/* selector 2, table 0x11 */
+  0x03, 0x11,		/* selector 3, table 0x11 */
+  0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
+  0x00			/* Successive approximation: 0 */
+};
+
+static void pac_start_frame(struct gspca_dev *gspca_dev,
+		struct gspca_frame *frame,
+		__u16 lines, __u16 samples_per_line)
+{
+	unsigned char tmpbuf[4];
+
+	gspca_frame_add(gspca_dev, FIRST_PACKET,
+		pac_jpeg_header1, sizeof(pac_jpeg_header1));
+
+	tmpbuf[0] = lines >> 8;
+	tmpbuf[1] = lines & 0xff;
+	tmpbuf[2] = samples_per_line >> 8;
+	tmpbuf[3] = samples_per_line & 0xff;
+
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		tmpbuf, sizeof(tmpbuf));
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		pac_jpeg_header2, sizeof(pac_jpeg_header2));
+}
+
+/* this function is run at interrupt level */
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct gspca_frame *frame;
+	unsigned char *sof;
+
+	sof = pac_find_sof(&sd->sof_read, data, len);
+	if (sof) {
+		int n, lum_offset, footer_length;
+
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+
+		/* 6 bytes after the FF D9 EOF marker a number of lumination
+		   bytes are send corresponding to different parts of the
+		   image, the 14th and 15th byte after the EOF seem to
+		   correspond to the center of the image */
+		lum_offset = 61 + sizeof pac_sof_marker;
+		footer_length = 74;
+
+		/* Finish decoding current frame */
+		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
+		if (n < 0) {
+			frame->data_end += n;
+			n = 0;
+		}
+		gspca_frame_add(gspca_dev, INTER_PACKET,
+					data, n);
+		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
+				frame->data_end[-2] == 0xff &&
+				frame->data_end[-1] == 0xd9)
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+
+		n = sof - data;
+		len -= n;
+		data = sof;
+
+		/* Get average lumination */
+		if (gspca_dev->last_packet_type == LAST_PACKET &&
+				n >= lum_offset)
+			atomic_set(&sd->avg_lum, data[-lum_offset] +
+						data[-lum_offset + 1]);
+		else
+			atomic_set(&sd->avg_lum, -1);
+
+		/* Start the new frame with the jpeg header */
+		/* The PAC7302 has the image rotated 90 degrees */
+		pac_start_frame(gspca_dev, frame,
+			gspca_dev->width, gspca_dev->height);
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming)
+		setbrightcont(gspca_dev);
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming) {
+		setbrightcont(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->colors = val;
+	if (gspca_dev->streaming)
+		setcolors(gspca_dev);
+	return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->colors;
+	return 0;
+}
+
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->white_balance = val;
+	if (gspca_dev->streaming)
+		ret = setwhitebalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->white_balance;
+	return 0;
+}
+
+static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->red_balance = val;
+	if (gspca_dev->streaming)
+		ret = setredbalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->red_balance;
+	return 0;
+}
+
+static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int ret = 0;
+
+	sd->blue_balance = val;
+	if (gspca_dev->streaming)
+		ret = setbluebalance(gspca_dev);
+	if (0 <= ret)
+		ret = 0;
+	return ret;
+}
+
+static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->blue_balance;
+	return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->autogain = val;
+	/* when switching to autogain set defaults to make sure
+	   we are on a valid point of the autogain gain /
+	   exposure knee graph, and give this change time to
+	   take effect before doing autogain. */
+	if (sd->autogain) {
+		sd->exposure = EXPOSURE_DEF;
+		sd->gain = GAIN_DEF;
+		if (gspca_dev->streaming) {
+			sd->autogain_ignore_frames =
+				PAC_AUTOGAIN_IGNORE_FRAMES;
+			setexposure(gspca_dev);
+			setgain(gspca_dev);
+		}
+	}
+
+	return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->autogain;
+	return 0;
+}
+
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hflip;
+	return 0;
+}
+
+static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vflip = val;
+	if (gspca_dev->streaming)
+		sethvflip(gspca_dev);
+	return 0;
+}
+
+static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->vflip;
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
+			struct v4l2_dbg_register *reg)
+{
+	int ret = -EINVAL;
+	__u8 index;
+	__u8 value;
+
+	/* 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 &&
+	    (reg->reg < 0x000000ff) &&
+	    (reg->val <= 0x000000ff)
+	) {
+		/* Currently writing to page 0 is only supported. */
+		/* reg_w() only supports 8bit index */
+		index = reg->reg & 0x000000ff;
+		value = reg->val & 0x000000ff;
+
+		/* Note that there shall be no access to other page
+		   by any other function between the page swith and
+		   the actual register write */
+		ret = reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, index, value);
+
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xdc, 0x01);
+	}
+	return ret;
+}
+
+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
+
+/* sub-driver description for pac7302 */
+static struct sd_desc sd_desc = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.config = sd_config,
+	.init = sd_init,
+	.start = sd_start,
+	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
+	.pkt_scan = sd_pkt_scan,
+	.dq_callback = do_autogain,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.set_register = sd_dbg_s_register,
+	.get_chip_ident = sd_chip_ident,
+#endif
+};
+
+/* -- module initialisation -- */
+static const struct usb_device_id device_table[] __devinitconst = {
+	{USB_DEVICE(0x06f8, 0x3009)},
+	{USB_DEVICE(0x093a, 0x2620)},
+	{USB_DEVICE(0x093a, 0x2621)},
+	{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
+	{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
+	{USB_DEVICE(0x093a, 0x2626)},
+	{USB_DEVICE(0x093a, 0x2628)},
+	{USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
+	{USB_DEVICE(0x093a, 0x262a)},
+	{USB_DEVICE(0x093a, 0x262c)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int __devinit sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac7311.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7311.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac7311.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac7311.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,23 +57,17 @@ MODULE_AUTHOR("Thomas Kaiser thomas@kais
 MODULE_DESCRIPTION("Pixart PAC7311");
 MODULE_LICENSE("GPL");
 
-/* specific webcam descriptor */
+/* specific webcam descriptor for pac7311 */
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	unsigned char brightness;
 	unsigned char contrast;
-	unsigned char colors;
 	unsigned char gain;
 	unsigned char exposure;
 	unsigned char autogain;
 	__u8 hflip;
 	__u8 vflip;
 
-	__u8 sensor;
-#define SENSOR_PAC7302 0
-#define SENSOR_PAC7311 1
-
 	u8 sof_read;
 	u8 autogain_ignore_frames;
 
@@ -81,12 +75,8 @@ struct sd {
 };
 
 /* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -99,23 +89,6 @@ static int sd_setexposure(struct gspca_d
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
-/* This control is pac7302 only */
-#define BRIGHTNESS_IDX 0
-	{
-	    {
-		.id      = V4L2_CID_BRIGHTNESS,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Brightness",
-		.minimum = 0,
-#define BRIGHTNESS_MAX 0x20
-		.maximum = BRIGHTNESS_MAX,
-		.step    = 1,
-#define BRIGHTNESS_DEF 0x10
-		.default_value = BRIGHTNESS_DEF,
-	    },
-	    .set = sd_setbrightness,
-	    .get = sd_getbrightness,
-	},
 /* This control is for both the 7302 and the 7311 */
 	{
 	    {
@@ -132,23 +105,6 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
-/* This control is pac7302 only */
-#define SATURATION_IDX 2
-	{
-	    {
-		.id      = V4L2_CID_SATURATION,
-		.type    = V4L2_CTRL_TYPE_INTEGER,
-		.name    = "Saturation",
-		.minimum = 0,
-#define COLOR_MAX 255
-		.maximum = COLOR_MAX,
-		.step    = 1,
-#define COLOR_DEF 127
-		.default_value = COLOR_DEF,
-	    },
-	    .set = sd_setcolors,
-	    .get = sd_getcolors,
-	},
 /* All controls below are for both the 7302 and the 7311 */
 	{
 	    {
@@ -244,101 +200,9 @@ static const struct v4l2_pix_format vga_
 		.priv = 0},
 };
 
-/* pac 7302 */
-static const __u8 init_7302[] = {
-/*	index,value */
-	0xff, 0x01,		/* page 1 */
-	0x78, 0x00,		/* deactivate */
-	0xff, 0x01,
-	0x78, 0x40,		/* led off */
-};
-static const __u8 start_7302[] = {
-/*	index, len, [value]* */
-	0xff, 1,	0x00,		/* page 0 */
-	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
-			0x00, 0x00, 0x00, 0x00,
-	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
-			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
-			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
-	0x26, 2,	0xaa, 0xaa,
-	0x2e, 1,	0x31,
-	0x38, 1,	0x01,
-	0x3a, 3,	0x14, 0xff, 0x5a,
-	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
-			0x00, 0x54, 0x11,
-	0x55, 1,	0x00,
-	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
-	0x6b, 1,	0x00,
-	0x6e, 3,	0x08, 0x06, 0x00,
-	0x72, 3,	0x00, 0xff, 0x00,
-	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
-			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
-			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
-	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
-			0xd2, 0xeb,
-	0xaf, 1,	0x02,
-	0xb5, 2,	0x08, 0x08,
-	0xb8, 2,	0x08, 0x88,
-	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
-	0xcc, 1,	0x00,
-	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
-			0xc1, 0xd7, 0xec,
-	0xdc, 1,	0x01,
-	0xff, 1,	0x01,		/* page 1 */
-	0x12, 3,	0x02, 0x00, 0x01,
-	0x3e, 2,	0x00, 0x00,
-	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
-	0x7c, 1,	0x00,
-	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
-			0x02, 0x00,
-	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
-	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
-	0xd8, 1,	0x01,
-	0xdb, 2,	0x00, 0x01,
-	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
-	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
-	0xeb, 1,	0x00,
-	0xff, 1,	0x02,		/* page 2 */
-	0x22, 1,	0x00,
-	0xff, 1,	0x03,		/* page 3 */
-	0x00, 255,			/* load the page 3 */
-	0x11, 1,	0x01,
-	0xff, 1,	0x02,		/* page 2 */
-	0x13, 1,	0x00,
-	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
-	0x27, 2,	0x14, 0x0c,
-	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
-	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
-	0x6e, 1,	0x08,
-	0xff, 1,	0x01,		/* page 1 */
-	0x78, 1,	0x00,
-	0, 0				/* end of sequence */
-};
-
-/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
-static const __u8 page3_7302[] = {
-	0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
-	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
-	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
-	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
-	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
-	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
-	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
-	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
-	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
-	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
-	0x00
-};
+#define LOAD_PAGE3		255
+#define LOAD_PAGE4		254
+#define END_OF_SEQUENCE		0
 
 /* pac 7311 */
 static const __u8 init_7311[] = {
@@ -378,119 +242,154 @@ static const __u8 start_7311[] = {
 	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
 			0x3f, 0x00, 0x0a, 0x01, 0x00,
 	0xff, 1,	0x04,		/* page 4 */
-	0x00, 254,			/* load the page 4 */
+	0, LOAD_PAGE4,			/* load the page 4 */
 	0x11, 1,	0x01,
-	0, 0				/* end of sequence */
+	0, END_OF_SEQUENCE		/* end of sequence */
 };
 
-/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
+#define SKIP		0xaa
+/* page 4 - the value SKIP says skip the index - see reg_w_page() */
 static const __u8 page4_7311[] = {
-	0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
-	0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
-	0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
-	0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
+	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
+	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
+	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
+	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
 	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
 	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 };
 
-static void reg_w_buf(struct gspca_dev *gspca_dev,
+static int reg_w_buf(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  const char *buffer, int len)
 {
+	int ret;
+
 	memcpy(gspca_dev->usb_buf, buffer, len);
-	usb_control_msg(gspca_dev->dev,
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			1,		/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,		/* value */
 			index, gspca_dev->usb_buf, len,
 			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w_buf(): "
+		"Failed to write registers to index 0x%x, error %i",
+		index, ret);
+	return ret;
 }
 
 
-static void reg_w(struct gspca_dev *gspca_dev,
+static int reg_w(struct gspca_dev *gspca_dev,
 		  __u8 index,
 		  __u8 value)
 {
+	int ret;
+
 	gspca_dev->usb_buf[0] = value;
-	usb_control_msg(gspca_dev->dev,
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0,			/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index, gspca_dev->usb_buf, 1,
 			500);
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg_w(): "
+		"Failed to write register to index 0x%x, value 0x%x, error %i",
+		index, value, ret);
+	return ret;
 }
 
-static void reg_w_seq(struct gspca_dev *gspca_dev,
+static int reg_w_seq(struct gspca_dev *gspca_dev,
 		const __u8 *seq, int len)
 {
+	int ret = 0;
 	while (--len >= 0) {
-		reg_w(gspca_dev, seq[0], seq[1]);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, seq[0], seq[1]);
 		seq += 2;
 	}
+	return ret;
 }
 
 /* load the beginning of a page */
-static void reg_w_page(struct gspca_dev *gspca_dev,
+static int reg_w_page(struct gspca_dev *gspca_dev,
 			const __u8 *page, int len)
 {
 	int index;
+	int ret = 0;
 
 	for (index = 0; index < len; index++) {
-		if (page[index] == 0xaa)		/* skip this index */
+		if (page[index] == SKIP)		/* skip this index */
 			continue;
 		gspca_dev->usb_buf[0] = page[index];
-		usb_control_msg(gspca_dev->dev,
+		ret = usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
 				0,			/* request */
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				0, index, gspca_dev->usb_buf, 1,
 				500);
+		if (ret < 0) {
+			PDEBUG(D_ERR, "reg_w_page(): "
+			"Failed to write register to index 0x%x, "
+			"value 0x%x, error %i",
+			index, page[index], ret);
+			break;
+		}
 	}
+	return ret;
 }
 
 /* output a variable sequence */
-static void reg_w_var(struct gspca_dev *gspca_dev,
-			const __u8 *seq)
+static int reg_w_var(struct gspca_dev *gspca_dev,
+			const __u8 *seq,
+			const __u8 *page3, unsigned int page3_len,
+			const __u8 *page4, unsigned int page4_len)
 {
 	int index, len;
+	int ret = 0;
 
 	for (;;) {
 		index = *seq++;
 		len = *seq++;
 		switch (len) {
-		case 0:
-			return;
-		case 254:
-			reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
+		case END_OF_SEQUENCE:
+			return ret;
+		case LOAD_PAGE4:
+			ret = reg_w_page(gspca_dev, page4, page4_len);
 			break;
-		case 255:
-			reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
+		case LOAD_PAGE3:
+			ret = reg_w_page(gspca_dev, page3, page3_len);
 			break;
 		default:
-			if (len > 64) {
+			if (len > USB_BUF_SZ) {
 				PDEBUG(D_ERR|D_STREAM,
 					"Incorrect variable sequence");
-				return;
+				return -EINVAL;
 			}
 			while (len > 0) {
 				if (len < 8) {
-					reg_w_buf(gspca_dev, index, seq, len);
+					ret = reg_w_buf(gspca_dev,
+						index, seq, len);
+					if (ret < 0)
+						return ret;
 					seq += len;
 					break;
 				}
-				reg_w_buf(gspca_dev, index, seq, 8);
+				ret = reg_w_buf(gspca_dev, index, seq, 8);
 				seq += 8;
 				index += 8;
 				len -= 8;
 			}
 		}
+		if (ret < 0)
+			return ret;
 	}
 	/* not reached */
 }
 
-/* this function is called at probe time */
+/* this function is called at probe time for pac7311 */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
 {
@@ -499,22 +398,11 @@ static int sd_config(struct gspca_dev *g
 
 	cam = &gspca_dev->cam;
 
-	sd->sensor = id->driver_info;
-	if (sd->sensor == SENSOR_PAC7302) {
-		PDEBUG(D_CONF, "Find Sensor PAC7302");
-		cam->cam_mode = &vga_mode[2];	/* only 640x480 */
-		cam->nmodes = 1;
-	} else {
-		PDEBUG(D_CONF, "Find Sensor PAC7311");
-		cam->cam_mode = vga_mode;
-		cam->nmodes = ARRAY_SIZE(vga_mode);
-		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
-				| (1 << SATURATION_IDX);
-	}
+	PDEBUG(D_CONF, "Find Sensor PAC7311");
+	cam->cam_mode = vga_mode;
+	cam->nmodes = ARRAY_SIZE(vga_mode);
 
-	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
-	sd->colors = COLOR_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
 	sd->autogain = AUTOGAIN_DEF;
@@ -523,91 +411,47 @@ static int sd_config(struct gspca_dev *g
 	return 0;
 }
 
-/* This function is used by pac7302 only */
-static void setbrightcont(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int i, v;
-	static const __u8 max[10] =
-		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
-		 0xd4, 0xec};
-	static const __u8 delta[10] =
-		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
-		 0x11, 0x0b};
-
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	for (i = 0; i < 10; i++) {
-		v = max[i];
-		v += (sd->brightness - BRIGHTNESS_MAX)
-			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
-		v -= delta[i] * sd->contrast / CONTRAST_MAX;
-		if (v < 0)
-			v = 0;
-		else if (v > 0xff)
-			v = 0xff;
-		reg_w(gspca_dev, 0xa2 + i, v);
-	}
-	reg_w(gspca_dev, 0xdc, 0x01);
-}
-
 /* This function is used by pac7311 only */
-static void setcontrast(struct gspca_dev *gspca_dev)
+static int setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
+	ret = reg_w(gspca_dev, 0xff, 0x04);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-/* This function is used by pac7302 only */
-static void setcolors(struct gspca_dev *gspca_dev)
+static int setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int i, v;
-	static const int a[9] =
-		{217, -212, 0, -101, 170, -67, -38, -315, 355};
-	static const int b[9] =
-		{19, 106, 0, 19, 106, 1, 19, 106, 1};
-
-	reg_w(gspca_dev, 0xff, 0x03);	/* page 3 */
-	reg_w(gspca_dev, 0x11, 0x01);
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	reg_w(gspca_dev, 0xff, 0x00);	/* page 0 */
-	for (i = 0; i < 9; i++) {
-		v = a[i] * sd->colors / COLOR_MAX + b[i];
-		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
-		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
-	}
-	reg_w(gspca_dev, 0xdc, 0x01);
-	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
-}
+	int gain = GAIN_MAX - sd->gain;
+	int ret;
 
-static void setgain(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
+	if (gain < 1)
+		gain = 1;
+	else if (gain > 245)
+		gain = 245;
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x0e, 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x0f, gain);
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		reg_w(gspca_dev, 0x10, sd->gain >> 3);
-	} else {
-		int gain = GAIN_MAX - sd->gain;
-		if (gain < 1)
-			gain = 1;
-		else if (gain > 245)
-			gain = 245;
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		reg_w(gspca_dev, 0x0e, 0x00);
-		reg_w(gspca_dev, 0x0f, gain);
-	}
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-static void setexposure(struct gspca_dev *gspca_dev)
+static int setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 	__u8 reg;
 
 	/* register 2 of frame 3/4 contains the clock divider configuring the
@@ -619,97 +463,94 @@ static void setexposure(struct gspca_dev
 	else if (reg > 63)
 		reg = 63;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		/* On the pac7302 reg2 MUST be a multiple of 3, so round it to
-		   the nearest multiple of 3, except when between 6 and 12? */
-		if (reg < 6 || reg > 12)
-			reg = ((reg + 1) / 3) * 3;
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		reg_w(gspca_dev, 0x02, reg);
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x02, reg);
+	/* Page 1 register 8 must always be 0x08 except when not in
+	   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
+			reg <= 3) {
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x08, 0x09);
 	} else {
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		reg_w(gspca_dev, 0x02, reg);
-		/* Page 1 register 8 must always be 0x08 except when not in
-		   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
-				reg <= 3)
-			reg_w(gspca_dev, 0x08, 0x09);
-		else
-			reg_w(gspca_dev, 0x08, 0x08);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x08, 0x08);
 	}
+
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-static void sethvflip(struct gspca_dev *gspca_dev)
+static int sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 	__u8 data;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x03);		/* page 3 */
-		data = (sd->hflip ? 0x08 : 0x00)
-			| (sd->vflip ? 0x04 : 0x00);
-	} else {
-		reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
-		data = (sd->hflip ? 0x04 : 0x00)
-			| (sd->vflip ? 0x08 : 0x00);
-	}
-	reg_w(gspca_dev, 0x21, data);
+	ret = reg_w(gspca_dev, 0xff, 0x04);		/* page 4 */
+	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x21, data);
 	/* load registers to sensor (Bit 0, auto clear) */
-	reg_w(gspca_dev, 0x11, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x11, 0x01);
+	return ret;
 }
 
-/* this function is called at probe and resume time */
+/* this function is called at probe and resume time for pac7311 */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	if (sd->sensor == SENSOR_PAC7302)
-		reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
-	else
-		reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
-
-	return 0;
+	return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
 	sd->sof_read = 0;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w_var(gspca_dev, start_7302);
-		setbrightcont(gspca_dev);
-		setcolors(gspca_dev);
-	} else {
-		reg_w_var(gspca_dev, start_7311);
-		setcontrast(gspca_dev);
-	}
-	setgain(gspca_dev);
-	setexposure(gspca_dev);
-	sethvflip(gspca_dev);
+	ret = reg_w_var(gspca_dev, start_7311,
+		NULL, 0,
+		page4_7311, sizeof(page4_7311));
+	if (0 <= ret)
+		ret = setcontrast(gspca_dev);
+	if (0 <= ret)
+		ret = setgain(gspca_dev);
+	if (0 <= ret)
+		ret = setexposure(gspca_dev);
+	if (0 <= ret)
+		ret = sethvflip(gspca_dev);
 
 	/* set correct resolution */
 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 	case 2:					/* 160x120 pac7311 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x20);
-		reg_w(gspca_dev, 0x87, 0x10);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x20);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x10);
 		break;
 	case 1:					/* 320x240 pac7311 */
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x30);
-		reg_w(gspca_dev, 0x87, 0x11);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x30);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x11);
 		break;
 	case 0:					/* 640x480 */
-		if (sd->sensor == SENSOR_PAC7302)
-			break;
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x17, 0x00);
-		reg_w(gspca_dev, 0x87, 0x12);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0xff, 0x01);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x17, 0x00);
+		if (0 <= ret)
+			ret = reg_w(gspca_dev, 0x87, 0x12);
 		break;
 	}
 
@@ -718,47 +559,42 @@ static int sd_start(struct gspca_dev *gs
 	atomic_set(&sd->avg_lum, -1);
 
 	/* start stream */
-	reg_w(gspca_dev, 0xff, 0x01);
-	if (sd->sensor == SENSOR_PAC7302)
-		reg_w(gspca_dev, 0x78, 0x01);
-	else
-		reg_w(gspca_dev, 0x78, 0x05);
-	return 0;
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x05);
+
+	return ret;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
+	int ret;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x78, 0x00);
-		reg_w(gspca_dev, 0x78, 0x00);
-		return;
-	}
-	reg_w(gspca_dev, 0xff, 0x04);
-	reg_w(gspca_dev, 0x27, 0x80);
-	reg_w(gspca_dev, 0x28, 0xca);
-	reg_w(gspca_dev, 0x29, 0x53);
-	reg_w(gspca_dev, 0x2a, 0x0e);
-	reg_w(gspca_dev, 0xff, 0x01);
-	reg_w(gspca_dev, 0x3e, 0x20);
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
-	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	ret = reg_w(gspca_dev, 0xff, 0x04);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x27, 0x80);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x28, 0xca);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x29, 0x53);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x2a, 0x0e);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0xff, 0x01);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x3e, 0x20);
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
+	if (0 <= ret)
+		ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 }
 
-/* called on streamoff with alt 0 and on disconnect */
+/* called on streamoff with alt 0 and on disconnect for 7311 */
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	if (!gspca_dev->present)
-		return;
-	if (sd->sensor == SENSOR_PAC7302) {
-		reg_w(gspca_dev, 0xff, 0x01);
-		reg_w(gspca_dev, 0x78, 0x40);
-	}
 }
 
 /* Include pac common sof detection functions */
@@ -773,22 +609,8 @@ static void do_autogain(struct gspca_dev
 	if (avg_lum == -1)
 		return;
 
-	if (sd->sensor == SENSOR_PAC7302) {
-		desired_lum = 270 + sd->brightness * 4;
-		/* Hack hack, with the 7202 the first exposure step is
-		   pretty large, so if we're about to make the first
-		   exposure increase make the deadzone large to avoid
-		   oscilating */
-		if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
-				sd->exposure > EXPOSURE_DEF &&
-				sd->exposure < 42)
-			deadzone = 90;
-		else
-			deadzone = 30;
-	} else {
-		desired_lum = 200;
-		deadzone = 20;
-	}
+	desired_lum = 200;
+	deadzone = 20;
 
 	if (sd->autogain_ignore_frames > 0)
 		sd->autogain_ignore_frames--;
@@ -797,53 +619,92 @@ static void do_autogain(struct gspca_dev
 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 }
 
-static const unsigned char pac7311_jpeg_header1[] = {
-  0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
+/* JPEG header, part 1 */
+static const unsigned char pac_jpeg_header1[] = {
+  0xff, 0xd8,		/* SOI: Start of Image */
+
+  0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
+  0x00, 0x11,		/* length = 17 bytes (including this length field) */
+  0x08			/* Precision: 8 */
+  /* 2 bytes is placed here: number of image lines */
+  /* 2 bytes is placed here: samples per line */
 };
 
-static const unsigned char pac7311_jpeg_header2[] = {
-  0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
-  0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
+/* JPEG header, continued */
+static const unsigned char pac_jpeg_header2[] = {
+  0x03,			/* Number of image components: 3 */
+  0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
+  0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
+  0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
+
+  0xff, 0xda,		/* SOS: Start Of Scan */
+  0x00, 0x0c,		/* length = 12 bytes (including this length field) */
+  0x03,			/* number of components: 3 */
+  0x01, 0x00,		/* selector 1, table 0x00 */
+  0x02, 0x11,		/* selector 2, table 0x11 */
+  0x03, 0x11,		/* selector 3, table 0x11 */
+  0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
+  0x00			/* Successive approximation: 0 */
 };
 
+static void pac_start_frame(struct gspca_dev *gspca_dev,
+		struct gspca_frame *frame,
+		__u16 lines, __u16 samples_per_line)
+{
+	unsigned char tmpbuf[4];
+
+	gspca_frame_add(gspca_dev, FIRST_PACKET,
+		pac_jpeg_header1, sizeof(pac_jpeg_header1));
+
+	tmpbuf[0] = lines >> 8;
+	tmpbuf[1] = lines & 0xff;
+	tmpbuf[2] = samples_per_line >> 8;
+	tmpbuf[3] = samples_per_line & 0xff;
+
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		tmpbuf, sizeof(tmpbuf));
+	gspca_frame_add(gspca_dev, INTER_PACKET,
+		pac_jpeg_header2, sizeof(pac_jpeg_header2));
+}
+
 /* this function is run at interrupt level */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned char *sof;
+	struct gspca_frame *frame;
 
-	sof = pac_find_sof(gspca_dev, data, len);
+	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
-		unsigned char tmpbuf[4];
 		int n, lum_offset, footer_length;
 
-		if (sd->sensor == SENSOR_PAC7302) {
-		  /* 6 bytes after the FF D9 EOF marker a number of lumination
-		     bytes are send corresponding to different parts of the
-		     image, the 14th and 15th byte after the EOF seem to
-		     correspond to the center of the image */
-		  lum_offset = 61 + sizeof pac_sof_marker;
-		  footer_length = 74;
-		} else {
-		  lum_offset = 24 + sizeof pac_sof_marker;
-		  footer_length = 26;
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
 		}
 
+		/* 6 bytes after the FF D9 EOF marker a number of lumination
+		   bytes are send corresponding to different parts of the
+		   image, the 14th and 15th byte after the EOF seem to
+		   correspond to the center of the image */
+		lum_offset = 24 + sizeof pac_sof_marker;
+		footer_length = 26;
+
 		/* Finish decoding current frame */
 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 		if (n < 0) {
 			frame->data_end += n;
 			n = 0;
 		}
-		frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+		gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, n);
 		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
 				frame->data_end[-2] == 0xff &&
 				frame->data_end[-1] == 0xd9)
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+			gspca_frame_add(gspca_dev, LAST_PACKET,
 						NULL, 0);
 
 		n = sof - data;
@@ -859,43 +720,10 @@ static void sd_pkt_scan(struct gspca_dev
 			atomic_set(&sd->avg_lum, -1);
 
 		/* Start the new frame with the jpeg header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-			pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
-		if (sd->sensor == SENSOR_PAC7302) {
-			/* The PAC7302 has the image rotated 90 degrees */
-			tmpbuf[0] = gspca_dev->width >> 8;
-			tmpbuf[1] = gspca_dev->width & 0xff;
-			tmpbuf[2] = gspca_dev->height >> 8;
-			tmpbuf[3] = gspca_dev->height & 0xff;
-		} else {
-			tmpbuf[0] = gspca_dev->height >> 8;
-			tmpbuf[1] = gspca_dev->height & 0xff;
-			tmpbuf[2] = gspca_dev->width >> 8;
-			tmpbuf[3] = gspca_dev->width & 0xff;
-		}
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
+		pac_start_frame(gspca_dev, frame,
+			gspca_dev->height, gspca_dev->width);
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
-}
-
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->brightness = val;
-	if (gspca_dev->streaming)
-		setbrightcont(gspca_dev);
-	return 0;
-}
-
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->brightness;
-	return 0;
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
@@ -904,10 +732,7 @@ static int sd_setcontrast(struct gspca_d
 
 	sd->contrast = val;
 	if (gspca_dev->streaming) {
-		if (sd->sensor == SENSOR_PAC7302)
-			setbrightcont(gspca_dev);
-		else
-			setcontrast(gspca_dev);
+		setcontrast(gspca_dev);
 	}
 	return 0;
 }
@@ -920,24 +745,6 @@ static int sd_getcontrast(struct gspca_d
 	return 0;
 }
 
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->colors = val;
-	if (gspca_dev->streaming)
-		setcolors(gspca_dev);
-	return 0;
-}
-
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	*val = sd->colors;
-	return 0;
-}
-
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1041,7 +848,7 @@ static int sd_getvflip(struct gspca_dev
 	return 0;
 }
 
-/* sub-driver description */
+/* sub-driver description for pac7311 */
 static struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
@@ -1056,28 +863,19 @@ static struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
-	{USB_DEVICE(0x093a, 0x2620), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
-	{USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
+static const struct usb_device_id device_table[] __devinitconst = {
+	{USB_DEVICE(0x093a, 0x2600)},
+	{USB_DEVICE(0x093a, 0x2601)},
+	{USB_DEVICE(0x093a, 0x2603)},
+	{USB_DEVICE(0x093a, 0x2608)},
+	{USB_DEVICE(0x093a, 0x260e)},
+	{USB_DEVICE(0x093a, 0x260f)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 
 /* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
+static int __devinit sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac_common.h linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac_common.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/pac_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/pac_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,26 +33,101 @@
 static const unsigned char pac_sof_marker[5] =
 		{ 0xff, 0xff, 0x00, 0xff, 0x96 };
 
-static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
+/*
+   The following state machine finds the SOF marker sequence
+   0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
+
+	   +----------+
+	   | 0: START |<---------------\
+	   +----------+<-\             |
+	     |       \---/otherwise    |
+	     v 0xff                    |
+	   +----------+ otherwise      |
+	   |     1    |--------------->*
+	   |          |                ^
+	   +----------+                |
+	     |                         |
+	     v 0xff                    |
+	   +----------+<-\0xff         |
+	/->|          |--/             |
+	|  |     2    |--------------->*
+	|  |          | otherwise      ^
+	|  +----------+                |
+	|    |                         |
+	|    v 0x00                    |
+	|  +----------+                |
+	|  |     3    |                |
+	|  |          |--------------->*
+	|  +----------+ otherwise      ^
+	|    |                         |
+   0xff |    v 0xff                    |
+	|  +----------+                |
+	\--|     4    |                |
+	   |          |----------------/
+	   +----------+ otherwise
+	     |
+	     v 0x96
+	   +----------+
+	   |  FOUND   |
+	   +----------+
+*/
+
+static unsigned char *pac_find_sof(u8 *sof_read,
 					unsigned char *m, int len)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
 
 	/* Search for the SOF marker (fixed part) in the header */
 	for (i = 0; i < len; i++) {
-		if (m[i] == pac_sof_marker[sd->sof_read]) {
-			sd->sof_read++;
-			if (sd->sof_read == sizeof(pac_sof_marker)) {
+		switch (*sof_read) {
+		case 0:
+			if (m[i] == 0xff)
+				*sof_read = 1;
+			break;
+		case 1:
+			if (m[i] == 0xff)
+				*sof_read = 2;
+			else
+				*sof_read = 0;
+			break;
+		case 2:
+			switch (m[i]) {
+			case 0x00:
+				*sof_read = 3;
+				break;
+			case 0xff:
+				/* stay in this state */
+				break;
+			default:
+				*sof_read = 0;
+			}
+			break;
+		case 3:
+			if (m[i] == 0xff)
+				*sof_read = 4;
+			else
+				*sof_read = 0;
+			break;
+		case 4:
+			switch (m[i]) {
+			case 0x96:
+				/* Pattern found */
 				PDEBUG(D_FRAM,
 					"SOF found, bytes to analyze: %u."
 					" Frame starts at byte #%u",
 					len, i + 1);
-				sd->sof_read = 0;
+				*sof_read = 0;
 				return m + i + 1;
+				break;
+			case 0xff:
+				*sof_read = 2;
+				break;
+			default:
+				*sof_read = 0;
 			}
-		} else {
-			sd->sof_read = 0;
+			break;
+		default:
+			*sof_read = 0;
 		}
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sn9c20x.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c20x.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sn9c20x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sn9c20x.c	2010-02-24 13:52:17.000000000 -0500
@@ -1158,7 +1158,7 @@ static int i2c_w2(struct gspca_dev *gspc
 	return i2c_w(gspca_dev, row);
 }
 
-int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
+static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 row[8];
@@ -1183,7 +1183,7 @@ int i2c_r1(struct gspca_dev *gspca_dev,
 	return 0;
 }
 
-int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
+static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 row[8];
@@ -1476,8 +1476,9 @@ static int sn9c20x_input_init(struct gsp
 	if (input_register_device(sd->input_dev))
 		return -EINVAL;
 
-	sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d",
-				     gspca_dev->vdev.minor);
+	sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s",
+				     gspca_dev->dev->bus->bus_name,
+				     gspca_dev->dev->devpath);
 
 	if (IS_ERR(sd->input_task))
 		return -EINVAL;
@@ -2174,8 +2175,7 @@ static void configure_sensor_output(stru
 }
 
 #define HW_WIN(mode, hstart, vstart) \
-((const u8 []){hstart & 0xff, hstart >> 8, \
-vstart & 0xff, vstart >> 8, \
+((const u8 []){hstart, 0, vstart, 0, \
 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
 
@@ -2319,7 +2319,7 @@ static void do_autogain(struct gspca_dev
 		}
 	}
 	if (avg_lum > MAX_AVG_LUM) {
-		if (sd->gain - 1 >= 0) {
+		if (sd->gain >= 1) {
 			sd->gain--;
 			set_gain(gspca_dev);
 		}
@@ -2342,7 +2342,6 @@ static void sd_dqcallback(struct gspca_d
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -2378,22 +2377,22 @@ static void sd_pkt_scan(struct gspca_dev
 		avg_lum >>= 9;
 		atomic_set(&sd->avg_lum, avg_lum);
 		gspca_frame_add(gspca_dev, LAST_PACKET,
-				frame, data, len);
+				data, len);
 		return;
 	}
 	if (gspca_dev->last_packet_type == LAST_PACKET) {
 		if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
 				& MODE_JPEG) {
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 				sd->jpeg_hdr, JPEG_HDR_SZ);
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 				data, len);
 		} else {
-			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
 				data, len);
 		}
 	} else {
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sonixb.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sonixb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixb.c	2010-02-24 13:52:17.000000000 -0500
@@ -304,7 +304,7 @@ static const __u8 initOv6650[] = {
 };
 static const __u8 ov6650_sensor_init[][8] =
 {
-	/* Bright, contrast, etc are set througth SCBB interface.
+	/* Bright, contrast, etc are set through SCBB interface.
 	 * AVCAP on win2 do not send any data on this 	controls. */
 	/* Anyway, some registers appears to alter bright and constrat */
 
@@ -995,8 +995,7 @@ static void sd_stopN(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			unsigned char *data,		/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	int i;
@@ -1054,12 +1053,12 @@ static void sd_pkt_scan(struct gspca_dev
 					pkt_type = DISCARD_PACKET;
 				}
 
-				frame = gspca_frame_add(gspca_dev, pkt_type,
-							frame, data, 0);
+				gspca_frame_add(gspca_dev, pkt_type,
+						NULL, 0);
 				data += i + fr_h_sz;
 				len -= i + fr_h_sz;
 				gspca_frame_add(gspca_dev, FIRST_PACKET,
-						frame, data, len);
+						data, len);
 				return;
 			}
 		}
@@ -1068,15 +1067,21 @@ static void sd_pkt_scan(struct gspca_dev
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
 		/* In raw mode we sometimes get some garbage after the frame
 		   ignore this */
-		int used = frame->data_end - frame->data;
+		struct gspca_frame *frame;
+		int used;
 		int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
 
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+		used = frame->data_end - frame->data;
 		if (used + len > size)
 			len = size - used;
 	}
 
-	gspca_frame_add(gspca_dev, INTER_PACKET,
-			frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -1221,7 +1226,7 @@ static const struct sd_desc sd_desc = {
 	.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
 
 
-static __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] __devinitconst = {
 	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
 	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
@@ -1252,7 +1257,7 @@ static __devinitdata struct usb_device_i
 MODULE_DEVICE_TABLE(usb, device_table);
 
 /* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
+static int __devinit sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sonixj.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixj.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sonixj.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sonixj.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,8 @@
 /*
- *		Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
- *		Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
+ * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
  *
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
+ * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
  *
  * 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
@@ -72,8 +72,9 @@ struct sd {
 #define SENSOR_OV7630 5
 #define SENSOR_OV7648 6
 #define SENSOR_OV7660 7
-#define SENSOR_SP80708 8
-	u8 i2c_base;
+#define SENSOR_PO1030 8
+#define SENSOR_SP80708 9
+	u8 i2c_addr;
 
 	u8 *jpeg_hdr;
 };
@@ -250,7 +251,7 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
 		.step    = 1,
-#define FREQ_DEF 2
+#define FREQ_DEF 1
 		.default_value = FREQ_DEF,
 	    },
 	    .set = sd_setfreq,
@@ -277,7 +278,9 @@ static __u32 ctrl_dis[] = {
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_OV7660 7 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
-			      (1 << FREQ_IDX),	/* SENSOR_SP80708 8 */
+			      (1 << FREQ_IDX),	/* SENSOR_PO1030 8 */
+	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
+			      (1 << FREQ_IDX),	/* SENSOR_SP80708 9 */
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -304,7 +307,7 @@ static const u8 sn_hv7131[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x03,	0x64,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xa1,	0x11,	0x02,	0x09,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x11,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x03,	0x28,	0x1e,	0x41,
 /*	reg18	reg19	reg1a	reg1b */
@@ -315,7 +318,7 @@ static const u8 sn_mi0360[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x61,	0x44,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xb1,	0x5d,	0x07,	0x00,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x61,
 /*	reg18	reg19	reg1a	reg1b */
@@ -337,7 +340,7 @@ static const u8 sn_mt9v111[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x5c,	0x07,	0x00,	0x00,	0x00,	0x00,	0x00,
+	0x81,	0x5c,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x02,	0x1c,	0x28,	0x1e,	0x40,
 /*	reg18	reg19	reg1a	reg1b */
@@ -346,7 +349,7 @@ static const u8 sn_mt9v111[0x1c] = {
 
 static const u8 sn_om6802[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
-	0x00,	0x23,	0x72,	0x00,	0x1a,	0x34,	0x27,	0x20,
+	0x00,	0x23,	0x72,	0x00,	0x1a,	0x20,	0x20,	0x19,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
 	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
@@ -359,7 +362,7 @@ static const u8 sn_ov7630[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x21,	0x40,	0x00,	0x1a,	0x20,	0x1f,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0xa1,	0x21,	0x76,	0x21,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
 /*	reg18	reg19	reg1a	reg1b */
@@ -370,7 +373,7 @@ static const u8 sn_ov7648[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x63,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x10,
+	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x00,	0x28,	0x1e,	0x00,
 /*	reg18	reg19	reg1a	reg1b */
@@ -388,11 +391,22 @@ static const u8 sn_ov7660[0x1c] = {
 	0x07,	0x00,	0x00,	0x00
 };
 
+static const u8 sn_po1030[0x1c] = {
+/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
+	0x00,	0x21,	0x62,	0x00,	0x1a,	0x20,	0x20,	0x20,
+/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
+	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x00,	0x06,	0x06,	0x28,	0x1e,	0x00,
+/*	reg18	reg19	reg1a	reg1b */
+	0x07,	0x00,	0x00,	0x00
+};
+
 static const u8 sn_sp80708[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
-	0x81,	0x18,	0x07,	0x00,	0x00,	0x00,	0x00,	0x00,
+	0x81,	0x18,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x03,	0x04,	0x28,	0x1e,	0x00,
 /*	reg18	reg19	reg1a	reg1b */
@@ -409,6 +423,7 @@ static const u8 *sn_tb[] = {
 	sn_ov7630,
 	sn_ov7648,
 	sn_ov7660,
+	sn_po1030,
 	sn_sp80708
 };
 
@@ -455,7 +470,7 @@ static const u8 hv7131r_sensor_init[][8]
 
 	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
 
@@ -464,6 +479,8 @@ static const u8 hv7131r_sensor_init[][8]
 	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
+							/* set sensor clock */
 	{}
 };
 static const u8 mi0360_sensor_init[][8] = {
@@ -545,7 +562,7 @@ static const u8 mo4000_sensor_init[][8]
 };
 static const u8 mt9v111_sensor_init[][8] = {
 	{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
-	/* delay 20 ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
 	{0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
@@ -572,7 +589,9 @@ static const u8 mt9v111_sensor_init[][8]
 	{0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
-	/*******/
+	{}
+};
+static const u8 mt9v111_sensor_param1[][8] = {
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
@@ -585,14 +604,20 @@ static const u8 mt9v111_sensor_init[][8]
 	{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
 	{}
 };
+static const u8 om6802_init0[2][8] = {
+/*fixme: variable*/
+	{0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
+};
 static const u8 om6802_sensor_init[][8] = {
-	{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
-	{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
-	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
+						/* factory mode */
 	{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
+						/* output raw RGB */
+	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
 /*	{0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
 	{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
-					/* white balance & auto-exposure */
+		/* auto-exposure speed (0) / white balance mode (auto RGB) */
 /*	{0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
 							 * set color mode */
 /*	{0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
@@ -606,26 +631,29 @@ static const u8 om6802_sensor_init[][8]
 /*	{0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
 							 * preset gamma */
 	{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
-					/* luminance mode (0x4f = AE) */
+				/* luminance mode (0x4f -> AutoExpo on) */
 	{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
 							/* preset shutter */
 /*	{0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
 							 * auto frame rate */
 /*	{0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
-
-/*	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
-/*	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
+	{0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{}
+};
+static const u8 om6802_sensor_param1[][8] = {
+	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{}
 };
 static const u8 ov7630_sensor_init[][8] = {
 	{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
-/* win: delay 20ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
-/* win: delay 20ms */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 /* win: i2c_r from 00 to 80 */
 	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
@@ -677,6 +705,7 @@ static const u8 ov7630_sensor_init[][8]
 static const u8 ov7648_sensor_init[][8] = {
 	{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},	/* reset */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
 	{0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
@@ -701,7 +730,9 @@ static const u8 ov7648_sensor_init[][8]
 /*	{0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
 /*	{0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
 /*	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
-/*...*/
+	{}
+};
+static const u8 ov7648_sensor_param1[][8] = {
 /*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
 /*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
 							 * set by setvflip */
@@ -723,7 +754,7 @@ static const u8 ov7648_sensor_init[][8]
 
 static const u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
-/*		(delay 20ms) */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
 						/* Outformat = rawRGB */
 	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -783,8 +814,11 @@ static const u8 ov7660_sensor_init[][8]
 	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
 	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
 	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
+/* not in all ms-win traces*/
 	{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
-/****** (some exchanges in the win trace) ******/
+	{}
+};
+static const u8 ov7660_sensor_param1[][8] = {
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
 						/* bits[3..0]reserved */
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -797,6 +831,7 @@ static const u8 ov7660_sensor_init[][8]
 	{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
 /*	{0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
 /****** (some exchanges in the win trace) ******/
+/*fixme:param2*/
 	{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
 	{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
 	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
@@ -804,6 +839,7 @@ static const u8 ov7660_sensor_init[][8]
 /*	{0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
 /****** (some exchanges in the win trace) ******/
 /******!! startsensor KO if changed !!****/
+/*fixme: param3*/
 	{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -811,6 +847,60 @@ static const u8 ov7660_sensor_init[][8]
 	{}
 };
 
+static const u8 po1030_sensor_init[][8] = {
+/* the sensor registers are described in m5602/m5602_po1030.h */
+	{0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
+	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
+	{0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
+	{0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
+	{0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
+	{0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
+	{0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
+	{0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
+	{0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
+	{0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
+	{0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
+	{0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
+	{0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
+	{0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
+	{0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
+	{0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
+	{0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
+	{0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
+
+	{0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
+	{}
+};
+static const u8 po1030_sensor_param1[][8] = {
+/* from ms-win traces - these values change with auto gain/expo/wb.. */
+	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
+/* mean values */
+	{0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
+	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
+	{0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
+
+	{0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
+	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
+	{0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
+/*	{0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
+	{}
+};
+
 static const u8 sp80708_sensor_init[][8] = {
 	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -883,7 +973,9 @@ static const u8 sp80708_sensor_init[][8]
 	{0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
-	/********/
+	{}
+};
+static const u8 sp80708_sensor_param1[][8] = {
 	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
@@ -894,6 +986,19 @@ static const u8 sp80708_sensor_init[][8]
 	{}
 };
 
+static const u8 (*sensor_init[10])[8] = {
+	hv7131r_sensor_init,	/* HV7131R 0 */
+	mi0360_sensor_init,	/* MI0360 1 */
+	mo4000_sensor_init,	/* MO4000 2 */
+	mt9v111_sensor_init,	/* MT9V111 3 */
+	om6802_sensor_init,	/* OM6802 4 */
+	ov7630_sensor_init,	/* OV7630 5 */
+	ov7648_sensor_init,	/* OV7648 6 */
+	ov7660_sensor_init,	/* OV7660 7 */
+	po1030_sensor_init,	/* PO1030 8 */
+	sp80708_sensor_init,	/* SP80708 9 */
+};
+
 /* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
 		  u16 value, int len)
@@ -958,8 +1063,15 @@ static void i2c_w1(struct gspca_dev *gsp
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
-	gspca_dev->usb_buf[0] = 0x81 | (2 << 4);	/* = a1 */
-	gspca_dev->usb_buf[1] = sd->i2c_base;
+	switch (sd->sensor) {
+	case SENSOR_OM6802:		/* i2c command = a0 (100 kHz) */
+		gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
+		break;
+	default:			/* i2c command = a1 (400 kHz) */
+		gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
+		break;
+	}
+	gspca_dev->usb_buf[1] = sd->i2c_addr;
 	gspca_dev->usb_buf[2] = reg;
 	gspca_dev->usb_buf[3] = val;
 	gspca_dev->usb_buf[4] = 0;
@@ -991,14 +1103,21 @@ static void i2c_w8(struct gspca_dev *gsp
 	msleep(2);
 }
 
-/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
+/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
+static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 mode[8];
 
-	mode[0] = 0x81 | 0x10;
-	mode[1] = sd->i2c_base;
+	switch (sd->sensor) {
+	case SENSOR_OM6802:		/* i2c command = 90 (100 kHz) */
+		mode[0] = 0x80 | 0x10;
+		break;
+	default:			/* i2c command = 91 (400 kHz) */
+		mode[0] = 0x81 | 0x10;
+		break;
+	}
+	mode[1] = sd->i2c_addr;
 	mode[2] = reg;
 	mode[3] = 0;
 	mode[4] = 0;
@@ -1007,33 +1126,43 @@ static void i2c_r5(struct gspca_dev *gsp
 	mode[7] = 0x10;
 	i2c_w8(gspca_dev, mode);
 	msleep(2);
-	mode[0] = 0x81 | (5 << 4) | 0x02;
+	mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
 	mode[2] = 0;
 	i2c_w8(gspca_dev, mode);
 	msleep(2);
 	reg_r(gspca_dev, 0x0a, 5);
 }
 
-static int hv7131r_probe(struct gspca_dev *gspca_dev)
+static void i2c_w_seq(struct gspca_dev *gspca_dev,
+			const u8 (*data)[8])
+{
+	while ((*data)[0] != 0) {
+		if ((*data)[0] != 0xdd)
+			i2c_w8(gspca_dev, *data);
+		else
+			msleep((*data)[1]);
+		data++;
+	}
+}
+
+static void hv7131r_probe(struct gspca_dev *gspca_dev)
 {
 	i2c_w1(gspca_dev, 0x02, 0);			/* sensor wakeup */
 	msleep(10);
 	reg_w1(gspca_dev, 0x02, 0x66);			/* Gpio on */
 	msleep(10);
-	i2c_r5(gspca_dev, 0);				/* read sensor id */
+	i2c_r(gspca_dev, 0, 5);				/* read sensor id */
 	if (gspca_dev->usb_buf[0] == 0x02
 	    && gspca_dev->usb_buf[1] == 0x09
 	    && gspca_dev->usb_buf[2] == 0x01
 	    && gspca_dev->usb_buf[3] == 0x00
 	    && gspca_dev->usb_buf[4] == 0x00) {
-		PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
-		return 0;
+		PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
+		return;
 	}
-	PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
+	PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
 		gspca_dev->usb_buf[2]);
-	PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
-	return -ENODEV;
 }
 
 static void mi0360_probe(struct gspca_dev *gspca_dev)
@@ -1075,7 +1204,6 @@ static void mi0360_probe(struct gspca_de
 	case 0x823a:
 		PDEBUG(D_PROBE, "Sensor mt9v111");
 		sd->sensor = SENSOR_MT9V111;
-		sd->i2c_base = 0x5c;
 		break;
 	case 0x8243:
 		PDEBUG(D_PROBE, "Sensor mi0360");
@@ -1086,7 +1214,42 @@ static void mi0360_probe(struct gspca_de
 	}
 }
 
-static int configure_gpio(struct gspca_dev *gspca_dev,
+static void ov7648_probe(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* check ov76xx */
+	reg_w1(gspca_dev, 0x17, 0x62);
+	reg_w1(gspca_dev, 0x01, 0x08);
+	sd->i2c_addr = 0x21;
+	i2c_r(gspca_dev, 0x0a, 2);
+	if (gspca_dev->usb_buf[3] == 0x76) {	/* ov76xx */
+		PDEBUG(D_PROBE, "Sensor ov%02x%02x",
+			gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
+		return;
+	}
+
+	/* reset */
+	reg_w1(gspca_dev, 0x01, 0x29);
+	reg_w1(gspca_dev, 0x17, 0x42);
+
+	/* check po1030 */
+	reg_w1(gspca_dev, 0x17, 0x62);
+	reg_w1(gspca_dev, 0x01, 0x08);
+	sd->i2c_addr = 0x6e;
+	i2c_r(gspca_dev, 0x00, 2);
+	if (gspca_dev->usb_buf[3] == 0x10	/* po1030 */
+	    && gspca_dev->usb_buf[4] == 0x30) {
+		PDEBUG(D_PROBE, "Sensor po1030");
+		sd->sensor = SENSOR_PO1030;
+		return;
+	}
+
+	PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
+		gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
+}
+
+static void bridge_init(struct gspca_dev *gspca_dev,
 			  const u8 *sn9c1xx)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1103,9 +1266,10 @@ static int configure_gpio(struct gspca_d
 	/* configure gpio */
 	reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
 	reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
-	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);	/* jfm len was 3 */
+	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
 	switch (sd->sensor) {
 	case SENSOR_OV7660:
+	case SENSOR_PO1030:
 	case SENSOR_SP80708:
 		reg9a = reg9a_spec;
 		break;
@@ -1115,7 +1279,7 @@ static int configure_gpio(struct gspca_d
 	}
 	reg_w(gspca_dev, 0x9a, reg9a, 6);
 
-	reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
+	reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
@@ -1127,10 +1291,22 @@ static int configure_gpio(struct gspca_d
 		reg_w1(gspca_dev, 0x01, 0x40);
 		break;
 	case SENSOR_OM6802:
-		reg_w1(gspca_dev, 0x02, 0x71);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		msleep(10);
+		reg_w1(gspca_dev, 0x02, 0x73);
+		reg_w1(gspca_dev, 0x17, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x22);
+		msleep(100);
+		reg_w1(gspca_dev, 0x01, 0x62);
 		reg_w1(gspca_dev, 0x17, 0x64);
+		reg_w1(gspca_dev, 0x17, 0x64);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		msleep(10);
 		reg_w1(gspca_dev, 0x01, 0x42);
+		i2c_w8(gspca_dev, om6802_init0[0]);
+		i2c_w8(gspca_dev, om6802_init0[1]);
+		msleep(15);
+		reg_w1(gspca_dev, 0x02, 0x71);
+		msleep(150);
 		break;
 	case SENSOR_OV7630:
 		reg_w1(gspca_dev, 0x01, 0x61);
@@ -1144,7 +1320,14 @@ static int configure_gpio(struct gspca_d
 		reg_w1(gspca_dev, 0x01, 0x62);
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
+	case SENSOR_PO1030:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	case SENSOR_OV7660:
+		/* fall thru */
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x01, 0x63);
 		reg_w1(gspca_dev, 0x17, 0x20);
@@ -1153,143 +1336,18 @@ static int configure_gpio(struct gspca_d
 		msleep(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
+	default:
 /*	case SENSOR_HV7131R: */
 /*	case SENSOR_MI0360: */
 /*	case SENSOR_MO4000: */
-	default:
 		reg_w1(gspca_dev, 0x01, 0x43);
 		reg_w1(gspca_dev, 0x17, 0x61);
 		reg_w1(gspca_dev, 0x01, 0x42);
-		if (sd->sensor == SENSOR_HV7131R) {
-			if (hv7131r_probe(gspca_dev) < 0)
-				return -ENODEV;
-		}
+		if (sd->sensor == SENSOR_HV7131R
+		    && sd->bridge == BRIDGE_SN9C102P)
+			hv7131r_probe(gspca_dev);
 		break;
 	}
-	return 0;
-}
-
-static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-	static const u8 SetSensorClk[] =	/* 0x08 Mclk */
-		{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
-
-	while (hv7131r_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
-		i++;
-	}
-	i2c_w8(gspca_dev, SetSensorClk);
-}
-
-static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (mi0360_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mi0360_sensor_init[i]);
-		i++;
-	}
-}
-
-static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (mo4000_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mo4000_sensor_init[i]);
-		i++;
-	}
-}
-
-static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
-	i++;
-	msleep(20);
-	while (mt9v111_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
-		i++;
-	}
-}
-
-static void om6802_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	while (om6802_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, om6802_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 76 01 */
-	i++;
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 (RGB+SRST) */
-	i++;
-	msleep(20);
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
-	i++;
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 c8 */
-	i++;
-	msleep(20);
-	i2c_w8(gspca_dev, ov7630_sensor_init[i]);	/* 12 48 */
-	i++;
-/*jfm:win i2c_r from 00 to 80*/
-
-	while (ov7630_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7630_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7648_sensor_init[i]);
-	i++;
-/* win: dble reset */
-	i2c_w8(gspca_dev, ov7648_sensor_init[i]);	/* reset */
-	i++;
-	msleep(20);
-/* win: i2c reg read 00..7f */
-	while (ov7648_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7648_sensor_init[i]);
-		i++;
-	}
-}
-
-static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, ov7660_sensor_init[i]);	/* reset SCCB */
-	i++;
-	msleep(20);
-	while (ov7660_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, ov7660_sensor_init[i]);
-		i++;
-	}
-}
-
-static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
-{
-	int i = 0;
-
-	i2c_w8(gspca_dev, sp80708_sensor_init[i]);	/* reset SCCB */
-	i++;
-	msleep(20);
-	while (sp80708_sensor_init[i][0]) {
-		i2c_w8(gspca_dev, sp80708_sensor_init[i]);
-		i++;
-	}
 }
 
 /* this function is called at probe time */
@@ -1305,8 +1363,7 @@ static int sd_config(struct gspca_dev *g
 	cam->npkt = 24;			/* 24 packets per ISOC message */
 
 	sd->bridge = id->driver_info >> 16;
-	sd->sensor = id->driver_info >> 8;
-	sd->i2c_base = id->driver_info;
+	sd->sensor = id->driver_info;
 
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
@@ -1322,7 +1379,6 @@ static int sd_config(struct gspca_dev *g
 	sd->quality = QUALITY_DEF;
 	sd->jpegqual = 80;
 
-	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
 	return 0;
 }
 
@@ -1330,6 +1386,7 @@ static int sd_config(struct gspca_dev *g
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	const u8 *sn9c1xx;
 	u8 regGpio[] = { 0x29, 0x74 };
 	u8 regF1;
 
@@ -1356,8 +1413,14 @@ static int sd_init(struct gspca_dev *gsp
 	case BRIDGE_SN9C120:
 		if (regF1 != 0x12)
 			return -ENODEV;
-		if (sd->sensor == SENSOR_MI0360)
+		switch (sd->sensor) {
+		case SENSOR_MI0360:
 			mi0360_probe(gspca_dev);
+			break;
+		case SENSOR_OV7648:
+			ov7648_probe(gspca_dev);
+			break;
+		}
 		regGpio[1] = 0x70;
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
@@ -1372,6 +1435,12 @@ static int sd_init(struct gspca_dev *gsp
 
 	reg_w1(gspca_dev, 0xf1, 0x01);
 
+	/* set the i2c address */
+	sn9c1xx = sn_tb[sd->sensor];
+	sd->i2c_addr = sn9c1xx[9];
+
+	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
+
 	return 0;
 }
 
@@ -1383,7 +1452,7 @@ static u32 setexposure(struct gspca_dev
 	switch (sd->sensor) {
 	case SENSOR_HV7131R: {
 		u8 Expodoit[] =
-			{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
+			{ 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
 
 		Expodoit[3] = expo >> 16;
 		Expodoit[4] = expo >> 8;
@@ -1393,7 +1462,7 @@ static u32 setexposure(struct gspca_dev
 	    }
 	case SENSOR_MI0360: {
 		u8 expoMi[] =		/* exposure 0x0635 -> 4 fp/s 0x10 */
-			{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+			{ 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
 		static const u8 doit[] =		/* update sensor */
 			{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
 		static const u8 sensorgo[] =		/* sensor on */
@@ -1412,9 +1481,9 @@ static u32 setexposure(struct gspca_dev
 	    }
 	case SENSOR_MO4000: {
 		u8 expoMof[] =
-			{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
+			{ 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
 		u8 expoMo10[] =
-			{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+			{ 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
 		static const u8 gainMo[] =
 			{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
 
@@ -1450,6 +1519,7 @@ static u32 setexposure(struct gspca_dev
 	case SENSOR_OM6802: {
 		u8 gainOm[] =
 			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
+				/* preset AGC - works when AutoExpo = off */
 
 		if (expo > 0x03ff)
 			expo = 0x03ff;
@@ -1457,7 +1527,7 @@ static u32 setexposure(struct gspca_dev
 			expo = 0x0001;
 		gainOm[3] = expo >> 2;
 		i2c_w8(gspca_dev, gainOm);
-		reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
+		reg_w1(gspca_dev, 0x96, expo >> 5);
 		PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
 		break;
 	    }
@@ -1489,7 +1559,7 @@ static void setbrightness(struct gspca_d
 	case SENSOR_MT9V111:
 		expo = sd->brightness >> 8;
 		sd->exposure = setexposure(gspca_dev, expo);
-		break;
+		return;			/* don't set the Y offset */
 	case SENSOR_OM6802:
 		expo = sd->brightness >> 6;
 		sd->exposure = setexposure(gspca_dev, expo);
@@ -1497,8 +1567,7 @@ static void setbrightness(struct gspca_d
 		break;
 	}
 
-	if (sd->sensor != SENSOR_MT9V111)
-		reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
+	reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1526,6 +1595,7 @@ static void setcolors(struct gspca_dev *
 		-24, -38, 64,		/* UR UG UB */
 		 62, -51, -9		/* VR VG VB */
 	};
+
 	for (i = 0; i < 6; i++) {
 		v = uv[i] * sd->colors / COLOR_DEF;
 		reg8a[i * 2] = v;
@@ -1605,6 +1675,8 @@ static void setvflip(struct sd *sd)
 {
 	u8 comn;
 
+	if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
+		return;
 	if (sd->sensor == SENSOR_OV7630) {
 		comn = 0x02;
 		if (!sd->vflip)
@@ -1726,8 +1798,9 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	u8 reg1, reg17;
+	u8 reg1, reg2, reg17;
 	const u8 *sn9c1xx;
+	const u8 (*init)[8];
 	int mode;
 	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
 	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
@@ -1743,8 +1816,26 @@ static int sd_start(struct gspca_dev *gs
 			0x21);		/* JPEG 422 */
 	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 
-	sn9c1xx = sn_tb[(int) sd->sensor];
-	configure_gpio(gspca_dev, sn9c1xx);
+	/* initialize the bridge */
+	sn9c1xx = sn_tb[sd->sensor];
+	bridge_init(gspca_dev, sn9c1xx);
+
+	/* initialize the sensor */
+	i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
+
+	switch (sd->sensor) {
+	case SENSOR_OM6802:
+		reg2 = 0x71;
+		break;
+	case SENSOR_SP80708:
+		reg2 = 0x62;
+		break;
+	default:
+		reg2 = 0x40;
+		break;
+	}
+	reg_w1(gspca_dev, 0x02, reg2);
+	reg_w1(gspca_dev, 0x02, reg2);
 
 	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
 	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
@@ -1771,6 +1862,9 @@ static int sd_start(struct gspca_dev *gs
 	case SENSOR_OV7660:
 		reg17 = 0xa0;
 		break;
+	case SENSOR_PO1030:
+		reg17 = 0xa0;
+		break;
 	default:
 		reg17 = 0x60;
 		break;
@@ -1791,6 +1885,10 @@ static int sd_start(struct gspca_dev *gs
 		reg_w1(gspca_dev, 0x9a, 0x07);
 		reg_w1(gspca_dev, 0x99, 0x59);
 		break;
+	case SENSOR_OM6802:
+		reg_w1(gspca_dev, 0x9a, 0x08);
+		reg_w1(gspca_dev, 0x99, 0x10);
+		break;
 	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x9a, 0x0a);
 		reg_w1(gspca_dev, 0x99, 0x60);
@@ -1806,21 +1904,20 @@ static int sd_start(struct gspca_dev *gs
 		break;
 	}
 
-	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
+	reg_w1(gspca_dev, 0x05, sn9c1xx[5]);	/* red */
+	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */
+	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */
+
+	init = NULL;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	if (mode)
 		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
 	else
 		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
 	reg17 = 0x61;		/* 0x:20: enable sensor clock */
 	switch (sd->sensor) {
-	case SENSOR_HV7131R:
-		hv7131R_InitSensor(gspca_dev);
-		break;
-	case SENSOR_MI0360:
-		mi0360_InitSensor(gspca_dev);
-		break;
 	case SENSOR_MO4000:
-		mo4000_InitSensor(gspca_dev);
 		if (mode) {
 /*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
 			reg1 = 0x06;	/* clk 24Mz */
@@ -1830,7 +1927,7 @@ static int sd_start(struct gspca_dev *gs
 		}
 		break;
 	case SENSOR_MT9V111:
-		mt9v111_InitSensor(gspca_dev);
+		init = mt9v111_sensor_param1;
 		if (mode) {
 			reg1 = 0x04;	/* 320 clk 48Mhz */
 		} else {
@@ -1839,22 +1936,21 @@ static int sd_start(struct gspca_dev *gs
 		}
 		break;
 	case SENSOR_OM6802:
-		om6802_InitSensor(gspca_dev);
+		init = om6802_sensor_param1;
 		reg17 = 0x64;		/* 640 MCKSIZE */
 		break;
 	case SENSOR_OV7630:
-		ov7630_InitSensor(gspca_dev);
 		setvflip(sd);
 		reg17 = 0xe2;
 		reg1 = 0x44;
 		break;
 	case SENSOR_OV7648:
-		ov7648_InitSensor(gspca_dev);
+		init = ov7648_sensor_param1;
 		reg17 = 0x21;
 /*		reg1 = 0x42;		 * 42 - 46? */
 		break;
 	case SENSOR_OV7660:
-		ov7660_InitSensor(gspca_dev);
+		init = ov7660_sensor_param1;
 		if (sd->bridge == BRIDGE_SN9C120) {
 			if (mode) {		/* 320x240 - 160x120 */
 				reg17 = 0xa2;
@@ -1866,9 +1962,14 @@ static int sd_start(struct gspca_dev *gs
 					 * inverse power down */
 		}
 		break;
+	case SENSOR_PO1030:
+		init = po1030_sensor_param1;
+		reg17 = 0xa2;
+		reg1 = 0x44;
+		break;
 	default:
 /*	case SENSOR_SP80708: */
-		sp80708_InitSensor(gspca_dev);
+		init = sp80708_sensor_param1;
 		if (mode) {
 /*??			reg1 = 0x04;	 * 320 clk 48Mhz */
 		} else {
@@ -1877,6 +1978,13 @@ static int sd_start(struct gspca_dev *gs
 		}
 		break;
 	}
+
+	/* more sensor initialization - param1 */
+	if (init != NULL) {
+		i2c_w_seq(gspca_dev, init);
+/*		init = NULL; */
+	}
+
 	reg_w(gspca_dev, 0xc0, C0, 6);
 	reg_w(gspca_dev, 0xca, CA, 4);
 	switch (sd->sensor) {
@@ -1891,6 +1999,7 @@ static int sd_start(struct gspca_dev *gs
 		break;
 	}
 
+
 	/* here change size mode 0 -> VGA; 1 -> CIF */
 	sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
 	reg_w1(gspca_dev, 0x18, sd->reg18);
@@ -1898,6 +2007,7 @@ static int sd_start(struct gspca_dev *gs
 
 	reg_w1(gspca_dev, 0x17, reg17);
 	reg_w1(gspca_dev, 0x01, reg1);
+
 	switch (sd->sensor) {
 	case SENSOR_OV7630:
 		setvflip(sd);
@@ -1937,14 +2047,11 @@ static void sd_stopN(struct gspca_dev *g
 		/* fall thru */
 	case SENSOR_MT9V111:
 	case SENSOR_OV7630:
+	case SENSOR_PO1030:
 		data = 0x29;
 		break;
-	default:
-/*	case SENSOR_MO4000: */
-/*	case SENSOR_OV7660: */
-		break;
 	}
-	sn9c1xx = sn_tb[(int) sd->sensor];
+	sn9c1xx = sn_tb[sd->sensor];
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
 	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -1987,11 +2094,19 @@ static void do_autogain(struct gspca_dev
 			sd->exposure = setexposure(gspca_dev,
 					(unsigned int) (expotimes << 8));
 			break;
+		case SENSOR_OM6802:
+			expotimes = sd->exposure;
+			expotimes += (luma_mean - delta) >> 2;
+			if (expotimes < 0)
+				expotimes = 0;
+			sd->exposure = setexposure(gspca_dev,
+						   (unsigned int) expotimes);
+			setredblue(gspca_dev);
+			break;
 		default:
 /*		case SENSOR_MO4000: */
 /*		case SENSOR_MI0360: */
 /*		case SENSOR_MT9V111: */
-/*		case SENSOR_OM6802: */
 			expotimes = sd->exposure;
 			expotimes += (luma_mean - delta) >> 6;
 			if (expotimes < 0)
@@ -2007,7 +2122,6 @@ static void do_autogain(struct gspca_dev
 /* scan the URB packets */
 /* This function is run at interrupt level. */
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -2019,7 +2133,7 @@ static void sd_pkt_scan(struct gspca_dev
 
 		/* end of frame */
 		gspca_frame_add(gspca_dev, LAST_PACKET,
-				frame, data, sof + 2);
+				data, sof + 2);
 		if (sd->ag_cnt < 0)
 			return;
 /* w1 w2 w3 */
@@ -2042,10 +2156,10 @@ static void sd_pkt_scan(struct gspca_dev
 	if (gspca_dev->last_packet_type == LAST_PACKET) {
 
 		/* put the JPEG 422 header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2295,69 +2409,69 @@ static const struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-#define BSI(bridge, sensor, i2c_addr) \
+#define BS(bridge, sensor) \
 	.driver_info = (BRIDGE_ ## bridge << 16) \
-			| (SENSOR_ ## sensor << 8) \
-			| (i2c_addr)
+			| SENSOR_ ## sensor
 static const __devinitdata struct usb_device_id device_table[] = {
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
-	{USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
+	{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
+	{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
 #endif
-	{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
-	{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
-/* bw600.inf:
-	{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
-/*	{USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
-/*	{USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
-/*	{USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
+	{USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
+	{USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
+/*	{USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
+	{USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
+/*	{USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
+/*	{USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
+	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
+/*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
+	{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
+/*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
+/*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
+/*	{USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
+	{USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
+/*	{USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
+/*	{USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
+	{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
-	{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
+	{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
+	{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
 #endif
-	{USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
-/*	{USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
-/*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
-	{USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
-	{USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
-/*	{USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
-/*	{USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
-	{USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
+	{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},	/*sn9c128*/
+/*	{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
+/*	{USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
+	{USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)},	/*sn9c128*/
+	{USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},	/*sn9c128*/
+/*	{USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
+/*	{USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
+/*	{USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
+	{USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},	/*sn9c325?*/
 /*bw600.inf:*/
-	{USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
-	{USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
-	{USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
+	{USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},	/*sn9c325?*/
+	{USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
+	{USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
+/*	{USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
+	{USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
 #endif
-/*	{USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
-	{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
-	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
+/*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
+	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
+	{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
-	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+	{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
 #endif
-	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
-	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
-/*	{USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
-	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
-	{USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
+	{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
+/*	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	 *sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca500.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca500.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca500.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca500.c	2010-02-24 13:52:17.000000000 -0500
@@ -589,7 +589,7 @@ static void spca500_reinit(struct gspca_
 	int err;
 	__u8 Data;
 
-	/* some unknow command from Aiptek pocket dv and family300 */
+	/* some unknown command from Aiptek pocket dv and family300 */
 
 	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
@@ -899,8 +899,7 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -913,11 +912,11 @@ static void sd_pkt_scan(struct gspca_dev
 /*			gspca_dev->last_packet_type = DISCARD_PACKET; */
 			return;
 		}
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		data += SPCA500_OFFSET_DATA;
@@ -931,7 +930,7 @@ static void sd_pkt_scan(struct gspca_dev
 	i = 0;
 	do {
 		if (data[i] == 0xff) {
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, i + 1);
 			len -= i;
 			data += i;
@@ -940,7 +939,7 @@ static void sd_pkt_scan(struct gspca_dev
 		}
 		i++;
 	} while (i < len);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca501.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca501.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca501.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca501.c	2010-02-24 13:52:17.000000000 -0500
@@ -1636,7 +1636,7 @@ static const __u16 spca501c_arowana_init
 	{}
 };
 
-/* Unknow camera from Ori Usbid 0x0000:0x0000 */
+/* Unknown camera from Ori Usbid 0x0000:0x0000 */
 /* Based on snoops from Ori Cohen */
 static const __u16 spca501c_mysterious_open_data[][3] = {
 	{0x02, 0x000f, 0x0005},
@@ -1945,7 +1945,7 @@ static int sd_init(struct gspca_dev *gsp
 			goto error;
 		break;
 	case MystFromOriUnknownCamera:
-		/* UnKnow Ori CMOS Camera data */
+		/* Unknown Ori CMOS Camera data */
 		if (write_vector(gspca_dev, spca501c_mysterious_open_data))
 			goto error;
 		break;
@@ -1978,7 +1978,7 @@ static int sd_start(struct gspca_dev *gs
 		write_vector(gspca_dev, spca501c_arowana_open_data);
 		break;
 	case MystFromOriUnknownCamera:
-		/* UnKnow  CMOS Camera data */
+		/* Unknown CMOS Camera data */
 		write_vector(gspca_dev, spca501c_mysterious_init_data);
 		break;
 	default:
@@ -2032,20 +2032,15 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev,
-					LAST_PACKET,
-					frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA501_OFFSET_DATA;
 		len -= SPCA501_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -2053,8 +2048,7 @@ static void sd_pkt_scan(struct gspca_dev
 	}
 	data++;
 	len--;
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca505.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca505.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca505.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca505.c	2010-02-24 13:52:17.000000000 -0500
@@ -739,26 +739,22 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 		break;
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca506.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca506.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca506.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca506.c	2010-02-24 13:52:17.000000000 -0500
@@ -543,18 +543,15 @@ static void sd_stopN(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA50X_OFFSET_DATA;
 		len -= SPCA50X_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 /*		gspca_dev->last_packet_type = DISCARD_PACKET; */
@@ -562,8 +559,7 @@ static void sd_pkt_scan(struct gspca_dev
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
@@ -689,7 +685,7 @@ static struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
-static __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] __devinitconst = {
 	{USB_DEVICE(0x06e1, 0xa190)},
 /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
 	{USB_DEVICE(0x0733, 0x0430)}, */
@@ -700,7 +696,7 @@ static __devinitdata struct usb_device_i
 MODULE_DEVICE_TABLE(usb, device_table);
 
 /* -- device connect -- */
-static int sd_probe(struct usb_interface *intf,
+static int __devinit sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca508.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca508.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca508.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca508.c	2010-02-24 13:52:17.000000000 -0500
@@ -1447,26 +1447,22 @@ static void sd_stopN(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	switch (data[0]) {
 	case 0:				/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += SPCA508_OFFSET_DATA;
 		len -= SPCA508_OFFSET_DATA;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		break;
 	case 0xff:			/* drop */
 		break;
 	default:
 		data += 1;
 		len -= 1;
-		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca561.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca561.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/spca561.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/spca561.c	2010-02-24 13:52:17.000000000 -0500
@@ -779,8 +779,7 @@ static void do_autogain(struct gspca_dev
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame, /* target */
-			__u8 *data,		/* isoc packet */
+			u8 *data,		/* isoc packet */
 			int len)		/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -788,12 +787,10 @@ static void sd_pkt_scan(struct gspca_dev
 	len--;
 	switch (*data++) {			/* sequence number */
 	case 0:					/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		if (data[1] & 0x10) {
 			/* compressed bayer */
-			gspca_frame_add(gspca_dev, FIRST_PACKET,
-					frame, data, len);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		} else {
 			/* raw bayer (with a header, which we skip) */
 			if (sd->chip_revision == Rev012A) {
@@ -803,14 +800,13 @@ static void sd_pkt_scan(struct gspca_dev
 				data += 16;
 				len -= 16;
 			}
-			gspca_frame_add(gspca_dev, FIRST_PACKET,
-						frame, data, len);
+			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		}
 		return;
 	case 0xff:			/* drop (empty mpackets) */
 		return;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 /* rev 72a only */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sq905.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sq905.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905.c	2010-02-24 13:52:17.000000000 -0500
@@ -168,18 +168,22 @@ static int sq905_ack_frame(struct gspca_
  *  request and read a block of data - see warning on sq905_command.
  */
 static int
-sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
+sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
 {
 	int ret;
 	int act_len;
 
 	gspca_dev->usb_buf[0] = '\0';
+	if (need_lock)
+		mutex_lock(&gspca_dev->usb_lock);
 	ret = usb_control_msg(gspca_dev->dev,
 			      usb_sndctrlpipe(gspca_dev->dev, 0),
 			      USB_REQ_SYNCH_FRAME,                /* request */
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      SQ905_BULK_READ, size, gspca_dev->usb_buf,
 			      1, SQ905_CMD_TIMEOUT);
+	if (need_lock)
+		mutex_unlock(&gspca_dev->usb_lock);
 	if (ret < 0) {
 		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
 		return ret;
@@ -210,11 +214,9 @@ static void sq905_dostream(struct work_s
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int bytes_left; /* bytes remaining in current frame. */
 	int data_len;   /* size to use for the next read. */
 	int header_read; /* true if we have already read the frame header. */
-	int discarding; /* true if we failed to get space for frame. */
 	int packet_type;
 	int frame_sz;
 	int ret;
@@ -222,7 +224,6 @@ static void sq905_dostream(struct work_s
 	u8 *buffer;
 
 	buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
-	mutex_lock(&gspca_dev->usb_lock);
 	if (!buffer) {
 		PDEBUG(D_ERR, "Couldn't allocate USB buffer");
 		goto quit_stream;
@@ -232,28 +233,22 @@ static void sq905_dostream(struct work_s
 			+ FRAME_HEADER_LEN;
 
 	while (gspca_dev->present && gspca_dev->streaming) {
-		/* Need a short delay to ensure streaming flag was set by
-		 * gspca and to make sure gspca can grab the mutex. */
-		mutex_unlock(&gspca_dev->usb_lock);
-		msleep(1);
-
 		/* request some data and then read it until we have
 		 * a complete frame. */
 		bytes_left = frame_sz;
 		header_read = 0;
-		discarding = 0;
 
-		while (bytes_left > 0) {
+		/* Note we do not check for gspca_dev->streaming here, as
+		   we must finish reading an entire frame, otherwise the
+		   next time we stream we start reading in the middle of a
+		   frame. */
+		while (bytes_left > 0 && gspca_dev->present) {
 			data_len = bytes_left > SQ905_MAX_TRANSFER ?
 				SQ905_MAX_TRANSFER : bytes_left;
-			mutex_lock(&gspca_dev->usb_lock);
-			if (!gspca_dev->present)
-				goto quit_stream;
-			ret = sq905_read_data(gspca_dev, buffer, data_len);
+			ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
 			if (ret < 0)
 				goto quit_stream;
-			mutex_unlock(&gspca_dev->usb_lock);
-			PDEBUG(D_STREAM,
+			PDEBUG(D_PACK,
 				"Got %d bytes out of %d for frame",
 				data_len, bytes_left);
 			bytes_left -= data_len;
@@ -270,34 +265,30 @@ static void sq905_dostream(struct work_s
 			} else {
 				packet_type = INTER_PACKET;
 			}
-			frame = gspca_get_i_frame(gspca_dev);
-			if (frame && !discarding) {
-				frame = gspca_frame_add(gspca_dev, packet_type,
-						frame, data, data_len);
-				/* If entire frame fits in one packet we still
-				   need to add a LAST_PACKET */
-				if (packet_type == FIRST_PACKET &&
-				    bytes_left == 0)
-					frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET,
-							frame, data, 0);
-			} else {
-				discarding = 1;
-			}
+			gspca_frame_add(gspca_dev, packet_type,
+					data, data_len);
+			/* If entire frame fits in one packet we still
+			   need to add a LAST_PACKET */
+			if (packet_type == FIRST_PACKET &&
+			    bytes_left == 0)
+				gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+		}
+		if (gspca_dev->present) {
+			/* acknowledge the frame */
+			mutex_lock(&gspca_dev->usb_lock);
+			ret = sq905_ack_frame(gspca_dev);
+			mutex_unlock(&gspca_dev->usb_lock);
+			if (ret < 0)
+				goto quit_stream;
 		}
-		/* acknowledge the frame */
-		mutex_lock(&gspca_dev->usb_lock);
-		if (!gspca_dev->present)
-			goto quit_stream;
-		ret = sq905_ack_frame(gspca_dev);
-		if (ret < 0)
-			goto quit_stream;
 	}
 quit_stream:
-	/* the usb_lock is already acquired */
-	if (gspca_dev->present)
+	if (gspca_dev->present) {
+		mutex_lock(&gspca_dev->usb_lock);
 		sq905_command(gspca_dev, SQ905_CLEAR);
-	mutex_unlock(&gspca_dev->usb_lock);
+		mutex_unlock(&gspca_dev->usb_lock);
+	}
 	kfree(buffer);
 }
 
@@ -346,7 +337,7 @@ static int sd_init(struct gspca_dev *gsp
 	ret = sq905_command(gspca_dev, SQ905_ID);
 	if (ret < 0)
 		return ret;
-	ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+	ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4, 0);
 	if (ret < 0)
 		return ret;
 	/* usb_buf is allocated with kmalloc so is aligned.
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sq905c.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sq905c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sq905c.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,11 +115,9 @@ static void sq905c_dostream(struct work_
 {
 	struct sd *dev = container_of(work, struct sd, work_struct);
 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	struct gspca_frame *frame;
 	int bytes_left; /* bytes remaining in current frame. */
 	int data_len;   /* size to use for the next read. */
 	int act_len;
-	int discarding = 0; /* true if we failed to get space for frame. */
 	int packet_type;
 	int ret;
 	u8 *buffer;
@@ -131,8 +129,6 @@ static void sq905c_dostream(struct work_
 	}
 
 	while (gspca_dev->present && gspca_dev->streaming) {
-		if (!gspca_dev->present)
-			goto quit_stream;
 		/* Request the header, which tells the size to download */
 		ret = usb_bulk_msg(gspca_dev->dev,
 				usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -149,17 +145,11 @@ static void sq905c_dostream(struct work_
 		PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
 		/* We keep the header. It has other information, too. */
 		packet_type = FIRST_PACKET;
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame && !discarding) {
-			gspca_frame_add(gspca_dev, packet_type,
-				frame, buffer, FRAME_HEADER_LEN);
-			} else
-				discarding = 1;
-		while (bytes_left > 0) {
+		gspca_frame_add(gspca_dev, packet_type,
+				buffer, FRAME_HEADER_LEN);
+		while (bytes_left > 0 && gspca_dev->present) {
 			data_len = bytes_left > SQ905C_MAX_TRANSFER ?
 				SQ905C_MAX_TRANSFER : bytes_left;
-			if (!gspca_dev->present)
-				goto quit_stream;
 			ret = usb_bulk_msg(gspca_dev->dev,
 				usb_rcvbulkpipe(gspca_dev->dev, 0x81),
 				buffer, data_len, &act_len,
@@ -174,19 +164,16 @@ static void sq905c_dostream(struct work_
 				packet_type = LAST_PACKET;
 			else
 				packet_type = INTER_PACKET;
-			frame = gspca_get_i_frame(gspca_dev);
-			if (frame && !discarding)
-				gspca_frame_add(gspca_dev, packet_type,
-						frame, buffer, data_len);
-			else
-				discarding = 1;
+			gspca_frame_add(gspca_dev, packet_type,
+					buffer, data_len);
 		}
 	}
 quit_stream:
-	mutex_lock(&gspca_dev->usb_lock);
-	if (gspca_dev->present)
+	if (gspca_dev->present) {
+		mutex_lock(&gspca_dev->usb_lock);
 		sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
-	mutex_unlock(&gspca_dev->usb_lock);
+		mutex_unlock(&gspca_dev->usb_lock);
+	}
 	kfree(buffer);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stk014.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stk014.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stk014.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stk014.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,12 +126,14 @@ static const struct v4l2_pix_format vga_
 };
 
 /* -- read a register -- */
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
 			__u16 index)
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return 0;
 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 			0x00,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -141,18 +143,21 @@ static int reg_r(struct gspca_dev *gspca
 			500);
 	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_r err %d", ret);
-		return ret;
+		gspca_dev->usb_err = ret;
+		return 0;
 	}
 	return gspca_dev->usb_buf[0];
 }
 
 /* -- write a register -- */
-static int reg_w(struct gspca_dev *gspca_dev,
+static void reg_w(struct gspca_dev *gspca_dev,
 			__u16 index, __u16 value)
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			0x01,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -161,13 +166,14 @@ static int reg_w(struct gspca_dev *gspca
 			NULL,
 			0,
 			500);
-	if (ret < 0)
+	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_w err %d", ret);
-	return ret;
+		gspca_dev->usb_err = ret;
+	}
 }
 
 /* -- get a bulk value (4 bytes) -- */
-static int rcv_val(struct gspca_dev *gspca_dev,
+static void rcv_val(struct gspca_dev *gspca_dev,
 			int ads)
 {
 	struct usb_device *dev = gspca_dev->dev;
@@ -182,17 +188,22 @@ static int rcv_val(struct gspca_dev *gsp
 	reg_w(gspca_dev, 0x63a, 0);
 	reg_w(gspca_dev, 0x63b, 0);
 	reg_w(gspca_dev, 0x630, 5);
+	if (gspca_dev->usb_err < 0)
+		return;
 	ret = usb_bulk_msg(dev,
 			usb_rcvbulkpipe(dev, 0x05),
 			gspca_dev->usb_buf,
 			4,		/* length */
 			&alen,
 			500);		/* timeout in milliseconds */
-	return ret;
+	if (ret < 0) {
+		PDEBUG(D_ERR, "rcv_val err %d", ret);
+		gspca_dev->usb_err = ret;
+	}
 }
 
 /* -- send a bulk value -- */
-static int snd_val(struct gspca_dev *gspca_dev,
+static void snd_val(struct gspca_dev *gspca_dev,
 			int ads,
 			unsigned int val)
 {
@@ -201,16 +212,9 @@ static int snd_val(struct gspca_dev *gsp
 	__u8 seq = 0;
 
 	if (ads == 0x003f08) {
-		ret = reg_r(gspca_dev, 0x0704);
-		if (ret < 0)
-			goto ko;
-		ret = reg_r(gspca_dev, 0x0705);
-		if (ret < 0)
-			goto ko;
-		seq = ret;		/* keep the sequence number */
-		ret = reg_r(gspca_dev, 0x0650);
-		if (ret < 0)
-			goto ko;
+		reg_r(gspca_dev, 0x0704);
+		seq = reg_r(gspca_dev, 0x0705);
+		reg_r(gspca_dev, 0x0650);
 		reg_w(gspca_dev, 0x654, seq);
 	} else {
 		reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
@@ -223,6 +227,8 @@ static int snd_val(struct gspca_dev *gsp
 	reg_w(gspca_dev, 0x65a, 0);
 	reg_w(gspca_dev, 0x65b, 0);
 	reg_w(gspca_dev, 0x650, 5);
+	if (gspca_dev->usb_err < 0)
+		return;
 	gspca_dev->usb_buf[0] = val >> 24;
 	gspca_dev->usb_buf[1] = val >> 16;
 	gspca_dev->usb_buf[2] = val >> 8;
@@ -233,24 +239,23 @@ static int snd_val(struct gspca_dev *gsp
 			4,
 			&alen,
 			500);	/* timeout in milliseconds */
-	if (ret < 0)
-		goto ko;
-	if (ads == 0x003f08) {
-		seq += 4;
-		seq &= 0x3f;
-		reg_w(gspca_dev, 0x705, seq);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "snd_val err %d", ret);
+		gspca_dev->usb_err = ret;
+	} else {
+		if (ads == 0x003f08) {
+			seq += 4;
+			seq &= 0x3f;
+			reg_w(gspca_dev, 0x705, seq);
+		}
 	}
-	return ret;
-ko:
-	PDEBUG(D_ERR, "snd_val err %d", ret);
-	return ret;
 }
 
 /* set a camera parameter */
-static int set_par(struct gspca_dev *gspca_dev,
+static void set_par(struct gspca_dev *gspca_dev,
 		   int parval)
 {
-	return snd_val(gspca_dev, 0x003f08, parval);
+	snd_val(gspca_dev, 0x003f08, parval);
 }
 
 static void setbrightness(struct gspca_dev *gspca_dev)
@@ -311,18 +316,18 @@ static int sd_config(struct gspca_dev *g
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	int ret;
+	u8 ret;
 
 	/* check if the device responds */
 	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 	ret = reg_r(gspca_dev, 0x0740);
-	if (ret < 0)
-		return ret;
-	if (ret != 0xff) {
-		PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
-		return -1;
+	if (gspca_dev->usb_err >= 0) {
+		if (ret != 0xff) {
+			PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
+			gspca_dev->usb_err = -EIO;
+		}
 	}
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 /* -- start the camera -- */
@@ -357,15 +362,12 @@ static int sd_start(struct gspca_dev *gs
 	if (ret < 0) {
 		PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
 			gspca_dev->iface, gspca_dev->alt);
+		gspca_dev->usb_err = ret;
 		goto out;
 	}
-	ret = reg_r(gspca_dev, 0x0630);
-	if (ret < 0)
-		goto out;
+	 reg_r(gspca_dev, 0x0630);
 	rcv_val(gspca_dev, 0x000020);	/* << (value ff ff ff ff) */
-	ret = reg_r(gspca_dev, 0x0650);
-	if (ret < 0)
-		goto out;
+	reg_r(gspca_dev, 0x0650);
 	snd_val(gspca_dev, 0x000020, 0xffffffff);
 	reg_w(gspca_dev, 0x0620, 0);
 	reg_w(gspca_dev, 0x0630, 0);
@@ -384,11 +386,11 @@ static int sd_start(struct gspca_dev *gs
 	/* start the video flow */
 	set_par(gspca_dev, 0x01000000);
 	set_par(gspca_dev, 0x01000000);
-	PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
-	return 0;
+	if (gspca_dev->usb_err >= 0)
+		PDEBUG(D_STREAM, "camera started alt: 0x%02x",
+				gspca_dev->alt);
 out:
-	PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
-	return ret;
+	return gspca_dev->usb_err;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -418,8 +420,7 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -435,11 +436,11 @@ static void sd_pkt_scan(struct gspca_dev
 	 *		(without ending - ff d9)
 	 */
 	if (data[0] == 0xff && data[1] == 0xfe) {
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					ffd9, 2);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				ffd9, 2);
 
 		/* put the JPEG 411 header */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		/* beginning of the frame */
@@ -447,7 +448,7 @@ static void sd_pkt_scan(struct gspca_dev
 		data += STKHDRSZ;
 		len -= STKHDRSZ;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -457,7 +458,7 @@ static int sd_setbrightness(struct gspca
 	sd->brightness = val;
 	if (gspca_dev->streaming)
 		setbrightness(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -475,7 +476,7 @@ static int sd_setcontrast(struct gspca_d
 	sd->contrast = val;
 	if (gspca_dev->streaming)
 		setcontrast(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -493,7 +494,7 @@ static int sd_setcolors(struct gspca_dev
 	sd->colors = val;
 	if (gspca_dev->streaming)
 		setcolors(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -511,7 +512,7 @@ static int sd_setfreq(struct gspca_dev *
 	sd->lightfreq = val;
 	if (gspca_dev->streaming)
 		setfreq(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
@@ -553,7 +554,7 @@ static int sd_set_jcomp(struct gspca_dev
 		sd->quality = jcomp->quality;
 	if (gspca_dev->streaming)
 		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv0680.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv0680.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv0680.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv0680.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,364 @@
+/*
+ * STV0680 USB Camera Driver
+ *
+ * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
+ *
+ * This module is adapted from the in kernel v4l1 stv680 driver:
+ *
+ *  STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
+ *
+ * Thanks to STMicroelectronics for information on the usb commands, and
+ * to Steve Miller at STM for his help and encouragement while I was
+ * writing this driver.
+ *
+ * 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 MODULE_NAME "stv0680"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_DESCRIPTION("STV0680 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;		/* !! must be the first item */
+	struct v4l2_pix_format mode;
+	u8 orig_mode;
+	u8 video_mode;
+	u8 current_mode;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
+		       int size)
+{
+	int ret = -1;
+	u8 req_type = 0;
+
+	switch (set) {
+	case 0: /*  0xc1  */
+		req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		break;
+	case 1: /*  0x41  */
+		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
+		break;
+	case 2:	/*  0x80  */
+		req_type = USB_DIR_IN | USB_RECIP_DEVICE;
+		break;
+	case 3:	/*  0x40  */
+		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+		break;
+	}
+
+	ret = usb_control_msg(gspca_dev->dev,
+			      usb_rcvctrlpipe(gspca_dev->dev, 0),
+			      req, req_type,
+			      val, 0, gspca_dev->usb_buf, size, 500);
+
+	if ((ret < 0) && (req != 0x0a))
+		PDEBUG(D_ERR,
+		       "usb_control_msg error %i, request = 0x%x, error = %i",
+		       set, req, ret);
+
+	return ret;
+}
+
+static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
+{
+	stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
+	PDEBUG(D_ERR, "last error: %i,  command = 0x%x",
+	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	return ret;
+}
+
+static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
+{
+	/* Note not sure if this init of usb_buf is really necessary */
+	memset(gspca_dev->usb_buf, 0, 8);
+	gspca_dev->usb_buf[0] = 0x0f;
+
+	if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
+		PDEBUG(D_ERR, "Get_Camera_Mode failed");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
+}
+
+static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->current_mode == mode)
+		return 0;
+
+	memset(gspca_dev->usb_buf, 0, 8);
+	gspca_dev->usb_buf[0] = mode;
+
+	if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
+		PDEBUG(D_ERR, "Set_Camera_Mode failed");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	/* Verify we got what we've asked for */
+	if (stv0680_get_video_mode(gspca_dev) != mode) {
+		PDEBUG(D_ERR, "Error setting camera video mode!");
+		return -EIO;
+	}
+
+	sd->current_mode = mode;
+
+	return 0;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	int ret;
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam = &gspca_dev->cam;
+
+	/* ping camera to be sure STV0680 is present */
+	if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
+	    gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
+		PDEBUG(D_ERR, "STV(e): camera ping failed!!");
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	}
+
+	/* get camera descriptor */
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
+	    gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
+		PDEBUG(D_ERR, "Could not get descriptor 0200.");
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	}
+	if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -ENODEV);
+
+	if (!(gspca_dev->usb_buf[7] & 0x09)) {
+		PDEBUG(D_ERR, "Camera supports neither CIF nor QVGA mode");
+		return -ENODEV;
+	}
+	if (gspca_dev->usb_buf[7] & 0x01)
+		PDEBUG(D_PROBE, "Camera supports CIF mode");
+	if (gspca_dev->usb_buf[7] & 0x02)
+		PDEBUG(D_PROBE, "Camera supports VGA mode");
+	if (gspca_dev->usb_buf[7] & 0x08)
+		PDEBUG(D_PROBE, "Camera supports QVGA mode");
+
+	if (gspca_dev->usb_buf[7] & 0x01)
+		sd->video_mode = 0x00; /* CIF */
+	else
+		sd->video_mode = 0x03; /* QVGA */
+
+	/* FW rev, ASIC rev, sensor ID  */
+	PDEBUG(D_PROBE, "Firmware rev is %i.%i",
+	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	PDEBUG(D_PROBE, "ASIC rev is %i.%i",
+	       gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
+	PDEBUG(D_PROBE, "Sensor ID is %i",
+	       (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
+
+
+	ret = stv0680_get_video_mode(gspca_dev);
+	if (ret < 0)
+		return ret;
+	sd->current_mode = sd->orig_mode = ret;
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
+	if (ret < 0)
+		return ret;
+
+	/* Get mode details */
+	if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	cam->bulk = 1;
+	cam->bulk_nurbs = 1; /* The cam cannot handle more */
+	cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
+			 (gspca_dev->usb_buf[1] << 16) |
+			 (gspca_dev->usb_buf[2] << 8) |
+			 (gspca_dev->usb_buf[3]);
+	sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
+			 (gspca_dev->usb_buf[5]);  /* 322, 356, 644 */
+	sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
+			  (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
+	sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
+	sd->mode.field = V4L2_FIELD_NONE;
+	sd->mode.bytesperline = sd->mode.width;
+	sd->mode.sizeimage = cam->bulk_size;
+	sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
+
+	/* origGain = gspca_dev->usb_buf[12]; */
+
+	cam->cam_mode = &sd->mode;
+	cam->nmodes = 1;
+
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
+	if (ret < 0)
+		return ret;
+
+	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
+	    gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
+		PDEBUG(D_ERR, "Could not get descriptor 0100.");
+		return stv0680_handle_error(gspca_dev, -EIO);
+	}
+
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return 0;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	int ret;
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
+	if (ret < 0)
+		return ret;
+
+	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	/* Start stream at:
+	   0x0000 = CIF (352x288)
+	   0x0100 = VGA (640x480)
+	   0x0300 = QVGA (320x240) */
+	if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
+		return stv0680_handle_error(gspca_dev, -EIO);
+
+	return 0;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	/* This is a high priority command; it stops all lower order cmds */
+	if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
+		stv0680_handle_error(gspca_dev, -EIO);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (!sd->gspca_dev.present)
+		return;
+
+	stv0680_set_video_mode(gspca_dev, sd->orig_mode);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,
+			int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* Every now and then the camera sends a 16 byte packet, no idea
+	   what it contains, but it is not image data, when this
+	   happens the frame received before this packet is corrupt,
+	   so discard it. */
+	if (len != sd->mode.sizeimage) {
+		gspca_dev->last_packet_type = DISCARD_PACKET;
+		return;
+	}
+
+	/* Finish the previous frame, we do this upon reception of the next
+	   packet, even though it is already complete so that the strange 16
+	   byte packets send after a corrupt frame can discard it. */
+	gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+
+	/* Store the just received frame */
+	gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name = MODULE_NAME,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.config = sd_config,
+	.init = sd_init,
+	.start = sd_start,
+	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
+	.pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x0553, 0x0202)},
+	{USB_DEVICE(0x041e, 0x4007)},
+	{}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+				THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name = MODULE_NAME,
+	.id_table = device_table,
+	.probe = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -312,8 +312,7 @@ out:
  * The 0005 and 0100 chunks seem to appear only in compressed stream.
  */
 static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -366,7 +365,7 @@ frame_data:
 				sd->to_skip -= skip;
 			}
 
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, chunk_len);
 			break;
 
@@ -378,7 +377,7 @@ frame_data:
 
 			/* Create a new frame, chunk length should be zero */
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
-					frame, data, 0);
+					NULL, 0);
 
 			if (sd->bridge == BRIDGE_ST6422)
 				sd->to_skip = gspca_dev->width * 4;
@@ -394,8 +393,8 @@ frame_data:
 			PDEBUG(D_PACK, "End of frame detected");
 
 			/* Complete the last frame (if any) */
-			frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-						frame, data, 0);
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 
 			if (chunk_len)
 				PDEBUG(D_ERR, "Chunk length is "
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h	2010-02-24 13:52:17.000000000 -0500
@@ -228,6 +228,7 @@ static const struct stv_init stv_bridge_
 	/* This reg is written twice. Some kind of reset? */
 	{NULL,  0x1620, 0x80},
 	{NULL,  0x1620, 0x00},
+	{NULL,  0x1443, 0x00},
 	{NULL,  0x1423, 0x04},
 	{x1500, 0x1500, ARRAY_SIZE(x1500)},
 	{x1536, 0x1536, ARRAY_SIZE(x1536)},
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sunplus.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sunplus.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/sunplus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/sunplus.c	2010-02-24 13:52:17.000000000 -0500
@@ -460,13 +460,17 @@ static void reg_r(struct gspca_dev *gspc
 		  u16 index,
 		  u16 len)
 {
+	int ret;
+
 #ifdef GSPCA_DEBUG
 	if (len > USB_BUF_SZ) {
 		err("reg_r: buffer overflow");
 		return;
 	}
 #endif
-	usb_control_msg(gspca_dev->dev,
+	if (gspca_dev->usb_err < 0)
+		return;
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
 			req,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -474,6 +478,10 @@ static void reg_r(struct gspca_dev *gspc
 			index,
 			len ? gspca_dev->usb_buf : NULL, len,
 			500);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "reg_r err %d", ret);
+		gspca_dev->usb_err = ret;
+	}
 }
 
 /* write one byte */
@@ -483,40 +491,55 @@ static void reg_w_1(struct gspca_dev *gs
 		   u16 index,
 		   u16 byte)
 {
+	int ret;
+
+	if (gspca_dev->usb_err < 0)
+		return;
 	gspca_dev->usb_buf[0] = byte;
-	usb_control_msg(gspca_dev->dev,
+	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index,
 			gspca_dev->usb_buf, 1,
 			500);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "reg_w_1 err %d", ret);
+		gspca_dev->usb_err = ret;
+	}
 }
 
 /* write req / index / value */
-static int reg_w_riv(struct usb_device *dev,
+static void reg_w_riv(struct gspca_dev *gspca_dev,
 		     u8 req, u16 index, u16 value)
 {
+	struct usb_device *dev = gspca_dev->dev;
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	ret = usb_control_msg(dev,
 			usb_sndctrlpipe(dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index, NULL, 0, 500);
-	PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
-		req, index, value, ret);
-	if (ret < 0)
-		PDEBUG(D_ERR, "reg write: error %d", ret);
-	return ret;
+	if (ret < 0) {
+		PDEBUG(D_ERR, "reg_w_riv err %d", ret);
+		gspca_dev->usb_err = ret;
+		return;
+	}
+	PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
+		req, index, value);
 }
 
 /* read 1 byte */
-static int reg_r_1(struct gspca_dev *gspca_dev,
+static u8 reg_r_1(struct gspca_dev *gspca_dev,
 			u16 value)	/* wValue */
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return 0;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
 			0x20,			/* request */
@@ -527,19 +550,22 @@ static int reg_r_1(struct gspca_dev *gsp
 			500);			/* timeout */
 	if (ret < 0) {
 		PDEBUG(D_ERR, "reg_r_1 err %d", ret);
+		gspca_dev->usb_err = ret;
 		return 0;
 	}
 	return gspca_dev->usb_buf[0];
 }
 
-/* read 1 or 2 bytes - returns < 0 if error */
-static int reg_r_12(struct gspca_dev *gspca_dev,
+/* read 1 or 2 bytes */
+static u16 reg_r_12(struct gspca_dev *gspca_dev,
 			u8 req,		/* bRequest */
 			u16 index,	/* wIndex */
 			u16 length)	/* wLength (1 or 2 only) */
 {
 	int ret;
 
+	if (gspca_dev->usb_err < 0)
+		return 0;
 	gspca_dev->usb_buf[1] = 0;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -550,62 +576,44 @@ static int reg_r_12(struct gspca_dev *gs
 			gspca_dev->usb_buf, length,
 			500);
 	if (ret < 0) {
-		PDEBUG(D_ERR, "reg_read err %d", ret);
-		return -1;
+		PDEBUG(D_ERR, "reg_r_12 err %d", ret);
+		gspca_dev->usb_err = ret;
+		return 0;
 	}
 	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
 }
 
-static int write_vector(struct gspca_dev *gspca_dev,
+static void write_vector(struct gspca_dev *gspca_dev,
 			const struct cmd *data, int ncmds)
 {
-	struct usb_device *dev = gspca_dev->dev;
-	int ret;
-
 	while (--ncmds >= 0) {
-		ret = reg_w_riv(dev, data->req, data->idx, data->val);
-		if (ret < 0) {
-			PDEBUG(D_ERR,
-			   "Register write failed for 0x%02x, 0x%04x, 0x%04x",
-				data->req, data->val, data->idx);
-			return ret;
-		}
+		reg_w_riv(gspca_dev, data->req, data->idx, data->val);
 		data++;
 	}
-	return 0;
 }
 
-static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
-				const u8 qtable[2][64])
+static void setup_qtable(struct gspca_dev *gspca_dev,
+			const u8 qtable[2][64])
 {
-	struct usb_device *dev = gspca_dev->dev;
-	int i, err;
+	int i;
 
 	/* loop over y components */
-	for (i = 0; i < 64; i++) {
-		err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
-		if (err < 0)
-			return err;
-	}
+	for (i = 0; i < 64; i++)
+		 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
 
 	/* loop over c components */
-	for (i = 0; i < 64; i++) {
-		err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
-		if (err < 0)
-			return err;
-	}
-	return 0;
+	for (i = 0; i < 64; i++)
+		reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
 }
 
 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
 			     u8 req, u16 idx, u16 val)
 {
-	struct usb_device *dev = gspca_dev->dev;
-	int notdone;
+	u16 notdone;
 
-	reg_w_riv(dev, req, idx, val);
+	reg_w_riv(gspca_dev, req, idx, val);
 	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
-	reg_w_riv(dev, req, idx, val);
+	reg_w_riv(gspca_dev, req, idx, val);
 
 	PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
 
@@ -616,23 +624,22 @@ static void spca504_acknowledged_command
 
 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 			u8 req,
-			u16 idx, u16 val, u8 stat, u8 count)
+			u16 idx, u16 val, u16 endcode, u8 count)
 {
-	struct usb_device *dev = gspca_dev->dev;
-	int status;
-	u8 endcode;
+	u16 status;
 
-	reg_w_riv(dev, req, idx, val);
+	reg_w_riv(gspca_dev, req, idx, val);
 	status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
-	endcode = stat;
-	PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
+	if (gspca_dev->usb_err < 0)
+		return;
+	PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode);
 	if (!count)
 		return;
 	count = 200;
 	while (--count > 0) {
 		msleep(10);
-		/* gsmart mini2 write a each wait setting 1 ms is enought */
-/*		reg_w_riv(dev, req, idx, val); */
+		/* gsmart mini2 write a each wait setting 1 ms is enough */
+/*		reg_w_riv(gspca_dev, req, idx, val); */
 		status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
 		if (status == endcode) {
 			PDEBUG(D_FRAM, "status 0x%04x after wait %d",
@@ -642,7 +649,7 @@ static void spca504A_acknowledged_comman
 	}
 }
 
-static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
+static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
 {
 	int count = 10;
 
@@ -652,7 +659,6 @@ static int spca504B_PollingDataReady(str
 			break;
 		msleep(10);
 	}
-	return gspca_dev->usb_buf[0];
 }
 
 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
@@ -686,28 +692,26 @@ static void spca50x_GetFirmware(struct g
 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	u8 Size;
-	int rc;
 
 	Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	switch (sd->bridge) {
 	case BRIDGE_SPCA533:
-		reg_w_riv(dev, 0x31, 0, 0);
+		reg_w_riv(gspca_dev, 0x31, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
-		rc = spca504B_PollingDataReady(gspca_dev);
+		spca504B_PollingDataReady(gspca_dev);
 		spca50x_GetFirmware(gspca_dev);
 		reg_w_1(gspca_dev, 0x24, 0, 8, 2);		/* type */
 		reg_r(gspca_dev, 0x24, 8, 1);
 
 		reg_w_1(gspca_dev, 0x25, 0, 4, Size);
 		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
-		rc = spca504B_PollingDataReady(gspca_dev);
+		spca504B_PollingDataReady(gspca_dev);
 
 		/* Init the cam width height with some values get on init ? */
-		reg_w_riv(dev, 0x31, 0, 0x04);
+		reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
 		spca504B_WaitCmdStatus(gspca_dev);
-		rc = spca504B_PollingDataReady(gspca_dev);
+		spca504B_PollingDataReady(gspca_dev);
 		break;
 	default:
 /* case BRIDGE_SPCA504B: */
@@ -716,7 +720,7 @@ static void spca504B_SetSizeType(struct
 		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
 		reg_w_1(gspca_dev, 0x27, 0, 0, 6);
 		reg_r(gspca_dev, 0x27, 0, 1);			/* type */
-		rc = spca504B_PollingDataReady(gspca_dev);
+		spca504B_PollingDataReady(gspca_dev);
 		break;
 	case BRIDGE_SPCA504:
 		Size += 3;
@@ -733,8 +737,8 @@ static void spca504B_SetSizeType(struct
 		break;
 	case BRIDGE_SPCA504C:
 		/* capture mode */
-		reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
-		reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
+		reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
+		reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
 		break;
 	}
 }
@@ -762,37 +766,33 @@ static void spca504B_setQtable(struct gs
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	u16 reg;
 
 	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
-	reg_w_riv(dev, 0x00, reg, sd->brightness);
+	reg_w_riv(gspca_dev, 0x00, reg, sd->brightness);
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	u16 reg;
 
 	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
-	reg_w_riv(dev, 0x00, reg, sd->contrast);
+	reg_w_riv(gspca_dev, 0x00, reg, sd->contrast);
 }
 
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	u16 reg;
 
 	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
-	reg_w_riv(dev, 0x00, reg, sd->colors);
+	reg_w_riv(gspca_dev, 0x00, reg, sd->colors);
 }
 
 static void init_ctl_reg(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	int pollreg = 1;
 
 	setbrightness(gspca_dev);
@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_de
 	default:
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w_riv(dev, 0, 0x00, 0x21ad);	/* hue */
-		reg_w_riv(dev, 0, 0x01, 0x21ac);	/* sat/hue */
-		reg_w_riv(dev, 0, 0x00, 0x21a3);	/* gamma */
+		reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);	/* hue */
+		reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);	/* sat/hue */
+		reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);	/* gamma */
 		break;
 	case BRIDGE_SPCA536:
-		reg_w_riv(dev, 0, 0x40, 0x20f5);
-		reg_w_riv(dev, 0, 0x01, 0x20f4);
-		reg_w_riv(dev, 0, 0x00, 0x2089);
+		reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
+		reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
+		reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
 		break;
 	}
 	if (pollreg)
@@ -881,18 +881,17 @@ static int sd_config(struct gspca_dev *g
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
-	int i, err_code;
+	int i;
 	u8 info[6];
 
 	switch (sd->bridge) {
 	case BRIDGE_SPCA504B:
-		reg_w_riv(dev, 0x1d, 0x00, 0);
-		reg_w_riv(dev, 0, 0x01, 0x2306);
-		reg_w_riv(dev, 0, 0x00, 0x0d04);
-		reg_w_riv(dev, 0, 0x00, 0x2000);
-		reg_w_riv(dev, 0, 0x13, 0x2301);
-		reg_w_riv(dev, 0, 0x00, 0x2306);
+		reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
+		reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
+		reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
+		reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
+		reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
+		reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
 		/* fall thru */
 	case BRIDGE_SPCA533:
 		spca504B_PollingDataReady(gspca_dev);
@@ -904,13 +903,13 @@ static int sd_init(struct gspca_dev *gsp
 		reg_w_1(gspca_dev, 0x24, 0, 0, 0);
 		reg_r(gspca_dev, 0x24, 0, 1);
 		spca504B_PollingDataReady(gspca_dev);
-		reg_w_riv(dev, 0x34, 0, 0);
+		reg_w_riv(gspca_dev, 0x34, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		break;
 	case BRIDGE_SPCA504C:	/* pccam600 */
 		PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
-		reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
-		reg_w_riv(dev, 0xe0, 0x0000, 0x0001);	/* reset */
+		reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
+		reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);	/* reset */
 		spca504_wait_status(gspca_dev);
 		if (sd->subtype == LogitechClickSmart420)
 			write_vector(gspca_dev,
@@ -919,12 +918,7 @@ static int sd_init(struct gspca_dev *gsp
 		else
 			write_vector(gspca_dev, spca504_pccam600_open_data,
 				ARRAY_SIZE(spca504_pccam600_open_data));
-		err_code = spca50x_setup_qtable(gspca_dev,
-						qtable_creative_pccam);
-		if (err_code < 0) {
-			PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
-			return err_code;
-		}
+		setup_qtable(gspca_dev, qtable_creative_pccam);
 		break;
 	default:
 /*	case BRIDGE_SPCA504: */
@@ -958,29 +952,24 @@ static int sd_init(struct gspca_dev *gsp
 							6, 0, 0x86, 1); */
 /*			spca504A_acknowledged_command (gspca_dev, 0x24,
 							0, 0, 0x9D, 1); */
-			reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
-			reg_w_riv(dev, 0x00, 0x2310, 0x05);
+			reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
+							/* L92 sno1t.txt */
+			reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
 			spca504A_acknowledged_command(gspca_dev, 0x01,
 							0x0f, 0, 0xff, 0);
 		}
 		/* setup qtable */
-		reg_w_riv(dev, 0, 0x2000, 0);
-		reg_w_riv(dev, 0, 0x2883, 1);
-		err_code = spca50x_setup_qtable(gspca_dev,
-						qtable_spca504_default);
-		if (err_code < 0) {
-			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
-			return err_code;
-		}
+		reg_w_riv(gspca_dev, 0, 0x2000, 0);
+		reg_w_riv(gspca_dev, 0, 0x2883, 1);
+		setup_qtable(gspca_dev, qtable_spca504_default);
 		break;
 	}
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 	int enable;
 	int i;
 	u8 info[6];
@@ -1005,13 +994,13 @@ static int sd_start(struct gspca_dev *gs
 		case MegapixV4:
 		case LogitechClickSmart820:
 		case MegaImageVI:
-			reg_w_riv(dev, 0xf0, 0, 0);
+			reg_w_riv(gspca_dev, 0xf0, 0, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
 			reg_r(gspca_dev, 0xf0, 4, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
 			break;
 		default:
-			reg_w_riv(dev, 0x31, 0, 0x04);
+			reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
 			spca504B_WaitCmdStatus(gspca_dev);
 			spca504B_PollingDataReady(gspca_dev);
 			break;
@@ -1048,8 +1037,9 @@ static int sd_start(struct gspca_dev *gs
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 		}
 		spca504B_SetSizeType(gspca_dev);
-		reg_w_riv(dev, 0x00, 0x270c, 0x05);	/* L92 sno1t.txt */
-		reg_w_riv(dev, 0x00, 0x2310, 0x05);
+		reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
+							/* L92 sno1t.txt */
+		reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
 		break;
 	case BRIDGE_SPCA504C:
 		if (sd->subtype == LogitechClickSmart420) {
@@ -1061,36 +1051,37 @@ static int sd_start(struct gspca_dev *gs
 				ARRAY_SIZE(spca504_pccam600_init_data));
 		}
 		enable = (sd->autogain ? 0x04 : 0x01);
-		reg_w_riv(dev, 0x0c, 0x0000, enable);	/* auto exposure */
-		reg_w_riv(dev, 0xb0, 0x0000, enable);	/* auto whiteness */
+		reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
+							/* auto exposure */
+		reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
+							/* auto whiteness */
 
 		/* set default exposure compensation and whiteness balance */
-		reg_w_riv(dev, 0x30, 0x0001, 800);	/* ~ 20 fps */
-		reg_w_riv(dev, 0x30, 0x0002, 1600);
+		reg_w_riv(gspca_dev, 0x30, 0x0001, 800);	/* ~ 20 fps */
+		reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
 		spca504B_SetSizeType(gspca_dev);
 		break;
 	}
 	init_ctl_reg(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
 
 	switch (sd->bridge) {
 	default:
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA536: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w_riv(dev, 0x31, 0, 0);
+		reg_w_riv(gspca_dev, 0x31, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		spca504B_PollingDataReady(gspca_dev);
 		break;
 	case BRIDGE_SPCA504:
 	case BRIDGE_SPCA504C:
-		reg_w_riv(dev, 0x00, 0x2000, 0x0000);
+		reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
 
 		if (sd->subtype == AiptekMiniPenCam13) {
 			/* spca504a aiptek */
@@ -1102,7 +1093,7 @@ static void sd_stopN(struct gspca_dev *g
 							0x0f, 0x00, 0xff, 1);
 		} else {
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
-			reg_w_riv(dev, 0x01, 0x000f, 0x0000);
+			reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
 		}
 		break;
 	}
@@ -1116,7 +1107,6 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -1186,11 +1176,11 @@ static void sd_pkt_scan(struct gspca_dev
 		break;
 	}
 	if (sof) {		/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					ffd9, 2);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+				ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
 
@@ -1198,7 +1188,7 @@ static void sd_pkt_scan(struct gspca_dev
 	i = 0;
 	do {
 		if (data[i] == 0xff) {
-			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, i + 1);
 			len -= i;
 			data += i;
@@ -1207,7 +1197,7 @@ static void sd_pkt_scan(struct gspca_dev
 		}
 		i++;
 	} while (i < len);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -1217,7 +1207,7 @@ static int sd_setbrightness(struct gspca
 	sd->brightness = val;
 	if (gspca_dev->streaming)
 		setbrightness(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1235,7 +1225,7 @@ static int sd_setcontrast(struct gspca_d
 	sd->contrast = val;
 	if (gspca_dev->streaming)
 		setcontrast(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1253,7 +1243,7 @@ static int sd_setcolors(struct gspca_dev
 	sd->colors = val;
 	if (gspca_dev->streaming)
 		setcolors(gspca_dev);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1293,7 +1283,7 @@ static int sd_set_jcomp(struct gspca_dev
 		sd->quality = jcomp->quality;
 	if (gspca_dev->streaming)
 		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/t613.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/t613.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/t613.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/t613.c	2010-02-24 13:52:17.000000000 -0500
@@ -938,7 +938,6 @@ static void sd_stopN(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
@@ -956,9 +955,9 @@ static void sd_pkt_scan(struct gspca_dev
 		/* extra bytes....., could be processed too but would be
 		 * a waste of time, right now leave the application and
 		 * libjpeg do it for ourserlves.. */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+		gspca_frame_add(gspca_dev, LAST_PACKET,
 					ffd9, 2);
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 
@@ -967,7 +966,7 @@ static void sd_pkt_scan(struct gspca_dev
 		 * other's do not include it... */
 		len -= 2;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/tv8532.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/tv8532.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/tv8532.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/tv8532.c	2010-02-24 13:52:17.000000000 -0500
@@ -398,8 +398,7 @@ static void sd_stopN(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -424,9 +423,9 @@ static void sd_pkt_scan(struct gspca_dev
 	 * - 4 bytes
 	 */
 	gspca_frame_add(gspca_dev, packet_type0,
-			frame, data + 2, gspca_dev->width);
+			data + 2, gspca_dev->width);
 	gspca_frame_add(gspca_dev, packet_type1,
-			frame, data + gspca_dev->width + 5, gspca_dev->width);
+			data + gspca_dev->width + 5, gspca_dev->width);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/vc032x.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/vc032x.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/vc032x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/vc032x.c	2010-02-24 13:52:17.000000000 -0500
@@ -2987,7 +2987,6 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
 			int len)			/* iso pkt length */
 {
@@ -2996,21 +2995,29 @@ static void sd_pkt_scan(struct gspca_dev
 	if (data[0] == 0xff && data[1] == 0xd8) {
 		PDEBUG(D_PACK,
 			"vc032x header packet found len %d", len);
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-						data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += sd->image_offset;
 		len -= sd->image_offset;
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-				data, len);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 		return;
 	}
 
 	/* The vc0321 sends some additional data after sending the complete
 	 * frame, we ignore this. */
-	if (sd->bridge == BRIDGE_VC0321
-	    && len > frame->v4l2_buf.length - (frame->data_end - frame->data))
-		len = frame->v4l2_buf.length - (frame->data_end - frame->data);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	if (sd->bridge == BRIDGE_VC0321) {
+		struct gspca_frame *frame;
+		int l;
+
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame == NULL) {
+			gspca_dev->last_packet_type = DISCARD_PACKET;
+			return;
+		}
+		l = frame->data_end - frame->data;
+		if (len > frame->v4l2_buf.length - l)
+			len = frame->v4l2_buf.length - l;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -3092,6 +3099,8 @@ static int sd_querymenu(struct gspca_dev
 
 	switch (menu->id) {
 	case V4L2_CID_POWER_LINE_FREQUENCY:
+		if (menu->index >= ARRAY_SIZE(freq_nm))
+			break;
 		strcpy((char *) menu->name, freq_nm[menu->index]);
 		return 0;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/w996Xcf.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/w996Xcf.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/w996Xcf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/w996Xcf.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,609 @@
+/**
+ *
+ * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
+ *
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This module is adapted from the in kernel v4l1 w9968cf driver:
+ *
+ * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
+ *
+ * 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
+ * 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
+ *
+ */
+
+/* Note this is not a stand alone driver, it gets included in ov519.c, this
+   is a bit of a hack, but it needs the driver code for a lot of different
+   ov sensors which is already present in ov519.c (the old v4l1 driver used
+   the ovchipcam framework). When we have the time we really should move
+   the sensor drivers to v4l2 sub drivers, and properly split of this
+   driver from ov519.c */
+
+/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
+#define CONEX_CAM
+#include "jpeg.h"
+
+#define W9968CF_I2C_BUS_DELAY    4 /* delay in us for I2C bit r/w operations */
+
+#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET)
+#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET)
+
+static const struct v4l2_pix_format w9968cf_vga_mode[] = {
+	{160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
+		.bytesperline = 160 * 2,
+		.sizeimage = 160 * 120 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
+		.bytesperline = 176 * 2,
+		.sizeimage = 176 * 144 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320 * 2,
+		.sizeimage = 320 * 240 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 352 * 2,
+		.sizeimage = 352 * 288 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 640 * 2,
+		.sizeimage = 640 * 480 * 2,
+		.colorspace = V4L2_COLORSPACE_JPEG},
+};
+
+static int reg_w(struct sd *sd, __u16 index, __u16 value);
+
+/*--------------------------------------------------------------------------
+  Write 64-bit data to the fast serial bus registers.
+  Return 0 on success, -1 otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_write_fsb(struct sd *sd, u16* data)
+{
+	struct usb_device* udev = sd->gspca_dev.dev;
+	u16 value;
+	int ret;
+
+	value = *data++;
+	memcpy(sd->gspca_dev.usb_buf, data, 6);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
+			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+			      value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*--------------------------------------------------------------------------
+  Write data to the serial bus control register.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_write_sb(struct sd *sd, u16 value)
+{
+	int ret;
+
+	/* We don't use reg_w here, as that would cause all writes when
+	   bitbanging i2c to be logged, making the logs impossible to read */
+	ret = usb_control_msg(sd->gspca_dev.dev,
+		usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+		0,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value, 0x01, NULL, 0, 500);
+
+	udelay(W9968CF_I2C_BUS_DELAY);
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*--------------------------------------------------------------------------
+  Read data from the serial bus control register.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_read_sb(struct sd *sd)
+{
+	int ret;
+
+	/* We don't use reg_r here, as the w9968cf is special and has 16
+	   bit registers instead of 8 bit */
+	ret = usb_control_msg(sd->gspca_dev.dev,
+			usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+			1,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
+	if (ret >= 0)
+		ret = sd->gspca_dev.usb_buf[0] |
+		      (sd->gspca_dev.usb_buf[1] << 8);
+	else
+		PDEBUG(D_ERR, "Read SB reg [01] failed");
+
+	udelay(W9968CF_I2C_BUS_DELAY);
+
+	return ret;
+}
+
+/*--------------------------------------------------------------------------
+  Upload quantization tables for the JPEG compression.
+  This function is called by w9968cf_start_transfer().
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_upload_quantizationtables(struct sd *sd)
+{
+	u16 a, b;
+	int ret = 0, i, j;
+
+	ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
+
+	for (i = 0, j = 0; i < 32; i++, j += 2) {
+		a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
+		b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
+		ret += reg_w(sd, 0x40+i, a);
+		ret += reg_w(sd, 0x60+i, b);
+	}
+	ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
+
+	return ret;
+}
+
+/****************************************************************************
+ * Low-level I2C I/O functions.                                             *
+ * The adapter supports the following I2C transfer functions:               *
+ * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only)           *
+ * i2c_adap_read_byte_data()                                                *
+ * i2c_adap_read_byte()                                                     *
+ ****************************************************************************/
+
+static int w9968cf_smbus_start(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_stop(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+	ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
+{
+	u8 bit;
+	int ret = 0, sda;
+
+	for (bit = 0 ; bit < 8 ; bit++) {
+		sda = (v & 0x80) ? 2 : 0;
+		v <<= 1;
+		/* SDE=1, SDA=sda, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x10 | sda);
+		/* SDE=1, SDA=sda, SCL=1 */
+		ret += w9968cf_write_sb(sd, 0x11 | sda);
+		/* SDE=1, SDA=sda, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x10 | sda);
+	}
+
+	return ret;
+}
+
+static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
+{
+	u8 bit;
+	int ret = 0;
+
+	/* No need to ensure SDA is high as we are always called after
+	   read_ack which ends with SDA high */
+	*v = 0;
+	for (bit = 0 ; bit < 8 ; bit++) {
+		*v <<= 1;
+		/* SDE=1, SDA=1, SCL=1 */
+		ret += w9968cf_write_sb(sd, 0x0013);
+		*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
+		/* SDE=1, SDA=1, SCL=0 */
+		ret += w9968cf_write_sb(sd, 0x0012);
+	}
+
+	return ret;
+}
+
+static int w9968cf_smbus_write_nack(struct sd *sd)
+{
+	int ret = 0;
+
+	/* No need to ensure SDA is high as we are always called after
+	   read_byte which ends with SDA high */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+
+	return ret;
+}
+
+static int w9968cf_smbus_read_ack(struct sd *sd)
+{
+	int ret = 0, sda;
+
+	/* Ensure SDA is high before raising clock to avoid a spurious stop */
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+	ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+	sda = w9968cf_read_sb(sd);
+	ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+	if (sda < 0)
+		ret += sda;
+	else if (sda & 0x08) {
+		PDEBUG(D_USBI, "Did not receive i2c ACK");
+		ret += -1;
+	}
+
+	return ret;
+}
+
+/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
+static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
+{
+	u16* data = (u16 *)sd->gspca_dev.usb_buf;
+	int ret = 0;
+
+	data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
+	data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
+	data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
+	data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
+	data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
+	data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
+	data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
+	data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
+	data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
+	data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
+	data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
+	data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
+	data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
+	data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
+	data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
+	data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
+	data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
+	data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
+	data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
+	data[3] = 0x001d;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
+	data[0] |= (value & 0x40) ? 0x0540 : 0x0;
+	data[0] |= (value & 0x20) ? 0x5000 : 0x0;
+	data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
+	data[1] |= (value & 0x10) ? 0x0054 : 0x0;
+	data[1] |= (value & 0x08) ? 0x1500 : 0x0;
+	data[1] |= (value & 0x04) ? 0x4000 : 0x0;
+	data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
+	data[2] |= (value & 0x02) ? 0x0150 : 0x0;
+	data[2] |= (value & 0x01) ? 0x5400 : 0x0;
+	data[3] = 0xfe1d;
+
+	ret += w9968cf_write_fsb(sd, data);
+
+	if (!ret)
+		PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+	else
+		PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
+
+	return ret;
+}
+
+/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
+static int w9968cf_i2c_r(struct sd *sd, u8 reg)
+{
+	int ret = 0;
+	u8 value;
+
+	/* Fast serial bus data control disable */
+	ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
+
+	ret += w9968cf_smbus_start(sd);
+	ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_write_byte(sd, reg);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_stop(sd);
+	ret += w9968cf_smbus_start(sd);
+	ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
+	ret += w9968cf_smbus_read_ack(sd);
+	ret += w9968cf_smbus_read_byte(sd, &value);
+	/* signal we don't want to read anymore, the v4l1 driver used to
+	   send an ack here which is very wrong! (and then fixed
+	   the issues this gave by retrying reads) */
+	ret += w9968cf_smbus_write_nack(sd);
+	ret += w9968cf_smbus_stop(sd);
+
+	/* Fast serial bus data control re-enable */
+	ret += w9968cf_write_sb(sd, 0x0030);
+
+	if (!ret) {
+		ret = value;
+		PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+	} else
+		PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
+
+	return ret;
+}
+
+
+/*--------------------------------------------------------------------------
+  Turn on the LED on some webcams. A beep should be heard too.
+  Return 0 on success, a negative number otherwise.
+  --------------------------------------------------------------------------*/
+static int w9968cf_configure(struct sd *sd)
+{
+	int ret = 0;
+
+	ret += reg_w(sd, 0x00, 0xff00); /* power-down */
+	ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
+	ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+	ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
+	ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
+	ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
+	ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
+
+	if (ret)
+		PDEBUG(D_ERR, "Couldn't turn on the LED");
+
+	sd->stopped = 1;
+
+	return ret;
+}
+
+static int w9968cf_init(struct sd *sd)
+{
+	int ret = 0;
+	unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
+		      y0 = 0x0000,
+		      u0 = y0 + hw_bufsize/2,
+		      v0 = u0 + hw_bufsize/4,
+		      y1 = v0 + hw_bufsize/4,
+		      u1 = y1 + hw_bufsize/2,
+		      v1 = u1 + hw_bufsize/4;
+
+	ret += reg_w(sd, 0x00, 0xff00); /* power off */
+	ret += reg_w(sd, 0x00, 0xbf10); /* power on */
+
+	ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
+	ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
+
+	ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
+	ret += reg_w(sd, 0x21, y0 >> 16);    /* Y buf.0, high */
+	ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
+	ret += reg_w(sd, 0x25, u0 >> 16);    /* U buf.0, high */
+	ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
+	ret += reg_w(sd, 0x29, v0 >> 16);    /* V buf.0, high */
+
+	ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
+	ret += reg_w(sd, 0x23, y1 >> 16);    /* Y buf.1, high */
+	ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
+	ret += reg_w(sd, 0x27, u1 >> 16);    /* U buf.1, high */
+	ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
+	ret += reg_w(sd, 0x2b, v1 >> 16);    /* V buf.1, high */
+
+	ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
+	ret += reg_w(sd, 0x33, y1 >> 16);    /* JPEG buf 0 high */
+
+	ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
+	ret += reg_w(sd, 0x35, y1 >> 16);    /* JPEG bug 1 high */
+
+	ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
+	ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
+	ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
+	ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
+
+	return ret;
+}
+
+static int w9968cf_set_crop_window(struct sd *sd)
+{
+	int ret = 0, start_cropx, start_cropy,  x, y, fw, fh, cw, ch,
+	    max_width, max_height;
+
+	if (sd->sif) {
+		max_width  = 352;
+		max_height = 288;
+	} else {
+		max_width  = 640;
+		max_height = 480;
+	}
+
+	if (sd->sensor == SEN_OV7620) {
+		/* Sigh, this is dependend on the clock / framerate changes
+		   made by the frequency control, sick. */
+		if (sd->freq == 1) {
+			start_cropx = 277;
+			start_cropy = 37;
+		} else {
+			start_cropx = 105;
+			start_cropy = 37;
+		}
+	} else {
+		start_cropx = 320;
+		start_cropy = 35;
+	}
+
+	/* Work around to avoid FP arithmetics */
+	#define SC(x) ((x) << 10)
+
+	/* Scaling factors */
+	fw = SC(sd->gspca_dev.width) / max_width;
+	fh = SC(sd->gspca_dev.height) / max_height;
+
+	cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
+	ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
+
+	sd->sensor_width = max_width;
+	sd->sensor_height = max_height;
+
+	x = (max_width - cw) / 2;
+	y = (max_height - ch) / 2;
+
+	ret += reg_w(sd, 0x10, start_cropx + x);
+	ret += reg_w(sd, 0x11, start_cropy + y);
+	ret += reg_w(sd, 0x12, start_cropx + x + cw);
+	ret += reg_w(sd, 0x13, start_cropy + y + ch);
+
+	return ret;
+}
+
+static int w9968cf_mode_init_regs(struct sd *sd)
+{
+	int ret = 0, val, vs_polarity, hs_polarity;
+
+	ret += w9968cf_set_crop_window(sd);
+
+	ret += reg_w(sd, 0x14, sd->gspca_dev.width);
+	ret += reg_w(sd, 0x15, sd->gspca_dev.height);
+
+	/* JPEG width & height */
+	ret += reg_w(sd, 0x30, sd->gspca_dev.width);
+	ret += reg_w(sd, 0x31, sd->gspca_dev.height);
+
+	/* Y & UV frame buffer strides (in WORD) */
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
+		ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
+	} else
+		ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
+
+	ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
+	ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+
+	/* Transfer size in WORDS (for UYVY format only) */
+	val = sd->gspca_dev.width * sd->gspca_dev.height;
+	ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
+	ret += reg_w(sd, 0x3e, val >> 16);    /* high bits */
+
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		/* We may get called multiple times (usb isoc bw negotiat.) */
+		if (!sd->jpeg_hdr)
+			sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+		if (!sd->jpeg_hdr)
+			return -ENOMEM;
+
+		jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
+			    sd->gspca_dev.width, 0x22); /* JPEG 420 */
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+		ret += w9968cf_upload_quantizationtables(sd);
+	}
+
+	/* Video Capture Control Register */
+	if (sd->sensor == SEN_OV7620) {
+		/* Seems to work around a bug in the image sensor */
+		vs_polarity = 1;
+		hs_polarity = 1;
+	} else {
+		vs_polarity = 1;
+		hs_polarity = 0;
+	}
+
+	val = (vs_polarity << 12) | (hs_polarity << 11);
+
+	/* NOTE: We may not have enough memory to do double buffering while
+	   doing compression (amount of memory differs per model cam).
+	   So we use the second image buffer also as jpeg stream buffer
+	   (see w9968cf_init), and disable double buffering. */
+	if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		/* val |= 0x0002; YUV422P */
+		val |= 0x0003; /* YUV420P */
+	} else
+		val |= 0x0080; /* Enable HW double buffering */
+
+	/* val |= 0x0020; enable clamping */
+	/* val |= 0x0008; enable (1-2-1) filter */
+	/* val |= 0x000c; enable (2-3-6-3-2) filter */
+
+	val |= 0x8000; /* capt. enable */
+
+	ret += reg_w(sd, 0x16, val);
+
+	sd->gspca_dev.empty_packet = 0;
+
+	return ret;
+}
+
+static void w9968cf_stop0(struct sd *sd)
+{
+	if (sd->gspca_dev.present) {
+		reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
+		reg_w(sd, 0x16, 0x0000); /* stop video capture */
+	}
+
+	kfree(sd->jpeg_hdr);
+	sd->jpeg_hdr = NULL;
+}
+
+/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
+   for the next frame). This seems to simply not be true when operating
+   in JPEG mode, in this case there may be empty packets within the
+   frame. So in JPEG mode use the JPEG SOI marker to detect SOF.
+
+   Note to make things even more interesting the w9968cf sends *PLANAR* jpeg,
+   to be precise it sends: SOI, SOF, DRI, SOS, Y-data, SOS, U-data, SOS,
+   V-data, EOI. */
+static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data,			/* isoc packet */
+			int len)			/* iso packet length */
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
+	    V4L2_PIX_FMT_JPEG) {
+		if (len >= 2 &&
+		    data[0] == 0xff &&
+		    data[1] == 0xd8) {
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					sd->jpeg_hdr, JPEG_HDR_SZ);
+			/* Strip the ff d8, our own header (which adds
+			   huffman and quantization tables) already has this */
+			len -= 2;
+			data += 2;
+		}
+	} else {
+		/* In UYVY mode an empty packet signals EOF */
+		if (gspca_dev->empty_packet) {
+			gspca_frame_add(gspca_dev, LAST_PACKET,
+						NULL, 0);
+			gspca_frame_add(gspca_dev, FIRST_PACKET,
+					NULL, 0);
+			gspca_dev->empty_packet = 0;
+		}
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/gspca/zc3xx.c linux-libre-2.6.33-gnu1/drivers/media/video/gspca/zc3xx.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/gspca/zc3xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/gspca/zc3xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,17 +61,18 @@ struct sd {
 #define SENSOR_HV7131C 6
 #define SENSOR_ICM105A 7
 #define SENSOR_MC501CB 8
-#define SENSOR_OV7620 9
-/*#define SENSOR_OV7648 9 - same values */
-#define SENSOR_OV7630C 10
-#define SENSOR_PAS106 11
-#define SENSOR_PAS202B 12
-#define SENSOR_PB0330 13
-#define SENSOR_PO2030 14
-#define SENSOR_TAS5130CK 15
-#define SENSOR_TAS5130CXX 16
-#define SENSOR_TAS5130C_VF0250 17
-#define SENSOR_MAX 18
+#define SENSOR_MI0360SOC 9
+#define SENSOR_OV7620 10
+/*#define SENSOR_OV7648 10 - same values */
+#define SENSOR_OV7630C 11
+#define SENSOR_PAS106 12
+#define SENSOR_PAS202B 13
+#define SENSOR_PB0330 14	/* (MI0360) */
+#define SENSOR_PO2030 15
+#define SENSOR_TAS5130CK 16
+#define SENSOR_TAS5130CXX 17
+#define SENSOR_TAS5130C_VF0250 18
+#define SENSOR_MAX 19
 	unsigned short chip_revision;
 
 	u8 *jpeg_hdr;
@@ -420,9 +421,7 @@ static const struct usb_action adcm2700_
 	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
 	{}
 };
-static const struct usb_action cs2102_Initial[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action cs2102_Initial[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -471,88 +470,10 @@ static const struct usb_action cs2102_In
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
 	{0xa0, 0x00, 0x01ad},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x24, ZC3XX_R120_GAMMA00},	/* gamma 5 */
-	{0xa0, 0x44, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x64, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x84, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x9d, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xb2, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xc4, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xd3, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xe0, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xeb, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x18, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x20, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0e, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf4, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf4, ZC3XX_R10D_RGB10},
-	{0xa0, 0x58, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf4, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf4, ZC3XX_R110_RGB20},
-	{0xa0, 0xf4, ZC3XX_R111_RGB21},
-	{0xa0, 0x58, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x23, 0x0001},
-	{0xaa, 0x24, 0x0055},
-	{0xaa, 0x25, 0x00cc},
-	{0xaa, 0x21, 0x003f},
-	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},
 	{}
 };
 
-static const struct usb_action cs2102_InitialScale[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action cs2102_InitialScale[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -601,57 +522,75 @@ static const struct usb_action cs2102_In
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
 	{0xa0, 0x00, 0x01ad},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x24, ZC3XX_R120_GAMMA00},	/* gamma 5 */
-	{0xa0, 0x44, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x64, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x84, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x9d, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xb2, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xc4, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xd3, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xe0, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xeb, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x18, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x20, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0e, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x58, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf4, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf4, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf4, ZC3XX_R10D_RGB10},
-	{0xa0, 0x58, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf4, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf4, ZC3XX_R110_RGB20},
-	{0xa0, 0xf4, ZC3XX_R111_RGB21},
-	{0xa0, 0x58, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action cs2102_50HZ[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x005f},
+	{0xaa, 0x25, 0x0090},
+	{0xaa, 0x21, 0x00dd},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x3a, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x98, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xdd, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xe4, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_50HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0000},
+	{0xaa, 0x24, 0x00af},
+	{0xaa, 0x25, 0x00c8},
+	{0xaa, 0x21, 0x0068},
+	{0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x90, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x1d, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x4c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x68, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xe3, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_60HZ[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x0055},
+	{0xaa, 0x25, 0x00cc},
+	{0xaa, 0x21, 0x003f},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action cs2102_60HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
 	{0xaa, 0x23, 0x0000},
 	{0xaa, 0x24, 0x00aa},
@@ -671,162 +610,50 @@ static const struct usb_action cs2102_In
 	{0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
 	{0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x40, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x40, ZC3XX_R118_BGAIN},
-	{}
-};
-static const struct usb_action cs2102_50HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */
-	{0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
-	{0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_50HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */
-	{0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
-	{0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_60HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */
-	{}
-};
-static const struct usb_action cs2102_60HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x00be}, /* 00,04,be,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x00be}, /* 00,11,be,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
-	{0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */
-	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
-	{0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
 	{}
 };
 static const struct usb_action cs2102_NoFliker[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0001},
+	{0xaa, 0x24, 0x005f},
+	{0xaa, 0x25, 0x0000},
+	{0xaa, 0x21, 0x0001},
+	{0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0xbf, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action cs2102_NoFlikerScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
-	{0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
-	{0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
-	{0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
-	{0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
-	{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
-	{0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
-	{0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xaa, 0x23, 0x0000},
+	{0xaa, 0x24, 0x00af},
+	{0xaa, 0x25, 0x0080},
+	{0xaa, 0x21, 0x0001},
+	{0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x5f, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x80, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x01, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xa0, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{}
 };
 
@@ -4409,170 +4236,80 @@ static const struct usb_action pas202b_N
 	{}
 };
 
-static const struct usb_action pb03303x_Initial[] = {
+/* mi0360soc and pb0330 from vm30x.inf for 0ac8:301b and 0ac8:303b 07/02/13 */
+static const struct usb_action mi0360soc_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
 	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},	/* 8b -> dc */
+	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},	/*jfm: was 03*/
+/*	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
 	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
 	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+	{0xdd, 0x00, 0x0200},
 	{0xaa, 0x01, 0x0001},
 	{0xaa, 0x06, 0x0000},
 	{0xaa, 0x08, 0x0483},
 	{0xaa, 0x01, 0x0004},
 	{0xaa, 0x08, 0x0006},
 	{0xaa, 0x02, 0x0011},
-	{0xaa, 0x03, 0x01e7},
-	{0xaa, 0x04, 0x0287},
+	{0xaa, 0x03, 0x01e5},			/*jfm: was 01e7*/
+	{0xaa, 0x04, 0x0285},			/*jfm: was 0287*/
 	{0xaa, 0x07, 0x3002},
-	{0xaa, 0x20, 0x1100},
-	{0xaa, 0x35, 0x0050},
+	{0xaa, 0x20, 0x5100},			/*jfm: was 1100*/
+	{0xaa, 0x35, 0x507f},			/*jfm: was 0050*/
 	{0xaa, 0x30, 0x0005},
 	{0xaa, 0x31, 0x0000},
 	{0xaa, 0x58, 0x0078},
 	{0xaa, 0x62, 0x0411},
 	{0xaa, 0x2b, 0x0028},
-	{0xaa, 0x2c, 0x0030},
-	{0xaa, 0x2d, 0x0030},
-	{0xaa, 0x2e, 0x0028},
+	{0xaa, 0x2c, 0x007f},			/*jfm: was 0030*/
+	{0xaa, 0x2d, 0x007f},			/*jfm: was 0030*/
+	{0xaa, 0x2e, 0x007f},			/*jfm: was 0030*/
 	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /*jfm: was 37*/
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00*/
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},	/* jfm: was 78 */
 	{0xa0, 0x61, ZC3XX_R116_RGAIN},
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},
-
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x0d, 0x003a},
-	{0xa0, 0x02, 0x003b},
-	{0xa0, 0x00, 0x0038},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-	{0xa0, 0x13, ZC3XX_R120_GAMMA00},	/* gamma 4 */
-	{0xa0, 0x38, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x59, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x79, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x92, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xa7, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xb9, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xc8, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xd4, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xdf, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x26, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x22, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0d, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0009},
-	{0xaa, 0x09, 0x0134},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 	{}
 };
-
-static const struct usb_action pb03303x_InitialScale[] = {
+static const struct usb_action mi0360soc_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
 	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},	/* 8b -> dc */
+	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+	{0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},	/*jfm: was 03*/
+/*	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, */
 	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
 	{0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+	{0xdd, 0x00, 0x0200},
 	{0xaa, 0x01, 0x0001},
 	{0xaa, 0x06, 0x0000},
 	{0xaa, 0x08, 0x0483},
@@ -4582,111 +4319,111 @@ static const struct usb_action pb03303x_
 	{0xaa, 0x03, 0x01e7},
 	{0xaa, 0x04, 0x0287},
 	{0xaa, 0x07, 0x3002},
-	{0xaa, 0x20, 0x1100},
-	{0xaa, 0x35, 0x0050},
+	{0xaa, 0x20, 0x5100},			/*jfm: was 1100*/
+	{0xaa, 0x35, 0x007f},			/*jfm: was 0050*/
 	{0xaa, 0x30, 0x0005},
 	{0xaa, 0x31, 0x0000},
 	{0xaa, 0x58, 0x0078},
 	{0xaa, 0x62, 0x0411},
-	{0xaa, 0x2b, 0x0028},
-	{0xaa, 0x2c, 0x0030},
-	{0xaa, 0x2d, 0x0030},
-	{0xaa, 0x2e, 0x0028},
+	{0xaa, 0x2b, 0x007f},			/*jfm: was 28*/
+	{0xaa, 0x2c, 0x007f},			/*jfm: was 30*/
+	{0xaa, 0x2d, 0x007f},			/*jfm: was 30*/
+	{0xaa, 0x2e, 0x007f},			/*jfm: was 28*/
 	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},	/*jfm: was 37*/
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00*/
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},	/*jfm: was 78*/
 	{0xa0, 0x61, ZC3XX_R116_RGAIN},
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},
-
-	{0xa1, 0x01, 0x0002},
-
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-
-	{0xa0, 0x0d, 0x003a},
-	{0xa0, 0x02, 0x003b},
-	{0xa0, 0x00, 0x0038},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x13, ZC3XX_R120_GAMMA00},	/* gamma 4 */
-	{0xa0, 0x38, ZC3XX_R121_GAMMA01},
-	{0xa0, 0x59, ZC3XX_R122_GAMMA02},
-	{0xa0, 0x79, ZC3XX_R123_GAMMA03},
-	{0xa0, 0x92, ZC3XX_R124_GAMMA04},
-	{0xa0, 0xa7, ZC3XX_R125_GAMMA05},
-	{0xa0, 0xb9, ZC3XX_R126_GAMMA06},
-	{0xa0, 0xc8, ZC3XX_R127_GAMMA07},
-	{0xa0, 0xd4, ZC3XX_R128_GAMMA08},
-	{0xa0, 0xdf, ZC3XX_R129_GAMMA09},
-	{0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
-	{0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
-	{0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
-	{0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
-	{0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
-	{0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
-	{0xa0, 0x26, ZC3XX_R130_GAMMA10},
-	{0xa0, 0x22, ZC3XX_R131_GAMMA11},
-	{0xa0, 0x20, ZC3XX_R132_GAMMA12},
-	{0xa0, 0x1c, ZC3XX_R133_GAMMA13},
-	{0xa0, 0x16, ZC3XX_R134_GAMMA14},
-	{0xa0, 0x13, ZC3XX_R135_GAMMA15},
-	{0xa0, 0x10, ZC3XX_R136_GAMMA16},
-	{0xa0, 0x0d, ZC3XX_R137_GAMMA17},
-	{0xa0, 0x0b, ZC3XX_R138_GAMMA18},
-	{0xa0, 0x09, ZC3XX_R139_GAMMA19},
-	{0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
-	{0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
-	{0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
-	{0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
-	{0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
-	{0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x0180},
+	{}
+};
+static const struct usb_action mi360soc_AE50HZ[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0562},
+	{0xbb, 0x01, 0x09aa},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE50HZScale[] = {
 	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0934},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE60HZ[] = {
 	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0009},
-	{0xaa, 0x09, 0x0134},
+	{0xbb, 0x00, 0x053d},
+	{0xbb, 0x01, 0x096e},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
 	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+static const struct usb_action mi360soc_AE60HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0983},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x8f, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW},
 	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
 	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
@@ -4696,20 +4433,60 @@ static const struct usb_action pb03303x_
 	{0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
+	{}
+};
+static const struct usb_action mi360soc_AENoFliker[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x01, 0x0960},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
 	{}
 };
-static const struct usb_action pb0330xx_Initial[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action mi360soc_AENoFlikerScale[] = {
+	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0534},
+	{0xbb, 0x02, 0x0960},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x34, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{}
+};
+
+static const struct usb_action pb0330_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4721,11 +4498,12 @@ static const struct usb_action pb0330xx_
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+	{0xdd, 0x00, 0x0200},
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xaa, 0x01, 0x0006},
 	{0xaa, 0x02, 0x0011},
-	{0xaa, 0x03, 0x01e7},
-	{0xaa, 0x04, 0x0287},
+	{0xaa, 0x03, 0x01e5},			/*jfm: was 1e7*/
+	{0xaa, 0x04, 0x0285},			/*jfm: was 0287*/
 	{0xaa, 0x06, 0x0003},
 	{0xaa, 0x07, 0x3002},
 	{0xaa, 0x20, 0x1100},
@@ -4743,88 +4521,21 @@ static const struct usb_action pb0330xx_
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},			/*jfm: was 00 */
+	{0xa0, 0x15, 0x01ae},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
-	{0xa1, 0x01, 0x0091},
-	{0xa1, 0x01, 0x0095},
-	{0xa1, 0x01, 0x0096},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0066},
-	{0xaa, 0x09, 0x02b2},
-	{0xaa, 0x10, 0x0002},
-
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0007},
-/*	{0xa0, 0x30, 0x0007}, */
-/*	{0xa0, 0x00, 0x0007}, */
+	{0xa0, 0x78, ZC3XX_R18D_YTARGET},	/*jfm: was 6c*/
 	{}
 };
-
-static const struct usb_action pb0330xx_InitialScale[] = {
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0008},
+static const struct usb_action pb0330_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* 00 */
 	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},	/* 10 */
+	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -4836,6 +4547,7 @@ static const struct usb_action pb0330xx_
 	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
 	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+	{0xdd, 0x00, 0x0200},
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xaa, 0x01, 0x0006},
 	{0xaa, 0x02, 0x0011},
@@ -4858,53 +4570,43 @@ static const struct usb_action pb0330xx_
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x00, 0x01ad},
+	{0xa0, 0x09, 0x01ad},
+	{0xa0, 0x15, 0x01ae},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
 	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
-	{0xa0, 0x6c, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0002},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
-	{0xa1, 0x01, 0x0091},
-	{0xa1, 0x01, 0x0095},
-	{0xa1, 0x01, 0x0096},
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x50, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xf8, ZC3XX_R10B_RGB01},
-	{0xa0, 0xf8, ZC3XX_R10C_RGB02},
-	{0xa0, 0xf8, ZC3XX_R10D_RGB10},
-	{0xa0, 0x50, ZC3XX_R10E_RGB11},
-	{0xa0, 0xf8, ZC3XX_R10F_RGB12},
-	{0xa0, 0xf8, ZC3XX_R110_RGB20},
-	{0xa0, 0xf8, ZC3XX_R111_RGB21},
-	{0xa0, 0x50, ZC3XX_R112_RGB22},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x78, ZC3XX_R18D_YTARGET},	/*jfm: was 6c*/
+	{}
+};
+static const struct usb_action pb0330_50HZ[] = {
 	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0x05, 0x0066},
-	{0xaa, 0x09, 0x02b2},
-	{0xaa, 0x10, 0x0002},
+	{0xbb, 0x00, 0x055c},
+	{0xbb, 0x01, 0x09aa},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xc4, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x5c, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+	{}
+};
+static const struct usb_action pb0330_50HZScale[] = {
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0566},
+	{0xbb, 0x02, 0x09b2},
+	{0xbb, 0x00, 0x1002},
 	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
 	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
@@ -4912,124 +4614,102 @@ static const struct usb_action pb0330xx_
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
 	{0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
 	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
 	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x09, 0x01ad},
-	{0xa0, 0x15, 0x01ae},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0008},
-	{0xa1, 0x01, 0x0007},
-/*	{0xa0, 0x30, 0x0007}, */
-/*	{0xa0, 0x00, 0x0007}, */
-	{}
-};
-static const struct usb_action pb0330_50HZ[] = {
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */
-	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
-	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
-	{}
-};
-static const struct usb_action pb0330_50HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */
-	{0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
 	{}
 };
 static const struct usb_action pb0330_60HZ[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */
-	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x01, 0x0974},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_60HZScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
-	{0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
-	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x02, 0x096c},
+	{0xbb, 0x00, 0x1002},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x7c, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x1a, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x50, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_NoFliker[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */
-	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0509},
+	{0xbb, 0x02, 0x0940},
+	{0xbb, 0x00, 0x1002},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 static const struct usb_action pb0330_NoFlikerScale[] = {
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},	/* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},	/* 01,8f,20,cc */
-	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
-	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
-	{0xa0, 0x09, ZC3XX_R01D_HSYNC_0},	/* 00,1d,09,cc */
-	{0xa0, 0x40, ZC3XX_R01E_HSYNC_1},	/* 00,1e,40,cc */
-	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},	/* 00,1f,90,cc */
+	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+	{0xbb, 0x00, 0x0535},
+	{0xbb, 0x01, 0x0980},
+	{0xbb, 0x00, 0x1001},
+	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP},
+	{0xa0, 0x35, ZC3XX_R01D_HSYNC_0},
+	{0xa0, 0x60, ZC3XX_R01E_HSYNC_1},
+	{0xa0, 0x90, ZC3XX_R01F_HSYNC_2},
+	{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
 	{}
 };
 
@@ -5655,7 +5335,7 @@ static const struct usb_action tas5130CK
 	{}
 };
 
-static const struct usb_action tas5130cxx_Initial[] = {
+static const struct usb_action tas5130cxx_InitialScale[] = {	/* 320x240 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -5665,9 +5345,6 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
-	{0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
-
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -5684,82 +5361,27 @@ static const struct usb_action tas5130cx
 	{0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x70, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x00, 0x01ad},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x68, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xec, ZC3XX_R10B_RGB01},
-	{0xa0, 0xec, ZC3XX_R10C_RGB02},
-	{0xa0, 0xec, ZC3XX_R10D_RGB10},
-	{0xa0, 0x68, ZC3XX_R10E_RGB11},
-	{0xa0, 0xec, ZC3XX_R10F_RGB12},
-	{0xa0, 0xec, ZC3XX_R110_RGB20},
-	{0xa0, 0xec, ZC3XX_R111_RGB21},
-	{0xa0, 0x68, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x018d},
-	{0xa0, 0x90, ZC3XX_R18D_YTARGET},	/* 90 */
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-
-	{0xaa, 0xa3, 0x0001},
-	{0xaa, 0xa4, 0x0077},
-	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
-	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW},
-
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 00 */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},	/* 03 */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW},	/* e8 */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 0 */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 0 */
-	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW},	/* 7d */
-
-	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 08 */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 24 */
-	{0xa0, 0xf0, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
-	{0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
-	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},	/* 50 */
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+	{0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
 	{}
 };
-static const struct usb_action tas5130cxx_InitialScale[] = {
-/*??	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, */
+static const struct usb_action tas5130cxx_Initial[] = {	/* 640x480 */
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
-
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa1, 0x01, 0x0008},
-
+	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 	{0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
 	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
 	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
-	{0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
@@ -5775,63 +5397,15 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
 	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x68, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+	{0xa0, 0x70, ZC3XX_R18D_YTARGET},
+	{0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x00, 0x01ad},
 	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa1, 0x01, 0x0002},
-	{0xa1, 0x01, 0x0008},
-
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa1, 0x01, 0x0008},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{0xa1, 0x01, 0x01c8},
-	{0xa1, 0x01, 0x01c9},
-	{0xa1, 0x01, 0x01ca},
-	{0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},	/* sharpness- */
-
-	{0xa0, 0x68, ZC3XX_R10A_RGB00},	/* matrix */
-	{0xa0, 0xec, ZC3XX_R10B_RGB01},
-	{0xa0, 0xec, ZC3XX_R10C_RGB02},
-	{0xa0, 0xec, ZC3XX_R10D_RGB10},
-	{0xa0, 0x68, ZC3XX_R10E_RGB11},
-	{0xa0, 0xec, ZC3XX_R10F_RGB12},
-	{0xa0, 0xec, ZC3XX_R110_RGB20},
-	{0xa0, 0xec, ZC3XX_R111_RGB21},
-	{0xa0, 0x68, ZC3XX_R112_RGB22},
-
-	{0xa1, 0x01, 0x018d},
-	{0xa0, 0x90, ZC3XX_R18D_YTARGET},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xaa, 0xa3, 0x0001},
-	{0xaa, 0xa4, 0x0063},
-	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
-	{0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0xd3, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0xda, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
-	{0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
-	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa1, 0x01, 0x0180},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+	{0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+	{0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
 	{}
 };
 static const struct usb_action tas5130cxx_50HZ[] = {
@@ -5841,20 +5415,22 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
-	{0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */
+	{0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xfe, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
 	{0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
 	{0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_50HZScale[] = {
@@ -5864,20 +5440,22 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xd0, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
-	{0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
 	{0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
 	{0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_60HZ[] = {
@@ -5887,20 +5465,22 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
 	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x28, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_60HZScale[] = {
@@ -5910,20 +5490,22 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+	{0xa0, 0x09, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x47, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
 	{0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
-	{0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
-	{0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+	{0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
 	{0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+	{0xa0, 0x20, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 static const struct usb_action tas5130cxx_NoFliker[] = {
@@ -5933,13 +5515,13 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
 	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
 	{0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5947,6 +5529,8 @@ static const struct usb_action tas5130cx
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+	{0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 
@@ -5957,13 +5541,13 @@ static const struct usb_action tas5130cx
 	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
 	{0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
-	{0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
-	{0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
-	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+	{0xa0, 0x0a, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
+	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+	{0xa0, 0x04, ZC3XX_R197_ANTIFLICKERLOW},
+	{0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+	{0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
 	{0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
 	{0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
 	{0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
@@ -5971,6 +5555,8 @@ static const struct usb_action tas5130cx
 	{0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
 	{0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+	{0xa0, 0xf0, ZC3XX_R0A0_MAXXLOW},
+	{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
 	{}
 };
 
@@ -6303,8 +5889,10 @@ static __u16 i2c_read(struct gspca_dev *
 
 	reg_w_i(gspca_dev->dev, reg, 0x0092);
 	reg_w_i(gspca_dev->dev, 0x02, 0x0090);		/* <- read command */
-	msleep(25);
+	msleep(20);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
+	if (retbyte != 0x00)
+		err("i2c_r status error %02x", retbyte);
 	retval = reg_r_i(gspca_dev, 0x0095);		/* read Lowbyte */
 	retval |= reg_r_i(gspca_dev, 0x0096) << 8;	/* read Hightbyte */
 	PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
@@ -6323,8 +5911,10 @@ static __u8 i2c_write(struct gspca_dev *
 	reg_w_i(gspca_dev->dev, valL, 0x93);
 	reg_w_i(gspca_dev->dev, valH, 0x94);
 	reg_w_i(gspca_dev->dev, 0x01, 0x90);		/* <- write command */
-	msleep(15);
+	msleep(1);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
+	if (retbyte != 0x00)
+		err("i2c_w status error %02x", retbyte);
 	PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
 			reg, valH, valL, retbyte);
 	return retbyte;
@@ -6359,7 +5949,7 @@ static void usb_exchange(struct gspca_de
 			break;
 		}
 		action++;
-/*		msleep(1); */
+		msleep(1);
 	}
 }
 
@@ -6380,11 +5970,13 @@ static void setmatrix(struct gspca_dev *
 		{0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
 	static const __u8 po2030_matrix[9] =
 		{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
+	static const u8 tas5130c_matrix[9] =
+		{0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
 	static const __u8 vf0250_matrix[9] =
 		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
 	static const __u8 *matrix_tb[SENSOR_MAX] = {
 		adcm2700_matrix, /* SENSOR_ADCM2700 0 */
-		NULL,		/* SENSOR_CS2102 1 */
+		ov7620_matrix,	/* SENSOR_CS2102 1 */
 		NULL,		/* SENSOR_CS2102K 2 */
 		gc0305_matrix,	/* SENSOR_GC0305 3 */
 		NULL,		/* SENSOR_HDCS2020b 4 */
@@ -6392,15 +5984,16 @@ static void setmatrix(struct gspca_dev *
 		NULL,		/* SENSOR_HV7131C 6 */
 		NULL,		/* SENSOR_ICM105A 7 */
 		NULL,		/* SENSOR_MC501CB 8 */
-		ov7620_matrix,	/* SENSOR_OV7620 9 */
-		NULL,		/* SENSOR_OV7630C 10 */
-		NULL,		/* SENSOR_PAS106 11 */
-		pas202b_matrix,	/* SENSOR_PAS202B 12 */
-		NULL,		/* SENSOR_PB0330 13 */
-		po2030_matrix,	/* SENSOR_PO2030 14 */
-		NULL,		/* SENSOR_TAS5130CK 15 */
-		NULL,		/* SENSOR_TAS5130CXX 16 */
-		vf0250_matrix,	/* SENSOR_TAS5130C_VF0250 17 */
+		gc0305_matrix,	/* SENSOR_MI0360SOC 9 */
+		ov7620_matrix,	/* SENSOR_OV7620 10 */
+		NULL,		/* SENSOR_OV7630C 11 */
+		NULL,		/* SENSOR_PAS106 12 */
+		pas202b_matrix,	/* SENSOR_PAS202B 13 */
+		gc0305_matrix,	/* SENSOR_PB0330 14 */
+		po2030_matrix,	/* SENSOR_PO2030 15 */
+		NULL,		/* SENSOR_TAS5130CK 16 */
+		tas5130c_matrix, /* SENSOR_TAS5130CXX 17 */
+		vf0250_matrix,	/* SENSOR_TAS5130C_VF0250 18 */
 	};
 
 	matrix = matrix_tb[sd->sensor];
@@ -6640,39 +6233,43 @@ static int setlightfreq(struct gspca_dev
 		{MC501CB_NoFliker, MC501CB_NoFlikerScale,
 		 MC501CB_50HZ, MC501CB_50HZScale,
 		 MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 9 */
+/* SENSOR_MI0360SOC 9 */
+		{mi360soc_AENoFlikerScale, mi360soc_AENoFliker,
+		 mi360soc_AE50HZScale, mi360soc_AE50HZ,
+		 mi360soc_AE60HZScale, mi360soc_AE60HZ},
+/* SENSOR_OV7620 10 */
 		{OV7620_NoFliker, OV7620_NoFliker,
 		 OV7620_50HZ, OV7620_50HZ,
 		 OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 10 */
+/* SENSOR_OV7630C 11 */
 		{NULL, NULL,
 		 NULL, NULL,
 		 NULL, NULL},
-/* SENSOR_PAS106 11 */
+/* SENSOR_PAS106 12 */
 		{pas106b_NoFliker, pas106b_NoFliker,
 		 pas106b_50HZ, pas106b_50HZ,
 		 pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 12 */
+/* SENSOR_PAS202B 13 */
 		{pas202b_NoFlikerScale, pas202b_NoFliker,
 		 pas202b_50HZScale, pas202b_50HZ,
 		 pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 13 */
-		{pb0330_NoFliker, pb0330_NoFlikerScale,
-		 pb0330_50HZ, pb0330_50HZScale,
-		 pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 14 */
+/* SENSOR_PB0330 14 */
+		{pb0330_NoFlikerScale, pb0330_NoFliker,
+		 pb0330_50HZScale, pb0330_50HZ,
+		 pb0330_60HZScale, pb0330_60HZ},
+/* SENSOR_PO2030 15 */
 		{PO2030_NoFliker, PO2030_NoFliker,
 		 PO2030_50HZ, PO2030_50HZ,
 		 PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 15 */
-		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
-		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
-		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 16 */
-		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
-		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
-		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 17 */
+/* SENSOR_TAS5130CK 16 */
+		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
+		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
+		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+/* SENSOR_TAS5130CXX 17 */
+		{tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker,
+		 tas5130cxx_50HZScale, tas5130cxx_50HZ,
+		 tas5130cxx_60HZScale, tas5130cxx_60HZ},
+/* SENSOR_TAS5130C_VF0250 18 */
 		{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
 		 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
 		 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6729,6 +6326,7 @@ static void send_unknown(struct usb_devi
 	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
+	case SENSOR_MI0360SOC:
 	case SENSOR_PB0330:
 	case SENSOR_PO2030:
 		reg_w(dev, 0x0d, 0x003a);
@@ -6820,16 +6418,16 @@ static int vga_2wr_probe(struct gspca_de
 	start_2wr_probe(dev, 0x0e);		/* PAS202BCB */
 	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
-	msleep(500);
+	msleep(50);
 	retword = i2c_read(gspca_dev, 0x03);
 	if (retword != 0)
 		return 0x0e;			/* PAS202BCB */
 
-	start_2wr_probe(dev, 0x02);		/* ?? */
+	start_2wr_probe(dev, 0x02);		/* TAS5130C */
 	i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
 	retword = i2c_read(gspca_dev, 0x01);
 	if (retword != 0)
-		return 0x02;			/* ?? */
+		return 0x02;			/* TAS5130C */
 ov_check:
 	reg_r(gspca_dev, 0x0010);		/* ?? */
 	reg_r(gspca_dev, 0x0010);
@@ -6863,7 +6461,8 @@ struct sensor_by_chipset_revision {
 	__u8 internal_sensor_id;
 };
 static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
-	{0xc001, 0x13},		/* MI0360 */
+	{0xc000, 0x12},		/* TAS5130C */
+	{0xc001, 0x13},		/* MI0360SOC */
 	{0xe001, 0x13},
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
@@ -6905,6 +6504,8 @@ static int vga_3wr_probe(struct gspca_de
 	reg_r(gspca_dev, 0x0010);
 	/* value 0x4001 is meaningless */
 	if (retword != 0x4001) {
+		if ((retword & 0xff00) == 0x6400)
+			return 0x02;		/* TAS5130C */
 		for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
 			if (chipset_revision_sensor[i].revision == retword) {
 				sd->chip_revision = retword;
@@ -6915,7 +6516,7 @@ static int vga_3wr_probe(struct gspca_de
 		}
 	}
 
-	reg_w(dev, 0x01, 0x0000);	/* check ?? */
+	reg_w(dev, 0x01, 0x0000);	/* check PB0330 */
 	reg_w(dev, 0x01, 0x0001);
 	reg_w(dev, 0xdd, 0x008b);
 	reg_w(dev, 0x0a, 0x0010);
@@ -6924,7 +6525,7 @@ static int vga_3wr_probe(struct gspca_de
 	retword = i2c_read(gspca_dev, 0x00);
 	if (retword != 0) {
 		PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
-		return 0x0a;			/* ?? */
+		return 0x0a;			/* PB0330 */
 	}
 
 	reg_w(dev, 0x01, 0x0000);
@@ -6963,7 +6564,6 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x01, 0x0001);
 	reg_w(dev, 0xee, 0x008b);
 	reg_w(dev, 0x03, 0x0012);
-/*	msleep(150); */
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0012);
 	retword = i2c_read(gspca_dev, 0x00) << 8;	/* ID 0 */
@@ -7025,7 +6625,7 @@ static int sd_config(struct gspca_dev *g
 	int vga = 1;		/* 1: vga, 0: sif */
 	static const __u8 gamma[SENSOR_MAX] = {
 		4,	/* SENSOR_ADCM2700 0 */
-		5,	/* SENSOR_CS2102 1 */
+		4,	/* SENSOR_CS2102 1 */
 		5,	/* SENSOR_CS2102K 2 */
 		4,	/* SENSOR_GC0305 3 */
 		4,	/* SENSOR_HDCS2020b 4 */
@@ -7033,15 +6633,16 @@ static int sd_config(struct gspca_dev *g
 		4,	/* SENSOR_HV7131C 6 */
 		4,	/* SENSOR_ICM105A 7 */
 		4,	/* SENSOR_MC501CB 8 */
-		3,	/* SENSOR_OV7620 9 */
-		4,	/* SENSOR_OV7630C 10 */
-		4,	/* SENSOR_PAS106 11 */
-		4,	/* SENSOR_PAS202B 12 */
-		4,	/* SENSOR_PB0330 13 */
-		4,	/* SENSOR_PO2030 14 */
-		4,	/* SENSOR_TAS5130CK 15 */
-		4,	/* SENSOR_TAS5130CXX 16 */
-		3,	/* SENSOR_TAS5130C_VF0250 17 */
+		4,	/* SENSOR_MI0360SOC 9 */
+		3,	/* SENSOR_OV7620 10 */
+		4,	/* SENSOR_OV7630C 11 */
+		4,	/* SENSOR_PAS106 12 */
+		4,	/* SENSOR_PAS202B 13 */
+		4,	/* SENSOR_PB0330 14 */
+		4,	/* SENSOR_PO2030 15 */
+		4,	/* SENSOR_TAS5130CK 16 */
+		3,	/* SENSOR_TAS5130CXX 17 */
+		3,	/* SENSOR_TAS5130C_VF0250 18 */
 	};
 
 	/* define some sensors from the vendor/product */
@@ -7065,7 +6666,7 @@ static int sd_config(struct gspca_dev *g
 				break;
 			default:
 				PDEBUG(D_PROBE,
-					"Sensor UNKNOW_0 force Tas5130");
+					"Sensor UNKNOWN_0 force Tas5130");
 				sd->sensor = SENSOR_TAS5130CXX;
 			}
 			break;
@@ -7073,6 +6674,10 @@ static int sd_config(struct gspca_dev *g
 			PDEBUG(D_PROBE, "Find Sensor HV7131B");
 			sd->sensor = SENSOR_HV7131B;
 			break;
+		case 0x02:
+			PDEBUG(D_PROBE, "Sensor TAS5130C");
+			sd->sensor = SENSOR_TAS5130CXX;
+			break;
 		case 0x04:
 			PDEBUG(D_PROBE, "Find Sensor CS2102");
 			sd->sensor = SENSOR_CS2102;
@@ -7103,7 +6708,7 @@ static int sd_config(struct gspca_dev *g
 			break;
 		case 0x10:
 		case 0x12:
-			PDEBUG(D_PROBE, "Find Sensor TAS5130");
+			PDEBUG(D_PROBE, "Find Sensor TAS5130C");
 			sd->sensor = SENSOR_TAS5130CXX;
 			break;
 		case 0x11:
@@ -7112,9 +6717,9 @@ static int sd_config(struct gspca_dev *g
 			break;
 		case 0x13:
 			PDEBUG(D_PROBE,
-				"Find Sensor MI0360. Chip revision %x",
+				"Find Sensor MI0360SOC. Chip revision %x",
 				sd->chip_revision);
-			sd->sensor = SENSOR_PB0330;
+			sd->sensor = SENSOR_MI0360SOC;
 			break;
 		case 0x14:
 			PDEBUG(D_PROBE,
@@ -7228,17 +6833,17 @@ static int sd_start(struct gspca_dev *gs
 		{hv7131cxx_InitialScale, hv7131cxx_Initial},	/* 6 */
 		{icm105axx_InitialScale, icm105axx_Initial},	/* 7 */
 		{MC501CB_InitialScale, MC501CB_Initial},	/* 8 */
-		{OV7620_mode0, OV7620_mode1},			/* 9 */
-		{ov7630c_InitialScale, ov7630c_Initial},	/* 10 */
-		{pas106b_InitialScale, pas106b_Initial},	/* 11 */
-		{pas202b_Initial, pas202b_InitialScale},	/* 12 */
-		{pb0330xx_InitialScale, pb0330xx_Initial},	/* 13 */
-/* or		{pb03303x_InitialScale, pb03303x_Initial}, */
-		{PO2030_mode0, PO2030_mode1},			/* 14 */
-		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 15 */
-		{tas5130cxx_InitialScale, tas5130cxx_Initial},	/* 16 */
+		{mi0360soc_Initial, mi0360soc_InitialScale},	/* 9 */
+		{OV7620_mode0, OV7620_mode1},			/* 10 */
+		{ov7630c_InitialScale, ov7630c_Initial},	/* 11 */
+		{pas106b_InitialScale, pas106b_Initial},	/* 12 */
+		{pas202b_Initial, pas202b_InitialScale},	/* 13 */
+		{pb0330_Initial, pb0330_InitialScale},		/* 14 */
+		{PO2030_mode0, PO2030_mode1},			/* 15 */
+		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 16 */
+		{tas5130cxx_Initial, tas5130cxx_InitialScale},	/* 17 */
 		{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
-								/* 17 */
+								/* 18 */
 	};
 
 	/* create the JPEG header */
@@ -7258,19 +6863,6 @@ static int sd_start(struct gspca_dev *gs
 	case SENSOR_PAS106:
 		usb_exchange(gspca_dev, pas106b_Initial_com);
 		break;
-	case SENSOR_PB0330:
-		if (mode) {
-			if (sd->chip_revision == 0xc001
-			    || sd->chip_revision == 0xe001
-			    || sd->chip_revision == 0x8001)
-				zc3_init = pb03303x_Initial;
-		} else {
-			if (sd->chip_revision == 0xc001
-			    || sd->chip_revision == 0xe001
-			    || sd->chip_revision == 0x8001)
-				zc3_init = pb03303x_InitialScale;
-		}
-		break;
 	}
 	usb_exchange(gspca_dev, zc3_init);
 
@@ -7279,11 +6871,14 @@ static int sd_start(struct gspca_dev *gs
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
 	case SENSOR_PO2030:
+	case SENSOR_TAS5130CXX:
 	case SENSOR_TAS5130C_VF0250:
 /*		msleep(100);			 * ?? */
 		reg_r(gspca_dev, 0x0002);	/* --> 0x40 */
 		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
 		reg_w(dev, 0x15, 0x01ae);
+		if (sd->sensor == SENSOR_TAS5130CXX)
+			break;
 		reg_w(dev, 0x0d, 0x003a);
 		reg_w(dev, 0x02, 0x003b);
 		reg_w(dev, 0x00, 0x0038);
@@ -7300,6 +6895,7 @@ static int sd_start(struct gspca_dev *gs
 		break;
 	case SENSOR_PAS202B:
 	case SENSOR_GC0305:
+	case SENSOR_TAS5130CXX:
 		reg_r(gspca_dev, 0x0008);
 		/* fall thru */
 	case SENSOR_PO2030:
@@ -7310,10 +6906,8 @@ static int sd_start(struct gspca_dev *gs
 
 	/* set the gamma tables when not set */
 	switch (sd->sensor) {
-	case SENSOR_CS2102:		/* gamma set in xxx_Initial */
-	case SENSOR_CS2102K:
+	case SENSOR_CS2102K:		/* gamma set in xxx_Initial */
 	case SENSOR_HDCS2020b:
-	case SENSOR_PB0330:		/* pb with chip_revision - see above */
 	case SENSOR_OV7630C:
 	case SENSOR_TAS5130CK:
 		break;
@@ -7343,6 +6937,7 @@ static int sd_start(struct gspca_dev *gs
 		reg_w(dev, 0x40, 0x0117);
 		break;
 	case SENSOR_GC0305:
+	case SENSOR_TAS5130CXX:
 		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
 		reg_w(dev, 0x15, 0x01ae);
 		/* fall thru */
@@ -7365,7 +6960,7 @@ static int sd_start(struct gspca_dev *gs
 	setautogain(gspca_dev);
 	switch (sd->sensor) {
 	case SENSOR_PO2030:
-		msleep(500);
+		msleep(50);
 		reg_r(gspca_dev, 0x0008);
 		reg_r(gspca_dev, 0x0007);
 		/*fall thru*/
@@ -7389,17 +6984,16 @@ static void sd_stop0(struct gspca_dev *g
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
-			struct gspca_frame *frame,
-			__u8 *data,
+			u8 *data,
 			int len)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (data[0] == 0xff && data[1] == 0xd8) {	/* start of frame */
-		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
-					data, 0);
+		gspca_frame_add(gspca_dev, LAST_PACKET,
+					NULL, 0);
 		/* put the JPEG header in the new frame */
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+		gspca_frame_add(gspca_dev, FIRST_PACKET,
 			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		/* remove the webcam's header:
@@ -7411,7 +7005,7 @@ static void sd_pkt_scan(struct gspca_dev
 		data += 18;
 		len -= 18;
 	}
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -7636,7 +7230,7 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x0ac8, 0x301b)},
 	{USB_DEVICE(0x0ac8, 0x303b)},
-	{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
+	{USB_DEVICE(0x0ac8, 0x305b)},
 	{USB_DEVICE(0x0ac8, 0x307b)},
 	{USB_DEVICE(0x10fd, 0x0128)},
 	{USB_DEVICE(0x10fd, 0x804d)},
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/hdpvr/hdpvr-core.c linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -145,7 +145,7 @@ static int device_authorization(struct h
 #ifdef HDPVR_DEBUG
 	else {
 		hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
-				   sizeof(print_buf), 0);
+				   5*buf_size+1, 0);
 		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
 			 "Status request returned, len %d: %s\n",
 			 ret, print_buf);
@@ -168,13 +168,13 @@ static int device_authorization(struct h
 
 	response = dev->usbc_buf+38;
 #ifdef HDPVR_DEBUG
-	hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+	hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
 	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
 		 print_buf);
 #endif
 	challenge(response);
 #ifdef HDPVR_DEBUG
-	hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+	hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0);
 	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
 		 print_buf);
 #endif
@@ -376,8 +376,8 @@ static int hdpvr_probe(struct usb_interf
 	usb_set_intfdata(interface, dev);
 
 	/* let the user know what node this device is now attached to */
-	v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
-		  dev->video_dev->minor);
+	v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
+		  video_device_node_name(dev->video_dev));
 	return 0;
 
 error:
@@ -391,13 +391,10 @@ error:
 static void hdpvr_disconnect(struct usb_interface *interface)
 {
 	struct hdpvr_device *dev;
-	int minor;
 
 	dev = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 
-	minor = dev->video_dev->minor;
-
 	/* prevent more I/O from starting and stop any ongoing */
 	mutex_lock(&dev->io_mutex);
 	dev->status = STATUS_DISCONNECTED;
@@ -425,7 +422,8 @@ static void hdpvr_disconnect(struct usb_
 
 	atomic_dec(&dev_nr);
 
-	v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+	v4l2_info(&dev->v4l2_dev, "device %s disconnected\n",
+		  video_device_node_name(dev->video_dev));
 
 	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev->usbc_buf);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/hdpvr/hdpvr-video.c linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,7 +139,7 @@ int hdpvr_alloc_buffers(struct hdpvr_dev
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
 			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
-			goto exit;
+			goto exit_urb;
 		}
 		buf->urb = urb;
 
@@ -148,7 +148,7 @@ int hdpvr_alloc_buffers(struct hdpvr_dev
 		if (!mem) {
 			v4l2_err(&dev->v4l2_dev,
 				 "cannot allocate usb transfer buffer\n");
-			goto exit;
+			goto exit_urb_buffer;
 		}
 
 		usb_fill_bulk_urb(buf->urb, dev->udev,
@@ -161,6 +161,10 @@ int hdpvr_alloc_buffers(struct hdpvr_dev
 		list_add_tail(&buf->buff_list, &dev->free_buff_list);
 	}
 	return 0;
+exit_urb_buffer:
+	usb_free_urb(urb);
+exit_urb:
+	kfree(buf);
 exit:
 	hdpvr_free_buffers(dev);
 	return retval;
@@ -519,7 +523,7 @@ static unsigned int hdpvr_poll(struct fi
 
 	mutex_lock(&dev->io_mutex);
 
-	if (video_is_unregistered(dev->video_dev)) {
+	if (!video_is_registered(dev->video_dev)) {
 		mutex_unlock(&dev->io_mutex);
 		return -EIO;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/hexium_gemini.c linux-libre-2.6.33-gnu1/drivers/media/video/hexium_gemini.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/hexium_gemini.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/hexium_gemini.c	2010-02-24 13:52:17.000000000 -0500
@@ -251,7 +251,7 @@ static int vidioc_s_input(struct file *f
 
 	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
 
-	if (input < 0 || input >= HEXIUM_INPUTS)
+	if (input >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	hexium->cur_input = input;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/hexium_orion.c linux-libre-2.6.33-gnu1/drivers/media/video/hexium_orion.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/hexium_orion.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/hexium_orion.c	2010-02-24 13:52:17.000000000 -0500
@@ -350,7 +350,7 @@ static int vidioc_s_input(struct file *f
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct hexium *hexium = (struct hexium *) dev->ext_priv;
 
-	if (input < 0 || input >= HEXIUM_INPUTS)
+	if (input >= HEXIUM_INPUTS)
 		return -EINVAL;
 
 	hexium->cur_input = input;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ir-kbd-i2c.c linux-libre-2.6.33-gnu1/drivers/media/video/ir-kbd-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ir-kbd-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ir-kbd-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -275,7 +275,7 @@ static void ir_key_poll(struct IR_i2c *i
 	if (0 == rc) {
 		ir_input_nokey(ir->input, &ir->ir);
 	} else {
-		ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
+		ir_input_keydown(ir->input, &ir->ir, ir_key);
 	}
 }
 
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *c
 {
 	struct ir_scancode_table *ir_codes = NULL;
 	const char *name = NULL;
-	int ir_type;
+	int ir_type = 0;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
 	struct i2c_adapter *adap = client->adapter;
@@ -353,10 +353,9 @@ static int ir_probe(struct i2c_client *c
 		ir_type     = IR_TYPE_RC5;
 		ir_codes    = &ir_codes_fusionhdtv_mce_table;
 		break;
-	case 0x7a:
+	case 0x0b:
 	case 0x47:
 	case 0x71:
-	case 0x2d:
 		if (adap->id == I2C_HW_B_CX2388x ||
 		    adap->id == I2C_HW_B_CX2341X) {
 			/* Handled by cx88-input */
@@ -381,10 +380,6 @@ static int ir_probe(struct i2c_client *c
 		ir_type     = IR_TYPE_OTHER;
 		ir_codes    = &ir_codes_avermedia_cardbus_table;
 		break;
-	default:
-		dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
-		err = -ENODEV;
-		goto err_out_free;
 	}
 
 	/* Let the caller override settings */
@@ -427,8 +422,8 @@ static int ir_probe(struct i2c_client *c
 	}
 
 	/* Make sure we are all setup before going on */
-	if (!name || !ir->get_key || !ir_codes) {
-		dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
+	if (!name || !ir->get_key || !ir_type || !ir_codes) {
+		dprintk(1, ": Unsupported device at address 0x%02x\n",
 			addr);
 		err = -ENODEV;
 		goto err_out_free;
@@ -443,12 +438,15 @@ static int ir_probe(struct i2c_client *c
 		 dev_name(&client->dev));
 
 	/* init + register input device */
-	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->name       = ir->name;
 	input_dev->phys       = ir->phys;
 
-	err = input_register_device(ir->input);
+	err = ir_input_register(ir->input, ir->ir_codes);
 	if (err)
 		goto err_out_free;
 
@@ -462,7 +460,6 @@ static int ir_probe(struct i2c_client *c
 	return 0;
 
  err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -475,7 +472,7 @@ static int ir_remove(struct i2c_client *
 	cancel_delayed_work_sync(&ir->work);
 
 	/* unregister device */
-	input_unregister_device(ir->input);
+	ir_input_unregister(ir->input);
 
 	/* free memory */
 	kfree(ir);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-cards.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.c	2010-02-24 13:52:17.000000000 -0500
@@ -136,7 +136,8 @@ static const struct ivtv_card ivtv_card_
 	.hw_audio = IVTV_HW_MSP34XX,
 	.hw_audio_ctrl = IVTV_HW_MSP34XX,
 	.hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
-		  IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
+		  IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
+		  IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, IVTV_SAA71XX_COMPOSITE4 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, IVTV_SAA71XX_SVIDEO0    },
@@ -199,7 +200,9 @@ static const struct ivtv_card ivtv_card_
 	.hw_audio_ctrl = IVTV_HW_CX25840,
 	.hw_muxer = IVTV_HW_WM8775,
 	.hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
-		  IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
+		  IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
+		  IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
+		  IVTV_HW_Z8F0811_IR_HAUP,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE7 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO1    },
@@ -955,7 +958,8 @@ static const struct ivtv_card ivtv_card_
 	.hw_video = IVTV_HW_CX25840,
 	.hw_audio = IVTV_HW_CX25840,
 	.hw_audio_ctrl = IVTV_HW_CX25840,
-	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
+	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
+		  IVTV_HW_I2C_IR_RX_AVER,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
 		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO3    },
@@ -965,6 +969,7 @@ static const struct ivtv_card ivtv_card_
 		{ IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5       },
 		{ IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
 	},
+	.radio_input = { IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5 },
 	/* enable line-in */
 	.gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
 	.xceive_pin = 10,
@@ -1025,13 +1030,15 @@ static const struct ivtv_card ivtv_card_
 /* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
 
 static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
-	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 },
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
 	{ 0, 0, 0 }
 };
 
 static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
 	.type = IVTV_CARD_AVER_ULTRA1500MCE,
 	.name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
+	.comment = "For non-NTSC tuners, use the pal= or secam= module options",
 	.v4l2_capabilities = IVTV_CAP_ENCODER,
 	.hw_video = IVTV_HW_CX25840,
 	.hw_audio = IVTV_HW_CX25840,
@@ -1058,6 +1065,7 @@ static const struct ivtv_card ivtv_card_
 	.tuners = {
 		/* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
 		{ .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
+		{ .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
 	},
 	.pci_list = ivtv_pci_aver_ultra1500mce,
 	.i2c = &ivtv_i2c_std,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-cards.h linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-cards.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-cards.h	2010-02-24 13:52:17.000000000 -0500
@@ -87,26 +87,43 @@
 #define IVTV_PCI_ID_GOTVIEW1		0xffac
 #define IVTV_PCI_ID_GOTVIEW2 		0xffad
 
-/* hardware flags, no gaps allowed, IVTV_HW_GPIO must always be last */
-#define IVTV_HW_CX25840   (1 << 0)
-#define IVTV_HW_SAA7115   (1 << 1)
-#define IVTV_HW_SAA7127   (1 << 2)
-#define IVTV_HW_MSP34XX   (1 << 3)
-#define IVTV_HW_TUNER     (1 << 4)
-#define IVTV_HW_WM8775    (1 << 5)
-#define IVTV_HW_CS53L32A  (1 << 6)
-#define IVTV_HW_TVEEPROM  (1 << 7)
-#define IVTV_HW_SAA7114   (1 << 8)
-#define IVTV_HW_UPD64031A (1 << 9)
-#define IVTV_HW_UPD6408X  (1 << 10)
-#define IVTV_HW_SAA717X   (1 << 11)
-#define IVTV_HW_WM8739    (1 << 12)
-#define IVTV_HW_VP27SMPX  (1 << 13)
-#define IVTV_HW_M52790    (1 << 14)
-#define IVTV_HW_GPIO      (1 << 15)
+/* hardware flags, no gaps allowed */
+#define IVTV_HW_CX25840			(1 << 0)
+#define IVTV_HW_SAA7115			(1 << 1)
+#define IVTV_HW_SAA7127			(1 << 2)
+#define IVTV_HW_MSP34XX			(1 << 3)
+#define IVTV_HW_TUNER			(1 << 4)
+#define IVTV_HW_WM8775			(1 << 5)
+#define IVTV_HW_CS53L32A		(1 << 6)
+#define IVTV_HW_TVEEPROM		(1 << 7)
+#define IVTV_HW_SAA7114			(1 << 8)
+#define IVTV_HW_UPD64031A		(1 << 9)
+#define IVTV_HW_UPD6408X		(1 << 10)
+#define IVTV_HW_SAA717X			(1 << 11)
+#define IVTV_HW_WM8739			(1 << 12)
+#define IVTV_HW_VP27SMPX		(1 << 13)
+#define IVTV_HW_M52790			(1 << 14)
+#define IVTV_HW_GPIO			(1 << 15)
+#define IVTV_HW_I2C_IR_RX_AVER		(1 << 16)
+#define IVTV_HW_I2C_IR_RX_HAUP_EXT	(1 << 17) /* External before internal */
+#define IVTV_HW_I2C_IR_RX_HAUP_INT	(1 << 18)
+#define IVTV_HW_Z8F0811_IR_TX_HAUP	(1 << 19)
+#define IVTV_HW_Z8F0811_IR_RX_HAUP	(1 << 20)
+
+#define IVTV_HW_Z8F0811_IR_HAUP	(IVTV_HW_Z8F0811_IR_RX_HAUP | \
+				 IVTV_HW_Z8F0811_IR_TX_HAUP)
 
 #define IVTV_HW_SAA711X   (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
 
+#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
+			   IVTV_HW_I2C_IR_RX_HAUP_EXT | \
+			   IVTV_HW_I2C_IR_RX_HAUP_INT | \
+			   IVTV_HW_Z8F0811_IR_RX_HAUP)
+
+#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
+
+#define IVTV_HW_IR_ANY	  (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
+
 /* video inputs */
 #define	IVTV_CARD_INPUT_VID_TUNER	1
 #define	IVTV_CARD_INPUT_SVIDEO1 	2
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-driver.c linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 12:03:49.000000000 -0400
@@ -91,10 +91,15 @@ static int radio[IVTV_MAX_CARDS] = { -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1,
 				     -1, -1, -1, -1, -1, -1, -1, -1 };
+static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1,
+					       -1, -1, -1, -1, -1, -1, -1, -1 };
 
 static unsigned int cardtype_c = 1;
 static unsigned int tuner_c = 1;
 static unsigned int radio_c = 1;
+static unsigned int i2c_clock_period_c = 1;
 static char pal[] = "---";
 static char secam[] = "--";
 static char ntsc[] = "-";
@@ -151,6 +156,7 @@ module_param(dec_vbi_buffers, int, 0644)
 
 module_param(tunertype, int, 0644);
 module_param(newi2c, int, 0644);
+module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
 
 MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
 			"\t\t\tsee tuner.h for values");
@@ -245,6 +251,10 @@ MODULE_PARM_DESC(newi2c,
 		 "Use new I2C implementation\n"
 		 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
 		 "\t\t\tDefault is autodetect");
+MODULE_PARM_DESC(i2c_clock_period,
+		 "Period of SCL for the I2C bus controlled by the CX23415/6\n"
+		 "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
+		 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
 
 MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
 
@@ -600,6 +610,15 @@ static void ivtv_process_options(struct
 	itv->options.cardtype = cardtype[itv->instance];
 	itv->options.tuner = tuner[itv->instance];
 	itv->options.radio = radio[itv->instance];
+
+	itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
+	if (itv->options.i2c_clock_period == -1)
+		itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
+	else if (itv->options.i2c_clock_period < 10)
+		itv->options.i2c_clock_period = 10;
+	else if (itv->options.i2c_clock_period > 4500)
+		itv->options.i2c_clock_period = 4500;
+
 	itv->options.newi2c = newi2c;
 	if (tunertype < -1 || tunertype > 1) {
 		IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
@@ -865,6 +884,10 @@ static void ivtv_load_and_init_modules(s
 			itv->hw_flags |= device;
 	}
 
+	/* probe for legacy IR controllers that aren't in card definitions */
+	if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
+		ivtv_i2c_new_ir_legacy(itv);
+
 	if (itv->card->hw_all & IVTV_HW_CX25840)
 		itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
 	else if (itv->card->hw_all & IVTV_HW_SAA717X)
@@ -1361,7 +1384,7 @@ static struct pci_driver ivtv_pci_driver
       .remove =   ivtv_remove,
 };
 
-static int module_start(void)
+static int __init module_start(void)
 {
 	printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
 
@@ -1385,7 +1408,7 @@ static int module_start(void)
 	return 0;
 }
 
-static void module_cleanup(void)
+static void __exit module_cleanup(void)
 {
 	pci_unregister_driver(&ivtv_pci_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-driver.h linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2010-02-24 13:52:17.000000000 -0500
@@ -64,6 +64,7 @@
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <media/cx2341x.h>
+#include <media/ir-kbd-i2c.h>
 
 #include <linux/ivtv.h>
 
@@ -176,12 +177,16 @@ extern int ivtv_debug;
 
 #define IVTV_MAX_PGM_INDEX (400)
 
+/* Default I2C SCL period in microseconds */
+#define IVTV_DEFAULT_I2C_CLOCK_PERIOD	20
+
 struct ivtv_options {
 	int kilobytes[IVTV_MAX_STREAMS];        /* size in kilobytes of each stream */
 	int cardtype;				/* force card type on load */
 	int tuner;				/* set tuner on load */
 	int radio;				/* enable/disable radio */
 	int newi2c;				/* new I2C algorithm */
+	int i2c_clock_period;			/* period of SCL for I2C bus */
 };
 
 /* ivtv-specific mailbox template */
@@ -677,6 +682,7 @@ struct ivtv {
 	int i2c_state;                  /* i2c bit state */
 	struct mutex i2c_bus_lock;      /* lock i2c bus */
 
+	struct IR_i2c_init_data ir_i2c_init_data;
 
 	/* Program Index information */
 	u32 pgm_info_offset;            /* start of pgm info in encoder memory */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-fileops.c linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-fileops.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-fileops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-fileops.c	2010-02-24 13:52:17.000000000 -0500
@@ -985,8 +985,8 @@ int ivtv_v4l2_open(struct file *filp)
 
 	mutex_lock(&itv->serialize_lock);
 	if (ivtv_init_on_first_open(itv)) {
-		IVTV_ERR("Failed to initialize on minor %d\n",
-				vdev->minor);
+		IVTV_ERR("Failed to initialize on device %s\n",
+			 video_device_node_name(vdev));
 		mutex_unlock(&itv->serialize_lock);
 		return -ENXIO;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-i2c.c linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -88,6 +88,11 @@
 #define IVTV_UPD64083_I2C_ADDR 		0x5c
 #define IVTV_VP27SMPX_I2C_ADDR      	0x5b
 #define IVTV_M52790_I2C_ADDR      	0x48
+#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR	0x40
+#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 	0x1a
+#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 	0x18
+#define IVTV_Z8F0811_IR_TX_I2C_ADDR	0x70
+#define IVTV_Z8F0811_IR_RX_I2C_ADDR	0x71
 
 /* This array should match the IVTV_HW_ defines */
 static const u8 hw_addrs[] = {
@@ -106,7 +111,12 @@ static const u8 hw_addrs[] = {
 	IVTV_WM8739_I2C_ADDR,
 	IVTV_VP27SMPX_I2C_ADDR,
 	IVTV_M52790_I2C_ADDR,
-	0 		/* IVTV_HW_GPIO dummy driver ID */
+	0,				/* IVTV_HW_GPIO dummy driver ID */
+	IVTV_AVERMEDIA_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_AVER */
+	IVTV_HAUP_EXT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	IVTV_HAUP_INT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	IVTV_Z8F0811_IR_TX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	IVTV_Z8F0811_IR_RX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the IVTV_HW_ defines */
@@ -126,7 +136,12 @@ static const char *hw_modules[] = {
 	"wm8739",
 	"vp27smpx",
 	"m52790",
-	NULL
+	NULL,
+	NULL,		/* IVTV_HW_I2C_IR_RX_AVER */
+	NULL,		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	NULL,		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	NULL,		/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	NULL,		/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the IVTV_HW_ defines */
@@ -147,8 +162,95 @@ static const char * const hw_devicenames
 	"vp27smpx",
 	"m52790",
 	"gpio",
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_AVER */
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
+	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
+	"ir_tx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
+	"ir_rx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
 };
 
+static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
+{
+	struct i2c_board_info info;
+	struct i2c_adapter *adap = &itv->i2c_adap;
+	struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
+	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
+
+	/* Only allow one IR transmitter to be registered per board */
+	if (hw & IVTV_HW_IR_TX_ANY) {
+		if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
+			return -1;
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, type, I2C_NAME_SIZE);
+		return i2c_new_probed_device(adap, &info, addr_list) == NULL
+								     ? -1 : 0;
+	}
+
+	/* Only allow one IR receiver to be registered per board */
+	if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
+		return -1;
+
+	/* Our default information for ir-kbd-i2c.c to use */
+	switch (hw) {
+	case IVTV_HW_I2C_IR_RX_AVER:
+		init_data->ir_codes = &ir_codes_avermedia_cardbus_table;
+		init_data->internal_get_key_func =
+					IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
+		init_data->type = IR_TYPE_OTHER;
+		init_data->name = "AVerMedia AVerTV card";
+		break;
+	case IVTV_HW_I2C_IR_RX_HAUP_EXT:
+	case IVTV_HW_I2C_IR_RX_HAUP_INT:
+		/* Default to old black remote */
+		init_data->ir_codes = &ir_codes_rc5_tv_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = itv->card_name;
+		break;
+	case IVTV_HW_Z8F0811_IR_RX_HAUP:
+		/* Default to grey remote */
+		init_data->ir_codes = &ir_codes_hauppauge_new_table;
+		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+		init_data->type = IR_TYPE_RC5;
+		init_data->name = itv->card_name;
+		break;
+	}
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.platform_data = init_data;
+	strlcpy(info.type, type, I2C_NAME_SIZE);
+
+	return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
+}
+
+/* Instantiate the IR receiver device using probing -- undesirable */
+struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
+{
+	struct i2c_board_info info;
+	/*
+	 * The external IR receiver is at i2c address 0x34.
+	 * The internal IR receiver is at i2c address 0x30.
+	 *
+	 * In theory, both can be fitted, and Hauppauge suggests an external
+	 * overrides an internal.  That's why we probe 0x1a (~0x34) first. CB
+	 *
+	 * Some of these addresses we probe may collide with other i2c address
+	 * allocations, so this function must be called after all other i2c
+	 * devices we care about are registered.
+	 */
+	const unsigned short addr_list[] = {
+		0x1a,	/* Hauppauge IR external - collides with WM8739 */
+		0x18,	/* Hauppauge IR internal */
+		0x71,	/* Hauppauge IR (PVR150) */
+		0x6b,	/* Adaptec IR */
+		I2C_CLIENT_END
+	};
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+}
+
 int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 {
 	struct v4l2_subdev *sd;
@@ -178,8 +280,15 @@ int ivtv_i2c_register(struct ivtv *itv,
 			sd->grp_id = 1 << idx;
 		return sd ? 0 : -1;
 	}
+
+	if (hw & IVTV_HW_IR_ANY)
+		return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
+
+	/* Is it not an I2C device or one we do not wish to register? */
 	if (!hw_addrs[idx])
 		return -1;
+
+	/* It's an I2C device other than an analog tuner or IR chip */
 	if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
@@ -564,20 +673,22 @@ static struct i2c_adapter ivtv_i2c_adap_
 	.owner = THIS_MODULE,
 };
 
+#define IVTV_ALGO_BIT_TIMEOUT	(2)	/* seconds */
+
 static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
 	.setsda		= ivtv_setsda_old,
 	.setscl		= ivtv_setscl_old,
 	.getsda		= ivtv_getsda_old,
 	.getscl		= ivtv_getscl_old,
-	.udelay		= 10,
-	.timeout	= 200,
+	.udelay		= IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2,  /* microseconds */
+	.timeout	= IVTV_ALGO_BIT_TIMEOUT * HZ,         /* jiffies */
 };
 
 static struct i2c_client ivtv_i2c_client_template = {
 	.name = "ivtv internal",
 };
 
-/* init + register i2c adapter + instantiate IR receiver */
+/* init + register i2c adapter */
 int init_ivtv_i2c(struct ivtv *itv)
 {
 	int retval;
@@ -585,11 +696,10 @@ int init_ivtv_i2c(struct ivtv *itv)
 	IVTV_DEBUG_I2C("i2c init\n");
 
 	/* Sanity checks for the I2C hardware arrays. They must be the
-	 * same size and GPIO must be the last entry.
+	 * same size.
 	 */
 	if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
-	    ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) ||
-	    IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
+	    ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules)) {
 		IVTV_ERR("Mismatched I2C hardware arrays\n");
 		return -ENODEV;
 	}
@@ -602,6 +712,7 @@ int init_ivtv_i2c(struct ivtv *itv)
 		memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
 		       sizeof(struct i2c_algo_bit_data));
 	}
+	itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
 	itv->i2c_algo.data = itv;
 	itv->i2c_adap.algo_data = &itv->i2c_algo;
 
@@ -623,32 +734,6 @@ int init_ivtv_i2c(struct ivtv *itv)
 	else
 		retval = i2c_bit_add_bus(&itv->i2c_adap);
 
-	/* Instantiate the IR receiver device, if present */
-	if (retval == 0) {
-		struct i2c_board_info info;
-		/* The external IR receiver is at i2c address 0x34 (0x35 for
-		   reads).  Future Hauppauge cards will have an internal
-		   receiver at 0x30 (0x31 for reads).  In theory, both can be
-		   fitted, and Hauppauge suggest an external overrides an
-		   internal.
-
-		   That's why we probe 0x1a (~0x34) first. CB
-		*/
-		const unsigned short addr_list[] = {
-			0x1a,	/* Hauppauge IR external */
-			0x18,	/* Hauppauge IR internal */
-			0x71,	/* Hauppauge IR (PVR150) */
-			0x64,	/* Pixelview IR */
-			0x30,	/* KNC ONE IR */
-			0x6b,	/* Adaptec IR */
-			I2C_CLIENT_END
-		};
-
-		memset(&info, 0, sizeof(struct i2c_board_info));
-		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
-		i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
-	}
-
 	return retval;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-i2c.h linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-i2c.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-i2c.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-i2c.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,7 @@
 #ifndef IVTV_I2C_H
 #define IVTV_I2C_H
 
+struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
 int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
 struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-streams.c linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-streams.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2010-02-24 13:52:17.000000000 -0500
@@ -245,6 +245,7 @@ static int ivtv_reg_dev(struct ivtv *itv
 {
 	struct ivtv_stream *s = &itv->streams[type];
 	int vfl_type = ivtv_stream_info[type].vfl_type;
+	const char *name;
 	int num;
 
 	if (s->vdev == NULL)
@@ -268,24 +269,24 @@ static int ivtv_reg_dev(struct ivtv *itv
 		s->vdev = NULL;
 		return -ENOMEM;
 	}
-	num = s->vdev->num;
+	name = video_device_node_name(s->vdev);
 
 	switch (vfl_type) {
 	case VFL_TYPE_GRABBER:
-		IVTV_INFO("Registered device video%d for %s (%d kB)\n",
-			num, s->name, itv->options.kilobytes[type]);
+		IVTV_INFO("Registered device %s for %s (%d kB)\n",
+			name, s->name, itv->options.kilobytes[type]);
 		break;
 	case VFL_TYPE_RADIO:
-		IVTV_INFO("Registered device radio%d for %s\n",
-			num, s->name);
+		IVTV_INFO("Registered device %s for %s\n",
+			name, s->name);
 		break;
 	case VFL_TYPE_VBI:
 		if (itv->options.kilobytes[type])
-			IVTV_INFO("Registered device vbi%d for %s (%d kB)\n",
-				num, s->name, itv->options.kilobytes[type]);
+			IVTV_INFO("Registered device %s for %s (%d kB)\n",
+				name, s->name, itv->options.kilobytes[type]);
 		else
-			IVTV_INFO("Registered device vbi%d for %s\n",
-				num, s->name);
+			IVTV_INFO("Registered device %s for %s\n",
+				name, s->name);
 		break;
 	}
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/Kconfig linux-libre-2.6.33-gnu1/drivers/media/video/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/media/video/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -37,10 +37,6 @@ config VIDEO_BTCX
 	depends on PCI
 	tristate
 
-config VIDEO_IR
-	tristate
-	depends on INPUT
-
 config VIDEO_TVEEPROM
 	tristate
 	depends on I2C
@@ -600,7 +596,7 @@ source "drivers/media/video/bt8xx/Kconfi
 
 config VIDEO_PMS
 	tristate "Mediavision Pro Movie Studio Video For Linux"
-	depends on ISA && VIDEO_V4L1
+	depends on ISA && VIDEO_V4L2
 	help
 	  Say Y if you have such a thing.
 
@@ -840,6 +836,12 @@ config SOC_CAMERA_MT9T031
 	help
 	  This driver supports MT9T031 cameras from Micron.
 
+config SOC_CAMERA_MT9T112
+	tristate "mt9t112 support"
+	depends on SOC_CAMERA && I2C
+	help
+	  This driver supports MT9T112 cameras from Aptina.
+
 config SOC_CAMERA_MT9V022
 	tristate "mt9v022 support"
 	depends on SOC_CAMERA && I2C
@@ -847,6 +849,12 @@ config SOC_CAMERA_MT9V022
 	help
 	  This driver supports MT9V022 cameras from Micron
 
+config SOC_CAMERA_RJ54N1
+	tristate "rj54n1cb0c support"
+	depends on SOC_CAMERA && I2C
+	help
+	  This is a rj54n1cb0c video driver
+
 config SOC_CAMERA_TW9910
 	tristate "tw9910 support"
 	depends on SOC_CAMERA && I2C
@@ -865,6 +873,12 @@ config SOC_CAMERA_OV772X
 	help
 	  This is a ov772x camera driver
 
+config SOC_CAMERA_OV9640
+	tristate "ov9640 camera support"
+	depends on SOC_CAMERA && I2C
+	help
+	  This is a ov9640 camera driver
+
 config MX1_VIDEO
 	bool
 
@@ -939,9 +953,14 @@ source "drivers/media/video/usbvideo/Kco
 source "drivers/media/video/et61x251/Kconfig"
 
 config VIDEO_OVCAMCHIP
-	tristate "OmniVision Camera Chip support"
+	tristate "OmniVision Camera Chip support (DEPRECATED)"
 	depends on I2C && VIDEO_V4L1
 	---help---
+	  This driver is DEPRECATED please use the gspca ov519 module
+	  instead. Note that for the ov511 / ov518 support of the gspca module
+	  you need atleast version 0.6.0 of libv4l and for the w9968cf
+	  atleast version 0.6.3 of libv4l.
+
 	  Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
 	  This driver is intended to be used with the ov511 and w9968cf USB
 	  camera drivers.
@@ -950,9 +969,13 @@ config VIDEO_OVCAMCHIP
 	  module will be called ovcamchip.
 
 config USB_W9968CF
-	tristate "USB W996[87]CF JPEG Dual Mode Camera support"
+	tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
 	---help---
+	  This driver is DEPRECATED please use the gspca ov519 module
+	  instead. Note that for the w9968cf support of the gspca module
+	  you need atleast version 0.6.3 of libv4l.
+
 	  Say Y here if you want support for cameras based on OV681 or
 	  Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
 
@@ -995,9 +1018,13 @@ config USB_SE401
 source "drivers/media/video/sn9c102/Kconfig"
 
 config USB_STV680
-	tristate "USB STV680 (Pencam) Camera support"
+	tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
 	depends on VIDEO_V4L1
 	---help---
+	  This driver is DEPRECATED please use the gspca stv0680 module
+	  instead. Note that for the gspca stv0680 module you need
+	  atleast version 0.6.3 of libv4l.
+
 	  Say Y here if you want to connect this type of camera to your
 	  computer's USB port. This includes the Pencam line of cameras.
 	  See <file:Documentation/video4linux/stv680.txt> for more information
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/Makefile linux-libre-2.6.33-gnu1/drivers/media/video/Makefile
--- linux-libre-2.6.32-gnu1/drivers/media/video/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -75,8 +75,11 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
 obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
 obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
+obj-$(CONFIG_SOC_CAMERA_MT9T112)	+= mt9t112.o
 obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
 obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
+obj-$(CONFIG_SOC_CAMERA_OV9640)		+= ov9640.o
+obj-$(CONFIG_SOC_CAMERA_RJ54N1)		+= rj54n1cb0c.o
 obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
 
 # And now the v4l2 drivers:
@@ -147,7 +150,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
 obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
 obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
-obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
+obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o soc_mediabus.o
 obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
 # soc-camera host drivers have to be linked after camera drivers
 obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/meye.c linux-libre-2.6.33-gnu1/drivers/media/video/meye.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/meye.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/meye.c	2010-02-24 13:52:17.000000000 -0500
@@ -800,8 +800,8 @@ again:
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
 		}
@@ -811,7 +811,8 @@ again:
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	} else {
 		int size;
@@ -820,8 +821,8 @@ again:
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
 		}
@@ -831,7 +832,8 @@ again:
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	}
 	mchip_free_frame();
@@ -859,8 +861,8 @@ static int meye_open(struct file *file)
 
 	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-	kfifo_reset(meye.grabq);
-	kfifo_reset(meye.doneq);
+	kfifo_reset(&meye.grabq);
+	kfifo_reset(&meye.doneq);
 	return 0;
 }
 
@@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb)
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
+	kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+			 &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -965,7 +968,9 @@ static int meyeioc_sync(struct file *fil
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
+		if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused,
+				sizeof(int), &meye.doneq_lock) != sizeof(int))
+					break;
 	}
 	*i = meye.grab_buffer[*i].size;
 	mutex_unlock(&meye.lock);
@@ -1452,7 +1457,8 @@ static int vidioc_qbuf(struct file *file
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+	kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index,
+			sizeof(int), &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -1467,19 +1473,19 @@ static int vidioc_dqbuf(struct file *fil
 
 	mutex_lock(&meye.lock);
 
-	if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
+	if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
 		mutex_unlock(&meye.lock);
 		return -EAGAIN;
 	}
 
 	if (wait_event_interruptible(meye.proc_list,
-				     kfifo_len(meye.doneq) != 0) < 0) {
+				     kfifo_len(&meye.doneq) != 0) < 0) {
 		mutex_unlock(&meye.lock);
 		return -EINTR;
 	}
 
-	if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
-		       sizeof(int))) {
+	if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr,
+		       sizeof(int), &meye.doneq_lock)) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
 	}
@@ -1529,8 +1535,8 @@ static int vidioc_streamoff(struct file
 {
 	mutex_lock(&meye.lock);
 	mchip_hic_stop();
-	kfifo_reset(meye.grabq);
-	kfifo_reset(meye.doneq);
+	kfifo_reset(&meye.grabq);
+	kfifo_reset(&meye.doneq);
 
 	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
@@ -1572,7 +1578,7 @@ static unsigned int meye_poll(struct fil
 
 	mutex_lock(&meye.lock);
 	poll_wait(file, &meye.proc_list, wait);
-	if (kfifo_len(meye.doneq))
+	if (kfifo_len(&meye.doneq))
 		res = POLLIN | POLLRDNORM;
 	mutex_unlock(&meye.lock);
 	return res;
@@ -1681,7 +1687,6 @@ static struct video_device meye_template
 	.fops		= &meye_fops,
 	.ioctl_ops 	= &meye_ioctl_ops,
 	.release	= video_device_release,
-	.minor		= -1,
 };
 
 #ifdef CONFIG_PM
@@ -1746,16 +1751,14 @@ static int __devinit meye_probe(struct p
 	}
 
 	spin_lock_init(&meye.grabq_lock);
-	meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.grabq_lock);
-	if (IS_ERR(meye.grabq)) {
+	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
 	spin_lock_init(&meye.doneq_lock);
-	meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.doneq_lock);
-	if (IS_ERR(meye.doneq)) {
+	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc2;
 	}
@@ -1869,9 +1872,9 @@ outregions:
 outenabledev:
 	sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 outsonypienable:
-	kfifo_free(meye.doneq);
+	kfifo_free(&meye.doneq);
 outkfifoalloc2:
-	kfifo_free(meye.grabq);
+	kfifo_free(&meye.grabq);
 outkfifoalloc1:
 	vfree(meye.grab_temp);
 outvmalloc:
@@ -1902,8 +1905,8 @@ static void __devexit meye_remove(struct
 
 	sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 
-	kfifo_free(meye.doneq);
-	kfifo_free(meye.grabq);
+	kfifo_free(&meye.doneq);
+	kfifo_free(&meye.grabq);
 
 	vfree(meye.grab_temp);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/meye.h linux-libre-2.6.33-gnu1/drivers/media/video/meye.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/meye.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/meye.h	2010-02-24 13:52:17.000000000 -0500
@@ -303,9 +303,9 @@ struct meye {
 	struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
 	int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
 	struct mutex lock;		/* mutex for open/mmap... */
-	struct kfifo *grabq;		/* queue for buffers to be grabbed */
+	struct kfifo grabq;		/* queue for buffers to be grabbed */
 	spinlock_t grabq_lock;		/* lock protecting the queue */
-	struct kfifo *doneq;		/* queue for grabbed buffers */
+	struct kfifo doneq;		/* queue for grabbed buffers */
 	spinlock_t doneq_lock;		/* lock protecting the queue */
 	wait_queue_head_t proc_list;	/* wait queue */
 	struct video_device *video_dev;	/* video device parameters */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mt9m001.c linux-libre-2.6.33-gnu1/drivers/media/video/mt9m001.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mt9m001.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mt9m001.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,11 @@
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
-/* mt9m001 i2c address 0x5d
+/*
+ * mt9m001 i2c address 0x5d
  * The platform has to define ctruct i2c_board_info objects and link to them
- * from struct soc_camera_link */
+ * from struct soc_camera_link
+ */
 
 /* mt9m001 selected register addresses */
 #define MT9M001_CHIP_VERSION		0x00
@@ -46,42 +48,50 @@
 #define MT9M001_COLUMN_SKIP		20
 #define MT9M001_ROW_SKIP		12
 
-static const struct soc_camera_data_format mt9m001_colour_formats[] = {
-	/* Order important: first natively supported,
-	 * second supported with a GPIO extender */
-	{
-		.name		= "Bayer (sRGB) 10 bit",
-		.depth		= 10,
-		.fourcc		= V4L2_PIX_FMT_SBGGR16,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
-	}, {
-		.name		= "Bayer (sRGB) 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_SBGGR8,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
-	}
+/* MT9M001 has only one fixed colorspace per pixelcode */
+struct mt9m001_datafmt {
+	enum v4l2_mbus_pixelcode	code;
+	enum v4l2_colorspace		colorspace;
 };
 
-static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
+/* Find a data format by a pixel code in an array */
+static const struct mt9m001_datafmt *mt9m001_find_datafmt(
+	enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt,
+	int n)
+{
+	int i;
+	for (i = 0; i < n; i++)
+		if (fmt[i].code == code)
+			return fmt + i;
+
+	return NULL;
+}
+
+static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
+	/*
+	 * Order important: first natively supported,
+	 * second supported with a GPIO extender
+	 */
+	{V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+};
+
+static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
 	/* Order important - see above */
-	{
-		.name		= "Monochrome 10 bit",
-		.depth		= 10,
-		.fourcc		= V4L2_PIX_FMT_Y16,
-	}, {
-		.name		= "Monochrome 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_GREY,
-	},
+	{V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
 };
 
 struct mt9m001 {
 	struct v4l2_subdev subdev;
 	struct v4l2_rect rect;	/* Sensor window */
-	__u32 fourcc;
+	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 gain;
 	unsigned int exposure;
+	unsigned short y_skip_top;	/* Lines to skip at the top */
 	unsigned char autoexposure;
 };
 
@@ -204,8 +214,7 @@ static int mt9m001_s_crop(struct v4l2_su
 	const u16 hblank = 9, vblank = 25;
 	unsigned int total_h;
 
-	if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
-	    mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
+	if (mt9m001->fmts == mt9m001_colour_fmts)
 		/*
 		 * Bayer format - even number of rows for simplicity,
 		 * but let the user play with the top row.
@@ -222,15 +231,17 @@ static int mt9m001_s_crop(struct v4l2_su
 	soc_camera_limit_side(&rect.top, &rect.height,
 		     MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
 
-	total_h = rect.height + icd->y_skip_top + vblank;
+	total_h = rect.height + mt9m001->y_skip_top + vblank;
 
 	/* Blanking and start values - default... */
 	ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
 	if (!ret)
 		ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
 
-	/* The caller provides a supported format, as verified per
-	 * call to icd->try_fmt() */
+	/*
+	 * The caller provides a supported format, as verified per
+	 * call to icd->try_fmt()
+	 */
 	if (!ret)
 		ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
 	if (!ret)
@@ -239,7 +250,7 @@ static int mt9m001_s_crop(struct v4l2_su
 		ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
 	if (!ret)
 		ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
-				rect.height + icd->y_skip_top - 1);
+				rect.height + mt9m001->y_skip_top - 1);
 	if (!ret && mt9m001->autoexposure) {
 		ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
 		if (!ret) {
@@ -283,32 +294,32 @@ static int mt9m001_cropcap(struct v4l2_s
 	return 0;
 }
 
-static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m001_g_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9m001 *mt9m001 = to_mt9m001(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	pix->width		= mt9m001->rect.width;
-	pix->height		= mt9m001->rect.height;
-	pix->pixelformat	= mt9m001->fourcc;
-	pix->field		= V4L2_FIELD_NONE;
-	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+	mf->width	= mt9m001->rect.width;
+	mf->height	= mt9m001->rect.height;
+	mf->code	= mt9m001->fmt->code;
+	mf->colorspace	= mt9m001->fmt->colorspace;
+	mf->field	= V4L2_FIELD_NONE;
 
 	return 0;
 }
 
-static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m001_s_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9m001 *mt9m001 = to_mt9m001(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_crop a = {
 		.c = {
 			.left	= mt9m001->rect.left,
 			.top	= mt9m001->rect.top,
-			.width	= pix->width,
-			.height	= pix->height,
+			.width	= mf->width,
+			.height	= mf->height,
 		},
 	};
 	int ret;
@@ -316,28 +327,39 @@ static int mt9m001_s_fmt(struct v4l2_sub
 	/* No support for scaling so far, just crop. TODO: use skipping */
 	ret = mt9m001_s_crop(sd, &a);
 	if (!ret) {
-		pix->width = mt9m001->rect.width;
-		pix->height = mt9m001->rect.height;
-		mt9m001->fourcc = pix->pixelformat;
+		mf->width	= mt9m001->rect.width;
+		mf->height	= mt9m001->rect.height;
+		mt9m001->fmt	= mt9m001_find_datafmt(mf->code,
+					mt9m001->fmts, mt9m001->num_fmts);
+		mf->colorspace	= mt9m001->fmt->colorspace;
 	}
 
 	return ret;
 }
 
-static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m001_try_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
-	struct soc_camera_device *icd = client->dev.platform_data;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	const struct mt9m001_datafmt *fmt;
 
-	v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
+	v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
 		MT9M001_MAX_WIDTH, 1,
-		&pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top,
-		MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0);
+		&mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
+		MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
 
-	if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
-	    pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
-		pix->height = ALIGN(pix->height - 1, 2);
+	if (mt9m001->fmts == mt9m001_colour_fmts)
+		mf->height = ALIGN(mf->height - 1, 2);
+
+	fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
+				   mt9m001->num_fmts);
+	if (!fmt) {
+		fmt = mt9m001->fmt;
+		mf->code = fmt->code;
+	}
+
+	mf->colorspace	= fmt->colorspace;
 
 	return 0;
 }
@@ -552,7 +574,7 @@ static int mt9m001_s_ctrl(struct v4l2_su
 		if (ctrl->value) {
 			const u16 vblank = 25;
 			unsigned int total_h = mt9m001->rect.height +
-				icd->y_skip_top + vblank;
+				mt9m001->y_skip_top + vblank;
 			if (reg_write(client, MT9M001_SHUTTER_WIDTH,
 				      total_h) < 0)
 				return -EIO;
@@ -568,8 +590,10 @@ static int mt9m001_s_ctrl(struct v4l2_su
 	return 0;
 }
 
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
 static int mt9m001_video_probe(struct soc_camera_device *icd,
 			       struct i2c_client *client)
 {
@@ -579,8 +603,10 @@ static int mt9m001_video_probe(struct so
 	unsigned long flags;
 	int ret;
 
-	/* We must have a parent by now. And it cannot be a wrong one.
-	 * So this entire test is completely redundant. */
+	/*
+	 * We must have a parent by now. And it cannot be a wrong one.
+	 * So this entire test is completely redundant.
+	 */
 	if (!icd->dev.parent ||
 	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
 		return -ENODEV;
@@ -597,11 +623,11 @@ static int mt9m001_video_probe(struct so
 	case 0x8411:
 	case 0x8421:
 		mt9m001->model = V4L2_IDENT_MT9M001C12ST;
-		icd->formats = mt9m001_colour_formats;
+		mt9m001->fmts = mt9m001_colour_fmts;
 		break;
 	case 0x8431:
 		mt9m001->model = V4L2_IDENT_MT9M001C12STM;
-		icd->formats = mt9m001_monochrome_formats;
+		mt9m001->fmts = mt9m001_monochrome_fmts;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -609,7 +635,7 @@ static int mt9m001_video_probe(struct so
 		return -ENODEV;
 	}
 
-	icd->num_formats = 0;
+	mt9m001->num_fmts = 0;
 
 	/*
 	 * This is a 10bit sensor, so by default we only allow 10bit.
@@ -622,14 +648,14 @@ static int mt9m001_video_probe(struct so
 		flags = SOCAM_DATAWIDTH_10;
 
 	if (flags & SOCAM_DATAWIDTH_10)
-		icd->num_formats++;
+		mt9m001->num_fmts++;
 	else
-		icd->formats++;
+		mt9m001->fmts++;
 
 	if (flags & SOCAM_DATAWIDTH_8)
-		icd->num_formats++;
+		mt9m001->num_fmts++;
 
-	mt9m001->fourcc = icd->formats->fourcc;
+	mt9m001->fmt = &mt9m001->fmts[0];
 
 	dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
 		 data == 0x8431 ? "C12STM" : "C12ST");
@@ -655,6 +681,16 @@ static void mt9m001_video_remove(struct
 		icl->free_bus(icl);
 }
 
+static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+	*lines = mt9m001->y_skip_top;
+
+	return 0;
+}
+
 static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
 	.g_ctrl		= mt9m001_g_ctrl,
 	.s_ctrl		= mt9m001_s_ctrl,
@@ -665,19 +701,38 @@ static struct v4l2_subdev_core_ops mt9m0
 #endif
 };
 
+static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index,
+			    enum v4l2_mbus_pixelcode *code)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+	if ((unsigned int)index >= mt9m001->num_fmts)
+		return -EINVAL;
+
+	*code = mt9m001->fmts[index].code;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
 	.s_stream	= mt9m001_s_stream,
-	.s_fmt		= mt9m001_s_fmt,
-	.g_fmt		= mt9m001_g_fmt,
-	.try_fmt	= mt9m001_try_fmt,
+	.s_mbus_fmt	= mt9m001_s_fmt,
+	.g_mbus_fmt	= mt9m001_g_fmt,
+	.try_mbus_fmt	= mt9m001_try_fmt,
 	.s_crop		= mt9m001_s_crop,
 	.g_crop		= mt9m001_g_crop,
 	.cropcap	= mt9m001_cropcap,
+	.enum_mbus_fmt	= mt9m001_enum_fmt,
+};
+
+static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
+	.g_skip_top_lines	= mt9m001_g_skip_top_lines,
 };
 
 static struct v4l2_subdev_ops mt9m001_subdev_ops = {
 	.core	= &mt9m001_subdev_core_ops,
 	.video	= &mt9m001_subdev_video_ops,
+	.sensor	= &mt9m001_subdev_sensor_ops,
 };
 
 static int mt9m001_probe(struct i2c_client *client,
@@ -714,15 +769,17 @@ static int mt9m001_probe(struct i2c_clie
 
 	/* Second stage probe - when a capture adapter is there */
 	icd->ops		= &mt9m001_ops;
-	icd->y_skip_top		= 0;
 
+	mt9m001->y_skip_top	= 0;
 	mt9m001->rect.left	= MT9M001_COLUMN_SKIP;
 	mt9m001->rect.top	= MT9M001_ROW_SKIP;
 	mt9m001->rect.width	= MT9M001_MAX_WIDTH;
 	mt9m001->rect.height	= MT9M001_MAX_HEIGHT;
 
-	/* Simulated autoexposure. If enabled, we calculate shutter width
-	 * ourselves in the driver based on vertical blanking and frame width */
+	/*
+	 * Simulated autoexposure. If enabled, we calculate shutter width
+	 * ourselves in the driver based on vertical blanking and frame width
+	 */
 	mt9m001->autoexposure = 1;
 
 	ret = mt9m001_video_probe(icd, client);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mt9m111.c linux-libre-2.6.33-gnu1/drivers/media/video/mt9m111.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mt9m111.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mt9m111.c	2010-02-24 13:52:17.000000000 -0500
@@ -123,23 +123,34 @@
 #define MT9M111_MAX_HEIGHT	1024
 #define MT9M111_MAX_WIDTH	1280
 
-#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
-	{ .name = _name, .depth = _depth, .fourcc = _fourcc, \
-	.colorspace = _colorspace }
-#define RGB_FMT(_name, _depth, _fourcc) \
-	COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB)
-#define JPG_FMT(_name, _depth, _fourcc) \
-	COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+/* MT9M111 has only one fixed colorspace per pixelcode */
+struct mt9m111_datafmt {
+	enum v4l2_mbus_pixelcode	code;
+	enum v4l2_colorspace		colorspace;
+};
 
-static const struct soc_camera_data_format mt9m111_colour_formats[] = {
-	JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY),
-	JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY),
-	JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV),
-	JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU),
-	RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565),
-	RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555),
-	RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16),
-	RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8),
+/* Find a data format by a pixel code in an array */
+static const struct mt9m111_datafmt *mt9m111_find_datafmt(
+	enum v4l2_mbus_pixelcode code, const struct mt9m111_datafmt *fmt,
+	int n)
+{
+	int i;
+	for (i = 0; i < n; i++)
+		if (fmt[i].code == code)
+			return fmt + i;
+
+	return NULL;
+}
+
+static const struct mt9m111_datafmt mt9m111_colour_fmts[] = {
+	{V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_YUYV8_2X8_BE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_YVYU8_2X8_BE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
 };
 
 enum mt9m111_context {
@@ -152,7 +163,7 @@ struct mt9m111 {
 	int model;	/* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
 	enum mt9m111_context context;
 	struct v4l2_rect rect;
-	u32 pixfmt;
+	const struct mt9m111_datafmt *fmt;
 	unsigned int gain;
 	unsigned char autoexposure;
 	unsigned char datawidth;
@@ -258,8 +269,8 @@ static int mt9m111_setup_rect(struct i2c
 	int width = rect->width;
 	int height = rect->height;
 
-	if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
-	    mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
+	if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
+	    mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE)
 		is_raw_format = 1;
 	else
 		is_raw_format = 0;
@@ -307,7 +318,8 @@ static int mt9m111_setup_pixfmt(struct i
 
 static int mt9m111_setfmt_bayer8(struct i2c_client *client)
 {
-	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
+	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER |
+				    MT9M111_OUTFMT_RGB);
 }
 
 static int mt9m111_setfmt_bayer10(struct i2c_client *client)
@@ -401,8 +413,8 @@ static int mt9m111_make_rect(struct i2c_
 {
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
-	if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
-	    mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
+	if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
+	    mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) {
 		/* Bayer format - even size lengths */
 		rect->width	= ALIGN(rect->width, 2);
 		rect->height	= ALIGN(rect->height, 2);
@@ -460,120 +472,139 @@ static int mt9m111_cropcap(struct v4l2_s
 	return 0;
 }
 
-static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m111_g_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	pix->width		= mt9m111->rect.width;
-	pix->height		= mt9m111->rect.height;
-	pix->pixelformat	= mt9m111->pixfmt;
-	pix->field		= V4L2_FIELD_NONE;
-	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+	mf->width	= mt9m111->rect.width;
+	mf->height	= mt9m111->rect.height;
+	mf->code	= mt9m111->fmt->code;
+	mf->field	= V4L2_FIELD_NONE;
 
 	return 0;
 }
 
-static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
+static int mt9m111_set_pixfmt(struct i2c_client *client,
+			      enum v4l2_mbus_pixelcode code)
 {
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
-	switch (pixfmt) {
-	case V4L2_PIX_FMT_SBGGR8:
+	switch (code) {
+	case V4L2_MBUS_FMT_SBGGR8_1X8:
 		ret = mt9m111_setfmt_bayer8(client);
 		break;
-	case V4L2_PIX_FMT_SBGGR16:
+	case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
 		ret = mt9m111_setfmt_bayer10(client);
 		break;
-	case V4L2_PIX_FMT_RGB555:
+	case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
 		ret = mt9m111_setfmt_rgb555(client);
 		break;
-	case V4L2_PIX_FMT_RGB565:
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
 		ret = mt9m111_setfmt_rgb565(client);
 		break;
-	case V4L2_PIX_FMT_UYVY:
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
 		mt9m111->swap_yuv_y_chromas = 0;
 		mt9m111->swap_yuv_cb_cr = 0;
 		ret = mt9m111_setfmt_yuv(client);
 		break;
-	case V4L2_PIX_FMT_VYUY:
+	case V4L2_MBUS_FMT_YVYU8_2X8_BE:
 		mt9m111->swap_yuv_y_chromas = 0;
 		mt9m111->swap_yuv_cb_cr = 1;
 		ret = mt9m111_setfmt_yuv(client);
 		break;
-	case V4L2_PIX_FMT_YUYV:
+	case V4L2_MBUS_FMT_YUYV8_2X8_LE:
 		mt9m111->swap_yuv_y_chromas = 1;
 		mt9m111->swap_yuv_cb_cr = 0;
 		ret = mt9m111_setfmt_yuv(client);
 		break;
-	case V4L2_PIX_FMT_YVYU:
+	case V4L2_MBUS_FMT_YVYU8_2X8_LE:
 		mt9m111->swap_yuv_y_chromas = 1;
 		mt9m111->swap_yuv_cb_cr = 1;
 		ret = mt9m111_setfmt_yuv(client);
 		break;
 	default:
 		dev_err(&client->dev, "Pixel format not handled : %x\n",
-			pixfmt);
+			code);
 		ret = -EINVAL;
 	}
 
-	if (!ret)
-		mt9m111->pixfmt = pixfmt;
-
 	return ret;
 }
 
-static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m111_s_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
+	const struct mt9m111_datafmt *fmt;
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_rect rect = {
 		.left	= mt9m111->rect.left,
 		.top	= mt9m111->rect.top,
-		.width	= pix->width,
-		.height	= pix->height,
+		.width	= mf->width,
+		.height	= mf->height,
 	};
 	int ret;
 
+	fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts,
+				   ARRAY_SIZE(mt9m111_colour_fmts));
+	if (!fmt)
+		return -EINVAL;
+
 	dev_dbg(&client->dev,
-		"%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
-		pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
+		"%s code=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
+		mf->code, rect.left, rect.top, rect.width, rect.height);
 
 	ret = mt9m111_make_rect(client, &rect);
 	if (!ret)
-		ret = mt9m111_set_pixfmt(client, pix->pixelformat);
-	if (!ret)
-		mt9m111->rect = rect;
+		ret = mt9m111_set_pixfmt(client, mf->code);
+	if (!ret) {
+		mt9m111->rect	= rect;
+		mt9m111->fmt	= fmt;
+		mf->colorspace	= fmt->colorspace;
+	}
+
 	return ret;
 }
 
-static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9m111_try_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_mbus_framefmt *mf)
 {
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
-		pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+	const struct mt9m111_datafmt *fmt;
+	bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE;
+
+	fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts,
+				   ARRAY_SIZE(mt9m111_colour_fmts));
+	if (!fmt) {
+		fmt = mt9m111->fmt;
+		mf->code = fmt->code;
+	}
 
 	/*
 	 * With Bayer format enforce even side lengths, but let the user play
 	 * with the starting pixel
 	 */
 
-	if (pix->height > MT9M111_MAX_HEIGHT)
-		pix->height = MT9M111_MAX_HEIGHT;
-	else if (pix->height < 2)
-		pix->height = 2;
+	if (mf->height > MT9M111_MAX_HEIGHT)
+		mf->height = MT9M111_MAX_HEIGHT;
+	else if (mf->height < 2)
+		mf->height = 2;
 	else if (bayer)
-		pix->height = ALIGN(pix->height, 2);
+		mf->height = ALIGN(mf->height, 2);
 
-	if (pix->width > MT9M111_MAX_WIDTH)
-		pix->width = MT9M111_MAX_WIDTH;
-	else if (pix->width < 2)
-		pix->width = 2;
+	if (mf->width > MT9M111_MAX_WIDTH)
+		mf->width = MT9M111_MAX_WIDTH;
+	else if (mf->width < 2)
+		mf->width = 2;
 	else if (bayer)
-		pix->width = ALIGN(pix->width, 2);
+		mf->width = ALIGN(mf->width, 2);
+
+	mf->colorspace = fmt->colorspace;
 
 	return 0;
 }
@@ -863,7 +894,7 @@ static int mt9m111_restore_state(struct
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
 	mt9m111_set_context(client, mt9m111->context);
-	mt9m111_set_pixfmt(client, mt9m111->pixfmt);
+	mt9m111_set_pixfmt(client, mt9m111->fmt->code);
 	mt9m111_setup_rect(client, &mt9m111->rect);
 	mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
 	mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
@@ -952,9 +983,6 @@ static int mt9m111_video_probe(struct so
 		goto ei2c;
 	}
 
-	icd->formats = mt9m111_colour_formats;
-	icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
-
 	dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
 
 ei2c:
@@ -971,13 +999,24 @@ static struct v4l2_subdev_core_ops mt9m1
 #endif
 };
 
+static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index,
+			    enum v4l2_mbus_pixelcode *code)
+{
+	if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts))
+		return -EINVAL;
+
+	*code = mt9m111_colour_fmts[index].code;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
-	.s_fmt		= mt9m111_s_fmt,
-	.g_fmt		= mt9m111_g_fmt,
-	.try_fmt	= mt9m111_try_fmt,
+	.s_mbus_fmt	= mt9m111_s_fmt,
+	.g_mbus_fmt	= mt9m111_g_fmt,
+	.try_mbus_fmt	= mt9m111_try_fmt,
 	.s_crop		= mt9m111_s_crop,
 	.g_crop		= mt9m111_g_crop,
 	.cropcap	= mt9m111_cropcap,
+	.enum_mbus_fmt	= mt9m111_enum_fmt,
 };
 
 static struct v4l2_subdev_ops mt9m111_subdev_ops = {
@@ -1019,12 +1058,12 @@ static int mt9m111_probe(struct i2c_clie
 
 	/* Second stage probe - when a capture adapter is there */
 	icd->ops		= &mt9m111_ops;
-	icd->y_skip_top		= 0;
 
 	mt9m111->rect.left	= MT9M111_MIN_DARK_COLS;
 	mt9m111->rect.top	= MT9M111_MIN_DARK_ROWS;
 	mt9m111->rect.width	= MT9M111_MAX_WIDTH;
 	mt9m111->rect.height	= MT9M111_MAX_HEIGHT;
+	mt9m111->fmt		= &mt9m111_colour_fmts[0];
 
 	ret = mt9m111_video_probe(icd, client);
 	if (ret) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mt9t031.c linux-libre-2.6.33-gnu1/drivers/media/video/mt9t031.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mt9t031.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mt9t031.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,9 +17,11 @@
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
-/* mt9t031 i2c address 0x5d
+/*
+ * mt9t031 i2c address 0x5d
  * The platform has to define i2c_board_info and link to it from
- * struct soc_camera_link */
+ * struct soc_camera_link
+ */
 
 /* mt9t031 selected register addresses */
 #define MT9T031_CHIP_VERSION		0x00
@@ -58,15 +60,6 @@
 	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH |	\
 	SOCAM_MASTER | SOCAM_DATAWIDTH_10)
 
-static const struct soc_camera_data_format mt9t031_colour_formats[] = {
-	{
-		.name		= "Bayer (sRGB) 10 bit",
-		.depth		= 10,
-		.fourcc		= V4L2_PIX_FMT_SGRBG10,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
-	}
-};
-
 struct mt9t031 {
 	struct v4l2_subdev subdev;
 	struct v4l2_rect rect;	/* Sensor window */
@@ -74,6 +67,7 @@ struct mt9t031 {
 	u16 xskip;
 	u16 yskip;
 	unsigned int gain;
+	unsigned short y_skip_top;	/* Lines to skip at the top */
 	unsigned int exposure;
 	unsigned char autoexposure;
 };
@@ -207,6 +201,71 @@ static unsigned long mt9t031_query_bus_p
 	return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
 }
 
+enum {
+	MT9T031_CTRL_VFLIP,
+	MT9T031_CTRL_HFLIP,
+	MT9T031_CTRL_GAIN,
+	MT9T031_CTRL_EXPOSURE,
+	MT9T031_CTRL_EXPOSURE_AUTO,
+};
+
+static const struct v4l2_queryctrl mt9t031_controls[] = {
+	[MT9T031_CTRL_VFLIP] = {
+		.id		= V4L2_CID_VFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Vertically",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+	[MT9T031_CTRL_HFLIP] = {
+		.id		= V4L2_CID_HFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Horizontally",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+	[MT9T031_CTRL_GAIN] = {
+		.id		= V4L2_CID_GAIN,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Gain",
+		.minimum	= 0,
+		.maximum	= 127,
+		.step		= 1,
+		.default_value	= 64,
+		.flags		= V4L2_CTRL_FLAG_SLIDER,
+	},
+	[MT9T031_CTRL_EXPOSURE] = {
+		.id		= V4L2_CID_EXPOSURE,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Exposure",
+		.minimum	= 1,
+		.maximum	= 255,
+		.step		= 1,
+		.default_value	= 255,
+		.flags		= V4L2_CTRL_FLAG_SLIDER,
+	},
+	[MT9T031_CTRL_EXPOSURE_AUTO] = {
+		.id		= V4L2_CID_EXPOSURE_AUTO,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Automatic Exposure",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 1,
+	}
+};
+
+static struct soc_camera_ops mt9t031_ops = {
+	.set_bus_param		= mt9t031_set_bus_param,
+	.query_bus_param	= mt9t031_query_bus_param,
+	.controls		= mt9t031_controls,
+	.num_controls		= ARRAY_SIZE(mt9t031_controls),
+};
+
 /* target must be _even_ */
 static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
 {
@@ -226,10 +285,9 @@ static u16 mt9t031_skip(s32 *source, s32
 }
 
 /* rect is the sensor rectangle, the caller guarantees parameter validity */
-static int mt9t031_set_params(struct soc_camera_device *icd,
+static int mt9t031_set_params(struct i2c_client *client,
 			      struct v4l2_rect *rect, u16 xskip, u16 yskip)
 {
-	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	int ret;
 	u16 xbin, ybin;
@@ -291,8 +349,10 @@ static int mt9t031_set_params(struct soc
 	dev_dbg(&client->dev, "new physical left %u, top %u\n",
 		rect->left, rect->top);
 
-	/* The caller provides a supported format, as guaranteed by
-	 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
+	/*
+	 * The caller provides a supported format, as guaranteed by
+	 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap()
+	 */
 	if (ret >= 0)
 		ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
 	if (ret >= 0)
@@ -301,15 +361,14 @@ static int mt9t031_set_params(struct soc
 		ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
 	if (ret >= 0)
 		ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
-				rect->height + icd->y_skip_top - 1);
+				rect->height + mt9t031->y_skip_top - 1);
 	if (ret >= 0 && mt9t031->autoexposure) {
-		unsigned int total_h = rect->height + icd->y_skip_top + vblank;
+		unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank;
 		ret = set_shutter(client, total_h);
 		if (ret >= 0) {
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
 			const struct v4l2_queryctrl *qctrl =
-				soc_camera_find_qctrl(icd->ops,
-						      V4L2_CID_EXPOSURE);
+				&mt9t031_controls[MT9T031_CTRL_EXPOSURE];
 			mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
 				 (qctrl->maximum - qctrl->minimum)) /
 				shutter_max + qctrl->minimum;
@@ -334,7 +393,6 @@ static int mt9t031_s_crop(struct v4l2_su
 	struct v4l2_rect rect = a->c;
 	struct i2c_client *client = sd->priv;
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
-	struct soc_camera_device *icd = client->dev.platform_data;
 
 	rect.width = ALIGN(rect.width, 2);
 	rect.height = ALIGN(rect.height, 2);
@@ -345,7 +403,7 @@ static int mt9t031_s_crop(struct v4l2_su
 	soc_camera_limit_side(&rect.top, &rect.height,
 		     MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
 
-	return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip);
+	return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
 }
 
 static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -373,27 +431,26 @@ static int mt9t031_cropcap(struct v4l2_s
 	return 0;
 }
 
-static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9t031_g_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	pix->width		= mt9t031->rect.width / mt9t031->xskip;
-	pix->height		= mt9t031->rect.height / mt9t031->yskip;
-	pix->pixelformat	= V4L2_PIX_FMT_SGRBG10;
-	pix->field		= V4L2_FIELD_NONE;
-	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+	mf->width	= mt9t031->rect.width / mt9t031->xskip;
+	mf->height	= mt9t031->rect.height / mt9t031->yskip;
+	mf->code	= V4L2_MBUS_FMT_SBGGR10_1X10;
+	mf->colorspace	= V4L2_COLORSPACE_SRGB;
+	mf->field	= V4L2_FIELD_NONE;
 
 	return 0;
 }
 
-static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9t031_s_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
-	struct soc_camera_device *icd = client->dev.platform_data;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	u16 xskip, yskip;
 	struct v4l2_rect rect = mt9t031->rect;
 
@@ -401,24 +458,29 @@ static int mt9t031_s_fmt(struct v4l2_sub
 	 * try_fmt has put width and height within limits.
 	 * S_FMT: use binning and skipping for scaling
 	 */
-	xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH);
-	yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT);
+	xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
+	yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
+
+	mf->code	= V4L2_MBUS_FMT_SBGGR10_1X10;
+	mf->colorspace	= V4L2_COLORSPACE_SRGB;
 
 	/* mt9t031_set_params() doesn't change width and height */
-	return mt9t031_set_params(icd, &rect, xskip, yskip);
+	return mt9t031_set_params(client, &rect, xskip, yskip);
 }
 
 /*
  * If a user window larger than sensor window is requested, we'll increase the
  * sensor window.
  */
-static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9t031_try_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_mbus_framefmt *mf)
 {
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-
 	v4l_bound_align_image(
-		&pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
-		&pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
+		&mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
+		&mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
+
+	mf->code	= V4L2_MBUS_FMT_SBGGR10_1X10;
+	mf->colorspace	= V4L2_COLORSPACE_SRGB;
 
 	return 0;
 }
@@ -479,59 +541,6 @@ static int mt9t031_s_register(struct v4l
 }
 #endif
 
-static const struct v4l2_queryctrl mt9t031_controls[] = {
-	{
-		.id		= V4L2_CID_VFLIP,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Flip Vertically",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 0,
-	}, {
-		.id		= V4L2_CID_HFLIP,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Flip Horizontally",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 0,
-	}, {
-		.id		= V4L2_CID_GAIN,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Gain",
-		.minimum	= 0,
-		.maximum	= 127,
-		.step		= 1,
-		.default_value	= 64,
-		.flags		= V4L2_CTRL_FLAG_SLIDER,
-	}, {
-		.id		= V4L2_CID_EXPOSURE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Exposure",
-		.minimum	= 1,
-		.maximum	= 255,
-		.step		= 1,
-		.default_value	= 255,
-		.flags		= V4L2_CTRL_FLAG_SLIDER,
-	}, {
-		.id		= V4L2_CID_EXPOSURE_AUTO,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Automatic Exposure",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	}
-};
-
-static struct soc_camera_ops mt9t031_ops = {
-	.set_bus_param		= mt9t031_set_bus_param,
-	.query_bus_param	= mt9t031_query_bus_param,
-	.controls		= mt9t031_controls,
-	.num_controls		= ARRAY_SIZE(mt9t031_controls),
-};
-
 static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	struct i2c_client *client = sd->priv;
@@ -568,15 +577,9 @@ static int mt9t031_s_ctrl(struct v4l2_su
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
-	struct soc_camera_device *icd = client->dev.platform_data;
 	const struct v4l2_queryctrl *qctrl;
 	int data;
 
-	qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id);
-
-	if (!qctrl)
-		return -EINVAL;
-
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		if (ctrl->value)
@@ -595,6 +598,7 @@ static int mt9t031_s_ctrl(struct v4l2_su
 			return -EIO;
 		break;
 	case V4L2_CID_GAIN:
+		qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
 		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 			return -EINVAL;
 		/* See Datasheet Table 7, Gain settings. */
@@ -634,6 +638,7 @@ static int mt9t031_s_ctrl(struct v4l2_su
 		mt9t031->gain = ctrl->value;
 		break;
 	case V4L2_CID_EXPOSURE:
+		qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
 		/* mt9t031 has maximum == default */
 		if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
 			return -EINVAL;
@@ -657,11 +662,11 @@ static int mt9t031_s_ctrl(struct v4l2_su
 			const u16 vblank = MT9T031_VERTICAL_BLANK;
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
 			unsigned int total_h = mt9t031->rect.height +
-				icd->y_skip_top + vblank;
+				mt9t031->y_skip_top + vblank;
 
 			if (set_shutter(client, total_h) < 0)
 				return -EIO;
-			qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
+			qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
 			mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
 				 (qctrl->maximum - qctrl->minimum)) /
 				shutter_max + qctrl->minimum;
@@ -669,15 +674,18 @@ static int mt9t031_s_ctrl(struct v4l2_su
 		} else
 			mt9t031->autoexposure = 0;
 		break;
+	default:
+		return -EINVAL;
 	}
 	return 0;
 }
 
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
 static int mt9t031_video_probe(struct i2c_client *client)
 {
-	struct soc_camera_device *icd = client->dev.platform_data;
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	s32 data;
 	int ret;
@@ -692,8 +700,6 @@ static int mt9t031_video_probe(struct i2
 	switch (data) {
 	case 0x1621:
 		mt9t031->model = V4L2_IDENT_MT9T031;
-		icd->formats = mt9t031_colour_formats;
-		icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
 		break;
 	default:
 		dev_err(&client->dev,
@@ -714,6 +720,16 @@ static int mt9t031_video_probe(struct i2
 	return ret;
 }
 
+static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+
+	*lines = mt9t031->y_skip_top;
+
+	return 0;
+}
+
 static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
 	.g_ctrl		= mt9t031_g_ctrl,
 	.s_ctrl		= mt9t031_s_ctrl,
@@ -724,19 +740,35 @@ static struct v4l2_subdev_core_ops mt9t0
 #endif
 };
 
+static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index,
+			    enum v4l2_mbus_pixelcode *code)
+{
+	if (index)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_SBGGR10_1X10;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
 	.s_stream	= mt9t031_s_stream,
-	.s_fmt		= mt9t031_s_fmt,
-	.g_fmt		= mt9t031_g_fmt,
-	.try_fmt	= mt9t031_try_fmt,
+	.s_mbus_fmt	= mt9t031_s_fmt,
+	.g_mbus_fmt	= mt9t031_g_fmt,
+	.try_mbus_fmt	= mt9t031_try_fmt,
 	.s_crop		= mt9t031_s_crop,
 	.g_crop		= mt9t031_g_crop,
 	.cropcap	= mt9t031_cropcap,
+	.enum_mbus_fmt	= mt9t031_enum_fmt,
+};
+
+static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
+	.g_skip_top_lines	= mt9t031_g_skip_top_lines,
 };
 
 static struct v4l2_subdev_ops mt9t031_subdev_ops = {
 	.core	= &mt9t031_subdev_core_ops,
 	.video	= &mt9t031_subdev_video_ops,
+	.sensor	= &mt9t031_subdev_sensor_ops,
 };
 
 static int mt9t031_probe(struct i2c_client *client,
@@ -745,18 +777,16 @@ static int mt9t031_probe(struct i2c_clie
 	struct mt9t031 *mt9t031;
 	struct soc_camera_device *icd = client->dev.platform_data;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct soc_camera_link *icl;
 	int ret;
 
-	if (!icd) {
-		dev_err(&client->dev, "MT9T031: missing soc-camera data!\n");
-		return -EINVAL;
-	}
+	if (icd) {
+		struct soc_camera_link *icl = to_soc_camera_link(icd);
+		if (!icl) {
+			dev_err(&client->dev, "MT9T031 driver needs platform data\n");
+			return -EINVAL;
+		}
 
-	icl = to_soc_camera_link(icd);
-	if (!icl) {
-		dev_err(&client->dev, "MT9T031 driver needs platform data\n");
-		return -EINVAL;
+		icd->ops = &mt9t031_ops;
 	}
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -771,17 +801,16 @@ static int mt9t031_probe(struct i2c_clie
 
 	v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
 
-	/* Second stage probe - when a capture adapter is there */
-	icd->ops		= &mt9t031_ops;
-	icd->y_skip_top		= 0;
-
+	mt9t031->y_skip_top	= 0;
 	mt9t031->rect.left	= MT9T031_COLUMN_SKIP;
 	mt9t031->rect.top	= MT9T031_ROW_SKIP;
 	mt9t031->rect.width	= MT9T031_MAX_WIDTH;
 	mt9t031->rect.height	= MT9T031_MAX_HEIGHT;
 
-	/* Simulated autoexposure. If enabled, we calculate shutter width
-	 * ourselves in the driver based on vertical blanking and frame width */
+	/*
+	 * Simulated autoexposure. If enabled, we calculate shutter width
+	 * ourselves in the driver based on vertical blanking and frame width
+	 */
 	mt9t031->autoexposure = 1;
 
 	mt9t031->xskip = 1;
@@ -794,7 +823,8 @@ static int mt9t031_probe(struct i2c_clie
 	mt9t031_disable(client);
 
 	if (ret) {
-		icd->ops = NULL;
+		if (icd)
+			icd->ops = NULL;
 		i2c_set_clientdata(client, NULL);
 		kfree(mt9t031);
 	}
@@ -807,7 +837,8 @@ static int mt9t031_remove(struct i2c_cli
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	struct soc_camera_device *icd = client->dev.platform_data;
 
-	icd->ops = NULL;
+	if (icd)
+		icd->ops = NULL;
 	i2c_set_clientdata(client, NULL);
 	client->driver = NULL;
 	kfree(mt9t031);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mt9t112.c linux-libre-2.6.33-gnu1/drivers/media/video/mt9t112.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mt9t112.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mt9t112.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1177 @@
+/*
+ * mt9t112 Camera Driver
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov772x driver, mt9m111 driver,
+ *
+ * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.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/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+
+#include <media/mt9t112.h>
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+
+/* you can check PLL/clock info */
+/* #define EXT_CLOCK 24000000 */
+
+/************************************************************************
+
+
+			macro
+
+
+************************************************************************/
+/*
+ * frame size
+ */
+#define MAX_WIDTH   2048
+#define MAX_HEIGHT  1536
+
+#define VGA_WIDTH   640
+#define VGA_HEIGHT  480
+
+/*
+ * macro of read/write
+ */
+#define ECHECKER(ret, x)		\
+	do {				\
+		(ret) = (x);		\
+		if ((ret) < 0)		\
+			return (ret);	\
+	} while (0)
+
+#define mt9t112_reg_write(ret, client, a, b) \
+	ECHECKER(ret, __mt9t112_reg_write(client, a, b))
+#define mt9t112_mcu_write(ret, client, a, b) \
+	ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
+
+#define mt9t112_reg_mask_set(ret, client, a, b, c) \
+	ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
+#define mt9t112_mcu_mask_set(ret, client, a, b, c) \
+	ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
+
+#define mt9t112_reg_read(ret, client, a) \
+	ECHECKER(ret, __mt9t112_reg_read(client, a))
+
+/*
+ * Logical address
+ */
+#define _VAR(id, offset, base)	(base | (id & 0x1f) << 10 | (offset & 0x3ff))
+#define VAR(id, offset)  _VAR(id, offset, 0x0000)
+#define VAR8(id, offset) _VAR(id, offset, 0x8000)
+
+/************************************************************************
+
+
+			struct
+
+
+************************************************************************/
+struct mt9t112_frame_size {
+	u16 width;
+	u16 height;
+};
+
+struct mt9t112_format {
+	enum v4l2_mbus_pixelcode code;
+	enum v4l2_colorspace colorspace;
+	u16 fmt;
+	u16 order;
+};
+
+struct mt9t112_priv {
+	struct v4l2_subdev		 subdev;
+	struct mt9t112_camera_info	*info;
+	struct i2c_client		*client;
+	struct soc_camera_device	 icd;
+	struct mt9t112_frame_size	 frame;
+	const struct mt9t112_format	*format;
+	int				 model;
+	u32				 flags;
+/* for flags */
+#define INIT_DONE  (1<<0)
+};
+
+/************************************************************************
+
+
+			supported format
+
+
+************************************************************************/
+
+static const struct mt9t112_format mt9t112_cfmts[] = {
+	{
+		.code		= V4L2_MBUS_FMT_YUYV8_2X8_BE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fmt		= 1,
+		.order		= 0,
+	}, {
+		.code		= V4L2_MBUS_FMT_YVYU8_2X8_BE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fmt		= 1,
+		.order		= 1,
+	}, {
+		.code		= V4L2_MBUS_FMT_YUYV8_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fmt		= 1,
+		.order		= 2,
+	}, {
+		.code		= V4L2_MBUS_FMT_YVYU8_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fmt		= 1,
+		.order		= 3,
+	}, {
+		.code		= V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.fmt		= 8,
+		.order		= 2,
+	}, {
+		.code		= V4L2_MBUS_FMT_RGB565_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.fmt		= 4,
+		.order		= 2,
+	},
+};
+
+/************************************************************************
+
+
+			general function
+
+
+************************************************************************/
+static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client),
+			    struct mt9t112_priv,
+			    subdev);
+}
+
+static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
+{
+	struct i2c_msg msg[2];
+	u8 buf[2];
+	int ret;
+
+	command = swab16(command);
+
+	msg[0].addr  = client->addr;
+	msg[0].flags = 0;
+	msg[0].len   = 2;
+	msg[0].buf   = (u8 *)&command;
+
+	msg[1].addr  = client->addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len   = 2;
+	msg[1].buf   = buf;
+
+	/*
+	 * if return value of this function is < 0,
+	 * it mean error.
+	 * else, under 16bit is valid data.
+	 */
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret < 0)
+		return ret;
+
+	memcpy(&ret, buf, 2);
+	return swab16(ret);
+}
+
+static int __mt9t112_reg_write(const struct i2c_client *client,
+			       u16 command, u16 data)
+{
+	struct i2c_msg msg;
+	u8 buf[4];
+	int ret;
+
+	command = swab16(command);
+	data = swab16(data);
+
+	memcpy(buf + 0, &command, 2);
+	memcpy(buf + 2, &data,    2);
+
+	msg.addr  = client->addr;
+	msg.flags = 0;
+	msg.len   = 4;
+	msg.buf   = buf;
+
+	/*
+	 * i2c_transfer return message length,
+	 * but this function should return 0 if correct case
+	 */
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret >= 0)
+		ret = 0;
+
+	return ret;
+}
+
+static int __mt9t112_reg_mask_set(const struct i2c_client *client,
+				  u16  command,
+				  u16  mask,
+				  u16  set)
+{
+	int val = __mt9t112_reg_read(client, command);
+	if (val < 0)
+		return val;
+
+	val &= ~mask;
+	val |= set & mask;
+
+	return __mt9t112_reg_write(client, command, val);
+}
+
+/* mcu access */
+static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
+{
+	int ret;
+
+	ret = __mt9t112_reg_write(client, 0x098E, command);
+	if (ret < 0)
+		return ret;
+
+	return __mt9t112_reg_read(client, 0x0990);
+}
+
+static int __mt9t112_mcu_write(const struct i2c_client *client,
+			       u16 command, u16 data)
+{
+	int ret;
+
+	ret = __mt9t112_reg_write(client, 0x098E, command);
+	if (ret < 0)
+		return ret;
+
+	return __mt9t112_reg_write(client, 0x0990, data);
+}
+
+static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
+				  u16  command,
+				  u16  mask,
+				  u16  set)
+{
+	int val = __mt9t112_mcu_read(client, command);
+	if (val < 0)
+		return val;
+
+	val &= ~mask;
+	val |= set & mask;
+
+	return __mt9t112_mcu_write(client, command, val);
+}
+
+static int mt9t112_reset(const struct i2c_client *client)
+{
+	int ret;
+
+	mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
+	msleep(1);
+	mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
+
+	return ret;
+}
+
+#ifndef EXT_CLOCK
+#define CLOCK_INFO(a, b)
+#else
+#define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
+static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
+{
+	int m, n, p1, p2, p3, p4, p5, p6, p7;
+	u32 vco, clk;
+	char *enable;
+
+	ext /= 1000; /* kbyte order */
+
+	mt9t112_reg_read(n, client, 0x0012);
+	p1 = n & 0x000f;
+	n = n >> 4;
+	p2 = n & 0x000f;
+	n = n >> 4;
+	p3 = n & 0x000f;
+
+	mt9t112_reg_read(n, client, 0x002a);
+	p4 = n & 0x000f;
+	n = n >> 4;
+	p5 = n & 0x000f;
+	n = n >> 4;
+	p6 = n & 0x000f;
+
+	mt9t112_reg_read(n, client, 0x002c);
+	p7 = n & 0x000f;
+
+	mt9t112_reg_read(n, client, 0x0010);
+	m = n & 0x00ff;
+	n = (n >> 8) & 0x003f;
+
+	enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
+	dev_info(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
+
+	vco = 2 * m * ext / (n+1);
+	enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
+	dev_info(&client->dev, "VCO             : %10u K %s\n", vco, enable);
+
+	clk = vco / (p1+1) / (p2+1);
+	enable = (96000 < clk) ? "X" : "";
+	dev_info(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
+
+	clk = vco / (p3+1);
+	enable = (768000 < clk) ? "X" : "";
+	dev_info(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
+
+	clk = vco / (p6+1);
+	enable = (96000 < clk) ? "X" : "";
+	dev_info(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
+
+	clk = vco / (p5+1);
+	enable = (54000 < clk) ? "X" : "";
+	dev_info(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
+
+	clk = vco / (p4+1);
+	enable = (70000 < clk) ? "X" : "";
+	dev_info(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
+
+	clk = vco / (p7+1);
+	dev_info(&client->dev, "External sensor : %10u K\n", clk);
+
+	clk = ext / (n+1);
+	enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
+	dev_info(&client->dev, "PFD             : %10u K %s\n", clk, enable);
+
+	return 0;
+}
+#endif
+
+static void mt9t112_frame_check(u32 *width, u32 *height)
+{
+	if (*width > MAX_WIDTH)
+		*width = MAX_WIDTH;
+
+	if (*height > MAX_HEIGHT)
+		*height = MAX_HEIGHT;
+}
+
+static int mt9t112_set_a_frame_size(const struct i2c_client *client,
+				   u16 width,
+				   u16 height)
+{
+	int ret;
+	u16 wstart = (MAX_WIDTH - width) / 2;
+	u16 hstart = (MAX_HEIGHT - height) / 2;
+
+	/* (Context A) Image Width/Height */
+	mt9t112_mcu_write(ret, client, VAR(26, 0), width);
+	mt9t112_mcu_write(ret, client, VAR(26, 2), height);
+
+	/* (Context A) Output Width/Height */
+	mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
+	mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
+
+	/* (Context A) Start Row/Column */
+	mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
+	mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
+
+	/* (Context A) End Row/Column */
+	mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
+	mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width  + wstart);
+
+	mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
+
+	return ret;
+}
+
+static int mt9t112_set_pll_dividers(const struct i2c_client *client,
+				    u8 m, u8 n,
+				    u8 p1, u8 p2, u8 p3,
+				    u8 p4, u8 p5, u8 p6,
+				    u8 p7)
+{
+	int ret;
+	u16 val;
+
+	/* N/M */
+	val = (n << 8) |
+	      (m << 0);
+	mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
+
+	/* P1/P2/P3 */
+	val = ((p3 & 0x0F) << 8) |
+	      ((p2 & 0x0F) << 4) |
+	      ((p1 & 0x0F) << 0);
+	mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
+
+	/* P4/P5/P6 */
+	val = (0x7         << 12) |
+	      ((p6 & 0x0F) <<  8) |
+	      ((p5 & 0x0F) <<  4) |
+	      ((p4 & 0x0F) <<  0);
+	mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
+
+	/* P7 */
+	val = (0x1         << 12) |
+	      ((p7 & 0x0F) <<  0);
+	mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
+
+	return ret;
+}
+
+static int mt9t112_init_pll(const struct i2c_client *client)
+{
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	int data, i, ret;
+
+	mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
+
+	/* PLL control: BYPASS PLL = 8517 */
+	mt9t112_reg_write(ret, client, 0x0014, 0x2145);
+
+	/* Replace these registers when new timing parameters are generated */
+	mt9t112_set_pll_dividers(client,
+				 priv->info->divider.m,
+				 priv->info->divider.n,
+				 priv->info->divider.p1,
+				 priv->info->divider.p2,
+				 priv->info->divider.p3,
+				 priv->info->divider.p4,
+				 priv->info->divider.p5,
+				 priv->info->divider.p6,
+				 priv->info->divider.p7);
+
+	/*
+	 * TEST_BYPASS  on
+	 * PLL_ENABLE   on
+	 * SEL_LOCK_DET on
+	 * TEST_BYPASS  off
+	 */
+	mt9t112_reg_write(ret, client, 0x0014, 0x2525);
+	mt9t112_reg_write(ret, client, 0x0014, 0x2527);
+	mt9t112_reg_write(ret, client, 0x0014, 0x3427);
+	mt9t112_reg_write(ret, client, 0x0014, 0x3027);
+
+	mdelay(10);
+
+	/*
+	 * PLL_BYPASS off
+	 * Reference clock count
+	 * I2C Master Clock Divider
+	 */
+	mt9t112_reg_write(ret, client, 0x0014, 0x3046);
+	mt9t112_reg_write(ret, client, 0x0022, 0x0190);
+	mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
+
+	/* External sensor clock is PLL bypass */
+	mt9t112_reg_write(ret, client, 0x002E, 0x0500);
+
+	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
+	mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
+
+	/* MCU disabled */
+	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
+
+	/* out of standby */
+	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
+
+	mdelay(50);
+
+	/*
+	 * Standby Workaround
+	 * Disable Secondary I2C Pads
+	 */
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+	mdelay(1);
+
+	/* poll to verify out of standby. Must Poll this bit */
+	for (i = 0; i < 100; i++) {
+		mt9t112_reg_read(data, client, 0x0018);
+		if (!(0x4000 & data))
+			break;
+
+		mdelay(10);
+	}
+
+	return ret;
+}
+
+static int mt9t112_init_setting(const struct i2c_client *client)
+{
+
+	int ret;
+
+	/* Adaptive Output Clock (A) */
+	mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
+
+	/* Read Mode (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
+
+	/* Fine Correction (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
+
+	/* Fine IT Min (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
+
+	/* Fine IT Max Margin (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
+
+	/* Base Frame Lines (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
+
+	/* Min Line Length (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
+
+	/* Line Length (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
+
+	/* Adaptive Output Clock (B) */
+	mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
+
+	/* Row Start (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
+
+	/* Column Start (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
+
+	/* Row End (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
+
+	/* Column End (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
+
+	/* Fine Correction (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
+
+	/* Fine IT Min (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
+
+	/* Fine IT Max Margin (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
+
+	/* Base Frame Lines (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
+
+	/* Min Line Length (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
+
+	/* Line Length (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
+
+	/*
+	 * Flicker Dectection registers
+	 * This section should be replaced whenever new Timing file is generated
+	 * All the following registers need to be replaced
+	 * Following registers are generated from Register Wizard but user can
+	 * modify them. For detail see auto flicker detection tuning
+	 */
+
+	/* FD_FDPERIOD_SELECT */
+	mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
+
+	/* PRI_B_CONFIG_FD_ALGO_RUN */
+	mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
+
+	/* PRI_A_CONFIG_FD_ALGO_RUN */
+	mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
+
+	/*
+	 * AFD range detection tuning registers
+	 */
+
+	/* search_f1_50 */
+	mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
+
+	/* search_f2_50 */
+	mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
+
+	/* search_f1_60 */
+	mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
+
+	/* search_f2_60 */
+	mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
+
+	/* period_50Hz (A) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
+
+	/* secret register by aptina */
+	/* period_50Hz (A MSB) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
+
+	/* period_60Hz (A) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
+
+	/* secret register by aptina */
+	/* period_60Hz (A MSB) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
+
+	/* period_50Hz (B) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
+
+	/* secret register by aptina */
+	/* period_50Hz (B) MSB */
+	mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
+
+	/* period_60Hz (B) */
+	mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
+
+	/* secret register by aptina */
+	/* period_60Hz (B) MSB */
+	mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
+
+	/* FD Mode */
+	mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
+
+	/* Stat_min */
+	mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
+
+	/* Stat_max */
+	mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
+
+	/* Min_amplitude */
+	mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
+
+	/* RX FIFO Watermark (A) */
+	mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
+
+	/* RX FIFO Watermark (B) */
+	mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
+
+	/* MCLK: 16MHz
+	 * PCLK: 73MHz
+	 * CorePixCLK: 36.5 MHz
+	 */
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
+
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
+	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
+
+	return ret;
+}
+
+static int mt9t112_auto_focus_setting(const struct i2c_client *client)
+{
+	int ret;
+
+	mt9t112_mcu_write(ret, client, VAR(12, 13),	0x000F);
+	mt9t112_mcu_write(ret, client, VAR(12, 23),	0x0F0F);
+	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x06);
+
+	mt9t112_reg_write(ret, client, 0x0614, 0x0000);
+
+	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x05);
+	mt9t112_mcu_write(ret, client, VAR8(12, 2),	0x02);
+	mt9t112_mcu_write(ret, client, VAR(12, 3),	0x0002);
+	mt9t112_mcu_write(ret, client, VAR(17, 3),	0x8001);
+	mt9t112_mcu_write(ret, client, VAR(17, 11),	0x0025);
+	mt9t112_mcu_write(ret, client, VAR(17, 13),	0x0193);
+	mt9t112_mcu_write(ret, client, VAR8(17, 33),	0x18);
+	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x05);
+
+	return ret;
+}
+
+static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
+{
+	int ret;
+
+	mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
+
+	return ret;
+}
+
+static int mt9t112_init_camera(const struct i2c_client *client)
+{
+	int ret;
+
+	ECHECKER(ret, mt9t112_reset(client));
+
+	ECHECKER(ret, mt9t112_init_pll(client));
+
+	ECHECKER(ret, mt9t112_init_setting(client));
+
+	ECHECKER(ret, mt9t112_auto_focus_setting(client));
+
+	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
+
+	/* Analog setting B */
+	mt9t112_reg_write(ret, client, 0x3084, 0x2409);
+	mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
+	mt9t112_reg_write(ret, client, 0x3094, 0x4949);
+	mt9t112_reg_write(ret, client, 0x3096, 0x4950);
+
+	/*
+	 * Disable adaptive clock
+	 * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
+	 * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
+	 */
+	mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
+	mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
+
+	/* Configure STatus in Status_before_length Format and enable header */
+	/* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
+	mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
+
+	/* Enable JPEG in context B */
+	/* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
+	mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
+
+	/* Disable Dac_TXLO */
+	mt9t112_reg_write(ret, client, 0x316C, 0x350F);
+
+	/* Set max slew rates */
+	mt9t112_reg_write(ret, client, 0x1E, 0x777);
+
+	return ret;
+}
+
+/************************************************************************
+
+
+			soc_camera_ops
+
+
+************************************************************************/
+static int mt9t112_set_bus_param(struct soc_camera_device *icd,
+				 unsigned long	flags)
+{
+	return 0;
+}
+
+static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
+{
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
+		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
+
+	flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
+		SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
+
+	if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
+		flags |= SOCAM_DATAWIDTH_8;
+	else
+		flags |= SOCAM_DATAWIDTH_10;
+
+	return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static struct soc_camera_ops mt9t112_ops = {
+	.set_bus_param		= mt9t112_set_bus_param,
+	.query_bus_param	= mt9t112_query_bus_param,
+};
+
+/************************************************************************
+
+
+			v4l2_subdev_core_ops
+
+
+************************************************************************/
+static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
+{
+	struct i2c_client *client = sd->priv;
+	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,
+			      struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+	int                ret;
+
+	reg->size = 2;
+	mt9t112_reg_read(ret, client, reg->reg);
+
+	reg->val = (__u64)ret;
+
+	return 0;
+}
+
+static int mt9t112_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+	int ret;
+
+	mt9t112_reg_write(ret, client, reg->reg, reg->val);
+
+	return ret;
+}
+#endif
+
+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,
+#endif
+};
+
+
+/************************************************************************
+
+
+			v4l2_subdev_video_ops
+
+
+************************************************************************/
+static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	int ret = 0;
+
+	if (!enable) {
+		/* FIXME
+		 *
+		 * If user selected large output size,
+		 * and used it long time,
+		 * mt9t112 camera will be very warm.
+		 *
+		 * But current driver can not stop mt9t112 camera.
+		 * So, set small size here to solve this problem.
+		 */
+		mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
+		return ret;
+	}
+
+	if (!(priv->flags & INIT_DONE)) {
+		u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
+			     priv->info->flags) ? 0x0001 : 0x0000;
+
+		ECHECKER(ret, mt9t112_init_camera(client));
+
+		/* Invert PCLK (Data sampled on falling edge of pixclk) */
+		mt9t112_reg_write(ret, client, 0x3C20, param);
+
+		mdelay(5);
+
+		priv->flags |= INIT_DONE;
+	}
+
+	mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
+	mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
+	mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
+
+	mt9t112_set_a_frame_size(client,
+				 priv->frame.width,
+				 priv->frame.height);
+
+	ECHECKER(ret, mt9t112_auto_focus_trigger(client));
+
+	dev_dbg(&client->dev, "format : %d\n", priv->format->code);
+	dev_dbg(&client->dev, "size   : %d x %d\n",
+		priv->frame.width,
+		priv->frame.height);
+
+	CLOCK_INFO(client, EXT_CLOCK);
+
+	return ret;
+}
+
+static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
+			      enum v4l2_mbus_pixelcode code)
+{
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	int i;
+
+	priv->format = NULL;
+
+	/*
+	 * frame size check
+	 */
+	mt9t112_frame_check(&width, &height);
+
+	/*
+	 * get color format
+	 */
+	for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
+		if (mt9t112_cfmts[i].code == code)
+			break;
+
+	if (i == ARRAY_SIZE(mt9t112_cfmts))
+		return -EINVAL;
+
+	priv->frame.width  = (u16)width;
+	priv->frame.height = (u16)height;
+
+	priv->format = mt9t112_cfmts + i;
+
+	return 0;
+}
+
+static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= 0;
+	a->bounds.top			= 0;
+	a->bounds.width			= VGA_WIDTH;
+	a->bounds.height		= VGA_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	a->c.left	= 0;
+	a->c.top	= 0;
+	a->c.width	= VGA_WIDTH;
+	a->c.height	= VGA_HEIGHT;
+	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct v4l2_rect *rect = &a->c;
+
+	return mt9t112_set_params(client, rect->width, rect->height,
+				 V4L2_MBUS_FMT_YUYV8_2X8_BE);
+}
+
+static int mt9t112_g_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9t112_priv *priv = to_mt9t112(client);
+
+	if (!priv->format) {
+		int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
+					     V4L2_MBUS_FMT_YUYV8_2X8_BE);
+		if (ret < 0)
+			return ret;
+	}
+
+	mf->width	= priv->frame.width;
+	mf->height	= priv->frame.height;
+	/* TODO: set colorspace */
+	mf->code	= priv->format->code;
+	mf->field	= V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int mt9t112_s_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+
+	/* TODO: set colorspace */
+	return mt9t112_set_params(client, mf->width, mf->height, mf->code);
+}
+
+static int mt9t112_try_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_mbus_framefmt *mf)
+{
+	mt9t112_frame_check(&mf->width, &mf->height);
+
+	/* TODO: set colorspace */
+	mf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts))
+		return -EINVAL;
+
+	*code = mt9t112_cfmts[index].code;
+	return 0;
+}
+
+static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
+	.s_stream	= mt9t112_s_stream,
+	.g_mbus_fmt	= mt9t112_g_fmt,
+	.s_mbus_fmt	= mt9t112_s_fmt,
+	.try_mbus_fmt	= mt9t112_try_fmt,
+	.cropcap	= mt9t112_cropcap,
+	.g_crop		= mt9t112_g_crop,
+	.s_crop		= mt9t112_s_crop,
+	.enum_mbus_fmt	= mt9t112_enum_fmt,
+};
+
+/************************************************************************
+
+
+			i2c driver
+
+
+************************************************************************/
+static struct v4l2_subdev_ops mt9t112_subdev_ops = {
+	.core	= &mt9t112_subdev_core_ops,
+	.video	= &mt9t112_subdev_video_ops,
+};
+
+static int mt9t112_camera_probe(struct soc_camera_device *icd,
+				struct i2c_client *client)
+{
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	const char          *devname;
+	int                  chipid;
+
+	/*
+	 * We must have a parent by now. And it cannot be a wrong one.
+	 * So this entire test is completely redundant.
+	 */
+	if (!icd->dev.parent ||
+	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+		return -ENODEV;
+
+	/*
+	 * check and show chip ID
+	 */
+	mt9t112_reg_read(chipid, client, 0x0000);
+
+	switch (chipid) {
+	case 0x2680:
+		devname = "mt9t111";
+		priv->model = V4L2_IDENT_MT9T111;
+		break;
+	case 0x2682:
+		devname = "mt9t112";
+		priv->model = V4L2_IDENT_MT9T112;
+		break;
+	default:
+		dev_err(&client->dev, "Product ID error %04x\n", chipid);
+		return -ENODEV;
+	}
+
+	dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
+
+	return 0;
+}
+
+static int mt9t112_probe(struct i2c_client *client,
+			 const struct i2c_device_id *did)
+{
+	struct mt9t112_priv        *priv;
+	struct soc_camera_device   *icd = client->dev.platform_data;
+	struct soc_camera_link     *icl;
+	int                         ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
+	if (!icl || !icl->priv)
+		return -EINVAL;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->info = icl->priv;
+
+	v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
+
+	icd->ops = &mt9t112_ops;
+
+	ret = mt9t112_camera_probe(icd, client);
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int mt9t112_remove(struct i2c_client *client)
+{
+	struct mt9t112_priv *priv = to_mt9t112(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+
+	icd->ops = NULL;
+	i2c_set_clientdata(client, NULL);
+	kfree(priv);
+	return 0;
+}
+
+static const struct i2c_device_id mt9t112_id[] = {
+	{ "mt9t112", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mt9t112_id);
+
+static struct i2c_driver mt9t112_i2c_driver = {
+	.driver = {
+		.name = "mt9t112",
+	},
+	.probe    = mt9t112_probe,
+	.remove   = mt9t112_remove,
+	.id_table = mt9t112_id,
+};
+
+/************************************************************************
+
+
+			module function
+
+
+************************************************************************/
+static int __init mt9t112_module_init(void)
+{
+	return i2c_add_driver(&mt9t112_i2c_driver);
+}
+
+static void __exit mt9t112_module_exit(void)
+{
+	i2c_del_driver(&mt9t112_i2c_driver);
+}
+
+module_init(mt9t112_module_init);
+module_exit(mt9t112_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
+MODULE_AUTHOR("Kuninori Morimoto");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mt9v022.c linux-libre-2.6.33-gnu1/drivers/media/video/mt9v022.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mt9v022.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mt9v022.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,9 +18,11 @@
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
-/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
+/*
+ * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
  * The platform has to define ctruct i2c_board_info objects and link to them
- * from struct soc_camera_link */
+ * from struct soc_camera_link
+ */
 
 static char *sensor_type;
 module_param(sensor_type, charp, S_IRUGO);
@@ -62,41 +64,49 @@ MODULE_PARM_DESC(sensor_type, "Sensor ty
 #define MT9V022_COLUMN_SKIP		1
 #define MT9V022_ROW_SKIP		4
 
-static const struct soc_camera_data_format mt9v022_colour_formats[] = {
-	/* Order important: first natively supported,
-	 * second supported with a GPIO extender */
-	{
-		.name		= "Bayer (sRGB) 10 bit",
-		.depth		= 10,
-		.fourcc		= V4L2_PIX_FMT_SBGGR16,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
-	}, {
-		.name		= "Bayer (sRGB) 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_SBGGR8,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
-	}
+/* MT9V022 has only one fixed colorspace per pixelcode */
+struct mt9v022_datafmt {
+	enum v4l2_mbus_pixelcode	code;
+	enum v4l2_colorspace		colorspace;
 };
 
-static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
+/* Find a data format by a pixel code in an array */
+static const struct mt9v022_datafmt *mt9v022_find_datafmt(
+	enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt,
+	int n)
+{
+	int i;
+	for (i = 0; i < n; i++)
+		if (fmt[i].code == code)
+			return fmt + i;
+
+	return NULL;
+}
+
+static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
+	/*
+	 * Order important: first natively supported,
+	 * second supported with a GPIO extender
+	 */
+	{V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+};
+
+static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
 	/* Order important - see above */
-	{
-		.name		= "Monochrome 10 bit",
-		.depth		= 10,
-		.fourcc		= V4L2_PIX_FMT_Y16,
-	}, {
-		.name		= "Monochrome 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_GREY,
-	},
+	{V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
 };
 
 struct mt9v022 {
 	struct v4l2_subdev subdev;
 	struct v4l2_rect rect;	/* Sensor window */
-	__u32 fourcc;
+	const struct mt9v022_datafmt *fmt;
+	const struct mt9v022_datafmt *fmts;
+	int num_fmts;
 	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
 	u16 chip_control;
+	unsigned short y_skip_top;	/* Lines to skip at the top */
 };
 
 static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
@@ -143,9 +153,11 @@ static int mt9v022_init(struct i2c_clien
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	int ret;
 
-	/* Almost the default mode: master, parallel, simultaneous, and an
+	/*
+	 * Almost the default mode: master, parallel, simultaneous, and an
 	 * undocumented bit 0x200, which is present in table 7, but not in 8,
-	 * plus snapshot mode to disable scan for now */
+	 * plus snapshot mode to disable scan for now
+	 */
 	mt9v022->chip_control |= 0x10;
 	ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
 	if (!ret)
@@ -265,12 +277,10 @@ static int mt9v022_s_crop(struct v4l2_su
 	struct i2c_client *client = sd->priv;
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	struct v4l2_rect rect = a->c;
-	struct soc_camera_device *icd = client->dev.platform_data;
 	int ret;
 
 	/* Bayer format - even size lengths */
-	if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
-	    mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
+	if (mt9v022->fmts == mt9v022_colour_fmts) {
 		rect.width	= ALIGN(rect.width, 2);
 		rect.height	= ALIGN(rect.height, 2);
 		/* Let the user play with the starting pixel */
@@ -287,10 +297,10 @@ static int mt9v022_s_crop(struct v4l2_su
 	if (ret >= 0) {
 		if (ret & 1) /* Autoexposure */
 			ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
-					rect.height + icd->y_skip_top + 43);
+					rect.height + mt9v022->y_skip_top + 43);
 		else
 			ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
-					rect.height + icd->y_skip_top + 43);
+					rect.height + mt9v022->y_skip_top + 43);
 	}
 	/* Setup frame format: defaults apart from width and height */
 	if (!ret)
@@ -298,8 +308,10 @@ static int mt9v022_s_crop(struct v4l2_su
 	if (!ret)
 		ret = reg_write(client, MT9V022_ROW_START, rect.top);
 	if (!ret)
-		/* Default 94, Phytec driver says:
-		 * "width + horizontal blank >= 660" */
+		/*
+		 * Default 94, Phytec driver says:
+		 * "width + horizontal blank >= 660"
+		 */
 		ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
 				rect.width > 660 - 43 ? 43 :
 				660 - rect.width);
@@ -309,7 +321,7 @@ static int mt9v022_s_crop(struct v4l2_su
 		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
 	if (!ret)
 		ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
-				rect.height + icd->y_skip_top);
+				rect.height + mt9v022->y_skip_top);
 
 	if (ret < 0)
 		return ret;
@@ -346,46 +358,48 @@ static int mt9v022_cropcap(struct v4l2_s
 	return 0;
 }
 
-static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9v022_g_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	pix->width		= mt9v022->rect.width;
-	pix->height		= mt9v022->rect.height;
-	pix->pixelformat	= mt9v022->fourcc;
-	pix->field		= V4L2_FIELD_NONE;
-	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+	mf->width	= mt9v022->rect.width;
+	mf->height	= mt9v022->rect.height;
+	mf->code	= mt9v022->fmt->code;
+	mf->colorspace	= mt9v022->fmt->colorspace;
+	mf->field	= V4L2_FIELD_NONE;
 
 	return 0;
 }
 
-static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9v022_s_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_crop a = {
 		.c = {
 			.left	= mt9v022->rect.left,
 			.top	= mt9v022->rect.top,
-			.width	= pix->width,
-			.height	= pix->height,
+			.width	= mf->width,
+			.height	= mf->height,
 		},
 	};
 	int ret;
 
-	/* The caller provides a supported format, as verified per call to
-	 * icd->try_fmt(), datawidth is from our supported format list */
-	switch (pix->pixelformat) {
-	case V4L2_PIX_FMT_GREY:
-	case V4L2_PIX_FMT_Y16:
+	/*
+	 * The caller provides a supported format, as verified per call to
+	 * icd->try_fmt(), datawidth is from our supported format list
+	 */
+	switch (mf->code) {
+	case V4L2_MBUS_FMT_GREY8_1X8:
+	case V4L2_MBUS_FMT_Y10_1X10:
 		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
 			return -EINVAL;
 		break;
-	case V4L2_PIX_FMT_SBGGR8:
-	case V4L2_PIX_FMT_SBGGR16:
+	case V4L2_MBUS_FMT_SBGGR8_1X8:
+	case V4L2_MBUS_FMT_SBGGR10_1X10:
 		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
 			return -EINVAL;
 		break;
@@ -399,26 +413,38 @@ static int mt9v022_s_fmt(struct v4l2_sub
 	/* No support for scaling on this camera, just crop. */
 	ret = mt9v022_s_crop(sd, &a);
 	if (!ret) {
-		pix->width = mt9v022->rect.width;
-		pix->height = mt9v022->rect.height;
-		mt9v022->fourcc = pix->pixelformat;
+		mf->width	= mt9v022->rect.width;
+		mf->height	= mt9v022->rect.height;
+		mt9v022->fmt	= mt9v022_find_datafmt(mf->code,
+					mt9v022->fmts, mt9v022->num_fmts);
+		mf->colorspace	= mt9v022->fmt->colorspace;
 	}
 
 	return ret;
 }
 
-static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int mt9v022_try_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
-	struct soc_camera_device *icd = client->dev.platform_data;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
-		pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	const struct mt9v022_datafmt *fmt;
+	int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_1X10;
 
-	v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
+	v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
 		MT9V022_MAX_WIDTH, align,
-		&pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
-		MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
+		&mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
+		MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
+
+	fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
+				   mt9v022->num_fmts);
+	if (!fmt) {
+		fmt = mt9v022->fmt;
+		mf->code = fmt->code;
+	}
+
+	mf->colorspace	= fmt->colorspace;
 
 	return 0;
 }
@@ -635,8 +661,10 @@ static int mt9v022_s_ctrl(struct v4l2_su
 					      48 + range / 2) / range + 16;
 			if (gain >= 32)
 				gain &= ~1;
-			/* The user wants to set gain manually, hope, she
-			 * knows, what she's doing... Switch AGC off. */
+			/*
+			 * The user wants to set gain manually, hope, she
+			 * knows, what she's doing... Switch AGC off.
+			 */
 
 			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
 				return -EIO;
@@ -655,8 +683,10 @@ static int mt9v022_s_ctrl(struct v4l2_su
 			unsigned long range = qctrl->maximum - qctrl->minimum;
 			unsigned long shutter = ((ctrl->value - qctrl->minimum) *
 						 479 + range / 2) / range + 1;
-			/* The user wants to set shutter width manually, hope,
-			 * she knows, what she's doing... Switch AEC off. */
+			/*
+			 * The user wants to set shutter width manually, hope,
+			 * she knows, what she's doing... Switch AEC off.
+			 */
 
 			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
 				return -EIO;
@@ -689,8 +719,10 @@ static int mt9v022_s_ctrl(struct v4l2_su
 	return 0;
 }
 
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
 static int mt9v022_video_probe(struct soc_camera_device *icd,
 			       struct i2c_client *client)
 {
@@ -733,17 +765,17 @@ static int mt9v022_video_probe(struct so
 			    !strcmp("color", sensor_type))) {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
-		icd->formats = mt9v022_colour_formats;
+		mt9v022->fmts = mt9v022_colour_fmts;
 	} else {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
-		icd->formats = mt9v022_monochrome_formats;
+		mt9v022->fmts = mt9v022_monochrome_fmts;
 	}
 
 	if (ret < 0)
 		goto ei2c;
 
-	icd->num_formats = 0;
+	mt9v022->num_fmts = 0;
 
 	/*
 	 * This is a 10bit sensor, so by default we only allow 10bit.
@@ -756,14 +788,14 @@ static int mt9v022_video_probe(struct so
 		flags = SOCAM_DATAWIDTH_10;
 
 	if (flags & SOCAM_DATAWIDTH_10)
-		icd->num_formats++;
+		mt9v022->num_fmts++;
 	else
-		icd->formats++;
+		mt9v022->fmts++;
 
 	if (flags & SOCAM_DATAWIDTH_8)
-		icd->num_formats++;
+		mt9v022->num_fmts++;
 
-	mt9v022->fourcc = icd->formats->fourcc;
+	mt9v022->fmt = &mt9v022->fmts[0];
 
 	dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
 		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
@@ -787,6 +819,16 @@ static void mt9v022_video_remove(struct
 		icl->free_bus(icl);
 }
 
+static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+	*lines = mt9v022->y_skip_top;
+
+	return 0;
+}
+
 static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
 	.g_ctrl		= mt9v022_g_ctrl,
 	.s_ctrl		= mt9v022_s_ctrl,
@@ -797,19 +839,38 @@ static struct v4l2_subdev_core_ops mt9v0
 #endif
 };
 
+static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index,
+			    enum v4l2_mbus_pixelcode *code)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+	if ((unsigned int)index >= mt9v022->num_fmts)
+		return -EINVAL;
+
+	*code = mt9v022->fmts[index].code;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
 	.s_stream	= mt9v022_s_stream,
-	.s_fmt		= mt9v022_s_fmt,
-	.g_fmt		= mt9v022_g_fmt,
-	.try_fmt	= mt9v022_try_fmt,
+	.s_mbus_fmt	= mt9v022_s_fmt,
+	.g_mbus_fmt	= mt9v022_g_fmt,
+	.try_mbus_fmt	= mt9v022_try_fmt,
 	.s_crop		= mt9v022_s_crop,
 	.g_crop		= mt9v022_g_crop,
 	.cropcap	= mt9v022_cropcap,
+	.enum_mbus_fmt	= mt9v022_enum_fmt,
+};
+
+static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
+	.g_skip_top_lines	= mt9v022_g_skip_top_lines,
 };
 
 static struct v4l2_subdev_ops mt9v022_subdev_ops = {
 	.core	= &mt9v022_subdev_core_ops,
 	.video	= &mt9v022_subdev_video_ops,
+	.sensor	= &mt9v022_subdev_sensor_ops,
 };
 
 static int mt9v022_probe(struct i2c_client *client,
@@ -851,8 +912,7 @@ static int mt9v022_probe(struct i2c_clie
 	 * MT9V022 _really_ corrupts the first read out line.
 	 * TODO: verify on i.MX31
 	 */
-	icd->y_skip_top		= 1;
-
+	mt9v022->y_skip_top	= 1;
 	mt9v022->rect.left	= MT9V022_COLUMN_SKIP;
 	mt9v022->rect.top	= MT9V022_ROW_SKIP;
 	mt9v022->rect.width	= MT9V022_MAX_WIDTH;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mx1_camera.c linux-libre-2.6.33-gnu1/drivers/media/video/mx1_camera.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mx1_camera.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mx1_camera.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-contig.h>
+#include <media/soc_mediabus.h>
 
 #include <asm/dma.h>
 #include <asm/fiq.h>
@@ -94,14 +95,16 @@
 /* buffer for one video frame */
 struct mx1_buffer {
 	/* common v4l buffer stuff -- must be first */
-	struct videobuf_buffer vb;
-	const struct soc_camera_data_format *fmt;
-	int inwork;
+	struct videobuf_buffer		vb;
+	enum v4l2_mbus_pixelcode	code;
+	int				inwork;
 };
 
-/* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
+/*
+ * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
  * Interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too */
+ * one camera, they will have to modify this driver too
+ */
 struct mx1_camera_dev {
 	struct soc_camera_host		soc_host;
 	struct soc_camera_device	*icd;
@@ -126,9 +129,13 @@ static int mx1_videobuf_setup(struct vid
 			      unsigned int *size)
 {
 	struct soc_camera_device *icd = vq->priv_data;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
 
-	*size = icd->user_width * icd->user_height *
-		((icd->current_fmt->depth + 7) >> 3);
+	if (bytes_per_line < 0)
+		return bytes_per_line;
+
+	*size = bytes_per_line * icd->user_height;
 
 	if (!*count)
 		*count = 32;
@@ -151,8 +158,10 @@ static void free_buffer(struct videobuf_
 	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
-	/* This waits until this buffer is out of danger, i.e., until it is no
-	 * longer in STATE_QUEUED or STATE_ACTIVE */
+	/*
+	 * This waits until this buffer is out of danger, i.e., until it is no
+	 * longer in STATE_QUEUED or STATE_ACTIVE
+	 */
 	videobuf_waiton(vb, 0, 0);
 	videobuf_dma_contig_free(vq, vb);
 
@@ -165,6 +174,11 @@ static int mx1_videobuf_prepare(struct v
 	struct soc_camera_device *icd = vq->priv_data;
 	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 	int ret;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+
+	if (bytes_per_line < 0)
+		return bytes_per_line;
 
 	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
@@ -174,22 +188,24 @@ static int mx1_videobuf_prepare(struct v
 
 	BUG_ON(NULL == icd->current_fmt);
 
-	/* I think, in buf_prepare you only have to protect global data,
-	 * the actual buffer is yours */
+	/*
+	 * I think, in buf_prepare you only have to protect global data,
+	 * the actual buffer is yours
+	 */
 	buf->inwork = 1;
 
-	if (buf->fmt	!= icd->current_fmt ||
+	if (buf->code	!= icd->current_fmt->code ||
 	    vb->width	!= icd->user_width ||
 	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
-		buf->fmt	= icd->current_fmt;
+		buf->code	= icd->current_fmt->code;
 		vb->width	= icd->user_width;
 		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
 
-	vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+	vb->size = bytes_per_line * vb->height;
 	if (0 != vb->baddr && vb->bsize < vb->size) {
 		ret = -EINVAL;
 		goto out;
@@ -381,8 +397,10 @@ static int mclk_get_divisor(struct mx1_c
 
 	lcdclk = clk_get_rate(pcdev->clk);
 
-	/* We verify platform_mclk_10khz != 0, so if anyone breaks it, here
-	 * they get a nice Oops */
+	/*
+	 * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
+	 * they get a nice Oops
+	 */
 	div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
 	dev_dbg(pcdev->icd->dev.parent,
@@ -420,8 +438,10 @@ static void mx1_camera_deactivate(struct
 	clk_disable(pcdev->clk);
 }
 
-/* The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface */
+/*
+ * 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)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -487,12 +507,10 @@ static int mx1_camera_set_bus_param(stru
 
 	/* MX1 supports only 8bit buswidth */
 	common_flags = soc_camera_bus_param_compatible(camera_flags,
-							       CSI_BUS_FLAGS);
+						       CSI_BUS_FLAGS);
 	if (!common_flags)
 		return -EINVAL;
 
-	icd->buswidth = 8;
-
 	/* Make choises, based on platform choice */
 	if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
 		(common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
@@ -545,7 +563,8 @@ static int mx1_camera_set_fmt(struct soc
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	int ret;
+	struct v4l2_mbus_framefmt mf;
+	int ret, buswidth;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
@@ -554,12 +573,33 @@ static int mx1_camera_set_fmt(struct soc
 		return -EINVAL;
 	}
 
-	ret = v4l2_subdev_call(sd, video, s_fmt, f);
-	if (!ret) {
-		icd->buswidth = xlate->buswidth;
-		icd->current_fmt = xlate->host_fmt;
+	buswidth = xlate->host_fmt->bits_per_sample;
+	if (buswidth > 8) {
+		dev_warn(icd->dev.parent,
+			 "bits-per-sample %d for format %x unsupported\n",
+			 buswidth, pix->pixelformat);
+		return -EINVAL;
 	}
 
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
+
+	ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+	if (ret < 0)
+		return ret;
+
+	if (mf.code != xlate->code)
+		return -EINVAL;
+
+	pix->width		= mf.width;
+	pix->height		= mf.height;
+	pix->field		= mf.field;
+	pix->colorspace		= mf.colorspace;
+	icd->current_fmt	= xlate;
+
 	return ret;
 }
 
@@ -567,10 +607,36 @@ static int mx1_camera_try_fmt(struct soc
 			      struct v4l2_format *f)
 {
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_mbus_framefmt mf;
+	int ret;
 	/* TODO: limit to mx1 hardware capabilities */
 
+	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+	if (!xlate) {
+		dev_warn(icd->dev.parent, "Format %x not found\n",
+			 pix->pixelformat);
+		return -EINVAL;
+	}
+
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
+
 	/* limit to sensor capabilities */
-	return v4l2_subdev_call(sd, video, try_fmt, f);
+	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+	if (ret < 0)
+		return ret;
+
+	pix->width	= mf.width;
+	pix->height	= mf.height;
+	pix->field	= mf.field;
+	pix->colorspace	= mf.colorspace;
+
+	return 0;
 }
 
 static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -578,10 +644,12 @@ static int mx1_camera_reqbufs(struct soc
 {
 	int i;
 
-	/* This is for locking debugging only. I removed spinlocks and now I
+	/*
+	 * This is for locking debugging only. I removed spinlocks and now I
 	 * check whether .prepare is ever called on a linked buffer, or whether
 	 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
-	 * it hadn't triggered */
+	 * it hadn't triggered
+	 */
 	for (i = 0; i < p->count; i++) {
 		struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i],
 						      struct mx1_buffer, vb);
@@ -650,7 +718,7 @@ static int __init mx1_camera_probe(struc
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	if (!res || !irq) {
+	if (!res || (int)irq <= 0) {
 		err = -ENODEV;
 		goto exit;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mx3_camera.c linux-libre-2.6.33-gnu1/drivers/media/video/mx3_camera.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mx3_camera.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mx3_camera.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-contig.h>
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 
 #include <mach/ipu.h>
 #include <mach/mx3_camera.h>
@@ -63,7 +64,7 @@
 struct mx3_camera_buffer {
 	/* common v4l buffer stuff -- must be first */
 	struct videobuf_buffer			vb;
-	const struct soc_camera_data_format	*fmt;
+	enum v4l2_mbus_pixelcode		code;
 
 	/* One descriptot per scatterlist (per frame) */
 	struct dma_async_tx_descriptor		*txd;
@@ -118,8 +119,6 @@ struct dma_chan_request {
 	enum ipu_channel	id;
 };
 
-static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt);
-
 static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
 {
 	return __raw_readl(mx3->base + reg);
@@ -211,17 +210,16 @@ static int mx3_videobuf_setup(struct vid
 	struct soc_camera_device *icd = vq->priv_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
-	/*
-	 * bits-per-pixel (depth) as specified in camera's pixel format does
-	 * not necessarily match what the camera interface writes to RAM, but
-	 * it should be good enough for now.
-	 */
-	unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8);
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+
+	if (bytes_per_line < 0)
+		return bytes_per_line;
 
 	if (!mx3_cam->idmac_channel[0])
 		return -EINVAL;
 
-	*size = icd->user_width * icd->user_height * bpp;
+	*size = bytes_per_line * icd->user_height;
 
 	if (!*count)
 		*count = 32;
@@ -241,21 +239,26 @@ static int mx3_videobuf_prepare(struct v
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct mx3_camera_buffer *buf =
 		container_of(vb, struct mx3_camera_buffer, vb);
-	/* current_fmt _must_ always be set */
-	size_t new_size = icd->user_width * icd->user_height *
-		((icd->current_fmt->depth + 7) >> 3);
+	size_t new_size;
 	int ret;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+
+	if (bytes_per_line < 0)
+		return bytes_per_line;
+
+	new_size = bytes_per_line * icd->user_height;
 
 	/*
 	 * I think, in buf_prepare you only have to protect global data,
 	 * the actual buffer is yours
 	 */
 
-	if (buf->fmt	!= icd->current_fmt ||
+	if (buf->code	!= icd->current_fmt->code ||
 	    vb->width	!= icd->user_width ||
 	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
-		buf->fmt	= icd->current_fmt;
+		buf->code	= icd->current_fmt->code;
 		vb->width	= icd->user_width;
 		vb->height	= icd->user_height;
 		vb->field	= field;
@@ -348,13 +351,13 @@ static void mx3_videobuf_queue(struct vi
 	struct dma_async_tx_descriptor *txd = buf->txd;
 	struct idmac_channel *ichan = to_idmac_chan(txd->chan);
 	struct idmac_video_param *video = &ichan->params.video;
-	const struct soc_camera_data_format *data_fmt = icd->current_fmt;
 	dma_cookie_t cookie;
+	u32 fourcc = icd->current_fmt->host_fmt->fourcc;
 
 	BUG_ON(!irqs_disabled());
 
 	/* This is the configuration of one sg-element */
-	video->out_pixel_fmt	= fourcc_to_ipu_pix(data_fmt->fourcc);
+	video->out_pixel_fmt	= fourcc_to_ipu_pix(fourcc);
 	video->out_width	= icd->user_width;
 	video->out_height	= icd->user_height;
 	video->out_stride	= icd->user_width;
@@ -564,30 +567,37 @@ static int test_platform_param(struct mx
 		SOCAM_DATA_ACTIVE_HIGH |
 		SOCAM_DATA_ACTIVE_LOW;
 
-	/* If requested data width is supported by the platform, use it or any
-	 * possible lower value - i.MX31 is smart enough to schift bits */
+	/*
+	 * If requested data width is supported by the platform, use it or any
+	 * possible lower value - i.MX31 is smart enough to schift bits
+	 */
+	if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
+		*flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
+			SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+	else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
+		*flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
+			SOCAM_DATAWIDTH_4;
+	else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
+		*flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+	else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
+		*flags |= SOCAM_DATAWIDTH_4;
+
 	switch (buswidth) {
 	case 15:
-		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15))
+		if (!(*flags & SOCAM_DATAWIDTH_15))
 			return -EINVAL;
-		*flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
-			SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
 		break;
 	case 10:
-		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10))
+		if (!(*flags & SOCAM_DATAWIDTH_10))
 			return -EINVAL;
-		*flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
-			SOCAM_DATAWIDTH_4;
 		break;
 	case 8:
-		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8))
+		if (!(*flags & SOCAM_DATAWIDTH_8))
 			return -EINVAL;
-		*flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
 		break;
 	case 4:
-		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4))
+		if (!(*flags & SOCAM_DATAWIDTH_4))
 			return -EINVAL;
-		*flags |= SOCAM_DATAWIDTH_4;
 		break;
 	default:
 		dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
@@ -636,91 +646,92 @@ static bool chan_filter(struct dma_chan
 		pdata->dma_dev == chan->device->dev;
 }
 
-static const struct soc_camera_data_format mx3_camera_formats[] = {
+static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
 	{
-		.name		= "Bayer (sRGB) 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_SBGGR8,
-		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.fourcc			= V4L2_PIX_FMT_SBGGR8,
+		.name			= "Bayer BGGR (sRGB) 8 bit",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
 	}, {
-		.name		= "Monochrome 8 bit",
-		.depth		= 8,
-		.fourcc		= V4L2_PIX_FMT_GREY,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fourcc			= V4L2_PIX_FMT_GREY,
+		.name			= "Monochrome 8 bit",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
 	},
 };
 
-static bool buswidth_supported(struct soc_camera_host *ici, int depth)
+/* This will be corrected as we get more formats */
+static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
 {
-	struct mx3_camera_dev *mx3_cam = ici->priv;
-
-	switch (depth) {
-	case 4:
-		return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4);
-	case 8:
-		return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8);
-	case 10:
-		return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10);
-	case 15:
-		return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15);
-	}
-	return false;
+	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
+		(fmt->bits_per_sample == 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
+		(fmt->bits_per_sample > 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 }
 
 static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
 				  struct soc_camera_format_xlate *xlate)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	int formats = 0, buswidth, ret;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->dev.parent;
+	int formats = 0, ret;
+	enum v4l2_mbus_pixelcode code;
+	const struct soc_mbus_pixelfmt *fmt;
 
-	buswidth = icd->formats[idx].depth;
+	ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+	if (ret < 0)
+		/* No more formats */
+		return 0;
 
-	if (!buswidth_supported(ici, buswidth))
+	fmt = soc_mbus_get_fmtdesc(code);
+	if (!fmt) {
+		dev_err(icd->dev.parent,
+			"Invalid format code #%d: %d\n", idx, code);
 		return 0;
+	}
 
-	ret = mx3_camera_try_bus_param(icd, buswidth);
+	/* This also checks support for the requested bits-per-sample */
+	ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
 	if (ret < 0)
 		return 0;
 
-	switch (icd->formats[idx].fourcc) {
-	case V4L2_PIX_FMT_SGRBG10:
+	switch (code) {
+	case V4L2_MBUS_FMT_SBGGR10_1X10:
 		formats++;
 		if (xlate) {
-			xlate->host_fmt = &mx3_camera_formats[0];
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = buswidth;
+			xlate->host_fmt	= &mx3_camera_formats[0];
+			xlate->code	= code;
 			xlate++;
-			dev_dbg(icd->dev.parent,
-				"Providing format %s using %s\n",
-				mx3_camera_formats[0].name,
-				icd->formats[idx].name);
+			dev_dbg(dev, "Providing format %s using code %d\n",
+				mx3_camera_formats[0].name, code);
 		}
-		goto passthrough;
-	case V4L2_PIX_FMT_Y16:
+		break;
+	case V4L2_MBUS_FMT_Y10_1X10:
 		formats++;
 		if (xlate) {
-			xlate->host_fmt = &mx3_camera_formats[1];
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = buswidth;
+			xlate->host_fmt	= &mx3_camera_formats[1];
+			xlate->code	= code;
 			xlate++;
-			dev_dbg(icd->dev.parent,
-				"Providing format %s using %s\n",
-				mx3_camera_formats[0].name,
-				icd->formats[idx].name);
+			dev_dbg(dev, "Providing format %s using code %d\n",
+				mx3_camera_formats[1].name, code);
 		}
+		break;
 	default:
-passthrough:
-		/* Generic pass-through */
-		formats++;
-		if (xlate) {
-			xlate->host_fmt = icd->formats + idx;
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = buswidth;
-			xlate++;
-			dev_dbg(icd->dev.parent,
-				"Providing format %s in pass-through mode\n",
-				icd->formats[idx].name);
-		}
+		if (!mx3_camera_packing_supported(fmt))
+			return 0;
+	}
+
+	/* Generic pass-through */
+	formats++;
+	if (xlate) {
+		xlate->host_fmt	= fmt;
+		xlate->code	= code;
+		xlate++;
+		dev_dbg(dev, "Providing format %x in pass-through mode\n",
+			xlate->host_fmt->fourcc);
 	}
 
 	return formats;
@@ -804,8 +815,7 @@ static int mx3_camera_set_crop(struct so
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
-	struct v4l2_pix_format *pix = &f.fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
@@ -816,19 +826,19 @@ static int mx3_camera_set_crop(struct so
 		return ret;
 
 	/* The capture device might have changed its output  */
-	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 	if (ret < 0)
 		return ret;
 
-	if (pix->width & 7) {
+	if (mf.width & 7) {
 		/* Ouch! We can only handle 8-byte aligned width... */
-		stride_align(&pix->width);
-		ret = v4l2_subdev_call(sd, video, s_fmt, &f);
+		stride_align(&mf.width);
+		ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
 		if (ret < 0)
 			return ret;
 	}
 
-	if (pix->width != icd->user_width || pix->height != icd->user_height) {
+	if (mf.width != icd->user_width || mf.height != icd->user_height) {
 		/*
 		 * We now know pixel formats and can decide upon DMA-channel(s)
 		 * So far only direct camera-to-memory is supported
@@ -839,14 +849,14 @@ static int mx3_camera_set_crop(struct so
 				return ret;
 		}
 
-		configure_geometry(mx3_cam, pix->width, pix->height);
+		configure_geometry(mx3_cam, mf.width, mf.height);
 	}
 
 	dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
-		pix->width, pix->height);
+		mf.width, mf.height);
 
-	icd->user_width = pix->width;
-	icd->user_height = pix->height;
+	icd->user_width		= mf.width;
+	icd->user_height	= mf.height;
 
 	return ret;
 }
@@ -859,6 +869,7 @@ static int mx3_camera_set_fmt(struct soc
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -883,11 +894,24 @@ static int mx3_camera_set_fmt(struct soc
 
 	configure_geometry(mx3_cam, pix->width, pix->height);
 
-	ret = v4l2_subdev_call(sd, video, s_fmt, f);
-	if (!ret) {
-		icd->buswidth = xlate->buswidth;
-		icd->current_fmt = xlate->host_fmt;
-	}
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
+
+	ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+	if (ret < 0)
+		return ret;
+
+	if (mf.code != xlate->code)
+		return -EINVAL;
+
+	pix->width		= mf.width;
+	pix->height		= mf.height;
+	pix->field		= mf.field;
+	pix->colorspace		= mf.colorspace;
+	icd->current_fmt	= xlate;
 
 	dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
 
@@ -900,8 +924,8 @@ static int mx3_camera_try_fmt(struct soc
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	__u32 pixfmt = pix->pixelformat;
-	enum v4l2_field field;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
@@ -916,23 +940,37 @@ static int mx3_camera_try_fmt(struct soc
 	if (pix->width > 4096)
 		pix->width = 4096;
 
-	pix->bytesperline = pix->width *
-		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+	pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
+						    xlate->host_fmt);
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
 	pix->sizeimage = pix->height * pix->bytesperline;
 
-	/* camera has to see its format, but the user the original one */
-	pix->pixelformat = xlate->cam_fmt->fourcc;
 	/* limit to sensor capabilities */
-	ret = v4l2_subdev_call(sd, video, try_fmt, f);
-	pix->pixelformat = xlate->host_fmt->fourcc;
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
 
-	field = pix->field;
+	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+	if (ret < 0)
+		return ret;
 
-	if (field == V4L2_FIELD_ANY) {
+	pix->width	= mf.width;
+	pix->height	= mf.height;
+	pix->colorspace	= mf.colorspace;
+
+	switch (mf.field) {
+	case V4L2_FIELD_ANY:
 		pix->field = V4L2_FIELD_NONE;
-	} else if (field != V4L2_FIELD_NONE) {
-		dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
-		return -EINVAL;
+		break;
+	case V4L2_FIELD_NONE:
+		break;
+	default:
+		dev_err(icd->dev.parent, "Field type %d unsupported.\n",
+			mf.field);
+		ret = -EINVAL;
 	}
 
 	return ret;
@@ -968,18 +1006,26 @@ static int mx3_camera_set_bus_param(stru
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	unsigned long bus_flags, camera_flags, common_flags;
 	u32 dw, sens_conf;
-	int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
+	const struct soc_mbus_pixelfmt *fmt;
+	int buswidth;
+	int ret;
 	const struct soc_camera_format_xlate *xlate;
 	struct device *dev = icd->dev.parent;
 
+	fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
+	if (!fmt)
+		return -EINVAL;
+
+	buswidth = fmt->bits_per_sample;
+	ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
+
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
 		dev_warn(dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
-	dev_dbg(dev, "requested bus width %d bit: %d\n",
-		icd->buswidth, ret);
+	dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
 
 	if (ret < 0)
 		return ret;
@@ -1027,8 +1073,10 @@ static int mx3_camera_set_bus_param(stru
 			common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
 	}
 
-	/* Make the camera work in widest common mode, we'll take care of
-	 * the rest */
+	/*
+	 * Make the camera work in widest common mode, we'll take care of
+	 * the rest
+	 */
 	if (common_flags & SOCAM_DATAWIDTH_15)
 		common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
 			SOCAM_DATAWIDTH_15;
@@ -1078,7 +1126,7 @@ static int mx3_camera_set_bus_param(stru
 		sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
 
 	/* Just do what we're asked to do */
-	switch (xlate->host_fmt->depth) {
+	switch (xlate->host_fmt->bits_per_sample) {
 	case 4:
 		dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
 		break;
@@ -1152,8 +1200,10 @@ static int __devinit mx3_camera_probe(st
 	if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
 			MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
 			MX3_CAMERA_DATAWIDTH_15))) {
-		/* Platform hasn't set available data widths. This is bad.
-		 * Warn and use a default. */
+		/*
+		 * Platform hasn't set available data widths. This is bad.
+		 * Warn and use a default.
+		 */
 		dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
 			 "data widths, using default 8 bit\n");
 		mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/mxb.c linux-libre-2.6.33-gnu1/drivers/media/video/mxb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/mxb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/mxb.c	2010-02-24 13:52:17.000000000 -0500
@@ -478,7 +478,7 @@ static int vidioc_s_input(struct file *f
 
 	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
 
-	if (input < 0 || input >= MXB_INPUTS)
+	if (input >= MXB_INPUTS)
 		return -EINVAL;
 
 	mxb->cur_input = input;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/omap24xxcam.c linux-libre-2.6.33-gnu1/drivers/media/video/omap24xxcam.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/omap24xxcam.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/omap24xxcam.c	2010-02-24 13:52:17.000000000 -0500
@@ -1450,12 +1450,11 @@ static int omap24xxcam_mmap(struct file
 
 static int omap24xxcam_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
 	struct omap24xxcam_device *cam = omap24xxcam.priv;
 	struct omap24xxcam_fh *fh;
 	struct v4l2_format format;
 
-	if (!cam || !cam->vfd || (cam->vfd->minor != minor))
+	if (!cam || !cam->vfd)
 		return -ENODEV;
 
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -1660,7 +1659,6 @@ static int omap24xxcam_device_register(s
 
 	strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
 	vfd->fops		 = &omap24xxcam_fops;
-	vfd->minor		 = -1;
 	vfd->ioctl_ops		 = &omap24xxcam_ioctl_fops;
 
 	omap24xxcam_hwinit(cam);
@@ -1671,14 +1669,14 @@ static int omap24xxcam_device_register(s
 
 	if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
 		dev_err(cam->dev, "could not register V4L device\n");
-		vfd->minor = -1;
 		rval = -EBUSY;
 		goto err;
 	}
 
 	omap24xxcam_poweron_reset(cam);
 
-	dev_info(cam->dev, "registered device video%d\n", vfd->minor);
+	dev_info(cam->dev, "registered device %s\n",
+		 video_device_node_name(vfd));
 
 	return 0;
 
@@ -1695,7 +1693,7 @@ static void omap24xxcam_device_unregiste
 	omap24xxcam_sensor_exit(cam);
 
 	if (cam->vfd) {
-		if (cam->vfd->minor == -1) {
+		if (!video_is_registered(cam->vfd)) {
 			/*
 			 * The device was never registered, so release the
 			 * video_device struct directly.
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ov511.c linux-libre-2.6.33-gnu1/drivers/media/video/ov511.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ov511.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ov511.c	2010-02-24 13:52:17.000000000 -0500
@@ -4674,7 +4674,6 @@ static struct video_device vdev_template
 	.name =		"OV511 USB Camera",
 	.fops =		&ov511_fops,
 	.release =	video_device_release,
-	.minor =	-1,
 };
 
 /****************************************************************************
@@ -5867,8 +5866,8 @@ ov51x_probe(struct usb_interface *intf,
 	ov511_devused |= 1 << nr;
 	ov->nr = nr;
 
-	dev_info(&intf->dev, "Device at %s registered to minor %d\n",
-		 ov->usb_path, ov->vdev->minor);
+	dev_info(&intf->dev, "Device at %s registered to %s\n",
+		 ov->usb_path, video_device_node_name(ov->vdev));
 
 	usb_set_intfdata(intf, ov);
 	if (ov_create_sysfs(ov->vdev)) {
@@ -5878,13 +5877,13 @@ ov51x_probe(struct usb_interface *intf,
 		goto error;
 	}
 
-	mutex_lock(&ov->lock);
+	mutex_unlock(&ov->lock);
 
 	return 0;
 
 error:
 	if (ov->vdev) {
-		if (-1 == ov->vdev->minor)
+		if (!video_is_registered(ov->vdev))
 			video_device_release(ov->vdev);
 		else
 			video_unregister_device(ov->vdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ov772x.c linux-libre-2.6.33-gnu1/drivers/media/video/ov772x.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ov772x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ov772x.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,7 @@
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 #include <media/ov772x.h>
 
 /*
@@ -247,7 +248,7 @@
 
 /* COM5 */
 #define AFR_ON_OFF      0x80	/* Auto frame rate control ON/OFF selection */
-#define AFR_SPPED       0x40	/* Auto frame rate control speed slection */
+#define AFR_SPPED       0x40	/* Auto frame rate control speed selection */
 				/* Auto frame rate max rate control */
 #define AFR_NO_RATE     0x00	/*     No  reduction of frame rate */
 #define AFR_1p2         0x10	/*     Max reduction to 1/2 frame rate */
@@ -382,7 +383,8 @@ struct regval_list {
 };
 
 struct ov772x_color_format {
-	const struct soc_camera_data_format *format;
+	enum v4l2_mbus_pixelcode code;
+	enum v4l2_colorspace colorspace;
 	u8 dsp3;
 	u8 com3;
 	u8 com7;
@@ -399,7 +401,7 @@ struct ov772x_win_size {
 struct ov772x_priv {
 	struct v4l2_subdev                subdev;
 	struct ov772x_camera_info        *info;
-	const struct ov772x_color_format *fmt;
+	const struct ov772x_color_format *cfmt;
 	const struct ov772x_win_size     *win;
 	int                               model;
 	unsigned short                    flag_vflip:1;
@@ -434,93 +436,57 @@ static const struct regval_list ov772x_v
 };
 
 /*
- * supported format list
- */
-
-#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type)
-static const struct soc_camera_data_format ov772x_fmt_lists[] = {
-	{
-		SETFOURCC(YUYV),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-	},
-	{
-		SETFOURCC(YVYU),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-	},
-	{
-		SETFOURCC(UYVY),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_JPEG,
-	},
-	{
-		SETFOURCC(RGB555),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-	},
-	{
-		SETFOURCC(RGB555X),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-	},
-	{
-		SETFOURCC(RGB565),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-	},
-	{
-		SETFOURCC(RGB565X),
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-	},
-};
-
-/*
- * color format list
+ * supported color format list
  */
 static const struct ov772x_color_format ov772x_cfmts[] = {
 	{
-		.format = &ov772x_fmt_lists[0],
-		.dsp3   = 0x0,
-		.com3   = SWAP_YUV,
-		.com7   = OFMT_YUV,
+		.code		= V4L2_MBUS_FMT_YUYV8_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.dsp3		= 0x0,
+		.com3		= SWAP_YUV,
+		.com7		= OFMT_YUV,
 	},
 	{
-		.format = &ov772x_fmt_lists[1],
-		.dsp3   = UV_ON,
-		.com3   = SWAP_YUV,
-		.com7   = OFMT_YUV,
+		.code		= V4L2_MBUS_FMT_YVYU8_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.dsp3		= UV_ON,
+		.com3		= SWAP_YUV,
+		.com7		= OFMT_YUV,
 	},
 	{
-		.format = &ov772x_fmt_lists[2],
-		.dsp3   = 0x0,
-		.com3   = 0x0,
-		.com7   = OFMT_YUV,
+		.code		= V4L2_MBUS_FMT_YUYV8_2X8_BE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.dsp3		= 0x0,
+		.com3		= 0x0,
+		.com7		= OFMT_YUV,
 	},
 	{
-		.format = &ov772x_fmt_lists[3],
-		.dsp3   = 0x0,
-		.com3   = SWAP_RGB,
-		.com7   = FMT_RGB555 | OFMT_RGB,
+		.code		= V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.dsp3		= 0x0,
+		.com3		= SWAP_RGB,
+		.com7		= FMT_RGB555 | OFMT_RGB,
 	},
 	{
-		.format = &ov772x_fmt_lists[4],
-		.dsp3   = 0x0,
-		.com3   = 0x0,
-		.com7   = FMT_RGB555 | OFMT_RGB,
+		.code		= V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.dsp3		= 0x0,
+		.com3		= 0x0,
+		.com7		= FMT_RGB555 | OFMT_RGB,
 	},
 	{
-		.format = &ov772x_fmt_lists[5],
-		.dsp3   = 0x0,
-		.com3   = SWAP_RGB,
-		.com7   = FMT_RGB565 | OFMT_RGB,
+		.code		= V4L2_MBUS_FMT_RGB565_2X8_LE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.dsp3		= 0x0,
+		.com3		= SWAP_RGB,
+		.com7		= FMT_RGB565 | OFMT_RGB,
 	},
 	{
-		.format = &ov772x_fmt_lists[6],
-		.dsp3   = 0x0,
-		.com3   = 0x0,
-		.com7   = FMT_RGB565 | OFMT_RGB,
+		.code		= V4L2_MBUS_FMT_RGB565_2X8_BE,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+		.dsp3		= 0x0,
+		.com3		= 0x0,
+		.com7		= FMT_RGB565 | OFMT_RGB,
 	},
 };
 
@@ -642,15 +608,15 @@ static int ov772x_s_stream(struct v4l2_s
 		return 0;
 	}
 
-	if (!priv->win || !priv->fmt) {
+	if (!priv->win || !priv->cfmt) {
 		dev_err(&client->dev, "norm or win select error\n");
 		return -EPERM;
 	}
 
 	ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
 
-	dev_dbg(&client->dev, "format %s, win %s\n",
-		priv->fmt->format->name, priv->win->name);
+	dev_dbg(&client->dev, "format %d, win %s\n",
+		priv->cfmt->code, priv->win->name);
 
 	return 0;
 }
@@ -806,8 +772,8 @@ static const struct ov772x_win_size *ov7
 	return win;
 }
 
-static int ov772x_set_params(struct i2c_client *client,
-			     u32 *width, u32 *height, u32 pixfmt)
+static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
+			     enum v4l2_mbus_pixelcode code)
 {
 	struct ov772x_priv *priv = to_ov772x(client);
 	int ret = -EINVAL;
@@ -817,14 +783,14 @@ static int ov772x_set_params(struct i2c_
 	/*
 	 * select format
 	 */
-	priv->fmt = NULL;
+	priv->cfmt = NULL;
 	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
-		if (pixfmt == ov772x_cfmts[i].format->fourcc) {
-			priv->fmt = ov772x_cfmts + i;
+		if (code == ov772x_cfmts[i].code) {
+			priv->cfmt = ov772x_cfmts + i;
 			break;
 		}
 	}
-	if (!priv->fmt)
+	if (!priv->cfmt)
 		goto ov772x_set_fmt_error;
 
 	/*
@@ -894,7 +860,7 @@ static int ov772x_set_params(struct i2c_
 	/*
 	 * set DSP_CTRL3
 	 */
-	val = priv->fmt->dsp3;
+	val = priv->cfmt->dsp3;
 	if (val) {
 		ret = ov772x_mask_set(client,
 				      DSP_CTRL3, UV_MASK, val);
@@ -905,7 +871,7 @@ static int ov772x_set_params(struct i2c_
 	/*
 	 * set COM3
 	 */
-	val = priv->fmt->com3;
+	val = priv->cfmt->com3;
 	if (priv->info->flags & OV772X_FLAG_VFLIP)
 		val |= VFLIP_IMG;
 	if (priv->info->flags & OV772X_FLAG_HFLIP)
@@ -923,9 +889,9 @@ static int ov772x_set_params(struct i2c_
 	/*
 	 * set COM7
 	 */
-	val = priv->win->com7_bit | priv->fmt->com7;
+	val = priv->win->com7_bit | priv->cfmt->com7;
 	ret = ov772x_mask_set(client,
-			      COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
+			      COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
 			      val);
 	if (ret < 0)
 		goto ov772x_set_fmt_error;
@@ -951,7 +917,7 @@ ov772x_set_fmt_error:
 
 	ov772x_reset(client);
 	priv->win = NULL;
-	priv->fmt = NULL;
+	priv->cfmt = NULL;
 
 	return ret;
 }
@@ -981,54 +947,79 @@ static int ov772x_cropcap(struct v4l2_su
 	return 0;
 }
 
-static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int ov772x_g_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct ov772x_priv *priv = to_ov772x(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (!priv->win || !priv->fmt) {
+	if (!priv->win || !priv->cfmt) {
 		u32 width = VGA_WIDTH, height = VGA_HEIGHT;
 		int ret = ov772x_set_params(client, &width, &height,
-					    V4L2_PIX_FMT_YUYV);
+					    V4L2_MBUS_FMT_YUYV8_2X8_LE);
 		if (ret < 0)
 			return ret;
 	}
 
-	f->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	pix->width		= priv->win->width;
-	pix->height		= priv->win->height;
-	pix->pixelformat	= priv->fmt->format->fourcc;
-	pix->colorspace		= priv->fmt->format->colorspace;
-	pix->field		= V4L2_FIELD_NONE;
+	mf->width	= priv->win->width;
+	mf->height	= priv->win->height;
+	mf->code	= priv->cfmt->code;
+	mf->colorspace	= priv->cfmt->colorspace;
+	mf->field	= V4L2_FIELD_NONE;
 
 	return 0;
 }
 
-static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int ov772x_s_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct ov772x_priv *priv = to_ov772x(client);
+	int ret = ov772x_set_params(client, &mf->width, &mf->height,
+				    mf->code);
 
-	return ov772x_set_params(client, &pix->width, &pix->height,
-				 pix->pixelformat);
+	if (!ret)
+		mf->colorspace = priv->cfmt->colorspace;
+
+	return ret;
 }
 
 static int ov772x_try_fmt(struct v4l2_subdev *sd,
-			  struct v4l2_format *f)
+			  struct v4l2_mbus_framefmt *mf)
 {
-	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
 	const struct ov772x_win_size *win;
+	int i;
 
 	/*
 	 * select suitable win
 	 */
-	win = ov772x_select_win(pix->width, pix->height);
+	win = ov772x_select_win(mf->width, mf->height);
 
-	pix->width  = win->width;
-	pix->height = win->height;
-	pix->field  = V4L2_FIELD_NONE;
+	mf->width	= win->width;
+	mf->height	= win->height;
+	mf->field	= V4L2_FIELD_NONE;
+
+	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++)
+		if (mf->code == ov772x_cfmts[i].code)
+			break;
+
+	if (i == ARRAY_SIZE(ov772x_cfmts)) {
+		/* Unsupported format requested. Propose either */
+		if (priv->cfmt) {
+			/* the current one or */
+			mf->colorspace = priv->cfmt->colorspace;
+			mf->code = priv->cfmt->code;
+		} else {
+			/* the default one */
+			mf->colorspace = ov772x_cfmts[0].colorspace;
+			mf->code = ov772x_cfmts[0].code;
+		}
+	} else {
+		/* Also return the colorspace */
+		mf->colorspace	= ov772x_cfmts[i].colorspace;
+	}
 
 	return 0;
 }
@@ -1057,9 +1048,6 @@ static int ov772x_video_probe(struct soc
 		return -ENODEV;
 	}
 
-	icd->formats     = ov772x_fmt_lists;
-	icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
-
 	/*
 	 * check and show product ID and manufacturer ID
 	 */
@@ -1109,13 +1097,24 @@ static struct v4l2_subdev_core_ops ov772
 #endif
 };
 
+static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts))
+		return -EINVAL;
+
+	*code = ov772x_cfmts[index].code;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
 	.s_stream	= ov772x_s_stream,
-	.g_fmt		= ov772x_g_fmt,
-	.s_fmt		= ov772x_s_fmt,
-	.try_fmt	= ov772x_try_fmt,
+	.g_mbus_fmt	= ov772x_g_fmt,
+	.s_mbus_fmt	= ov772x_s_fmt,
+	.try_mbus_fmt	= ov772x_try_fmt,
 	.cropcap	= ov772x_cropcap,
 	.g_crop		= ov772x_g_crop,
+	.enum_mbus_fmt	= ov772x_enum_fmt,
 };
 
 static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1143,10 +1142,10 @@ static int ov772x_probe(struct i2c_clien
 	}
 
 	icl = to_soc_camera_link(icd);
-	if (!icl)
+	if (!icl || !icl->priv)
 		return -EINVAL;
 
-	info = container_of(icl, struct ov772x_camera_info, link);
+	info = icl->priv;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&adapter->dev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ov9640.c linux-libre-2.6.33-gnu1/drivers/media/video/ov9640.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/ov9640.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ov9640.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,832 @@
+/*
+ * OmniVision OV96xx Camera Driver
+ *
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on ov772x camera driver:
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.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/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+#include <media/soc_camera.h>
+
+#include "ov9640.h"
+
+/* default register setup */
+static const struct ov9640_reg ov9640_regs_dflt[] = {
+	{ OV9640_COM5,	OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
+	{ OV9640_COM6,	OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
+			OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
+	{ OV9640_PSHFT,	OV9640_PSHFT_VAL(0x01) },
+	{ OV9640_ACOM,	OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
+	{ OV9640_TSLB,	OV9640_TSLB_YUYV_UYVY },
+	{ OV9640_COM16,	OV9640_COM16_RB_AVG },
+
+	/* Gamma curve P */
+	{ 0x6c, 0x40 },	{ 0x6d, 0x30 },	{ 0x6e, 0x4b },	{ 0x6f, 0x60 },
+	{ 0x70, 0x70 },	{ 0x71, 0x70 },	{ 0x72, 0x70 },	{ 0x73, 0x70 },
+	{ 0x74, 0x60 },	{ 0x75, 0x60 },	{ 0x76, 0x50 },	{ 0x77, 0x48 },
+	{ 0x78, 0x3a },	{ 0x79, 0x2e },	{ 0x7a, 0x28 },	{ 0x7b, 0x22 },
+
+	/* Gamma curve T */
+	{ 0x7c, 0x04 },	{ 0x7d, 0x07 },	{ 0x7e, 0x10 },	{ 0x7f, 0x28 },
+	{ 0x80, 0x36 },	{ 0x81, 0x44 },	{ 0x82, 0x52 },	{ 0x83, 0x60 },
+	{ 0x84, 0x6c },	{ 0x85, 0x78 },	{ 0x86, 0x8c },	{ 0x87, 0x9e },
+	{ 0x88, 0xbb },	{ 0x89, 0xd2 },	{ 0x8a, 0xe6 },
+};
+
+/* Configurations
+ * NOTE: for YUV, alter the following registers:
+ * 		COM12 |= OV9640_COM12_YUV_AVG
+ *
+ *	 for RGB, alter the following registers:
+ *	 	COM7  |= OV9640_COM7_RGB
+ *	 	COM13 |= OV9640_COM13_RGB_AVG
+ *	 	COM15 |= proper RGB color encoding mode
+ */
+static const struct ov9640_reg ov9640_regs_qqcif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
+	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QCIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qqvga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QVGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qcif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QCIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qvga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+	{ OV9640_COM7,	OV9640_COM7_QVGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_cif[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	OV9640_COM7_CIF },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_vga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	OV9640_COM7_VGA },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_sxga[] = {
+	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+	{ OV9640_COM3,	OV9640_COM3_VP },
+	{ OV9640_COM7,	0 },
+	{ OV9640_COM12,	OV9640_COM12_RSVD },
+	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_yuv[] = {
+	{ OV9640_MTX1,	0x58 },
+	{ OV9640_MTX2,	0x48 },
+	{ OV9640_MTX3,	0x10 },
+	{ OV9640_MTX4,	0x28 },
+	{ OV9640_MTX5,	0x48 },
+	{ OV9640_MTX6,	0x70 },
+	{ OV9640_MTX7,	0x40 },
+	{ OV9640_MTX8,	0x40 },
+	{ OV9640_MTX9,	0x40 },
+	{ OV9640_MTXS,	0x0f },
+};
+
+static const struct ov9640_reg ov9640_regs_rgb[] = {
+	{ OV9640_MTX1,	0x71 },
+	{ OV9640_MTX2,	0x3e },
+	{ OV9640_MTX3,	0x0c },
+	{ OV9640_MTX4,	0x33 },
+	{ OV9640_MTX5,	0x72 },
+	{ OV9640_MTX6,	0x00 },
+	{ OV9640_MTX7,	0x2b },
+	{ OV9640_MTX8,	0x66 },
+	{ OV9640_MTX9,	0xd2 },
+	{ OV9640_MTXS,	0x65 },
+};
+
+static enum v4l2_mbus_pixelcode ov9640_codes[] = {
+	V4L2_MBUS_FMT_YUYV8_2X8_BE,
+	V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
+	V4L2_MBUS_FMT_RGB565_2X8_LE,
+};
+
+static const struct v4l2_queryctrl ov9640_controls[] = {
+	{
+		.id		= V4L2_CID_VFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Vertically",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+	{
+		.id		= V4L2_CID_HFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Horizontally",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+};
+
+/* read a register */
+static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+	int ret;
+	u8 data = reg;
+	struct i2c_msg msg = {
+		.addr	= client->addr,
+		.flags	= 0,
+		.len	= 1,
+		.buf	= &data,
+	};
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		goto err;
+
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0)
+		goto err;
+
+	*val = data;
+	return 0;
+
+err:
+	dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
+	return ret;
+}
+
+/* write a register */
+static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret;
+	u8 _val;
+	unsigned char data[2] = { reg, val };
+	struct i2c_msg msg = {
+		.addr	= client->addr,
+		.flags	= 0,
+		.len	= 2,
+		.buf	= data,
+	};
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
+		return ret;
+	}
+
+	/* we have to read the register back ... no idea why, maybe HW bug */
+	ret = ov9640_reg_read(client, reg, &_val);
+	if (ret)
+		dev_err(&client->dev,
+			"Failed reading back register 0x%02x!\n", reg);
+
+	return 0;
+}
+
+
+/* Read a register, alter its bits, write it back */
+static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
+{
+	u8 val;
+	int ret;
+
+	ret = ov9640_reg_read(client, reg, &val);
+	if (ret) {
+		dev_err(&client->dev,
+			"[Read]-Modify-Write of register %02x failed!\n", reg);
+		return val;
+	}
+
+	val |= set;
+	val &= ~unset;
+
+	ret = ov9640_reg_write(client, reg, val);
+	if (ret)
+		dev_err(&client->dev,
+			"Read-Modify-[Write] of register %02x failed!\n", reg);
+
+	return ret;
+}
+
+/* Soft reset the camera. This has nothing to do with the RESET pin! */
+static int ov9640_reset(struct i2c_client *client)
+{
+	int ret;
+
+	ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
+	if (ret)
+		dev_err(&client->dev,
+			"An error occured while entering soft reset!\n");
+
+	return ret;
+}
+
+/* Start/Stop streaming from the device */
+static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	return 0;
+}
+
+/* Alter bus settings on camera side */
+static int ov9640_set_bus_param(struct soc_camera_device *icd,
+				unsigned long flags)
+{
+	return 0;
+}
+
+/* Request bus settings on camera side */
+static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
+{
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+
+	/*
+	 * REVISIT: the camera probably can do 10 bit transfers, but I don't
+	 *          have those pins connected on my hardware.
+	 */
+	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
+		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
+		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
+
+	return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+/* Get status of additional camera capabilities */
+static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		ctrl->value = priv->flag_vflip;
+		break;
+	case V4L2_CID_HFLIP:
+		ctrl->value = priv->flag_hflip;
+		break;
+	}
+	return 0;
+}
+
+/* Set status of additional camera capabilities */
+static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		priv->flag_vflip = ctrl->value;
+		if (ctrl->value)
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							OV9640_MVFP_V, 0);
+		else
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							0, OV9640_MVFP_V);
+		break;
+	case V4L2_CID_HFLIP:
+		priv->flag_hflip = ctrl->value;
+		if (ctrl->value)
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							OV9640_MVFP_H, 0);
+		else
+			ret = ov9640_reg_rmw(client, OV9640_MVFP,
+							0, OV9640_MVFP_H);
+		break;
+	}
+
+	return ret;
+}
+
+/* Get chip identification */
+static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
+					struct ov9640_priv, subdev);
+
+	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)
+{
+	struct i2c_client *client = sd->priv;
+	int ret;
+	u8 val;
+
+	if (reg->reg & ~0xff)
+		return -EINVAL;
+
+	reg->size = 1;
+
+	ret = ov9640_reg_read(client, reg->reg, &val);
+	if (ret)
+		return ret;
+
+	reg->val = (__u64)val;
+
+	return 0;
+}
+
+static int ov9640_set_register(struct v4l2_subdev *sd,
+				struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (reg->reg & ~0xff || reg->val & ~0xff)
+		return -EINVAL;
+
+	return ov9640_reg_write(client, reg->reg, reg->val);
+}
+#endif
+
+/* select nearest higher resolution for capture */
+static void ov9640_res_roundup(u32 *width, u32 *height)
+{
+	int i;
+	enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
+	int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
+	int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
+
+	for (i = 0; i < ARRAY_SIZE(res_x); i++) {
+		if (res_x[i] >= *width && res_y[i] >= *height) {
+			*width = res_x[i];
+			*height = res_y[i];
+			return;
+		}
+	}
+
+	*width = res_x[SXGA];
+	*height = res_y[SXGA];
+}
+
+/* Prepare necessary register changes depending on color encoding */
+static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code,
+			      struct ov9640_reg_alt *alt)
+{
+	switch (code) {
+	default:
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+		alt->com12	= OV9640_COM12_YUV_AVG;
+		alt->com13	= OV9640_COM13_Y_DELAY_EN |
+					OV9640_COM13_YUV_DLY(0x01);
+		break;
+	case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+		alt->com7	= OV9640_COM7_RGB;
+		alt->com13	= OV9640_COM13_RGB_AVG;
+		alt->com15	= OV9640_COM15_RGB_555;
+		break;
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
+		alt->com7	= OV9640_COM7_RGB;
+		alt->com13	= OV9640_COM13_RGB_AVG;
+		alt->com15	= OV9640_COM15_RGB_565;
+		break;
+	};
+}
+
+/* Setup registers according to resolution and color encoding */
+static int ov9640_write_regs(struct i2c_client *client, u32 width,
+		enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts)
+{
+	const struct ov9640_reg	*ov9640_regs, *matrix_regs;
+	int			ov9640_regs_len, matrix_regs_len;
+	int			i, ret;
+	u8			val;
+
+	/* select register configuration for given resolution */
+	switch (width) {
+	case W_QQCIF:
+		ov9640_regs	= ov9640_regs_qqcif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqcif);
+		break;
+	case W_QQVGA:
+		ov9640_regs	= ov9640_regs_qqvga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqvga);
+		break;
+	case W_QCIF:
+		ov9640_regs	= ov9640_regs_qcif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qcif);
+		break;
+	case W_QVGA:
+		ov9640_regs	= ov9640_regs_qvga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qvga);
+		break;
+	case W_CIF:
+		ov9640_regs	= ov9640_regs_cif;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_cif);
+		break;
+	case W_VGA:
+		ov9640_regs	= ov9640_regs_vga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_vga);
+		break;
+	case W_SXGA:
+		ov9640_regs	= ov9640_regs_sxga;
+		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_sxga);
+		break;
+	default:
+		dev_err(&client->dev, "Failed to select resolution!\n");
+		return -EINVAL;
+	}
+
+	/* select color matrix configuration for given color encoding */
+	if (code == V4L2_MBUS_FMT_YUYV8_2X8_BE) {
+		matrix_regs	= ov9640_regs_yuv;
+		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_yuv);
+	} else {
+		matrix_regs	= ov9640_regs_rgb;
+		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_rgb);
+	}
+
+	/* write register settings into the module */
+	for (i = 0; i < ov9640_regs_len; i++) {
+		val = ov9640_regs[i].val;
+
+		switch (ov9640_regs[i].reg) {
+		case OV9640_COM7:
+			val |= alts->com7;
+			break;
+		case OV9640_COM12:
+			val |= alts->com12;
+			break;
+		case OV9640_COM13:
+			val |= alts->com13;
+			break;
+		case OV9640_COM15:
+			val |= alts->com15;
+			break;
+		}
+
+		ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
+		if (ret)
+			return ret;
+	}
+
+	/* write color matrix configuration into the module */
+	for (i = 0; i < matrix_regs_len; i++) {
+		ret = ov9640_reg_write(client, matrix_regs[i].reg,
+						matrix_regs[i].val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* program default register values */
+static int ov9640_prog_dflt(struct i2c_client *client)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
+		ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
+						ov9640_regs_dflt[i].val);
+		if (ret)
+			return ret;
+	}
+
+	/* wait for the changes to actually happen, 140ms are not enough yet */
+	mdelay(150);
+
+	return 0;
+}
+
+/* set the format we will capture in */
+static int ov9640_s_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov9640_reg_alt alts = {0};
+	enum v4l2_colorspace cspace;
+	enum v4l2_mbus_pixelcode code = mf->code;
+	int ret;
+
+	ov9640_res_roundup(&mf->width, &mf->height);
+	ov9640_alter_regs(mf->code, &alts);
+
+	ov9640_reset(client);
+
+	ret = ov9640_prog_dflt(client);
+	if (ret)
+		return ret;
+
+	switch (code) {
+	case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
+		cspace = V4L2_COLORSPACE_SRGB;
+		break;
+	default:
+		code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+		cspace = V4L2_COLORSPACE_JPEG;
+	}
+
+	ret = ov9640_write_regs(client, mf->width, code, &alts);
+	if (!ret) {
+		mf->code	= code;
+		mf->colorspace	= cspace;
+	}
+
+	return ret;
+}
+
+static int ov9640_try_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_mbus_framefmt *mf)
+{
+	ov9640_res_roundup(&mf->width, &mf->height);
+
+	mf->field = V4L2_FIELD_NONE;
+
+	switch (mf->code) {
+	case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
+		mf->colorspace = V4L2_COLORSPACE_SRGB;
+		break;
+	default:
+		mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+		mf->colorspace = V4L2_COLORSPACE_JPEG;
+	}
+
+	return 0;
+}
+
+static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes))
+		return -EINVAL;
+
+	*code = ov9640_codes[index];
+	return 0;
+}
+
+static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	a->c.left	= 0;
+	a->c.top	= 0;
+	a->c.width	= W_SXGA;
+	a->c.height	= H_SXGA;
+	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= 0;
+	a->bounds.top			= 0;
+	a->bounds.width			= W_SXGA;
+	a->bounds.height		= H_SXGA;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+
+
+static int ov9640_video_probe(struct soc_camera_device *icd,
+				struct i2c_client *client)
+{
+	struct ov9640_priv *priv = i2c_get_clientdata(client);
+	u8		pid, ver, midh, midl;
+	const char	*devname;
+	int		ret = 0;
+
+	/*
+	 * We must have a parent by now. And it cannot be a wrong one.
+	 * So this entire test is completely redundant.
+	 */
+	if (!icd->dev.parent ||
+	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
+		dev_err(&client->dev, "Parent missing or invalid!\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	/*
+	 * check and show product ID and manufacturer ID
+	 */
+
+	ret = ov9640_reg_read(client, OV9640_PID, &pid);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_VER, &ver);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
+	if (ret)
+		goto err;
+
+	ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
+	if (ret)
+		goto err;
+
+	switch (VERSION(pid, ver)) {
+	case OV9640_V2:
+		devname		= "ov9640";
+		priv->model	= V4L2_IDENT_OV9640;
+		priv->revision	= 2;
+	case OV9640_V3:
+		devname		= "ov9640";
+		priv->model	= V4L2_IDENT_OV9640;
+		priv->revision	= 3;
+		break;
+	default:
+		dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+		 devname, pid, ver, midh, midl);
+
+err:
+	return ret;
+}
+
+static struct soc_camera_ops ov9640_ops = {
+	.set_bus_param		= ov9640_set_bus_param,
+	.query_bus_param	= ov9640_query_bus_param,
+	.controls		= ov9640_controls,
+	.num_controls		= ARRAY_SIZE(ov9640_controls),
+};
+
+static struct v4l2_subdev_core_ops ov9640_core_ops = {
+	.g_ctrl			= ov9640_g_ctrl,
+	.s_ctrl			= ov9640_s_ctrl,
+	.g_chip_ident		= ov9640_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register		= ov9640_get_register,
+	.s_register		= ov9640_set_register,
+#endif
+
+};
+
+static struct v4l2_subdev_video_ops ov9640_video_ops = {
+	.s_stream	= ov9640_s_stream,
+	.s_mbus_fmt	= ov9640_s_fmt,
+	.try_mbus_fmt	= ov9640_try_fmt,
+	.enum_mbus_fmt	= ov9640_enum_fmt,
+	.cropcap	= ov9640_cropcap,
+	.g_crop		= ov9640_g_crop,
+
+};
+
+static struct v4l2_subdev_ops ov9640_subdev_ops = {
+	.core	= &ov9640_core_ops,
+	.video	= &ov9640_video_ops,
+};
+
+/*
+ * i2c_driver function
+ */
+static int ov9640_probe(struct i2c_client *client,
+			const struct i2c_device_id *did)
+{
+	struct ov9640_priv *priv;
+	struct soc_camera_device *icd	= client->dev.platform_data;
+	struct soc_camera_link *icl;
+	int ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "Missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
+	if (!icl) {
+		dev_err(&client->dev, "Missing platform_data for driver\n");
+		return -EINVAL;
+	}
+
+	priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&client->dev,
+			"Failed to allocate memory for private data!\n");
+		return -ENOMEM;
+	}
+
+	v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
+
+	icd->ops	= &ov9640_ops;
+
+	ret = ov9640_video_probe(icd, client);
+
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int ov9640_remove(struct i2c_client *client)
+{
+	struct ov9640_priv *priv = i2c_get_clientdata(client);
+
+	i2c_set_clientdata(client, NULL);
+	kfree(priv);
+	return 0;
+}
+
+static const struct i2c_device_id ov9640_id[] = {
+	{ "ov9640", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ov9640_id);
+
+static struct i2c_driver ov9640_i2c_driver = {
+	.driver = {
+		.name = "ov9640",
+	},
+	.probe    = ov9640_probe,
+	.remove   = ov9640_remove,
+	.id_table = ov9640_id,
+};
+
+static int __init ov9640_module_init(void)
+{
+	return i2c_add_driver(&ov9640_i2c_driver);
+}
+
+static void __exit ov9640_module_exit(void)
+{
+	i2c_del_driver(&ov9640_i2c_driver);
+}
+
+module_init(ov9640_module_init);
+module_exit(ov9640_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/ov9640.h linux-libre-2.6.33-gnu1/drivers/media/video/ov9640.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/ov9640.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/ov9640.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,209 @@
+/*
+ * OmniVision OV96xx Camera Header File
+ *
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@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.
+ */
+
+#ifndef	__DRIVERS_MEDIA_VIDEO_OV9640_H__
+#define	__DRIVERS_MEDIA_VIDEO_OV9640_H__
+
+/* Register definitions */
+#define	OV9640_GAIN	0x00
+#define	OV9640_BLUE	0x01
+#define	OV9640_RED	0x02
+#define	OV9640_VFER	0x03
+#define	OV9640_COM1	0x04
+#define	OV9640_BAVE	0x05
+#define	OV9640_GEAVE	0x06
+#define	OV9640_RSID	0x07
+#define	OV9640_RAVE	0x08
+#define	OV9640_COM2	0x09
+#define	OV9640_PID	0x0a
+#define	OV9640_VER	0x0b
+#define	OV9640_COM3	0x0c
+#define	OV9640_COM4	0x0d
+#define	OV9640_COM5	0x0e
+#define	OV9640_COM6	0x0f
+#define	OV9640_AECH	0x10
+#define	OV9640_CLKRC	0x11
+#define	OV9640_COM7	0x12
+#define	OV9640_COM8	0x13
+#define	OV9640_COM9	0x14
+#define	OV9640_COM10	0x15
+/* 0x16 - RESERVED */
+#define	OV9640_HSTART	0x17
+#define	OV9640_HSTOP	0x18
+#define	OV9640_VSTART	0x19
+#define	OV9640_VSTOP	0x1a
+#define	OV9640_PSHFT	0x1b
+#define	OV9640_MIDH	0x1c
+#define	OV9640_MIDL	0x1d
+#define	OV9640_MVFP	0x1e
+#define	OV9640_LAEC	0x1f
+#define	OV9640_BOS	0x20
+#define	OV9640_GBOS	0x21
+#define	OV9640_GROS	0x22
+#define	OV9640_ROS	0x23
+#define	OV9640_AEW	0x24
+#define	OV9640_AEB	0x25
+#define	OV9640_VPT	0x26
+#define	OV9640_BBIAS	0x27
+#define	OV9640_GBBIAS	0x28
+/* 0x29 - RESERVED */
+#define	OV9640_EXHCH	0x2a
+#define	OV9640_EXHCL	0x2b
+#define	OV9640_RBIAS	0x2c
+#define	OV9640_ADVFL	0x2d
+#define	OV9640_ADVFH	0x2e
+#define	OV9640_YAVE	0x2f
+#define	OV9640_HSYST	0x30
+#define	OV9640_HSYEN	0x31
+#define	OV9640_HREF	0x32
+#define	OV9640_CHLF	0x33
+#define	OV9640_ARBLM	0x34
+/* 0x35..0x36 - RESERVED */
+#define	OV9640_ADC	0x37
+#define	OV9640_ACOM	0x38
+#define	OV9640_OFON	0x39
+#define	OV9640_TSLB	0x3a
+#define	OV9640_COM11	0x3b
+#define	OV9640_COM12	0x3c
+#define	OV9640_COM13	0x3d
+#define	OV9640_COM14	0x3e
+#define	OV9640_EDGE	0x3f
+#define	OV9640_COM15	0x40
+#define	OV9640_COM16	0x41
+#define	OV9640_COM17	0x42
+/* 0x43..0x4e - RESERVED */
+#define	OV9640_MTX1	0x4f
+#define	OV9640_MTX2	0x50
+#define	OV9640_MTX3	0x51
+#define	OV9640_MTX4	0x52
+#define	OV9640_MTX5	0x53
+#define	OV9640_MTX6	0x54
+#define	OV9640_MTX7	0x55
+#define	OV9640_MTX8	0x56
+#define	OV9640_MTX9	0x57
+#define	OV9640_MTXS	0x58
+/* 0x59..0x61 - RESERVED */
+#define	OV9640_LCC1	0x62
+#define	OV9640_LCC2	0x63
+#define	OV9640_LCC3	0x64
+#define	OV9640_LCC4	0x65
+#define	OV9640_LCC5	0x66
+#define	OV9640_MANU	0x67
+#define	OV9640_MANV	0x68
+#define	OV9640_HV	0x69
+#define	OV9640_MBD	0x6a
+#define	OV9640_DBLV	0x6b
+#define	OV9640_GSP	0x6c	/* ... till 0x7b */
+#define	OV9640_GST	0x7c	/* ... till 0x8a */
+
+#define	OV9640_CLKRC_DPLL_EN	0x80
+#define	OV9640_CLKRC_DIRECT	0x40
+#define	OV9640_CLKRC_DIV(x)	((x) & 0x3f)
+
+#define	OV9640_PSHFT_VAL(x)	((x) & 0xff)
+
+#define	OV9640_ACOM_2X_ANALOG	0x80
+#define	OV9640_ACOM_RSVD	0x12
+
+#define	OV9640_MVFP_V		0x10
+#define	OV9640_MVFP_H		0x20
+
+#define	OV9640_COM1_HREF_NOSKIP	0x00
+#define	OV9640_COM1_HREF_2SKIP	0x04
+#define	OV9640_COM1_HREF_3SKIP	0x08
+#define	OV9640_COM1_QQFMT	0x20
+
+#define	OV9640_COM2_SSM		0x10
+
+#define	OV9640_COM3_VP		0x04
+
+#define	OV9640_COM4_QQ_VP	0x80
+#define	OV9640_COM4_RSVD	0x40
+
+#define	OV9640_COM5_SYSCLK	0x80
+#define	OV9640_COM5_LONGEXP	0x01
+
+#define	OV9640_COM6_OPT_BLC	0x40
+#define	OV9640_COM6_ADBLC_BIAS	0x08
+#define	OV9640_COM6_FMT_RST	0x82
+#define	OV9640_COM6_ADBLC_OPTEN	0x01
+
+#define	OV9640_COM7_RAW_RGB	0x01
+#define	OV9640_COM7_RGB		0x04
+#define	OV9640_COM7_QCIF	0x08
+#define	OV9640_COM7_QVGA	0x10
+#define	OV9640_COM7_CIF		0x20
+#define	OV9640_COM7_VGA		0x40
+#define	OV9640_COM7_SCCB_RESET	0x80
+
+#define	OV9640_TSLB_YVYU_YUYV	0x04
+#define	OV9640_TSLB_YUYV_UYVY	0x08
+
+#define	OV9640_COM12_YUV_AVG	0x04
+#define	OV9640_COM12_RSVD	0x40
+
+#define	OV9640_COM13_GAMMA_NONE	0x00
+#define	OV9640_COM13_GAMMA_Y	0x40
+#define	OV9640_COM13_GAMMA_RAW	0x80
+#define	OV9640_COM13_RGB_AVG	0x20
+#define	OV9640_COM13_MATRIX_EN	0x10
+#define	OV9640_COM13_Y_DELAY_EN	0x08
+#define	OV9640_COM13_YUV_DLY(x)	((x) & 0x07)
+
+#define	OV9640_COM15_OR_00FF	0x00
+#define	OV9640_COM15_OR_01FE	0x40
+#define	OV9640_COM15_OR_10F0	0xc0
+#define	OV9640_COM15_RGB_NORM	0x00
+#define	OV9640_COM15_RGB_565	0x10
+#define	OV9640_COM15_RGB_555	0x30
+
+#define	OV9640_COM16_RB_AVG	0x01
+
+/* IDs */
+#define	OV9640_V2		0x9648
+#define	OV9640_V3		0x9649
+#define	VERSION(pid, ver)	(((pid) << 8) | ((ver) & 0xFF))
+
+/* supported resolutions */
+enum {
+	W_QQCIF	= 88,
+	W_QQVGA	= 160,
+	W_QCIF	= 176,
+	W_QVGA	= 320,
+	W_CIF	= 352,
+	W_VGA	= 640,
+	W_SXGA	= 1280
+};
+#define	H_SXGA	960
+
+/* Misc. structures */
+struct ov9640_reg_alt {
+	u8	com7;
+	u8	com12;
+	u8	com13;
+	u8	com15;
+};
+
+struct ov9640_reg {
+	u8	reg;
+	u8	val;
+};
+
+struct ov9640_priv {
+	struct v4l2_subdev		subdev;
+
+	int				model;
+	int				revision;
+
+	bool				flag_vflip;
+	bool				flag_hflip;
+};
+
+#endif	/* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pms.c linux-libre-2.6.33-gnu1/drivers/media/video/pms.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pms.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,8 +14,10 @@
  *	unless the userspace driver also doesn't work for you...
  *
  *      Changes:
- *      08/07/2003        Daniele Bellucci <bellucda@tiscali.it>
- *                        - pms_capture: report back -EFAULT
+ *	25-11-2009 	Hans Verkuil <hverkuil@xs4all.nl>
+ * 			- converted to version 2 of the V4L API.
+ *      08/07/2003      Daniele Bellucci <bellucda@tiscali.it>
+ *                      - pms_capture: report back -EFAULT
  */
 
 #include <linux/module.h>
@@ -27,175 +29,183 @@
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/version.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
 #include <asm/io.h>
-#include <linux/videodev.h>
+
+#include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <linux/mutex.h>
+#include <media/v4l2-device.h>
 
-#include <asm/uaccess.h>
+MODULE_LICENSE("GPL");
 
 
 #define MOTOROLA	1
-#define PHILIPS2	2
+#define PHILIPS2	2               /* SAA7191 */
 #define PHILIPS1	3
 #define MVVMEMORYWIDTH	0x40		/* 512 bytes */
 
-struct pms_device
-{
-	struct video_device v;
-	struct video_picture picture;
-	int height;
-	int width;
-	unsigned long in_use;
-	struct mutex lock;
-};
-
-struct i2c_info
-{
+struct i2c_info {
 	u8 slave;
 	u8 sub;
 	u8 data;
 	u8 hits;
 };
 
-static int i2c_count;
-static struct i2c_info i2cinfo[64];
+struct pms {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int height;
+	int width;
+	int depth;
+	int input;
+	s32 brightness, saturation, hue, contrast;
+	unsigned long in_use;
+	struct mutex lock;
+	int i2c_count;
+	struct i2c_info i2cinfo[64];
 
-static int decoder 		= PHILIPS2;
-static int standard;	/* 0 - auto 1 - ntsc 2 - pal 3 - secam */
+	int decoder;
+	int standard;	/* 0 - auto 1 - ntsc 2 - pal 3 - secam */
+	v4l2_std_id std;
+	int io;
+	int data;
+	void __iomem *mem;
+};
+
+static struct pms pms_card;
 
 /*
  *	I/O ports and Shared Memory
  */
 
-static int io_port		=	0x250;
-static int data_port		=	0x251;
-static int mem_base		=	0xC8000;
-static void __iomem *mem;
-static int video_nr             =       -1;
+static int io_port = 0x250;
+module_param(io_port, int, 0);
 
+static int mem_base = 0xc8000;
+module_param(mem_base, int, 0);
+
+static int video_nr = -1;
+module_param(video_nr, int, 0);
 
 
-static inline void mvv_write(u8 index, u8 value)
+static inline void mvv_write(struct pms *dev, u8 index, u8 value)
 {
-	outw(index|(value<<8), io_port);
+	outw(index | (value << 8), dev->io);
 }
 
-static inline u8 mvv_read(u8 index)
+static inline u8 mvv_read(struct pms *dev, u8 index)
 {
-	outb(index, io_port);
-	return inb(data_port);
+	outb(index, dev->io);
+	return inb(dev->data);
 }
 
-static int pms_i2c_stat(u8 slave)
+static int pms_i2c_stat(struct pms *dev, u8 slave)
 {
-	int counter;
+	int counter = 0;
 	int i;
 
-	outb(0x28, io_port);
+	outb(0x28, dev->io);
 
-	counter=0;
-	while((inb(data_port)&0x01)==0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) == 0)
+		if (counter++ == 256)
 			break;
 
-	while((inb(data_port)&0x01)!=0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) != 0)
+		if (counter++ == 256)
 			break;
 
-	outb(slave, io_port);
+	outb(slave, dev->io);
 
-	counter=0;
-	while((inb(data_port)&0x01)==0)
-		if(counter++==256)
+	counter = 0;
+	while ((inb(dev->data) & 0x01) == 0)
+		if (counter++ == 256)
 			break;
 
-	while((inb(data_port)&0x01)!=0)
-		if(counter++==256)
+	while ((inb(dev->data) & 0x01) != 0)
+		if (counter++ == 256)
 			break;
 
-	for(i=0;i<12;i++)
-	{
-		char st=inb(data_port);
-		if((st&2)!=0)
+	for (i = 0; i < 12; i++) {
+		char st = inb(dev->data);
+
+		if ((st & 2) != 0)
 			return -1;
-		if((st&1)==0)
+		if ((st & 1) == 0)
 			break;
 	}
-	outb(0x29, io_port);
-	return inb(data_port);
+	outb(0x29, dev->io);
+	return inb(dev->data);
 }
 
-static int pms_i2c_write(u16 slave, u16 sub, u16 data)
+static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
 {
-	int skip=0;
+	int skip = 0;
 	int count;
 	int i;
 
-	for(i=0;i<i2c_count;i++)
-	{
-		if((i2cinfo[i].slave==slave) &&
-		   (i2cinfo[i].sub == sub))
-		{
-			if(i2cinfo[i].data==data)
-				skip=1;
-			i2cinfo[i].data=data;
-			i=i2c_count+1;
+	for (i = 0; i < dev->i2c_count; i++) {
+		if ((dev->i2cinfo[i].slave == slave) &&
+		    (dev->i2cinfo[i].sub == sub)) {
+			if (dev->i2cinfo[i].data == data)
+				skip = 1;
+			dev->i2cinfo[i].data = data;
+			i = dev->i2c_count + 1;
 		}
 	}
 
-	if(i==i2c_count && i2c_count<64)
-	{
-		i2cinfo[i2c_count].slave=slave;
-		i2cinfo[i2c_count].sub=sub;
-		i2cinfo[i2c_count].data=data;
-		i2c_count++;
+	if (i == dev->i2c_count && dev->i2c_count < 64) {
+		dev->i2cinfo[dev->i2c_count].slave = slave;
+		dev->i2cinfo[dev->i2c_count].sub = sub;
+		dev->i2cinfo[dev->i2c_count].data = data;
+		dev->i2c_count++;
 	}
 
-	if(skip)
+	if (skip)
 		return 0;
 
-	mvv_write(0x29, sub);
-	mvv_write(0x2A, data);
-	mvv_write(0x28, slave);
+	mvv_write(dev, 0x29, sub);
+	mvv_write(dev, 0x2A, data);
+	mvv_write(dev, 0x28, slave);
 
-	outb(0x28, io_port);
+	outb(0x28, dev->io);
 
-	count=0;
-	while((inb(data_port)&1)==0)
-		if(count>255)
+	count = 0;
+	while ((inb(dev->data) & 1) == 0)
+		if (count > 255)
 			break;
-	while((inb(data_port)&1)!=0)
-		if(count>255)
+	while ((inb(dev->data) & 1) != 0)
+		if (count > 255)
 			break;
 
-	count=inb(data_port);
+	count = inb(dev->data);
 
-	if(count&2)
+	if (count & 2)
 		return -1;
 	return count;
 }
 
-static int pms_i2c_read(int slave, int sub)
+static int pms_i2c_read(struct pms *dev, int slave, int sub)
 {
-	int i=0;
-	for(i=0;i<i2c_count;i++)
-	{
-		if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
-			return i2cinfo[i].data;
+	int i;
+
+	for (i = 0; i < dev->i2c_count; i++) {
+		if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
+			return dev->i2cinfo[i].data;
 	}
 	return 0;
 }
 
 
-static void pms_i2c_andor(int slave, int sub, int and, int or)
+static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
 {
 	u8 tmp;
 
-	tmp=pms_i2c_read(slave, sub);
-	tmp = (tmp&and)|or;
-	pms_i2c_write(slave, sub, tmp);
+	tmp = pms_i2c_read(dev, slave, sub);
+	tmp = (tmp & and) | or;
+	pms_i2c_write(dev, slave, sub, tmp);
 }
 
 /*
@@ -203,100 +213,108 @@ static void pms_i2c_andor(int slave, int
  */
 
 
-static void pms_videosource(short source)
+static void pms_videosource(struct pms *dev, short source)
 {
-	mvv_write(0x2E, source?0x31:0x30);
+	switch (dev->decoder) {
+	case MOTOROLA:
+		break;
+	case PHILIPS2:
+		pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
+		break;
+	case PHILIPS1:
+		break;
+	}
+	mvv_write(dev, 0x2E, 0x31);
+	/* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
+	   But could not make this work correctly. Only Composite input
+	   worked for me. */
 }
 
-static void pms_hue(short hue)
+static void pms_hue(struct pms *dev, short hue)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, hue);
-			break;
-		case PHILIPS2:
-			pms_i2c_write(0x8A, 0x07, hue);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x07, hue);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, hue);
+		break;
+	case PHILIPS2:
+		pms_i2c_write(dev, 0x8a, 0x07, hue);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x07, hue);
+		break;
 	}
 }
 
-static void pms_colour(short colour)
+static void pms_saturation(struct pms *dev, short sat)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, colour);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x12, colour);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, sat);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x12, sat);
+		break;
 	}
 }
 
 
-static void pms_contrast(short contrast)
+static void pms_contrast(struct pms *dev, short contrast)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, contrast);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x13, contrast);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, contrast);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x13, contrast);
+		break;
 	}
 }
 
-static void pms_brightness(short brightness)
+static void pms_brightness(struct pms *dev, short brightness)
 {
-	switch(decoder)
-	{
-		case MOTOROLA:
-			pms_i2c_write(0x8A, 0x00, brightness);
-			pms_i2c_write(0x8A, 0x00, brightness);
-			pms_i2c_write(0x8A, 0x00, brightness);
-			break;
-		case PHILIPS1:
-			pms_i2c_write(0x42, 0x19, brightness);
-			break;
+	switch (dev->decoder) {
+	case MOTOROLA:
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		pms_i2c_write(dev, 0x8a, 0x00, brightness);
+		break;
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x42, 0x19, brightness);
+		break;
 	}
 }
 
 
-static void pms_format(short format)
+static void pms_format(struct pms *dev, short format)
 {
 	int target;
-	standard = format;
 
-	if(decoder==PHILIPS1)
-		target=0x42;
-	else if(decoder==PHILIPS2)
-		target=0x8A;
+	dev->standard = format;
+
+	if (dev->decoder == PHILIPS1)
+		target = 0x42;
+	else if (dev->decoder == PHILIPS2)
+		target = 0x8a;
 	else
 		return;
 
-	switch(format)
-	{
-		case 0:	/* Auto */
-			pms_i2c_andor(target, 0x0D, 0xFE,0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F,0x80);
-			break;
-		case 1: /* NTSC */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
-			break;
-		case 2: /* PAL */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
-			break;
-		case 3:	/* SECAM */
-			pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
-			pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
-			break;
+	switch (format) {
+	case 0:	/* Auto */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
+		break;
+	case 1: /* NTSC */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
+		break;
+	case 2: /* PAL */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
+		break;
+	case 3:	/* SECAM */
+		pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
+		pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
+		break;
 	}
 }
 
@@ -308,18 +326,17 @@ static void pms_format(short format)
  *	people need it. We also don't yet use the PMS interrupt.
  */
 
-static void pms_hstart(short start)
+static void pms_hstart(struct pms *dev, short start)
 {
-	switch(decoder)
-	{
-		case PHILIPS1:
-			pms_i2c_write(0x8A, 0x05, start);
-			pms_i2c_write(0x8A, 0x18, start);
-			break;
-		case PHILIPS2:
-			pms_i2c_write(0x42, 0x05, start);
-			pms_i2c_write(0x42, 0x18, start);
-			break;
+	switch (dev->decoder) {
+	case PHILIPS1:
+		pms_i2c_write(dev, 0x8a, 0x05, start);
+		pms_i2c_write(dev, 0x8a, 0x18, start);
+		break;
+	case PHILIPS2:
+		pms_i2c_write(dev, 0x42, 0x05, start);
+		pms_i2c_write(dev, 0x42, 0x18, start);
+		break;
 	}
 }
 
@@ -327,293 +344,271 @@ static void pms_hstart(short start)
  *	Bandpass filters
  */
 
-static void pms_bandpass(short pass)
+static void pms_bandpass(struct pms *dev, short pass)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
 }
 
-static void pms_antisnow(short snow)
+static void pms_antisnow(struct pms *dev, short snow)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
 }
 
-static void pms_sharpness(short sharp)
+static void pms_sharpness(struct pms *dev, short sharp)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
 }
 
-static void pms_chromaagc(short agc)
+static void pms_chromaagc(struct pms *dev, short agc)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
 }
 
-static void pms_vertnoise(short noise)
+static void pms_vertnoise(struct pms *dev, short noise)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
 }
 
-static void pms_forcecolour(short colour)
+static void pms_forcecolour(struct pms *dev, short colour)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
 }
 
-static void pms_antigamma(short gamma)
+static void pms_antigamma(struct pms *dev, short gamma)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
 }
 
-static void pms_prefilter(short filter)
+static void pms_prefilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
 }
 
-static void pms_hfilter(short filter)
+static void pms_hfilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
 }
 
-static void pms_vfilter(short filter)
+static void pms_vfilter(struct pms *dev, short filter)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
 }
 
-static void pms_killcolour(short colour)
+static void pms_killcolour(struct pms *dev, short colour)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
-		pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
-		pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
+	if (dev->decoder == PHILIPS2) {
+		pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
+		pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
+	} else if (dev->decoder == PHILIPS1) {
+		pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
+		pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
 	}
 }
 
-static void pms_chromagain(short chroma)
+static void pms_chromagain(struct pms *dev, short chroma)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_write(0x8A, 0x11, chroma);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_write(0x42, 0x11, chroma);
-	}
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_write(dev, 0x8a, 0x11, chroma);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_write(dev, 0x42, 0x11, chroma);
 }
 
 
-static void pms_spacialcompl(short data)
+static void pms_spacialcompl(struct pms *dev, short data)
 {
-	mvv_write(0x3B, data);
+	mvv_write(dev, 0x3b, data);
 }
 
-static void pms_spacialcomph(short data)
+static void pms_spacialcomph(struct pms *dev, short data)
 {
-	mvv_write(0x3A, data);
+	mvv_write(dev, 0x3a, data);
 }
 
-static void pms_vstart(short start)
+static void pms_vstart(struct pms *dev, short start)
 {
-	mvv_write(0x16, start);
-	mvv_write(0x17, (start>>8)&0x01);
+	mvv_write(dev, 0x16, start);
+	mvv_write(dev, 0x17, (start >> 8) & 0x01);
 }
 
 #endif
 
-static void pms_secamcross(short cross)
+static void pms_secamcross(struct pms *dev, short cross)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
 }
 
 
-static void pms_swsense(short sense)
+static void pms_swsense(struct pms *dev, short sense)
 {
-	if(decoder==PHILIPS2)
-	{
-		pms_i2c_write(0x8A, 0x0A, sense);
-		pms_i2c_write(0x8A, 0x0B, sense);
-	}
-	else if(decoder==PHILIPS1)
-	{
-		pms_i2c_write(0x42, 0x0A, sense);
-		pms_i2c_write(0x42, 0x0B, sense);
+	if (dev->decoder == PHILIPS2) {
+		pms_i2c_write(dev, 0x8a, 0x0a, sense);
+		pms_i2c_write(dev, 0x8a, 0x0b, sense);
+	} else if (dev->decoder == PHILIPS1) {
+		pms_i2c_write(dev, 0x42, 0x0a, sense);
+		pms_i2c_write(dev, 0x42, 0x0b, sense);
 	}
 }
 
 
-static void pms_framerate(short frr)
+static void pms_framerate(struct pms *dev, short frr)
 {
-	int fps=(standard==1)?30:25;
-	if(frr==0)
+	int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
+
+	if (frr == 0)
 		return;
-	fps=fps/frr;
-	mvv_write(0x14,0x80|fps);
-	mvv_write(0x15,1);
+	fps = fps/frr;
+	mvv_write(dev, 0x14, 0x80 | fps);
+	mvv_write(dev, 0x15, 1);
 }
 
-static void pms_vert(u8 deciden, u8 decinum)
+static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
 {
-	mvv_write(0x1C, deciden);	/* Denominator */
-	mvv_write(0x1D, decinum);	/* Numerator */
+	mvv_write(dev, 0x1c, deciden);	/* Denominator */
+	mvv_write(dev, 0x1d, decinum);	/* Numerator */
 }
 
 /*
  *	Turn 16bit ratios into best small ratio the chipset can grok
  */
 
-static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
+static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
 {
-	/* Knock it down by /5 once */
-	if(decinum%5==0)
-	{
-		deciden/=5;
-		decinum/=5;
+	/* Knock it down by / 5 once */
+	if (decinum % 5 == 0) {
+		deciden /= 5;
+		decinum /= 5;
 	}
 	/*
 	 *	3's
 	 */
-	while(decinum%3==0 && deciden%3==0)
-	{
-		deciden/=3;
-		decinum/=3;
+	while (decinum % 3 == 0 && deciden % 3 == 0) {
+		deciden /= 3;
+		decinum /= 3;
 	}
 	/*
 	 *	2's
 	 */
-	while(decinum%2==0 && deciden%2==0)
-	{
-		decinum/=2;
-		deciden/=2;
+	while (decinum % 2 == 0 && deciden % 2 == 0) {
+		decinum /= 2;
+		deciden /= 2;
 	}
 	/*
 	 *	Fudgyify
 	 */
-	while(deciden>32)
-	{
-		deciden/=2;
-		decinum=(decinum+1)/2;
+	while (deciden > 32) {
+		deciden /= 2;
+		decinum = (decinum + 1) / 2;
 	}
-	if(deciden==32)
+	if (deciden == 32)
 		deciden--;
-	pms_vert(deciden,decinum);
+	pms_vert(dev, deciden, decinum);
 }
 
-static void pms_horzdeci(short decinum, short deciden)
+static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
 {
-	if(decinum<=512)
-	{
-		if(decinum%5==0)
-		{
-			decinum/=5;
-			deciden/=5;
+	if (decinum <= 512) {
+		if (decinum % 5 == 0) {
+			decinum /= 5;
+			deciden /= 5;
 		}
-	}
-	else
-	{
-		decinum=512;
-		deciden=640;	/* 768 would be ideal */
+	} else {
+		decinum = 512;
+		deciden = 640;	/* 768 would be ideal */
 	}
 
-	while(((decinum|deciden)&1)==0)
-	{
-		decinum>>=1;
-		deciden>>=1;
+	while (((decinum | deciden) & 1) == 0) {
+		decinum >>= 1;
+		deciden >>= 1;
 	}
-	while(deciden>32)
-	{
-		deciden>>=1;
-		decinum=(decinum+1)>>1;
+	while (deciden > 32) {
+		deciden >>= 1;
+		decinum = (decinum + 1) >> 1;
 	}
-	if(deciden==32)
+	if (deciden == 32)
 		deciden--;
 
-	mvv_write(0x24, 0x80|deciden);
-	mvv_write(0x25, decinum);
+	mvv_write(dev, 0x24, 0x80 | deciden);
+	mvv_write(dev, 0x25, decinum);
 }
 
-static void pms_resolution(short width, short height)
+static void pms_resolution(struct pms *dev, short width, short height)
 {
 	int fg_height;
 
-	fg_height=height;
-	if(fg_height>280)
-		fg_height=280;
+	fg_height = height;
+	if (fg_height > 280)
+		fg_height = 280;
 
-	mvv_write(0x18, fg_height);
-	mvv_write(0x19, fg_height>>8);
+	mvv_write(dev, 0x18, fg_height);
+	mvv_write(dev, 0x19, fg_height >> 8);
 
-	if(standard==1)
-	{
-		mvv_write(0x1A, 0xFC);
-		mvv_write(0x1B, 0x00);
-		if(height>fg_height)
-			pms_vertdeci(240,240);
+	if (dev->std & V4L2_STD_525_60) {
+		mvv_write(dev, 0x1a, 0xfc);
+		mvv_write(dev, 0x1b, 0x00);
+		if (height > fg_height)
+			pms_vertdeci(dev, 240, 240);
 		else
-			pms_vertdeci(fg_height,240);
-	}
-	else
-	{
-		mvv_write(0x1A, 0x1A);
-		mvv_write(0x1B, 0x01);
-		if(fg_height>256)
-			pms_vertdeci(270,270);
+			pms_vertdeci(dev, fg_height, 240);
+	} else {
+		mvv_write(dev, 0x1a, 0x1a);
+		mvv_write(dev, 0x1b, 0x01);
+		if (fg_height > 256)
+			pms_vertdeci(dev, 270, 270);
 		else
-			pms_vertdeci(fg_height, 270);
+			pms_vertdeci(dev, fg_height, 270);
 	}
-	mvv_write(0x12,0);
-	mvv_write(0x13, MVVMEMORYWIDTH);
-	mvv_write(0x42, 0x00);
-	mvv_write(0x43, 0x00);
-	mvv_write(0x44, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x12, 0);
+	mvv_write(dev, 0x13, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x42, 0x00);
+	mvv_write(dev, 0x43, 0x00);
+	mvv_write(dev, 0x44, MVVMEMORYWIDTH);
 
-	mvv_write(0x22, width+8);
-	mvv_write(0x23, (width+8)>> 8);
+	mvv_write(dev, 0x22, width + 8);
+	mvv_write(dev, 0x23, (width + 8) >> 8);
 
-	if(standard==1)
-		pms_horzdeci(width,640);
+	if (dev->std & V4L2_STD_525_60)
+		pms_horzdeci(dev, width, 640);
 	else
-		pms_horzdeci(width+8, 768);
+		pms_horzdeci(dev, width + 8, 768);
 
-	mvv_write(0x30, mvv_read(0x30)&0xFE);
-	mvv_write(0x08, mvv_read(0x08)|0x01);
-	mvv_write(0x01, mvv_read(0x01)&0xFD);
-	mvv_write(0x32, 0x00);
-	mvv_write(0x33, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
+	mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
+	mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
+	mvv_write(dev, 0x32, 0x00);
+	mvv_write(dev, 0x33, MVVMEMORYWIDTH);
 }
 
 
@@ -621,52 +616,49 @@ static void pms_resolution(short width,
  *	Set Input
  */
 
-static void pms_vcrinput(short input)
+static void pms_vcrinput(struct pms *dev, short input)
 {
-	if(decoder==PHILIPS2)
-		pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
-	else if(decoder==PHILIPS1)
-		pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
+	if (dev->decoder == PHILIPS2)
+		pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
+	else if (dev->decoder == PHILIPS1)
+		pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
 }
 
 
-static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count)
+static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
 {
 	int y;
-	int dw = 2*dev->width;
-
-	char tmp[dw+32]; /* using a temp buffer is faster than direct  */
+	int dw = 2 * dev->width;
+	char tmp[dw + 32]; /* using a temp buffer is faster than direct  */
 	int cnt = 0;
-	int len=0;
+	int len = 0;
 	unsigned char r8 = 0x5;  /* value for reg8  */
 
 	if (rgb555)
 		r8 |= 0x20; /* else use untranslated rgb = 565 */
-	mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
+	mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
 
 /*	printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
 
-	for (y = 0; y < dev->height; y++ )
-	{
-		writeb(0, mem);  /* synchronisiert neue Zeile */
+	for (y = 0; y < dev->height; y++) {
+		writeb(0, dev->mem);  /* synchronisiert neue Zeile */
 
 		/*
 		 *	This is in truth a fifo, be very careful as if you
 		 *	forgot this odd things will occur 8)
 		 */
 
-		memcpy_fromio(tmp, mem, dw+32); /* discard 16 word   */
+		memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word   */
 		cnt -= dev->height;
-		while (cnt <= 0)
-		{
+		while (cnt <= 0) {
 			/*
 			 *	Don't copy too far
 			 */
-			int dt=dw;
-			if(dt+len>count)
-				dt=count-len;
+			int dt = dw;
+			if (dt + len > count)
+				dt = count - len;
 			cnt += dev->height;
-			if (copy_to_user(buf, tmp+32, dt))
+			if (copy_to_user(buf, tmp + 32, dt))
 				return len ? len : -EFAULT;
 			buf += dt;
 			len += dt;
@@ -680,221 +672,278 @@ static int pms_capture(struct pms_device
  *	Video4linux interfacing
  */
 
-static long pms_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+static int pms_querycap(struct file *file, void  *priv,
+					struct v4l2_capability *vcap)
 {
-	struct video_device *dev = video_devdata(file);
-	struct pms_device *pd=(struct pms_device *)dev;
+	struct pms *dev = video_drvdata(file);
 
-	switch(cmd)
-	{
-		case VIDIOCGCAP:
-		{
-			struct video_capability *b = arg;
-			strcpy(b->name, "Mediavision PMS");
-			b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
-			b->channels = 4;
-			b->audios = 0;
-			b->maxwidth = 640;
-			b->maxheight = 480;
-			b->minwidth = 16;
-			b->minheight = 16;
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			struct video_channel *v = arg;
-			if(v->channel<0 || v->channel>3)
-				return -EINVAL;
-			v->flags=0;
-			v->tuners=1;
-			/* Good question.. its composite or SVHS so.. */
-			v->type = VIDEO_TYPE_CAMERA;
-			switch(v->channel)
-			{
-				case 0:
-					strcpy(v->name, "Composite");break;
-				case 1:
-					strcpy(v->name, "SVideo");break;
-				case 2:
-					strcpy(v->name, "Composite(VCR)");break;
-				case 3:
-					strcpy(v->name, "SVideo(VCR)");break;
-			}
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			struct video_channel *v = arg;
-			if(v->channel<0 || v->channel>3)
-				return -EINVAL;
-			mutex_lock(&pd->lock);
-			pms_videosource(v->channel&1);
-			pms_vcrinput(v->channel>>1);
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner)
-				return -EINVAL;
-			strcpy(v->name, "Format");
-			v->rangelow=0;
-			v->rangehigh=0;
-			v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
-			switch(standard)
-			{
-				case 0:
-					v->mode = VIDEO_MODE_AUTO;
-					break;
-				case 1:
-					v->mode = VIDEO_MODE_NTSC;
-					break;
-				case 2:
-					v->mode = VIDEO_MODE_PAL;
-					break;
-				case 3:
-					v->mode = VIDEO_MODE_SECAM;
-					break;
-			}
-			return 0;
-		}
-		case VIDIOCSTUNER:
-		{
-			struct video_tuner *v = arg;
-			if(v->tuner)
-				return -EINVAL;
-			mutex_lock(&pd->lock);
-			switch(v->mode)
-			{
-				case VIDEO_MODE_AUTO:
-					pms_framerate(25);
-					pms_secamcross(0);
-					pms_format(0);
-					break;
-				case VIDEO_MODE_NTSC:
-					pms_framerate(30);
-					pms_secamcross(0);
-					pms_format(1);
-					break;
-				case VIDEO_MODE_PAL:
-					pms_framerate(25);
-					pms_secamcross(0);
-					pms_format(2);
-					break;
-				case VIDEO_MODE_SECAM:
-					pms_framerate(25);
-					pms_secamcross(1);
-					pms_format(2);
-					break;
-				default:
-					mutex_unlock(&pd->lock);
-					return -EINVAL;
-			}
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCGPICT:
-		{
-			struct video_picture *p = arg;
-			*p = pd->picture;
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture *p = arg;
-			if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
-			    ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
-				return -EINVAL;
-			pd->picture= *p;
+	strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
+	strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
+	strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info));
+	vcap->version = KERNEL_VERSION(0, 0, 3);
+	vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
+	return 0;
+}
 
-			/*
-			 *	Now load the card.
-			 */
+static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
+{
+	static const char *inputs[4] = {
+		"Composite",
+		"S-Video",
+		"Composite (VCR)",
+		"S-Video (VCR)"
+	};
 
-			mutex_lock(&pd->lock);
-			pms_brightness(p->brightness>>8);
-			pms_hue(p->hue>>8);
-			pms_colour(p->colour>>8);
-			pms_contrast(p->contrast>>8);
-			mutex_unlock(&pd->lock);
-			return 0;
-		}
-		case VIDIOCSWIN:
-		{
-			struct video_window *vw = arg;
-			if(vw->flags)
-				return -EINVAL;
-			if(vw->clipcount)
-				return -EINVAL;
-			if(vw->height<16||vw->height>480)
-				return -EINVAL;
-			if(vw->width<16||vw->width>640)
-				return -EINVAL;
-			pd->width=vw->width;
-			pd->height=vw->height;
-			mutex_lock(&pd->lock);
-			pms_resolution(pd->width, pd->height);
-			mutex_unlock(&pd->lock);			/* Ok we figured out what to use from our wide choice */
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window *vw = arg;
-			memset(vw,0,sizeof(*vw));
-			vw->width=pd->width;
-			vw->height=pd->height;
-			return 0;
-		}
-		case VIDIOCKEY:
-			return 0;
-		case VIDIOCCAPTURE:
-		case VIDIOCGFBUF:
-		case VIDIOCSFBUF:
-		case VIDIOCGFREQ:
-		case VIDIOCSFREQ:
-		case VIDIOCGAUDIO:
-		case VIDIOCSAUDIO:
-			return -EINVAL;
-		default:
-			return -ENOIOCTLCMD;
+	if (vin->index > 3)
+		return -EINVAL;
+	strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
+	vin->type = V4L2_INPUT_TYPE_CAMERA;
+	vin->audioset = 0;
+	vin->tuner = 0;
+	vin->std = V4L2_STD_ALL;
+	vin->status = 0;
+	return 0;
+}
+
+static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
+{
+	struct pms *dev = video_drvdata(file);
+
+	*inp = dev->input;
+	return 0;
+}
+
+static int pms_s_input(struct file *file, void *fh, unsigned int inp)
+{
+	struct pms *dev = video_drvdata(file);
+
+	if (inp > 3)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+	dev->input = inp;
+	pms_videosource(dev, inp & 1);
+	pms_vcrinput(dev, inp >> 1);
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct pms *dev = video_drvdata(file);
+
+	*std = dev->std;
+	return 0;
+}
+
+static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	dev->std = *std;
+	mutex_lock(&dev->lock);
+	if (dev->std & V4L2_STD_NTSC) {
+		pms_framerate(dev, 30);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 1);
+	} else if (dev->std & V4L2_STD_PAL) {
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 2);
+	} else if (dev->std & V4L2_STD_SECAM) {
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 1);
+		pms_format(dev, 2);
+	} else {
+		ret = -EINVAL;
 	}
+	/*
+	switch (v->mode) {
+	case VIDEO_MODE_AUTO:
+		pms_framerate(dev, 25);
+		pms_secamcross(dev, 0);
+		pms_format(dev, 0);
+		break;
+	}*/
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
-static long pms_ioctl(struct file *file,
-		     unsigned int cmd, unsigned long arg)
+static int pms_queryctrl(struct file *file, void *priv,
+					struct v4l2_queryctrl *qc)
 {
-	return video_usercopy(file, cmd, arg, pms_do_ioctl);
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
+	}
+	return -EINVAL;
+}
+
+static int pms_g_ctrl(struct file *file, void *priv,
+					struct v4l2_control *ctrl)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = dev->brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = dev->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = dev->saturation;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = dev->hue;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int pms_s_ctrl(struct file *file, void *priv,
+					struct v4l2_control *ctrl)
+{
+	struct pms *dev = video_drvdata(file);
+	int ret = 0;
+
+	mutex_lock(&dev->lock);
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		dev->brightness = ctrl->value;
+		pms_brightness(dev, dev->brightness);
+		break;
+	case V4L2_CID_CONTRAST:
+		dev->contrast = ctrl->value;
+		pms_contrast(dev, dev->contrast);
+		break;
+	case V4L2_CID_SATURATION:
+		dev->saturation = ctrl->value;
+		pms_saturation(dev, dev->saturation);
+		break;
+	case V4L2_CID_HUE:
+		dev->hue = ctrl->value;
+		pms_hue(dev, dev->hue);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct pms *dev = video_drvdata(file);
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+
+	pix->width = dev->width;
+	pix->height = dev->height;
+	pix->pixelformat = dev->width == 15 ?
+			    V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
+	pix->field = V4L2_FIELD_NONE;
+	pix->bytesperline = 2 * dev->width;
+	pix->sizeimage = 2 * dev->width * dev->height;
+	/* Just a guess */
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	return 0;
+}
+
+static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+
+	if (pix->height < 16 || pix->height > 480)
+		return -EINVAL;
+	if (pix->width < 16 || pix->width > 640)
+		return -EINVAL;
+	if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
+	    pix->pixelformat != V4L2_PIX_FMT_RGB565)
+		return -EINVAL;
+	pix->field = V4L2_FIELD_NONE;
+	pix->bytesperline = 2 * pix->width;
+	pix->sizeimage = 2 * pix->width * pix->height;
+	/* Just a guess */
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	return 0;
+}
+
+static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+	struct pms *dev = video_drvdata(file);
+	struct v4l2_pix_format *pix = &fmt->fmt.pix;
+	int ret = pms_try_fmt_vid_cap(file, fh, fmt);
+
+	if (ret)
+		return ret;
+	mutex_lock(&dev->lock);
+	dev->width = pix->width;
+	dev->height = pix->height;
+	dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
+	pms_resolution(dev, dev->width, dev->height);
+	/* Ok we figured out what to use from our wide choice */
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+	static struct v4l2_fmtdesc formats[] = {
+		{ 0, 0, 0,
+		  "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
+		  { 0, 0, 0, 0 }
+		},
+		{ 0, 0, 0,
+		  "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
+		  { 0, 0, 0, 0 }
+		},
+	};
+	enum v4l2_buf_type type = fmt->type;
+
+	if (fmt->index > 1)
+		return -EINVAL;
+
+	*fmt = formats[fmt->index];
+	fmt->type = type;
+	return 0;
 }
 
 static ssize_t pms_read(struct file *file, char __user *buf,
 		    size_t count, loff_t *ppos)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd=(struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 	int len;
 
-	mutex_lock(&pd->lock);
-	len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
-	mutex_unlock(&pd->lock);
+	mutex_lock(&dev->lock);
+	len = pms_capture(dev, buf, (dev->depth == 15), count);
+	mutex_unlock(&dev->lock);
 	return len;
 }
 
 static int pms_exclusive_open(struct file *file)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd = (struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 
-	return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0;
+	return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
 }
 
 static int pms_exclusive_release(struct file *file)
 {
-	struct video_device *v = video_devdata(file);
-	struct pms_device *pd = (struct pms_device *)v;
+	struct pms *dev = video_drvdata(file);
 
-	clear_bit(0, &pd->in_use);
+	clear_bit(0, &dev->in_use);
 	return 0;
 }
 
@@ -902,78 +951,81 @@ static const struct v4l2_file_operations
 	.owner		= THIS_MODULE,
 	.open           = pms_exclusive_open,
 	.release        = pms_exclusive_release,
-	.ioctl          = pms_ioctl,
+	.ioctl		= video_ioctl2,
 	.read           = pms_read,
 };
 
-static struct video_device pms_template=
-{
-	.name		= "Mediavision PMS",
-	.fops           = &pms_fops,
-	.release 	= video_device_release_empty,
+static const struct v4l2_ioctl_ops pms_ioctl_ops = {
+	.vidioc_querycap    		    = pms_querycap,
+	.vidioc_g_input      		    = pms_g_input,
+	.vidioc_s_input      		    = pms_s_input,
+	.vidioc_enum_input   		    = pms_enum_input,
+	.vidioc_g_std 			    = pms_g_std,
+	.vidioc_s_std 			    = pms_s_std,
+	.vidioc_queryctrl 		    = pms_queryctrl,
+	.vidioc_g_ctrl  		    = pms_g_ctrl,
+	.vidioc_s_ctrl 			    = pms_s_ctrl,
+	.vidioc_enum_fmt_vid_cap 	    = pms_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap 		    = pms_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap  		    = pms_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap  	    = pms_try_fmt_vid_cap,
 };
 
-static struct pms_device pms_device;
-
-
 /*
  *	Probe for and initialise the Mediavision PMS
  */
 
-static int init_mediavision(void)
+static int init_mediavision(struct pms *dev)
 {
 	int id;
 	int idec, decst;
 	int i;
-
-	unsigned char i2c_defs[]={
-		0x4C,0x30,0x00,0xE8,
-		0xB6,0xE2,0x00,0x00,
-		0xFF,0xFF,0x00,0x00,
-		0x00,0x00,0x78,0x98,
-		0x00,0x00,0x00,0x00,
-		0x34,0x0A,0xF4,0xCE,
-		0xE4
+	static const unsigned char i2c_defs[] = {
+		0x4c, 0x30, 0x00, 0xe8,
+		0xb6, 0xe2, 0x00, 0x00,
+		0xff, 0xff, 0x00, 0x00,
+		0x00, 0x00, 0x78, 0x98,
+		0x00, 0x00, 0x00, 0x00,
+		0x34, 0x0a, 0xf4, 0xce,
+		0xe4
 	};
 
-	mem = ioremap(mem_base, 0x800);
-	if (!mem)
+	dev->mem = ioremap(mem_base, 0x800);
+	if (!dev->mem)
 		return -ENOMEM;
 
-	if (!request_region(0x9A01, 1, "Mediavision PMS config"))
-	{
-		printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
-		iounmap(mem);
+	if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
+		printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
+		iounmap(dev->mem);
 		return -EBUSY;
 	}
-	if (!request_region(io_port, 3, "Mediavision PMS"))
-	{
-		printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
-		release_region(0x9A01, 1);
-		iounmap(mem);
+	if (!request_region(dev->io, 3, "Mediavision PMS")) {
+		printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
 		return -EBUSY;
 	}
-	outb(0xB8, 0x9A01);		/* Unlock */
-	outb(io_port>>4, 0x9A01);	/* Set IO port */
+	outb(0xb8, 0x9a01);		/* Unlock */
+	outb(dev->io >> 4, 0x9a01);	/* Set IO port */
 
 
-	id=mvv_read(3);
-	decst=pms_i2c_stat(0x43);
+	id = mvv_read(dev, 3);
+	decst = pms_i2c_stat(dev, 0x43);
 
-	if(decst!=-1)
-		idec=2;
-	else if(pms_i2c_stat(0xb9)!=-1)
-		idec=3;
-	else if(pms_i2c_stat(0x8b)!=-1)
-		idec=1;
+	if (decst != -1)
+		idec = 2;
+	else if (pms_i2c_stat(dev, 0xb9) != -1)
+		idec = 3;
+	else if (pms_i2c_stat(dev, 0x8b) != -1)
+		idec = 1;
 	else
-		idec=0;
+		idec = 0;
 
 	printk(KERN_INFO "PMS type is %d\n", idec);
-	if(idec == 0) {
-		release_region(io_port, 3);
-		release_region(0x9A01, 1);
-		iounmap(mem);
+	if (idec == 0) {
+		release_region(dev->io, 3);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
 		return -ENODEV;
 	}
 
@@ -981,51 +1033,50 @@ static int init_mediavision(void)
 	 *	Ok we have a PMS of some sort
 	 */
 
-	mvv_write(0x04, mem_base>>12);	/* Set the memory area */
+	mvv_write(dev, 0x04, mem_base >> 12);	/* Set the memory area */
 
 	/* Ok now load the defaults */
 
-	for(i=0;i<0x19;i++)
-	{
-		if(i2c_defs[i]==0xFF)
-			pms_i2c_andor(0x8A, i, 0x07,0x00);
+	for (i = 0; i < 0x19; i++) {
+		if (i2c_defs[i] == 0xff)
+			pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
 		else
-			pms_i2c_write(0x8A, i, i2c_defs[i]);
+			pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
 	}
 
-	pms_i2c_write(0xB8,0x00,0x12);
-	pms_i2c_write(0xB8,0x04,0x00);
-	pms_i2c_write(0xB8,0x07,0x00);
-	pms_i2c_write(0xB8,0x08,0x00);
-	pms_i2c_write(0xB8,0x09,0xFF);
-	pms_i2c_write(0xB8,0x0A,0x00);
-	pms_i2c_write(0xB8,0x0B,0x10);
-	pms_i2c_write(0xB8,0x10,0x03);
+	pms_i2c_write(dev, 0xb8, 0x00, 0x12);
+	pms_i2c_write(dev, 0xb8, 0x04, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x07, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x08, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x09, 0xff);
+	pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
+	pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
+	pms_i2c_write(dev, 0xb8, 0x10, 0x03);
 
-	mvv_write(0x01, 0x00);
-	mvv_write(0x05, 0xA0);
-	mvv_write(0x08, 0x25);
-	mvv_write(0x09, 0x00);
-	mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
+	mvv_write(dev, 0x01, 0x00);
+	mvv_write(dev, 0x05, 0xa0);
+	mvv_write(dev, 0x08, 0x25);
+	mvv_write(dev, 0x09, 0x00);
+	mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
 
-	mvv_write(0x10, 0x02);
-	mvv_write(0x1E, 0x0C);
-	mvv_write(0x1F, 0x03);
-	mvv_write(0x26, 0x06);
+	mvv_write(dev, 0x10, 0x02);
+	mvv_write(dev, 0x1e, 0x0c);
+	mvv_write(dev, 0x1f, 0x03);
+	mvv_write(dev, 0x26, 0x06);
 
-	mvv_write(0x2B, 0x00);
-	mvv_write(0x2C, 0x20);
-	mvv_write(0x2D, 0x00);
-	mvv_write(0x2F, 0x70);
-	mvv_write(0x32, 0x00);
-	mvv_write(0x33, MVVMEMORYWIDTH);
-	mvv_write(0x34, 0x00);
-	mvv_write(0x35, 0x00);
-	mvv_write(0x3A, 0x80);
-	mvv_write(0x3B, 0x10);
-	mvv_write(0x20, 0x00);
-	mvv_write(0x21, 0x00);
-	mvv_write(0x30, 0x22);
+	mvv_write(dev, 0x2b, 0x00);
+	mvv_write(dev, 0x2c, 0x20);
+	mvv_write(dev, 0x2d, 0x00);
+	mvv_write(dev, 0x2f, 0x70);
+	mvv_write(dev, 0x32, 0x00);
+	mvv_write(dev, 0x33, MVVMEMORYWIDTH);
+	mvv_write(dev, 0x34, 0x00);
+	mvv_write(dev, 0x35, 0x00);
+	mvv_write(dev, 0x3a, 0x80);
+	mvv_write(dev, 0x3b, 0x10);
+	mvv_write(dev, 0x20, 0x00);
+	mvv_write(dev, 0x21, 0x00);
+	mvv_write(dev, 0x30, 0x22);
 	return 0;
 }
 
@@ -1038,53 +1089,77 @@ static int enable;
 module_param(enable, int, 0);
 #endif
 
-static int __init init_pms_cards(void)
+static int __init pms_init(void)
 {
-	printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
+	struct pms *dev = &pms_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
+
+	v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
 
 #ifndef MODULE
 	if (!enable) {
-		printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to "
-				 "probe\n");
+		v4l2_err(v4l2_dev,
+			"PMS: not enabled, use pms.enable=1 to probe\n");
 		return -ENODEV;
 	}
 #endif
 
-	data_port = io_port +1;
+	dev->decoder = PHILIPS2;
+	dev->io = io_port;
+	dev->data = io_port + 1;
 
-	if(init_mediavision())
-	{
-		printk(KERN_INFO "Board not found.\n");
+	if (init_mediavision(dev)) {
+		v4l2_err(v4l2_dev, "Board not found.\n");
 		return -ENODEV;
 	}
-	memcpy(&pms_device, &pms_template, sizeof(pms_template));
-	mutex_init(&pms_device.lock);
-	pms_device.height=240;
-	pms_device.width=320;
-	pms_swsense(75);
-	pms_resolution(320,240);
-	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
-}
-
-module_param(io_port, int, 0);
-module_param(mem_base, int, 0);
-module_param(video_nr, int, 0);
-MODULE_LICENSE("GPL");
 
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
 
-static void __exit shutdown_mediavision(void)
-{
-	release_region(io_port,3);
-	release_region(0x9A01, 1);
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &pms_fops;
+	dev->vdev.ioctl_ops = &pms_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
+	mutex_init(&dev->lock);
+	dev->std = V4L2_STD_NTSC_M;
+	dev->height = 240;
+	dev->width = 320;
+	dev->depth = 15;
+	dev->brightness = 139;
+	dev->contrast = 70;
+	dev->hue = 0;
+	dev->saturation = 64;
+	pms_swsense(dev, 75);
+	pms_resolution(dev, 320, 240);
+	pms_videosource(dev, 0);
+	pms_vcrinput(dev, 0);
+	if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
+		v4l2_device_unregister(&dev->v4l2_dev);
+		release_region(dev->io, 3);
+		release_region(0x9a01, 1);
+		iounmap(dev->mem);
+		return -EINVAL;
+	}
+	return 0;
 }
 
-static void __exit cleanup_pms_module(void)
+static void __exit pms_exit(void)
 {
-	shutdown_mediavision();
-	video_unregister_device((struct video_device *)&pms_device);
-	iounmap(mem);
-}
+	struct pms *dev = &pms_card;
 
-module_init(init_pms_cards);
-module_exit(cleanup_pms_module);
+	video_unregister_device(&dev->vdev);
+	release_region(dev->io, 3);
+	release_region(0x9a01, 1);
+	iounmap(dev->mem);
+}
 
+module_init(pms_init);
+module_exit(pms_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,6 +142,9 @@ int pvr2_debugifc_print_info(struct pvr2
 {
 	int bcnt = 0;
 	int ccnt;
+	ccnt = scnprintf(buf, acnt, "Driver hardware description: %s\n",
+			 pvr2_hdw_get_desc(hdw));
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	ccnt = scnprintf(buf,acnt,"Driver state info:\n");
 	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
@@ -249,11 +252,15 @@ static int pvr2_debugifc_do1cmd(struct p
 			scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
 			if (scnt && wptr) {
 				count -= scnt; buf += scnt;
-				if (debugifc_match_keyword(wptr,wlen,"prom")) {
-					pvr2_hdw_cpufw_set_enabled(hdw,!0,!0);
-				} else if (debugifc_match_keyword(wptr,wlen,
-								  "ram")) {
-					pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
+				if (debugifc_match_keyword(wptr, wlen,
+							   "prom")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 2, !0);
+				} else if (debugifc_match_keyword(wptr, wlen,
+								  "ram8k")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 0, !0);
+				} else if (debugifc_match_keyword(wptr, wlen,
+								  "ram16k")) {
+					pvr2_hdw_cpufw_set_enabled(hdw, 1, !0);
 				} else {
 					return -EINVAL;
 				}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c	2013-05-03 13:58:37.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c	2013-05-03 12:07:09.000000000 -0400
@@ -58,7 +58,7 @@ static const char *pvr2_fw1_names_29xxx[
 };
 
 static const struct pvr2_device_desc pvr2_device_29xxx = {
-		.description = "WinTV PVR USB2 Model Category 29xxx",
+		.description = "WinTV PVR USB2 Model 29xxx",
 		.shortname = "29xxx",
 		.client_table.lst = pvr2_cli_29xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
@@ -91,7 +91,7 @@ static const char *pvr2_fw1_names_24xxx[
 };
 
 static const struct pvr2_device_desc pvr2_device_24xxx = {
-		.description = "WinTV PVR USB2 Model Category 24xxx",
+		.description = "WinTV PVR USB2 Model 24xxx",
 		.shortname = "24xxx",
 		.client_table.lst = pvr2_cli_24xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
@@ -340,7 +340,7 @@ static const char *pvr2_fw1_names_73xxx[
 };
 
 static const struct pvr2_device_desc pvr2_device_73xxx = {
-		.description = "WinTV HVR-1900 Model Category 73xxx",
+		.description = "WinTV HVR-1900 Model 73xxx",
 		.shortname = "73xxx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -351,6 +351,7 @@ static const struct pvr2_device_desc pvr
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
@@ -445,7 +446,7 @@ static const char *pvr2_fw1_names_75xxx[
 };
 
 static const struct pvr2_device_desc pvr2_device_750xx = {
-		.description = "WinTV HVR-1950 Model Category 750xx",
+		.description = "WinTV HVR-1950 Model 750xx",
 		.shortname = "750xx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -456,6 +457,7 @@ static const struct pvr2_device_desc pvr
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
@@ -467,7 +469,7 @@ static const struct pvr2_device_desc pvr
 };
 
 static const struct pvr2_device_desc pvr2_device_751xx = {
-		.description = "WinTV HVR-1950 Model Category 751xx",
+		.description = "WinTV HVR-1950 Model 751xx",
 		.shortname = "751xx",
 		.client_table.lst = pvr2_cli_73xxx,
 		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
@@ -478,6 +480,7 @@ static const struct pvr2_device_desc pvr
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
+		.flag_fx2_16kb = !0,
 		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
 		.default_std_mask = V4L2_STD_NTSC_M,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h	2010-02-24 13:52:17.000000000 -0500
@@ -176,6 +176,7 @@ struct pvr2_device_desc {
 	unsigned int flag_has_analogtuner:1;   /* Has analog tuner */
 	unsigned int flag_has_composite:1;     /* Has composite input */
 	unsigned int flag_has_svideo:1;        /* Has s-video input */
+	unsigned int flag_fx2_16kb:1;          /* 16KB FX2 firmware OK here */
 };
 
 extern struct usb_device_id pvr2_device_table[];
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c	2010-02-24 13:52:17.000000000 -0500
@@ -294,7 +294,10 @@ static int pvr2_encoder_cmd(void *ctxt,
 			pvr2_trace(
 				PVR2_TRACE_ERROR_LEGS,
 				"Giving up on command."
-				"  This is normally recovered by the driver.");
+				"  This is normally recovered via a firmware"
+				" reload and re-initialization; concern"
+				" is only warranted if this happens repeatedly"
+				" and rapidly.");
 			break;
 		}
 		wrData[0] = 0x7;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 13:58:35.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 12:07:07.000000000 -0400
@@ -1447,6 +1447,7 @@ static int pvr2_upload_firmware1(struct
 	const struct firmware *fw_entry = NULL;
 	void  *fw_ptr;
 	unsigned int pipe;
+	unsigned int fwsize;
 	int ret;
 	u16 address;
 
@@ -1473,9 +1474,21 @@ static int pvr2_upload_firmware1(struct
 	usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
 
 	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
+	fwsize = fw_entry->size;
 
-	if (fw_entry->size != 0x2000){
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
+	if ((fwsize != 0x2000) &&
+	    (!(hdw->hdw_desc->flag_fx2_16kb && (fwsize == 0x4000)))) {
+		if (hdw->hdw_desc->flag_fx2_16kb) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Wrong fx2 firmware size"
+				   " (expected 8192 or 16384, got %u)",
+				   fwsize);
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Wrong fx2 firmware size"
+				   " (expected 8192, got %u)",
+				   fwsize);
+		}
 		release_firmware(fw_entry);
 		return -ENOMEM;
 	}
@@ -1493,7 +1506,7 @@ static int pvr2_upload_firmware1(struct
 	   chunk. */
 
 	ret = 0;
-	for(address = 0; address < fw_entry->size; address += 0x800) {
+	for (address = 0; address < fwsize; address += 0x800) {
 		memcpy(fw_ptr, fw_entry->data + address, 0x800);
 		ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
 				       0, fw_ptr, 0x800, HZ);
@@ -1509,8 +1522,8 @@ static int pvr2_upload_firmware1(struct
 
 	trace_firmware("Upload done (%d bytes sent)",ret);
 
-	/* We should have written 8192 bytes */
-	if (ret == 8192) {
+	/* We should have written fwsize bytes */
+	if (ret == fwsize) {
 		hdw->fw1_state = FW1_STATE_RELOAD;
 		return 0;
 	}
@@ -2030,7 +2043,8 @@ static int pvr2_hdw_load_subdev(struct p
 	fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
 	if (!fname) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u for device %s has no name",
+			   "Module ID %u for device %s has no name?"
+			   "  The driver might have a configuration problem.",
 			   mid,
 			   hdw->hdw_desc->description);
 		return -EINVAL;
@@ -2058,7 +2072,8 @@ static int pvr2_hdw_load_subdev(struct p
 	if (!i2ccnt) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "Module ID %u (%s) for device %s:"
-			   " No i2c addresses",
+			   " No i2c addresses."
+			   "  The driver might have a configuration problem.",
 			   mid, fname, hdw->hdw_desc->description);
 		return -EINVAL;
 	}
@@ -2090,7 +2105,9 @@ static int pvr2_hdw_load_subdev(struct p
 
 	if (!sd) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Module ID %u (%s) for device %s failed to load",
+			   "Module ID %u (%s) for device %s failed to load."
+			   "  Possible missing sub-device kernel module or"
+			   " initialization failure within module.",
 			   mid, fname, hdw->hdw_desc->description);
 		return -EIO;
 	}
@@ -2132,7 +2149,10 @@ static void pvr2_hdw_load_modules(struct
 	for (idx = 0; idx < ct->cnt; idx++) {
 		if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
 	}
-	if (!okFl) pvr2_hdw_render_useless(hdw);
+	if (!okFl) {
+		hdw->flag_modulefail = !0;
+		pvr2_hdw_render_useless(hdw);
+	}
 }
 
 
@@ -2334,6 +2354,20 @@ static void pvr2_hdw_setup(struct pvr2_h
 				break;
 			}
 		}
+		if (hdw->flag_modulefail) {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"***WARNING*** pvrusb2 driver initialization"
+				" failed due to the failure of one or more"
+				" sub-device kernel modules.");
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"You need to resolve the failing condition"
+				" before this driver can function.  There"
+				" should be some earlier messages giving more"
+				" information about the problem.");
+			break;
+		}
 		if (procreload) {
 			pvr2_trace(
 				PVR2_TRACE_ERROR_LEGS,
@@ -2419,6 +2453,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 	hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
 	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
 		   hdw,hdw_desc->description);
+	pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
+		hdw_desc->description);
 	if (!hdw) goto fail;
 
 	init_timer(&hdw->quiescent_timer);
@@ -3480,7 +3516,7 @@ static u8 *pvr2_full_eeprom_fetch(struct
 
 
 void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
-				int prom_flag,
+				int mode,
 				int enable_flag)
 {
 	int ret;
@@ -3503,11 +3539,12 @@ void pvr2_hdw_cpufw_set_enabled(struct p
 			break;
 		}
 
-		hdw->fw_cpu_flag = (prom_flag == 0);
+		hdw->fw_cpu_flag = (mode != 2);
 		if (hdw->fw_cpu_flag) {
+			hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
 			pvr2_trace(PVR2_TRACE_FIRMWARE,
-				   "Preparing to suck out CPU firmware");
-			hdw->fw_size = 0x2000;
+				   "Preparing to suck out CPU firmware"
+				   " (size=%u)", hdw->fw_size);
 			hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
 			if (!hdw->fw_buffer) {
 				hdw->fw_size = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2010-02-24 13:52:17.000000000 -0500
@@ -219,7 +219,7 @@ int pvr2_hdw_get_stdenum_value(struct pv
    this may prevent the device from running (and leaving this mode may
    imply a device reset). */
 void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
-				int prom_flag,
+				int mode, /* 0=8KB FX2, 1=16KB FX2, 2=PROM */
 				int enable_flag);
 
 /* Return true if we're in a mode for retrieval CPU firmware */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2010-02-24 13:52:17.000000000 -0500
@@ -270,6 +270,7 @@ struct pvr2_hdw {
 
 	int force_dirty;        /* consider all controls dirty if true */
 	int flag_ok;            /* device in known good state */
+	int flag_modulefail;    /* true if at least one module failed to load */
 	int flag_disconnected;  /* flag_ok == 0 due to disconnect */
 	int flag_init_ok;       /* true if structure is fully initialized */
 	int fw1_state;          /* current situation with fw1 */
@@ -332,7 +333,7 @@ struct pvr2_hdw {
 
 	/* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */
 	unsigned int input_avail_mask;
-	/* Bit mask of PVR2_CVAL_INPUT choices which are currenly allowed */
+	/* Bit mask of PVR2_CVAL_INPUT choices which are currently allowed */
 	unsigned int input_allowed_mask;
 
 	/* Location of eeprom or a negative number if none */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,6 +50,7 @@ MODULE_PARM_DESC(disable_autoload_ir_vid
 
 /* Mapping of IR schemes to known I2C addresses - if any */
 static const unsigned char ir_video_addresses[] = {
+	[PVR2_IR_SCHEME_ZILOG] = 0x71,
 	[PVR2_IR_SCHEME_29XXX] = 0x18,
 	[PVR2_IR_SCHEME_24XXX] = 0x18,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2010-02-24 13:52:17.000000000 -0500
@@ -151,17 +151,6 @@ static struct v4l2_format pvr_format []
 };
 
 
-static const char *get_v4l_name(int v4l_type)
-{
-	switch (v4l_type) {
-	case VFL_TYPE_GRABBER: return "video";
-	case VFL_TYPE_RADIO: return "radio";
-	case VFL_TYPE_VBI: return "vbi";
-	default: return "?";
-	}
-}
-
-
 /*
  * pvr_ioctl()
  *
@@ -891,10 +880,8 @@ static long pvr2_v4l2_do_ioctl(struct fi
 
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 {
-	int num = dip->devbase.num;
 	struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
 	enum pvr2_config cfg = dip->config;
-	int v4l_type = dip->v4l_type;
 
 	pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
 
@@ -906,13 +893,22 @@ static void pvr2_v4l2_dev_destroy(struct
 	   are gone. */
 	video_unregister_device(&dip->devbase);
 
-	printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n",
-	       get_v4l_name(v4l_type), num,
+	printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n",
+	       video_device_node_name(&dip->devbase),
 	       pvr2_config_get_name(cfg));
 
 }
 
 
+static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
+{
+	if (!dip) return;
+	if (!dip->devbase.parent) return;
+	dip->devbase.parent = NULL;
+	device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
+}
+
+
 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 {
 	if (vp->dev_video) {
@@ -943,6 +939,8 @@ static void pvr2_v4l2_internal_check(str
 	struct pvr2_v4l2 *vp;
 	vp = container_of(chp,struct pvr2_v4l2,channel);
 	if (!vp->channel.mc_head->disconnect_flag) return;
+	pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
+	pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
 	if (vp->vfirst) return;
 	pvr2_v4l2_destroy_no_lock(vp);
 }
@@ -1250,12 +1248,13 @@ static void pvr2_v4l2_dev_init(struct pv
 			       struct pvr2_v4l2 *vp,
 			       int v4l_type)
 {
+	struct usb_device *usbdev;
 	int mindevnum;
 	int unit_number;
 	int *nr_ptr = NULL;
 	dip->v4lp = vp;
 
-
+	usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
 	dip->v4l_type = v4l_type;
 	switch (v4l_type) {
 	case VFL_TYPE_GRABBER:
@@ -1296,6 +1295,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;
 	if ((video_register_device(&dip->devbase,
 				   dip->v4l_type, mindevnum) < 0) &&
 	    (video_register_device(&dip->devbase,
@@ -1304,8 +1304,8 @@ static void pvr2_v4l2_dev_init(struct pv
 			": Failed to register pvrusb2 v4l device\n");
 	}
 
-	printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
-	       get_v4l_name(dip->v4l_type), dip->devbase.num,
+	printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
+	       video_device_node_name(&dip->devbase),
 	       pvr2_config_get_name(dip->config));
 
 	pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pwc/pwc-ctrl.c linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-ctrl.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pwc/pwc-ctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-ctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -753,7 +753,7 @@ int pwc_set_shutter_speed(struct pwc_dev
 		buf[0] = 0xff; /* fixed */
 
 	ret = send_control_msg(pdev,
-		SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf));
+		SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1);
 
 	if (!mode && ret >= 0) {
 		if (value < 0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pwc/pwc-if.c linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-if.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pwc/pwc-if.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pwc/pwc-if.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,6 +68,7 @@
 #endif
 #include <linux/vmalloc.h>
 #include <asm/io.h>
+#include <linux/kernel.h>		/* simple_strtol() */
 
 #include "pwc.h"
 #include "pwc-kiara.h"
@@ -168,7 +169,6 @@ static struct video_device pwc_template
 	.name =		"Philips Webcam",	/* Filled in later */
 	.release =	video_device_release,
 	.fops =         &pwc_fops,
-	.minor =        -1,
 };
 
 /***************************************************************************/
@@ -1806,7 +1806,7 @@ static int usb_pwc_probe(struct usb_inte
 		goto err_video_release;
 	}
 
-	PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
+	PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev));
 
 	/* occupy slot */
 	if (hint < MAX_DEV_HINTS)
@@ -1916,19 +1916,6 @@ disconnect_out:
 	unlock_kernel();
 }
 
-/* *grunt* We have to do atoi ourselves :-( */
-static int pwc_atoi(const char *s)
-{
-	int k = 0;
-
-	k = 0;
-	while (*s != '\0' && *s >= '0' && *s <= '9') {
-		k = 10 * k + (*s - '0');
-		s++;
-	}
-	return k;
-}
-
 
 /*
  * Initialization code & module stuff
@@ -1960,7 +1947,9 @@ MODULE_PARM_DESC(size, "Initial image si
 MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
 MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
 MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
+#ifdef CONFIG_USB_PWC_DEBUG
 MODULE_PARM_DESC(trace, "For debugging purposes");
+#endif
 MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
 MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
 MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
@@ -2078,13 +2067,16 @@ static int __init usb_pwc_init(void)
 				}
 				else {
 					/* No type or serial number specified, just a number. */
-					device_hint[i].device_node = pwc_atoi(s);
+					device_hint[i].device_node =
+						simple_strtol(s, NULL, 10);
 				}
 			}
 			else {
 				/* There's a colon, so we have at least a type and a device node */
-				device_hint[i].type = pwc_atoi(s);
-				device_hint[i].device_node = pwc_atoi(colon + 1);
+				device_hint[i].type =
+					simple_strtol(s, NULL, 10);
+				device_hint[i].device_node =
+					simple_strtol(colon + 1, NULL, 10);
 				if (*dot != '\0') {
 					/* There's a serial number as well */
 					int k;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/pxa_camera.c linux-libre-2.6.33-gnu1/drivers/media/video/pxa_camera.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/pxa_camera.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/pxa_camera.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-sg.h>
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 
 #include <linux/videodev2.h>
 
@@ -183,23 +184,21 @@ struct pxa_cam_dma {
 /* buffer for one video frame */
 struct pxa_buffer {
 	/* common v4l buffer stuff -- must be first */
-	struct videobuf_buffer vb;
-
-	const struct soc_camera_data_format        *fmt;
-
+	struct videobuf_buffer		vb;
+	enum v4l2_mbus_pixelcode	code;
 	/* our descriptor lists for Y, U and V channels */
-	struct pxa_cam_dma dmas[3];
-
-	int			inwork;
-
-	enum pxa_camera_active_dma active_dma;
+	struct pxa_cam_dma		dmas[3];
+	int				inwork;
+	enum pxa_camera_active_dma	active_dma;
 };
 
 struct pxa_camera_dev {
 	struct soc_camera_host	soc_host;
-	/* PXA27x is only supposed to handle one camera on its Quick Capture
+	/*
+	 * PXA27x is only supposed to handle one camera on its Quick Capture
 	 * interface. If anyone ever builds hardware to enable more than
-	 * one camera, they will have to modify this driver too */
+	 * one camera, they will have to modify this driver too
+	 */
 	struct soc_camera_device *icd;
 	struct clk		*clk;
 
@@ -241,11 +240,15 @@ static int pxa_videobuf_setup(struct vid
 			      unsigned int *size)
 {
 	struct soc_camera_device *icd = vq->priv_data;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+
+	if (bytes_per_line < 0)
+		return bytes_per_line;
 
 	dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
 
-	*size = roundup(icd->user_width * icd->user_height *
-			((icd->current_fmt->depth + 7) >> 3), 8);
+	*size = bytes_per_line * icd->user_height;
 
 	if (0 == *count)
 		*count = 32;
@@ -267,8 +270,10 @@ static void free_buffer(struct videobuf_
 	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		&buf->vb, buf->vb.baddr, buf->vb.bsize);
 
-	/* This waits until this buffer is out of danger, i.e., until it is no
-	 * longer in STATE_QUEUED or STATE_ACTIVE */
+	/*
+	 * This waits until this buffer is out of danger, i.e., until it is no
+	 * longer in STATE_QUEUED or STATE_ACTIVE
+	 */
 	videobuf_waiton(&buf->vb, 0, 0);
 	videobuf_dma_unmap(vq, dma);
 	videobuf_dma_free(dma);
@@ -429,6 +434,11 @@ static int pxa_videobuf_prepare(struct v
 	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
 	int ret;
 	int size_y, size_u = 0, size_v = 0;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
+
+	if (bytes_per_line < 0)
+		return bytes_per_line;
 
 	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
@@ -437,29 +447,33 @@ static int pxa_videobuf_prepare(struct v
 	WARN_ON(!list_empty(&vb->queue));
 
 #ifdef DEBUG
-	/* This can be useful if you want to see if we actually fill
-	 * the buffer with something */
+	/*
+	 * This can be useful if you want to see if we actually fill
+	 * the buffer with something
+	 */
 	memset((void *)vb->baddr, 0xaa, vb->bsize);
 #endif
 
 	BUG_ON(NULL == icd->current_fmt);
 
-	/* I think, in buf_prepare you only have to protect global data,
-	 * the actual buffer is yours */
+	/*
+	 * I think, in buf_prepare you only have to protect global data,
+	 * the actual buffer is yours
+	 */
 	buf->inwork = 1;
 
-	if (buf->fmt	!= icd->current_fmt ||
+	if (buf->code	!= icd->current_fmt->code ||
 	    vb->width	!= icd->user_width ||
 	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
-		buf->fmt	= icd->current_fmt;
+		buf->code	= icd->current_fmt->code;
 		vb->width	= icd->user_width;
 		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
 
-	vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+	vb->size = bytes_per_line * vb->height;
 	if (0 != vb->baddr && vb->bsize < vb->size) {
 		ret = -EINVAL;
 		goto out;
@@ -834,8 +848,10 @@ static void pxa_camera_init_videobuf(str
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
 
-	/* We must pass NULL as dev pointer, then all pci_* dma operations
-	 * transform to normal dma_* ones. */
+	/*
+	 * We must pass NULL as dev pointer, then all pci_* dma operations
+	 * transform to normal dma_* ones.
+	 */
 	videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
 				V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
 				sizeof(struct pxa_buffer), icd);
@@ -1051,11 +1067,18 @@ static void pxa_camera_setup_cicr(struct
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	unsigned long dw, bpp;
-	u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
+	u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top;
+	int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top);
 
-	/* Datawidth is now guaranteed to be equal to one of the three values.
-	 * We fix bit-per-pixel equal to data-width... */
+	if (ret < 0)
+		y_skip_top = 0;
+
+	/*
+	 * Datawidth is now guaranteed to be equal to one of the three values.
+	 * We fix bit-per-pixel equal to data-width...
+	 */
 	switch (flags & SOCAM_DATAWIDTH_MASK) {
 	case SOCAM_DATAWIDTH_10:
 		dw = 4;
@@ -1066,8 +1089,10 @@ static void pxa_camera_setup_cicr(struct
 		bpp = 0x20;
 		break;
 	default:
-		/* Actually it can only be 8 now,
-		 * default is just to silence compiler warnings */
+		/*
+		 * Actually it can only be 8 now,
+		 * default is just to silence compiler warnings
+		 */
 	case SOCAM_DATAWIDTH_8:
 		dw = 2;
 		bpp = 0;
@@ -1118,7 +1143,7 @@ static void pxa_camera_setup_cicr(struct
 
 	cicr2 = 0;
 	cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
-		CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
+		CICR3_BFW_VAL(min((u32)255, y_skip_top));
 	cicr4 |= pcdev->mclk_divisor;
 
 	__raw_writel(cicr1, pcdev->base + CICR1);
@@ -1138,9 +1163,15 @@ static int pxa_camera_set_bus_param(stru
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
 	unsigned long bus_flags, camera_flags, common_flags;
-	int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
+	const struct soc_mbus_pixelfmt *fmt;
+	int ret;
 	struct pxa_cam *cam = icd->host_priv;
 
+	fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
+	if (!fmt)
+		return -EINVAL;
+
+	ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
 	if (ret < 0)
 		return ret;
 
@@ -1204,59 +1235,49 @@ static int pxa_camera_try_bus_param(stru
 	return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL;
 }
 
-static const struct soc_camera_data_format pxa_camera_formats[] = {
+static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
 	{
-		.name		= "Planar YUV422 16 bit",
-		.depth		= 16,
-		.fourcc		= V4L2_PIX_FMT_YUV422P,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fourcc			= V4L2_PIX_FMT_YUV422P,
+		.name			= "Planar YUV422 16 bit",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
 	},
 };
 
-static bool buswidth_supported(struct soc_camera_device *icd, int depth)
-{
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
-
-	switch (depth) {
-	case 8:
-		return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8);
-	case 9:
-		return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9);
-	case 10:
-		return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10);
-	}
-	return false;
-}
-
-static int required_buswidth(const struct soc_camera_data_format *fmt)
+/* This will be corrected as we get more formats */
+static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
 {
-	switch (fmt->fourcc) {
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_YUYV:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_RGB565:
-	case V4L2_PIX_FMT_RGB555:
-		return 8;
-	default:
-		return fmt->depth;
-	}
+	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
+		(fmt->bits_per_sample == 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
+		(fmt->bits_per_sample > 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 }
 
 static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 				  struct soc_camera_format_xlate *xlate)
 {
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct device *dev = icd->dev.parent;
-	int formats = 0, buswidth, ret;
+	int formats = 0, ret;
 	struct pxa_cam *cam;
+	enum v4l2_mbus_pixelcode code;
+	const struct soc_mbus_pixelfmt *fmt;
 
-	buswidth = required_buswidth(icd->formats + idx);
+	ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+	if (ret < 0)
+		/* No more formats */
+		return 0;
 
-	if (!buswidth_supported(icd, buswidth))
+	fmt = soc_mbus_get_fmtdesc(code);
+	if (!fmt) {
+		dev_err(dev, "Invalid format code #%d: %d\n", idx, code);
 		return 0;
+	}
 
-	ret = pxa_camera_try_bus_param(icd, buswidth);
+	/* This also checks support for the requested bits-per-sample */
+	ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample);
 	if (ret < 0)
 		return 0;
 
@@ -1270,45 +1291,40 @@ static int pxa_camera_get_formats(struct
 		cam = icd->host_priv;
 	}
 
-	switch (icd->formats[idx].fourcc) {
-	case V4L2_PIX_FMT_UYVY:
+	switch (code) {
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
 		formats++;
 		if (xlate) {
-			xlate->host_fmt = &pxa_camera_formats[0];
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = buswidth;
+			xlate->host_fmt	= &pxa_camera_formats[0];
+			xlate->code	= code;
 			xlate++;
-			dev_dbg(dev, "Providing format %s using %s\n",
-				pxa_camera_formats[0].name,
-				icd->formats[idx].name);
+			dev_dbg(dev, "Providing format %s using code %d\n",
+				pxa_camera_formats[0].name, code);
 		}
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_YUYV:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_RGB565:
-	case V4L2_PIX_FMT_RGB555:
-		formats++;
-		if (xlate) {
-			xlate->host_fmt = icd->formats + idx;
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = buswidth;
-			xlate++;
+	case V4L2_MBUS_FMT_YVYU8_2X8_BE:
+	case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+	case V4L2_MBUS_FMT_YVYU8_2X8_LE:
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
+	case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+		if (xlate)
 			dev_dbg(dev, "Providing format %s packed\n",
-				icd->formats[idx].name);
-		}
+				fmt->name);
 		break;
 	default:
-		/* Generic pass-through */
-		formats++;
-		if (xlate) {
-			xlate->host_fmt = icd->formats + idx;
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = icd->formats[idx].depth;
-			xlate++;
+		if (!pxa_camera_packing_supported(fmt))
+			return 0;
+		if (xlate)
 			dev_dbg(dev,
 				"Providing format %s in pass-through mode\n",
-				icd->formats[idx].name);
-		}
+				fmt->name);
+	}
+
+	/* Generic pass-through */
+	formats++;
+	if (xlate) {
+		xlate->host_fmt	= fmt;
+		xlate->code	= code;
+		xlate++;
 	}
 
 	return formats;
@@ -1320,11 +1336,11 @@ static void pxa_camera_put_formats(struc
 	icd->host_priv = NULL;
 }
 
-static int pxa_camera_check_frame(struct v4l2_pix_format *pix)
+static int pxa_camera_check_frame(u32 width, u32 height)
 {
 	/* limit to pxa hardware capabilities */
-	return pix->height < 32 || pix->height > 2048 || pix->width < 48 ||
-		pix->width > 2048 || (pix->width & 0x01);
+	return height < 32 || height > 2048 || width < 48 || width > 2048 ||
+		(width & 0x01);
 }
 
 static int pxa_camera_set_crop(struct soc_camera_device *icd,
@@ -1339,9 +1355,9 @@ static int pxa_camera_set_crop(struct so
 		.master_clock = pcdev->mclk,
 		.pixel_clock_max = pcdev->ciclk / 4,
 	};
-	struct v4l2_format f;
-	struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
+	struct v4l2_mbus_framefmt mf;
 	struct pxa_cam *cam = icd->host_priv;
+	u32 fourcc = icd->current_fmt->host_fmt->fourcc;
 	int ret;
 
 	/* If PCLK is used to latch data from the sensor, check sense */
@@ -1358,27 +1374,23 @@ static int pxa_camera_set_crop(struct so
 		return ret;
 	}
 
-	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 	if (ret < 0)
 		return ret;
 
-	pix_tmp = *pix;
-	if (pxa_camera_check_frame(pix)) {
+	if (pxa_camera_check_frame(mf.width, mf.height)) {
 		/*
 		 * Camera cropping produced a frame beyond our capabilities.
 		 * FIXME: just extract a subframe, that we can process.
 		 */
-		v4l_bound_align_image(&pix->width, 48, 2048, 1,
-			&pix->height, 32, 2048, 0,
-			icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?
-				4 : 0);
-		ret = v4l2_subdev_call(sd, video, s_fmt, &f);
+		v4l_bound_align_image(&mf.width, 48, 2048, 1,
+			&mf.height, 32, 2048, 0,
+			fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
+		ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
 		if (ret < 0)
 			return ret;
 
-		if (pxa_camera_check_frame(pix)) {
+		if (pxa_camera_check_frame(mf.width, mf.height)) {
 			dev_warn(icd->dev.parent,
 				 "Inconsistent state. Use S_FMT to repair\n");
 			return -EINVAL;
@@ -1395,10 +1407,10 @@ static int pxa_camera_set_crop(struct so
 		recalculate_fifo_timeout(pcdev, sense.pixel_clock);
 	}
 
-	icd->user_width = pix->width;
-	icd->user_height = pix->height;
+	icd->user_width		= mf.width;
+	icd->user_height	= mf.height;
 
-	pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc);
+	pxa_camera_setup_cicr(icd, cam->flags, fourcc);
 
 	return ret;
 }
@@ -1410,14 +1422,13 @@ static int pxa_camera_set_fmt(struct soc
 	struct pxa_camera_dev *pcdev = ici->priv;
 	struct device *dev = icd->dev.parent;
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	const struct soc_camera_data_format *cam_fmt = NULL;
 	const struct soc_camera_format_xlate *xlate = NULL;
 	struct soc_camera_sense sense = {
 		.master_clock = pcdev->mclk,
 		.pixel_clock_max = pcdev->ciclk / 4,
 	};
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct v4l2_format cam_f = *f;
+	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -1426,26 +1437,31 @@ static int pxa_camera_set_fmt(struct soc
 		return -EINVAL;
 	}
 
-	cam_fmt = xlate->cam_fmt;
-
 	/* If PCLK is used to latch data from the sensor, check sense */
 	if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
+		/* The caller holds a mutex. */
 		icd->sense = &sense;
 
-	cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
-	ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f);
-	cam_f.fmt.pix.pixelformat = pix->pixelformat;
-	*pix = cam_f.fmt.pix;
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
+
+	ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+
+	if (mf.code != xlate->code)
+		return -EINVAL;
 
 	icd->sense = NULL;
 
 	if (ret < 0) {
 		dev_warn(dev, "Failed to configure for format %x\n",
 			 pix->pixelformat);
-	} else if (pxa_camera_check_frame(pix)) {
+	} else if (pxa_camera_check_frame(mf.width, mf.height)) {
 		dev_warn(dev,
 			 "Camera driver produced an unsupported frame %dx%d\n",
-			 pix->width, pix->height);
+			 mf.width, mf.height);
 		ret = -EINVAL;
 	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
@@ -1457,10 +1473,14 @@ static int pxa_camera_set_fmt(struct soc
 		recalculate_fifo_timeout(pcdev, sense.pixel_clock);
 	}
 
-	if (!ret) {
-		icd->buswidth = xlate->buswidth;
-		icd->current_fmt = xlate->host_fmt;
-	}
+	if (ret < 0)
+		return ret;
+
+	pix->width		= mf.width;
+	pix->height		= mf.height;
+	pix->field		= mf.field;
+	pix->colorspace		= mf.colorspace;
+	icd->current_fmt	= xlate;
 
 	return ret;
 }
@@ -1468,17 +1488,16 @@ static int pxa_camera_set_fmt(struct soc
 static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 			      struct v4l2_format *f)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	__u32 pixfmt = pix->pixelformat;
-	enum v4l2_field field;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
+		dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -1492,22 +1511,36 @@ static int pxa_camera_try_fmt(struct soc
 			      &pix->height, 32, 2048, 0,
 			      pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
 
-	pix->bytesperline = pix->width *
-		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+	pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
+						    xlate->host_fmt);
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
 	pix->sizeimage = pix->height * pix->bytesperline;
 
-	/* camera has to see its format, but the user the original one */
-	pix->pixelformat = xlate->cam_fmt->fourcc;
 	/* limit to sensor capabilities */
-	ret = v4l2_subdev_call(sd, video, try_fmt, f);
-	pix->pixelformat = pixfmt;
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
 
-	field = pix->field;
+	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+	if (ret < 0)
+		return ret;
 
-	if (field == V4L2_FIELD_ANY) {
-		pix->field = V4L2_FIELD_NONE;
-	} else if (field != V4L2_FIELD_NONE) {
-		dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
+	pix->width	= mf.width;
+	pix->height	= mf.height;
+	pix->colorspace	= mf.colorspace;
+
+	switch (mf.field) {
+	case V4L2_FIELD_ANY:
+	case V4L2_FIELD_NONE:
+		pix->field	= V4L2_FIELD_NONE;
+		break;
+	default:
+		/* TODO: support interlaced at least in pass-through mode */
+		dev_err(icd->dev.parent, "Field type %d unsupported.\n",
+			mf.field);
 		return -EINVAL;
 	}
 
@@ -1519,10 +1552,12 @@ static int pxa_camera_reqbufs(struct soc
 {
 	int i;
 
-	/* This is for locking debugging only. I removed spinlocks and now I
+	/*
+	 * This is for locking debugging only. I removed spinlocks and now I
 	 * check whether .prepare is ever called on a linked buffer, or whether
 	 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
-	 * it hadn't triggered */
+	 * it hadn't triggered
+	 */
 	for (i = 0; i < p->count; i++) {
 		struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i],
 						      struct pxa_buffer, vb);
@@ -1657,8 +1692,10 @@ static int __devinit pxa_camera_probe(st
 	pcdev->platform_flags = pcdev->pdata->flags;
 	if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 |
 			PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) {
-		/* Platform hasn't set available data widths. This is bad.
-		 * Warn and use a default. */
+		/*
+		 * Platform hasn't set available data widths. This is bad.
+		 * Warn and use a default.
+		 */
 		dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
 			 "data widths, using default 10 bit\n");
 		pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/rj54n1cb0c.c linux-libre-2.6.33-gnu1/drivers/media/video/rj54n1cb0c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/rj54n1cb0c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/rj54n1cb0c.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1501 @@
+/*
+ * Driver for RJ54N1CB0C CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2009, 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/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+
+#include <media/rj54n1cb0c.h>
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-chip-ident.h>
+
+#define RJ54N1_DEV_CODE			0x0400
+#define RJ54N1_DEV_CODE2		0x0401
+#define RJ54N1_OUT_SEL			0x0403
+#define RJ54N1_XY_OUTPUT_SIZE_S_H	0x0404
+#define RJ54N1_X_OUTPUT_SIZE_S_L	0x0405
+#define RJ54N1_Y_OUTPUT_SIZE_S_L	0x0406
+#define RJ54N1_XY_OUTPUT_SIZE_P_H	0x0407
+#define RJ54N1_X_OUTPUT_SIZE_P_L	0x0408
+#define RJ54N1_Y_OUTPUT_SIZE_P_L	0x0409
+#define RJ54N1_LINE_LENGTH_PCK_S_H	0x040a
+#define RJ54N1_LINE_LENGTH_PCK_S_L	0x040b
+#define RJ54N1_LINE_LENGTH_PCK_P_H	0x040c
+#define RJ54N1_LINE_LENGTH_PCK_P_L	0x040d
+#define RJ54N1_RESIZE_N			0x040e
+#define RJ54N1_RESIZE_N_STEP		0x040f
+#define RJ54N1_RESIZE_STEP		0x0410
+#define RJ54N1_RESIZE_HOLD_H		0x0411
+#define RJ54N1_RESIZE_HOLD_L		0x0412
+#define RJ54N1_H_OBEN_OFS		0x0413
+#define RJ54N1_V_OBEN_OFS		0x0414
+#define RJ54N1_RESIZE_CONTROL		0x0415
+#define RJ54N1_STILL_CONTROL		0x0417
+#define RJ54N1_INC_USE_SEL_H		0x0425
+#define RJ54N1_INC_USE_SEL_L		0x0426
+#define RJ54N1_MIRROR_STILL_MODE	0x0427
+#define RJ54N1_INIT_START		0x0428
+#define RJ54N1_SCALE_1_2_LEV		0x0429
+#define RJ54N1_SCALE_4_LEV		0x042a
+#define RJ54N1_Y_GAIN			0x04d8
+#define RJ54N1_APT_GAIN_UP		0x04fa
+#define RJ54N1_RA_SEL_UL		0x0530
+#define RJ54N1_BYTE_SWAP		0x0531
+#define RJ54N1_OUT_SIGPO		0x053b
+#define RJ54N1_WB_SEL_WEIGHT_I		0x054e
+#define RJ54N1_BIT8_WB			0x0569
+#define RJ54N1_HCAPS_WB			0x056a
+#define RJ54N1_VCAPS_WB			0x056b
+#define RJ54N1_HCAPE_WB			0x056c
+#define RJ54N1_VCAPE_WB			0x056d
+#define RJ54N1_EXPOSURE_CONTROL		0x058c
+#define RJ54N1_FRAME_LENGTH_S_H		0x0595
+#define RJ54N1_FRAME_LENGTH_S_L		0x0596
+#define RJ54N1_FRAME_LENGTH_P_H		0x0597
+#define RJ54N1_FRAME_LENGTH_P_L		0x0598
+#define RJ54N1_PEAK_H			0x05b7
+#define RJ54N1_PEAK_50			0x05b8
+#define RJ54N1_PEAK_60			0x05b9
+#define RJ54N1_PEAK_DIFF		0x05ba
+#define RJ54N1_IOC			0x05ef
+#define RJ54N1_TG_BYPASS		0x0700
+#define RJ54N1_PLL_L			0x0701
+#define RJ54N1_PLL_N			0x0702
+#define RJ54N1_PLL_EN			0x0704
+#define RJ54N1_RATIO_TG			0x0706
+#define RJ54N1_RATIO_T			0x0707
+#define RJ54N1_RATIO_R			0x0708
+#define RJ54N1_RAMP_TGCLK_EN		0x0709
+#define RJ54N1_OCLK_DSP			0x0710
+#define RJ54N1_RATIO_OP			0x0711
+#define RJ54N1_RATIO_O			0x0712
+#define RJ54N1_OCLK_SEL_EN		0x0713
+#define RJ54N1_CLK_RST			0x0717
+#define RJ54N1_RESET_STANDBY		0x0718
+#define RJ54N1_FWFLG			0x07fe
+
+#define E_EXCLK				(1 << 7)
+#define SOFT_STDBY			(1 << 4)
+#define SEN_RSTX			(1 << 2)
+#define TG_RSTX				(1 << 1)
+#define DSP_RSTX			(1 << 0)
+
+#define RESIZE_HOLD_SEL			(1 << 2)
+#define RESIZE_GO			(1 << 1)
+
+/*
+ * When cropping, the camera automatically centers the cropped region, there
+ * doesn't seem to be a way to specify an explicit location of the rectangle.
+ */
+#define RJ54N1_COLUMN_SKIP		0
+#define RJ54N1_ROW_SKIP			0
+#define RJ54N1_MAX_WIDTH		1600
+#define RJ54N1_MAX_HEIGHT		1200
+
+#define PLL_L				2
+#define PLL_N				0x31
+
+/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
+
+/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
+struct rj54n1_datafmt {
+	enum v4l2_mbus_pixelcode	code;
+	enum v4l2_colorspace		colorspace;
+};
+
+/* Find a data format by a pixel code in an array */
+static const struct rj54n1_datafmt *rj54n1_find_datafmt(
+	enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt,
+	int n)
+{
+	int i;
+	for (i = 0; i < n; i++)
+		if (fmt[i].code == code)
+			return fmt + i;
+
+	return NULL;
+}
+
+static const struct rj54n1_datafmt rj54n1_colour_fmts[] = {
+	{V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG},
+	{V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB},
+	{V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+};
+
+struct rj54n1_clock_div {
+	u8 ratio_tg;	/* can be 0 or an odd number */
+	u8 ratio_t;
+	u8 ratio_r;
+	u8 ratio_op;
+	u8 ratio_o;
+};
+
+struct rj54n1 {
+	struct v4l2_subdev subdev;
+	struct rj54n1_clock_div clk_div;
+	const struct rj54n1_datafmt *fmt;
+	struct v4l2_rect rect;	/* Sensor window */
+	unsigned int tgclk_mhz;
+	bool auto_wb;
+	unsigned short width;	/* Output window */
+	unsigned short height;
+	unsigned short resize;	/* Sensor * 1024 / resize = Output */
+	unsigned short scale;
+	u8 bank;
+};
+
+struct rj54n1_reg_val {
+	u16 reg;
+	u8 val;
+};
+
+const static struct rj54n1_reg_val bank_4[] = {
+	{0x417, 0},
+	{0x42c, 0},
+	{0x42d, 0xf0},
+	{0x42e, 0},
+	{0x42f, 0x50},
+	{0x430, 0xf5},
+	{0x431, 0x16},
+	{0x432, 0x20},
+	{0x433, 0},
+	{0x434, 0xc8},
+	{0x43c, 8},
+	{0x43e, 0x90},
+	{0x445, 0x83},
+	{0x4ba, 0x58},
+	{0x4bb, 4},
+	{0x4bc, 0x20},
+	{0x4db, 4},
+	{0x4fe, 2},
+};
+
+const static struct rj54n1_reg_val bank_5[] = {
+	{0x514, 0},
+	{0x516, 0},
+	{0x518, 0},
+	{0x51a, 0},
+	{0x51d, 0xff},
+	{0x56f, 0x28},
+	{0x575, 0x40},
+	{0x5bc, 0x48},
+	{0x5c1, 6},
+	{0x5e5, 0x11},
+	{0x5e6, 0x43},
+	{0x5e7, 0x33},
+	{0x5e8, 0x21},
+	{0x5e9, 0x30},
+	{0x5ea, 0x0},
+	{0x5eb, 0xa5},
+	{0x5ec, 0xff},
+	{0x5fe, 2},
+};
+
+const static struct rj54n1_reg_val bank_7[] = {
+	{0x70a, 0},
+	{0x714, 0xff},
+	{0x715, 0xff},
+	{0x716, 0x1f},
+	{0x7FE, 2},
+};
+
+const static struct rj54n1_reg_val bank_8[] = {
+	{0x800, 0x00},
+	{0x801, 0x01},
+	{0x802, 0x61},
+	{0x805, 0x00},
+	{0x806, 0x00},
+	{0x807, 0x00},
+	{0x808, 0x00},
+	{0x809, 0x01},
+	{0x80A, 0x61},
+	{0x80B, 0x00},
+	{0x80C, 0x01},
+	{0x80D, 0x00},
+	{0x80E, 0x00},
+	{0x80F, 0x00},
+	{0x810, 0x00},
+	{0x811, 0x01},
+	{0x812, 0x61},
+	{0x813, 0x00},
+	{0x814, 0x11},
+	{0x815, 0x00},
+	{0x816, 0x41},
+	{0x817, 0x00},
+	{0x818, 0x51},
+	{0x819, 0x01},
+	{0x81A, 0x1F},
+	{0x81B, 0x00},
+	{0x81C, 0x01},
+	{0x81D, 0x00},
+	{0x81E, 0x11},
+	{0x81F, 0x00},
+	{0x820, 0x41},
+	{0x821, 0x00},
+	{0x822, 0x51},
+	{0x823, 0x00},
+	{0x824, 0x00},
+	{0x825, 0x00},
+	{0x826, 0x47},
+	{0x827, 0x01},
+	{0x828, 0x4F},
+	{0x829, 0x00},
+	{0x82A, 0x00},
+	{0x82B, 0x00},
+	{0x82C, 0x30},
+	{0x82D, 0x00},
+	{0x82E, 0x40},
+	{0x82F, 0x00},
+	{0x830, 0xB3},
+	{0x831, 0x00},
+	{0x832, 0xE3},
+	{0x833, 0x00},
+	{0x834, 0x00},
+	{0x835, 0x00},
+	{0x836, 0x00},
+	{0x837, 0x00},
+	{0x838, 0x00},
+	{0x839, 0x01},
+	{0x83A, 0x61},
+	{0x83B, 0x00},
+	{0x83C, 0x01},
+	{0x83D, 0x00},
+	{0x83E, 0x00},
+	{0x83F, 0x00},
+	{0x840, 0x00},
+	{0x841, 0x01},
+	{0x842, 0x61},
+	{0x843, 0x00},
+	{0x844, 0x1D},
+	{0x845, 0x00},
+	{0x846, 0x00},
+	{0x847, 0x00},
+	{0x848, 0x00},
+	{0x849, 0x01},
+	{0x84A, 0x1F},
+	{0x84B, 0x00},
+	{0x84C, 0x05},
+	{0x84D, 0x00},
+	{0x84E, 0x19},
+	{0x84F, 0x01},
+	{0x850, 0x21},
+	{0x851, 0x01},
+	{0x852, 0x5D},
+	{0x853, 0x00},
+	{0x854, 0x00},
+	{0x855, 0x00},
+	{0x856, 0x19},
+	{0x857, 0x01},
+	{0x858, 0x21},
+	{0x859, 0x00},
+	{0x85A, 0x00},
+	{0x85B, 0x00},
+	{0x85C, 0x00},
+	{0x85D, 0x00},
+	{0x85E, 0x00},
+	{0x85F, 0x00},
+	{0x860, 0xB3},
+	{0x861, 0x00},
+	{0x862, 0xE3},
+	{0x863, 0x00},
+	{0x864, 0x00},
+	{0x865, 0x00},
+	{0x866, 0x00},
+	{0x867, 0x00},
+	{0x868, 0x00},
+	{0x869, 0xE2},
+	{0x86A, 0x00},
+	{0x86B, 0x01},
+	{0x86C, 0x06},
+	{0x86D, 0x00},
+	{0x86E, 0x00},
+	{0x86F, 0x00},
+	{0x870, 0x60},
+	{0x871, 0x8C},
+	{0x872, 0x10},
+	{0x873, 0x00},
+	{0x874, 0xE0},
+	{0x875, 0x00},
+	{0x876, 0x27},
+	{0x877, 0x01},
+	{0x878, 0x00},
+	{0x879, 0x00},
+	{0x87A, 0x00},
+	{0x87B, 0x03},
+	{0x87C, 0x00},
+	{0x87D, 0x00},
+	{0x87E, 0x00},
+	{0x87F, 0x00},
+	{0x880, 0x00},
+	{0x881, 0x00},
+	{0x882, 0x00},
+	{0x883, 0x00},
+	{0x884, 0x00},
+	{0x885, 0x00},
+	{0x886, 0xF8},
+	{0x887, 0x00},
+	{0x888, 0x03},
+	{0x889, 0x00},
+	{0x88A, 0x64},
+	{0x88B, 0x00},
+	{0x88C, 0x03},
+	{0x88D, 0x00},
+	{0x88E, 0xB1},
+	{0x88F, 0x00},
+	{0x890, 0x03},
+	{0x891, 0x01},
+	{0x892, 0x1D},
+	{0x893, 0x00},
+	{0x894, 0x03},
+	{0x895, 0x01},
+	{0x896, 0x4B},
+	{0x897, 0x00},
+	{0x898, 0xE5},
+	{0x899, 0x00},
+	{0x89A, 0x01},
+	{0x89B, 0x00},
+	{0x89C, 0x01},
+	{0x89D, 0x04},
+	{0x89E, 0xC8},
+	{0x89F, 0x00},
+	{0x8A0, 0x01},
+	{0x8A1, 0x01},
+	{0x8A2, 0x61},
+	{0x8A3, 0x00},
+	{0x8A4, 0x01},
+	{0x8A5, 0x00},
+	{0x8A6, 0x00},
+	{0x8A7, 0x00},
+	{0x8A8, 0x00},
+	{0x8A9, 0x00},
+	{0x8AA, 0x7F},
+	{0x8AB, 0x03},
+	{0x8AC, 0x00},
+	{0x8AD, 0x00},
+	{0x8AE, 0x00},
+	{0x8AF, 0x00},
+	{0x8B0, 0x00},
+	{0x8B1, 0x00},
+	{0x8B6, 0x00},
+	{0x8B7, 0x01},
+	{0x8B8, 0x00},
+	{0x8B9, 0x00},
+	{0x8BA, 0x02},
+	{0x8BB, 0x00},
+	{0x8BC, 0xFF},
+	{0x8BD, 0x00},
+	{0x8FE, 2},
+};
+
+const static struct rj54n1_reg_val bank_10[] = {
+	{0x10bf, 0x69}
+};
+
+/* Clock dividers - these are default register values, divider = register + 1 */
+const static struct rj54n1_clock_div clk_div = {
+	.ratio_tg	= 3 /* default: 5 */,
+	.ratio_t	= 4 /* default: 1 */,
+	.ratio_r	= 4 /* default: 0 */,
+	.ratio_op	= 1 /* default: 5 */,
+	.ratio_o	= 9 /* default: 0 */,
+};
+
+static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
+}
+
+static int reg_read(struct i2c_client *client, const u16 reg)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* set bank */
+	if (rj54n1->bank != reg >> 8) {
+		dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+		ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+		if (ret < 0)
+			return ret;
+		rj54n1->bank = reg >> 8;
+	}
+	return i2c_smbus_read_byte_data(client, reg & 0xff);
+}
+
+static int reg_write(struct i2c_client *client, const u16 reg,
+		     const u8 data)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* set bank */
+	if (rj54n1->bank != reg >> 8) {
+		dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+		ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+		if (ret < 0)
+			return ret;
+		rj54n1->bank = reg >> 8;
+	}
+	dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
+	return i2c_smbus_write_byte_data(client, reg & 0xff, data);
+}
+
+static int reg_set(struct i2c_client *client, const u16 reg,
+		   const u8 data, const u8 mask)
+{
+	int ret;
+
+	ret = reg_read(client, reg);
+	if (ret < 0)
+		return ret;
+	return reg_write(client, reg, (ret & ~mask) | (data & mask));
+}
+
+static int reg_write_multiple(struct i2c_client *client,
+			      const struct rj54n1_reg_val *rv, const int n)
+{
+	int i, ret;
+
+	for (i = 0; i < n; i++) {
+		ret = reg_write(client, rv->reg, rv->val);
+		if (ret < 0)
+			return ret;
+		rv++;
+	}
+
+	return 0;
+}
+
+static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts))
+		return -EINVAL;
+
+	*code = rj54n1_colour_fmts[index].code;
+	return 0;
+}
+
+static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct i2c_client *client = sd->priv;
+
+	/* Switch between preview and still shot modes */
+	return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
+}
+
+static int rj54n1_set_bus_param(struct soc_camera_device *icd,
+				unsigned long flags)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct i2c_client *client = sd->priv;
+	/* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
+
+	if (flags & SOCAM_PCLK_SAMPLE_RISING)
+		return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
+	else
+		return reg_write(client, RJ54N1_OUT_SIGPO, 0);
+}
+
+static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
+{
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	const unsigned long flags =
+		SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
+		SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
+		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
+		SOCAM_DATA_ACTIVE_HIGH;
+
+	return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int rj54n1_set_rect(struct i2c_client *client,
+			   u16 reg_x, u16 reg_y, u16 reg_xy,
+			   u32 width, u32 height)
+{
+	int ret;
+
+	ret = reg_write(client, reg_xy,
+			((width >> 4) & 0x70) |
+			((height >> 8) & 7));
+
+	if (!ret)
+		ret = reg_write(client, reg_x, width & 0xff);
+	if (!ret)
+		ret = reg_write(client, reg_y, height & 0xff);
+
+	return ret;
+}
+
+/*
+ * Some commands, specifically certain initialisation sequences, require
+ * a commit operation.
+ */
+static int rj54n1_commit(struct i2c_client *client)
+{
+	int ret = reg_write(client, RJ54N1_INIT_START, 1);
+	msleep(10);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_INIT_START, 0);
+	return ret;
+}
+
+static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
+			       u32 *out_w, u32 *out_h);
+
+static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	struct v4l2_rect *rect = &a->c;
+	unsigned int dummy = 0, output_w, output_h,
+		input_w = rect->width, input_h = rect->height;
+	int ret;
+
+	/* arbitrary minimum width and height, edges unimportant */
+	soc_camera_limit_side(&dummy, &input_w,
+		     RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
+
+	soc_camera_limit_side(&dummy, &input_h,
+		     RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT);
+
+	output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
+	output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
+
+	dev_dbg(&client->dev, "Scaling for %ux%u : %u = %ux%u\n",
+		input_w, input_h, rj54n1->resize, output_w, output_h);
+
+	ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
+	if (ret < 0)
+		return ret;
+
+	rj54n1->width		= output_w;
+	rj54n1->height		= output_h;
+	rj54n1->resize		= ret;
+	rj54n1->rect.width	= input_w;
+	rj54n1->rect.height	= input_h;
+
+	return 0;
+}
+
+static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+	a->c	= rj54n1->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= RJ54N1_COLUMN_SKIP;
+	a->bounds.top			= RJ54N1_ROW_SKIP;
+	a->bounds.width			= RJ54N1_MAX_WIDTH;
+	a->bounds.height		= RJ54N1_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int rj54n1_g_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+	mf->code	= rj54n1->fmt->code;
+	mf->colorspace	= rj54n1->fmt->colorspace;
+	mf->field	= V4L2_FIELD_NONE;
+	mf->width	= rj54n1->width;
+	mf->height	= rj54n1->height;
+
+	return 0;
+}
+
+/*
+ * The actual geometry configuration routine. It scales the input window into
+ * the output one, updates the window sizes and returns an error or the resize
+ * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
+ */
+static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
+			       u32 *out_w, u32 *out_h)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
+		output_w = *out_w, output_h = *out_h;
+	u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom;
+	unsigned int peak, peak_50, peak_60;
+	int ret;
+
+	/*
+	 * We have a problem with crops, where the window is larger than 512x384
+	 * and output window is larger than a half of the input one. In this
+	 * case we have to either reduce the input window to equal or below
+	 * 512x384 or the output window to equal or below 1/2 of the input.
+	 */
+	if (output_w > max(512U, input_w / 2)) {
+		if (2 * output_w > RJ54N1_MAX_WIDTH) {
+			input_w = RJ54N1_MAX_WIDTH;
+			output_w = RJ54N1_MAX_WIDTH / 2;
+		} else {
+			input_w = output_w * 2;
+		}
+
+		dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n",
+			input_w, output_w);
+	}
+
+	if (output_h > max(384U, input_h / 2)) {
+		if (2 * output_h > RJ54N1_MAX_HEIGHT) {
+			input_h = RJ54N1_MAX_HEIGHT;
+			output_h = RJ54N1_MAX_HEIGHT / 2;
+		} else {
+			input_h = output_h * 2;
+		}
+
+		dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n",
+			input_h, output_h);
+	}
+
+	/* Idea: use the read mode for snapshots, handle separate geometries */
+	ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
+			      RJ54N1_Y_OUTPUT_SIZE_S_L,
+			      RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
+	if (!ret)
+		ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
+			      RJ54N1_Y_OUTPUT_SIZE_P_L,
+			      RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
+
+	if (ret < 0)
+		return ret;
+
+	if (output_w > input_w && output_h > input_h) {
+		input_w = output_w;
+		input_h = output_h;
+
+		resize = 1024;
+	} else {
+		unsigned int resize_x, resize_y;
+		resize_x = (input_w * 1024 + output_w / 2) / output_w;
+		resize_y = (input_h * 1024 + output_h / 2) / output_h;
+
+		/* We want max(resize_x, resize_y), check if it still fits */
+		if (resize_x > resize_y &&
+		    (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT)
+			resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) /
+				output_h;
+		else if (resize_y > resize_x &&
+			 (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH)
+			resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) /
+				output_w;
+		else
+			resize = max(resize_x, resize_y);
+
+		/* Prohibited value ranges */
+		switch (resize) {
+		case 2040 ... 2047:
+			resize = 2039;
+			break;
+		case 4080 ... 4095:
+			resize = 4079;
+			break;
+		case 8160 ... 8191:
+			resize = 8159;
+			break;
+		case 16320 ... 16384:
+			resize = 16319;
+		}
+	}
+
+	/* Set scaling */
+	ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Configure a skipping bitmask. The sensor will select a skipping value
+	 * among set bits automatically. This is very unclear in the datasheet
+	 * too. I was told, in this register one enables all skipping values,
+	 * that are required for a specific resize, and the camera selects
+	 * automatically, which ones to use. But it is unclear how to identify,
+	 * which cropping values are needed. Secondly, why don't we just set all
+	 * bits and let the camera choose? Would it increase processing time and
+	 * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to
+	 * improve the image quality or stability for larger frames (see comment
+	 * above), but I didn't check the framerate.
+	 */
+	skip = min(resize / 1024, (unsigned)15);
+
+	inc_sel = 1 << skip;
+
+	if (inc_sel <= 2)
+		inc_sel = 0xc;
+	else if (resize & 1023 && skip < 15)
+		inc_sel |= 1 << (skip + 1);
+
+	ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
+
+	if (!rj54n1->auto_wb) {
+		/* Auto white balance window */
+		wb_left	  = output_w / 16;
+		wb_right  = (3 * output_w / 4 - 3) / 4;
+		wb_top	  = output_h / 16;
+		wb_bottom = (3 * output_h / 4 - 3) / 4;
+		wb_bit8	  = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) |
+			((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1);
+
+		if (!ret)
+			ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom);
+	}
+
+	/* Antiflicker */
+	peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz /
+		10000;
+	peak_50 = peak / 6;
+	peak_60 = peak / 5;
+
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PEAK_H,
+				((peak_50 >> 4) & 0xf0) | (peak_60 >> 8));
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PEAK_50, peak_50);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PEAK_60, peak_60);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150);
+
+	/* Start resizing */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+				RESIZE_HOLD_SEL | RESIZE_GO | 1);
+
+	if (ret < 0)
+		return ret;
+
+	/* Constant taken from manufacturer's example */
+	msleep(230);
+
+	ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
+	if (ret < 0)
+		return ret;
+
+	*in_w = (output_w * resize + 512) / 1024;
+	*in_h = (output_h * resize + 512) / 1024;
+	*out_w = output_w;
+	*out_h = output_h;
+
+	dev_dbg(&client->dev, "Scaled for %ux%u : %u = %ux%u, skip %u\n",
+		*in_w, *in_h, resize, output_w, output_h, skip);
+
+	return resize;
+}
+
+static int rj54n1_set_clock(struct i2c_client *client)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret;
+
+	/* Enable external clock */
+	ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
+	/* Leave stand-by. Note: use this when implementing suspend / resume */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
+
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_L, PLL_L);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_N, PLL_N);
+
+	/* TGCLK dividers */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_TG,
+				rj54n1->clk_div.ratio_tg);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_T,
+				rj54n1->clk_div.ratio_t);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_R,
+				rj54n1->clk_div.ratio_r);
+
+	/* Enable TGCLK & RAMP */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
+
+	/* Disable clock output */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
+
+	/* Set divisors */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_OP,
+				rj54n1->clk_div.ratio_op);
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RATIO_O,
+				rj54n1->clk_div.ratio_o);
+
+	/* Enable OCLK */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+	/* Use PLL for Timing Generator, write 2 to reserved bits */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
+
+	/* Take sensor out of reset */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | SEN_RSTX);
+	/* Enable PLL */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_PLL_EN, 1);
+
+	/* Wait for PLL to stabilise */
+	msleep(10);
+
+	/* Enable clock to frequency divider */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_CLK_RST, 1);
+
+	if (!ret)
+		ret = reg_read(client, RJ54N1_CLK_RST);
+	if (ret != 1) {
+		dev_err(&client->dev,
+			"Resetting RJ54N1CB0C clock failed: %d!\n", ret);
+		return -EIO;
+	}
+
+	/* Start the PLL */
+	ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
+
+	/* Enable OCLK */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+	return ret;
+}
+
+static int rj54n1_reg_init(struct i2c_client *client)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int ret = rj54n1_set_clock(client);
+
+	if (!ret)
+		ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
+	if (!ret)
+		ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
+
+	/* Set binning divisors */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
+	if (!ret)
+		ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
+
+	/* Switch to fixed resize mode */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+				RESIZE_HOLD_SEL | 1);
+
+	/* Set gain */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
+
+	/*
+	 * Mirror the image back: default is upside down and left-to-right...
+	 * Set manual preview / still shot switching
+	 */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27);
+
+	if (!ret)
+		ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
+
+	/* Auto exposure area */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80);
+	/* Check current auto WB config */
+	if (!ret)
+		ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I);
+	if (ret >= 0) {
+		rj54n1->auto_wb = ret & 0x80;
+		ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
+	}
+	if (!ret)
+		ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
+
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | DSP_RSTX | SEN_RSTX);
+
+	/* Commit init */
+	if (!ret)
+		ret = rj54n1_commit(client);
+
+	/* Take DSP, TG, sensor out of reset */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_RESET_STANDBY,
+				E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
+
+	/* Start register update? Same register as 0x?FE in many bank_* sets */
+	if (!ret)
+		ret = reg_write(client, RJ54N1_FWFLG, 2);
+
+	/* Constant taken from manufacturer's example */
+	msleep(700);
+
+	return ret;
+}
+
+static int rj54n1_try_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	const struct rj54n1_datafmt *fmt;
+	int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE ||
+		mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE;
+
+	dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
+		__func__, mf->code, mf->width, mf->height);
+
+	fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
+				  ARRAY_SIZE(rj54n1_colour_fmts));
+	if (!fmt) {
+		fmt = rj54n1->fmt;
+		mf->code = fmt->code;
+	}
+
+	mf->field	= V4L2_FIELD_NONE;
+	mf->colorspace	= fmt->colorspace;
+
+	v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
+			      &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
+
+	return 0;
+}
+
+static int rj54n1_s_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	const struct rj54n1_datafmt *fmt;
+	unsigned int output_w, output_h, max_w, max_h,
+		input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
+	int ret;
+
+	/*
+	 * The host driver can call us without .try_fmt(), so, we have to take
+	 * care ourseleves
+	 */
+	rj54n1_try_fmt(sd, mf);
+
+	/*
+	 * Verify if the sensor has just been powered on. TODO: replace this
+	 * with proper PM, when a suitable API is available.
+	 */
+	ret = reg_read(client, RJ54N1_RESET_STANDBY);
+	if (ret < 0)
+		return ret;
+
+	if (!(ret & E_EXCLK)) {
+		ret = rj54n1_reg_init(client);
+		if (ret < 0)
+			return ret;
+	}
+
+	dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
+		__func__, mf->code, mf->width, mf->height);
+
+	/* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
+	switch (mf->code) {
+	case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		break;
+	case V4L2_MBUS_FMT_YVYU8_2X8_LE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+		break;
+	case V4L2_MBUS_FMT_RGB565_2X8_LE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		break;
+	case V4L2_MBUS_FMT_RGB565_2X8_BE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+		break;
+	case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
+		break;
+	case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
+		break;
+	case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
+		break;
+	case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+		if (!ret)
+			ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+		if (!ret)
+			ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
+		break;
+	case V4L2_MBUS_FMT_SBGGR10_1X10:
+		ret = reg_write(client, RJ54N1_OUT_SEL, 5);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	/* Special case: a raw mode with 10 bits of data per clock tick */
+	if (!ret)
+		ret = reg_set(client, RJ54N1_OCLK_SEL_EN,
+			      (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2);
+
+	if (ret < 0)
+		return ret;
+
+	/* Supported scales 1:1 >= scale > 1:16 */
+	max_w = mf->width * (16 * 1024 - 1) / 1024;
+	if (input_w > max_w)
+		input_w = max_w;
+	max_h = mf->height * (16 * 1024 - 1) / 1024;
+	if (input_h > max_h)
+		input_h = max_h;
+
+	output_w = mf->width;
+	output_h = mf->height;
+
+	ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
+	if (ret < 0)
+		return ret;
+
+	fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
+				  ARRAY_SIZE(rj54n1_colour_fmts));
+
+	rj54n1->fmt		= fmt;
+	rj54n1->resize		= ret;
+	rj54n1->rect.width	= input_w;
+	rj54n1->rect.height	= input_h;
+	rj54n1->width		= output_w;
+	rj54n1->height		= output_h;
+
+	mf->width		= output_w;
+	mf->height		= output_h;
+	mf->field		= V4L2_FIELD_NONE;
+	mf->colorspace		= fmt->colorspace;
+
+	return 0;
+}
+
+static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_chip_ident *id)
+{
+	struct i2c_client *client = sd->priv;
+
+	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 = sd->priv;
+
+	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
+	    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);
+
+	if (reg->val > 0xff)
+		return -EIO;
+
+	return 0;
+}
+
+static int rj54n1_s_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = sd->priv;
+
+	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
+	    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;
+
+	return 0;
+}
+#endif
+
+static const struct v4l2_queryctrl rj54n1_controls[] = {
+	{
+		.id		= V4L2_CID_VFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Vertically",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	}, {
+		.id		= V4L2_CID_HFLIP,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Flip Horizontally",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	}, {
+		.id		= V4L2_CID_GAIN,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Gain",
+		.minimum	= 0,
+		.maximum	= 127,
+		.step		= 1,
+		.default_value	= 66,
+		.flags		= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.id		= V4L2_CID_AUTO_WHITE_BALANCE,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Auto white balance",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 1,
+	},
+};
+
+static struct soc_camera_ops rj54n1_ops = {
+	.set_bus_param		= rj54n1_set_bus_param,
+	.query_bus_param	= rj54n1_query_bus_param,
+	.controls		= rj54n1_controls,
+	.num_controls		= ARRAY_SIZE(rj54n1_controls),
+};
+
+static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	int data;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
+		if (data < 0)
+			return -EIO;
+		ctrl->value = !(data & 1);
+		break;
+	case V4L2_CID_HFLIP:
+		data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
+		if (data < 0)
+			return -EIO;
+		ctrl->value = !(data & 2);
+		break;
+	case V4L2_CID_GAIN:
+		data = reg_read(client, RJ54N1_Y_GAIN);
+		if (data < 0)
+			return -EIO;
+
+		ctrl->value = data / 2;
+		break;
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ctrl->value = rj54n1->auto_wb;
+		break;
+	}
+
+	return 0;
+}
+
+static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	int data;
+	struct i2c_client *client = sd->priv;
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	const struct v4l2_queryctrl *qctrl;
+
+	qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
+	if (!qctrl)
+		return -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		if (ctrl->value)
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
+		else
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
+		if (data < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_HFLIP:
+		if (ctrl->value)
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
+		else
+			data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
+		if (data < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_GAIN:
+		if (ctrl->value > qctrl->maximum ||
+		    ctrl->value < qctrl->minimum)
+			return -EINVAL;
+		else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
+			return -EIO;
+		break;
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		/* Auto WB area - whole image */
+		if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7,
+			    0x80) < 0)
+			return -EIO;
+		rj54n1->auto_wb = ctrl->value;
+		break;
+	}
+
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
+	.g_ctrl		= rj54n1_g_ctrl,
+	.s_ctrl		= rj54n1_s_ctrl,
+	.g_chip_ident	= rj54n1_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= rj54n1_g_register,
+	.s_register	= rj54n1_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
+	.s_stream	= rj54n1_s_stream,
+	.s_mbus_fmt	= rj54n1_s_fmt,
+	.g_mbus_fmt	= rj54n1_g_fmt,
+	.try_mbus_fmt	= rj54n1_try_fmt,
+	.enum_mbus_fmt	= rj54n1_enum_fmt,
+	.g_crop		= rj54n1_g_crop,
+	.s_crop		= rj54n1_s_crop,
+	.cropcap	= rj54n1_cropcap,
+};
+
+static struct v4l2_subdev_ops rj54n1_subdev_ops = {
+	.core	= &rj54n1_subdev_core_ops,
+	.video	= &rj54n1_subdev_video_ops,
+};
+
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int rj54n1_video_probe(struct soc_camera_device *icd,
+			      struct i2c_client *client,
+			      struct rj54n1_pdata *priv)
+{
+	int data1, data2;
+	int ret;
+
+	/* This could be a BUG_ON() or a WARN_ON(), or remove it completely */
+	if (!icd->dev.parent ||
+	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+		return -ENODEV;
+
+	/* Read out the chip version register */
+	data1 = reg_read(client, RJ54N1_DEV_CODE);
+	data2 = reg_read(client, RJ54N1_DEV_CODE2);
+
+	if (data1 != 0x51 || data2 != 0x10) {
+		ret = -ENODEV;
+		dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
+			 data1, data2);
+		goto ei2c;
+	}
+
+	/* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
+	ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
+	if (ret < 0)
+		goto ei2c;
+
+	dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
+		 data1, data2);
+
+ei2c:
+	return ret;
+}
+
+static int rj54n1_probe(struct i2c_client *client,
+			const struct i2c_device_id *did)
+{
+	struct rj54n1 *rj54n1;
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct soc_camera_link *icl;
+	struct rj54n1_pdata *rj54n1_priv;
+	int ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
+	if (!icl || !icl->priv) {
+		dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
+		return -EINVAL;
+	}
+
+	rj54n1_priv = icl->priv;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_warn(&adapter->dev,
+			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
+		return -EIO;
+	}
+
+	rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL);
+	if (!rj54n1)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
+
+	icd->ops		= &rj54n1_ops;
+
+	rj54n1->clk_div		= clk_div;
+	rj54n1->rect.left	= RJ54N1_COLUMN_SKIP;
+	rj54n1->rect.top	= RJ54N1_ROW_SKIP;
+	rj54n1->rect.width	= RJ54N1_MAX_WIDTH;
+	rj54n1->rect.height	= RJ54N1_MAX_HEIGHT;
+	rj54n1->width		= RJ54N1_MAX_WIDTH;
+	rj54n1->height		= RJ54N1_MAX_HEIGHT;
+	rj54n1->fmt		= &rj54n1_colour_fmts[0];
+	rj54n1->resize		= 1024;
+	rj54n1->tgclk_mhz	= (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
+		(clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
+
+	ret = rj54n1_video_probe(icd, client, rj54n1_priv);
+	if (ret < 0) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(rj54n1);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int rj54n1_remove(struct i2c_client *client)
+{
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+
+	icd->ops = NULL;
+	if (icl->free_bus)
+		icl->free_bus(icl);
+	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
+	kfree(rj54n1);
+
+	return 0;
+}
+
+static const struct i2c_device_id rj54n1_id[] = {
+	{ "rj54n1cb0c", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, rj54n1_id);
+
+static struct i2c_driver rj54n1_i2c_driver = {
+	.driver = {
+		.name = "rj54n1cb0c",
+	},
+	.probe		= rj54n1_probe,
+	.remove		= rj54n1_remove,
+	.id_table	= rj54n1_id,
+};
+
+static int __init rj54n1_mod_init(void)
+{
+	return i2c_add_driver(&rj54n1_i2c_driver);
+}
+
+static void __exit rj54n1_mod_exit(void)
+{
+	i2c_del_driver(&rj54n1_i2c_driver);
+}
+
+module_init(rj54n1_mod_init);
+module_exit(rj54n1_mod_exit);
+
+MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/s2255drv.c linux-libre-2.6.33-gnu1/drivers/media/video/s2255drv.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/s2255drv.c	2013-05-03 13:58:58.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/s2255drv.c	2013-05-03 12:07:31.000000000 -0400
@@ -233,7 +233,6 @@ struct s2255_dev {
 
 	struct s2255_dmaqueue	vidq[MAX_CHANNELS];
 	struct video_device	*vdev[MAX_CHANNELS];
-	struct list_head	s2255_devlist;
 	struct timer_list	timer;
 	struct s2255_fw	*fw_data;
 	struct s2255_pipeinfo	pipes[MAX_PIPE_BUFFERS];
@@ -313,8 +312,6 @@ struct s2255_fh {
 /* Channels on box are in reverse order */
 static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
 
-static LIST_HEAD(s2255_devlist);
-
 static int debug;
 static int *s2255_debug = &debug;
 
@@ -1533,32 +1530,24 @@ static int vidioc_s_parm(struct file *fi
 }
 static int s2255_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct s2255_dev *h, *dev = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct s2255_dev *dev = video_drvdata(file);
 	struct s2255_fh *fh;
-	struct list_head *list;
-	enum v4l2_buf_type type = 0;
+	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	int i = 0;
 	int cur_channel = -1;
 	int state;
-	dprintk(1, "s2255: open called (minor=%d)\n", minor);
+
+	dprintk(1, "s2255: open called (dev=%s)\n",
+		video_device_node_name(vdev));
 
 	lock_kernel();
-	list_for_each(list, &s2255_devlist) {
-		h = list_entry(list, struct s2255_dev, s2255_devlist);
-		for (i = 0; i < MAX_CHANNELS; i++) {
-			if (h->vdev[i]->minor == minor) {
-				cur_channel = i;
-				dev = h;
-				type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			}
-		}
-	}
 
-	if ((NULL == dev) || (cur_channel == -1)) {
-		unlock_kernel();
-		printk(KERN_INFO "s2255: openv4l no dev\n");
-		return -ENODEV;
+	for (i = 0; i < MAX_CHANNELS; i++) {
+		if (dev->vdev[i] == vdev) {
+			cur_channel = i;
+			break;
+		}
 	}
 
 	if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) {
@@ -1662,8 +1651,9 @@ static int s2255_open(struct file *file)
 	for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
 		qctl_regs[i] = s2255_qctrl[i].default_value;
 
-	dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n",
-		minor, v4l2_type_names[type], dev->users[cur_channel]);
+	dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n",
+		video_device_node_name(vdev), v4l2_type_names[type],
+		dev->users[cur_channel]);
 	dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
 		(unsigned long)fh, (unsigned long)dev,
 		(unsigned long)&dev->vidq[cur_channel]);
@@ -1699,7 +1689,6 @@ static unsigned int s2255_poll(struct fi
 static void s2255_destroy(struct kref *kref)
 {
 	struct s2255_dev *dev = to_s2255_dev(kref);
-	struct list_head *list;
 	int i;
 	if (!dev) {
 		printk(KERN_ERR "s2255drv: kref problem\n");
@@ -1733,10 +1722,6 @@ static void s2255_destroy(struct kref *k
 	usb_put_dev(dev->udev);
 	dprintk(1, "%s", __func__);
 
-	while (!list_empty(&s2255_devlist)) {
-		list = s2255_devlist.next;
-		list_del(list);
-	}
 	mutex_unlock(&dev->open_lock);
 	kfree(dev);
 }
@@ -1745,7 +1730,8 @@ static int s2255_close(struct file *file
 {
 	struct s2255_fh *fh = file->private_data;
 	struct s2255_dev *dev = fh->dev;
-	int minor = video_devdata(file)->minor;
+	struct video_device *vdev = video_devdata(file);
+
 	if (!dev)
 		return -ENODEV;
 
@@ -1765,8 +1751,8 @@ static int s2255_close(struct file *file
 	mutex_unlock(&dev->open_lock);
 
 	kref_put(&dev->kref, s2255_destroy);
-	dprintk(1, "s2255: close called (minor=%d, users=%d)\n",
-		minor, dev->users[fh->channel]);
+	dprintk(1, "s2255: close called (dev=%s, users=%d)\n",
+		video_device_node_name(vdev), dev->users[fh->channel]);
 	kfree(fh);
 	return 0;
 }
@@ -1830,7 +1816,6 @@ static struct video_device template = {
 	.name = "s2255v",
 	.fops = &s2255_fops_v4l,
 	.ioctl_ops = &s2255_ioctl_ops,
-	.minor = -1,
 	.release = video_device_release,
 	.tvnorms = S2255_NORMS,
 	.current_norm = V4L2_STD_NTSC_M,
@@ -1843,7 +1828,6 @@ static int s2255_probe_v4l(struct s2255_
 	int cur_nr = video_nr;
 
 	/* initialize all video 4 linux */
-	list_add_tail(&dev->s2255_devlist, &s2255_devlist);
 	/* register 4 video devices */
 	for (i = 0; i < MAX_CHANNELS; i++) {
 		INIT_LIST_HEAD(&dev->vidq[i].active);
@@ -1853,6 +1837,7 @@ static int s2255_probe_v4l(struct s2255_
 		dev->vdev[i] = video_device_alloc();
 		memcpy(dev->vdev[i], &template, sizeof(struct video_device));
 		dev->vdev[i]->parent = &dev->interface->dev;
+		video_set_drvdata(dev->vdev[i], dev);
 		if (video_nr == -1)
 			ret = video_register_device(dev->vdev[i],
 						    VFL_TYPE_GRABBER,
@@ -1880,7 +1865,7 @@ static void s2255_exit_v4l(struct s2255_
 
 	int i;
 	for (i = 0; i < MAX_CHANNELS; i++) {
-		if (-1 != dev->vdev[i]->minor) {
+		if (video_is_registered(dev->vdev[i])) {
 			video_unregister_device(dev->vdev[i]);
 			printk(KERN_INFO "s2255 unregistered\n");
 		} else {
@@ -1958,7 +1943,7 @@ static int save_frame(struct s2255_dev *
 				if (pdword[1] >= MAX_CHANNELS)
 					break;
 				cc = G_chnmap[pdword[1]];
-				if (!(cc >= 0 && cc < MAX_CHANNELS))
+				if (cc >= MAX_CHANNELS)
 					break;
 				switch (pdword[2]) {
 				case S2255_RESPONSE_SETMODE:
@@ -1980,7 +1965,7 @@ static int save_frame(struct s2255_dev *
 					wake_up(&dev->fw_data->wait_fw);
 					break;
 				default:
-					printk(KERN_INFO "s2255 unknwn resp\n");
+					printk(KERN_INFO "s2255 unknown resp\n");
 				}
 			default:
 				pdata++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa5246a.c linux-libre-2.6.33-gnu1/drivers/media/video/saa5246a.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa5246a.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa5246a.c	2010-02-24 13:52:17.000000000 -0500
@@ -1036,7 +1036,6 @@ static struct video_device saa_template
 	.name	  = "saa5246a",
 	.fops	  = &saa_fops,
 	.release  = video_device_release,
-	.minor    = -1,
 };
 
 static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7110.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7110.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7110.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7110.c	2010-02-24 13:52:17.000000000 -0500
@@ -304,7 +304,7 @@ static int saa7110_s_routing(struct v4l2
 {
 	struct saa7110 *decoder = to_saa7110(sd);
 
-	if (input < 0 || input >= SAA7110_MAX_INPUT) {
+	if (input >= SAA7110_MAX_INPUT) {
 		v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-cards.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-cards.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 13:56:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 12:03:49.000000000 -0400
@@ -5239,6 +5239,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs         = { {
 			.name = name_tv,
 			.vmux = 2,
@@ -5279,6 +5280,46 @@ struct saa7134_board saa7134_boards[] =
 			.amux = TV,
 		},
 	},
+	[SAA7134_BOARD_ASUS_EUROPA_HYBRID] = {
+		.name           = "Asus Europa Hybrid OEM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TD1316,
+		.radio_type     = UNSET,
+		.tuner_addr	= 0x61,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs = { {
+			.name   = name_tv,
+			.vmux   = 3,
+			.amux   = TV,
+			.tv     = 1,
+		}, {
+			.name   = name_comp1,
+			.vmux   = 4,
+			.amux   = LINE2,
+		}, {
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE2,
+		} },
+	},
+	[SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S] = {
+		.name           = "Leadtek Winfast DTV1000S",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs         = { {
+			.name = name_comp1,
+			.vmux = 3,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+		} },
+	},
 
 };
 
@@ -6418,6 +6459,18 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.subdevice    = 0x2004,
 		.driver_data  = SAA7134_BOARD_ZOLID_HYBRID_PCI,
 	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1043,
+		.subdevice    = 0x4847,
+		.driver_data  = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x107d,
+		.subdevice    = 0x6655,
+		.driver_data  = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
+	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6748,6 +6801,7 @@ int saa7134_board_init1(struct saa7134_d
 	case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
 	case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
@@ -7079,6 +7133,7 @@ int saa7134_board_init2(struct saa7134_d
 		/* break intentionally omitted */
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
+	case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
 	{
 
 		/* The Philips EUROPA based hybrid boards have the tuner
@@ -7156,9 +7211,31 @@ int saa7134_board_init2(struct saa7134_d
 	}
 	case SAA7134_BOARD_FLYDVB_TRIO:
 	{
+		u8 temp = 0;
+		int rc;
 		u8 data[] = { 0x3c, 0x33, 0x62};
 		struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
 		i2c_transfer(&dev->i2c_adap, &msg, 1);
+
+		/*
+		 * send weak up message to pic16C505 chip
+		 * @ LifeView FlyDVB Trio
+		 */
+		msg.buf = &temp;
+		msg.addr = 0x0b;
+		msg.len = 1;
+		if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) {
+			printk(KERN_WARNING "%s: send wake up byte to pic16C505"
+					"(IR chip) failed\n", dev->name);
+		} else {
+			msg.flags = I2C_M_RD;
+			rc = i2c_transfer(&dev->i2c_adap, &msg, 1);
+			printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n",
+				   dev->name, msg.addr,
+				   (1 == rc) ? "yes" : "no");
+			if (rc == 1)
+				dev->has_remote = SAA7134_REMOTE_I2C;
+		}
 		break;
 	}
 	case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-core.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -420,19 +420,6 @@ int saa7134_set_dmabits(struct saa7134_d
 		ctrl |= SAA7134_MAIN_CTRL_TE5;
 		irq  |= SAA7134_IRQ1_INTE_RA2_1 |
 			SAA7134_IRQ1_INTE_RA2_0;
-
-		/* dma: setup channel 5 (= TS) */
-
-		saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
-		saa_writeb(SAA7134_TS_DMA1,
-			((dev->ts.nr_packets - 1) >> 8) & 0xff);
-		/* TSNOPIT=0, TSCOLAP=0 */
-		saa_writeb(SAA7134_TS_DMA2,
-			(((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
-		saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
-		saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
-						  SAA7134_RS_CONTROL_ME |
-						  (dev->ts.pt_ts.dma >> 12));
 	}
 
 	/* set task conditions + field handling */
@@ -797,27 +784,28 @@ static struct video_device *vdev_init(st
 	vfd->debug   = video_debug;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 dev->name, type, saa7134_boards[dev->board].name);
+	video_set_drvdata(vfd, dev);
 	return vfd;
 }
 
 static void saa7134_unregister_video(struct saa7134_dev *dev)
 {
 	if (dev->video_dev) {
-		if (-1 != dev->video_dev->minor)
+		if (video_is_registered(dev->video_dev))
 			video_unregister_device(dev->video_dev);
 		else
 			video_device_release(dev->video_dev);
 		dev->video_dev = NULL;
 	}
 	if (dev->vbi_dev) {
-		if (-1 != dev->vbi_dev->minor)
+		if (video_is_registered(dev->vbi_dev))
 			video_unregister_device(dev->vbi_dev);
 		else
 			video_device_release(dev->vbi_dev);
 		dev->vbi_dev = NULL;
 	}
 	if (dev->radio_dev) {
-		if (-1 != dev->radio_dev->minor)
+		if (video_is_registered(dev->radio_dev))
 			video_unregister_device(dev->radio_dev);
 		else
 			video_device_release(dev->radio_dev);
@@ -1032,7 +1020,7 @@ static int __devinit saa7134_initdev(str
 	saa7134_irq_video_signalchange(dev);
 
 	if (TUNER_ABSENT != dev->tuner_type)
-		saa_call_all(dev, tuner, s_standby);
+		saa_call_all(dev, core, s_power, 0);
 
 	/* register v4l devices */
 	if (saa7134_no_overlay > 0)
@@ -1046,8 +1034,8 @@ static int __devinit saa7134_initdev(str
 		       dev->name);
 		goto fail4;
 	}
-	printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
-	       dev->name, dev->video_dev->num);
+	printk(KERN_INFO "%s: registered device %s [v4l2]\n",
+	       dev->name, video_device_node_name(dev->video_dev));
 
 	dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
 
@@ -1055,8 +1043,8 @@ static int __devinit saa7134_initdev(str
 				    vbi_nr[dev->nr]);
 	if (err < 0)
 		goto fail4;
-	printk(KERN_INFO "%s: registered device vbi%d\n",
-	       dev->name, dev->vbi_dev->num);
+	printk(KERN_INFO "%s: registered device %s\n",
+	       dev->name, video_device_node_name(dev->vbi_dev));
 
 	if (card_has_radio(dev)) {
 		dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
@@ -1064,8 +1052,8 @@ static int __devinit saa7134_initdev(str
 					    radio_nr[dev->nr]);
 		if (err < 0)
 			goto fail4;
-		printk(KERN_INFO "%s: registered device radio%d\n",
-		       dev->name, dev->radio_dev->num);
+		printk(KERN_INFO "%s: registered device %s\n",
+		       dev->name, video_device_node_name(dev->radio_dev));
 	}
 
 	/* everything worked */
@@ -1319,7 +1307,7 @@ static struct pci_driver saa7134_pci_dri
 #endif
 };
 
-static int saa7134_init(void)
+static int __init saa7134_init(void)
 {
 	INIT_LIST_HEAD(&saa7134_devlist);
 	printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
@@ -1333,7 +1321,7 @@ static int saa7134_init(void)
 	return pci_register_driver(&saa7134_pci_driver);
 }
 
-static void saa7134_fini(void)
+static void __exit saa7134_fini(void)
 {
 	pci_unregister_driver(&saa7134_pci_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 13:58:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 12:07:21.000000000 -0400
@@ -40,6 +40,7 @@
 #include "tda1004x.h"
 #include "nxt200x.h"
 #include "tuner-xc2028.h"
+#include "xc5000.h"
 
 #include "tda10086.h"
 #include "tda826x.h"
@@ -871,6 +872,20 @@ static struct zl10353_config behold_h6_c
 	.disable_i2c_gate_ctrl = 1,
 };
 
+static struct xc5000_config behold_x7_tunerconfig = {
+	.i2c_address      = 0xc2>>1,
+	.if_khz           = 4560,
+	.radio_input      = XC5000_RADIO_FM1,
+};
+
+static struct zl10353_config behold_x7_config = {
+	.demod_address = 0x1e>>1,
+	.if2           = 45600,
+	.no_tuner      = 1,
+	.parallel_ts   = 1,
+	.disable_i2c_gate_ctrl = 1,
+};
+
 /* ==================================================================
  * tda10086 based DVB-S cards, helper functions
  */
@@ -1030,6 +1045,32 @@ static struct tda18271_config zolid_tda1
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
+static struct tda10048_config dtv1000s_tda10048_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_PARALLEL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3800,
+	.dtv8_if_freq_khz = TDA10048_IF_4300,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+	.disable_gate_access = 1,
+};
+
+static struct tda18271_std_map dtv1000s_tda18271_std_map = {
+	.dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config dtv1000s_tda18271_config = {
+	.std_map = &dtv1000s_tda18271_std_map,
+	.gate    = TDA18271_GATE_ANALOG,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -1116,6 +1157,7 @@ static int dvb_init(struct saa7134_dev *
 		break;
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+	case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
 		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &philips_europa_config,
 					       &dev->i2c_adap);
@@ -1482,6 +1524,15 @@ static int dvb_init(struct saa7134_dev *
 				   TUNER_PHILIPS_FMD1216MEX_MK3);
 		}
 		break;
+	case SAA7134_BOARD_BEHOLD_X7:
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
+						&behold_x7_config,
+						&dev->i2c_adap);
+		if (fe0->dvb.frontend) {
+			dvb_attach(xc5000_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, &behold_x7_tunerconfig);
+		}
+		break;
 	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
 	case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
 		/* Zarlink ZL10313 */
@@ -1518,6 +1569,19 @@ static int dvb_init(struct saa7134_dev *
 				   &zolid_tda18271_config);
 		}
 		break;
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
+					       &dtv1000s_tda10048_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, 0x4b,
+				   &tda829x_no_probe);
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_adap,
+				   &dtv1000s_tda18271_config);
+		}
+		break;
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		break;
@@ -1550,7 +1614,7 @@ static int dvb_init(struct saa7134_dev *
 
 	/* register everything else */
 	ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
-		&dev->pci->dev, adapter_nr, 0);
+					&dev->pci->dev, adapter_nr, 0, NULL);
 
 	/* this sequence is necessary to make the tda1004x load its firmware
 	 * and to enter analog mode of hybrid boards
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-empress.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-empress.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2010-02-24 13:52:17.000000000 -0500
@@ -86,24 +86,16 @@ static int ts_init_encoder(struct saa713
 
 static int ts_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct saa7134_dev *dev;
+	struct video_device *vdev = video_devdata(file);
+	struct saa7134_dev *dev = video_drvdata(file);
 	int err;
 
-	lock_kernel();
-	list_for_each_entry(dev, &saa7134_devlist, devlist)
-		if (dev->empress_dev && dev->empress_dev->minor == minor)
-			goto found;
-	unlock_kernel();
-	return -ENODEV;
- found:
-
-	dprintk("open minor=%d\n",minor);
+	dprintk("open dev=%s\n", video_device_node_name(vdev));
 	err = -EBUSY;
 	if (!mutex_trylock(&dev->empress_tsq.vb_lock))
-		goto done;
+		return err;
 	if (atomic_read(&dev->empress_users))
-		goto done_up;
+		goto done;
 
 	/* Unmute audio */
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
@@ -113,10 +105,8 @@ static int ts_open(struct file *file)
 	file->private_data = dev;
 	err = 0;
 
-done_up:
-	mutex_unlock(&dev->empress_tsq.vb_lock);
 done:
-	unlock_kernel();
+	mutex_unlock(&dev->empress_tsq.vb_lock);
 	return err;
 }
 
@@ -489,7 +479,6 @@ static const struct v4l2_ioctl_ops ts_io
 static struct video_device saa7134_empress_template = {
 	.name          = "saa7134-empress",
 	.fops          = &ts_fops,
-	.minor	       = -1,
 	.ioctl_ops     = &ts_ioctl_ops,
 
 	.tvnorms			= SAA7134_NORMS,
@@ -531,6 +520,7 @@ static int empress_init(struct saa7134_d
 
 	INIT_WORK(&dev->empress_workqueue, empress_signal_update);
 
+	video_set_drvdata(dev->empress_dev, dev);
 	err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
 				    empress_nr[dev->nr]);
 	if (err < 0) {
@@ -540,8 +530,8 @@ static int empress_init(struct saa7134_d
 		dev->empress_dev = NULL;
 		return err;
 	}
-	printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
-	       dev->name, dev->empress_dev->num);
+	printk(KERN_INFO "%s: registered device %s [mpeg]\n",
+	       dev->name, video_device_node_name(dev->empress_dev));
 
 	videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
 			    &dev->pci->dev, &dev->slock,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134.h linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134.h	2010-02-24 13:52:17.000000000 -0500
@@ -297,6 +297,8 @@ struct saa7134_format {
 #define SAA7134_BOARD_BEHOLD_X7             171
 #define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
 #define SAA7134_BOARD_ZOLID_HYBRID_PCI		173
+#define SAA7134_BOARD_ASUS_EUROPA_HYBRID	174
+#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
@@ -592,7 +594,6 @@ struct saa7134_dev {
 	unsigned int               insuspend;
 
 	/* I2C keyboard data */
-	struct i2c_board_info      info;
 	struct IR_i2c_init_data    init_data;
 
 	/* SAA7134_MPEG_* */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-input.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-input.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-input.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-input.c	2010-02-24 13:52:17.000000000 -0500
@@ -102,14 +102,14 @@ static int build_key(struct saa7134_dev
 		if (data == ir->mask_keycode)
 			ir_input_nokey(ir->dev, &ir->ir);
 		else
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 		return 0;
 	}
 
 	if (ir->polling) {
 		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 		} else {
 			ir_input_nokey(ir->dev, &ir->ir);
 		}
@@ -117,7 +117,7 @@ static int build_key(struct saa7134_dev
 	else {	/* IRQ driven mode - handle key press and release in one go */
 		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_keydown(ir->dev, &ir->ir, data);
 			ir_input_nokey(ir->dev, &ir->ir);
 		}
 	}
@@ -127,6 +127,61 @@ static int build_key(struct saa7134_dev
 
 /* --------------------- Chip specific I2C key builders ----------------- */
 
+static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	int gpio;
+	int attempt = 0;
+	unsigned char b;
+
+	/* We need this to access GPI Used by the saa_readl macro. */
+	struct saa7134_dev *dev = ir->c->adapter->algo_data;
+
+	if (dev == NULL) {
+		dprintk("get_key_flydvb_trio: "
+			 "gir->c->adapter->algo_data is NULL!\n");
+		return -EIO;
+	}
+
+	/* rising SAA7134_GPIGPRESCAN reads the status */
+	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+	saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+
+	gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
+
+	if (0x40000 & ~gpio)
+		return 0; /* No button press */
+
+	/* No button press - only before first key pressed */
+	if (b == 0xFF)
+		return 0;
+
+	/* poll IR chip */
+	/* weak up the IR chip */
+	b = 0;
+
+	while (1 != i2c_master_send(ir->c, &b, 1)) {
+		if ((attempt++) < 10) {
+			/*
+			 * wait a bit for next attempt -
+			 * I don't know how make it better
+			 */
+			msleep(10);
+			continue;
+		}
+		i2cdprintk("send wake up byte to pic16C505 (IR chip)"
+			   "failed %dx\n", attempt);
+		return -EIO;
+	}
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+
+	*ir_key = b;
+	*ir_raw = b;
+	return 1;
+}
+
 static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
 				       u32 *ir_raw)
 {
@@ -616,6 +671,13 @@ int saa7134_input_init1(struct saa7134_d
 		mask_keycode = 0x003f00;
 		mask_keydown = 0x040000;
 		break;
+	case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+		ir_codes     = &ir_codes_winfast_table;
+		mask_keycode = 0x5f00;
+		mask_keyup   = 0x020000;
+		polling      = 50; /* ms */
+		break;
+	break;
 	}
 	if (NULL == ir_codes) {
 		printk("%s: Oops: IR config error [card=%d]\n",
@@ -646,7 +708,10 @@ int saa7134_input_init1(struct saa7134_d
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(dev->pci));
 
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	err = ir_input_init(input_dev, &ir->ir, ir_type);
+	if (err < 0)
+		goto err_out_free;
+
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
@@ -663,7 +728,7 @@ int saa7134_input_init1(struct saa7134_d
 	dev->remote = ir;
 	saa7134_ir_start(dev, ir);
 
-	err = input_register_device(ir->dev);
+	err = ir_input_register(ir->dev, ir_codes);
 	if (err)
 		goto err_out_stop;
 
@@ -677,7 +742,6 @@ int saa7134_input_init1(struct saa7134_d
 	saa7134_ir_stop(dev);
 	dev->remote = NULL;
  err_out_free:
-	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
@@ -688,17 +752,14 @@ void saa7134_input_fini(struct saa7134_d
 		return;
 
 	saa7134_ir_stop(dev);
-	input_unregister_device(dev->remote->dev);
+	ir_input_unregister(dev->remote->dev);
 	kfree(dev->remote);
 	dev->remote = NULL;
 }
 
 void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
-	const unsigned short addr_list[] = {
-		0x7a, 0x47, 0x71, 0x2d,
-		I2C_CLIENT_END
-	};
+	struct i2c_board_info info;
 
 	struct i2c_msg msg_msi = {
 		.addr = 0x50,
@@ -714,9 +775,9 @@ void saa7134_probe_i2c_ir(struct saa7134
 		return;
 	}
 
-	memset(&dev->info, 0, sizeof(dev->info));
+	memset(&info, 0, sizeof(struct i2c_board_info));
 	memset(&dev->init_data, 0, sizeof(dev->init_data));
-	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
 
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
@@ -725,23 +786,24 @@ void saa7134_probe_i2c_ir(struct saa7134
 		if (pinnacle_remote == 0) {
 			dev->init_data.get_key = get_key_pinnacle_color;
 			dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
-			dev->info.addr = 0x47;
+			info.addr = 0x47;
 		} else {
 			dev->init_data.get_key = get_key_pinnacle_grey;
 			dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
-			dev->info.addr = 0x47;
+			info.addr = 0x47;
 		}
 		break;
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
 		dev->init_data.name = "Purple TV";
 		dev->init_data.get_key = get_key_purpletv;
 		dev->init_data.ir_codes = &ir_codes_purpletv_table;
+		info.addr = 0x7a;
 		break;
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
 		dev->init_data.name = "MSI TV@nywhere Plus";
 		dev->init_data.get_key = get_key_msi_tvanywhere_plus;
 		dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
-		dev->info.addr = 0x30;
+		info.addr = 0x30;
 		/* MSI TV@nywhere Plus controller doesn't seem to
 		   respond to probes unless we read something from
 		   an existing device. Weird...
@@ -755,6 +817,7 @@ void saa7134_probe_i2c_ir(struct saa7134
 		dev->init_data.name = "HVR 1110";
 		dev->init_data.get_key = get_key_hvr1110;
 		dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
+		info.addr = 0x71;
 		break;
 	case SAA7134_BOARD_BEHOLD_607FM_MK3:
 	case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -772,23 +835,26 @@ void saa7134_probe_i2c_ir(struct saa7134
 		dev->init_data.name = "BeholdTV";
 		dev->init_data.get_key = get_key_beholdm6xx;
 		dev->init_data.ir_codes = &ir_codes_behold_table;
+		info.addr = 0x2d;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
-		dev->info.addr = 0x40;
+		info.addr = 0x40;
 		break;
-	}
-
-	if (dev->init_data.name)
-		dev->info.platform_data = &dev->init_data;
-	/* No need to probe if address is known */
-	if (dev->info.addr) {
-		i2c_new_device(&dev->i2c_adap, &dev->info);
+	case SAA7134_BOARD_FLYDVB_TRIO:
+		dev->init_data.name = "FlyDVB Trio";
+		dev->init_data.get_key = get_key_flydvb_trio;
+		dev->init_data.ir_codes = &ir_codes_flydvb_table;
+		info.addr = 0x0b;
+		break;
+	default:
+		dprintk("No I2C IR support for board %x\n", dev->board);
 		return;
 	}
 
-	/* Address not known, fallback to probing */
-	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+	if (dev->init_data.name)
+		info.platform_data = &dev->init_data;
+	i2c_new_device(&dev->i2c_adap, &info);
 }
 
 static int saa7134_rc5_irq(struct saa7134_dev *dev)
@@ -936,7 +1002,7 @@ static void nec_task(unsigned long data)
 		dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
 			 ir->code, ircode, not_code);
 
-		ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code);
+		ir_input_keydown(ir->dev, &ir->ir, ir->code);
 	} else
 		dprintk("Repeat last key\n");
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-ts.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-ts.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -250,6 +250,19 @@ int saa7134_ts_start(struct saa7134_dev
 
 	BUG_ON(dev->ts_started);
 
+	/* dma: setup channel 5 (= TS) */
+	saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
+	saa_writeb(SAA7134_TS_DMA1,
+		((dev->ts.nr_packets - 1) >> 8) & 0xff);
+	/* TSNOPIT=0, TSCOLAP=0 */
+	saa_writeb(SAA7134_TS_DMA2,
+		(((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
+	saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
+	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
+					  SAA7134_RS_CONTROL_ME |
+					  (dev->ts.pt_ts.dma >> 12));
+
+	/* reset hardware TS buffers */
 	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
 	saa_writeb(SAA7134_TS_SERIAL1, 0x03);
 	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-video.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7134/saa7134-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7134/saa7134-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -1326,33 +1326,26 @@ static int saa7134_resource(struct saa71
 
 static int video_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct saa7134_dev *dev;
+	struct video_device *vdev = video_devdata(file);
+	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_fh *fh;
-	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	enum v4l2_buf_type type = 0;
 	int radio = 0;
 
-	mutex_lock(&saa7134_devlist_lock);
-	list_for_each_entry(dev, &saa7134_devlist, devlist) {
-		if (dev->video_dev && (dev->video_dev->minor == minor))
-			goto found;
-		if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
-			radio = 1;
-			goto found;
-		}
-		if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-			goto found;
-		}
+	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;
 	}
-	mutex_unlock(&saa7134_devlist_lock);
-	return -ENODEV;
-
-found:
-	mutex_unlock(&saa7134_devlist_lock);
 
-	dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
-		v4l2_type_names[type]);
+	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);
@@ -1499,7 +1492,7 @@ static int video_release(struct file *fi
 	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
 	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
-	saa_call_all(dev, tuner, s_standby);
+	saa_call_all(dev, core, s_power, 0);
 	if (fh->radio)
 		saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
 
@@ -2502,7 +2495,6 @@ struct video_device saa7134_video_templa
 	.name				= "saa7134-video",
 	.fops				= &video_fops,
 	.ioctl_ops 			= &video_ioctl_ops,
-	.minor				= -1,
 	.tvnorms			= SAA7134_NORMS,
 	.current_norm			= V4L2_STD_PAL,
 };
@@ -2511,7 +2503,6 @@ struct video_device saa7134_radio_templa
 	.name			= "saa7134-radio",
 	.fops			= &radio_fops,
 	.ioctl_ops 		= &radio_ioctl_ops,
-	.minor			= -1,
 };
 
 int saa7134_video_init1(struct saa7134_dev *dev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7164/saa7164-core.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7164/saa7164-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -724,13 +724,13 @@ static struct pci_driver saa7164_pci_dri
 	.resume   = NULL,
 };
 
-static int saa7164_init(void)
+static int __init saa7164_init(void)
 {
 	printk(KERN_INFO "saa7164 driver loaded\n");
 	return pci_register_driver(&saa7164_pci_driver);
 }
 
-static void saa7164_fini(void)
+static void __exit saa7164_fini(void)
 {
 	pci_unregister_driver(&saa7164_pci_driver);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa7164/saa7164-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa7164/saa7164-dvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa7164/saa7164-dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,6 +68,7 @@ static struct tda18271_config hauppauge_
 	.std_map	= &hauppauge_tda18271_std_map,
 	.gate		= TDA18271_GATE_ANALOG,
 	.role		= TDA18271_SLAVE,
+	.output_opt     = TDA18271_OUTPUT_LT_OFF,
 	.rf_cal_on_startup = 1
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/saa717x.c linux-libre-2.6.33-gnu1/drivers/media/video/saa717x.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/saa717x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/saa717x.c	2010-02-24 13:52:17.000000000 -0500
@@ -1115,7 +1115,7 @@ static int saa717x_s_video_routing(struc
 	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
 	/* inputs from 0-9 are available*/
 	/* saa717x have mode0-mode9 but mode5 is reserved. */
-	if (input < 0 || input > 9 || input == 5)
+	if (input > 9 || input == 5)
 		return -EINVAL;
 
 	if (decoder->input != input) {
@@ -1312,7 +1312,7 @@ static int saa717x_s_tuner(struct v4l2_s
 		"MONO", "STEREO", "LANG1", "LANG2/SAP"
 	};
 
-	audio_mode = V4L2_TUNER_MODE_STEREO;
+	audio_mode = TUNER_AUDIO_STEREO;
 
 	switch (vt->audmode) {
 		case V4L2_TUNER_MODE_MONO:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/se401.c linux-libre-2.6.33-gnu1/drivers/media/video/se401.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/se401.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/se401.c	2010-02-24 13:52:17.000000000 -0500
@@ -1428,8 +1428,8 @@ static int se401_probe(struct usb_interf
 		err("video_register_device failed");
 		return -EIO;
 	}
-	dev_info(&intf->dev, "registered new video device: video%d\n",
-		 se401->vdev.num);
+	dev_info(&intf->dev, "registered new video device: %s\n",
+		 video_device_node_name(&se401->vdev));
 
 	usb_set_intfdata(intf, se401);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/sh_mobile_ceu_camera.c linux-libre-2.6.33-gnu1/drivers/media/video/sh_mobile_ceu_camera.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,8 @@
 #include <media/soc_camera.h>
 #include <media/sh_mobile_ceu.h>
 #include <media/videobuf-dma-contig.h>
+#include <media/v4l2-mediabus.h>
+#include <media/soc_mediabus.h>
 
 /* register offsets for sh7722 / sh7723 */
 
@@ -85,7 +87,7 @@
 /* per video frame buffer */
 struct sh_mobile_ceu_buffer {
 	struct videobuf_buffer vb; /* v4l buffer must be first */
-	const struct soc_camera_data_format *fmt;
+	enum v4l2_mbus_pixelcode code;
 };
 
 struct sh_mobile_ceu_dev {
@@ -105,7 +107,8 @@ struct sh_mobile_ceu_dev {
 
 	u32 cflcr;
 
-	unsigned int is_interlaced:1;
+	enum v4l2_field field;
+
 	unsigned int image_mode:1;
 	unsigned int is_16bit:1;
 };
@@ -114,8 +117,8 @@ struct sh_mobile_ceu_cam {
 	struct v4l2_rect ceu_rect;
 	unsigned int cam_width;
 	unsigned int cam_height;
-	const struct soc_camera_data_format *extra_fmt;
-	const struct soc_camera_data_format *camera_fmt;
+	const struct soc_mbus_pixelfmt *extra_fmt;
+	enum v4l2_mbus_pixelcode code;
 };
 
 static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
@@ -153,6 +156,40 @@ static u32 ceu_read(struct sh_mobile_ceu
 	return ioread32(priv->base + reg_offs);
 }
 
+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 */
+
+	/* wait CSTSR.CPTON bit */
+	for (i = 0; i < 1000; i++) {
+		if (!(ceu_read(pcdev, CSTSR) & 1)) {
+			success++;
+			break;
+		}
+		udelay(1);
+	}
+
+	/* wait CAPSR.CPKIL bit */
+	for (i = 0; i < 1000; i++) {
+		if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
+			success++;
+			break;
+		}
+		udelay(1);
+	}
+
+
+	if (2 != success) {
+		dev_warn(&icd->dev, "soft reset time out\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*
  *  Videobuf operations
  */
@@ -163,16 +200,19 @@ static int sh_mobile_ceu_videobuf_setup(
 	struct soc_camera_device *icd = vq->priv_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
 
-	*size = PAGE_ALIGN(icd->user_width * icd->user_height *
-			   bytes_per_pixel);
+	if (bytes_per_line < 0)
+		return bytes_per_line;
+
+	*size = bytes_per_line * icd->user_height;
 
 	if (0 == *count)
 		*count = 2;
 
 	if (pcdev->video_limit) {
-		while (*size * *count > pcdev->video_limit)
+		while (PAGE_ALIGN(*size) * *count > pcdev->video_limit)
 			(*count)--;
 	}
 
@@ -202,51 +242,86 @@ static void free_buffer(struct videobuf_
 #define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
 #define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
 #define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
+#define CEU_CEIER_VBP   (1 << 20) /* vbp error */
 #define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
+#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
 
 
-static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
+/*
+ * return value doesn't reflex the success/failure to queue the new buffer,
+ * but rather the status of the previous buffer.
+ */
+static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
 	struct soc_camera_device *icd = pcdev->icd;
 	dma_addr_t phys_addr_top, phys_addr_bottom;
+	unsigned long top1, top2;
+	unsigned long bottom1, bottom2;
+	u32 status;
+	int ret = 0;
 
-	/* The hardware is _very_ picky about this sequence. Especially
+	/*
+	 * The hardware is _very_ picky about this sequence. Especially
 	 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
 	 * several not-so-well documented interrupt sources in CETCR.
 	 */
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
-	ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
+	status = ceu_read(pcdev, CETCR);
+	ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
 	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
 	ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
 
+	/*
+	 * When a VBP interrupt occurs, a capture end interrupt does not occur
+	 * and the image of that frame is not captured correctly. So, soft reset
+	 * is needed here.
+	 */
+	if (status & CEU_CEIER_VBP) {
+		sh_mobile_ceu_soft_reset(pcdev);
+		ret = -EIO;
+	}
+
 	if (!pcdev->active)
-		return;
+		return ret;
+
+	if (V4L2_FIELD_INTERLACED_BT == pcdev->field) {
+		top1	= CDBYR;
+		top2	= CDBCR;
+		bottom1	= CDAYR;
+		bottom2	= CDACR;
+	} else {
+		top1	= CDAYR;
+		top2	= CDACR;
+		bottom1	= CDBYR;
+		bottom2	= CDBCR;
+	}
 
 	phys_addr_top = videobuf_to_dma_contig(pcdev->active);
-	ceu_write(pcdev, CDAYR, phys_addr_top);
-	if (pcdev->is_interlaced) {
+	ceu_write(pcdev, top1, phys_addr_top);
+	if (V4L2_FIELD_NONE != pcdev->field) {
 		phys_addr_bottom = phys_addr_top + icd->user_width;
-		ceu_write(pcdev, CDBYR, phys_addr_bottom);
+		ceu_write(pcdev, bottom1, phys_addr_bottom);
 	}
 
-	switch (icd->current_fmt->fourcc) {
+	switch (icd->current_fmt->host_fmt->fourcc) {
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
 		phys_addr_top += icd->user_width *
 			icd->user_height;
-		ceu_write(pcdev, CDACR, phys_addr_top);
-		if (pcdev->is_interlaced) {
-			phys_addr_bottom = phys_addr_top +
-				icd->user_width;
-			ceu_write(pcdev, CDBCR, phys_addr_bottom);
+		ceu_write(pcdev, top2, phys_addr_top);
+		if (V4L2_FIELD_NONE != pcdev->field) {
+			phys_addr_bottom = phys_addr_top + icd->user_width;
+			ceu_write(pcdev, bottom2, phys_addr_bottom);
 		}
 	}
 
 	pcdev->active->state = VIDEOBUF_ACTIVE;
 	ceu_write(pcdev, CAPSR, 0x1); /* start capture */
+
+	return ret;
 }
 
 static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
@@ -255,8 +330,13 @@ static int sh_mobile_ceu_videobuf_prepar
 {
 	struct soc_camera_device *icd = vq->priv_data;
 	struct sh_mobile_ceu_buffer *buf;
+	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+						icd->current_fmt->host_fmt);
 	int ret;
 
+	if (bytes_per_line < 0)
+		return bytes_per_line;
+
 	buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
 
 	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
@@ -266,25 +346,27 @@ static int sh_mobile_ceu_videobuf_prepar
 	WARN_ON(!list_empty(&vb->queue));
 
 #ifdef DEBUG
-	/* This can be useful if you want to see if we actually fill
-	 * the buffer with something */
+	/*
+	 * This can be useful if you want to see if we actually fill
+	 * the buffer with something
+	 */
 	memset((void *)vb->baddr, 0xaa, vb->bsize);
 #endif
 
 	BUG_ON(NULL == icd->current_fmt);
 
-	if (buf->fmt	!= icd->current_fmt ||
+	if (buf->code	!= icd->current_fmt->code ||
 	    vb->width	!= icd->user_width ||
 	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
-		buf->fmt	= icd->current_fmt;
+		buf->code	= icd->current_fmt->code;
 		vb->width	= icd->user_width;
 		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
 
-	vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+	vb->size = vb->height * bytes_per_line;
 	if (0 != vb->baddr && vb->bsize < vb->size) {
 		ret = -EINVAL;
 		goto out;
@@ -319,6 +401,11 @@ static void sh_mobile_ceu_videobuf_queue
 	list_add_tail(&vb->queue, &pcdev->capture);
 
 	if (!pcdev->active) {
+		/*
+		 * Because there were no active buffer at this moment,
+		 * we are not interested in the return value of
+		 * sh_mobile_ceu_capture here.
+		 */
 		pcdev->active = vb;
 		sh_mobile_ceu_capture(pcdev);
 	}
@@ -379,9 +466,8 @@ static irqreturn_t sh_mobile_ceu_irq(int
 	else
 		pcdev->active = NULL;
 
-	sh_mobile_ceu_capture(pcdev);
-
-	vb->state = VIDEOBUF_DONE;
+	vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ?
+		VIDEOBUF_ERROR : VIDEOBUF_DONE;
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
@@ -397,6 +483,7 @@ static int sh_mobile_ceu_add_device(stru
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	int ret;
 
 	if (pcdev->icd)
 		return -EBUSY;
@@ -407,13 +494,11 @@ static int sh_mobile_ceu_add_device(stru
 
 	pm_runtime_get_sync(ici->v4l2_dev.dev);
 
-	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
-	while (ceu_read(pcdev, CSTSR) & 1)
-		msleep(1);
-
-	pcdev->icd = icd;
+	ret = sh_mobile_ceu_soft_reset(pcdev);
+	if (!ret)
+		pcdev->icd = icd;
 
-	return 0;
+	return ret;
 }
 
 /* Called with .video_lock held */
@@ -427,7 +512,7 @@ static void sh_mobile_ceu_remove_device(
 
 	/* disable capture, disable interrupts */
 	ceu_write(pcdev, CEIER, 0);
-	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+	sh_mobile_ceu_soft_reset(pcdev);
 
 	/* make sure active buffer is canceled */
 	spin_lock_irqsave(&pcdev->lock, flags);
@@ -503,24 +588,35 @@ static void sh_mobile_ceu_set_rect(struc
 			in_width *= 2;
 			left_offset *= 2;
 		}
-		width = cdwdr_width = out_width;
+		width = out_width;
+		cdwdr_width = out_width;
 	} else {
-		unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3;
+		int bytes_per_line = soc_mbus_bytes_per_line(out_width,
+						icd->current_fmt->host_fmt);
+		unsigned int w_factor;
 
-		width = out_width * w_factor / 2;
+		width = out_width;
 
-		if (!pcdev->is_16bit)
-			w_factor *= 2;
+		switch (icd->current_fmt->host_fmt->packing) {
+		case SOC_MBUS_PACKING_2X8_PADHI:
+			w_factor = 2;
+			break;
+		default:
+			w_factor = 1;
+		}
 
-		in_width = rect->width * w_factor / 2;
-		left_offset = left_offset * w_factor / 2;
+		in_width = rect->width * w_factor;
+		left_offset = left_offset * w_factor;
 
-		cdwdr_width = width * 2;
+		if (bytes_per_line < 0)
+			cdwdr_width = out_width;
+		else
+			cdwdr_width = bytes_per_line;
 	}
 
 	height = out_height;
 	in_height = rect->height;
-	if (pcdev->is_interlaced) {
+	if (V4L2_FIELD_NONE != pcdev->field) {
 		height /= 2;
 		in_height /= 2;
 		top_offset /= 2;
@@ -591,6 +687,23 @@ static int sh_mobile_ceu_set_bus_param(s
 	if (!common_flags)
 		return -EINVAL;
 
+	/* Make choises, based on platform preferences */
+	if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+		if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
+			common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+	}
+
+	if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+		if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+	}
+
 	ret = icd->ops->set_bus_param(icd, common_flags);
 	if (ret < 0)
 		return ret;
@@ -612,24 +725,24 @@ static int sh_mobile_ceu_set_bus_param(s
 	value = 0x00000010; /* data fetch by default */
 	yuv_lineskip = 0;
 
-	switch (icd->current_fmt->fourcc) {
+	switch (icd->current_fmt->host_fmt->fourcc) {
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
 		yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */
 		/* fall-through */
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
-		switch (cam->camera_fmt->fourcc) {
-		case V4L2_PIX_FMT_UYVY:
+		switch (cam->code) {
+		case V4L2_MBUS_FMT_YUYV8_2X8_BE:
 			value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
 			break;
-		case V4L2_PIX_FMT_VYUY:
+		case V4L2_MBUS_FMT_YVYU8_2X8_BE:
 			value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
 			break;
-		case V4L2_PIX_FMT_YUYV:
+		case V4L2_MBUS_FMT_YUYV8_2X8_LE:
 			value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
 			break;
-		case V4L2_PIX_FMT_YVYU:
+		case V4L2_MBUS_FMT_YVYU8_2X8_LE:
 			value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
 			break;
 		default:
@@ -637,8 +750,8 @@ static int sh_mobile_ceu_set_bus_param(s
 		}
 	}
 
-	if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
-	    icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)
+	if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
+	    icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
 		value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
 
 	value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
@@ -647,14 +760,27 @@ static int sh_mobile_ceu_set_bus_param(s
 	ceu_write(pcdev, CAMCR, value);
 
 	ceu_write(pcdev, CAPCR, 0x00300000);
-	ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
+
+	switch (pcdev->field) {
+	case V4L2_FIELD_INTERLACED_TB:
+		value = 0x101;
+		break;
+	case V4L2_FIELD_INTERLACED_BT:
+		value = 0x102;
+		break;
+	default:
+		value = 0;
+		break;
+	}
+	ceu_write(pcdev, CAIFR, value);
 
 	sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
 	mdelay(1);
 
 	ceu_write(pcdev, CFLCR, pcdev->cflcr);
 
-	/* A few words about byte order (observed in Big Endian mode)
+	/*
+	 * A few words about byte order (observed in Big Endian mode)
 	 *
 	 * In data fetch mode bytes are received in chunks of 8 bytes.
 	 * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
@@ -684,7 +810,8 @@ static int sh_mobile_ceu_set_bus_param(s
 	return 0;
 }
 
-static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
+static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
+				       unsigned char buswidth)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -693,48 +820,75 @@ static int sh_mobile_ceu_try_bus_param(s
 	camera_flags = icd->ops->query_bus_param(icd);
 	common_flags = soc_camera_bus_param_compatible(camera_flags,
 						       make_bus_param(pcdev));
-	if (!common_flags)
+	if (!common_flags || buswidth > 16 ||
+	    (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16)))
 		return -EINVAL;
 
 	return 0;
 }
 
-static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
-	{
-		.name		= "NV12",
-		.depth		= 12,
-		.fourcc		= V4L2_PIX_FMT_NV12,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
-	},
-	{
-		.name		= "NV21",
-		.depth		= 12,
-		.fourcc		= V4L2_PIX_FMT_NV21,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
-	},
-	{
-		.name		= "NV16",
-		.depth		= 16,
-		.fourcc		= V4L2_PIX_FMT_NV16,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
-	},
+static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
 	{
-		.name		= "NV61",
-		.depth		= 16,
-		.fourcc		= V4L2_PIX_FMT_NV61,
-		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.fourcc			= V4L2_PIX_FMT_NV12,
+		.name			= "NV12",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_NV21,
+		.name			= "NV21",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_NV16,
+		.name			= "NV16",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_NV61,
+		.name			= "NV61",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
 	},
 };
 
+/* This will be corrected as we get more formats */
+static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+{
+	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
+		(fmt->bits_per_sample == 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
+		(fmt->bits_per_sample > 8 &&
+		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
+}
+
 static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
 				     struct soc_camera_format_xlate *xlate)
 {
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct device *dev = icd->dev.parent;
 	int ret, k, n;
 	int formats = 0;
 	struct sh_mobile_ceu_cam *cam;
+	enum v4l2_mbus_pixelcode code;
+	const struct soc_mbus_pixelfmt *fmt;
 
-	ret = sh_mobile_ceu_try_bus_param(icd);
+	ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+	if (ret < 0)
+		/* No more formats */
+		return 0;
+
+	fmt = soc_mbus_get_fmtdesc(code);
+	if (!fmt) {
+		dev_err(icd->dev.parent,
+			"Invalid format code #%d: %d\n", idx, code);
+		return -EINVAL;
+	}
+
+	ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
 	if (ret < 0)
 		return 0;
 
@@ -752,13 +906,13 @@ static int sh_mobile_ceu_get_formats(str
 	if (!idx)
 		cam->extra_fmt = NULL;
 
-	switch (icd->formats[idx].fourcc) {
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_YUYV:
-	case V4L2_PIX_FMT_YVYU:
+	switch (code) {
+	case V4L2_MBUS_FMT_YUYV8_2X8_BE:
+	case V4L2_MBUS_FMT_YVYU8_2X8_BE:
+	case V4L2_MBUS_FMT_YUYV8_2X8_LE:
+	case V4L2_MBUS_FMT_YVYU8_2X8_LE:
 		if (cam->extra_fmt)
-			goto add_single_format;
+			break;
 
 		/*
 		 * Our case is simple so far: for any of the above four camera
@@ -769,32 +923,31 @@ static int sh_mobile_ceu_get_formats(str
 		 * the host_priv pointer and check whether the format you're
 		 * going to add now is already there.
 		 */
-		cam->extra_fmt = (void *)sh_mobile_ceu_formats;
+		cam->extra_fmt = sh_mobile_ceu_formats;
 
 		n = ARRAY_SIZE(sh_mobile_ceu_formats);
 		formats += n;
 		for (k = 0; xlate && k < n; k++) {
-			xlate->host_fmt = &sh_mobile_ceu_formats[k];
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = icd->formats[idx].depth;
+			xlate->host_fmt	= &sh_mobile_ceu_formats[k];
+			xlate->code	= code;
 			xlate++;
-			dev_dbg(dev, "Providing format %s using %s\n",
-				sh_mobile_ceu_formats[k].name,
-				icd->formats[idx].name);
+			dev_dbg(dev, "Providing format %s using code %d\n",
+				sh_mobile_ceu_formats[k].name, code);
 		}
+		break;
 	default:
-add_single_format:
-		/* Generic pass-through */
-		formats++;
-		if (xlate) {
-			xlate->host_fmt = icd->formats + idx;
-			xlate->cam_fmt = icd->formats + idx;
-			xlate->buswidth = icd->formats[idx].depth;
-			xlate++;
-			dev_dbg(dev,
-				"Providing format %s in pass-through mode\n",
-				icd->formats[idx].name);
-		}
+		if (!sh_mobile_ceu_packing_supported(fmt))
+			return 0;
+	}
+
+	/* Generic pass-through */
+	formats++;
+	if (xlate) {
+		xlate->host_fmt	= fmt;
+		xlate->code	= code;
+		xlate++;
+		dev_dbg(dev, "Providing format %s in pass-through mode\n",
+			xlate->host_fmt->name);
 	}
 
 	return formats;
@@ -974,17 +1127,15 @@ static int client_s_crop(struct v4l2_sub
 static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
 			     unsigned int *scale_h, unsigned int *scale_v)
 {
-	struct v4l2_format f;
+	struct v4l2_mbus_framefmt mf;
 	int ret;
 
-	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 	if (ret < 0)
 		return ret;
 
-	*scale_h = calc_generic_scale(rect->width, f.fmt.pix.width);
-	*scale_v = calc_generic_scale(rect->height, f.fmt.pix.height);
+	*scale_h = calc_generic_scale(rect->width, mf.width);
+	*scale_v = calc_generic_scale(rect->height, mf.height);
 
 	return 0;
 }
@@ -999,32 +1150,29 @@ static int get_camera_subwin(struct soc_
 	if (!ceu_rect->width) {
 		struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 		struct device *dev = icd->dev.parent;
-		struct v4l2_format f;
-		struct v4l2_pix_format *pix = &f.fmt.pix;
+		struct v4l2_mbus_framefmt mf;
 		int ret;
 		/* First time */
 
-		f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-		ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+		ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 		if (ret < 0)
 			return ret;
 
-		dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height);
+		dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
 
-		if (pix->width > 2560) {
+		if (mf.width > 2560) {
 			ceu_rect->width	 = 2560;
-			ceu_rect->left	 = (pix->width - 2560) / 2;
+			ceu_rect->left	 = (mf.width - 2560) / 2;
 		} else {
-			ceu_rect->width	 = pix->width;
+			ceu_rect->width	 = mf.width;
 			ceu_rect->left	 = 0;
 		}
 
-		if (pix->height > 1920) {
+		if (mf.height > 1920) {
 			ceu_rect->height = 1920;
-			ceu_rect->top	 = (pix->height - 1920) / 2;
+			ceu_rect->top	 = (mf.height - 1920) / 2;
 		} else {
-			ceu_rect->height = pix->height;
+			ceu_rect->height = mf.height;
 			ceu_rect->top	 = 0;
 		}
 
@@ -1041,13 +1189,12 @@ static int get_camera_subwin(struct soc_
 	return 0;
 }
 
-static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f,
-			bool ceu_can_scale)
+static int client_s_fmt(struct soc_camera_device *icd,
+			struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
 {
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct device *dev = icd->dev.parent;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h;
+	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
 	unsigned int max_width, max_height;
 	struct v4l2_cropcap cap;
 	int ret;
@@ -1061,29 +1208,29 @@ static int client_s_fmt(struct soc_camer
 	max_width = min(cap.bounds.width, 2560);
 	max_height = min(cap.bounds.height, 1920);
 
-	ret = v4l2_subdev_call(sd, video, s_fmt, f);
+	ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
 	if (ret < 0)
 		return ret;
 
-	dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height);
+	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
 
-	if ((width == pix->width && height == pix->height) || !ceu_can_scale)
+	if ((width == mf->width && height == mf->height) || !ceu_can_scale)
 		return 0;
 
 	/* Camera set a format, but geometry is not precise, try to improve */
-	tmp_w = pix->width;
-	tmp_h = pix->height;
+	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);
-		pix->width = tmp_w;
-		pix->height = tmp_h;
-		ret = v4l2_subdev_call(sd, video, s_fmt, f);
+		mf->width = tmp_w;
+		mf->height = tmp_h;
+		ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
 		dev_geo(dev, "Camera scaled to %ux%u\n",
-			pix->width, pix->height);
+			mf->width, mf->height);
 		if (ret < 0) {
 			/* This shouldn't happen */
 			dev_err(dev, "Client failed to set format: %d\n", ret);
@@ -1101,27 +1248,26 @@ static int client_s_fmt(struct soc_camer
  */
 static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
 			struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect,
-			struct v4l2_format *f, bool ceu_can_scale)
+			struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
 {
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct sh_mobile_ceu_cam *cam = icd->host_priv;
 	struct device *dev = icd->dev.parent;
-	struct v4l2_format f_tmp = *f;
-	struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix;
+	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. */
-	ret = client_s_fmt(icd, &f_tmp, ceu_can_scale);
+	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",
-		pix_tmp->width, pix_tmp->height);
+		mf_tmp.width, mf_tmp.height);
 
 	/* 6. Retrieve camera output window (g_fmt) */
 
-	/* unneeded - it is already in "f_tmp" */
+	/* unneeded - it is already in "mf_tmp" */
 
 	/* 7. Calculate new camera scales. */
 	ret = get_camera_scales(sd, rect, &scale_h, &scale_v);
@@ -1130,10 +1276,11 @@ static int client_scale(struct soc_camer
 
 	dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
 
-	cam->cam_width		= pix_tmp->width;
-	cam->cam_height		= pix_tmp->height;
-	f->fmt.pix.width	= pix_tmp->width;
-	f->fmt.pix.height	= pix_tmp->height;
+	cam->cam_width	= mf_tmp.width;
+	cam->cam_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
@@ -1197,8 +1344,7 @@ static int sh_mobile_ceu_set_crop(struct
 	struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect;
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct device *dev = icd->dev.parent;
-	struct v4l2_format f;
-	struct v4l2_pix_format *pix = &f.fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v,
 		out_width, out_height;
 	u32 capsr, cflcr;
@@ -1247,26 +1393,25 @@ static int sh_mobile_ceu_set_crop(struct
 	 * 5. Using actual input window and calculated combined scales calculate
 	 *    camera target output window.
 	 */
-	pix->width		= scale_down(cam_rect->width, scale_comb_h);
-	pix->height		= scale_down(cam_rect->height, scale_comb_v);
+	mf.width	= scale_down(cam_rect->width, scale_comb_h);
+	mf.height	= scale_down(cam_rect->height, scale_comb_v);
 
-	dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height);
+	dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height);
 
 	/* 6. - 9. */
-	pix->pixelformat	= cam->camera_fmt->fourcc;
-	pix->colorspace		= cam->camera_fmt->colorspace;
+	mf.code		= cam->code;
+	mf.field	= pcdev->field;
 
 	capsr = capture_save_reset(pcdev);
 	dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
 
 	/* Make relative to camera rectangle */
-	rect->left		-= cam_rect->left;
-	rect->top		-= cam_rect->top;
-
-	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	rect->left	-= cam_rect->left;
+	rect->top	-= cam_rect->top;
 
-	ret = client_scale(icd, cam_rect, rect, ceu_rect, &f,
-			   pcdev->image_mode && !pcdev->is_interlaced);
+	ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf,
+			   pcdev->image_mode &&
+			   V4L2_FIELD_NONE == pcdev->field);
 
 	dev_geo(dev, "6-9: %d\n", ret);
 
@@ -1313,8 +1458,7 @@ static int sh_mobile_ceu_set_fmt(struct
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	struct sh_mobile_ceu_cam *cam = icd->host_priv;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct v4l2_format cam_f = *f;
-	struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix;
+	struct v4l2_mbus_framefmt mf;
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct device *dev = icd->dev.parent;
 	__u32 pixfmt = pix->pixelformat;
@@ -1324,18 +1468,20 @@ static int sh_mobile_ceu_set_fmt(struct
 	unsigned int scale_cam_h, scale_cam_v;
 	u16 scale_v, scale_h;
 	int ret;
-	bool is_interlaced, image_mode;
+	bool image_mode;
+	enum v4l2_field field;
 
 	switch (pix->field) {
-	case V4L2_FIELD_INTERLACED:
-		is_interlaced = true;
-		break;
-	case V4L2_FIELD_ANY:
 	default:
 		pix->field = V4L2_FIELD_NONE;
 		/* fall-through */
+	case V4L2_FIELD_INTERLACED_TB:
+	case V4L2_FIELD_INTERLACED_BT:
 	case V4L2_FIELD_NONE:
-		is_interlaced = false;
+		field = pix->field;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		field = V4L2_FIELD_INTERLACED_TB;
 		break;
 	}
 
@@ -1383,9 +1529,11 @@ static int sh_mobile_ceu_set_fmt(struct
 	 * 4. Calculate camera output window by applying combined scales to real
 	 *    input window.
 	 */
-	cam_pix->width = scale_down(cam_rect->width, scale_h);
-	cam_pix->height = scale_down(cam_rect->height, scale_v);
-	cam_pix->pixelformat = xlate->cam_fmt->fourcc;
+	mf.width	= scale_down(cam_rect->width, scale_h);
+	mf.height	= scale_down(cam_rect->height, scale_v);
+	mf.field	= pix->field;
+	mf.colorspace	= pix->colorspace;
+	mf.code		= xlate->code;
 
 	switch (pixfmt) {
 	case V4L2_PIX_FMT_NV12:
@@ -1398,51 +1546,61 @@ static int sh_mobile_ceu_set_fmt(struct
 		image_mode = false;
 	}
 
-	dev_geo(dev, "4: camera output %ux%u\n",
-		cam_pix->width, cam_pix->height);
+	dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height);
 
 	/* 5. - 9. */
-	ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f,
-			   image_mode && !is_interlaced);
+	ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf,
+			   image_mode && V4L2_FIELD_NONE == field);
 
 	dev_geo(dev, "5-9: client scale %d\n", ret);
 
 	/* Done with the camera. Now see if we can improve the result */
 
 	dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
-		ret, cam_pix->width, cam_pix->height, pix->width, pix->height);
+		ret, mf.width, mf.height, pix->width, pix->height);
 	if (ret < 0)
 		return ret;
 
+	if (mf.code != xlate->code)
+		return -EINVAL;
+
 	/* 10. Use CEU scaling to scale to the requested user window. */
 
 	/* We cannot scale up */
-	if (pix->width > cam_pix->width)
-		pix->width = cam_pix->width;
+	if (pix->width > mf.width)
+		pix->width = mf.width;
 	if (pix->width > ceu_rect.width)
 		pix->width = ceu_rect.width;
 
-	if (pix->height > cam_pix->height)
-		pix->height = cam_pix->height;
+	if (pix->height > mf.height)
+		pix->height = mf.height;
 	if (pix->height > ceu_rect.height)
 		pix->height = ceu_rect.height;
 
-	/* Let's rock: scale pix->{width x height} down to width x height */
-	scale_h = calc_scale(ceu_rect.width, &pix->width);
-	scale_v = calc_scale(ceu_rect.height, &pix->height);
+	pix->colorspace = mf.colorspace;
+
+	if (image_mode) {
+		/* Scale pix->{width x height} down to width x height */
+		scale_h = calc_scale(ceu_rect.width, &pix->width);
+		scale_v = calc_scale(ceu_rect.height, &pix->height);
+
+		pcdev->cflcr = scale_h | (scale_v << 16);
+	} else {
+		pix->width = ceu_rect.width;
+		pix->height = ceu_rect.height;
+		scale_h = scale_v = 0;
+		pcdev->cflcr = 0;
+	}
 
 	dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
 		ceu_rect.width, scale_h, pix->width,
 		ceu_rect.height, scale_v, pix->height);
 
-	pcdev->cflcr = scale_h | (scale_v << 16);
-
-	icd->buswidth = xlate->buswidth;
-	icd->current_fmt = xlate->host_fmt;
-	cam->camera_fmt = xlate->cam_fmt;
-	cam->ceu_rect = ceu_rect;
+	cam->code		= xlate->code;
+	cam->ceu_rect		= ceu_rect;
+	icd->current_fmt	= xlate;
 
-	pcdev->is_interlaced = is_interlaced;
+	pcdev->field = field;
 	pcdev->image_mode = image_mode;
 
 	return 0;
@@ -1454,6 +1612,7 @@ static int sh_mobile_ceu_try_fmt(struct
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct v4l2_mbus_framefmt mf;
 	__u32 pixfmt = pix->pixelformat;
 	int width, height;
 	int ret;
@@ -1472,18 +1631,27 @@ static int sh_mobile_ceu_try_fmt(struct
 	width = pix->width;
 	height = pix->height;
 
-	pix->bytesperline = pix->width *
-		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
-	pix->sizeimage = pix->height * pix->bytesperline;
-
-	pix->pixelformat = xlate->cam_fmt->fourcc;
+	pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
+	pix->sizeimage = height * pix->bytesperline;
 
 	/* limit to sensor capabilities */
-	ret = v4l2_subdev_call(sd, video, try_fmt, f);
-	pix->pixelformat = pixfmt;
+	mf.width	= pix->width;
+	mf.height	= pix->height;
+	mf.field	= pix->field;
+	mf.code		= xlate->code;
+	mf.colorspace	= pix->colorspace;
+
+	ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
 	if (ret < 0)
 		return ret;
 
+	pix->width	= mf.width;
+	pix->height	= mf.height;
+	pix->field	= mf.field;
+	pix->colorspace	= mf.colorspace;
+
 	switch (pixfmt) {
 	case V4L2_PIX_FMT_NV12:
 	case V4L2_PIX_FMT_NV21:
@@ -1492,21 +1660,25 @@ static int sh_mobile_ceu_try_fmt(struct
 		/* FIXME: check against rect_max after converting soc-camera */
 		/* We can scale precisely, need a bigger image from camera */
 		if (pix->width < width || pix->height < height) {
-			int tmp_w = pix->width, tmp_h = pix->height;
-			pix->width = 2560;
-			pix->height = 1920;
-			ret = v4l2_subdev_call(sd, video, try_fmt, f);
+			/*
+			 * We presume, the sensor behaves sanely, i.e., if
+			 * requested a bigger rectangle, it will not return a
+			 * smaller one.
+			 */
+			mf.width = 2560;
+			mf.height = 1920;
+			ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
 			if (ret < 0) {
 				/* Shouldn't actually happen... */
 				dev_err(icd->dev.parent,
-					"FIXME: try_fmt() returned %d\n", ret);
-				pix->width = tmp_w;
-				pix->height = tmp_h;
+					"FIXME: client try_fmt() = %d\n", ret);
+				return ret;
 			}
 		}
-		if (pix->width > width)
+		/* We will scale exactly */
+		if (mf.width > width)
 			pix->width = width;
-		if (pix->height > height)
+		if (mf.height > height)
 			pix->height = height;
 	}
 
@@ -1518,10 +1690,12 @@ static int sh_mobile_ceu_reqbufs(struct
 {
 	int i;
 
-	/* This is for locking debugging only. I removed spinlocks and now I
+	/*
+	 * This is for locking debugging only. I removed spinlocks and now I
 	 * check whether .prepare is ever called on a linked buffer, or whether
 	 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
-	 * it hadn't triggered */
+	 * it hadn't triggered
+	 */
 	for (i = 0; i < p->count; i++) {
 		struct sh_mobile_ceu_buffer *buf;
 
@@ -1569,8 +1743,7 @@ static void sh_mobile_ceu_init_videobuf(
 				       &sh_mobile_ceu_videobuf_ops,
 				       icd->dev.parent, &pcdev->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
-				       pcdev->is_interlaced ?
-				       V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
+				       pcdev->field,
 				       sizeof(struct sh_mobile_ceu_buffer),
 				       icd);
 }
@@ -1599,7 +1772,7 @@ static int sh_mobile_ceu_set_ctrl(struct
 
 	switch (ctrl->id) {
 	case V4L2_CID_SHARPNESS:
-		switch (icd->current_fmt->fourcc) {
+		switch (icd->current_fmt->host_fmt->fourcc) {
 		case V4L2_PIX_FMT_NV12:
 		case V4L2_PIX_FMT_NV21:
 		case V4L2_PIX_FMT_NV16:
@@ -1654,7 +1827,7 @@ static int __devinit sh_mobile_ceu_probe
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	if (!res || !irq) {
+	if (!res || (int)irq <= 0) {
 		dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
 		err = -ENODEV;
 		goto exit;
@@ -1770,7 +1943,7 @@ static int sh_mobile_ceu_runtime_nop(str
 	return 0;
 }
 
-static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
+static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
 	.runtime_suspend = sh_mobile_ceu_runtime_nop,
 	.runtime_resume = sh_mobile_ceu_runtime_nop,
 };
@@ -1781,7 +1954,7 @@ static struct platform_driver sh_mobile_
 		.pm	= &sh_mobile_ceu_dev_pm_ops,
 	},
 	.probe		= sh_mobile_ceu_probe,
-	.remove		= __exit_p(sh_mobile_ceu_remove),
+	.remove		= __devexit_p(sh_mobile_ceu_remove),
 };
 
 static int __init sh_mobile_ceu_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/sn9c102/sn9c102_core.c linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/sn9c102/sn9c102_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/sn9c102/sn9c102_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -1007,8 +1007,8 @@ static int sn9c102_stream_interrupt(stru
 	else if (cam->stream != STREAM_OFF) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "URB timeout reached. The camera is misconfigured. "
-		       "To use it, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "To use it, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1734,7 +1734,8 @@ static void sn9c102_release_resources(st
 
 	cam = container_of(kref, struct sn9c102_device, kref);
 
-	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
+	DBG(2, "V4L2 device %s deregistered",
+	    video_device_node_name(cam->v4ldev));
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 	usb_put_dev(cam->usbdev);
@@ -1791,8 +1792,8 @@ static int sn9c102_open(struct file *fil
 	}
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is already in use",
-		       cam->v4ldev->num);
+		DBG(2, "Device %s is already in use",
+		    video_device_node_name(cam->v4ldev));
 		DBG(3, "Simultaneous opens are not supported");
 		/*
 		   open() must follow the open flags and should block
@@ -1845,7 +1846,7 @@ static int sn9c102_open(struct file *fil
 	cam->frame_count = 0;
 	sn9c102_empty_framequeues(cam);
 
-	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
+	DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev));
 
 out:
 	mutex_unlock(&cam->open_mutex);
@@ -1870,7 +1871,7 @@ static int sn9c102_release(struct file *
 	cam->users--;
 	wake_up_interruptible_nr(&cam->wait_open, 1);
 
-	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
+	DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev));
 
 	kref_put(&cam->kref, sn9c102_release_resources);
 
@@ -2433,8 +2434,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_dev
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -2446,8 +2447,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_dev
 	    nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -2690,8 +2691,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -2702,8 +2703,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_
 	    nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -2748,9 +2749,9 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102
 	err += sn9c102_set_compression(cam, &jc);
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
-		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
-		       "problems. To use the camera, close and open "
-		       "/dev/video%d again.", cam->v4ldev->num);
+		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. "
+		       "To use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -3328,7 +3329,6 @@ sn9c102_usb_probe(struct usb_interface*
 
 	strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
 	cam->v4ldev->fops = &sn9c102_fops;
-	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	cam->v4ldev->parent = &udev->dev;
 
@@ -3346,7 +3346,8 @@ sn9c102_usb_probe(struct usb_interface*
 		goto fail;
 	}
 
-	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
+	DBG(2, "V4L2 device registered as %s",
+	    video_device_node_name(cam->v4ldev));
 
 	video_set_drvdata(cam->v4ldev, cam);
 	cam->module_param.force_munmap = force_munmap[dev_nr];
@@ -3398,9 +3399,9 @@ static void sn9c102_usb_disconnect(struc
 	DBG(2, "Disconnecting %s...", cam->v4ldev->name);
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is open! Deregistration and "
-		       "memory deallocation are deferred.",
-		    cam->v4ldev->num);
+		DBG(2, "Device %s is open! Deregistration and memory "
+		       "deallocation are deferred.",
+		    video_device_node_name(cam->v4ldev));
 		cam->state |= DEV_MISCONFIGURED;
 		sn9c102_stop_transfer(cam);
 		cam->state |= DEV_DISCONNECTED;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/soc_camera.c linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/soc_camera.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-core.h>
+#include <media/soc_mediabus.h>
 
 /* Default to VGA resolution */
 #define DEFAULT_WIDTH	640
@@ -40,18 +41,6 @@ static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
 static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
 
-const struct soc_camera_data_format *soc_camera_format_by_fourcc(
-	struct soc_camera_device *icd, unsigned int fourcc)
-{
-	unsigned int i;
-
-	for (i = 0; i < icd->num_formats; i++)
-		if (icd->formats[i].fourcc == fourcc)
-			return icd->formats + i;
-	return NULL;
-}
-EXPORT_SYMBOL(soc_camera_format_by_fourcc);
-
 const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
 	struct soc_camera_device *icd, unsigned int fourcc)
 {
@@ -207,21 +196,26 @@ static int soc_camera_dqbuf(struct file
 /* Always entered with .video_lock held */
 static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 {
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	int i, fmts = 0, ret;
+	int i, fmts = 0, raw_fmts = 0, ret;
+	enum v4l2_mbus_pixelcode code;
+
+	while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code))
+		raw_fmts++;
 
 	if (!ici->ops->get_formats)
 		/*
 		 * Fallback mode - the host will have to serve all
 		 * sensor-provided formats one-to-one to the user
 		 */
-		fmts = icd->num_formats;
+		fmts = raw_fmts;
 	else
 		/*
 		 * First pass - only count formats this host-sensor
 		 * configuration can provide
 		 */
-		for (i = 0; i < icd->num_formats; i++) {
+		for (i = 0; i < raw_fmts; i++) {
 			ret = ici->ops->get_formats(icd, i, NULL);
 			if (ret < 0)
 				return ret;
@@ -242,11 +236,12 @@ static int soc_camera_init_user_formats(
 
 	/* Second pass - actually fill data formats */
 	fmts = 0;
-	for (i = 0; i < icd->num_formats; i++)
+	for (i = 0; i < raw_fmts; i++)
 		if (!ici->ops->get_formats) {
-			icd->user_formats[i].host_fmt = icd->formats + i;
-			icd->user_formats[i].cam_fmt = icd->formats + i;
-			icd->user_formats[i].buswidth = icd->formats[i].depth;
+			v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
+			icd->user_formats[i].host_fmt =
+				soc_mbus_get_fmtdesc(code);
+			icd->user_formats[i].code = code;
 		} else {
 			ret = ici->ops->get_formats(icd, i,
 						    &icd->user_formats[fmts]);
@@ -255,7 +250,7 @@ static int soc_camera_init_user_formats(
 			fmts += ret;
 		}
 
-	icd->current_fmt = icd->user_formats[0].host_fmt;
+	icd->current_fmt = &icd->user_formats[0];
 
 	return 0;
 
@@ -281,7 +276,7 @@ static void soc_camera_free_user_formats
 #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
 	((x) >> 24) & 0xff
 
-/* Called with .vb_lock held */
+/* Called with .vb_lock held, or from the first open(2), see comment there */
 static int soc_camera_set_fmt(struct soc_camera_file *icf,
 			      struct v4l2_format *f)
 {
@@ -302,7 +297,7 @@ static int soc_camera_set_fmt(struct soc
 	if (ret < 0) {
 		return ret;
 	} else if (!icd->current_fmt ||
-		   icd->current_fmt->fourcc != pix->pixelformat) {
+		   icd->current_fmt->host_fmt->fourcc != pix->pixelformat) {
 		dev_err(&icd->dev,
 			"Host driver hasn't set up current format correctly!\n");
 		return -EINVAL;
@@ -310,6 +305,7 @@ static int soc_camera_set_fmt(struct soc
 
 	icd->user_width		= pix->width;
 	icd->user_height	= pix->height;
+	icd->colorspace		= pix->colorspace;
 	icf->vb_vidq.field	=
 		icd->field	= pix->field;
 
@@ -369,8 +365,9 @@ static int soc_camera_open(struct file *
 				.width		= icd->user_width,
 				.height		= icd->user_height,
 				.field		= icd->field,
-				.pixelformat	= icd->current_fmt->fourcc,
-				.colorspace	= icd->current_fmt->colorspace,
+				.colorspace	= icd->colorspace,
+				.pixelformat	=
+					icd->current_fmt->host_fmt->fourcc,
 			},
 		};
 
@@ -390,7 +387,12 @@ static int soc_camera_open(struct file *
 			goto eiciadd;
 		}
 
-		/* Try to configure with default parameters */
+		/*
+		 * Try to configure with default parameters. Notice: this is the
+		 * very first open, so, we cannot race against other calls,
+		 * apart from someone else calling open() simultaneously, but
+		 * .video_lock is protecting us against it.
+		 */
 		ret = soc_camera_set_fmt(icf, &f);
 		if (ret < 0)
 			goto esfmt;
@@ -534,7 +536,7 @@ static int soc_camera_enum_fmt_vid_cap(s
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
-	const struct soc_camera_data_format *format;
+	const struct soc_mbus_pixelfmt *format;
 
 	WARN_ON(priv != file->private_data);
 
@@ -543,7 +545,8 @@ static int soc_camera_enum_fmt_vid_cap(s
 
 	format = icd->user_formats[f->index].host_fmt;
 
-	strlcpy(f->description, format->name, sizeof(f->description));
+	if (format->name)
+		strlcpy(f->description, format->name, sizeof(f->description));
 	f->pixelformat = format->fourcc;
 	return 0;
 }
@@ -560,12 +563,15 @@ static int soc_camera_g_fmt_vid_cap(stru
 	pix->width		= icd->user_width;
 	pix->height		= icd->user_height;
 	pix->field		= icf->vb_vidq.field;
-	pix->pixelformat	= icd->current_fmt->fourcc;
-	pix->bytesperline	= pix->width *
-		DIV_ROUND_UP(icd->current_fmt->depth, 8);
+	pix->pixelformat	= icd->current_fmt->host_fmt->fourcc;
+	pix->bytesperline	= soc_mbus_bytes_per_line(pix->width,
+						icd->current_fmt->host_fmt);
+	pix->colorspace		= icd->colorspace;
+	if (pix->bytesperline < 0)
+		return pix->bytesperline;
 	pix->sizeimage		= pix->height * pix->bytesperline;
 	dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
-		icd->current_fmt->fourcc);
+		icd->current_fmt->host_fmt->fourcc);
 	return 0;
 }
 
@@ -621,8 +627,10 @@ static int soc_camera_streamoff(struct f
 
 	mutex_lock(&icd->video_lock);
 
-	/* This calls buf_release from host driver's videobuf_queue_ops for all
-	 * remaining buffers. When the last buffer is freed, stop capture */
+	/*
+	 * This calls buf_release from host driver's videobuf_queue_ops for all
+	 * remaining buffers. When the last buffer is freed, stop capture
+	 */
 	videobuf_streamoff(&icf->vb_vidq);
 
 	v4l2_subdev_call(sd, video, s_stream, 0);
@@ -892,7 +900,7 @@ static int soc_camera_probe(struct devic
 	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	struct device *control = NULL;
 	struct v4l2_subdev *sd;
-	struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
+	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	dev_info(dev, "Probing %s\n", dev_name(dev));
@@ -963,9 +971,11 @@ static int soc_camera_probe(struct devic
 
 	/* Try to improve our guess of a reasonable window format */
 	sd = soc_camera_to_subdev(icd);
-	if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
-		icd->user_width		= f.fmt.pix.width;
-		icd->user_height	= f.fmt.pix.height;
+	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;
 	}
 
 	/* Do we have to sysfs_remove_link() before device_unregister()? */
@@ -1004,8 +1014,10 @@ epower:
 	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 */
+/*
+ * This is called on device_unregister, which only means we have to disconnect
+ * from the host, but not remove ourselves from the device list
+ */
 static int soc_camera_remove(struct device *dev)
 {
 	struct soc_camera_device *icd = to_soc_camera_dev(dev);
@@ -1205,8 +1217,10 @@ static int soc_camera_device_register(st
 	}
 
 	if (num < 0)
-		/* ok, we have 256 cameras on this host...
-		 * man, stay reasonable... */
+		/*
+		 * ok, we have 256 cameras on this host...
+		 * man, stay reasonable...
+		 */
 		return -ENOMEM;
 
 	icd->devnum		= num;
@@ -1268,7 +1282,6 @@ static int video_dev_create(struct soc_c
 	vdev->fops		= &soc_camera_fops;
 	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
 	vdev->release		= video_device_release;
-	vdev->minor		= -1;
 	vdev->tvnorms		= V4L2_STD_UNKNOWN;
 
 	icd->vdev = vdev;
@@ -1291,8 +1304,7 @@ static int soc_camera_video_start(struct
 	    !icd->ops->set_bus_param)
 		return -EINVAL;
 
-	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
-				    icd->vdev->minor);
+	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
 		return ret;
@@ -1335,9 +1347,11 @@ escdevreg:
 	return ret;
 }
 
-/* Only called on rmmod for each platform device, since they are not
+/*
+ * Only called on rmmod for each platform device, since they are not
  * hot-pluggable. Now we know, that all our users - hosts and devices have
- * been unloaded already */
+ * been unloaded already
+ */
 static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
 {
 	struct soc_camera_device *icd = platform_get_drvdata(pdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/soc_camera_platform.c linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera_platform.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/soc_camera_platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/soc_camera_platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@
 
 struct soc_camera_platform_priv {
 	struct v4l2_subdev subdev;
-	struct soc_camera_data_format format;
 };
 
 static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
@@ -58,36 +57,36 @@ soc_camera_platform_query_bus_param(stru
 }
 
 static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
-				       struct v4l2_format *f)
+				       struct v4l2_mbus_framefmt *mf)
 {
 	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	pix->width = p->format.width;
-	pix->height = p->format.height;
+	mf->width	= p->format.width;
+	mf->height	= p->format.height;
+	mf->code	= p->format.code;
+	mf->colorspace	= p->format.colorspace;
+
 	return 0;
 }
 
-static void soc_camera_platform_video_probe(struct soc_camera_device *icd,
-					    struct platform_device *pdev)
+static struct v4l2_subdev_core_ops platform_subdev_core_ops;
+
+static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index,
+					enum v4l2_mbus_pixelcode *code)
 {
-	struct soc_camera_platform_priv *priv = get_priv(pdev);
-	struct soc_camera_platform_info *p = pdev->dev.platform_data;
+	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
 
-	priv->format.name = p->format_name;
-	priv->format.depth = p->format_depth;
-	priv->format.fourcc = p->format.pixelformat;
-	priv->format.colorspace = p->format.colorspace;
+	if (index)
+		return -EINVAL;
 
-	icd->formats = &priv->format;
-	icd->num_formats = 1;
+	*code = p->format.code;
+	return 0;
 }
 
-static struct v4l2_subdev_core_ops platform_subdev_core_ops;
-
 static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
 	.s_stream	= soc_camera_platform_s_stream,
-	.try_fmt	= soc_camera_platform_try_fmt,
+	.try_mbus_fmt	= soc_camera_platform_try_fmt,
+	.enum_mbus_fmt	= soc_camera_platform_enum_fmt,
 };
 
 static struct v4l2_subdev_ops platform_subdev_ops = {
@@ -128,13 +127,10 @@ static int soc_camera_platform_probe(str
 	/* Set the control device reference */
 	dev_set_drvdata(&icd->dev, &pdev->dev);
 
-	icd->y_skip_top		= 0;
-	icd->ops		= &soc_camera_platform_ops;
+	icd->ops = &soc_camera_platform_ops;
 
 	ici = to_soc_camera_host(icd->dev.parent);
 
-	soc_camera_platform_video_probe(icd, pdev);
-
 	v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
 	v4l2_set_subdevdata(&priv->subdev, p);
 	strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/soc_mediabus.c linux-libre-2.6.33-gnu1/drivers/media/video/soc_mediabus.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/soc_mediabus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/soc_mediabus.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,157 @@
+/*
+ * soc-camera media bus helper routines
+ *
+ * Copyright (C) 2009, 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/kernel.h>
+#include <linux/module.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-mediabus.h>
+#include <media/soc_mediabus.h>
+
+#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1)
+
+static const struct soc_mbus_pixelfmt mbus_fmt[] = {
+	[MBUS_IDX(YUYV8_2X8_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_YUYV,
+		.name			= "YUYV",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(YVYU8_2X8_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_YVYU,
+		.name			= "YVYU",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(YUYV8_2X8_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_UYVY,
+		.name			= "UYVY",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(YVYU8_2X8_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_VYUY,
+		.name			= "VYUY",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_RGB555,
+		.name			= "RGB555",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_RGB555X,
+		.name			= "RGB555X",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(RGB565_2X8_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_RGB565,
+		.name			= "RGB565",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(RGB565_2X8_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_RGB565X,
+		.name			= "RGB565X",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(SBGGR8_1X8)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR8,
+		.name			= "Bayer 8 BGGR",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(SBGGR10_1X10)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR10,
+		.name			= "Bayer 10 BGGR",
+		.bits_per_sample	= 10,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(GREY8_1X8)] = {
+		.fourcc			= V4L2_PIX_FMT_GREY,
+		.name			= "Grey",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(Y10_1X10)] = {
+		.fourcc			= V4L2_PIX_FMT_Y10,
+		.name			= "Grey 10bit",
+		.bits_per_sample	= 10,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR10,
+		.name			= "Bayer 10 BGGR",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR10,
+		.name			= "Bayer 10 BGGR",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADLO,
+		.order			= SOC_MBUS_ORDER_LE,
+	}, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR10,
+		.name			= "Bayer 10 BGGR",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_BE,
+	}, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR10,
+		.name			= "Bayer 10 BGGR",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADLO,
+		.order			= SOC_MBUS_ORDER_BE,
+	},
+};
+
+s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
+{
+	switch (mf->packing) {
+	case SOC_MBUS_PACKING_NONE:
+		return width * mf->bits_per_sample / 8;
+	case SOC_MBUS_PACKING_2X8_PADHI:
+	case SOC_MBUS_PACKING_2X8_PADLO:
+	case SOC_MBUS_PACKING_EXTEND16:
+		return width * 2;
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(soc_mbus_bytes_per_line);
+
+const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
+	enum v4l2_mbus_pixelcode code)
+{
+	if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt))
+		return NULL;
+	return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
+}
+EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
+
+static int __init soc_mbus_init(void)
+{
+	return 0;
+}
+
+static void __exit soc_mbus_exit(void)
+{
+}
+
+module_init(soc_mbus_init);
+module_exit(soc_mbus_exit);
+
+MODULE_DESCRIPTION("soc-camera media bus interface");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/stk-webcam.c linux-libre-2.6.33-gnu1/drivers/media/video/stk-webcam.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/stk-webcam.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/stk-webcam.c	2010-02-24 13:52:17.000000000 -0500
@@ -1307,7 +1307,6 @@ static void stk_v4l_dev_release(struct v
 
 static struct video_device stk_v4l_data = {
 	.name = "stkwebcam",
-	.minor = -1,
 	.tvnorms = V4L2_STD_UNKNOWN,
 	.current_norm = V4L2_STD_UNKNOWN,
 	.fops = &v4l_stk_fops,
@@ -1327,8 +1326,8 @@ static int stk_register_video_device(str
 	if (err)
 		STK_ERROR("v4l registration failed\n");
 	else
-		STK_INFO("Syntek USB2.0 Camera is now controlling video device"
-			" /dev/video%d\n", dev->vdev.num);
+		STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n",
+			 video_device_node_name(&dev->vdev));
 	return err;
 }
 
@@ -1418,8 +1417,8 @@ static void stk_camera_disconnect(struct
 	wake_up_interruptible(&dev->wait_frame);
 	stk_remove_sysfs_files(&dev->vdev);
 
-	STK_INFO("Syntek USB2.0 Camera release resources "
-		"video device /dev/video%d\n", dev->vdev.num);
+	STK_INFO("Syntek USB2.0 Camera release resources device %s\n",
+		 video_device_node_name(&dev->vdev));
 
 	video_unregister_device(&dev->vdev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/stradis.c linux-libre-2.6.33-gnu1/drivers/media/video/stradis.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/stradis.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/stradis.c	2010-02-24 13:52:17.000000000 -0500
@@ -1921,7 +1921,6 @@ static const struct v4l2_file_operations
 static struct video_device saa_template = {
 	.name = "SAA7146A",
 	.fops = &saa_fops,
-	.minor = -1,
 	.release = video_device_release_empty,
 };
 
@@ -1972,7 +1971,6 @@ static int __devinit configure_saa7146(s
 
 	saa->id = pdev->device;
 	saa->irq = pdev->irq;
-	saa->video_dev.minor = -1;
 	saa->saa7146_adr = pci_resource_start(pdev, 0);
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);
 
@@ -2134,7 +2132,7 @@ static void stradis_release_saa(struct p
 	free_irq(saa->irq, saa);
 	if (saa->saa7146_mem)
 		iounmap(saa->saa7146_mem);
-	if (saa->video_dev.minor != -1)
+	if (video_is_registered(&saa->video_dev))
 		video_unregister_device(&saa->video_dev);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/stv680.c linux-libre-2.6.33-gnu1/drivers/media/video/stv680.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/stv680.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/stv680.c	2010-02-24 13:52:17.000000000 -0500
@@ -1405,7 +1405,6 @@ static struct video_device stv680_templa
 	.name =		"STV0680 USB camera",
 	.fops =         &stv680_fops,
 	.release =	video_device_release,
-	.minor = 	-1,
 };
 
 static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
@@ -1467,8 +1466,8 @@ static int stv680_probe (struct usb_inte
 		retval = -EIO;
 		goto error_vdev;
 	}
-	PDEBUG(0, "STV(i): registered new video device: video%d",
-		stv680->vdev->num);
+	PDEBUG(0, "STV(i): registered new video device: %s",
+		video_device_node_name(stv680->vdev));
 
 	usb_set_intfdata (intf, stv680);
 	retval = stv680_create_sysfs_files(stv680->vdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/tuner-core.c linux-libre-2.6.33-gnu1/drivers/media/video/tuner-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/tuner-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/tuner-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -320,6 +320,7 @@ static void set_type(struct i2c_client *
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 	unsigned char buffer[4];
+	int tune_now = 1;
 
 	if (type == UNSET || type == TUNER_ABSENT) {
 		tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
@@ -328,7 +329,7 @@ static void set_type(struct i2c_client *
 
 	t->type = type;
 	/* prevent invalid config values */
-	t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
+	t->config = new_config < 256 ? new_config : 0;
 	if (tuner_callback != NULL) {
 		tuner_dbg("defining GPIO callback\n");
 		t->fe.callback = tuner_callback;
@@ -404,6 +405,7 @@ static void set_type(struct i2c_client *
 		};
 		if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	case TUNER_TDA9887:
@@ -419,6 +421,7 @@ static void set_type(struct i2c_client *
 		if (!dvb_attach(xc5000_attach,
 				&t->fe, t->i2c->adapter, &xc5000_cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	case TUNER_NXP_TDA18271:
@@ -430,6 +433,7 @@ static void set_type(struct i2c_client *
 		if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
 				t->i2c->adapter, &cfg))
 			goto attach_failed;
+		tune_now = 0;
 		break;
 	}
 	default:
@@ -458,12 +462,13 @@ static void set_type(struct i2c_client *
 	if (t->mode_mask == T_UNINITIALIZED)
 		t->mode_mask = new_mode_mask;
 
-	/* xc2028/3028 and xc5000 requires a firmware to be set-up later
+	/* Some tuners require more initialization setup before use,
+	   such as firmware download or device calibration.
 	   trying to set a frequency here will just fail
 	   FIXME: better to move set_freq to the tuner code. This is needed
 	   on analog tuners for PLL to properly work
 	 */
-	if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000)
+	if (tune_now)
 		set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
 			    t->radio_freq : t->tv_freq);
 
@@ -752,14 +757,17 @@ static int tuner_s_radio(struct v4l2_sub
 	return 0;
 }
 
-static int tuner_s_standby(struct v4l2_subdev *sd)
+static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
+	if (on)
+		return 0;
+
 	tuner_dbg("Putting tuner to sleep\n");
 
-	if (check_mode(t, "s_standby") == -EINVAL)
+	if (check_mode(t, "s_power") == -EINVAL)
 		return 0;
 	t->mode = T_STANDBY;
 	if (analog_ops->standby)
@@ -961,6 +969,7 @@ static int tuner_command(struct i2c_clie
 static const struct v4l2_subdev_core_ops tuner_core_ops = {
 	.log_status = tuner_log_status,
 	.s_std = tuner_s_std,
+	.s_power = tuner_s_power,
 };
 
 static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
@@ -971,7 +980,6 @@ static const struct v4l2_subdev_tuner_op
 	.g_frequency = tuner_g_frequency,
 	.s_type_addr = tuner_s_type_addr,
 	.s_config = tuner_s_config,
-	.s_standby = tuner_s_standby,
 };
 
 static const struct v4l2_subdev_ops tuner_ops = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/tvaudio.c linux-libre-2.6.33-gnu1/drivers/media/video/tvaudio.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/tvaudio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/tvaudio.c	2010-02-24 13:52:17.000000000 -0500
@@ -1919,7 +1919,7 @@ static const struct v4l2_subdev_tuner_op
 	.s_radio = tvaudio_s_radio,
 	.s_frequency = tvaudio_s_frequency,
 	.s_tuner = tvaudio_s_tuner,
-	.s_tuner = tvaudio_g_tuner,
+	.g_tuner = tvaudio_g_tuner,
 };
 
 static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/tvp514x.c linux-libre-2.6.33-gnu1/drivers/media/video/tvp514x.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/tvp514x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/tvp514x.c	2010-02-24 13:52:17.000000000 -0500
@@ -272,7 +272,7 @@ static int tvp514x_read_reg(struct v4l2_
 read_again:
 
 	err = i2c_smbus_read_byte_data(client, reg);
-	if (err == -1) {
+	if (err < 0) {
 		if (retry <= I2C_RETRY_COUNT) {
 			v4l2_warn(sd, "Read: retry ... %d\n", retry);
 			retry++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/tw9910.c linux-libre-2.6.33-gnu1/drivers/media/video/tw9910.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/tw9910.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/tw9910.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,7 @@
 #include <media/tw9910.h>
 
 #define GET_ID(val)  ((val & 0xF8) >> 3)
-#define GET_ReV(val) (val & 0x07)
+#define GET_REV(val) (val & 0x07)
 
 /*
  * register offset
@@ -117,7 +117,7 @@
 #define LCTL24		0x68
 #define LCTL25		0x69
 #define LCTL26		0x6A
-#define HSGEGIN		0x6B
+#define HSBEGIN		0x6B
 #define HSEND		0x6C
 #define OVSDLY		0x6D
 #define OVSEND		0x6E
@@ -152,7 +152,10 @@
 			 /* 1 : non-auto */
 #define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
 			 /* 0 : Vertical out ctrl by HACTIVE and DVALID */
-#define OEN         0x04 /* Output Enable together with TRI_SEL. */
+#define OEN_TRI_SEL_MASK	0x07
+#define OEN_TRI_SEL_ALL_ON	0x00 /* Enable output for Rev0/Rev1 */
+#define OEN_TRI_SEL_ALL_OFF_r0	0x06 /* All tri-stated for Rev0 */
+#define OEN_TRI_SEL_ALL_OFF_r1	0x07 /* All tri-stated for Rev1 */
 
 /* OUTCTR1 */
 #define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
@@ -178,11 +181,18 @@
 			  * but all register content remain unchanged.
 			  * This bit is self-resetting.
 			  */
+#define ACNTL1_PDN_MASK	0x0e
+#define CLK_PDN		0x08 /* system clock power down */
+#define Y_PDN		0x04 /* Luma ADC power down */
+#define C_PDN		0x02 /* Chroma ADC power down */
+
+/* ACNTL2 */
+#define ACNTL2_PDN_MASK	0x40
+#define PLL_PDN		0x40 /* PLL power down */
 
 /* VBICNTL */
-/* RTSEL : control the real time signal
-*          output from the MPOUT pin
-*/
+
+/* RTSEL : control the real time signal output from the MPOUT pin */
 #define RTSEL_MASK  0x07
 #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
 #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
@@ -226,28 +236,7 @@ struct tw9910_priv {
 	struct v4l2_subdev                subdev;
 	struct tw9910_video_info       *info;
 	const struct tw9910_scale_ctrl *scale;
-};
-
-/*
- * register settings
- */
-
-#define ENDMARKER { 0xff, 0xff }
-
-static const struct regval_list tw9910_default_regs[] =
-{
-	{ OPFORM,  0x00 },
-	{ OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
-	ENDMARKER,
-};
-
-static const struct soc_camera_data_format tw9910_color_fmt[] = {
-	{
-		.name       = "VYUY",
-		.fourcc     = V4L2_PIX_FMT_VYUY,
-		.depth      = 16,
-		.colorspace = V4L2_COLORSPACE_SMPTE170M,
-	}
+	u32                             revision;
 };
 
 static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
@@ -340,13 +329,6 @@ static const struct tw9910_scale_ctrl tw
 	},
 };
 
-static const struct tw9910_cropping_ctrl tw9910_cropping_ctrl = {
-	.vdelay  = 0x0012,
-	.vactive = 0x00F0,
-	.hdelay  = 0x0010,
-	.hactive = 0x02D0,
-};
-
 static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
 	.start = 0x0260,
 	.end   = 0x0300,
@@ -361,6 +343,19 @@ static struct tw9910_priv *to_tw9910(con
 			    subdev);
 }
 
+static int tw9910_mask_set(struct i2c_client *client, u8 command,
+			   u8 mask, u8 set)
+{
+	s32 val = i2c_smbus_read_byte_data(client, command);
+	if (val < 0)
+		return val;
+
+	val &= ~mask;
+	val |= set & mask;
+
+	return i2c_smbus_write_byte_data(client, command, val);
+}
+
 static int tw9910_set_scale(struct i2c_client *client,
 			    const struct tw9910_scale_ctrl *scale)
 {
@@ -383,47 +378,14 @@ static int tw9910_set_scale(struct i2c_c
 	return ret;
 }
 
-static int tw9910_set_cropping(struct i2c_client *client,
-			       const struct tw9910_cropping_ctrl *cropping)
-{
-	int ret;
-
-	ret = i2c_smbus_write_byte_data(client, CROP_HI,
-					(cropping->vdelay  & 0x0300) >> 2 |
-					(cropping->vactive & 0x0300) >> 4 |
-					(cropping->hdelay  & 0x0300) >> 6 |
-					(cropping->hactive & 0x0300) >> 8);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
-					cropping->vdelay & 0x00FF);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
-					cropping->vactive & 0x00FF);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(client, HDELAY_LO,
-					cropping->hdelay & 0x00FF);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(client, HACTIVE_LO,
-					cropping->hactive & 0x00FF);
-
-	return ret;
-}
-
 static int tw9910_set_hsync(struct i2c_client *client,
 			    const struct tw9910_hsync_ctrl *hsync)
 {
+	struct tw9910_priv *priv = to_tw9910(client);
 	int ret;
 
 	/* bit 10 - 3 */
-	ret = i2c_smbus_write_byte_data(client, HSGEGIN,
+	ret = i2c_smbus_write_byte_data(client, HSBEGIN,
 					(hsync->start & 0x07F8) >> 3);
 	if (ret < 0)
 		return ret;
@@ -434,50 +396,41 @@ static int tw9910_set_hsync(struct i2c_c
 	if (ret < 0)
 		return ret;
 
+	/* So far only revisions 0 and 1 have been seen */
 	/* bit 2 - 0 */
-	ret = i2c_smbus_read_byte_data(client, HSLOWCTL);
-	if (ret < 0)
-		return ret;
-
-	ret = i2c_smbus_write_byte_data(client, HSLOWCTL,
-					(ret & 0x88)                 |
-					(hsync->start & 0x0007) << 4 |
-					(hsync->end   & 0x0007));
+	if (1 == priv->revision)
+		ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
+				      (hsync->start & 0x0007) << 4 |
+				      (hsync->end   & 0x0007));
 
 	return ret;
 }
 
-static int tw9910_write_array(struct i2c_client *client,
-			      const struct regval_list *vals)
+static void tw9910_reset(struct i2c_client *client)
 {
-	while (vals->reg_num != 0xff) {
-		int ret = i2c_smbus_write_byte_data(client,
-						    vals->reg_num,
-						    vals->value);
-		if (ret < 0)
-			return ret;
-		vals++;
-	}
-	return 0;
+	tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
+	msleep(1);
 }
 
-static int tw9910_mask_set(struct i2c_client *client, u8 command,
-			   u8 mask, u8 set)
+static int tw9910_power(struct i2c_client *client, int enable)
 {
-	s32 val = i2c_smbus_read_byte_data(client, command);
-	if (val < 0)
-		return val;
+	int ret;
+	u8 acntl1;
+	u8 acntl2;
 
-	val &= ~mask;
-	val |= set & mask;
+	if (enable) {
+		acntl1 = 0;
+		acntl2 = 0;
+	} else {
+		acntl1 = CLK_PDN | Y_PDN | C_PDN;
+		acntl2 = PLL_PDN;
+	}
 
-	return i2c_smbus_write_byte_data(client, command, val);
-}
+	ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
+	if (ret < 0)
+		return ret;
 
-static void tw9910_reset(struct i2c_client *client)
-{
-	i2c_smbus_write_byte_data(client, ACNTL1, SRESET);
-	msleep(1);
+	return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
 }
 
 static const struct tw9910_scale_ctrl*
@@ -518,27 +471,62 @@ static int tw9910_s_stream(struct v4l2_s
 {
 	struct i2c_client *client = sd->priv;
 	struct tw9910_priv *priv = to_tw9910(client);
+	u8 val;
+	int ret;
 
-	if (!enable)
-		return 0;
+	if (!enable) {
+		switch (priv->revision) {
+		case 0:
+			val = OEN_TRI_SEL_ALL_OFF_r0;
+			break;
+		case 1:
+			val = OEN_TRI_SEL_ALL_OFF_r1;
+			break;
+		default:
+			dev_err(&client->dev, "un-supported revision\n");
+			return -EINVAL;
+		}
+	} else {
+		val = OEN_TRI_SEL_ALL_ON;
 
-	if (!priv->scale) {
-		dev_err(&client->dev, "norm select error\n");
-		return -EPERM;
+		if (!priv->scale) {
+			dev_err(&client->dev, "norm select error\n");
+			return -EPERM;
+		}
+
+		dev_dbg(&client->dev, "%s %dx%d\n",
+			priv->scale->name,
+			priv->scale->width,
+			priv->scale->height);
 	}
 
-	dev_dbg(&client->dev, "%s %dx%d\n",
-		 priv->scale->name,
-		 priv->scale->width,
-		 priv->scale->height);
+	ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
+	if (ret < 0)
+		return ret;
 
-	return 0;
+	return tw9910_power(client, enable);
 }
 
 static int tw9910_set_bus_param(struct soc_camera_device *icd,
 				unsigned long flags)
 {
-	return 0;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct i2c_client *client = sd->priv;
+	u8 val = VSSL_VVALID | HSSL_DVALID;
+
+	/*
+	 * set OUTCTR1
+	 *
+	 * We use VVALID and DVALID signals to control VSYNC and HSYNC
+	 * outputs, in this mode their polarity is inverted.
+	 */
+	if (flags & SOCAM_HSYNC_ACTIVE_LOW)
+		val |= HSP_HI;
+
+	if (flags & SOCAM_VSYNC_ACTIVE_LOW)
+		val |= VSP_HI;
+
+	return i2c_smbus_write_byte_data(client, OUTCTR1, val);
 }
 
 static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
@@ -548,6 +536,7 @@ static unsigned long tw9910_query_bus_pa
 	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
+		SOCAM_VSYNC_ACTIVE_LOW  | SOCAM_HSYNC_ACTIVE_LOW  |
 		SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
 
 	return soc_camera_apply_sensor_flags(icl, flags);
@@ -576,8 +565,11 @@ static int tw9910_enum_input(struct soc_
 static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
 			       struct v4l2_dbg_chip_ident *id)
 {
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
+
 	id->ident = V4L2_IDENT_TW9910;
-	id->revision = 0;
+	id->revision = priv->revision;
 
 	return 0;
 }
@@ -596,7 +588,8 @@ static int tw9910_g_register(struct v4l2
 	if (ret < 0)
 		return ret;
 
-	/* ret      = int
+	/*
+	 * ret      = int
 	 * reg->val = __u64
 	 */
 	reg->val = (__u64)ret;
@@ -637,9 +630,6 @@ static int tw9910_s_crop(struct v4l2_sub
 	 * reset hardware
 	 */
 	tw9910_reset(client);
-	ret = tw9910_write_array(client, tw9910_default_regs);
-	if (ret < 0)
-		goto tw9910_set_fmt_error;
 
 	/*
 	 * set bus width
@@ -688,13 +678,6 @@ static int tw9910_s_crop(struct v4l2_sub
 		goto tw9910_set_fmt_error;
 
 	/*
-	 * set cropping
-	 */
-	ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
-	if (ret < 0)
-		goto tw9910_set_fmt_error;
-
-	/*
 	 * set hsync
 	 */
 	ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
@@ -762,11 +745,11 @@ static int tw9910_cropcap(struct v4l2_su
 	return 0;
 }
 
-static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int tw9910_g_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct tw9910_priv *priv = to_tw9910(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
 	if (!priv->scale) {
 		int ret;
@@ -783,74 +766,76 @@ static int tw9910_g_fmt(struct v4l2_subd
 			return ret;
 	}
 
-	f->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	pix->width		= priv->scale->width;
-	pix->height		= priv->scale->height;
-	pix->pixelformat	= V4L2_PIX_FMT_VYUY;
-	pix->colorspace		= V4L2_COLORSPACE_SMPTE170M;
-	pix->field		= V4L2_FIELD_INTERLACED;
+	mf->width	= priv->scale->width;
+	mf->height	= priv->scale->height;
+	mf->code	= V4L2_MBUS_FMT_YUYV8_2X8_BE;
+	mf->colorspace	= V4L2_COLORSPACE_JPEG;
+	mf->field	= V4L2_FIELD_INTERLACED_BT;
 
 	return 0;
 }
 
-static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int tw9910_s_fmt(struct v4l2_subdev *sd,
+			struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct tw9910_priv *priv = to_tw9910(client);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	/* See tw9910_s_crop() - no proper cropping support */
 	struct v4l2_crop a = {
 		.c = {
 			.left	= 0,
 			.top	= 0,
-			.width	= pix->width,
-			.height	= pix->height,
+			.width	= mf->width,
+			.height	= mf->height,
 		},
 	};
-	int i, ret;
+	int ret;
+
+	WARN_ON(mf->field != V4L2_FIELD_ANY &&
+		mf->field != V4L2_FIELD_INTERLACED_BT);
 
 	/*
 	 * check color format
 	 */
-	for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
-		if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
-			break;
-
-	if (i == ARRAY_SIZE(tw9910_color_fmt))
+	if (mf->code != V4L2_MBUS_FMT_YUYV8_2X8_BE)
 		return -EINVAL;
 
+	mf->colorspace = V4L2_COLORSPACE_JPEG;
+
 	ret = tw9910_s_crop(sd, &a);
 	if (!ret) {
-		pix->width = priv->scale->width;
-		pix->height = priv->scale->height;
+		mf->width	= priv->scale->width;
+		mf->height	= priv->scale->height;
 	}
 	return ret;
 }
 
-static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int tw9910_try_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_mbus_framefmt *mf)
 {
 	struct i2c_client *client = sd->priv;
 	struct soc_camera_device *icd = client->dev.platform_data;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 	const struct tw9910_scale_ctrl *scale;
 
-	if (V4L2_FIELD_ANY == pix->field) {
-		pix->field = V4L2_FIELD_INTERLACED;
-	} else if (V4L2_FIELD_INTERLACED != pix->field) {
-		dev_err(&client->dev, "Field type invalid.\n");
+	if (V4L2_FIELD_ANY == mf->field) {
+		mf->field = V4L2_FIELD_INTERLACED_BT;
+	} else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
+		dev_err(&client->dev, "Field type %d invalid.\n", mf->field);
 		return -EINVAL;
 	}
 
+	mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
+	mf->colorspace = V4L2_COLORSPACE_JPEG;
+
 	/*
 	 * select suitable norm
 	 */
-	scale = tw9910_select_norm(icd, pix->width, pix->height);
+	scale = tw9910_select_norm(icd, mf->width, mf->height);
 	if (!scale)
 		return -EINVAL;
 
-	pix->width  = scale->width;
-	pix->height = scale->height;
+	mf->width	= scale->width;
+	mf->height	= scale->height;
 
 	return 0;
 }
@@ -859,7 +844,7 @@ static int tw9910_video_probe(struct soc
 			      struct i2c_client *client)
 {
 	struct tw9910_priv *priv = to_tw9910(client);
-	s32 val;
+	s32 id;
 
 	/*
 	 * We must have a parent by now. And it cannot be a wrong one.
@@ -878,23 +863,24 @@ static int tw9910_video_probe(struct soc
 		return -ENODEV;
 	}
 
-	icd->formats     = tw9910_color_fmt;
-	icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
-
 	/*
 	 * check and show Product ID
+	 * So far only revisions 0 and 1 have been seen
 	 */
-	val = i2c_smbus_read_byte_data(client, ID);
+	id = i2c_smbus_read_byte_data(client, ID);
+	priv->revision = GET_REV(id);
+	id = GET_ID(id);
 
-	if (0x0B != GET_ID(val) ||
-	    0x00 != GET_ReV(val)) {
+	if (0x0B != id ||
+	    0x01 < priv->revision) {
 		dev_err(&client->dev,
-			"Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
+			"Product ID error %x:%x\n",
+			id, priv->revision);
 		return -ENODEV;
 	}
 
 	dev_info(&client->dev,
-		 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
+		 "tw9910 Product ID %0x:%0x\n", id, priv->revision);
 
 	icd->vdev->tvnorms      = V4L2_STD_NTSC | V4L2_STD_PAL;
 	icd->vdev->current_norm = V4L2_STD_NTSC;
@@ -917,14 +903,25 @@ static struct v4l2_subdev_core_ops tw991
 #endif
 };
 
+static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index,
+			   enum v4l2_mbus_pixelcode *code)
+{
+	if (index)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_YUYV8_2X8_BE;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
 	.s_stream	= tw9910_s_stream,
-	.g_fmt		= tw9910_g_fmt,
-	.s_fmt		= tw9910_s_fmt,
-	.try_fmt	= tw9910_try_fmt,
+	.g_mbus_fmt	= tw9910_g_fmt,
+	.s_mbus_fmt	= tw9910_s_fmt,
+	.try_mbus_fmt	= tw9910_try_fmt,
 	.cropcap	= tw9910_cropcap,
 	.g_crop		= tw9910_g_crop,
 	.s_crop		= tw9910_s_crop,
+	.enum_mbus_fmt	= tw9910_enum_fmt,
 };
 
 static struct v4l2_subdev_ops tw9910_subdev_ops = {
@@ -954,10 +951,10 @@ static int tw9910_probe(struct i2c_clien
 	}
 
 	icl = to_soc_camera_link(icd);
-	if (!icl)
+	if (!icl || !icl->priv)
 		return -EINVAL;
 
-	info = container_of(icl, struct tw9910_video_info, link);
+	info = icl->priv;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&client->dev,
@@ -975,7 +972,7 @@ static int tw9910_probe(struct i2c_clien
 	v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
 
 	icd->ops     = &tw9910_ops;
-	icd->iface   = info->link.bus_id;
+	icd->iface   = icl->bus_id;
 
 	ret = tw9910_video_probe(icd, client);
 	if (ret) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/konicawc.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/konicawc.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/konicawc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/konicawc.c	2010-02-24 13:52:17.000000000 -0500
@@ -225,7 +225,7 @@ static void konicawc_register_input(stru
 	int error;
 
 	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
-	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+	strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/quickcam_messenger.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,7 +89,7 @@ static void qcm_register_input(struct qc
 	int error;
 
 	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
-	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+	strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/usbvideo.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/usbvideo.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/usbvideo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/usbvideo.c	2010-02-24 13:52:17.000000000 -0500
@@ -1053,9 +1053,9 @@ int usbvideo_RegisterVideoDevice(struct
 			 "%s: video_register_device() successful\n", __func__);
 	}
 
-	dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n",
+	dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n",
 		 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
-		 uvd->vdev.num, tmp2, tmp1);
+		 video_device_node_name(&uvd->vdev), tmp2, tmp1);
 
 	usb_get_dev(uvd->dev);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/vicam.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/vicam.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvideo/vicam.c	2013-05-03 13:59:00.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvideo/vicam.c	2013-05-03 12:07:33.000000000 -0400
@@ -796,7 +796,6 @@ static const struct v4l2_file_operations
 static struct video_device vicam_template = {
 	.name 		= "ViCam-based USB Camera",
 	.fops 		= &vicam_fops,
-	.minor 		= -1,
 	.release 	= video_device_release_empty,
 };
 
@@ -873,8 +872,8 @@ vicam_probe( struct usb_interface *intf,
 		return -EIO;
 	}
 
-	printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",
-			cam->vdev.num);
+	printk(KERN_INFO "ViCam webcam driver now controlling device %s\n",
+		video_device_node_name(&cam->vdev));
 
 	usb_set_intfdata (intf, cam);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvision/usbvision-i2c.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-i2c.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2010-02-24 13:52:17.000000000 -0500
@@ -215,8 +215,8 @@ int usbvision_i2c_register(struct usb_us
 	memcpy(&usbvision->i2c_adap, &i2c_adap_template,
 	       sizeof(struct i2c_adapter));
 
-	sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
-		" #%d", usbvision->vdev->num);
+	sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name,
+		usbvision->dev->bus->busnum, usbvision->dev->devpath);
 	PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
 	usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/usbvision/usbvision-video.c linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/usbvision/usbvision-video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/usbvision/usbvision-video.c	2010-02-24 13:52:17.000000000 -0500
@@ -601,7 +601,7 @@ static int vidioc_s_input (struct file *
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
 
-	if ((input >= usbvision->video_inputs) || (input < 0) )
+	if (input >= usbvision->video_inputs)
 		return -EINVAL;
 
 	mutex_lock(&usbvision->lock);
@@ -1328,7 +1328,6 @@ static struct video_device usbvision_vid
 	.ioctl_ops 	= &usbvision_ioctl_ops,
 	.name           = "usbvision-video",
 	.release	= video_device_release,
-	.minor		= -1,
 	.tvnorms              = USBVISION_NORMS,
 	.current_norm         = V4L2_STD_PAL
 };
@@ -1362,7 +1361,6 @@ static struct video_device usbvision_rad
 	.fops		= &usbvision_radio_fops,
 	.name           = "usbvision-radio",
 	.release	= video_device_release,
-	.minor		= -1,
 	.ioctl_ops 	= &usbvision_radio_ioctl_ops,
 
 	.tvnorms              = USBVISION_NORMS,
@@ -1382,7 +1380,6 @@ static struct video_device usbvision_vbi
 	.fops		= &usbvision_vbi_fops,
 	.release	= video_device_release,
 	.name           = "usbvision-vbi",
-	.minor		= -1,
 };
 
 
@@ -1404,7 +1401,6 @@ static struct video_device *usbvision_vd
 		return NULL;
 	}
 	*vdev = *vdev_template;
-//	vdev->minor   = -1;
 	vdev->v4l2_dev = &usbvision->v4l2_dev;
 	snprintf(vdev->name, sizeof(vdev->name), "%s", name);
 	video_set_drvdata(vdev, usbvision);
@@ -1416,9 +1412,9 @@ static void usbvision_unregister_video(s
 {
 	// vbi Device:
 	if (usbvision->vbi) {
-		PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]",
-		       usbvision->vbi->num);
-		if (usbvision->vbi->minor != -1) {
+		PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
+		       video_device_node_name(usbvision->vbi));
+		if (video_is_registered(usbvision->vbi)) {
 			video_unregister_device(usbvision->vbi);
 		} else {
 			video_device_release(usbvision->vbi);
@@ -1428,9 +1424,9 @@ static void usbvision_unregister_video(s
 
 	// Radio Device:
 	if (usbvision->rdev) {
-		PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]",
-		       usbvision->rdev->num);
-		if (usbvision->rdev->minor != -1) {
+		PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
+		       video_device_node_name(usbvision->rdev));
+		if (video_is_registered(usbvision->rdev)) {
 			video_unregister_device(usbvision->rdev);
 		} else {
 			video_device_release(usbvision->rdev);
@@ -1440,9 +1436,9 @@ static void usbvision_unregister_video(s
 
 	// Video Device:
 	if (usbvision->vdev) {
-		PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]",
-		       usbvision->vdev->num);
-		if (usbvision->vdev->minor != -1) {
+		PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
+		       video_device_node_name(usbvision->vdev));
+		if (video_is_registered(usbvision->vdev)) {
 			video_unregister_device(usbvision->vdev);
 		} else {
 			video_device_release(usbvision->vdev);
@@ -1466,8 +1462,8 @@ static int __devinit usbvision_register_
 				  video_nr)<0) {
 		goto err_exit;
 	}
-	printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n",
-	       usbvision->nr, usbvision->vdev->num);
+	printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
+	       usbvision->nr, video_device_node_name(usbvision->vdev));
 
 	// Radio Device:
 	if (usbvision_device_data[usbvision->DevModel].Radio) {
@@ -1483,8 +1479,8 @@ static int __devinit usbvision_register_
 					  radio_nr)<0) {
 			goto err_exit;
 		}
-		printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n",
-		       usbvision->nr, usbvision->rdev->num);
+		printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n",
+		       usbvision->nr, video_device_node_name(usbvision->rdev));
 	}
 	// vbi Device:
 	if (usbvision_device_data[usbvision->DevModel].vbi) {
@@ -1499,8 +1495,8 @@ static int __devinit usbvision_register_
 					  vbi_nr)<0) {
 			goto err_exit;
 		}
-		printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n",
-		       usbvision->nr, usbvision->vbi->num);
+		printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device %s [v4l2] (Not Working Yet!)\n",
+		       usbvision->nr, video_device_node_name(usbvision->vbi));
 	}
 	// all done
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_ctrl.c linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_ctrl.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -742,17 +742,7 @@ struct uvc_control *uvc_find_control(str
 	v4l2_id &= V4L2_CTRL_ID_MASK;
 
 	/* Find the control. */
-	__uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
-	if (ctrl && !next)
-		return ctrl;
-
-	list_for_each_entry(entity, &chain->iterms, chain) {
-		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
-		if (ctrl && !next)
-			return ctrl;
-	}
-
-	list_for_each_entry(entity, &chain->extensions, chain) {
+	list_for_each_entry(entity, &chain->entities, chain) {
 		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
 		if (ctrl && !next)
 			return ctrl;
@@ -826,6 +816,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video
 		ret = 0;
 		goto out;
 
+	case V4L2_CTRL_TYPE_BUTTON:
+		v4l2_ctrl->minimum = 0;
+		v4l2_ctrl->maximum = 0;
+		v4l2_ctrl->step = 0;
+		ret = 0;
+		goto out;
+
 	default:
 		break;
 	}
@@ -944,17 +941,7 @@ int __uvc_ctrl_commit(struct uvc_video_c
 	int ret = 0;
 
 	/* Find the control. */
-	ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
-	if (ret < 0)
-		goto done;
-
-	list_for_each_entry(entity, &chain->iterms, chain) {
-		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
-		if (ret < 0)
-			goto done;
-	}
-
-	list_for_each_entry(entity, &chain->extensions, chain) {
+	list_for_each_entry(entity, &chain->entities, chain) {
 		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
 		if (ret < 0)
 			goto done;
@@ -1068,8 +1055,9 @@ int uvc_xu_ctrl_query(struct uvc_video_c
 	int ret;
 
 	/* Find the extension unit. */
-	list_for_each_entry(entity, &chain->extensions, chain) {
-		if (entity->id == xctrl->unit)
+	list_for_each_entry(entity, &chain->entities, chain) {
+		if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
+		    entity->id == xctrl->unit)
 			break;
 	}
 
@@ -1405,7 +1393,7 @@ uvc_ctrl_prune_entity(struct uvc_device
 	size = entity->processing.bControlSize;
 
 	for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
-		if (!usb_match_id(dev->intf, &blacklist[i].id))
+		if (!usb_match_one_id(dev->intf, &blacklist[i].id))
 			continue;
 
 		if (blacklist[i].index >= 8 * size ||
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_driver.c linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_driver.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,6 +46,7 @@
 unsigned int uvc_no_drop_param;
 static unsigned int uvc_quirks_param;
 unsigned int uvc_trace_param;
+unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
 
 /* ------------------------------------------------------------------------
  * Video formats
@@ -248,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_
 		entity = list_entry(&dev->entities, struct uvc_entity, list);
 
 	list_for_each_entry_continue(entity, &dev->entities, list) {
-		switch (UVC_ENTITY_TYPE(entity)) {
-		case UVC_TT_STREAMING:
-			if (entity->output.bSourceID == id)
-				return entity;
-			break;
-
-		case UVC_VC_PROCESSING_UNIT:
-			if (entity->processing.bSourceID == id)
+		for (i = 0; i < entity->bNrInPins; ++i)
+			if (entity->baSourceID[i] == id)
 				return entity;
-			break;
-
-		case UVC_VC_SELECTOR_UNIT:
-			for (i = 0; i < entity->selector.bNrInPins; ++i)
-				if (entity->selector.baSourceID[i] == id)
-					return entity;
-			break;
-
-		case UVC_VC_EXTENSION_UNIT:
-			for (i = 0; i < entity->extension.bNrInPins; ++i)
-				if (entity->extension.baSourceID[i] == id)
-					return entity;
-			break;
-		}
 	}
 
 	return NULL;
@@ -426,7 +407,8 @@ static int uvc_parse_format(struct uvc_d
 	/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
 	 * based formats have frame descriptors.
 	 */
-	while (buflen > 2 && buffer[2] == ftype) {
+	while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	       buffer[2] == ftype) {
 		frame = &format->frame[format->nframes];
 		if (ftype != UVC_VS_FRAME_FRAME_BASED)
 			n = buflen > 25 ? buffer[25] : 0;
@@ -503,12 +485,14 @@ static int uvc_parse_format(struct uvc_d
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
+	if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	    buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
 		buflen -= buffer[0];
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) {
+	if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	    buffer[2] == UVC_VS_COLORFORMAT) {
 		if (buflen < 6) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d COLORFORMAT error\n",
@@ -749,6 +733,11 @@ static int uvc_parse_streaming(struct uv
 		buffer += buffer[0];
 	}
 
+	if (buflen)
+		uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+			"%d has %u bytes of trailing descriptor garbage.\n",
+			dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
+
 	/* Parse the alternate settings to find the maximum bandwidth. */
 	for (i = 0; i < intf->num_altsetting; ++i) {
 		struct usb_host_endpoint *ep;
@@ -776,6 +765,28 @@ error:
 	return ret;
 }
 
+static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
+		unsigned int num_pads, unsigned int extra_size)
+{
+	struct uvc_entity *entity;
+	unsigned int num_inputs;
+	unsigned int size;
+
+	num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
+	size = sizeof(*entity) + extra_size + num_inputs;
+	entity = kzalloc(size, GFP_KERNEL);
+	if (entity == NULL)
+		return NULL;
+
+	entity->id = id;
+	entity->type = type;
+
+	entity->bNrInPins = num_inputs;
+	entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
+
+	return entity;
+}
+
 /* Parse vendor-specific extensions. */
 static int uvc_parse_vendor_control(struct uvc_device *dev,
 	const unsigned char *buffer, int buflen)
@@ -827,21 +838,18 @@ static int uvc_parse_vendor_control(stru
 			break;
 		}
 
-		unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL);
+		unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
+					p + 1, 2*n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = UVC_VC_EXTENSION_UNIT;
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
-		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->extension.baSourceID, &buffer[22], p);
+		memcpy(unit->baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
-		unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
-		unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit
-					       + p + n;
+		unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
+		unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
+					       + n;
 		memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
 
 		if (buffer[24+p+2*n] != 0)
@@ -938,13 +946,11 @@ static int uvc_parse_standard_control(st
 			return -EINVAL;
 		}
 
-		term = kzalloc(sizeof *term + n + p, GFP_KERNEL);
+		term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
+					1, n + p);
 		if (term == NULL)
 			return -ENOMEM;
 
-		term->id = buffer[3];
-		term->type = type | UVC_TERM_INPUT;
-
 		if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
 			term->camera.bControlSize = n;
 			term->camera.bmControls = (__u8 *)term + sizeof *term;
@@ -999,13 +1005,12 @@ static int uvc_parse_standard_control(st
 			return 0;
 		}
 
-		term = kzalloc(sizeof *term, GFP_KERNEL);
+		term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
+					1, 0);
 		if (term == NULL)
 			return -ENOMEM;
 
-		term->id = buffer[3];
-		term->type = type | UVC_TERM_OUTPUT;
-		term->output.bSourceID = buffer[7];
+		memcpy(term->baSourceID, &buffer[7], 1);
 
 		if (buffer[8] != 0)
 			usb_string(udev, buffer[8], term->name,
@@ -1026,15 +1031,11 @@ static int uvc_parse_standard_control(st
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + p, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
-		unit->selector.bNrInPins = buffer[4];
-		unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->selector.baSourceID, &buffer[5], p);
+		memcpy(unit->baSourceID, &buffer[5], p);
 
 		if (buffer[5+p] != 0)
 			usb_string(udev, buffer[5+p], unit->name,
@@ -1056,13 +1057,11 @@ static int uvc_parse_standard_control(st
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + n, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
-		unit->processing.bSourceID = buffer[4];
+		memcpy(unit->baSourceID, &buffer[4], 1);
 		unit->processing.wMaxMultiplier =
 			get_unaligned_le16(&buffer[5]);
 		unit->processing.bControlSize = buffer[7];
@@ -1091,19 +1090,15 @@ static int uvc_parse_standard_control(st
 			return -EINVAL;
 		}
 
-		unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL);
+		unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
 		if (unit == NULL)
 			return -ENOMEM;
 
-		unit->id = buffer[3];
-		unit->type = buffer[2];
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
-		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
-		memcpy(unit->extension.baSourceID, &buffer[22], p);
+		memcpy(unit->baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
-		unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
+		unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
 		memcpy(unit->extension.bmControls, &buffer[23+p], n);
 
 		if (buffer[23+p+n] != 0)
@@ -1209,13 +1204,12 @@ static int uvc_scan_chain_entity(struct
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- XU %d", entity->id);
 
-		if (entity->extension.bNrInPins != 1) {
+		if (entity->bNrInPins != 1) {
 			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
 				"than 1 input pin.\n", entity->id);
 			return -1;
 		}
 
-		list_add_tail(&entity->chain, &chain->extensions);
 		break;
 
 	case UVC_VC_PROCESSING_UNIT:
@@ -1236,7 +1230,7 @@ static int uvc_scan_chain_entity(struct
 			printk(" <- SU %d", entity->id);
 
 		/* Single-input selector units are ignored. */
-		if (entity->selector.bNrInPins == 1)
+		if (entity->bNrInPins == 1)
 			break;
 
 		if (chain->selector != NULL) {
@@ -1254,20 +1248,17 @@ static int uvc_scan_chain_entity(struct
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- IT %d\n", entity->id);
 
-		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
 	case UVC_TT_STREAMING:
-		if (uvc_trace_param & UVC_TRACE_PROBE)
-			printk(" <- IT %d\n", entity->id);
-
-		if (!UVC_ENTITY_IS_ITERM(entity)) {
-			uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
-				"terminal %u.\n", entity->id);
-			return -1;
+		if (UVC_ENTITY_IS_ITERM(entity)) {
+			if (uvc_trace_param & UVC_TRACE_PROBE)
+				printk(" <- IT %d\n", entity->id);
+		} else {
+			if (uvc_trace_param & UVC_TRACE_PROBE)
+				printk(" OT %d", entity->id);
 		}
 
-		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
 	default:
@@ -1276,6 +1267,7 @@ static int uvc_scan_chain_entity(struct
 		return -1;
 	}
 
+	list_add_tail(&entity->chain, &chain->entities);
 	return 0;
 }
 
@@ -1299,14 +1291,14 @@ static int uvc_scan_chain_forward(struct
 
 		switch (UVC_ENTITY_TYPE(forward)) {
 		case UVC_VC_EXTENSION_UNIT:
-			if (forward->extension.bNrInPins != 1) {
+			if (forward->bNrInPins != 1) {
 				uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
 					  "has more than 1 input pin.\n",
 					  entity->id);
 				return -EINVAL;
 			}
 
-			list_add_tail(&forward->chain, &chain->extensions);
+			list_add_tail(&forward->chain, &chain->entities);
 			if (uvc_trace_param & UVC_TRACE_PROBE) {
 				if (!found)
 					printk(" (->");
@@ -1326,7 +1318,7 @@ static int uvc_scan_chain_forward(struct
 				return -EINVAL;
 			}
 
-			list_add_tail(&forward->chain, &chain->oterms);
+			list_add_tail(&forward->chain, &chain->entities);
 			if (uvc_trace_param & UVC_TRACE_PROBE) {
 				if (!found)
 					printk(" (->");
@@ -1344,24 +1336,22 @@ static int uvc_scan_chain_forward(struct
 }
 
 static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
-	struct uvc_entity *entity)
+	struct uvc_entity **_entity)
 {
+	struct uvc_entity *entity = *_entity;
 	struct uvc_entity *term;
-	int id = -1, i;
+	int id = -EINVAL, i;
 
 	switch (UVC_ENTITY_TYPE(entity)) {
 	case UVC_VC_EXTENSION_UNIT:
-		id = entity->extension.baSourceID[0];
-		break;
-
 	case UVC_VC_PROCESSING_UNIT:
-		id = entity->processing.bSourceID;
+		id = entity->baSourceID[0];
 		break;
 
 	case UVC_VC_SELECTOR_UNIT:
 		/* Single-input selector units are ignored. */
-		if (entity->selector.bNrInPins == 1) {
-			id = entity->selector.baSourceID[0];
+		if (entity->bNrInPins == 1) {
+			id = entity->baSourceID[0];
 			break;
 		}
 
@@ -1369,8 +1359,8 @@ static int uvc_scan_chain_backward(struc
 			printk(" <- IT");
 
 		chain->selector = entity;
-		for (i = 0; i < entity->selector.bNrInPins; ++i) {
-			id = entity->selector.baSourceID[i];
+		for (i = 0; i < entity->bNrInPins; ++i) {
+			id = entity->baSourceID[i];
 			term = uvc_entity_by_id(chain->dev, id);
 			if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
 				uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
@@ -1382,7 +1372,7 @@ static int uvc_scan_chain_backward(struc
 			if (uvc_trace_param & UVC_TRACE_PROBE)
 				printk(" %d", term->id);
 
-			list_add_tail(&term->chain, &chain->iterms);
+			list_add_tail(&term->chain, &chain->entities);
 			uvc_scan_chain_forward(chain, term, entity);
 		}
 
@@ -1391,34 +1381,49 @@ static int uvc_scan_chain_backward(struc
 
 		id = 0;
 		break;
+
+	case UVC_ITT_VENDOR_SPECIFIC:
+	case UVC_ITT_CAMERA:
+	case UVC_ITT_MEDIA_TRANSPORT_INPUT:
+	case UVC_OTT_VENDOR_SPECIFIC:
+	case UVC_OTT_DISPLAY:
+	case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
+	case UVC_TT_STREAMING:
+		id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
+		break;
 	}
 
-	return id;
+	if (id <= 0) {
+		*_entity = NULL;
+		return id;
+	}
+
+	entity = uvc_entity_by_id(chain->dev, id);
+	if (entity == NULL) {
+		uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+			"unknown entity %d.\n", id);
+		return -EINVAL;
+	}
+
+	*_entity = entity;
+	return 0;
 }
 
 static int uvc_scan_chain(struct uvc_video_chain *chain,
-			  struct uvc_entity *oterm)
+			  struct uvc_entity *term)
 {
 	struct uvc_entity *entity, *prev;
-	int id;
 
-	entity = oterm;
-	list_add_tail(&entity->chain, &chain->oterms);
-	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
+	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
 
-	id = entity->output.bSourceID;
-	while (id != 0) {
-		prev = entity;
-		entity = uvc_entity_by_id(chain->dev, id);
-		if (entity == NULL) {
-			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
-				"unknown entity %d.\n", id);
-			return -EINVAL;
-		}
+	entity = term;
+	prev = NULL;
 
+	while (entity != NULL) {
+		/* Entity must not be part of an existing chain */
 		if (entity->chain.next || entity->chain.prev) {
 			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
-				"entity %d already in chain.\n", id);
+				"entity %d already in chain.\n", entity->id);
 			return -EINVAL;
 		}
 
@@ -1430,34 +1435,34 @@ static int uvc_scan_chain(struct uvc_vid
 		if (uvc_scan_chain_forward(chain, entity, prev) < 0)
 			return -EINVAL;
 
-		/* Stop when a terminal is found. */
-		if (UVC_ENTITY_IS_TERM(entity))
-			break;
-
 		/* Backward scan */
-		id = uvc_scan_chain_backward(chain, entity);
-		if (id < 0)
-			return id;
+		prev = entity;
+		if (uvc_scan_chain_backward(chain, &entity) < 0)
+			return -EINVAL;
 	}
 
 	return 0;
 }
 
-static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
+static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
+		char *buffer)
 {
 	struct uvc_entity *term;
 	unsigned int nterms = 0;
 	char *p = buffer;
 
 	list_for_each_entry(term, terms, chain) {
-		p += sprintf(p, "%u", term->id);
-		if (term->chain.next != terms) {
+		if (!UVC_ENTITY_IS_TERM(term) ||
+		    UVC_TERM_DIRECTION(term) != dir)
+			continue;
+
+		if (nterms)
 			p += sprintf(p, ",");
-			if (++nterms >= 4) {
-				p += sprintf(p, "...");
-				break;
-			}
+		if (++nterms >= 4) {
+			p += sprintf(p, "...");
+			break;
 		}
+		p += sprintf(p, "%u", term->id);
 	}
 
 	return p - buffer;
@@ -1468,9 +1473,9 @@ static const char *uvc_print_chain(struc
 	static char buffer[43];
 	char *p = buffer;
 
-	p += uvc_print_terms(&chain->iterms, p);
+	p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
 	p += sprintf(p, " -> ");
-	uvc_print_terms(&chain->oterms, p);
+	uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
 
 	return buffer;
 }
@@ -1501,9 +1506,7 @@ static int uvc_scan_device(struct uvc_de
 		if (chain == NULL)
 			return -ENOMEM;
 
-		INIT_LIST_HEAD(&chain->iterms);
-		INIT_LIST_HEAD(&chain->oterms);
-		INIT_LIST_HEAD(&chain->extensions);
+		INIT_LIST_HEAD(&chain->entities);
 		mutex_init(&chain->ctrl_mutex);
 		chain->dev = dev;
 
@@ -1531,22 +1534,92 @@ static int uvc_scan_device(struct uvc_de
  */
 
 /*
+ * Delete the UVC device.
+ *
+ * Called by the kernel when the last reference to the uvc_device structure
+ * is released.
+ *
+ * As this function is called after or during disconnect(), all URBs have
+ * already been canceled by the USB core. There is no need to kill the
+ * interrupt URB manually.
+ */
+static void uvc_delete(struct uvc_device *dev)
+{
+	struct list_head *p, *n;
+
+	usb_put_intf(dev->intf);
+	usb_put_dev(dev->udev);
+
+	uvc_status_cleanup(dev);
+	uvc_ctrl_cleanup_device(dev);
+
+	list_for_each_safe(p, n, &dev->chains) {
+		struct uvc_video_chain *chain;
+		chain = list_entry(p, struct uvc_video_chain, list);
+		kfree(chain);
+	}
+
+	list_for_each_safe(p, n, &dev->entities) {
+		struct uvc_entity *entity;
+		entity = list_entry(p, struct uvc_entity, list);
+		kfree(entity);
+	}
+
+	list_for_each_safe(p, n, &dev->streams) {
+		struct uvc_streaming *streaming;
+		streaming = list_entry(p, struct uvc_streaming, list);
+		usb_driver_release_interface(&uvc_driver.driver,
+			streaming->intf);
+		usb_put_intf(streaming->intf);
+		kfree(streaming->format);
+		kfree(streaming->header.bmaControls);
+		kfree(streaming);
+	}
+
+	kfree(dev);
+}
+
+static void uvc_release(struct video_device *vdev)
+{
+	struct uvc_streaming *stream = video_get_drvdata(vdev);
+	struct uvc_device *dev = stream->dev;
+
+	video_device_release(vdev);
+
+	/* Decrement the registered streams count and delete the device when it
+	 * reaches zero.
+	 */
+	if (atomic_dec_and_test(&dev->nstreams))
+		uvc_delete(dev);
+}
+
+/*
  * Unregister the video devices.
  */
 static void uvc_unregister_video(struct uvc_device *dev)
 {
 	struct uvc_streaming *stream;
 
+	/* Unregistering all video devices might result in uvc_delete() being
+	 * called from inside the loop if there's no open file handle. To avoid
+	 * that, increment the stream count before iterating over the streams
+	 * and decrement it when done.
+	 */
+	atomic_inc(&dev->nstreams);
+
 	list_for_each_entry(stream, &dev->streams, list) {
 		if (stream->vdev == NULL)
 			continue;
 
-		if (stream->vdev->minor == -1)
-			video_device_release(stream->vdev);
-		else
-			video_unregister_device(stream->vdev);
+		video_unregister_device(stream->vdev);
 		stream->vdev = NULL;
 	}
+
+	/* Decrement the stream count and call uvc_delete explicitly if there
+	 * are no stream left.
+	 */
+	if (atomic_dec_and_test(&dev->nstreams))
+		uvc_delete(dev);
 }
 
 static int uvc_register_video(struct uvc_device *dev,
@@ -1578,9 +1651,8 @@ static int uvc_register_video(struct uvc
 	 * get another one.
 	 */
 	vdev->parent = &dev->intf->dev;
-	vdev->minor = -1;
 	vdev->fops = &uvc_fops;
-	vdev->release = video_device_release;
+	vdev->release = uvc_release;
 	strlcpy(vdev->name, dev->name, sizeof vdev->name);
 
 	/* Set the driver data before calling video_register_device, otherwise
@@ -1598,6 +1670,7 @@ static int uvc_register_video(struct uvc
 		return ret;
 	}
 
+	atomic_inc(&dev->nstreams);
 	return 0;
 }
 
@@ -1605,13 +1678,13 @@ static int uvc_register_video(struct uvc
  * Register all video devices in all chains.
  */
 static int uvc_register_terms(struct uvc_device *dev,
-	struct uvc_video_chain *chain, struct list_head *terms)
+	struct uvc_video_chain *chain)
 {
 	struct uvc_streaming *stream;
 	struct uvc_entity *term;
 	int ret;
 
-	list_for_each_entry(term, terms, chain) {
+	list_for_each_entry(term, &chain->entities, chain) {
 		if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
 			continue;
 
@@ -1637,11 +1710,7 @@ static int uvc_register_chains(struct uv
 	int ret;
 
 	list_for_each_entry(chain, &dev->chains, list) {
-		ret = uvc_register_terms(dev, chain, &chain->iterms);
-		if (ret < 0)
-			return ret;
-
-		ret = uvc_register_terms(dev, chain, &chain->oterms);
+		ret = uvc_register_terms(dev, chain);
 		if (ret < 0)
 			return ret;
 	}
@@ -1653,61 +1722,6 @@ static int uvc_register_chains(struct uv
  * USB probe, disconnect, suspend and resume
  */
 
-/*
- * Delete the UVC device.
- *
- * Called by the kernel when the last reference to the uvc_device structure
- * is released.
- *
- * Unregistering the video devices is done here because every opened instance
- * must be closed before the device can be unregistered. An alternative would
- * have been to use another reference count for uvc_v4l2_open/uvc_release, and
- * unregister the video devices on disconnect when that reference count drops
- * to zero.
- *
- * As this function is called after or during disconnect(), all URBs have
- * already been canceled by the USB core. There is no need to kill the
- * interrupt URB manually.
- */
-void uvc_delete(struct kref *kref)
-{
-	struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
-	struct list_head *p, *n;
-
-	/* Unregister the video devices. */
-	uvc_unregister_video(dev);
-	usb_put_intf(dev->intf);
-	usb_put_dev(dev->udev);
-
-	uvc_status_cleanup(dev);
-	uvc_ctrl_cleanup_device(dev);
-
-	list_for_each_safe(p, n, &dev->chains) {
-		struct uvc_video_chain *chain;
-		chain = list_entry(p, struct uvc_video_chain, list);
-		kfree(chain);
-	}
-
-	list_for_each_safe(p, n, &dev->entities) {
-		struct uvc_entity *entity;
-		entity = list_entry(p, struct uvc_entity, list);
-		kfree(entity);
-	}
-
-	list_for_each_safe(p, n, &dev->streams) {
-		struct uvc_streaming *streaming;
-		streaming = list_entry(p, struct uvc_streaming, list);
-		usb_driver_release_interface(&uvc_driver.driver,
-			streaming->intf);
-		usb_put_intf(streaming->intf);
-		kfree(streaming->format);
-		kfree(streaming->header.bmaControls);
-		kfree(streaming);
-	}
-
-	kfree(dev);
-}
-
 static int uvc_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
@@ -1730,7 +1744,7 @@ static int uvc_probe(struct usb_interfac
 	INIT_LIST_HEAD(&dev->entities);
 	INIT_LIST_HEAD(&dev->chains);
 	INIT_LIST_HEAD(&dev->streams);
-	kref_init(&dev->kref);
+	atomic_set(&dev->nstreams, 0);
 	atomic_set(&dev->users, 0);
 
 	dev->udev = usb_get_dev(udev);
@@ -1792,7 +1806,7 @@ static int uvc_probe(struct usb_interfac
 	return 0;
 
 error:
-	kref_put(&dev->kref, uvc_delete);
+	uvc_unregister_video(dev);
 	return -ENODEV;
 }
 
@@ -1809,21 +1823,9 @@ static void uvc_disconnect(struct usb_in
 	    UVC_SC_VIDEOSTREAMING)
 		return;
 
-	/* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
-	 * lock is needed to prevent uvc_disconnect from releasing its
-	 * reference to the uvc_device instance after uvc_v4l2_open() received
-	 * the pointer to the device (video_devdata) but before it got the
-	 * chance to increase the reference count (kref_get).
-	 *
-	 * Note that the reference can't be released with the lock held,
-	 * otherwise a AB-BA deadlock can occur with videodev_lock that
-	 * videodev acquires in videodev_open() and video_unregister_device().
-	 */
-	mutex_lock(&uvc_driver.open_mutex);
 	dev->state |= UVC_DEV_DISCONNECTED;
-	mutex_unlock(&uvc_driver.open_mutex);
 
-	kref_put(&dev->kref, uvc_delete);
+	uvc_unregister_video(dev);
 }
 
 static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
@@ -1899,6 +1901,15 @@ static int uvc_reset_resume(struct usb_i
  * though they are compliant.
  */
 static struct usb_device_id uvc_ids[] = {
+	/* Genius eFace 2025 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0458,
+	  .idProduct		= 0x706e,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Microsoft Lifecam NX-6000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2134,15 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STATUS_INTERVAL },
+	/* MSI StarCam 370i */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1b3b,
+	  .idProduct		= 0x2951,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* SiGma Micro USB Web Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2159,7 +2179,6 @@ static int __init uvc_init(void)
 
 	INIT_LIST_HEAD(&uvc_driver.devices);
 	INIT_LIST_HEAD(&uvc_driver.controls);
-	mutex_init(&uvc_driver.open_mutex);
 	mutex_init(&uvc_driver.ctrl_mutex);
 
 	uvc_ctrl_init();
@@ -2184,6 +2203,8 @@ module_param_named(quirks, uvc_quirks_pa
 MODULE_PARM_DESC(quirks, "Forced device quirks");
 module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(trace, "Trace level bitmask");
+module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_queue.c linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_queue.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_queue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_queue.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,9 +59,9 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
- *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
+ *    queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
- *    process tries to dequeue a buffer after it has been marked ready, the
+ *    process tries to dequeue a buffer after it has been marked done, the
  *    dequeing will succeed immediately.
  *
  * 2. Buffers are queued, user is waiting on a buffer and the device gets
@@ -201,6 +201,7 @@ static void __uvc_query_buffer(struct uv
 		break;
 	case UVC_BUF_STATE_QUEUED:
 	case UVC_BUF_STATE_ACTIVE:
+	case UVC_BUF_STATE_READY:
 		v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
 		break;
 	case UVC_BUF_STATE_IDLE:
@@ -295,13 +296,15 @@ static int uvc_queue_waiton(struct uvc_b
 {
 	if (nonblocking) {
 		return (buf->state != UVC_BUF_STATE_QUEUED &&
-			buf->state != UVC_BUF_STATE_ACTIVE)
+			buf->state != UVC_BUF_STATE_ACTIVE &&
+			buf->state != UVC_BUF_STATE_READY)
 			? 0 : -EAGAIN;
 	}
 
 	return wait_event_interruptible(buf->wait,
 		buf->state != UVC_BUF_STATE_QUEUED &&
-		buf->state != UVC_BUF_STATE_ACTIVE);
+		buf->state != UVC_BUF_STATE_ACTIVE &&
+		buf->state != UVC_BUF_STATE_READY);
 }
 
 /*
@@ -348,6 +351,7 @@ int uvc_dequeue_buffer(struct uvc_video_
 	case UVC_BUF_STATE_IDLE:
 	case UVC_BUF_STATE_QUEUED:
 	case UVC_BUF_STATE_ACTIVE:
+	case UVC_BUF_STATE_READY:
 	default:
 		uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
 			"(driver bug?).\n", buf->state);
@@ -489,6 +493,7 @@ struct uvc_buffer *uvc_queue_next_buffer
 
 	spin_lock_irqsave(&queue->irqlock, flags);
 	list_del(&buf->queue);
+	buf->state = UVC_BUF_STATE_DONE;
 	if (!list_empty(&queue->irqqueue))
 		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
 					   queue);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_v4l2.c linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_v4l2.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2010-02-24 13:52:17.000000000 -0500
@@ -364,37 +364,30 @@ static int uvc_v4l2_set_streamparm(struc
  * unprivileged state. Only a single instance can be in a privileged state at
  * a given time. Trying to perform an operation that requires privileges will
  * automatically acquire the required privileges if possible, or return -EBUSY
- * otherwise. Privileges are dismissed when closing the instance.
+ * otherwise. Privileges are dismissed when closing the instance or when
+ * freeing the video buffers using VIDIOC_REQBUFS.
  *
  * Operations that require privileges are:
  *
  * - VIDIOC_S_INPUT
  * - VIDIOC_S_PARM
  * - VIDIOC_S_FMT
- * - VIDIOC_TRY_FMT
  * - VIDIOC_REQBUFS
  */
 static int uvc_acquire_privileges(struct uvc_fh *handle)
 {
-	int ret = 0;
-
 	/* Always succeed if the handle is already privileged. */
 	if (handle->state == UVC_HANDLE_ACTIVE)
 		return 0;
 
 	/* Check if the device already has a privileged handle. */
-	mutex_lock(&uvc_driver.open_mutex);
 	if (atomic_inc_return(&handle->stream->active) != 1) {
 		atomic_dec(&handle->stream->active);
-		ret = -EBUSY;
-		goto done;
+		return -EBUSY;
 	}
 
 	handle->state = UVC_HANDLE_ACTIVE;
-
-done:
-	mutex_unlock(&uvc_driver.open_mutex);
-	return ret;
+	return 0;
 }
 
 static void uvc_dismiss_privileges(struct uvc_fh *handle)
@@ -421,24 +414,20 @@ static int uvc_v4l2_open(struct file *fi
 	int ret = 0;
 
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
-	mutex_lock(&uvc_driver.open_mutex);
 	stream = video_drvdata(file);
 
-	if (stream->dev->state & UVC_DEV_DISCONNECTED) {
-		ret = -ENODEV;
-		goto done;
-	}
+	if (stream->dev->state & UVC_DEV_DISCONNECTED)
+		return -ENODEV;
 
 	ret = usb_autopm_get_interface(stream->dev->intf);
 	if (ret < 0)
-		goto done;
+		return ret;
 
 	/* Create the device handle. */
 	handle = kzalloc(sizeof *handle, GFP_KERNEL);
 	if (handle == NULL) {
 		usb_autopm_put_interface(stream->dev->intf);
-		ret = -ENOMEM;
-		goto done;
+		return -ENOMEM;
 	}
 
 	if (atomic_inc_return(&stream->dev->users) == 1) {
@@ -447,7 +436,7 @@ static int uvc_v4l2_open(struct file *fi
 			usb_autopm_put_interface(stream->dev->intf);
 			atomic_dec(&stream->dev->users);
 			kfree(handle);
-			goto done;
+			return ret;
 		}
 	}
 
@@ -456,11 +445,7 @@ static int uvc_v4l2_open(struct file *fi
 	handle->state = UVC_HANDLE_PASSIVE;
 	file->private_data = handle;
 
-	kref_get(&stream->dev->kref);
-
-done:
-	mutex_unlock(&uvc_driver.open_mutex);
-	return ret;
+	return 0;
 }
 
 static int uvc_v4l2_release(struct file *file)
@@ -490,7 +475,6 @@ static int uvc_v4l2_release(struct file
 		uvc_status_stop(stream->dev);
 
 	usb_autopm_put_interface(stream->dev->intf);
-	kref_put(&stream->dev->kref, uvc_delete);
 	return 0;
 }
 
@@ -636,12 +620,16 @@ static long uvc_v4l2_do_ioctl(struct fil
 		    (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
 			if (index != 0)
 				return -EINVAL;
-			iterm = list_first_entry(&chain->iterms,
-					struct uvc_entity, chain);
+			list_for_each_entry(iterm, &chain->entities, chain) {
+				if (UVC_ENTITY_IS_ITERM(iterm))
+					break;
+			}
 			pin = iterm->id;
-		} else if (pin < selector->selector.bNrInPins) {
-			pin = selector->selector.baSourceID[index];
-			list_for_each_entry(iterm, chain->iterms.next, chain) {
+		} else if (pin < selector->bNrInPins) {
+			pin = selector->baSourceID[index];
+			list_for_each_entry(iterm, &chain->entities, chain) {
+				if (!UVC_ENTITY_IS_ITERM(iterm))
+					continue;
 				if (iterm->id == pin)
 					break;
 			}
@@ -692,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct fil
 			break;
 		}
 
-		if (input == 0 || input > chain->selector->selector.bNrInPins)
+		if (input == 0 || input > chain->selector->bNrInPins)
 			return -EINVAL;
 
 		return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
@@ -731,9 +719,6 @@ static long uvc_v4l2_do_ioctl(struct fil
 	{
 		struct uvc_streaming_control probe;
 
-		if ((ret = uvc_acquire_privileges(handle)) < 0)
-			return ret;
-
 		return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
 	}
 
@@ -888,6 +873,9 @@ static long uvc_v4l2_do_ioctl(struct fil
 		if (ret < 0)
 			return ret;
 
+		if (ret == 0)
+			uvc_dismiss_privileges(handle);
+
 		rb->count = ret;
 		ret = 0;
 		break;
@@ -1051,7 +1039,7 @@ static ssize_t uvc_v4l2_read(struct file
 		    size_t count, loff_t *ppos)
 {
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
-	return -ENODEV;
+	return -EINVAL;
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_video.c linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_video.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvc_video.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvc_video.c	2010-02-24 13:52:17.000000000 -0500
@@ -135,7 +135,7 @@ static int uvc_get_video_ctrl(struct uvc
 
 	ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
 		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
-		size, UVC_CTRL_STREAMING_TIMEOUT);
+		size, uvc_timeout_param);
 
 	if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
 		/* Some cameras, mostly based on Bison Electronics chipsets,
@@ -145,7 +145,7 @@ static int uvc_get_video_ctrl(struct uvc
 		uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non "
 			"compliance - GET_MIN/MAX(PROBE) incorrectly "
 			"supported. Enabling workaround.\n");
-		memset(ctrl, 0, sizeof ctrl);
+		memset(ctrl, 0, sizeof *ctrl);
 		ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
 		ret = 0;
 		goto out;
@@ -239,7 +239,7 @@ static int uvc_set_video_ctrl(struct uvc
 
 	ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
 		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
-		size, UVC_CTRL_STREAMING_TIMEOUT);
+		size, uvc_timeout_param);
 	if (ret != size) {
 		uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
 			"%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -441,7 +441,7 @@ static int uvc_video_decode_start(struct
 	if (fid != stream->last_fid && buf->buf.bytesused != 0) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
 				"toggled).\n");
-		buf->state = UVC_BUF_STATE_DONE;
+		buf->state = UVC_BUF_STATE_READY;
 		return -EAGAIN;
 	}
 
@@ -470,7 +470,7 @@ static void uvc_video_decode_data(struct
 	/* Complete the current frame if the buffer size was exceeded. */
 	if (len > maxlen) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
-		buf->state = UVC_BUF_STATE_DONE;
+		buf->state = UVC_BUF_STATE_READY;
 	}
 }
 
@@ -482,7 +482,7 @@ static void uvc_video_decode_end(struct
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
 		if (data[0] == len)
 			uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
-		buf->state = UVC_BUF_STATE_DONE;
+		buf->state = UVC_BUF_STATE_READY;
 		if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
 			stream->last_fid ^= UVC_STREAM_FID;
 	}
@@ -568,8 +568,7 @@ static void uvc_video_decode_isoc(struct
 		uvc_video_decode_end(stream, buf, mem,
 			urb->iso_frame_desc[i].actual_length);
 
-		if (buf->state == UVC_BUF_STATE_DONE ||
-		    buf->state == UVC_BUF_STATE_ERROR)
+		if (buf->state == UVC_BUF_STATE_READY)
 			buf = uvc_queue_next_buffer(&stream->queue, buf);
 	}
 }
@@ -627,8 +626,7 @@ static void uvc_video_decode_bulk(struct
 		if (!stream->bulk.skip_payload && buf != NULL) {
 			uvc_video_decode_end(stream, buf, stream->bulk.header,
 				stream->bulk.payload_size);
-			if (buf->state == UVC_BUF_STATE_DONE ||
-			    buf->state == UVC_BUF_STATE_ERROR)
+			if (buf->state == UVC_BUF_STATE_READY)
 				buf = uvc_queue_next_buffer(&stream->queue,
 							    buf);
 		}
@@ -669,7 +667,7 @@ static void uvc_video_encode_bulk(struct
 	    stream->bulk.payload_size == stream->bulk.max_payload_size) {
 		if (buf->buf.bytesused == stream->queue.buf_used) {
 			stream->queue.buf_used = 0;
-			buf->state = UVC_BUF_STATE_DONE;
+			buf->state = UVC_BUF_STATE_READY;
 			uvc_queue_next_buffer(&stream->queue, buf);
 			stream->last_fid ^= UVC_STREAM_FID;
 		}
@@ -770,8 +768,9 @@ static int uvc_alloc_urb_buffers(struct
 	/* Retry allocations until one succeed. */
 	for (; npackets > 1; npackets /= 2) {
 		for (i = 0; i < UVC_URBS; ++i) {
+			stream->urb_size = psize * npackets;
 			stream->urb_buffer[i] = usb_buffer_alloc(
-				stream->dev->udev, psize * npackets,
+				stream->dev->udev, stream->urb_size,
 				gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
 			if (!stream->urb_buffer[i]) {
 				uvc_free_urb_buffers(stream);
@@ -780,11 +779,15 @@ static int uvc_alloc_urb_buffers(struct
 		}
 
 		if (i == UVC_URBS) {
-			stream->urb_size = psize * npackets;
+			uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
+				"of %ux%u bytes each.\n", UVC_URBS, npackets,
+				psize);
 			return npackets;
 		}
 	}
 
+	uvc_trace(UVC_TRACE_VIDEO, "Failed to allocate URB buffers (%u bytes "
+		"per packet).\n", psize);
 	return 0;
 }
 
@@ -919,10 +922,8 @@ static int uvc_init_video_bulk(struct uv
 static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
 {
 	struct usb_interface *intf = stream->intf;
-	struct usb_host_interface *alts;
-	struct usb_host_endpoint *ep = NULL;
-	int intfnum = stream->intfnum;
-	unsigned int bandwidth, psize, i;
+	struct usb_host_endpoint *ep;
+	unsigned int i;
 	int ret;
 
 	stream->last_fid = -1;
@@ -931,17 +932,28 @@ static int uvc_init_video(struct uvc_str
 	stream->bulk.payload_size = 0;
 
 	if (intf->num_altsetting > 1) {
+		struct usb_host_endpoint *best_ep = NULL;
+		unsigned int best_psize = 3 * 1024;
+		unsigned int bandwidth;
+		unsigned int uninitialized_var(altsetting);
+		int intfnum = stream->intfnum;
+
 		/* Isochronous endpoint, select the alternate setting. */
 		bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
 
 		if (bandwidth == 0) {
-			uvc_printk(KERN_WARNING, "device %s requested null "
-				"bandwidth, defaulting to lowest.\n",
-				stream->dev->name);
+			uvc_trace(UVC_TRACE_VIDEO, "Device requested null "
+				"bandwidth, defaulting to lowest.\n");
 			bandwidth = 1;
+		} else {
+			uvc_trace(UVC_TRACE_VIDEO, "Device requested %u "
+				"B/frame bandwidth.\n", bandwidth);
 		}
 
 		for (i = 0; i < intf->num_altsetting; ++i) {
+			struct usb_host_interface *alts;
+			unsigned int psize;
+
 			alts = &intf->altsetting[i];
 			ep = uvc_find_endpoint(alts,
 				stream->header.bEndpointAddress);
@@ -951,18 +963,27 @@ static int uvc_init_video(struct uvc_str
 			/* Check if the bandwidth is high enough. */
 			psize = le16_to_cpu(ep->desc.wMaxPacketSize);
 			psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-			if (psize >= bandwidth)
-				break;
+			if (psize >= bandwidth && psize <= best_psize) {
+				altsetting = i;
+				best_psize = psize;
+				best_ep = ep;
+			}
 		}
 
-		if (i >= intf->num_altsetting)
+		if (best_ep == NULL) {
+			uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
+				"for requested bandwidth.\n");
 			return -EIO;
+		}
 
-		ret = usb_set_interface(stream->dev->udev, intfnum, i);
+		uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u "
+			"(%u B/frame bandwidth).\n", altsetting, best_psize);
+
+		ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
 		if (ret < 0)
 			return ret;
 
-		ret = uvc_init_video_isoc(stream, ep, gfp_flags);
+		ret = uvc_init_video_isoc(stream, best_ep, gfp_flags);
 	} else {
 		/* Bulk endpoint, proceed to URB initialization. */
 		ep = uvc_find_endpoint(&intf->altsetting[0],
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvcvideo.h linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvcvideo.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/uvc/uvcvideo.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/uvc/uvcvideo.h	2010-02-24 13:52:17.000000000 -0500
@@ -75,6 +75,7 @@ struct uvc_xu_control {
 
 #define UVC_TERM_INPUT			0x0000
 #define UVC_TERM_OUTPUT			0x8000
+#define UVC_TERM_DIRECTION(term)	((term)->type & 0x8000)
 
 #define UVC_ENTITY_TYPE(entity)		((entity)->type & 0x7fff)
 #define UVC_ENTITY_IS_UNIT(entity)	(((entity)->type & 0xff00) == 0)
@@ -148,7 +149,7 @@ struct uvc_xu_control {
 #define UVC_MAX_STATUS_SIZE	16
 
 #define UVC_CTRL_CONTROL_TIMEOUT	300
-#define UVC_CTRL_STREAMING_TIMEOUT	1000
+#define UVC_CTRL_STREAMING_TIMEOUT	3000
 
 /* Devices quirks */
 #define UVC_QUIRK_STATUS_INTERVAL	0x00000001
@@ -292,11 +293,9 @@ struct uvc_entity {
 		} media;
 
 		struct {
-			__u8  bSourceID;
 		} output;
 
 		struct {
-			__u8  bSourceID;
 			__u16 wMaxMultiplier;
 			__u8  bControlSize;
 			__u8  *bmControls;
@@ -304,21 +303,20 @@ struct uvc_entity {
 		} processing;
 
 		struct {
-			__u8  bNrInPins;
-			__u8  *baSourceID;
 		} selector;
 
 		struct {
 			__u8  guidExtensionCode[16];
 			__u8  bNumControls;
-			__u8  bNrInPins;
-			__u8  *baSourceID;
 			__u8  bControlSize;
 			__u8  *bmControls;
 			__u8  *bmControlsType;
 		} extension;
 	};
 
+	__u8 bNrInPins;
+	__u8 *baSourceID;
+
 	unsigned int ncontrols;
 	struct uvc_control *controls;
 };
@@ -367,8 +365,9 @@ enum uvc_buffer_state {
 	UVC_BUF_STATE_IDLE	= 0,
 	UVC_BUF_STATE_QUEUED	= 1,
 	UVC_BUF_STATE_ACTIVE	= 2,
-	UVC_BUF_STATE_DONE	= 3,
-	UVC_BUF_STATE_ERROR	= 4,
+	UVC_BUF_STATE_READY	= 3,
+	UVC_BUF_STATE_DONE	= 4,
+	UVC_BUF_STATE_ERROR	= 5,
 };
 
 struct uvc_buffer {
@@ -408,11 +407,9 @@ struct uvc_video_chain {
 	struct uvc_device *dev;
 	struct list_head list;
 
-	struct list_head iterms;		/* Input terminals */
-	struct list_head oterms;		/* Output terminals */
+	struct list_head entities;		/* All entities */
 	struct uvc_entity *processing;		/* Processing unit */
 	struct uvc_entity *selector;		/* Selector unit */
-	struct list_head extensions;		/* Extension units */
 
 	struct mutex ctrl_mutex;
 };
@@ -475,7 +472,6 @@ struct uvc_device {
 	char name[32];
 
 	enum uvc_device_state state;
-	struct kref kref;
 	struct list_head list;
 	atomic_t users;
 
@@ -488,6 +484,7 @@ struct uvc_device {
 
 	/* Video Streaming interfaces */
 	struct list_head streams;
+	atomic_t nstreams;
 
 	/* Status Interrupt Endpoint */
 	struct usb_host_endpoint *int_ep;
@@ -511,8 +508,6 @@ struct uvc_fh {
 struct uvc_driver {
 	struct usb_driver driver;
 
-	struct mutex open_mutex;	/* protects from open/disconnect race */
-
 	struct list_head devices;	/* struct uvc_device list */
 	struct list_head controls;	/* struct uvc_control_info list */
 	struct mutex ctrl_mutex;	/* protects controls and devices
@@ -533,12 +528,14 @@ struct uvc_driver {
 #define UVC_TRACE_FRAME		(1 << 7)
 #define UVC_TRACE_SUSPEND	(1 << 8)
 #define UVC_TRACE_STATUS	(1 << 9)
+#define UVC_TRACE_VIDEO		(1 << 10)
 
 #define UVC_WARN_MINMAX		0
 #define UVC_WARN_PROBE_DEF	1
 
 extern unsigned int uvc_no_drop_param;
 extern unsigned int uvc_trace_param;
+extern unsigned int uvc_timeout_param;
 
 #define uvc_trace(flag, msg...) \
 	do { \
@@ -571,7 +568,6 @@ extern unsigned int uvc_trace_param;
 
 /* Core driver */
 extern struct uvc_driver uvc_driver;
-extern void uvc_delete(struct kref *kref);
 
 /* Video buffers queue management. */
 extern void uvc_queue_init(struct uvc_video_queue *queue,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-common.c linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-common.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-common.c	2010-02-24 13:52:17.000000000 -0500
@@ -431,6 +431,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_CHROMA_AGC:		return "Chroma AGC";
 	case V4L2_CID_COLOR_KILLER:		return "Color Killer";
 	case V4L2_CID_COLORFX:			return "Color Effects";
+	case V4L2_CID_ROTATE:			return "Rotate";
+	case V4L2_CID_BG_COLOR:			return "Background color";
 
 	/* MPEG controls */
 	case V4L2_CID_MPEG_CLASS: 		return "MPEG Encoder Controls";
@@ -587,6 +589,13 @@ int v4l2_ctrl_query_fill(struct v4l2_que
 		qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		min = max = step = def = 0;
 		break;
+	case V4L2_CID_BG_COLOR:
+		qctrl->type = V4L2_CTRL_TYPE_INTEGER;
+		step = 1;
+		min = 0;
+		/* Max is calculated as RGB888 that is 2^24 */
+		max = 0xFFFFFF;
+		break;
 	default:
 		qctrl->type = V4L2_CTRL_TYPE_INTEGER;
 		break;
@@ -1015,3 +1024,50 @@ void v4l_bound_align_image(u32 *w, unsig
 	}
 }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
+
+/**
+ * v4l_fill_dv_preset_info - fill description of a digital video preset
+ * @preset - preset value
+ * @info - pointer to struct v4l2_dv_enum_preset
+ *
+ * drivers can use this helper function to fill description of dv preset
+ * in info.
+ */
+int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
+{
+	static const struct v4l2_dv_preset_info {
+		u16 width;
+		u16 height;
+		const char *name;
+	} dv_presets[] = {
+		{ 0, 0, "Invalid" },		/* V4L2_DV_INVALID */
+		{ 720,  480, "480p@59.94" },	/* V4L2_DV_480P59_94 */
+		{ 720,  576, "576p@50" },	/* V4L2_DV_576P50 */
+		{ 1280, 720, "720p@24" },	/* V4L2_DV_720P24 */
+		{ 1280, 720, "720p@25" },	/* V4L2_DV_720P25 */
+		{ 1280, 720, "720p@30" },	/* V4L2_DV_720P30 */
+		{ 1280, 720, "720p@50" },	/* V4L2_DV_720P50 */
+		{ 1280, 720, "720p@59.94" },	/* V4L2_DV_720P59_94 */
+		{ 1280, 720, "720p@60" },	/* V4L2_DV_720P60 */
+		{ 1920, 1080, "1080i@29.97" },	/* V4L2_DV_1080I29_97 */
+		{ 1920, 1080, "1080i@30" },	/* V4L2_DV_1080I30 */
+		{ 1920, 1080, "1080i@25" },	/* V4L2_DV_1080I25 */
+		{ 1920, 1080, "1080i@50" },	/* V4L2_DV_1080I50 */
+		{ 1920, 1080, "1080i@60" },	/* V4L2_DV_1080I60 */
+		{ 1920, 1080, "1080p@24" },	/* V4L2_DV_1080P24 */
+		{ 1920, 1080, "1080p@25" },	/* V4L2_DV_1080P25 */
+		{ 1920, 1080, "1080p@30" },	/* V4L2_DV_1080P30 */
+		{ 1920, 1080, "1080p@50" },	/* V4L2_DV_1080P50 */
+		{ 1920, 1080, "1080p@60" },	/* V4L2_DV_1080P60 */
+	};
+
+	if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
+		return -EINVAL;
+
+	info->preset = preset;
+	info->width = dv_presets[preset].width;
+	info->height = dv_presets[preset].height;
+	strlcpy(info->name, dv_presets[preset].name, sizeof(info->name));
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-compat-ioctl32.c linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-compat-ioctl32.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2010-02-24 13:52:17.000000000 -0500
@@ -1077,6 +1077,12 @@ long v4l2_compat_ioctl32(struct file *fi
 	case VIDIOC_DBG_G_REGISTER:
 	case VIDIOC_DBG_G_CHIP_IDENT:
 	case VIDIOC_S_HW_FREQ_SEEK:
+	case VIDIOC_ENUM_DV_PRESETS:
+	case VIDIOC_S_DV_PRESET:
+	case VIDIOC_G_DV_PRESET:
+	case VIDIOC_QUERY_DV_PRESET:
+	case VIDIOC_S_DV_TIMINGS:
+	case VIDIOC_G_DV_TIMINGS:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-dev.c linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-dev.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,7 @@ static ssize_t v4l2_read(struct file *fi
 
 	if (!vdev->fops->read)
 		return -EINVAL;
-	if (video_is_unregistered(vdev))
+	if (!video_is_registered(vdev))
 		return -EIO;
 	return vdev->fops->read(filp, buf, sz, off);
 }
@@ -201,7 +201,7 @@ static ssize_t v4l2_write(struct file *f
 
 	if (!vdev->fops->write)
 		return -EINVAL;
-	if (video_is_unregistered(vdev))
+	if (!video_is_registered(vdev))
 		return -EIO;
 	return vdev->fops->write(filp, buf, sz, off);
 }
@@ -210,7 +210,7 @@ static unsigned int v4l2_poll(struct fil
 {
 	struct video_device *vdev = video_devdata(filp);
 
-	if (!vdev->fops->poll || video_is_unregistered(vdev))
+	if (!vdev->fops->poll || !video_is_registered(vdev))
 		return DEFAULT_POLLMASK;
 	return vdev->fops->poll(filp, poll);
 }
@@ -250,7 +250,7 @@ static unsigned long v4l2_get_unmapped_a
 
 	if (!vdev->fops->get_unmapped_area)
 		return -ENOSYS;
-	if (video_is_unregistered(vdev))
+	if (!video_is_registered(vdev))
 		return -ENODEV;
 	return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
 }
@@ -260,8 +260,7 @@ static int v4l2_mmap(struct file *filp,
 {
 	struct video_device *vdev = video_devdata(filp);
 
-	if (!vdev->fops->mmap ||
-	    video_is_unregistered(vdev))
+	if (!vdev->fops->mmap || !video_is_registered(vdev))
 		return -ENODEV;
 	return vdev->fops->mmap(filp, vm);
 }
@@ -277,7 +276,7 @@ static int v4l2_open(struct inode *inode
 	vdev = video_devdata(filp);
 	/* return ENODEV if the video device has been removed
 	   already or if it is not registered anymore. */
-	if (vdev == NULL || video_is_unregistered(vdev)) {
+	if (vdev == NULL || !video_is_registered(vdev)) {
 		mutex_unlock(&videodev_lock);
 		return -ENODEV;
 	}
@@ -551,10 +550,11 @@ static int __video_register_device(struc
 	vdev->dev.release = v4l2_device_release;
 
 	if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
-		printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
-				__func__, name_base, nr, name_base, vdev->num);
+		printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
+			name_base, nr, video_device_node_name(vdev));
 
 	/* Part 5: Activate this minor. The char device can now be used. */
+	set_bit(V4L2_FL_REGISTERED, &vdev->flags);
 	mutex_lock(&videodev_lock);
 	video_device[vdev->minor] = vdev;
 	mutex_unlock(&videodev_lock);
@@ -593,11 +593,11 @@ EXPORT_SYMBOL(video_register_device_no_w
 void video_unregister_device(struct video_device *vdev)
 {
 	/* Check if vdev was ever registered at all */
-	if (!vdev || vdev->minor < 0)
+	if (!vdev || !video_is_registered(vdev))
 		return;
 
 	mutex_lock(&videodev_lock);
-	set_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
+	clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
 	mutex_unlock(&videodev_lock);
 	device_unregister(&vdev->dev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-ioctl.c linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/v4l2-ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/v4l2-ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,6 +284,12 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
 	[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)]   = "VIDIOC_S_HW_FREQ_SEEK",
 #endif
+	[_IOC_NR(VIDIOC_ENUM_DV_PRESETS)]  = "VIDIOC_ENUM_DV_PRESETS",
+	[_IOC_NR(VIDIOC_S_DV_PRESET)]	   = "VIDIOC_S_DV_PRESET",
+	[_IOC_NR(VIDIOC_G_DV_PRESET)]	   = "VIDIOC_G_DV_PRESET",
+	[_IOC_NR(VIDIOC_QUERY_DV_PRESET)]  = "VIDIOC_QUERY_DV_PRESET",
+	[_IOC_NR(VIDIOC_S_DV_TIMINGS)]     = "VIDIOC_S_DV_TIMINGS",
+	[_IOC_NR(VIDIOC_G_DV_TIMINGS)]     = "VIDIOC_G_DV_TIMINGS",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -1135,6 +1141,19 @@ static long __video_do_ioctl(struct file
 	{
 		struct v4l2_input *p = arg;
 
+		/*
+		 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
+		 * CAP_STD here based on ioctl handler provided by the
+		 * driver. If the driver doesn't support these
+		 * for a specific input, it must override these flags.
+		 */
+		if (ops->vidioc_s_std)
+			p->capabilities |= V4L2_IN_CAP_STD;
+		if (ops->vidioc_s_dv_preset)
+			p->capabilities |= V4L2_IN_CAP_PRESETS;
+		if (ops->vidioc_s_dv_timings)
+			p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
+
 		if (!ops->vidioc_enum_input)
 			break;
 
@@ -1179,6 +1198,19 @@ static long __video_do_ioctl(struct file
 		if (!ops->vidioc_enum_output)
 			break;
 
+		/*
+		 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
+		 * CAP_STD here based on ioctl handler provided by the
+		 * driver. If the driver doesn't support these
+		 * for a specific output, it must override these flags.
+		 */
+		if (ops->vidioc_s_std)
+			p->capabilities |= V4L2_OUT_CAP_STD;
+		if (ops->vidioc_s_dv_preset)
+			p->capabilities |= V4L2_OUT_CAP_PRESETS;
+		if (ops->vidioc_s_dv_timings)
+			p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
+
 		ret = ops->vidioc_enum_output(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1794,6 +1826,121 @@ static long __video_do_ioctl(struct file
 		}
 		break;
 	}
+	case VIDIOC_ENUM_DV_PRESETS:
+	{
+		struct v4l2_dv_enum_preset *p = arg;
+
+		if (!ops->vidioc_enum_dv_presets)
+			break;
+
+		ret = ops->vidioc_enum_dv_presets(file, fh, p);
+		if (!ret)
+			dbgarg(cmd,
+				"index=%d, preset=%d, name=%s, width=%d,"
+				" height=%d ",
+				p->index, p->preset, p->name, p->width,
+				p->height);
+		break;
+	}
+	case VIDIOC_S_DV_PRESET:
+	{
+		struct v4l2_dv_preset *p = arg;
+
+		if (!ops->vidioc_s_dv_preset)
+			break;
+
+		dbgarg(cmd, "preset=%d\n", p->preset);
+		ret = ops->vidioc_s_dv_preset(file, fh, p);
+		break;
+	}
+	case VIDIOC_G_DV_PRESET:
+	{
+		struct v4l2_dv_preset *p = arg;
+
+		if (!ops->vidioc_g_dv_preset)
+			break;
+
+		ret = ops->vidioc_g_dv_preset(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "preset=%d\n", p->preset);
+		break;
+	}
+	case VIDIOC_QUERY_DV_PRESET:
+	{
+		struct v4l2_dv_preset *p = arg;
+
+		if (!ops->vidioc_query_dv_preset)
+			break;
+
+		ret = ops->vidioc_query_dv_preset(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "preset=%d\n", p->preset);
+		break;
+	}
+	case VIDIOC_S_DV_TIMINGS:
+	{
+		struct v4l2_dv_timings *p = arg;
+
+		if (!ops->vidioc_s_dv_timings)
+			break;
+
+		switch (p->type) {
+		case V4L2_DV_BT_656_1120:
+			dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
+				" width=%d, height=%d, polarities=%x,"
+				" hfrontporch=%d, hsync=%d, hbackporch=%d,"
+				" vfrontporch=%d, vsync=%d, vbackporch=%d,"
+				" il_vfrontporch=%d, il_vsync=%d,"
+				" il_vbackporch=%d\n",
+				p->bt.interlaced, p->bt.pixelclock,
+				p->bt.width, p->bt.height, p->bt.polarities,
+				p->bt.hfrontporch, p->bt.hsync,
+				p->bt.hbackporch, p->bt.vfrontporch,
+				p->bt.vsync, p->bt.vbackporch,
+				p->bt.il_vfrontporch, p->bt.il_vsync,
+				p->bt.il_vbackporch);
+			ret = ops->vidioc_s_dv_timings(file, fh, p);
+			break;
+		default:
+			dbgarg2("Unknown type %d!\n", p->type);
+			break;
+		}
+		break;
+	}
+	case VIDIOC_G_DV_TIMINGS:
+	{
+		struct v4l2_dv_timings *p = arg;
+
+		if (!ops->vidioc_g_dv_timings)
+			break;
+
+		ret = ops->vidioc_g_dv_timings(file, fh, p);
+		if (!ret) {
+			switch (p->type) {
+			case V4L2_DV_BT_656_1120:
+				dbgarg2("bt-656/1120:interlaced=%d,"
+					" pixelclock=%lld,"
+					" width=%d, height=%d, polarities=%x,"
+					" hfrontporch=%d, hsync=%d,"
+					" hbackporch=%d, vfrontporch=%d,"
+					" vsync=%d, vbackporch=%d,"
+					" il_vfrontporch=%d, il_vsync=%d,"
+					" il_vbackporch=%d\n",
+					p->bt.interlaced, p->bt.pixelclock,
+					p->bt.width, p->bt.height,
+					p->bt.polarities, p->bt.hfrontporch,
+					p->bt.hsync, p->bt.hbackporch,
+					p->bt.vfrontporch, p->bt.vsync,
+					p->bt.vbackporch, p->bt.il_vfrontporch,
+					p->bt.il_vsync, p->bt.il_vbackporch);
+				break;
+			default:
+				dbgarg2("Unknown type %d!\n", p->type);
+				break;
+			}
+		}
+		break;
+	}
 
 	default:
 	{
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-core.c linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_to_vmal
 
 
 void videobuf_queue_core_init(struct videobuf_queue *q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
@@ -360,7 +360,7 @@ int __videobuf_mmap_setup(struct videobu
 		q->bufs[i]->bsize  = bsize;
 		switch (memory) {
 		case V4L2_MEMORY_MMAP:
-			q->bufs[i]->boff  = bsize * i;
+			q->bufs[i]->boff = PAGE_ALIGN(bsize) * i;
 			break;
 		case V4L2_MEMORY_USERPTR:
 		case V4L2_MEMORY_OVERLAY:
@@ -430,9 +430,9 @@ int videobuf_reqbufs(struct videobuf_que
 		count = VIDEO_MAX_FRAME;
 	size = 0;
 	q->ops->buf_setup(q, &count, &size);
-	size = PAGE_ALIGN(size);
-	dprintk(1, "reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
-		count, size, (count*size)>>PAGE_SHIFT);
+	dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
+		count, size,
+		(unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) );
 
 	retval = __videobuf_mmap_setup(q, count, size, req->memory);
 	if (retval < 0) {
@@ -1099,7 +1099,7 @@ int videobuf_cgmbuf(struct videobuf_queu
 	mbuf->size   = 0;
 	for (i = 0; i < mbuf->frames; i++) {
 		mbuf->offsets[i]  = q->bufs[i]->boff;
-		mbuf->size       += q->bufs[i]->bsize;
+		mbuf->size       += PAGE_ALIGN(q->bufs[i]->bsize);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dma-contig.c linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-contig.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dma-contig.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-contig.c	2010-02-24 13:52:17.000000000 -0500
@@ -141,9 +141,11 @@ static int videobuf_dma_contig_user_get(
 	struct vm_area_struct *vma;
 	unsigned long prev_pfn, this_pfn;
 	unsigned long pages_done, user_address;
+	unsigned int offset;
 	int ret;
 
-	mem->size = PAGE_ALIGN(vb->size);
+	offset = vb->baddr & ~PAGE_MASK;
+	mem->size = PAGE_ALIGN(vb->size + offset);
 	mem->is_userptr = 0;
 	ret = -EINVAL;
 
@@ -166,7 +168,7 @@ static int videobuf_dma_contig_user_get(
 			break;
 
 		if (pages_done == 0)
-			mem->dma_handle = this_pfn << PAGE_SHIFT;
+			mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
 		else if (this_pfn != (prev_pfn + 1))
 			ret = -EFAULT;
 
@@ -429,7 +431,7 @@ static struct videobuf_qtype_ops qops =
 };
 
 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
-				    struct videobuf_queue_ops *ops,
+				    const struct videobuf_queue_ops *ops,
 				    struct device *dev,
 				    spinlock_t *irqlock,
 				    enum v4l2_buf_type type,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dma-sg.c linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-sg.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dma-sg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dma-sg.c	2010-02-24 13:52:17.000000000 -0500
@@ -588,7 +588,7 @@ static int __videobuf_mmap_mapper(struct
 			retval = -EBUSY;
 			goto done;
 		}
-		size += q->bufs[last]->bsize;
+		size += PAGE_ALIGN(q->bufs[last]->bsize);
 		if (size == (vma->vm_end - vma->vm_start))
 			break;
 	}
@@ -610,7 +610,7 @@ static int __videobuf_mmap_mapper(struct
 			continue;
 		q->bufs[i]->map   = map;
 		q->bufs[i]->baddr = vma->vm_start + size;
-		size += q->bufs[i]->bsize;
+		size += PAGE_ALIGN(q->bufs[i]->bsize);
 	}
 
 	map->count    = 1;
@@ -702,7 +702,7 @@ void *videobuf_sg_alloc(size_t size)
 }
 
 void videobuf_queue_sg_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
+			 const struct videobuf_queue_ops *ops,
 			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dvb.c linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dvb.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-dvb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-dvb.c	2010-02-24 13:52:17.000000000 -0500
@@ -139,7 +139,9 @@ static int videobuf_dvb_register_adapter
 			  struct device *device,
 			  char *adapter_name,
 			  short *adapter_nr,
-			  int mfe_shared)
+			  int mfe_shared,
+			  int (*fe_ioctl_override)(struct dvb_frontend *,
+					unsigned int, void *, unsigned int))
 {
 	int result;
 
@@ -154,6 +156,7 @@ static int videobuf_dvb_register_adapter
 	}
 	fe->adapter.priv = adapter_priv;
 	fe->adapter.mfe_shared = mfe_shared;
+	fe->adapter.fe_ioctl_override = fe_ioctl_override;
 
 	return result;
 }
@@ -253,7 +256,9 @@ int videobuf_dvb_register_bus(struct vid
 			  void *adapter_priv,
 			  struct device *device,
 			  short *adapter_nr,
-			  int mfe_shared)
+			  int mfe_shared,
+			  int (*fe_ioctl_override)(struct dvb_frontend *,
+					unsigned int, void *, unsigned int))
 {
 	struct list_head *list, *q;
 	struct videobuf_dvb_frontend *fe;
@@ -267,7 +272,7 @@ int videobuf_dvb_register_bus(struct vid
 
 	/* Bring up the adapter */
 	res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
-		fe->dvb.name, adapter_nr, mfe_shared);
+		fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
 	if (res < 0) {
 		printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
 		return res;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-vmalloc.c linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-vmalloc.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/videobuf-vmalloc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/videobuf-vmalloc.c	2010-02-24 13:52:17.000000000 -0500
@@ -391,8 +391,8 @@ static struct videobuf_qtype_ops qops =
 };
 
 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
-			 struct videobuf_queue_ops *ops,
-			 void *dev,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
 			 spinlock_t *irqlock,
 			 enum v4l2_buf_type type,
 			 enum v4l2_field field,
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/vino.c linux-libre-2.6.33-gnu1/drivers/media/video/vino.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/vino.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/vino.c	2010-02-24 13:52:17.000000000 -0500
@@ -4068,7 +4068,6 @@ static struct video_device vdev_template
 	.fops		= &vino_fops,
 	.ioctl_ops 	= &vino_ioctl_ops,
 	.tvnorms 	= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-	.minor		= -1,
 };
 
 static void vino_module_cleanup(int stage)
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/vivi.c linux-libre-2.6.33-gnu1/drivers/media/video/vivi.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/vivi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/vivi.c	2010-02-24 13:52:17.000000000 -0500
@@ -1148,7 +1148,8 @@ static int vivi_open(struct file *file)
 		return -EBUSY;
 	}
 
-	dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
+	dprintk(dev, 1, "open %s type=%s users=%d\n",
+		video_device_node_name(dev->vfd),
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 
 	/* allocate + initialize per filehandle data */
@@ -1221,8 +1222,7 @@ static int vivi_close(struct file *file)
 	struct vivi_fh         *fh = file->private_data;
 	struct vivi_dev *dev       = fh->dev;
 	struct vivi_dmaqueue *vidq = &dev->vidq;
-
-	int minor = video_devdata(file)->minor;
+	struct video_device  *vdev = video_devdata(file);
 
 	vivi_stop_thread(vidq);
 	videobuf_stop(&fh->vb_vidq);
@@ -1234,8 +1234,8 @@ static int vivi_close(struct file *file)
 	dev->users--;
 	mutex_unlock(&dev->mutex);
 
-	dprintk(dev, 1, "close called (minor=%d, users=%d)\n",
-		minor, dev->users);
+	dprintk(dev, 1, "close called (dev=%s, users=%d)\n",
+		video_device_node_name(vdev), dev->users);
 
 	return 0;
 }
@@ -1296,7 +1296,6 @@ static struct video_device vivi_template
 	.name		= "vivi",
 	.fops           = &vivi_fops,
 	.ioctl_ops 	= &vivi_ioctl_ops,
-	.minor		= -1,
 	.release	= video_device_release,
 
 	.tvnorms              = V4L2_STD_525_60,
@@ -1317,8 +1316,8 @@ static int vivi_release(void)
 		list_del(list);
 		dev = list_entry(list, struct vivi_dev, vivi_devlist);
 
-		v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
-			dev->vfd->num);
+		v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
+			video_device_node_name(dev->vfd));
 		video_unregister_device(dev->vfd);
 		v4l2_device_unregister(&dev->v4l2_dev);
 		kfree(dev);
@@ -1372,15 +1371,12 @@ static int __init vivi_create_instance(i
 	/* Now that everything is fine, let's add it to device list */
 	list_add_tail(&dev->vivi_devlist, &vivi_devlist);
 
-	snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
-			vivi_template.name, vfd->num);
-
 	if (video_nr >= 0)
 		video_nr++;
 
 	dev->vfd = vfd;
-	v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
-			vfd->num);
+	v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
+		  video_device_node_name(vfd));
 	return 0;
 
 rel_vdev:
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/vpx3220.c linux-libre-2.6.33-gnu1/drivers/media/video/vpx3220.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/vpx3220.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/vpx3220.c	2010-02-24 13:52:17.000000000 -0500
@@ -391,7 +391,7 @@ static int vpx3220_s_routing(struct v4l2
 		{0x0e, 1}
 	};
 
-	if (input < 0 || input > 2)
+	if (input > 2)
 		return -EINVAL;
 
 	v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/w9968cf.c linux-libre-2.6.33-gnu1/drivers/media/video/w9968cf.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/w9968cf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/w9968cf.c	2010-02-24 13:52:17.000000000 -0500
@@ -2323,9 +2323,9 @@ static int w9968cf_sensor_init(struct w9
 error:
 	cam->sensor_initialized = 0;
 	cam->sensor = CC_UNKNOWN;
-	DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
+	DBG(1, "Image sensor initialization failed for %s (%s). "
 	       "Try to detach and attach this device again",
-	    symbolic(camlist, cam->id), cam->v4ldev->num)
+	    symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
 	return err;
 }
 
@@ -2571,7 +2571,8 @@ static void w9968cf_release_resources(st
 {
 	mutex_lock(&w9968cf_devlist_mutex);
 
-	DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num)
+	DBG(2, "V4L device deregistered: %s",
+	    video_device_node_name(cam->v4ldev))
 
 	video_unregister_device(cam->v4ldev);
 	list_del(&cam->v4llist);
@@ -2605,17 +2606,19 @@ static int w9968cf_open(struct file *fil
 
 	if (cam->sensor == CC_UNKNOWN) {
 		DBG(2, "No supported image sensor has been detected by the "
-		       "'ovcamchip' module for the %s (/dev/video%d). Make "
-		       "sure it is loaded *before* (re)connecting the camera.",
-		    symbolic(camlist, cam->id), cam->v4ldev->num)
+		       "'ovcamchip' module for the %s (%s). Make sure "
+		       "it is loaded *before* (re)connecting the camera.",
+		    symbolic(camlist, cam->id),
+		    video_device_node_name(cam->v4ldev))
 		mutex_unlock(&cam->dev_mutex);
 		up_read(&w9968cf_disconnect);
 		return -ENODEV;
 	}
 
 	if (cam->users) {
-		DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
-		    symbolic(camlist, cam->id), cam->v4ldev->num, cam->command)
+		DBG(2, "%s (%s) has been already occupied by '%s'",
+		    symbolic(camlist, cam->id),
+		    video_device_node_name(cam->v4ldev), cam->command)
 		if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
 			mutex_unlock(&cam->dev_mutex);
 			up_read(&w9968cf_disconnect);
@@ -2636,8 +2639,8 @@ static int w9968cf_open(struct file *fil
 		mutex_lock(&cam->dev_mutex);
 	}
 
-	DBG(5, "Opening '%s', /dev/video%d ...",
-	    symbolic(camlist, cam->id), cam->v4ldev->num)
+	DBG(5, "Opening '%s', %s ...",
+	    symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
 
 	cam->streaming = 0;
 	cam->misconfigured = 0;
@@ -2874,8 +2877,7 @@ static long w9968cf_v4l_ioctl(struct fil
 			.minwidth = cam->minwidth,
 			.minheight = cam->minheight,
 		};
-		sprintf(cap.name, "W996[87]CF USB Camera #%d",
-			cam->v4ldev->num);
+		sprintf(cap.name, "W996[87]CF USB Camera");
 		cap.maxwidth = (cam->upscaling && w9968cf_vpp)
 			       ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
 				 : cam->maxwidth;
@@ -3485,7 +3487,6 @@ w9968cf_usb_probe(struct usb_interface*
 
 	strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
 	cam->v4ldev->fops = &w9968cf_fops;
-	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	video_set_drvdata(cam->v4ldev, cam);
 	cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
@@ -3501,7 +3502,8 @@ w9968cf_usb_probe(struct usb_interface*
 		goto fail;
 	}
 
-	DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num)
+	DBG(2, "V4L device registered as %s",
+	    video_device_node_name(cam->v4ldev))
 
 	/* Set some basic constants */
 	w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
@@ -3557,10 +3559,10 @@ static void w9968cf_usb_disconnect(struc
 		wake_up_interruptible_all(&cam->open);
 
 		if (cam->users) {
-			DBG(2, "The device is open (/dev/video%d)! "
+			DBG(2, "The device is open (%s)! "
 			       "Process name: %s. Deregistration and memory "
 			       "deallocation are deferred on close.",
-			    cam->v4ldev->num, cam->command)
+			    video_device_node_name(cam->v4ldev), cam->command)
 			cam->misconfigured = 1;
 			w9968cf_stop_transfer(cam);
 			wake_up_interruptible(&cam->wait_queue);
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/zc0301/zc0301_core.c linux-libre-2.6.33-gnu1/drivers/media/video/zc0301/zc0301_core.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/zc0301/zc0301_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/zc0301/zc0301_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -538,8 +538,8 @@ static int zc0301_stream_interrupt(struc
 	else if (cam->stream != STREAM_OFF) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "URB timeout reached. The camera is misconfigured. To "
-		       "use it, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use it, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -640,7 +640,8 @@ static void zc0301_release_resources(str
 {
 	struct zc0301_device *cam = container_of(kref, struct zc0301_device,
 						 kref);
-	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num);
+	DBG(2, "V4L2 device %s deregistered",
+	    video_device_node_name(cam->v4ldev));
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 	usb_put_dev(cam->usbdev);
@@ -679,7 +680,8 @@ static int zc0301_open(struct file *filp
 	}
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->num);
+		DBG(2, "Device %s is busy...",
+		    video_device_node_name(cam->v4ldev));
 		DBG(3, "Simultaneous opens are not supported");
 		if ((filp->f_flags & O_NONBLOCK) ||
 		    (filp->f_flags & O_NDELAY)) {
@@ -722,7 +724,8 @@ static int zc0301_open(struct file *filp
 	cam->frame_count = 0;
 	zc0301_empty_framequeues(cam);
 
-	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num);
+	DBG(3, "Video device %s is open",
+	    video_device_node_name(cam->v4ldev));
 
 out:
 	mutex_unlock(&cam->open_mutex);
@@ -746,7 +749,8 @@ static int zc0301_release(struct file *f
 	cam->users--;
 	wake_up_interruptible_nr(&cam->wait_open, 1);
 
-	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num);
+	DBG(3, "Video device %s closed",
+	    video_device_node_name(cam->v4ldev));
 
 	kref_put(&cam->kref, zc0301_release_resources);
 
@@ -1276,8 +1280,8 @@ zc0301_vidioc_s_crop(struct zc0301_devic
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1289,8 +1293,8 @@ zc0301_vidioc_s_crop(struct zc0301_devic
 	    nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -1471,8 +1475,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_de
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1483,8 +1487,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_de
 	    nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
-		       "use the camera, close and open /dev/video%d again.",
-		    cam->v4ldev->num);
+		       "use the camera, close and open %s again.",
+		    video_device_node_name(cam->v4ldev));
 		return -ENOMEM;
 	}
 
@@ -1530,8 +1534,8 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_d
 	if (err) { /* atomic, no rollback in ioctl() */
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
-		       "problems. To use the camera, close and open "
-		       "/dev/video%d again.", cam->v4ldev->num);
+		       "problems. To use the camera, close and open %s again.",
+		       video_device_node_name(cam->v4ldev));
 		return -EIO;
 	}
 
@@ -1984,7 +1988,6 @@ zc0301_usb_probe(struct usb_interface* i
 
 	strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
 	cam->v4ldev->fops = &zc0301_fops;
-	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	cam->v4ldev->parent = &udev->dev;
 	video_set_drvdata(cam->v4ldev, cam);
@@ -2003,7 +2006,8 @@ zc0301_usb_probe(struct usb_interface* i
 		goto fail;
 	}
 
-	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num);
+	DBG(2, "V4L2 device registered as %s",
+	    video_device_node_name(cam->v4ldev));
 
 	cam->module_param.force_munmap = force_munmap[dev_nr];
 	cam->module_param.frame_timeout = frame_timeout[dev_nr];
@@ -2040,9 +2044,9 @@ static void zc0301_usb_disconnect(struct
 	DBG(2, "Disconnecting %s...", cam->v4ldev->name);
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is open! Deregistration and "
+		DBG(2, "Device %s is open! Deregistration and "
 		       "memory deallocation are deferred.",
-		    cam->v4ldev->num);
+		    video_device_node_name(cam->v4ldev));
 		cam->state |= DEV_MISCONFIGURED;
 		zc0301_stop_transfer(cam);
 		cam->state |= DEV_DISCONNECTED;
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/zoran/zoran_driver.c linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_driver.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/zoran/zoran_driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran_driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -2764,7 +2764,7 @@ static int zoran_enum_input(struct file
 	struct zoran_fh *fh = __fh;
 	struct zoran *zr = fh->zr;
 
-	if (inp->index < 0 || inp->index >= zr->card.inputs)
+	if (inp->index >= zr->card.inputs)
 		return -EINVAL;
 	else {
 		int id = inp->index;
@@ -3387,6 +3387,5 @@ struct video_device zoran_template __dev
 	.ioctl_ops = &zoran_ioctl_ops,
 	.release = &zoran_vdev_release,
 	.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-	.minor = -1
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/zoran/zoran.h linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran.h
--- linux-libre-2.6.32-gnu1/drivers/media/video/zoran/zoran.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/zoran/zoran.h	2010-02-24 13:52:17.000000000 -0500
@@ -106,7 +106,7 @@ struct zoran_params {
 	unsigned long jpeg_markers;	/* Which markers should go into the JPEG output.
 					 * Unless you exactly know what you do, leave them untouched.
 					 * Inluding less markers will make the resulting code
-					 * smaller, but there will be fewer aplications
+					 * smaller, but there will be fewer applications
 					 * which can read it.
 					 * The presence of the APP and COM marker is
 					 * influenced by APP0_len and COM_len ONLY! */
diff -druNp linux-libre-2.6.32-gnu1/drivers/media/video/zr364xx.c linux-libre-2.6.33-gnu1/drivers/media/video/zr364xx.c
--- linux-libre-2.6.32-gnu1/drivers/media/video/zr364xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/media/video/zr364xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,6 +115,7 @@ static struct usb_device_id device_table
 	{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
 	{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
 	{USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
+	{USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
 	{}			/* Terminating entry */
 };
 
@@ -1454,7 +1455,6 @@ static struct video_device zr364xx_templ
 	.fops = &zr364xx_fops,
 	.ioctl_ops = &zr364xx_ioctl_ops,
 	.release = video_device_release,
-	.minor = -1,
 };
 
 
@@ -1634,8 +1634,8 @@ static int zr364xx_probe(struct usb_inte
 
 	spin_lock_init(&cam->slock);
 
-	dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n",
-		 cam->vdev->num);
+	dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n",
+		 video_device_node_name(cam->vdev));
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/fusion/mptbase.c linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.c
--- linux-libre-2.6.32-gnu1/drivers/message/fusion/mptbase.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.c	2010-02-24 13:52:17.000000000 -0500
@@ -1587,7 +1587,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
 {
 	u8		__iomem *mem;
 	int		 ii;
-	unsigned long	 mem_phys;
+	resource_size_t	 mem_phys;
 	unsigned long	 port;
 	u32		 msize;
 	u32		 psize;
@@ -1677,8 +1677,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
 		return -EINVAL;
 	}
 	ioc->memmap = mem;
-	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
-	    ioc->name, mem, mem_phys));
+	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
+	    ioc->name, mem, (unsigned long long)mem_phys));
 
 	ioc->mem_phys = mem_phys;
 	ioc->chip = (SYSIF_REGS __iomem *)mem;
@@ -4330,6 +4330,8 @@ initChainBuffers(MPT_ADAPTER *ioc)
 
 	if (ioc->bus_type == SPI)
 		num_chain *= MPT_SCSI_CAN_QUEUE;
+	else if (ioc->bus_type == SAS)
+		num_chain *= MPT_SAS_CAN_QUEUE;
 	else
 		num_chain *= MPT_FC_CAN_QUEUE;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/fusion/mptbase.h linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.h
--- linux-libre-2.6.32-gnu1/drivers/message/fusion/mptbase.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/fusion/mptbase.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2008 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.12"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.12"
+#define MPT_LINUX_VERSION_COMMON	"3.04.13"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.13"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/fusion/mptctl.c linux-libre-2.6.33-gnu1/drivers/message/fusion/mptctl.c
--- linux-libre-2.6.32-gnu1/drivers/message/fusion/mptctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/fusion/mptctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsign
 	 */
 	iocnumX = khdr.iocnum & 0xFF;
 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
-	    (iocp == NULL)) {
-		printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
-				__FILE__, __LINE__, iocnumX);
+	    (iocp == NULL))
 		return -ENODEV;
-	}
 
 	if (!iocp->active) {
 		printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/fusion/mptscsih.c linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.c
--- linux-libre-2.6.32-gnu1/drivers/message/fusion/mptscsih.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.c	2010-02-24 13:52:17.000000000 -0500
@@ -792,11 +792,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			 *  precedence!
 			 */
 			sc->result = (DID_OK << 16) | scsi_status;
-			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
-				/* Have already saved the status and sense data
+			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
+
+				/*
+				 * For an Errata on LSI53C1030
+				 * When the length of request data
+				 * and transfer data are different
+				 * with result of command (READ or VERIFY),
+				 * DID_SOFT_ERROR is set.
 				 */
-				;
-			} else {
+				if (ioc->bus_type == SPI) {
+					if (pScsiReq->CDB[0] == READ_6  ||
+					    pScsiReq->CDB[0] == READ_10 ||
+					    pScsiReq->CDB[0] == READ_12 ||
+					    pScsiReq->CDB[0] == READ_16 ||
+					    pScsiReq->CDB[0] == VERIFY  ||
+					    pScsiReq->CDB[0] == VERIFY_16) {
+						if (scsi_bufflen(sc) !=
+							xfer_cnt) {
+							sc->result =
+							DID_SOFT_ERROR << 16;
+						    printk(KERN_WARNING "Errata"
+						    "on LSI53C1030 occurred."
+						    "sc->req_bufflen=0x%02x,"
+						    "xfer_cnt=0x%02x\n",
+						    scsi_bufflen(sc),
+						    xfer_cnt);
+						}
+					}
+				}
+
 				if (xfer_cnt < sc->underflow) {
 					if (scsi_status == SAM_STAT_BUSY)
 						sc->result = SAM_STAT_BUSY;
@@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			sc->result = (DID_OK << 16) | scsi_status;
 			if (scsi_state == 0) {
 				;
-			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
+			} else if (scsi_state &
+			    MPI_SCSI_STATE_AUTOSENSE_VALID) {
+
+				/*
+				 * For potential trouble on LSI53C1030.
+				 * (date:2007.xx.)
+				 * It is checked whether the length of
+				 * request data is equal to
+				 * the length of transfer and residual.
+				 * MEDIUM_ERROR is set by incorrect data.
+				 */
+				if ((ioc->bus_type == SPI) &&
+					(sc->sense_buffer[2] & 0x20)) {
+					u32	 difftransfer;
+					difftransfer =
+					sc->sense_buffer[3] << 24 |
+					sc->sense_buffer[4] << 16 |
+					sc->sense_buffer[5] << 8 |
+					sc->sense_buffer[6];
+					if (((sc->sense_buffer[3] & 0x80) ==
+						0x80) && (scsi_bufflen(sc)
+						!= xfer_cnt)) {
+						sc->sense_buffer[2] =
+						    MEDIUM_ERROR;
+						sc->sense_buffer[12] = 0xff;
+						sc->sense_buffer[13] = 0xff;
+						printk(KERN_WARNING"Errata"
+						"on LSI53C1030 occurred."
+						"sc->req_bufflen=0x%02x,"
+						"xfer_cnt=0x%02x\n" ,
+						scsi_bufflen(sc),
+						xfer_cnt);
+					}
+					if (((sc->sense_buffer[3] & 0x80)
+						!= 0x80) &&
+						(scsi_bufflen(sc) !=
+						xfer_cnt + difftransfer)) {
+						sc->sense_buffer[2] =
+							MEDIUM_ERROR;
+						sc->sense_buffer[12] = 0xff;
+						sc->sense_buffer[13] = 0xff;
+						printk(KERN_WARNING
+						"Errata on LSI53C1030 occurred"
+						"sc->req_bufflen=0x%02x,"
+						" xfer_cnt=0x%02x,"
+						"difftransfer=0x%02x\n",
+						scsi_bufflen(sc),
+						xfer_cnt,
+						difftransfer);
+					}
+				}
+
 				/*
 				 * If running against circa 200003dd 909 MPT f/w,
 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
@@ -1720,7 +1796,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
 		   "Command not in the active list! (sc=%p)\n", ioc->name,
 		   SCpnt));
-		retval = 0;
+		retval = SUCCESS;
 		goto out;
 	}
 
@@ -2275,11 +2351,12 @@ mptscsih_slave_destroy(struct scsi_devic
  *	mptscsih_change_queue_depth - This function will set a devices queue depth
  *	@sdev: per scsi_device pointer
  *	@qdepth: requested queue depth
+ *	@reason: calling context
  *
  *	Adding support for new 'change_queue_depth' api.
 */
 int
-mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
 	VirtTarget 		*vtarget;
@@ -2291,6 +2368,9 @@ mptscsih_change_queue_depth(struct scsi_
 	starget = scsi_target(sdev);
 	vtarget = starget->hostdata;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (ioc->bus_type == SPI) {
 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
 			max_depth = 1;
@@ -2357,7 +2437,8 @@ mptscsih_slave_configure(struct scsi_dev
 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
 		    vtarget->minSyncFactor));
 
-	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
+				    SCSI_QDEPTH_DEFAULT);
 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		"tagged %d, simple %d, ordered %d\n",
 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/fusion/mptscsih.h linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.h
--- linux-libre-2.6.32-gnu1/drivers/message/fusion/mptscsih.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/fusion/mptscsih.h	2010-02-24 13:52:17.000000000 -0500
@@ -128,7 +128,8 @@ extern int mptscsih_taskmgmt_complete(MP
 extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason);
 extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern struct device_attribute *mptscsih_host_attrs[];
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/i2o/i2o_block.c linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_block.c
--- linux-libre-2.6.32-gnu1/drivers/message/i2o/i2o_block.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_block.c	2010-02-24 13:52:17.000000000 -0500
@@ -940,7 +940,7 @@ static const struct block_device_operati
  *	Allocate memory for the i2o_block_device struct, gendisk and request
  *	queue and initialize them as far as no additional information is needed.
  *
- *	Returns a pointer to the allocated I2O Block device on succes or a
+ *	Returns a pointer to the allocated I2O Block device on success or a
  *	negative error code on failure.
  */
 static struct i2o_block_device *i2o_block_device_alloc(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/i2o/i2o_config.c linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_config.c
--- linux-libre-2.6.32-gnu1/drivers/message/i2o/i2o_config.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/i2o/i2o_config.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,8 +40,7 @@
 
 #define SG_TABLESIZE		30
 
-static int i2o_cfg_ioctl(struct inode *, struct file *, unsigned int,
-			 unsigned long);
+static long i2o_cfg_ioctl(struct file *, unsigned int, unsigned long);
 
 static spinlock_t i2o_config_lock;
 
@@ -751,7 +750,7 @@ static long i2o_cfg_compat_ioctl(struct
 	lock_kernel();
 	switch (cmd) {
 	case I2OGETIOPS:
-		ret = i2o_cfg_ioctl(NULL, file, cmd, arg);
+		ret = i2o_cfg_ioctl(file, cmd, arg);
 		break;
 	case I2OPASSTHRU32:
 		ret = i2o_cfg_passthru32(file, cmd, arg);
@@ -984,11 +983,11 @@ out:
 /*
  * IOCTL Handler
  */
-static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
-			 unsigned long arg)
+static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	int ret;
 
+	lock_kernel();
 	switch (cmd) {
 	case I2OGETIOPS:
 		ret = i2o_cfg_getiops(arg);
@@ -1044,7 +1043,7 @@ static int i2o_cfg_ioctl(struct inode *i
 		osm_debug("unknown ioctl called!\n");
 		ret = -EINVAL;
 	}
-
+	unlock_kernel();
 	return ret;
 }
 
@@ -1118,7 +1117,7 @@ static int cfg_release(struct inode *ino
 static const struct file_operations config_fops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
-	.ioctl = i2o_cfg_ioctl,
+	.unlocked_ioctl = i2o_cfg_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = i2o_cfg_compat_ioctl,
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/message/i2o/iop.c linux-libre-2.6.33-gnu1/drivers/message/i2o/iop.c
--- linux-libre-2.6.32-gnu1/drivers/message/i2o/iop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/message/i2o/iop.c	2010-02-24 13:52:17.000000000 -0500
@@ -132,7 +132,7 @@ u32 i2o_cntxt_list_add(struct i2o_contro
  *	Removes a previously added pointer from the context list and returns
  *	the matching context id.
  *
- *	Returns context id on succes or 0 on failure.
+ *	Returns context id on success or 0 on failure.
  */
 u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
 {
@@ -198,7 +198,7 @@ void *i2o_cntxt_list_get(struct i2o_cont
  *	@c: controller to which the context list belong
  *	@ptr: pointer to which the context id should be fetched
  *
- *	Returns context id which matches to the pointer on succes or 0 on
+ *	Returns context id which matches to the pointer on success or 0 on
  *	failure.
  */
 u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/88pm8607.c linux-libre-2.6.33-gnu1/drivers/mfd/88pm8607.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/88pm8607.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/88pm8607.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,302 @@
+/*
+ * Base driver for Marvell 88PM8607
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.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/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/88pm8607.h>
+
+
+#define PM8607_REG_RESOURCE(_start, _end)		\
+{							\
+	.start	= PM8607_##_start,			\
+	.end	= PM8607_##_end,			\
+	.flags	= IORESOURCE_IO,			\
+}
+
+static struct resource pm8607_regulator_resources[] = {
+	PM8607_REG_RESOURCE(BUCK1, BUCK1),
+	PM8607_REG_RESOURCE(BUCK2, BUCK2),
+	PM8607_REG_RESOURCE(BUCK3, BUCK3),
+	PM8607_REG_RESOURCE(LDO1,  LDO1),
+	PM8607_REG_RESOURCE(LDO2,  LDO2),
+	PM8607_REG_RESOURCE(LDO3,  LDO3),
+	PM8607_REG_RESOURCE(LDO4,  LDO4),
+	PM8607_REG_RESOURCE(LDO5,  LDO5),
+	PM8607_REG_RESOURCE(LDO6,  LDO6),
+	PM8607_REG_RESOURCE(LDO7,  LDO7),
+	PM8607_REG_RESOURCE(LDO8,  LDO8),
+	PM8607_REG_RESOURCE(LDO9,  LDO9),
+	PM8607_REG_RESOURCE(LDO10, LDO10),
+	PM8607_REG_RESOURCE(LDO12, LDO12),
+	PM8607_REG_RESOURCE(LDO14, LDO14),
+};
+
+#define PM8607_REG_DEVS(_name, _id)					\
+{									\
+	.name		= "88pm8607-" #_name,				\
+	.num_resources	= 1,						\
+	.resources	= &pm8607_regulator_resources[PM8607_ID_##_id],	\
+}
+
+static struct mfd_cell pm8607_devs[] = {
+	PM8607_REG_DEVS(buck1, BUCK1),
+	PM8607_REG_DEVS(buck2, BUCK2),
+	PM8607_REG_DEVS(buck3, BUCK3),
+	PM8607_REG_DEVS(ldo1,  LDO1),
+	PM8607_REG_DEVS(ldo2,  LDO2),
+	PM8607_REG_DEVS(ldo3,  LDO3),
+	PM8607_REG_DEVS(ldo4,  LDO4),
+	PM8607_REG_DEVS(ldo5,  LDO5),
+	PM8607_REG_DEVS(ldo6,  LDO6),
+	PM8607_REG_DEVS(ldo7,  LDO7),
+	PM8607_REG_DEVS(ldo8,  LDO8),
+	PM8607_REG_DEVS(ldo9,  LDO9),
+	PM8607_REG_DEVS(ldo10, LDO10),
+	PM8607_REG_DEVS(ldo12, LDO12),
+	PM8607_REG_DEVS(ldo14, LDO14),
+};
+
+static inline int pm8607_read_device(struct pm8607_chip *chip,
+				     int reg, int bytes, void *dest)
+{
+	struct i2c_client *i2c = chip->client;
+	unsigned char data;
+	int ret;
+
+	data = (unsigned char)reg;
+	ret = i2c_master_send(i2c, &data, 1);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static inline int pm8607_write_device(struct pm8607_chip *chip,
+				      int reg, int bytes, void *src)
+{
+	struct i2c_client *i2c = chip->client;
+	unsigned char buf[bytes + 1];
+	int ret;
+
+	buf[0] = (unsigned char)reg;
+	memcpy(&buf[1], src, bytes);
+
+	ret = i2c_master_send(i2c, buf, bytes + 1);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int pm8607_reg_read(struct pm8607_chip *chip, int reg)
+{
+	unsigned char data;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = chip->read(chip, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	if (ret < 0)
+		return ret;
+	else
+		return (int)data;
+}
+EXPORT_SYMBOL(pm8607_reg_read);
+
+int pm8607_reg_write(struct pm8607_chip *chip, int reg,
+		     unsigned char data)
+{
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = chip->write(chip, reg, 1, &data);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm8607_reg_write);
+
+int pm8607_bulk_read(struct pm8607_chip *chip, int reg,
+		     int count, unsigned char *buf)
+{
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = chip->read(chip, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm8607_bulk_read);
+
+int pm8607_bulk_write(struct pm8607_chip *chip, int reg,
+		      int count, unsigned char *buf)
+{
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = chip->write(chip, reg, count, buf);
+	mutex_unlock(&chip->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(pm8607_bulk_write);
+
+int pm8607_set_bits(struct pm8607_chip *chip, int reg,
+		    unsigned char mask, unsigned char data)
+{
+	unsigned char value;
+	int ret;
+
+	mutex_lock(&chip->io_lock);
+	ret = chip->read(chip, reg, 1, &value);
+	if (ret < 0)
+		goto out;
+	value &= ~mask;
+	value |= data;
+	ret = chip->write(chip, reg, 1, &value);
+out:
+	mutex_unlock(&chip->io_lock);
+	return ret;
+}
+EXPORT_SYMBOL(pm8607_set_bits);
+
+
+static const struct i2c_device_id pm8607_id_table[] = {
+	{ "88PM8607", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, pm8607_id_table);
+
+
+static int __devinit pm8607_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct pm8607_platform_data *pdata = client->dev.platform_data;
+	struct pm8607_chip *chip;
+	int i, count;
+	int ret;
+
+	chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->client = client;
+	chip->dev = &client->dev;
+	chip->read = pm8607_read_device;
+	chip->write = pm8607_write_device;
+	i2c_set_clientdata(client, chip);
+
+	mutex_init(&chip->io_lock);
+	dev_set_drvdata(chip->dev, chip);
+
+	ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
+		goto out;
+	}
+	if ((ret & CHIP_ID_MASK) == CHIP_ID)
+		dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
+			 ret);
+	else {
+		dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
+			"Chip ID: %02x\n", ret);
+		goto out;
+	}
+	chip->chip_id = ret;
+
+	ret = pm8607_reg_read(chip, PM8607_BUCK3);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
+		goto out;
+	}
+	if (ret & PM8607_BUCK3_DOUBLE)
+		chip->buck3_double = 1;
+
+	ret = pm8607_reg_read(chip, PM8607_MISC1);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
+		goto out;
+	}
+	if (pdata->i2c_port == PI2C_PORT)
+		ret |= PM8607_MISC1_PI2C;
+	else
+		ret &= ~PM8607_MISC1_PI2C;
+	ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
+		goto out;
+	}
+
+
+	count = ARRAY_SIZE(pm8607_devs);
+	for (i = 0; i < count; i++) {
+		ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i],
+				      1, NULL, 0);
+		if (ret != 0) {
+			dev_err(chip->dev, "Failed to add subdevs\n");
+			goto out;
+		}
+	}
+
+	return 0;
+
+out:
+	i2c_set_clientdata(client, NULL);
+	kfree(chip);
+	return ret;
+}
+
+static int __devexit pm8607_remove(struct i2c_client *client)
+{
+	struct pm8607_chip *chip = i2c_get_clientdata(client);
+
+	mfd_remove_devices(chip->dev);
+	kfree(chip);
+	return 0;
+}
+
+static struct i2c_driver pm8607_driver = {
+	.driver	= {
+		.name	= "88PM8607",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm8607_probe,
+	.remove		= __devexit_p(pm8607_remove),
+	.id_table	= pm8607_id_table,
+};
+
+static int __init pm8607_init(void)
+{
+	int ret;
+	ret = i2c_add_driver(&pm8607_driver);
+	if (ret != 0)
+		pr_err("Failed to register 88PM8607 I2C driver: %d\n", ret);
+	return ret;
+}
+subsys_initcall(pm8607_init);
+
+static void __exit pm8607_exit(void)
+{
+	i2c_del_driver(&pm8607_driver);
+}
+module_exit(pm8607_exit);
+
+MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ab3100-core.c linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ab3100-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ab3100-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -900,9 +900,6 @@ static int __init ab3100_probe(struct i2
 		goto exit_no_testreg_client;
 	}
 
-	strlcpy(ab3100->testreg_client->name, id->name,
-		sizeof(ab3100->testreg_client->name));
-
 	err = ab3100_setup(ab3100);
 	if (err)
 		goto exit_no_setup;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ab4500-core.c linux-libre-2.6.33-gnu1/drivers/mfd/ab4500-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ab4500-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ab4500-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@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.
+ *
+ * AB4500 is a companion power management chip used with U8500.
+ * On this platform, this is interfaced with SSP0 controller
+ * which is a ARM primecell pl022.
+ *
+ * At the moment the module just exports read/write features.
+ * Interrupt management to be added - TODO.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/ab4500.h>
+
+/* just required if probe fails, we need to
+ * unregister the device
+ */
+static struct spi_driver ab4500_driver;
+
+/*
+ * This funtion writes to any AB4500 registers using
+ * SPI protocol &  before it writes it packs the data
+ * in the below 24 bit frame format
+ *
+ *	 *|------------------------------------|
+ *	 *| 23|22...18|17.......10|9|8|7......0|
+ *	 *| r/w  bank       adr          data  |
+ *	 * ------------------------------------
+ *
+ * This function shouldn't be called from interrupt
+ * context
+ */
+int ab4500_write(struct ab4500 *ab4500, unsigned char block,
+		unsigned long addr, unsigned char data)
+{
+	struct spi_transfer xfer;
+	struct spi_message	msg;
+	int err;
+	unsigned long spi_data =
+		block << 18 | addr << 10 | data;
+
+	mutex_lock(&ab4500->lock);
+	ab4500->tx_buf[0] = spi_data;
+	ab4500->rx_buf[0] = 0;
+
+	xfer.tx_buf	= ab4500->tx_buf;
+	xfer.rx_buf 	= NULL;
+	xfer.len	= sizeof(unsigned long);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	err = spi_sync(ab4500->spi, &msg);
+	mutex_unlock(&ab4500->lock);
+
+	return err;
+}
+EXPORT_SYMBOL(ab4500_write);
+
+int ab4500_read(struct ab4500 *ab4500, unsigned char block,
+		unsigned long addr)
+{
+	struct spi_transfer xfer;
+	struct spi_message	msg;
+	unsigned long spi_data =
+		1 << 23 | block << 18 | addr << 10;
+
+	mutex_lock(&ab4500->lock);
+	ab4500->tx_buf[0] = spi_data;
+	ab4500->rx_buf[0] = 0;
+
+	xfer.tx_buf	= ab4500->tx_buf;
+	xfer.rx_buf 	= ab4500->rx_buf;
+	xfer.len	= sizeof(unsigned long);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	spi_sync(ab4500->spi, &msg);
+	mutex_unlock(&ab4500->lock);
+
+	return  ab4500->rx_buf[0];
+}
+EXPORT_SYMBOL(ab4500_read);
+
+/* ref: ab3100 core */
+#define AB4500_DEVICE(devname, devid)				\
+static struct platform_device ab4500_##devname##_device = {	\
+	.name	= devid,					\
+	.id	= -1,						\
+}
+
+/* list of childern devices of ab4500 - all are
+ * not populated here - TODO
+ */
+AB4500_DEVICE(charger, "ab4500-charger");
+AB4500_DEVICE(audio, "ab4500-audio");
+AB4500_DEVICE(usb, "ab4500-usb");
+AB4500_DEVICE(tvout, "ab4500-tvout");
+AB4500_DEVICE(sim, "ab4500-sim");
+AB4500_DEVICE(gpadc, "ab4500-gpadc");
+AB4500_DEVICE(clkmgt, "ab4500-clkmgt");
+AB4500_DEVICE(misc, "ab4500-misc");
+
+static struct platform_device *ab4500_platform_devs[] = {
+	&ab4500_charger_device,
+	&ab4500_audio_device,
+	&ab4500_usb_device,
+	&ab4500_tvout_device,
+	&ab4500_sim_device,
+	&ab4500_gpadc_device,
+	&ab4500_clkmgt_device,
+	&ab4500_misc_device,
+};
+
+static int __init ab4500_probe(struct spi_device *spi)
+{
+	struct ab4500	*ab4500;
+	unsigned char revision;
+	int err = 0;
+	int i;
+
+	ab4500 = kzalloc(sizeof *ab4500, GFP_KERNEL);
+	if (!ab4500) {
+		dev_err(&spi->dev, "could not allocate AB4500\n");
+		err = -ENOMEM;
+		goto not_detect;
+	}
+
+	ab4500->spi = spi;
+	spi_set_drvdata(spi, ab4500);
+
+	mutex_init(&ab4500->lock);
+
+	/* read the revision register */
+	revision = ab4500_read(ab4500, AB4500_MISC, AB4500_REV_REG);
+
+	/* revision id 0x0 is for early drop, 0x10 is for cut1.0 */
+	if (revision == 0x0 || revision == 0x10)
+		dev_info(&spi->dev, "Detected chip: %s, revision = %x\n",
+			ab4500_driver.driver.name, revision);
+	else	{
+		dev_err(&spi->dev, "unknown chip: 0x%x\n", revision);
+		goto not_detect;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ab4500_platform_devs); i++)	{
+		ab4500_platform_devs[i]->dev.parent =
+			&spi->dev;
+		platform_set_drvdata(ab4500_platform_devs[i], ab4500);
+	}
+
+	/* register the ab4500 platform devices */
+	platform_add_devices(ab4500_platform_devs,
+			ARRAY_SIZE(ab4500_platform_devs));
+
+	return err;
+
+ not_detect:
+	spi_unregister_driver(&ab4500_driver);
+	kfree(ab4500);
+	return err;
+}
+
+static int __devexit ab4500_remove(struct spi_device *spi)
+{
+	struct ab4500 *ab4500 =
+		spi_get_drvdata(spi);
+
+	kfree(ab4500);
+
+	return 0;
+}
+
+static struct spi_driver ab4500_driver = {
+	.driver = {
+		.name = "ab4500",
+		.owner = THIS_MODULE,
+	},
+	.probe = ab4500_probe,
+	.remove = __devexit_p(ab4500_remove)
+};
+
+static int __devinit ab4500_init(void)
+{
+	return spi_register_driver(&ab4500_driver);
+}
+
+static void __exit ab4500_exit(void)
+{
+	spi_unregister_driver(&ab4500_driver);
+}
+
+subsys_initcall(ab4500_init);
+module_exit(ab4500_exit);
+
+MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com");
+MODULE_DESCRIPTION("AB4500 core driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/adp5520.c linux-libre-2.6.33-gnu1/drivers/mfd/adp5520.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/adp5520.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/adp5520.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,379 @@
+/*
+ * Base driver for Analog Devices ADP5520/ADP5501 MFD PMICs
+ * LCD Backlight: drivers/video/backlight/adp5520_bl
+ * LEDs		: drivers/led/leds-adp5520
+ * GPIO		: drivers/gpio/adp5520-gpio (ADP5520 only)
+ * Keys		: drivers/input/keyboard/adp5520-keys (ADP5520 only)
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Derived from da903x:
+ * Copyright (C) 2008 Compulab, Ltd.
+ * 	Mike Rapoport <mike@compulab.co.il>
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ * 	Eric Miao <eric.miao@marvell.com>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+
+#include <linux/mfd/adp5520.h>
+
+struct adp5520_chip {
+	struct i2c_client *client;
+	struct device *dev;
+	struct mutex lock;
+	struct blocking_notifier_head notifier_list;
+	int irq;
+	unsigned long id;
+};
+
+static int __adp5520_read(struct i2c_client *client,
+				int reg, uint8_t *val)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
+		return ret;
+	}
+
+	*val = (uint8_t)ret;
+	return 0;
+}
+
+static int __adp5520_write(struct i2c_client *client,
+				 int reg, uint8_t val)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(client, reg, val);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
+				val, reg);
+		return ret;
+	}
+	return 0;
+}
+
+static int __adp5520_ack_bits(struct i2c_client *client, int reg,
+			      uint8_t bit_mask)
+{
+	struct adp5520_chip *chip = i2c_get_clientdata(client);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = __adp5520_read(client, reg, &reg_val);
+
+	if (!ret) {
+		reg_val |= bit_mask;
+		ret = __adp5520_write(client, reg, reg_val);
+	}
+
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+
+int adp5520_write(struct device *dev, int reg, uint8_t val)
+{
+	return __adp5520_write(to_i2c_client(dev), reg, val);
+}
+EXPORT_SYMBOL_GPL(adp5520_write);
+
+int adp5520_read(struct device *dev, int reg, uint8_t *val)
+{
+	return __adp5520_read(to_i2c_client(dev), reg, val);
+}
+EXPORT_SYMBOL_GPL(adp5520_read);
+
+int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(dev);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = __adp5520_read(chip->client, reg, &reg_val);
+
+	if (!ret && ((reg_val & bit_mask) == 0)) {
+		reg_val |= bit_mask;
+		ret = __adp5520_write(chip->client, reg, reg_val);
+	}
+
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(adp5520_set_bits);
+
+int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(dev);
+	uint8_t reg_val;
+	int ret;
+
+	mutex_lock(&chip->lock);
+
+	ret = __adp5520_read(chip->client, reg, &reg_val);
+
+	if (!ret && (reg_val & bit_mask)) {
+		reg_val &= ~bit_mask;
+		ret = __adp5520_write(chip->client, reg, reg_val);
+	}
+
+	mutex_unlock(&chip->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(adp5520_clr_bits);
+
+int adp5520_register_notifier(struct device *dev, struct notifier_block *nb,
+				unsigned int events)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(dev);
+
+	if (chip->irq) {
+		adp5520_set_bits(chip->dev, ADP5520_INTERRUPT_ENABLE,
+			events & (ADP5520_KP_IEN | ADP5520_KR_IEN |
+			ADP5520_OVP_IEN | ADP5520_CMPR_IEN));
+
+		return blocking_notifier_chain_register(&chip->notifier_list,
+			 nb);
+	}
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(adp5520_register_notifier);
+
+int adp5520_unregister_notifier(struct device *dev, struct notifier_block *nb,
+				unsigned int events)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(dev);
+
+	adp5520_clr_bits(chip->dev, ADP5520_INTERRUPT_ENABLE,
+		events & (ADP5520_KP_IEN | ADP5520_KR_IEN |
+		ADP5520_OVP_IEN | ADP5520_CMPR_IEN));
+
+	return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(adp5520_unregister_notifier);
+
+static irqreturn_t adp5520_irq_thread(int irq, void *data)
+{
+	struct adp5520_chip *chip = data;
+	unsigned int events;
+	uint8_t reg_val;
+	int ret;
+
+	ret = __adp5520_read(chip->client, ADP5520_MODE_STATUS, &reg_val);
+	if (ret)
+		goto out;
+
+	events =  reg_val & (ADP5520_OVP_INT | ADP5520_CMPR_INT |
+		ADP5520_GPI_INT | ADP5520_KR_INT | ADP5520_KP_INT);
+
+	blocking_notifier_call_chain(&chip->notifier_list, events, NULL);
+	/* ACK, Sticky bits are W1C */
+	__adp5520_ack_bits(chip->client, ADP5520_MODE_STATUS, events);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int __remove_subdev(struct device *dev, void *unused)
+{
+	platform_device_unregister(to_platform_device(dev));
+	return 0;
+}
+
+static int adp5520_remove_subdevs(struct adp5520_chip *chip)
+{
+	return device_for_each_child(chip->dev, NULL, __remove_subdev);
+}
+
+static int __devinit adp5520_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct adp5520_platform_data *pdata = client->dev.platform_data;
+	struct platform_device *pdev;
+	struct adp5520_chip *chip;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "SMBUS Word Data not Supported\n");
+		return -EIO;
+	}
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "missing platform data\n");
+		return -ENODEV;
+	}
+
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, chip);
+	chip->client = client;
+
+	chip->dev = &client->dev;
+	chip->irq = client->irq;
+	chip->id = id->driver_data;
+	mutex_init(&chip->lock);
+
+	if (chip->irq) {
+		BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);
+
+		ret = request_threaded_irq(chip->irq, NULL, adp5520_irq_thread,
+				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				"adp5520", chip);
+		if (ret) {
+			dev_err(&client->dev, "failed to request irq %d\n",
+					chip->irq);
+			goto out_free_chip;
+		}
+	}
+
+	ret = adp5520_write(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
+	if (ret) {
+		dev_err(&client->dev, "failed to write\n");
+		goto out_free_irq;
+	}
+
+	if (pdata->keys) {
+		pdev = platform_device_register_data(chip->dev, "adp5520-keys",
+				chip->id, pdata->keys, sizeof(*pdata->keys));
+		if (IS_ERR(pdev)) {
+			ret = PTR_ERR(pdev);
+			goto out_remove_subdevs;
+		}
+	}
+
+	if (pdata->gpio) {
+		pdev = platform_device_register_data(chip->dev, "adp5520-gpio",
+				chip->id, pdata->gpio, sizeof(*pdata->gpio));
+		if (IS_ERR(pdev)) {
+			ret = PTR_ERR(pdev);
+			goto out_remove_subdevs;
+		}
+	}
+
+	if (pdata->leds) {
+		pdev = platform_device_register_data(chip->dev, "adp5520-led",
+				chip->id, pdata->leds, sizeof(*pdata->leds));
+		if (IS_ERR(pdev)) {
+			ret = PTR_ERR(pdev);
+			goto out_remove_subdevs;
+		}
+	}
+
+	if (pdata->backlight) {
+		pdev = platform_device_register_data(chip->dev,
+						"adp5520-backlight",
+						chip->id,
+						pdata->backlight,
+						sizeof(*pdata->backlight));
+		if (IS_ERR(pdev)) {
+			ret = PTR_ERR(pdev);
+			goto out_remove_subdevs;
+		}
+	}
+
+	return 0;
+
+out_remove_subdevs:
+	adp5520_remove_subdevs(chip);
+
+out_free_irq:
+	if (chip->irq)
+		free_irq(chip->irq, chip);
+
+out_free_chip:
+	i2c_set_clientdata(client, NULL);
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit adp5520_remove(struct i2c_client *client)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
+
+	if (chip->irq)
+		free_irq(chip->irq, chip);
+
+	adp5520_remove_subdevs(chip);
+	adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
+	i2c_set_clientdata(client, NULL);
+	kfree(chip);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int adp5520_suspend(struct i2c_client *client,
+				 pm_message_t state)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
+
+	adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
+	return 0;
+}
+
+static int adp5520_resume(struct i2c_client *client)
+{
+	struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
+
+	adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
+	return 0;
+}
+#else
+#define adp5520_suspend	NULL
+#define adp5520_resume	NULL
+#endif
+
+static const struct i2c_device_id adp5520_id[] = {
+	{ "pmic-adp5520", ID_ADP5520 },
+	{ "pmic-adp5501", ID_ADP5501 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adp5520_id);
+
+static struct i2c_driver adp5520_driver = {
+	.driver = {
+		.name	= "adp5520",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= adp5520_probe,
+	.remove		= __devexit_p(adp5520_remove),
+	.suspend	= adp5520_suspend,
+	.resume		= adp5520_resume,
+	.id_table 	= adp5520_id,
+};
+
+static int __init adp5520_init(void)
+{
+	return i2c_add_driver(&adp5520_driver);
+}
+module_init(adp5520_init);
+
+static void __exit adp5520_exit(void)
+{
+	i2c_del_driver(&adp5520_driver);
+}
+module_exit(adp5520_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/asic3.c linux-libre-2.6.33-gnu1/drivers/mfd/asic3.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/asic3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/asic3.c	2010-02-24 13:52:17.000000000 -0500
@@ -80,6 +80,7 @@ struct asic3 {
 	u16 irq_bothedge[4];
 	struct gpio_chip gpio;
 	struct device *dev;
+	void __iomem *tmio_cnf;
 
 	struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)];
 };
@@ -685,8 +686,24 @@ static struct mfd_cell asic3_cell_ds1wm
 	.resources     = ds1wm_resources,
 };
 
+static void asic3_mmc_pwr(struct platform_device *pdev, int state)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	tmio_core_mmc_pwr(asic->tmio_cnf, 1 - asic->bus_shift, state);
+}
+
+static void asic3_mmc_clk_div(struct platform_device *pdev, int state)
+{
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	tmio_core_mmc_clk_div(asic->tmio_cnf, 1 - asic->bus_shift, state);
+}
+
 static struct tmio_mmc_data asic3_mmc_data = {
-	.hclk = 24576000,
+	.hclk           = 24576000,
+	.set_pwr        = asic3_mmc_pwr,
+	.set_clk_div    = asic3_mmc_clk_div,
 };
 
 static struct resource asic3_mmc_resources[] = {
@@ -696,11 +713,6 @@ static struct resource asic3_mmc_resourc
 		.flags = IORESOURCE_MEM,
 	},
 	{
-		.start = ASIC3_SD_CONFIG_BASE,
-		.end   = ASIC3_SD_CONFIG_BASE + 0x1ff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
 		.start = 0,
 		.end   = 0,
 		.flags = IORESOURCE_IRQ,
@@ -743,6 +755,10 @@ static int asic3_mmc_enable(struct platf
 	asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF),
 			   ASIC3_SDHWCTRL_SDPWR, 1);
 
+	/* ASIC3_SD_CTRL_BASE assumes 32-bit addressing, TMIO is 16-bit */
+	tmio_core_mmc_enable(asic->tmio_cnf, 1 - asic->bus_shift,
+			     ASIC3_SD_CTRL_BASE >> 1);
+
 	return 0;
 }
 
@@ -797,10 +813,15 @@ static int __init asic3_mfd_probe(struct
 	asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
 
 	/* MMC */
+	asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
+				 mem_sdio->start, 0x400 >> asic->bus_shift);
+	if (!asic->tmio_cnf) {
+		ret = -ENOMEM;
+		dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n");
+		goto out;
+	}
 	asic3_mmc_resources[0].start >>= asic->bus_shift;
 	asic3_mmc_resources[0].end   >>= asic->bus_shift;
-	asic3_mmc_resources[1].start >>= asic->bus_shift;
-	asic3_mmc_resources[1].end   >>= asic->bus_shift;
 
 	asic3_cell_mmc.platform_data = &asic3_cell_mmc;
 	asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc);
@@ -820,7 +841,10 @@ static int __init asic3_mfd_probe(struct
 
 static void asic3_mfd_remove(struct platform_device *pdev)
 {
+	struct asic3 *asic = platform_get_drvdata(pdev);
+
 	mfd_remove_devices(&pdev->dev);
+	iounmap(asic->tmio_cnf);
 }
 
 /* Core */
@@ -908,7 +932,7 @@ static int __init asic3_probe(struct pla
 	return ret;
 }
 
-static int asic3_remove(struct platform_device *pdev)
+static int __devexit asic3_remove(struct platform_device *pdev)
 {
 	int ret;
 	struct asic3 *asic = platform_get_drvdata(pdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ezx-pcap.c linux-libre-2.6.33-gnu1/drivers/mfd/ezx-pcap.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ezx-pcap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ezx-pcap.c	2010-02-24 13:52:17.000000000 -0500
@@ -387,7 +387,6 @@ static int __devinit pcap_add_subdev(str
 	pdev = platform_device_alloc(subdev->name, subdev->id);
 	pdev->dev.parent = &pcap->spi->dev;
 	pdev->dev.platform_data = subdev->platform_data;
-	platform_set_drvdata(pdev, pcap);
 
 	return platform_device_add(pdev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/Kconfig linux-libre-2.6.33-gnu1/drivers/mfd/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mfd/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,14 @@ config MFD_ASIC3
 	  This driver supports the ASIC3 multifunction chip found on many
 	  PDAs (mainly iPAQ and HTC based ones)
 
+config MFD_SH_MOBILE_SDHI
+	bool "Support for SuperH Mobile SDHI"
+	depends on SUPERH
+	select MFD_CORE
+	 ---help---
+	  This driver supports the SDHI hardware block found in many
+	  SuperH Mobile SoCs.
+
 config MFD_DM355EVM_MSP
 	bool "DaVinci DM355 EVM microcontroller"
 	depends on I2C && MACH_DAVINCI_DM355_EVM
@@ -95,10 +103,10 @@ config MENELAUS
 	  cell phones and PDAs.
 
 config TWL4030_CORE
-	bool "Texas Instruments TWL4030/TPS659x0 Support"
+	bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
 	depends on I2C=y && GENERIC_HARDIRQS
 	help
-	  Say yes here if you have TWL4030 family chip on your board.
+	  Say yes here if you have TWL4030 / TWL6030 family chip on your board.
 	  This core driver provides register access and IRQ handling
 	  facilities, and registers devices for the various functions
 	  so that function-specific drivers can bind to them.
@@ -121,6 +129,12 @@ config TWL4030_POWER
 	  and load scripts controling which resources are switched off/on
 	  or reset when a sleep, wakeup or warm reset event occurs.
 
+config TWL4030_CODEC
+	bool
+	depends on TWL4030_CORE
+	select MFD_CORE
+	default n
+
 config MFD_TMIO
 	bool
 	default n
@@ -160,6 +174,16 @@ config PMIC_DA903X
 	  individual components like LCD backlight, voltage regulators,
 	  LEDs and battery-charger under the corresponding menus.
 
+config PMIC_ADP5520
+	bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
+	depends on I2C=y
+	help
+	  Say yes here to add support for Analog Devices AD5520 and ADP5501,
+	  Multifunction Power Management IC. This includes
+	  the I2C driver and the core APIs _only_, you have to select
+	  individual components like LCD backlight, LEDs, GPIOs and Kepad
+	  under the corresponding menus.
+
 config MFD_WM8400
 	tristate "Support Wolfson Microelectronics WM8400"
 	select MFD_CORE
@@ -171,12 +195,12 @@ config MFD_WM8400
 	  the functionality of the device.
 
 config MFD_WM831X
-	tristate "Support Wolfson Microelectronics WM831x PMICs"
+	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
 	select MFD_CORE
-	depends on I2C
+	depends on I2C=y
 	help
-	  Support for the Wolfson Microelecronics WM831x PMICs.  This
-	  driver provides common support for accessing the device,
+	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
+	  This driver provides common support for accessing the device,
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
@@ -305,6 +329,25 @@ config EZX_PCAP
 	  This enables the PCAP ASIC present on EZX Phones. This is
 	  needed for MMC, TouchScreen, Sound, USB, etc..
 
+config MFD_88PM8607
+	bool "Support Marvell 88PM8607"
+	depends on I2C=y
+	select MFD_CORE
+	help
+	  This supports for Marvell 88PM8607 Power Management IC. This includes
+	  the I2C driver and the core APIs _only_, you have to select
+	  individual components like voltage regulators, RTC and
+	  battery-charger under the corresponding menus.
+
+config AB4500_CORE
+	tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip"
+	depends on SPI
+	help
+	  Select this option to enable access to AB4500 power management
+	  chip. This connects to U8500 on the SSP/SPI bus and exports
+	  read/write functions for the devices to get access to this chip.
+	  This chip embeds various other multimedia funtionalities as well.
+
 endmenu
 
 menu "Multimedia Capabilities Port drivers"
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/Makefile linux-libre-2.6.33-gnu1/drivers/mfd/Makefile
--- linux-libre-2.6.32-gnu1/drivers/mfd/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,29 +3,32 @@
 #
 
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
-obj-$(CONFIG_MFD_ASIC3)		+= asic3.o
+obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
+obj-$(CONFIG_MFD_SH_MOBILE_SDHI)		+= sh_mobile_sdhi.o
 
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
 
 obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
 
-obj-$(CONFIG_MFD_T7L66XB)	+= t7l66xb.o
-obj-$(CONFIG_MFD_TC6387XB)	+= tc6387xb.o
-obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o
+obj-$(CONFIG_MFD_T7L66XB)	+= t7l66xb.o tmio_core.o
+obj-$(CONFIG_MFD_TC6387XB)	+= tc6387xb.o tmio_core.o
+obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
 
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
 wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
+wm8350-objs			+= wm8350-irq.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
 obj-$(CONFIG_MFD_WM8350_I2C)	+= wm8350-i2c.o
 
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
-obj-$(CONFIG_TWL4030_CORE)	+= twl4030-core.o twl4030-irq.o
+obj-$(CONFIG_TWL4030_CORE)	+= twl-core.o twl4030-irq.o twl6030-irq.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
+obj-$(CONFIG_TWL4030_CODEC)	+= twl4030-codec.o
 
 obj-$(CONFIG_MFD_MC13783)	+= mc13783-core.o
 
@@ -50,3 +53,6 @@ obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-a
 obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-gpio.o
 obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
+obj-$(CONFIG_AB4500_CORE)	+= ab4500-core.o
+obj-$(CONFIG_MFD_88PM8607)	+= 88pm8607.o
+obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
\ No newline at end of file
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/mc13783-core.c linux-libre-2.6.33-gnu1/drivers/mfd/mc13783-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/mc13783-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/mc13783-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,286 +1,549 @@
 /*
- * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is in parts based on wm8350-core.c and pcf50633-core.c
- *
- * Initial development of this code was funded by
- * Phytec Messtechnik GmbH, http://www.phytec.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.
+ * Copyright 2009 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * loosely based on an earlier driver that has
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  *
- * You 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 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/mfd/mc13783-private.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/core.h>
-#include <linux/spi/spi.h>
-#include <linux/uaccess.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/mc13783-private.h>
 
-#define MC13783_MAX_REG_NUM	0x3f
-#define MC13783_FRAME_MASK	0x00ffffff
-#define MC13783_MAX_REG_NUM	0x3f
-#define MC13783_REG_NUM_SHIFT	0x19
-#define MC13783_WRITE_BIT_SHIFT	31
+#define MC13783_IRQSTAT0	0
+#define MC13783_IRQSTAT0_ADCDONEI	(1 << 0)
+#define MC13783_IRQSTAT0_ADCBISDONEI	(1 << 1)
+#define MC13783_IRQSTAT0_TSI		(1 << 2)
+#define MC13783_IRQSTAT0_WHIGHI		(1 << 3)
+#define MC13783_IRQSTAT0_WLOWI		(1 << 4)
+#define MC13783_IRQSTAT0_CHGDETI	(1 << 6)
+#define MC13783_IRQSTAT0_CHGOVI		(1 << 7)
+#define MC13783_IRQSTAT0_CHGREVI	(1 << 8)
+#define MC13783_IRQSTAT0_CHGSHORTI	(1 << 9)
+#define MC13783_IRQSTAT0_CCCVI		(1 << 10)
+#define MC13783_IRQSTAT0_CHGCURRI	(1 << 11)
+#define MC13783_IRQSTAT0_BPONI		(1 << 12)
+#define MC13783_IRQSTAT0_LOBATLI	(1 << 13)
+#define MC13783_IRQSTAT0_LOBATHI	(1 << 14)
+#define MC13783_IRQSTAT0_UDPI		(1 << 15)
+#define MC13783_IRQSTAT0_USBI		(1 << 16)
+#define MC13783_IRQSTAT0_IDI		(1 << 19)
+#define MC13783_IRQSTAT0_SE1I		(1 << 21)
+#define MC13783_IRQSTAT0_CKDETI		(1 << 22)
+#define MC13783_IRQSTAT0_UDMI		(1 << 23)
 
-static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len)
+#define MC13783_IRQMASK0	1
+#define MC13783_IRQMASK0_ADCDONEM	MC13783_IRQSTAT0_ADCDONEI
+#define MC13783_IRQMASK0_ADCBISDONEM	MC13783_IRQSTAT0_ADCBISDONEI
+#define MC13783_IRQMASK0_TSM		MC13783_IRQSTAT0_TSI
+#define MC13783_IRQMASK0_WHIGHM		MC13783_IRQSTAT0_WHIGHI
+#define MC13783_IRQMASK0_WLOWM		MC13783_IRQSTAT0_WLOWI
+#define MC13783_IRQMASK0_CHGDETM	MC13783_IRQSTAT0_CHGDETI
+#define MC13783_IRQMASK0_CHGOVM		MC13783_IRQSTAT0_CHGOVI
+#define MC13783_IRQMASK0_CHGREVM	MC13783_IRQSTAT0_CHGREVI
+#define MC13783_IRQMASK0_CHGSHORTM	MC13783_IRQSTAT0_CHGSHORTI
+#define MC13783_IRQMASK0_CCCVM		MC13783_IRQSTAT0_CCCVI
+#define MC13783_IRQMASK0_CHGCURRM	MC13783_IRQSTAT0_CHGCURRI
+#define MC13783_IRQMASK0_BPONM		MC13783_IRQSTAT0_BPONI
+#define MC13783_IRQMASK0_LOBATLM	MC13783_IRQSTAT0_LOBATLI
+#define MC13783_IRQMASK0_LOBATHM	MC13783_IRQSTAT0_LOBATHI
+#define MC13783_IRQMASK0_UDPM		MC13783_IRQSTAT0_UDPI
+#define MC13783_IRQMASK0_USBM		MC13783_IRQSTAT0_USBI
+#define MC13783_IRQMASK0_IDM		MC13783_IRQSTAT0_IDI
+#define MC13783_IRQMASK0_SE1M		MC13783_IRQSTAT0_SE1I
+#define MC13783_IRQMASK0_CKDETM		MC13783_IRQSTAT0_CKDETI
+#define MC13783_IRQMASK0_UDMM		MC13783_IRQSTAT0_UDMI
+
+#define MC13783_IRQSTAT1	3
+#define MC13783_IRQSTAT1_1HZI		(1 << 0)
+#define MC13783_IRQSTAT1_TODAI		(1 << 1)
+#define MC13783_IRQSTAT1_ONOFD1I	(1 << 3)
+#define MC13783_IRQSTAT1_ONOFD2I	(1 << 4)
+#define MC13783_IRQSTAT1_ONOFD3I	(1 << 5)
+#define MC13783_IRQSTAT1_SYSRSTI	(1 << 6)
+#define MC13783_IRQSTAT1_RTCRSTI	(1 << 7)
+#define MC13783_IRQSTAT1_PCI		(1 << 8)
+#define MC13783_IRQSTAT1_WARMI		(1 << 9)
+#define MC13783_IRQSTAT1_MEMHLDI	(1 << 10)
+#define MC13783_IRQSTAT1_PWRRDYI	(1 << 11)
+#define MC13783_IRQSTAT1_THWARNLI	(1 << 12)
+#define MC13783_IRQSTAT1_THWARNHI	(1 << 13)
+#define MC13783_IRQSTAT1_CLKI		(1 << 14)
+#define MC13783_IRQSTAT1_SEMAFI		(1 << 15)
+#define MC13783_IRQSTAT1_MC2BI		(1 << 17)
+#define MC13783_IRQSTAT1_HSDETI		(1 << 18)
+#define MC13783_IRQSTAT1_HSLI		(1 << 19)
+#define MC13783_IRQSTAT1_ALSPTHI	(1 << 20)
+#define MC13783_IRQSTAT1_AHSSHORTI	(1 << 21)
+
+#define MC13783_IRQMASK1	4
+#define MC13783_IRQMASK1_1HZM		MC13783_IRQSTAT1_1HZI
+#define MC13783_IRQMASK1_TODAM		MC13783_IRQSTAT1_TODAI
+#define MC13783_IRQMASK1_ONOFD1M	MC13783_IRQSTAT1_ONOFD1I
+#define MC13783_IRQMASK1_ONOFD2M	MC13783_IRQSTAT1_ONOFD2I
+#define MC13783_IRQMASK1_ONOFD3M	MC13783_IRQSTAT1_ONOFD3I
+#define MC13783_IRQMASK1_SYSRSTM	MC13783_IRQSTAT1_SYSRSTI
+#define MC13783_IRQMASK1_RTCRSTM	MC13783_IRQSTAT1_RTCRSTI
+#define MC13783_IRQMASK1_PCM		MC13783_IRQSTAT1_PCI
+#define MC13783_IRQMASK1_WARMM		MC13783_IRQSTAT1_WARMI
+#define MC13783_IRQMASK1_MEMHLDM	MC13783_IRQSTAT1_MEMHLDI
+#define MC13783_IRQMASK1_PWRRDYM	MC13783_IRQSTAT1_PWRRDYI
+#define MC13783_IRQMASK1_THWARNLM	MC13783_IRQSTAT1_THWARNLI
+#define MC13783_IRQMASK1_THWARNHM	MC13783_IRQSTAT1_THWARNHI
+#define MC13783_IRQMASK1_CLKM		MC13783_IRQSTAT1_CLKI
+#define MC13783_IRQMASK1_SEMAFM		MC13783_IRQSTAT1_SEMAFI
+#define MC13783_IRQMASK1_MC2BM		MC13783_IRQSTAT1_MC2BI
+#define MC13783_IRQMASK1_HSDETM		MC13783_IRQSTAT1_HSDETI
+#define MC13783_IRQMASK1_HSLM		MC13783_IRQSTAT1_HSLI
+#define MC13783_IRQMASK1_ALSPTHM	MC13783_IRQSTAT1_ALSPTHI
+#define MC13783_IRQMASK1_AHSSHORTM	MC13783_IRQSTAT1_AHSSHORTI
+
+#define MC13783_ADC1		44
+#define MC13783_ADC1_ADEN		(1 << 0)
+#define MC13783_ADC1_RAND		(1 << 1)
+#define MC13783_ADC1_ADSEL		(1 << 3)
+#define MC13783_ADC1_ASC		(1 << 20)
+#define MC13783_ADC1_ADTRIGIGN		(1 << 21)
+
+#define MC13783_NUMREGS 0x3f
+
+void mc13783_lock(struct mc13783 *mc13783)
 {
-	struct spi_transfer t = {
-		.tx_buf = (const void *)buf,
-		.rx_buf = buf,
-		.len = len,
-		.cs_change = 0,
-		.delay_usecs = 0,
-	};
-	struct spi_message m;
+	if (!mutex_trylock(&mc13783->lock)) {
+		dev_dbg(&mc13783->spidev->dev, "wait for %s from %pf\n",
+				__func__, __builtin_return_address(0));
 
-	spi_message_init(&m);
-	spi_message_add_tail(&t, &m);
-	if (spi_sync(spi, &m) != 0 || m.status != 0)
-		return -EINVAL;
-	return len - m.actual_length;
+		mutex_lock(&mc13783->lock);
+	}
+	dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
+			__func__, __builtin_return_address(0));
 }
+EXPORT_SYMBOL(mc13783_lock);
 
-static int mc13783_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val)
+void mc13783_unlock(struct mc13783 *mc13783)
 {
-	unsigned int frame = 0;
-	int ret = 0;
+	dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
+			__func__, __builtin_return_address(0));
+	mutex_unlock(&mc13783->lock);
+}
+EXPORT_SYMBOL(mc13783_unlock);
 
-	if (reg_num > MC13783_MAX_REG_NUM)
+#define MC13783_REGOFFSET_SHIFT 25
+int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val)
+{
+	struct spi_transfer t;
+	struct spi_message m;
+	int ret;
+
+	BUG_ON(!mutex_is_locked(&mc13783->lock));
+
+	if (offset > MC13783_NUMREGS)
 		return -EINVAL;
 
-	frame |= reg_num << MC13783_REG_NUM_SHIFT;
+	*val = offset << MC13783_REGOFFSET_SHIFT;
 
-	ret = spi_rw(mc13783->spi_device, (u8 *)&frame, 4);
+	memset(&t, 0, sizeof(t));
 
-	*reg_val = frame & MC13783_FRAME_MASK;
+	t.tx_buf = val;
+	t.rx_buf = val;
+	t.len = sizeof(u32);
 
-	return ret;
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	ret = spi_sync(mc13783->spidev, &m);
+
+	/* error in message.status implies error return from spi_sync */
+	BUG_ON(!ret && m.status);
+
+	if (ret)
+		return ret;
+
+	*val &= 0xffffff;
+
+	dev_vdbg(&mc13783->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
+
+	return 0;
 }
+EXPORT_SYMBOL(mc13783_reg_read);
 
-static int mc13783_write(struct mc13783 *mc13783, int reg_num, u32 reg_val)
+int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val)
 {
-	unsigned int frame = 0;
+	u32 buf;
+	struct spi_transfer t;
+	struct spi_message m;
+	int ret;
 
-	if (reg_num > MC13783_MAX_REG_NUM)
+	BUG_ON(!mutex_is_locked(&mc13783->lock));
+
+	dev_vdbg(&mc13783->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val);
+
+	if (offset > MC13783_NUMREGS || val > 0xffffff)
 		return -EINVAL;
 
-	frame |= (1 << MC13783_WRITE_BIT_SHIFT);
-	frame |= reg_num << MC13783_REG_NUM_SHIFT;
-	frame |= reg_val & MC13783_FRAME_MASK;
+	buf = 1 << 31 | offset << MC13783_REGOFFSET_SHIFT | val;
 
-	return spi_rw(mc13783->spi_device, (u8 *)&frame, 4);
+	memset(&t, 0, sizeof(t));
+
+	t.tx_buf = &buf;
+	t.rx_buf = &buf;
+	t.len = sizeof(u32);
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	ret = spi_sync(mc13783->spidev, &m);
+
+	BUG_ON(!ret && m.status);
+
+	if (ret)
+		return ret;
+
+	return 0;
 }
+EXPORT_SYMBOL(mc13783_reg_write);
 
-int mc13783_reg_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val)
+int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
+		u32 mask, u32 val)
 {
 	int ret;
+	u32 valread;
 
-	mutex_lock(&mc13783->io_lock);
-	ret = mc13783_read(mc13783, reg_num, reg_val);
-	mutex_unlock(&mc13783->io_lock);
+	BUG_ON(val & ~mask);
 
-	return ret;
+	ret = mc13783_reg_read(mc13783, offset, &valread);
+	if (ret)
+		return ret;
+
+	valread = (valread & ~mask) | val;
+
+	return mc13783_reg_write(mc13783, offset, valread);
 }
-EXPORT_SYMBOL_GPL(mc13783_reg_read);
+EXPORT_SYMBOL(mc13783_reg_rmw);
 
-int mc13783_reg_write(struct mc13783 *mc13783, int reg_num, u32 reg_val)
+int mc13783_mask(struct mc13783 *mc13783, int irq)
 {
 	int ret;
+	unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
+	u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
+	u32 mask;
 
-	mutex_lock(&mc13783->io_lock);
-	ret = mc13783_write(mc13783, reg_num, reg_val);
-	mutex_unlock(&mc13783->io_lock);
+	if (irq < 0 || irq >= MC13783_NUM_IRQ)
+		return -EINVAL;
 
-	return ret;
+	ret = mc13783_reg_read(mc13783, offmask, &mask);
+	if (ret)
+		return ret;
+
+	if (mask & irqbit)
+		/* already masked */
+		return 0;
+
+	return mc13783_reg_write(mc13783, offmask, mask | irqbit);
 }
-EXPORT_SYMBOL_GPL(mc13783_reg_write);
+EXPORT_SYMBOL(mc13783_mask);
 
-/**
- * mc13783_set_bits - Bitmask write
- *
- * @mc13783: Pointer to mc13783 control structure
- * @reg:    Register to access
- * @mask:   Mask of bits to change
- * @val:    Value to set for masked bits
- */
-int mc13783_set_bits(struct mc13783 *mc13783, int reg, u32 mask, u32 val)
+int mc13783_unmask(struct mc13783 *mc13783, int irq)
 {
-	u32 tmp;
 	int ret;
+	unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
+	u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
+	u32 mask;
 
-	mutex_lock(&mc13783->io_lock);
+	if (irq < 0 || irq >= MC13783_NUM_IRQ)
+		return -EINVAL;
 
-	ret = mc13783_read(mc13783, reg, &tmp);
-	tmp = (tmp & ~mask) | val;
-	if (ret == 0)
-		ret = mc13783_write(mc13783, reg, tmp);
+	ret = mc13783_reg_read(mc13783, offmask, &mask);
+	if (ret)
+		return ret;
 
-	mutex_unlock(&mc13783->io_lock);
+	if (!(mask & irqbit))
+		/* already unmasked */
+		return 0;
 
-	return ret;
+	return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
 }
-EXPORT_SYMBOL_GPL(mc13783_set_bits);
+EXPORT_SYMBOL(mc13783_unmask);
 
-int mc13783_register_irq(struct mc13783 *mc13783, int irq,
-		void (*handler) (int, void *), void *data)
+int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
+		irq_handler_t handler, const char *name, void *dev)
 {
-	if (irq < 0 || irq > MC13783_NUM_IRQ || !handler)
+	BUG_ON(!mutex_is_locked(&mc13783->lock));
+	BUG_ON(!handler);
+
+	if (irq < 0 || irq >= MC13783_NUM_IRQ)
 		return -EINVAL;
 
-	if (WARN_ON(mc13783->irq_handler[irq].handler))
+	if (mc13783->irqhandler[irq])
 		return -EBUSY;
 
-	mutex_lock(&mc13783->io_lock);
-	mc13783->irq_handler[irq].handler = handler;
-	mc13783->irq_handler[irq].data = data;
-	mutex_unlock(&mc13783->io_lock);
+	mc13783->irqhandler[irq] = handler;
+	mc13783->irqdata[irq] = dev;
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(mc13783_register_irq);
+EXPORT_SYMBOL(mc13783_irq_request_nounmask);
 
-int mc13783_free_irq(struct mc13783 *mc13783, int irq)
+int mc13783_irq_request(struct mc13783 *mc13783, int irq,
+		irq_handler_t handler, const char *name, void *dev)
 {
-	if (irq < 0 || irq > MC13783_NUM_IRQ)
+	int ret;
+
+	ret = mc13783_irq_request_nounmask(mc13783, irq, handler, name, dev);
+	if (ret)
+		return ret;
+
+	ret = mc13783_unmask(mc13783, irq);
+	if (ret) {
+		mc13783->irqhandler[irq] = NULL;
+		mc13783->irqdata[irq] = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mc13783_irq_request);
+
+int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
+{
+	int ret;
+	BUG_ON(!mutex_is_locked(&mc13783->lock));
+
+	if (irq < 0 || irq >= MC13783_NUM_IRQ || !mc13783->irqhandler[irq] ||
+			mc13783->irqdata[irq] != dev)
 		return -EINVAL;
 
-	mutex_lock(&mc13783->io_lock);
-	mc13783->irq_handler[irq].handler = NULL;
-	mutex_unlock(&mc13783->io_lock);
+	ret = mc13783_mask(mc13783, irq);
+	if (ret)
+		return ret;
+
+	mc13783->irqhandler[irq] = NULL;
+	mc13783->irqdata[irq] = NULL;
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(mc13783_free_irq);
+EXPORT_SYMBOL(mc13783_irq_free);
 
-static void mc13783_irq_work(struct work_struct *work)
+static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
 {
-	struct mc13783 *mc13783 = container_of(work, struct mc13783, work);
-	int i;
-	unsigned int adc_sts;
+	return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
+}
 
-	/* check if the adc has finished any completion */
-	mc13783_reg_read(mc13783, MC13783_REG_INTERRUPT_STATUS_0, &adc_sts);
-	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0,
-			adc_sts & MC13783_INT_STAT_ADCDONEI);
+int mc13783_ackirq(struct mc13783 *mc13783, int irq)
+{
+	unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
+	unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
 
-	if (adc_sts & MC13783_INT_STAT_ADCDONEI)
-		complete_all(&mc13783->adc_done);
+	BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
 
-	for (i = 0; i < MC13783_NUM_IRQ; i++)
-		if (mc13783->irq_handler[i].handler)
-			mc13783->irq_handler[i].handler(i,
-					mc13783->irq_handler[i].data);
-	enable_irq(mc13783->irq);
+	return mc13783_reg_write(mc13783, offstat, val);
 }
+EXPORT_SYMBOL(mc13783_ackirq);
 
-static irqreturn_t mc13783_interrupt(int irq, void *dev_id)
+/*
+ * returns: number of handled irqs or negative error
+ * locking: holds mc13783->lock
+ */
+static int mc13783_irq_handle(struct mc13783 *mc13783,
+		unsigned int offstat, unsigned int offmask, int baseirq)
 {
-	struct mc13783 *mc13783 = dev_id;
+	u32 stat, mask;
+	int ret = mc13783_reg_read(mc13783, offstat, &stat);
+	int num_handled = 0;
 
-	disable_irq_nosync(irq);
+	if (ret)
+		return ret;
 
-	schedule_work(&mc13783->work);
-	return IRQ_HANDLED;
+	ret = mc13783_reg_read(mc13783, offmask, &mask);
+	if (ret)
+		return ret;
+
+	while (stat & ~mask) {
+		int irq = __ffs(stat & ~mask);
+
+		stat &= ~(1 << irq);
+
+		if (likely(mc13783->irqhandler[baseirq + irq])) {
+			irqreturn_t handled;
+
+			handled = mc13783_irqhandler(mc13783, baseirq + irq);
+			if (handled == IRQ_HANDLED)
+				num_handled++;
+		} else {
+			dev_err(&mc13783->spidev->dev,
+					"BUG: irq %u but no handler\n",
+					baseirq + irq);
+
+			mask |= 1 << irq;
+
+			ret = mc13783_reg_write(mc13783, offmask, mask);
+		}
+	}
+
+	return num_handled;
 }
 
-/* set adc to ts interrupt mode, which generates touchscreen wakeup interrupt */
-static inline void mc13783_adc_set_ts_irq_mode(struct mc13783 *mc13783)
+static irqreturn_t mc13783_irq_thread(int irq, void *data)
 {
-	unsigned int reg_adc0, reg_adc1;
+	struct mc13783 *mc13783 = data;
+	irqreturn_t ret;
+	int handled = 0;
 
-	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
-			| MC13783_ADC0_TSMOD0;
-	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN;
+	mc13783_lock(mc13783);
 
-	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0);
-	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1);
+	ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT0,
+			MC13783_IRQMASK0, MC13783_IRQ_ADCDONE);
+	if (ret > 0)
+		handled = 1;
+
+	ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT1,
+			MC13783_IRQMASK1, MC13783_IRQ_1HZ);
+	if (ret > 0)
+		handled = 1;
+
+	mc13783_unlock(mc13783);
+
+	return IRQ_RETVAL(handled);
+}
+
+#define MC13783_ADC1_CHAN0_SHIFT	5
+#define MC13783_ADC1_CHAN1_SHIFT	8
+
+struct mc13783_adcdone_data {
+	struct mc13783 *mc13783;
+	struct completion done;
+};
+
+static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
+{
+	struct mc13783_adcdone_data *adcdone_data = data;
+
+	mc13783_ackirq(adcdone_data->mc13783, irq);
+
+	complete_all(&adcdone_data->done);
+
+	return IRQ_HANDLED;
 }
 
+#define MC13783_ADC_WORKING (1 << 16)
+
 int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
 		unsigned int channel, unsigned int *sample)
 {
-	unsigned int reg_adc0, reg_adc1;
-	int i;
+	u32 adc0, adc1, old_adc0;
+	int i, ret;
+	struct mc13783_adcdone_data adcdone_data = {
+		.mc13783 = mc13783,
+	};
+	init_completion(&adcdone_data.done);
 
-	mutex_lock(&mc13783->adc_conv_lock);
+	dev_dbg(&mc13783->spidev->dev, "%s\n", __func__);
 
-	/* set up auto incrementing anyway to make quick read */
-	reg_adc0 =  MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
-	/* enable the adc, ignore external triggering and set ASC to trigger
-	 * conversion */
-	reg_adc1 =  MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN
-		| MC13783_ADC1_ASC;
+	mc13783_lock(mc13783);
+
+	if (mc13783->flags & MC13783_ADC_WORKING) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	mc13783->flags |= MC13783_ADC_WORKING;
+
+	mc13783_reg_read(mc13783, MC13783_ADC0, &old_adc0);
+
+	adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
+	adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
 
-	/* setup channel number */
 	if (channel > 7)
-		reg_adc1 |= MC13783_ADC1_ADSEL;
+		adc1 |= MC13783_ADC1_ADSEL;
 
 	switch (mode) {
 	case MC13783_ADC_MODE_TS:
-		/* enables touch screen reference mode and set touchscreen mode
-		 * to position mode */
-		reg_adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
-			| MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1;
-		reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
+		adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 |
+			MC13783_ADC0_TSMOD1;
+		adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
 		break;
+
 	case MC13783_ADC_MODE_SINGLE_CHAN:
-		reg_adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
-		reg_adc1 |= MC13783_ADC1_RAND;
+		adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
+		adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
+		adc1 |= MC13783_ADC1_RAND;
 		break;
+
 	case MC13783_ADC_MODE_MULT_CHAN:
-		reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
+		adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
+		adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
 		break;
+
 	default:
+		mc13783_unlock(mc13783);
 		return -EINVAL;
 	}
 
-	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0);
-	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1);
+	dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
+	mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
+			mc13783_handler_adcdone, __func__, &adcdone_data);
+	mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE);
 
-	wait_for_completion_interruptible(&mc13783->adc_done);
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
 
-	for (i = 0; i < 4; i++)
-		mc13783_reg_read(mc13783, MC13783_REG_ADC_2, &sample[i]);
+	mc13783_unlock(mc13783);
 
-	if (mc13783->ts_active)
-		mc13783_adc_set_ts_irq_mode(mc13783);
+	ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ);
 
-	mutex_unlock(&mc13783->adc_conv_lock);
+	if (!ret)
+		ret = -ETIMEDOUT;
 
-	return 0;
+	mc13783_lock(mc13783);
+
+	mc13783_irq_free(mc13783, MC13783_IRQ_ADCDONE, &adcdone_data);
+
+	if (ret > 0)
+		for (i = 0; i < 4; ++i) {
+			ret = mc13783_reg_read(mc13783,
+					MC13783_REG_ADC_2, &sample[i]);
+			if (ret)
+				break;
+		}
+
+	if (mode == MC13783_ADC_MODE_TS)
+		/* restore TSMOD */
+		mc13783_reg_write(mc13783, MC13783_REG_ADC_0, old_adc0);
+
+	mc13783->flags &= ~MC13783_ADC_WORKING;
+out:
+	mc13783_unlock(mc13783);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
 
-void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status)
+static int mc13783_add_subdevice_pdata(struct mc13783 *mc13783,
+		const char *name, void *pdata, size_t pdata_size)
 {
-	mc13783->ts_active = status;
+	struct mfd_cell cell = {
+		.name = name,
+		.platform_data = pdata,
+		.data_size = pdata_size,
+	};
+
+	return mfd_add_devices(&mc13783->spidev->dev, -1, &cell, 1, NULL, 0);
+}
+
+static int mc13783_add_subdevice(struct mc13783 *mc13783, const char *name)
+{
+	return mc13783_add_subdevice_pdata(mc13783, name, NULL, 0);
 }
-EXPORT_SYMBOL_GPL(mc13783_adc_set_ts_status);
 
 static int mc13783_check_revision(struct mc13783 *mc13783)
 {
 	u32 rev_id, rev1, rev2, finid, icid;
 
-	mc13783_read(mc13783, MC13783_REG_REVISION, &rev_id);
+	mc13783_reg_read(mc13783, MC13783_REG_REVISION, &rev_id);
 
 	rev1 = (rev_id & 0x018) >> 3;
 	rev2 = (rev_id & 0x007);
@@ -292,38 +555,24 @@ static int mc13783_check_revision(struct
 		rev1 = 3;
 
 	if (rev1 == 0 || icid != 2) {
-		dev_err(mc13783->dev, "No MC13783 detected.\n");
+		dev_err(&mc13783->spidev->dev, "No MC13783 detected.\n");
 		return -ENODEV;
 	}
 
-	mc13783->revision = ((rev1 * 10) + rev2);
-	dev_info(mc13783->dev, "MC13783 Rev %d.%d FinVer %x detected\n", rev1,
-	       rev2, finid);
+	dev_info(&mc13783->spidev->dev,
+			"MC13783 Rev %d.%d FinVer %x detected\n",
+			rev1, rev2, finid);
 
 	return 0;
 }
 
-/*
- * Register a client device.  This is non-fatal since there is no need to
- * fail the entire device init due to a single platform device failing.
- */
-static void mc13783_client_dev_register(struct mc13783 *mc13783,
-				       const char *name)
-{
-	struct mfd_cell cell = {};
-
-	cell.name = name;
-
-	mfd_add_devices(mc13783->dev, -1, &cell, 1, NULL, 0);
-}
-
-static int __devinit mc13783_probe(struct spi_device *spi)
+static int mc13783_probe(struct spi_device *spi)
 {
 	struct mc13783 *mc13783;
-	struct mc13783_platform_data *pdata = spi->dev.platform_data;
+	struct mc13783_platform_data *pdata = dev_get_platdata(&spi->dev);
 	int ret;
 
-	mc13783 = kzalloc(sizeof(struct mc13783), GFP_KERNEL);
+	mc13783 = kzalloc(sizeof(*mc13783), GFP_KERNEL);
 	if (!mc13783)
 		return -ENOMEM;
 
@@ -332,96 +581,104 @@ static int __devinit mc13783_probe(struc
 	spi->bits_per_word = 32;
 	spi_setup(spi);
 
-	mc13783->spi_device = spi;
-	mc13783->dev = &spi->dev;
-	mc13783->irq = spi->irq;
+	mc13783->spidev = spi;
 
-	INIT_WORK(&mc13783->work, mc13783_irq_work);
-	mutex_init(&mc13783->io_lock);
-	mutex_init(&mc13783->adc_conv_lock);
-	init_completion(&mc13783->adc_done);
+	mutex_init(&mc13783->lock);
+	mc13783_lock(mc13783);
 
+	ret = mc13783_check_revision(mc13783);
+	if (ret)
+		goto err_revision;
+
+	/* mask all irqs */
+	ret = mc13783_reg_write(mc13783, MC13783_IRQMASK0, 0x00ffffff);
+	if (ret)
+		goto err_mask;
+
+	ret = mc13783_reg_write(mc13783, MC13783_IRQMASK1, 0x00ffffff);
+	if (ret)
+		goto err_mask;
+
+	ret = request_threaded_irq(spi->irq, NULL, mc13783_irq_thread,
+			IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13783", mc13783);
+
+	if (ret) {
+err_mask:
+err_revision:
+		mutex_unlock(&mc13783->lock);
+		dev_set_drvdata(&spi->dev, NULL);
+		kfree(mc13783);
+		return ret;
+	}
+
+	/* This should go away (BEGIN) */
 	if (pdata) {
 		mc13783->flags = pdata->flags;
 		mc13783->regulators = pdata->regulators;
 		mc13783->num_regulators = pdata->num_regulators;
 	}
+	/* This should go away (END) */
 
-	if (mc13783_check_revision(mc13783)) {
-		ret = -ENODEV;
-		goto err_out;
-	}
+	mc13783_unlock(mc13783);
 
-	/* clear and mask all interrupts */
-	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0, 0x00ffffff);
-	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_0, 0x00ffffff);
-	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_1, 0x00ffffff);
-	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_1, 0x00ffffff);
+	if (pdata->flags & MC13783_USE_ADC)
+		mc13783_add_subdevice(mc13783, "mc13783-adc");
 
-	/* unmask adcdone interrupts */
-	mc13783_set_bits(mc13783, MC13783_REG_INTERRUPT_MASK_0,
-			MC13783_INT_MASK_ADCDONEM, 0);
+	if (pdata->flags & MC13783_USE_CODEC)
+		mc13783_add_subdevice(mc13783, "mc13783-codec");
 
-	ret = request_irq(mc13783->irq, mc13783_interrupt,
-			IRQF_DISABLED | IRQF_TRIGGER_HIGH, "mc13783",
-			mc13783);
-	if (ret)
-		goto err_out;
+	if (pdata->flags & MC13783_USE_REGULATOR) {
+		struct mc13783_regulator_platform_data regulator_pdata = {
+			.num_regulators = pdata->num_regulators,
+			.regulators = pdata->regulators,
+		};
 
-	if (mc13783->flags & MC13783_USE_CODEC)
-		mc13783_client_dev_register(mc13783, "mc13783-codec");
-	if (mc13783->flags & MC13783_USE_ADC)
-		mc13783_client_dev_register(mc13783, "mc13783-adc");
-	if (mc13783->flags & MC13783_USE_RTC)
-		mc13783_client_dev_register(mc13783, "mc13783-rtc");
-	if (mc13783->flags & MC13783_USE_REGULATOR)
-		mc13783_client_dev_register(mc13783, "mc13783-regulator");
-	if (mc13783->flags & MC13783_USE_TOUCHSCREEN)
-		mc13783_client_dev_register(mc13783, "mc13783-ts");
+		mc13783_add_subdevice_pdata(mc13783, "mc13783-regulator",
+				&regulator_pdata, sizeof(regulator_pdata));
+	}
 
-	return 0;
+	if (pdata->flags & MC13783_USE_RTC)
+		mc13783_add_subdevice(mc13783, "mc13783-rtc");
 
-err_out:
-	kfree(mc13783);
-	return ret;
+	if (pdata->flags & MC13783_USE_TOUCHSCREEN)
+		mc13783_add_subdevice(mc13783, "mc13783-ts");
+
+	return 0;
 }
 
 static int __devexit mc13783_remove(struct spi_device *spi)
 {
-	struct mc13783 *mc13783;
-
-	mc13783 = dev_get_drvdata(&spi->dev);
+	struct mc13783 *mc13783 = dev_get_drvdata(&spi->dev);
 
-	free_irq(mc13783->irq, mc13783);
+	free_irq(mc13783->spidev->irq, mc13783);
 
 	mfd_remove_devices(&spi->dev);
 
 	return 0;
 }
 
-static struct spi_driver pmic_driver = {
+static struct spi_driver mc13783_driver = {
 	.driver = {
-		   .name = "mc13783",
-		   .bus = &spi_bus_type,
-		   .owner = THIS_MODULE,
+		.name = "mc13783",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
 	},
 	.probe = mc13783_probe,
 	.remove = __devexit_p(mc13783_remove),
 };
 
-static int __init pmic_init(void)
+static int __init mc13783_init(void)
 {
-	return spi_register_driver(&pmic_driver);
+	return spi_register_driver(&mc13783_driver);
 }
-subsys_initcall(pmic_init);
+subsys_initcall(mc13783_init);
 
-static void __exit pmic_exit(void)
+static void __exit mc13783_exit(void)
 {
-	spi_unregister_driver(&pmic_driver);
+	spi_unregister_driver(&mc13783_driver);
 }
-module_exit(pmic_exit);
-
-MODULE_DESCRIPTION("Core/Protocol driver for Freescale MC13783 PMIC");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_LICENSE("GPL");
+module_exit(mc13783_exit);
 
+MODULE_DESCRIPTION("Core driver for Freescale MC13783 PMIC");
+MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/mcp-core.c linux-libre-2.6.33-gnu1/drivers/mfd/mcp-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/mcp-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/mcp-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,11 +17,11 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/mfd/mcp.h>
 
 #include <mach/dma.h>
 #include <asm/system.h>
 
-#include "mcp.h"
 
 #define to_mcp(d)		container_of(d, struct mcp, attached_device)
 #define to_mcp_driver(d)	container_of(d, struct mcp_driver, drv)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/mcp.h linux-libre-2.6.33-gnu1/drivers/mfd/mcp.h
--- linux-libre-2.6.32-gnu1/drivers/mfd/mcp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/mcp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,66 +0,0 @@
-/*
- *  linux/drivers/mfd/mcp.h
- *
- *  Copyright (C) 2001 Russell King, 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.
- */
-#ifndef MCP_H
-#define MCP_H
-
-struct mcp_ops;
-
-struct mcp {
-	struct module	*owner;
-	struct mcp_ops	*ops;
-	spinlock_t	lock;
-	int		use_count;
-	unsigned int	sclk_rate;
-	unsigned int	rw_timeout;
-	dma_device_t	dma_audio_rd;
-	dma_device_t	dma_audio_wr;
-	dma_device_t	dma_telco_rd;
-	dma_device_t	dma_telco_wr;
-	struct device	attached_device;
-};
-
-struct mcp_ops {
-	void		(*set_telecom_divisor)(struct mcp *, unsigned int);
-	void		(*set_audio_divisor)(struct mcp *, unsigned int);
-	void		(*reg_write)(struct mcp *, unsigned int, unsigned int);
-	unsigned int	(*reg_read)(struct mcp *, unsigned int);
-	void		(*enable)(struct mcp *);
-	void		(*disable)(struct mcp *);
-};
-
-void mcp_set_telecom_divisor(struct mcp *, unsigned int);
-void mcp_set_audio_divisor(struct mcp *, unsigned int);
-void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
-unsigned int mcp_reg_read(struct mcp *, unsigned int);
-void mcp_enable(struct mcp *);
-void mcp_disable(struct mcp *);
-#define mcp_get_sclk_rate(mcp)	((mcp)->sclk_rate)
-
-struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *);
-void mcp_host_unregister(struct mcp *);
-
-struct mcp_driver {
-	struct device_driver drv;
-	int (*probe)(struct mcp *);
-	void (*remove)(struct mcp *);
-	int (*suspend)(struct mcp *, pm_message_t);
-	int (*resume)(struct mcp *);
-};
-
-int mcp_driver_register(struct mcp_driver *);
-void mcp_driver_unregister(struct mcp_driver *);
-
-#define mcp_get_drvdata(mcp)	dev_get_drvdata(&(mcp)->attached_device)
-#define mcp_set_drvdata(mcp,d)	dev_set_drvdata(&(mcp)->attached_device, d)
-
-#define mcp_priv(mcp)		((void *)((mcp)+1))
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/mcp-sa11x0.c linux-libre-2.6.33-gnu1/drivers/mfd/mcp-sa11x0.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/mcp-sa11x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/mcp-sa11x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/mcp.h>
 
 #include <mach/dma.h>
 #include <mach/hardware.h>
@@ -28,7 +29,6 @@
 
 #include <mach/assabet.h>
 
-#include "mcp.h"
 
 struct mcp_sa11x0 {
 	u32	mccr0;
@@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platf
 	mcp->dma_audio_wr	= DMA_Ser4MCP0Wr;
 	mcp->dma_telco_rd	= DMA_Ser4MCP1Rd;
 	mcp->dma_telco_wr	= DMA_Ser4MCP1Wr;
+	mcp->gpio_base		= data->gpio_base;
 
 	platform_set_drvdata(pdev, mcp);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/menelaus.c linux-libre-2.6.33-gnu1/drivers/mfd/menelaus.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/menelaus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/menelaus.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/gpio.h>
-#include <mach/menelaus.h>
+#include <plat/menelaus.h>
 
 #define DRIVER_NAME			"menelaus"
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/pcf50633-adc.c linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-adc.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/pcf50633-adc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-adc.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,17 +209,16 @@ static void pcf50633_adc_irq(int irq, vo
 
 static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
 {
-	struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
 	struct pcf50633_adc *adc;
 
 	adc = kzalloc(sizeof(*adc), GFP_KERNEL);
 	if (!adc)
 		return -ENOMEM;
 
-	adc->pcf = pdata->pcf;
+	adc->pcf = dev_to_pcf50633(pdev->dev.parent);
 	platform_set_drvdata(pdev, adc);
 
-	pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ADCRDY,
+	pcf50633_register_irq(adc->pcf, PCF50633_IRQ_ADCRDY,
 					pcf50633_adc_irq, adc);
 
 	mutex_init(&adc->queue_mutex);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/pcf50633-core.c linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/pcf50633-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/pcf50633-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -290,7 +290,7 @@ out:
 
 int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
 {
-	dev_info(pcf->dev, "Masking IRQ %d\n", irq);
+	dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
 
 	return __pcf50633_irq_mask_set(pcf, irq, 1);
 }
@@ -298,7 +298,7 @@ EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
 
 int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
 {
-	dev_info(pcf->dev, "Unmasking IRQ %d\n", irq);
+	dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
 
 	return __pcf50633_irq_mask_set(pcf, irq, 0);
 }
@@ -345,6 +345,9 @@ static void pcf50633_irq_worker(struct w
 		goto out;
 	}
 
+	/* defeat 8s death from lowsys on A5 */
+	pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN,  0x04);
+
 	/* We immediately read the usb and adapter status. We thus make sure
 	 * only of USBINS/USBREM IRQ handlers are called */
 	if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
@@ -453,7 +456,6 @@ static void
 pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
 						struct platform_device **pdev)
 {
-	struct pcf50633_subdev_pdata *subdev_pdata;
 	int ret;
 
 	*pdev = platform_device_alloc(name, -1);
@@ -462,15 +464,6 @@ pcf50633_client_dev_register(struct pcf5
 		return;
 	}
 
-	subdev_pdata = kmalloc(sizeof(*subdev_pdata), GFP_KERNEL);
-	if (!subdev_pdata) {
-		dev_err(pcf->dev, "Error allocating subdev pdata\n");
-		platform_device_put(*pdev);
-	}
-
-	subdev_pdata->pcf = pcf;
-	platform_device_add_data(*pdev, subdev_pdata, sizeof(*subdev_pdata));
-
 	(*pdev)->dev.parent = pcf->dev;
 
 	ret = platform_device_add(*pdev);
@@ -482,13 +475,13 @@ pcf50633_client_dev_register(struct pcf5
 }
 
 #ifdef CONFIG_PM
-static int pcf50633_suspend(struct device *dev, pm_message_t state)
+static int pcf50633_suspend(struct i2c_client *client, pm_message_t state)
 {
 	struct pcf50633 *pcf;
 	int ret = 0, i;
 	u8 res[5];
 
-	pcf = dev_get_drvdata(dev);
+	pcf = i2c_get_clientdata(client);
 
 	/* Make sure our interrupt handlers are not called
 	 * henceforth */
@@ -523,12 +516,12 @@ out:
 	return ret;
 }
 
-static int pcf50633_resume(struct device *dev)
+static int pcf50633_resume(struct i2c_client *client)
 {
 	struct pcf50633 *pcf;
 	int ret;
 
-	pcf = dev_get_drvdata(dev);
+	pcf = i2c_get_clientdata(client);
 
 	/* Write the saved mask registers */
 	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
@@ -560,9 +553,14 @@ static int __devinit pcf50633_probe(stru
 {
 	struct pcf50633 *pcf;
 	struct pcf50633_platform_data *pdata = client->dev.platform_data;
-	int i, ret = 0;
+	int i, ret;
 	int version, variant;
 
+	if (!client->irq) {
+		dev_err(&client->dev, "Missing IRQ\n");
+		return -ENOENT;
+	}
+
 	pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
 	if (!pcf)
 		return -ENOMEM;
@@ -577,6 +575,12 @@ static int __devinit pcf50633_probe(stru
 	pcf->irq = client->irq;
 	pcf->work_queue = create_singlethread_workqueue("pcf50633");
 
+	if (!pcf->work_queue) {
+		dev_err(&client->dev, "Failed to alloc workqueue\n");
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
 	INIT_WORK(&pcf->irq_work, pcf50633_irq_worker);
 
 	version = pcf50633_reg_read(pcf, 0);
@@ -584,7 +588,7 @@ static int __devinit pcf50633_probe(stru
 	if (version < 0 || variant < 0) {
 		dev_err(pcf->dev, "Unable to probe pcf50633\n");
 		ret = -ENODEV;
-		goto err;
+		goto err_destroy_workqueue;
 	}
 
 	dev_info(pcf->dev, "Probed device version %d variant %d\n",
@@ -598,6 +602,14 @@ static int __devinit pcf50633_probe(stru
 	pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
 	pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
 
+	ret = request_irq(client->irq, pcf50633_irq,
+					IRQF_TRIGGER_LOW, "pcf50633", pcf);
+
+	if (ret) {
+		dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
+		goto err_destroy_workqueue;
+	}
+
 	/* Create sub devices */
 	pcf50633_client_dev_register(pcf, "pcf50633-input",
 						&pcf->input_pdev);
@@ -613,31 +625,18 @@ static int __devinit pcf50633_probe(stru
 
 		pdev = platform_device_alloc("pcf50633-regltr", i);
 		if (!pdev) {
-			dev_err(pcf->dev, "Cannot create regulator\n");
+			dev_err(pcf->dev, "Cannot create regulator %d\n", i);
 			continue;
 		}
 
 		pdev->dev.parent = pcf->dev;
-		pdev->dev.platform_data = &pdata->reg_init_data[i];
-		dev_set_drvdata(&pdev->dev, pcf);
+		platform_device_add_data(pdev, &pdata->reg_init_data[i],
+					sizeof(pdata->reg_init_data[i]));
 		pcf->regulator_pdev[i] = pdev;
 
 		platform_device_add(pdev);
 	}
 
-	if (client->irq) {
-		ret = request_irq(client->irq, pcf50633_irq,
-				IRQF_TRIGGER_LOW, "pcf50633", pcf);
-
-		if (ret) {
-			dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
-			goto err;
-		}
-	} else {
-		dev_err(pcf->dev, "No IRQ configured\n");
-		goto err;
-	}
-
 	if (enable_irq_wake(client->irq) < 0)
 		dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
 			"in this hardware revision", client->irq);
@@ -651,9 +650,12 @@ static int __devinit pcf50633_probe(stru
 
 	return 0;
 
-err:
+err_destroy_workqueue:
 	destroy_workqueue(pcf->work_queue);
+err_free:
+	i2c_set_clientdata(client, NULL);
 	kfree(pcf);
+
 	return ret;
 }
 
@@ -686,12 +688,12 @@ static struct i2c_device_id pcf50633_id_
 static struct i2c_driver pcf50633_driver = {
 	.driver = {
 		.name	= "pcf50633",
-		.suspend = pcf50633_suspend,
-		.resume	= pcf50633_resume,
 	},
 	.id_table = pcf50633_id_table,
 	.probe = pcf50633_probe,
 	.remove = __devexit_p(pcf50633_remove),
+	.suspend = pcf50633_suspend,
+	.resume	= pcf50633_resume,
 };
 
 static int __init pcf50633_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/sh_mobile_sdhi.c linux-libre-2.6.33-gnu1/drivers/mfd/sh_mobile_sdhi.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/sh_mobile_sdhi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/sh_mobile_sdhi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,156 @@
+/*
+ * SuperH Mobile SDHI
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This 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 "Compaq ASIC3 support":
+ *
+ * Copyright 2001 Compaq Computer Corporation.
+ * Copyright 2004-2005 Phil Blundell
+ * Copyright 2007-2008 OpenedHand Ltd.
+ *
+ * Authors: Phil Blundell <pb@handhelds.org>,
+ *	    Samuel Ortiz <sameo@openedhand.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
+
+struct sh_mobile_sdhi {
+	struct clk *clk;
+	struct tmio_mmc_data mmc_data;
+	struct mfd_cell cell_mmc;
+};
+
+static struct resource sh_mobile_sdhi_resources[] = {
+	{
+		.start = 0x000,
+		.end   = 0x1ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0,
+		.end   = 0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell sh_mobile_sdhi_cell = {
+	.name          = "tmio-mmc",
+	.num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
+	.resources     = sh_mobile_sdhi_resources,
+};
+
+static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
+{
+	struct platform_device *pdev = to_platform_device(tmio->dev.parent);
+	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+
+	if (p && p->set_pwr)
+		p->set_pwr(pdev, state);
+}
+
+static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
+{
+	struct sh_mobile_sdhi *priv;
+	struct resource *mem;
+	char clk_name[8];
+	int ret, irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		dev_err(&pdev->dev, "missing MEM resource\n");
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		dev_err(&pdev->dev, "missing IRQ resource\n");
+
+	if (!mem || (irq < 0))
+		return -EINVAL;
+
+	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
+	if (priv == NULL) {
+		dev_err(&pdev->dev, "kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
+	priv->clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+		ret = PTR_ERR(priv->clk);
+		kfree(priv);
+		return ret;
+	}
+
+	clk_enable(priv->clk);
+
+	/* FIXME: silly const unsigned int hclk */
+	*(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
+	priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
+
+	memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
+	priv->cell_mmc.driver_data = &priv->mmc_data;
+	priv->cell_mmc.platform_data = &priv->cell_mmc;
+	priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = mfd_add_devices(&pdev->dev, pdev->id,
+			      &priv->cell_mmc, 1, mem, irq);
+	if (ret) {
+		clk_disable(priv->clk);
+		clk_put(priv->clk);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+{
+	struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
+
+	mfd_remove_devices(&pdev->dev);
+	clk_disable(priv->clk);
+	clk_put(priv->clk);
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver sh_mobile_sdhi_driver = {
+	.driver		= {
+		.name	= "sh_mobile_sdhi",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sh_mobile_sdhi_probe,
+	.remove		= __devexit_p(sh_mobile_sdhi_remove),
+};
+
+static int __init sh_mobile_sdhi_init(void)
+{
+	return platform_driver_register(&sh_mobile_sdhi_driver);
+}
+
+static void __exit sh_mobile_sdhi_exit(void)
+{
+	platform_driver_unregister(&sh_mobile_sdhi_driver);
+}
+
+module_init(sh_mobile_sdhi_init);
+module_exit(sh_mobile_sdhi_exit);
+
+MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/t7l66xb.c linux-libre-2.6.33-gnu1/drivers/mfd/t7l66xb.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/t7l66xb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/t7l66xb.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,19 @@ enum {
 	T7L66XB_CELL_MMC,
 };
 
+static const struct resource t7l66xb_mmc_resources[] = {
+	{
+		.start = 0x800,
+		.end	= 0x9ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_T7L66XB_MMC,
+		.end	= IRQ_T7L66XB_MMC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
 #define SCR_REVID	0x08		/* b Revision ID	*/
 #define SCR_IMR		0x42		/* b Interrupt Mask	*/
 #define SCR_DEV_CTL	0xe0		/* b Device control	*/
@@ -83,6 +96,9 @@ static int t7l66xb_mmc_enable(struct pla
 
 	spin_unlock_irqrestore(&t7l66xb->lock, flags);
 
+	tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0,
+		t7l66xb_mmc_resources[0].start & 0xfffe);
+
 	return 0;
 }
 
@@ -106,28 +122,28 @@ static int t7l66xb_mmc_disable(struct pl
 	return 0;
 }
 
+static void t7l66xb_mmc_pwr(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_pwr(t7l66xb->scr + 0x200, 0, state);
+}
+
+static void t7l66xb_mmc_clk_div(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_clk_div(t7l66xb->scr + 0x200, 0, state);
+}
+
 /*--------------------------------------------------------------------------*/
 
 static struct tmio_mmc_data t7166xb_mmc_data = {
 	.hclk = 24000000,
-};
-
-static const struct resource t7l66xb_mmc_resources[] = {
-	{
-		.start = 0x800,
-		.end	= 0x9ff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = 0x200,
-		.end	= 0x2ff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_T7L66XB_MMC,
-		.end	= IRQ_T7L66XB_MMC,
-		.flags = IORESOURCE_IRQ,
-	},
+	.set_pwr = t7l66xb_mmc_pwr,
+	.set_clk_div = t7l66xb_mmc_clk_div,
 };
 
 static const struct resource t7l66xb_nand_resources[] = {
@@ -282,6 +298,9 @@ static int t7l66xb_resume(struct platfor
 	if (pdata && pdata->resume)
 		pdata->resume(dev);
 
+	tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0,
+		t7l66xb_mmc_resources[0].start & 0xfffe);
+
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/tc6387xb.c linux-libre-2.6.33-gnu1/drivers/mfd/tc6387xb.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/tc6387xb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/tc6387xb.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,28 +22,52 @@ enum {
 	TC6387XB_CELL_MMC,
 };
 
+struct tc6387xb {
+	void __iomem *scr;
+	struct clk *clk32k;
+	struct resource rscr;
+};
+
+static struct resource tc6387xb_mmc_resources[] = {
+	{
+		.start = 0x800,
+		.end   = 0x9ff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0,
+		.end   = 0,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/*--------------------------------------------------------------------------*/
+
 #ifdef CONFIG_PM
 static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
 {
-	struct clk *clk32k = platform_get_drvdata(dev);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
 	struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
 
 	if (pdata && pdata->suspend)
 		pdata->suspend(dev);
-	clk_disable(clk32k);
+	clk_disable(tc6387xb->clk32k);
 
 	return 0;
 }
 
 static int tc6387xb_resume(struct platform_device *dev)
 {
-	struct clk *clk32k = platform_get_drvdata(dev);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
 	struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
 
-	clk_enable(clk32k);
+	clk_enable(tc6387xb->clk32k);
 	if (pdata && pdata->resume)
 		pdata->resume(dev);
 
+	tmio_core_mmc_resume(tc6387xb->scr + 0x200, 0,
+		tc6387xb_mmc_resources[0].start & 0xfffe);
+
 	return 0;
 }
 #else
@@ -53,12 +77,32 @@ static int tc6387xb_resume(struct platfo
 
 /*--------------------------------------------------------------------------*/
 
+static void tc6387xb_mmc_pwr(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_pwr(tc6387xb->scr + 0x200, 0, state);
+}
+
+static void tc6387xb_mmc_clk_div(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_clk_div(tc6387xb->scr + 0x200, 0, state);
+}
+
+
 static int tc6387xb_mmc_enable(struct platform_device *mmc)
 {
 	struct platform_device *dev      = to_platform_device(mmc->dev.parent);
-	struct clk *clk32k = platform_get_drvdata(dev);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
 
-	clk_enable(clk32k);
+	clk_enable(tc6387xb->clk32k);
+
+	tmio_core_mmc_enable(tc6387xb->scr + 0x200, 0,
+		tc6387xb_mmc_resources[0].start & 0xfffe);
 
 	return 0;
 }
@@ -66,36 +110,20 @@ static int tc6387xb_mmc_enable(struct pl
 static int tc6387xb_mmc_disable(struct platform_device *mmc)
 {
 	struct platform_device *dev      = to_platform_device(mmc->dev.parent);
-	struct clk *clk32k = platform_get_drvdata(dev);
+	struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
 
-	clk_disable(clk32k);
+	clk_disable(tc6387xb->clk32k);
 
 	return 0;
 }
 
-/*--------------------------------------------------------------------------*/
-
 static struct tmio_mmc_data tc6387xb_mmc_data = {
 	.hclk = 24000000,
+	.set_pwr = tc6387xb_mmc_pwr,
+	.set_clk_div = tc6387xb_mmc_clk_div,
 };
 
-static struct resource tc6387xb_mmc_resources[] = {
-	{
-		.start = 0x800,
-		.end   = 0x9ff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = 0x200,
-		.end   = 0x2ff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = 0,
-		.end   = 0,
-		.flags = IORESOURCE_IRQ,
-	},
-};
+/*--------------------------------------------------------------------------*/
 
 static struct mfd_cell tc6387xb_cells[] = {
 	[TC6387XB_CELL_MMC] = {
@@ -111,8 +139,9 @@ static struct mfd_cell tc6387xb_cells[]
 static int tc6387xb_probe(struct platform_device *dev)
 {
 	struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
-	struct resource *iomem;
+	struct resource *iomem, *rscr;
 	struct clk *clk32k;
+	struct tc6387xb *tc6387xb;
 	int irq, ret;
 
 	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
@@ -120,18 +149,40 @@ static int tc6387xb_probe(struct platfor
 		return -EINVAL;
 	}
 
+	tc6387xb = kzalloc(sizeof *tc6387xb, GFP_KERNEL);
+	if (!tc6387xb)
+		return -ENOMEM;
+
 	ret  = platform_get_irq(dev, 0);
 	if (ret >= 0)
 		irq = ret;
 	else
-		goto err_resource;
+		goto err_no_irq;
 
 	clk32k = clk_get(&dev->dev, "CLK_CK32K");
 	if (IS_ERR(clk32k)) {
 		ret = PTR_ERR(clk32k);
+		goto err_no_clk;
+	}
+
+	rscr = &tc6387xb->rscr;
+	rscr->name = "tc6387xb-core";
+	rscr->start = iomem->start;
+	rscr->end = iomem->start + 0xff;
+	rscr->flags = IORESOURCE_MEM;
+
+	ret = request_resource(iomem, rscr);
+	if (ret)
 		goto err_resource;
+
+	tc6387xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+	if (!tc6387xb->scr) {
+		ret = -ENOMEM;
+		goto err_ioremap;
 	}
-	platform_set_drvdata(dev, clk32k);
+
+	tc6387xb->clk32k = clk32k;
+	platform_set_drvdata(dev, tc6387xb);
 
 	if (pdata && pdata->enable)
 		pdata->enable(dev);
@@ -149,8 +200,13 @@ static int tc6387xb_probe(struct platfor
 	if (!ret)
 		return 0;
 
-	clk_put(clk32k);
+err_ioremap:
+	release_resource(&tc6387xb->rscr);
 err_resource:
+	clk_put(clk32k);
+err_no_clk:
+err_no_irq:
+	kfree(tc6387xb);
 	return ret;
 }
 
@@ -195,3 +251,4 @@ MODULE_DESCRIPTION("Toshiba TC6387XB cor
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Ian Molton");
 MODULE_ALIAS("platform:tc6387xb");
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/tc6393xb.c linux-libre-2.6.33-gnu1/drivers/mfd/tc6393xb.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/tc6393xb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/tc6393xb.c	2010-02-24 13:52:17.000000000 -0500
@@ -136,10 +136,6 @@ static int tc6393xb_nand_enable(struct p
 	return 0;
 }
 
-static struct tmio_mmc_data tc6393xb_mmc_data = {
-	.hclk = 24000000,
-};
-
 static struct resource __devinitdata tc6393xb_nand_resources[] = {
 	{
 		.start	= 0x1000,
@@ -165,11 +161,6 @@ static struct resource __devinitdata tc6
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.start	= 0x200,
-		.end	= 0x2ff,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
 		.start	= IRQ_TC6393_MMC,
 		.end	= IRQ_TC6393_MMC,
 		.flags	= IORESOURCE_IRQ,
@@ -346,6 +337,50 @@ int tc6393xb_lcd_mode(struct platform_de
 }
 EXPORT_SYMBOL(tc6393xb_lcd_mode);
 
+static int tc6393xb_mmc_enable(struct platform_device *mmc)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0,
+		tc6393xb_mmc_resources[0].start & 0xfffe);
+
+	return 0;
+}
+
+static int tc6393xb_mmc_resume(struct platform_device *mmc)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0,
+		tc6393xb_mmc_resources[0].start & 0xfffe);
+
+	return 0;
+}
+
+static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state);
+}
+
+static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state)
+{
+	struct platform_device *dev = to_platform_device(mmc->dev.parent);
+	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+
+	tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state);
+}
+
+static struct tmio_mmc_data tc6393xb_mmc_data = {
+	.hclk = 24000000,
+	.set_pwr = tc6393xb_mmc_pwr,
+	.set_clk_div = tc6393xb_mmc_clk_div,
+};
+
 static struct mfd_cell __devinitdata tc6393xb_cells[] = {
 	[TC6393XB_CELL_NAND] = {
 		.name = "tmio-nand",
@@ -355,6 +390,8 @@ static struct mfd_cell __devinitdata tc6
 	},
 	[TC6393XB_CELL_MMC] = {
 		.name = "tmio-mmc",
+		.enable = tc6393xb_mmc_enable,
+		.resume = tc6393xb_mmc_resume,
 		.driver_data = &tc6393xb_mmc_data,
 		.num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
 		.resources = tc6393xb_mmc_resources,
@@ -836,3 +873,4 @@ MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
 MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
 MODULE_ALIAS("platform:tc6393xb");
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/tmio_core.c linux-libre-2.6.33-gnu1/drivers/mfd/tmio_core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/tmio_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/tmio_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * Copyright(c) 2009 Ian Molton <spyro@f2s.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/mfd/tmio.h>
+
+int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
+{
+	/* Enable the MMC/SD Control registers */
+	sd_config_write16(cnf, shift, CNF_CMD, SDCREN);
+	sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe);
+
+	/* Disable SD power during suspend */
+	sd_config_write8(cnf, shift, CNF_PWR_CTL_3, 0x01);
+
+	/* The below is required but why? FIXME */
+	sd_config_write8(cnf, shift, CNF_STOP_CLK_CTL, 0x1f);
+
+	/* Power down SD bus */
+	sd_config_write8(cnf, shift, CNF_PWR_CTL_2, 0x00);
+
+	return 0;
+}
+EXPORT_SYMBOL(tmio_core_mmc_enable);
+
+int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base)
+{
+
+	/* Enable the MMC/SD Control registers */
+	sd_config_write16(cnf, shift, CNF_CMD, SDCREN);
+	sd_config_write32(cnf, shift, CNF_CTL_BASE, base & 0xfffe);
+
+	return 0;
+}
+EXPORT_SYMBOL(tmio_core_mmc_resume);
+
+void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state)
+{
+	sd_config_write8(cnf, shift, CNF_PWR_CTL_2, state ? 0x02 : 0x00);
+}
+EXPORT_SYMBOL(tmio_core_mmc_pwr);
+
+void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state)
+{
+	sd_config_write8(cnf, shift, CNF_SD_CLK_MODE, state ? 1 : 0);
+}
+EXPORT_SYMBOL(tmio_core_mmc_clk_div);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/tps65010.c linux-libre-2.6.33-gnu1/drivers/mfd/tps65010.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/tps65010.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/tps65010.c	2010-02-24 13:52:17.000000000 -0500
@@ -637,7 +637,7 @@ static int tps65010_probe(struct i2c_cli
 				tps, DEBUG_FOPS);
 
 	/* optionally register GPIOs */
-	if (board && board->base > 0) {
+	if (board && board->base != 0) {
 		tps->outmask = board->outmask;
 
 		tps->chip.label = client->name;
@@ -964,6 +964,34 @@ int tps65010_config_vregs1(unsigned valu
 }
 EXPORT_SYMBOL(tps65010_config_vregs1);
 
+int tps65010_config_vdcdc2(unsigned value)
+{
+	struct i2c_client *c;
+	int	 status;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	c = the_tps->client;
+	mutex_lock(&the_tps->lock);
+
+	pr_debug("%s: vdcdc2 0x%02x\n", DRIVER_NAME,
+		 i2c_smbus_read_byte_data(c, TPS_VDCDC2));
+
+	status = i2c_smbus_write_byte_data(c, TPS_VDCDC2, value);
+
+	if (status != 0)
+		printk(KERN_ERR "%s: Failed to write vdcdc2 register\n",
+			DRIVER_NAME);
+	else
+		pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
+			 i2c_smbus_read_byte_data(c, TPS_VDCDC2));
+
+	mutex_unlock(&the_tps->lock);
+	return status;
+}
+EXPORT_SYMBOL(tps65010_config_vdcdc2);
+
 /*-------------------------------------------------------------------------*/
 /* tps65013_set_low_pwr parameter:
  * mode: ON or OFF
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-codec.c linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-codec.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-codec.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-codec.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,276 @@
+/*
+ * MFD driver for twl4030 codec submodule
+ *
+ * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
+ *
+ * Copyright:   (C) 2009 Nokia 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/twl4030-codec.h>
+
+#define TWL4030_CODEC_CELLS	2
+
+static struct platform_device *twl4030_codec_dev;
+
+struct twl4030_codec_resource {
+	int request_count;
+	u8 reg;
+	u8 mask;
+};
+
+struct twl4030_codec {
+	unsigned int audio_mclk;
+	struct mutex mutex;
+	struct twl4030_codec_resource resource[TWL4030_CODEC_RES_MAX];
+	struct mfd_cell cells[TWL4030_CODEC_CELLS];
+};
+
+/*
+ * Modify the resource, the function returns the content of the register
+ * after the modification.
+ */
+static int twl4030_codec_set_resource(enum twl4030_codec_res id, int enable)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	u8 val;
+
+	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
+			codec->resource[id].reg);
+
+	if (enable)
+		val |= codec->resource[id].mask;
+	else
+		val &= ~codec->resource[id].mask;
+
+	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+					val, codec->resource[id].reg);
+
+	return val;
+}
+
+static inline int twl4030_codec_get_resource(enum twl4030_codec_res id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	u8 val;
+
+	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
+			codec->resource[id].reg);
+
+	return val;
+}
+
+/*
+ * Enable the resource.
+ * The function returns with error or the content of the register
+ */
+int twl4030_codec_enable_resource(enum twl4030_codec_res id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	int val;
+
+	if (id >= TWL4030_CODEC_RES_MAX) {
+		dev_err(&twl4030_codec_dev->dev,
+				"Invalid resource ID (%u)\n", id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&codec->mutex);
+	if (!codec->resource[id].request_count)
+		/* Resource was disabled, enable it */
+		val = twl4030_codec_set_resource(id, 1);
+	else
+		val = twl4030_codec_get_resource(id);
+
+	codec->resource[id].request_count++;
+	mutex_unlock(&codec->mutex);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(twl4030_codec_enable_resource);
+
+/*
+ * Disable the resource.
+ * The function returns with error or the content of the register
+ */
+int twl4030_codec_disable_resource(unsigned id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	int val;
+
+	if (id >= TWL4030_CODEC_RES_MAX) {
+		dev_err(&twl4030_codec_dev->dev,
+				"Invalid resource ID (%u)\n", id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&codec->mutex);
+	if (!codec->resource[id].request_count) {
+		dev_err(&twl4030_codec_dev->dev,
+			"Resource has been disabled already (%u)\n", id);
+		mutex_unlock(&codec->mutex);
+		return -EPERM;
+	}
+	codec->resource[id].request_count--;
+
+	if (!codec->resource[id].request_count)
+		/* Resource can be disabled now */
+		val = twl4030_codec_set_resource(id, 0);
+	else
+		val = twl4030_codec_get_resource(id);
+
+	mutex_unlock(&codec->mutex);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(twl4030_codec_disable_resource);
+
+unsigned int twl4030_codec_get_mclk(void)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+
+	return codec->audio_mclk;
+}
+EXPORT_SYMBOL_GPL(twl4030_codec_get_mclk);
+
+static int __devinit twl4030_codec_probe(struct platform_device *pdev)
+{
+	struct twl4030_codec *codec;
+	struct twl4030_codec_data *pdata = pdev->dev.platform_data;
+	struct mfd_cell *cell = NULL;
+	int ret, childs = 0;
+	u8 val;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Platform data is missing\n");
+		return -EINVAL;
+	}
+
+	/* Configure APLL_INFREQ and disable APLL if enabled */
+	val = 0;
+	switch (pdata->audio_mclk) {
+	case 19200000:
+		val |= TWL4030_APLL_INFREQ_19200KHZ;
+		break;
+	case 26000000:
+		val |= TWL4030_APLL_INFREQ_26000KHZ;
+		break;
+	case 38400000:
+		val |= TWL4030_APLL_INFREQ_38400KHZ;
+		break;
+	default:
+		dev_err(&pdev->dev, "Invalid audio_mclk\n");
+		return -EINVAL;
+	}
+	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+					val, TWL4030_REG_APLL_CTL);
+
+	codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL);
+	if (!codec)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, codec);
+
+	twl4030_codec_dev = pdev;
+	mutex_init(&codec->mutex);
+	codec->audio_mclk = pdata->audio_mclk;
+
+	/* Codec power */
+	codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
+	codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ;
+
+	/* PLL */
+	codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL;
+	codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN;
+
+	if (pdata->audio) {
+		cell = &codec->cells[childs];
+		cell->name = "twl4030_codec_audio";
+		cell->platform_data = pdata->audio;
+		cell->data_size = sizeof(*pdata->audio);
+		childs++;
+	}
+	if (pdata->vibra) {
+		cell = &codec->cells[childs];
+		cell->name = "twl4030_codec_vibra";
+		cell->platform_data = pdata->vibra;
+		cell->data_size = sizeof(*pdata->vibra);
+		childs++;
+	}
+
+	if (childs)
+		ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells,
+				      childs, NULL, 0);
+	else {
+		dev_err(&pdev->dev, "No platform data found for childs\n");
+		ret = -ENODEV;
+	}
+
+	if (!ret)
+		return 0;
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(codec);
+	twl4030_codec_dev = NULL;
+	return ret;
+}
+
+static int __devexit twl4030_codec_remove(struct platform_device *pdev)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(pdev);
+
+	mfd_remove_devices(&pdev->dev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(codec);
+	twl4030_codec_dev = NULL;
+
+	return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_codec");
+
+static struct platform_driver twl4030_codec_driver = {
+	.probe		= twl4030_codec_probe,
+	.remove		= __devexit_p(twl4030_codec_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "twl4030_codec",
+	},
+};
+
+static int __devinit twl4030_codec_init(void)
+{
+	return platform_driver_register(&twl4030_codec_driver);
+}
+module_init(twl4030_codec_init);
+
+static void __devexit twl4030_codec_exit(void)
+{
+	platform_driver_unregister(&twl4030_codec_driver);
+}
+module_exit(twl4030_codec_exit);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-core.c linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,865 +0,0 @@
-/*
- * twl4030_core.c - driver for TWL4030/TPS659x0 PM and audio CODEC devices
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * Modifications to defer interrupt handling to a kernel thread:
- * Copyright (C) 2006 MontaVista Software, Inc.
- *
- * Based on tlv320aic23.c:
- * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
- *
- * Code cleanup and modifications to IRQ handler.
- * by syed khasim <x0khasim@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <linux/regulator/machine.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c/twl4030.h>
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-#include <mach/cpu.h>
-#endif
-
-/*
- * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
- * Management and System Companion Device" chips originally designed for
- * use in OMAP2 and OMAP 3 based systems.  Its control interfaces use I2C,
- * often at around 3 Mbit/sec, including for interrupt handling.
- *
- * This driver core provides genirq support for the interrupts emitted,
- * by the various modules, and exports register access primitives.
- *
- * FIXME this driver currently requires use of the first interrupt line
- * (and associated registers).
- */
-
-#define DRIVER_NAME			"twl4030"
-
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
-	defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
-#define twl_has_bci()		true
-#else
-#define twl_has_bci()		false
-#endif
-
-#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
-#define twl_has_keypad()	true
-#else
-#define twl_has_keypad()	false
-#endif
-
-#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
-#define twl_has_gpio()	true
-#else
-#define twl_has_gpio()	false
-#endif
-
-#if defined(CONFIG_REGULATOR_TWL4030) \
-	|| defined(CONFIG_REGULATOR_TWL4030_MODULE)
-#define twl_has_regulator()	true
-#else
-#define twl_has_regulator()	false
-#endif
-
-#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
-#define twl_has_madc()	true
-#else
-#define twl_has_madc()	false
-#endif
-
-#ifdef CONFIG_TWL4030_POWER
-#define twl_has_power()        true
-#else
-#define twl_has_power()        false
-#endif
-
-#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
-#define twl_has_rtc()	true
-#else
-#define twl_has_rtc()	false
-#endif
-
-#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE)
-#define twl_has_usb()	true
-#else
-#define twl_has_usb()	false
-#endif
-
-#if defined(CONFIG_TWL4030_WATCHDOG) || \
-	defined(CONFIG_TWL4030_WATCHDOG_MODULE)
-#define twl_has_watchdog()        true
-#else
-#define twl_has_watchdog()        false
-#endif
-
-/* Triton Core internal information (BEGIN) */
-
-/* Last - for index max*/
-#define TWL4030_MODULE_LAST		TWL4030_MODULE_SECURED_REG
-
-#define TWL4030_NUM_SLAVES		4
-
-#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
-	|| defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
-#define twl_has_pwrbutton()	true
-#else
-#define twl_has_pwrbutton()	false
-#endif
-
-/* Base Address defns for twl4030_map[] */
-
-/* subchip/slave 0 - USB ID */
-#define TWL4030_BASEADD_USB		0x0000
-
-/* subchip/slave 1 - AUD ID */
-#define TWL4030_BASEADD_AUDIO_VOICE	0x0000
-#define TWL4030_BASEADD_GPIO		0x0098
-#define TWL4030_BASEADD_INTBR		0x0085
-#define TWL4030_BASEADD_PIH		0x0080
-#define TWL4030_BASEADD_TEST		0x004C
-
-/* subchip/slave 2 - AUX ID */
-#define TWL4030_BASEADD_INTERRUPTS	0x00B9
-#define TWL4030_BASEADD_LED		0x00EE
-#define TWL4030_BASEADD_MADC		0x0000
-#define TWL4030_BASEADD_MAIN_CHARGE	0x0074
-#define TWL4030_BASEADD_PRECHARGE	0x00AA
-#define TWL4030_BASEADD_PWM0		0x00F8
-#define TWL4030_BASEADD_PWM1		0x00FB
-#define TWL4030_BASEADD_PWMA		0x00EF
-#define TWL4030_BASEADD_PWMB		0x00F1
-#define TWL4030_BASEADD_KEYPAD		0x00D2
-
-/* subchip/slave 3 - POWER ID */
-#define TWL4030_BASEADD_BACKUP		0x0014
-#define TWL4030_BASEADD_INT		0x002E
-#define TWL4030_BASEADD_PM_MASTER	0x0036
-#define TWL4030_BASEADD_PM_RECEIVER	0x005B
-#define TWL4030_BASEADD_RTC		0x001C
-#define TWL4030_BASEADD_SECURED_REG	0x0000
-
-/* Triton Core internal information (END) */
-
-
-/* Few power values */
-#define R_CFG_BOOT			0x05
-#define R_PROTECT_KEY			0x0E
-
-/* access control values for R_PROTECT_KEY */
-#define KEY_UNLOCK1			0xce
-#define KEY_UNLOCK2			0xec
-#define KEY_LOCK			0x00
-
-/* some fields in R_CFG_BOOT */
-#define HFCLK_FREQ_19p2_MHZ		(1 << 0)
-#define HFCLK_FREQ_26_MHZ		(2 << 0)
-#define HFCLK_FREQ_38p4_MHZ		(3 << 0)
-#define HIGH_PERF_SQ			(1 << 3)
-
-
-/* chip-specific feature flags, for i2c_device_id.driver_data */
-#define TWL4030_VAUX2		BIT(0)	/* pre-5030 voltage ranges */
-#define TPS_SUBSET		BIT(1)	/* tps659[23]0 have fewer LDOs */
-
-/*----------------------------------------------------------------------*/
-
-/* is driver active, bound to a chip? */
-static bool inuse;
-
-/* Structure for each TWL4030 Slave */
-struct twl4030_client {
-	struct i2c_client *client;
-	u8 address;
-
-	/* max numb of i2c_msg required is for read =2 */
-	struct i2c_msg xfer_msg[2];
-
-	/* To lock access to xfer_msg */
-	struct mutex xfer_lock;
-};
-
-static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES];
-
-
-/* mapping the module id to slave id and base address */
-struct twl4030mapping {
-	unsigned char sid;	/* Slave ID */
-	unsigned char base;	/* base address */
-};
-
-static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
-	/*
-	 * NOTE:  don't change this table without updating the
-	 * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_*
-	 * so they continue to match the order in this table.
-	 */
-
-	{ 0, TWL4030_BASEADD_USB },
-
-	{ 1, TWL4030_BASEADD_AUDIO_VOICE },
-	{ 1, TWL4030_BASEADD_GPIO },
-	{ 1, TWL4030_BASEADD_INTBR },
-	{ 1, TWL4030_BASEADD_PIH },
-	{ 1, TWL4030_BASEADD_TEST },
-
-	{ 2, TWL4030_BASEADD_KEYPAD },
-	{ 2, TWL4030_BASEADD_MADC },
-	{ 2, TWL4030_BASEADD_INTERRUPTS },
-	{ 2, TWL4030_BASEADD_LED },
-	{ 2, TWL4030_BASEADD_MAIN_CHARGE },
-	{ 2, TWL4030_BASEADD_PRECHARGE },
-	{ 2, TWL4030_BASEADD_PWM0 },
-	{ 2, TWL4030_BASEADD_PWM1 },
-	{ 2, TWL4030_BASEADD_PWMA },
-	{ 2, TWL4030_BASEADD_PWMB },
-
-	{ 3, TWL4030_BASEADD_BACKUP },
-	{ 3, TWL4030_BASEADD_INT },
-	{ 3, TWL4030_BASEADD_PM_MASTER },
-	{ 3, TWL4030_BASEADD_PM_RECEIVER },
-	{ 3, TWL4030_BASEADD_RTC },
-	{ 3, TWL4030_BASEADD_SECURED_REG },
-};
-
-/*----------------------------------------------------------------------*/
-
-/* Exported Functions */
-
-/**
- * twl4030_i2c_write - Writes a n bit register in TWL4030
- * @mod_no: module number
- * @value: an array of num_bytes+1 containing data to write
- * @reg: register address (just offset will do)
- * @num_bytes: number of bytes to transfer
- *
- * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and
- * valid data starts at Offset 1.
- *
- * Returns the result of operation - 0 is success
- */
-int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
-{
-	int ret;
-	int sid;
-	struct twl4030_client *twl;
-	struct i2c_msg *msg;
-
-	if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
-		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
-		return -EPERM;
-	}
-	sid = twl4030_map[mod_no].sid;
-	twl = &twl4030_modules[sid];
-
-	if (unlikely(!inuse)) {
-		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
-		return -EPERM;
-	}
-	mutex_lock(&twl->xfer_lock);
-	/*
-	 * [MSG1]: fill the register address data
-	 * fill the data Tx buffer
-	 */
-	msg = &twl->xfer_msg[0];
-	msg->addr = twl->address;
-	msg->len = num_bytes + 1;
-	msg->flags = 0;
-	msg->buf = value;
-	/* over write the first byte of buffer with the register address */
-	*value = twl4030_map[mod_no].base + reg;
-	ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
-	mutex_unlock(&twl->xfer_lock);
-
-	/* i2cTransfer returns num messages.translate it pls.. */
-	if (ret >= 0)
-		ret = 0;
-	return ret;
-}
-EXPORT_SYMBOL(twl4030_i2c_write);
-
-/**
- * twl4030_i2c_read - Reads a n bit register in TWL4030
- * @mod_no: module number
- * @value: an array of num_bytes containing data to be read
- * @reg: register address (just offset will do)
- * @num_bytes: number of bytes to transfer
- *
- * Returns result of operation - num_bytes is success else failure.
- */
-int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
-{
-	int ret;
-	u8 val;
-	int sid;
-	struct twl4030_client *twl;
-	struct i2c_msg *msg;
-
-	if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
-		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
-		return -EPERM;
-	}
-	sid = twl4030_map[mod_no].sid;
-	twl = &twl4030_modules[sid];
-
-	if (unlikely(!inuse)) {
-		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
-		return -EPERM;
-	}
-	mutex_lock(&twl->xfer_lock);
-	/* [MSG1] fill the register address data */
-	msg = &twl->xfer_msg[0];
-	msg->addr = twl->address;
-	msg->len = 1;
-	msg->flags = 0;	/* Read the register value */
-	val = twl4030_map[mod_no].base + reg;
-	msg->buf = &val;
-	/* [MSG2] fill the data rx buffer */
-	msg = &twl->xfer_msg[1];
-	msg->addr = twl->address;
-	msg->flags = I2C_M_RD;	/* Read the register value */
-	msg->len = num_bytes;	/* only n bytes */
-	msg->buf = value;
-	ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
-	mutex_unlock(&twl->xfer_lock);
-
-	/* i2cTransfer returns num messages.translate it pls.. */
-	if (ret >= 0)
-		ret = 0;
-	return ret;
-}
-EXPORT_SYMBOL(twl4030_i2c_read);
-
-/**
- * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030
- * @mod_no: module number
- * @value: the value to be written 8 bit
- * @reg: register address (just offset will do)
- *
- * Returns result of operation - 0 is success
- */
-int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
-{
-
-	/* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
-	u8 temp_buffer[2] = { 0 };
-	/* offset 1 contains the data */
-	temp_buffer[1] = value;
-	return twl4030_i2c_write(mod_no, temp_buffer, reg, 1);
-}
-EXPORT_SYMBOL(twl4030_i2c_write_u8);
-
-/**
- * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030
- * @mod_no: module number
- * @value: the value read 8 bit
- * @reg: register address (just offset will do)
- *
- * Returns result of operation - 0 is success
- */
-int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg)
-{
-	return twl4030_i2c_read(mod_no, value, reg, 1);
-}
-EXPORT_SYMBOL(twl4030_i2c_read_u8);
-
-/*----------------------------------------------------------------------*/
-
-static struct device *
-add_numbered_child(unsigned chip, const char *name, int num,
-		void *pdata, unsigned pdata_len,
-		bool can_wakeup, int irq0, int irq1)
-{
-	struct platform_device	*pdev;
-	struct twl4030_client	*twl = &twl4030_modules[chip];
-	int			status;
-
-	pdev = platform_device_alloc(name, num);
-	if (!pdev) {
-		dev_dbg(&twl->client->dev, "can't alloc dev\n");
-		status = -ENOMEM;
-		goto err;
-	}
-
-	device_init_wakeup(&pdev->dev, can_wakeup);
-	pdev->dev.parent = &twl->client->dev;
-
-	if (pdata) {
-		status = platform_device_add_data(pdev, pdata, pdata_len);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "can't add platform_data\n");
-			goto err;
-		}
-	}
-
-	if (irq0) {
-		struct resource r[2] = {
-			{ .start = irq0, .flags = IORESOURCE_IRQ, },
-			{ .start = irq1, .flags = IORESOURCE_IRQ, },
-		};
-
-		status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "can't add irqs\n");
-			goto err;
-		}
-	}
-
-	status = platform_device_add(pdev);
-
-err:
-	if (status < 0) {
-		platform_device_put(pdev);
-		dev_err(&twl->client->dev, "can't add %s dev\n", name);
-		return ERR_PTR(status);
-	}
-	return &pdev->dev;
-}
-
-static inline struct device *add_child(unsigned chip, const char *name,
-		void *pdata, unsigned pdata_len,
-		bool can_wakeup, int irq0, int irq1)
-{
-	return add_numbered_child(chip, name, -1, pdata, pdata_len,
-		can_wakeup, irq0, irq1);
-}
-
-static struct device *
-add_regulator_linked(int num, struct regulator_init_data *pdata,
-		struct regulator_consumer_supply *consumers,
-		unsigned num_consumers)
-{
-	/* regulator framework demands init_data ... */
-	if (!pdata)
-		return NULL;
-
-	if (consumers) {
-		pdata->consumer_supplies = consumers;
-		pdata->num_consumer_supplies = num_consumers;
-	}
-
-	/* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
-	return add_numbered_child(3, "twl4030_reg", num,
-		pdata, sizeof(*pdata), false, 0, 0);
-}
-
-static struct device *
-add_regulator(int num, struct regulator_init_data *pdata)
-{
-	return add_regulator_linked(num, pdata, NULL, 0);
-}
-
-/*
- * NOTE:  We know the first 8 IRQs after pdata->base_irq are
- * for the PIH, and the next are for the PWR_INT SIH, since
- * that's how twl_init_irq() sets things up.
- */
-
-static int
-add_children(struct twl4030_platform_data *pdata, unsigned long features)
-{
-	struct device	*child;
-
-	if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) {
-		child = add_child(3, "twl4030_bci",
-				pdata->bci, sizeof(*pdata->bci),
-				false,
-				/* irq0 = CHG_PRES, irq1 = BCI */
-				pdata->irq_base + 8 + 1, pdata->irq_base + 2);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_gpio() && pdata->gpio) {
-		child = add_child(1, "twl4030_gpio",
-				pdata->gpio, sizeof(*pdata->gpio),
-				false, pdata->irq_base + 0, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_keypad() && pdata->keypad) {
-		child = add_child(2, "twl4030_keypad",
-				pdata->keypad, sizeof(*pdata->keypad),
-				true, pdata->irq_base + 1, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_madc() && pdata->madc) {
-		child = add_child(2, "twl4030_madc",
-				pdata->madc, sizeof(*pdata->madc),
-				true, pdata->irq_base + 3, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_rtc()) {
-		/*
-		 * REVISIT platform_data here currently might expose the
-		 * "msecure" line ... but for now we just expect board
-		 * setup to tell the chip "it's always ok to SET_TIME".
-		 * Eventually, Linux might become more aware of such
-		 * HW security concerns, and "least privilege".
-		 */
-		child = add_child(3, "twl4030_rtc",
-				NULL, 0,
-				true, pdata->irq_base + 8 + 3, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_usb() && pdata->usb) {
-
-		static struct regulator_consumer_supply usb1v5 = {
-			.supply =	"usb1v5",
-		};
-		static struct regulator_consumer_supply usb1v8 = {
-			.supply =	"usb1v8",
-		};
-		static struct regulator_consumer_supply usb3v1 = {
-			.supply =	"usb3v1",
-		};
-
-	/* First add the regulators so that they can be used by transceiver */
-		if (twl_has_regulator()) {
-			/* this is a template that gets copied */
-			struct regulator_init_data usb_fixed = {
-				.constraints.valid_modes_mask =
-					REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-				.constraints.valid_ops_mask =
-					REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-			};
-
-			child = add_regulator_linked(TWL4030_REG_VUSB1V5,
-						      &usb_fixed, &usb1v5, 1);
-			if (IS_ERR(child))
-				return PTR_ERR(child);
-
-			child = add_regulator_linked(TWL4030_REG_VUSB1V8,
-						      &usb_fixed, &usb1v8, 1);
-			if (IS_ERR(child))
-				return PTR_ERR(child);
-
-			child = add_regulator_linked(TWL4030_REG_VUSB3V1,
-						      &usb_fixed, &usb3v1, 1);
-			if (IS_ERR(child))
-				return PTR_ERR(child);
-
-		}
-
-		child = add_child(0, "twl4030_usb",
-				pdata->usb, sizeof(*pdata->usb),
-				true,
-				/* irq0 = USB_PRES, irq1 = USB */
-				pdata->irq_base + 8 + 2, pdata->irq_base + 4);
-
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		/* we need to connect regulators to this transceiver */
-		if (twl_has_regulator() && child) {
-			usb1v5.dev = child;
-			usb1v8.dev = child;
-			usb3v1.dev = child;
-		}
-	}
-
-	if (twl_has_watchdog()) {
-		child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_pwrbutton()) {
-		child = add_child(1, "twl4030_pwrbutton",
-				NULL, 0, true, pdata->irq_base + 8 + 0, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	if (twl_has_regulator()) {
-		/*
-		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-		*/
-
-		child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator((features & TWL4030_VAUX2)
-					? TWL4030_REG_VAUX2_4030
-					: TWL4030_REG_VAUX2,
-				pdata->vaux2);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	/* maybe add LDOs that are omitted on cost-reduced parts */
-	if (twl_has_regulator() && !(features & TPS_SUBSET)) {
-		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-
-		child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
-	return 0;
-}
-
-/*----------------------------------------------------------------------*/
-
-/*
- * These three functions initialize the on-chip clock framework,
- * letting it generate the right frequencies for USB, MADC, and
- * other purposes.
- */
-static inline int __init protect_pm_master(void)
-{
-	int e = 0;
-
-	e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK,
-			R_PROTECT_KEY);
-	return e;
-}
-
-static inline int __init unprotect_pm_master(void)
-{
-	int e = 0;
-
-	e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1,
-			R_PROTECT_KEY);
-	e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2,
-			R_PROTECT_KEY);
-	return e;
-}
-
-static void clocks_init(struct device *dev)
-{
-	int e = 0;
-	struct clk *osc;
-	u32 rate;
-	u8 ctrl = HFCLK_FREQ_26_MHZ;
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	if (cpu_is_omap2430())
-		osc = clk_get(dev, "osc_ck");
-	else
-		osc = clk_get(dev, "osc_sys_ck");
-
-	if (IS_ERR(osc)) {
-		printk(KERN_WARNING "Skipping twl4030 internal clock init and "
-				"using bootloader value (unknown osc rate)\n");
-		return;
-	}
-
-	rate = clk_get_rate(osc);
-	clk_put(osc);
-
-#else
-	/* REVISIT for non-OMAP systems, pass the clock rate from
-	 * board init code, using platform_data.
-	 */
-	osc = ERR_PTR(-EIO);
-
-	printk(KERN_WARNING "Skipping twl4030 internal clock init and "
-	       "using bootloader value (unknown osc rate)\n");
-
-	return;
-#endif
-
-	switch (rate) {
-	case 19200000:
-		ctrl = HFCLK_FREQ_19p2_MHZ;
-		break;
-	case 26000000:
-		ctrl = HFCLK_FREQ_26_MHZ;
-		break;
-	case 38400000:
-		ctrl = HFCLK_FREQ_38p4_MHZ;
-		break;
-	}
-
-	ctrl |= HIGH_PERF_SQ;
-	e |= unprotect_pm_master();
-	/* effect->MADC+USB ck en */
-	e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
-	e |= protect_pm_master();
-
-	if (e < 0)
-		pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e);
-}
-
-/*----------------------------------------------------------------------*/
-
-int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
-int twl_exit_irq(void);
-
-static int twl4030_remove(struct i2c_client *client)
-{
-	unsigned i;
-	int status;
-
-	status = twl_exit_irq();
-	if (status < 0)
-		return status;
-
-	for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
-		struct twl4030_client	*twl = &twl4030_modules[i];
-
-		if (twl->client && twl->client != client)
-			i2c_unregister_device(twl->client);
-		twl4030_modules[i].client = NULL;
-	}
-	inuse = false;
-	return 0;
-}
-
-/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
-static int
-twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
-	int				status;
-	unsigned			i;
-	struct twl4030_platform_data	*pdata = client->dev.platform_data;
-
-	if (!pdata) {
-		dev_dbg(&client->dev, "no platform data?\n");
-		return -EINVAL;
-	}
-
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
-		dev_dbg(&client->dev, "can't talk I2C?\n");
-		return -EIO;
-	}
-
-	if (inuse) {
-		dev_dbg(&client->dev, "driver is already in use\n");
-		return -EBUSY;
-	}
-
-	for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
-		struct twl4030_client	*twl = &twl4030_modules[i];
-
-		twl->address = client->addr + i;
-		if (i == 0)
-			twl->client = client;
-		else {
-			twl->client = i2c_new_dummy(client->adapter,
-					twl->address);
-			if (!twl->client) {
-				dev_err(&client->dev,
-					"can't attach client %d\n", i);
-				status = -ENOMEM;
-				goto fail;
-			}
-			strlcpy(twl->client->name, id->name,
-					sizeof(twl->client->name));
-		}
-		mutex_init(&twl->xfer_lock);
-	}
-	inuse = true;
-
-	/* setup clock framework */
-	clocks_init(&client->dev);
-
-	/* load power event scripts */
-	if (twl_has_power() && pdata->power)
-		twl4030_power_init(pdata->power);
-
-	/* Maybe init the T2 Interrupt subsystem */
-	if (client->irq
-			&& pdata->irq_base
-			&& pdata->irq_end > pdata->irq_base) {
-		status = twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
-		if (status < 0)
-			goto fail;
-	}
-
-	status = add_children(pdata, id->driver_data);
-fail:
-	if (status < 0)
-		twl4030_remove(client);
-	return status;
-}
-
-static const struct i2c_device_id twl4030_ids[] = {
-	{ "twl4030", TWL4030_VAUX2 },	/* "Triton 2" */
-	{ "twl5030", 0 },		/* T2 updated */
-	{ "tps65950", 0 },		/* catalog version of twl5030 */
-	{ "tps65930", TPS_SUBSET },	/* fewer LDOs and DACs; no charger */
-	{ "tps65920", TPS_SUBSET },	/* fewer LDOs; no codec or charger */
-	{ /* end of list */ },
-};
-MODULE_DEVICE_TABLE(i2c, twl4030_ids);
-
-/* One Client Driver , 4 Clients */
-static struct i2c_driver twl4030_driver = {
-	.driver.name	= DRIVER_NAME,
-	.id_table	= twl4030_ids,
-	.probe		= twl4030_probe,
-	.remove		= twl4030_remove,
-};
-
-static int __init twl4030_init(void)
-{
-	return i2c_add_driver(&twl4030_driver);
-}
-subsys_initcall(twl4030_init);
-
-static void __exit twl4030_exit(void)
-{
-	i2c_del_driver(&twl4030_driver);
-}
-module_exit(twl4030_exit);
-
-MODULE_AUTHOR("Texas Instruments, Inc.");
-MODULE_DESCRIPTION("I2C Core interface for TWL4030");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-irq.c linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-irq.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@
 #include <linux/irq.h>
 #include <linux/kthread.h>
 
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
@@ -74,6 +74,8 @@ struct sih {
 	u8	edr_offset;
 	u8	bytes_edr;		/* bytelen of EDR */
 
+	u8	irq_lines;		/* number of supported irq lines */
+
 	/* SIR ignored -- set interrupt, for testing only */
 	struct irq_data {
 		u8	isr_offset;
@@ -82,6 +84,9 @@ struct sih {
 	/* + 2 bytes padding */
 };
 
+static const struct sih *sih_modules;
+static int nr_sih_modules;
+
 #define SIH_INITIALIZER(modname, nbits) \
 	.module		= TWL4030_MODULE_ ## modname, \
 	.control_offset = TWL4030_ ## modname ## _SIH_CTRL, \
@@ -89,6 +94,7 @@ struct sih {
 	.bytes_ixr	= DIV_ROUND_UP(nbits, 8), \
 	.edr_offset	= TWL4030_ ## modname ## _EDR, \
 	.bytes_edr	= DIV_ROUND_UP((2*(nbits)), 8), \
+	.irq_lines	= 2, \
 	.mask = { { \
 		.isr_offset	= TWL4030_ ## modname ## _ISR1, \
 		.imr_offset	= TWL4030_ ## modname ## _IMR1, \
@@ -107,7 +113,8 @@ struct sih {
 /* Order in this table matches order in PIH_ISR.  That is,
  * BIT(n) in PIH_ISR is sih_modules[n].
  */
-static const struct sih sih_modules[6] = {
+/* sih_modules_twl4030 is used both in twl4030 and twl5030 */
+static const struct sih sih_modules_twl4030[6] = {
 	[0] = {
 		.name		= "gpio",
 		.module		= TWL4030_MODULE_GPIO,
@@ -118,6 +125,7 @@ static const struct sih sih_modules[6] =
 		/* Note: *all* of these IRQs default to no-trigger */
 		.edr_offset	= REG_GPIO_EDR1,
 		.bytes_edr	= 5,
+		.irq_lines	= 2,
 		.mask = { {
 			.isr_offset	= REG_GPIO_ISR1A,
 			.imr_offset	= REG_GPIO_IMR1A,
@@ -140,6 +148,7 @@ static const struct sih sih_modules[6] =
 		.edr_offset	= TWL4030_INTERRUPTS_BCIEDR1,
 		/* Note: most of these IRQs default to no-trigger */
 		.bytes_edr	= 3,
+		.irq_lines	= 2,
 		.mask = { {
 			.isr_offset	= TWL4030_INTERRUPTS_BCIISR1A,
 			.imr_offset	= TWL4030_INTERRUPTS_BCIIMR1A,
@@ -164,6 +173,99 @@ static const struct sih sih_modules[6] =
 		/* there are no SIH modules #6 or #7 ... */
 };
 
+static const struct sih sih_modules_twl5031[8] = {
+	[0] = {
+		.name		= "gpio",
+		.module		= TWL4030_MODULE_GPIO,
+		.control_offset	= REG_GPIO_SIH_CTRL,
+		.set_cor	= true,
+		.bits		= TWL4030_GPIO_MAX,
+		.bytes_ixr	= 3,
+		/* Note: *all* of these IRQs default to no-trigger */
+		.edr_offset	= REG_GPIO_EDR1,
+		.bytes_edr	= 5,
+		.irq_lines	= 2,
+		.mask = { {
+			.isr_offset	= REG_GPIO_ISR1A,
+			.imr_offset	= REG_GPIO_IMR1A,
+		}, {
+			.isr_offset	= REG_GPIO_ISR1B,
+			.imr_offset	= REG_GPIO_IMR1B,
+		}, },
+	},
+	[1] = {
+		.name		= "keypad",
+		.set_cor	= true,
+		SIH_INITIALIZER(KEYPAD_KEYP, 4)
+	},
+	[2] = {
+		.name		= "bci",
+		.module		= TWL5031_MODULE_INTERRUPTS,
+		.control_offset	= TWL5031_INTERRUPTS_BCISIHCTRL,
+		.bits		= 7,
+		.bytes_ixr	= 1,
+		.edr_offset	= TWL5031_INTERRUPTS_BCIEDR1,
+		/* Note: most of these IRQs default to no-trigger */
+		.bytes_edr	= 2,
+		.irq_lines	= 2,
+		.mask = { {
+			.isr_offset	= TWL5031_INTERRUPTS_BCIISR1,
+			.imr_offset	= TWL5031_INTERRUPTS_BCIIMR1,
+		}, {
+			.isr_offset	= TWL5031_INTERRUPTS_BCIISR2,
+			.imr_offset	= TWL5031_INTERRUPTS_BCIIMR2,
+		}, },
+	},
+	[3] = {
+		.name		= "madc",
+		SIH_INITIALIZER(MADC, 4)
+	},
+	[4] = {
+		/* USB doesn't use the same SIH organization */
+		.name		= "usb",
+	},
+	[5] = {
+		.name		= "power",
+		.set_cor	= true,
+		SIH_INITIALIZER(INT_PWR, 8)
+	},
+	[6] = {
+		/*
+		 * ACI doesn't use the same SIH organization.
+		 * For example, it supports only one interrupt line
+		 */
+		.name		= "aci",
+		.module		= TWL5031_MODULE_ACCESSORY,
+		.bits		= 9,
+		.bytes_ixr	= 2,
+		.irq_lines	= 1,
+		.mask = { {
+			.isr_offset	= TWL5031_ACIIDR_LSB,
+			.imr_offset	= TWL5031_ACIIMR_LSB,
+		}, },
+
+	},
+	[7] = {
+		/* Accessory */
+		.name		= "acc",
+		.module		= TWL5031_MODULE_ACCESSORY,
+		.control_offset	= TWL5031_ACCSIHCTRL,
+		.bits		= 2,
+		.bytes_ixr	= 1,
+		.edr_offset	= TWL5031_ACCEDR1,
+		/* Note: most of these IRQs default to no-trigger */
+		.bytes_edr	= 1,
+		.irq_lines	= 2,
+		.mask = { {
+			.isr_offset	= TWL5031_ACCISR1,
+			.imr_offset	= TWL5031_ACCIMR1,
+		}, {
+			.isr_offset	= TWL5031_ACCISR2,
+			.imr_offset	= TWL5031_ACCIMR2,
+		}, },
+	},
+};
+
 #undef TWL4030_MODULE_KEYPAD_KEYP
 #undef TWL4030_MODULE_INT_PWR
 #undef TWL4030_INT_PWR_EDR
@@ -194,7 +296,7 @@ static int twl4030_irq_thread(void *data
 		/* Wait for IRQ, then read PIH irq status (also blocking) */
 		wait_for_completion_interruptible(&irq_event);
 
-		ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
+		ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
 					  REG_PIH_ISR_P1);
 		if (ret) {
 			pr_warning("twl4030: I2C error %d reading PIH ISR\n",
@@ -284,13 +386,17 @@ static int twl4030_init_sih_modules(unsi
 	/* disable all interrupts on our line */
 	memset(buf, 0xff, sizeof buf);
 	sih = sih_modules;
-	for (i = 0; i < ARRAY_SIZE(sih_modules); i++, sih++) {
+	for (i = 0; i < nr_sih_modules; i++, sih++) {
 
 		/* skip USB -- it's funky */
 		if (!sih->bytes_ixr)
 			continue;
 
-		status = twl4030_i2c_write(sih->module, buf,
+		/* Not all the SIH modules support multiple interrupt lines */
+		if (sih->irq_lines <= line)
+			continue;
+
+		status = twl_i2c_write(sih->module, buf,
 				sih->mask[line].imr_offset, sih->bytes_ixr);
 		if (status < 0)
 			pr_err("twl4030: err %d initializing %s %s\n",
@@ -304,7 +410,7 @@ static int twl4030_init_sih_modules(unsi
 		 * And for PWR_INT it's not documented...
 		 */
 		if (sih->set_cor) {
-			status = twl4030_i2c_write_u8(sih->module,
+			status = twl_i2c_write_u8(sih->module,
 					TWL4030_SIH_CTRL_COR_MASK,
 					sih->control_offset);
 			if (status < 0)
@@ -314,7 +420,7 @@ static int twl4030_init_sih_modules(unsi
 	}
 
 	sih = sih_modules;
-	for (i = 0; i < ARRAY_SIZE(sih_modules); i++, sih++) {
+	for (i = 0; i < nr_sih_modules; i++, sih++) {
 		u8 rxbuf[4];
 		int j;
 
@@ -322,20 +428,24 @@ static int twl4030_init_sih_modules(unsi
 		if (!sih->bytes_ixr)
 			continue;
 
+		/* Not all the SIH modules support multiple interrupt lines */
+		if (sih->irq_lines <= line)
+			continue;
+
 		/* Clear pending interrupt status.  Either the read was
 		 * enough, or we need to write those bits.  Repeat, in
 		 * case an IRQ is pending (PENDDIS=0) ... that's not
 		 * uncommon with PWR_INT.PWRON.
 		 */
 		for (j = 0; j < 2; j++) {
-			status = twl4030_i2c_read(sih->module, rxbuf,
+			status = twl_i2c_read(sih->module, rxbuf,
 				sih->mask[line].isr_offset, sih->bytes_ixr);
 			if (status < 0)
 				pr_err("twl4030: err %d initializing %s %s\n",
 					status, sih->name, "ISR");
 
 			if (!sih->set_cor)
-				status = twl4030_i2c_write(sih->module, buf,
+				status = twl_i2c_write(sih->module, buf,
 					sih->mask[line].isr_offset,
 					sih->bytes_ixr);
 			/* else COR=1 means read sufficed.
@@ -404,7 +514,7 @@ static void twl4030_sih_do_mask(struct w
 		return;
 
 	/* write the whole mask ... simpler than subsetting it */
-	status = twl4030_i2c_write(sih->module, imr.bytes,
+	status = twl_i2c_write(sih->module, imr.bytes,
 			sih->mask[irq_line].imr_offset, sih->bytes_ixr);
 	if (status)
 		pr_err("twl4030: %s, %s --> %d\n", __func__,
@@ -435,7 +545,7 @@ static void twl4030_sih_do_edge(struct w
 	 * any processor on the other IRQ line, EDR registers are
 	 * shared.
 	 */
-	status = twl4030_i2c_read(sih->module, bytes + 1,
+	status = twl_i2c_read(sih->module, bytes + 1,
 			sih->edr_offset, sih->bytes_edr);
 	if (status) {
 		pr_err("twl4030: %s, %s --> %d\n", __func__,
@@ -458,18 +568,18 @@ static void twl4030_sih_do_edge(struct w
 
 		bytes[byte] &= ~(0x03 << off);
 
-		spin_lock_irq(&d->lock);
+		raw_spin_lock_irq(&d->lock);
 		if (d->status & IRQ_TYPE_EDGE_RISING)
 			bytes[byte] |= BIT(off + 1);
 		if (d->status & IRQ_TYPE_EDGE_FALLING)
 			bytes[byte] |= BIT(off + 0);
-		spin_unlock_irq(&d->lock);
+		raw_spin_unlock_irq(&d->lock);
 
 		edge_change &= ~BIT(i);
 	}
 
 	/* Write */
-	status = twl4030_i2c_write(sih->module, bytes,
+	status = twl_i2c_write(sih->module, bytes,
 			sih->edr_offset, sih->bytes_edr);
 	if (status)
 		pr_err("twl4030: %s, %s --> %d\n", __func__,
@@ -554,7 +664,7 @@ static inline int sih_read_isr(const str
 	/* FIXME need retry-on-error ... */
 
 	isr.word = 0;
-	status = twl4030_i2c_read(sih->module, isr.bytes,
+	status = twl_i2c_read(sih->module, isr.bytes,
 			sih->mask[irq_line].isr_offset, sih->bytes_ixr);
 
 	return (status < 0) ? status : le32_to_cpu(isr.word);
@@ -611,7 +721,7 @@ int twl4030_sih_setup(int module)
 
 	/* only support modules with standard clear-on-read for now */
 	for (sih_mod = 0, sih = sih_modules;
-			sih_mod < ARRAY_SIZE(sih_modules);
+			sih_mod < nr_sih_modules;
 			sih_mod++, sih++) {
 		if (sih->module == module && sih->set_cor) {
 			if (!WARN((irq_base + sih->bits) > NR_IRQS,
@@ -668,7 +778,7 @@ int twl4030_sih_setup(int module)
 /* FIXME pass in which interrupt line we'll use ... */
 #define twl_irq_line	0
 
-int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 {
 	static struct irq_chip	twl4030_irq_chip;
 
@@ -728,7 +838,8 @@ int twl_init_irq(int irq_num, unsigned i
 		goto fail_rqirq;
 	}
 
-	task = kthread_run(twl4030_irq_thread, (void *)irq_num, "twl4030-irq");
+	task = kthread_run(twl4030_irq_thread, (void *)(long)irq_num,
+								"twl4030-irq");
 	if (IS_ERR(task)) {
 		pr_err("twl4030: could not create irq %d thread!\n", irq_num);
 		status = PTR_ERR(task);
@@ -747,7 +858,7 @@ fail:
 	return status;
 }
 
-int twl_exit_irq(void)
+int twl4030_exit_irq(void)
 {
 	/* FIXME undo twl_init_irq() */
 	if (twl4030_irq_base) {
@@ -756,3 +867,16 @@ int twl_exit_irq(void)
 	}
 	return 0;
 }
+
+int twl4030_init_chip_irq(const char *chip)
+{
+	if (!strcmp(chip, "twl5031")) {
+		sih_modules = sih_modules_twl5031;
+		nr_sih_modules = ARRAY_SIZE(sih_modules_twl5031);
+	} else {
+		sih_modules = sih_modules_twl4030;
+		nr_sih_modules = ARRAY_SIZE(sih_modules_twl4030);
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-power.c linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-power.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl4030-power.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl4030-power.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/pm.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach-types.h>
@@ -67,19 +67,35 @@ static u8 twl4030_start_script_address =
 #define R_KEY_1			0xC0
 #define R_KEY_2			0x0C
 
-/* resource configuration registers */
-
-#define DEVGROUP_OFFSET		0
+/* resource configuration registers
+   <RESOURCE>_DEV_GRP   at address 'n+0'
+   <RESOURCE>_TYPE      at address 'n+1'
+   <RESOURCE>_REMAP     at address 'n+2'
+   <RESOURCE>_DEDICATED at address 'n+3'
+*/
+#define DEV_GRP_OFFSET		0
 #define TYPE_OFFSET		1
+#define REMAP_OFFSET		2
+#define DEDICATED_OFFSET	3
 
-/* Bit positions */
-#define DEVGROUP_SHIFT		5
-#define DEVGROUP_MASK		(7 << DEVGROUP_SHIFT)
+/* Bit positions in the registers */
+
+/* <RESOURCE>_DEV_GRP */
+#define DEV_GRP_SHIFT		5
+#define DEV_GRP_MASK		(7 << DEV_GRP_SHIFT)
+
+/* <RESOURCE>_TYPE */
 #define TYPE_SHIFT		0
 #define TYPE_MASK		(7 << TYPE_SHIFT)
 #define TYPE2_SHIFT		3
 #define TYPE2_MASK		(3 << TYPE2_SHIFT)
 
+/* <RESOURCE>_REMAP */
+#define SLEEP_STATE_SHIFT	0
+#define SLEEP_STATE_MASK	(0xf << SLEEP_STATE_SHIFT)
+#define OFF_STATE_SHIFT		4
+#define OFF_STATE_MASK		(0xf << OFF_STATE_SHIFT)
+
 static u8 res_config_addrs[] = {
 	[RES_VAUX1]	= 0x17,
 	[RES_VAUX2]	= 0x1b,
@@ -115,11 +131,11 @@ static int __init twl4030_write_script_b
 {
 	int err;
 
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
 				R_MEMORY_ADDRESS);
 	if (err)
 		goto out;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, byte,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, byte,
 				R_MEMORY_DATA);
 out:
 	return err;
@@ -176,18 +192,18 @@ static int __init twl4030_config_wakeup3
 	u8 data;
 
 	/* Set SLEEP to ACTIVE SEQ address for P3 */
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
 				R_SEQ_ADD_S2A3);
 	if (err)
 		goto out;
 
 	/* P3 LVL_WAKEUP should be on LEVEL */
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
 				R_P3_SW_EVENTS);
 	if (err)
 		goto out;
 	data |= LVL_WAKEUP;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
 				R_P3_SW_EVENTS);
 out:
 	if (err)
@@ -201,42 +217,42 @@ static int __init twl4030_config_wakeup1
 	u8 data;
 
 	/* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
 				R_SEQ_ADD_S2A12);
 	if (err)
 		goto out;
 
 	/* P1/P2 LVL_WAKEUP should be on LEVEL */
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
 				R_P1_SW_EVENTS);
 	if (err)
 		goto out;
 
 	data |= LVL_WAKEUP;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
 				R_P1_SW_EVENTS);
 	if (err)
 		goto out;
 
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
 				R_P2_SW_EVENTS);
 	if (err)
 		goto out;
 
 	data |= LVL_WAKEUP;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
 				R_P2_SW_EVENTS);
 	if (err)
 		goto out;
 
 	if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
 		/* Disabling AC charger effect on sleep-active transitions */
-		err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+		err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
 					R_CFG_P1_TRANSITION);
 		if (err)
 			goto out;
 		data &= ~(1<<1);
-		err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data ,
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data ,
 					R_CFG_P1_TRANSITION);
 		if (err)
 			goto out;
@@ -254,7 +270,7 @@ static int __init twl4030_config_sleep_s
 	int err;
 
 	/* Set ACTIVE to SLEEP SEQ address in T2 memory*/
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
 				R_SEQ_ADD_A2S);
 
 	if (err)
@@ -269,41 +285,41 @@ static int __init twl4030_config_warmres
 	u8 rd_data;
 
 	/* Set WARM RESET SEQ address for P1 */
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
 				R_SEQ_ADD_WARM);
 	if (err)
 		goto out;
 
 	/* P1/P2/P3 enable WARMRESET */
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
 				R_P1_SW_EVENTS);
 	if (err)
 		goto out;
 
 	rd_data |= ENABLE_WARMRESET;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
 				R_P1_SW_EVENTS);
 	if (err)
 		goto out;
 
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
 				R_P2_SW_EVENTS);
 	if (err)
 		goto out;
 
 	rd_data |= ENABLE_WARMRESET;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
 				R_P2_SW_EVENTS);
 	if (err)
 		goto out;
 
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
 				R_P3_SW_EVENTS);
 	if (err)
 		goto out;
 
 	rd_data |= ENABLE_WARMRESET;
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
 				R_P3_SW_EVENTS);
 out:
 	if (err)
@@ -317,6 +333,7 @@ static int __init twl4030_configure_reso
 	int err;
 	u8 type;
 	u8 grp;
+	u8 remap;
 
 	if (rconfig->resource > TOTAL_RESOURCES) {
 		pr_err("TWL4030 Resource %d does not exist\n",
@@ -327,19 +344,19 @@ static int __init twl4030_configure_reso
 	rconfig_addr = res_config_addrs[rconfig->resource];
 
 	/* Set resource group */
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
-				rconfig_addr + DEVGROUP_OFFSET);
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
+			      rconfig_addr + DEV_GRP_OFFSET);
 	if (err) {
 		pr_err("TWL4030 Resource %d group could not be read\n",
 			rconfig->resource);
 		return err;
 	}
 
-	if (rconfig->devgroup >= 0) {
-		grp &= ~DEVGROUP_MASK;
-		grp |= rconfig->devgroup << DEVGROUP_SHIFT;
-		err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
-					grp, rconfig_addr + DEVGROUP_OFFSET);
+	if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
+		grp &= ~DEV_GRP_MASK;
+		grp |= rconfig->devgroup << DEV_GRP_SHIFT;
+		err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+				       grp, rconfig_addr + DEV_GRP_OFFSET);
 		if (err < 0) {
 			pr_err("TWL4030 failed to program devgroup\n");
 			return err;
@@ -347,7 +364,7 @@ static int __init twl4030_configure_reso
 	}
 
 	/* Set resource types */
-	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
 				rconfig_addr + TYPE_OFFSET);
 	if (err < 0) {
 		pr_err("TWL4030 Resource %d type could not be read\n",
@@ -355,23 +372,50 @@ static int __init twl4030_configure_reso
 		return err;
 	}
 
-	if (rconfig->type >= 0) {
+	if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
 		type &= ~TYPE_MASK;
 		type |= rconfig->type << TYPE_SHIFT;
 	}
 
-	if (rconfig->type2 >= 0) {
+	if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
 		type &= ~TYPE2_MASK;
 		type |= rconfig->type2 << TYPE2_SHIFT;
 	}
 
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
 				type, rconfig_addr + TYPE_OFFSET);
 	if (err < 0) {
 		pr_err("TWL4030 failed to program resource type\n");
 		return err;
 	}
 
+	/* Set remap states */
+	err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap,
+			      rconfig_addr + REMAP_OFFSET);
+	if (err < 0) {
+		pr_err("TWL4030 Resource %d remap could not be read\n",
+			rconfig->resource);
+		return err;
+	}
+
+	if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
+		remap &= ~OFF_STATE_MASK;
+		remap |= rconfig->remap_off << OFF_STATE_SHIFT;
+	}
+
+	if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
+		remap &= ~SLEEP_STATE_MASK;
+		remap |= rconfig->remap_off << SLEEP_STATE_SHIFT;
+	}
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+			       remap,
+			       rconfig_addr + REMAP_OFFSET);
+	if (err < 0) {
+		pr_err("TWL4030 failed to program remap\n");
+		return err;
+	}
+
 	return 0;
 }
 
@@ -424,12 +468,12 @@ void __init twl4030_power_init(struct tw
 	struct twl4030_resconfig *resconfig;
 	u8 address = twl4030_start_script_address;
 
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
 				R_PROTECT_KEY);
 	if (err)
 		goto unlock;
 
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
 				R_PROTECT_KEY);
 	if (err)
 		goto unlock;
@@ -452,7 +496,7 @@ void __init twl4030_power_init(struct tw
 		}
 	}
 
-	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+	err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
 	if (err)
 		pr_err("TWL4030 Unable to relock registers\n");
 	return;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl6030-irq.c linux-libre-2.6.33-gnu1/drivers/mfd/twl6030-irq.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl6030-irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl6030-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,299 @@
+/*
+ * twl6030-irq.c - TWL6030 irq support
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ *
+ * Modifications to defer interrupt handling to a kernel thread:
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * Code cleanup and modifications to IRQ handler.
+ * by syed khasim <x0khasim@ti.com>
+ *
+ * TWL6030 specific code and IRQ handling changes by
+ * Jagadeesh Bhaskar Pakaravoor <j-pakaravoor@ti.com>
+ * Balaji T K <balajitk@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kthread.h>
+#include <linux/i2c/twl.h>
+
+/*
+ * TWL6030 (unlike its predecessors, which had two level interrupt handling)
+ * three interrupt registers INT_STS_A, INT_STS_B and INT_STS_C.
+ * It exposes status bits saying who has raised an interrupt. There are
+ * three mask registers that corresponds to these status registers, that
+ * enables/disables these interrupts.
+ *
+ * We set up IRQs starting at a platform-specified base. An interrupt map table,
+ * specifies mapping between interrupt number and the associated module.
+ *
+ */
+
+static int twl6030_interrupt_mapping[24] = {
+	PWR_INTR_OFFSET,	/* Bit 0	PWRON			*/
+	PWR_INTR_OFFSET,	/* Bit 1	RPWRON			*/
+	PWR_INTR_OFFSET,	/* Bit 2	BAT_VLOW		*/
+	RTC_INTR_OFFSET,	/* Bit 3	RTC_ALARM		*/
+	RTC_INTR_OFFSET,	/* Bit 4	RTC_PERIOD		*/
+	HOTDIE_INTR_OFFSET,	/* Bit 5	HOT_DIE			*/
+	SMPSLDO_INTR_OFFSET,	/* Bit 6	VXXX_SHORT		*/
+	SMPSLDO_INTR_OFFSET,	/* Bit 7	VMMC_SHORT		*/
+
+	SMPSLDO_INTR_OFFSET,	/* Bit 8	VUSIM_SHORT		*/
+	BATDETECT_INTR_OFFSET,	/* Bit 9	BAT			*/
+	SIMDETECT_INTR_OFFSET,	/* Bit 10	SIM			*/
+	MMCDETECT_INTR_OFFSET,	/* Bit 11	MMC			*/
+	RSV_INTR_OFFSET,  	/* Bit 12	Reserved		*/
+	MADC_INTR_OFFSET,	/* Bit 13	GPADC_RT_EOC		*/
+	MADC_INTR_OFFSET,	/* Bit 14	GPADC_SW_EOC		*/
+	GASGAUGE_INTR_OFFSET,	/* Bit 15	CC_AUTOCAL		*/
+
+	USBOTG_INTR_OFFSET,	/* Bit 16	ID_WKUP			*/
+	USBOTG_INTR_OFFSET,	/* Bit 17	VBUS_WKUP		*/
+	USBOTG_INTR_OFFSET,	/* Bit 18	ID			*/
+	USBOTG_INTR_OFFSET,	/* Bit 19	VBUS			*/
+	CHARGER_INTR_OFFSET,	/* Bit 20	CHRG_CTRL		*/
+	CHARGER_INTR_OFFSET,	/* Bit 21	EXT_CHRG		*/
+	CHARGER_INTR_OFFSET,	/* Bit 22	INT_CHRG		*/
+	RSV_INTR_OFFSET,	/* Bit 23	Reserved		*/
+};
+/*----------------------------------------------------------------------*/
+
+static unsigned twl6030_irq_base;
+
+static struct completion irq_event;
+
+/*
+ * This thread processes interrupts reported by the Primary Interrupt Handler.
+ */
+static int twl6030_irq_thread(void *data)
+{
+	long irq = (long)data;
+	static unsigned i2c_errors;
+	static const unsigned max_i2c_errors = 100;
+	int ret;
+
+	current->flags |= PF_NOFREEZE;
+
+	while (!kthread_should_stop()) {
+		int i;
+		union {
+		u8 bytes[4];
+		u32 int_sts;
+		} sts;
+
+		/* Wait for IRQ, then read PIH irq status (also blocking) */
+		wait_for_completion_interruptible(&irq_event);
+
+		/* read INT_STS_A, B and C in one shot using a burst read */
+		ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes,
+				REG_INT_STS_A, 3);
+		if (ret) {
+			pr_warning("twl6030: I2C error %d reading PIH ISR\n",
+					ret);
+			if (++i2c_errors >= max_i2c_errors) {
+				printk(KERN_ERR "Maximum I2C error count"
+						" exceeded.  Terminating %s.\n",
+						__func__);
+				break;
+			}
+			complete(&irq_event);
+			continue;
+		}
+
+
+
+		sts.bytes[3] = 0; /* Only 24 bits are valid*/
+
+		for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) {
+			local_irq_disable();
+			if (sts.int_sts & 0x1) {
+				int module_irq = twl6030_irq_base +
+					twl6030_interrupt_mapping[i];
+				struct irq_desc *d = irq_to_desc(module_irq);
+
+				if (!d) {
+					pr_err("twl6030: Invalid SIH IRQ: %d\n",
+					       module_irq);
+					return -EINVAL;
+				}
+
+				/* These can't be masked ... always warn
+				 * if we get any surprises.
+				 */
+				if (d->status & IRQ_DISABLED)
+					note_interrupt(module_irq, d,
+							IRQ_NONE);
+				else
+					d->handle_irq(module_irq, d);
+
+			}
+		local_irq_enable();
+		}
+		ret = twl_i2c_write(TWL_MODULE_PIH, sts.bytes,
+				REG_INT_STS_A, 3); /* clear INT_STS_A */
+		if (ret)
+			pr_warning("twl6030: I2C error in clearing PIH ISR\n");
+
+		enable_irq(irq);
+	}
+
+	return 0;
+}
+
+/*
+ * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt.
+ * This is a chained interrupt, so there is no desc->action method for it.
+ * Now we need to query the interrupt controller in the twl6030 to determine
+ * which module is generating the interrupt request.  However, we can't do i2c
+ * transactions in interrupt context, so we must defer that work to a kernel
+ * thread.  All we do here is acknowledge and mask the interrupt and wakeup
+ * the kernel thread.
+ */
+static irqreturn_t handle_twl6030_pih(int irq, void *devid)
+{
+	disable_irq_nosync(irq);
+	complete(devid);
+	return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+static inline void activate_irq(int irq)
+{
+#ifdef CONFIG_ARM
+	/* ARM requires an extra step to clear IRQ_NOREQUEST, which it
+	 * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
+	 */
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	/* same effect on other architectures */
+	set_irq_noprobe(irq);
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+
+static unsigned twl6030_irq_next;
+
+/*----------------------------------------------------------------------*/
+int twl6030_interrupt_unmask(u8 bit_mask, u8 offset)
+{
+	int ret;
+	u8 unmask_value;
+	ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value,
+			REG_INT_STS_A + offset);
+	unmask_value &= (~(bit_mask));
+	ret |= twl_i2c_write_u8(TWL_MODULE_PIH, unmask_value,
+			REG_INT_STS_A + offset); /* unmask INT_MSK_A/B/C */
+	return ret;
+}
+EXPORT_SYMBOL(twl6030_interrupt_unmask);
+
+int twl6030_interrupt_mask(u8 bit_mask, u8 offset)
+{
+	int ret;
+	u8 mask_value;
+	ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value,
+			REG_INT_STS_A + offset);
+	mask_value |= (bit_mask);
+	ret |= twl_i2c_write_u8(TWL_MODULE_PIH, mask_value,
+			REG_INT_STS_A + offset); /* mask INT_MSK_A/B/C */
+	return ret;
+}
+EXPORT_SYMBOL(twl6030_interrupt_mask);
+
+int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+{
+
+	int	status = 0;
+	int	i;
+	struct task_struct	*task;
+	int ret;
+	u8 mask[4];
+
+	static struct irq_chip	twl6030_irq_chip;
+	mask[1] = 0xFF;
+	mask[2] = 0xFF;
+	mask[3] = 0xFF;
+	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
+			REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */
+	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
+			REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */
+	ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0],
+			REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */
+
+	twl6030_irq_base = irq_base;
+
+	/* install an irq handler for each of the modules;
+	 * clone dummy irq_chip since PIH can't *do* anything
+	 */
+	twl6030_irq_chip = dummy_irq_chip;
+	twl6030_irq_chip.name = "twl6030";
+	twl6030_irq_chip.set_type = NULL;
+
+	for (i = irq_base; i < irq_end; i++) {
+		set_irq_chip_and_handler(i, &twl6030_irq_chip,
+				handle_simple_irq);
+		activate_irq(i);
+	}
+
+	twl6030_irq_next = i;
+	pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH",
+			irq_num, irq_base, twl6030_irq_next - 1);
+
+	/* install an irq handler to demultiplex the TWL6030 interrupt */
+	init_completion(&irq_event);
+	task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
+	if (IS_ERR(task)) {
+		pr_err("twl6030: could not create irq %d thread!\n", irq_num);
+		status = PTR_ERR(task);
+		goto fail_kthread;
+	}
+
+	status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED,
+				"TWL6030-PIH", &irq_event);
+	if (status < 0) {
+		pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
+		goto fail_irq;
+	}
+	return status;
+fail_irq:
+	free_irq(irq_num, &irq_event);
+
+fail_kthread:
+	for (i = irq_base; i < irq_end; i++)
+		set_irq_chip_and_handler(i, NULL, NULL);
+	return status;
+}
+
+int twl6030_exit_irq(void)
+{
+
+	if (twl6030_irq_base) {
+		pr_err("twl6030: can't yet clean up IRQs?\n");
+		return -ENOSYS;
+	}
+	return 0;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/twl-core.c linux-libre-2.6.33-gnu1/drivers/mfd/twl-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/twl-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/twl-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1076 @@
+/*
+ * twl_core.c - driver for TWL4030/TWL5030/TWL60X0/TPS659x0 PM
+ * and audio CODEC devices
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Modifications to defer interrupt handling to a kernel thread:
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * Code cleanup and modifications to IRQ handler.
+ * by syed khasim <x0khasim@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#include <plat/cpu.h>
+#endif
+
+/*
+ * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
+ * Management and System Companion Device" chips originally designed for
+ * use in OMAP2 and OMAP 3 based systems.  Its control interfaces use I2C,
+ * often at around 3 Mbit/sec, including for interrupt handling.
+ *
+ * This driver core provides genirq support for the interrupts emitted,
+ * by the various modules, and exports register access primitives.
+ *
+ * FIXME this driver currently requires use of the first interrupt line
+ * (and associated registers).
+ */
+
+#define DRIVER_NAME			"twl"
+
+#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
+	defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
+#define twl_has_bci()		true
+#else
+#define twl_has_bci()		false
+#endif
+
+#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
+#define twl_has_keypad()	true
+#else
+#define twl_has_keypad()	false
+#endif
+
+#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
+#define twl_has_gpio()	true
+#else
+#define twl_has_gpio()	false
+#endif
+
+#if defined(CONFIG_REGULATOR_TWL4030) \
+	|| defined(CONFIG_REGULATOR_TWL4030_MODULE)
+#define twl_has_regulator()	true
+#else
+#define twl_has_regulator()	false
+#endif
+
+#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
+#define twl_has_madc()	true
+#else
+#define twl_has_madc()	false
+#endif
+
+#ifdef CONFIG_TWL4030_POWER
+#define twl_has_power()        true
+#else
+#define twl_has_power()        false
+#endif
+
+#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
+#define twl_has_rtc()	true
+#else
+#define twl_has_rtc()	false
+#endif
+
+#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE)
+#define twl_has_usb()	true
+#else
+#define twl_has_usb()	false
+#endif
+
+#if defined(CONFIG_TWL4030_WATCHDOG) || \
+	defined(CONFIG_TWL4030_WATCHDOG_MODULE)
+#define twl_has_watchdog()        true
+#else
+#define twl_has_watchdog()        false
+#endif
+
+#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
+#define twl_has_codec()	true
+#else
+#define twl_has_codec()	false
+#endif
+
+/* Triton Core internal information (BEGIN) */
+
+/* Last - for index max*/
+#define TWL4030_MODULE_LAST		TWL4030_MODULE_SECURED_REG
+
+#define TWL_NUM_SLAVES		4
+
+#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
+	|| defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
+#define twl_has_pwrbutton()	true
+#else
+#define twl_has_pwrbutton()	false
+#endif
+
+#define SUB_CHIP_ID0 0
+#define SUB_CHIP_ID1 1
+#define SUB_CHIP_ID2 2
+#define SUB_CHIP_ID3 3
+
+#define TWL_MODULE_LAST TWL4030_MODULE_LAST
+
+/* Base Address defns for twl4030_map[] */
+
+/* subchip/slave 0 - USB ID */
+#define TWL4030_BASEADD_USB		0x0000
+
+/* subchip/slave 1 - AUD ID */
+#define TWL4030_BASEADD_AUDIO_VOICE	0x0000
+#define TWL4030_BASEADD_GPIO		0x0098
+#define TWL4030_BASEADD_INTBR		0x0085
+#define TWL4030_BASEADD_PIH		0x0080
+#define TWL4030_BASEADD_TEST		0x004C
+
+/* subchip/slave 2 - AUX ID */
+#define TWL4030_BASEADD_INTERRUPTS	0x00B9
+#define TWL4030_BASEADD_LED		0x00EE
+#define TWL4030_BASEADD_MADC		0x0000
+#define TWL4030_BASEADD_MAIN_CHARGE	0x0074
+#define TWL4030_BASEADD_PRECHARGE	0x00AA
+#define TWL4030_BASEADD_PWM0		0x00F8
+#define TWL4030_BASEADD_PWM1		0x00FB
+#define TWL4030_BASEADD_PWMA		0x00EF
+#define TWL4030_BASEADD_PWMB		0x00F1
+#define TWL4030_BASEADD_KEYPAD		0x00D2
+
+#define TWL5031_BASEADD_ACCESSORY	0x0074 /* Replaces Main Charge */
+#define TWL5031_BASEADD_INTERRUPTS	0x00B9 /* Different than TWL4030's
+						  one */
+
+/* subchip/slave 3 - POWER ID */
+#define TWL4030_BASEADD_BACKUP		0x0014
+#define TWL4030_BASEADD_INT		0x002E
+#define TWL4030_BASEADD_PM_MASTER	0x0036
+#define TWL4030_BASEADD_PM_RECEIVER	0x005B
+#define TWL4030_BASEADD_RTC		0x001C
+#define TWL4030_BASEADD_SECURED_REG	0x0000
+
+/* Triton Core internal information (END) */
+
+
+/* subchip/slave 0 0x48 - POWER */
+#define TWL6030_BASEADD_RTC		0x0000
+#define TWL6030_BASEADD_MEM		0x0017
+#define TWL6030_BASEADD_PM_MASTER	0x001F
+#define TWL6030_BASEADD_PM_SLAVE_MISC	0x0030 /* PM_RECEIVER */
+#define TWL6030_BASEADD_PM_MISC		0x00E2
+#define TWL6030_BASEADD_PM_PUPD		0x00F0
+
+/* subchip/slave 1 0x49 - FEATURE */
+#define TWL6030_BASEADD_USB		0x0000
+#define TWL6030_BASEADD_GPADC_CTRL	0x002E
+#define TWL6030_BASEADD_AUX		0x0090
+#define TWL6030_BASEADD_PWM		0x00BA
+#define TWL6030_BASEADD_GASGAUGE	0x00C0
+#define TWL6030_BASEADD_PIH		0x00D0
+#define TWL6030_BASEADD_CHARGER		0x00E0
+
+/* subchip/slave 2 0x4A - DFT */
+#define TWL6030_BASEADD_DIEID		0x00C0
+
+/* subchip/slave 3 0x4B - AUDIO */
+#define TWL6030_BASEADD_AUDIO		0x0000
+#define TWL6030_BASEADD_RSV		0x0000
+
+/* Few power values */
+#define R_CFG_BOOT			0x05
+#define R_PROTECT_KEY			0x0E
+
+/* access control values for R_PROTECT_KEY */
+#define KEY_UNLOCK1			0xce
+#define KEY_UNLOCK2			0xec
+#define KEY_LOCK			0x00
+
+/* some fields in R_CFG_BOOT */
+#define HFCLK_FREQ_19p2_MHZ		(1 << 0)
+#define HFCLK_FREQ_26_MHZ		(2 << 0)
+#define HFCLK_FREQ_38p4_MHZ		(3 << 0)
+#define HIGH_PERF_SQ			(1 << 3)
+#define CK32K_LOWPWR_EN			(1 << 7)
+
+
+/* chip-specific feature flags, for i2c_device_id.driver_data */
+#define TWL4030_VAUX2		BIT(0)	/* pre-5030 voltage ranges */
+#define TPS_SUBSET		BIT(1)	/* tps659[23]0 have fewer LDOs */
+#define TWL5031			BIT(2)  /* twl5031 has different registers */
+#define TWL6030_CLASS		BIT(3)	/* TWL6030 class */
+
+/*----------------------------------------------------------------------*/
+
+/* is driver active, bound to a chip? */
+static bool inuse;
+
+static unsigned int twl_id;
+unsigned int twl_rev(void)
+{
+	return twl_id;
+}
+EXPORT_SYMBOL(twl_rev);
+
+/* Structure for each TWL4030/TWL6030 Slave */
+struct twl_client {
+	struct i2c_client *client;
+	u8 address;
+
+	/* max numb of i2c_msg required is for read =2 */
+	struct i2c_msg xfer_msg[2];
+
+	/* To lock access to xfer_msg */
+	struct mutex xfer_lock;
+};
+
+static struct twl_client twl_modules[TWL_NUM_SLAVES];
+
+
+/* mapping the module id to slave id and base address */
+struct twl_mapping {
+	unsigned char sid;	/* Slave ID */
+	unsigned char base;	/* base address */
+};
+struct twl_mapping *twl_map;
+
+static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
+	/*
+	 * NOTE:  don't change this table without updating the
+	 * <linux/i2c/twl.h> defines for TWL4030_MODULE_*
+	 * so they continue to match the order in this table.
+	 */
+
+	{ 0, TWL4030_BASEADD_USB },
+
+	{ 1, TWL4030_BASEADD_AUDIO_VOICE },
+	{ 1, TWL4030_BASEADD_GPIO },
+	{ 1, TWL4030_BASEADD_INTBR },
+	{ 1, TWL4030_BASEADD_PIH },
+	{ 1, TWL4030_BASEADD_TEST },
+
+	{ 2, TWL4030_BASEADD_KEYPAD },
+	{ 2, TWL4030_BASEADD_MADC },
+	{ 2, TWL4030_BASEADD_INTERRUPTS },
+	{ 2, TWL4030_BASEADD_LED },
+	{ 2, TWL4030_BASEADD_MAIN_CHARGE },
+	{ 2, TWL4030_BASEADD_PRECHARGE },
+	{ 2, TWL4030_BASEADD_PWM0 },
+	{ 2, TWL4030_BASEADD_PWM1 },
+	{ 2, TWL4030_BASEADD_PWMA },
+	{ 2, TWL4030_BASEADD_PWMB },
+	{ 2, TWL5031_BASEADD_ACCESSORY },
+	{ 2, TWL5031_BASEADD_INTERRUPTS },
+
+	{ 3, TWL4030_BASEADD_BACKUP },
+	{ 3, TWL4030_BASEADD_INT },
+	{ 3, TWL4030_BASEADD_PM_MASTER },
+	{ 3, TWL4030_BASEADD_PM_RECEIVER },
+	{ 3, TWL4030_BASEADD_RTC },
+	{ 3, TWL4030_BASEADD_SECURED_REG },
+};
+
+static struct twl_mapping twl6030_map[] = {
+	/*
+	 * NOTE:  don't change this table without updating the
+	 * <linux/i2c/twl.h> defines for TWL4030_MODULE_*
+	 * so they continue to match the order in this table.
+	 */
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_USB },
+	{ SUB_CHIP_ID3, TWL6030_BASEADD_AUDIO },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_DIEID },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_PIH },
+
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_GPADC_CTRL },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER },
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE },
+	{ SUB_CHIP_ID1, TWL6030_BASEADD_PWM },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+	{ SUB_CHIP_ID0, TWL6030_BASEADD_PM_MASTER },
+	{ SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_MISC },
+
+	{ SUB_CHIP_ID0, TWL6030_BASEADD_RTC },
+	{ SUB_CHIP_ID0, TWL6030_BASEADD_MEM },
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Exported Functions */
+
+/**
+ * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
+ * @mod_no: module number
+ * @value: an array of num_bytes+1 containing data to write
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and
+ * valid data starts at Offset 1.
+ *
+ * Returns the result of operation - 0 is success
+ */
+int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
+{
+	int ret;
+	int sid;
+	struct twl_client *twl;
+	struct i2c_msg *msg;
+
+	if (unlikely(mod_no > TWL_MODULE_LAST)) {
+		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+		return -EPERM;
+	}
+	sid = twl_map[mod_no].sid;
+	twl = &twl_modules[sid];
+
+	if (unlikely(!inuse)) {
+		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+		return -EPERM;
+	}
+	mutex_lock(&twl->xfer_lock);
+	/*
+	 * [MSG1]: fill the register address data
+	 * fill the data Tx buffer
+	 */
+	msg = &twl->xfer_msg[0];
+	msg->addr = twl->address;
+	msg->len = num_bytes + 1;
+	msg->flags = 0;
+	msg->buf = value;
+	/* over write the first byte of buffer with the register address */
+	*value = twl_map[mod_no].base + reg;
+	ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
+	mutex_unlock(&twl->xfer_lock);
+
+	/* i2c_transfer returns number of messages transferred */
+	if (ret != 1) {
+		pr_err("%s: i2c_write failed to transfer all messages\n",
+			DRIVER_NAME);
+		if (ret < 0)
+			return ret;
+		else
+			return -EIO;
+	} else {
+		return 0;
+	}
+}
+EXPORT_SYMBOL(twl_i2c_write);
+
+/**
+ * twl_i2c_read - Reads a n bit register in TWL4030/TWL5030/TWL60X0
+ * @mod_no: module number
+ * @value: an array of num_bytes containing data to be read
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * Returns result of operation - num_bytes is success else failure.
+ */
+int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
+{
+	int ret;
+	u8 val;
+	int sid;
+	struct twl_client *twl;
+	struct i2c_msg *msg;
+
+	if (unlikely(mod_no > TWL_MODULE_LAST)) {
+		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+		return -EPERM;
+	}
+	sid = twl_map[mod_no].sid;
+	twl = &twl_modules[sid];
+
+	if (unlikely(!inuse)) {
+		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+		return -EPERM;
+	}
+	mutex_lock(&twl->xfer_lock);
+	/* [MSG1] fill the register address data */
+	msg = &twl->xfer_msg[0];
+	msg->addr = twl->address;
+	msg->len = 1;
+	msg->flags = 0;	/* Read the register value */
+	val = twl_map[mod_no].base + reg;
+	msg->buf = &val;
+	/* [MSG2] fill the data rx buffer */
+	msg = &twl->xfer_msg[1];
+	msg->addr = twl->address;
+	msg->flags = I2C_M_RD;	/* Read the register value */
+	msg->len = num_bytes;	/* only n bytes */
+	msg->buf = value;
+	ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
+	mutex_unlock(&twl->xfer_lock);
+
+	/* i2c_transfer returns number of messages transferred */
+	if (ret != 2) {
+		pr_err("%s: i2c_read failed to transfer all messages\n",
+			DRIVER_NAME);
+		if (ret < 0)
+			return ret;
+		else
+			return -EIO;
+	} else {
+		return 0;
+	}
+}
+EXPORT_SYMBOL(twl_i2c_read);
+
+/**
+ * twl_i2c_write_u8 - Writes a 8 bit register in TWL4030/TWL5030/TWL60X0
+ * @mod_no: module number
+ * @value: the value to be written 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
+{
+
+	/* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
+	u8 temp_buffer[2] = { 0 };
+	/* offset 1 contains the data */
+	temp_buffer[1] = value;
+	return twl_i2c_write(mod_no, temp_buffer, reg, 1);
+}
+EXPORT_SYMBOL(twl_i2c_write_u8);
+
+/**
+ * twl_i2c_read_u8 - Reads a 8 bit register from TWL4030/TWL5030/TWL60X0
+ * @mod_no: module number
+ * @value: the value read 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl_i2c_read_u8(u8 mod_no, u8 *value, u8 reg)
+{
+	return twl_i2c_read(mod_no, value, reg, 1);
+}
+EXPORT_SYMBOL(twl_i2c_read_u8);
+
+/*----------------------------------------------------------------------*/
+
+static struct device *
+add_numbered_child(unsigned chip, const char *name, int num,
+		void *pdata, unsigned pdata_len,
+		bool can_wakeup, int irq0, int irq1)
+{
+	struct platform_device	*pdev;
+	struct twl_client	*twl = &twl_modules[chip];
+	int			status;
+
+	pdev = platform_device_alloc(name, num);
+	if (!pdev) {
+		dev_dbg(&twl->client->dev, "can't alloc dev\n");
+		status = -ENOMEM;
+		goto err;
+	}
+
+	device_init_wakeup(&pdev->dev, can_wakeup);
+	pdev->dev.parent = &twl->client->dev;
+
+	if (pdata) {
+		status = platform_device_add_data(pdev, pdata, pdata_len);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "can't add platform_data\n");
+			goto err;
+		}
+	}
+
+	if (irq0) {
+		struct resource r[2] = {
+			{ .start = irq0, .flags = IORESOURCE_IRQ, },
+			{ .start = irq1, .flags = IORESOURCE_IRQ, },
+		};
+
+		status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "can't add irqs\n");
+			goto err;
+		}
+	}
+
+	status = platform_device_add(pdev);
+
+err:
+	if (status < 0) {
+		platform_device_put(pdev);
+		dev_err(&twl->client->dev, "can't add %s dev\n", name);
+		return ERR_PTR(status);
+	}
+	return &pdev->dev;
+}
+
+static inline struct device *add_child(unsigned chip, const char *name,
+		void *pdata, unsigned pdata_len,
+		bool can_wakeup, int irq0, int irq1)
+{
+	return add_numbered_child(chip, name, -1, pdata, pdata_len,
+		can_wakeup, irq0, irq1);
+}
+
+static struct device *
+add_regulator_linked(int num, struct regulator_init_data *pdata,
+		struct regulator_consumer_supply *consumers,
+		unsigned num_consumers)
+{
+	unsigned sub_chip_id;
+	/* regulator framework demands init_data ... */
+	if (!pdata)
+		return NULL;
+
+	if (consumers) {
+		pdata->consumer_supplies = consumers;
+		pdata->num_consumer_supplies = num_consumers;
+	}
+
+	/* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
+	sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
+	return add_numbered_child(sub_chip_id, "twl_reg", num,
+		pdata, sizeof(*pdata), false, 0, 0);
+}
+
+static struct device *
+add_regulator(int num, struct regulator_init_data *pdata)
+{
+	return add_regulator_linked(num, pdata, NULL, 0);
+}
+
+/*
+ * NOTE:  We know the first 8 IRQs after pdata->base_irq are
+ * for the PIH, and the next are for the PWR_INT SIH, since
+ * that's how twl_init_irq() sets things up.
+ */
+
+static int
+add_children(struct twl4030_platform_data *pdata, unsigned long features)
+{
+	struct device	*child;
+	unsigned sub_chip_id;
+
+	if (twl_has_bci() && pdata->bci &&
+	    !(features & (TPS_SUBSET | TWL5031))) {
+		child = add_child(3, "twl4030_bci",
+				pdata->bci, sizeof(*pdata->bci),
+				false,
+				/* irq0 = CHG_PRES, irq1 = BCI */
+				pdata->irq_base + BCI_PRES_INTR_OFFSET,
+				pdata->irq_base + BCI_INTR_OFFSET);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_gpio() && pdata->gpio) {
+		child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
+				pdata->gpio, sizeof(*pdata->gpio),
+				false, pdata->irq_base + GPIO_INTR_OFFSET, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_keypad() && pdata->keypad) {
+		child = add_child(SUB_CHIP_ID2, "twl4030_keypad",
+				pdata->keypad, sizeof(*pdata->keypad),
+				true, pdata->irq_base + KEYPAD_INTR_OFFSET, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_madc() && pdata->madc) {
+		child = add_child(2, "twl4030_madc",
+				pdata->madc, sizeof(*pdata->madc),
+				true, pdata->irq_base + MADC_INTR_OFFSET, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_rtc()) {
+		/*
+		 * REVISIT platform_data here currently might expose the
+		 * "msecure" line ... but for now we just expect board
+		 * setup to tell the chip "it's always ok to SET_TIME".
+		 * Eventually, Linux might become more aware of such
+		 * HW security concerns, and "least privilege".
+		 */
+		sub_chip_id = twl_map[TWL_MODULE_RTC].sid;
+		child = add_child(sub_chip_id, "twl_rtc",
+				NULL, 0,
+				true, pdata->irq_base + RTC_INTR_OFFSET, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_usb() && pdata->usb && twl_class_is_4030()) {
+
+		static struct regulator_consumer_supply usb1v5 = {
+			.supply =	"usb1v5",
+		};
+		static struct regulator_consumer_supply usb1v8 = {
+			.supply =	"usb1v8",
+		};
+		static struct regulator_consumer_supply usb3v1 = {
+			.supply =	"usb3v1",
+		};
+
+	/* First add the regulators so that they can be used by transceiver */
+		if (twl_has_regulator()) {
+			/* this is a template that gets copied */
+			struct regulator_init_data usb_fixed = {
+				.constraints.valid_modes_mask =
+					REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+				.constraints.valid_ops_mask =
+					REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+			};
+
+			child = add_regulator_linked(TWL4030_REG_VUSB1V5,
+						      &usb_fixed, &usb1v5, 1);
+			if (IS_ERR(child))
+				return PTR_ERR(child);
+
+			child = add_regulator_linked(TWL4030_REG_VUSB1V8,
+						      &usb_fixed, &usb1v8, 1);
+			if (IS_ERR(child))
+				return PTR_ERR(child);
+
+			child = add_regulator_linked(TWL4030_REG_VUSB3V1,
+						      &usb_fixed, &usb3v1, 1);
+			if (IS_ERR(child))
+				return PTR_ERR(child);
+
+		}
+
+		child = add_child(0, "twl4030_usb",
+				pdata->usb, sizeof(*pdata->usb),
+				true,
+				/* irq0 = USB_PRES, irq1 = USB */
+				pdata->irq_base + USB_PRES_INTR_OFFSET,
+				pdata->irq_base + USB_INTR_OFFSET);
+
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		/* we need to connect regulators to this transceiver */
+		if (twl_has_regulator() && child) {
+			usb1v5.dev = child;
+			usb1v8.dev = child;
+			usb3v1.dev = child;
+		}
+	}
+
+	if (twl_has_watchdog()) {
+		child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_pwrbutton()) {
+		child = add_child(1, "twl4030_pwrbutton",
+				NULL, 0, true, pdata->irq_base + 8 + 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (twl_has_codec() && pdata->codec) {
+		child = add_child(1, "twl4030_codec",
+				pdata->codec, sizeof(*pdata->codec),
+				false, 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	/* twl4030 regulators */
+	if (twl_has_regulator() && twl_class_is_4030()) {
+		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VIO, pdata->vio);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator((features & TWL4030_VAUX2)
+					? TWL4030_REG_VAUX2_4030
+					: TWL4030_REG_VAUX2,
+				pdata->vaux2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	/* maybe add LDOs that are omitted on cost-reduced parts */
+	if (twl_has_regulator() && !(features & TPS_SUBSET)
+	  && twl_class_is_4030()) {
+		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	/* twl6030 regulators */
+	if (twl_has_regulator() && twl_class_is_6030()) {
+		child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VPP, pdata->vpp);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VANA, pdata->vana);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VDAC, pdata->vdac);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VUSB, pdata->vusb);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * These three functions initialize the on-chip clock framework,
+ * letting it generate the right frequencies for USB, MADC, and
+ * other purposes.
+ */
+static inline int __init protect_pm_master(void)
+{
+	int e = 0;
+
+	e = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_LOCK,
+			R_PROTECT_KEY);
+	return e;
+}
+
+static inline int __init unprotect_pm_master(void)
+{
+	int e = 0;
+
+	e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK1,
+			R_PROTECT_KEY);
+	e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK2,
+			R_PROTECT_KEY);
+	return e;
+}
+
+static void clocks_init(struct device *dev,
+			struct twl4030_clock_init_data *clock)
+{
+	int e = 0;
+	struct clk *osc;
+	u32 rate;
+	u8 ctrl = HFCLK_FREQ_26_MHZ;
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	if (cpu_is_omap2430())
+		osc = clk_get(dev, "osc_ck");
+	else
+		osc = clk_get(dev, "osc_sys_ck");
+
+	if (IS_ERR(osc)) {
+		printk(KERN_WARNING "Skipping twl internal clock init and "
+				"using bootloader value (unknown osc rate)\n");
+		return;
+	}
+
+	rate = clk_get_rate(osc);
+	clk_put(osc);
+
+#else
+	/* REVISIT for non-OMAP systems, pass the clock rate from
+	 * board init code, using platform_data.
+	 */
+	osc = ERR_PTR(-EIO);
+
+	printk(KERN_WARNING "Skipping twl internal clock init and "
+	       "using bootloader value (unknown osc rate)\n");
+
+	return;
+#endif
+
+	switch (rate) {
+	case 19200000:
+		ctrl = HFCLK_FREQ_19p2_MHZ;
+		break;
+	case 26000000:
+		ctrl = HFCLK_FREQ_26_MHZ;
+		break;
+	case 38400000:
+		ctrl = HFCLK_FREQ_38p4_MHZ;
+		break;
+	}
+
+	ctrl |= HIGH_PERF_SQ;
+	if (clock && clock->ck32k_lowpwr_enable)
+		ctrl |= CK32K_LOWPWR_EN;
+
+	e |= unprotect_pm_master();
+	/* effect->MADC+USB ck en */
+	e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
+	e |= protect_pm_master();
+
+	if (e < 0)
+		pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e);
+}
+
+/*----------------------------------------------------------------------*/
+
+int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+int twl4030_exit_irq(void);
+int twl4030_init_chip_irq(const char *chip);
+int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+int twl6030_exit_irq(void);
+
+static int twl_remove(struct i2c_client *client)
+{
+	unsigned i;
+	int status;
+
+	if (twl_class_is_4030())
+		status = twl4030_exit_irq();
+	else
+		status = twl6030_exit_irq();
+
+	if (status < 0)
+		return status;
+
+	for (i = 0; i < TWL_NUM_SLAVES; i++) {
+		struct twl_client	*twl = &twl_modules[i];
+
+		if (twl->client && twl->client != client)
+			i2c_unregister_device(twl->client);
+		twl_modules[i].client = NULL;
+	}
+	inuse = false;
+	return 0;
+}
+
+/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
+static int __init
+twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	int				status;
+	unsigned			i;
+	struct twl4030_platform_data	*pdata = client->dev.platform_data;
+
+	if (!pdata) {
+		dev_dbg(&client->dev, "no platform data?\n");
+		return -EINVAL;
+	}
+
+	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
+		dev_dbg(&client->dev, "can't talk I2C?\n");
+		return -EIO;
+	}
+
+	if (inuse) {
+		dev_dbg(&client->dev, "driver is already in use\n");
+		return -EBUSY;
+	}
+
+	for (i = 0; i < TWL_NUM_SLAVES; i++) {
+		struct twl_client	*twl = &twl_modules[i];
+
+		twl->address = client->addr + i;
+		if (i == 0)
+			twl->client = client;
+		else {
+			twl->client = i2c_new_dummy(client->adapter,
+					twl->address);
+			if (!twl->client) {
+				dev_err(&client->dev,
+					"can't attach client %d\n", i);
+				status = -ENOMEM;
+				goto fail;
+			}
+		}
+		mutex_init(&twl->xfer_lock);
+	}
+	inuse = true;
+	if ((id->driver_data) & TWL6030_CLASS) {
+		twl_id = TWL6030_CLASS_ID;
+		twl_map = &twl6030_map[0];
+	} else {
+		twl_id = TWL4030_CLASS_ID;
+		twl_map = &twl4030_map[0];
+	}
+
+	/* setup clock framework */
+	clocks_init(&client->dev, pdata->clock);
+
+	/* load power event scripts */
+	if (twl_has_power() && pdata->power)
+		twl4030_power_init(pdata->power);
+
+	/* Maybe init the T2 Interrupt subsystem */
+	if (client->irq
+			&& pdata->irq_base
+			&& pdata->irq_end > pdata->irq_base) {
+		if (twl_class_is_4030()) {
+			twl4030_init_chip_irq(id->name);
+			status = twl4030_init_irq(client->irq, pdata->irq_base,
+			pdata->irq_end);
+		} else {
+			status = twl6030_init_irq(client->irq, pdata->irq_base,
+			pdata->irq_end);
+		}
+
+		if (status < 0)
+			goto fail;
+	}
+
+	status = add_children(pdata, id->driver_data);
+fail:
+	if (status < 0)
+		twl_remove(client);
+	return status;
+}
+
+static const struct i2c_device_id twl_ids[] = {
+	{ "twl4030", TWL4030_VAUX2 },	/* "Triton 2" */
+	{ "twl5030", 0 },		/* T2 updated */
+	{ "twl5031", TWL5031 },		/* TWL5030 updated */
+	{ "tps65950", 0 },		/* catalog version of twl5030 */
+	{ "tps65930", TPS_SUBSET },	/* fewer LDOs and DACs; no charger */
+	{ "tps65920", TPS_SUBSET },	/* fewer LDOs; no codec or charger */
+	{ "twl6030", TWL6030_CLASS },	/* "Phoenix power chip" */
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(i2c, twl_ids);
+
+/* One Client Driver , 4 Clients */
+static struct i2c_driver twl_driver = {
+	.driver.name	= DRIVER_NAME,
+	.id_table	= twl_ids,
+	.probe		= twl_probe,
+	.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_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("I2C Core interface for TWL");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ucb1400_core.c linux-libre-2.6.33-gnu1/drivers/mfd/ucb1400_core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ucb1400_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ucb1400_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,7 @@ static int ucb1400_core_probe(struct dev
 	struct ucb1400_ts ucb_ts;
 	struct ucb1400_gpio ucb_gpio;
 	struct snd_ac97 *ac97;
+	struct ucb1400_pdata *pdata = dev->platform_data;
 
 	memset(&ucb_ts, 0, sizeof(ucb_ts));
 	memset(&ucb_gpio, 0, sizeof(ucb_gpio));
@@ -88,6 +89,12 @@ static int ucb1400_core_probe(struct dev
 
 	/* TOUCHSCREEN */
 	ucb_ts.ac97 = ac97;
+
+	if (pdata != NULL && pdata->irq >= 0)
+		ucb_ts.irq = pdata->irq;
+	else
+		ucb_ts.irq = -1;
+
 	ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
 	if (!ucb->ucb1400_ts) {
 		err = -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-assabet.c linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-assabet.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-assabet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-assabet.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,10 +14,10 @@
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/device.h>
+#include <linux/mfd/ucb1x00.h>
 
 #include <mach/dma.h>
 
-#include "ucb1x00.h"
 
 #define UCB1X00_ATTR(name,input)\
 static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-core.c linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,12 +25,12 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/gpio.h>
 
 #include <mach/dma.h>
 #include <mach/hardware.h>
 
-#include "ucb1x00.h"
-
 static DEFINE_MUTEX(ucb1x00_mutex);
 static LIST_HEAD(ucb1x00_drivers);
 static LIST_HEAD(ucb1x00_devices);
@@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1
 	return ucb1x00_reg_read(ucb, UCB_IO_DATA);
 }
 
+static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ucb->io_lock, flags);
+	if (value)
+		ucb->io_out |= 1 << offset;
+	else
+		ucb->io_out &= ~(1 << offset);
+
+	ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+	spin_unlock_irqrestore(&ucb->io_lock, flags);
+}
+
+static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+	return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset);
+}
+
+static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ucb->io_lock, flags);
+	ucb->io_dir &= ~(1 << offset);
+	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+	spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+	return 0;
+}
+
+static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
+		, int value)
+{
+	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ucb->io_lock, flags);
+	ucb->io_dir |= (1 << offset);
+	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+
+	if (value)
+		ucb->io_out |= 1 << offset;
+	else
+		ucb->io_out &= ~(1 << offset);
+	ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+	spin_unlock_irqrestore(&ucb->io_lock, flags);
+
+	return 0;
+}
+
 /*
  * UCB1300 data sheet says we must:
  *  1. enable ADC	=> 5us (including reference startup time)
@@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp
 	struct ucb1x00_driver *drv;
 	unsigned int id;
 	int ret = -ENODEV;
+	int temp;
 
 	mcp_enable(mcp);
 	id = mcp_reg_read(mcp, UCB_ID);
@@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp
 		goto err_free;
 	}
 
+	ucb->gpio.base = -1;
+	if (mcp->gpio_base != 0) {
+		ucb->gpio.label = dev_name(&ucb->dev);
+		ucb->gpio.base = mcp->gpio_base;
+		ucb->gpio.ngpio = 10;
+		ucb->gpio.set = ucb1x00_gpio_set;
+		ucb->gpio.get = ucb1x00_gpio_get;
+		ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
+		ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
+		ret = gpiochip_add(&ucb->gpio);
+		if (ret)
+			goto err_free;
+	} else
+		dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
+
 	ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
 			  "UCB1x00", ucb);
 	if (ret) {
 		printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
 			ucb->irq, ret);
-		goto err_free;
+		goto err_gpio;
 	}
 
 	mcp_set_drvdata(mcp, ucb);
@@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp
 	if (ret)
 		goto err_irq;
 
+
 	INIT_LIST_HEAD(&ucb->devs);
 	mutex_lock(&ucb1x00_mutex);
 	list_add(&ucb->node, &ucb1x00_devices);
@@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp
 		ucb1x00_add_dev(ucb, drv);
 	}
 	mutex_unlock(&ucb1x00_mutex);
+
 	goto out;
 
  err_irq:
 	free_irq(ucb->irq, ucb);
+ err_gpio:
+	if (ucb->gpio.base != -1)
+		temp = gpiochip_remove(&ucb->gpio);
  err_free:
 	kfree(ucb);
  err_disable:
@@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *m
 {
 	struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
 	struct list_head *l, *n;
+	int ret;
 
 	mutex_lock(&ucb1x00_mutex);
 	list_del(&ucb->node);
@@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *m
 	}
 	mutex_unlock(&ucb1x00_mutex);
 
+	if (ucb->gpio.base != -1) {
+		ret = gpiochip_remove(&ucb->gpio);
+		if (ret)
+			dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret);
+	}
+
 	free_irq(ucb->irq, ucb);
 	device_unregister(&ucb->dev);
 }
@@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mc
 	struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
 	struct ucb1x00_dev *dev;
 
+	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
 	mutex_lock(&ucb1x00_mutex);
 	list_for_each_entry(dev, &ucb->devs, dev_node) {
 		if (dev->drv->resume)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00.h linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00.h
--- linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,255 +0,0 @@
-/*
- *  linux/drivers/mfd/ucb1x00.h
- *
- *  Copyright (C) 2001 Russell King, 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.
- */
-#ifndef UCB1200_H
-#define UCB1200_H
-
-#define UCB_IO_DATA	0x00
-#define UCB_IO_DIR	0x01
-
-#define UCB_IO_0		(1 << 0)
-#define UCB_IO_1		(1 << 1)
-#define UCB_IO_2		(1 << 2)
-#define UCB_IO_3		(1 << 3)
-#define UCB_IO_4		(1 << 4)
-#define UCB_IO_5		(1 << 5)
-#define UCB_IO_6		(1 << 6)
-#define UCB_IO_7		(1 << 7)
-#define UCB_IO_8		(1 << 8)
-#define UCB_IO_9		(1 << 9)
-
-#define UCB_IE_RIS	0x02
-#define UCB_IE_FAL	0x03
-#define UCB_IE_STATUS	0x04
-#define UCB_IE_CLEAR	0x04
-#define UCB_IE_ADC		(1 << 11)
-#define UCB_IE_TSPX		(1 << 12)
-#define UCB_IE_TSMX		(1 << 13)
-#define UCB_IE_TCLIP		(1 << 14)
-#define UCB_IE_ACLIP		(1 << 15)
-
-#define UCB_IRQ_TSPX		12
-
-#define UCB_TC_A	0x05
-#define UCB_TC_A_LOOP		(1 << 7)	/* UCB1200 */
-#define UCB_TC_A_AMPL		(1 << 7)	/* UCB1300 */
-
-#define UCB_TC_B	0x06
-#define UCB_TC_B_VOICE_ENA	(1 << 3)
-#define UCB_TC_B_CLIP		(1 << 4)
-#define UCB_TC_B_ATT		(1 << 6)
-#define UCB_TC_B_SIDE_ENA	(1 << 11)
-#define UCB_TC_B_MUTE		(1 << 13)
-#define UCB_TC_B_IN_ENA		(1 << 14)
-#define UCB_TC_B_OUT_ENA	(1 << 15)
-
-#define UCB_AC_A	0x07
-#define UCB_AC_B	0x08
-#define UCB_AC_B_LOOP		(1 << 8)
-#define UCB_AC_B_MUTE		(1 << 13)
-#define UCB_AC_B_IN_ENA		(1 << 14)
-#define UCB_AC_B_OUT_ENA	(1 << 15)
-
-#define UCB_TS_CR	0x09
-#define UCB_TS_CR_TSMX_POW	(1 << 0)
-#define UCB_TS_CR_TSPX_POW	(1 << 1)
-#define UCB_TS_CR_TSMY_POW	(1 << 2)
-#define UCB_TS_CR_TSPY_POW	(1 << 3)
-#define UCB_TS_CR_TSMX_GND	(1 << 4)
-#define UCB_TS_CR_TSPX_GND	(1 << 5)
-#define UCB_TS_CR_TSMY_GND	(1 << 6)
-#define UCB_TS_CR_TSPY_GND	(1 << 7)
-#define UCB_TS_CR_MODE_INT	(0 << 8)
-#define UCB_TS_CR_MODE_PRES	(1 << 8)
-#define UCB_TS_CR_MODE_POS	(2 << 8)
-#define UCB_TS_CR_BIAS_ENA	(1 << 11)
-#define UCB_TS_CR_TSPX_LOW	(1 << 12)
-#define UCB_TS_CR_TSMX_LOW	(1 << 13)
-
-#define UCB_ADC_CR	0x0a
-#define UCB_ADC_SYNC_ENA	(1 << 0)
-#define UCB_ADC_VREFBYP_CON	(1 << 1)
-#define UCB_ADC_INP_TSPX	(0 << 2)
-#define UCB_ADC_INP_TSMX	(1 << 2)
-#define UCB_ADC_INP_TSPY	(2 << 2)
-#define UCB_ADC_INP_TSMY	(3 << 2)
-#define UCB_ADC_INP_AD0		(4 << 2)
-#define UCB_ADC_INP_AD1		(5 << 2)
-#define UCB_ADC_INP_AD2		(6 << 2)
-#define UCB_ADC_INP_AD3		(7 << 2)
-#define UCB_ADC_EXT_REF		(1 << 5)
-#define UCB_ADC_START		(1 << 7)
-#define UCB_ADC_ENA		(1 << 15)
-
-#define UCB_ADC_DATA	0x0b
-#define UCB_ADC_DAT_VAL		(1 << 15)
-#define UCB_ADC_DAT(x)		(((x) & 0x7fe0) >> 5)
-
-#define UCB_ID		0x0c
-#define UCB_ID_1200		0x1004
-#define UCB_ID_1300		0x1005
-#define UCB_ID_TC35143          0x9712
-
-#define UCB_MODE	0x0d
-#define UCB_MODE_DYN_VFLAG_ENA	(1 << 12)
-#define UCB_MODE_AUD_OFF_CAN	(1 << 13)
-
-#include "mcp.h"
-
-struct ucb1x00_irq {
-	void *devid;
-	void (*fn)(int, void *);
-};
-
-struct ucb1x00 {
-	spinlock_t		lock;
-	struct mcp		*mcp;
-	unsigned int		irq;
-	struct semaphore	adc_sem;
-	spinlock_t		io_lock;
-	u16			id;
-	u16			io_dir;
-	u16			io_out;
-	u16			adc_cr;
-	u16			irq_fal_enbl;
-	u16			irq_ris_enbl;
-	struct ucb1x00_irq	irq_handler[16];
-	struct device		dev;
-	struct list_head	node;
-	struct list_head	devs;
-};
-
-struct ucb1x00_driver;
-
-struct ucb1x00_dev {
-	struct list_head	dev_node;
-	struct list_head	drv_node;
-	struct ucb1x00		*ucb;
-	struct ucb1x00_driver	*drv;
-	void			*priv;
-};
-
-struct ucb1x00_driver {
-	struct list_head	node;
-	struct list_head	devs;
-	int	(*add)(struct ucb1x00_dev *dev);
-	void	(*remove)(struct ucb1x00_dev *dev);
-	int	(*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
-	int	(*resume)(struct ucb1x00_dev *dev);
-};
-
-#define classdev_to_ucb1x00(cd)	container_of(cd, struct ucb1x00, dev)
-
-int ucb1x00_register_driver(struct ucb1x00_driver *);
-void ucb1x00_unregister_driver(struct ucb1x00_driver *);
-
-/**
- *	ucb1x00_clkrate - return the UCB1x00 SIB clock rate
- *	@ucb: UCB1x00 structure describing chip
- *
- *	Return the SIB clock rate in Hz.
- */
-static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-{
-	return mcp_get_sclk_rate(ucb->mcp);
-}
-
-/**
- *	ucb1x00_enable - enable the UCB1x00 SIB clock
- *	@ucb: UCB1x00 structure describing chip
- *
- *	Enable the SIB clock.  This can be called multiple times.
- */
-static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-{
-	mcp_enable(ucb->mcp);
-}
-
-/**
- *	ucb1x00_disable - disable the UCB1x00 SIB clock
- *	@ucb: UCB1x00 structure describing chip
- *
- *	Disable the SIB clock.  The SIB clock will only be disabled
- *	when the number of ucb1x00_enable calls match the number of
- *	ucb1x00_disable calls.
- */
-static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-{
-	mcp_disable(ucb->mcp);
-}
-
-/**
- *	ucb1x00_reg_write - write a UCB1x00 register
- *	@ucb: UCB1x00 structure describing chip
- *	@reg: UCB1x00 4-bit register index to write
- *	@val: UCB1x00 16-bit value to write
- *
- *	Write the UCB1x00 register @reg with value @val.  The SIB
- *	clock must be running for this function to return.
- */
-static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-{
-	mcp_reg_write(ucb->mcp, reg, val);
-}
-
-/**
- *	ucb1x00_reg_read - read a UCB1x00 register
- *	@ucb: UCB1x00 structure describing chip
- *	@reg: UCB1x00 4-bit register index to write
- *
- *	Read the UCB1x00 register @reg and return its value.  The SIB
- *	clock must be running for this function to return.
- */
-static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-{
-	return mcp_reg_read(ucb->mcp, reg);
-}
-/**
- *	ucb1x00_set_audio_divisor - 
- *	@ucb: UCB1x00 structure describing chip
- *	@div: SIB clock divisor
- */
-static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
-	mcp_set_audio_divisor(ucb->mcp, div);
-}
-
-/**
- *	ucb1x00_set_telecom_divisor -
- *	@ucb: UCB1x00 structure describing chip
- *	@div: SIB clock divisor
- */
-static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-{
-	mcp_set_telecom_divisor(ucb->mcp, div);
-}
-
-void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-
-#define UCB_NOSYNC	(0)
-#define UCB_SYNC	(1)
-
-unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-
-/*
- * Which edges of the IRQ do you want to control today?
- */
-#define UCB_RISING	(1 << 0)
-#define UCB_FALLING	(1 << 1)
-
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-ts.c linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-ts.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/ucb1x00-ts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/ucb1x00-ts.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,12 +30,12 @@
 #include <linux/freezer.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/mfd/ucb1x00.h>
 
 #include <mach/dma.h>
 #include <mach/collie.h>
 #include <asm/mach-types.h>
 
-#include "ucb1x00.h"
 
 
 struct ucb1x00_ts {
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/wm831x-core.c linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/wm831x-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,9 +90,10 @@ int wm831x_isinkv_values[WM831X_ISINK_MA
 EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
 
 enum wm831x_parent {
-	WM8310 = 0,
-	WM8311 = 1,
-	WM8312 = 2,
+	WM8310 = 0x8310,
+	WM8311 = 0x8311,
+	WM8312 = 0x8312,
+	WM8320 = 0x8320,
 };
 
 static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
@@ -478,6 +479,20 @@ static struct resource wm831x_dcdc4_reso
 	},
 };
 
+static struct resource wm8320_dcdc4_buck_resources[] = {
+	{
+		.start = WM831X_DC4_CONTROL,
+		.end   = WM832X_DC4_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_DC4,
+		.end   = WM831X_IRQ_UV_DC4,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
 static struct resource wm831x_gpio_resources[] = {
 	{
 		.start = WM831X_IRQ_GPIO_1,
@@ -794,6 +809,9 @@ static struct resource wm831x_wdt_resour
 
 static struct mfd_cell wm8310_devs[] = {
 	{
+		.name = "wm831x-backup",
+	},
+	{
 		.name = "wm831x-buckv",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
@@ -947,6 +965,9 @@ static struct mfd_cell wm8310_devs[] = {
 
 static struct mfd_cell wm8311_devs[] = {
 	{
+		.name = "wm831x-backup",
+	},
+	{
 		.name = "wm831x-buckv",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
@@ -1081,6 +1102,9 @@ static struct mfd_cell wm8311_devs[] = {
 
 static struct mfd_cell wm8312_devs[] = {
 	{
+		.name = "wm831x-backup",
+	},
+	{
 		.name = "wm831x-buckv",
 		.id = 1,
 		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
@@ -1237,6 +1261,137 @@ static struct mfd_cell wm8312_devs[] = {
 	},
 };
 
+static struct mfd_cell wm8320_devs[] = {
+	{
+		.name = "wm831x-backup",
+	},
+	{
+		.name = "wm831x-buckv",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
+		.resources = wm831x_dcdc1_resources,
+	},
+	{
+		.name = "wm831x-buckv",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
+		.resources = wm831x_dcdc2_resources,
+	},
+	{
+		.name = "wm831x-buckp",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
+		.resources = wm831x_dcdc3_resources,
+	},
+	{
+		.name = "wm831x-buckp",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
+		.resources = wm8320_dcdc4_buck_resources,
+	},
+	{
+		.name = "wm831x-gpio",
+		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
+		.resources = wm831x_gpio_resources,
+	},
+	{
+		.name = "wm831x-hwmon",
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
+		.resources = wm831x_ldo1_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
+		.resources = wm831x_ldo2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
+		.resources = wm831x_ldo3_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
+		.resources = wm831x_ldo4_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
+		.resources = wm831x_ldo5_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
+		.resources = wm831x_ldo6_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
+		.resources = wm831x_ldo7_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
+		.resources = wm831x_ldo8_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
+		.resources = wm831x_ldo9_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
+		.resources = wm831x_ldo10_resources,
+	},
+	{
+		.name = "wm831x-alive-ldo",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
+		.resources = wm831x_ldo11_resources,
+	},
+	{
+		.name = "wm831x-on",
+		.num_resources = ARRAY_SIZE(wm831x_on_resources),
+		.resources = wm831x_on_resources,
+	},
+	{
+		.name = "wm831x-rtc",
+		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
+		.resources = wm831x_rtc_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
+		.resources = wm831x_status1_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
+		.resources = wm831x_status2_resources,
+	},
+	{
+		.name = "wm831x-watchdog",
+		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
+		.resources = wm831x_wdt_resources,
+	},
+};
+
 static struct mfd_cell backlight_devs[] = {
 	{
 		.name = "wm831x-backlight",
@@ -1282,50 +1437,37 @@ static int wm831x_device_init(struct wm8
 		goto err;
 	}
 
+	/* Some engineering samples do not have the ID set, rely on
+	 * the device being registered correctly.
+	 */
+	if (ret == 0) {
+		dev_info(wm831x->dev, "Device is an engineering sample\n");
+		ret = id;
+	}
+
 	switch (ret) {
-	case 0x8310:
+	case WM8310:
 		parent = WM8310;
-		switch (rev) {
-		case 0:
-			dev_info(wm831x->dev, "WM8310 revision %c\n",
-				 'A' + rev);
-			break;
-		}
+		wm831x->num_gpio = 16;
+		dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
 		break;
 
-	case 0x8311:
+	case WM8311:
 		parent = WM8311;
-		switch (rev) {
-		case 0:
-			dev_info(wm831x->dev, "WM8311 revision %c\n",
-				 'A' + rev);
-			break;
-		}
+		wm831x->num_gpio = 16;
+		dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
 		break;
 
-	case 0x8312:
+	case WM8312:
 		parent = WM8312;
-		switch (rev) {
-		case 0:
-			dev_info(wm831x->dev, "WM8312 revision %c\n",
-				 'A' + rev);
-			break;
-		}
+		wm831x->num_gpio = 16;
+		dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
 		break;
 
-	case 0:
-		/* Some engineering samples do not have the ID set,
-		 * rely on the device being registered correctly.
-		 * This will need revisiting for future devices with
-		 * multiple dies.
-		 */
-		parent = id;
-		switch (rev) {
-		case 0:
-			dev_info(wm831x->dev, "WM831%d ES revision %c\n",
-				 parent, 'A' + rev);
-			break;
-		}
+	case WM8320:
+		parent = WM8320;
+		wm831x->num_gpio = 12;
+		dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
 		break;
 
 	default:
@@ -1338,7 +1480,7 @@ static int wm831x_device_init(struct wm8
 	 * current parts.
 	 */
 	if (parent != id)
-		dev_warn(wm831x->dev, "Device was registered as a WM831%lu\n",
+		dev_warn(wm831x->dev, "Device was registered as a WM%lx\n",
 			 id);
 
 	/* Bootstrap the user key */
@@ -1371,18 +1513,24 @@ static int wm831x_device_init(struct wm8
 	case WM8310:
 		ret = mfd_add_devices(wm831x->dev, -1,
 				      wm8310_devs, ARRAY_SIZE(wm8310_devs),
-				      NULL, 0);
+				      NULL, wm831x->irq_base);
 		break;
 
 	case WM8311:
 		ret = mfd_add_devices(wm831x->dev, -1,
 				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
-				      NULL, 0);
+				      NULL, wm831x->irq_base);
 		break;
 
 	case WM8312:
 		ret = mfd_add_devices(wm831x->dev, -1,
 				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
+				      NULL, wm831x->irq_base);
+		break;
+
+	case WM8320:
+		ret = mfd_add_devices(wm831x->dev, -1,
+				      wm8320_devs, ARRAY_SIZE(wm8320_devs),
 				      NULL, 0);
 		break;
 
@@ -1399,7 +1547,8 @@ static int wm831x_device_init(struct wm8
 	if (pdata && pdata->backlight) {
 		/* Treat errors as non-critical */
 		ret = mfd_add_devices(wm831x->dev, -1, backlight_devs,
-				      ARRAY_SIZE(backlight_devs), NULL, 0);
+				      ARRAY_SIZE(backlight_devs), NULL,
+				      wm831x->irq_base);
 		if (ret < 0)
 			dev_err(wm831x->dev, "Failed to add backlight: %d\n",
 				ret);
@@ -1511,6 +1660,7 @@ static const struct i2c_device_id wm831x
 	{ "wm8310", WM8310 },
 	{ "wm8311", WM8311 },
 	{ "wm8312", WM8312 },
+	{ "wm8320", WM8320 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/wm831x-irq.c linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-irq.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/wm831x-irq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/wm831x-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/irq.h>
 #include <linux/mfd/core.h>
 #include <linux/interrupt.h>
 
@@ -339,110 +340,71 @@ static inline int irq_data_to_mask_reg(s
 	return WM831X_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg;
 }
 
-static void __wm831x_enable_irq(struct wm831x *wm831x, int irq)
-{
-	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
-
-	wm831x->irq_masks[irq_data->reg - 1] &= ~irq_data->mask;
-	wm831x_reg_write(wm831x, irq_data_to_mask_reg(irq_data),
-			 wm831x->irq_masks[irq_data->reg - 1]);
-}
-
-void wm831x_enable_irq(struct wm831x *wm831x, int irq)
+static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
+							int irq)
 {
-	mutex_lock(&wm831x->irq_lock);
-	__wm831x_enable_irq(wm831x, irq);
-	mutex_unlock(&wm831x->irq_lock);
+	return &wm831x_irqs[irq - wm831x->irq_base];
 }
-EXPORT_SYMBOL_GPL(wm831x_enable_irq);
 
-static void __wm831x_disable_irq(struct wm831x *wm831x, int irq)
+static void wm831x_irq_lock(unsigned int irq)
 {
-	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
-
-	wm831x->irq_masks[irq_data->reg - 1] |= irq_data->mask;
-	wm831x_reg_write(wm831x, irq_data_to_mask_reg(irq_data),
-			 wm831x->irq_masks[irq_data->reg - 1]);
-}
+	struct wm831x *wm831x = get_irq_chip_data(irq);
 
-void wm831x_disable_irq(struct wm831x *wm831x, int irq)
-{
 	mutex_lock(&wm831x->irq_lock);
-	__wm831x_disable_irq(wm831x, irq);
-	mutex_unlock(&wm831x->irq_lock);
 }
-EXPORT_SYMBOL_GPL(wm831x_disable_irq);
 
-int wm831x_request_irq(struct wm831x *wm831x,
-		       unsigned int irq, irq_handler_t handler,
-		       unsigned long flags, const char *name,
-		       void *dev)
+static void wm831x_irq_sync_unlock(unsigned int irq)
 {
-	int ret = 0;
-
-	if (irq < 0 || irq >= WM831X_NUM_IRQS)
-		return -EINVAL;
-
-	mutex_lock(&wm831x->irq_lock);
+	struct wm831x *wm831x = get_irq_chip_data(irq);
+	int i;
 
-	if (wm831x_irqs[irq].handler) {
-		dev_err(wm831x->dev, "Already have handler for IRQ %d\n", irq);
-		ret = -EINVAL;
-		goto out;
+	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
+		/* If there's been a change in the mask write it back
+		 * to the hardware. */
+		if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {
+			wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];
+			wm831x_reg_write(wm831x,
+					 WM831X_INTERRUPT_STATUS_1_MASK + i,
+					 wm831x->irq_masks_cur[i]);
+		}
 	}
 
-	wm831x_irqs[irq].handler = handler;
-	wm831x_irqs[irq].handler_data = dev;
-
-	__wm831x_enable_irq(wm831x, irq);
-
-out:
 	mutex_unlock(&wm831x->irq_lock);
-
-	return ret;
 }
-EXPORT_SYMBOL_GPL(wm831x_request_irq);
 
-void wm831x_free_irq(struct wm831x *wm831x, unsigned int irq, void *data)
+static void wm831x_irq_unmask(unsigned int irq)
 {
-	if (irq < 0 || irq >= WM831X_NUM_IRQS)
-		return;
-
-	mutex_lock(&wm831x->irq_lock);
-
-	wm831x_irqs[irq].handler = NULL;
-	wm831x_irqs[irq].handler_data = NULL;
-
-	__wm831x_disable_irq(wm831x, irq);
+	struct wm831x *wm831x = get_irq_chip_data(irq);
+	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
-	mutex_unlock(&wm831x->irq_lock);
+	wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
 }
-EXPORT_SYMBOL_GPL(wm831x_free_irq);
-
 
-static void wm831x_handle_irq(struct wm831x *wm831x, int irq, int status)
+static void wm831x_irq_mask(unsigned int irq)
 {
-	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
+	struct wm831x *wm831x = get_irq_chip_data(irq);
+	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq);
 
-	if (irq_data->handler) {
-		irq_data->handler(irq, irq_data->handler_data);
-		wm831x_reg_write(wm831x, irq_data_to_status_reg(irq_data),
-				 irq_data->mask);
-	} else {
-		dev_err(wm831x->dev, "Unhandled IRQ %d, masking\n", irq);
-		__wm831x_disable_irq(wm831x, irq);
-	}
+	wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
 }
 
-/* Main interrupt handling occurs in a workqueue since we need
- * interrupts enabled to interact with the chip. */
-static void wm831x_irq_worker(struct work_struct *work)
+static struct irq_chip wm831x_irq_chip = {
+	.name = "wm831x",
+	.bus_lock = wm831x_irq_lock,
+	.bus_sync_unlock = wm831x_irq_sync_unlock,
+	.mask = wm831x_irq_mask,
+	.unmask = wm831x_irq_unmask,
+};
+
+/* The processing of the primary interrupt occurs in a thread so that
+ * we can interact with the device over I2C or SPI. */
+static irqreturn_t wm831x_irq_thread(int irq, void *data)
 {
-	struct wm831x *wm831x = container_of(work, struct wm831x, irq_work);
+	struct wm831x *wm831x = data;
 	unsigned int i;
 	int primary;
-	int status_regs[5];
-	int read[5] = { 0 };
+	int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
+	int read[WM831X_NUM_IRQ_REGS] = { 0 };
 	int *status;
 
 	primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);
@@ -452,8 +414,6 @@ static void wm831x_irq_worker(struct wor
 		goto out;
 	}
 
-	mutex_lock(&wm831x->irq_lock);
-
 	for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
 		int offset = wm831x_irqs[i].reg - 1;
 
@@ -471,41 +431,34 @@ static void wm831x_irq_worker(struct wor
 				dev_err(wm831x->dev,
 					"Failed to read IRQ status: %d\n",
 					*status);
-				goto out_lock;
+				goto out;
 			}
 
-			/* Mask out the disabled IRQs */
-			*status &= ~wm831x->irq_masks[offset];
 			read[offset] = 1;
 		}
 
-		if (*status & wm831x_irqs[i].mask)
-			wm831x_handle_irq(wm831x, i, *status);
+		/* Report it if it isn't masked, or forget the status. */
+		if ((*status & ~wm831x->irq_masks_cur[offset])
+		    & wm831x_irqs[i].mask)
+			handle_nested_irq(wm831x->irq_base + i);
+		else
+			*status &= ~wm831x_irqs[i].mask;
 	}
 
-out_lock:
-	mutex_unlock(&wm831x->irq_lock);
 out:
-	enable_irq(wm831x->irq);
-}
-
-
-static irqreturn_t wm831x_cpu_irq(int irq, void *data)
-{
-	struct wm831x *wm831x = data;
-
-	/* Shut the interrupt to the CPU up and schedule the actual
-	 * handler; we can't check that the IRQ is asserted. */
-	disable_irq_nosync(irq);
-
-	queue_work(wm831x->irq_wq, &wm831x->irq_work);
+	for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
+		if (status_regs[i])
+			wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
+					 status_regs[i]);
+	}
 
 	return IRQ_HANDLED;
 }
 
 int wm831x_irq_init(struct wm831x *wm831x, int irq)
 {
-	int i, ret;
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int i, cur_irq, ret;
 
 	mutex_init(&wm831x->irq_lock);
 
@@ -515,41 +468,53 @@ int wm831x_irq_init(struct wm831x *wm831
 		return 0;
 	}
 
-
-	wm831x->irq_wq = create_singlethread_workqueue("wm831x-irq");
-	if (!wm831x->irq_wq) {
-		dev_err(wm831x->dev, "Failed to allocate IRQ worker\n");
-		return -ESRCH;
+	if (!pdata || !pdata->irq_base) {
+		dev_err(wm831x->dev,
+			"No interrupt base specified, no interrupts\n");
+		return 0;
 	}
 
 	wm831x->irq = irq;
-	INIT_WORK(&wm831x->irq_work, wm831x_irq_worker);
+	wm831x->irq_base = pdata->irq_base;
 
 	/* Mask the individual interrupt sources */
-	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks); i++) {
-		wm831x->irq_masks[i] = 0xffff;
+	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {
+		wm831x->irq_masks_cur[i] = 0xffff;
+		wm831x->irq_masks_cache[i] = 0xffff;
 		wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,
 				 0xffff);
 	}
 
-	/* Enable top level interrupts, we mask at secondary level */
-	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
+	/* Register them with genirq */
+	for (cur_irq = wm831x->irq_base;
+	     cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base;
+	     cur_irq++) {
+		set_irq_chip_data(cur_irq, wm831x);
+		set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip,
+					 handle_edge_irq);
+		set_irq_nested_thread(cur_irq, 1);
 
-	/* We're good to go.  We set IRQF_SHARED since there's a
-	 * chance the driver will interoperate with another driver but
-	 * the need to disable the IRQ while handing via I2C/SPI means
-	 * that this may break and performance will be impacted.  If
-	 * this does happen it's a hardware design issue and the only
-	 * other alternative would be polling.
-	 */
-	ret = request_irq(irq, wm831x_cpu_irq, IRQF_TRIGGER_LOW | IRQF_SHARED,
-			  "wm831x", wm831x);
+		/* 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(cur_irq, IRQF_VALID);
+#else
+		set_irq_noprobe(cur_irq);
+#endif
+	}
+
+	ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
+				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				   "wm831x", wm831x);
 	if (ret != 0) {
 		dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
 			irq, ret);
 		return ret;
 	}
 
+	/* Enable top level interrupts, we mask at secondary level */
+	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-core.c linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-core.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,8 +134,7 @@ static inline int is_reg_locked(struct w
 	    wm8350->reg_cache[WM8350_SECURITY] == WM8350_UNLOCK_KEY)
 		return 0;
 
-	if ((reg == WM8350_GPIO_CONFIGURATION_I_O) ||
-	    (reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
+	if ((reg >= WM8350_GPIO_FUNCTION_SELECT_1 &&
 	     reg <= WM8350_GPIO_FUNCTION_SELECT_4) ||
 	    (reg >= WM8350_BATTERY_CHARGER_CONTROL_1 &&
 	     reg <= WM8350_BATTERY_CHARGER_CONTROL_3))
@@ -337,733 +336,6 @@ int wm8350_reg_unlock(struct wm8350 *wm8
 }
 EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
 
-static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
-{
-	mutex_lock(&wm8350->irq_mutex);
-
-	if (wm8350->irq[irq].handler)
-		wm8350->irq[irq].handler(wm8350, irq, wm8350->irq[irq].data);
-	else {
-		dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
-			irq);
-		wm8350_mask_irq(wm8350, irq);
-	}
-
-	mutex_unlock(&wm8350->irq_mutex);
-}
-
-/*
- * This is a threaded IRQ handler so can access I2C/SPI.  Since all
- * interrupts are clear on read the IRQ line will be reasserted and
- * the physical IRQ will be handled again if another interrupt is
- * asserted while we run - in the normal course of events this is a
- * rare occurrence so we save I2C/SPI reads.
- */
-static irqreturn_t wm8350_irq(int irq, void *data)
-{
-	struct wm8350 *wm8350 = data;
-	u16 level_one, status1, status2, comp;
-
-	/* TODO: Use block reads to improve performance? */
-	level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
-		& ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
-	status1 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_1)
-		& ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_1_MASK);
-	status2 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_2)
-		& ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_2_MASK);
-	comp = wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS)
-		& ~wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK);
-
-	/* over current */
-	if (level_one & WM8350_OC_INT) {
-		u16 oc;
-
-		oc = wm8350_reg_read(wm8350, WM8350_OVER_CURRENT_INT_STATUS);
-		oc &= ~wm8350_reg_read(wm8350,
-				       WM8350_OVER_CURRENT_INT_STATUS_MASK);
-
-		if (oc & WM8350_OC_LS_EINT)	/* limit switch */
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_OC_LS);
-	}
-
-	/* under voltage */
-	if (level_one & WM8350_UV_INT) {
-		u16 uv;
-
-		uv = wm8350_reg_read(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS);
-		uv &= ~wm8350_reg_read(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK);
-
-		if (uv & WM8350_UV_DC1_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC1);
-		if (uv & WM8350_UV_DC2_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC2);
-		if (uv & WM8350_UV_DC3_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC3);
-		if (uv & WM8350_UV_DC4_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC4);
-		if (uv & WM8350_UV_DC5_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC5);
-		if (uv & WM8350_UV_DC6_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC6);
-		if (uv & WM8350_UV_LDO1_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO1);
-		if (uv & WM8350_UV_LDO2_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO2);
-		if (uv & WM8350_UV_LDO3_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO3);
-		if (uv & WM8350_UV_LDO4_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO4);
-	}
-
-	/* charger, RTC */
-	if (status1) {
-		if (status1 & WM8350_CHG_BAT_HOT_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_BAT_HOT);
-		if (status1 & WM8350_CHG_BAT_COLD_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_BAT_COLD);
-		if (status1 & WM8350_CHG_BAT_FAIL_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_BAT_FAIL);
-		if (status1 & WM8350_CHG_TO_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_TO);
-		if (status1 & WM8350_CHG_END_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_END);
-		if (status1 & WM8350_CHG_START_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_START);
-		if (status1 & WM8350_CHG_FAST_RDY_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_FAST_RDY);
-		if (status1 & WM8350_CHG_VBATT_LT_3P9_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_VBATT_LT_3P9);
-		if (status1 & WM8350_CHG_VBATT_LT_3P1_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_VBATT_LT_3P1);
-		if (status1 & WM8350_CHG_VBATT_LT_2P85_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CHG_VBATT_LT_2P85);
-		if (status1 & WM8350_RTC_ALM_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_ALM);
-		if (status1 & WM8350_RTC_SEC_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_SEC);
-		if (status1 & WM8350_RTC_PER_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_PER);
-	}
-
-	/* current sink, system, aux adc */
-	if (status2) {
-		if (status2 & WM8350_CS1_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS1);
-		if (status2 & WM8350_CS2_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS2);
-
-		if (status2 & WM8350_SYS_HYST_COMP_FAIL_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_SYS_HYST_COMP_FAIL);
-		if (status2 & WM8350_SYS_CHIP_GT115_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_SYS_CHIP_GT115);
-		if (status2 & WM8350_SYS_CHIP_GT140_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_SYS_CHIP_GT140);
-		if (status2 & WM8350_SYS_WDOG_TO_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_SYS_WDOG_TO);
-
-		if (status2 & WM8350_AUXADC_DATARDY_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_AUXADC_DATARDY);
-		if (status2 & WM8350_AUXADC_DCOMP4_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_AUXADC_DCOMP4);
-		if (status2 & WM8350_AUXADC_DCOMP3_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_AUXADC_DCOMP3);
-		if (status2 & WM8350_AUXADC_DCOMP2_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_AUXADC_DCOMP2);
-		if (status2 & WM8350_AUXADC_DCOMP1_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_AUXADC_DCOMP1);
-
-		if (status2 & WM8350_USB_LIMIT_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_USB_LIMIT);
-	}
-
-	/* wake, codec, ext */
-	if (comp) {
-		if (comp & WM8350_WKUP_OFF_STATE_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_OFF_STATE);
-		if (comp & WM8350_WKUP_HIB_STATE_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_HIB_STATE);
-		if (comp & WM8350_WKUP_CONV_FAULT_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_CONV_FAULT);
-		if (comp & WM8350_WKUP_WDOG_RST_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_WDOG_RST);
-		if (comp & WM8350_WKUP_GP_PWR_ON_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_GP_PWR_ON);
-		if (comp & WM8350_WKUP_ONKEY_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_WKUP_ONKEY);
-		if (comp & WM8350_WKUP_GP_WAKEUP_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_WKUP_GP_WAKEUP);
-
-		if (comp & WM8350_CODEC_JCK_DET_L_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CODEC_JCK_DET_L);
-		if (comp & WM8350_CODEC_JCK_DET_R_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CODEC_JCK_DET_R);
-		if (comp & WM8350_CODEC_MICSCD_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_CODEC_MICSCD);
-		if (comp & WM8350_CODEC_MICD_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_CODEC_MICD);
-
-		if (comp & WM8350_EXT_USB_FB_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_USB_FB);
-		if (comp & WM8350_EXT_WALL_FB_EINT)
-			wm8350_irq_call_handler(wm8350,
-						WM8350_IRQ_EXT_WALL_FB);
-		if (comp & WM8350_EXT_BAT_FB_EINT)
-			wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_BAT_FB);
-	}
-
-	if (level_one & WM8350_GP_INT) {
-		int i;
-		u16 gpio;
-
-		gpio = wm8350_reg_read(wm8350, WM8350_GPIO_INT_STATUS);
-		gpio &= ~wm8350_reg_read(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK);
-
-		for (i = 0; i < 12; i++) {
-			if (gpio & (1 << i))
-				wm8350_irq_call_handler(wm8350,
-							WM8350_IRQ_GPIO(i));
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-int wm8350_register_irq(struct wm8350 *wm8350, int irq,
-			void (*handler) (struct wm8350 *, int, void *),
-			void *data)
-{
-	if (irq < 0 || irq > WM8350_NUM_IRQ || !handler)
-		return -EINVAL;
-
-	if (wm8350->irq[irq].handler)
-		return -EBUSY;
-
-	mutex_lock(&wm8350->irq_mutex);
-	wm8350->irq[irq].handler = handler;
-	wm8350->irq[irq].data = data;
-	mutex_unlock(&wm8350->irq_mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_register_irq);
-
-int wm8350_free_irq(struct wm8350 *wm8350, int irq)
-{
-	if (irq < 0 || irq > WM8350_NUM_IRQ)
-		return -EINVAL;
-
-	mutex_lock(&wm8350->irq_mutex);
-	wm8350->irq[irq].handler = NULL;
-	mutex_unlock(&wm8350->irq_mutex);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_free_irq);
-
-int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
-{
-	switch (irq) {
-	case WM8350_IRQ_CHG_BAT_HOT:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_BAT_HOT_EINT);
-	case WM8350_IRQ_CHG_BAT_COLD:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_BAT_COLD_EINT);
-	case WM8350_IRQ_CHG_BAT_FAIL:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_BAT_FAIL_EINT);
-	case WM8350_IRQ_CHG_TO:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_TO_EINT);
-	case WM8350_IRQ_CHG_END:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_END_EINT);
-	case WM8350_IRQ_CHG_START:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_START_EINT);
-	case WM8350_IRQ_CHG_FAST_RDY:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_FAST_RDY_EINT);
-	case WM8350_IRQ_RTC_PER:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_RTC_PER_EINT);
-	case WM8350_IRQ_RTC_SEC:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_RTC_SEC_EINT);
-	case WM8350_IRQ_RTC_ALM:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_RTC_ALM_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_3P9:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_VBATT_LT_3P9_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_3P1:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_VBATT_LT_3P1_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_2P85:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-				       WM8350_IM_CHG_VBATT_LT_2P85_EINT);
-	case WM8350_IRQ_CS1:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_CS1_EINT);
-	case WM8350_IRQ_CS2:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_CS2_EINT);
-	case WM8350_IRQ_USB_LIMIT:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_USB_LIMIT_EINT);
-	case WM8350_IRQ_AUXADC_DATARDY:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_AUXADC_DATARDY_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP4:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_AUXADC_DCOMP4_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP3:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_AUXADC_DCOMP3_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP2:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_AUXADC_DCOMP2_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP1:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_AUXADC_DCOMP1_EINT);
-	case WM8350_IRQ_SYS_HYST_COMP_FAIL:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
-	case WM8350_IRQ_SYS_CHIP_GT115:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_SYS_CHIP_GT115_EINT);
-	case WM8350_IRQ_SYS_CHIP_GT140:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_SYS_CHIP_GT140_EINT);
-	case WM8350_IRQ_SYS_WDOG_TO:
-		return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-				       WM8350_IM_SYS_WDOG_TO_EINT);
-	case WM8350_IRQ_UV_LDO4:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_LDO4_EINT);
-	case WM8350_IRQ_UV_LDO3:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_LDO3_EINT);
-	case WM8350_IRQ_UV_LDO2:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_LDO2_EINT);
-	case WM8350_IRQ_UV_LDO1:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_LDO1_EINT);
-	case WM8350_IRQ_UV_DC6:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC6_EINT);
-	case WM8350_IRQ_UV_DC5:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC5_EINT);
-	case WM8350_IRQ_UV_DC4:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC4_EINT);
-	case WM8350_IRQ_UV_DC3:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC3_EINT);
-	case WM8350_IRQ_UV_DC2:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC2_EINT);
-	case WM8350_IRQ_UV_DC1:
-		return wm8350_set_bits(wm8350,
-				       WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-				       WM8350_IM_UV_DC1_EINT);
-	case WM8350_IRQ_OC_LS:
-		return wm8350_set_bits(wm8350,
-				       WM8350_OVER_CURRENT_INT_STATUS_MASK,
-				       WM8350_IM_OC_LS_EINT);
-	case WM8350_IRQ_EXT_USB_FB:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_EXT_USB_FB_EINT);
-	case WM8350_IRQ_EXT_WALL_FB:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_EXT_WALL_FB_EINT);
-	case WM8350_IRQ_EXT_BAT_FB:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_EXT_BAT_FB_EINT);
-	case WM8350_IRQ_CODEC_JCK_DET_L:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_CODEC_JCK_DET_L_EINT);
-	case WM8350_IRQ_CODEC_JCK_DET_R:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_CODEC_JCK_DET_R_EINT);
-	case WM8350_IRQ_CODEC_MICSCD:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_CODEC_MICSCD_EINT);
-	case WM8350_IRQ_CODEC_MICD:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_CODEC_MICD_EINT);
-	case WM8350_IRQ_WKUP_OFF_STATE:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_OFF_STATE_EINT);
-	case WM8350_IRQ_WKUP_HIB_STATE:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_HIB_STATE_EINT);
-	case WM8350_IRQ_WKUP_CONV_FAULT:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_CONV_FAULT_EINT);
-	case WM8350_IRQ_WKUP_WDOG_RST:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_OFF_STATE_EINT);
-	case WM8350_IRQ_WKUP_GP_PWR_ON:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_GP_PWR_ON_EINT);
-	case WM8350_IRQ_WKUP_ONKEY:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_ONKEY_EINT);
-	case WM8350_IRQ_WKUP_GP_WAKEUP:
-		return wm8350_set_bits(wm8350,
-				       WM8350_COMPARATOR_INT_STATUS_MASK,
-				       WM8350_IM_WKUP_GP_WAKEUP_EINT);
-	case WM8350_IRQ_GPIO(0):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP0_EINT);
-	case WM8350_IRQ_GPIO(1):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP1_EINT);
-	case WM8350_IRQ_GPIO(2):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP2_EINT);
-	case WM8350_IRQ_GPIO(3):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP3_EINT);
-	case WM8350_IRQ_GPIO(4):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP4_EINT);
-	case WM8350_IRQ_GPIO(5):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP5_EINT);
-	case WM8350_IRQ_GPIO(6):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP6_EINT);
-	case WM8350_IRQ_GPIO(7):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP7_EINT);
-	case WM8350_IRQ_GPIO(8):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP8_EINT);
-	case WM8350_IRQ_GPIO(9):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP9_EINT);
-	case WM8350_IRQ_GPIO(10):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP10_EINT);
-	case WM8350_IRQ_GPIO(11):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP11_EINT);
-	case WM8350_IRQ_GPIO(12):
-		return wm8350_set_bits(wm8350,
-				       WM8350_GPIO_INT_STATUS_MASK,
-				       WM8350_IM_GP12_EINT);
-	default:
-		dev_warn(wm8350->dev, "Attempting to mask unknown IRQ %d\n",
-			 irq);
-		return -EINVAL;
-	}
-	return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_mask_irq);
-
-int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
-{
-	switch (irq) {
-	case WM8350_IRQ_CHG_BAT_HOT:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_BAT_HOT_EINT);
-	case WM8350_IRQ_CHG_BAT_COLD:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_BAT_COLD_EINT);
-	case WM8350_IRQ_CHG_BAT_FAIL:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_BAT_FAIL_EINT);
-	case WM8350_IRQ_CHG_TO:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_TO_EINT);
-	case WM8350_IRQ_CHG_END:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_END_EINT);
-	case WM8350_IRQ_CHG_START:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_START_EINT);
-	case WM8350_IRQ_CHG_FAST_RDY:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_FAST_RDY_EINT);
-	case WM8350_IRQ_RTC_PER:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_RTC_PER_EINT);
-	case WM8350_IRQ_RTC_SEC:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_RTC_SEC_EINT);
-	case WM8350_IRQ_RTC_ALM:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_RTC_ALM_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_3P9:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_VBATT_LT_3P9_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_3P1:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_VBATT_LT_3P1_EINT);
-	case WM8350_IRQ_CHG_VBATT_LT_2P85:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
-					 WM8350_IM_CHG_VBATT_LT_2P85_EINT);
-	case WM8350_IRQ_CS1:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_CS1_EINT);
-	case WM8350_IRQ_CS2:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_CS2_EINT);
-	case WM8350_IRQ_USB_LIMIT:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_USB_LIMIT_EINT);
-	case WM8350_IRQ_AUXADC_DATARDY:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_AUXADC_DATARDY_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP4:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_AUXADC_DCOMP4_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP3:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_AUXADC_DCOMP3_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP2:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_AUXADC_DCOMP2_EINT);
-	case WM8350_IRQ_AUXADC_DCOMP1:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_AUXADC_DCOMP1_EINT);
-	case WM8350_IRQ_SYS_HYST_COMP_FAIL:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
-	case WM8350_IRQ_SYS_CHIP_GT115:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_SYS_CHIP_GT115_EINT);
-	case WM8350_IRQ_SYS_CHIP_GT140:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_SYS_CHIP_GT140_EINT);
-	case WM8350_IRQ_SYS_WDOG_TO:
-		return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
-					 WM8350_IM_SYS_WDOG_TO_EINT);
-	case WM8350_IRQ_UV_LDO4:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_LDO4_EINT);
-	case WM8350_IRQ_UV_LDO3:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_LDO3_EINT);
-	case WM8350_IRQ_UV_LDO2:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_LDO2_EINT);
-	case WM8350_IRQ_UV_LDO1:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_LDO1_EINT);
-	case WM8350_IRQ_UV_DC6:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC6_EINT);
-	case WM8350_IRQ_UV_DC5:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC5_EINT);
-	case WM8350_IRQ_UV_DC4:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC4_EINT);
-	case WM8350_IRQ_UV_DC3:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC3_EINT);
-	case WM8350_IRQ_UV_DC2:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC2_EINT);
-	case WM8350_IRQ_UV_DC1:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
-					 WM8350_IM_UV_DC1_EINT);
-	case WM8350_IRQ_OC_LS:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_OVER_CURRENT_INT_STATUS_MASK,
-					 WM8350_IM_OC_LS_EINT);
-	case WM8350_IRQ_EXT_USB_FB:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_EXT_USB_FB_EINT);
-	case WM8350_IRQ_EXT_WALL_FB:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_EXT_WALL_FB_EINT);
-	case WM8350_IRQ_EXT_BAT_FB:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_EXT_BAT_FB_EINT);
-	case WM8350_IRQ_CODEC_JCK_DET_L:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_CODEC_JCK_DET_L_EINT);
-	case WM8350_IRQ_CODEC_JCK_DET_R:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_CODEC_JCK_DET_R_EINT);
-	case WM8350_IRQ_CODEC_MICSCD:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_CODEC_MICSCD_EINT);
-	case WM8350_IRQ_CODEC_MICD:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_CODEC_MICD_EINT);
-	case WM8350_IRQ_WKUP_OFF_STATE:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_OFF_STATE_EINT);
-	case WM8350_IRQ_WKUP_HIB_STATE:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_HIB_STATE_EINT);
-	case WM8350_IRQ_WKUP_CONV_FAULT:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_CONV_FAULT_EINT);
-	case WM8350_IRQ_WKUP_WDOG_RST:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_OFF_STATE_EINT);
-	case WM8350_IRQ_WKUP_GP_PWR_ON:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_GP_PWR_ON_EINT);
-	case WM8350_IRQ_WKUP_ONKEY:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_ONKEY_EINT);
-	case WM8350_IRQ_WKUP_GP_WAKEUP:
-		return wm8350_clear_bits(wm8350,
-					 WM8350_COMPARATOR_INT_STATUS_MASK,
-					 WM8350_IM_WKUP_GP_WAKEUP_EINT);
-	case WM8350_IRQ_GPIO(0):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP0_EINT);
-	case WM8350_IRQ_GPIO(1):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP1_EINT);
-	case WM8350_IRQ_GPIO(2):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP2_EINT);
-	case WM8350_IRQ_GPIO(3):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP3_EINT);
-	case WM8350_IRQ_GPIO(4):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP4_EINT);
-	case WM8350_IRQ_GPIO(5):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP5_EINT);
-	case WM8350_IRQ_GPIO(6):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP6_EINT);
-	case WM8350_IRQ_GPIO(7):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP7_EINT);
-	case WM8350_IRQ_GPIO(8):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP8_EINT);
-	case WM8350_IRQ_GPIO(9):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP9_EINT);
-	case WM8350_IRQ_GPIO(10):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP10_EINT);
-	case WM8350_IRQ_GPIO(11):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP11_EINT);
-	case WM8350_IRQ_GPIO(12):
-		return wm8350_clear_bits(wm8350,
-					 WM8350_GPIO_INT_STATUS_MASK,
-					 WM8350_IM_GP12_EINT);
-	default:
-		dev_warn(wm8350->dev, "Attempting to unmask unknown IRQ %d\n",
-			 irq);
-		return -EINVAL;
-	}
-	return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
-
 int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
 {
 	u16 reg, result = 0;
@@ -1264,7 +536,7 @@ static void wm8350_client_dev_register(s
 	int ret;
 
 	*pdev = platform_device_alloc(name, -1);
-	if (pdev == NULL) {
+	if (*pdev == NULL) {
 		dev_err(wm8350->dev, "Failed to allocate %s\n", name);
 		return;
 	}
@@ -1409,49 +681,18 @@ int wm8350_device_init(struct wm8350 *wm
 		return ret;
 	}
 
-	wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
-	wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
-
 	mutex_init(&wm8350->auxadc_mutex);
-	mutex_init(&wm8350->irq_mutex);
-	if (irq) {
-		int flags = IRQF_ONESHOT;
-
-		if (pdata && pdata->irq_high) {
-			flags |= IRQF_TRIGGER_HIGH;
-
-			wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
-					WM8350_IRQ_POL);
-		} else {
-			flags |= IRQF_TRIGGER_LOW;
 
-			wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
-					  WM8350_IRQ_POL);
-		}
-
-		ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
-					   "wm8350", wm8350);
-		if (ret != 0) {
-			dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
-				ret);
-			goto err;
-		}
-	} else {
-		dev_err(wm8350->dev, "No IRQ configured\n");
+	ret = wm8350_irq_init(wm8350, irq, pdata);
+	if (ret < 0)
 		goto err;
-	}
-	wm8350->chip_irq = irq;
 
 	if (pdata && pdata->init) {
 		ret = pdata->init(wm8350);
 		if (ret != 0) {
 			dev_err(wm8350->dev, "Platform init() failed: %d\n",
 				ret);
-			goto err;
+			goto err_irq;
 		}
 	}
 
@@ -1470,6 +711,8 @@ int wm8350_device_init(struct wm8350 *wm
 
 	return 0;
 
+err_irq:
+	wm8350_irq_exit(wm8350);
 err:
 	kfree(wm8350->reg_cache);
 	return ret;
@@ -1493,7 +736,8 @@ void wm8350_device_exit(struct wm8350 *w
 	platform_device_unregister(wm8350->gpio.pdev);
 	platform_device_unregister(wm8350->codec.pdev);
 
-	free_irq(wm8350->chip_irq, wm8350);
+	wm8350_irq_exit(wm8350);
+
 	kfree(wm8350->reg_cache);
 }
 EXPORT_SYMBOL_GPL(wm8350_device_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-irq.c linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-irq.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-irq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,529 @@
+/*
+ * wm8350-irq.c  --  IRQ support for Wolfson WM8350
+ *
+ * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Liam Girdwood, Mark Brown
+ *
+ *  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/module.h>
+#include <linux/init.h>
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/comparator.h>
+#include <linux/mfd/wm8350/gpio.h>
+#include <linux/mfd/wm8350/pmic.h>
+#include <linux/mfd/wm8350/rtc.h>
+#include <linux/mfd/wm8350/supply.h>
+#include <linux/mfd/wm8350/wdt.h>
+
+#define WM8350_NUM_IRQ_REGS 7
+
+#define WM8350_INT_OFFSET_1                     0
+#define WM8350_INT_OFFSET_2                     1
+#define WM8350_POWER_UP_INT_OFFSET              2
+#define WM8350_UNDER_VOLTAGE_INT_OFFSET         3
+#define WM8350_OVER_CURRENT_INT_OFFSET          4
+#define WM8350_GPIO_INT_OFFSET                  5
+#define WM8350_COMPARATOR_INT_OFFSET            6
+
+struct wm8350_irq_data {
+	int primary;
+	int reg;
+	int mask;
+	int primary_only;
+};
+
+static struct wm8350_irq_data wm8350_irqs[] = {
+	[WM8350_IRQ_OC_LS] = {
+		.primary = WM8350_OC_INT,
+		.reg = WM8350_OVER_CURRENT_INT_OFFSET,
+		.mask = WM8350_OC_LS_EINT,
+		.primary_only = 1,
+	},
+	[WM8350_IRQ_UV_DC1] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC1_EINT,
+	},
+	[WM8350_IRQ_UV_DC2] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC2_EINT,
+	},
+	[WM8350_IRQ_UV_DC3] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC3_EINT,
+	},
+	[WM8350_IRQ_UV_DC4] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC4_EINT,
+	},
+	[WM8350_IRQ_UV_DC5] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC5_EINT,
+	},
+	[WM8350_IRQ_UV_DC6] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_DC6_EINT,
+	},
+	[WM8350_IRQ_UV_LDO1] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_LDO1_EINT,
+	},
+	[WM8350_IRQ_UV_LDO2] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_LDO2_EINT,
+	},
+	[WM8350_IRQ_UV_LDO3] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_LDO3_EINT,
+	},
+	[WM8350_IRQ_UV_LDO4] = {
+		.primary = WM8350_UV_INT,
+		.reg = WM8350_UNDER_VOLTAGE_INT_OFFSET,
+		.mask = WM8350_UV_LDO4_EINT,
+	},
+	[WM8350_IRQ_CHG_BAT_HOT] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_BAT_HOT_EINT,
+	},
+	[WM8350_IRQ_CHG_BAT_COLD] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_BAT_COLD_EINT,
+	},
+	[WM8350_IRQ_CHG_BAT_FAIL] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_BAT_FAIL_EINT,
+	},
+	[WM8350_IRQ_CHG_TO] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_TO_EINT,
+	},
+	[WM8350_IRQ_CHG_END] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_END_EINT,
+	},
+	[WM8350_IRQ_CHG_START] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_START_EINT,
+	},
+	[WM8350_IRQ_CHG_FAST_RDY] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_FAST_RDY_EINT,
+	},
+	[WM8350_IRQ_CHG_VBATT_LT_3P9] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_VBATT_LT_3P9_EINT,
+	},
+	[WM8350_IRQ_CHG_VBATT_LT_3P1] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_VBATT_LT_3P1_EINT,
+	},
+	[WM8350_IRQ_CHG_VBATT_LT_2P85] = {
+		.primary = WM8350_CHG_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_CHG_VBATT_LT_2P85_EINT,
+	},
+	[WM8350_IRQ_RTC_ALM] = {
+		.primary = WM8350_RTC_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_RTC_ALM_EINT,
+	},
+	[WM8350_IRQ_RTC_SEC] = {
+		.primary = WM8350_RTC_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_RTC_SEC_EINT,
+	},
+	[WM8350_IRQ_RTC_PER] = {
+		.primary = WM8350_RTC_INT,
+		.reg = WM8350_INT_OFFSET_1,
+		.mask = WM8350_RTC_PER_EINT,
+	},
+	[WM8350_IRQ_CS1] = {
+		.primary = WM8350_CS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_CS1_EINT,
+	},
+	[WM8350_IRQ_CS2] = {
+		.primary = WM8350_CS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_CS2_EINT,
+	},
+	[WM8350_IRQ_SYS_HYST_COMP_FAIL] = {
+		.primary = WM8350_SYS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_SYS_HYST_COMP_FAIL_EINT,
+	},
+	[WM8350_IRQ_SYS_CHIP_GT115] = {
+		.primary = WM8350_SYS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_SYS_CHIP_GT115_EINT,
+	},
+	[WM8350_IRQ_SYS_CHIP_GT140] = {
+		.primary = WM8350_SYS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_SYS_CHIP_GT140_EINT,
+	},
+	[WM8350_IRQ_SYS_WDOG_TO] = {
+		.primary = WM8350_SYS_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_SYS_WDOG_TO_EINT,
+	},
+	[WM8350_IRQ_AUXADC_DATARDY] = {
+		.primary = WM8350_AUXADC_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_AUXADC_DATARDY_EINT,
+	},
+	[WM8350_IRQ_AUXADC_DCOMP4] = {
+		.primary = WM8350_AUXADC_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_AUXADC_DCOMP4_EINT,
+	},
+	[WM8350_IRQ_AUXADC_DCOMP3] = {
+		.primary = WM8350_AUXADC_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_AUXADC_DCOMP3_EINT,
+	},
+	[WM8350_IRQ_AUXADC_DCOMP2] = {
+		.primary = WM8350_AUXADC_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_AUXADC_DCOMP2_EINT,
+	},
+	[WM8350_IRQ_AUXADC_DCOMP1] = {
+		.primary = WM8350_AUXADC_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_AUXADC_DCOMP1_EINT,
+	},
+	[WM8350_IRQ_USB_LIMIT] = {
+		.primary = WM8350_USB_INT,
+		.reg = WM8350_INT_OFFSET_2,
+		.mask = WM8350_USB_LIMIT_EINT,
+		.primary_only = 1,
+	},
+	[WM8350_IRQ_WKUP_OFF_STATE] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_OFF_STATE_EINT,
+	},
+	[WM8350_IRQ_WKUP_HIB_STATE] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_HIB_STATE_EINT,
+	},
+	[WM8350_IRQ_WKUP_CONV_FAULT] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_CONV_FAULT_EINT,
+	},
+	[WM8350_IRQ_WKUP_WDOG_RST] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_WDOG_RST_EINT,
+	},
+	[WM8350_IRQ_WKUP_GP_PWR_ON] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_GP_PWR_ON_EINT,
+	},
+	[WM8350_IRQ_WKUP_ONKEY] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_ONKEY_EINT,
+	},
+	[WM8350_IRQ_WKUP_GP_WAKEUP] = {
+		.primary = WM8350_WKUP_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_WKUP_GP_WAKEUP_EINT,
+	},
+	[WM8350_IRQ_CODEC_JCK_DET_L] = {
+		.primary = WM8350_CODEC_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_CODEC_JCK_DET_L_EINT,
+	},
+	[WM8350_IRQ_CODEC_JCK_DET_R] = {
+		.primary = WM8350_CODEC_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_CODEC_JCK_DET_R_EINT,
+	},
+	[WM8350_IRQ_CODEC_MICSCD] = {
+		.primary = WM8350_CODEC_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_CODEC_MICSCD_EINT,
+	},
+	[WM8350_IRQ_CODEC_MICD] = {
+		.primary = WM8350_CODEC_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_CODEC_MICD_EINT,
+	},
+	[WM8350_IRQ_EXT_USB_FB] = {
+		.primary = WM8350_EXT_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_EXT_USB_FB_EINT,
+	},
+	[WM8350_IRQ_EXT_WALL_FB] = {
+		.primary = WM8350_EXT_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_EXT_WALL_FB_EINT,
+	},
+	[WM8350_IRQ_EXT_BAT_FB] = {
+		.primary = WM8350_EXT_INT,
+		.reg = WM8350_COMPARATOR_INT_OFFSET,
+		.mask = WM8350_EXT_BAT_FB_EINT,
+	},
+	[WM8350_IRQ_GPIO(0)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP0_EINT,
+	},
+	[WM8350_IRQ_GPIO(1)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP1_EINT,
+	},
+	[WM8350_IRQ_GPIO(2)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP2_EINT,
+	},
+	[WM8350_IRQ_GPIO(3)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP3_EINT,
+	},
+	[WM8350_IRQ_GPIO(4)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP4_EINT,
+	},
+	[WM8350_IRQ_GPIO(5)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP5_EINT,
+	},
+	[WM8350_IRQ_GPIO(6)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP6_EINT,
+	},
+	[WM8350_IRQ_GPIO(7)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP7_EINT,
+	},
+	[WM8350_IRQ_GPIO(8)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP8_EINT,
+	},
+	[WM8350_IRQ_GPIO(9)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP9_EINT,
+	},
+	[WM8350_IRQ_GPIO(10)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP10_EINT,
+	},
+	[WM8350_IRQ_GPIO(11)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP11_EINT,
+	},
+	[WM8350_IRQ_GPIO(12)] = {
+		.primary = WM8350_GP_INT,
+		.reg = WM8350_GPIO_INT_OFFSET,
+		.mask = WM8350_GP12_EINT,
+	},
+};
+
+static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
+{
+	mutex_lock(&wm8350->irq_mutex);
+
+	if (wm8350->irq[irq].handler)
+		wm8350->irq[irq].handler(irq, wm8350->irq[irq].data);
+	else {
+		dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
+			irq);
+		wm8350_mask_irq(wm8350, irq);
+	}
+
+	mutex_unlock(&wm8350->irq_mutex);
+}
+
+/*
+ * This is a threaded IRQ handler so can access I2C/SPI.  Since all
+ * interrupts are clear on read the IRQ line will be reasserted and
+ * the physical IRQ will be handled again if another interrupt is
+ * asserted while we run - in the normal course of events this is a
+ * rare occurrence so we save I2C/SPI reads.
+ */
+static irqreturn_t wm8350_irq(int irq, void *irq_data)
+{
+	struct wm8350 *wm8350 = irq_data;
+	u16 level_one;
+	u16 sub_reg[WM8350_NUM_IRQ_REGS];
+	int read_done[WM8350_NUM_IRQ_REGS];
+	struct wm8350_irq_data *data;
+	int i;
+
+	/* TODO: Use block reads to improve performance? */
+	level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
+		& ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
+
+	if (!level_one)
+		return IRQ_NONE;
+
+	memset(&read_done, 0, sizeof(read_done));
+
+	for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) {
+		data = &wm8350_irqs[i];
+
+		if (!(level_one & data->primary))
+			continue;
+
+		if (!read_done[data->reg]) {
+			sub_reg[data->reg] =
+				wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
+						data->reg);
+			sub_reg[data->reg] &=
+				~wm8350_reg_read(wm8350,
+						 WM8350_INT_STATUS_1_MASK +
+						 data->reg);
+			read_done[data->reg] = 1;
+		}
+
+		if (sub_reg[data->reg] & data->mask)
+			wm8350_irq_call_handler(wm8350, i);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int wm8350_register_irq(struct wm8350 *wm8350, int irq,
+			irq_handler_t handler, unsigned long flags,
+			const char *name, void *data)
+{
+	if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler)
+		return -EINVAL;
+
+	if (wm8350->irq[irq].handler)
+		return -EBUSY;
+
+	mutex_lock(&wm8350->irq_mutex);
+	wm8350->irq[irq].handler = handler;
+	wm8350->irq[irq].data = data;
+	mutex_unlock(&wm8350->irq_mutex);
+
+	wm8350_unmask_irq(wm8350, irq);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wm8350_register_irq);
+
+int wm8350_free_irq(struct wm8350 *wm8350, int irq)
+{
+	if (irq < 0 || irq >= WM8350_NUM_IRQ)
+		return -EINVAL;
+
+	wm8350_mask_irq(wm8350, irq);
+
+	mutex_lock(&wm8350->irq_mutex);
+	wm8350->irq[irq].handler = NULL;
+	mutex_unlock(&wm8350->irq_mutex);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wm8350_free_irq);
+
+int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
+{
+	return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK +
+			       wm8350_irqs[irq].reg,
+			       wm8350_irqs[irq].mask);
+}
+EXPORT_SYMBOL_GPL(wm8350_mask_irq);
+
+int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
+{
+	return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK +
+				 wm8350_irqs[irq].reg,
+				 wm8350_irqs[irq].mask);
+}
+EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
+
+int wm8350_irq_init(struct wm8350 *wm8350, int irq,
+		    struct wm8350_platform_data *pdata)
+{
+	int ret;
+	int flags = IRQF_ONESHOT;
+
+	if (!irq) {
+		dev_err(wm8350->dev, "No IRQ configured\n");
+		return -EINVAL;
+	}
+
+	wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
+	wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
+	wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
+	wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
+	wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
+	wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
+
+	mutex_init(&wm8350->irq_mutex);
+	wm8350->chip_irq = irq;
+
+	if (pdata && pdata->irq_high) {
+		flags |= IRQF_TRIGGER_HIGH;
+
+		wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+				WM8350_IRQ_POL);
+	} else {
+		flags |= IRQF_TRIGGER_LOW;
+
+		wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+				  WM8350_IRQ_POL);
+	}
+
+	ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
+				   "wm8350", wm8350);
+	if (ret != 0)
+		dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
+
+	return ret;
+}
+
+int wm8350_irq_exit(struct wm8350 *wm8350)
+{
+	free_irq(wm8350->chip_irq, wm8350);
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-regmap.c linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-regmap.c
--- linux-libre-2.6.32-gnu1/drivers/mfd/wm8350-regmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mfd/wm8350-regmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -3170,14 +3170,6 @@ const u16 wm8352_mode3_defaults[] = {
 };
 #endif
 
-/* The register defaults for the config mode used must be compiled in but
- * due to the impact on kernel size it is possible to disable
- */
-#ifndef WM8350_HAVE_CONFIG_MODE
-#warning No WM8350 config modes supported - select at least one of the
-#warning MFD_WM8350_CONFIG_MODE_n options from the board driver.
-#endif
-
 /*
  * Access masks.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/ad525x_dpot.c linux-libre-2.6.33-gnu1/drivers/misc/ad525x_dpot.c
--- linux-libre-2.6.32-gnu1/drivers/misc/ad525x_dpot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/ad525x_dpot.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,666 @@
+/*
+ * ad525x_dpot: Driver for the Analog Devices AD525x digital potentiometers
+ * Copyright (c) 2009 Analog Devices, Inc.
+ * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
+ *
+ * DEVID		#Wipers		#Positions 	Resistor Options (kOhm)
+ * AD5258		1		64		1, 10, 50, 100
+ * AD5259		1		256		5, 10, 50, 100
+ * AD5251		2		64		1, 10, 50, 100
+ * AD5252		2		256		1, 10, 50, 100
+ * AD5255		3		512		25, 250
+ * AD5253		4		64		1, 10, 50, 100
+ * AD5254		4		256		1, 10, 50, 100
+ *
+ * See Documentation/misc-devices/ad525x_dpot.txt for more info.
+ *
+ * derived from ad5258.c
+ * Copyright (c) 2009 Cyber Switching, Inc.
+ * Author: Chris Verges <chrisv@cyberswitching.com>
+ *
+ * derived from ad5252.c
+ * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+
+#define DRIVER_NAME			"ad525x_dpot"
+#define DRIVER_VERSION			"0.1"
+
+enum dpot_devid {
+	AD5258_ID,
+	AD5259_ID,
+	AD5251_ID,
+	AD5252_ID,
+	AD5253_ID,
+	AD5254_ID,
+	AD5255_ID,
+};
+
+#define AD5258_MAX_POSITION		64
+#define AD5259_MAX_POSITION		256
+#define AD5251_MAX_POSITION		64
+#define AD5252_MAX_POSITION		256
+#define AD5253_MAX_POSITION		64
+#define AD5254_MAX_POSITION		256
+#define AD5255_MAX_POSITION		512
+
+#define AD525X_RDAC0		0
+#define AD525X_RDAC1		1
+#define AD525X_RDAC2		2
+#define AD525X_RDAC3		3
+
+#define AD525X_REG_TOL		0x18
+#define AD525X_TOL_RDAC0	(AD525X_REG_TOL | AD525X_RDAC0)
+#define AD525X_TOL_RDAC1	(AD525X_REG_TOL | AD525X_RDAC1)
+#define AD525X_TOL_RDAC2	(AD525X_REG_TOL | AD525X_RDAC2)
+#define AD525X_TOL_RDAC3	(AD525X_REG_TOL | AD525X_RDAC3)
+
+/* RDAC-to-EEPROM Interface Commands */
+#define AD525X_I2C_RDAC		(0x00 << 5)
+#define AD525X_I2C_EEPROM	(0x01 << 5)
+#define AD525X_I2C_CMD		(0x80)
+
+#define AD525X_DEC_ALL_6DB	(AD525X_I2C_CMD | (0x4 << 3))
+#define AD525X_INC_ALL_6DB	(AD525X_I2C_CMD | (0x9 << 3))
+#define AD525X_DEC_ALL		(AD525X_I2C_CMD | (0x6 << 3))
+#define AD525X_INC_ALL		(AD525X_I2C_CMD | (0xB << 3))
+
+static s32 ad525x_read(struct i2c_client *client, u8 reg);
+static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value);
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct dpot_data {
+	struct mutex update_lock;
+	unsigned rdac_mask;
+	unsigned max_pos;
+	unsigned devid;
+};
+
+/* sysfs functions */
+
+static ssize_t sysfs_show_reg(struct device *dev,
+			      struct device_attribute *attr, char *buf, u32 reg)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dpot_data *data = i2c_get_clientdata(client);
+	s32 value;
+
+	mutex_lock(&data->update_lock);
+	value = ad525x_read(client, reg);
+	mutex_unlock(&data->update_lock);
+
+	if (value < 0)
+		return -EINVAL;
+	/*
+	 * Let someone else deal with converting this ...
+	 * the tolerance is a two-byte value where the MSB
+	 * is a sign + integer value, and the LSB is a
+	 * decimal value.  See page 18 of the AD5258
+	 * datasheet (Rev. A) for more details.
+	 */
+
+	if (reg & AD525X_REG_TOL)
+		return sprintf(buf, "0x%04x\n", value & 0xFFFF);
+	else
+		return sprintf(buf, "%u\n", value & data->rdac_mask);
+}
+
+static ssize_t sysfs_set_reg(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count, u32 reg)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dpot_data *data = i2c_get_clientdata(client);
+	unsigned long value;
+	int err;
+
+	err = strict_strtoul(buf, 10, &value);
+	if (err)
+		return err;
+
+	if (value > data->rdac_mask)
+		value = data->rdac_mask;
+
+	mutex_lock(&data->update_lock);
+	ad525x_write(client, reg, value);
+	if (reg & AD525X_I2C_EEPROM)
+		msleep(26);	/* Sleep while the EEPROM updates */
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t sysfs_do_cmd(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count, u32 reg)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dpot_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+	ad525x_write(client, reg, 0);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static ssize_t show_rdac0(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC0);
+}
+
+static ssize_t set_rdac0(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_RDAC | AD525X_RDAC0);
+}
+
+static DEVICE_ATTR(rdac0, S_IWUSR | S_IRUGO, show_rdac0, set_rdac0);
+
+static ssize_t show_eeprom0(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC0);
+}
+
+static ssize_t set_eeprom0(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_EEPROM | AD525X_RDAC0);
+}
+
+static DEVICE_ATTR(eeprom0, S_IWUSR | S_IRUGO, show_eeprom0, set_eeprom0);
+
+static ssize_t show_tolerance0(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf,
+			      AD525X_I2C_EEPROM | AD525X_TOL_RDAC0);
+}
+
+static DEVICE_ATTR(tolerance0, S_IRUGO, show_tolerance0, NULL);
+
+/* ------------------------------------------------------------------------- */
+
+static ssize_t show_rdac1(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC1);
+}
+
+static ssize_t set_rdac1(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_RDAC | AD525X_RDAC1);
+}
+
+static DEVICE_ATTR(rdac1, S_IWUSR | S_IRUGO, show_rdac1, set_rdac1);
+
+static ssize_t show_eeprom1(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC1);
+}
+
+static ssize_t set_eeprom1(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_EEPROM | AD525X_RDAC1);
+}
+
+static DEVICE_ATTR(eeprom1, S_IWUSR | S_IRUGO, show_eeprom1, set_eeprom1);
+
+static ssize_t show_tolerance1(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf,
+			      AD525X_I2C_EEPROM | AD525X_TOL_RDAC1);
+}
+
+static DEVICE_ATTR(tolerance1, S_IRUGO, show_tolerance1, NULL);
+
+/* ------------------------------------------------------------------------- */
+
+static ssize_t show_rdac2(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC2);
+}
+
+static ssize_t set_rdac2(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_RDAC | AD525X_RDAC2);
+}
+
+static DEVICE_ATTR(rdac2, S_IWUSR | S_IRUGO, show_rdac2, set_rdac2);
+
+static ssize_t show_eeprom2(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC2);
+}
+
+static ssize_t set_eeprom2(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_EEPROM | AD525X_RDAC2);
+}
+
+static DEVICE_ATTR(eeprom2, S_IWUSR | S_IRUGO, show_eeprom2, set_eeprom2);
+
+static ssize_t show_tolerance2(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf,
+			      AD525X_I2C_EEPROM | AD525X_TOL_RDAC2);
+}
+
+static DEVICE_ATTR(tolerance2, S_IRUGO, show_tolerance2, NULL);
+
+/* ------------------------------------------------------------------------- */
+
+static ssize_t show_rdac3(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC3);
+}
+
+static ssize_t set_rdac3(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_RDAC | AD525X_RDAC3);
+}
+
+static DEVICE_ATTR(rdac3, S_IWUSR | S_IRUGO, show_rdac3, set_rdac3);
+
+static ssize_t show_eeprom3(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC3);
+}
+
+static ssize_t set_eeprom3(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_set_reg(dev, attr, buf, count,
+			     AD525X_I2C_EEPROM | AD525X_RDAC3);
+}
+
+static DEVICE_ATTR(eeprom3, S_IWUSR | S_IRUGO, show_eeprom3, set_eeprom3);
+
+static ssize_t show_tolerance3(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	return sysfs_show_reg(dev, attr, buf,
+			      AD525X_I2C_EEPROM | AD525X_TOL_RDAC3);
+}
+
+static DEVICE_ATTR(tolerance3, S_IRUGO, show_tolerance3, NULL);
+
+static struct attribute *ad525x_attributes_wipers[4][4] = {
+	{
+		&dev_attr_rdac0.attr,
+		&dev_attr_eeprom0.attr,
+		&dev_attr_tolerance0.attr,
+		NULL
+	}, {
+		&dev_attr_rdac1.attr,
+		&dev_attr_eeprom1.attr,
+		&dev_attr_tolerance1.attr,
+		NULL
+	}, {
+		&dev_attr_rdac2.attr,
+		&dev_attr_eeprom2.attr,
+		&dev_attr_tolerance2.attr,
+		NULL
+	}, {
+		&dev_attr_rdac3.attr,
+		&dev_attr_eeprom3.attr,
+		&dev_attr_tolerance3.attr,
+		NULL
+	}
+};
+
+static const struct attribute_group ad525x_group_wipers[] = {
+	{.attrs = ad525x_attributes_wipers[AD525X_RDAC0]},
+	{.attrs = ad525x_attributes_wipers[AD525X_RDAC1]},
+	{.attrs = ad525x_attributes_wipers[AD525X_RDAC2]},
+	{.attrs = ad525x_attributes_wipers[AD525X_RDAC3]},
+};
+
+/* ------------------------------------------------------------------------- */
+
+static ssize_t set_inc_all(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_do_cmd(dev, attr, buf, count, AD525X_INC_ALL);
+}
+
+static DEVICE_ATTR(inc_all, S_IWUSR, NULL, set_inc_all);
+
+static ssize_t set_dec_all(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	return sysfs_do_cmd(dev, attr, buf, count, AD525X_DEC_ALL);
+}
+
+static DEVICE_ATTR(dec_all, S_IWUSR, NULL, set_dec_all);
+
+static ssize_t set_inc_all_6db(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	return sysfs_do_cmd(dev, attr, buf, count, AD525X_INC_ALL_6DB);
+}
+
+static DEVICE_ATTR(inc_all_6db, S_IWUSR, NULL, set_inc_all_6db);
+
+static ssize_t set_dec_all_6db(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	return sysfs_do_cmd(dev, attr, buf, count, AD525X_DEC_ALL_6DB);
+}
+
+static DEVICE_ATTR(dec_all_6db, S_IWUSR, NULL, set_dec_all_6db);
+
+static struct attribute *ad525x_attributes_commands[] = {
+	&dev_attr_inc_all.attr,
+	&dev_attr_dec_all.attr,
+	&dev_attr_inc_all_6db.attr,
+	&dev_attr_dec_all_6db.attr,
+	NULL
+};
+
+static const struct attribute_group ad525x_group_commands = {
+	.attrs = ad525x_attributes_commands,
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* i2c device functions */
+
+/**
+ * ad525x_read - return the value contained in the specified register
+ * on the AD5258 device.
+ * @client: value returned from i2c_new_device()
+ * @reg: the register to read
+ *
+ * If the tolerance register is specified, 2 bytes are returned.
+ * Otherwise, 1 byte is returned.  A negative value indicates an error
+ * occurred while reading the register.
+ */
+static s32 ad525x_read(struct i2c_client *client, u8 reg)
+{
+	struct dpot_data *data = i2c_get_clientdata(client);
+
+	if ((reg & AD525X_REG_TOL) || (data->max_pos > 256))
+		return i2c_smbus_read_word_data(client, (reg & 0xF8) |
+						((reg & 0x7) << 1));
+	else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+/**
+ * ad525x_write - store the given value in the specified register on
+ * the AD5258 device.
+ * @client: value returned from i2c_new_device()
+ * @reg: the register to write
+ * @value: the byte to store in the register
+ *
+ * For certain instructions that do not require a data byte, "NULL"
+ * should be specified for the "value" parameter.  These instructions
+ * include NOP, RESTORE_FROM_EEPROM, and STORE_TO_EEPROM.
+ *
+ * A negative return value indicates an error occurred while reading
+ * the register.
+ */
+static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value)
+{
+	struct dpot_data *data = i2c_get_clientdata(client);
+
+	/* Only write the instruction byte for certain commands */
+	if (reg & AD525X_I2C_CMD)
+		return i2c_smbus_write_byte(client, reg);
+
+	if (data->max_pos > 256)
+		return i2c_smbus_write_word_data(client, (reg & 0xF8) |
+						((reg & 0x7) << 1), value);
+	else
+		/* All other registers require instruction + data bytes */
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int ad525x_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct dpot_data *data;
+	int err = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(dev, "missing I2C functionality for this driver\n");
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	switch (id->driver_data) {
+	case AD5258_ID:
+		data->max_pos = AD5258_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC0]);
+		break;
+	case AD5259_ID:
+		data->max_pos = AD5259_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC0]);
+		break;
+	case AD5251_ID:
+		data->max_pos = AD5251_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC1]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC3]);
+		err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5252_ID:
+		data->max_pos = AD5252_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC1]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC3]);
+		err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5253_ID:
+		data->max_pos = AD5253_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC0]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC1]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC2]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC3]);
+		err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5254_ID:
+		data->max_pos = AD5254_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC0]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC1]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC2]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC3]);
+		err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5255_ID:
+		data->max_pos = AD5255_MAX_POSITION;
+		err = sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC0]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC1]);
+		err |= sysfs_create_group(&dev->kobj,
+				       &ad525x_group_wipers[AD525X_RDAC2]);
+		err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	default:
+		err = -ENODEV;
+		goto exit_free;
+	}
+
+	if (err) {
+		dev_err(dev, "failed to register sysfs hooks\n");
+		goto exit_free;
+	}
+
+	data->devid = id->driver_data;
+	data->rdac_mask = data->max_pos - 1;
+
+	dev_info(dev, "%s %d-Position Digital Potentiometer registered\n",
+		 id->name, data->max_pos);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+	i2c_set_clientdata(client, NULL);
+exit:
+	dev_err(dev, "failed to create client\n");
+	return err;
+}
+
+static int __devexit ad525x_remove(struct i2c_client *client)
+{
+	struct dpot_data *data = i2c_get_clientdata(client);
+	struct device *dev = &client->dev;
+
+	switch (data->devid) {
+	case AD5258_ID:
+	case AD5259_ID:
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC0]);
+		break;
+	case AD5251_ID:
+	case AD5252_ID:
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC1]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC3]);
+		sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5253_ID:
+	case AD5254_ID:
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC0]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC1]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC2]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC3]);
+		sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	case AD5255_ID:
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC0]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC1]);
+		sysfs_remove_group(&dev->kobj,
+				   &ad525x_group_wipers[AD525X_RDAC2]);
+		sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
+		break;
+	}
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad525x_idtable[] = {
+	{"ad5258", AD5258_ID},
+	{"ad5259", AD5259_ID},
+	{"ad5251", AD5251_ID},
+	{"ad5252", AD5252_ID},
+	{"ad5253", AD5253_ID},
+	{"ad5254", AD5254_ID},
+	{"ad5255", AD5255_ID},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, ad525x_idtable);
+
+static struct i2c_driver ad525x_driver = {
+	.driver = {
+		   .owner = THIS_MODULE,
+		   .name = DRIVER_NAME,
+		   },
+	.id_table = ad525x_idtable,
+	.probe = ad525x_probe,
+	.remove = __devexit_p(ad525x_remove),
+};
+
+static int __init ad525x_init(void)
+{
+	return i2c_add_driver(&ad525x_driver);
+}
+
+module_init(ad525x_init);
+
+static void __exit ad525x_exit(void)
+{
+	i2c_del_driver(&ad525x_driver);
+}
+
+module_exit(ad525x_exit);
+
+MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
+	      "Michael Hennerich <hennerich@blackfin.uclinux.org>, ");
+MODULE_DESCRIPTION("AD5258/9 digital potentiometer driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/cs5535-mfgpt.c linux-libre-2.6.33-gnu1/drivers/misc/cs5535-mfgpt.c
--- linux-libre-2.6.32-gnu1/drivers/misc/cs5535-mfgpt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/cs5535-mfgpt.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,370 @@
+/*
+ * Driver for the CS5535/CS5536 Multi-Function General Purpose Timers (MFGPT)
+ *
+ * Copyright (C) 2006, Advanced Micro Devices, Inc.
+ * Copyright (C) 2007  Andres Salomon <dilinger@debian.org>
+ * Copyright (C) 2009  Andres Salomon <dilinger@collabora.co.uk>
+ *
+ * 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.
+ *
+ * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/cs5535.h>
+
+#define DRV_NAME "cs5535-mfgpt"
+#define MFGPT_BAR 2
+
+static int mfgpt_reset_timers;
+module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644);
+MODULE_PARM_DESC(mfgptfix, "Reset the MFGPT timers during init; "
+		"required by some broken BIOSes (ie, TinyBIOS < 0.99).");
+
+struct cs5535_mfgpt_timer {
+	struct cs5535_mfgpt_chip *chip;
+	int nr;
+};
+
+static struct cs5535_mfgpt_chip {
+	DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS);
+	resource_size_t base;
+
+	struct pci_dev *pdev;
+	spinlock_t lock;
+	int initialized;
+} cs5535_mfgpt_chip;
+
+int cs5535_mfgpt_toggle_event(struct cs5535_mfgpt_timer *timer, int cmp,
+		int event, int enable)
+{
+	uint32_t msr, mask, value, dummy;
+	int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
+
+	if (!timer) {
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	/*
+	 * The register maps for these are described in sections 6.17.1.x of
+	 * the AMD Geode CS5536 Companion Device Data Book.
+	 */
+	switch (event) {
+	case MFGPT_EVENT_RESET:
+		/*
+		 * XXX: According to the docs, we cannot reset timers above
+		 * 6; that is, resets for 7 and 8 will be ignored.  Is this
+		 * a problem?   -dilinger
+		 */
+		msr = MSR_MFGPT_NR;
+		mask = 1 << (timer->nr + 24);
+		break;
+
+	case MFGPT_EVENT_NMI:
+		msr = MSR_MFGPT_NR;
+		mask = 1 << (timer->nr + shift);
+		break;
+
+	case MFGPT_EVENT_IRQ:
+		msr = MSR_MFGPT_IRQ;
+		mask = 1 << (timer->nr + shift);
+		break;
+
+	default:
+		return -EIO;
+	}
+
+	rdmsr(msr, value, dummy);
+
+	if (enable)
+		value |= mask;
+	else
+		value &= ~mask;
+
+	wrmsr(msr, value, dummy);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_toggle_event);
+
+int cs5535_mfgpt_set_irq(struct cs5535_mfgpt_timer *timer, int cmp, int *irq,
+		int enable)
+{
+	uint32_t zsel, lpc, dummy;
+	int shift;
+
+	if (!timer) {
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	/*
+	 * Unfortunately, MFGPTs come in pairs sharing their IRQ lines. If VSA
+	 * is using the same CMP of the timer's Siamese twin, the IRQ is set to
+	 * 2, and we mustn't use nor change it.
+	 * XXX: Likewise, 2 Linux drivers might clash if the 2nd overwrites the
+	 * IRQ of the 1st. This can only happen if forcing an IRQ, calling this
+	 * with *irq==0 is safe. Currently there _are_ no 2 drivers.
+	 */
+	rdmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
+	shift = ((cmp == MFGPT_CMP1 ? 0 : 4) + timer->nr % 4) * 4;
+	if (((zsel >> shift) & 0xF) == 2)
+		return -EIO;
+
+	/* Choose IRQ: if none supplied, keep IRQ already set or use default */
+	if (!*irq)
+		*irq = (zsel >> shift) & 0xF;
+	if (!*irq)
+		*irq = CONFIG_CS5535_MFGPT_DEFAULT_IRQ;
+
+	/* Can't use IRQ if it's 0 (=disabled), 2, or routed to LPC */
+	if (*irq < 1 || *irq == 2 || *irq > 15)
+		return -EIO;
+	rdmsr(MSR_PIC_IRQM_LPC, lpc, dummy);
+	if (lpc & (1 << *irq))
+		return -EIO;
+
+	/* All chosen and checked - go for it */
+	if (cs5535_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
+		return -EIO;
+	if (enable) {
+		zsel = (zsel & ~(0xF << shift)) | (*irq << shift);
+		wrmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_set_irq);
+
+struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer_nr, int domain)
+{
+	struct cs5535_mfgpt_chip *mfgpt = &cs5535_mfgpt_chip;
+	struct cs5535_mfgpt_timer *timer = NULL;
+	unsigned long flags;
+	int max;
+
+	if (!mfgpt->initialized)
+		goto done;
+
+	/* only allocate timers from the working domain if requested */
+	if (domain == MFGPT_DOMAIN_WORKING)
+		max = 6;
+	else
+		max = MFGPT_MAX_TIMERS;
+
+	if (timer_nr >= max) {
+		/* programmer error.  silly programmers! */
+		WARN_ON(1);
+		goto done;
+	}
+
+	spin_lock_irqsave(&mfgpt->lock, flags);
+	if (timer_nr < 0) {
+		unsigned long t;
+
+		/* try to find any available timer */
+		t = find_first_bit(mfgpt->avail, max);
+		/* set timer_nr to -1 if no timers available */
+		timer_nr = t < max ? (int) t : -1;
+	} else {
+		/* check if the requested timer's available */
+		if (test_bit(timer_nr, mfgpt->avail))
+			timer_nr = -1;
+	}
+
+	if (timer_nr >= 0)
+		/* if timer_nr is not -1, it's an available timer */
+		__clear_bit(timer_nr, mfgpt->avail);
+	spin_unlock_irqrestore(&mfgpt->lock, flags);
+
+	if (timer_nr < 0)
+		goto done;
+
+	timer = kmalloc(sizeof(*timer), GFP_KERNEL);
+	if (!timer) {
+		/* aw hell */
+		spin_lock_irqsave(&mfgpt->lock, flags);
+		__set_bit(timer_nr, mfgpt->avail);
+		spin_unlock_irqrestore(&mfgpt->lock, flags);
+		goto done;
+	}
+	timer->chip = mfgpt;
+	timer->nr = timer_nr;
+	dev_info(&mfgpt->pdev->dev, "registered timer %d\n", timer_nr);
+
+done:
+	return timer;
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_alloc_timer);
+
+/*
+ * XXX: This frees the timer memory, but never resets the actual hardware
+ * timer.  The old geode_mfgpt code did this; it would be good to figure
+ * out a way to actually release the hardware timer.  See comments below.
+ */
+void cs5535_mfgpt_free_timer(struct cs5535_mfgpt_timer *timer)
+{
+	kfree(timer);
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_free_timer);
+
+uint16_t cs5535_mfgpt_read(struct cs5535_mfgpt_timer *timer, uint16_t reg)
+{
+	return inw(timer->chip->base + reg + (timer->nr * 8));
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_read);
+
+void cs5535_mfgpt_write(struct cs5535_mfgpt_timer *timer, uint16_t reg,
+		uint16_t value)
+{
+	outw(value, timer->chip->base + reg + (timer->nr * 8));
+}
+EXPORT_SYMBOL_GPL(cs5535_mfgpt_write);
+
+/*
+ * This is a sledgehammer that resets all MFGPT timers. This is required by
+ * some broken BIOSes which leave the system in an unstable state
+ * (TinyBIOS 0.98, for example; fixed in 0.99).  It's uncertain as to
+ * whether or not this secret MSR can be used to release individual timers.
+ * Jordan tells me that he and Mitch once played w/ it, but it's unclear
+ * what the results of that were (and they experienced some instability).
+ */
+static void __init reset_all_timers(void)
+{
+	uint32_t val, dummy;
+
+	/* The following undocumented bit resets the MFGPT timers */
+	val = 0xFF; dummy = 0;
+	wrmsr(MSR_MFGPT_SETUP, val, dummy);
+}
+
+/*
+ * Check whether any MFGPTs are available for the kernel to use.  In most
+ * cases, firmware that uses AMD's VSA code will claim all timers during
+ * bootup; we certainly don't want to take them if they're already in use.
+ * In other cases (such as with VSAless OpenFirmware), the system firmware
+ * leaves timers available for us to use.
+ */
+static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt)
+{
+	struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
+	unsigned long flags;
+	int timers = 0;
+	uint16_t val;
+	int i;
+
+	/* bios workaround */
+	if (mfgpt_reset_timers)
+		reset_all_timers();
+
+	/* just to be safe, protect this section w/ lock */
+	spin_lock_irqsave(&mfgpt->lock, flags);
+	for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
+		timer.nr = i;
+		val = cs5535_mfgpt_read(&timer, MFGPT_REG_SETUP);
+		if (!(val & MFGPT_SETUP_SETUP)) {
+			__set_bit(i, mfgpt->avail);
+			timers++;
+		}
+	}
+	spin_unlock_irqrestore(&mfgpt->lock, flags);
+
+	return timers;
+}
+
+static int __init cs5535_mfgpt_probe(struct pci_dev *pdev,
+		const struct pci_device_id *pci_id)
+{
+	int err, t;
+
+	/* There are two ways to get the MFGPT base address; one is by
+	 * fetching it from MSR_LBAR_MFGPT, the other is by reading the
+	 * PCI BAR info.  The latter method is easier (especially across
+	 * different architectures), so we'll stick with that for now.  If
+	 * it turns out to be unreliable in the face of crappy BIOSes, we
+	 * can always go back to using MSRs.. */
+
+	err = pci_enable_device_io(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "can't enable device IO\n");
+		goto done;
+	}
+
+	err = pci_request_region(pdev, MFGPT_BAR, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", MFGPT_BAR);
+		goto done;
+	}
+
+	/* set up the driver-specific struct */
+	cs5535_mfgpt_chip.base = pci_resource_start(pdev, MFGPT_BAR);
+	cs5535_mfgpt_chip.pdev = pdev;
+	spin_lock_init(&cs5535_mfgpt_chip.lock);
+
+	dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", MFGPT_BAR,
+			(unsigned long long) cs5535_mfgpt_chip.base);
+
+	/* detect the available timers */
+	t = scan_timers(&cs5535_mfgpt_chip);
+	dev_info(&pdev->dev, DRV_NAME ": %d MFGPT timers available\n", t);
+	cs5535_mfgpt_chip.initialized = 1;
+	return 0;
+
+done:
+	return err;
+}
+
+static struct pci_device_id cs5535_mfgpt_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, cs5535_mfgpt_pci_tbl);
+
+/*
+ * Just like with the cs5535-gpio driver, we can't use the standard PCI driver
+ * registration stuff.  It only allows only one driver to bind to each PCI
+ * device, and we want the GPIO and MFGPT drivers to be able to share a PCI
+ * device.  Instead, we manually scan for the PCI device, request a single
+ * region, and keep track of the devices that we're using.
+ */
+
+static int __init cs5535_mfgpt_scan_pci(void)
+{
+	struct pci_dev *pdev;
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cs5535_mfgpt_pci_tbl); i++) {
+		pdev = pci_get_device(cs5535_mfgpt_pci_tbl[i].vendor,
+				cs5535_mfgpt_pci_tbl[i].device, NULL);
+		if (pdev) {
+			err = cs5535_mfgpt_probe(pdev,
+					&cs5535_mfgpt_pci_tbl[i]);
+			if (err)
+				pci_dev_put(pdev);
+
+			/* we only support a single CS5535/6 southbridge */
+			break;
+		}
+	}
+
+	return err;
+}
+
+static int __init cs5535_mfgpt_init(void)
+{
+	return cs5535_mfgpt_scan_pci();
+}
+
+module_init(cs5535_mfgpt_init);
+
+MODULE_AUTHOR("Andres Salomon <dilinger@collabora.co.uk>");
+MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/ds1682.c linux-libre-2.6.33-gnu1/drivers/misc/ds1682.c
--- linux-libre-2.6.32-gnu1/drivers/misc/ds1682.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/ds1682.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,267 @@
+/*
+ * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
+ *
+ * Written by: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * Copyright (C) 2007 Secret Lab 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.
+ */
+
+/*
+ * The DS1682 elapsed timer recorder is a simple device that implements
+ * one elapsed time counter, one event counter, an alarm signal and 10
+ * bytes of general purpose EEPROM.
+ *
+ * This driver provides access to the DS1682 counters and user data via
+ * the sysfs.  The following attributes are added to the device node:
+ *     elapsed_time (u32): Total elapsed event time in ms resolution
+ *     alarm_time (u32): When elapsed time exceeds the value in alarm_time,
+ *                       then the alarm pin is asserted.
+ *     event_count (u16): number of times the event pin has gone low.
+ *     eeprom (u8[10]): general purpose EEPROM
+ *
+ * Counter registers and user data are both read/write unless the device
+ * has been write protected.  This driver does not support turning off write
+ * protection.  Once write protection is turned on, it is impossible to
+ * turn it off again, so I have left the feature out of this driver to avoid
+ * accidental enabling, but it is trivial to add write protect support.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/sysfs.h>
+#include <linux/ctype.h>
+#include <linux/hwmon-sysfs.h>
+
+/* Device registers */
+#define DS1682_REG_CONFIG		0x00
+#define DS1682_REG_ALARM		0x01
+#define DS1682_REG_ELAPSED		0x05
+#define DS1682_REG_EVT_CNTR		0x09
+#define DS1682_REG_EEPROM		0x0b
+#define DS1682_REG_RESET		0x1d
+#define DS1682_REG_WRITE_DISABLE	0x1e
+#define DS1682_REG_WRITE_MEM_DISABLE	0x1f
+
+#define DS1682_EEPROM_SIZE		10
+
+/*
+ * Generic counter attributes
+ */
+static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	__le32 val = 0;
+	int rc;
+
+	dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
+
+	/* Read the register */
+	rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
+					   (u8 *) & val);
+	if (rc < 0)
+		return -EIO;
+
+	/* Special case: the 32 bit regs are time values with 1/4s
+	 * resolution, scale them up to milliseconds */
+	if (sattr->nr == 4)
+		return sprintf(buf, "%llu\n",
+			((unsigned long long)le32_to_cpu(val)) * 250);
+
+	/* Format the output string and return # of bytes */
+	return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
+}
+
+static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	char *endp;
+	u64 val;
+	__le32 val_le;
+	int rc;
+
+	dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
+
+	/* Decode input */
+	val = simple_strtoull(buf, &endp, 0);
+	if (buf == endp) {
+		dev_dbg(dev, "input string not a number\n");
+		return -EINVAL;
+	}
+
+	/* Special case: the 32 bit regs are time values with 1/4s
+	 * resolution, scale input down to quarter-seconds */
+	if (sattr->nr == 4)
+		do_div(val, 250);
+
+	/* write out the value */
+	val_le = cpu_to_le32(val);
+	rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
+					    (u8 *) & val_le);
+	if (rc < 0) {
+		dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
+			sattr->index, sattr->nr);
+		return -EIO;
+	}
+
+	return count;
+}
+
+/*
+ * Simple register attributes
+ */
+static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 4, DS1682_REG_ELAPSED);
+static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 4, DS1682_REG_ALARM);
+static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 2, DS1682_REG_EVT_CNTR);
+
+static const struct attribute_group ds1682_group = {
+	.attrs = (struct attribute *[]) {
+		&sensor_dev_attr_elapsed_time.dev_attr.attr,
+		&sensor_dev_attr_alarm_time.dev_attr.attr,
+		&sensor_dev_attr_event_count.dev_attr.attr,
+		NULL,
+	},
+};
+
+/*
+ * User data attribute
+ */
+static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr,
+				  char *buf, loff_t off, size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(kobj);
+	int rc;
+
+	dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
+		buf, off, count);
+
+	if (off >= DS1682_EEPROM_SIZE)
+		return 0;
+
+	if (off + count > DS1682_EEPROM_SIZE)
+		count = DS1682_EEPROM_SIZE - off;
+
+	rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
+					   count, buf);
+	if (rc < 0)
+		return -EIO;
+
+	return count;
+}
+
+static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr,
+				   char *buf, loff_t off, size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(kobj);
+
+	dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
+		buf, off, count);
+
+	if (off >= DS1682_EEPROM_SIZE)
+		return -ENOSPC;
+
+	if (off + count > DS1682_EEPROM_SIZE)
+		count = DS1682_EEPROM_SIZE - off;
+
+	/* Write out to the device */
+	if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
+					   count, buf) < 0)
+		return -EIO;
+
+	return count;
+}
+
+static struct bin_attribute ds1682_eeprom_attr = {
+	.attr = {
+		.name = "eeprom",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = DS1682_EEPROM_SIZE,
+	.read = ds1682_eeprom_read,
+	.write = ds1682_eeprom_write,
+};
+
+/*
+ * Called when a ds1682 device is matched with this driver
+ */
+static int ds1682_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int rc;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_I2C_BLOCK)) {
+		dev_err(&client->dev, "i2c bus does not support the ds1682\n");
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
+	if (rc)
+		goto exit;
+
+	rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+	if (rc)
+		goto exit_bin_attr;
+
+	return 0;
+
+ exit_bin_attr:
+	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+ exit:
+	return rc;
+}
+
+static int ds1682_remove(struct i2c_client *client)
+{
+	sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+	return 0;
+}
+
+static const struct i2c_device_id ds1682_id[] = {
+	{ "ds1682", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ds1682_id);
+
+static struct i2c_driver ds1682_driver = {
+	.driver = {
+		.name = "ds1682",
+	},
+	.probe = ds1682_probe,
+	.remove = ds1682_remove,
+	.id_table = ds1682_id,
+};
+
+static int __init ds1682_init(void)
+{
+	return i2c_add_driver(&ds1682_driver);
+}
+
+static void __exit ds1682_exit(void)
+{
+	i2c_del_driver(&ds1682_driver);
+}
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds1682_init);
+module_exit(ds1682_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/eeprom/eeprom.c linux-libre-2.6.33-gnu1/drivers/misc/eeprom/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/misc/eeprom/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/eeprom/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,9 +32,6 @@
 static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
 					0x55, 0x56, 0x57, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(eeprom);
-
 
 /* Size of EEPROM in bytes */
 #define EEPROM_SIZE		256
@@ -135,8 +132,7 @@ static struct bin_attribute eeprom_attr
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int eeprom_detect(struct i2c_client *client, int kind,
-			 struct i2c_board_info *info)
+static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
 
@@ -233,7 +229,7 @@ static struct i2c_driver eeprom_driver =
 
 	.class		= I2C_CLASS_DDC | I2C_CLASS_SPD,
 	.detect		= eeprom_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static int __init eeprom_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/enclosure.c linux-libre-2.6.33-gnu1/drivers/misc/enclosure.c
--- linux-libre-2.6.32-gnu1/drivers/misc/enclosure.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/enclosure.c	2010-02-24 13:52:17.000000000 -0500
@@ -391,6 +391,7 @@ static const char *const enclosure_statu
 	[ENCLOSURE_STATUS_NOT_INSTALLED] = "not installed",
 	[ENCLOSURE_STATUS_UNKNOWN] = "unknown",
 	[ENCLOSURE_STATUS_UNAVAILABLE] = "unavailable",
+	[ENCLOSURE_STATUS_MAX] = NULL,
 };
 
 static const char *const enclosure_type [] = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/hpilo.h linux-libre-2.6.33-gnu1/drivers/misc/hpilo.h
--- linux-libre-2.6.32-gnu1/drivers/misc/hpilo.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/hpilo.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,9 +44,20 @@ struct ilo_hwinfo {
 
 	struct pci_dev *ilo_dev;
 
+	/*
+	 * open_lock      serializes ccb_cnt during open and close
+	 * [ irq disabled ]
+	 * -> alloc_lock  used when adding/removing/searching ccb_alloc,
+	 *                which represents all ccbs open on the device
+	 * --> fifo_lock  controls access to fifo queues shared with hw
+	 *
+	 * Locks must be taken in this order, but open_lock and alloc_lock
+	 * are optional, they do not need to be held in order to take a
+	 * lower level lock.
+	 */
+	spinlock_t open_lock;
 	spinlock_t alloc_lock;
 	spinlock_t fifo_lock;
-	spinlock_t open_lock;
 
 	struct cdev cdev;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/ics932s401.c linux-libre-2.6.33-gnu1/drivers/misc/ics932s401.c
--- linux-libre-2.6.32-gnu1/drivers/misc/ics932s401.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/ics932s401.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,9 +30,6 @@
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
 
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ics932s401);
-
 /* ICS932S401 registers */
 #define ICS932S401_REG_CFG2			0x01
 #define 	ICS932S401_CFG1_SPREAD		0x01
@@ -106,12 +103,12 @@ struct ics932s401_data {
 
 static int ics932s401_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int ics932s401_detect(struct i2c_client *client, int kind,
+static int ics932s401_detect(struct i2c_client *client,
 			  struct i2c_board_info *info);
 static int ics932s401_remove(struct i2c_client *client);
 
 static const struct i2c_device_id ics932s401_id[] = {
-	{ "ics932s401", ics932s401 },
+	{ "ics932s401", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ics932s401_id);
@@ -125,7 +122,7 @@ static struct i2c_driver ics932s401_driv
 	.remove		= ics932s401_remove,
 	.id_table	= ics932s401_id,
 	.detect		= ics932s401_detect,
-	.address_data	= &addr_data,
+	.address_list	= normal_i2c,
 };
 
 static struct ics932s401_data *ics932s401_update_device(struct device *dev)
@@ -413,36 +410,29 @@ static ssize_t show_spread(struct device
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int ics932s401_detect(struct i2c_client *client, int kind,
+static int ics932s401_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (kind <= 0) {
-		int vendor, device, revision;
-
-		vendor = i2c_smbus_read_word_data(client,
-						  ICS932S401_REG_VENDOR_REV);
-		vendor >>= 8;
-		revision = vendor >> ICS932S401_REV_SHIFT;
-		vendor &= ICS932S401_VENDOR_MASK;
-		if (vendor != ICS932S401_VENDOR)
-			return -ENODEV;
+	vendor = i2c_smbus_read_word_data(client, ICS932S401_REG_VENDOR_REV);
+	vendor >>= 8;
+	revision = vendor >> ICS932S401_REV_SHIFT;
+	vendor &= ICS932S401_VENDOR_MASK;
+	if (vendor != ICS932S401_VENDOR)
+		return -ENODEV;
 
-		device = i2c_smbus_read_word_data(client,
-						  ICS932S401_REG_DEVICE);
-		device >>= 8;
-		if (device != ICS932S401_DEVICE)
-			return -ENODEV;
+	device = i2c_smbus_read_word_data(client, ICS932S401_REG_DEVICE);
+	device >>= 8;
+	if (device != ICS932S401_DEVICE)
+		return -ENODEV;
 
-		if (revision != ICS932S401_REV)
-			dev_info(&adapter->dev, "Unknown revision %d\n",
-				 revision);
-	} else
-		dev_dbg(&adapter->dev, "detection forced\n");
+	if (revision != ICS932S401_REV)
+		dev_info(&adapter->dev, "Unknown revision %d\n", revision);
 
 	strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/ioc4.c linux-libre-2.6.33-gnu1/drivers/misc/ioc4.c
--- linux-libre-2.6.32-gnu1/drivers/misc/ioc4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/ioc4.c	2010-02-24 13:52:17.000000000 -0500
@@ -138,7 +138,7 @@ ioc4_unregister_submodule(struct ioc4_su
  * even though the following code utilizes external interrupt registers
  * to perform the speed calculation.
  */
-static void
+static void __devinit
 ioc4_clock_calibrate(struct ioc4_driver_data *idd)
 {
 	union ioc4_int_out int_out;
@@ -230,7 +230,7 @@ ioc4_clock_calibrate(struct ioc4_driver_
  * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
  * If neither is present, it's a PCI-RT.
  */
-static unsigned int
+static unsigned int __devinit
 ioc4_variant(struct ioc4_driver_data *idd)
 {
 	struct pci_dev *pdev = NULL;
@@ -269,7 +269,7 @@ ioc4_variant(struct ioc4_driver_data *id
 	return IOC4_VARIANT_PCI_RT;
 }
 
-static void
+static void __devinit
 ioc4_load_modules(struct work_struct *work)
 {
 	/* arg just has to be freed */
@@ -280,7 +280,7 @@ ioc4_load_modules(struct work_struct *wo
 }
 
 /* Adds a new instance of an IOC4 card */
-static int
+static int __devinit
 ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 {
 	struct ioc4_driver_data *idd;
@@ -425,7 +425,7 @@ out:
 }
 
 /* Removes a particular instance of an IOC4 card. */
-static void
+static void __devexit
 ioc4_remove(struct pci_dev *pdev)
 {
 	struct ioc4_submodule *is;
@@ -476,7 +476,7 @@ static struct pci_driver ioc4_driver = {
 	.name = "IOC4",
 	.id_table = ioc4_id_table,
 	.probe = ioc4_probe,
-	.remove = ioc4_remove,
+	.remove = __devexit_p(ioc4_remove),
 };
 
 MODULE_DEVICE_TABLE(pci, ioc4_id_table);
@@ -486,14 +486,14 @@ MODULE_DEVICE_TABLE(pci, ioc4_id_table);
  *********************/
 
 /* Module load */
-static int __devinit
+static int __init
 ioc4_init(void)
 {
 	return pci_register_driver(&ioc4_driver);
 }
 
 /* Module unload */
-static void __devexit
+static void __exit
 ioc4_exit(void)
 {
 	/* Ensure ioc4_load_modules() has completed before exiting */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/debugfs.c linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,133 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/debufs.c
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio.h>
+#include <linux/debugfs.h>
+
+#include "iwmc3200top.h"
+#include "fw-msg.h"
+#include "log.h"
+#include "debugfs.h"
+
+
+
+/*      Constants definition        */
+#define HEXADECIMAL_RADIX	16
+
+/*      Functions definition        */
+
+
+#define DEBUGFS_ADD(name, parent) do {					\
+	dbgfs->dbgfs_##parent##_files.file_##name =			\
+	debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv,	\
+				&iwmct_dbgfs_##name##_ops);		\
+} while (0)
+
+#define DEBUGFS_RM(name)  do {		\
+	debugfs_remove(name);		\
+	name = NULL;			\
+} while (0)
+
+#define DEBUGFS_READ_FUNC(name)						\
+ssize_t iwmct_dbgfs_##name##_read(struct file *file,			\
+				  char __user *user_buf,		\
+				  size_t count, loff_t *ppos);
+
+#define DEBUGFS_WRITE_FUNC(name)					\
+ssize_t iwmct_dbgfs_##name##_write(struct file *file,			\
+				   const char __user *user_buf,		\
+				   size_t count, loff_t *ppos);
+
+#define DEBUGFS_READ_FILE_OPS(name)					\
+	DEBUGFS_READ_FUNC(name)						\
+	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
+		.read = iwmct_dbgfs_##name##_read,			\
+		.open = iwmct_dbgfs_open_file_generic,			\
+	};
+
+#define DEBUGFS_WRITE_FILE_OPS(name)					\
+	DEBUGFS_WRITE_FUNC(name)					\
+	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
+		.write = iwmct_dbgfs_##name##_write,			\
+		.open = iwmct_dbgfs_open_file_generic,			\
+	};
+
+#define DEBUGFS_READ_WRITE_FILE_OPS(name)				\
+	DEBUGFS_READ_FUNC(name)						\
+	DEBUGFS_WRITE_FUNC(name)					\
+	static const struct file_operations iwmct_dbgfs_##name##_ops = {\
+		.write = iwmct_dbgfs_##name##_write,			\
+		.read = iwmct_dbgfs_##name##_read,			\
+		.open = iwmct_dbgfs_open_file_generic,			\
+	};
+
+
+/*      Debugfs file ops definitions        */
+
+/*
+ * Create the debugfs files and directories
+ *
+ */
+void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
+{
+	struct iwmct_debugfs *dbgfs;
+
+	dbgfs = kzalloc(sizeof(struct iwmct_debugfs), GFP_KERNEL);
+	if (!dbgfs) {
+		LOG_ERROR(priv, DEBUGFS, "failed to allocate %zd bytes\n",
+					sizeof(struct iwmct_debugfs));
+		return;
+	}
+
+	priv->dbgfs = dbgfs;
+	dbgfs->name = name;
+	dbgfs->dir_drv = debugfs_create_dir(name, NULL);
+	if (!dbgfs->dir_drv) {
+		LOG_ERROR(priv, DEBUGFS, "failed to create debugfs dir\n");
+		return;
+	}
+
+	return;
+}
+
+/**
+ * Remove the debugfs files and directories
+ *
+ */
+void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
+{
+	if (!dbgfs)
+		return;
+
+	DEBUGFS_RM(dbgfs->dir_drv);
+	kfree(dbgfs);
+	dbgfs = NULL;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/debugfs.h linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.h
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/debugfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/debugfs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,58 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/debufs.h
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#ifndef __DEBUGFS_H__
+#define __DEBUGFS_H__
+
+
+#ifdef CONFIG_IWMC3200TOP_DEBUGFS
+
+struct iwmct_debugfs {
+	const char *name;
+	struct dentry *dir_drv;
+	struct dir_drv_files {
+	} dbgfs_drv_files;
+};
+
+void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name);
+void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs);
+
+#else /* CONFIG_IWMC3200TOP_DEBUGFS */
+
+struct iwmct_debugfs;
+
+static inline void
+iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
+{}
+
+static inline void
+iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
+{}
+
+#endif /* CONFIG_IWMC3200TOP_DEBUGFS */
+
+#endif /* __DEBUGFS_H__ */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/fw-download.c linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-download.c
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/fw-download.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-download.c	2013-05-03 12:10:04.000000000 -0400
@@ -0,0 +1,355 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/fw-download.c
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#include <linux/firmware.h>
+#include <linux/mmc/sdio_func.h>
+#include <asm/unaligned.h>
+
+#include "iwmc3200top.h"
+#include "log.h"
+#include "fw-msg.h"
+
+#define CHECKSUM_BYTES_NUM sizeof(u32)
+
+/**
+  init parser struct with file
+ */
+static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
+			      size_t file_size, size_t block_size)
+{
+	struct iwmct_parser *parser = &priv->parser;
+	struct iwmct_fw_hdr *fw_hdr = &parser->versions;
+
+	LOG_INFOEX(priv, INIT, "-->\n");
+
+	LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);
+
+	parser->file = file;
+	parser->file_size = file_size;
+	parser->cur_pos = 0;
+	parser->buf = NULL;
+
+	parser->buf = kzalloc(block_size, GFP_KERNEL);
+	if (!parser->buf) {
+		LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
+		return -ENOMEM;
+	}
+	parser->buf_size = block_size;
+
+	/* extract fw versions */
+	memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
+	LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
+		"top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
+		fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
+		fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
+		fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
+		fw_hdr->tic_name);
+
+	parser->cur_pos += sizeof(struct iwmct_fw_hdr);
+
+	LOG_INFOEX(priv, INIT, "<--\n");
+	return 0;
+}
+
+static bool iwmct_checksum(struct iwmct_priv *priv)
+{
+	struct iwmct_parser *parser = &priv->parser;
+	__le32 *file = (__le32 *)parser->file;
+	int i, pad, steps;
+	u32 accum = 0;
+	u32 checksum;
+	u32 mask = 0xffffffff;
+
+	pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
+	steps =  (parser->file_size - CHECKSUM_BYTES_NUM) / 4;
+
+	LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);
+
+	for (i = 0; i < steps; i++)
+		accum += le32_to_cpu(file[i]);
+
+	if (pad) {
+		mask <<= 8 * (4 - pad);
+		accum += le32_to_cpu(file[steps]) & mask;
+	}
+
+	checksum = get_unaligned_le32((__le32 *)(parser->file +
+			parser->file_size - CHECKSUM_BYTES_NUM));
+
+	LOG_INFO(priv, FW_DOWNLOAD,
+		"compare checksum accum=0x%x to checksum=0x%x\n",
+		accum, checksum);
+
+	return checksum == accum;
+}
+
+static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
+				  size_t *sec_size, __le32 *sec_addr)
+{
+	struct iwmct_parser *parser = &priv->parser;
+	struct iwmct_dbg *dbg = &priv->dbg;
+	struct iwmct_fw_sec_hdr *sec_hdr;
+
+	LOG_INFOEX(priv, INIT, "-->\n");
+
+	while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
+		<= parser->file_size) {
+
+		sec_hdr = (struct iwmct_fw_sec_hdr *)
+				(parser->file + parser->cur_pos);
+		parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);
+
+		LOG_INFO(priv, FW_DOWNLOAD,
+			"sec hdr: type=%s addr=0x%x size=%d\n",
+			sec_hdr->type, sec_hdr->target_addr,
+			sec_hdr->data_size);
+
+		if (strcmp(sec_hdr->type, "ENT") == 0)
+			parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
+		else if (strcmp(sec_hdr->type, "LBL") == 0)
+			strcpy(dbg->label_fw, parser->file + parser->cur_pos);
+		else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
+			  (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
+			 ((strcmp(sec_hdr->type, "GPS") == 0) &&
+			  (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
+			 ((strcmp(sec_hdr->type, "BTH") == 0) &&
+			  (priv->barker & BARKER_DNLOAD_BT_MSK))) {
+			*sec_addr = sec_hdr->target_addr;
+			*sec_size = le32_to_cpu(sec_hdr->data_size);
+			*p_sec = parser->file + parser->cur_pos;
+			parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
+			return 1;
+		} else if (strcmp(sec_hdr->type, "LOG") != 0)
+			LOG_WARNING(priv, FW_DOWNLOAD,
+				    "skipping section type %s\n",
+				    sec_hdr->type);
+
+		parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
+		LOG_INFO(priv, FW_DOWNLOAD,
+			"finished with section cur_pos=%zd\n", parser->cur_pos);
+	}
+
+	LOG_INFOEX(priv, INIT, "<--\n");
+	return 0;
+}
+
+static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
+				size_t sec_size, __le32 addr)
+{
+	struct iwmct_parser *parser = &priv->parser;
+	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
+	const u8 *cur_block = p_sec;
+	size_t sent = 0;
+	int cnt = 0;
+	int ret = 0;
+	u32 cmd = 0;
+
+	LOG_INFOEX(priv, INIT, "-->\n");
+	LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
+				addr, sec_size);
+
+	while (sent < sec_size) {
+		int i;
+		u32 chksm = 0;
+		u32 reset = atomic_read(&priv->reset);
+		/* actual FW data */
+		u32 data_size = min(parser->buf_size - sizeof(*hdr),
+				    sec_size - sent);
+		/* Pad to block size */
+		u32 trans_size = (data_size + sizeof(*hdr) +
+				  IWMC_SDIO_BLK_SIZE - 1) &
+				  ~(IWMC_SDIO_BLK_SIZE - 1);
+		++cnt;
+
+		/* in case of reset, interrupt FW DOWNLAOD */
+		if (reset) {
+			LOG_INFO(priv, FW_DOWNLOAD,
+				 "Reset detected. Abort FW download!!!");
+			ret = -ECANCELED;
+			goto exit;
+		}
+
+		memset(parser->buf, 0, parser->buf_size);
+		cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
+		cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
+		cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
+		cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
+		hdr->data_size = cpu_to_le32(data_size);
+		hdr->target_addr = addr;
+
+		/* checksum is allowed for sizes divisible by 4 */
+		if (data_size & 0x3)
+			cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;
+
+		memcpy(hdr->data, cur_block, data_size);
+
+
+		if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {
+
+			chksm = data_size + le32_to_cpu(addr) + cmd;
+			for (i = 0; i < data_size >> 2; i++)
+				chksm += ((u32 *)cur_block)[i];
+
+			hdr->block_chksm = cpu_to_le32(chksm);
+			LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
+				 hdr->block_chksm);
+		}
+
+		LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
+				"sec_size=%zd, startAddress 0x%X\n",
+				cnt, trans_size, sent, sec_size, addr);
+
+		if (priv->dbg.dump)
+			LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);
+
+
+		hdr->cmd = cpu_to_le32(cmd);
+		/* send it down */
+		/* TODO: add more proper sending and error checking */
+		ret = iwmct_tx(priv, 0, parser->buf, trans_size);
+		if (ret != 0) {
+			LOG_INFO(priv, FW_DOWNLOAD,
+				"iwmct_tx returned %d\n", ret);
+			goto exit;
+		}
+
+		addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
+		sent += data_size;
+		cur_block = p_sec + sent;
+
+		if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
+			LOG_INFO(priv, FW_DOWNLOAD,
+				"Block number limit is reached [%d]\n",
+				priv->dbg.blocks);
+			break;
+		}
+	}
+
+	if (sent < sec_size)
+		ret = -EINVAL;
+exit:
+	LOG_INFOEX(priv, INIT, "<--\n");
+	return ret;
+}
+
+static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
+{
+	struct iwmct_parser *parser = &priv->parser;
+	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
+	int ret;
+	u32 cmd;
+
+	LOG_INFOEX(priv, INIT, "-->\n");
+
+	memset(parser->buf, 0, parser->buf_size);
+	cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
+	if (jump) {
+		cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
+		hdr->target_addr = cpu_to_le32(parser->entry_point);
+		LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
+				parser->entry_point);
+	} else {
+		cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
+		LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
+	}
+
+	hdr->cmd = cpu_to_le32(cmd);
+
+	LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
+	/* send it down */
+	/* TODO: add more proper sending and error checking */
+	ret = iwmct_tx(priv, 0, parser->buf, IWMC_SDIO_BLK_SIZE);
+	if (ret)
+		LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
+
+	LOG_INFOEX(priv, INIT, "<--\n");
+	return 0;
+}
+
+int iwmct_fw_load(struct iwmct_priv *priv)
+{
+	const u8 *fw_name = FW_NAME(FW_API_VER);
+	const struct firmware *raw;
+	const u8 *pdata;
+	size_t len;
+	__le32 addr;
+	int ret;
+
+	/* clear parser struct */
+	memset(&priv->parser, 0, sizeof(struct iwmct_parser));
+
+	/* get the firmware */
+	ret = reject_firmware(&raw, fw_name, &priv->func->dev);
+	if (ret < 0) {
+		LOG_ERROR(priv, FW_DOWNLOAD, "%s reject_firmware failed %d\n",
+			  fw_name, ret);
+		goto exit;
+	}
+
+	if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
+		LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
+			  fw_name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
+		goto exit;
+	}
+
+	LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", fw_name);
+
+	ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
+	if (ret < 0) {
+		LOG_ERROR(priv, FW_DOWNLOAD,
+			  "iwmct_parser_init failed: Reason %d\n", ret);
+		goto exit;
+	}
+
+	/* checksum  */
+	if (!iwmct_checksum(priv)) {
+		LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* download firmware to device */
+	while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
+		if (iwmct_download_section(priv, pdata, len, addr)) {
+			LOG_ERROR(priv, FW_DOWNLOAD,
+				  "%s download section failed\n", fw_name);
+			ret = -EIO;
+			goto exit;
+		}
+	}
+
+	iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
+
+exit:
+	kfree(priv->parser.buf);
+
+	if (raw)
+		release_firmware(raw);
+
+	raw = NULL;
+
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/fw-msg.h linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-msg.h
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/fw-msg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/fw-msg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,113 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/fw-msg.h
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#ifndef __FWMSG_H__
+#define __FWMSG_H__
+
+#define COMM_TYPE_D2H           	0xFF
+#define COMM_TYPE_H2D           	0xEE
+
+#define COMM_CATEGORY_OPERATIONAL      	0x00
+#define COMM_CATEGORY_DEBUG            	0x01
+#define COMM_CATEGORY_TESTABILITY      	0x02
+#define COMM_CATEGORY_DIAGNOSTICS      	0x03
+
+#define OP_DBG_ZSTR_MSG			cpu_to_le16(0x1A)
+
+#define FW_LOG_SRC_MAX			32
+#define FW_LOG_SRC_ALL			255
+
+#define FW_STRING_TABLE_ADDR		cpu_to_le32(0x0C000000)
+
+#define CMD_DBG_LOG_LEVEL		cpu_to_le16(0x0001)
+#define CMD_TST_DEV_RESET		cpu_to_le16(0x0060)
+#define CMD_TST_FUNC_RESET		cpu_to_le16(0x0062)
+#define CMD_TST_IFACE_RESET		cpu_to_le16(0x0064)
+#define CMD_TST_CPU_UTILIZATION		cpu_to_le16(0x0065)
+#define CMD_TST_TOP_DEEP_SLEEP		cpu_to_le16(0x0080)
+#define CMD_TST_WAKEUP			cpu_to_le16(0x0081)
+#define CMD_TST_FUNC_WAKEUP		cpu_to_le16(0x0082)
+#define CMD_TST_FUNC_DEEP_SLEEP_REQUEST	cpu_to_le16(0x0083)
+#define CMD_TST_GET_MEM_DUMP		cpu_to_le16(0x0096)
+
+#define OP_OPR_ALIVE			cpu_to_le16(0x0010)
+#define OP_OPR_CMD_ACK			cpu_to_le16(0x001F)
+#define OP_OPR_CMD_NACK			cpu_to_le16(0x0020)
+#define OP_TST_MEM_DUMP			cpu_to_le16(0x0043)
+
+#define CMD_FLAG_PADDING_256		0x80
+
+#define FW_HCMD_BLOCK_SIZE      	256
+
+struct msg_hdr {
+	u8 type;
+	u8 category;
+	__le16 opcode;
+	u8 seqnum;
+	u8 flags;
+	__le16 length;
+} __attribute__((__packed__));
+
+struct log_hdr {
+	__le32 timestamp;
+	u8 severity;
+	u8 logsource;
+	__le16 reserved;
+} __attribute__((__packed__));
+
+struct mdump_hdr {
+	u8 dmpid;
+	u8 frag;
+	__le16 size;
+	__le32 addr;
+} __attribute__((__packed__));
+
+struct top_msg {
+	struct msg_hdr hdr;
+	union {
+		/* D2H messages */
+		struct {
+			struct log_hdr log_hdr;
+			u8 data[1];
+		} __attribute__((__packed__)) log;
+
+		struct {
+			struct log_hdr log_hdr;
+			struct mdump_hdr md_hdr;
+			u8 data[1];
+		} __attribute__((__packed__)) mdump;
+
+		/* H2D messages */
+		struct {
+			u8 logsource;
+			u8 sevmask;
+		} __attribute__((__packed__)) logdefs[FW_LOG_SRC_MAX];
+		struct mdump_hdr mdump_req;
+	} u;
+} __attribute__((__packed__));
+
+
+#endif /* __FWMSG_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/iwmc3200top.h	2013-05-03 12:10:04.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/iwmc3200top.h
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#ifndef __IWMC3200TOP_H__
+#define __IWMC3200TOP_H__
+
+#include <linux/workqueue.h>
+
+#define DRV_NAME "iwmc3200top"
+#define FW_API_VER 1
+/*(DEBLOBBED)*/
+#define FW_NAME(api) "/*(DEBLOBBED)*/"
+
+#define IWMC_SDIO_BLK_SIZE			256
+#define IWMC_DEFAULT_TR_BLK			64
+#define IWMC_SDIO_DATA_ADDR			0x0
+#define IWMC_SDIO_INTR_ENABLE_ADDR		0x14
+#define IWMC_SDIO_INTR_STATUS_ADDR		0x13
+#define IWMC_SDIO_INTR_CLEAR_ADDR		0x13
+#define IWMC_SDIO_INTR_GET_SIZE_ADDR		0x2C
+
+#define COMM_HUB_HEADER_LENGTH 16
+#define LOGGER_HEADER_LENGTH   10
+
+
+#define BARKER_DNLOAD_BT_POS		0
+#define BARKER_DNLOAD_BT_MSK		BIT(BARKER_DNLOAD_BT_POS)
+#define BARKER_DNLOAD_GPS_POS		1
+#define BARKER_DNLOAD_GPS_MSK		BIT(BARKER_DNLOAD_GPS_POS)
+#define BARKER_DNLOAD_TOP_POS		2
+#define BARKER_DNLOAD_TOP_MSK		BIT(BARKER_DNLOAD_TOP_POS)
+#define BARKER_DNLOAD_RESERVED1_POS	3
+#define BARKER_DNLOAD_RESERVED1_MSK	BIT(BARKER_DNLOAD_RESERVED1_POS)
+#define BARKER_DNLOAD_JUMP_POS		4
+#define BARKER_DNLOAD_JUMP_MSK		BIT(BARKER_DNLOAD_JUMP_POS)
+#define BARKER_DNLOAD_SYNC_POS		5
+#define BARKER_DNLOAD_SYNC_MSK		BIT(BARKER_DNLOAD_SYNC_POS)
+#define BARKER_DNLOAD_RESERVED2_POS	6
+#define BARKER_DNLOAD_RESERVED2_MSK	(0x3 << BARKER_DNLOAD_RESERVED2_POS)
+#define BARKER_DNLOAD_BARKER_POS	8
+#define BARKER_DNLOAD_BARKER_MSK	(0xffffff << BARKER_DNLOAD_BARKER_POS)
+
+#define IWMC_BARKER_REBOOT 	(0xdeadbe << BARKER_DNLOAD_BARKER_POS)
+/* whole field barker */
+#define IWMC_BARKER_ACK 	0xfeedbabe
+
+#define IWMC_CMD_SIGNATURE 	0xcbbc
+
+#define CMD_HDR_OPCODE_POS		0
+#define CMD_HDR_OPCODE_MSK_MSK		(0xf << CMD_HDR_OPCODE_MSK_POS)
+#define CMD_HDR_RESPONSE_CODE_POS	4
+#define CMD_HDR_RESPONSE_CODE_MSK	(0xf << CMD_HDR_RESPONSE_CODE_POS)
+#define CMD_HDR_USE_CHECKSUM_POS	8
+#define CMD_HDR_USE_CHECKSUM_MSK	BIT(CMD_HDR_USE_CHECKSUM_POS)
+#define CMD_HDR_RESPONSE_REQUIRED_POS	9
+#define CMD_HDR_RESPONSE_REQUIRED_MSK	BIT(CMD_HDR_RESPONSE_REQUIRED_POS)
+#define CMD_HDR_DIRECT_ACCESS_POS	10
+#define CMD_HDR_DIRECT_ACCESS_MSK	BIT(CMD_HDR_DIRECT_ACCESS_POS)
+#define CMD_HDR_RESERVED_POS		11
+#define CMD_HDR_RESERVED_MSK		BIT(0x1f << CMD_HDR_RESERVED_POS)
+#define CMD_HDR_SIGNATURE_POS		16
+#define CMD_HDR_SIGNATURE_MSK		BIT(0xffff << CMD_HDR_SIGNATURE_POS)
+
+enum {
+	IWMC_OPCODE_PING = 0,
+	IWMC_OPCODE_READ = 1,
+	IWMC_OPCODE_WRITE = 2,
+	IWMC_OPCODE_JUMP = 3,
+	IWMC_OPCODE_REBOOT = 4,
+	IWMC_OPCODE_PERSISTENT_WRITE = 5,
+	IWMC_OPCODE_PERSISTENT_READ = 6,
+	IWMC_OPCODE_READ_MODIFY_WRITE = 7,
+	IWMC_OPCODE_LAST_COMMAND = 15
+};
+
+struct iwmct_fw_load_hdr {
+	__le32 cmd;
+	__le32 target_addr;
+	__le32 data_size;
+	__le32 block_chksm;
+	u8 data[0];
+};
+
+/**
+ * struct iwmct_fw_hdr
+ * holds all sw components versions
+ */
+struct iwmct_fw_hdr {
+	u8 top_major;
+	u8 top_minor;
+	u8 top_revision;
+	u8 gps_major;
+	u8 gps_minor;
+	u8 gps_revision;
+	u8 bt_major;
+	u8 bt_minor;
+	u8 bt_revision;
+	u8 tic_name[31];
+};
+
+/**
+ * struct iwmct_fw_sec_hdr
+ * @type: function type
+ * @data_size: section's data size
+ * @target_addr: download address
+ */
+struct iwmct_fw_sec_hdr {
+	u8 type[4];
+	__le32 data_size;
+	__le32 target_addr;
+};
+
+/**
+ * struct iwmct_parser
+ * @file: fw image
+ * @file_size: fw size
+ * @cur_pos: position in file
+ * @buf: temp buf for download
+ * @buf_size: size of buf
+ * @entry_point: address to jump in fw kick-off
+ */
+struct iwmct_parser {
+	const u8 *file;
+	size_t file_size;
+	size_t cur_pos;
+	u8 *buf;
+	size_t buf_size;
+	u32 entry_point;
+	struct iwmct_fw_hdr versions;
+};
+
+
+struct iwmct_work_struct {
+	struct list_head list;
+	ssize_t iosize;
+};
+
+struct iwmct_dbg {
+	int blocks;
+	bool dump;
+	bool jump;
+	bool direct;
+	bool checksum;
+	bool fw_download;
+	int block_size;
+	int download_trans_blks;
+
+	char label_fw[256];
+};
+
+struct iwmct_debugfs;
+
+struct iwmct_priv {
+	struct sdio_func *func;
+	struct iwmct_debugfs *dbgfs;
+	struct iwmct_parser parser;
+	atomic_t reset;
+	atomic_t dev_sync;
+	u32 trans_len;
+	u32 barker;
+	struct iwmct_dbg dbg;
+
+	/* drivers work queue */
+	struct workqueue_struct *wq;
+	struct workqueue_struct *bus_rescan_wq;
+	struct work_struct bus_rescan_worker;
+	struct work_struct isr_worker;
+
+	/* drivers wait queue */
+	wait_queue_head_t wait_q;
+
+	/* rx request list */
+	struct list_head read_req_list;
+};
+
+extern int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
+		void *src, int count);
+
+extern int iwmct_fw_load(struct iwmct_priv *priv);
+
+extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
+extern void iwmct_dbg_init_drv_attrs(struct device_driver *drv);
+extern void iwmct_dbg_remove_drv_attrs(struct device_driver *drv);
+extern int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len);
+
+#endif  /*  __IWMC3200TOP_H__  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/Kconfig linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,20 @@
+config IWMC3200TOP
+        tristate "Intel Wireless MultiCom Top Driver"
+        depends on MMC && EXPERIMENTAL
+        select FW_LOADER
+	---help---
+	  Intel Wireless MultiCom 3200 Top driver is responsible for
+	  for firmware load and enabled coms enumeration
+
+config IWMC3200TOP_DEBUG
+	bool "Enable full debug output of iwmc3200top Driver"
+	depends on IWMC3200TOP
+	---help---
+	  Enable full debug output of iwmc3200top Driver
+
+config IWMC3200TOP_DEBUGFS
+	bool "Enable Debugfs debugging interface for iwmc3200top"
+	depends on IWMC3200TOP
+	---help---
+	  Enable creation of debugfs files for iwmc3200top
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/log.c linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.c
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/log.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,347 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/log.c
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/ctype.h>
+#include "fw-msg.h"
+#include "iwmc3200top.h"
+#include "log.h"
+
+/* Maximal hexadecimal string size of the FW memdump message */
+#define LOG_MSG_SIZE_MAX		12400
+
+/* iwmct_logdefs is a global used by log macros */
+u8 iwmct_logdefs[LOG_SRC_MAX];
+static u8 iwmct_fw_logdefs[FW_LOG_SRC_MAX];
+
+
+static int _log_set_log_filter(u8 *logdefs, int size, u8 src, u8 logmask)
+{
+	int i;
+
+	if (src < size)
+		logdefs[src] = logmask;
+	else if (src == LOG_SRC_ALL)
+		for (i = 0; i < size; i++)
+			logdefs[i] = logmask;
+	else
+		return -1;
+
+	return 0;
+}
+
+
+int iwmct_log_set_filter(u8 src, u8 logmask)
+{
+	return _log_set_log_filter(iwmct_logdefs, LOG_SRC_MAX, src, logmask);
+}
+
+
+int iwmct_log_set_fw_filter(u8 src, u8 logmask)
+{
+	return _log_set_log_filter(iwmct_fw_logdefs,
+				   FW_LOG_SRC_MAX, src, logmask);
+}
+
+
+static int log_msg_format_hex(char *str, int slen, u8 *ibuf,
+			      int ilen, char *pref)
+{
+	int pos = 0;
+	int i;
+	int len;
+
+	for (pos = 0, i = 0; pos < slen - 2 && pref[i] != '\0'; i++, pos++)
+		str[pos] = pref[i];
+
+	for (i = 0; pos < slen - 2 && i < ilen; pos += len, i++)
+		len = snprintf(&str[pos], slen - pos - 1, " %2.2X", ibuf[i]);
+
+	if (i < ilen)
+		return -1;
+
+	return 0;
+}
+
+/*	NOTE: This function is not thread safe.
+	Currently it's called only from sdio rx worker - no race there
+*/
+void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len)
+{
+	struct top_msg *msg;
+	static char logbuf[LOG_MSG_SIZE_MAX];
+
+	msg = (struct top_msg *)buf;
+
+	if (len < sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr)) {
+		LOG_ERROR(priv, FW_MSG, "Log message from TOP "
+			  "is too short %d (expected %zd)\n",
+			  len, sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr));
+		return;
+	}
+
+	if (!(iwmct_fw_logdefs[msg->u.log.log_hdr.logsource] &
+		BIT(msg->u.log.log_hdr.severity)) ||
+	    !(iwmct_logdefs[LOG_SRC_FW_MSG] & BIT(msg->u.log.log_hdr.severity)))
+		return;
+
+	switch (msg->hdr.category) {
+	case COMM_CATEGORY_TESTABILITY:
+		if (!(iwmct_logdefs[LOG_SRC_TST] &
+		      BIT(msg->u.log.log_hdr.severity)))
+			return;
+		if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
+				       le16_to_cpu(msg->hdr.length) +
+				       sizeof(msg->hdr), "<TST>"))
+			LOG_WARNING(priv, TST,
+				  "TOP TST message is too long, truncating...");
+		LOG_WARNING(priv, TST, "%s\n", logbuf);
+		break;
+	case COMM_CATEGORY_DEBUG:
+		if (msg->hdr.opcode == OP_DBG_ZSTR_MSG)
+			LOG_INFO(priv, FW_MSG, "%s %s", "<DBG>",
+				       ((u8 *)msg) + sizeof(msg->hdr)
+					+ sizeof(msg->u.log.log_hdr));
+		else {
+			if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
+					le16_to_cpu(msg->hdr.length)
+						+ sizeof(msg->hdr),
+					"<DBG>"))
+				LOG_WARNING(priv, FW_MSG,
+					"TOP DBG message is too long,"
+					"truncating...");
+			LOG_WARNING(priv, FW_MSG, "%s\n", logbuf);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static int _log_get_filter_str(u8 *logdefs, int logdefsz, char *buf, int size)
+{
+	int i, pos, len;
+	for (i = 0, pos = 0; (pos < size-1) && (i < logdefsz); i++) {
+		len = snprintf(&buf[pos], size - pos - 1, "0x%02X%02X,",
+				i, logdefs[i]);
+		pos += len;
+	}
+	buf[pos-1] = '\n';
+	buf[pos] = '\0';
+
+	if (i < logdefsz)
+		return -1;
+	return 0;
+}
+
+int log_get_filter_str(char *buf, int size)
+{
+	return _log_get_filter_str(iwmct_logdefs, LOG_SRC_MAX, buf, size);
+}
+
+int log_get_fw_filter_str(char *buf, int size)
+{
+	return _log_get_filter_str(iwmct_fw_logdefs, FW_LOG_SRC_MAX, buf, size);
+}
+
+#define HEXADECIMAL_RADIX	16
+#define LOG_SRC_FORMAT		7 /* log level is in format of "0xXXXX," */
+
+ssize_t show_iwmct_log_level(struct device *d,
+				struct device_attribute *attr, char *buf)
+{
+	struct iwmct_priv *priv = dev_get_drvdata(d);
+	char *str_buf;
+	int buf_size;
+	ssize_t ret;
+
+	buf_size = (LOG_SRC_FORMAT * LOG_SRC_MAX) + 1;
+	str_buf = kzalloc(buf_size, GFP_KERNEL);
+	if (!str_buf) {
+		LOG_ERROR(priv, DEBUGFS,
+			"failed to allocate %d bytes\n", buf_size);
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	if (log_get_filter_str(str_buf, buf_size) < 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = sprintf(buf, "%s", str_buf);
+
+exit:
+	kfree(str_buf);
+	return ret;
+}
+
+ssize_t store_iwmct_log_level(struct device *d,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct iwmct_priv *priv = dev_get_drvdata(d);
+	char *token, *str_buf = NULL;
+	long val;
+	ssize_t ret = count;
+	u8 src, mask;
+
+	if (!count)
+		goto exit;
+
+	str_buf = kzalloc(count, GFP_KERNEL);
+	if (!str_buf) {
+		LOG_ERROR(priv, DEBUGFS,
+			"failed to allocate %zd bytes\n", count);
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	memcpy(str_buf, buf, count);
+
+	while ((token = strsep(&str_buf, ",")) != NULL) {
+		while (isspace(*token))
+			++token;
+		if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
+			LOG_ERROR(priv, DEBUGFS,
+				  "failed to convert string to long %s\n",
+				  token);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		mask  = val & 0xFF;
+		src = (val & 0XFF00) >> 8;
+		iwmct_log_set_filter(src, mask);
+	}
+
+exit:
+	kfree(str_buf);
+	return ret;
+}
+
+ssize_t show_iwmct_log_level_fw(struct device *d,
+			struct device_attribute *attr, char *buf)
+{
+	struct iwmct_priv *priv = dev_get_drvdata(d);
+	char *str_buf;
+	int buf_size;
+	ssize_t ret;
+
+	buf_size = (LOG_SRC_FORMAT * FW_LOG_SRC_MAX) + 2;
+
+	str_buf = kzalloc(buf_size, GFP_KERNEL);
+	if (!str_buf) {
+		LOG_ERROR(priv, DEBUGFS,
+			"failed to allocate %d bytes\n", buf_size);
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	if (log_get_fw_filter_str(str_buf, buf_size) < 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = sprintf(buf, "%s", str_buf);
+
+exit:
+	kfree(str_buf);
+	return ret;
+}
+
+ssize_t store_iwmct_log_level_fw(struct device *d,
+			struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct iwmct_priv *priv = dev_get_drvdata(d);
+	struct top_msg cmd;
+	char *token, *str_buf = NULL;
+	ssize_t ret = count;
+	u16 cmdlen = 0;
+	int i;
+	long val;
+	u8 src, mask;
+
+	if (!count)
+		goto exit;
+
+	str_buf = kzalloc(count, GFP_KERNEL);
+	if (!str_buf) {
+		LOG_ERROR(priv, DEBUGFS,
+			"failed to allocate %zd bytes\n", count);
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	memcpy(str_buf, buf, count);
+
+	cmd.hdr.type = COMM_TYPE_H2D;
+	cmd.hdr.category = COMM_CATEGORY_DEBUG;
+	cmd.hdr.opcode = CMD_DBG_LOG_LEVEL;
+
+	for (i = 0; ((token = strsep(&str_buf, ",")) != NULL) &&
+		     (i < FW_LOG_SRC_MAX); i++) {
+
+		while (isspace(*token))
+			++token;
+
+		if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
+			LOG_ERROR(priv, DEBUGFS,
+				  "failed to convert string to long %s\n",
+				  token);
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		mask  = val & 0xFF; /* LSB */
+		src = (val & 0XFF00) >> 8; /* 2nd least significant byte. */
+		iwmct_log_set_fw_filter(src, mask);
+
+		cmd.u.logdefs[i].logsource = src;
+		cmd.u.logdefs[i].sevmask = mask;
+	}
+
+	cmd.hdr.length = cpu_to_le16(i * sizeof(cmd.u.logdefs[0]));
+	cmdlen = (i * sizeof(cmd.u.logdefs[0]) + sizeof(cmd.hdr));
+
+	ret = iwmct_send_hcmd(priv, (u8 *)&cmd, cmdlen);
+	if (ret) {
+		LOG_ERROR(priv, DEBUGFS,
+			  "Failed to send %d bytes of fwcmd, ret=%zd\n",
+			  cmdlen, ret);
+		goto exit;
+	} else
+		LOG_INFO(priv, DEBUGFS, "fwcmd sent (%d bytes)\n", cmdlen);
+
+	ret = count;
+
+exit:
+	kfree(str_buf);
+	return ret;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/log.h linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.h
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/log.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/log.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/log.h
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#ifndef __LOG_H__
+#define __LOG_H__
+
+
+/* log severity:
+ * The log levels here match FW log levels
+ * so values need to stay as is */
+#define LOG_SEV_CRITICAL		0
+#define LOG_SEV_ERROR			1
+#define LOG_SEV_WARNING			2
+#define LOG_SEV_INFO			3
+#define LOG_SEV_INFOEX			4
+
+#define LOG_SEV_FILTER_ALL		\
+	(BIT(LOG_SEV_CRITICAL) |	\
+	 BIT(LOG_SEV_ERROR)    |	\
+	 BIT(LOG_SEV_WARNING)  | 	\
+	 BIT(LOG_SEV_INFO)     |	\
+	 BIT(LOG_SEV_INFOEX))
+
+/* log source */
+#define LOG_SRC_INIT			0
+#define LOG_SRC_DEBUGFS			1
+#define LOG_SRC_FW_DOWNLOAD		2
+#define LOG_SRC_FW_MSG			3
+#define LOG_SRC_TST			4
+#define LOG_SRC_IRQ			5
+
+#define	LOG_SRC_MAX			6
+#define	LOG_SRC_ALL			0xFF
+
+/**
+ * Default intitialization runtime log level
+ */
+#ifndef LOG_SEV_FILTER_RUNTIME
+#define LOG_SEV_FILTER_RUNTIME			\
+	(BIT(LOG_SEV_CRITICAL)	|		\
+	 BIT(LOG_SEV_ERROR)	|		\
+	 BIT(LOG_SEV_WARNING))
+#endif
+
+#ifndef FW_LOG_SEV_FILTER_RUNTIME
+#define FW_LOG_SEV_FILTER_RUNTIME	LOG_SEV_FILTER_ALL
+#endif
+
+#ifdef CONFIG_IWMC3200TOP_DEBUG
+/**
+ * Log macros
+ */
+
+#define priv2dev(priv) (&(priv->func)->dev)
+
+#define LOG_CRITICAL(priv, src, fmt, args...)				\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_CRITICAL))	\
+		dev_crit(priv2dev(priv), "%s %d: " fmt,			\
+			__func__, __LINE__, ##args);			\
+} while (0)
+
+#define LOG_ERROR(priv, src, fmt, args...)				\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_ERROR))	\
+		dev_err(priv2dev(priv), "%s %d: " fmt,			\
+			__func__, __LINE__, ##args);			\
+} while (0)
+
+#define LOG_WARNING(priv, src, fmt, args...)				\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_WARNING))	\
+		dev_warn(priv2dev(priv), "%s %d: " fmt,			\
+			 __func__, __LINE__, ##args);			\
+} while (0)
+
+#define LOG_INFO(priv, src, fmt, args...)				\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFO))		\
+		dev_info(priv2dev(priv), "%s %d: " fmt,			\
+			 __func__, __LINE__, ##args);			\
+} while (0)
+
+#define LOG_INFOEX(priv, src, fmt, args...)				\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
+		dev_dbg(priv2dev(priv), "%s %d: " fmt,			\
+			 __func__, __LINE__, ##args);			\
+} while (0)
+
+#define LOG_HEXDUMP(src, ptr, len)					\
+do {									\
+	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
+		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,	\
+				16, 1, ptr, len, false);		\
+} while (0)
+
+void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len);
+
+extern u8 iwmct_logdefs[];
+
+int iwmct_log_set_filter(u8 src, u8 logmask);
+int iwmct_log_set_fw_filter(u8 src, u8 logmask);
+
+ssize_t show_iwmct_log_level(struct device *d,
+			struct device_attribute *attr, char *buf);
+ssize_t store_iwmct_log_level(struct device *d,
+			struct device_attribute *attr,
+			const char *buf, size_t count);
+ssize_t show_iwmct_log_level_fw(struct device *d,
+			struct device_attribute *attr, char *buf);
+ssize_t store_iwmct_log_level_fw(struct device *d,
+			struct device_attribute *attr,
+			const char *buf, size_t count);
+
+#else
+
+#define LOG_CRITICAL(priv, src, fmt, args...)
+#define LOG_ERROR(priv, src, fmt, args...)
+#define LOG_WARNING(priv, src, fmt, args...)
+#define LOG_INFO(priv, src, fmt, args...)
+#define LOG_INFOEX(priv, src, fmt, args...)
+#define LOG_HEXDUMP(src, ptr, len)
+
+static inline void iwmct_log_top_message(struct iwmct_priv *priv,
+					 u8 *buf, int len) {}
+static inline int iwmct_log_set_filter(u8 src, u8 logmask) { return 0; }
+static inline int iwmct_log_set_fw_filter(u8 src, u8 logmask) { return 0; }
+
+#endif /* CONFIG_IWMC3200TOP_DEBUG */
+
+int log_get_filter_str(char *buf, int size);
+int log_get_fw_filter_str(char *buf, int size);
+
+#endif /* __LOG_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/main.c linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/main.c
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/main.c	2013-05-03 12:10:06.000000000 -0400
@@ -0,0 +1,678 @@
+/*
+ * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+ * drivers/misc/iwmc3200top/main.c
+ *
+ * Copyright (C) 2009 Intel Corporation. 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+ *  -
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio.h>
+
+#include "iwmc3200top.h"
+#include "log.h"
+#include "fw-msg.h"
+#include "debugfs.h"
+
+
+#define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
+#define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
+
+#define DRIVER_VERSION  "0.1.62"
+
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR(DRIVER_COPYRIGHT);
+/*(DEBLOBBED)*/
+
+/*
+ * This workers main task is to wait for OP_OPR_ALIVE
+ * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
+ * When OP_OPR_ALIVE received it will issue
+ * a call to "bus_rescan_devices".
+ */
+static void iwmct_rescan_worker(struct work_struct *ws)
+{
+	struct iwmct_priv *priv;
+	int ret;
+
+	priv = container_of(ws, struct iwmct_priv, bus_rescan_worker);
+
+	LOG_INFO(priv, FW_MSG, "Calling bus_rescan\n");
+
+	ret = bus_rescan_devices(priv->func->dev.bus);
+	if (ret < 0)
+		LOG_INFO(priv, FW_DOWNLOAD, "bus_rescan_devices FAILED!!!\n");
+}
+
+static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
+{
+	switch (msg->hdr.opcode) {
+	case OP_OPR_ALIVE:
+		LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
+		queue_work(priv->bus_rescan_wq, &priv->bus_rescan_worker);
+		break;
+	default:
+		LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
+			msg->hdr.opcode);
+		break;
+	}
+}
+
+
+static void handle_top_message(struct iwmct_priv *priv, u8 *buf, int len)
+{
+	struct top_msg *msg;
+
+	msg = (struct top_msg *)buf;
+
+	if (msg->hdr.type != COMM_TYPE_D2H) {
+		LOG_ERROR(priv, FW_MSG,
+			"Message from TOP with invalid message type 0x%X\n",
+			msg->hdr.type);
+		return;
+	}
+
+	if (len < sizeof(msg->hdr)) {
+		LOG_ERROR(priv, FW_MSG,
+			"Message from TOP is too short for message header "
+			"received %d bytes, expected at least %zd bytes\n",
+			len, sizeof(msg->hdr));
+		return;
+	}
+
+	if (len < le16_to_cpu(msg->hdr.length) + sizeof(msg->hdr)) {
+		LOG_ERROR(priv, FW_MSG,
+			"Message length (%d bytes) is shorter than "
+			"in header (%d bytes)\n",
+			len, le16_to_cpu(msg->hdr.length));
+		return;
+	}
+
+	switch (msg->hdr.category) {
+	case COMM_CATEGORY_OPERATIONAL:
+		op_top_message(priv, (struct top_msg *)buf);
+		break;
+
+	case COMM_CATEGORY_DEBUG:
+	case COMM_CATEGORY_TESTABILITY:
+	case COMM_CATEGORY_DIAGNOSTICS:
+		iwmct_log_top_message(priv, buf, len);
+		break;
+
+	default:
+		LOG_ERROR(priv, FW_MSG,
+			"Message from TOP with unknown category 0x%X\n",
+			msg->hdr.category);
+		break;
+	}
+}
+
+int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len)
+{
+	int ret;
+	u8 *buf;
+
+	LOG_INFOEX(priv, FW_MSG, "Sending hcmd:\n");
+
+	/* add padding to 256 for IWMC */
+	((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
+
+	LOG_HEXDUMP(FW_MSG, cmd, len);
+
+	if (len > FW_HCMD_BLOCK_SIZE) {
+		LOG_ERROR(priv, FW_MSG, "size %d exceeded hcmd max size %d\n",
+			  len, FW_HCMD_BLOCK_SIZE);
+		return -1;
+	}
+
+	buf = kzalloc(FW_HCMD_BLOCK_SIZE, GFP_KERNEL);
+	if (!buf) {
+		LOG_ERROR(priv, FW_MSG, "kzalloc error, buf size %d\n",
+			  FW_HCMD_BLOCK_SIZE);
+		return -1;
+	}
+
+	memcpy(buf, cmd, len);
+
+	sdio_claim_host(priv->func);
+	ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, buf,
+			       FW_HCMD_BLOCK_SIZE);
+	sdio_release_host(priv->func);
+
+	kfree(buf);
+	return ret;
+}
+
+int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
+	void *src, int count)
+{
+	int ret;
+
+	sdio_claim_host(priv->func);
+	ret = sdio_memcpy_toio(priv->func, addr, src, count);
+	sdio_release_host(priv->func);
+
+	return ret;
+}
+
+static void iwmct_irq_read_worker(struct work_struct *ws)
+{
+	struct iwmct_priv *priv;
+	struct iwmct_work_struct *read_req;
+	__le32 *buf = NULL;
+	int ret;
+	int iosize;
+	u32 barker;
+	bool is_barker;
+
+	priv = container_of(ws, struct iwmct_priv, isr_worker);
+
+	LOG_INFO(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
+
+	/* --------------------- Handshake with device -------------------- */
+	sdio_claim_host(priv->func);
+
+	/* all list manipulations have to be protected by
+	 * sdio_claim_host/sdio_release_host */
+	if (list_empty(&priv->read_req_list)) {
+		LOG_ERROR(priv, IRQ, "read_req_list empty in read worker\n");
+		goto exit_release;
+	}
+
+	read_req = list_entry(priv->read_req_list.next,
+			      struct iwmct_work_struct, list);
+
+	list_del(&read_req->list);
+	iosize = read_req->iosize;
+	kfree(read_req);
+
+	buf = kzalloc(iosize, GFP_KERNEL);
+	if (!buf) {
+		LOG_ERROR(priv, IRQ, "kzalloc error, buf size %d\n", iosize);
+		goto exit_release;
+	}
+
+	LOG_INFO(priv, IRQ, "iosize=%d, buf=%p, func=%d\n",
+				iosize, buf, priv->func->num);
+
+	/* read from device */
+	ret = sdio_memcpy_fromio(priv->func, buf, IWMC_SDIO_DATA_ADDR, iosize);
+	if (ret) {
+		LOG_ERROR(priv, IRQ, "error %d reading buffer\n", ret);
+		goto exit_release;
+	}
+
+	LOG_HEXDUMP(IRQ, (u8 *)buf, iosize);
+
+	barker = le32_to_cpu(buf[0]);
+
+	/* Verify whether it's a barker and if not - treat as regular Rx */
+	if (barker == IWMC_BARKER_ACK ||
+	    (barker & BARKER_DNLOAD_BARKER_MSK) == IWMC_BARKER_REBOOT) {
+
+		/* Valid Barker is equal on first 4 dwords */
+		is_barker = (buf[1] == buf[0]) &&
+			    (buf[2] == buf[0]) &&
+			    (buf[3] == buf[0]);
+
+		if (!is_barker) {
+			LOG_WARNING(priv, IRQ,
+				"Potentially inconsistent barker "
+				"%08X_%08X_%08X_%08X\n",
+				le32_to_cpu(buf[0]), le32_to_cpu(buf[1]),
+				le32_to_cpu(buf[2]), le32_to_cpu(buf[3]));
+		}
+	} else {
+		is_barker = false;
+	}
+
+	/* Handle Top CommHub message */
+	if (!is_barker) {
+		sdio_release_host(priv->func);
+		handle_top_message(priv, (u8 *)buf, iosize);
+		goto exit;
+	} else if (barker == IWMC_BARKER_ACK) { /* Handle barkers */
+		if (atomic_read(&priv->dev_sync) == 0) {
+			LOG_ERROR(priv, IRQ,
+				  "ACK barker arrived out-of-sync\n");
+			goto exit_release;
+		}
+
+		/* Continuing to FW download (after Sync is completed)*/
+		atomic_set(&priv->dev_sync, 0);
+		LOG_INFO(priv, IRQ, "ACK barker arrived "
+				"- starting FW download\n");
+	} else { /* REBOOT barker */
+		LOG_INFO(priv, IRQ, "Recieved reboot barker: %x\n", barker);
+		priv->barker = barker;
+
+		if (barker & BARKER_DNLOAD_SYNC_MSK) {
+			/* Send the same barker back */
+			ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR,
+					       buf, iosize);
+			if (ret) {
+				LOG_ERROR(priv, IRQ,
+					 "error %d echoing barker\n", ret);
+				goto exit_release;
+			}
+			LOG_INFO(priv, IRQ, "Echoing barker to device\n");
+			atomic_set(&priv->dev_sync, 1);
+			goto exit_release;
+		}
+
+		/* Continuing to FW download (without Sync) */
+		LOG_INFO(priv, IRQ, "No sync requested "
+				    "- starting FW download\n");
+	}
+
+	sdio_release_host(priv->func);
+
+
+	LOG_INFO(priv, IRQ, "barker download request 0x%x is:\n", priv->barker);
+	LOG_INFO(priv, IRQ, "*******  Top FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
+	LOG_INFO(priv, IRQ, "*******  GPS FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
+	LOG_INFO(priv, IRQ, "*******  BT FW %s requested ********\n",
+			(priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
+
+	if (priv->dbg.fw_download)
+		iwmct_fw_load(priv);
+	else
+		LOG_ERROR(priv, IRQ, "FW download not allowed\n");
+
+	goto exit;
+
+exit_release:
+	sdio_release_host(priv->func);
+exit:
+	kfree(buf);
+	LOG_INFO(priv, IRQ, "exit iwmct_irq_read_worker\n");
+}
+
+static void iwmct_irq(struct sdio_func *func)
+{
+	struct iwmct_priv *priv;
+	int val, ret;
+	int iosize;
+	int addr = IWMC_SDIO_INTR_GET_SIZE_ADDR;
+	struct iwmct_work_struct *read_req;
+
+	priv = sdio_get_drvdata(func);
+
+	LOG_INFO(priv, IRQ, "enter iwmct_irq\n");
+
+	/* read the function's status register */
+	val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
+
+	LOG_INFO(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
+
+	if (!val) {
+		LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
+		goto exit_clear_intr;
+	}
+
+
+	/*
+	 * read 2 bytes of the transaction size
+	 * IMPORTANT: sdio transaction size has to be read before clearing
+	 * sdio interrupt!!!
+	 */
+	val = sdio_readb(priv->func, addr++, &ret);
+	iosize = val;
+	val = sdio_readb(priv->func, addr++, &ret);
+	iosize += val << 8;
+
+	LOG_INFO(priv, IRQ, "READ size %d\n", iosize);
+
+	if (iosize == 0) {
+		LOG_ERROR(priv, IRQ, "READ size %d, exiting ISR\n", iosize);
+		goto exit_clear_intr;
+	}
+
+	/* allocate a work structure to pass iosize to the worker */
+	read_req = kzalloc(sizeof(struct iwmct_work_struct), GFP_KERNEL);
+	if (!read_req) {
+		LOG_ERROR(priv, IRQ, "failed to allocate read_req, exit ISR\n");
+		goto exit_clear_intr;
+	}
+
+	INIT_LIST_HEAD(&read_req->list);
+	read_req->iosize = iosize;
+
+	list_add_tail(&priv->read_req_list, &read_req->list);
+
+	/* clear the function's interrupt request bit (write 1 to clear) */
+	sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
+
+	queue_work(priv->wq, &priv->isr_worker);
+
+	LOG_INFO(priv, IRQ, "exit iwmct_irq\n");
+
+	return;
+
+exit_clear_intr:
+	/* clear the function's interrupt request bit (write 1 to clear) */
+	sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
+}
+
+
+static int blocks;
+module_param(blocks, int, 0604);
+MODULE_PARM_DESC(blocks, "max_blocks_to_send");
+
+static int dump;
+module_param(dump, bool, 0604);
+MODULE_PARM_DESC(dump, "dump_hex_content");
+
+static int jump = 1;
+module_param(jump, bool, 0604);
+
+static int direct = 1;
+module_param(direct, bool, 0604);
+
+static int checksum = 1;
+module_param(checksum, bool, 0604);
+
+static int fw_download = 1;
+module_param(fw_download, bool, 0604);
+
+static int block_size = IWMC_SDIO_BLK_SIZE;
+module_param(block_size, int, 0404);
+
+static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
+module_param(download_trans_blks, int, 0604);
+
+static int rubbish_barker;
+module_param(rubbish_barker, bool, 0604);
+
+#ifdef CONFIG_IWMC3200TOP_DEBUG
+static int log_level[LOG_SRC_MAX];
+static unsigned int log_level_argc;
+module_param_array(log_level, int, &log_level_argc, 0604);
+MODULE_PARM_DESC(log_level, "log_level");
+
+static int log_level_fw[FW_LOG_SRC_MAX];
+static unsigned int log_level_fw_argc;
+module_param_array(log_level_fw, int, &log_level_fw_argc, 0604);
+MODULE_PARM_DESC(log_level_fw, "log_level_fw");
+#endif
+
+void iwmct_dbg_init_params(struct iwmct_priv *priv)
+{
+#ifdef CONFIG_IWMC3200TOP_DEBUG
+	int i;
+
+	for (i = 0; i < log_level_argc; i++) {
+		dev_notice(&priv->func->dev, "log_level[%d]=0x%X\n",
+						i, log_level[i]);
+		iwmct_log_set_filter((log_level[i] >> 8) & 0xFF,
+			       log_level[i] & 0xFF);
+	}
+	for (i = 0; i < log_level_fw_argc; i++) {
+		dev_notice(&priv->func->dev, "log_level_fw[%d]=0x%X\n",
+						i, log_level_fw[i]);
+		iwmct_log_set_fw_filter((log_level_fw[i] >> 8) & 0xFF,
+				  log_level_fw[i] & 0xFF);
+	}
+#endif
+
+	priv->dbg.blocks = blocks;
+	LOG_INFO(priv, INIT, "blocks=%d\n", blocks);
+	priv->dbg.dump = (bool)dump;
+	LOG_INFO(priv, INIT, "dump=%d\n", dump);
+	priv->dbg.jump = (bool)jump;
+	LOG_INFO(priv, INIT, "jump=%d\n", jump);
+	priv->dbg.direct = (bool)direct;
+	LOG_INFO(priv, INIT, "direct=%d\n", direct);
+	priv->dbg.checksum = (bool)checksum;
+	LOG_INFO(priv, INIT, "checksum=%d\n", checksum);
+	priv->dbg.fw_download = (bool)fw_download;
+	LOG_INFO(priv, INIT, "fw_download=%d\n", fw_download);
+	priv->dbg.block_size = block_size;
+	LOG_INFO(priv, INIT, "block_size=%d\n", block_size);
+	priv->dbg.download_trans_blks = download_trans_blks;
+	LOG_INFO(priv, INIT, "download_trans_blks=%d\n", download_trans_blks);
+}
+
+/*****************************************************************************
+ *
+ * sysfs attributes
+ *
+ *****************************************************************************/
+static ssize_t show_iwmct_fw_version(struct device *d,
+				  struct device_attribute *attr, char *buf)
+{
+	struct iwmct_priv *priv = dev_get_drvdata(d);
+	return sprintf(buf, "%s\n", priv->dbg.label_fw);
+}
+static DEVICE_ATTR(cc_label_fw, S_IRUGO, show_iwmct_fw_version, NULL);
+
+#ifdef CONFIG_IWMC3200TOP_DEBUG
+static DEVICE_ATTR(log_level, S_IWUSR | S_IRUGO,
+		   show_iwmct_log_level, store_iwmct_log_level);
+static DEVICE_ATTR(log_level_fw, S_IWUSR | S_IRUGO,
+		   show_iwmct_log_level_fw, store_iwmct_log_level_fw);
+#endif
+
+static struct attribute *iwmct_sysfs_entries[] = {
+	&dev_attr_cc_label_fw.attr,
+#ifdef CONFIG_IWMC3200TOP_DEBUG
+	&dev_attr_log_level.attr,
+	&dev_attr_log_level_fw.attr,
+#endif
+	NULL
+};
+
+static struct attribute_group iwmct_attribute_group = {
+	.name = NULL,		/* put in device directory */
+	.attrs = iwmct_sysfs_entries,
+};
+
+
+static int iwmct_probe(struct sdio_func *func,
+			   const struct sdio_device_id *id)
+{
+	struct iwmct_priv *priv;
+	int ret;
+	int val = 1;
+	int addr = IWMC_SDIO_INTR_ENABLE_ADDR;
+
+	dev_dbg(&func->dev, "enter iwmct_probe\n");
+
+	dev_dbg(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n",
+		jiffies_to_msecs(2147483647), HZ);
+
+	priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&func->dev, "kzalloc error\n");
+		return -ENOMEM;
+	}
+	priv->func = func;
+	sdio_set_drvdata(func, priv);
+
+
+	/* create drivers work queue */
+	priv->wq = create_workqueue(DRV_NAME "_wq");
+	priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq");
+	INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
+	INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
+
+	init_waitqueue_head(&priv->wait_q);
+
+	sdio_claim_host(func);
+	/* FIXME: Remove after it is fixed in the Boot ROM upgrade */
+	func->enable_timeout = 10;
+
+	/* In our HW, setting the block size also wakes up the boot rom. */
+	ret = sdio_set_block_size(func, priv->dbg.block_size);
+	if (ret) {
+		LOG_ERROR(priv, INIT,
+			"sdio_set_block_size() failure: %d\n", ret);
+		goto error_sdio_enable;
+	}
+
+	ret = sdio_enable_func(func);
+	if (ret) {
+		LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret);
+		goto error_sdio_enable;
+	}
+
+	/* init reset and dev_sync states */
+	atomic_set(&priv->reset, 0);
+	atomic_set(&priv->dev_sync, 0);
+
+	/* init read req queue */
+	INIT_LIST_HEAD(&priv->read_req_list);
+
+	/* process configurable parameters */
+	iwmct_dbg_init_params(priv);
+	ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group);
+	if (ret) {
+		LOG_ERROR(priv, INIT, "Failed to register attributes and "
+			 "initialize module_params\n");
+		goto error_dev_attrs;
+	}
+
+	iwmct_dbgfs_register(priv, DRV_NAME);
+
+	if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) {
+		LOG_INFO(priv, INIT,
+			 "Reducing transaction to 8 blocks = 2K (from %d)\n",
+			 priv->dbg.download_trans_blks);
+		priv->dbg.download_trans_blks = 8;
+	}
+	priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size;
+	LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len);
+
+	ret = sdio_claim_irq(func, iwmct_irq);
+	if (ret) {
+		LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret);
+		goto error_claim_irq;
+	}
+
+
+	/* Enable function's interrupt */
+	sdio_writeb(priv->func, val, addr, &ret);
+	if (ret) {
+		LOG_ERROR(priv, INIT, "Failure writing to "
+			  "Interrupt Enable Register (%d): %d\n", addr, ret);
+		goto error_enable_int;
+	}
+
+	sdio_release_host(func);
+
+	LOG_INFO(priv, INIT, "exit iwmct_probe\n");
+
+	return ret;
+
+error_enable_int:
+	sdio_release_irq(func);
+error_claim_irq:
+	sdio_disable_func(func);
+error_dev_attrs:
+	iwmct_dbgfs_unregister(priv->dbgfs);
+	sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
+error_sdio_enable:
+	sdio_release_host(func);
+	return ret;
+}
+
+static void iwmct_remove(struct sdio_func *func)
+{
+	struct iwmct_work_struct *read_req;
+	struct iwmct_priv *priv = sdio_get_drvdata(func);
+
+	priv = sdio_get_drvdata(func);
+
+	LOG_INFO(priv, INIT, "enter\n");
+
+	sdio_claim_host(func);
+	sdio_release_irq(func);
+	sdio_release_host(func);
+
+	/* Safely destroy osc workqueue */
+	destroy_workqueue(priv->bus_rescan_wq);
+	destroy_workqueue(priv->wq);
+
+	sdio_claim_host(func);
+	sdio_disable_func(func);
+	sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
+	iwmct_dbgfs_unregister(priv->dbgfs);
+	sdio_release_host(func);
+
+	/* free read requests */
+	while (!list_empty(&priv->read_req_list)) {
+		read_req = list_entry(priv->read_req_list.next,
+			struct iwmct_work_struct, list);
+
+		list_del(&read_req->list);
+		kfree(read_req);
+	}
+
+	kfree(priv);
+}
+
+
+static const struct sdio_device_id iwmct_ids[] = {
+	/* Intel Wireless MultiCom 3200 Top Driver */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1404)},
+	{ },	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(sdio, iwmct_ids);
+
+static struct sdio_driver iwmct_driver = {
+	.probe		= iwmct_probe,
+	.remove		= iwmct_remove,
+	.name		= DRV_NAME,
+	.id_table	= iwmct_ids,
+};
+
+static int __init iwmct_init(void)
+{
+	int rc;
+
+	/* Default log filter settings */
+	iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
+	iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FILTER_ALL);
+	iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
+
+	rc = sdio_register_driver(&iwmct_driver);
+
+	return rc;
+}
+
+static void __exit iwmct_exit(void)
+{
+	sdio_unregister_driver(&iwmct_driver);
+}
+
+module_init(iwmct_init);
+module_exit(iwmct_exit);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/Makefile linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/Makefile
--- linux-libre-2.6.32-gnu1/drivers/misc/iwmc3200top/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/iwmc3200top/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,29 @@
+# iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
+# drivers/misc/iwmc3200top/Makefile
+#
+# Copyright (C) 2009 Intel Corporation. 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You 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.
+#
+#
+# Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
+#  -
+#
+#
+
+obj-$(CONFIG_IWMC3200TOP)	+= iwmc3200top.o
+iwmc3200top-objs	:= main.o fw-download.o
+iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUG) += log.o
+iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUGFS) += debugfs.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/Kconfig linux-libre-2.6.33-gnu1/drivers/misc/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/misc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,20 @@ menuconfig MISC_DEVICES
 
 if MISC_DEVICES
 
+config AD525X_DPOT
+	tristate "Analog Devices AD525x Digital Potentiometers"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here, you get support for the Analog Devices
+	  AD5258, AD5259, AD5251, AD5252, AD5253, AD5254 and AD5255
+	  digital potentiometer chips.
+
+	  See Documentation/misc-devices/ad525x_dpot.txt for the
+	  userspace interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called ad525x_dpot.
+
 config ATMEL_PWM
 	tristate "Atmel AT32/AT91 PWM support"
 	depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
@@ -173,6 +187,31 @@ config SGI_XP
 	  this feature will allow for direct communication between SSIs
 	  based on a network adapter and DMA messaging.
 
+config CS5535_MFGPT
+	tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support"
+	depends on PCI
+	depends on X86
+	default n
+	help
+	  This driver provides access to MFGPT functionality for other
+	  drivers that need timers.  MFGPTs are available in the CS5535 and
+	  CS5536 companion chips that are found in AMD Geode and several
+	  other platforms.  They have a better resolution and max interval
+	  than the generic PIT, and are suitable for use as high-res timers.
+	  You probably don't want to enable this manually; other drivers that
+	  make use of it should enable it.
+
+config CS5535_MFGPT_DEFAULT_IRQ
+	int
+	depends on CS5535_MFGPT
+	default 7
+	help
+	  MFGPTs on the CS5535 require an interrupt.  The selected IRQ
+	  can be overridden as a module option as well as by driver that
+	  use the cs5535_mfgpt_ API; however, different architectures might
+	  want to use a different IRQ by default.  This is here for
+	  architectures to set as necessary.
+
 config HP_ILO
 	tristate "Channel interface driver for HP iLO/iLO2 processor"
 	depends on PCI
@@ -210,19 +249,6 @@ config SGI_GRU_DEBUG
 	This option enables addition debugging code for the SGI GRU driver. If
 	you are unsure, say N.
 
-config DELL_LAPTOP
-	tristate "Dell Laptop Extras (EXPERIMENTAL)"
-	depends on X86
-	depends on DCDBAS
-	depends on EXPERIMENTAL
-	depends on BACKLIGHT_CLASS_DEVICE
-	depends on RFKILL
-	depends on POWER_SUPPLY
-	default n
-	---help---
-	This driver adds support for rfkill and backlight control to Dell
-	laptops.
-
 config ISL29003
 	tristate "Intersil ISL29003 ambient light sensor"
 	depends on I2C && SYSFS
@@ -246,8 +272,29 @@ config EP93XX_PWM
 	  To compile this driver as a module, choose M here: the module will
 	  be called ep93xx_pwm.
 
+config DS1682
+	tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for Dallas Semiconductor
+	  DS1682 Total Elapsed Time Recorder.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called ds1682.
+
+config TI_DAC7512
+	tristate "Texas Instruments DAC7512"
+	depends on SPI && SYSFS
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  DAC7512 16-bit digital-to-analog converter.
+
+	  This driver can also be built as a module. If so, the module
+	  will be calles ti_dac7512.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
+source "drivers/misc/iwmc3200top/Kconfig"
 
 endif # MISC_DEVICES
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/kgdbts.c linux-libre-2.6.33-gnu1/drivers/misc/kgdbts.c
--- linux-libre-2.6.32-gnu1/drivers/misc/kgdbts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/kgdbts.c	2010-02-24 13:52:17.000000000 -0500
@@ -712,6 +712,12 @@ static int run_simple_test(int is_get_ch
 
 	/* End of packet == #XX so look for the '#' */
 	if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') {
+		if (put_buf_cnt >= BUFMAX) {
+			eprintk("kgdbts: ERROR: put buffer overflow on"
+				" '%s' line %i\n", ts.name, ts.idx);
+			put_buf_cnt = 0;
+			return 0;
+		}
 		put_buf[put_buf_cnt] = '\0';
 		v2printk("put%i: %s\n", ts.idx, put_buf);
 		/* Trigger check here */
@@ -885,16 +891,16 @@ static void kgdbts_run_tests(void)
 	int nmi_sleep = 0;
 	int i;
 
-	ptr = strstr(config, "F");
+	ptr = strchr(config, 'F');
 	if (ptr)
 		fork_test = simple_strtol(ptr + 1, NULL, 10);
-	ptr = strstr(config, "S");
+	ptr = strchr(config, 'S');
 	if (ptr)
 		do_sys_open_test = simple_strtol(ptr + 1, NULL, 10);
-	ptr = strstr(config, "N");
+	ptr = strchr(config, 'N');
 	if (ptr)
 		nmi_sleep = simple_strtol(ptr+1, NULL, 10);
-	ptr = strstr(config, "I");
+	ptr = strchr(config, 'I');
 	if (ptr)
 		sstep_test = simple_strtol(ptr+1, NULL, 10);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/Makefile linux-libre-2.6.33-gnu1/drivers/misc/Makefile
--- linux-libre-2.6.32-gnu1/drivers/misc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_IBM_ASM)		+= ibmasm/
 obj-$(CONFIG_HDPU_FEATURES)	+= hdpuftrs/
+obj-$(CONFIG_AD525X_DPOT)	+= ad525x_dpot.o
 obj-$(CONFIG_ATMEL_PWM)		+= atmel_pwm.o
 obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o
 obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib.o
@@ -17,9 +18,13 @@ obj-$(CONFIG_ENCLOSURE_SERVICES) += encl
 obj-$(CONFIG_KGDB_TESTS)	+= kgdbts.o
 obj-$(CONFIG_SGI_XP)		+= sgi-xp/
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
+obj-$(CONFIG_CS5535_MFGPT)	+= cs5535-mfgpt.o
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_EP93XX_PWM)	+= ep93xx_pwm.o
+obj-$(CONFIG_DS1682)		+= ds1682.o
+obj-$(CONFIG_TI_DAC7512)	+= ti_dac7512.o
 obj-$(CONFIG_C2PORT)		+= c2port/
+obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y				+= eeprom/
 obj-y				+= cb710/
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grufault.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grufault.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grufault.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grufault.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,12 @@
 #include "gru_instructions.h"
 #include <asm/uv/uv_hub.h>
 
+/* Return codes for vtop functions */
+#define VTOP_SUCCESS               0
+#define VTOP_INVALID               -1
+#define VTOP_RETRY                 -2
+
+
 /*
  * Test if a physical address is a valid GRU GSEG address
  */
@@ -90,19 +96,22 @@ static struct gru_thread_state *gru_allo
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
-	struct gru_thread_state *gts = NULL;
+	struct gru_thread_state *gts = ERR_PTR(-EINVAL);
 
 	down_write(&mm->mmap_sem);
 	vma = gru_find_vma(vaddr);
-	if (vma)
-		gts = gru_alloc_thread_state(vma, TSID(vaddr, vma));
-	if (gts) {
-		mutex_lock(&gts->ts_ctxlock);
-		downgrade_write(&mm->mmap_sem);
-	} else {
-		up_write(&mm->mmap_sem);
-	}
+	if (!vma)
+		goto err;
 
+	gts = gru_alloc_thread_state(vma, TSID(vaddr, vma));
+	if (IS_ERR(gts))
+		goto err;
+	mutex_lock(&gts->ts_ctxlock);
+	downgrade_write(&mm->mmap_sem);
+	return gts;
+
+err:
+	up_write(&mm->mmap_sem);
 	return gts;
 }
 
@@ -122,39 +131,15 @@ static void gru_unlock_gts(struct gru_th
  * is necessary to prevent the user from seeing a stale cb.istatus that will
  * change as soon as the TFH restart is complete. Races may cause an
  * occasional failure to clear the cb.istatus, but that is ok.
- *
- * If the cb address is not valid (should not happen, but...), nothing
- * bad will happen.. The get_user()/put_user() will fail but there
- * are no bad side-effects.
  */
-static void gru_cb_set_istatus_active(unsigned long __user *cb)
+static void gru_cb_set_istatus_active(struct gru_instruction_bits *cbk)
 {
-	union {
-		struct gru_instruction_bits bits;
-		unsigned long dw;
-	} u;
-
-	if (cb) {
-		get_user(u.dw, cb);
-		u.bits.istatus = CBS_ACTIVE;
-		put_user(u.dw, cb);
+	if (cbk) {
+		cbk->istatus = CBS_ACTIVE;
 	}
 }
 
 /*
- * Convert a interrupt IRQ to a pointer to the GRU GTS that caused the
- * interrupt. Interrupts are always sent to a cpu on the blade that contains the
- * GRU (except for headless blades which are not currently supported). A blade
- * has N grus; a block of N consecutive IRQs is assigned to the GRUs. The IRQ
- * number uniquely identifies the GRU chiplet on the local blade that caused the
- * interrupt. Always called in interrupt context.
- */
-static inline struct gru_state *irq_to_gru(int irq)
-{
-	return &gru_base[uv_numa_blade_id()]->bs_grus[irq - IRQ_GRU];
-}
-
-/*
  * Read & clear a TFM
  *
  * The GRU has an array of fault maps. A map is private to a cpu
@@ -207,10 +192,11 @@ static int non_atomic_pte_lookup(struct
 {
 	struct page *page;
 
-	/* ZZZ Need to handle HUGE pages */
-	if (is_vm_hugetlb_page(vma))
-		return -EFAULT;
+#ifdef CONFIG_HUGETLB_PAGE
+	*pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT;
+#else
 	*pageshift = PAGE_SHIFT;
+#endif
 	if (get_user_pages
 	    (current, current->mm, vaddr, 1, write, 0, &page, NULL) <= 0)
 		return -EFAULT;
@@ -268,7 +254,6 @@ static int atomic_pte_lookup(struct vm_a
 	return 0;
 
 err:
-	local_irq_enable();
 	return 1;
 }
 
@@ -301,14 +286,69 @@ static int gru_vtop(struct gru_thread_st
 	paddr = paddr & ~((1UL << ps) - 1);
 	*gpa = uv_soc_phys_ram_to_gpa(paddr);
 	*pageshift = ps;
-	return 0;
+	return VTOP_SUCCESS;
 
 inval:
-	return -1;
+	return VTOP_INVALID;
 upm:
-	return -2;
+	return VTOP_RETRY;
+}
+
+
+/*
+ * Flush a CBE from cache. The CBE is clean in the cache. Dirty the
+ * CBE cacheline so that the line will be written back to home agent.
+ * Otherwise the line may be silently dropped. This has no impact
+ * except on performance.
+ */
+static void gru_flush_cache_cbe(struct gru_control_block_extended *cbe)
+{
+	if (unlikely(cbe)) {
+		cbe->cbrexecstatus = 0;         /* make CL dirty */
+		gru_flush_cache(cbe);
+	}
 }
 
+/*
+ * Preload the TLB with entries that may be required. Currently, preloading
+ * is implemented only for BCOPY. Preload  <tlb_preload_count> pages OR to
+ * the end of the bcopy tranfer, whichever is smaller.
+ */
+static void gru_preload_tlb(struct gru_state *gru,
+			struct gru_thread_state *gts, int atomic,
+			unsigned long fault_vaddr, int asid, int write,
+			unsigned char tlb_preload_count,
+			struct gru_tlb_fault_handle *tfh,
+			struct gru_control_block_extended *cbe)
+{
+	unsigned long vaddr = 0, gpa;
+	int ret, pageshift;
+
+	if (cbe->opccpy != OP_BCOPY)
+		return;
+
+	if (fault_vaddr == cbe->cbe_baddr0)
+		vaddr = fault_vaddr + GRU_CACHE_LINE_BYTES * cbe->cbe_src_cl - 1;
+	else if (fault_vaddr == cbe->cbe_baddr1)
+		vaddr = fault_vaddr + (1 << cbe->xtypecpy) * cbe->cbe_nelemcur - 1;
+
+	fault_vaddr &= PAGE_MASK;
+	vaddr &= PAGE_MASK;
+	vaddr = min(vaddr, fault_vaddr + tlb_preload_count * PAGE_SIZE);
+
+	while (vaddr > fault_vaddr) {
+		ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
+		if (ret || tfh_write_only(tfh, gpa, GAA_RAM, vaddr, asid, write,
+					  GRU_PAGESIZE(pageshift)))
+			return;
+		gru_dbg(grudev,
+			"%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, rw %d, ps %d, gpa 0x%lx\n",
+			atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh,
+			vaddr, asid, write, pageshift, gpa);
+		vaddr -= PAGE_SIZE;
+		STAT(tlb_preload_page);
+	}
+}
 
 /*
  * Drop a TLB entry into the GRU. The fault is described by info in an TFH.
@@ -320,11 +360,14 @@ upm:
  * 		< 0 = error code
  *
  */
-static int gru_try_dropin(struct gru_thread_state *gts,
+static int gru_try_dropin(struct gru_state *gru,
+			  struct gru_thread_state *gts,
 			  struct gru_tlb_fault_handle *tfh,
-			  unsigned long __user *cb)
+			  struct gru_instruction_bits *cbk)
 {
-	int pageshift = 0, asid, write, ret, atomic = !cb;
+	struct gru_control_block_extended *cbe = NULL;
+	unsigned char tlb_preload_count = gts->ts_tlb_preload_count;
+	int pageshift = 0, asid, write, ret, atomic = !cbk, indexway;
 	unsigned long gpa = 0, vaddr = 0;
 
 	/*
@@ -335,24 +378,34 @@ static int gru_try_dropin(struct gru_thr
 	 */
 
 	/*
+	 * Prefetch the CBE if doing TLB preloading
+	 */
+	if (unlikely(tlb_preload_count)) {
+		cbe = gru_tfh_to_cbe(tfh);
+		prefetchw(cbe);
+	}
+
+	/*
 	 * Error if TFH state is IDLE or FMM mode & the user issuing a UPM call.
 	 * Might be a hardware race OR a stupid user. Ignore FMM because FMM
 	 * is a transient state.
 	 */
 	if (tfh->status != TFHSTATUS_EXCEPTION) {
 		gru_flush_cache(tfh);
+		sync_core();
 		if (tfh->status != TFHSTATUS_EXCEPTION)
 			goto failnoexception;
 		STAT(tfh_stale_on_fault);
 	}
 	if (tfh->state == TFHSTATE_IDLE)
 		goto failidle;
-	if (tfh->state == TFHSTATE_MISS_FMM && cb)
+	if (tfh->state == TFHSTATE_MISS_FMM && cbk)
 		goto failfmm;
 
 	write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0;
 	vaddr = tfh->missvaddr;
 	asid = tfh->missasid;
+	indexway = tfh->indexway;
 	if (asid == 0)
 		goto failnoasid;
 
@@ -366,41 +419,51 @@ static int gru_try_dropin(struct gru_thr
 		goto failactive;
 
 	ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
-	if (ret == -1)
+	if (ret == VTOP_INVALID)
 		goto failinval;
-	if (ret == -2)
+	if (ret == VTOP_RETRY)
 		goto failupm;
 
 	if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
 		gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
-		if (atomic || !gru_update_cch(gts, 0)) {
+		if (atomic || !gru_update_cch(gts)) {
 			gts->ts_force_cch_reload = 1;
 			goto failupm;
 		}
 	}
-	gru_cb_set_istatus_active(cb);
+
+	if (unlikely(cbe) && pageshift == PAGE_SHIFT) {
+		gru_preload_tlb(gru, gts, atomic, vaddr, asid, write, tlb_preload_count, tfh, cbe);
+		gru_flush_cache_cbe(cbe);
+	}
+
+	gru_cb_set_istatus_active(cbk);
+	gts->ustats.tlbdropin++;
 	tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
 			  GRU_PAGESIZE(pageshift));
-	STAT(tlb_dropin);
 	gru_dbg(grudev,
-		"%s: tfh 0x%p, vaddr 0x%lx, asid 0x%x, ps %d, gpa 0x%lx\n",
-		ret ? "non-atomic" : "atomic", tfh, vaddr, asid,
-		pageshift, gpa);
+		"%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, indexway 0x%x,"
+		" rw %d, ps %d, gpa 0x%lx\n",
+		atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh, vaddr, asid,
+		indexway, write, pageshift, gpa);
+	STAT(tlb_dropin);
 	return 0;
 
 failnoasid:
 	/* No asid (delayed unload). */
 	STAT(tlb_dropin_fail_no_asid);
 	gru_dbg(grudev, "FAILED no_asid tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
-	if (!cb)
+	if (!cbk)
 		tfh_user_polling_mode(tfh);
 	else
 		gru_flush_cache(tfh);
+	gru_flush_cache_cbe(cbe);
 	return -EAGAIN;
 
 failupm:
 	/* Atomic failure switch CBR to UPM */
 	tfh_user_polling_mode(tfh);
+	gru_flush_cache_cbe(cbe);
 	STAT(tlb_dropin_fail_upm);
 	gru_dbg(grudev, "FAILED upm tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
 	return 1;
@@ -408,6 +471,7 @@ failupm:
 failfmm:
 	/* FMM state on UPM call */
 	gru_flush_cache(tfh);
+	gru_flush_cache_cbe(cbe);
 	STAT(tlb_dropin_fail_fmm);
 	gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
 	return 0;
@@ -415,17 +479,20 @@ failfmm:
 failnoexception:
 	/* TFH status did not show exception pending */
 	gru_flush_cache(tfh);
-	if (cb)
-		gru_flush_cache(cb);
+	gru_flush_cache_cbe(cbe);
+	if (cbk)
+		gru_flush_cache(cbk);
 	STAT(tlb_dropin_fail_no_exception);
-	gru_dbg(grudev, "FAILED non-exception tfh: 0x%p, status %d, state %d\n", tfh, tfh->status, tfh->state);
+	gru_dbg(grudev, "FAILED non-exception tfh: 0x%p, status %d, state %d\n",
+		tfh, tfh->status, tfh->state);
 	return 0;
 
 failidle:
 	/* TFH state was idle  - no miss pending */
 	gru_flush_cache(tfh);
-	if (cb)
-		gru_flush_cache(cb);
+	gru_flush_cache_cbe(cbe);
+	if (cbk)
+		gru_flush_cache(cbk);
 	STAT(tlb_dropin_fail_idle);
 	gru_dbg(grudev, "FAILED idle tfh: 0x%p, state %d\n", tfh, tfh->state);
 	return 0;
@@ -433,16 +500,18 @@ failidle:
 failinval:
 	/* All errors (atomic & non-atomic) switch CBR to EXCEPTION state */
 	tfh_exception(tfh);
+	gru_flush_cache_cbe(cbe);
 	STAT(tlb_dropin_fail_invalid);
 	gru_dbg(grudev, "FAILED inval tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
 	return -EFAULT;
 
 failactive:
 	/* Range invalidate active. Switch to UPM iff atomic */
-	if (!cb)
+	if (!cbk)
 		tfh_user_polling_mode(tfh);
 	else
 		gru_flush_cache(tfh);
+	gru_flush_cache_cbe(cbe);
 	STAT(tlb_dropin_fail_range_active);
 	gru_dbg(grudev, "FAILED range active: tfh 0x%p, vaddr 0x%lx\n",
 		tfh, vaddr);
@@ -455,31 +524,41 @@ failactive:
  * Note that this is the interrupt handler that is registered with linux
  * interrupt handlers.
  */
-irqreturn_t gru_intr(int irq, void *dev_id)
+static irqreturn_t gru_intr(int chiplet, int blade)
 {
 	struct gru_state *gru;
 	struct gru_tlb_fault_map imap, dmap;
 	struct gru_thread_state *gts;
 	struct gru_tlb_fault_handle *tfh = NULL;
+	struct completion *cmp;
 	int cbrnum, ctxnum;
 
 	STAT(intr);
 
-	gru = irq_to_gru(irq);
+	gru = &gru_base[blade]->bs_grus[chiplet];
 	if (!gru) {
-		dev_err(grudev, "GRU: invalid interrupt: cpu %d, irq %d\n",
-			raw_smp_processor_id(), irq);
+		dev_err(grudev, "GRU: invalid interrupt: cpu %d, chiplet %d\n",
+			raw_smp_processor_id(), chiplet);
 		return IRQ_NONE;
 	}
 	get_clear_fault_map(gru, &imap, &dmap);
+	gru_dbg(grudev,
+		"cpu %d, chiplet %d, gid %d, imap %016lx %016lx, dmap %016lx %016lx\n",
+		smp_processor_id(), chiplet, gru->gs_gid,
+		imap.fault_bits[0], imap.fault_bits[1],
+		dmap.fault_bits[0], dmap.fault_bits[1]);
 
 	for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
-		complete(gru->gs_blade->bs_async_wq);
+		STAT(intr_cbr);
+		cmp = gru->gs_blade->bs_async_wq;
+		if (cmp)
+			complete(cmp);
 		gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
-			gru->gs_gid, cbrnum, gru->gs_blade->bs_async_wq->done);
+			gru->gs_gid, cbrnum, cmp ? cmp->done : -1);
 	}
 
 	for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
+		STAT(intr_tfh);
 		tfh = get_tfh_by_index(gru, cbrnum);
 		prefetchw(tfh);	/* Helps on hdw, required for emulator */
 
@@ -492,14 +571,20 @@ irqreturn_t gru_intr(int irq, void *dev_
 		ctxnum = tfh->ctxnum;
 		gts = gru->gs_gts[ctxnum];
 
+		/* Spurious interrupts can cause this. Ignore. */
+		if (!gts) {
+			STAT(intr_spurious);
+			continue;
+		}
+
 		/*
 		 * This is running in interrupt context. Trylock the mmap_sem.
 		 * If it fails, retry the fault in user context.
 		 */
+		gts->ustats.fmm_tlbmiss++;
 		if (!gts->ts_force_cch_reload &&
 					down_read_trylock(&gts->ts_mm->mmap_sem)) {
-			gts->ustats.fmm_tlbdropin++;
-			gru_try_dropin(gts, tfh, NULL);
+			gru_try_dropin(gru, gts, tfh, NULL);
 			up_read(&gts->ts_mm->mmap_sem);
 		} else {
 			tfh_user_polling_mode(tfh);
@@ -509,20 +594,43 @@ irqreturn_t gru_intr(int irq, void *dev_
 	return IRQ_HANDLED;
 }
 
+irqreturn_t gru0_intr(int irq, void *dev_id)
+{
+	return gru_intr(0, uv_numa_blade_id());
+}
+
+irqreturn_t gru1_intr(int irq, void *dev_id)
+{
+	return gru_intr(1, uv_numa_blade_id());
+}
+
+irqreturn_t gru_intr_mblade(int irq, void *dev_id)
+{
+	int blade;
+
+	for_each_possible_blade(blade) {
+		if (uv_blade_nr_possible_cpus(blade))
+			continue;
+		 gru_intr(0, blade);
+		 gru_intr(1, blade);
+	}
+	return IRQ_HANDLED;
+}
+
 
 static int gru_user_dropin(struct gru_thread_state *gts,
 			   struct gru_tlb_fault_handle *tfh,
-			   unsigned long __user *cb)
+			   void *cb)
 {
 	struct gru_mm_struct *gms = gts->ts_gms;
 	int ret;
 
-	gts->ustats.upm_tlbdropin++;
+	gts->ustats.upm_tlbmiss++;
 	while (1) {
 		wait_event(gms->ms_wait_queue,
 			   atomic_read(&gms->ms_range_active) == 0);
 		prefetchw(tfh);	/* Helps on hdw, required for emulator */
-		ret = gru_try_dropin(gts, tfh, cb);
+		ret = gru_try_dropin(gts->ts_gru, gts, tfh, cb);
 		if (ret <= 0)
 			return ret;
 		STAT(call_os_wait_queue);
@@ -538,52 +646,41 @@ int gru_handle_user_call_os(unsigned lon
 {
 	struct gru_tlb_fault_handle *tfh;
 	struct gru_thread_state *gts;
-	unsigned long __user *cbp;
+	void *cbk;
 	int ucbnum, cbrnum, ret = -EINVAL;
 
 	STAT(call_os);
-	gru_dbg(grudev, "address 0x%lx\n", cb);
 
 	/* sanity check the cb pointer */
 	ucbnum = get_cb_number((void *)cb);
 	if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
 		return -EINVAL;
-	cbp = (unsigned long *)cb;
 
 	gts = gru_find_lock_gts(cb);
 	if (!gts)
 		return -EINVAL;
+	gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
 
 	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
 		goto exit;
 
-	/*
-	 * If force_unload is set, the UPM TLB fault is phony. The task
-	 * has migrated to another node and the GSEG must be moved. Just
-	 * unload the context. The task will page fault and assign a new
-	 * context.
-	 */
-	if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 &&
-				gts->ts_blade != uv_numa_blade_id()) {
-		STAT(call_os_offnode_reference);
-		gts->ts_force_unload = 1;
-	}
+	gru_check_context_placement(gts);
 
 	/*
 	 * CCH may contain stale data if ts_force_cch_reload is set.
 	 */
 	if (gts->ts_gru && gts->ts_force_cch_reload) {
 		gts->ts_force_cch_reload = 0;
-		gru_update_cch(gts, 0);
+		gru_update_cch(gts);
 	}
 
 	ret = -EAGAIN;
 	cbrnum = thread_cbr_number(gts, ucbnum);
-	if (gts->ts_force_unload) {
-		gru_unload_context(gts, 1);
-	} else if (gts->ts_gru) {
+	if (gts->ts_gru) {
 		tfh = get_tfh_by_index(gts->ts_gru, cbrnum);
-		ret = gru_user_dropin(gts, tfh, cbp);
+		cbk = get_gseg_base_address_cb(gts->ts_gru->gs_gru_base_vaddr,
+				gts->ts_ctxnum, ucbnum);
+		ret = gru_user_dropin(gts, tfh, cbk);
 	}
 exit:
 	gru_unlock_gts(gts);
@@ -605,11 +702,11 @@ int gru_get_exception_detail(unsigned lo
 	if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet)))
 		return -EFAULT;
 
-	gru_dbg(grudev, "address 0x%lx\n", excdet.cb);
 	gts = gru_find_lock_gts(excdet.cb);
 	if (!gts)
 		return -EINVAL;
 
+	gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", excdet.cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
 	ucbnum = get_cb_number((void *)excdet.cb);
 	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
 		ret = -EINVAL;
@@ -617,6 +714,7 @@ int gru_get_exception_detail(unsigned lo
 		cbrnum = thread_cbr_number(gts, ucbnum);
 		cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
 		gru_flush_cache(cbe);	/* CBE not coherent */
+		sync_core();		/* make sure we are have current data */
 		excdet.opc = cbe->opccpy;
 		excdet.exopc = cbe->exopccpy;
 		excdet.ecause = cbe->ecause;
@@ -624,7 +722,7 @@ int gru_get_exception_detail(unsigned lo
 		excdet.exceptdet1 = cbe->idef3upd;
 		excdet.cbrstate = cbe->cbrstate;
 		excdet.cbrexecstatus = cbe->cbrexecstatus;
-		gru_flush_cache(cbe);
+		gru_flush_cache_cbe(cbe);
 		ret = 0;
 	} else {
 		ret = -EAGAIN;
@@ -733,6 +831,11 @@ long gru_get_gseg_statistics(unsigned lo
 	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
 		return -EFAULT;
 
+	/*
+	 * The library creates arrays of contexts for threaded programs.
+	 * If no gts exists in the array, the context has never been used & all
+	 * statistics are implicitly 0.
+	 */
 	gts = gru_find_lock_gts(req.gseg);
 	if (gts) {
 		memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
@@ -762,11 +865,25 @@ int gru_set_context_option(unsigned long
 		return -EFAULT;
 	gru_dbg(grudev, "op %d, gseg 0x%lx, value1 0x%lx\n", req.op, req.gseg, req.val1);
 
-	gts = gru_alloc_locked_gts(req.gseg);
-	if (!gts)
-		return -EINVAL;
+	gts = gru_find_lock_gts(req.gseg);
+	if (!gts) {
+		gts = gru_alloc_locked_gts(req.gseg);
+		if (IS_ERR(gts))
+			return PTR_ERR(gts);
+	}
 
 	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) {
+			ret = -EINVAL;
+		} else {
+			gts->ts_user_blade_id = req.val1;
+			gts->ts_user_chiplet_id = req.val0;
+			gru_check_context_placement(gts);
+		}
+		break;
 	case sco_gseg_owner:
  		/* Register the current task as the GSEG owner */
 		gts->ts_tgid_owner = current->tgid;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grufile.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grufile.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grufile.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grufile.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,9 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
+#ifdef CONFIG_X86_64
+#include <asm/uv/uv_irq.h>
+#endif
 #include <asm/uv/uv.h>
 #include "gru.h"
 #include "grulib.h"
@@ -92,7 +95,7 @@ static void gru_vma_close(struct vm_area
 /*
  * gru_file_mmap
  *
- * Called when mmaping the device.  Initializes the vma with a fault handler
+ * Called when mmapping the device.  Initializes the vma with a fault handler
  * and private data structure necessary to allocate, track, and free the
  * underlying pages.
  */
@@ -130,7 +133,6 @@ static int gru_create_new_context(unsign
 	struct gru_vma_data *vdata;
 	int ret = -EINVAL;
 
-
 	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
 		return -EFAULT;
 
@@ -150,6 +152,7 @@ static int gru_create_new_context(unsign
 		vdata->vd_dsr_au_count =
 		    GRU_DS_BYTES_TO_AU(req.data_segment_bytes);
 		vdata->vd_cbr_au_count = GRU_CB_COUNT_TO_AU(req.control_blocks);
+		vdata->vd_tlb_preload_count = req.tlb_preload_count;
 		ret = 0;
 	}
 	up_write(&current->mm->mmap_sem);
@@ -190,7 +193,7 @@ static long gru_file_unlocked_ioctl(stru
 {
 	int err = -EBADRQC;
 
-	gru_dbg(grudev, "file %p\n", file);
+	gru_dbg(grudev, "file %p, req 0x%x, 0x%lx\n", file, req, arg);
 
 	switch (req) {
 	case GRU_CREATE_CONTEXT:
@@ -232,23 +235,24 @@ static long gru_file_unlocked_ioctl(stru
  * system.
  */
 static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
-			     void *vaddr, int nid, int bid, int grunum)
+			     void *vaddr, int blade_id, int chiplet_id)
 {
 	spin_lock_init(&gru->gs_lock);
 	spin_lock_init(&gru->gs_asid_lock);
 	gru->gs_gru_base_paddr = paddr;
 	gru->gs_gru_base_vaddr = vaddr;
-	gru->gs_gid = bid * GRU_CHIPLETS_PER_BLADE + grunum;
-	gru->gs_blade = gru_base[bid];
-	gru->gs_blade_id = bid;
+	gru->gs_gid = blade_id * GRU_CHIPLETS_PER_BLADE + chiplet_id;
+	gru->gs_blade = gru_base[blade_id];
+	gru->gs_blade_id = blade_id;
+	gru->gs_chiplet_id = chiplet_id;
 	gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
 	gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
 	gru->gs_asid_limit = MAX_ASID;
 	gru_tgh_flush_init(gru);
 	if (gru->gs_gid >= gru_max_gids)
 		gru_max_gids = gru->gs_gid + 1;
-	gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
-		bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
+	gru_dbg(grudev, "bid %d, gid %d, vaddr %p (0x%lx)\n",
+		blade_id, gru->gs_gid, gru->gs_gru_base_vaddr,
 		gru->gs_gru_base_paddr);
 }
 
@@ -264,12 +268,10 @@ static int gru_init_tables(unsigned long
 
 	max_user_cbrs = GRU_NUM_CB;
 	max_user_dsr_bytes = GRU_NUM_DSR_BYTES;
-	for_each_online_node(nid) {
-		bid = uv_node_to_blade_id(nid);
-		pnode = uv_node_to_pnode(nid);
-		if (bid < 0 || gru_base[bid])
-			continue;
-		page = alloc_pages_exact_node(nid, GFP_KERNEL, order);
+	for_each_possible_blade(bid) {
+		pnode = uv_blade_to_pnode(bid);
+		nid = uv_blade_to_memory_nid(bid);/* -1 if no memory on blade */
+		page = alloc_pages_node(nid, GFP_KERNEL, order);
 		if (!page)
 			goto fail;
 		gru_base[bid] = page_address(page);
@@ -285,7 +287,7 @@ static int gru_init_tables(unsigned long
 				chip++, gru++) {
 			paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip);
 			vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip);
-			gru_init_chiplet(gru, paddr, vaddr, nid, bid, chip);
+			gru_init_chiplet(gru, paddr, vaddr, bid, chip);
 			n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
 			cbrs = max(cbrs, n);
 			n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
@@ -298,39 +300,215 @@ static int gru_init_tables(unsigned long
 	return 0;
 
 fail:
-	for (nid--; nid >= 0; nid--)
-		free_pages((unsigned long)gru_base[nid], order);
+	for (bid--; bid >= 0; bid--)
+		free_pages((unsigned long)gru_base[bid], order);
 	return -ENOMEM;
 }
 
-#ifdef CONFIG_IA64
+static void gru_free_tables(void)
+{
+	int bid;
+	int order = get_order(sizeof(struct gru_state) *
+			      GRU_CHIPLETS_PER_BLADE);
 
-static int get_base_irq(void)
+	for (bid = 0; bid < GRU_MAX_BLADES; bid++)
+		free_pages((unsigned long)gru_base[bid], order);
+}
+
+static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep)
 {
-	return IRQ_GRU;
+	unsigned long mmr = 0;
+	int core;
+
+	/*
+	 * We target the cores of a blade and not the hyperthreads themselves.
+	 * There is a max of 8 cores per socket and 2 sockets per blade,
+	 * making for a max total of 16 cores (i.e., 16 CPUs without
+	 * hyperthreading and 32 CPUs with hyperthreading).
+	 */
+	core = uv_cpu_core_number(cpu) + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
+	if (core >= GRU_NUM_TFM || uv_cpu_ht_number(cpu))
+		return 0;
+
+	if (chiplet == 0) {
+		mmr = UVH_GR0_TLB_INT0_CONFIG +
+		    core * (UVH_GR0_TLB_INT1_CONFIG - UVH_GR0_TLB_INT0_CONFIG);
+	} else if (chiplet == 1) {
+		mmr = UVH_GR1_TLB_INT0_CONFIG +
+		    core * (UVH_GR1_TLB_INT1_CONFIG - UVH_GR1_TLB_INT0_CONFIG);
+	} else {
+		BUG();
+	}
+
+	*corep = core;
+	return mmr;
 }
 
-#elif defined CONFIG_X86_64
+#ifdef CONFIG_IA64
 
-static void noop(unsigned int irq)
+static int gru_irq_count[GRU_CHIPLETS_PER_BLADE];
+
+static void gru_noop(unsigned int irq)
 {
 }
 
-static struct irq_chip gru_chip = {
-	.name		= "gru",
-	.mask		= noop,
-	.unmask		= noop,
-	.ack		= noop,
+static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = {
+	[0 ... GRU_CHIPLETS_PER_BLADE - 1] {
+		.mask		= gru_noop,
+		.unmask		= gru_noop,
+		.ack		= gru_noop
+	}
 };
 
-static int get_base_irq(void)
+static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
+			irq_handler_t irq_handler, int cpu, int blade)
 {
-	set_irq_chip(IRQ_GRU, &gru_chip);
-	set_irq_chip(IRQ_GRU + 1, &gru_chip);
-	return IRQ_GRU;
+	unsigned long mmr;
+	int irq = IRQ_GRU + chiplet;
+	int ret, core;
+
+	mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
+	if (mmr == 0)
+		return 0;
+
+	if (gru_irq_count[chiplet] == 0) {
+		gru_chip[chiplet].name = irq_name;
+		ret = set_irq_chip(irq, &gru_chip[chiplet]);
+		if (ret) {
+			printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n",
+			       GRU_DRIVER_ID_STR, -ret);
+			return ret;
+		}
+
+		ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
+		if (ret) {
+			printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
+			       GRU_DRIVER_ID_STR, -ret);
+			return ret;
+		}
+	}
+	gru_irq_count[chiplet]++;
+
+	return 0;
+}
+
+static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
+{
+	unsigned long mmr;
+	int core, irq = IRQ_GRU + chiplet;
+
+	if (gru_irq_count[chiplet] == 0)
+		return;
+
+	mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
+	if (mmr == 0)
+		return;
+
+	if (--gru_irq_count[chiplet] == 0)
+		free_irq(irq, NULL);
+}
+
+#elif defined CONFIG_X86_64
+
+static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
+			irq_handler_t irq_handler, int cpu, int blade)
+{
+	unsigned long mmr;
+	int irq, core;
+	int ret;
+
+	mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
+	if (mmr == 0)
+		return 0;
+
+	irq = uv_setup_irq(irq_name, cpu, blade, mmr, UV_AFFINITY_CPU);
+	if (irq < 0) {
+		printk(KERN_ERR "%s: uv_setup_irq failed, errno=%d\n",
+		       GRU_DRIVER_ID_STR, -irq);
+		return irq;
+	}
+
+	ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
+	if (ret) {
+		uv_teardown_irq(irq);
+		printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
+		       GRU_DRIVER_ID_STR, -ret);
+		return ret;
+	}
+	gru_base[blade]->bs_grus[chiplet].gs_irq[core] = irq;
+	return 0;
 }
+
+static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
+{
+	int irq, core;
+	unsigned long mmr;
+
+	mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
+	if (mmr) {
+		irq = gru_base[blade]->bs_grus[chiplet].gs_irq[core];
+		if (irq) {
+			free_irq(irq, NULL);
+			uv_teardown_irq(irq);
+		}
+	}
+}
+
 #endif
 
+static void gru_teardown_tlb_irqs(void)
+{
+	int blade;
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		blade = uv_cpu_to_blade_id(cpu);
+		gru_chiplet_teardown_tlb_irq(0, cpu, blade);
+		gru_chiplet_teardown_tlb_irq(1, cpu, blade);
+	}
+	for_each_possible_blade(blade) {
+		if (uv_blade_nr_possible_cpus(blade))
+			continue;
+		gru_chiplet_teardown_tlb_irq(0, 0, blade);
+		gru_chiplet_teardown_tlb_irq(1, 0, blade);
+	}
+}
+
+static int gru_setup_tlb_irqs(void)
+{
+	int blade;
+	int cpu;
+	int ret;
+
+	for_each_online_cpu(cpu) {
+		blade = uv_cpu_to_blade_id(cpu);
+		ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru0_intr, cpu, blade);
+		if (ret != 0)
+			goto exit1;
+
+		ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru1_intr, cpu, blade);
+		if (ret != 0)
+			goto exit1;
+	}
+	for_each_possible_blade(blade) {
+		if (uv_blade_nr_possible_cpus(blade))
+			continue;
+		ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru_intr_mblade, 0, blade);
+		if (ret != 0)
+			goto exit1;
+
+		ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru_intr_mblade, 0, blade);
+		if (ret != 0)
+			goto exit1;
+	}
+
+	return 0;
+
+exit1:
+	gru_teardown_tlb_irqs();
+	return ret;
+}
+
 /*
  * gru_init
  *
@@ -338,8 +516,7 @@ static int get_base_irq(void)
  */
 static int __init gru_init(void)
 {
-	int ret, irq, chip;
-	char id[10];
+	int ret;
 
 	if (!is_uv_system())
 		return 0;
@@ -354,41 +531,29 @@ static int __init gru_init(void)
 	gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
 	printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
 	       gru_start_paddr, gru_end_paddr);
-	irq = get_base_irq();
-	for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
-		ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
-		/* TODO: fix irq handling on x86. For now ignore failure because
-		 * interrupts are not required & not yet fully supported */
-		if (ret) {
-			printk(KERN_WARNING
-			       "!!!WARNING: GRU ignoring request failure!!!\n");
-			ret = 0;
-		}
-		if (ret) {
-			printk(KERN_ERR "%s: request_irq failed\n",
-			       GRU_DRIVER_ID_STR);
-			goto exit1;
-		}
-	}
-
 	ret = misc_register(&gru_miscdev);
 	if (ret) {
 		printk(KERN_ERR "%s: misc_register failed\n",
 		       GRU_DRIVER_ID_STR);
-		goto exit1;
+		goto exit0;
 	}
 
 	ret = gru_proc_init();
 	if (ret) {
 		printk(KERN_ERR "%s: proc init failed\n", GRU_DRIVER_ID_STR);
-		goto exit2;
+		goto exit1;
 	}
 
 	ret = gru_init_tables(gru_start_paddr, gru_start_vaddr);
 	if (ret) {
 		printk(KERN_ERR "%s: init tables failed\n", GRU_DRIVER_ID_STR);
-		goto exit3;
+		goto exit2;
 	}
+
+	ret = gru_setup_tlb_irqs();
+	if (ret != 0)
+		goto exit3;
+
 	gru_kservices_init();
 
 	printk(KERN_INFO "%s: v%s\n", GRU_DRIVER_ID_STR,
@@ -396,31 +561,24 @@ static int __init gru_init(void)
 	return 0;
 
 exit3:
-	gru_proc_exit();
+	gru_free_tables();
 exit2:
-	misc_deregister(&gru_miscdev);
+	gru_proc_exit();
 exit1:
-	for (--chip; chip >= 0; chip--)
-		free_irq(irq + chip, NULL);
+	misc_deregister(&gru_miscdev);
+exit0:
 	return ret;
 
 }
 
 static void __exit gru_exit(void)
 {
-	int i, bid;
-	int order = get_order(sizeof(struct gru_state) *
-			      GRU_CHIPLETS_PER_BLADE);
-
 	if (!is_uv_system())
 		return;
 
-	for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
-		free_irq(IRQ_GRU + i, NULL);
+	gru_teardown_tlb_irqs();
 	gru_kservices_exit();
-	for (bid = 0; bid < GRU_MAX_BLADES; bid++)
-		free_pages((unsigned long)gru_base[bid], order);
-
+	gru_free_tables();
 	misc_deregister(&gru_miscdev);
 	gru_proc_exit();
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gru.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gru.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gru.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gru.h	2010-02-24 13:52:17.000000000 -0500
@@ -53,6 +53,17 @@ struct gru_chiplet_info {
 	int	free_user_cbr;
 };
 
+/*
+ * Statictics kept for each context.
+ */
+struct gru_gseg_statistics {
+	unsigned long	fmm_tlbmiss;
+	unsigned long	upm_tlbmiss;
+	unsigned long	tlbdropin;
+	unsigned long	context_stolen;
+	unsigned long	reserved[10];
+};
+
 /* Flags for GRU options on the gru_create_context() call */
 /* Select one of the follow 4 options to specify how TLB misses are handled */
 #define GRU_OPT_MISS_DEFAULT	0x0000	/* Use default mode */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruhandles.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruhandles.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruhandles.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruhandles.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,9 +27,11 @@
 #ifdef CONFIG_IA64
 #include <asm/processor.h>
 #define GRU_OPERATION_TIMEOUT	(((cycles_t) local_cpu_data->itc_freq)*10)
+#define CLKS2NSEC(c)		((c) *1000000000 / local_cpu_data->itc_freq)
 #else
 #include <asm/tsc.h>
 #define GRU_OPERATION_TIMEOUT	((cycles_t) tsc_khz*10*1000)
+#define CLKS2NSEC(c)		((c) * 1000000 / tsc_khz)
 #endif
 
 /* Extract the status field from a kernel handle */
@@ -39,21 +41,39 @@ struct mcs_op_statistic mcs_op_statistic
 
 static void update_mcs_stats(enum mcs_op op, unsigned long clks)
 {
+	unsigned long nsec;
+
+	nsec = CLKS2NSEC(clks);
 	atomic_long_inc(&mcs_op_statistics[op].count);
-	atomic_long_add(clks, &mcs_op_statistics[op].total);
-	if (mcs_op_statistics[op].max < clks)
-		mcs_op_statistics[op].max = clks;
+	atomic_long_add(nsec, &mcs_op_statistics[op].total);
+	if (mcs_op_statistics[op].max < nsec)
+		mcs_op_statistics[op].max = nsec;
 }
 
 static void start_instruction(void *h)
 {
 	unsigned long *w0 = h;
 
-	wmb();		/* setting CMD bit must be last */
-	*w0 = *w0 | 1;
+	wmb();		/* setting CMD/STATUS bits must be last */
+	*w0 = *w0 | 0x20001;
 	gru_flush_cache(h);
 }
 
+static void report_instruction_timeout(void *h)
+{
+	unsigned long goff = GSEGPOFF((unsigned long)h);
+	char *id = "???";
+
+	if (TYPE_IS(CCH, goff))
+		id = "CCH";
+	else if (TYPE_IS(TGH, goff))
+		id = "TGH";
+	else if (TYPE_IS(TFH, goff))
+		id = "TFH";
+
+	panic(KERN_ALERT "GRU %p (%s) is malfunctioning\n", h, id);
+}
+
 static int wait_instruction_complete(void *h, enum mcs_op opc)
 {
 	int status;
@@ -64,9 +84,10 @@ static int wait_instruction_complete(voi
 		status = GET_MSEG_HANDLE_STATUS(h);
 		if (status != CCHSTATUS_ACTIVE)
 			break;
-		if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
-			panic("GRU %p is malfunctioning: start %ld, end %ld\n",
-			      h, start_time, (unsigned long)get_cycles());
+		if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) {
+			report_instruction_timeout(h);
+			start_time = get_cycles();
+		}
 	}
 	if (gru_options & OPT_STATS)
 		update_mcs_stats(opc, get_cycles() - start_time);
@@ -75,9 +96,18 @@ static int wait_instruction_complete(voi
 
 int cch_allocate(struct gru_context_configuration_handle *cch)
 {
+	int ret;
+
 	cch->opc = CCHOP_ALLOCATE;
 	start_instruction(cch);
-	return wait_instruction_complete(cch, cchop_allocate);
+	ret = wait_instruction_complete(cch, cchop_allocate);
+
+	/*
+	 * Stop speculation into the GSEG being mapped by the previous ALLOCATE.
+	 * The GSEG memory does not exist until the ALLOCATE completes.
+	 */
+	sync_core();
+	return ret;
 }
 
 int cch_start(struct gru_context_configuration_handle *cch)
@@ -96,9 +126,18 @@ int cch_interrupt(struct gru_context_con
 
 int cch_deallocate(struct gru_context_configuration_handle *cch)
 {
+	int ret;
+
 	cch->opc = CCHOP_DEALLOCATE;
 	start_instruction(cch);
-	return wait_instruction_complete(cch, cchop_deallocate);
+	ret = wait_instruction_complete(cch, cchop_deallocate);
+
+	/*
+	 * Stop speculation into the GSEG being unmapped by the previous
+	 * DEALLOCATE.
+	 */
+	sync_core();
+	return ret;
 }
 
 int cch_interrupt_sync(struct gru_context_configuration_handle
@@ -126,17 +165,20 @@ int tgh_invalidate(struct gru_tlb_global
 	return wait_instruction_complete(tgh, tghop_invalidate);
 }
 
-void tfh_write_only(struct gru_tlb_fault_handle *tfh,
-				  unsigned long pfn, unsigned long vaddr,
-				  int asid, int dirty, int pagesize)
+int tfh_write_only(struct gru_tlb_fault_handle *tfh,
+				  unsigned long paddr, int gaa,
+				  unsigned long vaddr, int asid, int dirty,
+				  int pagesize)
 {
 	tfh->fillasid = asid;
 	tfh->fillvaddr = vaddr;
-	tfh->pfn = pfn;
+	tfh->pfn = paddr >> GRU_PADDR_SHIFT;
+	tfh->gaa = gaa;
 	tfh->dirty = dirty;
 	tfh->pagesize = pagesize;
 	tfh->opc = TFHOP_WRITE_ONLY;
 	start_instruction(tfh);
+	return wait_instruction_complete(tfh, tfhop_write_only);
 }
 
 void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruhandles.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruhandles.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruhandles.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruhandles.h	2010-02-24 13:52:17.000000000 -0500
@@ -91,6 +91,12 @@
 /* Convert an arbitrary handle address to the beginning of the GRU segment */
 #define GRUBASE(h)		((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
 
+/* Test a valid handle address to determine the type */
+#define TYPE_IS(hn, h)		((h) >= GRU_##hn##_BASE && (h) <	\
+		GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE &&   \
+		(((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
+
+
 /* General addressing macros. */
 static inline void *get_gseg_base_address(void *base, int ctxnum)
 {
@@ -158,6 +164,16 @@ static inline void *gru_chiplet_vaddr(vo
 	return vaddr + GRU_SIZE * (2 * pnode  + chiplet);
 }
 
+static inline struct gru_control_block_extended *gru_tfh_to_cbe(
+					struct gru_tlb_fault_handle *tfh)
+{
+	unsigned long cbe;
+
+	cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
+	return (struct gru_control_block_extended*)cbe;
+}
+
+
 
 
 /*
@@ -236,6 +252,17 @@ enum gru_tgh_state {
 	TGHSTATE_RESTART_CTX,
 };
 
+enum gru_tgh_cause {
+	TGHCAUSE_RR_ECC,
+	TGHCAUSE_TLB_ECC,
+	TGHCAUSE_LRU_ECC,
+	TGHCAUSE_PS_ECC,
+	TGHCAUSE_MUL_ERR,
+	TGHCAUSE_DATA_ERR,
+	TGHCAUSE_SW_FORCE
+};
+
+
 /*
  * TFH - TLB Global Handle
  * 	Used for TLB dropins into the GRU TLB.
@@ -440,6 +467,12 @@ struct gru_control_block_extended {
 	unsigned int cbrexecstatus:8;
 };
 
+/* CBE fields for active BCOPY instructions */
+#define cbe_baddr0	idef1upd
+#define cbe_baddr1	idef3upd
+#define cbe_src_cl	idef6cpy
+#define cbe_nelemcur	idef5upd
+
 enum gru_cbr_state {
 	CBRSTATE_INACTIVE,
 	CBRSTATE_IDLE,
@@ -487,8 +520,8 @@ int cch_interrupt_sync(struct gru_contex
 int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
 	unsigned long vaddrmask, int asid, int pagesize, int global, int n,
 	unsigned short ctxbitmap);
-void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
-	unsigned long vaddr, int asid, int dirty, int pagesize);
+int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
+	int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
 void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
 	int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
 void tfh_restart(struct gru_tlb_fault_handle *tfh);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gru_instructions.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gru_instructions.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gru_instructions.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gru_instructions.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,17 +34,17 @@ extern void gru_wait_abort_proc(void *cb
 #include <asm/intrinsics.h>
 #define __flush_cache(p)		ia64_fc((unsigned long)p)
 /* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_int(p, v)					\
+#define gru_ordered_store_ulong(p, v)					\
 		do {							\
 			barrier();					\
-			*((volatile int *)(p)) = v; /* force st.rel */	\
+			*((volatile unsigned long *)(p)) = v; /* force st.rel */	\
 		} while (0)
 #elif defined(CONFIG_X86_64)
 #define __flush_cache(p)		clflush(p)
-#define gru_ordered_store_int(p, v)					\
+#define gru_ordered_store_ulong(p, v)					\
 		do {							\
 			barrier();					\
-			*(int *)p = v;					\
+			*(unsigned long *)p = v;			\
 		} while (0)
 #else
 #error "Unsupported architecture"
@@ -129,8 +129,13 @@ struct gru_instruction_bits {
  */
 struct gru_instruction {
     /* DW 0 */
-    unsigned int		op32;    /* icmd,xtype,iaa0,ima,opc */
-    unsigned int		tri0;
+    union {
+    	unsigned long		op64;    /* icmd,xtype,iaa0,ima,opc,tri0 */
+	struct {
+		unsigned int	op32;
+		unsigned int	tri0;
+	};
+    };
     unsigned long		tri1_bufsize;		/* DW 1 */
     unsigned long		baddr0;			/* DW 2 */
     unsigned long		nelem;			/* DW 3 */
@@ -140,7 +145,7 @@ struct gru_instruction {
     unsigned long		avalue;			/* DW 7 */
 };
 
-/* Some shifts and masks for the low 32 bits of a GRU command */
+/* Some shifts and masks for the low 64 bits of a GRU command */
 #define GRU_CB_ICMD_SHFT	0
 #define GRU_CB_ICMD_MASK	0x1
 #define GRU_CB_XTYPE_SHFT	8
@@ -155,6 +160,10 @@ struct gru_instruction {
 #define GRU_CB_OPC_MASK		0xff
 #define GRU_CB_EXOPC_SHFT	24
 #define GRU_CB_EXOPC_MASK	0xff
+#define GRU_IDEF2_SHFT		32
+#define GRU_IDEF2_MASK		0x3ffff
+#define GRU_ISTATUS_SHFT	56
+#define GRU_ISTATUS_MASK	0x3
 
 /* GRU instruction opcodes (opc field) */
 #define OP_NOP		0x00
@@ -256,6 +265,7 @@ struct gru_instruction {
 #define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR	(1 << 16)
 #define CBE_CAUSE_RA_RESPONSE_DATA_ERROR	(1 << 17)
 #define CBE_CAUSE_HA_RESPONSE_DATA_ERROR	(1 << 18)
+#define CBE_CAUSE_FORCED_ERROR			(1 << 19)
 
 /* CBE cbrexecstatus bits */
 #define CBR_EXS_ABORT_OCC_BIT			0
@@ -264,13 +274,15 @@ struct gru_instruction {
 #define CBR_EXS_QUEUED_BIT			3
 #define CBR_EXS_TLB_INVAL_BIT			4
 #define CBR_EXS_EXCEPTION_BIT			5
+#define CBR_EXS_CB_INT_PENDING_BIT		6
 
 #define CBR_EXS_ABORT_OCC			(1 << CBR_EXS_ABORT_OCC_BIT)
 #define CBR_EXS_INT_OCC				(1 << CBR_EXS_INT_OCC_BIT)
 #define CBR_EXS_PENDING				(1 << CBR_EXS_PENDING_BIT)
 #define CBR_EXS_QUEUED				(1 << CBR_EXS_QUEUED_BIT)
-#define CBR_TLB_INVAL				(1 << CBR_EXS_TLB_INVAL_BIT)
+#define CBR_EXS_TLB_INVAL			(1 << CBR_EXS_TLB_INVAL_BIT)
 #define CBR_EXS_EXCEPTION			(1 << CBR_EXS_EXCEPTION_BIT)
+#define CBR_EXS_CB_INT_PENDING			(1 << CBR_EXS_CB_INT_PENDING_BIT)
 
 /*
  * Exceptions are retried for the following cases. If any OTHER bits are set
@@ -296,12 +308,14 @@ union gru_mesqhead {
 
 
 /* Generate the low word of a GRU instruction */
-static inline unsigned int
-__opword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
+static inline unsigned long
+__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
        unsigned char iaa0, unsigned char iaa1,
-       unsigned char ima)
+       unsigned long idef2, unsigned char ima)
 {
     return (1 << GRU_CB_ICMD_SHFT) |
+	   ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
+	   (idef2<< GRU_IDEF2_SHFT) |
 	   (iaa0 << GRU_CB_IAA0_SHFT) |
 	   (iaa1 << GRU_CB_IAA1_SHFT) |
 	   (ima << GRU_CB_IMA_SHFT) |
@@ -319,12 +333,13 @@ static inline void gru_flush_cache(void
 }
 
 /*
- * Store the lower 32 bits of the command including the "start" bit. Then
+ * Store the lower 64 bits of the command including the "start" bit. Then
  * start the instruction executing.
  */
-static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
+static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
 {
-	gru_ordered_store_int(ins, op32);
+	gru_ordered_store_ulong(ins, op64);
+	mb();
 	gru_flush_cache(ins);
 }
 
@@ -340,6 +355,30 @@ static inline void gru_start_instruction
  *     	- nelem and stride are in elements
  *     	- tri0/tri1 is in bytes for the beginning of the data segment.
  */
+static inline void gru_vload_phys(void *cb, unsigned long gpa,
+		unsigned int tri0, int iaa, unsigned long hints)
+{
+	struct gru_instruction *ins = (struct gru_instruction *)cb;
+
+	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
+	ins->nelem = 1;
+	ins->op1_stride = 1;
+	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
+					(unsigned long)tri0, CB_IMA(hints)));
+}
+
+static inline void gru_vstore_phys(void *cb, unsigned long gpa,
+		unsigned int tri0, int iaa, unsigned long hints)
+{
+	struct gru_instruction *ins = (struct gru_instruction *)cb;
+
+	ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
+	ins->nelem = 1;
+	ins->op1_stride = 1;
+	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, XTYPE_DW, iaa, 0,
+					(unsigned long)tri0, CB_IMA(hints)));
+}
+
 static inline void gru_vload(void *cb, unsigned long mem_addr,
 		unsigned int tri0, unsigned char xtype, unsigned long nelem,
 		unsigned long stride, unsigned long hints)
@@ -348,10 +387,9 @@ static inline void gru_vload(void *cb, u
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
 	ins->op1_stride = stride;
-	gru_start_instruction(ins, __opword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
+					(unsigned long)tri0, CB_IMA(hints)));
 }
 
 static inline void gru_vstore(void *cb, unsigned long mem_addr,
@@ -362,10 +400,9 @@ static inline void gru_vstore(void *cb,
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
 	ins->op1_stride = stride;
-	gru_start_instruction(ins, __opword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
+					tri0, CB_IMA(hints)));
 }
 
 static inline void gru_ivload(void *cb, unsigned long mem_addr,
@@ -376,10 +413,9 @@ static inline void gru_ivload(void *cb,
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
 	ins->tri1_bufsize = tri1;
-	gru_start_instruction(ins, __opword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
+					tri0, CB_IMA(hints)));
 }
 
 static inline void gru_ivstore(void *cb, unsigned long mem_addr,
@@ -390,10 +426,9 @@ static inline void gru_ivstore(void *cb,
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
 	ins->tri1_bufsize = tri1;
-	gru_start_instruction(ins, __opword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
+					tri0, CB_IMA(hints)));
 }
 
 static inline void gru_vset(void *cb, unsigned long mem_addr,
@@ -406,8 +441,8 @@ static inline void gru_vset(void *cb, un
 	ins->op2_value_baddr1 = value;
 	ins->nelem = nelem;
 	ins->op1_stride = stride;
-	gru_start_instruction(ins, __opword(OP_VSET, 0, xtype, IAA_RAM, 0,
-					 CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
+					 0, CB_IMA(hints)));
 }
 
 static inline void gru_ivset(void *cb, unsigned long mem_addr,
@@ -420,8 +455,8 @@ static inline void gru_ivset(void *cb, u
 	ins->op2_value_baddr1 = value;
 	ins->nelem = nelem;
 	ins->tri1_bufsize = tri1;
-	gru_start_instruction(ins, __opword(OP_IVSET, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_vflush(void *cb, unsigned long mem_addr,
@@ -433,15 +468,15 @@ static inline void gru_vflush(void *cb,
 	ins->baddr0 = (long)mem_addr;
 	ins->op1_stride = stride;
 	ins->nelem = nelem;
-	gru_start_instruction(ins, __opword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_nop(void *cb, int hints)
 {
 	struct gru_instruction *ins = (void *)cb;
 
-	gru_start_instruction(ins, __opword(OP_NOP, 0, 0, 0, 0, CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
 }
 
 
@@ -455,10 +490,9 @@ static inline void gru_bcopy(void *cb, c
 	ins->baddr0 = (long)src;
 	ins->op2_value_baddr1 = (long)dest;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
 	ins->tri1_bufsize = bufsize;
-	gru_start_instruction(ins, __opword(OP_BCOPY, 0, xtype, IAA_RAM,
-					IAA_RAM, CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
+					IAA_RAM, tri0, CB_IMA(hints)));
 }
 
 static inline void gru_bstore(void *cb, const unsigned long src,
@@ -470,9 +504,8 @@ static inline void gru_bstore(void *cb,
 	ins->baddr0 = (long)src;
 	ins->op2_value_baddr1 = (long)dest;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
-	gru_start_instruction(ins, __opword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
+					tri0, CB_IMA(hints)));
 }
 
 static inline void gru_gamir(void *cb, int exopc, unsigned long src,
@@ -481,8 +514,8 @@ static inline void gru_gamir(void *cb, i
 	struct gru_instruction *ins = (void *)cb;
 
 	ins->baddr0 = (long)src;
-	gru_start_instruction(ins, __opword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
@@ -491,8 +524,8 @@ static inline void gru_gamirr(void *cb,
 	struct gru_instruction *ins = (void *)cb;
 
 	ins->baddr0 = (long)src;
-	gru_start_instruction(ins, __opword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_gamer(void *cb, int exopc, unsigned long src,
@@ -505,8 +538,8 @@ static inline void gru_gamer(void *cb, i
 	ins->baddr0 = (long)src;
 	ins->op1_stride = operand1;
 	ins->op2_value_baddr1 = operand2;
-	gru_start_instruction(ins, __opword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
@@ -518,8 +551,8 @@ static inline void gru_gamerr(void *cb,
 	ins->baddr0 = (long)src;
 	ins->op1_stride = operand1;
 	ins->op2_value_baddr1 = operand2;
-	gru_start_instruction(ins, __opword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
+					0, CB_IMA(hints)));
 }
 
 static inline void gru_gamxr(void *cb, unsigned long src,
@@ -529,8 +562,8 @@ static inline void gru_gamxr(void *cb, u
 
 	ins->baddr0 = (long)src;
 	ins->nelem = 4;
-	gru_start_instruction(ins, __opword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
-				 IAA_RAM, 0, CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
+				 IAA_RAM, 0, 0, CB_IMA(hints)));
 }
 
 static inline void gru_mesq(void *cb, unsigned long queue,
@@ -541,9 +574,8 @@ static inline void gru_mesq(void *cb, un
 
 	ins->baddr0 = (long)queue;
 	ins->nelem = nelem;
-	ins->tri0 = tri0;
-	gru_start_instruction(ins, __opword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
-					CB_IMA(hints)));
+	gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
+					tri0, CB_IMA(hints)));
 }
 
 static inline unsigned long gru_get_amo_value(void *cb)
@@ -662,6 +694,14 @@ static inline void gru_wait_abort(void *
 	gru_wait_abort_proc(cb);
 }
 
+/*
+ * Get a pointer to the start of a gseg
+ * 	p	- Any valid pointer within the gseg
+ */
+static inline void *gru_get_gseg_pointer (void *p)
+{
+	return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
+}
 
 /*
  * Get a pointer to a control block
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukdump.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukdump.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukdump.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukdump.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,8 @@ static int gru_user_copy_handle(void __u
 
 static int gru_dump_context_data(void *grubase,
 			struct gru_context_configuration_handle *cch,
-			void __user *ubuf, int ctxnum, int dsrcnt)
+			void __user *ubuf, int ctxnum, int dsrcnt,
+			int flush_cbrs)
 {
 	void *cb, *cbe, *tfh, *gseg;
 	int i, scr;
@@ -55,6 +56,8 @@ static int gru_dump_context_data(void *g
 	tfh = grubase + GRU_TFH_BASE;
 
 	for_each_cbr_in_allocation_map(i, &cch->cbr_allocation_map, scr) {
+		if (flush_cbrs)
+			gru_flush_cache(cb);
 		if (gru_user_copy_handle(&ubuf, cb))
 			goto fail;
 		if (gru_user_copy_handle(&ubuf, tfh + i * GRU_HANDLE_STRIDE))
@@ -115,7 +118,7 @@ fail:
 
 static int gru_dump_context(struct gru_state *gru, int ctxnum,
 		void __user *ubuf, void __user *ubufend, char data_opt,
-		char lock_cch)
+		char lock_cch, char flush_cbrs)
 {
 	struct gru_dump_context_header hdr;
 	struct gru_dump_context_header __user *uhdr = ubuf;
@@ -159,8 +162,7 @@ static int gru_dump_context(struct gru_s
 			ret = -EFBIG;
 		else
 			ret = gru_dump_context_data(grubase, cch, ubuf, ctxnum,
-							dsrcnt);
-
+							dsrcnt, flush_cbrs);
 	}
 	if (cch_locked)
 		unlock_cch_handle(cch);
@@ -215,7 +217,8 @@ int gru_dump_chiplet_request(unsigned lo
 	for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
 		if (req.ctxnum == ctxnum || req.ctxnum < 0) {
 			ret = gru_dump_context(gru, ctxnum, ubuf, ubufend,
-						req.data_opt, req.lock_cch);
+						req.data_opt, req.lock_cch,
+						req.flush_cbrs);
 			if (ret < 0)
 				goto fail;
 			ubuf += ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukservices.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukservices.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukservices.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukservices.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <linux/delay.h>
+#include <asm/io_apic.h>
 #include "gru.h"
 #include "grulib.h"
 #include "grutables.h"
@@ -97,9 +98,6 @@
 #define ASYNC_HAN_TO_BID(h)	((h) - 1)
 #define ASYNC_BID_TO_HAN(b)	((b) + 1)
 #define ASYNC_HAN_TO_BS(h)	gru_base[ASYNC_HAN_TO_BID(h)]
-#define KCB_TO_GID(cb)		((cb - gru_start_vaddr) /		\
-					(GRU_SIZE * GRU_CHIPLETS_PER_BLADE))
-#define KCB_TO_BS(cb)		gru_base[KCB_TO_GID(cb)]
 
 #define GRU_NUM_KERNEL_CBR	1
 #define GRU_NUM_KERNEL_DSR_BYTES 256
@@ -160,8 +158,10 @@ static void gru_load_kernel_context(stru
 	up_read(&bs->bs_kgts_sema);
 	down_write(&bs->bs_kgts_sema);
 
-	if (!bs->bs_kgts)
-		bs->bs_kgts = gru_alloc_gts(NULL, 0, 0, 0, 0);
+	if (!bs->bs_kgts) {
+		bs->bs_kgts = gru_alloc_gts(NULL, 0, 0, 0, 0, 0);
+		bs->bs_kgts->ts_user_blade_id = blade_id;
+	}
 	kgts = bs->bs_kgts;
 
 	if (!kgts->ts_gru) {
@@ -172,9 +172,9 @@ static void gru_load_kernel_context(stru
 		kgts->ts_dsr_au_count = GRU_DS_BYTES_TO_AU(
 			GRU_NUM_KERNEL_DSR_BYTES * ncpus +
 				bs->bs_async_dsr_bytes);
-		while (!gru_assign_gru_context(kgts, blade_id)) {
+		while (!gru_assign_gru_context(kgts)) {
 			msleep(1);
-			gru_steal_context(kgts, blade_id);
+			gru_steal_context(kgts);
 		}
 		gru_load_context(kgts);
 		gru = bs->bs_kgts->ts_gru;
@@ -200,13 +200,15 @@ static int gru_free_kernel_contexts(void
 		bs = gru_base[bid];
 		if (!bs)
 			continue;
+
+		/* Ignore busy contexts. Don't want to block here.  */
 		if (down_write_trylock(&bs->bs_kgts_sema)) {
 			kgts = bs->bs_kgts;
 			if (kgts && kgts->ts_gru)
 				gru_unload_context(kgts, 0);
-			kfree(kgts);
 			bs->bs_kgts = NULL;
 			up_write(&bs->bs_kgts_sema);
+			kfree(kgts);
 		} else {
 			ret++;
 		}
@@ -220,13 +222,21 @@ static int gru_free_kernel_contexts(void
 static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
 {
 	struct gru_blade_state *bs;
+	int bid;
 
 	STAT(lock_kernel_context);
-	bs = gru_base[blade_id];
+again:
+	bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
+	bs = gru_base[bid];
 
+	/* Handle the case where migration occured while waiting for the sema */
 	down_read(&bs->bs_kgts_sema);
+	if (blade_id < 0 && bid != uv_numa_blade_id()) {
+		up_read(&bs->bs_kgts_sema);
+		goto again;
+	}
 	if (!bs->bs_kgts || !bs->bs_kgts->ts_gru)
-		gru_load_kernel_context(bs, blade_id);
+		gru_load_kernel_context(bs, bid);
 	return bs;
 
 }
@@ -255,7 +265,7 @@ static int gru_get_cpu_resources(int dsr
 
 	BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
 	preempt_disable();
-	bs = gru_lock_kernel_context(uv_numa_blade_id());
+	bs = gru_lock_kernel_context(-1);
 	lcpu = uv_blade_processor_id();
 	*cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
 	*dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES;
@@ -384,13 +394,31 @@ int gru_get_cb_exception_detail(void *cb
 		struct control_block_extended_exc_detail *excdet)
 {
 	struct gru_control_block_extended *cbe;
-	struct gru_blade_state *bs;
-	int cbrnum;
+	struct gru_thread_state *kgts = NULL;
+	unsigned long off;
+	int cbrnum, bid;
 
-	bs = KCB_TO_BS(cb);
-	cbrnum = thread_cbr_number(bs->bs_kgts, get_cb_number(cb));
+	/*
+	 * Locate kgts for cb. This algorithm is SLOW but
+	 * this function is rarely called (ie., almost never).
+	 * Performance does not matter.
+	 */
+	for_each_possible_blade(bid) {
+		if (!gru_base[bid])
+			break;
+		kgts = gru_base[bid]->bs_kgts;
+		if (!kgts || !kgts->ts_gru)
+			continue;
+		off = cb - kgts->ts_gru->gs_gru_base_vaddr;
+		if (off < GRU_SIZE)
+			break;
+		kgts = NULL;
+	}
+	BUG_ON(!kgts);
+	cbrnum = thread_cbr_number(kgts, get_cb_number(cb));
 	cbe = get_cbe(GRUBASE(cb), cbrnum);
 	gru_flush_cache(cbe);	/* CBE not coherent */
+	sync_core();
 	excdet->opc = cbe->opccpy;
 	excdet->exopc = cbe->exopccpy;
 	excdet->ecause = cbe->ecause;
@@ -409,8 +437,8 @@ char *gru_get_cb_exception_detail_str(in
 	if (ret > 0 && gen->istatus == CBS_EXCEPTION) {
 		gru_get_cb_exception_detail(cb, &excdet);
 		snprintf(buf, size,
-			"GRU exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
-			"excdet0 0x%lx, excdet1 0x%x",
+			"GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
+			"excdet0 0x%lx, excdet1 0x%x", smp_processor_id(),
 			gen, excdet.opc, excdet.exopc, excdet.ecause,
 			excdet.exceptdet0, excdet.exceptdet1);
 	} else {
@@ -457,9 +485,10 @@ int gru_check_status_proc(void *cb)
 	int ret;
 
 	ret = gen->istatus;
-	if (ret != CBS_EXCEPTION)
-		return ret;
-	return gru_retry_exception(cb);
+	if (ret == CBS_EXCEPTION)
+		ret = gru_retry_exception(cb);
+	rmb();
+	return ret;
 
 }
 
@@ -471,7 +500,7 @@ int gru_wait_proc(void *cb)
 	ret = gru_wait_idle_or_exception(gen);
 	if (ret == CBS_EXCEPTION)
 		ret = gru_retry_exception(cb);
-
+	rmb();
 	return ret;
 }
 
@@ -538,7 +567,7 @@ int gru_create_message_queue(struct gru_
 	mqd->mq = mq;
 	mqd->mq_gpa = uv_gpa(mq);
 	mqd->qlines = qlines;
-	mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
+	mqd->interrupt_pnode = nasid >> 1;
 	mqd->interrupt_vector = vector;
 	mqd->interrupt_apicid = apicid;
 	return 0;
@@ -598,6 +627,8 @@ static int send_noop_message(void *cb, s
 				ret = MQE_UNEXPECTED_CB_ERR;
 			break;
 		case CBSS_PAGE_OVERFLOW:
+			STAT(mesq_noop_page_overflow);
+			/* fallthru */
 		default:
 			BUG();
 		}
@@ -673,18 +704,6 @@ cberr:
 }
 
 /*
- * Send a cross-partition interrupt to the SSI that contains the target
- * message queue. Normally, the interrupt is automatically delivered by hardware
- * but some error conditions require explicit delivery.
- */
-static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
-{
-	if (mqd->interrupt_vector)
-		uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid,
-				mqd->interrupt_vector);
-}
-
-/*
  * Handle a PUT failure. Note: if message was a 2-line message, one of the
  * lines might have successfully have been written. Before sending the
  * message, "present" must be cleared in BOTH lines to prevent the receiver
@@ -693,7 +712,8 @@ static void send_message_queue_interrupt
 static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
 			void *mesg, int lines)
 {
-	unsigned long m;
+	unsigned long m, *val = mesg, gpa, save;
+	int ret;
 
 	m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
 	if (lines == 2) {
@@ -704,7 +724,26 @@ static int send_message_put_nacked(void
 	gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
 	if (gru_wait(cb) != CBS_IDLE)
 		return MQE_UNEXPECTED_CB_ERR;
-	send_message_queue_interrupt(mqd);
+
+	if (!mqd->interrupt_vector)
+		return MQE_OK;
+
+	/*
+	 * Send a cross-partition interrupt to the SSI that contains the target
+	 * message queue. Normally, the interrupt is automatically delivered by
+	 * hardware but some error conditions require explicit delivery.
+	 * Use the GRU to deliver the interrupt. Otherwise partition failures
+	 * could cause unrecovered errors.
+	 */
+	gpa = uv_global_gru_mmr_address(mqd->interrupt_pnode, UVH_IPI_INT);
+	save = *val;
+	*val = uv_hub_ipi_value(mqd->interrupt_apicid, mqd->interrupt_vector,
+				dest_Fixed);
+	gru_vstore_phys(cb, gpa, gru_get_tri(mesg), IAA_REGISTER, IMA);
+	ret = gru_wait(cb);
+	*val = save;
+	if (ret != CBS_IDLE)
+		return MQE_UNEXPECTED_CB_ERR;
 	return MQE_OK;
 }
 
@@ -739,6 +778,9 @@ static int send_message_failure(void *cb
 		STAT(mesq_send_put_nacked);
 		ret = send_message_put_nacked(cb, mqd, mesg, lines);
 		break;
+	case CBSS_PAGE_OVERFLOW:
+		STAT(mesq_page_overflow);
+		/* fallthru */
 	default:
 		BUG();
 	}
@@ -831,7 +873,6 @@ void *gru_get_next_message(struct gru_me
 	int present = mhdr->present;
 
 	/* skip NOOP messages */
-	STAT(mesq_receive);
 	while (present == MQS_NOOP) {
 		gru_free_message(mqd, mhdr);
 		mhdr = mq->next;
@@ -851,6 +892,7 @@ void *gru_get_next_message(struct gru_me
 	if (mhdr->lines == 2)
 		restore_present2(mhdr, mhdr->present2);
 
+	STAT(mesq_receive);
 	return mhdr;
 }
 EXPORT_SYMBOL_GPL(gru_get_next_message);
@@ -858,6 +900,29 @@ EXPORT_SYMBOL_GPL(gru_get_next_message);
 /* ---------------------- GRU DATA COPY FUNCTIONS ---------------------------*/
 
 /*
+ * Load a DW from a global GPA. The GPA can be a memory or MMR address.
+ */
+int gru_read_gpa(unsigned long *value, unsigned long gpa)
+{
+	void *cb;
+	void *dsr;
+	int ret, iaa;
+
+	STAT(read_gpa);
+	if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
+		return MQE_BUG_NO_RESOURCES;
+	iaa = gpa >> 62;
+	gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa, IMA);
+	ret = gru_wait(cb);
+	if (ret == CBS_IDLE)
+		*value = *(unsigned long *)dsr;
+	gru_free_cpu_resources(cb, dsr);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gru_read_gpa);
+
+
+/*
  * Copy a block of data using the GRU resources
  */
 int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
@@ -898,24 +963,24 @@ static int quicktest0(unsigned long arg)
 
 	gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
 	if (gru_wait(cb) != CBS_IDLE) {
-		printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n");
+		printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 1\n", smp_processor_id());
 		goto done;
 	}
 
 	if (*p != MAGIC) {
-		printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p);
+		printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p);
 		goto done;
 	}
 	gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
 	if (gru_wait(cb) != CBS_IDLE) {
-		printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n");
+		printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 2\n", smp_processor_id());
 		goto done;
 	}
 
 	if (word0 != word1 || word1 != MAGIC) {
 		printk(KERN_DEBUG
-		       "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n",
-		     word1, MAGIC);
+		       "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
+		     smp_processor_id(), word1, MAGIC);
 		goto done;
 	}
 	ret = 0;
@@ -952,8 +1017,11 @@ static int quicktest1(unsigned long arg)
 		if (ret)
 			break;
 	}
-	if (ret != MQE_QUEUE_FULL || i != 4)
+	if (ret != MQE_QUEUE_FULL || i != 4) {
+		printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
+		       smp_processor_id(), ret, i);
 		goto done;
+	}
 
 	for (i = 0; i < 6; i++) {
 		m = gru_get_next_message(&mqd);
@@ -961,7 +1029,12 @@ static int quicktest1(unsigned long arg)
 			break;
 		gru_free_message(&mqd, m);
 	}
-	ret = (i == 4) ? 0 : -EIO;
+	if (i != 4) {
+		printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
+			smp_processor_id(), i, m, m ? m[8] : -1);
+		goto done;
+	}
+	ret = 0;
 
 done:
 	kfree(p);
@@ -977,6 +1050,7 @@ static int quicktest2(unsigned long arg)
 	int ret = 0;
 	unsigned long *buf;
 	void *cb0, *cb;
+	struct gru_control_block_status *gen;
 	int i, k, istatus, bytes;
 
 	bytes = numcb * 4 * 8;
@@ -996,20 +1070,30 @@ static int quicktest2(unsigned long arg)
 				XTYPE_DW, 4, 1, IMA_INTERRUPT);
 
 	ret = 0;
-	for (k = 0; k < numcb; k++) {
+	k = numcb;
+	do {
 		gru_wait_async_cbr(han);
 		for (i = 0; i < numcb; i++) {
 			cb = cb0 + i * GRU_HANDLE_STRIDE;
 			istatus = gru_check_status(cb);
-			if (istatus == CBS_ACTIVE)
-				continue;
-			if (istatus == CBS_EXCEPTION)
-				ret = -EFAULT;
-			else if (buf[i] || buf[i + 1] || buf[i + 2] ||
-					buf[i + 3])
-				ret = -EIO;
+			if (istatus != CBS_ACTIVE && istatus != CBS_CALL_OS)
+				break;
 		}
-	}
+		if (i == numcb)
+			continue;
+		if (istatus != CBS_IDLE) {
+			printk(KERN_DEBUG "GRU:%d quicktest2: cb %d, exception\n", smp_processor_id(), i);
+			ret = -EFAULT;
+		} else if (buf[4 * i] || buf[4 * i + 1] || buf[4 * i + 2] ||
+				buf[4 * i + 3]) {
+			printk(KERN_DEBUG "GRU:%d quicktest2:cb %d,  buf 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
+			       smp_processor_id(), i, buf[4 * i], buf[4 * i + 1], buf[4 * i + 2], buf[4 * i + 3]);
+			ret = -EIO;
+		}
+		k--;
+		gen = cb;
+		gen->istatus = CBS_CALL_OS; /* don't handle this CBR again */
+	} while (k);
 	BUG_ON(cmp.done);
 
 	gru_unlock_async_resource(han);
@@ -1019,6 +1103,22 @@ done:
 	return ret;
 }
 
+#define BUFSIZE 200
+static int quicktest3(unsigned long arg)
+{
+	char buf1[BUFSIZE], buf2[BUFSIZE];
+	int ret = 0;
+
+	memset(buf2, 0, sizeof(buf2));
+	memset(buf1, get_cycles() & 255, sizeof(buf1));
+	gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE);
+	if (memcmp(buf1, buf2, BUFSIZE)) {
+		printk(KERN_DEBUG "GRU:%d quicktest3 error\n", smp_processor_id());
+		ret = -EIO;
+	}
+	return ret;
+}
+
 /*
  * Debugging only. User hook for various kernel tests
  * of driver & gru.
@@ -1037,6 +1137,9 @@ int gru_ktest(unsigned long arg)
 	case 2:
 		ret = quicktest2(arg);
 		break;
+	case 3:
+		ret = quicktest3(arg);
+		break;
 	case 99:
 		ret = gru_free_kernel_contexts();
 		break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukservices.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukservices.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grukservices.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grukservices.h	2010-02-24 13:52:17.000000000 -0500
@@ -131,6 +131,20 @@ extern void *gru_get_next_message(struct
 
 
 /*
+ * Read a GRU global GPA. Source can be located in a remote partition.
+ *
+ *    Input:
+ *    	value		memory address where MMR value is returned
+ *    	gpa		source numalink physical address of GPA
+ *
+ *    Output:
+ *	0		OK
+ *	>0		error
+ */
+int gru_read_gpa(unsigned long *value, unsigned long gpa);
+
+
+/*
  * Copy data using the GRU. Source or destination can be located in a remote
  * partition.
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grulib.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grulib.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grulib.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grulib.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,18 +63,9 @@
 #define THREAD_POINTER(p, th)		(p + GRU_GSEG_PAGESIZE * (th))
 #define GSEG_START(cb)			((void *)((unsigned long)(cb) & ~(GRU_GSEG_PAGESIZE - 1)))
 
-/*
- * Statictics kept on a per-GTS basis.
- */
-struct gts_statistics {
-	unsigned long	fmm_tlbdropin;
-	unsigned long	upm_tlbdropin;
-	unsigned long	context_stolen;
-};
-
 struct gru_get_gseg_statistics_req {
-	unsigned long		gseg;
-	struct gts_statistics	stats;
+	unsigned long			gseg;
+	struct gru_gseg_statistics	stats;
 };
 
 /*
@@ -86,6 +77,7 @@ struct gru_create_context_req {
 	unsigned int		control_blocks;
 	unsigned int		maximum_thread_count;
 	unsigned int		options;
+	unsigned char		tlb_preload_count;
 };
 
 /*
@@ -98,11 +90,12 @@ struct gru_unload_context_req {
 /*
  * Structure used to set context options
  */
-enum {sco_gseg_owner, sco_cch_req_slice};
+enum {sco_gseg_owner, sco_cch_req_slice, sco_blade_chiplet};
 struct gru_set_context_option_req {
 	unsigned long	gseg;
 	int		op;
-	unsigned long	val1;
+	int		val0;
+	long		val1;
 };
 
 /*
@@ -124,6 +117,8 @@ struct gru_dump_chiplet_state_req {
 	int		ctxnum;
 	char		data_opt;
 	char		lock_cch;
+	char		flush_cbrs;
+	char		fill[10];
 	pid_t		pid;
 	void		*buf;
 	size_t		buflen;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grumain.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grumain.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grumain.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grumain.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/err.h>
 #include <asm/uv/uv_hub.h>
 #include "gru.h"
 #include "grutables.h"
@@ -48,12 +49,20 @@ struct device *grudev = &gru_device;
 /*
  * Select a gru fault map to be used by the current cpu. Note that
  * multiple cpus may be using the same map.
- *	ZZZ should "shift" be used?? Depends on HT cpu numbering
  *	ZZZ should be inline but did not work on emulator
  */
 int gru_cpu_fault_map_id(void)
 {
+#ifdef CONFIG_IA64
 	return uv_blade_processor_id() % GRU_NUM_TFM;
+#else
+	int cpu = smp_processor_id();
+	int id, core;
+
+	core = uv_cpu_core_number(cpu);
+	id = core + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
+	return id;
+#endif
 }
 
 /*--------- ASID Management -------------------------------------------
@@ -286,7 +295,8 @@ static void gru_unload_mm_tracker(struct
 void gts_drop(struct gru_thread_state *gts)
 {
 	if (gts && atomic_dec_return(&gts->ts_refcnt) == 0) {
-		gru_drop_mmu_notifier(gts->ts_gms);
+		if (gts->ts_gms)
+			gru_drop_mmu_notifier(gts->ts_gms);
 		kfree(gts);
 		STAT(gts_free);
 	}
@@ -310,16 +320,18 @@ static struct gru_thread_state *gru_find
  * Allocate a thread state structure.
  */
 struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
-		int cbr_au_count, int dsr_au_count, int options, int tsid)
+		int cbr_au_count, int dsr_au_count,
+		unsigned char tlb_preload_count, int options, int tsid)
 {
 	struct gru_thread_state *gts;
+	struct gru_mm_struct *gms;
 	int bytes;
 
 	bytes = DSR_BYTES(dsr_au_count) + CBR_BYTES(cbr_au_count);
 	bytes += sizeof(struct gru_thread_state);
 	gts = kmalloc(bytes, GFP_KERNEL);
 	if (!gts)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	STAT(gts_alloc);
 	memset(gts, 0, sizeof(struct gru_thread_state)); /* zero out header */
@@ -327,7 +339,10 @@ struct gru_thread_state *gru_alloc_gts(s
 	mutex_init(&gts->ts_ctxlock);
 	gts->ts_cbr_au_count = cbr_au_count;
 	gts->ts_dsr_au_count = dsr_au_count;
+	gts->ts_tlb_preload_count = tlb_preload_count;
 	gts->ts_user_options = options;
+	gts->ts_user_blade_id = -1;
+	gts->ts_user_chiplet_id = -1;
 	gts->ts_tsid = tsid;
 	gts->ts_ctxnum = NULLCTX;
 	gts->ts_tlb_int_select = -1;
@@ -336,9 +351,10 @@ struct gru_thread_state *gru_alloc_gts(s
 	if (vma) {
 		gts->ts_mm = current->mm;
 		gts->ts_vma = vma;
-		gts->ts_gms = gru_register_mmu_notifier();
-		if (!gts->ts_gms)
+		gms = gru_register_mmu_notifier();
+		if (IS_ERR(gms))
 			goto err;
+		gts->ts_gms = gms;
 	}
 
 	gru_dbg(grudev, "alloc gts %p\n", gts);
@@ -346,7 +362,7 @@ struct gru_thread_state *gru_alloc_gts(s
 
 err:
 	gts_drop(gts);
-	return NULL;
+	return ERR_CAST(gms);
 }
 
 /*
@@ -360,6 +376,7 @@ struct gru_vma_data *gru_alloc_vma_data(
 	if (!vdata)
 		return NULL;
 
+	STAT(vdata_alloc);
 	INIT_LIST_HEAD(&vdata->vd_head);
 	spin_lock_init(&vdata->vd_lock);
 	gru_dbg(grudev, "alloc vdata %p\n", vdata);
@@ -392,10 +409,12 @@ struct gru_thread_state *gru_alloc_threa
 	struct gru_vma_data *vdata = vma->vm_private_data;
 	struct gru_thread_state *gts, *ngts;
 
-	gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count, vdata->vd_dsr_au_count,
+	gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count,
+			    vdata->vd_dsr_au_count,
+			    vdata->vd_tlb_preload_count,
 			    vdata->vd_user_options, tsid);
-	if (!gts)
-		return NULL;
+	if (IS_ERR(gts))
+		return gts;
 
 	spin_lock(&vdata->vd_lock);
 	ngts = gru_find_current_gts_nolock(vdata, tsid);
@@ -493,6 +512,9 @@ static void gru_load_context_data(void *
 			memset(cbe + i * GRU_HANDLE_STRIDE, 0,
 						GRU_CACHE_LINE_BYTES);
 		}
+		/* Flush CBE to hide race in context restart */
+		mb();
+		gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
 		cb += GRU_HANDLE_STRIDE;
 	}
 
@@ -513,6 +535,12 @@ static void gru_unload_context_data(void
 	cb = gseg + GRU_CB_BASE;
 	cbe = grubase + GRU_CBE_BASE;
 	length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
+
+	/* CBEs may not be coherent. Flush them from cache */
+	for_each_cbr_in_allocation_map(i, &cbrmap, scr)
+		gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
+	mb();		/* Let the CL flush complete */
+
 	gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
 
 	for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
@@ -533,7 +561,8 @@ void gru_unload_context(struct gru_threa
 		zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
 	cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
 
-	gru_dbg(grudev, "gts %p\n", gts);
+	gru_dbg(grudev, "gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
+		gts, gts->ts_cbr_map, gts->ts_dsr_map);
 	lock_cch_handle(cch);
 	if (cch_interrupt_sync(cch))
 		BUG();
@@ -549,7 +578,6 @@ void gru_unload_context(struct gru_threa
 
 	if (cch_deallocate(cch))
 		BUG();
-	gts->ts_force_unload = 0;	/* ts_force_unload locked by CCH lock */
 	unlock_cch_handle(cch);
 
 	gru_free_gru_context(gts);
@@ -565,9 +593,7 @@ void gru_load_context(struct gru_thread_
 	struct gru_context_configuration_handle *cch;
 	int i, err, asid, ctxnum = gts->ts_ctxnum;
 
-	gru_dbg(grudev, "gts %p\n", gts);
 	cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
-
 	lock_cch_handle(cch);
 	cch->tfm_fault_bit_enable =
 	    (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
@@ -591,6 +617,7 @@ void gru_load_context(struct gru_thread_
 		cch->unmap_enable = 1;
 		cch->tfm_done_bit_enable = 1;
 		cch->cb_int_enable = 1;
+		cch->tlb_int_select = 0;	/* For now, ints go to cpu 0 */
 	} else {
 		cch->unmap_enable = 0;
 		cch->tfm_done_bit_enable = 0;
@@ -616,17 +643,18 @@ void gru_load_context(struct gru_thread_
 	if (cch_start(cch))
 		BUG();
 	unlock_cch_handle(cch);
+
+	gru_dbg(grudev, "gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
+		gts->ts_gru->gs_gid, gts, gts->ts_cbr_map, gts->ts_dsr_map,
+		(gts->ts_user_options == GRU_OPT_MISS_FMM_INTR), gts->ts_tlb_int_select);
 }
 
 /*
  * Update fields in an active CCH:
  * 	- retarget interrupts on local blade
  * 	- update sizeavail mask
- * 	- force a delayed context unload by clearing the CCH asids. This
- * 	  forces TLB misses for new GRU instructions. The context is unloaded
- * 	  when the next TLB miss occurs.
  */
-int gru_update_cch(struct gru_thread_state *gts, int force_unload)
+int gru_update_cch(struct gru_thread_state *gts)
 {
 	struct gru_context_configuration_handle *cch;
 	struct gru_state *gru = gts->ts_gru;
@@ -640,21 +668,13 @@ int gru_update_cch(struct gru_thread_sta
 			goto exit;
 		if (cch_interrupt(cch))
 			BUG();
-		if (!force_unload) {
-			for (i = 0; i < 8; i++)
-				cch->sizeavail[i] = gts->ts_sizeavail;
-			gts->ts_tlb_int_select = gru_cpu_fault_map_id();
-			cch->tlb_int_select = gru_cpu_fault_map_id();
-			cch->tfm_fault_bit_enable =
-			  (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
-			    || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
-		} else {
-			for (i = 0; i < 8; i++)
-				cch->asid[i] = 0;
-			cch->tfm_fault_bit_enable = 0;
-			cch->tlb_int_enable = 0;
-			gts->ts_force_unload = 1;
-		}
+		for (i = 0; i < 8; i++)
+			cch->sizeavail[i] = gts->ts_sizeavail;
+		gts->ts_tlb_int_select = gru_cpu_fault_map_id();
+		cch->tlb_int_select = gru_cpu_fault_map_id();
+		cch->tfm_fault_bit_enable =
+		  (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
+		    || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
 		if (cch_start(cch))
 			BUG();
 		ret = 1;
@@ -679,7 +699,54 @@ static int gru_retarget_intr(struct gru_
 
 	gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
 		gru_cpu_fault_map_id());
-	return gru_update_cch(gts, 0);
+	return gru_update_cch(gts);
+}
+
+/*
+ * Check if a GRU context is allowed to use a specific chiplet. By default
+ * a context is assigned to any blade-local chiplet. However, users can
+ * override this.
+ * 	Returns 1 if assignment allowed, 0 otherwise
+ */
+static int gru_check_chiplet_assignment(struct gru_state *gru,
+					struct gru_thread_state *gts)
+{
+	int blade_id;
+	int chiplet_id;
+
+	blade_id = gts->ts_user_blade_id;
+	if (blade_id < 0)
+		blade_id = uv_numa_blade_id();
+
+	chiplet_id = gts->ts_user_chiplet_id;
+	return gru->gs_blade_id == blade_id &&
+		(chiplet_id < 0 || chiplet_id == gru->gs_chiplet_id);
+}
+
+/*
+ * Unload the gru context if it is not assigned to the correct blade or
+ * chiplet. Misassignment can occur if the process migrates to a different
+ * blade or if the user changes the selected blade/chiplet.
+ */
+void gru_check_context_placement(struct gru_thread_state *gts)
+{
+	struct gru_state *gru;
+
+	/*
+	 * If the current task is the context owner, verify that the
+	 * context is correctly placed. This test is skipped for non-owner
+	 * references. Pthread apps use non-owner references to the CBRs.
+	 */
+	gru = gts->ts_gru;
+	if (!gru || gts->ts_tgid_owner != current->tgid)
+		return;
+
+	if (!gru_check_chiplet_assignment(gru, gts)) {
+		STAT(check_context_unload);
+		gru_unload_context(gts, 1);
+	} else if (gru_retarget_intr(gts)) {
+		STAT(check_context_retarget_intr);
+	}
 }
 
 
@@ -712,13 +779,17 @@ static void gts_stolen(struct gru_thread
 	}
 }
 
-void gru_steal_context(struct gru_thread_state *gts, int blade_id)
+void gru_steal_context(struct gru_thread_state *gts)
 {
 	struct gru_blade_state *blade;
 	struct gru_state *gru, *gru0;
 	struct gru_thread_state *ngts = NULL;
 	int ctxnum, ctxnum0, flag = 0, cbr, dsr;
+	int blade_id;
 
+	blade_id = gts->ts_user_blade_id;
+	if (blade_id < 0)
+		blade_id = uv_numa_blade_id();
 	cbr = gts->ts_cbr_au_count;
 	dsr = gts->ts_dsr_au_count;
 
@@ -729,35 +800,39 @@ void gru_steal_context(struct gru_thread
 	gru = blade->bs_lru_gru;
 	if (ctxnum == 0)
 		gru = next_gru(blade, gru);
+	blade->bs_lru_gru = gru;
+	blade->bs_lru_ctxnum = ctxnum;
 	ctxnum0 = ctxnum;
 	gru0 = gru;
 	while (1) {
-		if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
-			break;
-		spin_lock(&gru->gs_lock);
-		for (; ctxnum < GRU_NUM_CCH; ctxnum++) {
-			if (flag && gru == gru0 && ctxnum == ctxnum0)
+		if (gru_check_chiplet_assignment(gru, gts)) {
+			if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
 				break;
-			ngts = gru->gs_gts[ctxnum];
-			/*
-			 * We are grabbing locks out of order, so trylock is
-			 * needed. GTSs are usually not locked, so the odds of
-			 * success are high. If trylock fails, try to steal a
-			 * different GSEG.
-			 */
-			if (ngts && is_gts_stealable(ngts, blade))
+			spin_lock(&gru->gs_lock);
+			for (; ctxnum < GRU_NUM_CCH; ctxnum++) {
+				if (flag && gru == gru0 && ctxnum == ctxnum0)
+					break;
+				ngts = gru->gs_gts[ctxnum];
+				/*
+			 	* We are grabbing locks out of order, so trylock is
+			 	* needed. GTSs are usually not locked, so the odds of
+			 	* success are high. If trylock fails, try to steal a
+			 	* different GSEG.
+			 	*/
+				if (ngts && is_gts_stealable(ngts, blade))
+					break;
+				ngts = NULL;
+			}
+			spin_unlock(&gru->gs_lock);
+			if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
 				break;
-			ngts = NULL;
-			flag = 1;
 		}
-		spin_unlock(&gru->gs_lock);
-		if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
+		if (flag && gru == gru0)
 			break;
+		flag = 1;
 		ctxnum = 0;
 		gru = next_gru(blade, gru);
 	}
-	blade->bs_lru_gru = gru;
-	blade->bs_lru_ctxnum = ctxnum;
 	spin_unlock(&blade->bs_lock);
 
 	if (ngts) {
@@ -776,19 +851,34 @@ void gru_steal_context(struct gru_thread
 }
 
 /*
+ * Assign a gru context.
+ */
+static int gru_assign_context_number(struct gru_state *gru)
+{
+	int ctxnum;
+
+	ctxnum = find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
+	__set_bit(ctxnum, &gru->gs_context_map);
+	return ctxnum;
+}
+
+/*
  * Scan the GRUs on the local blade & assign a GRU context.
  */
-struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts,
-						int blade)
+struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts)
 {
 	struct gru_state *gru, *grux;
 	int i, max_active_contexts;
+	int blade_id = gts->ts_user_blade_id;
 
-
+	if (blade_id < 0)
+		blade_id = uv_numa_blade_id();
 again:
 	gru = NULL;
 	max_active_contexts = GRU_NUM_CCH;
-	for_each_gru_on_blade(grux, blade, i) {
+	for_each_gru_on_blade(grux, blade_id, i) {
+		if (!gru_check_chiplet_assignment(grux, gts))
+			continue;
 		if (check_gru_resources(grux, gts->ts_cbr_au_count,
 					gts->ts_dsr_au_count,
 					max_active_contexts)) {
@@ -809,12 +899,9 @@ again:
 		reserve_gru_resources(gru, gts);
 		gts->ts_gru = gru;
 		gts->ts_blade = gru->gs_blade_id;
-		gts->ts_ctxnum =
-		    find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
-		BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);
+		gts->ts_ctxnum = gru_assign_context_number(gru);
 		atomic_inc(&gts->ts_refcnt);
 		gru->gs_gts[gts->ts_ctxnum] = gts;
-		__set_bit(gts->ts_ctxnum, &gru->gs_context_map);
 		spin_unlock(&gru->gs_lock);
 
 		STAT(assign_context);
@@ -842,7 +929,6 @@ int gru_fault(struct vm_area_struct *vma
 {
 	struct gru_thread_state *gts;
 	unsigned long paddr, vaddr;
-	int blade_id;
 
 	vaddr = (unsigned long)vmf->virtual_address;
 	gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n",
@@ -857,28 +943,18 @@ int gru_fault(struct vm_area_struct *vma
 again:
 	mutex_lock(&gts->ts_ctxlock);
 	preempt_disable();
-	blade_id = uv_numa_blade_id();
 
-	if (gts->ts_gru) {
-		if (gts->ts_gru->gs_blade_id != blade_id) {
-			STAT(migrated_nopfn_unload);
-			gru_unload_context(gts, 1);
-		} else {
-			if (gru_retarget_intr(gts))
-				STAT(migrated_nopfn_retarget);
-		}
-	}
+	gru_check_context_placement(gts);
 
 	if (!gts->ts_gru) {
 		STAT(load_user_context);
-		if (!gru_assign_gru_context(gts, blade_id)) {
+		if (!gru_assign_gru_context(gts)) {
 			preempt_enable();
 			mutex_unlock(&gts->ts_ctxlock);
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(GRU_ASSIGN_DELAY);  /* true hack ZZZ */
-			blade_id = uv_numa_blade_id();
 			if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies)
-				gru_steal_context(gts, blade_id);
+				gru_steal_context(gts);
 			goto again;
 		}
 		gru_load_context(gts);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruprocfs.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruprocfs.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/gruprocfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/gruprocfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,8 +36,7 @@ static void printstat_val(struct seq_fil
 {
 	unsigned long val = atomic_long_read(v);
 
-	if (val)
-		seq_printf(s, "%16lu %s\n", val, id);
+	seq_printf(s, "%16lu %s\n", val, id);
 }
 
 static int statistics_show(struct seq_file *s, void *p)
@@ -46,7 +45,8 @@ static int statistics_show(struct seq_fi
 	printstat(s, vdata_free);
 	printstat(s, gts_alloc);
 	printstat(s, gts_free);
-	printstat(s, vdata_double_alloc);
+	printstat(s, gms_alloc);
+	printstat(s, gms_free);
 	printstat(s, gts_double_allocate);
 	printstat(s, assign_context);
 	printstat(s, assign_context_failed);
@@ -59,28 +59,25 @@ static int statistics_show(struct seq_fi
 	printstat(s, steal_kernel_context);
 	printstat(s, steal_context_failed);
 	printstat(s, nopfn);
-	printstat(s, break_cow);
 	printstat(s, asid_new);
 	printstat(s, asid_next);
 	printstat(s, asid_wrap);
 	printstat(s, asid_reuse);
 	printstat(s, intr);
+	printstat(s, intr_cbr);
+	printstat(s, intr_tfh);
+	printstat(s, intr_spurious);
 	printstat(s, intr_mm_lock_failed);
 	printstat(s, call_os);
-	printstat(s, call_os_offnode_reference);
-	printstat(s, call_os_check_for_bug);
 	printstat(s, call_os_wait_queue);
 	printstat(s, user_flush_tlb);
 	printstat(s, user_unload_context);
 	printstat(s, user_exception);
 	printstat(s, set_context_option);
-	printstat(s, migrate_check);
-	printstat(s, migrated_retarget);
-	printstat(s, migrated_unload);
-	printstat(s, migrated_unload_delay);
-	printstat(s, migrated_nopfn_retarget);
-	printstat(s, migrated_nopfn_unload);
+	printstat(s, check_context_retarget_intr);
+	printstat(s, check_context_unload);
 	printstat(s, tlb_dropin);
+	printstat(s, tlb_preload_page);
 	printstat(s, tlb_dropin_fail_no_asid);
 	printstat(s, tlb_dropin_fail_upm);
 	printstat(s, tlb_dropin_fail_invalid);
@@ -88,16 +85,15 @@ static int statistics_show(struct seq_fi
 	printstat(s, tlb_dropin_fail_idle);
 	printstat(s, tlb_dropin_fail_fmm);
 	printstat(s, tlb_dropin_fail_no_exception);
-	printstat(s, tlb_dropin_fail_no_exception_war);
 	printstat(s, tfh_stale_on_fault);
 	printstat(s, mmu_invalidate_range);
 	printstat(s, mmu_invalidate_page);
-	printstat(s, mmu_clear_flush_young);
 	printstat(s, flush_tlb);
 	printstat(s, flush_tlb_gru);
 	printstat(s, flush_tlb_gru_tgh);
 	printstat(s, flush_tlb_gru_zero_asid);
 	printstat(s, copy_gpa);
+	printstat(s, read_gpa);
 	printstat(s, mesq_receive);
 	printstat(s, mesq_receive_none);
 	printstat(s, mesq_send);
@@ -108,7 +104,6 @@ static int statistics_show(struct seq_fi
 	printstat(s, mesq_send_qlimit_reached);
 	printstat(s, mesq_send_amo_nacked);
 	printstat(s, mesq_send_put_nacked);
-	printstat(s, mesq_qf_not_full);
 	printstat(s, mesq_qf_locked);
 	printstat(s, mesq_qf_noop_not_full);
 	printstat(s, mesq_qf_switch_head_failed);
@@ -118,6 +113,7 @@ static int statistics_show(struct seq_fi
 	printstat(s, mesq_noop_qlimit_reached);
 	printstat(s, mesq_noop_amo_nacked);
 	printstat(s, mesq_noop_put_nacked);
+	printstat(s, mesq_noop_page_overflow);
 	return 0;
 }
 
@@ -133,8 +129,10 @@ static int mcs_statistics_show(struct se
 	int op;
 	unsigned long total, count, max;
 	static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
-		"cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
+		"cch_interrupt_sync", "cch_deallocate", "tfh_write_only",
+		"tfh_write_restart", "tgh_invalidate"};
 
+	seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
 	for (op = 0; op < mcsop_last; op++) {
 		count = atomic_long_read(&mcs_op_statistics[op].count);
 		total = atomic_long_read(&mcs_op_statistics[op].total);
@@ -154,6 +152,7 @@ static ssize_t mcs_statistics_write(stru
 
 static int options_show(struct seq_file *s, void *p)
 {
+	seq_printf(s, "#bitmask: 1=trace, 2=statistics\n");
 	seq_printf(s, "0x%lx\n", gru_options);
 	return 0;
 }
@@ -183,16 +182,17 @@ static int cch_seq_show(struct seq_file
 	const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" };
 
 	if (gid == 0)
-		seq_printf(file, "#%5s%5s%6s%9s%6s%8s%8s\n", "gid", "bid",
-			   "ctx#", "pid", "cbrs", "dsbytes", "mode");
+		seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s\n", "gid", "bid",
+			   "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode");
 	if (gru)
 		for (i = 0; i < GRU_NUM_CCH; i++) {
 			ts = gru->gs_gts[i];
 			if (!ts)
 				continue;
-			seq_printf(file, " %5d%5d%6d%9d%6d%8d%8s\n",
+			seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s\n",
 				   gru->gs_gid, gru->gs_blade_id, i,
-				   ts->ts_tgid_owner,
+				   is_kernel_context(ts) ? 0 : ts->ts_gms->ms_asids[gid].mt_asid,
+				   is_kernel_context(ts) ? 0 : ts->ts_tgid_owner,
 				   ts->ts_cbr_au_count * GRU_CBR_AU_SIZE,
 				   ts->ts_cbr_au_count * GRU_DSR_AU_BYTES,
 				   mode[ts->ts_user_options &
@@ -355,7 +355,7 @@ static void delete_proc_files(void)
 		for (p = proc_files; p->name; p++)
 			if (p->entry)
 				remove_proc_entry(p->name, proc_gru);
-		remove_proc_entry("gru", NULL);
+		remove_proc_entry("gru", proc_gru->parent);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grutables.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutables.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grutables.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutables.h	2010-02-24 13:52:17.000000000 -0500
@@ -161,7 +161,7 @@ extern unsigned int gru_max_gids;
 #define GRU_MAX_GRUS		(GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
 
 #define GRU_DRIVER_ID_STR	"SGI GRU Device Driver"
-#define GRU_DRIVER_VERSION_STR	"0.80"
+#define GRU_DRIVER_VERSION_STR	"0.85"
 
 /*
  * GRU statistics.
@@ -171,7 +171,8 @@ struct gru_stats_s {
 	atomic_long_t vdata_free;
 	atomic_long_t gts_alloc;
 	atomic_long_t gts_free;
-	atomic_long_t vdata_double_alloc;
+	atomic_long_t gms_alloc;
+	atomic_long_t gms_free;
 	atomic_long_t gts_double_allocate;
 	atomic_long_t assign_context;
 	atomic_long_t assign_context_failed;
@@ -184,28 +185,25 @@ struct gru_stats_s {
 	atomic_long_t steal_kernel_context;
 	atomic_long_t steal_context_failed;
 	atomic_long_t nopfn;
-	atomic_long_t break_cow;
 	atomic_long_t asid_new;
 	atomic_long_t asid_next;
 	atomic_long_t asid_wrap;
 	atomic_long_t asid_reuse;
 	atomic_long_t intr;
+	atomic_long_t intr_cbr;
+	atomic_long_t intr_tfh;
+	atomic_long_t intr_spurious;
 	atomic_long_t intr_mm_lock_failed;
 	atomic_long_t call_os;
-	atomic_long_t call_os_offnode_reference;
-	atomic_long_t call_os_check_for_bug;
 	atomic_long_t call_os_wait_queue;
 	atomic_long_t user_flush_tlb;
 	atomic_long_t user_unload_context;
 	atomic_long_t user_exception;
 	atomic_long_t set_context_option;
-	atomic_long_t migrate_check;
-	atomic_long_t migrated_retarget;
-	atomic_long_t migrated_unload;
-	atomic_long_t migrated_unload_delay;
-	atomic_long_t migrated_nopfn_retarget;
-	atomic_long_t migrated_nopfn_unload;
+	atomic_long_t check_context_retarget_intr;
+	atomic_long_t check_context_unload;
 	atomic_long_t tlb_dropin;
+	atomic_long_t tlb_preload_page;
 	atomic_long_t tlb_dropin_fail_no_asid;
 	atomic_long_t tlb_dropin_fail_upm;
 	atomic_long_t tlb_dropin_fail_invalid;
@@ -213,17 +211,16 @@ struct gru_stats_s {
 	atomic_long_t tlb_dropin_fail_idle;
 	atomic_long_t tlb_dropin_fail_fmm;
 	atomic_long_t tlb_dropin_fail_no_exception;
-	atomic_long_t tlb_dropin_fail_no_exception_war;
 	atomic_long_t tfh_stale_on_fault;
 	atomic_long_t mmu_invalidate_range;
 	atomic_long_t mmu_invalidate_page;
-	atomic_long_t mmu_clear_flush_young;
 	atomic_long_t flush_tlb;
 	atomic_long_t flush_tlb_gru;
 	atomic_long_t flush_tlb_gru_tgh;
 	atomic_long_t flush_tlb_gru_zero_asid;
 
 	atomic_long_t copy_gpa;
+	atomic_long_t read_gpa;
 
 	atomic_long_t mesq_receive;
 	atomic_long_t mesq_receive_none;
@@ -235,7 +232,7 @@ struct gru_stats_s {
 	atomic_long_t mesq_send_qlimit_reached;
 	atomic_long_t mesq_send_amo_nacked;
 	atomic_long_t mesq_send_put_nacked;
-	atomic_long_t mesq_qf_not_full;
+	atomic_long_t mesq_page_overflow;
 	atomic_long_t mesq_qf_locked;
 	atomic_long_t mesq_qf_noop_not_full;
 	atomic_long_t mesq_qf_switch_head_failed;
@@ -245,11 +242,13 @@ struct gru_stats_s {
 	atomic_long_t mesq_noop_qlimit_reached;
 	atomic_long_t mesq_noop_amo_nacked;
 	atomic_long_t mesq_noop_put_nacked;
+	atomic_long_t mesq_noop_page_overflow;
 
 };
 
 enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
-	cchop_deallocate, tghop_invalidate, mcsop_last};
+	cchop_deallocate, tfhop_write_only, tfhop_write_restart,
+	tghop_invalidate, mcsop_last};
 
 struct mcs_op_statistic {
 	atomic_long_t	count;
@@ -259,8 +258,8 @@ struct mcs_op_statistic {
 
 extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
 
-#define OPT_DPRINT	1
-#define OPT_STATS	2
+#define OPT_DPRINT		1
+#define OPT_STATS		2
 
 
 #define IRQ_GRU			110	/* Starting IRQ number for interrupts */
@@ -283,7 +282,7 @@ extern struct mcs_op_statistic mcs_op_st
 #define gru_dbg(dev, fmt, x...)						\
 	do {								\
 		if (gru_options & OPT_DPRINT)				\
-			dev_dbg(dev, "%s: " fmt, __func__, x);		\
+			printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\
 	} while (0)
 #else
 #define gru_dbg(x...)
@@ -297,13 +296,7 @@ extern struct mcs_op_statistic mcs_op_st
 #define ASID_INC	8	/* number of regions */
 
 /* Generate a GRU asid value from a GRU base asid & a virtual address. */
-#if defined CONFIG_IA64
 #define VADDR_HI_BIT		64
-#elif defined CONFIG_X86_64
-#define VADDR_HI_BIT		48
-#else
-#error "Unsupported architecture"
-#endif
 #define GRUREGION(addr)		((addr) >> (VADDR_HI_BIT - 3) & 3)
 #define GRUASID(asid, addr)	((asid) + GRUREGION(addr))
 
@@ -345,6 +338,7 @@ struct gru_vma_data {
 	long			vd_user_options;/* misc user option flags */
 	int			vd_cbr_au_count;
 	int			vd_dsr_au_count;
+	unsigned char		vd_tlb_preload_count;
 };
 
 /*
@@ -360,6 +354,7 @@ struct gru_thread_state {
 	struct gru_state	*ts_gru;	/* GRU where the context is
 						   loaded */
 	struct gru_mm_struct	*ts_gms;	/* asid & ioproc struct */
+	unsigned char		ts_tlb_preload_count; /* TLB preload pages */
 	unsigned long		ts_cbr_map;	/* map of allocated CBRs */
 	unsigned long		ts_dsr_map;	/* map of allocated DATA
 						   resources */
@@ -368,6 +363,8 @@ struct gru_thread_state {
 	long			ts_user_options;/* misc user option flags */
 	pid_t			ts_tgid_owner;	/* task that is using the
 						   context - for migration */
+	short			ts_user_blade_id;/* user selected blade */
+	char			ts_user_chiplet_id;/* user selected chiplet */
 	unsigned short		ts_sizeavail;	/* Pagesizes in use */
 	int			ts_tsid;	/* thread that owns the
 						   structure */
@@ -384,13 +381,11 @@ struct gru_thread_state {
 	char			ts_blade;	/* If >= 0, migrate context if
 						   ref from diferent blade */
 	char			ts_force_cch_reload;
-	char			ts_force_unload;/* force context to be unloaded
-						   after migration */
 	char			ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each
 							  allocated CB */
 	int			ts_data_valid;	/* Indicates if ts_gdata has
 						   valid data */
-	struct gts_statistics	ustats;		/* User statistics */
+	struct gru_gseg_statistics ustats;	/* User statistics */
 	unsigned long		ts_gdata[0];	/* save area for GRU data (CB,
 						   DS, CBE) */
 };
@@ -422,6 +417,7 @@ struct gru_state {
 							   gru segments (64) */
 	unsigned short		gs_gid;			/* unique GRU number */
 	unsigned short		gs_blade_id;		/* blade of GRU */
+	unsigned char		gs_chiplet_id;		/* blade chiplet of GRU */
 	unsigned char		gs_tgh_local_shift;	/* used to pick TGH for
 							   local flush */
 	unsigned char		gs_tgh_first_remote;	/* starting TGH# for
@@ -453,6 +449,7 @@ struct gru_state {
 							   in use */
 	struct gru_thread_state	*gs_gts[GRU_NUM_CCH];	/* GTS currently using
 							   the context */
+	int			gs_irq[GRU_NUM_TFM];	/* Interrupt irqs */
 };
 
 /*
@@ -619,6 +616,15 @@ static inline int is_kernel_context(stru
 	return !gts->ts_mm;
 }
 
+/*
+ * The following are for Nehelem-EX. A more general scheme is needed for
+ * future processors.
+ */
+#define UV_MAX_INT_CORES		8
+#define uv_cpu_socket_number(p)		((cpu_physical_id(p) >> 5) & 1)
+#define uv_cpu_ht_number(p)		(cpu_physical_id(p) & 1)
+#define uv_cpu_core_number(p)		(((cpu_physical_id(p) >> 2) & 4) |	\
+					((cpu_physical_id(p) >> 1) & 3))
 /*-----------------------------------------------------------------------------
  * Function prototypes & externs
  */
@@ -633,24 +639,26 @@ extern struct gru_thread_state *gru_find
 				*vma, int tsid);
 extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
 				*vma, int tsid);
-extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts,
-		int blade);
+extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts);
 extern void gru_load_context(struct gru_thread_state *gts);
-extern void gru_steal_context(struct gru_thread_state *gts, int blade_id);
+extern void gru_steal_context(struct gru_thread_state *gts);
 extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
-extern int gru_update_cch(struct gru_thread_state *gts, int force_unload);
+extern int gru_update_cch(struct gru_thread_state *gts);
 extern void gts_drop(struct gru_thread_state *gts);
 extern void gru_tgh_flush_init(struct gru_state *gru);
 extern int gru_kservices_init(void);
 extern void gru_kservices_exit(void);
+extern irqreturn_t gru0_intr(int irq, void *dev_id);
+extern irqreturn_t gru1_intr(int irq, void *dev_id);
+extern irqreturn_t gru_intr_mblade(int irq, void *dev_id);
 extern int gru_dump_chiplet_request(unsigned long arg);
 extern long gru_get_gseg_statistics(unsigned long arg);
-extern irqreturn_t gru_intr(int irq, void *dev_id);
 extern int gru_handle_user_call_os(unsigned long address);
 extern int gru_user_flush_tlb(unsigned long arg);
 extern int gru_user_unload_context(unsigned long arg);
 extern int gru_get_exception_detail(unsigned long arg);
 extern int gru_set_context_option(unsigned long address);
+extern void gru_check_context_placement(struct gru_thread_state *gts);
 extern int gru_cpu_fault_map_id(void);
 extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
 extern void gru_flush_all_tlb(struct gru_state *gru);
@@ -658,7 +666,8 @@ extern int gru_proc_init(void);
 extern void gru_proc_exit(void);
 
 extern struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
-		int cbr_au_count, int dsr_au_count, int options, int tsid);
+		int cbr_au_count, int dsr_au_count,
+		unsigned char tlb_preload_count, int options, int tsid);
 extern unsigned long gru_reserve_cb_resources(struct gru_state *gru,
 		int cbr_au_count, char *cbmap);
 extern unsigned long gru_reserve_ds_resources(struct gru_state *gru,
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grutlbpurge.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutlbpurge.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-gru/grutlbpurge.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-gru/grutlbpurge.c	2010-02-24 13:52:17.000000000 -0500
@@ -184,8 +184,8 @@ void gru_flush_tlb_range(struct gru_mm_s
 			STAT(flush_tlb_gru_tgh);
 			asid = GRUASID(asid, start);
 			gru_dbg(grudev,
-	"  FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n",
-				gid, asid, num, asids->mt_ctxbitmap);
+	"  FLUSH gruid %d, asid 0x%x, vaddr 0x%lx, vamask 0x%x, num %ld, cbmap 0x%x\n",
+			      gid, asid, start, grupagesize, num, asids->mt_ctxbitmap);
 			tgh = get_lock_tgh_handle(gru);
 			tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
 				       num - 1, asids->mt_ctxbitmap);
@@ -299,6 +299,7 @@ struct gru_mm_struct *gru_register_mmu_n
 {
 	struct gru_mm_struct *gms;
 	struct mmu_notifier *mn;
+	int err;
 
 	mn = mmu_find_ops(current->mm, &gru_mmuops);
 	if (mn) {
@@ -307,16 +308,22 @@ struct gru_mm_struct *gru_register_mmu_n
 	} else {
 		gms = kzalloc(sizeof(*gms), GFP_KERNEL);
 		if (gms) {
+			STAT(gms_alloc);
 			spin_lock_init(&gms->ms_asid_lock);
 			gms->ms_notifier.ops = &gru_mmuops;
 			atomic_set(&gms->ms_refcnt, 1);
 			init_waitqueue_head(&gms->ms_wait_queue);
-			__mmu_notifier_register(&gms->ms_notifier, current->mm);
+			err = __mmu_notifier_register(&gms->ms_notifier, current->mm);
+			if (err)
+				goto error;
 		}
 	}
 	gru_dbg(grudev, "gms %p, refcnt %d\n", gms,
 		atomic_read(&gms->ms_refcnt));
 	return gms;
+error:
+	kfree(gms);
+	return ERR_PTR(err);
 }
 
 void gru_drop_mmu_notifier(struct gru_mm_struct *gms)
@@ -327,6 +334,7 @@ void gru_drop_mmu_notifier(struct gru_mm
 		if (!gms->ms_released)
 			mmu_notifier_unregister(&gms->ms_notifier, current->mm);
 		kfree(gms);
+		STAT(gms_free);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_main.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_main.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,48 +89,40 @@ static int xpc_disengage_max_timelimit =
 
 static ctl_table xpc_sys_xpc_hb_dir[] = {
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "hb_interval",
 	 .data = &xpc_hb_interval,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = &proc_dointvec_minmax,
-	 .strategy = &sysctl_intvec,
+	 .proc_handler = proc_dointvec_minmax,
 	 .extra1 = &xpc_hb_min_interval,
 	 .extra2 = &xpc_hb_max_interval},
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "hb_check_interval",
 	 .data = &xpc_hb_check_interval,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = &proc_dointvec_minmax,
-	 .strategy = &sysctl_intvec,
+	 .proc_handler = proc_dointvec_minmax,
 	 .extra1 = &xpc_hb_check_min_interval,
 	 .extra2 = &xpc_hb_check_max_interval},
 	{}
 };
 static ctl_table xpc_sys_xpc_dir[] = {
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "hb",
 	 .mode = 0555,
 	 .child = xpc_sys_xpc_hb_dir},
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "disengage_timelimit",
 	 .data = &xpc_disengage_timelimit,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = &proc_dointvec_minmax,
-	 .strategy = &sysctl_intvec,
+	 .proc_handler = proc_dointvec_minmax,
 	 .extra1 = &xpc_disengage_min_timelimit,
 	 .extra2 = &xpc_disengage_max_timelimit},
 	{}
 };
 static ctl_table xpc_sys_dir[] = {
 	{
-	 .ctl_name = CTL_UNNUMBERED,
 	 .procname = "xpc",
 	 .mode = 0555,
 	 .child = xpc_sys_xpc_dir},
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_partition.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_partition.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/hardirq.h>
 #include "xpc.h"
+#include <asm/uv/uv_hub.h>
 
 /* XPC is exiting flag */
 int xpc_exiting;
@@ -92,8 +93,12 @@ xpc_get_rsvd_page_pa(int nasid)
 			break;
 
 		/* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
-		if (L1_CACHE_ALIGN(len) > buf_len) {
-			kfree(buf_base);
+		if (is_shub())
+			len = L1_CACHE_ALIGN(len);
+
+		if (len > buf_len) {
+			if (buf_base != NULL)
+				kfree(buf_base);
 			buf_len = L1_CACHE_ALIGN(len);
 			buf = xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL,
 							    &buf_base);
@@ -105,7 +110,7 @@ xpc_get_rsvd_page_pa(int nasid)
 			}
 		}
 
-		ret = xp_remote_memcpy(xp_pa(buf), rp_pa, buf_len);
+		ret = xp_remote_memcpy(xp_pa(buf), rp_pa, len);
 		if (ret != xpSuccess) {
 			dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
 			break;
@@ -143,7 +148,7 @@ xpc_setup_rsvd_page(void)
 		dev_err(xpc_part, "SAL failed to locate the reserved page\n");
 		return -ESRCH;
 	}
-	rp = (struct xpc_rsvd_page *)__va(rp_pa);
+	rp = (struct xpc_rsvd_page *)__va(xp_socket_pa(rp_pa));
 
 	if (rp->SAL_version < 3) {
 		/* SAL_versions < 3 had a SAL_partid defined as a u8 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_uv.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_uv.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2010-02-24 13:52:17.000000000 -0500
@@ -106,7 +106,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_
 	int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
 
 #if defined CONFIG_X86_64
-	mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
+	mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
+			UV_AFFINITY_CPU);
 	if (mq->irq < 0) {
 		dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
 			-mq->irq);
@@ -136,7 +137,7 @@ static void
 xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
 {
 #if defined CONFIG_X86_64
-	uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset);
+	uv_teardown_irq(mq->irq);
 
 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
 	int mmr_pnode;
@@ -156,22 +157,24 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc
 {
 	int ret;
 
-#if defined CONFIG_X86_64
-	ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
-					 mq->order, &mq->mmr_offset);
-	if (ret < 0) {
-		dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
-			"ret=%d\n", ret);
-		return ret;
-	}
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-	ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address),
+#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+	int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+
+	ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
 				    mq->order, &mq->mmr_offset);
 	if (ret < 0) {
 		dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
 			ret);
 		return -EBUSY;
 	}
+#elif defined CONFIG_X86_64
+	ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
+					 mq->order, &mq->mmr_offset);
+	if (ret < 0) {
+		dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
+			"ret=%d\n", ret);
+		return ret;
+	}
 #else
 	#error not a supported configuration
 #endif
@@ -184,12 +187,13 @@ static void
 xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
 {
 	int ret;
+	int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
 
 #if defined CONFIG_X86_64
-	ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
+	ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
 	BUG_ON(ret != BIOS_STATUS_SUCCESS);
 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-	ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num);
+	ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
 	BUG_ON(ret != SALRET_OK);
 #else
 	#error not a supported configuration
@@ -203,6 +207,7 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
 	enum xp_retval xp_ret;
 	int ret;
 	int nid;
+	int nasid;
 	int pg_order;
 	struct page *page;
 	struct xpc_gru_mq_uv *mq;
@@ -258,9 +263,11 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
 		goto out_5;
 	}
 
+	nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu));
+
 	mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
 	ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
-				       nid, mmr_value->vector, mmr_value->dest);
+				     nasid, mmr_value->vector, mmr_value->dest);
 	if (ret != 0) {
 		dev_err(xpc_part, "gru_create_message_queue() returned "
 			"error=%d\n", ret);
@@ -945,11 +952,13 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_he
 		head->first = first->next;
 		if (head->first == NULL)
 			head->last = NULL;
+
+		head->n_entries--;
+		BUG_ON(head->n_entries < 0);
+
+		first->next = NULL;
 	}
-	head->n_entries--;
-	BUG_ON(head->n_entries < 0);
 	spin_unlock_irqrestore(&head->lock, irq_flags);
-	first->next = NULL;
 	return first;
 }
 
@@ -1018,7 +1027,8 @@ xpc_make_first_contact_uv(struct xpc_par
 	xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
 				      XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV);
 
-	while (part->sn.uv.remote_act_state != XPC_P_AS_ACTIVATING) {
+	while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) ||
+		 (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) {
 
 		dev_dbg(xpc_part, "waiting to make first contact with "
 			"partition %d\n", XPC_PARTID(part));
@@ -1421,7 +1431,6 @@ xpc_handle_notify_mq_msg_uv(struct xpc_p
 	msg_slot = ch_uv->recv_msg_slots +
 	    (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
 
-	BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
 	BUG_ON(msg_slot->hdr.size != 0);
 
 	memcpy(msg_slot, msg, msg->hdr.size);
@@ -1645,8 +1654,6 @@ xpc_received_payload_uv(struct xpc_chann
 			       sizeof(struct xpc_notify_mq_msghdr_uv));
 	if (ret != xpSuccess)
 		XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
-
-	msg->hdr.msg_slot_number += ch->remote_nentries;
 }
 
 static struct xpc_arch_operations xpc_arch_ops_uv = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp.h linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp.h
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp.h	2010-02-24 13:52:17.000000000 -0500
@@ -339,6 +339,7 @@ extern short xp_partition_id;
 extern u8 xp_region_size;
 
 extern unsigned long (*xp_pa) (void *);
+extern unsigned long (*xp_socket_pa) (unsigned long);
 extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
 		       size_t);
 extern int (*xp_cpu_to_nasid) (int);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_main.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_main.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,9 @@ EXPORT_SYMBOL_GPL(xp_region_size);
 unsigned long (*xp_pa) (void *addr);
 EXPORT_SYMBOL_GPL(xp_pa);
 
+unsigned long (*xp_socket_pa) (unsigned long gpa);
+EXPORT_SYMBOL_GPL(xp_socket_pa);
+
 enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
 				    const unsigned long src_gpa, size_t len);
 EXPORT_SYMBOL_GPL(xp_remote_memcpy);
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_sn2.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_sn2.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_sn2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_sn2.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,15 @@ xp_pa_sn2(void *addr)
 }
 
 /*
+ * Convert a global physical to a socket physical address.
+ */
+static unsigned long
+xp_socket_pa_sn2(unsigned long gpa)
+{
+	return gpa;
+}
+
+/*
  * Wrapper for bte_copy().
  *
  *	dst_pa - physical address of the destination of the transfer.
@@ -162,6 +171,7 @@ xp_init_sn2(void)
 	xp_region_size = sn_region_size;
 
 	xp_pa = xp_pa_sn2;
+	xp_socket_pa = xp_socket_pa_sn2;
 	xp_remote_memcpy = xp_remote_memcpy_sn2;
 	xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
 	xp_expand_memprotect = xp_expand_memprotect_sn2;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_uv.c linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_uv.c
--- linux-libre-2.6.32-gnu1/drivers/misc/sgi-xp/xp_uv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/sgi-xp/xp_uv.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,12 +32,44 @@ xp_pa_uv(void *addr)
 	return uv_gpa(addr);
 }
 
+/*
+ * Convert a global physical to socket physical address.
+ */
+static unsigned long
+xp_socket_pa_uv(unsigned long gpa)
+{
+	return uv_gpa_to_soc_phys_ram(gpa);
+}
+
+static enum xp_retval
+xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
+		   size_t len)
+{
+	int ret;
+	unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
+
+	BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
+	BUG_ON(len != 8);
+
+	ret = gru_read_gpa(dst_va, src_gpa);
+	if (ret == 0)
+		return xpSuccess;
+
+	dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
+		"len=%ld\n", dst_gpa, src_gpa, len);
+	return xpGruCopyError;
+}
+
+
 static enum xp_retval
 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
 		    size_t len)
 {
 	int ret;
 
+	if (uv_gpa_in_mmr_space(src_gpa))
+		return xp_remote_mmr_read(dst_gpa, src_gpa, len);
+
 	ret = gru_copy_gpa(dst_gpa, src_gpa, len);
 	if (ret == 0)
 		return xpSuccess;
@@ -123,6 +155,7 @@ xp_init_uv(void)
 	xp_region_size = sn_region_size;
 
 	xp_pa = xp_pa_uv;
+	xp_socket_pa = xp_socket_pa_uv;
 	xp_remote_memcpy = xp_remote_memcpy_uv;
 	xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
 	xp_expand_memprotect = xp_expand_memprotect_uv;
diff -druNp linux-libre-2.6.32-gnu1/drivers/misc/ti_dac7512.c linux-libre-2.6.33-gnu1/drivers/misc/ti_dac7512.c
--- linux-libre-2.6.32-gnu1/drivers/misc/ti_dac7512.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/misc/ti_dac7512.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ *  dac7512.c - Linux kernel module for
+ * 	Texas Instruments DAC7512
+ *
+ *  Copyright (c) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spi/spi.h>
+
+#define DAC7512_DRV_NAME	"dac7512"
+#define DRIVER_VERSION		"1.0"
+
+static ssize_t dac7512_store_val(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	unsigned char tmp[2];
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) < 0)
+		return -EINVAL;
+
+	tmp[0] = val >> 8;
+	tmp[1] = val & 0xff;
+	spi_write(spi, tmp, sizeof(tmp));
+	return count;
+}
+
+static DEVICE_ATTR(value, S_IWUSR, NULL, dac7512_store_val);
+
+static struct attribute *dac7512_attributes[] = {
+	&dev_attr_value.attr,
+	NULL
+};
+
+static const struct attribute_group dac7512_attr_group = {
+	.attrs = dac7512_attributes,
+};
+
+static int __devinit dac7512_probe(struct spi_device *spi)
+{
+	int ret;
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_0;
+	ret = spi_setup(spi);
+	if (ret < 0)
+		return ret;
+
+	return sysfs_create_group(&spi->dev.kobj, &dac7512_attr_group);
+}
+
+static int __devexit dac7512_remove(struct spi_device *spi)
+{
+	sysfs_remove_group(&spi->dev.kobj, &dac7512_attr_group);
+	return 0;
+}
+
+static struct spi_driver dac7512_driver = {
+	.driver = {
+		.name	= DAC7512_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= dac7512_probe,
+	.remove	= __devexit_p(dac7512_remove),
+};
+
+static int __init dac7512_init(void)
+{
+	return spi_register_driver(&dac7512_driver);
+}
+
+static void __exit dac7512_exit(void)
+{
+	spi_unregister_driver(&dac7512_driver);
+}
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("DAC7512 16-bit DAC");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(dac7512_init);
+module_exit(dac7512_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/card/block.c linux-libre-2.6.33-gnu1/drivers/mmc/card/block.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/card/block.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/card/block.c	2010-02-24 13:52:17.000000000 -0500
@@ -85,7 +85,14 @@ static void mmc_blk_put(struct mmc_blk_d
 	mutex_lock(&open_lock);
 	md->usage--;
 	if (md->usage == 0) {
+		int devmaj = MAJOR(disk_devt(md->disk));
 		int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT;
+
+		if (!devmaj)
+			devidx = md->disk->first_minor >> MMC_SHIFT;
+
+		blk_cleanup_queue(md->queue.queue);
+
 		__clear_bit(devidx, dev_use);
 
 		put_disk(md->disk);
@@ -613,6 +620,7 @@ static int mmc_blk_probe(struct mmc_card
 	return 0;
 
  out:
+	mmc_cleanup_queue(&md->queue);
 	mmc_blk_put(md);
 
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/card/mmc_test.c linux-libre-2.6.33-gnu1/drivers/mmc/card/mmc_test.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/card/mmc_test.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/card/mmc_test.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,9 @@ static void mmc_test_prepare_mrq(struct
 	}
 
 	mrq->cmd->arg = dev_addr;
+	if (!mmc_card_blockaddr(test->card))
+		mrq->cmd->arg <<= 9;
+
 	mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
 	if (blocks == 1)
@@ -190,7 +193,7 @@ static int __mmc_test_prepare(struct mmc
 	}
 
 	for (i = 0;i < BUFFER_SIZE / 512;i++) {
-		ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
+		ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1);
 		if (ret)
 			return ret;
 	}
@@ -219,7 +222,7 @@ static int mmc_test_cleanup(struct mmc_t
 	memset(test->buffer, 0, 512);
 
 	for (i = 0;i < BUFFER_SIZE / 512;i++) {
-		ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
+		ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1);
 		if (ret)
 			return ret;
 	}
@@ -426,7 +429,7 @@ static int mmc_test_transfer(struct mmc_
 		for (i = 0;i < sectors;i++) {
 			ret = mmc_test_buffer_transfer(test,
 				test->buffer + i * 512,
-				dev_addr + i * 512, 512, 0);
+				dev_addr + i, 512, 0);
 			if (ret)
 				return ret;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/card/queue.c linux-libre-2.6.33-gnu1/drivers/mmc/card/queue.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/card/queue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/card/queue.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,9 +90,10 @@ static void mmc_request(struct request_q
 	struct request *req;
 
 	if (!mq) {
-		printk(KERN_ERR "MMC: killing requests for dead queue\n");
-		while ((req = blk_fetch_request(q)) != NULL)
+		while ((req = blk_fetch_request(q)) != NULL) {
+			req->cmd_flags |= REQ_QUIET;
 			__blk_end_request_all(req, -EIO);
+		}
 		return;
 	}
 
@@ -223,17 +224,18 @@ void mmc_cleanup_queue(struct mmc_queue
 	struct request_queue *q = mq->queue;
 	unsigned long flags;
 
-	/* Mark that we should start throwing out stragglers */
-	spin_lock_irqsave(q->queue_lock, flags);
-	q->queuedata = NULL;
-	spin_unlock_irqrestore(q->queue_lock, flags);
-
 	/* Make sure the queue isn't suspended, as that will deadlock */
 	mmc_queue_resume(mq);
 
 	/* Then terminate our worker thread */
 	kthread_stop(mq->thread);
 
+	/* Empty the queue */
+	spin_lock_irqsave(q->queue_lock, flags);
+	q->queuedata = NULL;
+	blk_start_queue(q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
  	if (mq->bounce_sg)
  		kfree(mq->bounce_sg);
  	mq->bounce_sg = NULL;
@@ -245,8 +247,6 @@ void mmc_cleanup_queue(struct mmc_queue
 		kfree(mq->bounce_buf);
 	mq->bounce_buf = NULL;
 
-	blk_cleanup_queue(mq->queue);
-
 	mq->card = NULL;
 }
 EXPORT_SYMBOL(mmc_cleanup_queue);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/card/sdio_uart.c linux-libre-2.6.33-gnu1/drivers/mmc/card/sdio_uart.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/card/sdio_uart.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/card/sdio_uart.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/seq_file.h>
 #include <linux/serial_reg.h>
@@ -73,11 +74,10 @@ struct uart_icount {
 };
 
 struct sdio_uart_port {
+	struct tty_port		port;
 	struct kref		kref;
 	struct tty_struct	*tty;
 	unsigned int		index;
-	unsigned int		opened;
-	struct mutex		open_lock;
 	struct sdio_func	*func;
 	struct mutex		func_lock;
 	struct task_struct	*in_sdio_uart_irq;
@@ -87,6 +87,7 @@ struct sdio_uart_port {
 	struct uart_icount	icount;
 	unsigned int		uartclk;
 	unsigned int		mctrl;
+	unsigned int		rx_mctrl;
 	unsigned int		read_status_mask;
 	unsigned int		ignore_status_mask;
 	unsigned char		x_char;
@@ -102,7 +103,6 @@ static int sdio_uart_add_port(struct sdi
 	int index, ret = -EBUSY;
 
 	kref_init(&port->kref);
-	mutex_init(&port->open_lock);
 	mutex_init(&port->func_lock);
 	spin_lock_init(&port->write_lock);
 
@@ -151,6 +151,7 @@ static void sdio_uart_port_put(struct sd
 static void sdio_uart_port_remove(struct sdio_uart_port *port)
 {
 	struct sdio_func *func;
+	struct tty_struct *tty;
 
 	BUG_ON(sdio_uart_table[port->index] != port);
 
@@ -165,15 +166,19 @@ static void sdio_uart_port_remove(struct
 	 * give up on that port ASAP.
 	 * Beware: the lock ordering is critical.
 	 */
-	mutex_lock(&port->open_lock);
+	mutex_lock(&port->port.mutex);
 	mutex_lock(&port->func_lock);
 	func = port->func;
 	sdio_claim_host(func);
 	port->func = NULL;
 	mutex_unlock(&port->func_lock);
-	if (port->opened)
-		tty_hangup(port->tty);
-	mutex_unlock(&port->open_lock);
+	tty = tty_port_tty_get(&port->port);
+	/* tty_hangup is async so is this safe as is ?? */
+	if (tty) {
+		tty_hangup(tty);
+		tty_kref_put(tty);
+	}
+	mutex_unlock(&port->port.mutex);
 	sdio_release_irq(func);
 	sdio_disable_func(func);
 	sdio_release_host(func);
@@ -217,6 +222,8 @@ static unsigned int sdio_uart_get_mctrl(
 	unsigned char status;
 	unsigned int ret;
 
+	/* FIXME: What stops this losing the delta bits and breaking
+	   sdio_uart_check_modem_status ? */
 	status = sdio_in(port, UART_MSR);
 
 	ret = 0;
@@ -231,7 +238,8 @@ static unsigned int sdio_uart_get_mctrl(
 	return ret;
 }
 
-static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl)
+static void sdio_uart_write_mctrl(struct sdio_uart_port *port,
+				  unsigned int mctrl)
 {
 	unsigned char mcr = 0;
 
@@ -387,9 +395,10 @@ static void sdio_uart_stop_rx(struct sdi
 	sdio_out(port, UART_IER, port->ier);
 }
 
-static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status)
+static void sdio_uart_receive_chars(struct sdio_uart_port *port,
+				    unsigned int *status)
 {
-	struct tty_struct *tty = port->tty;
+	struct tty_struct *tty = tty_port_tty_get(&port->port);
 	unsigned int ch, flag;
 	int max_count = 256;
 
@@ -399,7 +408,7 @@ static void sdio_uart_receive_chars(stru
 		port->icount.rx++;
 
 		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
-				        UART_LSR_FE | UART_LSR_OE))) {
+					UART_LSR_FE | UART_LSR_OE))) {
 			/*
 			 * For statistics only
 			 */
@@ -417,33 +426,39 @@ static void sdio_uart_receive_chars(stru
 			 * Mask off conditions which should be ignored.
 			 */
 			*status &= port->read_status_mask;
-			if (*status & UART_LSR_BI) {
+			if (*status & UART_LSR_BI)
 				flag = TTY_BREAK;
-			} else if (*status & UART_LSR_PE)
+			else if (*status & UART_LSR_PE)
 				flag = TTY_PARITY;
 			else if (*status & UART_LSR_FE)
 				flag = TTY_FRAME;
 		}
 
 		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
-			tty_insert_flip_char(tty, ch, flag);
+			if (tty)
+				tty_insert_flip_char(tty, ch, flag);
 
 		/*
 		 * Overrun is special.  Since it's reported immediately,
 		 * it doesn't affect the current character.
 		 */
 		if (*status & ~port->ignore_status_mask & UART_LSR_OE)
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+			if (tty)
+				tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 
 		*status = sdio_in(port, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
-	tty_flip_buffer_push(tty);
+	if (tty) {
+		tty_flip_buffer_push(tty);
+		tty_kref_put(tty);
+	}
 }
 
 static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
 {
 	struct circ_buf *xmit = &port->xmit;
 	int count;
+	struct tty_struct *tty;
 
 	if (port->x_char) {
 		sdio_out(port, UART_TX, port->x_char);
@@ -451,8 +466,13 @@ static void sdio_uart_transmit_chars(str
 		port->x_char = 0;
 		return;
 	}
-	if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
+
+	tty = tty_port_tty_get(&port->port);
+
+	if (tty == NULL || circ_empty(xmit) ||
+				tty->stopped || tty->hw_stopped) {
 		sdio_uart_stop_tx(port);
+		tty_kref_put(tty);
 		return;
 	}
 
@@ -466,15 +486,17 @@ static void sdio_uart_transmit_chars(str
 	} while (--count > 0);
 
 	if (circ_chars_pending(xmit) < WAKEUP_CHARS)
-		tty_wakeup(port->tty);
+		tty_wakeup(tty);
 
 	if (circ_empty(xmit))
 		sdio_uart_stop_tx(port);
+	tty_kref_put(tty);
 }
 
 static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
 {
 	int status;
+	struct tty_struct *tty;
 
 	status = sdio_in(port, UART_MSR);
 
@@ -485,25 +507,39 @@ static void sdio_uart_check_modem_status
 		port->icount.rng++;
 	if (status & UART_MSR_DDSR)
 		port->icount.dsr++;
-	if (status & UART_MSR_DDCD)
+	if (status & UART_MSR_DDCD) {
 		port->icount.dcd++;
+		/* DCD raise - wake for open */
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&port->port.open_wait);
+		else {
+			/* DCD drop - hang up if tty attached */
+			tty = tty_port_tty_get(&port->port);
+			if (tty) {
+				tty_hangup(tty);
+				tty_kref_put(tty);
+			}
+		}
+	}
 	if (status & UART_MSR_DCTS) {
 		port->icount.cts++;
-		if (port->tty->termios->c_cflag & CRTSCTS) {
+		tty = tty_port_tty_get(&port->port);
+		if (tty && (tty->termios->c_cflag & CRTSCTS)) {
 			int cts = (status & UART_MSR_CTS);
-			if (port->tty->hw_stopped) {
+			if (tty->hw_stopped) {
 				if (cts) {
-					port->tty->hw_stopped = 0;
+					tty->hw_stopped = 0;
 					sdio_uart_start_tx(port);
-					tty_wakeup(port->tty);
+					tty_wakeup(tty);
 				}
 			} else {
 				if (!cts) {
-					port->tty->hw_stopped = 1;
+					tty->hw_stopped = 1;
 					sdio_uart_stop_tx(port);
 				}
 			}
 		}
+		tty_kref_put(tty);
 	}
 }
 
@@ -540,8 +576,62 @@ static void sdio_uart_irq(struct sdio_fu
 	port->in_sdio_uart_irq = NULL;
 }
 
-static int sdio_uart_startup(struct sdio_uart_port *port)
+static int uart_carrier_raised(struct tty_port *tport)
 {
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
+	unsigned int ret = sdio_uart_claim_func(port);
+	if (ret)	/* Missing hardware shoudn't block for carrier */
+		return 1;
+	ret = sdio_uart_get_mctrl(port);
+	sdio_uart_release_func(port);
+	if (ret & TIOCM_CAR)
+		return 1;
+	return 0;
+}
+
+/**
+ *	uart_dtr_rts		-	 port helper to set uart signals
+ *	@tport: tty port to be updated
+ *	@onoff: set to turn on DTR/RTS
+ *
+ *	Called by the tty port helpers when the modem signals need to be
+ *	adjusted during an open, close and hangup.
+ */
+
+static void uart_dtr_rts(struct tty_port *tport, int onoff)
+{
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
+	int ret = sdio_uart_claim_func(port);
+	if (ret)
+		return;
+	if (onoff == 0)
+		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	else
+		sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	sdio_uart_release_func(port);
+}
+
+/**
+ *	sdio_uart_activate	-	start up hardware
+ *	@tport: tty port to activate
+ *	@tty: tty bound to this port
+ *
+ *	Activate a tty port. The port locking guarantees us this will be
+ *	run exactly once per set of opens, and if successful will see the
+ *	shutdown method run exactly once to match. Start up and shutdown are
+ *	protected from each other by the internal locking and will not run
+ *	at the same time even during a hangup event.
+ *
+ *	If we successfully start up the port we take an extra kref as we
+ *	will keep it around until shutdown when the kref is dropped.
+ */
+
+static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
+{
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
 	unsigned long page;
 	int ret;
 
@@ -549,7 +639,7 @@ static int sdio_uart_startup(struct sdio
 	 * Set the TTY IO error marker - we will only clear this
 	 * once we have successfully opened the port.
 	 */
-	set_bit(TTY_IO_ERROR, &port->tty->flags);
+	set_bit(TTY_IO_ERROR, &tty->flags);
 
 	/* Initialise and allocate the transmit buffer. */
 	page = __get_free_page(GFP_KERNEL);
@@ -574,7 +664,7 @@ static int sdio_uart_startup(struct sdio
 	 */
 	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
 	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
-			UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 	sdio_out(port, UART_FCR, 0);
 
 	/*
@@ -590,19 +680,19 @@ static int sdio_uart_startup(struct sdio
 	 */
 	sdio_out(port, UART_LCR, UART_LCR_WLEN8);
 
-	port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
+	port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
 	port->mctrl = TIOCM_OUT2;
 
-	sdio_uart_change_speed(port, port->tty->termios, NULL);
+	sdio_uart_change_speed(port, tty->termios, NULL);
 
-	if (port->tty->termios->c_cflag & CBAUD)
+	if (tty->termios->c_cflag & CBAUD)
 		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 
-	if (port->tty->termios->c_cflag & CRTSCTS)
+	if (tty->termios->c_cflag & CRTSCTS)
 		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
-			port->tty->hw_stopped = 1;
+			tty->hw_stopped = 1;
 
-	clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	clear_bit(TTY_IO_ERROR, &tty->flags);
 
 	/* Kick the IRQ handler once while we're still holding the host lock */
 	sdio_uart_irq(port->func);
@@ -619,8 +709,20 @@ err1:
 	return ret;
 }
 
-static void sdio_uart_shutdown(struct sdio_uart_port *port)
+/**
+ *	sdio_uart_shutdown	-	stop hardware
+ *	@tport: tty port to shut down
+ *
+ *	Deactivate a tty port. The port locking guarantees us this will be
+ *	run only if a successful matching activate already ran. The two are
+ *	protected from each other by the internal locking and will not run
+ *	at the same time even during a hangup event.
+ */
+
+static void sdio_uart_shutdown(struct tty_port *tport)
 {
+	struct sdio_uart_port *port =
+			container_of(tport, struct sdio_uart_port, port);
 	int ret;
 
 	ret = sdio_uart_claim_func(port);
@@ -629,13 +731,7 @@ static void sdio_uart_shutdown(struct sd
 
 	sdio_uart_stop_rx(port);
 
-	/* TODO: wait here for TX FIFO to drain */
-
-	/* Turn off DTR and RTS early. */
-	if (port->tty->termios->c_cflag & HUPCL)
-		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-
-	 /* Disable interrupts from this port */
+	/* Disable interrupts from this port */
 	sdio_release_irq(port->func);
 	port->ier = 0;
 	sdio_out(port, UART_IER, 0);
@@ -659,77 +755,70 @@ skip:
 	free_page((unsigned long)port->xmit.buf);
 }
 
-static int sdio_uart_open (struct tty_struct *tty, struct file * filp)
-{
-	struct sdio_uart_port *port;
-	int ret;
-
-	port = sdio_uart_port_get(tty->index);
-	if (!port)
-		return -ENODEV;
-
-	mutex_lock(&port->open_lock);
+/**
+ *	sdio_uart_install	-	install method
+ *	@driver: the driver in use (sdio_uart in our case)
+ *	@tty: the tty being bound
+ *
+ *	Look up and bind the tty and the driver together. Initialize
+ *	any needed private data (in our case the termios)
+ */
 
-	/*
-	 * Make sure not to mess up with a dead port
-	 * which has not been closed yet.
-	 */
-	if (tty->driver_data && tty->driver_data != port) {
-		mutex_unlock(&port->open_lock);
-		sdio_uart_port_put(port);
-		return -EBUSY;
-	}
+static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+	int idx = tty->index;
+	struct sdio_uart_port *port = sdio_uart_port_get(idx);
+	int ret = tty_init_termios(tty);
 
-	if (!port->opened) {
+	if (ret == 0) {
+		tty_driver_kref_get(driver);
+		tty->count++;
+		/* This is the ref sdio_uart_port get provided */
 		tty->driver_data = port;
-		port->tty = tty;
-		ret = sdio_uart_startup(port);
-		if (ret) {
-			tty->driver_data = NULL;
-			port->tty = NULL;
-			mutex_unlock(&port->open_lock);
-			sdio_uart_port_put(port);
-			return ret;
-		}
-	}
-	port->opened++;
-	mutex_unlock(&port->open_lock);
-	return 0;
+		driver->ttys[idx] = tty;
+	} else
+		sdio_uart_port_put(port);
+	return ret;
 }
 
-static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+/**
+ *	sdio_uart_cleanup	-	called on the last tty kref drop
+ *	@tty: the tty being destroyed
+ *
+ *	Called asynchronously when the last reference to the tty is dropped.
+ *	We cannot destroy the tty->driver_data port kref until this point
+ */
+
+static void sdio_uart_cleanup(struct tty_struct *tty)
 {
 	struct sdio_uart_port *port = tty->driver_data;
+	tty->driver_data = NULL;	/* Bug trap */
+	sdio_uart_port_put(port);
+}
 
-	if (!port)
-		return;
+/*
+ *	Open/close/hangup is now entirely boilerplate
+ */
 
-	mutex_lock(&port->open_lock);
-	BUG_ON(!port->opened);
+static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	return tty_port_open(&port->port, tty, filp);
+}
 
-	/*
-	 * This is messy.  The tty layer calls us even when open()
-	 * returned an error.  Ignore this close request if tty->count
-	 * is larger than port->count.
-	 */
-	if (tty->count > port->opened) {
-		mutex_unlock(&port->open_lock);
-		return;
-	}
+static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	tty_port_close(&port->port, tty, filp);
+}
 
-	if (--port->opened == 0) {
-		tty->closing = 1;
-		sdio_uart_shutdown(port);
-		tty_ldisc_flush(tty);
-		port->tty = NULL;
-		tty->driver_data = NULL;
-		tty->closing = 0;
-	}
-	mutex_unlock(&port->open_lock);
-	sdio_uart_port_put(port);
+static void sdio_uart_hangup(struct tty_struct *tty)
+{
+	struct sdio_uart_port *port = tty->driver_data;
+	tty_port_hangup(&port->port);
 }
 
-static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
+static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
 			   int count)
 {
 	struct sdio_uart_port *port = tty->driver_data;
@@ -754,7 +843,7 @@ static int sdio_uart_write(struct tty_st
 	}
 	spin_unlock(&port->write_lock);
 
-	if ( !(port->ier & UART_IER_THRI)) {
+	if (!(port->ier & UART_IER_THRI)) {
 		int err = sdio_uart_claim_func(port);
 		if (!err) {
 			sdio_uart_start_tx(port);
@@ -841,17 +930,12 @@ static void sdio_uart_unthrottle(struct
 	sdio_uart_release_func(port);
 }
 
-static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+static void sdio_uart_set_termios(struct tty_struct *tty,
+						struct ktermios *old_termios)
 {
 	struct sdio_uart_port *port = tty->driver_data;
 	unsigned int cflag = tty->termios->c_cflag;
 
-#define RELEVANT_IFLAG(iflag)   ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-	if ((cflag ^ old_termios->c_cflag) == 0 &&
-	    RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
-		return;
-
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
@@ -925,8 +1009,8 @@ static int sdio_uart_tiocmset(struct tty
 	struct sdio_uart_port *port = tty->driver_data;
 	int result;
 
-	result =sdio_uart_claim_func(port);
-	if(!result) {
+	result = sdio_uart_claim_func(port);
+	if (!result) {
 		sdio_uart_update_mctrl(port, set, clear);
 		sdio_uart_release_func(port);
 	}
@@ -944,33 +1028,33 @@ static int sdio_uart_proc_show(struct se
 		struct sdio_uart_port *port = sdio_uart_port_get(i);
 		if (port) {
 			seq_printf(m, "%d: uart:SDIO", i);
-			if(capable(CAP_SYS_ADMIN)) {
+			if (capable(CAP_SYS_ADMIN)) {
 				seq_printf(m, " tx:%d rx:%d",
-					       port->icount.tx, port->icount.rx);
+					      port->icount.tx, port->icount.rx);
 				if (port->icount.frame)
 					seq_printf(m, " fe:%d",
-						       port->icount.frame);
+						      port->icount.frame);
 				if (port->icount.parity)
 					seq_printf(m, " pe:%d",
-						       port->icount.parity);
+						      port->icount.parity);
 				if (port->icount.brk)
 					seq_printf(m, " brk:%d",
-						       port->icount.brk);
+						      port->icount.brk);
 				if (port->icount.overrun)
 					seq_printf(m, " oe:%d",
-						       port->icount.overrun);
+						      port->icount.overrun);
 				if (port->icount.cts)
 					seq_printf(m, " cts:%d",
-						       port->icount.cts);
+						      port->icount.cts);
 				if (port->icount.dsr)
 					seq_printf(m, " dsr:%d",
-						       port->icount.dsr);
+						      port->icount.dsr);
 				if (port->icount.rng)
 					seq_printf(m, " rng:%d",
-						       port->icount.rng);
+						      port->icount.rng);
 				if (port->icount.dcd)
 					seq_printf(m, " dcd:%d",
-						       port->icount.dcd);
+						      port->icount.dcd);
 			}
 			sdio_uart_port_put(port);
 			seq_putc(m, '\n');
@@ -992,6 +1076,13 @@ static const struct file_operations sdio
 	.release	= single_release,
 };
 
+static const struct tty_port_operations sdio_uart_port_ops = {
+	.dtr_rts = uart_dtr_rts,
+	.carrier_raised = uart_carrier_raised,
+	.shutdown = sdio_uart_shutdown,
+	.activate = sdio_uart_activate,
+};
+
 static const struct tty_operations sdio_uart_ops = {
 	.open			= sdio_uart_open,
 	.close			= sdio_uart_close,
@@ -1002,9 +1093,12 @@ static const struct tty_operations sdio_
 	.throttle		= sdio_uart_throttle,
 	.unthrottle		= sdio_uart_unthrottle,
 	.set_termios		= sdio_uart_set_termios,
+	.hangup			= sdio_uart_hangup,
 	.break_ctl		= sdio_uart_break_ctl,
 	.tiocmget		= sdio_uart_tiocmget,
 	.tiocmset		= sdio_uart_tiocmset,
+	.install		= sdio_uart_install,
+	.cleanup		= sdio_uart_cleanup,
 	.proc_fops		= &sdio_uart_proc_fops,
 };
 
@@ -1041,7 +1135,7 @@ static int sdio_uart_probe(struct sdio_f
 		}
 		if (!tpl) {
 			printk(KERN_WARNING
-			       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
+       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
 			       sdio_func_id(func));
 			kfree(port);
 			return -EINVAL;
@@ -1066,13 +1160,16 @@ static int sdio_uart_probe(struct sdio_f
 
 	port->func = func;
 	sdio_set_drvdata(func, port);
+	tty_port_init(&port->port);
+	port->port.ops = &sdio_uart_port_ops;
 
 	ret = sdio_uart_add_port(port);
 	if (ret) {
 		kfree(port);
 	} else {
 		struct device *dev;
-		dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
+		dev = tty_register_device(sdio_uart_tty_driver,
+						port->index, &func->dev);
 		if (IS_ERR(dev)) {
 			sdio_uart_port_remove(port);
 			ret = PTR_ERR(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/core.c linux-libre-2.6.33-gnu1/drivers/mmc/core/core.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,22 @@ int use_spi_crc = 1;
 module_param(use_spi_crc, bool, 0);
 
 /*
+ * We normally treat cards as removed during suspend if they are not
+ * known to be on a non-removable bus, to avoid the risk of writing
+ * back data to a different card after resume.  Allow this to be
+ * overridden if necessary.
+ */
+#ifdef CONFIG_MMC_UNSAFE_RESUME
+int mmc_assume_removable;
+#else
+int mmc_assume_removable = 1;
+#endif
+module_param_named(removable, mmc_assume_removable, bool, 0644);
+MODULE_PARM_DESC(
+	removable,
+	"MMC/SD cards are removable and may be removed during suspend");
+
+/*
  * Internal function. Schedule delayed work in the MMC work queue.
  */
 static int mmc_schedule_delayed_work(struct delayed_work *work,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/core.h linux-libre-2.6.33-gnu1/drivers/mmc/core/core.h
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/core.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,9 @@ int mmc_attach_mmc(struct mmc_host *host
 int mmc_attach_sd(struct mmc_host *host, u32 ocr);
 int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
 
+/* Module parameters */
 extern int use_spi_crc;
+extern int mmc_assume_removable;
 
 /* Debugfs information for hosts and cards */
 void mmc_add_host_debugfs(struct mmc_host *host);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/Kconfig linux-libre-2.6.33-gnu1/drivers/mmc/core/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,7 @@
 #
 
 config MMC_UNSAFE_RESUME
-	bool "Allow unsafe resume (DANGEROUS)"
+	bool "Assume MMC/SD cards are non-removable (DANGEROUS)"
 	help
 	  If you say Y here, the MMC layer will assume that all cards
 	  stayed in their respective slots during the suspend. The
@@ -14,3 +14,5 @@ config MMC_UNSAFE_RESUME
 	  This option is usually just for embedded systems which use
 	  a MMC/SD card for rootfs. Most people should say N here.
 
+	  This option sets a default which can be overridden by the
+	  module parameter "removable=0" or "removable=1".
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/mmc.c linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -207,7 +207,7 @@ static int mmc_read_ext_csd(struct mmc_c
 	}
 
 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
-	if (card->ext_csd.rev > 3) {
+	if (card->ext_csd.rev > 5) {
 		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
 			"version %d\n", mmc_hostname(card->host),
 			card->ext_csd.rev);
@@ -602,25 +602,6 @@ static int mmc_awake(struct mmc_host *ho
 	return err;
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
-static const struct mmc_bus_ops mmc_ops = {
-	.awake = mmc_awake,
-	.sleep = mmc_sleep,
-	.remove = mmc_remove,
-	.detect = mmc_detect,
-	.suspend = mmc_suspend,
-	.resume = mmc_resume,
-	.power_restore = mmc_power_restore,
-};
-
-static void mmc_attach_bus_ops(struct mmc_host *host)
-{
-	mmc_attach_bus(host, &mmc_ops);
-}
-
-#else
-
 static const struct mmc_bus_ops mmc_ops = {
 	.awake = mmc_awake,
 	.sleep = mmc_sleep,
@@ -645,15 +626,13 @@ static void mmc_attach_bus_ops(struct mm
 {
 	const struct mmc_bus_ops *bus_ops;
 
-	if (host->caps & MMC_CAP_NONREMOVABLE)
+	if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable)
 		bus_ops = &mmc_ops_unsafe;
 	else
 		bus_ops = &mmc_ops;
 	mmc_attach_bus(host, bus_ops);
 }
 
-#endif
-
 /*
  * Starting point for MMC card init.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/sd.c linux-libre-2.6.33-gnu1/drivers/mmc/core/sd.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/sd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/sd.c	2010-02-24 13:52:17.000000000 -0500
@@ -606,23 +606,6 @@ static void mmc_sd_power_restore(struct
 	mmc_release_host(host);
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
-static const struct mmc_bus_ops mmc_sd_ops = {
-	.remove = mmc_sd_remove,
-	.detect = mmc_sd_detect,
-	.suspend = mmc_sd_suspend,
-	.resume = mmc_sd_resume,
-	.power_restore = mmc_sd_power_restore,
-};
-
-static void mmc_sd_attach_bus_ops(struct mmc_host *host)
-{
-	mmc_attach_bus(host, &mmc_sd_ops);
-}
-
-#else
-
 static const struct mmc_bus_ops mmc_sd_ops = {
 	.remove = mmc_sd_remove,
 	.detect = mmc_sd_detect,
@@ -643,15 +626,13 @@ static void mmc_sd_attach_bus_ops(struct
 {
 	const struct mmc_bus_ops *bus_ops;
 
-	if (host->caps & MMC_CAP_NONREMOVABLE)
+	if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable)
 		bus_ops = &mmc_sd_ops_unsafe;
 	else
 		bus_ops = &mmc_sd_ops;
 	mmc_attach_bus(host, bus_ops);
 }
 
-#endif
-
 /*
  * Starting point for SD card init.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio_bus.c linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_bus.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio_bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -248,12 +248,15 @@ int sdio_add_func(struct sdio_func *func
 /*
  * Unregister a SDIO function with the driver model, and
  * (eventually) free it.
+ * This function can be called through error paths where sdio_add_func() was
+ * never executed (because a failure occurred at an earlier point).
  */
 void sdio_remove_func(struct sdio_func *func)
 {
-	if (sdio_func_present(func))
-		device_del(&func->dev);
+	if (!sdio_func_present(func))
+		return;
 
+	device_del(&func->dev);
 	put_device(&func->dev);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio.c linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio.c	2010-02-24 13:52:17.000000000 -0500
@@ -516,7 +516,8 @@ int mmc_attach_sdio(struct mmc_host *hos
 	 * The number of functions on the card is encoded inside
 	 * the ocr.
 	 */
-	card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28;
+	funcs = (ocr & 0x70000000) >> 28;
+	card->sdio_funcs = 0;
 
 	/*
 	 * If needed, disconnect card detection pull-up resistor.
@@ -528,7 +529,7 @@ int mmc_attach_sdio(struct mmc_host *hos
 	/*
 	 * Initialize (but don't add) all present functions.
 	 */
-	for (i = 0;i < funcs;i++) {
+	for (i = 0; i < funcs; i++, card->sdio_funcs++) {
 		err = sdio_init_func(host->card, i + 1);
 		if (err)
 			goto remove;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio_cis.c linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_cis.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/core/sdio_cis.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/core/sdio_cis.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,26 +97,56 @@ static const unsigned char speed_val[16]
 static const unsigned int speed_unit[8] =
 	{ 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
 
-/* FUNCE tuples with these types get passed to SDIO drivers */
-static const unsigned char funce_type_whitelist[] = {
-	4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */
+
+typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
+			   const unsigned char *, unsigned);
+
+struct cis_tpl {
+	unsigned char code;
+	unsigned char min_size;
+	tpl_parse_t *parse;
 };
 
-static int cistpl_funce_whitelisted(unsigned char type)
+static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func,
+			 const char *tpl_descr,
+			 const struct cis_tpl *tpl, int tpl_count,
+			 unsigned char code,
+			 const unsigned char *buf, unsigned size)
 {
-	int i;
+	int i, ret;
 
-	for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) {
-		if (funce_type_whitelist[i] == type)
-			return 1;
+	/* look for a matching code in the table */
+	for (i = 0; i < tpl_count; i++, tpl++) {
+		if (tpl->code == code)
+			break;
 	}
-	return 0;
+	if (i < tpl_count) {
+		if (size >= tpl->min_size) {
+			if (tpl->parse)
+				ret = tpl->parse(card, func, buf, size);
+			else
+				ret = -EILSEQ;	/* known tuple, not parsed */
+		} else {
+			/* invalid tuple */
+			ret = -EINVAL;
+		}
+		if (ret && ret != -EILSEQ && ret != -ENOENT) {
+			printk(KERN_ERR "%s: bad %s tuple 0x%02x (%u bytes)\n",
+			       mmc_hostname(card->host), tpl_descr, code, size);
+		}
+	} else {
+		/* unknown tuple */
+		ret = -ENOENT;
+	}
+
+	return ret;
 }
 
-static int cistpl_funce_common(struct mmc_card *card,
+static int cistpl_funce_common(struct mmc_card *card, struct sdio_func *func,
 			       const unsigned char *buf, unsigned size)
 {
-	if (size < 0x04 || buf[0] != 0)
+	/* Only valid for the common CIS (function 0) */
+	if (func)
 		return -EINVAL;
 
 	/* TPLFE_FN0_BLK_SIZE */
@@ -129,20 +159,24 @@ static int cistpl_funce_common(struct mm
 	return 0;
 }
 
-static int cistpl_funce_func(struct sdio_func *func,
+static int cistpl_funce_func(struct mmc_card *card, struct sdio_func *func,
 			     const unsigned char *buf, unsigned size)
 {
 	unsigned vsn;
 	unsigned min_size;
 
-	/* let SDIO drivers take care of whitelisted FUNCE tuples */
-	if (cistpl_funce_whitelisted(buf[0]))
-		return -EILSEQ;
+	/* Only valid for the individual function's CIS (1-7) */
+	if (!func)
+		return -EINVAL;
 
+	/*
+	 * This tuple has a different length depending on the SDIO spec
+	 * version.
+	 */
 	vsn = func->card->cccr.sdio_vsn;
 	min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
 
-	if (size < min_size || buf[0] != 1)
+	if (size < min_size)
 		return -EINVAL;
 
 	/* TPLFE_MAX_BLK_SIZE */
@@ -157,39 +191,32 @@ static int cistpl_funce_func(struct sdio
 	return 0;
 }
 
+/*
+ * Known TPLFE_TYPEs table for CISTPL_FUNCE tuples.
+ *
+ * Note that, unlike PCMCIA, CISTPL_FUNCE tuples are not parsed depending
+ * on the TPLFID_FUNCTION value of the previous CISTPL_FUNCID as on SDIO
+ * TPLFID_FUNCTION is always hardcoded to 0x0C.
+ */
+static const struct cis_tpl cis_tpl_funce_list[] = {
+	{	0x00,	4,	cistpl_funce_common		},
+	{	0x01,	0,	cistpl_funce_func		},
+	{	0x04,	1+1+6,	/* CISTPL_FUNCE_LAN_NODE_ID */	},
+};
+
 static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
 			const unsigned char *buf, unsigned size)
 {
-	int ret;
-
-	/*
-	 * There should be two versions of the CISTPL_FUNCE tuple,
-	 * one for the common CIS (function 0) and a version used by
-	 * the individual function's CIS (1-7). Yet, the later has a
-	 * different length depending on the SDIO spec version.
-	 */
-	if (func)
-		ret = cistpl_funce_func(func, buf, size);
-	else
-		ret = cistpl_funce_common(card, buf, size);
-
-	if (ret && ret != -EILSEQ) {
-		printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
-		       "type %u\n", mmc_hostname(card->host), size, buf[0]);
-	}
+	if (size < 1)
+		return -EINVAL;
 
-	return ret;
+	return cis_tpl_parse(card, func, "CISTPL_FUNCE",
+			     cis_tpl_funce_list,
+			     ARRAY_SIZE(cis_tpl_funce_list),
+			     buf[0], buf, size);
 }
 
-typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
-			   const unsigned char *, unsigned);
-
-struct cis_tpl {
-	unsigned char code;
-	unsigned char min_size;
-	tpl_parse_t *parse;
-};
-
+/* Known TPL_CODEs table for CIS tuples */
 static const struct cis_tpl cis_tpl_list[] = {
 	{	0x15,	3,	cistpl_vers_1		},
 	{	0x20,	4,	cistpl_manfid		},
@@ -268,46 +295,38 @@ static int sdio_read_cis(struct mmc_card
 			break;
 		}
 
-		for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
-			if (cis_tpl_list[i].code == tpl_code)
-				break;
-		if (i < ARRAY_SIZE(cis_tpl_list)) {
-			const struct cis_tpl *tpl = cis_tpl_list + i;
-			if (tpl_link < tpl->min_size) {
-				printk(KERN_ERR
-				       "%s: bad CIS tuple 0x%02x"
-				       " (length = %u, expected >= %u)\n",
-				       mmc_hostname(card->host),
-				       tpl_code, tpl_link, tpl->min_size);
-				ret = -EINVAL;
-			} else if (tpl->parse) {
-				ret = tpl->parse(card, func,
-						 this->data, tpl_link);
-			}
+		/* Try to parse the CIS tuple */
+		ret = cis_tpl_parse(card, func, "CIS",
+				    cis_tpl_list, ARRAY_SIZE(cis_tpl_list),
+				    tpl_code, this->data, tpl_link);
+		if (ret == -EILSEQ || ret == -ENOENT) {
 			/*
-			 * We don't need the tuple anymore if it was
-			 * successfully parsed by the SDIO core or if it is
-			 * not going to be parsed by SDIO drivers.
+			 * The tuple is unknown or known but not parsed.
+			 * Queue the tuple for the function driver.
 			 */
-			if (!ret || ret != -EILSEQ)
-				kfree(this);
-		} else {
-			/* unknown tuple */
-			ret = -EILSEQ;
-		}
-
-		if (ret == -EILSEQ) {
-			/* this tuple is unknown to the core or whitelisted */
 			this->next = NULL;
 			this->code = tpl_code;
 			this->size = tpl_link;
 			*prev = this;
 			prev = &this->next;
-			printk(KERN_DEBUG
-			       "%s: queuing CIS tuple 0x%02x length %u\n",
-			       mmc_hostname(card->host), tpl_code, tpl_link);
+
+			if (ret == -ENOENT) {
+				/* warn about unknown tuples */
+				printk(KERN_WARNING "%s: queuing unknown"
+				       " CIS tuple 0x%02x (%u bytes)\n",
+				       mmc_hostname(card->host),
+				       tpl_code, tpl_link);
+			}
+
 			/* keep on analyzing tuples */
 			ret = 0;
+		} else {
+			/*
+			 * We don't need the tuple anymore if it was
+			 * successfully parsed by the SDIO core or if it is
+			 * not going to be queued for a driver.
+			 */
+			kfree(this);
 		}
 
 		ptr += tpl_link;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/atmel-mci.c linux-libre-2.6.33-gnu1/drivers/mmc/host/atmel-mci.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/atmel-mci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/atmel-mci.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,8 @@
 #include <linux/stat.h>
 
 #include <linux/mmc/host.h>
+
+#include <mach/atmel-mci.h>
 #include <linux/atmel-mci.h>
 
 #include <asm/io.h>
@@ -92,6 +94,7 @@ struct atmel_mci_dma {
  * @need_clock_update: Update the clock rate before the next request.
  * @need_reset: Reset controller before next request.
  * @mode_reg: Value of the MR register.
+ * @cfg_reg: Value of the CFG register.
  * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
  *	rate and timeout calculations.
  * @mapbase: Physical address of the MMIO registers.
@@ -155,6 +158,7 @@ struct atmel_mci {
 	bool			need_clock_update;
 	bool			need_reset;
 	u32			mode_reg;
+	u32			cfg_reg;
 	unsigned long		bus_hz;
 	unsigned long		mapbase;
 	struct clk		*mck;
@@ -223,6 +227,19 @@ static bool mci_has_rwproof(void)
 }
 
 /*
+ * The new MCI2 module isn't 100% compatible with the old MCI module,
+ * and it has a few nice features which we want to use...
+ */
+static inline bool atmci_is_mci2(void)
+{
+	if (cpu_is_at91sam9g45())
+		return true;
+
+	return false;
+}
+
+
+/*
  * The debugfs stuff below is mostly optimized away when
  * CONFIG_DEBUG_FS is not set.
  */
@@ -357,12 +374,33 @@ static int atmci_regs_show(struct seq_fi
 			buf[MCI_BLKR / 4],
 			buf[MCI_BLKR / 4] & 0xffff,
 			(buf[MCI_BLKR / 4] >> 16) & 0xffff);
+	if (atmci_is_mci2())
+		seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]);
 
 	/* Don't read RSPR and RDR; it will consume the data there */
 
 	atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
 	atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
 
+	if (atmci_is_mci2()) {
+		u32 val;
+
+		val = buf[MCI_DMA / 4];
+		seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
+				val, val & 3,
+				((val >> 4) & 3) ?
+					1 << (((val >> 4) & 3) + 1) : 1,
+				val & MCI_DMAEN ? " DMAEN" : "");
+
+		val = buf[MCI_CFG / 4];
+		seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
+				val,
+				val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
+				val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
+				val & MCI_CFG_HSMODE ? " HSMODE" : "",
+				val & MCI_CFG_LSYNC ? " LSYNC" : "");
+	}
+
 	kfree(buf);
 
 	return 0;
@@ -557,6 +595,10 @@ static void atmci_dma_complete(void *arg
 
 	dev_vdbg(&host->pdev->dev, "DMA complete\n");
 
+	if (atmci_is_mci2())
+		/* Disable DMA hardware handshaking on MCI */
+		mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN);
+
 	atmci_dma_cleanup(host);
 
 	/*
@@ -592,7 +634,7 @@ static void atmci_dma_complete(void *arg
 }
 
 static int
-atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
+atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
 {
 	struct dma_chan			*chan;
 	struct dma_async_tx_descriptor	*desc;
@@ -624,6 +666,9 @@ atmci_submit_data_dma(struct atmel_mci *
 	if (!chan)
 		return -ENODEV;
 
+	if (atmci_is_mci2())
+		mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN);
+
 	if (data->flags & MMC_DATA_READ)
 		direction = DMA_FROM_DEVICE;
 	else
@@ -641,10 +686,6 @@ atmci_submit_data_dma(struct atmel_mci *
 	host->dma.data_desc = desc;
 	desc->callback = atmci_dma_complete;
 	desc->callback_param = host;
-	desc->tx_submit(desc);
-
-	/* Go! */
-	chan->device->device_issue_pending(chan);
 
 	return 0;
 unmap_exit:
@@ -652,13 +693,26 @@ unmap_exit:
 	return -ENOMEM;
 }
 
+static void atmci_submit_data(struct atmel_mci *host)
+{
+	struct dma_chan			*chan = host->data_chan;
+	struct dma_async_tx_descriptor	*desc = host->dma.data_desc;
+
+	if (chan) {
+		desc->tx_submit(desc);
+		chan->device->device_issue_pending(chan);
+	}
+}
+
 #else /* CONFIG_MMC_ATMELMCI_DMA */
 
-static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
+static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
 {
 	return -ENOSYS;
 }
 
+static void atmci_submit_data(struct atmel_mci *host) {}
+
 static void atmci_stop_dma(struct atmel_mci *host)
 {
 	/* Data transfer was stopped by the interrupt handler */
@@ -672,7 +726,7 @@ static void atmci_stop_dma(struct atmel_
  * Returns a mask of interrupt flags to be enabled after the whole
  * request has been prepared.
  */
-static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
+static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
 {
 	u32 iflags;
 
@@ -683,7 +737,7 @@ static u32 atmci_submit_data(struct atme
 	host->data = data;
 
 	iflags = ATMCI_DATA_ERROR_FLAGS;
-	if (atmci_submit_data_dma(host, data)) {
+	if (atmci_prepare_data_dma(host, data)) {
 		host->data_chan = NULL;
 
 		/*
@@ -729,6 +783,8 @@ static void atmci_start_request(struct a
 		mci_writel(host, CR, MCI_CR_SWRST);
 		mci_writel(host, CR, MCI_CR_MCIEN);
 		mci_writel(host, MR, host->mode_reg);
+		if (atmci_is_mci2())
+			mci_writel(host, CFG, host->cfg_reg);
 		host->need_reset = false;
 	}
 	mci_writel(host, SDCR, slot->sdc_reg);
@@ -744,6 +800,7 @@ static void atmci_start_request(struct a
 		while (!(mci_readl(host, SR) & MCI_CMDRDY))
 			cpu_relax();
 	}
+	iflags = 0;
 	data = mrq->data;
 	if (data) {
 		atmci_set_timeout(host, slot, data);
@@ -753,15 +810,17 @@ static void atmci_start_request(struct a
 				| MCI_BLKLEN(data->blksz));
 		dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
 			MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
+
+		iflags |= atmci_prepare_data(host, data);
 	}
 
-	iflags = MCI_CMDRDY;
+	iflags |= MCI_CMDRDY;
 	cmd = mrq->cmd;
 	cmdflags = atmci_prepare_command(slot->mmc, cmd);
 	atmci_start_command(host, cmd, cmdflags);
 
 	if (data)
-		iflags |= atmci_submit_data(host, data);
+		atmci_submit_data(host);
 
 	if (mrq->stop) {
 		host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
@@ -857,6 +916,8 @@ static void atmci_set_ios(struct mmc_hos
 			clk_enable(host->mck);
 			mci_writel(host, CR, MCI_CR_SWRST);
 			mci_writel(host, CR, MCI_CR_MCIEN);
+			if (atmci_is_mci2())
+				mci_writel(host, CFG, host->cfg_reg);
 		}
 
 		/*
@@ -1095,6 +1156,8 @@ static void atmci_detect_change(unsigned
 				mci_writel(host, CR, MCI_CR_SWRST);
 				mci_writel(host, CR, MCI_CR_MCIEN);
 				mci_writel(host, MR, host->mode_reg);
+				if (atmci_is_mci2())
+					mci_writel(host, CFG, host->cfg_reg);
 
 				host->data = NULL;
 				host->cmd = NULL;
@@ -1584,14 +1647,47 @@ static void __exit atmci_cleanup_slot(st
 #ifdef CONFIG_MMC_ATMELMCI_DMA
 static bool filter(struct dma_chan *chan, void *slave)
 {
-	struct dw_dma_slave *dws = slave;
+	struct mci_dma_data	*sl = slave;
 
-	if (dws->dma_dev == chan->device->dev) {
-		chan->private = dws;
+	if (sl && find_slave_dev(sl) == chan->device->dev) {
+		chan->private = slave_data_ptr(sl);
 		return true;
-	} else
+	} else {
 		return false;
+	}
+}
+
+static void atmci_configure_dma(struct atmel_mci *host)
+{
+	struct mci_platform_data	*pdata;
+
+	if (host == NULL)
+		return;
+
+	pdata = host->pdev->dev.platform_data;
+
+	if (pdata && find_slave_dev(pdata->dma_slave)) {
+		dma_cap_mask_t mask;
+
+		setup_dma_addr(pdata->dma_slave,
+			       host->mapbase + MCI_TDR,
+			       host->mapbase + MCI_RDR);
+
+		/* Try to grab a DMA channel */
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+		host->dma.chan =
+			dma_request_channel(mask, filter, pdata->dma_slave);
+	}
+	if (!host->dma.chan)
+		dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
+	else
+		dev_info(&host->pdev->dev,
+					"Using %s for DMA transfers\n",
+					dma_chan_name(host->dma.chan));
 }
+#else
+static void atmci_configure_dma(struct atmel_mci *host) {}
 #endif
 
 static int __init atmci_probe(struct platform_device *pdev)
@@ -1645,22 +1741,7 @@ static int __init atmci_probe(struct pla
 	if (ret)
 		goto err_request_irq;
 
-#ifdef CONFIG_MMC_ATMELMCI_DMA
-	if (pdata->dma_slave.dma_dev) {
-		struct dw_dma_slave *dws = &pdata->dma_slave;
-		dma_cap_mask_t mask;
-
-		dws->tx_reg = regs->start + MCI_TDR;
-		dws->rx_reg = regs->start + MCI_RDR;
-
-		/* Try to grab a DMA channel */
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-		host->dma.chan = dma_request_channel(mask, filter, dws);
-	}
-	if (!host->dma.chan)
-		dev_notice(&pdev->dev, "DMA not available, using PIO\n");
-#endif /* CONFIG_MMC_ATMELMCI_DMA */
+	atmci_configure_dma(host);
 
 	platform_set_drvdata(pdev, host);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/bfin_sdh.c linux-libre-2.6.33-gnu1/drivers/mmc/host/bfin_sdh.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/bfin_sdh.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/bfin_sdh.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,639 @@
+/*
+ * bfin_sdh.c - Analog Devices Blackfin SDH Controller
+ *
+ * Copyright (C) 2007-2009 Analog Device Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#define DRIVER_NAME	"bfin-sdh"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/proc_fs.h>
+
+#include <asm/cacheflush.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+#include <asm/bfin_sdh.h>
+
+#if defined(CONFIG_BF51x)
+#define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CTL
+#define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CTL
+#define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CTL
+#define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CTL
+#define bfin_write_SDH_ARGUMENT		bfin_write_RSI_ARGUMENT
+#define bfin_write_SDH_COMMAND		bfin_write_RSI_COMMAND
+#define bfin_write_SDH_DATA_TIMER	bfin_write_RSI_DATA_TIMER
+#define bfin_read_SDH_RESPONSE0		bfin_read_RSI_RESPONSE0
+#define bfin_read_SDH_RESPONSE1		bfin_read_RSI_RESPONSE1
+#define bfin_read_SDH_RESPONSE2		bfin_read_RSI_RESPONSE2
+#define bfin_read_SDH_RESPONSE3		bfin_read_RSI_RESPONSE3
+#define bfin_write_SDH_DATA_LGTH	bfin_write_RSI_DATA_LGTH
+#define bfin_read_SDH_DATA_CTL		bfin_read_RSI_DATA_CTL
+#define bfin_write_SDH_DATA_CTL		bfin_write_RSI_DATA_CTL
+#define bfin_read_SDH_DATA_CNT		bfin_read_RSI_DATA_CNT
+#define bfin_write_SDH_STATUS_CLR	bfin_write_RSI_STATUS_CLR
+#define bfin_read_SDH_E_STATUS		bfin_read_RSI_E_STATUS
+#define bfin_write_SDH_E_STATUS		bfin_write_RSI_E_STATUS
+#define bfin_read_SDH_STATUS		bfin_read_RSI_STATUS
+#define bfin_write_SDH_MASK0		bfin_write_RSI_MASK0
+#define bfin_read_SDH_CFG		bfin_read_RSI_CFG
+#define bfin_write_SDH_CFG		bfin_write_RSI_CFG
+#endif
+
+struct dma_desc_array {
+	unsigned long	start_addr;
+	unsigned short	cfg;
+	unsigned short	x_count;
+	short		x_modify;
+} __packed;
+
+struct sdh_host {
+	struct mmc_host		*mmc;
+	spinlock_t		lock;
+	struct resource		*res;
+	void __iomem		*base;
+	int			irq;
+	int			stat_irq;
+	int			dma_ch;
+	int			dma_dir;
+	struct dma_desc_array	*sg_cpu;
+	dma_addr_t		sg_dma;
+	int			dma_len;
+
+	unsigned int		imask;
+	unsigned int		power_mode;
+	unsigned int		clk_div;
+
+	struct mmc_request	*mrq;
+	struct mmc_command	*cmd;
+	struct mmc_data		*data;
+};
+
+static struct bfin_sd_host *get_sdh_data(struct platform_device *pdev)
+{
+	return pdev->dev.platform_data;
+}
+
+static void sdh_stop_clock(struct sdh_host *host)
+{
+	bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() & ~CLK_E);
+	SSYNC();
+}
+
+static void sdh_enable_stat_irq(struct sdh_host *host, unsigned int mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	host->imask |= mask;
+	bfin_write_SDH_MASK0(mask);
+	SSYNC();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void sdh_disable_stat_irq(struct sdh_host *host, unsigned int mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	host->imask &= ~mask;
+	bfin_write_SDH_MASK0(host->imask);
+	SSYNC();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
+{
+	unsigned int length;
+	unsigned int data_ctl;
+	unsigned int dma_cfg;
+	struct scatterlist *sg;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags);
+	host->data = data;
+	data_ctl = 0;
+	dma_cfg = 0;
+
+	length = data->blksz * data->blocks;
+	bfin_write_SDH_DATA_LGTH(length);
+
+	if (data->flags & MMC_DATA_STREAM)
+		data_ctl |= DTX_MODE;
+
+	if (data->flags & MMC_DATA_READ)
+		data_ctl |= DTX_DIR;
+	/* Only supports power-of-2 block size */
+	if (data->blksz & (data->blksz - 1))
+		return -EINVAL;
+	data_ctl |= ((ffs(data->blksz) - 1) << 4);
+
+	bfin_write_SDH_DATA_CTL(data_ctl);
+
+	bfin_write_SDH_DATA_TIMER(0xFFFF);
+	SSYNC();
+
+	if (data->flags & MMC_DATA_READ) {
+		host->dma_dir = DMA_FROM_DEVICE;
+		dma_cfg |= WNR;
+	} else
+		host->dma_dir = DMA_TO_DEVICE;
+
+	sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END));
+	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir);
+#if defined(CONFIG_BF54x)
+	dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
+	{
+		int i;
+		for_each_sg(data->sg, sg, host->dma_len, i) {
+			host->sg_cpu[i].start_addr = sg_dma_address(sg);
+			host->sg_cpu[i].cfg = dma_cfg;
+			host->sg_cpu[i].x_count = sg_dma_len(sg) / 4;
+			host->sg_cpu[i].x_modify = 4;
+			dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, "
+				"cfg:0x%x, x_count:0x%x, x_modify:0x%x\n",
+				i, host->sg_cpu[i].start_addr,
+				host->sg_cpu[i].cfg, host->sg_cpu[i].x_count,
+				host->sg_cpu[i].x_modify);
+		}
+	}
+	flush_dcache_range((unsigned int)host->sg_cpu,
+		(unsigned int)host->sg_cpu +
+			host->dma_len * sizeof(struct dma_desc_array));
+	/* Set the last descriptor to stop mode */
+	host->sg_cpu[host->dma_len - 1].cfg &= ~(DMAFLOW | NDSIZE);
+	host->sg_cpu[host->dma_len - 1].cfg |= DI_EN;
+
+	set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma);
+	set_dma_x_count(host->dma_ch, 0);
+	set_dma_x_modify(host->dma_ch, 0);
+	set_dma_config(host->dma_ch, dma_cfg);
+#elif defined(CONFIG_BF51x)
+	/* RSI DMA doesn't work in array mode */
+	dma_cfg |= WDSIZE_32 | DMAEN;
+	set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0]));
+	set_dma_x_count(host->dma_ch, length / 4);
+	set_dma_x_modify(host->dma_ch, 4);
+	set_dma_config(host->dma_ch, dma_cfg);
+#endif
+	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
+
+	SSYNC();
+
+	dev_dbg(mmc_dev(host->mmc), "%s exit\n", __func__);
+	return 0;
+}
+
+static void sdh_start_cmd(struct sdh_host *host, struct mmc_command *cmd)
+{
+	unsigned int sdh_cmd;
+	unsigned int stat_mask;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter cmd: 0x%p\n", __func__, cmd);
+	WARN_ON(host->cmd != NULL);
+	host->cmd = cmd;
+
+	sdh_cmd = 0;
+	stat_mask = 0;
+
+	sdh_cmd |= cmd->opcode;
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		sdh_cmd |= CMD_RSP;
+		stat_mask |= CMD_RESP_END;
+	} else {
+		stat_mask |= CMD_SENT;
+	}
+
+	if (cmd->flags & MMC_RSP_136)
+		sdh_cmd |= CMD_L_RSP;
+
+	stat_mask |= CMD_CRC_FAIL | CMD_TIME_OUT;
+
+	sdh_enable_stat_irq(host, stat_mask);
+
+	bfin_write_SDH_ARGUMENT(cmd->arg);
+	bfin_write_SDH_COMMAND(sdh_cmd | CMD_E);
+	bfin_write_SDH_CLK_CTL(bfin_read_SDH_CLK_CTL() | CLK_E);
+	SSYNC();
+}
+
+static void sdh_finish_request(struct sdh_host *host, struct mmc_request *mrq)
+{
+	dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__);
+	host->mrq = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+	mmc_request_done(host->mmc, mrq);
+}
+
+static int sdh_cmd_done(struct sdh_host *host, unsigned int stat)
+{
+	struct mmc_command *cmd = host->cmd;
+	int ret = 0;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter cmd: %p\n", __func__, cmd);
+	if (!cmd)
+		return 0;
+
+	host->cmd = NULL;
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		cmd->resp[0] = bfin_read_SDH_RESPONSE0();
+		if (cmd->flags & MMC_RSP_136) {
+			cmd->resp[1] = bfin_read_SDH_RESPONSE1();
+			cmd->resp[2] = bfin_read_SDH_RESPONSE2();
+			cmd->resp[3] = bfin_read_SDH_RESPONSE3();
+		}
+	}
+	if (stat & CMD_TIME_OUT)
+		cmd->error = -ETIMEDOUT;
+	else if (stat & CMD_CRC_FAIL && cmd->flags & MMC_RSP_CRC)
+		cmd->error = -EILSEQ;
+
+	sdh_disable_stat_irq(host, (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL));
+
+	if (host->data && !cmd->error) {
+		if (host->data->flags & MMC_DATA_WRITE) {
+			ret = sdh_setup_data(host, host->data);
+			if (ret)
+				return 0;
+		}
+
+		sdh_enable_stat_irq(host, DAT_END | RX_OVERRUN | TX_UNDERRUN | DAT_TIME_OUT);
+	} else
+		sdh_finish_request(host, host->mrq);
+
+	return 1;
+}
+
+static int sdh_data_done(struct sdh_host *host, unsigned int stat)
+{
+	struct mmc_data *data = host->data;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter stat: 0x%x\n", __func__, stat);
+	if (!data)
+		return 0;
+
+	disable_dma(host->dma_ch);
+	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+		     host->dma_dir);
+
+	if (stat & DAT_TIME_OUT)
+		data->error = -ETIMEDOUT;
+	else if (stat & DAT_CRC_FAIL)
+		data->error = -EILSEQ;
+	else if (stat & (RX_OVERRUN | TX_UNDERRUN))
+		data->error = -EIO;
+
+	if (!data->error)
+		data->bytes_xfered = data->blocks * data->blksz;
+	else
+		data->bytes_xfered = 0;
+
+	sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN);
+	bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \
+			DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN);
+	bfin_write_SDH_DATA_CTL(0);
+	SSYNC();
+
+	host->data = NULL;
+	if (host->mrq->stop) {
+		sdh_stop_clock(host);
+		sdh_start_cmd(host, host->mrq->stop);
+	} else {
+		sdh_finish_request(host, host->mrq);
+	}
+
+	return 1;
+}
+
+static void sdh_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct sdh_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd);
+	WARN_ON(host->mrq != NULL);
+
+	host->mrq = mrq;
+	host->data = mrq->data;
+
+	if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
+		ret = sdh_setup_data(host, mrq->data);
+		if (ret)
+			return;
+	}
+
+	sdh_start_cmd(host, mrq->cmd);
+}
+
+static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdh_host *host;
+	unsigned long flags;
+	u16 clk_ctl = 0;
+	u16 pwr_ctl = 0;
+	u16 cfg;
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (ios->clock) {
+		unsigned long  sys_clk, ios_clk;
+		unsigned char clk_div;
+		ios_clk = 2 * ios->clock;
+		sys_clk = get_sclk();
+		clk_div = sys_clk / ios_clk;
+		if (sys_clk % ios_clk == 0)
+			clk_div -= 1;
+		clk_div = min_t(unsigned char, clk_div, 0xFF);
+		clk_ctl |= clk_div;
+		clk_ctl |= CLK_E;
+		host->clk_div = clk_div;
+	} else
+		sdh_stop_clock(host);
+
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+#ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+		pwr_ctl |= ROD_CTL;
+#else
+		pwr_ctl |= SD_CMD_OD | ROD_CTL;
+#endif
+
+	if (ios->bus_width == MMC_BUS_WIDTH_4) {
+		cfg = bfin_read_SDH_CFG();
+		cfg &= ~PD_SDDAT3;
+		cfg |= PUP_SDDAT3;
+		/* Enable 4 bit SDIO */
+		cfg |= (SD4E | MWE);
+		bfin_write_SDH_CFG(cfg);
+		clk_ctl |= WIDE_BUS;
+	} else {
+		cfg = bfin_read_SDH_CFG();
+		cfg |= MWE;
+		bfin_write_SDH_CFG(cfg);
+	}
+
+	bfin_write_SDH_CLK_CTL(clk_ctl);
+
+	host->power_mode = ios->power_mode;
+	if (ios->power_mode == MMC_POWER_ON)
+		pwr_ctl |= PWR_ON;
+
+	bfin_write_SDH_PWR_CTL(pwr_ctl);
+	SSYNC();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n",
+		host->clk_div,
+		host->clk_div ? get_sclk() / (2 * (host->clk_div + 1)) : 0,
+		ios->clock);
+}
+
+static const struct mmc_host_ops sdh_ops = {
+	.request	= sdh_request,
+	.set_ios	= sdh_set_ios,
+};
+
+static irqreturn_t sdh_dma_irq(int irq, void *devid)
+{
+	struct sdh_host *host = devid;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__,
+		get_dma_curr_irqstat(host->dma_ch));
+	clear_dma_irqstat(host->dma_ch);
+	SSYNC();
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sdh_stat_irq(int irq, void *devid)
+{
+	struct sdh_host *host = devid;
+	unsigned int status;
+	int handled = 0;
+
+	dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__);
+	status = bfin_read_SDH_E_STATUS();
+	if (status & SD_CARD_DET) {
+		mmc_detect_change(host->mmc, 0);
+		bfin_write_SDH_E_STATUS(SD_CARD_DET);
+	}
+	status = bfin_read_SDH_STATUS();
+	if (status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL)) {
+		handled |= sdh_cmd_done(host, status);
+		bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | \
+				CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT);
+		SSYNC();
+	}
+
+	status = bfin_read_SDH_STATUS();
+	if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN))
+		handled |= sdh_data_done(host, status);
+
+	dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__);
+
+	return IRQ_RETVAL(handled);
+}
+
+static int __devinit sdh_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct sdh_host *host;
+	struct bfin_sd_host *drv_data = get_sdh_data(pdev);
+	int ret;
+
+	if (!drv_data) {
+		dev_err(&pdev->dev, "missing platform driver data\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	mmc->ops = &sdh_ops;
+	mmc->max_phys_segs = 32;
+	mmc->max_seg_size = 1 << 16;
+	mmc->max_blk_size = 1 << 11;
+	mmc->max_blk_count = 1 << 11;
+	mmc->max_req_size = PAGE_SIZE;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->f_max = get_sclk();
+	mmc->f_min = mmc->f_max >> 9;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL;
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+
+	spin_lock_init(&host->lock);
+	host->irq = drv_data->irq_int0;
+	host->dma_ch = drv_data->dma_chan;
+
+	ret = request_dma(host->dma_ch, DRIVER_NAME "DMA");
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request DMA channel\n");
+		goto out1;
+	}
+
+	ret = set_dma_callback(host->dma_ch, sdh_dma_irq, host);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request DMA irq\n");
+		goto out2;
+	}
+
+	host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
+	if (host->sg_cpu == NULL) {
+		ret = -ENOMEM;
+		goto out2;
+	}
+
+	platform_set_drvdata(pdev, mmc);
+	mmc_add_host(mmc);
+
+	ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request status irq\n");
+		goto out3;
+	}
+
+	ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request peripheral pins\n");
+		goto out4;
+	}
+#if defined(CONFIG_BF54x)
+	/* Secure Digital Host shares DMA with Nand controller */
+	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
+#endif
+
+	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+	SSYNC();
+
+	/* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and
+	 * mmc stack will do the detection.
+	 */
+	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
+	SSYNC();
+
+	return 0;
+
+out4:
+	free_irq(host->irq, host);
+out3:
+	mmc_remove_host(mmc);
+	dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+out2:
+	free_dma(host->dma_ch);
+out1:
+	mmc_free_host(mmc);
+ out:
+	return ret;
+}
+
+static int __devexit sdh_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (mmc) {
+		struct sdh_host *host = mmc_priv(mmc);
+
+		mmc_remove_host(mmc);
+
+		sdh_stop_clock(host);
+		free_irq(host->irq, host);
+		free_dma(host->dma_ch);
+		dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+
+		mmc_free_host(mmc);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdh_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	struct bfin_sd_host *drv_data = get_sdh_data(dev);
+	int ret = 0;
+
+	if (mmc)
+		ret = mmc_suspend_host(mmc, state);
+
+	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON);
+	peripheral_free_list(drv_data->pin_req);
+
+	return ret;
+}
+
+static int sdh_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	struct bfin_sd_host *drv_data = get_sdh_data(dev);
+	int ret = 0;
+
+	ret = peripheral_request_list(drv_data->pin_req, DRIVER_NAME);
+	if (ret) {
+		dev_err(&dev->dev, "unable to request peripheral pins\n");
+		return ret;
+	}
+
+	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON);
+#if defined(CONFIG_BF54x)
+	/* Secure Digital Host shares DMA with Nand controller */
+	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
+#endif
+	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+	SSYNC();
+
+	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
+	SSYNC();
+
+	if (mmc)
+		ret = mmc_resume_host(mmc);
+
+	return ret;
+}
+#else
+# define sdh_suspend NULL
+# define sdh_resume  NULL
+#endif
+
+static struct platform_driver sdh_driver = {
+	.probe   = sdh_probe,
+	.remove  = __devexit_p(sdh_remove),
+	.suspend = sdh_suspend,
+	.resume  = sdh_resume,
+	.driver  = {
+		.name = DRIVER_NAME,
+	},
+};
+
+static int __init sdh_init(void)
+{
+	return platform_driver_register(&sdh_driver);
+}
+module_init(sdh_init);
+
+static void __exit sdh_exit(void)
+{
+	platform_driver_unregister(&sdh_driver);
+}
+module_exit(sdh_exit);
+
+MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver");
+MODULE_AUTHOR("Cliff Cai, Roy Huang");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/davinci_mmc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/davinci_mmc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/davinci_mmc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/davinci_mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1349 @@
+/*
+ * davinci_mmc.c - TI DaVinci MMC/SD/SDIO driver
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *       Original author: Purushotam Kumar
+ * Copyright (C) 2009 David Brownell
+ *
+ * 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/module.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/cpufreq.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/mmc.h>
+
+#include <mach/mmc.h>
+#include <mach/edma.h>
+
+/*
+ * Register Definitions
+ */
+#define DAVINCI_MMCCTL       0x00 /* Control Register                  */
+#define DAVINCI_MMCCLK       0x04 /* Memory Clock Control Register     */
+#define DAVINCI_MMCST0       0x08 /* Status Register 0                 */
+#define DAVINCI_MMCST1       0x0C /* Status Register 1                 */
+#define DAVINCI_MMCIM        0x10 /* Interrupt Mask Register           */
+#define DAVINCI_MMCTOR       0x14 /* Response Time-Out Register        */
+#define DAVINCI_MMCTOD       0x18 /* Data Read Time-Out Register       */
+#define DAVINCI_MMCBLEN      0x1C /* Block Length Register             */
+#define DAVINCI_MMCNBLK      0x20 /* Number of Blocks Register         */
+#define DAVINCI_MMCNBLC      0x24 /* Number of Blocks Counter Register */
+#define DAVINCI_MMCDRR       0x28 /* Data Receive Register             */
+#define DAVINCI_MMCDXR       0x2C /* Data Transmit Register            */
+#define DAVINCI_MMCCMD       0x30 /* Command Register                  */
+#define DAVINCI_MMCARGHL     0x34 /* Argument Register                 */
+#define DAVINCI_MMCRSP01     0x38 /* Response Register 0 and 1         */
+#define DAVINCI_MMCRSP23     0x3C /* Response Register 0 and 1         */
+#define DAVINCI_MMCRSP45     0x40 /* Response Register 0 and 1         */
+#define DAVINCI_MMCRSP67     0x44 /* Response Register 0 and 1         */
+#define DAVINCI_MMCDRSP      0x48 /* Data Response Register            */
+#define DAVINCI_MMCETOK      0x4C
+#define DAVINCI_MMCCIDX      0x50 /* Command Index Register            */
+#define DAVINCI_MMCCKC       0x54
+#define DAVINCI_MMCTORC      0x58
+#define DAVINCI_MMCTODC      0x5C
+#define DAVINCI_MMCBLNC      0x60
+#define DAVINCI_SDIOCTL      0x64
+#define DAVINCI_SDIOST0      0x68
+#define DAVINCI_SDIOEN       0x6C
+#define DAVINCI_SDIOST       0x70
+#define DAVINCI_MMCFIFOCTL   0x74 /* FIFO Control Register             */
+
+/* DAVINCI_MMCCTL definitions */
+#define MMCCTL_DATRST         (1 << 0)
+#define MMCCTL_CMDRST         (1 << 1)
+#define MMCCTL_WIDTH_4_BIT    (1 << 2)
+#define MMCCTL_DATEG_DISABLED (0 << 6)
+#define MMCCTL_DATEG_RISING   (1 << 6)
+#define MMCCTL_DATEG_FALLING  (2 << 6)
+#define MMCCTL_DATEG_BOTH     (3 << 6)
+#define MMCCTL_PERMDR_LE      (0 << 9)
+#define MMCCTL_PERMDR_BE      (1 << 9)
+#define MMCCTL_PERMDX_LE      (0 << 10)
+#define MMCCTL_PERMDX_BE      (1 << 10)
+
+/* DAVINCI_MMCCLK definitions */
+#define MMCCLK_CLKEN          (1 << 8)
+#define MMCCLK_CLKRT_MASK     (0xFF << 0)
+
+/* IRQ bit definitions, for DAVINCI_MMCST0 and DAVINCI_MMCIM */
+#define MMCST0_DATDNE         BIT(0)	/* data done */
+#define MMCST0_BSYDNE         BIT(1)	/* busy done */
+#define MMCST0_RSPDNE         BIT(2)	/* command done */
+#define MMCST0_TOUTRD         BIT(3)	/* data read timeout */
+#define MMCST0_TOUTRS         BIT(4)	/* command response timeout */
+#define MMCST0_CRCWR          BIT(5)	/* data write CRC error */
+#define MMCST0_CRCRD          BIT(6)	/* data read CRC error */
+#define MMCST0_CRCRS          BIT(7)	/* command response CRC error */
+#define MMCST0_DXRDY          BIT(9)	/* data transmit ready (fifo empty) */
+#define MMCST0_DRRDY          BIT(10)	/* data receive ready (data in fifo)*/
+#define MMCST0_DATED          BIT(11)	/* DAT3 edge detect */
+#define MMCST0_TRNDNE         BIT(12)	/* transfer done */
+
+/* DAVINCI_MMCST1 definitions */
+#define MMCST1_BUSY           (1 << 0)
+
+/* DAVINCI_MMCCMD definitions */
+#define MMCCMD_CMD_MASK       (0x3F << 0)
+#define MMCCMD_PPLEN          (1 << 7)
+#define MMCCMD_BSYEXP         (1 << 8)
+#define MMCCMD_RSPFMT_MASK    (3 << 9)
+#define MMCCMD_RSPFMT_NONE    (0 << 9)
+#define MMCCMD_RSPFMT_R1456   (1 << 9)
+#define MMCCMD_RSPFMT_R2      (2 << 9)
+#define MMCCMD_RSPFMT_R3      (3 << 9)
+#define MMCCMD_DTRW           (1 << 11)
+#define MMCCMD_STRMTP         (1 << 12)
+#define MMCCMD_WDATX          (1 << 13)
+#define MMCCMD_INITCK         (1 << 14)
+#define MMCCMD_DCLR           (1 << 15)
+#define MMCCMD_DMATRIG        (1 << 16)
+
+/* DAVINCI_MMCFIFOCTL definitions */
+#define MMCFIFOCTL_FIFORST    (1 << 0)
+#define MMCFIFOCTL_FIFODIR_WR (1 << 1)
+#define MMCFIFOCTL_FIFODIR_RD (0 << 1)
+#define MMCFIFOCTL_FIFOLEV    (1 << 2) /* 0 = 128 bits, 1 = 256 bits */
+#define MMCFIFOCTL_ACCWD_4    (0 << 3) /* access width of 4 bytes    */
+#define MMCFIFOCTL_ACCWD_3    (1 << 3) /* access width of 3 bytes    */
+#define MMCFIFOCTL_ACCWD_2    (2 << 3) /* access width of 2 bytes    */
+#define MMCFIFOCTL_ACCWD_1    (3 << 3) /* access width of 1 byte     */
+
+
+/* MMCSD Init clock in Hz in opendrain mode */
+#define MMCSD_INIT_CLOCK		200000
+
+/*
+ * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units,
+ * and we handle up to NR_SG segments.  MMC_BLOCK_BOUNCE kicks in only
+ * for drivers with max_hw_segs == 1, making the segments bigger (64KB)
+ * than the page or two that's otherwise typical.  NR_SG == 16 gives at
+ * least the same throughput boost, using EDMA transfer linkage instead
+ * of spending CPU time copying pages.
+ */
+#define MAX_CCNT	((1 << 16) - 1)
+
+#define NR_SG		16
+
+static unsigned rw_threshold = 32;
+module_param(rw_threshold, uint, S_IRUGO);
+MODULE_PARM_DESC(rw_threshold,
+		"Read/Write threshold. Default = 32");
+
+static unsigned __initdata use_dma = 1;
+module_param(use_dma, uint, 0);
+MODULE_PARM_DESC(use_dma, "Whether to use DMA or not. Default = 1");
+
+struct mmc_davinci_host {
+	struct mmc_command *cmd;
+	struct mmc_data *data;
+	struct mmc_host *mmc;
+	struct clk *clk;
+	unsigned int mmc_input_clk;
+	void __iomem *base;
+	struct resource *mem_res;
+	int irq;
+	unsigned char bus_mode;
+
+#define DAVINCI_MMC_DATADIR_NONE	0
+#define DAVINCI_MMC_DATADIR_READ	1
+#define DAVINCI_MMC_DATADIR_WRITE	2
+	unsigned char data_dir;
+
+	/* buffer is used during PIO of one scatterlist segment, and
+	 * is updated along with buffer_bytes_left.  bytes_left applies
+	 * to all N blocks of the PIO transfer.
+	 */
+	u8 *buffer;
+	u32 buffer_bytes_left;
+	u32 bytes_left;
+
+	u32 rxdma, txdma;
+	bool use_dma;
+	bool do_dma;
+
+	/* Scatterlist DMA uses one or more parameter RAM entries:
+	 * the main one (associated with rxdma or txdma) plus zero or
+	 * more links.  The entries for a given transfer differ only
+	 * by memory buffer (address, length) and link field.
+	 */
+	struct edmacc_param	tx_template;
+	struct edmacc_param	rx_template;
+	unsigned		n_link;
+	u32			links[NR_SG - 1];
+
+	/* For PIO we walk scatterlists one segment at a time. */
+	unsigned int		sg_len;
+	struct scatterlist *sg;
+
+	/* Version of the MMC/SD controller */
+	u8 version;
+	/* for ns in one cycle calculation */
+	unsigned ns_in_one_cycle;
+#ifdef CONFIG_CPU_FREQ
+	struct notifier_block	freq_transition;
+#endif
+};
+
+
+/* PIO only */
+static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host)
+{
+	host->buffer_bytes_left = sg_dma_len(host->sg);
+	host->buffer = sg_virt(host->sg);
+	if (host->buffer_bytes_left > host->bytes_left)
+		host->buffer_bytes_left = host->bytes_left;
+}
+
+static void davinci_fifo_data_trans(struct mmc_davinci_host *host,
+					unsigned int n)
+{
+	u8 *p;
+	unsigned int i;
+
+	if (host->buffer_bytes_left == 0) {
+		host->sg = sg_next(host->data->sg);
+		mmc_davinci_sg_to_buf(host);
+	}
+
+	p = host->buffer;
+	if (n > host->buffer_bytes_left)
+		n = host->buffer_bytes_left;
+	host->buffer_bytes_left -= n;
+	host->bytes_left -= n;
+
+	/* NOTE:  we never transfer more than rw_threshold bytes
+	 * to/from the fifo here; there's no I/O overlap.
+	 * This also assumes that access width( i.e. ACCWD) is 4 bytes
+	 */
+	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
+		for (i = 0; i < (n >> 2); i++) {
+			writel(*((u32 *)p), host->base + DAVINCI_MMCDXR);
+			p = p + 4;
+		}
+		if (n & 3) {
+			iowrite8_rep(host->base + DAVINCI_MMCDXR, p, (n & 3));
+			p = p + (n & 3);
+		}
+	} else {
+		for (i = 0; i < (n >> 2); i++) {
+			*((u32 *)p) = readl(host->base + DAVINCI_MMCDRR);
+			p  = p + 4;
+		}
+		if (n & 3) {
+			ioread8_rep(host->base + DAVINCI_MMCDRR, p, (n & 3));
+			p = p + (n & 3);
+		}
+	}
+	host->buffer = p;
+}
+
+static void mmc_davinci_start_command(struct mmc_davinci_host *host,
+		struct mmc_command *cmd)
+{
+	u32 cmd_reg = 0;
+	u32 im_val;
+
+	dev_dbg(mmc_dev(host->mmc), "CMD%d, arg 0x%08x%s\n",
+		cmd->opcode, cmd->arg,
+		({ char *s;
+		switch (mmc_resp_type(cmd)) {
+		case MMC_RSP_R1:
+			s = ", R1/R5/R6/R7 response";
+			break;
+		case MMC_RSP_R1B:
+			s = ", R1b response";
+			break;
+		case MMC_RSP_R2:
+			s = ", R2 response";
+			break;
+		case MMC_RSP_R3:
+			s = ", R3/R4 response";
+			break;
+		default:
+			s = ", (R? response)";
+			break;
+		}; s; }));
+	host->cmd = cmd;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_R1B:
+		/* There's some spec confusion about when R1B is
+		 * allowed, but if the card doesn't issue a BUSY
+		 * then it's harmless for us to allow it.
+		 */
+		cmd_reg |= MMCCMD_BSYEXP;
+		/* FALLTHROUGH */
+	case MMC_RSP_R1:		/* 48 bits, CRC */
+		cmd_reg |= MMCCMD_RSPFMT_R1456;
+		break;
+	case MMC_RSP_R2:		/* 136 bits, CRC */
+		cmd_reg |= MMCCMD_RSPFMT_R2;
+		break;
+	case MMC_RSP_R3:		/* 48 bits, no CRC */
+		cmd_reg |= MMCCMD_RSPFMT_R3;
+		break;
+	default:
+		cmd_reg |= MMCCMD_RSPFMT_NONE;
+		dev_dbg(mmc_dev(host->mmc), "unknown resp_type %04x\n",
+			mmc_resp_type(cmd));
+		break;
+	}
+
+	/* Set command index */
+	cmd_reg |= cmd->opcode;
+
+	/* Enable EDMA transfer triggers */
+	if (host->do_dma)
+		cmd_reg |= MMCCMD_DMATRIG;
+
+	if (host->version == MMC_CTLR_VERSION_2 && host->data != NULL &&
+			host->data_dir == DAVINCI_MMC_DATADIR_READ)
+		cmd_reg |= MMCCMD_DMATRIG;
+
+	/* Setting whether command involves data transfer or not */
+	if (cmd->data)
+		cmd_reg |= MMCCMD_WDATX;
+
+	/* Setting whether stream or block transfer */
+	if (cmd->flags & MMC_DATA_STREAM)
+		cmd_reg |= MMCCMD_STRMTP;
+
+	/* Setting whether data read or write */
+	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
+		cmd_reg |= MMCCMD_DTRW;
+
+	if (host->bus_mode == MMC_BUSMODE_PUSHPULL)
+		cmd_reg |= MMCCMD_PPLEN;
+
+	/* set Command timeout */
+	writel(0x1FFF, host->base + DAVINCI_MMCTOR);
+
+	/* Enable interrupt (calculate here, defer until FIFO is stuffed). */
+	im_val =  MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS;
+	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
+		im_val |= MMCST0_DATDNE | MMCST0_CRCWR;
+
+		if (!host->do_dma)
+			im_val |= MMCST0_DXRDY;
+	} else if (host->data_dir == DAVINCI_MMC_DATADIR_READ) {
+		im_val |= MMCST0_DATDNE | MMCST0_CRCRD | MMCST0_TOUTRD;
+
+		if (!host->do_dma)
+			im_val |= MMCST0_DRRDY;
+	}
+
+	/*
+	 * Before non-DMA WRITE commands the controller needs priming:
+	 * FIFO should be populated with 32 bytes i.e. whatever is the FIFO size
+	 */
+	if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE))
+		davinci_fifo_data_trans(host, rw_threshold);
+
+	writel(cmd->arg, host->base + DAVINCI_MMCARGHL);
+	writel(cmd_reg,  host->base + DAVINCI_MMCCMD);
+	writel(im_val, host->base + DAVINCI_MMCIM);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* DMA infrastructure */
+
+static void davinci_abort_dma(struct mmc_davinci_host *host)
+{
+	int sync_dev;
+
+	if (host->data_dir == DAVINCI_MMC_DATADIR_READ)
+		sync_dev = host->rxdma;
+	else
+		sync_dev = host->txdma;
+
+	edma_stop(sync_dev);
+	edma_clean_channel(sync_dev);
+}
+
+static void
+mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data);
+
+static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data)
+{
+	if (DMA_COMPLETE != ch_status) {
+		struct mmc_davinci_host *host = data;
+
+		/* Currently means:  DMA Event Missed, or "null" transfer
+		 * request was seen.  In the future, TC errors (like bad
+		 * addresses) might be presented too.
+		 */
+		dev_warn(mmc_dev(host->mmc), "DMA %s error\n",
+			(host->data->flags & MMC_DATA_WRITE)
+				? "write" : "read");
+		host->data->error = -EIO;
+		mmc_davinci_xfer_done(host, host->data);
+	}
+}
+
+/* Set up tx or rx template, to be modified and updated later */
+static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host,
+		bool tx, struct edmacc_param *template)
+{
+	unsigned	sync_dev;
+	const u16	acnt = 4;
+	const u16	bcnt = rw_threshold >> 2;
+	const u16	ccnt = 0;
+	u32		src_port = 0;
+	u32		dst_port = 0;
+	s16		src_bidx, dst_bidx;
+	s16		src_cidx, dst_cidx;
+
+	/*
+	 * A-B Sync transfer:  each DMA request is for one "frame" of
+	 * rw_threshold bytes, broken into "acnt"-size chunks repeated
+	 * "bcnt" times.  Each segment needs "ccnt" such frames; since
+	 * we tell the block layer our mmc->max_seg_size limit, we can
+	 * trust (later) that it's within bounds.
+	 *
+	 * The FIFOs are read/written in 4-byte chunks (acnt == 4) and
+	 * EDMA will optimize memory operations to use larger bursts.
+	 */
+	if (tx) {
+		sync_dev = host->txdma;
+
+		/* src_prt, ccnt, and link to be set up later */
+		src_bidx = acnt;
+		src_cidx = acnt * bcnt;
+
+		dst_port = host->mem_res->start + DAVINCI_MMCDXR;
+		dst_bidx = 0;
+		dst_cidx = 0;
+	} else {
+		sync_dev = host->rxdma;
+
+		src_port = host->mem_res->start + DAVINCI_MMCDRR;
+		src_bidx = 0;
+		src_cidx = 0;
+
+		/* dst_prt, ccnt, and link to be set up later */
+		dst_bidx = acnt;
+		dst_cidx = acnt * bcnt;
+	}
+
+	/*
+	 * We can't use FIFO mode for the FIFOs because MMC FIFO addresses
+	 * are not 256-bit (32-byte) aligned.  So we use INCR, and the W8BIT
+	 * parameter is ignored.
+	 */
+	edma_set_src(sync_dev, src_port, INCR, W8BIT);
+	edma_set_dest(sync_dev, dst_port, INCR, W8BIT);
+
+	edma_set_src_index(sync_dev, src_bidx, src_cidx);
+	edma_set_dest_index(sync_dev, dst_bidx, dst_cidx);
+
+	edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC);
+
+	edma_read_slot(sync_dev, template);
+
+	/* don't bother with irqs or chaining */
+	template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12;
+}
+
+static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
+		struct mmc_data *data)
+{
+	struct edmacc_param	*template;
+	int			channel, slot;
+	unsigned		link;
+	struct scatterlist	*sg;
+	unsigned		sg_len;
+	unsigned		bytes_left = host->bytes_left;
+	const unsigned		shift = ffs(rw_threshold) - 1;;
+
+	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
+		template = &host->tx_template;
+		channel = host->txdma;
+	} else {
+		template = &host->rx_template;
+		channel = host->rxdma;
+	}
+
+	/* We know sg_len and ccnt will never be out of range because
+	 * we told the mmc layer which in turn tells the block layer
+	 * to ensure that it only hands us one scatterlist segment
+	 * per EDMA PARAM entry.  Update the PARAM
+	 * entries needed for each segment of this scatterlist.
+	 */
+	for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len;
+			sg_len-- != 0 && bytes_left;
+			sg = sg_next(sg), slot = host->links[link++]) {
+		u32		buf = sg_dma_address(sg);
+		unsigned	count = sg_dma_len(sg);
+
+		template->link_bcntrld = sg_len
+				? (EDMA_CHAN_SLOT(host->links[link]) << 5)
+				: 0xffff;
+
+		if (count > bytes_left)
+			count = bytes_left;
+		bytes_left -= count;
+
+		if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
+			template->src = buf;
+		else
+			template->dst = buf;
+		template->ccnt = count >> shift;
+
+		edma_write_slot(slot, template);
+	}
+
+	if (host->version == MMC_CTLR_VERSION_2)
+		edma_clear_event(channel);
+
+	edma_start(channel);
+}
+
+static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
+		struct mmc_data *data)
+{
+	int i;
+	int mask = rw_threshold - 1;
+
+	host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+				((data->flags & MMC_DATA_WRITE)
+				? DMA_TO_DEVICE
+				: DMA_FROM_DEVICE));
+
+	/* no individual DMA segment should need a partial FIFO */
+	for (i = 0; i < host->sg_len; i++) {
+		if (sg_dma_len(data->sg + i) & mask) {
+			dma_unmap_sg(mmc_dev(host->mmc),
+					data->sg, data->sg_len,
+					(data->flags & MMC_DATA_WRITE)
+					? DMA_TO_DEVICE
+					: DMA_FROM_DEVICE);
+			return -1;
+		}
+	}
+
+	host->do_dma = 1;
+	mmc_davinci_send_dma_request(host, data);
+
+	return 0;
+}
+
+static void __init_or_module
+davinci_release_dma_channels(struct mmc_davinci_host *host)
+{
+	unsigned	i;
+
+	if (!host->use_dma)
+		return;
+
+	for (i = 0; i < host->n_link; i++)
+		edma_free_slot(host->links[i]);
+
+	edma_free_channel(host->txdma);
+	edma_free_channel(host->rxdma);
+}
+
+static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host)
+{
+	int r, i;
+
+	/* Acquire master DMA write channel */
+	r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host,
+			EVENTQ_DEFAULT);
+	if (r < 0) {
+		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
+				"tx", r);
+		return r;
+	}
+	mmc_davinci_dma_setup(host, true, &host->tx_template);
+
+	/* Acquire master DMA read channel */
+	r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host,
+			EVENTQ_DEFAULT);
+	if (r < 0) {
+		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
+				"rx", r);
+		goto free_master_write;
+	}
+	mmc_davinci_dma_setup(host, false, &host->rx_template);
+
+	/* Allocate parameter RAM slots, which will later be bound to a
+	 * channel as needed to handle a scatterlist.
+	 */
+	for (i = 0; i < ARRAY_SIZE(host->links); i++) {
+		r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY);
+		if (r < 0) {
+			dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n",
+				r);
+			break;
+		}
+		host->links[i] = r;
+	}
+	host->n_link = i;
+
+	return 0;
+
+free_master_write:
+	edma_free_channel(host->txdma);
+
+	return r;
+}
+
+/*----------------------------------------------------------------------*/
+
+static void
+mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request *req)
+{
+	int fifo_lev = (rw_threshold == 32) ? MMCFIFOCTL_FIFOLEV : 0;
+	int timeout;
+	struct mmc_data *data = req->data;
+
+	if (host->version == MMC_CTLR_VERSION_2)
+		fifo_lev = (rw_threshold == 64) ? MMCFIFOCTL_FIFOLEV : 0;
+
+	host->data = data;
+	if (data == NULL) {
+		host->data_dir = DAVINCI_MMC_DATADIR_NONE;
+		writel(0, host->base + DAVINCI_MMCBLEN);
+		writel(0, host->base + DAVINCI_MMCNBLK);
+		return;
+	}
+
+	dev_dbg(mmc_dev(host->mmc), "%s %s, %d blocks of %d bytes\n",
+		(data->flags & MMC_DATA_STREAM) ? "stream" : "block",
+		(data->flags & MMC_DATA_WRITE) ? "write" : "read",
+		data->blocks, data->blksz);
+	dev_dbg(mmc_dev(host->mmc), "  DTO %d cycles + %d ns\n",
+		data->timeout_clks, data->timeout_ns);
+	timeout = data->timeout_clks +
+		(data->timeout_ns / host->ns_in_one_cycle);
+	if (timeout > 0xffff)
+		timeout = 0xffff;
+
+	writel(timeout, host->base + DAVINCI_MMCTOD);
+	writel(data->blocks, host->base + DAVINCI_MMCNBLK);
+	writel(data->blksz, host->base + DAVINCI_MMCBLEN);
+
+	/* Configure the FIFO */
+	switch (data->flags & MMC_DATA_WRITE) {
+	case MMC_DATA_WRITE:
+		host->data_dir = DAVINCI_MMC_DATADIR_WRITE;
+		writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR | MMCFIFOCTL_FIFORST,
+			host->base + DAVINCI_MMCFIFOCTL);
+		writel(fifo_lev | MMCFIFOCTL_FIFODIR_WR,
+			host->base + DAVINCI_MMCFIFOCTL);
+		break;
+
+	default:
+		host->data_dir = DAVINCI_MMC_DATADIR_READ;
+		writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD | MMCFIFOCTL_FIFORST,
+			host->base + DAVINCI_MMCFIFOCTL);
+		writel(fifo_lev | MMCFIFOCTL_FIFODIR_RD,
+			host->base + DAVINCI_MMCFIFOCTL);
+		break;
+	}
+
+	host->buffer = NULL;
+	host->bytes_left = data->blocks * data->blksz;
+
+	/* For now we try to use DMA whenever we won't need partial FIFO
+	 * reads or writes, either for the whole transfer (as tested here)
+	 * or for any individual scatterlist segment (tested when we call
+	 * start_dma_transfer).
+	 *
+	 * While we *could* change that, unusual block sizes are rarely
+	 * used.  The occasional fallback to PIO should't hurt.
+	 */
+	if (host->use_dma && (host->bytes_left & (rw_threshold - 1)) == 0
+			&& mmc_davinci_start_dma_transfer(host, data) == 0) {
+		/* zero this to ensure we take no PIO paths */
+		host->bytes_left = 0;
+	} else {
+		/* Revert to CPU Copy */
+		host->sg_len = data->sg_len;
+		host->sg = host->data->sg;
+		mmc_davinci_sg_to_buf(host);
+	}
+}
+
+static void mmc_davinci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+	struct mmc_davinci_host *host = mmc_priv(mmc);
+	unsigned long timeout = jiffies + msecs_to_jiffies(900);
+	u32 mmcst1 = 0;
+
+	/* Card may still be sending BUSY after a previous operation,
+	 * typically some kind of write.  If so, we can't proceed yet.
+	 */
+	while (time_before(jiffies, timeout)) {
+		mmcst1  = readl(host->base + DAVINCI_MMCST1);
+		if (!(mmcst1 & MMCST1_BUSY))
+			break;
+		cpu_relax();
+	}
+	if (mmcst1 & MMCST1_BUSY) {
+		dev_err(mmc_dev(host->mmc), "still BUSY? bad ... \n");
+		req->cmd->error = -ETIMEDOUT;
+		mmc_request_done(mmc, req);
+		return;
+	}
+
+	host->do_dma = 0;
+	mmc_davinci_prepare_data(host, req);
+	mmc_davinci_start_command(host, req->cmd);
+}
+
+static unsigned int calculate_freq_for_card(struct mmc_davinci_host *host,
+	unsigned int mmc_req_freq)
+{
+	unsigned int mmc_freq = 0, mmc_pclk = 0, mmc_push_pull_divisor = 0;
+
+	mmc_pclk = host->mmc_input_clk;
+	if (mmc_req_freq && mmc_pclk > (2 * mmc_req_freq))
+		mmc_push_pull_divisor = ((unsigned int)mmc_pclk
+				/ (2 * mmc_req_freq)) - 1;
+	else
+		mmc_push_pull_divisor = 0;
+
+	mmc_freq = (unsigned int)mmc_pclk
+		/ (2 * (mmc_push_pull_divisor + 1));
+
+	if (mmc_freq > mmc_req_freq)
+		mmc_push_pull_divisor = mmc_push_pull_divisor + 1;
+	/* Convert ns to clock cycles */
+	if (mmc_req_freq <= 400000)
+		host->ns_in_one_cycle = (1000000) / (((mmc_pclk
+				/ (2 * (mmc_push_pull_divisor + 1)))/1000));
+	else
+		host->ns_in_one_cycle = (1000000) / (((mmc_pclk
+				/ (2 * (mmc_push_pull_divisor + 1)))/1000000));
+
+	return mmc_push_pull_divisor;
+}
+
+static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	unsigned int open_drain_freq = 0, mmc_pclk = 0;
+	unsigned int mmc_push_pull_freq = 0;
+	struct mmc_davinci_host *host = mmc_priv(mmc);
+
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+		u32 temp;
+
+		/* Ignoring the init clock value passed for fixing the inter
+		 * operability with different cards.
+		 */
+		open_drain_freq = ((unsigned int)mmc_pclk
+				/ (2 * MMCSD_INIT_CLOCK)) - 1;
+
+		if (open_drain_freq > 0xFF)
+			open_drain_freq = 0xFF;
+
+		temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK;
+		temp |= open_drain_freq;
+		writel(temp, host->base + DAVINCI_MMCCLK);
+
+		/* Convert ns to clock cycles */
+		host->ns_in_one_cycle = (1000000) / (MMCSD_INIT_CLOCK/1000);
+	} else {
+		u32 temp;
+		mmc_push_pull_freq = calculate_freq_for_card(host, ios->clock);
+
+		if (mmc_push_pull_freq > 0xFF)
+			mmc_push_pull_freq = 0xFF;
+
+		temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKEN;
+		writel(temp, host->base + DAVINCI_MMCCLK);
+
+		udelay(10);
+
+		temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK;
+		temp |= mmc_push_pull_freq;
+		writel(temp, host->base + DAVINCI_MMCCLK);
+
+		writel(temp | MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK);
+
+		udelay(10);
+	}
+}
+
+static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	unsigned int mmc_pclk = 0;
+	struct mmc_davinci_host *host = mmc_priv(mmc);
+
+	mmc_pclk = host->mmc_input_clk;
+	dev_dbg(mmc_dev(host->mmc),
+		"clock %dHz busmode %d powermode %d Vdd %04x\n",
+		ios->clock, ios->bus_mode, ios->power_mode,
+		ios->vdd);
+	if (ios->bus_width == MMC_BUS_WIDTH_4) {
+		dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
+		writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
+			host->base + DAVINCI_MMCCTL);
+	} else {
+		dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
+		writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
+			host->base + DAVINCI_MMCCTL);
+	}
+
+	calculate_clk_divider(mmc, ios);
+
+	host->bus_mode = ios->bus_mode;
+	if (ios->power_mode == MMC_POWER_UP) {
+		unsigned long timeout = jiffies + msecs_to_jiffies(50);
+		bool lose = true;
+
+		/* Send clock cycles, poll completion */
+		writel(0, host->base + DAVINCI_MMCARGHL);
+		writel(MMCCMD_INITCK, host->base + DAVINCI_MMCCMD);
+		while (time_before(jiffies, timeout)) {
+			u32 tmp = readl(host->base + DAVINCI_MMCST0);
+
+			if (tmp & MMCST0_RSPDNE) {
+				lose = false;
+				break;
+			}
+			cpu_relax();
+		}
+		if (lose)
+			dev_warn(mmc_dev(host->mmc), "powerup timeout\n");
+	}
+
+	/* FIXME on power OFF, reset things ... */
+}
+
+static void
+mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data)
+{
+	host->data = NULL;
+
+	if (host->do_dma) {
+		davinci_abort_dma(host);
+
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+			     (data->flags & MMC_DATA_WRITE)
+			     ? DMA_TO_DEVICE
+			     : DMA_FROM_DEVICE);
+		host->do_dma = false;
+	}
+	host->data_dir = DAVINCI_MMC_DATADIR_NONE;
+
+	if (!data->stop || (host->cmd && host->cmd->error)) {
+		mmc_request_done(host->mmc, data->mrq);
+		writel(0, host->base + DAVINCI_MMCIM);
+	} else
+		mmc_davinci_start_command(host, data->stop);
+}
+
+static void mmc_davinci_cmd_done(struct mmc_davinci_host *host,
+				 struct mmc_command *cmd)
+{
+	host->cmd = NULL;
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		if (cmd->flags & MMC_RSP_136) {
+			/* response type 2 */
+			cmd->resp[3] = readl(host->base + DAVINCI_MMCRSP01);
+			cmd->resp[2] = readl(host->base + DAVINCI_MMCRSP23);
+			cmd->resp[1] = readl(host->base + DAVINCI_MMCRSP45);
+			cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67);
+		} else {
+			/* response types 1, 1b, 3, 4, 5, 6 */
+			cmd->resp[0] = readl(host->base + DAVINCI_MMCRSP67);
+		}
+	}
+
+	if (host->data == NULL || cmd->error) {
+		if (cmd->error == -ETIMEDOUT)
+			cmd->mrq->cmd->retries = 0;
+		mmc_request_done(host->mmc, cmd->mrq);
+		writel(0, host->base + DAVINCI_MMCIM);
+	}
+}
+
+static void
+davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data)
+{
+	u32 temp;
+
+	/* reset command and data state machines */
+	temp = readl(host->base + DAVINCI_MMCCTL);
+	writel(temp | MMCCTL_CMDRST | MMCCTL_DATRST,
+		host->base + DAVINCI_MMCCTL);
+
+	temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST);
+	udelay(10);
+	writel(temp, host->base + DAVINCI_MMCCTL);
+}
+
+static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
+{
+	struct mmc_davinci_host *host = (struct mmc_davinci_host *)dev_id;
+	unsigned int status, qstatus;
+	int end_command = 0;
+	int end_transfer = 0;
+	struct mmc_data *data = host->data;
+
+	if (host->cmd == NULL && host->data == NULL) {
+		status = readl(host->base + DAVINCI_MMCST0);
+		dev_dbg(mmc_dev(host->mmc),
+			"Spurious interrupt 0x%04x\n", status);
+		/* Disable the interrupt from mmcsd */
+		writel(0, host->base + DAVINCI_MMCIM);
+		return IRQ_NONE;
+	}
+
+	status = readl(host->base + DAVINCI_MMCST0);
+	qstatus = status;
+
+	/* handle FIFO first when using PIO for data.
+	 * bytes_left will decrease to zero as I/O progress and status will
+	 * read zero over iteration because this controller status
+	 * register(MMCST0) reports any status only once and it is cleared
+	 * by read. So, it is not unbouned loop even in the case of
+	 * non-dma.
+	 */
+	while (host->bytes_left && (status & (MMCST0_DXRDY | MMCST0_DRRDY))) {
+		davinci_fifo_data_trans(host, rw_threshold);
+		status = readl(host->base + DAVINCI_MMCST0);
+		if (!status)
+			break;
+		qstatus |= status;
+	}
+
+	if (qstatus & MMCST0_DATDNE) {
+		/* All blocks sent/received, and CRC checks passed */
+		if (data != NULL) {
+			if ((host->do_dma == 0) && (host->bytes_left > 0)) {
+				/* if datasize < rw_threshold
+				 * no RX ints are generated
+				 */
+				davinci_fifo_data_trans(host, host->bytes_left);
+			}
+			end_transfer = 1;
+			data->bytes_xfered = data->blocks * data->blksz;
+		} else {
+			dev_err(mmc_dev(host->mmc),
+					"DATDNE with no host->data\n");
+		}
+	}
+
+	if (qstatus & MMCST0_TOUTRD) {
+		/* Read data timeout */
+		data->error = -ETIMEDOUT;
+		end_transfer = 1;
+
+		dev_dbg(mmc_dev(host->mmc),
+			"read data timeout, status %x\n",
+			qstatus);
+
+		davinci_abort_data(host, data);
+	}
+
+	if (qstatus & (MMCST0_CRCWR | MMCST0_CRCRD)) {
+		/* Data CRC error */
+		data->error = -EILSEQ;
+		end_transfer = 1;
+
+		/* NOTE:  this controller uses CRCWR to report both CRC
+		 * errors and timeouts (on writes).  MMCDRSP values are
+		 * only weakly documented, but 0x9f was clearly a timeout
+		 * case and the two three-bit patterns in various SD specs
+		 * (101, 010) aren't part of it ...
+		 */
+		if (qstatus & MMCST0_CRCWR) {
+			u32 temp = readb(host->base + DAVINCI_MMCDRSP);
+
+			if (temp == 0x9f)
+				data->error = -ETIMEDOUT;
+		}
+		dev_dbg(mmc_dev(host->mmc), "data %s %s error\n",
+			(qstatus & MMCST0_CRCWR) ? "write" : "read",
+			(data->error == -ETIMEDOUT) ? "timeout" : "CRC");
+
+		davinci_abort_data(host, data);
+	}
+
+	if (qstatus & MMCST0_TOUTRS) {
+		/* Command timeout */
+		if (host->cmd) {
+			dev_dbg(mmc_dev(host->mmc),
+				"CMD%d timeout, status %x\n",
+				host->cmd->opcode, qstatus);
+			host->cmd->error = -ETIMEDOUT;
+			if (data) {
+				end_transfer = 1;
+				davinci_abort_data(host, data);
+			} else
+				end_command = 1;
+		}
+	}
+
+	if (qstatus & MMCST0_CRCRS) {
+		/* Command CRC error */
+		dev_dbg(mmc_dev(host->mmc), "Command CRC error\n");
+		if (host->cmd) {
+			host->cmd->error = -EILSEQ;
+			end_command = 1;
+		}
+	}
+
+	if (qstatus & MMCST0_RSPDNE) {
+		/* End of command phase */
+		end_command = (int) host->cmd;
+	}
+
+	if (end_command)
+		mmc_davinci_cmd_done(host, host->cmd);
+	if (end_transfer)
+		mmc_davinci_xfer_done(host, data);
+	return IRQ_HANDLED;
+}
+
+static int mmc_davinci_get_cd(struct mmc_host *mmc)
+{
+	struct platform_device *pdev = to_platform_device(mmc->parent);
+	struct davinci_mmc_config *config = pdev->dev.platform_data;
+
+	if (!config || !config->get_cd)
+		return -ENOSYS;
+	return config->get_cd(pdev->id);
+}
+
+static int mmc_davinci_get_ro(struct mmc_host *mmc)
+{
+	struct platform_device *pdev = to_platform_device(mmc->parent);
+	struct davinci_mmc_config *config = pdev->dev.platform_data;
+
+	if (!config || !config->get_ro)
+		return -ENOSYS;
+	return config->get_ro(pdev->id);
+}
+
+static struct mmc_host_ops mmc_davinci_ops = {
+	.request	= mmc_davinci_request,
+	.set_ios	= mmc_davinci_set_ios,
+	.get_cd		= mmc_davinci_get_cd,
+	.get_ro		= mmc_davinci_get_ro,
+};
+
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_CPU_FREQ
+static int mmc_davinci_cpufreq_transition(struct notifier_block *nb,
+				     unsigned long val, void *data)
+{
+	struct mmc_davinci_host *host;
+	unsigned int mmc_pclk;
+	struct mmc_host *mmc;
+	unsigned long flags;
+
+	host = container_of(nb, struct mmc_davinci_host, freq_transition);
+	mmc = host->mmc;
+	mmc_pclk = clk_get_rate(host->clk);
+
+	if (val == CPUFREQ_POSTCHANGE) {
+		spin_lock_irqsave(&mmc->lock, flags);
+		host->mmc_input_clk = mmc_pclk;
+		calculate_clk_divider(mmc, &mmc->ios);
+		spin_unlock_irqrestore(&mmc->lock, flags);
+	}
+
+	return 0;
+}
+
+static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
+{
+	host->freq_transition.notifier_call = mmc_davinci_cpufreq_transition;
+
+	return cpufreq_register_notifier(&host->freq_transition,
+					 CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
+{
+	cpufreq_unregister_notifier(&host->freq_transition,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+}
+#else
+static inline int mmc_davinci_cpufreq_register(struct mmc_davinci_host *host)
+{
+	return 0;
+}
+
+static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host)
+{
+}
+#endif
+static void __init init_mmcsd_host(struct mmc_davinci_host *host)
+{
+	/* DAT line portion is diabled and in reset state */
+	writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_DATRST,
+		host->base + DAVINCI_MMCCTL);
+
+	/* CMD line portion is diabled and in reset state */
+	writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_CMDRST,
+		host->base + DAVINCI_MMCCTL);
+
+	udelay(10);
+
+	writel(0, host->base + DAVINCI_MMCCLK);
+	writel(MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK);
+
+	writel(0x1FFF, host->base + DAVINCI_MMCTOR);
+	writel(0xFFFF, host->base + DAVINCI_MMCTOD);
+
+	writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST,
+		host->base + DAVINCI_MMCCTL);
+	writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_CMDRST,
+		host->base + DAVINCI_MMCCTL);
+
+	udelay(10);
+}
+
+static int __init davinci_mmcsd_probe(struct platform_device *pdev)
+{
+	struct davinci_mmc_config *pdata = pdev->dev.platform_data;
+	struct mmc_davinci_host *host = NULL;
+	struct mmc_host *mmc = NULL;
+	struct resource *r, *mem = NULL;
+	int ret = 0, irq = 0;
+	size_t mem_size;
+
+	/* REVISIT:  when we're fully converted, fail if pdata is NULL */
+
+	ret = -ENODEV;
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!r || irq == NO_IRQ)
+		goto out;
+
+	ret = -EBUSY;
+	mem_size = resource_size(r);
+	mem = request_mem_region(r->start, mem_size, pdev->name);
+	if (!mem)
+		goto out;
+
+	ret = -ENOMEM;
+	mmc = mmc_alloc_host(sizeof(struct mmc_davinci_host), &pdev->dev);
+	if (!mmc)
+		goto out;
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;	/* Important */
+
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!r)
+		goto out;
+	host->rxdma = r->start;
+
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (!r)
+		goto out;
+	host->txdma = r->start;
+
+	host->mem_res = mem;
+	host->base = ioremap(mem->start, mem_size);
+	if (!host->base)
+		goto out;
+
+	ret = -ENXIO;
+	host->clk = clk_get(&pdev->dev, "MMCSDCLK");
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		goto out;
+	}
+	clk_enable(host->clk);
+	host->mmc_input_clk = clk_get_rate(host->clk);
+
+	init_mmcsd_host(host);
+
+	host->use_dma = use_dma;
+	host->irq = irq;
+
+	if (host->use_dma && davinci_acquire_dma_channels(host) != 0)
+		host->use_dma = 0;
+
+	/* REVISIT:  someday, support IRQ-driven card detection.  */
+	mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	if (!pdata || pdata->wires == 4 || pdata->wires == 0)
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+	host->version = pdata->version;
+
+	mmc->ops = &mmc_davinci_ops;
+	mmc->f_min = 312500;
+	mmc->f_max = 25000000;
+	if (pdata && pdata->max_freq)
+		mmc->f_max = pdata->max_freq;
+	if (pdata && pdata->caps)
+		mmc->caps |= pdata->caps;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	/* With no iommu coalescing pages, each phys_seg is a hw_seg.
+	 * Each hw_seg uses one EDMA parameter RAM slot, always one
+	 * channel and then usually some linked slots.
+	 */
+	mmc->max_hw_segs	= 1 + host->n_link;
+	mmc->max_phys_segs	= mmc->max_hw_segs;
+
+	/* EDMA limit per hw segment (one or two MBytes) */
+	mmc->max_seg_size	= MAX_CCNT * rw_threshold;
+
+	/* MMC/SD controller limits for multiblock requests */
+	mmc->max_blk_size	= 4095;  /* BLEN is 12 bits */
+	mmc->max_blk_count	= 65535; /* NBLK is 16 bits */
+	mmc->max_req_size	= mmc->max_blk_size * mmc->max_blk_count;
+
+	dev_dbg(mmc_dev(host->mmc), "max_phys_segs=%d\n", mmc->max_phys_segs);
+	dev_dbg(mmc_dev(host->mmc), "max_hw_segs=%d\n", mmc->max_hw_segs);
+	dev_dbg(mmc_dev(host->mmc), "max_blk_size=%d\n", mmc->max_blk_size);
+	dev_dbg(mmc_dev(host->mmc), "max_req_size=%d\n", mmc->max_req_size);
+	dev_dbg(mmc_dev(host->mmc), "max_seg_size=%d\n", mmc->max_seg_size);
+
+	platform_set_drvdata(pdev, host);
+
+	ret = mmc_davinci_cpufreq_register(host);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register cpufreq\n");
+		goto cpu_freq_fail;
+	}
+
+	ret = mmc_add_host(mmc);
+	if (ret < 0)
+		goto out;
+
+	ret = request_irq(irq, mmc_davinci_irq, 0, mmc_hostname(mmc), host);
+	if (ret)
+		goto out;
+
+	rename_region(mem, mmc_hostname(mmc));
+
+	dev_info(mmc_dev(host->mmc), "Using %s, %d-bit mode\n",
+		host->use_dma ? "DMA" : "PIO",
+		(mmc->caps & MMC_CAP_4_BIT_DATA) ? 4 : 1);
+
+	return 0;
+
+out:
+	mmc_davinci_cpufreq_deregister(host);
+cpu_freq_fail:
+	if (host) {
+		davinci_release_dma_channels(host);
+
+		if (host->clk) {
+			clk_disable(host->clk);
+			clk_put(host->clk);
+		}
+
+		if (host->base)
+			iounmap(host->base);
+	}
+
+	if (mmc)
+		mmc_free_host(mmc);
+
+	if (mem)
+		release_resource(mem);
+
+	dev_dbg(&pdev->dev, "probe err %d\n", ret);
+
+	return ret;
+}
+
+static int __exit davinci_mmcsd_remove(struct platform_device *pdev)
+{
+	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	if (host) {
+		mmc_davinci_cpufreq_deregister(host);
+
+		mmc_remove_host(host->mmc);
+		free_irq(host->irq, host);
+
+		davinci_release_dma_channels(host);
+
+		clk_disable(host->clk);
+		clk_put(host->clk);
+
+		iounmap(host->base);
+
+		release_resource(host->mem_res);
+
+		mmc_free_host(host->mmc);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int davinci_mmcsd_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
+
+	return mmc_suspend_host(host->mmc, msg);
+}
+
+static int davinci_mmcsd_resume(struct platform_device *pdev)
+{
+	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
+
+	return mmc_resume_host(host->mmc);
+}
+#else
+#define davinci_mmcsd_suspend	NULL
+#define davinci_mmcsd_resume	NULL
+#endif
+
+static struct platform_driver davinci_mmcsd_driver = {
+	.driver		= {
+		.name	= "davinci_mmc",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __exit_p(davinci_mmcsd_remove),
+	.suspend	= davinci_mmcsd_suspend,
+	.resume		= davinci_mmcsd_resume,
+};
+
+static int __init davinci_mmcsd_init(void)
+{
+	return platform_driver_probe(&davinci_mmcsd_driver,
+				     davinci_mmcsd_probe);
+}
+module_init(davinci_mmcsd_init);
+
+static void __exit davinci_mmcsd_exit(void)
+{
+	platform_driver_unregister(&davinci_mmcsd_driver);
+}
+module_exit(davinci_mmcsd_exit);
+
+MODULE_AUTHOR("Texas Instruments India");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MMC/SD driver for Davinci MMC controller");
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/Kconfig linux-libre-2.6.33-gnu1/drivers/mmc/host/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,19 @@ config MMC_SDHCI_IO_ACCESSORS
 	  This is silent Kconfig symbol that is selected by the drivers that
 	  need to overwrite SDHCI IO memory accessors.
 
+config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+	bool
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This option is selected by drivers running on big endian hosts
+	  and performing I/O to a SDHCI controller through a bus that
+	  implements a hardware byte swapper using a 32-bit datum.
+	  This endian mapping mode is called "data invariance" and
+	  has the effect of scrambling the addresses and formats of data
+	  accessed in sizes other than the datum size.
+
+	  This is the case for the Freescale eSDHC and Nintendo Wii SDHCI.
+
 config MMC_SDHCI_PCI
 	tristate "SDHCI support on PCI bus"
 	depends on MMC_SDHCI && PCI
@@ -75,11 +88,29 @@ config MMC_RICOH_MMC
 config MMC_SDHCI_OF
 	tristate "SDHCI support on OpenFirmware platforms"
 	depends on MMC_SDHCI && PPC_OF
-	select MMC_SDHCI_IO_ACCESSORS
 	help
 	  This selects the OF support for Secure Digital Host Controller
-	  Interfaces. So far, only the Freescale eSDHC controller is known
-	  to exist on OF platforms.
+	  Interfaces.
+
+	  If unsure, say N.
+
+config MMC_SDHCI_OF_ESDHC
+	bool "SDHCI OF support for the Freescale eSDHC controller"
+	depends on MMC_SDHCI_OF
+	select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+	help
+	  This selects the Freescale eSDHC controller support.
+
+	  If unsure, say N.
+
+config MMC_SDHCI_OF_HLWD
+	bool "SDHCI OF support for the Nintendo Wii SDHCI controllers"
+	depends on MMC_SDHCI_OF
+	select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  found in the "Hollywood" chipset of the Nintendo Wii video game
+	  console.
 
 	  If unsure, say N.
 
@@ -251,6 +282,14 @@ config MMC_MVSDIO
 	  To compile this driver as a module, choose M here: the
 	  module will be called mvsdio.
 
+config MMC_DAVINCI
+        tristate "TI DAVINCI Multimedia Card Interface support"
+        depends on ARCH_DAVINCI
+        help
+          This selects the TI DAVINCI Multimedia card Interface.
+          If you have an DAVINCI board with a Multimedia Card slot,
+          say Y or M here.  If unsure, say N.
+
 config MMC_SPI
 	tristate "MMC/SD/SDIO over SPI"
 	depends on SPI_MASTER && !HIGHMEM && HAS_DMA
@@ -329,7 +368,7 @@ config MMC_SDRICOH_CS
 
 config MMC_TMIO
 	tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
-	depends on MFD_TMIO || MFD_ASIC3
+	depends on MFD_TMIO || MFD_ASIC3 || SUPERH
 	help
 	  This provides support for the SD/MMC cell found in TC6393XB,
 	  T7L66XB and also HTC ASIC3
@@ -357,3 +396,22 @@ config MMC_VIA_SDMMC
 	  If you have a controller with this interface, say Y or M here.
 
 	  If unsure, say N.
+
+config SDH_BFIN
+	tristate "Blackfin Secure Digital Host support"
+	depends on MMC && ((BF54x && !BF544) || (BF51x && !BF512))
+	help
+	  If you say yes here you will get support for the Blackfin on-chip
+	  Secure Digital Host interface.  This includes support for MMC and
+	  SD cards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin_sdh.
+
+	  If unsure, say N.
+
+config SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+	bool "Blackfin EZkit Missing SDH_CMD Pull Up Resistor Workaround"
+	depends on SDH_BFIN
+	help
+	  If you say yes here SD-Cards may work on the EZkit.
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/Makefile linux-libre-2.6.33-gnu1/drivers/mmc/host/Makefile
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,6 @@ obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_RICOH_MMC)	+= ricoh_mmc.o
-obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
 obj-$(CONFIG_MMC_SDHCI_PLTFM)	+= sdhci-pltfm.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
@@ -25,6 +24,7 @@ obj-$(CONFIG_MMC_ATMELMCI)	+= atmel-mci.
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
 obj-$(CONFIG_MMC_MSM7X00A)	+= msm_sdcc.o
 obj-$(CONFIG_MMC_MVSDIO)	+= mvsdio.o
+obj-$(CONFIG_MMC_DAVINCI)       += davinci_mmc.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_MMC_SPI)		+= of_mmc_spi.o
@@ -34,6 +34,12 @@ obj-$(CONFIG_MMC_SDRICOH_CS)	+= sdricoh_
 obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
 obj-$(CONFIG_MMC_CB710)	+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
+obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
+
+obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
+sdhci-of-y				:= sdhci-of-core.o
+sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
+sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD)	+= sdhci-of-hlwd.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/mmci.c linux-libre-2.6.33-gnu1/drivers/mmc/host/mmci.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/mmci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/mmci.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@ static void mmci_set_clkreg(struct mmci_
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
-		if (host->hw_designer == 0x80)
+		if (host->hw_designer == AMBA_VENDOR_ST)
 			clk |= MCI_FCEN; /* Bug fix in ST IP block */
 		clk |= MCI_CLK_ENABLE;
 		/* This hasn't proven to be worthwhile */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/msm_sdcc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/msm_sdcc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/msm_sdcc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/msm_sdcc.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,10 +38,9 @@
 #include <asm/div64.h>
 #include <asm/sizes.h>
 
-#include <asm/mach/mmc.h>
+#include <mach/mmc.h>
 #include <mach/msm_iomap.h>
 #include <mach/dma.h>
-#include <mach/htc_pwrsink.h>
 
 #include "msm_sdcc.h"
 
@@ -775,13 +774,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, st
 
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF:
-		htc_pwrsink_set(PWRSINK_SDCARD, 0);
 		break;
 	case MMC_POWER_UP:
 		pwr |= MCI_PWR_UP;
 		break;
 	case MMC_POWER_ON:
-		htc_pwrsink_set(PWRSINK_SDCARD, 100);
 		pwr |= MCI_PWR_ON;
 		break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/mxcmmc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/mxcmmc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/mxcmmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/mxcmmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -679,17 +679,17 @@ static int mxcmci_probe(struct platform_
 {
 	struct mmc_host *mmc;
 	struct mxcmci_host *host = NULL;
-	struct resource *r;
+	struct resource *iores, *r;
 	int ret = 0, irq;
 
 	printk(KERN_INFO "i.MX SDHC driver\n");
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	if (!r || irq < 0)
+	if (!iores || irq < 0)
 		return -EINVAL;
 
-	r = request_mem_region(r->start, resource_size(r), pdev->name);
+	r = request_mem_region(iores->start, resource_size(iores), pdev->name);
 	if (!r)
 		return -EBUSY;
 
@@ -809,7 +809,7 @@ out_iounmap:
 out_free:
 	mmc_free_host(mmc);
 out_release_mem:
-	release_mem_region(host->res->start, resource_size(host->res));
+	release_mem_region(iores->start, resource_size(iores));
 	return ret;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/of_mmc_spi.c linux-libre-2.6.33-gnu1/drivers/mmc/host/of_mmc_spi.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/of_mmc_spi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/of_mmc_spi.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,8 @@
 #include <linux/mmc/core.h>
 #include <linux/mmc/host.h>
 
+MODULE_LICENSE("GPL");
+
 enum {
 	CD_GPIO = 0,
 	WP_GPIO,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/omap.c linux-libre-2.6.33-gnu1/drivers/mmc/host/omap.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/omap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/omap.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,12 +30,12 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include <mach/board.h>
-#include <mach/mmc.h>
+#include <plat/board.h>
+#include <plat/mmc.h>
 #include <mach/gpio.h>
-#include <mach/dma.h>
-#include <mach/mux.h>
-#include <mach/fpga.h>
+#include <plat/dma.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
 
 #define	OMAP_MMC_REG_CMD	0x00
 #define	OMAP_MMC_REG_ARGL	0x04
@@ -1459,8 +1459,10 @@ static int __init mmc_omap_probe(struct
 		goto err_ioremap;
 
 	host->iclk = clk_get(&pdev->dev, "ick");
-	if (IS_ERR(host->iclk))
+	if (IS_ERR(host->iclk)) {
+		ret = PTR_ERR(host->iclk);
 		goto err_free_mmc_host;
+	}
 	clk_enable(host->iclk);
 
 	host->fclk = clk_get(&pdev->dev, "fck");
@@ -1500,10 +1502,8 @@ err_free_irq:
 err_free_fclk:
 	clk_put(host->fclk);
 err_free_iclk:
-	if (host->iclk != NULL) {
-		clk_disable(host->iclk);
-		clk_put(host->iclk);
-	}
+	clk_disable(host->iclk);
+	clk_put(host->iclk);
 err_free_mmc_host:
 	iounmap(host->virt_base);
 err_ioremap:
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/omap_hsmmc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/omap_hsmmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/omap_hsmmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,11 +30,11 @@
 #include <linux/mmc/core.h>
 #include <linux/io.h>
 #include <linux/semaphore.h>
-#include <mach/dma.h>
+#include <plat/dma.h>
 #include <mach/hardware.h>
-#include <mach/board.h>
-#include <mach/mmc.h>
-#include <mach/cpu.h>
+#include <plat/board.h>
+#include <plat/mmc.h>
+#include <plat/cpu.h>
 
 /* OMAP HSMMC Host Controller Registers */
 #define OMAP_HSMMC_SYSCONFIG	0x0010
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/pxamci.c linux-libre-2.6.33-gnu1/drivers/mmc/host/pxamci.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/pxamci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/pxamci.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,9 @@
 #define NR_SG	1
 #define CLKRT_OFF	(~0)
 
+#define mmc_has_26MHz()		(cpu_is_pxa300() || cpu_is_pxa310() \
+				|| cpu_is_pxa935())
+
 struct pxamci_host {
 	struct mmc_host		*mmc;
 	spinlock_t		lock;
@@ -457,7 +460,7 @@ static void pxamci_set_ios(struct mmc_ho
 			clk_enable(host->clk);
 
 		if (ios->clock == 26000000) {
-			/* to support 26MHz on pxa300/pxa310 */
+			/* to support 26MHz */
 			host->clkrt = 7;
 		} else {
 			/* to handle (19.5MHz, 26MHz) */
@@ -608,8 +611,7 @@ static int pxamci_probe(struct platform_
 	 * Calculate minimum clock rate, rounding up.
 	 */
 	mmc->f_min = (host->clkrate + 63) / 64;
-	mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
-							  : host->clkrate;
+	mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate;
 
 	pxamci_init_ocr(host);
 
@@ -618,7 +620,7 @@ static int pxamci_probe(struct platform_
 	if (!cpu_is_pxa25x()) {
 		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
 		host->cmdat |= CMDAT_SDIO_INT_EN;
-		if (cpu_is_pxa300() || cpu_is_pxa310())
+		if (mmc_has_26MHz())
 			mmc->caps |= MMC_CAP_MMC_HIGHSPEED |
 				     MMC_CAP_SD_HIGHSPEED;
 	}
@@ -826,7 +828,7 @@ static int pxamci_resume(struct device *
 	return ret;
 }
 
-static struct dev_pm_ops pxamci_pm_ops = {
+static const struct dev_pm_ops pxamci_pm_ops = {
 	.suspend	= pxamci_suspend,
 	.resume		= pxamci_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/s3cmci.c linux-libre-2.6.33-gnu1/drivers/mmc/host/s3cmci.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/s3cmci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/s3cmci.c	2010-02-24 13:52:17.000000000 -0500
@@ -820,7 +820,7 @@ fail_request:
 static void finalize_request(struct s3cmci_host *host)
 {
 	struct mmc_request *mrq = host->mrq;
-	struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
+	struct mmc_command *cmd;
 	int debug_as_failure = 0;
 
 	if (host->complete_what != COMPLETION_FINALIZE)
@@ -828,6 +828,7 @@ static void finalize_request(struct s3cm
 
 	if (!mrq)
 		return;
+	cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 
 	if (cmd->data && (cmd->error == 0) &&
 	    (cmd->data->error == 0)) {
@@ -1302,10 +1303,8 @@ static int s3cmci_get_ro(struct mmc_host
 	if (pdata->no_wprotect)
 		return 0;
 
-	ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);
-
-	if (pdata->wprotect_invert)
-		ret = !ret;
+	ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
+	ret ^= pdata->wprotect_invert;
 
 	return ret;
 }
@@ -1360,7 +1359,7 @@ static struct mmc_host_ops s3cmci_ops =
 
 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
 	/* This is currently here to avoid a number of if (host->pdata)
-	 * checks. Any zero fields to ensure reaonable defaults are picked. */
+	 * checks. Any zero fields to ensure reasonable defaults are picked. */
 };
 
 #ifdef CONFIG_CPU_FREQ
@@ -1654,7 +1653,7 @@ static int __devinit s3cmci_probe(struct
 			goto probe_free_irq;
 		}
 
-		host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
+		host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
 
 		if (host->irq_cd >= 0) {
 			if (request_irq(host->irq_cd, s3cmci_irq_cd,
@@ -1892,7 +1891,7 @@ static int s3cmci_resume(struct device *
 	return mmc_resume_host(mmc);
 }
 
-static struct dev_pm_ops s3cmci_pm = {
+static const struct dev_pm_ops s3cmci_pm = {
 	.suspend	= s3cmci_suspend,
 	.resume		= s3cmci_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci.h linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci.h
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,6 +8,8 @@
  * the Free Software Foundation; either version 2 of the License, or (at
  * your option) any later version.
  */
+#ifndef __SDHCI_H
+#define __SDHCI_H
 
 #include <linux/scatterlist.h>
 #include <linux/compiler.h>
@@ -408,3 +410,5 @@ extern void sdhci_remove_host(struct sdh
 extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
 extern int sdhci_resume_host(struct sdhci_host *host);
 #endif
+
+#endif /* __SDHCI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of.c linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,336 +0,0 @@
-/*
- * OpenFirmware bindings for Secure Digital Host Controller Interface.
- *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
- * Copyright (c) 2009 MontaVista Software, Inc.
- *
- * Authors: Xiaobo Xie <X.Xie@freescale.com>
- *	    Anton Vorontsov <avorontsov@ru.mvista.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/module.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/mmc/host.h>
-#include <asm/machdep.h>
-#include "sdhci.h"
-
-struct sdhci_of_data {
-	unsigned int quirks;
-	struct sdhci_ops ops;
-};
-
-struct sdhci_of_host {
-	unsigned int clock;
-	u16 xfer_mode_shadow;
-};
-
-/*
- * Ops and quirks for the Freescale eSDHC controller.
- */
-
-#define ESDHC_DMA_SYSCTL	0x40c
-#define ESDHC_DMA_SNOOP		0x00000040
-
-#define ESDHC_SYSTEM_CONTROL	0x2c
-#define ESDHC_CLOCK_MASK	0x0000fff0
-#define ESDHC_PREDIV_SHIFT	8
-#define ESDHC_DIVIDER_SHIFT	4
-#define ESDHC_CLOCK_PEREN	0x00000004
-#define ESDHC_CLOCK_HCKEN	0x00000002
-#define ESDHC_CLOCK_IPGEN	0x00000001
-
-#define ESDHC_HOST_CONTROL_RES	0x05
-
-static u32 esdhc_readl(struct sdhci_host *host, int reg)
-{
-	return in_be32(host->ioaddr + reg);
-}
-
-static u16 esdhc_readw(struct sdhci_host *host, int reg)
-{
-	u16 ret;
-
-	if (unlikely(reg == SDHCI_HOST_VERSION))
-		ret = in_be16(host->ioaddr + reg);
-	else
-		ret = in_be16(host->ioaddr + (reg ^ 0x2));
-	return ret;
-}
-
-static u8 esdhc_readb(struct sdhci_host *host, int reg)
-{
-	return in_8(host->ioaddr + (reg ^ 0x3));
-}
-
-static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
-{
-	out_be32(host->ioaddr + reg, val);
-}
-
-static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
-{
-	struct sdhci_of_host *of_host = sdhci_priv(host);
-	int base = reg & ~0x3;
-	int shift = (reg & 0x2) * 8;
-
-	switch (reg) {
-	case SDHCI_TRANSFER_MODE:
-		/*
-		 * Postpone this write, we must do it together with a
-		 * command write that is down below.
-		 */
-		of_host->xfer_mode_shadow = val;
-		return;
-	case SDHCI_COMMAND:
-		esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
-			     SDHCI_TRANSFER_MODE);
-		return;
-	case SDHCI_BLOCK_SIZE:
-		/*
-		 * Two last DMA bits are reserved, and first one is used for
-		 * non-standard blksz of 4096 bytes that we don't support
-		 * yet. So clear the DMA boundary bits.
-		 */
-		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
-		/* fall through */
-	}
-	clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
-}
-
-static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
-{
-	int base = reg & ~0x3;
-	int shift = (reg & 0x3) * 8;
-
-	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
-	if (reg == SDHCI_HOST_CONTROL)
-		val &= ~ESDHC_HOST_CONTROL_RES;
-
-	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
-}
-
-static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
-{
-	int pre_div = 2;
-	int div = 1;
-
-	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
-		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
-
-	if (clock == 0)
-		goto out;
-
-	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
-		pre_div *= 2;
-
-	while (host->max_clk / 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);
-
-	pre_div >>= 1;
-	div--;
-
-	setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
-		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
-		  div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
-	mdelay(100);
-out:
-	host->clock = clock;
-}
-
-static int esdhc_enable_dma(struct sdhci_host *host)
-{
-	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
-	return 0;
-}
-
-static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
-{
-	struct sdhci_of_host *of_host = sdhci_priv(host);
-
-	return of_host->clock;
-}
-
-static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
-{
-	struct sdhci_of_host *of_host = sdhci_priv(host);
-
-	return of_host->clock / 256 / 16;
-}
-
-static struct sdhci_of_data sdhci_esdhc = {
-	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
-		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
-		  SDHCI_QUIRK_NO_BUSY_IRQ |
-		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
-		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
-		  SDHCI_QUIRK_PIO_NEEDS_DELAY |
-		  SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
-		  SDHCI_QUIRK_NO_CARD_NO_RESET,
-	.ops = {
-		.readl = esdhc_readl,
-		.readw = esdhc_readw,
-		.readb = esdhc_readb,
-		.writel = esdhc_writel,
-		.writew = esdhc_writew,
-		.writeb = esdhc_writeb,
-		.set_clock = esdhc_set_clock,
-		.enable_dma = esdhc_enable_dma,
-		.get_max_clock = esdhc_get_max_clock,
-		.get_min_clock = esdhc_get_min_clock,
-	},
-};
-
-#ifdef CONFIG_PM
-
-static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
-{
-	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
-	return mmc_suspend_host(host->mmc, state);
-}
-
-static int sdhci_of_resume(struct of_device *ofdev)
-{
-	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
-	return mmc_resume_host(host->mmc);
-}
-
-#else
-
-#define sdhci_of_suspend NULL
-#define sdhci_of_resume NULL
-
-#endif
-
-static bool __devinit sdhci_of_wp_inverted(struct device_node *np)
-{
-	if (of_get_property(np, "sdhci,wp-inverted", NULL))
-		return true;
-
-	/* Old device trees don't have the wp-inverted property. */
-	return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
-}
-
-static int __devinit sdhci_of_probe(struct of_device *ofdev,
-				 const struct of_device_id *match)
-{
-	struct device_node *np = ofdev->node;
-	struct sdhci_of_data *sdhci_of_data = match->data;
-	struct sdhci_host *host;
-	struct sdhci_of_host *of_host;
-	const u32 *clk;
-	int size;
-	int ret;
-
-	if (!of_device_is_available(np))
-		return -ENODEV;
-
-	host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
-	if (IS_ERR(host))
-		return -ENOMEM;
-
-	of_host = sdhci_priv(host);
-	dev_set_drvdata(&ofdev->dev, host);
-
-	host->ioaddr = of_iomap(np, 0);
-	if (!host->ioaddr) {
-		ret = -ENOMEM;
-		goto err_addr_map;
-	}
-
-	host->irq = irq_of_parse_and_map(np, 0);
-	if (!host->irq) {
-		ret = -EINVAL;
-		goto err_no_irq;
-	}
-
-	host->hw_name = dev_name(&ofdev->dev);
-	if (sdhci_of_data) {
-		host->quirks = sdhci_of_data->quirks;
-		host->ops = &sdhci_of_data->ops;
-	}
-
-	if (of_get_property(np, "sdhci,1-bit-only", NULL))
-		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
-
-	if (sdhci_of_wp_inverted(np))
-		host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
-
-	clk = of_get_property(np, "clock-frequency", &size);
-	if (clk && size == sizeof(*clk) && *clk)
-		of_host->clock = *clk;
-
-	ret = sdhci_add_host(host);
-	if (ret)
-		goto err_add_host;
-
-	return 0;
-
-err_add_host:
-	irq_dispose_mapping(host->irq);
-err_no_irq:
-	iounmap(host->ioaddr);
-err_addr_map:
-	sdhci_free_host(host);
-	return ret;
-}
-
-static int __devexit sdhci_of_remove(struct of_device *ofdev)
-{
-	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
-
-	sdhci_remove_host(host, 0);
-	sdhci_free_host(host);
-	irq_dispose_mapping(host->irq);
-	iounmap(host->ioaddr);
-	return 0;
-}
-
-static const struct of_device_id sdhci_of_match[] = {
-	{ .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
-	{ .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
-	{ .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
-	{ .compatible = "generic-sdhci", },
-	{},
-};
-MODULE_DEVICE_TABLE(of, sdhci_of_match);
-
-static struct of_platform_driver sdhci_of_driver = {
-	.driver.name = "sdhci-of",
-	.match_table = sdhci_of_match,
-	.probe = sdhci_of_probe,
-	.remove = __devexit_p(sdhci_of_remove),
-	.suspend = sdhci_of_suspend,
-	.resume	= sdhci_of_resume,
-};
-
-static int __init sdhci_of_init(void)
-{
-	return of_register_platform_driver(&sdhci_of_driver);
-}
-module_init(sdhci_of_init);
-
-static void __exit sdhci_of_exit(void)
-{
-	of_unregister_platform_driver(&sdhci_of_driver);
-}
-module_exit(sdhci_of_exit);
-
-MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
-MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
-	      "Anton Vorontsov <avorontsov@ru.mvista.com>");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-core.c linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-core.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,231 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mmc/host.h>
+#include <asm/machdep.h>
+#include "sdhci-of.h"
+#include "sdhci.h"
+
+#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
+
+/*
+ * These accessors are designed for big endian hosts doing I/O to
+ * little endian controllers incorporating a 32-bit hardware byte swapper.
+ */
+
+u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg)
+{
+	return in_be32(host->ioaddr + reg);
+}
+
+u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg)
+{
+	return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg)
+{
+	return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	out_be32(host->ioaddr + reg, val);
+}
+
+void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+	int base = reg & ~0x3;
+	int shift = (reg & 0x2) * 8;
+
+	switch (reg) {
+	case SDHCI_TRANSFER_MODE:
+		/*
+		 * Postpone this write, we must do it together with a
+		 * command write that is down below.
+		 */
+		of_host->xfer_mode_shadow = val;
+		return;
+	case SDHCI_COMMAND:
+		sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow,
+				    SDHCI_TRANSFER_MODE);
+		return;
+	}
+	clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	int base = reg & ~0x3;
+	int shift = (reg & 0x3) * 8;
+
+	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */
+
+#ifdef CONFIG_PM
+
+static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	return mmc_suspend_host(host->mmc, state);
+}
+
+static int sdhci_of_resume(struct of_device *ofdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	return mmc_resume_host(host->mmc);
+}
+
+#else
+
+#define sdhci_of_suspend NULL
+#define sdhci_of_resume NULL
+
+#endif
+
+static bool __devinit sdhci_of_wp_inverted(struct device_node *np)
+{
+	if (of_get_property(np, "sdhci,wp-inverted", NULL))
+		return true;
+
+	/* Old device trees don't have the wp-inverted property. */
+	return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
+}
+
+static int __devinit sdhci_of_probe(struct of_device *ofdev,
+				 const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct sdhci_of_data *sdhci_of_data = match->data;
+	struct sdhci_host *host;
+	struct sdhci_of_host *of_host;
+	const u32 *clk;
+	int size;
+	int ret;
+
+	if (!of_device_is_available(np))
+		return -ENODEV;
+
+	host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+	if (IS_ERR(host))
+		return -ENOMEM;
+
+	of_host = sdhci_priv(host);
+	dev_set_drvdata(&ofdev->dev, host);
+
+	host->ioaddr = of_iomap(np, 0);
+	if (!host->ioaddr) {
+		ret = -ENOMEM;
+		goto err_addr_map;
+	}
+
+	host->irq = irq_of_parse_and_map(np, 0);
+	if (!host->irq) {
+		ret = -EINVAL;
+		goto err_no_irq;
+	}
+
+	host->hw_name = dev_name(&ofdev->dev);
+	if (sdhci_of_data) {
+		host->quirks = sdhci_of_data->quirks;
+		host->ops = &sdhci_of_data->ops;
+	}
+
+	if (of_get_property(np, "sdhci,1-bit-only", NULL))
+		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
+
+	if (sdhci_of_wp_inverted(np))
+		host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+
+	clk = of_get_property(np, "clock-frequency", &size);
+	if (clk && size == sizeof(*clk) && *clk)
+		of_host->clock = *clk;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_add_host;
+
+	return 0;
+
+err_add_host:
+	irq_dispose_mapping(host->irq);
+err_no_irq:
+	iounmap(host->ioaddr);
+err_addr_map:
+	sdhci_free_host(host);
+	return ret;
+}
+
+static int __devexit sdhci_of_remove(struct of_device *ofdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	sdhci_remove_host(host, 0);
+	sdhci_free_host(host);
+	irq_dispose_mapping(host->irq);
+	iounmap(host->ioaddr);
+	return 0;
+}
+
+static const struct of_device_id sdhci_of_match[] = {
+#ifdef CONFIG_MMC_SDHCI_OF_ESDHC
+	{ .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
+	{ .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
+	{ .compatible = "fsl,esdhc", .data = &sdhci_esdhc, },
+#endif
+#ifdef CONFIG_MMC_SDHCI_OF_HLWD
+	{ .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, },
+#endif
+	{ .compatible = "generic-sdhci", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sdhci_of_match);
+
+static struct of_platform_driver sdhci_of_driver = {
+	.driver.name = "sdhci-of",
+	.match_table = sdhci_of_match,
+	.probe = sdhci_of_probe,
+	.remove = __devexit_p(sdhci_of_remove),
+	.suspend = sdhci_of_suspend,
+	.resume	= sdhci_of_resume,
+};
+
+static int __init sdhci_of_init(void)
+{
+	return of_register_platform_driver(&sdhci_of_driver);
+}
+module_init(sdhci_of_init);
+
+static void __exit sdhci_of_exit(void)
+{
+	of_unregister_platform_driver(&sdhci_of_driver);
+}
+module_exit(sdhci_of_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+	      "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-esdhc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-esdhc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-esdhc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-esdhc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,143 @@
+/*
+ * Freescale eSDHC controller driver.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.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/io.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include "sdhci-of.h"
+#include "sdhci.h"
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DMA_SYSCTL	0x40c
+#define ESDHC_DMA_SNOOP		0x00000040
+
+#define ESDHC_SYSTEM_CONTROL	0x2c
+#define ESDHC_CLOCK_MASK	0x0000fff0
+#define ESDHC_PREDIV_SHIFT	8
+#define ESDHC_DIVIDER_SHIFT	4
+#define ESDHC_CLOCK_PEREN	0x00000004
+#define ESDHC_CLOCK_HCKEN	0x00000002
+#define ESDHC_CLOCK_IPGEN	0x00000001
+
+#define ESDHC_HOST_CONTROL_RES	0x05
+
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+	u16 ret;
+
+	if (unlikely(reg == SDHCI_HOST_VERSION))
+		ret = in_be16(host->ioaddr + reg);
+	else
+		ret = sdhci_be32bs_readw(host, reg);
+	return ret;
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	if (reg == SDHCI_BLOCK_SIZE) {
+		/*
+		 * Two last DMA bits are reserved, and first one is used for
+		 * non-standard blksz of 4096 bytes that we don't support
+		 * yet. So clear the DMA boundary bits.
+		 */
+		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+	}
+	sdhci_be32bs_writew(host, val, reg);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
+	if (reg == SDHCI_HOST_CONTROL)
+		val &= ~ESDHC_HOST_CONTROL_RES;
+	sdhci_be32bs_writeb(host, val, reg);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	int pre_div = 2;
+	int div = 1;
+
+	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+	if (clock == 0)
+		goto out;
+
+	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
+		pre_div *= 2;
+
+	while (host->max_clk / 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);
+
+	pre_div >>= 1;
+	div--;
+
+	setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
+		  div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
+	mdelay(100);
+out:
+	host->clock = clock;
+}
+
+static int esdhc_enable_dma(struct sdhci_host *host)
+{
+	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+	return 0;
+}
+
+static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+
+	return of_host->clock;
+}
+
+static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+
+	return of_host->clock / 256 / 16;
+}
+
+struct sdhci_of_data sdhci_esdhc = {
+	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_NO_BUSY_IRQ |
+		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		  SDHCI_QUIRK_PIO_NEEDS_DELAY |
+		  SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
+		  SDHCI_QUIRK_NO_CARD_NO_RESET,
+	.ops = {
+		.readl = sdhci_be32bs_readl,
+		.readw = esdhc_readw,
+		.readb = sdhci_be32bs_readb,
+		.writel = sdhci_be32bs_writel,
+		.writew = esdhc_writew,
+		.writeb = esdhc_writeb,
+		.set_clock = esdhc_set_clock,
+		.enable_dma = esdhc_enable_dma,
+		.get_max_clock = esdhc_get_max_clock,
+		.get_min_clock = esdhc_get_min_clock,
+	},
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of.h linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of.h
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,42 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.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 __SDHCI_OF_H
+#define __SDHCI_OF_H
+
+#include <linux/types.h>
+#include "sdhci.h"
+
+struct sdhci_of_data {
+	unsigned int quirks;
+	struct sdhci_ops ops;
+};
+
+struct sdhci_of_host {
+	unsigned int clock;
+	u16 xfer_mode_shadow;
+};
+
+extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg);
+extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg);
+extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg);
+extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg);
+extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg);
+extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg);
+
+extern struct sdhci_of_data sdhci_esdhc;
+extern struct sdhci_of_data sdhci_hlwd;
+
+#endif /* __SDHCI_OF_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-hlwd.c linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-hlwd.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-of-hlwd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-of-hlwd.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,65 @@
+/*
+ * drivers/mmc/host/sdhci-of-hlwd.c
+ *
+ * Nintendo Wii Secure Digital Host Controller Interface.
+ * Copyright (C) 2009 The GameCube Linux Team
+ * Copyright (C) 2009 Albert Herranz
+ *
+ * Based on sdhci-of-esdhc.c
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.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/delay.h>
+#include <linux/mmc/host.h>
+#include "sdhci-of.h"
+#include "sdhci.h"
+
+/*
+ * Ops and quirks for the Nintendo Wii SDHCI controllers.
+ */
+
+/*
+ * We need a small delay after each write, or things go horribly wrong.
+ */
+#define SDHCI_HLWD_WRITE_DELAY	5 /* usecs */
+
+static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	sdhci_be32bs_writel(host, val, reg);
+	udelay(SDHCI_HLWD_WRITE_DELAY);
+}
+
+static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	sdhci_be32bs_writew(host, val, reg);
+	udelay(SDHCI_HLWD_WRITE_DELAY);
+}
+
+static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	sdhci_be32bs_writeb(host, val, reg);
+	udelay(SDHCI_HLWD_WRITE_DELAY);
+}
+
+struct sdhci_of_data sdhci_hlwd = {
+	.quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
+		  SDHCI_QUIRK_32BIT_DMA_SIZE,
+	.ops = {
+		.readl = sdhci_be32bs_readl,
+		.readw = sdhci_be32bs_readw,
+		.readb = sdhci_be32bs_readb,
+		.writel = sdhci_hlwd_writel,
+		.writew = sdhci_hlwd_writew,
+		.writeb = sdhci_hlwd_writeb,
+	},
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-pci.c linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-pci.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/sdhci-pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/sdhci-pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -285,6 +285,73 @@ static const struct sdhci_pci_fixes sdhc
 	.resume		= jmicron_resume,
 };
 
+/* SysKonnect CardBus2SDIO extra registers */
+#define SYSKT_CTRL		0x200
+#define SYSKT_RDFIFO_STAT	0x204
+#define SYSKT_WRFIFO_STAT	0x208
+#define SYSKT_POWER_DATA	0x20c
+#define   SYSKT_POWER_330	0xef
+#define   SYSKT_POWER_300	0xf8
+#define   SYSKT_POWER_184	0xcc
+#define SYSKT_POWER_CMD		0x20d
+#define   SYSKT_POWER_START	(1 << 7)
+#define SYSKT_POWER_STATUS	0x20e
+#define   SYSKT_POWER_STATUS_OK	(1 << 0)
+#define SYSKT_BOARD_REV		0x210
+#define SYSKT_CHIP_REV		0x211
+#define SYSKT_CONF_DATA		0x212
+#define   SYSKT_CONF_DATA_1V8	(1 << 2)
+#define   SYSKT_CONF_DATA_2V5	(1 << 1)
+#define   SYSKT_CONF_DATA_3V3	(1 << 0)
+
+static int syskt_probe(struct sdhci_pci_chip *chip)
+{
+	if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
+		chip->pdev->class &= ~0x0000FF;
+		chip->pdev->class |= PCI_SDHCI_IFDMA;
+	}
+	return 0;
+}
+
+static int syskt_probe_slot(struct sdhci_pci_slot *slot)
+{
+	int tm, ps;
+
+	u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV);
+	u8  chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV);
+	dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, "
+					 "board rev %d.%d, chip rev %d.%d\n",
+					 board_rev >> 4, board_rev & 0xf,
+					 chip_rev >> 4,  chip_rev & 0xf);
+	if (chip_rev >= 0x20)
+		slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA;
+
+	writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA);
+	writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD);
+	udelay(50);
+	tm = 10;  /* Wait max 1 ms */
+	do {
+		ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS);
+		if (ps & SYSKT_POWER_STATUS_OK)
+			break;
+		udelay(100);
+	} while (--tm);
+	if (!tm) {
+		dev_err(&slot->chip->pdev->dev,
+			"power regulator never stabilized");
+		writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_syskt = {
+	.quirks		= SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
+	.probe		= syskt_probe,
+	.probe_slot	= syskt_probe_slot,
+};
+
 static int via_probe(struct sdhci_pci_chip *chip)
 {
 	if (chip->pdev->revision == 0x10)
@@ -363,6 +430,14 @@ static const struct pci_device_id pci_id
 	},
 
 	{
+		.vendor		= PCI_VENDOR_ID_SYSKONNECT,
+		.device		= 0x8000,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_syskt,
+	},
+
+	{
 		.vendor		= PCI_VENDOR_ID_VIA,
 		.device		= 0x95d0,
 		.subvendor	= PCI_ANY_ID,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/tmio_mmc.c linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.c
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/tmio_mmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,9 @@ static void tmio_mmc_set_clock(struct tm
 		clk |= 0x100;
 	}
 
-	sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22);
+	if (host->set_clk_div)
+		host->set_clk_div(host->pdev, (clk>>22) & 1);
+
 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
 }
 
@@ -427,12 +429,13 @@ static void tmio_mmc_set_ios(struct mmc_
 	/* Power sequence - OFF -> ON -> UP */
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF: /* power down SD bus */
-		sd_config_write8(host, CNF_PWR_CTL_2, 0x00);
+		if (host->set_pwr)
+			host->set_pwr(host->pdev, 0);
 		tmio_mmc_clk_stop(host);
 		break;
 	case MMC_POWER_ON: /* power up SD bus */
-
-		sd_config_write8(host, CNF_PWR_CTL_2, 0x02);
+		if (host->set_pwr)
+			host->set_pwr(host->pdev, 1);
 		break;
 	case MMC_POWER_UP: /* start bus clock */
 		tmio_mmc_clk_start(host);
@@ -485,21 +488,15 @@ static int tmio_mmc_resume(struct platfo
 {
 	struct mfd_cell	*cell = (struct mfd_cell *)dev->dev.platform_data;
 	struct mmc_host *mmc = platform_get_drvdata(dev);
-	struct tmio_mmc_host *host = mmc_priv(mmc);
 	int ret = 0;
 
 	/* Tell the MFD core we are ready to be enabled */
-	if (cell->enable) {
-		ret = cell->enable(dev);
+	if (cell->resume) {
+		ret = cell->resume(dev);
 		if (ret)
 			goto out;
 	}
 
-	/* Enable the MMC/SD Control registers */
-	sd_config_write16(host, CNF_CMD, SDCREN);
-	sd_config_write32(host, CNF_CTL_BASE,
-		(dev->resource[0].start >> host->bus_shift) & 0xfffe);
-
 	mmc_resume_host(mmc);
 
 out:
@@ -514,17 +511,16 @@ static int __devinit tmio_mmc_probe(stru
 {
 	struct mfd_cell	*cell = (struct mfd_cell *)dev->dev.platform_data;
 	struct tmio_mmc_data *pdata;
-	struct resource *res_ctl, *res_cnf;
+	struct resource *res_ctl;
 	struct tmio_mmc_host *host;
 	struct mmc_host *mmc;
 	int ret = -EINVAL;
 
-	if (dev->num_resources != 3)
+	if (dev->num_resources != 2)
 		goto out;
 
 	res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1);
-	if (!res_ctl || !res_cnf)
+	if (!res_ctl)
 		goto out;
 
 	pdata = cell->driver_data;
@@ -539,8 +535,12 @@ static int __devinit tmio_mmc_probe(stru
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
+	host->pdev = dev;
 	platform_set_drvdata(dev, mmc);
 
+	host->set_pwr = pdata->set_pwr;
+	host->set_clk_div = pdata->set_clk_div;
+
 	/* SD control register space size is 0x200, 0x400 for bus_shift=1 */
 	host->bus_shift = resource_size(res_ctl) >> 10;
 
@@ -548,10 +548,6 @@ static int __devinit tmio_mmc_probe(stru
 	if (!host->ctl)
 		goto host_free;
 
-	host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
-	if (!host->cnf)
-		goto unmap_ctl;
-
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA;
 	mmc->f_max = pdata->hclk;
@@ -562,23 +558,9 @@ static int __devinit tmio_mmc_probe(stru
 	if (cell->enable) {
 		ret = cell->enable(dev);
 		if (ret)
-			goto unmap_cnf;
+			goto unmap_ctl;
 	}
 
-	/* Enable the MMC/SD Control registers */
-	sd_config_write16(host, CNF_CMD, SDCREN);
-	sd_config_write32(host, CNF_CTL_BASE,
-		(dev->resource[0].start >> host->bus_shift) & 0xfffe);
-
-	/* Disable SD power during suspend */
-	sd_config_write8(host, CNF_PWR_CTL_3, 0x01);
-
-	/* The below is required but why? FIXME */
-	sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f);
-
-	/* Power down SD bus*/
-	sd_config_write8(host, CNF_PWR_CTL_2, 0x00);
-
 	tmio_mmc_clk_stop(host);
 	reset(host);
 
@@ -586,14 +568,14 @@ static int __devinit tmio_mmc_probe(stru
 	if (ret >= 0)
 		host->irq = ret;
 	else
-		goto unmap_cnf;
+		goto unmap_ctl;
 
 	disable_mmc_irqs(host, TMIO_MASK_ALL);
 
 	ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
-		IRQF_TRIGGER_FALLING, "tmio-mmc", host);
+		IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host);
 	if (ret)
-		goto unmap_cnf;
+		goto unmap_ctl;
 
 	mmc_add_host(mmc);
 
@@ -605,8 +587,6 @@ static int __devinit tmio_mmc_probe(stru
 
 	return 0;
 
-unmap_cnf:
-	iounmap(host->cnf);
 unmap_ctl:
 	iounmap(host->ctl);
 host_free:
@@ -626,7 +606,6 @@ static int __devexit tmio_mmc_remove(str
 		mmc_remove_host(mmc);
 		free_irq(host->irq, host);
 		iounmap(host->ctl);
-		iounmap(host->cnf);
 		mmc_free_host(mmc);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mmc/host/tmio_mmc.h linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.h
--- linux-libre-2.6.32-gnu1/drivers/mmc/host/tmio_mmc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mmc/host/tmio_mmc.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,26 +11,6 @@
 
 #include <linux/highmem.h>
 
-#define CNF_CMD     0x04
-#define CNF_CTL_BASE   0x10
-#define CNF_INT_PIN  0x3d
-#define CNF_STOP_CLK_CTL 0x40
-#define CNF_GCLK_CTL 0x41
-#define CNF_SD_CLK_MODE 0x42
-#define CNF_PIN_STATUS 0x44
-#define CNF_PWR_CTL_1 0x48
-#define CNF_PWR_CTL_2 0x49
-#define CNF_PWR_CTL_3 0x4a
-#define CNF_CARD_DETECT_MODE 0x4c
-#define CNF_SD_SLOT 0x50
-#define CNF_EXT_GCLK_CTL_1 0xf0
-#define CNF_EXT_GCLK_CTL_2 0xf1
-#define CNF_EXT_GCLK_CTL_3 0xf9
-#define CNF_SD_LED_EN_1 0xfa
-#define CNF_SD_LED_EN_2 0xfe
-
-#define   SDCREN 0x2   /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
-
 #define CTL_SD_CMD 0x00
 #define CTL_ARG_REG 0x04
 #define CTL_STOP_INTERNAL_ACTION 0x08
@@ -110,7 +90,6 @@
 
 
 struct tmio_mmc_host {
-	void __iomem *cnf;
 	void __iomem *ctl;
 	unsigned long bus_shift;
 	struct mmc_command      *cmd;
@@ -119,10 +98,16 @@ struct tmio_mmc_host {
 	struct mmc_host         *mmc;
 	int                     irq;
 
+	/* Callbacks for clock / power control */
+	void (*set_pwr)(struct platform_device *host, int state);
+	void (*set_clk_div)(struct platform_device *host, int state);
+
 	/* pio related stuff */
 	struct scatterlist      *sg_ptr;
 	unsigned int            sg_len;
 	unsigned int            sg_off;
+
+	struct platform_device *pdev;
 };
 
 #include <linux/io.h>
@@ -163,25 +148,6 @@ static inline void sd_ctrl_write32(struc
 	writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
 }
 
-static inline void sd_config_write8(struct tmio_mmc_host *host, int addr,
-		u8 val)
-{
-	writeb(val, host->cnf + (addr << host->bus_shift));
-}
-
-static inline void sd_config_write16(struct tmio_mmc_host *host, int addr,
-		u16 val)
-{
-	writew(val, host->cnf + (addr << host->bus_shift));
-}
-
-static inline void sd_config_write32(struct tmio_mmc_host *host, int addr,
-		u32 val)
-{
-	writew(val, host->cnf + (addr << host->bus_shift));
-	writew(val >> 16, host->cnf + ((addr + 2) << host->bus_shift));
-}
-
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,15 +43,17 @@
 // debugging, turns off buffer write mode if set to 1
 #define FORCE_WORD_WRITE 0
 
-#define MANUFACTURER_INTEL	0x0089
+/* Intel chips */
 #define I82802AB	0x00ad
 #define I82802AC	0x00ac
 #define PF38F4476	0x881c
-#define MANUFACTURER_ST         0x0020
+/* STMicroelectronics chips */
 #define M50LPW080       0x002F
 #define M50FLW080A	0x0080
 #define M50FLW080B	0x0081
+/* Atmel chips */
 #define AT49BV640D	0x02de
+#define AT49BV640DT	0x02db
 
 static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -199,6 +201,16 @@ static void fixup_convert_atmel_pri(stru
 	cfi->cfiq->BufWriteTimeoutMax = 0;
 }
 
+static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
+
+	cfip->FeatureSupport |= (1 << 5);
+	mtd->flags |= MTD_POWERUP_LOCK;
+}
+
 #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
 /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
 static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
@@ -283,6 +295,8 @@ static void fixup_unlock_powerup_lock(st
 
 static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+	{ CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL },
+	{ CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL },
 #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
 #endif
@@ -294,16 +308,16 @@ static struct cfi_fixup cfi_fixup_table[
 #endif
 	{ CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL },
 	{ CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL },
-	{ MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, },
+	{ CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, },
 	{ 0, 0, NULL, NULL }
 };
 
 static struct cfi_fixup jedec_fixup_table[] = {
-	{ MANUFACTURER_INTEL, I82802AB,   fixup_use_fwh_lock, NULL, },
-	{ MANUFACTURER_INTEL, I82802AC,   fixup_use_fwh_lock, NULL, },
-	{ MANUFACTURER_ST,    M50LPW080,  fixup_use_fwh_lock, NULL, },
-	{ MANUFACTURER_ST,    M50FLW080A, fixup_use_fwh_lock, NULL, },
-	{ MANUFACTURER_ST,    M50FLW080B, fixup_use_fwh_lock, NULL, },
+	{ CFI_MFR_INTEL, I82802AB,   fixup_use_fwh_lock, NULL, },
+	{ CFI_MFR_INTEL, I82802AC,   fixup_use_fwh_lock, NULL, },
+	{ CFI_MFR_ST,    M50LPW080,  fixup_use_fwh_lock, NULL, },
+	{ CFI_MFR_ST,    M50FLW080A, fixup_use_fwh_lock, NULL, },
+	{ CFI_MFR_ST,    M50FLW080B, fixup_use_fwh_lock, NULL, },
 	{ 0, 0, NULL, NULL }
 };
 static struct cfi_fixup fixup_table[] = {
@@ -319,7 +333,7 @@ static struct cfi_fixup fixup_table[] =
 static void cfi_fixup_major_minor(struct cfi_private *cfi,
 						struct cfi_pri_intelext *extp)
 {
-	if (cfi->mfr == MANUFACTURER_INTEL &&
+	if (cfi->mfr == CFI_MFR_INTEL &&
 			cfi->id == PF38F4476 && extp->MinorVersion == '3')
 		extp->MinorVersion = '1';
 }
@@ -2235,7 +2249,7 @@ static int cfi_intelext_otp_walk(struct
 
 	/* Some chips have OTP located in the _top_ partition only.
 	   For example: Intel 28F256L18T (T means top-parameter device) */
-	if (cfi->mfr == MANUFACTURER_INTEL) {
+	if (cfi->mfr == CFI_MFR_INTEL) {
 		switch (cfi->id) {
 		case 0x880b:
 		case 0x880c:
@@ -2564,6 +2578,7 @@ static int cfi_intelext_reset(struct mtd
 		if (!ret) {
 			map_write(map, CMD(0xff), chip->start);
 			chip->state = FL_SHUTDOWN;
+			put_chip(map, chip, chip->start);
 		}
 		spin_unlock(chip->mutex);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c	2010-02-24 13:52:17.000000000 -0500
@@ -490,10 +490,6 @@ static struct mtd_info *cfi_amdstd_setup
 	}
 #endif
 
-	/* FIXME: erase-suspend-program is broken.  See
-	   http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
-	printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");
-
 	__module_get(THIS_MODULE);
 	return mtd;
 
@@ -573,7 +569,6 @@ static int get_chip(struct map_info *map
 
 			if (time_after(jiffies, timeo)) {
 				printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
-				spin_unlock(chip->mutex);
 				return -EIO;
 			}
 			spin_unlock(chip->mutex);
@@ -589,15 +584,9 @@ static int get_chip(struct map_info *map
 		return 0;
 
 	case FL_ERASING:
-		if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */
-			goto sleep;
-
-		if (!(   mode == FL_READY
-		      || mode == FL_POINT
-		      || !cfip
-		      || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))
-		      || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1)
-		    )))
+		if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
+		    !(mode == FL_READY || mode == FL_POINT ||
+		    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
 			goto sleep;
 
 		/* We could check to see if we're trying to access the sector
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_util.c linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_util.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/chips/cfi_util.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/chips/cfi_util.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,13 @@ int __xipram cfi_qry_mode_on(uint32_t ba
 	cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL);
 	if (cfi_qry_present(map, base, cfi))
 		return 1;
+	/* some old SST chips, e.g. 39VF160x/39VF320x */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
+	if (cfi_qry_present(map, base, cfi))
+		return 1;
 	/* QRY not found */
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/chips/jedec_probe.c linux-libre-2.6.33-gnu1/drivers/mtd/chips/jedec_probe.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/chips/jedec_probe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/chips/jedec_probe.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,8 +142,8 @@
 
 /* ST - www.st.com */
 #define M29F800AB	0x0058
-#define M29W800DT	0x00D7
-#define M29W800DB	0x005B
+#define M29W800DT	0x22D7
+#define M29W800DB	0x225B
 #define M29W400DT	0x00EE
 #define M29W400DB	0x00EF
 #define M29W160DT	0x22C4
@@ -1575,7 +1575,7 @@ static const struct amd_flash_info jedec
 		.dev_id		= M29W800DT,
 		.name		= "ST M29W800DT",
 		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
-		.uaddr		= MTD_UADDR_0x5555_0x2AAA,	/* ???? */
+		.uaddr		= MTD_UADDR_0x0AAA_0x0555,
 		.dev_size	= SIZE_1MiB,
 		.cmd_set	= P_ID_AMD_STD,
 		.nr_regions	= 4,
@@ -1590,7 +1590,7 @@ static const struct amd_flash_info jedec
 		.dev_id		= M29W800DB,
 		.name		= "ST M29W800DB",
 		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
-		.uaddr		= MTD_UADDR_0x5555_0x2AAA,	/* ???? */
+		.uaddr		= MTD_UADDR_0x0AAA_0x0555,
 		.dev_size	= SIZE_1MiB,
 		.cmd_set	= P_ID_AMD_STD,
 		.nr_regions	= 4,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/chips/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/chips/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/chips/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/chips/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/chips/Kconfig
-
 menu "RAM/ROM/Flash chip drivers"
 	depends on MTD!=n
 
@@ -242,4 +240,3 @@ config MTD_XIP
 	  then say N.
 
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/devices/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/devices/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/devices/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/devices/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/maps/Kconfig
-
 menu "Self-contained MTD device drivers"
 	depends on MTD!=n
 
@@ -308,4 +306,3 @@ config MTD_DOCPROBE_55AA
 	  you have managed to wipe the first block.
 
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/devices/m25p80.c linux-libre-2.6.33-gnu1/drivers/mtd/devices/m25p80.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/devices/m25p80.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/devices/m25p80.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/math64.h>
 #include <linux/sched.h>
+#include <linux/mod_devicetable.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -29,9 +30,6 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 
-
-#define FLASH_PAGESIZE		256
-
 /* Flash opcodes. */
 #define	OPCODE_WREN		0x06	/* Write enable */
 #define	OPCODE_RDSR		0x05	/* Read status register */
@@ -61,7 +59,7 @@
 
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
-#define	CMD_SIZE		4
+#define	MAX_CMD_SIZE		4
 
 #ifdef CONFIG_M25PXX_USE_FAST_READ
 #define OPCODE_READ 	OPCODE_FAST_READ
@@ -78,8 +76,10 @@ struct m25p {
 	struct mutex		lock;
 	struct mtd_info		mtd;
 	unsigned		partitioned:1;
+	u16			page_size;
+	u16			addr_width;
 	u8			erase_opcode;
-	u8			command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
+	u8			*command;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -198,6 +198,19 @@ static int erase_chip(struct m25p *flash
 	return 0;
 }
 
+static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
+{
+	/* opcode is in cmd[0] */
+	cmd[1] = addr >> (flash->addr_width * 8 -  8);
+	cmd[2] = addr >> (flash->addr_width * 8 - 16);
+	cmd[3] = addr >> (flash->addr_width * 8 - 24);
+}
+
+static int m25p_cmdsz(struct m25p *flash)
+{
+	return 1 + flash->addr_width;
+}
+
 /*
  * Erase one sector of flash memory at offset ``offset'' which is any
  * address within the sector which should be erased.
@@ -219,11 +232,9 @@ static int erase_sector(struct m25p *fla
 
 	/* Set up command buffer. */
 	flash->command[0] = flash->erase_opcode;
-	flash->command[1] = offset >> 16;
-	flash->command[2] = offset >> 8;
-	flash->command[3] = offset;
+	m25p_addr2cmd(flash, offset, flash->command);
 
-	spi_write(flash->spi, flash->command, CMD_SIZE);
+	spi_write(flash->spi, flash->command, m25p_cmdsz(flash));
 
 	return 0;
 }
@@ -325,7 +336,7 @@ static int m25p80_read(struct mtd_info *
 	 * Should add 1 byte DUMMY_BYTE.
 	 */
 	t[0].tx_buf = flash->command;
-	t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE;
+	t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
 	spi_message_add_tail(&t[0], &m);
 
 	t[1].rx_buf = buf;
@@ -352,13 +363,11 @@ static int m25p80_read(struct mtd_info *
 
 	/* Set up the write data buffer. */
 	flash->command[0] = OPCODE_READ;
-	flash->command[1] = from >> 16;
-	flash->command[2] = from >> 8;
-	flash->command[3] = from;
+	m25p_addr2cmd(flash, from, flash->command);
 
 	spi_sync(flash->spi, &m);
 
-	*retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE;
+	*retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE;
 
 	mutex_unlock(&flash->lock);
 
@@ -396,7 +405,7 @@ static int m25p80_write(struct mtd_info
 	memset(t, 0, (sizeof t));
 
 	t[0].tx_buf = flash->command;
-	t[0].len = CMD_SIZE;
+	t[0].len = m25p_cmdsz(flash);
 	spi_message_add_tail(&t[0], &m);
 
 	t[1].tx_buf = buf;
@@ -414,41 +423,36 @@ static int m25p80_write(struct mtd_info
 
 	/* Set up the opcode in the write buffer. */
 	flash->command[0] = OPCODE_PP;
-	flash->command[1] = to >> 16;
-	flash->command[2] = to >> 8;
-	flash->command[3] = to;
+	m25p_addr2cmd(flash, to, flash->command);
 
-	/* what page do we start with? */
-	page_offset = to % FLASH_PAGESIZE;
+	page_offset = to & (flash->page_size - 1);
 
 	/* do all the bytes fit onto one page? */
-	if (page_offset + len <= FLASH_PAGESIZE) {
+	if (page_offset + len <= flash->page_size) {
 		t[1].len = len;
 
 		spi_sync(flash->spi, &m);
 
-		*retlen = m.actual_length - CMD_SIZE;
+		*retlen = m.actual_length - m25p_cmdsz(flash);
 	} else {
 		u32 i;
 
 		/* the size of data remaining on the first page */
-		page_size = FLASH_PAGESIZE - page_offset;
+		page_size = flash->page_size - page_offset;
 
 		t[1].len = page_size;
 		spi_sync(flash->spi, &m);
 
-		*retlen = m.actual_length - CMD_SIZE;
+		*retlen = m.actual_length - m25p_cmdsz(flash);
 
-		/* write everything in PAGESIZE chunks */
+		/* write everything in flash->page_size chunks */
 		for (i = page_size; i < len; i += page_size) {
 			page_size = len - i;
-			if (page_size > FLASH_PAGESIZE)
-				page_size = FLASH_PAGESIZE;
+			if (page_size > flash->page_size)
+				page_size = flash->page_size;
 
 			/* write the next page to flash */
-			flash->command[1] = (to + i) >> 16;
-			flash->command[2] = (to + i) >> 8;
-			flash->command[3] = (to + i);
+			m25p_addr2cmd(flash, to + i, flash->command);
 
 			t[1].tx_buf = buf + i;
 			t[1].len = page_size;
@@ -460,7 +464,7 @@ static int m25p80_write(struct mtd_info
 			spi_sync(flash->spi, &m);
 
 			if (retlen)
-				*retlen += m.actual_length - CMD_SIZE;
+				*retlen += m.actual_length - m25p_cmdsz(flash);
 		}
 	}
 
@@ -492,7 +496,7 @@ static int sst_write(struct mtd_info *mt
 	memset(t, 0, (sizeof t));
 
 	t[0].tx_buf = flash->command;
-	t[0].len = CMD_SIZE;
+	t[0].len = m25p_cmdsz(flash);
 	spi_message_add_tail(&t[0], &m);
 
 	t[1].tx_buf = buf;
@@ -511,9 +515,7 @@ static int sst_write(struct mtd_info *mt
 	/* Start write from odd address. */
 	if (actual) {
 		flash->command[0] = OPCODE_BP;
-		flash->command[1] = to >> 16;
-		flash->command[2] = to >> 8;
-		flash->command[3] = to;
+		m25p_addr2cmd(flash, to, flash->command);
 
 		/* write one byte. */
 		t[1].len = 1;
@@ -521,17 +523,15 @@ static int sst_write(struct mtd_info *mt
 		ret = wait_till_ready(flash);
 		if (ret)
 			goto time_out;
-		*retlen += m.actual_length - CMD_SIZE;
+		*retlen += m.actual_length - m25p_cmdsz(flash);
 	}
 	to += actual;
 
 	flash->command[0] = OPCODE_AAI_WP;
-	flash->command[1] = to >> 16;
-	flash->command[2] = to >> 8;
-	flash->command[3] = to;
+	m25p_addr2cmd(flash, to, flash->command);
 
 	/* Write out most of the data here. */
-	cmd_sz = CMD_SIZE;
+	cmd_sz = m25p_cmdsz(flash);
 	for (; actual < len - 1; actual += 2) {
 		t[0].len = cmd_sz;
 		/* write two bytes. */
@@ -555,10 +555,8 @@ static int sst_write(struct mtd_info *mt
 	if (actual != len) {
 		write_enable(flash);
 		flash->command[0] = OPCODE_BP;
-		flash->command[1] = to >> 16;
-		flash->command[2] = to >> 8;
-		flash->command[3] = to;
-		t[0].len = CMD_SIZE;
+		m25p_addr2cmd(flash, to, flash->command);
+		t[0].len = m25p_cmdsz(flash);
 		t[1].len = 1;
 		t[1].tx_buf = buf + actual;
 
@@ -566,7 +564,7 @@ static int sst_write(struct mtd_info *mt
 		ret = wait_till_ready(flash);
 		if (ret)
 			goto time_out;
-		*retlen += m.actual_length - CMD_SIZE;
+		*retlen += m.actual_length - m25p_cmdsz(flash);
 		write_disable(flash);
 	}
 
@@ -582,8 +580,6 @@ time_out:
  */
 
 struct flash_info {
-	char		*name;
-
 	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
 	 * a high byte of zero plus three data bytes: the manufacturer id,
 	 * then a two byte device id.
@@ -597,87 +593,119 @@ struct flash_info {
 	unsigned	sector_size;
 	u16		n_sectors;
 
+	u16		page_size;
+	u16		addr_width;
+
 	u16		flags;
 #define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */
+#define	M25P_NO_ERASE	0x02		/* No erase command needed */
 };
 
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
+	((kernel_ulong_t)&(struct flash_info) {				\
+		.jedec_id = (_jedec_id),				\
+		.ext_id = (_ext_id),					\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = 256,					\
+		.addr_width = 3,					\
+		.flags = (_flags),					\
+	})
+
+#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width)	\
+	((kernel_ulong_t)&(struct flash_info) {				\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = (_page_size),				\
+		.addr_width = (_addr_width),				\
+		.flags = M25P_NO_ERASE,					\
+	})
 
 /* NOTE: double check command sets and memory organization when you add
  * more flash chips.  This current list focusses on newer chips, which
  * have been converging on command sets which including JEDEC ID.
  */
-static struct flash_info __devinitdata m25p_data [] = {
-
+static const struct spi_device_id m25p_ids[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
-	{ "at25fs010",  0x1f6601, 0, 32 * 1024, 4, SECT_4K, },
-	{ "at25fs040",  0x1f6604, 0, 64 * 1024, 8, SECT_4K, },
+	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
+	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
 
-	{ "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, },
-	{ "at25df641",  0x1f4800, 0, 64 * 1024, 128, SECT_4K, },
+	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
+	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
 
-	{ "at26f004",   0x1f0400, 0, 64 * 1024, 8, SECT_4K, },
-	{ "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, },
-	{ "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
-	{ "at26df321",  0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
+	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
+	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
+	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
+	{ "at26df321",  INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
 
 	/* Macronix */
-	{ "mx25l3205d", 0xc22016, 0, 64 * 1024, 64, },
-	{ "mx25l6405d", 0xc22017, 0, 64 * 1024, 128, },
-	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, },
-	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, },
+	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
+	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
+	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
-	{ "s25sl004a", 0x010212, 0, 64 * 1024, 8, },
-	{ "s25sl008a", 0x010213, 0, 64 * 1024, 16, },
-	{ "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
-	{ "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
-	{ "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
-	{ "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
-	{ "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
-	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024, 64, },
-	{ "s25fl129p1", 0x012018, 0x4d01, 64 * 1024, 256, },
+	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
+	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
+	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
+	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
+	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
+	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
+	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
+	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
+	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
-	{ "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, },
-	{ "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, },
-	{ "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, },
-	{ "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, },
-	{ "sst25wf512",  0xbf2501, 0, 64 * 1024, 1, SECT_4K, },
-	{ "sst25wf010",  0xbf2502, 0, 64 * 1024, 2, SECT_4K, },
-	{ "sst25wf020",  0xbf2503, 0, 64 * 1024, 4, SECT_4K, },
-	{ "sst25wf040",  0xbf2504, 0, 64 * 1024, 8, SECT_4K, },
+	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K) },
+	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K) },
+	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K) },
+	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K) },
+	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K) },
+	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K) },
+	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K) },
+	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K) },
 
 	/* ST Microelectronics -- newer production may have feature updates */
-	{ "m25p05",  0x202010,  0, 32 * 1024, 2, },
-	{ "m25p10",  0x202011,  0, 32 * 1024, 4, },
-	{ "m25p20",  0x202012,  0, 64 * 1024, 4, },
-	{ "m25p40",  0x202013,  0, 64 * 1024, 8, },
-	{ "m25p80",         0,  0, 64 * 1024, 16, },
-	{ "m25p16",  0x202015,  0, 64 * 1024, 32, },
-	{ "m25p32",  0x202016,  0, 64 * 1024, 64, },
-	{ "m25p64",  0x202017,  0, 64 * 1024, 128, },
-	{ "m25p128", 0x202018, 0, 256 * 1024, 64, },
+	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
+	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
+	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
+	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
+	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
+	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
+	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
+	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
+	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
 
-	{ "m45pe10", 0x204011,  0, 64 * 1024, 2, },
-	{ "m45pe80", 0x204014,  0, 64 * 1024, 16, },
-	{ "m45pe16", 0x204015,  0, 64 * 1024, 32, },
+	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
+	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
+	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
 
-	{ "m25pe80", 0x208014,  0, 64 * 1024, 16, },
-	{ "m25pe16", 0x208015,  0, 64 * 1024, 32, SECT_4K, },
+	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
+	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
 
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
-	{ "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, },
-	{ "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, },
-	{ "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, },
-	{ "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, },
-	{ "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, },
-	{ "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, },
-	{ "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, },
+	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
+	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
+	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
+	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
+	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+
+	/* Catalyst / On Semiconductor -- non-JEDEC */
+	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
+	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2) },
+	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2) },
+	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2) },
+	{ "cat25128", CAT25_INFO(2048, 8, 64, 2) },
+	{ },
 };
+MODULE_DEVICE_TABLE(spi, m25p_ids);
 
-static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
+static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
 {
 	int			tmp;
 	u8			code = OPCODE_RDID;
@@ -702,18 +730,24 @@ static struct flash_info *__devinit jede
 	jedec = jedec << 8;
 	jedec |= id[2];
 
+	/*
+	 * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
+	 * which depend on technology process. Officially RDID command doesn't
+	 * exist for non-JEDEC chips, but for compatibility they return ID 0.
+	 */
+	if (jedec == 0)
+		return NULL;
+
 	ext_jedec = id[3] << 8 | id[4];
 
-	for (tmp = 0, info = m25p_data;
-			tmp < ARRAY_SIZE(m25p_data);
-			tmp++, info++) {
+	for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
+		info = (void *)m25p_ids[tmp].driver_data;
 		if (info->jedec_id == jedec) {
 			if (info->ext_id != 0 && info->ext_id != ext_jedec)
 				continue;
-			return info;
+			return &m25p_ids[tmp];
 		}
 	}
-	dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
 	return NULL;
 }
 
@@ -725,6 +759,7 @@ static struct flash_info *__devinit jede
  */
 static int __devinit m25p_probe(struct spi_device *spi)
 {
+	const struct spi_device_id	*id = spi_get_device_id(spi);
 	struct flash_platform_data	*data;
 	struct m25p			*flash;
 	struct flash_info		*info;
@@ -737,50 +772,65 @@ static int __devinit m25p_probe(struct s
 	 */
 	data = spi->dev.platform_data;
 	if (data && data->type) {
-		for (i = 0, info = m25p_data;
-				i < ARRAY_SIZE(m25p_data);
-				i++, info++) {
-			if (strcmp(data->type, info->name) == 0)
-				break;
+		const struct spi_device_id *plat_id;
+
+		for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) {
+			plat_id = &m25p_ids[i];
+			if (strcmp(data->type, plat_id->name))
+				continue;
+			break;
 		}
 
-		/* unrecognized chip? */
-		if (i == ARRAY_SIZE(m25p_data)) {
-			DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
-					dev_name(&spi->dev), data->type);
-			info = NULL;
+		if (plat_id)
+			id = plat_id;
+		else
+			dev_warn(&spi->dev, "unrecognized id %s\n", data->type);
+	}
 
-		/* recognized; is that chip really what's there? */
-		} else if (info->jedec_id) {
-			struct flash_info	*chip = jedec_probe(spi);
+	info = (void *)id->driver_data;
 
-			if (!chip || chip != info) {
-				dev_warn(&spi->dev, "found %s, expected %s\n",
-						chip ? chip->name : "UNKNOWN",
-						info->name);
-				info = NULL;
-			}
-		}
-	} else
-		info = jedec_probe(spi);
+	if (info->jedec_id) {
+		const struct spi_device_id *jid;
 
-	if (!info)
-		return -ENODEV;
+		jid = jedec_probe(spi);
+		if (!jid) {
+			dev_info(&spi->dev, "non-JEDEC variant of %s\n",
+				 id->name);
+		} else if (jid != id) {
+			/*
+			 * JEDEC knows better, so overwrite platform ID. We
+			 * can't trust partitions any longer, but we'll let
+			 * mtd apply them anyway, since some partitions may be
+			 * marked read-only, and we don't want to lose that
+			 * information, even if it's not 100% accurate.
+			 */
+			dev_warn(&spi->dev, "found %s, expected %s\n",
+				 jid->name, id->name);
+			id = jid;
+			info = (void *)jid->driver_data;
+		}
+	}
 
 	flash = kzalloc(sizeof *flash, GFP_KERNEL);
 	if (!flash)
 		return -ENOMEM;
+	flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
+	if (!flash->command) {
+		kfree(flash);
+		return -ENOMEM;
+	}
 
 	flash->spi = spi;
 	mutex_init(&flash->lock);
 	dev_set_drvdata(&spi->dev, flash);
 
 	/*
-	 * Atmel serial flash tend to power up
-	 * with the software protection bits set
+	 * Atmel and SST serial flash tend to power
+	 * up with the software protection bits set
 	 */
 
-	if (info->jedec_id >> 16 == 0x1f) {
+	if (info->jedec_id >> 16 == 0x1f ||
+	    info->jedec_id >> 16 == 0xbf) {
 		write_enable(flash);
 		write_sr(flash, 0);
 	}
@@ -812,9 +862,14 @@ static int __devinit m25p_probe(struct s
 		flash->mtd.erasesize = info->sector_size;
 	}
 
+	if (info->flags & M25P_NO_ERASE)
+		flash->mtd.flags |= MTD_NO_ERASE;
+
 	flash->mtd.dev.parent = &spi->dev;
+	flash->page_size = info->page_size;
+	flash->addr_width = info->addr_width;
 
-	dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
+	dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
 			(long long)flash->mtd.size >> 10);
 
 	DEBUG(MTD_DEBUG_LEVEL2,
@@ -888,8 +943,10 @@ static int __devexit m25p_remove(struct
 		status = del_mtd_partitions(&flash->mtd);
 	else
 		status = del_mtd_device(&flash->mtd);
-	if (status == 0)
+	if (status == 0) {
+		kfree(flash->command);
 		kfree(flash);
+	}
 	return 0;
 }
 
@@ -900,6 +957,7 @@ static struct spi_driver m25p80_driver =
 		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
+	.id_table	= m25p_ids,
 	.probe	= m25p_probe,
 	.remove	= __devexit_p(m25p_remove),
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/devices/mtd_dataflash.c linux-libre-2.6.33-gnu1/drivers/mtd/devices/mtd_dataflash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/devices/mtd_dataflash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/devices/mtd_dataflash.c	2010-02-24 13:52:17.000000000 -0500
@@ -636,6 +636,7 @@ add_dataflash_otp(struct spi_device *spi
 	struct mtd_info			*device;
 	struct flash_platform_data	*pdata = spi->dev.platform_data;
 	char				*otp_tag = "";
+	int				err = 0;
 
 	priv = kzalloc(sizeof *priv, GFP_KERNEL);
 	if (!priv)
@@ -693,13 +694,23 @@ add_dataflash_otp(struct spi_device *spi
 
 		if (nr_parts > 0) {
 			priv->partitioned = 1;
-			return add_mtd_partitions(device, parts, nr_parts);
+			err = add_mtd_partitions(device, parts, nr_parts);
+			goto out;
 		}
 	} else if (pdata && pdata->nr_parts)
 		dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
 				pdata->nr_parts, device->name);
 
-	return add_mtd_device(device) == 1 ? -ENODEV : 0;
+	if (add_mtd_device(device) == 1)
+		err = -ENODEV;
+
+out:
+	if (!err)
+		return 0;
+
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(priv);
+	return err;
 }
 
 static inline int __devinit
@@ -932,8 +943,10 @@ static int __devexit dataflash_remove(st
 		status = del_mtd_partitions(&flash->mtd);
 	else
 		status = del_mtd_device(&flash->mtd);
-	if (status == 0)
+	if (status == 0) {
+		dev_set_drvdata(&spi->dev, NULL);
 		kfree(flash);
+	}
 	return status;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/devices/slram.c linux-libre-2.6.33-gnu1/drivers/mtd/devices/slram.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/devices/slram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/devices/slram.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
                 to specify the offset instead of the absolute address
 
   NOTE:
-  With slram it's only possible to map a contigous memory region. Therfore
+  With slram it's only possible to map a contiguous memory region. Therefore
   if there's a device mapped somewhere in the region specified slram will
   fail to load (see kernel log if modprobe fails).
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/lpddr/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/lpddr/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/lpddr/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/lpddr/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/chips/Kconfig
-
 menu "LPDDR flash memory drivers"
 	depends on MTD!=n
 
@@ -20,4 +18,3 @@ config MTD_QINFO_PROBE
 	    families of devices. This serves similar purpose of CFI on legacy
 	    Flash products
 endmenu
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/ipaq-flash.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/ipaq-flash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/ipaq-flash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/ipaq-flash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,460 +0,0 @@
-/*
- * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
- *
- * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
- * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
- * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/page.h>
-#include <asm/mach-types.h>
-#include <asm/system.h>
-#include <asm/errno.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#ifdef CONFIG_MTD_CONCAT
-#include <linux/mtd/concat.h>
-#endif
-
-#include <mach/hardware.h>
-#include <mach/h3600.h>
-#include <asm/io.h>
-
-
-#ifndef CONFIG_IPAQ_HANDHELD
-#error This is for iPAQ Handhelds only
-#endif
-#ifdef CONFIG_SA1100_JORNADA56X
-
-static void jornada56x_set_vpp(struct map_info *map, int vpp)
-{
-	if (vpp)
-		GPSR = GPIO_GPIO26;
-	else
-		GPCR = GPIO_GPIO26;
-	GPDR |= GPIO_GPIO26;
-}
-
-#endif
-
-#ifdef CONFIG_SA1100_JORNADA720
-
-static void jornada720_set_vpp(struct map_info *map, int vpp)
-{
-	if (vpp)
-		PPSR |= 0x80;
-	else
-		PPSR &= ~0x80;
-	PPDR |= 0x80;
-}
-
-#endif
-
-#define MAX_IPAQ_CS 2		/* Number of CS we are going to test */
-
-#define IPAQ_MAP_INIT(X) \
-	{ \
-		name:		"IPAQ flash " X, \
-	}
-
-
-static struct map_info ipaq_map[MAX_IPAQ_CS] = {
-	IPAQ_MAP_INIT("bank 1"),
-	IPAQ_MAP_INIT("bank 2")
-};
-
-static struct mtd_info *my_sub_mtd[MAX_IPAQ_CS] = {
-	NULL,
-	NULL
-};
-
-/*
- * Here are partition information for all known IPAQ-based devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
- * The *_max_flash_size is the maximum possible mapped flash size which
- * is not necessarily the actual flash size.  It must be no more than
- * the value specified in the "struct map_desc *_io_desc" mapping
- * definition for the corresponding machine.
- *
- * Please keep these in alphabetical order, and formatted as per existing
- * entries.  Thanks.
- */
-
-#ifdef CONFIG_IPAQ_HANDHELD
-static unsigned long h3xxx_max_flash_size = 0x04000000;
-static struct mtd_partition h3xxx_partitions[] = {
-	{
-		name:		"H3XXX boot firmware",
-#ifndef CONFIG_LAB
-		size:		0x00040000,
-#else
-		size:		0x00080000,
-#endif
-		offset:		0,
-#ifndef CONFIG_LAB
-		mask_flags:	MTD_WRITEABLE,  /* force read-only */
-#endif
-	},
-	{
-		name:		"H3XXX root jffs2",
-#ifndef CONFIG_LAB
-		size:		0x2000000 - 2*0x40000, /* Warning, this is fixed later */
-		offset:		0x00040000,
-#else
-		size:		0x2000000 - 0x40000 - 0x80000, /* Warning, this is fixed later */
-		offset:		0x00080000,
-#endif
-	},
-	{
-		name:		"asset",
-		size:		0x40000,
-		offset:		0x2000000 - 0x40000, /* Warning, this is fixed later */
-		mask_flags:	MTD_WRITEABLE,  /* force read-only */
-	}
-};
-
-#ifndef CONFIG_MTD_CONCAT
-static struct mtd_partition h3xxx_partitions_bank2[] = {
-	/* this is used only on 2 CS machines when concat is not present */
-	{
-		name:		"second H3XXX root jffs2",
-		size:		0x1000000 - 0x40000, /* Warning, this is fixed later */
-		offset:		0x00000000,
-	},
-	{
-		name:		"second asset",
-		size:		0x40000,
-		offset:		0x1000000 - 0x40000, /* Warning, this is fixed later */
-		mask_flags:	MTD_WRITEABLE,  /* force read-only */
-	}
-};
-#endif
-
-static DEFINE_SPINLOCK(ipaq_vpp_lock);
-
-static void h3xxx_set_vpp(struct map_info *map, int vpp)
-{
-	static int nest = 0;
-
-	spin_lock(&ipaq_vpp_lock);
-	if (vpp)
-		nest++;
-	else
-		nest--;
-	if (nest)
-		assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 1);
-	else
-		assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 0);
-	spin_unlock(&ipaq_vpp_lock);
-}
-
-#endif
-
-#if defined(CONFIG_SA1100_JORNADA56X) || defined(CONFIG_SA1100_JORNADA720)
-static unsigned long jornada_max_flash_size = 0x02000000;
-static struct mtd_partition jornada_partitions[] = {
-	{
-		name:		"Jornada boot firmware",
-		size:		0x00040000,
-		offset:		0,
-		mask_flags:	MTD_WRITEABLE,  /* force read-only */
-	}, {
-		name:		"Jornada root jffs2",
-		size:		MTDPART_SIZ_FULL,
-		offset:		0x00040000,
-	}
-};
-#endif
-
-
-static struct mtd_partition *parsed_parts;
-static struct mtd_info *mymtd;
-
-static unsigned long cs_phys[] = {
-#ifdef CONFIG_ARCH_SA1100
-	SA1100_CS0_PHYS,
-	SA1100_CS1_PHYS,
-	SA1100_CS2_PHYS,
-	SA1100_CS3_PHYS,
-	SA1100_CS4_PHYS,
-	SA1100_CS5_PHYS,
-#else
-	PXA_CS0_PHYS,
-	PXA_CS1_PHYS,
-	PXA_CS2_PHYS,
-	PXA_CS3_PHYS,
-	PXA_CS4_PHYS,
-	PXA_CS5_PHYS,
-#endif
-};
-
-static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-
-static int __init h1900_special_case(void);
-
-static int __init ipaq_mtd_init(void)
-{
-	struct mtd_partition *parts = NULL;
-	int nb_parts = 0;
-	int parsed_nr_parts = 0;
-	const char *part_type;
-	int i; /* used when we have >1 flash chips */
-	unsigned long tot_flashsize = 0; /* used when we have >1 flash chips */
-
-	/* Default flash bankwidth */
-	// ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
-
-	if (machine_is_h1900())
-	{
-		/* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
-		return h1900_special_case();
-	}
-
-	if (machine_is_h3100() || machine_is_h1900())
-		for(i=0; i<MAX_IPAQ_CS; i++)
-			ipaq_map[i].bankwidth = 2;
-	else
-		for(i=0; i<MAX_IPAQ_CS; i++)
-			ipaq_map[i].bankwidth = 4;
-
-	/*
-	 * Static partition definition selection
-	 */
-	part_type = "static";
-
-	simple_map_init(&ipaq_map[0]);
-	simple_map_init(&ipaq_map[1]);
-
-#ifdef CONFIG_IPAQ_HANDHELD
-	if (machine_is_ipaq()) {
-		parts = h3xxx_partitions;
-		nb_parts = ARRAY_SIZE(h3xxx_partitions);
-		for(i=0; i<MAX_IPAQ_CS; i++) {
-			ipaq_map[i].size = h3xxx_max_flash_size;
-			ipaq_map[i].set_vpp = h3xxx_set_vpp;
-			ipaq_map[i].phys = cs_phys[i];
-			ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
-			if (machine_is_h3100 () || machine_is_h1900())
-				ipaq_map[i].bankwidth = 2;
-		}
-		if (machine_is_h3600()) {
-			/* No asset partition here */
-			h3xxx_partitions[1].size += 0x40000;
-			nb_parts--;
-		}
-	}
-#endif
-#ifdef CONFIG_ARCH_H5400
-	if (machine_is_h5400()) {
-		ipaq_map[0].size = 0x02000000;
-		ipaq_map[1].size = 0x02000000;
-		ipaq_map[1].phys = 0x02000000;
-		ipaq_map[1].virt = ipaq_map[0].virt + 0x02000000;
-	}
-#endif
-#ifdef CONFIG_ARCH_H1900
-	if (machine_is_h1900()) {
-		ipaq_map[0].size = 0x00400000;
-		ipaq_map[1].size = 0x02000000;
-		ipaq_map[1].phys = 0x00080000;
-		ipaq_map[1].virt = ipaq_map[0].virt + 0x00080000;
-	}
-#endif
-
-#ifdef CONFIG_SA1100_JORNADA56X
-	if (machine_is_jornada56x()) {
-		parts = jornada_partitions;
-		nb_parts = ARRAY_SIZE(jornada_partitions);
-		ipaq_map[0].size = jornada_max_flash_size;
-		ipaq_map[0].set_vpp = jornada56x_set_vpp;
-		ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
-	}
-#endif
-#ifdef CONFIG_SA1100_JORNADA720
-	if (machine_is_jornada720()) {
-		parts = jornada_partitions;
-		nb_parts = ARRAY_SIZE(jornada_partitions);
-		ipaq_map[0].size = jornada_max_flash_size;
-		ipaq_map[0].set_vpp = jornada720_set_vpp;
-	}
-#endif
-
-
-	if (machine_is_ipaq()) { /* for iPAQs only */
-		for(i=0; i<MAX_IPAQ_CS; i++) {
-			printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with CFI.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt);
-			my_sub_mtd[i] = do_map_probe("cfi_probe", &ipaq_map[i]);
-			if (!my_sub_mtd[i]) {
-				printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt);
-				my_sub_mtd[i] = do_map_probe("jedec_probe", &ipaq_map[i]);
-			}
-			if (!my_sub_mtd[i]) {
-				printk(KERN_NOTICE "iPAQ flash: failed to find flash.\n");
-				if (i)
-					break;
-				else
-					return -ENXIO;
-			} else
-				printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
-
-			/* do we really need this debugging? --joshua 20030703 */
-			// printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
-			my_sub_mtd[i]->owner = THIS_MODULE;
-			tot_flashsize += my_sub_mtd[i]->size;
-		}
-#ifdef CONFIG_MTD_CONCAT
-		/* fix the asset location */
-#	ifdef CONFIG_LAB
-		h3xxx_partitions[1].size = tot_flashsize - 0x40000 - 0x80000 /* extra big boot block */;
-#	else
-		h3xxx_partitions[1].size = tot_flashsize - 2 * 0x40000;
-#	endif
-		h3xxx_partitions[2].offset = tot_flashsize - 0x40000;
-		/* and concat the devices */
-		mymtd = mtd_concat_create(&my_sub_mtd[0], i,
-					  "ipaq");
-		if (!mymtd) {
-			printk("Cannot create iPAQ concat device\n");
-			return -ENXIO;
-		}
-#else
-		mymtd = my_sub_mtd[0];
-
-		/*
-		 *In the very near future, command line partition parsing
-		 * will use the device name as 'mtd-id' instead of a value
-		 * passed to the parse_cmdline_partitions() routine. Since
-		 * the bootldr says 'ipaq', make sure it continues to work.
-		 */
-		mymtd->name = "ipaq";
-
-		if ((machine_is_h3600())) {
-#	ifdef CONFIG_LAB
-			h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x80000;
-#	else
-			h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000;
-#	endif
-			nb_parts = 2;
-		} else {
-#	ifdef CONFIG_LAB
-			h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000 - 0x80000; /* extra big boot block */
-#	else
-			h3xxx_partitions[1].size = my_sub_mtd[0]->size - 2*0x40000;
-#	endif
-			h3xxx_partitions[2].offset = my_sub_mtd[0]->size - 0x40000;
-		}
-
-		if (my_sub_mtd[1]) {
-#	ifdef CONFIG_LAB
-			h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x80000;
-#	else
-			h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x40000;
-#	endif
-			h3xxx_partitions_bank2[1].offset = my_sub_mtd[1]->size - 0x40000;
-		}
-#endif
-	}
-	else {
-		/*
-		 * Now let's probe for the actual flash.  Do it here since
-		 * specific machine settings might have been set above.
-		 */
-		printk(KERN_NOTICE "IPAQ flash: probing %d-bit flash bus, window=%lx\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
-		mymtd = do_map_probe("cfi_probe", &ipaq_map[0]);
-		if (!mymtd)
-			return -ENXIO;
-		mymtd->owner = THIS_MODULE;
-	}
-
-
-	/*
-	 * Dynamic partition selection stuff (might override the static ones)
-	 */
-
-	 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
-
-	 if (i > 0) {
-		 nb_parts = parsed_nr_parts = i;
-		 parts = parsed_parts;
-		 part_type = "dynamic";
-	 }
-
-	 if (!parts) {
-		 printk(KERN_NOTICE "IPAQ flash: no partition info available, registering whole flash at once\n");
-		 add_mtd_device(mymtd);
-#ifndef CONFIG_MTD_CONCAT
-		 if (my_sub_mtd[1])
-			 add_mtd_device(my_sub_mtd[1]);
-#endif
-	 } else {
-		 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-		 add_mtd_partitions(mymtd, parts, nb_parts);
-#ifndef CONFIG_MTD_CONCAT
-		 if (my_sub_mtd[1])
-			 add_mtd_partitions(my_sub_mtd[1], h3xxx_partitions_bank2, ARRAY_SIZE(h3xxx_partitions_bank2));
-#endif
-	 }
-
-	 return 0;
-}
-
-static void __exit ipaq_mtd_cleanup(void)
-{
-	int i;
-
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-#ifndef CONFIG_MTD_CONCAT
-		if (my_sub_mtd[1])
-			del_mtd_partitions(my_sub_mtd[1]);
-#endif
-		map_destroy(mymtd);
-#ifdef CONFIG_MTD_CONCAT
-		for(i=0; i<MAX_IPAQ_CS; i++)
-#else
-			for(i=1; i<MAX_IPAQ_CS; i++)
-#endif
-			{
-				if (my_sub_mtd[i])
-					map_destroy(my_sub_mtd[i]);
-			}
-		kfree(parsed_parts);
-	}
-}
-
-static int __init h1900_special_case(void)
-{
-	/* The iPAQ h1900 is a special case - it has weird ROM. */
-	simple_map_init(&ipaq_map[0]);
-	ipaq_map[0].size = 0x80000;
-	ipaq_map[0].set_vpp = h3xxx_set_vpp;
-	ipaq_map[0].phys = 0x0;
-	ipaq_map[0].virt = ioremap(0x0, 0x04000000);
-	ipaq_map[0].bankwidth = 2;
-
-	printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
-	mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
-	if (!mymtd)
-		return -ENODEV;
-	add_mtd_device(mymtd);
-	printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
-
-	return 0;
-}
-
-module_init(ipaq_mtd_init);
-module_exit(ipaq_mtd_cleanup);
-
-MODULE_AUTHOR("Jamey Hicks");
-MODULE_DESCRIPTION("IPAQ CFI map driver");
-MODULE_LICENSE("MIT");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/ixp4xx.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/ixp4xx.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/ixp4xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/ixp4xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -210,7 +210,7 @@ static int ixp4xx_flash_probe(struct pla
 	 * not attempt to do a direct access on us.
 	 */
 	info->map.phys = NO_XIP;
-	info->map.size = dev->resource->end - dev->resource->start + 1;
+	info->map.size = resource_size(dev->resource);
 
 	/*
 	 * We only support 16-bit accesses for now. If and when
@@ -224,7 +224,7 @@ static int ixp4xx_flash_probe(struct pla
 	info->map.copy_from = ixp4xx_copy_from,
 
 	info->res = request_mem_region(dev->resource->start,
-			dev->resource->end - dev->resource->start + 1,
+			resource_size(dev->resource),
 			"IXP4XXFlash");
 	if (!info->res) {
 		printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -233,7 +233,7 @@ static int ixp4xx_flash_probe(struct pla
 	}
 
 	info->map.virt = ioremap(dev->resource->start,
-				 dev->resource->end - dev->resource->start + 1);
+				 resource_size(dev->resource));
 	if (!info->map.virt) {
 		printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
 		err = -EIO;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/maps/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/maps/Kconfig
-
 menu "Mapping drivers for chip access"
 	depends on MTD!=n
 
@@ -361,12 +359,6 @@ config MTD_SA1100
 	  the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
 	  If you have such a board, say 'Y'.
 
-config MTD_IPAQ
-	tristate "CFI Flash device mapped on Compaq/HP iPAQ"
-	depends on IPAQ_HANDHELD && MTD_CFI
-	help
-	  This provides a driver for the on-board flash of the iPAQ.
-
 config MTD_DC21285
 	tristate "CFI Flash device mapped on DC21285 Footbridge"
 	depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
@@ -389,9 +381,9 @@ config MTD_IXP2000
 	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
 	help
 	  This enables MTD access to flash devices on platforms based
-	  on Intel's IXP2000 family of network processors such as the
-	  IXDP425 and Coyote. If you have an IXP2000 based board and
-	  would like to use the flash chips on it, say 'Y'.
+	  on Intel's IXP2000 family of network processors. If you have an
+	  IXP2000 based board and would like to use the flash chips on it,
+	  say 'Y'.
 
 config MTD_FORTUNET
 	tristate "CFI Flash device mapped on the FortuNet board"
@@ -557,4 +549,21 @@ config MTD_VMU
 	  To build this as a module select M here, the module will be called
 	  vmu-flash.
 
+config MTD_PISMO
+	tristate "MTD discovery driver for PISMO modules"
+	depends on I2C
+	depends on ARCH_VERSATILE
+	help
+	  This driver allows for discovery of PISMO modules - see
+	  <http://www.pismoworld.org/>.  These are small modules containing
+	  up to five memory devices (eg, SRAM, flash, DOC) described by an
+	  I2C EEPROM.
+
+	  This driver does not create any MTD maps itself; instead it
+	  creates MTD physmap and MTD SRAM platform devices.  If you
+	  enable this option, you should consider enabling MTD_PHYSMAP
+	  and/or MTD_PLATRAM according to the devices on your module.
+
+	  When built as a module, it will be called pismo.ko
+
 endmenu
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/Makefile linux-libre-2.6.33-gnu1/drivers/mtd/maps/Makefile
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -24,12 +24,12 @@ obj-$(CONFIG_MTD_CEIVA)		+= ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o
 obj-$(CONFIG_MTD_PHYSMAP_OF)	+= physmap_of.o
+obj-$(CONFIG_MTD_PISMO)		+= pismo.o
 obj-$(CONFIG_MTD_PMC_MSP_EVM)   += pmcmsp-flash.o
 obj-$(CONFIG_MTD_PCMCIA)	+= pcmciamtd.o
 obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
 obj-$(CONFIG_MTD_TQM8XXL)	+= tqm8xxl.o
 obj-$(CONFIG_MTD_SA1100)	+= sa1100-flash.o
-obj-$(CONFIG_MTD_IPAQ)		+= ipaq-flash.o
 obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o
 obj-$(CONFIG_MTD_SC520CDP)	+= sc520cdp.o
 obj-$(CONFIG_MTD_NETSC520)	+= netsc520.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/omap_nor.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/omap_nor.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/omap_nor.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/omap_nor.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,7 +45,7 @@
 #include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/mach/flash.h>
-#include <mach/tc.h>
+#include <plat/tc.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/pcmciamtd.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/pcmciamtd.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/pcmciamtd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/pcmciamtd.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_i
 		DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
 		      dev->offset, mrq.CardOffset);
 		mrq.Page = 0;
-		ret = pcmcia_map_mem_page(win, &mrq);
-		if (ret != 0) {
-			cs_error(dev->p_dev, MapMemPage, ret);
+		ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
+		if (ret != 0)
 			return NULL;
-		}
 		dev->offset = mrq.CardOffset;
 	}
 	return dev->win_base + (to & (dev->win_size-1));
@@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map
 
 	DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
 	ret = pcmcia_modify_configuration(link, &mod);
-	if (ret != 0)
-		cs_error(link, ModifyConfiguration, ret);
 }
 
 
@@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcm
 			iounmap(dev->win_base);
 			dev->win_base = NULL;
 		}
-		pcmcia_release_window(link->win);
+		pcmcia_release_window(link, link->win);
 	}
 	pcmcia_disable_device(link);
 }
 
 
-static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+#ifdef CONFIG_MTD_DEBUG
+static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
+				tuple_t *tuple,
+				void *priv_data)
 {
-	int rc;
-	tuple_t tuple;
 	cisparse_t parse;
-	u_char buf[64];
 
-	tuple.Attributes = 0;
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+	if (!pcmcia_parse_tuple(tuple, &parse)) {
+		cistpl_format_t *t = &parse.format;
+		(void)t; /* Shut up, gcc */
+		DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
+			t->type, t->edc, t->offset, t->length);
+	}
+	return -ENOSPC;
+}
 
-	rc = pcmcia_get_first_tuple(link, &tuple);
-	while (rc == 0) {
-		rc = pcmcia_get_tuple_data(link, &tuple);
-		if (rc != 0) {
-			cs_error(link, GetTupleData, rc);
-			break;
-		}
-		rc = pcmcia_parse_tuple(&tuple, &parse);
-		if (rc != 0) {
-			cs_error(link, ParseTuple, rc);
-			break;
-		}
+static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
+				tuple_t *tuple,
+				void *priv_data)
+{
+	cisparse_t parse;
+	int i;
 
-		switch(tuple.TupleCode) {
-		case  CISTPL_FORMAT: {
-			cistpl_format_t *t = &parse.format;
-			(void)t; /* Shut up, gcc */
-			DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
-			      t->type, t->edc, t->offset, t->length);
-			break;
+	if (!pcmcia_parse_tuple(tuple, &parse)) {
+		cistpl_jedec_t *t = &parse.jedec;
+		for (i = 0; i < t->nid; i++)
+			DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
+	}
+	return -ENOSPC;
+}
+#endif
 
-		}
+static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
+				tuple_t *tuple,
+				void *priv_data)
+{
+	struct pcmciamtd_dev *dev = priv_data;
+	cisparse_t parse;
+	cistpl_device_t *t = &parse.device;
+	int i;
 
-		case CISTPL_DEVICE: {
-			cistpl_device_t *t = &parse.device;
-			int i;
-			DEBUG(2, "Common memory:");
-			dev->pcmcia_map.size = t->dev[0].size;
-			for(i = 0; i < t->ndev; i++) {
-				DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
-				DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
-				DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
-				DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
-			}
-			break;
-		}
+	if (pcmcia_parse_tuple(tuple, &parse))
+		return -EINVAL;
 
-		case CISTPL_VERS_1: {
-			cistpl_vers_1_t *t = &parse.version_1;
-			int i;
-			if(t->ns) {
-				dev->mtd_name[0] = '\0';
-				for(i = 0; i < t->ns; i++) {
-					if(i)
-						strcat(dev->mtd_name, " ");
-					strcat(dev->mtd_name, t->str+t->ofs[i]);
-				}
-			}
-			DEBUG(2, "Found name: %s", dev->mtd_name);
-			break;
-		}
+	DEBUG(2, "Common memory:");
+	dev->pcmcia_map.size = t->dev[0].size;
+	/* from here on: DEBUG only */
+	for (i = 0; i < t->ndev; i++) {
+		DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
+		DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
+		DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
+		DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
+	}
+	return 0;
+}
 
-		case CISTPL_JEDEC_C: {
-			cistpl_jedec_t *t = &parse.jedec;
-			int i;
-			for(i = 0; i < t->nid; i++) {
-				DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
-			}
-			break;
-		}
+static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
+				tuple_t *tuple,
+				void *priv_data)
+{
+	struct pcmciamtd_dev *dev = priv_data;
+	cisparse_t parse;
+	cistpl_device_geo_t *t = &parse.device_geo;
+	int i;
 
-		case CISTPL_DEVICE_GEO: {
-			cistpl_device_geo_t *t = &parse.device_geo;
-			int i;
-			dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
-			for(i = 0; i < t->ngeo; i++) {
-				DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
-				DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
-				DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
-				DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
-				DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
-				DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
-			}
-			break;
-		}
+	if (pcmcia_parse_tuple(tuple, &parse))
+		return -EINVAL;
 
-		default:
-			DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
-		}
+	dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
+	/* from here on: DEBUG only */
+	for (i = 0; i < t->ngeo; i++) {
+		DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
+		DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
+		DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
+		DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
+		DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
+		DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
+	}
+	return 0;
+}
 
-		rc = pcmcia_get_next_tuple(link, &tuple);
+
+static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+{
+	int i;
+
+	if (p_dev->prod_id[0]) {
+		dev->mtd_name[0] = '\0';
+		for (i = 0; i < 4; i++) {
+			if (i)
+				strcat(dev->mtd_name, " ");
+			if (p_dev->prod_id[i])
+				strcat(dev->mtd_name, p_dev->prod_id[i]);
+		}
+		DEBUG(2, "Found name: %s", dev->mtd_name);
 	}
+
+#ifdef CONFIG_MTD_DEBUG
+	pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
+	pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
+#endif
+	pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
+	pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
+
 	if(!dev->pcmcia_map.size)
 		dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
 
@@ -481,16 +486,12 @@ static void card_settings(struct pcmciam
  * MTD device available to the system.
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int pcmciamtd_config(struct pcmcia_device *link)
 {
 	struct pcmciamtd_dev *dev = link->priv;
 	struct mtd_info *mtd = NULL;
 	cs_status_t status;
 	win_req_t req;
-	int last_ret = 0, last_fn = 0;
 	int ret;
 	int i;
 	static char *probes[] = { "jedec_probe", "cfi_probe" };
@@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmci
 		int ret;
 		DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
 		      req.Size >> 10, req.AccessSpeed);
-		ret = pcmcia_request_window(&link, &req, &link->win);
+		ret = pcmcia_request_window(link, &req, &link->win);
 		DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
 		if(ret) {
 			req.Size >>= 1;
@@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmci
 	DEBUG(2, "Setting Configuration");
 	ret = pcmcia_request_configuration(link, &link->conf);
 	if (ret != 0) {
-		cs_error(link, RequestConfiguration, ret);
 		if (dev->win_base) {
 			iounmap(dev->win_base);
 			dev->win_base = NULL;
@@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmci
 	link->dev_node = &dev->node;
 	return 0;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
+ failed:
 	err("CS Error, exiting");
 	pcmciamtd_release(link);
 	return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/physmap.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/physmap.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/physmap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/physmap.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,23 +48,22 @@ static int physmap_flash_remove(struct p
 
 	if (info->cmtd) {
 #ifdef CONFIG_MTD_PARTITIONS
-		if (info->nr_parts || physmap_data->nr_parts)
+		if (info->nr_parts || physmap_data->nr_parts) {
 			del_mtd_partitions(info->cmtd);
-		else
+
+			if (info->nr_parts)
+				kfree(info->parts);
+		} else {
 			del_mtd_device(info->cmtd);
+		}
 #else
 		del_mtd_device(info->cmtd);
 #endif
-	}
-#ifdef CONFIG_MTD_PARTITIONS
-	if (info->nr_parts)
-		kfree(info->parts);
-#endif
-
 #ifdef CONFIG_MTD_CONCAT
-	if (info->cmtd != info->mtd[0])
-		mtd_concat_destroy(info->cmtd);
+		if (info->cmtd != info->mtd[0])
+			mtd_concat_destroy(info->cmtd);
 #endif
+	}
 
 	for (i = 0; i < MAX_RESOURCES; i++) {
 		if (info->mtd[i] != NULL)
@@ -130,7 +129,7 @@ static int physmap_flash_probe(struct pl
 						 info->map[i].size);
 		if (info->map[i].virt == NULL) {
 			dev_err(&dev->dev, "Failed to ioremap flash region\n");
-			err = EIO;
+			err = -EIO;
 			goto err_out;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/pismo.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/pismo.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/pismo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/pismo.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,320 @@
+/*
+ * PISMO memory driver - http://www.pismoworld.org/
+ *
+ * For ARM Realview and Versatile platforms
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/pismo.h>
+
+#define PISMO_NUM_CS	5
+
+struct pismo_cs_block {
+	u8	type;
+	u8	width;
+	__le16	access;
+	__le32	size;
+	u32	reserved[2];
+	char	device[32];
+} __packed;
+
+struct pismo_eeprom {
+	struct pismo_cs_block cs[PISMO_NUM_CS];
+	char	board[15];
+	u8	sum;
+} __packed;
+
+struct pismo_mem {
+	phys_addr_t base;
+	u32	size;
+	u16	access;
+	u8	width;
+	u8	type;
+};
+
+struct pismo_data {
+	struct i2c_client	*client;
+	void			(*vpp)(void *, int);
+	void			*vpp_data;
+	struct platform_device	*dev[PISMO_NUM_CS];
+};
+
+/* FIXME: set_vpp could do with a better calling convention */
+static struct pismo_data *vpp_pismo;
+static DEFINE_MUTEX(pismo_mutex);
+
+static int pismo_setvpp_probe_fix(struct pismo_data *pismo)
+{
+	mutex_lock(&pismo_mutex);
+	if (vpp_pismo) {
+		mutex_unlock(&pismo_mutex);
+		kfree(pismo);
+		return -EBUSY;
+	}
+	vpp_pismo = pismo;
+	mutex_unlock(&pismo_mutex);
+	return 0;
+}
+
+static void pismo_setvpp_remove_fix(struct pismo_data *pismo)
+{
+	mutex_lock(&pismo_mutex);
+	if (vpp_pismo == pismo)
+		vpp_pismo = NULL;
+	mutex_unlock(&pismo_mutex);
+}
+
+static void pismo_set_vpp(struct map_info *map, int on)
+{
+	struct pismo_data *pismo = vpp_pismo;
+
+	pismo->vpp(pismo->vpp_data, on);
+}
+/* end of hack */
+
+
+static unsigned int __devinit pismo_width_to_bytes(unsigned int width)
+{
+	width &= 15;
+	if (width > 2)
+		return 0;
+	return 1 << width;
+}
+
+static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf,
+	u8 addr, size_t size)
+{
+	int ret;
+	struct i2c_msg msg[] = {
+		{
+			.addr = client->addr,
+			.len = sizeof(addr),
+			.buf = &addr,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = size,
+			.buf = buf,
+		},
+	};
+
+	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+
+	return ret == ARRAY_SIZE(msg) ? size : -EIO;
+}
+
+static int __devinit pismo_add_device(struct pismo_data *pismo, int i,
+	struct pismo_mem *region, const char *name, void *pdata, size_t psize)
+{
+	struct platform_device *dev;
+	struct resource res = { };
+	phys_addr_t base = region.base;
+	int ret;
+
+	if (base == ~0)
+		return -ENXIO;
+
+	res.start = base;
+	res.end = base + region->size - 1;
+	res.flags = IORESOURCE_MEM;
+
+	dev = platform_device_alloc(name, i);
+	if (!dev)
+		return -ENOMEM;
+	dev->dev.parent = &pismo->client->dev;
+
+	do {
+		ret = platform_device_add_resources(dev, &res, 1);
+		if (ret)
+			break;
+
+		ret = platform_device_add_data(dev, pdata, psize);
+		if (ret)
+			break;
+
+		ret = platform_device_add(dev);
+		if (ret)
+			break;
+
+		pismo->dev[i] = dev;
+		return 0;
+	} while (0);
+
+	platform_device_put(dev);
+	return ret;
+}
+
+static int __devinit pismo_add_nor(struct pismo_data *pismo, int i,
+	struct pismo_mem *region)
+{
+	struct physmap_flash_data data = {
+		.width = region->width,
+	};
+
+	if (pismo->vpp)
+		data.set_vpp = pismo_set_vpp;
+
+	return pismo_add_device(pismo, i, region, "physmap-flash",
+		&data, sizeof(data));
+}
+
+static int __devinit pismo_add_sram(struct pismo_data *pismo, int i,
+	struct pismo_mem *region)
+{
+	struct platdata_mtd_ram data = {
+		.bankwidth = region->width,
+	};
+
+	return pismo_add_device(pismo, i, region, "mtd-ram",
+		&data, sizeof(data));
+}
+
+static void __devinit pismo_add_one(struct pismo_data *pismo, int i,
+	const struct pismo_cs_block *cs, phys_addr_t base)
+{
+	struct device *dev = &pismo->client->dev;
+	struct pismo_mem region;
+
+	region.base = base;
+	region.type = cs->type;
+	region.width = pismo_width_to_bytes(cs->width);
+	region.access = le16_to_cpu(cs->access);
+	region.size = le32_to_cpu(cs->size);
+
+	if (region.width == 0) {
+		dev_err(dev, "cs%u: bad width: %02x, ignoring\n", i, cs->width);
+		return;
+	}
+
+	/*
+	 * FIXME: may need to the platforms memory controller here, but at
+	 * the moment we assume that it has already been correctly setup.
+	 * The memory controller can also tell us the base address as well.
+	 */
+
+	dev_info(dev, "cs%u: %.32s: type %02x access %u00ps size %uK\n",
+		i, cs->device, region.type, region.access, region.size / 1024);
+
+	switch (region.type) {
+	case 0:
+		break;
+	case 1:
+		/* static DOC */
+		break;
+	case 2:
+		/* static NOR */
+		pismo_add_nor(pismo, i, &region);
+		break;
+	case 3:
+		/* static RAM */
+		pismo_add_sram(pismo, i, &region);
+		break;
+	}
+}
+
+static int __devexit pismo_remove(struct i2c_client *client)
+{
+	struct pismo_data *pismo = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pismo->dev); i++)
+		platform_device_unregister(pismo->dev[i]);
+
+	/* FIXME: set_vpp needs saner arguments */
+	pismo_setvpp_remove_fix(pismo);
+
+	kfree(pismo);
+
+	return 0;
+}
+
+static int __devinit pismo_probe(struct i2c_client *client,
+				 const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct pismo_pdata *pdata = client->dev.platform_data;
+	struct pismo_eeprom eeprom;
+	struct pismo_data *pismo;
+	int ret, i;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "functionality mismatch\n");
+		return -EIO;
+	}
+
+	pismo = kzalloc(sizeof(*pismo), GFP_KERNEL);
+	if (!pismo)
+		return -ENOMEM;
+
+	/* FIXME: set_vpp needs saner arguments */
+	ret = pismo_setvpp_probe_fix(pismo);
+	if (ret)
+		return ret;
+
+	pismo->client = client;
+	if (pdata) {
+		pismo->vpp = pdata->set_vpp;
+		pismo->vpp_data = pdata->vpp_data;
+	}
+	i2c_set_clientdata(client, pismo);
+
+	ret = pismo_eeprom_read(client, &eeprom, 0, sizeof(eeprom));
+	if (ret < 0) {
+		dev_err(&client->dev, "error reading EEPROM: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(&client->dev, "%.15s board found\n", eeprom.board);
+
+	for (i = 0; i < ARRAY_SIZE(eeprom.cs); i++)
+		if (eeprom.cs[i].type != 0xff)
+			pismo_add_one(pismo, i, &eeprom.cs[i],
+				      pdata->cs_addrs[i]);
+
+	return 0;
+}
+
+static const struct i2c_device_id pismo_id[] = {
+	{ "pismo" },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, pismo_id);
+
+static struct i2c_driver pismo_driver = {
+	.driver	= {
+		.name	= "pismo",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pismo_probe,
+	.remove		= __devexit_p(pismo_remove),
+	.id_table	= pismo_id,
+};
+
+static int __init pismo_init(void)
+{
+	BUILD_BUG_ON(sizeof(struct pismo_cs_block) != 48);
+	BUILD_BUG_ON(sizeof(struct pismo_eeprom) != 256);
+
+	return i2c_add_driver(&pismo_driver);
+}
+module_init(pismo_init);
+
+static void __exit pismo_exit(void)
+{
+	i2c_del_driver(&pismo_driver);
+}
+module_exit(pismo_exit);
+
+MODULE_AUTHOR("Russell King <linux@arm.linux.org.uk>");
+MODULE_DESCRIPTION("PISMO memory driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/pxa2xx-flash.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/pxa2xx-flash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,14 +20,23 @@
 
 #include <asm/io.h>
 #include <mach/hardware.h>
-#include <asm/cacheflush.h>
 
 #include <asm/mach/flash.h>
 
+#define CACHELINESIZE	32
+
 static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
 				      ssize_t len)
 {
-	flush_ioremap_region(map->phys, map->cached, from, len);
+	unsigned long start = (unsigned long)map->cached + from;
+	unsigned long end = start + len;
+
+	start &= ~(CACHELINESIZE - 1);
+	while (start < end) {
+		/* invalidate D cache line */
+		asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
+		start += CACHELINESIZE;
+	}
 }
 
 struct pxa2xx_flash_info {
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/sa1100-flash.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/sa1100-flash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/sa1100-flash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/sa1100-flash.c	2010-02-24 13:52:17.000000000 -0500
@@ -248,7 +248,7 @@ static void sa1100_destroy(struct sa_inf
 		plat->exit();
 }
 
-static struct sa_info *__init
+static struct sa_info *__devinit
 sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
 {
 	struct sa_info *info;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/maps/vmu-flash.c linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmu-flash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/maps/vmu-flash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/maps/vmu-flash.c	2010-02-24 13:52:17.000000000 -0500
@@ -612,16 +612,15 @@ static int __devinit vmu_connect(struct
 
 	test_flash_data = be32_to_cpu(mdev->devinfo.function);
 	/* Need to count how many bits are set - to find out which
-	 * function_data element has details of the memory card:
-	 * using Brian Kernighan's/Peter Wegner's method */
-	for (c = 0; test_flash_data; c++)
-		test_flash_data &= test_flash_data - 1;
+	 * function_data element has details of the memory card
+	 */
+	c = hweight_long(test_flash_data);
 
 	basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
 
 	card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
 	if (!card) {
-		error = ENOMEM;
+		error = -ENOMEM;
 		goto fail_nomem;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/mtd_blkdevs.c linux-libre-2.6.33-gnu1/drivers/mtd/mtd_blkdevs.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/mtd_blkdevs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/mtd_blkdevs.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,12 +59,14 @@ static int do_blktrans_request(struct mt
 		for (; nsect > 0; nsect--, block++, buf += tr->blksize)
 			if (tr->readsect(dev, block, buf))
 				return -EIO;
+		rq_flush_dcache_pages(req);
 		return 0;
 
 	case WRITE:
 		if (!tr->writesect)
 			return -EIO;
 
+		rq_flush_dcache_pages(req);
 		for (; nsect > 0; nsect--, block++, buf += tr->blksize)
 			if (tr->writesect(dev, block, buf))
 				return -EIO;
@@ -82,9 +84,6 @@ static int mtd_blktrans_thread(void *arg
 	struct request_queue *rq = tr->blkcore_priv->rq;
 	struct request *req = NULL;
 
-	/* we might get involved when memory gets low, so use PF_MEMALLOC */
-	current->flags |= PF_MEMALLOC;
-
 	spin_lock_irq(rq->queue_lock);
 
 	while (!kthread_should_stop()) {
@@ -379,7 +378,7 @@ int register_mtd_blktrans(struct mtd_blk
 	tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
 			"%sd", tr->name);
 	if (IS_ERR(tr->blkcore_priv->thread)) {
-		int ret = PTR_ERR(tr->blkcore_priv->thread);
+		ret = PTR_ERR(tr->blkcore_priv->thread);
 		blk_cleanup_queue(tr->blkcore_priv->rq);
 		unregister_blkdev(tr->major, tr->name);
 		kfree(tr->blkcore_priv);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/mtdcore.c linux-libre-2.6.33-gnu1/drivers/mtd/mtdcore.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/mtdcore.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/mtdcore.c	2010-02-24 13:52:17.000000000 -0500
@@ -447,7 +447,7 @@ struct mtd_info *get_mtd_device(struct m
 		for (i=0; i< MAX_MTD_DEVICES; i++)
 			if (mtd_table[i] == mtd)
 				ret = mtd_table[i];
-	} else if (num < MAX_MTD_DEVICES) {
+	} else if (num >= 0 && num < MAX_MTD_DEVICES) {
 		ret = mtd_table[num];
 		if (mtd && mtd != ret)
 			ret = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/mtdoops.c linux-libre-2.6.33-gnu1/drivers/mtd/mtdoops.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/mtdoops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/mtdoops.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,14 +29,34 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
-#include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
+#include <linux/kmsg_dump.h>
+
+/* Maximum MTD partition size */
+#define MTDOOPS_MAX_MTD_SIZE (8 * 1024 * 1024)
 
 #define MTDOOPS_KERNMSG_MAGIC 0x5d005d00
-#define OOPS_PAGE_SIZE 4096
+#define MTDOOPS_HEADER_SIZE   8
+
+static unsigned long record_size = 4096;
+module_param(record_size, ulong, 0400);
+MODULE_PARM_DESC(record_size,
+		"record size for MTD OOPS pages in bytes (default 4096)");
+
+static char mtddev[80];
+module_param_string(mtddev, mtddev, 80, 0400);
+MODULE_PARM_DESC(mtddev,
+		"name or index number of the MTD device to use");
+
+static int dump_oops = 1;
+module_param(dump_oops, int, 0600);
+MODULE_PARM_DESC(dump_oops,
+		"set to 1 to dump oopses, 0 to only dump panics (default 1)");
 
 static struct mtdoops_context {
+	struct kmsg_dumper dump;
+
 	int mtd_index;
 	struct work_struct work_erase;
 	struct work_struct work_write;
@@ -44,28 +64,43 @@ static struct mtdoops_context {
 	int oops_pages;
 	int nextpage;
 	int nextcount;
-	char *name;
+	unsigned long *oops_page_used;
 
 	void *oops_buf;
-
-	/* writecount and disabling ready are spin lock protected */
-	spinlock_t writecount_lock;
-	int ready;
-	int writecount;
 } oops_cxt;
 
+static void mark_page_used(struct mtdoops_context *cxt, int page)
+{
+	set_bit(page, cxt->oops_page_used);
+}
+
+static void mark_page_unused(struct mtdoops_context *cxt, int page)
+{
+	clear_bit(page, cxt->oops_page_used);
+}
+
+static int page_is_used(struct mtdoops_context *cxt, int page)
+{
+	return test_bit(page, cxt->oops_page_used);
+}
+
 static void mtdoops_erase_callback(struct erase_info *done)
 {
 	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
 	wake_up(wait_q);
 }
 
-static int mtdoops_erase_block(struct mtd_info *mtd, int offset)
+static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
 {
+	struct mtd_info *mtd = cxt->mtd;
+	u32 start_page_offset = mtd_div_by_eb(offset, mtd) * mtd->erasesize;
+	u32 start_page = start_page_offset / record_size;
+	u32 erase_pages = mtd->erasesize / record_size;
 	struct erase_info erase;
 	DECLARE_WAITQUEUE(wait, current);
 	wait_queue_head_t wait_q;
 	int ret;
+	int page;
 
 	init_waitqueue_head(&wait_q);
 	erase.mtd = mtd;
@@ -81,25 +116,24 @@ static int mtdoops_erase_block(struct mt
 	if (ret) {
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&wait_q, &wait);
-		printk (KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] "
-				     "on \"%s\" failed\n",
-			(unsigned long long)erase.addr, (unsigned long long)erase.len, mtd->name);
+		printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n",
+		       (unsigned long long)erase.addr,
+		       (unsigned long long)erase.len, mtddev);
 		return ret;
 	}
 
 	schedule();  /* Wait for erase to finish. */
 	remove_wait_queue(&wait_q, &wait);
 
+	/* Mark pages as unused */
+	for (page = start_page; page < start_page + erase_pages; page++)
+		mark_page_unused(cxt, page);
+
 	return 0;
 }
 
 static void mtdoops_inc_counter(struct mtdoops_context *cxt)
 {
-	struct mtd_info *mtd = cxt->mtd;
-	size_t retlen;
-	u32 count;
-	int ret;
-
 	cxt->nextpage++;
 	if (cxt->nextpage >= cxt->oops_pages)
 		cxt->nextpage = 0;
@@ -107,25 +141,13 @@ static void mtdoops_inc_counter(struct m
 	if (cxt->nextcount == 0xffffffff)
 		cxt->nextcount = 0;
 
-	ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4,
-			&retlen, (u_char *) &count);
-	if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) {
-		printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)"
-				", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE,
-				retlen, ret);
-		schedule_work(&cxt->work_erase);
-		return;
-	}
-
-	/* See if we need to erase the next block */
-	if (count != 0xffffffff) {
+	if (page_is_used(cxt, cxt->nextpage)) {
 		schedule_work(&cxt->work_erase);
 		return;
 	}
 
-	printk(KERN_DEBUG "mtdoops: Ready %d, %d (no erase)\n",
-			cxt->nextpage, cxt->nextcount);
-	cxt->ready = 1;
+	printk(KERN_DEBUG "mtdoops: ready %d, %d (no erase)\n",
+	       cxt->nextpage, cxt->nextcount);
 }
 
 /* Scheduled work - when we can't proceed without erasing a block */
@@ -140,47 +162,47 @@ static void mtdoops_workfunc_erase(struc
 	if (!mtd)
 		return;
 
-	mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize;
+	mod = (cxt->nextpage * record_size) % mtd->erasesize;
 	if (mod != 0) {
-		cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE);
+		cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / record_size);
 		if (cxt->nextpage >= cxt->oops_pages)
 			cxt->nextpage = 0;
 	}
 
 	while (mtd->block_isbad) {
-		ret = mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
+		ret = mtd->block_isbad(mtd, cxt->nextpage * record_size);
 		if (!ret)
 			break;
 		if (ret < 0) {
-			printk(KERN_ERR "mtdoops: block_isbad failed, aborting.\n");
+			printk(KERN_ERR "mtdoops: block_isbad failed, aborting\n");
 			return;
 		}
 badblock:
-		printk(KERN_WARNING "mtdoops: Bad block at %08x\n",
-				cxt->nextpage * OOPS_PAGE_SIZE);
+		printk(KERN_WARNING "mtdoops: bad block at %08lx\n",
+		       cxt->nextpage * record_size);
 		i++;
-		cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE);
+		cxt->nextpage = cxt->nextpage + (mtd->erasesize / record_size);
 		if (cxt->nextpage >= cxt->oops_pages)
 			cxt->nextpage = 0;
-		if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) {
-			printk(KERN_ERR "mtdoops: All blocks bad!\n");
+		if (i == cxt->oops_pages / (mtd->erasesize / record_size)) {
+			printk(KERN_ERR "mtdoops: all blocks bad!\n");
 			return;
 		}
 	}
 
 	for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
-		ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
+		ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size);
 
 	if (ret >= 0) {
-		printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount);
-		cxt->ready = 1;
+		printk(KERN_DEBUG "mtdoops: ready %d, %d\n",
+		       cxt->nextpage, cxt->nextcount);
 		return;
 	}
 
-	if (mtd->block_markbad && (ret == -EIO)) {
-		ret = mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
+	if (mtd->block_markbad && ret == -EIO) {
+		ret = mtd->block_markbad(mtd, cxt->nextpage * record_size);
 		if (ret < 0) {
-			printk(KERN_ERR "mtdoops: block_markbad failed, aborting.\n");
+			printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n");
 			return;
 		}
 	}
@@ -191,36 +213,37 @@ static void mtdoops_write(struct mtdoops
 {
 	struct mtd_info *mtd = cxt->mtd;
 	size_t retlen;
+	u32 *hdr;
 	int ret;
 
-	if (cxt->writecount < OOPS_PAGE_SIZE)
-		memset(cxt->oops_buf + cxt->writecount, 0xff,
-					OOPS_PAGE_SIZE - cxt->writecount);
+	/* Add mtdoops header to the buffer */
+	hdr = cxt->oops_buf;
+	hdr[0] = cxt->nextcount;
+	hdr[1] = MTDOOPS_KERNMSG_MAGIC;
 
 	if (panic)
-		ret = mtd->panic_write(mtd, cxt->nextpage * OOPS_PAGE_SIZE,
-					OOPS_PAGE_SIZE, &retlen, cxt->oops_buf);
+		ret = mtd->panic_write(mtd, cxt->nextpage * record_size,
+					record_size, &retlen, cxt->oops_buf);
 	else
-		ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE,
-					OOPS_PAGE_SIZE, &retlen, cxt->oops_buf);
-
-	cxt->writecount = 0;
+		ret = mtd->write(mtd, cxt->nextpage * record_size,
+					record_size, &retlen, cxt->oops_buf);
 
-	if ((retlen != OOPS_PAGE_SIZE) || (ret < 0))
-		printk(KERN_ERR "mtdoops: Write failure at %d (%td of %d written), err %d.\n",
-			cxt->nextpage * OOPS_PAGE_SIZE, retlen,	OOPS_PAGE_SIZE, ret);
+	if (retlen != record_size || ret < 0)
+		printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n",
+		       cxt->nextpage * record_size, retlen, record_size, ret);
+	mark_page_used(cxt, cxt->nextpage);
+	memset(cxt->oops_buf, 0xff, record_size);
 
 	mtdoops_inc_counter(cxt);
 }
 
-
 static void mtdoops_workfunc_write(struct work_struct *work)
 {
 	struct mtdoops_context *cxt =
 			container_of(work, struct mtdoops_context, work_write);
 
 	mtdoops_write(cxt, 0);
-}					
+}
 
 static void find_next_position(struct mtdoops_context *cxt)
 {
@@ -230,28 +253,33 @@ static void find_next_position(struct mt
 	size_t retlen;
 
 	for (page = 0; page < cxt->oops_pages; page++) {
-		ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]);
-		if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) {
-			printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)"
-				", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret);
+		/* Assume the page is used */
+		mark_page_used(cxt, page);
+		ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
+				&retlen, (u_char *) &count[0]);
+		if (retlen != MTDOOPS_HEADER_SIZE ||
+				(ret < 0 && ret != -EUCLEAN)) {
+			printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
+			       page * record_size, retlen,
+			       MTDOOPS_HEADER_SIZE, ret);
 			continue;
 		}
 
-		if (count[1] != MTDOOPS_KERNMSG_MAGIC)
-			continue;
+		if (count[0] == 0xffffffff && count[1] == 0xffffffff)
+			mark_page_unused(cxt, page);
 		if (count[0] == 0xffffffff)
 			continue;
 		if (maxcount == 0xffffffff) {
 			maxcount = count[0];
 			maxpos = page;
-		} else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) {
+		} else if (count[0] < 0x40000000 && maxcount > 0xc0000000) {
 			maxcount = count[0];
 			maxpos = page;
-		} else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) {
+		} else if (count[0] > maxcount && count[0] < 0xc0000000) {
 			maxcount = count[0];
 			maxpos = page;
-		} else if ((count[0] > maxcount) && (count[0] > 0xc0000000)
-					&& (maxcount > 0x80000000)) {
+		} else if (count[0] > maxcount && count[0] > 0xc0000000
+					&& maxcount > 0x80000000) {
 			maxcount = count[0];
 			maxpos = page;
 		}
@@ -269,187 +297,170 @@ static void find_next_position(struct mt
 	mtdoops_inc_counter(cxt);
 }
 
-
-static void mtdoops_notify_add(struct mtd_info *mtd)
+static void mtdoops_do_dump(struct kmsg_dumper *dumper,
+		enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
+		const char *s2, unsigned long l2)
 {
-	struct mtdoops_context *cxt = &oops_cxt;
-
-	if (cxt->name && !strcmp(mtd->name, cxt->name))
-		cxt->mtd_index = mtd->index;
-
-	if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
-		return;
-
-	if (mtd->size < (mtd->erasesize * 2)) {
-		printk(KERN_ERR "MTD partition %d not big enough for mtdoops\n",
-				mtd->index);
-		return;
-	}
+	struct mtdoops_context *cxt = container_of(dumper,
+			struct mtdoops_context, dump);
+	unsigned long s1_start, s2_start;
+	unsigned long l1_cpy, l2_cpy;
+	char *dst;
 
-	if (mtd->erasesize < OOPS_PAGE_SIZE) {
-		printk(KERN_ERR "Eraseblock size of MTD partition %d too small\n",
-				mtd->index);
+	/* Only dump oopses if dump_oops is set */
+	if (reason == KMSG_DUMP_OOPS && !dump_oops)
 		return;
-	}
 
-	cxt->mtd = mtd;
-	if (mtd->size > INT_MAX)
-		cxt->oops_pages = INT_MAX / OOPS_PAGE_SIZE;
-	else
-		cxt->oops_pages = (int)mtd->size / OOPS_PAGE_SIZE;
-
-	find_next_position(cxt);
+	dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */
+	l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE);
+	l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy);
 
-	printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index);
-}
+	s2_start = l2 - l2_cpy;
+	s1_start = l1 - l1_cpy;
 
-static void mtdoops_notify_remove(struct mtd_info *mtd)
-{
-	struct mtdoops_context *cxt = &oops_cxt;
+	memcpy(dst, s1 + s1_start, l1_cpy);
+	memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);
 
-	if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
+	/* Panics must be written immediately */
+	if (reason != KMSG_DUMP_OOPS) {
+		if (!cxt->mtd->panic_write)
+			printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n");
+		else
+			mtdoops_write(cxt, 1);
 		return;
+	}
 
-	cxt->mtd = NULL;
-	flush_scheduled_work();
+	/* For other cases, schedule work to write it "nicely" */
+	schedule_work(&cxt->work_write);
 }
 
-static void mtdoops_console_sync(void)
+static void mtdoops_notify_add(struct mtd_info *mtd)
 {
 	struct mtdoops_context *cxt = &oops_cxt;
-	struct mtd_info *mtd = cxt->mtd;
-	unsigned long flags;
+	u64 mtdoops_pages = div_u64(mtd->size, record_size);
+	int err;
 
-	if (!cxt->ready || !mtd || cxt->writecount == 0)
+	if (!strcmp(mtd->name, mtddev))
+		cxt->mtd_index = mtd->index;
+
+	if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0)
 		return;
 
-	/* 
-	 *  Once ready is 0 and we've held the lock no further writes to the 
-	 *  buffer will happen
-	 */
-	spin_lock_irqsave(&cxt->writecount_lock, flags);
-	if (!cxt->ready) {
-		spin_unlock_irqrestore(&cxt->writecount_lock, flags);
+	if (mtd->size < mtd->erasesize * 2) {
+		printk(KERN_ERR "mtdoops: MTD partition %d not big enough for mtdoops\n",
+		       mtd->index);
 		return;
 	}
-	cxt->ready = 0;
-	spin_unlock_irqrestore(&cxt->writecount_lock, flags);
-
-	if (mtd->panic_write && in_interrupt())
-		/* Interrupt context, we're going to panic so try and log */
-		mtdoops_write(cxt, 1);
-	else
-		schedule_work(&cxt->work_write);
-}
-
-static void
-mtdoops_console_write(struct console *co, const char *s, unsigned int count)
-{
-	struct mtdoops_context *cxt = co->data;
-	struct mtd_info *mtd = cxt->mtd;
-	unsigned long flags;
-
-	if (!oops_in_progress) {
-		mtdoops_console_sync();
+	if (mtd->erasesize < record_size) {
+		printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n",
+		       mtd->index);
 		return;
 	}
-
-	if (!cxt->ready || !mtd)
+	if (mtd->size > MTDOOPS_MAX_MTD_SIZE) {
+		printk(KERN_ERR "mtdoops: mtd%d is too large (limit is %d MiB)\n",
+		       mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024);
 		return;
+	}
 
-	/* Locking on writecount ensures sequential writes to the buffer */
-	spin_lock_irqsave(&cxt->writecount_lock, flags);
-
-	/* Check ready status didn't change whilst waiting for the lock */
-	if (!cxt->ready) {
-		spin_unlock_irqrestore(&cxt->writecount_lock, flags);
+	/* oops_page_used is a bit field */
+	cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages,
+			BITS_PER_LONG));
+	if (!cxt->oops_page_used) {
+		printk(KERN_ERR "mtdoops: could not allocate page array\n");
 		return;
 	}
 
-	if (cxt->writecount == 0) {
-		u32 *stamp = cxt->oops_buf;
-		*stamp++ = cxt->nextcount;
-		*stamp = MTDOOPS_KERNMSG_MAGIC;
-		cxt->writecount = 8;
+	cxt->dump.dump = mtdoops_do_dump;
+	err = kmsg_dump_register(&cxt->dump);
+	if (err) {
+		printk(KERN_ERR "mtdoops: registering kmsg dumper failed, error %d\n", err);
+		vfree(cxt->oops_page_used);
+		cxt->oops_page_used = NULL;
+		return;
 	}
 
-	if ((count + cxt->writecount) > OOPS_PAGE_SIZE)
-		count = OOPS_PAGE_SIZE - cxt->writecount;
-
-	memcpy(cxt->oops_buf + cxt->writecount, s, count);
-	cxt->writecount += count;
-
-	spin_unlock_irqrestore(&cxt->writecount_lock, flags);
-
-	if (cxt->writecount == OOPS_PAGE_SIZE)
-		mtdoops_console_sync();
+	cxt->mtd = mtd;
+	cxt->oops_pages = (int)mtd->size / record_size;
+	find_next_position(cxt);
+	printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index);
 }
 
-static int __init mtdoops_console_setup(struct console *co, char *options)
+static void mtdoops_notify_remove(struct mtd_info *mtd)
 {
-	struct mtdoops_context *cxt = co->data;
+	struct mtdoops_context *cxt = &oops_cxt;
 
-	if (cxt->mtd_index != -1 || cxt->name)
-		return -EBUSY;
-	if (options) {
-		cxt->name = kstrdup(options, GFP_KERNEL);
-		return 0;
-	}
-	if (co->index == -1)
-		return -EINVAL;
+	if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0)
+		return;
 
-	cxt->mtd_index = co->index;
-	return 0;
+	if (kmsg_dump_unregister(&cxt->dump) < 0)
+		printk(KERN_WARNING "mtdoops: could not unregister kmsg_dumper\n");
+
+	cxt->mtd = NULL;
+	flush_scheduled_work();
 }
 
+
 static struct mtd_notifier mtdoops_notifier = {
 	.add	= mtdoops_notify_add,
 	.remove	= mtdoops_notify_remove,
 };
 
-static struct console mtdoops_console = {
-	.name		= "ttyMTD",
-	.write		= mtdoops_console_write,
-	.setup		= mtdoops_console_setup,
-	.unblank	= mtdoops_console_sync,
-	.index		= -1,
-	.data		= &oops_cxt,
-};
-
-static int __init mtdoops_console_init(void)
+static int __init mtdoops_init(void)
 {
 	struct mtdoops_context *cxt = &oops_cxt;
+	int mtd_index;
+	char *endp;
+
+	if (strlen(mtddev) == 0) {
+		printk(KERN_ERR "mtdoops: mtd device (mtddev=name/number) must be supplied\n");
+		return -EINVAL;
+	}
+	if ((record_size & 4095) != 0) {
+		printk(KERN_ERR "mtdoops: record_size must be a multiple of 4096\n");
+		return -EINVAL;
+	}
+	if (record_size < 4096) {
+		printk(KERN_ERR "mtdoops: record_size must be over 4096 bytes\n");
+		return -EINVAL;
+	}
 
+	/* Setup the MTD device to use */
 	cxt->mtd_index = -1;
-	cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
-	spin_lock_init(&cxt->writecount_lock);
+	mtd_index = simple_strtoul(mtddev, &endp, 0);
+	if (*endp == '\0')
+		cxt->mtd_index = mtd_index;
+	if (cxt->mtd_index > MAX_MTD_DEVICES) {
+		printk(KERN_ERR "mtdoops: invalid mtd device number (%u) given\n",
+				mtd_index);
+		return -EINVAL;
+	}
 
+	cxt->oops_buf = vmalloc(record_size);
 	if (!cxt->oops_buf) {
-		printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
+		printk(KERN_ERR "mtdoops: failed to allocate buffer workspace\n");
 		return -ENOMEM;
 	}
+	memset(cxt->oops_buf, 0xff, record_size);
 
 	INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase);
 	INIT_WORK(&cxt->work_write, mtdoops_workfunc_write);
 
-	register_console(&mtdoops_console);
 	register_mtd_user(&mtdoops_notifier);
 	return 0;
 }
 
-static void __exit mtdoops_console_exit(void)
+static void __exit mtdoops_exit(void)
 {
 	struct mtdoops_context *cxt = &oops_cxt;
 
 	unregister_mtd_user(&mtdoops_notifier);
-	unregister_console(&mtdoops_console);
-	kfree(cxt->name);
 	vfree(cxt->oops_buf);
+	vfree(cxt->oops_page_used);
 }
 
 
-subsys_initcall(mtdoops_console_init);
-module_exit(mtdoops_console_exit);
+module_init(mtdoops_init);
+module_exit(mtdoops_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/alauda.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/alauda.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/alauda.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/alauda.c	2010-02-24 13:52:17.000000000 -0500
@@ -372,15 +372,6 @@ static int alauda_read_oob(struct mtd_in
 	return __alauda_read_page(mtd, from, ignore_buf, oob);
 }
 
-static int popcount8(u8 c)
-{
-	int ret = 0;
-
-	for ( ; c; c>>=1)
-		ret += c & 1;
-	return ret;
-}
-
 static int alauda_isbad(struct mtd_info *mtd, loff_t ofs)
 {
 	u8 oob[16];
@@ -391,7 +382,7 @@ static int alauda_isbad(struct mtd_info
 		return err;
 
 	/* A block is marked bad if two or more bits are zero */
-	return popcount8(oob[5]) >= 7 ? 0 : 1;
+	return hweight8(oob[5]) >= 7 ? 0 : 1;
 }
 
 static int alauda_bounce_read(struct mtd_info *mtd, loff_t from, size_t len,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/ams-delta.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/ams-delta.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/ams-delta.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/ams-delta.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 #include <asm/sizes.h>
 #include <mach/gpio.h>
-#include <mach/board-ams-delta.h>
+#include <plat/board-ams-delta.h>
 
 /*
  * MTD structure for E3 (Delta)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/atmel_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/atmel_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/atmel_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/atmel_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -192,7 +192,6 @@ static int atmel_nand_calculate(struct m
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct atmel_nand_host *host = nand_chip->priv;
-	uint32_t *eccpos = nand_chip->ecc.layout->eccpos;
 	unsigned int ecc_value;
 
 	/* get the first 2 ECC bytes */
@@ -464,7 +463,7 @@ static int __init atmel_nand_probe(struc
 	if (host->board->det_pin) {
 		if (gpio_get_value(host->board->det_pin)) {
 			printk(KERN_INFO "No SmartMedia card inserted.\n");
-			res = ENXIO;
+			res = -ENXIO;
 			goto err_no_card;
 		}
 	}
@@ -535,7 +534,7 @@ static int __init atmel_nand_probe(struc
 
 	if ((!partitions) || (num_partitions == 0)) {
 		printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n");
-		res = ENXIO;
+		res = -ENXIO;
 		goto err_no_partitions;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/bcm_umi_bch.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_bch.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/bcm_umi_bch.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_bch.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,213 @@
+/*****************************************************************************
+* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include "nand_bcm_umi.h"
+
+/* ---- External Variable Declarations ----------------------------------- */
+/* ---- External Function Prototypes ------------------------------------- */
+/* ---- Public Variables ------------------------------------------------- */
+/* ---- Private Constants and Types -------------------------------------- */
+
+/* ---- Private Function Prototypes -------------------------------------- */
+static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
+	struct nand_chip *chip, uint8_t *buf, int page);
+static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
+	struct nand_chip *chip, const uint8_t *buf);
+
+/* ---- Private Variables ------------------------------------------------ */
+
+/*
+** nand_hw_eccoob
+** New oob placement block for use with hardware ecc generation.
+*/
+static struct nand_ecclayout nand_hw_eccoob_512 = {
+	/* Reserve 5 for BI indicator */
+	.oobfree = {
+#if (NAND_ECC_NUM_BYTES > 3)
+		    {.offset = 0, .length = 2}
+#else
+		    {.offset = 0, .length = 5},
+		    {.offset = 6, .length = 7}
+#endif
+		    }
+};
+
+/*
+** We treat the OOB for a 2K page as if it were 4 512 byte oobs,
+** except the BI is at byte 0.
+*/
+static struct nand_ecclayout nand_hw_eccoob_2048 = {
+	/* Reserve 0 as BI indicator */
+	.oobfree = {
+#if (NAND_ECC_NUM_BYTES > 10)
+		    {.offset = 1, .length = 2},
+#elif (NAND_ECC_NUM_BYTES > 7)
+		    {.offset = 1, .length = 5},
+		    {.offset = 16, .length = 6},
+		    {.offset = 32, .length = 6},
+		    {.offset = 48, .length = 6}
+#else
+		    {.offset = 1, .length = 8},
+		    {.offset = 16, .length = 9},
+		    {.offset = 32, .length = 9},
+		    {.offset = 48, .length = 9}
+#endif
+		    }
+};
+
+/* We treat the OOB for a 4K page as if it were 8 512 byte oobs,
+ * except the BI is at byte 0. */
+static struct nand_ecclayout nand_hw_eccoob_4096 = {
+	/* Reserve 0 as BI indicator */
+	.oobfree = {
+#if (NAND_ECC_NUM_BYTES > 10)
+		    {.offset = 1, .length = 2},
+		    {.offset = 16, .length = 3},
+		    {.offset = 32, .length = 3},
+		    {.offset = 48, .length = 3},
+		    {.offset = 64, .length = 3},
+		    {.offset = 80, .length = 3},
+		    {.offset = 96, .length = 3},
+		    {.offset = 112, .length = 3}
+#else
+		    {.offset = 1, .length = 5},
+		    {.offset = 16, .length = 6},
+		    {.offset = 32, .length = 6},
+		    {.offset = 48, .length = 6},
+		    {.offset = 64, .length = 6},
+		    {.offset = 80, .length = 6},
+		    {.offset = 96, .length = 6},
+		    {.offset = 112, .length = 6}
+#endif
+		    }
+};
+
+/* ---- Private Functions ------------------------------------------------ */
+/* ==== Public Functions ================================================= */
+
+/****************************************************************************
+*
+*  bcm_umi_bch_read_page_hwecc - hardware ecc based page read function
+*  @mtd:	mtd info structure
+*  @chip:	nand chip info structure
+*  @buf:	buffer to store read data
+*
+***************************************************************************/
+static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
+				       struct nand_chip *chip, uint8_t * buf,
+						 int page)
+{
+	int sectorIdx = 0;
+	int eccsize = chip->ecc.size;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *datap = buf;
+	uint8_t eccCalc[NAND_ECC_NUM_BYTES];
+	int sectorOobSize = mtd->oobsize / eccsteps;
+	int stat;
+
+	for (sectorIdx = 0; sectorIdx < eccsteps;
+			sectorIdx++, datap += eccsize) {
+		if (sectorIdx > 0) {
+			/* Seek to page location within sector */
+			chip->cmdfunc(mtd, NAND_CMD_RNDOUT, sectorIdx * eccsize,
+				      -1);
+		}
+
+		/* Enable hardware ECC before reading the buf */
+		nand_bcm_umi_bch_enable_read_hwecc();
+
+		/* Read in data */
+		bcm_umi_nand_read_buf(mtd, datap, eccsize);
+
+		/* Pause hardware ECC after reading the buf */
+		nand_bcm_umi_bch_pause_read_ecc_calc();
+
+		/* Read the OOB ECC */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+			      mtd->writesize + sectorIdx * sectorOobSize, -1);
+		nand_bcm_umi_bch_read_oobEcc(mtd->writesize, eccCalc,
+					     NAND_ECC_NUM_BYTES,
+					     chip->oob_poi +
+					     sectorIdx * sectorOobSize);
+
+		/* Correct any ECC detected errors */
+		stat =
+		    nand_bcm_umi_bch_correct_page(datap, eccCalc,
+						  NAND_ECC_NUM_BYTES);
+
+		/* Update Stats */
+		if (stat < 0) {
+#if defined(NAND_BCM_UMI_DEBUG)
+			printk(KERN_WARNING "%s uncorr_err sectorIdx=%d\n",
+			       __func__, sectorIdx);
+			printk(KERN_WARNING
+			       "%s data %02x %02x %02x %02x "
+					 "%02x %02x %02x %02x\n",
+			       __func__, datap[0], datap[1], datap[2], datap[3],
+			       datap[4], datap[5], datap[6], datap[7]);
+			printk(KERN_WARNING
+			       "%s ecc  %02x %02x %02x %02x "
+					 "%02x %02x %02x %02x %02x %02x "
+					 "%02x %02x %02x\n",
+			       __func__, eccCalc[0], eccCalc[1], eccCalc[2],
+			       eccCalc[3], eccCalc[4], eccCalc[5], eccCalc[6],
+			       eccCalc[7], eccCalc[8], eccCalc[9], eccCalc[10],
+			       eccCalc[11], eccCalc[12]);
+			BUG();
+#endif
+			mtd->ecc_stats.failed++;
+		} else {
+#if defined(NAND_BCM_UMI_DEBUG)
+			if (stat > 0) {
+				printk(KERN_INFO
+				       "%s %d correctable_errors detected\n",
+				       __func__, stat);
+			}
+#endif
+			mtd->ecc_stats.corrected += stat;
+		}
+	}
+	return 0;
+}
+
+/****************************************************************************
+*
+*  bcm_umi_bch_write_page_hwecc - hardware ecc based page write function
+*  @mtd:	mtd info structure
+*  @chip:	nand chip info structure
+*  @buf:	data buffer
+*
+***************************************************************************/
+static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
+	struct nand_chip *chip, const uint8_t *buf)
+{
+	int sectorIdx = 0;
+	int eccsize = chip->ecc.size;
+	int eccsteps = chip->ecc.steps;
+	const uint8_t *datap = buf;
+	uint8_t *oobp = chip->oob_poi;
+	int sectorOobSize = mtd->oobsize / eccsteps;
+
+	for (sectorIdx = 0; sectorIdx < eccsteps;
+	     sectorIdx++, datap += eccsize, oobp += sectorOobSize) {
+		/* Enable hardware ECC before writing the buf */
+		nand_bcm_umi_bch_enable_write_hwecc();
+		bcm_umi_nand_write_buf(mtd, datap, eccsize);
+		nand_bcm_umi_bch_write_oobEcc(mtd->writesize, oobp,
+					      NAND_ECC_NUM_BYTES);
+	}
+
+	bcm_umi_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/bcm_umi_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/bcm_umi_nand.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/bcm_umi_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,581 @@
+/*****************************************************************************
+* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#include <mach/reg_nand.h>
+#include <mach/reg_umi.h>
+
+#include "nand_bcm_umi.h"
+
+#include <mach/memory_settings.h>
+
+#define USE_DMA 1
+#include <mach/dma.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+
+/* ---- External Variable Declarations ----------------------------------- */
+/* ---- External Function Prototypes ------------------------------------- */
+/* ---- Public Variables ------------------------------------------------- */
+/* ---- Private Constants and Types -------------------------------------- */
+static const __devinitconst char gBanner[] = KERN_INFO \
+	"BCM UMI MTD NAND Driver: 1.00\n";
+
+#ifdef CONFIG_MTD_PARTITIONS
+const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+#if NAND_ECC_BCH
+static uint8_t scan_ff_pattern[] = { 0xff };
+
+static struct nand_bbt_descr largepage_bbt = {
+	.options = 0,
+	.offs = 0,
+	.len = 1,
+	.pattern = scan_ff_pattern
+};
+#endif
+
+/*
+** Preallocate a buffer to avoid having to do this every dma operation.
+** This is the size of the preallocated coherent DMA buffer.
+*/
+#if USE_DMA
+#define DMA_MIN_BUFLEN	512
+#define DMA_MAX_BUFLEN	PAGE_SIZE
+#define USE_DIRECT_IO(len)	(((len) < DMA_MIN_BUFLEN) || \
+	((len) > DMA_MAX_BUFLEN))
+
+/*
+ * The current NAND data space goes from 0x80001900 to 0x80001FFF,
+ * which is only 0x700 = 1792 bytes long. This is too small for 2K, 4K page
+ * size NAND flash. Need to break the DMA down to multiple 1Ks.
+ *
+ * Need to make sure REG_NAND_DATA_PADDR + DMA_MAX_LEN < 0x80002000
+ */
+#define DMA_MAX_LEN             1024
+
+#else /* !USE_DMA */
+#define DMA_MIN_BUFLEN          0
+#define DMA_MAX_BUFLEN          0
+#define USE_DIRECT_IO(len)      1
+#endif
+/* ---- Private Function Prototypes -------------------------------------- */
+static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len);
+static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
+				   int len);
+
+/* ---- Private Variables ------------------------------------------------ */
+static struct mtd_info *board_mtd;
+static void __iomem *bcm_umi_io_base;
+static void *virtPtr;
+static dma_addr_t physPtr;
+static struct completion nand_comp;
+
+/* ---- Private Functions ------------------------------------------------ */
+#if NAND_ECC_BCH
+#include "bcm_umi_bch.c"
+#else
+#include "bcm_umi_hamming.c"
+#endif
+
+#if USE_DMA
+
+/* Handler called when the DMA finishes. */
+static void nand_dma_handler(DMA_Device_t dev, int reason, void *userData)
+{
+	complete(&nand_comp);
+}
+
+static int nand_dma_init(void)
+{
+	int rc;
+
+	rc = dma_set_device_handler(DMA_DEVICE_NAND_MEM_TO_MEM,
+		nand_dma_handler, NULL);
+	if (rc != 0) {
+		printk(KERN_ERR "dma_set_device_handler failed: %d\n", rc);
+		return rc;
+	}
+
+	virtPtr =
+	    dma_alloc_coherent(NULL, DMA_MAX_BUFLEN, &physPtr, GFP_KERNEL);
+	if (virtPtr == NULL) {
+		printk(KERN_ERR "NAND - Failed to allocate memory for DMA buffer\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void nand_dma_term(void)
+{
+	if (virtPtr != NULL)
+		dma_free_coherent(NULL, DMA_MAX_BUFLEN, virtPtr, physPtr);
+}
+
+static void nand_dma_read(void *buf, int len)
+{
+	int offset = 0;
+	int tmp_len = 0;
+	int len_left = len;
+	DMA_Handle_t hndl;
+
+	if (virtPtr == NULL)
+		panic("nand_dma_read: virtPtr == NULL\n");
+
+	if ((void *)physPtr == NULL)
+		panic("nand_dma_read: physPtr == NULL\n");
+
+	hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
+	if (hndl < 0) {
+		printk(KERN_ERR
+		       "nand_dma_read: unable to allocate dma channel: %d\n",
+		       (int)hndl);
+		panic("\n");
+	}
+
+	while (len_left > 0) {
+		if (len_left > DMA_MAX_LEN) {
+			tmp_len = DMA_MAX_LEN;
+			len_left -= DMA_MAX_LEN;
+		} else {
+			tmp_len = len_left;
+			len_left = 0;
+		}
+
+		init_completion(&nand_comp);
+		dma_transfer_mem_to_mem(hndl, REG_NAND_DATA_PADDR,
+					physPtr + offset, tmp_len);
+		wait_for_completion(&nand_comp);
+
+		offset += tmp_len;
+	}
+
+	dma_free_channel(hndl);
+
+	if (buf != NULL)
+		memcpy(buf, virtPtr, len);
+}
+
+static void nand_dma_write(const void *buf, int len)
+{
+	int offset = 0;
+	int tmp_len = 0;
+	int len_left = len;
+	DMA_Handle_t hndl;
+
+	if (buf == NULL)
+		panic("nand_dma_write: buf == NULL\n");
+
+	if (virtPtr == NULL)
+		panic("nand_dma_write: virtPtr == NULL\n");
+
+	if ((void *)physPtr == NULL)
+		panic("nand_dma_write: physPtr == NULL\n");
+
+	memcpy(virtPtr, buf, len);
+
+
+	hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
+	if (hndl < 0) {
+		printk(KERN_ERR
+		       "nand_dma_write: unable to allocate dma channel: %d\n",
+		       (int)hndl);
+		panic("\n");
+	}
+
+	while (len_left > 0) {
+		if (len_left > DMA_MAX_LEN) {
+			tmp_len = DMA_MAX_LEN;
+			len_left -= DMA_MAX_LEN;
+		} else {
+			tmp_len = len_left;
+			len_left = 0;
+		}
+
+		init_completion(&nand_comp);
+		dma_transfer_mem_to_mem(hndl, physPtr + offset,
+					REG_NAND_DATA_PADDR, tmp_len);
+		wait_for_completion(&nand_comp);
+
+		offset += tmp_len;
+	}
+
+	dma_free_channel(hndl);
+}
+
+#endif
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+	return nand_bcm_umi_dev_ready();
+}
+
+/****************************************************************************
+*
+*  bcm_umi_nand_inithw
+*
+*   This routine does the necessary hardware (board-specific)
+*   initializations.  This includes setting up the timings, etc.
+*
+***************************************************************************/
+int bcm_umi_nand_inithw(void)
+{
+	/* Configure nand timing parameters */
+	REG_UMI_NAND_TCR &= ~0x7ffff;
+	REG_UMI_NAND_TCR |= HW_CFG_NAND_TCR;
+
+#if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS)
+	/* enable software control of CS */
+	REG_UMI_NAND_TCR |= REG_UMI_NAND_TCR_CS_SWCTRL;
+#endif
+
+	/* keep NAND chip select asserted */
+	REG_UMI_NAND_RCSR |= REG_UMI_NAND_RCSR_CS_ASSERTED;
+
+	REG_UMI_NAND_TCR &= ~REG_UMI_NAND_TCR_WORD16;
+	/* enable writes to flash */
+	REG_UMI_MMD_ICR |= REG_UMI_MMD_ICR_FLASH_WP;
+
+	writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET);
+	nand_bcm_umi_wait_till_ready();
+
+#if NAND_ECC_BCH
+	nand_bcm_umi_bch_config_ecc(NAND_ECC_NUM_BYTES);
+#endif
+
+	return 0;
+}
+
+/* Used to turn latch the proper register for access. */
+static void bcm_umi_nand_hwcontrol(struct mtd_info *mtd, int cmd,
+				   unsigned int ctrl)
+{
+	/* send command to hardware */
+	struct nand_chip *chip = mtd->priv;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_CLE) {
+			chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_CMD_OFFSET;
+			goto CMD;
+		}
+		if (ctrl & NAND_ALE) {
+			chip->IO_ADDR_W =
+			    bcm_umi_io_base + REG_NAND_ADDR_OFFSET;
+			goto CMD;
+		}
+		chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
+	}
+
+CMD:
+	/* Send command to chip directly */
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, chip->IO_ADDR_W);
+}
+
+static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
+				   int len)
+{
+	if (USE_DIRECT_IO(len)) {
+		/* Do it the old way if the buffer is small or too large.
+		 * Probably quicker than starting and checking dma. */
+		int i;
+		struct nand_chip *this = mtd->priv;
+
+		for (i = 0; i < len; i++)
+			writeb(buf[i], this->IO_ADDR_W);
+	}
+#if USE_DMA
+	else
+		nand_dma_write(buf, len);
+#endif
+}
+
+static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len)
+{
+	if (USE_DIRECT_IO(len)) {
+		int i;
+		struct nand_chip *this = mtd->priv;
+
+		for (i = 0; i < len; i++)
+			buf[i] = readb(this->IO_ADDR_R);
+	}
+#if USE_DMA
+	else
+		nand_dma_read(buf, len);
+#endif
+}
+
+static uint8_t readbackbuf[NAND_MAX_PAGESIZE];
+static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
+				   int len)
+{
+	/*
+	 * Try to readback page with ECC correction. This is necessary
+	 * for MLC parts which may have permanently stuck bits.
+	 */
+	struct nand_chip *chip = mtd->priv;
+	int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0);
+	if (ret < 0)
+		return -EFAULT;
+	else {
+		if (memcmp(readbackbuf, buf, len) == 0)
+			return 0;
+
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
+{
+	struct nand_chip *this;
+	struct resource *r;
+	int err = 0;
+
+	printk(gBanner);
+
+	/* Allocate memory for MTD device structure and private data */
+	board_mtd =
+	    kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
+		    GFP_KERNEL);
+	if (!board_mtd) {
+		printk(KERN_WARNING
+		       "Unable to allocate NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!r)
+		return -ENXIO;
+
+	/* map physical adress */
+	bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1);
+
+	if (!bcm_umi_io_base) {
+		printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n");
+		kfree(board_mtd);
+		return -EIO;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *)(&board_mtd[1]);
+
+	/* Initialize structures */
+	memset((char *)board_mtd, 0, sizeof(struct mtd_info));
+	memset((char *)this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	board_mtd->priv = this;
+
+	/* Initialize the NAND hardware.  */
+	if (bcm_umi_nand_inithw() < 0) {
+		printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n");
+		iounmap(bcm_umi_io_base);
+		kfree(board_mtd);
+		return -EIO;
+	}
+
+	/* Set address of NAND IO lines */
+	this->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
+	this->IO_ADDR_R = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
+
+	/* Set command delay time, see datasheet for correct value */
+	this->chip_delay = 0;
+	/* Assign the device ready function, if available */
+	this->dev_ready = nand_dev_ready;
+	this->options = 0;
+
+	this->write_buf = bcm_umi_nand_write_buf;
+	this->read_buf = bcm_umi_nand_read_buf;
+	this->verify_buf = bcm_umi_nand_verify_buf;
+
+	this->cmd_ctrl = bcm_umi_nand_hwcontrol;
+	this->ecc.mode = NAND_ECC_HW;
+	this->ecc.size = 512;
+	this->ecc.bytes = NAND_ECC_NUM_BYTES;
+#if NAND_ECC_BCH
+	this->ecc.read_page = bcm_umi_bch_read_page_hwecc;
+	this->ecc.write_page = bcm_umi_bch_write_page_hwecc;
+#else
+	this->ecc.correct = nand_correct_data512;
+	this->ecc.calculate = bcm_umi_hamming_get_hw_ecc;
+	this->ecc.hwctl = bcm_umi_hamming_enable_hwecc;
+#endif
+
+#if USE_DMA
+	err = nand_dma_init();
+	if (err != 0)
+		return err;
+#endif
+
+	/* Figure out the size of the device that we have.
+	 * We need to do this to figure out which ECC
+	 * layout we'll be using.
+	 */
+
+	err = nand_scan_ident(board_mtd, 1);
+	if (err) {
+		printk(KERN_ERR "nand_scan failed: %d\n", err);
+		iounmap(bcm_umi_io_base);
+		kfree(board_mtd);
+		return err;
+	}
+
+	/* Now that we know the nand size, we can setup the ECC layout */
+
+	switch (board_mtd->writesize) {	/* writesize is the pagesize */
+	case 4096:
+		this->ecc.layout = &nand_hw_eccoob_4096;
+		break;
+	case 2048:
+		this->ecc.layout = &nand_hw_eccoob_2048;
+		break;
+	case 512:
+		this->ecc.layout = &nand_hw_eccoob_512;
+		break;
+	default:
+		{
+			printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n",
+					 board_mtd->writesize);
+			return -EINVAL;
+		}
+	}
+
+#if NAND_ECC_BCH
+	if (board_mtd->writesize > 512) {
+		if (this->options & NAND_USE_FLASH_BBT)
+			largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
+		this->badblock_pattern = &largepage_bbt;
+	}
+#endif
+
+	/* Now finish off the scan, now that ecc.layout has been initialized. */
+
+	err = nand_scan_tail(board_mtd);
+	if (err) {
+		printk(KERN_ERR "nand_scan failed: %d\n", err);
+		iounmap(bcm_umi_io_base);
+		kfree(board_mtd);
+		return err;
+	}
+
+	/* Register the partitions */
+	{
+		int nr_partitions;
+		struct mtd_partition *partition_info;
+
+		board_mtd->name = "bcm_umi-nand";
+		nr_partitions =
+		    parse_mtd_partitions(board_mtd, part_probes,
+					 &partition_info, 0);
+
+		if (nr_partitions <= 0) {
+			printk(KERN_ERR "BCM UMI NAND: Too few partitions - %d\n",
+			       nr_partitions);
+			iounmap(bcm_umi_io_base);
+			kfree(board_mtd);
+			return -EIO;
+		}
+		add_mtd_partitions(board_mtd, partition_info, nr_partitions);
+	}
+
+	/* Return happy */
+	return 0;
+}
+
+static int bcm_umi_nand_remove(struct platform_device *pdev)
+{
+#if USE_DMA
+	nand_dma_term();
+#endif
+
+	/* Release resources, unregister device */
+	nand_release(board_mtd);
+
+	/* unmap physical adress */
+	iounmap(bcm_umi_io_base);
+
+	/* Free the MTD device structure */
+	kfree(board_mtd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int bcm_umi_nand_suspend(struct platform_device *pdev,
+				pm_message_t state)
+{
+	printk(KERN_ERR "MTD NAND suspend is being called\n");
+	return 0;
+}
+
+static int bcm_umi_nand_resume(struct platform_device *pdev)
+{
+	printk(KERN_ERR "MTD NAND resume is being called\n");
+	return 0;
+}
+#else
+#define bcm_umi_nand_suspend   NULL
+#define bcm_umi_nand_resume    NULL
+#endif
+
+static struct platform_driver nand_driver = {
+	.driver = {
+		   .name = "bcm-nand",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = bcm_umi_nand_probe,
+	.remove = bcm_umi_nand_remove,
+	.suspend = bcm_umi_nand_suspend,
+	.resume = bcm_umi_nand_resume,
+};
+
+static int __init nand_init(void)
+{
+	return platform_driver_register(&nand_driver);
+}
+
+static void __exit nand_exit(void)
+{
+	platform_driver_unregister(&nand_driver);
+}
+
+module_init(nand_init);
+module_exit(nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Broadcom");
+MODULE_DESCRIPTION("BCM UMI MTD NAND driver");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/davinci_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/davinci_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/davinci_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/davinci_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -591,6 +591,8 @@ static int __init nand_davinci_probe(str
 
 	/* options such as NAND_USE_FLASH_BBT or 16-bit widths */
 	info->chip.options	= pdata->options;
+	info->chip.bbt_td	= pdata->bbt_td;
+	info->chip.bbt_md	= pdata->bbt_md;
 
 	info->ioaddr		= (uint32_t __force) vaddr;
 
@@ -599,7 +601,7 @@ static int __init nand_davinci_probe(str
 	info->mask_chipsel	= pdata->mask_chipsel;
 
 	/* use nandboot-capable ALE/CLE masks by default */
-	info->mask_ale		= pdata->mask_cle ? : MASK_ALE;
+	info->mask_ale		= pdata->mask_ale ? : MASK_ALE;
 	info->mask_cle		= pdata->mask_cle ? : MASK_CLE;
 
 	/* Set address of hardware control function */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/diskonchip.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/diskonchip.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/diskonchip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/diskonchip.c	2010-02-24 13:52:17.000000000 -0500
@@ -1056,7 +1056,7 @@ static struct nand_ecclayout doc200x_oob
 };
 
 /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
-   On sucessful return, buf will contain a copy of the media header for
+   On successful return, buf will contain a copy of the media header for
    further processing.  id is the string to scan for, and will presumably be
    either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media
    header.  The page #s of the found media headers are placed in mh0_page and
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/excite_nandflash.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/excite_nandflash.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/excite_nandflash.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/excite_nandflash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,248 +0,0 @@
-/*
-*  Copyright (C) 2005 - 2007 by Basler Vision Technologies AG
-*  Author: Thomas Koeller <thomas.koeller.qbaslerweb.com>
-*  Original code by Thies Moeller <thies.moeller@baslerweb.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/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/rm9k-ocd.h>
-
-#include <excite_nandflash.h>
-
-#define EXCITE_NANDFLASH_VERSION "0.1"
-
-/* I/O register offsets */
-#define EXCITE_NANDFLASH_DATA_BYTE   0x00
-#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c
-#define EXCITE_NANDFLASH_ADDR_BYTE   0x10
-#define EXCITE_NANDFLASH_CMD_BYTE    0x14
-
-/* prefix for debug output */
-static const char module_id[] = "excite_nandflash";
-
-/*
- * partition definition
- */
-static const struct mtd_partition partition_info[] = {
-	{
-		.name = "eXcite RootFS",
-		.offset = 0,
-		.size = MTDPART_SIZ_FULL
-	}
-};
-
-static inline const struct resource *
-excite_nand_get_resource(struct platform_device *d, unsigned long flags,
-			 const char *basename)
-{
-	char buf[80];
-
-	if (snprintf(buf, sizeof buf, "%s_%u", basename, d->id) >= sizeof buf)
-		return NULL;
-	return platform_get_resource_byname(d, flags, buf);
-}
-
-static inline void __iomem *
-excite_nand_map_regs(struct platform_device *d, const char *basename)
-{
-	void *result = NULL;
-	const struct resource *const r =
-	    excite_nand_get_resource(d, IORESOURCE_MEM, basename);
-
-	if (r)
-		result = ioremap_nocache(r->start, r->end + 1 - r->start);
-	return result;
-}
-
-/* controller and mtd information */
-struct excite_nand_drvdata {
-	struct mtd_info board_mtd;
-	struct nand_chip board_chip;
-	void __iomem *regs;
-	void __iomem *tgt;
-};
-
-/* Control function */
-static void excite_nand_control(struct mtd_info *mtd, int cmd,
-				       unsigned int ctrl)
-{
-	struct excite_nand_drvdata * const d =
-	    container_of(mtd, struct excite_nand_drvdata, board_mtd);
-
-	switch (ctrl) {
-	case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
-		d->tgt = d->regs + EXCITE_NANDFLASH_CMD_BYTE;
-		break;
-	case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
-		d->tgt = d->regs + EXCITE_NANDFLASH_ADDR_BYTE;
-		break;
-	case NAND_CTRL_CHANGE | NAND_NCE:
-		d->tgt = d->regs + EXCITE_NANDFLASH_DATA_BYTE;
-		break;
-	}
-
-	if (cmd != NAND_CMD_NONE)
-		__raw_writeb(cmd, d->tgt);
-}
-
-/* Return 0 if flash is busy, 1 if ready */
-static int excite_nand_devready(struct mtd_info *mtd)
-{
-	struct excite_nand_drvdata * const drvdata =
-	    container_of(mtd, struct excite_nand_drvdata, board_mtd);
-
-	return __raw_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE);
-}
-
-/*
- * Called by device layer to remove the driver.
- * The binding to the mtd and all allocated
- * resources are released.
- */
-static int __exit excite_nand_remove(struct platform_device *dev)
-{
-	struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
-
-	platform_set_drvdata(dev, NULL);
-
-	if (unlikely(!this)) {
-		printk(KERN_ERR "%s: called %s without private data!!",
-		       module_id, __func__);
-		return -EINVAL;
-	}
-
-	/* first thing we need to do is release our mtd
-	 * then go through freeing the resource used
-	 */
-	nand_release(&this->board_mtd);
-
-	/* free the common resources */
-	iounmap(this->regs);
-	kfree(this);
-
-	DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id);
-	return 0;
-}
-
-/*
- * Called by device layer when it finds a device matching
- * one our driver can handle. This code checks to see if
- * it can allocate all necessary resources then calls the
- * nand layer to look for devices.
-*/
-static int __init excite_nand_probe(struct platform_device *pdev)
-{
-	struct excite_nand_drvdata *drvdata;	/* private driver data */
-	struct nand_chip *board_chip;	/* private flash chip data */
-	struct mtd_info *board_mtd;	/* mtd info for this board */
-	int scan_res;
-
-	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
-	if (unlikely(!drvdata)) {
-		printk(KERN_ERR "%s: no memory for drvdata\n",
-		       module_id);
-		return -ENOMEM;
-	}
-
-	/* bind private data into driver */
-	platform_set_drvdata(pdev, drvdata);
-
-	/* allocate and map the resource */
-	drvdata->regs =
-		excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
-
-	if (unlikely(!drvdata->regs)) {
-		printk(KERN_ERR "%s: cannot reserve register region\n",
-		       module_id);
-		kfree(drvdata);
-		return -ENXIO;
-	}
-	
-	drvdata->tgt = drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
-
-	/* initialise our chip */
-	board_chip = &drvdata->board_chip;
-	board_chip->IO_ADDR_R = board_chip->IO_ADDR_W =
-		drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
-	board_chip->cmd_ctrl = excite_nand_control;
-	board_chip->dev_ready = excite_nand_devready;
-	board_chip->chip_delay = 25;
-	board_chip->ecc.mode = NAND_ECC_SOFT;
-
-	/* link chip to mtd */
-	board_mtd = &drvdata->board_mtd;
-	board_mtd->priv = board_chip;
-
-	DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id);
-	scan_res = nand_scan(&drvdata->board_mtd, 1);
-
-	if (likely(!scan_res)) {
-		DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id);
-		add_mtd_partitions(&drvdata->board_mtd, partition_info,
-				   ARRAY_SIZE(partition_info));
-	} else {
-		iounmap(drvdata->regs);
-		kfree(drvdata);
-		printk(KERN_ERR "%s: device scan failed\n", module_id);
-		return -EIO;
-	}
-	return 0;
-}
-
-static struct platform_driver excite_nand_driver = {
-	.driver = {
-		.name = "excite_nand",
-		.owner		= THIS_MODULE,
-	},
-	.probe = excite_nand_probe,
-	.remove = __devexit_p(excite_nand_remove)
-};
-
-static int __init excite_nand_init(void)
-{
-	pr_info("Basler eXcite nand flash driver Version "
-		EXCITE_NANDFLASH_VERSION "\n");
-	return platform_driver_register(&excite_nand_driver);
-}
-
-static void __exit excite_nand_exit(void)
-{
-	platform_driver_unregister(&excite_nand_driver);
-}
-
-module_init(excite_nand_init);
-module_exit(excite_nand_exit);
-
-MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
-MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(EXCITE_NANDFLASH_VERSION)
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/fsl_elbc_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_elbc_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/fsl_elbc_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_elbc_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -237,12 +237,15 @@ static int fsl_elbc_run_command(struct m
 
 	ctrl->use_mdr = 0;
 
-	dev_vdbg(ctrl->dev,
-	         "fsl_elbc_run_command: stat=%08x mdr=%08x fmr=%08x\n",
-	         ctrl->status, ctrl->mdr, in_be32(&lbc->fmr));
+	if (ctrl->status != LTESR_CC) {
+		dev_info(ctrl->dev,
+		         "command failed: fir %x fcr %x status %x mdr %x\n",
+		         in_be32(&lbc->fir), in_be32(&lbc->fcr),
+		         ctrl->status, ctrl->mdr);
+		return -EIO;
+	}
 
-	/* returns 0 on success otherwise non-zero) */
-	return ctrl->status == LTESR_CC ? 0 : -EIO;
+	return 0;
 }
 
 static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
@@ -253,17 +256,17 @@ static void fsl_elbc_do_read(struct nand
 
 	if (priv->page_size) {
 		out_be32(&lbc->fir,
-		         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+		         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 		         (FIR_OP_CA  << FIR_OP1_SHIFT) |
 		         (FIR_OP_PA  << FIR_OP2_SHIFT) |
-		         (FIR_OP_CW1 << FIR_OP3_SHIFT) |
+		         (FIR_OP_CM1 << FIR_OP3_SHIFT) |
 		         (FIR_OP_RBW << FIR_OP4_SHIFT));
 
 		out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
 		                    (NAND_CMD_READSTART << FCR_CMD1_SHIFT));
 	} else {
 		out_be32(&lbc->fir,
-		         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+		         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 		         (FIR_OP_CA  << FIR_OP1_SHIFT) |
 		         (FIR_OP_PA  << FIR_OP2_SHIFT) |
 		         (FIR_OP_RBW << FIR_OP3_SHIFT));
@@ -332,7 +335,7 @@ static void fsl_elbc_cmdfunc(struct mtd_
 	case NAND_CMD_READID:
 		dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
 
-		out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+		out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 		                    (FIR_OP_UA  << FIR_OP1_SHIFT) |
 		                    (FIR_OP_RBW << FIR_OP2_SHIFT));
 		out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
@@ -359,16 +362,20 @@ static void fsl_elbc_cmdfunc(struct mtd_
 		dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n");
 
 		out_be32(&lbc->fir,
-		         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+		         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 		         (FIR_OP_PA  << FIR_OP1_SHIFT) |
-		         (FIR_OP_CM1 << FIR_OP2_SHIFT));
+		         (FIR_OP_CM2 << FIR_OP2_SHIFT) |
+		         (FIR_OP_CW1 << FIR_OP3_SHIFT) |
+		         (FIR_OP_RS  << FIR_OP4_SHIFT));
 
 		out_be32(&lbc->fcr,
 		         (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) |
-		         (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT));
+		         (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
+		         (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT));
 
 		out_be32(&lbc->fbcr, 0);
 		ctrl->read_bytes = 0;
+		ctrl->use_mdr = 1;
 
 		fsl_elbc_run_command(mtd);
 		return;
@@ -383,40 +390,41 @@ static void fsl_elbc_cmdfunc(struct mtd_
 
 		ctrl->column = column;
 		ctrl->oob = 0;
+		ctrl->use_mdr = 1;
 
-		if (priv->page_size) {
-			fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) |
-			      (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT);
+		fcr = (NAND_CMD_STATUS   << FCR_CMD1_SHIFT) |
+		      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
+		      (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
 
+		if (priv->page_size) {
 			out_be32(&lbc->fir,
-			         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+			         (FIR_OP_CM2 << FIR_OP0_SHIFT) |
 			         (FIR_OP_CA  << FIR_OP1_SHIFT) |
 			         (FIR_OP_PA  << FIR_OP2_SHIFT) |
 			         (FIR_OP_WB  << FIR_OP3_SHIFT) |
-			         (FIR_OP_CW1 << FIR_OP4_SHIFT));
+			         (FIR_OP_CM3 << FIR_OP4_SHIFT) |
+			         (FIR_OP_CW1 << FIR_OP5_SHIFT) |
+			         (FIR_OP_RS  << FIR_OP6_SHIFT));
 		} else {
-			fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) |
-			      (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
-
 			out_be32(&lbc->fir,
-			         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+			         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
 			         (FIR_OP_CM2 << FIR_OP1_SHIFT) |
 			         (FIR_OP_CA  << FIR_OP2_SHIFT) |
 			         (FIR_OP_PA  << FIR_OP3_SHIFT) |
 			         (FIR_OP_WB  << FIR_OP4_SHIFT) |
-			         (FIR_OP_CW1 << FIR_OP5_SHIFT));
+			         (FIR_OP_CM3 << FIR_OP5_SHIFT) |
+			         (FIR_OP_CW1 << FIR_OP6_SHIFT) |
+			         (FIR_OP_RS  << FIR_OP7_SHIFT));
 
 			if (column >= mtd->writesize) {
 				/* OOB area --> READOOB */
 				column -= mtd->writesize;
 				fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
 				ctrl->oob = 1;
-			} else if (column < 256) {
+			} else {
+				WARN_ON(column != 0);
 				/* First 256 bytes --> READ0 */
 				fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
-			} else {
-				/* Second 256 bytes --> READ1 */
-				fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT;
 			}
 		}
 
@@ -628,22 +636,6 @@ static int fsl_elbc_wait(struct mtd_info
 {
 	struct fsl_elbc_mtd *priv = chip->priv;
 	struct fsl_elbc_ctrl *ctrl = priv->ctrl;
-	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
-
-	if (ctrl->status != LTESR_CC)
-		return NAND_STATUS_FAIL;
-
-	/* Use READ_STATUS command, but wait for the device to be ready */
-	ctrl->use_mdr = 0;
-	out_be32(&lbc->fir,
-	         (FIR_OP_CW0 << FIR_OP0_SHIFT) |
-	         (FIR_OP_RBW << FIR_OP1_SHIFT));
-	out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT);
-	out_be32(&lbc->fbcr, 1);
-	set_addr(mtd, 0, 0, 0);
-	ctrl->read_bytes = 1;
-
-	fsl_elbc_run_command(mtd);
 
 	if (ctrl->status != LTESR_CC)
 		return NAND_STATUS_FAIL;
@@ -651,8 +643,7 @@ static int fsl_elbc_wait(struct mtd_info
 	/* The chip always seems to report that it is
 	 * write-protected, even when it is not.
 	 */
-	setbits8(ctrl->addr, NAND_STATUS_WP);
-	return fsl_elbc_read_byte(mtd);
+	return (ctrl->mdr & 0xff) | NAND_STATUS_WP;
 }
 
 static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
@@ -946,6 +937,13 @@ static int __devinit fsl_elbc_ctrl_init(
 {
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
+	/*
+	 * NAND transactions can tie up the bus for a long time, so set the
+	 * bus timeout to max by clearing LBCR[BMT] (highest base counter
+	 * value) and setting LBCR[BMTPS] to the highest prescaler value.
+	 */
+	clrsetbits_be32(&lbc->lbcr, LBCR_BMT, 15);
+
 	/* clear event registers */
 	setbits32(&lbc->ltesr, LTESR_NAND_MASK);
 	out_be32(&lbc->lteatr, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/fsl_upm.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_upm.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/fsl_upm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/fsl_upm.c	2010-02-24 13:52:17.000000000 -0500
@@ -112,7 +112,7 @@ static void fun_select_chip(struct mtd_i
 
 	if (mchip_nr == -1) {
 		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
-	} else if (mchip_nr >= 0) {
+	} else if (mchip_nr >= 0 && mchip_nr < NAND_MAX_CHIPS) {
 		fun->mchip_number = mchip_nr;
 		chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
 		chip->IO_ADDR_W = chip->IO_ADDR_R;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/nand/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/nand/Kconfig
-
 menuconfig MTD_NAND
 	tristate "NAND Device Support"
 	depends on MTD
@@ -203,6 +201,22 @@ config MTD_NAND_S3C2410_CLKSTOP
 	  when the is NAND chip selected or released, but will save
 	  approximately 5mA of power when there is nothing happening.
 
+config MTD_NAND_BCM_UMI
+	tristate "NAND Flash support for BCM Reference Boards"
+	depends on ARCH_BCMRING && MTD_NAND
+	help
+	  This enables the NAND flash controller on the BCM UMI block.
+
+	  No board specfic support is done by this driver, each board
+	  must advertise a platform_device for the driver to attach.
+
+config MTD_NAND_BCM_UMI_HWCS
+	bool "BCM UMI NAND Hardware CS"
+	depends on MTD_NAND_BCM_UMI
+	help
+	  Enable the use of the BCM UMI block's internal CS using NAND.
+	  This should only be used if you know the external NAND CS can toggle.
+
 config MTD_NAND_DISKONCHIP
 	tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
@@ -277,14 +291,6 @@ config MTD_NAND_SHARPSL
 	tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
 	depends on ARCH_PXA
 
-config MTD_NAND_BASLER_EXCITE
-	tristate  "Support for NAND Flash on Basler eXcite"
-	depends on BASLER_EXCITE
-	help
-          This enables the driver for the NAND flash device found on the
-          Basler eXcite Smart Camera. If built as a module, the driver
-          will be named excite_nandflash.
-
 config MTD_NAND_CAFE
 	tristate "NAND support for OLPC CAFÉ chip"
 	depends on PCI
@@ -358,7 +364,7 @@ endchoice
 
 config MTD_NAND_PXA3xx
 	tristate "Support for NAND flash devices on PXA3xx"
-	depends on MTD_NAND && PXA3xx
+	depends on MTD_NAND && (PXA3xx || ARCH_MMP)
 	help
 	  This enables the driver for the NAND flash device found on
 	  PXA3xx processors
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/Makefile linux-libre-2.6.33-gnu1/drivers/mtd/nand/Makefile
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,6 @@ obj-$(CONFIG_MTD_NAND_ATMEL)		+= atmel_n
 obj-$(CONFIG_MTD_NAND_GPIO)		+= gpio.o
 obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2.o
 obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
-obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)	+= excite_nandflash.o
 obj-$(CONFIG_MTD_NAND_PXA3xx)		+= pxa3xx_nand.o
 obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
 obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
@@ -42,5 +41,6 @@ obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socr
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_W90P910)		+= w90p910_nand.o
 obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
+obj-$(CONFIG_MTD_NAND_BCM_UMI)		+= bcm_umi_nand.o nand_bcm_umi.o
 
 nand-objs := nand_base.o nand_bbt.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/mxc_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/mxc_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/mxc_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/mxc_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,9 +33,13 @@
 
 #include <asm/mach/flash.h>
 #include <mach/mxc_nand.h>
+#include <mach/hardware.h>
 
 #define DRIVER_NAME "mxc_nand"
 
+#define nfc_is_v21()		(cpu_is_mx25() || cpu_is_mx35())
+#define nfc_is_v1()		(cpu_is_mx31() || cpu_is_mx27())
+
 /* Addresses for NFC registers */
 #define NFC_BUF_SIZE		0xE00
 #define NFC_BUF_ADDR		0xE04
@@ -46,24 +50,14 @@
 #define NFC_RSLTMAIN_AREA	0xE0E
 #define NFC_RSLTSPARE_AREA	0xE10
 #define NFC_WRPROT		0xE12
-#define NFC_UNLOCKSTART_BLKADDR	0xE14
-#define NFC_UNLOCKEND_BLKADDR	0xE16
+#define NFC_V1_UNLOCKSTART_BLKADDR	0xe14
+#define NFC_V1_UNLOCKEND_BLKADDR	0xe16
+#define NFC_V21_UNLOCKSTART_BLKADDR	0xe20
+#define NFC_V21_UNLOCKEND_BLKADDR	0xe22
 #define NFC_NF_WRPRST		0xE18
 #define NFC_CONFIG1		0xE1A
 #define NFC_CONFIG2		0xE1C
 
-/* Addresses for NFC RAM BUFFER Main area 0 */
-#define MAIN_AREA0		0x000
-#define MAIN_AREA1		0x200
-#define MAIN_AREA2		0x400
-#define MAIN_AREA3		0x600
-
-/* Addresses for NFC SPARE BUFFER Spare area 0 */
-#define SPARE_AREA0		0x800
-#define SPARE_AREA1		0x810
-#define SPARE_AREA2		0x820
-#define SPARE_AREA3		0x830
-
 /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
  * for Command operation */
 #define NFC_CMD            0x1
@@ -106,48 +100,66 @@ struct mxc_nand_host {
 	struct mtd_partition	*parts;
 	struct device		*dev;
 
+	void			*spare0;
+	void			*main_area0;
+	void			*main_area1;
+
+	void __iomem		*base;
 	void __iomem		*regs;
-	int			spare_only;
 	int			status_request;
-	int			pagesize_2k;
-	uint16_t		col_addr;
 	struct clk		*clk;
 	int			clk_act;
 	int			irq;
 
 	wait_queue_head_t	irq_waitq;
-};
-
-/* Define delays in microsec for NAND device operations */
-#define TROP_US_DELAY   2000
-/* Macros to get byte and bit positions of ECC */
-#define COLPOS(x)  ((x) >> 3)
-#define BITPOS(x) ((x) & 0xf)
 
-/* Define single bit Error positions in Main & Spare area */
-#define MAIN_SINGLEBIT_ERROR 0x4
-#define SPARE_SINGLEBIT_ERROR 0x1
-
-/* OOB placement block for use with hardware ecc generation */
-static struct nand_ecclayout nand_hw_eccoob_8 = {
-	.eccbytes = 5,
-	.eccpos = {6, 7, 8, 9, 10},
-	.oobfree = {{0, 5}, {11, 5}, }
+	uint8_t			*data_buf;
+	unsigned int		buf_start;
+	int			spare_len;
 };
 
-static struct nand_ecclayout nand_hw_eccoob_16 = {
+/* OOB placement block for use with hardware ecc generation */
+static struct nand_ecclayout nandv1_hw_eccoob_smallpage = {
 	.eccbytes = 5,
 	.eccpos = {6, 7, 8, 9, 10},
-	.oobfree = {{0, 5}, {11, 5}, }
+	.oobfree = {{0, 5}, {12, 4}, }
 };
 
-static struct nand_ecclayout nand_hw_eccoob_64 = {
+static struct nand_ecclayout nandv1_hw_eccoob_largepage = {
 	.eccbytes = 20,
 	.eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26,
 		   38, 39, 40, 41, 42, 54, 55, 56, 57, 58},
 	.oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, }
 };
 
+/* OOB description for 512 byte pages with 16 byte OOB */
+static struct nand_ecclayout nandv2_hw_eccoob_smallpage = {
+	.eccbytes = 1 * 9,
+	.eccpos = {
+		 7,  8,  9, 10, 11, 12, 13, 14, 15
+	},
+	.oobfree = {
+		{.offset = 0, .length = 5}
+	}
+};
+
+/* OOB description for 2048 byte pages with 64 byte OOB */
+static struct nand_ecclayout nandv2_hw_eccoob_largepage = {
+	.eccbytes = 4 * 9,
+	.eccpos = {
+		 7,  8,  9, 10, 11, 12, 13, 14, 15,
+		23, 24, 25, 26, 27, 28, 29, 30, 31,
+		39, 40, 41, 42, 43, 44, 45, 46, 47,
+		55, 56, 57, 58, 59, 60, 61, 62, 63
+	},
+	.oobfree = {
+		{.offset = 2, .length = 4},
+		{.offset = 16, .length = 7},
+		{.offset = 32, .length = 7},
+		{.offset = 48, .length = 7}
+	}
+};
+
 #ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL };
 #endif
@@ -170,10 +182,10 @@ static irqreturn_t mxc_nfc_irq(int irq,
 /* This function polls the NANDFC to wait for the basic operation to
  * complete by checking the INT bit of config2 register.
  */
-static void wait_op_done(struct mxc_nand_host *host, int max_retries,
-				uint16_t param, int useirq)
+static void wait_op_done(struct mxc_nand_host *host, int useirq)
 {
 	uint32_t tmp;
+	int max_retries = 2000;
 
 	if (useirq) {
 		if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
@@ -200,8 +212,8 @@ static void wait_op_done(struct mxc_nand
 			udelay(1);
 		}
 		if (max_retries < 0)
-			DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
-			      __func__, param);
+			DEBUG(MTD_DEBUG_LEVEL0, "%s: INT not set\n",
+			      __func__);
 	}
 }
 
@@ -215,7 +227,7 @@ static void send_cmd(struct mxc_nand_hos
 	writew(NFC_CMD, host->regs + NFC_CONFIG2);
 
 	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, cmd, useirq);
+	wait_op_done(host, useirq);
 }
 
 /* This function sends an address (or partial address) to the
@@ -229,82 +241,47 @@ static void send_addr(struct mxc_nand_ho
 	writew(NFC_ADDR, host->regs + NFC_CONFIG2);
 
 	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, addr, islast);
+	wait_op_done(host, islast);
 }
 
-/* This function requests the NANDFC to initate the transfer
- * of data currently in the NANDFC RAM buffer to the NAND device. */
-static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
-			int spare_only)
+static void send_page(struct mtd_info *mtd, unsigned int ops)
 {
-	DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only);
-
-	/* NANDFC buffer 0 is used for page read/write */
-	writew(buf_id, host->regs + NFC_BUF_ADDR);
-
-	/* Configure spare or page+spare access */
-	if (!host->pagesize_2k) {
-		uint16_t config1 = readw(host->regs + NFC_CONFIG1);
-		if (spare_only)
-			config1 |= NFC_SP_EN;
-		else
-			config1 &= ~(NFC_SP_EN);
-		writew(config1, host->regs + NFC_CONFIG1);
-	}
+	struct nand_chip *nand_chip = mtd->priv;
+	struct mxc_nand_host *host = nand_chip->priv;
+	int bufs, i;
 
-	writew(NFC_INPUT, host->regs + NFC_CONFIG2);
+	if (nfc_is_v1() && mtd->writesize > 512)
+		bufs = 4;
+	else
+		bufs = 1;
 
-	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, spare_only, true);
-}
+	for (i = 0; i < bufs; i++) {
 
-/* Requests NANDFC to initated the transfer of data from the
- * NAND device into in the NANDFC ram buffer. */
-static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
-		int spare_only)
-{
-	DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
+		/* NANDFC buffer 0 is used for page read/write */
+		writew(i, host->regs + NFC_BUF_ADDR);
 
-	/* NANDFC buffer 0 is used for page read/write */
-	writew(buf_id, host->regs + NFC_BUF_ADDR);
+		writew(ops, host->regs + NFC_CONFIG2);
 
-	/* Configure spare or page+spare access */
-	if (!host->pagesize_2k) {
-		uint32_t config1 = readw(host->regs + NFC_CONFIG1);
-		if (spare_only)
-			config1 |= NFC_SP_EN;
-		else
-			config1 &= ~NFC_SP_EN;
-		writew(config1, host->regs + NFC_CONFIG1);
+		/* Wait for operation to complete */
+		wait_op_done(host, true);
 	}
-
-	writew(NFC_OUTPUT, host->regs + NFC_CONFIG2);
-
-	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, spare_only, true);
 }
 
 /* Request the NANDFC to perform a read of the NAND device ID. */
 static void send_read_id(struct mxc_nand_host *host)
 {
 	struct nand_chip *this = &host->nand;
-	uint16_t tmp;
 
 	/* NANDFC buffer 0 is used for device ID output */
 	writew(0x0, host->regs + NFC_BUF_ADDR);
 
-	/* Read ID into main buffer */
-	tmp = readw(host->regs + NFC_CONFIG1);
-	tmp &= ~NFC_SP_EN;
-	writew(tmp, host->regs + NFC_CONFIG1);
-
 	writew(NFC_ID, host->regs + NFC_CONFIG2);
 
 	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, 0, true);
+	wait_op_done(host, true);
 
 	if (this->options & NAND_BUSWIDTH_16) {
-		void __iomem *main_buf = host->regs + MAIN_AREA0;
+		void __iomem *main_buf = host->main_area0;
 		/* compress the ID info */
 		writeb(readb(main_buf + 2), main_buf + 1);
 		writeb(readb(main_buf + 4), main_buf + 2);
@@ -312,15 +289,16 @@ static void send_read_id(struct mxc_nand
 		writeb(readb(main_buf + 8), main_buf + 4);
 		writeb(readb(main_buf + 10), main_buf + 5);
 	}
+	memcpy(host->data_buf, host->main_area0, 16);
 }
 
 /* This function requests the NANDFC to perform a read of the
  * NAND device status and returns the current status. */
 static uint16_t get_dev_status(struct mxc_nand_host *host)
 {
-	void __iomem *main_buf = host->regs + MAIN_AREA1;
+	void __iomem *main_buf = host->main_area1;
 	uint32_t store;
-	uint16_t ret, tmp;
+	uint16_t ret;
 	/* Issue status request to NAND device */
 
 	/* store the main area1 first word, later do recovery */
@@ -329,15 +307,10 @@ static uint16_t get_dev_status(struct mx
 	 * corruption of read/write buffer on status requests. */
 	writew(1, host->regs + NFC_BUF_ADDR);
 
-	/* Read status into main buffer */
-	tmp = readw(host->regs + NFC_CONFIG1);
-	tmp &= ~NFC_SP_EN;
-	writew(tmp, host->regs + NFC_CONFIG1);
-
 	writew(NFC_STATUS, host->regs + NFC_CONFIG2);
 
 	/* Wait for operation to complete */
-	wait_op_done(host, TROP_US_DELAY, 0, true);
+	wait_op_done(host, true);
 
 	/* Status is placed in first word of main buffer */
 	/* get status, then recovery area 1 data */
@@ -397,32 +370,14 @@ static u_char mxc_nand_read_byte(struct
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	uint8_t ret = 0;
-	uint16_t col, rd_word;
-	uint16_t __iomem *main_buf = host->regs + MAIN_AREA0;
-	uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0;
+	uint8_t ret;
 
 	/* Check for status request */
 	if (host->status_request)
 		return get_dev_status(host) & 0xFF;
 
-	/* Get column for 16-bit access */
-	col = host->col_addr >> 1;
-
-	/* If we are accessing the spare region */
-	if (host->spare_only)
-		rd_word = readw(&spare_buf[col]);
-	else
-		rd_word = readw(&main_buf[col]);
-
-	/* Pick upper/lower byte of word from RAM buffer */
-	if (host->col_addr & 0x1)
-		ret = (rd_word >> 8) & 0xFF;
-	else
-		ret = rd_word & 0xFF;
-
-	/* Update saved column address */
-	host->col_addr++;
+	ret = *(uint8_t *)(host->data_buf + host->buf_start);
+	host->buf_start++;
 
 	return ret;
 }
@@ -431,33 +386,10 @@ static uint16_t mxc_nand_read_word(struc
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	uint16_t col, rd_word, ret;
-	uint16_t __iomem *p;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "mxc_nand_read_word(col = %d)\n", host->col_addr);
-
-	col = host->col_addr;
-	/* Adjust saved column address */
-	if (col < mtd->writesize && host->spare_only)
-		col += mtd->writesize;
-
-	if (col < mtd->writesize)
-		p = (host->regs + MAIN_AREA0) + (col >> 1);
-	else
-		p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1);
-
-	if (col & 1) {
-		rd_word = readw(p);
-		ret = (rd_word >> 8) & 0xff;
-		rd_word = readw(&p[1]);
-		ret |= (rd_word << 8) & 0xff00;
-
-	} else
-		ret = readw(p);
+	uint16_t ret;
 
-	/* Update saved column address */
-	host->col_addr = col + 2;
+	ret = *(uint16_t *)(host->data_buf + host->buf_start);
+	host->buf_start += 2;
 
 	return ret;
 }
@@ -470,94 +402,14 @@ static void mxc_nand_write_buf(struct mt
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	int n, col, i = 0;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
-	      len);
-
-	col = host->col_addr;
-
-	/* Adjust saved column address */
-	if (col < mtd->writesize && host->spare_only)
-		col += mtd->writesize;
-
-	n = mtd->writesize + mtd->oobsize - col;
-	n = min(len, n);
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
-
-	while (n) {
-		void __iomem *p;
-
-		if (col < mtd->writesize)
-			p = host->regs + MAIN_AREA0 + (col & ~3);
-		else
-			p = host->regs + SPARE_AREA0 -
-						mtd->writesize + (col & ~3);
-
-		DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
-		      __LINE__, p);
-
-		if (((col | (int)&buf[i]) & 3) || n < 16) {
-			uint32_t data = 0;
-
-			if (col & 3 || n < 4)
-				data = readl(p);
-
-			switch (col & 3) {
-			case 0:
-				if (n) {
-					data = (data & 0xffffff00) |
-					    (buf[i++] << 0);
-					n--;
-					col++;
-				}
-			case 1:
-				if (n) {
-					data = (data & 0xffff00ff) |
-					    (buf[i++] << 8);
-					n--;
-					col++;
-				}
-			case 2:
-				if (n) {
-					data = (data & 0xff00ffff) |
-					    (buf[i++] << 16);
-					n--;
-					col++;
-				}
-			case 3:
-				if (n) {
-					data = (data & 0x00ffffff) |
-					    (buf[i++] << 24);
-					n--;
-					col++;
-				}
-			}
-
-			writel(data, p);
-		} else {
-			int m = mtd->writesize - col;
-
-			if (col >= mtd->writesize)
-				m += mtd->oobsize;
+	u16 col = host->buf_start;
+	int n = mtd->oobsize + mtd->writesize - col;
 
-			m = min(n, m) & ~3;
+	n = min(n, len);
 
-			DEBUG(MTD_DEBUG_LEVEL3,
-			      "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
-			      __func__,  __LINE__, n, m, i, col);
+	memcpy(host->data_buf + col, buf, n);
 
-			memcpy(p, &buf[i], m);
-			col += m;
-			i += m;
-			n -= m;
-		}
-	}
-	/* Update saved column address */
-	host->col_addr = col;
+	host->buf_start += n;
 }
 
 /* Read the data buffer from the NAND Flash. To read the data from NAND
@@ -568,75 +420,14 @@ static void mxc_nand_read_buf(struct mtd
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
-	int n, col, i = 0;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
-
-	col = host->col_addr;
-
-	/* Adjust saved column address */
-	if (col < mtd->writesize && host->spare_only)
-		col += mtd->writesize;
-
-	n = mtd->writesize + mtd->oobsize - col;
-	n = min(len, n);
-
-	while (n) {
-		void __iomem *p;
-
-		if (col < mtd->writesize)
-			p = host->regs + MAIN_AREA0 + (col & ~3);
-		else
-			p = host->regs + SPARE_AREA0 -
-					mtd->writesize + (col & ~3);
-
-		if (((col | (int)&buf[i]) & 3) || n < 16) {
-			uint32_t data;
-
-			data = readl(p);
-			switch (col & 3) {
-			case 0:
-				if (n) {
-					buf[i++] = (uint8_t) (data);
-					n--;
-					col++;
-				}
-			case 1:
-				if (n) {
-					buf[i++] = (uint8_t) (data >> 8);
-					n--;
-					col++;
-				}
-			case 2:
-				if (n) {
-					buf[i++] = (uint8_t) (data >> 16);
-					n--;
-					col++;
-				}
-			case 3:
-				if (n) {
-					buf[i++] = (uint8_t) (data >> 24);
-					n--;
-					col++;
-				}
-			}
-		} else {
-			int m = mtd->writesize - col;
+	u16 col = host->buf_start;
+	int n = mtd->oobsize + mtd->writesize - col;
 
-			if (col >= mtd->writesize)
-				m += mtd->oobsize;
+	n = min(n, len);
 
-			m = min(n, m) & ~3;
-			memcpy(&buf[i], p, m);
-			col += m;
-			i += m;
-			n -= m;
-		}
-	}
-	/* Update saved column address */
-	host->col_addr = col;
+	memcpy(buf, host->data_buf + col, len);
 
+	host->buf_start += len;
 }
 
 /* Used by the upper layer to verify the data in NAND Flash
@@ -654,23 +445,6 @@ static void mxc_nand_select_chip(struct
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
 
-#ifdef CONFIG_MTD_NAND_MXC_FORCE_CE
-	if (chip > 0) {
-		DEBUG(MTD_DEBUG_LEVEL0,
-		      "ERROR:  Illegal chip select (chip = %d)\n", chip);
-		return;
-	}
-
-	if (chip == -1) {
-		writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE,
-				host->regs + NFC_CONFIG1);
-		return;
-	}
-
-	writew(readw(host->regs + NFC_CONFIG1) | NFC_CE,
-			host->regs + NFC_CONFIG1);
-#endif
-
 	switch (chip) {
 	case -1:
 		/* Disable the NFC clock */
@@ -692,94 +466,40 @@ static void mxc_nand_select_chip(struct
 	}
 }
 
-/* Used by the upper layer to write command to NAND Flash for
- * different operations to be carried out on NAND Flash */
-static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
-				int column, int page_addr)
+/*
+ * Function to transfer data to/from spare area.
+ */
+static void copy_spare(struct mtd_info *mtd, bool bfrom)
 {
-	struct nand_chip *nand_chip = mtd->priv;
-	struct mxc_nand_host *host = nand_chip->priv;
-	int useirq = true;
-
-	DEBUG(MTD_DEBUG_LEVEL3,
-	      "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
-	      command, column, page_addr);
-
-	/* Reset command state information */
-	host->status_request = false;
-
-	/* Command pre-processing step */
-	switch (command) {
-
-	case NAND_CMD_STATUS:
-		host->col_addr = 0;
-		host->status_request = true;
-		break;
-
-	case NAND_CMD_READ0:
-		host->col_addr = column;
-		host->spare_only = false;
-		useirq = false;
-		break;
-
-	case NAND_CMD_READOOB:
-		host->col_addr = column;
-		host->spare_only = true;
-		useirq = false;
-		if (host->pagesize_2k)
-			command = NAND_CMD_READ0; /* only READ0 is valid */
-		break;
-
-	case NAND_CMD_SEQIN:
-		if (column >= mtd->writesize) {
-			/*
-			 * FIXME: before send SEQIN command for write OOB,
-			 * We must read one page out.
-			 * For K9F1GXX has no READ1 command to set current HW
-			 * pointer to spare area, we must write the whole page
-			 * including OOB together.
-			 */
-			if (host->pagesize_2k)
-				/* call ourself to read a page */
-				mxc_nand_command(mtd, NAND_CMD_READ0, 0,
-						page_addr);
-
-			host->col_addr = column - mtd->writesize;
-			host->spare_only = true;
-
-			/* Set program pointer to spare region */
-			if (!host->pagesize_2k)
-				send_cmd(host, NAND_CMD_READOOB, false);
-		} else {
-			host->spare_only = false;
-			host->col_addr = column;
-
-			/* Set program pointer to page start */
-			if (!host->pagesize_2k)
-				send_cmd(host, NAND_CMD_READ0, false);
-		}
-		useirq = false;
-		break;
+	struct nand_chip *this = mtd->priv;
+	struct mxc_nand_host *host = this->priv;
+	u16 i, j;
+	u16 n = mtd->writesize >> 9;
+	u8 *d = host->data_buf + mtd->writesize;
+	u8 *s = host->spare0;
+	u16 t = host->spare_len;
 
-	case NAND_CMD_PAGEPROG:
-		send_prog_page(host, 0, host->spare_only);
+	j = (mtd->oobsize / n >> 1) << 1;
 
-		if (host->pagesize_2k) {
-			/* data in 4 areas datas */
-			send_prog_page(host, 1, host->spare_only);
-			send_prog_page(host, 2, host->spare_only);
-			send_prog_page(host, 3, host->spare_only);
-		}
+	if (bfrom) {
+		for (i = 0; i < n - 1; i++)
+			memcpy(d + i * j, s + i * t, j);
 
-		break;
+		/* the last section */
+		memcpy(d + i * j, s + i * t, mtd->oobsize - i * j);
+	} else {
+		for (i = 0; i < n - 1; i++)
+			memcpy(&s[i * t], &d[i * j], j);
 
-	case NAND_CMD_ERASE1:
-		useirq = false;
-		break;
+		/* the last section */
+		memcpy(&s[i * t], &d[i * j], mtd->oobsize - i * j);
 	}
+}
 
-	/* Write out the command to the device. */
-	send_cmd(host, command, useirq);
+static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct mxc_nand_host *host = nand_chip->priv;
 
 	/* Write out column address, if necessary */
 	if (column != -1) {
@@ -791,7 +511,7 @@ static void mxc_nand_command(struct mtd_
 		 * the full page.
 		 */
 		send_addr(host, 0, page_addr == -1);
-		if (host->pagesize_2k)
+		if (mtd->writesize > 512)
 			/* another col addr cycle for 2k page */
 			send_addr(host, 0, false);
 	}
@@ -801,7 +521,7 @@ static void mxc_nand_command(struct mtd_
 		/* paddr_0 - p_addr_7 */
 		send_addr(host, (page_addr & 0xff), false);
 
-		if (host->pagesize_2k) {
+		if (mtd->writesize > 512) {
 			if (mtd->size >= 0x10000000) {
 				/* paddr_8 - paddr_15 */
 				send_addr(host, (page_addr >> 8) & 0xff, false);
@@ -820,52 +540,136 @@ static void mxc_nand_command(struct mtd_
 				send_addr(host, (page_addr >> 8) & 0xff, true);
 		}
 	}
+}
 
-	/* Command post-processing step */
+/* Used by the upper layer to write command to NAND Flash for
+ * different operations to be carried out on NAND Flash */
+static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
+				int column, int page_addr)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct mxc_nand_host *host = nand_chip->priv;
+
+	DEBUG(MTD_DEBUG_LEVEL3,
+	      "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
+	      command, column, page_addr);
+
+	/* Reset command state information */
+	host->status_request = false;
+
+	/* Command pre-processing step */
 	switch (command) {
 
-	case NAND_CMD_RESET:
+	case NAND_CMD_STATUS:
+		host->buf_start = 0;
+		host->status_request = true;
+
+		send_cmd(host, command, true);
+		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
-	case NAND_CMD_READOOB:
 	case NAND_CMD_READ0:
-		if (host->pagesize_2k) {
-			/* send read confirm command */
+	case NAND_CMD_READOOB:
+		if (command == NAND_CMD_READ0)
+			host->buf_start = column;
+		else
+			host->buf_start = column + mtd->writesize;
+
+		if (mtd->writesize > 512)
+			command = NAND_CMD_READ0; /* only READ0 is valid */
+
+		send_cmd(host, command, false);
+		mxc_do_addr_cycle(mtd, column, page_addr);
+
+		if (mtd->writesize > 512)
 			send_cmd(host, NAND_CMD_READSTART, true);
-			/* read for each AREA */
-			send_read_page(host, 0, host->spare_only);
-			send_read_page(host, 1, host->spare_only);
-			send_read_page(host, 2, host->spare_only);
-			send_read_page(host, 3, host->spare_only);
-		} else
-			send_read_page(host, 0, host->spare_only);
+
+		send_page(mtd, NFC_OUTPUT);
+
+		memcpy(host->data_buf, host->main_area0, mtd->writesize);
+		copy_spare(mtd, true);
 		break;
 
-	case NAND_CMD_READID:
-		host->col_addr = 0;
-		send_read_id(host);
+	case NAND_CMD_SEQIN:
+		if (column >= mtd->writesize) {
+			/*
+			 * FIXME: before send SEQIN command for write OOB,
+			 * We must read one page out.
+			 * For K9F1GXX has no READ1 command to set current HW
+			 * pointer to spare area, we must write the whole page
+			 * including OOB together.
+			 */
+			if (mtd->writesize > 512)
+				/* call ourself to read a page */
+				mxc_nand_command(mtd, NAND_CMD_READ0, 0,
+						page_addr);
+
+			host->buf_start = column;
+
+			/* Set program pointer to spare region */
+			if (mtd->writesize == 512)
+				send_cmd(host, NAND_CMD_READOOB, false);
+		} else {
+			host->buf_start = column;
+
+			/* Set program pointer to page start */
+			if (mtd->writesize == 512)
+				send_cmd(host, NAND_CMD_READ0, false);
+		}
+
+		send_cmd(host, command, false);
+		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
 	case NAND_CMD_PAGEPROG:
+		memcpy(host->main_area0, host->data_buf, mtd->writesize);
+		copy_spare(mtd, false);
+		send_page(mtd, NFC_INPUT);
+		send_cmd(host, command, true);
+		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 
-	case NAND_CMD_STATUS:
+	case NAND_CMD_READID:
+		send_cmd(host, command, true);
+		mxc_do_addr_cycle(mtd, column, page_addr);
+		send_read_id(host);
+		host->buf_start = column;
 		break;
 
+	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE2:
+		send_cmd(host, command, false);
+		mxc_do_addr_cycle(mtd, column, page_addr);
+
 		break;
 	}
 }
 
-/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks. */
-static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+/*
+ * The generic flash bbt decriptors overlap with our ecc
+ * hardware, so define some i.MX specific ones.
+ */
+static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
 
-static struct nand_bbt_descr smallpage_memorybased = {
-	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = 5,
-	.len = 1,
-	.pattern = scan_ff_pattern
+static struct nand_bbt_descr bbt_main_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+	    | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs = 0,
+	.len = 4,
+	.veroffs = 4,
+	.maxblocks = 4,
+	.pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+	    | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs = 0,
+	.len = 4,
+	.veroffs = 4,
+	.maxblocks = 4,
+	.pattern = mirror_pattern,
 };
 
 static int __init mxcnd_probe(struct platform_device *pdev)
@@ -877,12 +681,16 @@ static int __init mxcnd_probe(struct pla
 	struct resource *res;
 	uint16_t tmp;
 	int err = 0, nr_parts = 0;
+	struct nand_ecclayout *oob_smallpage, *oob_largepage;
 
 	/* Allocate memory for MTD device structure and private data */
-	host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL);
+	host = kzalloc(sizeof(struct mxc_nand_host) + NAND_MAX_PAGESIZE +
+			NAND_MAX_OOBSIZE, GFP_KERNEL);
 	if (!host)
 		return -ENOMEM;
 
+	host->data_buf = (uint8_t *)(host + 1);
+
 	host->dev = &pdev->dev;
 	/* structures must be linked */
 	this = &host->nand;
@@ -890,7 +698,7 @@ static int __init mxcnd_probe(struct pla
 	mtd->priv = this;
 	mtd->owner = THIS_MODULE;
 	mtd->dev.parent = &pdev->dev;
-	mtd->name = "mxc_nand";
+	mtd->name = DRIVER_NAME;
 
 	/* 50 us command delay time */
 	this->chip_delay = 5;
@@ -920,62 +728,93 @@ static int __init mxcnd_probe(struct pla
 		goto eres;
 	}
 
-	host->regs = ioremap(res->start, res->end - res->start + 1);
-	if (!host->regs) {
+	host->base = ioremap(res->start, resource_size(res));
+	if (!host->base) {
 		err = -ENOMEM;
 		goto eres;
 	}
 
+	host->main_area0 = host->base;
+	host->main_area1 = host->base + 0x200;
+
+	if (nfc_is_v21()) {
+		host->regs = host->base + 0x1000;
+		host->spare0 = host->base + 0x1000;
+		host->spare_len = 64;
+		oob_smallpage = &nandv2_hw_eccoob_smallpage;
+		oob_largepage = &nandv2_hw_eccoob_largepage;
+	} else if (nfc_is_v1()) {
+		host->regs = host->base;
+		host->spare0 = host->base + 0x800;
+		host->spare_len = 16;
+		oob_smallpage = &nandv1_hw_eccoob_smallpage;
+		oob_largepage = &nandv1_hw_eccoob_largepage;
+	} else
+		BUG();
+
+	/* disable interrupt and spare enable */
 	tmp = readw(host->regs + NFC_CONFIG1);
 	tmp |= NFC_INT_MSK;
+	tmp &= ~NFC_SP_EN;
 	writew(tmp, host->regs + NFC_CONFIG1);
 
 	init_waitqueue_head(&host->irq_waitq);
 
 	host->irq = platform_get_irq(pdev, 0);
 
-	err = request_irq(host->irq, mxc_nfc_irq, 0, "mxc_nd", host);
+	err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
 	if (err)
 		goto eirq;
 
+	/* Reset NAND */
+	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+	/* preset operation */
+	/* Unlock the internal RAM Buffer */
+	writew(0x2, host->regs + NFC_CONFIG);
+
+	/* Blocks to be unlocked */
+	if (nfc_is_v21()) {
+		writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
+	        writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
+		this->ecc.bytes = 9;
+	} else if (nfc_is_v1()) {
+		writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
+	        writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
+		this->ecc.bytes = 3;
+	} else
+		BUG();
+
+	/* Unlock Block Command for given address range */
+	writew(0x4, host->regs + NFC_WRPROT);
+
+	this->ecc.size = 512;
+	this->ecc.layout = oob_smallpage;
+
 	if (pdata->hw_ecc) {
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		this->ecc.correct = mxc_nand_correct_data;
 		this->ecc.mode = NAND_ECC_HW;
-		this->ecc.size = 512;
-		this->ecc.bytes = 3;
 		tmp = readw(host->regs + NFC_CONFIG1);
 		tmp |= NFC_ECC_EN;
 		writew(tmp, host->regs + NFC_CONFIG1);
 	} else {
-		this->ecc.size = 512;
-		this->ecc.bytes = 3;
-		this->ecc.layout = &nand_hw_eccoob_8;
 		this->ecc.mode = NAND_ECC_SOFT;
 		tmp = readw(host->regs + NFC_CONFIG1);
 		tmp &= ~NFC_ECC_EN;
 		writew(tmp, host->regs + NFC_CONFIG1);
 	}
 
-	/* Reset NAND */
-	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
-	/* preset operation */
-	/* Unlock the internal RAM Buffer */
-	writew(0x2, host->regs + NFC_CONFIG);
-
-	/* Blocks to be unlocked */
-	writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR);
-	writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR);
-
-	/* Unlock Block Command for given address range */
-	writew(0x4, host->regs + NFC_WRPROT);
-
 	/* NAND bus width determines access funtions used by upper layer */
-	if (pdata->width == 2) {
+	if (pdata->width == 2)
 		this->options |= NAND_BUSWIDTH_16;
-		this->ecc.layout = &nand_hw_eccoob_16;
+
+	if (pdata->flash_bbt) {
+		this->bbt_td = &bbt_main_descr;
+		this->bbt_md = &bbt_mirror_descr;
+		/* update flash based bbt */
+		this->options |= NAND_USE_FLASH_BBT;
 	}
 
 	/* first scan to find the device and get the page size */
@@ -984,38 +823,8 @@ static int __init mxcnd_probe(struct pla
 		goto escan;
 	}
 
-	if (mtd->writesize == 2048) {
-		host->pagesize_2k = 1;
-		this->badblock_pattern = &smallpage_memorybased;
-	}
-
-	if (this->ecc.mode == NAND_ECC_HW) {
-		switch (mtd->oobsize) {
-		case 8:
-			this->ecc.layout = &nand_hw_eccoob_8;
-			break;
-		case 16:
-			this->ecc.layout = &nand_hw_eccoob_16;
-			break;
-		case 64:
-			this->ecc.layout = &nand_hw_eccoob_64;
-			break;
-		default:
-			/* page size not handled by HW ECC */
-			/* switching back to soft ECC */
-			this->ecc.size = 512;
-			this->ecc.bytes = 3;
-			this->ecc.layout = &nand_hw_eccoob_8;
-			this->ecc.mode = NAND_ECC_SOFT;
-			this->ecc.calculate = NULL;
-			this->ecc.correct = NULL;
-			this->ecc.hwctl = NULL;
-			tmp = readw(host->regs + NFC_CONFIG1);
-			tmp &= ~NFC_ECC_EN;
-			writew(tmp, host->regs + NFC_CONFIG1);
-			break;
-		}
-	}
+	if (mtd->writesize == 2048)
+		this->ecc.layout = oob_largepage;
 
 	/* second phase scan */
 	if (nand_scan_tail(mtd)) {
@@ -1043,7 +852,7 @@ static int __init mxcnd_probe(struct pla
 escan:
 	free_irq(host->irq, host);
 eirq:
-	iounmap(host->regs);
+	iounmap(host->base);
 eres:
 	clk_put(host->clk);
 eclk:
@@ -1062,7 +871,7 @@ static int __devexit mxcnd_remove(struct
 
 	nand_release(&host->mtd);
 	free_irq(host->irq, host);
-	iounmap(host->regs);
+	iounmap(host->base);
 	kfree(host);
 
 	return 0;
@@ -1113,7 +922,7 @@ static struct platform_driver mxcnd_driv
 	.driver = {
 		   .name = DRIVER_NAME,
 		   },
-	.remove = __exit_p(mxcnd_remove),
+	.remove = __devexit_p(mxcnd_remove),
 	.suspend = mxcnd_suspend,
 	.resume = mxcnd_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_base.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_base.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -428,6 +428,28 @@ static int nand_block_checkbad(struct mt
 	return nand_isbad_bbt(mtd, ofs, allowbbt);
 }
 
+/**
+ * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
+ * @mtd:	MTD device structure
+ * @timeo:	Timeout
+ *
+ * Helper function for nand_wait_ready used when needing to wait in interrupt
+ * context.
+ */
+static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
+{
+	struct nand_chip *chip = mtd->priv;
+	int i;
+
+	/* Wait for the device to get ready */
+	for (i = 0; i < timeo; i++) {
+		if (chip->dev_ready(mtd))
+			break;
+		touch_softlockup_watchdog();
+		mdelay(1);
+	}
+}
+
 /*
  * Wait for the ready pin, after a command
  * The timeout is catched later.
@@ -437,6 +459,10 @@ void nand_wait_ready(struct mtd_info *mt
 	struct nand_chip *chip = mtd->priv;
 	unsigned long timeo = jiffies + 2;
 
+	/* 400ms timeout */
+	if (in_interrupt() || oops_in_progress)
+		return panic_nand_wait_ready(mtd, 400);
+
 	led_trigger_event(nand_led_trigger, LED_FULL);
 	/* wait until command is processed or timeout occures */
 	do {
@@ -672,6 +698,22 @@ static void nand_command_lp(struct mtd_i
 }
 
 /**
+ * panic_nand_get_device - [GENERIC] Get chip for selected access
+ * @chip:	the nand chip descriptor
+ * @mtd:	MTD device structure
+ * @new_state:	the state which is requested
+ *
+ * Used when in panic, no locks are taken.
+ */
+static void panic_nand_get_device(struct nand_chip *chip,
+		      struct mtd_info *mtd, int new_state)
+{
+	/* Hardware controller shared among independend devices */
+	chip->controller->active = chip;
+	chip->state = new_state;
+}
+
+/**
  * nand_get_device - [GENERIC] Get chip for selected access
  * @chip:	the nand chip descriptor
  * @mtd:	MTD device structure
@@ -698,8 +740,14 @@ nand_get_device(struct nand_chip *chip,
 		return 0;
 	}
 	if (new_state == FL_PM_SUSPENDED) {
-		spin_unlock(lock);
-		return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
+		if (chip->controller->active->state == FL_PM_SUSPENDED) {
+			chip->state = FL_PM_SUSPENDED;
+			spin_unlock(lock);
+			return 0;
+		} else {
+			spin_unlock(lock);
+			return -EAGAIN;
+		}
 	}
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	add_wait_queue(wq, &wait);
@@ -710,6 +758,32 @@ nand_get_device(struct nand_chip *chip,
 }
 
 /**
+ * panic_nand_wait - [GENERIC]  wait until the command is done
+ * @mtd:	MTD device structure
+ * @chip:	NAND chip structure
+ * @timeo:	Timeout
+ *
+ * Wait for command done. This is a helper function for nand_wait used when
+ * we are in interrupt context. May happen when in panic and trying to write
+ * an oops trough mtdoops.
+ */
+static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
+			    unsigned long timeo)
+{
+	int i;
+	for (i = 0; i < timeo; i++) {
+		if (chip->dev_ready) {
+			if (chip->dev_ready(mtd))
+				break;
+		} else {
+			if (chip->read_byte(mtd) & NAND_STATUS_READY)
+				break;
+		}
+		mdelay(1);
+        }
+}
+
+/**
  * nand_wait - [DEFAULT]  wait until the command is done
  * @mtd:	MTD device structure
  * @chip:	NAND chip structure
@@ -740,15 +814,19 @@ static int nand_wait(struct mtd_info *mt
 	else
 		chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
 
-	while (time_before(jiffies, timeo)) {
-		if (chip->dev_ready) {
-			if (chip->dev_ready(mtd))
-				break;
-		} else {
-			if (chip->read_byte(mtd) & NAND_STATUS_READY)
-				break;
+	if (in_interrupt() || oops_in_progress)
+		panic_nand_wait(mtd, chip, timeo);
+	else {
+		while (time_before(jiffies, timeo)) {
+			if (chip->dev_ready) {
+				if (chip->dev_ready(mtd))
+					break;
+			} else {
+				if (chip->read_byte(mtd) & NAND_STATUS_READY)
+					break;
+			}
+			cond_resched();
 		}
-		cond_resched();
 	}
 	led_trigger_event(nand_led_trigger, LED_OFF);
 
@@ -1949,6 +2027,45 @@ static int nand_do_write_ops(struct mtd_
 }
 
 /**
+ * panic_nand_write - [MTD Interface] NAND write with ECC
+ * @mtd:	MTD device structure
+ * @to:		offset to write to
+ * @len:	number of bytes to write
+ * @retlen:	pointer to variable to store the number of written bytes
+ * @buf:	the data to write
+ *
+ * NAND write with ECC. Used when performing writes in interrupt context, this
+ * may for example be called by mtdoops when writing an oops while in panic.
+ */
+static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
+			    size_t *retlen, const uint8_t *buf)
+{
+	struct nand_chip *chip = mtd->priv;
+	int ret;
+
+	/* Do not allow reads past end of device */
+	if ((to + len) > mtd->size)
+		return -EINVAL;
+	if (!len)
+		return 0;
+
+	/* Wait for the device to get ready.  */
+	panic_nand_wait(mtd, chip, 400);
+
+	/* Grab the device.  */
+	panic_nand_get_device(chip, mtd, FL_WRITING);
+
+	chip->ops.len = len;
+	chip->ops.datbuf = (uint8_t *)buf;
+	chip->ops.oobbuf = NULL;
+
+	ret = nand_do_write_ops(mtd, to, &chip->ops);
+
+	*retlen = chip->ops.retlen;
+	return ret;
+}
+
+/**
  * nand_write - [MTD Interface] NAND write with ECC
  * @mtd:	MTD device structure
  * @to:		offset to write to
@@ -2645,7 +2762,8 @@ int nand_scan_ident(struct mtd_info *mtd
 	type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
 
 	if (IS_ERR(type)) {
-		printk(KERN_WARNING "No NAND device found!!!\n");
+		if (!(chip->options & NAND_SCAN_SILENT_NODEV))
+			printk(KERN_WARNING "No NAND device found.\n");
 		chip->select_chip(mtd, -1);
 		return PTR_ERR(type);
 	}
@@ -2877,6 +2995,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->unpoint = NULL;
 	mtd->read = nand_read;
 	mtd->write = nand_write;
+	mtd->panic_write = panic_nand_write;
 	mtd->read_oob = nand_read_oob;
 	mtd->write_oob = nand_write_oob;
 	mtd->sync = nand_sync;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_bcm_umi.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_bcm_umi.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_bcm_umi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_bcm_umi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,149 @@
+/*****************************************************************************
+* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/reg_umi.h>
+#include "nand_bcm_umi.h"
+#ifdef BOOT0_BUILD
+#include <uart.h>
+#endif
+
+/* ---- External Variable Declarations ----------------------------------- */
+/* ---- External Function Prototypes ------------------------------------- */
+/* ---- Public Variables ------------------------------------------------- */
+/* ---- Private Constants and Types -------------------------------------- */
+/* ---- Private Function Prototypes -------------------------------------- */
+/* ---- Private Variables ------------------------------------------------ */
+/* ---- Private Functions ------------------------------------------------ */
+
+#if NAND_ECC_BCH
+/****************************************************************************
+*  nand_bch_ecc_flip_bit - Routine to flip an errored bit
+*
+*  PURPOSE:
+*     This is a helper routine that flips the bit (0 -> 1 or 1 -> 0) of the
+*     errored bit specified
+*
+*  PARAMETERS:
+*     datap - Container that holds the 512 byte data
+*     errorLocation - Location of the bit that needs to be flipped
+*
+*  RETURNS:
+*     None
+****************************************************************************/
+static void nand_bcm_umi_bch_ecc_flip_bit(uint8_t *datap, int errorLocation)
+{
+	int locWithinAByte = (errorLocation & REG_UMI_BCH_ERR_LOC_BYTE) >> 0;
+	int locWithinAWord = (errorLocation & REG_UMI_BCH_ERR_LOC_WORD) >> 3;
+	int locWithinAPage = (errorLocation & REG_UMI_BCH_ERR_LOC_PAGE) >> 5;
+
+	uint8_t errorByte = 0;
+	uint8_t byteMask = 1 << locWithinAByte;
+
+	/* BCH uses big endian, need to change the location
+	 * bits to little endian */
+	locWithinAWord = 3 - locWithinAWord;
+
+	errorByte = datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord];
+
+#ifdef BOOT0_BUILD
+	puthexs("\nECC Correct Offset: ",
+		locWithinAPage * sizeof(uint32_t) + locWithinAWord);
+	puthexs(" errorByte:", errorByte);
+	puthex8(" Bit: ", locWithinAByte);
+#endif
+
+	if (errorByte & byteMask) {
+		/* bit needs to be cleared */
+		errorByte &= ~byteMask;
+	} else {
+		/* bit needs to be set */
+		errorByte |= byteMask;
+	}
+
+	/* write back the value with the fixed bit */
+	datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord] = errorByte;
+}
+
+/****************************************************************************
+*  nand_correct_page_bch - Routine to correct bit errors when reading NAND
+*
+*  PURPOSE:
+*     This routine reads the BCH registers to determine if there are any bit
+*     errors during the read of the last 512 bytes of data + ECC bytes.  If
+*     errors exists, the routine fixes it.
+*
+*  PARAMETERS:
+*     datap - Container that holds the 512 byte data
+*
+*  RETURNS:
+*     0 or greater = Number of errors corrected
+*                    (No errors are found or errors have been fixed)
+*    -1 = Error(s) cannot be fixed
+****************************************************************************/
+int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
+				  int numEccBytes)
+{
+	int numErrors;
+	int errorLocation;
+	int idx;
+	uint32_t regValue;
+
+	/* wait for read ECC to be valid */
+	regValue = nand_bcm_umi_bch_poll_read_ecc_calc();
+
+	/*
+	 * read the control status register to determine if there
+	 * are error'ed bits
+	 * see if errors are correctible
+	 */
+	if ((regValue & REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR) > 0) {
+		int i;
+
+		for (i = 0; i < numEccBytes; i++) {
+			if (readEccData[i] != 0xff) {
+				/* errors cannot be fixed, return -1 */
+				return -1;
+			}
+		}
+		/* If ECC is unprogrammed then we can't correct,
+		 * assume everything OK */
+		return 0;
+	}
+
+	if ((regValue & REG_UMI_BCH_CTRL_STATUS_CORR_ERR) == 0) {
+		/* no errors */
+		return 0;
+	}
+
+	/*
+	 * Fix errored bits by doing the following:
+	 * 1. Read the number of errors in the control and status register
+	 * 2. Read the error location registers that corresponds to the number
+	 *    of errors reported
+	 * 3. Invert the bit in the data
+	 */
+	numErrors = (regValue & REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR) >> 20;
+
+	for (idx = 0; idx < numErrors; idx++) {
+		errorLocation =
+		    REG_UMI_BCH_ERR_LOC_ADDR(idx) & REG_UMI_BCH_ERR_LOC_MASK;
+
+		/* Flip bit */
+		nand_bcm_umi_bch_ecc_flip_bit(datap, errorLocation);
+	}
+	/* Errors corrected */
+	return numErrors;
+}
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_bcm_umi.h linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_bcm_umi.h
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_bcm_umi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_bcm_umi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,358 @@
+/*****************************************************************************
+* Copyright 2003 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+#ifndef NAND_BCM_UMI_H
+#define NAND_BCM_UMI_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/reg_umi.h>
+#include <mach/reg_nand.h>
+#include <cfg_global.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+#if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING)
+#define NAND_ECC_BCH (CFG_GLOBAL_CHIP_REV > 0xA0)
+#else
+#define NAND_ECC_BCH 0
+#endif
+
+#define CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES	13
+
+#if NAND_ECC_BCH
+#ifdef BOOT0_BUILD
+#define NAND_ECC_NUM_BYTES 13
+#else
+#define NAND_ECC_NUM_BYTES CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES
+#endif
+#else
+#define NAND_ECC_NUM_BYTES 3
+#endif
+
+#define NAND_DATA_ACCESS_SIZE 512
+
+/* ---- Variable Externs ------------------------------------------ */
+/* ---- Function Prototypes --------------------------------------- */
+int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
+				  int numEccBytes);
+
+/* Check in device is ready */
+static inline int nand_bcm_umi_dev_ready(void)
+{
+	return REG_UMI_NAND_RCSR & REG_UMI_NAND_RCSR_RDY;
+}
+
+/* Wait until device is ready */
+static inline void nand_bcm_umi_wait_till_ready(void)
+{
+	while (nand_bcm_umi_dev_ready() == 0)
+		;
+}
+
+/* Enable Hamming ECC */
+static inline void nand_bcm_umi_hamming_enable_hwecc(void)
+{
+	/* disable and reset ECC, 512 byte page */
+	REG_UMI_NAND_ECC_CSR &= ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE |
+		REG_UMI_NAND_ECC_CSR_256BYTE);
+	/* enable ECC */
+	REG_UMI_NAND_ECC_CSR |= REG_UMI_NAND_ECC_CSR_ECC_ENABLE;
+}
+
+#if NAND_ECC_BCH
+/* BCH ECC specifics */
+#define ECC_BITS_PER_CORRECTABLE_BIT 13
+
+/* Enable BCH Read ECC */
+static inline void nand_bcm_umi_bch_enable_read_hwecc(void)
+{
+	/* disable and reset ECC */
+	REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID;
+	/* Turn on ECC */
+	REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN;
+}
+
+/* Enable BCH Write ECC */
+static inline void nand_bcm_umi_bch_enable_write_hwecc(void)
+{
+	/* disable and reset ECC */
+	REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID;
+	/* Turn on ECC */
+	REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN;
+}
+
+/* Config number of BCH ECC bytes */
+static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes)
+{
+	uint32_t nValue;
+	uint32_t tValue;
+	uint32_t kValue;
+	uint32_t numBits = numEccBytes * 8;
+
+	/* disable and reset ECC */
+	REG_UMI_BCH_CTRL_STATUS =
+	    REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID |
+	    REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID;
+
+	/* Every correctible bit requires 13 ECC bits */
+	tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT);
+
+	/* Total data in number of bits for generating and computing BCH ECC */
+	nValue = (NAND_DATA_ACCESS_SIZE + numEccBytes) * 8;
+
+	/* K parameter is used internally.  K = N - (T * 13) */
+	kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT);
+
+	/* Write the settings */
+	REG_UMI_BCH_N = nValue;
+	REG_UMI_BCH_T = tValue;
+	REG_UMI_BCH_K = kValue;
+}
+
+/* Pause during ECC read calculation to skip bytes in OOB */
+static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void)
+{
+	REG_UMI_BCH_CTRL_STATUS =
+	    REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN |
+	    REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC;
+}
+
+/* Resume during ECC read calculation after skipping bytes in OOB */
+static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void)
+{
+	REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN;
+}
+
+/* Poll read ECC calc to check when hardware completes */
+static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void)
+{
+	uint32_t regVal;
+
+	do {
+		/* wait for ECC to be valid */
+		regVal = REG_UMI_BCH_CTRL_STATUS;
+	} while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0);
+
+	return regVal;
+}
+
+/* Poll write ECC calc to check when hardware completes */
+static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void)
+{
+	/* wait for ECC to be valid */
+	while ((REG_UMI_BCH_CTRL_STATUS & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID)
+	       == 0)
+		;
+}
+
+/* Read the OOB and ECC, for kernel write OOB to a buffer */
+#if defined(__KERNEL__) && !defined(STANDALONE)
+static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
+	uint8_t *eccCalc, int numEccBytes, uint8_t *oobp)
+#else
+static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
+	uint8_t *eccCalc, int numEccBytes)
+#endif
+{
+	int eccPos = 0;
+	int numToRead = 16;	/* There are 16 bytes per sector in the OOB */
+
+	/* ECC is already paused when this function is called */
+
+	if (pageSize == NAND_DATA_ACCESS_SIZE) {
+		while (numToRead > numEccBytes) {
+			/* skip free oob region */
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp++ = REG_NAND_DATA8;
+#else
+			REG_NAND_DATA8;
+#endif
+			numToRead--;
+		}
+
+		/* read ECC bytes before BI */
+		nand_bcm_umi_bch_resume_read_ecc_calc();
+
+		while (numToRead > 11) {
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp = REG_NAND_DATA8;
+			eccCalc[eccPos++] = *oobp;
+			oobp++;
+#else
+			eccCalc[eccPos++] = REG_NAND_DATA8;
+#endif
+		}
+
+		nand_bcm_umi_bch_pause_read_ecc_calc();
+
+		if (numToRead == 11) {
+			/* read BI */
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp++ = REG_NAND_DATA8;
+#else
+			REG_NAND_DATA8;
+#endif
+			numToRead--;
+		}
+
+		/* read ECC bytes */
+		nand_bcm_umi_bch_resume_read_ecc_calc();
+		while (numToRead) {
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp = REG_NAND_DATA8;
+			eccCalc[eccPos++] = *oobp;
+			oobp++;
+#else
+			eccCalc[eccPos++] = REG_NAND_DATA8;
+#endif
+			numToRead--;
+		}
+	} else {
+		/* skip BI */
+#if defined(__KERNEL__) && !defined(STANDALONE)
+		*oobp++ = REG_NAND_DATA8;
+#else
+		REG_NAND_DATA8;
+#endif
+		numToRead--;
+
+		while (numToRead > numEccBytes) {
+			/* skip free oob region */
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp++ = REG_NAND_DATA8;
+#else
+			REG_NAND_DATA8;
+#endif
+			numToRead--;
+		}
+
+		/* read ECC bytes */
+		nand_bcm_umi_bch_resume_read_ecc_calc();
+		while (numToRead) {
+#if defined(__KERNEL__) && !defined(STANDALONE)
+			*oobp = REG_NAND_DATA8;
+			eccCalc[eccPos++] = *oobp;
+			oobp++;
+#else
+			eccCalc[eccPos++] = REG_NAND_DATA8;
+#endif
+			numToRead--;
+		}
+	}
+}
+
+/* Helper function to write ECC */
+static inline void NAND_BCM_UMI_ECC_WRITE(int numEccBytes, int eccBytePos,
+					  uint8_t *oobp, uint8_t eccVal)
+{
+	if (eccBytePos <= numEccBytes)
+		*oobp = eccVal;
+}
+
+/* Write OOB with ECC */
+static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize,
+						 uint8_t *oobp, int numEccBytes)
+{
+	uint32_t eccVal = 0xffffffff;
+
+	/* wait for write ECC to be valid */
+	nand_bcm_umi_bch_poll_write_ecc_calc();
+
+	/*
+	 ** Get the hardware ecc from the 32-bit result registers.
+	 ** Read after 512 byte accesses. Format B3B2B1B0
+	 ** where B3 = ecc3, etc.
+	 */
+
+	if (pageSize == NAND_DATA_ACCESS_SIZE) {
+		/* Now fill in the ECC bytes */
+		if (numEccBytes >= 13)
+			eccVal = REG_UMI_BCH_WR_ECC_3;
+
+		/* Usually we skip CM in oob[0,1] */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0],
+			(eccVal >> 16) & 0xff);
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[1],
+			(eccVal >> 8) & 0xff);
+
+		/* Write ECC in oob[2,3,4] */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[2],
+			eccVal & 0xff);	/* ECC 12 */
+
+		if (numEccBytes >= 9)
+			eccVal = REG_UMI_BCH_WR_ECC_2;
+
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3],
+			(eccVal >> 24) & 0xff);	/* ECC11 */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[4],
+			(eccVal >> 16) & 0xff);	/* ECC10 */
+
+		/* Always Skip BI in oob[5] */
+	} else {
+		/* Always Skip BI in oob[0] */
+
+		/* Now fill in the ECC bytes */
+		if (numEccBytes >= 13)
+			eccVal = REG_UMI_BCH_WR_ECC_3;
+
+		/* Usually skip CM in oob[1,2] */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1],
+			(eccVal >> 16) & 0xff);
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[2],
+			(eccVal >> 8) & 0xff);
+
+		/* Write ECC in oob[3-15] */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[3],
+			eccVal & 0xff);	/* ECC12 */
+
+		if (numEccBytes >= 9)
+			eccVal = REG_UMI_BCH_WR_ECC_2;
+
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4],
+			(eccVal >> 24) & 0xff);	/* ECC11 */
+		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[5],
+			(eccVal >> 16) & 0xff);	/* ECC10 */
+	}
+
+	/* Fill in the remainder of ECC locations */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 10, &oobp[6],
+		(eccVal >> 8) & 0xff);	/* ECC9 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 9, &oobp[7],
+		eccVal & 0xff);	/* ECC8 */
+
+	if (numEccBytes >= 5)
+		eccVal = REG_UMI_BCH_WR_ECC_1;
+
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8],
+		(eccVal >> 24) & 0xff);	/* ECC7 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 7, &oobp[9],
+		(eccVal >> 16) & 0xff);	/* ECC6 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 6, &oobp[10],
+		(eccVal >> 8) & 0xff);	/* ECC5 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 5, &oobp[11],
+		eccVal & 0xff);	/* ECC4 */
+
+	if (numEccBytes >= 1)
+		eccVal = REG_UMI_BCH_WR_ECC_0;
+
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12],
+		(eccVal >> 24) & 0xff);	/* ECC3 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 3, &oobp[13],
+		(eccVal >> 16) & 0xff);	/* ECC2 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 2, &oobp[14],
+		(eccVal >> 8) & 0xff);	/* ECC1 */
+	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 1, &oobp[15],
+		eccVal & 0xff);	/* ECC0 */
+}
+#endif
+
+#endif /* NAND_BCM_UMI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_ecc.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_ecc.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nand_ecc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nand_ecc.c	2010-02-24 13:52:17.000000000 -0500
@@ -150,20 +150,19 @@ static const char addressbits[256] = {
 };
 
 /**
- * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
+ * __nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
  *			 block
- * @mtd:	MTD block structure
  * @buf:	input buffer with raw data
+ * @eccsize:	data bytes per ecc step (256 or 512)
  * @code:	output buffer with ECC
  */
-int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
+void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
 		       unsigned char *code)
 {
 	int i;
 	const uint32_t *bp = (uint32_t *)buf;
 	/* 256 or 512 bytes/ecc  */
-	const uint32_t eccsize_mult =
-			(((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
+	const uint32_t eccsize_mult = eccsize >> 8;
 	uint32_t cur;		/* current value in buffer */
 	/* rp0..rp15..rp17 are the various accumulated parities (per byte) */
 	uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
@@ -412,6 +411,22 @@ int nand_calculate_ecc(struct mtd_info *
 		    (invparity[par & 0x55] << 2) |
 		    (invparity[rp17] << 1) |
 		    (invparity[rp16] << 0);
+}
+EXPORT_SYMBOL(__nand_calculate_ecc);
+
+/**
+ * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
+ *			 block
+ * @mtd:	MTD block structure
+ * @buf:	input buffer with raw data
+ * @code:	output buffer with ECC
+ */
+int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
+		       unsigned char *code)
+{
+	__nand_calculate_ecc(buf,
+			((struct nand_chip *)mtd->priv)->ecc.size, code);
+
 	return 0;
 }
 EXPORT_SYMBOL(nand_calculate_ecc);
@@ -475,7 +490,7 @@ int __nand_correct_data(unsigned char *b
 		 *
 		 * The b2 shift is there to get rid of the lowest two bits.
 		 * We could also do addressbits[b2] >> 1 but for the
-		 * performace it does not make any difference
+		 * performance it does not make any difference
 		 */
 		if (eccsize_mult == 1)
 			byte_addr = (addressbits[b1] << 4) + addressbits[b0];
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nandsim.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/nandsim.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nandsim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nandsim.c	2010-02-24 13:52:17.000000000 -0500
@@ -161,7 +161,7 @@ MODULE_PARM_DESC(overridesize,   "Specif
 MODULE_PARM_DESC(cache_file,     "File to use to cache nand pages instead of memory");
 
 /* The largest possible page size */
-#define NS_LARGEST_PAGE_SIZE	2048
+#define NS_LARGEST_PAGE_SIZE	4096
 
 /* The prefix for simulator output */
 #define NS_OUTPUT_PREFIX "[nandsim]"
@@ -259,7 +259,8 @@ MODULE_PARM_DESC(cache_file,     "File t
 #define OPT_SMARTMEDIA   0x00000010 /* SmartMedia technology chips */
 #define OPT_AUTOINCR     0x00000020 /* page number auto inctimentation is possible */
 #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */
-#define OPT_LARGEPAGE    (OPT_PAGE2048) /* 2048-byte page chips */
+#define OPT_PAGE4096     0x00000080 /* 4096-byte page chips */
+#define OPT_LARGEPAGE    (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */
 #define OPT_SMALLPAGE    (OPT_PAGE256  | OPT_PAGE512)  /* 256 and 512-byte page chips */
 
 /* Remove action bits ftom state */
@@ -588,6 +589,8 @@ static int init_nandsim(struct mtd_info
 			ns->options |= OPT_PAGE512_8BIT;
 	} else if (ns->geom.pgsz == 2048) {
 		ns->options |= OPT_PAGE2048;
+	} else if (ns->geom.pgsz == 4096) {
+		ns->options |= OPT_PAGE4096;
 	} else {
 		NS_ERR("init_nandsim: unknown page size %u\n", ns->geom.pgsz);
 		return -EIO;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/nomadik_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/nomadik_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/nomadik_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/nomadik_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -216,7 +216,7 @@ static int nomadik_nand_resume(struct de
 	return 0;
 }
 
-static struct dev_pm_ops nomadik_nand_pm_ops = {
+static const struct dev_pm_ops nomadik_nand_pm_ops = {
 	.suspend = nomadik_nand_suspend,
 	.resume = nomadik_nand_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/omap2.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/omap2.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/omap2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/omap2.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,9 +18,9 @@
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 
-#include <mach/dma.h>
-#include <mach/gpmc.h>
-#include <mach/nand.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
 
 #define GPMC_IRQ_STATUS		0x18
 #define GPMC_ECC_CONFIG		0x1F4
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/plat_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/plat_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/plat_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/plat_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,12 @@ static int __devinit plat_nand_probe(str
 {
 	struct platform_nand_data *pdata = pdev->dev.platform_data;
 	struct plat_nand_data *data;
-	int res = 0;
+	struct resource *res;
+	int err = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
 
 	/* Allocate memory for the device structure (and zero it) */
 	data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL);
@@ -43,12 +48,18 @@ static int __devinit plat_nand_probe(str
 		return -ENOMEM;
 	}
 
-	data->io_base = ioremap(pdev->resource[0].start,
-				pdev->resource[0].end - pdev->resource[0].start + 1);
+	if (!request_mem_region(res->start, resource_size(res),
+				dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev, "request_mem_region failed\n");
+		err = -EBUSY;
+		goto out_free;
+	}
+
+	data->io_base = ioremap(res->start, resource_size(res));
 	if (data->io_base == NULL) {
 		dev_err(&pdev->dev, "ioremap failed\n");
-		kfree(data);
-		return -EIO;
+		err = -EIO;
+		goto out_release_io;
 	}
 
 	data->chip.priv = &data;
@@ -74,24 +85,24 @@ static int __devinit plat_nand_probe(str
 
 	/* Handle any platform specific setup */
 	if (pdata->ctrl.probe) {
-		res = pdata->ctrl.probe(pdev);
-		if (res)
+		err = pdata->ctrl.probe(pdev);
+		if (err)
 			goto out;
 	}
 
 	/* Scan to find existance of the device */
 	if (nand_scan(&data->mtd, 1)) {
-		res = -ENXIO;
+		err = -ENXIO;
 		goto out;
 	}
 
 #ifdef CONFIG_MTD_PARTITIONS
 	if (pdata->chip.part_probe_types) {
-		res = parse_mtd_partitions(&data->mtd,
+		err = parse_mtd_partitions(&data->mtd,
 					pdata->chip.part_probe_types,
 					&data->parts, 0);
-		if (res > 0) {
-			add_mtd_partitions(&data->mtd, data->parts, res);
+		if (err > 0) {
+			add_mtd_partitions(&data->mtd, data->parts, err);
 			return 0;
 		}
 	}
@@ -99,14 +110,14 @@ static int __devinit plat_nand_probe(str
 		pdata->chip.set_parts(data->mtd.size, &pdata->chip);
 	if (pdata->chip.partitions) {
 		data->parts = pdata->chip.partitions;
-		res = add_mtd_partitions(&data->mtd, data->parts,
+		err = add_mtd_partitions(&data->mtd, data->parts,
 			pdata->chip.nr_partitions);
 	} else
 #endif
-	res = add_mtd_device(&data->mtd);
+	err = add_mtd_device(&data->mtd);
 
-	if (!res)
-		return res;
+	if (!err)
+		return err;
 
 	nand_release(&data->mtd);
 out:
@@ -114,8 +125,11 @@ out:
 		pdata->ctrl.remove(pdev);
 	platform_set_drvdata(pdev, NULL);
 	iounmap(data->io_base);
+out_release_io:
+	release_mem_region(res->start, resource_size(res));
+out_free:
 	kfree(data);
-	return res;
+	return err;
 }
 
 /*
@@ -125,6 +139,9 @@ static int __devexit plat_nand_remove(st
 {
 	struct plat_nand_data *data = platform_get_drvdata(pdev);
 	struct platform_nand_data *pdata = pdev->dev.platform_data;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	nand_release(&data->mtd);
 #ifdef CONFIG_MTD_PARTITIONS
@@ -134,6 +151,7 @@ static int __devexit plat_nand_remove(st
 	if (pdata->ctrl.remove)
 		pdata->ctrl.remove(pdev);
 	iounmap(data->io_base);
+	release_mem_region(res->start, resource_size(res));
 	kfree(data);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/pxa3xx_nand.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/pxa3xx_nand.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
@@ -22,7 +23,7 @@
 #include <linux/irq.h>
 
 #include <mach/dma.h>
-#include <mach/pxa3xx_nand.h>
+#include <plat/pxa3xx_nand.h>
 
 #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
 
@@ -84,10 +85,6 @@
 #define NDCB0_CMD1_MASK		(0xff)
 #define NDCB0_ADDR_CYC_SHIFT	(16)
 
-/* dma-able I/O address for the NAND data and commands */
-#define NDCB0_DMA_ADDR		(0x43100048)
-#define NDDB_DMA_ADDR		(0x43100040)
-
 /* macros for registers read/write */
 #define nand_writel(info, off, val)	\
 	__raw_writel((val), (info)->mmio_base + (off))
@@ -123,6 +120,7 @@ struct pxa3xx_nand_info {
 
 	struct clk		*clk;
 	void __iomem		*mmio_base;
+	unsigned long		mmio_phys;
 
 	unsigned int 		buf_start;
 	unsigned int		buf_count;
@@ -228,13 +226,35 @@ static struct pxa3xx_nand_flash samsung5
 	.chip_id	= 0x46ec,
 };
 
+static struct pxa3xx_nand_flash samsung2GbX8 = {
+	.timing		= &samsung512MbX16_timing,
+	.cmdset		= &smallpage_cmdset,
+	.page_per_block	= 64,
+	.page_size	= 2048,
+	.flash_width	= 8,
+	.dfc_width	= 8,
+	.num_blocks	= 2048,
+	.chip_id	= 0xdaec,
+};
+
+static struct pxa3xx_nand_flash samsung32GbX8 = {
+	.timing		= &samsung512MbX16_timing,
+	.cmdset		= &smallpage_cmdset,
+	.page_per_block	= 128,
+	.page_size	= 4096,
+	.flash_width	= 8,
+	.dfc_width	= 8,
+	.num_blocks	= 8192,
+	.chip_id	= 0xd7ec,
+};
+
 static struct pxa3xx_nand_timing micron_timing = {
 	.tCH	= 10,
 	.tCS	= 25,
 	.tWH	= 15,
 	.tWP	= 25,
 	.tRH	= 15,
-	.tRP	= 25,
+	.tRP	= 30,
 	.tR	= 25000,
 	.tWHR	= 60,
 	.tAR	= 10,
@@ -262,6 +282,28 @@ static struct pxa3xx_nand_flash micron1G
 	.chip_id	= 0xb12c,
 };
 
+static struct pxa3xx_nand_flash micron4GbX8 = {
+	.timing		= &micron_timing,
+	.cmdset		= &largepage_cmdset,
+	.page_per_block	= 64,
+	.page_size	= 2048,
+	.flash_width	= 8,
+	.dfc_width	= 8,
+	.num_blocks	= 4096,
+	.chip_id	= 0xdc2c,
+};
+
+static struct pxa3xx_nand_flash micron4GbX16 = {
+	.timing		= &micron_timing,
+	.cmdset		= &largepage_cmdset,
+	.page_per_block	= 64,
+	.page_size	= 2048,
+	.flash_width	= 16,
+	.dfc_width	= 16,
+	.num_blocks	= 4096,
+	.chip_id	= 0xcc2c,
+};
+
 static struct pxa3xx_nand_timing stm2GbX16_timing = {
 	.tCH = 10,
 	.tCS = 35,
@@ -287,8 +329,12 @@ static struct pxa3xx_nand_flash stm2GbX1
 
 static struct pxa3xx_nand_flash *builtin_flash_types[] = {
 	&samsung512MbX16,
+	&samsung2GbX8,
+	&samsung32GbX8,
 	&micron1GbX8,
 	&micron1GbX16,
+	&micron4GbX8,
+	&micron4GbX16,
 	&stm2GbX16,
 };
 #endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */
@@ -489,7 +535,7 @@ static int handle_data_pio(struct pxa3xx
 	switch (info->state) {
 	case STATE_PIO_WRITING:
 		__raw_writesl(info->mmio_base + NDDB, info->data_buff,
-				info->data_size << 2);
+				DIV_ROUND_UP(info->data_size, 4));
 
 		enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD);
 
@@ -501,7 +547,7 @@ static int handle_data_pio(struct pxa3xx
 		break;
 	case STATE_PIO_READING:
 		__raw_readsl(info->mmio_base + NDDB, info->data_buff,
-				info->data_size << 2);
+				DIV_ROUND_UP(info->data_size, 4));
 		break;
 	default:
 		printk(KERN_ERR "%s: invalid state %d\n", __func__,
@@ -523,11 +569,11 @@ static void start_data_dma(struct pxa3xx
 
 	if (dir_out) {
 		desc->dsadr = info->data_buff_phys;
-		desc->dtadr = NDDB_DMA_ADDR;
+		desc->dtadr = info->mmio_phys + NDDB;
 		desc->dcmd |= DCMD_INCSRCADDR | DCMD_FLOWTRG;
 	} else {
 		desc->dtadr = info->data_buff_phys;
-		desc->dsadr = NDDB_DMA_ADDR;
+		desc->dsadr = info->mmio_phys + NDDB;
 		desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
 	}
 
@@ -669,6 +715,7 @@ static void pxa3xx_nand_cmdfunc(struct m
 		/* disable HW ECC to get all the OOB data */
 		info->buf_count = mtd->writesize + mtd->oobsize;
 		info->buf_start = mtd->writesize + column;
+		memset(info->data_buff, 0xFF, info->buf_count);
 
 		if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr))
 			break;
@@ -1239,13 +1286,17 @@ static int pxa3xx_nand_probe(struct plat
 		ret = -ENODEV;
 		goto fail_free_res;
 	}
+	info->mmio_phys = r->start;
 
 	ret = pxa3xx_nand_init_buff(info);
 	if (ret)
 		goto fail_free_io;
 
-	ret = request_irq(IRQ_NAND, pxa3xx_nand_irq, IRQF_DISABLED,
-				pdev->name, info);
+	/* initialize all interrupts to be disabled */
+	disable_int(info, NDSR_MASK);
+
+	ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED,
+			  pdev->name, info);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
 		goto fail_free_buf;
@@ -1271,7 +1322,7 @@ static int pxa3xx_nand_probe(struct plat
 	return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
 
 fail_free_irq:
-	free_irq(IRQ_NAND, info);
+	free_irq(irq, info);
 fail_free_buf:
 	if (use_dma) {
 		pxa_free_dma(info->data_dma_ch);
@@ -1296,12 +1347,15 @@ static int pxa3xx_nand_remove(struct pla
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
 	struct pxa3xx_nand_info *info = mtd->priv;
 	struct resource *r;
+	int irq;
 
 	platform_set_drvdata(pdev, NULL);
 
 	del_mtd_device(mtd);
 	del_mtd_partitions(mtd);
-	free_irq(IRQ_NAND, info);
+	irq = platform_get_irq(pdev, 0);
+	if (irq >= 0)
+		free_irq(irq, info);
 	if (use_dma) {
 		pxa_free_dma(info->data_dma_ch);
 		dma_free_writecombine(&pdev->dev, info->data_buff_size,
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/s3c2410.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/s3c2410.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/s3c2410.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/s3c2410.c	2010-02-24 13:52:17.000000000 -0500
@@ -774,7 +774,7 @@ static void s3c2410_nand_init_chip(struc
 	chip->select_chip  = s3c2410_nand_select_chip;
 	chip->chip_delay   = 50;
 	chip->priv	   = nmtd;
-	chip->options	   = 0;
+	chip->options	   = set->options;
 	chip->controller   = &info->controller;
 
 	switch (info->cpu_type) {
@@ -875,7 +875,7 @@ static void s3c2410_nand_init_chip(struc
  * @info: The controller instance.
  * @nmtd: The driver version of the MTD instance.
  *
- * This routine is called after the chip probe has succesfully completed
+ * This routine is called after the chip probe has successfully completed
  * and the relevant per-chip information updated. This call ensure that
  * we update the internal state accordingly.
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/nand/txx9ndfmc.c linux-libre-2.6.33-gnu1/drivers/mtd/nand/txx9ndfmc.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/nand/txx9ndfmc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/nand/txx9ndfmc.c	2010-02-24 13:52:17.000000000 -0500
@@ -429,11 +429,10 @@ static int __exit txx9ndfmc_remove(struc
 		chip = mtd->priv;
 		txx9_priv = chip->priv;
 
+		nand_release(mtd);
 #ifdef CONFIG_MTD_PARTITIONS
-		del_mtd_partitions(mtd);
 		kfree(drvdata->parts[i]);
 #endif
-		del_mtd_device(mtd);
 		kfree(txx9_priv->mtdname);
 		kfree(txx9_priv);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/onenand/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/onenand/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/onenand/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/onenand/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,3 @@
-#
-# linux/drivers/mtd/onenand/Kconfig
-#
-
 menuconfig MTD_ONENAND
 	tristate "OneNAND Device Support"
 	depends on MTD
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/onenand/omap2.c linux-libre-2.6.33-gnu1/drivers/mtd/onenand/omap2.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/onenand/omap2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/onenand/omap2.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,13 +36,13 @@
 #include <linux/io.h>
 
 #include <asm/mach/flash.h>
-#include <mach/gpmc.h>
-#include <mach/onenand.h>
+#include <plat/gpmc.h>
+#include <plat/onenand.h>
 #include <mach/gpio.h>
 
-#include <mach/dma.h>
+#include <plat/dma.h>
 
-#include <mach/board.h>
+#include <plat/board.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -112,10 +112,24 @@ static int omap2_onenand_wait(struct mtd
 	unsigned long timeout;
 	u32 syscfg;
 
-	if (state == FL_RESETING) {
-		int i;
+	if (state == FL_RESETING || state == FL_PREPARING_ERASE ||
+	    state == FL_VERIFYING_ERASE) {
+		int i = 21;
+		unsigned int intr_flags = ONENAND_INT_MASTER;
 
-		for (i = 0; i < 20; i++) {
+		switch (state) {
+		case FL_RESETING:
+			intr_flags |= ONENAND_INT_RESET;
+			break;
+		case FL_PREPARING_ERASE:
+			intr_flags |= ONENAND_INT_ERASE;
+			break;
+		case FL_VERIFYING_ERASE:
+			i = 101;
+			break;
+		}
+
+		while (--i) {
 			udelay(1);
 			intr = read_reg(c, ONENAND_REG_INTERRUPT);
 			if (intr & ONENAND_INT_MASTER)
@@ -126,7 +140,7 @@ static int omap2_onenand_wait(struct mtd
 			wait_err("controller error", state, ctrl, intr);
 			return -EIO;
 		}
-		if (!(intr & ONENAND_INT_RESET)) {
+		if ((intr & intr_flags) != intr_flags) {
 			wait_err("timeout", state, ctrl, intr);
 			return -EIO;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/onenand/onenand_base.c linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_base.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/onenand/onenand_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/onenand/onenand_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,17 +1,19 @@
 /*
  *  linux/drivers/mtd/onenand/onenand_base.c
  *
- *  Copyright (C) 2005-2007 Samsung Electronics
+ *  Copyright © 2005-2009 Samsung Electronics
+ *  Copyright © 2007 Nokia Corporation
+ *
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  *  Credits:
  *	Adrian Hunter <ext-adrian.hunter@nokia.com>:
  *	auto-placement support, read-while load support, various fixes
- *	Copyright (C) Nokia Corporation, 2007
  *
  *	Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
  *	Flex-OneNAND support
- *	Copyright (C) Samsung Electronics, 2008
+ *	Amul Kumar Saha <amul.saha at samsung.com>
+ *	OTP 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
@@ -32,6 +34,13 @@
 
 #include <asm/io.h>
 
+/*
+ * Multiblock erase if number of blocks to erase is 2 or more.
+ * Maximum number of blocks for simultaneous erase is 64.
+ */
+#define MB_ERASE_MIN_BLK_COUNT 2
+#define MB_ERASE_MAX_BLK_COUNT 64
+
 /* Default Flex-OneNAND boundary and lock respectively */
 static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 };
 
@@ -43,6 +52,18 @@ MODULE_PARM_DESC(flex_bdry,	"SLC Boundar
 				"    : 0->Set boundary in unlocked status"
 				"    : 1->Set boundary in locked status");
 
+/* Default OneNAND/Flex-OneNAND OTP options*/
+static int otp;
+
+module_param(otp, int, 0400);
+MODULE_PARM_DESC(otp,	"Corresponding behaviour of OneNAND in OTP"
+			"Syntax : otp=LOCK_TYPE"
+			"LOCK_TYPE : Keys issued, for specific OTP Lock type"
+			"	   : 0 -> Default (No Blocks Locked)"
+			"	   : 1 -> OTP Block lock"
+			"	   : 2 -> 1st Block lock"
+			"	   : 3 -> BOTH OTP Block and 1st Block lock");
+
 /**
  *  onenand_oob_128 - oob info for Flex-Onenand with 4KB page
  *  For now, we expose only 64 out of 80 ecc bytes
@@ -339,6 +360,8 @@ static int onenand_command(struct mtd_in
 		break;
 
 	case ONENAND_CMD_ERASE:
+	case ONENAND_CMD_MULTIBLOCK_ERASE:
+	case ONENAND_CMD_ERASE_VERIFY:
 	case ONENAND_CMD_BUFFERRAM:
 	case ONENAND_CMD_OTP_ACCESS:
 		block = onenand_block(this, addr);
@@ -483,7 +506,7 @@ static int onenand_wait(struct mtd_info
 		if (interrupt & flags)
 			break;
 
-		if (state != FL_READING)
+		if (state != FL_READING && state != FL_PREPARING_ERASE)
 			cond_resched();
 	}
 	/* To get correct interrupt status in timeout case */
@@ -500,25 +523,40 @@ static int onenand_wait(struct mtd_info
 		int ecc = onenand_read_ecc(this);
 		if (ecc) {
 			if (ecc & ONENAND_ECC_2BIT_ALL) {
-				printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
+				printk(KERN_ERR "%s: ECC error = 0x%04x\n",
+					__func__, ecc);
 				mtd->ecc_stats.failed++;
 				return -EBADMSG;
 			} else if (ecc & ONENAND_ECC_1BIT_ALL) {
-				printk(KERN_DEBUG "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
+				printk(KERN_DEBUG "%s: correctable ECC error = 0x%04x\n",
+					__func__, ecc);
 				mtd->ecc_stats.corrected++;
 			}
 		}
 	} else if (state == FL_READING) {
-		printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
+		printk(KERN_ERR "%s: read timeout! ctrl=0x%04x intr=0x%04x\n",
+			__func__, ctrl, interrupt);
+		return -EIO;
+	}
+
+	if (state == FL_PREPARING_ERASE && !(interrupt & ONENAND_INT_ERASE)) {
+		printk(KERN_ERR "%s: mb erase timeout! ctrl=0x%04x intr=0x%04x\n",
+		       __func__, ctrl, interrupt);
+		return -EIO;
+	}
+
+	if (!(interrupt & ONENAND_INT_MASTER)) {
+		printk(KERN_ERR "%s: timeout! ctrl=0x%04x intr=0x%04x\n",
+		       __func__, ctrl, interrupt);
 		return -EIO;
 	}
 
 	/* If there's controller error, it's a real error */
 	if (ctrl & ONENAND_CTRL_ERROR) {
-		printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n",
-			ctrl);
+		printk(KERN_ERR "%s: controller error = 0x%04x\n",
+			__func__, ctrl);
 		if (ctrl & ONENAND_CTRL_LOCK)
-			printk(KERN_ERR "onenand_wait: it's locked error.\n");
+			printk(KERN_ERR "%s: it's locked error.\n", __func__);
 		return -EIO;
 	}
 
@@ -1015,7 +1053,8 @@ static int onenand_recover_lsb(struct mt
 	/* We are attempting to reread, so decrement stats.failed
 	 * which was incremented by onenand_wait due to read failure
 	 */
-	printk(KERN_INFO "onenand_recover_lsb: Attempting to recover from uncorrectable read\n");
+	printk(KERN_INFO "%s: Attempting to recover from uncorrectable read\n",
+		__func__);
 	mtd->ecc_stats.failed--;
 
 	/* Issue the LSB page recovery command */
@@ -1046,7 +1085,8 @@ static int onenand_mlc_read_ops_nolock(s
 	int ret = 0;
 	int writesize = this->writesize;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_mlc_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
+	      __func__, (unsigned int) from, (int) len);
 
 	if (ops->mode == MTD_OOB_AUTO)
 		oobsize = this->ecclayout->oobavail;
@@ -1057,7 +1097,8 @@ static int onenand_mlc_read_ops_nolock(s
 
 	/* Do not allow reads past end of device */
 	if (from + len > mtd->size) {
-		printk(KERN_ERR "onenand_mlc_read_ops_nolock: Attempt read beyond end of device\n");
+		printk(KERN_ERR "%s: Attempt read beyond end of device\n",
+			__func__);
 		ops->retlen = 0;
 		ops->oobretlen = 0;
 		return -EINVAL;
@@ -1146,7 +1187,8 @@ static int onenand_read_ops_nolock(struc
 	int ret = 0, boundary = 0;
 	int writesize = this->writesize;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
+			__func__, (unsigned int) from, (int) len);
 
 	if (ops->mode == MTD_OOB_AUTO)
 		oobsize = this->ecclayout->oobavail;
@@ -1157,7 +1199,8 @@ static int onenand_read_ops_nolock(struc
 
 	/* Do not allow reads past end of device */
 	if ((from + len) > mtd->size) {
-		printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n");
+		printk(KERN_ERR "%s: Attempt read beyond end of device\n",
+			__func__);
 		ops->retlen = 0;
 		ops->oobretlen = 0;
 		return -EINVAL;
@@ -1275,7 +1318,8 @@ static int onenand_read_oob_nolock(struc
 
 	from += ops->ooboffs;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
+		__func__, (unsigned int) from, (int) len);
 
 	/* Initialize return length value */
 	ops->oobretlen = 0;
@@ -1288,7 +1332,8 @@ static int onenand_read_oob_nolock(struc
 	column = from & (mtd->oobsize - 1);
 
 	if (unlikely(column >= oobsize)) {
-		printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n");
+		printk(KERN_ERR "%s: Attempted to start read outside oob\n",
+			__func__);
 		return -EINVAL;
 	}
 
@@ -1296,7 +1341,8 @@ static int onenand_read_oob_nolock(struc
 	if (unlikely(from >= mtd->size ||
 		     column + len > ((mtd->size >> this->page_shift) -
 				     (from >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n");
+		printk(KERN_ERR "%s: Attempted to read beyond end of device\n",
+			__func__);
 		return -EINVAL;
 	}
 
@@ -1319,7 +1365,8 @@ static int onenand_read_oob_nolock(struc
 			ret = onenand_recover_lsb(mtd, from, ret);
 
 		if (ret && ret != -EBADMSG) {
-			printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
+			printk(KERN_ERR "%s: read failed = 0x%x\n",
+				__func__, ret);
 			break;
 		}
 
@@ -1450,20 +1497,21 @@ static int onenand_bbt_wait(struct mtd_i
 	if (interrupt & ONENAND_INT_READ) {
 		int ecc = onenand_read_ecc(this);
 		if (ecc & ONENAND_ECC_2BIT_ALL) {
-			printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
-				", controller error 0x%04x\n", ecc, ctrl);
+			printk(KERN_WARNING "%s: ecc error = 0x%04x, "
+				"controller error 0x%04x\n",
+				__func__, ecc, ctrl);
 			return ONENAND_BBT_READ_ECC_ERROR;
 		}
 	} else {
-		printk(KERN_ERR "onenand_bbt_wait: read timeout!"
-			"ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
+		printk(KERN_ERR "%s: read timeout! ctrl=0x%04x intr=0x%04x\n",
+			__func__, ctrl, interrupt);
 		return ONENAND_BBT_READ_FATAL_ERROR;
 	}
 
 	/* Initial bad block case: 0x2400 or 0x0400 */
 	if (ctrl & ONENAND_CTRL_ERROR) {
-		printk(KERN_DEBUG "onenand_bbt_wait: "
-			"controller error = 0x%04x\n", ctrl);
+		printk(KERN_DEBUG "%s: controller error = 0x%04x\n",
+			__func__, ctrl);
 		return ONENAND_BBT_READ_ERROR;
 	}
 
@@ -1487,14 +1535,16 @@ int onenand_bbt_read_oob(struct mtd_info
 	size_t len = ops->ooblen;
 	u_char *buf = ops->oobbuf;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %zi\n",
+		__func__, (unsigned int) from, len);
 
 	/* Initialize return value */
 	ops->oobretlen = 0;
 
 	/* Do not allow reads past end of device */
 	if (unlikely((from + len) > mtd->size)) {
-		printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
+		printk(KERN_ERR "%s: Attempt read beyond end of device\n",
+			__func__);
 		return ONENAND_BBT_READ_FATAL_ERROR;
 	}
 
@@ -1661,21 +1711,23 @@ static int onenand_panic_write(struct mt
 	/* Wait for any existing operation to clear */
 	onenand_panic_wait(mtd);
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_panic_write: to = 0x%08x, len = %i\n",
-	      (unsigned int) to, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
+		__func__, (unsigned int) to, (int) len);
 
 	/* Initialize retlen, in case of early exit */
 	*retlen = 0;
 
 	/* Do not allow writes past end of device */
 	if (unlikely((to + len) > mtd->size)) {
-		printk(KERN_ERR "onenand_panic_write: Attempt write to past end of device\n");
+		printk(KERN_ERR "%s: Attempt write to past end of device\n",
+			__func__);
 		return -EINVAL;
 	}
 
 	/* Reject writes, which are not page aligned */
         if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
-                printk(KERN_ERR "onenand_panic_write: Attempt to write not page aligned data\n");
+		printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
+			__func__);
                 return -EINVAL;
         }
 
@@ -1711,7 +1763,7 @@ static int onenand_panic_write(struct mt
 		}
 
 		if (ret) {
-			printk(KERN_ERR "onenand_panic_write: write failed %d\n", ret);
+			printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
 			break;
 		}
 
@@ -1792,7 +1844,8 @@ static int onenand_write_ops_nolock(stru
 	u_char *oobbuf;
 	int ret = 0;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
+		__func__, (unsigned int) to, (int) len);
 
 	/* Initialize retlen, in case of early exit */
 	ops->retlen = 0;
@@ -1800,13 +1853,15 @@ static int onenand_write_ops_nolock(stru
 
 	/* Do not allow writes past end of device */
 	if (unlikely((to + len) > mtd->size)) {
-		printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n");
+		printk(KERN_ERR "%s: Attempt write to past end of device\n",
+			__func__);
 		return -EINVAL;
 	}
 
 	/* Reject writes, which are not page aligned */
         if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
-                printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
+		printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
+			__func__);
                 return -EINVAL;
         }
 
@@ -1879,7 +1934,8 @@ static int onenand_write_ops_nolock(stru
 			onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
 			if (ret) {
 				written -= prevlen;
-				printk(KERN_ERR "onenand_write_ops_nolock: write failed %d\n", ret);
+				printk(KERN_ERR "%s: write failed %d\n",
+					__func__, ret);
 				break;
 			}
 
@@ -1887,7 +1943,8 @@ static int onenand_write_ops_nolock(stru
 				/* Only check verify write turn on */
 				ret = onenand_verify(mtd, buf - len, to - len, len);
 				if (ret)
-					printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+					printk(KERN_ERR "%s: verify failed %d\n",
+						__func__, ret);
 				break;
 			}
 
@@ -1905,14 +1962,16 @@ static int onenand_write_ops_nolock(stru
 			/* In partial page write we don't update bufferram */
 			onenand_update_bufferram(mtd, to, !ret && !subpage);
 			if (ret) {
-				printk(KERN_ERR "onenand_write_ops_nolock: write failed %d\n", ret);
+				printk(KERN_ERR "%s: write failed %d\n",
+					__func__, ret);
 				break;
 			}
 
 			/* Only check verify write turn on */
 			ret = onenand_verify(mtd, buf, to, thislen);
 			if (ret) {
-				printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+				printk(KERN_ERR "%s: verify failed %d\n",
+					__func__, ret);
 				break;
 			}
 
@@ -1968,7 +2027,8 @@ static int onenand_write_oob_nolock(stru
 
 	to += ops->ooboffs;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
+		__func__, (unsigned int) to, (int) len);
 
 	/* Initialize retlen, in case of early exit */
 	ops->oobretlen = 0;
@@ -1981,14 +2041,15 @@ static int onenand_write_oob_nolock(stru
 	column = to & (mtd->oobsize - 1);
 
 	if (unlikely(column >= oobsize)) {
-		printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n");
+		printk(KERN_ERR "%s: Attempted to start write outside oob\n",
+			__func__);
 		return -EINVAL;
 	}
 
 	/* For compatibility with NAND: Do not allow write past end of page */
 	if (unlikely(column + len > oobsize)) {
-		printk(KERN_ERR "onenand_write_oob_nolock: "
-		      "Attempt to write past end of page\n");
+		printk(KERN_ERR "%s: Attempt to write past end of page\n",
+			__func__);
 		return -EINVAL;
 	}
 
@@ -1996,7 +2057,8 @@ static int onenand_write_oob_nolock(stru
 	if (unlikely(to >= mtd->size ||
 		     column + len > ((mtd->size >> this->page_shift) -
 				     (to >> this->page_shift)) * oobsize)) {
-		printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n");
+		printk(KERN_ERR "%s: Attempted to write past end of device\n",
+		       __func__);
 		return -EINVAL;
 	}
 
@@ -2038,13 +2100,14 @@ static int onenand_write_oob_nolock(stru
 
 		ret = this->wait(mtd, FL_WRITING);
 		if (ret) {
-			printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret);
+			printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
 			break;
 		}
 
 		ret = onenand_verify_oob(mtd, oobbuf, to);
 		if (ret) {
-			printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret);
+			printk(KERN_ERR "%s: verify failed %d\n",
+				__func__, ret);
 			break;
 		}
 
@@ -2140,78 +2203,186 @@ static int onenand_block_isbad_nolock(st
 	return bbm->isbad_bbt(mtd, ofs, allowbbt);
 }
 
+
+static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
+					   struct erase_info *instr)
+{
+	struct onenand_chip *this = mtd->priv;
+	loff_t addr = instr->addr;
+	int len = instr->len;
+	unsigned int block_size = (1 << this->erase_shift);
+	int ret = 0;
+
+	while (len) {
+		this->command(mtd, ONENAND_CMD_ERASE_VERIFY, addr, block_size);
+		ret = this->wait(mtd, FL_VERIFYING_ERASE);
+		if (ret) {
+			printk(KERN_ERR "%s: Failed verify, block %d\n",
+			       __func__, onenand_block(this, addr));
+			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr = addr;
+			return -1;
+		}
+		len -= block_size;
+		addr += block_size;
+	}
+	return 0;
+}
+
 /**
- * onenand_erase - [MTD Interface] erase block(s)
+ * onenand_multiblock_erase - [Internal] erase block(s) using multiblock erase
  * @param mtd		MTD device structure
  * @param instr		erase instruction
+ * @param region	erase region
  *
- * Erase one ore more blocks
+ * Erase one or more blocks up to 64 block at a time
  */
-static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int onenand_multiblock_erase(struct mtd_info *mtd,
+				    struct erase_info *instr,
+				    unsigned int block_size)
 {
 	struct onenand_chip *this = mtd->priv;
-	unsigned int block_size;
 	loff_t addr = instr->addr;
-	loff_t len = instr->len;
-	int ret = 0, i;
-	struct mtd_erase_region_info *region = NULL;
-	loff_t region_end = 0;
+	int len = instr->len;
+	int eb_count = 0;
+	int ret = 0;
+	int bdry_block = 0;
 
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len);
+	instr->state = MTD_ERASING;
 
-	/* Do not allow erase past end of device */
-	if (unlikely((len + addr) > mtd->size)) {
-		printk(KERN_ERR "onenand_erase: Erase past end of device\n");
-		return -EINVAL;
+	if (ONENAND_IS_DDP(this)) {
+		loff_t bdry_addr = this->chipsize >> 1;
+		if (addr < bdry_addr && (addr + len) > bdry_addr)
+			bdry_block = bdry_addr >> this->erase_shift;
 	}
 
-	if (FLEXONENAND(this)) {
-		/* Find the eraseregion of this address */
-		i = flexonenand_region(mtd, addr);
-		region = &mtd->eraseregions[i];
+	/* Pre-check bbs */
+	while (len) {
+		/* Check if we have a bad block, we do not erase bad blocks */
+		if (onenand_block_isbad_nolock(mtd, addr, 0)) {
+			printk(KERN_WARNING "%s: attempt to erase a bad block "
+			       "at addr 0x%012llx\n",
+			       __func__, (unsigned long long) addr);
+			instr->state = MTD_ERASE_FAILED;
+			return -EIO;
+		}
+		len -= block_size;
+		addr += block_size;
+	}
 
-		block_size = region->erasesize;
-		region_end = region->offset + region->erasesize * region->numblocks;
+	len = instr->len;
+	addr = instr->addr;
 
-		/* Start address within region must align on block boundary.
-		 * Erase region's start offset is always block start address.
-		 */
-		if (unlikely((addr - region->offset) & (block_size - 1))) {
-			printk(KERN_ERR "onenand_erase: Unaligned address\n");
-			return -EINVAL;
+	/* loop over 64 eb batches */
+	while (len) {
+		struct erase_info verify_instr = *instr;
+		int max_eb_count = MB_ERASE_MAX_BLK_COUNT;
+
+		verify_instr.addr = addr;
+		verify_instr.len = 0;
+
+		/* do not cross chip boundary */
+		if (bdry_block) {
+			int this_block = (addr >> this->erase_shift);
+
+			if (this_block < bdry_block) {
+				max_eb_count = min(max_eb_count,
+						   (bdry_block - this_block));
+			}
 		}
-	} else {
-		block_size = 1 << this->erase_shift;
 
-		/* Start address must align on block boundary */
-		if (unlikely(addr & (block_size - 1))) {
-			printk(KERN_ERR "onenand_erase: Unaligned address\n");
-			return -EINVAL;
+		eb_count = 0;
+
+		while (len > block_size && eb_count < (max_eb_count - 1)) {
+			this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE,
+				      addr, block_size);
+			onenand_invalidate_bufferram(mtd, addr, block_size);
+
+			ret = this->wait(mtd, FL_PREPARING_ERASE);
+			if (ret) {
+				printk(KERN_ERR "%s: Failed multiblock erase, "
+				       "block %d\n", __func__,
+				       onenand_block(this, addr));
+				instr->state = MTD_ERASE_FAILED;
+				instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+				return -EIO;
+			}
+
+			len -= block_size;
+			addr += block_size;
+			eb_count++;
+		}
+
+		/* last block of 64-eb series */
+		cond_resched();
+		this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
+		onenand_invalidate_bufferram(mtd, addr, block_size);
+
+		ret = this->wait(mtd, FL_ERASING);
+		/* Check if it is write protected */
+		if (ret) {
+			printk(KERN_ERR "%s: Failed erase, block %d\n",
+			       __func__, onenand_block(this, addr));
+			instr->state = MTD_ERASE_FAILED;
+			instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+			return -EIO;
+		}
+
+		len -= block_size;
+		addr += block_size;
+		eb_count++;
+
+		/* verify */
+		verify_instr.len = eb_count * block_size;
+		if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
+			instr->state = verify_instr.state;
+			instr->fail_addr = verify_instr.fail_addr;
+			return -EIO;
 		}
-	}
 
-	/* Length must align on block boundary */
-	if (unlikely(len & (block_size - 1))) {
-		printk(KERN_ERR "onenand_erase: Length not block aligned\n");
-		return -EINVAL;
 	}
+	return 0;
+}
 
-	instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
 
-	/* Grab the lock and see if the device is available */
-	onenand_get_device(mtd, FL_ERASING);
+/**
+ * onenand_block_by_block_erase - [Internal] erase block(s) using regular erase
+ * @param mtd		MTD device structure
+ * @param instr		erase instruction
+ * @param region	erase region
+ * @param block_size	erase block size
+ *
+ * Erase one or more blocks one block at a time
+ */
+static int onenand_block_by_block_erase(struct mtd_info *mtd,
+					struct erase_info *instr,
+					struct mtd_erase_region_info *region,
+					unsigned int block_size)
+{
+	struct onenand_chip *this = mtd->priv;
+	loff_t addr = instr->addr;
+	int len = instr->len;
+	loff_t region_end = 0;
+	int ret = 0;
+
+	if (region) {
+		/* region is set for Flex-OneNAND */
+		region_end = region->offset + region->erasesize * region->numblocks;
+	}
 
-	/* Loop through the blocks */
 	instr->state = MTD_ERASING;
 
+	/* Loop through the blocks */
 	while (len) {
 		cond_resched();
 
 		/* Check if we have a bad block, we do not erase bad blocks */
 		if (onenand_block_isbad_nolock(mtd, addr, 0)) {
-			printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%012llx\n", (unsigned long long) addr);
+			printk(KERN_WARNING "%s: attempt to erase a bad block "
+					"at addr 0x%012llx\n",
+					__func__, (unsigned long long) addr);
 			instr->state = MTD_ERASE_FAILED;
-			goto erase_exit;
+			return -EIO;
 		}
 
 		this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
@@ -2221,11 +2392,11 @@ static int onenand_erase(struct mtd_info
 		ret = this->wait(mtd, FL_ERASING);
 		/* Check, if it is write protected */
 		if (ret) {
-			printk(KERN_ERR "onenand_erase: Failed erase, block %d\n",
-						 onenand_block(this, addr));
+			printk(KERN_ERR "%s: Failed erase, block %d\n",
+				__func__, onenand_block(this, addr));
 			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = addr;
-			goto erase_exit;
+			return -EIO;
 		}
 
 		len -= block_size;
@@ -2241,25 +2412,88 @@ static int onenand_erase(struct mtd_info
 
 			if (len & (block_size - 1)) {
 				/* FIXME: This should be handled at MTD partitioning level. */
-				printk(KERN_ERR "onenand_erase: Unaligned address\n");
-				goto erase_exit;
+				printk(KERN_ERR "%s: Unaligned address\n",
+					__func__);
+				return -EIO;
 			}
 		}
+	}
+	return 0;
+}
 
+/**
+ * onenand_erase - [MTD Interface] erase block(s)
+ * @param mtd		MTD device structure
+ * @param instr		erase instruction
+ *
+ * Erase one or more blocks
+ */
+static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct onenand_chip *this = mtd->priv;
+	unsigned int block_size;
+	loff_t addr = instr->addr;
+	loff_t len = instr->len;
+	int ret = 0;
+	struct mtd_erase_region_info *region = NULL;
+	loff_t region_offset = 0;
+
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: start=0x%012llx, len=%llu\n", __func__,
+	      (unsigned long long) instr->addr, (unsigned long long) instr->len);
+
+	/* Do not allow erase past end of device */
+	if (unlikely((len + addr) > mtd->size)) {
+		printk(KERN_ERR "%s: Erase past end of device\n", __func__);
+		return -EINVAL;
 	}
 
-	instr->state = MTD_ERASE_DONE;
+	if (FLEXONENAND(this)) {
+		/* Find the eraseregion of this address */
+		int i = flexonenand_region(mtd, addr);
 
-erase_exit:
+		region = &mtd->eraseregions[i];
+		block_size = region->erasesize;
 
-	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
+		/* Start address within region must align on block boundary.
+		 * Erase region's start offset is always block start address.
+		 */
+		region_offset = region->offset;
+	} else
+		block_size = 1 << this->erase_shift;
+
+	/* Start address must align on block boundary */
+	if (unlikely((addr - region_offset) & (block_size - 1))) {
+		printk(KERN_ERR "%s: Unaligned address\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Length must align on block boundary */
+	if (unlikely(len & (block_size - 1))) {
+		printk(KERN_ERR "%s: Length not block aligned\n", __func__);
+		return -EINVAL;
+	}
+
+	instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+
+	/* Grab the lock and see if the device is available */
+	onenand_get_device(mtd, FL_ERASING);
+
+	if (region || instr->len < MB_ERASE_MIN_BLK_COUNT * block_size) {
+		/* region is set for Flex-OneNAND (no mb erase) */
+		ret = onenand_block_by_block_erase(mtd, instr,
+						   region, block_size);
+	} else {
+		ret = onenand_multiblock_erase(mtd, instr, block_size);
+	}
 
 	/* Deselect and wake up anyone waiting on the device */
 	onenand_release_device(mtd);
 
 	/* Do call back function */
-	if (!ret)
+	if (!ret) {
+		instr->state = MTD_ERASE_DONE;
 		mtd_erase_callback(instr);
+	}
 
 	return ret;
 }
@@ -2272,7 +2506,7 @@ erase_exit:
  */
 static void onenand_sync(struct mtd_info *mtd)
 {
-	DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
+	DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
 
 	/* Grab the lock and see if the device is available */
 	onenand_get_device(mtd, FL_SYNCING);
@@ -2406,7 +2640,8 @@ static int onenand_do_lock_cmd(struct mt
 		/* Check lock status */
 		status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
 		if (!(status & wp_status_mask))
-			printk(KERN_ERR "wp status = 0x%x\n", status);
+			printk(KERN_ERR "%s: wp status = 0x%x\n",
+				__func__, status);
 
 		return 0;
 	}
@@ -2435,7 +2670,8 @@ static int onenand_do_lock_cmd(struct mt
 		/* Check lock status */
 		status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
 		if (!(status & wp_status_mask))
-			printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+			printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
+				__func__, block, status);
 	}
 
 	return 0;
@@ -2502,7 +2738,8 @@ static int onenand_check_lock_status(str
 		/* Check lock status */
 		status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
 		if (!(status & ONENAND_WP_US)) {
-			printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+			printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n",
+				__func__, block, status);
 			return 0;
 		}
 	}
@@ -2557,6 +2794,208 @@ static void onenand_unlock_all(struct mt
 
 #ifdef CONFIG_MTD_ONENAND_OTP
 
+/**
+ * onenand_otp_command - Send OTP specific command to OneNAND device
+ * @param mtd	 MTD device structure
+ * @param cmd	 the command to be sent
+ * @param addr	 offset to read from or write to
+ * @param len	 number of bytes to read or write
+ */
+static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
+				size_t len)
+{
+	struct onenand_chip *this = mtd->priv;
+	int value, block, page;
+
+	/* Address translation */
+	switch (cmd) {
+	case ONENAND_CMD_OTP_ACCESS:
+		block = (int) (addr >> this->erase_shift);
+		page = -1;
+		break;
+
+	default:
+		block = (int) (addr >> this->erase_shift);
+		page = (int) (addr >> this->page_shift);
+
+		if (ONENAND_IS_2PLANE(this)) {
+			/* Make the even block number */
+			block &= ~1;
+			/* Is it the odd plane? */
+			if (addr & this->writesize)
+				block++;
+			page >>= 1;
+		}
+		page &= this->page_mask;
+		break;
+	}
+
+	if (block != -1) {
+		/* Write 'DFS, FBA' of Flash */
+		value = onenand_block_address(this, block);
+		this->write_word(value, this->base +
+				ONENAND_REG_START_ADDRESS1);
+	}
+
+	if (page != -1) {
+		/* Now we use page size operation */
+		int sectors = 4, count = 4;
+		int dataram;
+
+		switch (cmd) {
+		default:
+			if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
+				cmd = ONENAND_CMD_2X_PROG;
+			dataram = ONENAND_CURRENT_BUFFERRAM(this);
+			break;
+		}
+
+		/* Write 'FPA, FSA' of Flash */
+		value = onenand_page_address(page, sectors);
+		this->write_word(value, this->base +
+				ONENAND_REG_START_ADDRESS8);
+
+		/* Write 'BSA, BSC' of DataRAM */
+		value = onenand_buffer_address(dataram, sectors, count);
+		this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
+	}
+
+	/* Interrupt clear */
+	this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
+
+	/* Write command */
+	this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
+
+	return 0;
+}
+
+/**
+ * onenand_otp_write_oob_nolock - [Internal] OneNAND write out-of-band, specific to OTP
+ * @param mtd		MTD device structure
+ * @param to		offset to write to
+ * @param len		number of bytes to write
+ * @param retlen	pointer to variable to store the number of written bytes
+ * @param buf		the data to write
+ *
+ * OneNAND write out-of-band only for OTP
+ */
+static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to,
+				    struct mtd_oob_ops *ops)
+{
+	struct onenand_chip *this = mtd->priv;
+	int column, ret = 0, oobsize;
+	int written = 0;
+	u_char *oobbuf;
+	size_t len = ops->ooblen;
+	const u_char *buf = ops->oobbuf;
+	int block, value, status;
+
+	to += ops->ooboffs;
+
+	/* Initialize retlen, in case of early exit */
+	ops->oobretlen = 0;
+
+	oobsize = mtd->oobsize;
+
+	column = to & (mtd->oobsize - 1);
+
+	oobbuf = this->oob_buf;
+
+	/* Loop until all data write */
+	while (written < len) {
+		int thislen = min_t(int, oobsize, len - written);
+
+		cond_resched();
+
+		block = (int) (to >> this->erase_shift);
+		/*
+		 * Write 'DFS, FBA' of Flash
+		 * Add: F100h DQ=DFS, FBA
+		 */
+
+		value = onenand_block_address(this, block);
+		this->write_word(value, this->base +
+				ONENAND_REG_START_ADDRESS1);
+
+		/*
+		 * Select DataRAM for DDP
+		 * Add: F101h DQ=DBS
+		 */
+
+		value = onenand_bufferram_address(this, block);
+		this->write_word(value, this->base +
+				ONENAND_REG_START_ADDRESS2);
+		ONENAND_SET_NEXT_BUFFERRAM(this);
+
+		/*
+		 * Enter OTP access mode
+		 */
+		this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
+		this->wait(mtd, FL_OTPING);
+
+		/* We send data to spare ram with oobsize
+		 * to prevent byte access */
+		memcpy(oobbuf + column, buf, thislen);
+
+		/*
+		 * Write Data into DataRAM
+		 * Add: 8th Word
+		 * in sector0/spare/page0
+		 * DQ=XXFCh
+		 */
+		this->write_bufferram(mtd, ONENAND_SPARERAM,
+					oobbuf, 0, mtd->oobsize);
+
+		onenand_otp_command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
+		onenand_update_bufferram(mtd, to, 0);
+		if (ONENAND_IS_2PLANE(this)) {
+			ONENAND_SET_BUFFERRAM1(this);
+			onenand_update_bufferram(mtd, to + this->writesize, 0);
+		}
+
+		ret = this->wait(mtd, FL_WRITING);
+		if (ret) {
+			printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
+			break;
+		}
+
+		/* Exit OTP access mode */
+		this->command(mtd, ONENAND_CMD_RESET, 0, 0);
+		this->wait(mtd, FL_RESETING);
+
+		status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
+		status &= 0x60;
+
+		if (status == 0x60) {
+			printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
+			printk(KERN_DEBUG "1st Block\tLOCKED\n");
+			printk(KERN_DEBUG "OTP Block\tLOCKED\n");
+		} else if (status == 0x20) {
+			printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
+			printk(KERN_DEBUG "1st Block\tLOCKED\n");
+			printk(KERN_DEBUG "OTP Block\tUN-LOCKED\n");
+		} else if (status == 0x40) {
+			printk(KERN_DEBUG "\nBLOCK\tSTATUS\n");
+			printk(KERN_DEBUG "1st Block\tUN-LOCKED\n");
+			printk(KERN_DEBUG "OTP Block\tLOCKED\n");
+		} else {
+			printk(KERN_DEBUG "Reboot to check\n");
+		}
+
+		written += thislen;
+		if (written == len)
+			break;
+
+		to += mtd->writesize;
+		buf += thislen;
+		column = 0;
+	}
+
+	ops->oobretlen = written;
+
+	return ret;
+}
+
 /* Internal OTP operation */
 typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
 		size_t *retlen, u_char *buf);
@@ -2659,11 +3098,11 @@ static int do_otp_lock(struct mtd_info *
 	struct mtd_oob_ops ops;
 	int ret;
 
-	/* Enter OTP access mode */
-	this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
-	this->wait(mtd, FL_OTPING);
-
 	if (FLEXONENAND(this)) {
+
+		/* Enter OTP access mode */
+		this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
+		this->wait(mtd, FL_OTPING);
 		/*
 		 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
 		 * main area of page 49.
@@ -2674,19 +3113,19 @@ static int do_otp_lock(struct mtd_info *
 		ops.oobbuf = NULL;
 		ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops);
 		*retlen = ops.retlen;
+
+		/* Exit OTP access mode */
+		this->command(mtd, ONENAND_CMD_RESET, 0, 0);
+		this->wait(mtd, FL_RESETING);
 	} else {
 		ops.mode = MTD_OOB_PLACE;
 		ops.ooblen = len;
 		ops.oobbuf = buf;
 		ops.ooboffs = 0;
-		ret = onenand_write_oob_nolock(mtd, from, &ops);
+		ret = onenand_otp_write_oob_nolock(mtd, from, &ops);
 		*retlen = ops.oobretlen;
 	}
 
-	/* Exit OTP access mode */
-	this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-	this->wait(mtd, FL_RESETING);
-
 	return ret;
 }
 
@@ -2717,16 +3156,21 @@ static int onenand_otp_walk(struct mtd_i
 	if (density < ONENAND_DEVICE_DENSITY_512Mb)
 		otp_pages = 20;
 	else
-		otp_pages = 10;
+		otp_pages = 50;
 
 	if (mode == MTD_OTP_FACTORY) {
 		from += mtd->writesize * otp_pages;
-		otp_pages = 64 - otp_pages;
+		otp_pages = ONENAND_PAGES_PER_BLOCK - otp_pages;
 	}
 
 	/* Check User/Factory boundary */
-	if (((mtd->writesize * otp_pages) - (from + len)) < 0)
-		return 0;
+	if (mode == MTD_OTP_USER) {
+		if (mtd->writesize * otp_pages < from + len)
+			return 0;
+	} else {
+		if (mtd->writesize * otp_pages <  len)
+			return 0;
+	}
 
 	onenand_get_device(mtd, FL_OTPING);
 	while (len > 0 && otp_pages > 0) {
@@ -2749,13 +3193,12 @@ static int onenand_otp_walk(struct mtd_i
 			*retlen += sizeof(struct otp_info);
 		} else {
 			size_t tmp_retlen;
-			int size = len;
 
 			ret = action(mtd, from, len, &tmp_retlen, buf);
 
-			buf += size;
-			len -= size;
-			*retlen += size;
+			buf += tmp_retlen;
+			len -= tmp_retlen;
+			*retlen += tmp_retlen;
 
 			if (ret)
 				break;
@@ -2868,21 +3311,11 @@ static int onenand_lock_user_prot_reg(st
 	u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
 	size_t retlen;
 	int ret;
+	unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET;
 
 	memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
 						 : mtd->oobsize);
 	/*
-	 * Note: OTP lock operation
-	 *       OTP block : 0xXXFC
-	 *       1st block : 0xXXF3 (If chip support)
-	 *       Both      : 0xXXF0 (If chip support)
-	 */
-	if (FLEXONENAND(this))
-		buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC;
-	else
-		buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
-
-	/*
 	 * Write lock mark to 8th word of sector0 of page0 of the spare0.
 	 * We write 16 bytes spare area instead of 2 bytes.
 	 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
@@ -2892,10 +3325,30 @@ static int onenand_lock_user_prot_reg(st
 	from = 0;
 	len = FLEXONENAND(this) ? mtd->writesize : 16;
 
+	/*
+	 * Note: OTP lock operation
+	 *       OTP block : 0xXXFC			XX 1111 1100
+	 *       1st block : 0xXXF3 (If chip support)	XX 1111 0011
+	 *       Both      : 0xXXF0 (If chip support)	XX 1111 0000
+	 */
+	if (FLEXONENAND(this))
+		otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET;
+
+	/* ONENAND_OTP_AREA | ONENAND_OTP_BLOCK0 | ONENAND_OTP_AREA_BLOCK0 */
+	if (otp == 1)
+		buf[otp_lock_offset] = 0xFC;
+	else if (otp == 2)
+		buf[otp_lock_offset] = 0xF3;
+	else if (otp == 3)
+		buf[otp_lock_offset] = 0xF0;
+	else if (otp != 0)
+		printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n");
+
 	ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
 
 	return ret ? : retlen;
 }
+
 #endif	/* CONFIG_MTD_ONENAND_OTP */
 
 /**
@@ -3172,7 +3625,8 @@ static int flexonenand_check_blocks_eras
 				break;
 
 		if (i != mtd->oobsize) {
-			printk(KERN_WARNING "Block %d not erased.\n", block);
+			printk(KERN_WARNING "%s: Block %d not erased.\n",
+				__func__, block);
 			return 1;
 		}
 	}
@@ -3204,8 +3658,8 @@ int flexonenand_set_boundary(struct mtd_
 	blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
 
 	if (boundary >= blksperdie) {
-		printk(KERN_ERR "flexonenand_set_boundary: Invalid boundary value. "
-				"Boundary not changed.\n");
+		printk(KERN_ERR "%s: Invalid boundary value. "
+				"Boundary not changed.\n", __func__);
 		return -EINVAL;
 	}
 
@@ -3214,7 +3668,8 @@ int flexonenand_set_boundary(struct mtd_
 	new = boundary + (die * this->density_mask);
 	ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
 	if (ret) {
-		printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
+		printk(KERN_ERR "%s: Please erase blocks "
+				"before boundary change\n", __func__);
 		return ret;
 	}
 
@@ -3227,12 +3682,12 @@ int flexonenand_set_boundary(struct mtd_
 
 	thisboundary = this->read_word(this->base + ONENAND_DATARAM);
 	if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
-		printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
+		printk(KERN_ERR "%s: boundary locked\n", __func__);
 		ret = 1;
 		goto out;
 	}
 
-	printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
+	printk(KERN_INFO "Changing die %d boundary: %d%s\n",
 			die, boundary, lock ? "(Locked)" : "(Unlocked)");
 
 	addr = die ? this->diesize[0] : 0;
@@ -3243,7 +3698,8 @@ int flexonenand_set_boundary(struct mtd_
 	this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
 	ret = this->wait(mtd, FL_ERASING);
 	if (ret) {
-		printk(KERN_ERR "flexonenand_set_boundary: Failed PI erase for Die %d\n", die);
+		printk(KERN_ERR "%s: Failed PI erase for Die %d\n",
+		       __func__, die);
 		goto out;
 	}
 
@@ -3251,7 +3707,8 @@ int flexonenand_set_boundary(struct mtd_
 	this->command(mtd, ONENAND_CMD_PROG, addr, 0);
 	ret = this->wait(mtd, FL_WRITING);
 	if (ret) {
-		printk(KERN_ERR "flexonenand_set_boundary: Failed PI write for Die %d\n", die);
+		printk(KERN_ERR "%s: Failed PI write for Die %d\n",
+			__func__, die);
 		goto out;
 	}
 
@@ -3408,8 +3865,8 @@ static void onenand_resume(struct mtd_in
 	if (this->state == FL_PM_SUSPENDED)
 		onenand_release_device(mtd);
 	else
-		printk(KERN_ERR "resume() called for the chip which is not"
-				"in suspended state\n");
+		printk(KERN_ERR "%s: resume() called for the chip which is not "
+				"in suspended state\n", __func__);
 }
 
 /**
@@ -3464,7 +3921,8 @@ int onenand_scan(struct mtd_info *mtd, i
 	if (!this->page_buf) {
 		this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
 		if (!this->page_buf) {
-			printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
+			printk(KERN_ERR "%s: Can't allocate page_buf\n",
+				__func__);
 			return -ENOMEM;
 		}
 		this->options |= ONENAND_PAGEBUF_ALLOC;
@@ -3472,7 +3930,8 @@ int onenand_scan(struct mtd_info *mtd, i
 	if (!this->oob_buf) {
 		this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
 		if (!this->oob_buf) {
-			printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
+			printk(KERN_ERR "%s: Can't allocate oob_buf\n",
+				__func__);
 			if (this->options & ONENAND_PAGEBUF_ALLOC) {
 				this->options &= ~ONENAND_PAGEBUF_ALLOC;
 				kfree(this->page_buf);
@@ -3505,8 +3964,8 @@ int onenand_scan(struct mtd_info *mtd, i
 		break;
 
 	default:
-		printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
-			mtd->oobsize);
+		printk(KERN_WARNING "%s: No OOB scheme defined for oobsize %d\n",
+			__func__, mtd->oobsize);
 		mtd->subpage_sft = 0;
 		/* To prevent kernel oops */
 		this->ecclayout = &onenand_oob_32;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/Makefile linux-libre-2.6.33-gnu1/drivers/mtd/tests/Makefile
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,3 +5,4 @@ obj-$(CONFIG_MTD_TESTS) += mtd_speedtest
 obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o
 obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o
 obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o
+obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_nandecctest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_nandecctest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_nandecctest.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_nandecctest.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,87 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <linux/jiffies.h>
+#include <linux/mtd/nand_ecc.h>
+
+#if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE)
+
+static void inject_single_bit_error(void *data, size_t size)
+{
+	unsigned long offset = random32() % (size * BITS_PER_BYTE);
+
+	__change_bit(offset, data);
+}
+
+static unsigned char data[512];
+static unsigned char error_data[512];
+
+static int nand_ecc_test(const size_t size)
+{
+	unsigned char code[3];
+	unsigned char error_code[3];
+	char testname[30];
+
+	BUG_ON(sizeof(data) < size);
+
+	sprintf(testname, "nand-ecc-%zu", size);
+
+	get_random_bytes(data, size);
+
+	memcpy(error_data, data, size);
+	inject_single_bit_error(error_data, size);
+
+	__nand_calculate_ecc(data, size, code);
+	__nand_calculate_ecc(error_data, size, error_code);
+	__nand_correct_data(error_data, code, error_code, size);
+
+	if (!memcmp(data, error_data, size)) {
+		printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname);
+		return 0;
+	}
+
+	printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname);
+
+	printk(KERN_DEBUG "hexdump of data:\n");
+	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
+			data, size, false);
+	printk(KERN_DEBUG "hexdump of error data:\n");
+	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
+			error_data, size, false);
+
+	return -1;
+}
+
+#else
+
+static int nand_ecc_test(const size_t size)
+{
+	return 0;
+}
+
+#endif
+
+static int __init ecc_test_init(void)
+{
+	srandom32(jiffies);
+
+	nand_ecc_test(256);
+	nand_ecc_test(512);
+
+	return 0;
+}
+
+static void __exit ecc_test_exit(void)
+{
+}
+
+module_init(ecc_test_init);
+module_exit(ecc_test_exit);
+
+MODULE_DESCRIPTION("NAND ECC function test module");
+MODULE_AUTHOR("Akinobu Mita");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_oobtest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_oobtest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_oobtest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_oobtest.c	2010-02-24 13:52:17.000000000 -0500
@@ -343,7 +343,6 @@ static int scan_for_bad_eraseblocks(void
 		printk(PRINT_PREF "error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
-	memset(bbt, 0 , ebcnt);
 
 	printk(PRINT_PREF "scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
@@ -392,7 +391,6 @@ static int __init mtd_oobtest_init(void)
 	       mtd->writesize, ebcnt, pgcnt, mtd->oobsize);
 
 	err = -ENOMEM;
-	mtd->erasesize = mtd->erasesize;
 	readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!readbuf) {
 		printk(PRINT_PREF "error: cannot allocate memory\n");
@@ -476,18 +474,10 @@ static int __init mtd_oobtest_init(void)
 	use_len_max = mtd->ecclayout->oobavail;
 	vary_offset = 1;
 	simple_srand(5);
-	printk(PRINT_PREF "writing OOBs of whole device\n");
-	for (i = 0; i < ebcnt; ++i) {
-		if (bbt[i])
-			continue;
-		err = write_eraseblock(i);
-		if (err)
-			goto out;
-		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
-		cond_resched();
-	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+
+	err = write_whole_device();
+	if (err)
+		goto out;
 
 	/* Check all eraseblocks */
 	use_offset = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_pagetest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_pagetest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_pagetest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_pagetest.c	2010-02-24 13:52:17.000000000 -0500
@@ -523,6 +523,7 @@ static int __init mtd_pagetest_init(void
 	do_div(tmp, mtd->erasesize);
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / mtd->writesize;
+	pgsize = mtd->writesize;
 
 	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_readtest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_readtest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_readtest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_readtest.c	2010-02-24 13:52:17.000000000 -0500
@@ -147,6 +147,10 @@ static int scan_for_bad_eraseblocks(void
 	}
 	memset(bbt, 0 , ebcnt);
 
+	/* NOR flash does not implement block_isbad */
+	if (mtd->block_isbad == NULL)
+		return 0;
+
 	printk(PRINT_PREF "scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
@@ -184,7 +188,7 @@ static int __init mtd_readtest_init(void
 	tmp = mtd->size;
 	do_div(tmp, mtd->erasesize);
 	ebcnt = tmp;
-	pgcnt = mtd->erasesize / mtd->writesize;
+	pgcnt = mtd->erasesize / pgsize;
 
 	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_speedtest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_speedtest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_speedtest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_speedtest.c	2010-02-24 13:52:17.000000000 -0500
@@ -301,6 +301,10 @@ static int scan_for_bad_eraseblocks(void
 	}
 	memset(bbt, 0 , ebcnt);
 
+	/* NOR flash does not implement block_isbad */
+	if (mtd->block_isbad == NULL)
+		goto out;
+
 	printk(PRINT_PREF "scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
@@ -309,6 +313,7 @@ static int scan_for_bad_eraseblocks(void
 		cond_resched();
 	}
 	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+out:
 	goodebcnt = ebcnt - bad;
 	return 0;
 }
@@ -340,7 +345,7 @@ static int __init mtd_speedtest_init(voi
 	tmp = mtd->size;
 	do_div(tmp, mtd->erasesize);
 	ebcnt = tmp;
-	pgcnt = mtd->erasesize / mtd->writesize;
+	pgcnt = mtd->erasesize / pgsize;
 
 	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_stresstest.c linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_stresstest.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/tests/mtd_stresstest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/tests/mtd_stresstest.c	2010-02-24 13:52:17.000000000 -0500
@@ -227,6 +227,10 @@ static int scan_for_bad_eraseblocks(void
 	}
 	memset(bbt, 0 , ebcnt);
 
+	/* NOR flash does not implement block_isbad */
+	if (mtd->block_isbad == NULL)
+		return 0;
+
 	printk(PRINT_PREF "scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
@@ -265,7 +269,7 @@ static int __init mtd_stresstest_init(vo
 	tmp = mtd->size;
 	do_div(tmp, mtd->erasesize);
 	ebcnt = tmp;
-	pgcnt = mtd->erasesize / mtd->writesize;
+	pgcnt = mtd->erasesize / pgsize;
 
 	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/ubi/cdev.c linux-libre-2.6.33-gnu1/drivers/mtd/ubi/cdev.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/ubi/cdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/ubi/cdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -853,7 +853,6 @@ static long ubi_cdev_ioctl(struct file *
 			break;
 		}
 
-		req.name[req.name_len] = '\0';
 		err = verify_mkvol_req(ubi, &req);
 		if (err)
 			break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/ubi/kapi.c linux-libre-2.6.33-gnu1/drivers/mtd/ubi/kapi.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/ubi/kapi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/ubi/kapi.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,8 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
 #include <asm/div64.h>
 #include "ubi.h"
 
@@ -280,6 +282,43 @@ struct ubi_volume_desc *ubi_open_volume_
 EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
 
 /**
+ * ubi_open_volume_path - open UBI volume by its character device node path.
+ * @pathname: volume character device node path
+ * @mode: open mode
+ *
+ * This function is similar to 'ubi_open_volume()', but opens a volume the path
+ * to its character device node.
+ */
+struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
+{
+	int error, ubi_num, vol_id, mod;
+	struct inode *inode;
+	struct path path;
+
+	dbg_gen("open volume %s, mode %d", pathname, mode);
+
+	if (!pathname || !*pathname)
+		return ERR_PTR(-EINVAL);
+
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	if (error)
+		return ERR_PTR(error);
+
+	inode = path.dentry->d_inode;
+	mod = inode->i_mode;
+	ubi_num = ubi_major2num(imajor(inode));
+	vol_id = iminor(inode) - 1;
+	path_put(&path);
+
+	if (!S_ISCHR(mod))
+		return ERR_PTR(-EINVAL);
+	if (vol_id >= 0 && ubi_num >= 0)
+		return ubi_open_volume(ubi_num, vol_id, mode);
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(ubi_open_volume_path);
+
+/**
  * ubi_close_volume - close UBI volume.
  * @desc: volume descriptor
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/ubi/Kconfig linux-libre-2.6.33-gnu1/drivers/mtd/ubi/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/mtd/ubi/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/ubi/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/mtd/ubi/Kconfig
-
 menu "UBI - Unsorted block images"
 	depends on MTD
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/ubi/upd.c linux-libre-2.6.33-gnu1/drivers/mtd/ubi/upd.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/ubi/upd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/ubi/upd.c	2010-02-24 13:52:17.000000000 -0500
@@ -147,12 +147,15 @@ int ubi_start_update(struct ubi_device *
 	}
 
 	if (bytes == 0) {
+		err = ubi_wl_flush(ubi);
+		if (err)
+			return err;
+
 		err = clear_update_marker(ubi, vol, 0);
 		if (err)
 			return err;
-		err = ubi_wl_flush(ubi);
-		if (!err)
-			vol->updating = 0;
+		vol->updating = 0;
+		return 0;
 	}
 
 	vol->upd_buf = vmalloc(ubi->leb_size);
@@ -362,16 +365,16 @@ int ubi_more_update_data(struct ubi_devi
 
 	ubi_assert(vol->upd_received <= vol->upd_bytes);
 	if (vol->upd_received == vol->upd_bytes) {
+		err = ubi_wl_flush(ubi);
+		if (err)
+			return err;
 		/* The update is finished, clear the update marker */
 		err = clear_update_marker(ubi, vol, vol->upd_bytes);
 		if (err)
 			return err;
-		err = ubi_wl_flush(ubi);
-		if (err == 0) {
-			vol->updating = 0;
-			err = to_write;
-			vfree(vol->upd_buf);
-		}
+		vol->updating = 0;
+		err = to_write;
+		vfree(vol->upd_buf);
 	}
 
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/mtd/ubi/vtbl.c linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vtbl.c
--- linux-libre-2.6.32-gnu1/drivers/mtd/ubi/vtbl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/mtd/ubi/vtbl.c	2010-02-24 13:52:17.000000000 -0500
@@ -566,6 +566,7 @@ static int init_volumes(struct ubi_devic
 		vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs);
 		vol->alignment = be32_to_cpu(vtbl[i].alignment);
 		vol->data_pad = be32_to_cpu(vtbl[i].data_pad);
+		vol->upd_marker = vtbl[i].upd_marker;
 		vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ?
 					UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
 		vol->name_len = be16_to_cpu(vtbl[i].name_len);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c501.c linux-libre-2.6.33-gnu1/drivers/net/3c501.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c501.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c501.c	2010-02-24 13:52:17.000000000 -0500
@@ -249,11 +249,11 @@ static int __init el1_probe1(struct net_
 	 *	for the Sager NP943 prefix.
 	 */
 
-	if (station_addr[0] == 0x02  &&  station_addr[1] == 0x60
-						&& station_addr[2] == 0x8c)
+	if (station_addr[0] == 0x02 && station_addr[1] == 0x60 &&
+	    station_addr[2] == 0x8c)
 		mname = "3c501";
-	else if (station_addr[0] == 0x00  &&  station_addr[1] == 0x80
-						&& station_addr[2] == 0xC8)
+	else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 &&
+		 station_addr[2] == 0xC8)
 		mname = "NP943";
 	else {
 		release_region(ioaddr, EL1_IO_EXTENT);
@@ -345,7 +345,7 @@ static int el_open(struct net_device *de
 	if (el_debug > 2)
 		pr_debug("%s: Doing el_open()...\n", dev->name);
 
-	retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
+	retval = request_irq(dev->irq, el_interrupt, 0, dev->name, dev);
 	if (retval)
 		return retval;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c503.c linux-libre-2.6.33-gnu1/drivers/net/3c503.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c503.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c503.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,8 +214,8 @@ el2_probe1(struct net_device *dev, int i
     iobase_reg = inb(ioaddr+0x403);
     membase_reg = inb(ioaddr+0x404);
     /* ASIC location registers should be 0 or have only a single bit set. */
-    if (   (iobase_reg  & (iobase_reg - 1))
-	|| (membase_reg & (membase_reg - 1))) {
+    if ((iobase_reg  & (iobase_reg - 1)) ||
+	(membase_reg & (membase_reg - 1))) {
 	retval = -ENODEV;
 	goto out1;
     }
@@ -291,8 +291,8 @@ el2_probe1(struct net_device *dev, int i
 	    writel(0xba5eba5e, mem_base);
 	    for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
 		writel(test_val, mem_base + i);
-		if (readl(mem_base) != 0xba5eba5e
-		    || readl(mem_base + i) != test_val) {
+		if (readl(mem_base) != 0xba5eba5e ||
+		    readl(mem_base + i) != test_val) {
 		    pr_warning("3c503: memory failure or memory address conflict.\n");
 		    dev->mem_start = 0;
 		    ei_status.name = "3c503-PIO";
@@ -397,9 +397,10 @@ el2_open(struct net_device *dev)
 		unsigned long cookie = probe_irq_on();
 		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
 		outb_p(0x00, E33G_IDCFR);
-		if (*irqp == probe_irq_off(cookie)	/* It's a good IRQ line! */
-		    && ((retval = request_irq(dev->irq = *irqp,
-		    eip_interrupt, 0, dev->name, dev)) == 0))
+		if (*irqp == probe_irq_off(cookie) &&	/* It's a good IRQ line! */
+		    ((retval = request_irq(dev->irq = *irqp,
+					   eip_interrupt, 0,
+					   dev->name, dev)) == 0))
 		    break;
 	    } else {
 		    if (retval != -EBUSY)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c505.c linux-libre-2.6.33-gnu1/drivers/net/3c505.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c505.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c505.c	2010-02-24 13:52:17.000000000 -0500
@@ -886,7 +886,7 @@ static int elp_open(struct net_device *d
 	/*
 	 * install our interrupt service routine
 	 */
-	if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
+	if ((retval = request_irq(dev->irq, elp_interrupt, 0, dev->name, dev))) {
 		pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
 		return retval;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c507.c linux-libre-2.6.33-gnu1/drivers/net/3c507.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c507.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c507.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,7 @@ static const char version[] =
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_ether.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -399,7 +400,7 @@ static int __init el16_probe1(struct net
 
 	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
-	irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
+	irqval = request_irq(irq, el16_interrupt, 0, DRV_NAME, dev);
 	if (irqval) {
 		pr_cont("\n");
 		pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
@@ -734,8 +735,7 @@ static void init_82586_mem(struct net_de
 	memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10);
 
 	/* Fill in the station address. */
-	memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr,
-		   sizeof(dev->dev_addr));
+	memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN);
 
 	/* The Tx-block list is written as needed.  We just set up the values. */
 	lp->tx_cmd_link = IDLELOOP + 4;
@@ -836,8 +836,8 @@ static void el16_rx(struct net_device *d
 		void __iomem *data_frame = lp->base + data_buffer_addr;
 		ushort pkt_len = readw(data_frame);
 
-		if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
-			|| (pkt_len & 0xC000) != 0xC000) {
+		if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 ||
+		    (pkt_len & 0xC000) != 0xC000) {
 			pr_err("%s: Rx frame at %#x corrupted, "
 			       "status %04x cmd %04x next %04x "
 			       "data-buf @%04x %04x.\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c509.c linux-libre-2.6.33-gnu1/drivers/net/3c509.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c509.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c509.c	2010-02-24 13:52:17.000000000 -0500
@@ -253,9 +253,9 @@ static int el3_isa_id_sequence(__be16 *p
 		   This check is needed in order not to register them twice. */
 		for (i = 0; i < el3_cards; i++) {
 			struct el3_private *lp = netdev_priv(el3_devs[i]);
-			if (lp->type == EL3_PNP
-			    && !memcmp(phys_addr, el3_devs[i]->dev_addr,
-				       ETH_ALEN)) {
+			if (lp->type == EL3_PNP &&
+			    !memcmp(phys_addr, el3_devs[i]->dev_addr,
+				    ETH_ALEN)) {
 				if (el3_debug > 3)
 					pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
 						phys_addr[0] & 0xff, phys_addr[0] >> 8,
@@ -780,7 +780,7 @@ el3_open(struct net_device *dev)
 	outw(RxReset, ioaddr + EL3_CMD);
 	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
-	i = request_irq(dev->irq, &el3_interrupt, 0, dev->name, dev);
+	i = request_irq(dev->irq, el3_interrupt, 0, dev->name, dev);
 	if (i)
 		return i;
 
@@ -835,8 +835,8 @@ el3_start_xmit(struct sk_buff *skb, stru
 #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. */
+		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),
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c515.c linux-libre-2.6.33-gnu1/drivers/net/3c515.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c515.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c515.c	2010-02-24 13:52:17.000000000 -0500
@@ -764,13 +764,14 @@ static int corkscrew_open(struct net_dev
 	/* Use the now-standard shared IRQ implementation. */
 	if (vp->capabilities == 0x11c7) {
 		/* Corkscrew: Cannot share ISA resources. */
-		if (dev->irq == 0
-		    || dev->dma == 0
-		    || request_irq(dev->irq, &corkscrew_interrupt, 0,
-				   vp->product_name, dev)) return -EAGAIN;
+		if (dev->irq == 0 ||
+		    dev->dma == 0 ||
+		    request_irq(dev->irq, corkscrew_interrupt, 0,
+				vp->product_name, dev))
+			return -EAGAIN;
 		enable_dma(dev->dma);
 		set_dma_mode(dev->dma, DMA_MODE_CASCADE);
-	} else if (request_irq(dev->irq, &corkscrew_interrupt, IRQF_SHARED,
+	} else if (request_irq(dev->irq, corkscrew_interrupt, IRQF_SHARED,
 			       vp->product_name, dev)) {
 		return -EAGAIN;
 	}
@@ -1368,8 +1369,8 @@ static int boomerang_rx(struct net_devic
 
 			/* Check if the packet is long enough to just accept without
 			   copying to a properly sized skbuff. */
-			if (pkt_len < rx_copybreak
-			    && (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c523.c linux-libre-2.6.33-gnu1/drivers/net/3c523.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c523.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c523.c	2010-02-24 13:52:17.000000000 -0500
@@ -288,7 +288,7 @@ static int elmc_open(struct net_device *
 
 	elmc_id_attn586();	/* disable interrupts */
 
-	ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+	ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
 			  dev->name, dev);
 	if (ret) {
 		pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c527.c linux-libre-2.6.33-gnu1/drivers/net/3c527.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c527.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c527.c	2010-02-24 13:52:17.000000000 -0500
@@ -443,7 +443,7 @@ static int __init mc32_probe1(struct net
 	 *	Grab the IRQ
 	 */
 
-	err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
+	err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
 	if (err) {
 		release_region(dev->base_addr, MC32_IO_EXTENT);
 		pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
@@ -1168,8 +1168,8 @@ static void mc32_rx_ring(struct net_devi
 
 			/* Try to save time by avoiding a copy on big frames */
 
-			if ((length > RX_COPYBREAK)
-			    && ((newskb=dev_alloc_skb(1532)) != NULL))
+			if ((length > RX_COPYBREAK) &&
+			    ((newskb=dev_alloc_skb(1532)) != NULL))
 			{
 				skb=lp->rx_ring[rx_ring_tail].skb;
 				skb_put(skb, length);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/3c59x.c linux-libre-2.6.33-gnu1/drivers/net/3c59x.c
--- linux-libre-2.6.32-gnu1/drivers/net/3c59x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/3c59x.c	2010-02-24 13:52:17.000000000 -0500
@@ -837,7 +837,7 @@ static int vortex_resume(struct device *
 	return 0;
 }
 
-static struct dev_pm_ops vortex_pm_ops = {
+static const struct dev_pm_ops vortex_pm_ops = {
 	.suspend = vortex_suspend,
 	.resume = vortex_resume,
 	.freeze = vortex_suspend,
@@ -1942,8 +1942,8 @@ vortex_error(struct net_device *dev, int
 	if (status & TxComplete) {			/* Really "TxError" for us. */
 		tx_status = ioread8(ioaddr + TxStatus);
 		/* Presumably a tx-timeout. We must merely re-enable. */
-		if (vortex_debug > 2
-			|| (tx_status != 0x88 && vortex_debug > 0)) {
+		if (vortex_debug > 2 ||
+		    (tx_status != 0x88 && vortex_debug > 0)) {
 			pr_err("%s: Transmit error, Tx status register %2.2x.\n",
 				   dev->name, tx_status);
 			if (tx_status == 0x82) {
@@ -2560,7 +2560,7 @@ boomerang_rx(struct net_device *dev)
 		struct sk_buff *skb;
 		entry = vp->dirty_rx % RX_RING_SIZE;
 		if (vp->rx_skbuff[entry] == NULL) {
-			skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
+			skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ);
 			if (skb == NULL) {
 				static unsigned long last_jif;
 				if (time_after(jiffies, last_jif + 10 * HZ)) {
@@ -2572,7 +2572,6 @@ boomerang_rx(struct net_device *dev)
 				break;			/* Bad news!  */
 			}
 
-			skb_reserve(skb, NET_IP_ALIGN);
 			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/8139cp.c linux-libre-2.6.33-gnu1/drivers/net/8139cp.c
--- linux-libre-2.6.32-gnu1/drivers/net/8139cp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/8139cp.c	2010-02-24 13:52:17.000000000 -0500
@@ -549,14 +549,12 @@ rx_status_loop:
 			pr_debug("%s: rx slot %d status 0x%x len %d\n",
 			       dev->name, rx_tail, status, len);
 
-		new_skb = netdev_alloc_skb(dev, buflen + NET_IP_ALIGN);
+		new_skb = netdev_alloc_skb_ip_align(dev, buflen);
 		if (!new_skb) {
 			dev->stats.rx_dropped++;
 			goto rx_next;
 		}
 
-		skb_reserve(new_skb, NET_IP_ALIGN);
-
 		dma_unmap_single(&cp->pdev->dev, mapping,
 				 buflen, PCI_DMA_FROMDEVICE);
 
@@ -911,8 +909,8 @@ static void __cp_set_rx_mode (struct net
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
@@ -1057,12 +1055,10 @@ static int cp_refill_rx(struct cp_privat
 		struct sk_buff *skb;
 		dma_addr_t mapping;
 
-		skb = netdev_alloc_skb(dev, cp->rx_buf_sz + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(dev, cp->rx_buf_sz);
 		if (!skb)
 			goto err_out;
 
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		mapping = dma_map_single(&cp->pdev->dev, skb->data,
 					 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[i] = skb;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/8139too.c linux-libre-2.6.33-gnu1/drivers/net/8139too.c
--- linux-libre-2.6.32-gnu1/drivers/net/8139too.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/8139too.c	2010-02-24 13:52:17.000000000 -0500
@@ -1549,8 +1549,8 @@ static inline void rtl8139_thread_iter (
 	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
 
 	if (!tp->mii.force_media && mii_lpa != 0xffff) {
-		int duplex = (mii_lpa & LPA_100FULL)
-		    || (mii_lpa & 0x01C0) == 0x0040;
+		int duplex = ((mii_lpa & LPA_100FULL) ||
+			      (mii_lpa & 0x01C0) == 0x0040);
 		if (tp->mii.full_duplex != duplex) {
 			tp->mii.full_duplex = duplex;
 
@@ -1936,8 +1936,8 @@ static int rtl8139_rx(struct net_device
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-	while (netif_running(dev) && received < budget
-	       && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
+	while (netif_running(dev) && received < budget &&
+	       (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
 		u32 ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int pkt_size;
@@ -2004,9 +2004,8 @@ no_early_rx:
 		/* Malloc up new buffer, compatible with net-2e. */
 		/* Omit the four octet CRC from the length. */
 
-		skb = netdev_alloc_skb(dev, pkt_size + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(dev, pkt_size);
 		if (likely(skb)) {
-			skb_reserve (skb, NET_IP_ALIGN);	/* 16 byte align the IP fields. */
 #if RX_BUF_IDX == 3
 			wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
 #else
@@ -2522,8 +2521,8 @@ static void __set_rx_mode (struct net_de
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/82596.c linux-libre-2.6.33-gnu1/drivers/net/82596.c
--- linux-libre-2.6.32-gnu1/drivers/net/82596.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/82596.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/amd8111e.c linux-libre-2.6.33-gnu1/drivers/net/amd8111e.c
--- linux-libre-2.6.32-gnu1/drivers/net/amd8111e.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/amd8111e.c	2010-02-24 13:52:17.000000000 -0500
@@ -1633,8 +1633,13 @@ static int amd8111e_enable_link_change(s
 	readl(lp->mmio + CMD7);
 	return 0;
 }
-/* This function is called when a packet transmission fails to complete within a  resonable period, on the assumption that an interrupts have been failed or the  interface is locked up. This function will reinitialize the hardware */
 
+/*
+ * This function is called when a packet transmission fails to complete
+ * within a reasonable period, on the assumption that an interrupt have
+ * failed or the interface is locked up. This function will reinitialize
+ * the hardware.
+ */
 static void amd8111e_tx_timeout(struct net_device *dev)
 {
 	struct amd8111e_priv* lp = netdev_priv(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/appletalk/cops.c linux-libre-2.6.33-gnu1/drivers/net/appletalk/cops.c
--- linux-libre-2.6.32-gnu1/drivers/net/appletalk/cops.c	2013-05-03 14:01:26.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/appletalk/cops.c	2013-05-03 12:08:47.000000000 -0400
@@ -119,7 +119,7 @@ static int irq = 5;		/* Default IRQ */
  *      DAYNA driver mode:
  *              Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, 
  *		Farallon PhoneNET PC III, Farallon PhoneNET PC II
- *	Other cards possibly supported mode unkown though:
+ *	Other cards possibly supported mode unknown though:
  *		Dayna DL2000 (Full length), COPS LT/M (Micro-Channel)
  *
  *	Cards NOT supported by this driver but supported by the ltpc.c
@@ -327,7 +327,7 @@ static int __init cops_probe1(struct net
 
 	/* Reserve any actual interrupt. */
 	if (dev->irq) {
-		retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
+		retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev);
 		if (retval)
 			goto err_out;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/appletalk/ipddp.c linux-libre-2.6.33-gnu1/drivers/net/appletalk/ipddp.c
--- linux-libre-2.6.32-gnu1/drivers/net/appletalk/ipddp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/appletalk/ipddp.c	2010-02-24 13:52:17.000000000 -0500
@@ -230,9 +230,9 @@ static int ipddp_delete(struct ipddp_rou
 	spin_lock_bh(&ipddp_route_lock);
         while((tmp = *r) != NULL)
         {
-                if(tmp->ip == rt->ip
-                        && tmp->at.s_net == rt->at.s_net
-                        && tmp->at.s_node == rt->at.s_node)
+                if(tmp->ip == rt->ip &&
+		   tmp->at.s_net == rt->at.s_net &&
+		   tmp->at.s_node == rt->at.s_node)
                 {
                         *r = tmp->next;
 			spin_unlock_bh(&ipddp_route_lock);
@@ -255,9 +255,9 @@ static struct ipddp_route* __ipddp_find_
 
         for(f = ipddp_route_list; f != NULL; f = f->next)
         {
-                if(f->ip == rt->ip
-                        && f->at.s_net == rt->at.s_net
-                        && f->at.s_node == rt->at.s_node)
+                if(f->ip == rt->ip &&
+		   f->at.s_net == rt->at.s_net &&
+		   f->at.s_node == rt->at.s_node)
                         return (f);
         }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/appletalk/ltpc.c linux-libre-2.6.33-gnu1/drivers/net/appletalk/ltpc.c
--- linux-libre-2.6.32-gnu1/drivers/net/appletalk/ltpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/appletalk/ltpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -1158,7 +1158,7 @@ struct net_device * __init ltpc_probe(vo
 	}
 
 	/* grab it and don't let go :-) */
-	if (irq && request_irq( irq, &ltpc_interrupt, 0, "ltpc", dev) >= 0)
+	if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0)
 	{
 		(void) inb_p(io+7);  /* enable interrupts from board */
 		(void) inb_p(io+7);  /* and reset irq line */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arcnet/arcnet.c linux-libre-2.6.33-gnu1/drivers/net/arcnet/arcnet.c
--- linux-libre-2.6.32-gnu1/drivers/net/arcnet/arcnet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arcnet/arcnet.c	2010-02-24 13:52:17.000000000 -0500
@@ -301,8 +301,8 @@ static int choose_mtu(void)
 
 	/* choose the smallest MTU of all available encaps */
 	for (count = 0; count < 256; count++) {
-		if (arc_proto_map[count] != &arc_proto_null
-		    && arc_proto_map[count]->mtu < mtu) {
+		if (arc_proto_map[count] != &arc_proto_null &&
+		    arc_proto_map[count]->mtu < mtu) {
 			mtu = arc_proto_map[count]->mtu;
 		}
 	}
@@ -953,13 +953,13 @@ irqreturn_t arcnet_interrupt(int irq, vo
 				 *    > RECON_THRESHOLD/min;
 				 * then print a warning message.
 				 */
-				if (!lp->network_down
-				    && (lp->last_recon - lp->first_recon) <= HZ * 60
-				  && lp->num_recons >= RECON_THRESHOLD) {
+				if (!lp->network_down &&
+				    (lp->last_recon - lp->first_recon) <= HZ * 60 &&
+				    lp->num_recons >= RECON_THRESHOLD) {
 					lp->network_down = 1;
 					BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
-				} else if (!lp->network_down
-					   && lp->last_recon - lp->first_recon > HZ * 60) {
+				} else if (!lp->network_down &&
+					   lp->last_recon - lp->first_recon > HZ * 60) {
 					/* reset counters if we've gone for over a minute. */
 					lp->first_recon = lp->last_recon;
 					lp->num_recons = 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arcnet/arc-rimi.c linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rimi.c
--- linux-libre-2.6.32-gnu1/drivers/net/arcnet/arc-rimi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arcnet/arc-rimi.c	2010-02-24 13:52:17.000000000 -0500
@@ -156,7 +156,7 @@ static int __init arcrimi_found(struct n
 	}
 
 	/* reserve the irq */
-	if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
+	if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
 		iounmap(p);
 		release_mem_region(dev->mem_start, MIRROR_SIZE);
 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
@@ -174,9 +174,9 @@ static int __init arcrimi_found(struct n
 	 * 2k (or there are no mirrors at all) but on some, it's 4k.
 	 */
 	mirror_size = MIRROR_SIZE;
-	if (readb(p) == TESTvalue
-	    && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0
-	    && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
+	if (readb(p) == TESTvalue &&
+	    check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
+	    check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
 		mirror_size = 2 * MIRROR_SIZE;
 
 	first_mirror = shmem - mirror_size;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arcnet/com20020.c linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020.c
--- linux-libre-2.6.32-gnu1/drivers/net/arcnet/com20020.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arcnet/com20020.c	2010-02-24 13:52:17.000000000 -0500
@@ -200,7 +200,7 @@ int com20020_found(struct net_device *de
 	outb(dev->dev_addr[0], _XREG);
 
 	/* reserve the irq */
-	if (request_irq(dev->irq, &arcnet_interrupt, shared,
+	if (request_irq(dev->irq, arcnet_interrupt, shared,
 			"arcnet (COM20020)", dev)) {
 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
 		return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arcnet/com90io.c linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90io.c
--- linux-libre-2.6.32-gnu1/drivers/net/arcnet/com90io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90io.c	2010-02-24 13:52:17.000000000 -0500
@@ -238,7 +238,7 @@ static int __init com90io_found(struct n
 	int err;
 
 	/* Reserve the irq */
-	if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
+	if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
 		return -ENODEV;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arcnet/com90xx.c linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90xx.c
--- linux-libre-2.6.32-gnu1/drivers/net/arcnet/com90xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arcnet/com90xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -501,7 +501,7 @@ static int __init com90xx_found(int ioad
 		goto err_free_dev;
 
 	/* reserve the irq */
-	if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+	if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
 		goto err_release_mem;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ariadne.h linux-libre-2.6.33-gnu1/drivers/net/ariadne.h
--- linux-libre-2.6.32-gnu1/drivers/net/ariadne.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ariadne.h	2010-02-24 13:52:17.000000000 -0500
@@ -244,7 +244,7 @@ struct Am79C960 {
 #define DLNKTST		0x0010	/* Disable Link Status */
 #define DAPC		0x0008	/* Disable Automatic Polarity Correction */
 #define MENDECL		0x0004	/* MENDEC Loopback Mode */
-#define LRTTSEL		0x0002	/* Low Receive Treshold/Transmit Mode Select */
+#define LRTTSEL		0x0002	/* Low Receive Threshold/Transmit Mode Select */
 #define PORTSEL1	0x0001	/* Port Select Bits */
 #define PORTSEL2	0x8000	/* Port Select Bits */
 #define INTL		0x4000	/* Internal Loopback */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arm/ixp4xx_eth.c linux-libre-2.6.33-gnu1/drivers/net/arm/ixp4xx_eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/arm/ixp4xx_eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arm/ixp4xx_eth.c	2010-02-24 13:52:17.000000000 -0500
@@ -322,7 +322,7 @@ static int ixp4xx_mdio_write(struct mii_
 	ret = ixp4xx_mdio_cmd(bus, phy_id, location, 1, val);
 	spin_unlock_irqrestore(&mdio_lock, flags);
 #if DEBUG_MDIO
-	printk(KERN_DEBUG "%s #%i: MII read [%i] <- 0x%X, err = %i\n",
+	printk(KERN_DEBUG "%s #%i: MII write [%i] <- 0x%X, err = %i\n",
 	       bus->name, phy_id, location, val, ret);
 #endif
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arm/Kconfig linux-libre-2.6.33-gnu1/drivers/net/arm/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/arm/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arm/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -68,6 +68,7 @@ config W90P910_ETH
 	tristate "Nuvoton w90p910 Ethernet support"
 	depends on ARM && ARCH_W90X900
 	select PHYLIB
+	select MII
 	help
 	  Say Y here if you want to use built-in Ethernet ports
 	  on w90p910 processor.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arm/ks8695net.c linux-libre-2.6.33-gnu1/drivers/net/arm/ks8695net.c
--- linux-libre-2.6.32-gnu1/drivers/net/arm/ks8695net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arm/ks8695net.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,11 +35,13 @@
 
 #include <mach/regs-switch.h>
 #include <mach/regs-misc.h>
+#include <asm/mach/irq.h>
+#include <mach/regs-irq.h>
 
 #include "ks8695net.h"
 
 #define MODULENAME	"ks8695_ether"
-#define MODULEVERSION	"1.01"
+#define MODULEVERSION	"1.02"
 
 /*
  * Transmit and device reset timeout, default 5 seconds.
@@ -95,6 +97,9 @@ struct ks8695_skbuff {
 #define MAX_RX_DESC 16
 #define MAX_RX_DESC_MASK 0xf
 
+/*napi_weight have better more than rx DMA buffers*/
+#define NAPI_WEIGHT   64
+
 #define MAX_RXBUF_SIZE 0x700
 
 #define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC)
@@ -120,6 +125,7 @@ enum ks8695_dtype {
  *	@dev: The platform device object for this interface
  *	@dtype: The type of this device
  *	@io_regs: The ioremapped registers for this interface
+ *      @napi : Add support NAPI for Rx
  *	@rx_irq_name: The textual name of the RX IRQ from the platform data
  *	@tx_irq_name: The textual name of the TX IRQ from the platform data
  *	@link_irq_name: The textual name of the link IRQ from the
@@ -143,6 +149,7 @@ enum ks8695_dtype {
  *	@rx_ring_dma: The DMA mapped equivalent of rx_ring
  *	@rx_buffers: The sk_buff mappings for the RX ring
  *	@next_rx_desc_read: The next RX descriptor to read from on IRQ
+ *      @rx_lock: A lock to protect Rx irq function
  *	@msg_enable: The flags for which messages to emit
  */
 struct ks8695_priv {
@@ -152,6 +159,8 @@ struct ks8695_priv {
 	enum ks8695_dtype dtype;
 	void __iomem *io_regs;
 
+	struct napi_struct	napi;
+
 	const char *rx_irq_name, *tx_irq_name, *link_irq_name;
 	int rx_irq, tx_irq, link_irq;
 
@@ -172,6 +181,7 @@ struct ks8695_priv {
 	dma_addr_t rx_ring_dma;
 	struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
 	int next_rx_desc_read;
+	spinlock_t rx_lock;
 
 	int msg_enable;
 };
@@ -392,29 +402,74 @@ ks8695_tx_irq(int irq, void *dev_id)
 }
 
 /**
+ *	ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit
+ *	@ksp: Private data for the KS8695 Ethernet
+ *
+ *    For KS8695 document:
+ *    Interrupt Enable Register (offset 0xE204)
+ *        Bit29 : WAN MAC Receive Interrupt Enable
+ *        Bit16 : LAN MAC Receive Interrupt Enable
+ *    Interrupt Status Register (Offset 0xF208)
+ *        Bit29: WAN MAC Receive Status
+ *        Bit16: LAN MAC Receive Status
+ *    So, this Rx interrrupt enable/status bit number is equal
+ *    as Rx IRQ number.
+ */
+static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp)
+{
+	return ksp->rx_irq;
+}
+
+/**
  *	ks8695_rx_irq - Receive IRQ handler
  *	@irq: The IRQ which went off (ignored)
  *	@dev_id: The net_device for the interrupt
  *
- *	Process the RX ring, passing any received packets up to the
- *	host.  If we received anything other than errors, we then
- *	refill the ring.
+ *	Inform NAPI that packet reception needs to be scheduled
  */
+
 static irqreturn_t
 ks8695_rx_irq(int irq, void *dev_id)
 {
 	struct net_device *ndev = (struct net_device *)dev_id;
 	struct ks8695_priv *ksp = netdev_priv(ndev);
+
+	spin_lock(&ksp->rx_lock);
+
+	if (napi_schedule_prep(&ksp->napi)) {
+		unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN);
+		unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
+		/*disable rx interrupt*/
+		status &= ~mask_bit;
+		writel(status , KS8695_IRQ_VA + KS8695_INTEN);
+		__napi_schedule(&ksp->napi);
+	}
+
+	spin_unlock(&ksp->rx_lock);
+	return IRQ_HANDLED;
+}
+
+/**
+ *	ks8695_rx - Receive packets  called by NAPI poll method
+ *	@ksp: Private data for the KS8695 Ethernet
+ *	@budget: The max packets would be receive
+ */
+
+static int ks8695_rx(struct ks8695_priv *ksp, int budget)
+{
+	struct net_device *ndev = ksp->ndev;
 	struct sk_buff *skb;
 	int buff_n;
 	u32 flags;
 	int pktlen;
 	int last_rx_processed = -1;
+	int received = 0;
 
 	buff_n = ksp->next_rx_desc_read;
-	do {
-		if (ksp->rx_buffers[buff_n].skb &&
-		    !(ksp->rx_ring[buff_n].status & cpu_to_le32(RDES_OWN))) {
+	while (received < budget
+			&& ksp->rx_buffers[buff_n].skb
+			&& (!(ksp->rx_ring[buff_n].status &
+					cpu_to_le32(RDES_OWN)))) {
 			rmb();
 			flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
 			/* Found an SKB which we own, this means we
@@ -464,7 +519,7 @@ ks8695_rx_irq(int irq, void *dev_id)
 			/* Relinquish the SKB to the network layer */
 			skb_put(skb, pktlen);
 			skb->protocol = eth_type_trans(skb, ndev);
-			netif_rx(skb);
+			netif_receive_skb(skb);
 
 			/* Record stats */
 			ndev->stats.rx_packets++;
@@ -478,29 +533,55 @@ rx_failure:
 			/* Give the ring entry back to the hardware */
 			ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
 rx_finished:
+			received++;
 			/* And note this as processed so we can start
 			 * from here next time
 			 */
 			last_rx_processed = buff_n;
-		} else {
-			/* Ran out of things to process, stop now */
-			break;
-		}
-		buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
-	} while (buff_n != ksp->next_rx_desc_read);
-
-	/* And note which RX descriptor we last did anything with */
-	if (likely(last_rx_processed != -1))
-		ksp->next_rx_desc_read =
-			(last_rx_processed + 1) & MAX_RX_DESC_MASK;
-
+			buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
+			/*And note which RX descriptor we last did */
+			if (likely(last_rx_processed != -1))
+				ksp->next_rx_desc_read =
+					(last_rx_processed + 1) &
+					MAX_RX_DESC_MASK;
+	}
 	/* And refill the buffers */
 	ks8695_refill_rxbuffers(ksp);
 
-	/* Kick the RX DMA engine, in case it became suspended */
+	/* Kick the RX DMA engine, in case it became
+	 *  suspended */
 	ks8695_writereg(ksp, KS8695_DRSC, 0);
+	return received;
+}
 
-	return IRQ_HANDLED;
+
+/**
+ *	ks8695_poll - Receive packet by NAPI poll method
+ *	@ksp: Private data for the KS8695 Ethernet
+ *	@budget: The remaining number packets for network subsystem
+ *
+ *     Invoked by the network core when it requests for new
+ *     packets from the driver
+ */
+static int ks8695_poll(struct napi_struct *napi, int budget)
+{
+	struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
+	unsigned long  work_done;
+
+	unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN);
+	unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
+
+	work_done = ks8695_rx(ksp, budget);
+
+	if (work_done < budget) {
+		unsigned long flags;
+		spin_lock_irqsave(&ksp->rx_lock, flags);
+		/*enable rx interrupt*/
+		writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
+		__napi_complete(napi);
+		spin_unlock_irqrestore(&ksp->rx_lock, flags);
+	}
+	return work_done;
 }
 
 /**
@@ -1253,6 +1334,7 @@ ks8695_stop(struct net_device *ndev)
 	struct ks8695_priv *ksp = netdev_priv(ndev);
 
 	netif_stop_queue(ndev);
+	napi_disable(&ksp->napi);
 	netif_carrier_off(ndev);
 
 	ks8695_shutdown(ksp);
@@ -1287,6 +1369,7 @@ ks8695_open(struct net_device *ndev)
 		return ret;
 	}
 
+	napi_enable(&ksp->napi);
 	netif_start_queue(ndev);
 
 	return 0;
@@ -1472,6 +1555,8 @@ ks8695_probe(struct platform_device *pde
 	SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
 	ndev->watchdog_timeo	 = msecs_to_jiffies(watchdog);
 
+	netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
+
 	/* Retrieve the default MAC addr from the chip. */
 	/* The bootloader should have left it in there for us. */
 
@@ -1505,6 +1590,7 @@ ks8695_probe(struct platform_device *pde
 
 	/* And initialise the queue's lock */
 	spin_lock_init(&ksp->txq_lock);
+	spin_lock_init(&ksp->rx_lock);
 
 	/* Specify the RX DMA ring buffer */
 	ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
@@ -1626,6 +1712,7 @@ ks8695_drv_remove(struct platform_device
 	struct ks8695_priv *ksp = netdev_priv(ndev);
 
 	platform_set_drvdata(pdev, NULL);
+	netif_napi_del(&ksp->napi);
 
 	unregister_netdev(ndev);
 	ks8695_release_device(ksp);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/arm/w90p910_ether.c linux-libre-2.6.33-gnu1/drivers/net/arm/w90p910_ether.c
--- linux-libre-2.6.32-gnu1/drivers/net/arm/w90p910_ether.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/arm/w90p910_ether.c	2010-02-24 13:52:17.000000000 -0500
@@ -160,8 +160,8 @@ struct  w90p910_ether {
 	struct mii_if_info mii;
 	struct timer_list check_timer;
 	void __iomem *reg;
-	unsigned int rxirq;
-	unsigned int txirq;
+	int rxirq;
+	int txirq;
 	unsigned int cur_tx;
 	unsigned int cur_rx;
 	unsigned int finish_tx;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/at1700.c linux-libre-2.6.33-gnu1/drivers/net/at1700.c
--- linux-libre-2.6.32-gnu1/drivers/net/at1700.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/at1700.c	2010-02-24 13:52:17.000000000 -0500
@@ -350,13 +350,13 @@ static int __init at1700_probe1(struct n
 	slot = -1;
 	/* We must check for the EEPROM-config boards first, else accessing
 	   IOCONFIG0 will move the board! */
-	if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
-		&& read_eeprom(ioaddr, 4) == 0x0000
-		&& (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
+	if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr &&
+	    read_eeprom(ioaddr, 4) == 0x0000 &&
+	    (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
 		is_at1700 = 1;
-	else if (inb(ioaddr   + SAPROM    ) == 0x00
-		&& inb(ioaddr + SAPROM + 1) == 0x00
-		&& inb(ioaddr + SAPROM + 2) == 0x0e)
+	else if (inb(ioaddr + SAPROM    ) == 0x00 &&
+		 inb(ioaddr + SAPROM + 1) == 0x00 &&
+		 inb(ioaddr + SAPROM + 2) == 0x0e)
 		is_fmv18x = 1;
 	else {
 		goto err_out;
@@ -468,7 +468,7 @@ found:
 	lp->jumpered = is_fmv18x;
 	lp->mca_slot = slot;
 	/* Snarf the interrupt vector now. */
-	ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
+	ret = request_irq(irq, net_interrupt, 0, DRV_NAME, dev);
 	if (ret) {
 		printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
 		       "conflict on IRQ %d.\n",
@@ -839,8 +839,8 @@ set_rx_mode(struct net_device *dev)
 	if (dev->flags & IFF_PROMISC) {
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-	} else if (dev->mc_count > MC_FILTERBREAK
-			   ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if (dev->mc_count > MC_FILTERBREAK ||
+			   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atarilance.c linux-libre-2.6.33-gnu1/drivers/net/atarilance.c
--- linux-libre-2.6.32-gnu1/drivers/net/atarilance.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atarilance.c	2010-02-24 13:52:17.000000000 -0500
@@ -663,7 +663,7 @@ static int lance_open( struct net_device
 	while (--i > 0)
 		if (DREG & CSR0_IDON)
 			break;
-	if (i < 0 || (DREG & CSR0_ERR)) {
+	if (i <= 0 || (DREG & CSR0_ERR)) {
 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
 					  dev->name, i, DREG ));
 		DREG = CSR0_STOP;
@@ -930,8 +930,8 @@ static irqreturn_t lance_interrupt( int
 			}
 #endif
 
-			if (lp->tx_full && (netif_queue_stopped(dev))
-				&& dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
+			if (lp->tx_full && (netif_queue_stopped(dev)) &&
+				dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
 				/* The ring is no longer full, clear tbusy. */
 				lp->tx_full = 0;
 				netif_wake_queue (dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atl1c/atl1c.h linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c.h
--- linux-libre-2.6.32-gnu1/drivers/net/atl1c/atl1c.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c.h	2010-02-24 13:52:17.000000000 -0500
@@ -470,12 +470,33 @@ struct atl1c_ring_header {
 struct atl1c_buffer {
 	struct sk_buff *skb;	/* socket buffer */
 	u16 length;		/* rx buffer length */
-	u16 state;		/* state of buffer */
-#define ATL1_BUFFER_FREE	0
-#define ATL1_BUFFER_BUSY	1
+	u16 flags;		/* information of buffer */
+#define ATL1C_BUFFER_FREE		0x0001
+#define ATL1C_BUFFER_BUSY		0x0002
+#define ATL1C_BUFFER_STATE_MASK		0x0003
+
+#define ATL1C_PCIMAP_SINGLE		0x0004
+#define ATL1C_PCIMAP_PAGE		0x0008
+#define ATL1C_PCIMAP_TYPE_MASK		0x000C
+
+#define ATL1C_PCIMAP_TODEVICE		0x0010
+#define ATL1C_PCIMAP_FROMDEVICE		0x0020
+#define ATL1C_PCIMAP_DIRECTION_MASK	0x0030
 	dma_addr_t dma;
 };
 
+#define ATL1C_SET_BUFFER_STATE(buff, state) do {	\
+	((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK;	\
+	((buff)->flags) |= (state);			\
+	} while (0)
+
+#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do {	\
+	((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK;		\
+	((buff)->flags) |= (type);				\
+	((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK;	\
+	((buff)->flags) |= (direction);				\
+	} while (0)
+
 /* transimit packet descriptor (tpd) ring */
 struct atl1c_tpd_ring {
 	void *desc;		/* descriptor ring virtual address */
@@ -534,6 +555,9 @@ struct atl1c_adapter {
 #define __AT_TESTING        0x0001
 #define __AT_RESETTING      0x0002
 #define __AT_DOWN           0x0003
+	u8 work_event;
+#define ATL1C_WORK_EVENT_RESET 		0x01
+#define ATL1C_WORK_EVENT_LINK_CHANGE	0x02
 	u32 msg_enable;
 
 	bool have_msi;
@@ -545,8 +569,7 @@ struct atl1c_adapter {
 	spinlock_t tx_lock;
 	atomic_t irq_sem;
 
-	struct work_struct reset_task;
-	struct work_struct link_chg_task;
+	struct work_struct common_task;
 	struct timer_list watchdog_timer;
 	struct timer_list phy_config_timer;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atl1c/atl1c_main.c linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/atl1c/atl1c_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atl1c/atl1c_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -198,27 +198,12 @@ static void atl1c_phy_config(unsigned lo
 
 void atl1c_reinit_locked(struct atl1c_adapter *adapter)
 {
-
 	WARN_ON(in_interrupt());
 	atl1c_down(adapter);
 	atl1c_up(adapter);
 	clear_bit(__AT_RESETTING, &adapter->flags);
 }
 
-static void atl1c_reset_task(struct work_struct *work)
-{
-	struct atl1c_adapter *adapter;
-	struct net_device *netdev;
-
-	adapter = container_of(work, struct atl1c_adapter, reset_task);
-	netdev = adapter->netdev;
-
-	netif_device_detach(netdev);
-	atl1c_down(adapter);
-	atl1c_up(adapter);
-	netif_device_attach(netdev);
-}
-
 static void atl1c_check_link_status(struct atl1c_adapter *adapter)
 {
 	struct atl1c_hw *hw = &adapter->hw;
@@ -275,18 +260,6 @@ static void atl1c_check_link_status(stru
 	}
 }
 
-/*
- * atl1c_link_chg_task - deal with link change event Out of interrupt context
- * @netdev: network interface device structure
- */
-static void atl1c_link_chg_task(struct work_struct *work)
-{
-	struct atl1c_adapter *adapter;
-
-	adapter = container_of(work, struct atl1c_adapter, link_chg_task);
-	atl1c_check_link_status(adapter);
-}
-
 static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
@@ -311,20 +284,40 @@ static void atl1c_link_chg_event(struct
 			adapter->link_speed = SPEED_0;
 		}
 	}
-	schedule_work(&adapter->link_chg_task);
+
+	adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE;
+	schedule_work(&adapter->common_task);
 }
 
-static void atl1c_del_timer(struct atl1c_adapter *adapter)
+static void atl1c_common_task(struct work_struct *work)
 {
-	del_timer_sync(&adapter->phy_config_timer);
+	struct atl1c_adapter *adapter;
+	struct net_device *netdev;
+
+	adapter = container_of(work, struct atl1c_adapter, common_task);
+	netdev = adapter->netdev;
+
+	if (adapter->work_event & ATL1C_WORK_EVENT_RESET) {
+		netif_device_detach(netdev);
+		atl1c_down(adapter);
+		atl1c_up(adapter);
+		netif_device_attach(netdev);
+		return;
+	}
+
+	if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE)
+		atl1c_check_link_status(adapter);
+
+	return;
 }
 
-static void atl1c_cancel_work(struct atl1c_adapter *adapter)
+
+static void atl1c_del_timer(struct atl1c_adapter *adapter)
 {
-	cancel_work_sync(&adapter->reset_task);
-	cancel_work_sync(&adapter->link_chg_task);
+	del_timer_sync(&adapter->phy_config_timer);
 }
 
+
 /*
  * atl1c_tx_timeout - Respond to a Tx Hang
  * @netdev: network interface device structure
@@ -334,7 +327,8 @@ static void atl1c_tx_timeout(struct net_
 	struct atl1c_adapter *adapter = netdev_priv(netdev);
 
 	/* Do the reset outside of interrupt context */
-	schedule_work(&adapter->reset_task);
+	adapter->work_event |= ATL1C_WORK_EVENT_RESET;
+	schedule_work(&adapter->common_task);
 }
 
 /*
@@ -710,6 +704,35 @@ static int __devinit atl1c_sw_init(struc
 	return 0;
 }
 
+static inline void atl1c_clean_buffer(struct pci_dev *pdev,
+				struct atl1c_buffer *buffer_info, int in_irq)
+{
+	u16 pci_driection;
+	if (buffer_info->flags & ATL1C_BUFFER_FREE)
+		return;
+	if (buffer_info->dma) {
+		if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE)
+			pci_driection = PCI_DMA_FROMDEVICE;
+		else
+			pci_driection = PCI_DMA_TODEVICE;
+
+		if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
+			pci_unmap_single(pdev, buffer_info->dma,
+					buffer_info->length, pci_driection);
+		else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
+			pci_unmap_page(pdev, buffer_info->dma,
+					buffer_info->length, pci_driection);
+	}
+	if (buffer_info->skb) {
+		if (in_irq)
+			dev_kfree_skb_irq(buffer_info->skb);
+		else
+			dev_kfree_skb(buffer_info->skb);
+	}
+	buffer_info->dma = 0;
+	buffer_info->skb = NULL;
+	ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+}
 /*
  * atl1c_clean_tx_ring - Free Tx-skb
  * @adapter: board private structure
@@ -725,22 +748,12 @@ static void atl1c_clean_tx_ring(struct a
 	ring_count = tpd_ring->count;
 	for (index = 0; index < ring_count; index++) {
 		buffer_info = &tpd_ring->buffer_info[index];
-		if (buffer_info->state == ATL1_BUFFER_FREE)
-			continue;
-		if (buffer_info->dma)
-			pci_unmap_single(pdev, buffer_info->dma,
-					buffer_info->length,
-					PCI_DMA_TODEVICE);
-		if (buffer_info->skb)
-			dev_kfree_skb(buffer_info->skb);
-		buffer_info->dma = 0;
-		buffer_info->skb = NULL;
-		buffer_info->state = ATL1_BUFFER_FREE;
+		atl1c_clean_buffer(pdev, buffer_info, 0);
 	}
 
 	/* Zero out Tx-buffers */
 	memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
-				ring_count);
+		ring_count);
 	atomic_set(&tpd_ring->next_to_clean, 0);
 	tpd_ring->next_to_use = 0;
 }
@@ -760,16 +773,7 @@ static void atl1c_clean_rx_ring(struct a
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		for (j = 0; j < rfd_ring[i].count; j++) {
 			buffer_info = &rfd_ring[i].buffer_info[j];
-			if (buffer_info->state == ATL1_BUFFER_FREE)
-				continue;
-			if (buffer_info->dma)
-				pci_unmap_single(pdev, buffer_info->dma,
-						buffer_info->length,
-						PCI_DMA_FROMDEVICE);
-			if (buffer_info->skb)
-				dev_kfree_skb(buffer_info->skb);
-			buffer_info->state = ATL1_BUFFER_FREE;
-			buffer_info->skb = NULL;
+			atl1c_clean_buffer(pdev, buffer_info, 0);
 		}
 		/* zero out the descriptor ring */
 		memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
@@ -796,7 +800,8 @@ static void atl1c_init_ring_ptrs(struct
 		atomic_set(&tpd_ring[i].next_to_clean, 0);
 		buffer_info = tpd_ring[i].buffer_info;
 		for (j = 0; j < tpd_ring->count; j++)
-			buffer_info[i].state = ATL1_BUFFER_FREE;
+			ATL1C_SET_BUFFER_STATE(&buffer_info[i],
+					ATL1C_BUFFER_FREE);
 	}
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		rfd_ring[i].next_to_use = 0;
@@ -805,7 +810,7 @@ static void atl1c_init_ring_ptrs(struct
 		rrd_ring[i].next_to_clean = 0;
 		for (j = 0; j < rfd_ring[i].count; j++) {
 			buffer_info = &rfd_ring[i].buffer_info[j];
-			buffer_info->state = ATL1_BUFFER_FREE;
+			ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
 		}
 	}
 }
@@ -1447,6 +1452,7 @@ static bool atl1c_clean_tx_irq(struct at
 	struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
 				&adapter->tpd_ring[type];
 	struct atl1c_buffer *buffer_info;
+	struct pci_dev *pdev = adapter->pdev;
 	u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
 	u16 hw_next_to_clean;
 	u16 shift;
@@ -1462,16 +1468,7 @@ static bool atl1c_clean_tx_irq(struct at
 
 	while (next_to_clean != hw_next_to_clean) {
 		buffer_info = &tpd_ring->buffer_info[next_to_clean];
-		if (buffer_info->state == ATL1_BUFFER_BUSY) {
-			pci_unmap_page(adapter->pdev, buffer_info->dma,
-					buffer_info->length, PCI_DMA_TODEVICE);
-			buffer_info->dma = 0;
-			if (buffer_info->skb) {
-				dev_kfree_skb_irq(buffer_info->skb);
-				buffer_info->skb = NULL;
-			}
-			buffer_info->state = ATL1_BUFFER_FREE;
-		}
+		atl1c_clean_buffer(pdev, buffer_info, 1);
 		if (++next_to_clean == tpd_ring->count)
 			next_to_clean = 0;
 		atomic_set(&tpd_ring->next_to_clean, next_to_clean);
@@ -1536,14 +1533,15 @@ static irqreturn_t atl1c_intr(int irq, v
 			/* reset MAC */
 			hw->intr_mask &= ~ISR_ERROR;
 			AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
-			schedule_work(&adapter->reset_task);
+			adapter->work_event |= ATL1C_WORK_EVENT_RESET;
+			schedule_work(&adapter->common_task);
 			break;
 		}
 
 		if (status & ISR_OVER)
 			if (netif_msg_intr(adapter))
 				dev_warn(&pdev->dev,
-					"TX/RX over flow (status = 0x%x)\n",
+					"TX/RX overflow (status = 0x%x)\n",
 					status & ISR_OVER);
 
 		/* link event */
@@ -1587,7 +1585,7 @@ static int atl1c_alloc_rx_buffer(struct
 	buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
 	next_info = &rfd_ring->buffer_info[next_next];
 
-	while (next_info->state == ATL1_BUFFER_FREE) {
+	while (next_info->flags & ATL1C_BUFFER_FREE) {
 		rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
 
 		skb = dev_alloc_skb(adapter->rx_buffer_len);
@@ -1603,12 +1601,14 @@ static int atl1c_alloc_rx_buffer(struct
 		 * the 14 byte MAC header is removed
 		 */
 		vir_addr = skb->data;
-		buffer_info->state = ATL1_BUFFER_BUSY;
+		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 		buffer_info->dma = pci_map_single(pdev, vir_addr,
 						buffer_info->length,
 						PCI_DMA_FROMDEVICE);
+		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+			ATL1C_PCIMAP_FROMDEVICE);
 		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
 		rfd_next_to_use = next_next;
 		if (++next_next == rfd_ring->count)
@@ -1653,7 +1653,8 @@ static void atl1c_clean_rfd(struct atl1c
 			RRS_RX_RFD_INDEX_MASK;
 	for (i = 0; i < num; i++) {
 		buffer_info[rfd_index].skb = NULL;
-		buffer_info[rfd_index].state = ATL1_BUFFER_FREE;
+		ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
+					ATL1C_BUFFER_FREE);
 		if (++rfd_index == rfd_ring->count)
 			rfd_index = 0;
 	}
@@ -1967,7 +1968,9 @@ static void atl1c_tx_map(struct atl1c_ad
 		buffer_info->length = map_len;
 		buffer_info->dma = pci_map_single(adapter->pdev,
 					skb->data, hdr_len, PCI_DMA_TODEVICE);
-		buffer_info->state = ATL1_BUFFER_BUSY;
+		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+			ATL1C_PCIMAP_TODEVICE);
 		mapped_len += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
 		use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
@@ -1981,16 +1984,15 @@ static void atl1c_tx_map(struct atl1c_ad
 		else {
 			use_tpd = atl1c_get_tpd(adapter, type);
 			memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
-			use_tpd = atl1c_get_tpd(adapter, type);
-			memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
 		}
 		buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
 		buffer_info->length = buf_len - mapped_len;
 		buffer_info->dma =
 			pci_map_single(adapter->pdev, skb->data + mapped_len,
 					buffer_info->length, PCI_DMA_TODEVICE);
-		buffer_info->state = ATL1_BUFFER_BUSY;
-
+		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+			ATL1C_PCIMAP_TODEVICE);
 		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
 		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
 	}
@@ -2010,8 +2012,9 @@ static void atl1c_tx_map(struct atl1c_ad
 					frag->page_offset,
 					buffer_info->length,
 					PCI_DMA_TODEVICE);
-		buffer_info->state = ATL1_BUFFER_BUSY;
-
+		ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+		ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,
+			ATL1C_PCIMAP_TODEVICE);
 		use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
 		use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
 	}
@@ -2137,7 +2140,7 @@ static int atl1c_request_irq(struct atl1
 
 	if (!adapter->have_msi)
 		flags |= IRQF_SHARED;
-	err = request_irq(adapter->pdev->irq, &atl1c_intr, flags,
+	err = request_irq(adapter->pdev->irq, atl1c_intr, flags,
 			netdev->name, netdev);
 	if (err) {
 		if (netif_msg_ifup(adapter))
@@ -2200,8 +2203,7 @@ void atl1c_down(struct atl1c_adapter *ad
 	struct net_device *netdev = adapter->netdev;
 
 	atl1c_del_timer(adapter);
-	atl1c_cancel_work(adapter);
-
+	adapter->work_event = 0; /* clear all event */
 	/* signal that we're down so the interrupt handler does not
 	 * reschedule our watchdog timer */
 	set_bit(__AT_DOWN, &adapter->flags);
@@ -2601,8 +2603,8 @@ static int __devinit atl1c_probe(struct
 			adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
 
 	atl1c_hw_set_mac_addr(&adapter->hw);
-	INIT_WORK(&adapter->reset_task, atl1c_reset_task);
-	INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task);
+	INIT_WORK(&adapter->common_task, atl1c_common_task);
+	adapter->work_event = 0;
 	err = register_netdev(netdev);
 	if (err) {
 		dev_err(&pdev->dev, "register netdevice failed\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atl1e/atl1e_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/atl1e/atl1e_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,11 +131,6 @@ static int atl1e_set_settings(struct net
 	return 0;
 }
 
-static u32 atl1e_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
 static u32 atl1e_get_msglevel(struct net_device *netdev)
 {
 #ifdef DBG
@@ -145,10 +140,6 @@ static u32 atl1e_get_msglevel(struct net
 #endif
 }
 
-static void atl1e_set_msglevel(struct net_device *netdev, u32 data)
-{
-}
-
 static int atl1e_get_regs_len(struct net_device *netdev)
 {
 	return AT_REGS_LEN * sizeof(u32);
@@ -387,18 +378,14 @@ static const struct ethtool_ops atl1e_et
 	.get_wol                = atl1e_get_wol,
 	.set_wol                = atl1e_set_wol,
 	.get_msglevel           = atl1e_get_msglevel,
-	.set_msglevel           = atl1e_set_msglevel,
 	.nway_reset             = atl1e_nway_reset,
 	.get_link               = ethtool_op_get_link,
 	.get_eeprom_len         = atl1e_get_eeprom_len,
 	.get_eeprom             = atl1e_get_eeprom,
 	.set_eeprom             = atl1e_set_eeprom,
-	.get_tx_csum            = atl1e_get_tx_csum,
-	.get_sg                 = ethtool_op_get_sg,
+	.set_tx_csum            = ethtool_op_set_tx_hw_csum,
 	.set_sg                 = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
-	.get_tso                = ethtool_op_get_tso,
-#endif
+	.set_tso                = ethtool_op_set_tso,
 };
 
 void atl1e_set_ethtool_ops(struct net_device *netdev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atl1e/atl1e_main.c linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/atl1e/atl1e_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atl1e/atl1e_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -1433,14 +1433,12 @@ static void atl1e_clean_rx_irq(struct at
 
 			packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
 					RRS_PKT_SIZE_MASK) - 4; /* CRC */
-			skb = netdev_alloc_skb(netdev,
-					       packet_size + NET_IP_ALIGN);
+			skb = netdev_alloc_skb_ip_align(netdev, packet_size);
 			if (skb == NULL) {
 				dev_warn(&pdev->dev, "%s: Memory squeeze,"
 					"deferring packet.\n", netdev->name);
 				goto skip_pkt;
 			}
-			skb_reserve(skb, NET_IP_ALIGN);
 			skb->dev = netdev;
 			memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
 			skb_put(skb, packet_size);
@@ -1666,41 +1664,6 @@ static int atl1e_tso_csum(struct atl1e_a
 			}
 			return 0;
 		}
-
-		if (offload_type & SKB_GSO_TCPV6) {
-			real_len = (((unsigned char *)ipv6_hdr(skb) - skb->data)
-					+ ntohs(ipv6_hdr(skb)->payload_len));
-			if (real_len < skb->len)
-				pskb_trim(skb, real_len);
-
-			/* check payload == 0 byte ? */
-			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-			if (unlikely(skb->len == hdr_len)) {
-				/* only xsum need */
-				dev_warn(&pdev->dev,
-					"IPV6 tso with zero data??\n");
-				goto check_sum;
-			} else {
-				tcp_hdr(skb)->check = ~csum_ipv6_magic(
-						&ipv6_hdr(skb)->saddr,
-						&ipv6_hdr(skb)->daddr,
-						0, IPPROTO_TCP, 0);
-				tpd->word3 |= 1 << TPD_IP_VERSION_SHIFT;
-				hdr_len >>= 1;
-				tpd->word3 |= (hdr_len & TPD_V6_IPHLLO_MASK) <<
-					TPD_V6_IPHLLO_SHIFT;
-				tpd->word3 |= ((hdr_len >> 3) &
-					TPD_V6_IPHLHI_MASK) <<
-					TPD_V6_IPHLHI_SHIFT;
-				tpd->word3 |= (tcp_hdrlen(skb) >> 2 &
-					TPD_TCPHDRLEN_MASK) <<
-					TPD_TCPHDRLEN_SHIFT;
-				tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
-					TPD_MSS_MASK) << TPD_MSS_SHIFT;
-					tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
-			}
-		}
-		return 0;
 	}
 
 check_sum:
@@ -1932,7 +1895,7 @@ static int atl1e_request_irq(struct atl1
 
 	if (!adapter->have_msi)
 		flags |= IRQF_SHARED;
-	err = request_irq(adapter->pdev->irq, &atl1e_intr, flags,
+	err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
 			netdev->name, netdev);
 	if (err) {
 		dev_dbg(&pdev->dev,
@@ -2289,7 +2252,6 @@ static int atl1e_init_netdev(struct net_
 		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 	netdev->features |= NETIF_F_LLTX;
 	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atlx/atl1.c linux-libre-2.6.33-gnu1/drivers/net/atlx/atl1.c
--- linux-libre-2.6.32-gnu1/drivers/net/atlx/atl1.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atlx/atl1.c	2010-02-24 13:52:17.000000000 -0500
@@ -1344,8 +1344,8 @@ static u32 atl1_check_link(struct atl1_a
 
 	/* link result is our setting */
 	if (!reconfig) {
-		if (adapter->link_speed != speed
-		    || adapter->link_duplex != duplex) {
+		if (adapter->link_speed != speed ||
+		    adapter->link_duplex != duplex) {
 			adapter->link_speed = speed;
 			adapter->link_duplex = duplex;
 			atl1_setup_mac_ctrl(adapter);
@@ -1864,21 +1864,14 @@ static u16 atl1_alloc_rx_buffers(struct
 
 		rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
 
-		skb = netdev_alloc_skb(adapter->netdev,
-				       adapter->rx_buffer_len + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(adapter->netdev,
+						adapter->rx_buffer_len);
 		if (unlikely(!skb)) {
 			/* Better luck next round */
 			adapter->netdev->stats.rx_dropped++;
 			break;
 		}
 
-		/*
-		 * Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->alloced = 1;
 		buffer_info->skb = skb;
 		buffer_info->length = (u16) adapter->rx_buffer_len;
@@ -2094,8 +2087,8 @@ static void atl1_intr_tx(struct atl1_ada
 	}
 	atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
 
-	if (netif_queue_stopped(adapter->netdev)
-	    && netif_carrier_ok(adapter->netdev))
+	if (netif_queue_stopped(adapter->netdev) &&
+	    netif_carrier_ok(adapter->netdev))
 		netif_wake_queue(adapter->netdev);
 }
 
@@ -2596,7 +2589,7 @@ static s32 atl1_up(struct atl1_adapter *
 		irq_flags |= IRQF_SHARED;
 	}
 
-	err = request_irq(adapter->pdev->irq, &atl1_intr, irq_flags,
+	err = request_irq(adapter->pdev->irq, atl1_intr, irq_flags,
 			netdev->name, netdev);
 	if (unlikely(err))
 		goto err_up;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atlx/atl2.c linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.c
--- linux-libre-2.6.32-gnu1/drivers/net/atlx/atl2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atlx/atl2.c	2010-02-24 13:52:17.000000000 -0500
@@ -409,7 +409,7 @@ static void atl2_intr_rx(struct atl2_ada
 		if (rxd->status.ok && rxd->status.pkt_size >= 60) {
 			int rx_size = (int)(rxd->status.pkt_size - 4);
 			/* alloc new buffer */
-			skb = netdev_alloc_skb(netdev, rx_size + NET_IP_ALIGN);
+			skb = netdev_alloc_skb_ip_align(netdev, rx_size);
 			if (NULL == skb) {
 				printk(KERN_WARNING
 					"%s: Mem squeeze, deferring packet.\n",
@@ -421,7 +421,6 @@ static void atl2_intr_rx(struct atl2_ada
 				netdev->stats.rx_dropped++;
 				break;
 			}
-			skb_reserve(skb, NET_IP_ALIGN);
 			skb->dev = netdev;
 			memcpy(skb->data, rxd->packet, rx_size);
 			skb_put(skb, rx_size);
@@ -652,7 +651,7 @@ static int atl2_request_irq(struct atl2_
 	if (adapter->have_msi)
 		flags &= ~IRQF_SHARED;
 
-	return request_irq(adapter->pdev->irq, &atl2_intr, flags, netdev->name,
+	return request_irq(adapter->pdev->irq, atl2_intr, flags, netdev->name,
 		netdev);
 }
 
@@ -1960,12 +1959,15 @@ static int atl2_get_eeprom(struct net_de
 		return -ENOMEM;
 
 	for (i = first_dword; i < last_dword; i++) {
-		if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword])))
-			return -EIO;
+		if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) {
+			ret_val = -EIO;
+			goto free;
+		}
 	}
 
 	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
 		eeprom->len);
+free:
 	kfree(eeprom_buff);
 
 	return ret_val;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/atp.c linux-libre-2.6.33-gnu1/drivers/net/atp.c
--- linux-libre-2.6.32-gnu1/drivers/net/atp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/atp.c	2010-02-24 13:52:17.000000000 -0500
@@ -437,7 +437,7 @@ static int net_open(struct net_device *d
 	/* The interrupt line is turned off (tri-stated) when the device isn't in
 	   use.  That's especially important for "attached" interfaces where the
 	   port or interrupt may be shared. */
-	ret = request_irq(dev->irq, &atp_interrupt, 0, dev->name, dev);
+	ret = request_irq(dev->irq, atp_interrupt, 0, dev->name, dev);
 	if (ret)
 		return ret;
 
@@ -673,8 +673,8 @@ static irqreturn_t atp_interrupt(int irq
 				netif_wake_queue(dev);	/* Inform upper layers. */
 			}
 			num_tx_since_rx++;
-		} else if (num_tx_since_rx > 8
-				   && time_after(jiffies, dev->last_rx + HZ)) {
+		} else if (num_tx_since_rx > 8 &&
+			   time_after(jiffies, dev->last_rx + HZ)) {
 			if (net_debug > 2)
 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/au1000_eth.c linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/au1000_eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/au1000_eth.c	2010-02-24 13:52:17.000000000 -0500
@@ -881,7 +881,7 @@ static int au1000_open(struct net_device
 	if (au1000_debug > 4)
 		printk("%s: open: dev=%p\n", dev->name, dev);
 
-	if ((retval = request_irq(dev->irq, &au1000_interrupt, 0,
+	if ((retval = request_irq(dev->irq, au1000_interrupt, 0,
 					dev->name, dev))) {
 		printk(KERN_ERR "%s: unable to get IRQ %d\n",
 				dev->name, dev->irq);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ax88796.c linux-libre-2.6.33-gnu1/drivers/net/ax88796.c
--- linux-libre-2.6.32-gnu1/drivers/net/ax88796.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ax88796.c	2010-02-24 13:52:17.000000000 -0500
@@ -921,7 +921,7 @@ static int ax_probe(struct platform_devi
  		size = (res->end - res->start) + 1;
 
 		ax->mem2 = request_mem_region(res->start, size, pdev->name);
-		if (ax->mem == NULL) {
+		if (ax->mem2 == NULL) {
 			dev_err(&pdev->dev, "cannot reserve registers\n");
 			ret = -ENXIO;
 			goto exit_mem1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/b44.c linux-libre-2.6.33-gnu1/drivers/net/b44.c
--- linux-libre-2.6.32-gnu1/drivers/net/b44.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/b44.c	2010-02-24 13:52:17.000000000 -0500
@@ -1505,8 +1505,7 @@ static int b44_magic_pattern(u8 *macaddr
 		for (k = 0; k< ethaddr_bytes; k++) {
 			ppattern[offset + magicsync +
 				(j * ETH_ALEN) + k] = macaddr[k];
-			len++;
-			set_bit(len, (unsigned long *) pmask);
+			set_bit(len++, (unsigned long *) pmask);
 		}
 	}
 	return len - 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bcm63xx_enet.c linux-libre-2.6.33-gnu1/drivers/net/bcm63xx_enet.c
--- linux-libre-2.6.32-gnu1/drivers/net/bcm63xx_enet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bcm63xx_enet.c	2010-02-24 13:52:17.000000000 -0500
@@ -320,16 +320,13 @@ static int bcm_enet_receive_queue(struct
 		if (len < copybreak) {
 			struct sk_buff *nskb;
 
-			nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
+			nskb = netdev_alloc_skb_ip_align(dev, len);
 			if (!nskb) {
 				/* forget packet, just rearm desc */
 				priv->stats.rx_dropped++;
 				continue;
 			}
 
-			/* since we're copying the data, we can align
-			 * them properly */
-			skb_reserve(nskb, NET_IP_ALIGN);
 			dma_sync_single_for_cpu(kdev, desc->address,
 						len, DMA_FROM_DEVICE);
 			memcpy(nskb->data, skb->data, len);
@@ -1248,9 +1245,15 @@ static void bcm_enet_get_drvinfo(struct
 	drvinfo->n_stats = BCM_ENET_STATS_LEN;
 }
 
-static int bcm_enet_get_stats_count(struct net_device *netdev)
+static int bcm_enet_get_sset_count(struct net_device *netdev,
+					int string_set)
 {
-	return BCM_ENET_STATS_LEN;
+	switch (string_set) {
+	case ETH_SS_STATS:
+		return BCM_ENET_STATS_LEN;
+	default:
+		return -EINVAL;
+	}
 }
 
 static void bcm_enet_get_strings(struct net_device *netdev,
@@ -1476,7 +1479,7 @@ static int bcm_enet_set_pauseparam(struc
 
 static struct ethtool_ops bcm_enet_ethtool_ops = {
 	.get_strings		= bcm_enet_get_strings,
-	.get_stats_count	= bcm_enet_get_stats_count,
+	.get_sset_count		= bcm_enet_get_sset_count,
 	.get_ethtool_stats      = bcm_enet_get_ethtool_stats,
 	.get_settings		= bcm_enet_get_settings,
 	.set_settings		= bcm_enet_set_settings,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be_cmds.c linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.c
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be_cmds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,8 +71,8 @@ static int be_mcc_compl_process(struct b
 		extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
 				CQE_STATUS_EXTD_MASK;
 		dev_warn(&adapter->pdev->dev,
-			"Error in cmd completion: status(compl/extd)=%d/%d\n",
-			compl_status, extd_status);
+		"Error in cmd completion - opcode %d, compl %d, extd %d\n",
+			compl->tag0, compl_status, extd_status);
 	}
 	return compl_status;
 }
@@ -277,7 +277,7 @@ static inline struct be_sge *nonembedded
 
 /* Don't touch the hdr after it's prepared */
 static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
-				bool embedded, u8 sge_cnt)
+				bool embedded, u8 sge_cnt, u32 opcode)
 {
 	if (embedded)
 		wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
@@ -285,7 +285,8 @@ static void be_wrb_hdr_prepare(struct be
 		wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
 				MCC_WRB_SGE_CNT_SHIFT;
 	wrb->payload_length = payload_len;
-	be_dws_cpu_to_le(wrb, 20);
+	wrb->tag0 = opcode;
+	be_dws_cpu_to_le(wrb, 8);
 }
 
 /* Don't touch the hdr after it's prepared */
@@ -295,6 +296,7 @@ static void be_cmd_hdr_prepare(struct be
 	req_hdr->opcode = opcode;
 	req_hdr->subsystem = subsystem;
 	req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
+	req_hdr->version = 0;
 }
 
 static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
@@ -349,7 +351,11 @@ static struct be_mcc_wrb *wrb_from_mccq(
 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
 	struct be_mcc_wrb *wrb;
 
-	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+	if (atomic_read(&mccq->used) >= mccq->len) {
+		dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n");
+		return NULL;
+	}
+
 	wrb = queue_head_node(mccq);
 	queue_head_inc(mccq);
 	atomic_inc(&mccq->used);
@@ -357,6 +363,57 @@ static struct be_mcc_wrb *wrb_from_mccq(
 	return wrb;
 }
 
+/* Tell fw we're about to start firing cmds by writing a
+ * special pattern across the wrb hdr; uses mbox
+ */
+int be_cmd_fw_init(struct be_adapter *adapter)
+{
+	u8 *wrb;
+	int status;
+
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = (u8 *)wrb_from_mbox(adapter);
+	*wrb++ = 0xFF;
+	*wrb++ = 0x12;
+	*wrb++ = 0x34;
+	*wrb++ = 0xFF;
+	*wrb++ = 0xFF;
+	*wrb++ = 0x56;
+	*wrb++ = 0x78;
+	*wrb = 0xFF;
+
+	status = be_mbox_notify_wait(adapter);
+
+	spin_unlock(&adapter->mbox_lock);
+	return status;
+}
+
+/* Tell fw we're done with firing cmds by writing a
+ * special pattern across the wrb hdr; uses mbox
+ */
+int be_cmd_fw_clean(struct be_adapter *adapter)
+{
+	u8 *wrb;
+	int status;
+
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = (u8 *)wrb_from_mbox(adapter);
+	*wrb++ = 0xFF;
+	*wrb++ = 0xAA;
+	*wrb++ = 0xBB;
+	*wrb++ = 0xFF;
+	*wrb++ = 0xFF;
+	*wrb++ = 0xCC;
+	*wrb++ = 0xDD;
+	*wrb = 0xFF;
+
+	status = be_mbox_notify_wait(adapter);
+
+	spin_unlock(&adapter->mbox_lock);
+	return status;
+}
 int be_cmd_eq_create(struct be_adapter *adapter,
 		struct be_queue_info *eq, int eq_delay)
 {
@@ -370,7 +427,7 @@ int be_cmd_eq_create(struct be_adapter *
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_COMMON_EQ_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_EQ_CREATE, sizeof(*req));
@@ -414,7 +471,8 @@ int be_cmd_mac_addr_query(struct be_adap
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_MAC_QUERY);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req));
@@ -448,9 +506,14 @@ int be_cmd_pmac_add(struct be_adapter *a
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_PMAC_ADD);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req));
@@ -464,6 +527,7 @@ int be_cmd_pmac_add(struct be_adapter *a
 		*pmac_id = le32_to_cpu(resp->pmac_id);
 	}
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -478,9 +542,14 @@ int be_cmd_pmac_del(struct be_adapter *a
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_PMAC_DEL);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req));
@@ -490,8 +559,8 @@ int be_cmd_pmac_del(struct be_adapter *a
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
-
 	return status;
 }
 
@@ -512,7 +581,8 @@ int be_cmd_cq_create(struct be_adapter *
 	req = embedded_payload(wrb);
 	ctxt = &req->context;
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_CQ_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_CQ_CREATE, sizeof(*req));
@@ -569,7 +639,8 @@ int be_cmd_mccq_create(struct be_adapter
 	req = embedded_payload(wrb);
 	ctxt = &req->context;
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_MCC_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
@@ -613,7 +684,8 @@ int be_cmd_txq_create(struct be_adapter
 	req = embedded_payload(wrb);
 	ctxt = &req->context;
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_ETH_TX_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE,
 		sizeof(*req));
@@ -660,7 +732,8 @@ int be_cmd_rxq_create(struct be_adapter
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_ETH_RX_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_CREATE,
 		sizeof(*req));
@@ -701,8 +774,6 @@ int be_cmd_q_destroy(struct be_adapter *
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-
 	switch (queue_type) {
 	case QTYPE_EQ:
 		subsys = CMD_SUBSYSTEM_COMMON;
@@ -727,6 +798,9 @@ int be_cmd_q_destroy(struct be_adapter *
 	default:
 		BUG();
 	}
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, opcode);
+
 	be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
 	req->id = cpu_to_le16(q->id);
 
@@ -752,7 +826,8 @@ int be_cmd_if_create(struct be_adapter *
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_INTERFACE_CREATE);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
@@ -787,7 +862,8 @@ int be_cmd_if_destroy(struct be_adapter
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_INTERFACE_DESTROY);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
@@ -810,15 +886,20 @@ int be_cmd_get_stats(struct be_adapter *
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_get_stats *req;
 	struct be_sge *sge;
+	int status = 0;
 
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = nonemb_cmd->va;
 	sge = nonembedded_sgl(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
-	wrb->tag0 = OPCODE_ETH_GET_STATISTICS;
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+			OPCODE_ETH_GET_STATISTICS);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
 		OPCODE_ETH_GET_STATISTICS, sizeof(*req));
@@ -828,13 +909,14 @@ int be_cmd_get_stats(struct be_adapter *
 
 	be_mcc_notify(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
-	return 0;
+	return status;
 }
 
 /* Uses synchronous mcc */
 int be_cmd_link_status_query(struct be_adapter *adapter,
-			bool *link_up)
+			bool *link_up, u8 *mac_speed, u16 *link_speed)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_link_status *req;
@@ -843,11 +925,16 @@ int be_cmd_link_status_query(struct be_a
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
 	*link_up = false;
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_LINK_STATUS_QUERY);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
@@ -855,10 +942,14 @@ int be_cmd_link_status_query(struct be_a
 	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
-		if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
+		if (resp->mac_speed != PHY_LINK_SPEED_ZERO) {
 			*link_up = true;
+			*link_speed = le16_to_cpu(resp->link_speed);
+			*mac_speed = resp->mac_speed;
+		}
 	}
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -875,7 +966,8 @@ int be_cmd_get_fw_ver(struct be_adapter
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_GET_FW_VERSION);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
@@ -897,13 +989,19 @@ int be_cmd_modify_eqd(struct be_adapter
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_modify_eq_delay *req;
+	int status = 0;
 
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_MODIFY_EQ_DELAY);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
@@ -915,8 +1013,9 @@ int be_cmd_modify_eqd(struct be_adapter
 
 	be_mcc_notify(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
-	return 0;
+	return status;
 }
 
 /* Uses sycnhronous mcc */
@@ -930,9 +1029,14 @@ int be_cmd_vlan_config(struct be_adapter
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_NTWK_VLAN_CONFIG);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req));
@@ -948,6 +1052,7 @@ int be_cmd_vlan_config(struct be_adapter
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -964,9 +1069,13 @@ int be_cmd_promiscuous_config(struct be_
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_PROMISCUOUS);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
 		OPCODE_ETH_PROMISCUOUS, sizeof(*req));
@@ -978,6 +1087,7 @@ int be_cmd_promiscuous_config(struct be_
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -987,24 +1097,35 @@ int be_cmd_promiscuous_config(struct be_
  * (mc == NULL) => multicast promiscous
  */
 int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-		struct dev_mc_list *mc_list, u32 mc_count)
+		struct dev_mc_list *mc_list, u32 mc_count,
+		struct be_dma_mem *mem)
 {
-#define BE_MAX_MC		32 /* set mcast promisc if > 32 */
 	struct be_mcc_wrb *wrb;
-	struct be_cmd_req_mcast_mac_config *req;
+	struct be_cmd_req_mcast_mac_config *req = mem->va;
+	struct be_sge *sge;
+	int status;
 
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
-	req = embedded_payload(wrb);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	sge = nonembedded_sgl(wrb);
+	memset(req, 0, sizeof(*req));
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+			OPCODE_COMMON_NTWK_MULTICAST_SET);
+	sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
+	sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(mem->size);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
 
 	req->interface_id = if_id;
-	if (mc_list && mc_count <= BE_MAX_MC) {
+	if (mc_list) {
 		int i;
 		struct dev_mc_list *mc;
 
@@ -1016,11 +1137,11 @@ int be_cmd_multicast_set(struct be_adapt
 		req->promiscuous = 1;
 	}
 
-	be_mcc_notify_wait(adapter);
+	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
-
-	return 0;
+	return status;
 }
 
 /* Uses synchrounous mcc */
@@ -1033,9 +1154,14 @@ int be_cmd_set_flow_control(struct be_ad
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_SET_FLOW_CONTROL);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req));
@@ -1045,6 +1171,7 @@ int be_cmd_set_flow_control(struct be_ad
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -1059,9 +1186,14 @@ int be_cmd_get_flow_control(struct be_ad
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_GET_FLOW_CONTROL);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
@@ -1074,6 +1206,7 @@ int be_cmd_get_flow_control(struct be_ad
 		*rx_fc = le16_to_cpu(resp->rx_flow_control);
 	}
 
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
@@ -1090,7 +1223,8 @@ int be_cmd_query_fw_cfg(struct be_adapte
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_QUERY_FIRMWARE_CONFIG);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
@@ -1118,7 +1252,8 @@ int be_cmd_reset_function(struct be_adap
 	wrb = wrb_from_mbox(adapter);
 	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_FUNCTION_RESET);
 
 	be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
@@ -1129,6 +1264,113 @@ int be_cmd_reset_function(struct be_adap
 	return status;
 }
 
+/* Uses sync mcc */
+int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
+			u8 bcn, u8 sts, u8 state)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_enable_disable_beacon *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_ENABLE_DISABLE_BEACON);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_ENABLE_DISABLE_BEACON, sizeof(*req));
+
+	req->port_num = port_num;
+	req->beacon_state = state;
+	req->beacon_duration = bcn;
+	req->status_duration = sts;
+
+	status = be_mcc_notify_wait(adapter);
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+/* Uses sync mcc */
+int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_beacon_state *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_GET_BEACON_STATE);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req));
+
+	req->port_num = port_num;
+
+	status = be_mcc_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_get_beacon_state *resp =
+						embedded_payload(wrb);
+		*state = resp->beacon_state;
+	}
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+/* Uses sync mcc */
+int be_cmd_read_port_type(struct be_adapter *adapter, u32 port,
+				u8 *connector)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_port_type *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0,
+			OPCODE_COMMON_READ_TRANSRECV_DATA);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_READ_TRANSRECV_DATA, sizeof(*req));
+
+	req->port = cpu_to_le32(port);
+	req->page_num = cpu_to_le32(TR_PAGE_A0);
+	status = be_mcc_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_port_type *resp = embedded_payload(wrb);
+			*connector = resp->data.connector;
+	}
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
 int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
 			u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
@@ -1140,9 +1382,15 @@ int be_cmd_write_flashrom(struct be_adap
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = cmd->va;
 	sge = nonembedded_sgl(wrb);
 
-	be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
+	be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
+			OPCODE_COMMON_WRITE_FLASHROM);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
@@ -1156,6 +1404,207 @@ int be_cmd_write_flashrom(struct be_adap
 
 	status = be_mcc_notify_wait(adapter);
 
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_write_flashrom *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req)+4, true, 0,
+			OPCODE_COMMON_READ_FLASHROM);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4);
+
+	req->params.op_type = cpu_to_le32(FLASHROM_TYPE_REDBOOT);
+	req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
+	req->params.offset = 0x3FFFC;
+	req->params.data_buf_size = 0x4;
+
+	status = be_mcc_notify_wait(adapter);
+	if (!status)
+		memcpy(flashed_crc, req->params.data_buf, 4);
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
+				struct be_dma_mem *nonemb_cmd)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_acpi_wol_magic_config *req;
+	struct be_sge *sge;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = nonemb_cmd->va;
+	sge = nonembedded_sgl(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+			OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+		OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req));
+	memcpy(req->magic_mac, mac, ETH_ALEN);
+
+	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(nonemb_cmd->size);
+
+	status = be_mcc_notify_wait(adapter);
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
+			u8 loopback_type, u8 enable)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_set_lmode *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+				OPCODE_LOWLEVEL_SET_LOOPBACK_MODE);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
+			OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
+			sizeof(*req));
+
+	req->src_port = port_num;
+	req->dest_port = port_num;
+	req->loopback_type = loopback_type;
+	req->loopback_state = enable;
+
+	status = be_mcc_notify_wait(adapter);
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
+		u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_loopback_test *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+				OPCODE_LOWLEVEL_LOOPBACK_TEST);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
+			OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req));
+	req->hdr.timeout = 4;
+
+	req->pattern = cpu_to_le64(pattern);
+	req->src_port = cpu_to_le32(port_num);
+	req->dest_port = cpu_to_le32(port_num);
+	req->pkt_size = cpu_to_le32(pkt_size);
+	req->num_pkts = cpu_to_le32(num_pkts);
+	req->loopback_type = cpu_to_le32(loopback_type);
+
+	status = be_mcc_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_loopback_test *resp = embedded_payload(wrb);
+		status = le32_to_cpu(resp->status);
+	}
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
+				u32 byte_cnt, struct be_dma_mem *cmd)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_ddrdma_test *req;
+	struct be_sge *sge;
+	int status;
+	int i, j = 0;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = cmd->va;
+	sge = nonembedded_sgl(wrb);
+	be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
+				OPCODE_LOWLEVEL_HOST_DDR_DMA);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
+			OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size);
+
+	sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
+	sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(cmd->size);
+
+	req->pattern = cpu_to_le64(pattern);
+	req->byte_count = cpu_to_le32(byte_cnt);
+	for (i = 0; i < byte_cnt; i++) {
+		req->snd_buff[i] = (u8)(pattern >> (j*8));
+		j++;
+		if (j > 7)
+			j = 0;
+	}
+
+	status = be_mcc_notify_wait(adapter);
+
+	if (!status) {
+		struct be_cmd_resp_ddrdma_test *resp;
+		resp = cmd->va;
+		if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
+				resp->snd_err) {
+			status = -1;
+		}
+	}
+
+err:
 	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be_cmds.h linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.h
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be_cmds.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be_cmds.h	2010-02-24 13:52:17.000000000 -0500
@@ -112,12 +112,14 @@ struct be_mcc_mailbox {
 
 #define CMD_SUBSYSTEM_COMMON	0x1
 #define CMD_SUBSYSTEM_ETH 	0x3
+#define CMD_SUBSYSTEM_LOWLEVEL  0xb
 
 #define OPCODE_COMMON_NTWK_MAC_QUERY			1
 #define OPCODE_COMMON_NTWK_MAC_SET			2
 #define OPCODE_COMMON_NTWK_MULTICAST_SET		3
 #define OPCODE_COMMON_NTWK_VLAN_CONFIG  		4
 #define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY		5
+#define OPCODE_COMMON_READ_FLASHROM			6
 #define OPCODE_COMMON_WRITE_FLASHROM			7
 #define OPCODE_COMMON_CQ_CREATE				12
 #define OPCODE_COMMON_EQ_CREATE				13
@@ -138,6 +140,9 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_NTWK_PMAC_ADD			59
 #define OPCODE_COMMON_NTWK_PMAC_DEL			60
 #define OPCODE_COMMON_FUNCTION_RESET			61
+#define OPCODE_COMMON_ENABLE_DISABLE_BEACON		69
+#define OPCODE_COMMON_GET_BEACON_STATE			70
+#define OPCODE_COMMON_READ_TRANSRECV_DATA		73
 
 #define OPCODE_ETH_ACPI_CONFIG				2
 #define OPCODE_ETH_PROMISCUOUS				3
@@ -146,6 +151,11 @@ struct be_mcc_mailbox {
 #define OPCODE_ETH_RX_CREATE            		8
 #define OPCODE_ETH_TX_DESTROY           		9
 #define OPCODE_ETH_RX_DESTROY           		10
+#define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG		12
+
+#define OPCODE_LOWLEVEL_HOST_DDR_DMA                    17
+#define OPCODE_LOWLEVEL_LOOPBACK_TEST                   18
+#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE		19
 
 struct be_cmd_req_hdr {
 	u8 opcode;		/* dword 0 */
@@ -154,7 +164,8 @@ struct be_cmd_req_hdr {
 	u8 domain;		/* dword 0 */
 	u32 timeout;		/* dword 1 */
 	u32 request_length;	/* dword 2 */
-	u32 rsvd;		/* dword 3 */
+	u8 version;		/* dword 3 */
+	u8 rsvd[3];		/* dword 3 */
 };
 
 #define RESP_HDR_INFO_OPCODE_SHIFT	0	/* bits 0 - 7 */
@@ -435,7 +446,7 @@ enum be_if_flags {
  * filtering capabilities. */
 struct be_cmd_req_if_create {
 	struct be_cmd_req_hdr hdr;
-	u32 version;		/* ignore currntly */
+	u32 version;		/* ignore currently */
 	u32 capability_flags;
 	u32 enable_flags;
 	u8 mac_addr[ETH_ALEN];
@@ -587,6 +598,8 @@ struct be_cmd_req_promiscuous_config {
 	u16 rsvd0;
 } __packed;
 
+/******************** Multicast MAC Config *******************/
+#define BE_MAX_MC		64 /* set mcast promisc if > 64 */
 struct macaddr {
 	u8 byte[ETH_ALEN];
 };
@@ -596,7 +609,7 @@ struct be_cmd_req_mcast_mac_config {
 	u16 num_mac;
 	u8 promiscuous;
 	u8 interface_id;
-	struct macaddr mac[32];
+	struct macaddr mac[BE_MAX_MC];
 } __packed;
 
 static inline struct be_hw_stats *
@@ -633,9 +646,47 @@ struct be_cmd_resp_link_status {
 	u8 mac_fault;
 	u8 mgmt_mac_duplex;
 	u8 mgmt_mac_speed;
-	u16 rsvd0;
+	u16 link_speed;
+	u32 rsvd0;
 } __packed;
 
+/******************** Port Identification ***************************/
+/*    Identifies the type of port attached to NIC     */
+struct be_cmd_req_port_type {
+	struct be_cmd_req_hdr hdr;
+	u32 page_num;
+	u32 port;
+};
+
+enum {
+	TR_PAGE_A0 = 0xa0,
+	TR_PAGE_A2 = 0xa2
+};
+
+struct be_cmd_resp_port_type {
+	struct be_cmd_resp_hdr hdr;
+	u32 page_num;
+	u32 port;
+	struct data {
+		u8 identifier;
+		u8 identifier_ext;
+		u8 connector;
+		u8 transceiver[8];
+		u8 rsvd0[3];
+		u8 length_km;
+		u8 length_hm;
+		u8 length_om1;
+		u8 length_om2;
+		u8 length_cu;
+		u8 length_cu_m;
+		u8 vendor_name[16];
+		u8 rsvd;
+		u8 vendor_oui[3];
+		u8 vendor_pn[16];
+		u8 vendor_rev[4];
+	} data;
+};
+
 /******************** Get FW Version *******************/
 struct be_cmd_req_get_fw_version {
 	struct be_cmd_req_hdr hdr;
@@ -699,6 +750,37 @@ struct be_cmd_resp_query_fw_cfg {
 	u32 rsvd[26];
 };
 
+/******************** Port Beacon ***************************/
+
+#define BEACON_STATE_ENABLED		0x1
+#define BEACON_STATE_DISABLED		0x0
+
+struct be_cmd_req_enable_disable_beacon {
+	struct be_cmd_req_hdr hdr;
+	u8  port_num;
+	u8  beacon_state;
+	u8  beacon_duration;
+	u8  status_duration;
+} __packed;
+
+struct be_cmd_resp_enable_disable_beacon {
+	struct be_cmd_resp_hdr resp_hdr;
+	u32 rsvd0;
+} __packed;
+
+struct be_cmd_req_get_beacon_state {
+	struct be_cmd_req_hdr hdr;
+	u8  port_num;
+	u8  rsvd0;
+	u16 rsvd1;
+} __packed;
+
+struct be_cmd_resp_get_beacon_state {
+	struct be_cmd_resp_hdr resp_hdr;
+	u8 beacon_state;
+	u8 rsvd0[3];
+} __packed;
+
 /****************** Firmware Flash ******************/
 struct flashrom_params {
 	u32 op_code;
@@ -713,6 +795,66 @@ struct be_cmd_write_flashrom {
 	struct flashrom_params params;
 };
 
+/************************ WOL *******************************/
+struct be_cmd_req_acpi_wol_magic_config{
+	struct be_cmd_req_hdr hdr;
+	u32 rsvd0[145];
+	u8 magic_mac[6];
+	u8 rsvd2[2];
+} __packed;
+
+/********************** LoopBack test *********************/
+struct be_cmd_req_loopback_test {
+	struct be_cmd_req_hdr hdr;
+	u32 loopback_type;
+	u32 num_pkts;
+	u64 pattern;
+	u32 src_port;
+	u32 dest_port;
+	u32 pkt_size;
+};
+
+struct be_cmd_resp_loopback_test {
+	struct be_cmd_resp_hdr resp_hdr;
+	u32    status;
+	u32    num_txfer;
+	u32    num_rx;
+	u32    miscomp_off;
+	u32    ticks_compl;
+};
+
+struct be_cmd_req_set_lmode {
+	struct be_cmd_req_hdr hdr;
+	u8 src_port;
+	u8 dest_port;
+	u8 loopback_type;
+	u8 loopback_state;
+};
+
+struct be_cmd_resp_set_lmode {
+	struct be_cmd_resp_hdr resp_hdr;
+	u8 rsvd0[4];
+};
+
+/********************** DDR DMA test *********************/
+struct be_cmd_req_ddrdma_test {
+	struct be_cmd_req_hdr hdr;
+	u64 pattern;
+	u32 byte_count;
+	u32 rsvd0;
+	u8  snd_buff[4096];
+	u8  rsvd1[4096];
+};
+
+struct be_cmd_resp_ddrdma_test {
+	struct be_cmd_resp_hdr hdr;
+	u64 pattern;
+	u32 byte_cnt;
+	u32 snd_err;
+	u8  rsvd0[4096];
+	u8  rcv_buff[4096];
+};
+
 extern int be_pci_fnum_get(struct be_adapter *adapter);
 extern int be_cmd_POST(struct be_adapter *adapter);
 extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -743,7 +885,7 @@ extern int be_cmd_rxq_create(struct be_a
 extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 			int type);
 extern int be_cmd_link_status_query(struct be_adapter *adapter,
-			bool *link_up);
+			bool *link_up, u8 *mac_speed, u16 *link_speed);
 extern int be_cmd_reset(struct be_adapter *adapter);
 extern int be_cmd_get_stats(struct be_adapter *adapter,
 			struct be_dma_mem *nonemb_cmd);
@@ -756,7 +898,8 @@ extern int be_cmd_vlan_config(struct be_
 extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
 			u8 port_num, bool en);
 extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-			struct dev_mc_list *mc_list, u32 mc_count);
+			struct dev_mc_list *mc_list, u32 mc_count,
+			struct be_dma_mem *mem);
 extern int be_cmd_set_flow_control(struct be_adapter *adapter,
 			u32 tx_fc, u32 rx_fc);
 extern int be_cmd_get_flow_control(struct be_adapter *adapter,
@@ -765,6 +908,24 @@ extern int be_cmd_query_fw_cfg(struct be
 			u32 *port_num, u32 *cap);
 extern int be_cmd_reset_function(struct be_adapter *adapter);
 extern int be_process_mcc(struct be_adapter *adapter);
+extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
+			u8 port_num, u8 beacon, u8 status, u8 state);
+extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
+			u8 port_num, u32 *state);
+extern int be_cmd_read_port_type(struct be_adapter *adapter, u32 port,
+					u8 *connector);
 extern int be_cmd_write_flashrom(struct be_adapter *adapter,
 			struct be_dma_mem *cmd, u32 flash_oper,
 			u32 flash_opcode, u32 buf_size);
+extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc);
+extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
+				struct be_dma_mem *nonemb_cmd);
+extern int be_cmd_fw_init(struct be_adapter *adapter);
+extern int be_cmd_fw_clean(struct be_adapter *adapter);
+extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
+				u32 loopback_type, u32 pkt_size,
+				u32 num_pkts, u64 pattern);
+extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
+			u32 byte_cnt, struct be_dma_mem *cmd);
+extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
+				u8 loopback_type, u8 enable);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/benet/be_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,7 +55,7 @@ static const struct be_ethtool_stat et_s
 	{DRVSTAT_INFO(be_tx_stops)},
 	{DRVSTAT_INFO(be_fwd_reqs)},
 	{DRVSTAT_INFO(be_tx_wrbs)},
-	{DRVSTAT_INFO(be_polls)},
+	{DRVSTAT_INFO(be_rx_polls)},
 	{DRVSTAT_INFO(be_tx_events)},
 	{DRVSTAT_INFO(be_rx_events)},
 	{DRVSTAT_INFO(be_tx_compl)},
@@ -107,6 +107,19 @@ static const struct be_ethtool_stat et_s
 };
 #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
 
+static const char et_self_tests[][ETH_GSTRING_LEN] = {
+	"MAC Loopback test",
+	"PHY Loopback test",
+	"External Loopback test",
+	"DDR DMA test"
+};
+
+#define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
+#define BE_MAC_LOOPBACK 0x0
+#define BE_PHY_LOOPBACK 0x1
+#define BE_ONE_PORT_EXT_LOOPBACK 0x2
+#define BE_NO_LOOPBACK 0xff
+
 static void
 be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 {
@@ -234,7 +247,7 @@ be_get_ethtool_stats(struct net_device *
 	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
 	struct be_port_rxf_stats *port_stats =
 			&rxf_stats->port[adapter->port_num];
-	struct net_device_stats *net_stats = &adapter->stats.net_stats;
+	struct net_device_stats *net_stats = &netdev->stats;
 	struct be_erx_stats *erx_stats = &hw_stats->erx;
 	void *p = NULL;
 	int i;
@@ -278,19 +291,100 @@ be_get_stat_strings(struct net_device *n
 			data += ETH_GSTRING_LEN;
 		}
 		break;
+	case ETH_SS_TEST:
+		for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
+			memcpy(data, et_self_tests[i], ETH_GSTRING_LEN);
+			data += ETH_GSTRING_LEN;
+		}
+		break;
 	}
 }
 
-static int be_get_stats_count(struct net_device *netdev)
+static int be_get_sset_count(struct net_device *netdev, int stringset)
 {
-	return ETHTOOL_STATS_NUM;
+	switch (stringset) {
+	case ETH_SS_TEST:
+		return ETHTOOL_TESTS_NUM;
+	case ETH_SS_STATS:
+		return ETHTOOL_STATS_NUM;
+	default:
+		return -EINVAL;
+	}
 }
 
 static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-	ecmd->speed = SPEED_10000;
+	struct be_adapter *adapter = netdev_priv(netdev);
+	u8 mac_speed = 0, connector = 0;
+	u16 link_speed = 0;
+	bool link_up = false;
+	int status;
+
+	if (adapter->link_speed < 0) {
+		status = be_cmd_link_status_query(adapter, &link_up,
+						&mac_speed, &link_speed);
+
+		/* link_speed is in units of 10 Mbps */
+		if (link_speed) {
+			ecmd->speed = link_speed*10;
+		} else {
+			switch (mac_speed) {
+			case PHY_LINK_SPEED_1GBPS:
+				ecmd->speed = SPEED_1000;
+				break;
+			case PHY_LINK_SPEED_10GBPS:
+				ecmd->speed = SPEED_10000;
+				break;
+			}
+		}
+
+		status = be_cmd_read_port_type(adapter, adapter->port_num,
+						&connector);
+		if (!status) {
+			switch (connector) {
+			case 7:
+				ecmd->port = PORT_FIBRE;
+				ecmd->transceiver = XCVR_EXTERNAL;
+				break;
+			case 0:
+				ecmd->port = PORT_TP;
+				ecmd->transceiver = XCVR_EXTERNAL;
+				break;
+			default:
+				ecmd->port = PORT_TP;
+				ecmd->transceiver = XCVR_INTERNAL;
+				break;
+			}
+		} else {
+			ecmd->port = PORT_AUI;
+			ecmd->transceiver = XCVR_INTERNAL;
+		}
+
+		/* Save for future use */
+		adapter->link_speed = ecmd->speed;
+		adapter->port_type = ecmd->port;
+		adapter->transceiver = ecmd->transceiver;
+	} else {
+		ecmd->speed = adapter->link_speed;
+		ecmd->port = adapter->port_type;
+		ecmd->transceiver = adapter->transceiver;
+	}
+
 	ecmd->duplex = DUPLEX_FULL;
 	ecmd->autoneg = AUTONEG_DISABLE;
+	ecmd->phy_address = adapter->port_num;
+	switch (ecmd->port) {
+	case PORT_FIBRE:
+		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
+		break;
+	case PORT_TP:
+		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
+		break;
+	case PORT_AUI:
+		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI);
+		break;
+	}
+
 	return 0;
 }
 
@@ -335,6 +429,131 @@ be_set_pauseparam(struct net_device *net
 }
 
 static int
+be_phys_id(struct net_device *netdev, u32 data)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	int status;
+	u32 cur;
+
+	be_cmd_get_beacon_state(adapter, adapter->port_num, &cur);
+
+	if (cur == BEACON_STATE_ENABLED)
+		return 0;
+
+	if (data < 2)
+		data = 2;
+
+	status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0,
+			BEACON_STATE_ENABLED);
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(data*HZ);
+
+	status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0,
+			BEACON_STATE_DISABLED);
+
+	return status;
+}
+
+static void
+be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+
+	wol->supported = WAKE_MAGIC;
+	if (adapter->wol)
+		wol->wolopts = WAKE_MAGIC;
+	else
+		wol->wolopts = 0;
+	memset(&wol->sopass, 0, sizeof(wol->sopass));
+	return;
+}
+
+static int
+be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+
+	if (wol->wolopts & ~WAKE_MAGIC)
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		adapter->wol = true;
+	else
+		adapter->wol = false;
+
+	return 0;
+}
+
+static int
+be_test_ddr_dma(struct be_adapter *adapter)
+{
+	int ret, i;
+	struct be_dma_mem ddrdma_cmd;
+	u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5};
+
+	ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
+	ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
+					&ddrdma_cmd.dma);
+	if (!ddrdma_cmd.va) {
+		dev_err(&adapter->pdev->dev, "Memory allocation failure \n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < 2; i++) {
+		ret = be_cmd_ddr_dma_test(adapter, pattern[i],
+					4096, &ddrdma_cmd);
+		if (ret != 0)
+			goto err;
+	}
+
+err:
+	pci_free_consistent(adapter->pdev, ddrdma_cmd.size,
+			ddrdma_cmd.va, ddrdma_cmd.dma);
+	return ret;
+}
+
+static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
+				u64 *status)
+{
+	be_cmd_set_loopback(adapter, adapter->port_num,
+				loopback_type, 1);
+	*status = be_cmd_loopback_test(adapter, adapter->port_num,
+				loopback_type, 1500,
+				2, 0xabc);
+	be_cmd_set_loopback(adapter, adapter->port_num,
+				BE_NO_LOOPBACK, 1);
+	return *status;
+}
+
+static void
+be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+
+	memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
+
+	if (test->flags & ETH_TEST_FL_OFFLINE) {
+		if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
+						&data[0]) != 0) {
+			test->flags |= ETH_TEST_FL_FAILED;
+		}
+		if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
+						&data[1]) != 0) {
+			test->flags |= ETH_TEST_FL_FAILED;
+		}
+		if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
+						&data[2]) != 0) {
+			test->flags |= ETH_TEST_FL_FAILED;
+		}
+
+		data[3] = be_test_ddr_dma(adapter);
+		if (data[3] != 0)
+			test->flags |= ETH_TEST_FL_FAILED;
+	}
+
+}
+
+static int
 be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
@@ -351,6 +570,8 @@ be_do_flash(struct net_device *netdev, s
 const struct ethtool_ops be_ethtool_ops = {
 	.get_settings = be_get_settings,
 	.get_drvinfo = be_get_drvinfo,
+	.get_wol = be_get_wol,
+	.set_wol = be_set_wol,
 	.get_link = ethtool_op_get_link,
 	.get_coalesce = be_get_coalesce,
 	.set_coalesce = be_set_coalesce,
@@ -366,7 +587,9 @@ const struct ethtool_ops be_ethtool_ops
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 	.get_strings = be_get_stat_strings,
-	.get_stats_count = be_get_stats_count,
+	.phys_id = be_phys_id,
+	.get_sset_count = be_get_sset_count,
 	.get_ethtool_stats = be_get_ethtool_stats,
 	.flash_device = be_do_flash,
+	.self_test = be_self_test,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be.h linux-libre-2.6.33-gnu1/drivers/net/benet/be.h
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,23 +32,34 @@
 
 #include "be_hw.h"
 
-#define DRV_VER			"2.101.205"
+#define DRV_VER			"2.101.346u"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
+#define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC"
 #define OC_NAME			"Emulex OneConnect 10Gbps NIC"
+#define OC_NAME1		"Emulex OneConnect 10Gbps NIC (be3)"
 #define DRV_DESC		BE_NAME "Driver"
 
 #define BE_VENDOR_ID 		0x19a2
 #define BE_DEVICE_ID1		0x211
+#define BE_DEVICE_ID2		0x221
 #define OC_DEVICE_ID1		0x700
 #define OC_DEVICE_ID2		0x701
+#define OC_DEVICE_ID3		0x710
 
 static inline char *nic_name(struct pci_dev *pdev)
 {
-	if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2)
+	switch (pdev->device) {
+	case OC_DEVICE_ID1:
+	case OC_DEVICE_ID2:
 		return OC_NAME;
-	else
+	case OC_DEVICE_ID3:
+		return OC_NAME1;
+	case BE_DEVICE_ID2:
+		return BE3_NAME;
+	default:
 		return BE_NAME;
+	}
 }
 
 /* Number of bytes of an RX frame that are copied to skb->data */
@@ -159,7 +170,7 @@ struct be_drvr_stats {
 	u32 cache_barrier[16];
 
 	u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
-	u32 be_polls;		/* number of times NAPI called poll function */
+	u32 be_rx_polls;	/* number of times NAPI called poll function */
 	u32 be_rx_events;	/* number of ucast rx completion events  */
 	u32 be_rx_compl;	/* number of rx completion entries processed */
 	ulong be_rx_jiffies;
@@ -181,7 +192,6 @@ struct be_drvr_stats {
 
 struct be_stats_obj {
 	struct be_drvr_stats drvr_stats;
-	struct net_device_stats net_stats;
 	struct be_dma_mem cmd;
 };
 
@@ -244,6 +254,7 @@ struct be_adapter {
 	struct vlan_group *vlan_grp;
 	u16 num_vlans;
 	u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
+	struct be_dma_mem mc_cmd_mem;
 
 	struct be_stats_obj stats;
 	/* Work queue used to perform periodic tasks like getting statistics */
@@ -258,11 +269,20 @@ struct be_adapter {
 	bool link_up;
 	u32 port_num;
 	bool promiscuous;
+	bool wol;
 	u32 cap;
 	u32 rx_fc;		/* Rx flow control */
 	u32 tx_fc;		/* Tx flow control */
+	int link_speed;
+	u8 port_type;
+	u8 transceiver;
+	u8 generation;		/* BladeEngine ASIC generation */
 };
 
+/* BladeEngine Generation numbers */
+#define BE_GEN2 2
+#define BE_GEN3 3
+
 extern const struct ethtool_ops be_ethtool_ops;
 
 #define drvr_stats(adapter)		(&adapter->stats.drvr_stats)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be_hw.h linux-libre-2.6.33-gnu1/drivers/net/benet/be_hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be_hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be_hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -52,6 +52,10 @@
  */
 #define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK	(1 << 29) /* bit 29 */
 
+/********* Power managment (WOL) **********/
+#define PCICFG_PM_CONTROL_OFFSET		0x44
+#define PCICFG_PM_CONTROL_MASK			0x108	/* bits 3 & 8 */
+
 /********* ISR0 Register offset **********/
 #define CEV_ISR0_OFFSET 			0xC18
 #define CEV_ISR_SIZE				4
@@ -225,6 +229,7 @@ struct be_eth_rx_compl {
 #define NUM_FLASHDIR_ENTRIES		32
 
 #define FLASHROM_TYPE_ISCSI_ACTIVE	0
+#define FLASHROM_TYPE_REDBOOT		1
 #define FLASHROM_TYPE_BIOS		2
 #define FLASHROM_TYPE_PXE_BIOS		3
 #define FLASHROM_TYPE_FCOE_BIOS		8
@@ -234,9 +239,11 @@ struct be_eth_rx_compl {
 
 #define FLASHROM_OPER_FLASH		1
 #define FLASHROM_OPER_SAVE		2
+#define FLASHROM_OPER_REPORT		4
 
 #define FLASH_IMAGE_MAX_SIZE            (1310720) /* Max firmware image size */
 #define FLASH_BIOS_IMAGE_MAX_SIZE       (262144)  /* Max OPTION ROM image sz */
+#define FLASH_REDBOOT_IMAGE_MAX_SIZE    (262144)  /* Max redboot image sz */
 
 /* Offsets for components on Flash. */
 #define FLASH_iSCSI_PRIMARY_IMAGE_START (1048576)
@@ -246,6 +253,8 @@ struct be_eth_rx_compl {
 #define FLASH_iSCSI_BIOS_START          (7340032)
 #define FLASH_PXE_BIOS_START            (7864320)
 #define FLASH_FCoE_BIOS_START           (524288)
+#define FLASH_REDBOOT_START		(32768)
+#define FLASH_REDBOOT_ISM_START		(0)
 
 struct controller_id {
 	u32 vendor;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/benet/be_main.c linux-libre-2.6.33-gnu1/drivers/net/benet/be_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/benet/be_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/benet/be_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,8 +31,10 @@ MODULE_PARM_DESC(rx_frag_size, "Size of
 
 static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -123,6 +125,9 @@ static int be_mac_addr_set(struct net_de
 	struct sockaddr *addr = p;
 	int status = 0;
 
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
 	status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
 	if (status)
 		return status;
@@ -141,7 +146,7 @@ void netdev_stats_update(struct be_adapt
 	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
 	struct be_port_rxf_stats *port_stats =
 			&rxf_stats->port[adapter->port_num];
-	struct net_device_stats *dev_stats = &adapter->stats.net_stats;
+	struct net_device_stats *dev_stats = &adapter->netdev->stats;
 	struct be_erx_stats *erx_stats = &hw_stats->erx;
 
 	dev_stats->rx_packets = port_stats->rx_total_frames;
@@ -168,7 +173,8 @@ void netdev_stats_update(struct be_adapt
 		port_stats->rx_udp_checksum_errs;
 
 	/*  no space in linux buffers: best possible approximation */
-	dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0];
+	dev_stats->rx_dropped =
+		erx_stats->rx_drops_no_fragments[adapter->rx_obj.q.id];
 
 	/* detailed rx errors */
 	dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
@@ -214,6 +220,7 @@ void be_link_status_update(struct be_ada
 
 	/* If link came up or went down */
 	if (adapter->link_up != link_up) {
+		adapter->link_speed = -1;
 		if (link_up) {
 			netif_start_queue(netdev);
 			netif_carrier_on(netdev);
@@ -269,9 +276,7 @@ static void be_rx_eqd_update(struct be_a
 
 static struct net_device_stats *be_get_stats(struct net_device *dev)
 {
-	struct be_adapter *adapter = netdev_priv(dev);
-
-	return &adapter->stats.net_stats;
+	return &dev->stats;
 }
 
 static u32 be_calc_rate(u64 bytes, unsigned long ticks)
@@ -389,15 +394,11 @@ static int make_tx_wrbs(struct be_adapte
 	atomic_add(wrb_cnt, &txq->used);
 	queue_head_inc(txq);
 
-	if (skb_dma_map(&pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&pdev->dev, "TX DMA mapping failed\n");
-		return 0;
-	}
-
 	if (skb->len > skb->data_len) {
 		int len = skb->len - skb->data_len;
+		busaddr = pci_map_single(pdev, skb->data, len,
+					 PCI_DMA_TODEVICE);
 		wrb = queue_head_node(txq);
-		busaddr = skb_shinfo(skb)->dma_head;
 		wrb_fill(wrb, busaddr, len);
 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
 		queue_head_inc(txq);
@@ -407,8 +408,9 @@ static int make_tx_wrbs(struct be_adapte
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		struct skb_frag_struct *frag =
 			&skb_shinfo(skb)->frags[i];
-
-		busaddr = skb_shinfo(skb)->dma_maps[i];
+		busaddr = pci_map_page(pdev, frag->page,
+				       frag->page_offset,
+				       frag->size, PCI_DMA_TODEVICE);
 		wrb = queue_head_node(txq);
 		wrb_fill(wrb, busaddr, frag->size);
 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
@@ -562,13 +564,15 @@ static void be_set_multicast_list(struct
 		be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
 	}
 
-	if (netdev->flags & IFF_ALLMULTI) {
-		be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0);
+	/* Enable multicast promisc if num configured exceeds what we support */
+	if (netdev->flags & IFF_ALLMULTI || netdev->mc_count > BE_MAX_MC) {
+		be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0,
+				&adapter->mc_cmd_mem);
 		goto done;
 	}
 
 	be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
-		netdev->mc_count);
+		netdev->mc_count, &adapter->mc_cmd_mem);
 done:
 	return;
 }
@@ -755,10 +759,10 @@ static void be_rx_compl_process(struct b
 
 	/* vlanf could be wrongly set in some cards.
 	 * ignore if vtm is not set */
-	if ((adapter->cap == 0x400) && !vtm)
+	if ((adapter->cap & 0x400) && !vtm)
 		vlanf = 0;
 
-	skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
+	skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
 	if (!skb) {
 		if (net_ratelimit())
 			dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
@@ -766,8 +770,6 @@ static void be_rx_compl_process(struct b
 		return;
 	}
 
-	skb_reserve(skb, NET_IP_ALIGN);
-
 	skb_fill_rx_data(adapter, skb, rxcp);
 
 	if (do_pkt_csum(rxcp, adapter->rx_csum))
@@ -814,7 +816,7 @@ static void be_rx_compl_process_gro(stru
 
 	/* vlanf could be wrongly set in some cards.
 	 * ignore if vtm is not set */
-	if ((adapter->cap == 0x400) && !vtm)
+	if ((adapter->cap & 0x400) && !vtm)
 		vlanf = 0;
 
 	skb = napi_get_frags(&eq_obj->napi);
@@ -908,7 +910,7 @@ static inline struct page *be_alloc_page
 static void be_post_rx_frags(struct be_adapter *adapter)
 {
 	struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl;
-	struct be_rx_page_info *page_info = NULL;
+	struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
 	struct be_queue_info *rxq = &adapter->rx_obj.q;
 	struct page *pagep = NULL;
 	struct be_eth_rx_d *rxd;
@@ -939,7 +941,6 @@ static void be_post_rx_frags(struct be_a
 		rxd = queue_head_node(rxq);
 		rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF);
 		rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr));
-		queue_head_inc(rxq);
 
 		/* Any space left in the current big page for another frag? */
 		if ((page_offset + rx_frag_size + rx_frag_size) >
@@ -947,10 +948,13 @@ static void be_post_rx_frags(struct be_a
 			pagep = NULL;
 			page_info->last_page_user = true;
 		}
+
+		prev_page_info = page_info;
+		queue_head_inc(rxq);
 		page_info = &page_info_tbl[rxq->head];
 	}
 	if (pagep)
-		page_info->last_page_user = true;
+		prev_page_info->last_page_user = true;
 
 	if (posted) {
 		atomic_add(posted, &rxq->used);
@@ -981,23 +985,41 @@ static struct be_eth_tx_compl *be_tx_com
 static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 {
 	struct be_queue_info *txq = &adapter->tx_obj.q;
+	struct be_eth_wrb *wrb;
 	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 	struct sk_buff *sent_skb;
+	u64 busaddr;
 	u16 cur_index, num_wrbs = 0;
 
 	cur_index = txq->tail;
 	sent_skb = sent_skbs[cur_index];
 	BUG_ON(!sent_skb);
 	sent_skbs[cur_index] = NULL;
+	wrb = queue_tail_node(txq);
+	be_dws_le_to_cpu(wrb, sizeof(*wrb));
+	busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
+	if (busaddr != 0) {
+		pci_unmap_single(adapter->pdev, busaddr,
+				 wrb->frag_len, PCI_DMA_TODEVICE);
+	}
+	num_wrbs++;
+	queue_tail_inc(txq);
 
-	do {
+	while (cur_index != last_index) {
 		cur_index = txq->tail;
+		wrb = queue_tail_node(txq);
+		be_dws_le_to_cpu(wrb, sizeof(*wrb));
+		busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
+		if (busaddr != 0) {
+			pci_unmap_page(adapter->pdev, busaddr,
+				       wrb->frag_len, PCI_DMA_TODEVICE);
+		}
 		num_wrbs++;
 		queue_tail_inc(txq);
-	} while (cur_index != last_index);
+	}
 
 	atomic_sub(num_wrbs, &txq->used);
-	skb_dma_unmap(&adapter->pdev->dev, sent_skb, DMA_TO_DEVICE);
+
 	kfree_skb(sent_skb);
 }
 
@@ -1328,7 +1350,7 @@ static irqreturn_t be_intx(int irq, void
 	int isr;
 
 	isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
-			be_pci_func(adapter) * CEV_ISR_SIZE);
+		(adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE);
 	if (!isr)
 		return IRQ_NONE;
 
@@ -1377,6 +1399,7 @@ int be_poll_rx(struct napi_struct *napi,
 	struct be_eth_rx_compl *rxcp;
 	u32 work_done;
 
+	adapter->stats.drvr_stats.be_rx_polls++;
 	for (work_done = 0; work_done < budget; work_done++) {
 		rxcp = be_rx_compl_get(adapter);
 		if (!rxcp)
@@ -1475,6 +1498,14 @@ static void be_worker(struct work_struct
 	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
 }
 
+static void be_msix_disable(struct be_adapter *adapter)
+{
+	if (adapter->msix_enabled) {
+		pci_disable_msix(adapter->pdev);
+		adapter->msix_enabled = false;
+	}
+}
+
 static void be_msix_enable(struct be_adapter *adapter)
 {
 	int i, status;
@@ -1590,6 +1621,8 @@ static int be_open(struct net_device *ne
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
 	bool link_up;
 	int status;
+	u8 mac_speed;
+	u16 link_speed;
 
 	/* First time posting */
 	be_post_rx_frags(adapter);
@@ -1608,7 +1641,8 @@ static int be_open(struct net_device *ne
 	/* Rx compl queue may be in unarmed state; rearm it */
 	be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
 
-	status = be_cmd_link_status_query(adapter, &link_up);
+	status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
+			&link_speed);
 	if (status)
 		goto ret_sts;
 	be_link_status_update(adapter, link_up);
@@ -1627,6 +1661,44 @@ ret_sts:
 	return status;
 }
 
+static int be_setup_wol(struct be_adapter *adapter, bool enable)
+{
+	struct be_dma_mem cmd;
+	int status = 0;
+	u8 mac[ETH_ALEN];
+
+	memset(mac, 0, ETH_ALEN);
+
+	cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
+	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
+	if (cmd.va == NULL)
+		return -1;
+	memset(cmd.va, 0, cmd.size);
+
+	if (enable) {
+		status = pci_write_config_dword(adapter->pdev,
+			PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
+		if (status) {
+			dev_err(&adapter->pdev->dev,
+				"Could not enable Wake-on-lan \n");
+			pci_free_consistent(adapter->pdev, cmd.size, cmd.va,
+					cmd.dma);
+			return status;
+		}
+		status = be_cmd_enable_magic_wol(adapter,
+				adapter->netdev->dev_addr, &cmd);
+		pci_enable_wake(adapter->pdev, PCI_D3hot, 1);
+		pci_enable_wake(adapter->pdev, PCI_D3cold, 1);
+	} else {
+		status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
+		pci_enable_wake(adapter->pdev, PCI_D3hot, 0);
+		pci_enable_wake(adapter->pdev, PCI_D3cold, 0);
+	}
+
+	pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
+	return status;
+}
+
 static int be_setup(struct be_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
@@ -1658,6 +1730,8 @@ static int be_setup(struct be_adapter *a
 	if (status != 0)
 		goto rx_qs_destroy;
 
+	adapter->link_speed = -1;
+
 	return 0;
 
 rx_qs_destroy:
@@ -1678,6 +1752,8 @@ static int be_clear(struct be_adapter *a
 
 	be_cmd_if_destroy(adapter, adapter->if_handle);
 
+	/* tell fw we're done with firing cmds */
+	be_cmd_fw_clean(adapter);
 	return 0;
 }
 
@@ -1720,6 +1796,31 @@ static int be_close(struct net_device *n
 #define FW_FILE_HDR_SIGN 	"ServerEngines Corp. "
 char flash_cookie[2][16] =	{"*** SE FLAS",
 				"H DIRECTORY *** "};
+
+static bool be_flash_redboot(struct be_adapter *adapter,
+			const u8 *p)
+{
+	u32 crc_offset;
+	u8 flashed_crc[4];
+	int status;
+	crc_offset = FLASH_REDBOOT_START + FLASH_REDBOOT_IMAGE_MAX_SIZE - 4
+			+ sizeof(struct flash_file_hdr) - 32*1024;
+	p += crc_offset;
+	status = be_cmd_get_flash_crc(adapter, flashed_crc);
+	if (status) {
+		dev_err(&adapter->pdev->dev,
+		"could not get crc from flash, not flashing redboot\n");
+		return false;
+	}
+
+	/*update redboot only if crc does not match*/
+	if (!memcmp(flashed_crc, p, 4))
+		return false;
+	else
+		return true;
+
+}
+
 static int be_flash_image(struct be_adapter *adapter,
 			const struct firmware *fw,
 			struct be_dma_mem *flash_cmd, u32 flash_type)
@@ -1759,6 +1860,12 @@ static int be_flash_image(struct be_adap
 		image_offset = FLASH_PXE_BIOS_START;
 		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
 		break;
+	case FLASHROM_TYPE_REDBOOT:
+		if (!be_flash_redboot(adapter, fw->data))
+			return 0;
+		image_offset = FLASH_REDBOOT_ISM_START;
+		image_size = FLASH_REDBOOT_IMAGE_MAX_SIZE;
+		break;
 	default:
 		return 0;
 	}
@@ -1877,7 +1984,7 @@ int be_load_fw(struct be_adapter *adapte
 		goto fw_exit;
 	}
 
-	dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n");
+	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
 
 fw_exit:
 	release_firmware(fw);
@@ -1906,6 +2013,8 @@ static void be_netdev_init(struct net_de
 		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
 		NETIF_F_GRO;
 
+	netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
+
 	netdev->flags |= IFF_MULTICAST;
 
 	adapter->rx_csum = true;
@@ -1942,6 +2051,7 @@ static void be_unmap_pci_bars(struct be_
 static int be_map_pci_bars(struct be_adapter *adapter)
 {
 	u8 __iomem *addr;
+	int pcicfg_reg;
 
 	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
 			pci_resource_len(adapter->pdev, 2));
@@ -1955,8 +2065,13 @@ static int be_map_pci_bars(struct be_ada
 		goto pci_map_err;
 	adapter->db = addr;
 
-	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1),
-			pci_resource_len(adapter->pdev, 1));
+	if (adapter->generation == BE_GEN2)
+		pcicfg_reg = 1;
+	else
+		pcicfg_reg = 0;
+
+	addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg),
+			pci_resource_len(adapter->pdev, pcicfg_reg));
 	if (addr == NULL)
 		goto pci_map_err;
 	adapter->pcicfg = addr;
@@ -1977,34 +2092,61 @@ static void be_ctrl_cleanup(struct be_ad
 	if (mem->va)
 		pci_free_consistent(adapter->pdev, mem->size,
 			mem->va, mem->dma);
+
+	mem = &adapter->mc_cmd_mem;
+	if (mem->va)
+		pci_free_consistent(adapter->pdev, mem->size,
+			mem->va, mem->dma);
 }
 
 static int be_ctrl_init(struct be_adapter *adapter)
 {
 	struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
 	struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
+	struct be_dma_mem *mc_cmd_mem = &adapter->mc_cmd_mem;
 	int status;
 
 	status = be_map_pci_bars(adapter);
 	if (status)
-		return status;
+		goto done;
 
 	mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
 	mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev,
 				mbox_mem_alloc->size, &mbox_mem_alloc->dma);
 	if (!mbox_mem_alloc->va) {
-		be_unmap_pci_bars(adapter);
-		return -1;
+		status = -ENOMEM;
+		goto unmap_pci_bars;
 	}
+
 	mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
 	mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
 	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
 	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
+
+	mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config);
+	mc_cmd_mem->va = pci_alloc_consistent(adapter->pdev, mc_cmd_mem->size,
+			&mc_cmd_mem->dma);
+	if (mc_cmd_mem->va == NULL) {
+		status = -ENOMEM;
+		goto free_mbox;
+	}
+	memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
+
 	spin_lock_init(&adapter->mbox_lock);
 	spin_lock_init(&adapter->mcc_lock);
 	spin_lock_init(&adapter->mcc_cq_lock);
 
 	return 0;
+
+free_mbox:
+	pci_free_consistent(adapter->pdev, mbox_mem_alloc->size,
+		mbox_mem_alloc->va, mbox_mem_alloc->dma);
+
+unmap_pci_bars:
+	be_unmap_pci_bars(adapter);
+
+done:
+	return status;
 }
 
 static void be_stats_cleanup(struct be_adapter *adapter)
@@ -2026,12 +2168,14 @@ static int be_stats_init(struct be_adapt
 	cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
 	if (cmd->va == NULL)
 		return -1;
+	memset(cmd->va, 0, cmd->size);
 	return 0;
 }
 
 static void __devexit be_remove(struct pci_dev *pdev)
 {
 	struct be_adapter *adapter = pci_get_drvdata(pdev);
+
 	if (!adapter)
 		return;
 
@@ -2043,10 +2187,7 @@ static void __devexit be_remove(struct p
 
 	be_ctrl_cleanup(adapter);
 
-	if (adapter->msix_enabled) {
-		pci_disable_msix(adapter->pdev);
-		adapter->msix_enabled = false;
-	}
+	be_msix_disable(adapter);
 
 	pci_set_drvdata(pdev, NULL);
 	pci_release_regions(pdev);
@@ -2055,25 +2196,33 @@ static void __devexit be_remove(struct p
 	free_netdev(adapter->netdev);
 }
 
-static int be_hw_up(struct be_adapter *adapter)
+static int be_get_config(struct be_adapter *adapter)
 {
 	int status;
+	u8 mac[ETH_ALEN];
 
-	status = be_cmd_POST(adapter);
+	status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
 	if (status)
 		return status;
 
-	status = be_cmd_reset_function(adapter);
+	status = be_cmd_query_fw_cfg(adapter,
+				&adapter->port_num, &adapter->cap);
 	if (status)
 		return status;
 
-	status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
+	memset(mac, 0, ETH_ALEN);
+	status = be_cmd_mac_addr_query(adapter, mac,
+			MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
 	if (status)
 		return status;
 
-	status = be_cmd_query_fw_cfg(adapter,
-				&adapter->port_num, &adapter->cap);
-	return status;
+	if (!is_valid_ether_addr(mac))
+		return -EADDRNOTAVAIL;
+
+	memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
+	memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
+
+	return 0;
 }
 
 static int __devinit be_probe(struct pci_dev *pdev,
@@ -2082,7 +2231,6 @@ static int __devinit be_probe(struct pci
 	int status = 0;
 	struct be_adapter *adapter;
 	struct net_device *netdev;
-	u8 mac[ETH_ALEN];
 
 	status = pci_enable_device(pdev);
 	if (status)
@@ -2099,9 +2247,25 @@ static int __devinit be_probe(struct pci
 		goto rel_reg;
 	}
 	adapter = netdev_priv(netdev);
+
+	switch (pdev->device) {
+	case BE_DEVICE_ID1:
+	case OC_DEVICE_ID1:
+		adapter->generation = BE_GEN2;
+		break;
+	case BE_DEVICE_ID2:
+	case OC_DEVICE_ID2:
+		adapter->generation = BE_GEN3;
+		break;
+	default:
+		adapter->generation = 0;
+	}
+
 	adapter->pdev = pdev;
 	pci_set_drvdata(pdev, adapter);
 	adapter->netdev = netdev;
+	be_netdev_init(netdev);
+	SET_NETDEV_DEV(netdev, &pdev->dev);
 
 	be_msix_enable(adapter);
 
@@ -2120,27 +2284,34 @@ static int __devinit be_probe(struct pci
 	if (status)
 		goto free_netdev;
 
-	status = be_stats_init(adapter);
+	/* sync up with fw's ready state */
+	status = be_cmd_POST(adapter);
 	if (status)
 		goto ctrl_clean;
 
-	status = be_hw_up(adapter);
+	/* tell fw we're ready to fire cmds */
+	status = be_cmd_fw_init(adapter);
 	if (status)
-		goto stats_clean;
+		goto ctrl_clean;
 
-	status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK,
-			true /* permanent */, 0);
+	status = be_cmd_reset_function(adapter);
+	if (status)
+		goto ctrl_clean;
+
+	status = be_stats_init(adapter);
+	if (status)
+		goto ctrl_clean;
+
+	status = be_get_config(adapter);
 	if (status)
 		goto stats_clean;
-	memcpy(netdev->dev_addr, mac, ETH_ALEN);
 
 	INIT_DELAYED_WORK(&adapter->work, be_worker);
-	be_netdev_init(netdev);
-	SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
 
 	status = be_setup(adapter);
 	if (status)
 		goto stats_clean;
+
 	status = register_netdev(netdev);
 	if (status != 0)
 		goto unsetup;
@@ -2155,7 +2326,9 @@ stats_clean:
 ctrl_clean:
 	be_ctrl_cleanup(adapter);
 free_netdev:
+	be_msix_disable(adapter);
 	free_netdev(adapter->netdev);
+	pci_set_drvdata(pdev, NULL);
 rel_reg:
 	pci_release_regions(pdev);
 disable_dev:
@@ -2170,6 +2343,9 @@ static int be_suspend(struct pci_dev *pd
 	struct be_adapter *adapter = pci_get_drvdata(pdev);
 	struct net_device *netdev =  adapter->netdev;
 
+	if (adapter->wol)
+		be_setup_wol(adapter, true);
+
 	netif_device_detach(netdev);
 	if (netif_running(netdev)) {
 		rtnl_lock();
@@ -2200,6 +2376,11 @@ static int be_resume(struct pci_dev *pde
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 
+	/* tell fw we're ready to fire cmds */
+	status = be_cmd_fw_init(adapter);
+	if (status)
+		return status;
+
 	be_setup(adapter);
 	if (netif_running(netdev)) {
 		rtnl_lock();
@@ -2207,6 +2388,9 @@ static int be_resume(struct pci_dev *pde
 		rtnl_unlock();
 	}
 	netif_device_attach(netdev);
+
+	if (adapter->wol)
+		be_setup_wol(adapter, false);
 	return 0;
 }
 
@@ -2221,8 +2405,8 @@ static struct pci_driver be_driver = {
 
 static int __init be_init_module(void)
 {
-	if (rx_frag_size != 8192 && rx_frag_size != 4096
-		&& rx_frag_size != 2048) {
+	if (rx_frag_size != 8192 && rx_frag_size != 4096 &&
+	    rx_frag_size != 2048) {
 		printk(KERN_WARNING DRV_NAME
 			" : Module param rx_frag_size must be 2048/4096/8192."
 			" Using 2048\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bfin_mac.c linux-libre-2.6.33-gnu1/drivers/net/bfin_mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/bfin_mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bfin_mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <asm/dma.h>
 #include <linux/dma-mapping.h>
 
+#include <asm/dpmc.h>
 #include <asm/blackfin.h>
 #include <asm/cacheflush.h>
 #include <asm/portmux.h>
@@ -386,8 +387,8 @@ static int mii_probe(struct net_device *
 	u32 sclk, mdc_div;
 
 	/* Enable PHY output early */
-	if (!(bfin_read_VR_CTL() & PHYCLKOE))
-		bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
+	if (!(bfin_read_VR_CTL() & CLKBUFOE))
+		bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
 
 	sclk = get_sclk();
 	mdc_div = ((sclk / MDC_CLK) / 2) - 1;
@@ -554,8 +555,8 @@ static void adjust_tx_list(void)
 {
 	int timeout_cnt = MAX_TIMEOUT_CNT;
 
-	if (tx_list_head->status.status_word != 0
-	    && current_tx_ptr != tx_list_head) {
+	if (tx_list_head->status.status_word != 0 &&
+	    current_tx_ptr != tx_list_head) {
 		goto adjust_head;	/* released something, just return; */
 	}
 
@@ -567,8 +568,8 @@ static void adjust_tx_list(void)
 	if (current_tx_ptr->next->next == tx_list_head) {
 		while (tx_list_head->status.status_word == 0) {
 			udelay(10);
-			if (tx_list_head->status.status_word != 0
-			    || !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
+			if (tx_list_head->status.status_word != 0 ||
+			    !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
 				goto adjust_head;
 			}
 			if (timeout_cnt-- < 0) {
@@ -596,8 +597,8 @@ adjust_head:
 			       ": no sk_buff in a transmitted frame!\n");
 		}
 		tx_list_head = tx_list_head->next;
-	} while (tx_list_head->status.status_word != 0
-		 && current_tx_ptr != tx_list_head);
+	} while (tx_list_head->status.status_word != 0 &&
+		 current_tx_ptr != tx_list_head);
 	return;
 
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bmac.c linux-libre-2.6.33-gnu1/drivers/net/bmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/bmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -438,8 +438,8 @@ bmac_init_phy(struct net_device *dev)
 
 		ctrl = bmac_mif_read(dev, 0);
 		capable = ((bmac_mif_read(dev, 1) & 0xf800) >> 6) | 1;
-		if (bmac_mif_read(dev, 4) != capable
-		    || (ctrl & 0x1000) == 0) {
+		if (bmac_mif_read(dev, 4) != capable ||
+		    (ctrl & 0x1000) == 0) {
 			bmac_mif_write(dev, 4, capable);
 			bmac_mif_write(dev, 0, 0x1200);
 		} else
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2.c linux-libre-2.6.33-gnu1/drivers/net/bnx2.c
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2.c	2013-05-03 13:59:15.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2.c	2013-05-03 12:07:48.000000000 -0400
@@ -59,8 +59,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"2.0.2"
-#define DRV_MODULE_RELDATE	"Aug 21, 2009"
+#define DRV_MODULE_VERSION	"2.0.3"
+#define DRV_MODULE_RELDATE	"Dec 03, 2009"
 #define FW_MIPS_FILE_06		"/*(DEBLOBBED)*/"
 #define FW_RV2P_FILE_06		"/*(DEBLOBBED)*/"
 #define FW_MIPS_FILE_09		"/*(DEBLOBBED)*/"
@@ -649,12 +649,20 @@ static void
 bnx2_netif_stop(struct bnx2 *bp)
 {
 	bnx2_cnic_stop(bp);
-	bnx2_disable_int_sync(bp);
 	if (netif_running(bp->dev)) {
+		int i;
+
 		bnx2_napi_disable(bp);
 		netif_tx_disable(bp->dev);
-		bp->dev->trans_start = jiffies;	/* prevent tx timeout */
+		/* prevent tx timeout */
+		for (i = 0; i <  bp->dev->num_tx_queues; i++) {
+			struct netdev_queue *txq;
+
+			txq = netdev_get_tx_queue(bp->dev, i);
+			txq->trans_start = jiffies;
+		}
 	}
+	bnx2_disable_int_sync(bp);
 }
 
 static void
@@ -1462,6 +1470,8 @@ bnx2_enable_forced_2g5(struct bnx2 *bp)
 	} else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
 		bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
 		bmcr |= BCM5708S_BMCR_FORCE_2500;
+	} else {
+		return;
 	}
 
 	if (bp->autoneg & AUTONEG_SPEED) {
@@ -1496,6 +1506,8 @@ bnx2_disable_forced_2g5(struct bnx2 *bp)
 	} else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
 		bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
 		bmcr &= ~BCM5708S_BMCR_FORCE_2500;
+	} else {
+		return;
 	}
 
 	if (bp->autoneg & AUTONEG_SPEED)
@@ -2807,13 +2819,21 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2
 			}
 		}
 
-		skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
+		pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+			skb_headlen(skb), PCI_DMA_TODEVICE);
 
 		tx_buf->skb = NULL;
 		last = tx_buf->nr_frags;
 
 		for (i = 0; i < last; i++) {
 			sw_cons = NEXT_TX_BD(sw_cons);
+
+			pci_unmap_page(bp->pdev,
+				pci_unmap_addr(
+					&txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
+					mapping),
+				skb_shinfo(skb)->frags[i].size,
+				PCI_DMA_TODEVICE);
 		}
 
 		sw_cons = NEXT_TX_BD(sw_cons);
@@ -5142,8 +5162,12 @@ bnx2_init_rx_ring(struct bnx2 *bp, int r
 
 	ring_prod = prod = rxr->rx_pg_prod;
 	for (i = 0; i < bp->rx_pg_ring_size; i++) {
-		if (bnx2_alloc_rx_page(bp, rxr, ring_prod) < 0)
+		if (bnx2_alloc_rx_page(bp, rxr, ring_prod) < 0) {
+			printk(KERN_WARNING PFX "%s: init'ed rx page ring %d "
+						"with %d/%d pages only\n",
+			       bp->dev->name, ring_num, i, bp->rx_pg_ring_size);
 			break;
+		}
 		prod = NEXT_RX_BD(prod);
 		ring_prod = RX_PG_RING_IDX(prod);
 	}
@@ -5151,8 +5175,12 @@ bnx2_init_rx_ring(struct bnx2 *bp, int r
 
 	ring_prod = prod = rxr->rx_prod;
 	for (i = 0; i < bp->rx_ring_size; i++) {
-		if (bnx2_alloc_rx_skb(bp, rxr, ring_prod) < 0)
+		if (bnx2_alloc_rx_skb(bp, rxr, ring_prod) < 0) {
+			printk(KERN_WARNING PFX "%s: init'ed rx ring %d with "
+						"%d/%d skbs only\n",
+			       bp->dev->name, ring_num, i, bp->rx_ring_size);
 			break;
+		}
 		prod = NEXT_RX_BD(prod);
 		ring_prod = RX_RING_IDX(prod);
 	}
@@ -5287,17 +5315,29 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
 		for (j = 0; j < TX_DESC_CNT; ) {
 			struct sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
 			struct sk_buff *skb = tx_buf->skb;
+			int k, last;
 
 			if (skb == NULL) {
 				j++;
 				continue;
 			}
 
-			skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
+			pci_unmap_single(bp->pdev,
+					 pci_unmap_addr(tx_buf, mapping),
+					 skb_headlen(skb),
+					 PCI_DMA_TODEVICE);
 
 			tx_buf->skb = NULL;
 
-			j += skb_shinfo(skb)->nr_frags + 1;
+			last = tx_buf->nr_frags;
+			j++;
+			for (k = 0; k < last; k++, j++) {
+				tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)];
+				pci_unmap_page(bp->pdev,
+					pci_unmap_addr(tx_buf, mapping),
+					skb_shinfo(skb)->frags[k].size,
+					PCI_DMA_TODEVICE);
+			}
 			dev_kfree_skb(skb);
 		}
 	}
@@ -5676,11 +5716,12 @@ bnx2_run_loopback(struct bnx2 *bp, int l
 	for (i = 14; i < pkt_size; i++)
 		packet[i] = (unsigned char) (i & 0xff);
 
-	if (skb_dma_map(&bp->pdev->dev, skb, DMA_TO_DEVICE)) {
+	map = pci_map_single(bp->pdev, skb->data, pkt_size,
+		PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(bp->pdev, map)) {
 		dev_kfree_skb(skb);
 		return -EIO;
 	}
-	map = skb_shinfo(skb)->dma_head;
 
 	REG_WR(bp, BNX2_HC_COMMAND,
 	       bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
@@ -5715,7 +5756,7 @@ bnx2_run_loopback(struct bnx2 *bp, int l
 
 	udelay(5);
 
-	skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
+	pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
 	dev_kfree_skb(skb);
 
 	if (bnx2_get_hw_tx_cons(tx_napi) != txr->tx_prod)
@@ -6234,8 +6275,11 @@ bnx2_reset_task(struct work_struct *work
 {
 	struct bnx2 *bp = container_of(work, struct bnx2, reset_task);
 
-	if (!netif_running(bp->dev))
+	rtnl_lock();
+	if (!netif_running(bp->dev)) {
+		rtnl_unlock();
 		return;
+	}
 
 	bnx2_netif_stop(bp);
 
@@ -6243,6 +6287,28 @@ bnx2_reset_task(struct work_struct *work
 
 	atomic_set(&bp->intr_sem, 1);
 	bnx2_netif_start(bp);
+	rtnl_unlock();
+}
+
+static void
+bnx2_dump_state(struct bnx2 *bp)
+{
+	struct net_device *dev = bp->dev;
+
+	printk(KERN_ERR PFX "%s DEBUG: intr_sem[%x]\n", dev->name,
+		atomic_read(&bp->intr_sem));
+	printk(KERN_ERR PFX "%s DEBUG: EMAC_TX_STATUS[%08x] "
+			    "RPM_MGMT_PKT_CTRL[%08x]\n", dev->name,
+		REG_RD(bp, BNX2_EMAC_TX_STATUS),
+		REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
+	printk(KERN_ERR PFX "%s DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
+		dev->name, bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P0),
+		bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P1));
+	printk(KERN_ERR PFX "%s DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
+		dev->name, REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
+	if (bp->flags & BNX2_FLAG_USING_MSIX)
+		printk(KERN_ERR PFX "%s DEBUG: PBA[%08x]\n", dev->name,
+			REG_RD(bp, BNX2_PCI_GRC_WINDOW3_BASE));
 }
 
 static void
@@ -6250,6 +6316,8 @@ bnx2_tx_timeout(struct net_device *dev)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
+	bnx2_dump_state(bp);
+
 	/* This allows the netif to be shutdown gracefully before resetting */
 	schedule_work(&bp->reset_task);
 }
@@ -6294,7 +6362,6 @@ bnx2_start_xmit(struct sk_buff *skb, str
 	struct bnx2_napi *bnapi;
 	struct bnx2_tx_ring_info *txr;
 	struct netdev_queue *txq;
-	struct skb_shared_info *sp;
 
 	/*  Determine which tx ring we will be placed on */
 	i = skb_get_queue_mapping(skb);
@@ -6359,16 +6426,15 @@ bnx2_start_xmit(struct sk_buff *skb, str
 	} else
 		mss = 0;
 
-	if (skb_dma_map(&bp->pdev->dev, skb, DMA_TO_DEVICE)) {
+	mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(bp->pdev, mapping)) {
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
-	sp = skb_shinfo(skb);
-	mapping = sp->dma_head;
-
 	tx_buf = &txr->tx_buf_ring[ring_prod];
 	tx_buf->skb = skb;
+	pci_unmap_addr_set(tx_buf, mapping, mapping);
 
 	txbd = &txr->tx_desc_ring[ring_prod];
 
@@ -6389,7 +6455,12 @@ bnx2_start_xmit(struct sk_buff *skb, str
 		txbd = &txr->tx_desc_ring[ring_prod];
 
 		len = frag->size;
-		mapping = sp->dma_maps[i];
+		mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
+			len, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(bp->pdev, mapping))
+			goto dma_error;
+		pci_unmap_addr_set(&txr->tx_buf_ring[ring_prod], mapping,
+				   mapping);
 
 		txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
 		txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -6416,6 +6487,30 @@ bnx2_start_xmit(struct sk_buff *skb, str
 	}
 
 	return NETDEV_TX_OK;
+dma_error:
+	/* save value of frag that failed */
+	last_frag = i;
+
+	/* start back at beginning and unmap skb */
+	prod = txr->tx_prod;
+	ring_prod = TX_RING_IDX(prod);
+	tx_buf = &txr->tx_buf_ring[ring_prod];
+	tx_buf->skb = NULL;
+	pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+			 skb_headlen(skb), PCI_DMA_TODEVICE);
+
+	/* unmap remaining mapped pages */
+	for (i = 0; i < last_frag; i++) {
+		prod = NEXT_TX_BD(prod);
+		ring_prod = TX_RING_IDX(prod);
+		tx_buf = &txr->tx_buf_ring[ring_prod];
+		pci_unmap_page(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+			       skb_shinfo(skb)->frags[i].size,
+			       PCI_DMA_TODEVICE);
+	}
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 /* Called with rtnl_lock */
@@ -7631,6 +7726,86 @@ bnx2_get_pci_speed(struct bnx2 *bp)
 
 }
 
+static void __devinit
+bnx2_read_vpd_fw_ver(struct bnx2 *bp)
+{
+	int rc, i, v0_len = 0;
+	u8 *data;
+	u8 *v0_str = NULL;
+	bool mn_match = false;
+
+#define BNX2_VPD_NVRAM_OFFSET	0x300
+#define BNX2_VPD_LEN		128
+#define BNX2_MAX_VER_SLEN	30
+
+	data = kmalloc(256, GFP_KERNEL);
+	if (!data)
+		return;
+
+	rc = bnx2_nvram_read(bp, BNX2_VPD_NVRAM_OFFSET, data + BNX2_VPD_LEN,
+			     BNX2_VPD_LEN);
+	if (rc)
+		goto vpd_done;
+
+	for (i = 0; i < BNX2_VPD_LEN; i += 4) {
+		data[i] = data[i + BNX2_VPD_LEN + 3];
+		data[i + 1] = data[i + BNX2_VPD_LEN + 2];
+		data[i + 2] = data[i + BNX2_VPD_LEN + 1];
+		data[i + 3] = data[i + BNX2_VPD_LEN];
+	}
+
+	for (i = 0; i <= BNX2_VPD_LEN - 3; ) {
+		unsigned char val = data[i];
+		unsigned int block_end;
+
+		if (val == 0x82 || val == 0x91) {
+			i = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
+			continue;
+		}
+
+		if (val != 0x90)
+			goto vpd_done;
+
+		block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
+		i += 3;
+
+		if (block_end > BNX2_VPD_LEN)
+			goto vpd_done;
+
+		while (i < (block_end - 2)) {
+			int len = data[i + 2];
+
+			if (i + 3 + len > block_end)
+				goto vpd_done;
+
+			if (data[i] == 'M' && data[i + 1] == 'N') {
+				if (len != 4 ||
+				    memcmp(&data[i + 3], "1028", 4))
+					goto vpd_done;
+				mn_match = true;
+
+			} else if (data[i] == 'V' && data[i + 1] == '0') {
+				if (len > BNX2_MAX_VER_SLEN)
+					goto vpd_done;
+
+				v0_len = len;
+				v0_str = &data[i + 3];
+			}
+			i += 3 + len;
+
+			if (mn_match && v0_str) {
+				memcpy(bp->fw_version, v0_str, v0_len);
+				bp->fw_version[v0_len] = ' ';
+				goto vpd_done;
+			}
+		}
+		goto vpd_done;
+	}
+
+vpd_done:
+	kfree(data);
+}
+
 static int __devinit
 bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 {
@@ -7804,10 +7979,18 @@ bnx2_init_board(struct pci_dev *pdev, st
 		goto err_out_unmap;
 	}
 
+	bnx2_read_vpd_fw_ver(bp);
+
+	j = strlen(bp->fw_version);
 	reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_BC_REV);
-	for (i = 0, j = 0; i < 3; i++) {
+	for (i = 0; i < 3 && j < 24; i++) {
 		u8 num, k, skip0;
 
+		if (i == 0) {
+			bp->fw_version[j++] = 'b';
+			bp->fw_version[j++] = 'c';
+			bp->fw_version[j++] = ' ';
+		}
 		num = (u8) (reg >> (24 - (i * 8)));
 		for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
 			if (num >= k || !skip0 || k == 1) {
@@ -7838,8 +8021,9 @@ bnx2_init_board(struct pci_dev *pdev, st
 	    reg != BNX2_CONDITION_MFW_RUN_NONE) {
 		u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
 
-		bp->fw_version[j++] = ' ';
-		for (i = 0; i < 3; i++) {
+		if (j < 32)
+			bp->fw_version[j++] = ' ';
+		for (i = 0; i < 3 && j < 28; i++) {
 			reg = bnx2_reg_rd_ind(bp, addr + i * 4);
 			reg = swab32(reg);
 			memcpy(&bp->fw_version[j], &reg, 4);
@@ -8260,6 +8444,7 @@ static pci_ers_result_t bnx2_io_slot_res
 	}
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
+	pci_save_state(pdev);
 
 	if (netif_running(dev)) {
 		bnx2_set_power_state(bp, PCI_D0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2.h linux-libre-2.6.33-gnu1/drivers/net/bnx2.h
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2.h	2010-02-24 13:52:17.000000000 -0500
@@ -6345,6 +6345,8 @@ struct l2_fhdr {
 
 #define BNX2_MCP_ROM					0x00150000
 #define BNX2_MCP_SCRATCH				0x00160000
+#define BNX2_MCP_STATE_P1				 0x0016f9c8
+#define BNX2_MCP_STATE_P0				 0x0016fdc8
 
 #define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
 #define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
@@ -6559,6 +6561,7 @@ struct sw_pg {
 
 struct sw_tx_bd {
 	struct sk_buff		*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
 	unsigned short		is_gso;
 	unsigned short		nr_frags;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x.h linux-libre-2.6.33-gnu1/drivers/net/bnx2x.h
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,10 @@
 #define BCM_VLAN			1
 #endif
 
+#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
+#define BCM_CNIC 1
+#include "cnic_if.h"
+#endif
 
 #define BNX2X_MULTI_QUEUE
 
@@ -255,9 +259,6 @@ struct bnx2x_eth_q_stats {
 struct bnx2x_fastpath {
 
 	struct napi_struct	napi;
-
-	u8			is_rx_queue;
-
 	struct host_status_block *status_blk;
 	dma_addr_t		status_blk_mapping;
 
@@ -762,7 +763,11 @@ struct bnx2x_eth_stats {
 			(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
 
 
+#ifdef BCM_CNIC
+#define MAX_CONTEXT			15
+#else
 #define MAX_CONTEXT			16
+#endif
 
 union cdu_context {
 	struct eth_context eth;
@@ -811,13 +816,21 @@ struct bnx2x {
 	struct bnx2x_fastpath	fp[MAX_CONTEXT];
 	void __iomem		*regview;
 	void __iomem		*doorbells;
+#ifdef BCM_CNIC
+#define BNX2X_DB_SIZE		(18*BCM_PAGE_SIZE)
+#else
 #define BNX2X_DB_SIZE		(16*BCM_PAGE_SIZE)
+#endif
 
 	struct net_device	*dev;
 	struct pci_dev		*pdev;
 
 	atomic_t		intr_sem;
+#ifdef BCM_CNIC
+	struct msix_entry	msix_table[MAX_CONTEXT+2];
+#else
 	struct msix_entry	msix_table[MAX_CONTEXT+1];
+#endif
 #define INT_MODE_INTx			1
 #define INT_MODE_MSI			2
 #define INT_MODE_MSIX			3
@@ -863,8 +876,8 @@ struct bnx2x {
 
 	/* Flags for marking that there is a STAT_QUERY or
 	   SET_MAC ramrod pending */
-	u8			stats_pending;
-	u8			set_mac_pending;
+	int			stats_pending;
+	int			set_mac_pending;
 
 	/* End of fields used in the performance code paths */
 
@@ -884,6 +897,7 @@ struct bnx2x {
 #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
 #define HW_VLAN_TX_FLAG			0x400
 #define HW_VLAN_RX_FLAG			0x800
+#define MF_FUNC_DIS			0x1000
 
 	int			func;
 #define BP_PORT(bp)			(bp->func % PORT_MAX)
@@ -891,6 +905,11 @@ struct bnx2x {
 #define BP_E1HVN(bp)			(bp->func >> 1)
 #define BP_L_ID(bp)			(BP_E1HVN(bp) << 2)
 
+#ifdef BCM_CNIC
+#define BCM_CNIC_CID_START		16
+#define BCM_ISCSI_ETH_CL_ID		17
+#endif
+
 	int			pm_cap;
 	int			pcie_cap;
 	int			mrrs;
@@ -944,13 +963,11 @@ struct bnx2x {
 #define BNX2X_STATE_CLOSING_WAIT4_HALT	0x4000
 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
 #define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
-#define BNX2X_STATE_DISABLED		0xd000
 #define BNX2X_STATE_DIAG		0xe000
 #define BNX2X_STATE_ERROR		0xf000
 
 	int			multi_mode;
-	int			num_rx_queues;
-	int			num_tx_queues;
+	int			num_queues;
 
 	u32			rx_mode;
 #define BNX2X_RX_MODE_NONE		0
@@ -960,28 +977,51 @@ struct bnx2x {
 #define BNX2X_MAX_MULTICAST		64
 #define BNX2X_MAX_EMUL_MULTI		16
 
+	u32 			rx_mode_cl_mask;
+
 	dma_addr_t		def_status_blk_mapping;
 
 	struct bnx2x_slowpath	*slowpath;
 	dma_addr_t		slowpath_mapping;
 
-#ifdef BCM_ISCSI
-	void    		*t1;
-	dma_addr_t      	t1_mapping;
-	void    		*t2;
-	dma_addr_t      	t2_mapping;
-	void    		*timers;
-	dma_addr_t      	timers_mapping;
-	void    		*qm;
-	dma_addr_t      	qm_mapping;
-#endif
-
 	int			dropless_fc;
 
+#ifdef BCM_CNIC
+	u32			cnic_flags;
+#define BNX2X_CNIC_FLAG_MAC_SET		1
+
+	void			*t1;
+	dma_addr_t		t1_mapping;
+	void			*t2;
+	dma_addr_t		t2_mapping;
+	void			*timers;
+	dma_addr_t		timers_mapping;
+	void			*qm;
+	dma_addr_t		qm_mapping;
+	struct cnic_ops		*cnic_ops;
+	void			*cnic_data;
+	u32			cnic_tag;
+	struct cnic_eth_dev	cnic_eth_dev;
+	struct host_status_block *cnic_sb;
+	dma_addr_t		cnic_sb_mapping;
+#define CNIC_SB_ID(bp)			BP_L_ID(bp)
+	struct eth_spe		*cnic_kwq;
+	struct eth_spe		*cnic_kwq_prod;
+	struct eth_spe		*cnic_kwq_cons;
+	struct eth_spe		*cnic_kwq_last;
+	u16			cnic_kwq_pending;
+	u16			cnic_spq_pending;
+	struct mutex		cnic_mutex;
+	u8			iscsi_mac[6];
+#endif
+
 	int			dmae_ready;
 	/* used to synchronize dmae accesses */
 	struct mutex		dmae_mutex;
 
+	/* used to protect the FW mail box */
+	struct mutex		fw_mb_mutex;
+
 	/* used to synchronize stats collecting */
 	int			stats_state;
 	/* used by dmae command loader */
@@ -1030,20 +1070,15 @@ struct bnx2x {
 };
 
 
-#define BNX2X_MAX_QUEUES(bp)	(IS_E1HMF(bp) ? (MAX_CONTEXT/(2 * E1HVN_MAX)) \
-					      : (MAX_CONTEXT/2))
-#define BNX2X_NUM_QUEUES(bp)	(bp->num_rx_queues + bp->num_tx_queues)
-#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 2)
+#define BNX2X_MAX_QUEUES(bp)	(IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \
+					      : MAX_CONTEXT)
+#define BNX2X_NUM_QUEUES(bp)	(bp->num_queues)
+#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 1)
 
-#define for_each_rx_queue(bp, var) \
-			for (var = 0; var < bp->num_rx_queues; var++)
-#define for_each_tx_queue(bp, var) \
-			for (var = bp->num_rx_queues; \
-			     var < BNX2X_NUM_QUEUES(bp); var++)
 #define for_each_queue(bp, var) \
 			for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
 #define for_each_nondefault_queue(bp, var) \
-			for (var = 1; var < bp->num_rx_queues; var++)
+			for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
 
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
@@ -1147,7 +1182,7 @@ static inline u32 reg_poll(struct bnx2x
 #define MAX_SP_DESC_CNT			(SP_DESC_CNT - 1)
 
 
-#define BNX2X_BTR			3
+#define BNX2X_BTR			1
 #define MAX_SPQ_PENDING			8
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x_hsi.h linux-libre-2.6.33-gnu1/drivers/net/bnx2x_hsi.h
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 13:59:25.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 12:07:57.000000000 -0400
@@ -7,6 +7,20 @@
  * the Free Software Foundation.
  */
 
+struct license_key {
+	u32 reserved[6];
+
+#if defined(__BIG_ENDIAN)
+	u16 max_iscsi_init_conn;
+	u16 max_iscsi_trgt_conn;
+#elif defined(__LITTLE_ENDIAN)
+	u16 max_iscsi_trgt_conn;
+	u16 max_iscsi_init_conn;
+#endif
+
+	u32 reserved_a[6];
+};
+
 
 #define PORT_0				0
 #define PORT_1				1
@@ -250,6 +264,7 @@ struct port_hw_cfg {			    /* port 0: 0x
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101	    0x00000800
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727	    0x00000900
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC   0x00000a00
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823	    0x00000b00
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE	    0x0000fd00
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN	    0x0000ff00
 
@@ -881,7 +896,7 @@ struct shmem_region {			       /*   Shar
 
 	struct shm_dev_info	dev_info;		 /* 0x8     (0x438) */
 
-	u8			reserved[52*PORT_MAX];
+	struct license_key	drv_lic_key[PORT_MAX];	/* 0x440 (52*2=0x68) */
 
 	/* FW information (for internal FW use) */
 	u32			fw_info_fio_offset;    /* 0x4a8       (0x4) */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x_link.c linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.c
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x_link.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.c	2010-02-24 13:52:17.000000000 -0500
@@ -1107,18 +1107,21 @@ static void bnx2x_set_parallel_detection
 			      MDIO_REG_BANK_SERDES_DIGITAL,
 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
 			      &control2);
-
-
-	control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
-
-
+	if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
+	else
+		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
+	DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
+		params->speed_cap_mask, control2);
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_SERDES_DIGITAL,
 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
 			      control2);
 
-	if (phy_flags & PHY_XGXS_FLAG) {
+	if ((phy_flags & PHY_XGXS_FLAG) &&
+	     (params->speed_cap_mask &
+		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
 		DP(NETIF_MSG_LINK, "XGXS\n");
 
 		CL45_WR_OVER_CL22(bp, params->port,
@@ -1225,7 +1228,7 @@ static void bnx2x_set_autoneg(struct lin
 				      params->phy_addr,
 				      MDIO_REG_BANK_CL73_USERB0,
 				    MDIO_CL73_USERB0_CL73_UCTRL,
-				    MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL);
+				      0xe);
 
 		/* Enable BAM Station Manager*/
 		CL45_WR_OVER_CL22(bp, params->port,
@@ -1236,29 +1239,25 @@ static void bnx2x_set_autoneg(struct lin
 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
 
-		/* Merge CL73 and CL37 aneg resolution */
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_CL73_USERB0,
-				      MDIO_CL73_USERB0_CL73_BAM_CTRL3,
-				      &reg_val);
-
-		if (params->speed_cap_mask &
-		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
-			/* Set the CL73 AN speed */
+		/* Advertise CL73 link speeds */
 			CL45_RD_OVER_CL22(bp, params->port,
 					      params->phy_addr,
 					      MDIO_REG_BANK_CL73_IEEEB1,
 					      MDIO_CL73_IEEEB1_AN_ADV2,
 					      &reg_val);
+		if (params->speed_cap_mask &
+		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
+		if (params->speed_cap_mask &
+		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
 
 			CL45_WR_OVER_CL22(bp, params->port,
 					      params->phy_addr,
 					      MDIO_REG_BANK_CL73_IEEEB1,
 					      MDIO_CL73_IEEEB1_AN_ADV2,
-			  reg_val | MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4);
+				      reg_val);
 
-		}
 		/* CL73 Autoneg Enabled */
 		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
 
@@ -1351,6 +1350,7 @@ static void bnx2x_set_brcm_cl37_advertis
 
 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
 {
+	struct bnx2x *bp = params->bp;
 	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
 	/* resolve pause mode and advertisement
 	 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
@@ -1380,18 +1380,30 @@ static void bnx2x_calc_ieee_aneg_adv(str
 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
 		break;
 	}
+	DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
 }
 
 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
 					   u16 ieee_fc)
 {
 	struct bnx2x *bp = params->bp;
+	u16 val;
 	/* for AN, we are always publishing full duplex */
 
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_COMBO_IEEE0,
 			      MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_CL73_IEEEB1,
+			      MDIO_CL73_IEEEB1_AN_ADV1, &val);
+	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
+	val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
+	CL45_WR_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_CL73_IEEEB1,
+			      MDIO_CL73_IEEEB1_AN_ADV1, val);
 }
 
 static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
@@ -1609,6 +1621,39 @@ static u8 bnx2x_ext_phy_resolve_fc(struc
 	return ret;
 }
 
+static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u16 pd_10g, status2_1000x;
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_SERDES_DIGITAL,
+			      MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
+			      &status2_1000x);
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_SERDES_DIGITAL,
+			      MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
+			      &status2_1000x);
+	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
+		DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
+			 params->port);
+		return 1;
+	}
+
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_10G_PARALLEL_DETECT,
+			      MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
+			      &pd_10g);
+
+	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
+		DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
+			 params->port);
+		return 1;
+	}
+	return 0;
+}
 
 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
 				  struct link_vars *vars,
@@ -1627,21 +1672,53 @@ static void bnx2x_flow_ctrl_resolve(stru
 	    (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
 	    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 	     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_COMBO_IEEE0,
-				      MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
-				      &ld_pause);
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-			MDIO_REG_BANK_COMBO_IEEE0,
-			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
-			&lp_pause);
-		pause_result = (ld_pause &
+		if (bnx2x_direct_parallel_detect_used(params)) {
+			vars->flow_ctrl = params->req_fc_auto_adv;
+			return;
+		}
+		if ((gp_status &
+		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
+		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
+		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
+		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
+
+			CL45_RD_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      MDIO_REG_BANK_CL73_IEEEB1,
+					      MDIO_CL73_IEEEB1_AN_ADV1,
+					      &ld_pause);
+			CL45_RD_OVER_CL22(bp, params->port,
+					     params->phy_addr,
+					     MDIO_REG_BANK_CL73_IEEEB1,
+					     MDIO_CL73_IEEEB1_AN_LP_ADV1,
+					     &lp_pause);
+			pause_result = (ld_pause &
+					MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
+					>> 8;
+			pause_result |= (lp_pause &
+					MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
+					>> 10;
+			DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
+				 pause_result);
+		} else {
+
+			CL45_RD_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      MDIO_REG_BANK_COMBO_IEEE0,
+					      MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
+					      &ld_pause);
+			CL45_RD_OVER_CL22(bp, params->port,
+			       params->phy_addr,
+			       MDIO_REG_BANK_COMBO_IEEE0,
+			       MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
+			       &lp_pause);
+			pause_result = (ld_pause &
 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
-		pause_result |= (lp_pause &
+			pause_result |= (lp_pause &
 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
-		DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+			DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
+				 pause_result);
+		}
 		bnx2x_pause_resolve(vars, pause_result);
 	} else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
 		   (bnx2x_ext_phy_resolve_fc(params, vars))) {
@@ -1853,6 +1930,8 @@ static u8 bnx2x_link_settings_status(str
 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
+		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
 			vars->autoneg = AUTO_NEG_ENABLED;
 
@@ -1987,8 +2066,7 @@ static u8 bnx2x_emac_program(struct link
 		    GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
 		    mode);
 
-	bnx2x_set_led(bp, params->port, LED_MODE_OPER,
-		    line_speed, params->hw_led_mode, params->chip_id);
+	bnx2x_set_led(params, LED_MODE_OPER, line_speed);
 	return 0;
 }
 
@@ -2122,6 +2200,8 @@ static void bnx2x_ext_phy_reset(struct l
 				       MDIO_PMA_REG_CTRL,
 				       1<<15);
 			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
+			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
 			DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
 			break;
@@ -2512,16 +2592,11 @@ static void bnx2x_bcm8726_external_rom_b
 	/* Need to wait 100ms after reset */
 	msleep(100);
 
-	/* Set serial boot control for external load */
-	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
-		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
-
 	/* Micro controller re-boot */
 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
-		       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+		       0x018B);
 
 	/* Set soft reset */
 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
@@ -2529,14 +2604,10 @@ static void bnx2x_bcm8726_external_rom_b
 		       MDIO_PMA_REG_GEN_CTRL,
 		       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
 
-	/* Set PLL register value to be same like in P13 ver */
 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_PLL_CTRL,
-		       0x73A0);
+		       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
 
-	/* Clear soft reset.
-	Will automatically reset micro-controller re-boot */
 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
@@ -3462,8 +3533,8 @@ static void bnx2x_8481_set_10G_led_mode(
 		       MDIO_PMA_REG_8481_LINK_SIGNAL,
 		       &val1);
 	/* Set bit 2 to 0, and bits [1:0] to 10 */
-	val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
-	val1 |= (1<<1); /* Set bit 1 */
+	val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/
+	val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
 
 	bnx2x_cl45_write(bp, params->port,
 		       ext_phy_type,
@@ -3497,36 +3568,19 @@ static void bnx2x_8481_set_10G_led_mode(
 		       MDIO_PMA_REG_8481_LED2_MASK,
 		       0);
 
-	/* LED3 (10G/1G/100/10G Activity) */
-	bnx2x_cl45_read(bp, params->port,
-		      ext_phy_type,
-		      ext_phy_addr,
-		      MDIO_PMA_DEVAD,
-		      MDIO_PMA_REG_8481_LINK_SIGNAL,
-		      &val1);
-	/* Enable blink based on source 4(Activity) */
-	val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
-	val1 |= (1<<6); /* Set only bit 6 */
+	/* Unmask LED3 for 10G link */
 	bnx2x_cl45_write(bp, params->port,
 		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_8481_LINK_SIGNAL,
-		       val1);
-
-	bnx2x_cl45_read(bp, params->port,
-		      ext_phy_type,
-		      ext_phy_addr,
-		      MDIO_PMA_DEVAD,
 		      MDIO_PMA_REG_8481_LED3_MASK,
-		      &val1);
-	val1 |= (1<<4); /* Unmask LED3 for 10G link */
+		       0x6);
 	bnx2x_cl45_write(bp, params->port,
 		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_8481_LED3_MASK,
-		       val1);
+		       MDIO_PMA_REG_8481_LED3_BLINK,
+		       0);
 }
 
 
@@ -3544,7 +3598,10 @@ static void bnx2x_init_internal_phy(stru
 			bnx2x_set_preemphasis(params);
 
 		/* forced speed requested? */
-		if (vars->line_speed != SPEED_AUTO_NEG) {
+		if (vars->line_speed != SPEED_AUTO_NEG ||
+		    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+			  params->loopback_mode == LOOPBACK_EXT)) {
 			DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
 
 			/* disable autoneg */
@@ -3693,19 +3750,6 @@ static u8 bnx2x_ext_phy_init(struct link
 				}
 			}
 			/* Force speed */
-			/* First enable LASI */
-			bnx2x_cl45_write(bp, params->port,
-				       ext_phy_type,
-				       ext_phy_addr,
-				       MDIO_PMA_DEVAD,
-				       MDIO_PMA_REG_RX_ALARM_CTRL,
-				       0x0400);
-			bnx2x_cl45_write(bp, params->port,
-				       ext_phy_type,
-				       ext_phy_addr,
-				       MDIO_PMA_DEVAD,
-				       MDIO_PMA_REG_LASI_CTRL, 0x0004);
-
 			if (params->req_line_speed == SPEED_10000) {
 				DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
 
@@ -3715,6 +3759,9 @@ static u8 bnx2x_ext_phy_init(struct link
 					       MDIO_PMA_DEVAD,
 					       MDIO_PMA_REG_DIGITAL_CTRL,
 					       0x400);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_LASI_CTRL, 1);
 			} else {
 				/* Force 1Gbps using autoneg with 1G
 				advertisment */
@@ -3756,6 +3803,17 @@ static u8 bnx2x_ext_phy_init(struct link
 					       MDIO_AN_DEVAD,
 					       MDIO_AN_REG_CTRL,
 					       0x1200);
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_RX_ALARM_CTRL,
+					       0x0400);
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_LASI_CTRL, 0x0004);
 
 			}
 			bnx2x_save_bcm_spirom_ver(bp, params->port,
@@ -4291,6 +4349,7 @@ static u8 bnx2x_ext_phy_init(struct link
 			break;
 		}
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
 			/* This phy uses the NIG latch mechanism since link
 				indication arrives through its LED4 and not via
 				its LASI signal, so we get steady signal
@@ -4298,6 +4357,12 @@ static u8 bnx2x_ext_phy_init(struct link
 			bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
 				    1 << NIG_LATCH_BC_ENABLE_MI_INT);
 
+			bnx2x_cl45_write(bp, params->port,
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_CTRL, 0x0000);
+
 			bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
 			if (params->req_line_speed == SPEED_AUTO_NEG) {
 
@@ -4394,17 +4459,12 @@ static u8 bnx2x_ext_phy_init(struct link
 				    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
 					DP(NETIF_MSG_LINK, "Advertising 10G\n");
 					/* Restart autoneg for 10G*/
-			bnx2x_cl45_read(bp, params->port,
-				      ext_phy_type,
-				      ext_phy_addr,
-				      MDIO_AN_DEVAD,
-				      MDIO_AN_REG_CTRL, &val);
-			val |= 0x200;
+
 			bnx2x_cl45_write(bp, params->port,
 				       ext_phy_type,
 				       ext_phy_addr,
 				       MDIO_AN_DEVAD,
-				       MDIO_AN_REG_CTRL, val);
+				       MDIO_AN_REG_CTRL, 0x3200);
 				}
 			} else {
 				/* Force speed */
@@ -4657,8 +4717,8 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 				      0xc809, &val1);
 
 			DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
-			ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
-					   && ((val1 & (1<<8)) == 0));
+			ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) &&
+					   ((val1 & (1<<8)) == 0));
 			if (ext_phy_link_up)
 				vars->line_speed = SPEED_10000;
 			break;
@@ -5148,6 +5208,7 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 			}
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
 			/* Check 10G-BaseT link status */
 			/* Check PMD signal ok */
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
@@ -5363,8 +5424,10 @@ static void bnx2x_link_int_ack(struct li
 		     (NIG_STATUS_XGXS0_LINK10G |
 		      NIG_STATUS_XGXS0_LINK_STATUS |
 		      NIG_STATUS_SERDES0_LINK_STATUS));
-	if (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
-	    == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) {
+	if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
+		== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
+	(XGXS_EXT_PHY_TYPE(params->ext_phy_config)
+		== PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
 		bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
 	}
 	if (vars->phy_link_up) {
@@ -5477,6 +5540,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct l
 		status = bnx2x_format_ver(spirom_ver, version, len);
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
 		spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
 			(spirom_ver & 0x7F);
 		status = bnx2x_format_ver(spirom_ver, version, len);
@@ -5728,13 +5792,15 @@ u8 bnx2x_override_led_value(struct bnx2x
 }
 
 
-u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
-	       u16 hw_led_mode, u32 chip_id)
+u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
 {
+	u8 port = params->port;
+	u16 hw_led_mode = params->hw_led_mode;
 	u8 rc = 0;
 	u32 tmp;
 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+	struct bnx2x *bp = params->bp;
 	DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
 	DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
 		 speed, hw_led_mode);
@@ -5749,7 +5815,14 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 po
 		break;
 
 	case LED_MODE_OPER:
-		REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
+		if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
+			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
+			REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+		} else {
+			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+				   hw_led_mode);
+		}
+
 		REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
 			   port*4, 0);
 		/* Set blinking rate to ~15.9Hz */
@@ -5761,7 +5834,7 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 po
 		EMAC_WR(bp, EMAC_REG_EMAC_LED,
 			    (tmp & (~EMAC_LED_OVERRIDE)));
 
-		if (!CHIP_IS_E1H(bp) &&
+		if (CHIP_IS_E1(bp) &&
 		    ((speed == SPEED_2500) ||
 		     (speed == SPEED_1000) ||
 		     (speed == SPEED_100) ||
@@ -5864,6 +5937,7 @@ static u8 bnx2x_link_initialize(struct l
 
 	if (non_ext_phy ||
 	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
 	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
 	    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
 		if (params->req_line_speed == SPEED_AUTO_NEG)
@@ -6030,10 +6104,7 @@ u8 bnx2x_phy_init(struct link_params *pa
 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
 			    params->port*4, 0);
 
-		bnx2x_set_led(bp, params->port, LED_MODE_OPER,
-			    vars->line_speed, params->hw_led_mode,
-			    params->chip_id);
-
+		bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
 	} else
 	/* No loopback */
 	{
@@ -6091,15 +6162,13 @@ u8 bnx2x_link_reset(struct link_params *
 {
 	struct bnx2x *bp = params->bp;
 	u32 ext_phy_config = params->ext_phy_config;
-	u16 hw_led_mode = params->hw_led_mode;
-	u32 chip_id = params->chip_id;
 	u8 port = params->port;
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
 	u32 val = REG_RD(bp, params->shmem_base +
 			     offsetof(struct shmem_region, dev_info.
 				      port_feature_config[params->port].
 				      config));
-
+	DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
 	/* disable attentions */
 	vars->link_status = 0;
 	bnx2x_update_mng(params, vars->link_status);
@@ -6127,7 +6196,7 @@ u8 bnx2x_link_reset(struct link_params *
 	 * Hold it as vars low
 	 */
 	 /* clear link led */
-	bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
+	bnx2x_set_led(params, LED_MODE_OFF, 0);
 	if (reset_ext_phy) {
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
@@ -6163,6 +6232,22 @@ u8 bnx2x_link_reset(struct link_params *
 			bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
 			break;
 		}
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
+		{
+			u8 ext_phy_addr =
+				XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+			bnx2x_cl45_write(bp, port,
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+				       ext_phy_addr,
+				       MDIO_AN_DEVAD,
+				       MDIO_AN_REG_CTRL, 0x0000);
+			bnx2x_cl45_write(bp, port,
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_CTRL, 1);
+			break;
+		}
 		default:
 			/* HW reset */
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
@@ -6198,9 +6283,7 @@ static u8 bnx2x_update_link_down(struct
 	u8 port = params->port;
 
 	DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
-	bnx2x_set_led(bp, port, LED_MODE_OFF,
-		    0, params->hw_led_mode,
-		    params->chip_id);
+	bnx2x_set_led(params, LED_MODE_OFF, 0);
 
 	/* indicate no mac active */
 	vars->mac_type = MAC_TYPE_NONE;
@@ -6237,15 +6320,13 @@ static u8 bnx2x_update_link_up(struct li
 	vars->link_status |= LINK_STATUS_LINK_UP;
 	if (link_10g) {
 		bnx2x_bmac_enable(params, vars, 0);
-		bnx2x_set_led(bp, port, LED_MODE_OPER,
-			    SPEED_10000, params->hw_led_mode,
-			    params->chip_id);
-
+		bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
 	} else {
-		bnx2x_emac_enable(params, vars, 0);
 		rc = bnx2x_emac_program(params, vars->line_speed,
 				      vars->duplex);
 
+		bnx2x_emac_enable(params, vars, 0);
+
 		/* AN complete? */
 		if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
 			if (!(vars->phy_flags &
@@ -6343,6 +6424,7 @@ u8 bnx2x_link_update(struct link_params
 
 	if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
 	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
+	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
 	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
 	    (ext_phy_link_up && !vars->phy_link_up))
 		bnx2x_init_internal_phy(params, vars, 0);
@@ -6578,6 +6660,13 @@ static u8 bnx2x_8726_common_init_phy(str
 	return 0;
 }
 
+
+static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+{
+	/* HW reset */
+	bnx2x_ext_phy_hw_reset(bp, 1);
+	return 0;
+}
 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 {
 	u8 rc = 0;
@@ -6607,7 +6696,9 @@ u8 bnx2x_common_init_phy(struct bnx2x *b
 		/* GPIO1 affects both ports, so there's need to pull
 		it for single port alone */
 		rc = bnx2x_8726_common_init_phy(bp, shmem_base);
-
+		break;
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
+		rc = bnx2x_84823_common_init_phy(bp, shmem_base);
 		break;
 	default:
 		DP(NETIF_MSG_LINK,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x_link.h linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.h
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x_link.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x_link.h	2010-02-24 13:52:17.000000000 -0500
@@ -178,8 +178,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct l
    Basically, the CLC takes care of the led for the link, but in case one needs
    to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to
    blink the led, and LED_MODE_OFF to set the led off.*/
-u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
-	       u16 hw_led_mode, u32 chip_id);
+u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed);
 #define LED_MODE_OFF	0
 #define LED_MODE_OPER 	2
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x_main.c linux-libre-2.6.33-gnu1/drivers/net/bnx2x_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x_main.c	2013-05-03 13:59:22.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x_main.c	2013-05-03 12:07:54.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/prefetch.h>
 #include <linux/zlib.h>
 #include <linux/io.h>
+#include <linux/stringify.h>
 
 
 #include "bnx2x.h"
@@ -59,15 +60,16 @@
   return (printk(KERN_ERR PFX "%s: Missing Free firmware\n", bp->dev->name),\
 	  -EINVAL)
 
-#define DRV_MODULE_VERSION	"1.52.1"
-#define DRV_MODULE_RELDATE	"2009/08/12"
+#define DRV_MODULE_VERSION	"1.52.1-5"
+#define DRV_MODULE_RELDATE	"2009/11/09"
 #define BNX2X_BC_VER		0x040200
 
 #include <linux/firmware.h>
 #include "bnx2x_fw_file_hdr.h"
 /* FW files */
-#define FW_FILE_PREFIX_E1	"/*(DEBLOBBED)*/"
-#define FW_FILE_PREFIX_E1H	"/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
+#define FW_FILE_NAME_E1		"/*(DEBLOBBED)*/"
+#define FW_FILE_NAME_E1H	"/*(DEBLOBBED)*/"
 
 /* Time in jiffies before concluding the transmitter is hung */
 #define TX_TIMEOUT		(5*HZ)
@@ -80,21 +82,17 @@ MODULE_AUTHOR("Eliezer Tamir");
 MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
+/*(DEBLOBBED)*/
 
 static int multi_mode = 1;
 module_param(multi_mode, int, 0);
 MODULE_PARM_DESC(multi_mode, " Multi queue mode "
 			     "(0 Disable; 1 Enable (default))");
 
-static int num_rx_queues;
-module_param(num_rx_queues, int, 0);
-MODULE_PARM_DESC(num_rx_queues, " Number of Rx queues for multi_mode=1"
-				" (default is half number of CPUs)");
-
-static int num_tx_queues;
-module_param(num_tx_queues, int, 0);
-MODULE_PARM_DESC(num_tx_queues, " Number of Tx queues for multi_mode=1"
-				" (default is half number of CPUs)");
+static int num_queues;
+module_param(num_queues, int, 0);
+MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1"
+				" (default is as a number of CPUs)");
 
 static int disable_tpa;
 module_param(disable_tpa, int, 0);
@@ -553,7 +551,7 @@ static void bnx2x_panic_dump(struct bnx2
 		  bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
 
 	/* Rx */
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		BNX2X_ERR("fp%d: rx_bd_prod(%x)  rx_bd_cons(%x)"
@@ -570,7 +568,7 @@ static void bnx2x_panic_dump(struct bnx2
 	}
 
 	/* Tx */
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		BNX2X_ERR("fp%d: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
@@ -585,7 +583,7 @@ static void bnx2x_panic_dump(struct bnx2
 
 	/* Rings */
 	/* Rx */
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
@@ -619,7 +617,7 @@ static void bnx2x_panic_dump(struct bnx2
 	}
 
 	/* Tx */
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
@@ -745,6 +743,9 @@ static void bnx2x_int_disable_sync(struc
 	if (msix) {
 		synchronize_irq(bp->msix_table[0].vector);
 		offset = 1;
+#ifdef BCM_CNIC
+		offset++;
+#endif
 		for_each_queue(bp, i)
 			synchronize_irq(bp->msix_table[i + offset].vector);
 	} else
@@ -784,21 +785,13 @@ static inline void bnx2x_ack_sb(struct b
 	barrier();
 }
 
-static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
+static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
 {
 	struct host_status_block *fpsb = fp->status_blk;
-	u16 rc = 0;
 
 	barrier(); /* status block is written to by the chip */
-	if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) {
-		fp->fp_c_idx = fpsb->c_status_block.status_block_index;
-		rc |= 1;
-	}
-	if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) {
-		fp->fp_u_idx = fpsb->u_status_block.status_block_index;
-		rc |= 2;
-	}
-	return rc;
+	fp->fp_c_idx = fpsb->c_status_block.status_block_index;
+	fp->fp_u_idx = fpsb->u_status_block.status_block_index;
 }
 
 static u16 bnx2x_ack_int(struct bnx2x *bp)
@@ -838,6 +831,9 @@ static u16 bnx2x_free_tx_pkt(struct bnx2
 	u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
 	int nbd;
 
+	/* prefetch skb end pointer to speedup dev_kfree_skb() */
+	prefetch(&skb->end);
+
 	DP(BNX2X_MSG_OFF, "pkt_idx %d  buff @(%p)->skb %p\n",
 	   idx, tx_buf, skb);
 
@@ -882,7 +878,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2
 
 	/* release skb */
 	WARN_ON(!skb);
-	dev_kfree_skb_any(skb);
+	dev_kfree_skb(skb);
 	tx_buf->first_bd = 0;
 	tx_buf->skb = NULL;
 
@@ -912,19 +908,28 @@ static inline u16 bnx2x_tx_avail(struct
 	return (s16)(fp->bp->tx_ring_size) - used;
 }
 
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
+static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+	u16 hw_cons;
+
+	/* Tell compiler that status block fields can change */
+	barrier();
+	hw_cons = le16_to_cpu(*fp->tx_cons_sb);
+	return hw_cons != fp->tx_pkt_cons;
+}
+
+static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
 {
 	struct bnx2x *bp = fp->bp;
 	struct netdev_queue *txq;
 	u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
-	int done = 0;
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
-		return;
+		return -1;
 #endif
 
-	txq = netdev_get_tx_queue(bp->dev, fp->index - bp->num_rx_queues);
+	txq = netdev_get_tx_queue(bp->dev, fp->index);
 	hw_cons = le16_to_cpu(*fp->tx_cons_sb);
 	sw_cons = fp->tx_pkt_cons;
 
@@ -945,7 +950,6 @@ static void bnx2x_tx_int(struct bnx2x_fa
 */
 		bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
 		sw_cons++;
-		done++;
 	}
 
 	fp->tx_pkt_cons = sw_cons;
@@ -967,8 +971,12 @@ static void bnx2x_tx_int(struct bnx2x_fa
 		    (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
 			netif_tx_wake_queue(txq);
 	}
+	return 0;
 }
 
+#ifdef BCM_CNIC
+static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid);
+#endif
 
 static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
 			   union eth_rx_cqe *rr_cqe)
@@ -1025,16 +1033,24 @@ static void bnx2x_sp_event(struct bnx2x_
 		bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
 		break;
 
+#ifdef BCM_CNIC
+	case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN):
+		DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid);
+		bnx2x_cnic_cfc_comp(bp, cid);
+		break;
+#endif
 
 	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
 	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
 		DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
-		bp->set_mac_pending = 0;
+		bp->set_mac_pending--;
+		smp_wmb();
 		break;
 
 	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
-	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DISABLED):
 		DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
+		bp->set_mac_pending--;
+		smp_wmb();
 		break;
 
 	default:
@@ -1542,6 +1558,8 @@ static int bnx2x_rx_int(struct bnx2x_fas
 		} else {
 			rx_buf = &fp->rx_buf_ring[bd_cons];
 			skb = rx_buf->skb;
+			prefetch(skb);
+			prefetch((u8 *)skb + 256);
 			len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
 			pad = cqe->fast_path_cqe.placement_offset;
 
@@ -1723,27 +1741,13 @@ static irqreturn_t bnx2x_msix_fp_int(int
 	if (unlikely(bp->panic))
 		return IRQ_HANDLED;
 #endif
-	/* Handle Rx or Tx according to MSI-X vector */
-	if (fp->is_rx_queue) {
-		prefetch(fp->rx_cons_sb);
-		prefetch(&fp->status_blk->u_status_block.status_block_index);
-
-		napi_schedule(&bnx2x_fp(bp, fp->index, napi));
 
-	} else {
-		prefetch(fp->tx_cons_sb);
-		prefetch(&fp->status_blk->c_status_block.status_block_index);
-
-		bnx2x_update_fpsb_idx(fp);
-		rmb();
-		bnx2x_tx_int(fp);
-
-		/* Re-enable interrupts */
-		bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
-			     le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
-		bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
-			     le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
-	}
+	/* Handle Rx and Tx according to MSI-X vector */
+	prefetch(fp->rx_cons_sb);
+	prefetch(fp->tx_cons_sb);
+	prefetch(&fp->status_blk->u_status_block.status_block_index);
+	prefetch(&fp->status_blk->c_status_block.status_block_index);
+	napi_schedule(&bnx2x_fp(bp, fp->index, napi));
 
 	return IRQ_HANDLED;
 }
@@ -1778,35 +1782,32 @@ static irqreturn_t bnx2x_interrupt(int i
 
 		mask = 0x2 << fp->sb_id;
 		if (status & mask) {
-			/* Handle Rx or Tx according to SB id */
-			if (fp->is_rx_queue) {
-				prefetch(fp->rx_cons_sb);
-				prefetch(&fp->status_blk->u_status_block.
-							status_block_index);
-
-				napi_schedule(&bnx2x_fp(bp, fp->index, napi));
-
-			} else {
-				prefetch(fp->tx_cons_sb);
-				prefetch(&fp->status_blk->c_status_block.
-							status_block_index);
-
-				bnx2x_update_fpsb_idx(fp);
-				rmb();
-				bnx2x_tx_int(fp);
-
-				/* Re-enable interrupts */
-				bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
-					     le16_to_cpu(fp->fp_u_idx),
-					     IGU_INT_NOP, 1);
-				bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
-					     le16_to_cpu(fp->fp_c_idx),
-					     IGU_INT_ENABLE, 1);
-			}
+			/* Handle Rx and Tx according to SB id */
+			prefetch(fp->rx_cons_sb);
+			prefetch(&fp->status_blk->u_status_block.
+						status_block_index);
+			prefetch(fp->tx_cons_sb);
+			prefetch(&fp->status_blk->c_status_block.
+						status_block_index);
+			napi_schedule(&bnx2x_fp(bp, fp->index, napi));
 			status &= ~mask;
 		}
 	}
 
+#ifdef BCM_CNIC
+	mask = 0x2 << CNIC_SB_ID(bp);
+	if (status & (mask | 0x1)) {
+		struct cnic_ops *c_ops = NULL;
+
+		rcu_read_lock();
+		c_ops = rcu_dereference(bp->cnic_ops);
+		if (c_ops)
+			c_ops->cnic_handler(bp->cnic_data, NULL);
+		rcu_read_unlock();
+
+		status &= ~mask;
+	}
+#endif
 
 	if (unlikely(status & 0x1)) {
 		queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
@@ -2131,18 +2132,30 @@ static void bnx2x_calc_fc_adv(struct bnx
 
 static void bnx2x_link_report(struct bnx2x *bp)
 {
-	if (bp->state == BNX2X_STATE_DISABLED) {
+	if (bp->flags & MF_FUNC_DIS) {
 		netif_carrier_off(bp->dev);
 		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
 		return;
 	}
 
 	if (bp->link_vars.link_up) {
+		u16 line_speed;
+
 		if (bp->state == BNX2X_STATE_OPEN)
 			netif_carrier_on(bp->dev);
 		printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
 
-		printk("%d Mbps ", bp->link_vars.line_speed);
+		line_speed = bp->link_vars.line_speed;
+		if (IS_E1HMF(bp)) {
+			u16 vn_max_rate;
+
+			vn_max_rate =
+				((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+				 FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
+			if (vn_max_rate < line_speed)
+				line_speed = vn_max_rate;
+		}
+		printk("%d Mbps ", line_speed);
 
 		if (bp->link_vars.duplex == DUPLEX_FULL)
 			printk("full duplex");
@@ -2307,8 +2320,14 @@ static void bnx2x_calc_vn_weight_sum(str
 	}
 
 	/* ... only if all min rates are zeros - disable fairness */
-	if (all_zero)
-		bp->vn_weight_sum = 0;
+	if (all_zero) {
+		bp->cmng.flags.cmng_enables &=
+					~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
+		DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+		   "  fairness will be disabled\n");
+	} else
+		bp->cmng.flags.cmng_enables |=
+					CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
 }
 
 static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
@@ -2327,17 +2346,14 @@ static void bnx2x_init_vn_minmax(struct
 	} else {
 		vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
 				FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
-		/* If fairness is enabled (not all min rates are zeroes) and
-		   if current min rate is zero - set it to 1.
-		   This is a requirement of the algorithm. */
-		if (bp->vn_weight_sum && (vn_min_rate == 0))
+		/* If min rate is zero - set it to 1 */
+		if (!vn_min_rate)
 			vn_min_rate = DEF_MIN_RATE;
 		vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
 				FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
 	}
-
 	DP(NETIF_MSG_IFUP,
-	   "func %d: vn_min_rate=%d  vn_max_rate=%d  vn_weight_sum=%d\n",
+	   "func %d: vn_min_rate %d  vn_max_rate %d  vn_weight_sum %d\n",
 	   func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
 
 	memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
@@ -2408,8 +2424,7 @@ static void bnx2x_link_attn(struct bnx2x
 			memset(&(pstats->mac_stx[0]), 0,
 			       sizeof(struct mac_stx));
 		}
-		if ((bp->state == BNX2X_STATE_OPEN) ||
-		    (bp->state == BNX2X_STATE_DISABLED))
+		if (bp->state == BNX2X_STATE_OPEN)
 			bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
 	}
 
@@ -2452,9 +2467,7 @@ static void bnx2x_link_attn(struct bnx2x
 
 static void bnx2x__link_status_update(struct bnx2x *bp)
 {
-	int func = BP_FUNC(bp);
-
-	if (bp->state != BNX2X_STATE_OPEN)
+	if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
 		return;
 
 	bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2464,7 +2477,6 @@ static void bnx2x__link_status_update(st
 	else
 		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
-	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 	bnx2x_calc_vn_weight_sum(bp);
 
 	/* indicate link status */
@@ -2504,6 +2516,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u
 	u32 cnt = 1;
 	u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
 
+	mutex_lock(&bp->fw_mb_mutex);
 	SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
 	DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
 
@@ -2513,8 +2526,8 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u
 
 		rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
 
-		/* Give the FW up to 2 second (200*10ms) */
-	} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
+		/* Give the FW up to 5 second (500*10ms) */
+	} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500));
 
 	DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
 	   cnt*delay, rc, seq);
@@ -2528,32 +2541,23 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u
 		bnx2x_fw_dump(bp);
 		rc = 0;
 	}
+	mutex_unlock(&bp->fw_mb_mutex);
 
 	return rc;
 }
 
 static void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
-static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set);
+static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set);
 static void bnx2x_set_rx_mode(struct net_device *dev);
 
 static void bnx2x_e1h_disable(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
-	int i;
-
-	bp->rx_mode = BNX2X_RX_MODE_NONE;
-	bnx2x_set_storm_rx_mode(bp);
 
 	netif_tx_disable(bp->dev);
-	bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 
 	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
 
-	bnx2x_set_mac_addr_e1h(bp, 0);
-
-	for (i = 0; i < MC_HASH_SIZE; i++)
-		REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
-
 	netif_carrier_off(bp->dev);
 }
 
@@ -2563,13 +2567,13 @@ static void bnx2x_e1h_enable(struct bnx2
 
 	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
 
-	bnx2x_set_mac_addr_e1h(bp, 1);
-
 	/* Tx queue should be only reenabled */
 	netif_tx_wake_all_queues(bp->dev);
 
-	/* Initialize the receive filter. */
-	bnx2x_set_rx_mode(bp->dev);
+	/*
+	 * Should not call netif_carrier_on since it will be called if the link
+	 * is up when checking for link state
+	 */
 }
 
 static void bnx2x_update_min_max(struct bnx2x *bp)
@@ -2608,21 +2612,23 @@ static void bnx2x_update_min_max(struct
 
 static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
 {
-	int func = BP_FUNC(bp);
-
 	DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
-	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 
 	if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
 
+		/*
+		 * This is the only place besides the function initialization
+		 * where the bp->flags can change so it is done without any
+		 * locks
+		 */
 		if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
 			DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n");
-			bp->state = BNX2X_STATE_DISABLED;
+			bp->flags |= MF_FUNC_DIS;
 
 			bnx2x_e1h_disable(bp);
 		} else {
 			DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n");
-			bp->state = BNX2X_STATE_OPEN;
+			bp->flags &= ~MF_FUNC_DIS;
 
 			bnx2x_e1h_enable(bp);
 		}
@@ -2641,11 +2647,40 @@ static void bnx2x_dcc_event(struct bnx2x
 		bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
 }
 
+/* must be called under the spq lock */
+static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp)
+{
+	struct eth_spe *next_spe = bp->spq_prod_bd;
+
+	if (bp->spq_prod_bd == bp->spq_last_bd) {
+		bp->spq_prod_bd = bp->spq;
+		bp->spq_prod_idx = 0;
+		DP(NETIF_MSG_TIMER, "end of spq\n");
+	} else {
+		bp->spq_prod_bd++;
+		bp->spq_prod_idx++;
+	}
+	return next_spe;
+}
+
+/* must be called under the spq lock */
+static inline void bnx2x_sp_prod_update(struct bnx2x *bp)
+{
+	int func = BP_FUNC(bp);
+
+	/* Make sure that BD data is updated before writing the producer */
+	wmb();
+
+	REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
+	       bp->spq_prod_idx);
+	mmiowb();
+}
+
 /* the slow path queue is odd since completions arrive on the fastpath ring */
 static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 			 u32 data_hi, u32 data_lo, int common)
 {
-	int func = BP_FUNC(bp);
+	struct eth_spe *spe;
 
 	DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
 	   "SPQE (%x:%x)  command %d  hw_cid %x  data (%x:%x)  left %x\n",
@@ -2667,38 +2702,23 @@ static int bnx2x_sp_post(struct bnx2x *b
 		return -EBUSY;
 	}
 
+	spe = bnx2x_sp_get_next(bp);
+
 	/* CID needs port number to be encoded int it */
-	bp->spq_prod_bd->hdr.conn_and_cmd_data =
+	spe->hdr.conn_and_cmd_data =
 			cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
 				     HW_CID(bp, cid)));
-	bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
+	spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
 	if (common)
-		bp->spq_prod_bd->hdr.type |=
+		spe->hdr.type |=
 			cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
 
-	bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
-	bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
+	spe->data.mac_config_addr.hi = cpu_to_le32(data_hi);
+	spe->data.mac_config_addr.lo = cpu_to_le32(data_lo);
 
 	bp->spq_left--;
 
-	if (bp->spq_prod_bd == bp->spq_last_bd) {
-		bp->spq_prod_bd = bp->spq;
-		bp->spq_prod_idx = 0;
-		DP(NETIF_MSG_TIMER, "end of spq\n");
-
-	} else {
-		bp->spq_prod_bd++;
-		bp->spq_prod_idx++;
-	}
-
-	/* Make sure that BD data is updated before writing the producer */
-	wmb();
-
-	REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
-	       bp->spq_prod_idx);
-
-	mmiowb();
-
+	bnx2x_sp_prod_update(bp);
 	spin_unlock_bh(&bp->spq_lock);
 	return 0;
 }
@@ -3027,6 +3047,8 @@ static inline void bnx2x_attn_int_deasse
 			int func = BP_FUNC(bp);
 
 			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+			bp->mf_config = SHMEM_RD(bp,
+					   mf_cfg.func_mf_config[func].config);
 			val = SHMEM_RD(bp, func_mb[func].drv_status);
 			if (val & DRV_STATUS_DCC_EVENT_MASK)
 				bnx2x_dcc_event(bp,
@@ -3230,6 +3252,17 @@ static irqreturn_t bnx2x_msix_sp_int(int
 		return IRQ_HANDLED;
 #endif
 
+#ifdef BCM_CNIC
+	{
+		struct cnic_ops *c_ops;
+
+		rcu_read_lock();
+		c_ops = rcu_dereference(bp->cnic_ops);
+		if (c_ops)
+			c_ops->cnic_handler(bp->cnic_data, NULL);
+		rcu_read_unlock();
+	}
+#endif
 	queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
 
 	return IRQ_HANDLED;
@@ -3961,7 +3994,7 @@ static int bnx2x_storm_stats_update(stru
 	estats->no_buff_discard_hi = 0;
 	estats->no_buff_discard_lo = 0;
 
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		int cl_id = fp->cl_id;
 		struct tstorm_per_client_stats *tclient =
@@ -4178,7 +4211,7 @@ static void bnx2x_net_stats_update(struc
 	nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
 
 	nstats->rx_dropped = estats->mac_discard;
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		nstats->rx_dropped +=
 			le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
 
@@ -4232,7 +4265,7 @@ static void bnx2x_drv_stats_update(struc
 	estats->rx_err_discard_pkt = 0;
 	estats->rx_skb_alloc_failed = 0;
 	estats->hw_csum_err = 0;
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
 
 		estats->driver_xoff += qstats->driver_xoff;
@@ -4263,7 +4296,7 @@ static void bnx2x_stats_update(struct bn
 
 	if (bp->msglevel & NETIF_MSG_TIMER) {
 		struct bnx2x_fastpath *fp0_rx = bp->fp;
-		struct bnx2x_fastpath *fp0_tx = &(bp->fp[bp->num_rx_queues]);
+		struct bnx2x_fastpath *fp0_tx = bp->fp;
 		struct tstorm_per_client_stats *old_tclient =
 							&bp->fp->old_tclient;
 		struct bnx2x_eth_q_stats *qstats = &bp->fp->eth_q_stats;
@@ -4643,8 +4676,7 @@ static void bnx2x_timer(unsigned long da
 		}
 	}
 
-	if ((bp->state == BNX2X_STATE_OPEN) ||
-	    (bp->state == BNX2X_STATE_DISABLED))
+	if (bp->state == BNX2X_STATE_OPEN)
 		bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
 
 timer_restart:
@@ -4863,21 +4895,21 @@ static void bnx2x_update_coalesce(struct
 		REG_WR8(bp, BAR_CSTRORM_INTMEM +
 			CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id,
 						      U_SB_ETH_RX_CQ_INDEX),
-			bp->rx_ticks/12);
+			bp->rx_ticks/(4 * BNX2X_BTR));
 		REG_WR16(bp, BAR_CSTRORM_INTMEM +
 			 CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id,
 						       U_SB_ETH_RX_CQ_INDEX),
-			 (bp->rx_ticks/12) ? 0 : 1);
+			 (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1);
 
 		/* HC_INDEX_C_ETH_TX_CQ_CONS */
 		REG_WR8(bp, BAR_CSTRORM_INTMEM +
 			CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id,
 						      C_SB_ETH_TX_CQ_INDEX),
-			bp->tx_ticks/12);
+			bp->tx_ticks/(4 * BNX2X_BTR));
 		REG_WR16(bp, BAR_CSTRORM_INTMEM +
 			 CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id,
 						       C_SB_ETH_TX_CQ_INDEX),
-			 (bp->tx_ticks/12) ? 0 : 1);
+			 (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1);
 	}
 }
 
@@ -4919,7 +4951,7 @@ static void bnx2x_init_rx_rings(struct b
 
 	if (bp->flags & TPA_ENABLE_FLAG) {
 
-		for_each_rx_queue(bp, j) {
+		for_each_queue(bp, j) {
 			struct bnx2x_fastpath *fp = &bp->fp[j];
 
 			for (i = 0; i < max_agg_queues; i++) {
@@ -4942,16 +4974,13 @@ static void bnx2x_init_rx_rings(struct b
 		}
 	}
 
-	for_each_rx_queue(bp, j) {
+	for_each_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		fp->rx_bd_cons = 0;
 		fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
 		fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX;
 
-		/* Mark queue as Rx */
-		fp->is_rx_queue = 1;
-
 		/* "next page" elements initialization */
 		/* SGE ring */
 		for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
@@ -5057,7 +5086,7 @@ static void bnx2x_init_tx_ring(struct bn
 {
 	int i, j;
 
-	for_each_tx_queue(bp, j) {
+	for_each_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -5083,10 +5112,6 @@ static void bnx2x_init_tx_ring(struct bn
 		fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
 		fp->tx_pkt = 0;
 	}
-
-	/* clean tx statistics */
-	for_each_rx_queue(bp, i)
-		bnx2x_fp(bp, i, tx_pkt) = 0;
 }
 
 static void bnx2x_init_sp_ring(struct bnx2x *bp)
@@ -5115,7 +5140,8 @@ static void bnx2x_init_context(struct bn
 {
 	int i;
 
-	for_each_rx_queue(bp, i) {
+	/* Rx */
+	for_each_queue(bp, i) {
 		struct eth_context *context = bnx2x_sp(bp, context[i].eth);
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		u8 cl_id = fp->cl_id;
@@ -5167,10 +5193,11 @@ static void bnx2x_init_context(struct bn
 					       ETH_CONNECTION_TYPE);
 	}
 
-	for_each_tx_queue(bp, i) {
+	/* Tx */
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		struct eth_context *context =
-			bnx2x_sp(bp, context[i - bp->num_rx_queues].eth);
+			bnx2x_sp(bp, context[i].eth);
 
 		context->cstorm_st_context.sb_index_number =
 						C_SB_ETH_TX_CQ_INDEX;
@@ -5198,7 +5225,7 @@ static void bnx2x_init_ind_table(struct
 	for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
 		REG_WR8(bp, BAR_TSTRORM_INTMEM +
 			TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
-			bp->fp->cl_id + (i % bp->num_rx_queues));
+			bp->fp->cl_id + (i % bp->num_queues));
 }
 
 static void bnx2x_set_client_config(struct bnx2x *bp)
@@ -5238,7 +5265,7 @@ static void bnx2x_set_storm_rx_mode(stru
 {
 	struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
 	int mode = bp->rx_mode;
-	int mask = (1 << BP_L_ID(bp));
+	int mask = bp->rx_mode_cl_mask;
 	int func = BP_FUNC(bp);
 	int port = BP_PORT(bp);
 	int i;
@@ -5351,6 +5378,7 @@ static void bnx2x_init_internal_func(str
 	       (*(u32 *)&tstorm_config));
 
 	bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
+	bp->rx_mode_cl_mask = (1 << BP_L_ID(bp));
 	bnx2x_set_storm_rx_mode(bp);
 
 	for_each_queue(bp, i) {
@@ -5441,7 +5469,7 @@ static void bnx2x_init_internal_func(str
 		min((u32)(min((u32)8, (u32)MAX_SKB_FRAGS) *
 			  SGE_PAGE_SIZE * PAGES_PER_SGE),
 		    (u32)0xffff);
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		REG_WR(bp, BAR_USTRORM_INTMEM +
@@ -5476,7 +5504,7 @@ static void bnx2x_init_internal_func(str
 		rx_pause.cqe_thr_high = 350;
 		rx_pause.sge_thr_high = 0;
 
-		for_each_rx_queue(bp, i) {
+		for_each_queue(bp, i) {
 			struct bnx2x_fastpath *fp = &bp->fp[i];
 
 			if (!fp->disable_tpa) {
@@ -5507,20 +5535,18 @@ static void bnx2x_init_internal_func(str
 		bp->link_vars.line_speed = SPEED_10000;
 		bnx2x_init_port_minmax(bp);
 
+		if (!BP_NOMCP(bp))
+			bp->mf_config =
+			      SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 		bnx2x_calc_vn_weight_sum(bp);
 
 		for (vn = VN_0; vn < E1HVN_MAX; vn++)
 			bnx2x_init_vn_minmax(bp, 2*vn + port);
 
 		/* Enable rate shaping and fairness */
-		bp->cmng.flags.cmng_enables =
+		bp->cmng.flags.cmng_enables |=
 					CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
-		if (bp->vn_weight_sum)
-			bp->cmng.flags.cmng_enables |=
-					CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
-		else
-			DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
-			   "  fairness will be disabled\n");
+
 	} else {
 		/* rate shaping and fairness are disabled */
 		DP(NETIF_MSG_IFUP,
@@ -5568,10 +5594,11 @@ static void bnx2x_nic_init(struct bnx2x
 		fp->state = BNX2X_FP_STATE_CLOSED;
 		fp->index = i;
 		fp->cl_id = BP_L_ID(bp) + i;
+#ifdef BCM_CNIC
+		fp->sb_id = fp->cl_id + 1;
+#else
 		fp->sb_id = fp->cl_id;
-		/* Suitable Rx and Tx SBs are served by the same client */
-		if (i >= bp->num_rx_queues)
-			fp->cl_id -= bp->num_rx_queues;
+#endif
 		DP(NETIF_MSG_IFUP,
 		   "queue[%d]:  bnx2x_init_sb(%p,%p)  cl_id %d  sb %d\n",
 		   i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
@@ -5870,7 +5897,7 @@ static int bnx2x_int_mem_test(struct bnx
 	msleep(50);
 	bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
 	bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
-#ifndef BCM_ISCSI
+#ifndef BCM_CNIC
 	/* set NIC mode */
 	REG_WR(bp, PRS_REG_NIC_MODE, 1);
 #endif
@@ -6009,6 +6036,9 @@ static void bnx2x_setup_fan_failure_dete
 static int bnx2x_init_common(struct bnx2x *bp)
 {
 	u32 val, i;
+#ifdef BCM_CNIC
+	u32 wb_write[2];
+#endif
 
 	DP(BNX2X_MSG_MCP, "starting common init  func %d\n", BP_FUNC(bp));
 
@@ -6051,7 +6081,7 @@ static int bnx2x_init_common(struct bnx2
 #endif
 
 	REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2);
-#ifdef BCM_ISCSI
+#ifdef BCM_CNIC
 	REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
 	REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
 	REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
@@ -6094,11 +6124,26 @@ static int bnx2x_init_common(struct bnx2
 	bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
 
 	bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
+
+#ifdef BCM_CNIC
+	wb_write[0] = 0;
+	wb_write[1] = 0;
+	for (i = 0; i < 64; i++) {
+		REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16));
+		bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2);
+
+		if (CHIP_IS_E1H(bp)) {
+			REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16));
+			bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
+					  wb_write, 2);
+		}
+	}
+#endif
 	/* soft reset pulse */
 	REG_WR(bp, QM_REG_SOFT_RESET, 1);
 	REG_WR(bp, QM_REG_SOFT_RESET, 0);
 
-#ifdef BCM_ISCSI
+#ifdef BCM_CNIC
 	bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
 #endif
 
@@ -6112,8 +6157,10 @@ static int bnx2x_init_common(struct bnx2
 	bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
 	bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
 	REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
+#ifndef BCM_CNIC
 	/* set NIC mode */
 	REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif
 	if (CHIP_IS_E1H(bp))
 		REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
 
@@ -6148,6 +6195,18 @@ static int bnx2x_init_common(struct bnx2
 		/* TODO: replace with something meaningful */
 	}
 	bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
+#ifdef BCM_CNIC
+	REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672);
+	REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc);
+	REG_WR(bp, SRC_REG_KEYSEARCH_2, 0x223aef9b);
+	REG_WR(bp, SRC_REG_KEYSEARCH_3, 0x26001e3a);
+	REG_WR(bp, SRC_REG_KEYSEARCH_4, 0x7ae91116);
+	REG_WR(bp, SRC_REG_KEYSEARCH_5, 0x5ce5230b);
+	REG_WR(bp, SRC_REG_KEYSEARCH_6, 0x298d8adf);
+	REG_WR(bp, SRC_REG_KEYSEARCH_7, 0x6eb0ff09);
+	REG_WR(bp, SRC_REG_KEYSEARCH_8, 0x1830f82f);
+	REG_WR(bp, SRC_REG_KEYSEARCH_9, 0x01e46be7);
+#endif
 	REG_WR(bp, SRC_REG_SOFT_RST, 0);
 
 	if (sizeof(union cdu_context) != 1024)
@@ -6264,38 +6323,14 @@ static int bnx2x_init_port(struct bnx2x
 	bnx2x_init_block(bp, TCM_BLOCK, init_stage);
 	bnx2x_init_block(bp, UCM_BLOCK, init_stage);
 	bnx2x_init_block(bp, CCM_BLOCK, init_stage);
-#ifdef BCM_ISCSI
-	/* Port0  1
-	 * Port1  385 */
-	i++;
-	wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping);
-	wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping);
-	REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
-	REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
-
-	/* Port0  2
-	 * Port1  386 */
-	i++;
-	wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping);
-	wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping);
-	REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
-	REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
-
-	/* Port0  3
-	 * Port1  387 */
-	i++;
-	wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping);
-	wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping);
-	REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
-	REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
-#endif
 	bnx2x_init_block(bp, XCM_BLOCK, init_stage);
 
-#ifdef BCM_ISCSI
-	REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
-	REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
+#ifdef BCM_CNIC
+	REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1);
 
 	bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
+	REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20);
+	REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31);
 #endif
 	bnx2x_init_block(bp, DQ_BLOCK, init_stage);
 
@@ -6353,18 +6388,8 @@ static int bnx2x_init_port(struct bnx2x
 	msleep(5);
 	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0);
 
-#ifdef BCM_ISCSI
-	/* tell the searcher where the T2 table is */
-	REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64);
-
-	wb_write[0] = U64_LO(bp->t2_mapping);
-	wb_write[1] = U64_HI(bp->t2_mapping);
-	REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2);
-	wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64);
-	wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64);
-	REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
-
-	REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
+#ifdef BCM_CNIC
+	bnx2x_init_block(bp, SRCH_BLOCK, init_stage);
 #endif
 	bnx2x_init_block(bp, CDU_BLOCK, init_stage);
 	bnx2x_init_block(bp, CFC_BLOCK, init_stage);
@@ -6473,7 +6498,12 @@ static int bnx2x_init_port(struct bnx2x
 #define PXP_ONE_ILT(x)		(((x) << 10) | x)
 #define PXP_ILT_RANGE(f, l)	(((l) << 10) | f)
 
+#ifdef BCM_CNIC
+#define CNIC_ILT_LINES		127
+#define CNIC_CTX_PER_ILT	16
+#else
 #define CNIC_ILT_LINES		0
+#endif
 
 static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr)
 {
@@ -6512,6 +6542,46 @@ static int bnx2x_init_func(struct bnx2x
 		REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4,
 		       PXP_ILT_RANGE(i, i + CNIC_ILT_LINES));
 
+#ifdef BCM_CNIC
+	i += 1 + CNIC_ILT_LINES;
+	bnx2x_ilt_wr(bp, i, bp->timers_mapping);
+	if (CHIP_IS_E1(bp))
+		REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
+	else {
+		REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i);
+		REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i);
+	}
+
+	i++;
+	bnx2x_ilt_wr(bp, i, bp->qm_mapping);
+	if (CHIP_IS_E1(bp))
+		REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
+	else {
+		REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i);
+		REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i);
+	}
+
+	i++;
+	bnx2x_ilt_wr(bp, i, bp->t1_mapping);
+	if (CHIP_IS_E1(bp))
+		REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
+	else {
+		REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i);
+		REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i);
+	}
+
+	/* tell the searcher where the T2 table is */
+	REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64);
+
+	bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16,
+		    U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping));
+
+	bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16,
+		    U64_LO((u64)bp->t2_mapping + 16*1024 - 64),
+		    U64_HI((u64)bp->t2_mapping + 16*1024 - 64));
+
+	REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10);
+#endif
 
 	if (CHIP_IS_E1H(bp)) {
 		bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
@@ -6596,6 +6666,9 @@ static int bnx2x_init_hw(struct bnx2x *b
 	bnx2x_zero_def_sb(bp);
 	for_each_queue(bp, i)
 		bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
+#ifdef BCM_CNIC
+	bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
+#endif
 
 init_hw_err:
 	bnx2x_gunzip_end(bp);
@@ -6635,7 +6708,7 @@ static void bnx2x_free_mem(struct bnx2x
 			       sizeof(struct host_status_block));
 	}
 	/* Rx */
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 
 		/* fastpath rx rings: rx_buf rx_desc rx_comp */
 		BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
@@ -6655,7 +6728,7 @@ static void bnx2x_free_mem(struct bnx2x
 			       BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
 	}
 	/* Tx */
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 
 		/* fastpath tx rings: tx_buf tx_desc */
 		BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
@@ -6671,11 +6744,13 @@ static void bnx2x_free_mem(struct bnx2x
 	BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
 		       sizeof(struct bnx2x_slowpath));
 
-#ifdef BCM_ISCSI
+#ifdef BCM_CNIC
 	BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
 	BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
 	BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
 	BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
+	BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping,
+		       sizeof(struct host_status_block));
 #endif
 	BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE);
 
@@ -6715,7 +6790,7 @@ static int bnx2x_alloc_mem(struct bnx2x
 				sizeof(struct host_status_block));
 	}
 	/* Rx */
-	for_each_rx_queue(bp, i) {
+	for_each_queue(bp, i) {
 
 		/* fastpath rx rings: rx_buf rx_desc rx_comp */
 		BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
@@ -6737,7 +6812,7 @@ static int bnx2x_alloc_mem(struct bnx2x
 				BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
 	}
 	/* Tx */
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 
 		/* fastpath tx rings: tx_buf tx_desc */
 		BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
@@ -6754,32 +6829,26 @@ static int bnx2x_alloc_mem(struct bnx2x
 	BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
 			sizeof(struct bnx2x_slowpath));
 
-#ifdef BCM_ISCSI
+#ifdef BCM_CNIC
 	BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
 
-	/* Initialize T1 */
-	for (i = 0; i < 64*1024; i += 64) {
-		*(u64 *)((char *)bp->t1 + i + 56) = 0x0UL;
-		*(u64 *)((char *)bp->t1 + i + 3) = 0x0UL;
-	}
-
 	/* allocate searcher T2 table
 	   we allocate 1/4 of alloc num for T2
 	  (which is not entered into the ILT) */
 	BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
 
-	/* Initialize T2 */
+	/* Initialize T2 (for 1024 connections) */
 	for (i = 0; i < 16*1024; i += 64)
-		* (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
-
-	/* now fixup the last line in the block to point to the next block */
-	*(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
+		*(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
 
-	/* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
+	/* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */
 	BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
 
 	/* QM queues (128*MAX_CONN) */
 	BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
+
+	BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping,
+			sizeof(struct host_status_block));
 #endif
 
 	/* Slow path ring */
@@ -6799,7 +6868,7 @@ static void bnx2x_free_tx_skbs(struct bn
 {
 	int i;
 
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		u16 bd_cons = fp->tx_bd_cons;
@@ -6817,7 +6886,7 @@ static void bnx2x_free_rx_skbs(struct bn
 {
 	int i, j;
 
-	for_each_rx_queue(bp, j) {
+	for_each_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		for (i = 0; i < NUM_RX_BD; i++) {
@@ -6855,6 +6924,9 @@ static void bnx2x_free_msix_irqs(struct
 	DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
 	   bp->msix_table[0].vector);
 
+#ifdef BCM_CNIC
+	offset++;
+#endif
 	for_each_queue(bp, i) {
 		DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq  "
 		   "state %x\n", i, bp->msix_table[i + offset].vector,
@@ -6888,6 +6960,12 @@ static int bnx2x_enable_msix(struct bnx2
 	bp->msix_table[0].entry = igu_vec;
 	DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec);
 
+#ifdef BCM_CNIC
+	igu_vec = BP_L_ID(bp) + offset;
+	bp->msix_table[1].entry = igu_vec;
+	DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec);
+	offset++;
+#endif
 	for_each_queue(bp, i) {
 		igu_vec = BP_L_ID(bp) + offset + i;
 		bp->msix_table[i + offset].entry = igu_vec;
@@ -6918,14 +6996,13 @@ static int bnx2x_req_msix_irqs(struct bn
 		return -EBUSY;
 	}
 
+#ifdef BCM_CNIC
+	offset++;
+#endif
 	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
-
-		if (i < bp->num_rx_queues)
-			sprintf(fp->name, "%s-rx-%d", bp->dev->name, i);
-		else
-			sprintf(fp->name, "%s-tx-%d",
-				bp->dev->name, i - bp->num_rx_queues);
+		snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
+			 bp->dev->name, i);
 
 		rc = request_irq(bp->msix_table[i + offset].vector,
 				 bnx2x_msix_fp_int, 0, fp->name, fp);
@@ -6984,7 +7061,7 @@ static void bnx2x_napi_enable(struct bnx
 {
 	int i;
 
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		napi_enable(&bnx2x_fp(bp, i, napi));
 }
 
@@ -6992,7 +7069,7 @@ static void bnx2x_napi_disable(struct bn
 {
 	int i;
 
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		napi_disable(&bnx2x_fp(bp, i, napi));
 }
 
@@ -7018,14 +7095,25 @@ static void bnx2x_netif_stop(struct bnx2
 	bnx2x_int_disable_sync(bp, disable_hw);
 	bnx2x_napi_disable(bp);
 	netif_tx_disable(bp->dev);
-	bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 }
 
 /*
  * Init service functions
  */
 
-static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
+/**
+ * Sets a MAC in a CAM for a few L2 Clients for E1 chip
+ *
+ * @param bp driver descriptor
+ * @param set set or clear an entry (1 or 0)
+ * @param mac pointer to a buffer containing a MAC
+ * @param cl_bit_vec bit vector of clients to register a MAC for
+ * @param cam_offset offset in a CAM to use
+ * @param with_bcast set broadcast MAC as well
+ */
+static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac,
+				      u32 cl_bit_vec, u8 cam_offset,
+				      u8 with_bcast)
 {
 	struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
 	int port = BP_PORT(bp);
@@ -7034,25 +7122,25 @@ static void bnx2x_set_mac_addr_e1(struct
 	 * unicasts 0-31:port0 32-63:port1
 	 * multicast 64-127:port0 128-191:port1
 	 */
-	config->hdr.length = 2;
-	config->hdr.offset = port ? 32 : 0;
-	config->hdr.client_id = bp->fp->cl_id;
+	config->hdr.length = 1 + (with_bcast ? 1 : 0);
+	config->hdr.offset = cam_offset;
+	config->hdr.client_id = 0xff;
 	config->hdr.reserved1 = 0;
 
 	/* primary MAC */
 	config->config_table[0].cam_entry.msb_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[0]);
+					swab16(*(u16 *)&mac[0]);
 	config->config_table[0].cam_entry.middle_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[2]);
+					swab16(*(u16 *)&mac[2]);
 	config->config_table[0].cam_entry.lsb_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[4]);
+					swab16(*(u16 *)&mac[4]);
 	config->config_table[0].cam_entry.flags = cpu_to_le16(port);
 	if (set)
 		config->config_table[0].target_table_entry.flags = 0;
 	else
 		CAM_INVALIDATE(config->config_table[0]);
 	config->config_table[0].target_table_entry.clients_bit_vector =
-						cpu_to_le32(1 << BP_L_ID(bp));
+						cpu_to_le32(cl_bit_vec);
 	config->config_table[0].target_table_entry.vlan_id = 0;
 
 	DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
@@ -7062,47 +7150,58 @@ static void bnx2x_set_mac_addr_e1(struct
 	   config->config_table[0].cam_entry.lsb_mac_addr);
 
 	/* broadcast */
-	config->config_table[1].cam_entry.msb_mac_addr = cpu_to_le16(0xffff);
-	config->config_table[1].cam_entry.middle_mac_addr = cpu_to_le16(0xffff);
-	config->config_table[1].cam_entry.lsb_mac_addr = cpu_to_le16(0xffff);
-	config->config_table[1].cam_entry.flags = cpu_to_le16(port);
-	if (set)
-		config->config_table[1].target_table_entry.flags =
-				TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
-	else
-		CAM_INVALIDATE(config->config_table[1]);
-	config->config_table[1].target_table_entry.clients_bit_vector =
-						cpu_to_le32(1 << BP_L_ID(bp));
-	config->config_table[1].target_table_entry.vlan_id = 0;
+	if (with_bcast) {
+		config->config_table[1].cam_entry.msb_mac_addr =
+			cpu_to_le16(0xffff);
+		config->config_table[1].cam_entry.middle_mac_addr =
+			cpu_to_le16(0xffff);
+		config->config_table[1].cam_entry.lsb_mac_addr =
+			cpu_to_le16(0xffff);
+		config->config_table[1].cam_entry.flags = cpu_to_le16(port);
+		if (set)
+			config->config_table[1].target_table_entry.flags =
+					TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
+		else
+			CAM_INVALIDATE(config->config_table[1]);
+		config->config_table[1].target_table_entry.clients_bit_vector =
+							cpu_to_le32(cl_bit_vec);
+		config->config_table[1].target_table_entry.vlan_id = 0;
+	}
 
 	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
 		      U64_HI(bnx2x_sp_mapping(bp, mac_config)),
 		      U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
 }
 
-static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
+/**
+ * Sets a MAC in a CAM for a few L2 Clients for E1H chip
+ *
+ * @param bp driver descriptor
+ * @param set set or clear an entry (1 or 0)
+ * @param mac pointer to a buffer containing a MAC
+ * @param cl_bit_vec bit vector of clients to register a MAC for
+ * @param cam_offset offset in a CAM to use
+ */
+static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac,
+				       u32 cl_bit_vec, u8 cam_offset)
 {
 	struct mac_configuration_cmd_e1h *config =
 		(struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
 
-	/* CAM allocation for E1H
-	 * unicasts: by func number
-	 * multicast: 20+FUNC*20, 20 each
-	 */
 	config->hdr.length = 1;
-	config->hdr.offset = BP_FUNC(bp);
-	config->hdr.client_id = bp->fp->cl_id;
+	config->hdr.offset = cam_offset;
+	config->hdr.client_id = 0xff;
 	config->hdr.reserved1 = 0;
 
 	/* primary MAC */
 	config->config_table[0].msb_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[0]);
+					swab16(*(u16 *)&mac[0]);
 	config->config_table[0].middle_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[2]);
+					swab16(*(u16 *)&mac[2]);
 	config->config_table[0].lsb_mac_addr =
-					swab16(*(u16 *)&bp->dev->dev_addr[4]);
+					swab16(*(u16 *)&mac[4]);
 	config->config_table[0].clients_bit_vector =
-					cpu_to_le32(1 << BP_L_ID(bp));
+					cpu_to_le32(cl_bit_vec);
 	config->config_table[0].vlan_id = 0;
 	config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
 	if (set)
@@ -7111,11 +7210,11 @@ static void bnx2x_set_mac_addr_e1h(struc
 		config->config_table[0].flags =
 				MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE;
 
-	DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)  E1HOV %d  CLID %d\n",
+	DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)  E1HOV %d  CLID mask %d\n",
 	   (set ? "setting" : "clearing"),
 	   config->config_table[0].msb_mac_addr,
 	   config->config_table[0].middle_mac_addr,
-	   config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp));
+	   config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec);
 
 	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
 		      U64_HI(bnx2x_sp_mapping(bp, mac_config)),
@@ -7167,6 +7266,69 @@ static int bnx2x_wait_ramrod(struct bnx2
 	return -EBUSY;
 }
 
+static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set)
+{
+	bp->set_mac_pending++;
+	smp_wmb();
+
+	bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr,
+				   (1 << bp->fp->cl_id), BP_FUNC(bp));
+
+	/* Wait for a completion */
+	bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+}
+
+static void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set)
+{
+	bp->set_mac_pending++;
+	smp_wmb();
+
+	bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr,
+				  (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0),
+				  1);
+
+	/* Wait for a completion */
+	bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+}
+
+#ifdef BCM_CNIC
+/**
+ * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
+ * MAC(s). This function will wait until the ramdord completion
+ * returns.
+ *
+ * @param bp driver handle
+ * @param set set or clear the CAM entry
+ *
+ * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ */
+static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
+{
+	u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID);
+
+	bp->set_mac_pending++;
+	smp_wmb();
+
+	/* Send a SET_MAC ramrod */
+	if (CHIP_IS_E1(bp))
+		bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac,
+				  cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2,
+				  1);
+	else
+		/* CAM allocation for E1H
+		* unicasts: by func number
+		* multicast: 20+FUNC*20, 20 each
+		*/
+		bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac,
+				   cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp));
+
+	/* Wait for a completion when setting */
+	bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+
+	return 0;
+}
+#endif
+
 static int bnx2x_setup_leading(struct bnx2x *bp)
 {
 	int rc;
@@ -7202,96 +7364,67 @@ static int bnx2x_setup_multi(struct bnx2
 
 static int bnx2x_poll(struct napi_struct *napi, int budget);
 
-static void bnx2x_set_int_mode_msix(struct bnx2x *bp, int *num_rx_queues_out,
-				    int *num_tx_queues_out)
+static void bnx2x_set_num_queues_msix(struct bnx2x *bp)
 {
-	int _num_rx_queues = 0, _num_tx_queues = 0;
 
 	switch (bp->multi_mode) {
 	case ETH_RSS_MODE_DISABLED:
-		_num_rx_queues = 1;
-		_num_tx_queues = 1;
+		bp->num_queues = 1;
 		break;
 
 	case ETH_RSS_MODE_REGULAR:
-		if (num_rx_queues)
-			_num_rx_queues = min_t(u32, num_rx_queues,
-					       BNX2X_MAX_QUEUES(bp));
-		else
-			_num_rx_queues = min_t(u32, num_online_cpus(),
-					       BNX2X_MAX_QUEUES(bp));
-
-		if (num_tx_queues)
-			_num_tx_queues = min_t(u32, num_tx_queues,
-					       BNX2X_MAX_QUEUES(bp));
+		if (num_queues)
+			bp->num_queues = min_t(u32, num_queues,
+						  BNX2X_MAX_QUEUES(bp));
 		else
-			_num_tx_queues = min_t(u32, num_online_cpus(),
-					       BNX2X_MAX_QUEUES(bp));
-
-		/* There must be not more Tx queues than Rx queues */
-		if (_num_tx_queues > _num_rx_queues) {
-			BNX2X_ERR("number of tx queues (%d) > "
-				  "number of rx queues (%d)"
-				  "  defaulting to %d\n",
-				  _num_tx_queues, _num_rx_queues,
-				  _num_rx_queues);
-			_num_tx_queues = _num_rx_queues;
-		}
+			bp->num_queues = min_t(u32, num_online_cpus(),
+						  BNX2X_MAX_QUEUES(bp));
 		break;
 
 
 	default:
-		_num_rx_queues = 1;
-		_num_tx_queues = 1;
+		bp->num_queues = 1;
 		break;
 	}
-
-	*num_rx_queues_out = _num_rx_queues;
-	*num_tx_queues_out = _num_tx_queues;
 }
 
-static int bnx2x_set_int_mode(struct bnx2x *bp)
+static int bnx2x_set_num_queues(struct bnx2x *bp)
 {
 	int rc = 0;
 
 	switch (int_mode) {
 	case INT_MODE_INTx:
 	case INT_MODE_MSI:
-		bp->num_rx_queues = 1;
-		bp->num_tx_queues = 1;
+		bp->num_queues = 1;
 		DP(NETIF_MSG_IFUP, "set number of queues to 1\n");
 		break;
 
 	case INT_MODE_MSIX:
 	default:
-		/* Set interrupt mode according to bp->multi_mode value */
-		bnx2x_set_int_mode_msix(bp, &bp->num_rx_queues,
-					&bp->num_tx_queues);
+		/* Set number of queues according to bp->multi_mode value */
+		bnx2x_set_num_queues_msix(bp);
 
-		DP(NETIF_MSG_IFUP, "set number of queues to: rx %d tx %d\n",
-		   bp->num_rx_queues, bp->num_tx_queues);
+		DP(NETIF_MSG_IFUP, "set number of queues to %d\n",
+		   bp->num_queues);
 
 		/* if we can't use MSI-X we only need one fp,
 		 * so try to enable MSI-X with the requested number of fp's
 		 * and fallback to MSI or legacy INTx with one fp
 		 */
 		rc = bnx2x_enable_msix(bp);
-		if (rc) {
+		if (rc)
 			/* failed to enable MSI-X */
-			if (bp->multi_mode)
-				BNX2X_ERR("Multi requested but failed to "
-					  "enable MSI-X (rx %d tx %d), "
-					  "set number of queues to 1\n",
-					  bp->num_rx_queues, bp->num_tx_queues);
-			bp->num_rx_queues = 1;
-			bp->num_tx_queues = 1;
-		}
+			bp->num_queues = 1;
 		break;
 	}
-	bp->dev->real_num_tx_queues = bp->num_tx_queues;
+	bp->dev->real_num_tx_queues = bp->num_queues;
 	return rc;
 }
 
+#ifdef BCM_CNIC
+static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
+static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
+#endif
 
 /* must be called with rtnl_lock */
 static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
@@ -7306,16 +7439,16 @@ static int bnx2x_nic_load(struct bnx2x *
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
-	rc = bnx2x_set_int_mode(bp);
+	rc = bnx2x_set_num_queues(bp);
 
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;
 
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		bnx2x_fp(bp, i, disable_tpa) =
 					((bp->flags & TPA_ENABLE_FLAG) == 0);
 
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
 			       bnx2x_poll, 128);
 
@@ -7329,7 +7462,7 @@ static int bnx2x_nic_load(struct bnx2x *
 		}
 	} else {
 		/* Fall to INTx if failed to enable MSI-X due to lack of
-		   memory (in bnx2x_set_int_mode()) */
+		   memory (in bnx2x_set_num_queues()) */
 		if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx))
 			bnx2x_enable_msi(bp);
 		bnx2x_ack_int(bp);
@@ -7430,20 +7563,39 @@ static int bnx2x_nic_load(struct bnx2x *
 	if (CHIP_IS_E1H(bp))
 		if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
 			DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
-			bp->state = BNX2X_STATE_DISABLED;
+			bp->flags |= MF_FUNC_DIS;
 		}
 
 	if (bp->state == BNX2X_STATE_OPEN) {
+#ifdef BCM_CNIC
+		/* Enable Timer scan */
+		REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1);
+#endif
 		for_each_nondefault_queue(bp, i) {
 			rc = bnx2x_setup_multi(bp, i);
 			if (rc)
+#ifdef BCM_CNIC
+				goto load_error4;
+#else
 				goto load_error3;
+#endif
 		}
 
 		if (CHIP_IS_E1(bp))
-			bnx2x_set_mac_addr_e1(bp, 1);
+			bnx2x_set_eth_mac_addr_e1(bp, 1);
 		else
-			bnx2x_set_mac_addr_e1h(bp, 1);
+			bnx2x_set_eth_mac_addr_e1h(bp, 1);
+#ifdef BCM_CNIC
+		/* Set iSCSI L2 MAC */
+		mutex_lock(&bp->cnic_mutex);
+		if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) {
+			bnx2x_set_iscsi_eth_mac_addr(bp, 1);
+			bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
+			bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping,
+				      CNIC_SB_ID(bp));
+		}
+		mutex_unlock(&bp->cnic_mutex);
+#endif
 	}
 
 	if (bp->port.pmf)
@@ -7484,9 +7636,19 @@ static int bnx2x_nic_load(struct bnx2x *
 	/* start the timer */
 	mod_timer(&bp->timer, jiffies + bp->current_interval);
 
+#ifdef BCM_CNIC
+	bnx2x_setup_cnic_irq_info(bp);
+	if (bp->state == BNX2X_STATE_OPEN)
+		bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD);
+#endif
 
 	return 0;
 
+#ifdef BCM_CNIC
+load_error4:
+	/* Disable Timer scan */
+	REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 0);
+#endif
 load_error3:
 	bnx2x_int_disable_sync(bp, 1);
 	if (!BP_NOMCP(bp)) {
@@ -7496,14 +7658,14 @@ load_error3:
 	bp->port.pmf = 0;
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
 load_error2:
 	/* Release IRQs */
 	bnx2x_free_irq(bp);
 load_error1:
 	bnx2x_napi_disable(bp);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
@@ -7594,6 +7756,19 @@ static void bnx2x_reset_func(struct bnx2
 	REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
 	REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
 
+#ifdef BCM_CNIC
+	/* Disable Timer scan */
+	REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0);
+	/*
+	 * Wait for at least 10ms and up to 2 second for the timers scan to
+	 * complete
+	 */
+	for (i = 0; i < 200; i++) {
+		msleep(10);
+		if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4))
+			break;
+	}
+#endif
 	/* Clear ILT */
 	base = FUNC_ILT_BASE(func);
 	for (i = base; i < base + ILT_PER_FUNC; i++)
@@ -7660,6 +7835,9 @@ static int bnx2x_nic_unload(struct bnx2x
 	u32 reset_code = 0;
 	int i, cnt, rc;
 
+#ifdef BCM_CNIC
+	bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
+#endif
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
 
 	/* Set "drop all" */
@@ -7678,7 +7856,7 @@ static int bnx2x_nic_unload(struct bnx2x
 	bnx2x_free_irq(bp);
 
 	/* Wait until tx fastpath tasks complete */
-	for_each_tx_queue(bp, i) {
+	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		cnt = 1000;
@@ -7706,7 +7884,7 @@ static int bnx2x_nic_unload(struct bnx2x
 		struct mac_configuration_cmd *config =
 						bnx2x_sp(bp, mcast_config);
 
-		bnx2x_set_mac_addr_e1(bp, 0);
+		bnx2x_set_eth_mac_addr_e1(bp, 0);
 
 		for (i = 0; i < config->hdr.length; i++)
 			CAM_INVALIDATE(config->config_table[i]);
@@ -7719,6 +7897,9 @@ static int bnx2x_nic_unload(struct bnx2x
 		config->hdr.client_id = bp->fp->cl_id;
 		config->hdr.reserved1 = 0;
 
+		bp->set_mac_pending++;
+		smp_wmb();
+
 		bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
 			      U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
 			      U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
@@ -7726,13 +7907,22 @@ static int bnx2x_nic_unload(struct bnx2x
 	} else { /* E1H */
 		REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
 
-		bnx2x_set_mac_addr_e1h(bp, 0);
+		bnx2x_set_eth_mac_addr_e1h(bp, 0);
 
 		for (i = 0; i < MC_HASH_SIZE; i++)
 			REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
 
 		REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
 	}
+#ifdef BCM_CNIC
+	/* Clear iSCSI L2 MAC */
+	mutex_lock(&bp->cnic_mutex);
+	if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
+		bnx2x_set_iscsi_eth_mac_addr(bp, 0);
+		bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
+	}
+	mutex_unlock(&bp->cnic_mutex);
+#endif
 
 	if (unload_mode == UNLOAD_NORMAL)
 		reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
@@ -7809,9 +7999,9 @@ unload_error:
 
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
@@ -8509,6 +8699,14 @@ static void __devinit bnx2x_link_setting
 		       bp->link_params.req_flow_ctrl, bp->port.advertising);
 }
 
+static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
+{
+	mac_hi = cpu_to_be16(mac_hi);
+	mac_lo = cpu_to_be32(mac_lo);
+	memcpy(mac_buf, &mac_hi, sizeof(mac_hi));
+	memcpy(mac_buf + sizeof(mac_hi), &mac_lo, sizeof(mac_lo));
+}
+
 static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
@@ -8590,14 +8788,15 @@ static void __devinit bnx2x_get_port_hwi
 
 	val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
 	val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
-	bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
-	bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
-	bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
-	bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
-	bp->dev->dev_addr[4] = (u8)(val >> 8  & 0xff);
-	bp->dev->dev_addr[5] = (u8)(val & 0xff);
+	bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2);
 	memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
 	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
+
+#ifdef BCM_CNIC
+	val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper);
+	val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower);
+	bnx2x_set_mac_buf(bp->iscsi_mac, val, val2);
+#endif
 }
 
 static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -8693,6 +8892,10 @@ static int __devinit bnx2x_init_bp(struc
 	smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
 
 	mutex_init(&bp->port.phy_mutex);
+	mutex_init(&bp->fw_mb_mutex);
+#ifdef BCM_CNIC
+	mutex_init(&bp->cnic_mutex);
+#endif
 
 	INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task);
 	INIT_WORK(&bp->reset_task, bnx2x_reset_task);
@@ -8741,8 +8944,9 @@ static int __devinit bnx2x_init_bp(struc
 
 	bp->rx_csum = 1;
 
-	bp->tx_ticks = 50;
-	bp->rx_ticks = 25;
+	/* make sure that the numbers are in the right granularity */
+	bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR);
+	bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR);
 
 	timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
 	bp->current_interval = (poll ? poll : timer_interval);
@@ -8768,20 +8972,23 @@ static int bnx2x_get_settings(struct net
 	cmd->supported = bp->port.supported;
 	cmd->advertising = bp->port.advertising;
 
-	if (netif_carrier_ok(dev)) {
+	if ((bp->state == BNX2X_STATE_OPEN) &&
+	    !(bp->flags & MF_FUNC_DIS) &&
+	    (bp->link_vars.link_up)) {
 		cmd->speed = bp->link_vars.line_speed;
 		cmd->duplex = bp->link_vars.duplex;
-	} else {
-		cmd->speed = bp->link_params.req_line_speed;
-		cmd->duplex = bp->link_params.req_duplex;
-	}
-	if (IS_E1HMF(bp)) {
-		u16 vn_max_rate;
+		if (IS_E1HMF(bp)) {
+			u16 vn_max_rate;
 
-		vn_max_rate = ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+			vn_max_rate =
+				((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
 				FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
-		if (vn_max_rate < cmd->speed)
-			cmd->speed = vn_max_rate;
+			if (vn_max_rate < cmd->speed)
+				cmd->speed = vn_max_rate;
+		}
+	} else {
+		cmd->speed = -1;
+		cmd->duplex = -1;
 	}
 
 	if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
@@ -9166,6 +9373,9 @@ static u32 bnx2x_get_link(struct net_dev
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
+	if (bp->flags & MF_FUNC_DIS)
+		return 0;
+
 	return bp->link_vars.link_up;
 }
 
@@ -9570,8 +9780,7 @@ static int bnx2x_set_eeprom(struct net_d
 
 	} else if (eeprom->magic == 0x50485952) {
 		/* 'PHYR' (0x50485952): re-init link after FW upgrade */
-		if ((bp->state == BNX2X_STATE_OPEN) ||
-		    (bp->state == BNX2X_STATE_DISABLED)) {
+		if (bp->state == BNX2X_STATE_OPEN) {
 			bnx2x_acquire_phy_lock(bp);
 			rc |= bnx2x_link_reset(&bp->link_params,
 					       &bp->link_vars, 1);
@@ -9821,11 +10030,6 @@ static const struct {
 	{ "idle check (online)" }
 };
 
-static int bnx2x_self_test_count(struct net_device *dev)
-{
-	return BNX2X_NUM_TESTS;
-}
-
 static int bnx2x_test_registers(struct bnx2x *bp)
 {
 	int idx, i, rc = -ENODEV;
@@ -9993,7 +10197,7 @@ static int bnx2x_run_loopback(struct bnx
 	struct sk_buff *skb;
 	unsigned char *packet;
 	struct bnx2x_fastpath *fp_rx = &bp->fp[0];
-	struct bnx2x_fastpath *fp_tx = &bp->fp[bp->num_rx_queues];
+	struct bnx2x_fastpath *fp_tx = &bp->fp[0];
 	u16 tx_start_idx, tx_idx;
 	u16 rx_start_idx, rx_idx;
 	u16 pkt_prod, bd_prod;
@@ -10070,13 +10274,12 @@ static int bnx2x_run_loopback(struct bnx
 
 	fp_tx->tx_db.data.prod += 2;
 	barrier();
-	DOORBELL(bp, fp_tx->index - bp->num_rx_queues, fp_tx->tx_db.raw);
+	DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw);
 
 	mmiowb();
 
 	num_pkts++;
 	fp_tx->tx_bd_prod += 2; /* start + pbd */
-	bp->dev->trans_start = jiffies;
 
 	udelay(100);
 
@@ -10226,14 +10429,16 @@ static int bnx2x_test_intr(struct bnx2x
 	config->hdr.client_id = bp->fp->cl_id;
 	config->hdr.reserved1 = 0;
 
+	bp->set_mac_pending++;
+	smp_wmb();
 	rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
 			   U64_HI(bnx2x_sp_mapping(bp, mac_config)),
 			   U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
 	if (rc == 0) {
-		bp->set_mac_pending++;
 		for (i = 0; i < 10; i++) {
 			if (!bp->set_mac_pending)
 				break;
+			smp_rmb();
 			msleep_interruptible(10);
 		}
 		if (i == 10)
@@ -10267,7 +10472,7 @@ static void bnx2x_self_test(struct net_d
 		/* disable input for TX port IF */
 		REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
 
-		link_up = bp->link_vars.link_up;
+		link_up = (bnx2x_link_test(bp) == 0);
 		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
 		bnx2x_nic_load(bp, LOAD_DIAG);
 		/* wait until link state is restored */
@@ -10439,6 +10644,36 @@ static const struct {
 #define IS_E1HMF_MODE_STAT(bp) \
 			(IS_E1HMF(bp) && !(bp->msglevel & BNX2X_MSG_STATS))
 
+static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	int i, num_stats;
+
+	switch(stringset) {
+	case ETH_SS_STATS:
+		if (is_multi(bp)) {
+			num_stats = BNX2X_NUM_Q_STATS * bp->num_queues;
+			if (!IS_E1HMF_MODE_STAT(bp))
+				num_stats += BNX2X_NUM_STATS;
+		} else {
+			if (IS_E1HMF_MODE_STAT(bp)) {
+				num_stats = 0;
+				for (i = 0; i < BNX2X_NUM_STATS; i++)
+					if (IS_FUNC_STAT(i))
+						num_stats++;
+			} else
+				num_stats = BNX2X_NUM_STATS;
+		}
+		return num_stats;
+
+	case ETH_SS_TEST:
+		return BNX2X_NUM_TESTS;
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -10448,7 +10683,7 @@ static void bnx2x_get_strings(struct net
 	case ETH_SS_STATS:
 		if (is_multi(bp)) {
 			k = 0;
-			for_each_rx_queue(bp, i) {
+			for_each_queue(bp, i) {
 				for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
 					sprintf(buf + (k + j)*ETH_GSTRING_LEN,
 						bnx2x_q_stats_arr[j].string, i);
@@ -10476,28 +10711,6 @@ static void bnx2x_get_strings(struct net
 	}
 }
 
-static int bnx2x_get_stats_count(struct net_device *dev)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-	int i, num_stats;
-
-	if (is_multi(bp)) {
-		num_stats = BNX2X_NUM_Q_STATS * bp->num_rx_queues;
-		if (!IS_E1HMF_MODE_STAT(bp))
-			num_stats += BNX2X_NUM_STATS;
-	} else {
-		if (IS_E1HMF_MODE_STAT(bp)) {
-			num_stats = 0;
-			for (i = 0; i < BNX2X_NUM_STATS; i++)
-				if (IS_FUNC_STAT(i))
-					num_stats++;
-		} else
-			num_stats = BNX2X_NUM_STATS;
-	}
-
-	return num_stats;
-}
-
 static void bnx2x_get_ethtool_stats(struct net_device *dev,
 				    struct ethtool_stats *stats, u64 *buf)
 {
@@ -10507,7 +10720,7 @@ static void bnx2x_get_ethtool_stats(stru
 
 	if (is_multi(bp)) {
 		k = 0;
-		for_each_rx_queue(bp, i) {
+		for_each_queue(bp, i) {
 			hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
 			for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
 				if (bnx2x_q_stats_arr[j].size == 0) {
@@ -10573,7 +10786,6 @@ static void bnx2x_get_ethtool_stats(stru
 static int bnx2x_phys_id(struct net_device *dev, u32 data)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int port = BP_PORT(bp);
 	int i;
 
 	if (!netif_running(dev))
@@ -10587,13 +10799,10 @@ static int bnx2x_phys_id(struct net_devi
 
 	for (i = 0; i < (data * 2); i++) {
 		if ((i % 2) == 0)
-			bnx2x_set_led(bp, port, LED_MODE_OPER, SPEED_1000,
-				      bp->link_params.hw_led_mode,
-				      bp->link_params.chip_id);
+			bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
+				      SPEED_1000);
 		else
-			bnx2x_set_led(bp, port, LED_MODE_OFF, 0,
-				      bp->link_params.hw_led_mode,
-				      bp->link_params.chip_id);
+			bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0);
 
 		msleep_interruptible(500);
 		if (signal_pending(current))
@@ -10601,10 +10810,8 @@ static int bnx2x_phys_id(struct net_devi
 	}
 
 	if (bp->link_vars.link_up)
-		bnx2x_set_led(bp, port, LED_MODE_OPER,
-			      bp->link_vars.line_speed,
-			      bp->link_params.hw_led_mode,
-			      bp->link_params.chip_id);
+		bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
+			      bp->link_vars.line_speed);
 
 	return 0;
 }
@@ -10640,11 +10847,10 @@ static const struct ethtool_ops bnx2x_et
 	.set_sg			= ethtool_op_set_sg,
 	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= bnx2x_set_tso,
-	.self_test_count	= bnx2x_self_test_count,
 	.self_test		= bnx2x_self_test,
+	.get_sset_count		= bnx2x_get_sset_count,
 	.get_strings		= bnx2x_get_strings,
 	.phys_id		= bnx2x_phys_id,
-	.get_stats_count	= bnx2x_get_stats_count,
 	.get_ethtool_stats	= bnx2x_get_ethtool_stats,
 };
 
@@ -10710,54 +10916,60 @@ static inline int bnx2x_has_rx_work(stru
 
 static int bnx2x_poll(struct napi_struct *napi, int budget)
 {
+	int work_done = 0;
 	struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
 						 napi);
 	struct bnx2x *bp = fp->bp;
-	int work_done = 0;
 
+	while (1) {
 #ifdef BNX2X_STOP_ON_ERROR
-	if (unlikely(bp->panic))
-		goto poll_panic;
+		if (unlikely(bp->panic)) {
+			napi_complete(napi);
+			return 0;
+		}
 #endif
 
-	prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
-	prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
-
-	bnx2x_update_fpsb_idx(fp);
-
-	if (bnx2x_has_rx_work(fp)) {
-		work_done = bnx2x_rx_int(fp, budget);
+		if (bnx2x_has_tx_work(fp))
+			bnx2x_tx_int(fp);
 
-		/* must not complete if we consumed full budget */
-		if (work_done >= budget)
-			goto poll_again;
-	}
+		if (bnx2x_has_rx_work(fp)) {
+			work_done += bnx2x_rx_int(fp, budget - work_done);
 
-	/* bnx2x_has_rx_work() reads the status block, thus we need to
-	 * ensure that status block indices have been actually read
-	 * (bnx2x_update_fpsb_idx) prior to this check (bnx2x_has_rx_work)
-	 * so that we won't write the "newer" value of the status block to IGU
-	 * (if there was a DMA right after bnx2x_has_rx_work and
-	 * if there is no rmb, the memory reading (bnx2x_update_fpsb_idx)
-	 * may be postponed to right before bnx2x_ack_sb). In this case
-	 * there will never be another interrupt until there is another update
-	 * of the status block, while there is still unhandled work.
-	 */
-	rmb();
+			/* must not complete if we consumed full budget */
+			if (work_done >= budget)
+				break;
+		}
 
-	if (!bnx2x_has_rx_work(fp)) {
-#ifdef BNX2X_STOP_ON_ERROR
-poll_panic:
-#endif
-		napi_complete(napi);
+		/* Fall out from the NAPI loop if needed */
+		if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+			bnx2x_update_fpsb_idx(fp);
+		/* bnx2x_has_rx_work() reads the status block, thus we need
+		 * to ensure that status block indices have been actually read
+		 * (bnx2x_update_fpsb_idx) prior to this check
+		 * (bnx2x_has_rx_work) so that we won't write the "newer"
+		 * value of the status block to IGU (if there was a DMA right
+		 * after bnx2x_has_rx_work and if there is no rmb, the memory
+		 * reading (bnx2x_update_fpsb_idx) may be postponed to right
+		 * before bnx2x_ack_sb). In this case there will never be
+		 * another interrupt until there is another update of the
+		 * status block, while there is still unhandled work.
+		 */
+			rmb();
 
-		bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
-			     le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
-		bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
-			     le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
+			if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+				napi_complete(napi);
+				/* Re-enable interrupts */
+				bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
+					     le16_to_cpu(fp->fp_c_idx),
+					     IGU_INT_NOP, 1);
+				bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
+					     le16_to_cpu(fp->fp_u_idx),
+					     IGU_INT_ENABLE, 1);
+				break;
+			}
+		}
 	}
 
-poll_again:
 	return work_done;
 }
 
@@ -10846,10 +11058,10 @@ static inline u32 bnx2x_xmit_type(struct
 	}
 
 	if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
-		rc |= XMIT_GSO_V4;
+		rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP);
 
 	else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-		rc |= XMIT_GSO_V6;
+		rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6);
 
 	return rc;
 }
@@ -10942,7 +11154,7 @@ exit_lbl:
 static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	struct bnx2x_fastpath *fp, *fp_stat;
+	struct bnx2x_fastpath *fp;
 	struct netdev_queue *txq;
 	struct sw_tx_bd *tx_buf;
 	struct eth_tx_start_bd *tx_start_bd;
@@ -10964,11 +11176,10 @@ static netdev_tx_t bnx2x_start_xmit(stru
 	fp_index = skb_get_queue_mapping(skb);
 	txq = netdev_get_tx_queue(dev, fp_index);
 
-	fp = &bp->fp[fp_index + bp->num_rx_queues];
-	fp_stat = &bp->fp[fp_index];
+	fp = &bp->fp[fp_index];
 
 	if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
-		fp_stat->eth_q_stats.driver_xoff++;
+		fp->eth_q_stats.driver_xoff++;
 		netif_tx_stop_queue(txq);
 		BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
@@ -11194,7 +11405,7 @@ static netdev_tx_t bnx2x_start_xmit(stru
 
 	fp->tx_db.data.prod += nbd;
 	barrier();
-	DOORBELL(bp, fp->index - bp->num_rx_queues, fp->tx_db.raw);
+	DOORBELL(bp, fp->index, fp->tx_db.raw);
 
 	mmiowb();
 
@@ -11205,11 +11416,11 @@ static netdev_tx_t bnx2x_start_xmit(stru
 		/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
 		   if we put Tx into XOFF state. */
 		smp_mb();
-		fp_stat->eth_q_stats.driver_xoff++;
+		fp->eth_q_stats.driver_xoff++;
 		if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
 			netif_tx_wake_queue(txq);
 	}
-	fp_stat->tx_pkt++;
+	fp->tx_pkt++;
 
 	return NETDEV_TX_OK;
 }
@@ -11324,6 +11535,9 @@ static void bnx2x_set_rx_mode(struct net
 			config->hdr.client_id = bp->fp->cl_id;
 			config->hdr.reserved1 = 0;
 
+			bp->set_mac_pending++;
+			smp_wmb();
+
 			bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
 				   U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
 				   U64_LO(bnx2x_sp_mapping(bp, mcast_config)),
@@ -11373,9 +11587,9 @@ static int bnx2x_change_mac_addr(struct
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 	if (netif_running(dev)) {
 		if (CHIP_IS_E1(bp))
-			bnx2x_set_mac_addr_e1(bp, 1);
+			bnx2x_set_eth_mac_addr_e1(bp, 1);
 		else
-			bnx2x_set_mac_addr_e1h(bp, 1);
+			bnx2x_set_eth_mac_addr_e1h(bp, 1);
 	}
 
 	return 0;
@@ -11774,17 +11988,14 @@ static inline void be16_to_cpu_n(const u
 
 static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 {
-	char fw_file_name[40] = {0};
+	const char *fw_file_name;
 	struct bnx2x_fw_file_hdr *fw_hdr;
-	int rc, offset;
+	int rc;
 
-	/* Create a FW file name */
 	if (CHIP_IS_E1(bp))
-		offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+		fw_file_name = FW_FILE_NAME_E1;
 	else
-		offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
-
-	/*(DEBLOBBED)*/
+		fw_file_name = FW_FILE_NAME_E1H;
 
 	printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
 
@@ -12038,9 +12249,9 @@ static int bnx2x_eeh_nic_unload(struct b
 
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-	for_each_rx_queue(bp, i)
+	for_each_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
@@ -12216,4 +12427,287 @@ static void __exit bnx2x_cleanup(void)
 module_init(bnx2x_init);
 module_exit(bnx2x_cleanup);
 
+#ifdef BCM_CNIC
+
+/* count denotes the number of new completions we have seen */
+static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
+{
+	struct eth_spe *spe;
+
+#ifdef BNX2X_STOP_ON_ERROR
+	if (unlikely(bp->panic))
+		return;
+#endif
+
+	spin_lock_bh(&bp->spq_lock);
+	bp->cnic_spq_pending -= count;
+
+	for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending;
+	     bp->cnic_spq_pending++) {
+
+		if (!bp->cnic_kwq_pending)
+			break;
+
+		spe = bnx2x_sp_get_next(bp);
+		*spe = *bp->cnic_kwq_cons;
+
+		bp->cnic_kwq_pending--;
+
+		DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n",
+		   bp->cnic_spq_pending, bp->cnic_kwq_pending, count);
+
+		if (bp->cnic_kwq_cons == bp->cnic_kwq_last)
+			bp->cnic_kwq_cons = bp->cnic_kwq;
+		else
+			bp->cnic_kwq_cons++;
+	}
+	bnx2x_sp_prod_update(bp);
+	spin_unlock_bh(&bp->spq_lock);
+}
+
+static int bnx2x_cnic_sp_queue(struct net_device *dev,
+			       struct kwqe_16 *kwqes[], u32 count)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	int i;
+
+#ifdef BNX2X_STOP_ON_ERROR
+	if (unlikely(bp->panic))
+		return -EIO;
+#endif
+
+	spin_lock_bh(&bp->spq_lock);
+
+	for (i = 0; i < count; i++) {
+		struct eth_spe *spe = (struct eth_spe *)kwqes[i];
+
+		if (bp->cnic_kwq_pending == MAX_SP_DESC_CNT)
+			break;
+
+		*bp->cnic_kwq_prod = *spe;
+
+		bp->cnic_kwq_pending++;
+
+		DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n",
+		   spe->hdr.conn_and_cmd_data, spe->hdr.type,
+		   spe->data.mac_config_addr.hi,
+		   spe->data.mac_config_addr.lo,
+		   bp->cnic_kwq_pending);
+
+		if (bp->cnic_kwq_prod == bp->cnic_kwq_last)
+			bp->cnic_kwq_prod = bp->cnic_kwq;
+		else
+			bp->cnic_kwq_prod++;
+	}
+
+	spin_unlock_bh(&bp->spq_lock);
+
+	if (bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending)
+		bnx2x_cnic_sp_post(bp, 0);
+
+	return i;
+}
+
+static int bnx2x_cnic_ctl_send(struct bnx2x *bp, struct cnic_ctl_info *ctl)
+{
+	struct cnic_ops *c_ops;
+	int rc = 0;
+
+	mutex_lock(&bp->cnic_mutex);
+	c_ops = bp->cnic_ops;
+	if (c_ops)
+		rc = c_ops->cnic_ctl(bp->cnic_data, ctl);
+	mutex_unlock(&bp->cnic_mutex);
+
+	return rc;
+}
+
+static int bnx2x_cnic_ctl_send_bh(struct bnx2x *bp, struct cnic_ctl_info *ctl)
+{
+	struct cnic_ops *c_ops;
+	int rc = 0;
+
+	rcu_read_lock();
+	c_ops = rcu_dereference(bp->cnic_ops);
+	if (c_ops)
+		rc = c_ops->cnic_ctl(bp->cnic_data, ctl);
+	rcu_read_unlock();
+
+	return rc;
+}
+
+/*
+ * for commands that have no data
+ */
+static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd)
+{
+	struct cnic_ctl_info ctl = {0};
+
+	ctl.cmd = cmd;
+
+	return bnx2x_cnic_ctl_send(bp, &ctl);
+}
+
+static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid)
+{
+	struct cnic_ctl_info ctl;
+
+	/* first we tell CNIC and only then we count this as a completion */
+	ctl.cmd = CNIC_CTL_COMPLETION_CMD;
+	ctl.data.comp.cid = cid;
+
+	bnx2x_cnic_ctl_send_bh(bp, &ctl);
+	bnx2x_cnic_sp_post(bp, 1);
+}
+
+static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	int rc = 0;
+
+	switch (ctl->cmd) {
+	case DRV_CTL_CTXTBL_WR_CMD: {
+		u32 index = ctl->data.io.offset;
+		dma_addr_t addr = ctl->data.io.dma_addr;
+
+		bnx2x_ilt_wr(bp, index, addr);
+		break;
+	}
+
+	case DRV_CTL_COMPLETION_CMD: {
+		int count = ctl->data.comp.comp_count;
+
+		bnx2x_cnic_sp_post(bp, count);
+		break;
+	}
+
+	/* rtnl_lock is held.  */
+	case DRV_CTL_START_L2_CMD: {
+		u32 cli = ctl->data.ring.client_id;
+
+		bp->rx_mode_cl_mask |= (1 << cli);
+		bnx2x_set_storm_rx_mode(bp);
+		break;
+	}
+
+	/* rtnl_lock is held.  */
+	case DRV_CTL_STOP_L2_CMD: {
+		u32 cli = ctl->data.ring.client_id;
+
+		bp->rx_mode_cl_mask &= ~(1 << cli);
+		bnx2x_set_storm_rx_mode(bp);
+		break;
+	}
+
+	default:
+		BNX2X_ERR("unknown command %x\n", ctl->cmd);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp)
+{
+	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+	if (bp->flags & USING_MSIX_FLAG) {
+		cp->drv_state |= CNIC_DRV_STATE_USING_MSIX;
+		cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX;
+		cp->irq_arr[0].vector = bp->msix_table[1].vector;
+	} else {
+		cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
+		cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX;
+	}
+	cp->irq_arr[0].status_blk = bp->cnic_sb;
+	cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp);
+	cp->irq_arr[1].status_blk = bp->def_status_blk;
+	cp->irq_arr[1].status_blk_num = DEF_SB_ID;
+
+	cp->num_irq = 2;
+}
+
+static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops,
+			       void *data)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+	if (ops == NULL)
+		return -EINVAL;
+
+	if (atomic_read(&bp->intr_sem) != 0)
+		return -EBUSY;
+
+	bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!bp->cnic_kwq)
+		return -ENOMEM;
+
+	bp->cnic_kwq_cons = bp->cnic_kwq;
+	bp->cnic_kwq_prod = bp->cnic_kwq;
+	bp->cnic_kwq_last = bp->cnic_kwq + MAX_SP_DESC_CNT;
+
+	bp->cnic_spq_pending = 0;
+	bp->cnic_kwq_pending = 0;
+
+	bp->cnic_data = data;
+
+	cp->num_irq = 0;
+	cp->drv_state = CNIC_DRV_STATE_REGD;
+
+	bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp));
+
+	bnx2x_setup_cnic_irq_info(bp);
+	bnx2x_set_iscsi_eth_mac_addr(bp, 1);
+	bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
+	rcu_assign_pointer(bp->cnic_ops, ops);
+
+	return 0;
+}
+
+static int bnx2x_unregister_cnic(struct net_device *dev)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+	mutex_lock(&bp->cnic_mutex);
+	if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
+		bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
+		bnx2x_set_iscsi_eth_mac_addr(bp, 0);
+	}
+	cp->drv_state = 0;
+	rcu_assign_pointer(bp->cnic_ops, NULL);
+	mutex_unlock(&bp->cnic_mutex);
+	synchronize_rcu();
+	kfree(bp->cnic_kwq);
+	bp->cnic_kwq = NULL;
+
+	return 0;
+}
+
+struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+	cp->drv_owner = THIS_MODULE;
+	cp->chip_id = CHIP_ID(bp);
+	cp->pdev = bp->pdev;
+	cp->io_base = bp->regview;
+	cp->io_base2 = bp->doorbells;
+	cp->max_kwqe_pending = 8;
+	cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context);
+	cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1;
+	cp->ctx_tbl_len = CNIC_ILT_LINES;
+	cp->starting_cid = BCM_CNIC_CID_START;
+	cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
+	cp->drv_ctl = bnx2x_drv_ctl;
+	cp->drv_register_cnic = bnx2x_register_cnic;
+	cp->drv_unregister_cnic = bnx2x_unregister_cnic;
+
+	return cp;
+}
+EXPORT_SYMBOL(bnx2x_cnic_probe);
+
+#endif /* BCM_CNIC */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bnx2x_reg.h linux-libre-2.6.33-gnu1/drivers/net/bnx2x_reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/bnx2x_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bnx2x_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -2536,7 +2536,7 @@
 /* [RC 1] A flag to indicate that overflow error occurred in one of the
    queues. */
 #define QM_REG_OVFERROR 					 0x16805c
-/* [RC 7] the Q were the qverflow occurs */
+/* [RC 7] the Q where the overflow occurs */
 #define QM_REG_OVFQNUM						 0x168058
 /* [R 16] Pause state for physical queues 15-0 */
 #define QM_REG_PAUSESTATE0					 0x168410
@@ -4772,18 +4772,28 @@
 #define PCI_ID_VAL2					0x438
 
 
-#define MDIO_REG_BANK_CL73_IEEEB0			0x0
-#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL		0x0
+#define MDIO_REG_BANK_CL73_IEEEB0	0x0
+#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL	0x0
 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN	0x0200
 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN		0x1000
 #define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST	0x8000
 
-#define MDIO_REG_BANK_CL73_IEEEB1			0x10
-#define MDIO_CL73_IEEEB1_AN_ADV2				0x01
+#define MDIO_REG_BANK_CL73_IEEEB1	0x10
+#define MDIO_CL73_IEEEB1_AN_ADV1		0x00
+#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE			0x0400
+#define MDIO_CL73_IEEEB1_AN_ADV1_ASYMMETRIC		0x0800
+#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH		0x0C00
+#define MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK		0x0C00
+#define MDIO_CL73_IEEEB1_AN_ADV2		0x01
 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M		0x0000
 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX		0x0020
 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4		0x0040
 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR		0x0080
+#define MDIO_CL73_IEEEB1_AN_LP_ADV1		0x03
+#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE		0x0400
+#define MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC		0x0800
+#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH		0x0C00
+#define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK		0x0C00
 
 #define MDIO_REG_BANK_RX0				0x80b0
 #define MDIO_RX0_RX_STATUS				0x10
@@ -4910,6 +4920,8 @@
 
 
 #define MDIO_REG_BANK_10G_PARALLEL_DETECT		0x8130
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS		0x10
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK		0x8000
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL		0x11
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN	0x1
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK		0x13
@@ -4934,6 +4946,8 @@
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G			0x0010
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M			0x0008
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M			0x0000
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2			0x15
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED 		0x0002
 #define MDIO_SERDES_DIGITAL_MISC1				0x18
 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK			0xE000
 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M			0x0000
@@ -5115,6 +5129,7 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_8481_LED1_MASK	0xa82c
 #define MDIO_PMA_REG_8481_LED2_MASK	0xa82f
 #define MDIO_PMA_REG_8481_LED3_MASK	0xa832
+#define MDIO_PMA_REG_8481_LED3_BLINK	0xa834
 #define MDIO_PMA_REG_8481_SIGNAL_MASK	0xa835
 #define MDIO_PMA_REG_8481_LINK_SIGNAL	0xa83b
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_3ad.c linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_3ad.c
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_3ad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_3ad.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
@@ -352,7 +354,8 @@ static u16 __get_link_speed(struct port
 		}
 	}
 
-	pr_debug("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
+	pr_debug("Port %d Received link speed %d update from adapter\n",
+		 port->actor_port_number, speed);
 	return speed;
 }
 
@@ -378,12 +381,14 @@ static u8 __get_duplex(struct port *port
 		switch (slave->duplex) {
 		case DUPLEX_FULL:
 			retval=0x1;
-			pr_debug("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
+			pr_debug("Port %d Received status full duplex update from adapter\n",
+				 port->actor_port_number);
 			break;
 		case DUPLEX_HALF:
 		default:
 			retval=0x0;
-			pr_debug("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
+			pr_debug("Port %d Received status NOT full duplex update from adapter\n",
+				 port->actor_port_number);
 			break;
 		}
 	}
@@ -446,6 +451,48 @@ static u16 __ad_timer_to_ticks(u16 timer
 /////////////////////////////////////////////////////////////////////////////////
 
 /**
+ * __choose_matched - update a port's matched variable from a received lacpdu
+ * @lacpdu: the lacpdu we've received
+ * @port: the port we're looking at
+ *
+ * Update the value of the matched variable, using parameter values from a
+ * newly received lacpdu. Parameter values for the partner carried in the
+ * received PDU are compared with the corresponding operational parameter
+ * values for the actor. Matched is set to TRUE if all of these parameters
+ * match and the PDU parameter partner_state.aggregation has the same value as
+ * actor_oper_port_state.aggregation and lacp will actively maintain the link
+ * in the aggregation. Matched is also set to TRUE if the value of
+ * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates
+ * an individual link and lacp will actively maintain the link. Otherwise,
+ * matched is set to FALSE. LACP is considered to be actively maintaining the
+ * link if either the PDU's actor_state.lacp_activity variable is TRUE or both
+ * the actor's actor_oper_port_state.lacp_activity and the PDU's
+ * partner_state.lacp_activity variables are TRUE.
+ *
+ * Note: the AD_PORT_MATCHED "variable" is not specified by 802.3ad; it is
+ * used here to implement the language from 802.3ad 43.4.9 that requires
+ * recordPDU to "match" the LACPDU parameters to the stored values.
+ */
+static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
+{
+	// check if all parameters are alike
+	if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
+	     (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
+	     !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
+	     (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
+	     (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
+	     ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
+	    // or this is individual link(aggregation == FALSE)
+	    ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
+		) {
+		// update the state machine Matched variable
+		port->sm_vars |= AD_PORT_MATCHED;
+	} else {
+		port->sm_vars &= ~AD_PORT_MATCHED;
+	}
+}
+
+/**
  * __record_pdu - record parameters from a received lacpdu
  * @lacpdu: the lacpdu we've received
  * @port: the port we're looking at
@@ -459,6 +506,7 @@ static void __record_pdu(struct lacpdu *
 	if (lacpdu && port) {
 		struct port_params *partner = &port->partner_oper;
 
+		__choose_matched(lacpdu, port);
 		// record the new parameter values for the partner operational
 		partner->port_number = ntohs(lacpdu->actor_port);
 		partner->port_priority = ntohs(lacpdu->actor_port_priority);
@@ -518,12 +566,12 @@ static void __update_selected(struct lac
 		const struct port_params *partner = &port->partner_oper;
 
 		// check if any parameter is different
-		if (ntohs(lacpdu->actor_port) != partner->port_number
-		    || ntohs(lacpdu->actor_port_priority) != partner->port_priority
-		    || MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system)
-		    || ntohs(lacpdu->actor_system_priority) != partner->system_priority
-		    || ntohs(lacpdu->actor_key) != partner->key
-		    || (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) {
+		if (ntohs(lacpdu->actor_port) != partner->port_number ||
+		    ntohs(lacpdu->actor_port_priority) != partner->port_priority ||
+		    MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system) ||
+		    ntohs(lacpdu->actor_system_priority) != partner->system_priority ||
+		    ntohs(lacpdu->actor_key) != partner->key ||
+		    (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) {
 			// update the state machine Selected variable
 			port->sm_vars &= ~AD_PORT_SELECTED;
 		}
@@ -549,12 +597,12 @@ static void __update_default_selected(st
 		const struct port_params *oper = &port->partner_oper;
 
 		// check if any parameter is different
-		if (admin->port_number != oper->port_number
-		    || admin->port_priority != oper->port_priority
-		    || MAC_ADDRESS_COMPARE(&admin->system, &oper->system)
-		    || admin->system_priority != oper->system_priority
-		    || admin->key != oper->key
-		    || (admin->port_state & AD_STATE_AGGREGATION)
+		if (admin->port_number != oper->port_number ||
+		    admin->port_priority != oper->port_priority ||
+		    MAC_ADDRESS_COMPARE(&admin->system, &oper->system) ||
+		    admin->system_priority != oper->system_priority ||
+		    admin->key != oper->key ||
+		    (admin->port_state & AD_STATE_AGGREGATION)
 			!= (oper->port_state & AD_STATE_AGGREGATION)) {
 			// update the state machine Selected variable
 			port->sm_vars &= ~AD_PORT_SELECTED;
@@ -563,47 +611,6 @@ static void __update_default_selected(st
 }
 
 /**
- * __choose_matched - update a port's matched variable from a received lacpdu
- * @lacpdu: the lacpdu we've received
- * @port: the port we're looking at
- *
- * Update the value of the matched variable, using parameter values from a
- * newly received lacpdu. Parameter values for the partner carried in the
- * received PDU are compared with the corresponding operational parameter
- * values for the actor. Matched is set to TRUE if all of these parameters
- * match and the PDU parameter partner_state.aggregation has the same value as
- * actor_oper_port_state.aggregation and lacp will actively maintain the link
- * in the aggregation. Matched is also set to TRUE if the value of
- * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates
- * an individual link and lacp will actively maintain the link. Otherwise,
- * matched is set to FALSE. LACP is considered to be actively maintaining the
- * link if either the PDU's actor_state.lacp_activity variable is TRUE or both
- * the actor's actor_oper_port_state.lacp_activity and the PDU's
- * partner_state.lacp_activity variables are TRUE.
- */
-static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
-{
-	// validate lacpdu and port
-	if (lacpdu && port) {
-		// check if all parameters are alike
-		if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
-		     (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
-		     !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
-		     (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
-		     (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
-		     ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
-		    // or this is individual link(aggregation == FALSE)
-		    ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
-		   ) {
-			// update the state machine Matched variable
-			port->sm_vars |= AD_PORT_MATCHED;
-		} else {
-			port->sm_vars &= ~AD_PORT_MATCHED;
-		}
-	}
-}
-
-/**
  * __update_ntt - update a port's ntt variable from a received lacpdu
  * @lacpdu: the lacpdu we've received
  * @port: the port we're looking at
@@ -978,7 +985,9 @@ static void ad_mux_machine(struct port *
 
 	// check if the state machine was changed
 	if (port->sm_mux_state != last_state) {
-		pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
+		pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n",
+			 port->actor_port_number, last_state,
+			 port->sm_mux_state);
 		switch (port->sm_mux_state) {
 		case AD_MUX_DETACHED:
 			__detach_bond_from_agg(port);
@@ -1077,7 +1086,9 @@ static void ad_rx_machine(struct lacpdu
 
 	// check if the State machine was changed or new lacpdu arrived
 	if ((port->sm_rx_state != last_state) || (lacpdu)) {
-		pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
+		pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n",
+			 port->actor_port_number, last_state,
+			 port->sm_rx_state);
 		switch (port->sm_rx_state) {
 		case AD_RX_INITIALIZE:
 			if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
@@ -1124,9 +1135,8 @@ static void ad_rx_machine(struct lacpdu
 			// detect loopback situation
 			if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
 				// INFO_RECEIVED_LOOPBACK_FRAMES
-				pr_err(DRV_NAME ": %s: An illegal loopback occurred on "
-				       "adapter (%s). Check the configuration to verify that all "
-				       "Adapters are connected to 802.3ad compliant switch ports\n",
+				pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
+				       "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
 				       port->slave->dev->master->name, port->slave->dev->name);
 				__release_rx_machine_lock(port);
 				return;
@@ -1134,7 +1144,6 @@ static void ad_rx_machine(struct lacpdu
 			__update_selected(lacpdu, port);
 			__update_ntt(lacpdu, port);
 			__record_pdu(lacpdu, port);
-			__choose_matched(lacpdu, port);
 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT));
 			port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
 			// verify that if the aggregator is enabled, the port is enabled too.
@@ -1165,7 +1174,8 @@ static void ad_tx_machine(struct port *p
 			__update_lacpdu_from_port(port);
 
 			if (ad_lacpdu_send(port) >= 0) {
-				pr_debug("Sent LACPDU on port %d\n", port->actor_port_number);
+				pr_debug("Sent LACPDU on port %d\n",
+					 port->actor_port_number);
 
 				/* mark ntt as false, so it will not be sent again until
 				   demanded */
@@ -1240,7 +1250,9 @@ static void ad_periodic_machine(struct p
 
 	// check if the state machine was changed
 	if (port->sm_periodic_state != last_state) {
-		pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
+		pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n",
+			 port->actor_port_number, last_state,
+			 port->sm_periodic_state);
 		switch (port->sm_periodic_state) {
 		case AD_NO_PERIODIC:
 			port->sm_periodic_timer_counter = 0;	   // zero timer
@@ -1297,7 +1309,9 @@ static void ad_port_selection_logic(stru
 				port->next_port_in_aggregator=NULL;
 				port->actor_port_aggregator_identifier=0;
 
-				pr_debug("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
+				pr_debug("Port %d left LAG %d\n",
+					 port->actor_port_number,
+					 temp_aggregator->aggregator_identifier);
 				// if the aggregator is empty, clear its parameters, and set it ready to be attached
 				if (!temp_aggregator->lag_ports) {
 					ad_clear_agg(temp_aggregator);
@@ -1306,9 +1320,7 @@ static void ad_port_selection_logic(stru
 			}
 		}
 		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-			pr_warning(DRV_NAME ": %s: Warning: Port %d (on %s) "
-				   "was related to aggregator %d but was not "
-				   "on its port list\n",
+			pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
 				   port->slave->dev->master->name,
 				   port->actor_port_number,
 				   port->slave->dev->name,
@@ -1342,7 +1354,9 @@ static void ad_port_selection_logic(stru
 			port->next_port_in_aggregator=aggregator->lag_ports;
 			port->aggregator->num_of_ports++;
 			aggregator->lag_ports=port;
-			pr_debug("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+			pr_debug("Port %d joined LAG %d(existing LAG)\n",
+				 port->actor_port_number,
+				 port->aggregator->aggregator_identifier);
 
 			// mark this port as selected
 			port->sm_vars |= AD_PORT_SELECTED;
@@ -1379,10 +1393,11 @@ static void ad_port_selection_logic(stru
 			// mark this port as selected
 			port->sm_vars |= AD_PORT_SELECTED;
 
-			pr_debug("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+			pr_debug("Port %d joined LAG %d(new LAG)\n",
+				 port->actor_port_number,
+				 port->aggregator->aggregator_identifier);
 		} else {
-			pr_err(DRV_NAME ": %s: Port %d (on %s) did not find "
-			       "a suitable aggregator\n",
+			pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n",
 			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name);
 		}
@@ -1459,8 +1474,7 @@ static struct aggregator *ad_agg_selecti
 		break;
 
 	default:
-		pr_warning(DRV_NAME
-			   ": %s: Impossible agg select mode %d\n",
+		pr_warning("%s: Impossible agg select mode %d\n",
 			   curr->slave->dev->master->name,
 			   __get_agg_selection_mode(curr->lag_ports));
 		break;
@@ -1545,40 +1559,38 @@ static void ad_agg_selection_logic(struc
 	// if there is new best aggregator, activate it
 	if (best) {
 		pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
-		       best->aggregator_identifier, best->num_of_ports,
-		       best->actor_oper_aggregator_key,
-		       best->partner_oper_aggregator_key,
-		       best->is_individual, best->is_active);
+			 best->aggregator_identifier, best->num_of_ports,
+			 best->actor_oper_aggregator_key,
+			 best->partner_oper_aggregator_key,
+			 best->is_individual, best->is_active);
 		pr_debug("best ports %p slave %p %s\n",
-		       best->lag_ports, best->slave,
-		       best->slave ? best->slave->dev->name : "NULL");
+			 best->lag_ports, best->slave,
+			 best->slave ? best->slave->dev->name : "NULL");
 
 		for (agg = __get_first_agg(best->lag_ports); agg;
 		     agg = __get_next_agg(agg)) {
 
 			pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
-				agg->aggregator_identifier, agg->num_of_ports,
-				agg->actor_oper_aggregator_key,
-				agg->partner_oper_aggregator_key,
-				agg->is_individual, agg->is_active);
+				 agg->aggregator_identifier, agg->num_of_ports,
+				 agg->actor_oper_aggregator_key,
+				 agg->partner_oper_aggregator_key,
+				 agg->is_individual, agg->is_active);
 		}
 
 		// check if any partner replys
 		if (best->is_individual) {
-			pr_warning(DRV_NAME ": %s: Warning: No 802.3ad"
-			       " response from the link partner for any"
-			       " adapters in the bond\n",
-			       best->slave->dev->master->name);
+			pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
+				   best->slave ? best->slave->dev->master->name : "NULL");
 		}
 
 		best->is_active = 1;
 		pr_debug("LAG %d chosen as the active LAG\n",
-			best->aggregator_identifier);
+			 best->aggregator_identifier);
 		pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
-			best->aggregator_identifier, best->num_of_ports,
-			best->actor_oper_aggregator_key,
-			best->partner_oper_aggregator_key,
-			best->is_individual, best->is_active);
+			 best->aggregator_identifier, best->num_of_ports,
+			 best->actor_oper_aggregator_key,
+			 best->partner_oper_aggregator_key,
+			 best->is_individual, best->is_active);
 
 		// disable the ports that were related to the former active_aggregator
 		if (active) {
@@ -1632,7 +1644,8 @@ static void ad_clear_agg(struct aggregat
 		aggregator->lag_ports = NULL;
 		aggregator->is_active = 0;
 		aggregator->num_of_ports = 0;
-		pr_debug("LAG %d was cleared\n", aggregator->aggregator_identifier);
+		pr_debug("LAG %d was cleared\n",
+			 aggregator->aggregator_identifier);
 	}
 }
 
@@ -1727,7 +1740,9 @@ static void ad_initialize_port(struct po
 static void ad_enable_collecting_distributing(struct port *port)
 {
 	if (port->aggregator->is_active) {
-		pr_debug("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+		pr_debug("Enabling port %d(LAG %d)\n",
+			 port->actor_port_number,
+			 port->aggregator->aggregator_identifier);
 		__enable_port(port);
 	}
 }
@@ -1740,7 +1755,9 @@ static void ad_enable_collecting_distrib
 static void ad_disable_collecting_distributing(struct port *port)
 {
 	if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
-		pr_debug("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+		pr_debug("Disabling port %d(LAG %d)\n",
+			 port->actor_port_number,
+			 port->aggregator->aggregator_identifier);
 		__disable_port(port);
 	}
 }
@@ -1778,7 +1795,8 @@ static void ad_marker_info_send(struct p
 
 	// send the marker information
 	if (ad_marker_send(port, &marker) >= 0) {
-		pr_debug("Sent Marker Information on port %d\n", port->actor_port_number);
+		pr_debug("Sent Marker Information on port %d\n",
+			 port->actor_port_number);
 	}
 }
 #endif
@@ -1802,7 +1820,8 @@ static void ad_marker_info_received(stru
 	// send the marker response
 
 	if (ad_marker_send(port, &marker) >= 0) {
-		pr_debug("Sent Marker Response on port %d\n", port->actor_port_number);
+		pr_debug("Sent Marker Response on port %d\n",
+			 port->actor_port_number);
 	}
 }
 
@@ -1888,8 +1907,7 @@ int bond_3ad_bind_slave(struct slave *sl
 	struct aggregator *aggregator;
 
 	if (bond == NULL) {
-		pr_err(DRV_NAME ": %s: The slave %s is not attached to "
-		       "its bond\n",
+		pr_err("%s: The slave %s is not attached to its bond\n",
 		       slave->dev->master->name, slave->dev->name);
 		return -1;
 	}
@@ -1956,7 +1974,7 @@ void bond_3ad_unbind_slave(struct slave
 	struct port *port, *prev_port, *temp_port;
 	struct aggregator *aggregator, *new_aggregator, *temp_aggregator;
 	int select_new_active_agg = 0;
-	
+
 	// find the aggregator related to this slave
 	aggregator = &(SLAVE_AD_INFO(slave).aggregator);
 
@@ -1965,13 +1983,13 @@ void bond_3ad_unbind_slave(struct slave
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		pr_warning(DRV_NAME ": Warning: %s: Trying to "
-			   "unbind an uninitialized port on %s\n",
+		pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n",
 			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
-	pr_debug("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
+	pr_debug("Unbinding Link Aggregation Group %d\n",
+		 aggregator->aggregator_identifier);
 
 	/* Tell the partner that this port is not suitable for aggregation */
 	port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
@@ -1995,10 +2013,12 @@ void bond_3ad_unbind_slave(struct slave
 			// if new aggregator found, copy the aggregator's parameters
 			// and connect the related lag_ports to the new aggregator
 			if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
-				pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
+				pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n",
+					 aggregator->aggregator_identifier,
+					 new_aggregator->aggregator_identifier);
 
 				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-					pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+					pr_info("%s: Removing an active aggregator\n",
 						aggregator->slave->dev->master->name);
 					// select new active aggregator
 					 select_new_active_agg = 1;
@@ -2024,13 +2044,12 @@ void bond_3ad_unbind_slave(struct slave
 
 				// clear the aggregator
 				ad_clear_agg(aggregator);
-				
+
 				if (select_new_active_agg) {
 					ad_agg_selection_logic(__get_first_agg(port));
 				}
 			} else {
-				pr_warning(DRV_NAME ": %s: Warning: unbinding aggregator, "
-					   "and could not find a new aggregator for its ports\n",
+				pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
 					   slave->dev->master->name);
 			}
 		} else { // in case that the only port related to this aggregator is the one we want to remove
@@ -2038,7 +2057,7 @@ void bond_3ad_unbind_slave(struct slave
 			// clear the aggregator
 			ad_clear_agg(aggregator);
 			if (select_new_active_agg) {
-				pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+				pr_info("%s: Removing an active aggregator\n",
 					slave->dev->master->name);
 				// select new active aggregator
 				ad_agg_selection_logic(__get_first_agg(port));
@@ -2065,7 +2084,7 @@ void bond_3ad_unbind_slave(struct slave
 					// clear the aggregator
 					ad_clear_agg(temp_aggregator);
 					if (select_new_active_agg) {
-						pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+						pr_info("%s: Removing an active aggregator\n",
 							slave->dev->master->name);
 						// select new active aggregator
 						ad_agg_selection_logic(__get_first_agg(port));
@@ -2075,7 +2094,7 @@ void bond_3ad_unbind_slave(struct slave
 			}
 		}
 	}
-	port->slave=NULL;	
+	port->slave=NULL;
 }
 
 /**
@@ -2114,8 +2133,8 @@ void bond_3ad_state_machine_handler(stru
 		// select the active aggregator for the bond
 		if ((port = __get_first_port(bond))) {
 			if (!port->slave) {
-				pr_warning(DRV_NAME ": %s: Warning: bond's first port is "
-					   "uninitialized\n", bond->dev->name);
+				pr_warning("%s: Warning: bond's first port is uninitialized\n",
+					   bond->dev->name);
 				goto re_arm;
 			}
 
@@ -2128,8 +2147,8 @@ void bond_3ad_state_machine_handler(stru
 	// for each port run the state machines
 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
 		if (!port->slave) {
-			pr_warning(DRV_NAME ": %s: Warning: Found an uninitialized "
-				   "port\n", bond->dev->name);
+			pr_warning("%s: Warning: Found an uninitialized port\n",
+				   bond->dev->name);
 			goto re_arm;
 		}
 
@@ -2170,15 +2189,15 @@ static void bond_3ad_rx_indication(struc
 		port = &(SLAVE_AD_INFO(slave).port);
 
 		if (!port->slave) {
-			pr_warning(DRV_NAME ": %s: Warning: port of slave %s "
-				   "is uninitialized\n",
+			pr_warning("%s: Warning: port of slave %s is uninitialized\n",
 				   slave->dev->name, slave->dev->master->name);
 			return;
 		}
 
 		switch (lacpdu->subtype) {
 		case AD_TYPE_LACPDU:
-			pr_debug("Received LACPDU on port %d\n", port->actor_port_number);
+			pr_debug("Received LACPDU on port %d\n",
+				 port->actor_port_number);
 			ad_rx_machine(lacpdu, port);
 			break;
 
@@ -2187,17 +2206,20 @@ static void bond_3ad_rx_indication(struc
 
 			switch (((struct bond_marker *)lacpdu)->tlv_type) {
 			case AD_MARKER_INFORMATION_SUBTYPE:
-				pr_debug("Received Marker Information on port %d\n", port->actor_port_number);
+				pr_debug("Received Marker Information on port %d\n",
+					 port->actor_port_number);
 				ad_marker_info_received((struct bond_marker *)lacpdu, port);
 				break;
 
 			case AD_MARKER_RESPONSE_SUBTYPE:
-				pr_debug("Received Marker Response on port %d\n", port->actor_port_number);
+				pr_debug("Received Marker Response on port %d\n",
+					 port->actor_port_number);
 				ad_marker_response_received((struct bond_marker *)lacpdu, port);
 				break;
 
 			default:
-				pr_debug("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
+				pr_debug("Received an unknown Marker subtype on slot %d\n",
+					 port->actor_port_number);
 			}
 		}
 	}
@@ -2217,8 +2239,7 @@ void bond_3ad_adapter_speed_changed(stru
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		pr_warning(DRV_NAME ": Warning: %s: speed "
-			   "changed for uninitialized port on %s\n",
+		pr_warning("Warning: %s: speed changed for uninitialized port on %s\n",
 			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
@@ -2245,8 +2266,7 @@ void bond_3ad_adapter_duplex_changed(str
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		pr_warning(DRV_NAME ": %s: Warning: duplex changed "
-			   "for uninitialized port on %s\n",
+		pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
 			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
@@ -2274,8 +2294,7 @@ void bond_3ad_handle_link_change(struct
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		pr_warning(DRV_NAME ": Warning: %s: link status changed for "
-			   "uninitialized port on %s\n",
+		pr_warning("Warning: %s: link status changed for uninitialized port on %s\n",
 			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
@@ -2301,7 +2320,7 @@ void bond_3ad_handle_link_change(struct
 }
 
 /*
- * set link state for bonding master: if we have an active 
+ * set link state for bonding master: if we have an active
  * aggregator, we're up, if not, we're down.  Presumes that we cannot
  * have an active aggregator if there are no slaves with link up.
  *
@@ -2380,8 +2399,8 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
 	}
 
 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-		pr_debug(DRV_NAME ": %s: Error: "
-			 "bond_3ad_get_active_agg_info failed\n", dev->name);
+		pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
+			 dev->name);
 		goto out;
 	}
 
@@ -2390,12 +2409,11 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
 
 	if (slaves_in_agg == 0) {
 		/*the aggregator is empty*/
-		pr_debug(DRV_NAME ": %s: Error: active aggregator is empty\n",
-			 dev->name);
+		pr_debug("%s: Error: active aggregator is empty\n", dev->name);
 		goto out;
 	}
 
-	slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
+	slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
 
 	bond_for_each_slave(bond, slave, i) {
 		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
@@ -2409,8 +2427,8 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
 	}
 
 	if (slave_agg_no >= 0) {
-		pr_err(DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
-		       "for aggregator ID %d\n", dev->name, agg_id);
+		pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n",
+		       dev->name, agg_id);
 		goto out;
 	}
 
@@ -2445,9 +2463,6 @@ int bond_3ad_lacpdu_recv(struct sk_buff
 	struct slave *slave = NULL;
 	int ret = NET_RX_DROP;
 
-	if (dev_net(dev) != &init_net)
-		goto out;
-
 	if (!(dev->flags & IFF_MASTER))
 		goto out;
 
@@ -2468,4 +2483,3 @@ out:
 
 	return ret;
 }
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_alb.c linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_alb.c
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_alb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_alb.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -201,8 +203,7 @@ static int tlb_initialize(struct bonding
 
 	new_hashtbl = kzalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
-		pr_err(DRV_NAME
-		       ": %s: Error: Failed to allocate TLB hash table\n",
+		pr_err("%s: Error: Failed to allocate TLB hash table\n",
 		       bond->dev->name);
 		return -1;
 	}
@@ -355,9 +356,6 @@ static int rlb_arp_recv(struct sk_buff *
 	struct arp_pkt *arp = (struct arp_pkt *)skb->data;
 	int res = NET_RX_DROP;
 
-	if (dev_net(bond_dev) != &init_net)
-		goto out;
-
 	while (bond_dev->priv_flags & IFF_802_1Q_VLAN)
 		bond_dev = vlan_dev_real_dev(bond_dev);
 
@@ -517,8 +515,7 @@ static void rlb_update_client(struct rlb
 				 client_info->slave->dev->dev_addr,
 				 client_info->mac_dst);
 		if (!skb) {
-			pr_err(DRV_NAME
-			       ": %s: Error: failed to create an ARP packet\n",
+			pr_err("%s: Error: failed to create an ARP packet\n",
 			       client_info->slave->dev->master->name);
 			continue;
 		}
@@ -528,8 +525,7 @@ static void rlb_update_client(struct rlb
 		if (client_info->tag) {
 			skb = vlan_put_tag(skb, client_info->vlan_id);
 			if (!skb) {
-				pr_err(DRV_NAME
-				       ": %s: Error: failed to insert VLAN tag\n",
+				pr_err("%s: Error: failed to insert VLAN tag\n",
 				       client_info->slave->dev->master->name);
 				continue;
 			}
@@ -559,7 +555,7 @@ static void rlb_update_rx_clients(struct
 		}
 	}
 
-	/* do not update the entries again untill this counter is zero so that
+	/* do not update the entries again until this counter is zero so that
 	 * not to confuse the clients.
 	 */
 	bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY;
@@ -612,9 +608,7 @@ static void rlb_req_update_subnet_client
 		client_info = &(bond_info->rx_hashtbl[hash_index]);
 
 		if (!client_info->slave) {
-			pr_err(DRV_NAME
-			       ": %s: Error: found a client with no channel in "
-			       "the client's hash table\n",
+			pr_err("%s: Error: found a client with no channel in the client's hash table\n",
 			       bond->dev->name);
 			continue;
 		}
@@ -809,8 +803,7 @@ static int rlb_initialize(struct bonding
 
 	new_hashtbl = kmalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
-		pr_err(DRV_NAME
-		       ": %s: Error: Failed to allocate RLB hash table\n",
+		pr_err("%s: Error: Failed to allocate RLB hash table\n",
 		       bond->dev->name);
 		return -1;
 	}
@@ -931,8 +924,7 @@ static void alb_send_learning_packets(st
 
 			skb = vlan_put_tag(skb, vlan->vlan_id);
 			if (!skb) {
-				pr_err(DRV_NAME
-				       ": %s: Error: failed to insert VLAN tag\n",
+				pr_err("%s: Error: failed to insert VLAN tag\n",
 				       bond->dev->name);
 				continue;
 			}
@@ -961,11 +953,8 @@ static int alb_set_slave_mac_addr(struct
 	memcpy(s_addr.sa_data, addr, dev->addr_len);
 	s_addr.sa_family = dev->type;
 	if (dev_set_mac_address(dev, &s_addr)) {
-		pr_err(DRV_NAME
-		       ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
-		       "mode requires that the base driver support setting "
-		       "the hw address also when the network device's "
-		       "interface is open\n",
+		pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n"
+		       "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
 		       dev->master->name, dev->name);
 		return -EOPNOTSUPP;
 	}
@@ -1172,18 +1161,12 @@ static int alb_handle_addr_collision_on_
 		alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
 				       bond->alb_info.rlb_enabled);
 
-		pr_warning(DRV_NAME
-			   ": %s: Warning: the hw address of slave %s is "
-			   "in use by the bond; giving it the hw address "
-			   "of %s\n",
+		pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
 			   bond->dev->name, slave->dev->name,
 			   free_mac_slave->dev->name);
 
 	} else if (has_bond_addr) {
-		pr_err(DRV_NAME
-		       ": %s: Error: the hw address of slave %s is in use by the "
-		       "bond; couldn't find a slave with a free hw address to "
-		       "give it (this should not have happened)\n",
+		pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n",
 		       bond->dev->name, slave->dev->name);
 		return -EFAULT;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bonding.h linux-libre-2.6.33-gnu1/drivers/net/bonding/bonding.h
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bonding.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bonding.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,15 +23,13 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"3.5.0"
-#define DRV_RELDATE	"November 4, 2008"
+#define DRV_VERSION	"3.6.0"
+#define DRV_RELDATE	"September 26, 2009"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
 #define BOND_MAX_ARP_TARGETS	16
 
-extern struct list_head bond_dev_list;
-
 #define IS_UP(dev)					   \
 	      ((((dev)->flags & IFF_UP) == IFF_UP)	&& \
 	       netif_running(dev)			&& \
@@ -131,6 +129,7 @@ struct bond_params {
 	int lacp_fast;
 	int ad_select;
 	char primary[IFNAMSIZ];
+	int primary_reselect;
 	__be32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
 
@@ -190,6 +189,7 @@ struct bonding {
 	struct   slave *curr_active_slave;
 	struct   slave *current_arp_slave;
 	struct   slave *primary_slave;
+	bool     force_primary;
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
 	rwlock_t lock;
 	rwlock_t curr_slave_lock;
@@ -204,7 +204,7 @@ struct bonding {
 #endif /* CONFIG_PROC_FS */
 	struct   list_head bond_list;
 	struct   dev_mc_list *mc_list;
-	int      (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
+	int      (*xmit_hash_policy)(struct sk_buff *, int);
 	__be32   master_ip;
 	u16      flags;
 	u16      rr_tx_counter;
@@ -254,10 +254,14 @@ static inline struct bonding *bond_get_b
 
 static inline bool bond_is_lb(const struct bonding *bond)
 {
-	return bond->params.mode == BOND_MODE_TLB
-		|| bond->params.mode == BOND_MODE_ALB;
+	return (bond->params.mode == BOND_MODE_TLB ||
+		bond->params.mode == BOND_MODE_ALB);
 }
 
+#define BOND_PRI_RESELECT_ALWAYS	0
+#define BOND_PRI_RESELECT_BETTER	1
+#define BOND_PRI_RESELECT_FAILURE	2
+
 #define BOND_FOM_NONE			0
 #define BOND_FOM_ACTIVE			1
 #define BOND_FOM_FOLLOW			2
@@ -321,12 +325,11 @@ static inline void bond_unset_master_alb
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(const char *name);
+int bond_create(struct net *net, const char *name);
 int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);
-void bond_destroy_sysfs_entry(struct bonding *bond);
-int bond_create_sysfs_entry(struct bonding *bond);
+void bond_prepare_sysfs_group(struct bonding *bond);
 int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
 void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
@@ -341,13 +344,22 @@ void bond_change_active_slave(struct bon
 void bond_register_arp(struct bonding *);
 void bond_unregister_arp(struct bonding *);
 
+struct bond_net {
+	struct net *		net;	/* Associated network namespace */
+	struct list_head	dev_list;
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *	proc_dir;
+#endif
+};
+
 /* exported from bond_main.c */
-extern struct list_head bond_dev_list;
+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 fail_over_mac_tbl[];
+extern const struct bond_parm_tbl pri_reselect_tbl[];
 extern struct bond_parm_tbl ad_select_tbl[];
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -370,4 +382,3 @@ static inline void bond_unregister_ipv6_
 #endif
 
 #endif /* _LINUX_BONDING_H */
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_ipv6.c linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_ipv6.c
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_ipv6.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_ipv6.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,11 +20,14 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/if_vlan.h>
 #include <net/ipv6.h>
 #include <net/ndisc.h>
 #include <net/addrconf.h>
+#include <net/netns/generic.h>
 #include "bonding.h"
 
 /*
@@ -73,20 +76,20 @@ static void bond_na_send(struct net_devi
 	addrconf_addr_solict_mult(daddr, &mcaddr);
 
 	pr_debug("ipv6 na on slave %s: dest %pI6, src %pI6\n",
-	       slave_dev->name, &mcaddr, daddr);
+		 slave_dev->name, &mcaddr, daddr);
 
 	skb = ndisc_build_skb(slave_dev, &mcaddr, daddr, &icmp6h, daddr,
 			      ND_OPT_TARGET_LL_ADDR);
 
 	if (!skb) {
-		pr_err(DRV_NAME ": NA packet allocation failed\n");
+		pr_err("NA packet allocation failed\n");
 		return;
 	}
 
 	if (vlan_id) {
 		skb = vlan_put_tag(skb, vlan_id);
 		if (!skb) {
-			pr_err(DRV_NAME ": failed to insert VLAN tag\n");
+			pr_err("failed to insert VLAN tag\n");
 			return;
 		}
 	}
@@ -108,8 +111,8 @@ void bond_send_unsolicited_na(struct bon
 	struct inet6_dev *idev;
 	int is_router;
 
-	pr_debug("bond_send_unsol_na: bond %s slave %s\n", bond->dev->name,
-				slave ? slave->dev->name : "NULL");
+	pr_debug("%s: bond %s slave %s\n", bond->dev->name,
+		 __func__, slave ? slave->dev->name : "NULL");
 
 	if (!slave || !bond->send_unsol_na ||
 	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
@@ -152,11 +155,9 @@ static int bond_inet6addr_event(struct n
 	struct net_device *vlan_dev, *event_dev = ifa->idev->dev;
 	struct bonding *bond;
 	struct vlan_entry *vlan;
+	struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id);
 
-	if (dev_net(event_dev) != &init_net)
-		return NOTIFY_DONE;
-
-	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 		if (bond->dev == event_dev) {
 			switch (event) {
 			case NETDEV_UP:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_main.c linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -75,6 +77,7 @@
 #include <linux/jiffies.h>
 #include <net/route.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 #include "bond_alb.h"
@@ -94,6 +97,7 @@ static int downdelay;
 static int use_carrier	= 1;
 static char *mode;
 static char *primary;
+static char *primary_reselect;
 static char *lacp_rate;
 static char *ad_select;
 static char *xmit_hash_policy;
@@ -126,6 +130,14 @@ MODULE_PARM_DESC(mode, "Mode of operatio
 		       "6 for balance-alb");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
+module_param(primary_reselect, charp, 0);
+MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
+				   "once it comes up; "
+				   "0 for always (default), "
+				   "1 for only if speed of primary is "
+				   "better, "
+				   "2 for only on active slave "
+				   "failure");
 module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
 			    "(slow/fast)");
@@ -148,11 +160,7 @@ MODULE_PARM_DESC(fail_over_mac, "For act
 static const char * const version =
 	DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-LIST_HEAD(bond_dev_list);
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *bond_proc_dir;
-#endif
+int bond_net_id __read_mostly;
 
 static __be32 arp_target[BOND_MAX_ARP_TARGETS];
 static int arp_ip_count;
@@ -200,6 +208,13 @@ const struct bond_parm_tbl fail_over_mac
 {	NULL,			-1},
 };
 
+const struct bond_parm_tbl pri_reselect_tbl[] = {
+{	"always",		BOND_PRI_RESELECT_ALWAYS},
+{	"better",		BOND_PRI_RESELECT_BETTER},
+{	"failure",		BOND_PRI_RESELECT_FAILURE},
+{	NULL,			-1},
+};
+
 struct bond_parm_tbl ad_select_tbl[] = {
 {	"stable",	BOND_AD_STABLE},
 {	"bandwidth",	BOND_AD_BANDWIDTH},
@@ -211,7 +226,7 @@ struct bond_parm_tbl ad_select_tbl[] = {
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
 static int bond_init(struct net_device *bond_dev);
-static void bond_deinit(struct net_device *bond_dev);
+static void bond_uninit(struct net_device *bond_dev);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -247,7 +262,7 @@ static int bond_add_vlan(struct bonding
 	struct vlan_entry *vlan;
 
 	pr_debug("bond: %s, vlan id %d\n",
-		(bond ? bond->dev->name : "None"), vlan_id);
+		 (bond ? bond->dev->name : "None"), vlan_id);
 
 	vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
 	if (!vlan)
@@ -290,8 +305,8 @@ static int bond_del_vlan(struct bonding
 			if (bond_is_lb(bond))
 				bond_alb_clear_vlan(bond, vlan_id);
 
-			pr_debug("removed VLAN ID %d from bond %s\n", vlan_id,
-				bond->dev->name);
+			pr_debug("removed VLAN ID %d from bond %s\n",
+				 vlan_id, bond->dev->name);
 
 			kfree(vlan);
 
@@ -310,8 +325,8 @@ static int bond_del_vlan(struct bonding
 		}
 	}
 
-	pr_debug("couldn't find VLAN ID %d in bond %s\n", vlan_id,
-		bond->dev->name);
+	pr_debug("couldn't find VLAN ID %d in bond %s\n",
+		 vlan_id, bond->dev->name);
 
 out:
 	write_unlock_bh(&bond->lock);
@@ -335,7 +350,7 @@ static int bond_has_challenged_slaves(st
 	bond_for_each_slave(bond, slave, i) {
 		if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
 			pr_debug("found VLAN challenged slave - %s\n",
-				slave->dev->name);
+				 slave->dev->name);
 			return 1;
 		}
 	}
@@ -486,8 +501,7 @@ static void bond_vlan_rx_add_vid(struct
 
 	res = bond_add_vlan(bond, vid);
 	if (res) {
-		pr_err(DRV_NAME
-		       ": %s: Error: Failed to add vlan id %d\n",
+		pr_err("%s: Error: Failed to add vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -521,8 +535,7 @@ static void bond_vlan_rx_kill_vid(struct
 
 	res = bond_del_vlan(bond, vid);
 	if (res) {
-		pr_err(DRV_NAME
-		       ": %s: Error: Failed to remove vlan id %d\n",
+		pr_err("%s: Error: Failed to remove vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -1040,8 +1053,7 @@ static void bond_do_fail_over_mac(struct
 
 		rv = dev_set_mac_address(new_active->dev, &saddr);
 		if (rv) {
-			pr_err(DRV_NAME
-			       ": %s: Error %d setting MAC of slave %s\n",
+			pr_err("%s: Error %d setting MAC of slave %s\n",
 			       bond->dev->name, -rv, new_active->dev->name);
 			goto out;
 		}
@@ -1054,22 +1066,39 @@ static void bond_do_fail_over_mac(struct
 
 		rv = dev_set_mac_address(old_active->dev, &saddr);
 		if (rv)
-			pr_err(DRV_NAME
-			       ": %s: Error %d setting MAC of slave %s\n",
+			pr_err("%s: Error %d setting MAC of slave %s\n",
 			       bond->dev->name, -rv, new_active->dev->name);
 out:
 		read_lock(&bond->lock);
 		write_lock_bh(&bond->curr_slave_lock);
 		break;
 	default:
-		pr_err(DRV_NAME
-		       ": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
+		pr_err("%s: bond_do_fail_over_mac impossible: bad policy %d\n",
 		       bond->dev->name, bond->params.fail_over_mac);
 		break;
 	}
 
 }
 
+static bool bond_should_change_active(struct bonding *bond)
+{
+	struct slave *prim = bond->primary_slave;
+	struct slave *curr = bond->curr_active_slave;
+
+	if (!prim || !curr || curr->link != BOND_LINK_UP)
+		return true;
+	if (bond->force_primary) {
+		bond->force_primary = false;
+		return true;
+	}
+	if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
+	    (prim->speed < curr->speed ||
+	     (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
+		return false;
+	if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
+		return false;
+	return true;
+}
 
 /**
  * find_best_interface - select the best available slave to be the active one
@@ -1084,7 +1113,7 @@ static struct slave *bond_find_best_slav
 	int mintime = bond->params.updelay;
 	int i;
 
-	new_active = old_active = bond->curr_active_slave;
+	new_active = bond->curr_active_slave;
 
 	if (!new_active) { /* there were no active slaves left */
 		if (bond->slave_cnt > 0)   /* found one slave */
@@ -1094,7 +1123,8 @@ static struct slave *bond_find_best_slav
 	}
 
 	if ((bond->primary_slave) &&
-	    bond->primary_slave->link == BOND_LINK_UP) {
+	    bond->primary_slave->link == BOND_LINK_UP &&
+	    bond_should_change_active(bond)) {
 		new_active = bond->primary_slave;
 	}
 
@@ -1145,11 +1175,9 @@ void bond_change_active_slave(struct bon
 
 		if (new_active->link == BOND_LINK_BACK) {
 			if (USES_PRIMARY(bond->params.mode)) {
-				pr_info(DRV_NAME
-				       ": %s: making interface %s the new "
-				       "active one %d ms earlier.\n",
-				       bond->dev->name, new_active->dev->name,
-				       (bond->params.updelay - new_active->delay) * bond->params.miimon);
+				pr_info("%s: making interface %s the new active one %d ms earlier.\n",
+					bond->dev->name, new_active->dev->name,
+					(bond->params.updelay - new_active->delay) * bond->params.miimon);
 			}
 
 			new_active->delay = 0;
@@ -1162,10 +1190,8 @@ void bond_change_active_slave(struct bon
 				bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
 		} else {
 			if (USES_PRIMARY(bond->params.mode)) {
-				pr_info(DRV_NAME
-				       ": %s: making interface %s the new "
-				       "active one.\n",
-				       bond->dev->name, new_active->dev->name);
+				pr_info("%s: making interface %s the new active one.\n",
+					bond->dev->name, new_active->dev->name);
 			}
 		}
 	}
@@ -1235,13 +1261,11 @@ void bond_select_active_slave(struct bon
 			return;
 
 		if (netif_carrier_ok(bond->dev)) {
-			pr_info(DRV_NAME
-			       ": %s: first active interface up!\n",
-			       bond->dev->name);
+			pr_info("%s: first active interface up!\n",
+				bond->dev->name);
 		} else {
-			pr_info(DRV_NAME ": %s: "
-			       "now running without any active interface !\n",
-			       bond->dev->name);
+			pr_info("%s: now running without any active interface !\n",
+				bond->dev->name);
 		}
 	}
 }
@@ -1390,16 +1414,14 @@ int bond_enslave(struct net_device *bond
 
 	if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
 		slave_ops->ndo_do_ioctl == NULL) {
-		pr_warning(DRV_NAME
-		       ": %s: Warning: no link monitoring support for %s\n",
-		       bond_dev->name, slave_dev->name);
+		pr_warning("%s: Warning: no link monitoring support for %s\n",
+			   bond_dev->name, slave_dev->name);
 	}
 
 	/* bond must be initialized by bond_open() before enslaving */
 	if (!(bond_dev->flags & IFF_UP)) {
-		pr_warning(DRV_NAME
-			" %s: master_dev is not up in bond_enslave\n",
-			bond_dev->name);
+		pr_warning("%s: master_dev is not up in bond_enslave\n",
+			   bond_dev->name);
 	}
 
 	/* already enslaved */
@@ -1413,19 +1435,13 @@ int bond_enslave(struct net_device *bond
 	if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
 		pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
 		if (!list_empty(&bond->vlan_list)) {
-			pr_err(DRV_NAME
-			       ": %s: Error: cannot enslave VLAN "
-			       "challenged slave %s on VLAN enabled "
-			       "bond %s\n", bond_dev->name, slave_dev->name,
-			       bond_dev->name);
+			pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
+			       bond_dev->name, slave_dev->name, bond_dev->name);
 			return -EPERM;
 		} else {
-			pr_warning(DRV_NAME
-			       ": %s: Warning: enslaved VLAN challenged "
-			       "slave %s. Adding VLANs will be blocked as "
-			       "long as %s is part of bond %s\n",
-			       bond_dev->name, slave_dev->name, slave_dev->name,
-			       bond_dev->name);
+			pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
+				   bond_dev->name, slave_dev->name,
+				   slave_dev->name, bond_dev->name);
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		}
 	} else {
@@ -1445,8 +1461,7 @@ int bond_enslave(struct net_device *bond
 	 * enslaving it; the old ifenslave will not.
 	 */
 	if ((slave_dev->flags & IFF_UP)) {
-		pr_err(DRV_NAME ": %s is up. "
-		       "This may be due to an out of date ifenslave.\n",
+		pr_err("%s is up. This may be due to an out of date ifenslave.\n",
 		       slave_dev->name);
 		res = -EPERM;
 		goto err_undo_flags;
@@ -1462,7 +1477,8 @@ int bond_enslave(struct net_device *bond
 	if (bond->slave_cnt == 0) {
 		if (bond_dev->type != slave_dev->type) {
 			pr_debug("%s: change device type from %d to %d\n",
-				bond_dev->name, bond_dev->type, slave_dev->type);
+				 bond_dev->name,
+				 bond_dev->type, slave_dev->type);
 
 			netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE);
 
@@ -1474,28 +1490,21 @@ int bond_enslave(struct net_device *bond
 			netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE);
 		}
 	} else if (bond_dev->type != slave_dev->type) {
-		pr_err(DRV_NAME ": %s ether type (%d) is different "
-			"from other slaves (%d), can not enslave it.\n",
-			slave_dev->name,
-			slave_dev->type, bond_dev->type);
-			res = -EINVAL;
-			goto err_undo_flags;
+		pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it.\n",
+		       slave_dev->name,
+		       slave_dev->type, bond_dev->type);
+		res = -EINVAL;
+		goto err_undo_flags;
 	}
 
 	if (slave_ops->ndo_set_mac_address == NULL) {
 		if (bond->slave_cnt == 0) {
-			pr_warning(DRV_NAME
-			       ": %s: Warning: The first slave device "
-			       "specified does not support setting the MAC "
-			       "address. Setting fail_over_mac to active.",
-			       bond_dev->name);
+			pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.",
+				   bond_dev->name);
 			bond->params.fail_over_mac = BOND_FOM_ACTIVE;
 		} else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
-			pr_err(DRV_NAME
-				": %s: Error: The slave device specified "
-				"does not support setting the MAC address, "
-				"but fail_over_mac is not set to active.\n"
-				, bond_dev->name);
+			pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n",
+			       bond_dev->name);
 			res = -EOPNOTSUPP;
 			goto err_undo_flags;
 		}
@@ -1622,22 +1631,12 @@ int bond_enslave(struct net_device *bond
 			 * supported); thus, we don't need to change
 			 * the messages for netif_carrier.
 			 */
-			pr_warning(DRV_NAME
-			       ": %s: Warning: MII and ETHTOOL support not "
-			       "available for interface %s, and "
-			       "arp_interval/arp_ip_target module parameters "
-			       "not specified, thus bonding will not detect "
-			       "link failures! see bonding.txt for details.\n",
+			pr_warning("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details.\n",
 			       bond_dev->name, slave_dev->name);
 		} else if (link_reporting == -1) {
 			/* unable get link status using mii/ethtool */
-			pr_warning(DRV_NAME
-			       ": %s: Warning: can't get link status from "
-			       "interface %s; the network driver associated "
-			       "with this interface does not support MII or "
-			       "ETHTOOL link status reporting, thus miimon "
-			       "has no effect on this interface.\n",
-			       bond_dev->name, slave_dev->name);
+			pr_warning("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface.\n",
+				   bond_dev->name, slave_dev->name);
 		}
 	}
 
@@ -1645,41 +1644,36 @@ int bond_enslave(struct net_device *bond
 	if (!bond->params.miimon ||
 	    (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS)) {
 		if (bond->params.updelay) {
-			pr_debug("Initial state of slave_dev is "
-				"BOND_LINK_BACK\n");
+			pr_debug("Initial state of slave_dev is BOND_LINK_BACK\n");
 			new_slave->link  = BOND_LINK_BACK;
 			new_slave->delay = bond->params.updelay;
 		} else {
-			pr_debug("Initial state of slave_dev is "
-				"BOND_LINK_UP\n");
+			pr_debug("Initial state of slave_dev is BOND_LINK_UP\n");
 			new_slave->link  = BOND_LINK_UP;
 		}
 		new_slave->jiffies = jiffies;
 	} else {
-		pr_debug("Initial state of slave_dev is "
-			"BOND_LINK_DOWN\n");
+		pr_debug("Initial state of slave_dev is BOND_LINK_DOWN\n");
 		new_slave->link  = BOND_LINK_DOWN;
 	}
 
 	if (bond_update_speed_duplex(new_slave) &&
 	    (new_slave->link != BOND_LINK_DOWN)) {
-		pr_warning(DRV_NAME
-		       ": %s: Warning: failed to get speed and duplex from %s, "
-		       "assumed to be 100Mb/sec and Full.\n",
-		       bond_dev->name, new_slave->dev->name);
+		pr_warning("%s: Warning: failed to get speed and duplex from %s, assumed to be 100Mb/sec and Full.\n",
+			   bond_dev->name, new_slave->dev->name);
 
 		if (bond->params.mode == BOND_MODE_8023AD) {
-			pr_warning(DRV_NAME
-			       ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
-			       "support in base driver for proper aggregator "
-			       "selection.\n", bond_dev->name);
+			pr_warning("%s: Warning: Operation of 802.3ad mode requires ETHTOOL support in base driver for proper aggregator selection.\n",
+				   bond_dev->name);
 		}
 	}
 
 	if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
 		/* if there is a primary slave, remember it */
-		if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
+		if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
 			bond->primary_slave = new_slave;
+			bond->force_primary = true;
+		}
 	}
 
 	write_lock_bh(&bond->curr_slave_lock);
@@ -1742,11 +1736,10 @@ int bond_enslave(struct net_device *bond
 	if (res)
 		goto err_close;
 
-	pr_info(DRV_NAME
-	       ": %s: enslaving %s as a%s interface with a%s link.\n",
-	       bond_dev->name, slave_dev->name,
-	       new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
-	       new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
+	pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
+		bond_dev->name, slave_dev->name,
+		new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
+		new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
 
 	/* enslave is successful */
 	return 0;
@@ -1798,8 +1791,7 @@ int bond_release(struct net_device *bond
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
 	    (slave_dev->master != bond_dev)) {
-		pr_err(DRV_NAME
-		       ": %s: Error: cannot release %s.\n",
+		pr_err("%s: Error: cannot release %s.\n",
 		       bond_dev->name, slave_dev->name);
 		return -EINVAL;
 	}
@@ -1809,24 +1801,19 @@ int bond_release(struct net_device *bond
 	slave = bond_get_slave_by_dev(bond, slave_dev);
 	if (!slave) {
 		/* not a slave of this bond */
-		pr_info(DRV_NAME
-		       ": %s: %s not enslaved\n",
-		       bond_dev->name, slave_dev->name);
+		pr_info("%s: %s not enslaved\n",
+			bond_dev->name, slave_dev->name);
 		write_unlock_bh(&bond->lock);
 		return -EINVAL;
 	}
 
 	if (!bond->params.fail_over_mac) {
-		if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr)
-		    && bond->slave_cnt > 1)
-			pr_warning(DRV_NAME
-			       ": %s: Warning: the permanent HWaddr of %s - "
-			       "%pM - is still in use by %s. "
-			       "Set the HWaddr of %s to a different address "
-			       "to avoid conflicts.\n",
-			       bond_dev->name, slave_dev->name,
-			       slave->perm_hwaddr,
-			       bond_dev->name, slave_dev->name);
+		if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) &&
+		    bond->slave_cnt > 1)
+			pr_warning("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n",
+				   bond_dev->name, slave_dev->name,
+				   slave->perm_hwaddr,
+				   bond_dev->name, slave_dev->name);
 	}
 
 	/* Inform AD package of unbinding of slave. */
@@ -1837,12 +1824,10 @@ int bond_release(struct net_device *bond
 		bond_3ad_unbind_slave(slave);
 	}
 
-	pr_info(DRV_NAME
-	       ": %s: releasing %s interface %s\n",
-	       bond_dev->name,
-	       (slave->state == BOND_STATE_ACTIVE)
-	       ? "active" : "backup",
-	       slave_dev->name);
+	pr_info("%s: releasing %s interface %s\n",
+		bond_dev->name,
+		(slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
+		slave_dev->name);
 
 	oldcurrent = bond->curr_active_slave;
 
@@ -1899,21 +1884,15 @@ int bond_release(struct net_device *bond
 		if (list_empty(&bond->vlan_list)) {
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		} else {
-			pr_warning(DRV_NAME
-			       ": %s: Warning: clearing HW address of %s while it "
-			       "still has VLANs.\n",
-			       bond_dev->name, bond_dev->name);
-			pr_warning(DRV_NAME
-			       ": %s: When re-adding slaves, make sure the bond's "
-			       "HW address matches its VLANs'.\n",
-			       bond_dev->name);
+			pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
+				   bond_dev->name, bond_dev->name);
+			pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
+				   bond_dev->name);
 		}
 	} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
 		   !bond_has_challenged_slaves(bond)) {
-		pr_info(DRV_NAME
-		       ": %s: last VLAN challenged slave %s "
-		       "left bond %s. VLAN blocking is removed\n",
-		       bond_dev->name, slave_dev->name, bond_dev->name);
+		pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
+			bond_dev->name, slave_dev->name, bond_dev->name);
 		bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
 	}
 
@@ -1965,25 +1944,6 @@ int bond_release(struct net_device *bond
 }
 
 /*
-* Destroy a bonding device.
-* Must be under rtnl_lock when this function is called.
-*/
-static void bond_uninit(struct net_device *bond_dev)
-{
-	struct bonding *bond = netdev_priv(bond_dev);
-
-	bond_deinit(bond_dev);
-	bond_destroy_sysfs_entry(bond);
-
-	if (bond->wq)
-		destroy_workqueue(bond->wq);
-
-	netif_addr_lock_bh(bond_dev);
-	bond_mc_list_destroy(bond);
-	netif_addr_unlock_bh(bond_dev);
-}
-
-/*
 * First release a slave and than destroy the bond if no more slaves are left.
 * Must be under rtnl_lock when this function is called.
 */
@@ -1995,8 +1955,8 @@ int  bond_release_and_destroy(struct net
 
 	ret = bond_release(bond_dev, slave_dev);
 	if ((ret == 0) && (bond->slave_cnt == 0)) {
-		pr_info(DRV_NAME ": %s: destroying bond %s.\n",
-		       bond_dev->name, bond_dev->name);
+		pr_info("%s: destroying bond %s.\n",
+			bond_dev->name, bond_dev->name);
 		unregister_netdevice(bond_dev);
 	}
 	return ret;
@@ -2100,19 +2060,13 @@ static int bond_release_all(struct net_d
 	if (list_empty(&bond->vlan_list))
 		bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 	else {
-		pr_warning(DRV_NAME
-		       ": %s: Warning: clearing HW address of %s while it "
-		       "still has VLANs.\n",
-		       bond_dev->name, bond_dev->name);
-		pr_warning(DRV_NAME
-		       ": %s: When re-adding slaves, make sure the bond's "
-		       "HW address matches its VLANs'.\n",
-		       bond_dev->name);
+		pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
+			   bond_dev->name, bond_dev->name);
+		pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
+			   bond_dev->name);
 	}
 
-	pr_info(DRV_NAME
-	       ": %s: released all slaves\n",
-	       bond_dev->name);
+	pr_info("%s: released all slaves\n", bond_dev->name);
 
 out:
 	write_unlock_bh(&bond->lock);
@@ -2238,16 +2192,14 @@ static int bond_miimon_inspect(struct bo
 			slave->link = BOND_LINK_FAIL;
 			slave->delay = bond->params.downdelay;
 			if (slave->delay) {
-				pr_info(DRV_NAME
-				       ": %s: link status down for %s"
-				       "interface %s, disabling it in %d ms.\n",
-				       bond->dev->name,
-				       (bond->params.mode ==
-					BOND_MODE_ACTIVEBACKUP) ?
-				       ((slave->state == BOND_STATE_ACTIVE) ?
-					"active " : "backup ") : "",
-				       slave->dev->name,
-				       bond->params.downdelay * bond->params.miimon);
+				pr_info("%s: link status down for %sinterface %s, disabling it in %d ms.\n",
+					bond->dev->name,
+					(bond->params.mode ==
+					 BOND_MODE_ACTIVEBACKUP) ?
+					((slave->state == BOND_STATE_ACTIVE) ?
+					 "active " : "backup ") : "",
+					slave->dev->name,
+					bond->params.downdelay * bond->params.miimon);
 			}
 			/*FALLTHRU*/
 		case BOND_LINK_FAIL:
@@ -2257,13 +2209,11 @@ static int bond_miimon_inspect(struct bo
 				 */
 				slave->link = BOND_LINK_UP;
 				slave->jiffies = jiffies;
-				pr_info(DRV_NAME
-				       ": %s: link status up again after %d "
-				       "ms for interface %s.\n",
-				       bond->dev->name,
-				       (bond->params.downdelay - slave->delay) *
-				       bond->params.miimon,
-				       slave->dev->name);
+				pr_info("%s: link status up again after %d ms for interface %s.\n",
+					bond->dev->name,
+					(bond->params.downdelay - slave->delay) *
+					bond->params.miimon,
+					slave->dev->name);
 				continue;
 			}
 
@@ -2284,25 +2234,21 @@ static int bond_miimon_inspect(struct bo
 			slave->delay = bond->params.updelay;
 
 			if (slave->delay) {
-				pr_info(DRV_NAME
-				       ": %s: link status up for "
-				       "interface %s, enabling it in %d ms.\n",
-				       bond->dev->name, slave->dev->name,
-				       ignore_updelay ? 0 :
-				       bond->params.updelay *
-				       bond->params.miimon);
+				pr_info("%s: link status up for interface %s, enabling it in %d ms.\n",
+					bond->dev->name, slave->dev->name,
+					ignore_updelay ? 0 :
+					bond->params.updelay *
+					bond->params.miimon);
 			}
 			/*FALLTHRU*/
 		case BOND_LINK_BACK:
 			if (!link_state) {
 				slave->link = BOND_LINK_DOWN;
-				pr_info(DRV_NAME
-				       ": %s: link status down again after %d "
-				       "ms for interface %s.\n",
-				       bond->dev->name,
-				       (bond->params.updelay - slave->delay) *
-				       bond->params.miimon,
-				       slave->dev->name);
+				pr_info("%s: link status down again after %d ms for interface %s.\n",
+					bond->dev->name,
+					(bond->params.updelay - slave->delay) *
+					bond->params.miimon,
+					slave->dev->name);
 
 				continue;
 			}
@@ -2350,10 +2296,8 @@ static void bond_miimon_commit(struct bo
 				slave->state = BOND_STATE_BACKUP;
 			}
 
-			pr_info(DRV_NAME
-			       ": %s: link status definitely "
-			       "up for interface %s.\n",
-			       bond->dev->name, slave->dev->name);
+			pr_info("%s: link status definitely up for interface %s.\n",
+				bond->dev->name, slave->dev->name);
 
 			/* notify ad that the link status has changed */
 			if (bond->params.mode == BOND_MODE_8023AD)
@@ -2379,10 +2323,8 @@ static void bond_miimon_commit(struct bo
 			    bond->params.mode == BOND_MODE_8023AD)
 				bond_set_slave_inactive_flags(slave);
 
-			pr_info(DRV_NAME
-			       ": %s: link status definitely down for "
-			       "interface %s, disabling it\n",
-			       bond->dev->name, slave->dev->name);
+			pr_info("%s: link status definitely down for interface %s, disabling it\n",
+				bond->dev->name, slave->dev->name);
 
 			if (bond->params.mode == BOND_MODE_8023AD)
 				bond_3ad_handle_link_change(slave,
@@ -2398,8 +2340,7 @@ static void bond_miimon_commit(struct bo
 			continue;
 
 		default:
-			pr_err(DRV_NAME
-			       ": %s: invalid new link %d on slave %s\n",
+			pr_err("%s: invalid new link %d on slave %s\n",
 			       bond->dev->name, slave->new_link,
 			       slave->dev->name);
 			slave->new_link = BOND_LINK_NOCHANGE;
@@ -2518,19 +2459,19 @@ static void bond_arp_send(struct net_dev
 	struct sk_buff *skb;
 
 	pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
-	       slave_dev->name, dest_ip, src_ip, vlan_id);
+		 slave_dev->name, dest_ip, src_ip, vlan_id);
 
 	skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
 			 NULL, slave_dev->dev_addr, NULL);
 
 	if (!skb) {
-		pr_err(DRV_NAME ": ARP packet allocation failed\n");
+		pr_err("ARP packet allocation failed\n");
 		return;
 	}
 	if (vlan_id) {
 		skb = vlan_put_tag(skb, vlan_id);
 		if (!skb) {
-			pr_err(DRV_NAME ": failed to insert VLAN tag\n");
+			pr_err("failed to insert VLAN tag\n");
 			return;
 		}
 	}
@@ -2567,12 +2508,11 @@ static void bond_arp_send_all(struct bon
 		fl.fl4_dst = targets[i];
 		fl.fl4_tos = RTO_ONLINK;
 
-		rv = ip_route_output_key(&init_net, &rt, &fl);
+		rv = ip_route_output_key(dev_net(bond->dev), &rt, &fl);
 		if (rv) {
 			if (net_ratelimit()) {
-				pr_warning(DRV_NAME
-			     ": %s: no route to arp_ip_target %pI4\n",
-				       bond->dev->name, &fl.fl4_dst);
+				pr_warning("%s: no route to arp_ip_target %pI4\n",
+					   bond->dev->name, &fl.fl4_dst);
 			}
 			continue;
 		}
@@ -2607,10 +2547,9 @@ static void bond_arp_send_all(struct bon
 		}
 
 		if (net_ratelimit()) {
-			pr_warning(DRV_NAME
-	       ": %s: no path to arp_ip_target %pI4 via rt.dev %s\n",
-			       bond->dev->name, &fl.fl4_dst,
-			       rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
+			pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
+				   bond->dev->name, &fl.fl4_dst,
+				   rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
 		}
 		ip_rt_put(rt);
 	}
@@ -2628,8 +2567,8 @@ static void bond_send_gratuitous_arp(str
 	struct vlan_entry *vlan;
 	struct net_device *vlan_dev;
 
-	pr_debug("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
-				slave ? slave->dev->name : "NULL");
+	pr_debug("bond_send_grat_arp: bond %s slave %s\n",
+		 bond->dev->name, slave ? slave->dev->name : "NULL");
 
 	if (!slave || !bond->send_grat_arp ||
 	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
@@ -2658,7 +2597,8 @@ static void bond_validate_arp(struct bon
 
 	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));
+			 &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;
@@ -2675,9 +2615,6 @@ static int bond_arp_rcv(struct sk_buff *
 	unsigned char *arp_ptr;
 	__be32 sip, tip;
 
-	if (dev_net(dev) != &init_net)
-		goto out;
-
 	if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
 		goto out;
 
@@ -2685,8 +2622,8 @@ static int bond_arp_rcv(struct sk_buff *
 	read_lock(&bond->lock);
 
 	pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
-		bond->dev->name, skb->dev ? skb->dev->name : "NULL",
-		orig_dev ? orig_dev->name : "NULL");
+		 bond->dev->name, skb->dev ? skb->dev->name : "NULL",
+		 orig_dev ? orig_dev->name : "NULL");
 
 	slave = bond_get_slave_by_dev(bond, orig_dev);
 	if (!slave || !slave_do_arp_validate(bond, slave))
@@ -2711,9 +2648,9 @@ static int bond_arp_rcv(struct sk_buff *
 	memcpy(&tip, arp_ptr, 4);
 
 	pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
-		bond->dev->name, slave->dev->name, slave->state,
-		bond->params.arp_validate, slave_do_arp_validate(bond, slave),
-		&sip, &tip);
+		 bond->dev->name, slave->dev->name, slave->state,
+		 bond->params.arp_validate, slave_do_arp_validate(bond, slave),
+		 &sip, &tip);
 
 	/*
 	 * Backup slaves won't see the ARP reply, but do come through
@@ -2787,17 +2724,14 @@ void bond_loadbalance_arp_mon(struct wor
 				 * is closed.
 				 */
 				if (!oldcurrent) {
-					pr_info(DRV_NAME
-					       ": %s: link status definitely "
-					       "up for interface %s, ",
-					       bond->dev->name,
-					       slave->dev->name);
+					pr_info("%s: link status definitely up for interface %s, ",
+						bond->dev->name,
+						slave->dev->name);
 					do_failover = 1;
 				} else {
-					pr_info(DRV_NAME
-					       ": %s: interface %s is now up\n",
-					       bond->dev->name,
-					       slave->dev->name);
+					pr_info("%s: interface %s is now up\n",
+						bond->dev->name,
+						slave->dev->name);
 				}
 			}
 		} else {
@@ -2816,10 +2750,9 @@ void bond_loadbalance_arp_mon(struct wor
 				if (slave->link_failure_count < UINT_MAX)
 					slave->link_failure_count++;
 
-				pr_info(DRV_NAME
-				       ": %s: interface %s is now down.\n",
-				       bond->dev->name,
-				       slave->dev->name);
+				pr_info("%s: interface %s is now down.\n",
+					bond->dev->name,
+					slave->dev->name);
 
 				if (slave == oldcurrent)
 					do_failover = 1;
@@ -2952,9 +2885,7 @@ static void bond_ab_arp_commit(struct bo
 				slave->link = BOND_LINK_UP;
 				bond->current_arp_slave = NULL;
 
-				pr_info(DRV_NAME
-					": %s: link status definitely "
-					"up for interface %s.\n",
+				pr_info("%s: link status definitely up for interface %s.\n",
 					bond->dev->name, slave->dev->name);
 
 				if (!bond->curr_active_slave ||
@@ -2972,9 +2903,7 @@ static void bond_ab_arp_commit(struct bo
 			slave->link = BOND_LINK_DOWN;
 			bond_set_slave_inactive_flags(slave);
 
-			pr_info(DRV_NAME
-				": %s: link status definitely down for "
-				"interface %s, disabling it\n",
+			pr_info("%s: link status definitely down for interface %s, disabling it\n",
 				bond->dev->name, slave->dev->name);
 
 			if (slave == bond->curr_active_slave) {
@@ -2985,8 +2914,7 @@ static void bond_ab_arp_commit(struct bo
 			continue;
 
 		default:
-			pr_err(DRV_NAME
-			       ": %s: impossible: new_link %d on slave %s\n",
+			pr_err("%s: impossible: new_link %d on slave %s\n",
 			       bond->dev->name, slave->new_link,
 			       slave->dev->name);
 			continue;
@@ -3015,9 +2943,9 @@ static void bond_ab_arp_probe(struct bon
 	read_lock(&bond->curr_slave_lock);
 
 	if (bond->current_arp_slave && bond->curr_active_slave)
-		pr_info(DRV_NAME "PROBE: c_arp %s && cas %s BAD\n",
-		       bond->current_arp_slave->dev->name,
-		       bond->curr_active_slave->dev->name);
+		pr_info("PROBE: c_arp %s && cas %s BAD\n",
+			bond->current_arp_slave->dev->name,
+			bond->curr_active_slave->dev->name);
 
 	if (bond->curr_active_slave) {
 		bond_arp_send_all(bond, bond->curr_active_slave);
@@ -3065,9 +2993,8 @@ static void bond_ab_arp_probe(struct bon
 
 			bond_set_slave_inactive_flags(slave);
 
-			pr_info(DRV_NAME
-			       ": %s: backup interface %s is now down.\n",
-			       bond->dev->name, slave->dev->name);
+			pr_info("%s: backup interface %s is now down.\n",
+				bond->dev->name, slave->dev->name);
 		}
 	}
 }
@@ -3201,11 +3128,14 @@ static void bond_info_show_master(struct
 	}
 
 	if (USES_PRIMARY(bond->params.mode)) {
-		seq_printf(seq, "Primary Slave: %s\n",
+		seq_printf(seq, "Primary Slave: %s",
 			   (bond->primary_slave) ?
 			   bond->primary_slave->dev->name : "None");
+		if (bond->primary_slave)
+			seq_printf(seq, " (primary_reselect %s)",
+		   pri_reselect_tbl[bond->params.primary_reselect].modename);
 
-		seq_printf(seq, "Currently Active Slave: %s\n",
+		seq_printf(seq, "\nCurrently Active Slave: %s\n",
 			   (curr) ? curr->dev->name : "None");
 	}
 
@@ -3334,29 +3264,30 @@ static const struct file_operations bond
 	.release = seq_release,
 };
 
-static int bond_create_proc_entry(struct bonding *bond)
+static void bond_create_proc_entry(struct bonding *bond)
 {
 	struct net_device *bond_dev = bond->dev;
+	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
 
-	if (bond_proc_dir) {
+	if (bn->proc_dir) {
 		bond->proc_entry = proc_create_data(bond_dev->name,
-						    S_IRUGO, bond_proc_dir,
+						    S_IRUGO, bn->proc_dir,
 						    &bond_info_fops, bond);
 		if (bond->proc_entry == NULL)
-			pr_warning(DRV_NAME
-			       ": Warning: Cannot create /proc/net/%s/%s\n",
-			       DRV_NAME, bond_dev->name);
+			pr_warning("Warning: Cannot create /proc/net/%s/%s\n",
+				   DRV_NAME, bond_dev->name);
 		else
 			memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
 	}
-
-	return 0;
 }
 
 static void bond_remove_proc_entry(struct bonding *bond)
 {
-	if (bond_proc_dir && bond->proc_entry) {
-		remove_proc_entry(bond->proc_file_name, bond_proc_dir);
+	struct net_device *bond_dev = bond->dev;
+	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
+
+	if (bn->proc_dir && bond->proc_entry) {
+		remove_proc_entry(bond->proc_file_name, bn->proc_dir);
 		memset(bond->proc_file_name, 0, IFNAMSIZ);
 		bond->proc_entry = NULL;
 	}
@@ -3365,31 +3296,30 @@ static void bond_remove_proc_entry(struc
 /* Create the bonding directory under /proc/net, if doesn't exist yet.
  * Caller must hold rtnl_lock.
  */
-static void bond_create_proc_dir(void)
+static void bond_create_proc_dir(struct bond_net *bn)
 {
-	if (!bond_proc_dir) {
-		bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
-		if (!bond_proc_dir)
-			pr_warning(DRV_NAME
-				": Warning: cannot create /proc/net/%s\n",
-				DRV_NAME);
+	if (!bn->proc_dir) {
+		bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
+		if (!bn->proc_dir)
+			pr_warning("Warning: cannot create /proc/net/%s\n",
+				   DRV_NAME);
 	}
 }
 
 /* Destroy the bonding directory under /proc/net, if empty.
  * Caller must hold rtnl_lock.
  */
-static void bond_destroy_proc_dir(void)
+static void bond_destroy_proc_dir(struct bond_net *bn)
 {
-	if (bond_proc_dir) {
-		remove_proc_entry(DRV_NAME, init_net.proc_net);
-		bond_proc_dir = NULL;
+	if (bn->proc_dir) {
+		remove_proc_entry(DRV_NAME, bn->net->proc_net);
+		bn->proc_dir = NULL;
 	}
 }
 
 #else /* !CONFIG_PROC_FS */
 
-static int bond_create_proc_entry(struct bonding *bond)
+static void bond_create_proc_entry(struct bonding *bond)
 {
 }
 
@@ -3397,11 +3327,11 @@ static void bond_remove_proc_entry(struc
 {
 }
 
-static void bond_create_proc_dir(void)
+static void bond_create_proc_dir(struct bond_net *bn)
 {
 }
 
-static void bond_destroy_proc_dir(void)
+static void bond_destroy_proc_dir(struct bond_net *bn)
 {
 }
 
@@ -3418,9 +3348,6 @@ static int bond_event_changename(struct
 	bond_remove_proc_entry(bond);
 	bond_create_proc_entry(bond);
 
-	bond_destroy_sysfs_entry(bond);
-	bond_create_sysfs_entry(bond);
-
 	return NOTIFY_DONE;
 }
 
@@ -3432,9 +3359,6 @@ static int bond_master_netdev_event(unsi
 	switch (event) {
 	case NETDEV_CHANGENAME:
 		return bond_event_changename(event_bond);
-	case NETDEV_UNREGISTER:
-		bond_release_all(event_bond->dev);
-		break;
 	default:
 		break;
 	}
@@ -3526,12 +3450,9 @@ static int bond_netdev_event(struct noti
 {
 	struct net_device *event_dev = (struct net_device *)ptr;
 
-	if (dev_net(event_dev) != &init_net)
-		return NOTIFY_DONE;
-
 	pr_debug("event_dev: %s, event: %lx\n",
-		(event_dev ? event_dev->name : "None"),
-		event);
+		 event_dev ? event_dev->name : "None",
+		 event);
 
 	if (!(event_dev->priv_flags & IFF_BONDING))
 		return NOTIFY_DONE;
@@ -3561,13 +3482,11 @@ static int bond_inetaddr_event(struct no
 {
 	struct in_ifaddr *ifa = ptr;
 	struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
+	struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id);
 	struct bonding *bond;
 	struct vlan_entry *vlan;
 
-	if (dev_net(ifa->ifa_dev->dev) != &init_net)
-		return NOTIFY_DONE;
-
-	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 		if (bond->dev == event_dev) {
 			switch (event) {
 			case NETDEV_UP:
@@ -3657,8 +3576,7 @@ void bond_unregister_arp(struct bonding
  * Hash for the output device based upon layer 2 and layer 3 data. If
  * the packet is not IP mimic bond_xmit_hash_policy_l2()
  */
-static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
-				     struct net_device *bond_dev, int count)
+static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
 {
 	struct ethhdr *data = (struct ethhdr *)skb->data;
 	struct iphdr *iph = ip_hdr(skb);
@@ -3676,8 +3594,7 @@ static int bond_xmit_hash_policy_l23(str
  * the packet is a frag or not TCP or UDP, just use layer 3 data.  If it is
  * altogether not IP, mimic bond_xmit_hash_policy_l2()
  */
-static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
-				    struct net_device *bond_dev, int count)
+static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
 {
 	struct ethhdr *data = (struct ethhdr *)skb->data;
 	struct iphdr *iph = ip_hdr(skb);
@@ -3701,8 +3618,7 @@ static int bond_xmit_hash_policy_l34(str
 /*
  * Hash for the output device based upon layer 2 data
  */
-static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
-				   struct net_device *bond_dev, int count)
+static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
 {
 	struct ethhdr *data = (struct ethhdr *)skb->data;
 
@@ -3723,7 +3639,7 @@ static int bond_open(struct net_device *
 		 */
 		if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
 			/* something went wrong - fail the open operation */
-			return -1;
+			return -ENOMEM;
 		}
 
 		INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
@@ -3871,8 +3787,7 @@ static int bond_do_ioctl(struct net_devi
 	struct mii_ioctl_data *mii = NULL;
 	int res = 0;
 
-	pr_debug("bond_ioctl: master=%s, cmd=%d\n",
-		bond_dev->name, cmd);
+	pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd);
 
 	switch (cmd) {
 	case SIOCGMIIPHY:
@@ -3939,14 +3854,14 @@ static int bond_do_ioctl(struct net_devi
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
-	slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
+	slave_dev = dev_get_by_name(dev_net(bond_dev), ifr->ifr_slave);
 
-	pr_debug("slave_dev=%p: \n", slave_dev);
+	pr_debug("slave_dev=%p:\n", slave_dev);
 
 	if (!slave_dev)
 		res = -ENODEV;
 	else {
-		pr_debug("slave_dev->name=%s: \n", slave_dev->name);
+		pr_debug("slave_dev->name=%s:\n", slave_dev->name);
 		switch (cmd) {
 		case BOND_ENSLAVE_OLD:
 		case SIOCBONDENSLAVE:
@@ -4055,7 +3970,7 @@ static int bond_change_mtu(struct net_de
 	int i;
 
 	pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond,
-		(bond_dev ? bond_dev->name : "None"), new_mtu);
+		 (bond_dev ? bond_dev->name : "None"), new_mtu);
 
 	/* Can't hold bond->lock with bh disabled here since
 	 * some base drivers panic. On the other hand we can't
@@ -4073,8 +3988,10 @@ static int bond_change_mtu(struct net_de
 	 */
 
 	bond_for_each_slave(bond, slave, i) {
-		pr_debug("s %p s->p %p c_m %p\n", slave,
-			slave->prev, slave->dev->netdev_ops->ndo_change_mtu);
+		pr_debug("s %p s->p %p c_m %p\n",
+			 slave,
+			 slave->prev,
+			 slave->dev->netdev_ops->ndo_change_mtu);
 
 		res = dev_set_mtu(slave->dev, new_mtu);
 
@@ -4104,8 +4021,8 @@ unwind:
 
 		tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu);
 		if (tmp_res) {
-			pr_debug("unwind err %d dev %s\n", tmp_res,
-				slave->dev->name);
+			pr_debug("unwind err %d dev %s\n",
+				 tmp_res, slave->dev->name);
 		}
 	}
 
@@ -4131,7 +4048,8 @@ static int bond_set_mac_address(struct n
 		return bond_alb_set_mac_address(bond_dev, addr);
 
 
-	pr_debug("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
+	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
@@ -4196,8 +4114,8 @@ unwind:
 
 		tmp_res = dev_set_mac_address(slave->dev, &tmp_sa);
 		if (tmp_res) {
-			pr_debug("unwind err %d dev %s\n", tmp_res,
-				slave->dev->name);
+			pr_debug("unwind err %d dev %s\n",
+				 tmp_res, slave->dev->name);
 		}
 	}
 
@@ -4295,7 +4213,7 @@ static int bond_xmit_xor(struct sk_buff
 	if (!BOND_IS_OK(bond))
 		goto out;
 
-	slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
+	slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
 
 	bond_for_each_slave(bond, slave, i) {
 		slave_no--;
@@ -4353,9 +4271,7 @@ static int bond_xmit_broadcast(struct sk
 			if (tx_dev) {
 				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 				if (!skb2) {
-					pr_err(DRV_NAME
-					       ": %s: Error: bond_xmit_broadcast(): "
-					       "skb_clone() failed\n",
+					pr_err("%s: Error: bond_xmit_broadcast(): skb_clone() failed\n",
 					       bond_dev->name);
 					continue;
 				}
@@ -4421,8 +4337,8 @@ static netdev_tx_t bond_start_xmit(struc
 		return bond_alb_xmit(skb, dev);
 	default:
 		/* Should never happen, mode already checked */
-		pr_err(DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
-		     dev->name, bond->params.mode);
+		pr_err("%s: Error: Unknown bonding mode %d\n",
+		       dev->name, bond->params.mode);
 		WARN_ON_ONCE(1);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
@@ -4458,10 +4374,8 @@ void bond_set_mode_ops(struct bonding *b
 		break;
 	default:
 		/* Should never happen, mode already checked */
-		pr_err(DRV_NAME
-		       ": %s: Error: Unknown bonding mode %d\n",
-		       bond_dev->name,
-		       mode);
+		pr_err("%s: Error: Unknown bonding mode %d\n",
+		       bond_dev->name, mode);
 		break;
 	}
 }
@@ -4576,37 +4490,29 @@ static void bond_work_cancel_all(struct
 		cancel_delayed_work(&bond->ad_work);
 }
 
-/* De-initialize device specific data.
- * Caller must hold rtnl_lock.
- */
-static void bond_deinit(struct net_device *bond_dev)
+/*
+* Destroy a bonding device.
+* Must be under rtnl_lock when this function is called.
+*/
+static void bond_uninit(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 
+	/* Release the bonded slaves */
+	bond_release_all(bond_dev);
+
 	list_del(&bond->bond_list);
 
 	bond_work_cancel_all(bond);
 
 	bond_remove_proc_entry(bond);
-}
-
-/* Unregister and free all bond devices.
- * Caller must hold rtnl_lock.
- */
-static void bond_free_all(void)
-{
-	struct bonding *bond, *nxt;
 
-	list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
-		struct net_device *bond_dev = bond->dev;
-
-		bond_work_cancel_all(bond);
-		/* Release the bonded slaves */
-		bond_release_all(bond_dev);
-		unregister_netdevice(bond_dev);
-	}
+	if (bond->wq)
+		destroy_workqueue(bond->wq);
 
-	bond_destroy_proc_dir();
+	netif_addr_lock_bh(bond_dev);
+	bond_mc_list_destroy(bond);
+	netif_addr_unlock_bh(bond_dev);
 }
 
 /*------------------------- Module initialization ---------------------------*/
@@ -4646,7 +4552,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;
+	int arp_validate_value, fail_over_mac_value, primary_reselect_value;
 
 	/*
 	 * Convert string parameters.
@@ -4654,8 +4560,7 @@ static int bond_check_params(struct bond
 	if (mode) {
 		bond_mode = bond_parse_parm(mode, bond_mode_tbl);
 		if (bond_mode == -1) {
-			pr_err(DRV_NAME
-			       ": Error: Invalid bonding mode \"%s\"\n",
+			pr_err("Error: Invalid bonding mode \"%s\"\n",
 			       mode == NULL ? "NULL" : mode);
 			return -EINVAL;
 		}
@@ -4664,15 +4569,13 @@ static int bond_check_params(struct bond
 	if (xmit_hash_policy) {
 		if ((bond_mode != BOND_MODE_XOR) &&
 		    (bond_mode != BOND_MODE_8023AD)) {
-			pr_info(DRV_NAME
-			       ": xor_mode param is irrelevant in mode %s\n",
+			pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
 			       bond_mode_name(bond_mode));
 		} else {
 			xmit_hashtype = bond_parse_parm(xmit_hash_policy,
 							xmit_hashtype_tbl);
 			if (xmit_hashtype == -1) {
-				pr_err(DRV_NAME
-				       ": Error: Invalid xmit_hash_policy \"%s\"\n",
+				pr_err("Error: Invalid xmit_hash_policy \"%s\"\n",
 				       xmit_hash_policy == NULL ? "NULL" :
 				       xmit_hash_policy);
 				return -EINVAL;
@@ -4682,14 +4585,12 @@ static int bond_check_params(struct bond
 
 	if (lacp_rate) {
 		if (bond_mode != BOND_MODE_8023AD) {
-			pr_info(DRV_NAME
-			       ": lacp_rate param is irrelevant in mode %s\n",
-			       bond_mode_name(bond_mode));
+			pr_info("lacp_rate param is irrelevant in mode %s\n",
+				bond_mode_name(bond_mode));
 		} else {
 			lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
 			if (lacp_fast == -1) {
-				pr_err(DRV_NAME
-				       ": Error: Invalid lacp rate \"%s\"\n",
+				pr_err("Error: Invalid lacp rate \"%s\"\n",
 				       lacp_rate == NULL ? "NULL" : lacp_rate);
 				return -EINVAL;
 			}
@@ -4699,82 +4600,64 @@ static int bond_check_params(struct bond
 	if (ad_select) {
 		params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
 		if (params->ad_select == -1) {
-			pr_err(DRV_NAME
-			       ": Error: Invalid ad_select \"%s\"\n",
+			pr_err("Error: Invalid ad_select \"%s\"\n",
 			       ad_select == NULL ? "NULL" : ad_select);
 			return -EINVAL;
 		}
 
 		if (bond_mode != BOND_MODE_8023AD) {
-			pr_warning(DRV_NAME
-			       ": ad_select param only affects 802.3ad mode\n");
+			pr_warning("ad_select param only affects 802.3ad mode\n");
 		}
 	} else {
 		params->ad_select = BOND_AD_STABLE;
 	}
 
 	if (max_bonds < 0) {
-		pr_warning(DRV_NAME
-		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
-		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
-		       max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
+		pr_warning("Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
+			   max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
 		max_bonds = BOND_DEFAULT_MAX_BONDS;
 	}
 
 	if (miimon < 0) {
-		pr_warning(DRV_NAME
-		       ": Warning: miimon module parameter (%d), "
-		       "not in range 0-%d, so it was reset to %d\n",
-		       miimon, INT_MAX, BOND_LINK_MON_INTERV);
+		pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to %d\n",
+			   miimon, INT_MAX, BOND_LINK_MON_INTERV);
 		miimon = BOND_LINK_MON_INTERV;
 	}
 
 	if (updelay < 0) {
-		pr_warning(DRV_NAME
-		       ": Warning: updelay module parameter (%d), "
-		       "not in range 0-%d, so it was reset to 0\n",
-		       updelay, INT_MAX);
+		pr_warning("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+			   updelay, INT_MAX);
 		updelay = 0;
 	}
 
 	if (downdelay < 0) {
-		pr_warning(DRV_NAME
-		       ": Warning: downdelay module parameter (%d), "
-		       "not in range 0-%d, so it was reset to 0\n",
-		       downdelay, INT_MAX);
+		pr_warning("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+			   downdelay, INT_MAX);
 		downdelay = 0;
 	}
 
 	if ((use_carrier != 0) && (use_carrier != 1)) {
-		pr_warning(DRV_NAME
-		       ": Warning: use_carrier module parameter (%d), "
-		       "not of valid value (0/1), so it was set to 1\n",
-		       use_carrier);
+		pr_warning("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n",
+			   use_carrier);
 		use_carrier = 1;
 	}
 
 	if (num_grat_arp < 0 || num_grat_arp > 255) {
-		pr_warning(DRV_NAME
-		       ": Warning: num_grat_arp (%d) not in range 0-255 so it "
-		       "was reset to 1 \n", num_grat_arp);
+		pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1 \n",
+			   num_grat_arp);
 		num_grat_arp = 1;
 	}
 
 	if (num_unsol_na < 0 || num_unsol_na > 255) {
-		pr_warning(DRV_NAME
-		       ": Warning: num_unsol_na (%d) not in range 0-255 so it "
-		       "was reset to 1 \n", num_unsol_na);
+		pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1 \n",
+			   num_unsol_na);
 		num_unsol_na = 1;
 	}
 
 	/* reset values for 802.3ad */
 	if (bond_mode == BOND_MODE_8023AD) {
 		if (!miimon) {
-			pr_warning(DRV_NAME
-			       ": Warning: miimon must be specified, "
-			       "otherwise bonding will not detect link "
-			       "failure, speed and duplex which are "
-			       "essential for 802.3ad operation\n");
+			pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
 			pr_warning("Forcing miimon to 100msec\n");
 			miimon = 100;
 		}
@@ -4784,24 +4667,15 @@ static int bond_check_params(struct bond
 	if ((bond_mode == BOND_MODE_TLB) ||
 	    (bond_mode == BOND_MODE_ALB)) {
 		if (!miimon) {
-			pr_warning(DRV_NAME
-			       ": Warning: miimon must be specified, "
-			       "otherwise bonding will not detect link "
-			       "failure and link speed which are essential "
-			       "for TLB/ALB load balancing\n");
+			pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n");
 			pr_warning("Forcing miimon to 100msec\n");
 			miimon = 100;
 		}
 	}
 
 	if (bond_mode == BOND_MODE_ALB) {
-		pr_notice(DRV_NAME
-		       ": In ALB mode you might experience client "
-		       "disconnections upon reconnection of a link if the "
-		       "bonding module updelay parameter (%d msec) is "
-		       "incompatible with the forwarding delay time of the "
-		       "switch\n",
-		       updelay);
+		pr_notice("In ALB mode you might experience client disconnections upon reconnection of a link if the bonding module updelay parameter (%d msec) is incompatible with the forwarding delay time of the switch\n",
+			  updelay);
 	}
 
 	if (!miimon) {
@@ -4809,49 +4683,37 @@ static int bond_check_params(struct bond
 			/* just warn the user the up/down delay will have
 			 * no effect since miimon is zero...
 			 */
-			pr_warning(DRV_NAME
-			       ": Warning: miimon module parameter not set "
-			       "and updelay (%d) or downdelay (%d) module "
-			       "parameter is set; updelay and downdelay have "
-			       "no effect unless miimon is set\n",
-			       updelay, downdelay);
+			pr_warning("Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set\n",
+				   updelay, downdelay);
 		}
 	} else {
 		/* don't allow arp monitoring */
 		if (arp_interval) {
-			pr_warning(DRV_NAME
-			       ": Warning: miimon (%d) and arp_interval (%d) "
-			       "can't be used simultaneously, disabling ARP "
-			       "monitoring\n",
-			       miimon, arp_interval);
+			pr_warning("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n",
+				   miimon, arp_interval);
 			arp_interval = 0;
 		}
 
 		if ((updelay % miimon) != 0) {
-			pr_warning(DRV_NAME
-			       ": Warning: updelay (%d) is not a multiple "
-			       "of miimon (%d), updelay rounded to %d ms\n",
-			       updelay, miimon, (updelay / miimon) * miimon);
+			pr_warning("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
+				   updelay, miimon,
+				   (updelay / miimon) * miimon);
 		}
 
 		updelay /= miimon;
 
 		if ((downdelay % miimon) != 0) {
-			pr_warning(DRV_NAME
-			       ": Warning: downdelay (%d) is not a multiple "
-			       "of miimon (%d), downdelay rounded to %d ms\n",
-			       downdelay, miimon,
-			       (downdelay / miimon) * miimon);
+			pr_warning("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n",
+				   downdelay, miimon,
+				   (downdelay / miimon) * miimon);
 		}
 
 		downdelay /= miimon;
 	}
 
 	if (arp_interval < 0) {
-		pr_warning(DRV_NAME
-		       ": Warning: arp_interval module parameter (%d) "
-		       ", not in range 0-%d, so it was reset to %d\n",
-		       arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
+		pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to %d\n",
+			   arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
 		arp_interval = BOND_LINK_ARP_INTERV;
 	}
 
@@ -4861,10 +4723,8 @@ static int bond_check_params(struct bond
 		/* not complete check, but should be good enough to
 		   catch mistakes */
 		if (!isdigit(arp_ip_target[arp_ip_count][0])) {
-			pr_warning(DRV_NAME
-			       ": Warning: bad arp_ip_target module parameter "
-			       "(%s), ARP monitoring will not be performed\n",
-			       arp_ip_target[arp_ip_count]);
+			pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
+				   arp_ip_target[arp_ip_count]);
 			arp_interval = 0;
 		} else {
 			__be32 ip = in_aton(arp_ip_target[arp_ip_count]);
@@ -4874,31 +4734,25 @@ static int bond_check_params(struct bond
 
 	if (arp_interval && !arp_ip_count) {
 		/* don't allow arping if no arp_ip_target given... */
-		pr_warning(DRV_NAME
-		       ": Warning: arp_interval module parameter (%d) "
-		       "specified without providing an arp_ip_target "
-		       "parameter, arp_interval was reset to 0\n",
-		       arp_interval);
+		pr_warning("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n",
+			   arp_interval);
 		arp_interval = 0;
 	}
 
 	if (arp_validate) {
 		if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
-			pr_err(DRV_NAME
-			       ": arp_validate only supported in active-backup mode\n");
+			pr_err("arp_validate only supported in active-backup mode\n");
 			return -EINVAL;
 		}
 		if (!arp_interval) {
-			pr_err(DRV_NAME
-			       ": arp_validate requires arp_interval\n");
+			pr_err("arp_validate requires arp_interval\n");
 			return -EINVAL;
 		}
 
 		arp_validate_value = bond_parse_parm(arp_validate,
 						     arp_validate_tbl);
 		if (arp_validate_value == -1) {
-			pr_err(DRV_NAME
-			       ": Error: invalid arp_validate \"%s\"\n",
+			pr_err("Error: invalid arp_validate \"%s\"\n",
 			       arp_validate == NULL ? "NULL" : arp_validate);
 			return -EINVAL;
 		}
@@ -4906,17 +4760,14 @@ static int bond_check_params(struct bond
 		arp_validate_value = 0;
 
 	if (miimon) {
-		pr_info(DRV_NAME
-		       ": MII link monitoring set to %d ms\n",
-		       miimon);
+		pr_info("MII link monitoring set to %d ms\n", miimon);
 	} else if (arp_interval) {
 		int i;
 
-		pr_info(DRV_NAME ": ARP monitoring set to %d ms,"
-		       " validate %s, with %d target(s):",
-		       arp_interval,
-		       arp_validate_tbl[arp_validate_value].modename,
-		       arp_ip_count);
+		pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):",
+			arp_interval,
+			arp_validate_tbl[arp_validate_value].modename,
+			arp_ip_count);
 
 		for (i = 0; i < arp_ip_count; i++)
 			pr_info(" %s", arp_ip_target[i]);
@@ -4927,38 +4778,42 @@ static int bond_check_params(struct bond
 		/* miimon and arp_interval not set, we need one so things
 		 * work as expected, see bonding.txt for details
 		 */
-		pr_warning(DRV_NAME
-		       ": Warning: either miimon or arp_interval and "
-		       "arp_ip_target module parameters must be specified, "
-		       "otherwise bonding will not detect link failures! see "
-		       "bonding.txt for details.\n");
+		pr_warning("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.\n");
 	}
 
 	if (primary && !USES_PRIMARY(bond_mode)) {
 		/* currently, using a primary only makes sense
 		 * in active backup, TLB or ALB modes
 		 */
-		pr_warning(DRV_NAME
-		       ": Warning: %s primary device specified but has no "
-		       "effect in %s mode\n",
-		       primary, bond_mode_name(bond_mode));
+		pr_warning("Warning: %s primary device specified but has no effect in %s mode\n",
+			   primary, bond_mode_name(bond_mode));
 		primary = NULL;
 	}
 
+	if (primary && primary_reselect) {
+		primary_reselect_value = bond_parse_parm(primary_reselect,
+							 pri_reselect_tbl);
+		if (primary_reselect_value == -1) {
+			pr_err("Error: Invalid primary_reselect \"%s\"\n",
+			       primary_reselect ==
+					NULL ? "NULL" : primary_reselect);
+			return -EINVAL;
+		}
+	} else {
+		primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
+	}
+
 	if (fail_over_mac) {
 		fail_over_mac_value = bond_parse_parm(fail_over_mac,
 						      fail_over_mac_tbl);
 		if (fail_over_mac_value == -1) {
-			pr_err(DRV_NAME
-			       ": Error: invalid fail_over_mac \"%s\"\n",
+			pr_err("Error: invalid fail_over_mac \"%s\"\n",
 			       arp_validate == NULL ? "NULL" : arp_validate);
 			return -EINVAL;
 		}
 
 		if (bond_mode != BOND_MODE_ACTIVEBACKUP)
-			pr_warning(DRV_NAME
-			       ": Warning: fail_over_mac only affects "
-			       "active-backup mode.\n");
+			pr_warning("Warning: fail_over_mac only affects active-backup mode.\n");
 	} else {
 		fail_over_mac_value = BOND_FOM_NONE;
 	}
@@ -4976,6 +4831,7 @@ static int bond_check_params(struct bond
 	params->use_carrier = use_carrier;
 	params->lacp_fast = lacp_fast;
 	params->primary[0] = 0;
+	params->primary_reselect = primary_reselect_value;
 	params->fail_over_mac = fail_over_mac_value;
 
 	if (primary) {
@@ -5012,6 +4868,7 @@ static void bond_set_lockdep_class(struc
 static int bond_init(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
+	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
 
 	pr_debug("Begin bond_init for %s\n", bond_dev->name);
 
@@ -5024,40 +4881,53 @@ static int bond_init(struct net_device *
 	netif_carrier_off(bond_dev);
 
 	bond_create_proc_entry(bond);
-	list_add_tail(&bond->bond_list, &bond_dev_list);
+	list_add_tail(&bond->bond_list, &bn->dev_list);
 
+	bond_prepare_sysfs_group(bond);
 	return 0;
 }
 
+static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	if (tb[IFLA_ADDRESS]) {
+		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+			return -EINVAL;
+		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+			return -EADDRNOTAVAIL;
+	}
+	return 0;
+}
+
+static struct rtnl_link_ops bond_link_ops __read_mostly = {
+	.kind		= "bond",
+	.priv_size	= sizeof(struct bonding),
+	.setup		= bond_setup,
+	.validate	= bond_validate,
+};
+
 /* Create a new bond based on the specified name and bonding parameters.
  * If name is NULL, obtain a suitable "bond%d" name for us.
  * Caller must NOT hold rtnl_lock; we need to release it here before we
  * set up our sysfs entries.
  */
-int bond_create(const char *name)
+int bond_create(struct net *net, const char *name)
 {
 	struct net_device *bond_dev;
 	int res;
 
 	rtnl_lock();
-	/* Check to see if the bond already exists. */
-	/* FIXME: pass netns from caller */
-	if (name && __dev_get_by_name(&init_net, name)) {
-		pr_err(DRV_NAME ": cannot add bond %s; already exists\n",
-		       name);
-		res = -EEXIST;
-		goto out_rtnl;
-	}
 
 	bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
 				bond_setup);
 	if (!bond_dev) {
-		pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n",
-		       name);
+		pr_err("%s: eek! can't alloc netdev!\n", name);
 		res = -ENOMEM;
-		goto out_rtnl;
+		goto out;
 	}
 
+	dev_net_set(bond_dev, net);
+	bond_dev->rtnl_link_ops = &bond_link_ops;
+
 	if (!name) {
 		res = dev_alloc_name(bond_dev, "bond%d");
 		if (res < 0)
@@ -5065,27 +4935,41 @@ int bond_create(const char *name)
 	}
 
 	res = register_netdevice(bond_dev);
-	if (res < 0)
-		goto out_bond;
-
-	res = bond_create_sysfs_entry(netdev_priv(bond_dev));
-	if (res < 0)
-		goto out_unreg;
 
+out:
 	rtnl_unlock();
-	return 0;
-
-out_unreg:
-	unregister_netdevice(bond_dev);
-out_bond:
-	bond_deinit(bond_dev);
+	return res;
 out_netdev:
 	free_netdev(bond_dev);
-out_rtnl:
-	rtnl_unlock();
-	return res;
+	goto out;
 }
 
+static int bond_net_init(struct net *net)
+{
+	struct bond_net *bn = net_generic(net, bond_net_id);
+
+	bn->net = net;
+	INIT_LIST_HEAD(&bn->dev_list);
+
+	bond_create_proc_dir(bn);
+	
+	return 0;
+}
+
+static void bond_net_exit(struct net *net)
+{
+	struct bond_net *bn = net_generic(net, bond_net_id);
+
+	bond_destroy_proc_dir(bn);
+}
+
+static struct pernet_operations bond_net_ops = {
+	.init = bond_net_init,
+	.exit = bond_net_exit,
+	.id   = &bond_net_id,
+	.size = sizeof(struct bond_net),
+};
+
 static int __init bonding_init(void)
 {
 	int i;
@@ -5097,10 +4981,16 @@ static int __init bonding_init(void)
 	if (res)
 		goto out;
 
-	bond_create_proc_dir();
+	res = register_pernet_subsys(&bond_net_ops);
+	if (res)
+		goto out;
+
+	res = rtnl_link_register(&bond_link_ops);
+	if (res)
+		goto err_link;
 
 	for (i = 0; i < max_bonds; i++) {
-		res = bond_create(NULL);
+		res = bond_create(&init_net, NULL);
 		if (res)
 			goto err;
 	}
@@ -5112,14 +5002,13 @@ static int __init bonding_init(void)
 	register_netdevice_notifier(&bond_netdev_notifier);
 	register_inetaddr_notifier(&bond_inetaddr_notifier);
 	bond_register_ipv6_notifier();
-
-	goto out;
-err:
-	rtnl_lock();
-	bond_free_all();
-	rtnl_unlock();
 out:
 	return res;
+err:
+	rtnl_link_unregister(&bond_link_ops);
+err_link:
+	unregister_pernet_subsys(&bond_net_ops);
+	goto out;
 
 }
 
@@ -5131,9 +5020,8 @@ static void __exit bonding_exit(void)
 
 	bond_destroy_sysfs();
 
-	rtnl_lock();
-	bond_free_all();
-	rtnl_unlock();
+	rtnl_link_unregister(&bond_link_ops);
+	unregister_pernet_subsys(&bond_net_ops);
 }
 
 module_init(bonding_init);
@@ -5142,3 +5030,4 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
 MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
+MODULE_ALIAS_RTNL_LINK("bond");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_sysfs.c linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/bonding/bond_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/bonding/bond_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,9 @@
  * file called LICENSE.
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -36,6 +39,8 @@
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <linux/nsproxy.h>
 
 #include "bonding.h"
 
@@ -48,12 +53,14 @@
  */
 static ssize_t bonding_show_bonds(struct class *cls, char *buf)
 {
+	struct net *net = current->nsproxy->net_ns;
+	struct bond_net *bn = net_generic(net, bond_net_id);
 	int res = 0;
 	struct bonding *bond;
 
 	rtnl_lock();
 
-	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 		if (res > (PAGE_SIZE - IFNAMSIZ)) {
 			/* not enough space for another interface name */
 			if ((PAGE_SIZE - res) > 10)
@@ -70,11 +77,12 @@ static ssize_t bonding_show_bonds(struct
 	return res;
 }
 
-static struct net_device *bond_get_by_name(const char *ifname)
+static struct net_device *bond_get_by_name(struct net *net, const char *ifname)
 {
+	struct bond_net *bn = net_generic(net, bond_net_id);
 	struct bonding *bond;
 
-	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 		if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
 			return bond->dev;
 	}
@@ -92,6 +100,7 @@ static struct net_device *bond_get_by_na
 static ssize_t bonding_store_bonds(struct class *cls,
 				   const char *buffer, size_t count)
 {
+	struct net *net = current->nsproxy->net_ns;
 	char command[IFNAMSIZ + 1] = {0, };
 	char *ifname;
 	int rv, res = count;
@@ -103,25 +112,22 @@ static ssize_t bonding_store_bonds(struc
 		goto err_no_cmd;
 
 	if (command[0] == '+') {
-		pr_info(DRV_NAME
-			": %s is being created...\n", ifname);
-		rv = bond_create(ifname);
+		pr_info("%s is being created...\n", ifname);
+		rv = bond_create(net, ifname);
 		if (rv) {
-			pr_info(DRV_NAME ": Bond creation failed.\n");
+			pr_info("Bond creation failed.\n");
 			res = rv;
 		}
 	} else if (command[0] == '-') {
 		struct net_device *bond_dev;
 
 		rtnl_lock();
-		bond_dev = bond_get_by_name(ifname);
+		bond_dev = bond_get_by_name(net, ifname);
 		if (bond_dev) {
-			pr_info(DRV_NAME ": %s is being deleted...\n",
-				ifname);
+			pr_info("%s is being deleted...\n", ifname);
 			unregister_netdevice(bond_dev);
 		} else {
-			pr_err(DRV_NAME ": unable to delete non-existent %s\n",
-			       ifname);
+			pr_err("unable to delete non-existent %s\n", ifname);
 			res = -ENODEV;
 		}
 		rtnl_unlock();
@@ -134,8 +140,7 @@ static ssize_t bonding_store_bonds(struc
 	return res;
 
 err_no_cmd:
-	pr_err(DRV_NAME ": no command found in bonding_masters."
-	       " Use +ifname or -ifname.\n");
+	pr_err("no command found in bonding_masters. Use +ifname or -ifname.\n");
 	return -EPERM;
 }
 
@@ -219,8 +224,8 @@ static ssize_t bonding_store_slaves(stru
 
 	/* Quick sanity check -- is the bond interface up? */
 	if (!(bond->dev->flags & IFF_UP)) {
-		pr_warning(DRV_NAME ": %s: doing slave updates when "
-			   "interface is down.\n", bond->dev->name);
+		pr_warning("%s: doing slave updates when interface is down.\n",
+			   bond->dev->name);
 	}
 
 	/* Note:  We can't hold bond->lock here, as bond_create grabs it. */
@@ -239,20 +244,16 @@ static ssize_t bonding_store_slaves(stru
 		/* Got a slave name in ifname.  Is it already in the list? */
 		found = 0;
 
-		/* FIXME: get netns from sysfs object */
-		dev = __dev_get_by_name(&init_net, ifname);
+		dev = __dev_get_by_name(dev_net(bond->dev), ifname);
 		if (!dev) {
-			pr_info(DRV_NAME
-			       ": %s: Interface %s does not exist!\n",
-			       bond->dev->name, ifname);
+			pr_info("%s: Interface %s does not exist!\n",
+				bond->dev->name, ifname);
 			ret = -ENODEV;
 			goto out;
 		}
 
 		if (dev->flags & IFF_UP) {
-			pr_err(DRV_NAME
-			       ": %s: Error: Unable to enslave %s "
-			       "because it is already up.\n",
+			pr_err("%s: Error: Unable to enslave %s because it is already up.\n",
 			       bond->dev->name, dev->name);
 			ret = -EPERM;
 			goto out;
@@ -261,8 +262,7 @@ static ssize_t bonding_store_slaves(stru
 		read_lock(&bond->lock);
 		bond_for_each_slave(bond, slave, i)
 			if (slave->dev == dev) {
-				pr_err(DRV_NAME
-				       ": %s: Interface %s is already enslaved!\n",
+				pr_err("%s: Interface %s is already enslaved!\n",
 				       bond->dev->name, ifname);
 				ret = -EPERM;
 				read_unlock(&bond->lock);
@@ -270,8 +270,7 @@ static ssize_t bonding_store_slaves(stru
 			}
 		read_unlock(&bond->lock);
 
-		pr_info(DRV_NAME ": %s: Adding slave %s.\n",
-			bond->dev->name, ifname);
+		pr_info("%s: Adding slave %s.\n", bond->dev->name, ifname);
 
 		/* If this is the first slave, then we need to set
 		   the master's hardware address to be the same as the
@@ -308,7 +307,7 @@ static ssize_t bonding_store_slaves(stru
 				break;
 			}
 		if (dev) {
-			pr_info(DRV_NAME ": %s: Removing slave %s\n",
+			pr_info("%s: Removing slave %s\n",
 				bond->dev->name, dev->name);
 				res = bond_release(bond->dev, dev);
 			if (res) {
@@ -318,16 +317,16 @@ static ssize_t bonding_store_slaves(stru
 			/* set the slave MTU to the default */
 			dev_set_mtu(dev, original_mtu);
 		} else {
-			pr_err(DRV_NAME ": unable to remove non-existent"
-			       " slave %s for bond %s.\n",
-				ifname, bond->dev->name);
+			pr_err("unable to remove non-existent slave %s for bond %s.\n",
+			       ifname, bond->dev->name);
 			ret = -ENODEV;
 		}
 		goto out;
 	}
 
 err_no_cmd:
-	pr_err(DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+	pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n",
+	       bond->dev->name);
 	ret = -EPERM;
 
 out:
@@ -360,18 +359,16 @@ static ssize_t bonding_store_mode(struct
 	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
-		pr_err(DRV_NAME ": unable to update mode of %s"
-		       " because interface is up.\n", bond->dev->name);
+		pr_err("unable to update mode of %s because interface is up.\n",
+		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
 
 	new_value = bond_parse_parm(buf, bond_mode_tbl);
 	if (new_value < 0)  {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid mode value %.*s.\n",
-		       bond->dev->name,
-		       (int)strlen(buf) - 1, buf);
+		pr_err("%s: Ignoring invalid mode value %.*s.\n",
+		       bond->dev->name, (int)strlen(buf) - 1, buf);
 		ret = -EINVAL;
 		goto out;
 	} else {
@@ -383,8 +380,8 @@ static ssize_t bonding_store_mode(struct
 
 		bond->params.mode = new_value;
 		bond_set_mode_ops(bond, bond->params.mode);
-		pr_info(DRV_NAME ": %s: setting mode to %s (%d).\n",
-		       bond->dev->name, bond_mode_tbl[new_value].modename,
+		pr_info("%s: setting mode to %s (%d).\n",
+			bond->dev->name, bond_mode_tbl[new_value].modename,
 		       new_value);
 	}
 out:
@@ -416,8 +413,7 @@ static ssize_t bonding_store_xmit_hash(s
 	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
-		pr_err(DRV_NAME
-		       "%s: Interface is up. Unable to update xmit policy.\n",
+		pr_err("%s: Interface is up. Unable to update xmit policy.\n",
 		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
@@ -425,8 +421,7 @@ static ssize_t bonding_store_xmit_hash(s
 
 	new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
 	if (new_value < 0)  {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
+		pr_err("%s: Ignoring invalid xmit hash policy value %.*s.\n",
 		       bond->dev->name,
 		       (int)strlen(buf) - 1, buf);
 		ret = -EINVAL;
@@ -434,7 +429,7 @@ static ssize_t bonding_store_xmit_hash(s
 	} else {
 		bond->params.xmit_policy = new_value;
 		bond_set_mode_ops(bond, bond->params.mode);
-		pr_info(DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+		pr_info("%s: setting xmit hash policy to %s (%d).\n",
 			bond->dev->name,
 			xmit_hashtype_tbl[new_value].modename, new_value);
 	}
@@ -467,20 +462,18 @@ static ssize_t bonding_store_arp_validat
 
 	new_value = bond_parse_parm(buf, arp_validate_tbl);
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid arp_validate value %s\n",
+		pr_err("%s: Ignoring invalid arp_validate value %s\n",
 		       bond->dev->name, buf);
 		return -EINVAL;
 	}
 	if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
-		pr_err(DRV_NAME
-		       ": %s: arp_validate only supported in active-backup mode.\n",
+		pr_err("%s: arp_validate only supported in active-backup mode.\n",
 		       bond->dev->name);
 		return -EINVAL;
 	}
-	pr_info(DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
-	       bond->dev->name, arp_validate_tbl[new_value].modename,
-	       new_value);
+	pr_info("%s: setting arp_validate to %s (%d).\n",
+		bond->dev->name, arp_validate_tbl[new_value].modename,
+		new_value);
 
 	if (!bond->params.arp_validate && new_value)
 		bond_register_arp(bond);
@@ -518,24 +511,22 @@ static ssize_t bonding_store_fail_over_m
 	struct bonding *bond = to_bond(d);
 
 	if (bond->slave_cnt != 0) {
-		pr_err(DRV_NAME
-		       ": %s: Can't alter fail_over_mac with slaves in bond.\n",
+		pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n",
 		       bond->dev->name);
 		return -EPERM;
 	}
 
 	new_value = bond_parse_parm(buf, fail_over_mac_tbl);
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid fail_over_mac value %s.\n",
+		pr_err("%s: Ignoring invalid fail_over_mac value %s.\n",
 		       bond->dev->name, buf);
 		return -EINVAL;
 	}
 
 	bond->params.fail_over_mac = new_value;
-	pr_info(DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
-	       bond->dev->name, fail_over_mac_tbl[new_value].modename,
-	       new_value);
+	pr_info("%s: Setting fail_over_mac to %s (%d).\n",
+		bond->dev->name, fail_over_mac_tbl[new_value].modename,
+		new_value);
 
 	return count;
 }
@@ -566,31 +557,26 @@ static ssize_t bonding_store_arp_interva
 	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no arp_interval value specified.\n",
+		pr_err("%s: no arp_interval value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
+		pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
 		       bond->dev->name, new_value, INT_MAX);
 		ret = -EINVAL;
 		goto out;
 	}
 
-	pr_info(DRV_NAME
-	       ": %s: Setting ARP monitoring interval to %d.\n",
-	       bond->dev->name, new_value);
+	pr_info("%s: Setting ARP monitoring interval to %d.\n",
+		bond->dev->name, new_value);
 	bond->params.arp_interval = new_value;
 	if (bond->params.arp_interval)
 		bond->dev->priv_flags |= IFF_MASTER_ARPMON;
 	if (bond->params.miimon) {
-		pr_info(DRV_NAME
-		       ": %s: ARP monitoring cannot be used with MII monitoring. "
-		       "%s Disabling MII monitoring.\n",
-		       bond->dev->name, bond->dev->name);
+		pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+			bond->dev->name, bond->dev->name);
 		bond->params.miimon = 0;
 		if (delayed_work_pending(&bond->mii_work)) {
 			cancel_delayed_work(&bond->mii_work);
@@ -598,10 +584,8 @@ static ssize_t bonding_store_arp_interva
 		}
 	}
 	if (!bond->params.arp_targets[0]) {
-		pr_info(DRV_NAME
-		       ": %s: ARP monitoring has been set up, "
-		       "but no ARP targets have been specified.\n",
-		       bond->dev->name);
+		pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+			bond->dev->name);
 	}
 	if (bond->dev->flags & IFF_UP) {
 		/* If the interface is up, we may need to fire off
@@ -661,8 +645,7 @@ static ssize_t bonding_store_arp_targets
 	/* look for adds */
 	if (buf[0] == '+') {
 		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
-			pr_err(DRV_NAME
-			       ": %s: invalid ARP target %pI4 specified for addition\n",
+			pr_err("%s: invalid ARP target %pI4 specified for addition\n",
 			       bond->dev->name, &newtarget);
 			ret = -EINVAL;
 			goto out;
@@ -670,23 +653,20 @@ static ssize_t bonding_store_arp_targets
 		/* 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(DRV_NAME
-				       ": %s: ARP target %pI4 is already present\n",
+				pr_err("%s: ARP target %pI4 is already present\n",
 				       bond->dev->name, &newtarget);
 				ret = -EINVAL;
 				goto out;
 			}
 			if (targets[i] == 0) {
-				pr_info(DRV_NAME
-				       ": %s: adding ARP target %pI4.\n",
-				       bond->dev->name, &newtarget);
+				pr_info("%s: adding ARP target %pI4.\n",
+					bond->dev->name, &newtarget);
 				done = 1;
 				targets[i] = newtarget;
 			}
 		}
 		if (!done) {
-			pr_err(DRV_NAME
-			       ": %s: ARP target table is full!\n",
+			pr_err("%s: ARP target table is full!\n",
 			       bond->dev->name);
 			ret = -EINVAL;
 			goto out;
@@ -694,8 +674,7 @@ static ssize_t bonding_store_arp_targets
 
 	} else if (buf[0] == '-')	{
 		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
-			pr_err(DRV_NAME
-			       ": %s: invalid ARP target %pI4 specified for removal\n",
+			pr_err("%s: invalid ARP target %pI4 specified for removal\n",
 			       bond->dev->name, &newtarget);
 			ret = -EINVAL;
 			goto out;
@@ -704,9 +683,8 @@ static ssize_t bonding_store_arp_targets
 		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
 			if (targets[i] == newtarget) {
 				int j;
-				pr_info(DRV_NAME
-				       ": %s: removing ARP target %pI4.\n",
-				       bond->dev->name, &newtarget);
+				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];
 
@@ -715,16 +693,14 @@ static ssize_t bonding_store_arp_targets
 			}
 		}
 		if (!done) {
-			pr_info(DRV_NAME
-			       ": %s: unable to remove nonexistent ARP target %pI4.\n",
-			       bond->dev->name, &newtarget);
+			pr_info("%s: unable to remove nonexistent ARP target %pI4.\n",
+				bond->dev->name, &newtarget);
 			ret = -EINVAL;
 			goto out;
 		}
 	} else {
-		pr_err(DRV_NAME ": no command found in arp_ip_targets file"
-		       " for bond %s. Use +<addr> or -<addr>.\n",
-			bond->dev->name);
+		pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
@@ -756,41 +732,34 @@ static ssize_t bonding_store_downdelay(s
 	struct bonding *bond = to_bond(d);
 
 	if (!(bond->params.miimon)) {
-		pr_err(DRV_NAME
-		       ": %s: Unable to set down delay as MII monitoring is disabled\n",
+		pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
 		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no down delay value specified.\n",
-		       bond->dev->name);
+		pr_err("%s: no down delay value specified.\n", bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
 		       bond->dev->name, new_value, 1, INT_MAX);
 		ret = -EINVAL;
 		goto out;
 	} else {
 		if ((new_value % bond->params.miimon) != 0) {
-			pr_warning(DRV_NAME
-				   ": %s: Warning: down delay (%d) is not a "
-				   "multiple of miimon (%d), delay rounded "
-				   "to %d ms\n",
+			pr_warning("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
 				   bond->dev->name, new_value,
 				   bond->params.miimon,
 				   (new_value / bond->params.miimon) *
 				   bond->params.miimon);
 		}
 		bond->params.downdelay = new_value / bond->params.miimon;
-		pr_info(DRV_NAME ": %s: Setting down delay to %d.\n",
-		       bond->dev->name,
-		       bond->params.downdelay * bond->params.miimon);
+		pr_info("%s: Setting down delay to %d.\n",
+			bond->dev->name,
+			bond->params.downdelay * bond->params.miimon);
 
 	}
 
@@ -818,41 +787,35 @@ static ssize_t bonding_store_updelay(str
 	struct bonding *bond = to_bond(d);
 
 	if (!(bond->params.miimon)) {
-		pr_err(DRV_NAME
-		       ": %s: Unable to set up delay as MII monitoring is disabled\n",
+		pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
 		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no up delay value specified.\n",
+		pr_err("%s: no up delay value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
 		       bond->dev->name, new_value, 1, INT_MAX);
 		ret = -EINVAL;
 		goto out;
 	} else {
 		if ((new_value % bond->params.miimon) != 0) {
-			pr_warning(DRV_NAME
-				   ": %s: Warning: up delay (%d) is not a "
-				   "multiple of miimon (%d), updelay rounded "
-				   "to %d ms\n",
+			pr_warning("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
 				   bond->dev->name, new_value,
 				   bond->params.miimon,
 				   (new_value / bond->params.miimon) *
 				   bond->params.miimon);
 		}
 		bond->params.updelay = new_value / bond->params.miimon;
-		pr_info(DRV_NAME ": %s: Setting up delay to %d.\n",
-		       bond->dev->name, bond->params.updelay * bond->params.miimon);
-
+		pr_info("%s: Setting up delay to %d.\n",
+			bond->dev->name,
+			bond->params.updelay * bond->params.miimon);
 	}
 
 out:
@@ -884,16 +847,14 @@ static ssize_t bonding_store_lacp(struct
 	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
-		pr_err(DRV_NAME
-		       ": %s: Unable to update LACP rate because interface is up.\n",
+		pr_err("%s: Unable to update LACP rate because interface is up.\n",
 		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
 
 	if (bond->params.mode != BOND_MODE_8023AD) {
-		pr_err(DRV_NAME
-		       ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
+		pr_err("%s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
 		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
@@ -903,12 +864,11 @@ static ssize_t bonding_store_lacp(struct
 
 	if ((new_value == 1) || (new_value == 0)) {
 		bond->params.lacp_fast = new_value;
-		pr_info(DRV_NAME ": %s: Setting LACP rate to %s (%d).\n",
+		pr_info("%s: Setting LACP rate to %s (%d).\n",
 			bond->dev->name, bond_lacp_tbl[new_value].modename,
 			new_value);
 	} else {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid LACP rate value %.*s.\n",
+		pr_err("%s: Ignoring invalid LACP rate value %.*s.\n",
 		       bond->dev->name, (int)strlen(buf) - 1, buf);
 		ret = -EINVAL;
 	}
@@ -938,9 +898,8 @@ static ssize_t bonding_store_ad_select(s
 	struct bonding *bond = to_bond(d);
 
 	if (bond->dev->flags & IFF_UP) {
-		pr_err(DRV_NAME
-		       ": %s: Unable to update ad_select because interface "
-		       "is up.\n", bond->dev->name);
+		pr_err("%s: Unable to update ad_select because interface is up.\n",
+		       bond->dev->name);
 		ret = -EPERM;
 		goto out;
 	}
@@ -949,13 +908,11 @@ static ssize_t bonding_store_ad_select(s
 
 	if (new_value != -1) {
 		bond->params.ad_select = new_value;
-		pr_info(DRV_NAME
-		       ": %s: Setting ad_select to %s (%d).\n",
-		       bond->dev->name, ad_select_tbl[new_value].modename,
-		       new_value);
+		pr_info("%s: Setting ad_select to %s (%d).\n",
+			bond->dev->name, ad_select_tbl[new_value].modename,
+			new_value);
 	} else {
-		pr_err(DRV_NAME
-		       ": %s: Ignoring invalid ad_select value %.*s.\n",
+		pr_err("%s: Ignoring invalid ad_select value %.*s.\n",
 		       bond->dev->name, (int)strlen(buf) - 1, buf);
 		ret = -EINVAL;
 	}
@@ -985,15 +942,13 @@ static ssize_t bonding_store_n_grat_arp(
 	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no num_grat_arp value specified.\n",
+		pr_err("%s: no num_grat_arp value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (new_value < 0 || new_value > 255) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
+		pr_err("%s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
 		       bond->dev->name, new_value);
 		ret = -EINVAL;
 		goto out;
@@ -1026,16 +981,14 @@ static ssize_t bonding_store_n_unsol_na(
 	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no num_unsol_na value specified.\n",
+		pr_err("%s: no num_unsol_na value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 
 	if (new_value < 0 || new_value > 255) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
+		pr_err("%s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
 		       bond->dev->name, new_value);
 		ret = -EINVAL;
 		goto out;
@@ -1070,40 +1023,31 @@ static ssize_t bonding_store_miimon(stru
 	struct bonding *bond = to_bond(d);
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no miimon value specified.\n",
+		pr_err("%s: no miimon value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (new_value < 0) {
-		pr_err(DRV_NAME
-		       ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
+		pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
 		       bond->dev->name, new_value, 1, INT_MAX);
 		ret = -EINVAL;
 		goto out;
 	} else {
-		pr_info(DRV_NAME
-		       ": %s: Setting MII monitoring interval to %d.\n",
-		       bond->dev->name, new_value);
+		pr_info("%s: Setting MII monitoring interval to %d.\n",
+			bond->dev->name, new_value);
 		bond->params.miimon = new_value;
 		if (bond->params.updelay)
-			pr_info(DRV_NAME
-			      ": %s: Note: Updating updelay (to %d) "
-			      "since it is a multiple of the miimon value.\n",
-			      bond->dev->name,
-			      bond->params.updelay * bond->params.miimon);
+			pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
+				bond->dev->name,
+				bond->params.updelay * bond->params.miimon);
 		if (bond->params.downdelay)
-			pr_info(DRV_NAME
-			      ": %s: Note: Updating downdelay (to %d) "
-			      "since it is a multiple of the miimon value.\n",
-			      bond->dev->name,
-			      bond->params.downdelay * bond->params.miimon);
+			pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
+				bond->dev->name,
+				bond->params.downdelay * bond->params.miimon);
 		if (bond->params.arp_interval) {
-			pr_info(DRV_NAME
-			       ": %s: MII monitoring cannot be used with "
-			       "ARP monitoring. Disabling ARP monitoring...\n",
-			       bond->dev->name);
+			pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
+				bond->dev->name);
 			bond->params.arp_interval = 0;
 			bond->dev->priv_flags &= ~IFF_MASTER_ARPMON;
 			if (bond->params.arp_validate) {
@@ -1171,17 +1115,15 @@ static ssize_t bonding_store_primary(str
 	write_lock_bh(&bond->curr_slave_lock);
 
 	if (!USES_PRIMARY(bond->params.mode)) {
-		pr_info(DRV_NAME
-		       ": %s: Unable to set primary slave; %s is in mode %d\n",
-		       bond->dev->name, bond->dev->name, bond->params.mode);
+		pr_info("%s: Unable to set primary slave; %s is in mode %d\n",
+			bond->dev->name, bond->dev->name, bond->params.mode);
 	} else {
 		bond_for_each_slave(bond, slave, i) {
 			if (strnicmp
 			    (slave->dev->name, buf,
 			     strlen(slave->dev->name)) == 0) {
-				pr_info(DRV_NAME
-				       ": %s: Setting %s as primary slave.\n",
-				       bond->dev->name, slave->dev->name);
+				pr_info("%s: Setting %s as primary slave.\n",
+					bond->dev->name, slave->dev->name);
 				bond->primary_slave = slave;
 				strcpy(bond->params.primary, slave->dev->name);
 				bond_select_active_slave(bond);
@@ -1192,15 +1134,13 @@ static ssize_t bonding_store_primary(str
 		/* if we got here, then we didn't match the name of any slave */
 
 		if (strlen(buf) == 0 || buf[0] == '\n') {
-			pr_info(DRV_NAME
-			       ": %s: Setting primary slave to None.\n",
-			       bond->dev->name);
+			pr_info("%s: Setting primary slave to None.\n",
+				bond->dev->name);
 			bond->primary_slave = NULL;
 				bond_select_active_slave(bond);
 		} else {
-			pr_info(DRV_NAME
-			       ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
-			       bond->dev->name, (int)strlen(buf) - 1, buf);
+			pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n",
+				bond->dev->name, (int)strlen(buf) - 1, buf);
 		}
 	}
 out:
@@ -1214,6 +1154,57 @@ static DEVICE_ATTR(primary, S_IRUGO | S_
 		   bonding_show_primary, bonding_store_primary);
 
 /*
+ * Show and set the primary_reselect flag.
+ */
+static ssize_t bonding_show_primary_reselect(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	return sprintf(buf, "%s %d\n",
+		       pri_reselect_tbl[bond->params.primary_reselect].modename,
+		       bond->params.primary_reselect);
+}
+
+static ssize_t bonding_store_primary_reselect(struct device *d,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(d);
+
+	if (!rtnl_trylock())
+		return restart_syscall();
+
+	new_value = bond_parse_parm(buf, pri_reselect_tbl);
+	if (new_value < 0)  {
+		pr_err("%s: Ignoring invalid primary_reselect value %.*s.\n",
+		       bond->dev->name,
+		       (int) strlen(buf) - 1, buf);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	bond->params.primary_reselect = new_value;
+	pr_info("%s: setting primary_reselect to %s (%d).\n",
+		bond->dev->name, pri_reselect_tbl[new_value].modename,
+		new_value);
+
+	read_lock(&bond->lock);
+	write_lock_bh(&bond->curr_slave_lock);
+	bond_select_active_slave(bond);
+	write_unlock_bh(&bond->curr_slave_lock);
+	read_unlock(&bond->lock);
+out:
+	rtnl_unlock();
+	return ret;
+}
+static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
+		   bonding_show_primary_reselect,
+		   bonding_store_primary_reselect);
+
+/*
  * Show and set the use_carrier flag.
  */
 static ssize_t bonding_show_carrier(struct device *d,
@@ -1234,20 +1225,18 @@ static ssize_t bonding_store_carrier(str
 
 
 	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err(DRV_NAME
-		       ": %s: no use_carrier value specified.\n",
+		pr_err("%s: no use_carrier value specified.\n",
 		       bond->dev->name);
 		ret = -EINVAL;
 		goto out;
 	}
 	if ((new_value == 0) || (new_value == 1)) {
 		bond->params.use_carrier = new_value;
-		pr_info(DRV_NAME ": %s: Setting use_carrier to %d.\n",
-		       bond->dev->name, new_value);
+		pr_info("%s: Setting use_carrier to %d.\n",
+			bond->dev->name, new_value);
 	} else {
-		pr_info(DRV_NAME
-		       ": %s: Ignoring invalid use_carrier value %d.\n",
-		       bond->dev->name, new_value);
+		pr_info("%s: Ignoring invalid use_carrier value %d.\n",
+			bond->dev->name, new_value);
 	}
 out:
 	return count;
@@ -1292,8 +1281,7 @@ static ssize_t bonding_store_active_slav
 	write_lock_bh(&bond->curr_slave_lock);
 
 	if (!USES_PRIMARY(bond->params.mode))
-		pr_info(DRV_NAME ": %s: Unable to change active slave;"
-			" %s is in mode %d\n",
+		pr_info("%s: Unable to change active slave; %s is in mode %d\n",
 			bond->dev->name, bond->dev->name, bond->params.mode);
 	else {
 		bond_for_each_slave(bond, slave, i) {
@@ -1304,9 +1292,9 @@ static ssize_t bonding_store_active_slav
         			new_active = slave;
         			if (new_active == old_active) {
 					/* do nothing */
-					pr_info(DRV_NAME
-						": %s: %s is already the current active slave.\n",
-						bond->dev->name, slave->dev->name);
+					pr_info("%s: %s is already the current active slave.\n",
+						bond->dev->name,
+						slave->dev->name);
 					goto out;
 				}
 				else {
@@ -1314,16 +1302,15 @@ static ssize_t bonding_store_active_slav
             				    (old_active) &&
 				            (new_active->link == BOND_LINK_UP) &&
 				            IS_UP(new_active->dev)) {
-						pr_info(DRV_NAME
-							": %s: Setting %s as active slave.\n",
-							bond->dev->name, slave->dev->name);
+						pr_info("%s: Setting %s as active slave.\n",
+							bond->dev->name,
+							slave->dev->name);
 							bond_change_active_slave(bond, new_active);
         				}
 					else {
-						pr_info(DRV_NAME
-							": %s: Could not set %s as active slave; "
-							"either %s is down or the link is down.\n",
-							bond->dev->name, slave->dev->name,
+						pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n",
+							bond->dev->name,
+							slave->dev->name,
 							slave->dev->name);
 					}
 					goto out;
@@ -1334,14 +1321,12 @@ static ssize_t bonding_store_active_slav
 		/* if we got here, then we didn't match the name of any slave */
 
 		if (strlen(buf) == 0 || buf[0] == '\n') {
-			pr_info(DRV_NAME
-				": %s: Setting active slave to None.\n",
+			pr_info("%s: Setting active slave to None.\n",
 				bond->dev->name);
 			bond->primary_slave = NULL;
 			bond_select_active_slave(bond);
 		} else {
-			pr_info(DRV_NAME ": %s: Unable to set %.*s"
-				" as active slave as it is not a slave.\n",
+			pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n",
 				bond->dev->name, (int)strlen(buf) - 1, buf);
 		}
 	}
@@ -1502,6 +1487,7 @@ static struct attribute *per_bond_attrs[
 	&dev_attr_num_unsol_na.attr,
 	&dev_attr_miimon.attr,
 	&dev_attr_primary.attr,
+	&dev_attr_primary_reselect.attr,
 	&dev_attr_use_carrier.attr,
 	&dev_attr_active_slave.attr,
 	&dev_attr_mii_status.attr,
@@ -1542,8 +1528,7 @@ int bond_create_sysfs(void)
 		/* Is someone being kinky and naming a device bonding_master? */
 		if (__dev_get_by_name(&init_net,
 				      class_attr_bonding_masters.attr.name))
-			pr_err("network device named %s already "
-			       "exists in sysfs",
+			pr_err("network device named %s already exists in sysfs",
 			       class_attr_bonding_masters.attr.name);
 		ret = 0;
 	}
@@ -1564,24 +1549,8 @@ void bond_destroy_sysfs(void)
  * Initialize sysfs for each bond.  This sets up and registers
  * the 'bondctl' directory for each individual bond under /sys/class/net.
  */
-int bond_create_sysfs_entry(struct bonding *bond)
-{
-	struct net_device *dev = bond->dev;
-	int err;
-
-	err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
-	if (err)
-		pr_emerg("eek! didn't create group!\n");
-
-	return err;
-}
-/*
- * Remove sysfs entries for each bond.
- */
-void bond_destroy_sysfs_entry(struct bonding *bond)
+void bond_prepare_sysfs_group(struct bonding *bond)
 {
-	struct net_device *dev = bond->dev;
-
-	sysfs_remove_group(&(dev->dev.kobj), &bonding_group);
+	bond->dev->sysfs_groups[0] = &bonding_group;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/at91_can.c linux-libre-2.6.33-gnu1/drivers/net/can/at91_can.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/at91_can.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/at91_can.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,38 +221,6 @@ static inline void set_mb_mode(const str
 	set_mb_mode_prio(priv, mb, mode, 0);
 }
 
-static struct sk_buff *alloc_can_skb(struct net_device *dev,
-		struct can_frame **cf)
-{
-	struct sk_buff *skb;
-
-	skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
-	if (unlikely(!skb))
-		return NULL;
-
-	skb->protocol = htons(ETH_P_CAN);
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
-	*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
-	return skb;
-}
-
-static struct sk_buff *alloc_can_err_skb(struct net_device *dev,
-		struct can_frame **cf)
-{
-	struct sk_buff *skb;
-
-	skb = alloc_can_skb(dev, cf);
-	if (unlikely(!skb))
-		return NULL;
-
-	memset(*cf, 0, sizeof(struct can_frame));
-	(*cf)->can_id = CAN_ERR_FLAG;
-	(*cf)->can_dlc = CAN_ERR_DLC;
-
-	return skb;
-}
-
 /*
  * Swtich transceiver on or off
  */
@@ -506,7 +474,7 @@ static void at91_read_mb(struct net_devi
 	reg_msr = at91_read(priv, AT91_MSR(mb));
 	if (reg_msr & AT91_MSR_MRTR)
 		cf->can_id |= CAN_RTR_FLAG;
-	cf->can_dlc = min_t(__u8, (reg_msr >> 16) & 0xf, 8);
+	cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf);
 
 	*(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
 	*(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
@@ -1069,7 +1037,7 @@ static int __init at91_can_probe(struct
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	if (!res || !irq) {
+	if (!res || irq <= 0) {
 		err = -ENODEV;
 		goto exit_put;
 	}
@@ -1087,7 +1055,7 @@ static int __init at91_can_probe(struct
 		goto exit_release;
 	}
 
-	dev = alloc_candev(sizeof(struct at91_priv));
+	dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM);
 	if (!dev) {
 		err = -ENOMEM;
 		goto exit_iounmap;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/bfin_can.c linux-libre-2.6.33-gnu1/drivers/net/can/bfin_can.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/bfin_can.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/bfin_can.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,783 @@
+/*
+ * Blackfin On-Chip CAN Driver
+ *
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include <asm/portmux.h>
+
+#define DRV_NAME "bfin_can"
+#define BFIN_CAN_TIMEOUT 100
+
+/*
+ * transmit and receive channels
+ */
+#define TRANSMIT_CHL            24
+#define RECEIVE_STD_CHL         0
+#define RECEIVE_EXT_CHL         4
+#define RECEIVE_RTR_CHL         8
+#define RECEIVE_EXT_RTR_CHL     12
+#define MAX_CHL_NUMBER          32
+
+/*
+ * bfin can registers layout
+ */
+struct bfin_can_mask_regs {
+	u16 aml;
+	u16 dummy1;
+	u16 amh;
+	u16 dummy2;
+};
+
+struct bfin_can_channel_regs {
+	u16 data[8];
+	u16 dlc;
+	u16 dummy1;
+	u16 tsv;
+	u16 dummy2;
+	u16 id0;
+	u16 dummy3;
+	u16 id1;
+	u16 dummy4;
+};
+
+struct bfin_can_regs {
+	/*
+	 * global control and status registers
+	 */
+	u16 mc1;           /* offset 0 */
+	u16 dummy1;
+	u16 md1;           /* offset 4 */
+	u16 rsv1[13];
+	u16 mbtif1;        /* offset 0x20 */
+	u16 dummy2;
+	u16 mbrif1;        /* offset 0x24 */
+	u16 dummy3;
+	u16 mbim1;         /* offset 0x28 */
+	u16 rsv2[11];
+	u16 mc2;           /* offset 0x40 */
+	u16 dummy4;
+	u16 md2;           /* offset 0x44 */
+	u16 dummy5;
+	u16 trs2;          /* offset 0x48 */
+	u16 rsv3[11];
+	u16 mbtif2;        /* offset 0x60 */
+	u16 dummy6;
+	u16 mbrif2;        /* offset 0x64 */
+	u16 dummy7;
+	u16 mbim2;         /* offset 0x68 */
+	u16 rsv4[11];
+	u16 clk;           /* offset 0x80 */
+	u16 dummy8;
+	u16 timing;        /* offset 0x84 */
+	u16 rsv5[3];
+	u16 status;        /* offset 0x8c */
+	u16 dummy9;
+	u16 cec;           /* offset 0x90 */
+	u16 dummy10;
+	u16 gis;           /* offset 0x94 */
+	u16 dummy11;
+	u16 gim;           /* offset 0x98 */
+	u16 rsv6[3];
+	u16 ctrl;          /* offset 0xa0 */
+	u16 dummy12;
+	u16 intr;          /* offset 0xa4 */
+	u16 rsv7[7];
+	u16 esr;           /* offset 0xb4 */
+	u16 rsv8[37];
+
+	/*
+	 * channel(mailbox) mask and message registers
+	 */
+	struct bfin_can_mask_regs msk[MAX_CHL_NUMBER];    /* offset 0x100 */
+	struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
+};
+
+/*
+ * bfin can private data
+ */
+struct bfin_can_priv {
+	struct can_priv can;	/* must be the first member */
+	struct net_device *dev;
+	void __iomem *membase;
+	int rx_irq;
+	int tx_irq;
+	int err_irq;
+	unsigned short *pin_list;
+};
+
+/*
+ * bfin can timing parameters
+ */
+static struct can_bittiming_const bfin_can_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 1,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	/*
+	 * Although the BRP field can be set to any value, it is recommended
+	 * that the value be greater than or equal to 4, as restrictions
+	 * apply to the bit timing configuration when BRP is less than 4.
+	 */
+	.brp_min = 4,
+	.brp_max = 1024,
+	.brp_inc = 1,
+};
+
+static int bfin_can_set_bittiming(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u16 clk, timing;
+
+	clk = bt->brp - 1;
+	timing = ((bt->sjw - 1) << 8) | (bt->prop_seg + bt->phase_seg1 - 1) |
+		((bt->phase_seg2 - 1) << 4);
+
+	/*
+	 * If the SAM bit is set, the input signal is oversampled three times
+	 * at the SCLK rate.
+	 */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+		timing |= SAM;
+
+	bfin_write16(&reg->clk, clk);
+	bfin_write16(&reg->timing, timing);
+
+	dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n",
+			clk, timing);
+
+	return 0;
+}
+
+static void bfin_can_set_reset_mode(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	int timeout = BFIN_CAN_TIMEOUT;
+	int i;
+
+	/* disable interrupts */
+	bfin_write16(&reg->mbim1, 0);
+	bfin_write16(&reg->mbim2, 0);
+	bfin_write16(&reg->gim, 0);
+
+	/* reset can and enter configuration mode */
+	bfin_write16(&reg->ctrl, SRS | CCR);
+	SSYNC();
+	bfin_write16(&reg->ctrl, CCR);
+	SSYNC();
+	while (!(bfin_read16(&reg->ctrl) & CCA)) {
+		udelay(10);
+		if (--timeout == 0) {
+			dev_err(dev->dev.parent,
+					"fail to enter configuration mode\n");
+			BUG();
+		}
+	}
+
+	/*
+	 * All mailbox configurations are marked as inactive
+	 * by writing to CAN Mailbox Configuration Registers 1 and 2
+	 * For all bits: 0 - Mailbox disabled, 1 - Mailbox enabled
+	 */
+	bfin_write16(&reg->mc1, 0);
+	bfin_write16(&reg->mc2, 0);
+
+	/* Set Mailbox Direction */
+	bfin_write16(&reg->md1, 0xFFFF);   /* mailbox 1-16 are RX */
+	bfin_write16(&reg->md2, 0);   /* mailbox 17-32 are TX */
+
+	/* RECEIVE_STD_CHL */
+	for (i = 0; i < 2; i++) {
+		bfin_write16(&reg->chl[RECEIVE_STD_CHL + i].id0, 0);
+		bfin_write16(&reg->chl[RECEIVE_STD_CHL + i].id1, AME);
+		bfin_write16(&reg->chl[RECEIVE_STD_CHL + i].dlc, 0);
+		bfin_write16(&reg->msk[RECEIVE_STD_CHL + i].amh, 0x1FFF);
+		bfin_write16(&reg->msk[RECEIVE_STD_CHL + i].aml, 0xFFFF);
+	}
+
+	/* RECEIVE_EXT_CHL */
+	for (i = 0; i < 2; i++) {
+		bfin_write16(&reg->chl[RECEIVE_EXT_CHL + i].id0, 0);
+		bfin_write16(&reg->chl[RECEIVE_EXT_CHL + i].id1, AME | IDE);
+		bfin_write16(&reg->chl[RECEIVE_EXT_CHL + i].dlc, 0);
+		bfin_write16(&reg->msk[RECEIVE_EXT_CHL + i].amh, 0x1FFF);
+		bfin_write16(&reg->msk[RECEIVE_EXT_CHL + i].aml, 0xFFFF);
+	}
+
+	bfin_write16(&reg->mc2, BIT(TRANSMIT_CHL - 16));
+	bfin_write16(&reg->mc1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL));
+	SSYNC();
+
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+static void bfin_can_set_normal_mode(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	int timeout = BFIN_CAN_TIMEOUT;
+
+	/*
+	 * leave configuration mode
+	 */
+	bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) & ~CCR);
+
+	while (bfin_read16(&reg->status) & CCA) {
+		udelay(10);
+		if (--timeout == 0) {
+			dev_err(dev->dev.parent,
+					"fail to leave configuration mode\n");
+			BUG();
+		}
+	}
+
+	/*
+	 * clear _All_  tx and rx interrupts
+	 */
+	bfin_write16(&reg->mbtif1, 0xFFFF);
+	bfin_write16(&reg->mbtif2, 0xFFFF);
+	bfin_write16(&reg->mbrif1, 0xFFFF);
+	bfin_write16(&reg->mbrif2, 0xFFFF);
+
+	/*
+	 * clear global interrupt status register
+	 */
+	bfin_write16(&reg->gis, 0x7FF); /* overwrites with '1' */
+
+	/*
+	 * Initialize Interrupts
+	 * - set bits in the mailbox interrupt mask register
+	 * - global interrupt mask
+	 */
+	bfin_write16(&reg->mbim1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL));
+	bfin_write16(&reg->mbim2, BIT(TRANSMIT_CHL - 16));
+
+	bfin_write16(&reg->gim, EPIM | BOIM | RMLIM);
+	SSYNC();
+}
+
+static void bfin_can_start(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+
+	/* enter reset mode */
+	if (priv->can.state != CAN_STATE_STOPPED)
+		bfin_can_set_reset_mode(dev);
+
+	/* leave reset mode */
+	bfin_can_set_normal_mode(dev);
+}
+
+static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	switch (mode) {
+	case CAN_MODE_START:
+		bfin_can_start(dev);
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u8 dlc = cf->can_dlc;
+	canid_t id = cf->can_id;
+	u8 *data = cf->data;
+	u16 val;
+	int i;
+
+	netif_stop_queue(dev);
+
+	/* fill id */
+	if (id & CAN_EFF_FLAG) {
+		bfin_write16(&reg->chl[TRANSMIT_CHL].id0, id);
+		if (id & CAN_RTR_FLAG)
+			writew(((id & 0x1FFF0000) >> 16) | IDE | AME | RTR,
+					&reg->chl[TRANSMIT_CHL].id1);
+		else
+			writew(((id & 0x1FFF0000) >> 16) | IDE | AME,
+					&reg->chl[TRANSMIT_CHL].id1);
+
+	} else {
+		if (id & CAN_RTR_FLAG)
+			writew((id << 2) | AME | RTR,
+				&reg->chl[TRANSMIT_CHL].id1);
+		else
+			bfin_write16(&reg->chl[TRANSMIT_CHL].id1,
+					(id << 2) | AME);
+	}
+
+	/* fill payload */
+	for (i = 0; i < 8; i += 2) {
+		val = ((7 - i) < dlc ? (data[7 - i]) : 0) +
+			((6 - i) < dlc ? (data[6 - i] << 8) : 0);
+		bfin_write16(&reg->chl[TRANSMIT_CHL].data[i], val);
+	}
+
+	/* fill data length code */
+	bfin_write16(&reg->chl[TRANSMIT_CHL].dlc, dlc);
+
+	dev->trans_start = jiffies;
+
+	can_put_echo_skb(skb, dev, 0);
+
+	/* set transmit request */
+	bfin_write16(&reg->trs2, BIT(TRANSMIT_CHL - 16));
+
+	return 0;
+}
+
+static void bfin_can_rx(struct net_device *dev, u16 isrc)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	int obj;
+	int i;
+	u16 val;
+
+	skb = alloc_can_skb(dev, &cf);
+	if (skb == NULL)
+		return;
+
+	/* get id */
+	if (isrc & BIT(RECEIVE_EXT_CHL)) {
+		/* extended frame format (EFF) */
+		cf->can_id = ((bfin_read16(&reg->chl[RECEIVE_EXT_CHL].id1)
+			     & 0x1FFF) << 16)
+			     + bfin_read16(&reg->chl[RECEIVE_EXT_CHL].id0);
+		cf->can_id |= CAN_EFF_FLAG;
+		obj = RECEIVE_EXT_CHL;
+	} else {
+		/* standard frame format (SFF) */
+		cf->can_id = (bfin_read16(&reg->chl[RECEIVE_STD_CHL].id1)
+			     & 0x1ffc) >> 2;
+		obj = RECEIVE_STD_CHL;
+	}
+	if (bfin_read16(&reg->chl[obj].id1) & RTR)
+		cf->can_id |= CAN_RTR_FLAG;
+
+	/* get data length code */
+	cf->can_dlc = get_can_dlc(bfin_read16(&reg->chl[obj].dlc) & 0xF);
+
+	/* get payload */
+	for (i = 0; i < 8; i += 2) {
+		val = bfin_read16(&reg->chl[obj].data[i]);
+		cf->data[7 - i] = (7 - i) < cf->can_dlc ? val : 0;
+		cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0;
+	}
+
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+}
+
+static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	enum can_state state = priv->can.state;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	if (isrc & RMLIS) {
+		/* data overrun interrupt */
+		dev_dbg(dev->dev.parent, "data overrun interrupt\n");
+		cf->can_id |= CAN_ERR_CRTL;
+		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+	}
+
+	if (isrc & BOIS) {
+		dev_dbg(dev->dev.parent, "bus-off mode interrupt\n");
+		state = CAN_STATE_BUS_OFF;
+		cf->can_id |= CAN_ERR_BUSOFF;
+		can_bus_off(dev);
+	}
+
+	if (isrc & EPIS) {
+		/* error passive interrupt */
+		dev_dbg(dev->dev.parent, "error passive interrupt\n");
+		state = CAN_STATE_ERROR_PASSIVE;
+	}
+
+	if ((isrc & EWTIS) || (isrc & EWRIS)) {
+		dev_dbg(dev->dev.parent,
+				"Error Warning Transmit/Receive Interrupt\n");
+		state = CAN_STATE_ERROR_WARNING;
+	}
+
+	if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
+				state == CAN_STATE_ERROR_PASSIVE)) {
+		u16 cec = bfin_read16(&reg->cec);
+		u8 rxerr = cec;
+		u8 txerr = cec >> 8;
+
+		cf->can_id |= CAN_ERR_CRTL;
+		if (state == CAN_STATE_ERROR_WARNING) {
+			priv->can.can_stats.error_warning++;
+			cf->data[1] = (txerr > rxerr) ?
+				CAN_ERR_CRTL_TX_WARNING :
+				CAN_ERR_CRTL_RX_WARNING;
+		} else {
+			priv->can.can_stats.error_passive++;
+			cf->data[1] = (txerr > rxerr) ?
+				CAN_ERR_CRTL_TX_PASSIVE :
+				CAN_ERR_CRTL_RX_PASSIVE;
+		}
+	}
+
+	if (status) {
+		priv->can.can_stats.bus_error++;
+
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+		if (status & BEF)
+			cf->data[2] |= CAN_ERR_PROT_BIT;
+		else if (status & FER)
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+		else if (status & SER)
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+		else
+			cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+	}
+
+	priv->can.state = state;
+
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+
+	return 0;
+}
+
+irqreturn_t bfin_can_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	struct net_device_stats *stats = &dev->stats;
+	u16 status, isrc;
+
+	if ((irq == priv->tx_irq) && bfin_read16(&reg->mbtif2)) {
+		/* transmission complete interrupt */
+		bfin_write16(&reg->mbtif2, 0xFFFF);
+		stats->tx_packets++;
+		stats->tx_bytes += bfin_read16(&reg->chl[TRANSMIT_CHL].dlc);
+		can_get_echo_skb(dev, 0);
+		netif_wake_queue(dev);
+	} else if ((irq == priv->rx_irq) && bfin_read16(&reg->mbrif1)) {
+		/* receive interrupt */
+		isrc = bfin_read16(&reg->mbrif1);
+		bfin_write16(&reg->mbrif1, 0xFFFF);
+		bfin_can_rx(dev, isrc);
+	} else if ((irq == priv->err_irq) && bfin_read16(&reg->gis)) {
+		/* error interrupt */
+		isrc = bfin_read16(&reg->gis);
+		status = bfin_read16(&reg->esr);
+		bfin_write16(&reg->gis, 0x7FF);
+		bfin_can_err(dev, isrc, status);
+	} else {
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int bfin_can_open(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	int err;
+
+	/* set chip into reset mode */
+	bfin_can_set_reset_mode(dev);
+
+	/* common open */
+	err = open_candev(dev);
+	if (err)
+		goto exit_open;
+
+	/* register interrupt handler */
+	err = request_irq(priv->rx_irq, &bfin_can_interrupt, 0,
+			"bfin-can-rx", dev);
+	if (err)
+		goto exit_rx_irq;
+	err = request_irq(priv->tx_irq, &bfin_can_interrupt, 0,
+			"bfin-can-tx", dev);
+	if (err)
+		goto exit_tx_irq;
+	err = request_irq(priv->err_irq, &bfin_can_interrupt, 0,
+			"bfin-can-err", dev);
+	if (err)
+		goto exit_err_irq;
+
+	bfin_can_start(dev);
+
+	netif_start_queue(dev);
+
+	return 0;
+
+exit_err_irq:
+	free_irq(priv->tx_irq, dev);
+exit_tx_irq:
+	free_irq(priv->rx_irq, dev);
+exit_rx_irq:
+	close_candev(dev);
+exit_open:
+	return err;
+}
+
+static int bfin_can_close(struct net_device *dev)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	bfin_can_set_reset_mode(dev);
+
+	close_candev(dev);
+
+	free_irq(priv->rx_irq, dev);
+	free_irq(priv->tx_irq, dev);
+	free_irq(priv->err_irq, dev);
+
+	return 0;
+}
+
+struct net_device *alloc_bfin_candev(void)
+{
+	struct net_device *dev;
+	struct bfin_can_priv *priv;
+
+	dev = alloc_candev(sizeof(*priv));
+	if (!dev)
+		return NULL;
+
+	priv = netdev_priv(dev);
+
+	priv->dev = dev;
+	priv->can.bittiming_const = &bfin_can_bittiming_const;
+	priv->can.do_set_bittiming = bfin_can_set_bittiming;
+	priv->can.do_set_mode = bfin_can_set_mode;
+
+	return dev;
+}
+
+static const struct net_device_ops bfin_can_netdev_ops = {
+	.ndo_open               = bfin_can_open,
+	.ndo_stop               = bfin_can_close,
+	.ndo_start_xmit         = bfin_can_start_xmit,
+};
+
+static int __devinit bfin_can_probe(struct platform_device *pdev)
+{
+	int err;
+	struct net_device *dev;
+	struct bfin_can_priv *priv;
+	struct resource *res_mem, *rx_irq, *tx_irq, *err_irq;
+	unsigned short *pdata;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data provided!\n");
+		err = -EINVAL;
+		goto exit;
+	}
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	rx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	tx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+	err_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+	if (!res_mem || !rx_irq || !tx_irq || !err_irq) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	if (!request_mem_region(res_mem->start, resource_size(res_mem),
+				dev_name(&pdev->dev))) {
+		err = -EBUSY;
+		goto exit;
+	}
+
+	/* request peripheral pins */
+	err = peripheral_request_list(pdata, dev_name(&pdev->dev));
+	if (err)
+		goto exit_mem_release;
+
+	dev = alloc_bfin_candev();
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_peri_pin_free;
+	}
+
+	priv = netdev_priv(dev);
+	priv->membase = (void __iomem *)res_mem->start;
+	priv->rx_irq = rx_irq->start;
+	priv->tx_irq = tx_irq->start;
+	priv->err_irq = err_irq->start;
+	priv->pin_list = pdata;
+	priv->can.clock.freq = get_sclk();
+
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	dev->flags |= IFF_ECHO;	/* we support local echo */
+	dev->netdev_ops = &bfin_can_netdev_ops;
+
+	bfin_can_set_reset_mode(dev);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&pdev->dev, "registering failed (err=%d)\n", err);
+		goto exit_candev_free;
+	}
+
+	dev_info(&pdev->dev,
+		"%s device registered"
+		"(&reg_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n",
+		DRV_NAME, (void *)priv->membase, priv->rx_irq,
+		priv->tx_irq, priv->err_irq, priv->can.clock.freq);
+	return 0;
+
+exit_candev_free:
+	free_candev(dev);
+exit_peri_pin_free:
+	peripheral_free_list(pdata);
+exit_mem_release:
+	release_mem_region(res_mem->start, resource_size(res_mem));
+exit:
+	return err;
+}
+
+static int __devexit bfin_can_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct resource *res;
+
+	bfin_can_set_reset_mode(dev);
+
+	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));
+
+	peripheral_free_list(priv->pin_list);
+
+	free_candev(dev);
+	return 0;
+}
+
+#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 bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+	int timeout = BFIN_CAN_TIMEOUT;
+
+	if (netif_running(dev)) {
+		/* enter sleep mode */
+		bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) | SMR);
+		SSYNC();
+		while (!(bfin_read16(&reg->intr) & SMACK)) {
+			udelay(10);
+			if (--timeout == 0) {
+				dev_err(dev->dev.parent,
+						"fail to enter sleep mode\n");
+				BUG();
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int bfin_can_resume(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+
+	if (netif_running(dev)) {
+		/* leave sleep mode */
+		bfin_write16(&reg->intr, 0);
+		SSYNC();
+	}
+
+	return 0;
+}
+#else
+#define bfin_can_suspend NULL
+#define bfin_can_resume NULL
+#endif	/* CONFIG_PM */
+
+static struct platform_driver bfin_can_driver = {
+	.probe = bfin_can_probe,
+	.remove = __devexit_p(bfin_can_remove),
+	.suspend = bfin_can_suspend,
+	.resume = bfin_can_resume,
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init bfin_can_init(void)
+{
+	return platform_driver_register(&bfin_can_driver);
+}
+module_init(bfin_can_init);
+
+static void __exit bfin_can_exit(void)
+{
+	platform_driver_unregister(&bfin_can_driver);
+}
+module_exit(bfin_can_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Blackfin on-chip CAN netdevice driver");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/dev.c linux-libre-2.6.33-gnu1/drivers/net/can/dev.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct ne
 	struct net_device_stats *stats = &dev->stats;
 	int i;
 
-	for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
+	for (i = 0; i < priv->echo_skb_max; i++) {
 		if (priv->echo_skb[i]) {
 			kfree_skb(priv->echo_skb[i]);
 			priv->echo_skb[i] = NULL;
@@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct ne
  * of the device driver. The driver must protect access to
  * priv->echo_skb, if necessary.
  */
-void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+		      unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	/* check flag whether this packet has to be looped back */
 	if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
 		kfree_skb(skb);
@@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
  * is handled in the device driver. The driver must protect
  * access to priv->echo_skb, if necessary.
  */
-void can_get_echo_skb(struct net_device *dev, int idx)
+void can_get_echo_skb(struct net_device *dev, unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	if (priv->echo_skb[idx]) {
 		netif_rx(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
@@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
   *
   * The function is typically called when TX failed.
   */
-void can_free_echo_skb(struct net_device *dev, int idx)
+void can_free_echo_skb(struct net_device *dev, unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	if (priv->echo_skb[idx]) {
 		kfree_skb(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
@@ -359,17 +366,12 @@ void can_restart(unsigned long data)
 	can_flush_echo_skb(dev);
 
 	/* send restart message upstream */
-	skb = dev_alloc_skb(sizeof(struct can_frame));
+	skb = alloc_can_err_skb(dev, &cf);
 	if (skb == NULL) {
 		err = -ENOMEM;
 		goto restart;
 	}
-	skb->dev = dev;
-	skb->protocol = htons(ETH_P_CAN);
-	cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-	memset(cf, 0, sizeof(struct can_frame));
-	cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
-	cf->can_dlc = CAN_ERR_DLC;
+	cf->can_id |= CAN_ERR_RESTARTED;
 
 	netif_rx(skb);
 
@@ -442,20 +444,66 @@ static void can_setup(struct net_device
 	dev->features = NETIF_F_NO_CSUM;
 }
 
+struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
+{
+	struct sk_buff *skb;
+
+	skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
+	if (unlikely(!skb))
+		return NULL;
+
+	skb->protocol = htons(ETH_P_CAN);
+	skb->pkt_type = PACKET_BROADCAST;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+	memset(*cf, 0, sizeof(struct can_frame));
+
+	return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_skb);
+
+struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_can_skb(dev, cf);
+	if (unlikely(!skb))
+		return NULL;
+
+	(*cf)->can_id = CAN_ERR_FLAG;
+	(*cf)->can_dlc = CAN_ERR_DLC;
+
+	return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_err_skb);
+
 /*
  * Allocate and setup space for the CAN network device
  */
-struct net_device *alloc_candev(int sizeof_priv)
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
 {
 	struct net_device *dev;
 	struct can_priv *priv;
+	int size;
 
-	dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
+	if (echo_skb_max)
+		size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
+			echo_skb_max * sizeof(struct sk_buff *);
+	else
+		size = sizeof_priv;
+
+	dev = alloc_netdev(size, "can%d", can_setup);
 	if (!dev)
 		return NULL;
 
 	priv = netdev_priv(dev);
 
+	if (echo_skb_max) {
+		priv->echo_skb_max = echo_skb_max;
+		priv->echo_skb = (void *)priv +
+			ALIGN(sizeof_priv, sizeof(struct sk_buff *));
+	}
+
 	priv->state = CAN_STATE_STOPPED;
 
 	init_timer(&priv->restart_timer);
@@ -647,7 +695,7 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
-static int can_newlink(struct net_device *dev,
+static int can_newlink(struct net *src_net, struct net_device *dev,
 		       struct nlattr *tb[], struct nlattr *data[])
 {
 	return -EOPNOTSUPP;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/Kconfig linux-libre-2.6.33-gnu1/drivers/net/can/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/can/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,30 @@ config CAN_AT91
 	---help---
 	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
 
+config CAN_TI_HECC
+	depends on CAN_DEV && ARCH_OMAP3
+	tristate "TI High End CAN Controller"
+	---help---
+	  Driver for TI HECC (High End CAN Controller) module found on many
+	  TI devices. The device specifications are available from www.ti.com
+
+config CAN_MCP251X
+	tristate "Microchip MCP251x SPI CAN controllers"
+	depends on CAN_DEV && SPI && HAS_DMA
+	---help---
+	  Driver for the Microchip MCP251x SPI CAN controllers.
+
+config CAN_BFIN
+	depends on CAN_DEV && (BF534 || BF536 || BF537 || BF538 || BF539 || BF54x)
+	tristate "Analog Devices Blackfin on-chip CAN"
+	---help---
+	  Driver for the Analog Devices Blackfin on-chip CAN controllers
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin_can.
+
+source "drivers/net/can/mscan/Kconfig"
+
 source "drivers/net/can/sja1000/Kconfig"
 
 source "drivers/net/can/usb/Kconfig"
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/Makefile linux-libre-2.6.33-gnu1/drivers/net/can/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/can/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,10 @@ can-dev-y			:= dev.o
 obj-y				+= usb/
 
 obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
+obj-$(CONFIG_CAN_MSCAN)		+= mscan/
 obj-$(CONFIG_CAN_AT91)		+= at91_can.o
+obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
+obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
+obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mcp251x.c linux-libre-2.6.33-gnu1/drivers/net/can/mcp251x.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/mcp251x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mcp251x.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1159 @@
+/*
+ * CAN bus driver for Microchip 251x CAN Controller with SPI Interface
+ *
+ * MCP2510 support and bug fixes by Christian Pellegrin
+ * <chripell@evolware.org>
+ *
+ * Copyright 2009 Christian Pellegrin EVOL S.r.l.
+ *
+ * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved.
+ * Written under contract by:
+ *   Chris Elston, Katalix Systems, Ltd.
+ *
+ * Based on Microchip MCP251x CAN controller driver written by
+ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
+ *
+ * Based on CAN bus driver for the CCAN controller written by
+ * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
+ * - Simon Kallweit, intefo AG
+ * Copyright 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ *
+ * Your platform definition file should specify something like:
+ *
+ * static struct mcp251x_platform_data mcp251x_info = {
+ *         .oscillator_frequency = 8000000,
+ *         .board_specific_setup = &mcp251x_setup,
+ *         .model = CAN_MCP251X_MCP2510,
+ *         .power_enable = mcp251x_power_enable,
+ *         .transceiver_enable = NULL,
+ * };
+ *
+ * static struct spi_board_info spi_board_info[] = {
+ *         {
+ *                 .modalias = "mcp251x",
+ *                 .platform_data = &mcp251x_info,
+ *                 .irq = IRQ_EINT13,
+ *                 .max_speed_hz = 2*1000*1000,
+ *                 .chip_select = 2,
+ *         },
+ * };
+ *
+ * Please see mcp251x.h for a description of the fields in
+ * struct mcp251x_platform_data.
+ *
+ */
+
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/mcp251x.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/uaccess.h>
+
+/* SPI interface instruction set */
+#define INSTRUCTION_WRITE	0x02
+#define INSTRUCTION_READ	0x03
+#define INSTRUCTION_BIT_MODIFY	0x05
+#define INSTRUCTION_LOAD_TXB(n)	(0x40 + 2 * (n))
+#define INSTRUCTION_READ_RXB(n)	(((n) == 0) ? 0x90 : 0x94)
+#define INSTRUCTION_RESET	0xC0
+
+/* MPC251x registers */
+#define CANSTAT	      0x0e
+#define CANCTRL	      0x0f
+#  define CANCTRL_REQOP_MASK	    0xe0
+#  define CANCTRL_REQOP_CONF	    0x80
+#  define CANCTRL_REQOP_LISTEN_ONLY 0x60
+#  define CANCTRL_REQOP_LOOPBACK    0x40
+#  define CANCTRL_REQOP_SLEEP	    0x20
+#  define CANCTRL_REQOP_NORMAL	    0x00
+#  define CANCTRL_OSM		    0x08
+#  define CANCTRL_ABAT		    0x10
+#define TEC	      0x1c
+#define REC	      0x1d
+#define CNF1	      0x2a
+#  define CNF1_SJW_SHIFT   6
+#define CNF2	      0x29
+#  define CNF2_BTLMODE	   0x80
+#  define CNF2_SAM         0x40
+#  define CNF2_PS1_SHIFT   3
+#define CNF3	      0x28
+#  define CNF3_SOF	   0x08
+#  define CNF3_WAKFIL	   0x04
+#  define CNF3_PHSEG2_MASK 0x07
+#define CANINTE	      0x2b
+#  define CANINTE_MERRE 0x80
+#  define CANINTE_WAKIE 0x40
+#  define CANINTE_ERRIE 0x20
+#  define CANINTE_TX2IE 0x10
+#  define CANINTE_TX1IE 0x08
+#  define CANINTE_TX0IE 0x04
+#  define CANINTE_RX1IE 0x02
+#  define CANINTE_RX0IE 0x01
+#define CANINTF	      0x2c
+#  define CANINTF_MERRF 0x80
+#  define CANINTF_WAKIF 0x40
+#  define CANINTF_ERRIF 0x20
+#  define CANINTF_TX2IF 0x10
+#  define CANINTF_TX1IF 0x08
+#  define CANINTF_TX0IF 0x04
+#  define CANINTF_RX1IF 0x02
+#  define CANINTF_RX0IF 0x01
+#define EFLG	      0x2d
+#  define EFLG_EWARN	0x01
+#  define EFLG_RXWAR	0x02
+#  define EFLG_TXWAR	0x04
+#  define EFLG_RXEP	0x08
+#  define EFLG_TXEP	0x10
+#  define EFLG_TXBO	0x20
+#  define EFLG_RX0OVR	0x40
+#  define EFLG_RX1OVR	0x80
+#define TXBCTRL(n)  (((n) * 0x10) + 0x30 + TXBCTRL_OFF)
+#  define TXBCTRL_ABTF	0x40
+#  define TXBCTRL_MLOA	0x20
+#  define TXBCTRL_TXERR 0x10
+#  define TXBCTRL_TXREQ 0x08
+#define TXBSIDH(n)  (((n) * 0x10) + 0x30 + TXBSIDH_OFF)
+#  define SIDH_SHIFT    3
+#define TXBSIDL(n)  (((n) * 0x10) + 0x30 + TXBSIDL_OFF)
+#  define SIDL_SID_MASK    7
+#  define SIDL_SID_SHIFT   5
+#  define SIDL_EXIDE_SHIFT 3
+#  define SIDL_EID_SHIFT   16
+#  define SIDL_EID_MASK    3
+#define TXBEID8(n)  (((n) * 0x10) + 0x30 + TXBEID8_OFF)
+#define TXBEID0(n)  (((n) * 0x10) + 0x30 + TXBEID0_OFF)
+#define TXBDLC(n)   (((n) * 0x10) + 0x30 + TXBDLC_OFF)
+#  define DLC_RTR_SHIFT    6
+#define TXBCTRL_OFF 0
+#define TXBSIDH_OFF 1
+#define TXBSIDL_OFF 2
+#define TXBEID8_OFF 3
+#define TXBEID0_OFF 4
+#define TXBDLC_OFF  5
+#define TXBDAT_OFF  6
+#define RXBCTRL(n)  (((n) * 0x10) + 0x60 + RXBCTRL_OFF)
+#  define RXBCTRL_BUKT	0x04
+#  define RXBCTRL_RXM0	0x20
+#  define RXBCTRL_RXM1	0x40
+#define RXBSIDH(n)  (((n) * 0x10) + 0x60 + RXBSIDH_OFF)
+#  define RXBSIDH_SHIFT 3
+#define RXBSIDL(n)  (((n) * 0x10) + 0x60 + RXBSIDL_OFF)
+#  define RXBSIDL_IDE   0x08
+#  define RXBSIDL_EID   3
+#  define RXBSIDL_SHIFT 5
+#define RXBEID8(n)  (((n) * 0x10) + 0x60 + RXBEID8_OFF)
+#define RXBEID0(n)  (((n) * 0x10) + 0x60 + RXBEID0_OFF)
+#define RXBDLC(n)   (((n) * 0x10) + 0x60 + RXBDLC_OFF)
+#  define RXBDLC_LEN_MASK  0x0f
+#  define RXBDLC_RTR       0x40
+#define RXBCTRL_OFF 0
+#define RXBSIDH_OFF 1
+#define RXBSIDL_OFF 2
+#define RXBEID8_OFF 3
+#define RXBEID0_OFF 4
+#define RXBDLC_OFF  5
+#define RXBDAT_OFF  6
+
+#define GET_BYTE(val, byte)			\
+	(((val) >> ((byte) * 8)) & 0xff)
+#define SET_BYTE(val, byte)			\
+	(((val) & 0xff) << ((byte) * 8))
+
+/*
+ * Buffer size required for the largest SPI transfer (i.e., reading a
+ * frame)
+ */
+#define CAN_FRAME_MAX_DATA_LEN	8
+#define SPI_TRANSFER_BUF_LEN	(6 + CAN_FRAME_MAX_DATA_LEN)
+#define CAN_FRAME_MAX_BITS	128
+
+#define TX_ECHO_SKB_MAX	1
+
+#define DEVICE_NAME "mcp251x"
+
+static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
+module_param(mcp251x_enable_dma, int, S_IRUGO);
+MODULE_PARM_DESC(mcp251x_enable_dma, "Enable SPI DMA. Default: 0 (Off)");
+
+static struct can_bittiming_const mcp251x_bittiming_const = {
+	.name = DEVICE_NAME,
+	.tseg1_min = 3,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 64,
+	.brp_inc = 1,
+};
+
+struct mcp251x_priv {
+	struct can_priv	   can;
+	struct net_device *net;
+	struct spi_device *spi;
+
+	struct mutex spi_lock; /* SPI buffer lock */
+	u8 *spi_tx_buf;
+	u8 *spi_rx_buf;
+	dma_addr_t spi_tx_dma;
+	dma_addr_t spi_rx_dma;
+
+	struct sk_buff *tx_skb;
+	int tx_len;
+	struct workqueue_struct *wq;
+	struct work_struct tx_work;
+	struct work_struct irq_work;
+	struct completion awake;
+	int wake;
+	int force_quit;
+	int after_suspend;
+#define AFTER_SUSPEND_UP 1
+#define AFTER_SUSPEND_DOWN 2
+#define AFTER_SUSPEND_POWER 4
+#define AFTER_SUSPEND_RESTART 8
+	int restart_tx;
+};
+
+static void mcp251x_clean(struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+
+	net->stats.tx_errors++;
+	if (priv->tx_skb)
+		dev_kfree_skb(priv->tx_skb);
+	if (priv->tx_len)
+		can_free_echo_skb(priv->net, 0);
+	priv->tx_skb = NULL;
+	priv->tx_len = 0;
+}
+
+/*
+ * Note about handling of error return of mcp251x_spi_trans: accessing
+ * registers via SPI is not really different conceptually than using
+ * normal I/O assembler instructions, although it's much more
+ * complicated from a practical POV. So it's not advisable to always
+ * check the return value of this function. Imagine that every
+ * read{b,l}, write{b,l} and friends would be bracketed in "if ( < 0)
+ * error();", it would be a great mess (well there are some situation
+ * when exception handling C++ like could be useful after all). So we
+ * just check that transfers are OK at the beginning of our
+ * conversation with the chip and to avoid doing really nasty things
+ * (like injecting bogus packets in the network stack).
+ */
+static int mcp251x_spi_trans(struct spi_device *spi, int len)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	struct spi_transfer t = {
+		.tx_buf = priv->spi_tx_buf,
+		.rx_buf = priv->spi_rx_buf,
+		.len = len,
+		.cs_change = 0,
+	};
+	struct spi_message m;
+	int ret;
+
+	spi_message_init(&m);
+
+	if (mcp251x_enable_dma) {
+		t.tx_dma = priv->spi_tx_dma;
+		t.rx_dma = priv->spi_rx_dma;
+		m.is_dma_mapped = 1;
+	}
+
+	spi_message_add_tail(&t, &m);
+
+	ret = spi_sync(spi, &m);
+	if (ret)
+		dev_err(&spi->dev, "spi transfer failed: ret = %d\n", ret);
+	return ret;
+}
+
+static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	u8 val = 0;
+
+	mutex_lock(&priv->spi_lock);
+
+	priv->spi_tx_buf[0] = INSTRUCTION_READ;
+	priv->spi_tx_buf[1] = reg;
+
+	mcp251x_spi_trans(spi, 3);
+	val = priv->spi_rx_buf[2];
+
+	mutex_unlock(&priv->spi_lock);
+
+	return val;
+}
+
+static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+	mutex_lock(&priv->spi_lock);
+
+	priv->spi_tx_buf[0] = INSTRUCTION_WRITE;
+	priv->spi_tx_buf[1] = reg;
+	priv->spi_tx_buf[2] = val;
+
+	mcp251x_spi_trans(spi, 3);
+
+	mutex_unlock(&priv->spi_lock);
+}
+
+static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
+			       u8 mask, uint8_t val)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+	mutex_lock(&priv->spi_lock);
+
+	priv->spi_tx_buf[0] = INSTRUCTION_BIT_MODIFY;
+	priv->spi_tx_buf[1] = reg;
+	priv->spi_tx_buf[2] = mask;
+	priv->spi_tx_buf[3] = val;
+
+	mcp251x_spi_trans(spi, 4);
+
+	mutex_unlock(&priv->spi_lock);
+}
+
+static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
+				int len, int tx_buf_idx)
+{
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+	if (pdata->model == CAN_MCP251X_MCP2510) {
+		int i;
+
+		for (i = 1; i < TXBDAT_OFF + len; i++)
+			mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx) + i,
+					  buf[i]);
+	} else {
+		mutex_lock(&priv->spi_lock);
+		memcpy(priv->spi_tx_buf, buf, TXBDAT_OFF + len);
+		mcp251x_spi_trans(spi, TXBDAT_OFF + len);
+		mutex_unlock(&priv->spi_lock);
+	}
+}
+
+static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
+			  int tx_buf_idx)
+{
+	u32 sid, eid, exide, rtr;
+	u8 buf[SPI_TRANSFER_BUF_LEN];
+
+	exide = (frame->can_id & CAN_EFF_FLAG) ? 1 : 0; /* Extended ID Enable */
+	if (exide)
+		sid = (frame->can_id & CAN_EFF_MASK) >> 18;
+	else
+		sid = frame->can_id & CAN_SFF_MASK; /* Standard ID */
+	eid = frame->can_id & CAN_EFF_MASK; /* Extended ID */
+	rtr = (frame->can_id & CAN_RTR_FLAG) ? 1 : 0; /* Remote transmission */
+
+	buf[TXBCTRL_OFF] = INSTRUCTION_LOAD_TXB(tx_buf_idx);
+	buf[TXBSIDH_OFF] = sid >> SIDH_SHIFT;
+	buf[TXBSIDL_OFF] = ((sid & SIDL_SID_MASK) << SIDL_SID_SHIFT) |
+		(exide << SIDL_EXIDE_SHIFT) |
+		((eid >> SIDL_EID_SHIFT) & SIDL_EID_MASK);
+	buf[TXBEID8_OFF] = GET_BYTE(eid, 1);
+	buf[TXBEID0_OFF] = GET_BYTE(eid, 0);
+	buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
+	memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
+	mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
+	mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
+}
+
+static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
+				int buf_idx)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+
+	if (pdata->model == CAN_MCP251X_MCP2510) {
+		int i, len;
+
+		for (i = 1; i < RXBDAT_OFF; i++)
+			buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
+
+		len = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
+		for (; i < (RXBDAT_OFF + len); i++)
+			buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
+	} else {
+		mutex_lock(&priv->spi_lock);
+
+		priv->spi_tx_buf[RXBCTRL_OFF] = INSTRUCTION_READ_RXB(buf_idx);
+		mcp251x_spi_trans(spi, SPI_TRANSFER_BUF_LEN);
+		memcpy(buf, priv->spi_rx_buf, SPI_TRANSFER_BUF_LEN);
+
+		mutex_unlock(&priv->spi_lock);
+	}
+}
+
+static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	struct sk_buff *skb;
+	struct can_frame *frame;
+	u8 buf[SPI_TRANSFER_BUF_LEN];
+
+	skb = alloc_can_skb(priv->net, &frame);
+	if (!skb) {
+		dev_err(&spi->dev, "cannot allocate RX skb\n");
+		priv->net->stats.rx_dropped++;
+		return;
+	}
+
+	mcp251x_hw_rx_frame(spi, buf, buf_idx);
+	if (buf[RXBSIDL_OFF] & RXBSIDL_IDE) {
+		/* Extended ID format */
+		frame->can_id = CAN_EFF_FLAG;
+		frame->can_id |=
+			/* Extended ID part */
+			SET_BYTE(buf[RXBSIDL_OFF] & RXBSIDL_EID, 2) |
+			SET_BYTE(buf[RXBEID8_OFF], 1) |
+			SET_BYTE(buf[RXBEID0_OFF], 0) |
+			/* Standard ID part */
+			(((buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) |
+			  (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT)) << 18);
+		/* Remote transmission request */
+		if (buf[RXBDLC_OFF] & RXBDLC_RTR)
+			frame->can_id |= CAN_RTR_FLAG;
+	} else {
+		/* Standard ID format */
+		frame->can_id =
+			(buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) |
+			(buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT);
+	}
+	/* Data length */
+	frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
+	memcpy(frame->data, buf + RXBDAT_OFF, frame->can_dlc);
+
+	priv->net->stats.rx_packets++;
+	priv->net->stats.rx_bytes += frame->can_dlc;
+	netif_rx(skb);
+}
+
+static void mcp251x_hw_sleep(struct spi_device *spi)
+{
+	mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
+}
+
+static void mcp251x_hw_wakeup(struct spi_device *spi)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+	priv->wake = 1;
+
+	/* Can only wake up by generating a wake-up interrupt. */
+	mcp251x_write_bits(spi, CANINTE, CANINTE_WAKIE, CANINTE_WAKIE);
+	mcp251x_write_bits(spi, CANINTF, CANINTF_WAKIF, CANINTF_WAKIF);
+
+	/* Wait until the device is awake */
+	if (!wait_for_completion_timeout(&priv->awake, HZ))
+		dev_err(&spi->dev, "MCP251x didn't wake-up\n");
+}
+
+static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+					   struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+	struct spi_device *spi = priv->spi;
+
+	if (priv->tx_skb || priv->tx_len) {
+		dev_warn(&spi->dev, "hard_xmit called while tx busy\n");
+		netif_stop_queue(net);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (skb->len != sizeof(struct can_frame)) {
+		dev_err(&spi->dev, "dropping packet - bad length\n");
+		dev_kfree_skb(skb);
+		net->stats.tx_dropped++;
+		return NETDEV_TX_OK;
+	}
+
+	netif_stop_queue(net);
+	priv->tx_skb = skb;
+	net->trans_start = jiffies;
+	queue_work(priv->wq, &priv->tx_work);
+
+	return NETDEV_TX_OK;
+}
+
+static int mcp251x_do_set_mode(struct net_device *net, enum can_mode mode)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+
+	switch (mode) {
+	case CAN_MODE_START:
+		/* We have to delay work since SPI I/O may sleep */
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		priv->restart_tx = 1;
+		if (priv->can.restart_ms == 0)
+			priv->after_suspend = AFTER_SUSPEND_RESTART;
+		queue_work(priv->wq, &priv->irq_work);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static void mcp251x_set_normal_mode(struct spi_device *spi)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	unsigned long timeout;
+
+	/* Enable interrupts */
+	mcp251x_write_reg(spi, CANINTE,
+			  CANINTE_ERRIE | CANINTE_TX2IE | CANINTE_TX1IE |
+			  CANINTE_TX0IE | CANINTE_RX1IE | CANINTE_RX0IE |
+			  CANINTF_MERRF);
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		/* Put device into loopback mode */
+		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
+	} else {
+		/* Put device into normal mode */
+		mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
+
+		/* Wait for the device to enter normal mode */
+		timeout = jiffies + HZ;
+		while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) {
+			schedule();
+			if (time_after(jiffies, timeout)) {
+				dev_err(&spi->dev, "MCP251x didn't"
+					" enter in normal mode\n");
+				return;
+			}
+		}
+	}
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+static int mcp251x_do_set_bittiming(struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+	struct can_bittiming *bt = &priv->can.bittiming;
+	struct spi_device *spi = priv->spi;
+
+	mcp251x_write_reg(spi, CNF1, ((bt->sjw - 1) << CNF1_SJW_SHIFT) |
+			  (bt->brp - 1));
+	mcp251x_write_reg(spi, CNF2, CNF2_BTLMODE |
+			  (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+			   CNF2_SAM : 0) |
+			  ((bt->phase_seg1 - 1) << CNF2_PS1_SHIFT) |
+			  (bt->prop_seg - 1));
+	mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK,
+			   (bt->phase_seg2 - 1));
+	dev_info(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n",
+		 mcp251x_read_reg(spi, CNF1),
+		 mcp251x_read_reg(spi, CNF2),
+		 mcp251x_read_reg(spi, CNF3));
+
+	return 0;
+}
+
+static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
+			 struct spi_device *spi)
+{
+	mcp251x_do_set_bittiming(net);
+
+	/* Enable RX0->RX1 buffer roll over and disable filters */
+	mcp251x_write_bits(spi, RXBCTRL(0),
+			   RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1,
+			   RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
+	mcp251x_write_bits(spi, RXBCTRL(1),
+			   RXBCTRL_RXM0 | RXBCTRL_RXM1,
+			   RXBCTRL_RXM0 | RXBCTRL_RXM1);
+	return 0;
+}
+
+static void mcp251x_hw_reset(struct spi_device *spi)
+{
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	int ret;
+
+	mutex_lock(&priv->spi_lock);
+
+	priv->spi_tx_buf[0] = INSTRUCTION_RESET;
+
+	ret = spi_write(spi, priv->spi_tx_buf, 1);
+
+	mutex_unlock(&priv->spi_lock);
+
+	if (ret)
+		dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
+	/* Wait for reset to finish */
+	mdelay(10);
+}
+
+static int mcp251x_hw_probe(struct spi_device *spi)
+{
+	int st1, st2;
+
+	mcp251x_hw_reset(spi);
+
+	/*
+	 * Please note that these are "magic values" based on after
+	 * reset defaults taken from data sheet which allows us to see
+	 * if we really have a chip on the bus (we avoid common all
+	 * zeroes or all ones situations)
+	 */
+	st1 = mcp251x_read_reg(spi, CANSTAT) & 0xEE;
+	st2 = mcp251x_read_reg(spi, CANCTRL) & 0x17;
+
+	dev_dbg(&spi->dev, "CANSTAT 0x%02x CANCTRL 0x%02x\n", st1, st2);
+
+	/* Check for power up default values */
+	return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
+}
+
+static irqreturn_t mcp251x_can_isr(int irq, void *dev_id)
+{
+	struct net_device *net = (struct net_device *)dev_id;
+	struct mcp251x_priv *priv = netdev_priv(net);
+
+	/* Schedule bottom half */
+	if (!work_pending(&priv->irq_work))
+		queue_work(priv->wq, &priv->irq_work);
+
+	return IRQ_HANDLED;
+}
+
+static int mcp251x_open(struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+	struct spi_device *spi = priv->spi;
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	int ret;
+
+	ret = open_candev(net);
+	if (ret) {
+		dev_err(&spi->dev, "unable to set initial baudrate!\n");
+		return ret;
+	}
+
+	if (pdata->transceiver_enable)
+		pdata->transceiver_enable(1);
+
+	priv->force_quit = 0;
+	priv->tx_skb = NULL;
+	priv->tx_len = 0;
+
+	ret = request_irq(spi->irq, mcp251x_can_isr,
+			  IRQF_TRIGGER_FALLING, DEVICE_NAME, net);
+	if (ret) {
+		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
+		if (pdata->transceiver_enable)
+			pdata->transceiver_enable(0);
+		close_candev(net);
+		return ret;
+	}
+
+	mcp251x_hw_wakeup(spi);
+	mcp251x_hw_reset(spi);
+	ret = mcp251x_setup(net, priv, spi);
+	if (ret) {
+		free_irq(spi->irq, net);
+		mcp251x_hw_sleep(spi);
+		if (pdata->transceiver_enable)
+			pdata->transceiver_enable(0);
+		close_candev(net);
+		return ret;
+	}
+	mcp251x_set_normal_mode(spi);
+	netif_wake_queue(net);
+
+	return 0;
+}
+
+static int mcp251x_stop(struct net_device *net)
+{
+	struct mcp251x_priv *priv = netdev_priv(net);
+	struct spi_device *spi = priv->spi;
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+
+	close_candev(net);
+
+	/* Disable and clear pending interrupts */
+	mcp251x_write_reg(spi, CANINTE, 0x00);
+	mcp251x_write_reg(spi, CANINTF, 0x00);
+
+	priv->force_quit = 1;
+	free_irq(spi->irq, net);
+	flush_workqueue(priv->wq);
+
+	mcp251x_write_reg(spi, TXBCTRL(0), 0);
+	if (priv->tx_skb || priv->tx_len)
+		mcp251x_clean(net);
+
+	mcp251x_hw_sleep(spi);
+
+	if (pdata->transceiver_enable)
+		pdata->transceiver_enable(0);
+
+	priv->can.state = CAN_STATE_STOPPED;
+
+	return 0;
+}
+
+static void mcp251x_tx_work_handler(struct work_struct *ws)
+{
+	struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
+						 tx_work);
+	struct spi_device *spi = priv->spi;
+	struct net_device *net = priv->net;
+	struct can_frame *frame;
+
+	if (priv->tx_skb) {
+		frame = (struct can_frame *)priv->tx_skb->data;
+
+		if (priv->can.state == CAN_STATE_BUS_OFF) {
+			mcp251x_clean(net);
+			netif_wake_queue(net);
+			return;
+		}
+		if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
+			frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
+		mcp251x_hw_tx(spi, frame, 0);
+		priv->tx_len = 1 + frame->can_dlc;
+		can_put_echo_skb(priv->tx_skb, net, 0);
+		priv->tx_skb = NULL;
+	}
+}
+
+static void mcp251x_irq_work_handler(struct work_struct *ws)
+{
+	struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
+						 irq_work);
+	struct spi_device *spi = priv->spi;
+	struct net_device *net = priv->net;
+	u8 txbnctrl;
+	u8 intf;
+	enum can_state new_state;
+
+	if (priv->after_suspend) {
+		mdelay(10);
+		mcp251x_hw_reset(spi);
+		mcp251x_setup(net, priv, spi);
+		if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
+			mcp251x_set_normal_mode(spi);
+		} else if (priv->after_suspend & AFTER_SUSPEND_UP) {
+			netif_device_attach(net);
+			/* Clean since we lost tx buffer */
+			if (priv->tx_skb || priv->tx_len) {
+				mcp251x_clean(net);
+				netif_wake_queue(net);
+			}
+			mcp251x_set_normal_mode(spi);
+		} else {
+			mcp251x_hw_sleep(spi);
+		}
+		priv->after_suspend = 0;
+	}
+
+	if (priv->can.restart_ms == 0 && priv->can.state == CAN_STATE_BUS_OFF)
+		return;
+
+	while (!priv->force_quit && !freezing(current)) {
+		u8 eflag = mcp251x_read_reg(spi, EFLG);
+		int can_id = 0, data1 = 0;
+
+		mcp251x_write_reg(spi, EFLG, 0x00);
+
+		if (priv->restart_tx) {
+			priv->restart_tx = 0;
+			mcp251x_write_reg(spi, TXBCTRL(0), 0);
+			if (priv->tx_skb || priv->tx_len)
+				mcp251x_clean(net);
+			netif_wake_queue(net);
+			can_id |= CAN_ERR_RESTARTED;
+		}
+
+		if (priv->wake) {
+			/* Wait whilst the device wakes up */
+			mdelay(10);
+			priv->wake = 0;
+		}
+
+		intf = mcp251x_read_reg(spi, CANINTF);
+		mcp251x_write_bits(spi, CANINTF, intf, 0x00);
+
+		/* Update can state */
+		if (eflag & EFLG_TXBO) {
+			new_state = CAN_STATE_BUS_OFF;
+			can_id |= CAN_ERR_BUSOFF;
+		} else if (eflag & EFLG_TXEP) {
+			new_state = CAN_STATE_ERROR_PASSIVE;
+			can_id |= CAN_ERR_CRTL;
+			data1 |= CAN_ERR_CRTL_TX_PASSIVE;
+		} else if (eflag & EFLG_RXEP) {
+			new_state = CAN_STATE_ERROR_PASSIVE;
+			can_id |= CAN_ERR_CRTL;
+			data1 |= CAN_ERR_CRTL_RX_PASSIVE;
+		} else if (eflag & EFLG_TXWAR) {
+			new_state = CAN_STATE_ERROR_WARNING;
+			can_id |= CAN_ERR_CRTL;
+			data1 |= CAN_ERR_CRTL_TX_WARNING;
+		} else if (eflag & EFLG_RXWAR) {
+			new_state = CAN_STATE_ERROR_WARNING;
+			can_id |= CAN_ERR_CRTL;
+			data1 |= CAN_ERR_CRTL_RX_WARNING;
+		} else {
+			new_state = CAN_STATE_ERROR_ACTIVE;
+		}
+
+		/* Update can state statistics */
+		switch (priv->can.state) {
+		case CAN_STATE_ERROR_ACTIVE:
+			if (new_state >= CAN_STATE_ERROR_WARNING &&
+			    new_state <= CAN_STATE_BUS_OFF)
+				priv->can.can_stats.error_warning++;
+		case CAN_STATE_ERROR_WARNING:	/* fallthrough */
+			if (new_state >= CAN_STATE_ERROR_PASSIVE &&
+			    new_state <= CAN_STATE_BUS_OFF)
+				priv->can.can_stats.error_passive++;
+			break;
+		default:
+			break;
+		}
+		priv->can.state = new_state;
+
+		if ((intf & CANINTF_ERRIF) || (can_id & CAN_ERR_RESTARTED)) {
+			struct sk_buff *skb;
+			struct can_frame *frame;
+
+			/* Create error frame */
+			skb = alloc_can_err_skb(net, &frame);
+			if (skb) {
+				/* Set error frame flags based on bus state */
+				frame->can_id = can_id;
+				frame->data[1] = data1;
+
+				/* Update net stats for overflows */
+				if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) {
+					if (eflag & EFLG_RX0OVR)
+						net->stats.rx_over_errors++;
+					if (eflag & EFLG_RX1OVR)
+						net->stats.rx_over_errors++;
+					frame->can_id |= CAN_ERR_CRTL;
+					frame->data[1] |=
+						CAN_ERR_CRTL_RX_OVERFLOW;
+				}
+
+				netif_rx(skb);
+			} else {
+				dev_info(&spi->dev,
+					 "cannot allocate error skb\n");
+			}
+		}
+
+		if (priv->can.state == CAN_STATE_BUS_OFF) {
+			if (priv->can.restart_ms == 0) {
+				can_bus_off(net);
+				mcp251x_hw_sleep(spi);
+				return;
+			}
+		}
+
+		if (intf == 0)
+			break;
+
+		if (intf & CANINTF_WAKIF)
+			complete(&priv->awake);
+
+		if (intf & CANINTF_MERRF) {
+			/* If there are pending Tx buffers, restart queue */
+			txbnctrl = mcp251x_read_reg(spi, TXBCTRL(0));
+			if (!(txbnctrl & TXBCTRL_TXREQ)) {
+				if (priv->tx_skb || priv->tx_len)
+					mcp251x_clean(net);
+				netif_wake_queue(net);
+			}
+		}
+
+		if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
+			net->stats.tx_packets++;
+			net->stats.tx_bytes += priv->tx_len - 1;
+			if (priv->tx_len) {
+				can_get_echo_skb(net, 0);
+				priv->tx_len = 0;
+			}
+			netif_wake_queue(net);
+		}
+
+		if (intf & CANINTF_RX0IF)
+			mcp251x_hw_rx(spi, 0);
+
+		if (intf & CANINTF_RX1IF)
+			mcp251x_hw_rx(spi, 1);
+	}
+}
+
+static const struct net_device_ops mcp251x_netdev_ops = {
+	.ndo_open = mcp251x_open,
+	.ndo_stop = mcp251x_stop,
+	.ndo_start_xmit = mcp251x_hard_start_xmit,
+};
+
+static int __devinit mcp251x_can_probe(struct spi_device *spi)
+{
+	struct net_device *net;
+	struct mcp251x_priv *priv;
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	int ret = -ENODEV;
+
+	if (!pdata)
+		/* Platform data is required for osc freq */
+		goto error_out;
+
+	/* Allocate can/net device */
+	net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
+	if (!net) {
+		ret = -ENOMEM;
+		goto error_alloc;
+	}
+
+	net->netdev_ops = &mcp251x_netdev_ops;
+	net->flags |= IFF_ECHO;
+
+	priv = netdev_priv(net);
+	priv->can.bittiming_const = &mcp251x_bittiming_const;
+	priv->can.do_set_mode = mcp251x_do_set_mode;
+	priv->can.clock.freq = pdata->oscillator_frequency / 2;
+	priv->net = net;
+	dev_set_drvdata(&spi->dev, priv);
+
+	priv->spi = spi;
+	mutex_init(&priv->spi_lock);
+
+	/* If requested, allocate DMA buffers */
+	if (mcp251x_enable_dma) {
+		spi->dev.coherent_dma_mask = ~0;
+
+		/*
+		 * Minimum coherent DMA allocation is PAGE_SIZE, so allocate
+		 * that much and share it between Tx and Rx DMA buffers.
+		 */
+		priv->spi_tx_buf = dma_alloc_coherent(&spi->dev,
+						      PAGE_SIZE,
+						      &priv->spi_tx_dma,
+						      GFP_DMA);
+
+		if (priv->spi_tx_buf) {
+			priv->spi_rx_buf = (u8 *)(priv->spi_tx_buf +
+						  (PAGE_SIZE / 2));
+			priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
+							(PAGE_SIZE / 2));
+		} else {
+			/* Fall back to non-DMA */
+			mcp251x_enable_dma = 0;
+		}
+	}
+
+	/* Allocate non-DMA buffers */
+	if (!mcp251x_enable_dma) {
+		priv->spi_tx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
+		if (!priv->spi_tx_buf) {
+			ret = -ENOMEM;
+			goto error_tx_buf;
+		}
+		priv->spi_rx_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
+		if (!priv->spi_rx_buf) {
+			ret = -ENOMEM;
+			goto error_rx_buf;
+		}
+	}
+
+	if (pdata->power_enable)
+		pdata->power_enable(1);
+
+	/* Call out to platform specific setup */
+	if (pdata->board_specific_setup)
+		pdata->board_specific_setup(spi);
+
+	SET_NETDEV_DEV(net, &spi->dev);
+
+	priv->wq = create_freezeable_workqueue("mcp251x_wq");
+
+	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
+	INIT_WORK(&priv->irq_work, mcp251x_irq_work_handler);
+
+	init_completion(&priv->awake);
+
+	/* Configure the SPI bus */
+	spi->mode = SPI_MODE_0;
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+
+	if (!mcp251x_hw_probe(spi)) {
+		dev_info(&spi->dev, "Probe failed\n");
+		goto error_probe;
+	}
+	mcp251x_hw_sleep(spi);
+
+	if (pdata->transceiver_enable)
+		pdata->transceiver_enable(0);
+
+	ret = register_candev(net);
+	if (!ret) {
+		dev_info(&spi->dev, "probed\n");
+		return ret;
+	}
+error_probe:
+	if (!mcp251x_enable_dma)
+		kfree(priv->spi_rx_buf);
+error_rx_buf:
+	if (!mcp251x_enable_dma)
+		kfree(priv->spi_tx_buf);
+error_tx_buf:
+	free_candev(net);
+	if (mcp251x_enable_dma)
+		dma_free_coherent(&spi->dev, PAGE_SIZE,
+				  priv->spi_tx_buf, priv->spi_tx_dma);
+error_alloc:
+	if (pdata->power_enable)
+		pdata->power_enable(0);
+	dev_err(&spi->dev, "probe failed\n");
+error_out:
+	return ret;
+}
+
+static int __devexit mcp251x_can_remove(struct spi_device *spi)
+{
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	struct net_device *net = priv->net;
+
+	unregister_candev(net);
+	free_candev(net);
+
+	priv->force_quit = 1;
+	flush_workqueue(priv->wq);
+	destroy_workqueue(priv->wq);
+
+	if (mcp251x_enable_dma) {
+		dma_free_coherent(&spi->dev, PAGE_SIZE,
+				  priv->spi_tx_buf, priv->spi_tx_dma);
+	} else {
+		kfree(priv->spi_tx_buf);
+		kfree(priv->spi_rx_buf);
+	}
+
+	if (pdata->power_enable)
+		pdata->power_enable(0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mcp251x_can_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+	struct net_device *net = priv->net;
+
+	if (netif_running(net)) {
+		netif_device_detach(net);
+
+		mcp251x_hw_sleep(spi);
+		if (pdata->transceiver_enable)
+			pdata->transceiver_enable(0);
+		priv->after_suspend = AFTER_SUSPEND_UP;
+	} else {
+		priv->after_suspend = AFTER_SUSPEND_DOWN;
+	}
+
+	if (pdata->power_enable) {
+		pdata->power_enable(0);
+		priv->after_suspend |= AFTER_SUSPEND_POWER;
+	}
+
+	return 0;
+}
+
+static int mcp251x_can_resume(struct spi_device *spi)
+{
+	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+
+	if (priv->after_suspend & AFTER_SUSPEND_POWER) {
+		pdata->power_enable(1);
+		queue_work(priv->wq, &priv->irq_work);
+	} else {
+		if (priv->after_suspend & AFTER_SUSPEND_UP) {
+			if (pdata->transceiver_enable)
+				pdata->transceiver_enable(1);
+			queue_work(priv->wq, &priv->irq_work);
+		} else {
+			priv->after_suspend = 0;
+		}
+	}
+	return 0;
+}
+#else
+#define mcp251x_can_suspend NULL
+#define mcp251x_can_resume NULL
+#endif
+
+static struct spi_driver mcp251x_can_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+
+	.probe = mcp251x_can_probe,
+	.remove = __devexit_p(mcp251x_can_remove),
+	.suspend = mcp251x_can_suspend,
+	.resume = mcp251x_can_resume,
+};
+
+static int __init mcp251x_can_init(void)
+{
+	return spi_register_driver(&mcp251x_can_driver);
+}
+
+static void __exit mcp251x_can_exit(void)
+{
+	spi_unregister_driver(&mcp251x_can_driver);
+}
+
+module_init(mcp251x_can_init);
+module_exit(mcp251x_can_exit);
+
+MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
+	      "Christian Pellegrin <chripell@evolware.org>");
+MODULE_DESCRIPTION("Microchip 251x CAN driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mscan/Kconfig linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/can/mscan/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,23 @@
+config CAN_MSCAN
+	depends on CAN_DEV && (PPC || M68K || M68KNOMMU)
+	tristate "Support for Freescale MSCAN based chips"
+	---help---
+	  The Motorola Scalable Controller Area Network (MSCAN) definition
+	  is based on the MSCAN12 definition which is the specific
+	  implementation of the Motorola Scalable CAN concept targeted for
+	  the Motorola MC68HC12 Microcontroller Family.
+
+if CAN_MSCAN
+
+config CAN_MPC5XXX
+	tristate "Freescale MPC5xxx onboard CAN controller"
+	depends on PPC_MPC52xx
+	---help---
+	  If you say yes here you get support for Freescale's MPC5xxx
+	  onboard CAN controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called mscan-mpc5xxx.ko.
+
+endif
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mscan/Makefile linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/can/mscan/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mscan/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_CAN_MPC5XXX)	+= mscan-mpc5xxx.o
+mscan-mpc5xxx-objs		:= mscan.o mpc5xxx_can.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mpc5xxx_can.c linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mpc5xxx_can.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mpc5xxx_can.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mpc5xxx_can.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,259 @@
+/*
+ * CAN bus driver for the Freescale MPC5xxx embedded CPU.
+ *
+ * Copyright (C) 2004-2005 Andrey Volkov <avolkov@varma-el.com>,
+ *                         Varma Electronics Oy
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <linux/io.h>
+#include <asm/mpc52xx.h>
+
+#include "mscan.h"
+
+#define DRV_NAME "mpc5xxx_can"
+
+static struct of_device_id mpc52xx_cdm_ids[] __devinitdata = {
+	{ .compatible = "fsl,mpc5200-cdm", },
+	{}
+};
+
+/*
+ * Get frequency of the MSCAN clock source
+ *
+ * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock (IP_CLK)
+ * can be selected. According to the MPC5200 user's manual, the oscillator
+ * clock is the better choice as it has less jitter but due to a hardware
+ * bug, it can not be selected for the old MPC5200 Rev. A chips.
+ */
+
+static unsigned int  __devinit mpc52xx_can_clock_freq(struct of_device *of,
+						      int clock_src)
+{
+	unsigned int pvr;
+	struct mpc52xx_cdm  __iomem *cdm;
+	struct device_node *np_cdm;
+	unsigned int freq;
+	u32 val;
+
+	pvr = mfspr(SPRN_PVR);
+
+	freq = mpc5xxx_get_bus_frequency(of->node);
+	if (!freq)
+		return 0;
+
+	if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
+		return freq;
+
+	/* Determine SYS_XTAL_IN frequency from the clock domain settings */
+	np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
+	if (!np_cdm) {
+		dev_err(&of->dev, "can't get clock node!\n");
+		return 0;
+	}
+	cdm = of_iomap(np_cdm, 0);
+	of_node_put(np_cdm);
+
+	if (in_8(&cdm->ipb_clk_sel) & 0x1)
+		freq *= 2;
+	val = in_be32(&cdm->rstcfg);
+
+	freq *= (val & (1 << 5)) ? 8 : 4;
+	freq /= (val & (1 << 6)) ? 12 : 16;
+
+	iounmap(cdm);
+
+	return freq;
+}
+
+static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
+				       const struct of_device_id *id)
+{
+	struct device_node *np = ofdev->node;
+	struct net_device *dev;
+	struct mscan_priv *priv;
+	void __iomem *base;
+	const char *clk_src;
+	int err, irq, clock_src;
+
+	base = of_iomap(ofdev->node, 0);
+	if (!base) {
+		dev_err(&ofdev->dev, "couldn't ioremap\n");
+		err = -ENOMEM;
+		goto exit_release_mem;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (!irq) {
+		dev_err(&ofdev->dev, "no irq found\n");
+		err = -ENODEV;
+		goto exit_unmap_mem;
+	}
+
+	dev = alloc_mscandev();
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_dispose_irq;
+	}
+
+	priv = netdev_priv(dev);
+	priv->reg_base = base;
+	dev->irq = irq;
+
+	/*
+	 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
+	 * (IP_CLK) can be selected as MSCAN clock source. According to
+	 * the MPC5200 user's manual, the oscillator clock is the better
+	 * choice as it has less jitter. For this reason, it is selected
+	 * by default.
+	 */
+	clk_src = of_get_property(np, "fsl,mscan-clock-source", NULL);
+	if (clk_src && strcmp(clk_src, "ip") == 0)
+		clock_src = MSCAN_CLKSRC_BUS;
+	else
+		clock_src = MSCAN_CLKSRC_XTAL;
+	priv->can.clock.freq = mpc52xx_can_clock_freq(ofdev, clock_src);
+	if (!priv->can.clock.freq) {
+		dev_err(&ofdev->dev, "couldn't get MSCAN clock frequency\n");
+		err = -ENODEV;
+		goto exit_free_mscan;
+	}
+
+	SET_NETDEV_DEV(dev, &ofdev->dev);
+
+	err = register_mscandev(dev, clock_src);
+	if (err) {
+		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_free_mscan;
+	}
+
+	dev_set_drvdata(&ofdev->dev, dev);
+
+	dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
+		 priv->reg_base, dev->irq, priv->can.clock.freq);
+
+	return 0;
+
+exit_free_mscan:
+	free_candev(dev);
+exit_dispose_irq:
+	irq_dispose_mapping(irq);
+exit_unmap_mem:
+	iounmap(base);
+exit_release_mem:
+	return err;
+}
+
+static int __devexit mpc5xxx_can_remove(struct of_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	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);
+	free_candev(dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static struct mscan_regs saved_regs;
+static int mpc5xxx_can_suspend(struct of_device *ofdev, pm_message_t state)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+	_memcpy_fromio(&saved_regs, regs, sizeof(*regs));
+
+	return 0;
+}
+
+static int mpc5xxx_can_resume(struct of_device *ofdev)
+{
+	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+	regs->canctl0 |= MSCAN_INITRQ;
+	while (!(regs->canctl1 & MSCAN_INITAK))
+		udelay(10);
+
+	regs->canctl1 = saved_regs.canctl1;
+	regs->canbtr0 = saved_regs.canbtr0;
+	regs->canbtr1 = saved_regs.canbtr1;
+	regs->canidac = saved_regs.canidac;
+
+	/* restore masks, buffers etc. */
+	_memcpy_toio(&regs->canidar1_0, (void *)&saved_regs.canidar1_0,
+		     sizeof(*regs) - offsetof(struct mscan_regs, canidar1_0));
+
+	regs->canctl0 &= ~MSCAN_INITRQ;
+	regs->cantbsel = saved_regs.cantbsel;
+	regs->canrier = saved_regs.canrier;
+	regs->cantier = saved_regs.cantier;
+	regs->canctl0 = saved_regs.canctl0;
+
+	return 0;
+}
+#endif
+
+static struct of_device_id __devinitdata mpc5xxx_can_table[] = {
+	{.compatible = "fsl,mpc5200-mscan"},
+	{},
+};
+
+static struct of_platform_driver mpc5xxx_can_driver = {
+	.owner = THIS_MODULE,
+	.name = "mpc5xxx_can",
+	.probe = mpc5xxx_can_probe,
+	.remove = __devexit_p(mpc5xxx_can_remove),
+#ifdef CONFIG_PM
+	.suspend = mpc5xxx_can_suspend,
+	.resume = mpc5xxx_can_resume,
+#endif
+	.match_table = mpc5xxx_can_table,
+};
+
+static int __init mpc5xxx_can_init(void)
+{
+	return of_register_platform_driver(&mpc5xxx_can_driver);
+}
+module_init(mpc5xxx_can_init);
+
+static void __exit mpc5xxx_can_exit(void)
+{
+	return of_unregister_platform_driver(&mpc5xxx_can_driver);
+};
+module_exit(mpc5xxx_can_exit);
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Freescale MPC5200 CAN driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mscan.c linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mscan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,669 @@
+/*
+ * CAN bus driver for the alone generic (as possible as) MSCAN controller.
+ *
+ * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
+ *                         Varma Electronics Oy
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ * Copytight (C) 2008-2009 Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/list.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/io.h>
+
+#include "mscan.h"
+
+static struct can_bittiming_const mscan_bittiming_const = {
+	.name = "mscan",
+	.tseg1_min = 4,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 64,
+	.brp_inc = 1,
+};
+
+struct mscan_state {
+	u8 mode;
+	u8 canrier;
+	u8 cantier;
+};
+
+static enum can_state state_map[] = {
+	CAN_STATE_ERROR_ACTIVE,
+	CAN_STATE_ERROR_WARNING,
+	CAN_STATE_ERROR_PASSIVE,
+	CAN_STATE_BUS_OFF
+};
+
+static int mscan_set_mode(struct net_device *dev, u8 mode)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	int ret = 0;
+	int i;
+	u8 canctl1;
+
+	if (mode != MSCAN_NORMAL_MODE) {
+		if (priv->tx_active) {
+			/* Abort transfers before going to sleep */#
+			out_8(&regs->cantarq, priv->tx_active);
+			/* Suppress TX done interrupts */
+			out_8(&regs->cantier, 0);
+		}
+
+		canctl1 = in_8(&regs->canctl1);
+		if ((mode & MSCAN_SLPRQ) && !(canctl1 & MSCAN_SLPAK)) {
+			setbits8(&regs->canctl0, MSCAN_SLPRQ);
+			for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+				if (in_8(&regs->canctl1) & MSCAN_SLPAK)
+					break;
+				udelay(100);
+			}
+			/*
+			 * The mscan controller will fail to enter sleep mode,
+			 * while there are irregular activities on bus, like
+			 * somebody keeps retransmitting. This behavior is
+			 * undocumented and seems to differ between mscan built
+			 * in mpc5200b and mpc5200. We proceed in that case,
+			 * since otherwise the slprq will be kept set and the
+			 * controller will get stuck. NOTE: INITRQ or CSWAI
+			 * will abort all active transmit actions, if still
+			 * any, at once.
+			 */
+			if (i >= MSCAN_SET_MODE_RETRIES)
+				dev_dbg(dev->dev.parent,
+					"device failed to enter sleep mode. "
+					"We proceed anyhow.\n");
+			else
+				priv->can.state = CAN_STATE_SLEEPING;
+		}
+
+		if ((mode & MSCAN_INITRQ) && !(canctl1 & MSCAN_INITAK)) {
+			setbits8(&regs->canctl0, MSCAN_INITRQ);
+			for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+				if (in_8(&regs->canctl1) & MSCAN_INITAK)
+					break;
+			}
+			if (i >= MSCAN_SET_MODE_RETRIES)
+				ret = -ENODEV;
+		}
+		if (!ret)
+			priv->can.state = CAN_STATE_STOPPED;
+
+		if (mode & MSCAN_CSWAI)
+			setbits8(&regs->canctl0, MSCAN_CSWAI);
+
+	} else {
+		canctl1 = in_8(&regs->canctl1);
+		if (canctl1 & (MSCAN_SLPAK | MSCAN_INITAK)) {
+			clrbits8(&regs->canctl0, MSCAN_SLPRQ | MSCAN_INITRQ);
+			for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+				canctl1 = in_8(&regs->canctl1);
+				if (!(canctl1 & (MSCAN_INITAK | MSCAN_SLPAK)))
+					break;
+			}
+			if (i >= MSCAN_SET_MODE_RETRIES)
+				ret = -ENODEV;
+			else
+				priv->can.state = CAN_STATE_ERROR_ACTIVE;
+		}
+	}
+	return ret;
+}
+
+static int mscan_start(struct net_device *dev)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	u8 canrflg;
+	int err;
+
+	out_8(&regs->canrier, 0);
+
+	INIT_LIST_HEAD(&priv->tx_head);
+	priv->prev_buf_id = 0;
+	priv->cur_pri = 0;
+	priv->tx_active = 0;
+	priv->shadow_canrier = 0;
+	priv->flags = 0;
+
+	err = mscan_set_mode(dev, MSCAN_NORMAL_MODE);
+	if (err)
+		return err;
+
+	canrflg = in_8(&regs->canrflg);
+	priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
+	priv->can.state = state_map[max(MSCAN_STATE_RX(canrflg),
+				    MSCAN_STATE_TX(canrflg))];
+	out_8(&regs->cantier, 0);
+
+	/* Enable receive interrupts. */
+	out_8(&regs->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE |
+	      MSCAN_RSTATE1 | MSCAN_RSTATE0 | MSCAN_TSTATE1 | MSCAN_TSTATE0);
+
+	return 0;
+}
+
+static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct can_frame *frame = (struct can_frame *)skb->data;
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	int i, rtr, buf_id;
+	u32 can_id;
+
+	if (frame->can_dlc > 8)
+		return -EINVAL;
+
+	out_8(&regs->cantier, 0);
+
+	i = ~priv->tx_active & MSCAN_TXE;
+	buf_id = ffs(i) - 1;
+	switch (hweight8(i)) {
+	case 0:
+		netif_stop_queue(dev);
+		dev_err(dev->dev.parent, "Tx Ring full when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	case 1:
+		/*
+		 * if buf_id < 3, then current frame will be send out of order,
+		 * since buffer with lower id have higher priority (hell..)
+		 */
+		netif_stop_queue(dev);
+	case 2:
+		if (buf_id < priv->prev_buf_id) {
+			priv->cur_pri++;
+			if (priv->cur_pri == 0xff) {
+				set_bit(F_TX_WAIT_ALL, &priv->flags);
+				netif_stop_queue(dev);
+			}
+		}
+		set_bit(F_TX_PROGRESS, &priv->flags);
+		break;
+	}
+	priv->prev_buf_id = buf_id;
+	out_8(&regs->cantbsel, i);
+
+	rtr = frame->can_id & CAN_RTR_FLAG;
+
+	/* RTR is always the lowest bit of interest, then IDs follow */
+	if (frame->can_id & CAN_EFF_FLAG) {
+		can_id = (frame->can_id & CAN_EFF_MASK)
+			 << (MSCAN_EFF_RTR_SHIFT + 1);
+		if (rtr)
+			can_id |= 1 << MSCAN_EFF_RTR_SHIFT;
+		out_be16(&regs->tx.idr3_2, can_id);
+
+		can_id >>= 16;
+		/* EFF_FLAGS are inbetween the IDs :( */
+		can_id = (can_id & 0x7) | ((can_id << 2) & 0xffe0)
+			 | MSCAN_EFF_FLAGS;
+	} else {
+		can_id = (frame->can_id & CAN_SFF_MASK)
+			 << (MSCAN_SFF_RTR_SHIFT + 1);
+		if (rtr)
+			can_id |= 1 << MSCAN_SFF_RTR_SHIFT;
+	}
+	out_be16(&regs->tx.idr1_0, can_id);
+
+	if (!rtr) {
+		void __iomem *data = &regs->tx.dsr1_0;
+		u16 *payload = (u16 *)frame->data;
+
+		/* It is safe to write into dsr[dlc+1] */
+		for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
+			out_be16(data, *payload++);
+			data += 2 + _MSCAN_RESERVED_DSR_SIZE;
+		}
+	}
+
+	out_8(&regs->tx.dlr, frame->can_dlc);
+	out_8(&regs->tx.tbpr, priv->cur_pri);
+
+	/* Start transmission. */
+	out_8(&regs->cantflg, 1 << buf_id);
+
+	if (!test_bit(F_TX_PROGRESS, &priv->flags))
+		dev->trans_start = jiffies;
+
+	list_add_tail(&priv->tx_queue[buf_id].list, &priv->tx_head);
+
+	can_put_echo_skb(skb, dev, buf_id);
+
+	/* Enable interrupt. */
+	priv->tx_active |= 1 << buf_id;
+	out_8(&regs->cantier, priv->tx_active);
+
+	return NETDEV_TX_OK;
+}
+
+/* This function returns the old state to see where we came from */
+static enum can_state check_set_state(struct net_device *dev, u8 canrflg)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	enum can_state state, old_state = priv->can.state;
+
+	if (canrflg & MSCAN_CSCIF && old_state <= CAN_STATE_BUS_OFF) {
+		state = state_map[max(MSCAN_STATE_RX(canrflg),
+				      MSCAN_STATE_TX(canrflg))];
+		priv->can.state = state;
+	}
+	return old_state;
+}
+
+static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	u32 can_id;
+	int i;
+
+	can_id = in_be16(&regs->rx.idr1_0);
+	if (can_id & (1 << 3)) {
+		frame->can_id = CAN_EFF_FLAG;
+		can_id = ((can_id << 16) | in_be16(&regs->rx.idr3_2));
+		can_id = ((can_id & 0xffe00000) |
+			  ((can_id & 0x7ffff) << 2)) >> 2;
+	} else {
+		can_id >>= 4;
+		frame->can_id = 0;
+	}
+
+	frame->can_id |= can_id >> 1;
+	if (can_id & 1)
+		frame->can_id |= CAN_RTR_FLAG;
+
+	frame->can_dlc = get_can_dlc(in_8(&regs->rx.dlr) & 0xf);
+
+	if (!(frame->can_id & CAN_RTR_FLAG)) {
+		void __iomem *data = &regs->rx.dsr1_0;
+		u16 *payload = (u16 *)frame->data;
+
+		for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
+			*payload++ = in_be16(data);
+			data += 2 + _MSCAN_RESERVED_DSR_SIZE;
+		}
+	}
+
+	out_8(&regs->canrflg, MSCAN_RXF);
+}
+
+static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
+				u8 canrflg)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	struct net_device_stats *stats = &dev->stats;
+	enum can_state old_state;
+
+	dev_dbg(dev->dev.parent, "error interrupt (canrflg=%#x)\n", canrflg);
+	frame->can_id = CAN_ERR_FLAG;
+
+	if (canrflg & MSCAN_OVRIF) {
+		frame->can_id |= CAN_ERR_CRTL;
+		frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		stats->rx_over_errors++;
+		stats->rx_errors++;
+	} else {
+		frame->data[1] = 0;
+	}
+
+	old_state = check_set_state(dev, canrflg);
+	/* State changed */
+	if (old_state != priv->can.state) {
+		switch (priv->can.state) {
+		case CAN_STATE_ERROR_WARNING:
+			frame->can_id |= CAN_ERR_CRTL;
+			priv->can.can_stats.error_warning++;
+			if ((priv->shadow_statflg & MSCAN_RSTAT_MSK) <
+			    (canrflg & MSCAN_RSTAT_MSK))
+				frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+			if ((priv->shadow_statflg & MSCAN_TSTAT_MSK) <
+			    (canrflg & MSCAN_TSTAT_MSK))
+				frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			break;
+		case CAN_STATE_ERROR_PASSIVE:
+			frame->can_id |= CAN_ERR_CRTL;
+			priv->can.can_stats.error_passive++;
+			frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+			break;
+		case CAN_STATE_BUS_OFF:
+			frame->can_id |= CAN_ERR_BUSOFF;
+			/*
+			 * The MSCAN on the MPC5200 does recover from bus-off
+			 * automatically. To avoid that we stop the chip doing
+			 * a light-weight stop (we are in irq-context).
+			 */
+			out_8(&regs->cantier, 0);
+			out_8(&regs->canrier, 0);
+			setbits8(&regs->canctl0, MSCAN_SLPRQ | MSCAN_INITRQ);
+			can_bus_off(dev);
+			break;
+		default:
+			break;
+		}
+	}
+	priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
+	frame->can_dlc = CAN_ERR_DLC;
+	out_8(&regs->canrflg, MSCAN_ERR_IF);
+}
+
+static int mscan_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi);
+	struct net_device *dev = napi->dev;
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	struct net_device_stats *stats = &dev->stats;
+	int npackets = 0;
+	int ret = 1;
+	struct sk_buff *skb;
+	struct can_frame *frame;
+	u8 canrflg;
+
+	while (npackets < quota) {
+		canrflg = in_8(&regs->canrflg);
+		if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF)))
+			break;
+
+		skb = alloc_can_skb(dev, &frame);
+		if (!skb) {
+			if (printk_ratelimit())
+				dev_notice(dev->dev.parent, "packet dropped\n");
+			stats->rx_dropped++;
+			out_8(&regs->canrflg, canrflg);
+			continue;
+		}
+
+		if (canrflg & MSCAN_RXF)
+			mscan_get_rx_frame(dev, frame);
+		else if (canrflg & MSCAN_ERR_IF)
+			mscan_get_err_frame(dev, frame, canrflg);
+
+		stats->rx_packets++;
+		stats->rx_bytes += frame->can_dlc;
+		npackets++;
+		netif_receive_skb(skb);
+	}
+
+	if (!(in_8(&regs->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) {
+		napi_complete(&priv->napi);
+		clear_bit(F_RX_PROGRESS, &priv->flags);
+		if (priv->can.state < CAN_STATE_BUS_OFF)
+			out_8(&regs->canrier, priv->shadow_canrier);
+		ret = 0;
+	}
+	return ret;
+}
+
+static irqreturn_t mscan_isr(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	struct net_device_stats *stats = &dev->stats;
+	u8 cantier, cantflg, canrflg;
+	irqreturn_t ret = IRQ_NONE;
+
+	cantier = in_8(&regs->cantier) & MSCAN_TXE;
+	cantflg = in_8(&regs->cantflg) & cantier;
+
+	if (cantier && cantflg) {
+		struct list_head *tmp, *pos;
+
+		list_for_each_safe(pos, tmp, &priv->tx_head) {
+			struct tx_queue_entry *entry =
+			    list_entry(pos, struct tx_queue_entry, list);
+			u8 mask = entry->mask;
+
+			if (!(cantflg & mask))
+				continue;
+
+			out_8(&regs->cantbsel, mask);
+			stats->tx_bytes += in_8(&regs->tx.dlr);
+			stats->tx_packets++;
+			can_get_echo_skb(dev, entry->id);
+			priv->tx_active &= ~mask;
+			list_del(pos);
+		}
+
+		if (list_empty(&priv->tx_head)) {
+			clear_bit(F_TX_WAIT_ALL, &priv->flags);
+			clear_bit(F_TX_PROGRESS, &priv->flags);
+			priv->cur_pri = 0;
+		} else {
+			dev->trans_start = jiffies;
+		}
+
+		if (!test_bit(F_TX_WAIT_ALL, &priv->flags))
+			netif_wake_queue(dev);
+
+		out_8(&regs->cantier, priv->tx_active);
+		ret = IRQ_HANDLED;
+	}
+
+	canrflg = in_8(&regs->canrflg);
+	if ((canrflg & ~MSCAN_STAT_MSK) &&
+	    !test_and_set_bit(F_RX_PROGRESS, &priv->flags)) {
+		if (canrflg & ~MSCAN_STAT_MSK) {
+			priv->shadow_canrier = in_8(&regs->canrier);
+			out_8(&regs->canrier, 0);
+			napi_schedule(&priv->napi);
+			ret = IRQ_HANDLED;
+		} else {
+			clear_bit(F_RX_PROGRESS, &priv->flags);
+		}
+	}
+	return ret;
+}
+
+static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	int ret = 0;
+
+	if (!priv->open_time)
+		return -EINVAL;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		if (priv->can.state <= CAN_STATE_BUS_OFF)
+			mscan_set_mode(dev, MSCAN_INIT_MODE);
+		ret = mscan_start(dev);
+		if (ret)
+			break;
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+		break;
+
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+	return ret;
+}
+
+static int mscan_do_set_bittiming(struct net_device *dev)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	struct can_bittiming *bt = &priv->can.bittiming;
+	u8 btr0, btr1;
+
+	btr0 = BTR0_SET_BRP(bt->brp) | BTR0_SET_SJW(bt->sjw);
+	btr1 = (BTR1_SET_TSEG1(bt->prop_seg + bt->phase_seg1) |
+		BTR1_SET_TSEG2(bt->phase_seg2) |
+		BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES));
+
+	dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n",
+		btr0, btr1);
+
+	out_8(&regs->canbtr0, btr0);
+	out_8(&regs->canbtr1, btr1);
+
+	return 0;
+}
+
+static int mscan_open(struct net_device *dev)
+{
+	int ret;
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+	/* common open */
+	ret = open_candev(dev);
+	if (ret)
+		return ret;
+
+	napi_enable(&priv->napi);
+
+	ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev);
+	if (ret < 0) {
+		dev_err(dev->dev.parent, "failed to attach interrupt\n");
+		goto exit_napi_disable;
+	}
+
+	priv->open_time = jiffies;
+
+	clrbits8(&regs->canctl1, MSCAN_LISTEN);
+
+	ret = mscan_start(dev);
+	if (ret)
+		goto exit_free_irq;
+
+	netif_start_queue(dev);
+
+	return 0;
+
+exit_free_irq:
+	priv->open_time = 0;
+	free_irq(dev->irq, dev);
+exit_napi_disable:
+	napi_disable(&priv->napi);
+	close_candev(dev);
+	return ret;
+}
+
+static int mscan_close(struct net_device *dev)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+	netif_stop_queue(dev);
+	napi_disable(&priv->napi);
+
+	out_8(&regs->cantier, 0);
+	out_8(&regs->canrier, 0);
+	mscan_set_mode(dev, MSCAN_INIT_MODE);
+	close_candev(dev);
+	free_irq(dev->irq, dev);
+	priv->open_time = 0;
+
+	return 0;
+}
+
+static const struct net_device_ops mscan_netdev_ops = {
+       .ndo_open               = mscan_open,
+       .ndo_stop               = mscan_close,
+       .ndo_start_xmit         = mscan_start_xmit,
+};
+
+int register_mscandev(struct net_device *dev, int clock_src)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	u8 ctl1;
+
+	ctl1 = in_8(&regs->canctl1);
+	if (clock_src)
+		ctl1 |= MSCAN_CLKSRC;
+	else
+		ctl1 &= ~MSCAN_CLKSRC;
+
+	ctl1 |= MSCAN_CANE;
+	out_8(&regs->canctl1, ctl1);
+	udelay(100);
+
+	/* acceptance mask/acceptance code (accept everything) */
+	out_be16(&regs->canidar1_0, 0);
+	out_be16(&regs->canidar3_2, 0);
+	out_be16(&regs->canidar5_4, 0);
+	out_be16(&regs->canidar7_6, 0);
+
+	out_be16(&regs->canidmr1_0, 0xffff);
+	out_be16(&regs->canidmr3_2, 0xffff);
+	out_be16(&regs->canidmr5_4, 0xffff);
+	out_be16(&regs->canidmr7_6, 0xffff);
+	/* Two 32 bit Acceptance Filters */
+	out_8(&regs->canidac, MSCAN_AF_32BIT);
+
+	mscan_set_mode(dev, MSCAN_INIT_MODE);
+
+	return register_candev(dev);
+}
+
+void unregister_mscandev(struct net_device *dev)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+	mscan_set_mode(dev, MSCAN_INIT_MODE);
+	clrbits8(&regs->canctl1, MSCAN_CANE);
+	unregister_candev(dev);
+}
+
+struct net_device *alloc_mscandev(void)
+{
+	struct net_device *dev;
+	struct mscan_priv *priv;
+	int i;
+
+	dev = alloc_candev(sizeof(struct mscan_priv), MSCAN_ECHO_SKB_MAX);
+	if (!dev)
+		return NULL;
+	priv = netdev_priv(dev);
+
+	dev->netdev_ops = &mscan_netdev_ops;
+
+	dev->flags |= IFF_ECHO;	/* we support local echo */
+
+	netif_napi_add(dev, &priv->napi, mscan_rx_poll, 8);
+
+	priv->can.bittiming_const = &mscan_bittiming_const;
+	priv->can.do_set_bittiming = mscan_do_set_bittiming;
+	priv->can.do_set_mode = mscan_do_set_mode;
+
+	for (i = 0; i < TX_QUEUE_SIZE; i++) {
+		priv->tx_queue[i].id = i;
+		priv->tx_queue[i].mask = 1 << i;
+	}
+
+	return dev;
+}
+
+MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN port driver for a MSCAN based chips");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mscan.h linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.h
--- linux-libre-2.6.32-gnu1/drivers/net/can/mscan/mscan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/mscan/mscan.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,296 @@
+/*
+ * Definitions of consts/structs to drive the Freescale MSCAN.
+ *
+ * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
+ *                         Varma Electronics Oy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MSCAN_H__
+#define __MSCAN_H__
+
+#include <linux/types.h>
+
+/* MSCAN control register 0 (CANCTL0) bits */
+#define MSCAN_RXFRM		0x80
+#define MSCAN_RXACT		0x40
+#define MSCAN_CSWAI		0x20
+#define MSCAN_SYNCH		0x10
+#define MSCAN_TIME		0x08
+#define MSCAN_WUPE		0x04
+#define MSCAN_SLPRQ		0x02
+#define MSCAN_INITRQ		0x01
+
+/* MSCAN control register 1 (CANCTL1) bits */
+#define MSCAN_CANE		0x80
+#define MSCAN_CLKSRC		0x40
+#define MSCAN_LOOPB		0x20
+#define MSCAN_LISTEN		0x10
+#define MSCAN_WUPM		0x04
+#define MSCAN_SLPAK		0x02
+#define MSCAN_INITAK		0x01
+
+/* Use the MPC5200 MSCAN variant? */
+#ifdef CONFIG_PPC
+#define MSCAN_FOR_MPC5200
+#endif
+
+#ifdef MSCAN_FOR_MPC5200
+#define MSCAN_CLKSRC_BUS	0
+#define MSCAN_CLKSRC_XTAL	MSCAN_CLKSRC
+#else
+#define MSCAN_CLKSRC_BUS	MSCAN_CLKSRC
+#define MSCAN_CLKSRC_XTAL	0
+#endif
+
+/* MSCAN receiver flag register (CANRFLG) bits */
+#define MSCAN_WUPIF		0x80
+#define MSCAN_CSCIF		0x40
+#define MSCAN_RSTAT1		0x20
+#define MSCAN_RSTAT0		0x10
+#define MSCAN_TSTAT1		0x08
+#define MSCAN_TSTAT0		0x04
+#define MSCAN_OVRIF		0x02
+#define MSCAN_RXF		0x01
+#define MSCAN_ERR_IF 		(MSCAN_OVRIF | MSCAN_CSCIF)
+#define MSCAN_RSTAT_MSK		(MSCAN_RSTAT1 | MSCAN_RSTAT0)
+#define MSCAN_TSTAT_MSK		(MSCAN_TSTAT1 | MSCAN_TSTAT0)
+#define MSCAN_STAT_MSK		(MSCAN_RSTAT_MSK | MSCAN_TSTAT_MSK)
+
+#define MSCAN_STATE_BUS_OFF	(MSCAN_RSTAT1 | MSCAN_RSTAT0 | \
+				 MSCAN_TSTAT1 | MSCAN_TSTAT0)
+#define MSCAN_STATE_TX(canrflg)	(((canrflg)&MSCAN_TSTAT_MSK)>>2)
+#define MSCAN_STATE_RX(canrflg)	(((canrflg)&MSCAN_RSTAT_MSK)>>4)
+#define MSCAN_STATE_ACTIVE	0
+#define MSCAN_STATE_WARNING	1
+#define MSCAN_STATE_PASSIVE	2
+#define MSCAN_STATE_BUSOFF	3
+
+/* MSCAN receiver interrupt enable register (CANRIER) bits */
+#define MSCAN_WUPIE		0x80
+#define MSCAN_CSCIE		0x40
+#define MSCAN_RSTATE1		0x20
+#define MSCAN_RSTATE0		0x10
+#define MSCAN_TSTATE1		0x08
+#define MSCAN_TSTATE0		0x04
+#define MSCAN_OVRIE		0x02
+#define MSCAN_RXFIE		0x01
+
+/* MSCAN transmitter flag register (CANTFLG) bits */
+#define MSCAN_TXE2		0x04
+#define MSCAN_TXE1		0x02
+#define MSCAN_TXE0		0x01
+#define MSCAN_TXE		(MSCAN_TXE2 | MSCAN_TXE1 | MSCAN_TXE0)
+
+/* MSCAN transmitter interrupt enable register (CANTIER) bits */
+#define MSCAN_TXIE2		0x04
+#define MSCAN_TXIE1		0x02
+#define MSCAN_TXIE0		0x01
+#define MSCAN_TXIE		(MSCAN_TXIE2 | MSCAN_TXIE1 | MSCAN_TXIE0)
+
+/* MSCAN transmitter message abort request (CANTARQ) bits */
+#define MSCAN_ABTRQ2		0x04
+#define MSCAN_ABTRQ1		0x02
+#define MSCAN_ABTRQ0		0x01
+
+/* MSCAN transmitter message abort ack (CANTAAK) bits */
+#define MSCAN_ABTAK2		0x04
+#define MSCAN_ABTAK1		0x02
+#define MSCAN_ABTAK0		0x01
+
+/* MSCAN transmit buffer selection (CANTBSEL) bits */
+#define MSCAN_TX2		0x04
+#define MSCAN_TX1		0x02
+#define MSCAN_TX0		0x01
+
+/* MSCAN ID acceptance control register (CANIDAC) bits */
+#define MSCAN_IDAM1		0x20
+#define MSCAN_IDAM0		0x10
+#define MSCAN_IDHIT2		0x04
+#define MSCAN_IDHIT1		0x02
+#define MSCAN_IDHIT0		0x01
+
+#define MSCAN_AF_32BIT		0x00
+#define MSCAN_AF_16BIT		MSCAN_IDAM0
+#define MSCAN_AF_8BIT		MSCAN_IDAM1
+#define MSCAN_AF_CLOSED		(MSCAN_IDAM0|MSCAN_IDAM1)
+#define MSCAN_AF_MASK		(~(MSCAN_IDAM0|MSCAN_IDAM1))
+
+/* MSCAN Miscellaneous Register (CANMISC) bits */
+#define MSCAN_BOHOLD		0x01
+
+/* MSCAN Identifier Register (IDR) bits */
+#define MSCAN_SFF_RTR_SHIFT	4
+#define MSCAN_EFF_RTR_SHIFT	0
+#define MSCAN_EFF_FLAGS		0x18	/* IDE + SRR */
+
+#ifdef MSCAN_FOR_MPC5200
+#define _MSCAN_RESERVED_(n, num) u8 _res##n[num]
+#define _MSCAN_RESERVED_DSR_SIZE	2
+#else
+#define _MSCAN_RESERVED_(n, num)
+#define _MSCAN_RESERVED_DSR_SIZE	0
+#endif
+
+/* Structure of the hardware registers */
+struct mscan_regs {
+	/* (see doc S12MSCANV3/D)		  MPC5200    MSCAN */
+	u8 canctl0;				/* + 0x00     0x00 */
+	u8 canctl1;				/* + 0x01     0x01 */
+	_MSCAN_RESERVED_(1, 2);			/* + 0x02          */
+	u8 canbtr0;				/* + 0x04     0x02 */
+	u8 canbtr1;				/* + 0x05     0x03 */
+	_MSCAN_RESERVED_(2, 2);			/* + 0x06          */
+	u8 canrflg;				/* + 0x08     0x04 */
+	u8 canrier;				/* + 0x09     0x05 */
+	_MSCAN_RESERVED_(3, 2);			/* + 0x0a          */
+	u8 cantflg;				/* + 0x0c     0x06 */
+	u8 cantier;				/* + 0x0d     0x07 */
+	_MSCAN_RESERVED_(4, 2);			/* + 0x0e          */
+	u8 cantarq;				/* + 0x10     0x08 */
+	u8 cantaak;				/* + 0x11     0x09 */
+	_MSCAN_RESERVED_(5, 2);			/* + 0x12          */
+	u8 cantbsel;				/* + 0x14     0x0a */
+	u8 canidac;				/* + 0x15     0x0b */
+	u8 reserved;				/* + 0x16     0x0c */
+	_MSCAN_RESERVED_(6, 5);			/* + 0x17          */
+#ifndef MSCAN_FOR_MPC5200
+	u8 canmisc;				/*            0x0d */
+#endif
+	u8 canrxerr;				/* + 0x1c     0x0e */
+	u8 cantxerr;				/* + 0x1d     0x0f */
+	_MSCAN_RESERVED_(7, 2);			/* + 0x1e          */
+	u16 canidar1_0;				/* + 0x20     0x10 */
+	_MSCAN_RESERVED_(8, 2);			/* + 0x22          */
+	u16 canidar3_2;				/* + 0x24     0x12 */
+	_MSCAN_RESERVED_(9, 2);			/* + 0x26          */
+	u16 canidmr1_0;				/* + 0x28     0x14 */
+	_MSCAN_RESERVED_(10, 2);		/* + 0x2a          */
+	u16 canidmr3_2;				/* + 0x2c     0x16 */
+	_MSCAN_RESERVED_(11, 2);		/* + 0x2e          */
+	u16 canidar5_4;				/* + 0x30     0x18 */
+	_MSCAN_RESERVED_(12, 2);		/* + 0x32          */
+	u16 canidar7_6;				/* + 0x34     0x1a */
+	_MSCAN_RESERVED_(13, 2);		/* + 0x36          */
+	u16 canidmr5_4;				/* + 0x38     0x1c */
+	_MSCAN_RESERVED_(14, 2);		/* + 0x3a          */
+	u16 canidmr7_6;				/* + 0x3c     0x1e */
+	_MSCAN_RESERVED_(15, 2);		/* + 0x3e          */
+	struct {
+		u16 idr1_0;			/* + 0x40     0x20 */
+		 _MSCAN_RESERVED_(16, 2);	/* + 0x42          */
+		u16 idr3_2;			/* + 0x44     0x22 */
+		 _MSCAN_RESERVED_(17, 2);	/* + 0x46          */
+		u16 dsr1_0;			/* + 0x48     0x24 */
+		 _MSCAN_RESERVED_(18, 2);	/* + 0x4a          */
+		u16 dsr3_2;			/* + 0x4c     0x26 */
+		 _MSCAN_RESERVED_(19, 2);	/* + 0x4e          */
+		u16 dsr5_4;			/* + 0x50     0x28 */
+		 _MSCAN_RESERVED_(20, 2);	/* + 0x52          */
+		u16 dsr7_6;			/* + 0x54     0x2a */
+		 _MSCAN_RESERVED_(21, 2);	/* + 0x56          */
+		u8 dlr;				/* + 0x58     0x2c */
+		 u8:8;				/* + 0x59     0x2d */
+		 _MSCAN_RESERVED_(22, 2);	/* + 0x5a          */
+		u16 time;			/* + 0x5c     0x2e */
+	} rx;
+	 _MSCAN_RESERVED_(23, 2);		/* + 0x5e          */
+	struct {
+		u16 idr1_0;			/* + 0x60     0x30 */
+		 _MSCAN_RESERVED_(24, 2);	/* + 0x62          */
+		u16 idr3_2;			/* + 0x64     0x32 */
+		 _MSCAN_RESERVED_(25, 2);	/* + 0x66          */
+		u16 dsr1_0;			/* + 0x68     0x34 */
+		 _MSCAN_RESERVED_(26, 2);	/* + 0x6a          */
+		u16 dsr3_2;			/* + 0x6c     0x36 */
+		 _MSCAN_RESERVED_(27, 2);	/* + 0x6e          */
+		u16 dsr5_4;			/* + 0x70     0x38 */
+		 _MSCAN_RESERVED_(28, 2);	/* + 0x72          */
+		u16 dsr7_6;			/* + 0x74     0x3a */
+		 _MSCAN_RESERVED_(29, 2);	/* + 0x76          */
+		u8 dlr;				/* + 0x78     0x3c */
+		u8 tbpr;			/* + 0x79     0x3d */
+		 _MSCAN_RESERVED_(30, 2);	/* + 0x7a          */
+		u16 time;			/* + 0x7c     0x3e */
+	} tx;
+	 _MSCAN_RESERVED_(31, 2);		/* + 0x7e          */
+} __attribute__ ((packed));
+
+#undef _MSCAN_RESERVED_
+#define MSCAN_REGION 	sizeof(struct mscan)
+
+#define MSCAN_NORMAL_MODE	0
+#define MSCAN_SLEEP_MODE	MSCAN_SLPRQ
+#define MSCAN_INIT_MODE		(MSCAN_INITRQ | MSCAN_SLPRQ)
+#define MSCAN_POWEROFF_MODE	(MSCAN_CSWAI | MSCAN_SLPRQ)
+#define MSCAN_SET_MODE_RETRIES	255
+#define MSCAN_ECHO_SKB_MAX	3
+
+#define BTR0_BRP_MASK		0x3f
+#define BTR0_SJW_SHIFT		6
+#define BTR0_SJW_MASK		(0x3 << BTR0_SJW_SHIFT)
+
+#define BTR1_TSEG1_MASK 	0xf
+#define BTR1_TSEG2_SHIFT	4
+#define BTR1_TSEG2_MASK 	(0x7 << BTR1_TSEG2_SHIFT)
+#define BTR1_SAM_SHIFT  	7
+
+#define BTR0_SET_BRP(brp)	(((brp) - 1) & BTR0_BRP_MASK)
+#define BTR0_SET_SJW(sjw)	((((sjw) - 1) << BTR0_SJW_SHIFT) & \
+				 BTR0_SJW_MASK)
+
+#define BTR1_SET_TSEG1(tseg1)	(((tseg1) - 1) &  BTR1_TSEG1_MASK)
+#define BTR1_SET_TSEG2(tseg2)	((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & \
+				 BTR1_TSEG2_MASK)
+#define BTR1_SET_SAM(sam)	((sam) ? 1 << BTR1_SAM_SHIFT : 0)
+
+#define F_RX_PROGRESS	0
+#define F_TX_PROGRESS	1
+#define F_TX_WAIT_ALL	2
+
+#define TX_QUEUE_SIZE	3
+
+struct tx_queue_entry {
+	struct list_head list;
+	u8 mask;
+	u8 id;
+};
+
+struct mscan_priv {
+	struct can_priv can;	/* must be the first member */
+	long open_time;
+	unsigned long flags;
+	void __iomem *reg_base;	/* ioremap'ed address to registers */
+	u8 shadow_statflg;
+	u8 shadow_canrier;
+	u8 cur_pri;
+	u8 prev_buf_id;
+	u8 tx_active;
+
+	struct list_head tx_head;
+	struct tx_queue_entry tx_queue[TX_QUEUE_SIZE];
+	struct napi_struct napi;
+};
+
+extern struct net_device *alloc_mscandev(void);
+/*
+ * clock_src:
+ *	1 = The MSCAN clock source is the onchip Bus Clock.
+ *	0 = The MSCAN clock source is the chip Oscillator Clock.
+ */
+extern int register_mscandev(struct net_device *dev, int clock_src);
+extern void unregister_mscandev(struct net_device *dev);
+
+#endif /* __MSCAN_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/sja1000/sja1000.c linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/sja1000/sja1000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.c	2010-02-24 13:52:17.000000000 -0500
@@ -293,17 +293,14 @@ static void sja1000_rx(struct net_device
 	uint8_t fi;
 	uint8_t dreg;
 	canid_t id;
-	uint8_t dlc;
 	int i;
 
-	skb = dev_alloc_skb(sizeof(struct can_frame));
+	/* create zero'ed CAN frame buffer */
+	skb = alloc_can_skb(dev, &cf);
 	if (skb == NULL)
 		return;
-	skb->dev = dev;
-	skb->protocol = htons(ETH_P_CAN);
 
 	fi = priv->read_reg(priv, REG_FI);
-	dlc = fi & 0x0F;
 
 	if (fi & FI_FF) {
 		/* extended frame format (EFF) */
@@ -320,18 +317,15 @@ static void sja1000_rx(struct net_device
 		    | (priv->read_reg(priv, REG_ID2) >> 5);
 	}
 
-	if (fi & FI_RTR)
+	if (fi & FI_RTR) {
 		id |= CAN_RTR_FLAG;
+	} else {
+		cf->can_dlc = get_can_dlc(fi & 0x0F);
+		for (i = 0; i < cf->can_dlc; i++)
+			cf->data[i] = priv->read_reg(priv, dreg++);
+	}
 
-	cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-	memset(cf, 0, sizeof(struct can_frame));
 	cf->can_id = id;
-	cf->can_dlc = dlc;
-	for (i = 0; i < dlc; i++)
-		cf->data[i] = priv->read_reg(priv, dreg++);
-
-	while (i < 8)
-		cf->data[i++] = 0;
 
 	/* release receive buffer */
 	priv->write_reg(priv, REG_CMR, CMD_RRB);
@@ -339,7 +333,7 @@ static void sja1000_rx(struct net_device
 	netif_rx(skb);
 
 	stats->rx_packets++;
-	stats->rx_bytes += dlc;
+	stats->rx_bytes += cf->can_dlc;
 }
 
 static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
@@ -351,15 +345,9 @@ static int sja1000_err(struct net_device
 	enum can_state state = priv->can.state;
 	uint8_t ecc, alc;
 
-	skb = dev_alloc_skb(sizeof(struct can_frame));
+	skb = alloc_can_err_skb(dev, &cf);
 	if (skb == NULL)
 		return -ENOMEM;
-	skb->dev = dev;
-	skb->protocol = htons(ETH_P_CAN);
-	cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-	memset(cf, 0, sizeof(struct can_frame));
-	cf->can_id = CAN_ERR_FLAG;
-	cf->can_dlc = CAN_ERR_DLC;
 
 	if (isrc & IRQ_DOI) {
 		/* data overrun interrupt */
@@ -526,7 +514,7 @@ static int sja1000_open(struct net_devic
 
 	/* register interrupt handler, if not done by the device driver */
 	if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
-		err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags,
+		err = request_irq(dev->irq, sja1000_interrupt, priv->irq_flags,
 				  dev->name, (void *)dev);
 		if (err) {
 			close_candev(dev);
@@ -565,7 +553,8 @@ struct net_device *alloc_sja1000dev(int
 	struct net_device *dev;
 	struct sja1000_priv *priv;
 
-	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
+	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv,
+		SJA1000_ECHO_SKB_MAX);
 	if (!dev)
 		return NULL;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/sja1000/sja1000.h linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.h
--- linux-libre-2.6.32-gnu1/drivers/net/can/sja1000/sja1000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/sja1000/sja1000.h	2010-02-24 13:52:17.000000000 -0500
@@ -50,6 +50,8 @@
 #include <linux/can/dev.h>
 #include <linux/can/platform/sja1000.h>
 
+#define SJA1000_ECHO_SKB_MAX	1 /* the SJA1000 has one TX buffer object */
+
 #define SJA1000_MAX_IRQ 20	/* max. number of interrupts handled in ISR */
 
 /* SJA1000 registers - manual section 6.4 (Pelican Mode) */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/ti_hecc.c linux-libre-2.6.33-gnu1/drivers/net/can/ti_hecc.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/ti_hecc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/ti_hecc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,993 @@
+/*
+ * TI HECC (CAN) device driver
+ *
+ * This driver supports TI's HECC (High End CAN Controller module) and the
+ * specs for the same is available at <http://www.ti.com>
+ *
+ * Copyright (C) 2009 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.
+ *
+ */
+
+/*
+ * Your platform definitions should specify module ram offsets and interrupt
+ * number to use as follows:
+ *
+ * static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
+ *         .scc_hecc_offset        = 0,
+ *         .scc_ram_offset         = 0x3000,
+ *         .hecc_ram_offset        = 0x3000,
+ *         .mbx_offset             = 0x2000,
+ *         .int_line               = 0,
+ *         .revision               = 1,
+ * };
+ *
+ * Please see include/can/platform/ti_hecc.h for description of above fields
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/platform/ti_hecc.h>
+
+#define DRV_NAME "ti_hecc"
+#define HECC_MODULE_VERSION     "0.7"
+MODULE_VERSION(HECC_MODULE_VERSION);
+#define DRV_DESC "TI High End CAN Controller Driver " HECC_MODULE_VERSION
+
+/* TX / RX Mailbox Configuration */
+#define HECC_MAX_MAILBOXES	32	/* hardware mailboxes - do not change */
+#define MAX_TX_PRIO		0x3F	/* hardware value - do not change */
+
+/*
+ * Important Note: TX mailbox configuration
+ * TX mailboxes should be restricted to the number of SKB buffers to avoid
+ * maintaining SKB buffers separately. TX mailboxes should be a power of 2
+ * for the mailbox logic to work.  Top mailbox numbers are reserved for RX
+ * and lower mailboxes for TX.
+ *
+ * HECC_MAX_TX_MBOX	HECC_MB_TX_SHIFT
+ * 4 (default)		2
+ * 8			3
+ * 16			4
+ */
+#define HECC_MB_TX_SHIFT	2 /* as per table above */
+#define HECC_MAX_TX_MBOX	BIT(HECC_MB_TX_SHIFT)
+
+#define HECC_TX_PRIO_SHIFT	(HECC_MB_TX_SHIFT)
+#define HECC_TX_PRIO_MASK	(MAX_TX_PRIO << HECC_MB_TX_SHIFT)
+#define HECC_TX_MB_MASK		(HECC_MAX_TX_MBOX - 1)
+#define HECC_TX_MASK		((HECC_MAX_TX_MBOX - 1) | HECC_TX_PRIO_MASK)
+#define HECC_TX_MBOX_MASK	(~(BIT(HECC_MAX_TX_MBOX) - 1))
+#define HECC_DEF_NAPI_WEIGHT	HECC_MAX_RX_MBOX
+
+/*
+ * Important Note: RX mailbox configuration
+ * RX mailboxes are further logically split into two - main and buffer
+ * mailboxes. The goal is to get all packets into main mailboxes as
+ * driven by mailbox number and receive priority (higher to lower) and
+ * buffer mailboxes are used to receive pkts while main mailboxes are being
+ * processed. This ensures in-order packet reception.
+ *
+ * Here are the recommended values for buffer mailbox. Note that RX mailboxes
+ * start after TX mailboxes:
+ *
+ * HECC_MAX_RX_MBOX		HECC_RX_BUFFER_MBOX	No of buffer mailboxes
+ * 28				12			8
+ * 16				20			4
+ */
+
+#define HECC_MAX_RX_MBOX	(HECC_MAX_MAILBOXES - HECC_MAX_TX_MBOX)
+#define HECC_RX_BUFFER_MBOX	12 /* as per table above */
+#define HECC_RX_FIRST_MBOX	(HECC_MAX_MAILBOXES - 1)
+#define HECC_RX_HIGH_MBOX_MASK	(~(BIT(HECC_RX_BUFFER_MBOX) - 1))
+
+/* TI HECC module registers */
+#define HECC_CANME		0x0	/* Mailbox enable */
+#define HECC_CANMD		0x4	/* Mailbox direction */
+#define HECC_CANTRS		0x8	/* Transmit request set */
+#define HECC_CANTRR		0xC	/* Transmit request */
+#define HECC_CANTA		0x10	/* Transmission acknowledge */
+#define HECC_CANAA		0x14	/* Abort acknowledge */
+#define HECC_CANRMP		0x18	/* Receive message pending */
+#define HECC_CANRML		0x1C	/* Remote message lost */
+#define HECC_CANRFP		0x20	/* Remote frame pending */
+#define HECC_CANGAM		0x24	/* SECC only:Global acceptance mask */
+#define HECC_CANMC		0x28	/* Master control */
+#define HECC_CANBTC		0x2C	/* Bit timing configuration */
+#define HECC_CANES		0x30	/* Error and status */
+#define HECC_CANTEC		0x34	/* Transmit error counter */
+#define HECC_CANREC		0x38	/* Receive error counter */
+#define HECC_CANGIF0		0x3C	/* Global interrupt flag 0 */
+#define HECC_CANGIM		0x40	/* Global interrupt mask */
+#define HECC_CANGIF1		0x44	/* Global interrupt flag 1 */
+#define HECC_CANMIM		0x48	/* Mailbox interrupt mask */
+#define HECC_CANMIL		0x4C	/* Mailbox interrupt level */
+#define HECC_CANOPC		0x50	/* Overwrite protection control */
+#define HECC_CANTIOC		0x54	/* Transmit I/O control */
+#define HECC_CANRIOC		0x58	/* Receive I/O control */
+#define HECC_CANLNT		0x5C	/* HECC only: Local network time */
+#define HECC_CANTOC		0x60	/* HECC only: Time-out control */
+#define HECC_CANTOS		0x64	/* HECC only: Time-out status */
+#define HECC_CANTIOCE		0x68	/* SCC only:Enhanced TX I/O control */
+#define HECC_CANRIOCE		0x6C	/* SCC only:Enhanced RX I/O control */
+
+/* Mailbox registers */
+#define HECC_CANMID		0x0
+#define HECC_CANMCF		0x4
+#define HECC_CANMDL		0x8
+#define HECC_CANMDH		0xC
+
+#define HECC_SET_REG		0xFFFFFFFF
+#define HECC_CANID_MASK		0x3FF	/* 18 bits mask for extended id's */
+#define HECC_CCE_WAIT_COUNT     100	/* Wait for ~1 sec for CCE bit */
+
+#define HECC_CANMC_SCM		BIT(13)	/* SCC compat mode */
+#define HECC_CANMC_CCR		BIT(12)	/* Change config request */
+#define HECC_CANMC_PDR		BIT(11)	/* Local Power down - for sleep mode */
+#define HECC_CANMC_ABO		BIT(7)	/* Auto Bus On */
+#define HECC_CANMC_STM		BIT(6)	/* Self test mode - loopback */
+#define HECC_CANMC_SRES		BIT(5)	/* Software reset */
+
+#define HECC_CANTIOC_EN		BIT(3)	/* Enable CAN TX I/O pin */
+#define HECC_CANRIOC_EN		BIT(3)	/* Enable CAN RX I/O pin */
+
+#define HECC_CANMID_IDE		BIT(31)	/* Extended frame format */
+#define HECC_CANMID_AME		BIT(30)	/* Acceptance mask enable */
+#define HECC_CANMID_AAM		BIT(29)	/* Auto answer mode */
+
+#define HECC_CANES_FE		BIT(24)	/* form error */
+#define HECC_CANES_BE		BIT(23)	/* bit error */
+#define HECC_CANES_SA1		BIT(22)	/* stuck at dominant error */
+#define HECC_CANES_CRCE		BIT(21)	/* CRC error */
+#define HECC_CANES_SE		BIT(20)	/* stuff bit error */
+#define HECC_CANES_ACKE		BIT(19)	/* ack error */
+#define HECC_CANES_BO		BIT(18)	/* Bus off status */
+#define HECC_CANES_EP		BIT(17)	/* Error passive status */
+#define HECC_CANES_EW		BIT(16)	/* Error warning status */
+#define HECC_CANES_SMA		BIT(5)	/* suspend mode ack */
+#define HECC_CANES_CCE		BIT(4)	/* Change config enabled */
+#define HECC_CANES_PDA		BIT(3)	/* Power down mode ack */
+
+#define HECC_CANBTC_SAM		BIT(7)	/* sample points */
+
+#define HECC_BUS_ERROR		(HECC_CANES_FE | HECC_CANES_BE |\
+				HECC_CANES_CRCE | HECC_CANES_SE |\
+				HECC_CANES_ACKE)
+
+#define HECC_CANMCF_RTR		BIT(4)	/* Remote transmit request */
+
+#define HECC_CANGIF_MAIF	BIT(17)	/* Message alarm interrupt */
+#define HECC_CANGIF_TCOIF	BIT(16) /* Timer counter overflow int */
+#define HECC_CANGIF_GMIF	BIT(15)	/* Global mailbox interrupt */
+#define HECC_CANGIF_AAIF	BIT(14)	/* Abort ack interrupt */
+#define HECC_CANGIF_WDIF	BIT(13)	/* Write denied interrupt */
+#define HECC_CANGIF_WUIF	BIT(12)	/* Wake up interrupt */
+#define HECC_CANGIF_RMLIF	BIT(11)	/* Receive message lost interrupt */
+#define HECC_CANGIF_BOIF	BIT(10)	/* Bus off interrupt */
+#define HECC_CANGIF_EPIF	BIT(9)	/* Error passive interrupt */
+#define HECC_CANGIF_WLIF	BIT(8)	/* Warning level interrupt */
+#define HECC_CANGIF_MBOX_MASK	0x1F	/* Mailbox number mask */
+#define HECC_CANGIM_I1EN	BIT(1)	/* Int line 1 enable */
+#define HECC_CANGIM_I0EN	BIT(0)	/* Int line 0 enable */
+#define HECC_CANGIM_DEF_MASK	0x700	/* only busoff/warning/passive */
+#define HECC_CANGIM_SIL		BIT(2)	/* system interrupts to int line 1 */
+
+/* CAN Bittiming constants as per HECC specs */
+static struct can_bittiming_const ti_hecc_bittiming_const = {
+	.name = DRV_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 1,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 1,
+};
+
+struct ti_hecc_priv {
+	struct can_priv can;	/* MUST be first member/field */
+	struct napi_struct napi;
+	struct net_device *ndev;
+	struct clk *clk;
+	void __iomem *base;
+	u32 scc_ram_offset;
+	u32 hecc_ram_offset;
+	u32 mbx_offset;
+	u32 int_line;
+	spinlock_t mbx_lock; /* CANME register needs protection */
+	u32 tx_head;
+	u32 tx_tail;
+	u32 rx_next;
+};
+
+static inline int get_tx_head_mb(struct ti_hecc_priv *priv)
+{
+	return priv->tx_head & HECC_TX_MB_MASK;
+}
+
+static inline int get_tx_tail_mb(struct ti_hecc_priv *priv)
+{
+	return priv->tx_tail & HECC_TX_MB_MASK;
+}
+
+static inline int get_tx_head_prio(struct ti_hecc_priv *priv)
+{
+	return (priv->tx_head >> HECC_TX_PRIO_SHIFT) & MAX_TX_PRIO;
+}
+
+static inline void hecc_write_lam(struct ti_hecc_priv *priv, u32 mbxno, u32 val)
+{
+	__raw_writel(val, priv->base + priv->hecc_ram_offset + mbxno * 4);
+}
+
+static inline void hecc_write_mbx(struct ti_hecc_priv *priv, u32 mbxno,
+	u32 reg, u32 val)
+{
+	__raw_writel(val, priv->base + priv->mbx_offset + mbxno * 0x10 +
+			reg);
+}
+
+static inline u32 hecc_read_mbx(struct ti_hecc_priv *priv, u32 mbxno, u32 reg)
+{
+	return __raw_readl(priv->base + priv->mbx_offset + mbxno * 0x10 +
+			reg);
+}
+
+static inline void hecc_write(struct ti_hecc_priv *priv, u32 reg, u32 val)
+{
+	__raw_writel(val, priv->base + reg);
+}
+
+static inline u32 hecc_read(struct ti_hecc_priv *priv, int reg)
+{
+	return __raw_readl(priv->base + reg);
+}
+
+static inline void hecc_set_bit(struct ti_hecc_priv *priv, int reg,
+	u32 bit_mask)
+{
+	hecc_write(priv, reg, hecc_read(priv, reg) | bit_mask);
+}
+
+static inline void hecc_clear_bit(struct ti_hecc_priv *priv, int reg,
+	u32 bit_mask)
+{
+	hecc_write(priv, reg, hecc_read(priv, reg) & ~bit_mask);
+}
+
+static inline u32 hecc_get_bit(struct ti_hecc_priv *priv, int reg, u32 bit_mask)
+{
+	return (hecc_read(priv, reg) & bit_mask) ? 1 : 0;
+}
+
+static int ti_hecc_get_state(const struct net_device *ndev,
+	enum can_state *state)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	*state = priv->can.state;
+	return 0;
+}
+
+static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
+{
+	struct can_bittiming *bit_timing = &priv->can.bittiming;
+	u32 can_btc;
+
+	can_btc = (bit_timing->phase_seg2 - 1) & 0x7;
+	can_btc |= ((bit_timing->phase_seg1 + bit_timing->prop_seg - 1)
+			& 0xF) << 3;
+	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) {
+		if (bit_timing->brp > 4)
+			can_btc |= HECC_CANBTC_SAM;
+		else
+			dev_warn(priv->ndev->dev.parent, "WARN: Triple" \
+				"sampling not set due to h/w limitations");
+	}
+	can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8;
+	can_btc |= ((bit_timing->brp - 1) & 0xFF) << 16;
+
+	/* ERM being set to 0 by default meaning resync at falling edge */
+
+	hecc_write(priv, HECC_CANBTC, can_btc);
+	dev_info(priv->ndev->dev.parent, "setting CANBTC=%#x\n", can_btc);
+
+	return 0;
+}
+
+static void ti_hecc_reset(struct net_device *ndev)
+{
+	u32 cnt;
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	dev_dbg(ndev->dev.parent, "resetting hecc ...\n");
+	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SRES);
+
+	/* Set change control request and wait till enabled */
+	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+
+	/*
+	 * INFO: It has been observed that at times CCE bit may not be
+	 * set and hw seems to be ok even if this bit is not set so
+	 * timing out with a timing of 1ms to respect the specs
+	 */
+	cnt = HECC_CCE_WAIT_COUNT;
+	while (!hecc_get_bit(priv, HECC_CANES, HECC_CANES_CCE) && cnt != 0) {
+		--cnt;
+		udelay(10);
+	}
+
+	/*
+	 * Note: On HECC, BTC can be programmed only in initialization mode, so
+	 * it is expected that the can bittiming parameters are set via ip
+	 * utility before the device is opened
+	 */
+	ti_hecc_set_btc(priv);
+
+	/* Clear CCR (and CANMC register) and wait for CCE = 0 enable */
+	hecc_write(priv, HECC_CANMC, 0);
+
+	/*
+	 * INFO: CAN net stack handles bus off and hence disabling auto-bus-on
+	 * hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_ABO);
+	 */
+
+	/*
+	 * INFO: It has been observed that at times CCE bit may not be
+	 * set and hw seems to be ok even if this bit is not set so
+	 */
+	cnt = HECC_CCE_WAIT_COUNT;
+	while (hecc_get_bit(priv, HECC_CANES, HECC_CANES_CCE) && cnt != 0) {
+		--cnt;
+		udelay(10);
+	}
+
+	/* Enable TX and RX I/O Control pins */
+	hecc_write(priv, HECC_CANTIOC, HECC_CANTIOC_EN);
+	hecc_write(priv, HECC_CANRIOC, HECC_CANRIOC_EN);
+
+	/* Clear registers for clean operation */
+	hecc_write(priv, HECC_CANTA, HECC_SET_REG);
+	hecc_write(priv, HECC_CANRMP, HECC_SET_REG);
+	hecc_write(priv, HECC_CANGIF0, HECC_SET_REG);
+	hecc_write(priv, HECC_CANGIF1, HECC_SET_REG);
+	hecc_write(priv, HECC_CANME, 0);
+	hecc_write(priv, HECC_CANMD, 0);
+
+	/* SCC compat mode NOT supported (and not needed too) */
+	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SCM);
+}
+
+static void ti_hecc_start(struct net_device *ndev)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	u32 cnt, mbxno, mbx_mask;
+
+	/* put HECC in initialization mode and set btc */
+	ti_hecc_reset(ndev);
+
+	priv->tx_head = priv->tx_tail = HECC_TX_MASK;
+	priv->rx_next = HECC_RX_FIRST_MBOX;
+
+	/* Enable local and global acceptance mask registers */
+	hecc_write(priv, HECC_CANGAM, HECC_SET_REG);
+
+	/* Prepare configured mailboxes to receive messages */
+	for (cnt = 0; cnt < HECC_MAX_RX_MBOX; cnt++) {
+		mbxno = HECC_MAX_MAILBOXES - 1 - cnt;
+		mbx_mask = BIT(mbxno);
+		hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+		hecc_write_mbx(priv, mbxno, HECC_CANMID, HECC_CANMID_AME);
+		hecc_write_lam(priv, mbxno, HECC_SET_REG);
+		hecc_set_bit(priv, HECC_CANMD, mbx_mask);
+		hecc_set_bit(priv, HECC_CANME, mbx_mask);
+		hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
+	}
+
+	/* Prevent message over-write & Enable interrupts */
+	hecc_write(priv, HECC_CANOPC, HECC_SET_REG);
+	if (priv->int_line) {
+		hecc_write(priv, HECC_CANMIL, HECC_SET_REG);
+		hecc_write(priv, HECC_CANGIM, HECC_CANGIM_DEF_MASK |
+			HECC_CANGIM_I1EN | HECC_CANGIM_SIL);
+	} else {
+		hecc_write(priv, HECC_CANMIL, 0);
+		hecc_write(priv, HECC_CANGIM,
+			HECC_CANGIM_DEF_MASK | HECC_CANGIM_I0EN);
+	}
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+static void ti_hecc_stop(struct net_device *ndev)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	/* Disable interrupts and disable mailboxes */
+	hecc_write(priv, HECC_CANGIM, 0);
+	hecc_write(priv, HECC_CANMIM, 0);
+	hecc_write(priv, HECC_CANME, 0);
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int ti_hecc_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+	int ret = 0;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		ti_hecc_start(ndev);
+		netif_wake_queue(ndev);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * ti_hecc_xmit: HECC Transmit
+ *
+ * The transmit mailboxes start from 0 to HECC_MAX_TX_MBOX. In HECC the
+ * priority of the mailbox for tranmission is dependent upon priority setting
+ * field in mailbox registers. The mailbox with highest value in priority field
+ * is transmitted first. Only when two mailboxes have the same value in
+ * priority field the highest numbered mailbox is transmitted first.
+ *
+ * To utilize the HECC priority feature as described above we start with the
+ * highest numbered mailbox with highest priority level and move on to the next
+ * mailbox with the same priority level and so on. Once we loop through all the
+ * transmit mailboxes we choose the next priority level (lower) and so on
+ * until we reach the lowest priority level on the lowest numbered mailbox
+ * when we stop transmission until all mailboxes are transmitted and then
+ * restart at highest numbered mailbox with highest priority.
+ *
+ * Two counters (head and tail) are used to track the next mailbox to transmit
+ * and to track the echo buffer for already transmitted mailbox. The queue
+ * is stopped when all the mailboxes are busy or when there is a priority
+ * value roll-over happens.
+ */
+static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	u32 mbxno, mbx_mask, data;
+	unsigned long flags;
+
+	mbxno = get_tx_head_mb(priv);
+	mbx_mask = BIT(mbxno);
+	spin_lock_irqsave(&priv->mbx_lock, flags);
+	if (unlikely(hecc_read(priv, HECC_CANME) & mbx_mask)) {
+		spin_unlock_irqrestore(&priv->mbx_lock, flags);
+		netif_stop_queue(ndev);
+		dev_err(priv->ndev->dev.parent,
+			"BUG: TX mbx not ready tx_head=%08X, tx_tail=%08X\n",
+			priv->tx_head, priv->tx_tail);
+		return NETDEV_TX_BUSY;
+	}
+	spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+	/* Prepare mailbox for transmission */
+	data = min_t(u8, cf->can_dlc, 8);
+	if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
+		data |= HECC_CANMCF_RTR;
+	data |= get_tx_head_prio(priv) << 8;
+	hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);
+
+	if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
+		data = (cf->can_id & CAN_EFF_MASK) | HECC_CANMID_IDE;
+	else /* Standard frame format */
+		data = (cf->can_id & CAN_SFF_MASK) << 18;
+	hecc_write_mbx(priv, mbxno, HECC_CANMID, data);
+	hecc_write_mbx(priv, mbxno, HECC_CANMDL,
+		be32_to_cpu(*(u32 *)(cf->data)));
+	if (cf->can_dlc > 4)
+		hecc_write_mbx(priv, mbxno, HECC_CANMDH,
+			be32_to_cpu(*(u32 *)(cf->data + 4)));
+	else
+		*(u32 *)(cf->data + 4) = 0;
+	can_put_echo_skb(skb, ndev, mbxno);
+
+	spin_lock_irqsave(&priv->mbx_lock, flags);
+	--priv->tx_head;
+	if ((hecc_read(priv, HECC_CANME) & BIT(get_tx_head_mb(priv))) ||
+		(priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK) {
+		netif_stop_queue(ndev);
+	}
+	hecc_set_bit(priv, HECC_CANME, mbx_mask);
+	spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+	hecc_clear_bit(priv, HECC_CANMD, mbx_mask);
+	hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
+	hecc_write(priv, HECC_CANTRS, mbx_mask);
+
+	return NETDEV_TX_OK;
+}
+
+static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 data, mbx_mask;
+	unsigned long flags;
+
+	skb = alloc_can_skb(priv->ndev, &cf);
+	if (!skb) {
+		if (printk_ratelimit())
+			dev_err(priv->ndev->dev.parent,
+				"ti_hecc_rx_pkt: alloc_can_skb() failed\n");
+		return -ENOMEM;
+	}
+
+	mbx_mask = BIT(mbxno);
+	data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
+	if (data & HECC_CANMID_IDE)
+		cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
+	else
+		cf->can_id = (data >> 18) & CAN_SFF_MASK;
+	data = hecc_read_mbx(priv, mbxno, HECC_CANMCF);
+	if (data & HECC_CANMCF_RTR)
+		cf->can_id |= CAN_RTR_FLAG;
+	cf->can_dlc = get_can_dlc(data & 0xF);
+	data = hecc_read_mbx(priv, mbxno, HECC_CANMDL);
+	*(u32 *)(cf->data) = cpu_to_be32(data);
+	if (cf->can_dlc > 4) {
+		data = hecc_read_mbx(priv, mbxno, HECC_CANMDH);
+		*(u32 *)(cf->data + 4) = cpu_to_be32(data);
+	} else {
+		*(u32 *)(cf->data + 4) = 0;
+	}
+	spin_lock_irqsave(&priv->mbx_lock, flags);
+	hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+	hecc_write(priv, HECC_CANRMP, mbx_mask);
+	/* enable mailbox only if it is part of rx buffer mailboxes */
+	if (priv->rx_next < HECC_RX_BUFFER_MBOX)
+		hecc_set_bit(priv, HECC_CANME, mbx_mask);
+	spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+	stats->rx_bytes += cf->can_dlc;
+	netif_receive_skb(skb);
+	stats->rx_packets++;
+
+	return 0;
+}
+
+/*
+ * ti_hecc_rx_poll - HECC receive pkts
+ *
+ * The receive mailboxes start from highest numbered mailbox till last xmit
+ * mailbox. On CAN frame reception the hardware places the data into highest
+ * numbered mailbox that matches the CAN ID filter. Since all receive mailboxes
+ * have same filtering (ALL CAN frames) packets will arrive in the highest
+ * available RX mailbox and we need to ensure in-order packet reception.
+ *
+ * To ensure the packets are received in the right order we logically divide
+ * the RX mailboxes into main and buffer mailboxes. Packets are received as per
+ * mailbox priotity (higher to lower) in the main bank and once it is full we
+ * disable further reception into main mailboxes. While the main mailboxes are
+ * processed in NAPI, further packets are received in buffer mailboxes.
+ *
+ * We maintain a RX next mailbox counter to process packets and once all main
+ * mailboxe packets are passed to the upper stack we enable all of them but
+ * continue to process packets received in buffer mailboxes. With each packet
+ * received from buffer mailbox we enable it immediately so as to handle the
+ * overflow from higher mailboxes.
+ */
+static int ti_hecc_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	u32 num_pkts = 0;
+	u32 mbx_mask;
+	unsigned long pending_pkts, flags;
+
+	if (!netif_running(ndev))
+		return 0;
+
+	while ((pending_pkts = hecc_read(priv, HECC_CANRMP)) &&
+		num_pkts < quota) {
+		mbx_mask = BIT(priv->rx_next); /* next rx mailbox to process */
+		if (mbx_mask & pending_pkts) {
+			if (ti_hecc_rx_pkt(priv, priv->rx_next) < 0)
+				return num_pkts;
+			++num_pkts;
+		} else if (priv->rx_next > HECC_RX_BUFFER_MBOX) {
+			break; /* pkt not received yet */
+		}
+		--priv->rx_next;
+		if (priv->rx_next == HECC_RX_BUFFER_MBOX) {
+			/* enable high bank mailboxes */
+			spin_lock_irqsave(&priv->mbx_lock, flags);
+			mbx_mask = hecc_read(priv, HECC_CANME);
+			mbx_mask |= HECC_RX_HIGH_MBOX_MASK;
+			hecc_write(priv, HECC_CANME, mbx_mask);
+			spin_unlock_irqrestore(&priv->mbx_lock, flags);
+		} else if (priv->rx_next == HECC_MAX_TX_MBOX - 1) {
+			priv->rx_next = HECC_RX_FIRST_MBOX;
+			break;
+		}
+	}
+
+	/* Enable packet interrupt if all pkts are handled */
+	if (hecc_read(priv, HECC_CANRMP) == 0) {
+		napi_complete(napi);
+		/* Re-enable RX mailbox interrupts */
+		mbx_mask = hecc_read(priv, HECC_CANMIM);
+		mbx_mask |= HECC_TX_MBOX_MASK;
+		hecc_write(priv, HECC_CANMIM, mbx_mask);
+	}
+
+	return num_pkts;
+}
+
+static int ti_hecc_error(struct net_device *ndev, int int_status,
+	int err_status)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+
+	/* propogate the error condition to the can stack */
+	skb = alloc_can_err_skb(ndev, &cf);
+	if (!skb) {
+		if (printk_ratelimit())
+			dev_err(priv->ndev->dev.parent,
+				"ti_hecc_error: alloc_can_err_skb() failed\n");
+		return -ENOMEM;
+	}
+
+	if (int_status & HECC_CANGIF_WLIF) { /* warning level int */
+		if ((int_status & HECC_CANGIF_BOIF) == 0) {
+			priv->can.state = CAN_STATE_ERROR_WARNING;
+			++priv->can.can_stats.error_warning;
+			cf->can_id |= CAN_ERR_CRTL;
+			if (hecc_read(priv, HECC_CANTEC) > 96)
+				cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			if (hecc_read(priv, HECC_CANREC) > 96)
+				cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+		}
+		hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW);
+		dev_dbg(priv->ndev->dev.parent, "Error Warning interrupt\n");
+		hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+	}
+
+	if (int_status & HECC_CANGIF_EPIF) { /* error passive int */
+		if ((int_status & HECC_CANGIF_BOIF) == 0) {
+			priv->can.state = CAN_STATE_ERROR_PASSIVE;
+			++priv->can.can_stats.error_passive;
+			cf->can_id |= CAN_ERR_CRTL;
+			if (hecc_read(priv, HECC_CANTEC) > 127)
+				cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+			if (hecc_read(priv, HECC_CANREC) > 127)
+				cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+		}
+		hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP);
+		dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n");
+		hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+	}
+
+	/*
+	 * Need to check busoff condition in error status register too to
+	 * ensure warning interrupts don't hog the system
+	 */
+	if ((int_status & HECC_CANGIF_BOIF) || (err_status & HECC_CANES_BO)) {
+		priv->can.state = CAN_STATE_BUS_OFF;
+		cf->can_id |= CAN_ERR_BUSOFF;
+		hecc_set_bit(priv, HECC_CANES, HECC_CANES_BO);
+		hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+		/* Disable all interrupts in bus-off to avoid int hog */
+		hecc_write(priv, HECC_CANGIM, 0);
+		can_bus_off(ndev);
+	}
+
+	if (err_status & HECC_BUS_ERROR) {
+		++priv->can.can_stats.bus_error;
+		cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+		cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+		if (err_status & HECC_CANES_FE) {
+			hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE);
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+		}
+		if (err_status & HECC_CANES_BE) {
+			hecc_set_bit(priv, HECC_CANES, HECC_CANES_BE);
+			cf->data[2] |= CAN_ERR_PROT_BIT;
+		}
+		if (err_status & HECC_CANES_SE) {
+			hecc_set_bit(priv, HECC_CANES, HECC_CANES_SE);
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+		}
+		if (err_status & HECC_CANES_CRCE) {
+			hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
+			cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+					CAN_ERR_PROT_LOC_CRC_DEL;
+		}
+		if (err_status & HECC_CANES_ACKE) {
+			hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
+			cf->data[2] |= CAN_ERR_PROT_LOC_ACK |
+					CAN_ERR_PROT_LOC_ACK_DEL;
+		}
+	}
+
+	netif_receive_skb(skb);
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+	return 0;
+}
+
+static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = (struct net_device *)dev_id;
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	u32 mbxno, mbx_mask, int_status, err_status;
+	unsigned long ack, flags;
+
+	int_status = hecc_read(priv,
+		(priv->int_line) ? HECC_CANGIF1 : HECC_CANGIF0);
+
+	if (!int_status)
+		return IRQ_NONE;
+
+	err_status = hecc_read(priv, HECC_CANES);
+	if (err_status & (HECC_BUS_ERROR | HECC_CANES_BO |
+		HECC_CANES_EP | HECC_CANES_EW))
+			ti_hecc_error(ndev, int_status, err_status);
+
+	if (int_status & HECC_CANGIF_GMIF) {
+		while (priv->tx_tail - priv->tx_head > 0) {
+			mbxno = get_tx_tail_mb(priv);
+			mbx_mask = BIT(mbxno);
+			if (!(mbx_mask & hecc_read(priv, HECC_CANTA)))
+				break;
+			hecc_clear_bit(priv, HECC_CANMIM, mbx_mask);
+			hecc_write(priv, HECC_CANTA, mbx_mask);
+			spin_lock_irqsave(&priv->mbx_lock, flags);
+			hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+			spin_unlock_irqrestore(&priv->mbx_lock, flags);
+			stats->tx_bytes += hecc_read_mbx(priv, mbxno,
+						HECC_CANMCF) & 0xF;
+			stats->tx_packets++;
+			can_get_echo_skb(ndev, mbxno);
+			--priv->tx_tail;
+		}
+
+		/* restart queue if wrap-up or if queue stalled on last pkt */
+		if (((priv->tx_head == priv->tx_tail) &&
+		((priv->tx_head & HECC_TX_MASK) != HECC_TX_MASK)) ||
+		(((priv->tx_tail & HECC_TX_MASK) == HECC_TX_MASK) &&
+		((priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK)))
+			netif_wake_queue(ndev);
+
+		/* Disable RX mailbox interrupts and let NAPI reenable them */
+		if (hecc_read(priv, HECC_CANRMP)) {
+			ack = hecc_read(priv, HECC_CANMIM);
+			ack &= BIT(HECC_MAX_TX_MBOX) - 1;
+			hecc_write(priv, HECC_CANMIM, ack);
+			napi_schedule(&priv->napi);
+		}
+	}
+
+	/* clear all interrupt conditions - read back to avoid spurious ints */
+	if (priv->int_line) {
+		hecc_write(priv, HECC_CANGIF1, HECC_SET_REG);
+		int_status = hecc_read(priv, HECC_CANGIF1);
+	} else {
+		hecc_write(priv, HECC_CANGIF0, HECC_SET_REG);
+		int_status = hecc_read(priv, HECC_CANGIF0);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int ti_hecc_open(struct net_device *ndev)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+	int err;
+
+	err = request_irq(ndev->irq, ti_hecc_interrupt, IRQF_SHARED,
+			ndev->name, ndev);
+	if (err) {
+		dev_err(ndev->dev.parent, "error requesting interrupt\n");
+		return err;
+	}
+
+	/* Open common can device */
+	err = open_candev(ndev);
+	if (err) {
+		dev_err(ndev->dev.parent, "open_candev() failed %d\n", err);
+		free_irq(ndev->irq, ndev);
+		return err;
+	}
+
+	clk_enable(priv->clk);
+	ti_hecc_start(ndev);
+	napi_enable(&priv->napi);
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+static int ti_hecc_close(struct net_device *ndev)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	netif_stop_queue(ndev);
+	napi_disable(&priv->napi);
+	ti_hecc_stop(ndev);
+	free_irq(ndev->irq, ndev);
+	clk_disable(priv->clk);
+	close_candev(ndev);
+
+	return 0;
+}
+
+static const struct net_device_ops ti_hecc_netdev_ops = {
+	.ndo_open		= ti_hecc_open,
+	.ndo_stop		= ti_hecc_close,
+	.ndo_start_xmit		= ti_hecc_xmit,
+};
+
+static int ti_hecc_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev = (struct net_device *)0;
+	struct ti_hecc_priv *priv;
+	struct ti_hecc_platform_data *pdata;
+	struct resource *mem, *irq;
+	void __iomem *addr;
+	int err = -ENODEV;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data\n");
+		goto probe_exit;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(&pdev->dev, "No mem resources\n");
+		goto probe_exit;
+	}
+	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irq) {
+		dev_err(&pdev->dev, "No irq resource\n");
+		goto probe_exit;
+	}
+	if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
+		dev_err(&pdev->dev, "HECC region already claimed\n");
+		err = -EBUSY;
+		goto probe_exit;
+	}
+	addr = ioremap(mem->start, resource_size(mem));
+	if (!addr) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		err = -ENOMEM;
+		goto probe_exit_free_region;
+	}
+
+	ndev = alloc_candev(sizeof(struct ti_hecc_priv), HECC_MAX_TX_MBOX);
+	if (!ndev) {
+		dev_err(&pdev->dev, "alloc_candev failed\n");
+		err = -ENOMEM;
+		goto probe_exit_iounmap;
+	}
+
+	priv = netdev_priv(ndev);
+	priv->ndev = ndev;
+	priv->base = addr;
+	priv->scc_ram_offset = pdata->scc_ram_offset;
+	priv->hecc_ram_offset = pdata->hecc_ram_offset;
+	priv->mbx_offset = pdata->mbx_offset;
+	priv->int_line = pdata->int_line;
+
+	priv->can.bittiming_const = &ti_hecc_bittiming_const;
+	priv->can.do_set_mode = ti_hecc_do_set_mode;
+	priv->can.do_get_state = ti_hecc_get_state;
+
+	ndev->irq = irq->start;
+	ndev->flags |= IFF_ECHO;
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+	ndev->netdev_ops = &ti_hecc_netdev_ops;
+
+	priv->clk = clk_get(&pdev->dev, "hecc_ck");
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "No clock available\n");
+		err = PTR_ERR(priv->clk);
+		priv->clk = NULL;
+		goto probe_exit_candev;
+	}
+	priv->can.clock.freq = clk_get_rate(priv->clk);
+	netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
+		HECC_DEF_NAPI_WEIGHT);
+
+	err = register_candev(ndev);
+	if (err) {
+		dev_err(&pdev->dev, "register_candev() failed\n");
+		goto probe_exit_clk;
+	}
+	dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n",
+		priv->base, (u32) ndev->irq);
+
+	return 0;
+
+probe_exit_clk:
+	clk_put(priv->clk);
+probe_exit_candev:
+	free_candev(ndev);
+probe_exit_iounmap:
+	iounmap(addr);
+probe_exit_free_region:
+	release_mem_region(mem->start, resource_size(mem));
+probe_exit:
+	return err;
+}
+
+static int __devexit ti_hecc_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	clk_put(priv->clk);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iounmap(priv->base);
+	release_mem_region(res->start, resource_size(res));
+	unregister_candev(ndev);
+	free_candev(ndev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+/* TI HECC netdevice driver: platform driver structure */
+static struct platform_driver ti_hecc_driver = {
+	.driver = {
+		.name    = DRV_NAME,
+		.owner   = THIS_MODULE,
+	},
+	.probe = ti_hecc_probe,
+	.remove = __devexit_p(ti_hecc_remove),
+};
+
+static int __init ti_hecc_init_driver(void)
+{
+	printk(KERN_INFO DRV_DESC "\n");
+	return platform_driver_register(&ti_hecc_driver);
+}
+module_init(ti_hecc_init_driver);
+
+static void __exit ti_hecc_exit_driver(void)
+{
+	printk(KERN_INFO DRV_DESC " unloaded\n");
+	platform_driver_unregister(&ti_hecc_driver);
+}
+module_exit(ti_hecc_exit_driver);
+
+MODULE_AUTHOR("Anant Gole <anantgole@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRV_DESC);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/can/usb/ems_usb.c linux-libre-2.6.33-gnu1/drivers/net/can/usb/ems_usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/can/usb/ems_usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/can/usb/ems_usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,7 @@ MODULE_DEVICE_TABLE(usb, ems_usb_table);
 #define INTR_IN_BUFFER_SIZE 4
 
 #define MAX_RX_URBS 10
-#define MAX_TX_URBS CAN_ECHO_SKB_MAX
+#define MAX_TX_URBS 10
 
 struct ems_usb;
 
@@ -311,23 +311,19 @@ static void ems_usb_rx_can_msg(struct em
 	int i;
 	struct net_device_stats *stats = &dev->netdev->stats;
 
-	skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+	skb = alloc_can_skb(dev->netdev, &cf);
 	if (skb == NULL)
 		return;
 
-	skb->protocol = htons(ETH_P_CAN);
-
-	cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
 	cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
-	cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
+	cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF);
 
-	if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME
-	    || msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
+	if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME ||
+	    msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
 		cf->can_id |= CAN_EFF_FLAG;
 
-	if (msg->type == CPC_MSG_TYPE_RTR_FRAME
-	    || msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) {
+	if (msg->type == CPC_MSG_TYPE_RTR_FRAME ||
+	    msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) {
 		cf->can_id |= CAN_RTR_FLAG;
 	} else {
 		for (i = 0; i < cf->can_dlc; i++)
@@ -346,18 +342,10 @@ static void ems_usb_rx_err(struct ems_us
 	struct sk_buff *skb;
 	struct net_device_stats *stats = &dev->netdev->stats;
 
-	skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+	skb = alloc_can_err_skb(dev->netdev, &cf);
 	if (skb == NULL)
 		return;
 
-	skb->protocol = htons(ETH_P_CAN);
-
-	cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-	memset(cf, 0, sizeof(struct can_frame));
-
-	cf->can_id = CAN_ERR_FLAG;
-	cf->can_dlc = CAN_ERR_DLC;
-
 	if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
 		u8 state = msg->msg.can_state;
 
@@ -1015,7 +1003,7 @@ static int ems_usb_probe(struct usb_inte
 	struct ems_usb *dev;
 	int i, err = -ENOMEM;
 
-	netdev = alloc_candev(sizeof(struct ems_usb));
+	netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
 	if (!netdev) {
 		dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
 		return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/chelsio/sge.c linux-libre-2.6.33-gnu1/drivers/net/chelsio/sge.c
--- linux-libre-2.6.32-gnu1/drivers/net/chelsio/sge.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/chelsio/sge.c	2010-02-24 13:52:17.000000000 -0500
@@ -1378,7 +1378,7 @@ static void sge_rx(struct sge *sge, stru
 	}
 	__skb_pull(skb, sizeof(*p));
 
-	st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id());
+	st = this_cpu_ptr(sge->port_stats[p->iff]);
 
 	skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
 	if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
@@ -1780,8 +1780,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff
 {
 	struct adapter *adapter = dev->ml_priv;
 	struct sge *sge = adapter->sge;
-	struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port],
-						smp_processor_id());
+	struct sge_port_stats *st = this_cpu_ptr(sge->port_stats[dev->if_port]);
 	struct cpl_tx_pkt *cpl;
 	struct sk_buff *orig_skb = skb;
 	int ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cnic.c linux-libre-2.6.33-gnu1/drivers/net/cnic.c
--- linux-libre-2.6.32-gnu1/drivers/net/cnic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cnic.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,10 +33,16 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
+#include <net/ip6_checksum.h>
 #include <scsi/iscsi_if.h>
 
 #include "cnic_if.h"
 #include "bnx2.h"
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "../scsi/bnx2i/57xx_iscsi_constants.h"
+#include "../scsi/bnx2i/57xx_iscsi_hsi.h"
 #include "cnic.h"
 #include "cnic_defs.h"
 
@@ -59,6 +65,7 @@ static DEFINE_MUTEX(cnic_lock);
 static struct cnic_ulp_ops *cnic_ulp_tbl[MAX_CNIC_ULP_TYPE];
 
 static int cnic_service_bnx2(void *, void *);
+static int cnic_service_bnx2x(void *, void *);
 static int cnic_ctl(void *, struct cnic_ctl_info *);
 
 static struct cnic_ops cnic_bnx2_ops = {
@@ -67,9 +74,14 @@ static struct cnic_ops cnic_bnx2_ops = {
 	.cnic_ctl	= cnic_ctl,
 };
 
-static void cnic_shutdown_bnx2_rx_ring(struct cnic_dev *);
-static void cnic_init_bnx2_tx_ring(struct cnic_dev *);
-static void cnic_init_bnx2_rx_ring(struct cnic_dev *);
+static struct cnic_ops cnic_bnx2x_ops = {
+	.cnic_owner	= THIS_MODULE,
+	.cnic_handler	= cnic_service_bnx2x,
+	.cnic_ctl	= cnic_ctl,
+};
+
+static void cnic_shutdown_rings(struct cnic_dev *);
+static void cnic_init_rings(struct cnic_dev *);
 static int cnic_cm_set_pg(struct cnic_sock *);
 
 static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
@@ -83,10 +95,16 @@ static int cnic_uio_open(struct uio_info
 	if (cp->uio_dev != -1)
 		return -EBUSY;
 
+	rtnl_lock();
+	if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
+		rtnl_unlock();
+		return -ENODEV;
+	}
+
 	cp->uio_dev = iminor(inode);
 
-	cnic_init_bnx2_tx_ring(dev);
-	cnic_init_bnx2_rx_ring(dev);
+	cnic_init_rings(dev);
+	rtnl_unlock();
 
 	return 0;
 }
@@ -96,7 +114,7 @@ static int cnic_uio_close(struct uio_inf
 	struct cnic_dev *dev = uinfo->priv;
 	struct cnic_local *cp = dev->cnic_priv;
 
-	cnic_shutdown_bnx2_rx_ring(dev);
+	cnic_shutdown_rings(dev);
 
 	cp->uio_dev = -1;
 	return 0;
@@ -162,6 +180,36 @@ static void cnic_ctx_wr(struct cnic_dev
 	ethdev->drv_ctl(dev->netdev, &info);
 }
 
+static void cnic_ctx_tbl_wr(struct cnic_dev *dev, u32 off, dma_addr_t addr)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	struct drv_ctl_info info;
+	struct drv_ctl_io *io = &info.data.io;
+
+	info.cmd = DRV_CTL_CTXTBL_WR_CMD;
+	io->offset = off;
+	io->dma_addr = addr;
+	ethdev->drv_ctl(dev->netdev, &info);
+}
+
+static void cnic_ring_ctl(struct cnic_dev *dev, u32 cid, u32 cl_id, int start)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	struct drv_ctl_info info;
+	struct drv_ctl_l2_ring *ring = &info.data.ring;
+
+	if (start)
+		info.cmd = DRV_CTL_START_L2_CMD;
+	else
+		info.cmd = DRV_CTL_STOP_L2_CMD;
+
+	ring->cid = cid;
+	ring->client_id = cl_id;
+	ethdev->drv_ctl(dev->netdev, &info);
+}
+
 static void cnic_reg_wr_ind(struct cnic_dev *dev, u32 off, u32 val)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -204,6 +252,19 @@ static void cnic_kwq_completion(struct c
 	ethdev->drv_ctl(dev->netdev, &info);
 }
 
+static int cnic_get_l5_cid(struct cnic_local *cp, u32 cid, u32 *l5_cid)
+{
+	u32 i;
+
+	for (i = 0; i < MAX_ISCSI_TBL_SZ; i++) {
+		if (cp->ctx_tbl[i].cid == cid) {
+			*l5_cid = i;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
 static int cnic_send_nlmsg(struct cnic_local *cp, u32 type,
 			   struct cnic_sock *csk)
 {
@@ -347,7 +408,7 @@ int cnic_register_driver(int ulp_type, s
 {
 	struct cnic_dev *dev;
 
-	if (ulp_type >= MAX_CNIC_ULP_TYPE) {
+	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
 		printk(KERN_ERR PFX "cnic_register_driver: Bad type %d\n",
 		       ulp_type);
 		return -EINVAL;
@@ -393,7 +454,7 @@ int cnic_unregister_driver(int ulp_type)
 	struct cnic_ulp_ops *ulp_ops;
 	int i = 0;
 
-	if (ulp_type >= MAX_CNIC_ULP_TYPE) {
+	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
 		printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
 		       ulp_type);
 		return -EINVAL;
@@ -449,7 +510,7 @@ static int cnic_register_device(struct c
 	struct cnic_local *cp = dev->cnic_priv;
 	struct cnic_ulp_ops *ulp_ops;
 
-	if (ulp_type >= MAX_CNIC_ULP_TYPE) {
+	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
 		printk(KERN_ERR PFX "cnic_register_device: Bad type %d\n",
 		       ulp_type);
 		return -EINVAL;
@@ -490,7 +551,7 @@ static int cnic_unregister_device(struct
 	struct cnic_local *cp = dev->cnic_priv;
 	int i = 0;
 
-	if (ulp_type >= MAX_CNIC_ULP_TYPE) {
+	if (ulp_type < 0 || ulp_type >= MAX_CNIC_ULP_TYPE) {
 		printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
 		       ulp_type);
 		return -EINVAL;
@@ -606,14 +667,14 @@ static void cnic_free_dma(struct cnic_de
 
 	for (i = 0; i < dma->num_pages; i++) {
 		if (dma->pg_arr[i]) {
-			pci_free_consistent(dev->pcidev, BCM_PAGE_SIZE,
-					    dma->pg_arr[i], dma->pg_map_arr[i]);
+			dma_free_coherent(&dev->pcidev->dev, BCM_PAGE_SIZE,
+					  dma->pg_arr[i], dma->pg_map_arr[i]);
 			dma->pg_arr[i] = NULL;
 		}
 	}
 	if (dma->pgtbl) {
-		pci_free_consistent(dev->pcidev, dma->pgtbl_size,
-				    dma->pgtbl, dma->pgtbl_map);
+		dma_free_coherent(&dev->pcidev->dev, dma->pgtbl_size,
+				  dma->pgtbl, dma->pgtbl_map);
 		dma->pgtbl = NULL;
 	}
 	kfree(dma->pg_arr);
@@ -635,6 +696,20 @@ static void cnic_setup_page_tbl(struct c
 	}
 }
 
+static void cnic_setup_page_tbl_le(struct cnic_dev *dev, struct cnic_dma *dma)
+{
+	int i;
+	u32 *page_table = dma->pgtbl;
+
+	for (i = 0; i < dma->num_pages; i++) {
+		/* Each entry needs to be in little endian format. */
+		*page_table = dma->pg_map_arr[i] & 0xffffffff;
+		page_table++;
+		*page_table = (u32) ((u64) dma->pg_map_arr[i] >> 32);
+		page_table++;
+	}
+}
+
 static int cnic_alloc_dma(struct cnic_dev *dev, struct cnic_dma *dma,
 			  int pages, int use_pg_tbl)
 {
@@ -650,9 +725,10 @@ static int cnic_alloc_dma(struct cnic_de
 	dma->num_pages = pages;
 
 	for (i = 0; i < pages; i++) {
-		dma->pg_arr[i] = pci_alloc_consistent(dev->pcidev,
-						      BCM_PAGE_SIZE,
-						      &dma->pg_map_arr[i]);
+		dma->pg_arr[i] = dma_alloc_coherent(&dev->pcidev->dev,
+						    BCM_PAGE_SIZE,
+						    &dma->pg_map_arr[i],
+						    GFP_ATOMIC);
 		if (dma->pg_arr[i] == NULL)
 			goto error;
 	}
@@ -661,8 +737,8 @@ static int cnic_alloc_dma(struct cnic_de
 
 	dma->pgtbl_size = ((pages * 8) + BCM_PAGE_SIZE - 1) &
 			  ~(BCM_PAGE_SIZE - 1);
-	dma->pgtbl = pci_alloc_consistent(dev->pcidev, dma->pgtbl_size,
-					  &dma->pgtbl_map);
+	dma->pgtbl = dma_alloc_coherent(&dev->pcidev->dev, dma->pgtbl_size,
+					&dma->pgtbl_map, GFP_ATOMIC);
 	if (dma->pgtbl == NULL)
 		goto error;
 
@@ -675,6 +751,21 @@ error:
 	return -ENOMEM;
 }
 
+static void cnic_free_context(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int i;
+
+	for (i = 0; i < cp->ctx_blks; i++) {
+		if (cp->ctx_arr[i].ctx) {
+			dma_free_coherent(&dev->pcidev->dev, cp->ctx_blk_size,
+					  cp->ctx_arr[i].ctx,
+					  cp->ctx_arr[i].mapping);
+			cp->ctx_arr[i].ctx = NULL;
+		}
+	}
+}
+
 static void cnic_free_resc(struct cnic_dev *dev)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -691,25 +782,18 @@ static void cnic_free_resc(struct cnic_d
 	}
 
 	if (cp->l2_buf) {
-		pci_free_consistent(dev->pcidev, cp->l2_buf_size,
-				    cp->l2_buf, cp->l2_buf_map);
+		dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size,
+				  cp->l2_buf, cp->l2_buf_map);
 		cp->l2_buf = NULL;
 	}
 
 	if (cp->l2_ring) {
-		pci_free_consistent(dev->pcidev, cp->l2_ring_size,
-				    cp->l2_ring, cp->l2_ring_map);
+		dma_free_coherent(&dev->pcidev->dev, cp->l2_ring_size,
+				  cp->l2_ring, cp->l2_ring_map);
 		cp->l2_ring = NULL;
 	}
 
-	for (i = 0; i < cp->ctx_blks; i++) {
-		if (cp->ctx_arr[i].ctx) {
-			pci_free_consistent(dev->pcidev, cp->ctx_blk_size,
-					    cp->ctx_arr[i].ctx,
-					    cp->ctx_arr[i].mapping);
-			cp->ctx_arr[i].ctx = NULL;
-		}
-	}
+	cnic_free_context(dev);
 	kfree(cp->ctx_arr);
 	cp->ctx_arr = NULL;
 	cp->ctx_blks = 0;
@@ -717,6 +801,7 @@ static void cnic_free_resc(struct cnic_d
 	cnic_free_dma(dev, &cp->gbl_buf_info);
 	cnic_free_dma(dev, &cp->conn_buf_info);
 	cnic_free_dma(dev, &cp->kwq_info);
+	cnic_free_dma(dev, &cp->kwq_16_data_info);
 	cnic_free_dma(dev, &cp->kcq_info);
 	kfree(cp->iscsi_tbl);
 	cp->iscsi_tbl = NULL;
@@ -765,8 +850,10 @@ static int cnic_alloc_context(struct cni
 
 		for (i = 0; i < cp->ctx_blks; i++) {
 			cp->ctx_arr[i].ctx =
-				pci_alloc_consistent(dev->pcidev, BCM_PAGE_SIZE,
-						     &cp->ctx_arr[i].mapping);
+				dma_alloc_coherent(&dev->pcidev->dev,
+						   BCM_PAGE_SIZE,
+						   &cp->ctx_arr[i].mapping,
+						   GFP_KERNEL);
 			if (cp->ctx_arr[i].ctx == NULL)
 				return -ENOMEM;
 		}
@@ -779,15 +866,17 @@ static int cnic_alloc_l2_rings(struct cn
 	struct cnic_local *cp = dev->cnic_priv;
 
 	cp->l2_ring_size = pages * BCM_PAGE_SIZE;
-	cp->l2_ring = pci_alloc_consistent(dev->pcidev, cp->l2_ring_size,
-					   &cp->l2_ring_map);
+	cp->l2_ring = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_ring_size,
+					 &cp->l2_ring_map,
+					 GFP_KERNEL | __GFP_COMP);
 	if (!cp->l2_ring)
 		return -ENOMEM;
 
 	cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
 	cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size);
-	cp->l2_buf = pci_alloc_consistent(dev->pcidev, cp->l2_buf_size,
-					   &cp->l2_buf_map);
+	cp->l2_buf = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_buf_size,
+					&cp->l2_buf_map,
+					GFP_KERNEL | __GFP_COMP);
 	if (!cp->l2_buf)
 		return -ENOMEM;
 
@@ -808,14 +897,20 @@ static int cnic_alloc_uio(struct cnic_de
 	uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start;
 	uinfo->mem[0].memtype = UIO_MEM_PHYS;
 
-	uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
 	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+		uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
 		if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
 			uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
 		else
 			uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE;
 
 		uinfo->name = "bnx2_cnic";
+	} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
+		uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk &
+			PAGE_MASK;
+		uinfo->mem[1].size = sizeof(struct host_def_status_block);
+
+		uinfo->name = "bnx2x_cnic";
 	}
 
 	uinfo->mem[1].memtype = UIO_MEM_LOGICAL;
@@ -880,6 +975,154 @@ error:
 	return ret;
 }
 
+static int cnic_alloc_bnx2x_context(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	int ctx_blk_size = cp->ethdev->ctx_blk_size;
+	int total_mem, blks, i, cid_space;
+
+	if (BNX2X_ISCSI_START_CID < ethdev->starting_cid)
+		return -EINVAL;
+
+	cid_space = MAX_ISCSI_TBL_SZ +
+		    (BNX2X_ISCSI_START_CID - ethdev->starting_cid);
+
+	total_mem = BNX2X_CONTEXT_MEM_SIZE * cid_space;
+	blks = total_mem / ctx_blk_size;
+	if (total_mem % ctx_blk_size)
+		blks++;
+
+	if (blks > cp->ethdev->ctx_tbl_len)
+		return -ENOMEM;
+
+	cp->ctx_arr = kzalloc(blks * sizeof(struct cnic_ctx), GFP_KERNEL);
+	if (cp->ctx_arr == NULL)
+		return -ENOMEM;
+
+	cp->ctx_blks = blks;
+	cp->ctx_blk_size = ctx_blk_size;
+	if (BNX2X_CHIP_IS_E1H(cp->chip_id))
+		cp->ctx_align = 0;
+	else
+		cp->ctx_align = ctx_blk_size;
+
+	cp->cids_per_blk = ctx_blk_size / BNX2X_CONTEXT_MEM_SIZE;
+
+	for (i = 0; i < blks; i++) {
+		cp->ctx_arr[i].ctx =
+			dma_alloc_coherent(&dev->pcidev->dev, cp->ctx_blk_size,
+					   &cp->ctx_arr[i].mapping,
+					   GFP_KERNEL);
+		if (cp->ctx_arr[i].ctx == NULL)
+			return -ENOMEM;
+
+		if (cp->ctx_align && cp->ctx_blk_size == ctx_blk_size) {
+			if (cp->ctx_arr[i].mapping & (cp->ctx_align - 1)) {
+				cnic_free_context(dev);
+				cp->ctx_blk_size += cp->ctx_align;
+				i = -1;
+				continue;
+			}
+		}
+	}
+	return 0;
+}
+
+static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int i, j, n, ret, pages;
+	struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info;
+
+	cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ,
+				GFP_KERNEL);
+	if (!cp->iscsi_tbl)
+		goto error;
+
+	cp->ctx_tbl = kzalloc(sizeof(struct cnic_context) *
+				  MAX_CNIC_L5_CONTEXT, GFP_KERNEL);
+	if (!cp->ctx_tbl)
+		goto error;
+
+	for (i = 0; i < MAX_ISCSI_TBL_SZ; i++) {
+		cp->ctx_tbl[i].proto.iscsi = &cp->iscsi_tbl[i];
+		cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_ISCSI;
+	}
+
+	pages = PAGE_ALIGN(MAX_CNIC_L5_CONTEXT * CNIC_KWQ16_DATA_SIZE) /
+		PAGE_SIZE;
+
+	ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0);
+	if (ret)
+		return -ENOMEM;
+
+	n = PAGE_SIZE / CNIC_KWQ16_DATA_SIZE;
+	for (i = 0, j = 0; i < MAX_ISCSI_TBL_SZ; i++) {
+		long off = CNIC_KWQ16_DATA_SIZE * (i % n);
+
+		cp->ctx_tbl[i].kwqe_data = kwq_16_dma->pg_arr[j] + off;
+		cp->ctx_tbl[i].kwqe_data_mapping = kwq_16_dma->pg_map_arr[j] +
+						   off;
+
+		if ((i % n) == (n - 1))
+			j++;
+	}
+
+	ret = cnic_alloc_dma(dev, &cp->kcq_info, KCQ_PAGE_CNT, 0);
+	if (ret)
+		goto error;
+	cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr;
+
+	for (i = 0; i < KCQ_PAGE_CNT; i++) {
+		struct bnx2x_bd_chain_next *next =
+			(struct bnx2x_bd_chain_next *)
+			&cp->kcq[i][MAX_KCQE_CNT];
+		int j = i + 1;
+
+		if (j >= KCQ_PAGE_CNT)
+			j = 0;
+		next->addr_hi = (u64) cp->kcq_info.pg_map_arr[j] >> 32;
+		next->addr_lo = cp->kcq_info.pg_map_arr[j] & 0xffffffff;
+	}
+
+	pages = PAGE_ALIGN(BNX2X_ISCSI_NUM_CONNECTIONS *
+			   BNX2X_ISCSI_CONN_BUF_SIZE) / PAGE_SIZE;
+	ret = cnic_alloc_dma(dev, &cp->conn_buf_info, pages, 1);
+	if (ret)
+		goto error;
+
+	pages = PAGE_ALIGN(BNX2X_ISCSI_GLB_BUF_SIZE) / PAGE_SIZE;
+	ret = cnic_alloc_dma(dev, &cp->gbl_buf_info, pages, 0);
+	if (ret)
+		goto error;
+
+	ret = cnic_alloc_bnx2x_context(dev);
+	if (ret)
+		goto error;
+
+	cp->bnx2x_status_blk = cp->status_blk;
+	cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk;
+
+	memset(cp->bnx2x_status_blk, 0, sizeof(struct host_status_block));
+
+	cp->l2_rx_ring_size = 15;
+
+	ret = cnic_alloc_l2_rings(dev, 4);
+	if (ret)
+		goto error;
+
+	ret = cnic_alloc_uio(dev);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	cnic_free_resc(dev);
+	return -ENOMEM;
+}
+
 static inline u32 cnic_kwq_avail(struct cnic_local *cp)
 {
 	return cp->max_kwq_idx -
@@ -921,6 +1164,880 @@ static int cnic_submit_bnx2_kwqes(struct
 	return 0;
 }
 
+static void *cnic_get_kwqe_16_data(struct cnic_local *cp, u32 l5_cid,
+				   union l5cm_specific_data *l5_data)
+{
+	struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+	dma_addr_t map;
+
+	map = ctx->kwqe_data_mapping;
+	l5_data->phy_address.lo = (u64) map & 0xffffffff;
+	l5_data->phy_address.hi = (u64) map >> 32;
+	return ctx->kwqe_data;
+}
+
+static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid,
+				u32 type, union l5cm_specific_data *l5_data)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct l5cm_spe kwqe;
+	struct kwqe_16 *kwq[1];
+	int ret;
+
+	kwqe.hdr.conn_and_cmd_data =
+		cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) |
+			     BNX2X_HW_CID(cid, cp->func)));
+	kwqe.hdr.type = cpu_to_le16(type);
+	kwqe.hdr.reserved = 0;
+	kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo);
+	kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi);
+
+	kwq[0] = (struct kwqe_16 *) &kwqe;
+
+	spin_lock_bh(&cp->cnic_ulp_lock);
+	ret = cp->ethdev->drv_submit_kwqes_16(dev->netdev, kwq, 1);
+	spin_unlock_bh(&cp->cnic_ulp_lock);
+
+	if (ret == 1)
+		return 0;
+
+	return -EBUSY;
+}
+
+static void cnic_reply_bnx2x_kcqes(struct cnic_dev *dev, int ulp_type,
+				   struct kcqe *cqes[], u32 num_cqes)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_ulp_ops *ulp_ops;
+
+	rcu_read_lock();
+	ulp_ops = rcu_dereference(cp->ulp_ops[ulp_type]);
+	if (likely(ulp_ops)) {
+		ulp_ops->indicate_kcqes(cp->ulp_handle[ulp_type],
+					  cqes, num_cqes);
+	}
+	rcu_read_unlock();
+}
+
+static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct iscsi_kwqe_init1 *req1 = (struct iscsi_kwqe_init1 *) kwqe;
+	int func = cp->func, pages;
+	int hq_bds;
+
+	cp->num_iscsi_tasks = req1->num_tasks_per_conn;
+	cp->num_ccells = req1->num_ccells_per_conn;
+	cp->task_array_size = BNX2X_ISCSI_TASK_CONTEXT_SIZE *
+			      cp->num_iscsi_tasks;
+	cp->r2tq_size = cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS *
+			BNX2X_ISCSI_R2TQE_SIZE;
+	cp->hq_size = cp->num_ccells * BNX2X_ISCSI_HQ_BD_SIZE;
+	pages = PAGE_ALIGN(cp->hq_size) / PAGE_SIZE;
+	hq_bds = pages * (PAGE_SIZE / BNX2X_ISCSI_HQ_BD_SIZE);
+	cp->num_cqs = req1->num_cqs;
+
+	if (!dev->max_iscsi_conn)
+		return 0;
+
+	/* init Tstorm RAM */
+	CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(func),
+		  req1->rq_num_wqes);
+	CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+		  PAGE_SIZE);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+	CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
+		  TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+		  req1->num_tasks_per_conn);
+
+	/* init Ustorm RAM */
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM +
+		  USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(func),
+		  req1->rq_buffer_size);
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+		  PAGE_SIZE);
+	CNIC_WR8(dev, BAR_USTRORM_INTMEM +
+		 USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM +
+		  USTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+		  req1->num_tasks_per_conn);
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(func),
+		  req1->rq_num_wqes);
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(func),
+		  req1->cq_num_wqes);
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(func),
+		  cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS);
+
+	/* init Xstorm RAM */
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+		  PAGE_SIZE);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
+		  XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+		  req1->num_tasks_per_conn);
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(func),
+		  hq_bds);
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(func),
+		  req1->num_tasks_per_conn);
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(func),
+		  cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS);
+
+	/* init Cstorm RAM */
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(func),
+		  PAGE_SIZE);
+	CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
+		 CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
+		  CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func),
+		  req1->num_tasks_per_conn);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(func),
+		  req1->cq_num_wqes);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(func),
+		  hq_bds);
+
+	return 0;
+}
+
+static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct iscsi_kwqe_init2 *req2 = (struct iscsi_kwqe_init2 *) kwqe;
+	struct cnic_local *cp = dev->cnic_priv;
+	int func = cp->func;
+	struct iscsi_kcqe kcqe;
+	struct kcqe *cqes[1];
+
+	memset(&kcqe, 0, sizeof(kcqe));
+	if (!dev->max_iscsi_conn) {
+		kcqe.completion_status =
+			ISCSI_KCQE_COMPLETION_STATUS_ISCSI_NOT_SUPPORTED;
+		goto done;
+	}
+
+	CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+		TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]);
+	CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+		TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4,
+		req2->error_bit_map[1]);
+
+	CNIC_WR16(dev, BAR_USTRORM_INTMEM +
+		  USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn);
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]);
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4,
+		req2->error_bit_map[1]);
+
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
+		  CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn);
+
+	kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS;
+
+done:
+	kcqe.op_code = ISCSI_KCQE_OPCODE_INIT;
+	cqes[0] = (struct kcqe *) &kcqe;
+	cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_ISCSI, cqes, 1);
+
+	return 0;
+}
+
+static void cnic_free_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+
+	if (ctx->ulp_proto_id == CNIC_ULP_ISCSI) {
+		struct cnic_iscsi *iscsi = ctx->proto.iscsi;
+
+		cnic_free_dma(dev, &iscsi->hq_info);
+		cnic_free_dma(dev, &iscsi->r2tq_info);
+		cnic_free_dma(dev, &iscsi->task_array_info);
+	}
+	cnic_free_id(&cp->cid_tbl, ctx->cid);
+	ctx->cid = 0;
+}
+
+static int cnic_alloc_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid)
+{
+	u32 cid;
+	int ret, pages;
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+	struct cnic_iscsi *iscsi = ctx->proto.iscsi;
+
+	cid = cnic_alloc_new_id(&cp->cid_tbl);
+	if (cid == -1) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	ctx->cid = cid;
+	pages = PAGE_ALIGN(cp->task_array_size) / PAGE_SIZE;
+
+	ret = cnic_alloc_dma(dev, &iscsi->task_array_info, pages, 1);
+	if (ret)
+		goto error;
+
+	pages = PAGE_ALIGN(cp->r2tq_size) / PAGE_SIZE;
+	ret = cnic_alloc_dma(dev, &iscsi->r2tq_info, pages, 1);
+	if (ret)
+		goto error;
+
+	pages = PAGE_ALIGN(cp->hq_size) / PAGE_SIZE;
+	ret = cnic_alloc_dma(dev, &iscsi->hq_info, pages, 1);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	cnic_free_bnx2x_conn_resc(dev, l5_cid);
+	return ret;
+}
+
+static void *cnic_get_bnx2x_ctx(struct cnic_dev *dev, u32 cid, int init,
+				struct regpair *ctx_addr)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	int blk = (cid - ethdev->starting_cid) / cp->cids_per_blk;
+	int off = (cid - ethdev->starting_cid) % cp->cids_per_blk;
+	unsigned long align_off = 0;
+	dma_addr_t ctx_map;
+	void *ctx;
+
+	if (cp->ctx_align) {
+		unsigned long mask = cp->ctx_align - 1;
+
+		if (cp->ctx_arr[blk].mapping & mask)
+			align_off = cp->ctx_align -
+				    (cp->ctx_arr[blk].mapping & mask);
+	}
+	ctx_map = cp->ctx_arr[blk].mapping + align_off +
+		(off * BNX2X_CONTEXT_MEM_SIZE);
+	ctx = cp->ctx_arr[blk].ctx + align_off +
+	      (off * BNX2X_CONTEXT_MEM_SIZE);
+	if (init)
+		memset(ctx, 0, BNX2X_CONTEXT_MEM_SIZE);
+
+	ctx_addr->lo = ctx_map & 0xffffffff;
+	ctx_addr->hi = (u64) ctx_map >> 32;
+	return ctx;
+}
+
+static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[],
+				u32 num)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct iscsi_kwqe_conn_offload1 *req1 =
+			(struct iscsi_kwqe_conn_offload1 *) wqes[0];
+	struct iscsi_kwqe_conn_offload2 *req2 =
+			(struct iscsi_kwqe_conn_offload2 *) wqes[1];
+	struct iscsi_kwqe_conn_offload3 *req3;
+	struct cnic_context *ctx = &cp->ctx_tbl[req1->iscsi_conn_id];
+	struct cnic_iscsi *iscsi = ctx->proto.iscsi;
+	u32 cid = ctx->cid;
+	u32 hw_cid = BNX2X_HW_CID(cid, cp->func);
+	struct iscsi_context *ictx;
+	struct regpair context_addr;
+	int i, j, n = 2, n_max;
+
+	ctx->ctx_flags = 0;
+	if (!req2->num_additional_wqes)
+		return -EINVAL;
+
+	n_max = req2->num_additional_wqes + 2;
+
+	ictx = cnic_get_bnx2x_ctx(dev, cid, 1, &context_addr);
+	if (ictx == NULL)
+		return -ENOMEM;
+
+	req3 = (struct iscsi_kwqe_conn_offload3 *) wqes[n++];
+
+	ictx->xstorm_ag_context.hq_prod = 1;
+
+	ictx->xstorm_st_context.iscsi.first_burst_length =
+		ISCSI_DEF_FIRST_BURST_LEN;
+	ictx->xstorm_st_context.iscsi.max_send_pdu_length =
+		ISCSI_DEF_MAX_RECV_SEG_LEN;
+	ictx->xstorm_st_context.iscsi.sq_pbl_base.lo =
+		req1->sq_page_table_addr_lo;
+	ictx->xstorm_st_context.iscsi.sq_pbl_base.hi =
+		req1->sq_page_table_addr_hi;
+	ictx->xstorm_st_context.iscsi.sq_curr_pbe.lo = req2->sq_first_pte.hi;
+	ictx->xstorm_st_context.iscsi.sq_curr_pbe.hi = req2->sq_first_pte.lo;
+	ictx->xstorm_st_context.iscsi.hq_pbl_base.lo =
+		iscsi->hq_info.pgtbl_map & 0xffffffff;
+	ictx->xstorm_st_context.iscsi.hq_pbl_base.hi =
+		(u64) iscsi->hq_info.pgtbl_map >> 32;
+	ictx->xstorm_st_context.iscsi.hq_curr_pbe_base.lo =
+		iscsi->hq_info.pgtbl[0];
+	ictx->xstorm_st_context.iscsi.hq_curr_pbe_base.hi =
+		iscsi->hq_info.pgtbl[1];
+	ictx->xstorm_st_context.iscsi.r2tq_pbl_base.lo =
+		iscsi->r2tq_info.pgtbl_map & 0xffffffff;
+	ictx->xstorm_st_context.iscsi.r2tq_pbl_base.hi =
+		(u64) iscsi->r2tq_info.pgtbl_map >> 32;
+	ictx->xstorm_st_context.iscsi.r2tq_curr_pbe_base.lo =
+		iscsi->r2tq_info.pgtbl[0];
+	ictx->xstorm_st_context.iscsi.r2tq_curr_pbe_base.hi =
+		iscsi->r2tq_info.pgtbl[1];
+	ictx->xstorm_st_context.iscsi.task_pbl_base.lo =
+		iscsi->task_array_info.pgtbl_map & 0xffffffff;
+	ictx->xstorm_st_context.iscsi.task_pbl_base.hi =
+		(u64) iscsi->task_array_info.pgtbl_map >> 32;
+	ictx->xstorm_st_context.iscsi.task_pbl_cache_idx =
+		BNX2X_ISCSI_PBL_NOT_CACHED;
+	ictx->xstorm_st_context.iscsi.flags.flags |=
+		XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA;
+	ictx->xstorm_st_context.iscsi.flags.flags |=
+		XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T;
+
+	ictx->tstorm_st_context.iscsi.hdr_bytes_2_fetch = ISCSI_HEADER_SIZE;
+	/* TSTORM requires the base address of RQ DB & not PTE */
+	ictx->tstorm_st_context.iscsi.rq_db_phy_addr.lo =
+		req2->rq_page_table_addr_lo & PAGE_MASK;
+	ictx->tstorm_st_context.iscsi.rq_db_phy_addr.hi =
+		req2->rq_page_table_addr_hi;
+	ictx->tstorm_st_context.iscsi.iscsi_conn_id = req1->iscsi_conn_id;
+	ictx->tstorm_st_context.tcp.cwnd = 0x5A8;
+	ictx->tstorm_st_context.tcp.flags2 |=
+		TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN;
+
+	ictx->timers_context.flags |= ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG;
+
+	ictx->ustorm_st_context.ring.rq.pbl_base.lo =
+		req2->rq_page_table_addr_lo;
+	ictx->ustorm_st_context.ring.rq.pbl_base.hi =
+		req2->rq_page_table_addr_hi;
+	ictx->ustorm_st_context.ring.rq.curr_pbe.lo = req3->qp_first_pte[0].hi;
+	ictx->ustorm_st_context.ring.rq.curr_pbe.hi = req3->qp_first_pte[0].lo;
+	ictx->ustorm_st_context.ring.r2tq.pbl_base.lo =
+		iscsi->r2tq_info.pgtbl_map & 0xffffffff;
+	ictx->ustorm_st_context.ring.r2tq.pbl_base.hi =
+		(u64) iscsi->r2tq_info.pgtbl_map >> 32;
+	ictx->ustorm_st_context.ring.r2tq.curr_pbe.lo =
+		iscsi->r2tq_info.pgtbl[0];
+	ictx->ustorm_st_context.ring.r2tq.curr_pbe.hi =
+		iscsi->r2tq_info.pgtbl[1];
+	ictx->ustorm_st_context.ring.cq_pbl_base.lo =
+		req1->cq_page_table_addr_lo;
+	ictx->ustorm_st_context.ring.cq_pbl_base.hi =
+		req1->cq_page_table_addr_hi;
+	ictx->ustorm_st_context.ring.cq[0].cq_sn = ISCSI_INITIAL_SN;
+	ictx->ustorm_st_context.ring.cq[0].curr_pbe.lo = req2->cq_first_pte.hi;
+	ictx->ustorm_st_context.ring.cq[0].curr_pbe.hi = req2->cq_first_pte.lo;
+	ictx->ustorm_st_context.task_pbe_cache_index =
+		BNX2X_ISCSI_PBL_NOT_CACHED;
+	ictx->ustorm_st_context.task_pdu_cache_index =
+		BNX2X_ISCSI_PDU_HEADER_NOT_CACHED;
+
+	for (i = 1, j = 1; i < cp->num_cqs; i++, j++) {
+		if (j == 3) {
+			if (n >= n_max)
+				break;
+			req3 = (struct iscsi_kwqe_conn_offload3 *) wqes[n++];
+			j = 0;
+		}
+		ictx->ustorm_st_context.ring.cq[i].cq_sn = ISCSI_INITIAL_SN;
+		ictx->ustorm_st_context.ring.cq[i].curr_pbe.lo =
+			req3->qp_first_pte[j].hi;
+		ictx->ustorm_st_context.ring.cq[i].curr_pbe.hi =
+			req3->qp_first_pte[j].lo;
+	}
+
+	ictx->ustorm_st_context.task_pbl_base.lo =
+		iscsi->task_array_info.pgtbl_map & 0xffffffff;
+	ictx->ustorm_st_context.task_pbl_base.hi =
+		(u64) iscsi->task_array_info.pgtbl_map >> 32;
+	ictx->ustorm_st_context.tce_phy_addr.lo =
+		iscsi->task_array_info.pgtbl[0];
+	ictx->ustorm_st_context.tce_phy_addr.hi =
+		iscsi->task_array_info.pgtbl[1];
+	ictx->ustorm_st_context.iscsi_conn_id = req1->iscsi_conn_id;
+	ictx->ustorm_st_context.num_cqs = cp->num_cqs;
+	ictx->ustorm_st_context.negotiated_rx |= ISCSI_DEF_MAX_RECV_SEG_LEN;
+	ictx->ustorm_st_context.negotiated_rx_and_flags |=
+		ISCSI_DEF_MAX_BURST_LEN;
+	ictx->ustorm_st_context.negotiated_rx |=
+		ISCSI_DEFAULT_MAX_OUTSTANDING_R2T <<
+		USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS_SHIFT;
+
+	ictx->cstorm_st_context.hq_pbl_base.lo =
+		iscsi->hq_info.pgtbl_map & 0xffffffff;
+	ictx->cstorm_st_context.hq_pbl_base.hi =
+		(u64) iscsi->hq_info.pgtbl_map >> 32;
+	ictx->cstorm_st_context.hq_curr_pbe.lo = iscsi->hq_info.pgtbl[0];
+	ictx->cstorm_st_context.hq_curr_pbe.hi = iscsi->hq_info.pgtbl[1];
+	ictx->cstorm_st_context.task_pbl_base.lo =
+		iscsi->task_array_info.pgtbl_map & 0xffffffff;
+	ictx->cstorm_st_context.task_pbl_base.hi =
+		(u64) iscsi->task_array_info.pgtbl_map >> 32;
+	/* CSTORM and USTORM initialization is different, CSTORM requires
+	 * CQ DB base & not PTE addr */
+	ictx->cstorm_st_context.cq_db_base.lo =
+		req1->cq_page_table_addr_lo & PAGE_MASK;
+	ictx->cstorm_st_context.cq_db_base.hi = req1->cq_page_table_addr_hi;
+	ictx->cstorm_st_context.iscsi_conn_id = req1->iscsi_conn_id;
+	ictx->cstorm_st_context.cq_proc_en_bit_map = (1 << cp->num_cqs) - 1;
+	for (i = 0; i < cp->num_cqs; i++) {
+		ictx->cstorm_st_context.cq_c_prod_sqn_arr.sqn[i] =
+			ISCSI_INITIAL_SN;
+		ictx->cstorm_st_context.cq_c_sqn_2_notify_arr.sqn[i] =
+			ISCSI_INITIAL_SN;
+	}
+
+	ictx->xstorm_ag_context.cdu_reserved =
+		CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_XCM_AG,
+				       ISCSI_CONNECTION_TYPE);
+	ictx->ustorm_ag_context.cdu_usage =
+		CDU_RSRVD_VALUE_TYPE_A(hw_cid, CDU_REGION_NUMBER_UCM_AG,
+				       ISCSI_CONNECTION_TYPE);
+	return 0;
+
+}
+
+static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
+				   u32 num, int *work)
+{
+	struct iscsi_kwqe_conn_offload1 *req1;
+	struct iscsi_kwqe_conn_offload2 *req2;
+	struct cnic_local *cp = dev->cnic_priv;
+	struct iscsi_kcqe kcqe;
+	struct kcqe *cqes[1];
+	u32 l5_cid;
+	int ret;
+
+	if (num < 2) {
+		*work = num;
+		return -EINVAL;
+	}
+
+	req1 = (struct iscsi_kwqe_conn_offload1 *) wqes[0];
+	req2 = (struct iscsi_kwqe_conn_offload2 *) wqes[1];
+	if ((num - 2) < req2->num_additional_wqes) {
+		*work = num;
+		return -EINVAL;
+	}
+	*work = 2 + req2->num_additional_wqes;;
+
+	l5_cid = req1->iscsi_conn_id;
+	if (l5_cid >= MAX_ISCSI_TBL_SZ)
+		return -EINVAL;
+
+	memset(&kcqe, 0, sizeof(kcqe));
+	kcqe.op_code = ISCSI_KCQE_OPCODE_OFFLOAD_CONN;
+	kcqe.iscsi_conn_id = l5_cid;
+	kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE;
+
+	if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) {
+		atomic_dec(&cp->iscsi_conn);
+		ret = 0;
+		goto done;
+	}
+	ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid);
+	if (ret) {
+		atomic_dec(&cp->iscsi_conn);
+		ret = 0;
+		goto done;
+	}
+	ret = cnic_setup_bnx2x_ctx(dev, wqes, num);
+	if (ret < 0) {
+		cnic_free_bnx2x_conn_resc(dev, l5_cid);
+		atomic_dec(&cp->iscsi_conn);
+		goto done;
+	}
+
+	kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS;
+	kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp->ctx_tbl[l5_cid].cid,
+						  cp->func);
+
+done:
+	cqes[0] = (struct kcqe *) &kcqe;
+	cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_ISCSI, cqes, 1);
+	return ret;
+}
+
+
+static int cnic_bnx2x_iscsi_update(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct iscsi_kwqe_conn_update *req =
+		(struct iscsi_kwqe_conn_update *) kwqe;
+	void *data;
+	union l5cm_specific_data l5_data;
+	u32 l5_cid, cid = BNX2X_SW_CID(req->context_id);
+	int ret;
+
+	if (cnic_get_l5_cid(cp, cid, &l5_cid) != 0)
+		return -EINVAL;
+
+	data = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
+	if (!data)
+		return -ENOMEM;
+
+	memcpy(data, kwqe, sizeof(struct kwqe));
+
+	ret = cnic_submit_kwqe_16(dev, ISCSI_RAMROD_CMD_ID_UPDATE_CONN,
+			req->context_id, ISCSI_CONNECTION_TYPE, &l5_data);
+	return ret;
+}
+
+static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct iscsi_kwqe_conn_destroy *req =
+		(struct iscsi_kwqe_conn_destroy *) kwqe;
+	union l5cm_specific_data l5_data;
+	u32 l5_cid = req->reserved0;
+	struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+	int ret = 0;
+	struct iscsi_kcqe kcqe;
+	struct kcqe *cqes[1];
+
+	if (!(ctx->ctx_flags & CTX_FL_OFFLD_START))
+		goto skip_cfc_delete;
+
+	while (!time_after(jiffies, ctx->timestamp + (2 * HZ)))
+		msleep(250);
+
+	init_waitqueue_head(&ctx->waitq);
+	ctx->wait_cond = 0;
+	memset(&l5_data, 0, sizeof(l5_data));
+	ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL,
+				  req->context_id,
+				  ETH_CONNECTION_TYPE |
+				  (1 << SPE_HDR_COMMON_RAMROD_SHIFT),
+				  &l5_data);
+	if (ret == 0)
+		wait_event(ctx->waitq, ctx->wait_cond);
+
+skip_cfc_delete:
+	cnic_free_bnx2x_conn_resc(dev, l5_cid);
+
+	atomic_dec(&cp->iscsi_conn);
+
+	memset(&kcqe, 0, sizeof(kcqe));
+	kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN;
+	kcqe.iscsi_conn_id = l5_cid;
+	kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS;
+	kcqe.iscsi_conn_context_id = req->context_id;
+
+	cqes[0] = (struct kcqe *) &kcqe;
+	cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_ISCSI, cqes, 1);
+
+	return ret;
+}
+
+static void cnic_init_storm_conn_bufs(struct cnic_dev *dev,
+				      struct l4_kwq_connect_req1 *kwqe1,
+				      struct l4_kwq_connect_req3 *kwqe3,
+				      struct l5cm_active_conn_buffer *conn_buf)
+{
+	struct l5cm_conn_addr_params *conn_addr = &conn_buf->conn_addr_buf;
+	struct l5cm_xstorm_conn_buffer *xstorm_buf =
+		&conn_buf->xstorm_conn_buffer;
+	struct l5cm_tstorm_conn_buffer *tstorm_buf =
+		&conn_buf->tstorm_conn_buffer;
+	struct regpair context_addr;
+	u32 cid = BNX2X_SW_CID(kwqe1->cid);
+	struct in6_addr src_ip, dst_ip;
+	int i;
+	u32 *addrp;
+
+	addrp = (u32 *) &conn_addr->local_ip_addr;
+	for (i = 0; i < 4; i++, addrp++)
+		src_ip.in6_u.u6_addr32[i] = cpu_to_be32(*addrp);
+
+	addrp = (u32 *) &conn_addr->remote_ip_addr;
+	for (i = 0; i < 4; i++, addrp++)
+		dst_ip.in6_u.u6_addr32[i] = cpu_to_be32(*addrp);
+
+	cnic_get_bnx2x_ctx(dev, cid, 0, &context_addr);
+
+	xstorm_buf->context_addr.hi = context_addr.hi;
+	xstorm_buf->context_addr.lo = context_addr.lo;
+	xstorm_buf->mss = 0xffff;
+	xstorm_buf->rcv_buf = kwqe3->rcv_buf;
+	if (kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_NAGLE_ENABLE)
+		xstorm_buf->params |= L5CM_XSTORM_CONN_BUFFER_NAGLE_ENABLE;
+	xstorm_buf->pseudo_header_checksum =
+		swab16(~csum_ipv6_magic(&src_ip, &dst_ip, 0, IPPROTO_TCP, 0));
+
+	if (!(kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_NO_DELAY_ACK))
+		tstorm_buf->params |=
+			L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE;
+	if (kwqe3->ka_timeout) {
+		tstorm_buf->ka_enable = 1;
+		tstorm_buf->ka_timeout = kwqe3->ka_timeout;
+		tstorm_buf->ka_interval = kwqe3->ka_interval;
+		tstorm_buf->ka_max_probe_count = kwqe3->ka_max_probe_count;
+	}
+	tstorm_buf->rcv_buf = kwqe3->rcv_buf;
+	tstorm_buf->snd_buf = kwqe3->snd_buf;
+	tstorm_buf->max_rt_time = 0xffffffff;
+}
+
+static void cnic_init_bnx2x_mac(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int func = CNIC_FUNC(cp);
+	u8 *mac = dev->mac_addr;
+
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(func), mac[0]);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(func), mac[1]);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(func), mac[2]);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(func), mac[3]);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(func), mac[4]);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(func), mac[5]);
+
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func), mac[5]);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func) + 1,
+		 mac[4]);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func), mac[3]);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 1,
+		 mac[2]);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 2,
+		 mac[1]);
+	CNIC_WR8(dev, BAR_TSTRORM_INTMEM +
+		 TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 3,
+		 mac[0]);
+}
+
+static void cnic_bnx2x_set_tcp_timestamp(struct cnic_dev *dev, int tcp_ts)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	u8 xstorm_flags = XSTORM_L5CM_TCP_FLAGS_WND_SCL_EN;
+	u16 tstorm_flags = 0;
+
+	if (tcp_ts) {
+		xstorm_flags |= XSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
+		tstorm_flags |= TSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
+	}
+
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), xstorm_flags);
+
+	CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
+		  TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), tstorm_flags);
+}
+
+static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
+			      u32 num, int *work)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct l4_kwq_connect_req1 *kwqe1 =
+		(struct l4_kwq_connect_req1 *) wqes[0];
+	struct l4_kwq_connect_req3 *kwqe3;
+	struct l5cm_active_conn_buffer *conn_buf;
+	struct l5cm_conn_addr_params *conn_addr;
+	union l5cm_specific_data l5_data;
+	u32 l5_cid = kwqe1->pg_cid;
+	struct cnic_sock *csk = &cp->csk_tbl[l5_cid];
+	struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+	int ret;
+
+	if (num < 2) {
+		*work = num;
+		return -EINVAL;
+	}
+
+	if (kwqe1->conn_flags & L4_KWQ_CONNECT_REQ1_IP_V6)
+		*work = 3;
+	else
+		*work = 2;
+
+	if (num < *work) {
+		*work = num;
+		return -EINVAL;
+	}
+
+	if (sizeof(*conn_buf) > CNIC_KWQ16_DATA_SIZE) {
+		printk(KERN_ERR PFX "%s: conn_buf size too big\n",
+			       dev->netdev->name);
+		return -ENOMEM;
+	}
+	conn_buf = cnic_get_kwqe_16_data(cp, l5_cid, &l5_data);
+	if (!conn_buf)
+		return -ENOMEM;
+
+	memset(conn_buf, 0, sizeof(*conn_buf));
+
+	conn_addr = &conn_buf->conn_addr_buf;
+	conn_addr->remote_addr_0 = csk->ha[0];
+	conn_addr->remote_addr_1 = csk->ha[1];
+	conn_addr->remote_addr_2 = csk->ha[2];
+	conn_addr->remote_addr_3 = csk->ha[3];
+	conn_addr->remote_addr_4 = csk->ha[4];
+	conn_addr->remote_addr_5 = csk->ha[5];
+
+	if (kwqe1->conn_flags & L4_KWQ_CONNECT_REQ1_IP_V6) {
+		struct l4_kwq_connect_req2 *kwqe2 =
+			(struct l4_kwq_connect_req2 *) wqes[1];
+
+		conn_addr->local_ip_addr.ip_addr_hi_hi = kwqe2->src_ip_v6_4;
+		conn_addr->local_ip_addr.ip_addr_hi_lo = kwqe2->src_ip_v6_3;
+		conn_addr->local_ip_addr.ip_addr_lo_hi = kwqe2->src_ip_v6_2;
+
+		conn_addr->remote_ip_addr.ip_addr_hi_hi = kwqe2->dst_ip_v6_4;
+		conn_addr->remote_ip_addr.ip_addr_hi_lo = kwqe2->dst_ip_v6_3;
+		conn_addr->remote_ip_addr.ip_addr_lo_hi = kwqe2->dst_ip_v6_2;
+		conn_addr->params |= L5CM_CONN_ADDR_PARAMS_IP_VERSION;
+	}
+	kwqe3 = (struct l4_kwq_connect_req3 *) wqes[*work - 1];
+
+	conn_addr->local_ip_addr.ip_addr_lo_lo = kwqe1->src_ip;
+	conn_addr->remote_ip_addr.ip_addr_lo_lo = kwqe1->dst_ip;
+	conn_addr->local_tcp_port = kwqe1->src_port;
+	conn_addr->remote_tcp_port = kwqe1->dst_port;
+
+	conn_addr->pmtu = kwqe3->pmtu;
+	cnic_init_storm_conn_bufs(dev, kwqe1, kwqe3, conn_buf);
+
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
+		  XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->func), csk->vlan_id);
+
+	cnic_bnx2x_set_tcp_timestamp(dev,
+		kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_TIME_STAMP);
+
+	ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_TCP_CONNECT,
+			kwqe1->cid, ISCSI_CONNECTION_TYPE, &l5_data);
+	if (!ret)
+		ctx->ctx_flags |= CTX_FL_OFFLD_START;
+
+	return ret;
+}
+
+static int cnic_bnx2x_close(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct l4_kwq_close_req *req = (struct l4_kwq_close_req *) kwqe;
+	union l5cm_specific_data l5_data;
+	int ret;
+
+	memset(&l5_data, 0, sizeof(l5_data));
+	ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_CLOSE,
+			req->cid, ISCSI_CONNECTION_TYPE, &l5_data);
+	return ret;
+}
+
+static int cnic_bnx2x_reset(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct l4_kwq_reset_req *req = (struct l4_kwq_reset_req *) kwqe;
+	union l5cm_specific_data l5_data;
+	int ret;
+
+	memset(&l5_data, 0, sizeof(l5_data));
+	ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_ABORT,
+			req->cid, ISCSI_CONNECTION_TYPE, &l5_data);
+	return ret;
+}
+static int cnic_bnx2x_offload_pg(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct l4_kwq_offload_pg *req = (struct l4_kwq_offload_pg *) kwqe;
+	struct l4_kcq kcqe;
+	struct kcqe *cqes[1];
+
+	memset(&kcqe, 0, sizeof(kcqe));
+	kcqe.pg_host_opaque = req->host_opaque;
+	kcqe.pg_cid = req->host_opaque;
+	kcqe.op_code = L4_KCQE_OPCODE_VALUE_OFFLOAD_PG;
+	cqes[0] = (struct kcqe *) &kcqe;
+	cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_L4, cqes, 1);
+	return 0;
+}
+
+static int cnic_bnx2x_update_pg(struct cnic_dev *dev, struct kwqe *kwqe)
+{
+	struct l4_kwq_update_pg *req = (struct l4_kwq_update_pg *) kwqe;
+	struct l4_kcq kcqe;
+	struct kcqe *cqes[1];
+
+	memset(&kcqe, 0, sizeof(kcqe));
+	kcqe.pg_host_opaque = req->pg_host_opaque;
+	kcqe.pg_cid = req->pg_cid;
+	kcqe.op_code = L4_KCQE_OPCODE_VALUE_UPDATE_PG;
+	cqes[0] = (struct kcqe *) &kcqe;
+	cnic_reply_bnx2x_kcqes(dev, CNIC_ULP_L4, cqes, 1);
+	return 0;
+}
+
+static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[],
+				   u32 num_wqes)
+{
+	int i, work, ret;
+	u32 opcode;
+	struct kwqe *kwqe;
+
+	if (!test_bit(CNIC_F_CNIC_UP, &dev->flags))
+		return -EAGAIN;		/* bnx2 is down */
+
+	for (i = 0; i < num_wqes; ) {
+		kwqe = wqes[i];
+		opcode = KWQE_OPCODE(kwqe->kwqe_op_flag);
+		work = 1;
+
+		switch (opcode) {
+		case ISCSI_KWQE_OPCODE_INIT1:
+			ret = cnic_bnx2x_iscsi_init1(dev, kwqe);
+			break;
+		case ISCSI_KWQE_OPCODE_INIT2:
+			ret = cnic_bnx2x_iscsi_init2(dev, kwqe);
+			break;
+		case ISCSI_KWQE_OPCODE_OFFLOAD_CONN1:
+			ret = cnic_bnx2x_iscsi_ofld1(dev, &wqes[i],
+						     num_wqes - i, &work);
+			break;
+		case ISCSI_KWQE_OPCODE_UPDATE_CONN:
+			ret = cnic_bnx2x_iscsi_update(dev, kwqe);
+			break;
+		case ISCSI_KWQE_OPCODE_DESTROY_CONN:
+			ret = cnic_bnx2x_iscsi_destroy(dev, kwqe);
+			break;
+		case L4_KWQE_OPCODE_VALUE_CONNECT1:
+			ret = cnic_bnx2x_connect(dev, &wqes[i], num_wqes - i,
+						 &work);
+			break;
+		case L4_KWQE_OPCODE_VALUE_CLOSE:
+			ret = cnic_bnx2x_close(dev, kwqe);
+			break;
+		case L4_KWQE_OPCODE_VALUE_RESET:
+			ret = cnic_bnx2x_reset(dev, kwqe);
+			break;
+		case L4_KWQE_OPCODE_VALUE_OFFLOAD_PG:
+			ret = cnic_bnx2x_offload_pg(dev, kwqe);
+			break;
+		case L4_KWQE_OPCODE_VALUE_UPDATE_PG:
+			ret = cnic_bnx2x_update_pg(dev, kwqe);
+			break;
+		case L4_KWQE_OPCODE_VALUE_UPLOAD_PG:
+			ret = 0;
+			break;
+		default:
+			ret = 0;
+			printk(KERN_ERR PFX "%s: Unknown type of KWQE(0x%x)\n",
+			       dev->netdev->name, opcode);
+			break;
+		}
+		if (ret < 0)
+			printk(KERN_ERR PFX "%s: KWQE(0x%x) failed\n",
+			       dev->netdev->name, opcode);
+		i += work;
+	}
+	return 0;
+}
+
 static void service_kcqes(struct cnic_dev *dev, int num_cqes)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -987,6 +2104,22 @@ static u16 cnic_bnx2_hw_idx(u16 idx)
 	return idx;
 }
 
+static u16 cnic_bnx2x_next_idx(u16 idx)
+{
+	idx++;
+	if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT)
+		idx++;
+
+	return idx;
+}
+
+static u16 cnic_bnx2x_hw_idx(u16 idx)
+{
+	if ((idx & MAX_KCQE_CNT) == MAX_KCQE_CNT)
+		idx++;
+	return idx;
+}
+
 static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -1012,7 +2145,7 @@ static int cnic_get_kcqes(struct cnic_de
 	return last_cnt;
 }
 
-static void cnic_chk_bnx2_pkt_rings(struct cnic_local *cp)
+static void cnic_chk_pkt_rings(struct cnic_local *cp)
 {
 	u16 rx_cons = *cp->rx_cons_ptr;
 	u16 tx_cons = *cp->tx_cons_ptr;
@@ -1020,6 +2153,7 @@ static void cnic_chk_bnx2_pkt_rings(stru
 	if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) {
 		cp->tx_cons = tx_cons;
 		cp->rx_cons = rx_cons;
+
 		uio_event_notify(cp->cnic_uinfo);
 	}
 }
@@ -1062,7 +2196,7 @@ done:
 
 	cp->kcq_prod_idx = sw_prod;
 
-	cnic_chk_bnx2_pkt_rings(cp);
+	cnic_chk_pkt_rings(cp);
 	return status_idx;
 }
 
@@ -1100,7 +2234,7 @@ done:
 	CNIC_WR16(dev, cp->kcq_io_addr, sw_prod);
 	cp->kcq_prod_idx = sw_prod;
 
-	cnic_chk_bnx2_pkt_rings(cp);
+	cnic_chk_pkt_rings(cp);
 
 	cp->last_status_idx = status_idx;
 	CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num |
@@ -1125,6 +2259,91 @@ static irqreturn_t cnic_irq(int irq, voi
 	return IRQ_HANDLED;
 }
 
+static inline void cnic_ack_bnx2x_int(struct cnic_dev *dev, u8 id, u8 storm,
+				      u16 index, u8 op, u8 update)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	u32 hc_addr = (HC_REG_COMMAND_REG + CNIC_PORT(cp) * 32 +
+		       COMMAND_REG_INT_ACK);
+	struct igu_ack_register igu_ack;
+
+	igu_ack.status_block_index = index;
+	igu_ack.sb_id_and_flags =
+			((id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
+			 (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
+			 (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
+			 (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
+
+	CNIC_WR(dev, hc_addr, (*(u32 *)&igu_ack));
+}
+
+static void cnic_ack_bnx2x_msix(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+
+	cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 0,
+			   IGU_INT_DISABLE, 0);
+}
+
+static void cnic_service_bnx2x_bh(unsigned long data)
+{
+	struct cnic_dev *dev = (struct cnic_dev *) data;
+	struct cnic_local *cp = dev->cnic_priv;
+	u16 hw_prod, sw_prod;
+	struct cstorm_status_block_c *sblk =
+		&cp->bnx2x_status_blk->c_status_block;
+	u32 status_idx = sblk->status_block_index;
+	int kcqe_cnt;
+
+	if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
+		return;
+
+	hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
+	hw_prod = cp->hw_idx(hw_prod);
+	sw_prod = cp->kcq_prod_idx;
+	while (sw_prod != hw_prod) {
+		kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
+		if (kcqe_cnt == 0)
+			goto done;
+
+		service_kcqes(dev, kcqe_cnt);
+
+		/* Tell compiler that sblk fields can change. */
+		barrier();
+		if (status_idx == sblk->status_block_index)
+			break;
+
+		status_idx = sblk->status_block_index;
+		hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
+		hw_prod = cp->hw_idx(hw_prod);
+	}
+
+done:
+	CNIC_WR16(dev, cp->kcq_io_addr, sw_prod + MAX_KCQ_IDX);
+	cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
+			   status_idx, IGU_INT_ENABLE, 1);
+
+	cp->kcq_prod_idx = sw_prod;
+	return;
+}
+
+static int cnic_service_bnx2x(void *data, void *status_blk)
+{
+	struct cnic_dev *dev = data;
+	struct cnic_local *cp = dev->cnic_priv;
+	u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
+
+	prefetch(cp->status_blk);
+	prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+
+	if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
+		tasklet_schedule(&cp->cnic_irq_task);
+
+	cnic_chk_pkt_rings(cp);
+
+	return 0;
+}
+
 static void cnic_ulp_stop(struct cnic_dev *dev)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -1197,6 +2416,19 @@ static int cnic_ctl(void *data, struct c
 
 		cnic_put(dev);
 		break;
+	case CNIC_CTL_COMPLETION_CMD: {
+		u32 cid = BNX2X_SW_CID(info->data.comp.cid);
+		u32 l5_cid;
+		struct cnic_local *cp = dev->cnic_priv;
+
+		if (cnic_get_l5_cid(cp, cid, &l5_cid) == 0) {
+			struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
+
+			ctx->wait_cond = 1;
+			wake_up(&ctx->waitq);
+		}
+		break;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -1872,6 +3104,8 @@ static void cnic_cm_process_kcqe(struct
 		/* fall through */
 	case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:
 	case L4_KCQE_OPCODE_VALUE_RESET_COMP:
+	case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE:
+	case L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD:
 		cp->close_conn(csk, opcode);
 		break;
 
@@ -1957,6 +3191,76 @@ static int cnic_cm_init_bnx2_hw(struct c
 	return 0;
 }
 
+static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode)
+{
+	struct cnic_dev *dev = csk->dev;
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_context *ctx = &cp->ctx_tbl[csk->l5_cid];
+	union l5cm_specific_data l5_data;
+	u32 cmd = 0;
+	int close_complete = 0;
+
+	switch (opcode) {
+	case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED:
+	case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:
+	case L4_KCQE_OPCODE_VALUE_RESET_COMP:
+		if (cnic_ready_to_close(csk, opcode))
+			cmd = L5CM_RAMROD_CMD_ID_SEARCHER_DELETE;
+		break;
+	case L5CM_RAMROD_CMD_ID_SEARCHER_DELETE:
+		cmd = L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD;
+		break;
+	case L5CM_RAMROD_CMD_ID_TERMINATE_OFFLOAD:
+		close_complete = 1;
+		break;
+	}
+	if (cmd) {
+		memset(&l5_data, 0, sizeof(l5_data));
+
+		cnic_submit_kwqe_16(dev, cmd, csk->cid, ISCSI_CONNECTION_TYPE,
+				    &l5_data);
+	} else if (close_complete) {
+		ctx->timestamp = jiffies;
+		cnic_close_conn(csk);
+		cnic_cm_upcall(cp, csk, csk->state);
+	}
+}
+
+static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
+{
+}
+
+static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int func = CNIC_FUNC(cp);
+
+	cnic_init_bnx2x_mac(dev);
+	cnic_bnx2x_set_tcp_timestamp(dev, 1);
+
+	CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
+		  XSTORM_ISCSI_LOCAL_VLAN_OFFSET(func), 0);
+
+	CNIC_WR(dev, BAR_XSTRORM_INTMEM +
+		XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(func), 1);
+	CNIC_WR(dev, BAR_XSTRORM_INTMEM +
+		XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(func),
+		DEF_MAX_DA_COUNT);
+
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(func), DEF_TTL);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(func), DEF_TOS);
+	CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+		 XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(func), 2);
+	CNIC_WR(dev, BAR_XSTRORM_INTMEM +
+		XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(func), DEF_SWS_TIMER);
+
+	CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(func),
+		DEF_MAX_CWND);
+	return 0;
+}
+
 static int cnic_cm_open(struct cnic_dev *dev)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -2091,7 +3395,7 @@ static int cnic_init_bnx2_irq(struct cni
 
 		cp->bnx2_status_blk = cp->status_blk;
 		cp->last_status_idx = cp->bnx2_status_blk->status_idx;
-		tasklet_init(&cp->cnic_irq_task, &cnic_service_bnx2_msix,
+		tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2_msix,
 			     (unsigned long) dev);
 		err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0,
 				  "cnic", dev);
@@ -2464,6 +3768,432 @@ static int cnic_start_bnx2_hw(struct cni
 	return 0;
 }
 
+static void cnic_setup_bnx2x_context(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	u32 start_offset = ethdev->ctx_tbl_offset;
+	int i;
+
+	for (i = 0; i < cp->ctx_blks; i++) {
+		struct cnic_ctx *ctx = &cp->ctx_arr[i];
+		dma_addr_t map = ctx->mapping;
+
+		if (cp->ctx_align) {
+			unsigned long mask = cp->ctx_align - 1;
+
+			map = (map + mask) & ~mask;
+		}
+
+		cnic_ctx_tbl_wr(dev, start_offset + i, map);
+	}
+}
+
+static int cnic_init_bnx2x_irq(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct cnic_eth_dev *ethdev = cp->ethdev;
+	int err = 0;
+
+	tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2x_bh,
+		     (unsigned long) dev);
+	if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
+		err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0,
+				  "cnic", dev);
+		if (err)
+			tasklet_disable(&cp->cnic_irq_task);
+	}
+	return err;
+}
+
+static void cnic_enable_bnx2x_int(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	u8 sb_id = cp->status_blk_num;
+	int port = CNIC_PORT(cp);
+
+	CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
+		 CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id,
+					       HC_INDEX_C_ISCSI_EQ_CONS),
+		 64 / 12);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
+		  CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id,
+						HC_INDEX_C_ISCSI_EQ_CONS), 0);
+}
+
+static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev)
+{
+}
+
+static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring;
+	struct eth_context *context;
+	struct regpair context_addr;
+	dma_addr_t buf_map;
+	int func = CNIC_FUNC(cp);
+	int port = CNIC_PORT(cp);
+	int i;
+	int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+	u32 val;
+
+	memset(txbd, 0, BCM_PAGE_SIZE);
+
+	buf_map = cp->l2_buf_map;
+	for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) {
+		struct eth_tx_start_bd *start_bd = &txbd->start_bd;
+		struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd);
+
+		start_bd->addr_hi = cpu_to_le32((u64) buf_map >> 32);
+		start_bd->addr_lo = cpu_to_le32(buf_map & 0xffffffff);
+		reg_bd->addr_hi = start_bd->addr_hi;
+		reg_bd->addr_lo = start_bd->addr_lo + 0x10;
+		start_bd->nbytes = cpu_to_le16(0x10);
+		start_bd->nbd = cpu_to_le16(3);
+		start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+		start_bd->general_data = (UNICAST_ADDRESS <<
+			ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT);
+		start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT);
+
+	}
+	context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr);
+
+	val = (u64) cp->l2_ring_map >> 32;
+	txbd->next_bd.addr_hi = cpu_to_le32(val);
+
+	context->xstorm_st_context.tx_bd_page_base_hi = val;
+
+	val = (u64) cp->l2_ring_map & 0xffffffff;
+	txbd->next_bd.addr_lo = cpu_to_le32(val);
+
+	context->xstorm_st_context.tx_bd_page_base_lo = val;
+
+	context->cstorm_st_context.sb_index_number =
+		HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS;
+	context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID;
+
+	context->xstorm_st_context.statistics_data = (cli |
+				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+
+	context->xstorm_ag_context.cdu_reserved =
+		CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func),
+					CDU_REGION_NUMBER_XCM_AG,
+					ETH_CONNECTION_TYPE);
+
+	/* reset xstorm per client statistics */
+	val = BAR_XSTRORM_INTMEM +
+	      XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+	for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++)
+		CNIC_WR(dev, val + i * 4, 0);
+
+	cp->tx_cons_ptr =
+		&cp->bnx2x_def_status_blk->c_def_status_block.index_values[
+			HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS];
+}
+
+static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring +
+				BCM_PAGE_SIZE);
+	struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *)
+				(cp->l2_ring + (2 * BCM_PAGE_SIZE));
+	struct eth_context *context;
+	struct regpair context_addr;
+	int i;
+	int port = CNIC_PORT(cp);
+	int func = CNIC_FUNC(cp);
+	int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+	u32 val;
+	struct tstorm_eth_client_config tstorm_client = {0};
+
+	for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) {
+		dma_addr_t buf_map;
+		int n = (i % cp->l2_rx_ring_size) + 1;
+
+		buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size);
+		rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32);
+		rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff);
+	}
+	context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr);
+
+	val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32;
+	rxbd->addr_hi = cpu_to_le32(val);
+
+	context->ustorm_st_context.common.bd_page_base_hi = val;
+
+	val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff;
+	rxbd->addr_lo = cpu_to_le32(val);
+
+	context->ustorm_st_context.common.bd_page_base_lo = val;
+
+	context->ustorm_st_context.common.sb_index_numbers =
+						BNX2X_ISCSI_RX_SB_INDEX_NUM;
+	context->ustorm_st_context.common.clientId = cli;
+	context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID;
+	context->ustorm_st_context.common.flags =
+		USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS;
+	context->ustorm_st_context.common.statistics_counter_id = cli;
+	context->ustorm_st_context.common.mc_alignment_log_size = 0;
+	context->ustorm_st_context.common.bd_buff_size =
+						cp->l2_single_buf_size;
+
+	context->ustorm_ag_context.cdu_usage =
+		CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func),
+					CDU_REGION_NUMBER_UCM_AG,
+					ETH_CONNECTION_TYPE);
+
+	rxcqe += BNX2X_MAX_RCQ_DESC_CNT;
+	val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32;
+	rxcqe->addr_hi = cpu_to_le32(val);
+
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_CQE_PAGE_BASE_OFFSET(port, cli) + 4, val);
+
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val);
+
+	val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff;
+	rxcqe->addr_lo = cpu_to_le32(val);
+
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_CQE_PAGE_BASE_OFFSET(port, cli), val);
+
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_CQE_PAGE_NEXT_OFFSET(port, cli), val);
+
+	/* client tstorm info */
+	tstorm_client.mtu = cp->l2_single_buf_size - 14;
+	tstorm_client.config_flags =
+			(TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE |
+			TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE);
+	tstorm_client.statistics_counter_id = cli;
+
+	CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+		   TSTORM_CLIENT_CONFIG_OFFSET(port, cli),
+		   ((u32 *)&tstorm_client)[0]);
+	CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+		   TSTORM_CLIENT_CONFIG_OFFSET(port, cli) + 4,
+		   ((u32 *)&tstorm_client)[1]);
+
+	/* reset tstorm per client statistics */
+	val = BAR_TSTRORM_INTMEM +
+	      TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+	for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++)
+		CNIC_WR(dev, val + i * 4, 0);
+
+	/* reset ustorm per client statistics */
+	val = BAR_USTRORM_INTMEM +
+	      USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+	for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++)
+		CNIC_WR(dev, val + i * 4, 0);
+
+	cp->rx_cons_ptr =
+		&cp->bnx2x_def_status_blk->u_def_status_block.index_values[
+			HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS];
+}
+
+static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	u32 base, addr, val;
+	int port = CNIC_PORT(cp);
+
+	dev->max_iscsi_conn = 0;
+	base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR);
+	if (base < 0xa0000 || base >= 0xc0000)
+		return;
+
+	addr = BNX2X_SHMEM_ADDR(base,
+		dev_info.port_hw_config[port].iscsi_mac_upper);
+
+	val = CNIC_RD(dev, addr);
+
+	dev->mac_addr[0] = (u8) (val >> 8);
+	dev->mac_addr[1] = (u8) val;
+
+	addr = BNX2X_SHMEM_ADDR(base,
+		dev_info.port_hw_config[port].iscsi_mac_lower);
+
+	val = CNIC_RD(dev, addr);
+
+	dev->mac_addr[2] = (u8) (val >> 24);
+	dev->mac_addr[3] = (u8) (val >> 16);
+	dev->mac_addr[4] = (u8) (val >> 8);
+	dev->mac_addr[5] = (u8) val;
+
+	addr = BNX2X_SHMEM_ADDR(base, validity_map[port]);
+	val = CNIC_RD(dev, addr);
+
+	if (!(val & SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT)) {
+		u16 val16;
+
+		addr = BNX2X_SHMEM_ADDR(base,
+				drv_lic_key[port].max_iscsi_init_conn);
+		val16 = CNIC_RD16(dev, addr);
+
+		if (val16)
+			val16 ^= 0x1e1e;
+		dev->max_iscsi_conn = val16;
+	}
+	if (BNX2X_CHIP_IS_E1H(cp->chip_id)) {
+		int func = CNIC_FUNC(cp);
+
+		addr = BNX2X_SHMEM_ADDR(base,
+				mf_cfg.func_mf_config[func].e1hov_tag);
+		val = CNIC_RD(dev, addr);
+		val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
+		if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
+			addr = BNX2X_SHMEM_ADDR(base,
+				mf_cfg.func_mf_config[func].config);
+			val = CNIC_RD(dev, addr);
+			val &= FUNC_MF_CFG_PROTOCOL_MASK;
+			if (val != FUNC_MF_CFG_PROTOCOL_ISCSI)
+				dev->max_iscsi_conn = 0;
+		}
+	}
+}
+
+static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int func = CNIC_FUNC(cp), ret, i;
+	int port = CNIC_PORT(cp);
+	u16 eq_idx;
+	u8 sb_id = cp->status_blk_num;
+
+	ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ,
+			       BNX2X_ISCSI_START_CID);
+
+	if (ret)
+		return -ENOMEM;
+
+	cp->kcq_io_addr = BAR_CSTRORM_INTMEM +
+			  CSTORM_ISCSI_EQ_PROD_OFFSET(func, 0);
+	cp->kcq_prod_idx = 0;
+
+	cnic_get_bnx2x_iscsi_info(dev);
+
+	/* Only 1 EQ */
+	CNIC_WR16(dev, cp->kcq_io_addr, MAX_KCQ_IDX);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_CONS_OFFSET(func, 0), 0);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0),
+		cp->kcq_info.pg_map_arr[1] & 0xffffffff);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0) + 4,
+		(u64) cp->kcq_info.pg_map_arr[1] >> 32);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0),
+		cp->kcq_info.pg_map_arr[0] & 0xffffffff);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0) + 4,
+		(u64) cp->kcq_info.pg_map_arr[0] >> 32);
+	CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, 0), 1);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_SB_NUM_OFFSET(func, 0), cp->status_blk_num);
+	CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(func, 0),
+		HC_INDEX_C_ISCSI_EQ_CONS);
+
+	for (i = 0; i < cp->conn_buf_info.num_pages; i++) {
+		CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+			TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i),
+			cp->conn_buf_info.pgtbl[2 * i]);
+		CNIC_WR(dev, BAR_TSTRORM_INTMEM +
+			TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i) + 4,
+			cp->conn_buf_info.pgtbl[(2 * i) + 1]);
+	}
+
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func),
+		cp->gbl_buf_info.pg_map_arr[0] & 0xffffffff);
+	CNIC_WR(dev, BAR_USTRORM_INTMEM +
+		USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func) + 4,
+		(u64) cp->gbl_buf_info.pg_map_arr[0] >> 32);
+
+	cnic_setup_bnx2x_context(dev);
+
+	eq_idx = CNIC_RD16(dev, BAR_CSTRORM_INTMEM +
+			   CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) +
+			   offsetof(struct cstorm_status_block_c,
+				    index_values[HC_INDEX_C_ISCSI_EQ_CONS]));
+	if (eq_idx != 0) {
+		printk(KERN_ERR PFX "%s: EQ cons index %x != 0\n",
+		       dev->netdev->name, eq_idx);
+		return -EBUSY;
+	}
+	ret = cnic_init_bnx2x_irq(dev);
+	if (ret)
+		return ret;
+
+	cnic_init_bnx2x_tx_ring(dev);
+	cnic_init_bnx2x_rx_ring(dev);
+
+	return 0;
+}
+
+static void cnic_init_rings(struct cnic_dev *dev)
+{
+	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+		cnic_init_bnx2_tx_ring(dev);
+		cnic_init_bnx2_rx_ring(dev);
+	} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
+		struct cnic_local *cp = dev->cnic_priv;
+		u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+		union l5cm_specific_data l5_data;
+		struct ustorm_eth_rx_producers rx_prods = {0};
+		u32 off, i;
+
+		rx_prods.bd_prod = 0;
+		rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT;
+		barrier();
+
+		off = BAR_USTRORM_INTMEM +
+			USTORM_RX_PRODS_OFFSET(CNIC_PORT(cp), cli);
+
+		for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++)
+			CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]);
+
+		cnic_init_bnx2x_tx_ring(dev);
+		cnic_init_bnx2x_rx_ring(dev);
+
+		l5_data.phy_address.lo = cli;
+		l5_data.phy_address.hi = 0;
+		cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP,
+			BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
+		cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1);
+	}
+}
+
+static void cnic_shutdown_rings(struct cnic_dev *dev)
+{
+	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+		cnic_shutdown_bnx2_rx_ring(dev);
+	} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
+		struct cnic_local *cp = dev->cnic_priv;
+		u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp));
+		union l5cm_specific_data l5_data;
+
+		cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0);
+
+		l5_data.phy_address.lo = cli;
+		l5_data.phy_address.hi = 0;
+		cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_HALT,
+			BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data);
+		msleep(10);
+
+		memset(&l5_data, 0, sizeof(l5_data));
+		cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL,
+			BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE |
+			(1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data);
+		msleep(10);
+	}
+}
+
 static int cnic_register_netdev(struct cnic_dev *dev)
 {
 	struct cnic_local *cp = dev->cnic_priv;
@@ -2554,6 +4284,25 @@ static void cnic_stop_bnx2_hw(struct cni
 	cnic_free_resc(dev);
 }
 
+
+static void cnic_stop_bnx2x_hw(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	u8 sb_id = cp->status_blk_num;
+	int port = CNIC_PORT(cp);
+
+	cnic_free_irq(dev);
+	CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
+		  CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) +
+		  offsetof(struct cstorm_status_block_c,
+			   index_values[HC_INDEX_C_ISCSI_EQ_CONS]),
+		  0);
+	CNIC_WR(dev, BAR_CSTRORM_INTMEM +
+		CSTORM_ISCSI_EQ_CONS_OFFSET(cp->func, 0), 0);
+	CNIC_WR16(dev, cp->kcq_io_addr, 0);
+	cnic_free_resc(dev);
+}
+
 static void cnic_stop_hw(struct cnic_dev *dev)
 {
 	if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
@@ -2685,6 +4434,57 @@ cnic_err:
 	return NULL;
 }
 
+static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev)
+{
+	struct pci_dev *pdev;
+	struct cnic_dev *cdev;
+	struct cnic_local *cp;
+	struct cnic_eth_dev *ethdev = NULL;
+	struct cnic_eth_dev *(*probe)(struct net_device *) = NULL;
+
+	probe = symbol_get(bnx2x_cnic_probe);
+	if (probe) {
+		ethdev = (*probe)(dev);
+		symbol_put(bnx2x_cnic_probe);
+	}
+	if (!ethdev)
+		return NULL;
+
+	pdev = ethdev->pdev;
+	if (!pdev)
+		return NULL;
+
+	dev_hold(dev);
+	cdev = cnic_alloc_dev(dev, pdev);
+	if (cdev == NULL) {
+		dev_put(dev);
+		return NULL;
+	}
+
+	set_bit(CNIC_F_BNX2X_CLASS, &cdev->flags);
+	cdev->submit_kwqes = cnic_submit_bnx2x_kwqes;
+
+	cp = cdev->cnic_priv;
+	cp->ethdev = ethdev;
+	cdev->pcidev = pdev;
+
+	cp->cnic_ops = &cnic_bnx2x_ops;
+	cp->start_hw = cnic_start_bnx2x_hw;
+	cp->stop_hw = cnic_stop_bnx2x_hw;
+	cp->setup_pgtbl = cnic_setup_page_tbl_le;
+	cp->alloc_resc = cnic_alloc_bnx2x_resc;
+	cp->free_resc = cnic_free_resc;
+	cp->start_cm = cnic_cm_init_bnx2x_hw;
+	cp->stop_cm = cnic_cm_stop_bnx2x_hw;
+	cp->enable_int = cnic_enable_bnx2x_int;
+	cp->disable_int_sync = cnic_disable_bnx2x_int_sync;
+	cp->ack_int = cnic_ack_bnx2x_msix;
+	cp->close_conn = cnic_close_bnx2x_conn;
+	cp->next_idx = cnic_bnx2x_next_idx;
+	cp->hw_idx = cnic_bnx2x_hw_idx;
+	return cdev;
+}
+
 static struct cnic_dev *is_cnic_dev(struct net_device *dev)
 {
 	struct ethtool_drvinfo drvinfo;
@@ -2696,6 +4496,8 @@ static struct cnic_dev *is_cnic_dev(stru
 
 		if (!strcmp(drvinfo.driver, "bnx2"))
 			cdev = init_bnx2_cnic(dev);
+		if (!strcmp(drvinfo.driver, "bnx2x"))
+			cdev = init_bnx2x_cnic(dev);
 		if (cdev) {
 			write_lock(&cnic_dev_lock);
 			list_add(&cdev->list, &cnic_dev_list);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cnic_defs.h linux-libre-2.6.33-gnu1/drivers/net/cnic_defs.h
--- linux-libre-2.6.32-gnu1/drivers/net/cnic_defs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cnic_defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,9 @@
 #define L4_KCQE_COMPLETION_STATUS_SUCCESS		    (0)
 #define L4_KCQE_COMPLETION_STATUS_TIMEOUT        (0x93)
 
+#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83)
+#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG   (0x89)
+
 #define L4_LAYER_CODE (4)
 #define L2_LAYER_CODE (2)
 
@@ -577,4 +580,1918 @@ struct l4_kwq_upload {
 	u32 reserved2[6];
 };
 
+/*
+ * bnx2x structures
+ */
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct ustorm_iscsi_rq_db {
+	struct regpair pbl_base;
+	struct regpair curr_pbe;
+};
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct ustorm_iscsi_r2tq_db {
+	struct regpair pbl_base;
+	struct regpair curr_pbe;
+};
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct ustorm_iscsi_cq_db {
+#if defined(__BIG_ENDIAN)
+	u16 cq_sn;
+	u16 prod;
+#elif defined(__LITTLE_ENDIAN)
+	u16 prod;
+	u16 cq_sn;
+#endif
+	struct regpair curr_pbe;
+};
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct rings_db {
+	struct ustorm_iscsi_rq_db rq;
+	struct ustorm_iscsi_r2tq_db r2tq;
+	struct ustorm_iscsi_cq_db cq[8];
+#if defined(__BIG_ENDIAN)
+	u16 rq_prod;
+	u16 r2tq_prod;
+#elif defined(__LITTLE_ENDIAN)
+	u16 r2tq_prod;
+	u16 rq_prod;
+#endif
+	struct regpair cq_pbl_base;
+};
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct ustorm_iscsi_placement_db {
+	u32 sgl_base_lo;
+	u32 sgl_base_hi;
+	u32 local_sge_0_address_hi;
+	u32 local_sge_0_address_lo;
+#if defined(__BIG_ENDIAN)
+	u16 curr_sge_offset;
+	u16 local_sge_0_size;
+#elif defined(__LITTLE_ENDIAN)
+	u16 local_sge_0_size;
+	u16 curr_sge_offset;
+#endif
+	u32 local_sge_1_address_hi;
+	u32 local_sge_1_address_lo;
+#if defined(__BIG_ENDIAN)
+	u16 reserved6;
+	u16 local_sge_1_size;
+#elif defined(__LITTLE_ENDIAN)
+	u16 local_sge_1_size;
+	u16 reserved6;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 sgl_size;
+	u8 local_sge_index_2b;
+	u16 reserved7;
+#elif defined(__LITTLE_ENDIAN)
+	u16 reserved7;
+	u8 local_sge_index_2b;
+	u8 sgl_size;
+#endif
+	u32 rem_pdu;
+	u32 place_db_bitfield_1;
+#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD (0xFFFFFF<<0)
+#define USTORM_ISCSI_PLACEMENT_DB_REM_PDU_PAYLOAD_SHIFT 0
+#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID (0xFF<<24)
+#define USTORM_ISCSI_PLACEMENT_DB_CQ_ID_SHIFT 24
+	u32 place_db_bitfield_2;
+#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE (0xFFFFFF<<0)
+#define USTORM_ISCSI_PLACEMENT_DB_BYTES_2_TRUNCATE_SHIFT 0
+#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX (0xFF<<24)
+#define USTORM_ISCSI_PLACEMENT_DB_HOST_SGE_INDEX_SHIFT 24
+	u32 nal;
+#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE (0xFFFFFF<<0)
+#define USTORM_ISCSI_PLACEMENT_DB_REM_SGE_SIZE_SHIFT 0
+#define USTORM_ISCSI_PLACEMENT_DB_EXP_PADDING_2B (0x3<<24)
+#define USTORM_ISCSI_PLACEMENT_DB_EXP_PADDING_2B_SHIFT 24
+#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B (0x7<<26)
+#define USTORM_ISCSI_PLACEMENT_DB_EXP_DIGEST_3B_SHIFT 26
+#define USTORM_ISCSI_PLACEMENT_DB_NAL_LEN_3B (0x7<<29)
+#define USTORM_ISCSI_PLACEMENT_DB_NAL_LEN_3B_SHIFT 29
+};
+
+/*
+ * Ustorm iSCSI Storm Context
+ */
+struct ustorm_iscsi_st_context {
+	u32 exp_stat_sn;
+	u32 exp_data_sn;
+	struct rings_db ring;
+	struct regpair task_pbl_base;
+	struct regpair tce_phy_addr;
+	struct ustorm_iscsi_placement_db place_db;
+	u32 data_rcv_seq;
+	u32 rem_rcv_len;
+#if defined(__BIG_ENDIAN)
+	u16 hdr_itt;
+	u16 iscsi_conn_id;
+#elif defined(__LITTLE_ENDIAN)
+	u16 iscsi_conn_id;
+	u16 hdr_itt;
+#endif
+	u32 nal_bytes;
+#if defined(__BIG_ENDIAN)
+	u8 hdr_second_byte_union;
+	u8 bitfield_0;
+#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0)
+#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0
+#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1)
+#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2)
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2
+	u8 task_pdu_cache_index;
+	u8 task_pbe_cache_index;
+#elif defined(__LITTLE_ENDIAN)
+	u8 task_pbe_cache_index;
+	u8 task_pdu_cache_index;
+	u8 bitfield_0;
+#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU (0x1<<0)
+#define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0
+#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1)
+#define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2)
+#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2
+	u8 hdr_second_byte_union;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 reserved3;
+	u8 reserved2;
+	u8 acDecrement;
+#elif defined(__LITTLE_ENDIAN)
+	u8 acDecrement;
+	u8 reserved2;
+	u16 reserved3;
+#endif
+	u32 task_stat;
+#if defined(__BIG_ENDIAN)
+	u8 hdr_opcode;
+	u8 num_cqs;
+	u16 reserved5;
+#elif defined(__LITTLE_ENDIAN)
+	u16 reserved5;
+	u8 num_cqs;
+	u8 hdr_opcode;
+#endif
+	u32 negotiated_rx;
+#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH (0xFFFFFF<<0)
+#define USTORM_ISCSI_ST_CONTEXT_MAX_RECV_PDU_LENGTH_SHIFT 0
+#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS (0xFF<<24)
+#define USTORM_ISCSI_ST_CONTEXT_MAX_OUTSTANDING_R2TS_SHIFT 24
+	u32 negotiated_rx_and_flags;
+#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH (0xFFFFFF<<0)
+#define USTORM_ISCSI_ST_CONTEXT_MAX_BURST_LENGTH_SHIFT 0
+#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED (0x1<<24)
+#define USTORM_ISCSI_ST_CONTEXT_B_CQE_POSTED_OR_HEADER_CACHED_SHIFT 24
+#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN (0x1<<25)
+#define USTORM_ISCSI_ST_CONTEXT_B_HDR_DIGEST_EN_SHIFT 25
+#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN (0x1<<26)
+#define USTORM_ISCSI_ST_CONTEXT_B_DATA_DIGEST_EN_SHIFT 26
+#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR (0x1<<27)
+#define USTORM_ISCSI_ST_CONTEXT_B_PROTOCOL_ERROR_SHIFT 27
+#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID (0x1<<28)
+#define USTORM_ISCSI_ST_CONTEXT_B_TASK_VALID_SHIFT 28
+#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE (0x3<<29)
+#define USTORM_ISCSI_ST_CONTEXT_TASK_TYPE_SHIFT 29
+#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED (0x1<<31)
+#define USTORM_ISCSI_ST_CONTEXT_B_ALL_DATA_ACKED_SHIFT 31
+};
+
+/*
+ * TCP context region, shared in TOE, RDMA and ISCSI
+ */
+struct tstorm_tcp_st_context_section {
+	u32 flags1;
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B (0xFFFFFF<<0)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B_SHIFT 0
+#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24
+#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25
+#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS (0x1<<26)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS_SHIFT 26
+#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27
+#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED_SHIFT 28
+#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE (0x1<<29)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29
+#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3 (0x1<<31)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3_SHIFT 31
+	u32 flags2;
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B (0xFFFFFF<<0)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B_SHIFT 0
+#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24
+#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN_SHIFT 25
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT (0x1<<26)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_KA_PROBE_SENT_SHIFT 26
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT (0x1<<27)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_PERSIST_PROBE_SENT_SHIFT 27
+#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<28)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28
+#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29)
+#define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED (0x1<<30)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED_SHIFT 30
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO (0x1<<31)
+#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO_SHIFT 31
+#if defined(__BIG_ENDIAN)
+	u16 reserved_slowpath;
+	u8 tcp_sm_state_3b;
+	u8 rto_exp_3b;
+#elif defined(__LITTLE_ENDIAN)
+	u8 rto_exp_3b;
+	u8 tcp_sm_state_3b;
+	u16 reserved_slowpath;
+#endif
+	u32 rcv_nxt;
+	u32 timestamp_recent;
+	u32 timestamp_recent_time;
+	u32 cwnd;
+	u32 ss_thresh;
+	u32 cwnd_accum;
+	u32 prev_seg_seq;
+	u32 expected_rel_seq;
+	u32 recover;
+#if defined(__BIG_ENDIAN)
+	u8 retransmit_count;
+	u8 ka_max_probe_count;
+	u8 persist_probe_count;
+	u8 ka_probe_count;
+#elif defined(__LITTLE_ENDIAN)
+	u8 ka_probe_count;
+	u8 persist_probe_count;
+	u8 ka_max_probe_count;
+	u8 retransmit_count;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 statistics_counter_id;
+	u8 ooo_support_mode;
+	u8 snd_wnd_scale_4b;
+	u8 dup_ack_count;
+#elif defined(__LITTLE_ENDIAN)
+	u8 dup_ack_count;
+	u8 snd_wnd_scale_4b;
+	u8 ooo_support_mode;
+	u8 statistics_counter_id;
+#endif
+	u32 retransmit_start_time;
+	u32 ka_timeout;
+	u32 ka_interval;
+	u32 isle_start_seq;
+	u32 isle_end_seq;
+#if defined(__BIG_ENDIAN)
+	u16 mss;
+	u16 recent_seg_wnd;
+#elif defined(__LITTLE_ENDIAN)
+	u16 recent_seg_wnd;
+	u16 mss;
+#endif
+	u32 reserved4;
+	u32 max_rt_time;
+#if defined(__BIG_ENDIAN)
+	u16 lsb_mac_address;
+	u16 vlan_id;
+#elif defined(__LITTLE_ENDIAN)
+	u16 vlan_id;
+	u16 lsb_mac_address;
+#endif
+	u32 msb_mac_address;
+	u32 reserved2;
+};
+
+/*
+ * Termination variables
+ */
+struct iscsi_term_vars {
+	u8 BitMap;
+#define ISCSI_TERM_VARS_TCP_STATE (0xF<<0)
+#define ISCSI_TERM_VARS_TCP_STATE_SHIFT 0
+#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT (0x1<<4)
+#define ISCSI_TERM_VARS_FIN_RECEIVED_SBIT_SHIFT 4
+#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT (0x1<<5)
+#define ISCSI_TERM_VARS_ACK_ON_FIN_RECEIVED_SBIT_SHIFT 5
+#define ISCSI_TERM_VARS_TERM_ON_CHIP (0x1<<6)
+#define ISCSI_TERM_VARS_TERM_ON_CHIP_SHIFT 6
+#define ISCSI_TERM_VARS_RSRV (0x1<<7)
+#define ISCSI_TERM_VARS_RSRV_SHIFT 7
+};
+
+/*
+ * iSCSI context region, used only in iSCSI
+ */
+struct tstorm_iscsi_st_context_section {
+#if defined(__BIG_ENDIAN)
+	u16 rem_tcp_data_len;
+	u16 brb_offset;
+#elif defined(__LITTLE_ENDIAN)
+	u16 brb_offset;
+	u16 rem_tcp_data_len;
+#endif
+	u32 b2nh;
+#if defined(__BIG_ENDIAN)
+	u16 rq_cons;
+	u8 flags;
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV (0x7<<5)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV_SHIFT 5
+	u8 hdr_bytes_2_fetch;
+#elif defined(__LITTLE_ENDIAN)
+	u8 hdr_bytes_2_fetch;
+	u8 flags;
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN (0x1<<0)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_HDR_DIGEST_EN_SHIFT 0
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN (0x1<<1)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DATA_DIGEST_EN_SHIFT 1
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER (0x1<<2)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_PARTIAL_HEADER_SHIFT 2
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE (0x1<<3)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_FULL_FEATURE_SHIFT 3
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS (0x1<<4)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_B_DROP_ALL_PDUS_SHIFT 4
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV (0x7<<5)
+#define TSTORM_ISCSI_ST_CONTEXT_SECTION_FLAGS_RSRV_SHIFT 5
+	u16 rq_cons;
+#endif
+	struct regpair rq_db_phy_addr;
+#if defined(__BIG_ENDIAN)
+	struct iscsi_term_vars term_vars;
+	u8 scratchpad_idx;
+	u16 iscsi_conn_id;
+#elif defined(__LITTLE_ENDIAN)
+	u16 iscsi_conn_id;
+	u8 scratchpad_idx;
+	struct iscsi_term_vars term_vars;
+#endif
+	u32 reserved2;
+};
+
+/*
+ * The iSCSI non-aggregative context of Tstorm
+ */
+struct tstorm_iscsi_st_context {
+	struct tstorm_tcp_st_context_section tcp;
+	struct tstorm_iscsi_st_context_section iscsi;
+};
+
+/*
+ * The tcp aggregative context section of Xstorm
+ */
+struct xstorm_tcp_tcp_ag_context_section {
+#if defined(__BIG_ENDIAN)
+	u8 __tcp_agg_vars1;
+	u8 __da_cnt;
+	u16 mss;
+#elif defined(__LITTLE_ENDIAN)
+	u16 mss;
+	u8 __da_cnt;
+	u8 __tcp_agg_vars1;
+#endif
+	u32 snd_nxt;
+	u32 tx_wnd;
+	u32 snd_una;
+	u32 local_adv_wnd;
+#if defined(__BIG_ENDIAN)
+	u8 __agg_val8_th;
+	u8 __agg_val8;
+	u16 tcp_agg_vars2;
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0)
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5)
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN (0x1<<7)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN_SHIFT 7
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14
+#elif defined(__LITTLE_ENDIAN)
+	u16 tcp_agg_vars2;
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG (0x1<<0)
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_SHIFT 0
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED (0x1<<1)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_UNBLOCKED_SHIFT 1
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE (0x1<<2)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_TIMER_ACTIVE_SHIFT 2
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG (0x1<<3)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_FLAG_SHIFT 3
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG (0x1<<4)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX4_FLAG_SHIFT 4
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE (0x1<<5)
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DA_ENABLE_SHIFT 5
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN (0x1<<6)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ACK_TO_FE_UPDATED_EN_SHIFT 6
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN (0x1<<7)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX3_CF_EN_SHIFT 7
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN (0x1<<8)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_FIN_FLAG_EN_SHIFT 8
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<9)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 9
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF (0x3<<10)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_SET_RTO_CF_SHIFT 10
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF (0x3<<12)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_UPDATED_CF_SHIFT 12
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF (0x3<<14)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_SHIFT 14
+	u8 __agg_val8;
+	u8 __agg_val8_th;
+#endif
+	u32 ack_to_far_end;
+	u32 rto_timer;
+	u32 ka_timer;
+	u32 ts_to_echo;
+#if defined(__BIG_ENDIAN)
+	u16 __agg_val7_th;
+	u16 __agg_val7;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __agg_val7;
+	u16 __agg_val7_th;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 __tcp_agg_vars5;
+	u8 __tcp_agg_vars4;
+	u8 __tcp_agg_vars3;
+	u8 __force_pure_ack_cnt;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __force_pure_ack_cnt;
+	u8 __tcp_agg_vars3;
+	u8 __tcp_agg_vars4;
+	u8 __tcp_agg_vars5;
+#endif
+	u32 tcp_agg_vars6;
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN (0x1<<0)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TS_TO_ECHO_CF_EN_SHIFT 0
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_EN (0x1<<1)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX8_CF_EN_SHIFT 1
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN (0x1<<2)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_EN_SHIFT 2
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<3)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 3
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG (0x1<<4)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX6_FLAG_SHIFT 4
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG (0x1<<5)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX7_FLAG_SHIFT 5
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF (0x3<<6)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX5_CF_SHIFT 6
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF (0x3<<8)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX9_CF_SHIFT 8
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF (0x3<<10)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_SHIFT 10
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF (0x3<<12)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_SHIFT 12
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF (0x3<<14)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_SHIFT 14
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF (0x3<<16)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX13_CF_SHIFT 16
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF (0x3<<18)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX14_CF_SHIFT 18
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF (0x3<<20)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX15_CF_SHIFT 20
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF (0x3<<22)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX16_CF_SHIFT 22
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF (0x3<<24)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX17_CF_SHIFT 24
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG (0x1<<26)
+#define XSTORM_TCP_TCP_AG_CONTEXT_SECTION_ECE_FLAG_SHIFT 26
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71 (0x1<<27)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED71_SHIFT 27
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY (0x1<<28)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_FORCE_PURE_ACK_CNT_DIRTY_SHIFT 28
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG (0x1<<29)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_TCP_AUTO_STOP_FLAG_SHIFT 29
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG (0x1<<30)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_DO_TS_UPDATE_FLAG_SHIFT 30
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG (0x1<<31)
+#define __XSTORM_TCP_TCP_AG_CONTEXT_SECTION_CANCEL_RETRANSMIT_FLAG_SHIFT 31
+#if defined(__BIG_ENDIAN)
+	u16 __agg_misc6;
+	u16 __tcp_agg_vars7;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __tcp_agg_vars7;
+	u16 __agg_misc6;
+#endif
+	u32 __agg_val10;
+	u32 __agg_val10_th;
+#if defined(__BIG_ENDIAN)
+	u16 __reserved3;
+	u8 __reserved2;
+	u8 __da_only_cnt;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __da_only_cnt;
+	u8 __reserved2;
+	u16 __reserved3;
+#endif
+};
+
+/*
+ * The iscsi aggregative context of Xstorm
+ */
+struct xstorm_iscsi_ag_context {
+#if defined(__BIG_ENDIAN)
+	u16 agg_val1;
+	u8 agg_vars1;
+#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5)
+#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6
+#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7
+	u8 state;
+#elif defined(__LITTLE_ENDIAN)
+	u8 state;
+	u8 agg_vars1;
+#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define XSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_MORE_TO_SEND_EN_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN (0x1<<5)
+#define XSTORM_ISCSI_AG_CONTEXT_NAGLE_EN_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG (0x1<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_SHIFT 6
+#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_UNA_GT_NXT_EN_SHIFT 7
+	u16 agg_val1;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 cdu_reserved;
+	u8 agg_vars4;
+#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7
+	u8 agg_vars3;
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6
+	u8 agg_vars2;
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+#elif defined(__LITTLE_ENDIAN)
+	u8 agg_vars2;
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN (0x1<<2)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_SPARE_FLAG_EN_SHIFT 2
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG (0x1<<3)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX8_FLAG_SHIFT 3
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX9_FLAG_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1 (0x3<<5)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE1_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+	u8 agg_vars3;
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6
+	u8 agg_vars4;
+#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5
+#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6)
+#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7
+	u8 cdu_reserved;
+#endif
+	u32 more_to_send;
+#if defined(__BIG_ENDIAN)
+	u16 agg_vars5;
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14
+	u16 sq_cons;
+#elif defined(__LITTLE_ENDIAN)
+	u16 sq_cons;
+	u16 agg_vars5;
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5 (0x3<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE5_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0 (0x3F<<2)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM0_SHIFT 2
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1 (0x3F<<8)
+#define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM1_SHIFT 8
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2 (0x3<<14)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE2_SHIFT 14
+#endif
+	struct xstorm_tcp_tcp_ag_context_section tcp;
+#if defined(__BIG_ENDIAN)
+	u16 agg_vars7;
+#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3
+#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4)
+#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6
+#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8)
+#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8
+#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10)
+#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+	u8 agg_val3_th;
+	u8 agg_vars6;
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6
+#elif defined(__LITTLE_ENDIAN)
+	u8 agg_vars6;
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7 (0x7<<3)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE7_SHIFT 3
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4 (0x3<<6)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE4_SHIFT 6
+	u8 agg_val3_th;
+	u16 agg_vars7;
+#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE (0x7<<0)
+#define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3
+#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4)
+#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6)
+#define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6
+#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8)
+#define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_SHIFT 8
+#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK (0x1<<10)
+#define __XSTORM_ISCSI_AG_CONTEXT_COMPLETION_SEQ_DECISION_MASK_SHIFT 10
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN (0x1<<11)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX1_CF_EN_SHIFT 11
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG (0x1<<12)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX10_FLAG_SHIFT 12
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG (0x1<<13)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15)
+#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __agg_val11_th;
+	u16 __agg_val11;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __agg_val11;
+	u16 __agg_val11_th;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 __reserved1;
+	u8 __agg_val6_th;
+	u16 __agg_val9;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __agg_val9;
+	u8 __agg_val6_th;
+	u8 __reserved1;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 hq_prod;
+	u16 hq_cons;
+#elif defined(__LITTLE_ENDIAN)
+	u16 hq_cons;
+	u16 hq_prod;
+#endif
+	u32 agg_vars8;
+#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2 (0xFFFFFF<<0)
+#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC2_SHIFT 0
+#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3 (0xFF<<24)
+#define XSTORM_ISCSI_AG_CONTEXT_AGG_MISC3_SHIFT 24
+#if defined(__BIG_ENDIAN)
+	u16 r2tq_prod;
+	u16 sq_prod;
+#elif defined(__LITTLE_ENDIAN)
+	u16 sq_prod;
+	u16 r2tq_prod;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 agg_val3;
+	u8 agg_val6;
+	u8 agg_val5_th;
+	u8 agg_val5;
+#elif defined(__LITTLE_ENDIAN)
+	u8 agg_val5;
+	u8 agg_val5_th;
+	u8 agg_val6;
+	u8 agg_val3;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __agg_misc1;
+	u16 agg_limit1;
+#elif defined(__LITTLE_ENDIAN)
+	u16 agg_limit1;
+	u16 __agg_misc1;
+#endif
+	u32 hq_cons_tcp_seq;
+	u32 exp_stat_sn;
+	u32 agg_misc5;
+};
+
+/*
+ * The tcp aggregative context section of Tstorm
+ */
+struct tstorm_tcp_tcp_ag_context_section {
+	u32 __agg_val1;
+#if defined(__BIG_ENDIAN)
+	u8 __tcp_agg_vars2;
+	u8 __agg_val3;
+	u16 __agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __agg_val2;
+	u8 __agg_val3;
+	u8 __tcp_agg_vars2;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __agg_val5;
+	u8 __agg_val6;
+	u8 __tcp_agg_vars3;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __tcp_agg_vars3;
+	u8 __agg_val6;
+	u16 __agg_val5;
+#endif
+	u32 snd_nxt;
+	u32 rtt_seq;
+	u32 rtt_time;
+	u32 __reserved66;
+	u32 wnd_right_edge;
+	u32 tcp_agg_vars1;
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<0)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 0
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG (0x1<<1)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_LAST_PACKET_FIN_FLAG_SHIFT 1
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF (0x3<<2)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_SHIFT 2
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF (0x3<<4)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_SHIFT 4
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN (0x1<<6)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_WND_UPD_CF_EN_SHIFT 6
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN (0x1<<7)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TIMEOUT_CF_EN_SHIFT 7
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN (0x1<<8)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_SEQ_EN_SHIFT 8
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN (0x1<<9)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_SND_NXT_EN_SHIFT 9
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG (0x1<<10)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_FLAG_SHIFT 10
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG (0x1<<11)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_FLAG_SHIFT 11
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN (0x1<<12)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_EN_SHIFT 12
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN (0x1<<13)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_EN_SHIFT 13
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF (0x3<<14)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX1_CF_SHIFT 14
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF (0x3<<16)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX2_CF_SHIFT 16
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED (0x1<<18)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_TX_BLOCKED_SHIFT 18
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN (0x1<<19)
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX10_CF_EN_SHIFT 19
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN (0x1<<20)
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX11_CF_EN_SHIFT 20
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN (0x1<<21)
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_AUX12_CF_EN_SHIFT 21
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1 (0x3<<22)
+#define __TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RESERVED1_SHIFT 22
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ (0xF<<24)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_PEND_SEQ_SHIFT 24
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ (0xF<<28)
+#define TSTORM_TCP_TCP_AG_CONTEXT_SECTION_RETRANSMIT_DONE_SEQ_SHIFT 28
+	u32 snd_max;
+	u32 snd_una;
+	u32 __reserved2;
+};
+
+/*
+ * The iscsi aggregative context of Tstorm
+ */
+struct tstorm_iscsi_ag_context {
+#if defined(__BIG_ENDIAN)
+	u16 ulp_credit;
+	u8 agg_vars1;
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+	u8 state;
+#elif defined(__LITTLE_ENDIAN)
+	u8 state;
+	u8 agg_vars1;
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7
+	u16 ulp_credit;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __agg_val4;
+	u16 agg_vars2;
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10
+#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11
+#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
+#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
+#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15
+#elif defined(__LITTLE_ENDIAN)
+	u16 agg_vars2;
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10)
+#define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10
+#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11
+#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12
+#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13
+#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14
+#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15)
+#define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15
+	u16 __agg_val4;
+#endif
+	struct tstorm_tcp_tcp_ag_context_section tcp;
+};
+
+/*
+ * The iscsi aggregative context of Cstorm
+ */
+struct cstorm_iscsi_ag_context {
+	u32 agg_vars1;
+#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0)
+#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11)
+#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16
+#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18)
+#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22)
+#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22
+#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23)
+#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23
+#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26)
+#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30)
+#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30
+#if defined(__BIG_ENDIAN)
+	u8 __aux1_th;
+	u8 __aux1_val;
+	u16 __agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __agg_vars2;
+	u8 __aux1_val;
+	u8 __aux1_th;
+#endif
+	u32 rel_seq;
+	u32 rel_seq_th;
+#if defined(__BIG_ENDIAN)
+	u16 hq_cons;
+	u16 hq_prod;
+#elif defined(__LITTLE_ENDIAN)
+	u16 hq_prod;
+	u16 hq_cons;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 __reserved62;
+	u8 __reserved61;
+	u8 __reserved60;
+	u8 __reserved59;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __reserved59;
+	u8 __reserved60;
+	u8 __reserved61;
+	u8 __reserved62;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __reserved64;
+	u16 __cq_u_prod0;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __cq_u_prod0;
+	u16 __reserved64;
+#endif
+	u32 __cq_u_prod1;
+#if defined(__BIG_ENDIAN)
+	u16 __agg_vars3;
+	u16 __cq_u_prod2;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __cq_u_prod2;
+	u16 __agg_vars3;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __aux2_th;
+	u16 __cq_u_prod3;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __cq_u_prod3;
+	u16 __aux2_th;
+#endif
+};
+
+/*
+ * The iscsi aggregative context of Ustorm
+ */
+struct ustorm_iscsi_ag_context {
+#if defined(__BIG_ENDIAN)
+	u8 __aux_counter_flags;
+	u8 agg_vars2;
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0)
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2)
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2
+#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7
+	u8 agg_vars1;
+#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4)
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6)
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6
+	u8 state;
+#elif defined(__LITTLE_ENDIAN)
+	u8 state;
+	u8 agg_vars1;
+#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<0)
+#define __USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 0
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<1)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 1
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<2)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3)
+#define USTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF (0x3<<4)
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_SHIFT 4
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF (0x3<<6)
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_SHIFT 6
+	u8 agg_vars2;
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF (0x3<<0)
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_SHIFT 0
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF (0x3<<2)
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_SHIFT 2
+#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE (0x7<<4)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_MISC4_RULE_SHIFT 4
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_MASK_SHIFT 7
+	u8 __aux_counter_flags;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 cdu_usage;
+	u8 agg_misc2;
+	u16 __cq_local_comp_itt_val;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __cq_local_comp_itt_val;
+	u8 agg_misc2;
+	u8 cdu_usage;
+#endif
+	u32 agg_misc4;
+#if defined(__BIG_ENDIAN)
+	u8 agg_val3_th;
+	u8 agg_val3;
+	u16 agg_misc3;
+#elif defined(__LITTLE_ENDIAN)
+	u16 agg_misc3;
+	u8 agg_val3;
+	u8 agg_val3_th;
+#endif
+	u32 agg_val1;
+	u32 agg_misc4_th;
+#if defined(__BIG_ENDIAN)
+	u16 agg_val2_th;
+	u16 agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+	u16 agg_val2;
+	u16 agg_val2_th;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __reserved2;
+	u8 decision_rules;
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
+#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7
+	u8 decision_rule_enable_bits;
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0)
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1)
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2)
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3)
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3
+#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4)
+#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4
+#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5)
+#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5
+#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6)
+#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6
+#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+#elif defined(__LITTLE_ENDIAN)
+	u8 decision_rule_enable_bits;
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN (0x1<<0)
+#define USTORM_ISCSI_AG_CONTEXT_INV_CF_EN_SHIFT 0
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN (0x1<<1)
+#define USTORM_ISCSI_AG_CONTEXT_COMPLETION_CF_EN_SHIFT 1
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN (0x1<<2)
+#define USTORM_ISCSI_AG_CONTEXT_TX_CF_EN_SHIFT 2
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN (0x1<<3)
+#define __USTORM_ISCSI_AG_CONTEXT_TIMER_CF_EN_SHIFT 3
+#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN (0x1<<4)
+#define __USTORM_ISCSI_AG_CONTEXT_CQ_LOCAL_COMP_CF_EN_SHIFT 4
+#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<5)
+#define __USTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 5
+#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<6)
+#define __USTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 6
+#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_DQ_CF_EN_SHIFT 7
+	u8 decision_rules;
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE (0x7<<0)
+#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6)
+#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6
+#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7)
+#define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7
+	u16 __reserved2;
+#endif
+};
+
+/*
+ * Timers connection context
+ */
+struct iscsi_timers_block_context {
+	u32 __reserved_0;
+	u32 __reserved_1;
+	u32 __reserved_2;
+	u32 flags;
+#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0)
+#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0
+#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2)
+#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2
+#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3)
+#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3
+};
+
+/*
+ * Ethernet context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_eth_context_section {
+#if defined(__BIG_ENDIAN)
+	u8 remote_addr_4;
+	u8 remote_addr_5;
+	u8 local_addr_0;
+	u8 local_addr_1;
+#elif defined(__LITTLE_ENDIAN)
+	u8 local_addr_1;
+	u8 local_addr_0;
+	u8 remote_addr_5;
+	u8 remote_addr_4;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 remote_addr_0;
+	u8 remote_addr_1;
+	u8 remote_addr_2;
+	u8 remote_addr_3;
+#elif defined(__LITTLE_ENDIAN)
+	u8 remote_addr_3;
+	u8 remote_addr_2;
+	u8 remote_addr_1;
+	u8 remote_addr_0;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 reserved_vlan_type;
+	u16 params;
+#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
+#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
+#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12)
+#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12
+#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13)
+#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13
+#elif defined(__LITTLE_ENDIAN)
+	u16 params;
+#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
+#define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
+#define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12)
+#define XSTORM_ETH_CONTEXT_SECTION_CFI_SHIFT 12
+#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13)
+#define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13
+	u16 reserved_vlan_type;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 local_addr_2;
+	u8 local_addr_3;
+	u8 local_addr_4;
+	u8 local_addr_5;
+#elif defined(__LITTLE_ENDIAN)
+	u8 local_addr_5;
+	u8 local_addr_4;
+	u8 local_addr_3;
+	u8 local_addr_2;
+#endif
+};
+
+/*
+ * IpV4 context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_ip_v4_context_section {
+#if defined(__BIG_ENDIAN)
+	u16 __pbf_hdr_cmd_rsvd_id;
+	u16 __pbf_hdr_cmd_rsvd_flags_offset;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __pbf_hdr_cmd_rsvd_flags_offset;
+	u16 __pbf_hdr_cmd_rsvd_id;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 __pbf_hdr_cmd_rsvd_ver_ihl;
+	u8 tos;
+	u16 __pbf_hdr_cmd_rsvd_length;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __pbf_hdr_cmd_rsvd_length;
+	u8 tos;
+	u8 __pbf_hdr_cmd_rsvd_ver_ihl;
+#endif
+	u32 ip_local_addr;
+#if defined(__BIG_ENDIAN)
+	u8 ttl;
+	u8 __pbf_hdr_cmd_rsvd_protocol;
+	u16 __pbf_hdr_cmd_rsvd_csum;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __pbf_hdr_cmd_rsvd_csum;
+	u8 __pbf_hdr_cmd_rsvd_protocol;
+	u8 ttl;
+#endif
+	u32 __pbf_hdr_cmd_rsvd_1;
+	u32 ip_remote_addr;
+};
+
+/*
+ * context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_padded_ip_v4_context_section {
+	struct xstorm_ip_v4_context_section ip_v4;
+	u32 reserved1[4];
+};
+
+/*
+ * IpV6 context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_ip_v6_context_section {
+#if defined(__BIG_ENDIAN)
+	u16 pbf_hdr_cmd_rsvd_payload_len;
+	u8 pbf_hdr_cmd_rsvd_nxt_hdr;
+	u8 hop_limit;
+#elif defined(__LITTLE_ENDIAN)
+	u8 hop_limit;
+	u8 pbf_hdr_cmd_rsvd_nxt_hdr;
+	u16 pbf_hdr_cmd_rsvd_payload_len;
+#endif
+	u32 priority_flow_label;
+#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL (0xFFFFF<<0)
+#define XSTORM_IP_V6_CONTEXT_SECTION_FLOW_LABEL_SHIFT 0
+#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS (0xFF<<20)
+#define XSTORM_IP_V6_CONTEXT_SECTION_TRAFFIC_CLASS_SHIFT 20
+#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER (0xF<<28)
+#define XSTORM_IP_V6_CONTEXT_SECTION_PBF_HDR_CMD_RSVD_VER_SHIFT 28
+	u32 ip_local_addr_lo_hi;
+	u32 ip_local_addr_lo_lo;
+	u32 ip_local_addr_hi_hi;
+	u32 ip_local_addr_hi_lo;
+	u32 ip_remote_addr_lo_hi;
+	u32 ip_remote_addr_lo_lo;
+	u32 ip_remote_addr_hi_hi;
+	u32 ip_remote_addr_hi_lo;
+};
+
+union xstorm_ip_context_section_types {
+	struct xstorm_padded_ip_v4_context_section padded_ip_v4;
+	struct xstorm_ip_v6_context_section ip_v6;
+};
+
+/*
+ * TCP context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_tcp_context_section {
+	u32 snd_max;
+#if defined(__BIG_ENDIAN)
+	u16 remote_port;
+	u16 local_port;
+#elif defined(__LITTLE_ENDIAN)
+	u16 local_port;
+	u16 remote_port;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 original_nagle_1b;
+	u8 ts_enabled_1b;
+	u16 tcp_params;
+#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0)
+#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0
+#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8)
+#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8
+#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9)
+#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9
+#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10)
+#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10
+#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11)
+#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11
+#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12)
+#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12
+#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13)
+#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13
+#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14)
+#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14
+#elif defined(__LITTLE_ENDIAN)
+	u16 tcp_params;
+#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0)
+#define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0
+#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT (0x1<<8)
+#define __XSTORM_TCP_CONTEXT_SECTION_ECT_BIT_SHIFT 8
+#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED (0x1<<9)
+#define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9
+#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10)
+#define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10
+#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11)
+#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11
+#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12)
+#define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12
+#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13)
+#define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13
+#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14)
+#define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14
+	u8 ts_enabled_1b;
+	u8 original_nagle_1b;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 pseudo_csum;
+	u16 window_scaling_factor;
+#elif defined(__LITTLE_ENDIAN)
+	u16 window_scaling_factor;
+	u16 pseudo_csum;
+#endif
+	u32 reserved2;
+	u32 ts_time_diff;
+	u32 __next_timer_expir;
+};
+
+/*
+ * Common context section, shared in TOE, RDMA and ISCSI
+ */
+struct xstorm_common_context_section {
+	struct xstorm_eth_context_section ethernet;
+	union xstorm_ip_context_section_types ip_union;
+	struct xstorm_tcp_context_section tcp;
+#if defined(__BIG_ENDIAN)
+	u16 reserved;
+	u8 statistics_params;
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0)
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1)
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1
+#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2)
+#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2
+#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7)
+#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7
+	u8 ip_version_1b;
+#elif defined(__LITTLE_ENDIAN)
+	u8 ip_version_1b;
+	u8 statistics_params;
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS (0x1<<0)
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 0
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<1)
+#define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1
+#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2)
+#define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2
+#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7)
+#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7
+	u16 reserved;
+#endif
+};
+
+/*
+ * Flags used in ISCSI context section
+ */
+struct xstorm_iscsi_context_flags {
+	u8 flags;
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA (0x1<<0)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_IMMEDIATE_DATA_SHIFT 0
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T (0x1<<1)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_INITIAL_R2T_SHIFT 1
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST (0x1<<2)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_HEADER_DIGEST_SHIFT 2
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST (0x1<<3)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_EN_DATA_DIGEST_SHIFT 3
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN (0x1<<4)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_HQ_BD_WRITTEN_SHIFT 4
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ (0x1<<5)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_LAST_OP_SQ_SHIFT 5
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT (0x1<<6)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_B_UPDATE_SND_NXT_SHIFT 6
+#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4 (0x1<<7)
+#define XSTORM_ISCSI_CONTEXT_FLAGS_RESERVED4_SHIFT 7
+};
+
+struct iscsi_task_context_entry_x {
+	u32 data_out_buffer_offset;
+	u32 itt;
+	u32 data_sn;
+};
+
+struct iscsi_task_context_entry_xuc_x_write_only {
+	u32 tx_r2t_sn;
+};
+
+struct iscsi_task_context_entry_xuc_xu_write_both {
+	u32 sgl_base_lo;
+	u32 sgl_base_hi;
+#if defined(__BIG_ENDIAN)
+	u8 sgl_size;
+	u8 sge_index;
+	u16 sge_offset;
+#elif defined(__LITTLE_ENDIAN)
+	u16 sge_offset;
+	u8 sge_index;
+	u8 sgl_size;
+#endif
+};
+
+/*
+ * iSCSI context section
+ */
+struct xstorm_iscsi_context_section {
+	u32 first_burst_length;
+	u32 max_send_pdu_length;
+	struct regpair sq_pbl_base;
+	struct regpair sq_curr_pbe;
+	struct regpair hq_pbl_base;
+	struct regpair hq_curr_pbe_base;
+	struct regpair r2tq_pbl_base;
+	struct regpair r2tq_curr_pbe_base;
+	struct regpair task_pbl_base;
+#if defined(__BIG_ENDIAN)
+	u16 data_out_count;
+	struct xstorm_iscsi_context_flags flags;
+	u8 task_pbl_cache_idx;
+#elif defined(__LITTLE_ENDIAN)
+	u8 task_pbl_cache_idx;
+	struct xstorm_iscsi_context_flags flags;
+	u16 data_out_count;
+#endif
+	u32 seq_more_2_send;
+	u32 pdu_more_2_send;
+	struct iscsi_task_context_entry_x temp_tce_x;
+	struct iscsi_task_context_entry_xuc_x_write_only temp_tce_x_wr;
+	struct iscsi_task_context_entry_xuc_xu_write_both temp_tce_xu_wr;
+	struct regpair lun;
+	u32 exp_data_transfer_len_ttt;
+	u32 pdu_data_2_rxmit;
+	u32 rxmit_bytes_2_dr;
+#if defined(__BIG_ENDIAN)
+	u16 rxmit_sge_offset;
+	u16 hq_rxmit_cons;
+#elif defined(__LITTLE_ENDIAN)
+	u16 hq_rxmit_cons;
+	u16 rxmit_sge_offset;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 r2tq_cons;
+	u8 rxmit_flags;
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7
+	u8 rxmit_sge_idx;
+#elif defined(__LITTLE_ENDIAN)
+	u8 rxmit_sge_idx;
+	u8 rxmit_flags;
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD (0x1<<0)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_NEW_HQ_BD_SHIFT 0
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR (0x1<<1)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PDU_HDR_SHIFT 1
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU (0x1<<2)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_END_PDU_SHIFT 2
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR (0x1<<3)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_DR_SHIFT 3
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR (0x1<<4)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_START_DR_SHIFT 4
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING (0x3<<5)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_RXMIT_PADDING_SHIFT 5
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT (0x1<<7)
+#define XSTORM_ISCSI_CONTEXT_SECTION_B_ISCSI_CONT_FAST_RXMIT_SHIFT 7
+	u16 r2tq_cons;
+#endif
+	u32 hq_rxmit_tcp_seq;
+};
+
+/*
+ * Xstorm iSCSI Storm Context
+ */
+struct xstorm_iscsi_st_context {
+	struct xstorm_common_context_section common;
+	struct xstorm_iscsi_context_section iscsi;
+};
+
+/*
+ * CQ DB CQ producer and pending completion counter
+ */
+struct iscsi_cq_db_prod_pnd_cmpltn_cnt {
+#if defined(__BIG_ENDIAN)
+	u16 cntr;
+	u16 prod;
+#elif defined(__LITTLE_ENDIAN)
+	u16 prod;
+	u16 cntr;
+#endif
+};
+
+/*
+ * CQ DB pending completion ITT array
+ */
+struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr {
+	struct iscsi_cq_db_prod_pnd_cmpltn_cnt prod_pend_comp[8];
+};
+
+/*
+ * Cstorm CQ sequence to notify array, updated by driver
+ */
+struct iscsi_cq_db_sqn_2_notify_arr {
+	u16 sqn[8];
+};
+
+/*
+ * Cstorm iSCSI Storm Context
+ */
+struct cstorm_iscsi_st_context {
+	struct iscsi_cq_db_prod_pnd_cmpltn_cnt_arr cq_c_prod_pend_comp_ctr_arr;
+	struct iscsi_cq_db_sqn_2_notify_arr cq_c_prod_sqn_arr;
+	struct iscsi_cq_db_sqn_2_notify_arr cq_c_sqn_2_notify_arr;
+	struct regpair hq_pbl_base;
+	struct regpair hq_curr_pbe;
+	struct regpair task_pbl_base;
+	struct regpair cq_db_base;
+#if defined(__BIG_ENDIAN)
+	u16 hq_bd_itt;
+	u16 iscsi_conn_id;
+#elif defined(__LITTLE_ENDIAN)
+	u16 iscsi_conn_id;
+	u16 hq_bd_itt;
+#endif
+	u32 hq_bd_data_segment_len;
+	u32 hq_bd_buffer_offset;
+#if defined(__BIG_ENDIAN)
+	u8 timer_entry_idx;
+	u8 cq_proc_en_bit_map;
+	u8 cq_pend_comp_itt_valid_bit_map;
+	u8 hq_bd_opcode;
+#elif defined(__LITTLE_ENDIAN)
+	u8 hq_bd_opcode;
+	u8 cq_pend_comp_itt_valid_bit_map;
+	u8 cq_proc_en_bit_map;
+	u8 timer_entry_idx;
+#endif
+	u32 hq_tcp_seq;
+#if defined(__BIG_ENDIAN)
+	u16 flags;
+#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0)
+#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0
+#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1)
+#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4
+#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5)
+#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5
+	u16 hq_cons;
+#elif defined(__LITTLE_ENDIAN)
+	u16 hq_cons;
+	u16 flags;
+#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN (0x1<<0)
+#define CSTORM_ISCSI_ST_CONTEXT_DATA_DIGEST_EN_SHIFT 0
+#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN (0x1<<1)
+#define CSTORM_ISCSI_ST_CONTEXT_HDR_DIGEST_EN_SHIFT 1
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID (0x1<<2)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_CTXT_VALID_SHIFT 2
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG (0x1<<3)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_LCL_CMPLN_FLG_SHIFT 3
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK (0x1<<4)
+#define CSTORM_ISCSI_ST_CONTEXT_HQ_BD_WRITE_TASK_SHIFT 4
+#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV (0x7FF<<5)
+#define CSTORM_ISCSI_ST_CONTEXT_CTRL_FLAGS_RSRV_SHIFT 5
+#endif
+	struct regpair rsrv1;
+};
+
+/*
+ * Iscsi connection context
+ */
+struct iscsi_context {
+	struct ustorm_iscsi_st_context ustorm_st_context;
+	struct tstorm_iscsi_st_context tstorm_st_context;
+	struct xstorm_iscsi_ag_context xstorm_ag_context;
+	struct tstorm_iscsi_ag_context tstorm_ag_context;
+	struct cstorm_iscsi_ag_context cstorm_ag_context;
+	struct ustorm_iscsi_ag_context ustorm_ag_context;
+	struct iscsi_timers_block_context timers_context;
+	struct regpair upb_context;
+	struct xstorm_iscsi_st_context xstorm_st_context;
+	struct regpair xpb_context;
+	struct cstorm_iscsi_st_context cstorm_st_context;
+};
+
+/*
+ * Buffer per connection, used in Tstorm
+ */
+struct iscsi_conn_buf {
+	struct regpair reserved[8];
+};
+
+/*
+ * ipv6 structure
+ */
+struct ip_v6_addr {
+	u32 ip_addr_lo_lo;
+	u32 ip_addr_lo_hi;
+	u32 ip_addr_hi_lo;
+	u32 ip_addr_hi_hi;
+};
+
+/*
+ * l5cm- connection identification params
+ */
+struct l5cm_conn_addr_params {
+	u32 pmtu;
+#if defined(__BIG_ENDIAN)
+	u8 remote_addr_3;
+	u8 remote_addr_2;
+	u8 remote_addr_1;
+	u8 remote_addr_0;
+#elif defined(__LITTLE_ENDIAN)
+	u8 remote_addr_0;
+	u8 remote_addr_1;
+	u8 remote_addr_2;
+	u8 remote_addr_3;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 params;
+#define L5CM_CONN_ADDR_PARAMS_IP_VERSION (0x1<<0)
+#define L5CM_CONN_ADDR_PARAMS_IP_VERSION_SHIFT 0
+#define L5CM_CONN_ADDR_PARAMS_RSRV (0x7FFF<<1)
+#define L5CM_CONN_ADDR_PARAMS_RSRV_SHIFT 1
+	u8 remote_addr_5;
+	u8 remote_addr_4;
+#elif defined(__LITTLE_ENDIAN)
+	u8 remote_addr_4;
+	u8 remote_addr_5;
+	u16 params;
+#define L5CM_CONN_ADDR_PARAMS_IP_VERSION (0x1<<0)
+#define L5CM_CONN_ADDR_PARAMS_IP_VERSION_SHIFT 0
+#define L5CM_CONN_ADDR_PARAMS_RSRV (0x7FFF<<1)
+#define L5CM_CONN_ADDR_PARAMS_RSRV_SHIFT 1
+#endif
+	struct ip_v6_addr local_ip_addr;
+	struct ip_v6_addr remote_ip_addr;
+	u32 ipv6_flow_label_20b;
+	u32 reserved1;
+#if defined(__BIG_ENDIAN)
+	u16 remote_tcp_port;
+	u16 local_tcp_port;
+#elif defined(__LITTLE_ENDIAN)
+	u16 local_tcp_port;
+	u16 remote_tcp_port;
+#endif
+};
+
+/*
+ * l5cm-xstorm connection buffer
+ */
+struct l5cm_xstorm_conn_buffer {
+#if defined(__BIG_ENDIAN)
+	u16 rsrv1;
+	u16 params;
+#define L5CM_XSTORM_CONN_BUFFER_NAGLE_ENABLE (0x1<<0)
+#define L5CM_XSTORM_CONN_BUFFER_NAGLE_ENABLE_SHIFT 0
+#define L5CM_XSTORM_CONN_BUFFER_RSRV (0x7FFF<<1)
+#define L5CM_XSTORM_CONN_BUFFER_RSRV_SHIFT 1
+#elif defined(__LITTLE_ENDIAN)
+	u16 params;
+#define L5CM_XSTORM_CONN_BUFFER_NAGLE_ENABLE (0x1<<0)
+#define L5CM_XSTORM_CONN_BUFFER_NAGLE_ENABLE_SHIFT 0
+#define L5CM_XSTORM_CONN_BUFFER_RSRV (0x7FFF<<1)
+#define L5CM_XSTORM_CONN_BUFFER_RSRV_SHIFT 1
+	u16 rsrv1;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 mss;
+	u16 pseudo_header_checksum;
+#elif defined(__LITTLE_ENDIAN)
+	u16 pseudo_header_checksum;
+	u16 mss;
+#endif
+	u32 rcv_buf;
+	u32 rsrv2;
+	struct regpair context_addr;
+};
+
+/*
+ * l5cm-tstorm connection buffer
+ */
+struct l5cm_tstorm_conn_buffer {
+	u32 snd_buf;
+	u32 rcv_buf;
+#if defined(__BIG_ENDIAN)
+	u16 params;
+#define L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE (0x1<<0)
+#define L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE_SHIFT 0
+#define L5CM_TSTORM_CONN_BUFFER_RSRV (0x7FFF<<1)
+#define L5CM_TSTORM_CONN_BUFFER_RSRV_SHIFT 1
+	u8 ka_max_probe_count;
+	u8 ka_enable;
+#elif defined(__LITTLE_ENDIAN)
+	u8 ka_enable;
+	u8 ka_max_probe_count;
+	u16 params;
+#define L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE (0x1<<0)
+#define L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE_SHIFT 0
+#define L5CM_TSTORM_CONN_BUFFER_RSRV (0x7FFF<<1)
+#define L5CM_TSTORM_CONN_BUFFER_RSRV_SHIFT 1
+#endif
+	u32 ka_timeout;
+	u32 ka_interval;
+	u32 max_rt_time;
+};
+
+/*
+ * l5cm connection buffer for active side
+ */
+struct l5cm_active_conn_buffer {
+	struct l5cm_conn_addr_params conn_addr_buf;
+	struct l5cm_xstorm_conn_buffer xstorm_conn_buffer;
+	struct l5cm_tstorm_conn_buffer tstorm_conn_buffer;
+};
+
+/*
+ * l5cm slow path element
+ */
+struct l5cm_packet_size {
+	u32 size;
+	u32 rsrv;
+};
+
+/*
+ * l5cm connection parameters
+ */
+union l5cm_reduce_param_union {
+	u32 passive_side_scramble_key;
+	u32 pcs_id;
+};
+
+/*
+ * l5cm connection parameters
+ */
+struct l5cm_reduce_conn {
+	union l5cm_reduce_param_union param;
+	u32 isn;
+};
+
+/*
+ * l5cm slow path element
+ */
+union l5cm_specific_data {
+	u8 protocol_data[8];
+	struct regpair phy_address;
+	struct l5cm_packet_size packet_size;
+	struct l5cm_reduce_conn reduced_conn;
+};
+
+/*
+ * l5 slow path element
+ */
+struct l5cm_spe {
+	struct spe_hdr hdr;
+	union l5cm_specific_data data;
+};
+
+/*
+ * Tstorm Tcp flags
+ */
+struct tstorm_l5cm_tcp_flags {
+	u16 flags;
+#define TSTORM_L5CM_TCP_FLAGS_VLAN_ID (0xFFF<<0)
+#define TSTORM_L5CM_TCP_FLAGS_VLAN_ID_SHIFT 0
+#define TSTORM_L5CM_TCP_FLAGS_RSRV0 (0x1<<12)
+#define TSTORM_L5CM_TCP_FLAGS_RSRV0_SHIFT 12
+#define TSTORM_L5CM_TCP_FLAGS_TS_ENABLED (0x1<<13)
+#define TSTORM_L5CM_TCP_FLAGS_TS_ENABLED_SHIFT 13
+#define TSTORM_L5CM_TCP_FLAGS_RSRV1 (0x3<<14)
+#define TSTORM_L5CM_TCP_FLAGS_RSRV1_SHIFT 14
+};
+
+/*
+ * Xstorm Tcp flags
+ */
+struct xstorm_l5cm_tcp_flags {
+	u8 flags;
+#define XSTORM_L5CM_TCP_FLAGS_ENC_ENABLED (0x1<<0)
+#define XSTORM_L5CM_TCP_FLAGS_ENC_ENABLED_SHIFT 0
+#define XSTORM_L5CM_TCP_FLAGS_TS_ENABLED (0x1<<1)
+#define XSTORM_L5CM_TCP_FLAGS_TS_ENABLED_SHIFT 1
+#define XSTORM_L5CM_TCP_FLAGS_WND_SCL_EN (0x1<<2)
+#define XSTORM_L5CM_TCP_FLAGS_WND_SCL_EN_SHIFT 2
+#define XSTORM_L5CM_TCP_FLAGS_RSRV (0x1F<<3)
+#define XSTORM_L5CM_TCP_FLAGS_RSRV_SHIFT 3
+};
+
 #endif /* CNIC_DEFS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cnic.h linux-libre-2.6.33-gnu1/drivers/net/cnic.h
--- linux-libre-2.6.32-gnu1/drivers/net/cnic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cnic.h	2010-02-24 13:52:17.000000000 -0500
@@ -227,6 +227,7 @@ struct cnic_local {
 	void				*status_blk;
 	struct status_block_msix	*bnx2_status_blk;
 	struct host_status_block	*bnx2x_status_blk;
+	struct host_def_status_block	*bnx2x_def_status_blk;
 
 	u32				status_blk_num;
 	u32				int_num;
@@ -258,6 +259,7 @@ struct cnic_local {
 	struct cnic_ctx		*ctx_arr;
 	int			ctx_blks;
 	int			ctx_blk_size;
+	unsigned long		ctx_align;
 	int			cids_per_blk;
 
 	u32			chip_id;
@@ -290,11 +292,73 @@ struct bnx2x_bd_chain_next {
 	u8	reserved[8];
 };
 
+#define ISCSI_DEFAULT_MAX_OUTSTANDING_R2T 	(1)
+
 #define ISCSI_RAMROD_CMD_ID_UPDATE_CONN		(ISCSI_KCQE_OPCODE_UPDATE_CONN)
 #define ISCSI_RAMROD_CMD_ID_INIT		(ISCSI_KCQE_OPCODE_INIT)
 
 #define CDU_REGION_NUMBER_XCM_AG 2
 #define CDU_REGION_NUMBER_UCM_AG 4
 
+#define CDU_VALID_DATA(_cid, _region, _type)	\
+	(((_cid) << 8) | (((_region)&0xf)<<4) | (((_type)&0xf)))
+
+#define CDU_CRC8(_cid, _region, _type)	\
+	(calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff))
+
+#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type)	\
+	(0x80 | ((CDU_CRC8(_cid, _region, _type)) & 0x7f))
+
+#define BNX2X_CONTEXT_MEM_SIZE		1024
+#define BNX2X_FCOE_CID			16
+
+/* iSCSI client IDs are 17, 19, 21, 23 */
+#define BNX2X_ISCSI_BASE_CL_ID		17
+#define BNX2X_ISCSI_CL_ID(vn)		(BNX2X_ISCSI_BASE_CL_ID + ((vn) << 1))
+
+#define BNX2X_ISCSI_L2_CID		17
+#define BNX2X_ISCSI_START_CID		18
+#define BNX2X_ISCSI_NUM_CONNECTIONS	128
+#define BNX2X_ISCSI_TASK_CONTEXT_SIZE	128
+#define BNX2X_ISCSI_MAX_PENDING_R2TS	4
+#define BNX2X_ISCSI_R2TQE_SIZE		8
+#define BNX2X_ISCSI_HQ_BD_SIZE		64
+#define BNX2X_ISCSI_CONN_BUF_SIZE	64
+#define BNX2X_ISCSI_GLB_BUF_SIZE	64
+#define BNX2X_ISCSI_PBL_NOT_CACHED	0xff
+#define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED	0xff
+#define BNX2X_HW_CID(x, func)		((x) | (((func) % PORT_MAX) << 23) | \
+					 (((func) >> 1) << 17))
+#define BNX2X_SW_CID(x)			(x & 0x1ffff)
+#define BNX2X_CHIP_NUM_57711		0x164f
+#define BNX2X_CHIP_NUM_57711E		0x1650
+#define BNX2X_CHIP_NUM(x)		(x >> 16)
+#define BNX2X_CHIP_IS_57711(x)		\
+	(BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711)
+#define BNX2X_CHIP_IS_57711E(x)		\
+	(BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711E)
+#define BNX2X_CHIP_IS_E1H(x)		\
+	(BNX2X_CHIP_IS_57711(x) || BNX2X_CHIP_IS_57711E(x))
+#define IS_E1H_OFFSET       		BNX2X_CHIP_IS_E1H(cp->chip_id)
+
+#define BNX2X_RX_DESC_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
+#define BNX2X_MAX_RX_DESC_CNT		(BNX2X_RX_DESC_CNT - 2)
+#define BNX2X_RCQ_DESC_CNT		(BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
+#define BNX2X_MAX_RCQ_DESC_CNT		(BNX2X_RCQ_DESC_CNT - 1)
+
+#define BNX2X_DEF_SB_ID			16
+
+#define BNX2X_ISCSI_RX_SB_INDEX_NUM					\
+		((HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS << \
+		  USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \
+		 USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER)
+
+#define BNX2X_SHMEM_ADDR(base, field)	(base + \
+					 offsetof(struct shmem_region, field))
+
+#define CNIC_PORT(cp)			((cp)->func % PORT_MAX)
+#define CNIC_FUNC(cp)			((cp)->func)
+#define CNIC_E1HVN(cp)			((cp)->func >> 1)
+
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cnic_if.h linux-libre-2.6.33-gnu1/drivers/net/cnic_if.h
--- linux-libre-2.6.32-gnu1/drivers/net/cnic_if.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cnic_if.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION	"2.0.1"
-#define CNIC_MODULE_RELDATE	"Oct 01, 2009"
+#define CNIC_MODULE_VERSION	"2.1.0"
+#define CNIC_MODULE_RELDATE	"Oct 10, 2009"
 
 #define CNIC_ULP_RDMA		0
 #define CNIC_ULP_ISCSI		1
@@ -81,6 +81,8 @@ struct kcqe {
 #define DRV_CTL_CTX_WR_CMD		0x103
 #define DRV_CTL_CTXTBL_WR_CMD		0x104
 #define DRV_CTL_COMPLETION_CMD		0x105
+#define DRV_CTL_START_L2_CMD		0x106
+#define DRV_CTL_STOP_L2_CMD		0x107
 
 struct cnic_ctl_completion {
 	u32	cid;
@@ -105,11 +107,17 @@ struct drv_ctl_io {
 	dma_addr_t	dma_addr;
 };
 
+struct drv_ctl_l2_ring {
+	u32		client_id;
+	u32		cid;
+};
+
 struct drv_ctl_info {
 	int	cmd;
 	union {
 		struct drv_ctl_completion comp;
 		struct drv_ctl_io io;
+		struct drv_ctl_l2_ring ring;
 		char bytes[MAX_DRV_CTL_DATA];
 	} data;
 };
@@ -143,6 +151,7 @@ struct cnic_eth_dev {
 	u32		max_kwqe_pending;
 	struct pci_dev	*pdev;
 	void __iomem	*io_base;
+	void __iomem	*io_base2;
 
 	u32		ctx_tbl_offset;
 	u32		ctx_tbl_len;
@@ -298,5 +307,6 @@ extern int cnic_register_driver(int ulp_
 extern int cnic_unregister_driver(int ulp_type);
 
 extern struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev);
+extern struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cpmac.c linux-libre-2.6.33-gnu1/drivers/net/cpmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/cpmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cpmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -380,9 +380,8 @@ static struct sk_buff *cpmac_rx_one(stru
 		return NULL;
 	}
 
-	skb = netdev_alloc_skb(priv->dev, CPMAC_SKB_SIZE);
+	skb = netdev_alloc_skb_ip_align(priv->dev, CPMAC_SKB_SIZE);
 	if (likely(skb)) {
-		skb_reserve(skb, 2);
 		skb_put(desc->skb, desc->datalen);
 		desc->skb->protocol = eth_type_trans(desc->skb, priv->dev);
 		desc->skb->ip_summed = CHECKSUM_NONE;
@@ -991,12 +990,11 @@ static int cpmac_open(struct net_device
 
 	priv->rx_head = &priv->desc_ring[CPMAC_QUEUES];
 	for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) {
-		skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+		skb = netdev_alloc_skb_ip_align(dev, CPMAC_SKB_SIZE);
 		if (unlikely(!skb)) {
 			res = -ENOMEM;
 			goto fail_desc;
 		}
-		skb_reserve(skb, 2);
 		desc->skb = skb;
 		desc->data_mapping = dma_map_single(&dev->dev, skb->data,
 						    CPMAC_SKB_SIZE,
@@ -1165,7 +1163,7 @@ static int __devinit cpmac_probe(struct
 	priv->dev = dev;
 	priv->ring_size = 64;
 	priv->msg_enable = netif_msg_init(debug_level, 0xff);
-	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
+	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr));
 
 	snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cs89x0.c linux-libre-2.6.33-gnu1/drivers/net/cs89x0.c
--- linux-libre-2.6.32-gnu1/drivers/net/cs89x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cs89x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -1323,10 +1323,9 @@ net_open(struct net_device *dev)
 		writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 #endif
 		write_irq(dev, lp->chip_type, dev->irq);
-		ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
+		ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
 		if (ret) {
-			if (net_debug)
-				printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq);
+			printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq);
 			goto bad_out;
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cxgb3/adapter.h linux-libre-2.6.33-gnu1/drivers/net/cxgb3/adapter.h
--- linux-libre-2.6.32-gnu1/drivers/net/cxgb3/adapter.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cxgb3/adapter.h	2010-02-24 13:52:17.000000000 -0500
@@ -48,12 +48,27 @@
 struct vlan_group;
 struct adapter;
 struct sge_qset;
+struct port_info;
 
 enum {			/* rx_offload flags */
 	T3_RX_CSUM	= 1 << 0,
 	T3_LRO		= 1 << 1,
 };
 
+enum mac_idx_types {
+	LAN_MAC_IDX	= 0,
+	SAN_MAC_IDX,
+
+	MAX_MAC_IDX
+};
+
+struct iscsi_config {
+	__u8	mac_addr[ETH_ALEN];
+	__u32	flags;
+	int (*send)(struct port_info *pi, struct sk_buff **skb);
+	int (*recv)(struct port_info *pi, struct sk_buff *skb);
+};
+
 struct port_info {
 	struct adapter *adapter;
 	struct vlan_group *vlan_grp;
@@ -68,6 +83,7 @@ struct port_info {
 	struct net_device_stats netstats;
 	int activity;
 	__be32 iscsi_ipv4addr;
+	struct iscsi_config iscsic;
 
 	int link_fault; /* link fault was detected */
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cxgb3/common.h linux-libre-2.6.33-gnu1/drivers/net/cxgb3/common.h
--- linux-libre-2.6.32-gnu1/drivers/net/cxgb3/common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cxgb3/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -125,11 +125,9 @@ enum {				/* adapter interrupt-maintaine
 	IRQ_NUM_STATS		/* keep last */
 };
 
-enum {
-	TP_VERSION_MAJOR	= 1,
-	TP_VERSION_MINOR	= 1,
-	TP_VERSION_MICRO	= 0
-};
+#define TP_VERSION_MAJOR	1
+#define TP_VERSION_MINOR	1
+#define TP_VERSION_MICRO	0
 
 #define S_TP_VERSION_MAJOR		16
 #define M_TP_VERSION_MAJOR		0xFF
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cxgb3/cxgb3_main.c linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 14:00:49.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 12:08:06.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/firmware.h>
 #include <linux/log2.h>
+#include <linux/stringify.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -344,8 +345,10 @@ static void link_start(struct net_device
 
 	init_rx_mode(&rm, dev, dev->mc_list);
 	t3_mac_reset(mac);
+	t3_mac_set_num_ucast(mac, MAX_MAC_IDX);
 	t3_mac_set_mtu(mac, dev->mtu);
-	t3_mac_set_address(mac, 0, dev->dev_addr);
+	t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
+	t3_mac_set_address(mac, SAN_MAC_IDX, pi->iscsic.mac_addr);
 	t3_mac_set_rx_mode(mac, &rm);
 	t3_link_start(&pi->phy, mac, &pi->link_config);
 	t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -903,6 +906,7 @@ static inline int offload_tx(struct t3cd
 static int write_smt_entry(struct adapter *adapter, int idx)
 {
 	struct cpl_smt_write_req *req;
+	struct port_info *pi = netdev_priv(adapter->port[idx]);
 	struct sk_buff *skb = alloc_skb(sizeof(*req), GFP_KERNEL);
 
 	if (!skb)
@@ -913,8 +917,8 @@ static int write_smt_entry(struct adapte
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx));
 	req->mtu_idx = NMTUS - 1;	/* should be 0 but there's a T3 bug */
 	req->iff = idx;
-	memset(req->src_mac1, 0, sizeof(req->src_mac1));
 	memcpy(req->src_mac0, adapter->port[idx]->dev_addr, ETH_ALEN);
+	memcpy(req->src_mac1, pi->iscsic.mac_addr, ETH_ALEN);
 	skb->priority = 1;
 	offload_tx(&adapter->tdev, skb);
 	return 0;
@@ -989,11 +993,14 @@ static int bind_qsets(struct adapter *ad
 	return err;
 }
 
+/*(DEBLOBBED)*/
 #define FW_FNAME "/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
 #define TPSRAM_NAME "/*(DEBLOBBED)*/"
 #define AEL2005_OPT_EDC_NAME "/*(DEBLOBBED)*/"
 #define AEL2005_TWX_EDC_NAME "/*(DEBLOBBED)*/"
 #define AEL2020_TWX_EDC_NAME "/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
 
 static inline const char *get_edc_fw_name(int edc_idx)
 {
@@ -1064,16 +1071,13 @@ int t3_get_edc_fw(struct cphy *phy, int
 static int upgrade_fw(struct adapter *adap)
 {
 	int ret;
-	char buf[64];
 	const struct firmware *fw;
 	struct device *dev = &adap->pdev->dev;
 
-	snprintf(buf, sizeof(buf), FW_FNAME, FW_VERSION_MAJOR,
-		 FW_VERSION_MINOR, FW_VERSION_MICRO);
-	ret = reject_firmware(&fw, buf, dev);
+	ret = reject_firmware(&fw, FW_FNAME, dev);
 	if (ret < 0) {
 		dev_err(dev, "could not upgrade firmware: unable to load %s\n",
-			buf);
+			FW_FNAME);
 		return ret;
 	}
 	ret = t3_load_fw(adap, fw->data, fw->size);
@@ -1117,8 +1121,7 @@ static int update_tpsram(struct adapter
 	if (!rev)
 		return 0;
 
-	snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
-		 TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
+	snprintf(buf, sizeof(buf), TPSRAM_NAME, rev);
 
 	ret = reject_firmware(&tpsram, buf, dev);
 	if (ret < 0) {
@@ -2107,19 +2110,19 @@ static int cxgb_extension_ioctl(struct n
 		if (t.qset_idx >= SGE_QSETS)
 			return -EINVAL;
 		if (!in_range(t.intr_lat, 0, M_NEWTIMER) ||
-			!in_range(t.cong_thres, 0, 255) ||
-			!in_range(t.txq_size[0], MIN_TXQ_ENTRIES,
-				MAX_TXQ_ENTRIES) ||
-			!in_range(t.txq_size[1], MIN_TXQ_ENTRIES,
-				MAX_TXQ_ENTRIES) ||
-			!in_range(t.txq_size[2], MIN_CTRL_TXQ_ENTRIES,
-				MAX_CTRL_TXQ_ENTRIES) ||
-			!in_range(t.fl_size[0], MIN_FL_ENTRIES,
-				MAX_RX_BUFFERS)
-			|| !in_range(t.fl_size[1], MIN_FL_ENTRIES,
-					MAX_RX_JUMBO_BUFFERS)
-			|| !in_range(t.rspq_size, MIN_RSPQ_ENTRIES,
-					MAX_RSPQ_ENTRIES))
+		    !in_range(t.cong_thres, 0, 255) ||
+		    !in_range(t.txq_size[0], MIN_TXQ_ENTRIES,
+			      MAX_TXQ_ENTRIES) ||
+		    !in_range(t.txq_size[1], MIN_TXQ_ENTRIES,
+			      MAX_TXQ_ENTRIES) ||
+		    !in_range(t.txq_size[2], MIN_CTRL_TXQ_ENTRIES,
+			      MAX_CTRL_TXQ_ENTRIES) ||
+		    !in_range(t.fl_size[0], MIN_FL_ENTRIES,
+			      MAX_RX_BUFFERS) ||
+		    !in_range(t.fl_size[1], MIN_FL_ENTRIES,
+			      MAX_RX_JUMBO_BUFFERS) ||
+		    !in_range(t.rspq_size, MIN_RSPQ_ENTRIES,
+			      MAX_RSPQ_ENTRIES))
 			return -EINVAL;
 
 		if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0)
@@ -2516,7 +2519,7 @@ static int cxgb_set_mac_addr(struct net_
 		return -EINVAL;
 
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-	t3_mac_set_address(&pi->mac, 0, dev->dev_addr);
+	t3_mac_set_address(&pi->mac, LAN_MAC_IDX, dev->dev_addr);
 	if (offload_running(adapter))
 		write_smt_entry(adapter, pi->port_id);
 	return 0;
@@ -2654,7 +2657,7 @@ static void check_t3b2_mac(struct adapte
 			struct cmac *mac = &p->mac;
 
 			t3_mac_set_mtu(mac, dev->mtu);
-			t3_mac_set_address(mac, 0, dev->dev_addr);
+			t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
 			cxgb_set_rxmode(dev);
 			t3_link_start(&p->phy, mac, &p->link_config);
 			t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -2850,6 +2853,7 @@ static int t3_reenable_adapter(struct ad
 	}
 	pci_set_master(adapter->pdev);
 	pci_restore_state(adapter->pdev);
+	pci_save_state(adapter->pdev);
 
 	/* Free sge resources */
 	t3_free_sge_resources(adapter);
@@ -3112,6 +3116,14 @@ static const struct net_device_ops cxgb_
 #endif
 };
 
+static void __devinit cxgb3_init_iscsi_mac(struct net_device *dev)
+{
+	struct port_info *pi = netdev_priv(dev);
+
+	memcpy(pi->iscsic.mac_addr, dev->dev_addr, ETH_ALEN);
+	pi->iscsic.mac_addr[3] |= 0x80;
+}
+
 static int __devinit init_one(struct pci_dev *pdev,
 			      const struct pci_device_id *ent)
 {
@@ -3270,6 +3282,9 @@ static int __devinit init_one(struct pci
 		goto out_free_dev;
 	}
 
+	for_each_port(adapter, i)
+		cxgb3_init_iscsi_mac(adapter->port[i]);
+
 	/* Driver's ready. Reflect it on LEDs */
 	t3_led_ready(adapter);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/cxgb3/sge.c linux-libre-2.6.33-gnu1/drivers/net/cxgb3/sge.c
--- linux-libre-2.6.32-gnu1/drivers/net/cxgb3/sge.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/cxgb3/sge.c	2010-02-24 13:52:17.000000000 -0500
@@ -1260,7 +1260,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *
 		if (should_restart_tx(q) &&
 		    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
 			q->restarts++;
-			netif_tx_wake_queue(txq);
+			netif_tx_start_queue(txq);
 		}
 	}
 
@@ -1285,7 +1285,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *
 
 	/*
 	 * We do not use Tx completion interrupts to free DMAd Tx packets.
-	 * This is good for performamce but means that we rely on new Tx
+	 * This is good for performance but means that we rely on new Tx
 	 * packets arriving to run the destructors of completed packets,
 	 * which open up space in their sockets' send queues.  Sometimes
 	 * we do not get such new packets causing Tx to stall.  A single
@@ -1946,10 +1946,9 @@ static void restart_tx(struct sge_qset *
  *	Check if the ARP request is probing the private IP address
  *	dedicated to iSCSI, generate an ARP reply if so.
  */
-static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
+static void cxgb3_arp_process(struct port_info *pi, struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
-	struct port_info *pi;
 	struct arphdr *arp;
 	unsigned char *arp_ptr;
 	unsigned char *sha;
@@ -1972,12 +1971,11 @@ static void cxgb3_arp_process(struct ada
 	arp_ptr += dev->addr_len;
 	memcpy(&tip, arp_ptr, sizeof(tip));
 
-	pi = netdev_priv(dev);
 	if (tip != pi->iscsi_ipv4addr)
 		return;
 
 	arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
-		 dev->dev_addr, sha);
+		 pi->iscsic.mac_addr, sha);
 
 }
 
@@ -1986,6 +1984,19 @@ static inline int is_arp(struct sk_buff
 	return skb->protocol == htons(ETH_P_ARP);
 }
 
+static void cxgb3_process_iscsi_prov_pack(struct port_info *pi,
+					struct sk_buff *skb)
+{
+	if (is_arp(skb)) {
+		cxgb3_arp_process(pi, skb);
+		return;
+	}
+
+	if (pi->iscsic.recv)
+		pi->iscsic.recv(pi, skb);
+
+}
+
 /**
  *	rx_eth - process an ingress ethernet packet
  *	@adap: the adapter
@@ -2024,13 +2035,12 @@ static void rx_eth(struct adapter *adap,
 				vlan_gro_receive(&qs->napi, grp,
 						 ntohs(p->vlan), skb);
 			else {
-				if (unlikely(pi->iscsi_ipv4addr &&
-				    is_arp(skb))) {
+				if (unlikely(pi->iscsic.flags)) {
 					unsigned short vtag = ntohs(p->vlan) &
 								VLAN_VID_MASK;
 					skb->dev = vlan_group_get_device(grp,
 									 vtag);
-					cxgb3_arp_process(adap, skb);
+					cxgb3_process_iscsi_prov_pack(pi, skb);
 				}
 				__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
 					  	  rq->polling);
@@ -2041,8 +2051,8 @@ static void rx_eth(struct adapter *adap,
 		if (lro)
 			napi_gro_receive(&qs->napi, skb);
 		else {
-			if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
-				cxgb3_arp_process(adap, skb);
+			if (unlikely(pi->iscsic.flags))
+				cxgb3_process_iscsi_prov_pack(pi, skb);
 			netif_receive_skb(skb);
 		}
 	} else
@@ -2069,6 +2079,7 @@ static void lro_add_page(struct adapter
 			 struct sge_fl *fl, int len, int complete)
 {
 	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+	struct port_info *pi = netdev_priv(qs->netdev);
 	struct sk_buff *skb = NULL;
 	struct cpl_rx_pkt *cpl;
 	struct skb_frag_struct *rx_frag;
@@ -2106,11 +2117,18 @@ static void lro_add_page(struct adapter
 
 	if (!nr_frags) {
 		offset = 2 + sizeof(struct cpl_rx_pkt);
-		qs->lro_va = sd->pg_chunk.va + 2;
-	}
-	len -= offset;
+		cpl = qs->lro_va = sd->pg_chunk.va + 2;
 
-	prefetch(qs->lro_va);
+		if ((pi->rx_offload & T3_RX_CSUM) &&
+		     cpl->csum_valid && cpl->csum == htons(0xffff)) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
+		} else
+			skb->ip_summed = CHECKSUM_NONE;
+	} else
+		cpl = qs->lro_va;
+
+	len -= offset;
 
 	rx_frag += nr_frags;
 	rx_frag->page = sd->pg_chunk.page;
@@ -2125,12 +2143,9 @@ static void lro_add_page(struct adapter
 	if (!complete)
 		return;
 
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
-	cpl = qs->lro_va;
+	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
 
 	if (unlikely(cpl->vlan_valid)) {
-		struct net_device *dev = qs->netdev;
-		struct port_info *pi = netdev_priv(dev);
 		struct vlan_group *grp = pi->vlan_grp;
 
 		if (likely(grp != NULL)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/davinci_emac.c linux-libre-2.6.33-gnu1/drivers/net/davinci_emac.c
--- linux-libre-2.6.32-gnu1/drivers/net/davinci_emac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/davinci_emac.c	2010-02-24 13:52:17.000000000 -0500
@@ -2272,7 +2272,7 @@ static int emac_mii_reset(struct mii_bus
 	unsigned int clk_div;
 	int mdio_bus_freq = emac_bus_frequency;
 
-	if (mdio_max_freq & mdio_bus_freq)
+	if (mdio_max_freq && mdio_bus_freq)
 		clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
 	else
 		clk_div = 0xFF;
@@ -2711,6 +2711,8 @@ static int __devinit davinci_emac_probe(
 	SET_ETHTOOL_OPS(ndev, &ethtool_ops);
 	netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
 
+	clk_enable(emac_clk);
+
 	/* register the network device */
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	rc = register_netdev(ndev);
@@ -2720,7 +2722,6 @@ static int __devinit davinci_emac_probe(
 		goto netdev_reg_err;
 	}
 
-	clk_enable(emac_clk);
 
 	/* MII/Phy intialisation, mdio bus registration */
 	emac_mii = mdiobus_alloc();
@@ -2760,6 +2761,7 @@ mdiobus_quit:
 
 netdev_reg_err:
 mdio_alloc_err:
+	clk_disable(emac_clk);
 no_irq_res:
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, res->end - res->start + 1);
@@ -2803,11 +2805,33 @@ static int __devexit davinci_emac_remove
 	return 0;
 }
 
+static
+int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	if (netif_running(dev))
+		emac_dev_stop(dev);
+
+	clk_disable(emac_clk);
+
+	return 0;
+}
+
+static int davinci_emac_resume(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	clk_enable(emac_clk);
+
+	if (netif_running(dev))
+		emac_dev_open(dev);
+
+	return 0;
+}
+
 /**
  * davinci_emac_driver: EMAC platform driver structure
- *
- * We implement only probe and remove functions - suspend/resume and
- * others not supported by this module
  */
 static struct platform_driver davinci_emac_driver = {
 	.driver = {
@@ -2816,6 +2840,8 @@ static struct platform_driver davinci_em
 	},
 	.probe = davinci_emac_probe,
 	.remove = __devexit_p(davinci_emac_remove),
+	.suspend = davinci_emac_suspend,
+	.resume = davinci_emac_resume,
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/declance.c linux-libre-2.6.33-gnu1/drivers/net/declance.c
--- linux-libre-2.6.32-gnu1/drivers/net/declance.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/declance.c	2010-02-24 13:52:17.000000000 -0500
@@ -801,14 +801,14 @@ static int lance_open(struct net_device
 	netif_start_queue(dev);
 
 	/* Associate IRQ with lance_interrupt */
-	if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) {
+	if (request_irq(dev->irq, lance_interrupt, 0, "lance", dev)) {
 		printk("%s: Can't get IRQ %d\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
 	if (lp->dma_irq >= 0) {
 		unsigned long flags;
 
-		if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0,
+		if (request_irq(lp->dma_irq, lance_dma_merr_int, 0,
 				"lance error", dev)) {
 			free_irq(dev->irq, dev);
 			printk("%s: Can't get DMA IRQ %d\n", dev->name,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/depca.c linux-libre-2.6.33-gnu1/drivers/net/depca.c
--- linux-libre-2.6.32-gnu1/drivers/net/depca.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/depca.c	2010-02-24 13:52:17.000000000 -0500
@@ -849,7 +849,7 @@ static int depca_open(struct net_device
 
 	depca_dbg_open(dev);
 
-	if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, dev)) {
+	if (request_irq(dev->irq, depca_interrupt, 0, lp->adapter_name, dev)) {
 		printk("depca_open(): Requested IRQ%d is busy\n", dev->irq);
 		status = -EAGAIN;
 	} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/dl2k.c linux-libre-2.6.33-gnu1/drivers/net/dl2k.c
--- linux-libre-2.6.32-gnu1/drivers/net/dl2k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/dl2k.c	2010-02-24 13:52:17.000000000 -0500
@@ -163,8 +163,8 @@ rio_probe1 (struct pci_dev *pdev, const
 			    strcmp (media[card_idx], "4") == 0) {
 				np->speed = 100;
 				np->full_duplex = 1;
-			} else if (strcmp (media[card_idx], "100mbps_hd") == 0
-				   || strcmp (media[card_idx], "3") == 0) {
+			} else if (strcmp (media[card_idx], "100mbps_hd") == 0 ||
+				   strcmp (media[card_idx], "3") == 0) {
 				np->speed = 100;
 				np->full_duplex = 0;
 			} else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
@@ -411,7 +411,7 @@ rio_open (struct net_device *dev)
 	int i;
 	u16 macctrl;
 
-	i = request_irq (dev->irq, &rio_interrupt, IRQF_SHARED, dev->name, dev);
+	i = request_irq (dev->irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
 	if (i)
 		return i;
 
@@ -505,7 +505,8 @@ rio_timer (unsigned long data)
 			entry = np->old_rx % RX_RING_SIZE;
 			/* Dropped packets don't need to re-allocate */
 			if (np->rx_skbuff[entry] == NULL) {
-				skb = netdev_alloc_skb (dev, np->rx_buf_sz);
+				skb = netdev_alloc_skb_ip_align(dev,
+								np->rx_buf_sz);
 				if (skb == NULL) {
 					np->rx_ring[entry].fraginfo = 0;
 					printk (KERN_INFO
@@ -514,8 +515,6 @@ rio_timer (unsigned long data)
 					break;
 				}
 				np->rx_skbuff[entry] = skb;
-				/* 16 byte align the IP header */
-				skb_reserve (skb, 2);
 				np->rx_ring[entry].fraginfo =
 				    cpu_to_le64 (pci_map_single
 					 (np->pdev, skb->data, np->rx_buf_sz,
@@ -576,7 +575,9 @@ alloc_list (struct net_device *dev)
 	/* Allocate the rx buffers */
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		/* Allocated fixed size of skbuff */
-		struct sk_buff *skb = netdev_alloc_skb (dev, np->rx_buf_sz);
+		struct sk_buff *skb;
+
+		skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
 		np->rx_skbuff[i] = skb;
 		if (skb == NULL) {
 			printk (KERN_ERR
@@ -584,7 +585,6 @@ alloc_list (struct net_device *dev)
 				dev->name);
 			break;
 		}
-		skb_reserve (skb, 2);	/* 16 byte align the IP header. */
 		/* Rubicon now supports 40 bits of addressing space. */
 		np->rx_ring[i].fraginfo =
 		    cpu_to_le64 ( pci_map_single (
@@ -871,13 +871,11 @@ receive_packet (struct net_device *dev)
 						  PCI_DMA_FROMDEVICE);
 				skb_put (skb = np->rx_skbuff[entry], pkt_len);
 				np->rx_skbuff[entry] = NULL;
-			} else if ((skb = netdev_alloc_skb(dev, pkt_len + 2))) {
+			} else if ((skb = netdev_alloc_skb_ip_align(dev, pkt_len))) {
 				pci_dma_sync_single_for_cpu(np->pdev,
 							    desc_to_dma(desc),
 							    np->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
-				/* 16 byte align the IP header */
-				skb_reserve (skb, 2);
 				skb_copy_to_linear_data (skb,
 						  np->rx_skbuff[entry]->data,
 						  pkt_len);
@@ -907,7 +905,7 @@ receive_packet (struct net_device *dev)
 		struct sk_buff *skb;
 		/* Dropped packets don't need to re-allocate */
 		if (np->rx_skbuff[entry] == NULL) {
-			skb = netdev_alloc_skb(dev, np->rx_buf_sz);
+			skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
 			if (skb == NULL) {
 				np->rx_ring[entry].fraginfo = 0;
 				printk (KERN_INFO
@@ -917,8 +915,6 @@ receive_packet (struct net_device *dev)
 				break;
 			}
 			np->rx_skbuff[entry] = skb;
-			/* 16 byte align the IP header */
-			skb_reserve (skb, 2);
 			np->rx_ring[entry].fraginfo =
 			    cpu_to_le64 (pci_map_single
 					 (np->pdev, skb->data, np->rx_buf_sz,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/dm9000.c linux-libre-2.6.33-gnu1/drivers/net/dm9000.c
--- linux-libre-2.6.32-gnu1/drivers/net/dm9000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/dm9000.c	2010-02-24 13:52:17.000000000 -0500
@@ -100,6 +100,7 @@ typedef struct board_info {
 
 	unsigned int	flags;
 	unsigned int	in_suspend :1;
+	unsigned int	wake_supported :1;
 	int		debug_level;
 
 	enum dm9000_type type;
@@ -116,6 +117,8 @@ typedef struct board_info {
 	struct resource *data_req;
 	struct resource *irq_res;
 
+	int		 irq_wake;
+
 	struct mutex	 addr_lock;	/* phy and eeprom access lock */
 
 	struct delayed_work phy_poll;
@@ -125,6 +128,7 @@ typedef struct board_info {
 
 	struct mii_if_info mii;
 	u32		msg_enable;
+	u32		wake_state;
 
 	int		rx_csum;
 	int		can_csum;
@@ -568,6 +572,54 @@ static int dm9000_set_eeprom(struct net_
 	return 0;
 }
 
+static void dm9000_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	memset(w, 0, sizeof(struct ethtool_wolinfo));
+
+	/* note, we could probably support wake-phy too */
+	w->supported = dm->wake_supported ? WAKE_MAGIC : 0;
+	w->wolopts = dm->wake_state;
+}
+
+static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	unsigned long flags;
+	u32 opts = w->wolopts;
+	u32 wcr = 0;
+
+	if (!dm->wake_supported)
+		return -EOPNOTSUPP;
+
+	if (opts & ~WAKE_MAGIC)
+		return -EINVAL;
+
+	if (opts & WAKE_MAGIC)
+		wcr |= WCR_MAGICEN;
+
+	mutex_lock(&dm->addr_lock);
+
+	spin_lock_irqsave(&dm->lock, flags);
+	iow(dm, DM9000_WCR, wcr);
+	spin_unlock_irqrestore(&dm->lock, flags);
+
+	mutex_unlock(&dm->addr_lock);
+
+	if (dm->wake_state != opts) {
+		/* change in wol state, update IRQ state */
+
+		if (!dm->wake_state)
+			set_irq_wake(dm->irq_wake, 1);
+		else if (dm->wake_state & !opts)
+			set_irq_wake(dm->irq_wake, 0);
+	}
+
+	dm->wake_state = opts;
+	return 0;
+}
+
 static const struct ethtool_ops dm9000_ethtool_ops = {
 	.get_drvinfo		= dm9000_get_drvinfo,
 	.get_settings		= dm9000_get_settings,
@@ -576,6 +628,8 @@ static const struct ethtool_ops dm9000_e
 	.set_msglevel		= dm9000_set_msglevel,
 	.nway_reset		= dm9000_nway_reset,
 	.get_link		= dm9000_get_link,
+	.get_wol		= dm9000_get_wol,
+	.set_wol		= dm9000_set_wol,
  	.get_eeprom_len		= dm9000_get_eeprom_len,
  	.get_eeprom		= dm9000_get_eeprom,
  	.set_eeprom		= dm9000_set_eeprom,
@@ -722,6 +776,7 @@ dm9000_init_dm9000(struct net_device *de
 {
 	board_info_t *db = netdev_priv(dev);
 	unsigned int imr;
+	unsigned int ncr;
 
 	dm9000_dbg(db, 1, "entering %s\n", __func__);
 
@@ -736,8 +791,15 @@ dm9000_init_dm9000(struct net_device *de
 	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
 	iow(db, DM9000_GPR, 0);	/* Enable PHY */
 
-	if (db->flags & DM9000_PLATF_EXT_PHY)
-		iow(db, DM9000_NCR, NCR_EXT_PHY);
+	ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
+
+	/* if wol is needed, then always set NCR_WAKEEN otherwise we end
+	 * up dumping the wake events if we disable this. There is already
+	 * a wake-mask in DM9000_WCR */
+	if (db->wake_supported)
+		ncr |= NCR_WAKEEN;
+
+	iow(db, DM9000_NCR, ncr);
 
 	/* Program operating register */
 	iow(db, DM9000_TCR, 0);	        /* TX Polling clear */
@@ -962,8 +1024,8 @@ dm9000_rx(struct net_device *dev)
 		}
 
 		/* Move data from DM9000 */
-		if (GoodPacket
-		    && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
+		if (GoodPacket &&
+		    ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
 			skb_reserve(skb, 2);
 			rdptr = (u8 *) skb_put(skb, RxLen - 4);
 
@@ -1045,6 +1107,41 @@ static irqreturn_t dm9000_interrupt(int
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t dm9000_wol_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	board_info_t *db = netdev_priv(dev);
+	unsigned long flags;
+	unsigned nsr, wcr;
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	nsr = ior(db, DM9000_NSR);
+	wcr = ior(db, DM9000_WCR);
+
+	dev_dbg(db->dev, "%s: NSR=0x%02x, WCR=0x%02x\n", __func__, nsr, wcr);
+
+	if (nsr & NSR_WAKEST) {
+		/* clear, so we can avoid */
+		iow(db, DM9000_NSR, NSR_WAKEST);
+
+		if (wcr & WCR_LINKST)
+			dev_info(db->dev, "wake by link status change\n");
+		if (wcr & WCR_SAMPLEST)
+			dev_info(db->dev, "wake by sample packet\n");
+		if (wcr & WCR_MAGICST )
+			dev_info(db->dev, "wake by magic packet\n");
+		if (!(wcr & (WCR_LINKST | WCR_SAMPLEST | WCR_MAGICST)))
+			dev_err(db->dev, "wake signalled with no reason? "
+				"NSR=0x%02x, WSR=0x%02x\n", nsr, wcr);
+
+	}
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	return (nsr & NSR_WAKEST) ? IRQ_HANDLED : IRQ_NONE;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  *Used by netconsole
@@ -1078,7 +1175,7 @@ dm9000_open(struct net_device *dev)
 
 	irqflags |= IRQF_SHARED;
 
-	if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
+	if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
 		return -EAGAIN;
 
 	/* Initialize DM9000 board */
@@ -1299,6 +1396,29 @@ dm9000_probe(struct platform_device *pde
 		goto out;
 	}
 
+	db->irq_wake = platform_get_irq(pdev, 1);
+	if (db->irq_wake >= 0) {
+		dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);
+
+		ret = request_irq(db->irq_wake, dm9000_wol_interrupt,
+				  IRQF_SHARED, dev_name(db->dev), ndev);
+		if (ret) {
+			dev_err(db->dev, "cannot get wakeup irq (%d)\n", ret);
+		} else {
+
+			/* test to see if irq is really wakeup capable */
+			ret = set_irq_wake(db->irq_wake, 1);
+			if (ret) {
+				dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",
+					db->irq_wake, ret);
+				ret = 0;
+			} else {
+				set_irq_wake(db->irq_wake, 0);
+				db->wake_supported = 1;
+			}
+		}
+	}
+
 	iosize = resource_size(db->addr_res);
 	db->addr_req = request_mem_region(db->addr_res->start, iosize,
 					  pdev->name);
@@ -1490,10 +1610,14 @@ dm9000_drv_suspend(struct device *dev)
 		db = netdev_priv(ndev);
 		db->in_suspend = 1;
 
-		if (netif_running(ndev)) {
-			netif_device_detach(ndev);
+		if (!netif_running(ndev))
+			return 0;
+
+		netif_device_detach(ndev);
+
+		/* only shutdown if not using WoL */
+		if (!db->wake_state)
 			dm9000_shutdown(ndev);
-		}
 	}
 	return 0;
 }
@@ -1506,10 +1630,13 @@ dm9000_drv_resume(struct device *dev)
 	board_info_t *db = netdev_priv(ndev);
 
 	if (ndev) {
-
 		if (netif_running(ndev)) {
-			dm9000_reset(db);
-			dm9000_init_dm9000(ndev);
+			/* reset if we were not in wake mode to ensure if
+			 * the device was powered off it is in a known state */
+			if (!db->wake_state) {
+				dm9000_reset(db);
+				dm9000_init_dm9000(ndev);
+			}
 
 			netif_device_attach(ndev);
 		}
@@ -1519,7 +1646,7 @@ dm9000_drv_resume(struct device *dev)
 	return 0;
 }
 
-static struct dev_pm_ops dm9000_drv_pm_ops = {
+static const struct dev_pm_ops dm9000_drv_pm_ops = {
 	.suspend	= dm9000_drv_suspend,
 	.resume		= dm9000_drv_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/dm9000.h linux-libre-2.6.33-gnu1/drivers/net/dm9000.h
--- linux-libre-2.6.32-gnu1/drivers/net/dm9000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/dm9000.h	2010-02-24 13:52:17.000000000 -0500
@@ -111,6 +111,13 @@
 #define RSR_CE              (1<<1)
 #define RSR_FOE             (1<<0)
 
+#define WCR_LINKEN		(1 << 5)
+#define WCR_SAMPLEEN		(1 << 4)
+#define WCR_MAGICEN		(1 << 3)
+#define WCR_LINKST		(1 << 2)
+#define WCR_SAMPLEST		(1 << 1)
+#define WCR_MAGICST		(1 << 0)
+
 #define FCTR_HWOT(ot)	(( ot & 0xf ) << 4 )
 #define FCTR_LWOT(ot)	( ot & 0xf )
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,14 +31,22 @@
 #include "e1000.h"
 #include <asm/uaccess.h>
 
+enum {NETDEV_STATS, E1000_STATS};
+
 struct e1000_stats {
 	char stat_string[ETH_GSTRING_LEN];
+	int type;
 	int sizeof_stat;
 	int stat_offset;
 };
 
-#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \
-		      offsetof(struct e1000_adapter, m)
+#define E1000_STAT(m)		E1000_STATS, \
+				sizeof(((struct e1000_adapter *)0)->m), \
+		      		offsetof(struct e1000_adapter, m)
+#define E1000_NETDEV_STAT(m)	NETDEV_STATS, \
+				sizeof(((struct net_device *)0)->m), \
+				offsetof(struct net_device, m)
+
 static const struct e1000_stats e1000_gstrings_stats[] = {
 	{ "rx_packets", E1000_STAT(stats.gprc) },
 	{ "tx_packets", E1000_STAT(stats.gptc) },
@@ -50,19 +58,19 @@ static const struct e1000_stats e1000_gs
 	{ "tx_multicast", E1000_STAT(stats.mptc) },
 	{ "rx_errors", E1000_STAT(stats.rxerrc) },
 	{ "tx_errors", E1000_STAT(stats.txerrc) },
-	{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
+	{ "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
 	{ "multicast", E1000_STAT(stats.mprc) },
 	{ "collisions", E1000_STAT(stats.colc) },
 	{ "rx_length_errors", E1000_STAT(stats.rlerrc) },
-	{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
+	{ "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
 	{ "rx_crc_errors", E1000_STAT(stats.crcerrs) },
-	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
+	{ "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
 	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
 	{ "rx_missed_errors", E1000_STAT(stats.mpc) },
 	{ "tx_aborted_errors", E1000_STAT(stats.ecol) },
 	{ "tx_carrier_errors", E1000_STAT(stats.tncrs) },
-	{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
-	{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
+	{ "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
+	{ "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
 	{ "tx_window_errors", E1000_STAT(stats.latecol) },
 	{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
 	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
@@ -861,10 +869,10 @@ static int e1000_intr_test(struct e1000_
 
 	/* NOTE: we don't test MSI interrupts here, yet */
 	/* Hook up test interrupt handler just for this test */
-	if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
+	if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
 	                 netdev))
 		shared_int = false;
-	else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED,
+	else if (request_irq(irq, e1000_test_intr, IRQF_SHARED,
 	         netdev->name, netdev)) {
 		*data = 1;
 		return -1;
@@ -1830,10 +1838,21 @@ static void e1000_get_ethtool_stats(stru
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int i;
+	char *p = NULL;
 
 	e1000_update_stats(adapter);
 	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
-		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
+		switch (e1000_gstrings_stats[i].type) {
+		case NETDEV_STATS:
+			p = (char *) netdev +
+					e1000_gstrings_stats[i].stat_offset;
+			break;
+		case E1000_STATS:
+			p = (char *) adapter +
+					e1000_gstrings_stats[i].stat_offset;
+			break;
+		}
+
 		data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000.h linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000.h
--- linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000.h	2010-02-24 13:52:17.000000000 -0500
@@ -167,6 +167,7 @@ struct e1000_buffer {
 	unsigned long time_stamp;
 	u16 length;
 	u16 next_to_watch;
+	u16 mapped_as_page;
 };
 
 struct e1000_tx_ring {
@@ -302,7 +303,6 @@ struct e1000_adapter {
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
-	struct net_device_stats net_stats;
 
 	/* structs defined in e1000_hw.h */
 	struct e1000_hw hw;
@@ -326,6 +326,8 @@ struct e1000_adapter {
 	/* for ioport free */
 	int bars;
 	int need_ioport;
+
+	bool discarding;
 };
 
 enum e1000_state_t {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000_main.c linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000/e1000_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000/e1000_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -1698,18 +1698,6 @@ static void e1000_setup_rctl(struct e100
 	rctl &= ~E1000_RCTL_SZ_4096;
 	rctl |= E1000_RCTL_BSEX;
 	switch (adapter->rx_buffer_len) {
-		case E1000_RXBUFFER_256:
-			rctl |= E1000_RCTL_SZ_256;
-			rctl &= ~E1000_RCTL_BSEX;
-			break;
-		case E1000_RXBUFFER_512:
-			rctl |= E1000_RCTL_SZ_512;
-			rctl &= ~E1000_RCTL_BSEX;
-			break;
-		case E1000_RXBUFFER_1024:
-			rctl |= E1000_RCTL_SZ_1024;
-			rctl &= ~E1000_RCTL_BSEX;
-			break;
 		case E1000_RXBUFFER_2048:
 		default:
 			rctl |= E1000_RCTL_SZ_2048;
@@ -1839,10 +1827,17 @@ void e1000_free_all_tx_resources(struct
 static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
 					     struct e1000_buffer *buffer_info)
 {
-	buffer_info->dma = 0;
+	if (buffer_info->dma) {
+		if (buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev, buffer_info->dma,
+				       buffer_info->length, PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev,	buffer_info->dma,
+					 buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
 	if (buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
@@ -2683,22 +2678,14 @@ static int e1000_tx_map(struct e1000_ada
 			unsigned int mss)
 {
 	struct e1000_hw *hw = &adapter->hw;
+	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_buffer *buffer_info;
 	unsigned int len = skb_headlen(skb);
-	unsigned int offset, size, count = 0, i;
+	unsigned int offset = 0, size, count = 0, i;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-	offset = 0;
-
 	while (len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
@@ -2735,7 +2722,11 @@ static int e1000_tx_map(struct e1000_ada
 		buffer_info->length = size;
 		/* set time_stamp *before* dma to help avoid a possible race */
 		buffer_info->time_stamp = jiffies;
-		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
+		buffer_info->mapped_as_page = false;
+		buffer_info->dma = pci_map_single(pdev,	skb->data + offset,
+						  size,	PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma))
+			goto dma_error;
 		buffer_info->next_to_watch = i;
 
 		len -= size;
@@ -2753,7 +2744,7 @@ static int e1000_tx_map(struct e1000_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = 0;
+		offset = frag->page_offset;
 
 		while (len) {
 			i++;
@@ -2777,7 +2768,12 @@ static int e1000_tx_map(struct e1000_ada
 
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
-			buffer_info->dma = map[f] + offset;
+			buffer_info->mapped_as_page = true;
+			buffer_info->dma = pci_map_page(pdev, frag->page,
+							offset,	size,
+							PCI_DMA_TODEVICE);
+			if (pci_dma_mapping_error(pdev, buffer_info->dma))
+				goto dma_error;
 			buffer_info->next_to_watch = i;
 
 			len -= size;
@@ -2790,6 +2786,22 @@ static int e1000_tx_map(struct e1000_ada
 	tx_ring->buffer_info[first].next_to_watch = i;
 
 	return count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+	buffer_info->dma = 0;
+	if (count)
+		count--;
+
+	while (count--) {
+		if (i==0)
+			i += tx_ring->count;
+		i--;
+		buffer_info = &tx_ring->buffer_info[i];
+		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
+	}
+
+	return 0;
 }
 
 static void e1000_tx_queue(struct e1000_adapter *adapter,
@@ -3101,10 +3113,8 @@ static void e1000_reset_task(struct work
 
 static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-
 	/* only return the current stats */
-	return &adapter->net_stats;
+	return &netdev->stats;
 }
 
 /**
@@ -3154,13 +3164,7 @@ static int e1000_change_mtu(struct net_d
 	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
 	 *  fragmented skbs */
 
-	if (max_frame <= E1000_RXBUFFER_256)
-		adapter->rx_buffer_len = E1000_RXBUFFER_256;
-	else if (max_frame <= E1000_RXBUFFER_512)
-		adapter->rx_buffer_len = E1000_RXBUFFER_512;
-	else if (max_frame <= E1000_RXBUFFER_1024)
-		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
-	else if (max_frame <= E1000_RXBUFFER_2048)
+	if (max_frame <= E1000_RXBUFFER_2048)
 		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
 	else
 #if (PAGE_SIZE >= E1000_RXBUFFER_16384)
@@ -3196,6 +3200,7 @@ static int e1000_change_mtu(struct net_d
 
 void e1000_update_stats(struct e1000_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
 	unsigned long flags;
@@ -3288,32 +3293,32 @@ void e1000_update_stats(struct e1000_ada
 	}
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.multicast = adapter->stats.mprc;
-	adapter->net_stats.collisions = adapter->stats.colc;
+	netdev->stats.multicast = adapter->stats.mprc;
+	netdev->stats.collisions = adapter->stats.colc;
 
 	/* Rx Errors */
 
 	/* RLEC on some newer hardware can be incorrect so build
 	* our own version based on RUC and ROC */
-	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+	netdev->stats.rx_errors = adapter->stats.rxerrc +
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.ruc + adapter->stats.roc +
 		adapter->stats.cexterr;
 	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
-	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
-	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
+	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
+	netdev->stats.rx_missed_errors = adapter->stats.mpc;
 
 	/* Tx Errors */
 	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
-	adapter->net_stats.tx_errors = adapter->stats.txerrc;
-	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
-	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
-	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+	netdev->stats.tx_errors = adapter->stats.txerrc;
+	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
+	netdev->stats.tx_window_errors = adapter->stats.latecol;
+	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
 	if (hw->bad_tx_carr_stats_fd &&
 	    adapter->link_duplex == FULL_DUPLEX) {
-		adapter->net_stats.tx_carrier_errors = 0;
+		netdev->stats.tx_carrier_errors = 0;
 		adapter->stats.tncrs = 0;
 	}
 
@@ -3484,8 +3489,8 @@ static bool e1000_clean_tx_irq(struct e1
 		adapter->detect_tx_hung = false;
 		if (tx_ring->buffer_info[eop].time_stamp &&
 		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
-		               (adapter->tx_timeout_factor * HZ))
-		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+		               (adapter->tx_timeout_factor * HZ)) &&
+		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 
 			/* detected Tx unit hang */
 			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
@@ -3514,8 +3519,8 @@ static bool e1000_clean_tx_irq(struct e1
 	}
 	adapter->total_tx_bytes += total_tx_bytes;
 	adapter->total_tx_packets += total_tx_packets;
-	adapter->net_stats.tx_bytes += total_tx_bytes;
-	adapter->net_stats.tx_packets += total_tx_packets;
+	netdev->stats.tx_bytes += total_tx_bytes;
+	netdev->stats.tx_packets += total_tx_packets;
 	return (count < tx_ring->count);
 }
 
@@ -3767,8 +3772,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -3827,13 +3832,22 @@ static bool e1000_clean_rx_irq(struct e1
 
 		length = le16_to_cpu(rx_desc->length);
 		/* !EOP means multiple descriptors were used to store a single
-		 * packet, also make sure the frame isn't just CRC only */
-		if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
+		 * packet, if thats the case we need to toss it.  In fact, we
+		 * to toss every packet with the EOP bit clear and the next
+		 * frame that _does_ have the EOP bit set, as it is by
+		 * definition only a frame fragment
+		 */
+		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+			adapter->discarding = true;
+
+		if (adapter->discarding) {
 			/* All receives must fit into a single buffer */
 			E1000_DBG("%s: Receive packet consumed multiple"
 				  " buffers\n", netdev->name);
 			/* recycle */
 			buffer_info->skb = skb;
+			if (status & E1000_RXD_STAT_EOP)
+				adapter->discarding = false;
 			goto next_desc;
 		}
 
@@ -3867,9 +3881,8 @@ static bool e1000_clean_rx_irq(struct e1
 		 * of reassembly being done in the stack */
 		if (length < copybreak) {
 			struct sk_buff *new_skb =
-			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
+			    netdev_alloc_skb_ip_align(netdev, length);
 			if (new_skb) {
-				skb_reserve(new_skb, NET_IP_ALIGN);
 				skb_copy_to_linear_data_offset(new_skb,
 							       -NET_IP_ALIGN,
 							       (skb->data -
@@ -3916,8 +3929,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -3938,9 +3951,7 @@ e1000_alloc_jumbo_rx_buffers(struct e100
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
-	unsigned int bufsz = 256 -
-	                     16 /*for skb_reserve */ -
-	                     NET_IP_ALIGN;
+	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
 
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -3952,7 +3963,7 @@ e1000_alloc_jumbo_rx_buffers(struct e100
 			goto check_page;
 		}
 
-		skb = netdev_alloc_skb(netdev, bufsz);
+		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 		if (unlikely(!skb)) {
 			/* Better luck next round */
 			adapter->alloc_rx_buff_failed++;
@@ -3965,7 +3976,7 @@ e1000_alloc_jumbo_rx_buffers(struct e100
 			DPRINTK(PROBE, ERR, "skb align check failed: %u bytes "
 					     "at %p\n", bufsz, skb->data);
 			/* Try again, without freeing the previous */
-			skb = netdev_alloc_skb(netdev, bufsz);
+			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 			/* Failed allocation, critical failure */
 			if (!skb) {
 				dev_kfree_skb(oldskb);
@@ -3983,12 +3994,6 @@ e1000_alloc_jumbo_rx_buffers(struct e100
 			/* Use new allocation */
 			dev_kfree_skb(oldskb);
 		}
-		/* Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 check_page:
@@ -4001,11 +4006,21 @@ check_page:
 			}
 		}
 
-		if (!buffer_info->dma)
+		if (!buffer_info->dma) {
 			buffer_info->dma = pci_map_page(pdev,
 			                                buffer_info->page, 0,
 			                                buffer_info->length,
 			                                PCI_DMA_FROMDEVICE);
+			if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+				put_page(buffer_info->page);
+				dev_kfree_skb(skb);
+				buffer_info->page = NULL;
+				buffer_info->skb = NULL;
+				buffer_info->dma = 0;
+				adapter->alloc_rx_buff_failed++;
+				break; /* while !buffer_info->skb */
+			}
+		}
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -4045,7 +4060,7 @@ static void e1000_alloc_rx_buffers(struc
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
-	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+	unsigned int bufsz = adapter->rx_buffer_len;
 
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -4057,7 +4072,7 @@ static void e1000_alloc_rx_buffers(struc
 			goto map_skb;
 		}
 
-		skb = netdev_alloc_skb(netdev, bufsz);
+		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 		if (unlikely(!skb)) {
 			/* Better luck next round */
 			adapter->alloc_rx_buff_failed++;
@@ -4070,7 +4085,7 @@ static void e1000_alloc_rx_buffers(struc
 			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
 					     "at %p\n", bufsz, skb->data);
 			/* Try again, without freeing the previous */
-			skb = netdev_alloc_skb(netdev, bufsz);
+			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 			/* Failed allocation, critical failure */
 			if (!skb) {
 				dev_kfree_skb(oldskb);
@@ -4089,12 +4104,6 @@ static void e1000_alloc_rx_buffers(struc
 			/* Use new allocation */
 			dev_kfree_skb(oldskb);
 		}
-		/* Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 map_skb:
@@ -4102,6 +4111,13 @@ map_skb:
 						  skb->data,
 						  buffer_info->length,
 						  PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+			dev_kfree_skb(skb);
+			buffer_info->skb = NULL;
+			buffer_info->dma = 0;
+			adapter->alloc_rx_buff_failed++;
+			break; /* while !buffer_info->skb */
+		}
 
 		/*
 		 * XXX if it was allocated cleanly it will never map to a
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/82571.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/82571.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/82571.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/82571.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -43,10 +43,6 @@
  * 82583V Gigabit Network Connection
  */
 
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
 #include "e1000.h"
 
 #define ID_LED_RESERVED_F746 0xF746
@@ -69,15 +65,15 @@ static s32 e1000_fix_nvm_checksum_82571(
 static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
 static s32 e1000_setup_link_82571(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+static void e1000_clear_vfta_82571(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
 static s32 e1000_led_on_82574(struct e1000_hw *hw);
 static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
+static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
 
 /**
  *  e1000_init_phy_params_82571 - Init PHY func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 {
@@ -93,6 +89,9 @@ static s32 e1000_init_phy_params_82571(s
 	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;
+
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
@@ -140,8 +139,6 @@ static s32 e1000_init_phy_params_82571(s
 /**
  *  e1000_init_nvm_params_82571 - Init NVM func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
 {
@@ -205,8 +202,6 @@ static s32 e1000_init_nvm_params_82571(s
 /**
  *  e1000_init_mac_params_82571 - Init MAC func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 {
@@ -240,7 +235,10 @@ static s32 e1000_init_mac_params_82571(s
 	/* Set rar entry count */
 	mac->rar_entry_count = E1000_RAR_ENTRIES;
 	/* Set if manageability features are enabled. */
-	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
+	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
+	                ? true : false;
+	/* Adaptive IFS supported */
+	mac->adaptive_ifs = true;
 
 	/* check for link */
 	switch (hw->phy.media_type) {
@@ -313,7 +311,7 @@ static s32 e1000_init_mac_params_82571(s
 			 * indicates that the bootagent or EFI code has
 			 * improperly left this bit enabled
 			 */
-			hw_dbg(hw, "Please update your 82571 Bootagent\n");
+			e_dbg("Please update your 82571 Bootagent\n");
 		}
 		ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
 	}
@@ -487,7 +485,7 @@ static s32 e1000_get_hw_semaphore_82571(
 	}
 
 	if (i == sw_timeout) {
-		hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+		e_dbg("Driver can't access device - SMBI bit is set.\n");
 		hw->dev_spec.e82571.smb_counter++;
 	}
 	/* Get the FW semaphore. */
@@ -505,7 +503,7 @@ static s32 e1000_get_hw_semaphore_82571(
 	if (i == fw_timeout) {
 		/* Release semaphores */
 		e1000_put_hw_semaphore_82571(hw);
-		hw_dbg(hw, "Driver can't access the NVM\n");
+		e_dbg("Driver can't access the NVM\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -702,8 +700,7 @@ static s32 e1000_write_nvm_eewr_82571(st
 				      u16 words, u16 *data)
 {
 	struct e1000_nvm_info *nvm = &hw->nvm;
-	u32 i;
-	u32 eewr = 0;
+	u32 i, eewr = 0;
 	s32 ret_val = 0;
 
 	/*
@@ -712,7 +709,7 @@ static s32 e1000_write_nvm_eewr_82571(st
 	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
-		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+		e_dbg("nvm parameter(s) out of bounds\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -753,7 +750,7 @@ static s32 e1000_get_cfg_done_82571(stru
 		timeout--;
 	}
 	if (!timeout) {
-		hw_dbg(hw, "MNG configuration cycle has not completed.\n");
+		e_dbg("MNG configuration cycle has not completed.\n");
 		return -E1000_ERR_RESET;
 	}
 
@@ -763,7 +760,7 @@ static s32 e1000_get_cfg_done_82571(stru
 /**
  *  e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state
  *  @hw: pointer to the HW structure
- *  @active: TRUE to enable LPLU, FALSE to disable
+ *  @active: true to enable LPLU, false to disable
  *
  *  Sets the LPLU D0 state according to the active flag.  When activating LPLU
  *  this function also disables smart speed and vice versa.  LPLU will not be
@@ -834,15 +831,11 @@ static s32 e1000_set_d0_lplu_state_82571
  *  e1000_reset_hw_82571 - Reset hardware
  *  @hw: pointer to the HW structure
  *
- *  This resets the hardware into a known state.  This is a
- *  function pointer entry point called by the api module.
+ *  This resets the hardware into a known state.
  **/
 static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 {
-	u32 ctrl;
-	u32 extcnf_ctrl;
-	u32 ctrl_ext;
-	u32 icr;
+	u32 ctrl, extcnf_ctrl, ctrl_ext, icr;
 	s32 ret_val;
 	u16 i = 0;
 
@@ -852,9 +845,9 @@ static s32 e1000_reset_hw_82571(struct e
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
 	if (ret_val)
-		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+		e_dbg("PCI-E Master disable polling has failed.\n");
 
-	hw_dbg(hw, "Masking off all interrupts\n");
+	e_dbg("Masking off all interrupts\n");
 	ew32(IMC, 0xffffffff);
 
 	ew32(RCTL, 0);
@@ -893,7 +886,7 @@ static s32 e1000_reset_hw_82571(struct e
 
 	ctrl = er32(CTRL);
 
-	hw_dbg(hw, "Issuing a global reset to MAC\n");
+	e_dbg("Issuing a global reset to MAC\n");
 	ew32(CTRL, ctrl | E1000_CTRL_RST);
 
 	if (hw->nvm.type == e1000_nvm_flash_hw) {
@@ -951,21 +944,19 @@ static s32 e1000_init_hw_82571(struct e1
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 reg_data;
 	s32 ret_val;
-	u16 i;
-	u16 rar_count = mac->rar_entry_count;
+	u16 i, rar_count = mac->rar_entry_count;
 
 	e1000_initialize_hw_bits_82571(hw);
 
 	/* Initialize identification LED */
 	ret_val = e1000e_id_led_init(hw);
-	if (ret_val) {
-		hw_dbg(hw, "Error initializing identification LED\n");
-		return ret_val;
-	}
+	if (ret_val)
+		e_dbg("Error initializing identification LED\n");
+		/* This is not fatal and we should not stop init due to this */
 
 	/* Disabling VLAN filtering */
-	hw_dbg(hw, "Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	e_dbg("Initializing the IEEE VLAN\n");
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	/*
@@ -978,7 +969,7 @@ static s32 e1000_init_hw_82571(struct e1
 	e1000e_init_rx_addrs(hw, rar_count);
 
 	/* Zero out the Multicast HASH table */
-	hw_dbg(hw, "Zeroing the MTA\n");
+	e_dbg("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
 
@@ -1125,6 +1116,13 @@ static void e1000_initialize_hw_bits_825
 		reg |= (1 << 22);
 		ew32(GCR, reg);
 
+		/*
+		 * Workaround for hardware errata.
+		 * apply workaround for hardware errata documented in errata
+		 * docs Fixes issue where some error prone or unreliable PCIe
+		 * completions are occurring, particularly with ASPM enabled.
+		 * Without fix, issue can cause tx timeouts.
+		 */
 		reg = er32(GCR2);
 		reg |= 1;
 		ew32(GCR2, reg);
@@ -1137,13 +1135,13 @@ static void e1000_initialize_hw_bits_825
 }
 
 /**
- *  e1000e_clear_vfta - Clear VLAN filter table
+ *  e1000_clear_vfta_82571 - Clear VLAN filter table
  *  @hw: pointer to the HW structure
  *
  *  Clears the register array which contains the VLAN filter table by
  *  setting all the values to 0.
  **/
-void e1000e_clear_vfta(struct e1000_hw *hw)
+static void e1000_clear_vfta_82571(struct e1000_hw *hw)
 {
 	u32 offset;
 	u32 vfta_value = 0;
@@ -1294,7 +1292,6 @@ static s32 e1000_setup_link_82571(struct
 static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
 {
 	u32 ctrl;
-	u32 led_ctrl;
 	s32 ret_val;
 
 	ctrl = er32(CTRL);
@@ -1309,11 +1306,6 @@ static s32 e1000_setup_copper_link_82571
 		break;
 	case e1000_phy_igp_2:
 		ret_val = e1000e_copper_link_setup_igp(hw);
-		/* Setup activity LED */
-		led_ctrl = er32(LEDCTL);
-		led_ctrl &= IGP_ACTIVITY_LED_MASK;
-		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-		ew32(LEDCTL, led_ctrl);
 		break;
 	default:
 		return -E1000_ERR_PHY;
@@ -1360,8 +1352,20 @@ static s32 e1000_setup_fiber_serdes_link
  *  e1000_check_for_serdes_link_82571 - Check for link (Serdes)
  *  @hw: pointer to the HW structure
  *
- *  Checks for link up on the hardware.  If link is not up and we have
- *  a signal, then we need to force link up.
+ *  Reports the link state as up or down.
+ *
+ *  If autonegotiation is supported by the link partner, the link state is
+ *  determined by the result of autonegotiation. This is the most likely case.
+ *  If autonegotiation is not supported by the link partner, and the link
+ *  has a valid signal, force the link up.
+ *
+ *  The link state is represented internally here by 4 states:
+ *
+ *  1) down
+ *  2) autoneg_progress
+ *  3) autoneg_complete (the link sucessfully autonegotiated)
+ *  4) forced_up (the link has been forced up, it did not autonegotiate)
+ *
  **/
 static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 {
@@ -1387,7 +1391,8 @@ static s32 e1000_check_for_serdes_link_8
 				 */
 				mac->serdes_link_state =
 				    e1000_serdes_link_autoneg_progress;
-				hw_dbg(hw, "AN_UP     -> AN_PROG\n");
+				mac->serdes_has_link = false;
+				e_dbg("AN_UP     -> AN_PROG\n");
 			}
 		break;
 
@@ -1401,79 +1406,86 @@ static s32 e1000_check_for_serdes_link_8
 			if (rxcw & E1000_RXCW_C) {
 				/* Enable autoneg, and unforce link up */
 				ew32(TXCW, mac->txcw);
-				ew32(CTRL,
-				    (ctrl & ~E1000_CTRL_SLU));
+				ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 				mac->serdes_link_state =
 				    e1000_serdes_link_autoneg_progress;
-				hw_dbg(hw, "FORCED_UP -> AN_PROG\n");
+				mac->serdes_has_link = false;
+				e_dbg("FORCED_UP -> AN_PROG\n");
 			}
 			break;
 
 		case e1000_serdes_link_autoneg_progress:
-			/*
-			 * If the LU bit is set in the STATUS register,
-			 * autoneg has completed sucessfully. If not,
-			 * try foring the link because the far end may be
-			 * available but not capable of autonegotiation.
-			 */
-			if (status & E1000_STATUS_LU)  {
-				mac->serdes_link_state =
-				    e1000_serdes_link_autoneg_complete;
-				hw_dbg(hw, "AN_PROG   -> AN_UP\n");
+			if (rxcw & E1000_RXCW_C) {
+				/*
+				 * We received /C/ ordered sets, meaning the
+				 * link partner has autonegotiated, and we can
+				 * trust the Link Up (LU) status bit.
+				 */
+				if (status & E1000_STATUS_LU) {
+					mac->serdes_link_state =
+					    e1000_serdes_link_autoneg_complete;
+					e_dbg("AN_PROG   -> AN_UP\n");
+					mac->serdes_has_link = true;
+				} else {
+					/* Autoneg completed, but failed. */
+					mac->serdes_link_state =
+					    e1000_serdes_link_down;
+					e_dbg("AN_PROG   -> DOWN\n");
+				}
 			} else {
 				/*
-				 * Disable autoneg, force link up and
-				 * full duplex, and change state to forced
+				 * The link partner did not autoneg.
+				 * Force link up and full duplex, and change
+				 * state to forced.
 				 */
-				ew32(TXCW,
-				    (mac->txcw & ~E1000_TXCW_ANE));
+				ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
 				ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
 				ew32(CTRL, ctrl);
 
 				/* Configure Flow Control after link up. */
-				ret_val =
-				    e1000e_config_fc_after_link_up(hw);
+				ret_val = e1000e_config_fc_after_link_up(hw);
 				if (ret_val) {
-					hw_dbg(hw, "Error config flow control\n");
+					e_dbg("Error config flow control\n");
 					break;
 				}
 				mac->serdes_link_state =
 				    e1000_serdes_link_forced_up;
-				hw_dbg(hw, "AN_PROG   -> FORCED_UP\n");
+				mac->serdes_has_link = true;
+				e_dbg("AN_PROG   -> FORCED_UP\n");
 			}
-			mac->serdes_has_link = true;
 			break;
 
 		case e1000_serdes_link_down:
 		default:
-			/* The link was down but the receiver has now gained
+			/*
+			 * The link was down but the receiver has now gained
 			 * valid sync, so lets see if we can bring the link
-			 * up. */
+			 * up.
+			 */
 			ew32(TXCW, mac->txcw);
-			ew32(CTRL,
-			    (ctrl & ~E1000_CTRL_SLU));
+			ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 			mac->serdes_link_state =
 			    e1000_serdes_link_autoneg_progress;
-			hw_dbg(hw, "DOWN      -> AN_PROG\n");
+			e_dbg("DOWN      -> AN_PROG\n");
 			break;
 		}
 	} else {
 		if (!(rxcw & E1000_RXCW_SYNCH)) {
 			mac->serdes_has_link = false;
 			mac->serdes_link_state = e1000_serdes_link_down;
-			hw_dbg(hw, "ANYSTATE  -> DOWN\n");
+			e_dbg("ANYSTATE  -> DOWN\n");
 		} else {
 			/*
-			 * We have sync, and can tolerate one
-			 * invalid (IV) codeword before declaring
-			 * link down, so reread to look again
+			 * We have sync, and can tolerate one invalid (IV)
+			 * codeword before declaring link down, so reread
+			 * to look again.
 			 */
 			udelay(10);
 			rxcw = er32(RXCW);
 			if (rxcw & E1000_RXCW_IV) {
 				mac->serdes_link_state = e1000_serdes_link_down;
 				mac->serdes_has_link = false;
-				hw_dbg(hw, "ANYSTATE  -> DOWN\n");
+				e_dbg("ANYSTATE  -> DOWN\n");
 			}
 		}
 	}
@@ -1495,7 +1507,7 @@ static s32 e1000_valid_led_default_82571
 
 	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 
@@ -1525,7 +1537,7 @@ static s32 e1000_valid_led_default_82571
 bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
 {
 	if (hw->mac.type != e1000_82571)
-		return 0;
+		return false;
 
 	return hw->dev_spec.e82571.laa_is_present;
 }
@@ -1535,7 +1547,7 @@ bool e1000e_get_laa_state_82571(struct e
  *  @hw: pointer to the HW structure
  *  @state: enable/disable locally administered address
  *
- *  Enable/Disable the current locally administers address state.
+ *  Enable/Disable the current locally administered address state.
  **/
 void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
 {
@@ -1609,6 +1621,28 @@ static s32 e1000_fix_nvm_checksum_82571(
 }
 
 /**
+ * e1000_power_down_phy_copper_82571 - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	struct e1000_mac_info *mac = &hw->mac;
+
+	if (!(phy->ops.check_reset_block))
+		return;
+
+	/* If the management interface is not enabled, then power down */
+	if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
@@ -1616,44 +1650,42 @@ static s32 e1000_fix_nvm_checksum_82571(
  **/
 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
 {
-	u32 temp;
-
 	e1000e_clear_hw_cntrs_base(hw);
 
-	temp = er32(PRC64);
-	temp = er32(PRC127);
-	temp = er32(PRC255);
-	temp = er32(PRC511);
-	temp = er32(PRC1023);
-	temp = er32(PRC1522);
-	temp = er32(PTC64);
-	temp = er32(PTC127);
-	temp = er32(PTC255);
-	temp = er32(PTC511);
-	temp = er32(PTC1023);
-	temp = er32(PTC1522);
+	er32(PRC64);
+	er32(PRC127);
+	er32(PRC255);
+	er32(PRC511);
+	er32(PRC1023);
+	er32(PRC1522);
+	er32(PTC64);
+	er32(PTC127);
+	er32(PTC255);
+	er32(PTC511);
+	er32(PTC1023);
+	er32(PTC1522);
 
-	temp = er32(ALGNERRC);
-	temp = er32(RXERRC);
-	temp = er32(TNCRS);
-	temp = er32(CEXTERR);
-	temp = er32(TSCTC);
-	temp = er32(TSCTFC);
+	er32(ALGNERRC);
+	er32(RXERRC);
+	er32(TNCRS);
+	er32(CEXTERR);
+	er32(TSCTC);
+	er32(TSCTFC);
 
-	temp = er32(MGTPRC);
-	temp = er32(MGTPDC);
-	temp = er32(MGTPTC);
+	er32(MGTPRC);
+	er32(MGTPDC);
+	er32(MGTPTC);
 
-	temp = er32(IAC);
-	temp = er32(ICRXOC);
+	er32(IAC);
+	er32(ICRXOC);
 
-	temp = er32(ICRXPTC);
-	temp = er32(ICRXATC);
-	temp = er32(ICTXPTC);
-	temp = er32(ICTXATC);
-	temp = er32(ICTXQEC);
-	temp = er32(ICTXQMTC);
-	temp = er32(ICRXDMTC);
+	er32(ICRXPTC);
+	er32(ICRXATC);
+	er32(ICTXPTC);
+	er32(ICTXATC);
+	er32(ICTXQEC);
+	er32(ICTXQMTC);
+	er32(ICRXDMTC);
 }
 
 static struct e1000_mac_operations e82571_mac_ops = {
@@ -1667,6 +1699,8 @@ static struct e1000_mac_operations e8257
 	/* .led_on: mac type dependent */
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000_update_mc_addr_list_82571,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_82571,
 	.reset_hw		= e1000_reset_hw_82571,
 	.init_hw		= e1000_init_hw_82571,
 	.setup_link		= e1000_setup_link_82571,
@@ -1675,64 +1709,67 @@ static struct e1000_mac_operations e8257
 };
 
 static struct e1000_phy_operations e82_phy_ops_igp = {
-	.acquire_phy		= e1000_get_hw_semaphore_82571,
+	.acquire		= e1000_get_hw_semaphore_82571,
+	.check_polarity		= e1000_check_polarity_igp,
 	.check_reset_block	= e1000e_check_reset_block_generic,
-	.commit_phy		= NULL,
+	.commit			= NULL,
 	.force_speed_duplex	= e1000e_phy_force_speed_duplex_igp,
 	.get_cfg_done		= e1000_get_cfg_done_82571,
 	.get_cable_length	= e1000e_get_cable_length_igp_2,
-	.get_phy_info		= e1000e_get_phy_info_igp,
-	.read_phy_reg		= e1000e_read_phy_reg_igp,
-	.release_phy		= e1000_put_hw_semaphore_82571,
-	.reset_phy		= e1000e_phy_hw_reset_generic,
+	.get_info		= e1000e_get_phy_info_igp,
+	.read_reg		= e1000e_read_phy_reg_igp,
+	.release		= e1000_put_hw_semaphore_82571,
+	.reset			= e1000e_phy_hw_reset_generic,
 	.set_d0_lplu_state	= e1000_set_d0_lplu_state_82571,
 	.set_d3_lplu_state	= e1000e_set_d3_lplu_state,
-	.write_phy_reg		= e1000e_write_phy_reg_igp,
+	.write_reg		= e1000e_write_phy_reg_igp,
 	.cfg_on_link_up      	= NULL,
 };
 
 static struct e1000_phy_operations e82_phy_ops_m88 = {
-	.acquire_phy		= e1000_get_hw_semaphore_82571,
+	.acquire		= e1000_get_hw_semaphore_82571,
+	.check_polarity		= e1000_check_polarity_m88,
 	.check_reset_block	= e1000e_check_reset_block_generic,
-	.commit_phy		= e1000e_phy_sw_reset,
+	.commit			= e1000e_phy_sw_reset,
 	.force_speed_duplex	= e1000e_phy_force_speed_duplex_m88,
 	.get_cfg_done		= e1000e_get_cfg_done,
 	.get_cable_length	= e1000e_get_cable_length_m88,
-	.get_phy_info		= e1000e_get_phy_info_m88,
-	.read_phy_reg		= e1000e_read_phy_reg_m88,
-	.release_phy		= e1000_put_hw_semaphore_82571,
-	.reset_phy		= e1000e_phy_hw_reset_generic,
+	.get_info		= e1000e_get_phy_info_m88,
+	.read_reg		= e1000e_read_phy_reg_m88,
+	.release		= e1000_put_hw_semaphore_82571,
+	.reset			= e1000e_phy_hw_reset_generic,
 	.set_d0_lplu_state	= e1000_set_d0_lplu_state_82571,
 	.set_d3_lplu_state	= e1000e_set_d3_lplu_state,
-	.write_phy_reg		= e1000e_write_phy_reg_m88,
+	.write_reg		= e1000e_write_phy_reg_m88,
 	.cfg_on_link_up      	= NULL,
 };
 
 static struct e1000_phy_operations e82_phy_ops_bm = {
-	.acquire_phy		= e1000_get_hw_semaphore_82571,
+	.acquire		= e1000_get_hw_semaphore_82571,
+	.check_polarity		= e1000_check_polarity_m88,
 	.check_reset_block	= e1000e_check_reset_block_generic,
-	.commit_phy		= e1000e_phy_sw_reset,
+	.commit			= e1000e_phy_sw_reset,
 	.force_speed_duplex	= e1000e_phy_force_speed_duplex_m88,
 	.get_cfg_done		= e1000e_get_cfg_done,
 	.get_cable_length	= e1000e_get_cable_length_m88,
-	.get_phy_info		= e1000e_get_phy_info_m88,
-	.read_phy_reg		= e1000e_read_phy_reg_bm2,
-	.release_phy		= e1000_put_hw_semaphore_82571,
-	.reset_phy		= e1000e_phy_hw_reset_generic,
+	.get_info		= e1000e_get_phy_info_m88,
+	.read_reg		= e1000e_read_phy_reg_bm2,
+	.release		= e1000_put_hw_semaphore_82571,
+	.reset			= e1000e_phy_hw_reset_generic,
 	.set_d0_lplu_state	= e1000_set_d0_lplu_state_82571,
 	.set_d3_lplu_state	= e1000e_set_d3_lplu_state,
-	.write_phy_reg		= e1000e_write_phy_reg_bm2,
+	.write_reg		= e1000e_write_phy_reg_bm2,
 	.cfg_on_link_up      	= NULL,
 };
 
 static struct e1000_nvm_operations e82571_nvm_ops = {
-	.acquire_nvm		= e1000_acquire_nvm_82571,
-	.read_nvm		= e1000e_read_nvm_eerd,
-	.release_nvm		= e1000_release_nvm_82571,
-	.update_nvm		= e1000_update_nvm_checksum_82571,
+	.acquire		= e1000_acquire_nvm_82571,
+	.read			= e1000e_read_nvm_eerd,
+	.release		= e1000_release_nvm_82571,
+	.update			= e1000_update_nvm_checksum_82571,
 	.valid_led_default	= e1000_valid_led_default_82571,
-	.validate_nvm		= e1000_validate_nvm_checksum_82571,
-	.write_nvm		= e1000_write_nvm_82571,
+	.validate		= e1000_validate_nvm_checksum_82571,
+	.write			= e1000_write_nvm_82571,
 };
 
 struct e1000_info e1000_82571_info = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/defines.h linux-libre-2.6.33-gnu1/drivers/net/e1000e/defines.h
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/defines.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/defines.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -74,7 +74,7 @@
 #define E1000_WUS_BC           E1000_WUFC_BC
 
 /* Extended Device Control */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
+#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
 #define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
 #define E1000_CTRL_EXT_SPD_BYPS  0x00008000 /* Speed Select Bypass */
 #define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/e1000.h linux-libre-2.6.33-gnu1/drivers/net/e1000e/e1000.h
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/e1000.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/e1000.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -36,6 +36,7 @@
 #include <linux/workqueue.h>
 #include <linux/io.h>
 #include <linux/netdevice.h>
+#include <linux/pci.h>
 
 #include "hw.h"
 
@@ -47,9 +48,9 @@ struct e1000_info;
 
 #ifdef DEBUG
 #define e_dbg(format, arg...) \
-	e_printk(KERN_DEBUG , adapter, format, ## arg)
+	e_printk(KERN_DEBUG , hw->adapter, format, ## arg)
 #else
-#define e_dbg(format, arg...) do { (void)(adapter); } while (0)
+#define e_dbg(format, arg...) do { (void)(hw); } while (0)
 #endif
 
 #define e_err(format, arg...) \
@@ -193,12 +194,15 @@ struct e1000_buffer {
 			unsigned long time_stamp;
 			u16 length;
 			u16 next_to_watch;
+			u16 mapped_as_page;
 		};
 		/* Rx */
-		/* arrays of page information for packet split */
-		struct e1000_ps_page *ps_pages;
+		struct {
+			/* arrays of page information for packet split */
+			struct e1000_ps_page *ps_pages;
+			struct page *page;
+		};
 	};
-	struct page *page;
 };
 
 struct e1000_ring {
@@ -331,7 +335,6 @@ struct e1000_adapter {
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
-	struct net_device_stats net_stats;
 
 	/* structs defined in e1000_hw.h */
 	struct e1000_hw hw;
@@ -366,6 +369,7 @@ struct e1000_adapter {
 	struct work_struct downshift_task;
 	struct work_struct update_phy_task;
 	struct work_struct led_blink_task;
+	struct work_struct print_hang_task;
 };
 
 struct e1000_info {
@@ -417,6 +421,7 @@ struct e1000_info {
 /* CRC Stripping defines */
 #define FLAG2_CRC_STRIPPING               (1 << 0)
 #define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
+#define FLAG2_IS_DISCARDING               (1 << 2)
 
 #define E1000_RX_DESC_PS(R, i)	    \
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -488,6 +493,7 @@ extern void e1000e_set_kmrn_lock_loss_wo
 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
 extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
 extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
+extern s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
 
 extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
 extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
@@ -507,7 +513,7 @@ extern s32 e1000e_setup_fiber_serdes_lin
 extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
 extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
 extern s32 e1000e_setup_link(struct e1000_hw *hw);
-extern void e1000e_clear_vfta(struct e1000_hw *hw);
+extern void e1000_clear_vfta_generic(struct e1000_hw *hw);
 extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
 					       u8 *mc_addr_list,
@@ -523,7 +529,7 @@ extern void e1000e_config_collision_dist
 extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
 extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
 extern s32 e1000e_blink_led(struct e1000_hw *hw);
-extern void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
+extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
 extern void e1000e_reset_adaptive(struct e1000_hw *hw);
 extern void e1000e_update_adaptive(struct e1000_hw *hw);
 
@@ -566,6 +572,8 @@ extern s32 e1000e_read_kmrn_reg_locked(s
 extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success);
 extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
+extern void e1000_power_up_phy_copper(struct e1000_hw *hw);
+extern void e1000_power_down_phy_copper(struct e1000_hw *hw);
 extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_check_downshift(struct e1000_hw *hw);
@@ -575,7 +583,6 @@ extern s32 e1000_read_phy_reg_hv_locked(
 extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
                                          u16 data);
-extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
 extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
 extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
 extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
@@ -583,9 +590,15 @@ extern s32 e1000_get_phy_info_82577(stru
 extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
 extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
 
+extern s32 e1000_check_polarity_m88(struct e1000_hw *hw);
+extern s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
+extern s32 e1000_check_polarity_ife(struct e1000_hw *hw);
+extern s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
+extern s32 e1000_check_polarity_igp(struct e1000_hw *hw);
+
 static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
-	return hw->phy.ops.reset_phy(hw);
+	return hw->phy.ops.reset(hw);
 }
 
 static inline s32 e1000_check_reset_block(struct e1000_hw *hw)
@@ -595,12 +608,12 @@ static inline s32 e1000_check_reset_bloc
 
 static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data)
 {
-	return hw->phy.ops.read_phy_reg(hw, offset, data);
+	return hw->phy.ops.read_reg(hw, offset, data);
 }
 
 static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data)
 {
-	return hw->phy.ops.write_phy_reg(hw, offset, data);
+	return hw->phy.ops.write_reg(hw, offset, data);
 }
 
 static inline s32 e1000_get_cable_length(struct e1000_hw *hw)
@@ -620,27 +633,27 @@ extern s32 e1000e_read_mac_addr(struct e
 
 static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
 {
-	return hw->nvm.ops.validate_nvm(hw);
+	return hw->nvm.ops.validate(hw);
 }
 
 static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw)
 {
-	return hw->nvm.ops.update_nvm(hw);
+	return hw->nvm.ops.update(hw);
 }
 
 static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
-	return hw->nvm.ops.read_nvm(hw, offset, words, data);
+	return hw->nvm.ops.read(hw, offset, words, data);
 }
 
 static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
-	return hw->nvm.ops.write_nvm(hw, offset, words, data);
+	return hw->nvm.ops.write(hw, offset, words, data);
 }
 
 static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
 {
-	return hw->phy.ops.get_phy_info(hw);
+	return hw->phy.ops.get_info(hw);
 }
 
 static inline s32 e1000e_check_mng_mode(struct e1000_hw *hw)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/es2lan.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/es2lan.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/es2lan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/es2lan.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -31,11 +31,6 @@
  * 80003ES2LAN Gigabit Ethernet Controller (Serdes)
  */
 
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
 #include "e1000.h"
 
 #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL	 0x00
@@ -51,6 +46,9 @@
 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT	 0x0000
 #define E1000_KMRNCTRLSTA_OPMODE_E_IDLE		 0x2000
 
+#define E1000_KMRNCTRLSTA_OPMODE_MASK		 0x000C
+#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO	 0x0004
+
 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
 #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN	 0x00010000
 
@@ -104,6 +102,8 @@
  */
 static const u16 e1000_gg82563_cable_length_table[] =
 	 { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };
+#define GG82563_CABLE_LENGTH_TABLE_SIZE \
+		ARRAY_SIZE(e1000_gg82563_cable_length_table)
 
 static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw);
 static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
@@ -117,12 +117,11 @@ static s32  e1000_read_kmrn_reg_80003es2
                                             u16 *data);
 static s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
                                              u16 data);
+static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
 
 /**
  *  e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
 {
@@ -132,6 +131,9 @@ static s32 e1000_init_phy_params_80003es
 	if (hw->phy.media_type != e1000_media_type_copper) {
 		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;
@@ -152,8 +154,6 @@ static s32 e1000_init_phy_params_80003es
 /**
  *  e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw)
 {
@@ -200,8 +200,6 @@ static s32 e1000_init_nvm_params_80003es
 /**
  *  e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
 {
@@ -224,7 +222,10 @@ static s32 e1000_init_mac_params_80003es
 	/* Set rar entry count */
 	mac->rar_entry_count = E1000_RAR_ENTRIES;
 	/* Set if manageability features are enabled. */
-	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
+	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK)
+                        ? true : false;
+	/* Adaptive IFS not supported */
+	mac->adaptive_ifs = false;
 
 	/* check for link */
 	switch (hw->phy.media_type) {
@@ -272,8 +273,7 @@ static s32 e1000_get_variants_80003es2la
  *  e1000_acquire_phy_80003es2lan - Acquire rights to access PHY
  *  @hw: pointer to the HW structure
  *
- *  A wrapper to acquire access rights to the correct PHY.  This is a
- *  function pointer entry point called by the api module.
+ *  A wrapper to acquire access rights to the correct PHY.
  **/
 static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
 {
@@ -287,8 +287,7 @@ static s32 e1000_acquire_phy_80003es2lan
  *  e1000_release_phy_80003es2lan - Release rights to access PHY
  *  @hw: pointer to the HW structure
  *
- *  A wrapper to release access rights to the correct PHY.  This is a
- *  function pointer entry point called by the api module.
+ *  A wrapper to release access rights to the correct PHY.
  **/
 static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
 {
@@ -333,8 +332,7 @@ static void e1000_release_mac_csr_80003e
  *  e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM
  *  @hw: pointer to the HW structure
  *
- *  Acquire the semaphore to access the EEPROM.  This is a function
- *  pointer entry point called by the api module.
+ *  Acquire the semaphore to access the EEPROM.
  **/
 static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw)
 {
@@ -356,8 +354,7 @@ static s32 e1000_acquire_nvm_80003es2lan
  *  e1000_release_nvm_80003es2lan - Relinquish rights to access NVM
  *  @hw: pointer to the HW structure
  *
- *  Release the semaphore used to access the EEPROM.  This is a
- *  function pointer entry point called by the api module.
+ *  Release the semaphore used to access the EEPROM.
  **/
 static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw)
 {
@@ -399,8 +396,7 @@ static s32 e1000_acquire_swfw_sync_80003
 	}
 
 	if (i == timeout) {
-		hw_dbg(hw,
-		       "Driver can't access resource, SW_FW_SYNC timeout.\n");
+		e_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
 		return -E1000_ERR_SWFW_SYNC;
 	}
 
@@ -440,8 +436,7 @@ static void e1000_release_swfw_sync_8000
  *  @offset: offset of the register to read
  *  @data: pointer to the data returned from the operation
  *
- *  Read the GG82563 PHY register.  This is a function pointer entry
- *  point called by the api module.
+ *  Read the GG82563 PHY register.
  **/
 static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 						  u32 offset, u16 *data)
@@ -472,28 +467,36 @@ static s32 e1000_read_phy_reg_gg82563_80
 		return ret_val;
 	}
 
-	/*
-	 * The "ready" bit in the MDIC register may be incorrectly set
-	 * before the device has completed the "Page Select" MDI
-	 * transaction.  So we wait 200us after each MDI command...
-	 */
-	udelay(200);
+	if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
+		/*
+		 * The "ready" bit in the MDIC register may be incorrectly set
+		 * before the device has completed the "Page Select" MDI
+		 * transaction.  So we wait 200us after each MDI command...
+		 */
+		udelay(200);
 
-	/* ...and verify the command was successful. */
-	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
+		/* ...and verify the command was successful. */
+		ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
 
-	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-		ret_val = -E1000_ERR_PHY;
-		e1000_release_phy_80003es2lan(hw);
-		return ret_val;
-	}
+		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
+			ret_val = -E1000_ERR_PHY;
+			e1000_release_phy_80003es2lan(hw);
+			return ret_val;
+		}
 
-	udelay(200);
+		udelay(200);
 
-	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-					   data);
+		ret_val = e1000e_read_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
+
+		udelay(200);
+	} else {
+		ret_val = e1000e_read_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
+	}
 
-	udelay(200);
 	e1000_release_phy_80003es2lan(hw);
 
 	return ret_val;
@@ -505,8 +508,7 @@ static s32 e1000_read_phy_reg_gg82563_80
  *  @offset: offset of the register to read
  *  @data: value to write to the register
  *
- *  Write to the GG82563 PHY register.  This is a function pointer entry
- *  point called by the api module.
+ *  Write to the GG82563 PHY register.
  **/
 static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 						   u32 offset, u16 data)
@@ -537,28 +539,35 @@ static s32 e1000_write_phy_reg_gg82563_8
 		return ret_val;
 	}
 
+	if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
+		/*
+		 * The "ready" bit in the MDIC register may be incorrectly set
+		 * before the device has completed the "Page Select" MDI
+		 * transaction.  So we wait 200us after each MDI command...
+		 */
+		udelay(200);
 
-	/*
-	 * The "ready" bit in the MDIC register may be incorrectly set
-	 * before the device has completed the "Page Select" MDI
-	 * transaction.  So we wait 200us after each MDI command...
-	 */
-	udelay(200);
+		/* ...and verify the command was successful. */
+		ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
 
-	/* ...and verify the command was successful. */
-	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
+		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
+			e1000_release_phy_80003es2lan(hw);
+			return -E1000_ERR_PHY;
+		}
 
-	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-		e1000_release_phy_80003es2lan(hw);
-		return -E1000_ERR_PHY;
-	}
+		udelay(200);
 
-	udelay(200);
+		ret_val = e1000e_write_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
 
-	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-					    data);
+		udelay(200);
+	} else {
+		ret_val = e1000e_write_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
+	}
 
-	udelay(200);
 	e1000_release_phy_80003es2lan(hw);
 
 	return ret_val;
@@ -571,8 +580,7 @@ static s32 e1000_write_phy_reg_gg82563_8
  *  @words: number of words to write
  *  @data: buffer of data to write to the NVM
  *
- *  Write "words" of data to the ESB2 NVM.  This is a function
- *  pointer entry point called by the api module.
+ *  Write "words" of data to the ESB2 NVM.
  **/
 static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
 				       u16 words, u16 *data)
@@ -602,7 +610,7 @@ static s32 e1000_get_cfg_done_80003es2la
 		timeout--;
 	}
 	if (!timeout) {
-		hw_dbg(hw, "MNG configuration cycle has not completed.\n");
+		e_dbg("MNG configuration cycle has not completed.\n");
 		return -E1000_ERR_RESET;
 	}
 
@@ -635,7 +643,7 @@ static s32 e1000_phy_force_speed_duplex_
 	if (ret_val)
 		return ret_val;
 
-	hw_dbg(hw, "GG82563 PSCR: %X\n", phy_data);
+	e_dbg("GG82563 PSCR: %X\n", phy_data);
 
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
 	if (ret_val)
@@ -653,7 +661,7 @@ static s32 e1000_phy_force_speed_duplex_
 	udelay(1);
 
 	if (hw->phy.autoneg_wait_to_complete) {
-		hw_dbg(hw, "Waiting for forced speed/duplex link "
+		e_dbg("Waiting for forced speed/duplex link "
 			 "on GG82563 phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
@@ -712,21 +720,27 @@ static s32 e1000_phy_force_speed_duplex_
 static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
-	u16 phy_data;
-	u16 index;
+	s32 ret_val = 0;
+	u16 phy_data, index;
 
 	ret_val = e1e_rphy(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
 	if (ret_val)
-		return ret_val;
+		goto out;
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
+
+	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
 	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
-	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];
+	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-	return 0;
+out:
+	return ret_val;
 }
 
 /**
@@ -736,7 +750,6 @@ static s32 e1000_get_cable_length_80003e
  *  @duplex: pointer to duplex buffer
  *
  *  Retrieve the current speed and duplex configuration.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
 					      u16 *duplex)
@@ -762,12 +775,10 @@ static s32 e1000_get_link_up_info_80003e
  *  @hw: pointer to the HW structure
  *
  *  Perform a global reset to the ESB2 controller.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
 {
-	u32 ctrl;
-	u32 icr;
+	u32 ctrl, icr;
 	s32 ret_val;
 
 	/*
@@ -776,9 +787,9 @@ static s32 e1000_reset_hw_80003es2lan(st
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
 	if (ret_val)
-		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+		e_dbg("PCI-E Master disable polling has failed.\n");
 
-	hw_dbg(hw, "Masking off all interrupts\n");
+	e_dbg("Masking off all interrupts\n");
 	ew32(IMC, 0xffffffff);
 
 	ew32(RCTL, 0);
@@ -790,7 +801,7 @@ static s32 e1000_reset_hw_80003es2lan(st
 	ctrl = er32(CTRL);
 
 	ret_val = e1000_acquire_phy_80003es2lan(hw);
-	hw_dbg(hw, "Issuing a global reset to MAC\n");
+	e_dbg("Issuing a global reset to MAC\n");
 	ew32(CTRL, ctrl | E1000_CTRL_RST);
 	e1000_release_phy_80003es2lan(hw);
 
@@ -811,7 +822,6 @@ static s32 e1000_reset_hw_80003es2lan(st
  *  @hw: pointer to the HW structure
  *
  *  Initialize the hw bits, LED, VFTA, MTA, link and hw counters.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
 {
@@ -824,20 +834,19 @@ static s32 e1000_init_hw_80003es2lan(str
 
 	/* Initialize identification LED */
 	ret_val = e1000e_id_led_init(hw);
-	if (ret_val) {
-		hw_dbg(hw, "Error initializing identification LED\n");
-		return ret_val;
-	}
+	if (ret_val)
+		e_dbg("Error initializing identification LED\n");
+		/* This is not fatal and we should not stop init due to this */
 
 	/* Disabling VLAN filtering */
-	hw_dbg(hw, "Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	e_dbg("Initializing the IEEE VLAN\n");
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	e1000e_init_rx_addrs(hw, mac->rar_entry_count);
 
 	/* Zero out the Multicast HASH table */
-	hw_dbg(hw, "Zeroing the MTA\n");
+	e_dbg("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
 
@@ -877,6 +886,19 @@ static s32 e1000_init_hw_80003es2lan(str
 	reg_data &= ~0x00100000;
 	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);
 
+	/* default to true to enable the MDIC W/A */
+	hw->dev_spec.e80003es2lan.mdic_wa_enable = true;
+
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
+	                              E1000_KMRNCTRLSTA_OFFSET >>
+	                              E1000_KMRNCTRLSTA_OFFSET_SHIFT,
+	                              &i);
+	if (!ret_val) {
+		if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
+		     E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
+			hw->dev_spec.e80003es2lan.mdic_wa_enable = false;
+	}
+
 	/*
 	 * Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
@@ -994,7 +1016,7 @@ static s32 e1000_copper_link_setup_gg825
 	/* SW Reset the PHY so all changes take effect */
 	ret_val = e1000e_commit_phy(hw);
 	if (ret_val) {
-		hw_dbg(hw, "Error Resetting the PHY\n");
+		e_dbg("Error Resetting the PHY\n");
 		return ret_val;
 	}
 
@@ -1318,6 +1340,23 @@ static s32 e1000_write_kmrn_reg_80003es2
 }
 
 /**
+ * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw)
+{
+	/* If the management interface is not enabled, then power down */
+	if (!(hw->mac.ops.check_mng_mode(hw) ||
+	      hw->phy.ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
@@ -1325,44 +1364,42 @@ static s32 e1000_write_kmrn_reg_80003es2
  **/
 static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
 {
-	u32 temp;
-
 	e1000e_clear_hw_cntrs_base(hw);
 
-	temp = er32(PRC64);
-	temp = er32(PRC127);
-	temp = er32(PRC255);
-	temp = er32(PRC511);
-	temp = er32(PRC1023);
-	temp = er32(PRC1522);
-	temp = er32(PTC64);
-	temp = er32(PTC127);
-	temp = er32(PTC255);
-	temp = er32(PTC511);
-	temp = er32(PTC1023);
-	temp = er32(PTC1522);
+	er32(PRC64);
+	er32(PRC127);
+	er32(PRC255);
+	er32(PRC511);
+	er32(PRC1023);
+	er32(PRC1522);
+	er32(PTC64);
+	er32(PTC127);
+	er32(PTC255);
+	er32(PTC511);
+	er32(PTC1023);
+	er32(PTC1522);
 
-	temp = er32(ALGNERRC);
-	temp = er32(RXERRC);
-	temp = er32(TNCRS);
-	temp = er32(CEXTERR);
-	temp = er32(TSCTC);
-	temp = er32(TSCTFC);
+	er32(ALGNERRC);
+	er32(RXERRC);
+	er32(TNCRS);
+	er32(CEXTERR);
+	er32(TSCTC);
+	er32(TSCTFC);
 
-	temp = er32(MGTPRC);
-	temp = er32(MGTPDC);
-	temp = er32(MGTPTC);
+	er32(MGTPRC);
+	er32(MGTPDC);
+	er32(MGTPTC);
 
-	temp = er32(IAC);
-	temp = er32(ICRXOC);
+	er32(IAC);
+	er32(ICRXOC);
 
-	temp = er32(ICRXPTC);
-	temp = er32(ICRXATC);
-	temp = er32(ICTXPTC);
-	temp = er32(ICTXATC);
-	temp = er32(ICTXQEC);
-	temp = er32(ICTXQMTC);
-	temp = er32(ICRXDMTC);
+	er32(ICRXPTC);
+	er32(ICRXATC);
+	er32(ICTXPTC);
+	er32(ICTXATC);
+	er32(ICTXQEC);
+	er32(ICTXQMTC);
+	er32(ICRXDMTC);
 }
 
 static struct e1000_mac_operations es2_mac_ops = {
@@ -1376,6 +1413,8 @@ static struct e1000_mac_operations es2_m
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_generic,
 	.reset_hw		= e1000_reset_hw_80003es2lan,
 	.init_hw		= e1000_init_hw_80003es2lan,
 	.setup_link		= e1000e_setup_link,
@@ -1384,30 +1423,31 @@ static struct e1000_mac_operations es2_m
 };
 
 static struct e1000_phy_operations es2_phy_ops = {
-	.acquire_phy		= e1000_acquire_phy_80003es2lan,
+	.acquire		= e1000_acquire_phy_80003es2lan,
+	.check_polarity		= e1000_check_polarity_m88,
 	.check_reset_block	= e1000e_check_reset_block_generic,
-	.commit_phy	 	= e1000e_phy_sw_reset,
+	.commit		 	= e1000e_phy_sw_reset,
 	.force_speed_duplex 	= e1000_phy_force_speed_duplex_80003es2lan,
 	.get_cfg_done       	= e1000_get_cfg_done_80003es2lan,
 	.get_cable_length   	= e1000_get_cable_length_80003es2lan,
-	.get_phy_info       	= e1000e_get_phy_info_m88,
-	.read_phy_reg       	= e1000_read_phy_reg_gg82563_80003es2lan,
-	.release_phy		= e1000_release_phy_80003es2lan,
-	.reset_phy	  	= e1000e_phy_hw_reset_generic,
+	.get_info       	= e1000e_get_phy_info_m88,
+	.read_reg       	= e1000_read_phy_reg_gg82563_80003es2lan,
+	.release		= e1000_release_phy_80003es2lan,
+	.reset		  	= e1000e_phy_hw_reset_generic,
 	.set_d0_lplu_state  	= NULL,
 	.set_d3_lplu_state  	= e1000e_set_d3_lplu_state,
-	.write_phy_reg      	= e1000_write_phy_reg_gg82563_80003es2lan,
+	.write_reg      	= e1000_write_phy_reg_gg82563_80003es2lan,
 	.cfg_on_link_up      	= e1000_cfg_on_link_up_80003es2lan,
 };
 
 static struct e1000_nvm_operations es2_nvm_ops = {
-	.acquire_nvm		= e1000_acquire_nvm_80003es2lan,
-	.read_nvm		= e1000e_read_nvm_eerd,
-	.release_nvm		= e1000_release_nvm_80003es2lan,
-	.update_nvm		= e1000e_update_nvm_checksum_generic,
+	.acquire		= e1000_acquire_nvm_80003es2lan,
+	.read			= e1000e_read_nvm_eerd,
+	.release		= e1000_release_nvm_80003es2lan,
+	.update			= e1000e_update_nvm_checksum_generic,
 	.valid_led_default	= e1000e_valid_led_default,
-	.validate_nvm		= e1000e_validate_nvm_checksum_generic,
-	.write_nvm		= e1000_write_nvm_80003es2lan,
+	.validate		= e1000e_validate_nvm_checksum_generic,
+	.write			= e1000_write_nvm_80003es2lan,
 };
 
 struct e1000_info e1000_es2_info = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/ethtool.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -35,14 +35,22 @@
 
 #include "e1000.h"
 
+enum {NETDEV_STATS, E1000_STATS};
+
 struct e1000_stats {
 	char stat_string[ETH_GSTRING_LEN];
+	int type;
 	int sizeof_stat;
 	int stat_offset;
 };
 
-#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
-		      offsetof(struct e1000_adapter, m)
+#define E1000_STAT(m)		E1000_STATS, \
+				sizeof(((struct e1000_adapter *)0)->m), \
+		      		offsetof(struct e1000_adapter, m)
+#define E1000_NETDEV_STAT(m)	NETDEV_STATS, \
+				sizeof(((struct net_device *)0)->m), \
+				offsetof(struct net_device, m)
+
 static const struct e1000_stats e1000_gstrings_stats[] = {
 	{ "rx_packets", E1000_STAT(stats.gprc) },
 	{ "tx_packets", E1000_STAT(stats.gptc) },
@@ -52,21 +60,21 @@ static const struct e1000_stats e1000_gs
 	{ "tx_broadcast", E1000_STAT(stats.bptc) },
 	{ "rx_multicast", E1000_STAT(stats.mprc) },
 	{ "tx_multicast", E1000_STAT(stats.mptc) },
-	{ "rx_errors", E1000_STAT(net_stats.rx_errors) },
-	{ "tx_errors", E1000_STAT(net_stats.tx_errors) },
-	{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
+	{ "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) },
+	{ "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) },
+	{ "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
 	{ "multicast", E1000_STAT(stats.mprc) },
 	{ "collisions", E1000_STAT(stats.colc) },
-	{ "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
-	{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
+	{ "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) },
+	{ "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
 	{ "rx_crc_errors", E1000_STAT(stats.crcerrs) },
-	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
+	{ "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
 	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
 	{ "rx_missed_errors", E1000_STAT(stats.mpc) },
 	{ "tx_aborted_errors", E1000_STAT(stats.ecol) },
 	{ "tx_carrier_errors", E1000_STAT(stats.tncrs) },
-	{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
-	{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
+	{ "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
+	{ "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
 	{ "tx_window_errors", E1000_STAT(stats.latecol) },
 	{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
 	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
@@ -182,6 +190,17 @@ static int e1000_get_settings(struct net
 static u32 e1000_get_link(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+
+	/*
+	 * If the link is not reported up to netdev, interrupts are disabled,
+	 * and so the physical link state may have changed since we last
+	 * looked. Set get_link_status to make sure that the true link
+	 * state is interrogated, rather than pulling a cached and possibly
+	 * stale link state from the driver.
+	 */
+	if (!netif_carrier_ok(netdev))
+		mac->get_link_status = 1;
 
 	return e1000_has_link(adapter);
 }
@@ -516,7 +535,8 @@ static int e1000_get_eeprom(struct net_d
 
 	if (ret_val) {
 		/* a read error occurred, throw away the result */
-		memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
+		memset(eeprom_buff, 0xff, sizeof(u16) *
+		       (last_word - first_word + 1));
 	} else {
 		/* Device's eeprom is always little-endian, word addressable */
 		for (i = 0; i < last_word - first_word + 1; i++)
@@ -596,7 +616,9 @@ static int e1000_set_eeprom(struct net_d
 	 * and flush shadow RAM for applicable controllers
 	 */
 	if ((first_word <= NVM_CHECKSUM_REG) ||
-	    (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573))
+	    (hw->mac.type == e1000_82583) ||
+	    (hw->mac.type == e1000_82574) ||
+	    (hw->mac.type == e1000_82573))
 		ret_val = e1000e_update_nvm_checksum(hw);
 
 out:
@@ -929,10 +951,10 @@ static int e1000_intr_test(struct e1000_
 		e1000e_set_interrupt_capability(adapter);
 	}
 	/* Hook up test interrupt handler just for this test */
-	if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
+	if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
 			 netdev)) {
 		shared_int = 0;
-	} else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED,
+	} else if (request_irq(irq, e1000_test_intr, IRQF_SHARED,
 		 netdev->name, netdev)) {
 		*data = 1;
 		ret_val = -1;
@@ -1239,6 +1261,10 @@ static int e1000_integrated_phy_loopback
 
 	hw->mac.autoneg = 0;
 
+	/* Workaround: K1 must be disabled for stable 1Gbps operation */
+	if (hw->mac.type == e1000_pchlan)
+		e1000_configure_k1_ich8lan(hw, false);
+
 	if (hw->phy.type == e1000_phy_m88) {
 		/* Auto-MDI/MDIX Off */
 		e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
@@ -1769,12 +1795,11 @@ static int e1000_set_wol(struct net_devi
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	if (wol->wolopts & WAKE_MAGICSECURE)
-		return -EOPNOTSUPP;
-
 	if (!(adapter->flags & FLAG_HAS_WOL) ||
-	    !device_can_wakeup(&adapter->pdev->dev))
-		return wol->wolopts ? -EOPNOTSUPP : 0;
+	    !device_can_wakeup(&adapter->pdev->dev) ||
+	    (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
+	                      WAKE_MAGIC | WAKE_PHY | WAKE_ARP)))
+		return -EOPNOTSUPP;
 
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
@@ -1832,6 +1857,7 @@ static int e1000_phys_id(struct net_devi
 
 	if ((hw->phy.type == e1000_phy_ife) ||
 	    (hw->mac.type == e1000_pchlan) ||
+	    (hw->mac.type == e1000_82583) ||
 	    (hw->mac.type == e1000_82574)) {
 		INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
 		if (!adapter->blink_timer.function) {
@@ -1912,10 +1938,21 @@ static void e1000_get_ethtool_stats(stru
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int i;
+	char *p = NULL;
 
 	e1000e_update_stats(adapter);
 	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
-		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
+		switch (e1000_gstrings_stats[i].type) {
+		case NETDEV_STATS:
+			p = (char *) netdev +
+					e1000_gstrings_stats[i].stat_offset;
+			break;
+		case E1000_STATS:
+			p = (char *) adapter +
+					e1000_gstrings_stats[i].stat_offset;
+			break;
+		}
+
 		data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
@@ -1975,6 +2012,8 @@ static const struct ethtool_ops e1000_et
 	.get_sset_count		= e1000e_get_sset_count,
 	.get_coalesce		= e1000_get_coalesce,
 	.set_coalesce		= e1000_set_coalesce,
+	.get_flags		= ethtool_op_get_flags,
+	.set_flags		= ethtool_op_set_flags,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/hw.h linux-libre-2.6.33-gnu1/drivers/net/e1000e/hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -219,7 +219,7 @@ enum e1e_registers {
 	E1000_HICR      = 0x08F00, /* Host Interface Control */
 };
 
-/* RSS registers */
+#define E1000_MAX_PHY_ADDR		4
 
 /* IGP01E1000 Specific Registers */
 #define IGP01E1000_PHY_PORT_CONFIG	0x10 /* Port Config */
@@ -302,6 +302,8 @@ enum e1e_registers {
 #define E1000_KMRNCTRLSTA_OFFSET_SHIFT	16
 #define E1000_KMRNCTRLSTA_REN		0x00200000
 #define E1000_KMRNCTRLSTA_DIAG_OFFSET	0x3    /* Kumeran Diagnostic */
+#define E1000_KMRNCTRLSTA_TIMEOUTS	0x4    /* Kumeran Timeouts */
+#define E1000_KMRNCTRLSTA_INBAND_PARAM	0x9    /* Kumeran InBand Parameters */
 #define E1000_KMRNCTRLSTA_DIAG_NELPBK	0x1000 /* Nearend Loopback mode */
 #define E1000_KMRNCTRLSTA_K1_CONFIG	0x7
 #define E1000_KMRNCTRLSTA_K1_ENABLE	0x140E
@@ -356,6 +358,7 @@ enum e1e_registers {
 #define E1000_DEV_ID_80003ES2LAN_COPPER_SPT	0x10BA
 #define E1000_DEV_ID_80003ES2LAN_SERDES_SPT	0x10BB
 
+#define E1000_DEV_ID_ICH8_82567V_3		0x1501
 #define E1000_DEV_ID_ICH8_IGP_M_AMT		0x1049
 #define E1000_DEV_ID_ICH8_IGP_AMT		0x104A
 #define E1000_DEV_ID_ICH8_IGP_C			0x104B
@@ -741,6 +744,7 @@ struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
 	s32  (*cleanup_led)(struct e1000_hw *);
 	void (*clear_hw_cntrs)(struct e1000_hw *);
+	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
@@ -751,38 +755,41 @@ struct e1000_mac_operations {
 	s32  (*setup_link)(struct e1000_hw *);
 	s32  (*setup_physical_interface)(struct e1000_hw *);
 	s32  (*setup_led)(struct e1000_hw *);
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
 };
 
 /* Function pointers for the PHY. */
 struct e1000_phy_operations {
-	s32  (*acquire_phy)(struct e1000_hw *);
+	s32  (*acquire)(struct e1000_hw *);
+	s32  (*cfg_on_link_up)(struct e1000_hw *);
 	s32  (*check_polarity)(struct e1000_hw *);
 	s32  (*check_reset_block)(struct e1000_hw *);
-	s32  (*commit_phy)(struct e1000_hw *);
+	s32  (*commit)(struct e1000_hw *);
 	s32  (*force_speed_duplex)(struct e1000_hw *);
 	s32  (*get_cfg_done)(struct e1000_hw *hw);
 	s32  (*get_cable_length)(struct e1000_hw *);
-	s32  (*get_phy_info)(struct e1000_hw *);
-	s32  (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
-	s32  (*read_phy_reg_locked)(struct e1000_hw *, u32, u16 *);
-	void (*release_phy)(struct e1000_hw *);
-	s32  (*reset_phy)(struct e1000_hw *);
+	s32  (*get_info)(struct e1000_hw *);
+	s32  (*read_reg)(struct e1000_hw *, u32, u16 *);
+	s32  (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
+	void (*release)(struct e1000_hw *);
+	s32  (*reset)(struct e1000_hw *);
 	s32  (*set_d0_lplu_state)(struct e1000_hw *, bool);
 	s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
-	s32  (*write_phy_reg)(struct e1000_hw *, u32, u16);
-	s32  (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
-	s32  (*cfg_on_link_up)(struct e1000_hw *);
+	s32  (*write_reg)(struct e1000_hw *, u32, u16);
+	s32  (*write_reg_locked)(struct e1000_hw *, u32, u16);
+	void (*power_up)(struct e1000_hw *);
+	void (*power_down)(struct e1000_hw *);
 };
 
 /* Function pointers for the NVM. */
 struct e1000_nvm_operations {
-	s32  (*acquire_nvm)(struct e1000_hw *);
-	s32  (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
-	void (*release_nvm)(struct e1000_hw *);
-	s32  (*update_nvm)(struct e1000_hw *);
+	s32  (*acquire)(struct e1000_hw *);
+	s32  (*read)(struct e1000_hw *, u16, u16, u16 *);
+	void (*release)(struct e1000_hw *);
+	s32  (*update)(struct e1000_hw *);
 	s32  (*valid_led_default)(struct e1000_hw *, u16 *);
-	s32  (*validate_nvm)(struct e1000_hw *);
-	s32  (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+	s32  (*validate)(struct e1000_hw *);
+	s32  (*write)(struct e1000_hw *, u16, u16, u16 *);
 };
 
 struct e1000_mac_info {
@@ -811,6 +818,7 @@ struct e1000_mac_info {
 
 	u8  forced_speed_duplex;
 
+	bool adaptive_ifs;
 	bool arc_subsystem_valid;
 	bool autoneg;
 	bool autoneg_failed;
@@ -893,6 +901,10 @@ struct e1000_dev_spec_82571 {
 	u32 smb_counter;
 };
 
+struct e1000_dev_spec_80003es2lan {
+	bool  mdic_wa_enable;
+};
+
 struct e1000_shadow_ram {
 	u16  value;
 	bool modified;
@@ -921,19 +933,9 @@ struct e1000_hw {
 
 	union {
 		struct e1000_dev_spec_82571	e82571;
+		struct e1000_dev_spec_80003es2lan e80003es2lan;
 		struct e1000_dev_spec_ich8lan	ich8lan;
 	} dev_spec;
 };
 
-#ifdef DEBUG
-#define hw_dbg(hw, format, arg...) \
-	printk(KERN_DEBUG "%s: " format, e1000e_get_hw_dev_name(hw), ##arg)
-#else
-static inline int __attribute__ ((format (printf, 2, 3)))
-hw_dbg(struct e1000_hw *hw, const char *format, ...)
-{
-	return 0;
-}
-#endif
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/ich8lan.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/ich8lan.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/ich8lan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/ich8lan.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -54,11 +54,6 @@
  * 82578DC Gigabit Network Connection
  */
 
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
 #include "e1000.h"
 
 #define ICH_FLASH_GFPREG		0x0000
@@ -143,6 +138,10 @@
 #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
 #define E1000_NVM_K1_ENABLE 0x1  /* NVM Enable K1 bit */
 
+/* KMRN Mode Control */
+#define HV_KMRN_MODE_CTRL      PHY_REG(769, 16)
+#define HV_KMRN_MDIO_SLOW      0x0400
+
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
 union ich8_hws_flash_status {
@@ -200,7 +199,6 @@ union ich8_flash_protected_range {
 static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
-static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw);
 static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
 static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
 						u32 offset, u8 byte);
@@ -222,9 +220,10 @@ static s32 e1000_cleanup_led_pchlan(stru
 static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
 static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
 static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
+static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
 static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
 static s32  e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
-static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
+static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -265,28 +264,54 @@ static s32 e1000_init_phy_params_pchlan(
 	phy->addr                     = 1;
 	phy->reset_delay_us           = 100;
 
-	phy->ops.check_polarity       = e1000_check_polarity_ife_ich8lan;
-	phy->ops.read_phy_reg         = e1000_read_phy_reg_hv;
-	phy->ops.read_phy_reg_locked  = e1000_read_phy_reg_hv_locked;
+	phy->ops.read_reg             = e1000_read_phy_reg_hv;
+	phy->ops.read_reg_locked      = e1000_read_phy_reg_hv_locked;
 	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_phy_reg        = e1000_write_phy_reg_hv;
-	phy->ops.write_phy_reg_locked = e1000_write_phy_reg_hv_locked;
+	phy->ops.write_reg            = e1000_write_phy_reg_hv;
+	phy->ops.write_reg_locked     = e1000_write_phy_reg_hv_locked;
+	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;
-	e1000e_get_phy_id(hw);
+	ret_val = e1000e_get_phy_id(hw);
+	if (ret_val)
+		goto out;
+	if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) {
+		/*
+		 * In case the PHY needs to be in mdio slow mode (eg. 82577),
+		 * set slow mode and try to get the PHY id again.
+		 */
+		ret_val = e1000_set_mdio_slow_mode_hv(hw);
+		if (ret_val)
+			goto out;
+		ret_val = e1000e_get_phy_id(hw);
+		if (ret_val)
+			goto out;
+	}
 	phy->type = e1000e_get_phy_type_from_id(phy->id);
 
-	if (phy->type == e1000_phy_82577) {
+	switch (phy->type) {
+	case e1000_phy_82577:
 		phy->ops.check_polarity = e1000_check_polarity_82577;
 		phy->ops.force_speed_duplex =
 			e1000_phy_force_speed_duplex_82577;
-		phy->ops.get_cable_length   = e1000_get_cable_length_82577;
-		phy->ops.get_phy_info = e1000_get_phy_info_82577;
-		phy->ops.commit_phy = e1000e_phy_sw_reset;
+		phy->ops.get_cable_length = e1000_get_cable_length_82577;
+		phy->ops.get_info = e1000_get_phy_info_82577;
+		phy->ops.commit = e1000e_phy_sw_reset;
+	case e1000_phy_82578:
+		phy->ops.check_polarity = e1000_check_polarity_m88;
+		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
+		phy->ops.get_cable_length = e1000e_get_cable_length_m88;
+		phy->ops.get_info = e1000e_get_phy_info_m88;
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		break;
 	}
 
+out:
 	return ret_val;
 }
 
@@ -305,17 +330,22 @@ static s32 e1000_init_phy_params_ich8lan
 	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;
+
 	/*
 	 * We may need to do this twice - once for IGP and if that fails,
 	 * we'll set BM func pointers and try again
 	 */
 	ret_val = e1000e_determine_phy_address(hw);
 	if (ret_val) {
-		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
-		hw->phy.ops.read_phy_reg  = e1000e_read_phy_reg_bm;
+		phy->ops.write_reg = e1000e_write_phy_reg_bm;
+		phy->ops.read_reg  = e1000e_read_phy_reg_bm;
 		ret_val = e1000e_determine_phy_address(hw);
-		if (ret_val)
+		if (ret_val) {
+			e_dbg("Cannot determine PHY addr. Erroring out\n");
 			return ret_val;
+		}
 	}
 
 	phy->id = 0;
@@ -332,29 +362,36 @@ static s32 e1000_init_phy_params_ich8lan
 	case IGP03E1000_E_PHY_ID:
 		phy->type = e1000_phy_igp_3;
 		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-		phy->ops.read_phy_reg_locked = e1000e_read_phy_reg_igp_locked;
-		phy->ops.write_phy_reg_locked = e1000e_write_phy_reg_igp_locked;
+		phy->ops.read_reg_locked = e1000e_read_phy_reg_igp_locked;
+		phy->ops.write_reg_locked = e1000e_write_phy_reg_igp_locked;
+		phy->ops.get_info = e1000e_get_phy_info_igp;
+		phy->ops.check_polarity = e1000_check_polarity_igp;
+		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_igp;
 		break;
 	case IFE_E_PHY_ID:
 	case IFE_PLUS_E_PHY_ID:
 	case IFE_C_E_PHY_ID:
 		phy->type = e1000_phy_ife;
 		phy->autoneg_mask = E1000_ALL_NOT_GIG;
+		phy->ops.get_info = e1000_get_phy_info_ife;
+		phy->ops.check_polarity = e1000_check_polarity_ife;
+		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
 		break;
 	case BME1000_E_PHY_ID:
 		phy->type = e1000_phy_bm;
 		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-		hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
-		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
-		hw->phy.ops.commit_phy = e1000e_phy_sw_reset;
+		phy->ops.read_reg = e1000e_read_phy_reg_bm;
+		phy->ops.write_reg = e1000e_write_phy_reg_bm;
+		phy->ops.commit = e1000e_phy_sw_reset;
+		phy->ops.get_info = e1000e_get_phy_info_m88;
+		phy->ops.check_polarity = e1000_check_polarity_m88;
+		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
 		break;
 	default:
 		return -E1000_ERR_PHY;
 		break;
 	}
 
-	phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
-
 	return 0;
 }
 
@@ -374,7 +411,7 @@ static s32 e1000_init_nvm_params_ich8lan
 
 	/* Can't read flash registers if the register set isn't mapped. */
 	if (!hw->flash_address) {
-		hw_dbg(hw, "ERROR: Flash registers not mapped\n");
+		e_dbg("ERROR: Flash registers not mapped\n");
 		return -E1000_ERR_CONFIG;
 	}
 
@@ -407,7 +444,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 = 0;
+		dev_spec->shadow_ram[i].modified = false;
 		dev_spec->shadow_ram[i].value    = 0xFFFF;
 	}
 
@@ -436,7 +473,9 @@ static s32 e1000_init_mac_params_ich8lan
 	if (mac->type == e1000_ich8lan)
 		mac->rar_entry_count--;
 	/* Set if manageability features are enabled. */
-	mac->arc_subsystem_valid = 1;
+	mac->arc_subsystem_valid = true;
+	/* Adaptive IFS supported */
+	mac->adaptive_ifs = true;
 
 	/* LED operations */
 	switch (mac->type) {
@@ -470,7 +509,7 @@ static s32 e1000_init_mac_params_ich8lan
 
 	/* Enable PCS Lock-loss workaround for ICH8 */
 	if (mac->type == e1000_ich8lan)
-		e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1);
+		e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
 
 	return 0;
 }
@@ -556,7 +595,7 @@ static s32 e1000_check_for_copper_link_i
 	 */
 	ret_val = e1000e_config_fc_after_link_up(hw);
 	if (ret_val)
-		hw_dbg(hw, "Error configuring flow control\n");
+		e_dbg("Error configuring flow control\n");
 
 out:
 	return ret_val;
@@ -636,8 +675,6 @@ static s32 e1000_acquire_swflag_ich8lan(
 	u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
 	s32 ret_val = 0;
 
-	might_sleep();
-
 	mutex_lock(&swflag_mutex);
 
 	while (timeout) {
@@ -650,7 +687,7 @@ static s32 e1000_acquire_swflag_ich8lan(
 	}
 
 	if (!timeout) {
-		hw_dbg(hw, "SW/FW/HW has locked the resource for too long.\n");
+		e_dbg("SW/FW/HW has locked the resource for too long.\n");
 		ret_val = -E1000_ERR_CONFIG;
 		goto out;
 	}
@@ -670,7 +707,7 @@ static s32 e1000_acquire_swflag_ich8lan(
 	}
 
 	if (!timeout) {
-		hw_dbg(hw, "Failed to acquire the semaphore.\n");
+		e_dbg("Failed to acquire the semaphore.\n");
 		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
 		ew32(EXTCNF_CTRL, extcnf_ctrl);
 		ret_val = -E1000_ERR_CONFIG;
@@ -714,7 +751,9 @@ static void e1000_release_swflag_ich8lan
  **/
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
 {
-	u32 fwsm = er32(FWSM);
+	u32 fwsm;
+
+	fwsm = er32(FWSM);
 
 	return (fwsm & E1000_FWSM_MODE_MASK) ==
 		(E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
@@ -738,77 +777,6 @@ static s32 e1000_check_reset_block_ich8l
 }
 
 /**
- *  e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex
- *  @hw: pointer to the HW structure
- *
- *  Forces the speed and duplex settings of the PHY.
- *  This is a function pointer entry point only called by
- *  PHY setup routines.
- **/
-static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
-{
-	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
-	u16 data;
-	bool link;
-
-	if (phy->type != e1000_phy_ife) {
-		ret_val = e1000e_phy_force_speed_duplex_igp(hw);
-		return ret_val;
-	}
-
-	ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
-	if (ret_val)
-		return ret_val;
-
-	e1000e_phy_force_speed_duplex_setup(hw, &data);
-
-	ret_val = e1e_wphy(hw, PHY_CONTROL, data);
-	if (ret_val)
-		return ret_val;
-
-	/* Disable MDI-X support for 10/100 */
-	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
-	if (ret_val)
-		return ret_val;
-
-	data &= ~IFE_PMC_AUTO_MDIX;
-	data &= ~IFE_PMC_FORCE_MDIX;
-
-	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
-	if (ret_val)
-		return ret_val;
-
-	hw_dbg(hw, "IFE PMC: %X\n", data);
-
-	udelay(1);
-
-	if (phy->autoneg_wait_to_complete) {
-		hw_dbg(hw, "Waiting for forced speed/duplex link on IFE phy.\n");
-
-		ret_val = e1000e_phy_has_link_generic(hw,
-						     PHY_FORCE_LIMIT,
-						     100000,
-						     &link);
-		if (ret_val)
-			return ret_val;
-
-		if (!link)
-			hw_dbg(hw, "Link taking longer than expected.\n");
-
-		/* Try once more */
-		ret_val = e1000e_phy_has_link_generic(hw,
-						     PHY_FORCE_LIMIT,
-						     100000,
-						     &link);
-		if (ret_val)
-			return ret_val;
-	}
-
-	return 0;
-}
-
-/**
  *  e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
  *  @hw:   pointer to the HW structure
  *
@@ -822,7 +790,7 @@ static s32 e1000_sw_lcd_config_ich8lan(s
 	s32 ret_val;
 	u16 word_addr, reg_data, reg_addr, phy_page = 0;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -918,7 +886,7 @@ static s32 e1000_sw_lcd_config_ich8lan(s
 			reg_addr &= PHY_REG_MASK;
 			reg_addr |= phy_page;
 
-			ret_val = phy->ops.write_phy_reg_locked(hw,
+			ret_val = phy->ops.write_reg_locked(hw,
 			                                    (u32)reg_addr,
 			                                    reg_data);
 			if (ret_val)
@@ -927,7 +895,7 @@ static s32 e1000_sw_lcd_config_ich8lan(s
 	}
 
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 	return ret_val;
 }
 
@@ -951,15 +919,14 @@ static s32 e1000_k1_gig_workaround_hv(st
 		goto out;
 
 	/* Wrap the whole flow with the sw flag */
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		goto out;
 
 	/* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
 	if (link) {
 		if (hw->phy.type == e1000_phy_82578) {
-			ret_val = hw->phy.ops.read_phy_reg_locked(hw,
-			                                          BM_CS_STATUS,
+			ret_val = hw->phy.ops.read_reg_locked(hw, BM_CS_STATUS,
 			                                          &status_reg);
 			if (ret_val)
 				goto release;
@@ -975,8 +942,7 @@ static s32 e1000_k1_gig_workaround_hv(st
 		}
 
 		if (hw->phy.type == e1000_phy_82577) {
-			ret_val = hw->phy.ops.read_phy_reg_locked(hw,
-			                                          HV_M_STATUS,
+			ret_val = hw->phy.ops.read_reg_locked(hw, HV_M_STATUS,
 			                                          &status_reg);
 			if (ret_val)
 				goto release;
@@ -992,14 +958,14 @@ static s32 e1000_k1_gig_workaround_hv(st
 		}
 
 		/* Link stall fix for link up */
-		ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
+		ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19),
 		                                           0x0100);
 		if (ret_val)
 			goto release;
 
 	} else {
 		/* Link stall fix for link down */
-		ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
+		ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19),
 		                                           0x4100);
 		if (ret_val)
 			goto release;
@@ -1008,7 +974,7 @@ static s32 e1000_k1_gig_workaround_hv(st
 	ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);
 
 release:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 out:
 	return ret_val;
 }
@@ -1023,7 +989,7 @@ out:
  *
  *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
  **/
-static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
+s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
 {
 	s32 ret_val = 0;
 	u32 ctrl_reg = 0;
@@ -1084,7 +1050,7 @@ static s32 e1000_oem_bits_config_ich8lan
 	if (hw->mac.type != e1000_pchlan)
 		return ret_val;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -1098,7 +1064,7 @@ static s32 e1000_oem_bits_config_ich8lan
 
 	mac_reg = er32(PHY_CTRL);
 
-	ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg);
+	ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg);
 	if (ret_val)
 		goto out;
 
@@ -1120,26 +1086,54 @@ static s32 e1000_oem_bits_config_ich8lan
 	/* Restart auto-neg to activate the bits */
 	if (!e1000_check_reset_block(hw))
 		oem_reg |= HV_OEM_BITS_RESTART_AN;
-	ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
+	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
 
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 
 	return ret_val;
 }
 
 
 /**
+ *  e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
+ *  @hw:   pointer to the HW structure
+ **/
+static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 data;
+
+	ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data);
+	if (ret_val)
+		return ret_val;
+
+	data |= HV_KMRN_MDIO_SLOW;
+
+	ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data);
+
+	return ret_val;
+}
+
+/**
  *  e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
  *  done after every PHY reset.
  **/
 static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 {
 	s32 ret_val = 0;
+	u16 phy_data;
 
 	if (hw->mac.type != e1000_pchlan)
 		return ret_val;
 
+	/* Set MDIO slow mode before any other MDIO access */
+	if (hw->phy.type == e1000_phy_82577) {
+		ret_val = e1000_set_mdio_slow_mode_hv(hw);
+		if (ret_val)
+			goto out;
+	}
+
 	if (((hw->phy.type == e1000_phy_82577) &&
 	     ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
 	    ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
@@ -1166,22 +1160,38 @@ static s32 e1000_hv_phy_workarounds_ich8
 	}
 
 	/* Select page 0 */
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
 	hw->phy.addr = 1;
 	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+	hw->phy.ops.release(hw);
 	if (ret_val)
 		goto out;
-	hw->phy.ops.release_phy(hw);
 
 	/*
 	 * Configure the K1 Si workaround during phy reset assuming there is
 	 * link so that it disables K1 if link is in 1Gbps.
 	 */
 	ret_val = e1000_k1_gig_workaround_hv(hw, true);
+	if (ret_val)
+		goto out;
 
+	/* Workaround for link disconnects on a busy hub in half duplex */
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
+	ret_val = hw->phy.ops.read_reg_locked(hw,
+	                                      PHY_REG(BM_PORT_CTRL_PAGE, 17),
+	                                      &phy_data);
+	if (ret_val)
+		goto release;
+	ret_val = hw->phy.ops.write_reg_locked(hw,
+	                                       PHY_REG(BM_PORT_CTRL_PAGE, 17),
+	                                       phy_data & 0x00FF);
+release:
+	hw->phy.ops.release(hw);
 out:
 	return ret_val;
 }
@@ -1210,7 +1220,7 @@ static void e1000_lan_init_done_ich8lan(
 	 * leave the PHY in a bad state possibly resulting in no link.
 	 */
 	if (loop == 0)
-		hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
+		e_dbg("LAN_INIT_DONE not set, increase timeout\n");
 
 	/* Clear the Init Done bit for the next init event */
 	data = er32(STATUS);
@@ -1238,6 +1248,7 @@ static s32 e1000_phy_hw_reset_ich8lan(st
 	/* Allow time for h/w to get to a quiescent state after reset */
 	mdelay(10);
 
+	/* Perform any necessary post-reset workarounds */
 	if (hw->mac.type == e1000_pchlan) {
 		ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
 		if (ret_val)
@@ -1262,122 +1273,6 @@ out:
 }
 
 /**
- *  e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states
- *  @hw: pointer to the HW structure
- *
- *  Populates "phy" structure with various feature states.
- *  This function is only called by other family-specific
- *  routines.
- **/
-static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
-{
-	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
-	u16 data;
-	bool link;
-
-	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
-	if (ret_val)
-		return ret_val;
-
-	if (!link) {
-		hw_dbg(hw, "Phy info is only valid if link is up\n");
-		return -E1000_ERR_CONFIG;
-	}
-
-	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
-	if (ret_val)
-		return ret_val;
-	phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE));
-
-	if (phy->polarity_correction) {
-		ret_val = phy->ops.check_polarity(hw);
-		if (ret_val)
-			return ret_val;
-	} else {
-		/* Polarity is forced */
-		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
-	}
-
-	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
-	if (ret_val)
-		return ret_val;
-
-	phy->is_mdix = (data & IFE_PMC_MDIX_STATUS);
-
-	/* The following parameters are undefined for 10/100 operation. */
-	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
-	phy->local_rx = e1000_1000t_rx_status_undefined;
-	phy->remote_rx = e1000_1000t_rx_status_undefined;
-
-	return 0;
-}
-
-/**
- *  e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info
- *  @hw: pointer to the HW structure
- *
- *  Wrapper for calling the get_phy_info routines for the appropriate phy type.
- *  This is a function pointer entry point called by drivers
- *  or other shared routines.
- **/
-static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
-{
-	switch (hw->phy.type) {
-	case e1000_phy_ife:
-		return e1000_get_phy_info_ife_ich8lan(hw);
-		break;
-	case e1000_phy_igp_3:
-	case e1000_phy_bm:
-	case e1000_phy_82578:
-	case e1000_phy_82577:
-		return e1000e_get_phy_info_igp(hw);
-		break;
-	default:
-		break;
-	}
-
-	return -E1000_ERR_PHY_TYPE;
-}
-
-/**
- *  e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
- *  @hw: pointer to the HW structure
- *
- *  Polarity is determined on the polarity reversal feature being enabled.
- *  This function is only called by other family-specific
- *  routines.
- **/
-static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
-{
-	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
-	u16 phy_data, offset, mask;
-
-	/*
-	 * Polarity is determined based on the reversal feature being enabled.
-	 */
-	if (phy->polarity_correction) {
-		offset	= IFE_PHY_EXTENDED_STATUS_CONTROL;
-		mask	= IFE_PESC_POLARITY_REVERSED;
-	} else {
-		offset	= IFE_PHY_SPECIAL_CONTROL;
-		mask	= IFE_PSC_FORCE_POLARITY;
-	}
-
-	ret_val = e1e_rphy(hw, offset, &phy_data);
-
-	if (!ret_val)
-		phy->cable_polarity = (phy_data & mask)
-				      ? e1000_rev_polarity_reversed
-				      : e1000_rev_polarity_normal;
-
-	return ret_val;
-}
-
-/**
  *  e1000_set_lplu_state_pchlan - Set Low Power Link Up state
  *  @hw: pointer to the HW structure
  *  @active: true to enable LPLU, false to disable
@@ -1412,7 +1307,7 @@ out:
 /**
  *  e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
  *  @hw: pointer to the HW structure
- *  @active: TRUE to enable LPLU, FALSE to disable
+ *  @active: true to enable LPLU, false to disable
  *
  *  Sets the LPLU D0 state according to the active flag.  When
  *  activating LPLU this function also disables smart speed
@@ -1498,7 +1393,7 @@ static s32 e1000_set_d0_lplu_state_ich8l
 /**
  *  e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state
  *  @hw: pointer to the HW structure
- *  @active: TRUE to enable LPLU, FALSE to disable
+ *  @active: true to enable LPLU, false to disable
  *
  *  Sets the LPLU D3 state according to the active flag.  When
  *  activating LPLU this function also disables smart speed
@@ -1611,7 +1506,7 @@ static s32 e1000_valid_nvm_bank_detect_i
 
 			return 0;
 		}
-		hw_dbg(hw, "Unable to determine valid NVM bank via EEC - "
+		e_dbg("Unable to determine valid NVM bank via EEC - "
 		       "reading flash signature\n");
 		/* fall-thru */
 	default:
@@ -1641,7 +1536,7 @@ static s32 e1000_valid_nvm_bank_detect_i
 			return 0;
 		}
 
-		hw_dbg(hw, "ERROR: No valid NVM bank present\n");
+		e_dbg("ERROR: No valid NVM bank present\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -1669,16 +1564,16 @@ static s32 e1000_read_nvm_ich8lan(struct
 
 	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
 	    (words == 0)) {
-		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+		e_dbg("nvm parameter(s) out of bounds\n");
 		ret_val = -E1000_ERR_NVM;
 		goto out;
 	}
 
-	nvm->ops.acquire_nvm(hw);
+	nvm->ops.acquire(hw);
 
 	ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
 	if (ret_val) {
-		hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+		e_dbg("Could not detect valid bank, assuming bank 0\n");
 		bank = 0;
 	}
 
@@ -1700,11 +1595,11 @@ static s32 e1000_read_nvm_ich8lan(struct
 		}
 	}
 
-	nvm->ops.release_nvm(hw);
+	nvm->ops.release(hw);
 
 out:
 	if (ret_val)
-		hw_dbg(hw, "NVM read error: %d\n", ret_val);
+		e_dbg("NVM read error: %d\n", ret_val);
 
 	return ret_val;
 }
@@ -1726,7 +1621,7 @@ static s32 e1000_flash_cycle_init_ich8la
 
 	/* Check if the flash descriptor is valid */
 	if (hsfsts.hsf_status.fldesvalid == 0) {
-		hw_dbg(hw, "Flash descriptor invalid.  "
+		e_dbg("Flash descriptor invalid.  "
 			 "SW Sequencing must be used.");
 		return -E1000_ERR_NVM;
 	}
@@ -1749,7 +1644,7 @@ static s32 e1000_flash_cycle_init_ich8la
 	if (hsfsts.hsf_status.flcinprog == 0) {
 		/*
 		 * There is no cycle running at present,
-		 * so we can start a cycle
+		 * so we can start a cycle.
 		 * Begin by setting Flash Cycle Done.
 		 */
 		hsfsts.hsf_status.flcdone = 1;
@@ -1757,7 +1652,7 @@ static s32 e1000_flash_cycle_init_ich8la
 		ret_val = 0;
 	} else {
 		/*
-		 * otherwise poll for sometime so the current
+		 * Otherwise poll for sometime so the current
 		 * cycle has a chance to end before giving up.
 		 */
 		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
@@ -1776,7 +1671,7 @@ static s32 e1000_flash_cycle_init_ich8la
 			hsfsts.hsf_status.flcdone = 1;
 			ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 		} else {
-			hw_dbg(hw, "Flash controller busy, cannot get access");
+			e_dbg("Flash controller busy, cannot get access");
 		}
 	}
 
@@ -1926,7 +1821,7 @@ static s32 e1000_read_flash_data_ich8lan
 				/* Repeat for some time before giving up. */
 				continue;
 			} else if (hsfsts.hsf_status.flcdone == 0) {
-				hw_dbg(hw, "Timeout error - flash cycle "
+				e_dbg("Timeout error - flash cycle "
 					 "did not complete.");
 				break;
 			}
@@ -1954,18 +1849,18 @@ static s32 e1000_write_nvm_ich8lan(struc
 
 	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
 	    (words == 0)) {
-		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+		e_dbg("nvm parameter(s) out of bounds\n");
 		return -E1000_ERR_NVM;
 	}
 
-	nvm->ops.acquire_nvm(hw);
+	nvm->ops.acquire(hw);
 
 	for (i = 0; i < words; i++) {
-		dev_spec->shadow_ram[offset+i].modified = 1;
+		dev_spec->shadow_ram[offset+i].modified = true;
 		dev_spec->shadow_ram[offset+i].value = data[i];
 	}
 
-	nvm->ops.release_nvm(hw);
+	nvm->ops.release(hw);
 
 	return 0;
 }
@@ -1996,7 +1891,7 @@ static s32 e1000_update_nvm_checksum_ich
 	if (nvm->type != e1000_nvm_flash_sw)
 		goto out;
 
-	nvm->ops.acquire_nvm(hw);
+	nvm->ops.acquire(hw);
 
 	/*
 	 * We're writing to the opposite bank so if we're on bank 1,
@@ -2005,7 +1900,7 @@ static s32 e1000_update_nvm_checksum_ich
 	 */
 	ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
 	if (ret_val) {
-		hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+		e_dbg("Could not detect valid bank, assuming bank 0\n");
 		bank = 0;
 	}
 
@@ -2014,7 +1909,7 @@ static s32 e1000_update_nvm_checksum_ich
 		old_bank_offset = 0;
 		ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
 		if (ret_val) {
-			nvm->ops.release_nvm(hw);
+			nvm->ops.release(hw);
 			goto out;
 		}
 	} else {
@@ -2022,7 +1917,7 @@ static s32 e1000_update_nvm_checksum_ich
 		new_bank_offset = 0;
 		ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
 		if (ret_val) {
-			nvm->ops.release_nvm(hw);
+			nvm->ops.release(hw);
 			goto out;
 		}
 	}
@@ -2079,8 +1974,8 @@ static s32 e1000_update_nvm_checksum_ich
 	 */
 	if (ret_val) {
 		/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
-		hw_dbg(hw, "Flash commit failed.\n");
-		nvm->ops.release_nvm(hw);
+		e_dbg("Flash commit failed.\n");
+		nvm->ops.release(hw);
 		goto out;
 	}
 
@@ -2093,7 +1988,7 @@ static s32 e1000_update_nvm_checksum_ich
 	act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
 	ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
 	if (ret_val) {
-		nvm->ops.release_nvm(hw);
+		nvm->ops.release(hw);
 		goto out;
 	}
 	data &= 0xBFFF;
@@ -2101,7 +1996,7 @@ static s32 e1000_update_nvm_checksum_ich
 						       act_offset * 2 + 1,
 						       (u8)(data >> 8));
 	if (ret_val) {
-		nvm->ops.release_nvm(hw);
+		nvm->ops.release(hw);
 		goto out;
 	}
 
@@ -2114,17 +2009,17 @@ static s32 e1000_update_nvm_checksum_ich
 	act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
 	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
 	if (ret_val) {
-		nvm->ops.release_nvm(hw);
+		nvm->ops.release(hw);
 		goto out;
 	}
 
 	/* Great!  Everything worked, we can now clear the cached entries. */
 	for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
-		dev_spec->shadow_ram[i].modified = 0;
+		dev_spec->shadow_ram[i].modified = false;
 		dev_spec->shadow_ram[i].value = 0xFFFF;
 	}
 
-	nvm->ops.release_nvm(hw);
+	nvm->ops.release(hw);
 
 	/*
 	 * Reload the EEPROM, or else modifications will not appear
@@ -2135,7 +2030,7 @@ static s32 e1000_update_nvm_checksum_ich
 
 out:
 	if (ret_val)
-		hw_dbg(hw, "NVM update error: %d\n", ret_val);
+		e_dbg("NVM update error: %d\n", ret_val);
 
 	return ret_val;
 }
@@ -2193,7 +2088,7 @@ void e1000e_write_protect_nvm_ich8lan(st
 	union ich8_hws_flash_status hsfsts;
 	u32 gfpreg;
 
-	nvm->ops.acquire_nvm(hw);
+	nvm->ops.acquire(hw);
 
 	gfpreg = er32flash(ICH_FLASH_GFPREG);
 
@@ -2214,7 +2109,7 @@ void e1000e_write_protect_nvm_ich8lan(st
 	hsfsts.hsf_status.flockdn = true;
 	ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 
-	nvm->ops.release_nvm(hw);
+	nvm->ops.release(hw);
 }
 
 /**
@@ -2285,7 +2180,7 @@ static s32 e1000_write_flash_data_ich8la
 			/* Repeat for some time before giving up. */
 			continue;
 		if (hsfsts.hsf_status.flcdone == 0) {
-			hw_dbg(hw, "Timeout error - flash cycle "
+			e_dbg("Timeout error - flash cycle "
 				 "did not complete.");
 			break;
 		}
@@ -2330,7 +2225,7 @@ static s32 e1000_retry_write_flash_byte_
 		return ret_val;
 
 	for (program_retries = 0; program_retries < 100; program_retries++) {
-		hw_dbg(hw, "Retrying Byte %2.2X at offset %u\n", byte, offset);
+		e_dbg("Retrying Byte %2.2X at offset %u\n", byte, offset);
 		udelay(100);
 		ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
 		if (!ret_val)
@@ -2360,9 +2255,7 @@ static s32 e1000_erase_flash_bank_ich8la
 	u32 flash_bank_size = nvm->flash_bank_size * 2;
 	s32 ret_val;
 	s32 count = 0;
-	s32 iteration;
-	s32 sector_size;
-	s32 j;
+	s32 j, iteration, sector_size;
 
 	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
 
@@ -2465,7 +2358,7 @@ static s32 e1000_valid_led_default_ich8l
 
 	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 
@@ -2595,10 +2488,10 @@ static s32 e1000_reset_hw_ich8lan(struct
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
 	if (ret_val) {
-		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+		e_dbg("PCI-E Master disable polling has failed.\n");
 	}
 
-	hw_dbg(hw, "Masking off all interrupts\n");
+	e_dbg("Masking off all interrupts\n");
 	ew32(IMC, 0xffffffff);
 
 	/*
@@ -2649,14 +2542,17 @@ static s32 e1000_reset_hw_ich8lan(struct
 		ctrl |= E1000_CTRL_PHY_RST;
 	}
 	ret_val = e1000_acquire_swflag_ich8lan(hw);
-	/* Whether or not the swflag was acquired, we need to reset the part */
-	hw_dbg(hw, "Issuing a global reset to ich8lan\n");
+	e_dbg("Issuing a global reset to ich8lan\n");
 	ew32(CTRL, (ctrl | E1000_CTRL_RST));
 	msleep(20);
 
 	if (!ret_val)
 		e1000_release_swflag_ich8lan(hw);
 
+	/* Perform any necessary post-reset workarounds */
+	if (hw->mac.type == e1000_pchlan)
+		ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+
 	if (ctrl & E1000_CTRL_PHY_RST)
 		ret_val = hw->phy.ops.get_cfg_done(hw);
 
@@ -2670,7 +2566,7 @@ static s32 e1000_reset_hw_ich8lan(struct
 			 * return with an error. This can happen in situations
 			 * where there is no eeprom and prevents getting link.
 			 */
-			hw_dbg(hw, "Auto Read Done did not complete\n");
+			e_dbg("Auto Read Done did not complete\n");
 		}
 	}
 	/* Dummy read to clear the phy wakeup bit after lcd reset */
@@ -2701,9 +2597,6 @@ static s32 e1000_reset_hw_ich8lan(struct
 	kab |= E1000_KABGTXD_BGSQLBIAS;
 	ew32(KABGTXD, kab);
 
-	if (hw->mac.type == e1000_pchlan)
-		ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
-
 out:
 	return ret_val;
 }
@@ -2731,16 +2624,15 @@ static s32 e1000_init_hw_ich8lan(struct
 
 	/* Initialize identification LED */
 	ret_val = mac->ops.id_led_init(hw);
-	if (ret_val) {
-		hw_dbg(hw, "Error initializing identification LED\n");
-		return ret_val;
-	}
+	if (ret_val)
+		e_dbg("Error initializing identification LED\n");
+		/* This is not fatal and we should not stop init due to this */
 
 	/* Setup the receive address. */
 	e1000e_init_rx_addrs(hw, mac->rar_entry_count);
 
 	/* Zero out the Multicast HASH table */
-	hw_dbg(hw, "Zeroing the MTA\n");
+	e_dbg("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
 		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
 
@@ -2750,7 +2642,7 @@ static s32 e1000_init_hw_ich8lan(struct
 	 * Reset the phy after disabling host wakeup to reset the Rx buffer.
 	 */
 	if (hw->phy.type == e1000_phy_82578) {
-		hw->phy.ops.read_phy_reg(hw, BM_WUC, &i);
+		hw->phy.ops.read_reg(hw, BM_WUC, &i);
 		ret_val = e1000_phy_hw_reset_ich8lan(hw);
 		if (ret_val)
 			return ret_val;
@@ -2886,7 +2778,7 @@ static s32 e1000_setup_link_ich8lan(stru
 	 */
 	hw->fc.current_mode = hw->fc.requested_mode;
 
-	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n",
+	e_dbg("After fix-ups FlowControl is now = %x\n",
 		hw->fc.current_mode);
 
 	/* Continue to configure the copper link. */
@@ -2897,7 +2789,7 @@ static s32 e1000_setup_link_ich8lan(stru
 	ew32(FCTTV, hw->fc.pause_time);
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
-		ret_val = hw->phy.ops.write_phy_reg(hw,
+		ret_val = hw->phy.ops.write_reg(hw,
 		                             PHY_REG(BM_PORT_CTRL_PAGE, 27),
 		                             hw->fc.pause_time);
 		if (ret_val)
@@ -2931,14 +2823,16 @@ static s32 e1000_setup_copper_link_ich8l
 	 * and increase the max iterations when polling the phy;
 	 * this fixes erroneous timeouts at 10Mbps.
 	 */
-	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_TIMEOUTS, 0xFFFF);
 	if (ret_val)
 		return ret_val;
-	ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
+	ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
+	                               &reg_data);
 	if (ret_val)
 		return ret_val;
 	reg_data |= 0x3F;
-	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
+	                                reg_data);
 	if (ret_val)
 		return ret_val;
 
@@ -2960,7 +2854,7 @@ static s32 e1000_setup_copper_link_ich8l
 			return ret_val;
 		break;
 	case e1000_phy_ife:
-		ret_val = hw->phy.ops.read_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+		ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL,
 		                               &reg_data);
 		if (ret_val)
 			return ret_val;
@@ -2979,7 +2873,7 @@ static s32 e1000_setup_copper_link_ich8l
 			reg_data |= IFE_PMC_AUTO_MDIX;
 			break;
 		}
-		ret_val = hw->phy.ops.write_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+		ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL,
 		                                reg_data);
 		if (ret_val)
 			return ret_val;
@@ -3092,8 +2986,8 @@ static s32 e1000_kmrn_lock_loss_workarou
  *  @hw: pointer to the HW structure
  *  @state: boolean value used to set the current Kumeran workaround state
  *
- *  If ICH8, set the current Kumeran workaround state (enabled - TRUE
- *  /disabled - FALSE).
+ *  If ICH8, set the current Kumeran workaround state (enabled - true
+ *  /disabled - false).
  **/
 void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
 						 bool state)
@@ -3101,7 +2995,7 @@ void e1000e_set_kmrn_lock_loss_workaroun
 	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
 
 	if (hw->mac.type != e1000_ich8lan) {
-		hw_dbg(hw, "Workaround applies to ICH8 only.\n");
+		e_dbg("Workaround applies to ICH8 only.\n");
 		return;
 	}
 
@@ -3209,6 +3103,7 @@ void e1000e_disable_gig_wol_ich8lan(stru
 	u32 phy_ctrl;
 
 	switch (hw->mac.type) {
+	case e1000_ich8lan:
 	case e1000_ich9lan:
 	case e1000_ich10lan:
 	case e1000_pchlan:
@@ -3281,7 +3176,7 @@ static s32 e1000_led_off_ich8lan(struct
  **/
 static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
 {
-	return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
 					(u16)hw->mac.ledctl_mode1);
 }
 
@@ -3293,7 +3188,7 @@ static s32 e1000_setup_led_pchlan(struct
  **/
 static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
 {
-	return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
 					(u16)hw->mac.ledctl_default);
 }
 
@@ -3325,7 +3220,7 @@ static s32 e1000_led_on_pchlan(struct e1
 		}
 	}
 
-	return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
 }
 
 /**
@@ -3356,7 +3251,7 @@ static s32 e1000_led_off_pchlan(struct e
 		}
 	}
 
-	return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
 }
 
 /**
@@ -3379,8 +3274,7 @@ static s32 e1000_get_cfg_done_ich8lan(st
 		if (status & E1000_STATUS_PHYRA)
 			ew32(STATUS, status & ~E1000_STATUS_PHYRA);
 		else
-			hw_dbg(hw,
-			       "PHY Reset Asserted not set - needs delay\n");
+			e_dbg("PHY Reset Asserted not set - needs delay\n");
 	}
 
 	e1000e_get_cfg_done(hw);
@@ -3395,7 +3289,7 @@ static s32 e1000_get_cfg_done_ich8lan(st
 	} else {
 		if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) {
 			/* Maybe we should do a basic PHY config */
-			hw_dbg(hw, "EEPROM not present\n");
+			e_dbg("EEPROM not present\n");
 			return -E1000_ERR_CONFIG;
 		}
 	}
@@ -3404,6 +3298,23 @@ static s32 e1000_get_cfg_done_ich8lan(st
 }
 
 /**
+ * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
+{
+	/* If the management interface is not enabled, then power down */
+	if (!(hw->mac.ops.check_mng_mode(hw) ||
+	      hw->phy.ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
  *  @hw: pointer to the HW structure
  *
@@ -3412,42 +3323,41 @@ static s32 e1000_get_cfg_done_ich8lan(st
  **/
 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
 {
-	u32 temp;
 	u16 phy_data;
 
 	e1000e_clear_hw_cntrs_base(hw);
 
-	temp = er32(ALGNERRC);
-	temp = er32(RXERRC);
-	temp = er32(TNCRS);
-	temp = er32(CEXTERR);
-	temp = er32(TSCTC);
-	temp = er32(TSCTFC);
+	er32(ALGNERRC);
+	er32(RXERRC);
+	er32(TNCRS);
+	er32(CEXTERR);
+	er32(TSCTC);
+	er32(TSCTFC);
 
-	temp = er32(MGTPRC);
-	temp = er32(MGTPDC);
-	temp = er32(MGTPTC);
+	er32(MGTPRC);
+	er32(MGTPDC);
+	er32(MGTPTC);
 
-	temp = er32(IAC);
-	temp = er32(ICRXOC);
+	er32(IAC);
+	er32(ICRXOC);
 
 	/* Clear PHY statistics registers */
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
-		hw->phy.ops.read_phy_reg(hw, HV_SCC_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_SCC_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_ECOL_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_ECOL_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_MCC_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_MCC_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_LATECOL_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_LATECOL_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_COLC_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_COLC_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_DC_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_DC_LOWER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_TNCRS_UPPER, &phy_data);
-		hw->phy.ops.read_phy_reg(hw, HV_TNCRS_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_ECOL_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_ECOL_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_MCC_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_MCC_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_LATECOL_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_LATECOL_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_COLC_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_COLC_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_DC_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_DC_LOWER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_TNCRS_UPPER, &phy_data);
+		hw->phy.ops.read_reg(hw, HV_TNCRS_LOWER, &phy_data);
 	}
 }
 
@@ -3470,29 +3380,27 @@ static struct e1000_mac_operations ich8_
 };
 
 static struct e1000_phy_operations ich8_phy_ops = {
-	.acquire_phy		= e1000_acquire_swflag_ich8lan,
+	.acquire		= e1000_acquire_swflag_ich8lan,
 	.check_reset_block	= e1000_check_reset_block_ich8lan,
-	.commit_phy		= NULL,
-	.force_speed_duplex	= e1000_phy_force_speed_duplex_ich8lan,
+	.commit			= NULL,
 	.get_cfg_done		= e1000_get_cfg_done_ich8lan,
 	.get_cable_length	= e1000e_get_cable_length_igp_2,
-	.get_phy_info		= e1000_get_phy_info_ich8lan,
-	.read_phy_reg		= e1000e_read_phy_reg_igp,
-	.release_phy		= e1000_release_swflag_ich8lan,
-	.reset_phy		= e1000_phy_hw_reset_ich8lan,
+	.read_reg		= e1000e_read_phy_reg_igp,
+	.release		= e1000_release_swflag_ich8lan,
+	.reset			= e1000_phy_hw_reset_ich8lan,
 	.set_d0_lplu_state	= e1000_set_d0_lplu_state_ich8lan,
 	.set_d3_lplu_state	= e1000_set_d3_lplu_state_ich8lan,
-	.write_phy_reg		= e1000e_write_phy_reg_igp,
+	.write_reg		= e1000e_write_phy_reg_igp,
 };
 
 static struct e1000_nvm_operations ich8_nvm_ops = {
-	.acquire_nvm		= e1000_acquire_nvm_ich8lan,
-	.read_nvm	 	= e1000_read_nvm_ich8lan,
-	.release_nvm		= e1000_release_nvm_ich8lan,
-	.update_nvm		= e1000_update_nvm_checksum_ich8lan,
+	.acquire		= e1000_acquire_nvm_ich8lan,
+	.read		 	= e1000_read_nvm_ich8lan,
+	.release		= e1000_release_nvm_ich8lan,
+	.update			= e1000_update_nvm_checksum_ich8lan,
 	.valid_led_default	= e1000_valid_led_default_ich8lan,
-	.validate_nvm		= e1000_validate_nvm_checksum_ich8lan,
-	.write_nvm		= e1000_write_nvm_ich8lan,
+	.validate		= e1000_validate_nvm_checksum_ich8lan,
+	.write			= e1000_write_nvm_ich8lan,
 };
 
 struct e1000_info e1000_ich8_info = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/lib.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/lib.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/lib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/lib.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -26,11 +26,6 @@
 
 *******************************************************************************/
 
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
 #include "e1000.h"
 
 enum e1000_mng_mode {
@@ -87,7 +82,24 @@ s32 e1000e_get_bus_info_pcie(struct e100
 }
 
 /**
- *  e1000e_write_vfta - Write value to VLAN filter table
+ *  e1000_clear_vfta_generic - Clear VLAN filter table
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the register array which contains the VLAN filter table by
+ *  setting all the values to 0.
+ **/
+void e1000_clear_vfta_generic(struct e1000_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
+		e1e_flush();
+	}
+}
+
+/**
+ *  e1000_write_vfta_generic - Write value to VLAN filter table
  *  @hw: pointer to the HW structure
  *  @offset: register offset in VLAN filter table
  *  @value: register value written to VLAN filter table
@@ -95,7 +107,7 @@ s32 e1000e_get_bus_info_pcie(struct e100
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
 {
 	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
 	e1e_flush();
@@ -113,20 +125,17 @@ void e1000e_write_vfta(struct e1000_hw *
 void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
 {
 	u32 i;
+	u8 mac_addr[ETH_ALEN] = {0};
 
 	/* Setup the receive address */
-	hw_dbg(hw, "Programming MAC Address into RAR[0]\n");
+	e_dbg("Programming MAC Address into RAR[0]\n");
 
 	e1000e_rar_set(hw, hw->mac.addr, 0);
 
 	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	hw_dbg(hw, "Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0);
-		e1e_flush();
-		E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0);
-		e1e_flush();
-	}
+	e_dbg("Clearing RAR[1-%u]\n", rar_count-1);
+	for (i = 1; i < rar_count; i++)
+		e1000e_rar_set(hw, mac_addr, i);
 }
 
 /**
@@ -152,10 +161,19 @@ void e1000e_rar_set(struct e1000_hw *hw,
 
 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
 
-	rar_high |= E1000_RAH_AV;
+	/* If MAC address zero, no need to set the AV bit */
+	if (rar_low || rar_high)
+		rar_high |= E1000_RAH_AV;
 
-	E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
-	E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
+	/*
+	 * Some bridges will combine consecutive 32-bit writes into
+	 * a single burst write, which will malfunction on some parts.
+	 * The flushes avoid this.
+	 */
+	ew32(RAL(index), rar_low);
+	e1e_flush();
+	ew32(RAH(index), rar_high);
+	e1e_flush();
 }
 
 /**
@@ -276,7 +294,7 @@ void e1000e_update_mc_addr_list_generic(
 	for (; mc_addr_count > 0; mc_addr_count--) {
 		u32 hash_value, hash_reg, hash_bit, mta;
 		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
-		hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
+		e_dbg("Hash value = 0x%03X\n", hash_value);
 		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
 		hash_bit = hash_value & 0x1F;
 		mta = (1 << hash_bit);
@@ -300,45 +318,43 @@ void e1000e_update_mc_addr_list_generic(
  **/
 void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
 {
-	u32 temp;
-
-	temp = er32(CRCERRS);
-	temp = er32(SYMERRS);
-	temp = er32(MPC);
-	temp = er32(SCC);
-	temp = er32(ECOL);
-	temp = er32(MCC);
-	temp = er32(LATECOL);
-	temp = er32(COLC);
-	temp = er32(DC);
-	temp = er32(SEC);
-	temp = er32(RLEC);
-	temp = er32(XONRXC);
-	temp = er32(XONTXC);
-	temp = er32(XOFFRXC);
-	temp = er32(XOFFTXC);
-	temp = er32(FCRUC);
-	temp = er32(GPRC);
-	temp = er32(BPRC);
-	temp = er32(MPRC);
-	temp = er32(GPTC);
-	temp = er32(GORCL);
-	temp = er32(GORCH);
-	temp = er32(GOTCL);
-	temp = er32(GOTCH);
-	temp = er32(RNBC);
-	temp = er32(RUC);
-	temp = er32(RFC);
-	temp = er32(ROC);
-	temp = er32(RJC);
-	temp = er32(TORL);
-	temp = er32(TORH);
-	temp = er32(TOTL);
-	temp = er32(TOTH);
-	temp = er32(TPR);
-	temp = er32(TPT);
-	temp = er32(MPTC);
-	temp = er32(BPTC);
+	er32(CRCERRS);
+	er32(SYMERRS);
+	er32(MPC);
+	er32(SCC);
+	er32(ECOL);
+	er32(MCC);
+	er32(LATECOL);
+	er32(COLC);
+	er32(DC);
+	er32(SEC);
+	er32(RLEC);
+	er32(XONRXC);
+	er32(XONTXC);
+	er32(XOFFRXC);
+	er32(XOFFTXC);
+	er32(FCRUC);
+	er32(GPRC);
+	er32(BPRC);
+	er32(MPRC);
+	er32(GPTC);
+	er32(GORCL);
+	er32(GORCH);
+	er32(GOTCL);
+	er32(GOTCH);
+	er32(RNBC);
+	er32(RUC);
+	er32(RFC);
+	er32(ROC);
+	er32(RJC);
+	er32(TORL);
+	er32(TORH);
+	er32(TOTL);
+	er32(TOTH);
+	er32(TPR);
+	er32(TPT);
+	er32(MPTC);
+	er32(BPTC);
 }
 
 /**
@@ -376,7 +392,7 @@ s32 e1000e_check_for_copper_link(struct
 	if (!link)
 		return ret_val; /* No link detected */
 
-	mac->get_link_status = 0;
+	mac->get_link_status = false;
 
 	/*
 	 * Check if there was DownShift, must be checked
@@ -408,7 +424,7 @@ s32 e1000e_check_for_copper_link(struct
 	 */
 	ret_val = e1000e_config_fc_after_link_up(hw);
 	if (ret_val) {
-		hw_dbg(hw, "Error configuring flow control\n");
+		e_dbg("Error configuring flow control\n");
 	}
 
 	return ret_val;
@@ -448,7 +464,7 @@ s32 e1000e_check_for_fiber_link(struct e
 			mac->autoneg_failed = 1;
 			return 0;
 		}
-		hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n");
+		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
 
 		/* Disable auto-negotiation in the TXCW register */
 		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
@@ -461,7 +477,7 @@ s32 e1000e_check_for_fiber_link(struct e
 		/* Configure Flow Control after forcing link up. */
 		ret_val = e1000e_config_fc_after_link_up(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error configuring flow control\n");
+			e_dbg("Error configuring flow control\n");
 			return ret_val;
 		}
 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
@@ -471,7 +487,7 @@ s32 e1000e_check_for_fiber_link(struct e
 		 * and disable forced link in the Device Control register
 		 * in an attempt to auto-negotiate with our link partner.
 		 */
-		hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");
+		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
 		ew32(TXCW, mac->txcw);
 		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
@@ -513,7 +529,7 @@ s32 e1000e_check_for_serdes_link(struct
 			mac->autoneg_failed = 1;
 			return 0;
 		}
-		hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n");
+		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
 
 		/* Disable auto-negotiation in the TXCW register */
 		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
@@ -526,7 +542,7 @@ s32 e1000e_check_for_serdes_link(struct
 		/* Configure Flow Control after forcing link up. */
 		ret_val = e1000e_config_fc_after_link_up(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error configuring flow control\n");
+			e_dbg("Error configuring flow control\n");
 			return ret_val;
 		}
 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
@@ -536,7 +552,7 @@ s32 e1000e_check_for_serdes_link(struct
 		 * and disable forced link in the Device Control register
 		 * in an attempt to auto-negotiate with our link partner.
 		 */
-		hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");
+		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
 		ew32(TXCW, mac->txcw);
 		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
@@ -553,11 +569,11 @@ s32 e1000e_check_for_serdes_link(struct
 		if (rxcw & E1000_RXCW_SYNCH) {
 			if (!(rxcw & E1000_RXCW_IV)) {
 				mac->serdes_has_link = true;
-				hw_dbg(hw, "SERDES: Link up - forced.\n");
+				e_dbg("SERDES: Link up - forced.\n");
 			}
 		} else {
 			mac->serdes_has_link = false;
-			hw_dbg(hw, "SERDES: Link down - force failed.\n");
+			e_dbg("SERDES: Link down - force failed.\n");
 		}
 	}
 
@@ -570,20 +586,20 @@ s32 e1000e_check_for_serdes_link(struct
 			if (rxcw & E1000_RXCW_SYNCH) {
 				if (!(rxcw & E1000_RXCW_IV)) {
 					mac->serdes_has_link = true;
-					hw_dbg(hw, "SERDES: Link up - autoneg "
+					e_dbg("SERDES: Link up - autoneg "
 					   "completed sucessfully.\n");
 				} else {
 					mac->serdes_has_link = false;
-					hw_dbg(hw, "SERDES: Link down - invalid"
+					e_dbg("SERDES: Link down - invalid"
 					   "codewords detected in autoneg.\n");
 				}
 			} else {
 				mac->serdes_has_link = false;
-				hw_dbg(hw, "SERDES: Link down - no sync.\n");
+				e_dbg("SERDES: Link down - no sync.\n");
 			}
 		} else {
 			mac->serdes_has_link = false;
-			hw_dbg(hw, "SERDES: Link down - autoneg failed\n");
+			e_dbg("SERDES: Link down - autoneg failed\n");
 		}
 	}
 
@@ -614,7 +630,7 @@ static s32 e1000_set_default_fc_generic(
 	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
 
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 
@@ -667,7 +683,7 @@ s32 e1000e_setup_link(struct e1000_hw *h
 	 */
 	hw->fc.current_mode = hw->fc.requested_mode;
 
-	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n",
+	e_dbg("After fix-ups FlowControl is now = %x\n",
 		hw->fc.current_mode);
 
 	/* Call the necessary media_type subroutine to configure the link. */
@@ -681,7 +697,7 @@ s32 e1000e_setup_link(struct e1000_hw *h
 	 * control is disabled, because it does not hurt anything to
 	 * initialize these registers.
 	 */
-	hw_dbg(hw, "Initializing the Flow Control address, type and timer regs\n");
+	e_dbg("Initializing the Flow Control address, type and timer regs\n");
 	ew32(FCT, FLOW_CONTROL_TYPE);
 	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
 	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
@@ -751,7 +767,7 @@ static s32 e1000_commit_fc_settings_gene
 		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
 		break;
 	default:
-		hw_dbg(hw, "Flow control param set incorrectly\n");
+		e_dbg("Flow control param set incorrectly\n");
 		return -E1000_ERR_CONFIG;
 		break;
 	}
@@ -789,7 +805,7 @@ static s32 e1000_poll_fiber_serdes_link_
 			break;
 	}
 	if (i == FIBER_LINK_UP_LIMIT) {
-		hw_dbg(hw, "Never got a valid link from auto-neg!!!\n");
+		e_dbg("Never got a valid link from auto-neg!!!\n");
 		mac->autoneg_failed = 1;
 		/*
 		 * AutoNeg failed to achieve a link, so we'll call
@@ -799,13 +815,13 @@ static s32 e1000_poll_fiber_serdes_link_
 		 */
 		ret_val = mac->ops.check_for_link(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error while checking for link\n");
+			e_dbg("Error while checking for link\n");
 			return ret_val;
 		}
 		mac->autoneg_failed = 0;
 	} else {
 		mac->autoneg_failed = 0;
-		hw_dbg(hw, "Valid Link Found\n");
+		e_dbg("Valid Link Found\n");
 	}
 
 	return 0;
@@ -841,7 +857,7 @@ s32 e1000e_setup_fiber_serdes_link(struc
 	 * then the link-up status bit will be set and the flow control enable
 	 * bits (RFCE and TFCE) will be set according to their negotiated value.
 	 */
-	hw_dbg(hw, "Auto-negotiation enabled\n");
+	e_dbg("Auto-negotiation enabled\n");
 
 	ew32(CTRL, ctrl);
 	e1e_flush();
@@ -856,7 +872,7 @@ s32 e1000e_setup_fiber_serdes_link(struc
 	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
 		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
 	} else {
-		hw_dbg(hw, "No signal detected\n");
+		e_dbg("No signal detected\n");
 	}
 
 	return 0;
@@ -952,7 +968,7 @@ s32 e1000e_force_mac_fc(struct e1000_hw
 	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
 	 *  other:  No other values should be possible at this point.
 	 */
-	hw_dbg(hw, "hw->fc.current_mode = %u\n", hw->fc.current_mode);
+	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
 
 	switch (hw->fc.current_mode) {
 	case e1000_fc_none:
@@ -970,7 +986,7 @@ s32 e1000e_force_mac_fc(struct e1000_hw
 		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
 		break;
 	default:
-		hw_dbg(hw, "Flow control param set incorrectly\n");
+		e_dbg("Flow control param set incorrectly\n");
 		return -E1000_ERR_CONFIG;
 	}
 
@@ -1011,7 +1027,7 @@ s32 e1000e_config_fc_after_link_up(struc
 	}
 
 	if (ret_val) {
-		hw_dbg(hw, "Error forcing flow control settings\n");
+		e_dbg("Error forcing flow control settings\n");
 		return ret_val;
 	}
 
@@ -1035,7 +1051,7 @@ s32 e1000e_config_fc_after_link_up(struc
 			return ret_val;
 
 		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
-			hw_dbg(hw, "Copper PHY and Auto Neg "
+			e_dbg("Copper PHY and Auto Neg "
 				 "has not completed.\n");
 			return ret_val;
 		}
@@ -1076,7 +1092,6 @@ s32 e1000e_config_fc_after_link_up(struc
 		 *   1   |    1    |   0   |    0    | e1000_fc_none
 		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
 		 *
-		 *
 		 * Are both PAUSE bits set to 1?  If so, this implies
 		 * Symmetric Flow Control is enabled at both ends.  The
 		 * ASM_DIR bits are irrelevant per the spec.
@@ -1100,10 +1115,10 @@ s32 e1000e_config_fc_after_link_up(struc
 			 */
 			if (hw->fc.requested_mode == e1000_fc_full) {
 				hw->fc.current_mode = e1000_fc_full;
-				hw_dbg(hw, "Flow Control = FULL.\r\n");
+				e_dbg("Flow Control = FULL.\r\n");
 			} else {
 				hw->fc.current_mode = e1000_fc_rx_pause;
-				hw_dbg(hw, "Flow Control = "
+				e_dbg("Flow Control = "
 					 "RX PAUSE frames only.\r\n");
 			}
 		}
@@ -1114,14 +1129,13 @@ s32 e1000e_config_fc_after_link_up(struc
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
 		 *-------|---------|-------|---------|--------------------
 		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-		 *
 		 */
 		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 			hw->fc.current_mode = e1000_fc_tx_pause;
-			hw_dbg(hw, "Flow Control = Tx PAUSE frames only.\r\n");
+			e_dbg("Flow Control = Tx PAUSE frames only.\r\n");
 		}
 		/*
 		 * For transmitting PAUSE frames ONLY.
@@ -1130,21 +1144,20 @@ s32 e1000e_config_fc_after_link_up(struc
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
 		 *-------|---------|-------|---------|--------------------
 		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-		 *
 		 */
 		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 			hw->fc.current_mode = e1000_fc_rx_pause;
-			hw_dbg(hw, "Flow Control = Rx PAUSE frames only.\r\n");
+			e_dbg("Flow Control = Rx PAUSE frames only.\r\n");
 		} else {
 			/*
 			 * Per the IEEE spec, at this point flow control
 			 * should be disabled.
 			 */
 			hw->fc.current_mode = e1000_fc_none;
-			hw_dbg(hw, "Flow Control = NONE.\r\n");
+			e_dbg("Flow Control = NONE.\r\n");
 		}
 
 		/*
@@ -1154,7 +1167,7 @@ s32 e1000e_config_fc_after_link_up(struc
 		 */
 		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
 		if (ret_val) {
-			hw_dbg(hw, "Error getting link speed and duplex\n");
+			e_dbg("Error getting link speed and duplex\n");
 			return ret_val;
 		}
 
@@ -1167,7 +1180,7 @@ s32 e1000e_config_fc_after_link_up(struc
 		 */
 		ret_val = e1000e_force_mac_fc(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error forcing flow control settings\n");
+			e_dbg("Error forcing flow control settings\n");
 			return ret_val;
 		}
 	}
@@ -1191,21 +1204,21 @@ s32 e1000e_get_speed_and_duplex_copper(s
 	status = er32(STATUS);
 	if (status & E1000_STATUS_SPEED_1000) {
 		*speed = SPEED_1000;
-		hw_dbg(hw, "1000 Mbs, ");
+		e_dbg("1000 Mbs, ");
 	} else if (status & E1000_STATUS_SPEED_100) {
 		*speed = SPEED_100;
-		hw_dbg(hw, "100 Mbs, ");
+		e_dbg("100 Mbs, ");
 	} else {
 		*speed = SPEED_10;
-		hw_dbg(hw, "10 Mbs, ");
+		e_dbg("10 Mbs, ");
 	}
 
 	if (status & E1000_STATUS_FD) {
 		*duplex = FULL_DUPLEX;
-		hw_dbg(hw, "Full Duplex\n");
+		e_dbg("Full Duplex\n");
 	} else {
 		*duplex = HALF_DUPLEX;
-		hw_dbg(hw, "Half Duplex\n");
+		e_dbg("Half Duplex\n");
 	}
 
 	return 0;
@@ -1251,7 +1264,7 @@ s32 e1000e_get_hw_semaphore(struct e1000
 	}
 
 	if (i == timeout) {
-		hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+		e_dbg("Driver can't access device - SMBI bit is set.\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -1270,7 +1283,7 @@ s32 e1000e_get_hw_semaphore(struct e1000
 	if (i == timeout) {
 		/* Release semaphores */
 		e1000e_put_hw_semaphore(hw);
-		hw_dbg(hw, "Driver can't access the NVM\n");
+		e_dbg("Driver can't access the NVM\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -1310,7 +1323,7 @@ s32 e1000e_get_auto_rd_done(struct e1000
 	}
 
 	if (i == AUTO_READ_DONE_TIMEOUT) {
-		hw_dbg(hw, "Auto read by HW from NVM has not completed.\n");
+		e_dbg("Auto read by HW from NVM has not completed.\n");
 		return -E1000_ERR_RESET;
 	}
 
@@ -1331,7 +1344,7 @@ s32 e1000e_valid_led_default(struct e100
 
 	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 
@@ -1585,7 +1598,7 @@ s32 e1000e_disable_pcie_master(struct e1
 	}
 
 	if (!timeout) {
-		hw_dbg(hw, "Master requests are pending.\n");
+		e_dbg("Master requests are pending.\n");
 		return -E1000_ERR_MASTER_REQUESTS_PENDING;
 	}
 
@@ -1602,14 +1615,21 @@ void e1000e_reset_adaptive(struct e1000_
 {
 	struct e1000_mac_info *mac = &hw->mac;
 
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		goto out;
+	}
+
 	mac->current_ifs_val = 0;
 	mac->ifs_min_val = IFS_MIN;
 	mac->ifs_max_val = IFS_MAX;
 	mac->ifs_step_size = IFS_STEP;
 	mac->ifs_ratio = IFS_RATIO;
 
-	mac->in_ifs_mode = 0;
+	mac->in_ifs_mode = false;
 	ew32(AIT, 0);
+out:
+	return;
 }
 
 /**
@@ -1623,9 +1643,14 @@ void e1000e_update_adaptive(struct e1000
 {
 	struct e1000_mac_info *mac = &hw->mac;
 
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		goto out;
+	}
+
 	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
 		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
-			mac->in_ifs_mode = 1;
+			mac->in_ifs_mode = true;
 			if (mac->current_ifs_val < mac->ifs_max_val) {
 				if (!mac->current_ifs_val)
 					mac->current_ifs_val = mac->ifs_min_val;
@@ -1639,10 +1664,12 @@ void e1000e_update_adaptive(struct e1000
 		if (mac->in_ifs_mode &&
 		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
 			mac->current_ifs_val = 0;
-			mac->in_ifs_mode = 0;
+			mac->in_ifs_mode = false;
 			ew32(AIT, 0);
 		}
 	}
+out:
+	return;
 }
 
 /**
@@ -1809,7 +1836,7 @@ s32 e1000e_acquire_nvm(struct e1000_hw *
 	if (!timeout) {
 		eecd &= ~E1000_EECD_REQ;
 		ew32(EECD, eecd);
-		hw_dbg(hw, "Could not acquire NVM grant\n");
+		e_dbg("Could not acquire NVM grant\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -1914,7 +1941,7 @@ static s32 e1000_ready_nvm_eeprom(struct
 		}
 
 		if (!timeout) {
-			hw_dbg(hw, "SPI NVM Status error\n");
+			e_dbg("SPI NVM Status error\n");
 			return -E1000_ERR_NVM;
 		}
 	}
@@ -1943,7 +1970,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw
 	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
-		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+		e_dbg("nvm parameter(s) out of bounds\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -1986,11 +2013,11 @@ s32 e1000e_write_nvm_spi(struct e1000_hw
 	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
-		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+		e_dbg("nvm parameter(s) out of bounds\n");
 		return -E1000_ERR_NVM;
 	}
 
-	ret_val = nvm->ops.acquire_nvm(hw);
+	ret_val = nvm->ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -2001,7 +2028,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw
 
 		ret_val = e1000_ready_nvm_eeprom(hw);
 		if (ret_val) {
-			nvm->ops.release_nvm(hw);
+			nvm->ops.release(hw);
 			return ret_val;
 		}
 
@@ -2040,7 +2067,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw
 	}
 
 	msleep(10);
-	nvm->ops.release_nvm(hw);
+	nvm->ops.release(hw);
 	return 0;
 }
 
@@ -2066,7 +2093,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw
 		ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
 					 &mac_addr_offset);
 		if (ret_val) {
-			hw_dbg(hw, "NVM Read Error\n");
+			e_dbg("NVM Read Error\n");
 			return ret_val;
 		}
 		if (mac_addr_offset == 0xFFFF)
@@ -2081,7 +2108,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw
 			ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
 						 &nvm_data);
 			if (ret_val) {
-				hw_dbg(hw, "NVM Read Error\n");
+				e_dbg("NVM Read Error\n");
 				return ret_val;
 			}
 			if (nvm_data & 0x0001)
@@ -2096,7 +2123,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw
 		offset = mac_addr_offset + (i >> 1);
 		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
 		if (ret_val) {
-			hw_dbg(hw, "NVM Read Error\n");
+			e_dbg("NVM Read Error\n");
 			return ret_val;
 		}
 		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
@@ -2129,14 +2156,14 @@ s32 e1000e_validate_nvm_checksum_generic
 	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
 		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
 		if (ret_val) {
-			hw_dbg(hw, "NVM Read Error\n");
+			e_dbg("NVM Read Error\n");
 			return ret_val;
 		}
 		checksum += nvm_data;
 	}
 
 	if (checksum != (u16) NVM_SUM) {
-		hw_dbg(hw, "NVM Checksum Invalid\n");
+		e_dbg("NVM Checksum Invalid\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -2160,7 +2187,7 @@ s32 e1000e_update_nvm_checksum_generic(s
 	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
 		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
 		if (ret_val) {
-			hw_dbg(hw, "NVM Read Error while updating checksum.\n");
+			e_dbg("NVM Read Error while updating checksum.\n");
 			return ret_val;
 		}
 		checksum += nvm_data;
@@ -2168,7 +2195,7 @@ s32 e1000e_update_nvm_checksum_generic(s
 	checksum = (u16) NVM_SUM - checksum;
 	ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
 	if (ret_val)
-		hw_dbg(hw, "NVM Write Error while updating checksum.\n");
+		e_dbg("NVM Write Error while updating checksum.\n");
 
 	return ret_val;
 }
@@ -2231,7 +2258,7 @@ static s32 e1000_mng_enable_host_if(stru
 	/* Check that the host interface is enabled. */
 	hicr = er32(HICR);
 	if ((hicr & E1000_HICR_EN) == 0) {
-		hw_dbg(hw, "E1000_HOST_EN bit disabled.\n");
+		e_dbg("E1000_HOST_EN bit disabled.\n");
 		return -E1000_ERR_HOST_INTERFACE_COMMAND;
 	}
 	/* check the previous command is completed */
@@ -2243,7 +2270,7 @@ static s32 e1000_mng_enable_host_if(stru
 	}
 
 	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
-		hw_dbg(hw, "Previous command timeout failed .\n");
+		e_dbg("Previous command timeout failed .\n");
 		return -E1000_ERR_HOST_INTERFACE_COMMAND;
 	}
 
@@ -2280,10 +2307,12 @@ bool e1000e_enable_tx_pkt_filtering(stru
 	s32 ret_val, hdr_csum, csum;
 	u8 i, len;
 
+	hw->mac.tx_pkt_filtering = true;
+
 	/* No manageability, no filtering */
 	if (!e1000e_check_mng_mode(hw)) {
-		hw->mac.tx_pkt_filtering = 0;
-		return 0;
+		hw->mac.tx_pkt_filtering = false;
+		goto out;
 	}
 
 	/*
@@ -2291,9 +2320,9 @@ bool e1000e_enable_tx_pkt_filtering(stru
 	 * reason, disable filtering.
 	 */
 	ret_val = e1000_mng_enable_host_if(hw);
-	if (ret_val != 0) {
-		hw->mac.tx_pkt_filtering = 0;
-		return ret_val;
+	if (ret_val) {
+		hw->mac.tx_pkt_filtering = false;
+		goto out;
 	}
 
 	/* Read in the header.  Length and offset are in dwords. */
@@ -2311,18 +2340,18 @@ bool e1000e_enable_tx_pkt_filtering(stru
 	 * take the safe route of assuming Tx filtering is enabled.
 	 */
 	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
-		hw->mac.tx_pkt_filtering = 1;
-		return 1;
+		hw->mac.tx_pkt_filtering = true;
+		goto out;
 	}
 
 	/* Cookie area is valid, make the final check for filtering. */
 	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
-		hw->mac.tx_pkt_filtering = 0;
-		return 0;
+		hw->mac.tx_pkt_filtering = false;
+		goto out;
 	}
 
-	hw->mac.tx_pkt_filtering = 1;
-	return 1;
+out:
+	return hw->mac.tx_pkt_filtering;
 }
 
 /**
@@ -2353,7 +2382,7 @@ static s32 e1000_mng_write_cmd_header(st
 }
 
 /**
- *  e1000_mng_host_if_write - Writes to the manageability host interface
+ *  e1000_mng_host_if_write - Write to the manageability host interface
  *  @hw: pointer to the HW structure
  *  @buffer: pointer to the host interface buffer
  *  @length: size of the buffer
@@ -2478,7 +2507,7 @@ bool e1000e_enable_mng_pass_thru(struct
 {
 	u32 manc;
 	u32 fwsm, factps;
-	bool ret_val = 0;
+	bool ret_val = false;
 
 	manc = er32(MANC);
 
@@ -2493,13 +2522,13 @@ bool e1000e_enable_mng_pass_thru(struct
 		if (!(factps & E1000_FACTPS_MNGCG) &&
 		    ((fwsm & E1000_FWSM_MODE_MASK) ==
 		     (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
-			ret_val = 1;
+			ret_val = true;
 			return ret_val;
 		}
 	} else {
 		if ((manc & E1000_MANC_SMBUS_EN) &&
 		    !(manc & E1000_MANC_ASF_EN)) {
-			ret_val = 1;
+			ret_val = true;
 			return ret_val;
 		}
 	}
@@ -2514,14 +2543,14 @@ s32 e1000e_read_pba_num(struct e1000_hw
 
 	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 	*pba_num = (u32)(nvm_data << 16);
 
 	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
 	if (ret_val) {
-		hw_dbg(hw, "NVM Read Error\n");
+		e_dbg("NVM Read Error\n");
 		return ret_val;
 	}
 	*pba_num |= nvm_data;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/netdev.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/netdev.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/netdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/netdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -65,17 +65,6 @@ static const struct e1000_info *e1000_in
 	[board_pchlan]		= &e1000_pch_info,
 };
 
-#ifdef DEBUG
-/**
- * e1000_get_hw_dev_name - return device name string
- * used by hardware layer to print debugging information
- **/
-char *e1000e_get_hw_dev_name(struct e1000_hw *hw)
-{
-	return hw->adapter->netdev->name;
-}
-#endif
-
 /**
  * e1000_desc_unused - calculate if we have unused descriptors
  **/
@@ -167,7 +156,7 @@ static void e1000_alloc_rx_buffers(struc
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
-	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+	unsigned int bufsz = adapter->rx_buffer_len;
 
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -179,20 +168,13 @@ static void e1000_alloc_rx_buffers(struc
 			goto map_skb;
 		}
 
-		skb = netdev_alloc_skb(netdev, bufsz);
+		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 		if (!skb) {
 			/* Better luck next round */
 			adapter->alloc_rx_buff_failed++;
 			break;
 		}
 
-		/*
-		 * Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 map_skb:
 		buffer_info->dma = pci_map_single(pdev, skb->data,
@@ -284,21 +266,14 @@ static void e1000_alloc_rx_buffers_ps(st
 			     cpu_to_le64(ps_page->dma);
 		}
 
-		skb = netdev_alloc_skb(netdev,
-				       adapter->rx_ps_bsize0 + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(netdev,
+						adapter->rx_ps_bsize0);
 
 		if (!skb) {
 			adapter->alloc_rx_buff_failed++;
 			break;
 		}
 
-		/*
-		 * Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 		buffer_info->dma = pci_map_single(pdev, skb->data,
 						  adapter->rx_ps_bsize0,
@@ -359,9 +334,7 @@ static void e1000_alloc_jumbo_rx_buffers
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
-	unsigned int bufsz = 256 -
-	                     16 /* for skb_reserve */ -
-	                     NET_IP_ALIGN;
+	unsigned int bufsz = 256 - 16 /* for skb_reserve */;
 
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -373,19 +346,13 @@ static void e1000_alloc_jumbo_rx_buffers
 			goto check_page;
 		}
 
-		skb = netdev_alloc_skb(netdev, bufsz);
+		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 		if (unlikely(!skb)) {
 			/* Better luck next round */
 			adapter->alloc_rx_buff_failed++;
 			break;
 		}
 
-		/* Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 check_page:
 		/* allocate a new page if necessary */
@@ -437,6 +404,7 @@ static bool e1000_clean_rx_irq(struct e1
 {
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_ring *rx_ring = adapter->rx_ring;
 	struct e1000_rx_desc *rx_desc, *next_rxd;
 	struct e1000_buffer *buffer_info, *next_buffer;
@@ -482,14 +450,23 @@ static bool e1000_clean_rx_irq(struct e1
 
 		length = le16_to_cpu(rx_desc->length);
 
-		/* !EOP means multiple descriptors were used to store a single
-		 * packet, also make sure the frame isn't just CRC only */
-		if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
+		/*
+		 * !EOP means multiple descriptors were used to store a single
+		 * packet, if that's the case we need to toss it.  In fact, we
+		 * need to toss every packet with the EOP bit clear and the
+		 * next frame that _does_ have the EOP bit set, as it is by
+		 * definition only a frame fragment
+		 */
+		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+			adapter->flags2 |= FLAG2_IS_DISCARDING;
+
+		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
 			/* All receives must fit into a single buffer */
-			e_dbg("%s: Receive packet consumed multiple buffers\n",
-			      netdev->name);
+			e_dbg("Receive packet consumed multiple buffers\n");
 			/* recycle */
 			buffer_info->skb = skb;
+			if (status & E1000_RXD_STAT_EOP)
+				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
 			goto next_desc;
 		}
 
@@ -513,9 +490,8 @@ static bool e1000_clean_rx_irq(struct e1
 		 */
 		if (length < copybreak) {
 			struct sk_buff *new_skb =
-			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
+			    netdev_alloc_skb_ip_align(netdev, length);
 			if (new_skb) {
-				skb_reserve(new_skb, NET_IP_ALIGN);
 				skb_copy_to_linear_data_offset(new_skb,
 							       -NET_IP_ALIGN,
 							       (skb->data -
@@ -560,33 +536,52 @@ next_desc:
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
 static void e1000_put_txbuf(struct e1000_adapter *adapter,
 			     struct e1000_buffer *buffer_info)
 {
-	buffer_info->dma = 0;
+	if (buffer_info->dma) {
+		if (buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev, buffer_info->dma,
+				       buffer_info->length, PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev,	buffer_info->dma,
+					 buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
 	if (buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
 	buffer_info->time_stamp = 0;
 }
 
-static void e1000_print_tx_hang(struct e1000_adapter *adapter)
+static void e1000_print_hw_hang(struct work_struct *work)
 {
+	struct e1000_adapter *adapter = container_of(work,
+	                                             struct e1000_adapter,
+	                                             print_hang_task);
 	struct e1000_ring *tx_ring = adapter->tx_ring;
 	unsigned int i = tx_ring->next_to_clean;
 	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
 	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
+	struct e1000_hw *hw = &adapter->hw;
+	u16 phy_status, phy_1000t_status, phy_ext_status;
+	u16 pci_status;
 
-	/* detected Tx unit hang */
-	e_err("Detected Tx Unit Hang:\n"
+	e1e_rphy(hw, PHY_STATUS, &phy_status);
+	e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
+	e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
+
+	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
+
+	/* detected Hardware unit hang */
+	e_err("Detected Hardware Unit Hang:\n"
 	      "  TDH                  <%x>\n"
 	      "  TDT                  <%x>\n"
 	      "  next_to_use          <%x>\n"
@@ -595,7 +590,12 @@ static void e1000_print_tx_hang(struct e
 	      "  time_stamp           <%lx>\n"
 	      "  next_to_watch        <%x>\n"
 	      "  jiffies              <%lx>\n"
-	      "  next_to_watch.status <%x>\n",
+	      "  next_to_watch.status <%x>\n"
+	      "MAC Status             <%x>\n"
+	      "PHY Status             <%x>\n"
+	      "PHY 1000BASE-T Status  <%x>\n"
+	      "PHY Extended Status    <%x>\n"
+	      "PCI Status             <%x>\n",
 	      readl(adapter->hw.hw_addr + tx_ring->head),
 	      readl(adapter->hw.hw_addr + tx_ring->tail),
 	      tx_ring->next_to_use,
@@ -603,7 +603,12 @@ static void e1000_print_tx_hang(struct e
 	      tx_ring->buffer_info[eop].time_stamp,
 	      eop,
 	      jiffies,
-	      eop_desc->upper.fields.status);
+	      eop_desc->upper.fields.status,
+	      er32(STATUS),
+	      phy_status,
+	      phy_1000t_status,
+	      phy_ext_status,
+	      pci_status);
 }
 
 /**
@@ -677,21 +682,23 @@ static bool e1000_clean_tx_irq(struct e1
 	}
 
 	if (adapter->detect_tx_hung) {
-		/* Detect a transmit hang in hardware, this serializes the
-		 * check with the clearing of time_stamp and movement of i */
+		/*
+		 * Detect a transmit hang in hardware, this serializes the
+		 * check with the clearing of time_stamp and movement of i
+		 */
 		adapter->detect_tx_hung = 0;
 		if (tx_ring->buffer_info[i].time_stamp &&
 		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
-			       + (adapter->tx_timeout_factor * HZ))
-		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
-			e1000_print_tx_hang(adapter);
+			       + (adapter->tx_timeout_factor * HZ)) &&
+		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+			schedule_work(&adapter->print_hang_task);
 			netif_stop_queue(netdev);
 		}
 	}
 	adapter->total_tx_bytes += total_tx_bytes;
 	adapter->total_tx_packets += total_tx_packets;
-	adapter->net_stats.tx_bytes += total_tx_bytes;
-	adapter->net_stats.tx_packets += total_tx_packets;
+	netdev->stats.tx_bytes += total_tx_bytes;
+	netdev->stats.tx_packets += total_tx_packets;
 	return (count < tx_ring->count);
 }
 
@@ -705,6 +712,7 @@ static bool e1000_clean_tx_irq(struct e1
 static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 				  int *work_done, int work_to_do)
 {
+	struct e1000_hw *hw = &adapter->hw;
 	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
@@ -747,10 +755,16 @@ static bool e1000_clean_rx_irq_ps(struct
 				 PCI_DMA_FROMDEVICE);
 		buffer_info->dma = 0;
 
-		if (!(staterr & E1000_RXD_STAT_EOP)) {
-			e_dbg("%s: Packet Split buffers didn't pick up the "
-			      "full packet\n", netdev->name);
+		/* see !EOP comment in other rx routine */
+		if (!(staterr & E1000_RXD_STAT_EOP))
+			adapter->flags2 |= FLAG2_IS_DISCARDING;
+
+		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
+			e_dbg("Packet Split buffers didn't pick up the full "
+			      "packet\n");
 			dev_kfree_skb_irq(skb);
+			if (staterr & E1000_RXD_STAT_EOP)
+				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
 			goto next_desc;
 		}
 
@@ -762,8 +776,8 @@ static bool e1000_clean_rx_irq_ps(struct
 		length = le16_to_cpu(rx_desc->wb.middle.length0);
 
 		if (!length) {
-			e_dbg("%s: Last part of the packet spanning multiple "
-			      "descriptors\n", netdev->name);
+			e_dbg("Last part of the packet spanning multiple "
+			      "descriptors\n");
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
@@ -871,8 +885,8 @@ next_desc:
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -1051,8 +1065,8 @@ next_desc:
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -1120,6 +1134,7 @@ static void e1000_clean_rx_ring(struct e
 
 	rx_ring->next_to_clean = 0;
 	rx_ring->next_to_use = 0;
+	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
 
 	writel(0, adapter->hw.hw_addr + rx_ring->head);
 	writel(0, adapter->hw.hw_addr + rx_ring->tail);
@@ -1199,7 +1214,7 @@ static irqreturn_t e1000_intr(int irq, v
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl, icr = er32(ICR);
 
-	if (!icr)
+	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
 		return IRQ_NONE;  /* Not our interrupt */
 
 	/*
@@ -1481,7 +1496,7 @@ static int e1000_request_msix(struct e10
 	else
 		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
 	err = request_irq(adapter->msix_entries[vector].vector,
-			  &e1000_intr_msix_rx, 0, adapter->rx_ring->name,
+			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
 			  netdev);
 	if (err)
 		goto out;
@@ -1494,7 +1509,7 @@ static int e1000_request_msix(struct e10
 	else
 		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
 	err = request_irq(adapter->msix_entries[vector].vector,
-			  &e1000_intr_msix_tx, 0, adapter->tx_ring->name,
+			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
 			  netdev);
 	if (err)
 		goto out;
@@ -1503,7 +1518,7 @@ static int e1000_request_msix(struct e10
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
-			  &e1000_msix_other, 0, netdev->name, netdev);
+			  e1000_msix_other, 0, netdev->name, netdev);
 	if (err)
 		goto out;
 
@@ -1534,7 +1549,7 @@ static int e1000_request_irq(struct e100
 		e1000e_set_interrupt_capability(adapter);
 	}
 	if (adapter->flags & FLAG_MSI_ENABLED) {
-		err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0,
+		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
 				  netdev->name, netdev);
 		if (!err)
 			return err;
@@ -1544,7 +1559,7 @@ static int e1000_request_irq(struct e100
 		adapter->int_mode = E1000E_INT_MODE_LEGACY;
 	}
 
-	err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED,
+	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
 			  netdev->name, netdev);
 	if (err)
 		e_err("Unable to allocate interrupt, Error: %d\n", err);
@@ -2040,11 +2055,14 @@ static void e1000_vlan_rx_add_vid(struct
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	    (vid == adapter->mng_vlan_id))
 		return;
+
 	/* add VID to filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta |= (1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta |= (1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2069,10 +2087,12 @@ static void e1000_vlan_rx_kill_vid(struc
 	}
 
 	/* remove VID from filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta &= ~(1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta &= ~(1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
@@ -2330,18 +2350,6 @@ static void e1000_setup_rctl(struct e100
 	rctl &= ~E1000_RCTL_SZ_4096;
 	rctl |= E1000_RCTL_BSEX;
 	switch (adapter->rx_buffer_len) {
-	case 256:
-		rctl |= E1000_RCTL_SZ_256;
-		rctl &= ~E1000_RCTL_BSEX;
-		break;
-	case 512:
-		rctl |= E1000_RCTL_SZ_512;
-		rctl &= ~E1000_RCTL_BSEX;
-		break;
-	case 1024:
-		rctl |= E1000_RCTL_SZ_1024;
-		rctl &= ~E1000_RCTL_BSEX;
-		break;
 	case 2048:
 	default:
 		rctl |= E1000_RCTL_SZ_2048;
@@ -2464,8 +2472,6 @@ static void e1000_configure_rx(struct e1
 		ew32(ITR, 1000000000 / (adapter->itr * 256));
 
 	ctrl_ext = er32(CTRL_EXT);
-	/* Reset delay timers after every interrupt */
-	ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
 	/* Auto-Mask interrupts upon ICR access */
 	ctrl_ext |= E1000_CTRL_EXT_IAME;
 	ew32(IAM, 0xffffffff);
@@ -2507,21 +2513,23 @@ static void e1000_configure_rx(struct e1
 	 * packet size is equal or larger than the specified value (in 8 byte
 	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
 	 */
-	if ((adapter->flags & FLAG_HAS_ERT) &&
-	    (adapter->netdev->mtu > ETH_DATA_LEN)) {
-		u32 rxdctl = er32(RXDCTL(0));
-		ew32(RXDCTL(0), rxdctl | 0x3);
-		ew32(ERT, E1000_ERT_2048 | (1 << 13));
-		/*
-		 * With jumbo frames and early-receive enabled, excessive
-		 * C4->C2 latencies result in dropped transactions.
-		 */
-		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
-					  e1000e_driver_name, 55);
-	} else {
-		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
-					  e1000e_driver_name,
-					  PM_QOS_DEFAULT_VALUE);
+	if (adapter->flags & FLAG_HAS_ERT) {
+		if (adapter->netdev->mtu > ETH_DATA_LEN) {
+			u32 rxdctl = er32(RXDCTL(0));
+			ew32(RXDCTL(0), rxdctl | 0x3);
+			ew32(ERT, E1000_ERT_2048 | (1 << 13));
+			/*
+			 * With jumbo frames and early-receive enabled,
+			 * excessive C-state transition latencies result in
+			 * dropped transactions.
+			 */
+			pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+						  adapter->netdev->name, 55);
+		} else {
+			pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+						  adapter->netdev->name,
+						  PM_QOS_DEFAULT_VALUE);
+		}
 	}
 
 	/* Enable Receives */
@@ -2645,18 +2653,8 @@ static void e1000_configure(struct e1000
  **/
 void e1000e_power_up_phy(struct e1000_adapter *adapter)
 {
-	u16 mii_reg = 0;
-
-	/* Just clear the power down bit to wake the phy back up */
-	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
-		/*
-		 * According to the manual, the phy will retain its
-		 * settings across a power-down/up cycle
-		 */
-		e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg);
-		mii_reg &= ~MII_CR_POWER_DOWN;
-		e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg);
-	}
+	if (adapter->hw.phy.ops.power_up)
+		adapter->hw.phy.ops.power_up(&adapter->hw);
 
 	adapter->hw.mac.ops.setup_link(&adapter->hw);
 }
@@ -2664,35 +2662,17 @@ void e1000e_power_up_phy(struct e1000_ad
 /**
  * e1000_power_down_phy - Power down the PHY
  *
- * Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down is management or WoL is active
+ * Power down the PHY so no link is implied when interface is down.
+ * The PHY cannot be powered down if management or WoL is active.
  */
 static void e1000_power_down_phy(struct e1000_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
-	u16 mii_reg;
-
 	/* WoL is enabled */
 	if (adapter->wol)
 		return;
 
-	/* non-copper PHY? */
-	if (adapter->hw.phy.media_type != e1000_media_type_copper)
-		return;
-
-	/* reset is blocked because of a SoL/IDER session */
-	if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw))
-		return;
-
-	/* manageability (AMT) is enabled */
-	if (er32(MANC) & E1000_MANC_SMBUS_EN)
-		return;
-
-	/* power down the PHY */
-	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
-	mii_reg |= MII_CR_POWER_DOWN;
-	e1e_wphy(hw, PHY_CONTROL, mii_reg);
-	mdelay(1);
+	if (adapter->hw.phy.ops.power_down)
+		adapter->hw.phy.ops.power_down(&adapter->hw);
 }
 
 /**
@@ -2856,6 +2836,12 @@ int e1000e_up(struct e1000_adapter *adap
 {
 	struct e1000_hw *hw = &adapter->hw;
 
+	/* DMA latency requirement to workaround early-receive/jumbo issue */
+	if (adapter->flags & FLAG_HAS_ERT)
+		pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
+		                       adapter->netdev->name,
+				       PM_QOS_DEFAULT_VALUE);
+
 	/* hardware has been reset, we need to reload some things */
 	e1000_configure(adapter);
 
@@ -2916,6 +2902,10 @@ void e1000e_down(struct e1000_adapter *a
 	e1000_clean_tx_ring(adapter);
 	e1000_clean_rx_ring(adapter);
 
+	if (adapter->flags & FLAG_HAS_ERT)
+		pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
+		                          adapter->netdev->name);
+
 	/*
 	 * TODO: for power management, we could drop the link and
 	 * pci_disable_device here.
@@ -2973,7 +2963,7 @@ static irqreturn_t e1000_intr_msi_test(i
 	struct e1000_hw *hw = &adapter->hw;
 	u32 icr = er32(ICR);
 
-	e_dbg("%s: icr is %08X\n", netdev->name, icr);
+	e_dbg("icr is %08X\n", icr);
 	if (icr & E1000_ICR_RXSEQ) {
 		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
 		wmb();
@@ -3010,7 +3000,7 @@ static int e1000_test_msi_interrupt(stru
 	if (err)
 		goto msi_test_failed;
 
-	err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
+	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
 			  netdev->name, netdev);
 	if (err) {
 		pci_disable_msi(adapter->pdev);
@@ -3043,7 +3033,7 @@ static int e1000_test_msi_interrupt(stru
 		goto msi_test_failed;
 
 	/* okay so the test worked, restore settings */
-	e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
+	e_dbg("MSI interrupt test succeeded!\n");
 msi_test_failed:
 	e1000e_set_interrupt_capability(adapter);
 	e1000_request_irq(adapter);
@@ -3304,6 +3294,7 @@ static void e1000_update_phy_info(unsign
  **/
 void e1000e_update_stats(struct e1000_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
 	u16 phy_data;
@@ -3329,24 +3320,24 @@ void e1000e_update_stats(struct e1000_ad
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
-		adapter->stats.scc += phy_data;
+		if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
+			adapter->stats.scc += phy_data;
 
 		e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
-		e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
-		adapter->stats.ecol += phy_data;
+		if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
+			adapter->stats.ecol += phy_data;
 
 		e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
-		adapter->stats.mcc += phy_data;
+		if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
+			adapter->stats.mcc += phy_data;
 
 		e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
-		e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
-		adapter->stats.latecol += phy_data;
+		if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
+			adapter->stats.latecol += phy_data;
 
 		e1e_rphy(hw, HV_DC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_DC_LOWER, &phy_data);
-		adapter->stats.dc += phy_data;
+		if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
+			adapter->stats.dc += phy_data;
 	} else {
 		adapter->stats.scc += er32(SCC);
 		adapter->stats.ecol += er32(ECOL);
@@ -3374,8 +3365,8 @@ void e1000e_update_stats(struct e1000_ad
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
-		e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
-		hw->mac.collision_delta = phy_data;
+		if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
+			hw->mac.collision_delta = phy_data;
 	} else {
 		hw->mac.collision_delta = er32(COLC);
 	}
@@ -3386,8 +3377,8 @@ void e1000e_update_stats(struct e1000_ad
 	if ((hw->phy.type == e1000_phy_82578) ||
 	    (hw->phy.type == e1000_phy_82577)) {
 		e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
-		e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
-		adapter->stats.tncrs += phy_data;
+		if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
+			adapter->stats.tncrs += phy_data;
 	} else {
 		if ((hw->mac.type != e1000_82574) &&
 		    (hw->mac.type != e1000_82583))
@@ -3398,8 +3389,8 @@ void e1000e_update_stats(struct e1000_ad
 	adapter->stats.tsctfc += er32(TSCTFC);
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.multicast = adapter->stats.mprc;
-	adapter->net_stats.collisions = adapter->stats.colc;
+	netdev->stats.multicast = adapter->stats.mprc;
+	netdev->stats.collisions = adapter->stats.colc;
 
 	/* Rx Errors */
 
@@ -3407,22 +3398,22 @@ void e1000e_update_stats(struct e1000_ad
 	 * RLEC on some newer hardware can be incorrect so build
 	 * our own version based on RUC and ROC
 	 */
-	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+	netdev->stats.rx_errors = adapter->stats.rxerrc +
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.ruc + adapter->stats.roc +
 		adapter->stats.cexterr;
-	adapter->net_stats.rx_length_errors = adapter->stats.ruc +
+	netdev->stats.rx_length_errors = adapter->stats.ruc +
 					      adapter->stats.roc;
-	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
+	netdev->stats.rx_missed_errors = adapter->stats.mpc;
 
 	/* Tx Errors */
-	adapter->net_stats.tx_errors = adapter->stats.ecol +
+	netdev->stats.tx_errors = adapter->stats.ecol +
 				       adapter->stats.latecol;
-	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
-	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
-	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
+	netdev->stats.tx_window_errors = adapter->stats.latecol;
+	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
 
 	/* Tx Dropped needs to be maintained elsewhere */
 
@@ -3776,68 +3767,64 @@ static int e1000_tso(struct e1000_adapte
 	u8 ipcss, ipcso, tucss, tucso, hdr_len;
 	int err;
 
-	if (skb_is_gso(skb)) {
-		if (skb_header_cloned(skb)) {
-			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-			if (err)
-				return err;
-		}
+	if (!skb_is_gso(skb))
+		return 0;
 
-		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-		mss = skb_shinfo(skb)->gso_size;
-		if (skb->protocol == htons(ETH_P_IP)) {
-			struct iphdr *iph = ip_hdr(skb);
-			iph->tot_len = 0;
-			iph->check = 0;
-			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-								 iph->daddr, 0,
-								 IPPROTO_TCP,
-								 0);
-			cmd_length = E1000_TXD_CMD_IP;
-			ipcse = skb_transport_offset(skb) - 1;
-		} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
-			ipv6_hdr(skb)->payload_len = 0;
-			tcp_hdr(skb)->check =
-				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-						 &ipv6_hdr(skb)->daddr,
-						 0, IPPROTO_TCP, 0);
-			ipcse = 0;
-		}
-		ipcss = skb_network_offset(skb);
-		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
-		tucss = skb_transport_offset(skb);
-		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
-		tucse = 0;
+	if (skb_header_cloned(skb)) {
+		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+		if (err)
+			return err;
+	}
 
-		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
-			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
+	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+	mss = skb_shinfo(skb)->gso_size;
+	if (skb->protocol == htons(ETH_P_IP)) {
+		struct iphdr *iph = ip_hdr(skb);
+		iph->tot_len = 0;
+		iph->check = 0;
+		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+		                                         0, IPPROTO_TCP, 0);
+		cmd_length = E1000_TXD_CMD_IP;
+		ipcse = skb_transport_offset(skb) - 1;
+	} else if (skb_is_gso_v6(skb)) {
+		ipv6_hdr(skb)->payload_len = 0;
+		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+		                                       &ipv6_hdr(skb)->daddr,
+		                                       0, IPPROTO_TCP, 0);
+		ipcse = 0;
+	}
+	ipcss = skb_network_offset(skb);
+	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
+	tucss = skb_transport_offset(skb);
+	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
+	tucse = 0;
 
-		i = tx_ring->next_to_use;
-		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
-		buffer_info = &tx_ring->buffer_info[i];
+	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
+	               E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
 
-		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 = cpu_to_le16(tucse);
-		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);
+	i = tx_ring->next_to_use;
+	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+	buffer_info = &tx_ring->buffer_info[i];
 
-		buffer_info->time_stamp = jiffies;
-		buffer_info->next_to_watch = 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->upper_setup.tcp_fields.tucss = tucss;
+	context_desc->upper_setup.tcp_fields.tucso = tucso;
+	context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
+	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);
 
-		i++;
-		if (i == tx_ring->count)
-			i = 0;
-		tx_ring->next_to_use = i;
+	buffer_info->time_stamp = jiffies;
+	buffer_info->next_to_watch = i;
 
-		return 1;
-	}
+	i++;
+	if (i == tx_ring->count)
+		i = 0;
+	tx_ring->next_to_use = i;
 
-	return 0;
+	return 1;
 }
 
 static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
@@ -3909,23 +3896,14 @@ static int e1000_tx_map(struct e1000_ada
 			unsigned int mss)
 {
 	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_buffer *buffer_info;
 	unsigned int len = skb_headlen(skb);
-	unsigned int offset, size, count = 0, i;
+	unsigned int offset = 0, size, count = 0, i;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		adapter->tx_dma_failed++;
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-	offset = 0;
-
 	while (len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
@@ -3933,11 +3911,15 @@ static int e1000_tx_map(struct e1000_ada
 		buffer_info->length = size;
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
-		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
-		count++;
+		buffer_info->dma = pci_map_single(pdev,	skb->data + offset,
+						  size,	PCI_DMA_TODEVICE);
+		buffer_info->mapped_as_page = false;
+		if (pci_dma_mapping_error(pdev, buffer_info->dma))
+			goto dma_error;
 
 		len -= size;
 		offset += size;
+		count++;
 
 		if (len) {
 			i++;
@@ -3951,7 +3933,7 @@ static int e1000_tx_map(struct e1000_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = 0;
+		offset = frag->page_offset;
 
 		while (len) {
 			i++;
@@ -3964,7 +3946,12 @@ static int e1000_tx_map(struct e1000_ada
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
 			buffer_info->next_to_watch = i;
-			buffer_info->dma = map[f] + offset;
+			buffer_info->dma = pci_map_page(pdev, frag->page,
+							offset, size,
+							PCI_DMA_TODEVICE);
+			buffer_info->mapped_as_page = true;
+			if (pci_dma_mapping_error(pdev, buffer_info->dma))
+				goto dma_error;
 
 			len -= size;
 			offset += size;
@@ -3976,6 +3963,22 @@ static int e1000_tx_map(struct e1000_ada
 	tx_ring->buffer_info[first].next_to_watch = i;
 
 	return count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+	buffer_info->dma = 0;
+	if (count)
+		count--;
+
+	while (count--) {
+		if (i==0)
+			i += tx_ring->count;
+		i--;
+		buffer_info = &tx_ring->buffer_info[i];
+		e1000_put_txbuf(adapter, buffer_info);;
+	}
+
+	return 0;
 }
 
 static void e1000_tx_queue(struct e1000_adapter *adapter,
@@ -4048,8 +4051,8 @@ static int e1000_transfer_dhcp_info(stru
 	u16 length, offset;
 
 	if (vlan_tx_tag_present(skb)) {
-		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id)
-		    && (adapter->hw.mng_cookie.status &
+		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
+		    (adapter->hw.mng_cookie.status &
 			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
 			return 0;
 	}
@@ -4271,10 +4274,8 @@ static void e1000_reset_task(struct work
  **/
 static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-
 	/* only return the current stats */
-	return &adapter->net_stats;
+	return &netdev->stats;
 }
 
 /**
@@ -4321,13 +4322,7 @@ static int e1000_change_mtu(struct net_d
 	 * fragmented skbs
 	 */
 
-	if (max_frame <= 256)
-		adapter->rx_buffer_len = 256;
-	else if (max_frame <= 512)
-		adapter->rx_buffer_len = 512;
-	else if (max_frame <= 1024)
-		adapter->rx_buffer_len = 1024;
-	else if (max_frame <= 2048)
+	if (max_frame <= 2048)
 		adapter->rx_buffer_len = 2048;
 	else
 		adapter->rx_buffer_len = 4096;
@@ -4362,6 +4357,8 @@ static int e1000_mii_ioctl(struct net_de
 		data->phy_id = adapter->hw.phy.addr;
 		break;
 	case SIOCGMIIREG:
+		e1000_phy_read_status(adapter);
+
 		switch (data->reg_num & 0x1F) {
 		case MII_BMCR:
 			data->val_out = adapter->phy_regs.bmcr;
@@ -4469,7 +4466,7 @@ static int e1000_init_phy_wakeup(struct
 	e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
 
 	/* activate PHY wakeup */
-	retval = hw->phy.ops.acquire_phy(hw);
+	retval = hw->phy.ops.acquire(hw);
 	if (retval) {
 		e_err("Could not acquire PHY\n");
 		return retval;
@@ -4486,7 +4483,7 @@ static int e1000_init_phy_wakeup(struct
 	if (retval)
 		e_err("Could not set PHY Host Wakeup bit\n");
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 
 	return retval;
 }
@@ -4543,7 +4540,7 @@ static int __e1000_shutdown(struct pci_d
 		    e1000_media_type_internal_serdes) {
 			/* keep the laser running in D3 */
 			ctrl_ext = er32(CTRL_EXT);
-			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
 			ew32(CTRL_EXT, ctrl_ext);
 		}
 
@@ -4676,6 +4673,7 @@ static int e1000_resume(struct pci_dev *
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+	pci_save_state(pdev);
 	e1000e_disable_l1aspm(pdev);
 
 	err = pci_enable_device_mem(pdev);
@@ -4827,6 +4825,7 @@ static pci_ers_result_t e1000_io_slot_re
 	} else {
 		pci_set_master(pdev);
 		pci_restore_state(pdev);
+		pci_save_state(pdev);
 
 		pci_enable_wake(pdev, PCI_D3hot, 0);
 		pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -5160,6 +5159,7 @@ static int __devinit e1000_probe(struct
 	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
 	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
 	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
+	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
 
 	/* Initialize link parameters. User can change them with ethtool */
 	adapter->hw.mac.autoneg = 1;
@@ -5283,19 +5283,24 @@ static void __devexit e1000_remove(struc
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
+	cancel_work_sync(&adapter->reset_task);
+	cancel_work_sync(&adapter->watchdog_task);
+	cancel_work_sync(&adapter->downshift_task);
+	cancel_work_sync(&adapter->update_phy_task);
+	cancel_work_sync(&adapter->print_hang_task);
 	flush_scheduled_work();
 
+	if (!(netdev->flags & IFF_UP))
+		e1000_power_down_phy(adapter);
+
+	unregister_netdev(netdev);
+
 	/*
 	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant.
 	 */
 	e1000_release_hw_control(adapter);
 
-	unregister_netdev(netdev);
-
-	if (!e1000_check_reset_block(&adapter->hw))
-		e1000_phy_hw_reset(&adapter->hw);
-
 	e1000e_reset_interrupt_capability(adapter);
 	kfree(adapter->tx_ring);
 	kfree(adapter->rx_ring);
@@ -5361,6 +5366,7 @@ static struct pci_device_id e1000_pci_tb
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
 
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
@@ -5414,12 +5420,10 @@ static int __init e1000_init_module(void
 	int ret;
 	printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Driver - %s\n",
 	       e1000e_driver_name, e1000e_driver_version);
-	printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
+	printk(KERN_INFO "%s: Copyright (c) 1999 - 2009 Intel Corporation.\n",
 	       e1000e_driver_name);
 	ret = pci_register_driver(&e1000_driver);
-	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name,
-			       PM_QOS_DEFAULT_VALUE);
-				
+
 	return ret;
 }
 module_init(e1000_init_module);
@@ -5433,7 +5437,6 @@ module_init(e1000_init_module);
 static void __exit e1000_exit_module(void)
 {
 	pci_unregister_driver(&e1000_driver);
-	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name);
 }
 module_exit(e1000_exit_module);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/param.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/param.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/param.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/param.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e1000e/phy.c linux-libre-2.6.33-gnu1/drivers/net/e1000e/phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/e1000e/phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e1000e/phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2009 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,
@@ -44,6 +44,8 @@ static s32 e1000_access_phy_debug_regs_h
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
 	{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+		ARRAY_SIZE(e1000_m88_cable_length_table)
 
 static const u16 e1000_igp_2_cable_length_table[] =
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
@@ -130,7 +132,7 @@ s32 e1000e_get_phy_id(struct e1000_hw *h
 	u16 phy_id;
 	u16 retry_count = 0;
 
-	if (!(phy->ops.read_phy_reg))
+	if (!(phy->ops.read_reg))
 		goto out;
 
 	while (retry_count < 2) {
@@ -150,32 +152,9 @@ s32 e1000e_get_phy_id(struct e1000_hw *h
 		if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
 			goto out;
 
-		/*
-		 * If the PHY ID is still unknown, we may have an 82577i
-		 * without link.  We will try again after setting Slow
-		 * MDIC mode. No harm in trying again in this case since
-		 * the PHY ID is unknown at this point anyway
-		 */
-		ret_val = phy->ops.acquire_phy(hw);
-		if (ret_val)
-			goto out;
-		ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
-		if (ret_val)
-			goto out;
-		phy->ops.release_phy(hw);
-
 		retry_count++;
 	}
 out:
-	/* Revert to MDIO fast mode, if applicable */
-	if (retry_count) {
-		ret_val = phy->ops.acquire_phy(hw);
-		if (ret_val)
-			return ret_val;
-		ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
-		phy->ops.release_phy(hw);
-	}
-
 	return ret_val;
 }
 
@@ -211,7 +190,7 @@ s32 e1000e_read_phy_reg_mdic(struct e100
 	u32 i, mdic = 0;
 
 	if (offset > MAX_PHY_REG_ADDRESS) {
-		hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+		e_dbg("PHY Address %d is out of range\n", offset);
 		return -E1000_ERR_PARAM;
 	}
 
@@ -238,11 +217,11 @@ s32 e1000e_read_phy_reg_mdic(struct e100
 			break;
 	}
 	if (!(mdic & E1000_MDIC_READY)) {
-		hw_dbg(hw, "MDI Read did not complete\n");
+		e_dbg("MDI Read did not complete\n");
 		return -E1000_ERR_PHY;
 	}
 	if (mdic & E1000_MDIC_ERROR) {
-		hw_dbg(hw, "MDI Error\n");
+		e_dbg("MDI Error\n");
 		return -E1000_ERR_PHY;
 	}
 	*data = (u16) mdic;
@@ -264,7 +243,7 @@ s32 e1000e_write_phy_reg_mdic(struct e10
 	u32 i, mdic = 0;
 
 	if (offset > MAX_PHY_REG_ADDRESS) {
-		hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+		e_dbg("PHY Address %d is out of range\n", offset);
 		return -E1000_ERR_PARAM;
 	}
 
@@ -292,11 +271,11 @@ s32 e1000e_write_phy_reg_mdic(struct e10
 			break;
 	}
 	if (!(mdic & E1000_MDIC_READY)) {
-		hw_dbg(hw, "MDI Write did not complete\n");
+		e_dbg("MDI Write did not complete\n");
 		return -E1000_ERR_PHY;
 	}
 	if (mdic & E1000_MDIC_ERROR) {
-		hw_dbg(hw, "MDI Error\n");
+		e_dbg("MDI Error\n");
 		return -E1000_ERR_PHY;
 	}
 
@@ -317,14 +296,14 @@ s32 e1000e_read_phy_reg_m88(struct e1000
 {
 	s32 ret_val;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					   data);
 
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 
 	return ret_val;
 }
@@ -342,14 +321,14 @@ s32 e1000e_write_phy_reg_m88(struct e100
 {
 	s32 ret_val;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					    data);
 
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 
 	return ret_val;
 }
@@ -371,10 +350,10 @@ static s32 __e1000e_read_phy_reg_igp(str
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire_phy))
+		if (!(hw->phy.ops.acquire))
 			goto out;
 
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			goto out;
 	}
@@ -392,7 +371,7 @@ static s32 __e1000e_read_phy_reg_igp(str
 
 release:
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 out:
 	return ret_val;
 }
@@ -442,10 +421,10 @@ static s32 __e1000e_write_phy_reg_igp(st
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire_phy))
+		if (!(hw->phy.ops.acquire))
 			goto out;
 
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			goto out;
 	}
@@ -463,7 +442,7 @@ static s32 __e1000e_write_phy_reg_igp(st
 
 release:
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 
 out:
 	return ret_val;
@@ -515,10 +494,10 @@ static s32 __e1000_read_kmrn_reg(struct
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire_phy))
+		if (!(hw->phy.ops.acquire))
 			goto out;
 
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			goto out;
 	}
@@ -533,7 +512,7 @@ static s32 __e1000_read_kmrn_reg(struct
 	*data = (u16)kmrnctrlsta;
 
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 
 out:
 	return ret_val;
@@ -587,10 +566,10 @@ static s32 __e1000_write_kmrn_reg(struct
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire_phy))
+		if (!(hw->phy.ops.acquire))
 			goto out;
 
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			goto out;
 	}
@@ -602,7 +581,7 @@ static s32 __e1000_write_kmrn_reg(struct
 	udelay(2);
 
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 
 out:
 	return ret_val;
@@ -649,7 +628,7 @@ s32 e1000_copper_link_setup_82577(struct
 	u16 phy_data;
 
 	/* Enable CRS on TX. This must be set for half-duplex operation. */
-	ret_val = phy->ops.read_phy_reg(hw, I82577_CFG_REG, &phy_data);
+	ret_val = phy->ops.read_reg(hw, I82577_CFG_REG, &phy_data);
 	if (ret_val)
 		goto out;
 
@@ -658,7 +637,7 @@ s32 e1000_copper_link_setup_82577(struct
 	/* Enable downshift */
 	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
 
-	ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
+	ret_val = phy->ops.write_reg(hw, I82577_CFG_REG, phy_data);
 
 out:
 	return ret_val;
@@ -776,12 +755,12 @@ s32 e1000e_copper_link_setup_m88(struct
 	/* Commit the changes. */
 	ret_val = e1000e_commit_phy(hw);
 	if (ret_val) {
-		hw_dbg(hw, "Error committing the PHY changes\n");
+		e_dbg("Error committing the PHY changes\n");
 		return ret_val;
 	}
 
 	if (phy->type == e1000_phy_82578) {
-		ret_val = phy->ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+		ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
 		                            &phy_data);
 		if (ret_val)
 			return ret_val;
@@ -789,7 +768,7 @@ s32 e1000e_copper_link_setup_m88(struct
 		/* 82578 PHY - set the downshift count to 1x. */
 		phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
 		phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
-		ret_val = phy->ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+		ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
 		                             phy_data);
 		if (ret_val)
 			return ret_val;
@@ -813,7 +792,7 @@ s32 e1000e_copper_link_setup_igp(struct
 
 	ret_val = e1000_phy_hw_reset(hw);
 	if (ret_val) {
-		hw_dbg(hw, "Error resetting the PHY.\n");
+		e_dbg("Error resetting the PHY.\n");
 		return ret_val;
 	}
 
@@ -824,9 +803,9 @@ s32 e1000e_copper_link_setup_igp(struct
 	msleep(100);
 
 	/* disable lplu d0 during driver init */
-	ret_val = e1000_set_d0_lplu_state(hw, 0);
+	ret_val = e1000_set_d0_lplu_state(hw, false);
 	if (ret_val) {
-		hw_dbg(hw, "Error Disabling LPLU D0\n");
+		e_dbg("Error Disabling LPLU D0\n");
 		return ret_val;
 	}
 	/* Configure mdi-mdix settings */
@@ -962,39 +941,39 @@ static s32 e1000_phy_setup_autoneg(struc
 				 NWAY_AR_10T_HD_CAPS);
 	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
 
-	hw_dbg(hw, "autoneg_advertised %x\n", phy->autoneg_advertised);
+	e_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
 
 	/* Do we want to advertise 10 Mb Half Duplex? */
 	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
-		hw_dbg(hw, "Advertise 10mb Half duplex\n");
+		e_dbg("Advertise 10mb Half duplex\n");
 		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
 	}
 
 	/* Do we want to advertise 10 Mb Full Duplex? */
 	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
-		hw_dbg(hw, "Advertise 10mb Full duplex\n");
+		e_dbg("Advertise 10mb Full duplex\n");
 		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
 	}
 
 	/* Do we want to advertise 100 Mb Half Duplex? */
 	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
-		hw_dbg(hw, "Advertise 100mb Half duplex\n");
+		e_dbg("Advertise 100mb Half duplex\n");
 		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
 	}
 
 	/* Do we want to advertise 100 Mb Full Duplex? */
 	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
-		hw_dbg(hw, "Advertise 100mb Full duplex\n");
+		e_dbg("Advertise 100mb Full duplex\n");
 		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
 	}
 
 	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
 	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
-		hw_dbg(hw, "Advertise 1000mb Half duplex request denied!\n");
+		e_dbg("Advertise 1000mb Half duplex request denied!\n");
 
 	/* Do we want to advertise 1000 Mb Full Duplex? */
 	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
-		hw_dbg(hw, "Advertise 1000mb Full duplex\n");
+		e_dbg("Advertise 1000mb Full duplex\n");
 		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
 	}
 
@@ -1053,7 +1032,7 @@ static s32 e1000_phy_setup_autoneg(struc
 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 		break;
 	default:
-		hw_dbg(hw, "Flow control param set incorrectly\n");
+		e_dbg("Flow control param set incorrectly\n");
 		ret_val = -E1000_ERR_CONFIG;
 		return ret_val;
 	}
@@ -1062,7 +1041,7 @@ static s32 e1000_phy_setup_autoneg(struc
 	if (ret_val)
 		return ret_val;
 
-	hw_dbg(hw, "Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 
 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
 		ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
@@ -1099,13 +1078,13 @@ static s32 e1000_copper_link_autoneg(str
 	if (phy->autoneg_advertised == 0)
 		phy->autoneg_advertised = phy->autoneg_mask;
 
-	hw_dbg(hw, "Reconfiguring auto-neg advertisement params\n");
+	e_dbg("Reconfiguring auto-neg advertisement params\n");
 	ret_val = e1000_phy_setup_autoneg(hw);
 	if (ret_val) {
-		hw_dbg(hw, "Error Setting up Auto-Negotiation\n");
+		e_dbg("Error Setting up Auto-Negotiation\n");
 		return ret_val;
 	}
-	hw_dbg(hw, "Restarting Auto-Neg\n");
+	e_dbg("Restarting Auto-Neg\n");
 
 	/*
 	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
@@ -1127,7 +1106,7 @@ static s32 e1000_copper_link_autoneg(str
 	if (phy->autoneg_wait_to_complete) {
 		ret_val = e1000_wait_autoneg(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error while waiting for "
+			e_dbg("Error while waiting for "
 				 "autoneg to complete\n");
 			return ret_val;
 		}
@@ -1165,10 +1144,10 @@ s32 e1000e_setup_copper_link(struct e100
 		 * PHY will be set to 10H, 10F, 100H or 100F
 		 * depending on user settings.
 		 */
-		hw_dbg(hw, "Forcing Speed and Duplex\n");
+		e_dbg("Forcing Speed and Duplex\n");
 		ret_val = e1000_phy_force_speed_duplex(hw);
 		if (ret_val) {
-			hw_dbg(hw, "Error Forcing Speed and Duplex\n");
+			e_dbg("Error Forcing Speed and Duplex\n");
 			return ret_val;
 		}
 	}
@@ -1185,11 +1164,11 @@ s32 e1000e_setup_copper_link(struct e100
 		return ret_val;
 
 	if (link) {
-		hw_dbg(hw, "Valid link established!!!\n");
+		e_dbg("Valid link established!!!\n");
 		e1000e_config_collision_dist(hw);
 		ret_val = e1000e_config_fc_after_link_up(hw);
 	} else {
-		hw_dbg(hw, "Unable to establish link!!!\n");
+		e_dbg("Unable to establish link!!!\n");
 	}
 
 	return ret_val;
@@ -1235,12 +1214,12 @@ s32 e1000e_phy_force_speed_duplex_igp(st
 	if (ret_val)
 		return ret_val;
 
-	hw_dbg(hw, "IGP PSCR: %X\n", phy_data);
+	e_dbg("IGP PSCR: %X\n", phy_data);
 
 	udelay(1);
 
 	if (phy->autoneg_wait_to_complete) {
-		hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n");
+		e_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw,
 						     PHY_FORCE_LIMIT,
@@ -1250,7 +1229,7 @@ s32 e1000e_phy_force_speed_duplex_igp(st
 			return ret_val;
 
 		if (!link)
-			hw_dbg(hw, "Link taking longer than expected.\n");
+			e_dbg("Link taking longer than expected.\n");
 
 		/* Try once more */
 		ret_val = e1000e_phy_has_link_generic(hw,
@@ -1294,7 +1273,7 @@ s32 e1000e_phy_force_speed_duplex_m88(st
 	if (ret_val)
 		return ret_val;
 
-	hw_dbg(hw, "M88E1000 PSCR: %X\n", phy_data);
+	e_dbg("M88E1000 PSCR: %X\n", phy_data);
 
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
 	if (ret_val)
@@ -1312,7 +1291,7 @@ s32 e1000e_phy_force_speed_duplex_m88(st
 		return ret_val;
 
 	if (phy->autoneg_wait_to_complete) {
-		hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
+		e_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
 						     100000, &link);
@@ -1320,17 +1299,22 @@ s32 e1000e_phy_force_speed_duplex_m88(st
 			return ret_val;
 
 		if (!link) {
-			/*
-			 * We didn't get link.
-			 * Reset the DSP and cross our fingers.
-			 */
-			ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT,
-					   0x001d);
-			if (ret_val)
-				return ret_val;
-			ret_val = e1000e_phy_reset_dsp(hw);
-			if (ret_val)
-				return ret_val;
+			if (hw->phy.type != e1000_phy_m88) {
+				e_dbg("Link taking longer than expected.\n");
+			} else {
+				/*
+				 * We didn't get link.
+				 * Reset the DSP and cross our fingers.
+				 */
+				ret_val = e1e_wphy(hw,
+						M88E1000_PHY_PAGE_SELECT,
+						0x001d);
+				if (ret_val)
+					return ret_val;
+				ret_val = e1000e_phy_reset_dsp(hw);
+				if (ret_val)
+					return ret_val;
+			}
 		}
 
 		/* Try once more */
@@ -1340,6 +1324,9 @@ s32 e1000e_phy_force_speed_duplex_m88(st
 			return ret_val;
 	}
 
+	if (hw->phy.type != e1000_phy_m88)
+		return 0;
+
 	ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		return ret_val;
@@ -1369,6 +1356,73 @@ s32 e1000e_phy_force_speed_duplex_m88(st
 }
 
 /**
+ *  e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
+ *  @hw: pointer to the HW structure
+ *
+ *  Forces the speed and duplex settings of the PHY.
+ *  This is a function pointer entry point only called by
+ *  PHY setup routines.
+ **/
+s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+	bool link;
+
+	ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
+	if (ret_val)
+		goto out;
+
+	e1000e_phy_force_speed_duplex_setup(hw, &data);
+
+	ret_val = e1e_wphy(hw, PHY_CONTROL, data);
+	if (ret_val)
+		goto out;
+
+	/* Disable MDI-X support for 10/100 */
+	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
+	if (ret_val)
+		goto out;
+
+	data &= ~IFE_PMC_AUTO_MDIX;
+	data &= ~IFE_PMC_FORCE_MDIX;
+
+	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
+	if (ret_val)
+		goto out;
+
+	e_dbg("IFE PMC: %X\n", data);
+
+	udelay(1);
+
+	if (phy->autoneg_wait_to_complete) {
+		e_dbg("Waiting for forced speed/duplex link on IFE phy.\n");
+
+		ret_val = e1000e_phy_has_link_generic(hw,
+		                                     PHY_FORCE_LIMIT,
+		                                     100000,
+		                                     &link);
+		if (ret_val)
+			goto out;
+
+		if (!link)
+			e_dbg("Link taking longer than expected.\n");
+
+		/* Try once more */
+		ret_val = e1000e_phy_has_link_generic(hw,
+		                                     PHY_FORCE_LIMIT,
+		                                     100000,
+		                                     &link);
+		if (ret_val)
+			goto out;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
  *  @hw: pointer to the HW structure
  *  @phy_ctrl: pointer to current value of PHY_CONTROL
@@ -1403,11 +1457,11 @@ void e1000e_phy_force_speed_duplex_setup
 	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
 		ctrl &= ~E1000_CTRL_FD;
 		*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
-		hw_dbg(hw, "Half Duplex\n");
+		e_dbg("Half Duplex\n");
 	} else {
 		ctrl |= E1000_CTRL_FD;
 		*phy_ctrl |= MII_CR_FULL_DUPLEX;
-		hw_dbg(hw, "Full Duplex\n");
+		e_dbg("Full Duplex\n");
 	}
 
 	/* Forcing 10mb or 100mb? */
@@ -1415,12 +1469,12 @@ void e1000e_phy_force_speed_duplex_setup
 		ctrl |= E1000_CTRL_SPD_100;
 		*phy_ctrl |= MII_CR_SPEED_100;
 		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
-		hw_dbg(hw, "Forcing 100mb\n");
+		e_dbg("Forcing 100mb\n");
 	} else {
 		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
 		*phy_ctrl |= MII_CR_SPEED_10;
 		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
-		hw_dbg(hw, "Forcing 10mb\n");
+		e_dbg("Forcing 10mb\n");
 	}
 
 	e1000e_config_collision_dist(hw);
@@ -1523,8 +1577,8 @@ s32 e1000e_check_downshift(struct e1000_
 	switch (phy->type) {
 	case e1000_phy_m88:
 	case e1000_phy_gg82563:
+	case e1000_phy_bm:
 	case e1000_phy_82578:
-	case e1000_phy_82577:
 		offset	= M88E1000_PHY_SPEC_STATUS;
 		mask	= M88E1000_PSSR_DOWNSHIFT;
 		break;
@@ -1535,7 +1589,7 @@ s32 e1000e_check_downshift(struct e1000_
 		break;
 	default:
 		/* speed downshift not supported */
-		phy->speed_downgraded = 0;
+		phy->speed_downgraded = false;
 		return 0;
 	}
 
@@ -1555,7 +1609,7 @@ s32 e1000e_check_downshift(struct e1000_
  *
  *  Polarity is determined based on the PHY specific status register.
  **/
-static s32 e1000_check_polarity_m88(struct e1000_hw *hw)
+s32 e1000_check_polarity_m88(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1580,7 +1634,7 @@ static s32 e1000_check_polarity_m88(stru
  *  Polarity is determined based on the PHY port status register, and the
  *  current speed (since there is no polarity at 100Mbps).
  **/
-static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
+s32 e1000_check_polarity_igp(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1618,6 +1672,39 @@ static s32 e1000_check_polarity_igp(stru
 }
 
 /**
+ *  e1000_check_polarity_ife - Check cable polarity for IFE PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Polarity is determined on the polarity reversal feature being enabled.
+ **/
+s32 e1000_check_polarity_ife(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data, offset, mask;
+
+	/*
+	 * Polarity is determined based on the reversal feature being enabled.
+	 */
+	if (phy->polarity_correction) {
+		offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
+		mask = IFE_PESC_POLARITY_REVERSED;
+	} else {
+		offset = IFE_PHY_SPECIAL_CONTROL;
+		mask = IFE_PSC_FORCE_POLARITY;
+	}
+
+	ret_val = e1e_rphy(hw, offset, &phy_data);
+
+	if (!ret_val)
+		phy->cable_polarity = (phy_data & mask)
+		                       ? e1000_rev_polarity_reversed
+		                       : e1000_rev_polarity_normal;
+
+	return ret_val;
+}
+
+/**
  *  e1000_wait_autoneg - Wait for auto-neg completion
  *  @hw: pointer to the HW structure
  *
@@ -1717,15 +1804,21 @@ s32 e1000e_get_cable_length_m88(struct e
 
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
-		return ret_val;
+		goto out;
 
 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-		M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	        M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
 	phy->min_cable_length = e1000_m88_cable_length_table[index];
-	phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
+out:
 	return ret_val;
 }
 
@@ -1736,7 +1829,7 @@ s32 e1000e_get_cable_length_m88(struct e
  *  The automatic gain control (agc) normalizes the amplitude of the
  *  received signal, adjusting for the attenuation produced by the
  *  cable.  By reading the AGC registers, which represent the
- *  combination of course and fine gain value, the value can be put
+ *  combination of coarse and fine gain value, the value can be put
  *  into a lookup table to obtain the approximate cable length
  *  for each channel.
  **/
@@ -1761,7 +1854,7 @@ s32 e1000e_get_cable_length_igp_2(struct
 
 		/*
 		 * Getting bits 15:9, which represent the combination of
-		 * course and fine gain values.  The result is a number
+		 * coarse and fine gain values.  The result is a number
 		 * that can be put into the lookup table to obtain the
 		 * approximate cable length.
 		 */
@@ -1815,8 +1908,8 @@ s32 e1000e_get_phy_info_m88(struct e1000
 	u16 phy_data;
 	bool link;
 
-	if (hw->phy.media_type != e1000_media_type_copper) {
-		hw_dbg(hw, "Phy info is only valid for copper media\n");
+	if (phy->media_type != e1000_media_type_copper) {
+		e_dbg("Phy info is only valid for copper media\n");
 		return -E1000_ERR_CONFIG;
 	}
 
@@ -1825,7 +1918,7 @@ s32 e1000e_get_phy_info_m88(struct e1000
 		return ret_val;
 
 	if (!link) {
-		hw_dbg(hw, "Phy info is only valid if link is up\n");
+		e_dbg("Phy info is only valid if link is up\n");
 		return -E1000_ERR_CONFIG;
 	}
 
@@ -1893,11 +1986,11 @@ s32 e1000e_get_phy_info_igp(struct e1000
 		return ret_val;
 
 	if (!link) {
-		hw_dbg(hw, "Phy info is only valid if link is up\n");
+		e_dbg("Phy info is only valid if link is up\n");
 		return -E1000_ERR_CONFIG;
 	}
 
-	phy->polarity_correction = 1;
+	phy->polarity_correction = true;
 
 	ret_val = e1000_check_polarity_igp(hw);
 	if (ret_val)
@@ -1936,6 +2029,61 @@ s32 e1000e_get_phy_info_igp(struct e1000
 }
 
 /**
+ *  e1000_get_phy_info_ife - Retrieves various IFE PHY states
+ *  @hw: pointer to the HW structure
+ *
+ *  Populates "phy" structure with various feature states.
+ **/
+s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+	bool link;
+
+	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+	if (ret_val)
+		goto out;
+
+	if (!link) {
+		e_dbg("Phy info is only valid if link is up\n");
+		ret_val = -E1000_ERR_CONFIG;
+		goto out;
+	}
+
+	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
+	if (ret_val)
+		goto out;
+	phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE)
+	                           ? false : true;
+
+	if (phy->polarity_correction) {
+		ret_val = e1000_check_polarity_ife(hw);
+		if (ret_val)
+			goto out;
+	} else {
+		/* Polarity is forced */
+		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
+		                      ? e1000_rev_polarity_reversed
+		                      : e1000_rev_polarity_normal;
+	}
+
+	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
+	if (ret_val)
+		goto out;
+
+	phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? true : false;
+
+	/* The following parameters are undefined for 10/100 operation. */
+	phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+	phy->local_rx = e1000_1000t_rx_status_undefined;
+	phy->remote_rx = e1000_1000t_rx_status_undefined;
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000e_phy_sw_reset - PHY software reset
  *  @hw: pointer to the HW structure
  *
@@ -1980,7 +2128,7 @@ s32 e1000e_phy_hw_reset_generic(struct e
 	if (ret_val)
 		return 0;
 
-	ret_val = phy->ops.acquire_phy(hw);
+	ret_val = phy->ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -1995,7 +2143,7 @@ s32 e1000e_phy_hw_reset_generic(struct e
 
 	udelay(150);
 
-	phy->ops.release_phy(hw);
+	phy->ops.release(hw);
 
 	return e1000_get_phy_cfg_done(hw);
 }
@@ -2021,7 +2169,7 @@ s32 e1000e_get_cfg_done(struct e1000_hw
  **/
 s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw)
 {
-	hw_dbg(hw, "Running IGP 3 PHY init script\n");
+	e_dbg("Running IGP 3 PHY init script\n");
 
 	/* PHY init IGP 3 */
 	/* Enable rise/fall, 10-mode work in class-A */
@@ -2189,28 +2337,34 @@ enum e1000_phy_type e1000e_get_phy_type_
 s32 e1000e_determine_phy_address(struct e1000_hw *hw)
 {
 	s32 ret_val = -E1000_ERR_PHY_TYPE;
-	u32 phy_addr= 0;
-	u32 i = 0;
+	u32 phy_addr = 0;
+	u32 i;
 	enum e1000_phy_type phy_type = e1000_phy_unknown;
 
-	do {
-		for (phy_addr = 0; phy_addr < 4; phy_addr++) {
-			hw->phy.addr = phy_addr;
+	hw->phy.id = phy_type;
+
+	for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
+		hw->phy.addr = phy_addr;
+		i = 0;
+
+		do {
 			e1000e_get_phy_id(hw);
 			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
 
-			/* 
+			/*
 			 * If phy_type is valid, break - we found our
 			 * PHY address
 			 */
 			if (phy_type  != e1000_phy_unknown) {
 				ret_val = 0;
-				break;
+				goto out;
 			}
-		}
-		i++;
-	} while ((ret_val != 0) && (i < 100));
+			msleep(1);
+			i++;
+		} while (i < 10);
+	}
 
+out:
 	return ret_val;
 }
 
@@ -2246,7 +2400,7 @@ s32 e1000e_write_phy_reg_bm(struct e1000
 	u32 page = offset >> IGP_PAGE_SHIFT;
 	u32 page_shift = 0;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -2284,7 +2438,7 @@ s32 e1000e_write_phy_reg_bm(struct e1000
 	                                    data);
 
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 	return ret_val;
 }
 
@@ -2305,7 +2459,7 @@ s32 e1000e_read_phy_reg_bm(struct e1000_
 	u32 page = offset >> IGP_PAGE_SHIFT;
 	u32 page_shift = 0;
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -2342,7 +2496,7 @@ s32 e1000e_read_phy_reg_bm(struct e1000_
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 	                                   data);
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 	return ret_val;
 }
 
@@ -2361,7 +2515,7 @@ s32 e1000e_read_phy_reg_bm2(struct e1000
 	s32 ret_val;
 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -2387,7 +2541,7 @@ s32 e1000e_read_phy_reg_bm2(struct e1000
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					   data);
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 	return ret_val;
 }
 
@@ -2405,7 +2559,7 @@ s32 e1000e_write_phy_reg_bm2(struct e100
 	s32 ret_val;
 	u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
 
-	ret_val = hw->phy.ops.acquire_phy(hw);
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -2431,7 +2585,7 @@ s32 e1000e_write_phy_reg_bm2(struct e100
 					    data);
 
 out:
-	hw->phy.ops.release_phy(hw);
+	hw->phy.ops.release(hw);
 	return ret_val;
 }
 
@@ -2464,7 +2618,7 @@ static s32 e1000_access_phy_wakeup_reg_b
 	/* Gig must be disabled for MDIO accesses to page 800 */
 	if ((hw->mac.type == e1000_pchlan) &&
 	   (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
-		hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
+		e_dbg("Attempting to access page 800 while gig enabled.\n");
 
 	/* All operations in this function are phy address 1 */
 	hw->phy.addr = 1;
@@ -2474,20 +2628,26 @@ static s32 e1000_access_phy_wakeup_reg_b
 	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not read PHY page 769\n");
 		goto out;
+	}
 
 	/* First clear bit 4 to avoid a power state change */
 	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not clear PHY page 769 bit 4\n");
 		goto out;
+	}
 
 	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
 	                                    phy_reg | BM_WUC_ENABLE_BIT);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not write PHY page 769 bit 2\n");
 		goto out;
+	}
 
 	/* Select page 800 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
@@ -2495,21 +2655,25 @@ static s32 e1000_access_phy_wakeup_reg_b
 
 	/* Write the page 800 offset value using opcode 0x11 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not write address opcode to page 800\n");
 		goto out;
+	}
 
 	if (read) {
 	        /* Read the page 800 value using opcode 0x12 */
 		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
 		                                   data);
 	} else {
-	        /* Read the page 800 value using opcode 0x12 */
+	        /* Write the page 800 value using opcode 0x12 */
 		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
 						    *data);
 	}
 
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not access data value from page 800\n");
 		goto out;
+	}
 
 	/*
 	 * Restore 769_17.2 to its original value
@@ -2520,12 +2684,53 @@ static s32 e1000_access_phy_wakeup_reg_b
 
 	/* Clear 769_17.2 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+	if (ret_val) {
+		e_dbg("Could not clear PHY page 769 bit 2\n");
+		goto out;
+	}
 
 out:
 	return ret_val;
 }
 
 /**
+ * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, restore the link to previous
+ * settings.
+ **/
+void e1000_power_up_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
+	mii_reg &= ~MII_CR_POWER_DOWN;
+	e1e_wphy(hw, PHY_CONTROL, mii_reg);
+}
+
+/**
+ * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, restore the link to previous
+ * settings.
+ **/
+void e1000_power_down_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
+	mii_reg |= MII_CR_POWER_DOWN;
+	e1e_wphy(hw, PHY_CONTROL, mii_reg);
+	msleep(1);
+}
+
+/**
  *  e1000e_commit_phy - Soft PHY reset
  *  @hw: pointer to the HW structure
  *
@@ -2534,8 +2739,8 @@ out:
  **/
 s32 e1000e_commit_phy(struct e1000_hw *hw)
 {
-	if (hw->phy.ops.commit_phy)
-		return hw->phy.ops.commit_phy(hw);
+	if (hw->phy.ops.commit)
+		return hw->phy.ops.commit(hw);
 
 	return 0;
 }
@@ -2563,38 +2768,6 @@ static s32 e1000_set_d0_lplu_state(struc
 }
 
 /**
- *  e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
- *  @hw:   pointer to the HW structure
- *  @slow: true for slow mode, false for normal mode
- *
- *  Assumes semaphore already acquired.
- **/
-s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
-{
-	s32 ret_val = 0;
-	u16 data = 0;
-
-	/* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
-	hw->phy.addr = 1;
-	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
-				         (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
-	if (ret_val)
-		goto out;
-
-	ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
-	                                   (0x2180 | (slow << 10)));
-	if (ret_val)
-		goto out;
-
-	/* dummy read when reverting to fast mode - throw away result */
-	if (!slow)
-		ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
-
-out:
-	return ret_val;
-}
-
-/**
  *  __e1000_read_phy_reg_hv -  Read HV PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
@@ -2611,24 +2784,13 @@ static s32 __e1000_read_phy_reg_hv(struc
 	s32 ret_val;
 	u16 page = BM_PHY_REG_PAGE(offset);
 	u16 reg = BM_PHY_REG_NUM(offset);
-	bool in_slow_mode = false;
 
 	if (!locked) {
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			return ret_val;
 	}
 
-	/* Workaround failure in MDIO access while cable is disconnected */
-	if ((hw->phy.type == e1000_phy_82577) &&
-	    !(er32(STATUS) & E1000_STATUS_LU)) {
-		ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
-		if (ret_val)
-			goto out;
-
-		in_slow_mode = true;
-	}
-
 	/* Page 800 works differently than the rest so it has its own func */
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
@@ -2665,12 +2827,8 @@ static s32 __e1000_read_phy_reg_hv(struc
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
 	                                  data);
 out:
-	/* Revert to MDIO fast mode, if applicable */
-	if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-		ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
-
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 
 	return ret_val;
 }
@@ -2720,24 +2878,13 @@ static s32 __e1000_write_phy_reg_hv(stru
 	s32 ret_val;
 	u16 page = BM_PHY_REG_PAGE(offset);
 	u16 reg = BM_PHY_REG_NUM(offset);
-	bool in_slow_mode = false;
 
 	if (!locked) {
-		ret_val = hw->phy.ops.acquire_phy(hw);
+		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
 			return ret_val;
 	}
 
-	/* Workaround failure in MDIO access while cable is disconnected */
-	if ((hw->phy.type == e1000_phy_82577) &&
-	    !(er32(STATUS) & E1000_STATUS_LU)) {
-		ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
-		if (ret_val)
-			goto out;
-
-		in_slow_mode = true;
-	}
-
 	/* Page 800 works differently than the rest so it has its own func */
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
@@ -2791,12 +2938,8 @@ static s32 __e1000_write_phy_reg_hv(stru
 	                                  data);
 
 out:
-	/* Revert to MDIO fast mode, if applicable */
-	if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-		ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
-
 	if (!locked)
-		hw->phy.ops.release_phy(hw);
+		hw->phy.ops.release(hw);
 
 	return ret_val;
 }
@@ -2872,7 +3015,7 @@ static s32 e1000_access_phy_debug_regs_h
 	/* masking with 0x3F to remove the page from offset */
 	ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
 	if (ret_val) {
-		hw_dbg(hw, "Could not write PHY the HV address register\n");
+		e_dbg("Could not write PHY the HV address register\n");
 		goto out;
 	}
 
@@ -2883,7 +3026,7 @@ static s32 e1000_access_phy_debug_regs_h
 		ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
 
 	if (ret_val) {
-		hw_dbg(hw, "Could not read data value from HV data register\n");
+		e_dbg("Could not read data value from HV data register\n");
 		goto out;
 	}
 
@@ -2911,12 +3054,12 @@ s32 e1000_link_stall_workaround_hv(struc
 		goto out;
 
 	/* Do not apply workaround if in PHY loopback bit 14 set */
-	hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &data);
+	hw->phy.ops.read_reg(hw, PHY_CONTROL, &data);
 	if (data & PHY_CONTROL_LB)
 		goto out;
 
 	/* check if link is up and at 1Gbps */
-	ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data);
+	ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data);
 	if (ret_val)
 		goto out;
 
@@ -2932,13 +3075,13 @@ s32 e1000_link_stall_workaround_hv(struc
 	mdelay(200);
 
 	/* flush the packets in the fifo buffer */
-	ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+	ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
 	                                HV_MUX_DATA_CTRL_GEN_TO_MAC |
 	                                HV_MUX_DATA_CTRL_FORCE_SPEED);
 	if (ret_val)
 		goto out;
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+	ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
 	                                HV_MUX_DATA_CTRL_GEN_TO_MAC);
 
 out:
@@ -2959,7 +3102,7 @@ s32 e1000_check_polarity_82577(struct e1
 	s32 ret_val;
 	u16 data;
 
-	ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+	ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
 
 	if (!ret_val)
 		phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
@@ -2984,13 +3127,13 @@ s32 e1000_phy_force_speed_duplex_82577(s
 	u16 phy_data;
 	bool link;
 
-	ret_val = phy->ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
 	if (ret_val)
 		goto out;
 
 	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
 
-	ret_val = phy->ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
 	if (ret_val)
 		goto out;
 
@@ -2998,23 +3141,23 @@ s32 e1000_phy_force_speed_duplex_82577(s
 	 * Clear Auto-Crossover to force MDI manually.  82577 requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
-	ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_CTRL_2, &phy_data);
+	ret_val = phy->ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
 	phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
 
-	ret_val = phy->ops.write_phy_reg(hw, I82577_PHY_CTRL_2, phy_data);
+	ret_val = phy->ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
 	if (ret_val)
 		goto out;
 
-	hw_dbg(hw, "I82577_PHY_CTRL_2: %X\n", phy_data);
+	e_dbg("I82577_PHY_CTRL_2: %X\n", phy_data);
 
 	udelay(1);
 
 	if (phy->autoneg_wait_to_complete) {
-		hw_dbg(hw, "Waiting for forced speed/duplex link on 82577 phy\n");
+		e_dbg("Waiting for forced speed/duplex link on 82577 phy\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw,
 		                                     PHY_FORCE_LIMIT,
@@ -3024,7 +3167,7 @@ s32 e1000_phy_force_speed_duplex_82577(s
 			goto out;
 
 		if (!link)
-			hw_dbg(hw, "Link taking longer than expected.\n");
+			e_dbg("Link taking longer than expected.\n");
 
 		/* Try once more */
 		ret_val = e1000e_phy_has_link_generic(hw,
@@ -3060,7 +3203,7 @@ s32 e1000_get_phy_info_82577(struct e100
 		goto out;
 
 	if (!link) {
-		hw_dbg(hw, "Phy info is only valid if link is up\n");
+		e_dbg("Phy info is only valid if link is up\n");
 		ret_val = -E1000_ERR_CONFIG;
 		goto out;
 	}
@@ -3071,7 +3214,7 @@ s32 e1000_get_phy_info_82577(struct e100
 	if (ret_val)
 		goto out;
 
-	ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+	ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
 	if (ret_val)
 		goto out;
 
@@ -3083,7 +3226,7 @@ s32 e1000_get_phy_info_82577(struct e100
 		if (ret_val)
 			goto out;
 
-		ret_val = phy->ops.read_phy_reg(hw, PHY_1000T_STATUS, &data);
+		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
 		if (ret_val)
 			goto out;
 
@@ -3117,7 +3260,7 @@ s32 e1000_get_cable_length_82577(struct
 	s32 ret_val;
 	u16 phy_data, length;
 
-	ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
+	ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
 	if (ret_val)
 		goto out;
 
@@ -3125,7 +3268,7 @@ s32 e1000_get_cable_length_82577(struct
 	         I82577_DSTATUS_CABLE_LENGTH_SHIFT;
 
 	if (length == E1000_CABLE_LENGTH_UNDEFINED)
-		ret_val = E1000_ERR_PHY;
+		ret_val = -E1000_ERR_PHY;
 
 	phy->cable_length = length;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e100.c linux-libre-2.6.33-gnu1/drivers/net/e100.c
--- linux-libre-2.6.32-gnu1/drivers/net/e100.c	2013-05-03 14:00:53.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/e100.c	2013-05-03 12:08:10.000000000 -0400
@@ -622,6 +622,7 @@ struct nic {
 	u16 eeprom_wc;
 	__le16 eeprom[256];
 	spinlock_t mdio_lock;
+	const struct firmware *fw;
 };
 
 static inline void e100_write_flush(struct nic *nic)
@@ -1223,9 +1224,9 @@ static void e100_configure(struct nic *n
 static const struct firmware *e100_reject_firmware(struct nic *nic)
 {
 	const char *fw_name;
-	const struct firmware *fw;
+	const struct firmware *fw = nic->fw;
 	u8 timer, bundle, min_size;
-	int err;
+	int err = 0;
 
 	/* do not load u-code for ICH devices */
 	if (nic->flags & ich)
@@ -1241,13 +1242,21 @@ static const struct firmware *e100_rejec
 	else /* No ucode on other devices */
 		return NULL;
 
-	err = reject_firmware(&fw, fw_name, &nic->pdev->dev);
+	/* If the firmware has not previously been loaded, request a pointer
+	 * to it. If it was previously loaded, we are reinitializing the
+	 * adapter, possibly in a resume from hibernate, in which case
+	 * reject_firmware() cannot be used.
+	 */
+	if (!fw)
+		err = reject_firmware(&fw, fw_name, &nic->pdev->dev);
+
 	if (err) {
 		DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
 			fw_name, err);
 		DPRINTK(PROBE,ERR, "Proceeding without firmware\n");
 		return NULL;
 	}
+
 	/* Firmware should be precisely UCODE_SIZE (words) plus three bytes
 	   indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
 	if (fw->size != UCODE_SIZE * 4 + 3) {
@@ -1270,7 +1279,10 @@ static const struct firmware *e100_rejec
 		release_firmware(fw);
 		return ERR_PTR(-EINVAL);
 	}
-	/* OK, firmware is validated and ready to use... */
+
+	/* OK, firmware is validated and ready to use. Save a pointer
+	 * to it in the nic */
+	nic->fw = fw;
 	return fw;
 }
 
@@ -1816,6 +1828,7 @@ static int e100_alloc_cbs(struct nic *ni
 				  &nic->cbs_dma_addr);
 	if (!nic->cbs)
 		return -ENOMEM;
+	memset(nic->cbs, 0, count * sizeof(struct cb));
 
 	for (cb = nic->cbs, i = 0; i < count; cb++, i++) {
 		cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;
@@ -1824,7 +1837,6 @@ static int e100_alloc_cbs(struct nic *ni
 		cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb);
 		cb->link = cpu_to_le32(nic->cbs_dma_addr +
 			((i+1) % count) * sizeof(struct cb));
-		cb->skb = NULL;
 	}
 
 	nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
@@ -1851,11 +1863,10 @@ static inline void e100_start_receiver(s
 #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
 static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
 {
-	if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN)))
+	if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN)))
 		return -ENOMEM;
 
-	/* Align, init, and map the RFD. */
-	skb_reserve(rx->skb, NET_IP_ALIGN);
+	/* Init, and map the RFD. */
 	skb_copy_to_linear_data(rx->skb, &nic->blank_rfd, sizeof(struct rfd));
 	rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
 		RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/e2100.c linux-libre-2.6.33-gnu1/drivers/net/e2100.c
--- linux-libre-2.6.32-gnu1/drivers/net/e2100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/e2100.c	2010-02-24 13:52:17.000000000 -0500
@@ -186,9 +186,9 @@ static int __init e21_probe1(struct net_
 		return -EBUSY;
 
 	/* First check the station address for the Ctron prefix. */
-	if (inb(ioaddr + E21_SAPROM + 0) != 0x00
-		|| inb(ioaddr + E21_SAPROM + 1) != 0x00
-		|| inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
+	if (inb(ioaddr + E21_SAPROM + 0) != 0x00 ||
+	    inb(ioaddr + E21_SAPROM + 1) != 0x00 ||
+	    inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
 		retval = -ENODEV;
 		goto out;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/eepro.c linux-libre-2.6.33-gnu1/drivers/net/eepro.c
--- linux-libre-2.6.32-gnu1/drivers/net/eepro.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/eepro.c	2010-02-24 13:52:17.000000000 -0500
@@ -990,7 +990,7 @@ static int eepro_open(struct net_device
 		return -EAGAIN;
 	}
 
-	if (request_irq(dev->irq , &eepro_interrupt, 0, dev->name, dev)) {
+	if (request_irq(dev->irq , eepro_interrupt, 0, dev->name, dev)) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/eexpress.c linux-libre-2.6.33-gnu1/drivers/net/eexpress.c
--- linux-libre-2.6.32-gnu1/drivers/net/eexpress.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/eexpress.c	2010-02-24 13:52:17.000000000 -0500
@@ -457,7 +457,7 @@ static int eexp_open(struct net_device *
 	if (!dev->irq || !irqrmap[dev->irq])
 		return -ENXIO;
 
-	ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev);
+	ret = request_irq(dev->irq, eexp_irq, 0, dev->name, dev);
 	if (ret)
 		return ret;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,7 +118,7 @@ doit:
 	ret = ehea_set_portspeed(port, sp);
 
 	if (!ret)
-		ehea_info("%s: Port speed succesfully set: %dMbps "
+		ehea_info("%s: Port speed successfully set: %dMbps "
 			  "%s Duplex",
 			  port->netdev->name, port->port_speed,
 			  port->full_duplex == 1 ? "Full" : "Half");
@@ -134,7 +134,7 @@ static int ehea_nway_reset(struct net_de
 	ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG);
 
 	if (!ret)
-		ehea_info("%s: Port speed succesfully set: %dMbps "
+		ehea_info("%s: Port speed successfully set: %dMbps "
 			  "%s Duplex",
 			  port->netdev->name, port->port_speed,
 			  port->full_duplex == 1 ? "Full" : "Half");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_hcall.h linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_hcall.h
--- linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_hcall.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_hcall.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- *  linux/drivers/net/ehea/ehea_hcall.h
- *
- *  eHEA ethernet device driver for IBM eServer System p
- *
- *  (C) Copyright IBM Corp. 2006
- *
- *  Authors:
- *       Christoph Raisch <raisch@de.ibm.com>
- *       Jan-Bernd Themann <themann@de.ibm.com>
- *       Thomas Klein <tklein@de.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, 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.
- */
-
-#ifndef __EHEA_HCALL_H__
-#define __EHEA_HCALL_H__
-
-/**
- * This file contains HCALL defines that are to be included in the appropriate
- * kernel files later
- */
-
-#define H_ALLOC_HEA_RESOURCE   0x278
-#define H_MODIFY_HEA_QP        0x250
-#define H_QUERY_HEA_QP         0x254
-#define H_QUERY_HEA            0x258
-#define H_QUERY_HEA_PORT       0x25C
-#define H_MODIFY_HEA_PORT      0x260
-#define H_REG_BCMC             0x264
-#define H_DEREG_BCMC           0x268
-#define H_REGISTER_HEA_RPAGES  0x26C
-#define H_DISABLE_AND_GET_HEA  0x270
-#define H_GET_HEA_INFO         0x274
-#define H_ADD_CONN             0x284
-#define H_DEL_CONN             0x288
-
-#endif	/* __EHEA_HCALL_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_main.c linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,8 +189,8 @@ static void ehea_update_firmware_handles
 		for (k = 0; k < EHEA_MAX_PORTS; k++) {
 			struct ehea_port *port = adapter->port[k];
 
-			if (!port || (port->state != EHEA_PORT_UP)
-				|| (num_ports == 0))
+			if (!port || (port->state != EHEA_PORT_UP) ||
+			    (num_ports == 0))
 				continue;
 
 			for (l = 0;
@@ -447,7 +447,9 @@ static int ehea_refill_rq_def(struct ehe
 	max_index_mask = q_skba->len - 1;
 	for (i = 0; i < fill_wqes; i++) {
 		u64 tmp_addr;
-		struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
+		struct sk_buff *skb;
+
+		skb = netdev_alloc_skb_ip_align(dev, packet_size);
 		if (!skb) {
 			q_skba->os_skbs = fill_wqes - i;
 			if (q_skba->os_skbs == q_skba->len - 2) {
@@ -457,7 +459,6 @@ static int ehea_refill_rq_def(struct ehe
 			}
 			break;
 		}
-		skb_reserve(skb, NET_IP_ALIGN);
 
 		skb_arr[index] = skb;
 		tmp_addr = ehea_map_vaddr(skb->data);
@@ -500,7 +501,7 @@ static int ehea_refill_rq2(struct ehea_p
 {
 	return ehea_refill_rq_def(pr, &pr->rq2_skba, 2,
 				  nr_of_wqes, EHEA_RWQE2_TYPE,
-				  EHEA_RQ2_PKT_SIZE + NET_IP_ALIGN);
+				  EHEA_RQ2_PKT_SIZE);
 }
 
 
@@ -508,7 +509,7 @@ static int ehea_refill_rq3(struct ehea_p
 {
 	return ehea_refill_rq_def(pr, &pr->rq3_skba, 3,
 				  nr_of_wqes, EHEA_RWQE3_TYPE,
-				  EHEA_MAX_PACKET_SIZE + NET_IP_ALIGN);
+				  EHEA_MAX_PACKET_SIZE);
 }
 
 static inline int ehea_check_cqe(struct ehea_cqe *cqe, int *rq_num)
@@ -656,8 +657,8 @@ static int get_skb_hdr(struct sk_buff *s
 static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
 			  struct sk_buff *skb)
 {
-	int vlan_extracted = (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
-		&& pr->port->vgrp;
+	int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
+			      pr->port->vgrp);
 
 	if (use_lro) {
 		if (vlan_extracted)
@@ -1388,8 +1389,8 @@ out:
 
 int ehea_rem_smrs(struct ehea_port_res *pr)
 {
-	if ((ehea_rem_mr(&pr->send_mr))
-	    || (ehea_rem_mr(&pr->recv_mr)))
+	if ((ehea_rem_mr(&pr->send_mr)) ||
+	    (ehea_rem_mr(&pr->recv_mr)))
 		return -EIO;
 	else
 		return 0;
@@ -2030,8 +2031,8 @@ static void ehea_xmit2(struct sk_buff *s
 		write_ip_start_end(swqe, skb);
 
 		if (iph->protocol == IPPROTO_UDP) {
-			if ((iph->frag_off & IP_MF)
-			    || (iph->frag_off & IP_OFFSET))
+			if ((iph->frag_off & IP_MF) ||
+			    (iph->frag_off & IP_OFFSET))
 				/* IP fragment, so don't change cs */
 				swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM;
 			else
@@ -2076,8 +2077,8 @@ static void ehea_xmit3(struct sk_buff *s
 			write_tcp_offset_end(swqe, skb);
 
 		} else if (iph->protocol == IPPROTO_UDP) {
-			if ((iph->frag_off & IP_MF)
-			    || (iph->frag_off & IP_OFFSET))
+			if ((iph->frag_off & IP_MF) ||
+			    (iph->frag_off & IP_OFFSET))
 				/* IP fragment, so don't change cs */
 				swqe->tx_control |= EHEA_SWQE_CRC
 						 | EHEA_SWQE_IMM_DATA_PRESENT;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_phyp.h linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_phyp.h
--- linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_phyp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_phyp.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,7 +33,6 @@
 #include <asm/hvcall.h>
 #include "ehea.h"
 #include "ehea_hw.h"
-#include "ehea_hcall.h"
 
 /* Some abbreviations used here:
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_qmr.c linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_qmr.c
--- linux-libre-2.6.32-gnu1/drivers/net/ehea/ehea_qmr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ehea/ehea_qmr.c	2010-02-24 13:52:17.000000000 -0500
@@ -837,8 +837,8 @@ static u64 ehea_reg_mr_section(int top,
 		hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0,
 						0, pt_abs, EHEA_MAX_RPAGE);
 
-		if ((hret != H_SUCCESS)
-		    && (hret != H_PAGE_REGISTERED)) {
+		if ((hret != H_SUCCESS) &&
+		    (hret != H_PAGE_REGISTERED)) {
 			ehea_h_free_resource(adapter->handle, mr->handle,
 					     FORCE_FREE);
 			ehea_error("register_rpage_mr failed");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/enic/enic_main.c linux-libre-2.6.33-gnu1/drivers/net/enic/enic_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/enic/enic_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/enic/enic_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -870,19 +870,6 @@ static void enic_free_rq_buf(struct vnic
 	dev_kfree_skb_any(buf->os_buf);
 }
 
-static inline struct sk_buff *enic_rq_alloc_skb(struct net_device *netdev,
-	unsigned int size)
-{
-	struct sk_buff *skb;
-
-	skb = netdev_alloc_skb(netdev, size + NET_IP_ALIGN);
-
-	if (skb)
-		skb_reserve(skb, NET_IP_ALIGN);
-
-	return skb;
-}
-
 static int enic_rq_alloc_buf(struct vnic_rq *rq)
 {
 	struct enic *enic = vnic_dev_priv(rq->vdev);
@@ -892,7 +879,7 @@ static int enic_rq_alloc_buf(struct vnic
 	unsigned int os_buf_index = 0;
 	dma_addr_t dma_addr;
 
-	skb = enic_rq_alloc_skb(netdev, len);
+	skb = netdev_alloc_skb_ip_align(netdev, len);
 	if (!skb)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/epic100.c linux-libre-2.6.33-gnu1/drivers/net/epic100.c
--- linux-libre-2.6.32-gnu1/drivers/net/epic100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/epic100.c	2010-02-24 13:52:17.000000000 -0500
@@ -630,8 +630,8 @@ static int mdio_read(struct net_device *
 		barrier();
 		if ((inl(ioaddr + MIICtrl) & MII_READOP) == 0) {
 			/* Work around read failure bug. */
-			if (phy_id == 1 && location < 6
-				&& inw(ioaddr + MIIData) == 0xffff) {
+			if (phy_id == 1 && location < 6 &&
+			    inw(ioaddr + MIIData) == 0xffff) {
 				outl(read_cmd, ioaddr + MIICtrl);
 				continue;
 			}
@@ -668,7 +668,7 @@ static int epic_open(struct net_device *
 	outl(0x4001, ioaddr + GENCTL);
 
 	napi_enable(&ep->napi);
-	if ((retval = request_irq(dev->irq, &epic_interrupt, IRQF_SHARED, dev->name, dev))) {
+	if ((retval = request_irq(dev->irq, epic_interrupt, IRQF_SHARED, dev->name, dev))) {
 		napi_disable(&ep->napi);
 		return retval;
 	}
@@ -1205,8 +1205,8 @@ static int epic_rx(struct net_device *de
 			}
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(ep->pci_dev,
 							    ep->rx_ring[entry].bufaddr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ethoc.c linux-libre-2.6.33-gnu1/drivers/net/ethoc.c
--- linux-libre-2.6.32-gnu1/drivers/net/ethoc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ethoc.c	2010-02-24 13:52:17.000000000 -0500
@@ -406,10 +406,10 @@ static int ethoc_rx(struct net_device *d
 
 		if (ethoc_update_rx_stats(priv, &bd) == 0) {
 			int size = bd.stat >> 16;
-			struct sk_buff *skb = netdev_alloc_skb(dev, size);
+			struct sk_buff *skb;
 
 			size -= 4; /* strip the CRC */
-			skb_reserve(skb, 2); /* align TCP/IP header */
+			skb = netdev_alloc_skb_ip_align(dev, size);
 
 			if (likely(skb)) {
 				void *src = phys_to_virt(bd.addr);
@@ -641,7 +641,7 @@ static int ethoc_mdio_probe(struct net_d
 		return -ENXIO;
 	}
 
-	phy = phy_connect(dev, dev_name(&phy->dev), &ethoc_mdio_poll, 0,
+	phy = phy_connect(dev, dev_name(&phy->dev), ethoc_mdio_poll, 0,
 			PHY_INTERFACE_MODE_GMII);
 	if (IS_ERR(phy)) {
 		dev_err(&dev->dev, "could not attach to PHY\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/fealnx.c linux-libre-2.6.33-gnu1/drivers/net/fealnx.c
--- linux-libre-2.6.32-gnu1/drivers/net/fealnx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/fealnx.c	2010-02-24 13:52:17.000000000 -0500
@@ -839,7 +839,7 @@ static int netdev_open(struct net_device
 
 	iowrite32(0x00000001, ioaddr + BCR);	/* Reset */
 
-	if (request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev))
+	if (request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev))
 		return -EAGAIN;
 
 	for (i = 0; i < 3; i++)
@@ -1629,8 +1629,8 @@ static int netdev_rx(struct net_device *
 		if (debug)
 			printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n", rx_status);
 
-		if ((!((rx_status & RXFSD) && (rx_status & RXLSD)))
-		    || (rx_status & ErrorSummary)) {
+		if ((!((rx_status & RXFSD) && (rx_status & RXLSD))) ||
+		    (rx_status & ErrorSummary)) {
 			if (rx_status & ErrorSummary) {	/* there was a fatal error */
 				if (debug)
 					printk(KERN_DEBUG
@@ -1655,8 +1655,8 @@ static int netdev_rx(struct net_device *
 					cur = np->cur_rx;
 					while (desno <= np->really_rx_count) {
 						++desno;
-						if ((!(cur->status & RXOWN))
-						    && (cur->status & RXLSD))
+						if ((!(cur->status & RXOWN)) &&
+						    (cur->status & RXLSD))
 							break;
 						/* goto next rx descriptor */
 						cur = cur->next_desc_logical;
@@ -1786,8 +1786,8 @@ static void __set_rx_mode(struct net_dev
 	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = CR_W_PROM | CR_W_AB | CR_W_AM;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = CR_W_AB | CR_W_AM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/fec_mpc52xx.c linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx.c
--- linux-libre-2.6.32-gnu1/drivers/net/fec_mpc52xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/fec_mpc52xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -85,11 +85,15 @@ MODULE_PARM_DESC(debug, "debugging messa
 
 static void mpc52xx_fec_tx_timeout(struct net_device *dev)
 {
+	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
 	dev_warn(&dev->dev, "transmit timed out\n");
 
+	spin_lock_irqsave(&priv->lock, flags);
 	mpc52xx_fec_reset(dev);
-
 	dev->stats.tx_errors++;
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	netif_wake_queue(dev);
 }
@@ -135,28 +139,32 @@ static void mpc52xx_fec_free_rx_buffers(
 	}
 }
 
+static void
+mpc52xx_fec_rx_submit(struct net_device *dev, struct sk_buff *rskb)
+{
+	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+	struct bcom_fec_bd *bd;
+
+	bd = (struct bcom_fec_bd *) bcom_prepare_next_buffer(priv->rx_dmatsk);
+	bd->status = FEC_RX_BUFFER_SIZE;
+	bd->skb_pa = dma_map_single(dev->dev.parent, rskb->data,
+				    FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
+	bcom_submit_next_buffer(priv->rx_dmatsk, rskb);
+}
+
 static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task *rxtsk)
 {
-	while (!bcom_queue_full(rxtsk)) {
-		struct sk_buff *skb;
-		struct bcom_fec_bd *bd;
+	struct sk_buff *skb;
 
+	while (!bcom_queue_full(rxtsk)) {
 		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
-		if (skb == NULL)
+		if (!skb)
 			return -EAGAIN;
 
 		/* zero out the initial receive buffers to aid debugging */
 		memset(skb->data, 0, FEC_RX_BUFFER_SIZE);
-
-		bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk);
-
-		bd->status = FEC_RX_BUFFER_SIZE;
-		bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
-				FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
-
-		bcom_submit_next_buffer(rxtsk, skb);
+		mpc52xx_fec_rx_submit(dev, skb);
 	}
-
 	return 0;
 }
 
@@ -226,17 +234,17 @@ static int mpc52xx_fec_open(struct net_d
 		phy_start(priv->phydev);
 	}
 
-	if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
+	if (request_irq(dev->irq, mpc52xx_fec_interrupt, IRQF_SHARED,
 	                DRIVER_NAME "_ctrl", dev)) {
 		dev_err(&dev->dev, "ctrl interrupt request failed\n");
 		goto free_phy;
 	}
-	if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
+	if (request_irq(priv->r_irq, mpc52xx_fec_rx_interrupt, 0,
 	                DRIVER_NAME "_rx", dev)) {
 		dev_err(&dev->dev, "rx interrupt request failed\n");
 		goto free_ctrl_irq;
 	}
-	if (request_irq(priv->t_irq, &mpc52xx_fec_tx_interrupt, 0,
+	if (request_irq(priv->t_irq, mpc52xx_fec_tx_interrupt, 0,
 	                DRIVER_NAME "_tx", dev)) {
 		dev_err(&dev->dev, "tx interrupt request failed\n");
 		goto free_2irqs;
@@ -328,13 +336,12 @@ static int mpc52xx_fec_start_xmit(struct
 				    DMA_TO_DEVICE);
 
 	bcom_submit_next_buffer(priv->tx_dmatsk, skb);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	if (bcom_queue_full(priv->tx_dmatsk)) {
 		netif_stop_queue(dev);
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	return NETDEV_TX_OK;
 }
 
@@ -359,9 +366,9 @@ static irqreturn_t mpc52xx_fec_tx_interr
 {
 	struct net_device *dev = dev_id;
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+	unsigned long flags;
 
-	spin_lock(&priv->lock);
-
+	spin_lock_irqsave(&priv->lock, flags);
 	while (bcom_buffer_done(priv->tx_dmatsk)) {
 		struct sk_buff *skb;
 		struct bcom_fec_bd *bd;
@@ -372,11 +379,10 @@ static irqreturn_t mpc52xx_fec_tx_interr
 
 		dev_kfree_skb_irq(skb);
 	}
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	netif_wake_queue(dev);
 
-	spin_unlock(&priv->lock);
-
 	return IRQ_HANDLED;
 }
 
@@ -384,67 +390,60 @@ static irqreturn_t mpc52xx_fec_rx_interr
 {
 	struct net_device *dev = dev_id;
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+	struct sk_buff *rskb; /* received sk_buff */
+	struct sk_buff *skb;  /* new sk_buff to enqueue in its place */
+	struct bcom_fec_bd *bd;
+	u32 status, physaddr;
+	int length;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
 
 	while (bcom_buffer_done(priv->rx_dmatsk)) {
-		struct sk_buff *skb;
-		struct sk_buff *rskb;
-		struct bcom_fec_bd *bd;
-		u32 status;
 
 		rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status,
-				(struct bcom_bd **)&bd);
-		dma_unmap_single(dev->dev.parent, bd->skb_pa, rskb->len,
-				 DMA_FROM_DEVICE);
+					    (struct bcom_bd **)&bd);
+		physaddr = bd->skb_pa;
 
 		/* Test for errors in received frame */
 		if (status & BCOM_FEC_RX_BD_ERRORS) {
 			/* Drop packet and reuse the buffer */
-			bd = (struct bcom_fec_bd *)
-				bcom_prepare_next_buffer(priv->rx_dmatsk);
-
-			bd->status = FEC_RX_BUFFER_SIZE;
-			bd->skb_pa = dma_map_single(dev->dev.parent,
-					rskb->data,
-					FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
-
-			bcom_submit_next_buffer(priv->rx_dmatsk, rskb);
-
+			mpc52xx_fec_rx_submit(dev, rskb);
 			dev->stats.rx_dropped++;
-
 			continue;
 		}
 
 		/* skbs are allocated on open, so now we allocate a new one,
 		 * and remove the old (with the packet) */
 		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
-		if (skb) {
-			/* Process the received skb */
-			int length = status & BCOM_FEC_RX_BD_LEN_MASK;
-
-			skb_put(rskb, length - 4);	/* length without CRC32 */
-
-			rskb->dev = dev;
-			rskb->protocol = eth_type_trans(rskb, dev);
-
-			netif_rx(rskb);
-		} else {
+		if (!skb) {
 			/* Can't get a new one : reuse the same & drop pkt */
-			dev_notice(&dev->dev, "Memory squeeze, dropping packet.\n");
+			dev_notice(&dev->dev, "Low memory - dropped packet.\n");
+			mpc52xx_fec_rx_submit(dev, rskb);
 			dev->stats.rx_dropped++;
-
-			skb = rskb;
+			continue;
 		}
 
-		bd = (struct bcom_fec_bd *)
-			bcom_prepare_next_buffer(priv->rx_dmatsk);
+		/* Enqueue the new sk_buff back on the hardware */
+		mpc52xx_fec_rx_submit(dev, skb);
 
-		bd->status = FEC_RX_BUFFER_SIZE;
-		bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
-				FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
+		/* Process the received skb - Drop the spin lock while
+		 * calling into the network stack */
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-		bcom_submit_next_buffer(priv->rx_dmatsk, skb);
+		dma_unmap_single(dev->dev.parent, physaddr, rskb->len,
+				 DMA_FROM_DEVICE);
+		length = status & BCOM_FEC_RX_BD_LEN_MASK;
+		skb_put(rskb, length - 4);	/* length without CRC32 */
+		rskb->dev = dev;
+		rskb->protocol = eth_type_trans(rskb, dev);
+		netif_rx(rskb);
+
+		spin_lock_irqsave(&priv->lock, flags);
 	}
 
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	return IRQ_HANDLED;
 }
 
@@ -454,6 +453,7 @@ static irqreturn_t mpc52xx_fec_interrupt
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 	struct mpc52xx_fec __iomem *fec = priv->fec;
 	u32 ievent;
+	unsigned long flags;
 
 	ievent = in_be32(&fec->ievent);
 
@@ -471,9 +471,10 @@ static irqreturn_t mpc52xx_fec_interrupt
 		if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
 			dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
 
+		spin_lock_irqsave(&priv->lock, flags);
 		mpc52xx_fec_reset(dev);
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-		netif_wake_queue(dev);
 		return IRQ_HANDLED;
 	}
 
@@ -768,6 +769,8 @@ static void mpc52xx_fec_reset(struct net
 	bcom_enable(priv->tx_dmatsk);
 
 	mpc52xx_fec_start(dev);
+
+	netif_wake_queue(dev);
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/forcedeth.c linux-libre-2.6.33-gnu1/drivers/net/forcedeth.c
--- linux-libre-2.6.32-gnu1/drivers/net/forcedeth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/forcedeth.c	2010-02-24 13:52:17.000000000 -0500
@@ -4004,7 +4004,7 @@ static int nv_request_irq(struct net_dev
 				/* Request irq for rx handling */
 				sprintf(np->name_rx, "%s-rx", dev->name);
 				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector,
-						&nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
+						nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
 					printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
 					pci_disable_msix(np->pci_dev);
 					np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4013,7 +4013,7 @@ static int nv_request_irq(struct net_dev
 				/* Request irq for tx handling */
 				sprintf(np->name_tx, "%s-tx", dev->name);
 				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector,
-						&nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
+						nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
 					printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
 					pci_disable_msix(np->pci_dev);
 					np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4022,7 +4022,7 @@ static int nv_request_irq(struct net_dev
 				/* Request irq for link and timer handling */
 				sprintf(np->name_other, "%s-other", dev->name);
 				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector,
-						&nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
+						nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
 					printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
 					pci_disable_msix(np->pci_dev);
 					np->msi_flags &= ~NV_MSI_X_ENABLED;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/fsl_pq_mdio.c linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.c
--- linux-libre-2.6.32-gnu1/drivers/net/fsl_pq_mdio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,8 +3,9 @@
  * Provides Bus interface for MIIM regs
  *
  * Author: Andy Fleming <afleming@freescale.com>
+ * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
+ * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc.
  *
  * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
  *
@@ -45,6 +46,11 @@
 #include "gianfar.h"
 #include "fsl_pq_mdio.h"
 
+struct fsl_pq_mdio_priv {
+	void __iomem *map;
+	struct fsl_pq_mdio __iomem *regs;
+};
+
 /*
  * Write value to the PHY at mii_id at register regnum,
  * on the bus attached to the local interface, which may be different from the
@@ -102,13 +108,20 @@ int fsl_pq_local_mdio_read(struct fsl_pq
 	return value;
 }
 
+static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus)
+{
+	struct fsl_pq_mdio_priv *priv = bus->priv;
+
+	return priv->regs;
+}
+
 /*
  * Write value to the PHY at mii_id at register regnum,
  * on the bus, waiting until the write is done before returning.
  */
 int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
 {
-	struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+	struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
 
 	/* Write to the local MII regs */
 	return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value));
@@ -120,7 +133,7 @@ int fsl_pq_mdio_write(struct mii_bus *bu
  */
 int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
-	struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+	struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
 
 	/* Read the local MII regs */
 	return(fsl_pq_local_mdio_read(regs, mii_id, regnum));
@@ -129,7 +142,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus
 /* Reset the MIIM registers, and wait for the bus to free */
 static int fsl_pq_mdio_reset(struct mii_bus *bus)
 {
-	struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+	struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
 	int timeout = PHY_INIT_TIMEOUT;
 
 	mutex_lock(&bus->mdio_lock);
@@ -189,19 +202,29 @@ static int fsl_pq_mdio_find_free(struct
 
 
 #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
-static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs)
+static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
 {
 	struct gfar __iomem *enet_regs;
+	u32 __iomem *ioremap_tbipa;
+	u64 addr, size;
 
 	/*
 	 * This is mildly evil, but so is our hardware for doing this.
 	 * Also, we have to cast back to struct gfar because of
 	 * definition weirdness done in gianfar.h.
 	 */
-	enet_regs = (struct gfar __iomem *)
-		((char __iomem *)regs - offsetof(struct gfar, gfar_mii_regs));
-
-	return &enet_regs->tbipa;
+	if(of_device_is_compatible(np, "fsl,gianfar-mdio") ||
+		of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+		of_device_is_compatible(np, "gianfar")) {
+		enet_regs = (struct gfar __iomem *)regs;
+		return &enet_regs->tbipa;
+	} else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
+			of_device_is_compatible(np, "fsl,etsec2-tbi")) {
+		addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
+		ioremap_tbipa = ioremap(addr, size);
+		return ioremap_tbipa;
+	} else
+		return NULL;
 }
 #endif
 
@@ -250,33 +273,46 @@ static int fsl_pq_mdio_probe(struct of_d
 {
 	struct device_node *np = ofdev->node;
 	struct device_node *tbi;
-	struct fsl_pq_mdio __iomem *regs;
+	struct fsl_pq_mdio_priv *priv;
+	struct fsl_pq_mdio __iomem *regs = NULL;
+	void __iomem *map;
 	u32 __iomem *tbipa;
 	struct mii_bus *new_bus;
 	int tbiaddr = -1;
-	u64 addr, size;
+	u64 addr = 0, size = 0;
 	int err = 0;
 
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	new_bus = mdiobus_alloc();
 	if (NULL == new_bus)
-		return -ENOMEM;
+		goto err_free_priv;
 
 	new_bus->name = "Freescale PowerQUICC MII Bus",
 	new_bus->read = &fsl_pq_mdio_read,
 	new_bus->write = &fsl_pq_mdio_write,
 	new_bus->reset = &fsl_pq_mdio_reset,
+	new_bus->priv = priv;
 	fsl_pq_mdio_bus_name(new_bus->id, np);
 
 	/* Set the PHY base address */
 	addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
-	regs = ioremap(addr, size);
-
-	if (NULL == regs) {
+	map = ioremap(addr, size);
+	if (!map) {
 		err = -ENOMEM;
 		goto err_free_bus;
 	}
+	priv->map = map;
 
-	new_bus->priv = (void __force *)regs;
+	if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
+			of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+			of_device_is_compatible(np, "fsl,ucc-mdio") ||
+			of_device_is_compatible(np, "ucc_geth_phy"))
+		map -= offsetof(struct fsl_pq_mdio, miimcfg);
+	regs = map;
+	priv->regs = regs;
 
 	new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
 
@@ -290,9 +326,15 @@ static int fsl_pq_mdio_probe(struct of_d
 
 	if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
 			of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+			of_device_is_compatible(np, "fsl,etsec2-mdio") ||
+			of_device_is_compatible(np, "fsl,etsec2-tbi") ||
 			of_device_is_compatible(np, "gianfar")) {
 #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
-		tbipa = get_gfar_tbipa(regs);
+		tbipa = get_gfar_tbipa(regs, np);
+		if (!tbipa) {
+			err = -EINVAL;
+			goto err_free_irqs;
+		}
 #else
 		err = -ENODEV;
 		goto err_free_irqs;
@@ -363,10 +405,11 @@ static int fsl_pq_mdio_probe(struct of_d
 err_free_irqs:
 	kfree(new_bus->irq);
 err_unmap_regs:
-	iounmap(regs);
+	iounmap(priv->map);
 err_free_bus:
 	kfree(new_bus);
-
+err_free_priv:
+	kfree(priv);
 	return err;
 }
 
@@ -375,14 +418,16 @@ static int fsl_pq_mdio_remove(struct of_
 {
 	struct device *device = &ofdev->dev;
 	struct mii_bus *bus = dev_get_drvdata(device);
+	struct fsl_pq_mdio_priv *priv = bus->priv;
 
 	mdiobus_unregister(bus);
 
 	dev_set_drvdata(device, NULL);
 
-	iounmap((void __iomem *)bus->priv);
+	iounmap(priv->map);
 	bus->priv = NULL;
 	mdiobus_free(bus);
+	kfree(priv);
 
 	return 0;
 }
@@ -405,6 +450,12 @@ static struct of_device_id fsl_pq_mdio_m
 	{
 		.compatible = "fsl,gianfar-mdio",
 	},
+	{
+		.compatible = "fsl,etsec2-tbi",
+	},
+	{
+		.compatible = "fsl,etsec2-mdio",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/fsl_pq_mdio.h linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.h
--- linux-libre-2.6.32-gnu1/drivers/net/fsl_pq_mdio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/fsl_pq_mdio.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,8 +3,9 @@
  * Driver for the MDIO bus controller on Freescale PowerQUICC processors
  *
  * Author: Andy Fleming
+ * Modifier: Sandeep Gopalpet
  *
- * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
+ * Copyright 2002-2004, 2008-2009 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
@@ -23,6 +24,12 @@
 #define MII_READ_COMMAND       0x00000001
 
 struct fsl_pq_mdio {
+	u8 res1[16];
+	u32 ieventm;	/* MDIO Interrupt event register (for etsec2)*/
+	u32 imaskm;	/* MDIO Interrupt mask register (for etsec2)*/
+	u8 res2[4];
+	u32 emapm;	/* MDIO Event mapping register (for etsec2)*/
+	u8 res3[1280];
 	u32 miimcfg;		/* MII management configuration reg */
 	u32 miimcom;		/* MII management command reg */
 	u32 miimadd;		/* MII management address reg */
@@ -31,9 +38,9 @@ struct fsl_pq_mdio {
 	u32 miimind;		/* MII management indication reg */
 	u8 reserved[28];	/* Space holder */
 	u32 utbipar;		/* TBI phy address reg (only on UCC) */
+	u8 res4[2728];
 } __attribute__ ((packed));
 
-
 int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
 int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
 int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/gianfar.c linux-libre-2.6.33-gnu1/drivers/net/gianfar.c
--- linux-libre-2.6.32-gnu1/drivers/net/gianfar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/gianfar.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,9 +8,10 @@
  *
  * Author: Andy Fleming
  * Maintainer: Kumar Gala
+ * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright (c) 2002-2006 Freescale Semiconductor, Inc.
- * Copyright (c) 2007 MontaVista Software, Inc.
+ * Copyright 2002-2009 Freescale Semiconductor, Inc.
+ * Copyright 2007 MontaVista Software, 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
@@ -109,7 +110,7 @@ static void gfar_reset_task(struct work_
 static void gfar_timeout(struct net_device *dev);
 static int gfar_close(struct net_device *dev);
 struct sk_buff *gfar_new_skb(struct net_device *dev);
-static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
+static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
 		struct sk_buff *skb);
 static int gfar_set_mac_address(struct net_device *dev);
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
@@ -130,8 +131,8 @@ static int gfar_poll(struct napi_struct
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void gfar_netpoll(struct net_device *dev);
 #endif
-int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
-static int gfar_clean_tx_ring(struct net_device *dev);
+int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
+static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
 			      int amount_pull);
 static void gfar_vlan_rx_register(struct net_device *netdev,
@@ -147,6 +148,304 @@ MODULE_AUTHOR("Freescale Semiconductor,
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
+static void gfar_init_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
+			    dma_addr_t buf)
+{
+	u32 lstatus;
+
+	bdp->bufPtr = buf;
+
+	lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
+	if (bdp == rx_queue->rx_bd_base + rx_queue->rx_ring_size - 1)
+		lstatus |= BD_LFLAG(RXBD_WRAP);
+
+	eieio();
+
+	bdp->lstatus = lstatus;
+}
+
+static int gfar_init_bds(struct net_device *ndev)
+{
+	struct gfar_private *priv = netdev_priv(ndev);
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+	struct txbd8 *txbdp;
+	struct rxbd8 *rxbdp;
+	int i, j;
+
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		tx_queue = priv->tx_queue[i];
+		/* Initialize some variables in our dev structure */
+		tx_queue->num_txbdfree = tx_queue->tx_ring_size;
+		tx_queue->dirty_tx = tx_queue->tx_bd_base;
+		tx_queue->cur_tx = tx_queue->tx_bd_base;
+		tx_queue->skb_curtx = 0;
+		tx_queue->skb_dirtytx = 0;
+
+		/* Initialize Transmit Descriptor Ring */
+		txbdp = tx_queue->tx_bd_base;
+		for (j = 0; j < tx_queue->tx_ring_size; j++) {
+			txbdp->lstatus = 0;
+			txbdp->bufPtr = 0;
+			txbdp++;
+		}
+
+		/* Set the last descriptor in the ring to indicate wrap */
+		txbdp--;
+		txbdp->status |= TXBD_WRAP;
+	}
+
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		rx_queue = priv->rx_queue[i];
+		rx_queue->cur_rx = rx_queue->rx_bd_base;
+		rx_queue->skb_currx = 0;
+		rxbdp = rx_queue->rx_bd_base;
+
+		for (j = 0; j < rx_queue->rx_ring_size; j++) {
+			struct sk_buff *skb = rx_queue->rx_skbuff[j];
+
+			if (skb) {
+				gfar_init_rxbdp(rx_queue, rxbdp,
+						rxbdp->bufPtr);
+			} else {
+				skb = gfar_new_skb(ndev);
+				if (!skb) {
+					pr_err("%s: Can't allocate RX buffers\n",
+							ndev->name);
+					goto err_rxalloc_fail;
+				}
+				rx_queue->rx_skbuff[j] = skb;
+
+				gfar_new_rxbdp(rx_queue, rxbdp, skb);
+			}
+
+			rxbdp++;
+		}
+
+	}
+
+	return 0;
+
+err_rxalloc_fail:
+	free_skb_resources(priv);
+	return -ENOMEM;
+}
+
+static int gfar_alloc_skb_resources(struct net_device *ndev)
+{
+	void *vaddr;
+	dma_addr_t addr;
+	int i, j, k;
+	struct gfar_private *priv = netdev_priv(ndev);
+	struct device *dev = &priv->ofdev->dev;
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+
+	priv->total_tx_ring_size = 0;
+	for (i = 0; i < priv->num_tx_queues; i++)
+		priv->total_tx_ring_size += priv->tx_queue[i]->tx_ring_size;
+
+	priv->total_rx_ring_size = 0;
+	for (i = 0; i < priv->num_rx_queues; i++)
+		priv->total_rx_ring_size += priv->rx_queue[i]->rx_ring_size;
+
+	/* Allocate memory for the buffer descriptors */
+	vaddr = dma_alloc_coherent(dev,
+			sizeof(struct txbd8) * priv->total_tx_ring_size +
+			sizeof(struct rxbd8) * priv->total_rx_ring_size,
+			&addr, GFP_KERNEL);
+	if (!vaddr) {
+		if (netif_msg_ifup(priv))
+			pr_err("%s: Could not allocate buffer descriptors!\n",
+			       ndev->name);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		tx_queue = priv->tx_queue[i];
+		tx_queue->tx_bd_base = (struct txbd8 *) vaddr;
+		tx_queue->tx_bd_dma_base = addr;
+		tx_queue->dev = ndev;
+		/* enet DMA only understands physical addresses */
+		addr    += sizeof(struct txbd8) *tx_queue->tx_ring_size;
+		vaddr   += sizeof(struct txbd8) *tx_queue->tx_ring_size;
+	}
+
+	/* Start the rx descriptor ring where the tx ring leaves off */
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		rx_queue = priv->rx_queue[i];
+		rx_queue->rx_bd_base = (struct rxbd8 *) vaddr;
+		rx_queue->rx_bd_dma_base = addr;
+		rx_queue->dev = ndev;
+		addr    += sizeof (struct rxbd8) * rx_queue->rx_ring_size;
+		vaddr   += sizeof (struct rxbd8) * rx_queue->rx_ring_size;
+	}
+
+	/* Setup the skbuff rings */
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		tx_queue = priv->tx_queue[i];
+		tx_queue->tx_skbuff = kmalloc(sizeof(*tx_queue->tx_skbuff) *
+				  tx_queue->tx_ring_size, GFP_KERNEL);
+		if (!tx_queue->tx_skbuff) {
+			if (netif_msg_ifup(priv))
+				pr_err("%s: Could not allocate tx_skbuff\n",
+						ndev->name);
+			goto cleanup;
+		}
+
+		for (k = 0; k < tx_queue->tx_ring_size; k++)
+			tx_queue->tx_skbuff[k] = NULL;
+	}
+
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		rx_queue = priv->rx_queue[i];
+		rx_queue->rx_skbuff = kmalloc(sizeof(*rx_queue->rx_skbuff) *
+				  rx_queue->rx_ring_size, GFP_KERNEL);
+
+		if (!rx_queue->rx_skbuff) {
+			if (netif_msg_ifup(priv))
+				pr_err("%s: Could not allocate rx_skbuff\n",
+				       ndev->name);
+			goto cleanup;
+		}
+
+		for (j = 0; j < rx_queue->rx_ring_size; j++)
+			rx_queue->rx_skbuff[j] = NULL;
+	}
+
+	if (gfar_init_bds(ndev))
+		goto cleanup;
+
+	return 0;
+
+cleanup:
+	free_skb_resources(priv);
+	return -ENOMEM;
+}
+
+static void gfar_init_tx_rx_base(struct gfar_private *priv)
+{
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 __iomem *baddr;
+	int i;
+
+	baddr = &regs->tbase0;
+	for(i = 0; i < priv->num_tx_queues; i++) {
+		gfar_write(baddr, priv->tx_queue[i]->tx_bd_dma_base);
+		baddr	+= 2;
+	}
+
+	baddr = &regs->rbase0;
+	for(i = 0; i < priv->num_rx_queues; i++) {
+		gfar_write(baddr, priv->rx_queue[i]->rx_bd_dma_base);
+		baddr   += 2;
+	}
+}
+
+static void gfar_init_mac(struct net_device *ndev)
+{
+	struct gfar_private *priv = netdev_priv(ndev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 rctrl = 0;
+	u32 tctrl = 0;
+	u32 attrs = 0;
+
+	/* write the tx/rx base registers */
+	gfar_init_tx_rx_base(priv);
+
+	/* Configure the coalescing support */
+	gfar_configure_coalescing(priv, 0xFF, 0xFF);
+
+	if (priv->rx_filer_enable) {
+		rctrl |= RCTRL_FILREN;
+		/* Program the RIR0 reg with the required distribution */
+		gfar_write(&regs->rir0, DEFAULT_RIR0);
+	}
+
+	if (priv->rx_csum_enable)
+		rctrl |= RCTRL_CHECKSUMMING;
+
+	if (priv->extended_hash) {
+		rctrl |= RCTRL_EXTHASH;
+
+		gfar_clear_exact_match(ndev);
+		rctrl |= RCTRL_EMEN;
+	}
+
+	if (priv->padding) {
+		rctrl &= ~RCTRL_PAL_MASK;
+		rctrl |= RCTRL_PADDING(priv->padding);
+	}
+
+	/* keep vlan related bits if it's enabled */
+	if (priv->vlgrp) {
+		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
+		tctrl |= TCTRL_VLINS;
+	}
+
+	/* Init rctrl based on our settings */
+	gfar_write(&regs->rctrl, rctrl);
+
+	if (ndev->features & NETIF_F_IP_CSUM)
+		tctrl |= TCTRL_INIT_CSUM;
+
+	tctrl |= TCTRL_TXSCHED_PRIO;
+
+	gfar_write(&regs->tctrl, tctrl);
+
+	/* Set the extraction length and index */
+	attrs = ATTRELI_EL(priv->rx_stash_size) |
+		ATTRELI_EI(priv->rx_stash_index);
+
+	gfar_write(&regs->attreli, attrs);
+
+	/* Start with defaults, and add stashing or locking
+	 * depending on the approprate variables */
+	attrs = ATTR_INIT_SETTINGS;
+
+	if (priv->bd_stash_en)
+		attrs |= ATTR_BDSTASH;
+
+	if (priv->rx_stash_size != 0)
+		attrs |= ATTR_BUFSTASH;
+
+	gfar_write(&regs->attr, attrs);
+
+	gfar_write(&regs->fifo_tx_thr, priv->fifo_threshold);
+	gfar_write(&regs->fifo_tx_starve, priv->fifo_starve);
+	gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+}
+
+static struct net_device_stats *gfar_get_stats(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct netdev_queue *txq;
+	unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0;
+	unsigned long tx_packets = 0, tx_bytes = 0;
+	int i = 0;
+
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		rx_packets += priv->rx_queue[i]->stats.rx_packets;
+		rx_bytes += priv->rx_queue[i]->stats.rx_bytes;
+		rx_dropped += priv->rx_queue[i]->stats.rx_dropped;
+	}
+
+	dev->stats.rx_packets = rx_packets;
+	dev->stats.rx_bytes = rx_bytes;
+	dev->stats.rx_dropped = rx_dropped;
+
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		txq = netdev_get_tx_queue(dev, i);
+		tx_bytes += txq->tx_bytes;
+		tx_packets += txq->tx_packets;
+	}
+
+	dev->stats.tx_bytes = tx_bytes;
+	dev->stats.tx_packets = tx_packets;
+
+	return &dev->stats;
+}
+
 static const struct net_device_ops gfar_netdev_ops = {
 	.ndo_open = gfar_enet_open,
 	.ndo_start_xmit = gfar_start_xmit,
@@ -155,6 +454,7 @@ static const struct net_device_ops gfar_
 	.ndo_set_multicast_list = gfar_set_multi,
 	.ndo_tx_timeout = gfar_timeout,
 	.ndo_do_ioctl = gfar_ioctl,
+	.ndo_get_stats = gfar_get_stats,
 	.ndo_vlan_rx_register = gfar_vlan_rx_register,
 	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr = eth_validate_addr,
@@ -163,56 +463,248 @@ static const struct net_device_ops gfar_
 #endif
 };
 
+unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
+
+void lock_rx_qs(struct gfar_private *priv)
+{
+	int i = 0x0;
+
+	for (i = 0; i < priv->num_rx_queues; i++)
+		spin_lock(&priv->rx_queue[i]->rxlock);
+}
+
+void lock_tx_qs(struct gfar_private *priv)
+{
+	int i = 0x0;
+
+	for (i = 0; i < priv->num_tx_queues; i++)
+		spin_lock(&priv->tx_queue[i]->txlock);
+}
+
+void unlock_rx_qs(struct gfar_private *priv)
+{
+	int i = 0x0;
+
+	for (i = 0; i < priv->num_rx_queues; i++)
+		spin_unlock(&priv->rx_queue[i]->rxlock);
+}
+
+void unlock_tx_qs(struct gfar_private *priv)
+{
+	int i = 0x0;
+
+	for (i = 0; i < priv->num_tx_queues; i++)
+		spin_unlock(&priv->tx_queue[i]->txlock);
+}
+
 /* Returns 1 if incoming frames use an FCB */
 static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
 	return priv->vlgrp || priv->rx_csum_enable;
 }
 
-static int gfar_of_init(struct net_device *dev)
+static void free_tx_pointers(struct gfar_private *priv)
+{
+	int i = 0;
+
+	for (i = 0; i < priv->num_tx_queues; i++)
+		kfree(priv->tx_queue[i]);
+}
+
+static void free_rx_pointers(struct gfar_private *priv)
+{
+	int i = 0;
+
+	for (i = 0; i < priv->num_rx_queues; i++)
+		kfree(priv->rx_queue[i]);
+}
+
+static void unmap_group_regs(struct gfar_private *priv)
+{
+	int i = 0;
+
+	for (i = 0; i < MAXGROUPS; i++)
+		if (priv->gfargrp[i].regs)
+			iounmap(priv->gfargrp[i].regs);
+}
+
+static void disable_napi(struct gfar_private *priv)
+{
+	int i = 0;
+
+	for (i = 0; i < priv->num_grps; i++)
+		napi_disable(&priv->gfargrp[i].napi);
+}
+
+static void enable_napi(struct gfar_private *priv)
+{
+	int i = 0;
+
+	for (i = 0; i < priv->num_grps; i++)
+		napi_enable(&priv->gfargrp[i].napi);
+}
+
+static int gfar_parse_group(struct device_node *np,
+		struct gfar_private *priv, const char *model)
+{
+	u32 *queue_mask;
+	u64 addr, size;
+
+	addr = of_translate_address(np,
+			of_get_address(np, 0, &size, NULL));
+	priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
+
+	if (!priv->gfargrp[priv->num_grps].regs)
+		return -ENOMEM;
+
+	priv->gfargrp[priv->num_grps].interruptTransmit =
+			irq_of_parse_and_map(np, 0);
+
+	/* If we aren't the FEC we have multiple interrupts */
+	if (model && strcasecmp(model, "FEC")) {
+		priv->gfargrp[priv->num_grps].interruptReceive =
+			irq_of_parse_and_map(np, 1);
+		priv->gfargrp[priv->num_grps].interruptError =
+			irq_of_parse_and_map(np,2);
+		if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 ||
+			priv->gfargrp[priv->num_grps].interruptReceive < 0 ||
+			priv->gfargrp[priv->num_grps].interruptError < 0) {
+			return -EINVAL;
+		}
+	}
+
+	priv->gfargrp[priv->num_grps].grp_id = priv->num_grps;
+	priv->gfargrp[priv->num_grps].priv = priv;
+	spin_lock_init(&priv->gfargrp[priv->num_grps].grplock);
+	if(priv->mode == MQ_MG_MODE) {
+		queue_mask = (u32 *)of_get_property(np,
+					"fsl,rx-bit-map", NULL);
+		priv->gfargrp[priv->num_grps].rx_bit_map =
+			queue_mask ?  *queue_mask :(DEFAULT_MAPPING >> priv->num_grps);
+		queue_mask = (u32 *)of_get_property(np,
+					"fsl,tx-bit-map", NULL);
+		priv->gfargrp[priv->num_grps].tx_bit_map =
+			queue_mask ? *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
+	} else {
+		priv->gfargrp[priv->num_grps].rx_bit_map = 0xFF;
+		priv->gfargrp[priv->num_grps].tx_bit_map = 0xFF;
+	}
+	priv->num_grps++;
+
+	return 0;
+}
+
+static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
 {
 	const char *model;
 	const char *ctype;
 	const void *mac_addr;
-	u64 addr, size;
-	int err = 0;
-	struct gfar_private *priv = netdev_priv(dev);
-	struct device_node *np = priv->node;
+	int err = 0, i;
+	struct net_device *dev = NULL;
+	struct gfar_private *priv = NULL;
+	struct device_node *np = ofdev->node;
+	struct device_node *child = NULL;
 	const u32 *stash;
 	const u32 *stash_len;
 	const u32 *stash_idx;
+	unsigned int num_tx_qs, num_rx_qs;
+	u32 *tx_queues, *rx_queues;
 
 	if (!np || !of_device_is_available(np))
 		return -ENODEV;
 
-	/* get a pointer to the register memory */
-	addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
-	priv->regs = ioremap(addr, size);
+	/* parse the num of tx and rx queues */
+	tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL);
+	num_tx_qs = tx_queues ? *tx_queues : 1;
 
-	if (priv->regs == NULL)
+	if (num_tx_qs > MAX_TX_QS) {
+		printk(KERN_ERR "num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n",
+				num_tx_qs, MAX_TX_QS);
+		printk(KERN_ERR "Cannot do alloc_etherdev, aborting\n");
+		return -EINVAL;
+	}
+
+	rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
+	num_rx_qs = rx_queues ? *rx_queues : 1;
+
+	if (num_rx_qs > MAX_RX_QS) {
+		printk(KERN_ERR "num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n",
+				num_tx_qs, MAX_TX_QS);
+		printk(KERN_ERR "Cannot do alloc_etherdev, aborting\n");
+		return -EINVAL;
+	}
+
+	*pdev = alloc_etherdev_mq(sizeof(*priv), num_tx_qs);
+	dev = *pdev;
+	if (NULL == dev)
 		return -ENOMEM;
 
-	priv->interruptTransmit = irq_of_parse_and_map(np, 0);
+	priv = netdev_priv(dev);
+	priv->node = ofdev->node;
+	priv->ndev = dev;
+
+	dev->num_tx_queues = num_tx_qs;
+	dev->real_num_tx_queues = num_tx_qs;
+	priv->num_tx_queues = num_tx_qs;
+	priv->num_rx_queues = num_rx_qs;
+	priv->num_grps = 0x0;
 
 	model = of_get_property(np, "model", NULL);
 
-	/* If we aren't the FEC we have multiple interrupts */
-	if (model && strcasecmp(model, "FEC")) {
-		priv->interruptReceive = irq_of_parse_and_map(np, 1);
+	for (i = 0; i < MAXGROUPS; i++)
+		priv->gfargrp[i].regs = NULL;
 
-		priv->interruptError = irq_of_parse_and_map(np, 2);
+	/* Parse and initialize group specific information */
+	if (of_device_is_compatible(np, "fsl,etsec2")) {
+		priv->mode = MQ_MG_MODE;
+		for_each_child_of_node(np, child) {
+			err = gfar_parse_group(child, priv, model);
+			if (err)
+				goto err_grp_init;
+		}
+	} else {
+		priv->mode = SQ_SG_MODE;
+		err = gfar_parse_group(np, priv, model);
+		if(err)
+			goto err_grp_init;
+	}
 
-		if (priv->interruptTransmit < 0 ||
-				priv->interruptReceive < 0 ||
-				priv->interruptError < 0) {
-			err = -EINVAL;
-			goto err_out;
+	for (i = 0; i < priv->num_tx_queues; i++)
+	       priv->tx_queue[i] = NULL;
+	for (i = 0; i < priv->num_rx_queues; i++)
+		priv->rx_queue[i] = NULL;
+
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		priv->tx_queue[i] =  (struct gfar_priv_tx_q *)kmalloc(
+				sizeof (struct gfar_priv_tx_q), GFP_KERNEL);
+		if (!priv->tx_queue[i]) {
+			err = -ENOMEM;
+			goto tx_alloc_failed;
 		}
+		priv->tx_queue[i]->tx_skbuff = NULL;
+		priv->tx_queue[i]->qindex = i;
+		priv->tx_queue[i]->dev = dev;
+		spin_lock_init(&(priv->tx_queue[i]->txlock));
 	}
 
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc(
+					sizeof (struct gfar_priv_rx_q), GFP_KERNEL);
+		if (!priv->rx_queue[i]) {
+			err = -ENOMEM;
+			goto rx_alloc_failed;
+		}
+		priv->rx_queue[i]->rx_skbuff = NULL;
+		priv->rx_queue[i]->qindex = i;
+		priv->rx_queue[i]->dev = dev;
+		spin_lock_init(&(priv->rx_queue[i]->rxlock));
+	}
+
+
 	stash = of_get_property(np, "bd-stash", NULL);
 
-	if(stash) {
+	if (stash) {
 		priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING;
 		priv->bd_stash_en = 1;
 	}
@@ -270,8 +762,13 @@ static int gfar_of_init(struct net_devic
 
 	return 0;
 
-err_out:
-	iounmap(priv->regs);
+rx_alloc_failed:
+	free_rx_pointers(priv);
+tx_alloc_failed:
+	free_tx_pointers(priv);
+err_grp_init:
+	unmap_group_regs(priv);
+	free_netdev(dev);
 	return err;
 }
 
@@ -289,6 +786,85 @@ static int gfar_ioctl(struct net_device
 	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
 }
 
+static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
+{
+	unsigned int new_bit_map = 0x0;
+	int mask = 0x1 << (max_qs - 1), i;
+	for (i = 0; i < max_qs; i++) {
+		if (bit_map & mask)
+			new_bit_map = new_bit_map + (1 << i);
+		mask = mask >> 0x1;
+	}
+	return new_bit_map;
+}
+
+static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
+				   u32 class)
+{
+	u32 rqfpr = FPR_FILER_MASK;
+	u32 rqfcr = 0x0;
+
+	rqfar--;
+	rqfcr = RQFCR_CLE | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
+	ftp_rqfpr[rqfar] = rqfpr;
+	ftp_rqfcr[rqfar] = rqfcr;
+	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+	rqfar--;
+	rqfcr = RQFCR_CMP_NOMATCH;
+	ftp_rqfpr[rqfar] = rqfpr;
+	ftp_rqfcr[rqfar] = rqfcr;
+	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+	rqfar--;
+	rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND;
+	rqfpr = class;
+	ftp_rqfcr[rqfar] = rqfcr;
+	ftp_rqfpr[rqfar] = rqfpr;
+	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+	rqfar--;
+	rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_MASK | RQFCR_AND;
+	rqfpr = class;
+	ftp_rqfcr[rqfar] = rqfcr;
+	ftp_rqfpr[rqfar] = rqfpr;
+	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+	return rqfar;
+}
+
+static void gfar_init_filer_table(struct gfar_private *priv)
+{
+	int i = 0x0;
+	u32 rqfar = MAX_FILER_IDX;
+	u32 rqfcr = 0x0;
+	u32 rqfpr = FPR_FILER_MASK;
+
+	/* Default rule */
+	rqfcr = RQFCR_CMP_MATCH;
+	ftp_rqfcr[rqfar] = rqfcr;
+	ftp_rqfpr[rqfar] = rqfpr;
+	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
+
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6);
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6 | RQFPR_UDP);
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6 | RQFPR_TCP);
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4);
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4 | RQFPR_UDP);
+	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV4 | RQFPR_TCP);
+
+	/* cur_filer_idx indicated the fisrt non-masked rule */
+	priv->cur_filer_idx = rqfar;
+
+	/* Rest are masked rules */
+	rqfcr = RQFCR_CMP_NOMATCH;
+	for (i = 0; i < rqfar; i++) {
+		ftp_rqfcr[i] = rqfcr;
+		ftp_rqfpr[i] = rqfpr;
+		gfar_write_filer(priv, i, rqfcr, rqfpr);
+	}
+}
+
 /* Set up the ethernet device structure, private data,
  * and anything else we need before we start */
 static int gfar_probe(struct of_device *ofdev,
@@ -297,14 +873,17 @@ static int gfar_probe(struct of_device *
 	u32 tempval;
 	struct net_device *dev = NULL;
 	struct gfar_private *priv = NULL;
-	int err = 0;
+	struct gfar __iomem *regs = NULL;
+	int err = 0, i, grp_idx = 0;
 	int len_devname;
+	u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
+	u32 isrg = 0;
+	u32 __iomem *baddr;
 
-	/* Create an ethernet device instance */
-	dev = alloc_etherdev(sizeof (*priv));
+	err = gfar_of_init(ofdev, &dev);
 
-	if (NULL == dev)
-		return -ENOMEM;
+	if (err)
+		return err;
 
 	priv = netdev_priv(dev);
 	priv->ndev = dev;
@@ -312,50 +891,46 @@ static int gfar_probe(struct of_device *
 	priv->node = ofdev->node;
 	SET_NETDEV_DEV(dev, &ofdev->dev);
 
-	err = gfar_of_init(dev);
-
-	if (err)
-		goto regs_fail;
-
-	spin_lock_init(&priv->txlock);
-	spin_lock_init(&priv->rxlock);
 	spin_lock_init(&priv->bflock);
 	INIT_WORK(&priv->reset_task, gfar_reset_task);
 
 	dev_set_drvdata(&ofdev->dev, priv);
+	regs = priv->gfargrp[0].regs;
 
 	/* Stop the DMA engine now, in case it was running before */
 	/* (The firmware could have used it, and left it running). */
 	gfar_halt(dev);
 
 	/* Reset MAC layer */
-	gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
+	gfar_write(&regs->maccfg1, MACCFG1_SOFT_RESET);
 
 	/* We need to delay at least 3 TX clocks */
 	udelay(2);
 
 	tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
-	gfar_write(&priv->regs->maccfg1, tempval);
+	gfar_write(&regs->maccfg1, tempval);
 
 	/* Initialize MACCFG2. */
-	gfar_write(&priv->regs->maccfg2, MACCFG2_INIT_SETTINGS);
+	gfar_write(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
 
 	/* Initialize ECNTRL */
-	gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS);
+	gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
 
 	/* Set the dev->base_addr to the gfar reg region */
-	dev->base_addr = (unsigned long) (priv->regs);
+	dev->base_addr = (unsigned long) regs;
 
 	SET_NETDEV_DEV(dev, &ofdev->dev);
 
 	/* Fill in the dev structure */
 	dev->watchdog_timeo = TX_TIMEOUT;
-	netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
 	dev->mtu = 1500;
-
 	dev->netdev_ops = &gfar_netdev_ops;
 	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, GFAR_DEV_WEIGHT);
+
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
 		priv->rx_csum_enable = 1;
 		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA;
@@ -371,35 +946,35 @@ static int gfar_probe(struct of_device *
 		priv->extended_hash = 1;
 		priv->hash_width = 9;
 
-		priv->hash_regs[0] = &priv->regs->igaddr0;
-		priv->hash_regs[1] = &priv->regs->igaddr1;
-		priv->hash_regs[2] = &priv->regs->igaddr2;
-		priv->hash_regs[3] = &priv->regs->igaddr3;
-		priv->hash_regs[4] = &priv->regs->igaddr4;
-		priv->hash_regs[5] = &priv->regs->igaddr5;
-		priv->hash_regs[6] = &priv->regs->igaddr6;
-		priv->hash_regs[7] = &priv->regs->igaddr7;
-		priv->hash_regs[8] = &priv->regs->gaddr0;
-		priv->hash_regs[9] = &priv->regs->gaddr1;
-		priv->hash_regs[10] = &priv->regs->gaddr2;
-		priv->hash_regs[11] = &priv->regs->gaddr3;
-		priv->hash_regs[12] = &priv->regs->gaddr4;
-		priv->hash_regs[13] = &priv->regs->gaddr5;
-		priv->hash_regs[14] = &priv->regs->gaddr6;
-		priv->hash_regs[15] = &priv->regs->gaddr7;
+		priv->hash_regs[0] = &regs->igaddr0;
+		priv->hash_regs[1] = &regs->igaddr1;
+		priv->hash_regs[2] = &regs->igaddr2;
+		priv->hash_regs[3] = &regs->igaddr3;
+		priv->hash_regs[4] = &regs->igaddr4;
+		priv->hash_regs[5] = &regs->igaddr5;
+		priv->hash_regs[6] = &regs->igaddr6;
+		priv->hash_regs[7] = &regs->igaddr7;
+		priv->hash_regs[8] = &regs->gaddr0;
+		priv->hash_regs[9] = &regs->gaddr1;
+		priv->hash_regs[10] = &regs->gaddr2;
+		priv->hash_regs[11] = &regs->gaddr3;
+		priv->hash_regs[12] = &regs->gaddr4;
+		priv->hash_regs[13] = &regs->gaddr5;
+		priv->hash_regs[14] = &regs->gaddr6;
+		priv->hash_regs[15] = &regs->gaddr7;
 
 	} else {
 		priv->extended_hash = 0;
 		priv->hash_width = 8;
 
-		priv->hash_regs[0] = &priv->regs->gaddr0;
-		priv->hash_regs[1] = &priv->regs->gaddr1;
-		priv->hash_regs[2] = &priv->regs->gaddr2;
-		priv->hash_regs[3] = &priv->regs->gaddr3;
-		priv->hash_regs[4] = &priv->regs->gaddr4;
-		priv->hash_regs[5] = &priv->regs->gaddr5;
-		priv->hash_regs[6] = &priv->regs->gaddr6;
-		priv->hash_regs[7] = &priv->regs->gaddr7;
+		priv->hash_regs[0] = &regs->gaddr0;
+		priv->hash_regs[1] = &regs->gaddr1;
+		priv->hash_regs[2] = &regs->gaddr2;
+		priv->hash_regs[3] = &regs->gaddr3;
+		priv->hash_regs[4] = &regs->gaddr4;
+		priv->hash_regs[5] = &regs->gaddr5;
+		priv->hash_regs[6] = &regs->gaddr6;
+		priv->hash_regs[7] = &regs->gaddr7;
 	}
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
@@ -410,16 +985,74 @@ static int gfar_probe(struct of_device *
 	if (dev->features & NETIF_F_IP_CSUM)
 		dev->hard_header_len += GMAC_FCB_LEN;
 
+	/* Program the isrg regs only if number of grps > 1 */
+	if (priv->num_grps > 1) {
+		baddr = &regs->isrg0;
+		for (i = 0; i < priv->num_grps; i++) {
+			isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
+			isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
+			gfar_write(baddr, isrg);
+			baddr++;
+			isrg = 0x0;
+		}
+	}
+
+	/* Need to reverse the bit maps as  bit_map's MSB is q0
+	 * but, for_each_bit parses from right to left, which
+	 * basically reverses the queue numbers */
+	for (i = 0; i< priv->num_grps; i++) {
+		priv->gfargrp[i].tx_bit_map = reverse_bitmap(
+				priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
+		priv->gfargrp[i].rx_bit_map = reverse_bitmap(
+				priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
+	}
+
+	/* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
+	 * also assign queues to groups */
+	for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
+		priv->gfargrp[grp_idx].num_rx_queues = 0x0;
+		for_each_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
+				priv->num_rx_queues) {
+			priv->gfargrp[grp_idx].num_rx_queues++;
+			priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
+			rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
+			rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
+		}
+		priv->gfargrp[grp_idx].num_tx_queues = 0x0;
+		for_each_bit (i, &priv->gfargrp[grp_idx].tx_bit_map,
+				priv->num_tx_queues) {
+			priv->gfargrp[grp_idx].num_tx_queues++;
+			priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
+			tstat = tstat | (TSTAT_CLEAR_THALT >> i);
+			tqueue = tqueue | (TQUEUE_EN0 >> i);
+		}
+		priv->gfargrp[grp_idx].rstat = rstat;
+		priv->gfargrp[grp_idx].tstat = tstat;
+		rstat = tstat =0;
+	}
+
+	gfar_write(&regs->rqueue, rqueue);
+	gfar_write(&regs->tqueue, tqueue);
+
 	priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
-	priv->tx_ring_size = DEFAULT_TX_RING_SIZE;
-	priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
-	priv->num_txbdfree = DEFAULT_TX_RING_SIZE;
 
-	priv->txcoalescing = DEFAULT_TX_COALESCE;
-	priv->txic = DEFAULT_TXIC;
-	priv->rxcoalescing = DEFAULT_RX_COALESCE;
-	priv->rxic = DEFAULT_RXIC;
+	/* Initializing some of the rx/tx queue level parameters */
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		priv->tx_queue[i]->tx_ring_size = DEFAULT_TX_RING_SIZE;
+		priv->tx_queue[i]->num_txbdfree = DEFAULT_TX_RING_SIZE;
+		priv->tx_queue[i]->txcoalescing = DEFAULT_TX_COALESCE;
+		priv->tx_queue[i]->txic = DEFAULT_TXIC;
+	}
+
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		priv->rx_queue[i]->rx_ring_size = DEFAULT_RX_RING_SIZE;
+		priv->rx_queue[i]->rxcoalescing = DEFAULT_RX_COALESCE;
+		priv->rx_queue[i]->rxic = DEFAULT_RXIC;
+	}
 
+	/* enable filer if using multiple RX queues*/
+	if(priv->num_rx_queues > 1)
+		priv->rx_filer_enable = 1;
 	/* Enable most messages by default */
 	priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
 
@@ -439,20 +1072,43 @@ static int gfar_probe(struct of_device *
 
 	/* fill out IRQ number and name fields */
 	len_devname = strlen(dev->name);
-	strncpy(&priv->int_name_tx[0], dev->name, len_devname);
-	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-		strncpy(&priv->int_name_tx[len_devname],
-			"_tx", sizeof("_tx") + 1);
+	for (i = 0; i < priv->num_grps; i++) {
+		strncpy(&priv->gfargrp[i].int_name_tx[0], dev->name,
+				len_devname);
+		if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
+			strncpy(&priv->gfargrp[i].int_name_tx[len_devname],
+				"_g", sizeof("_g"));
+			priv->gfargrp[i].int_name_tx[
+				strlen(priv->gfargrp[i].int_name_tx)] = i+48;
+			strncpy(&priv->gfargrp[i].int_name_tx[strlen(
+				priv->gfargrp[i].int_name_tx)],
+				"_tx", sizeof("_tx") + 1);
 
-		strncpy(&priv->int_name_rx[0], dev->name, len_devname);
-		strncpy(&priv->int_name_rx[len_devname],
-			"_rx", sizeof("_rx") + 1);
+			strncpy(&priv->gfargrp[i].int_name_rx[0], dev->name,
+					len_devname);
+			strncpy(&priv->gfargrp[i].int_name_rx[len_devname],
+					"_g", sizeof("_g"));
+			priv->gfargrp[i].int_name_rx[
+				strlen(priv->gfargrp[i].int_name_rx)] = i+48;
+			strncpy(&priv->gfargrp[i].int_name_rx[strlen(
+				priv->gfargrp[i].int_name_rx)],
+				"_rx", sizeof("_rx") + 1);
 
-		strncpy(&priv->int_name_er[0], dev->name, len_devname);
-		strncpy(&priv->int_name_er[len_devname],
-			"_er", sizeof("_er") + 1);
-	} else
-		priv->int_name_tx[len_devname] = '\0';
+			strncpy(&priv->gfargrp[i].int_name_er[0], dev->name,
+					len_devname);
+			strncpy(&priv->gfargrp[i].int_name_er[len_devname],
+				"_g", sizeof("_g"));
+			priv->gfargrp[i].int_name_er[strlen(
+					priv->gfargrp[i].int_name_er)] = i+48;
+			strncpy(&priv->gfargrp[i].int_name_er[strlen(\
+				priv->gfargrp[i].int_name_er)],
+				"_er", sizeof("_er") + 1);
+		} else
+			priv->gfargrp[i].int_name_tx[len_devname] = '\0';
+	}
+
+	/* Initialize the filer table */
+	gfar_init_filer_table(priv);
 
 	/* Create all the sysfs files */
 	gfar_init_sysfs(dev);
@@ -463,14 +1119,19 @@ static int gfar_probe(struct of_device *
 	/* Even more device info helps when determining which kernel */
 	/* provided which set of benchmarks. */
 	printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
-	printk(KERN_INFO "%s: %d/%d RX/TX BD ring size\n",
-	       dev->name, priv->rx_ring_size, priv->tx_ring_size);
+	for (i = 0; i < priv->num_rx_queues; i++)
+		printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n",
+			dev->name, i, priv->rx_queue[i]->rx_ring_size);
+	for(i = 0; i < priv->num_tx_queues; i++)
+		 printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n",
+			dev->name, i, priv->tx_queue[i]->tx_ring_size);
 
 	return 0;
 
 register_fail:
-	iounmap(priv->regs);
-regs_fail:
+	unmap_group_regs(priv);
+	free_tx_pointers(priv);
+	free_rx_pointers(priv);
 	if (priv->phy_node)
 		of_node_put(priv->phy_node);
 	if (priv->tbi_node)
@@ -491,54 +1152,59 @@ static int gfar_remove(struct of_device
 	dev_set_drvdata(&ofdev->dev, NULL);
 
 	unregister_netdev(priv->ndev);
-	iounmap(priv->regs);
+	unmap_group_regs(priv);
 	free_netdev(priv->ndev);
 
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
+
+static int gfar_suspend(struct device *dev)
 {
-	struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-	struct net_device *dev = priv->ndev;
+	struct gfar_private *priv = dev_get_drvdata(dev);
+	struct net_device *ndev = priv->ndev;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned long flags;
 	u32 tempval;
 
 	int magic_packet = priv->wol_en &&
 		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
 
-	netif_device_detach(dev);
+	netif_device_detach(ndev);
 
-	if (netif_running(dev)) {
-		spin_lock_irqsave(&priv->txlock, flags);
-		spin_lock(&priv->rxlock);
+	if (netif_running(ndev)) {
 
-		gfar_halt_nodisable(dev);
+		local_irq_save(flags);
+		lock_tx_qs(priv);
+		lock_rx_qs(priv);
+
+		gfar_halt_nodisable(ndev);
 
 		/* Disable Tx, and Rx if wake-on-LAN is disabled. */
-		tempval = gfar_read(&priv->regs->maccfg1);
+		tempval = gfar_read(&regs->maccfg1);
 
 		tempval &= ~MACCFG1_TX_EN;
 
 		if (!magic_packet)
 			tempval &= ~MACCFG1_RX_EN;
 
-		gfar_write(&priv->regs->maccfg1, tempval);
+		gfar_write(&regs->maccfg1, tempval);
 
-		spin_unlock(&priv->rxlock);
-		spin_unlock_irqrestore(&priv->txlock, flags);
+		unlock_rx_qs(priv);
+		unlock_tx_qs(priv);
+		local_irq_restore(flags);
 
-		napi_disable(&priv->napi);
+		disable_napi(priv);
 
 		if (magic_packet) {
 			/* Enable interrupt on Magic Packet */
-			gfar_write(&priv->regs->imask, IMASK_MAG);
+			gfar_write(&regs->imask, IMASK_MAG);
 
 			/* Enable Magic Packet mode */
-			tempval = gfar_read(&priv->regs->maccfg2);
+			tempval = gfar_read(&regs->maccfg2);
 			tempval |= MACCFG2_MPEN;
-			gfar_write(&priv->regs->maccfg2, tempval);
+			gfar_write(&regs->maccfg2, tempval);
 		} else {
 			phy_stop(priv->phydev);
 		}
@@ -547,17 +1213,18 @@ static int gfar_suspend(struct of_device
 	return 0;
 }
 
-static int gfar_resume(struct of_device *ofdev)
+static int gfar_resume(struct device *dev)
 {
-	struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-	struct net_device *dev = priv->ndev;
+	struct gfar_private *priv = dev_get_drvdata(dev);
+	struct net_device *ndev = priv->ndev;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned long flags;
 	u32 tempval;
 	int magic_packet = priv->wol_en &&
 		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
 
-	if (!netif_running(dev)) {
-		netif_device_attach(dev);
+	if (!netif_running(ndev)) {
+		netif_device_attach(ndev);
 		return 0;
 	}
 
@@ -567,28 +1234,80 @@ static int gfar_resume(struct of_device
 	/* Disable Magic Packet mode, in case something
 	 * else woke us up.
 	 */
+	local_irq_save(flags);
+	lock_tx_qs(priv);
+	lock_rx_qs(priv);
 
-	spin_lock_irqsave(&priv->txlock, flags);
-	spin_lock(&priv->rxlock);
-
-	tempval = gfar_read(&priv->regs->maccfg2);
+	tempval = gfar_read(&regs->maccfg2);
 	tempval &= ~MACCFG2_MPEN;
-	gfar_write(&priv->regs->maccfg2, tempval);
+	gfar_write(&regs->maccfg2, tempval);
 
-	gfar_start(dev);
+	gfar_start(ndev);
 
-	spin_unlock(&priv->rxlock);
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_rx_qs(priv);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 
-	netif_device_attach(dev);
+	netif_device_attach(ndev);
 
-	napi_enable(&priv->napi);
+	enable_napi(priv);
+
+	return 0;
+}
+
+static int gfar_restore(struct device *dev)
+{
+	struct gfar_private *priv = dev_get_drvdata(dev);
+	struct net_device *ndev = priv->ndev;
+
+	if (!netif_running(ndev))
+		return 0;
+
+	gfar_init_bds(ndev);
+	init_registers(ndev);
+	gfar_set_mac_address(ndev);
+	gfar_init_mac(ndev);
+	gfar_start(ndev);
+
+	priv->oldlink = 0;
+	priv->oldspeed = 0;
+	priv->oldduplex = -1;
+
+	if (priv->phydev)
+		phy_start(priv->phydev);
+
+	netif_device_attach(ndev);
+	enable_napi(priv);
 
 	return 0;
 }
+
+static struct dev_pm_ops gfar_pm_ops = {
+	.suspend = gfar_suspend,
+	.resume = gfar_resume,
+	.freeze = gfar_suspend,
+	.thaw = gfar_resume,
+	.restore = gfar_restore,
+};
+
+#define GFAR_PM_OPS (&gfar_pm_ops)
+
+static int gfar_legacy_suspend(struct of_device *ofdev, pm_message_t state)
+{
+	return gfar_suspend(&ofdev->dev);
+}
+
+static int gfar_legacy_resume(struct of_device *ofdev)
+{
+	return gfar_resume(&ofdev->dev);
+}
+
 #else
-#define gfar_suspend NULL
-#define gfar_resume NULL
+
+#define GFAR_PM_OPS NULL
+#define gfar_legacy_suspend NULL
+#define gfar_legacy_resume NULL
+
 #endif
 
 /* Reads the controller's registers to determine what interface
@@ -597,7 +1316,10 @@ static int gfar_resume(struct of_device
 static phy_interface_t gfar_get_interface(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	u32 ecntrl = gfar_read(&priv->regs->ecntrl);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 ecntrl;
+
+	ecntrl = gfar_read(&regs->ecntrl);
 
 	if (ecntrl & ECNTRL_SGMII_MODE)
 		return PHY_INTERFACE_MODE_SGMII;
@@ -719,46 +1441,52 @@ static void gfar_configure_serdes(struct
 static void init_registers(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = NULL;
+	int i = 0;
 
-	/* Clear IEVENT */
-	gfar_write(&priv->regs->ievent, IEVENT_INIT_CLEAR);
+	for (i = 0; i < priv->num_grps; i++) {
+		regs = priv->gfargrp[i].regs;
+		/* Clear IEVENT */
+		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
 
-	/* Initialize IMASK */
-	gfar_write(&priv->regs->imask, IMASK_INIT_CLEAR);
+		/* Initialize IMASK */
+		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
+	}
 
+	regs = priv->gfargrp[0].regs;
 	/* Init hash registers to zero */
-	gfar_write(&priv->regs->igaddr0, 0);
-	gfar_write(&priv->regs->igaddr1, 0);
-	gfar_write(&priv->regs->igaddr2, 0);
-	gfar_write(&priv->regs->igaddr3, 0);
-	gfar_write(&priv->regs->igaddr4, 0);
-	gfar_write(&priv->regs->igaddr5, 0);
-	gfar_write(&priv->regs->igaddr6, 0);
-	gfar_write(&priv->regs->igaddr7, 0);
+	gfar_write(&regs->igaddr0, 0);
+	gfar_write(&regs->igaddr1, 0);
+	gfar_write(&regs->igaddr2, 0);
+	gfar_write(&regs->igaddr3, 0);
+	gfar_write(&regs->igaddr4, 0);
+	gfar_write(&regs->igaddr5, 0);
+	gfar_write(&regs->igaddr6, 0);
+	gfar_write(&regs->igaddr7, 0);
 
-	gfar_write(&priv->regs->gaddr0, 0);
-	gfar_write(&priv->regs->gaddr1, 0);
-	gfar_write(&priv->regs->gaddr2, 0);
-	gfar_write(&priv->regs->gaddr3, 0);
-	gfar_write(&priv->regs->gaddr4, 0);
-	gfar_write(&priv->regs->gaddr5, 0);
-	gfar_write(&priv->regs->gaddr6, 0);
-	gfar_write(&priv->regs->gaddr7, 0);
+	gfar_write(&regs->gaddr0, 0);
+	gfar_write(&regs->gaddr1, 0);
+	gfar_write(&regs->gaddr2, 0);
+	gfar_write(&regs->gaddr3, 0);
+	gfar_write(&regs->gaddr4, 0);
+	gfar_write(&regs->gaddr5, 0);
+	gfar_write(&regs->gaddr6, 0);
+	gfar_write(&regs->gaddr7, 0);
 
 	/* Zero out the rmon mib registers if it has them */
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-		memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib));
+		memset_io(&(regs->rmon), 0, sizeof (struct rmon_mib));
 
 		/* Mask off the CAM interrupts */
-		gfar_write(&priv->regs->rmon.cam1, 0xffffffff);
-		gfar_write(&priv->regs->rmon.cam2, 0xffffffff);
+		gfar_write(&regs->rmon.cam1, 0xffffffff);
+		gfar_write(&regs->rmon.cam2, 0xffffffff);
 	}
 
 	/* Initialize the max receive buffer length */
-	gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
+	gfar_write(&regs->mrblr, priv->rx_buffer_size);
 
 	/* Initialize the Minimum Frame Length Register */
-	gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
+	gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
 }
 
 
@@ -766,23 +1494,28 @@ static void init_registers(struct net_de
 static void gfar_halt_nodisable(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
+	struct gfar __iomem *regs = NULL;
 	u32 tempval;
+	int i = 0;
 
-	/* Mask all interrupts */
-	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
+	for (i = 0; i < priv->num_grps; i++) {
+		regs = priv->gfargrp[i].regs;
+		/* Mask all interrupts */
+		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
-	/* Clear all interrupts */
-	gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
+		/* Clear all interrupts */
+		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
+	}
 
+	regs = priv->gfargrp[0].regs;
 	/* Stop the DMA, and wait for it to stop */
-	tempval = gfar_read(&priv->regs->dmactrl);
+	tempval = gfar_read(&regs->dmactrl);
 	if ((tempval & (DMACTRL_GRS | DMACTRL_GTS))
 	    != (DMACTRL_GRS | DMACTRL_GTS)) {
 		tempval |= (DMACTRL_GRS | DMACTRL_GTS);
-		gfar_write(&priv->regs->dmactrl, tempval);
+		gfar_write(&regs->dmactrl, tempval);
 
-		while (!(gfar_read(&priv->regs->ievent) &
+		while (!(gfar_read(&regs->ievent) &
 			 (IEVENT_GRSC | IEVENT_GTSC)))
 			cpu_relax();
 	}
@@ -792,7 +1525,7 @@ static void gfar_halt_nodisable(struct n
 void gfar_halt(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	u32 tempval;
 
 	gfar_halt_nodisable(dev);
@@ -803,101 +1536,131 @@ void gfar_halt(struct net_device *dev)
 	gfar_write(&regs->maccfg1, tempval);
 }
 
+static void free_grp_irqs(struct gfar_priv_grp *grp)
+{
+	free_irq(grp->interruptError, grp);
+	free_irq(grp->interruptTransmit, grp);
+	free_irq(grp->interruptReceive, grp);
+}
+
 void stop_gfar(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
 	unsigned long flags;
+	int i;
 
 	phy_stop(priv->phydev);
 
+
 	/* Lock it down */
-	spin_lock_irqsave(&priv->txlock, flags);
-	spin_lock(&priv->rxlock);
+	local_irq_save(flags);
+	lock_tx_qs(priv);
+	lock_rx_qs(priv);
 
 	gfar_halt(dev);
 
-	spin_unlock(&priv->rxlock);
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_rx_qs(priv);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 
 	/* Free the IRQs */
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-		free_irq(priv->interruptError, dev);
-		free_irq(priv->interruptTransmit, dev);
-		free_irq(priv->interruptReceive, dev);
+		for (i = 0; i < priv->num_grps; i++)
+			free_grp_irqs(&priv->gfargrp[i]);
 	} else {
-		free_irq(priv->interruptTransmit, dev);
+		for (i = 0; i < priv->num_grps; i++)
+			free_irq(priv->gfargrp[i].interruptTransmit,
+					&priv->gfargrp[i]);
 	}
 
 	free_skb_resources(priv);
-
-	dma_free_coherent(&priv->ofdev->dev,
-			sizeof(struct txbd8)*priv->tx_ring_size
-			+ sizeof(struct rxbd8)*priv->rx_ring_size,
-			priv->tx_bd_base,
-			gfar_read(&regs->tbase0));
 }
 
-/* If there are any tx skbs or rx skbs still around, free them.
- * Then free tx_skbuff and rx_skbuff */
-static void free_skb_resources(struct gfar_private *priv)
+static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue)
 {
-	struct rxbd8 *rxbdp;
 	struct txbd8 *txbdp;
+	struct gfar_private *priv = netdev_priv(tx_queue->dev);
 	int i, j;
 
-	/* Go through all the buffer descriptors and free their data buffers */
-	txbdp = priv->tx_bd_base;
+	txbdp = tx_queue->tx_bd_base;
 
-	for (i = 0; i < priv->tx_ring_size; i++) {
-		if (!priv->tx_skbuff[i])
+	for (i = 0; i < tx_queue->tx_ring_size; i++) {
+		if (!tx_queue->tx_skbuff[i])
 			continue;
 
 		dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr,
 				txbdp->length, DMA_TO_DEVICE);
 		txbdp->lstatus = 0;
-		for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) {
+		for (j = 0; j < skb_shinfo(tx_queue->tx_skbuff[i])->nr_frags;
+				j++) {
 			txbdp++;
 			dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
 					txbdp->length, DMA_TO_DEVICE);
 		}
 		txbdp++;
-		dev_kfree_skb_any(priv->tx_skbuff[i]);
-		priv->tx_skbuff[i] = NULL;
+		dev_kfree_skb_any(tx_queue->tx_skbuff[i]);
+		tx_queue->tx_skbuff[i] = NULL;
 	}
+	kfree(tx_queue->tx_skbuff);
+}
 
-	kfree(priv->tx_skbuff);
-
-	rxbdp = priv->rx_bd_base;
+static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue)
+{
+	struct rxbd8 *rxbdp;
+	struct gfar_private *priv = netdev_priv(rx_queue->dev);
+	int i;
 
-	/* rx_skbuff is not guaranteed to be allocated, so only
-	 * free it and its contents if it is allocated */
-	if(priv->rx_skbuff != NULL) {
-		for (i = 0; i < priv->rx_ring_size; i++) {
-			if (priv->rx_skbuff[i]) {
-				dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
-						priv->rx_buffer_size,
-						DMA_FROM_DEVICE);
+	rxbdp = rx_queue->rx_bd_base;
 
-				dev_kfree_skb_any(priv->rx_skbuff[i]);
-				priv->rx_skbuff[i] = NULL;
-			}
+	for (i = 0; i < rx_queue->rx_ring_size; i++) {
+		if (rx_queue->rx_skbuff[i]) {
+			dma_unmap_single(&priv->ofdev->dev,
+					rxbdp->bufPtr, priv->rx_buffer_size,
+					DMA_FROM_DEVICE);
+			dev_kfree_skb_any(rx_queue->rx_skbuff[i]);
+			rx_queue->rx_skbuff[i] = NULL;
+		}
+		rxbdp->lstatus = 0;
+		rxbdp->bufPtr = 0;
+		rxbdp++;
+	}
+	kfree(rx_queue->rx_skbuff);
+}
 
-			rxbdp->lstatus = 0;
-			rxbdp->bufPtr = 0;
+/* If there are any tx skbs or rx skbs still around, free them.
+ * Then free tx_skbuff and rx_skbuff */
+static void free_skb_resources(struct gfar_private *priv)
+{
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+	int i;
 
-			rxbdp++;
-		}
+	/* Go through all the buffer descriptors and free their data buffers */
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		tx_queue = priv->tx_queue[i];
+		if(!tx_queue->tx_skbuff)
+			free_skb_tx_queue(tx_queue);
+	}
 
-		kfree(priv->rx_skbuff);
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		rx_queue = priv->rx_queue[i];
+		if(!rx_queue->rx_skbuff)
+			free_skb_rx_queue(rx_queue);
 	}
+
+	dma_free_coherent(&priv->ofdev->dev,
+			sizeof(struct txbd8) * priv->total_tx_ring_size +
+			sizeof(struct rxbd8) * priv->total_rx_ring_size,
+			priv->tx_queue[0]->tx_bd_base,
+			priv->tx_queue[0]->tx_bd_dma_base);
 }
 
 void gfar_start(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	u32 tempval;
+	int i = 0;
 
 	/* Enable Rx and Tx in MACCFG1 */
 	tempval = gfar_read(&regs->maccfg1);
@@ -905,269 +1668,159 @@ void gfar_start(struct net_device *dev)
 	gfar_write(&regs->maccfg1, tempval);
 
 	/* Initialize DMACTRL to have WWR and WOP */
-	tempval = gfar_read(&priv->regs->dmactrl);
+	tempval = gfar_read(&regs->dmactrl);
 	tempval |= DMACTRL_INIT_SETTINGS;
-	gfar_write(&priv->regs->dmactrl, tempval);
+	gfar_write(&regs->dmactrl, tempval);
 
 	/* Make sure we aren't stopped */
-	tempval = gfar_read(&priv->regs->dmactrl);
+	tempval = gfar_read(&regs->dmactrl);
 	tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
-	gfar_write(&priv->regs->dmactrl, tempval);
-
-	/* Clear THLT/RHLT, so that the DMA starts polling now */
-	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT);
-	gfar_write(&regs->rstat, RSTAT_CLEAR_RHALT);
+	gfar_write(&regs->dmactrl, tempval);
 
-	/* Unmask the interrupts we look for */
-	gfar_write(&regs->imask, IMASK_DEFAULT);
+	for (i = 0; i < priv->num_grps; i++) {
+		regs = priv->gfargrp[i].regs;
+		/* Clear THLT/RHLT, so that the DMA starts polling now */
+		gfar_write(&regs->tstat, priv->gfargrp[i].tstat);
+		gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
+		/* Unmask the interrupts we look for */
+		gfar_write(&regs->imask, IMASK_DEFAULT);
+	}
 
 	dev->trans_start = jiffies;
 }
 
-/* Bring the controller up and running */
-int startup_gfar(struct net_device *dev)
+void gfar_configure_coalescing(struct gfar_private *priv,
+	unsigned long tx_mask, unsigned long rx_mask)
 {
-	struct txbd8 *txbdp;
-	struct rxbd8 *rxbdp;
-	dma_addr_t addr = 0;
-	unsigned long vaddr;
-	int i;
-	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
-	int err = 0;
-	u32 rctrl = 0;
-	u32 tctrl = 0;
-	u32 attrs = 0;
-
-	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
-
-	/* Allocate memory for the buffer descriptors */
-	vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
-			sizeof (struct txbd8) * priv->tx_ring_size +
-			sizeof (struct rxbd8) * priv->rx_ring_size,
-			&addr, GFP_KERNEL);
-
-	if (vaddr == 0) {
-		if (netif_msg_ifup(priv))
-			printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n",
-					dev->name);
-		return -ENOMEM;
-	}
-
-	priv->tx_bd_base = (struct txbd8 *) vaddr;
-
-	/* enet DMA only understands physical addresses */
-	gfar_write(&regs->tbase0, addr);
-
-	/* Start the rx descriptor ring where the tx ring leaves off */
-	addr = addr + sizeof (struct txbd8) * priv->tx_ring_size;
-	vaddr = vaddr + sizeof (struct txbd8) * priv->tx_ring_size;
-	priv->rx_bd_base = (struct rxbd8 *) vaddr;
-	gfar_write(&regs->rbase0, addr);
-
-	/* Setup the skbuff rings */
-	priv->tx_skbuff =
-	    (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
-					priv->tx_ring_size, GFP_KERNEL);
-
-	if (NULL == priv->tx_skbuff) {
-		if (netif_msg_ifup(priv))
-			printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
-					dev->name);
-		err = -ENOMEM;
-		goto tx_skb_fail;
-	}
-
-	for (i = 0; i < priv->tx_ring_size; i++)
-		priv->tx_skbuff[i] = NULL;
-
-	priv->rx_skbuff =
-	    (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
-					priv->rx_ring_size, GFP_KERNEL);
-
-	if (NULL == priv->rx_skbuff) {
-		if (netif_msg_ifup(priv))
-			printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
-					dev->name);
-		err = -ENOMEM;
-		goto rx_skb_fail;
-	}
-
-	for (i = 0; i < priv->rx_ring_size; i++)
-		priv->rx_skbuff[i] = NULL;
-
-	/* Initialize some variables in our dev structure */
-	priv->num_txbdfree = priv->tx_ring_size;
-	priv->dirty_tx = priv->cur_tx = priv->tx_bd_base;
-	priv->cur_rx = priv->rx_bd_base;
-	priv->skb_curtx = priv->skb_dirtytx = 0;
-	priv->skb_currx = 0;
-
-	/* Initialize Transmit Descriptor Ring */
-	txbdp = priv->tx_bd_base;
-	for (i = 0; i < priv->tx_ring_size; i++) {
-		txbdp->lstatus = 0;
-		txbdp->bufPtr = 0;
-		txbdp++;
-	}
-
-	/* Set the last descriptor in the ring to indicate wrap */
-	txbdp--;
-	txbdp->status |= TXBD_WRAP;
-
-	rxbdp = priv->rx_bd_base;
-	for (i = 0; i < priv->rx_ring_size; i++) {
-		struct sk_buff *skb;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+	u32 __iomem *baddr;
+	int i = 0;
 
-		skb = gfar_new_skb(dev);
+	/* Backward compatible case ---- even if we enable
+	 * multiple queues, there's only single reg to program
+	 */
+	gfar_write(&regs->txic, 0);
+	if(likely(priv->tx_queue[0]->txcoalescing))
+		gfar_write(&regs->txic, priv->tx_queue[0]->txic);
 
-		if (!skb) {
-			printk(KERN_ERR "%s: Can't allocate RX buffers\n",
-					dev->name);
+	gfar_write(&regs->rxic, 0);
+	if(unlikely(priv->rx_queue[0]->rxcoalescing))
+		gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
 
-			goto err_rxalloc_fail;
+	if (priv->mode == MQ_MG_MODE) {
+		baddr = &regs->txic0;
+		for_each_bit (i, &tx_mask, priv->num_tx_queues) {
+			if (likely(priv->tx_queue[i]->txcoalescing)) {
+				gfar_write(baddr + i, 0);
+				gfar_write(baddr + i, priv->tx_queue[i]->txic);
+			}
 		}
 
-		priv->rx_skbuff[i] = skb;
-
-		gfar_new_rxbdp(dev, rxbdp, skb);
-
-		rxbdp++;
+		baddr = &regs->rxic0;
+		for_each_bit (i, &rx_mask, priv->num_rx_queues) {
+			if (likely(priv->rx_queue[i]->rxcoalescing)) {
+				gfar_write(baddr + i, 0);
+				gfar_write(baddr + i, priv->rx_queue[i]->rxic);
+			}
+		}
 	}
+}
 
-	/* Set the last descriptor in the ring to wrap */
-	rxbdp--;
-	rxbdp->status |= RXBD_WRAP;
+static int register_grp_irqs(struct gfar_priv_grp *grp)
+{
+	struct gfar_private *priv = grp->priv;
+	struct net_device *dev = priv->ndev;
+	int err;
 
 	/* If the device has multiple interrupts, register for
 	 * them.  Otherwise, only register for the one */
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
 		/* Install our interrupt handlers for Error,
 		 * Transmit, and Receive */
-		if (request_irq(priv->interruptError, gfar_error,
-				0, priv->int_name_er, dev) < 0) {
+		if ((err = request_irq(grp->interruptError, gfar_error, 0,
+				grp->int_name_er,grp)) < 0) {
 			if (netif_msg_intr(priv))
 				printk(KERN_ERR "%s: Can't get IRQ %d\n",
-					dev->name, priv->interruptError);
+					dev->name, grp->interruptError);
 
-			err = -1;
-			goto err_irq_fail;
+				goto err_irq_fail;
 		}
 
-		if (request_irq(priv->interruptTransmit, gfar_transmit,
-				0, priv->int_name_tx, dev) < 0) {
+		if ((err = request_irq(grp->interruptTransmit, gfar_transmit,
+				0, grp->int_name_tx, grp)) < 0) {
 			if (netif_msg_intr(priv))
 				printk(KERN_ERR "%s: Can't get IRQ %d\n",
-					dev->name, priv->interruptTransmit);
-
-			err = -1;
-
+					dev->name, grp->interruptTransmit);
 			goto tx_irq_fail;
 		}
 
-		if (request_irq(priv->interruptReceive, gfar_receive,
-				0, priv->int_name_rx, dev) < 0) {
+		if ((err = request_irq(grp->interruptReceive, gfar_receive, 0,
+				grp->int_name_rx, grp)) < 0) {
 			if (netif_msg_intr(priv))
-				printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n",
-						dev->name, priv->interruptReceive);
-
-			err = -1;
+				printk(KERN_ERR "%s: Can't get IRQ %d\n",
+					dev->name, grp->interruptReceive);
 			goto rx_irq_fail;
 		}
 	} else {
-		if (request_irq(priv->interruptTransmit, gfar_interrupt,
-				0, priv->int_name_tx, dev) < 0) {
+		if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, 0,
+				grp->int_name_tx, grp)) < 0) {
 			if (netif_msg_intr(priv))
 				printk(KERN_ERR "%s: Can't get IRQ %d\n",
-					dev->name, priv->interruptTransmit);
-
-			err = -1;
+					dev->name, grp->interruptTransmit);
 			goto err_irq_fail;
 		}
 	}
 
-	phy_start(priv->phydev);
-
-	/* Configure the coalescing support */
-	gfar_write(&regs->txic, 0);
-	if (priv->txcoalescing)
-		gfar_write(&regs->txic, priv->txic);
-
-	gfar_write(&regs->rxic, 0);
-	if (priv->rxcoalescing)
-		gfar_write(&regs->rxic, priv->rxic);
-
-	if (priv->rx_csum_enable)
-		rctrl |= RCTRL_CHECKSUMMING;
+	return 0;
 
-	if (priv->extended_hash) {
-		rctrl |= RCTRL_EXTHASH;
+rx_irq_fail:
+	free_irq(grp->interruptTransmit, grp);
+tx_irq_fail:
+	free_irq(grp->interruptError, grp);
+err_irq_fail:
+	return err;
 
-		gfar_clear_exact_match(dev);
-		rctrl |= RCTRL_EMEN;
-	}
+}
 
-	if (priv->padding) {
-		rctrl &= ~RCTRL_PAL_MASK;
-		rctrl |= RCTRL_PADDING(priv->padding);
-	}
+/* Bring the controller up and running */
+int startup_gfar(struct net_device *ndev)
+{
+	struct gfar_private *priv = netdev_priv(ndev);
+	struct gfar __iomem *regs = NULL;
+	int err, i, j;
 
-	/* keep vlan related bits if it's enabled */
-	if (priv->vlgrp) {
-		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
-		tctrl |= TCTRL_VLINS;
+	for (i = 0; i < priv->num_grps; i++) {
+		regs= priv->gfargrp[i].regs;
+		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 	}
 
-	/* Init rctrl based on our settings */
-	gfar_write(&priv->regs->rctrl, rctrl);
-
-	if (dev->features & NETIF_F_IP_CSUM)
-		tctrl |= TCTRL_INIT_CSUM;
-
-	gfar_write(&priv->regs->tctrl, tctrl);
-
-	/* Set the extraction length and index */
-	attrs = ATTRELI_EL(priv->rx_stash_size) |
-		ATTRELI_EI(priv->rx_stash_index);
-
-	gfar_write(&priv->regs->attreli, attrs);
-
-	/* Start with defaults, and add stashing or locking
-	 * depending on the approprate variables */
-	attrs = ATTR_INIT_SETTINGS;
+	regs= priv->gfargrp[0].regs;
+	err = gfar_alloc_skb_resources(ndev);
+	if (err)
+		return err;
 
-	if (priv->bd_stash_en)
-		attrs |= ATTR_BDSTASH;
+	gfar_init_mac(ndev);
 
-	if (priv->rx_stash_size != 0)
-		attrs |= ATTR_BUFSTASH;
+	for (i = 0; i < priv->num_grps; i++) {
+		err = register_grp_irqs(&priv->gfargrp[i]);
+		if (err) {
+			for (j = 0; j < i; j++)
+				free_grp_irqs(&priv->gfargrp[j]);
+				goto irq_fail;
+		}
+	}
 
-	gfar_write(&priv->regs->attr, attrs);
+	/* Start the controller */
+	gfar_start(ndev);
 
-	gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
-	gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
-	gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+	phy_start(priv->phydev);
 
-	/* Start the controller */
-	gfar_start(dev);
+	gfar_configure_coalescing(priv, 0xFF, 0xFF);
 
 	return 0;
 
-rx_irq_fail:
-	free_irq(priv->interruptTransmit, dev);
-tx_irq_fail:
-	free_irq(priv->interruptError, dev);
-err_irq_fail:
-err_rxalloc_fail:
-rx_skb_fail:
+irq_fail:
 	free_skb_resources(priv);
-tx_skb_fail:
-	dma_free_coherent(&priv->ofdev->dev,
-			sizeof(struct txbd8)*priv->tx_ring_size
-			+ sizeof(struct rxbd8)*priv->rx_ring_size,
-			priv->tx_bd_base,
-			gfar_read(&regs->tbase0));
-
 	return err;
 }
 
@@ -1178,7 +1831,7 @@ static int gfar_enet_open(struct net_dev
 	struct gfar_private *priv = netdev_priv(dev);
 	int err;
 
-	napi_enable(&priv->napi);
+	enable_napi(priv);
 
 	skb_queue_head_init(&priv->rx_recycle);
 
@@ -1189,18 +1842,18 @@ static int gfar_enet_open(struct net_dev
 
 	err = init_phy(dev);
 
-	if(err) {
-		napi_disable(&priv->napi);
+	if (err) {
+		disable_napi(priv);
 		return err;
 	}
 
 	err = startup_gfar(dev);
 	if (err) {
-		napi_disable(&priv->napi);
+		disable_napi(priv);
 		return err;
 	}
 
-	netif_start_queue(dev);
+	netif_tx_start_all_queues(dev);
 
 	device_set_wakeup_enable(&dev->dev, priv->wol_en);
 
@@ -1269,15 +1922,23 @@ static inline struct txbd8 *next_txbd(st
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct netdev_queue *txq;
+	struct gfar __iomem *regs = NULL;
 	struct txfcb *fcb = NULL;
 	struct txbd8 *txbdp, *txbdp_start, *base;
 	u32 lstatus;
-	int i;
+	int i, rq = 0;
 	u32 bufaddr;
 	unsigned long flags;
 	unsigned int nr_frags, length;
 
-	base = priv->tx_bd_base;
+
+	rq = skb->queue_mapping;
+	tx_queue = priv->tx_queue[rq];
+	txq = netdev_get_tx_queue(dev, rq);
+	base = tx_queue->tx_bd_base;
+	regs = tx_queue->grp->regs;
 
 	/* make space for additional header when fcb is needed */
 	if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -1298,21 +1959,19 @@ static int gfar_start_xmit(struct sk_buf
 	/* total number of fragments in the SKB */
 	nr_frags = skb_shinfo(skb)->nr_frags;
 
-	spin_lock_irqsave(&priv->txlock, flags);
-
 	/* check if there is space to queue this packet */
-	if ((nr_frags+1) > priv->num_txbdfree) {
+	if ((nr_frags+1) > tx_queue->num_txbdfree) {
 		/* no space, stop the queue */
-		netif_stop_queue(dev);
+		netif_tx_stop_queue(txq);
 		dev->stats.tx_fifo_errors++;
-		spin_unlock_irqrestore(&priv->txlock, flags);
 		return NETDEV_TX_BUSY;
 	}
 
 	/* Update transmit stats */
-	dev->stats.tx_bytes += skb->len;
+	txq->tx_bytes += skb->len;
+	txq->tx_packets ++;
 
-	txbdp = txbdp_start = priv->cur_tx;
+	txbdp = txbdp_start = tx_queue->cur_tx;
 
 	if (nr_frags == 0) {
 		lstatus = txbdp->lstatus | BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
@@ -1320,7 +1979,7 @@ static int gfar_start_xmit(struct sk_buf
 		/* Place the fragment addresses and lengths into the TxBDs */
 		for (i = 0; i < nr_frags; i++) {
 			/* Point at the next BD, wrapping as needed */
-			txbdp = next_txbd(txbdp, base, priv->tx_ring_size);
+			txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
 
 			length = skb_shinfo(skb)->frags[i].size;
 
@@ -1362,13 +2021,27 @@ static int gfar_start_xmit(struct sk_buf
 	}
 
 	/* setup the TxBD length and buffer pointer for the first BD */
-	priv->tx_skbuff[priv->skb_curtx] = skb;
+	tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
 	txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
 			skb_headlen(skb), DMA_TO_DEVICE);
 
 	lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
 
 	/*
+	 * We can work in parallel with gfar_clean_tx_ring(), except
+	 * when modifying num_txbdfree. Note that we didn't grab the lock
+	 * when we were reading the num_txbdfree and checking for available
+	 * space, that's because outside of this function it can only grow,
+	 * and once we've got needed space, it cannot suddenly disappear.
+	 *
+	 * The lock also protects us from gfar_error(), which can modify
+	 * regs->tstat and thus retrigger the transfers, which is why we
+	 * also must grab the lock before setting ready bit for the first
+	 * to be transmitted BD.
+	 */
+	spin_lock_irqsave(&tx_queue->txlock, flags);
+
+	/*
 	 * The powerpc-specific eieio() is used, as wmb() has too strong
 	 * semantics (it requires synchronization between cacheable and
 	 * uncacheable mappings, which eieio doesn't provide and which we
@@ -1382,29 +2055,29 @@ static int gfar_start_xmit(struct sk_buf
 
 	/* Update the current skb pointer to the next entry we will use
 	 * (wrapping if necessary) */
-	priv->skb_curtx = (priv->skb_curtx + 1) &
-		TX_RING_MOD_MASK(priv->tx_ring_size);
+	tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
+		TX_RING_MOD_MASK(tx_queue->tx_ring_size);
 
-	priv->cur_tx = next_txbd(txbdp, base, priv->tx_ring_size);
+	tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size);
 
 	/* reduce TxBD free count */
-	priv->num_txbdfree -= (nr_frags + 1);
+	tx_queue->num_txbdfree -= (nr_frags + 1);
 
 	dev->trans_start = jiffies;
 
 	/* If the next BD still needs to be cleaned up, then the bds
 	   are full.  We need to tell the kernel to stop sending us stuff. */
-	if (!priv->num_txbdfree) {
-		netif_stop_queue(dev);
+	if (!tx_queue->num_txbdfree) {
+		netif_tx_stop_queue(txq);
 
 		dev->stats.tx_fifo_errors++;
 	}
 
 	/* Tell the DMA to go go go */
-	gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT);
+	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT >> tx_queue->qindex);
 
 	/* Unlock priv */
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	spin_unlock_irqrestore(&tx_queue->txlock, flags);
 
 	return NETDEV_TX_OK;
 }
@@ -1414,7 +2087,7 @@ static int gfar_close(struct net_device
 {
 	struct gfar_private *priv = netdev_priv(dev);
 
-	napi_disable(&priv->napi);
+	disable_napi(priv);
 
 	skb_queue_purge(&priv->rx_recycle);
 	cancel_work_sync(&priv->reset_task);
@@ -1424,7 +2097,7 @@ static int gfar_close(struct net_device
 	phy_disconnect(priv->phydev);
 	priv->phydev = NULL;
 
-	netif_stop_queue(dev);
+	netif_tx_stop_all_queues(dev);
 
 	return 0;
 }
@@ -1443,50 +2116,55 @@ static void gfar_vlan_rx_register(struct
 		struct vlan_group *grp)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = NULL;
 	unsigned long flags;
 	u32 tempval;
 
-	spin_lock_irqsave(&priv->rxlock, flags);
+	regs = priv->gfargrp[0].regs;
+	local_irq_save(flags);
+	lock_rx_qs(priv);
 
 	priv->vlgrp = grp;
 
 	if (grp) {
 		/* Enable VLAN tag insertion */
-		tempval = gfar_read(&priv->regs->tctrl);
+		tempval = gfar_read(&regs->tctrl);
 		tempval |= TCTRL_VLINS;
 
-		gfar_write(&priv->regs->tctrl, tempval);
+		gfar_write(&regs->tctrl, tempval);
 
 		/* Enable VLAN tag extraction */
-		tempval = gfar_read(&priv->regs->rctrl);
+		tempval = gfar_read(&regs->rctrl);
 		tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
-		gfar_write(&priv->regs->rctrl, tempval);
+		gfar_write(&regs->rctrl, tempval);
 	} else {
 		/* Disable VLAN tag insertion */
-		tempval = gfar_read(&priv->regs->tctrl);
+		tempval = gfar_read(&regs->tctrl);
 		tempval &= ~TCTRL_VLINS;
-		gfar_write(&priv->regs->tctrl, tempval);
+		gfar_write(&regs->tctrl, tempval);
 
 		/* Disable VLAN tag extraction */
-		tempval = gfar_read(&priv->regs->rctrl);
+		tempval = gfar_read(&regs->rctrl);
 		tempval &= ~RCTRL_VLEX;
 		/* If parse is no longer required, then disable parser */
 		if (tempval & RCTRL_REQ_PARSER)
 			tempval |= RCTRL_PRSDEP_INIT;
 		else
 			tempval &= ~RCTRL_PRSDEP_INIT;
-		gfar_write(&priv->regs->rctrl, tempval);
+		gfar_write(&regs->rctrl, tempval);
 	}
 
 	gfar_change_mtu(dev, dev->mtu);
 
-	spin_unlock_irqrestore(&priv->rxlock, flags);
+	unlock_rx_qs(priv);
+	local_irq_restore(flags);
 }
 
 static int gfar_change_mtu(struct net_device *dev, int new_mtu)
 {
 	int tempsize, tempval;
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	int oldsize = priv->rx_buffer_size;
 	int frame_size = new_mtu + ETH_HLEN;
 
@@ -1518,20 +2196,20 @@ static int gfar_change_mtu(struct net_de
 
 	dev->mtu = new_mtu;
 
-	gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
-	gfar_write(&priv->regs->maxfrm, priv->rx_buffer_size);
+	gfar_write(&regs->mrblr, priv->rx_buffer_size);
+	gfar_write(&regs->maxfrm, priv->rx_buffer_size);
 
 	/* If the mtu is larger than the max size for standard
 	 * ethernet frames (ie, a jumbo frame), then set maccfg2
 	 * to allow huge frames, and to check the length */
-	tempval = gfar_read(&priv->regs->maccfg2);
+	tempval = gfar_read(&regs->maccfg2);
 
 	if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE)
 		tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
 	else
 		tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
 
-	gfar_write(&priv->regs->maccfg2, tempval);
+	gfar_write(&regs->maccfg2, tempval);
 
 	if ((oldsize != tempsize) && (dev->flags & IFF_UP))
 		startup_gfar(dev);
@@ -1551,10 +2229,10 @@ static void gfar_reset_task(struct work_
 	struct net_device *dev = priv->ndev;
 
 	if (dev->flags & IFF_UP) {
-		netif_stop_queue(dev);
+		netif_tx_stop_all_queues(dev);
 		stop_gfar(dev);
 		startup_gfar(dev);
-		netif_start_queue(dev);
+		netif_tx_start_all_queues(dev);
 	}
 
 	netif_tx_schedule_all(dev);
@@ -1569,24 +2247,29 @@ static void gfar_timeout(struct net_devi
 }
 
 /* Interrupt Handler for Transmit complete */
-static int gfar_clean_tx_ring(struct net_device *dev)
+static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 {
+	struct net_device *dev = tx_queue->dev;
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_rx_q *rx_queue = NULL;
 	struct txbd8 *bdp;
 	struct txbd8 *lbdp = NULL;
-	struct txbd8 *base = priv->tx_bd_base;
+	struct txbd8 *base = tx_queue->tx_bd_base;
 	struct sk_buff *skb;
 	int skb_dirtytx;
-	int tx_ring_size = priv->tx_ring_size;
+	int tx_ring_size = tx_queue->tx_ring_size;
 	int frags = 0;
 	int i;
 	int howmany = 0;
 	u32 lstatus;
 
-	bdp = priv->dirty_tx;
-	skb_dirtytx = priv->skb_dirtytx;
+	rx_queue = priv->rx_queue[tx_queue->qindex];
+	bdp = tx_queue->dirty_tx;
+	skb_dirtytx = tx_queue->skb_dirtytx;
+
+	while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
+		unsigned long flags;
 
-	while ((skb = priv->tx_skbuff[skb_dirtytx])) {
 		frags = skb_shinfo(skb)->nr_frags;
 		lbdp = skip_txbd(bdp, frags, base, tx_ring_size);
 
@@ -1618,82 +2301,71 @@ static int gfar_clean_tx_ring(struct net
 		 * If there's room in the queue (limit it to rx_buffer_size)
 		 * we add this skb back into the pool, if it's the right size
 		 */
-		if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size &&
+		if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
 				skb_recycle_check(skb, priv->rx_buffer_size +
 					RXBUF_ALIGNMENT))
 			__skb_queue_head(&priv->rx_recycle, skb);
 		else
 			dev_kfree_skb_any(skb);
 
-		priv->tx_skbuff[skb_dirtytx] = NULL;
+		tx_queue->tx_skbuff[skb_dirtytx] = NULL;
 
 		skb_dirtytx = (skb_dirtytx + 1) &
 			TX_RING_MOD_MASK(tx_ring_size);
 
 		howmany++;
-		priv->num_txbdfree += frags + 1;
+		spin_lock_irqsave(&tx_queue->txlock, flags);
+		tx_queue->num_txbdfree += frags + 1;
+		spin_unlock_irqrestore(&tx_queue->txlock, flags);
 	}
 
 	/* If we freed a buffer, we can restart transmission, if necessary */
-	if (netif_queue_stopped(dev) && priv->num_txbdfree)
-		netif_wake_queue(dev);
+	if (__netif_subqueue_stopped(dev, tx_queue->qindex) && tx_queue->num_txbdfree)
+		netif_wake_subqueue(dev, tx_queue->qindex);
 
 	/* Update dirty indicators */
-	priv->skb_dirtytx = skb_dirtytx;
-	priv->dirty_tx = bdp;
-
-	dev->stats.tx_packets += howmany;
+	tx_queue->skb_dirtytx = skb_dirtytx;
+	tx_queue->dirty_tx = bdp;
 
 	return howmany;
 }
 
-static void gfar_schedule_cleanup(struct net_device *dev)
+static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp)
 {
-	struct gfar_private *priv = netdev_priv(dev);
 	unsigned long flags;
 
-	spin_lock_irqsave(&priv->txlock, flags);
-	spin_lock(&priv->rxlock);
-
-	if (napi_schedule_prep(&priv->napi)) {
-		gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
-		__napi_schedule(&priv->napi);
+	spin_lock_irqsave(&gfargrp->grplock, flags);
+	if (napi_schedule_prep(&gfargrp->napi)) {
+		gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED);
+		__napi_schedule(&gfargrp->napi);
 	} else {
 		/*
 		 * Clear IEVENT, so interrupts aren't called again
 		 * because of the packets that have already arrived.
 		 */
-		gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
+		gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK);
 	}
+	spin_unlock_irqrestore(&gfargrp->grplock, flags);
 
-	spin_unlock(&priv->rxlock);
-	spin_unlock_irqrestore(&priv->txlock, flags);
 }
 
 /* Interrupt Handler for Transmit complete */
-static irqreturn_t gfar_transmit(int irq, void *dev_id)
+static irqreturn_t gfar_transmit(int irq, void *grp_id)
 {
-	gfar_schedule_cleanup((struct net_device *)dev_id);
+	gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
 	return IRQ_HANDLED;
 }
 
-static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
+static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
 		struct sk_buff *skb)
 {
+	struct net_device *dev = rx_queue->dev;
 	struct gfar_private *priv = netdev_priv(dev);
-	u32 lstatus;
-
-	bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
-			priv->rx_buffer_size, DMA_FROM_DEVICE);
-
-	lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
-
-	if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
-		lstatus |= BD_LFLAG(RXBD_WRAP);
-
-	eieio();
+	dma_addr_t buf;
 
-	bdp->lstatus = lstatus;
+	buf = dma_map_single(&priv->ofdev->dev, skb->data,
+			     priv->rx_buffer_size, DMA_FROM_DEVICE);
+	gfar_init_rxbdp(rx_queue, bdp, buf);
 }
 
 
@@ -1760,9 +2432,9 @@ static inline void count_errors(unsigned
 	}
 }
 
-irqreturn_t gfar_receive(int irq, void *dev_id)
+irqreturn_t gfar_receive(int irq, void *grp_id)
 {
-	gfar_schedule_cleanup((struct net_device *)dev_id);
+	gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
 	return IRQ_HANDLED;
 }
 
@@ -1793,8 +2465,10 @@ static int gfar_process_frame(struct net
 
 	/* Remove the FCB from the skb */
 	/* Remove the padded bytes, if there are any */
-	if (amount_pull)
+	if (amount_pull) {
+		skb_record_rx_queue(skb, fcb->rq);
 		skb_pull(skb, amount_pull);
+	}
 
 	if (priv->rx_csum_enable)
 		gfar_rx_checksum(skb, fcb);
@@ -1818,8 +2492,9 @@ static int gfar_process_frame(struct net
  *   until the budget/quota has been reached. Returns the number
  *   of frames handled
  */
-int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
+int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
 {
+	struct net_device *dev = rx_queue->dev;
 	struct rxbd8 *bdp, *base;
 	struct sk_buff *skb;
 	int pkt_len;
@@ -1828,8 +2503,8 @@ int gfar_clean_rx_ring(struct net_device
 	struct gfar_private *priv = netdev_priv(dev);
 
 	/* Get the first full descriptor */
-	bdp = priv->cur_rx;
-	base = priv->rx_bd_base;
+	bdp = rx_queue->cur_rx;
+	base = rx_queue->rx_bd_base;
 
 	amount_pull = (gfar_uses_fcb(priv) ? GMAC_FCB_LEN : 0) +
 		priv->padding;
@@ -1841,7 +2516,7 @@ int gfar_clean_rx_ring(struct net_device
 		/* Add another skb for the future */
 		newskb = gfar_new_skb(dev);
 
-		skb = priv->rx_skbuff[priv->skb_currx];
+		skb = rx_queue->rx_skbuff[rx_queue->skb_currx];
 
 		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
 				priv->rx_buffer_size, DMA_FROM_DEVICE);
@@ -1866,68 +2541,90 @@ int gfar_clean_rx_ring(struct net_device
 			}
 		} else {
 			/* Increment the number of packets */
-			dev->stats.rx_packets++;
+			rx_queue->stats.rx_packets++;
 			howmany++;
 
 			if (likely(skb)) {
 				pkt_len = bdp->length - ETH_FCS_LEN;
 				/* Remove the FCS from the packet length */
 				skb_put(skb, pkt_len);
-				dev->stats.rx_bytes += pkt_len;
-
-				if (in_irq() || irqs_disabled())
-					printk("Interrupt problem!\n");
+				rx_queue->stats.rx_bytes += pkt_len;
+				skb_record_rx_queue(skb, rx_queue->qindex);
 				gfar_process_frame(dev, skb, amount_pull);
 
 			} else {
 				if (netif_msg_rx_err(priv))
 					printk(KERN_WARNING
 					       "%s: Missing skb!\n", dev->name);
-				dev->stats.rx_dropped++;
+				rx_queue->stats.rx_dropped++;
 				priv->extra_stats.rx_skbmissing++;
 			}
 
 		}
 
-		priv->rx_skbuff[priv->skb_currx] = newskb;
+		rx_queue->rx_skbuff[rx_queue->skb_currx] = newskb;
 
 		/* Setup the new bdp */
-		gfar_new_rxbdp(dev, bdp, newskb);
+		gfar_new_rxbdp(rx_queue, bdp, newskb);
 
 		/* Update to the next pointer */
-		bdp = next_bd(bdp, base, priv->rx_ring_size);
+		bdp = next_bd(bdp, base, rx_queue->rx_ring_size);
 
 		/* update to point at the next skb */
-		priv->skb_currx =
-		    (priv->skb_currx + 1) &
-		    RX_RING_MOD_MASK(priv->rx_ring_size);
+		rx_queue->skb_currx =
+		    (rx_queue->skb_currx + 1) &
+		    RX_RING_MOD_MASK(rx_queue->rx_ring_size);
 	}
 
 	/* Update the current rxbd pointer to be the next one */
-	priv->cur_rx = bdp;
+	rx_queue->cur_rx = bdp;
 
 	return howmany;
 }
 
 static int gfar_poll(struct napi_struct *napi, int budget)
 {
-	struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
-	struct net_device *dev = priv->ndev;
-	int tx_cleaned = 0;
-	int rx_cleaned = 0;
-	unsigned long flags;
+	struct gfar_priv_grp *gfargrp = container_of(napi,
+			struct gfar_priv_grp, napi);
+	struct gfar_private *priv = gfargrp->priv;
+	struct gfar __iomem *regs = gfargrp->regs;
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+	int rx_cleaned = 0, budget_per_queue = 0, rx_cleaned_per_queue = 0;
+	int tx_cleaned = 0, i, left_over_budget = budget;
+	unsigned long serviced_queues = 0;
+	int num_queues = 0;
+
+	num_queues = gfargrp->num_rx_queues;
+	budget_per_queue = budget/num_queues;
 
 	/* Clear IEVENT, so interrupts aren't called again
 	 * because of the packets that have already arrived */
-	gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
+	gfar_write(&regs->ievent, IEVENT_RTX_MASK);
 
-	/* If we fail to get the lock, don't bother with the TX BDs */
-	if (spin_trylock_irqsave(&priv->txlock, flags)) {
-		tx_cleaned = gfar_clean_tx_ring(dev);
-		spin_unlock_irqrestore(&priv->txlock, flags);
-	}
+	while (num_queues && left_over_budget) {
 
-	rx_cleaned = gfar_clean_rx_ring(dev, budget);
+		budget_per_queue = left_over_budget/num_queues;
+		left_over_budget = 0;
+
+		for_each_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
+			if (test_bit(i, &serviced_queues))
+				continue;
+			rx_queue = priv->rx_queue[i];
+			tx_queue = priv->tx_queue[rx_queue->qindex];
+
+			tx_cleaned += gfar_clean_tx_ring(tx_queue);
+			rx_cleaned_per_queue = gfar_clean_rx_ring(rx_queue,
+							budget_per_queue);
+			rx_cleaned += rx_cleaned_per_queue;
+			if(rx_cleaned_per_queue < budget_per_queue) {
+				left_over_budget = left_over_budget +
+					(budget_per_queue - rx_cleaned_per_queue);
+				set_bit(i, &serviced_queues);
+				num_queues--;
+			}
+		}
+	}
 
 	if (tx_cleaned)
 		return budget;
@@ -1936,20 +2633,14 @@ static int gfar_poll(struct napi_struct
 		napi_complete(napi);
 
 		/* Clear the halt bit in RSTAT */
-		gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
+		gfar_write(&regs->rstat, gfargrp->rstat);
 
-		gfar_write(&priv->regs->imask, IMASK_DEFAULT);
+		gfar_write(&regs->imask, IMASK_DEFAULT);
 
 		/* If we are coalescing interrupts, update the timer */
 		/* Otherwise, clear it */
-		if (likely(priv->rxcoalescing)) {
-			gfar_write(&priv->regs->rxic, 0);
-			gfar_write(&priv->regs->rxic, priv->rxic);
-		}
-		if (likely(priv->txcoalescing)) {
-			gfar_write(&priv->regs->txic, 0);
-			gfar_write(&priv->regs->txic, priv->txic);
-		}
+		gfar_configure_coalescing(priv,
+				gfargrp->rx_bit_map, gfargrp->tx_bit_map);
 	}
 
 	return rx_cleaned;
@@ -1964,44 +2655,50 @@ static int gfar_poll(struct napi_struct
 static void gfar_netpoll(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	int i = 0;
 
 	/* If the device has multiple interrupts, run tx/rx */
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-		disable_irq(priv->interruptTransmit);
-		disable_irq(priv->interruptReceive);
-		disable_irq(priv->interruptError);
-		gfar_interrupt(priv->interruptTransmit, dev);
-		enable_irq(priv->interruptError);
-		enable_irq(priv->interruptReceive);
-		enable_irq(priv->interruptTransmit);
+		for (i = 0; i < priv->num_grps; i++) {
+			disable_irq(priv->gfargrp[i].interruptTransmit);
+			disable_irq(priv->gfargrp[i].interruptReceive);
+			disable_irq(priv->gfargrp[i].interruptError);
+			gfar_interrupt(priv->gfargrp[i].interruptTransmit,
+						&priv->gfargrp[i]);
+			enable_irq(priv->gfargrp[i].interruptError);
+			enable_irq(priv->gfargrp[i].interruptReceive);
+			enable_irq(priv->gfargrp[i].interruptTransmit);
+		}
 	} else {
-		disable_irq(priv->interruptTransmit);
-		gfar_interrupt(priv->interruptTransmit, dev);
-		enable_irq(priv->interruptTransmit);
+		for (i = 0; i < priv->num_grps; i++) {
+			disable_irq(priv->gfargrp[i].interruptTransmit);
+			gfar_interrupt(priv->gfargrp[i].interruptTransmit,
+						&priv->gfargrp[i]);
+			enable_irq(priv->gfargrp[i].interruptTransmit);
+		}
 	}
 }
 #endif
 
 /* The interrupt handler for devices with one interrupt */
-static irqreturn_t gfar_interrupt(int irq, void *dev_id)
+static irqreturn_t gfar_interrupt(int irq, void *grp_id)
 {
-	struct net_device *dev = dev_id;
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_grp *gfargrp = grp_id;
 
 	/* Save ievent for future reference */
-	u32 events = gfar_read(&priv->regs->ievent);
+	u32 events = gfar_read(&gfargrp->regs->ievent);
 
 	/* Check for reception */
 	if (events & IEVENT_RX_MASK)
-		gfar_receive(irq, dev_id);
+		gfar_receive(irq, grp_id);
 
 	/* Check for transmit completion */
 	if (events & IEVENT_TX_MASK)
-		gfar_transmit(irq, dev_id);
+		gfar_transmit(irq, grp_id);
 
 	/* Check for errors */
 	if (events & IEVENT_ERR_MASK)
-		gfar_error(irq, dev_id);
+		gfar_error(irq, grp_id);
 
 	return IRQ_HANDLED;
 }
@@ -2015,12 +2712,14 @@ static irqreturn_t gfar_interrupt(int ir
 static void adjust_link(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned long flags;
 	struct phy_device *phydev = priv->phydev;
 	int new_state = 0;
 
-	spin_lock_irqsave(&priv->txlock, flags);
+	local_irq_save(flags);
+	lock_tx_qs(priv);
+
 	if (phydev->link) {
 		u32 tempval = gfar_read(&regs->maccfg2);
 		u32 ecntrl = gfar_read(&regs->ecntrl);
@@ -2085,8 +2784,8 @@ static void adjust_link(struct net_devic
 
 	if (new_state && netif_msg_link(priv))
 		phy_print_status(phydev);
-
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 }
 
 /* Update the hash table based on the current list of multicast
@@ -2097,10 +2796,10 @@ static void gfar_set_multi(struct net_de
 {
 	struct dev_mc_list *mc_ptr;
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar __iomem *regs = priv->regs;
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	u32 tempval;
 
-	if(dev->flags & IFF_PROMISC) {
+	if (dev->flags & IFF_PROMISC) {
 		/* Set RCTRL to PROM */
 		tempval = gfar_read(&regs->rctrl);
 		tempval |= RCTRL_PROM;
@@ -2112,7 +2811,7 @@ static void gfar_set_multi(struct net_de
 		gfar_write(&regs->rctrl, tempval);
 	}
 
-	if(dev->flags & IFF_ALLMULTI) {
+	if (dev->flags & IFF_ALLMULTI) {
 		/* Set the hash to rx all multicast frames */
 		gfar_write(&regs->igaddr0, 0xffffffff);
 		gfar_write(&regs->igaddr1, 0xffffffff);
@@ -2164,7 +2863,7 @@ static void gfar_set_multi(struct net_de
 			em_num = 0;
 		}
 
-		if(dev->mc_count == 0)
+		if (dev->mc_count == 0)
 			return;
 
 		/* Parse the list, and set the appropriate bits */
@@ -2230,10 +2929,11 @@ static void gfar_set_hash_for_addr(struc
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	int idx;
 	char tmpbuf[MAC_ADDR_LEN];
 	u32 tempval;
-	u32 __iomem *macptr = &priv->regs->macstnaddr1;
+	u32 __iomem *macptr = &regs->macstnaddr1;
 
 	macptr += num*2;
 
@@ -2250,16 +2950,18 @@ static void gfar_set_mac_for_addr(struct
 }
 
 /* GFAR error interrupt handler */
-static irqreturn_t gfar_error(int irq, void *dev_id)
+static irqreturn_t gfar_error(int irq, void *grp_id)
 {
-	struct net_device *dev = dev_id;
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_grp *gfargrp = grp_id;
+	struct gfar __iomem *regs = gfargrp->regs;
+	struct gfar_private *priv= gfargrp->priv;
+	struct net_device *dev = priv->ndev;
 
 	/* Save ievent for future reference */
-	u32 events = gfar_read(&priv->regs->ievent);
+	u32 events = gfar_read(&regs->ievent);
 
 	/* Clear IEVENT */
-	gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK);
+	gfar_write(&regs->ievent, events & IEVENT_ERR_MASK);
 
 	/* Magic Packet is not an error. */
 	if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
@@ -2269,7 +2971,7 @@ static irqreturn_t gfar_error(int irq, v
 	/* Hmm... */
 	if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
 		printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n",
-		       dev->name, events, gfar_read(&priv->regs->imask));
+		       dev->name, events, gfar_read(&regs->imask));
 
 	/* Update the error counters */
 	if (events & IEVENT_TXE) {
@@ -2280,14 +2982,22 @@ static irqreturn_t gfar_error(int irq, v
 		if (events & IEVENT_CRL)
 			dev->stats.tx_aborted_errors++;
 		if (events & IEVENT_XFUN) {
+			unsigned long flags;
+
 			if (netif_msg_tx_err(priv))
 				printk(KERN_DEBUG "%s: TX FIFO underrun, "
 				       "packet dropped.\n", dev->name);
 			dev->stats.tx_dropped++;
 			priv->extra_stats.tx_underrun++;
 
+			local_irq_save(flags);
+			lock_tx_qs(priv);
+
 			/* Reactivate the Tx Queues */
-			gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT);
+			gfar_write(&regs->tstat, gfargrp->tstat);
+
+			unlock_tx_qs(priv);
+			local_irq_restore(flags);
 		}
 		if (netif_msg_tx_err(priv))
 			printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);
@@ -2296,11 +3006,11 @@ static irqreturn_t gfar_error(int irq, v
 		dev->stats.rx_errors++;
 		priv->extra_stats.rx_bsy++;
 
-		gfar_receive(irq, dev_id);
+		gfar_receive(irq, grp_id);
 
 		if (netif_msg_rx_err(priv))
 			printk(KERN_DEBUG "%s: busy error (rstat: %x)\n",
-			       dev->name, gfar_read(&priv->regs->rstat));
+			       dev->name, gfar_read(&regs->rstat));
 	}
 	if (events & IEVENT_BABR) {
 		dev->stats.rx_errors++;
@@ -2331,6 +3041,9 @@ static struct of_device_id gfar_match[]
 		.type = "network",
 		.compatible = "gianfar",
 	},
+	{
+		.compatible = "fsl,etsec2",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, gfar_match);
@@ -2342,8 +3055,9 @@ static struct of_platform_driver gfar_dr
 
 	.probe = gfar_probe,
 	.remove = gfar_remove,
-	.suspend = gfar_suspend,
-	.resume = gfar_resume,
+	.suspend = gfar_legacy_suspend,
+	.resume = gfar_legacy_resume,
+	.driver.pm = GFAR_PM_OPS,
 };
 
 static int __init gfar_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/gianfar_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/gianfar_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/gianfar_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/gianfar_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,8 +7,9 @@
  *
  *  Author: Andy Fleming
  *  Maintainer: Kumar Gala
+ *  Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- *  Copyright (c) 2003,2004 Freescale Semiconductor, Inc.
+ *  Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc.
  *
  *  This software may be used and distributed according to
  *  the terms of the GNU Public License, Version 2, incorporated herein
@@ -41,7 +42,7 @@
 #include "gianfar.h"
 
 extern void gfar_start(struct net_device *dev);
-extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
 
 #define GFAR_MAX_COAL_USECS 0xffff
 #define GFAR_MAX_COAL_FRAMES 0xff
@@ -136,10 +137,11 @@ static void gfar_fill_stats(struct net_d
 {
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	u64 *extra = (u64 *) & priv->extra_stats;
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-		u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon;
+		u32 __iomem *rmon = (u32 __iomem *) &regs->rmon;
 		struct gfar_stats *stats = (struct gfar_stats *) buf;
 
 		for (i = 0; i < GFAR_RMON_LEN; i++)
@@ -197,12 +199,18 @@ static int gfar_gsettings(struct net_dev
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	struct phy_device *phydev = priv->phydev;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+	struct gfar_priv_tx_q *tx_queue = NULL;
 
 	if (NULL == phydev)
 		return -ENODEV;
+	tx_queue = priv->tx_queue[0];
+	rx_queue = priv->rx_queue[0];
 
-	cmd->maxtxpkt = get_icft_value(priv->txic);
-	cmd->maxrxpkt = get_icft_value(priv->rxic);
+	/* etsec-1.7 and older versions have only one txic
+	 * and rxic regs although they support multiple queues */
+	cmd->maxtxpkt = get_icft_value(tx_queue->txic);
+	cmd->maxrxpkt = get_icft_value(rx_queue->rxic);
 
 	return phy_ethtool_gset(phydev, cmd);
 }
@@ -218,7 +226,7 @@ static void gfar_get_regs(struct net_dev
 {
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
-	u32 __iomem *theregs = (u32 __iomem *) priv->regs;
+	u32 __iomem *theregs = (u32 __iomem *) priv->gfargrp[0].regs;
 	u32 *buf = (u32 *) regbuf;
 
 	for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
@@ -279,6 +287,8 @@ static unsigned int gfar_ticks2usecs(str
 static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_rx_q *rx_queue = NULL;
+	struct gfar_priv_tx_q *tx_queue = NULL;
 	unsigned long rxtime;
 	unsigned long rxcount;
 	unsigned long txtime;
@@ -290,10 +300,13 @@ static int gfar_gcoalesce(struct net_dev
 	if (NULL == priv->phydev)
 		return -ENODEV;
 
-	rxtime  = get_ictt_value(priv->rxic);
-	rxcount = get_icft_value(priv->rxic);
-	txtime  = get_ictt_value(priv->txic);
-	txcount = get_icft_value(priv->txic);
+	rx_queue = priv->rx_queue[0];
+	tx_queue = priv->tx_queue[0];
+
+	rxtime  = get_ictt_value(rx_queue->rxic);
+	rxcount = get_icft_value(rx_queue->rxic);
+	txtime  = get_ictt_value(tx_queue->txic);
+	txcount = get_icft_value(tx_queue->txic);
 	cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
 	cvals->rx_max_coalesced_frames = rxcount;
 
@@ -339,16 +352,23 @@ static int gfar_gcoalesce(struct net_dev
 static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	int i = 0;
 
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
 		return -EOPNOTSUPP;
 
 	/* Set up rx coalescing */
+	/* As of now, we will enable/disable coalescing for all
+	 * queues together in case of eTSEC2, this will be modified
+	 * along with the ethtool interface */
 	if ((cvals->rx_coalesce_usecs == 0) ||
-	    (cvals->rx_max_coalesced_frames == 0))
-		priv->rxcoalescing = 0;
-	else
-		priv->rxcoalescing = 1;
+	    (cvals->rx_max_coalesced_frames == 0)) {
+		for (i = 0; i < priv->num_rx_queues; i++)
+			priv->rx_queue[i]->rxcoalescing = 0;
+	} else {
+		for (i = 0; i < priv->num_rx_queues; i++)
+			priv->rx_queue[i]->rxcoalescing = 1;
+	}
 
 	if (NULL == priv->phydev)
 		return -ENODEV;
@@ -366,15 +386,21 @@ static int gfar_scoalesce(struct net_dev
 		return -EINVAL;
 	}
 
-	priv->rxic = mk_ic_value(cvals->rx_max_coalesced_frames,
-		gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		priv->rx_queue[i]->rxic = mk_ic_value(
+			cvals->rx_max_coalesced_frames,
+			gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
+	}
 
 	/* Set up tx coalescing */
 	if ((cvals->tx_coalesce_usecs == 0) ||
-	    (cvals->tx_max_coalesced_frames == 0))
-		priv->txcoalescing = 0;
-	else
-		priv->txcoalescing = 1;
+	    (cvals->tx_max_coalesced_frames == 0)) {
+		for (i = 0; i < priv->num_tx_queues; i++)
+			priv->tx_queue[i]->txcoalescing = 0;
+	} else {
+		for (i = 0; i < priv->num_tx_queues; i++)
+			priv->tx_queue[i]->txcoalescing = 1;
+	}
 
 	/* Check the bounds of the values */
 	if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
@@ -389,16 +415,13 @@ static int gfar_scoalesce(struct net_dev
 		return -EINVAL;
 	}
 
-	priv->txic = mk_ic_value(cvals->tx_max_coalesced_frames,
-		gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
-
-	gfar_write(&priv->regs->rxic, 0);
-	if (priv->rxcoalescing)
-		gfar_write(&priv->regs->rxic, priv->rxic);
+	for (i = 0; i < priv->num_tx_queues; i++) {
+		priv->tx_queue[i]->txic = mk_ic_value(
+			cvals->tx_max_coalesced_frames,
+			gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
+	}
 
-	gfar_write(&priv->regs->txic, 0);
-	if (priv->txcoalescing)
-		gfar_write(&priv->regs->txic, priv->txic);
+	gfar_configure_coalescing(priv, 0xFF, 0xFF);
 
 	return 0;
 }
@@ -409,6 +432,11 @@ static int gfar_scoalesce(struct net_dev
 static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_priv_tx_q *tx_queue = NULL;
+	struct gfar_priv_rx_q *rx_queue = NULL;
+
+	tx_queue = priv->tx_queue[0];
+	rx_queue = priv->rx_queue[0];
 
 	rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE;
 	rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE;
@@ -418,10 +446,10 @@ static void gfar_gringparam(struct net_d
 	/* Values changeable by the user.  The valid values are
 	 * in the range 1 to the "*_max_pending" counterpart above.
 	 */
-	rvals->rx_pending = priv->rx_ring_size;
-	rvals->rx_mini_pending = priv->rx_ring_size;
-	rvals->rx_jumbo_pending = priv->rx_ring_size;
-	rvals->tx_pending = priv->tx_ring_size;
+	rvals->rx_pending = rx_queue->rx_ring_size;
+	rvals->rx_mini_pending = rx_queue->rx_ring_size;
+	rvals->rx_jumbo_pending = rx_queue->rx_ring_size;
+	rvals->tx_pending = tx_queue->tx_ring_size;
 }
 
 /* Change the current ring parameters, stopping the controller if
@@ -431,7 +459,7 @@ static void gfar_gringparam(struct net_d
 static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	int err = 0;
+	int err = 0, i = 0;
 
 	if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
 		return -EINVAL;
@@ -451,34 +479,41 @@ static int gfar_sringparam(struct net_de
 		return -EINVAL;
 	}
 
+
 	if (dev->flags & IFF_UP) {
 		unsigned long flags;
 
 		/* Halt TX and RX, and process the frames which
 		 * have already been received */
-		spin_lock_irqsave(&priv->txlock, flags);
-		spin_lock(&priv->rxlock);
+		local_irq_save(flags);
+		lock_tx_qs(priv);
+		lock_rx_qs(priv);
 
 		gfar_halt(dev);
 
-		spin_unlock(&priv->rxlock);
-		spin_unlock_irqrestore(&priv->txlock, flags);
+		unlock_rx_qs(priv);
+		unlock_tx_qs(priv);
+		local_irq_restore(flags);
 
-		gfar_clean_rx_ring(dev, priv->rx_ring_size);
+		for (i = 0; i < priv->num_rx_queues; i++)
+			gfar_clean_rx_ring(priv->rx_queue[i],
+					priv->rx_queue[i]->rx_ring_size);
 
 		/* Now we take down the rings to rebuild them */
 		stop_gfar(dev);
 	}
 
 	/* Change the size */
-	priv->rx_ring_size = rvals->rx_pending;
-	priv->tx_ring_size = rvals->tx_pending;
-	priv->num_txbdfree = priv->tx_ring_size;
+	for (i = 0; i < priv->num_rx_queues; i++) {
+		priv->rx_queue[i]->rx_ring_size = rvals->rx_pending;
+		priv->tx_queue[i]->tx_ring_size = rvals->tx_pending;
+		priv->tx_queue[i]->num_txbdfree = priv->tx_queue[i]->tx_ring_size;
+	}
 
 	/* Rebuild the rings with the new size */
 	if (dev->flags & IFF_UP) {
 		err = startup_gfar(dev);
-		netif_wake_queue(dev);
+		netif_tx_wake_all_queues(dev);
 	}
 	return err;
 }
@@ -487,23 +522,28 @@ static int gfar_set_rx_csum(struct net_d
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	unsigned long flags;
-	int err = 0;
+	int err = 0, i = 0;
 
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
 		return -EOPNOTSUPP;
 
+
 	if (dev->flags & IFF_UP) {
 		/* Halt TX and RX, and process the frames which
 		 * have already been received */
-		spin_lock_irqsave(&priv->txlock, flags);
-		spin_lock(&priv->rxlock);
+		local_irq_save(flags);
+		lock_tx_qs(priv);
+		lock_rx_qs(priv);
 
 		gfar_halt(dev);
 
-		spin_unlock(&priv->rxlock);
-		spin_unlock_irqrestore(&priv->txlock, flags);
+		unlock_tx_qs(priv);
+		unlock_rx_qs(priv);
+		local_irq_save(flags);
 
-		gfar_clean_rx_ring(dev, priv->rx_ring_size);
+		for (i = 0; i < priv->num_rx_queues; i++)
+			gfar_clean_rx_ring(priv->rx_queue[i],
+					priv->rx_queue[i]->rx_ring_size);
 
 		/* Now we take down the rings to rebuild them */
 		stop_gfar(dev);
@@ -515,7 +555,7 @@ static int gfar_set_rx_csum(struct net_d
 
 	if (dev->flags & IFF_UP) {
 		err = startup_gfar(dev);
-		netif_wake_queue(dev);
+		netif_tx_wake_all_queues(dev);
 	}
 	return err;
 }
@@ -605,6 +645,241 @@ static int gfar_set_wol(struct net_devic
 }
 #endif
 
+static int gfar_ethflow_to_class(int flow_type, u64 *class)
+{
+	switch (flow_type) {
+	case TCP_V4_FLOW:
+		*class = CLASS_CODE_TCP_IPV4;
+		break;
+	case UDP_V4_FLOW:
+		*class = CLASS_CODE_UDP_IPV4;
+		break;
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+		*class = CLASS_CODE_AH_ESP_IPV4;
+		break;
+	case SCTP_V4_FLOW:
+		*class = CLASS_CODE_SCTP_IPV4;
+		break;
+	case TCP_V6_FLOW:
+		*class = CLASS_CODE_TCP_IPV6;
+		break;
+	case UDP_V6_FLOW:
+		*class = CLASS_CODE_UDP_IPV6;
+		break;
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+		*class = CLASS_CODE_AH_ESP_IPV6;
+		break;
+	case SCTP_V6_FLOW:
+		*class = CLASS_CODE_SCTP_IPV6;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
+{
+	u32 fcr = 0x0, fpr = FPR_FILER_MASK;
+
+	if (ethflow & RXH_L2DA) {
+		fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
+			RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+
+		fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
+				RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & RXH_VLAN) {
+		fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+				RQFCR_AND | RQFCR_HASHTBL_0;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & RXH_IP_SRC) {
+		fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+			RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & (RXH_IP_DST)) {
+		fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+			RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & RXH_L3_PROTO) {
+		fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+			RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & RXH_L4_B_0_1) {
+		fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+			RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	if (ethflow & RXH_L4_B_2_3) {
+		fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
+			RQFCR_AND | RQFCR_HASHTBL_0;
+		ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+}
+
+static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class)
+{
+	unsigned int last_rule_idx = priv->cur_filer_idx;
+	unsigned int cmp_rqfpr;
+	unsigned int local_rqfpr[MAX_FILER_IDX + 1];
+	unsigned int local_rqfcr[MAX_FILER_IDX + 1];
+	int i = 0x0, k = 0x0;
+	int j = MAX_FILER_IDX, l = 0x0;
+
+	switch (class) {
+	case TCP_V4_FLOW:
+		cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP;
+		break;
+	case UDP_V4_FLOW:
+		cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP;
+		break;
+	case TCP_V6_FLOW:
+		cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP;
+		break;
+	case UDP_V6_FLOW:
+		cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP;
+		break;
+	case IPV4_FLOW:
+		cmp_rqfpr = RQFPR_IPV4;
+	case IPV6_FLOW:
+		cmp_rqfpr = RQFPR_IPV6;
+		break;
+	default:
+		printk(KERN_ERR "Right now this class is not supported\n");
+		return 0;
+	}
+
+	for (i = 0; i < MAX_FILER_IDX + 1; i++) {
+		local_rqfpr[j] = ftp_rqfpr[i];
+		local_rqfcr[j] = ftp_rqfcr[i];
+		j--;
+		if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE |
+			RQFCR_CLE |RQFCR_AND)) &&
+			(ftp_rqfpr[i] == cmp_rqfpr))
+			break;
+	}
+
+	if (i == MAX_FILER_IDX + 1) {
+		printk(KERN_ERR "No parse rule found, ");
+		printk(KERN_ERR "can't create hash rules\n");
+		return 0;
+	}
+
+	/* If a match was found, then it begins the starting of a cluster rule
+	 * if it was already programmed, we need to overwrite these rules
+	 */
+	for (l = i+1; l < MAX_FILER_IDX; l++) {
+		if ((ftp_rqfcr[l] & RQFCR_CLE) &&
+			!(ftp_rqfcr[l] & RQFCR_AND)) {
+			ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
+				RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
+			ftp_rqfpr[l] = FPR_FILER_MASK;
+			gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]);
+			break;
+		}
+
+		if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND))
+			continue;
+		else {
+			local_rqfpr[j] = ftp_rqfpr[l];
+			local_rqfcr[j] = ftp_rqfcr[l];
+			j--;
+		}
+	}
+
+	priv->cur_filer_idx = l - 1;
+	last_rule_idx = l;
+
+	/* hash rules */
+	ethflow_to_filer_rules(priv, ethflow);
+
+	/* Write back the popped out rules again */
+	for (k = j+1; k < MAX_FILER_IDX; k++) {
+		ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
+		ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
+		gfar_write_filer(priv, priv->cur_filer_idx,
+				local_rqfcr[k], local_rqfpr[k]);
+		if (!priv->cur_filer_idx)
+			break;
+		priv->cur_filer_idx = priv->cur_filer_idx - 1;
+	}
+
+	return 1;
+}
+
+static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
+{
+	u64 class;
+
+	if (!gfar_ethflow_to_class(cmd->flow_type, &class))
+		return -EINVAL;
+
+	if (class < CLASS_CODE_USER_PROG1 ||
+			class > CLASS_CODE_SCTP_IPV6)
+		return -EINVAL;
+
+	/* write the filer rules here */
+	if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type))
+		return -1;
+
+	return 0;
+}
+
+static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	int ret = 0;
+
+	switch(cmd->cmd) {
+	case ETHTOOL_SRXFH:
+		ret = gfar_set_hash_opts(priv, cmd);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 const struct ethtool_ops gfar_ethtool_ops = {
 	.get_settings = gfar_gsettings,
 	.set_settings = gfar_ssettings,
@@ -630,4 +905,5 @@ const struct ethtool_ops gfar_ethtool_op
 	.get_wol = gfar_get_wol,
 	.set_wol = gfar_set_wol,
 #endif
+	.set_rxnfc = gfar_set_nfc,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/gianfar.h linux-libre-2.6.33-gnu1/drivers/net/gianfar.h
--- linux-libre-2.6.32-gnu1/drivers/net/gianfar.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/gianfar.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,8 +7,9 @@
  *
  * Author: Andy Fleming
  * Maintainer: Kumar Gala
+ * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ * Copyright 2002-2009 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
@@ -74,6 +75,13 @@
 extern const char gfar_driver_name[];
 extern const char gfar_driver_version[];
 
+/* MAXIMUM NUMBER OF QUEUES SUPPORTED */
+#define MAX_TX_QS	0x8
+#define MAX_RX_QS	0x8
+
+/* MAXIMUM NUMBER OF GROUPS SUPPORTED */
+#define MAXGROUPS 0x2
+
 /* These need to be powers of 2 for this driver */
 #define DEFAULT_TX_RING_SIZE	256
 #define DEFAULT_RX_RING_SIZE	256
@@ -171,12 +179,63 @@ extern const char gfar_driver_version[];
 
 #define MINFLR_INIT_SETTINGS	0x00000040
 
+/* Tqueue control */
+#define TQUEUE_EN0		0x00008000
+#define TQUEUE_EN1		0x00004000
+#define TQUEUE_EN2		0x00002000
+#define TQUEUE_EN3		0x00001000
+#define TQUEUE_EN4		0x00000800
+#define TQUEUE_EN5		0x00000400
+#define TQUEUE_EN6		0x00000200
+#define TQUEUE_EN7		0x00000100
+#define TQUEUE_EN_ALL		0x0000FF00
+
+#define TR03WT_WT0_MASK		0xFF000000
+#define TR03WT_WT1_MASK		0x00FF0000
+#define TR03WT_WT2_MASK		0x0000FF00
+#define TR03WT_WT3_MASK		0x000000FF
+
+#define TR47WT_WT4_MASK		0xFF000000
+#define TR47WT_WT5_MASK		0x00FF0000
+#define TR47WT_WT6_MASK		0x0000FF00
+#define TR47WT_WT7_MASK		0x000000FF
+
+/* Rqueue control */
+#define RQUEUE_EX0		0x00800000
+#define RQUEUE_EX1		0x00400000
+#define RQUEUE_EX2		0x00200000
+#define RQUEUE_EX3		0x00100000
+#define RQUEUE_EX4		0x00080000
+#define RQUEUE_EX5		0x00040000
+#define RQUEUE_EX6		0x00020000
+#define RQUEUE_EX7		0x00010000
+#define RQUEUE_EX_ALL		0x00FF0000
+
+#define RQUEUE_EN0		0x00000080
+#define RQUEUE_EN1		0x00000040
+#define RQUEUE_EN2		0x00000020
+#define RQUEUE_EN3		0x00000010
+#define RQUEUE_EN4		0x00000008
+#define RQUEUE_EN5		0x00000004
+#define RQUEUE_EN6		0x00000002
+#define RQUEUE_EN7		0x00000001
+#define RQUEUE_EN_ALL		0x000000FF
+
 /* Init to do tx snooping for buffers and descriptors */
 #define DMACTRL_INIT_SETTINGS   0x000000c3
 #define DMACTRL_GRS             0x00000010
 #define DMACTRL_GTS             0x00000008
 
-#define TSTAT_CLEAR_THALT       0x80000000
+#define TSTAT_CLEAR_THALT_ALL	0xFF000000
+#define TSTAT_CLEAR_THALT	0x80000000
+#define TSTAT_CLEAR_THALT0	0x80000000
+#define TSTAT_CLEAR_THALT1	0x40000000
+#define TSTAT_CLEAR_THALT2	0x20000000
+#define TSTAT_CLEAR_THALT3	0x10000000
+#define TSTAT_CLEAR_THALT4	0x08000000
+#define TSTAT_CLEAR_THALT5	0x04000000
+#define TSTAT_CLEAR_THALT6	0x02000000
+#define TSTAT_CLEAR_THALT7	0x01000000
 
 /* Interrupt coalescing macros */
 #define IC_ICEN			0x80000000
@@ -227,6 +286,13 @@ extern const char gfar_driver_version[];
 #define TCTRL_IPCSEN		0x00004000
 #define TCTRL_TUCSEN		0x00002000
 #define TCTRL_VLINS		0x00001000
+#define TCTRL_THDF		0x00000800
+#define TCTRL_RFCPAUSE		0x00000010
+#define TCTRL_TFCPAUSE		0x00000008
+#define TCTRL_TXSCHED_MASK	0x00000006
+#define TCTRL_TXSCHED_INIT	0x00000000
+#define TCTRL_TXSCHED_PRIO	0x00000002
+#define TCTRL_TXSCHED_WRRS	0x00000004
 #define TCTRL_INIT_CSUM		(TCTRL_TUCSEN | TCTRL_IPCSEN)
 
 #define IEVENT_INIT_CLEAR	0xffffffff
@@ -267,7 +333,7 @@ extern const char gfar_driver_version[];
 #define IMASK_BSY               0x20000000
 #define IMASK_EBERR             0x10000000
 #define IMASK_MSRO		0x04000000
-#define IMASK_GRSC              0x02000000
+#define IMASK_GTSC              0x02000000
 #define IMASK_BABT		0x01000000
 #define IMASK_TXC               0x00800000
 #define IMASK_TXEEN		0x00400000
@@ -278,7 +344,7 @@ extern const char gfar_driver_version[];
 #define IMASK_XFUN		0x00010000
 #define IMASK_RXB0              0x00008000
 #define IMASK_MAG		0x00000800
-#define IMASK_GTSC              0x00000100
+#define IMASK_GRSC              0x00000100
 #define IMASK_RXFEN0		0x00000080
 #define IMASK_FIR		0x00000008
 #define IMASK_FIQ		0x00000004
@@ -315,6 +381,88 @@ extern const char gfar_driver_version[];
 #define BD_LFLAG(flags) ((flags) << 16)
 #define BD_LENGTH_MASK		0x0000ffff
 
+#define CLASS_CODE_UNRECOG		0x00
+#define CLASS_CODE_DUMMY1		0x01
+#define CLASS_CODE_ETHERTYPE1		0x02
+#define CLASS_CODE_ETHERTYPE2		0x03
+#define CLASS_CODE_USER_PROG1		0x04
+#define CLASS_CODE_USER_PROG2		0x05
+#define CLASS_CODE_USER_PROG3		0x06
+#define CLASS_CODE_USER_PROG4		0x07
+#define CLASS_CODE_TCP_IPV4		0x08
+#define CLASS_CODE_UDP_IPV4		0x09
+#define CLASS_CODE_AH_ESP_IPV4		0x0a
+#define CLASS_CODE_SCTP_IPV4		0x0b
+#define CLASS_CODE_TCP_IPV6		0x0c
+#define CLASS_CODE_UDP_IPV6		0x0d
+#define CLASS_CODE_AH_ESP_IPV6		0x0e
+#define CLASS_CODE_SCTP_IPV6		0x0f
+
+#define FPR_FILER_MASK	0xFFFFFFFF
+#define MAX_FILER_IDX	0xFF
+
+/* This default RIR value directly corresponds
+ * to the 3-bit hash value generated */
+#define DEFAULT_RIR0	0x05397700
+
+/* RQFCR register bits */
+#define RQFCR_GPI		0x80000000
+#define RQFCR_HASHTBL_Q		0x00000000
+#define RQFCR_HASHTBL_0		0x00020000
+#define RQFCR_HASHTBL_1		0x00040000
+#define RQFCR_HASHTBL_2		0x00060000
+#define RQFCR_HASHTBL_3		0x00080000
+#define RQFCR_HASH		0x00010000
+#define RQFCR_CLE		0x00000200
+#define RQFCR_RJE		0x00000100
+#define RQFCR_AND		0x00000080
+#define RQFCR_CMP_EXACT		0x00000000
+#define RQFCR_CMP_MATCH		0x00000020
+#define RQFCR_CMP_NOEXACT	0x00000040
+#define RQFCR_CMP_NOMATCH	0x00000060
+
+/* RQFCR PID values */
+#define	RQFCR_PID_MASK		0x00000000
+#define	RQFCR_PID_PARSE		0x00000001
+#define	RQFCR_PID_ARB		0x00000002
+#define	RQFCR_PID_DAH		0x00000003
+#define	RQFCR_PID_DAL		0x00000004
+#define	RQFCR_PID_SAH		0x00000005
+#define	RQFCR_PID_SAL		0x00000006
+#define	RQFCR_PID_ETY		0x00000007
+#define	RQFCR_PID_VID		0x00000008
+#define	RQFCR_PID_PRI		0x00000009
+#define	RQFCR_PID_TOS		0x0000000A
+#define	RQFCR_PID_L4P		0x0000000B
+#define	RQFCR_PID_DIA		0x0000000C
+#define	RQFCR_PID_SIA		0x0000000D
+#define	RQFCR_PID_DPT		0x0000000E
+#define	RQFCR_PID_SPT		0x0000000F
+
+/* RQFPR when PID is 0x0001 */
+#define RQFPR_HDR_GE_512	0x00200000
+#define RQFPR_LERR		0x00100000
+#define RQFPR_RAR		0x00080000
+#define RQFPR_RARQ		0x00040000
+#define RQFPR_AR		0x00020000
+#define RQFPR_ARQ		0x00010000
+#define RQFPR_EBC		0x00008000
+#define RQFPR_VLN		0x00004000
+#define RQFPR_CFI		0x00002000
+#define RQFPR_JUM		0x00001000
+#define RQFPR_IPF		0x00000800
+#define RQFPR_FIF		0x00000400
+#define RQFPR_IPV4		0x00000200
+#define RQFPR_IPV6		0x00000100
+#define RQFPR_ICC		0x00000080
+#define RQFPR_ICV		0x00000040
+#define RQFPR_TCP		0x00000020
+#define RQFPR_UDP		0x00000010
+#define RQFPR_TUC		0x00000008
+#define RQFPR_TUV		0x00000004
+#define RQFPR_PER		0x00000002
+#define RQFPR_EER		0x00000001
+
 /* TxBD status field bits */
 #define TXBD_READY		0x8000
 #define TXBD_PADCRC		0x4000
@@ -503,25 +651,32 @@ struct gfar_stats {
 
 struct gfar {
 	u32	tsec_id;	/* 0x.000 - Controller ID register */
-	u8	res1[12];
+	u32	tsec_id2;	/* 0x.004 - Controller ID2 register */
+	u8	res1[8];
 	u32	ievent;		/* 0x.010 - Interrupt Event Register */
 	u32	imask;		/* 0x.014 - Interrupt Mask Register */
 	u32	edis;		/* 0x.018 - Error Disabled Register */
-	u8	res2[4];
+	u32	emapg;		/* 0x.01c - Group Error mapping register */
 	u32	ecntrl;		/* 0x.020 - Ethernet Control Register */
 	u32	minflr;		/* 0x.024 - Minimum Frame Length Register */
 	u32	ptv;		/* 0x.028 - Pause Time Value Register */
 	u32	dmactrl;	/* 0x.02c - DMA Control Register */
 	u32	tbipa;		/* 0x.030 - TBI PHY Address Register */
-	u8	res3[88];
+	u8	res2[28];
+	u32	fifo_rx_pause;	/* 0x.050 - FIFO receive pause start threshold
+					register */
+	u32	fifo_rx_pause_shutoff;	/* x.054 - FIFO receive starve shutoff
+						register */
+	u32	fifo_rx_alarm;	/* 0x.058 - FIFO receive alarm start threshold
+						register */
+	u32	fifo_rx_alarm_shutoff;	/*0x.05c - FIFO receive alarm  starve
+						shutoff register */
+	u8	res3[44];
 	u32	fifo_tx_thr;	/* 0x.08c - FIFO transmit threshold register */
 	u8	res4[8];
 	u32	fifo_tx_starve;	/* 0x.098 - FIFO transmit starve register */
 	u32	fifo_tx_starve_shutoff;	/* 0x.09c - FIFO transmit starve shutoff register */
-	u8	res5[4];
-	u32	fifo_rx_pause;	/* 0x.0a4 - FIFO receive pause threshold register */
-	u32	fifo_rx_alarm;	/* 0x.0a8 - FIFO receive alarm threshold register */
-	u8	res6[84];
+	u8	res5[96];
 	u32	tctrl;		/* 0x.100 - Transmit Control Register */
 	u32	tstat;		/* 0x.104 - Transmit Status Register */
 	u32	dfvlan;		/* 0x.108 - Default VLAN Control word */
@@ -572,7 +727,11 @@ struct gfar {
 	u8	res12[8];
 	u32	rxic;		/* 0x.310 - Receive Interrupt Coalescing Configuration Register */
 	u32	rqueue;		/* 0x.314 - Receive queue control register */
-	u8	res13[24];
+	u32	rir0;		/* 0x.318 - Ring mapping register 0 */
+	u32	rir1;		/* 0x.31c - Ring mapping register 1 */
+	u32	rir2;		/* 0x.320 - Ring mapping register 2 */
+	u32	rir3;		/* 0x.324 - Ring mapping register 3 */
+	u8	res13[8];
 	u32	rbifx;		/* 0x.330 - Receive bit field extract control register */
 	u32	rqfar;		/* 0x.334 - Receive queue filing table address register */
 	u32	rqfcr;		/* 0x.338 - Receive queue filing table control register */
@@ -621,7 +780,7 @@ struct gfar {
 	u32	maxfrm;		/* 0x.510 - Maximum Frame Length Register */
 	u8	res18[12];
 	u8	gfar_mii_regs[24];	/* See gianfar_phy.h */
-	u8	res19[4];
+	u32	ifctrl;		/* 0x.538 - Interface control register */
 	u32	ifstat;		/* 0x.53c - Interface Status Register */
 	u32	macstnaddr1;	/* 0x.540 - Station Address Part 1 Register */
 	u32	macstnaddr2;	/* 0x.544 - Station Address Part 2 Register */
@@ -682,8 +841,30 @@ struct gfar {
 	u8	res23c[248];
 	u32	attr;		/* 0x.bf8 - Attributes Register */
 	u32	attreli;	/* 0x.bfc - Attributes Extract Length and Extract Index Register */
-	u8	res24[1024];
-
+	u8	res24[688];
+	u32	isrg0;		/* 0x.eb0 - Interrupt steering group 0 register */
+	u32	isrg1;		/* 0x.eb4 - Interrupt steering group 1 register */
+	u32	isrg2;		/* 0x.eb8 - Interrupt steering group 2 register */
+	u32	isrg3;		/* 0x.ebc - Interrupt steering group 3 register */
+	u8	res25[16];
+	u32	rxic0;		/* 0x.ed0 - Ring 0 Rx interrupt coalescing */
+	u32	rxic1;		/* 0x.ed4 - Ring 1 Rx interrupt coalescing */
+	u32	rxic2;		/* 0x.ed8 - Ring 2 Rx interrupt coalescing */
+	u32	rxic3;		/* 0x.edc - Ring 3 Rx interrupt coalescing */
+	u32	rxic4;		/* 0x.ee0 - Ring 4 Rx interrupt coalescing */
+	u32	rxic5;		/* 0x.ee4 - Ring 5 Rx interrupt coalescing */
+	u32	rxic6;		/* 0x.ee8 - Ring 6 Rx interrupt coalescing */
+	u32	rxic7;		/* 0x.eec - Ring 7 Rx interrupt coalescing */
+	u8	res26[32];
+	u32	txic0;		/* 0x.f10 - Ring 0 Tx interrupt coalescing */
+	u32	txic1;		/* 0x.f14 - Ring 1 Tx interrupt coalescing */
+	u32	txic2;		/* 0x.f18 - Ring 2 Tx interrupt coalescing */
+	u32	txic3;		/* 0x.f1c - Ring 3 Tx interrupt coalescing */
+	u32	txic4;		/* 0x.f20 - Ring 4 Tx interrupt coalescing */
+	u32	txic5;		/* 0x.f24 - Ring 5 Tx interrupt coalescing */
+	u32	txic6;		/* 0x.f28 - Ring 6 Tx interrupt coalescing */
+	u32	txic7;		/* 0x.f2c - Ring 7 Tx interrupt coalescing */
+	u8	res27[208];
 };
 
 /* Flags related to gianfar device features */
@@ -699,6 +880,143 @@ struct gfar {
 #define FSL_GIANFAR_DEV_HAS_BD_STASHING		0x00000200
 #define FSL_GIANFAR_DEV_HAS_BUF_STASHING	0x00000400
 
+#if (MAXGROUPS == 2)
+#define DEFAULT_MAPPING 	0xAA
+#else
+#define DEFAULT_MAPPING 	0xFF
+#endif
+
+#define ISRG_SHIFT_TX	0x10
+#define ISRG_SHIFT_RX	0x18
+
+/* The same driver can operate in two modes */
+/* SQ_SG_MODE: Single Queue Single Group Mode
+ * 		(Backward compatible mode)
+ * MQ_MG_MODE: Multi Queue Multi Group mode
+ */
+enum {
+	SQ_SG_MODE = 0,
+	MQ_MG_MODE
+};
+
+/**
+ *	struct gfar_priv_tx_q - per tx queue structure
+ *	@txlock: per queue tx spin lock
+ *	@tx_skbuff:skb pointers
+ *	@skb_curtx: to be used skb pointer
+ *	@skb_dirtytx:the last used skb pointer
+ *	@qindex: index of this queue
+ *	@dev: back pointer to the dev structure
+ *	@grp: back pointer to the group to which this queue belongs
+ *	@tx_bd_base: First tx buffer descriptor
+ *	@cur_tx: Next free ring entry
+ *	@dirty_tx: First buffer in line to be transmitted
+ *	@tx_ring_size: Tx ring size
+ *	@num_txbdfree: number of free TxBds
+ *	@txcoalescing: enable/disable tx coalescing
+ *	@txic: transmit interrupt coalescing value
+ *	@txcount: coalescing value if based on tx frame count
+ *	@txtime: coalescing value if based on time
+ */
+struct gfar_priv_tx_q {
+	spinlock_t txlock __attribute__ ((aligned (SMP_CACHE_BYTES)));
+	struct sk_buff ** tx_skbuff;
+	/* Buffer descriptor pointers */
+	dma_addr_t tx_bd_dma_base;
+	struct	txbd8 *tx_bd_base;
+	struct	txbd8 *cur_tx;
+	struct	txbd8 *dirty_tx;
+	struct	net_device *dev;
+	struct gfar_priv_grp *grp;
+	u16	skb_curtx;
+	u16	skb_dirtytx;
+	u16	qindex;
+	unsigned int tx_ring_size;
+	unsigned int num_txbdfree;
+	/* Configuration info for the coalescing features */
+	unsigned char txcoalescing;
+	unsigned long txic;
+	unsigned short txcount;
+	unsigned short txtime;
+};
+
+/*
+ * Per RX queue stats
+ */
+struct rx_q_stats {
+	unsigned long rx_packets;
+	unsigned long rx_bytes;
+	unsigned long rx_dropped;
+};
+
+/**
+ *	struct gfar_priv_rx_q - per rx queue structure
+ *	@rxlock: per queue rx spin lock
+ *	@rx_skbuff: skb pointers
+ *	@skb_currx: currently use skb pointer
+ *	@rx_bd_base: First rx buffer descriptor
+ *	@cur_rx: Next free rx ring entry
+ *	@qindex: index of this queue
+ *	@dev: back pointer to the dev structure
+ *	@rx_ring_size: Rx ring size
+ *	@rxcoalescing: enable/disable rx-coalescing
+ *	@rxic: receive interrupt coalescing vlaue
+ */
+
+struct gfar_priv_rx_q {
+	spinlock_t rxlock __attribute__ ((aligned (SMP_CACHE_BYTES)));
+	struct	sk_buff ** rx_skbuff;
+	dma_addr_t rx_bd_dma_base;
+	struct	rxbd8 *rx_bd_base;
+	struct	rxbd8 *cur_rx;
+	struct	net_device *dev;
+	struct gfar_priv_grp *grp;
+	struct rx_q_stats stats;
+	u16	skb_currx;
+	u16	qindex;
+	unsigned int	rx_ring_size;
+	/* RX Coalescing values */
+	unsigned char rxcoalescing;
+	unsigned long rxic;
+};
+
+/**
+ *	struct gfar_priv_grp - per group structure
+ *	@napi: the napi poll function
+ *	@priv: back pointer to the priv structure
+ *	@regs: the ioremapped register space for this group
+ *	@grp_id: group id for this group
+ *	@interruptTransmit: The TX interrupt number for this group
+ *	@interruptReceive: The RX interrupt number for this group
+ *	@interruptError: The ERROR interrupt number for this group
+ *	@int_name_tx: tx interrupt name for this group
+ *	@int_name_rx: rx interrupt name for this group
+ *	@int_name_er: er interrupt name for this group
+ */
+
+struct gfar_priv_grp {
+	spinlock_t grplock __attribute__ ((aligned (SMP_CACHE_BYTES)));
+	struct	napi_struct napi;
+	struct gfar_private *priv;
+	struct gfar __iomem *regs;
+	unsigned int grp_id;
+	unsigned long rx_bit_map;
+	unsigned long tx_bit_map;
+	unsigned long num_tx_queues;
+	unsigned long num_rx_queues;
+	unsigned int rstat;
+	unsigned int tstat;
+	unsigned int imask;
+	unsigned int ievent;
+	unsigned int interruptTransmit;
+	unsigned int interruptReceive;
+	unsigned int interruptError;
+
+	char int_name_tx[GFAR_INT_NAME_MAX];
+	char int_name_rx[GFAR_INT_NAME_MAX];
+	char int_name_er[GFAR_INT_NAME_MAX];
+};
+
 /* Struct stolen almost completely (and shamelessly) from the FCC enet source
  * (Ok, that's not so true anymore, but there is a family resemblence)
  * The GFAR buffer descriptors track the ring buffers.  The rx_bd_base
@@ -709,62 +1027,36 @@ struct gfar {
  * the buffer descriptor determines the actual condition.
  */
 struct gfar_private {
-	/* Fields controlled by TX lock */
-	spinlock_t txlock;
 
-	/* Pointer to the array of skbuffs */
-	struct sk_buff ** tx_skbuff;
-
-	/* next free skb in the array */
-	u16 skb_curtx;
-
-	/* First skb in line to be transmitted */
-	u16 skb_dirtytx;
-
-	/* Configuration info for the coalescing features */
-	unsigned char txcoalescing;
-	unsigned long txic;
-
-	/* Buffer descriptor pointers */
-	struct txbd8 *tx_bd_base;	/* First tx buffer descriptor */
-	struct txbd8 *cur_tx;	        /* Next free ring entry */
-	struct txbd8 *dirty_tx;		/* First buffer in line
-					   to be transmitted */
-	unsigned int tx_ring_size;
-	unsigned int num_txbdfree;	/* number of TxBDs free */
+	/* Indicates how many tx, rx queues are enabled */
+	unsigned int num_tx_queues;
+	unsigned int num_rx_queues;
+	unsigned int num_grps;
+	unsigned int mode;
 
-	/* RX Locked fields */
-	spinlock_t rxlock;
+	/* The total tx and rx ring size for the enabled queues */
+	unsigned int total_tx_ring_size;
+	unsigned int total_rx_ring_size;
 
 	struct device_node *node;
 	struct net_device *ndev;
 	struct of_device *ofdev;
-	struct napi_struct napi;
-
-	/* skb array and index */
-	struct sk_buff ** rx_skbuff;
-	u16 skb_currx;
 
-	/* RX Coalescing values */
-	unsigned char rxcoalescing;
-	unsigned long rxic;
-
-	struct rxbd8 *rx_bd_base;	/* First Rx buffers */
-	struct rxbd8 *cur_rx;           /* Next free rx ring entry */
+	struct gfar_priv_grp gfargrp[MAXGROUPS];
+	struct gfar_priv_tx_q *tx_queue[MAX_TX_QS];
+	struct gfar_priv_rx_q *rx_queue[MAX_RX_QS];
 
-	/* RX parameters */
-	unsigned int rx_ring_size;
+	/* RX per device parameters */
 	unsigned int rx_buffer_size;
 	unsigned int rx_stash_size;
 	unsigned int rx_stash_index;
 
+	u32 cur_filer_idx;
+
 	struct sk_buff_head rx_recycle;
 
 	struct vlan_group *vlgrp;
 
-	/* Unprotected fields */
-	/* Pointer to the GFAR memory mapped Registers */
-	struct gfar __iomem *regs;
 
 	/* Hash registers and their width */
 	u32 __iomem *hash_regs[16];
@@ -785,13 +1077,10 @@ struct gfar_private {
 	unsigned char rx_csum_enable:1,
 		extended_hash:1,
 		bd_stash_en:1,
+		rx_filer_enable:1,
 		wol_en:1; /* Wake-on-LAN enabled */
 	unsigned short padding;
 
-	unsigned int interruptTransmit;
-	unsigned int interruptReceive;
-	unsigned int interruptError;
-
 	/* PHY stuff */
 	struct phy_device *phydev;
 	struct mii_bus *mii_bus;
@@ -803,14 +1092,13 @@ struct gfar_private {
 
 	struct work_struct reset_task;
 
-	char int_name_tx[GFAR_INT_NAME_MAX];
-	char int_name_rx[GFAR_INT_NAME_MAX];
-	char int_name_er[GFAR_INT_NAME_MAX];
-
 	/* Network Statistics */
 	struct gfar_extra_stats extra_stats;
 };
 
+extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
+
 static inline u32 gfar_read(volatile unsigned __iomem *addr)
 {
 	u32 val;
@@ -823,12 +1111,28 @@ static inline void gfar_write(volatile u
 	out_be32(addr, val);
 }
 
+static inline void gfar_write_filer(struct gfar_private *priv,
+		unsigned int far, unsigned int fcr, unsigned int fpr)
+{
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
+
+	gfar_write(&regs->rqfar, far);
+	gfar_write(&regs->rqfcr, fcr);
+	gfar_write(&regs->rqfpr, fpr);
+}
+
+extern void lock_rx_qs(struct gfar_private *priv);
+extern void lock_tx_qs(struct gfar_private *priv);
+extern void unlock_rx_qs(struct gfar_private *priv);
+extern void unlock_tx_qs(struct gfar_private *priv);
 extern irqreturn_t gfar_receive(int irq, void *dev_id);
 extern int startup_gfar(struct net_device *dev);
 extern void stop_gfar(struct net_device *dev);
 extern void gfar_halt(struct net_device *dev);
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
+extern void gfar_configure_coalescing(struct gfar_private *priv,
+		unsigned long tx_mask, unsigned long rx_mask);
 void gfar_init_sysfs(struct net_device *dev);
 
 extern const struct ethtool_ops gfar_ethtool_ops;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/gianfar_sysfs.c linux-libre-2.6.33-gnu1/drivers/net/gianfar_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/gianfar_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/gianfar_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,8 +8,9 @@
  *
  * Author: Andy Fleming
  * Maintainer: Kumar Gala (galak@kernel.crashing.org)
+ * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
+ * Copyright 2002-2009 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
@@ -49,6 +50,7 @@ static ssize_t gfar_set_bd_stash(struct
 				 const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	int new_setting = 0;
 	u32 temp;
 	unsigned long flags;
@@ -56,30 +58,34 @@ static ssize_t gfar_set_bd_stash(struct
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
 		return count;
 
+
 	/* Find out the new setting */
 	if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
 		new_setting = 1;
-	else if (!strncmp("off", buf, count - 1)
-		 || !strncmp("0", buf, count - 1))
+	else if (!strncmp("off", buf, count - 1) ||
+		 !strncmp("0", buf, count - 1))
 		new_setting = 0;
 	else
 		return count;
 
-	spin_lock_irqsave(&priv->rxlock, flags);
+
+	local_irq_save(flags);
+	lock_rx_qs(priv);
 
 	/* Set the new stashing value */
 	priv->bd_stash_en = new_setting;
 
-	temp = gfar_read(&priv->regs->attr);
+	temp = gfar_read(&regs->attr);
 
 	if (new_setting)
 		temp |= ATTR_BDSTASH;
 	else
 		temp &= ~(ATTR_BDSTASH);
 
-	gfar_write(&priv->regs->attr, temp);
+	gfar_write(&regs->attr, temp);
 
-	spin_unlock_irqrestore(&priv->rxlock, flags);
+	unlock_rx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
@@ -99,6 +105,7 @@ static ssize_t gfar_set_rx_stash_size(st
 				      const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned int length = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -106,7 +113,9 @@ static ssize_t gfar_set_rx_stash_size(st
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
 		return count;
 
-	spin_lock_irqsave(&priv->rxlock, flags);
+	local_irq_save(flags);
+	lock_rx_qs(priv);
+
 	if (length > priv->rx_buffer_size)
 		goto out;
 
@@ -115,23 +124,24 @@ static ssize_t gfar_set_rx_stash_size(st
 
 	priv->rx_stash_size = length;
 
-	temp = gfar_read(&priv->regs->attreli);
+	temp = gfar_read(&regs->attreli);
 	temp &= ~ATTRELI_EL_MASK;
 	temp |= ATTRELI_EL(length);
-	gfar_write(&priv->regs->attreli, temp);
+	gfar_write(&regs->attreli, temp);
 
 	/* Turn stashing on/off as appropriate */
-	temp = gfar_read(&priv->regs->attr);
+	temp = gfar_read(&regs->attr);
 
 	if (length)
 		temp |= ATTR_BUFSTASH;
 	else
 		temp &= ~(ATTR_BUFSTASH);
 
-	gfar_write(&priv->regs->attr, temp);
+	gfar_write(&regs->attr, temp);
 
 out:
-	spin_unlock_irqrestore(&priv->rxlock, flags);
+	unlock_rx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
@@ -154,6 +164,7 @@ static ssize_t gfar_set_rx_stash_index(s
 				       const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned short index = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -161,7 +172,9 @@ static ssize_t gfar_set_rx_stash_index(s
 	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
 		return count;
 
-	spin_lock_irqsave(&priv->rxlock, flags);
+	local_irq_save(flags);
+	lock_rx_qs(priv);
+
 	if (index > priv->rx_stash_size)
 		goto out;
 
@@ -170,13 +183,14 @@ static ssize_t gfar_set_rx_stash_index(s
 
 	priv->rx_stash_index = index;
 
-	temp = gfar_read(&priv->regs->attreli);
+	temp = gfar_read(&regs->attreli);
 	temp &= ~ATTRELI_EI_MASK;
 	temp |= ATTRELI_EI(index);
-	gfar_write(&priv->regs->attreli, flags);
+	gfar_write(&regs->attreli, temp);
 
 out:
-	spin_unlock_irqrestore(&priv->rxlock, flags);
+	unlock_rx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
@@ -198,6 +212,7 @@ static ssize_t gfar_set_fifo_threshold(s
 				       const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned int length = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -205,16 +220,18 @@ static ssize_t gfar_set_fifo_threshold(s
 	if (length > GFAR_MAX_FIFO_THRESHOLD)
 		return count;
 
-	spin_lock_irqsave(&priv->txlock, flags);
+	local_irq_save(flags);
+	lock_tx_qs(priv);
 
 	priv->fifo_threshold = length;
 
-	temp = gfar_read(&priv->regs->fifo_tx_thr);
+	temp = gfar_read(&regs->fifo_tx_thr);
 	temp &= ~FIFO_TX_THR_MASK;
 	temp |= length;
-	gfar_write(&priv->regs->fifo_tx_thr, temp);
+	gfar_write(&regs->fifo_tx_thr, temp);
 
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
@@ -235,6 +252,7 @@ static ssize_t gfar_set_fifo_starve(stru
 				    const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned int num = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -242,16 +260,18 @@ static ssize_t gfar_set_fifo_starve(stru
 	if (num > GFAR_MAX_FIFO_STARVE)
 		return count;
 
-	spin_lock_irqsave(&priv->txlock, flags);
+	local_irq_save(flags);
+	lock_tx_qs(priv);
 
 	priv->fifo_starve = num;
 
-	temp = gfar_read(&priv->regs->fifo_tx_starve);
+	temp = gfar_read(&regs->fifo_tx_starve);
 	temp &= ~FIFO_TX_STARVE_MASK;
 	temp |= num;
-	gfar_write(&priv->regs->fifo_tx_starve, temp);
+	gfar_write(&regs->fifo_tx_starve, temp);
 
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
@@ -273,6 +293,7 @@ static ssize_t gfar_set_fifo_starve_off(
 					const char *buf, size_t count)
 {
 	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
+	struct gfar __iomem *regs = priv->gfargrp[0].regs;
 	unsigned int num = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -280,16 +301,18 @@ static ssize_t gfar_set_fifo_starve_off(
 	if (num > GFAR_MAX_FIFO_STARVE_OFF)
 		return count;
 
-	spin_lock_irqsave(&priv->txlock, flags);
+	local_irq_save(flags);
+	lock_tx_qs(priv);
 
 	priv->fifo_starve_off = num;
 
-	temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
+	temp = gfar_read(&regs->fifo_tx_starve_shutoff);
 	temp &= ~FIFO_TX_STARVE_OFF_MASK;
 	temp |= num;
-	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
+	gfar_write(&regs->fifo_tx_starve_shutoff, temp);
 
-	spin_unlock_irqrestore(&priv->txlock, flags);
+	unlock_tx_qs(priv);
+	local_irq_restore(flags);
 
 	return count;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamachi.c linux-libre-2.6.33-gnu1/drivers/net/hamachi.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamachi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamachi.c	2010-02-24 13:52:17.000000000 -0500
@@ -407,10 +407,9 @@ that case.
 /* A few values that may be tweaked. */
 /* Size of each temporary Rx buffer, calculated as:
  * 1518 bytes (ethernet packet) + 2 bytes (to get 8 byte alignment for
- * the card) + 8 bytes of status info + 8 bytes for the Rx Checksum +
- * 2 more because we use skb_reserve.
+ * the card) + 8 bytes of status info + 8 bytes for the Rx Checksum
  */
-#define PKT_BUF_SZ		1538
+#define PKT_BUF_SZ		1536
 
 /* For now, this is going to be set to the maximum size of an ethernet
  * packet.  Eventually, we may want to make it a variable that is
@@ -873,7 +872,7 @@ static int hamachi_open(struct net_devic
 	u32 rx_int_var, tx_int_var;
 	u16 fifo_info;
 
-	i = request_irq(dev->irq, &hamachi_interrupt, IRQF_SHARED, dev->name, dev);
+	i = request_irq(dev->irq, hamachi_interrupt, IRQF_SHARED, dev->name, dev);
 	if (i)
 		return i;
 
@@ -1152,12 +1151,13 @@ static void hamachi_tx_timeout(struct ne
 	}
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz);
+		struct sk_buff *skb;
+
+		skb = netdev_alloc_skb_ip_align(dev, hmp->rx_buf_sz);
 		hmp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
 
-		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
 			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
@@ -1196,7 +1196,7 @@ static void hamachi_init_ring(struct net
 	 * card.  -KDU
 	 */
 	hmp->rx_buf_sz = (dev->mtu <= 1492 ? PKT_BUF_SZ :
-		(((dev->mtu+26+7) & ~7) + 2 + 16));
+		(((dev->mtu+26+7) & ~7) + 16));
 
 	/* Initialize all Rx descriptors. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
@@ -1566,8 +1566,8 @@ static int hamachi_rx(struct net_device
 #endif
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 #ifdef RX_CHECKSUM
 				printk(KERN_ERR "%s: rx_copybreak non-zero "
 				  "not good with RX_CHECKSUM\n", dev->name);
@@ -1722,10 +1722,10 @@ static void hamachi_error(struct net_dev
 		readl(ioaddr + 0x370);
 		readl(ioaddr + 0x3F0);
 	}
-	if ((intr_status & ~(LinkChange|StatsMax|NegotiationChange|IntrRxDone|IntrTxDone))
-		&& hamachi_debug)
+	if ((intr_status & ~(LinkChange|StatsMax|NegotiationChange|IntrRxDone|IntrTxDone)) &&
+	    hamachi_debug)
 		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
-			   dev->name, intr_status);
+		       dev->name, intr_status);
 	/* Hmmmmm, it's not clear how to recover from PCI faults. */
 	if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
 		hmp->stats.tx_fifo_errors++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/6pack.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/6pack.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/6pack.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/6pack.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/semaphore.h>
+#include <linux/compat.h>
 #include <asm/atomic.h>
 
 #define SIXPACK_VERSION    "Revision: 0.3.0"
@@ -777,6 +778,23 @@ static int sixpack_ioctl(struct tty_stru
 	return err;
 }
 
+#ifdef CONFIG_COMPAT
+static long sixpack_compat_ioctl(struct tty_struct * tty, struct file * file,
+				unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case SIOCGIFNAME:
+	case SIOCGIFENCAP:
+	case SIOCSIFENCAP:
+	case SIOCSIFHWADDR:
+		return sixpack_ioctl(tty, file, cmd,
+				(unsigned long)compat_ptr(arg));
+	}
+
+	return -ENOIOCTLCMD;
+}
+#endif
+
 static struct tty_ldisc_ops sp_ldisc = {
 	.owner		= THIS_MODULE,
 	.magic		= TTY_LDISC_MAGIC,
@@ -784,6 +802,9 @@ static struct tty_ldisc_ops sp_ldisc = {
 	.open		= sixpack_open,
 	.close		= sixpack_close,
 	.ioctl		= sixpack_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= sixpack_compat_ioctl,
+#endif
 	.receive_buf	= sixpack_receive_buf,
 	.write_wakeup	= sixpack_write_wakeup,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/baycom_epp.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/baycom_epp.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/baycom_epp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/baycom_epp.c	2010-02-24 13:52:17.000000000 -0500
@@ -596,16 +596,16 @@ static int receive(struct net_device *de
 					if (!(notbitstream & (0x1fc << j)))
 						state = 0;
 
-					/* not flag received */
-					else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) {
+					/* flag received */
+					else if ((bitstream & (0x1fe << j)) == (0x0fc << j)) {
 						if (state)
 							do_rxpacket(dev);
 						bc->hdlcrx.bufcnt = 0;
 						bc->hdlcrx.bufptr = bc->hdlcrx.buf;
 						state = 1;
 						numbits = 7-j;
-						}
 					}
+				}
 
 				/* stuffed bit */
 				else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/baycom_ser_fdx.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/baycom_ser_fdx.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/baycom_ser_fdx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/baycom_ser_fdx.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,7 @@
  *          driver only supports standard serial hardware (8250, 16450, 16550A)
  *
  *          This modem usually draws its supply current out of the otherwise unused
- *          TXD pin of the serial port. Thus a contignuous stream of 0x00-bytes
+ *          TXD pin of the serial port. Thus a contiguous stream of 0x00-bytes
  *          is transmitted to achieve a positive supply voltage.
  *
  *  hsk:    This is a 4800 baud FSK modem, designed for TNC use. It works fine
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/bpqether.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/bpqether.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/bpqether.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/bpqether.c	2010-02-24 13:52:17.000000000 -0500
@@ -167,10 +167,7 @@ static inline struct net_device *bpq_get
 
 static inline int dev_is_ethdev(struct net_device *dev)
 {
-	return (
-			dev->type == ARPHRD_ETHER
-			&& strncmp(dev->name, "dummy", 5)
-	);
+	return (dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
 }
 
 /* ------------------------------------------------------------------------ */
@@ -186,7 +183,7 @@ static int bpq_rcv(struct sk_buff *skb,
 	struct ethhdr *eth;
 	struct bpqdev *bpq;
 
-	if (dev_net(dev) != &init_net)
+	if (!net_eq(dev_net(dev), &init_net))
 		goto drop;
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
@@ -251,6 +248,7 @@ static netdev_tx_t bpq_xmit(struct sk_bu
 {
 	unsigned char *ptr;
 	struct bpqdev *bpq;
+	struct net_device *orig_dev;
 	int size;
 
 	/*
@@ -285,8 +283,9 @@ static netdev_tx_t bpq_xmit(struct sk_bu
 
 	bpq = netdev_priv(dev);
 
+	orig_dev = dev;
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
-		dev->stats.tx_dropped++;
+		orig_dev->stats.tx_dropped++;
 		kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -552,7 +551,7 @@ static int bpq_device_event(struct notif
 {
 	struct net_device *dev = (struct net_device *)ptr;
 
-	if (dev_net(dev) != &init_net)
+	if (!net_eq(dev_net(dev), &init_net))
 		return NOTIFY_DONE;
 
 	if (!dev_is_ethdev(dev))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/dmascc.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/dmascc.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/dmascc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/dmascc.c	2010-02-24 13:52:17.000000000 -0500
@@ -331,8 +331,8 @@ static int __init dmascc_init(void)
 			for (i = 0; i < MAX_NUM_DEVS && io[i]; i++) {
 				j = (io[i] -
 				     hw[h].io_region) / hw[h].io_delta;
-				if (j >= 0 && j < hw[h].num_devs
-				    && hw[h].io_region +
+				if (j >= 0 && j < hw[h].num_devs &&
+				    hw[h].io_region +
 				    j * hw[h].io_delta == io[i]) {
 					base[j] = io[i];
 				}
@@ -396,8 +396,8 @@ static int __init dmascc_init(void)
 					t_val =
 					    inb(t1[i]) + (inb(t1[i]) << 8);
 					/* Also check whether counter did wrap */
-					if (t_val == 0
-					    || t_val > TMR_0_HZ / HZ * 10)
+					if (t_val == 0 ||
+					    t_val > TMR_0_HZ / HZ * 10)
 						counting[i] = 0;
 					delay[i] = jiffies - start[i];
 				}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hamradio/mkiss.c linux-libre-2.6.33-gnu1/drivers/net/hamradio/mkiss.c
--- linux-libre-2.6.32-gnu1/drivers/net/hamradio/mkiss.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hamradio/mkiss.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/jiffies.h>
+#include <linux/compat.h>
 
 #include <net/ax25.h>
 
@@ -898,6 +899,23 @@ static int mkiss_ioctl(struct tty_struct
 	return err;
 }
 
+#ifdef CONFIG_COMPAT
+static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case SIOCGIFNAME:
+	case SIOCGIFENCAP:
+	case SIOCSIFENCAP:
+	case SIOCSIFHWADDR:
+		return mkiss_ioctl(tty, file, cmd,
+				   (unsigned long)compat_ptr(arg));
+	}
+
+	return -ENOIOCTLCMD;
+}
+#endif
+
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -972,6 +990,9 @@ static struct tty_ldisc_ops ax_ldisc = {
 	.open		= mkiss_open,
 	.close		= mkiss_close,
 	.ioctl		= mkiss_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= mkiss_compat_ioctl,
+#endif
 	.receive_buf	= mkiss_receive_buf,
 	.write_wakeup	= mkiss_write_wakeup
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hp100.c linux-libre-2.6.33-gnu1/drivers/net/hp100.c
--- linux-libre-2.6.32-gnu1/drivers/net/hp100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hp100.c	2010-02-24 13:52:17.000000000 -0500
@@ -993,8 +993,8 @@ static void hp100_mmuinit(struct net_dev
 	if (lp->mode == 1) {	/* only needed for Busmaster */
 		int xmit_stop, recv_stop;
 
-		if ((lp->chip == HP100_CHIPID_RAINIER)
-		    || (lp->chip == HP100_CHIPID_SHASTA)) {
+		if ((lp->chip == HP100_CHIPID_RAINIER) ||
+		    (lp->chip == HP100_CHIPID_SHASTA)) {
 			int pdl_stop;
 
 			/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/hp-plus.c linux-libre-2.6.33-gnu1/drivers/net/hp-plus.c
--- linux-libre-2.6.32-gnu1/drivers/net/hp-plus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/hp-plus.c	2010-02-24 13:52:17.000000000 -0500
@@ -187,8 +187,8 @@ static int __init hpp_probe1(struct net_
 		return -EBUSY;
 
 	/* Check for the HP+ signature, 50 48 0x 53. */
-	if (inw(ioaddr + HP_ID) != 0x4850
-		|| (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) {
+	if (inw(ioaddr + HP_ID) != 0x4850 ||
+	    (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) {
 		retval = -ENODEV;
 		goto out;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ibmlana.c linux-libre-2.6.33-gnu1/drivers/net/ibmlana.c
--- linux-libre-2.6.32-gnu1/drivers/net/ibmlana.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ibmlana.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,6 +87,7 @@ History:
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_ether.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 
@@ -988,7 +989,7 @@ static int __devinit ibmlana_init_one(st
 
 	/* copy out MAC address */
 
-	for (z = 0; z < sizeof(dev->dev_addr); z++)
+	for (z = 0; z < ETH_ALEN; z++)
 		dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z);
 
 	/* print config */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ibm_newemac/core.c linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.c
--- linux-libre-2.6.32-gnu1/drivers/net/ibm_newemac/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ibm_newemac/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -1976,27 +1976,27 @@ static int emac_ethtool_set_settings(str
 	if (cmd->autoneg == AUTONEG_DISABLE) {
 		switch (cmd->speed) {
 		case SPEED_10:
-			if (cmd->duplex == DUPLEX_HALF
-			    && !(f & SUPPORTED_10baseT_Half))
+			if (cmd->duplex == DUPLEX_HALF &&
+			    !(f & SUPPORTED_10baseT_Half))
 				return -EINVAL;
-			if (cmd->duplex == DUPLEX_FULL
-			    && !(f & SUPPORTED_10baseT_Full))
+			if (cmd->duplex == DUPLEX_FULL &&
+			    !(f & SUPPORTED_10baseT_Full))
 				return -EINVAL;
 			break;
 		case SPEED_100:
-			if (cmd->duplex == DUPLEX_HALF
-			    && !(f & SUPPORTED_100baseT_Half))
+			if (cmd->duplex == DUPLEX_HALF &&
+			    !(f & SUPPORTED_100baseT_Half))
 				return -EINVAL;
-			if (cmd->duplex == DUPLEX_FULL
-			    && !(f & SUPPORTED_100baseT_Full))
+			if (cmd->duplex == DUPLEX_FULL &&
+			    !(f & SUPPORTED_100baseT_Full))
 				return -EINVAL;
 			break;
 		case SPEED_1000:
-			if (cmd->duplex == DUPLEX_HALF
-			    && !(f & SUPPORTED_1000baseT_Half))
+			if (cmd->duplex == DUPLEX_HALF &&
+			    !(f & SUPPORTED_1000baseT_Half))
 				return -EINVAL;
-			if (cmd->duplex == DUPLEX_FULL
-			    && !(f & SUPPORTED_1000baseT_Full))
+			if (cmd->duplex == DUPLEX_FULL &&
+			    !(f & SUPPORTED_1000baseT_Full))
 				return -EINVAL;
 			break;
 		default:
@@ -2149,9 +2149,12 @@ static int emac_ethtool_nway_reset(struc
 	return res;
 }
 
-static int emac_ethtool_get_stats_count(struct net_device *ndev)
+static int emac_ethtool_get_sset_count(struct net_device *ndev, int stringset)
 {
-	return EMAC_ETHTOOL_STATS_COUNT;
+	if (stringset == ETH_SS_STATS)
+		return EMAC_ETHTOOL_STATS_COUNT;
+	else
+		return -EINVAL;
 }
 
 static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset,
@@ -2182,7 +2185,6 @@ static void emac_ethtool_get_drvinfo(str
 	info->fw_version[0] = '\0';
 	sprintf(info->bus_info, "PPC 4xx EMAC-%d %s",
 		dev->cell_index, dev->ofdev->node->full_name);
-	info->n_stats = emac_ethtool_get_stats_count(ndev);
 	info->regdump_len = emac_ethtool_get_regs_len(ndev);
 }
 
@@ -2202,7 +2204,7 @@ static const struct ethtool_ops emac_eth
 	.get_rx_csum = emac_ethtool_get_rx_csum,
 
 	.get_strings = emac_ethtool_get_strings,
-	.get_stats_count = emac_ethtool_get_stats_count,
+	.get_sset_count = emac_ethtool_get_sset_count,
 	.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
 
 	.get_link = ethtool_op_get_link,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ibmveth.c linux-libre-2.6.33-gnu1/drivers/net/ibmveth.c
--- linux-libre-2.6.32-gnu1/drivers/net/ibmveth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ibmveth.c	2010-02-24 13:52:17.000000000 -0500
@@ -625,7 +625,7 @@ static int ibmveth_open(struct net_devic
 	}
 
 	ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq);
-	if((rc = request_irq(netdev->irq, &ibmveth_interrupt, 0, netdev->name, netdev)) != 0) {
+	if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) {
 		ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc);
 		do {
 			rc = h_free_logical_lan(adapter->vdev->unit_address);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ifb.c linux-libre-2.6.33-gnu1/drivers/net/ifb.c
--- linux-libre-2.6.32-gnu1/drivers/net/ifb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ifb.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,14 +98,16 @@ static void ri_tasklet(unsigned long dev
 		stats->tx_packets++;
 		stats->tx_bytes +=skb->len;
 
-		skb->dev = dev_get_by_index(&init_net, skb->iif);
+		rcu_read_lock();
+		skb->dev = dev_get_by_index_rcu(&init_net, skb->skb_iif);
 		if (!skb->dev) {
+			rcu_read_unlock();
 			dev_kfree_skb(skb);
 			stats->tx_dropped++;
 			break;
 		}
-		dev_put(skb->dev);
-		skb->iif = _dev->ifindex;
+		rcu_read_unlock();
+		skb->skb_iif = _dev->ifindex;
 
 		if (from & AT_EGRESS) {
 			dp->st_rx_frm_egr++;
@@ -170,7 +172,7 @@ static netdev_tx_t ifb_xmit(struct sk_bu
 	stats->rx_packets++;
 	stats->rx_bytes+=skb->len;
 
-	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->iif) {
+	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
 		dev_kfree_skb(skb);
 		stats->rx_dropped++;
 		return NETDEV_TX_OK;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_82575.c linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_82575.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,10 @@ static s32  igb_get_cfg_done_82575(struc
 static s32  igb_init_hw_82575(struct e1000_hw *);
 static s32  igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
 static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
+static s32  igb_read_phy_reg_82580(struct e1000_hw *, u32, u16 *);
+static s32  igb_write_phy_reg_82580(struct e1000_hw *, u32, u16);
 static s32  igb_reset_hw_82575(struct e1000_hw *);
+static s32  igb_reset_hw_82580(struct e1000_hw *);
 static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
 static s32  igb_setup_copper_link_82575(struct e1000_hw *);
 static s32  igb_setup_serdes_link_82575(struct e1000_hw *);
@@ -62,6 +65,12 @@ static s32  igb_reset_init_script_82575(
 static s32  igb_read_mac_addr_82575(struct e1000_hw *);
 static s32  igb_set_pcie_completion_timeout(struct e1000_hw *hw);
 
+static const u16 e1000_82580_rxpbs_table[] =
+	{ 36, 72, 144, 1, 2, 4, 8, 16,
+	  35, 70, 140 };
+#define E1000_82580_RXPBS_TABLE_SIZE \
+	(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
@@ -81,12 +90,20 @@ static s32 igb_get_invariants_82575(stru
 		break;
 	case E1000_DEV_ID_82576:
 	case E1000_DEV_ID_82576_NS:
+	case E1000_DEV_ID_82576_NS_SERDES:
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
 	case E1000_DEV_ID_82576_QUAD_COPPER:
 	case E1000_DEV_ID_82576_SERDES_QUAD:
 		mac->type = e1000_82576;
 		break;
+	case E1000_DEV_ID_82580_COPPER:
+	case E1000_DEV_ID_82580_FIBER:
+	case E1000_DEV_ID_82580_SERDES:
+	case E1000_DEV_ID_82580_SGMII:
+	case E1000_DEV_ID_82580_COPPER_DUAL:
+		mac->type = e1000_82580;
+		break;
 	default:
 		return -E1000_ERR_MAC_INIT;
 		break;
@@ -109,6 +126,7 @@ static s32 igb_get_invariants_82575(stru
 		dev_spec->sgmii_active = true;
 		ctrl_ext |= E1000_CTRL_I2C_ENA;
 		break;
+	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;
 		ctrl_ext |= E1000_CTRL_I2C_ENA;
@@ -120,12 +138,26 @@ static s32 igb_get_invariants_82575(stru
 
 	wr32(E1000_CTRL_EXT, ctrl_ext);
 
+	/*
+	 * if using i2c make certain the MDICNFG register is cleared to prevent
+	 * communications from being misrouted to the mdic registers
+	 */
+	if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580))
+		wr32(E1000_MDICNFG, 0);
+
 	/* Set mta register count */
 	mac->mta_reg_count = 128;
 	/* Set rar entry count */
 	mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
 	if (mac->type == e1000_82576)
 		mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
+	if (mac->type == e1000_82580)
+		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
+	/* reset */
+	if (mac->type == e1000_82580)
+		mac->ops.reset_hw = igb_reset_hw_82580;
+	else
+		mac->ops.reset_hw = igb_reset_hw_82575;
 	/* Set if part includes ASF firmware */
 	mac->asf_firmware_present = true;
 	/* Set if manageability features are enabled. */
@@ -193,6 +225,10 @@ static s32 igb_get_invariants_82575(stru
 		phy->ops.reset              = igb_phy_hw_reset_sgmii_82575;
 		phy->ops.read_reg           = igb_read_phy_reg_sgmii_82575;
 		phy->ops.write_reg          = igb_write_phy_reg_sgmii_82575;
+	} else if (hw->mac.type == e1000_82580) {
+		phy->ops.reset              = igb_phy_hw_reset;
+		phy->ops.read_reg           = igb_read_phy_reg_82580;
+		phy->ops.write_reg          = igb_write_phy_reg_82580;
 	} else {
 		phy->ops.reset              = igb_phy_hw_reset;
 		phy->ops.read_reg           = igb_read_phy_reg_igp;
@@ -224,6 +260,12 @@ static s32 igb_get_invariants_82575(stru
 		phy->ops.set_d0_lplu_state  = igb_set_d0_lplu_state_82575;
 		phy->ops.set_d3_lplu_state  = igb_set_d3_lplu_state;
 		break;
+	case I82580_I_PHY_ID:
+		phy->type                   = e1000_phy_82580;
+		phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580;
+		phy->ops.get_cable_length   = igb_get_cable_length_82580;
+		phy->ops.get_phy_info       = igb_get_phy_info_82580;
+		break;
 	default:
 		return -E1000_ERR_PHY;
 	}
@@ -240,9 +282,10 @@ static s32 igb_get_invariants_82575(stru
  **/
 static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
 {
-	u16 mask;
+	u16 mask = E1000_SWFW_PHY0_SM;
 
-	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+	if (hw->bus.func == E1000_FUNC_1)
+		mask = E1000_SWFW_PHY1_SM;
 
 	return igb_acquire_swfw_sync_82575(hw, mask);
 }
@@ -256,9 +299,11 @@ static s32 igb_acquire_phy_82575(struct
  **/
 static void igb_release_phy_82575(struct e1000_hw *hw)
 {
-	u16 mask;
+	u16 mask = E1000_SWFW_PHY0_SM;
+
+	if (hw->bus.func == E1000_FUNC_1)
+		mask = E1000_SWFW_PHY1_SM;
 
-	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
 	igb_release_swfw_sync_82575(hw, mask);
 }
 
@@ -274,45 +319,23 @@ static void igb_release_phy_82575(struct
 static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
 					  u16 *data)
 {
-	struct e1000_phy_info *phy = &hw->phy;
-	u32 i, i2ccmd = 0;
+	s32 ret_val = -E1000_ERR_PARAM;
 
 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
 		hw_dbg("PHY Address %u is out of range\n", offset);
-		return -E1000_ERR_PARAM;
+		goto out;
 	}
 
-	/*
-	 * Set up Op-code, Phy Address, and register address in the I2CCMD
-	 * register.  The MAC will take care of interfacing with the
-	 * PHY to retrieve the desired data.
-	 */
-	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
-		  (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
-		  (E1000_I2CCMD_OPCODE_READ));
-
-	wr32(E1000_I2CCMD, i2ccmd);
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
 
-	/* Poll the ready bit to see if the I2C read completed */
-	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
-		udelay(50);
-		i2ccmd = rd32(E1000_I2CCMD);
-		if (i2ccmd & E1000_I2CCMD_READY)
-			break;
-	}
-	if (!(i2ccmd & E1000_I2CCMD_READY)) {
-		hw_dbg("I2CCMD Read did not complete\n");
-		return -E1000_ERR_PHY;
-	}
-	if (i2ccmd & E1000_I2CCMD_ERROR) {
-		hw_dbg("I2CCMD Error bit set\n");
-		return -E1000_ERR_PHY;
-	}
+	ret_val = igb_read_phy_reg_i2c(hw, offset, data);
 
-	/* Need to byte-swap the 16-bit value. */
-	*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
+	hw->phy.ops.release(hw);
 
-	return 0;
+out:
+	return ret_val;
 }
 
 /**
@@ -327,47 +350,24 @@ static s32 igb_read_phy_reg_sgmii_82575(
 static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
 					   u16 data)
 {
-	struct e1000_phy_info *phy = &hw->phy;
-	u32 i, i2ccmd = 0;
-	u16 phy_data_swapped;
+	s32 ret_val = -E1000_ERR_PARAM;
+
 
 	if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
 		hw_dbg("PHY Address %d is out of range\n", offset);
-		return -E1000_ERR_PARAM;
+		goto out;
 	}
 
-	/* Swap the data bytes for the I2C interface */
-	phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
-
-	/*
-	 * Set up Op-code, Phy Address, and register address in the I2CCMD
-	 * register.  The MAC will take care of interfacing with the
-	 * PHY to retrieve the desired data.
-	 */
-	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
-		  (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
-		  E1000_I2CCMD_OPCODE_WRITE |
-		  phy_data_swapped);
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
 
-	wr32(E1000_I2CCMD, i2ccmd);
+	ret_val = igb_write_phy_reg_i2c(hw, offset, data);
 
-	/* Poll the ready bit to see if the I2C read completed */
-	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
-		udelay(50);
-		i2ccmd = rd32(E1000_I2CCMD);
-		if (i2ccmd & E1000_I2CCMD_READY)
-			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;
-	}
+	hw->phy.ops.release(hw);
 
-	return 0;
+out:
+	return ret_val;
 }
 
 /**
@@ -676,6 +676,10 @@ static s32 igb_get_cfg_done_82575(struct
 
 	if (hw->bus.func == 1)
 		mask = E1000_NVM_CFG_DONE_PORT_1;
+	else if (hw->bus.func == E1000_FUNC_2)
+		mask = E1000_NVM_CFG_DONE_PORT_2;
+	else if (hw->bus.func == E1000_FUNC_3)
+		mask = E1000_NVM_CFG_DONE_PORT_3;
 
 	while (timeout) {
 		if (rd32(E1000_EEMNGCTL) & mask)
@@ -706,9 +710,7 @@ static s32 igb_check_for_link_82575(stru
 	s32 ret_val;
 	u16 speed, duplex;
 
-	/* SGMII link check is done through the PCS register. */
-	if ((hw->phy.media_type != e1000_media_type_copper) ||
-	    (igb_sgmii_active_82575(hw))) {
+	if (hw->phy.media_type != e1000_media_type_copper) {
 		ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
 		                                             &duplex);
 		/*
@@ -723,6 +725,7 @@ static s32 igb_check_for_link_82575(stru
 
 	return ret_val;
 }
+
 /**
  *  igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
  *  @hw: pointer to the HW structure
@@ -788,13 +791,27 @@ static s32 igb_get_pcs_speed_and_duplex_
 void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
 {
 	u32 reg;
+	u16 eeprom_data = 0;
 
 	if (hw->phy.media_type != e1000_media_type_internal_serdes ||
 	    igb_sgmii_active_82575(hw))
 		return;
 
-	/* if the management interface is not enabled, then power down */
-	if (!igb_enable_mng_pass_thru(hw)) {
+	if (hw->bus.func == E1000_FUNC_0)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+	else if (hw->mac.type == e1000_82580)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
+		                 NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
+		                 &eeprom_data);
+	else if (hw->bus.func == E1000_FUNC_1)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+
+	/*
+	 * If APM is not enabled in the EEPROM and management interface is
+	 * not enabled, then power down.
+	 */
+	if (!(eeprom_data & E1000_NVM_APME_82575) &&
+	    !igb_enable_mng_pass_thru(hw)) {
 		/* Disable PCS to turn off link */
 		reg = rd32(E1000_PCS_CFG0);
 		reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -908,6 +925,11 @@ static s32 igb_init_hw_82575(struct e100
 	for (i = 0; i < mac->mta_reg_count; i++)
 		array_wr32(E1000_MTA, i, 0);
 
+	/* Zero out the Unicast HASH table */
+	hw_dbg("Zeroing the UTA\n");
+	for (i = 0; i < mac->uta_reg_count; i++)
+		array_wr32(E1000_UTA, i, 0);
+
 	/* Setup link and flow control */
 	ret_val = igb_setup_link(hw);
 
@@ -934,7 +956,6 @@ static s32 igb_setup_copper_link_82575(s
 {
 	u32 ctrl;
 	s32  ret_val;
-	bool link;
 
 	ctrl = rd32(E1000_CTRL);
 	ctrl |= E1000_CTRL_SLU;
@@ -946,6 +967,9 @@ static s32 igb_setup_copper_link_82575(s
 		goto out;
 
 	if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
+		/* allow time for SFP cage time to power up phy */
+		msleep(300);
+
 		ret_val = hw->phy.ops.reset(hw);
 		if (ret_val) {
 			hw_dbg("Error resetting the PHY.\n");
@@ -959,6 +983,9 @@ static s32 igb_setup_copper_link_82575(s
 	case e1000_phy_igp_3:
 		ret_val = igb_copper_link_setup_igp(hw);
 		break;
+	case e1000_phy_82580:
+		ret_val = igb_copper_link_setup_82580(hw);
+		break;
 	default:
 		ret_val = -E1000_ERR_PHY;
 		break;
@@ -967,57 +994,24 @@ static s32 igb_setup_copper_link_82575(s
 	if (ret_val)
 		goto out;
 
-	if (hw->mac.autoneg) {
-		/*
-		 * Setup autoneg and flow control advertisement
-		 * and perform autonegotiation.
-		 */
-		ret_val = igb_copper_link_autoneg(hw);
-		if (ret_val)
-			goto out;
-	} else {
-		/*
-		 * PHY will be set to 10H, 10F, 100H or 100F
-		 * depending on user settings.
-		 */
-		hw_dbg("Forcing Speed and Duplex\n");
-		ret_val = hw->phy.ops.force_speed_duplex(hw);
-		if (ret_val) {
-			hw_dbg("Error Forcing Speed and Duplex\n");
-			goto out;
-		}
-	}
-
-	/*
-	 * Check link status. Wait up to 100 microseconds for link to become
-	 * valid.
-	 */
-	ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
-	if (ret_val)
-		goto out;
-
-	if (link) {
-		hw_dbg("Valid link established!!!\n");
-		/* Config the MAC and PHY after link is up */
-		igb_config_collision_dist(hw);
-		ret_val = igb_config_fc_after_link_up(hw);
-	} else {
-		hw_dbg("Unable to establish link!!!\n");
-	}
-
+	ret_val = igb_setup_copper_link(hw);
 out:
 	return ret_val;
 }
 
 /**
- *  igb_setup_serdes_link_82575 - Setup link for fiber/serdes
+ *  igb_setup_serdes_link_82575 - Setup link for serdes
  *  @hw: pointer to the HW structure
  *
- *  Configures speed and duplex for fiber and serdes links.
+ *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
+ *  used on copper connections where the serialized gigabit media independent
+ *  interface (sgmii), or serdes fiber is being used.  Configures the link
+ *  for auto-negotiation or forces speed/duplex.
  **/
 static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
 {
-	u32 ctrl_reg, reg;
+	u32 ctrl_ext, ctrl_reg, reg;
+	bool pcs_autoneg;
 
 	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
 	    !igb_sgmii_active_82575(hw))
@@ -1032,9 +1026,9 @@ static s32 igb_setup_serdes_link_82575(s
 	wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
 
 	/* power on the sfp cage if present */
-	reg = rd32(E1000_CTRL_EXT);
-	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
-	wr32(E1000_CTRL_EXT, reg);
+	ctrl_ext = rd32(E1000_CTRL_EXT);
+	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
+	wr32(E1000_CTRL_EXT, ctrl_ext);
 
 	ctrl_reg = rd32(E1000_CTRL);
 	ctrl_reg |= E1000_CTRL_SLU;
@@ -1051,15 +1045,31 @@ static s32 igb_setup_serdes_link_82575(s
 
 	reg = rd32(E1000_PCS_LCTL);
 
-	if (igb_sgmii_active_82575(hw)) {
-		/* allow time for SFP cage to power up phy */
-		msleep(300);
+	/* default pcs_autoneg to the same setting as mac autoneg */
+	pcs_autoneg = hw->mac.autoneg;
 
-		/* AN time out should be disabled for SGMII mode */
+	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
+	case E1000_CTRL_EXT_LINK_MODE_SGMII:
+		/* sgmii mode lets the phy handle forcing speed/duplex */
+		pcs_autoneg = true;
+		/* autoneg time out should be disabled for SGMII mode */
 		reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
-	} else {
+		break;
+	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
+		/* disable PCS autoneg and support parallel detect only */
+		pcs_autoneg = false;
+	default:
+		/*
+		 * non-SGMII modes only supports a speed of 1000/Full for the
+		 * link so it is best to just force the MAC and let the pcs
+		 * link either autoneg or be forced to 1000/Full
+		 */
 		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
 		            E1000_CTRL_FD | E1000_CTRL_FRCDPX;
+
+		/* set speed of 1000/Full if speed/duplex is forced */
+		reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
+		break;
 	}
 
 	wr32(E1000_CTRL, ctrl_reg);
@@ -1070,7 +1080,6 @@ static s32 igb_setup_serdes_link_82575(s
 	 * mode that will be compatible with older link partners and switches.
 	 * However, both are supported by the hardware and some drivers/tools.
 	 */
-
 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
 		E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
 
@@ -1080,25 +1089,16 @@ static s32 igb_setup_serdes_link_82575(s
 	 */
 	reg |= E1000_PCS_LCTL_FORCE_FCTRL;
 
-	/*
-	 * we always set sgmii to autoneg since it is the phy that will be
-	 * forcing the link and the serdes is just a go-between
-	 */
-	if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
+	if (pcs_autoneg) {
 		/* Set PCS register for autoneg */
-		reg |= E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
-		       E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
-		       E1000_PCS_LCTL_AN_ENABLE |     /* Enable Autoneg */
-		       E1000_PCS_LCTL_AN_RESTART;     /* Restart autoneg */
-		hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
+		reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
+		       E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
+		hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
 	} else {
-		/* Set PCS register for forced speed */
-		reg |= E1000_PCS_LCTL_FLV_LINK_UP |   /* Force link up */
-		       E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
-		       E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
-		       E1000_PCS_LCTL_FSD |           /* Force Speed */
-		       E1000_PCS_LCTL_FORCE_LINK;     /* Force Link */
-		hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
+		/* Set PCS register for forced link */
+		reg |= E1000_PCS_LCTL_FSD;        /* Force Speed */
+
+		hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
 	}
 
 	wr32(E1000_PCS_LCTL, reg);
@@ -1167,9 +1167,18 @@ static s32 igb_read_mac_addr_82575(struc
 {
 	s32 ret_val = 0;
 
-	if (igb_check_alt_mac_addr(hw))
-		ret_val = igb_read_mac_addr(hw);
+	/*
+	 * If there's an alternate MAC address place it in RAR0
+	 * so that it will override the Si installed default perm
+	 * address.
+	 */
+	ret_val = igb_check_alt_mac_addr(hw);
+	if (ret_val)
+		goto out;
 
+	ret_val = igb_read_mac_addr(hw);
+
+out:
 	return ret_val;
 }
 
@@ -1181,61 +1190,59 @@ static s32 igb_read_mac_addr_82575(struc
  **/
 static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
 {
-	u32 temp;
-
 	igb_clear_hw_cntrs_base(hw);
 
-	temp = rd32(E1000_PRC64);
-	temp = rd32(E1000_PRC127);
-	temp = rd32(E1000_PRC255);
-	temp = rd32(E1000_PRC511);
-	temp = rd32(E1000_PRC1023);
-	temp = rd32(E1000_PRC1522);
-	temp = rd32(E1000_PTC64);
-	temp = rd32(E1000_PTC127);
-	temp = rd32(E1000_PTC255);
-	temp = rd32(E1000_PTC511);
-	temp = rd32(E1000_PTC1023);
-	temp = rd32(E1000_PTC1522);
+	rd32(E1000_PRC64);
+	rd32(E1000_PRC127);
+	rd32(E1000_PRC255);
+	rd32(E1000_PRC511);
+	rd32(E1000_PRC1023);
+	rd32(E1000_PRC1522);
+	rd32(E1000_PTC64);
+	rd32(E1000_PTC127);
+	rd32(E1000_PTC255);
+	rd32(E1000_PTC511);
+	rd32(E1000_PTC1023);
+	rd32(E1000_PTC1522);
 
-	temp = rd32(E1000_ALGNERRC);
-	temp = rd32(E1000_RXERRC);
-	temp = rd32(E1000_TNCRS);
-	temp = rd32(E1000_CEXTERR);
-	temp = rd32(E1000_TSCTC);
-	temp = rd32(E1000_TSCTFC);
+	rd32(E1000_ALGNERRC);
+	rd32(E1000_RXERRC);
+	rd32(E1000_TNCRS);
+	rd32(E1000_CEXTERR);
+	rd32(E1000_TSCTC);
+	rd32(E1000_TSCTFC);
 
-	temp = rd32(E1000_MGTPRC);
-	temp = rd32(E1000_MGTPDC);
-	temp = rd32(E1000_MGTPTC);
+	rd32(E1000_MGTPRC);
+	rd32(E1000_MGTPDC);
+	rd32(E1000_MGTPTC);
 
-	temp = rd32(E1000_IAC);
-	temp = rd32(E1000_ICRXOC);
+	rd32(E1000_IAC);
+	rd32(E1000_ICRXOC);
 
-	temp = rd32(E1000_ICRXPTC);
-	temp = rd32(E1000_ICRXATC);
-	temp = rd32(E1000_ICTXPTC);
-	temp = rd32(E1000_ICTXATC);
-	temp = rd32(E1000_ICTXQEC);
-	temp = rd32(E1000_ICTXQMTC);
-	temp = rd32(E1000_ICRXDMTC);
+	rd32(E1000_ICRXPTC);
+	rd32(E1000_ICRXATC);
+	rd32(E1000_ICTXPTC);
+	rd32(E1000_ICTXATC);
+	rd32(E1000_ICTXQEC);
+	rd32(E1000_ICTXQMTC);
+	rd32(E1000_ICRXDMTC);
 
-	temp = rd32(E1000_CBTMPC);
-	temp = rd32(E1000_HTDPMC);
-	temp = rd32(E1000_CBRMPC);
-	temp = rd32(E1000_RPTHC);
-	temp = rd32(E1000_HGPTC);
-	temp = rd32(E1000_HTCBDPC);
-	temp = rd32(E1000_HGORCL);
-	temp = rd32(E1000_HGORCH);
-	temp = rd32(E1000_HGOTCL);
-	temp = rd32(E1000_HGOTCH);
-	temp = rd32(E1000_LENERRS);
+	rd32(E1000_CBTMPC);
+	rd32(E1000_HTDPMC);
+	rd32(E1000_CBRMPC);
+	rd32(E1000_RPTHC);
+	rd32(E1000_HGPTC);
+	rd32(E1000_HTCBDPC);
+	rd32(E1000_HGORCL);
+	rd32(E1000_HGORCH);
+	rd32(E1000_HGOTCL);
+	rd32(E1000_HGOTCH);
+	rd32(E1000_LENERRS);
 
 	/* This register should not be read in copper configurations */
 	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
 	    igb_sgmii_active_82575(hw))
-		temp = rd32(E1000_SCVPC);
+		rd32(E1000_SCVPC);
 }
 
 /**
@@ -1400,8 +1407,183 @@ void igb_vmdq_set_replication_pf(struct
 	wr32(E1000_VT_CTL, vt_ctl);
 }
 
+/**
+ *  igb_read_phy_reg_82580 - Read 82580 MDI control register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the MDI control register in the PHY at offset and stores the
+ *  information read to data.
+ **/
+static s32 igb_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+	u32 mdicnfg = 0;
+	s32 ret_val;
+
+
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
+
+	/*
+	 * We config the phy address in MDICNFG register now. Same bits
+	 * as before. The values in MDIC can be written but will be
+	 * ignored. This allows us to call the old function after
+	 * configuring the PHY address in the new register
+	 */
+	mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT);
+	wr32(E1000_MDICNFG, mdicnfg);
+
+	ret_val = igb_read_phy_reg_mdic(hw, offset, data);
+
+	hw->phy.ops.release(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  igb_write_phy_reg_82580 - Write 82580 MDI control register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write to register at offset
+ *
+ *  Writes data to MDI control register in the PHY at offset.
+ **/
+static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data)
+{
+	u32 mdicnfg = 0;
+	s32 ret_val;
+
+
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		goto out;
+
+	/*
+	 * We config the phy address in MDICNFG register now. Same bits
+	 * as before. The values in MDIC can be written but will be
+	 * ignored. This allows us to call the old function after
+	 * configuring the PHY address in the new register
+	 */
+	mdicnfg = (hw->phy.addr << E1000_MDIC_PHY_SHIFT);
+	wr32(E1000_MDICNFG, mdicnfg);
+
+	ret_val = igb_write_phy_reg_mdic(hw, offset, data);
+
+	hw->phy.ops.release(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  igb_reset_hw_82580 - Reset hardware
+ *  @hw: pointer to the HW structure
+ *
+ *  This resets function or entire device (all ports, etc.)
+ *  to a known state.
+ **/
+static s32 igb_reset_hw_82580(struct e1000_hw *hw)
+{
+	s32 ret_val = 0;
+	/* BH SW mailbox bit in SW_FW_SYNC */
+	u16 swmbsw_mask = E1000_SW_SYNCH_MB;
+	u32 ctrl, icr;
+	bool global_device_reset = hw->dev_spec._82575.global_device_reset;
+
+
+	hw->dev_spec._82575.global_device_reset = false;
+
+	/* Get current control state. */
+	ctrl = rd32(E1000_CTRL);
+
+	/*
+	 * Prevent the PCI-E bus from sticking if there is no TLP connection
+	 * on the last TLP read/write transaction when MAC is reset.
+	 */
+	ret_val = igb_disable_pcie_master(hw);
+	if (ret_val)
+		hw_dbg("PCI-E Master disable polling has failed.\n");
+
+	hw_dbg("Masking off all interrupts\n");
+	wr32(E1000_IMC, 0xffffffff);
+	wr32(E1000_RCTL, 0);
+	wr32(E1000_TCTL, E1000_TCTL_PSP);
+	wrfl();
+
+	msleep(10);
+
+	/* Determine whether or not a global dev reset is requested */
+	if (global_device_reset &&
+		igb_acquire_swfw_sync_82575(hw, swmbsw_mask))
+			global_device_reset = false;
+
+	if (global_device_reset &&
+		!(rd32(E1000_STATUS) & E1000_STAT_DEV_RST_SET))
+		ctrl |= E1000_CTRL_DEV_RST;
+	else
+		ctrl |= E1000_CTRL_RST;
+
+	wr32(E1000_CTRL, ctrl);
+
+	/* Add delay to insure DEV_RST has time to complete */
+	if (global_device_reset)
+		msleep(5);
+
+	ret_val = igb_get_auto_rd_done(hw);
+	if (ret_val) {
+		/*
+		 * When auto config read does not complete, do not
+		 * return with an error. This can happen in situations
+		 * where there is no eeprom and prevents getting link.
+		 */
+		hw_dbg("Auto Read Done did not complete\n");
+	}
+
+	/* If EEPROM is not present, run manual init scripts */
+	if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0)
+		igb_reset_init_script_82575(hw);
+
+	/* clear global device reset status bit */
+	wr32(E1000_STATUS, E1000_STAT_DEV_RST_SET);
+
+	/* Clear any pending interrupt events. */
+	wr32(E1000_IMC, 0xffffffff);
+	icr = rd32(E1000_ICR);
+
+	/* Install any alternate MAC address into RAR0 */
+	ret_val = igb_check_alt_mac_addr(hw);
+
+	/* Release semaphore */
+	if (global_device_reset)
+		igb_release_swfw_sync_82575(hw, swmbsw_mask);
+
+	return ret_val;
+}
+
+/**
+ *  igb_rxpbs_adjust_82580 - adjust RXPBS value to reflect actual RX PBA size
+ *  @data: data received by reading RXPBS register
+ *
+ *  The 82580 uses a table based approach for packet buffer allocation sizes.
+ *  This function converts the retrieved value into the correct table value
+ *     0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
+ *  0x0 36  72 144   1   2   4   8  16
+ *  0x8 35  70 140 rsv rsv rsv rsv rsv
+ */
+u16 igb_rxpbs_adjust_82580(u32 data)
+{
+	u16 ret_val = 0;
+
+	if (data < E1000_82580_RXPBS_TABLE_SIZE)
+		ret_val = e1000_82580_rxpbs_table[data];
+
+	return ret_val;
+}
+
 static struct e1000_mac_operations e1000_mac_ops_82575 = {
-	.reset_hw             = igb_reset_hw_82575,
 	.init_hw              = igb_init_hw_82575,
 	.check_for_link       = igb_check_for_link_82575,
 	.rar_set              = igb_rar_set,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_82575.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_82575.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_82575.h	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,11 @@ extern void igb_rx_fifo_flush_82575(stru
 
 #define E1000_RAR_ENTRIES_82575   16
 #define E1000_RAR_ENTRIES_82576   24
+#define E1000_RAR_ENTRIES_82580   24
+
+#define E1000_SW_SYNCH_MB              0x00000100
+#define E1000_STAT_DEV_RST_SET         0x00100000
+#define E1000_CTRL_DEV_RST             0x20000000
 
 /* SRRCTL bit definitions */
 #define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
@@ -66,6 +71,8 @@ extern void igb_rx_fifo_flush_82575(stru
     E1000_EICR_RX_QUEUE3)
 
 /* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
+#define E1000_IMIREXT_SIZE_BP     0x00001000  /* Packet size bypass */
+#define E1000_IMIREXT_CTRL_BP     0x00080000  /* Bypass check of ctrl bits */
 
 /* Receive Descriptor - Advanced */
 union e1000_adv_rx_desc {
@@ -98,6 +105,7 @@ union e1000_adv_rx_desc {
 
 #define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
 #define E1000_RXDADV_HDRBUFLEN_SHIFT     5
+#define E1000_RXDADV_STAT_TS             0x10000 /* Pkt was time stamped */
 
 /* Transmit Descriptor - Advanced */
 union e1000_adv_tx_desc {
@@ -167,6 +175,18 @@ struct e1000_adv_tx_context_desc {
 #define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
 #define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
 
+/* ETQF register bit definitions */
+#define E1000_ETQF_FILTER_ENABLE   (1 << 26)
+#define E1000_ETQF_1588            (1 << 30)
+
+/* FTQF register bit definitions */
+#define E1000_FTQF_VF_BP               0x00008000
+#define E1000_FTQF_1588_TIME_STAMP     0x08000000
+#define E1000_FTQF_MASK                0xF0000000
+#define E1000_FTQF_MASK_PROTO_BP       0x10000000
+#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
+
+#define E1000_NVM_APME_82575          0x0400
 #define MAX_NUM_VFS                   8
 
 #define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31)  /* global VF LB enable */
@@ -202,9 +222,21 @@ struct e1000_adv_tx_context_desc {
 #define E1000_IOVCTL 0x05BBC
 #define E1000_IOVCTL_REUSE_VFQ 0x00000001
 
+#define E1000_RPLOLR_STRVLAN   0x40000000
+#define E1000_RPLOLR_STRCRC    0x80000000
+
+#define E1000_DTXCTL_8023LL     0x0004
+#define E1000_DTXCTL_VLAN_ADDED 0x0008
+#define E1000_DTXCTL_OOS_ENABLE 0x0010
+#define E1000_DTXCTL_MDP_EN     0x0020
+#define E1000_DTXCTL_SPOOF_INT  0x0040
+
 #define ALL_QUEUES   0xFFFF
 
+/* RX packet buffer size defines */
+#define E1000_RXPBS_SIZE_MASK_82576  0x0000007F
 void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
 void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
+u16 igb_rxpbs_adjust_82580(u32 data);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_defines.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_defines.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_defines.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_defines.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,7 @@
 #define E1000_CTRL_EXT_PFRSTD    0x00004000
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
 #define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES  0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX  0x00400000
 #define E1000_CTRL_EXT_LINK_MODE_SGMII   0x00800000
 #define E1000_CTRL_EXT_EIAME          0x01000000
 #define E1000_CTRL_EXT_IRCA           0x00000001
@@ -329,6 +330,7 @@
 #define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
 #define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
 #define E1000_ICR_VMMB          0x00000100 /* VM MB event */
+#define E1000_ICR_DRSTA         0x40000000 /* Device Reset Asserted */
 /* If this bit asserted, the driver should claim the interrupt */
 #define E1000_ICR_INT_ASSERTED  0x80000000
 /* LAN connected device generates an interrupt */
@@ -370,6 +372,7 @@
 #define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
 #define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
 #define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMS_DRSTA     E1000_ICR_DRSTA     /* Device Reset Asserted */
 #define E1000_IMS_DOUTSYNC  E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
 
 /* Extended Interrupt Mask Set */
@@ -378,6 +381,7 @@
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_DRSTA     E1000_ICR_DRSTA     /* Device Reset Aserted */
 
 /* Extended Interrupt Cause Set */
 
@@ -435,6 +439,39 @@
 /* Flow Control */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
+#define E1000_TSYNCTXCTL_VALID    0x00000001 /* tx timestamp valid */
+#define E1000_TSYNCTXCTL_ENABLED  0x00000010 /* enable tx timestampping */
+
+#define E1000_TSYNCRXCTL_VALID      0x00000001 /* rx timestamp valid */
+#define E1000_TSYNCRXCTL_TYPE_MASK  0x0000000E /* rx type mask */
+#define E1000_TSYNCRXCTL_TYPE_L2_V2       0x00
+#define E1000_TSYNCRXCTL_TYPE_L4_V1       0x02
+#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2    0x04
+#define E1000_TSYNCRXCTL_TYPE_ALL         0x08
+#define E1000_TSYNCRXCTL_TYPE_EVENT_V2    0x0A
+#define E1000_TSYNCRXCTL_ENABLED    0x00000010 /* enable rx timestampping */
+
+#define E1000_TSYNCRXCFG_PTP_V1_CTRLT_MASK   0x000000FF
+#define E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE       0x00
+#define E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE  0x01
+#define E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE   0x02
+#define E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE 0x03
+#define E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE 0x04
+
+#define E1000_TSYNCRXCFG_PTP_V2_MSGID_MASK               0x00000F00
+#define E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE                 0x0000
+#define E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE            0x0100
+#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE       0x0200
+#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE      0x0300
+#define E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE             0x0800
+#define E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE           0x0900
+#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE  0x0A00
+#define E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE             0x0B00
+#define E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE           0x0C00
+#define E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE           0x0D00
+
+#define E1000_TIMINCA_16NS_SHIFT 24
+
 /* PCI Express Control */
 #define E1000_GCR_CMPL_TMOUT_MASK       0x0000F000
 #define E1000_GCR_CMPL_TMOUT_10ms       0x00001000
@@ -524,8 +561,12 @@
 #define NVM_ALT_MAC_ADDR_PTR       0x0037
 #define NVM_CHECKSUM_REG           0x003F
 
-#define E1000_NVM_CFG_DONE_PORT_0  0x40000 /* MNG config cycle done */
-#define E1000_NVM_CFG_DONE_PORT_1  0x80000 /* ...for second port */
+#define E1000_NVM_CFG_DONE_PORT_0  0x040000 /* MNG config cycle done */
+#define E1000_NVM_CFG_DONE_PORT_1  0x080000 /* ...for second port */
+#define E1000_NVM_CFG_DONE_PORT_2  0x100000 /* ...for third port */
+#define E1000_NVM_CFG_DONE_PORT_3  0x200000 /* ...for fourth port */
+
+#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0)
 
 /* Mask bits for fields in Word 0x0f of the NVM */
 #define NVM_WORD0F_PAUSE_MASK       0x3000
@@ -592,6 +633,7 @@
  */
 #define M88E1111_I_PHY_ID    0x01410CC0
 #define IGP03E1000_E_PHY_ID  0x02A80390
+#define I82580_I_PHY_ID      0x015403A0
 #define M88_VENDOR           0x0141
 
 /* M88E1000 Specific Registers */
@@ -678,4 +720,8 @@
 #define E1000_VFTA_ENTRY_MASK                0x7F
 #define E1000_VFTA_ENTRY_BIT_SHIFT_MASK      0x1F
 
+/* DMA Coalescing register fields */
+#define E1000_PCIEMISC_LX_DECISION      0x00000080 /* Lx power decision based
+                                                      on DMA coal */
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_hw.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,20 +42,35 @@ struct e1000_hw;
 #define E1000_DEV_ID_82576_SERDES             0x10E7
 #define E1000_DEV_ID_82576_QUAD_COPPER        0x10E8
 #define E1000_DEV_ID_82576_NS                 0x150A
+#define E1000_DEV_ID_82576_NS_SERDES          0x1518
 #define E1000_DEV_ID_82576_SERDES_QUAD        0x150D
 #define E1000_DEV_ID_82575EB_COPPER           0x10A7
 #define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
 #define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
+#define E1000_DEV_ID_82580_COPPER             0x150E
+#define E1000_DEV_ID_82580_FIBER              0x150F
+#define E1000_DEV_ID_82580_SERDES             0x1510
+#define E1000_DEV_ID_82580_SGMII              0x1511
+#define E1000_DEV_ID_82580_COPPER_DUAL        0x1516
 
 #define E1000_REVISION_2 2
 #define E1000_REVISION_4 4
 
+#define E1000_FUNC_0     0
 #define E1000_FUNC_1     1
+#define E1000_FUNC_2     2
+#define E1000_FUNC_3     3
+
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0   0
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1   3
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2   6
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3   9
 
 enum e1000_mac_type {
 	e1000_undefined = 0,
 	e1000_82575,
 	e1000_82576,
+	e1000_82580,
 	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
 };
 
@@ -70,7 +85,6 @@ enum e1000_nvm_type {
 	e1000_nvm_unknown = 0,
 	e1000_nvm_none,
 	e1000_nvm_eeprom_spi,
-	e1000_nvm_eeprom_microwire,
 	e1000_nvm_flash_hw,
 	e1000_nvm_flash_sw
 };
@@ -79,8 +93,6 @@ enum e1000_nvm_override {
 	e1000_nvm_override_none = 0,
 	e1000_nvm_override_spi_small,
 	e1000_nvm_override_spi_large,
-	e1000_nvm_override_microwire_small,
-	e1000_nvm_override_microwire_large
 };
 
 enum e1000_phy_type {
@@ -92,6 +104,7 @@ enum e1000_phy_type {
 	e1000_phy_gg82563,
 	e1000_phy_igp_3,
 	e1000_phy_ife,
+	e1000_phy_82580,
 };
 
 enum e1000_bus_type {
@@ -288,6 +301,7 @@ struct e1000_mac_operations {
 
 struct e1000_phy_operations {
 	s32  (*acquire)(struct e1000_hw *);
+	s32  (*check_polarity)(struct e1000_hw *);
 	s32  (*check_reset_block)(struct e1000_hw *);
 	s32  (*force_speed_duplex)(struct e1000_hw *);
 	s32  (*get_cfg_done)(struct e1000_hw *hw);
@@ -339,6 +353,7 @@ struct e1000_mac_info {
 	u16 ifs_ratio;
 	u16 ifs_step_size;
 	u16 mta_reg_count;
+	u16 uta_reg_count;
 
 	/* Maximum size of the MTA register table in all supported adapters */
 	#define MAX_MTA_REG 128
@@ -463,6 +478,7 @@ struct e1000_mbx_info {
 
 struct e1000_dev_spec_82575 {
 	bool sgmii_active;
+	bool global_device_reset;
 };
 
 struct e1000_hw {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mac.c linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_
 	}
 
 	if (nvm_alt_mac_addr_offset == 0xFFFF) {
-		ret_val = -(E1000_NOT_IMPLEMENTED);
+		/* There is no Alternate MAC Address */
 		goto out;
 	}
 
 	if (hw->bus.func == E1000_FUNC_1)
-		nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16);
-
+		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
 	for (i = 0; i < ETH_ALEN; i += 2) {
 		offset = nvm_alt_mac_addr_offset + (i >> 1);
 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
@@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_
 
 	/* if multicast bit is set, the alternate address will not be used */
 	if (alt_mac_addr[0] & 0x01) {
-		ret_val = -(E1000_NOT_IMPLEMENTED);
+		hw_dbg("Ignoring Alternate Mac Address with MC bit set\n");
 		goto out;
 	}
 
-	for (i = 0; i < ETH_ALEN; i++)
-		hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
-
-	hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
+	/*
+	 * We have a valid alternate MAC address, and we want to treat it the
+	 * same as the normal permanent MAC address stored by the HW into the
+	 * RAR. Do this by mapping this address into RAR0.
+	 */
+	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
 
 out:
 	return ret_val;
@@ -246,8 +247,15 @@ void igb_rar_set(struct e1000_hw *hw, u8
 	if (rar_low || rar_high)
 		rar_high |= E1000_RAH_AV;
 
+	/*
+	 * Some bridges will combine consecutive 32-bit writes into
+	 * a single burst write, which will malfunction on some parts.
+	 * The flushes avoid this.
+	 */
 	wr32(E1000_RAL(index), rar_low);
+	wrfl();
 	wr32(E1000_RAH(index), rar_high);
+	wrfl();
 }
 
 /**
@@ -399,45 +407,43 @@ void igb_update_mc_addr_list(struct e100
  **/
 void igb_clear_hw_cntrs_base(struct e1000_hw *hw)
 {
-	u32 temp;
-
-	temp = rd32(E1000_CRCERRS);
-	temp = rd32(E1000_SYMERRS);
-	temp = rd32(E1000_MPC);
-	temp = rd32(E1000_SCC);
-	temp = rd32(E1000_ECOL);
-	temp = rd32(E1000_MCC);
-	temp = rd32(E1000_LATECOL);
-	temp = rd32(E1000_COLC);
-	temp = rd32(E1000_DC);
-	temp = rd32(E1000_SEC);
-	temp = rd32(E1000_RLEC);
-	temp = rd32(E1000_XONRXC);
-	temp = rd32(E1000_XONTXC);
-	temp = rd32(E1000_XOFFRXC);
-	temp = rd32(E1000_XOFFTXC);
-	temp = rd32(E1000_FCRUC);
-	temp = rd32(E1000_GPRC);
-	temp = rd32(E1000_BPRC);
-	temp = rd32(E1000_MPRC);
-	temp = rd32(E1000_GPTC);
-	temp = rd32(E1000_GORCL);
-	temp = rd32(E1000_GORCH);
-	temp = rd32(E1000_GOTCL);
-	temp = rd32(E1000_GOTCH);
-	temp = rd32(E1000_RNBC);
-	temp = rd32(E1000_RUC);
-	temp = rd32(E1000_RFC);
-	temp = rd32(E1000_ROC);
-	temp = rd32(E1000_RJC);
-	temp = rd32(E1000_TORL);
-	temp = rd32(E1000_TORH);
-	temp = rd32(E1000_TOTL);
-	temp = rd32(E1000_TOTH);
-	temp = rd32(E1000_TPR);
-	temp = rd32(E1000_TPT);
-	temp = rd32(E1000_MPTC);
-	temp = rd32(E1000_BPTC);
+	rd32(E1000_CRCERRS);
+	rd32(E1000_SYMERRS);
+	rd32(E1000_MPC);
+	rd32(E1000_SCC);
+	rd32(E1000_ECOL);
+	rd32(E1000_MCC);
+	rd32(E1000_LATECOL);
+	rd32(E1000_COLC);
+	rd32(E1000_DC);
+	rd32(E1000_SEC);
+	rd32(E1000_RLEC);
+	rd32(E1000_XONRXC);
+	rd32(E1000_XONTXC);
+	rd32(E1000_XOFFRXC);
+	rd32(E1000_XOFFTXC);
+	rd32(E1000_FCRUC);
+	rd32(E1000_GPRC);
+	rd32(E1000_BPRC);
+	rd32(E1000_MPRC);
+	rd32(E1000_GPTC);
+	rd32(E1000_GORCL);
+	rd32(E1000_GORCH);
+	rd32(E1000_GOTCL);
+	rd32(E1000_GOTCH);
+	rd32(E1000_RNBC);
+	rd32(E1000_RUC);
+	rd32(E1000_RFC);
+	rd32(E1000_ROC);
+	rd32(E1000_RJC);
+	rd32(E1000_TORL);
+	rd32(E1000_TORH);
+	rd32(E1000_TOTL);
+	rd32(E1000_TOTH);
+	rd32(E1000_TPR);
+	rd32(E1000_TPT);
+	rd32(E1000_MPTC);
+	rd32(E1000_BPTC);
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mbx.c linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mbx.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mbx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mbx.c	2010-02-24 13:52:17.000000000 -0500
@@ -143,12 +143,16 @@ static s32 igb_poll_for_msg(struct e1000
 	if (!countdown || !mbx->ops.check_for_msg)
 		goto out;
 
-	while (mbx->ops.check_for_msg(hw, mbx_id)) {
+	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
 		countdown--;
 		if (!countdown)
 			break;
 		udelay(mbx->usec_delay);
 	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
 out:
 	return countdown ? 0 : -E1000_ERR_MBX;
 }
@@ -168,12 +172,16 @@ static s32 igb_poll_for_ack(struct e1000
 	if (!countdown || !mbx->ops.check_for_ack)
 		goto out;
 
-	while (mbx->ops.check_for_ack(hw, mbx_id)) {
+	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
 		countdown--;
 		if (!countdown)
 			break;
 		udelay(mbx->usec_delay);
 	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
 out:
 	return countdown ? 0 : -E1000_ERR_MBX;
 }
@@ -217,12 +225,13 @@ out:
 static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
 {
 	struct e1000_mbx_info *mbx = &hw->mbx;
-	s32 ret_val = 0;
+	s32 ret_val = -E1000_ERR_MBX;
 
-	if (!mbx->ops.write)
+	/* exit if either we can't write or there isn't a defined timeout */
+	if (!mbx->ops.write || !mbx->timeout)
 		goto out;
 
-	/* send msg*/
+	/* send msg */
 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
 
 	/* if msg sent wait until we receive an ack */
@@ -305,6 +314,30 @@ static s32 igb_check_for_rst_pf(struct e
 }
 
 /**
+ *  igb_obtain_mbx_lock_pf - obtain mailbox lock
+ *  @hw: pointer to the HW structure
+ *  @vf_number: the VF index
+ *
+ *  return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+	u32 p2v_mailbox;
+
+
+	/* Take ownership of the buffer */
+	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+	/* reserve mailbox for vf use */
+	p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+	if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
+		ret_val = 0;
+
+	return ret_val;
+}
+
+/**
  *  igb_write_mbx_pf - Places a message in the mailbox
  *  @hw: pointer to the HW structure
  *  @msg: The message buffer
@@ -316,27 +349,17 @@ static s32 igb_check_for_rst_pf(struct e
 static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
                               u16 vf_number)
 {
-	u32 p2v_mailbox;
-	s32 ret_val = 0;
+	s32 ret_val;
 	u16 i;
 
-	/* Take ownership of the buffer */
-	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
-	/* Make sure we have ownership now... */
-	p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
-	if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
-		/* failed to grab ownership */
-		ret_val = -E1000_ERR_MBX;
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+	if (ret_val)
 		goto out_no_write;
-	}
 
-	/*
-	 * flush any ack or msg which may already be in the queue
-	 * as they are likely the result of an error
-	 */
-	igb_check_for_ack_pf(hw, vf_number);
+	/* flush msg and acks as we are overwriting the message buffer */
 	igb_check_for_msg_pf(hw, vf_number);
+	igb_check_for_ack_pf(hw, vf_number);
 
 	/* copy the caller specified message to the mailbox memory buffer */
 	for (i = 0; i < size; i++)
@@ -367,20 +390,13 @@ out_no_write:
 static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
                              u16 vf_number)
 {
-	u32 p2v_mailbox;
-	s32 ret_val = 0;
+	s32 ret_val;
 	u16 i;
 
-	/* Take ownership of the buffer */
-	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
-	/* Make sure we have ownership now... */
-	p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
-	if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
-		/* failed to grab ownership */
-		ret_val = -E1000_ERR_MBX;
+	/* lock the mailbox to prevent pf/vf race condition */
+	ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+	if (ret_val)
 		goto out_no_read;
-	}
 
 	/* copy the message to the mailbox memory buffer */
 	for (i = 0; i < size; i++)
@@ -392,8 +408,6 @@ static s32 igb_read_mbx_pf(struct e1000_
 	/* update stats */
 	hw->mbx.stats.msgs_rx++;
 
-	ret_val = 0;
-
 out_no_read:
 	return ret_val;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mbx.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mbx.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_mbx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_mbx.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,10 +58,12 @@
 #define E1000_VT_MSGINFO_MASK     (0xFF << E1000_VT_MSGINFO_SHIFT)
 
 #define E1000_VF_RESET            0x01 /* VF requests reset */
-#define E1000_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */
-#define E1000_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
-#define E1000_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
-#define E1000_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+#define E1000_VF_SET_MAC_ADDR     0x02 /* VF requests to set MAC addr */
+#define E1000_VF_SET_MULTICAST    0x03 /* VF requests to set MC addr */
+#define E1000_VF_SET_VLAN         0x04 /* VF requests to set VLAN */
+#define E1000_VF_SET_LPE          0x05 /* VF requests to set VMOLR.LPE */
+#define E1000_VF_SET_PROMISC      0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
+#define E1000_VF_SET_PROMISC_MULTICAST    (0x02 << E1000_VT_MSGINFO_SHIFT)
 
 #define E1000_PF_CONTROL_MSG      0x0100 /* PF control message */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_nvm.c linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_nvm.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_nvm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_nvm.c	2010-02-24 13:52:17.000000000 -0500
@@ -78,9 +78,7 @@ static void igb_shift_out_eec_bits(struc
 	u32 mask;
 
 	mask = 0x01 << (count - 1);
-	if (nvm->type == e1000_nvm_eeprom_microwire)
-		eecd &= ~E1000_EECD_DO;
-	else if (nvm->type == e1000_nvm_eeprom_spi)
+	if (nvm->type == e1000_nvm_eeprom_spi)
 		eecd |= E1000_EECD_DO;
 
 	do {
@@ -220,22 +218,7 @@ static void igb_standby_nvm(struct e1000
 	struct e1000_nvm_info *nvm = &hw->nvm;
 	u32 eecd = rd32(E1000_EECD);
 
-	if (nvm->type == e1000_nvm_eeprom_microwire) {
-		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-		wr32(E1000_EECD, eecd);
-		wrfl();
-		udelay(nvm->delay_usec);
-
-		igb_raise_eec_clk(hw, &eecd);
-
-		/* Select EEPROM */
-		eecd |= E1000_EECD_CS;
-		wr32(E1000_EECD, eecd);
-		wrfl();
-		udelay(nvm->delay_usec);
-
-		igb_lower_eec_clk(hw, &eecd);
-	} else if (nvm->type == e1000_nvm_eeprom_spi) {
+	if (nvm->type == e1000_nvm_eeprom_spi) {
 		/* Toggle CS to flush commands */
 		eecd |= E1000_EECD_CS;
 		wr32(E1000_EECD, eecd);
@@ -263,12 +246,6 @@ static void e1000_stop_nvm(struct e1000_
 		/* Pull CS high */
 		eecd |= E1000_EECD_CS;
 		igb_lower_eec_clk(hw, &eecd);
-	} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
-		/* CS on Microcwire is active-high */
-		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
-		wr32(E1000_EECD, eecd);
-		igb_raise_eec_clk(hw, &eecd);
-		igb_lower_eec_clk(hw, &eecd);
 	}
 }
 
@@ -304,14 +281,7 @@ static s32 igb_ready_nvm_eeprom(struct e
 	u8 spi_stat_reg;
 
 
-	if (nvm->type == e1000_nvm_eeprom_microwire) {
-		/* Clear SK and DI */
-		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
-		wr32(E1000_EECD, eecd);
-		/* Set CS */
-		eecd |= E1000_EECD_CS;
-		wr32(E1000_EECD, eecd);
-	} else if (nvm->type == e1000_nvm_eeprom_spi) {
+	if (nvm->type == e1000_nvm_eeprom_spi) {
 		/* Clear SK and CS */
 		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
 		wr32(E1000_EECD, eecd);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_phy.c linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,9 @@ static s32  igb_wait_autoneg(struct e100
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
 	{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+                (sizeof(e1000_m88_cable_length_table) / \
+                 sizeof(e1000_m88_cable_length_table[0]))
 
 static const u16 e1000_igp_2_cable_length_table[] =
     { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -109,7 +112,10 @@ out:
  **/
 static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
 {
-	s32 ret_val;
+	s32 ret_val = 0;
+
+	if (!(hw->phy.ops.write_reg))
+		goto out;
 
 	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
 	if (ret_val)
@@ -130,7 +136,7 @@ out:
  *  Reads the MDI control regsiter in the PHY at offset and stores the
  *  information read to data.
  **/
-static s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 i, mdic = 0;
@@ -188,7 +194,7 @@ out:
  *
  *  Writes data to MDI control register in the PHY at offset.
  **/
-static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
+s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 i, mdic = 0;
@@ -239,6 +245,103 @@ out:
 }
 
 /**
+ *  igb_read_phy_reg_i2c - Read PHY register using i2c
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the PHY register at offset using the i2c interface and stores the
+ *  retrieved information in data.
+ **/
+s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	u32 i, i2ccmd = 0;
+
+
+	/*
+	 * Set up Op-code, Phy Address, and register address in the I2CCMD
+	 * register.  The MAC will take care of interfacing with the
+	 * PHY to retrieve the desired data.
+	 */
+	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+	          (phy->addr << E1000_I2CCMD_PHY_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);
+		i2ccmd = rd32(E1000_I2CCMD);
+		if (i2ccmd & E1000_I2CCMD_READY)
+			break;
+	}
+	if (!(i2ccmd & E1000_I2CCMD_READY)) {
+		hw_dbg("I2CCMD Read did not complete\n");
+		return -E1000_ERR_PHY;
+	}
+	if (i2ccmd & E1000_I2CCMD_ERROR) {
+		hw_dbg("I2CCMD Error bit set\n");
+		return -E1000_ERR_PHY;
+	}
+
+	/* Need to byte-swap the 16-bit value. */
+	*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
+
+	return 0;
+}
+
+/**
+ *  igb_write_phy_reg_i2c - Write PHY register using i2c
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Writes the data to PHY register at the offset using the i2c interface.
+ **/
+s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	u32 i, i2ccmd = 0;
+	u16 phy_data_swapped;
+
+
+	/* Swap the data bytes for the I2C interface */
+	phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
+
+	/*
+	 * Set up Op-code, Phy Address, and register address in the I2CCMD
+	 * register.  The MAC will take care of interfacing with the
+	 * PHY to retrieve the desired data.
+	 */
+	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+	          (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
+	          E1000_I2CCMD_OPCODE_WRITE |
+	          phy_data_swapped);
+
+	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);
+		i2ccmd = rd32(E1000_I2CCMD);
+		if (i2ccmd & E1000_I2CCMD_READY)
+			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
@@ -318,6 +421,48 @@ out:
 }
 
 /**
+ *  igb_copper_link_setup_82580 - Setup 82580 PHY for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets up Carrier-sense on Transmit and downshift values.
+ **/
+s32 igb_copper_link_setup_82580(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data;
+
+
+	if (phy->reset_disable) {
+		ret_val = 0;
+		goto out;
+	}
+
+	if (phy->type == e1000_phy_82580) {
+		ret_val = hw->phy.ops.reset(hw);
+		if (ret_val) {
+			hw_dbg("Error resetting the PHY.\n");
+			goto out;
+		}
+	}
+
+	/* Enable CRS on TX. This must be set for half-duplex operation. */
+	ret_val = phy->ops.read_reg(hw, I82580_CFG_REG, &phy_data);
+	if (ret_val)
+		goto out;
+
+	phy_data |= I82580_CFG_ASSERT_CRS_ON_TX;
+
+	/* Enable downshift */
+	phy_data |= I82580_CFG_ENABLE_DOWNSHIFT;
+
+	ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data);
+
+out:
+	return ret_val;
+}
+
+/**
  *  igb_copper_link_setup_m88 - Setup m88 PHY's for copper link
  *  @hw: pointer to the HW structure
  *
@@ -572,7 +717,7 @@ out:
  *  and restart the negotiation process between the link partner.  If
  *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
  **/
-s32 igb_copper_link_autoneg(struct e1000_hw *hw)
+static s32 igb_copper_link_autoneg(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -796,6 +941,65 @@ out:
 }
 
 /**
+ *  igb_setup_copper_link - Configure copper link settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Calls the appropriate function to configure the link for auto-neg or forced
+ *  speed and duplex.  Then we check for link, once link is established calls
+ *  to configure collision distance and flow control are called.  If link is
+ *  not established, we return -E1000_ERR_PHY (-2).
+ **/
+s32 igb_setup_copper_link(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	bool link;
+
+
+	if (hw->mac.autoneg) {
+		/*
+		 * Setup autoneg and flow control advertisement and perform
+		 * autonegotiation.
+		 */
+		ret_val = igb_copper_link_autoneg(hw);
+		if (ret_val)
+			goto out;
+	} else {
+		/*
+		 * PHY will be set to 10H, 10F, 100H or 100F
+		 * depending on user settings.
+		 */
+		hw_dbg("Forcing Speed and Duplex\n");
+		ret_val = hw->phy.ops.force_speed_duplex(hw);
+		if (ret_val) {
+			hw_dbg("Error Forcing Speed and Duplex\n");
+			goto out;
+		}
+	}
+
+	/*
+	 * Check link status. Wait up to 100 microseconds for link to become
+	 * valid.
+	 */
+	ret_val = igb_phy_has_link(hw,
+	                           COPPER_LINK_UP_LIMIT,
+	                           10,
+	                           &link);
+	if (ret_val)
+		goto out;
+
+	if (link) {
+		hw_dbg("Valid link established!!!\n");
+		igb_config_collision_dist(hw);
+		ret_val = igb_config_fc_after_link_up(hw);
+	} else {
+		hw_dbg("Unable to establish link!!!\n");
+	}
+
+out:
+	return ret_val;
+}
+
+/**
  *  igb_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
  *  @hw: pointer to the HW structure
  *
@@ -903,22 +1107,19 @@ s32 igb_phy_force_speed_duplex_m88(struc
 
 	igb_phy_force_speed_duplex_setup(hw, &phy_data);
 
-	/* Reset the phy to commit changes. */
-	phy_data |= MII_CR_RESET;
-
 	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
 	if (ret_val)
 		goto out;
 
-	udelay(1);
+	/* Reset the phy to commit changes. */
+	ret_val = igb_phy_sw_reset(hw);
+	if (ret_val)
+		goto out;
 
 	if (phy->autoneg_wait_to_complete) {
 		hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
 
-		ret_val = igb_phy_has_link(hw,
-						     PHY_FORCE_LIMIT,
-						     100000,
-						     &link);
+		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
 		if (ret_val)
 			goto out;
 
@@ -928,8 +1129,8 @@ s32 igb_phy_force_speed_duplex_m88(struc
 			 * Reset the DSP and cross our fingers.
 			 */
 			ret_val = phy->ops.write_reg(hw,
-						      M88E1000_PHY_PAGE_SELECT,
-						      0x001d);
+						     M88E1000_PHY_PAGE_SELECT,
+						     0x001d);
 			if (ret_val)
 				goto out;
 			ret_val = igb_phy_reset_dsp(hw);
@@ -939,7 +1140,7 @@ s32 igb_phy_force_speed_duplex_m88(struc
 
 		/* Try once more */
 		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
-					     100000, &link);
+					   100000, &link);
 		if (ret_val)
 			goto out;
 	}
@@ -1051,9 +1252,12 @@ static void igb_phy_force_speed_duplex_s
 s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 data;
 
+	if (!(hw->phy.ops.read_reg))
+		goto out;
+
 	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
 	if (ret_val)
 		goto out;
@@ -1288,8 +1492,14 @@ s32 igb_phy_has_link(struct e1000_hw *hw
 		 * it across the board.
 		 */
 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
-		if (ret_val)
-			break;
+		if (ret_val) {
+			/*
+			 * If the first read fails, another entity may have
+			 * ownership of the resources, wait and try again to
+			 * see if they have relinquished the resources yet.
+			 */
+			udelay(usec_interval);
+		}
 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
@@ -1333,8 +1543,13 @@ s32 igb_get_cable_length_m88(struct e100
 
 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
 		M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
 	phy->min_cable_length = e1000_m88_cable_length_table[index];
-	phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
@@ -1715,3 +1930,194 @@ s32 igb_phy_init_script_igp3(struct e100
 	return 0;
 }
 
+/**
+ *  igb_check_polarity_82580 - Checks the polarity.
+ *  @hw: pointer to the HW structure
+ *
+ *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
+ *
+ *  Polarity is determined based on the PHY specific status register.
+ **/
+static s32 igb_check_polarity_82580(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+
+
+	ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data);
+
+	if (!ret_val)
+		phy->cable_polarity = (data & I82580_PHY_STATUS2_REV_POLARITY)
+		                      ? e1000_rev_polarity_reversed
+		                      : e1000_rev_polarity_normal;
+
+	return ret_val;
+}
+
+/**
+ *  igb_phy_force_speed_duplex_82580 - Force speed/duplex for I82580 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Calls the PHY setup function to force speed and duplex.  Clears the
+ *  auto-crossover to force MDI manually.  Waits for link and returns
+ *  successful if link up is successful, else -E1000_ERR_PHY (-2).
+ **/
+s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data;
+	bool link;
+
+
+	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
+	if (ret_val)
+		goto out;
+
+	igb_phy_force_speed_duplex_setup(hw, &phy_data);
+
+	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
+	if (ret_val)
+		goto out;
+
+	/*
+	 * Clear Auto-Crossover to force MDI manually.  82580 requires MDI
+	 * forced whenever speed and duplex are forced.
+	 */
+	ret_val = phy->ops.read_reg(hw, I82580_PHY_CTRL_2, &phy_data);
+	if (ret_val)
+		goto out;
+
+	phy_data &= ~I82580_PHY_CTRL2_AUTO_MDIX;
+	phy_data &= ~I82580_PHY_CTRL2_FORCE_MDI_MDIX;
+
+	ret_val = phy->ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data);
+	if (ret_val)
+		goto out;
+
+	hw_dbg("I82580_PHY_CTRL_2: %X\n", phy_data);
+
+	udelay(1);
+
+	if (phy->autoneg_wait_to_complete) {
+		hw_dbg("Waiting for forced speed/duplex link on 82580 phy\n");
+
+		ret_val = igb_phy_has_link(hw,
+		                           PHY_FORCE_LIMIT,
+		                           100000,
+		                           &link);
+		if (ret_val)
+			goto out;
+
+		if (!link)
+			hw_dbg("Link taking longer than expected.\n");
+
+		/* Try once more */
+		ret_val = igb_phy_has_link(hw,
+		                           PHY_FORCE_LIMIT,
+		                           100000,
+		                           &link);
+		if (ret_val)
+			goto out;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  igb_get_phy_info_82580 - Retrieve I82580 PHY information
+ *  @hw: pointer to the HW structure
+ *
+ *  Read PHY status to determine if link is up.  If link is up, then
+ *  set/determine 10base-T extended distance and polarity correction.  Read
+ *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
+ *  determine on the cable length, local and remote receiver.
+ **/
+s32 igb_get_phy_info_82580(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 data;
+	bool link;
+
+
+	ret_val = igb_phy_has_link(hw, 1, 0, &link);
+	if (ret_val)
+		goto out;
+
+	if (!link) {
+		hw_dbg("Phy info is only valid if link is up\n");
+		ret_val = -E1000_ERR_CONFIG;
+		goto out;
+	}
+
+	phy->polarity_correction = true;
+
+	ret_val = igb_check_polarity_82580(hw);
+	if (ret_val)
+		goto out;
+
+	ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data);
+	if (ret_val)
+		goto out;
+
+	phy->is_mdix = (data & I82580_PHY_STATUS2_MDIX) ? true : false;
+
+	if ((data & I82580_PHY_STATUS2_SPEED_MASK) ==
+	    I82580_PHY_STATUS2_SPEED_1000MBPS) {
+		ret_val = hw->phy.ops.get_cable_length(hw);
+		if (ret_val)
+			goto out;
+
+		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
+		if (ret_val)
+			goto out;
+
+		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
+		                ? e1000_1000t_rx_status_ok
+		                : e1000_1000t_rx_status_not_ok;
+
+		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
+		                 ? e1000_1000t_rx_status_ok
+		                 : e1000_1000t_rx_status_not_ok;
+	} else {
+		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+		phy->local_rx = e1000_1000t_rx_status_undefined;
+		phy->remote_rx = e1000_1000t_rx_status_undefined;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  igb_get_cable_length_82580 - Determine cable length for 82580 PHY
+ *  @hw: pointer to the HW structure
+ *
+ * Reads the diagnostic status register and verifies result is valid before
+ * placing it in the phy_cable_length field.
+ **/
+s32 igb_get_cable_length_82580(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data, length;
+
+
+	ret_val = phy->ops.read_reg(hw, I82580_PHY_DIAG_STATUS, &phy_data);
+	if (ret_val)
+		goto out;
+
+	length = (phy_data & I82580_DSTATUS_CABLE_LENGTH) >>
+	         I82580_DSTATUS_CABLE_LENGTH_SHIFT;
+
+	if (length == E1000_CABLE_LENGTH_UNDEFINED)
+		ret_val = -E1000_ERR_PHY;
+
+	phy->cable_length = length;
+
+out:
+	return ret_val;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_phy.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_phy.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_phy.h	2010-02-24 13:52:17.000000000 -0500
@@ -43,7 +43,6 @@ enum e1000_smart_speed {
 
 s32  igb_check_downshift(struct e1000_hw *hw);
 s32  igb_check_reset_block(struct e1000_hw *hw);
-s32  igb_copper_link_autoneg(struct e1000_hw *hw);
 s32  igb_copper_link_setup_igp(struct e1000_hw *hw);
 s32  igb_copper_link_setup_m88(struct e1000_hw *hw);
 s32  igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
@@ -57,10 +56,19 @@ s32  igb_phy_sw_reset(struct e1000_hw *h
 s32  igb_phy_hw_reset(struct e1000_hw *hw);
 s32  igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
 s32  igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
+s32  igb_setup_copper_link(struct e1000_hw *hw);
 s32  igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
 s32  igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
 				u32 usec_interval, bool *success);
 s32  igb_phy_init_script_igp3(struct e1000_hw *hw);
+s32  igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
+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_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);
+s32  igb_get_cable_length_82580(struct e1000_hw *hw);
 
 /* IGP01E1000 Specific Registers */
 #define IGP01E1000_PHY_PORT_CONFIG        0x10 /* Port Config */
@@ -75,6 +83,33 @@ s32  igb_phy_init_script_igp3(struct e10
 #define IGP01E1000_PSCR_FORCE_MDI_MDIX    0x2000 /* 0=MDI, 1=MDIX */
 #define IGP01E1000_PSCFR_SMART_SPEED      0x0080
 
+#define I82580_ADDR_REG                   16
+#define I82580_CFG_REG                    22
+#define I82580_CFG_ASSERT_CRS_ON_TX       (1 << 15)
+#define I82580_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
+#define I82580_CTRL_REG                   23
+#define I82580_CTRL_DOWNSHIFT_MASK        (7 << 10)
+
+/* 82580 specific PHY registers */
+#define I82580_PHY_CTRL_2            18
+#define I82580_PHY_LBK_CTRL          19
+#define I82580_PHY_STATUS_2          26
+#define I82580_PHY_DIAG_STATUS       31
+
+/* I82580 PHY Status 2 */
+#define I82580_PHY_STATUS2_REV_POLARITY   0x0400
+#define I82580_PHY_STATUS2_MDIX           0x0800
+#define I82580_PHY_STATUS2_SPEED_MASK     0x0300
+#define I82580_PHY_STATUS2_SPEED_1000MBPS 0x0200
+#define I82580_PHY_STATUS2_SPEED_100MBPS  0x0100
+
+/* I82580 PHY Control 2 */
+#define I82580_PHY_CTRL2_AUTO_MDIX        0x0400
+#define I82580_PHY_CTRL2_FORCE_MDI_MDIX   0x0200
+
+/* I82580 PHY Diagnostics Status */
+#define I82580_DSTATUS_CABLE_LENGTH       0x03FC
+#define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2
 /* Enable flexible speed on link-up */
 #define IGP02E1000_PM_D0_LPLU             0x0002 /* For D0a states */
 #define IGP02E1000_PM_D3_LPLU             0x0004 /* For all other states */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_regs.h linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_regs.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/e1000_regs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/e1000_regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,7 @@
 #define E1000_EERD     0x00014  /* EEPROM Read - RW */
 #define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
 #define E1000_MDIC     0x00020  /* MDI Control - RW */
+#define E1000_MDICNFG  0x00E04  /* MDI Config - RW */
 #define E1000_SCTL     0x00024  /* SerDes Control - RW */
 #define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
 #define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
@@ -76,59 +77,20 @@
 #define E1000_FCRTV    0x02460  /* Flow Control Refresh Timer Value - RW */
 
 /* IEEE 1588 TIMESYNCH */
-#define E1000_TSYNCTXCTL 0x0B614
-#define E1000_TSYNCTXCTL_VALID (1<<0)
-#define E1000_TSYNCTXCTL_ENABLED (1<<4)
-#define E1000_TSYNCRXCTL 0x0B620
-#define E1000_TSYNCRXCTL_VALID (1<<0)
-#define E1000_TSYNCRXCTL_ENABLED (1<<4)
-enum {
-	E1000_TSYNCRXCTL_TYPE_L2_V2 = 0,
-	E1000_TSYNCRXCTL_TYPE_L4_V1 = (1<<1),
-	E1000_TSYNCRXCTL_TYPE_L2_L4_V2 = (1<<2),
-	E1000_TSYNCRXCTL_TYPE_ALL = (1<<3),
-	E1000_TSYNCRXCTL_TYPE_EVENT_V2 = (1<<3) | (1<<1),
-};
-#define E1000_TSYNCRXCFG 0x05F50
-enum {
-	E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE = 0<<0,
-	E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE = 1<<0,
-	E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE = 2<<0,
-	E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE = 3<<0,
-	E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE = 4<<0,
-
-	E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE = 0<<8,
-	E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE = 1<<8,
-	E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE = 2<<8,
-	E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE = 3<<8,
-	E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE = 8<<8,
-	E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE = 9<<8,
-	E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE = 0xA<<8,
-	E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE = 0xB<<8,
-	E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE = 0xC<<8,
-	E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE = 0xD<<8,
-};
-#define E1000_SYSTIML 0x0B600
-#define E1000_SYSTIMH 0x0B604
-#define E1000_TIMINCA 0x0B608
-
-#define E1000_RXMTRL     0x0B634
-#define E1000_RXSTMPL 0x0B624
-#define E1000_RXSTMPH 0x0B628
-#define E1000_RXSATRL 0x0B62C
-#define E1000_RXSATRH 0x0B630
-
-#define E1000_TXSTMPL 0x0B618
-#define E1000_TXSTMPH 0x0B61C
-
-#define E1000_ETQF0   0x05CB0
-#define E1000_ETQF1   0x05CB4
-#define E1000_ETQF2   0x05CB8
-#define E1000_ETQF3   0x05CBC
-#define E1000_ETQF4   0x05CC0
-#define E1000_ETQF5   0x05CC4
-#define E1000_ETQF6   0x05CC8
-#define E1000_ETQF7   0x05CCC
+#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
+#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
+#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
+#define E1000_RXSTMPL    0x0B624 /* Rx timestamp Low - RO */
+#define E1000_RXSTMPH    0x0B628 /* Rx timestamp High - RO */
+#define E1000_RXSATRL    0x0B62C /* Rx timestamp attribute low - RO */
+#define E1000_RXSATRH    0x0B630 /* Rx timestamp attribute high - RO */
+#define E1000_TXSTMPL    0x0B618 /* Tx timestamp value Low - RO */
+#define E1000_TXSTMPH    0x0B61C /* Tx timestamp value High - RO */
+#define E1000_SYSTIML    0x0B600 /* System time register Low - RO */
+#define E1000_SYSTIMH    0x0B604 /* System time register High - RO */
+#define E1000_TIMINCA    0x0B608 /* Increment attributes register - RW */
+#define E1000_TSAUXC     0x0B640 /* Timesync Auxiliary Control register */
+#define E1000_SYSTIMR    0x0B6F8 /* System time register Residue */
 
 /* Filtering Registers */
 #define E1000_SAQF(_n) (0x5980 + 4 * (_n))
@@ -143,7 +105,9 @@ enum {
 #define E1000_ETQF(_n)  (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
 
 #define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
+
 /* Split and Replication RX Control - RW */
+#define E1000_RXPBS    0x02404  /* Rx Packet Buffer Size - RW */
 /*
  * Convenience macros
  *
@@ -288,10 +252,17 @@ enum {
 #define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
 #define E1000_RA       0x05400  /* Receive Address - RW Array */
 #define E1000_RA2      0x054E0  /* 2nd half of receive address array - RW Array */
+#define E1000_PSRTYPE(_i)       (0x05480 + ((_i) * 4))
 #define E1000_RAL(_i)  (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
                                        (0x054E0 + ((_i - 16) * 8)))
 #define E1000_RAH(_i)  (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
                                        (0x054E4 + ((_i - 16) * 8)))
+#define E1000_IP4AT_REG(_i)     (0x05840 + ((_i) * 8))
+#define E1000_IP6AT_REG(_i)     (0x05880 + ((_i) * 4))
+#define E1000_WUPM_REG(_i)      (0x05A00 + ((_i) * 4))
+#define E1000_FFMT_REG(_i)      (0x09000 + ((_i) * 8))
+#define E1000_FFVT_REG(_i)      (0x09800 + ((_i) * 8))
+#define E1000_FFLT_REG(_i)      (0x05F00 + ((_i) * 8))
 #define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
 #define E1000_VT_CTL   0x0581C  /* VMDq Control - RW */
 #define E1000_WUC      0x05800  /* Wakeup Control - RW */
@@ -331,6 +302,7 @@ enum {
 #define E1000_QDE       0x02408 /* Queue Drop Enable - RW */
 #define E1000_DTXSWC    0x03500 /* DMA Tx Switch Control - RW */
 #define E1000_RPLOLR    0x05AF0 /* Replication Offload - RW */
+#define E1000_UTA       0x0A000 /* Unicast Table Array - RW */
 #define E1000_IOVTCL    0x05BBC /* IOV Control Register */
 /* These act per VF so an array friendly macro is used */
 #define E1000_P2VMAILBOX(_n)   (0x00C00 + (4 * (_n)))
@@ -348,4 +320,6 @@ enum {
 #define array_rd32(reg, offset) \
 	(readl(hw->hw_addr + reg + ((offset) << 2)))
 
+/* DMA Coalescing registers */
+#define E1000_PCIEMISC          0x05BB8 /* PCIE misc config register */
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/igb_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/igb/igb_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/igb_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/igb_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,78 +44,94 @@ struct igb_stats {
 	int stat_offset;
 };
 
-#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \
-		      offsetof(struct igb_adapter, m)
+#define IGB_STAT(_name, _stat) { \
+	.stat_string = _name, \
+	.sizeof_stat = FIELD_SIZEOF(struct igb_adapter, _stat), \
+	.stat_offset = offsetof(struct igb_adapter, _stat) \
+}
 static const struct igb_stats igb_gstrings_stats[] = {
-	{ "rx_packets", IGB_STAT(stats.gprc) },
-	{ "tx_packets", IGB_STAT(stats.gptc) },
-	{ "rx_bytes", IGB_STAT(stats.gorc) },
-	{ "tx_bytes", IGB_STAT(stats.gotc) },
-	{ "rx_broadcast", IGB_STAT(stats.bprc) },
-	{ "tx_broadcast", IGB_STAT(stats.bptc) },
-	{ "rx_multicast", IGB_STAT(stats.mprc) },
-	{ "tx_multicast", IGB_STAT(stats.mptc) },
-	{ "rx_errors", IGB_STAT(net_stats.rx_errors) },
-	{ "tx_errors", IGB_STAT(net_stats.tx_errors) },
-	{ "tx_dropped", IGB_STAT(net_stats.tx_dropped) },
-	{ "multicast", IGB_STAT(stats.mprc) },
-	{ "collisions", IGB_STAT(stats.colc) },
-	{ "rx_length_errors", IGB_STAT(net_stats.rx_length_errors) },
-	{ "rx_over_errors", IGB_STAT(net_stats.rx_over_errors) },
-	{ "rx_crc_errors", IGB_STAT(stats.crcerrs) },
-	{ "rx_frame_errors", IGB_STAT(net_stats.rx_frame_errors) },
-	{ "rx_no_buffer_count", IGB_STAT(stats.rnbc) },
-	{ "rx_queue_drop_packet_count", IGB_STAT(net_stats.rx_fifo_errors) },
-	{ "rx_missed_errors", IGB_STAT(stats.mpc) },
-	{ "tx_aborted_errors", IGB_STAT(stats.ecol) },
-	{ "tx_carrier_errors", IGB_STAT(stats.tncrs) },
-	{ "tx_fifo_errors", IGB_STAT(net_stats.tx_fifo_errors) },
-	{ "tx_heartbeat_errors", IGB_STAT(net_stats.tx_heartbeat_errors) },
-	{ "tx_window_errors", IGB_STAT(stats.latecol) },
-	{ "tx_abort_late_coll", IGB_STAT(stats.latecol) },
-	{ "tx_deferred_ok", IGB_STAT(stats.dc) },
-	{ "tx_single_coll_ok", IGB_STAT(stats.scc) },
-	{ "tx_multi_coll_ok", IGB_STAT(stats.mcc) },
-	{ "tx_timeout_count", IGB_STAT(tx_timeout_count) },
-	{ "tx_restart_queue", IGB_STAT(restart_queue) },
-	{ "rx_long_length_errors", IGB_STAT(stats.roc) },
-	{ "rx_short_length_errors", IGB_STAT(stats.ruc) },
-	{ "rx_align_errors", IGB_STAT(stats.algnerrc) },
-	{ "tx_tcp_seg_good", IGB_STAT(stats.tsctc) },
-	{ "tx_tcp_seg_failed", IGB_STAT(stats.tsctfc) },
-	{ "rx_flow_control_xon", IGB_STAT(stats.xonrxc) },
-	{ "rx_flow_control_xoff", IGB_STAT(stats.xoffrxc) },
-	{ "tx_flow_control_xon", IGB_STAT(stats.xontxc) },
-	{ "tx_flow_control_xoff", IGB_STAT(stats.xofftxc) },
-	{ "rx_long_byte_count", IGB_STAT(stats.gorc) },
-	{ "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
-	{ "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
-	{ "tx_dma_out_of_sync", IGB_STAT(stats.doosync) },
-	{ "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
-	{ "tx_smbus", IGB_STAT(stats.mgptc) },
-	{ "rx_smbus", IGB_STAT(stats.mgprc) },
-	{ "dropped_smbus", IGB_STAT(stats.mgpdc) },
+	IGB_STAT("rx_packets", stats.gprc),
+	IGB_STAT("tx_packets", stats.gptc),
+	IGB_STAT("rx_bytes", stats.gorc),
+	IGB_STAT("tx_bytes", stats.gotc),
+	IGB_STAT("rx_broadcast", stats.bprc),
+	IGB_STAT("tx_broadcast", stats.bptc),
+	IGB_STAT("rx_multicast", stats.mprc),
+	IGB_STAT("tx_multicast", stats.mptc),
+	IGB_STAT("multicast", stats.mprc),
+	IGB_STAT("collisions", stats.colc),
+	IGB_STAT("rx_crc_errors", stats.crcerrs),
+	IGB_STAT("rx_no_buffer_count", stats.rnbc),
+	IGB_STAT("rx_missed_errors", stats.mpc),
+	IGB_STAT("tx_aborted_errors", stats.ecol),
+	IGB_STAT("tx_carrier_errors", stats.tncrs),
+	IGB_STAT("tx_window_errors", stats.latecol),
+	IGB_STAT("tx_abort_late_coll", stats.latecol),
+	IGB_STAT("tx_deferred_ok", stats.dc),
+	IGB_STAT("tx_single_coll_ok", stats.scc),
+	IGB_STAT("tx_multi_coll_ok", stats.mcc),
+	IGB_STAT("tx_timeout_count", tx_timeout_count),
+	IGB_STAT("rx_long_length_errors", stats.roc),
+	IGB_STAT("rx_short_length_errors", stats.ruc),
+	IGB_STAT("rx_align_errors", stats.algnerrc),
+	IGB_STAT("tx_tcp_seg_good", stats.tsctc),
+	IGB_STAT("tx_tcp_seg_failed", stats.tsctfc),
+	IGB_STAT("rx_flow_control_xon", stats.xonrxc),
+	IGB_STAT("rx_flow_control_xoff", stats.xoffrxc),
+	IGB_STAT("tx_flow_control_xon", stats.xontxc),
+	IGB_STAT("tx_flow_control_xoff", stats.xofftxc),
+	IGB_STAT("rx_long_byte_count", stats.gorc),
+	IGB_STAT("tx_dma_out_of_sync", stats.doosync),
+	IGB_STAT("tx_smbus", stats.mgptc),
+	IGB_STAT("rx_smbus", stats.mgprc),
+	IGB_STAT("dropped_smbus", stats.mgpdc),
+};
+
+#define IGB_NETDEV_STAT(_net_stat) { \
+	.stat_string = __stringify(_net_stat), \
+	.sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
+	.stat_offset = offsetof(struct net_device_stats, _net_stat) \
+}
+static const struct igb_stats igb_gstrings_net_stats[] = {
+	IGB_NETDEV_STAT(rx_errors),
+	IGB_NETDEV_STAT(tx_errors),
+	IGB_NETDEV_STAT(tx_dropped),
+	IGB_NETDEV_STAT(rx_length_errors),
+	IGB_NETDEV_STAT(rx_over_errors),
+	IGB_NETDEV_STAT(rx_frame_errors),
+	IGB_NETDEV_STAT(rx_fifo_errors),
+	IGB_NETDEV_STAT(tx_fifo_errors),
+	IGB_NETDEV_STAT(tx_heartbeat_errors)
 };
 
-#define IGB_QUEUE_STATS_LEN \
-	(((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \
-	  (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \
-	 ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
-	  (sizeof(struct igb_tx_queue_stats) / sizeof(u64))))
 #define IGB_GLOBAL_STATS_LEN	\
-	sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
-#define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN)
+	(sizeof(igb_gstrings_stats) / sizeof(struct igb_stats))
+#define IGB_NETDEV_STATS_LEN	\
+	(sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats))
+#define IGB_RX_QUEUE_STATS_LEN \
+	(sizeof(struct igb_rx_queue_stats) / sizeof(u64))
+#define IGB_TX_QUEUE_STATS_LEN \
+	(sizeof(struct igb_tx_queue_stats) / sizeof(u64))
+#define IGB_QUEUE_STATS_LEN \
+	((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \
+	  IGB_RX_QUEUE_STATS_LEN) + \
+	 (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \
+	  IGB_TX_QUEUE_STATS_LEN))
+#define IGB_STATS_LEN \
+	(IGB_GLOBAL_STATS_LEN + IGB_NETDEV_STATS_LEN + IGB_QUEUE_STATS_LEN)
+
 static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register test  (offline)", "Eeprom test    (offline)",
 	"Interrupt test (offline)", "Loopback test  (offline)",
 	"Link test   (on/offline)"
 };
-#define IGB_TEST_LEN sizeof(igb_gstrings_test) / ETH_GSTRING_LEN
+#define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN)
 
 static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	u32 status;
 
 	if (hw->phy.media_type == e1000_media_type_copper) {
 
@@ -150,17 +166,20 @@ static int igb_get_settings(struct net_d
 
 	ecmd->transceiver = XCVR_INTERNAL;
 
-	if (rd32(E1000_STATUS) & E1000_STATUS_LU) {
+	status = rd32(E1000_STATUS);
 
-		adapter->hw.mac.ops.get_speed_and_duplex(hw,
-					&adapter->link_speed,
-					&adapter->link_duplex);
-		ecmd->speed = adapter->link_speed;
+	if (status & E1000_STATUS_LU) {
 
-		/* unfortunately FULL_DUPLEX != DUPLEX_FULL
-		 *          and HALF_DUPLEX != DUPLEX_HALF */
+		if ((status & E1000_STATUS_SPEED_1000) ||
+		    hw->phy.media_type != e1000_media_type_copper)
+			ecmd->speed = SPEED_1000;
+		else if (status & E1000_STATUS_SPEED_100)
+			ecmd->speed = SPEED_100;
+		else
+			ecmd->speed = SPEED_10;
 
-		if (adapter->link_duplex == FULL_DUPLEX)
+		if ((status & E1000_STATUS_FD) ||
+		    hw->phy.media_type != e1000_media_type_copper)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
@@ -251,8 +270,9 @@ static int igb_set_pauseparam(struct net
 		if (netif_running(adapter->netdev)) {
 			igb_down(adapter);
 			igb_up(adapter);
-		} else
+		} else {
 			igb_reset(adapter);
+		}
 	} else {
 		if (pause->rx_pause && pause->tx_pause)
 			hw->fc.requested_mode = e1000_fc_full;
@@ -276,17 +296,20 @@ static int igb_set_pauseparam(struct net
 static u32 igb_get_rx_csum(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	return !(adapter->flags & IGB_FLAG_RX_CSUM_DISABLED);
+	return !!(adapter->rx_ring[0].flags & IGB_RING_FLAG_RX_CSUM);
 }
 
 static int igb_set_rx_csum(struct net_device *netdev, u32 data)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	int i;
 
-	if (data)
-		adapter->flags &= ~IGB_FLAG_RX_CSUM_DISABLED;
-	else
-		adapter->flags |= IGB_FLAG_RX_CSUM_DISABLED;
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		if (data)
+			adapter->rx_ring[i].flags |= IGB_RING_FLAG_RX_CSUM;
+		else
+			adapter->rx_ring[i].flags &= ~IGB_RING_FLAG_RX_CSUM;
+	}
 
 	return 0;
 }
@@ -302,7 +325,7 @@ static int igb_set_tx_csum(struct net_de
 
 	if (data) {
 		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-		if (adapter->hw.mac.type == e1000_82576)
+		if (adapter->hw.mac.type >= e1000_82576)
 			netdev->features |= NETIF_F_SCTP_CSUM;
 	} else {
 		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
@@ -496,19 +519,10 @@ static void igb_get_regs(struct net_devi
 	regs_buff[119] = adapter->stats.scvpc;
 	regs_buff[120] = adapter->stats.hrmpc;
 
-	/* These should probably be added to e1000_regs.h instead */
-	#define E1000_PSRTYPE_REG(_i) (0x05480 + ((_i) * 4))
-	#define E1000_IP4AT_REG(_i)   (0x05840 + ((_i) * 8))
-	#define E1000_IP6AT_REG(_i)   (0x05880 + ((_i) * 4))
-	#define E1000_WUPM_REG(_i)    (0x05A00 + ((_i) * 4))
-	#define E1000_FFMT_REG(_i)    (0x09000 + ((_i) * 8))
-	#define E1000_FFVT_REG(_i)    (0x09800 + ((_i) * 8))
-	#define E1000_FFLT_REG(_i)    (0x05F00 + ((_i) * 8))
-
 	for (i = 0; i < 4; i++)
 		regs_buff[121 + i] = rd32(E1000_SRRCTL(i));
 	for (i = 0; i < 4; i++)
-		regs_buff[125 + i] = rd32(E1000_PSRTYPE_REG(i));
+		regs_buff[125 + i] = rd32(E1000_PSRTYPE(i));
 	for (i = 0; i < 4; i++)
 		regs_buff[129 + i] = rd32(E1000_RDBAL(i));
 	for (i = 0; i < 4; i++)
@@ -733,17 +747,17 @@ static int igb_set_ringparam(struct net_
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct igb_ring *temp_ring;
 	int i, err = 0;
-	u32 new_rx_count, new_tx_count;
+	u16 new_rx_count, new_tx_count;
 
 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
-	new_rx_count = max(ring->rx_pending, (u32)IGB_MIN_RXD);
-	new_rx_count = min(new_rx_count, (u32)IGB_MAX_RXD);
+	new_rx_count = min_t(u32, ring->rx_pending, IGB_MAX_RXD);
+	new_rx_count = max_t(u16, new_rx_count, IGB_MIN_RXD);
 	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
 
-	new_tx_count = max(ring->tx_pending, (u32)IGB_MIN_TXD);
-	new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD);
+	new_tx_count = min_t(u32, ring->tx_pending, IGB_MAX_TXD);
+	new_tx_count = max_t(u16, new_tx_count, IGB_MIN_TXD);
 	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
 
 	if ((new_tx_count == adapter->tx_ring_count) &&
@@ -788,7 +802,7 @@ static int igb_set_ringparam(struct net_
 
 		for (i = 0; i < adapter->num_tx_queues; i++) {
 			temp_ring[i].count = new_tx_count;
-			err = igb_setup_tx_resources(adapter, &temp_ring[i]);
+			err = igb_setup_tx_resources(&temp_ring[i]);
 			if (err) {
 				while (i) {
 					i--;
@@ -813,7 +827,7 @@ static int igb_set_ringparam(struct net_
 
 		for (i = 0; i < adapter->num_rx_queues; i++) {
 			temp_ring[i].count = new_rx_count;
-			err = igb_setup_rx_resources(adapter, &temp_ring[i]);
+			err = igb_setup_rx_resources(&temp_ring[i]);
 			if (err) {
 				while (i) {
 					i--;
@@ -867,6 +881,49 @@ struct igb_reg_test {
 #define TABLE64_TEST_LO	5
 #define TABLE64_TEST_HI	6
 
+/* 82580 reg test */
+static struct igb_reg_test reg_test_82580[] = {
+	{ E1000_FCAL,	   0x100, 1,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_FCAH,	   0x100, 1,  PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+	{ E1000_FCT,	   0x100, 1,  PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+	{ E1000_VET,	   0x100, 1,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RDBAL(0),  0x100, 4,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_RDBAH(0),  0x100, 4,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RDLEN(0),  0x100, 4,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	{ E1000_RDBAL(4),  0x40,  4,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_RDBAH(4),  0x40,  4,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RDLEN(4),  0x40,  4,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	/* RDH is read-only for 82580, only test RDT. */
+	{ E1000_RDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_RDT(4),	   0x40,  4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_FCRTH,	   0x100, 1,  PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
+	{ E1000_FCTTV,	   0x100, 1,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_TIPG,	   0x100, 1,  PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
+	{ E1000_TDBAL(0),  0x100, 4,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_TDBAH(0),  0x100, 4,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_TDLEN(0),  0x100, 4,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	{ E1000_TDBAL(4),  0x40,  4,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_TDBAH(4),  0x40,  4,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_TDLEN(4),  0x40,  4,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	{ E1000_TDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_TDT(4),	   0x40,  4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+	{ E1000_TCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+	{ E1000_RA,	   0, 16, TABLE64_TEST_LO,
+						0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RA,	   0, 16, TABLE64_TEST_HI,
+						0x83FFFFFF, 0xFFFFFFFF },
+	{ E1000_RA2,	   0, 8, TABLE64_TEST_LO,
+						0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RA2,	   0, 8, TABLE64_TEST_HI,
+						0x83FFFFFF, 0xFFFFFFFF },
+	{ E1000_MTA,	   0, 128, TABLE32_TEST,
+						0xFFFFFFFF, 0xFFFFFFFF },
+	{ 0, 0, 0, 0 }
+};
+
 /* 82576 reg test */
 static struct igb_reg_test reg_test_82576[] = {
 	{ E1000_FCAL,	   0x100, 1,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -944,7 +1001,7 @@ static bool reg_pattern_test(struct igb_
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 pat, val;
-	u32 _test[] =
+	static const u32 _test[] =
 		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
 	for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
 		wr32(reg, (_test[pat] & write));
@@ -957,6 +1014,7 @@ static bool reg_pattern_test(struct igb_
 			return 1;
 		}
 	}
+
 	return 0;
 }
 
@@ -974,6 +1032,7 @@ static bool reg_set_and_check(struct igb
 		*data = reg;
 		return 1;
 	}
+
 	return 0;
 }
 
@@ -996,14 +1055,18 @@ static int igb_reg_test(struct igb_adapt
 	u32 value, before, after;
 	u32 i, toggle;
 
-	toggle = 0x7FFFF3FF;
-
 	switch (adapter->hw.mac.type) {
+	case e1000_82580:
+		test = reg_test_82580;
+		toggle = 0x7FEFF3FF;
+		break;
 	case e1000_82576:
 		test = reg_test_82576;
+		toggle = 0x7FFFF3FF;
 		break;
 	default:
 		test = reg_test_82575;
+		toggle = 0x7FFFF3FF;
 		break;
 	}
 
@@ -1081,8 +1144,7 @@ static int igb_eeprom_test(struct igb_ad
 	*data = 0;
 	/* Read and add up the contents of the EEPROM */
 	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
-		if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp))
-		    < 0) {
+		if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) {
 			*data = 1;
 			break;
 		}
@@ -1098,8 +1160,7 @@ static int igb_eeprom_test(struct igb_ad
 
 static irqreturn_t igb_test_intr(int irq, void *data)
 {
-	struct net_device *netdev = (struct net_device *) data;
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct igb_adapter *adapter = (struct igb_adapter *) data;
 	struct e1000_hw *hw = &adapter->hw;
 
 	adapter->test_icr |= rd32(E1000_ICR);
@@ -1117,38 +1178,45 @@ static int igb_intr_test(struct igb_adap
 	*data = 0;
 
 	/* Hook up test interrupt handler just for this test */
-	if (adapter->msix_entries)
-		/* NOTE: we don't test MSI-X interrupts here, yet */
-		return 0;
-
-	if (adapter->flags & IGB_FLAG_HAS_MSI) {
+	if (adapter->msix_entries) {
+		if (request_irq(adapter->msix_entries[0].vector,
+		                igb_test_intr, 0, netdev->name, adapter)) {
+			*data = 1;
+			return -1;
+		}
+	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
 		shared_int = false;
-		if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
+		if (request_irq(irq,
+		                igb_test_intr, 0, netdev->name, adapter)) {
 			*data = 1;
 			return -1;
 		}
-	} else if (!request_irq(irq, &igb_test_intr, IRQF_PROBE_SHARED,
-				netdev->name, netdev)) {
+	} else if (!request_irq(irq, igb_test_intr, IRQF_PROBE_SHARED,
+				netdev->name, adapter)) {
 		shared_int = false;
-	} else if (request_irq(irq, &igb_test_intr, IRQF_SHARED,
-		 netdev->name, netdev)) {
+	} else if (request_irq(irq, igb_test_intr, IRQF_SHARED,
+		 netdev->name, adapter)) {
 		*data = 1;
 		return -1;
 	}
 	dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
 		(shared_int ? "shared" : "unshared"));
+
 	/* Disable all the interrupts */
-	wr32(E1000_IMC, 0xFFFFFFFF);
+	wr32(E1000_IMC, ~0);
 	msleep(10);
 
 	/* Define all writable bits for ICS */
-	switch(hw->mac.type) {
+	switch (hw->mac.type) {
 	case e1000_82575:
 		ics_mask = 0x37F47EDD;
 		break;
 	case e1000_82576:
 		ics_mask = 0x77D4FBFD;
 		break;
+	case e1000_82580:
+		ics_mask = 0x77DCFED5;
+		break;
 	default:
 		ics_mask = 0x7FFFFFFF;
 		break;
@@ -1232,190 +1300,61 @@ static int igb_intr_test(struct igb_adap
 	msleep(10);
 
 	/* Unhook test interrupt handler */
-	free_irq(irq, netdev);
+	if (adapter->msix_entries)
+		free_irq(adapter->msix_entries[0].vector, adapter);
+	else
+		free_irq(irq, adapter);
 
 	return *data;
 }
 
 static void igb_free_desc_rings(struct igb_adapter *adapter)
 {
-	struct igb_ring *tx_ring = &adapter->test_tx_ring;
-	struct igb_ring *rx_ring = &adapter->test_rx_ring;
-	struct pci_dev *pdev = adapter->pdev;
-	int i;
-
-	if (tx_ring->desc && tx_ring->buffer_info) {
-		for (i = 0; i < tx_ring->count; i++) {
-			struct igb_buffer *buf = &(tx_ring->buffer_info[i]);
-			if (buf->dma)
-				pci_unmap_single(pdev, buf->dma, buf->length,
-						 PCI_DMA_TODEVICE);
-			if (buf->skb)
-				dev_kfree_skb(buf->skb);
-		}
-	}
-
-	if (rx_ring->desc && rx_ring->buffer_info) {
-		for (i = 0; i < rx_ring->count; i++) {
-			struct igb_buffer *buf = &(rx_ring->buffer_info[i]);
-			if (buf->dma)
-				pci_unmap_single(pdev, buf->dma,
-						 IGB_RXBUFFER_2048,
-						 PCI_DMA_FROMDEVICE);
-			if (buf->skb)
-				dev_kfree_skb(buf->skb);
-		}
-	}
-
-	if (tx_ring->desc) {
-		pci_free_consistent(pdev, tx_ring->size, tx_ring->desc,
-				    tx_ring->dma);
-		tx_ring->desc = NULL;
-	}
-	if (rx_ring->desc) {
-		pci_free_consistent(pdev, rx_ring->size, rx_ring->desc,
-				    rx_ring->dma);
-		rx_ring->desc = NULL;
-	}
-
-	kfree(tx_ring->buffer_info);
-	tx_ring->buffer_info = NULL;
-	kfree(rx_ring->buffer_info);
-	rx_ring->buffer_info = NULL;
-
-	return;
+	igb_free_tx_resources(&adapter->test_tx_ring);
+	igb_free_rx_resources(&adapter->test_rx_ring);
 }
 
 static int igb_setup_desc_rings(struct igb_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct igb_ring *tx_ring = &adapter->test_tx_ring;
 	struct igb_ring *rx_ring = &adapter->test_rx_ring;
-	struct pci_dev *pdev = adapter->pdev;
-	struct igb_buffer *buffer_info;
-	u32 rctl;
-	int i, ret_val;
+	struct e1000_hw *hw = &adapter->hw;
+	int ret_val;
 
 	/* Setup Tx descriptor ring and Tx buffers */
+	tx_ring->count = IGB_DEFAULT_TXD;
+	tx_ring->pdev = adapter->pdev;
+	tx_ring->netdev = adapter->netdev;
+	tx_ring->reg_idx = adapter->vfs_allocated_count;
 
-	if (!tx_ring->count)
-		tx_ring->count = IGB_DEFAULT_TXD;
-
-	tx_ring->buffer_info = kcalloc(tx_ring->count,
-				       sizeof(struct igb_buffer),
-				       GFP_KERNEL);
-	if (!tx_ring->buffer_info) {
+	if (igb_setup_tx_resources(tx_ring)) {
 		ret_val = 1;
 		goto err_nomem;
 	}
 
-	tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
-	tx_ring->size = ALIGN(tx_ring->size, 4096);
-	tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
-					     &tx_ring->dma);
-	if (!tx_ring->desc) {
-		ret_val = 2;
-		goto err_nomem;
-	}
-	tx_ring->next_to_use = tx_ring->next_to_clean = 0;
-
-	wr32(E1000_TDBAL(0),
-			((u64) tx_ring->dma & 0x00000000FFFFFFFF));
-	wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
-	wr32(E1000_TDLEN(0),
-			tx_ring->count * sizeof(union e1000_adv_tx_desc));
-	wr32(E1000_TDH(0), 0);
-	wr32(E1000_TDT(0), 0);
-	wr32(E1000_TCTL,
-			E1000_TCTL_PSP | E1000_TCTL_EN |
-			E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
-			E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
-
-	for (i = 0; i < tx_ring->count; i++) {
-		union e1000_adv_tx_desc *tx_desc;
-		struct sk_buff *skb;
-		unsigned int size = 1024;
-
-		tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
-		skb = alloc_skb(size, GFP_KERNEL);
-		if (!skb) {
-			ret_val = 3;
-			goto err_nomem;
-		}
-		skb_put(skb, size);
-		buffer_info = &tx_ring->buffer_info[i];
-		buffer_info->skb = skb;
-		buffer_info->length = skb->len;
-		buffer_info->dma = pci_map_single(pdev, skb->data, skb->len,
-		                                  PCI_DMA_TODEVICE);
-		tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
-		tx_desc->read.olinfo_status = cpu_to_le32(skb->len) <<
-		                              E1000_ADVTXD_PAYLEN_SHIFT;
-		tx_desc->read.cmd_type_len = cpu_to_le32(skb->len);
-		tx_desc->read.cmd_type_len |= cpu_to_le32(E1000_TXD_CMD_EOP |
-		                                          E1000_TXD_CMD_IFCS |
-		                                          E1000_TXD_CMD_RS |
-		                                          E1000_ADVTXD_DTYP_DATA |
-		                                          E1000_ADVTXD_DCMD_DEXT);
-	}
+	igb_setup_tctl(adapter);
+	igb_configure_tx_ring(adapter, tx_ring);
 
 	/* Setup Rx descriptor ring and Rx buffers */
+	rx_ring->count = IGB_DEFAULT_RXD;
+	rx_ring->pdev = adapter->pdev;
+	rx_ring->netdev = adapter->netdev;
+	rx_ring->rx_buffer_len = IGB_RXBUFFER_2048;
+	rx_ring->reg_idx = adapter->vfs_allocated_count;
 
-	if (!rx_ring->count)
-		rx_ring->count = IGB_DEFAULT_RXD;
-
-	rx_ring->buffer_info = kcalloc(rx_ring->count,
-				       sizeof(struct igb_buffer),
-				       GFP_KERNEL);
-	if (!rx_ring->buffer_info) {
-		ret_val = 4;
-		goto err_nomem;
-	}
-
-	rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc);
-	rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
-					     &rx_ring->dma);
-	if (!rx_ring->desc) {
-		ret_val = 5;
+	if (igb_setup_rx_resources(rx_ring)) {
+		ret_val = 3;
 		goto err_nomem;
 	}
-	rx_ring->next_to_use = rx_ring->next_to_clean = 0;
 
-	rctl = rd32(E1000_RCTL);
-	wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
-	wr32(E1000_RDBAL(0),
-			((u64) rx_ring->dma & 0xFFFFFFFF));
-	wr32(E1000_RDBAH(0),
-			((u64) rx_ring->dma >> 32));
-	wr32(E1000_RDLEN(0), rx_ring->size);
-	wr32(E1000_RDH(0), 0);
-	wr32(E1000_RDT(0), 0);
-	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
-	rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
-		(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
-	wr32(E1000_RCTL, rctl);
-	wr32(E1000_SRRCTL(0), E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
+	/* set the default queue to queue 0 of PF */
+	wr32(E1000_MRQC, adapter->vfs_allocated_count << 3);
 
-	for (i = 0; i < rx_ring->count; i++) {
-		union e1000_adv_rx_desc *rx_desc;
-		struct sk_buff *skb;
+	/* enable receive ring */
+	igb_setup_rctl(adapter);
+	igb_configure_rx_ring(adapter, rx_ring);
 
-		buffer_info = &rx_ring->buffer_info[i];
-		rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
-		skb = alloc_skb(IGB_RXBUFFER_2048 + NET_IP_ALIGN,
-				GFP_KERNEL);
-		if (!skb) {
-			ret_val = 6;
-			goto err_nomem;
-		}
-		skb_reserve(skb, NET_IP_ALIGN);
-		buffer_info->skb = skb;
-		buffer_info->dma = pci_map_single(pdev, skb->data,
-		                                  IGB_RXBUFFER_2048,
-		                                  PCI_DMA_FROMDEVICE);
-		rx_desc->read.pkt_addr = cpu_to_le64(buffer_info->dma);
-		memset(skb->data, 0x00, skb->len);
-	}
+	igb_alloc_rx_buffers_adv(rx_ring, igb_desc_unused(rx_ring));
 
 	return 0;
 
@@ -1449,6 +1388,9 @@ static int igb_integrated_phy_loopback(s
 		igb_write_phy_reg(hw, PHY_CONTROL, 0x9140);
 		/* autoneg off */
 		igb_write_phy_reg(hw, PHY_CONTROL, 0x8140);
+	} else if (hw->phy.type == e1000_phy_82580) {
+		/* enable MII loopback */
+		igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041);
 	}
 
 	ctrl_reg = rd32(E1000_CTRL);
@@ -1491,7 +1433,10 @@ static int igb_setup_loopback_test(struc
 	struct e1000_hw *hw = &adapter->hw;
 	u32 reg;
 
-	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
+	reg = rd32(E1000_CTRL_EXT);
+
+	/* use CTRL_EXT to identify link type as SGMII can appear as copper */
+	if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) {
 		reg = rd32(E1000_RCTL);
 		reg |= E1000_RCTL_LBM_TCVR;
 		wr32(E1000_RCTL, reg);
@@ -1522,11 +1467,9 @@ static int igb_setup_loopback_test(struc
 		wr32(E1000_PCS_LCTL, reg);
 
 		return 0;
-	} else if (hw->phy.media_type == e1000_media_type_copper) {
-		return igb_set_phy_loopback(adapter);
 	}
 
-	return 7;
+	return igb_set_phy_loopback(adapter);
 }
 
 static void igb_loopback_cleanup(struct igb_adapter *adapter)
@@ -1552,35 +1495,99 @@ static void igb_create_lbtest_frame(stru
 				    unsigned int frame_size)
 {
 	memset(skb->data, 0xFF, frame_size);
-	frame_size &= ~1;
-	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
-	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
-	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+	frame_size /= 2;
+	memset(&skb->data[frame_size], 0xAA, frame_size - 1);
+	memset(&skb->data[frame_size + 10], 0xBE, 1);
+	memset(&skb->data[frame_size + 12], 0xAF, 1);
 }
 
 static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
 {
-	frame_size &= ~1;
-	if (*(skb->data + 3) == 0xFF)
-		if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
-		   (*(skb->data + frame_size / 2 + 12) == 0xAF))
+	frame_size /= 2;
+	if (*(skb->data + 3) == 0xFF) {
+		if ((*(skb->data + frame_size + 10) == 0xBE) &&
+		   (*(skb->data + frame_size + 12) == 0xAF)) {
 			return 0;
+		}
+	}
 	return 13;
 }
 
+static int igb_clean_test_rings(struct igb_ring *rx_ring,
+                                struct igb_ring *tx_ring,
+                                unsigned int size)
+{
+	union e1000_adv_rx_desc *rx_desc;
+	struct igb_buffer *buffer_info;
+	int rx_ntc, tx_ntc, count = 0;
+	u32 staterr;
+
+	/* initialize next to clean and descriptor values */
+	rx_ntc = rx_ring->next_to_clean;
+	tx_ntc = tx_ring->next_to_clean;
+	rx_desc = E1000_RX_DESC_ADV(*rx_ring, rx_ntc);
+	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+	while (staterr & E1000_RXD_STAT_DD) {
+		/* check rx buffer */
+		buffer_info = &rx_ring->buffer_info[rx_ntc];
+
+		/* unmap rx buffer, will be remapped by alloc_rx_buffers */
+		pci_unmap_single(rx_ring->pdev,
+		                 buffer_info->dma,
+				 rx_ring->rx_buffer_len,
+				 PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+
+		/* verify contents of skb */
+		if (!igb_check_lbtest_frame(buffer_info->skb, size))
+			count++;
+
+		/* unmap buffer on tx side */
+		buffer_info = &tx_ring->buffer_info[tx_ntc];
+		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
+
+		/* increment rx/tx next to clean counters */
+		rx_ntc++;
+		if (rx_ntc == rx_ring->count)
+			rx_ntc = 0;
+		tx_ntc++;
+		if (tx_ntc == tx_ring->count)
+			tx_ntc = 0;
+
+		/* fetch next descriptor */
+		rx_desc = E1000_RX_DESC_ADV(*rx_ring, rx_ntc);
+		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	}
+
+	/* re-map buffers to ring, store next to clean values */
+	igb_alloc_rx_buffers_adv(rx_ring, count);
+	rx_ring->next_to_clean = rx_ntc;
+	tx_ring->next_to_clean = tx_ntc;
+
+	return count;
+}
+
 static int igb_run_loopback_test(struct igb_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct igb_ring *tx_ring = &adapter->test_tx_ring;
 	struct igb_ring *rx_ring = &adapter->test_rx_ring;
-	struct pci_dev *pdev = adapter->pdev;
-	int i, j, k, l, lc, good_cnt;
-	int ret_val = 0;
-	unsigned long time;
+	int i, j, lc, good_cnt, ret_val = 0;
+	unsigned int size = 1024;
+	netdev_tx_t tx_ret_val;
+	struct sk_buff *skb;
 
-	wr32(E1000_RDT(0), rx_ring->count - 1);
+	/* allocate test skb */
+	skb = alloc_skb(size, GFP_KERNEL);
+	if (!skb)
+		return 11;
 
-	/* Calculate the loop count based on the largest descriptor ring
+	/* place data into test skb */
+	igb_create_lbtest_frame(skb, size);
+	skb_put(skb, size);
+
+	/*
+	 * Calculate the loop count based on the largest descriptor ring
 	 * The idea is to wrap the largest ring a number of times using 64
 	 * send/receive pairs during each loop
 	 */
@@ -1590,50 +1597,36 @@ static int igb_run_loopback_test(struct
 	else
 		lc = ((rx_ring->count / 64) * 2) + 1;
 
-	k = l = 0;
 	for (j = 0; j <= lc; j++) { /* loop count loop */
-		for (i = 0; i < 64; i++) { /* send the packets */
-			igb_create_lbtest_frame(tx_ring->buffer_info[k].skb,
-						1024);
-			pci_dma_sync_single_for_device(pdev,
-				tx_ring->buffer_info[k].dma,
-				tx_ring->buffer_info[k].length,
-				PCI_DMA_TODEVICE);
-			k++;
-			if (k == tx_ring->count)
-				k = 0;
-		}
-		wr32(E1000_TDT(0), k);
-		msleep(200);
-		time = jiffies; /* set the start time for the receive */
+		/* reset count of good packets */
 		good_cnt = 0;
-		do { /* receive the sent packets */
-			pci_dma_sync_single_for_cpu(pdev,
-					rx_ring->buffer_info[l].dma,
-					IGB_RXBUFFER_2048,
-					PCI_DMA_FROMDEVICE);
 
-			ret_val = igb_check_lbtest_frame(
-					     rx_ring->buffer_info[l].skb, 1024);
-			if (!ret_val)
+		/* place 64 packets on the transmit queue*/
+		for (i = 0; i < 64; i++) {
+			skb_get(skb);
+			tx_ret_val = igb_xmit_frame_ring_adv(skb, tx_ring);
+			if (tx_ret_val == NETDEV_TX_OK)
 				good_cnt++;
-			l++;
-			if (l == rx_ring->count)
-				l = 0;
-			/* time + 20 msecs (200 msecs on 2.4) is more than
-			 * enough time to complete the receives, if it's
-			 * exceeded, break and error off
-			 */
-		} while (good_cnt < 64 && jiffies < (time + 20));
+		}
+
 		if (good_cnt != 64) {
-			ret_val = 13; /* ret_val is the same as mis-compare */
+			ret_val = 12;
 			break;
 		}
-		if (jiffies >= (time + 20)) {
-			ret_val = 14; /* error code for time out error */
+
+		/* allow 200 milliseconds for packets to go from tx to rx */
+		msleep(200);
+
+		good_cnt = igb_clean_test_rings(rx_ring, tx_ring, size);
+		if (good_cnt != 64) {
+			ret_val = 13;
 			break;
 		}
 	} /* end loop count loop */
+
+	/* free the original skb */
+	kfree_skb(skb);
+
 	return ret_val;
 }
 
@@ -1686,8 +1679,7 @@ static int igb_link_test(struct igb_adap
 		if (hw->mac.autoneg)
 			msleep(4000);
 
-		if (!(rd32(E1000_STATUS) &
-		      E1000_STATUS_LU))
+		if (!(rd32(E1000_STATUS) & E1000_STATUS_LU))
 			*data = 1;
 	}
 	return *data;
@@ -1803,7 +1795,7 @@ static int igb_wol_exclusion(struct igb_
 		/* dual port cards only support WoL on port A from now on
 		 * unless it was enabled in the eeprom for port B
 		 * so exclude FUNC_1 ports from having WoL enabled */
-		if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1 &&
+		if ((rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) &&
 		    !adapter->eeprom_wol) {
 			wol->supported = 0;
 			break;
@@ -1869,7 +1861,6 @@ static int igb_set_wol(struct net_device
 		adapter->wol |= E1000_WUFC_BC;
 	if (wol->wolopts & WAKE_MAGIC)
 		adapter->wol |= E1000_WUFC_MAG;
-
 	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
 	return 0;
@@ -1882,12 +1873,19 @@ static int igb_phys_id(struct net_device
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	unsigned long timeout;
 
-	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
-		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+	timeout = data * 1000;
+
+	/*
+	 *  msleep_interruptable only accepts unsigned int so we are limited
+	 * in how long a duration we can wait
+	 */
+	if (!timeout || timeout > UINT_MAX)
+		timeout = UINT_MAX;
 
 	igb_blink_led(hw);
-	msleep_interruptible(data * 1000);
+	msleep_interruptible(timeout);
 
 	igb_led_off(hw);
 	clear_bit(IGB_LED_ON, &adapter->led_status);
@@ -1900,7 +1898,6 @@ static int igb_set_coalesce(struct net_d
 			    struct ethtool_coalesce *ec)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
 	int i;
 
 	if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
@@ -1909,17 +1906,39 @@ static int igb_set_coalesce(struct net_d
 	    (ec->rx_coalesce_usecs == 2))
 		return -EINVAL;
 
+	if ((ec->tx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
+	    ((ec->tx_coalesce_usecs > 3) &&
+	     (ec->tx_coalesce_usecs < IGB_MIN_ITR_USECS)) ||
+	    (ec->tx_coalesce_usecs == 2))
+		return -EINVAL;
+
+	if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs)
+		return -EINVAL;
+
 	/* convert to rate of irq's per second */
-	if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
-		adapter->itr_setting = ec->rx_coalesce_usecs;
-		adapter->itr = IGB_START_ITR;
-	} else {
-		adapter->itr_setting = ec->rx_coalesce_usecs << 2;
-		adapter->itr = adapter->itr_setting;
-	}
+	if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3)
+		adapter->rx_itr_setting = ec->rx_coalesce_usecs;
+	else
+		adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;
 
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		wr32(adapter->rx_ring[i].itr_register, adapter->itr);
+	/* convert to rate of irq's per second */
+	if (adapter->flags & IGB_FLAG_QUEUE_PAIRS)
+		adapter->tx_itr_setting = adapter->rx_itr_setting;
+	else if (ec->tx_coalesce_usecs && ec->tx_coalesce_usecs <= 3)
+		adapter->tx_itr_setting = ec->tx_coalesce_usecs;
+	else
+		adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;
+
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		if (q_vector->rx_ring)
+			q_vector->itr_val = adapter->rx_itr_setting;
+		else
+			q_vector->itr_val = adapter->tx_itr_setting;
+		if (q_vector->itr_val && q_vector->itr_val <= 3)
+			q_vector->itr_val = IGB_START_ITR;
+		q_vector->set_itr = 1;
+	}
 
 	return 0;
 }
@@ -1929,15 +1948,21 @@ static int igb_get_coalesce(struct net_d
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	if (adapter->itr_setting <= 3)
-		ec->rx_coalesce_usecs = adapter->itr_setting;
+	if (adapter->rx_itr_setting <= 3)
+		ec->rx_coalesce_usecs = adapter->rx_itr_setting;
 	else
-		ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
+		ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;
+
+	if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) {
+		if (adapter->tx_itr_setting <= 3)
+			ec->tx_coalesce_usecs = adapter->tx_itr_setting;
+		else
+			ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;
+	}
 
 	return 0;
 }
 
-
 static int igb_nway_reset(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
@@ -1962,31 +1987,32 @@ static void igb_get_ethtool_stats(struct
 				  struct ethtool_stats *stats, u64 *data)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct net_device_stats *net_stats = &netdev->stats;
 	u64 *queue_stat;
-	int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64);
-	int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64);
-	int j;
-	int i;
+	int i, j, k;
+	char *p;
 
 	igb_update_stats(adapter);
+
 	for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
-		char *p = (char *)adapter+igb_gstrings_stats[i].stat_offset;
+		p = (char *)adapter + igb_gstrings_stats[i].stat_offset;
 		data[i] = (igb_gstrings_stats[i].sizeof_stat ==
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
+	for (j = 0; j < IGB_NETDEV_STATS_LEN; j++, i++) {
+		p = (char *)net_stats + igb_gstrings_net_stats[j].stat_offset;
+		data[i] = (igb_gstrings_net_stats[j].sizeof_stat ==
+			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+	}
 	for (j = 0; j < adapter->num_tx_queues; j++) {
-		int k;
 		queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
-		for (k = 0; k < stat_count_tx; k++)
-			data[i + k] = queue_stat[k];
-		i += k;
+		for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
+			data[i] = queue_stat[k];
 	}
 	for (j = 0; j < adapter->num_rx_queues; j++) {
-		int k;
 		queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
-		for (k = 0; k < stat_count_rx; k++)
-			data[i + k] = queue_stat[k];
-		i += k;
+		for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
+			data[i] = queue_stat[k];
 	}
 }
 
@@ -2007,11 +2033,18 @@ static void igb_get_strings(struct net_d
 			       ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
+		for (i = 0; i < IGB_NETDEV_STATS_LEN; i++) {
+			memcpy(p, igb_gstrings_net_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
 		for (i = 0; i < adapter->num_tx_queues; i++) {
 			sprintf(p, "tx_queue_%u_packets", i);
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "tx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_queue_%u_restart", i);
+			p += ETH_GSTRING_LEN;
 		}
 		for (i = 0; i < adapter->num_rx_queues; i++) {
 			sprintf(p, "rx_queue_%u_packets", i);
@@ -2020,6 +2053,10 @@ static void igb_get_strings(struct net_d
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "rx_queue_%u_drops", i);
 			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_csum_err", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_alloc_failed", i);
+			p += ETH_GSTRING_LEN;
 		}
 /*		BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
 		break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/igb.h linux-libre-2.6.33-gnu1/drivers/net/igb/igb.h
--- linux-libre-2.6.32-gnu1/drivers/net/igb/igb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/igb.h	2010-02-24 13:52:17.000000000 -0500
@@ -55,12 +55,14 @@ struct igb_adapter;
 #define IGB_DEFAULT_ITR                    3 /* dynamic */
 #define IGB_MAX_ITR_USECS              10000
 #define IGB_MIN_ITR_USECS                 10
+#define NON_Q_VECTORS                      1
+#define MAX_Q_VECTORS                      8
 
 /* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES     (adapter->vfs_allocated_count ? \
-                               (adapter->vfs_allocated_count > 6 ? 1 : 2) : 4)
-#define IGB_MAX_TX_QUEUES     IGB_MAX_RX_QUEUES
-#define IGB_ABS_MAX_TX_QUEUES     4
+#define IGB_MAX_RX_QUEUES                  (adapter->vfs_allocated_count ? 2 : \
+                                           (hw->mac.type > e1000_82575 ? 8 : 4))
+#define IGB_ABS_MAX_TX_QUEUES              8
+#define IGB_MAX_TX_QUEUES                  IGB_MAX_RX_QUEUES
 
 #define IGB_MAX_VF_MC_ENTRIES              30
 #define IGB_MAX_VF_FUNCTIONS               8
@@ -71,9 +73,14 @@ struct vf_data_storage {
 	u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
 	u16 num_vf_mc_hashes;
 	u16 vlans_enabled;
-	bool clear_to_send;
+	u32 flags;
+	unsigned long last_nack;
 };
 
+#define IGB_VF_FLAG_CTS            0x00000001 /* VF is clear to send data */
+#define IGB_VF_FLAG_UNI_PROMISC    0x00000002 /* VF has unicast promisc */
+#define IGB_VF_FLAG_MULTI_PROMISC  0x00000004 /* VF has multicast promisc */
+
 /* RX descriptor control thresholds.
  * PTHRESH - MAC will consider prefetch if it has fewer than this number of
  *           descriptors available in its onboard memory.
@@ -85,17 +92,19 @@ struct vf_data_storage {
  *           descriptors until either it has this many to write back, or the
  *           ITR timer expires.
  */
-#define IGB_RX_PTHRESH                    16
+#define IGB_RX_PTHRESH                    (hw->mac.type <= e1000_82576 ? 16 : 8)
 #define IGB_RX_HTHRESH                     8
 #define IGB_RX_WTHRESH                     1
+#define IGB_TX_PTHRESH                     8
+#define IGB_TX_HTHRESH                     1
+#define IGB_TX_WTHRESH                     ((hw->mac.type == e1000_82576 && \
+                                             adapter->msix_entries) ? 0 : 16)
 
 /* this is the size past which hardware will drop packets when setting LPE=0 */
 #define MAXIMUM_ETHERNET_VLAN_SIZE 1522
 
 /* Supported Rx Buffer Sizes */
 #define IGB_RXBUFFER_128   128    /* Used for packet split */
-#define IGB_RXBUFFER_256   256    /* Used for packet split */
-#define IGB_RXBUFFER_512   512
 #define IGB_RXBUFFER_1024  1024
 #define IGB_RXBUFFER_2048  2048
 #define IGB_RXBUFFER_16384 16384
@@ -128,12 +137,13 @@ struct igb_buffer {
 			unsigned long time_stamp;
 			u16 length;
 			u16 next_to_watch;
+			u16 mapped_as_page;
 		};
 		/* RX */
 		struct {
 			struct page *page;
-			u64 page_dma;
-			unsigned int page_offset;
+			dma_addr_t page_dma;
+			u16 page_offset;
 		};
 	};
 };
@@ -141,36 +151,55 @@ struct igb_buffer {
 struct igb_tx_queue_stats {
 	u64 packets;
 	u64 bytes;
+	u64 restart_queue;
 };
 
 struct igb_rx_queue_stats {
 	u64 packets;
 	u64 bytes;
 	u64 drops;
+	u64 csum_err;
+	u64 alloc_failed;
 };
 
-struct igb_ring {
+struct igb_q_vector {
 	struct igb_adapter *adapter; /* backlink */
-	void *desc;                  /* descriptor ring memory */
-	dma_addr_t dma;              /* phys address of the ring */
-	unsigned int size;           /* length of desc. ring in bytes */
-	unsigned int count;          /* number of desc. in the ring */
-	u16 next_to_use;
-	u16 next_to_clean;
-	u16 head;
-	u16 tail;
-	struct igb_buffer *buffer_info; /* array of buffer info structs */
+	struct igb_ring *rx_ring;
+	struct igb_ring *tx_ring;
+	struct napi_struct napi;
 
 	u32 eims_value;
-	u32 itr_val;
-	u16 itr_register;
 	u16 cpu;
 
-	u16 queue_index;
-	u16 reg_idx;
+	u16 itr_val;
+	u8 set_itr;
+	u8 itr_shift;
+	void __iomem *itr_register;
+
+	char name[IFNAMSIZ + 9];
+};
+
+struct igb_ring {
+	struct igb_q_vector *q_vector; /* backlink to q_vector */
+	struct net_device *netdev;     /* back pointer to net_device */
+	struct pci_dev *pdev;          /* pci device for dma mapping */
+	dma_addr_t dma;                /* phys address of the ring */
+	void *desc;                    /* descriptor ring memory */
+	unsigned int size;             /* length of desc. ring in bytes */
+	u16 count;                     /* number of desc. in the ring */
+	u16 next_to_use;
+	u16 next_to_clean;
+	u8 queue_index;
+	u8 reg_idx;
+	void __iomem *head;
+	void __iomem *tail;
+	struct igb_buffer *buffer_info; /* array of buffer info structs */
+
 	unsigned int total_bytes;
 	unsigned int total_packets;
 
+	u32 flags;
+
 	union {
 		/* TX */
 		struct {
@@ -180,16 +209,18 @@ struct igb_ring {
 		/* RX */
 		struct {
 			struct igb_rx_queue_stats rx_stats;
-			u64 rx_queue_drops;
-			struct napi_struct napi;
-			int set_itr;
-			struct igb_ring *buddy;
+			u32 rx_buffer_len;
 		};
 	};
-
-	char name[IFNAMSIZ + 5];
 };
 
+#define IGB_RING_FLAG_RX_CSUM        0x00000001 /* RX CSUM enabled */
+#define IGB_RING_FLAG_RX_SCTP_CSUM   0x00000002 /* SCTP CSUM offload enabled */
+
+#define IGB_RING_FLAG_TX_CTX_IDX     0x00000001 /* HW requires context index */
+
+#define IGB_ADVTXD_DCMD (E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS)
+
 #define E1000_RX_DESC_ADV(R, i)	    \
 	(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
 #define E1000_TX_DESC_ADV(R, i)	    \
@@ -197,6 +228,15 @@ struct igb_ring {
 #define E1000_TX_CTXTDESC_ADV(R, i)	    \
 	(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
 
+/* igb_desc_unused - calculate if we have unused descriptors */
+static inline int igb_desc_unused(struct igb_ring *ring)
+{
+	if (ring->next_to_clean > ring->next_to_use)
+		return ring->next_to_clean - ring->next_to_use - 1;
+
+	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
+}
+
 /* board specific private data structure */
 
 struct igb_adapter {
@@ -205,18 +245,14 @@ struct igb_adapter {
 	struct vlan_group *vlgrp;
 	u16 mng_vlan_id;
 	u32 bd_number;
-	u32 rx_buffer_len;
 	u32 wol;
 	u32 en_mng_pt;
 	u16 link_speed;
 	u16 link_duplex;
-	unsigned int total_tx_bytes;
-	unsigned int total_tx_packets;
-	unsigned int total_rx_bytes;
-	unsigned int total_rx_packets;
+
 	/* Interrupt Throttle Rate */
-	u32 itr;
-	u32 itr_setting;
+	u32 rx_itr_setting;
+	u32 tx_itr_setting;
 	u16 tx_itr;
 	u16 rx_itr;
 
@@ -229,13 +265,7 @@ struct igb_adapter {
 
 	/* TX */
 	struct igb_ring *tx_ring;      /* One per active queue */
-	unsigned int restart_queue;
 	unsigned long tx_queue_len;
-	u32 txd_cmd;
-	u32 gotc;
-	u64 gotc_old;
-	u64 tpt_old;
-	u64 colc_old;
 	u32 tx_timeout_count;
 
 	/* RX */
@@ -243,20 +273,12 @@ struct igb_adapter {
 	int num_tx_queues;
 	int num_rx_queues;
 
-	u64 hw_csum_err;
-	u64 hw_csum_good;
-	u32 alloc_rx_buff_failed;
-	u32 gorc;
-	u64 gorc_old;
-	u16 rx_ps_hdr_size;
 	u32 max_frame_size;
 	u32 min_frame_size;
 
 	/* OS defined structs */
 	struct net_device *netdev;
-	struct napi_struct napi;
 	struct pci_dev *pdev;
-	struct net_device_stats net_stats;
 	struct cyclecounter cycles;
 	struct timecounter clock;
 	struct timecompare compare;
@@ -273,6 +295,9 @@ struct igb_adapter {
 	struct igb_ring test_rx_ring;
 
 	int msg_enable;
+
+	unsigned int num_q_vectors;
+	struct igb_q_vector *q_vector[MAX_Q_VECTORS];
 	struct msix_entry *msix_entries;
 	u32 eims_enable_mask;
 	u32 eims_other;
@@ -283,18 +308,20 @@ struct igb_adapter {
 	u32 eeprom_wol;
 
 	struct igb_ring *multi_tx_table[IGB_ABS_MAX_TX_QUEUES];
-	unsigned int tx_ring_count;
-	unsigned int rx_ring_count;
+	u16 tx_ring_count;
+	u16 rx_ring_count;
 	unsigned int vfs_allocated_count;
 	struct vf_data_storage *vf_data;
+	u32 rss_queues;
 };
 
 #define IGB_FLAG_HAS_MSI           (1 << 0)
 #define IGB_FLAG_DCA_ENABLED       (1 << 1)
 #define IGB_FLAG_QUAD_PORT_A       (1 << 2)
-#define IGB_FLAG_NEED_CTX_IDX      (1 << 3)
-#define IGB_FLAG_RX_CSUM_DISABLED  (1 << 4)
+#define IGB_FLAG_QUEUE_PAIRS       (1 << 3)
 
+#define IGB_82576_TSYNC_SHIFT 19
+#define IGB_82580_TSYNC_SHIFT 24
 enum e1000_state_t {
 	__IGB_TESTING,
 	__IGB_RESETTING,
@@ -314,10 +341,18 @@ extern void igb_down(struct igb_adapter
 extern void igb_reinit_locked(struct igb_adapter *);
 extern void igb_reset(struct igb_adapter *);
 extern int igb_set_spd_dplx(struct igb_adapter *, u16);
-extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *);
-extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *);
+extern int igb_setup_tx_resources(struct igb_ring *);
+extern int igb_setup_rx_resources(struct igb_ring *);
 extern void igb_free_tx_resources(struct igb_ring *);
 extern void igb_free_rx_resources(struct igb_ring *);
+extern void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *);
+extern void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *);
+extern void igb_setup_tctl(struct igb_adapter *);
+extern void igb_setup_rctl(struct igb_adapter *);
+extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *);
+extern void igb_unmap_and_free_tx_resource(struct igb_ring *,
+					   struct igb_buffer *);
+extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
 extern void igb_update_stats(struct igb_adapter *);
 extern void igb_set_ethtool_ops(struct net_device *);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igb/igb_main.c linux-libre-2.6.33-gnu1/drivers/net/igb/igb_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/igb/igb_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igb/igb_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -49,7 +49,7 @@
 #endif
 #include "igb.h"
 
-#define DRV_VERSION "1.3.16-k2"
+#define DRV_VERSION "2.1.0-k2"
 char igb_driver_name[] = "igb";
 char igb_driver_version[] = DRV_VERSION;
 static const char igb_driver_string[] =
@@ -61,8 +61,14 @@ static const struct e1000_info *igb_info
 };
 
 static struct pci_device_id igb_pci_tbl[] = {
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
@@ -81,6 +87,7 @@ static int igb_setup_all_tx_resources(st
 static int igb_setup_all_rx_resources(struct igb_adapter *);
 static void igb_free_all_tx_resources(struct igb_adapter *);
 static void igb_free_all_rx_resources(struct igb_adapter *);
+static void igb_setup_mrqc(struct igb_adapter *);
 void igb_update_stats(struct igb_adapter *);
 static int igb_probe(struct pci_dev *, const struct pci_device_id *);
 static void __devexit igb_remove(struct pci_dev *pdev);
@@ -89,7 +96,6 @@ static int igb_open(struct net_device *)
 static int igb_close(struct net_device *);
 static void igb_configure_tx(struct igb_adapter *);
 static void igb_configure_rx(struct igb_adapter *);
-static void igb_setup_rctl(struct igb_adapter *);
 static void igb_clean_all_tx_rings(struct igb_adapter *);
 static void igb_clean_all_rx_rings(struct igb_adapter *);
 static void igb_clean_tx_ring(struct igb_ring *);
@@ -98,28 +104,22 @@ static void igb_set_rx_mode(struct net_d
 static void igb_update_phy_info(unsigned long);
 static void igb_watchdog(unsigned long);
 static void igb_watchdog_task(struct work_struct *);
-static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *,
-					   struct net_device *,
-					   struct igb_ring *);
-static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
-				      struct net_device *);
+static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *);
 static struct net_device_stats *igb_get_stats(struct net_device *);
 static int igb_change_mtu(struct net_device *, int);
 static int igb_set_mac(struct net_device *, void *);
+static void igb_set_uta(struct igb_adapter *adapter);
 static irqreturn_t igb_intr(int irq, void *);
 static irqreturn_t igb_intr_msi(int irq, void *);
 static irqreturn_t igb_msix_other(int irq, void *);
-static irqreturn_t igb_msix_rx(int irq, void *);
-static irqreturn_t igb_msix_tx(int irq, void *);
+static irqreturn_t igb_msix_ring(int irq, void *);
 #ifdef CONFIG_IGB_DCA
-static void igb_update_rx_dca(struct igb_ring *);
-static void igb_update_tx_dca(struct igb_ring *);
+static void igb_update_dca(struct igb_q_vector *);
 static void igb_setup_dca(struct igb_adapter *);
 #endif /* CONFIG_IGB_DCA */
-static bool igb_clean_tx_irq(struct igb_ring *);
+static bool igb_clean_tx_irq(struct igb_q_vector *);
 static int igb_poll(struct napi_struct *, int);
-static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
-static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
+static bool igb_clean_rx_irq_adv(struct igb_q_vector *, int *, int);
 static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
 static void igb_tx_timeout(struct net_device *);
 static void igb_reset_task(struct work_struct *);
@@ -127,57 +127,13 @@ static void igb_vlan_rx_register(struct
 static void igb_vlan_rx_add_vid(struct net_device *, u16);
 static void igb_vlan_rx_kill_vid(struct net_device *, u16);
 static void igb_restore_vlan(struct igb_adapter *);
+static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);
 static void igb_ping_all_vfs(struct igb_adapter *);
 static void igb_msg_task(struct igb_adapter *);
-static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
 static void igb_vmm_control(struct igb_adapter *);
-static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
+static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
 
-static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
-{
-	u32 reg_data;
-
-	reg_data = rd32(E1000_VMOLR(vfn));
-	reg_data |= E1000_VMOLR_BAM |	 /* Accept broadcast */
-	            E1000_VMOLR_ROPE |   /* Accept packets matched in UTA */
-	            E1000_VMOLR_ROMPE |  /* Accept packets matched in MTA */
-	            E1000_VMOLR_AUPE |   /* Accept untagged packets */
-	            E1000_VMOLR_STRVLAN; /* Strip vlan tags */
-	wr32(E1000_VMOLR(vfn), reg_data);
-}
-
-static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
-                                 int vfn)
-{
-	struct e1000_hw *hw = &adapter->hw;
-	u32 vmolr;
-
-	/* if it isn't the PF check to see if VFs are enabled and
-	 * increase the size to support vlan tags */
-	if (vfn < adapter->vfs_allocated_count &&
-	    adapter->vf_data[vfn].vlans_enabled)
-		size += VLAN_TAG_SIZE;
-
-	vmolr = rd32(E1000_VMOLR(vfn));
-	vmolr &= ~E1000_VMOLR_RLPML_MASK;
-	vmolr |= size | E1000_VMOLR_LPE;
-	wr32(E1000_VMOLR(vfn), vmolr);
-
-	return 0;
-}
-
-static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
-{
-	u32 reg_data;
-
-	reg_data = rd32(E1000_RAH(entry));
-	reg_data &= ~E1000_RAH_POOL_MASK;
-	reg_data |= E1000_RAH_POOL_1 << pool;;
-	wr32(E1000_RAH(entry), reg_data);
-}
-
 #ifdef CONFIG_PM
 static int igb_suspend(struct pci_dev *, pm_message_t);
 static int igb_resume(struct pci_dev *);
@@ -228,46 +184,12 @@ static struct pci_driver igb_driver = {
 	.err_handler = &igb_err_handler
 };
 
-static int global_quad_port_a; /* global quad port a indication */
-
 MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
 MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
 /**
- * Scale the NIC clock cycle by a large factor so that
- * relatively small clock corrections can be added or
- * substracted at each clock tick. The drawbacks of a
- * large factor are a) that the clock register overflows
- * more quickly (not such a big deal) and b) that the
- * increment per tick has to fit into 24 bits.
- *
- * Note that
- *   TIMINCA = IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS *
- *             IGB_TSYNC_SCALE
- *   TIMINCA += TIMINCA * adjustment [ppm] / 1e9
- *
- * The base scale factor is intentionally a power of two
- * so that the division in %struct timecounter can be done with
- * a shift.
- */
-#define IGB_TSYNC_SHIFT (19)
-#define IGB_TSYNC_SCALE (1<<IGB_TSYNC_SHIFT)
-
-/**
- * The duration of one clock cycle of the NIC.
- *
- * @todo This hard-coded value is part of the specification and might change
- * in future hardware revisions. Add revision check.
- */
-#define IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS 16
-
-#if (IGB_TSYNC_SCALE * IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS) >= (1<<24)
-# error IGB_TSYNC_SCALE and/or IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS are too large to fit into TIMINCA
-#endif
-
-/**
  * igb_read_clock - read raw cycle counter (to be used by time counter)
  */
 static cycle_t igb_read_clock(const struct cyclecounter *tc)
@@ -275,11 +197,21 @@ static cycle_t igb_read_clock(const stru
 	struct igb_adapter *adapter =
 		container_of(tc, struct igb_adapter, cycles);
 	struct e1000_hw *hw = &adapter->hw;
-	u64 stamp;
+	u64 stamp = 0;
+	int shift = 0;
 
-	stamp =  rd32(E1000_SYSTIML);
-	stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL;
+	/*
+	 * The timestamp latches on lowest register read. For the 82580
+	 * the lowest register is SYSTIMR instead of SYSTIML.  However we never
+	 * adjusted TIMINCA so SYSTIMR will just read as all 0s so ignore it.
+	 */
+	if (hw->mac.type == e1000_82580) {
+		stamp = rd32(E1000_SYSTIMR) >> 8;
+		shift = IGB_82580_TSYNC_SHIFT;
+	}
 
+	stamp |= (u64)rd32(E1000_SYSTIML) << shift;
+	stamp |= (u64)rd32(E1000_SYSTIMH) << (shift + 32);
 	return stamp;
 }
 
@@ -320,17 +252,6 @@ static char *igb_get_time_str(struct igb
 #endif
 
 /**
- * igb_desc_unused - calculate if we have unused descriptors
- **/
-static int igb_desc_unused(struct igb_ring *ring)
-{
-	if (ring->next_to_clean > ring->next_to_use)
-		return ring->next_to_clean - ring->next_to_use - 1;
-
-	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
-}
-
-/**
  * igb_init_module - Driver Registration Routine
  *
  * igb_init_module is the first routine called when the driver is
@@ -344,12 +265,9 @@ static int __init igb_init_module(void)
 
 	printk(KERN_INFO "%s\n", igb_copyright);
 
-	global_quad_port_a = 0;
-
 #ifdef CONFIG_IGB_DCA
 	dca_register_notify(&dca_notifier);
 #endif
-
 	ret = pci_register_driver(&igb_driver);
 	return ret;
 }
@@ -382,8 +300,8 @@ module_exit(igb_exit_module);
  **/
 static void igb_cache_ring_register(struct igb_adapter *adapter)
 {
-	int i;
-	unsigned int rbase_offset = adapter->vfs_allocated_count;
+	int i = 0, j = 0;
+	u32 rbase_offset = adapter->vfs_allocated_count;
 
 	switch (adapter->hw.mac.type) {
 	case e1000_82576:
@@ -392,23 +310,37 @@ static void igb_cache_ring_register(stru
 		 * In order to avoid collision we start at the first free queue
 		 * and continue consuming queues in the same sequence
 		 */
-		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = rbase_offset +
-			                              Q_IDX_82576(i);
-		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].reg_idx = rbase_offset +
-			                              Q_IDX_82576(i);
-		break;
+		if (adapter->vfs_allocated_count) {
+			for (; i < adapter->rss_queues; i++)
+				adapter->rx_ring[i].reg_idx = rbase_offset +
+				                              Q_IDX_82576(i);
+			for (; j < adapter->rss_queues; j++)
+				adapter->tx_ring[j].reg_idx = rbase_offset +
+				                              Q_IDX_82576(j);
+		}
 	case e1000_82575:
+	case e1000_82580:
 	default:
-		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = i;
-		for (i = 0; i < adapter->num_tx_queues; i++)
-			adapter->tx_ring[i].reg_idx = i;
+		for (; i < adapter->num_rx_queues; i++)
+			adapter->rx_ring[i].reg_idx = rbase_offset + i;
+		for (; j < adapter->num_tx_queues; j++)
+			adapter->tx_ring[j].reg_idx = rbase_offset + j;
 		break;
 	}
 }
 
+static void igb_free_queues(struct igb_adapter *adapter)
+{
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+
+	adapter->tx_ring = NULL;
+	adapter->rx_ring = NULL;
+
+	adapter->num_rx_queues = 0;
+	adapter->num_tx_queues = 0;
+}
+
 /**
  * igb_alloc_queues - Allocate memory for all rings
  * @adapter: board private structure to initialize
@@ -423,59 +355,61 @@ static int igb_alloc_queues(struct igb_a
 	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
 				   sizeof(struct igb_ring), GFP_KERNEL);
 	if (!adapter->tx_ring)
-		return -ENOMEM;
+		goto err;
 
 	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
 				   sizeof(struct igb_ring), GFP_KERNEL);
-	if (!adapter->rx_ring) {
-		kfree(adapter->tx_ring);
-		return -ENOMEM;
-	}
-
-	adapter->rx_ring->buddy = adapter->tx_ring;
+	if (!adapter->rx_ring)
+		goto err;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
 		struct igb_ring *ring = &(adapter->tx_ring[i]);
 		ring->count = adapter->tx_ring_count;
-		ring->adapter = adapter;
 		ring->queue_index = i;
+		ring->pdev = adapter->pdev;
+		ring->netdev = adapter->netdev;
+		/* For 82575, context index must be unique per ring. */
+		if (adapter->hw.mac.type == e1000_82575)
+			ring->flags = IGB_RING_FLAG_TX_CTX_IDX;
 	}
+
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		struct igb_ring *ring = &(adapter->rx_ring[i]);
 		ring->count = adapter->rx_ring_count;
-		ring->adapter = adapter;
 		ring->queue_index = i;
-		ring->itr_register = E1000_ITR;
-
-		/* set a default napi handler for each rx_ring */
-		netif_napi_add(adapter->netdev, &ring->napi, igb_poll, 64);
+		ring->pdev = adapter->pdev;
+		ring->netdev = adapter->netdev;
+		ring->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+		ring->flags = IGB_RING_FLAG_RX_CSUM; /* enable rx checksum */
+		/* set flag indicating ring supports SCTP checksum offload */
+		if (adapter->hw.mac.type >= e1000_82576)
+			ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM;
 	}
 
 	igb_cache_ring_register(adapter);
-	return 0;
-}
 
-static void igb_free_queues(struct igb_adapter *adapter)
-{
-	int i;
-
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		netif_napi_del(&adapter->rx_ring[i].napi);
+	return 0;
 
-	adapter->num_rx_queues = 0;
-	adapter->num_tx_queues = 0;
+err:
+	igb_free_queues(adapter);
 
-	kfree(adapter->tx_ring);
-	kfree(adapter->rx_ring);
+	return -ENOMEM;
 }
 
 #define IGB_N0_QUEUE -1
-static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
-			      int tx_queue, int msix_vector)
+static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
 {
 	u32 msixbm = 0;
+	struct igb_adapter *adapter = q_vector->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 ivar, index;
+	int rx_queue = IGB_N0_QUEUE;
+	int tx_queue = IGB_N0_QUEUE;
+
+	if (q_vector->rx_ring)
+		rx_queue = q_vector->rx_ring->reg_idx;
+	if (q_vector->tx_ring)
+		tx_queue = q_vector->tx_ring->reg_idx;
 
 	switch (hw->mac.type) {
 	case e1000_82575:
@@ -483,16 +417,14 @@ static void igb_assign_vector(struct igb
 		   bitmask for the EICR/EIMS/EIMC registers.  To assign one
 		   or more queues to a vector, we write the appropriate bits
 		   into the MSIXBM register for that vector. */
-		if (rx_queue > IGB_N0_QUEUE) {
+		if (rx_queue > IGB_N0_QUEUE)
 			msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
-			adapter->rx_ring[rx_queue].eims_value = msixbm;
-		}
-		if (tx_queue > IGB_N0_QUEUE) {
+		if (tx_queue > IGB_N0_QUEUE)
 			msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
-			adapter->tx_ring[tx_queue].eims_value =
-				  E1000_EICR_TX_QUEUE0 << tx_queue;
-		}
+		if (!adapter->msix_entries && msix_vector == 0)
+			msixbm |= E1000_EIMS_OTHER;
 		array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
+		q_vector->eims_value = msixbm;
 		break;
 	case e1000_82576:
 		/* 82576 uses a table-based method for assigning vectors.
@@ -500,7 +432,40 @@ static void igb_assign_vector(struct igb
 		   a vector number along with a "valid" bit.  Sadly, the layout
 		   of the table is somewhat counterintuitive. */
 		if (rx_queue > IGB_N0_QUEUE) {
-			index = (rx_queue >> 1) + adapter->vfs_allocated_count;
+			index = (rx_queue & 0x7);
+			ivar = array_rd32(E1000_IVAR0, index);
+			if (rx_queue < 8) {
+				/* vector goes into low byte of register */
+				ivar = ivar & 0xFFFFFF00;
+				ivar |= msix_vector | E1000_IVAR_VALID;
+			} else {
+				/* vector goes into third byte of register */
+				ivar = ivar & 0xFF00FFFF;
+				ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+			}
+			array_wr32(E1000_IVAR0, index, ivar);
+		}
+		if (tx_queue > IGB_N0_QUEUE) {
+			index = (tx_queue & 0x7);
+			ivar = array_rd32(E1000_IVAR0, index);
+			if (tx_queue < 8) {
+				/* vector goes into second byte of register */
+				ivar = ivar & 0xFFFF00FF;
+				ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+			} else {
+				/* vector goes into high byte of register */
+				ivar = ivar & 0x00FFFFFF;
+				ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+			}
+			array_wr32(E1000_IVAR0, index, ivar);
+		}
+		q_vector->eims_value = 1 << msix_vector;
+		break;
+	case e1000_82580:
+		/* 82580 uses the same table-based approach as 82576 but has fewer
+		   entries as a result we carry over for queues greater than 4. */
+		if (rx_queue > IGB_N0_QUEUE) {
+			index = (rx_queue >> 1);
 			ivar = array_rd32(E1000_IVAR0, index);
 			if (rx_queue & 0x1) {
 				/* vector goes into third byte of register */
@@ -511,11 +476,10 @@ static void igb_assign_vector(struct igb
 				ivar = ivar & 0xFFFFFF00;
 				ivar |= msix_vector | E1000_IVAR_VALID;
 			}
-			adapter->rx_ring[rx_queue].eims_value= 1 << msix_vector;
 			array_wr32(E1000_IVAR0, index, ivar);
 		}
 		if (tx_queue > IGB_N0_QUEUE) {
-			index = (tx_queue >> 1) + adapter->vfs_allocated_count;
+			index = (tx_queue >> 1);
 			ivar = array_rd32(E1000_IVAR0, index);
 			if (tx_queue & 0x1) {
 				/* vector goes into high byte of register */
@@ -526,9 +490,9 @@ static void igb_assign_vector(struct igb
 				ivar = ivar & 0xFFFF00FF;
 				ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
 			}
-			adapter->tx_ring[tx_queue].eims_value= 1 << msix_vector;
 			array_wr32(E1000_IVAR0, index, ivar);
 		}
+		q_vector->eims_value = 1 << msix_vector;
 		break;
 	default:
 		BUG();
@@ -549,43 +513,10 @@ static void igb_configure_msix(struct ig
 	struct e1000_hw *hw = &adapter->hw;
 
 	adapter->eims_enable_mask = 0;
-	if (hw->mac.type == e1000_82576)
-		/* Turn on MSI-X capability first, or our settings
-		 * won't stick.  And it will take days to debug. */
-		wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
-				   E1000_GPIE_PBA | E1000_GPIE_EIAME |
- 				   E1000_GPIE_NSICR);
-
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *tx_ring = &adapter->tx_ring[i];
-		igb_assign_vector(adapter, IGB_N0_QUEUE, i, vector++);
-		adapter->eims_enable_mask |= tx_ring->eims_value;
-		if (tx_ring->itr_val)
-			writel(tx_ring->itr_val,
-			       hw->hw_addr + tx_ring->itr_register);
-		else
-			writel(1, hw->hw_addr + tx_ring->itr_register);
-	}
-
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		struct igb_ring *rx_ring = &adapter->rx_ring[i];
-		rx_ring->buddy = NULL;
-		igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
-		adapter->eims_enable_mask |= rx_ring->eims_value;
-		if (rx_ring->itr_val)
-			writel(rx_ring->itr_val,
-			       hw->hw_addr + rx_ring->itr_register);
-		else
-			writel(1, hw->hw_addr + rx_ring->itr_register);
-	}
-
 
 	/* set vector for other causes, i.e. link changes */
 	switch (hw->mac.type) {
 	case e1000_82575:
-		array_wr32(E1000_MSIXBM(0), vector++,
-				      E1000_EIMS_OTHER);
-
 		tmp = rd32(E1000_CTRL_EXT);
 		/* enable MSI-X PBA support*/
 		tmp |= E1000_CTRL_EXT_PBA_CLR;
@@ -595,22 +526,41 @@ static void igb_configure_msix(struct ig
 		tmp |= E1000_CTRL_EXT_IRCA;
 
 		wr32(E1000_CTRL_EXT, tmp);
-		adapter->eims_enable_mask |= E1000_EIMS_OTHER;
+
+		/* enable msix_other interrupt */
+		array_wr32(E1000_MSIXBM(0), vector++,
+		                      E1000_EIMS_OTHER);
 		adapter->eims_other = E1000_EIMS_OTHER;
 
 		break;
 
 	case e1000_82576:
+	case e1000_82580:
+		/* Turn on MSI-X capability first, or our settings
+		 * won't stick.  And it will take days to debug. */
+		wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
+		                E1000_GPIE_PBA | E1000_GPIE_EIAME |
+		                E1000_GPIE_NSICR);
+
+		/* enable msix_other interrupt */
+		adapter->eims_other = 1 << vector;
 		tmp = (vector++ | E1000_IVAR_VALID) << 8;
-		wr32(E1000_IVAR_MISC, tmp);
 
-		adapter->eims_enable_mask = (1 << (vector)) - 1;
-		adapter->eims_other = 1 << (vector - 1);
+		wr32(E1000_IVAR_MISC, tmp);
 		break;
 	default:
 		/* do nothing, since nothing else supports MSI-X */
 		break;
 	} /* switch (hw->mac.type) */
+
+	adapter->eims_enable_mask |= adapter->eims_other;
+
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		igb_assign_vector(q_vector, vector++);
+		adapter->eims_enable_mask |= q_vector->eims_value;
+	}
+
 	wrfl();
 }
 
@@ -623,43 +573,40 @@ static void igb_configure_msix(struct ig
 static int igb_request_msix(struct igb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
 	int i, err = 0, vector = 0;
 
-	vector = 0;
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  igb_msix_other, 0, netdev->name, adapter);
+	if (err)
+		goto out;
+	vector++;
 
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *ring = &(adapter->tx_ring[i]);
-		sprintf(ring->name, "%s-tx-%d", netdev->name, i);
-		err = request_irq(adapter->msix_entries[vector].vector,
-				  &igb_msix_tx, 0, ring->name,
-				  &(adapter->tx_ring[i]));
-		if (err)
-			goto out;
-		ring->itr_register = E1000_EITR(0) + (vector << 2);
-		ring->itr_val = 976; /* ~4000 ints/sec */
-		vector++;
-	}
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		struct igb_ring *ring = &(adapter->rx_ring[i]);
-		if (strlen(netdev->name) < (IFNAMSIZ - 5))
-			sprintf(ring->name, "%s-rx-%d", netdev->name, i);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+
+		q_vector->itr_register = hw->hw_addr + E1000_EITR(vector);
+
+		if (q_vector->rx_ring && q_vector->tx_ring)
+			sprintf(q_vector->name, "%s-TxRx-%u", netdev->name,
+			        q_vector->rx_ring->queue_index);
+		else if (q_vector->tx_ring)
+			sprintf(q_vector->name, "%s-tx-%u", netdev->name,
+			        q_vector->tx_ring->queue_index);
+		else if (q_vector->rx_ring)
+			sprintf(q_vector->name, "%s-rx-%u", netdev->name,
+			        q_vector->rx_ring->queue_index);
 		else
-			memcpy(ring->name, netdev->name, IFNAMSIZ);
+			sprintf(q_vector->name, "%s-unused", netdev->name);
+
 		err = request_irq(adapter->msix_entries[vector].vector,
-				  &igb_msix_rx, 0, ring->name,
-				  &(adapter->rx_ring[i]));
+		                  igb_msix_ring, 0, q_vector->name,
+		                  q_vector);
 		if (err)
 			goto out;
-		ring->itr_register = E1000_EITR(0) + (vector << 2);
-		ring->itr_val = adapter->itr;
 		vector++;
 	}
 
-	err = request_irq(adapter->msix_entries[vector].vector,
-			  &igb_msix_other, 0, netdev->name, netdev);
-	if (err)
-		goto out;
-
 	igb_configure_msix(adapter);
 	return 0;
 out:
@@ -672,11 +619,44 @@ static void igb_reset_interrupt_capabili
 		pci_disable_msix(adapter->pdev);
 		kfree(adapter->msix_entries);
 		adapter->msix_entries = NULL;
-	} else if (adapter->flags & IGB_FLAG_HAS_MSI)
+	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
 		pci_disable_msi(adapter->pdev);
-	return;
+	}
+}
+
+/**
+ * igb_free_q_vectors - Free memory allocated for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function frees the memory allocated to the q_vectors.  In addition if
+ * NAPI is enabled it will delete any references to the NAPI struct prior
+ * to freeing the q_vector.
+ **/
+static void igb_free_q_vectors(struct igb_adapter *adapter)
+{
+	int v_idx;
+
+	for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
+		adapter->q_vector[v_idx] = NULL;
+		netif_napi_del(&q_vector->napi);
+		kfree(q_vector);
+	}
+	adapter->num_q_vectors = 0;
 }
 
+/**
+ * igb_clear_interrupt_scheme - reset the device to a state of no interrupts
+ *
+ * This function resets the device so that it has 0 rx queues, tx queues, and
+ * MSI-X interrupts allocated.
+ */
+static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
+{
+	igb_free_queues(adapter);
+	igb_free_q_vectors(adapter);
+	igb_reset_interrupt_capability(adapter);
+}
 
 /**
  * igb_set_interrupt_capability - set MSI or MSI-X if supported
@@ -690,11 +670,21 @@ static void igb_set_interrupt_capability
 	int numvecs, i;
 
 	/* Number of supported queues. */
-	/* Having more queues than CPUs doesn't make sense. */
-	adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
-	adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus());
+	adapter->num_rx_queues = adapter->rss_queues;
+	adapter->num_tx_queues = adapter->rss_queues;
 
-	numvecs = adapter->num_tx_queues + adapter->num_rx_queues + 1;
+	/* start with one vector for every rx queue */
+	numvecs = adapter->num_rx_queues;
+
+	/* if tx handler is seperate add 1 for every tx queue */
+	if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS))
+		numvecs += adapter->num_tx_queues;
+
+	/* store the number of vectors reserved for queues */
+	adapter->num_q_vectors = numvecs;
+
+	/* add 1 vector for link status interrupts */
+	numvecs++;
 	adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
 					GFP_KERNEL);
 	if (!adapter->msix_entries)
@@ -728,8 +718,12 @@ msi_only:
 		dev_info(&adapter->pdev->dev, "IOV Disabled\n");
 	}
 #endif
+	adapter->vfs_allocated_count = 0;
+	adapter->rss_queues = 1;
+	adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
 	adapter->num_rx_queues = 1;
 	adapter->num_tx_queues = 1;
+	adapter->num_q_vectors = 1;
 	if (!pci_enable_msi(adapter->pdev))
 		adapter->flags |= IGB_FLAG_HAS_MSI;
 out:
@@ -739,6 +733,143 @@ out:
 }
 
 /**
+ * igb_alloc_q_vectors - Allocate memory for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one q_vector per queue interrupt.  If allocation fails we
+ * return -ENOMEM.
+ **/
+static int igb_alloc_q_vectors(struct igb_adapter *adapter)
+{
+	struct igb_q_vector *q_vector;
+	struct e1000_hw *hw = &adapter->hw;
+	int v_idx;
+
+	for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) {
+		q_vector = kzalloc(sizeof(struct igb_q_vector), GFP_KERNEL);
+		if (!q_vector)
+			goto err_out;
+		q_vector->adapter = adapter;
+		q_vector->itr_shift = (hw->mac.type == e1000_82575) ? 16 : 0;
+		q_vector->itr_register = hw->hw_addr + E1000_EITR(0);
+		q_vector->itr_val = IGB_START_ITR;
+		q_vector->set_itr = 1;
+		netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
+		adapter->q_vector[v_idx] = q_vector;
+	}
+	return 0;
+
+err_out:
+	while (v_idx) {
+		v_idx--;
+		q_vector = adapter->q_vector[v_idx];
+		netif_napi_del(&q_vector->napi);
+		kfree(q_vector);
+		adapter->q_vector[v_idx] = NULL;
+	}
+	return -ENOMEM;
+}
+
+static void igb_map_rx_ring_to_vector(struct igb_adapter *adapter,
+                                      int ring_idx, int v_idx)
+{
+	struct igb_q_vector *q_vector;
+
+	q_vector = adapter->q_vector[v_idx];
+	q_vector->rx_ring = &adapter->rx_ring[ring_idx];
+	q_vector->rx_ring->q_vector = q_vector;
+	q_vector->itr_val = adapter->rx_itr_setting;
+	if (q_vector->itr_val && q_vector->itr_val <= 3)
+		q_vector->itr_val = IGB_START_ITR;
+}
+
+static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter,
+                                      int ring_idx, int v_idx)
+{
+	struct igb_q_vector *q_vector;
+
+	q_vector = adapter->q_vector[v_idx];
+	q_vector->tx_ring = &adapter->tx_ring[ring_idx];
+	q_vector->tx_ring->q_vector = q_vector;
+	q_vector->itr_val = adapter->tx_itr_setting;
+	if (q_vector->itr_val && q_vector->itr_val <= 3)
+		q_vector->itr_val = IGB_START_ITR;
+}
+
+/**
+ * igb_map_ring_to_vector - maps allocated queues to vectors
+ *
+ * This function maps the recently allocated queues to vectors.
+ **/
+static int igb_map_ring_to_vector(struct igb_adapter *adapter)
+{
+	int i;
+	int v_idx = 0;
+
+	if ((adapter->num_q_vectors < adapter->num_rx_queues) ||
+	    (adapter->num_q_vectors < adapter->num_tx_queues))
+		return -ENOMEM;
+
+	if (adapter->num_q_vectors >=
+	    (adapter->num_rx_queues + adapter->num_tx_queues)) {
+		for (i = 0; i < adapter->num_rx_queues; i++)
+			igb_map_rx_ring_to_vector(adapter, i, v_idx++);
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			igb_map_tx_ring_to_vector(adapter, i, v_idx++);
+	} else {
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			if (i < adapter->num_tx_queues)
+				igb_map_tx_ring_to_vector(adapter, i, v_idx);
+			igb_map_rx_ring_to_vector(adapter, i, v_idx++);
+		}
+		for (; i < adapter->num_tx_queues; i++)
+			igb_map_tx_ring_to_vector(adapter, i, v_idx++);
+	}
+	return 0;
+}
+
+/**
+ * igb_init_interrupt_scheme - initialize interrupts, allocate queues/vectors
+ *
+ * This function initializes the interrupts and allocates all of the queues.
+ **/
+static int igb_init_interrupt_scheme(struct igb_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int err;
+
+	igb_set_interrupt_capability(adapter);
+
+	err = igb_alloc_q_vectors(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to allocate memory for vectors\n");
+		goto err_alloc_q_vectors;
+	}
+
+	err = igb_alloc_queues(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+		goto err_alloc_queues;
+	}
+
+	err = igb_map_ring_to_vector(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Invalid q_vector to ring mapping\n");
+		goto err_map_queues;
+	}
+
+
+	return 0;
+err_map_queues:
+	igb_free_queues(adapter);
+err_alloc_queues:
+	igb_free_q_vectors(adapter);
+err_alloc_q_vectors:
+	igb_reset_interrupt_capability(adapter);
+	return err;
+}
+
+/**
  * igb_request_irq - initialize interrupts
  *
  * Attempts to configure interrupts using the best available
@@ -747,7 +878,7 @@ out:
 static int igb_request_irq(struct igb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct e1000_hw *hw = &adapter->hw;
+	struct pci_dev *pdev = adapter->pdev;
 	int err = 0;
 
 	if (adapter->msix_entries) {
@@ -755,39 +886,46 @@ static int igb_request_irq(struct igb_ad
 		if (!err)
 			goto request_done;
 		/* fall back to MSI */
-		igb_reset_interrupt_capability(adapter);
+		igb_clear_interrupt_scheme(adapter);
 		if (!pci_enable_msi(adapter->pdev))
 			adapter->flags |= IGB_FLAG_HAS_MSI;
 		igb_free_all_tx_resources(adapter);
 		igb_free_all_rx_resources(adapter);
+		adapter->num_tx_queues = 1;
 		adapter->num_rx_queues = 1;
-		igb_alloc_queues(adapter);
-	} else {
-		switch (hw->mac.type) {
-		case e1000_82575:
-			wr32(E1000_MSIXBM(0),
-			     (E1000_EICR_RX_QUEUE0 | E1000_EIMS_OTHER));
-			break;
-		case e1000_82576:
-			wr32(E1000_IVAR0, E1000_IVAR_VALID);
-			break;
-		default:
-			break;
+		adapter->num_q_vectors = 1;
+		err = igb_alloc_q_vectors(adapter);
+		if (err) {
+			dev_err(&pdev->dev,
+			        "Unable to allocate memory for vectors\n");
+			goto request_done;
+		}
+		err = igb_alloc_queues(adapter);
+		if (err) {
+			dev_err(&pdev->dev,
+			        "Unable to allocate memory for queues\n");
+			igb_free_q_vectors(adapter);
+			goto request_done;
 		}
+		igb_setup_all_tx_resources(adapter);
+		igb_setup_all_rx_resources(adapter);
+	} else {
+		igb_assign_vector(adapter->q_vector[0], 0);
 	}
 
 	if (adapter->flags & IGB_FLAG_HAS_MSI) {
-		err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
-				  netdev->name, netdev);
+		err = request_irq(adapter->pdev->irq, igb_intr_msi, 0,
+				  netdev->name, adapter);
 		if (!err)
 			goto request_done;
+
 		/* fall back to legacy interrupts */
 		igb_reset_interrupt_capability(adapter);
 		adapter->flags &= ~IGB_FLAG_HAS_MSI;
 	}
 
-	err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
-			  netdev->name, netdev);
+	err = request_irq(adapter->pdev->irq, igb_intr, IRQF_SHARED,
+			  netdev->name, adapter);
 
 	if (err)
 		dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
@@ -799,23 +937,19 @@ request_done:
 
 static void igb_free_irq(struct igb_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
-
 	if (adapter->msix_entries) {
 		int vector = 0, i;
 
-		for (i = 0; i < adapter->num_tx_queues; i++)
-			free_irq(adapter->msix_entries[vector++].vector,
-				&(adapter->tx_ring[i]));
-		for (i = 0; i < adapter->num_rx_queues; i++)
-			free_irq(adapter->msix_entries[vector++].vector,
-				&(adapter->rx_ring[i]));
+		free_irq(adapter->msix_entries[vector++].vector, adapter);
 
-		free_irq(adapter->msix_entries[vector++].vector, netdev);
-		return;
+		for (i = 0; i < adapter->num_q_vectors; i++) {
+			struct igb_q_vector *q_vector = adapter->q_vector[i];
+			free_irq(adapter->msix_entries[vector++].vector,
+			         q_vector);
+		}
+	} else {
+		free_irq(adapter->pdev->irq, adapter);
 	}
-
-	free_irq(adapter->pdev->irq, netdev);
 }
 
 /**
@@ -826,6 +960,11 @@ static void igb_irq_disable(struct igb_a
 {
 	struct e1000_hw *hw = &adapter->hw;
 
+	/*
+	 * we need to be careful when disabling interrupts.  The VFs are also
+	 * mapped into these registers and so clearing the bits can cause
+	 * issues on the VF drivers so we only need to clear what we set
+	 */
 	if (adapter->msix_entries) {
 		u32 regval = rd32(E1000_EIAM);
 		wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask);
@@ -849,41 +988,47 @@ static void igb_irq_enable(struct igb_ad
 	struct e1000_hw *hw = &adapter->hw;
 
 	if (adapter->msix_entries) {
+		u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC;
 		u32 regval = rd32(E1000_EIAC);
 		wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
 		regval = rd32(E1000_EIAM);
 		wr32(E1000_EIAM, regval | adapter->eims_enable_mask);
 		wr32(E1000_EIMS, adapter->eims_enable_mask);
-		if (adapter->vfs_allocated_count)
+		if (adapter->vfs_allocated_count) {
 			wr32(E1000_MBVFIMR, 0xFF);
-		wr32(E1000_IMS, (E1000_IMS_LSC | E1000_IMS_VMMB |
-		                 E1000_IMS_DOUTSYNC));
+			ims |= E1000_IMS_VMMB;
+		}
+		if (adapter->hw.mac.type == e1000_82580)
+			ims |= E1000_IMS_DRSTA;
+
+		wr32(E1000_IMS, ims);
 	} else {
-		wr32(E1000_IMS, IMS_ENABLE_MASK);
-		wr32(E1000_IAM, IMS_ENABLE_MASK);
+		wr32(E1000_IMS, IMS_ENABLE_MASK |
+				E1000_IMS_DRSTA);
+		wr32(E1000_IAM, IMS_ENABLE_MASK |
+				E1000_IMS_DRSTA);
 	}
 }
 
 static void igb_update_mng_vlan(struct igb_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
 	u16 vid = adapter->hw.mng_cookie.vlan_id;
 	u16 old_vid = adapter->mng_vlan_id;
-	if (adapter->vlgrp) {
-		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
-			if (adapter->hw.mng_cookie.status &
-				E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
-				igb_vlan_rx_add_vid(netdev, vid);
-				adapter->mng_vlan_id = vid;
-			} else
-				adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
 
-			if ((old_vid != (u16)IGB_MNG_VLAN_NONE) &&
-					(vid != old_vid) &&
-			    !vlan_group_get_device(adapter->vlgrp, old_vid))
-				igb_vlan_rx_kill_vid(netdev, old_vid);
-		} else
-			adapter->mng_vlan_id = vid;
+	if (hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
+		/* add VID to filter table */
+		igb_vfta_set(hw, vid, true);
+		adapter->mng_vlan_id = vid;
+	} else {
+		adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
+	}
+
+	if ((old_vid != (u16)IGB_MNG_VLAN_NONE) &&
+	    (vid != old_vid) &&
+	    !vlan_group_get_device(adapter->vlgrp, old_vid)) {
+		/* remove VID from filter table */
+		igb_vfta_set(hw, old_vid, false);
 	}
 }
 
@@ -907,7 +1052,6 @@ static void igb_release_hw_control(struc
 			ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
 }
 
-
 /**
  * igb_get_hw_control - get control of the h/w from f/w
  * @adapter: address of board private structure
@@ -942,8 +1086,11 @@ static void igb_configure(struct igb_ada
 
 	igb_restore_vlan(adapter);
 
-	igb_configure_tx(adapter);
+	igb_setup_tctl(adapter);
+	igb_setup_mrqc(adapter);
 	igb_setup_rctl(adapter);
+
+	igb_configure_tx(adapter);
 	igb_configure_rx(adapter);
 
 	igb_rx_fifo_flush_82575(&adapter->hw);
@@ -965,7 +1112,6 @@ static void igb_configure(struct igb_ada
  * igb_up - Open the interface and prepare it to handle traffic
  * @adapter: board private structure
  **/
-
 int igb_up(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
@@ -976,30 +1122,39 @@ int igb_up(struct igb_adapter *adapter)
 
 	clear_bit(__IGB_DOWN, &adapter->state);
 
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		napi_enable(&adapter->rx_ring[i].napi);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		napi_enable(&q_vector->napi);
+	}
 	if (adapter->msix_entries)
 		igb_configure_msix(adapter);
-
-	igb_vmm_control(adapter);
-	igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
-	igb_set_vmolr(hw, adapter->vfs_allocated_count);
+	else
+		igb_assign_vector(adapter->q_vector[0], 0);
 
 	/* Clear any pending interrupts. */
 	rd32(E1000_ICR);
 	igb_irq_enable(adapter);
 
+	/* notify VFs that reset has been completed */
+	if (adapter->vfs_allocated_count) {
+		u32 reg_data = rd32(E1000_CTRL_EXT);
+		reg_data |= E1000_CTRL_EXT_PFRSTD;
+		wr32(E1000_CTRL_EXT, reg_data);
+	}
+
 	netif_tx_start_all_queues(adapter->netdev);
 
-	/* Fire a link change interrupt to start the watchdog. */
-	wr32(E1000_ICS, E1000_ICS_LSC);
+	/* start the watchdog. */
+	hw->mac.get_link_status = 1;
+	schedule_work(&adapter->watchdog_task);
+
 	return 0;
 }
 
 void igb_down(struct igb_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
 	u32 tctl, rctl;
 	int i;
 
@@ -1022,8 +1177,10 @@ void igb_down(struct igb_adapter *adapte
 	wrfl();
 	msleep(10);
 
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		napi_disable(&adapter->rx_ring[i].napi);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		napi_disable(&q_vector->napi);
+	}
 
 	igb_irq_disable(adapter);
 
@@ -1062,6 +1219,7 @@ void igb_reinit_locked(struct igb_adapte
 
 void igb_reset(struct igb_adapter *adapter)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_fc_info *fc = &hw->fc;
@@ -1072,8 +1230,13 @@ void igb_reset(struct igb_adapter *adapt
 	 * To take effect CTRL.RST is required.
 	 */
 	switch (mac->type) {
+	case e1000_82580:
+		pba = rd32(E1000_RXPBS);
+		pba = igb_rxpbs_adjust_82580(pba);
+		break;
 	case e1000_82576:
-		pba = E1000_PBA_64K;
+		pba = rd32(E1000_RXPBS);
+		pba &= E1000_RXPBS_SIZE_MASK_82576;
 		break;
 	case e1000_82575:
 	default:
@@ -1133,13 +1296,8 @@ void igb_reset(struct igb_adapter *adapt
 	hwm = min(((pba << 10) * 9 / 10),
 			((pba << 10) - 2 * adapter->max_frame_size));
 
-	if (mac->type < e1000_82576) {
-		fc->high_water = hwm & 0xFFF8;	/* 8-byte granularity */
-		fc->low_water = fc->high_water - 8;
-	} else {
-		fc->high_water = hwm & 0xFFF0;	/* 16-byte granularity */
-		fc->low_water = fc->high_water - 16;
-	}
+	fc->high_water = hwm & 0xFFF0;	/* 16-byte granularity */
+	fc->low_water = fc->high_water - 16;
 	fc->pause_time = 0xFFFF;
 	fc->send_xon = 1;
 	fc->current_mode = fc->requested_mode;
@@ -1148,10 +1306,10 @@ void igb_reset(struct igb_adapter *adapt
 	if (adapter->vfs_allocated_count) {
 		int i;
 		for (i = 0 ; i < adapter->vfs_allocated_count; i++)
-			adapter->vf_data[i].clear_to_send = false;
+			adapter->vf_data[i].flags = 0;
 
 		/* ping all the active vfs to let them know we are going down */
-			igb_ping_all_vfs(adapter);
+		igb_ping_all_vfs(adapter);
 
 		/* disable transmits and receives */
 		wr32(E1000_VFRE, 0);
@@ -1159,23 +1317,28 @@ void igb_reset(struct igb_adapter *adapt
 	}
 
 	/* Allow time for pending master requests to run */
-	adapter->hw.mac.ops.reset_hw(&adapter->hw);
+	hw->mac.ops.reset_hw(hw);
 	wr32(E1000_WUC, 0);
 
-	if (adapter->hw.mac.ops.init_hw(&adapter->hw))
-		dev_err(&adapter->pdev->dev, "Hardware Error\n");
+	if (hw->mac.ops.init_hw(hw))
+		dev_err(&pdev->dev, "Hardware Error\n");
 
+	if (hw->mac.type == e1000_82580) {
+		u32 reg = rd32(E1000_PCIEMISC);
+		wr32(E1000_PCIEMISC,
+		                reg & ~E1000_PCIEMISC_LX_DECISION);
+	}
 	igb_update_mng_vlan(adapter);
 
 	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
 	wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
 
-	igb_reset_adaptive(&adapter->hw);
-	igb_get_phy_info(&adapter->hw);
+	igb_reset_adaptive(hw);
+	igb_get_phy_info(hw);
 }
 
 static const struct net_device_ops igb_netdev_ops = {
-	.ndo_open 		= igb_open,
+	.ndo_open		= igb_open,
 	.ndo_stop		= igb_close,
 	.ndo_start_xmit		= igb_xmit_frame_adv,
 	.ndo_get_stats		= igb_get_stats,
@@ -1211,10 +1374,11 @@ static int __devinit igb_probe(struct pc
 	struct net_device *netdev;
 	struct igb_adapter *adapter;
 	struct e1000_hw *hw;
+	u16 eeprom_data = 0;
+	static int global_quad_port_a; /* global quad port a indication */
 	const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
 	unsigned long mmio_start, mmio_len;
 	int err, pci_using_dac;
-	u16 eeprom_data = 0;
 	u16 eeprom_apme_mask = IGB_EEPROM_APME;
 	u32 part_num;
 
@@ -1291,8 +1455,6 @@ static int __devinit igb_probe(struct pc
 	hw->subsystem_vendor_id = pdev->subsystem_vendor;
 	hw->subsystem_device_id = pdev->subsystem_device;
 
-	/* setup the private structure */
-	hw->back = adapter;
 	/* Copy the default MAC, PHY and NVM function pointers */
 	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
 	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
@@ -1302,46 +1464,6 @@ static int __devinit igb_probe(struct pc
 	if (err)
 		goto err_sw_init;
 
-#ifdef CONFIG_PCI_IOV
-	/* since iov functionality isn't critical to base device function we
-	 * can accept failure.  If it fails we don't allow iov to be enabled */
-	if (hw->mac.type == e1000_82576) {
-		/* 82576 supports a maximum of 7 VFs in addition to the PF */
-		unsigned int num_vfs = (max_vfs > 7) ? 7 : max_vfs;
-		int i;
-		unsigned char mac_addr[ETH_ALEN];
-
-		if (num_vfs) {
-			adapter->vf_data = kcalloc(num_vfs,
-						sizeof(struct vf_data_storage),
-						GFP_KERNEL);
-			if (!adapter->vf_data) {
-				dev_err(&pdev->dev,
-				        "Could not allocate VF private data - "
-					"IOV enable failed\n");
-			} else {
-				err = pci_enable_sriov(pdev, num_vfs);
-				if (!err) {
-					adapter->vfs_allocated_count = num_vfs;
-					dev_info(&pdev->dev,
-					         "%d vfs allocated\n",
-					         num_vfs);
-					for (i = 0;
-					     i < adapter->vfs_allocated_count;
-					     i++) {
-						random_ether_addr(mac_addr);
-						igb_set_vf_mac(adapter, i,
-						               mac_addr);
-					}
-				} else {
-					kfree(adapter->vf_data);
-					adapter->vf_data = NULL;
-				}
-			}
-		}
-	}
-
-#endif
 	/* setup the private structure */
 	err = igb_sw_init(adapter);
 	if (err)
@@ -1349,16 +1471,6 @@ static int __devinit igb_probe(struct pc
 
 	igb_get_bus_info_pcie(hw);
 
-	/* set flags */
-	switch (hw->mac.type) {
-	case e1000_82575:
-		adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
-		break;
-	case e1000_82576:
-	default:
-		break;
-	}
-
 	hw->phy.autoneg_wait_to_complete = false;
 	hw->mac.adaptive_ifs = true;
 
@@ -1382,7 +1494,6 @@ static int __devinit igb_probe(struct pc
 	netdev->features |= NETIF_F_IPV6_CSUM;
 	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_TSO6;
-
 	netdev->features |= NETIF_F_GRO;
 
 	netdev->vlan_features |= NETIF_F_TSO;
@@ -1394,10 +1505,10 @@ static int __devinit igb_probe(struct pc
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	if (adapter->hw.mac.type == e1000_82576)
+	if (hw->mac.type >= e1000_82576)
 		netdev->features |= NETIF_F_SCTP_CSUM;
 
-	adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
+	adapter->en_mng_pt = igb_enable_mng_pass_thru(hw);
 
 	/* before reading the NVM, reset the controller to put the device in a
 	 * known good starting state */
@@ -1439,9 +1550,6 @@ static int __devinit igb_probe(struct pc
 	hw->fc.requested_mode = e1000_fc_default;
 	hw->fc.current_mode = e1000_fc_default;
 
-	adapter->itr_setting = IGB_DEFAULT_ITR;
-	adapter->itr = IGB_START_ITR;
-
 	igb_validate_mdi_setting(hw);
 
 	/* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
@@ -1450,6 +1558,10 @@ static int __devinit igb_probe(struct pc
 
 	if (hw->bus.func == 0)
 		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+	else if (hw->mac.type == e1000_82580)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
+		                 NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
+		                 &eeprom_data);
 	else if (hw->bus.func == 1)
 		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 
@@ -1508,66 +1620,14 @@ static int __devinit igb_probe(struct pc
 		dev_info(&pdev->dev, "DCA enabled\n");
 		igb_setup_dca(adapter);
 	}
-#endif
 
-	/*
-	 * Initialize hardware timer: we keep it running just in case
-	 * that some program needs it later on.
-	 */
-	memset(&adapter->cycles, 0, sizeof(adapter->cycles));
-	adapter->cycles.read = igb_read_clock;
-	adapter->cycles.mask = CLOCKSOURCE_MASK(64);
-	adapter->cycles.mult = 1;
-	adapter->cycles.shift = IGB_TSYNC_SHIFT;
-	wr32(E1000_TIMINCA,
-	     (1<<24) |
-	     IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * IGB_TSYNC_SCALE);
-#if 0
-	/*
-	 * Avoid rollover while we initialize by resetting the time counter.
-	 */
-	wr32(E1000_SYSTIML, 0x00000000);
-	wr32(E1000_SYSTIMH, 0x00000000);
-#else
-	/*
-	 * Set registers so that rollover occurs soon to test this.
-	 */
-	wr32(E1000_SYSTIML, 0x00000000);
-	wr32(E1000_SYSTIMH, 0xFF800000);
 #endif
-	wrfl();
-	timecounter_init(&adapter->clock,
-			 &adapter->cycles,
-			 ktime_to_ns(ktime_get_real()));
-
-	/*
-	 * Synchronize our NIC clock against system wall clock. NIC
-	 * time stamp reading requires ~3us per sample, each sample
-	 * was pretty stable even under load => only require 10
-	 * samples for each offset comparison.
-	 */
-	memset(&adapter->compare, 0, sizeof(adapter->compare));
-	adapter->compare.source = &adapter->clock;
-	adapter->compare.target = ktime_get_real;
-	adapter->compare.num_samples = 10;
-	timecompare_update(&adapter->compare, 0);
-
-#ifdef DEBUG
-	{
-		char buffer[160];
-		printk(KERN_DEBUG
-			"igb: %s: hw %p initialized timer\n",
-			igb_get_time_str(adapter, buffer),
-			&adapter->hw);
-	}
-#endif
-
 	dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
 	/* print bus type/speed/width info */
 	dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
 		 netdev->name,
-		 ((hw->bus.speed == e1000_bus_speed_2500)
-		  ? "2.5Gb/s" : "unknown"),
+		 ((hw->bus.speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
+		                                            "unknown"),
 		 ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
 		  (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" :
 		  (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" :
@@ -1594,15 +1654,14 @@ err_eeprom:
 
 	if (hw->flash_address)
 		iounmap(hw->flash_address);
-
-	igb_free_queues(adapter);
 err_sw_init:
+	igb_clear_interrupt_scheme(adapter);
 	iounmap(hw->hw_addr);
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
-	pci_release_selected_regions(pdev, pci_select_bars(pdev,
-	                             IORESOURCE_MEM));
+	pci_release_selected_regions(pdev,
+	                             pci_select_bars(pdev, IORESOURCE_MEM));
 err_pci_reg:
 err_dma:
 	pci_disable_device(pdev);
@@ -1647,12 +1706,10 @@ static void __devexit igb_remove(struct
 
 	unregister_netdev(netdev);
 
-	if (!igb_check_reset_block(&adapter->hw))
-		igb_reset_phy(&adapter->hw);
-
-	igb_reset_interrupt_capability(adapter);
+	if (!igb_check_reset_block(hw))
+		igb_reset_phy(hw);
 
-	igb_free_queues(adapter);
+	igb_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_PCI_IOV
 	/* reclaim resources allocated to VFs */
@@ -1668,11 +1725,12 @@ static void __devexit igb_remove(struct
 		dev_info(&pdev->dev, "IOV Disabled\n");
 	}
 #endif
+
 	iounmap(hw->hw_addr);
 	if (hw->flash_address)
 		iounmap(hw->flash_address);
-	pci_release_selected_regions(pdev, pci_select_bars(pdev,
-	                             IORESOURCE_MEM));
+	pci_release_selected_regions(pdev,
+	                             pci_select_bars(pdev, IORESOURCE_MEM));
 
 	free_netdev(netdev);
 
@@ -1682,6 +1740,160 @@ static void __devexit igb_remove(struct
 }
 
 /**
+ * igb_probe_vfs - Initialize vf data storage and add VFs to pci config space
+ * @adapter: board private structure to initialize
+ *
+ * This function initializes the vf specific data storage and then attempts to
+ * allocate the VFs.  The reason for ordering it this way is because it is much
+ * mor expensive time wise to disable SR-IOV than it is to allocate and free
+ * the memory for the VFs.
+ **/
+static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
+{
+#ifdef CONFIG_PCI_IOV
+	struct pci_dev *pdev = adapter->pdev;
+
+	if (adapter->vfs_allocated_count > 7)
+		adapter->vfs_allocated_count = 7;
+
+	if (adapter->vfs_allocated_count) {
+		adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
+		                           sizeof(struct vf_data_storage),
+		                           GFP_KERNEL);
+		/* if allocation failed then we do not support SR-IOV */
+		if (!adapter->vf_data) {
+			adapter->vfs_allocated_count = 0;
+			dev_err(&pdev->dev, "Unable to allocate memory for VF "
+			        "Data Storage\n");
+		}
+	}
+
+	if (pci_enable_sriov(pdev, adapter->vfs_allocated_count)) {
+		kfree(adapter->vf_data);
+		adapter->vf_data = NULL;
+#endif /* CONFIG_PCI_IOV */
+		adapter->vfs_allocated_count = 0;
+#ifdef CONFIG_PCI_IOV
+	} else {
+		unsigned char mac_addr[ETH_ALEN];
+		int i;
+		dev_info(&pdev->dev, "%d vfs allocated\n",
+		         adapter->vfs_allocated_count);
+		for (i = 0; i < adapter->vfs_allocated_count; i++) {
+			random_ether_addr(mac_addr);
+			igb_set_vf_mac(adapter, i, mac_addr);
+		}
+	}
+#endif /* CONFIG_PCI_IOV */
+}
+
+
+/**
+ * igb_init_hw_timer - Initialize hardware timer used with IEEE 1588 timestamp
+ * @adapter: board private structure to initialize
+ *
+ * igb_init_hw_timer initializes the function pointer and values for the hw
+ * timer found in hardware.
+ **/
+static void igb_init_hw_timer(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	switch (hw->mac.type) {
+	case e1000_82580:
+		memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+		adapter->cycles.read = igb_read_clock;
+		adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+		adapter->cycles.mult = 1;
+		/*
+		 * The 82580 timesync updates the system timer every 8ns by 8ns
+		 * and the value cannot be shifted.  Instead we need to shift
+		 * the registers to generate a 64bit timer value.  As a result
+		 * SYSTIMR/L/H, TXSTMPL/H, RXSTMPL/H all have to be shifted by
+		 * 24 in order to generate a larger value for synchronization.
+		 */
+		adapter->cycles.shift = IGB_82580_TSYNC_SHIFT;
+		/* disable system timer temporarily by setting bit 31 */
+		wr32(E1000_TSAUXC, 0x80000000);
+		wrfl();
+
+		/* Set registers so that rollover occurs soon to test this. */
+		wr32(E1000_SYSTIMR, 0x00000000);
+		wr32(E1000_SYSTIML, 0x80000000);
+		wr32(E1000_SYSTIMH, 0x000000FF);
+		wrfl();
+
+		/* enable system timer by clearing bit 31 */
+		wr32(E1000_TSAUXC, 0x0);
+		wrfl();
+
+		timecounter_init(&adapter->clock,
+				 &adapter->cycles,
+				 ktime_to_ns(ktime_get_real()));
+		/*
+		 * Synchronize our NIC clock against system wall clock. NIC
+		 * time stamp reading requires ~3us per sample, each sample
+		 * was pretty stable even under load => only require 10
+		 * samples for each offset comparison.
+		 */
+		memset(&adapter->compare, 0, sizeof(adapter->compare));
+		adapter->compare.source = &adapter->clock;
+		adapter->compare.target = ktime_get_real;
+		adapter->compare.num_samples = 10;
+		timecompare_update(&adapter->compare, 0);
+		break;
+	case e1000_82576:
+		/*
+		 * Initialize hardware timer: we keep it running just in case
+		 * that some program needs it later on.
+		 */
+		memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+		adapter->cycles.read = igb_read_clock;
+		adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+		adapter->cycles.mult = 1;
+		/**
+		 * Scale the NIC clock cycle by a large factor so that
+		 * relatively small clock corrections can be added or
+		 * substracted at each clock tick. The drawbacks of a large
+		 * factor are a) that the clock register overflows more quickly
+		 * (not such a big deal) and b) that the increment per tick has
+		 * to fit into 24 bits.  As a result we need to use a shift of
+		 * 19 so we can fit a value of 16 into the TIMINCA register.
+		 */
+		adapter->cycles.shift = IGB_82576_TSYNC_SHIFT;
+		wr32(E1000_TIMINCA,
+		                (1 << E1000_TIMINCA_16NS_SHIFT) |
+		                (16 << IGB_82576_TSYNC_SHIFT));
+
+		/* Set registers so that rollover occurs soon to test this. */
+		wr32(E1000_SYSTIML, 0x00000000);
+		wr32(E1000_SYSTIMH, 0xFF800000);
+		wrfl();
+
+		timecounter_init(&adapter->clock,
+				 &adapter->cycles,
+				 ktime_to_ns(ktime_get_real()));
+		/*
+		 * Synchronize our NIC clock against system wall clock. NIC
+		 * time stamp reading requires ~3us per sample, each sample
+		 * was pretty stable even under load => only require 10
+		 * samples for each offset comparison.
+		 */
+		memset(&adapter->compare, 0, sizeof(adapter->compare));
+		adapter->compare.source = &adapter->clock;
+		adapter->compare.target = ktime_get_real;
+		adapter->compare.num_samples = 10;
+		timecompare_update(&adapter->compare, 0);
+		break;
+	case e1000_82575:
+		/* 82575 does not support timesync */
+	default:
+		break;
+	}
+
+}
+
+/**
  * igb_sw_init - Initialize general software structures (struct igb_adapter)
  * @adapter: board private structure to initialize
  *
@@ -1699,20 +1911,37 @@ static int __devinit igb_sw_init(struct
 
 	adapter->tx_ring_count = IGB_DEFAULT_TXD;
 	adapter->rx_ring_count = IGB_DEFAULT_RXD;
-	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-	adapter->rx_ps_hdr_size = 0; /* disable packet split */
+	adapter->rx_itr_setting = IGB_DEFAULT_ITR;
+	adapter->tx_itr_setting = IGB_DEFAULT_ITR;
+
 	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
-	/* This call may decrease the number of queues depending on
-	 * interrupt mode. */
-	igb_set_interrupt_capability(adapter);
+#ifdef CONFIG_PCI_IOV
+	if (hw->mac.type == e1000_82576)
+		adapter->vfs_allocated_count = max_vfs;
 
-	if (igb_alloc_queues(adapter)) {
+#endif /* CONFIG_PCI_IOV */
+	adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
+
+	/*
+	 * if rss_queues > 4 or vfs are going to be allocated with rss_queues
+	 * then we should combine the queues into a queue pair in order to
+	 * conserve interrupts due to limited supply
+	 */
+	if ((adapter->rss_queues > 4) ||
+	    ((adapter->rss_queues > 1) && (adapter->vfs_allocated_count > 6)))
+		adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
+
+	/* This call may decrease the number of queues */
+	if (igb_init_interrupt_scheme(adapter)) {
 		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
 		return -ENOMEM;
 	}
 
+	igb_init_hw_timer(adapter);
+	igb_probe_vfs(adapter);
+
 	/* Explicitly disable IRQ since the NIC can be in any state. */
 	igb_irq_disable(adapter);
 
@@ -1757,21 +1986,12 @@ static int igb_open(struct net_device *n
 
 	/* e1000_power_up_phy(adapter); */
 
-	adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
-	if ((adapter->hw.mng_cookie.status &
-	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
-		igb_update_mng_vlan(adapter);
-
 	/* before we allocate an interrupt, we must be ready to handle it.
 	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
 	 * as soon as we call pci_request_irq, so we have to setup our
 	 * clean_rx handler before we do so.  */
 	igb_configure(adapter);
 
-	igb_vmm_control(adapter);
-	igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
-	igb_set_vmolr(hw, adapter->vfs_allocated_count);
-
 	err = igb_request_irq(adapter);
 	if (err)
 		goto err_req_irq;
@@ -1779,18 +1999,28 @@ static int igb_open(struct net_device *n
 	/* From here on the code is the same as igb_up() */
 	clear_bit(__IGB_DOWN, &adapter->state);
 
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		napi_enable(&adapter->rx_ring[i].napi);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		napi_enable(&q_vector->napi);
+	}
 
 	/* Clear any pending interrupts. */
 	rd32(E1000_ICR);
 
 	igb_irq_enable(adapter);
 
+	/* notify VFs that reset has been completed */
+	if (adapter->vfs_allocated_count) {
+		u32 reg_data = rd32(E1000_CTRL_EXT);
+		reg_data |= E1000_CTRL_EXT_PFRSTD;
+		wr32(E1000_CTRL_EXT, reg_data);
+	}
+
 	netif_tx_start_all_queues(netdev);
 
-	/* Fire a link status change interrupt to start the watchdog. */
-	wr32(E1000_ICS, E1000_ICS_LSC);
+	/* start the watchdog. */
+	hw->mac.get_link_status = 1;
+	schedule_work(&adapter->watchdog_task);
 
 	return 0;
 
@@ -1829,28 +2059,18 @@ static int igb_close(struct net_device *
 	igb_free_all_tx_resources(adapter);
 	igb_free_all_rx_resources(adapter);
 
-	/* kill manageability vlan ID if supported, but not if a vlan with
-	 * the same ID is registered on the host OS (let 8021q kill it) */
-	if ((adapter->hw.mng_cookie.status &
-			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
-	     !(adapter->vlgrp &&
-	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
-		igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
-
 	return 0;
 }
 
 /**
  * igb_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
  * @tx_ring: tx descriptor ring (for a specific queue) to setup
  *
  * Return 0 on success, negative on failure
  **/
-int igb_setup_tx_resources(struct igb_adapter *adapter,
-			   struct igb_ring *tx_ring)
+int igb_setup_tx_resources(struct igb_ring *tx_ring)
 {
-	struct pci_dev *pdev = adapter->pdev;
+	struct pci_dev *pdev = tx_ring->pdev;
 	int size;
 
 	size = sizeof(struct igb_buffer) * tx_ring->count;
@@ -1863,20 +2083,20 @@ int igb_setup_tx_resources(struct igb_ad
 	tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
 	tx_ring->size = ALIGN(tx_ring->size, 4096);
 
-	tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+	tx_ring->desc = pci_alloc_consistent(pdev,
+	                                     tx_ring->size,
 					     &tx_ring->dma);
 
 	if (!tx_ring->desc)
 		goto err;
 
-	tx_ring->adapter = adapter;
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
 	return 0;
 
 err:
 	vfree(tx_ring->buffer_info);
-	dev_err(&adapter->pdev->dev,
+	dev_err(&pdev->dev,
 		"Unable to allocate memory for the transmit descriptor ring\n");
 	return -ENOMEM;
 }
@@ -1890,13 +2110,13 @@ err:
  **/
 static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	int i, err = 0;
-	int r_idx;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+		err = igb_setup_tx_resources(&adapter->tx_ring[i]);
 		if (err) {
-			dev_err(&adapter->pdev->dev,
+			dev_err(&pdev->dev,
 				"Allocation for Tx Queue %u failed\n", i);
 			for (i--; i >= 0; i--)
 				igb_free_tx_resources(&adapter->tx_ring[i]);
@@ -1904,57 +2124,24 @@ static int igb_setup_all_tx_resources(st
 		}
 	}
 
-	for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
-		r_idx = i % adapter->num_tx_queues;
+	for (i = 0; i < IGB_ABS_MAX_TX_QUEUES; i++) {
+		int r_idx = i % adapter->num_tx_queues;
 		adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
 	}
 	return err;
 }
 
 /**
- * igb_configure_tx - Configure transmit Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx unit of the MAC after a reset.
+ * igb_setup_tctl - configure the transmit control registers
+ * @adapter: Board private structure
  **/
-static void igb_configure_tx(struct igb_adapter *adapter)
+void igb_setup_tctl(struct igb_adapter *adapter)
 {
-	u64 tdba;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 tctl;
-	u32 txdctl, txctrl;
-	int i, j;
 
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *ring = &adapter->tx_ring[i];
-		j = ring->reg_idx;
-		wr32(E1000_TDLEN(j),
-		     ring->count * sizeof(union e1000_adv_tx_desc));
-		tdba = ring->dma;
-		wr32(E1000_TDBAL(j),
-		     tdba & 0x00000000ffffffffULL);
-		wr32(E1000_TDBAH(j), tdba >> 32);
-
-		ring->head = E1000_TDH(j);
-		ring->tail = E1000_TDT(j);
-		writel(0, hw->hw_addr + ring->tail);
-		writel(0, hw->hw_addr + ring->head);
-		txdctl = rd32(E1000_TXDCTL(j));
-		txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
-		wr32(E1000_TXDCTL(j), txdctl);
-
-		/* Turn off Relaxed Ordering on head write-backs.  The
-		 * writebacks MUST be delivered in order or it will
-		 * completely screw up our bookeeping.
-		 */
-		txctrl = rd32(E1000_DCA_TXCTRL(j));
-		txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
-		wr32(E1000_DCA_TXCTRL(j), txctrl);
-	}
-
-	/* disable queue 0 to prevent tail bump w/o re-configuration */
-	if (adapter->vfs_allocated_count)
-		wr32(E1000_TXDCTL(0), 0);
+	/* disable queue 0 which is enabled by default on 82575 and 82576 */
+	wr32(E1000_TXDCTL(0), 0);
 
 	/* Program the Transmit Control Register */
 	tctl = rd32(E1000_TCTL);
@@ -1964,9 +2151,6 @@ static void igb_configure_tx(struct igb_
 
 	igb_config_collision_dist(hw);
 
-	/* Setup Transmit Descriptor Settings for eop descriptor */
-	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;
-
 	/* Enable transmits */
 	tctl |= E1000_TCTL_EN;
 
@@ -1974,16 +2158,69 @@ static void igb_configure_tx(struct igb_
 }
 
 /**
- * igb_setup_rx_resources - allocate Rx resources (Descriptors)
+ * igb_configure_tx_ring - Configure transmit ring after Reset
+ * @adapter: board private structure
+ * @ring: tx ring to configure
+ *
+ * Configure a transmit ring after a reset.
+ **/
+void igb_configure_tx_ring(struct igb_adapter *adapter,
+                           struct igb_ring *ring)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 txdctl;
+	u64 tdba = ring->dma;
+	int reg_idx = ring->reg_idx;
+
+	/* disable the queue */
+	txdctl = rd32(E1000_TXDCTL(reg_idx));
+	wr32(E1000_TXDCTL(reg_idx),
+	                txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+	wrfl();
+	mdelay(10);
+
+	wr32(E1000_TDLEN(reg_idx),
+	                ring->count * sizeof(union e1000_adv_tx_desc));
+	wr32(E1000_TDBAL(reg_idx),
+	                tdba & 0x00000000ffffffffULL);
+	wr32(E1000_TDBAH(reg_idx), tdba >> 32);
+
+	ring->head = hw->hw_addr + E1000_TDH(reg_idx);
+	ring->tail = hw->hw_addr + E1000_TDT(reg_idx);
+	writel(0, ring->head);
+	writel(0, ring->tail);
+
+	txdctl |= IGB_TX_PTHRESH;
+	txdctl |= IGB_TX_HTHRESH << 8;
+	txdctl |= IGB_TX_WTHRESH << 16;
+
+	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+	wr32(E1000_TXDCTL(reg_idx), txdctl);
+}
+
+/**
+ * igb_configure_tx - Configure transmit Unit after Reset
  * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igb_configure_tx(struct igb_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_tx_queues; i++)
+		igb_configure_tx_ring(adapter, &adapter->tx_ring[i]);
+}
+
+/**
+ * igb_setup_rx_resources - allocate Rx resources (Descriptors)
  * @rx_ring:    rx descriptor ring (for a specific queue) to setup
  *
  * Returns 0 on success, negative on failure
  **/
-int igb_setup_rx_resources(struct igb_adapter *adapter,
-			   struct igb_ring *rx_ring)
+int igb_setup_rx_resources(struct igb_ring *rx_ring)
 {
-	struct pci_dev *pdev = adapter->pdev;
+	struct pci_dev *pdev = rx_ring->pdev;
 	int size, desc_len;
 
 	size = sizeof(struct igb_buffer) * rx_ring->count;
@@ -2007,13 +2244,12 @@ int igb_setup_rx_resources(struct igb_ad
 	rx_ring->next_to_clean = 0;
 	rx_ring->next_to_use = 0;
 
-	rx_ring->adapter = adapter;
-
 	return 0;
 
 err:
 	vfree(rx_ring->buffer_info);
-	dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
+	rx_ring->buffer_info = NULL;
+	dev_err(&pdev->dev, "Unable to allocate memory for "
 		"the receive descriptor ring\n");
 	return -ENOMEM;
 }
@@ -2027,12 +2263,13 @@ err:
  **/
 static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	int i, err = 0;
 
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		err = igb_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+		err = igb_setup_rx_resources(&adapter->rx_ring[i]);
 		if (err) {
-			dev_err(&adapter->pdev->dev,
+			dev_err(&pdev->dev,
 				"Allocation for Rx Queue %u failed\n", i);
 			for (i--; i >= 0; i--)
 				igb_free_rx_resources(&adapter->rx_ring[i]);
@@ -2044,15 +2281,122 @@ static int igb_setup_all_rx_resources(st
 }
 
 /**
+ * igb_setup_mrqc - configure the multiple receive queue control registers
+ * @adapter: Board private structure
+ **/
+static void igb_setup_mrqc(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 mrqc, rxcsum;
+	u32 j, num_rx_queues, shift = 0, shift2 = 0;
+	union e1000_reta {
+		u32 dword;
+		u8  bytes[4];
+	} reta;
+	static const u8 rsshash[40] = {
+		0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67,
+		0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb,
+		0xae, 0x7b, 0x30, 0xb4,	0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30,
+		0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa };
+
+	/* Fill out hash function seeds */
+	for (j = 0; j < 10; j++) {
+		u32 rsskey = rsshash[(j * 4)];
+		rsskey |= rsshash[(j * 4) + 1] << 8;
+		rsskey |= rsshash[(j * 4) + 2] << 16;
+		rsskey |= rsshash[(j * 4) + 3] << 24;
+		array_wr32(E1000_RSSRK(0), j, rsskey);
+	}
+
+	num_rx_queues = adapter->rss_queues;
+
+	if (adapter->vfs_allocated_count) {
+		/* 82575 and 82576 supports 2 RSS queues for VMDq */
+		switch (hw->mac.type) {
+		case e1000_82580:
+			num_rx_queues = 1;
+			shift = 0;
+			break;
+		case e1000_82576:
+			shift = 3;
+			num_rx_queues = 2;
+			break;
+		case e1000_82575:
+			shift = 2;
+			shift2 = 6;
+		default:
+			break;
+		}
+	} else {
+		if (hw->mac.type == e1000_82575)
+			shift = 6;
+	}
+
+	for (j = 0; j < (32 * 4); j++) {
+		reta.bytes[j & 3] = (j % num_rx_queues) << shift;
+		if (shift2)
+			reta.bytes[j & 3] |= num_rx_queues << shift2;
+		if ((j & 3) == 3)
+			wr32(E1000_RETA(j >> 2), reta.dword);
+	}
+
+	/*
+	 * Disable raw packet checksumming so that RSS hash is placed in
+	 * descriptor on writeback.  No need to enable TCP/UDP/IP checksum
+	 * offloads as they are enabled by default
+	 */
+	rxcsum = rd32(E1000_RXCSUM);
+	rxcsum |= E1000_RXCSUM_PCSD;
+
+	if (adapter->hw.mac.type >= e1000_82576)
+		/* Enable Receive Checksum Offload for SCTP */
+		rxcsum |= E1000_RXCSUM_CRCOFL;
+
+	/* Don't need to set TUOFL or IPOFL, they default to 1 */
+	wr32(E1000_RXCSUM, rxcsum);
+
+	/* If VMDq is enabled then we set the appropriate mode for that, else
+	 * we default to RSS so that an RSS hash is calculated per packet even
+	 * if we are only using one queue */
+	if (adapter->vfs_allocated_count) {
+		if (hw->mac.type > e1000_82575) {
+			/* Set the default pool for the PF's first queue */
+			u32 vtctl = rd32(E1000_VT_CTL);
+			vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
+				   E1000_VT_CTL_DISABLE_DEF_POOL);
+			vtctl |= adapter->vfs_allocated_count <<
+				E1000_VT_CTL_DEFAULT_POOL_SHIFT;
+			wr32(E1000_VT_CTL, vtctl);
+		}
+		if (adapter->rss_queues > 1)
+			mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
+		else
+			mrqc = E1000_MRQC_ENABLE_VMDQ;
+	} else {
+		mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+	}
+	igb_vmm_control(adapter);
+
+	mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+		 E1000_MRQC_RSS_FIELD_IPV4_TCP);
+	mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
+		 E1000_MRQC_RSS_FIELD_IPV6_TCP);
+	mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
+		 E1000_MRQC_RSS_FIELD_IPV6_UDP);
+	mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
+		 E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+
+	wr32(E1000_MRQC, mrqc);
+}
+
+/**
  * igb_setup_rctl - configure the receive control registers
  * @adapter: Board private structure
  **/
-static void igb_setup_rctl(struct igb_adapter *adapter)
+void igb_setup_rctl(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl;
-	u32 srrctl = 0;
-	int i;
 
 	rctl = rd32(E1000_RCTL);
 
@@ -2069,75 +2413,45 @@ static void igb_setup_rctl(struct igb_ad
 	 */
 	rctl |= E1000_RCTL_SECRC;
 
-	/*
-	 * disable store bad packets and clear size bits.
-	 */
+	/* disable store bad packets and clear size bits. */
 	rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
 
-	/* enable LPE when to prevent packets larger than max_frame_size */
-		rctl |= E1000_RCTL_LPE;
-
-	/* Setup buffer sizes */
-	switch (adapter->rx_buffer_len) {
-	case IGB_RXBUFFER_256:
-		rctl |= E1000_RCTL_SZ_256;
-		break;
-	case IGB_RXBUFFER_512:
-		rctl |= E1000_RCTL_SZ_512;
-		break;
-	default:
-		srrctl = ALIGN(adapter->rx_buffer_len, 1024)
-		         >> E1000_SRRCTL_BSIZEPKT_SHIFT;
-		break;
-	}
+	/* enable LPE to prevent packets larger than max_frame_size */
+	rctl |= E1000_RCTL_LPE;
 
-	/* 82575 and greater support packet-split where the protocol
-	 * header is placed in skb->data and the packet data is
-	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
-	 * In the case of a non-split, skb->data is linearly filled,
-	 * followed by the page buffers.  Therefore, skb->data is
-	 * sized to hold the largest protocol header.
-	 */
-	/* allocations using alloc_page take too long for regular MTU
-	 * so only enable packet split for jumbo frames */
-	if (adapter->netdev->mtu > ETH_DATA_LEN) {
-		adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
-		srrctl |= adapter->rx_ps_hdr_size <<
-			 E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
-		srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
-	} else {
-		adapter->rx_ps_hdr_size = 0;
-		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
-	}
+	/* disable queue 0 to prevent tail write w/o re-config */
+	wr32(E1000_RXDCTL(0), 0);
 
 	/* Attention!!!  For SR-IOV PF driver operations you must enable
 	 * queue drop for all VF and PF queues to prevent head of line blocking
 	 * if an un-trusted VF does not provide descriptors to hardware.
 	 */
 	if (adapter->vfs_allocated_count) {
-		u32 vmolr;
-
 		/* set all queue drop enable bits */
 		wr32(E1000_QDE, ALL_QUEUES);
-		srrctl |= E1000_SRRCTL_DROP_EN;
+	}
 
-		/* disable queue 0 to prevent tail write w/o re-config */
-		wr32(E1000_RXDCTL(0), 0);
+	wr32(E1000_RCTL, rctl);
+}
 
-		vmolr = rd32(E1000_VMOLR(adapter->vfs_allocated_count));
-		if (rctl & E1000_RCTL_LPE)
-			vmolr |= E1000_VMOLR_LPE;
-		if (adapter->num_rx_queues > 1)
-			vmolr |= E1000_VMOLR_RSSE;
-		wr32(E1000_VMOLR(adapter->vfs_allocated_count), vmolr);
-	}
+static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
+                                   int vfn)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 vmolr;
 
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		int j = adapter->rx_ring[i].reg_idx;
-		wr32(E1000_SRRCTL(j), srrctl);
-	}
+	/* if it isn't the PF check to see if VFs are enabled and
+	 * increase the size to support vlan tags */
+	if (vfn < adapter->vfs_allocated_count &&
+	    adapter->vf_data[vfn].vlans_enabled)
+		size += VLAN_TAG_SIZE;
 
-	wr32(E1000_RCTL, rctl);
+	vmolr = rd32(E1000_VMOLR(vfn));
+	vmolr &= ~E1000_VMOLR_RLPML_MASK;
+	vmolr |= size | E1000_VMOLR_LPE;
+	wr32(E1000_VMOLR(vfn), vmolr);
+
+	return 0;
 }
 
 /**
@@ -2159,149 +2473,130 @@ static void igb_rlpml_set(struct igb_ada
 	 * size and set the VMOLR RLPML to the size we need */
 	if (pf_id) {
 		igb_set_vf_rlpml(adapter, max_frame_size, pf_id);
-		max_frame_size = MAX_STD_JUMBO_FRAME_SIZE + VLAN_TAG_SIZE;
+		max_frame_size = MAX_JUMBO_FRAME_SIZE;
 	}
 
 	wr32(E1000_RLPML, max_frame_size);
 }
 
-/**
- * igb_configure_vt_default_pool - Configure VT default pool
- * @adapter: board private structure
- *
- * Configure the default pool
- **/
-static void igb_configure_vt_default_pool(struct igb_adapter *adapter)
+static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	u16 pf_id = adapter->vfs_allocated_count;
-	u32 vtctl;
+	u32 vmolr;
 
-	/* not in sr-iov mode - do nothing */
-	if (!pf_id)
+	/*
+	 * This register exists only on 82576 and newer so if we are older then
+	 * we should exit and do nothing
+	 */
+	if (hw->mac.type < e1000_82576)
 		return;
 
-	vtctl = rd32(E1000_VT_CTL);
-	vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
-		   E1000_VT_CTL_DISABLE_DEF_POOL);
-	vtctl |= pf_id << E1000_VT_CTL_DEFAULT_POOL_SHIFT;
-	wr32(E1000_VT_CTL, vtctl);
+	vmolr = rd32(E1000_VMOLR(vfn));
+	vmolr |= E1000_VMOLR_AUPE |        /* Accept untagged packets */
+	         E1000_VMOLR_STRVLAN;      /* Strip vlan tags */
+
+	/* clear all bits that might not be set */
+	vmolr &= ~(E1000_VMOLR_BAM | E1000_VMOLR_RSSE);
+
+	if (adapter->rss_queues > 1 && vfn == adapter->vfs_allocated_count)
+		vmolr |= E1000_VMOLR_RSSE; /* enable RSS */
+	/*
+	 * for VMDq only allow the VFs and pool 0 to accept broadcast and
+	 * multicast packets
+	 */
+	if (vfn <= adapter->vfs_allocated_count)
+		vmolr |= E1000_VMOLR_BAM;	   /* Accept broadcast */
+
+	wr32(E1000_VMOLR(vfn), vmolr);
 }
 
 /**
- * igb_configure_rx - Configure receive Unit after Reset
+ * igb_configure_rx_ring - Configure a receive ring after Reset
  * @adapter: board private structure
+ * @ring: receive ring to be configured
  *
  * Configure the Rx unit of the MAC after a reset.
  **/
-static void igb_configure_rx(struct igb_adapter *adapter)
+void igb_configure_rx_ring(struct igb_adapter *adapter,
+                           struct igb_ring *ring)
 {
-	u64 rdba;
 	struct e1000_hw *hw = &adapter->hw;
-	u32 rctl, rxcsum;
-	u32 rxdctl;
-	int i;
-
-	/* disable receives while setting up the descriptors */
-	rctl = rd32(E1000_RCTL);
-	wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
-	wrfl();
-	mdelay(10);
+	u64 rdba = ring->dma;
+	int reg_idx = ring->reg_idx;
+	u32 srrctl, rxdctl;
 
-	if (adapter->itr_setting > 3)
-		wr32(E1000_ITR, adapter->itr);
+	/* disable the queue */
+	rxdctl = rd32(E1000_RXDCTL(reg_idx));
+	wr32(E1000_RXDCTL(reg_idx),
+	                rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
 
-	/* Setup the HW Rx Head and Tail Descriptor Pointers and
-	 * the Base and Length of the Rx Descriptor Ring */
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		struct igb_ring *ring = &adapter->rx_ring[i];
-		int j = ring->reg_idx;
-		rdba = ring->dma;
-		wr32(E1000_RDBAL(j),
-		     rdba & 0x00000000ffffffffULL);
-		wr32(E1000_RDBAH(j), rdba >> 32);
-		wr32(E1000_RDLEN(j),
-		     ring->count * sizeof(union e1000_adv_rx_desc));
+	/* Set DMA base address registers */
+	wr32(E1000_RDBAL(reg_idx),
+	     rdba & 0x00000000ffffffffULL);
+	wr32(E1000_RDBAH(reg_idx), rdba >> 32);
+	wr32(E1000_RDLEN(reg_idx),
+	               ring->count * sizeof(union e1000_adv_rx_desc));
 
-		ring->head = E1000_RDH(j);
-		ring->tail = E1000_RDT(j);
-		writel(0, hw->hw_addr + ring->tail);
-		writel(0, hw->hw_addr + ring->head);
+	/* initialize head and tail */
+	ring->head = hw->hw_addr + E1000_RDH(reg_idx);
+	ring->tail = hw->hw_addr + E1000_RDT(reg_idx);
+	writel(0, ring->head);
+	writel(0, ring->tail);
 
-		rxdctl = rd32(E1000_RXDCTL(j));
-		rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
-		rxdctl &= 0xFFF00000;
-		rxdctl |= IGB_RX_PTHRESH;
-		rxdctl |= IGB_RX_HTHRESH << 8;
-		rxdctl |= IGB_RX_WTHRESH << 16;
-		wr32(E1000_RXDCTL(j), rxdctl);
+	/* set descriptor configuration */
+	if (ring->rx_buffer_len < IGB_RXBUFFER_1024) {
+		srrctl = ALIGN(ring->rx_buffer_len, 64) <<
+		         E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
+		srrctl |= IGB_RXBUFFER_16384 >>
+		          E1000_SRRCTL_BSIZEPKT_SHIFT;
+#else
+		srrctl |= (PAGE_SIZE / 2) >>
+		          E1000_SRRCTL_BSIZEPKT_SHIFT;
+#endif
+		srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+	} else {
+		srrctl = ALIGN(ring->rx_buffer_len, 1024) >>
+		         E1000_SRRCTL_BSIZEPKT_SHIFT;
+		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
 	}
 
-	if (adapter->num_rx_queues > 1) {
-		u32 random[10];
-		u32 mrqc;
-		u32 j, shift;
-		union e1000_reta {
-			u32 dword;
-			u8  bytes[4];
-		} reta;
-
-		get_random_bytes(&random[0], 40);
-
-		if (hw->mac.type >= e1000_82576)
-			shift = 0;
-		else
-			shift = 6;
-		for (j = 0; j < (32 * 4); j++) {
-			reta.bytes[j & 3] =
-				adapter->rx_ring[(j % adapter->num_rx_queues)].reg_idx << shift;
-			if ((j & 3) == 3)
-				writel(reta.dword,
-				       hw->hw_addr + E1000_RETA(0) + (j & ~3));
-		}
-		if (adapter->vfs_allocated_count)
-			mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
-		else
-			mrqc = E1000_MRQC_ENABLE_RSS_4Q;
-
-		/* Fill out hash function seeds */
-		for (j = 0; j < 10; j++)
-			array_wr32(E1000_RSSRK(0), j, random[j]);
-
-		mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
-			 E1000_MRQC_RSS_FIELD_IPV4_TCP);
-		mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
-			 E1000_MRQC_RSS_FIELD_IPV6_TCP);
-		mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
-			 E1000_MRQC_RSS_FIELD_IPV6_UDP);
-		mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
-			 E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
-
-		wr32(E1000_MRQC, mrqc);
-	} else if (adapter->vfs_allocated_count) {
-		/* Enable multi-queue for sr-iov */
-		wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
-	}
+	wr32(E1000_SRRCTL(reg_idx), srrctl);
 
-	/* Enable Receive Checksum Offload for TCP and UDP */
-	rxcsum = rd32(E1000_RXCSUM);
-	/* Disable raw packet checksumming */
-	rxcsum |= E1000_RXCSUM_PCSD;
+	/* set filtering for VMDQ pools */
+	igb_set_vmolr(adapter, reg_idx & 0x7);
 
-	if (adapter->hw.mac.type == e1000_82576)
-		/* Enable Receive Checksum Offload for SCTP */
-		rxcsum |= E1000_RXCSUM_CRCOFL;
+	/* enable receive descriptor fetching */
+	rxdctl = rd32(E1000_RXDCTL(reg_idx));
+	rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+	rxdctl &= 0xFFF00000;
+	rxdctl |= IGB_RX_PTHRESH;
+	rxdctl |= IGB_RX_HTHRESH << 8;
+	rxdctl |= IGB_RX_WTHRESH << 16;
+	wr32(E1000_RXDCTL(reg_idx), rxdctl);
+}
 
-	/* Don't need to set TUOFL or IPOFL, they default to 1 */
-	wr32(E1000_RXCSUM, rxcsum);
+/**
+ * igb_configure_rx - Configure receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igb_configure_rx(struct igb_adapter *adapter)
+{
+	int i;
 
-	/* Set the default pool for the PF's first queue */
-	igb_configure_vt_default_pool(adapter);
+	/* set UTA to appropriate mode */
+	igb_set_uta(adapter);
 
-	igb_rlpml_set(adapter);
+	/* set the correct pool for the PF default MAC address in entry 0 */
+	igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
+	                 adapter->vfs_allocated_count);
 
-	/* Enable Receives */
-	wr32(E1000_RCTL, rctl);
+	/* Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring */
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		igb_configure_rx_ring(adapter, &adapter->rx_ring[i]);
 }
 
 /**
@@ -2312,14 +2607,17 @@ static void igb_configure_rx(struct igb_
  **/
 void igb_free_tx_resources(struct igb_ring *tx_ring)
 {
-	struct pci_dev *pdev = tx_ring->adapter->pdev;
-
 	igb_clean_tx_ring(tx_ring);
 
 	vfree(tx_ring->buffer_info);
 	tx_ring->buffer_info = NULL;
 
-	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+	/* if not set, then don't free */
+	if (!tx_ring->desc)
+		return;
+
+	pci_free_consistent(tx_ring->pdev, tx_ring->size,
+	                    tx_ring->desc, tx_ring->dma);
 
 	tx_ring->desc = NULL;
 }
@@ -2338,18 +2636,30 @@ static void igb_free_all_tx_resources(st
 		igb_free_tx_resources(&adapter->tx_ring[i]);
 }
 
-static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
-					   struct igb_buffer *buffer_info)
+void igb_unmap_and_free_tx_resource(struct igb_ring *tx_ring,
+				    struct igb_buffer *buffer_info)
 {
-	buffer_info->dma = 0;
+	if (buffer_info->dma) {
+		if (buffer_info->mapped_as_page)
+			pci_unmap_page(tx_ring->pdev,
+					buffer_info->dma,
+					buffer_info->length,
+					PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(tx_ring->pdev,
+					buffer_info->dma,
+					buffer_info->length,
+					PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
 	if (buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
 	buffer_info->time_stamp = 0;
-	/* buffer_info must be completely set up in the transmit path */
+	buffer_info->length = 0;
+	buffer_info->next_to_watch = 0;
+	buffer_info->mapped_as_page = false;
 }
 
 /**
@@ -2358,7 +2668,6 @@ static void igb_unmap_and_free_tx_resour
  **/
 static void igb_clean_tx_ring(struct igb_ring *tx_ring)
 {
-	struct igb_adapter *adapter = tx_ring->adapter;
 	struct igb_buffer *buffer_info;
 	unsigned long size;
 	unsigned int i;
@@ -2369,21 +2678,17 @@ static void igb_clean_tx_ring(struct igb
 
 	for (i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		igb_unmap_and_free_tx_resource(adapter, buffer_info);
+		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
 	}
 
 	size = sizeof(struct igb_buffer) * tx_ring->count;
 	memset(tx_ring->buffer_info, 0, size);
 
 	/* Zero out the descriptor ring */
-
 	memset(tx_ring->desc, 0, tx_ring->size);
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
-
-	writel(0, adapter->hw.hw_addr + tx_ring->head);
-	writel(0, adapter->hw.hw_addr + tx_ring->tail);
 }
 
 /**
@@ -2406,14 +2711,17 @@ static void igb_clean_all_tx_rings(struc
  **/
 void igb_free_rx_resources(struct igb_ring *rx_ring)
 {
-	struct pci_dev *pdev = rx_ring->adapter->pdev;
-
 	igb_clean_rx_ring(rx_ring);
 
 	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
 
-	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+	/* if not set, then don't free */
+	if (!rx_ring->desc)
+		return;
+
+	pci_free_consistent(rx_ring->pdev, rx_ring->size,
+	                    rx_ring->desc, rx_ring->dma);
 
 	rx_ring->desc = NULL;
 }
@@ -2438,26 +2746,21 @@ static void igb_free_all_rx_resources(st
  **/
 static void igb_clean_rx_ring(struct igb_ring *rx_ring)
 {
-	struct igb_adapter *adapter = rx_ring->adapter;
 	struct igb_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
 	unsigned long size;
 	unsigned int i;
 
 	if (!rx_ring->buffer_info)
 		return;
+
 	/* Free all the Rx ring sk_buffs */
 	for (i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
 		if (buffer_info->dma) {
-			if (adapter->rx_ps_hdr_size)
-				pci_unmap_single(pdev, buffer_info->dma,
-						 adapter->rx_ps_hdr_size,
-						 PCI_DMA_FROMDEVICE);
-			else
-				pci_unmap_single(pdev, buffer_info->dma,
-						 adapter->rx_buffer_len,
-						 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(rx_ring->pdev,
+			                 buffer_info->dma,
+					 rx_ring->rx_buffer_len,
+					 PCI_DMA_FROMDEVICE);
 			buffer_info->dma = 0;
 		}
 
@@ -2465,14 +2768,16 @@ static void igb_clean_rx_ring(struct igb
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
 		}
+		if (buffer_info->page_dma) {
+			pci_unmap_page(rx_ring->pdev,
+			               buffer_info->page_dma,
+				       PAGE_SIZE / 2,
+				       PCI_DMA_FROMDEVICE);
+			buffer_info->page_dma = 0;
+		}
 		if (buffer_info->page) {
-			if (buffer_info->page_dma)
-				pci_unmap_page(pdev, buffer_info->page_dma,
-					       PAGE_SIZE / 2,
-					       PCI_DMA_FROMDEVICE);
 			put_page(buffer_info->page);
 			buffer_info->page = NULL;
-			buffer_info->page_dma = 0;
 			buffer_info->page_offset = 0;
 		}
 	}
@@ -2485,9 +2790,6 @@ static void igb_clean_rx_ring(struct igb
 
 	rx_ring->next_to_clean = 0;
 	rx_ring->next_to_use = 0;
-
-	writel(0, adapter->hw.hw_addr + rx_ring->head);
-	writel(0, adapter->hw.hw_addr + rx_ring->tail);
 }
 
 /**
@@ -2521,61 +2823,90 @@ static int igb_set_mac(struct net_device
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	igb_rar_set(hw, hw->mac.addr, 0);
-	igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+	/* set the correct pool for the new PF MAC address in entry 0 */
+	igb_rar_set_qsel(adapter, hw->mac.addr, 0,
+	                 adapter->vfs_allocated_count);
 
 	return 0;
 }
 
 /**
- * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * igb_write_mc_addr_list - write multicast addresses to MTA
  * @netdev: network interface device structure
  *
- * The set_rx_mode entry point is called whenever the unicast or multicast
- * address lists or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper unicast, multicast,
- * promiscuous mode, and all-multi behavior.
+ * Writes multicast address list to the MTA hash table.
+ * Returns: -ENOMEM on failure
+ *                0 on no addresses written
+ *                X on writing X addresses to MTA
  **/
-static void igb_set_rx_mode(struct net_device *netdev)
+static int igb_write_mc_addr_list(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	unsigned int rar_entries = hw->mac.rar_entry_count -
-	                           (adapter->vfs_allocated_count + 1);
 	struct dev_mc_list *mc_ptr = netdev->mc_list;
-	u8  *mta_list = NULL;
-	u32 rctl;
+	u8  *mta_list;
+	u32 vmolr = 0;
 	int i;
 
-	/* Check for Promiscuous and All Multicast modes */
-	rctl = rd32(E1000_RCTL);
+	if (!netdev->mc_count) {
+		/* nothing to program, so clear mc list */
+		igb_update_mc_addr_list(hw, NULL, 0);
+		igb_restore_vf_multicasts(adapter);
+		return 0;
+	}
 
-	if (netdev->flags & IFF_PROMISC) {
-		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
-		rctl &= ~E1000_RCTL_VFE;
-	} else {
-		if (netdev->flags & IFF_ALLMULTI)
-			rctl |= E1000_RCTL_MPE;
-		else
-			rctl &= ~E1000_RCTL_MPE;
+	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	if (!mta_list)
+		return -ENOMEM;
 
-		if (netdev->uc.count > rar_entries)
-			rctl |= E1000_RCTL_UPE;
-		else
-			rctl &= ~E1000_RCTL_UPE;
-		rctl |= E1000_RCTL_VFE;
+	/* set vmolr receive overflow multicast bit */
+	vmolr |= E1000_VMOLR_ROMPE;
+
+	/* The shared function expects a packed array of only addresses. */
+	mc_ptr = netdev->mc_list;
+
+	for (i = 0; i < netdev->mc_count; i++) {
+		if (!mc_ptr)
+			break;
+		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
+		mc_ptr = mc_ptr->next;
 	}
-	wr32(E1000_RCTL, rctl);
+	igb_update_mc_addr_list(hw, mta_list, i);
+	kfree(mta_list);
+
+	return netdev->mc_count;
+}
+
+/**
+ * igb_write_uc_addr_list - write unicast addresses to RAR table
+ * @netdev: network interface device structure
+ *
+ * Writes unicast address list to the RAR table.
+ * Returns: -ENOMEM on failure/insufficient address space
+ *                0 on no addresses written
+ *                X on writing X addresses to the RAR table
+ **/
+static int igb_write_uc_addr_list(struct net_device *netdev)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	unsigned int vfn = adapter->vfs_allocated_count;
+	unsigned int rar_entries = hw->mac.rar_entry_count - (vfn + 1);
+	int count = 0;
+
+	/* return ENOMEM indicating insufficient memory for addresses */
+	if (netdev->uc.count > rar_entries)
+		return -ENOMEM;
 
 	if (netdev->uc.count && rar_entries) {
 		struct netdev_hw_addr *ha;
 		list_for_each_entry(ha, &netdev->uc.list, list) {
 			if (!rar_entries)
 				break;
-			igb_rar_set(hw, ha->addr, rar_entries);
-			igb_set_rah_pool(hw, adapter->vfs_allocated_count,
-			                 rar_entries);
-			rar_entries--;
+			igb_rar_set_qsel(adapter, ha->addr,
+			                 rar_entries--,
+			                 vfn);
+			count++;
 		}
 	}
 	/* write the addresses in reverse order to avoid write combining */
@@ -2585,29 +2916,79 @@ static void igb_set_rx_mode(struct net_d
 	}
 	wrfl();
 
-	if (!netdev->mc_count) {
-		/* nothing to program, so clear mc list */
-		igb_update_mc_addr_list(hw, NULL, 0);
-		igb_restore_vf_multicasts(adapter);
-		return;
+	return count;
+}
+
+/**
+ * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igb_set_rx_mode(struct net_device *netdev)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	unsigned int vfn = adapter->vfs_allocated_count;
+	u32 rctl, vmolr = 0;
+	int count;
+
+	/* Check for Promiscuous and All Multicast modes */
+	rctl = rd32(E1000_RCTL);
+
+	/* clear the effected bits */
+	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
+
+	if (netdev->flags & IFF_PROMISC) {
+		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+		vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
+	} else {
+		if (netdev->flags & IFF_ALLMULTI) {
+			rctl |= E1000_RCTL_MPE;
+			vmolr |= E1000_VMOLR_MPME;
+		} else {
+			/*
+			 * Write addresses to the MTA, if the attempt fails
+			 * then we should just turn on promiscous mode so
+			 * that we can at least receive multicast traffic
+			 */
+			count = igb_write_mc_addr_list(netdev);
+			if (count < 0) {
+				rctl |= E1000_RCTL_MPE;
+				vmolr |= E1000_VMOLR_MPME;
+			} else if (count) {
+				vmolr |= E1000_VMOLR_ROMPE;
+			}
+		}
+		/*
+		 * Write addresses to available RAR registers, if there is not
+		 * sufficient space to store all the addresses then enable
+		 * unicast promiscous mode
+		 */
+		count = igb_write_uc_addr_list(netdev);
+		if (count < 0) {
+			rctl |= E1000_RCTL_UPE;
+			vmolr |= E1000_VMOLR_ROPE;
+		}
+		rctl |= E1000_RCTL_VFE;
 	}
+	wr32(E1000_RCTL, rctl);
 
-	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
-	if (!mta_list) {
-		dev_err(&adapter->pdev->dev,
-		        "failed to allocate multicast filter list\n");
+	/*
+	 * In order to support SR-IOV and eventually VMDq it is necessary to set
+	 * the VMOLR to enable the appropriate modes.  Without this workaround
+	 * we will have issues with VLAN tag stripping not being done for frames
+	 * that are only arriving because we are the default pool
+	 */
+	if (hw->mac.type < e1000_82576)
 		return;
-	}
 
-	/* The shared function expects a packed array of only addresses. */
-	for (i = 0; i < netdev->mc_count; i++) {
-		if (!mc_ptr)
-			break;
-		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
-		mc_ptr = mc_ptr->next;
-	}
-	igb_update_mc_addr_list(hw, mta_list, i);
-	kfree(mta_list);
+	vmolr |= rd32(E1000_VMOLR(vfn)) &
+	         ~(E1000_VMOLR_ROPE | E1000_VMOLR_MPME | E1000_VMOLR_ROMPE);
+	wr32(E1000_VMOLR(vfn), vmolr);
 	igb_restore_vf_multicasts(adapter);
 }
 
@@ -2669,37 +3050,33 @@ static void igb_watchdog(unsigned long d
 static void igb_watchdog_task(struct work_struct *work)
 {
 	struct igb_adapter *adapter = container_of(work,
-					struct igb_adapter, watchdog_task);
+	                                           struct igb_adapter,
+                                                   watchdog_task);
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
-	struct igb_ring *tx_ring = adapter->tx_ring;
 	u32 link;
-	u32 eics = 0;
 	int i;
 
 	link = igb_has_link(adapter);
-	if ((netif_carrier_ok(netdev)) && link)
-		goto link_up;
-
 	if (link) {
 		if (!netif_carrier_ok(netdev)) {
 			u32 ctrl;
-			hw->mac.ops.get_speed_and_duplex(&adapter->hw,
-						   &adapter->link_speed,
-						   &adapter->link_duplex);
+			hw->mac.ops.get_speed_and_duplex(hw,
+			                                 &adapter->link_speed,
+			                                 &adapter->link_duplex);
 
 			ctrl = rd32(E1000_CTRL);
 			/* Links status message must follow this format */
 			printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, "
 				 "Flow Control: %s\n",
-			         netdev->name,
-				 adapter->link_speed,
-				 adapter->link_duplex == FULL_DUPLEX ?
+			       netdev->name,
+			       adapter->link_speed,
+			       adapter->link_duplex == FULL_DUPLEX ?
 				 "Full Duplex" : "Half Duplex",
-				 ((ctrl & E1000_CTRL_TFCE) && (ctrl &
-				 E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
-				 E1000_CTRL_RFCE) ? "RX" : ((ctrl &
-				 E1000_CTRL_TFCE) ? "TX" : "None")));
+			       ((ctrl & E1000_CTRL_TFCE) &&
+			        (ctrl & E1000_CTRL_RFCE)) ? "RX/TX" :
+			       ((ctrl & E1000_CTRL_RFCE) ?  "RX" :
+			       ((ctrl & E1000_CTRL_TFCE) ?  "TX" : "None")));
 
 			/* tweak tx_queue_len according to speed/duplex and
 			 * adjust the timeout factor */
@@ -2743,46 +3120,40 @@ static void igb_watchdog_task(struct wor
 		}
 	}
 
-link_up:
 	igb_update_stats(adapter);
+	igb_update_adaptive(hw);
 
-	hw->mac.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
-	adapter->tpt_old = adapter->stats.tpt;
-	hw->mac.collision_delta = adapter->stats.colc - adapter->colc_old;
-	adapter->colc_old = adapter->stats.colc;
-
-	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
-	adapter->gorc_old = adapter->stats.gorc;
-	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
-	adapter->gotc_old = adapter->stats.gotc;
-
-	igb_update_adaptive(&adapter->hw);
-
-	if (!netif_carrier_ok(netdev)) {
-		if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		struct igb_ring *tx_ring = &adapter->tx_ring[i];
+		if (!netif_carrier_ok(netdev)) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
 			 * (Do the reset outside of interrupt context). */
-			adapter->tx_timeout_count++;
-			schedule_work(&adapter->reset_task);
-			/* return immediately since reset is imminent */
-			return;
+			if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
+				adapter->tx_timeout_count++;
+				schedule_work(&adapter->reset_task);
+				/* return immediately since reset is imminent */
+				return;
+			}
 		}
+
+		/* Force detection of hung controller every watchdog period */
+		tx_ring->detect_tx_hung = true;
 	}
 
 	/* Cause software interrupt to ensure rx ring is cleaned */
 	if (adapter->msix_entries) {
-		for (i = 0; i < adapter->num_rx_queues; i++)
-			eics |= adapter->rx_ring[i].eims_value;
+		u32 eics = 0;
+		for (i = 0; i < adapter->num_q_vectors; i++) {
+			struct igb_q_vector *q_vector = adapter->q_vector[i];
+			eics |= q_vector->eims_value;
+		}
 		wr32(E1000_EICS, eics);
 	} else {
 		wr32(E1000_ICS, E1000_ICS_RXDMT0);
 	}
 
-	/* Force detection of hung controller every watchdog period */
-	tx_ring->detect_tx_hung = true;
-
 	/* Reset the timer */
 	if (!test_bit(__IGB_DOWN, &adapter->state))
 		mod_timer(&adapter->watchdog_timer,
@@ -2796,7 +3167,6 @@ enum latency_range {
 	latency_invalid = 255
 };
 
-
 /**
  * igb_update_ring_itr - update the dynamic ITR value based on packet size
  *
@@ -2811,25 +3181,37 @@ enum latency_range {
  *      parameter (see igb_param.c)
  *      NOTE:  This function is called only when operating in a multiqueue
  *             receive environment.
- * @rx_ring: pointer to ring
+ * @q_vector: pointer to q_vector
  **/
-static void igb_update_ring_itr(struct igb_ring *rx_ring)
+static void igb_update_ring_itr(struct igb_q_vector *q_vector)
 {
-	int new_val = rx_ring->itr_val;
+	int new_val = q_vector->itr_val;
 	int avg_wire_size = 0;
-	struct igb_adapter *adapter = rx_ring->adapter;
-
-	if (!rx_ring->total_packets)
-		goto clear_counts; /* no packets, so don't do anything */
+	struct igb_adapter *adapter = q_vector->adapter;
 
 	/* For non-gigabit speeds, just fix the interrupt rate at 4000
 	 * ints/sec - ITR timer value of 120 ticks.
 	 */
 	if (adapter->link_speed != SPEED_1000) {
-		new_val = 120;
+		new_val = 976;
 		goto set_itr_val;
 	}
-	avg_wire_size = rx_ring->total_bytes / rx_ring->total_packets;
+
+	if (q_vector->rx_ring && q_vector->rx_ring->total_packets) {
+		struct igb_ring *ring = q_vector->rx_ring;
+		avg_wire_size = ring->total_bytes / ring->total_packets;
+	}
+
+	if (q_vector->tx_ring && q_vector->tx_ring->total_packets) {
+		struct igb_ring *ring = q_vector->tx_ring;
+		avg_wire_size = max_t(u32, avg_wire_size,
+		                      (ring->total_bytes /
+		                       ring->total_packets));
+	}
+
+	/* if avg_wire_size isn't set no work was done */
+	if (!avg_wire_size)
+		goto clear_counts;
 
 	/* Add 24 bytes to size to account for CRC, preamble, and gap */
 	avg_wire_size += 24;
@@ -2844,13 +3226,19 @@ static void igb_update_ring_itr(struct i
 		new_val = avg_wire_size / 2;
 
 set_itr_val:
-	if (new_val != rx_ring->itr_val) {
-		rx_ring->itr_val = new_val;
-		rx_ring->set_itr = 1;
+	if (new_val != q_vector->itr_val) {
+		q_vector->itr_val = new_val;
+		q_vector->set_itr = 1;
 	}
 clear_counts:
-	rx_ring->total_bytes = 0;
-	rx_ring->total_packets = 0;
+	if (q_vector->rx_ring) {
+		q_vector->rx_ring->total_bytes = 0;
+		q_vector->rx_ring->total_packets = 0;
+	}
+	if (q_vector->tx_ring) {
+		q_vector->tx_ring->total_bytes = 0;
+		q_vector->tx_ring->total_packets = 0;
+	}
 }
 
 /**
@@ -2867,7 +3255,7 @@ clear_counts:
  *      NOTE:  These calculations are only valid when operating in a single-
  *             queue environment.
  * @adapter: pointer to adapter
- * @itr_setting: current adapter->itr
+ * @itr_setting: current q_vector->itr_val
  * @packets: the number of packets during this measurement interval
  * @bytes: the number of bytes during this measurement interval
  **/
@@ -2919,8 +3307,9 @@ update_itr_done:
 
 static void igb_set_itr(struct igb_adapter *adapter)
 {
+	struct igb_q_vector *q_vector = adapter->q_vector[0];
 	u16 current_itr;
-	u32 new_itr = adapter->itr;
+	u32 new_itr = q_vector->itr_val;
 
 	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
 	if (adapter->link_speed != SPEED_1000) {
@@ -2934,18 +3323,14 @@ static void igb_set_itr(struct igb_adapt
 				    adapter->rx_ring->total_packets,
 				    adapter->rx_ring->total_bytes);
 
-	if (adapter->rx_ring->buddy) {
-		adapter->tx_itr = igb_update_itr(adapter,
-					    adapter->tx_itr,
-					    adapter->tx_ring->total_packets,
-					    adapter->tx_ring->total_bytes);
-		current_itr = max(adapter->rx_itr, adapter->tx_itr);
-	} else {
-		current_itr = adapter->rx_itr;
-	}
+	adapter->tx_itr = igb_update_itr(adapter,
+				    adapter->tx_itr,
+				    adapter->tx_ring->total_packets,
+				    adapter->tx_ring->total_bytes);
+	current_itr = max(adapter->rx_itr, adapter->tx_itr);
 
 	/* conservative mode (itr 3) eliminates the lowest_latency setting */
-	if (adapter->itr_setting == 3 && current_itr == lowest_latency)
+	if (adapter->rx_itr_setting == 3 && current_itr == lowest_latency)
 		current_itr = low_latency;
 
 	switch (current_itr) {
@@ -2966,18 +3351,17 @@ static void igb_set_itr(struct igb_adapt
 set_itr_now:
 	adapter->rx_ring->total_bytes = 0;
 	adapter->rx_ring->total_packets = 0;
-	if (adapter->rx_ring->buddy) {
-		adapter->rx_ring->buddy->total_bytes = 0;
-		adapter->rx_ring->buddy->total_packets = 0;
-	}
+	adapter->tx_ring->total_bytes = 0;
+	adapter->tx_ring->total_packets = 0;
 
-	if (new_itr != adapter->itr) {
+	if (new_itr != q_vector->itr_val) {
 		/* this attempts to bias the interrupt rate towards Bulk
 		 * by adding intermediate steps when interrupt rate is
 		 * increasing */
-		new_itr = new_itr > adapter->itr ?
-			     max((new_itr * adapter->itr) /
-			         (new_itr + (adapter->itr >> 2)), new_itr) :
+		new_itr = new_itr > q_vector->itr_val ?
+		             max((new_itr * q_vector->itr_val) /
+		                 (new_itr + (q_vector->itr_val >> 2)),
+		                 new_itr) :
 			     new_itr;
 		/* Don't write the value here; it resets the adapter's
 		 * internal timer, and causes us to delay far longer than
@@ -2985,25 +3369,22 @@ set_itr_now:
 		 * value at the beginning of the next interrupt so the timing
 		 * ends up being correct.
 		 */
-		adapter->itr = new_itr;
-		adapter->rx_ring->itr_val = new_itr;
-		adapter->rx_ring->set_itr = 1;
+		q_vector->itr_val = new_itr;
+		q_vector->set_itr = 1;
 	}
 
 	return;
 }
 
-
 #define IGB_TX_FLAGS_CSUM		0x00000001
 #define IGB_TX_FLAGS_VLAN		0x00000002
 #define IGB_TX_FLAGS_TSO		0x00000004
 #define IGB_TX_FLAGS_IPV4		0x00000008
-#define IGB_TX_FLAGS_TSTAMP             0x00000010
-#define IGB_TX_FLAGS_VLAN_MASK	0xffff0000
-#define IGB_TX_FLAGS_VLAN_SHIFT	16
+#define IGB_TX_FLAGS_TSTAMP		0x00000010
+#define IGB_TX_FLAGS_VLAN_MASK		0xffff0000
+#define IGB_TX_FLAGS_VLAN_SHIFT		        16
 
-static inline int igb_tso_adv(struct igb_adapter *adapter,
-			      struct igb_ring *tx_ring,
+static inline int igb_tso_adv(struct igb_ring *tx_ring,
 			      struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
 {
 	struct e1000_adv_tx_context_desc *context_desc;
@@ -3031,7 +3412,7 @@ static inline int igb_tso_adv(struct igb
 							 iph->daddr, 0,
 							 IPPROTO_TCP,
 							 0);
-	} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+	} else if (skb_is_gso_v6(skb)) {
 		ipv6_hdr(skb)->payload_len = 0;
 		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
 						       &ipv6_hdr(skb)->daddr,
@@ -3065,8 +3446,8 @@ static inline int igb_tso_adv(struct igb
 	mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
 
 	/* For 82575, context index must be unique per ring. */
-	if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
-		mss_l4len_idx |= tx_ring->queue_index << 4;
+	if (tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX)
+		mss_l4len_idx |= tx_ring->reg_idx << 4;
 
 	context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
 	context_desc->seqnum_seed = 0;
@@ -3083,14 +3464,14 @@ static inline int igb_tso_adv(struct igb
 	return true;
 }
 
-static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
-					struct igb_ring *tx_ring,
-					struct sk_buff *skb, u32 tx_flags)
+static inline bool igb_tx_csum_adv(struct igb_ring *tx_ring,
+				   struct sk_buff *skb, u32 tx_flags)
 {
 	struct e1000_adv_tx_context_desc *context_desc;
-	unsigned int i;
+	struct pci_dev *pdev = tx_ring->pdev;
 	struct igb_buffer *buffer_info;
 	u32 info = 0, tu_cmd = 0;
+	unsigned int i;
 
 	if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
 	    (tx_flags & IGB_TX_FLAGS_VLAN)) {
@@ -3100,6 +3481,7 @@ static inline bool igb_tx_csum_adv(struc
 
 		if (tx_flags & IGB_TX_FLAGS_VLAN)
 			info |= (tx_flags & IGB_TX_FLAGS_VLAN_MASK);
+
 		info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
 		if (skb->ip_summed == CHECKSUM_PARTIAL)
 			info |= skb_network_header_len(skb);
@@ -3137,7 +3519,7 @@ static inline bool igb_tx_csum_adv(struc
 				break;
 			default:
 				if (unlikely(net_ratelimit()))
-					dev_warn(&adapter->pdev->dev,
+					dev_warn(&pdev->dev,
 					    "partial checksum but proto=%x!\n",
 					    skb->protocol);
 				break;
@@ -3146,11 +3528,9 @@ static inline bool igb_tx_csum_adv(struc
 
 		context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
 		context_desc->seqnum_seed = 0;
-		if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+		if (tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX)
 			context_desc->mss_l4len_idx =
-				cpu_to_le32(tx_ring->queue_index << 4);
-		else
-			context_desc->mss_l4len_idx = 0;
+				cpu_to_le32(tx_ring->reg_idx << 4);
 
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
@@ -3169,36 +3549,32 @@ static inline bool igb_tx_csum_adv(struc
 #define IGB_MAX_TXD_PWR	16
 #define IGB_MAX_DATA_PER_TXD	(1<<IGB_MAX_TXD_PWR)
 
-static inline int igb_tx_map_adv(struct igb_adapter *adapter,
-				 struct igb_ring *tx_ring, struct sk_buff *skb,
+static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
 				 unsigned int first)
 {
 	struct igb_buffer *buffer_info;
+	struct pci_dev *pdev = tx_ring->pdev;
 	unsigned int len = skb_headlen(skb);
 	unsigned int count = 0, i;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-
 	buffer_info = &tx_ring->buffer_info[i];
 	BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
 	buffer_info->length = len;
 	/* set time_stamp *before* dma to help avoid a possible race */
 	buffer_info->time_stamp = jiffies;
 	buffer_info->next_to_watch = i;
-	buffer_info->dma = skb_shinfo(skb)->dma_head;
+	buffer_info->dma = pci_map_single(pdev, skb->data, len,
+					  PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(pdev, buffer_info->dma))
+		goto dma_error;
 
 	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
+		count++;
 		i++;
 		if (i == tx_ring->count)
 			i = 0;
@@ -3211,25 +3587,54 @@ static inline int igb_tx_map_adv(struct
 		buffer_info->length = len;
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
-		buffer_info->dma = map[count];
-		count++;
+		buffer_info->mapped_as_page = true;
+		buffer_info->dma = pci_map_page(pdev,
+						frag->page,
+						frag->page_offset,
+						len,
+						PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma))
+			goto dma_error;
+
 	}
 
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
-	return count + 1;
+	return ++count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+
+	/* clear timestamp and dma mappings for failed buffer_info mapping */
+	buffer_info->dma = 0;
+	buffer_info->time_stamp = 0;
+	buffer_info->length = 0;
+	buffer_info->next_to_watch = 0;
+	buffer_info->mapped_as_page = false;
+	count--;
+
+	/* clear timestamp and dma mappings for remaining portion of packet */
+	while (count >= 0) {
+		count--;
+		i--;
+		if (i < 0)
+			i += tx_ring->count;
+		buffer_info = &tx_ring->buffer_info[i];
+		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
+	}
+
+	return 0;
 }
 
-static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
-				    struct igb_ring *tx_ring,
+static inline void igb_tx_queue_adv(struct igb_ring *tx_ring,
 				    int tx_flags, int count, u32 paylen,
 				    u8 hdr_len)
 {
-	union e1000_adv_tx_desc *tx_desc = NULL;
+	union e1000_adv_tx_desc *tx_desc;
 	struct igb_buffer *buffer_info;
 	u32 olinfo_status = 0, cmd_type_len;
-	unsigned int i;
+	unsigned int i = tx_ring->next_to_use;
 
 	cmd_type_len = (E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS |
 			E1000_ADVTXD_DCMD_DEXT);
@@ -3254,27 +3659,28 @@ static inline void igb_tx_queue_adv(stru
 		olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
 	}
 
-	if ((adapter->flags & IGB_FLAG_NEED_CTX_IDX) &&
-	    (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+	if ((tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX) &&
+	    (tx_flags & (IGB_TX_FLAGS_CSUM |
+	                 IGB_TX_FLAGS_TSO |
 			 IGB_TX_FLAGS_VLAN)))
-		olinfo_status |= tx_ring->queue_index << 4;
+		olinfo_status |= tx_ring->reg_idx << 4;
 
 	olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
 
-	i = tx_ring->next_to_use;
-	while (count--) {
+	do {
 		buffer_info = &tx_ring->buffer_info[i];
 		tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
 		tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
 		tx_desc->read.cmd_type_len =
 			cpu_to_le32(cmd_type_len | buffer_info->length);
 		tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+		count--;
 		i++;
 		if (i == tx_ring->count)
 			i = 0;
-	}
+	} while (count > 0);
 
-	tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+	tx_desc->read.cmd_type_len |= cpu_to_le32(IGB_ADVTXD_DCMD);
 	/* Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
 	 * applicable for weak-ordered memory model archs,
@@ -3282,16 +3688,15 @@ static inline void igb_tx_queue_adv(stru
 	wmb();
 
 	tx_ring->next_to_use = i;
-	writel(i, adapter->hw.hw_addr + tx_ring->tail);
+	writel(i, tx_ring->tail);
 	/* we need this if more than one processor can write to our tail
 	 * at a time, it syncronizes IO on IA64/Altix systems */
 	mmiowb();
 }
 
-static int __igb_maybe_stop_tx(struct net_device *netdev,
-			       struct igb_ring *tx_ring, int size)
+static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
 {
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct net_device *netdev = tx_ring->netdev;
 
 	netif_stop_subqueue(netdev, tx_ring->queue_index);
 
@@ -3307,66 +3712,43 @@ static int __igb_maybe_stop_tx(struct ne
 
 	/* A reprieve! */
 	netif_wake_subqueue(netdev, tx_ring->queue_index);
-	++adapter->restart_queue;
+	tx_ring->tx_stats.restart_queue++;
 	return 0;
 }
 
-static int igb_maybe_stop_tx(struct net_device *netdev,
-			     struct igb_ring *tx_ring, int size)
+static int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
 {
 	if (igb_desc_unused(tx_ring) >= size)
 		return 0;
-	return __igb_maybe_stop_tx(netdev, tx_ring, size);
+	return __igb_maybe_stop_tx(tx_ring, size);
 }
 
-static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
-					   struct net_device *netdev,
-					   struct igb_ring *tx_ring)
+netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
+				    struct igb_ring *tx_ring)
 {
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
 	unsigned int first;
 	unsigned int tx_flags = 0;
 	u8 hdr_len = 0;
-	int count = 0;
-	int tso = 0;
-	union skb_shared_tx *shtx;
-
-	if (test_bit(__IGB_DOWN, &adapter->state)) {
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
-	}
-
-	if (skb->len <= 0) {
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
-	}
+	int tso = 0, count;
+	union skb_shared_tx *shtx = skb_tx(skb);
 
 	/* need: 1 descriptor per page,
 	 *       + 2 desc gap to keep tail from touching head,
 	 *       + 1 desc for skb->data,
 	 *       + 1 desc for context descriptor,
 	 * otherwise try next time */
-	if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
+	if (igb_maybe_stop_tx(tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
 		/* this is a hard error */
 		return NETDEV_TX_BUSY;
 	}
 
-	/*
-	 * TODO: check that there currently is no other packet with
-	 * time stamping in the queue
-	 *
-	 * When doing time stamping, keep the connection to the socket
-	 * a while longer: it is still needed by skb_hwtstamp_tx(),
-	 * called either in igb_tx_hwtstamp() or by our caller when
-	 * doing software time stamping.
-	 */
-	shtx = skb_tx(skb);
 	if (unlikely(shtx->hardware)) {
 		shtx->in_progress = 1;
 		tx_flags |= IGB_TX_FLAGS_TSTAMP;
 	}
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb) && adapter->vlgrp) {
 		tx_flags |= IGB_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
 	}
@@ -3375,37 +3757,38 @@ static netdev_tx_t igb_xmit_frame_ring_a
 		tx_flags |= IGB_TX_FLAGS_IPV4;
 
 	first = tx_ring->next_to_use;
-	tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
-					      &hdr_len) : 0;
+	if (skb_is_gso(skb)) {
+		tso = igb_tso_adv(tx_ring, skb, tx_flags, &hdr_len);
 
-	if (tso < 0) {
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
+		if (tso < 0) {
+			dev_kfree_skb_any(skb);
+			return NETDEV_TX_OK;
+		}
 	}
 
 	if (tso)
 		tx_flags |= IGB_TX_FLAGS_TSO;
-	else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags) &&
+	else if (igb_tx_csum_adv(tx_ring, skb, tx_flags) &&
 	         (skb->ip_summed == CHECKSUM_PARTIAL))
 		tx_flags |= IGB_TX_FLAGS_CSUM;
 
 	/*
-	 * count reflects descriptors mapped, if 0 then mapping error
+	 * count reflects descriptors mapped, if 0 or less then mapping error
 	 * has occured and we need to rewind the descriptor queue
 	 */
-	count = igb_tx_map_adv(adapter, tx_ring, skb, first);
-
-	if (count) {
-		igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
-			         skb->len, hdr_len);
-		/* Make sure there is space in the ring for the next send. */
-		igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
-	} else {
+	count = igb_tx_map_adv(tx_ring, skb, first);
+	if (!count) {
 		dev_kfree_skb_any(skb);
 		tx_ring->buffer_info[first].time_stamp = 0;
 		tx_ring->next_to_use = first;
+		return NETDEV_TX_OK;
 	}
 
+	igb_tx_queue_adv(tx_ring, tx_flags, count, skb->len, hdr_len);
+
+	/* Make sure there is space in the ring for the next send. */
+	igb_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 4);
+
 	return NETDEV_TX_OK;
 }
 
@@ -3414,8 +3797,18 @@ static netdev_tx_t igb_xmit_frame_adv(st
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct igb_ring *tx_ring;
-
 	int r_idx = 0;
+
+	if (test_bit(__IGB_DOWN, &adapter->state)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (skb->len <= 0) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
 	r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
 	tx_ring = adapter->multi_tx_table[r_idx];
 
@@ -3423,7 +3816,7 @@ static netdev_tx_t igb_xmit_frame_adv(st
 	 * to a flow.  Right now, performance is impacted slightly negatively
 	 * if using multiple tx queues.  If the stack breaks away from a
 	 * single qdisc implementation, we can look at this again. */
-	return igb_xmit_frame_ring_adv(skb, netdev, tx_ring);
+	return igb_xmit_frame_ring_adv(skb, tx_ring);
 }
 
 /**
@@ -3437,6 +3830,10 @@ static void igb_tx_timeout(struct net_de
 
 	/* Do the reset outside of interrupt context */
 	adapter->tx_timeout_count++;
+
+	if (hw->mac.type == e1000_82580)
+		hw->dev_spec._82575.global_device_reset = true;
+
 	schedule_work(&adapter->reset_task);
 	wr32(E1000_EICS,
 	     (adapter->eims_enable_mask & ~adapter->eims_other));
@@ -3459,10 +3856,8 @@ static void igb_reset_task(struct work_s
  **/
 static struct net_device_stats *igb_get_stats(struct net_device *netdev)
 {
-	struct igb_adapter *adapter = netdev_priv(netdev);
-
 	/* only return the current stats */
-	return &adapter->net_stats;
+	return &netdev->stats;
 }
 
 /**
@@ -3475,16 +3870,17 @@ static struct net_device_stats *igb_get_
 static int igb_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct pci_dev *pdev = adapter->pdev;
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+	u32 rx_buffer_len, i;
 
-	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
-	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		dev_err(&adapter->pdev->dev, "Invalid MTU setting\n");
+	if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+		dev_err(&pdev->dev, "Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
 	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-		dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
+		dev_err(&pdev->dev, "MTU > 9216 not supported.\n");
 		return -EINVAL;
 	}
 
@@ -3493,8 +3889,6 @@ static int igb_change_mtu(struct net_dev
 
 	/* igb_down has a dependency on max_frame_size */
 	adapter->max_frame_size = max_frame;
-	if (netif_running(netdev))
-		igb_down(adapter);
 
 	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
 	 * means we reserve 2 more, this pushes us to allocate from the next
@@ -3502,35 +3896,23 @@ static int igb_change_mtu(struct net_dev
 	 * i.e. RXBUFFER_2048 --> size-4096 slab
 	 */
 
-	if (max_frame <= IGB_RXBUFFER_256)
-		adapter->rx_buffer_len = IGB_RXBUFFER_256;
-	else if (max_frame <= IGB_RXBUFFER_512)
-		adapter->rx_buffer_len = IGB_RXBUFFER_512;
-	else if (max_frame <= IGB_RXBUFFER_1024)
-		adapter->rx_buffer_len = IGB_RXBUFFER_1024;
-	else if (max_frame <= IGB_RXBUFFER_2048)
-		adapter->rx_buffer_len = IGB_RXBUFFER_2048;
+	if (max_frame <= IGB_RXBUFFER_1024)
+		rx_buffer_len = IGB_RXBUFFER_1024;
+	else if (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE)
+		rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
 	else
-#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
-		adapter->rx_buffer_len = IGB_RXBUFFER_16384;
-#else
-		adapter->rx_buffer_len = PAGE_SIZE / 2;
-#endif
-
-	/* if sr-iov is enabled we need to force buffer size to 1K or larger */
-	if (adapter->vfs_allocated_count &&
-	    (adapter->rx_buffer_len < IGB_RXBUFFER_1024))
-		adapter->rx_buffer_len = IGB_RXBUFFER_1024;
+		rx_buffer_len = IGB_RXBUFFER_128;
 
-	/* adjust allocation if LPE protects us, and we aren't using SBP */
-	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
-	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
-		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+	if (netif_running(netdev))
+		igb_down(adapter);
 
-	dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
+	dev_info(&pdev->dev, "changing MTU from %d to %d\n",
 		 netdev->mtu, new_mtu);
 	netdev->mtu = new_mtu;
 
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		adapter->rx_ring[i].rx_buffer_len = rx_buffer_len;
+
 	if (netif_running(netdev))
 		igb_up(adapter);
 	else
@@ -3548,9 +3930,13 @@ static int igb_change_mtu(struct net_dev
 
 void igb_update_stats(struct igb_adapter *adapter)
 {
+	struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
+	u32 rnbc;
 	u16 phy_tmp;
+	int i;
+	u64 bytes, packets;
 
 #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
 
@@ -3563,6 +3949,29 @@ void igb_update_stats(struct igb_adapter
 	if (pci_channel_offline(pdev))
 		return;
 
+	bytes = 0;
+	packets = 0;
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF;
+		adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
+		net_stats->rx_fifo_errors += rqdpc_tmp;
+		bytes += adapter->rx_ring[i].rx_stats.bytes;
+		packets += adapter->rx_ring[i].rx_stats.packets;
+	}
+
+	net_stats->rx_bytes = bytes;
+	net_stats->rx_packets = packets;
+
+	bytes = 0;
+	packets = 0;
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		bytes += adapter->tx_ring[i].tx_stats.bytes;
+		packets += adapter->tx_ring[i].tx_stats.packets;
+	}
+	net_stats->tx_bytes = bytes;
+	net_stats->tx_packets = packets;
+
+	/* read stats registers */
 	adapter->stats.crcerrs += rd32(E1000_CRCERRS);
 	adapter->stats.gprc += rd32(E1000_GPRC);
 	adapter->stats.gorc += rd32(E1000_GORCL);
@@ -3595,7 +4004,9 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.gptc += rd32(E1000_GPTC);
 	adapter->stats.gotc += rd32(E1000_GOTCL);
 	rd32(E1000_GOTCH); /* clear GOTCL */
-	adapter->stats.rnbc += rd32(E1000_RNBC);
+	rnbc = rd32(E1000_RNBC);
+	adapter->stats.rnbc += rnbc;
+	net_stats->rx_fifo_errors += rnbc;
 	adapter->stats.ruc += rd32(E1000_RUC);
 	adapter->stats.rfc += rd32(E1000_RFC);
 	adapter->stats.rjc += rd32(E1000_RJC);
@@ -3614,7 +4025,6 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.bptc += rd32(E1000_BPTC);
 
 	/* used for adaptive IFS */
-
 	hw->mac.tx_packet_delta = rd32(E1000_TPT);
 	adapter->stats.tpt += hw->mac.tx_packet_delta;
 	hw->mac.collision_delta = rd32(E1000_COLC);
@@ -3637,56 +4047,29 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.icrxdmtc += rd32(E1000_ICRXDMTC);
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.multicast = adapter->stats.mprc;
-	adapter->net_stats.collisions = adapter->stats.colc;
+	net_stats->multicast = adapter->stats.mprc;
+	net_stats->collisions = adapter->stats.colc;
 
 	/* Rx Errors */
 
-	if (hw->mac.type != e1000_82575) {
-		u32 rqdpc_tmp;
-		u64 rqdpc_total = 0;
-		int i;
-		/* Read out drops stats per RX queue.  Notice RQDPC (Receive
-		 * Queue Drop Packet Count) stats only gets incremented, if
-		 * the DROP_EN but it set (in the SRRCTL register for that
-		 * queue).  If DROP_EN bit is NOT set, then the some what
-		 * equivalent count is stored in RNBC (not per queue basis).
-		 * Also note the drop count is due to lack of available
-		 * descriptors.
-		 */
-		for (i = 0; i < adapter->num_rx_queues; i++) {
-			rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0xFFF;
-			adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
-			rqdpc_total += adapter->rx_ring[i].rx_stats.drops;
-		}
-		adapter->net_stats.rx_fifo_errors = rqdpc_total;
-	}
-
-	/* Note RNBC (Receive No Buffers Count) is an not an exact
-	 * drop count as the hardware FIFO might save the day.  Thats
-	 * one of the reason for saving it in rx_fifo_errors, as its
-	 * potentially not a true drop.
-	 */
-	adapter->net_stats.rx_fifo_errors += adapter->stats.rnbc;
-
 	/* RLEC on some newer hardware can be incorrect so build
 	 * our own version based on RUC and ROC */
-	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
+	net_stats->rx_errors = adapter->stats.rxerrc +
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.ruc + adapter->stats.roc +
 		adapter->stats.cexterr;
-	adapter->net_stats.rx_length_errors = adapter->stats.ruc +
-					      adapter->stats.roc;
-	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+	net_stats->rx_length_errors = adapter->stats.ruc +
+				      adapter->stats.roc;
+	net_stats->rx_crc_errors = adapter->stats.crcerrs;
+	net_stats->rx_frame_errors = adapter->stats.algnerrc;
+	net_stats->rx_missed_errors = adapter->stats.mpc;
 
 	/* Tx Errors */
-	adapter->net_stats.tx_errors = adapter->stats.ecol +
-				       adapter->stats.latecol;
-	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
-	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
-	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+	net_stats->tx_errors = adapter->stats.ecol +
+			       adapter->stats.latecol;
+	net_stats->tx_aborted_errors = adapter->stats.ecol;
+	net_stats->tx_window_errors = adapter->stats.latecol;
+	net_stats->tx_carrier_errors = adapter->stats.tncrs;
 
 	/* Tx Dropped needs to be maintained elsewhere */
 
@@ -3707,14 +4090,12 @@ void igb_update_stats(struct igb_adapter
 
 static irqreturn_t igb_msix_other(int irq, void *data)
 {
-	struct net_device *netdev = data;
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct igb_adapter *adapter = data;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 icr = rd32(E1000_ICR);
-
 	/* reading ICR causes bit 31 of EICR to be cleared */
 
-	if(icr & E1000_ICR_DOUTSYNC) {
+	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
 	}
@@ -3730,125 +4111,90 @@ static irqreturn_t igb_msix_other(int ir
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_VMMB);
+	if (adapter->vfs_allocated_count)
+		wr32(E1000_IMS, E1000_IMS_LSC |
+				E1000_IMS_VMMB |
+				E1000_IMS_DOUTSYNC);
+	else
+		wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC);
 	wr32(E1000_EIMS, adapter->eims_other);
 
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t igb_msix_tx(int irq, void *data)
+static void igb_write_itr(struct igb_q_vector *q_vector)
 {
-	struct igb_ring *tx_ring = data;
-	struct igb_adapter *adapter = tx_ring->adapter;
-	struct e1000_hw *hw = &adapter->hw;
+	u32 itr_val = q_vector->itr_val & 0x7FFC;
 
-#ifdef CONFIG_IGB_DCA
-	if (adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_tx_dca(tx_ring);
-#endif
+	if (!q_vector->set_itr)
+		return;
 
-	tx_ring->total_bytes = 0;
-	tx_ring->total_packets = 0;
+	if (!itr_val)
+		itr_val = 0x4;
 
-	/* auto mask will automatically reenable the interrupt when we write
-	 * EICS */
-	if (!igb_clean_tx_irq(tx_ring))
-		/* Ring was not completely cleaned, so fire another interrupt */
-		wr32(E1000_EICS, tx_ring->eims_value);
+	if (q_vector->itr_shift)
+		itr_val |= itr_val << q_vector->itr_shift;
 	else
-		wr32(E1000_EIMS, tx_ring->eims_value);
-
-	return IRQ_HANDLED;
-}
+		itr_val |= 0x8000000;
 
-static void igb_write_itr(struct igb_ring *ring)
-{
-	struct e1000_hw *hw = &ring->adapter->hw;
-	if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
-		switch (hw->mac.type) {
-		case e1000_82576:
-			wr32(ring->itr_register, ring->itr_val |
-			     0x80000000);
-			break;
-		default:
-			wr32(ring->itr_register, ring->itr_val |
-			     (ring->itr_val << 16));
-			break;
-		}
-		ring->set_itr = 0;
-	}
+	writel(itr_val, q_vector->itr_register);
+	q_vector->set_itr = 0;
 }
 
-static irqreturn_t igb_msix_rx(int irq, void *data)
+static irqreturn_t igb_msix_ring(int irq, void *data)
 {
-	struct igb_ring *rx_ring = data;
-
-	/* Write the ITR value calculated at the end of the
-	 * previous interrupt.
-	 */
+	struct igb_q_vector *q_vector = data;
 
-	igb_write_itr(rx_ring);
+	/* Write the ITR value calculated from the previous interrupt. */
+	igb_write_itr(q_vector);
 
-	if (napi_schedule_prep(&rx_ring->napi))
-		__napi_schedule(&rx_ring->napi);
+	napi_schedule(&q_vector->napi);
 
-#ifdef CONFIG_IGB_DCA
-	if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_rx_dca(rx_ring);
-#endif
-		return IRQ_HANDLED;
+	return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_IGB_DCA
-static void igb_update_rx_dca(struct igb_ring *rx_ring)
+static void igb_update_dca(struct igb_q_vector *q_vector)
 {
-	u32 dca_rxctrl;
-	struct igb_adapter *adapter = rx_ring->adapter;
+	struct igb_adapter *adapter = q_vector->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 	int cpu = get_cpu();
-	int q = rx_ring->reg_idx;
 
-	if (rx_ring->cpu != cpu) {
-		dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
-		if (hw->mac.type == e1000_82576) {
-			dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
-			dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
-			              E1000_DCA_RXCTRL_CPUID_SHIFT;
+	if (q_vector->cpu == cpu)
+		goto out_no_update;
+
+	if (q_vector->tx_ring) {
+		int q = q_vector->tx_ring->reg_idx;
+		u32 dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
+		if (hw->mac.type == e1000_82575) {
+			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
+			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		} else {
+			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
+			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
+			              E1000_DCA_TXCTRL_CPUID_SHIFT;
+		}
+		dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
+		wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
+	}
+	if (q_vector->rx_ring) {
+		int q = q_vector->rx_ring->reg_idx;
+		u32 dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
+		if (hw->mac.type == e1000_82575) {
 			dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
 			dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+		} else {
+			dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
+			dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
+			              E1000_DCA_RXCTRL_CPUID_SHIFT;
 		}
 		dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
 		dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
 		dca_rxctrl |= E1000_DCA_RXCTRL_DATA_DCA_EN;
 		wr32(E1000_DCA_RXCTRL(q), dca_rxctrl);
-		rx_ring->cpu = cpu;
-	}
-	put_cpu();
-}
-
-static void igb_update_tx_dca(struct igb_ring *tx_ring)
-{
-	u32 dca_txctrl;
-	struct igb_adapter *adapter = tx_ring->adapter;
-	struct e1000_hw *hw = &adapter->hw;
-	int cpu = get_cpu();
-	int q = tx_ring->reg_idx;
-
-	if (tx_ring->cpu != cpu) {
-		dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
-		if (hw->mac.type == e1000_82576) {
-			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
-			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
-			              E1000_DCA_TXCTRL_CPUID_SHIFT;
-		} else {
-			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
-			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
-		}
-		dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
-		wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
-		tx_ring->cpu = cpu;
 	}
+	q_vector->cpu = cpu;
+out_no_update:
 	put_cpu();
 }
 
@@ -3863,13 +4209,10 @@ static void igb_setup_dca(struct igb_ada
 	/* Always use CB2 mode, difference is masked in the CB driver. */
 	wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
 
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		adapter->tx_ring[i].cpu = -1;
-		igb_update_tx_dca(&adapter->tx_ring[i]);
-	}
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		adapter->rx_ring[i].cpu = -1;
-		igb_update_rx_dca(&adapter->rx_ring[i]);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		q_vector->cpu = -1;
+		igb_update_dca(q_vector);
 	}
 }
 
@@ -3877,6 +4220,7 @@ static int __igb_notify_dca(struct devic
 {
 	struct net_device *netdev = dev_get_drvdata(dev);
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_hw *hw = &adapter->hw;
 	unsigned long event = *(unsigned long *)data;
 
@@ -3885,12 +4229,9 @@ static int __igb_notify_dca(struct devic
 		/* if already enabled, don't do it again */
 		if (adapter->flags & IGB_FLAG_DCA_ENABLED)
 			break;
-		/* Always use CB2 mode, difference is masked
-		 * in the CB driver. */
-		wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
 		if (dca_add_requester(dev) == 0) {
 			adapter->flags |= IGB_FLAG_DCA_ENABLED;
-			dev_info(&adapter->pdev->dev, "DCA enabled\n");
+			dev_info(&pdev->dev, "DCA enabled\n");
 			igb_setup_dca(adapter);
 			break;
 		}
@@ -3898,9 +4239,9 @@ static int __igb_notify_dca(struct devic
 	case DCA_PROVIDER_REMOVE:
 		if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
 			/* without this a class_device is left
- 			 * hanging around in the sysfs model */
+			 * hanging around in the sysfs model */
 			dca_remove_requester(dev);
-			dev_info(&adapter->pdev->dev, "DCA disabled\n");
+			dev_info(&pdev->dev, "DCA disabled\n");
 			adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
 			wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
 		}
@@ -3930,12 +4271,51 @@ static void igb_ping_all_vfs(struct igb_
 
 	for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
 		ping = E1000_PF_CONTROL_MSG;
-		if (adapter->vf_data[i].clear_to_send)
+		if (adapter->vf_data[i].flags & IGB_VF_FLAG_CTS)
 			ping |= E1000_VT_MSGTYPE_CTS;
 		igb_write_mbx(hw, &ping, 1, i);
 	}
 }
 
+static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 vmolr = rd32(E1000_VMOLR(vf));
+	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
+
+	vf_data->flags |= ~(IGB_VF_FLAG_UNI_PROMISC |
+	                    IGB_VF_FLAG_MULTI_PROMISC);
+	vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
+
+	if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) {
+		vmolr |= E1000_VMOLR_MPME;
+		*msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST;
+	} else {
+		/*
+		 * if we have hashes and we are clearing a multicast promisc
+		 * flag we need to write the hashes to the MTA as this step
+		 * was previously skipped
+		 */
+		if (vf_data->num_vf_mc_hashes > 30) {
+			vmolr |= E1000_VMOLR_MPME;
+		} else if (vf_data->num_vf_mc_hashes) {
+			int j;
+			vmolr |= E1000_VMOLR_ROMPE;
+			for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
+				igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
+		}
+	}
+
+	wr32(E1000_VMOLR(vf), vmolr);
+
+	/* there are flags left unprocessed, likely not supported */
+	if (*msgbuf & E1000_VT_MSGINFO_MASK)
+		return -EINVAL;
+
+	return 0;
+
+}
+
 static int igb_set_vf_multicasts(struct igb_adapter *adapter,
 				  u32 *msgbuf, u32 vf)
 {
@@ -3944,18 +4324,17 @@ static int igb_set_vf_multicasts(struct
 	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
 	int i;
 
-	/* only up to 30 hash values supported */
-	if (n > 30)
-		n = 30;
-
-	/* salt away the number of multi cast addresses assigned
+	/* salt away the number of multicast addresses assigned
 	 * to this VF for later use to restore when the PF multi cast
 	 * list changes
 	 */
 	vf_data->num_vf_mc_hashes = n;
 
-	/* VFs are limited to using the MTA hash table for their multicast
-	 * addresses */
+	/* only up to 30 hash values supported */
+	if (n > 30)
+		n = 30;
+
+	/* store the hashes for later use */
 	for (i = 0; i < n; i++)
 		vf_data->vf_mc_hashes[i] = hash_list[i];
 
@@ -3972,9 +4351,20 @@ static void igb_restore_vf_multicasts(st
 	int i, j;
 
 	for (i = 0; i < adapter->vfs_allocated_count; i++) {
+		u32 vmolr = rd32(E1000_VMOLR(i));
+		vmolr &= ~(E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
+
 		vf_data = &adapter->vf_data[i];
-		for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
-			igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
+
+		if ((vf_data->num_vf_mc_hashes > 30) ||
+		    (vf_data->flags & IGB_VF_FLAG_MULTI_PROMISC)) {
+			vmolr |= E1000_VMOLR_MPME;
+		} else if (vf_data->num_vf_mc_hashes) {
+			vmolr |= E1000_VMOLR_ROMPE;
+			for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
+				igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
+		}
+		wr32(E1000_VMOLR(i), vmolr);
 	}
 }
 
@@ -4012,7 +4402,11 @@ static s32 igb_vlvf_set(struct igb_adapt
 	struct e1000_hw *hw = &adapter->hw;
 	u32 reg, i;
 
-	/* It is an error to call this function when VFs are not enabled */
+	/* The vlvf table only exists on 82576 hardware and newer */
+	if (hw->mac.type < e1000_82576)
+		return -1;
+
+	/* we only need to do this if VMDq is enabled */
 	if (!adapter->vfs_allocated_count)
 		return -1;
 
@@ -4042,16 +4436,12 @@ static s32 igb_vlvf_set(struct igb_adapt
 
 			/* if !enabled we need to set this up in vfta */
 			if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
-				/* add VID to filter table, if bit already set
-				 * PF must have added it outside of table */
-				if (igb_vfta_set(hw, vid, true))
-					reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT +
-						adapter->vfs_allocated_count);
+				/* add VID to filter table */
+				igb_vfta_set(hw, vid, true);
 				reg |= E1000_VLVF_VLANID_ENABLE;
 			}
 			reg &= ~E1000_VLVF_VLANID_MASK;
 			reg |= vid;
-
 			wr32(E1000_VLVF(i), reg);
 
 			/* do not modify RLPML for PF devices */
@@ -4067,8 +4457,8 @@ static s32 igb_vlvf_set(struct igb_adapt
 				reg |= size;
 				wr32(E1000_VMOLR(vf), reg);
 			}
-			adapter->vf_data[vf].vlans_enabled++;
 
+			adapter->vf_data[vf].vlans_enabled++;
 			return 0;
 		}
 	} else {
@@ -4110,15 +4500,14 @@ static int igb_set_vf_vlan(struct igb_ad
 	return igb_vlvf_set(adapter, vid, add, vf);
 }
 
-static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
 {
-	struct e1000_hw *hw = &adapter->hw;
-
-	/* disable mailbox functionality for vf */
-	adapter->vf_data[vf].clear_to_send = false;
+	/* clear all flags */
+	adapter->vf_data[vf].flags = 0;
+	adapter->vf_data[vf].last_nack = jiffies;
 
 	/* reset offloads to defaults */
-	igb_set_vmolr(hw, vf);
+	igb_set_vmolr(adapter, vf);
 
 	/* reset vlans for device */
 	igb_clear_vf_vfta(adapter, vf);
@@ -4130,7 +4519,18 @@ static inline void igb_vf_reset_event(st
 	igb_set_rx_mode(adapter->netdev);
 }
 
-static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+{
+	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+
+	/* generate a new mac address as we were hotplug removed/added */
+	random_ether_addr(vf_mac);
+
+	/* process remaining reset events */
+	igb_vf_reset(adapter, vf);
+}
+
+static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
@@ -4139,11 +4539,10 @@ static inline void igb_vf_reset_msg(stru
 	u8 *addr = (u8 *)(&msgbuf[1]);
 
 	/* process all the same items cleared in a function level reset */
-	igb_vf_reset_event(adapter, vf);
+	igb_vf_reset(adapter, vf);
 
 	/* set vf mac address */
-	igb_rar_set(hw, vf_mac, rar_entry);
-	igb_set_rah_pool(hw, vf, rar_entry);
+	igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf);
 
 	/* enable transmit and receive for vf */
 	reg = rd32(E1000_VFTE);
@@ -4151,8 +4550,7 @@ static inline void igb_vf_reset_msg(stru
 	reg = rd32(E1000_VFRE);
 	wr32(E1000_VFRE, reg | (1 << vf));
 
-	/* enable mailbox functionality for vf */
-	adapter->vf_data[vf].clear_to_send = true;
+	adapter->vf_data[vf].flags = IGB_VF_FLAG_CTS;
 
 	/* reply to reset with ack and vf mac address */
 	msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
@@ -4162,66 +4560,51 @@ static inline void igb_vf_reset_msg(stru
 
 static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
 {
-		unsigned char *addr = (char *)&msg[1];
-		int err = -1;
-
-		if (is_valid_ether_addr(addr))
-			err = igb_set_vf_mac(adapter, vf, addr);
+	unsigned char *addr = (char *)&msg[1];
+	int err = -1;
 
-		return err;
+	if (is_valid_ether_addr(addr))
+		err = igb_set_vf_mac(adapter, vf, addr);
 
+	return err;
 }
 
 static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
 {
 	struct e1000_hw *hw = &adapter->hw;
+	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
 	u32 msg = E1000_VT_MSGTYPE_NACK;
 
 	/* if device isn't clear to send it shouldn't be reading either */
-	if (!adapter->vf_data[vf].clear_to_send)
+	if (!(vf_data->flags & IGB_VF_FLAG_CTS) &&
+	    time_after(jiffies, vf_data->last_nack + (2 * HZ))) {
 		igb_write_mbx(hw, &msg, 1, vf);
-}
-
-
-static void igb_msg_task(struct igb_adapter *adapter)
-{
-	struct e1000_hw *hw = &adapter->hw;
-	u32 vf;
-
-	for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
-		/* process any reset requests */
-		if (!igb_check_for_rst(hw, vf)) {
-			adapter->vf_data[vf].clear_to_send = false;
-			igb_vf_reset_event(adapter, vf);
-		}
-
-		/* process any messages pending */
-		if (!igb_check_for_msg(hw, vf))
-			igb_rcv_msg_from_vf(adapter, vf);
-
-		/* process any acks */
-		if (!igb_check_for_ack(hw, vf))
-			igb_rcv_ack_from_vf(adapter, vf);
-
+		vf_data->last_nack = jiffies;
 	}
 }
 
-static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
+static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
 {
-	u32 mbx_size = E1000_VFMAILBOX_SIZE;
-	u32 msgbuf[mbx_size];
+	struct pci_dev *pdev = adapter->pdev;
+	u32 msgbuf[E1000_VFMAILBOX_SIZE];
 	struct e1000_hw *hw = &adapter->hw;
+	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
 	s32 retval;
 
-	retval = igb_read_mbx(hw, msgbuf, mbx_size, vf);
+	retval = igb_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf);
 
-	if (retval)
-		dev_err(&adapter->pdev->dev,
-		        "Error receiving message from VF\n");
+	if (retval) {
+		/* if receive failed revoke VF CTS stats and restart init */
+		dev_err(&pdev->dev, "Error receiving message from VF\n");
+		vf_data->flags &= ~IGB_VF_FLAG_CTS;
+		if (!time_after(jiffies, vf_data->last_nack + (2 * HZ)))
+			return;
+		goto out;
+	}
 
 	/* this is a message we already processed, do nothing */
 	if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
-		return retval;
+		return;
 
 	/*
 	 * until the vf completes a reset it should not be
@@ -4230,20 +4613,23 @@ static int igb_rcv_msg_from_vf(struct ig
 
 	if (msgbuf[0] == E1000_VF_RESET) {
 		igb_vf_reset_msg(adapter, vf);
-
-		return retval;
+		return;
 	}
 
-	if (!adapter->vf_data[vf].clear_to_send) {
-		msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
-		igb_write_mbx(hw, msgbuf, 1, vf);
-		return retval;
+	if (!(vf_data->flags & IGB_VF_FLAG_CTS)) {
+		if (!time_after(jiffies, vf_data->last_nack + (2 * HZ)))
+			return;
+		retval = -1;
+		goto out;
 	}
 
 	switch ((msgbuf[0] & 0xFFFF)) {
 	case E1000_VF_SET_MAC_ADDR:
 		retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
 		break;
+	case E1000_VF_SET_PROMISC:
+		retval = igb_set_vf_promisc(adapter, msgbuf, vf);
+		break;
 	case E1000_VF_SET_MULTICAST:
 		retval = igb_set_vf_multicasts(adapter, msgbuf, vf);
 		break;
@@ -4254,22 +4640,67 @@ static int igb_rcv_msg_from_vf(struct ig
 		retval = igb_set_vf_vlan(adapter, msgbuf, vf);
 		break;
 	default:
-		dev_err(&adapter->pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
+		dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
 		retval = -1;
 		break;
 	}
 
+	msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
+out:
 	/* notify the VF of the results of what it sent us */
 	if (retval)
 		msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
 	else
 		msgbuf[0] |= E1000_VT_MSGTYPE_ACK;
 
-	msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
-
 	igb_write_mbx(hw, msgbuf, 1, vf);
+}
 
-	return retval;
+static void igb_msg_task(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 vf;
+
+	for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
+		/* process any reset requests */
+		if (!igb_check_for_rst(hw, vf))
+			igb_vf_reset_event(adapter, vf);
+
+		/* process any messages pending */
+		if (!igb_check_for_msg(hw, vf))
+			igb_rcv_msg_from_vf(adapter, vf);
+
+		/* process any acks */
+		if (!igb_check_for_ack(hw, vf))
+			igb_rcv_ack_from_vf(adapter, vf);
+	}
+}
+
+/**
+ *  igb_set_uta - Set unicast filter table address
+ *  @adapter: board private structure
+ *
+ *  The unicast table address is a register array of 32-bit registers.
+ *  The table is meant to be used in a way similar to how the MTA is used
+ *  however due to certain limitations in the hardware it is necessary to
+ *  set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscous
+ *  enable bit to allow vlan tag stripping when promiscous mode is enabled
+ **/
+static void igb_set_uta(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	int i;
+
+	/* The UTA table only exists on 82576 hardware and newer */
+	if (hw->mac.type < e1000_82576)
+		return;
+
+	/* we only need to do this if VMDq is enabled */
+	if (!adapter->vfs_allocated_count)
+		return;
+
+	for (i = 0; i < hw->mac.uta_reg_count; i++)
+		array_wr32(E1000_UTA, i, ~0);
 }
 
 /**
@@ -4279,15 +4710,15 @@ static int igb_rcv_msg_from_vf(struct ig
  **/
 static irqreturn_t igb_intr_msi(int irq, void *data)
 {
-	struct net_device *netdev = data;
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct igb_adapter *adapter = data;
+	struct igb_q_vector *q_vector = adapter->q_vector[0];
 	struct e1000_hw *hw = &adapter->hw;
 	/* read ICR disables interrupts using IAM */
 	u32 icr = rd32(E1000_ICR);
 
-	igb_write_itr(adapter->rx_ring);
+	igb_write_itr(q_vector);
 
-	if(icr & E1000_ICR_DOUTSYNC) {
+	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
 	}
@@ -4298,7 +4729,7 @@ static irqreturn_t igb_intr_msi(int irq,
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	napi_schedule(&adapter->rx_ring[0].napi);
+	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -4310,8 +4741,8 @@ static irqreturn_t igb_intr_msi(int irq,
  **/
 static irqreturn_t igb_intr(int irq, void *data)
 {
-	struct net_device *netdev = data;
-	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct igb_adapter *adapter = data;
+	struct igb_q_vector *q_vector = adapter->q_vector[0];
 	struct e1000_hw *hw = &adapter->hw;
 	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
 	 * need for the IMC write */
@@ -4319,14 +4750,14 @@ static irqreturn_t igb_intr(int irq, voi
 	if (!icr)
 		return IRQ_NONE;  /* Not our interrupt */
 
-	igb_write_itr(adapter->rx_ring);
+	igb_write_itr(q_vector);
 
 	/* 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 */
 	if (!(icr & E1000_ICR_INT_ASSERTED))
 		return IRQ_NONE;
 
-	if(icr & E1000_ICR_DOUTSYNC) {
+	if (icr & E1000_ICR_DOUTSYNC) {
 		/* HW is reporting DMA is out of sync */
 		adapter->stats.doosync++;
 	}
@@ -4338,26 +4769,27 @@ static irqreturn_t igb_intr(int irq, voi
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	napi_schedule(&adapter->rx_ring[0].napi);
+	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
 
-static inline void igb_rx_irq_enable(struct igb_ring *rx_ring)
+static inline void igb_ring_irq_enable(struct igb_q_vector *q_vector)
 {
-	struct igb_adapter *adapter = rx_ring->adapter;
+	struct igb_adapter *adapter = q_vector->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 
-	if (adapter->itr_setting & 3) {
-		if (adapter->num_rx_queues == 1)
+	if ((q_vector->rx_ring && (adapter->rx_itr_setting & 3)) ||
+	    (!q_vector->rx_ring && (adapter->tx_itr_setting & 3))) {
+		if (!adapter->msix_entries)
 			igb_set_itr(adapter);
 		else
-			igb_update_ring_itr(rx_ring);
+			igb_update_ring_itr(q_vector);
 	}
 
 	if (!test_bit(__IGB_DOWN, &adapter->state)) {
 		if (adapter->msix_entries)
-			wr32(E1000_EIMS, rx_ring->eims_value);
+			wr32(E1000_EIMS, q_vector->eims_value);
 		else
 			igb_irq_enable(adapter);
 	}
@@ -4370,76 +4802,101 @@ static inline void igb_rx_irq_enable(str
  **/
 static int igb_poll(struct napi_struct *napi, int budget)
 {
-	struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
-	int work_done = 0;
+	struct igb_q_vector *q_vector = container_of(napi,
+	                                             struct igb_q_vector,
+	                                             napi);
+	int tx_clean_complete = 1, work_done = 0;
 
 #ifdef CONFIG_IGB_DCA
-	if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_rx_dca(rx_ring);
+	if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
+		igb_update_dca(q_vector);
 #endif
-	igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
+	if (q_vector->tx_ring)
+		tx_clean_complete = igb_clean_tx_irq(q_vector);
 
-	if (rx_ring->buddy) {
-#ifdef CONFIG_IGB_DCA
-		if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
-			igb_update_tx_dca(rx_ring->buddy);
-#endif
-		if (!igb_clean_tx_irq(rx_ring->buddy))
-			work_done = budget;
-	}
+	if (q_vector->rx_ring)
+		igb_clean_rx_irq_adv(q_vector, &work_done, budget);
+
+	if (!tx_clean_complete)
+		work_done = budget;
 
 	/* If not enough Rx work done, exit the polling mode */
 	if (work_done < budget) {
 		napi_complete(napi);
-		igb_rx_irq_enable(rx_ring);
+		igb_ring_irq_enable(q_vector);
 	}
 
 	return work_done;
 }
 
 /**
- * igb_hwtstamp - utility function which checks for TX time stamp
+ * igb_systim_to_hwtstamp - convert system time value to hw timestamp
  * @adapter: board private structure
+ * @shhwtstamps: timestamp structure to update
+ * @regval: unsigned 64bit system time value.
+ *
+ * We need to convert the system time value stored in the RX/TXSTMP registers
+ * into a hwtstamp which can be used by the upper level timestamping functions
+ */
+static void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
+                                   struct skb_shared_hwtstamps *shhwtstamps,
+                                   u64 regval)
+{
+	u64 ns;
+
+	/*
+	 * The 82580 starts with 1ns at bit 0 in RX/TXSTMPL, shift this up to
+	 * 24 to match clock shift we setup earlier.
+	 */
+	if (adapter->hw.mac.type == e1000_82580)
+		regval <<= IGB_82580_TSYNC_SHIFT;
+
+	ns = timecounter_cyc2time(&adapter->clock, regval);
+	timecompare_update(&adapter->compare, ns);
+	memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+	shhwtstamps->hwtstamp = ns_to_ktime(ns);
+	shhwtstamps->syststamp = timecompare_transform(&adapter->compare, ns);
+}
+
+/**
+ * igb_tx_hwtstamp - utility function which checks for TX time stamp
+ * @q_vector: pointer to q_vector containing needed info
  * @skb: packet that was just sent
  *
  * If we were asked to do hardware stamping and such a time stamp is
  * available, then it must have been for this skb here because we only
  * allow only one such packet into the queue.
  */
-static void igb_tx_hwtstamp(struct igb_adapter *adapter, struct sk_buff *skb)
+static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
 {
+	struct igb_adapter *adapter = q_vector->adapter;
 	union skb_shared_tx *shtx = skb_tx(skb);
 	struct e1000_hw *hw = &adapter->hw;
+	struct skb_shared_hwtstamps shhwtstamps;
+	u64 regval;
 
-	if (unlikely(shtx->hardware)) {
-		u32 valid = rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID;
-		if (valid) {
-			u64 regval = rd32(E1000_TXSTMPL);
-			u64 ns;
-			struct skb_shared_hwtstamps shhwtstamps;
+	/* if skb does not support hw timestamp or TX stamp not valid exit */
+	if (likely(!shtx->hardware) ||
+	    !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
+		return;
 
-			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
-			regval |= (u64)rd32(E1000_TXSTMPH) << 32;
-			ns = timecounter_cyc2time(&adapter->clock,
-						  regval);
-			timecompare_update(&adapter->compare, ns);
-			shhwtstamps.hwtstamp = ns_to_ktime(ns);
-			shhwtstamps.syststamp =
-				timecompare_transform(&adapter->compare, ns);
-			skb_tstamp_tx(skb, &shhwtstamps);
-		}
-	}
+	regval = rd32(E1000_TXSTMPL);
+	regval |= (u64)rd32(E1000_TXSTMPH) << 32;
+
+	igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
+	skb_tstamp_tx(skb, &shhwtstamps);
 }
 
 /**
  * igb_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
+ * @q_vector: pointer to q_vector containing needed info
  * returns true if ring is completely cleaned
  **/
-static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
+static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
 {
-	struct igb_adapter *adapter = tx_ring->adapter;
-	struct net_device *netdev = adapter->netdev;
+	struct igb_adapter *adapter = q_vector->adapter;
+	struct igb_ring *tx_ring = q_vector->tx_ring;
+	struct net_device *netdev = tx_ring->netdev;
 	struct e1000_hw *hw = &adapter->hw;
 	struct igb_buffer *buffer_info;
 	struct sk_buff *skb;
@@ -4470,10 +4927,10 @@ static bool igb_clean_tx_irq(struct igb_
 				total_packets += segs;
 				total_bytes += bytecount;
 
-				igb_tx_hwtstamp(adapter, skb);
+				igb_tx_hwtstamp(q_vector, skb);
 			}
 
-			igb_unmap_and_free_tx_resource(adapter, buffer_info);
+			igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
 			tx_desc->wb.status = 0;
 
 			i++;
@@ -4496,7 +4953,7 @@ static bool igb_clean_tx_irq(struct igb_
 		if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
 		    !(test_bit(__IGB_DOWN, &adapter->state))) {
 			netif_wake_subqueue(netdev, tx_ring->queue_index);
-			++adapter->restart_queue;
+			tx_ring->tx_stats.restart_queue++;
 		}
 	}
 
@@ -4506,12 +4963,11 @@ static bool igb_clean_tx_irq(struct igb_
 		tx_ring->detect_tx_hung = false;
 		if (tx_ring->buffer_info[i].time_stamp &&
 		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
-			       (adapter->tx_timeout_factor * HZ))
-		    && !(rd32(E1000_STATUS) &
-			 E1000_STATUS_TXOFF)) {
+			       (adapter->tx_timeout_factor * HZ)) &&
+		    !(rd32(E1000_STATUS) & E1000_STATUS_TXOFF)) {
 
 			/* detected Tx unit hang */
-			dev_err(&adapter->pdev->dev,
+			dev_err(&tx_ring->pdev->dev,
 				"Detected Tx Unit Hang\n"
 				"  Tx Queue             <%d>\n"
 				"  TDH                  <%x>\n"
@@ -4524,11 +4980,11 @@ static bool igb_clean_tx_irq(struct igb_
 				"  jiffies              <%lx>\n"
 				"  desc.status          <%x>\n",
 				tx_ring->queue_index,
-				readl(adapter->hw.hw_addr + tx_ring->head),
-				readl(adapter->hw.hw_addr + tx_ring->tail),
+				readl(tx_ring->head),
+				readl(tx_ring->tail),
 				tx_ring->next_to_use,
 				tx_ring->next_to_clean,
-				tx_ring->buffer_info[i].time_stamp,
+				tx_ring->buffer_info[eop].time_stamp,
 				eop,
 				jiffies,
 				eop_desc->wb.status);
@@ -4539,43 +4995,38 @@ static bool igb_clean_tx_irq(struct igb_
 	tx_ring->total_packets += total_packets;
 	tx_ring->tx_stats.bytes += total_bytes;
 	tx_ring->tx_stats.packets += total_packets;
-	adapter->net_stats.tx_bytes += total_bytes;
-	adapter->net_stats.tx_packets += total_packets;
 	return (count < tx_ring->count);
 }
 
 /**
  * igb_receive_skb - helper function to handle rx indications
- * @ring: pointer to receive ring receving this packet
- * @status: descriptor status field as written by hardware
- * @rx_desc: receive descriptor containing vlan and type information.
- * @skb: pointer to sk_buff to be indicated to stack
+ * @q_vector: structure containing interrupt and ring information
+ * @skb: packet to send up
+ * @vlan_tag: vlan tag for packet
  **/
-static void igb_receive_skb(struct igb_ring *ring, u8 status,
-                            union e1000_adv_rx_desc * rx_desc,
-                            struct sk_buff *skb)
+static void igb_receive_skb(struct igb_q_vector *q_vector,
+                            struct sk_buff *skb,
+                            u16 vlan_tag)
 {
-	struct igb_adapter * adapter = ring->adapter;
-	bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
+	struct igb_adapter *adapter = q_vector->adapter;
 
-	skb_record_rx_queue(skb, ring->queue_index);
-	if (vlan_extracted)
-		vlan_gro_receive(&ring->napi, adapter->vlgrp,
-		                 le16_to_cpu(rx_desc->wb.upper.vlan),
-		                 skb);
+	if (vlan_tag)
+		vlan_gro_receive(&q_vector->napi, adapter->vlgrp,
+		                 vlan_tag, skb);
 	else
-		napi_gro_receive(&ring->napi, skb);
+		napi_gro_receive(&q_vector->napi, skb);
 }
 
-static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
+static inline void igb_rx_checksum_adv(struct igb_ring *ring,
 				       u32 status_err, struct sk_buff *skb)
 {
 	skb->ip_summed = CHECKSUM_NONE;
 
 	/* Ignore Checksum bit is set or checksum is disabled through ethtool */
-	if ((status_err & E1000_RXD_STAT_IXSM) ||
-	    (adapter->flags & IGB_FLAG_RX_CSUM_DISABLED))
+	if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) ||
+	     (status_err & E1000_RXD_STAT_IXSM))
 		return;
+
 	/* TCP/UDP checksum error bit is set */
 	if (status_err &
 	    (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
@@ -4584,9 +5035,10 @@ static inline void igb_rx_checksum_adv(s
 		 * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
 		 * packets, (aka let the stack check the crc32c)
 		 */
-		if (!((adapter->hw.mac.type == e1000_82576) &&
-		      (skb->len == 60)))
-			adapter->hw_csum_err++;
+		if ((skb->len == 60) &&
+		    (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM))
+			ring->rx_stats.csum_err++;
+
 		/* let the stack verify checksum errors */
 		return;
 	}
@@ -4594,11 +5046,38 @@ static inline void igb_rx_checksum_adv(s
 	if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err);
-	adapter->hw_csum_good++;
+	dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err);
 }
 
-static inline u16 igb_get_hlen(struct igb_adapter *adapter,
+static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
+                                   struct sk_buff *skb)
+{
+	struct igb_adapter *adapter = q_vector->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+	u64 regval;
+
+	/*
+	 * If this bit is set, then the RX registers contain the time stamp. No
+	 * other packet will be time stamped until we read these registers, so
+	 * read the registers to make them available again. Because only one
+	 * packet can be time stamped at a time, we know that the register
+	 * values must belong to this one here and therefore we don't need to
+	 * compare any of the additional attributes stored for it.
+	 *
+	 * If nothing went wrong, then it should have a skb_shared_tx that we
+	 * can turn into a skb_shared_hwtstamps.
+	 */
+	if (likely(!(staterr & E1000_RXDADV_STAT_TS)))
+		return;
+	if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
+		return;
+
+	regval = rd32(E1000_RXSTMPL);
+	regval |= (u64)rd32(E1000_RXSTMPH) << 32;
+
+	igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
+}
+static inline u16 igb_get_hlen(struct igb_ring *rx_ring,
                                union e1000_adv_rx_desc *rx_desc)
 {
 	/* HW will not DMA in data larger than the given buffer, even if it
@@ -4607,27 +5086,28 @@ static inline u16 igb_get_hlen(struct ig
 	 */
 	u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
 	           E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
-	if (hlen > adapter->rx_ps_hdr_size)
-		hlen = adapter->rx_ps_hdr_size;
+	if (hlen > rx_ring->rx_buffer_len)
+		hlen = rx_ring->rx_buffer_len;
 	return hlen;
 }
 
-static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
-				 int *work_done, int budget)
+static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
+                                 int *work_done, int budget)
 {
-	struct igb_adapter *adapter = rx_ring->adapter;
-	struct net_device *netdev = adapter->netdev;
-	struct e1000_hw *hw = &adapter->hw;
-	struct pci_dev *pdev = adapter->pdev;
+	struct igb_ring *rx_ring = q_vector->rx_ring;
+	struct net_device *netdev = rx_ring->netdev;
+	struct pci_dev *pdev = rx_ring->pdev;
 	union e1000_adv_rx_desc *rx_desc , *next_rxd;
 	struct igb_buffer *buffer_info , *next_buffer;
 	struct sk_buff *skb;
 	bool cleaned = false;
 	int cleaned_count = 0;
+	int current_node = numa_node_id();
 	unsigned int total_bytes = 0, total_packets = 0;
 	unsigned int i;
 	u32 staterr;
 	u16 length;
+	u16 vlan_tag;
 
 	i = rx_ring->next_to_clean;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -4646,6 +5126,7 @@ static bool igb_clean_rx_irq_adv(struct
 		i++;
 		if (i == rx_ring->count)
 			i = 0;
+
 		next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
 		prefetch(next_rxd);
 		next_buffer = &rx_ring->buffer_info[i];
@@ -4654,23 +5135,16 @@ static bool igb_clean_rx_irq_adv(struct
 		cleaned = true;
 		cleaned_count++;
 
-		/* this is the fast path for the non-packet split case */
-		if (!adapter->rx_ps_hdr_size) {
-			pci_unmap_single(pdev, buffer_info->dma,
-					 adapter->rx_buffer_len,
-					 PCI_DMA_FROMDEVICE);
-			buffer_info->dma = 0;
-			skb_put(skb, length);
-			goto send_up;
-		}
-
 		if (buffer_info->dma) {
-			u16 hlen = igb_get_hlen(adapter, rx_desc);
 			pci_unmap_single(pdev, buffer_info->dma,
-					 adapter->rx_ps_hdr_size,
+					 rx_ring->rx_buffer_len,
 					 PCI_DMA_FROMDEVICE);
 			buffer_info->dma = 0;
-			skb_put(skb, hlen);
+			if (rx_ring->rx_buffer_len >= IGB_RXBUFFER_1024) {
+				skb_put(skb, length);
+				goto send_up;
+			}
+			skb_put(skb, igb_get_hlen(rx_ring, rx_desc));
 		}
 
 		if (length) {
@@ -4683,15 +5157,14 @@ static bool igb_clean_rx_irq_adv(struct
 						buffer_info->page_offset,
 						length);
 
-			if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
-			    (page_count(buffer_info->page) != 1))
+			if ((page_count(buffer_info->page) != 1) ||
+			    (page_to_nid(buffer_info->page) != current_node))
 				buffer_info->page = NULL;
 			else
 				get_page(buffer_info->page);
 
 			skb->len += length;
 			skb->data_len += length;
-
 			skb->truesize += length;
 		}
 
@@ -4703,60 +5176,24 @@ static bool igb_clean_rx_irq_adv(struct
 			goto next_desc;
 		}
 send_up:
-		/*
-		 * If this bit is set, then the RX registers contain
-		 * the time stamp. No other packet will be time
-		 * stamped until we read these registers, so read the
-		 * registers to make them available again. Because
-		 * only one packet can be time stamped at a time, we
-		 * know that the register values must belong to this
-		 * one here and therefore we don't need to compare
-		 * any of the additional attributes stored for it.
-		 *
-		 * If nothing went wrong, then it should have a
-		 * skb_shared_tx that we can turn into a
-		 * skb_shared_hwtstamps.
-		 *
-		 * TODO: can time stamping be triggered (thus locking
-		 * the registers) without the packet reaching this point
-		 * here? In that case RX time stamping would get stuck.
-		 *
-		 * TODO: in "time stamp all packets" mode this bit is
-		 * not set. Need a global flag for this mode and then
-		 * always read the registers. Cannot be done without
-		 * a race condition.
-		 */
-		if (unlikely(staterr & E1000_RXD_STAT_TS)) {
-			u64 regval;
-			u64 ns;
-			struct skb_shared_hwtstamps *shhwtstamps =
-				skb_hwtstamps(skb);
-
-			WARN(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID),
-			     "igb: no RX time stamp available for time stamped packet");
-			regval = rd32(E1000_RXSTMPL);
-			regval |= (u64)rd32(E1000_RXSTMPH) << 32;
-			ns = timecounter_cyc2time(&adapter->clock, regval);
-			timecompare_update(&adapter->compare, ns);
-			memset(shhwtstamps, 0, sizeof(*shhwtstamps));
-			shhwtstamps->hwtstamp = ns_to_ktime(ns);
-			shhwtstamps->syststamp =
-				timecompare_transform(&adapter->compare, ns);
-		}
-
 		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
 
+		igb_rx_hwtstamp(q_vector, staterr, skb);
 		total_bytes += skb->len;
 		total_packets++;
 
-		igb_rx_checksum_adv(adapter, staterr, skb);
+		igb_rx_checksum_adv(rx_ring, staterr, skb);
 
 		skb->protocol = eth_type_trans(skb, netdev);
+		skb_record_rx_queue(skb, rx_ring->queue_index);
 
-		igb_receive_skb(rx_ring, staterr, rx_desc, skb);
+		vlan_tag = ((staterr & E1000_RXD_STAT_VP) ?
+		            le16_to_cpu(rx_desc->wb.upper.vlan) : 0);
+
+		igb_receive_skb(q_vector, skb, vlan_tag);
 
 next_desc:
 		rx_desc->wb.upper.status_error = 0;
@@ -4783,8 +5220,6 @@ next_desc:
 	rx_ring->total_bytes += total_bytes;
 	rx_ring->rx_stats.packets += total_packets;
 	rx_ring->rx_stats.bytes += total_bytes;
-	adapter->net_stats.rx_bytes += total_bytes;
-	adapter->net_stats.rx_packets += total_packets;
 	return cleaned;
 }
 
@@ -4792,12 +5227,9 @@ next_desc:
  * igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
  * @adapter: address of board private structure
  **/
-static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
-				     int cleaned_count)
+void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
 {
-	struct igb_adapter *adapter = rx_ring->adapter;
-	struct net_device *netdev = adapter->netdev;
-	struct pci_dev *pdev = adapter->pdev;
+	struct net_device *netdev = rx_ring->netdev;
 	union e1000_adv_rx_desc *rx_desc;
 	struct igb_buffer *buffer_info;
 	struct sk_buff *skb;
@@ -4807,19 +5239,16 @@ static void igb_alloc_rx_buffers_adv(str
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
 
-	if (adapter->rx_ps_hdr_size)
-		bufsz = adapter->rx_ps_hdr_size;
-	else
-		bufsz = adapter->rx_buffer_len;
+	bufsz = rx_ring->rx_buffer_len;
 
 	while (cleaned_count--) {
 		rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
 
-		if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
+		if ((bufsz < IGB_RXBUFFER_1024) && !buffer_info->page_dma) {
 			if (!buffer_info->page) {
-				buffer_info->page = alloc_page(GFP_ATOMIC);
+				buffer_info->page = netdev_alloc_page(netdev);
 				if (!buffer_info->page) {
-					adapter->alloc_rx_buff_failed++;
+					rx_ring->rx_stats.alloc_failed++;
 					goto no_buffers;
 				}
 				buffer_info->page_offset = 0;
@@ -4827,39 +5256,48 @@ static void igb_alloc_rx_buffers_adv(str
 				buffer_info->page_offset ^= PAGE_SIZE / 2;
 			}
 			buffer_info->page_dma =
-				pci_map_page(pdev, buffer_info->page,
+				pci_map_page(rx_ring->pdev, buffer_info->page,
 					     buffer_info->page_offset,
 					     PAGE_SIZE / 2,
 					     PCI_DMA_FROMDEVICE);
+			if (pci_dma_mapping_error(rx_ring->pdev,
+			                          buffer_info->page_dma)) {
+				buffer_info->page_dma = 0;
+				rx_ring->rx_stats.alloc_failed++;
+				goto no_buffers;
+			}
 		}
 
-		if (!buffer_info->skb) {
-			skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN);
+		skb = buffer_info->skb;
+		if (!skb) {
+			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 			if (!skb) {
-				adapter->alloc_rx_buff_failed++;
+				rx_ring->rx_stats.alloc_failed++;
 				goto no_buffers;
 			}
 
-			/* Make buffer alignment 2 beyond a 16 byte boundary
-			 * this will result in a 16 byte aligned IP header after
-			 * the 14 byte MAC header is removed
-			 */
-			skb_reserve(skb, NET_IP_ALIGN);
-
 			buffer_info->skb = skb;
-			buffer_info->dma = pci_map_single(pdev, skb->data,
+		}
+		if (!buffer_info->dma) {
+			buffer_info->dma = pci_map_single(rx_ring->pdev,
+			                                  skb->data,
 							  bufsz,
 							  PCI_DMA_FROMDEVICE);
+			if (pci_dma_mapping_error(rx_ring->pdev,
+			                          buffer_info->dma)) {
+				buffer_info->dma = 0;
+				rx_ring->rx_stats.alloc_failed++;
+				goto no_buffers;
+			}
 		}
 		/* Refresh the desc even if buffer_addrs didn't change because
 		 * each write-back erases this info. */
-		if (adapter->rx_ps_hdr_size) {
+		if (bufsz < IGB_RXBUFFER_1024) {
 			rx_desc->read.pkt_addr =
 			     cpu_to_le64(buffer_info->page_dma);
 			rx_desc->read.hdr_addr = cpu_to_le64(buffer_info->dma);
 		} else {
-			rx_desc->read.pkt_addr =
-			     cpu_to_le64(buffer_info->dma);
+			rx_desc->read.pkt_addr = cpu_to_le64(buffer_info->dma);
 			rx_desc->read.hdr_addr = 0;
 		}
 
@@ -4882,7 +5320,7 @@ no_buffers:
 		 * applicable for weak-ordered memory model archs,
 		 * such as IA-64). */
 		wmb();
-		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+		writel(i, rx_ring->tail);
 	}
 }
 
@@ -4941,13 +5379,11 @@ static int igb_hwtstamp_ioctl(struct net
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct hwtstamp_config config;
-	u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
-	u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED;
-	u32 tsync_rx_ctl_type = 0;
+	u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
+	u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
 	u32 tsync_rx_cfg = 0;
-	int is_l4 = 0;
-	int is_l2 = 0;
-	short port = 319; /* PTP */
+	bool is_l4 = false;
+	bool is_l2 = false;
 	u32 regval;
 
 	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
@@ -4959,10 +5395,8 @@ static int igb_hwtstamp_ioctl(struct net
 
 	switch (config.tx_type) {
 	case HWTSTAMP_TX_OFF:
-		tsync_tx_ctl_bit = 0;
-		break;
+		tsync_tx_ctl = 0;
 	case HWTSTAMP_TX_ON:
-		tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
 		break;
 	default:
 		return -ERANGE;
@@ -4970,7 +5404,7 @@ static int igb_hwtstamp_ioctl(struct net
 
 	switch (config.rx_filter) {
 	case HWTSTAMP_FILTER_NONE:
-		tsync_rx_ctl_bit = 0;
+		tsync_rx_ctl = 0;
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
@@ -4981,86 +5415,97 @@ static int igb_hwtstamp_ioctl(struct net
 		 * possible to time stamp both Sync and Delay_Req messages
 		 * => fall back to time stamping all packets
 		 */
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
 		config.rx_filter = HWTSTAMP_FILTER_ALL;
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
-		is_l4 = 1;
+		is_l4 = true;
 		break;
 	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
 		tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
-		is_l4 = 1;
+		is_l4 = true;
 		break;
 	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
 	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
 		tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
-		is_l2 = 1;
-		is_l4 = 1;
+		is_l2 = true;
+		is_l4 = true;
 		config.rx_filter = HWTSTAMP_FILTER_SOME;
 		break;
 	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
 	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
 		tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
-		is_l2 = 1;
-		is_l4 = 1;
+		is_l2 = true;
+		is_l4 = true;
 		config.rx_filter = HWTSTAMP_FILTER_SOME;
 		break;
 	case HWTSTAMP_FILTER_PTP_V2_EVENT:
 	case HWTSTAMP_FILTER_PTP_V2_SYNC:
 	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2;
+		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
 		config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
-		is_l2 = 1;
+		is_l2 = true;
 		break;
 	default:
 		return -ERANGE;
 	}
 
+	if (hw->mac.type == e1000_82575) {
+		if (tsync_rx_ctl | tsync_tx_ctl)
+			return -EINVAL;
+		return 0;
+	}
+
 	/* enable/disable TX */
 	regval = rd32(E1000_TSYNCTXCTL);
-	regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
+	regval &= ~E1000_TSYNCTXCTL_ENABLED;
+	regval |= tsync_tx_ctl;
 	wr32(E1000_TSYNCTXCTL, regval);
 
-	/* enable/disable RX, define which PTP packets are time stamped */
+	/* enable/disable RX */
 	regval = rd32(E1000_TSYNCRXCTL);
-	regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
-	regval = (regval & ~0xE) | tsync_rx_ctl_type;
+	regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
+	regval |= tsync_rx_ctl;
 	wr32(E1000_TSYNCRXCTL, regval);
+
+	/* define which PTP packets are time stamped */
 	wr32(E1000_TSYNCRXCFG, tsync_rx_cfg);
 
-	/*
-	 * Ethertype Filter Queue Filter[0][15:0] = 0x88F7
-	 *                                          (Ethertype to filter on)
-	 * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter)
-	 * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping)
-	 */
-	wr32(E1000_ETQF0, is_l2 ? 0x440088f7 : 0);
+	/* define ethertype filter for timestamped packets */
+	if (is_l2)
+		wr32(E1000_ETQF(3),
+		                (E1000_ETQF_FILTER_ENABLE | /* enable filter */
+		                 E1000_ETQF_1588 | /* enable timestamping */
+		                 ETH_P_1588));     /* 1588 eth protocol type */
+	else
+		wr32(E1000_ETQF(3), 0);
 
-	/* L4 Queue Filter[0]: only filter by source and destination port */
-	wr32(E1000_SPQF0, htons(port));
-	wr32(E1000_IMIREXT(0), is_l4 ?
-	     ((1<<12) | (1<<19) /* bypass size and control flags */) : 0);
-	wr32(E1000_IMIR(0), is_l4 ?
-	     (htons(port)
-	      | (0<<16) /* immediate interrupt disabled */
-	      | 0 /* (1<<17) bit cleared: do not bypass
-		     destination port check */)
-		: 0);
-	wr32(E1000_FTQF0, is_l4 ?
-	     (0x11 /* UDP */
-	      | (1<<15) /* VF not compared */
-	      | (1<<27) /* Enable Timestamping */
-	      | (7<<28) /* only source port filter enabled,
-			   source/target address and protocol
-			   masked */)
-	     : ((1<<15) | (15<<28) /* all mask bits set = filter not
-				      enabled */));
+#define PTP_PORT 319
+	/* L4 Queue Filter[3]: filter by destination port and protocol */
+	if (is_l4) {
+		u32 ftqf = (IPPROTO_UDP /* UDP */
+			| E1000_FTQF_VF_BP /* VF not compared */
+			| E1000_FTQF_1588_TIME_STAMP /* Enable Timestamping */
+			| E1000_FTQF_MASK); /* mask all inputs */
+		ftqf &= ~E1000_FTQF_MASK_PROTO_BP; /* enable protocol check */
 
+		wr32(E1000_IMIR(3), htons(PTP_PORT));
+		wr32(E1000_IMIREXT(3),
+		     (E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_BP));
+		if (hw->mac.type == e1000_82576) {
+			/* enable source port check */
+			wr32(E1000_SPQF(3), htons(PTP_PORT));
+			ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+		}
+		wr32(E1000_FTQF(3), ftqf);
+	} else {
+		wr32(E1000_FTQF(3), E1000_FTQF_MASK);
+	}
 	wrfl();
 
 	adapter->hwtstamp_config = config;
@@ -5137,21 +5582,15 @@ static void igb_vlan_rx_register(struct
 		ctrl |= E1000_CTRL_VME;
 		wr32(E1000_CTRL, ctrl);
 
-		/* enable VLAN receive filtering */
+		/* Disable CFI check */
 		rctl = rd32(E1000_RCTL);
 		rctl &= ~E1000_RCTL_CFIEN;
 		wr32(E1000_RCTL, rctl);
-		igb_update_mng_vlan(adapter);
 	} else {
 		/* disable VLAN tag insert/strip */
 		ctrl = rd32(E1000_CTRL);
 		ctrl &= ~E1000_CTRL_VME;
 		wr32(E1000_CTRL, ctrl);
-
-		if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) {
-			igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
-			adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
-		}
 	}
 
 	igb_rlpml_set(adapter);
@@ -5166,16 +5605,11 @@ static void igb_vlan_rx_add_vid(struct n
 	struct e1000_hw *hw = &adapter->hw;
 	int pf_id = adapter->vfs_allocated_count;
 
-	if ((hw->mng_cookie.status &
-	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
-	    (vid == adapter->mng_vlan_id))
-		return;
-
-	/* add vid to vlvf if sr-iov is enabled,
-	 * if that fails add directly to filter table */
-	if (igb_vlvf_set(adapter, vid, true, pf_id))
-		igb_vfta_set(hw, vid, true);
+	/* attempt to add filter to vlvf array */
+	igb_vlvf_set(adapter, vid, true, pf_id);
 
+	/* add the filter since PF can receive vlans w/o entry in vlvf */
+	igb_vfta_set(hw, vid, true);
 }
 
 static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -5183,6 +5617,7 @@ static void igb_vlan_rx_kill_vid(struct
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	int pf_id = adapter->vfs_allocated_count;
+	s32 err;
 
 	igb_irq_disable(adapter);
 	vlan_group_set_device(adapter->vlgrp, vid, NULL);
@@ -5190,17 +5625,11 @@ static void igb_vlan_rx_kill_vid(struct
 	if (!test_bit(__IGB_DOWN, &adapter->state))
 		igb_irq_enable(adapter);
 
-	if ((adapter->hw.mng_cookie.status &
-	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
-	    (vid == adapter->mng_vlan_id)) {
-		/* release control to f/w */
-		igb_release_hw_control(adapter);
-		return;
-	}
+	/* remove vlan from VLVF table array */
+	err = igb_vlvf_set(adapter, vid, false, pf_id);
 
-	/* remove vid from vlvf if sr-iov is enabled,
-	 * if not in vlvf remove from vfta */
-	if (igb_vlvf_set(adapter, vid, false, pf_id))
+	/* if vid was not present in VLVF just remove it from table */
+	if (err)
 		igb_vfta_set(hw, vid, false);
 }
 
@@ -5220,6 +5649,7 @@ static void igb_restore_vlan(struct igb_
 
 int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 
 	mac->autoneg = 0;
@@ -5243,8 +5673,7 @@ int igb_set_spd_dplx(struct igb_adapter
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		dev_err(&adapter->pdev->dev,
-			"Unsupported Speed/Duplex configuration\n");
+		dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -5266,9 +5695,7 @@ static int __igb_shutdown(struct pci_dev
 	if (netif_running(netdev))
 		igb_close(netdev);
 
-	igb_reset_interrupt_capability(adapter);
-
-	igb_free_queues(adapter);
+	igb_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_PM
 	retval = pci_save_state(pdev);
@@ -5300,7 +5727,7 @@ static int __igb_shutdown(struct pci_dev
 		wr32(E1000_CTRL, ctrl);
 
 		/* Allow time for pending master requests to run */
-		igb_disable_pcie_master(&adapter->hw);
+		igb_disable_pcie_master(hw);
 
 		wr32(E1000_WUC, E1000_WUC_PME_EN);
 		wr32(E1000_WUFC, wufc);
@@ -5363,9 +5790,7 @@ static int igb_resume(struct pci_dev *pd
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
-	igb_set_interrupt_capability(adapter);
-
-	if (igb_alloc_queues(adapter)) {
+	if (igb_init_interrupt_scheme(adapter)) {
 		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
 		return -ENOMEM;
 	}
@@ -5417,22 +5842,16 @@ static void igb_netpoll(struct net_devic
 	int i;
 
 	if (!adapter->msix_entries) {
+		struct igb_q_vector *q_vector = adapter->q_vector[0];
 		igb_irq_disable(adapter);
-		napi_schedule(&adapter->rx_ring[0].napi);
+		napi_schedule(&q_vector->napi);
 		return;
 	}
 
-	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *tx_ring = &adapter->tx_ring[i];
-		wr32(E1000_EIMC, tx_ring->eims_value);
-		igb_clean_tx_irq(tx_ring);
-		wr32(E1000_EIMS, tx_ring->eims_value);
-	}
-
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		struct igb_ring *rx_ring = &adapter->rx_ring[i];
-		wr32(E1000_EIMC, rx_ring->eims_value);
-		napi_schedule(&rx_ring->napi);
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		struct igb_q_vector *q_vector = adapter->q_vector[i];
+		wr32(E1000_EIMC, q_vector->eims_value);
+		napi_schedule(&q_vector->napi);
 	}
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -5532,6 +5951,33 @@ static void igb_io_resume(struct pci_dev
 	igb_get_hw_control(adapter);
 }
 
+static void igb_rar_set_qsel(struct igb_adapter *adapter, u8 *addr, u32 index,
+                             u8 qsel)
+{
+	u32 rar_low, rar_high;
+	struct e1000_hw *hw = &adapter->hw;
+
+	/* HW expects these in little endian so we reverse the byte order
+	 * from network order (big endian) to little endian
+	 */
+	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
+	          ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+
+	/* Indicate to hardware the Address is Valid. */
+	rar_high |= E1000_RAH_AV;
+
+	if (hw->mac.type == e1000_82575)
+		rar_high |= E1000_RAH_POOL_1 * qsel;
+	else
+		rar_high |= E1000_RAH_POOL_1 << qsel;
+
+	wr32(E1000_RAL(index), rar_low);
+	wrfl();
+	wr32(E1000_RAH(index), rar_high);
+	wrfl();
+}
+
 static int igb_set_vf_mac(struct igb_adapter *adapter,
                           int vf, unsigned char *mac_addr)
 {
@@ -5542,8 +5988,7 @@ static int igb_set_vf_mac(struct igb_ada
 
 	memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
 
-	igb_rar_set(hw, mac_addr, rar_entry);
-	igb_set_rah_pool(hw, vf, rar_entry);
+	igb_rar_set_qsel(adapter, mac_addr, rar_entry, vf);
 
 	return 0;
 }
@@ -5551,19 +5996,29 @@ static int igb_set_vf_mac(struct igb_ada
 static void igb_vmm_control(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	u32 reg_data;
+	u32 reg;
 
-	if (!adapter->vfs_allocated_count)
+	/* replication is not supported for 82575 */
+	if (hw->mac.type == e1000_82575)
 		return;
 
-	/* VF's need PF reset indication before they
-	 * can send/receive mail */
-	reg_data = rd32(E1000_CTRL_EXT);
-	reg_data |= E1000_CTRL_EXT_PFRSTD;
-	wr32(E1000_CTRL_EXT, reg_data);
+	/* enable replication vlan tag stripping */
+	reg = rd32(E1000_RPLOLR);
+	reg |= E1000_RPLOLR_STRVLAN;
+	wr32(E1000_RPLOLR, reg);
 
-	igb_vmdq_set_loopback_pf(hw, true);
-	igb_vmdq_set_replication_pf(hw, true);
+	/* notify HW that the MAC is adding vlan tags */
+	reg = rd32(E1000_DTXCTL);
+	reg |= E1000_DTXCTL_VLAN_ADDED;
+	wr32(E1000_DTXCTL, reg);
+
+	if (adapter->vfs_allocated_count) {
+		igb_vmdq_set_loopback_pf(hw, true);
+		igb_vmdq_set_replication_pf(hw, true);
+	} else {
+		igb_vmdq_set_loopback_pf(hw, false);
+		igb_vmdq_set_replication_pf(hw, false);
+	}
 }
 
 /* igb_main.c */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igbvf/ethtool.c linux-libre-2.6.33-gnu1/drivers/net/igbvf/ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/igbvf/ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igbvf/ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -367,16 +367,6 @@ static int igbvf_link_test(struct igbvf_
 	return *data;
 }
 
-static int igbvf_get_self_test_count(struct net_device *netdev)
-{
-	return IGBVF_TEST_LEN;
-}
-
-static int igbvf_get_stats_count(struct net_device *netdev)
-{
-	return IGBVF_GLOBAL_STATS_LEN;
-}
-
 static void igbvf_diag_test(struct net_device *netdev,
                             struct ethtool_test *eth_test, u64 *data)
 {
@@ -484,6 +474,18 @@ static void igbvf_get_ethtool_stats(stru
 
 }
 
+static int igbvf_get_sset_count(struct net_device *dev, int stringset)
+{
+	switch(stringset) {
+	case ETH_SS_TEST:
+		return IGBVF_TEST_LEN;
+	case ETH_SS_STATS:
+		return IGBVF_GLOBAL_STATS_LEN;
+	default:
+		return -EINVAL;
+	}
+}
+
 static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
                               u8 *data)
 {
@@ -532,11 +534,10 @@ static const struct ethtool_ops igbvf_et
 	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= igbvf_set_tso,
 	.self_test		= igbvf_diag_test,
+	.get_sset_count		= igbvf_get_sset_count,
 	.get_strings		= igbvf_get_strings,
 	.phys_id		= igbvf_phys_id,
 	.get_ethtool_stats	= igbvf_get_ethtool_stats,
-	.self_test_count	= igbvf_get_self_test_count,
-	.get_stats_count	= igbvf_get_stats_count,
 	.get_coalesce		= igbvf_get_coalesce,
 	.set_coalesce		= igbvf_set_coalesce,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igbvf/igbvf.h linux-libre-2.6.33-gnu1/drivers/net/igbvf/igbvf.h
--- linux-libre-2.6.32-gnu1/drivers/net/igbvf/igbvf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igbvf/igbvf.h	2010-02-24 13:52:17.000000000 -0500
@@ -117,6 +117,7 @@ struct igbvf_buffer {
 			unsigned long time_stamp;
 			u16 length;
 			u16 next_to_watch;
+			u16 mapped_as_page;
 		};
 		/* Rx */
 		struct {
@@ -275,6 +276,7 @@ struct igbvf_adapter {
 	unsigned long led_status;
 
 	unsigned int flags;
+	unsigned long last_reset;
 };
 
 struct igbvf_info {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/igbvf/netdev.c linux-libre-2.6.33-gnu1/drivers/net/igbvf/netdev.c
--- linux-libre-2.6.32-gnu1/drivers/net/igbvf/netdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/igbvf/netdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -170,18 +170,12 @@ static void igbvf_alloc_rx_buffers(struc
 		}
 
 		if (!buffer_info->skb) {
-			skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN);
+			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
 				goto no_buffers;
 			}
 
-			/* Make buffer alignment 2 beyond a 16 byte boundary
-			 * this will result in a 16 byte aligned IP header after
-			 * the 14 byte MAC header is removed
-			 */
-			skb_reserve(skb, NET_IP_ALIGN);
-
 			buffer_info->skb = skb;
 			buffer_info->dma = pci_map_single(pdev, skb->data,
 			                                  bufsz,
@@ -372,10 +366,20 @@ next_desc:
 static void igbvf_put_txbuf(struct igbvf_adapter *adapter,
                             struct igbvf_buffer *buffer_info)
 {
-	buffer_info->dma = 0;
+	if (buffer_info->dma) {
+		if (buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev,
+				       buffer_info->dma,
+				       buffer_info->length,
+				       PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev,
+					 buffer_info->dma,
+					 buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
 	if (buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
@@ -823,8 +827,8 @@ static bool igbvf_clean_tx_irq(struct ig
 		adapter->detect_tx_hung = false;
 		if (tx_ring->buffer_info[i].time_stamp &&
 		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
-		               (adapter->tx_timeout_factor * HZ))
-		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+		               (adapter->tx_timeout_factor * HZ)) &&
+		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 
 			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
 			/* detected Tx unit hang */
@@ -1049,7 +1053,7 @@ static int igbvf_request_msix(struct igb
 	}
 
 	err = request_irq(adapter->msix_entries[vector].vector,
-	                  &igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
+	                  igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
 	                  netdev);
 	if (err)
 		goto out;
@@ -1059,7 +1063,7 @@ static int igbvf_request_msix(struct igb
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
-	                  &igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
+	                  igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
 	                  netdev);
 	if (err)
 		goto out;
@@ -1069,7 +1073,7 @@ static int igbvf_request_msix(struct igb
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
-	                  &igbvf_msix_other, 0, netdev->name, netdev);
+	                  igbvf_msix_other, 0, netdev->name, netdev);
 	if (err)
 		goto out;
 
@@ -1465,6 +1469,8 @@ static void igbvf_reset(struct igbvf_ada
 		memcpy(netdev->perm_addr, adapter->hw.mac.addr,
 		       netdev->addr_len);
 	}
+
+	adapter->last_reset = jiffies;
 }
 
 int igbvf_up(struct igbvf_adapter *adapter)
@@ -1808,11 +1814,15 @@ static bool igbvf_has_link(struct igbvf_
 	s32 ret_val = E1000_SUCCESS;
 	bool link_active;
 
+	/* If interface is down, stay link down */
+	if (test_bit(__IGBVF_DOWN, &adapter->state))
+		return false;
+
 	ret_val = hw->mac.ops.check_for_link(hw);
 	link_active = !hw->mac.get_link_status;
 
 	/* if check for link returns error we will need to reset */
-	if (ret_val)
+	if (ret_val && time_after(jiffies, adapter->last_reset + (10 * HZ)))
 		schedule_work(&adapter->reset_task);
 
 	return link_active;
@@ -1953,7 +1963,7 @@ static int igbvf_tso(struct igbvf_adapte
 		                                         iph->daddr, 0,
 		                                         IPPROTO_TCP,
 		                                         0);
-	} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+	} else if (skb_is_gso_v6(skb)) {
 		ipv6_hdr(skb)->payload_len = 0;
 		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
 		                                       &ipv6_hdr(skb)->daddr,
@@ -2094,31 +2104,30 @@ static inline int igbvf_tx_map_adv(struc
                                    unsigned int first)
 {
 	struct igbvf_buffer *buffer_info;
+	struct pci_dev *pdev = adapter->pdev;
 	unsigned int len = skb_headlen(skb);
 	unsigned int count = 0, i;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-
 	buffer_info = &tx_ring->buffer_info[i];
 	BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
 	buffer_info->length = len;
 	/* set time_stamp *before* dma to help avoid a possible race */
 	buffer_info->time_stamp = jiffies;
 	buffer_info->next_to_watch = i;
-	buffer_info->dma = skb_shinfo(skb)->dma_head;
+	buffer_info->mapped_as_page = false;
+	buffer_info->dma = pci_map_single(pdev, skb->data, len,
+					  PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(pdev, buffer_info->dma))
+		goto dma_error;
+
 
 	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
+		count++;
 		i++;
 		if (i == tx_ring->count)
 			i = 0;
@@ -2131,14 +2140,43 @@ static inline int igbvf_tx_map_adv(struc
 		buffer_info->length = len;
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
-		buffer_info->dma = map[count];
-		count++;
+		buffer_info->mapped_as_page = true;
+		buffer_info->dma = pci_map_page(pdev,
+						frag->page,
+						frag->page_offset,
+						len,
+						PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma))
+			goto dma_error;
 	}
 
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
-	return count + 1;
+	return ++count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+
+	/* clear timestamp and dma mappings for failed buffer_info mapping */
+	buffer_info->dma = 0;
+	buffer_info->time_stamp = 0;
+	buffer_info->length = 0;
+	buffer_info->next_to_watch = 0;
+	buffer_info->mapped_as_page = false;
+	if (count)
+		count--;
+
+	/* clear timestamp and dma mappings for remaining portion of packet */
+	while (count--) {
+		if (i==0)
+			i += tx_ring->count;
+		i--;
+		buffer_info = &tx_ring->buffer_info[i];
+		igbvf_put_txbuf(adapter, buffer_info);
+	}
+
+	return 0;
 }
 
 static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
@@ -2726,7 +2764,8 @@ static int __devinit igbvf_probe(struct
 	err = hw->mac.ops.reset_hw(hw);
 	if (err) {
 		dev_info(&pdev->dev,
-		         "PF still in reset state, assigning new address\n");
+			 "PF still in reset state, assigning new address."
+			 " Is the PF interface up?\n");
 		random_ether_addr(hw->mac.addr);
 	} else {
 		err = hw->mac.ops.read_mac_addr(hw);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ipg.c linux-libre-2.6.33-gnu1/drivers/net/ipg.c
--- linux-libre-2.6.32-gnu1/drivers/net/ipg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ipg.c	2010-02-24 13:52:17.000000000 -0500
@@ -738,17 +738,12 @@ static int ipg_get_rxbuff(struct net_dev
 
 	IPG_DEBUG_MSG("_get_rxbuff\n");
 
-	skb = netdev_alloc_skb(dev, sp->rxsupport_size + NET_IP_ALIGN);
+	skb = netdev_alloc_skb_ip_align(dev, sp->rxsupport_size);
 	if (!skb) {
 		sp->rx_buff[entry] = NULL;
 		return -ENOMEM;
 	}
 
-	/* Adjust the data start location within the buffer to
-	 * align IP address field to a 16 byte boundary.
-	 */
-	skb_reserve(skb, NET_IP_ALIGN);
-
 	/* Associate the receive buffer with the IPG NIC. */
 	skb->dev = dev;
 
@@ -1756,7 +1751,7 @@ static int ipg_nic_open(struct net_devic
 	/* Register the interrupt line to be used by the IPG within
 	 * the Linux system.
 	 */
-	rc = request_irq(pdev->irq, &ipg_interrupt_handler, IRQF_SHARED,
+	rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED,
 			 dev->name, dev);
 	if (rc < 0) {
 		printk(KERN_INFO "%s: Error when requesting interrupt.\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/au1k_ir.c linux-libre-2.6.33-gnu1/drivers/net/irda/au1k_ir.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/au1k_ir.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/au1k_ir.c	2010-02-24 13:52:17.000000000 -0500
@@ -353,13 +353,13 @@ static int au1k_irda_start(struct net_de
 		return retval;
 	}
 
-	if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, 
+	if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt, 
 					0, dev->name, dev))) {
 		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
 				dev->name, dev->irq);
 		return retval;
 	}
-	if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, 
+	if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt, 
 					0, dev->name, dev))) {
 		free_irq(AU1000_IRDA_TX_INT, dev);
 		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/irda-usb.c linux-libre-2.6.33-gnu1/drivers/net/irda/irda-usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 14:01:31.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 12:08:52.000000000 -0400
@@ -852,7 +852,7 @@ static void irda_usb_receive(struct urb
 		 * hot unplug of the dongle...
 		 * Lowest effective timer is 10ms...
 		 * Jean II */
-		self->rx_defer_timer.function = &irda_usb_rx_defer_expired;
+		self->rx_defer_timer.function = irda_usb_rx_defer_expired;
 		self->rx_defer_timer.data = (unsigned long) urb;
 		mod_timer(&self->rx_defer_timer, jiffies + (10 * HZ / 1000));
 		return;
@@ -1121,11 +1121,11 @@ static int stir421x_patch_device(struct
                  * The actual image starts after the "STMP" keyword
                  * so forward to the firmware header tag
                  */
-                for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG)
-			     && (i < fw->size); i++) ;
+                for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) &&
+			     (i < fw->size); i++) ;
                 /* here we check for the out of buffer case */
-                if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i])
-                    && (i < STIR421X_PATCH_CODE_OFFSET)) {
+                if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) &&
+                    (i < STIR421X_PATCH_CODE_OFFSET)) {
                         if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG,
                                     sizeof(STIR421X_PATCH_STMP_TAG) - 1)) {
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/smsc-ircc2.c linux-libre-2.6.33-gnu1/drivers/net/irda/smsc-ircc2.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/smsc-ircc2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/smsc-ircc2.c	2010-02-24 13:52:17.000000000 -0500
@@ -115,7 +115,7 @@ struct smsc_ircc_subsystem_configuration
 	unsigned short vendor; /* PCI vendor ID */
 	unsigned short device; /* PCI vendor ID */
 	unsigned short subvendor; /* PCI subsystem vendor ID */
-	unsigned short subdevice; /* PCI sybsystem device ID */
+	unsigned short subdevice; /* PCI subsystem device ID */
 	unsigned short sir_io; /* I/O port for SIR */
 	unsigned short fir_io; /* I/O port for FIR */
 	unsigned char  fir_irq; /* FIR IRQ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/stir4200.c linux-libre-2.6.33-gnu1/drivers/net/irda/stir4200.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/stir4200.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/stir4200.c	2010-02-24 13:52:17.000000000 -0500
@@ -612,16 +612,16 @@ static int fifo_txwait(struct stir_cb *s
 		pr_debug("fifo status 0x%lx count %lu\n", status, count);
 
 		/* is fifo receiving already, or empty */
-		if (!(status & FIFOCTL_DIR)
-		    || (status & FIFOCTL_EMPTY))
+		if (!(status & FIFOCTL_DIR) ||
+		    (status & FIFOCTL_EMPTY))
 			return 0;
 
 		if (signal_pending(current))
 			return -EINTR;
 
 		/* shutting down? */
-		if (!netif_running(stir->netdev)
-		    || !netif_device_present(stir->netdev))
+		if (!netif_running(stir->netdev) ||
+		    !netif_device_present(stir->netdev))
 			return -ESHUTDOWN;
 
 		/* only waiting for some space */
@@ -776,8 +776,8 @@ static int stir_transmit_thread(void *ar
 		}
 
 		/* nothing to send? start receiving */
-		if (!stir->receiving 
-		    && irda_device_txqueue_empty(dev)) {
+		if (!stir->receiving &&
+		    irda_device_txqueue_empty(dev)) {
 			/* Wait otherwise chip gets confused. */
 			if (fifo_txwait(stir, -1))
 				break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/via-ircc.c linux-libre-2.6.33-gnu1/drivers/net/irda/via-ircc.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/via-ircc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/via-ircc.c	2010-02-24 13:52:17.000000000 -0500
@@ -1185,8 +1185,8 @@ F01_E */
 		 * if frame size,data ptr,or skb ptr are wrong ,the get next
 		 * entry.
 		 */
-		if ((skb == NULL) || (skb->data == NULL)
-		    || (self->rx_buff.data == NULL) || (len < 6)) {
+		if ((skb == NULL) || (skb->data == NULL) ||
+		    (self->rx_buff.data == NULL) || (len < 6)) {
 			self->netdev->stats.rx_dropped++;
 			return TRUE;
 		}
@@ -1284,8 +1284,8 @@ static int RxTimerHandler(struct via_irc
 		self->RetryCount++;
 
 	if ((self->RetryCount >= 1) ||
-	    ((st_fifo->pending_bytes + 2048) > self->rx_buff.truesize)
-	    || (st_fifo->len >= (MAX_RX_WINDOW))) {
+	    ((st_fifo->pending_bytes + 2048) > self->rx_buff.truesize) ||
+	    (st_fifo->len >= (MAX_RX_WINDOW))) {
 		while (st_fifo->len > 0) {	//upload frame
 			// Put this entry back in fifo 
 			if (st_fifo->head > MAX_RX_WINDOW)
@@ -1300,8 +1300,8 @@ static int RxTimerHandler(struct via_irc
 			 * if frame size, data ptr, or skb ptr are wrong,
 			 * then get next entry.
 			 */
-			if ((skb == NULL) || (skb->data == NULL)
-			    || (self->rx_buff.data == NULL) || (len < 6)) {
+			if ((skb == NULL) || (skb->data == NULL) ||
+			    (self->rx_buff.data == NULL) || (len < 6)) {
 				self->netdev->stats.rx_dropped++;
 				continue;
 			}
@@ -1332,8 +1332,8 @@ static int RxTimerHandler(struct via_irc
 		 * if frame is receive complete at this routine ,then upload
 		 * frame.
 		 */
-		if ((GetRXStatus(iobase) & 0x10)
-		    && (RxCurCount(iobase, self) != self->RxLastCount)) {
+		if ((GetRXStatus(iobase) & 0x10) &&
+		    (RxCurCount(iobase, self) != self->RxLastCount)) {
 			upload_rxdata(self, iobase);
 			if (irda_device_txqueue_empty(self->netdev))
 				via_ircc_dma_receive(self);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/irda/vlsi_ir.c linux-libre-2.6.33-gnu1/drivers/net/irda/vlsi_ir.c
--- linux-libre-2.6.32-gnu1/drivers/net/irda/vlsi_ir.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/irda/vlsi_ir.c	2010-02-24 13:52:17.000000000 -0500
@@ -431,8 +431,8 @@ static struct vlsi_ring *vlsi_alloc_ring
 		memset(rd, 0, sizeof(*rd));
 		rd->hw = hwmap + i;
 		rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA);
-		if (rd->buf == NULL
-		    ||  !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
+		if (rd->buf == NULL ||
+		    !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
 			if (rd->buf) {
 				IRDA_ERROR("%s: failed to create PCI-MAP for %p",
 					   __func__, rd->buf);
@@ -955,8 +955,8 @@ static netdev_tx_t vlsi_hard_start_xmit(
 		}
 		for(;;) {
 			do_gettimeofday(&now);
-			if (now.tv_sec > ready.tv_sec
-			    ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
+			if (now.tv_sec > ready.tv_sec ||
+			    (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
 			    	break;
 			udelay(100);
 			/* must not sleep here - called under netif_tx_lock! */
@@ -1594,8 +1594,8 @@ static int vlsi_irda_init(struct net_dev
 	 * see include file for details why we need these 2 masks, in this order!
 	 */
 
-	if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW)
-	    || pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) {
+	if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW) ||
+	    pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) {
 		IRDA_ERROR("%s: aborting due to PCI BM-DMA address limitations\n", __func__);
 		return -1;
 	}
@@ -1641,8 +1641,8 @@ vlsi_irda_probe(struct pci_dev *pdev, co
 	IRDA_MESSAGE("%s: IrDA PCI controller %s detected\n",
 		     drivername, pci_name(pdev));
 
-	if ( !pci_resource_start(pdev,0)
-	     || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) {
+	if ( !pci_resource_start(pdev,0) ||
+	     !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) {
 		IRDA_ERROR("%s: bar 0 invalid", __func__);
 		goto out_disable;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/isa-skeleton.c linux-libre-2.6.33-gnu1/drivers/net/isa-skeleton.c
--- linux-libre-2.6.32-gnu1/drivers/net/isa-skeleton.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/isa-skeleton.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,9 +214,9 @@ static int __init netcard_probe1(struct
 	 * contains the manufacturer's unique code. That might be a good probe
 	 * method. Ideally you would add additional checks.
 	 */
-	if (inb(ioaddr + 0) != SA_ADDR0
-		||	 inb(ioaddr + 1) != SA_ADDR1
-		||	 inb(ioaddr + 2) != SA_ADDR2)
+	if (inb(ioaddr + 0) != SA_ADDR0 ||
+	    inb(ioaddr + 1) != SA_ADDR1 ||
+	    inb(ioaddr + 2) != SA_ADDR2)
 		goto out;
 
 	if (net_debug  &&  version_printed++ == 0)
@@ -260,7 +260,7 @@ static int __init netcard_probe1(struct
 		dev->irq = 9;
 
 	{
-		int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname, dev);
+		int irqval = request_irq(dev->irq, net_interrupt, 0, cardname, dev);
 		if (irqval) {
 			printk("%s: unable to get IRQ %d (irqval=%d).\n",
 				   dev->name, dev->irq, irqval);
@@ -378,7 +378,7 @@ net_open(struct net_device *dev)
 	 * This is used if the interrupt line can turned off (shared).
 	 * See 3c503.c for an example of selecting the IRQ at config-time.
 	 */
-	if (request_irq(dev->irq, &net_interrupt, 0, cardname, dev)) {
+	if (request_irq(dev->irq, net_interrupt, 0, cardname, dev)) {
 		return -EAGAIN;
 	}
 	/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/iseries_veth.c linux-libre-2.6.33-gnu1/drivers/net/iseries_veth.c
--- linux-libre-2.6.32-gnu1/drivers/net/iseries_veth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/iseries_veth.c	2010-02-24 13:52:17.000000000 -0500
@@ -604,10 +604,10 @@ static int veth_process_caps(struct veth
 	/* Convert timer to jiffies */
 	cnx->ack_timeout = remote_caps->ack_timeout * HZ / 1000000;
 
-	if ( (remote_caps->num_buffers == 0)
-	     || (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG)
-	     || (remote_caps->ack_threshold == 0)
-	     || (cnx->ack_timeout == 0) ) {
+	if ( (remote_caps->num_buffers == 0) ||
+	     (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG) ||
+	     (remote_caps->ack_threshold == 0) ||
+	     (cnx->ack_timeout == 0) ) {
 		veth_error("Received incompatible capabilities from LPAR %d.\n",
 				cnx->remote_lp);
 		return HvLpEvent_Rc_InvalidSubtypeData;
@@ -714,8 +714,8 @@ static void veth_statemachine(struct wor
 		cnx->state |= VETH_STATE_OPEN;
 	}
 
-	if ( (cnx->state & VETH_STATE_OPEN)
-	     && !(cnx->state & VETH_STATE_SENTMON) ) {
+	if ( (cnx->state & VETH_STATE_OPEN) &&
+	     !(cnx->state & VETH_STATE_SENTMON) ) {
 		rc = veth_signalevent(cnx, VETH_EVENT_MONITOR,
 				      HvLpEvent_AckInd_DoAck,
 				      HvLpEvent_AckType_DeferredAck,
@@ -724,8 +724,8 @@ static void veth_statemachine(struct wor
 		if (rc == HvLpEvent_Rc_Good) {
 			cnx->state |= VETH_STATE_SENTMON;
 		} else {
-			if ( (rc != HvLpEvent_Rc_PartitionDead)
-			     && (rc != HvLpEvent_Rc_PathClosed) )
+			if ( (rc != HvLpEvent_Rc_PartitionDead) &&
+			     (rc != HvLpEvent_Rc_PathClosed) )
 				veth_error("Error sending monitor to LPAR %d, "
 						"rc = %d\n", rlp, rc);
 
@@ -735,8 +735,8 @@ static void veth_statemachine(struct wor
 		}
 	}
 
-	if ( (cnx->state & VETH_STATE_OPEN)
-	     && !(cnx->state & VETH_STATE_SENTCAPS)) {
+	if ( (cnx->state & VETH_STATE_OPEN) &&
+	     !(cnx->state & VETH_STATE_SENTCAPS)) {
 		u64 *rawcap = (u64 *)&cnx->local_caps;
 
 		rc = veth_signalevent(cnx, VETH_EVENT_CAP,
@@ -748,8 +748,8 @@ static void veth_statemachine(struct wor
 		if (rc == HvLpEvent_Rc_Good) {
 			cnx->state |= VETH_STATE_SENTCAPS;
 		} else {
-			if ( (rc != HvLpEvent_Rc_PartitionDead)
-			     && (rc != HvLpEvent_Rc_PathClosed) )
+			if ( (rc != HvLpEvent_Rc_PartitionDead) &&
+			     (rc != HvLpEvent_Rc_PathClosed) )
 				veth_error("Error sending caps to LPAR %d, "
 						"rc = %d\n", rlp, rc);
 
@@ -759,8 +759,8 @@ static void veth_statemachine(struct wor
 		}
 	}
 
-	if ((cnx->state & VETH_STATE_GOTCAPS)
-	    && !(cnx->state & VETH_STATE_SENTCAPACK)) {
+	if ((cnx->state & VETH_STATE_GOTCAPS) &&
+	    !(cnx->state & VETH_STATE_SENTCAPACK)) {
 		struct veth_cap_data *remote_caps = &cnx->remote_caps;
 
 		memcpy(remote_caps, &cnx->cap_event.u.caps_data,
@@ -783,9 +783,9 @@ static void veth_statemachine(struct wor
 			goto cant_cope;
 	}
 
-	if ((cnx->state & VETH_STATE_GOTCAPACK)
-	    && (cnx->state & VETH_STATE_GOTCAPS)
-	    && !(cnx->state & VETH_STATE_READY)) {
+	if ((cnx->state & VETH_STATE_GOTCAPACK) &&
+	    (cnx->state & VETH_STATE_GOTCAPS) &&
+	    !(cnx->state & VETH_STATE_READY)) {
 		if (cnx->cap_ack_event.base_event.xRc == HvLpEvent_Rc_Good) {
 			/* Start the ACK timer */
 			cnx->ack_timer.expires = jiffies + cnx->ack_timeout;
@@ -818,8 +818,8 @@ static int veth_init_connection(u8 rlp)
 	struct veth_msg *msgs;
 	int i;
 
-	if ( (rlp == this_lp)
-	     || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) )
+	if ( (rlp == this_lp) ||
+	     ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) )
 		return 0;
 
 	cnx = kzalloc(sizeof(*cnx), GFP_KERNEL);
@@ -1384,7 +1384,7 @@ static inline void veth_build_dma_list(s
 	unsigned long done;
 	int i = 1;
 
-	/* FIXME: skbs are continguous in real addresses.  Do we
+	/* FIXME: skbs are contiguous in real addresses.  Do we
 	 * really need to break it into PAGE_SIZE chunks, or can we do
 	 * it just at the granularity of iSeries real->absolute
 	 * mapping?  Indeed, given the way the allocator works, can we
@@ -1538,8 +1538,8 @@ static void veth_receive(struct veth_lpa
 	cnx->pending_acks[cnx->num_pending_acks++] =
 		event->base_event.xCorrelationToken;
 
-	if ( (cnx->num_pending_acks >= cnx->remote_caps.ack_threshold)
-	     || (cnx->num_pending_acks >= VETH_MAX_ACKS_PER_MSG) )
+	if ( (cnx->num_pending_acks >= cnx->remote_caps.ack_threshold) ||
+	     (cnx->num_pending_acks >= VETH_MAX_ACKS_PER_MSG) )
 		veth_flush_acks(cnx);
 
 	spin_unlock_irqrestore(&cnx->lock, flags);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,38 +34,46 @@
 
 #define IXGB_ALL_RAR_ENTRIES 16
 
+enum {NETDEV_STATS, IXGB_STATS};
+
 struct ixgb_stats {
 	char stat_string[ETH_GSTRING_LEN];
+	int type;
 	int sizeof_stat;
 	int stat_offset;
 };
 
-#define IXGB_STAT(m) FIELD_SIZEOF(struct ixgb_adapter, m), \
-		      offsetof(struct ixgb_adapter, m)
+#define IXGB_STAT(m)		IXGB_STATS, \
+				FIELD_SIZEOF(struct ixgb_adapter, m), \
+				offsetof(struct ixgb_adapter, m)
+#define IXGB_NETDEV_STAT(m)	NETDEV_STATS, \
+				FIELD_SIZEOF(struct net_device, m), \
+				offsetof(struct net_device, m)
+
 static struct ixgb_stats ixgb_gstrings_stats[] = {
-	{"rx_packets", IXGB_STAT(net_stats.rx_packets)},
-	{"tx_packets", IXGB_STAT(net_stats.tx_packets)},
-	{"rx_bytes", IXGB_STAT(net_stats.rx_bytes)},
-	{"tx_bytes", IXGB_STAT(net_stats.tx_bytes)},
-	{"rx_errors", IXGB_STAT(net_stats.rx_errors)},
-	{"tx_errors", IXGB_STAT(net_stats.tx_errors)},
-	{"rx_dropped", IXGB_STAT(net_stats.rx_dropped)},
-	{"tx_dropped", IXGB_STAT(net_stats.tx_dropped)},
-	{"multicast", IXGB_STAT(net_stats.multicast)},
-	{"collisions", IXGB_STAT(net_stats.collisions)},
+	{"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)},
+	{"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)},
+	{"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)},
+	{"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)},
+	{"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)},
+	{"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)},
+	{"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)},
+	{"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)},
+	{"multicast", IXGB_NETDEV_STAT(stats.multicast)},
+	{"collisions", IXGB_NETDEV_STAT(stats.collisions)},
 
-/*	{ "rx_length_errors", IXGB_STAT(net_stats.rx_length_errors) },	*/
-	{"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},
-	{"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},
-	{"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)},
+/*	{ "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) },	*/
+	{"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)},
+	{"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)},
+	{"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)},
 	{"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
-	{"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)},
-	{"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)},
-	{"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)},
-	{"tx_carrier_errors", IXGB_STAT(net_stats.tx_carrier_errors)},
-	{"tx_fifo_errors", IXGB_STAT(net_stats.tx_fifo_errors)},
-	{"tx_heartbeat_errors", IXGB_STAT(net_stats.tx_heartbeat_errors)},
-	{"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},
+	{"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)},
+	{"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)},
+	{"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)},
+	{"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)},
+	{"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)},
+	{"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)},
+	{"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)},
 	{"tx_deferred_ok", IXGB_STAT(stats.dc)},
 	{"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
 	{"tx_restart_queue", IXGB_STAT(restart_queue) },
@@ -662,10 +670,21 @@ ixgb_get_ethtool_stats(struct net_device
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 	int i;
+	char *p = NULL;
 
 	ixgb_update_stats(adapter);
 	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;
+		switch (ixgb_gstrings_stats[i].type) {
+		case NETDEV_STATS:
+			p = (char *) netdev +
+					ixgb_gstrings_stats[i].stat_offset;
+			break;
+		case IXGB_STATS:
+			p = (char *) adapter +
+					ixgb_gstrings_stats[i].stat_offset;
+			break;
+		}
+
 		data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb.h linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb.h	2010-02-24 13:52:17.000000000 -0500
@@ -117,6 +117,7 @@ struct ixgb_buffer {
 	unsigned long time_stamp;
 	u16 length;
 	u16 next_to_watch;
+	u16 mapped_as_page;
 };
 
 struct ixgb_desc_ring {
@@ -183,7 +184,6 @@ struct ixgb_adapter {
 	struct napi_struct napi;
 	struct net_device *netdev;
 	struct pci_dev *pdev;
-	struct net_device_stats net_stats;
 
 	/* structs defined in ixgb_hw.h */
 	struct ixgb_hw hw;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb_main.c linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgb/ixgb_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgb/ixgb_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -233,7 +233,7 @@ ixgb_up(struct ixgb_adapter *adapter)
 		/* proceed to try to request regular interrupt */
 	}
 
-	err = request_irq(adapter->pdev->irq, &ixgb_intr, irq_flags,
+	err = request_irq(adapter->pdev->irq, ixgb_intr, irq_flags,
 	                  netdev->name, netdev);
 	if (err) {
 		if (adapter->have_msi)
@@ -892,10 +892,18 @@ static void
 ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
                                 struct ixgb_buffer *buffer_info)
 {
-	buffer_info->dma = 0;
+	if (buffer_info->dma) {
+		if (buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev, buffer_info->dma,
+				       buffer_info->length, PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev, buffer_info->dma,
+					 buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+
 	if (buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
@@ -1272,24 +1280,16 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 	    unsigned int first)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
+	struct pci_dev *pdev = adapter->pdev;
 	struct ixgb_buffer *buffer_info;
 	int len = skb_headlen(skb);
 	unsigned int offset = 0, size, count = 0, i;
 	unsigned int mss = skb_shinfo(skb)->gso_size;
-
 	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-
 	while (len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1301,11 +1301,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 		buffer_info->length = size;
 		WARN_ON(buffer_info->dma != 0);
 		buffer_info->time_stamp = jiffies;
-		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
-			pci_map_single(adapter->pdev,
-				skb->data + offset,
-				size,
-				PCI_DMA_TODEVICE);
+		buffer_info->mapped_as_page = false;
+		buffer_info->dma = pci_map_single(pdev, skb->data + offset,
+						  size, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma))
+			goto dma_error;
 		buffer_info->next_to_watch = 0;
 
 		len -= size;
@@ -1323,7 +1323,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = 0;
+		offset = frag->page_offset;
 
 		while (len) {
 			i++;
@@ -1341,7 +1341,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
-			buffer_info->dma = map[f] + offset;
+			buffer_info->mapped_as_page = true;
+			buffer_info->dma =
+				pci_map_page(pdev, frag->page,
+					     offset, size,
+					     PCI_DMA_TODEVICE);
+			if (pci_dma_mapping_error(pdev, buffer_info->dma))
+				goto dma_error;
 			buffer_info->next_to_watch = 0;
 
 			len -= size;
@@ -1353,6 +1359,22 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 	tx_ring->buffer_info[first].next_to_watch = i;
 
 	return count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+	buffer_info->dma = 0;
+	if (count)
+		count--;
+
+	while (count--) {
+		if (i==0)
+			i += tx_ring->count;
+		i--;
+		buffer_info = &tx_ring->buffer_info[i];
+		ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
+	}
+
+	return 0;
 }
 
 static void
@@ -1537,9 +1559,7 @@ ixgb_tx_timeout_task(struct work_struct
 static struct net_device_stats *
 ixgb_get_stats(struct net_device *netdev)
 {
-	struct ixgb_adapter *adapter = netdev_priv(netdev);
-
-	return &adapter->net_stats;
+	return &netdev->stats;
 }
 
 /**
@@ -1676,16 +1696,16 @@ ixgb_update_stats(struct ixgb_adapter *a
 
 	/* Fill out the OS statistics structure */
 
-	adapter->net_stats.rx_packets = adapter->stats.gprcl;
-	adapter->net_stats.tx_packets = adapter->stats.gptcl;
-	adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-	adapter->net_stats.tx_bytes = adapter->stats.gotcl;
-	adapter->net_stats.multicast = adapter->stats.mprcl;
-	adapter->net_stats.collisions = 0;
+	netdev->stats.rx_packets = adapter->stats.gprcl;
+	netdev->stats.tx_packets = adapter->stats.gptcl;
+	netdev->stats.rx_bytes = adapter->stats.gorcl;
+	netdev->stats.tx_bytes = adapter->stats.gotcl;
+	netdev->stats.multicast = adapter->stats.mprcl;
+	netdev->stats.collisions = 0;
 
 	/* ignore RLEC as it reports errors for padded (<64bytes) frames
 	 * with a length in the type/len field */
-	adapter->net_stats.rx_errors =
+	netdev->stats.rx_errors =
 	    /* adapter->stats.rnbc + */ adapter->stats.crcerrs +
 	    adapter->stats.ruc +
 	    adapter->stats.roc /*+ adapter->stats.rlec */  +
@@ -1693,21 +1713,21 @@ ixgb_update_stats(struct ixgb_adapter *a
 	    adapter->stats.ecbc + adapter->stats.mpc;
 
 	/* see above
-	 * adapter->net_stats.rx_length_errors = adapter->stats.rlec;
+	 * netdev->stats.rx_length_errors = adapter->stats.rlec;
 	 */
 
-	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
-	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
-	adapter->net_stats.rx_over_errors = adapter->stats.mpc;
+	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+	netdev->stats.rx_fifo_errors = adapter->stats.mpc;
+	netdev->stats.rx_missed_errors = adapter->stats.mpc;
+	netdev->stats.rx_over_errors = adapter->stats.mpc;
 
-	adapter->net_stats.tx_errors = 0;
-	adapter->net_stats.rx_frame_errors = 0;
-	adapter->net_stats.tx_aborted_errors = 0;
-	adapter->net_stats.tx_carrier_errors = 0;
-	adapter->net_stats.tx_fifo_errors = 0;
-	adapter->net_stats.tx_heartbeat_errors = 0;
-	adapter->net_stats.tx_window_errors = 0;
+	netdev->stats.tx_errors = 0;
+	netdev->stats.rx_frame_errors = 0;
+	netdev->stats.tx_aborted_errors = 0;
+	netdev->stats.tx_carrier_errors = 0;
+	netdev->stats.tx_fifo_errors = 0;
+	netdev->stats.tx_heartbeat_errors = 0;
+	netdev->stats.tx_window_errors = 0;
 }
 
 #define IXGB_MAX_INTR 10
@@ -1974,9 +1994,8 @@ ixgb_clean_rx_irq(struct ixgb_adapter *a
 		 * of reassembly being done in the stack */
 		if (length < copybreak) {
 			struct sk_buff *new_skb =
-			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
+			    netdev_alloc_skb_ip_align(netdev, length);
 			if (new_skb) {
-				skb_reserve(new_skb, NET_IP_ALIGN);
 				skb_copy_to_linear_data_offset(new_skb,
 							       -NET_IP_ALIGN,
 							       (skb->data -
@@ -2059,20 +2078,13 @@ ixgb_alloc_rx_buffers(struct ixgb_adapte
 			goto map_skb;
 		}
 
-		skb = netdev_alloc_skb(netdev, adapter->rx_buffer_len
-			               + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(netdev, adapter->rx_buffer_len);
 		if (unlikely(!skb)) {
 			/* Better luck next round */
 			adapter->alloc_rx_buff_failed++;
 			break;
 		}
 
-		/* Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 map_skb:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_82598.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82598.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_82598.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82598.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -357,12 +357,34 @@ static s32 ixgbe_fc_enable_82598(struct
 	u32 fctrl_reg;
 	u32 rmcs_reg;
 	u32 reg;
+	u32 link_speed = 0;
+	bool link_up;
 
 #ifdef CONFIG_DCB
 	if (hw->fc.requested_mode == ixgbe_fc_pfc)
 		goto out;
 
 #endif /* CONFIG_DCB */
+	/*
+	 * On 82598 having Rx FC on causes resets while doing 1G
+	 * so if it's on turn it off once we know link_speed. For
+	 * more details see 82598 Specification update.
+	 */
+	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
+		switch (hw->fc.requested_mode) {
+		case ixgbe_fc_full:
+			hw->fc.requested_mode = ixgbe_fc_tx_pause;
+			break;
+		case ixgbe_fc_rx_pause:
+			hw->fc.requested_mode = ixgbe_fc_none;
+			break;
+		default:
+			/* no change */
+			break;
+		}
+	}
+
 	/* Negotiate the fc mode to use */
 	ret_val = ixgbe_fc_autoneg(hw);
 	if (ret_val)
@@ -510,6 +532,40 @@ static s32 ixgbe_start_mac_link_82598(st
 }
 
 /**
+ *  ixgbe_validate_link_ready - Function looks for phy link
+ *  @hw: pointer to hardware structure
+ *
+ *  Function indicates success when phy link is available. If phy is not ready
+ *  within 5 seconds of MAC indicating link, the function returns error.
+ **/
+static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
+{
+	u32 timeout;
+	u16 an_reg;
+
+	if (hw->device_id != IXGBE_DEV_ID_82598AT2)
+		return 0;
+
+	for (timeout = 0;
+	     timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
+		hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, &an_reg);
+
+		if ((an_reg & MDIO_AN_STAT1_COMPLETE) &&
+		    (an_reg & MDIO_STAT1_LSTATUS))
+			break;
+
+		msleep(100);
+	}
+
+	if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
+		hw_dbg(hw, "Link was indicated but link is down\n");
+		return IXGBE_ERR_LINK_SETUP;
+	}
+
+	return 0;
+}
+
+/**
  *  ixgbe_check_mac_link_82598 - Get link/speed status
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
@@ -589,6 +645,10 @@ static s32 ixgbe_check_mac_link_82598(st
 	else
 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
 
+	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == true) &&
+	    (ixgbe_validate_link_ready(hw) != 0))
+		*link_up = false;
+
 	/* if link is down, zero out the current_mode */
 	if (*link_up == false) {
 		hw->fc.current_mode = ixgbe_fc_none;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_82599.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82599.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_82599.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_82599.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -42,6 +42,10 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
                                           ixgbe_link_speed speed,
                                           bool autoneg,
                                           bool autoneg_wait_to_complete);
+static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
+                                           ixgbe_link_speed speed,
+                                           bool autoneg,
+                                           bool autoneg_wait_to_complete);
 s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
                                bool autoneg_wait_to_complete);
 s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
@@ -64,7 +68,13 @@ static void ixgbe_init_mac_link_ops_8259
 		/* Set up dual speed SFP+ support */
 		mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
 	} else {
-		mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
+		if ((mac->ops.get_media_type(hw) ==
+		     ixgbe_media_type_backplane) &&
+		    (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
+		     hw->phy.smart_speed == ixgbe_smart_speed_on))
+			mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
+		else
+			mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
 	}
 }
 
@@ -332,11 +342,13 @@ static enum ixgbe_media_type ixgbe_get_m
 	case IXGBE_DEV_ID_82599_KX4:
 	case IXGBE_DEV_ID_82599_KX4_MEZZ:
 	case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+	case IXGBE_DEV_ID_82599_KR:
 	case IXGBE_DEV_ID_82599_XAUI_LOM:
 		/* Default device ID is mezzanine card KX/KX4 */
 		media_type = ixgbe_media_type_backplane;
 		break;
 	case IXGBE_DEV_ID_82599_SFP:
+	case IXGBE_DEV_ID_82599_SFP_EM:
 		media_type = ixgbe_media_type_fiber;
 		break;
 	case IXGBE_DEV_ID_82599_CX4:
@@ -479,7 +491,12 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
 			hw->mac.autotry_restart = false;
 		}
 
-		/* The controller may take up to 500ms at 10g to acquire link */
+		/*
+		 * Wait for the controller to acquire link.  Per IEEE 802.3ap,
+		 * Section 73.10.2, we may have to wait up to 500ms if KR is
+		 * attempted.  82599 uses the same timing for 10g SFI.
+		 */
+
 		for (i = 0; i < 5; i++) {
 			/* Wait for the link partner to also set speed */
 			msleep(100);
@@ -567,6 +584,111 @@ out:
 }
 
 /**
+ *  ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
+ *  @hw: pointer to hardware structure
+ *  @speed: new link speed
+ *  @autoneg: true if autonegotiation enabled
+ *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ *  Implements the Intel SmartSpeed algorithm.
+ **/
+static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
+				     ixgbe_link_speed speed, bool autoneg,
+				     bool autoneg_wait_to_complete)
+{
+	s32 status = 0;
+	ixgbe_link_speed link_speed;
+	s32 i, j;
+	bool link_up = false;
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+	hw_dbg(hw, "ixgbe_setup_mac_link_smartspeed.\n");
+
+	 /* Set autoneg_advertised value based on input link speed */
+	hw->phy.autoneg_advertised = 0;
+
+	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+	if (speed & IXGBE_LINK_SPEED_100_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
+
+	/*
+	 * Implement Intel SmartSpeed algorithm.  SmartSpeed will reduce the
+	 * autoneg advertisement if link is unable to be established at the
+	 * highest negotiated rate.  This can sometimes happen due to integrity
+	 * issues with the physical media connection.
+	 */
+
+	/* First, try to get link with full advertisement */
+	hw->phy.smart_speed_active = false;
+	for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
+		status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+						    autoneg_wait_to_complete);
+		if (status)
+			goto out;
+
+		/*
+		 * Wait for the controller to acquire link.  Per IEEE 802.3ap,
+		 * Section 73.10.2, we may have to wait up to 500ms if KR is
+		 * attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per
+		 * Table 9 in the AN MAS.
+		 */
+		for (i = 0; i < 5; i++) {
+			mdelay(100);
+
+			/* If we have link, just jump out */
+			hw->mac.ops.check_link(hw, &link_speed,
+			                       &link_up, false);
+			if (link_up)
+				goto out;
+		}
+	}
+
+	/*
+	 * We didn't get link.  If we advertised KR plus one of KX4/KX
+	 * (or BX4/BX), then disable KR and try again.
+	 */
+	if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) ||
+	    ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
+		goto out;
+
+	/* Turn SmartSpeed on to disable KR support */
+	hw->phy.smart_speed_active = true;
+	status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+					    autoneg_wait_to_complete);
+	if (status)
+		goto out;
+
+	/*
+	 * Wait for the controller to acquire link.  600ms will allow for
+	 * the AN link_fail_inhibit_timer as well for multiple cycles of
+	 * parallel detect, both 10g and 1g. This allows for the maximum
+	 * connect attempts as defined in the AN MAS table 73-7.
+	 */
+	for (i = 0; i < 6; i++) {
+		mdelay(100);
+
+		/* If we have link, just jump out */
+		hw->mac.ops.check_link(hw, &link_speed,
+		                       &link_up, false);
+		if (link_up)
+			goto out;
+	}
+
+	/* We didn't get link.  Turn SmartSpeed back off. */
+	hw->phy.smart_speed_active = false;
+	status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+					    autoneg_wait_to_complete);
+
+out:
+	return status;
+}
+
+/**
  *  ixgbe_check_mac_link_82599 - Determine link and speed status
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
@@ -669,7 +791,8 @@ s32 ixgbe_setup_mac_link_82599(struct ix
 		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
 			if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
 				autoc |= IXGBE_AUTOC_KX4_SUPP;
-			if (orig_autoc & IXGBE_AUTOC_KR_SUPP)
+			if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) &&
+			    (hw->phy.smart_speed_active == false))
 				autoc |= IXGBE_AUTOC_KR_SUPP;
 		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
 			autoc |= IXGBE_AUTOC_KX_SUPP;
@@ -878,6 +1001,10 @@ static s32 ixgbe_reset_hw_82599(struct i
 		hw->mac.num_rar_entries--;
 	}
 
+	/* Store the alternative WWNN/WWPN prefix */
+	hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
+	                               &hw->mac.wwpn_prefix);
+
 reset_hw_out:
 	return status;
 }
@@ -2414,6 +2541,51 @@ fw_version_out:
 	return status;
 }
 
+/**
+ *  ixgbe_get_wwn_prefix_82599 - Get alternative WWNN/WWPN prefix from
+ *  the EEPROM
+ *  @hw: pointer to hardware structure
+ *  @wwnn_prefix: the alternative WWNN prefix
+ *  @wwpn_prefix: the alternative WWPN prefix
+ *
+ *  This function will read the EEPROM from the alternative SAN MAC address
+ *  block to check the support for the alternative WWNN/WWPN prefix support.
+ **/
+static s32 ixgbe_get_wwn_prefix_82599(struct ixgbe_hw *hw, u16 *wwnn_prefix,
+                                      u16 *wwpn_prefix)
+{
+	u16 offset, caps;
+	u16 alt_san_mac_blk_offset;
+
+	/* clear output first */
+	*wwnn_prefix = 0xFFFF;
+	*wwpn_prefix = 0xFFFF;
+
+	/* check if alternative SAN MAC is supported */
+	hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR,
+	                    &alt_san_mac_blk_offset);
+
+	if ((alt_san_mac_blk_offset == 0) ||
+	    (alt_san_mac_blk_offset == 0xFFFF))
+		goto wwn_prefix_out;
+
+	/* check capability in alternative san mac address block */
+	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
+	hw->eeprom.ops.read(hw, offset, &caps);
+	if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
+		goto wwn_prefix_out;
+
+	/* get the corresponding prefix for WWNN/WWPN */
+	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
+	hw->eeprom.ops.read(hw, offset, wwnn_prefix);
+
+	offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET;
+	hw->eeprom.ops.read(hw, offset, wwpn_prefix);
+
+wwn_prefix_out:
+	return 0;
+}
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
 	.init_hw                = &ixgbe_init_hw_generic,
 	.reset_hw               = &ixgbe_reset_hw_82599,
@@ -2425,6 +2597,7 @@ static struct ixgbe_mac_operations mac_o
 	.get_mac_addr           = &ixgbe_get_mac_addr_generic,
 	.get_san_mac_addr       = &ixgbe_get_san_mac_addr_82599,
 	.get_device_caps        = &ixgbe_get_device_caps_82599,
+	.get_wwn_prefix         = &ixgbe_get_wwn_prefix_82599,
 	.stop_adapter           = &ixgbe_stop_adapter_generic,
 	.get_bus_info           = &ixgbe_get_bus_info_generic,
 	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_common.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -1382,10 +1382,10 @@ s32 ixgbe_update_uc_addr_list_generic(st
 	hw->addr_ctrl.overflow_promisc = 0;
 
 	/* Zero out the other receive addresses */
-	hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use);
-	for (i = 1; i <= uc_addr_in_use; i++) {
-		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
+	hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use + 1);
+	for (i = 0; i < uc_addr_in_use; i++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0);
 	}
 
 	/* Add the new addresses */
@@ -1755,17 +1755,24 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw
 	/*
 	 * On backplane, bail out if
 	 * - backplane autoneg was not completed, or if
-	 * - link partner is not AN enabled
+	 * - we are 82599 and link partner is not AN enabled
 	 */
 	if (hw->phy.media_type == ixgbe_media_type_backplane) {
 		links = IXGBE_READ_REG(hw, IXGBE_LINKS);
-		links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
-		if (((links & IXGBE_LINKS_KX_AN_COMP) == 0) ||
-		    ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)) {
+		if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
 			hw->fc.fc_was_autonegged = false;
 			hw->fc.current_mode = hw->fc.requested_mode;
 			goto out;
 		}
+
+		if (hw->mac.type == ixgbe_mac_82599EB) {
+			links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
+			if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
+				hw->fc.fc_was_autonegged = false;
+				hw->fc.current_mode = hw->fc.requested_mode;
+				goto out;
+			}
+		}
 	}
 
 	/*
@@ -1784,6 +1791,20 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw
 	}
 
 	/*
+	 * Bail out on
+	 * - copper or CX4 adapters
+	 * - fiber adapters running at 10gig
+	 */
+	if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+	     (hw->phy.media_type == ixgbe_media_type_cx4) ||
+	     ((hw->phy.media_type == ixgbe_media_type_fiber) &&
+	     (speed == IXGBE_LINK_SPEED_10GB_FULL))) {
+		hw->fc.fc_was_autonegged = false;
+		hw->fc.current_mode = hw->fc.requested_mode;
+		goto out;
+	}
+
+	/*
 	 * Read the AN advertisement and LP ability registers and resolve
 	 * local flow control settings accordingly
 	 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_common.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -223,7 +223,7 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_t
 
 	if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
 	    adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
-		adapter->dcb_set_bitmap |= BIT_PG_RX;
+		adapter->dcb_set_bitmap |= BIT_PG_TX;
 		adapter->dcb_set_bitmap |= BIT_RESETLINK;
 	}
 }
@@ -341,6 +341,12 @@ static u8 ixgbe_dcbnl_set_all(struct net
 	if (!adapter->dcb_set_bitmap)
 		return DCB_NO_HW_CHG;
 
+	ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
+				 adapter->ring_feature[RING_F_DCB].indices);
+
+	if (ret)
+		return DCB_NO_HW_CHG;
+
 	/*
 	 * Only take down the adapter if the configuration change
 	 * requires a reset.
@@ -359,14 +365,6 @@ static u8 ixgbe_dcbnl_set_all(struct net
 		}
 	}
 
-	ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
-				 adapter->ring_feature[RING_F_DCB].indices);
-	if (ret) {
-		if (adapter->dcb_set_bitmap & BIT_RESETLINK)
-			clear_bit(__IXGBE_RESETTING, &adapter->state);
-		return DCB_NO_HW_CHG;
-	}
-
 	if (adapter->dcb_cfg.pfc_mode_enable) {
 		if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
 			(adapter->hw.fc.current_mode != ixgbe_fc_pfc))
@@ -563,7 +561,7 @@ static u8 ixgbe_dcbnl_setapp(struct net_
 	return rval;
 }
 
-struct dcbnl_rtnl_ops dcbnl_ops = {
+const struct dcbnl_rtnl_ops dcbnl_ops = {
 	.getstate	= ixgbe_dcbnl_get_state,
 	.setstate	= ixgbe_dcbnl_set_state,
 	.getpermhwaddr	= ixgbe_dcbnl_get_perm_hw_addr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -40,19 +40,27 @@
 
 #define IXGBE_ALL_RAR_ENTRIES 16
 
+enum {NETDEV_STATS, IXGBE_STATS};
+
 struct ixgbe_stats {
 	char stat_string[ETH_GSTRING_LEN];
+	int type;
 	int sizeof_stat;
 	int stat_offset;
 };
 
-#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \
-                             offsetof(struct ixgbe_adapter, m)
+#define IXGBE_STAT(m)		IXGBE_STATS, \
+				sizeof(((struct ixgbe_adapter *)0)->m), \
+				offsetof(struct ixgbe_adapter, m)
+#define IXGBE_NETDEV_STAT(m)	NETDEV_STATS, \
+				sizeof(((struct net_device *)0)->m), \
+				offsetof(struct net_device, m)
+
 static struct ixgbe_stats ixgbe_gstrings_stats[] = {
-	{"rx_packets", IXGBE_STAT(net_stats.rx_packets)},
-	{"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
-	{"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
-	{"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
+	{"rx_packets", IXGBE_NETDEV_STAT(stats.rx_packets)},
+	{"tx_packets", IXGBE_NETDEV_STAT(stats.tx_packets)},
+	{"rx_bytes", IXGBE_NETDEV_STAT(stats.rx_bytes)},
+	{"tx_bytes", IXGBE_NETDEV_STAT(stats.tx_bytes)},
 	{"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
 	{"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
 	{"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
@@ -60,40 +68,36 @@ static struct ixgbe_stats ixgbe_gstrings
 	{"lsc_int", IXGBE_STAT(lsc_int)},
 	{"tx_busy", IXGBE_STAT(tx_busy)},
 	{"non_eop_descs", IXGBE_STAT(non_eop_descs)},
-	{"rx_errors", IXGBE_STAT(net_stats.rx_errors)},
-	{"tx_errors", IXGBE_STAT(net_stats.tx_errors)},
-	{"rx_dropped", IXGBE_STAT(net_stats.rx_dropped)},
-	{"tx_dropped", IXGBE_STAT(net_stats.tx_dropped)},
-	{"multicast", IXGBE_STAT(net_stats.multicast)},
+	{"rx_errors", IXGBE_NETDEV_STAT(stats.rx_errors)},
+	{"tx_errors", IXGBE_NETDEV_STAT(stats.tx_errors)},
+	{"rx_dropped", IXGBE_NETDEV_STAT(stats.rx_dropped)},
+	{"tx_dropped", IXGBE_NETDEV_STAT(stats.tx_dropped)},
+	{"multicast", IXGBE_NETDEV_STAT(stats.multicast)},
 	{"broadcast", IXGBE_STAT(stats.bprc)},
 	{"rx_no_buffer_count", IXGBE_STAT(stats.rnbc[0]) },
-	{"collisions", IXGBE_STAT(net_stats.collisions)},
-	{"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)},
-	{"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)},
-	{"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)},
-	{"hw_rsc_count", IXGBE_STAT(rsc_count)},
+	{"collisions", IXGBE_NETDEV_STAT(stats.collisions)},
+	{"rx_over_errors", IXGBE_NETDEV_STAT(stats.rx_over_errors)},
+	{"rx_crc_errors", IXGBE_NETDEV_STAT(stats.rx_crc_errors)},
+	{"rx_frame_errors", IXGBE_NETDEV_STAT(stats.rx_frame_errors)},
+	{"hw_rsc_aggregated", IXGBE_STAT(rsc_total_count)},
+	{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
 	{"fdir_match", IXGBE_STAT(stats.fdirmatch)},
 	{"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
-	{"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)},
-	{"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)},
-	{"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)},
-	{"tx_carrier_errors", IXGBE_STAT(net_stats.tx_carrier_errors)},
-	{"tx_fifo_errors", IXGBE_STAT(net_stats.tx_fifo_errors)},
-	{"tx_heartbeat_errors", IXGBE_STAT(net_stats.tx_heartbeat_errors)},
+	{"rx_fifo_errors", IXGBE_NETDEV_STAT(stats.rx_fifo_errors)},
+	{"rx_missed_errors", IXGBE_NETDEV_STAT(stats.rx_missed_errors)},
+	{"tx_aborted_errors", IXGBE_NETDEV_STAT(stats.tx_aborted_errors)},
+	{"tx_carrier_errors", IXGBE_NETDEV_STAT(stats.tx_carrier_errors)},
+	{"tx_fifo_errors", IXGBE_NETDEV_STAT(stats.tx_fifo_errors)},
+	{"tx_heartbeat_errors", IXGBE_NETDEV_STAT(stats.tx_heartbeat_errors)},
 	{"tx_timeout_count", IXGBE_STAT(tx_timeout_count)},
 	{"tx_restart_queue", IXGBE_STAT(restart_queue)},
 	{"rx_long_length_errors", IXGBE_STAT(stats.roc)},
 	{"rx_short_length_errors", IXGBE_STAT(stats.ruc)},
-	{"tx_tcp4_seg_ctxt", IXGBE_STAT(hw_tso_ctxt)},
-	{"tx_tcp6_seg_ctxt", IXGBE_STAT(hw_tso6_ctxt)},
 	{"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)},
 	{"rx_flow_control_xon", IXGBE_STAT(stats.lxonrxc)},
 	{"tx_flow_control_xoff", IXGBE_STAT(stats.lxofftxc)},
 	{"rx_flow_control_xoff", IXGBE_STAT(stats.lxoffrxc)},
-	{"rx_csum_offload_good", IXGBE_STAT(hw_csum_rx_good)},
 	{"rx_csum_offload_errors", IXGBE_STAT(hw_csum_rx_error)},
-	{"tx_csum_offload_ctxt", IXGBE_STAT(hw_csum_tx_good)},
-	{"rx_header_split", IXGBE_STAT(rx_hdr_split)},
 	{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
 	{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
 	{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
@@ -196,6 +200,56 @@ static int ixgbe_get_settings(struct net
 		ecmd->autoneg = AUTONEG_DISABLE;
 	}
 
+	/* Get PHY type */
+	switch (adapter->hw.phy.type) {
+	case ixgbe_phy_tn:
+	case ixgbe_phy_cu_unknown:
+		/* Copper 10G-BASET */
+		ecmd->port = PORT_TP;
+		break;
+	case ixgbe_phy_qt:
+		ecmd->port = PORT_FIBRE;
+		break;
+	case ixgbe_phy_nl:
+	case ixgbe_phy_tw_tyco:
+	case ixgbe_phy_tw_unknown:
+	case ixgbe_phy_sfp_ftl:
+	case ixgbe_phy_sfp_avago:
+	case ixgbe_phy_sfp_intel:
+	case ixgbe_phy_sfp_unknown:
+		switch (adapter->hw.phy.sfp_type) {
+		/* SFP+ devices, further checking needed */
+		case ixgbe_sfp_type_da_cu:
+		case ixgbe_sfp_type_da_cu_core0:
+		case ixgbe_sfp_type_da_cu_core1:
+			ecmd->port = PORT_DA;
+			break;
+		case ixgbe_sfp_type_sr:
+		case ixgbe_sfp_type_lr:
+		case ixgbe_sfp_type_srlr_core0:
+		case ixgbe_sfp_type_srlr_core1:
+			ecmd->port = PORT_FIBRE;
+			break;
+		case ixgbe_sfp_type_not_present:
+			ecmd->port = PORT_NONE;
+			break;
+		case ixgbe_sfp_type_unknown:
+		default:
+			ecmd->port = PORT_OTHER;
+			break;
+		}
+		break;
+	case ixgbe_phy_xaui:
+		ecmd->port = PORT_NONE;
+		break;
+	case ixgbe_phy_unknown:
+	case ixgbe_phy_generic:
+	case ixgbe_phy_sfp_unsupported:
+	default:
+		ecmd->port = PORT_OTHER;
+		break;
+	}
+
 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
 	if (link_up) {
 		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
@@ -933,10 +987,22 @@ static void ixgbe_get_ethtool_stats(stru
 	int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
 	int j, k;
 	int i;
+	char *p = NULL;
 
 	ixgbe_update_stats(adapter);
+	dev_get_stats(netdev);
 	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
-		char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset;
+		switch (ixgbe_gstrings_stats[i].type) {
+		case NETDEV_STATS:
+			p = (char *) netdev +
+					ixgbe_gstrings_stats[i].stat_offset;
+			break;
+		case IXGBE_STATS:
+			p = (char *) adapter +
+					ixgbe_gstrings_stats[i].stat_offset;
+			break;
+		}
+
 		data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
 		           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
@@ -1255,15 +1321,15 @@ static int ixgbe_intr_test(struct ixgbe_
 		return 0;
 	} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
 		shared_int = false;
-		if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name,
+		if (request_irq(irq, ixgbe_test_intr, 0, netdev->name,
 				netdev)) {
 			*data = 1;
 			return -1;
 		}
-	} else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED,
+	} else if (!request_irq(irq, ixgbe_test_intr, IRQF_PROBE_SHARED,
 	                        netdev->name, netdev)) {
 		shared_int = false;
-	} else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED,
+	} else if (request_irq(irq, ixgbe_test_intr, IRQF_SHARED,
 	                       netdev->name, netdev)) {
 		*data = 1;
 		return -1;
@@ -1952,6 +2018,10 @@ static int ixgbe_get_coalesce(struct net
 		break;
 	}
 
+	/* if in mixed tx/rx queues per vector mode, report only rx settings */
+	if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count)
+		return 0;
+
 	/* only valid if in constant ITR mode */
 	switch (adapter->tx_itr_setting) {
 	case 0:
@@ -1977,12 +2047,9 @@ static int ixgbe_set_coalesce(struct net
 	struct ixgbe_q_vector *q_vector;
 	int i;
 
-	/*
-	 * don't accept tx specific changes if we've got mixed RxTx vectors
-	 * test and jump out here if needed before changing the rx numbers
-	 */
-	if ((1000000/ec->tx_coalesce_usecs) != adapter->tx_eitr_param &&
-	    adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count)
+	/* don't accept tx specific changes if we've got mixed RxTx vectors */
+	if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count
+	   && ec->tx_coalesce_usecs)
 		return -EINVAL;
 
 	if (ec->tx_max_coalesced_frames_irq)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -499,6 +499,10 @@ void ixgbe_configure_fcoe(struct ixgbe_a
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct ixgbe_fcoe *fcoe = &adapter->fcoe;
 	struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+#ifdef CONFIG_IXGBE_DCB
+	u8 tc;
+	u32 up2tc;
+#endif
 
 	/* create the pool for ddp if not created yet */
 	if (!fcoe->pool) {
@@ -540,6 +544,17 @@ void ixgbe_configure_fcoe(struct ixgbe_a
 			IXGBE_FCRXCTRL_FCOELLI |
 			IXGBE_FCRXCTRL_FCCRCBO |
 			(FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT));
+#ifdef CONFIG_IXGBE_DCB
+	up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
+	for (i = 0; i < MAX_USER_PRIORITY; i++) {
+		tc = (u8)(up2tc >> (i * IXGBE_RTTUP2TC_UP_SHIFT));
+		tc &= (MAX_TRAFFIC_CLASS - 1);
+		if (fcoe->tc == tc) {
+			fcoe->up = i;
+			break;
+		}
+	}
+#endif
 }
 
 /**
@@ -671,19 +686,7 @@ out_disable:
  */
 u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter)
 {
-	int i;
-	u8 tc;
-	u32 up2tc;
-
-	up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
-	for (i = 0; i < MAX_USER_PRIORITY; i++) {
-		tc = (u8)(up2tc >> (i * IXGBE_RTTUP2TC_UP_SHIFT));
-		tc &= (MAX_TRAFFIC_CLASS - 1);
-		if (adapter->fcoe.tc == tc)
-			return 1 << i;
-	}
-
-	return 0;
+	return 1 << adapter->fcoe.up;
 }
 
 /**
@@ -710,6 +713,7 @@ u8 ixgbe_fcoe_setapp(struct ixgbe_adapte
 				up2tc >>= (i * IXGBE_RTTUP2TC_UP_SHIFT);
 				up2tc &= (MAX_TRAFFIC_CLASS - 1);
 				adapter->fcoe.tc = (u8)up2tc;
+				adapter->fcoe.up = i;
 				return 0;
 			}
 		}
@@ -718,3 +722,49 @@ u8 ixgbe_fcoe_setapp(struct ixgbe_adapte
 	return 1;
 }
 #endif /* CONFIG_IXGBE_DCB */
+
+/**
+ * ixgbe_fcoe_get_wwn - get world wide name for the node or the port
+ * @netdev : ixgbe adapter
+ * @wwn : the world wide name
+ * @type: the type of world wide name
+ *
+ * Returns the node or port world wide name if both the prefix and the san
+ * mac address are valid, then the wwn is formed based on the NAA-2 for
+ * IEEE Extended name identifier (ref. to T10 FC-LS Spec., Sec. 15.3).
+ *
+ * Returns : 0 on success
+ */
+int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
+{
+	int rc = -EINVAL;
+	u16 prefix = 0xffff;
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_mac_info *mac = &adapter->hw.mac;
+
+	switch (type) {
+	case NETDEV_FCOE_WWNN:
+		prefix = mac->wwnn_prefix;
+		break;
+	case NETDEV_FCOE_WWPN:
+		prefix = mac->wwpn_prefix;
+		break;
+	default:
+		break;
+	}
+
+	if ((prefix != 0xffff) &&
+	    is_valid_ether_addr(mac->san_addr)) {
+		*wwn = ((u64) prefix << 48) |
+		       ((u64) mac->san_addr[0] << 40) |
+		       ((u64) mac->san_addr[1] << 32) |
+		       ((u64) mac->san_addr[2] << 24) |
+		       ((u64) mac->san_addr[3] << 16) |
+		       ((u64) mac->san_addr[4] << 8)  |
+		       ((u64) mac->san_addr[5]);
+		rc = 0;
+	}
+	return rc;
+}
+
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_fcoe.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_fcoe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_fcoe.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -62,7 +62,10 @@ struct ixgbe_fcoe_ddp {
 };
 
 struct ixgbe_fcoe {
+#ifdef CONFIG_IXGBE_DCB
 	u8 tc;
+	u8 up;
+#endif
 	spinlock_t lock;
 	struct pci_pool *pool;
 	struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -51,11 +51,11 @@
 		__func__ , ## args)))
 
 /* TX/RX descriptor defines */
-#define IXGBE_DEFAULT_TXD		   1024
+#define IXGBE_DEFAULT_TXD		    512
 #define IXGBE_MAX_TXD			   4096
 #define IXGBE_MIN_TXD			     64
 
-#define IXGBE_DEFAULT_RXD		   1024
+#define IXGBE_DEFAULT_RXD		    512
 #define IXGBE_MAX_RXD			   4096
 #define IXGBE_MIN_RXD			     64
 
@@ -106,6 +106,7 @@ struct ixgbe_tx_buffer {
 	unsigned long time_stamp;
 	u16 length;
 	u16 next_to_watch;
+	u16 mapped_as_page;
 };
 
 struct ixgbe_rx_buffer {
@@ -159,10 +160,13 @@ struct ixgbe_ring {
 	struct ixgbe_queue_stats stats;
 	unsigned long reinit_state;
 	u64 rsc_count;			/* stat for coalesced packets */
+	u64 rsc_flush;			/* stats for flushed packets */
+	u32 restart_queue;		/* track tx queue restarts */
+	u32 non_eop_descs;		/* track hardware descriptor chaining */
 
 	unsigned int size;		/* length in bytes */
 	dma_addr_t dma;			/* phys. address of descriptor ring */
-};
+} ____cacheline_internodealigned_in_smp;
 
 enum ixgbe_ring_f_enum {
 	RING_F_NONE = 0,
@@ -187,7 +191,7 @@ enum ixgbe_ring_f_enum {
 struct ixgbe_ring_feature {
 	int indices;
 	int mask;
-};
+} ____cacheline_internodealigned_in_smp;
 
 #define MAX_RX_QUEUES 128
 #define MAX_TX_QUEUES 128
@@ -273,29 +277,25 @@ struct ixgbe_adapter {
 	u16 eitr_high;
 
 	/* TX */
-	struct ixgbe_ring *tx_ring;	/* One per active queue */
+	struct ixgbe_ring *tx_ring ____cacheline_aligned_in_smp; /* One per active queue */
 	int num_tx_queues;
-	u64 restart_queue;
-	u64 hw_csum_tx_good;
-	u64 lsc_int;
-	u64 hw_tso_ctxt;
-	u64 hw_tso6_ctxt;
 	u32 tx_timeout_count;
 	bool detect_tx_hung;
 
+	u64 restart_queue;
+	u64 lsc_int;
+
 	/* RX */
-	struct ixgbe_ring *rx_ring;	/* One per active queue */
+	struct ixgbe_ring *rx_ring ____cacheline_aligned_in_smp; /* One per active queue */
 	int num_rx_queues;
 	u64 hw_csum_rx_error;
 	u64 hw_rx_no_dma_resources;
-	u64 hw_csum_rx_good;
 	u64 non_eop_descs;
 	int num_msix_vectors;
 	int max_msix_q_vectors;         /* true count of q_vectors for device */
 	struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE];
 	struct msix_entry *msix_entries;
 
-	u64 rx_hdr_split;
 	u32 alloc_rx_page_failed;
 	u32 alloc_rx_buff_failed;
 
@@ -340,7 +340,6 @@ struct ixgbe_adapter {
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
-	struct net_device_stats net_stats;
 
 	u32 test_icr;
 	struct ixgbe_ring test_tx_ring;
@@ -376,7 +375,8 @@ struct ixgbe_adapter {
 #ifdef IXGBE_FCOE
 	struct ixgbe_fcoe fcoe;
 #endif /* IXGBE_FCOE */
-	u64 rsc_count;
+	u64 rsc_total_count;
+	u64 rsc_total_flush;
 	u32 wol;
 	u16 eeprom_version;
 };
@@ -397,7 +397,7 @@ enum ixgbe_boards {
 extern struct ixgbe_info ixgbe_82598_info;
 extern struct ixgbe_info ixgbe_82599_info;
 #ifdef CONFIG_IXGBE_DCB
-extern struct dcbnl_rtnl_ops dcbnl_ops;
+extern const struct dcbnl_rtnl_ops dcbnl_ops;
 extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
                               struct ixgbe_dcb_config *dst_dcb_cfg,
                               int tc_max);
@@ -458,6 +458,7 @@ extern int ixgbe_fcoe_disable(struct net
 extern u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter);
 extern u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up);
 #endif /* CONFIG_IXGBE_DCB */
+extern int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type);
 #endif /* IXGBE_FCOE */
 
 #endif /* _IXGBE_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_main.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -52,7 +52,7 @@ static const char ixgbe_driver_string[]
 
 #define DRV_VERSION "2.0.44-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
-static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
 	[board_82598] = &ixgbe_82598_info,
@@ -96,8 +96,12 @@ static struct pci_device_id ixgbe_pci_tb
 	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM),
 	 board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR),
+	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
 	 board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_EM),
+	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ),
 	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
@@ -216,10 +220,20 @@ static void ixgbe_unmap_and_free_tx_reso
                                              struct ixgbe_tx_buffer
                                              *tx_buffer_info)
 {
-	tx_buffer_info->dma = 0;
+	if (tx_buffer_info->dma) {
+		if (tx_buffer_info->mapped_as_page)
+			pci_unmap_page(adapter->pdev,
+				       tx_buffer_info->dma,
+				       tx_buffer_info->length,
+				       PCI_DMA_TODEVICE);
+		else
+			pci_unmap_single(adapter->pdev,
+					 tx_buffer_info->dma,
+					 tx_buffer_info->length,
+					 PCI_DMA_TODEVICE);
+		tx_buffer_info->dma = 0;
+	}
 	if (tx_buffer_info->skb) {
-		skb_dma_unmap(&adapter->pdev->dev, tx_buffer_info->skb,
-		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(tx_buffer_info->skb);
 		tx_buffer_info->skb = NULL;
 	}
@@ -248,10 +262,12 @@ static inline bool ixgbe_tx_is_paused(st
 		int reg_idx = tx_ring->reg_idx;
 		int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
 
-		if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+		switch (adapter->hw.mac.type) {
+		case ixgbe_mac_82598EB:
 			tc = reg_idx >> 2;
 			txoff = IXGBE_TFCS_TXOFF0;
-		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+			break;
+		case ixgbe_mac_82599EB:
 			tc = 0;
 			txoff = IXGBE_TFCS_TXOFF;
 			if (dcb_i == 8) {
@@ -270,6 +286,9 @@ static inline bool ixgbe_tx_is_paused(st
 						tc += (reg_idx - 96) >> 4;
 				}
 			}
+			break;
+		default:
+			tc = 0;
 		}
 		txoff <<= tc;
 	}
@@ -401,7 +420,7 @@ static bool ixgbe_clean_tx_irq(struct ix
 		if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
 		    !test_bit(__IXGBE_DOWN, &adapter->state)) {
 			netif_wake_subqueue(netdev, tx_ring->queue_index);
-			++adapter->restart_queue;
+			++tx_ring->restart_queue;
 		}
 	}
 
@@ -423,8 +442,6 @@ static bool ixgbe_clean_tx_irq(struct ix
 	tx_ring->total_packets += total_packets;
 	tx_ring->stats.packets += total_packets;
 	tx_ring->stats.bytes += total_bytes;
-	adapter->net_stats.tx_bytes += total_bytes;
-	adapter->net_stats.tx_packets += total_packets;
 	return (count < tx_ring->work_limit);
 }
 
@@ -612,7 +629,6 @@ static inline void ixgbe_rx_checksum(str
 
 	/* It must be a TCP or UDP packet with a valid checksum */
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
-	adapter->hw_csum_rx_good++;
 }
 
 static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
@@ -669,21 +685,18 @@ static void ixgbe_alloc_rx_buffers(struc
 
 		if (!bi->skb) {
 			struct sk_buff *skb;
-			skb = netdev_alloc_skb(adapter->netdev,
-			                       (rx_ring->rx_buf_len +
-			                        NET_IP_ALIGN));
+			/* netdev_alloc_skb reserves 32 bytes up front!! */
+			uint bufsz = rx_ring->rx_buf_len + SMP_CACHE_BYTES;
+			skb = netdev_alloc_skb(adapter->netdev, bufsz);
 
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
 				goto no_buffers;
 			}
 
-			/*
-			 * Make buffer alignment 2 beyond a 16 byte boundary
-			 * this will result in a 16 byte aligned IP header after
-			 * the 14 byte MAC header is removed
-			 */
-			skb_reserve(skb, NET_IP_ALIGN);
+			/* advance the data pointer to the next cache line */
+			skb_reserve(skb, (PTR_ALIGN(skb->data, SMP_CACHE_BYTES)
+			                  - skb->data));
 
 			bi->skb = skb;
 			bi->dma = pci_map_single(pdev, skb->data,
@@ -735,12 +748,14 @@ static inline u32 ixgbe_get_rsc_count(un
 /**
  * ixgbe_transform_rsc_queue - change rsc queue into a full packet
  * @skb: pointer to the last skb in the rsc queue
+ * @count: pointer to number of packets coalesced in this context
  *
  * This function changes a queue full of hw rsc buffers into a completed
  * packet.  It uses the ->prev pointers to find the first packet and then
  * turns it into the frag list owner.
  **/
-static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
+static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
+                                                        u64 *count)
 {
 	unsigned int frag_list_size = 0;
 
@@ -749,6 +764,7 @@ static inline struct sk_buff *ixgbe_tran
 		frag_list_size += skb->len;
 		skb->prev = NULL;
 		skb = prev;
+		*count += 1;
 	}
 
 	skb_shinfo(skb)->frag_list = skb->next;
@@ -764,6 +780,7 @@ static bool ixgbe_clean_rx_irq(struct ix
                                int *work_done, int work_to_do)
 {
 	struct ixgbe_adapter *adapter = q_vector->adapter;
+	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
 	struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -793,8 +810,6 @@ static bool ixgbe_clean_rx_irq(struct ix
 			hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
 			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
 			       IXGBE_RXDADV_HDRBUFLEN_SHIFT;
-			if (hdr_info & IXGBE_RXDADV_SPH)
-				adapter->rx_hdr_split++;
 			if (len > IXGBE_RX_HDR_SIZE)
 				len = IXGBE_RX_HDR_SIZE;
 			upper_len = le16_to_cpu(rx_desc->wb.upper.length);
@@ -804,7 +819,7 @@ static bool ixgbe_clean_rx_irq(struct ix
 
 		cleaned = true;
 		skb = rx_buffer_info->skb;
-		prefetch(skb->data - NET_IP_ALIGN);
+		prefetch(skb->data);
 		rx_buffer_info->skb = NULL;
 
 		if (rx_buffer_info->dma) {
@@ -850,14 +865,20 @@ static bool ixgbe_clean_rx_irq(struct ix
 			u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
 				     IXGBE_RXDADV_NEXTP_SHIFT;
 			next_buffer = &rx_ring->rx_buffer_info[nextp];
-			rx_ring->rsc_count += (rsc_count - 1);
 		} else {
 			next_buffer = &rx_ring->rx_buffer_info[i];
 		}
 
 		if (staterr & IXGBE_RXD_STAT_EOP) {
 			if (skb->prev)
-				skb = ixgbe_transform_rsc_queue(skb);
+				skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
+			if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
+				if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
+					rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
+				else
+					rx_ring->rsc_count++;
+				rx_ring->rsc_flush++;
+			}
 			rx_ring->stats.packets++;
 			rx_ring->stats.bytes += skb->len;
 		} else {
@@ -870,7 +891,7 @@ static bool ixgbe_clean_rx_irq(struct ix
 				skb->next = next_buffer->skb;
 				skb->next->prev = skb;
 			}
-			adapter->non_eop_descs++;
+			rx_ring->non_eop_descs++;
 			goto next_desc;
 		}
 
@@ -935,8 +956,8 @@ next_desc:
 
 	rx_ring->total_packets += total_rx_packets;
 	rx_ring->total_bytes += total_rx_bytes;
-	adapter->net_stats.rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	netdev->stats.rx_bytes += total_rx_bytes;
+	netdev->stats.rx_packets += total_rx_packets;
 
 	return cleaned;
 }
@@ -1209,6 +1230,7 @@ static void ixgbe_check_lsc(struct ixgbe
 	adapter->link_check_timeout = jiffies;
 	if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
 		IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
+		IXGBE_WRITE_FLUSH(hw);
 		schedule_work(&adapter->watchdog_task);
 	}
 }
@@ -1312,8 +1334,7 @@ static irqreturn_t ixgbe_msix_clean_tx(i
 		                      r_idx + 1);
 	}
 
-	/* disable interrupts on this vector only */
-	ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+	/* EIAM disabled interrupts (on this vector) for us */
 	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
@@ -1344,10 +1365,8 @@ static irqreturn_t ixgbe_msix_clean_rx(i
 	if (!q_vector->rxr_count)
 		return IRQ_HANDLED;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* disable interrupts on this vector only */
-	ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+	/* EIAM disabled interrupts (on this vector) for us */
 	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
@@ -1382,8 +1401,7 @@ static irqreturn_t ixgbe_msix_clean_many
 		                      r_idx + 1);
 	}
 
-	/* disable interrupts on this vector only */
-	ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+	/* EIAM disabled interrupts (on this vector) for us */
 	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
@@ -1667,7 +1685,7 @@ static int ixgbe_request_msix_irqs(struc
 
 	sprintf(adapter->name[vector], "%s:lsc", netdev->name);
 	err = request_irq(adapter->msix_entries[vector].vector,
-	                  &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+	                  ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
 	if (err) {
 		DPRINTK(PROBE, ERR,
 			"request_irq for msix_lsc failed: %d\n", err);
@@ -1838,10 +1856,10 @@ static int ixgbe_request_irq(struct ixgb
 	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
 		err = ixgbe_request_msix_irqs(adapter);
 	} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
-		err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
+		err = request_irq(adapter->pdev->irq, ixgbe_intr, 0,
 		                  netdev->name, netdev);
 	} else {
-		err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
+		err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED,
 		                  netdev->name, netdev);
 	}
 
@@ -2063,18 +2081,18 @@ static u32 ixgbe_setup_mrqc(struct ixgbe
  * ixgbe_configure_rscctl - enable RSC for the indicated ring
  * @adapter:    address of board private structure
  * @index:      index of ring to set
- * @rx_buf_len: rx buffer length
  **/
-static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index,
-                                   int rx_buf_len)
+static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index)
 {
 	struct ixgbe_ring *rx_ring;
 	struct ixgbe_hw *hw = &adapter->hw;
 	int j;
 	u32 rscctrl;
+	int rx_buf_len;
 
 	rx_ring = &adapter->rx_ring[index];
 	j = rx_ring->reg_idx;
+	rx_buf_len = rx_ring->rx_buf_len;
 	rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
 	rscctrl |= IXGBE_RSCCTL_RSCEN;
 	/*
@@ -2282,7 +2300,7 @@ static void ixgbe_configure_rx(struct ix
 	if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
 		/* Enable 82599 HW-RSC */
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			ixgbe_configure_rscctl(adapter, i, rx_buf_len);
+			ixgbe_configure_rscctl(adapter, i);
 
 		/* Disable RSC for ACK packets */
 		IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
@@ -2333,23 +2351,25 @@ static void ixgbe_vlan_rx_register(struc
 	 * not in DCB mode.
 	 */
 	ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
+
+	/* Disable CFI check */
+	ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+
+	/* enable VLAN tag stripping */
 	if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
-		ctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
-		ctrl &= ~IXGBE_VLNCTRL_CFIEN;
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+		ctrl |= IXGBE_VLNCTRL_VME;
 	} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-		ctrl |= IXGBE_VLNCTRL_VFE;
-		/* enable VLAN tag insert/strip */
-		ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
-		ctrl &= ~IXGBE_VLNCTRL_CFIEN;
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
 		for (i = 0; i < adapter->num_rx_queues; i++) {
+			u32 ctrl;
 			j = adapter->rx_ring[i].reg_idx;
 			ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
 			ctrl |= IXGBE_RXDCTL_VME;
 			IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
 		}
 	}
+
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+
 	ixgbe_vlan_rx_add_vid(netdev, 0);
 
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
@@ -2699,7 +2719,22 @@ static int ixgbe_up_complete(struct ixgb
 		IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
 	}
 
-	if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
+	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+		/*
+		 * use EIAM to auto-mask when MSI-X interrupt is asserted
+		 * this saves a register write for every interrupt
+		 */
+		switch (hw->mac.type) {
+		case ixgbe_mac_82598EB:
+			IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
+			break;
+		default:
+		case ixgbe_mac_82599EB:
+			IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF);
+			IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF);
+			break;
+		}
+	} else {
 		/* legacy interrupts, use EIAM to auto-mask when reading EICR,
 		 * specifically only auto mask tx and rx interrupts */
 		IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
@@ -3632,10 +3667,10 @@ static int ixgbe_set_interrupt_capabilit
 	 * It's easy to be greedy for MSI-X vectors, but it really
 	 * doesn't do us much good if we have a lot more vectors
 	 * than CPU's.  So let's be conservative and only ask for
-	 * (roughly) twice the number of vectors as there are CPU's.
+	 * (roughly) the same number of vectors as there are CPU's.
 	 */
 	v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
-	               (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+	               (int)num_online_cpus()) + NON_Q_VECTORS;
 
 	/*
 	 * At the same time, hardware can only support a maximum of
@@ -3943,8 +3978,10 @@ static int __devinit ixgbe_sw_init(struc
 		adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
 		adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
 		adapter->ring_feature[RING_F_FCOE].indices = 0;
+#ifdef CONFIG_IXGBE_DCB
 		/* Default traffic class to use for FCoE */
 		adapter->fcoe.tc = IXGBE_FCOE_DEFTC;
+#endif
 #endif /* IXGBE_FCOE */
 	}
 
@@ -4341,6 +4378,11 @@ static int ixgbe_resume(struct pci_dev *
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+	/*
+	 * pci_restore_state clears dev->state_saved so call
+	 * pci_save_state to restore it.
+	 */
+	pci_save_state(pdev);
 
 	err = pci_enable_device_mem(pdev);
 	if (err) {
@@ -4475,20 +4517,35 @@ static void ixgbe_shutdown(struct pci_de
  **/
 void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u64 total_mpc = 0;
 	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
+	u64 non_eop_descs = 0, restart_queue = 0;
 
-	if (hw->mac.type == ixgbe_mac_82599EB) {
+	if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
 		u64 rsc_count = 0;
+		u64 rsc_flush = 0;
 		for (i = 0; i < 16; i++)
 			adapter->hw_rx_no_dma_resources +=
 			                     IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
-		for (i = 0; i < adapter->num_rx_queues; i++)
+		for (i = 0; i < adapter->num_rx_queues; i++) {
 			rsc_count += adapter->rx_ring[i].rsc_count;
-		adapter->rsc_count = rsc_count;
+			rsc_flush += adapter->rx_ring[i].rsc_flush;
+		}
+		adapter->rsc_total_count = rsc_count;
+		adapter->rsc_total_flush = rsc_flush;
 	}
 
+	/* gather some stats to the adapter struct that are per queue */
+	for (i = 0; i < adapter->num_tx_queues; i++)
+		restart_queue += adapter->tx_ring[i].restart_queue;
+	adapter->restart_queue = restart_queue;
+
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		non_eop_descs += adapter->rx_ring[i].non_eop_descs;
+	adapter->non_eop_descs = non_eop_descs;
+
 	adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
 	for (i = 0; i < 8; i++) {
 		/* for packet buffers not used, the register should read 0 */
@@ -4594,15 +4651,15 @@ void ixgbe_update_stats(struct ixgbe_ada
 	adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.multicast = adapter->stats.mprc;
+	netdev->stats.multicast = adapter->stats.mprc;
 
 	/* Rx Errors */
-	adapter->net_stats.rx_errors = adapter->stats.crcerrs +
+	netdev->stats.rx_errors = adapter->stats.crcerrs +
 	                               adapter->stats.rlec;
-	adapter->net_stats.rx_dropped = 0;
-	adapter->net_stats.rx_length_errors = adapter->stats.rlec;
-	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_missed_errors = total_mpc;
+	netdev->stats.rx_dropped = 0;
+	netdev->stats.rx_length_errors = adapter->stats.rlec;
+	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+	netdev->stats.rx_missed_errors = total_mpc;
 }
 
 /**
@@ -4871,14 +4928,12 @@ static int ixgbe_tso(struct ixgbe_adapte
 			                                         iph->daddr, 0,
 			                                         IPPROTO_TCP,
 			                                         0);
-			adapter->hw_tso_ctxt++;
-		} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+		} else if (skb_is_gso_v6(skb)) {
 			ipv6_hdr(skb)->payload_len = 0;
 			tcp_hdr(skb)->check =
 			    ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
 			                     &ipv6_hdr(skb)->daddr,
 			                     0, IPPROTO_TCP, 0);
-			adapter->hw_tso6_ctxt++;
 		}
 
 		i = tx_ring->next_to_use;
@@ -4961,7 +5016,18 @@ static bool ixgbe_tx_csum(struct ixgbe_a
 		                    IXGBE_ADVTXD_DTYP_CTXT);
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
-			switch (skb->protocol) {
+			__be16 protocol;
+
+			if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+				const struct vlan_ethhdr *vhdr =
+					(const struct vlan_ethhdr *)skb->data;
+
+				protocol = vhdr->h_vlan_encapsulated_proto;
+			} else {
+				protocol = skb->protocol;
+			}
+
+			switch (protocol) {
 			case cpu_to_be16(ETH_P_IP):
 				type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
 				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
@@ -4997,7 +5063,6 @@ static bool ixgbe_tx_csum(struct ixgbe_a
 		tx_buffer_info->time_stamp = jiffies;
 		tx_buffer_info->next_to_watch = i;
 
-		adapter->hw_csum_tx_good++;
 		i++;
 		if (i == tx_ring->count)
 			i = 0;
@@ -5014,23 +5079,16 @@ static int ixgbe_tx_map(struct ixgbe_ada
                         struct sk_buff *skb, u32 tx_flags,
                         unsigned int first)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	struct ixgbe_tx_buffer *tx_buffer_info;
 	unsigned int len;
 	unsigned int total = skb->len;
 	unsigned int offset = 0, size, count = 0, i;
 	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
 	unsigned int f;
-	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
-	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
-		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-		return 0;
-	}
-
-	map = skb_shinfo(skb)->dma_maps;
-
 	if (tx_flags & IXGBE_TX_FLAGS_FCOE)
 		/* excluding fcoe_crc_eof for FCoE */
 		total -= sizeof(struct fcoe_crc_eof);
@@ -5041,7 +5099,12 @@ static int ixgbe_tx_map(struct ixgbe_ada
 		size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 		tx_buffer_info->length = size;
-		tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
+		tx_buffer_info->mapped_as_page = false;
+		tx_buffer_info->dma = pci_map_single(pdev,
+						     skb->data + offset,
+						     size, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, tx_buffer_info->dma))
+			goto dma_error;
 		tx_buffer_info->time_stamp = jiffies;
 		tx_buffer_info->next_to_watch = i;
 
@@ -5062,7 +5125,7 @@ static int ixgbe_tx_map(struct ixgbe_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = min((unsigned int)frag->size, total);
-		offset = 0;
+		offset = frag->page_offset;
 
 		while (len) {
 			i++;
@@ -5073,7 +5136,13 @@ static int ixgbe_tx_map(struct ixgbe_ada
 			size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 			tx_buffer_info->length = size;
-			tx_buffer_info->dma = map[f] + offset;
+			tx_buffer_info->dma = pci_map_page(adapter->pdev,
+							   frag->page,
+							   offset, size,
+							   PCI_DMA_TODEVICE);
+			tx_buffer_info->mapped_as_page = true;
+			if (pci_dma_mapping_error(pdev, tx_buffer_info->dma))
+				goto dma_error;
 			tx_buffer_info->time_stamp = jiffies;
 			tx_buffer_info->next_to_watch = i;
 
@@ -5090,6 +5159,27 @@ static int ixgbe_tx_map(struct ixgbe_ada
 	tx_ring->tx_buffer_info[first].next_to_watch = i;
 
 	return count;
+
+dma_error:
+	dev_err(&pdev->dev, "TX DMA map failed\n");
+
+	/* clear timestamp and dma mappings for failed tx_buffer_info map */
+	tx_buffer_info->dma = 0;
+	tx_buffer_info->time_stamp = 0;
+	tx_buffer_info->next_to_watch = 0;
+	if (count)
+		count--;
+
+	/* clear timestamp and dma mappings for remaining portion of packet */
+	while (count--) {
+		if (i==0)
+			i += tx_ring->count;
+		i--;
+		tx_buffer_info = &tx_ring->tx_buffer_info[i];
+		ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+	}
+
+	return 0;
 }
 
 static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
@@ -5209,8 +5299,6 @@ static void ixgbe_atr(struct ixgbe_adapt
 static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
                                  struct ixgbe_ring *tx_ring, int size)
 {
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
 	netif_stop_subqueue(netdev, tx_ring->queue_index);
 	/* Herbert's original patch had:
 	 *  smp_mb__after_netif_stop_queue();
@@ -5224,7 +5312,7 @@ static int __ixgbe_maybe_stop_tx(struct
 
 	/* A reprieve! - use start_queue because it doesn't call schedule */
 	netif_start_subqueue(netdev, tx_ring->queue_index);
-	++adapter->restart_queue;
+	++tx_ring->restart_queue;
 	return 0;
 }
 
@@ -5239,10 +5327,22 @@ static int ixgbe_maybe_stop_tx(struct ne
 static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	int txq = smp_processor_id();
 
-	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)
-		return smp_processor_id();
+	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
+		while (unlikely(txq >= dev->real_num_tx_queues))
+			txq -= dev->real_num_tx_queues;
+		return txq;
+	}
 
+#ifdef IXGBE_FCOE
+	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+	    (skb->protocol == htons(ETH_P_FCOE))) {
+		txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
+		txq += adapter->ring_feature[RING_F_FCOE].mask;
+		return txq;
+	}
+#endif
 	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
 		return (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK) >> 13;
 
@@ -5254,10 +5354,11 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_ring *tx_ring;
+	struct netdev_queue *txq;
 	unsigned int first;
 	unsigned int tx_flags = 0;
 	u8 hdr_len = 0;
-	int r_idx = 0, tso;
+	int tso;
 	int count = 0;
 	unsigned int f;
 
@@ -5265,13 +5366,13 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 		tx_flags |= vlan_tx_tag_get(skb);
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 			tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
-			tx_flags |= (skb->queue_mapping << 13);
+			tx_flags |= ((skb->queue_mapping & 0x7) << 13);
 		}
 		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 	} else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 		if (skb->priority != TC_PRIO_CONTROL) {
-			tx_flags |= (skb->queue_mapping << 13);
+			tx_flags |= ((skb->queue_mapping & 0x7) << 13);
 			tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 			tx_flags |= IXGBE_TX_FLAGS_VLAN;
 		} else {
@@ -5280,17 +5381,18 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 		}
 	}
 
-	r_idx = skb->queue_mapping;
-	tx_ring = &adapter->tx_ring[r_idx];
+	tx_ring = &adapter->tx_ring[skb->queue_mapping];
 
 	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
 	    (skb->protocol == htons(ETH_P_FCOE))) {
 		tx_flags |= IXGBE_TX_FLAGS_FCOE;
 #ifdef IXGBE_FCOE
-		r_idx = smp_processor_id();
-		r_idx &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
-		r_idx += adapter->ring_feature[RING_F_FCOE].mask;
-		tx_ring = &adapter->tx_ring[r_idx];
+#ifdef CONFIG_IXGBE_DCB
+		tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
+			      << IXGBE_TX_FLAGS_VLAN_SHIFT);
+		tx_flags |= ((adapter->fcoe.up << 13)
+			      << IXGBE_TX_FLAGS_VLAN_SHIFT);
+#endif
 #endif
 	}
 	/* four things can cause us to need a context descriptor */
@@ -5350,6 +5452,9 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 				tx_ring->atr_count = 0;
 			}
 		}
+		txq = netdev_get_tx_queue(netdev, tx_ring->queue_index);
+		txq->tx_bytes += skb->len;
+		txq->tx_packets++;
 		ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
 		               hdr_len);
 		ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
@@ -5364,21 +5469,6 @@ static netdev_tx_t ixgbe_xmit_frame(stru
 }
 
 /**
- * ixgbe_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- **/
-static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	/* only return the current stats */
-	return &adapter->net_stats;
-}
-
-/**
  * ixgbe_set_mac - Change the Ethernet Address of the NIC
  * @netdev: network interface device structure
  * @p: pointer to an address structure
@@ -5489,6 +5579,10 @@ static void ixgbe_netpoll(struct net_dev
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	int i;
 
+	/* if interface is down do nothing */
+	if (test_bit(__IXGBE_DOWN, &adapter->state))
+		return;
+
 	adapter->flags |= IXGBE_FLAG_IN_NETPOLL;
 	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
 		int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -5508,7 +5602,6 @@ static const struct net_device_ops ixgbe
 	.ndo_stop		= ixgbe_close,
 	.ndo_start_xmit		= ixgbe_xmit_frame,
 	.ndo_select_queue	= ixgbe_select_queue,
-	.ndo_get_stats		= ixgbe_get_stats,
 	.ndo_set_rx_mode        = ixgbe_set_rx_mode,
 	.ndo_set_multicast_list	= ixgbe_set_rx_mode,
 	.ndo_validate_addr	= eth_validate_addr,
@@ -5527,6 +5620,7 @@ static const struct net_device_ops ixgbe
 	.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
 	.ndo_fcoe_enable = ixgbe_fcoe_enable,
 	.ndo_fcoe_disable = ixgbe_fcoe_disable,
+	.ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn,
 #endif /* IXGBE_FCOE */
 };
 
@@ -5669,6 +5763,10 @@ static int __devinit ixgbe_probe(struct
 	if (err)
 		goto err_sw_init;
 
+	/* Make it possible the adapter to be woken up via WOL */
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
+
 	/*
 	 * If there is a fan on this device and it has failed log the
 	 * failure.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_phy.c linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_phy.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_phy.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_phy.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_phy.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_type.h linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_type.h
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/ixgbe_type.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/ixgbe_type.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 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,
@@ -50,8 +50,10 @@
 #define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
 #define IXGBE_DEV_ID_82599_KX4           0x10F7
 #define IXGBE_DEV_ID_82599_KX4_MEZZ      0x1514
+#define IXGBE_DEV_ID_82599_KR            0x1517
 #define IXGBE_DEV_ID_82599_CX4           0x10F9
 #define IXGBE_DEV_ID_82599_SFP           0x10FB
+#define IXGBE_DEV_ID_82599_SFP_EM        0x1507
 #define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
 
@@ -839,6 +841,8 @@
 #define IXGBE_MPVC      0x04318
 #define IXGBE_SGMIIC    0x04314
 
+#define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50
+
 /* Omer CORECTL */
 #define IXGBE_CORECTL           0x014F00
 /* BARCTRL */
@@ -1538,6 +1542,16 @@
 #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR   0x4
 #define IXGBE_FW_PATCH_VERSION_4   0x7
 
+/* Alternative SAN MAC Address Block */
+#define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR      0x27 /* Alt. SAN MAC block */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET  0x0 /* Alt. SAN MAC capability */
+#define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_PORT1_OFFSET 0x4 /* Alt. SAN MAC 1 offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET  0x7 /* Alt. WWNN prefix offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET  0x8 /* Alt. WWPN prefix offset */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_SANMAC  0x0 /* Alt. SAN MAC exists */
+#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN  0x1 /* Alt. WWN base exists */
+
 /* PCI Bus Info */
 #define IXGBE_PCI_LINK_STATUS     0xB2
 #define IXGBE_PCI_DEVICE_CONTROL2 0xC8
@@ -2171,6 +2185,14 @@ enum ixgbe_fc_mode {
 	ixgbe_fc_default
 };
 
+/* Smart Speed Settings */
+#define IXGBE_SMARTSPEED_MAX_RETRIES	3
+enum ixgbe_smart_speed {
+	ixgbe_smart_speed_auto = 0,
+	ixgbe_smart_speed_on,
+	ixgbe_smart_speed_off
+};
+
 /* PCI bus types */
 enum ixgbe_bus_type {
 	ixgbe_bus_type_unknown = 0,
@@ -2336,6 +2358,7 @@ struct ixgbe_mac_operations {
 	s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
 	s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
 	s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
+	s32 (*get_wwn_prefix)(struct ixgbe_hw *, u16 *, u16 *);
 	s32 (*stop_adapter)(struct ixgbe_hw *);
 	s32 (*get_bus_info)(struct ixgbe_hw *);
 	void (*set_lan_id)(struct ixgbe_hw *);
@@ -2407,6 +2430,10 @@ struct ixgbe_mac_info {
 	u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
 	u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
 	u8                              san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+	/* prefix for World Wide Node Name (WWNN) */
+	u16                             wwnn_prefix;
+	/* prefix for World Wide Port Name (WWPN) */
+	u16                             wwpn_prefix;
 	s32                             mc_filter_type;
 	u32                             mcft_size;
 	u32                             vft_size;
@@ -2431,6 +2458,8 @@ struct ixgbe_phy_info {
 	enum ixgbe_media_type           media_type;
 	bool                            reset_disable;
 	ixgbe_autoneg_advertised        autoneg_advertised;
+	enum ixgbe_smart_speed          smart_speed;
+	bool                            smart_speed_active;
 	bool                            multispeed_fiber;
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixgbe/Makefile linux-libre-2.6.33-gnu1/drivers/net/ixgbe/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/ixgbe/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixgbe/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2009 Intel Corporation.
+# Copyright(c) 1999 - 2010 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,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ixp2000/ixpdev.c linux-libre-2.6.33-gnu1/drivers/net/ixp2000/ixpdev.c
--- linux-libre-2.6.32-gnu1/drivers/net/ixp2000/ixpdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ixp2000/ixpdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,9 +109,8 @@ static int ixpdev_rx(struct net_device *
 		if (unlikely(!netif_running(nds[desc->channel])))
 			goto err;
 
-		skb = netdev_alloc_skb(dev, desc->pkt_length + 2);
+		skb = netdev_alloc_skb_ip_align(dev, desc->pkt_length);
 		if (likely(skb != NULL)) {
-			skb_reserve(skb, 2);
 			skb_copy_to_linear_data(skb, buf, desc->pkt_length);
 			skb_put(skb, desc->pkt_length);
 			skb->protocol = eth_type_trans(skb, nds[desc->channel]);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/jazzsonic.c linux-libre-2.6.33-gnu1/drivers/net/jazzsonic.c
--- linux-libre-2.6.32-gnu1/drivers/net/jazzsonic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/jazzsonic.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ static unsigned short known_revisions[]
 
 static int jazzsonic_open(struct net_device* dev)
 {
-	if (request_irq(dev->irq, &sonic_interrupt, IRQF_DISABLED, "sonic", dev)) {
+	if (request_irq(dev->irq, sonic_interrupt, IRQF_DISABLED, "sonic", dev)) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
@@ -130,8 +130,8 @@ static int __devinit sonic_probe1(struct
 		printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
 
 	i = 0;
-	while (known_revisions[i] != 0xffff
-	       && known_revisions[i] != silicon_revision)
+	while (known_revisions[i] != 0xffff &&
+	       known_revisions[i] != silicon_revision)
 		i++;
 
 	if (known_revisions[i] == 0xffff) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/jme.c linux-libre-2.6.33-gnu1/drivers/net/jme.c
--- linux-libre-2.6.32-gnu1/drivers/net/jme.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/jme.c	2010-02-24 13:52:17.000000000 -0500
@@ -1050,8 +1050,8 @@ jme_dynamic_pcc(struct jme_adapter *jme)
 
 	if ((NET_STAT(jme).rx_bytes - dpi->last_bytes) > PCC_P3_THRESHOLD)
 		jme_attempt_pcc(dpi, PCC_P3);
-	else if ((NET_STAT(jme).rx_packets - dpi->last_pkts) > PCC_P2_THRESHOLD
-	|| dpi->intr_cnt > PCC_INTR_THRESHOLD)
+	else if ((NET_STAT(jme).rx_packets - dpi->last_pkts) > PCC_P2_THRESHOLD ||
+		 dpi->intr_cnt > PCC_INTR_THRESHOLD)
 		jme_attempt_pcc(dpi, PCC_P2);
 	else
 		jme_attempt_pcc(dpi, PCC_P1);
@@ -2199,8 +2199,8 @@ jme_set_coalesce(struct net_device *netd
 	if (netif_running(netdev))
 		return -EBUSY;
 
-	if (ecmd->use_adaptive_rx_coalesce
-	&& test_bit(JME_FLAG_POLL, &jme->flags)) {
+	if (ecmd->use_adaptive_rx_coalesce &&
+	    test_bit(JME_FLAG_POLL, &jme->flags)) {
 		clear_bit(JME_FLAG_POLL, &jme->flags);
 		jme->jme_rx = netif_rx;
 		jme->jme_vlan_rx = vlan_hwaccel_rx;
@@ -2209,8 +2209,8 @@ jme_set_coalesce(struct net_device *netd
 		dpi->cnt		= 0;
 		jme_set_rx_pcc(jme, PCC_P1);
 		jme_interrupt_mode(jme);
-	} else if (!(ecmd->use_adaptive_rx_coalesce)
-	&& !(test_bit(JME_FLAG_POLL, &jme->flags))) {
+	} else if (!(ecmd->use_adaptive_rx_coalesce) &&
+		   !(test_bit(JME_FLAG_POLL, &jme->flags))) {
 		set_bit(JME_FLAG_POLL, &jme->flags);
 		jme->jme_rx = netif_receive_skb;
 		jme->jme_vlan_rx = vlan_hwaccel_receive_skb;
@@ -2764,19 +2764,19 @@ jme_init_one(struct pci_dev *pdev,
 	atomic_set(&jme->rx_empty, 1);
 
 	tasklet_init(&jme->pcc_task,
-		     &jme_pcc_tasklet,
+		     jme_pcc_tasklet,
 		     (unsigned long) jme);
 	tasklet_init(&jme->linkch_task,
-		     &jme_link_change_tasklet,
+		     jme_link_change_tasklet,
 		     (unsigned long) jme);
 	tasklet_init(&jme->txclean_task,
-		     &jme_tx_clean_tasklet,
+		     jme_tx_clean_tasklet,
 		     (unsigned long) jme);
 	tasklet_init(&jme->rxclean_task,
-		     &jme_rx_clean_tasklet,
+		     jme_rx_clean_tasklet,
 		     (unsigned long) jme);
 	tasklet_init(&jme->rxempty_task,
-		     &jme_rx_empty_tasklet,
+		     jme_rx_empty_tasklet,
 		     (unsigned long) jme);
 	tasklet_disable_nosync(&jme->linkch_task);
 	tasklet_disable_nosync(&jme->txclean_task);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/Kconfig linux-libre-2.6.33-gnu1/drivers/net/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1001,7 +1001,7 @@ config SMC911X
 
 config SMSC911X
 	tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
-	depends on ARM || SUPERH || BLACKFIN
+	depends on ARM || SUPERH || BLACKFIN || MIPS
 	select CRC32
 	select MII
 	select PHYLIB
@@ -1953,6 +1953,8 @@ config BCM63XX_ENET
 
 source "drivers/net/fs_enet/Kconfig"
 
+source "drivers/net/octeon/Kconfig"
+
 endif # NET_ETHERNET
 
 #
@@ -2344,6 +2346,7 @@ config GELIC_NET
 
 config GELIC_WIRELESS
 	bool "PS3 Wireless support"
+	depends on WLAN
 	depends on GELIC_NET
 	select WIRELESS_EXT
 	help
@@ -2356,6 +2359,7 @@ config GELIC_WIRELESS
 config GELIC_WIRELESS_OLD_PSK_INTERFACE
        bool "PS3 Wireless private PSK interface (OBSOLETE)"
        depends on GELIC_WIRELESS
+       select WEXT_PRIV
        help
           This option retains the obsolete private interface to pass
           the PSK from user space programs to the driver.  The PSK
@@ -2696,6 +2700,7 @@ config NETXEN_NIC
 config NIU
 	tristate "Sun Neptune 10Gbit Ethernet support"
 	depends on PCI
+	select CRC32
 	help
 	  This enables support for cards based upon Sun's
 	  Neptune chipset.
@@ -3235,7 +3240,7 @@ config VIRTIO_NET
 
 config VMXNET3
        tristate "VMware VMXNET3 ethernet driver"
-       depends on PCI && X86 && INET
+       depends on PCI && INET
        help
          This driver supports VMware's vmxnet3 virtual ethernet NIC.
          To compile this driver as a module, choose M here: the
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/korina.c linux-libre-2.6.33-gnu1/drivers/net/korina.c
--- linux-libre-2.6.32-gnu1/drivers/net/korina.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/korina.c	2010-02-24 13:52:17.000000000 -0500
@@ -400,7 +400,7 @@ static int korina_rx(struct net_device *
 			dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4);
 
 			/* Malloc up new buffer. */
-			skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2);
+			skb_new = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE);
 
 			if (!skb_new)
 				break;
@@ -417,9 +417,6 @@ static int korina_rx(struct net_device *
 			if (devcs & ETH_RX_MP)
 				dev->stats.multicast++;
 
-			/* 16 bit align */
-			skb_reserve(skb_new, 2);
-
 			lp->rx_skb[lp->rx_next_done] = skb_new;
 		}
 
@@ -1017,14 +1014,14 @@ static int korina_open(struct net_device
 	/* Install the interrupt handler
 	 * that handles the Done Finished
 	 * Ovr and Und Events */
-	ret = request_irq(lp->rx_irq, &korina_rx_dma_interrupt,
+	ret = request_irq(lp->rx_irq, korina_rx_dma_interrupt,
 			IRQF_DISABLED, "Korina ethernet Rx", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get Rx DMA IRQ %d\n",
 		    dev->name, lp->rx_irq);
 		goto err_release;
 	}
-	ret = request_irq(lp->tx_irq, &korina_tx_dma_interrupt,
+	ret = request_irq(lp->tx_irq, korina_tx_dma_interrupt,
 			IRQF_DISABLED, "Korina ethernet Tx", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get Tx DMA IRQ %d\n",
@@ -1033,7 +1030,7 @@ static int korina_open(struct net_device
 	}
 
 	/* Install handler for overrun error. */
-	ret = request_irq(lp->ovr_irq, &korina_ovr_interrupt,
+	ret = request_irq(lp->ovr_irq, korina_ovr_interrupt,
 			IRQF_DISABLED, "Ethernet Overflow", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get OVR IRQ %d\n",
@@ -1042,7 +1039,7 @@ static int korina_open(struct net_device
 	}
 
 	/* Install handler for underflow error. */
-	ret = request_irq(lp->und_irq, &korina_und_interrupt,
+	ret = request_irq(lp->und_irq, korina_und_interrupt,
 			IRQF_DISABLED, "Ethernet Underflow", dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: unable to get UND IRQ %d\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ks8842.c linux-libre-2.6.33-gnu1/drivers/net/ks8842.c
--- linux-libre-2.6.32-gnu1/drivers/net/ks8842.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ks8842.c	2010-02-24 13:52:17.000000000 -0500
@@ -357,7 +357,7 @@ static void ks8842_rx_frame(struct net_d
 
 	/* check the status */
 	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
-		struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2);
+		struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len);
 
 		dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
 			__func__, len);
@@ -369,9 +369,6 @@ static void ks8842_rx_frame(struct net_d
 			if (status & RXSR_MULTICAST)
 				netdev->stats.multicast++;
 
-			/* Align socket buffer in 4-byte boundary for
-				 better performance. */
-			skb_reserve(skb, 2);
 			data = (u32 *)skb_put(skb, len);
 
 			ks8842_select_bank(adapter, 17);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ks8851.c linux-libre-2.6.33-gnu1/drivers/net/ks8851.c
--- linux-libre-2.6.32-gnu1/drivers/net/ks8851.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ks8851.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,4 +1,4 @@
-/* drivers/net/ks8651.c
+/* drivers/net/ks8851.c
  *
  * Copyright 2009 Simtec Electronics
  *	http://www.simtec.co.uk/
@@ -714,7 +714,7 @@ static void ks8851_tx_work(struct work_s
 {
 	struct ks8851_net *ks = container_of(work, struct ks8851_net, tx_work);
 	struct sk_buff *txb;
-	bool last = false;
+	bool last = skb_queue_empty(&ks->txq);
 
 	mutex_lock(&ks->lock);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ks8851_mll.c linux-libre-2.6.33-gnu1/drivers/net/ks8851_mll.c
--- linux-libre-2.6.32-gnu1/drivers/net/ks8851_mll.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ks8851_mll.c	2010-02-24 13:52:17.000000000 -0500
@@ -854,8 +854,8 @@ static void ks_update_link_status(struct
 
 static irqreturn_t ks_irq(int irq, void *pw)
 {
-	struct ks_net *ks = pw;
-	struct net_device *netdev = ks->netdev;
+	struct net_device *netdev = pw;
+	struct ks_net *ks = netdev_priv(netdev);
 	u16 status;
 
 	/*this should be the first in IRQ handler */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/lance.c linux-libre-2.6.33-gnu1/drivers/net/lance.c
--- linux-libre-2.6.32-gnu1/drivers/net/lance.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/lance.c	2010-02-24 13:52:17.000000000 -0500
@@ -493,14 +493,14 @@ static int __init lance_probe1(struct ne
 		static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
 		int hp_port = (readl(bios + 1) & 1)  ? 0x499 : 0x99;
 		/* We can have boards other than the built-in!  Verify this is on-board. */
-		if ((inb(hp_port) & 0xc0) == 0x80
-			&& ioaddr_table[inb(hp_port) & 3] == ioaddr)
+		if ((inb(hp_port) & 0xc0) == 0x80 &&
+		    ioaddr_table[inb(hp_port) & 3] == ioaddr)
 			hp_builtin = hp_port;
 	}
 	iounmap(bios);
 	/* We also recognize the HP Vectra on-board here, but check below. */
-	hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
-				&& inb(ioaddr+2) == 0x09);
+	hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00 &&
+		    inb(ioaddr+2) == 0x09);
 
 	/* Reset the LANCE.	 */
 	reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
@@ -755,7 +755,7 @@ lance_open(struct net_device *dev)
 	int i;
 
 	if (dev->irq == 0 ||
-		request_irq(dev->irq, &lance_interrupt, 0, lp->name, dev)) {
+		request_irq(dev->irq, lance_interrupt, 0, lp->name, dev)) {
 		return -EAGAIN;
 	}
 
@@ -1035,8 +1035,8 @@ static irqreturn_t lance_interrupt(int i
 	spin_lock (&lp->devlock);
 
 	outw(0x00, dev->base_addr + LANCE_ADDR);
-	while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600
-		   && --boguscnt >= 0) {
+	while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600 &&
+	       --boguscnt >= 0) {
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/lasi_82596.c linux-libre-2.6.33-gnu1/drivers/net/lasi_82596.c
--- linux-libre-2.6.32-gnu1/drivers/net/lasi_82596.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/lasi_82596.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/lib82596.c linux-libre-2.6.33-gnu1/drivers/net/lib82596.c
--- linux-libre-2.6.32-gnu1/drivers/net/lib82596.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/lib82596.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@
    TBD:
    * look at deferring rx frames rather than discarding (as per tulip)
    * handle tx ring full as per tulip
-   * performace test to tune rx_copybreak
+   * performance test to tune rx_copybreak
 
    Most of my modifications relate to the braindead big-endian
    implementation by Intel.  When the i596 is operating in
@@ -470,11 +470,11 @@ static inline int init_rx_bufs(struct ne
 
 	for (i = 0, rbd = dma->rbds; i < rx_ring_size; i++, rbd++) {
 		dma_addr_t dma_addr;
-		struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
+		struct sk_buff *skb;
 
+		skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ);
 		if (skb == NULL)
 			return -1;
-		skb_reserve(skb, 2);
 		dma_addr = dma_map_single(dev->dev.parent, skb->data,
 					  PKT_BUF_SZ, DMA_FROM_DEVICE);
 		rbd->v_next = rbd+1;
@@ -588,7 +588,7 @@ static int init_i596_mem(struct net_devi
 			     "%s: i82596 initialization successful\n",
 			     dev->name));
 
-	if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
+	if (request_irq(dev->irq, i596_interrupt, 0, "i82596", dev)) {
 		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
 		goto failed;
 	}
@@ -697,12 +697,12 @@ static inline int i596_rx(struct net_dev
 						 (dma_addr_t)SWAP32(rbd->b_data),
 						 PKT_BUF_SZ, DMA_FROM_DEVICE);
 				/* Get fresh skbuff to replace filled one. */
-				newskb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
+				newskb = netdev_alloc_skb_ip_align(dev,
+								   PKT_BUF_SZ);
 				if (newskb == NULL) {
 					skb = NULL;	/* drop pkt */
 					goto memory_squeeze;
 				}
-				skb_reserve(newskb, 2);
 
 				/* Pass up the skb already on the Rx ring. */
 				skb_put(skb, pkt_len);
@@ -716,7 +716,7 @@ static inline int i596_rx(struct net_dev
 				rbd->b_data = SWAP32(dma_addr);
 				DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
 			} else
-				skb = netdev_alloc_skb(dev, pkt_len + 2);
+				skb = netdev_alloc_skb_ip_align(dev, pkt_len);
 memory_squeeze:
 			if (skb == NULL) {
 				/* XXX tulip.c can defer packets here!! */
@@ -730,7 +730,6 @@ memory_squeeze:
 					dma_sync_single_for_cpu(dev->dev.parent,
 								(dma_addr_t)SWAP32(rbd->b_data),
 								PKT_BUF_SZ, DMA_FROM_DEVICE);
-					skb_reserve(skb, 2);
 					memcpy(skb_put(skb, pkt_len), rbd->v_data, pkt_len);
 					dma_sync_single_for_device(dev->dev.parent,
 								   (dma_addr_t)SWAP32(rbd->b_data),
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/lib8390.c linux-libre-2.6.33-gnu1/drivers/net/lib8390.c
--- linux-libre-2.6.32-gnu1/drivers/net/lib8390.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/lib8390.c	2010-02-24 13:52:17.000000000 -0500
@@ -464,8 +464,8 @@ static irqreturn_t __ei_interrupt(int ir
 			   ei_inb_p(e8390_base + EN0_ISR));
 
 	/* !!Assumption!! -- we stay in page 0.	 Don't break this. */
-	while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0
-		   && ++nr_serviced < MAX_SERVICE)
+	while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0 &&
+	       ++nr_serviced < MAX_SERVICE)
 	{
 		if (!netif_running(dev)) {
 			printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
@@ -721,10 +721,10 @@ static void ei_receive(struct net_device
 		/* Check for bogosity warned by 3c503 book: the status byte is never
 		   written.  This happened a lot during testing! This code should be
 		   cleaned up someday. */
-		if (rx_frame.next != next_frame
-			&& rx_frame.next != next_frame + 1
-			&& rx_frame.next != next_frame - num_rx_pages
-			&& rx_frame.next != next_frame + 1 - num_rx_pages) {
+		if (rx_frame.next != next_frame &&
+		    rx_frame.next != next_frame + 1 &&
+		    rx_frame.next != next_frame - num_rx_pages &&
+		    rx_frame.next != next_frame + 1 - num_rx_pages) {
 			ei_local->current_page = rxing_page;
 			ei_outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
 			dev->stats.rx_errors++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ll_temac_main.c linux-libre-2.6.33-gnu1/drivers/net/ll_temac_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/ll_temac_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ll_temac_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -134,7 +134,7 @@ static int temac_dma_bd_init(struct net_
 	struct sk_buff *skb;
 	int i;
 
-	lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+	lp->rx_skb = kzalloc(sizeof(*lp->rx_skb) * RX_BD_NUM, GFP_KERNEL);
 	/* allocate the tx and rx ring buffer descriptors. */
 	/* returns a virtual addres and a physical address. */
 	lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
@@ -231,8 +231,8 @@ static void temac_set_multicast_list(str
 	int i;
 
 	mutex_lock(&lp->indirect_mutex);
-	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)
-			|| ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
+	    ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
 		/*
 		 *	We must make the kernel realise we had to move
 		 *	into promisc mode or we start all out war on
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/loopback.c linux-libre-2.6.33-gnu1/drivers/net/loopback.c
--- linux-libre-2.6.32-gnu1/drivers/net/loopback.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/loopback.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ static netdev_tx_t loopback_xmit(struct
 
 	/* it's OK to use per_cpu_ptr() because BHs are off */
 	pcpu_lstats = dev->ml_priv;
-	lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
+	lb_stats = this_cpu_ptr(pcpu_lstats);
 
 	len = skb->len;
 	if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
@@ -207,20 +207,12 @@ static __net_init int loopback_net_init(
 out_free_netdev:
 	free_netdev(dev);
 out:
-	if (net == &init_net)
+	if (net_eq(net, &init_net))
 		panic("loopback: Failed to register netdevice: %d\n", err);
 	return err;
 }
 
-static __net_exit void loopback_net_exit(struct net *net)
-{
-	struct net_device *dev = net->loopback_dev;
-
-	unregister_netdev(dev);
-}
-
 /* Registered in net/core/dev.c */
 struct pernet_operations __net_initdata loopback_net_ops = {
        .init = loopback_net_init,
-       .exit = loopback_net_exit,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/lp486e.c linux-libre-2.6.33-gnu1/drivers/net/lp486e.c
--- linux-libre-2.6.32-gnu1/drivers/net/lp486e.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/lp486e.c	2010-02-24 13:52:17.000000000 -0500
@@ -845,7 +845,7 @@ static int i596_open(struct net_device *
 {
 	int i;
 
-	i = request_irq(dev->irq, &i596_interrupt, IRQF_SHARED, dev->name, dev);
+	i = request_irq(dev->irq, i596_interrupt, IRQF_SHARED, dev->name, dev);
 	if (i) {
 		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
 		return i;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mac89x0.c linux-libre-2.6.33-gnu1/drivers/net/mac89x0.c
--- linux-libre-2.6.32-gnu1/drivers/net/mac89x0.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mac89x0.c	2010-02-24 13:52:17.000000000 -0500
@@ -222,8 +222,8 @@ struct net_device * __init mac89x0_probe
 		int card_present;
 
 		local_irq_save(flags);
-		card_present = hwreg_present((void*) ioaddr+4)
-		  && hwreg_present((void*) ioaddr + DATA_PORT);
+		card_present = (hwreg_present((void*) ioaddr+4) &&
+				hwreg_present((void*) ioaddr + DATA_PORT));
 		local_irq_restore(flags);
 
 		if (!card_present)
@@ -337,7 +337,7 @@ net_open(struct net_device *dev)
 	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
 
 	/* Grab the interrupt */
-	if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", dev))
+	if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
 		return -EAGAIN;
 
 	/* Set up the IRQ - Apparently magic */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mace.c linux-libre-2.6.33-gnu1/drivers/net/mace.c
--- linux-libre-2.6.32-gnu1/drivers/net/mace.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mace.c	2010-02-24 13:52:17.000000000 -0500
@@ -897,8 +897,8 @@ static irqreturn_t mace_rxdma_intr(int i
 	    if (next >= N_RX_RING)
 		next = 0;
 	    np = mp->rx_cmds + next;
-	    if (next != mp->rx_fill
-		&& (ld_le16(&np->xfer_status) & ACTIVE) != 0) {
+	    if (next != mp->rx_fill &&
+		(ld_le16(&np->xfer_status) & ACTIVE) != 0) {
 		printk(KERN_DEBUG "mace: lost a status word\n");
 		++mace_lost_status;
 	    } else
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/macsonic.c linux-libre-2.6.33-gnu1/drivers/net/macsonic.c
--- linux-libre-2.6.32-gnu1/drivers/net/macsonic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/macsonic.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,7 +140,7 @@ static irqreturn_t macsonic_interrupt(in
 
 static int macsonic_open(struct net_device* dev)
 {
-	if (request_irq(dev->irq, &sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
+	if (request_irq(dev->irq, sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
@@ -149,7 +149,7 @@ static int macsonic_open(struct net_devi
 	 * rupt as well, which must prevent re-entrance of the sonic handler.
 	 */
 	if (dev->irq == IRQ_AUTO_3)
-		if (request_irq(IRQ_NUBUS_9, &macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
+		if (request_irq(IRQ_NUBUS_9, macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
 			printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, IRQ_NUBUS_9);
 			free_irq(dev->irq, dev);
 			return -EAGAIN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/macvlan.c linux-libre-2.6.33-gnu1/drivers/net/macvlan.c
--- linux-libre-2.6.32-gnu1/drivers/net/macvlan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/macvlan.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,7 @@
 #include <linux/if_link.h>
 #include <linux/if_macvlan.h>
 #include <net/rtnetlink.h>
+#include <net/xfrm.h>
 
 #define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
 
@@ -38,12 +39,28 @@ struct macvlan_port {
 	struct list_head	vlans;
 };
 
+/**
+ *	struct macvlan_rx_stats - MACVLAN percpu rx stats
+ *	@rx_packets: number of received packets
+ *	@rx_bytes: number of received bytes
+ *	@multicast: number of received multicast packets
+ *	@rx_errors: number of errors
+ */
+struct macvlan_rx_stats {
+	unsigned long rx_packets;
+	unsigned long rx_bytes;
+	unsigned long multicast;
+	unsigned long rx_errors;
+};
+
 struct macvlan_dev {
 	struct net_device	*dev;
 	struct list_head	list;
 	struct hlist_node	hlist;
 	struct macvlan_port	*port;
 	struct net_device	*lowerdev;
+	struct macvlan_rx_stats *rx_stats;
+	enum macvlan_mode	mode;
 };
 
 
@@ -101,41 +118,67 @@ static int macvlan_addr_busy(const struc
 	return 0;
 }
 
+static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
+				    unsigned int len, bool success,
+				    bool multicast)
+{
+	struct macvlan_rx_stats *rx_stats;
+
+	rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
+	if (likely(success)) {
+		rx_stats->rx_packets++;;
+		rx_stats->rx_bytes += len;
+		if (multicast)
+			rx_stats->multicast++;
+	} else {
+		rx_stats->rx_errors++;
+	}
+}
+
+static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
+				 const struct ethhdr *eth, bool local)
+{
+	if (!skb)
+		return NET_RX_DROP;
+
+	if (local)
+		return dev_forward_skb(dev, skb);
+
+	skb->dev = dev;
+	if (!compare_ether_addr_64bits(eth->h_dest,
+				       dev->broadcast))
+		skb->pkt_type = PACKET_BROADCAST;
+	else
+		skb->pkt_type = PACKET_MULTICAST;
+
+	return netif_rx(skb);
+}
+
 static void macvlan_broadcast(struct sk_buff *skb,
-			      const struct macvlan_port *port)
+			      const struct macvlan_port *port,
+			      struct net_device *src,
+			      enum macvlan_mode mode)
 {
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_dev *vlan;
 	struct hlist_node *n;
-	struct net_device *dev;
 	struct sk_buff *nskb;
 	unsigned int i;
+	int err;
 
 	if (skb->protocol == htons(ETH_P_PAUSE))
 		return;
 
 	for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
 		hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
-			dev = vlan->dev;
-
-			nskb = skb_clone(skb, GFP_ATOMIC);
-			if (nskb == NULL) {
-				dev->stats.rx_errors++;
-				dev->stats.rx_dropped++;
+			if (vlan->dev == src || !(vlan->mode & mode))
 				continue;
-			}
 
-			dev->stats.rx_bytes += skb->len + ETH_HLEN;
-			dev->stats.rx_packets++;
-			dev->stats.multicast++;
-
-			nskb->dev = dev;
-			if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
-				nskb->pkt_type = PACKET_BROADCAST;
-			else
-				nskb->pkt_type = PACKET_MULTICAST;
-
-			netif_rx(nskb);
+			nskb = skb_clone(skb, GFP_ATOMIC);
+			err = macvlan_broadcast_one(nskb, vlan->dev, eth,
+					 mode == MACVLAN_MODE_BRIDGE);
+			macvlan_count_rx(vlan, skb->len + ETH_HLEN,
+					 err == NET_RX_SUCCESS, 1);
 		}
 	}
 }
@@ -146,14 +189,34 @@ static struct sk_buff *macvlan_handle_fr
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_port *port;
 	const struct macvlan_dev *vlan;
+	const struct macvlan_dev *src;
 	struct net_device *dev;
+	unsigned int len;
 
 	port = rcu_dereference(skb->dev->macvlan_port);
 	if (port == NULL)
 		return skb;
 
 	if (is_multicast_ether_addr(eth->h_dest)) {
-		macvlan_broadcast(skb, port);
+		src = macvlan_hash_lookup(port, eth->h_source);
+		if (!src)
+			/* frame comes from an external address */
+			macvlan_broadcast(skb, port, NULL,
+					  MACVLAN_MODE_PRIVATE |
+					  MACVLAN_MODE_VEPA    |
+					  MACVLAN_MODE_BRIDGE);
+		else if (src->mode == MACVLAN_MODE_VEPA)
+			/* flood to everyone except source */
+			macvlan_broadcast(skb, port, src->dev,
+					  MACVLAN_MODE_VEPA |
+					  MACVLAN_MODE_BRIDGE);
+		else if (src->mode == MACVLAN_MODE_BRIDGE)
+			/*
+			 * flood only to VEPA ports, bridge ports
+			 * already saw the frame on the way out.
+			 */
+			macvlan_broadcast(skb, port, src->dev,
+					  MACVLAN_MODE_VEPA);
 		return skb;
 	}
 
@@ -166,16 +229,11 @@ static struct sk_buff *macvlan_handle_fr
 		kfree_skb(skb);
 		return NULL;
 	}
-
+	len = skb->len + ETH_HLEN;
 	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (skb == NULL) {
-		dev->stats.rx_errors++;
-		dev->stats.rx_dropped++;
+	macvlan_count_rx(vlan, len, skb != NULL, 0);
+	if (!skb)
 		return NULL;
-	}
-
-	dev->stats.rx_bytes += skb->len + ETH_HLEN;
-	dev->stats.rx_packets++;
 
 	skb->dev = dev;
 	skb->pkt_type = PACKET_HOST;
@@ -184,25 +242,53 @@ static struct sk_buff *macvlan_handle_fr
 	return NULL;
 }
 
+static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	const struct macvlan_dev *vlan = netdev_priv(dev);
+	const struct macvlan_port *port = vlan->port;
+	const struct macvlan_dev *dest;
+
+	if (vlan->mode == MACVLAN_MODE_BRIDGE) {
+		const struct ethhdr *eth = (void *)skb->data;
+
+		/* send to other bridge ports directly */
+		if (is_multicast_ether_addr(eth->h_dest)) {
+			macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE);
+			goto xmit_world;
+		}
+
+		dest = macvlan_hash_lookup(port, eth->h_dest);
+		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
+			unsigned int length = skb->len + ETH_HLEN;
+			int ret = dev_forward_skb(dest->dev, skb);
+			macvlan_count_rx(dest, length,
+					 ret == NET_RX_SUCCESS, 0);
+
+			return NET_XMIT_SUCCESS;
+		}
+	}
+
+xmit_world:
+	skb->dev = vlan->lowerdev;
+	return dev_queue_xmit(skb);
+}
+
 static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
 	int i = skb_get_queue_mapping(skb);
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-	const struct macvlan_dev *vlan = netdev_priv(dev);
 	unsigned int len = skb->len;
 	int ret;
 
-	skb->dev = vlan->lowerdev;
-	ret = dev_queue_xmit(skb);
-
+	ret = macvlan_queue_xmit(skb, dev);
 	if (likely(ret == NET_XMIT_SUCCESS)) {
 		txq->tx_packets++;
 		txq->tx_bytes += len;
 	} else
 		txq->tx_dropped++;
 
-	return NETDEV_TX_OK;
+	return ret;
 }
 
 static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
@@ -366,9 +452,47 @@ static int macvlan_init(struct net_devic
 
 	macvlan_set_lockdep_class(dev);
 
+	vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats);
+	if (!vlan->rx_stats)
+		return -ENOMEM;
+
 	return 0;
 }
 
+static void macvlan_uninit(struct net_device *dev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	free_percpu(vlan->rx_stats);
+}
+
+static struct net_device_stats *macvlan_dev_get_stats(struct net_device *dev)
+{
+	struct net_device_stats *stats = &dev->stats;
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	dev_txq_stats_fold(dev, stats);
+
+	if (vlan->rx_stats) {
+		struct macvlan_rx_stats *p, rx = {0};
+		int i;
+
+		for_each_possible_cpu(i) {
+			p = per_cpu_ptr(vlan->rx_stats, i);
+			rx.rx_packets += p->rx_packets;
+			rx.rx_bytes   += p->rx_bytes;
+			rx.rx_errors  += p->rx_errors;
+			rx.multicast  += p->multicast;
+		}
+		stats->rx_packets = rx.rx_packets;
+		stats->rx_bytes   = rx.rx_bytes;
+		stats->rx_errors  = rx.rx_errors;
+		stats->rx_dropped = rx.rx_errors;
+		stats->multicast  = rx.multicast;
+	}
+	return stats;
+}
+
 static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
 					struct ethtool_drvinfo *drvinfo)
 {
@@ -405,6 +529,7 @@ static const struct ethtool_ops macvlan_
 
 static const struct net_device_ops macvlan_netdev_ops = {
 	.ndo_init		= macvlan_init,
+	.ndo_uninit		= macvlan_uninit,
 	.ndo_open		= macvlan_open,
 	.ndo_stop		= macvlan_stop,
 	.ndo_start_xmit		= macvlan_start_xmit,
@@ -412,6 +537,7 @@ static const struct net_device_ops macvl
 	.ndo_change_rx_flags	= macvlan_change_rx_flags,
 	.ndo_set_mac_address	= macvlan_set_mac_address,
 	.ndo_set_multicast_list	= macvlan_set_multicast_list,
+	.ndo_get_stats		= macvlan_dev_get_stats,
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
@@ -456,25 +582,6 @@ static void macvlan_port_destroy(struct
 	kfree(port);
 }
 
-static void macvlan_transfer_operstate(struct net_device *dev)
-{
-	struct macvlan_dev *vlan = netdev_priv(dev);
-	const struct net_device *lowerdev = vlan->lowerdev;
-
-	if (lowerdev->operstate == IF_OPER_DORMANT)
-		netif_dormant_on(dev);
-	else
-		netif_dormant_off(dev);
-
-	if (netif_carrier_ok(lowerdev)) {
-		if (!netif_carrier_ok(dev))
-			netif_carrier_on(dev);
-	} else {
-		if (netif_carrier_ok(dev))
-			netif_carrier_off(dev);
-	}
-}
-
 static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 {
 	if (tb[IFLA_ADDRESS]) {
@@ -483,6 +590,17 @@ static int macvlan_validate(struct nlatt
 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
 			return -EADDRNOTAVAIL;
 	}
+
+	if (data && data[IFLA_MACVLAN_MODE]) {
+		switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
+		case MACVLAN_MODE_PRIVATE:
+		case MACVLAN_MODE_VEPA:
+		case MACVLAN_MODE_BRIDGE:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
 	return 0;
 }
 
@@ -505,7 +623,7 @@ static int macvlan_get_tx_queues(struct
 	return 0;
 }
 
-static int macvlan_newlink(struct net_device *dev,
+static int macvlan_newlink(struct net *src_net, struct net_device *dev,
 			   struct nlattr *tb[], struct nlattr *data[])
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
@@ -516,7 +634,7 @@ static int macvlan_newlink(struct net_de
 	if (!tb[IFLA_LINK])
 		return -EINVAL;
 
-	lowerdev = __dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK]));
+	lowerdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
 	if (lowerdev == NULL)
 		return -ENODEV;
 
@@ -547,27 +665,61 @@ static int macvlan_newlink(struct net_de
 	vlan->dev      = dev;
 	vlan->port     = port;
 
+	vlan->mode     = MACVLAN_MODE_VEPA;
+	if (data && data[IFLA_MACVLAN_MODE])
+		vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+
 	err = register_netdevice(dev);
 	if (err < 0)
 		return err;
 
 	list_add_tail(&vlan->list, &port->vlans);
-	macvlan_transfer_operstate(dev);
+	netif_stacked_transfer_operstate(lowerdev, dev);
 	return 0;
 }
 
-static void macvlan_dellink(struct net_device *dev)
+static void macvlan_dellink(struct net_device *dev, struct list_head *head)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvlan_port *port = vlan->port;
 
 	list_del(&vlan->list);
-	unregister_netdevice(dev);
+	unregister_netdevice_queue(dev, head);
 
 	if (list_empty(&port->vlans))
 		macvlan_port_destroy(port->dev);
 }
 
+static int macvlan_changelink(struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[])
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	if (data && data[IFLA_MACVLAN_MODE])
+		vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+	return 0;
+}
+
+static size_t macvlan_get_size(const struct net_device *dev)
+{
+	return nla_total_size(4);
+}
+
+static int macvlan_fill_info(struct sk_buff *skb,
+				const struct net_device *dev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	NLA_PUT_U32(skb, IFLA_MACVLAN_MODE, vlan->mode);
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
+static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
+	[IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
+};
+
 static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 	.kind		= "macvlan",
 	.priv_size	= sizeof(struct macvlan_dev),
@@ -576,6 +728,11 @@ static struct rtnl_link_ops macvlan_link
 	.validate	= macvlan_validate,
 	.newlink	= macvlan_newlink,
 	.dellink	= macvlan_dellink,
+	.maxtype	= IFLA_MACVLAN_MAX,
+	.policy		= macvlan_policy,
+	.changelink	= macvlan_changelink,
+	.get_size	= macvlan_get_size,
+	.fill_info	= macvlan_fill_info,
 };
 
 static int macvlan_device_event(struct notifier_block *unused,
@@ -592,7 +749,8 @@ static int macvlan_device_event(struct n
 	switch (event) {
 	case NETDEV_CHANGE:
 		list_for_each_entry(vlan, &port->vlans, list)
-			macvlan_transfer_operstate(vlan->dev);
+			netif_stacked_transfer_operstate(vlan->lowerdev,
+							 vlan->dev);
 		break;
 	case NETDEV_FEAT_CHANGE:
 		list_for_each_entry(vlan, &port->vlans, list) {
@@ -603,7 +761,7 @@ static int macvlan_device_event(struct n
 		break;
 	case NETDEV_UNREGISTER:
 		list_for_each_entry_safe(vlan, next, &port->vlans, list)
-			macvlan_dellink(vlan->dev);
+			macvlan_dellink(vlan->dev, NULL);
 		break;
 	}
 	return NOTIFY_DONE;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/Makefile linux-libre-2.6.33-gnu1/drivers/net/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -285,3 +285,5 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_SFC) += sfc/
 
 obj-$(CONFIG_WIMAX) += wimax/
+
+obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mdio.c linux-libre-2.6.33-gnu1/drivers/net/mdio.c
--- linux-libre-2.6.32-gnu1/drivers/net/mdio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mdio.c	2010-02-24 13:52:17.000000000 -0500
@@ -162,6 +162,10 @@ static u32 mdio45_get_an(const struct md
 		result |= ADVERTISED_100baseT_Half;
 	if (reg & ADVERTISE_100FULL)
 		result |= ADVERTISED_100baseT_Full;
+	if (reg & ADVERTISE_PAUSE_CAP)
+		result |= ADVERTISED_Pause;
+	if (reg & ADVERTISE_PAUSE_ASYM)
+		result |= ADVERTISED_Asym_Pause;
 	return result;
 }
 
@@ -344,11 +348,9 @@ void mdio45_ethtool_spauseparam_an(const
 
 	old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
 				  MDIO_AN_ADVERTISE);
-	adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-	if (ecmd->autoneg)
-		adv |= mii_advertise_flowctrl(
-			(ecmd->rx_pause ? FLOW_CTRL_RX : 0) |
-			(ecmd->tx_pause ? FLOW_CTRL_TX : 0));
+	adv = ((old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) |
+	       mii_advertise_flowctrl((ecmd->rx_pause ? FLOW_CTRL_RX : 0) |
+				      (ecmd->tx_pause ? FLOW_CTRL_TX : 0)));
 	if (adv != old_adv) {
 		mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN,
 				 MDIO_AN_ADVERTISE, adv);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mipsnet.c linux-libre-2.6.33-gnu1/drivers/net/mipsnet.c
--- linux-libre-2.6.32-gnu1/drivers/net/mipsnet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mipsnet.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,7 +211,7 @@ static int mipsnet_open(struct net_devic
 {
 	int err;
 
-	err = request_irq(dev->irq, &mipsnet_interrupt,
+	err = request_irq(dev->irq, mipsnet_interrupt,
 			  IRQF_SHARED, dev->name, (void *) dev);
 	if (err) {
 		release_region(dev->base_addr, sizeof(struct mipsnet_regs));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/alloc.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/alloc.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/alloc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/alloc.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,35 +72,6 @@ void mlx4_bitmap_free(struct mlx4_bitmap
 	mlx4_bitmap_free_range(bitmap, obj, 1);
 }
 
-static unsigned long find_aligned_range(unsigned long *bitmap,
-					u32 start, u32 nbits,
-					int len, int align)
-{
-	unsigned long end, i;
-
-again:
-	start = ALIGN(start, align);
-
-	while ((start < nbits) && test_bit(start, bitmap))
-		start += align;
-
-	if (start >= nbits)
-		return -1;
-
-	end = start+len;
-	if (end > nbits)
-		return -1;
-
-	for (i = start + 1; i < end; i++) {
-		if (test_bit(i, bitmap)) {
-			start = i + 1;
-			goto again;
-		}
-	}
-
-	return start;
-}
-
 u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
 {
 	u32 obj, i;
@@ -110,13 +81,13 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_
 
 	spin_lock(&bitmap->lock);
 
-	obj = find_aligned_range(bitmap->table, bitmap->last,
-				 bitmap->max, cnt, align);
+	obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
+				bitmap->last, cnt, align - 1);
 	if (obj >= bitmap->max) {
 		bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
 				& bitmap->mask;
-		obj = find_aligned_range(bitmap->table, 0, bitmap->max,
-					 cnt, align);
+		obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
+						0, cnt, align - 1);
 	}
 
 	if (obj < bitmap->max) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/en_rx.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/en_rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,7 @@ static void mlx4_en_free_rx_desc(struct
 		en_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
 		dma = be64_to_cpu(rx_desc->data[nr].addr);
 
-		en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
+		en_dbg(DRV, priv, "Unmapping buffer at dma:0x%llx\n", (u64) dma);
 		pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
 				 PCI_DMA_FROMDEVICE);
 		put_page(skb_frags[nr].page);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/en_tx.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/en_tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/en_tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@ enum {
 static int inline_thold __read_mostly = MAX_INLINE;
 
 module_param_named(inline_thold, inline_thold, int, 0444);
-MODULE_PARM_DESC(inline_thold, "treshold for using inline data");
+MODULE_PARM_DESC(inline_thold, "threshold for using inline data");
 
 int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
 			   struct mlx4_en_tx_ring *ring, u32 size,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/fw.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/fw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/fw.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,6 +90,7 @@ static void dump_dev_cap_flags(struct ml
 		[ 9] = "Q_Key violation counter",
 		[10] = "VMM",
 		[12] = "DPDP",
+		[15] = "Big LSO headers",
 		[16] = "MW support",
 		[17] = "APM support",
 		[18] = "Atomic ops support",
@@ -235,7 +236,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *
 	MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MPT_OFFSET);
 	dev_cap->max_mpts = 1 << (field & 0x3f);
 	MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET);
-	dev_cap->reserved_eqs = 1 << (field & 0xf);
+	dev_cap->reserved_eqs = field & 0xf;
 	MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET);
 	dev_cap->max_eqs = 1 << (field & 0xf);
 	MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/main.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -1174,7 +1174,7 @@ static int __mlx4_init_one(struct pci_de
 	return 0;
 
 err_port:
-	for (port = 1; port <= dev->caps.num_ports; port++)
+	for (--port; port >= 1; --port)
 		mlx4_cleanup_port_info(&priv->port[port]);
 
 	mlx4_cleanup_mcg_table(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/mlx4_en.h linux-libre-2.6.33-gnu1/drivers/net/mlx4/mlx4_en.h
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/mlx4_en.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/mlx4_en.h	2010-02-24 13:52:17.000000000 -0500
@@ -162,7 +162,7 @@ enum {
 #define MLX4_EN_DEF_RX_PAUSE	1
 #define MLX4_EN_DEF_TX_PAUSE	1
 
-/* Interval between sucessive polls in the Tx routine when polling is used
+/* Interval between successive polls in the Tx routine when polling is used
    instead of interrupts (in per-core Tx rings) - should be power of 2 */
 #define MLX4_EN_TX_POLL_MODER	16
 #define MLX4_EN_TX_POLL_TIMEOUT	(HZ / 4)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mlx4/sense.c linux-libre-2.6.33-gnu1/drivers/net/mlx4/sense.c
--- linux-libre-2.6.32-gnu1/drivers/net/mlx4/sense.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mlx4/sense.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,7 @@ static int mlx4_SENSE_PORT(struct mlx4_d
 
 	if (out_param > 2) {
 		mlx4_err(dev, "Sense returned illegal value: 0x%llx\n", out_param);
-		return EINVAL;
+		return -EINVAL;
 	}
 
 	*type = out_param;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/mv643xx_eth.c linux-libre-2.6.33-gnu1/drivers/net/mv643xx_eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/mv643xx_eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/mv643xx_eth.c	2010-02-24 13:52:17.000000000 -0500
@@ -656,6 +656,7 @@ static int rxq_refill(struct rx_queue *r
 		struct sk_buff *skb;
 		int rx;
 		struct rx_desc *rx_desc;
+		int size;
 
 		skb = __skb_dequeue(&mp->rx_recycle);
 		if (skb == NULL)
@@ -678,10 +679,11 @@ static int rxq_refill(struct rx_queue *r
 
 		rx_desc = rxq->rx_desc_area + rx;
 
+		size = skb->end - skb->data;
 		rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
-						  skb->data, mp->skb_size,
+						  skb->data, size,
 						  DMA_FROM_DEVICE);
-		rx_desc->buf_size = mp->skb_size;
+		rx_desc->buf_size = size;
 		rxq->rx_skb[rx] = skb;
 		wmb();
 		rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT;
@@ -849,7 +851,7 @@ no_csum:
 	return 0;
 }
 
-static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	int queue;
@@ -1827,6 +1829,9 @@ static int mv643xx_eth_set_mac_address(s
 {
 	struct sockaddr *sa = addr;
 
+	if (!is_valid_ether_addr(sa->sa_data))
+		return -EINVAL;
+
 	memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
 
 	netif_addr_lock_bh(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/myri10ge/myri10ge.c linux-libre-2.6.33-gnu1/drivers/net/myri10ge/myri10ge.c
--- linux-libre-2.6.32-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 14:01:00.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 12:08:15.000000000 -0400
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.5.1-1.451"
+#define MYRI10GE_VERSION_STR "1.5.1-1.453"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -207,7 +207,6 @@ struct myri10ge_priv {
 	int big_bytes;
 	int max_intr_slots;
 	struct net_device *dev;
-	struct net_device_stats stats;
 	spinlock_t stats_lock;
 	u8 __iomem *sram;
 	int sram_size;
@@ -264,6 +263,7 @@ static char *myri10ge_fw_unaligned = "/*
 static char *myri10ge_fw_aligned = "/*(DEBLOBBED)*/";
 static char *myri10ge_fw_rss_unaligned = "/*(DEBLOBBED)*/";
 static char *myri10ge_fw_rss_aligned = "/*(DEBLOBBED)*/";
+/*(DEBLOBBED)*/
 
 static char *myri10ge_fw_name = NULL;
 module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
@@ -344,7 +344,7 @@ static int myri10ge_max_slices = 1;
 module_param(myri10ge_max_slices, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_max_slices, "Max tx/rx queues");
 
-static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
+static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT;
 module_param(myri10ge_rss_hash, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do");
 
@@ -407,8 +407,8 @@ myri10ge_send_cmd(struct myri10ge_priv *
 		 * and try to get the completion quickly
 		 * (1ms will be enough for those commands) */
 		for (sleep_total = 0;
-		     sleep_total < 1000
-		     && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
+		     sleep_total < 1000 &&
+		     response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
 		     sleep_total += 10) {
 			udelay(10);
 			mb();
@@ -416,8 +416,8 @@ myri10ge_send_cmd(struct myri10ge_priv *
 	} else {
 		/* use msleep for most command */
 		for (sleep_total = 0;
-		     sleep_total < 15
-		     && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
+		     sleep_total < 15 &&
+		     response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
 		     sleep_total++)
 			msleep(1);
 	}
@@ -554,8 +554,8 @@ myri10ge_validate_firmware(struct myri10
 	sscanf(mgp->fw_version, "%d.%d.%d", &mgp->fw_ver_major,
 	       &mgp->fw_ver_minor, &mgp->fw_ver_tiny);
 
-	if (!(mgp->fw_ver_major == MXGEFW_VERSION_MAJOR
-	      && mgp->fw_ver_minor == MXGEFW_VERSION_MINOR)) {
+	if (!(mgp->fw_ver_major == MXGEFW_VERSION_MAJOR &&
+	      mgp->fw_ver_minor == MXGEFW_VERSION_MINOR)) {
 		dev_err(dev, "Found firmware version %s\n", mgp->fw_version);
 		dev_err(dev, "Driver needs %d.%d\n", MXGEFW_VERSION_MAJOR,
 			MXGEFW_VERSION_MINOR);
@@ -1409,8 +1409,8 @@ myri10ge_tx_done(struct myri10ge_slice_s
 	}
 
 	/* start the queue if we've stopped it */
-	if (netif_tx_queue_stopped(dev_queue)
-	    && tx->req - tx->done < (tx->mask >> 1)) {
+	if (netif_tx_queue_stopped(dev_queue) &&
+	    tx->req - tx->done < (tx->mask >> 1)) {
 		tx->wake_queue++;
 		netif_tx_wake_queue(dev_queue);
 	}
@@ -1832,7 +1832,7 @@ myri10ge_get_ethtool_stats(struct net_de
 	/* force stats update */
 	(void)myri10ge_get_stats(netdev);
 	for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
-		data[i] = ((unsigned long *)&mgp->stats)[i];
+		data[i] = ((unsigned long *)&netdev->stats)[i];
 
 	data[i++] = (unsigned int)mgp->tx_boundary;
 	data[i++] = (unsigned int)mgp->wc_enabled;
@@ -3002,7 +3002,7 @@ static struct net_device_stats *myri10ge
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_slice_netstats *slice_stats;
-	struct net_device_stats *stats = &mgp->stats;
+	struct net_device_stats *stats = &dev->stats;
 	int i;
 
 	spin_lock(&mgp->stats_lock);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/myri_sbus.c linux-libre-2.6.33-gnu1/drivers/net/myri_sbus.c
--- linux-libre-2.6.32-gnu1/drivers/net/myri_sbus.c	2013-05-03 14:00:55.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/myri_sbus.c	2013-05-03 12:08:12.000000000 -0400
@@ -1084,7 +1084,7 @@ static int __devinit myri_sbus_probe(str
 
 	/* Register interrupt handler now. */
 	DET(("Requesting MYRIcom IRQ line.\n"));
-	if (request_irq(dev->irq, &myri_interrupt,
+	if (request_irq(dev->irq, myri_interrupt,
 			IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) {
 		printk("MyriCOM: Cannot register interrupt handler.\n");
 		goto err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/natsemi.c linux-libre-2.6.33-gnu1/drivers/net/natsemi.c
--- linux-libre-2.6.32-gnu1/drivers/net/natsemi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/natsemi.c	2010-02-24 13:52:17.000000000 -0500
@@ -683,8 +683,8 @@ static ssize_t natsemi_set_dspcfg_workar
         /* Find out the new setting */
         if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
                 new_setting = 1;
-        else if (!strncmp("off", buf, count - 1)
-                 || !strncmp("0", buf, count - 1))
+        else if (!strncmp("off", buf, count - 1) ||
+                 !strncmp("0", buf, count - 1))
 		new_setting = 0;
 	else
                  return count;
@@ -757,8 +757,8 @@ static void __devinit natsemi_init_media
 	np->autoneg    = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE;
 	np->advertising= mdio_read(dev, MII_ADVERTISE);
 
-	if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL
-	 && netif_msg_probe(np)) {
+	if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL &&
+	    netif_msg_probe(np)) {
 		printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s "
 			"10%s %s duplex.\n",
 			pci_name(np->pci_dev),
@@ -1153,8 +1153,8 @@ static void init_phy_fixup(struct net_de
 	tmp = mdio_read(dev, MII_BMCR);
 	if (np->autoneg == AUTONEG_ENABLE) {
 		/* renegotiate if something changed */
-		if ((tmp & BMCR_ANENABLE) == 0
-		 || np->advertising != mdio_read(dev, MII_ADVERTISE))
+		if ((tmp & BMCR_ANENABLE) == 0 ||
+		    np->advertising != mdio_read(dev, MII_ADVERTISE))
 		{
 			/* turn on autonegotiation and force negotiation */
 			tmp |= (BMCR_ANENABLE | BMCR_ANRESTART);
@@ -1535,7 +1535,7 @@ static int netdev_open(struct net_device
 	/* Reset the chip, just in case. */
 	natsemi_reset(dev);
 
-	i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev);
+	i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
 	if (i) return i;
 
 	if (netif_msg_ifup(np))
@@ -2164,8 +2164,8 @@ static void netdev_tx_done(struct net_de
 		dev_kfree_skb_irq(np->tx_skbuff[entry]);
 		np->tx_skbuff[entry] = NULL;
 	}
-	if (netif_queue_stopped(dev)
-		&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
+	if (netif_queue_stopped(dev) &&
+	    np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 		/* The ring is no longer full, wake queue. */
 		netif_wake_queue(dev);
 	}
@@ -2343,8 +2343,8 @@ static void netdev_rx(struct net_device
 			/* Omit CRC size. */
 			/* Check if the packet is long enough to accept
 			 * without copying to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-			    && (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) {
 				/* 16 byte align the IP header */
 				skb_reserve(skb, RX_OFFSET);
 				pci_dma_sync_single_for_cpu(np->pci_dev,
@@ -2390,8 +2390,8 @@ static void netdev_error(struct net_devi
 	spin_lock(&np->lock);
 	if (intr_status & LinkChange) {
 		u16 lpa = mdio_read(dev, MII_LPA);
-		if (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE
-		 && netif_msg_link(np)) {
+		if (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE &&
+		    netif_msg_link(np)) {
 			printk(KERN_INFO
 				"%s: Autonegotiation advertising"
 				" %#04x  partner %#04x.\n", dev->name,
@@ -2488,8 +2488,8 @@ static void __set_rx_mode(struct net_dev
 	if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptAllMulticast | AcceptAllPhys | AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit)
-	  || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptAllMulticast | AcceptMyPhys;
 	} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@ static const char netxen_nic_gstrings_te
 
 #define NETXEN_NIC_TEST_LEN	ARRAY_SIZE(netxen_nic_gstrings_test)
 
-#define NETXEN_NIC_REGS_COUNT 42
+#define NETXEN_NIC_REGS_COUNT 30
 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
 #define NETXEN_MAX_EEPROM_LEN   1024
 
@@ -85,11 +85,9 @@ netxen_nic_get_drvinfo(struct net_device
 
 	strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
 	strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
-	read_lock(&adapter->adapter_lock);
 	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
 	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
 	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-	read_unlock(&adapter->adapter_lock);
 	sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
@@ -259,18 +257,18 @@ netxen_nic_set_settings(struct net_devic
 	/* read which mode */
 	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		/* autonegotiation */
-		if (adapter->phy_write
-		    && adapter->phy_write(adapter,
-					  NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-					  ecmd->autoneg) != 0)
+		if (adapter->phy_write &&
+		    adapter->phy_write(adapter,
+				       NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+				       ecmd->autoneg) != 0)
 			return -EIO;
 		else
 			adapter->link_autoneg = ecmd->autoneg;
 
-		if (adapter->phy_read
-		    && adapter->phy_read(adapter,
-					 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-					 &status) != 0)
+		if (adapter->phy_read &&
+		    adapter->phy_read(adapter,
+				      NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+				      &status) != 0)
 			return -EIO;
 
 		/* speed */
@@ -290,10 +288,10 @@ netxen_nic_set_settings(struct net_devic
 			netxen_clear_phy_duplex(status);
 		if (ecmd->duplex == DUPLEX_FULL)
 			netxen_set_phy_duplex(status);
-		if (adapter->phy_write
-		    && adapter->phy_write(adapter,
-					  NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-					  *((int *)&status)) != 0)
+		if (adapter->phy_write &&
+		    adapter->phy_write(adapter,
+				       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+				       *((int *)&status)) != 0)
 			return -EIO;
 		else {
 			adapter->link_speed = ecmd->speed;
@@ -314,150 +312,91 @@ static int netxen_nic_get_regs_len(struc
 	return NETXEN_NIC_REGS_LEN;
 }
 
-struct netxen_niu_regs {
-	__u32 reg[NETXEN_NIC_REGS_COUNT];
-};
-
-static struct netxen_niu_regs niu_registers[] = {
-	{
-	 /* GB Mode */
-	 {
-	  NETXEN_NIU_GB_SERDES_RESET,
-	  NETXEN_NIU_GB0_MII_MODE,
-	  NETXEN_NIU_GB1_MII_MODE,
-	  NETXEN_NIU_GB2_MII_MODE,
-	  NETXEN_NIU_GB3_MII_MODE,
-	  NETXEN_NIU_GB0_GMII_MODE,
-	  NETXEN_NIU_GB1_GMII_MODE,
-	  NETXEN_NIU_GB2_GMII_MODE,
-	  NETXEN_NIU_GB3_GMII_MODE,
-	  NETXEN_NIU_REMOTE_LOOPBACK,
-	  NETXEN_NIU_GB0_HALF_DUPLEX,
-	  NETXEN_NIU_GB1_HALF_DUPLEX,
-	  NETXEN_NIU_RESET_SYS_FIFOS,
-	  NETXEN_NIU_GB_CRC_DROP,
-	  NETXEN_NIU_GB_DROP_WRONGADDR,
-	  NETXEN_NIU_TEST_MUX_CTL,
-
-	  NETXEN_NIU_GB_MAC_CONFIG_0(0),
-	  NETXEN_NIU_GB_MAC_CONFIG_1(0),
-	  NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0),
-	  NETXEN_NIU_GB_MAX_FRAME_SIZE(0),
-	  NETXEN_NIU_GB_TEST_REG(0),
-	  NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
-	  NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
-	  NETXEN_NIU_GB_MII_MGMT_ADDR(0),
-	  NETXEN_NIU_GB_MII_MGMT_CTRL(0),
-	  NETXEN_NIU_GB_MII_MGMT_STATUS(0),
-	  NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
-	  NETXEN_NIU_GB_INTERFACE_CTRL(0),
-	  NETXEN_NIU_GB_INTERFACE_STATUS(0),
-	  NETXEN_NIU_GB_STATION_ADDR_0(0),
-	  NETXEN_NIU_GB_STATION_ADDR_1(0),
-	  -1,
-	  }
-	 },
-	{
-	 /* XG Mode */
-	 {
-	  NETXEN_NIU_XG_SINGLE_TERM,
-	  NETXEN_NIU_XG_DRIVE_HI,
-	  NETXEN_NIU_XG_DRIVE_LO,
-	  NETXEN_NIU_XG_DTX,
-	  NETXEN_NIU_XG_DEQ,
-	  NETXEN_NIU_XG_WORD_ALIGN,
-	  NETXEN_NIU_XG_RESET,
-	  NETXEN_NIU_XG_POWER_DOWN,
-	  NETXEN_NIU_XG_RESET_PLL,
-	  NETXEN_NIU_XG_SERDES_LOOPBACK,
-	  NETXEN_NIU_XG_DO_BYTE_ALIGN,
-	  NETXEN_NIU_XG_TX_ENABLE,
-	  NETXEN_NIU_XG_RX_ENABLE,
-	  NETXEN_NIU_XG_STATUS,
-	  NETXEN_NIU_XG_PAUSE_THRESHOLD,
-	  NETXEN_NIU_XGE_CONFIG_0,
-	  NETXEN_NIU_XGE_CONFIG_1,
-	  NETXEN_NIU_XGE_IPG,
-	  NETXEN_NIU_XGE_STATION_ADDR_0_HI,
-	  NETXEN_NIU_XGE_STATION_ADDR_0_1,
-	  NETXEN_NIU_XGE_STATION_ADDR_1_LO,
-	  NETXEN_NIU_XGE_STATUS,
-	  NETXEN_NIU_XGE_MAX_FRAME_SIZE,
-	  NETXEN_NIU_XGE_PAUSE_FRAME_VALUE,
-	  NETXEN_NIU_XGE_TX_BYTE_CNT,
-	  NETXEN_NIU_XGE_TX_FRAME_CNT,
-	  NETXEN_NIU_XGE_RX_BYTE_CNT,
-	  NETXEN_NIU_XGE_RX_FRAME_CNT,
-	  NETXEN_NIU_XGE_AGGR_ERROR_CNT,
-	  NETXEN_NIU_XGE_MULTICAST_FRAME_CNT,
-	  NETXEN_NIU_XGE_UNICAST_FRAME_CNT,
-	  NETXEN_NIU_XGE_CRC_ERROR_CNT,
-	  NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR,
-	  NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR,
-	  NETXEN_NIU_XGE_LOCAL_ERROR_CNT,
-	  NETXEN_NIU_XGE_REMOTE_ERROR_CNT,
-	  NETXEN_NIU_XGE_CONTROL_CHAR_CNT,
-	  NETXEN_NIU_XGE_PAUSE_FRAME_CNT,
-	  -1,
-	  }
-	 }
-};
-
 static void
 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	__u32 mode, *regs_buff = p;
-	int i, window;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct nx_host_sds_ring *sds_ring;
+	u32 *regs_buff = p;
+	int ring, i = 0;
+	int port = adapter->physical_port;
 
 	memset(p, 0, NETXEN_NIC_REGS_LEN);
+
 	regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
 	    (adapter->pdev)->device;
-	/* which mode */
-	regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
-	mode = regs_buff[0];
 
-	/* Common registers to all the modes */
-	regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
-	/* GB/XGB Mode */
-	mode = (mode / 2) - 1;
-	window = 0;
-	if (mode <= 1) {
-		for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
-			/* GB: port specific registers */
-			if (mode == 0 && i >= 19)
-				window = adapter->physical_port *
-					NETXEN_NIC_PORT_WINDOW;
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
 
-			regs_buff[i] = NXRD32(adapter,
-				niu_registers[mode].reg[i - 3] + window);
-		}
+	regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
+	regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
+	regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+	regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
+	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+	regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
 
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
+	regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+
+		regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
+		i += 2;
+
+		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
+		regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
+
+	} else {
+		i++;
+
+		regs_buff[i++] = NXRD32(adapter,
+					NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
+		regs_buff[i++] = NXRD32(adapter,
+					NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
+
+		regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
+		regs_buff[i++] = NXRDIO(adapter,
+				 adapter->tx_ring->crb_cmd_consumer);
+	}
+
+	regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
+
+	regs_buff[i++] = NXRDIO(adapter,
+			 recv_ctx->rds_rings[0].crb_rcv_producer);
+	regs_buff[i++] = NXRDIO(adapter,
+			 recv_ctx->rds_rings[1].crb_rcv_producer);
+
+	regs_buff[i++] = adapter->max_sds_rings;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &(recv_ctx->sds_rings[ring]);
+		regs_buff[i++] = NXRDIO(adapter,
+					sds_ring->crb_sts_consumer);
 	}
 }
 
 static u32 netxen_nic_test_link(struct net_device *dev)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	__u32 status;
-	int val;
+	u32 val, port;
 
-	/* read which mode */
-	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-		if (adapter->phy_read
-		    && adapter->phy_read(adapter,
-					 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-					 &status) != 0)
-			return -EIO;
-		else {
-			val = netxen_get_phy_link(status);
-			return !val;
-		}
-	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+	port = adapter->physical_port;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		val = NXRD32(adapter, CRB_XG_STATE_P3);
+		val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+		return (val == XG_LINK_UP_P3) ? 0 : 1;
+	} else {
 		val = NXRD32(adapter, CRB_XG_STATE);
+		val = (val >> port*8) & 0xff;
 		return (val == XG_LINK_UP) ? 0 : 1;
 	}
-	return -EIO;
 }
 
 static int
@@ -690,8 +629,8 @@ static int netxen_nic_reg_test(struct ne
 	u32 data_read, data_written;
 
 	data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
-	if ((data_read & 0xffff) != PHAN_VENDOR_ID)
-	return 1;
+	if ((data_read & 0xffff) != adapter->pdev->vendor)
+		return 1;
 
 	data_written = (u32)0xa5a5a5a5;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic.h linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic.h
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic.h	2013-05-03 14:01:00.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic.h	2013-05-03 12:08:18.000000000 -0400
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 50
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.50"
+#define _NETXEN_NIC_LINUX_SUBVERSION 72
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.72"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
@@ -74,8 +74,6 @@
 #define NETXEN_FLASH_TOTAL_SIZE  (NETXEN_NUM_FLASH_SECTORS \
 					* NETXEN_FLASH_SECTOR_SIZE)
 
-#define PHAN_VENDOR_ID 0x4040
-
 #define RCV_DESC_RINGSIZE(rds_ring)	\
 	(sizeof(struct rcv_desc) * (rds_ring)->num_desc)
 #define RCV_BUFF_RINGSIZE(rds_ring)	\
@@ -117,9 +115,11 @@
 #define NX_P3_B0		0x40
 #define NX_P3_B1		0x41
 #define NX_P3_B2		0x42
+#define NX_P3P_A0		0x50
 
 #define NX_IS_REVISION_P2(REVISION)     (REVISION <= NX_P2_C1)
 #define NX_IS_REVISION_P3(REVISION)     (REVISION >= NX_P3_A0)
+#define NX_IS_REVISION_P3P(REVISION)     (REVISION >= NX_P3P_A0)
 
 #define FIRST_PAGE_GROUP_START	0
 #define FIRST_PAGE_GROUP_END	0x100000
@@ -419,6 +419,34 @@ struct status_desc {
 	__le64 status_desc_data[2];
 } __attribute__ ((aligned(16)));
 
+/* UNIFIED ROMIMAGE *************************/
+#define NX_UNI_FW_MIN_SIZE		0x3eb000
+#define NX_UNI_DIR_SECT_PRODUCT_TBL	0x0
+#define NX_UNI_DIR_SECT_BOOTLD		0x6
+#define NX_UNI_DIR_SECT_FW		0x7
+
+/*Offsets */
+#define NX_UNI_CHIP_REV_OFF		10
+#define NX_UNI_FLAGS_OFF		11
+#define NX_UNI_BIOS_VERSION_OFF 	12
+#define NX_UNI_BOOTLD_IDX_OFF		27
+#define NX_UNI_FIRMWARE_IDX_OFF 	29
+
+struct uni_table_desc{
+	uint32_t	findex;
+	uint32_t	num_entries;
+	uint32_t	entry_size;
+	uint32_t	reserved[5];
+};
+
+struct uni_data_desc{
+	uint32_t	findex;
+	uint32_t	size;
+	uint32_t	reserved[5];
+};
+
+/* UNIFIED ROMIMAGE *************************/
+
 /* The version of the main data structure */
 #define	NETXEN_BDINFO_VERSION 1
 
@@ -485,7 +513,15 @@ struct status_desc {
 #define NX_P2_MN_ROMIMAGE	0
 #define NX_P3_CT_ROMIMAGE	1
 #define NX_P3_MN_ROMIMAGE	2
-#define NX_FLASH_ROMIMAGE	3
+#define NX_UNIFIED_ROMIMAGE	3
+#define NX_FLASH_ROMIMAGE	4
+#define NX_UNKNOWN_ROMIMAGE	0xff
+
+#define NX_P2_MN_ROMIMAGE_NAME		"/*(DEBLOBBED)*/"
+#define NX_P3_CT_ROMIMAGE_NAME		"/*(DEBLOBBED)*/"
+#define NX_P3_MN_ROMIMAGE_NAME		"/*(DEBLOBBED)*/"
+#define NX_UNIFIED_ROMIMAGE_NAME	"/*(DEBLOBBED)*/"
+#define NX_FLASH_ROMIMAGE_NAME		"flash"
 
 extern char netxen_nic_driver_name[];
 
@@ -543,13 +579,16 @@ struct netxen_hardware_context {
 	void __iomem *pci_base1;
 	void __iomem *pci_base2;
 	void __iomem *db_base;
+	void __iomem *ocm_win_crb;
+
 	unsigned long db_len;
 	unsigned long pci_len0;
 
-	int qdr_sn_window;
-	int ddr_mn_window;
-	u32 mn_win_crb;
-	u32 ms_win_crb;
+	u32 ocm_win;
+	u32 crb_win;
+
+	rwlock_t crb_lock;
+	spinlock_t mem_lock;
 
 	u8 cut_through;
 	u8 revision_id;
@@ -1039,6 +1078,9 @@ typedef struct {
 #define LINKEVENT_LINKSPEED_MBPS	0
 #define LINKEVENT_LINKSPEED_ENCODED	1
 
+#define AUTO_FW_RESET_ENABLED	0xEF10AF12
+#define AUTO_FW_RESET_DISABLED	0xDCBAAF12
+
 /* firmware response header:
  *	63:58 - message type
  *	57:56 - owner
@@ -1086,6 +1128,7 @@ typedef struct {
 #define NETXEN_NIC_MSIX_ENABLED		0x04
 #define NETXEN_NIC_LRO_ENABLED		0x08
 #define NETXEN_NIC_BRIDGE_ENABLED       0X10
+#define NETXEN_NIC_DIAG_ENABLED		0x20
 #define NETXEN_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
 
@@ -1115,10 +1158,6 @@ struct netxen_adapter {
 	struct pci_dev *pdev;
 	struct list_head mac_list;
 
-	u32 curr_window;
-	u32 crb_win;
-	rwlock_t adapter_lock;
-
 	spinlock_t tx_clean_lock;
 
 	u16 num_txd;
@@ -1182,11 +1221,10 @@ struct netxen_adapter {
 	u32 (*crb_read)(struct netxen_adapter *, ulong);
 	int (*crb_write)(struct netxen_adapter *, ulong, u32);
 
-	int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
-	int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
+	int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *);
+	int (*pci_mem_write)(struct netxen_adapter *, u64, u64);
 
-	unsigned long (*pci_set_window)(struct netxen_adapter *,
-			unsigned long long);
+	int (*pci_set_window)(struct netxen_adapter *, u64, u32 *);
 
 	u32 (*io_read)(struct netxen_adapter *, void __iomem *);
 	void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
@@ -1205,12 +1243,10 @@ struct netxen_adapter {
 
 	struct work_struct  tx_timeout_task;
 
-	struct net_device_stats net_stats;
-
 	nx_nic_intr_coalesce_t coal;
 
 	unsigned long state;
-	u32 resv5;
+	__le32 file_prd_off;	/*File fw product offset*/
 	u32 fw_version;
 	const struct firmware *fw;
 };
@@ -1273,7 +1309,7 @@ int netxen_load_firmware(struct netxen_a
 int netxen_need_fw_reset(struct netxen_adapter *adapter);
 void netxen_reject_firmware(struct netxen_adapter *adapter);
 void netxen_release_firmware(struct netxen_adapter *adapter);
-int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
+int netxen_pinit_from_rom(struct netxen_adapter *adapter);
 
 int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
 int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_hdr.h linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hdr.h
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2010-02-24 13:52:17.000000000 -0500
@@ -664,40 +664,51 @@ enum {
 #define NETXEN_NIU_AP_STATION_ADDR_0(I)    (NETXEN_CRB_NIU+0xa0040+(I)*0x10000)
 #define NETXEN_NIU_AP_STATION_ADDR_1(I)    (NETXEN_CRB_NIU+0xa0044+(I)*0x10000)
 
+
+#define TEST_AGT_CTRL	(0x00)
+
+#define TA_CTL_START	1
+#define TA_CTL_ENABLE	2
+#define TA_CTL_WRITE	4
+#define TA_CTL_BUSY	8
+
 /*
  *   Register offsets for MN
  */
-#define	MIU_CONTROL	       (0x000)
-#define MIU_TEST_AGT_CTRL      (0x090)
-#define MIU_TEST_AGT_ADDR_LO   (0x094)
-#define MIU_TEST_AGT_ADDR_HI   (0x098)
-#define MIU_TEST_AGT_WRDATA_LO (0x0a0)
-#define MIU_TEST_AGT_WRDATA_HI (0x0a4)
-#define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i)))
-#define MIU_TEST_AGT_RDDATA_LO (0x0a8)
-#define MIU_TEST_AGT_RDDATA_HI (0x0ac)
-#define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i)))
-#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8
-#define MIU_TEST_AGT_UPPER_ADDR(off) (0)
+#define MIU_TEST_AGT_BASE		(0x90)
 
-/* MIU_TEST_AGT_CTRL flags. work for SIU as well */
-#define MIU_TA_CTL_START        1
-#define MIU_TA_CTL_ENABLE       2
-#define MIU_TA_CTL_WRITE        4
-#define MIU_TA_CTL_BUSY         8
+#define MIU_TEST_AGT_ADDR_LO		(0x04)
+#define MIU_TEST_AGT_ADDR_HI		(0x08)
+#define MIU_TEST_AGT_WRDATA_LO		(0x10)
+#define MIU_TEST_AGT_WRDATA_HI		(0x14)
+#define MIU_TEST_AGT_WRDATA_UPPER_LO	(0x20)
+#define MIU_TEST_AGT_WRDATA_UPPER_HI	(0x24)
+#define MIU_TEST_AGT_WRDATA(i)		(0x10+(0x10*((i)>>1))+(4*((i)&1)))
+#define MIU_TEST_AGT_RDDATA_LO		(0x18)
+#define MIU_TEST_AGT_RDDATA_HI		(0x1c)
+#define MIU_TEST_AGT_RDDATA_UPPER_LO	(0x28)
+#define MIU_TEST_AGT_RDDATA_UPPER_HI	(0x2c)
+#define MIU_TEST_AGT_RDDATA(i)		(0x18+(0x10*((i)>>1))+(4*((i)&1)))
 
-#define SIU_TEST_AGT_CTRL      (0x060)
-#define SIU_TEST_AGT_ADDR_LO   (0x064)
-#define SIU_TEST_AGT_ADDR_HI   (0x078)
-#define SIU_TEST_AGT_WRDATA_LO (0x068)
-#define SIU_TEST_AGT_WRDATA_HI (0x06c)
-#define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i)))
-#define SIU_TEST_AGT_RDDATA_LO (0x070)
-#define SIU_TEST_AGT_RDDATA_HI (0x074)
-#define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i)))
+#define MIU_TEST_AGT_ADDR_MASK		0xfffffff8
+#define MIU_TEST_AGT_UPPER_ADDR(off)	(0)
 
-#define SIU_TEST_AGT_ADDR_MASK 0x3ffff8
-#define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22)
+/*
+ *   Register offsets for MS
+ */
+#define SIU_TEST_AGT_BASE		(0x60)
+
+#define SIU_TEST_AGT_ADDR_LO		(0x04)
+#define SIU_TEST_AGT_ADDR_HI		(0x18)
+#define SIU_TEST_AGT_WRDATA_LO		(0x08)
+#define SIU_TEST_AGT_WRDATA_HI		(0x0c)
+#define SIU_TEST_AGT_WRDATA(i)		(0x08+(4*(i)))
+#define SIU_TEST_AGT_RDDATA_LO		(0x10)
+#define SIU_TEST_AGT_RDDATA_HI		(0x14)
+#define SIU_TEST_AGT_RDDATA(i)		(0x10+(4*(i)))
+
+#define SIU_TEST_AGT_ADDR_MASK		0x3ffff8
+#define SIU_TEST_AGT_UPPER_ADDR(off)	((off)>>22)
 
 /* XG Link status */
 #define XG_LINK_UP	0x10
@@ -859,6 +870,9 @@ enum {
 		(PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\
 		(PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4))))
 
+#define PCIX_OCM_WINDOW		(0x10800)
+#define PCIX_OCM_WINDOW_REG(func)	(PCIX_OCM_WINDOW + 0x20 * (func))
+
 #define PCIX_TARGET_STATUS	(0x10118)
 #define PCIX_TARGET_STATUS_F1	(0x10160)
 #define PCIX_TARGET_STATUS_F2	(0x10164)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_hw.c linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.c
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_hw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #define MASK(n) ((1ULL<<(n))-1)
 #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
 #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
+#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
 #define MS_WIN(addr) (addr & 0x0ffc0000)
 
 #define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
@@ -41,6 +42,11 @@
 #define CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
 #define CRB_INDIRECT_2M	(0x1e0000UL)
 
+static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
+		void __iomem *addr, u32 data);
+static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
+		void __iomem *addr);
+
 #ifndef readq
 static inline u64 readq(void __iomem *addr)
 {
@@ -326,7 +332,7 @@ netxen_pcie_sem_lock(struct netxen_adapt
 		if (done == 1)
 			break;
 		if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
-			return -1;
+			return -EIO;
 		msleep(1);
 	}
 
@@ -339,8 +345,7 @@ netxen_pcie_sem_lock(struct netxen_adapt
 void
 netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
 {
-	int val;
-	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
 }
 
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
@@ -685,6 +690,9 @@ void netxen_p3_nic_set_multi(struct net_
 	struct list_head *head;
 	nx_mac_list_t *cur;
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
 	list_splice_tail_init(&adapter->mac_list, &del_list);
 
 	nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
@@ -1073,89 +1081,71 @@ int netxen_p3_get_mac_addr(struct netxen
  * Changes the CRB window to the specified window.
  */
 static void
-netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
+netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter,
+		u32 window)
 {
 	void __iomem *offset;
-	u32 tmp;
-	int count = 0;
-	uint8_t func = adapter->ahw.pci_func;
+	int count = 10;
+	u8 func = adapter->ahw.pci_func;
 
-	if (adapter->curr_window == wndw)
+	if (adapter->ahw.crb_win == window)
 		return;
-	/*
-	 * Move the CRB window.
-	 * We need to write to the "direct access" region of PCI
-	 * to avoid a race condition where the window register has
-	 * not been successfully written across CRB before the target
-	 * register address is received by PCI. The direct region bypasses
-	 * the CRB bus.
-	 */
+
 	offset = PCI_OFFSET_SECOND_RANGE(adapter,
 			NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));
 
-	if (wndw & 0x1)
-		wndw = NETXEN_WINDOW_ONE;
+	writel(window, offset);
+	do {
+		if (window == readl(offset))
+			break;
 
-	writel(wndw, offset);
+		if (printk_ratelimit())
+			dev_warn(&adapter->pdev->dev,
+					"failed to set CRB window to %d\n",
+					(window == NETXEN_WINDOW_ONE));
+		udelay(1);
 
-	/* MUST make sure window is set before we forge on... */
-	while ((tmp = readl(offset)) != wndw) {
-		printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
-		       "registered properly: 0x%08x.\n",
-		       netxen_nic_driver_name, __func__, tmp);
-		mdelay(1);
-		if (count >= 10)
-			break;
-		count++;
-	}
+	} while (--count > 0);
 
-	if (wndw == NETXEN_WINDOW_ONE)
-		adapter->curr_window = 1;
-	else
-		adapter->curr_window = 0;
+	if (count > 0)
+		adapter->ahw.crb_win = window;
 }
 
 /*
- * Return -1 if off is not valid,
+ * Returns < 0 if off is not valid,
  *	 1 if window access is needed. 'off' is set to offset from
  *	   CRB space in 128M pci map
  *	 0 if no window access is needed. 'off' is set to 2M addr
  * In: 'off' is offset from base in 128M pci map
  */
 static int
-netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
+netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
+		ulong off, void __iomem **addr)
 {
 	crb_128M_2M_sub_block_map_t *m;
 
 
-	if (*off >= NETXEN_CRB_MAX)
-		return -1;
-
-	if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
-		*off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
-			(ulong)adapter->ahw.pci_base0;
-		return 0;
-	}
-
-	if (*off < NETXEN_PCI_CRBSPACE)
-		return -1;
+	if ((off >= NETXEN_CRB_MAX) || (off < NETXEN_PCI_CRBSPACE))
+		return -EINVAL;
 
-	*off -= NETXEN_PCI_CRBSPACE;
+	off -= NETXEN_PCI_CRBSPACE;
 
 	/*
 	 * Try direct map
 	 */
-	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
+	m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
 
-	if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
-		*off = *off + m->start_2M - m->start_128M +
-			(ulong)adapter->ahw.pci_base0;
+	if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
+		*addr = adapter->ahw.pci_base0 + m->start_2M +
+			(off - m->start_128M);
 		return 0;
 	}
 
 	/*
 	 * Not in direct map, use crb window
 	 */
+	*addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M +
+		(off & MASK(16));
 	return 1;
 }
 
@@ -1165,52 +1155,78 @@ netxen_nic_pci_get_crb_addr_2M(struct ne
  * side effect: lock crb window
  */
 static void
-netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
+netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)
 {
-	u32 win_read;
+	u32 window;
+	void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
 
-	adapter->crb_win = CRB_HI(*off);
-	writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M));
-	/*
-	 * Read back value to make sure write has gone through before trying
-	 * to use it.
-	 */
-	win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M);
-	if (win_read != adapter->crb_win) {
-		printk(KERN_ERR "%s: Written crbwin (0x%x) != "
-				"Read crbwin (0x%x), off=0x%lx\n",
-				__func__, adapter->crb_win, win_read, *off);
+	off -= NETXEN_PCI_CRBSPACE;
+
+	window = CRB_HI(off);
+
+	if (adapter->ahw.crb_win == window)
+		return;
+
+	writel(window, addr);
+	if (readl(addr) != window) {
+		if (printk_ratelimit())
+			dev_warn(&adapter->pdev->dev,
+				"failed to set CRB window to %d off 0x%lx\n",
+				window, off);
 	}
-	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
-		(ulong)adapter->ahw.pci_base0;
+	adapter->ahw.crb_win = window;
+}
+
+static void __iomem *
+netxen_nic_map_indirect_address_128M(struct netxen_adapter *adapter,
+		ulong win_off, void __iomem **mem_ptr)
+{
+	ulong off = win_off;
+	void __iomem *addr;
+	resource_size_t mem_base;
+
+	if (ADDR_IN_WINDOW1(win_off))
+		off = NETXEN_CRB_NORMAL(win_off);
+
+	addr = pci_base_offset(adapter, off);
+	if (addr)
+		return addr;
+
+	if (adapter->ahw.pci_len0 == 0)
+		off -= NETXEN_PCI_CRBSPACE;
+
+	mem_base = pci_resource_start(adapter->pdev, 0);
+	*mem_ptr = ioremap(mem_base + (off & PAGE_MASK), PAGE_SIZE);
+	if (*mem_ptr)
+		addr = *mem_ptr + (off & (PAGE_SIZE - 1));
+
+	return addr;
 }
 
 static int
 netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
 	unsigned long flags;
-	void __iomem *addr;
-
-	if (ADDR_IN_WINDOW1(off))
-		addr = NETXEN_CRB_NORMALIZE(adapter, off);
-	else
-		addr = pci_base_offset(adapter, off);
+	void __iomem *addr, *mem_ptr = NULL;
 
-	BUG_ON(!addr);
+	addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
+	if (!addr)
+		return -EIO;
 
-	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
-		read_lock(&adapter->adapter_lock);
-		writel(data, addr);
-		read_unlock(&adapter->adapter_lock);
-	} else {		/* Window 0 */
-		write_lock_irqsave(&adapter->adapter_lock, flags);
-		addr = pci_base_offset(adapter, off);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+	if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
+		netxen_nic_io_write_128M(adapter, addr, data);
+	} else {        /* Window 0 */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		netxen_nic_pci_set_crbwindow_128M(adapter, 0);
 		writel(data, addr);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+		netxen_nic_pci_set_crbwindow_128M(adapter,
+				NETXEN_WINDOW_ONE);
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
 	}
 
+	if (mem_ptr)
+		iounmap(mem_ptr);
+
 	return 0;
 }
 
@@ -1218,28 +1234,27 @@ static u32
 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
 {
 	unsigned long flags;
-	void __iomem *addr;
+	void __iomem *addr, *mem_ptr = NULL;
 	u32 data;
 
-	if (ADDR_IN_WINDOW1(off))
-		addr = NETXEN_CRB_NORMALIZE(adapter, off);
-	else
-		addr = pci_base_offset(adapter, off);
-
-	BUG_ON(!addr);
+	addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
+	if (!addr)
+		return -EIO;
 
-	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
-		read_lock(&adapter->adapter_lock);
-		data = readl(addr);
-		read_unlock(&adapter->adapter_lock);
-	} else {		/* Window 0 */
-		write_lock_irqsave(&adapter->adapter_lock, flags);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+	if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
+		data = netxen_nic_io_read_128M(adapter, addr);
+	} else {        /* Window 0 */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		netxen_nic_pci_set_crbwindow_128M(adapter, 0);
 		data = readl(addr);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+		netxen_nic_pci_set_crbwindow_128M(adapter,
+				NETXEN_WINDOW_ONE);
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
 	}
 
+	if (mem_ptr)
+		iounmap(mem_ptr);
+
 	return data;
 }
 
@@ -1248,28 +1263,30 @@ netxen_nic_hw_write_wx_2M(struct netxen_
 {
 	unsigned long flags;
 	int rv;
+	void __iomem *addr = NULL;
 
-	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
+	rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
 
-	if (rv == -1) {
-		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
-				__func__, off);
-		dump_stack();
-		return -1;
+	if (rv == 0) {
+		writel(data, addr);
+		return 0;
 	}
 
-	if (rv == 1) {
-		write_lock_irqsave(&adapter->adapter_lock, flags);
+	if (rv > 0) {
+		/* indirect access */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
 		crb_win_lock(adapter);
-		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-		writel(data, (void __iomem *)off);
+		netxen_nic_pci_set_crbwindow_2M(adapter, off);
+		writel(data, addr);
 		crb_win_unlock(adapter);
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	} else
-		writel(data, (void __iomem *)off);
-
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		return 0;
+	}
 
-	return 0;
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -EIO;
 }
 
 static u32
@@ -1278,102 +1295,37 @@ netxen_nic_hw_read_wx_2M(struct netxen_a
 	unsigned long flags;
 	int rv;
 	u32 data;
+	void __iomem *addr = NULL;
 
-	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
+	rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
 
-	if (rv == -1) {
-		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
-				__func__, off);
-		dump_stack();
-		return -1;
-	}
+	if (rv == 0)
+		return readl(addr);
 
-	if (rv == 1) {
-		write_lock_irqsave(&adapter->adapter_lock, flags);
+	if (rv > 0) {
+		/* indirect access */
+		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
 		crb_win_lock(adapter);
-		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-		data = readl((void __iomem *)off);
+		netxen_nic_pci_set_crbwindow_2M(adapter, off);
+		data = readl(addr);
 		crb_win_unlock(adapter);
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	} else
-		data = readl((void __iomem *)off);
-
-	return data;
-}
-
-static int netxen_pci_set_window_warning_count;
-
-static unsigned long
-netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
-		unsigned long long addr)
-{
-	void __iomem *offset;
-	int window;
-	unsigned long long	qdr_max;
-	uint8_t func = adapter->ahw.pci_func;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
-	} else {
-		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
+		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		return data;
 	}
 
-	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		/* DDR network side */
-		addr -= NETXEN_ADDR_DDR_NET;
-		window = (addr >> 25) & 0x3ff;
-		if (adapter->ahw.ddr_mn_window != window) {
-			adapter->ahw.ddr_mn_window = window;
-			offset = PCI_OFFSET_SECOND_RANGE(adapter,
-				NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
-			writel(window, offset);
-			/* MUST make sure window is set before we forge on... */
-			readl(offset);
-		}
-		addr -= (window * NETXEN_WINDOW_ONE);
-		addr += NETXEN_PCI_DDR_NET;
-	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
-		addr -= NETXEN_ADDR_OCM0;
-		addr += NETXEN_PCI_OCM0;
-	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
-		addr -= NETXEN_ADDR_OCM1;
-		addr += NETXEN_PCI_OCM1;
-	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
-		/* QDR network side */
-		addr -= NETXEN_ADDR_QDR_NET;
-		window = (addr >> 22) & 0x3f;
-		if (adapter->ahw.qdr_sn_window != window) {
-			adapter->ahw.qdr_sn_window = window;
-			offset = PCI_OFFSET_SECOND_RANGE(adapter,
-				NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
-			writel((window << 22), offset);
-			/* MUST make sure window is set before we forge on... */
-			readl(offset);
-		}
-		addr -= (window * 0x400000);
-		addr += NETXEN_PCI_QDR_NET;
-	} else {
-		/*
-		 * peg gdb frequently accesses memory that doesn't exist,
-		 * this limits the chit chat so debugging isn't slowed down.
-		 */
-		if ((netxen_pci_set_window_warning_count++ < 8)
-		    || (netxen_pci_set_window_warning_count % 64 == 0))
-			printk("%s: Warning:netxen_nic_pci_set_window()"
-			       " Unknown address range!\n",
-			       netxen_nic_driver_name);
-		addr = -1UL;
-	}
-	return addr;
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -1;
 }
 
 /* window 1 registers only */
 static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
 		void __iomem *addr, u32 data)
 {
-	read_lock(&adapter->adapter_lock);
+	read_lock(&adapter->ahw.crb_lock);
 	writel(data, addr);
-	read_unlock(&adapter->adapter_lock);
+	read_unlock(&adapter->ahw.crb_lock);
 }
 
 static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
@@ -1381,9 +1333,9 @@ static u32 netxen_nic_io_read_128M(struc
 {
 	u32 val;
 
-	read_lock(&adapter->adapter_lock);
+	read_lock(&adapter->ahw.crb_lock);
 	val = readl(addr);
-	read_unlock(&adapter->adapter_lock);
+	read_unlock(&adapter->ahw.crb_lock);
 
 	return val;
 }
@@ -1403,488 +1355,437 @@ static u32 netxen_nic_io_read_2M(struct
 void __iomem *
 netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
 {
-	ulong off = offset;
+	void __iomem *addr = NULL;
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		if (offset < NETXEN_CRB_PCIX_HOST2 &&
-				offset > NETXEN_CRB_PCIX_HOST)
-			return PCI_OFFSET_SECOND_RANGE(adapter, offset);
-		return NETXEN_CRB_NORMALIZE(adapter, offset);
+		if ((offset < NETXEN_CRB_PCIX_HOST2) &&
+				(offset > NETXEN_CRB_PCIX_HOST))
+			addr = PCI_OFFSET_SECOND_RANGE(adapter, offset);
+		else
+			addr = NETXEN_CRB_NORMALIZE(adapter, offset);
+	} else {
+		WARN_ON(netxen_nic_pci_get_crb_addr_2M(adapter,
+					offset, &addr));
 	}
 
-	BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off));
-	return (void __iomem *)off;
+	return addr;
 }
 
-static unsigned long
+static int
+netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
+		u64 addr, u32 *start)
+{
+	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+		*start = (addr - NETXEN_ADDR_OCM0  + NETXEN_PCI_OCM0);
+		return 0;
+	} else if (ADDR_IN_RANGE(addr,
+				NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+		*start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
+		return 0;
+	}
+
+	return -EIO;
+}
+
+static int
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
-		unsigned long long addr)
+		u64 addr, u32 *start)
 {
-	int window;
-	u32 win_read;
+	u32 window;
+	struct pci_dev *pdev = adapter->pdev;
 
-	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		/* DDR network side */
-		window = MN_WIN(addr);
-		adapter->ahw.ddr_mn_window = window;
-		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
-		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
-		if ((win_read << 17) != window) {
-			printk(KERN_INFO "Written MNwin (0x%x) != "
-				"Read MNwin (0x%x)\n", window, win_read);
-		}
-		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
-	} else if (ADDR_IN_RANGE(addr,
-				NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
-		if ((addr & 0x00ff800) == 0xff800) {
-			printk("%s: QM access not handled.\n", __func__);
-			addr = -1UL;
-		}
+	if ((addr & 0x00ff800) == 0xff800) {
+		if (printk_ratelimit())
+			dev_warn(&pdev->dev, "QM access not handled\n");
+		return -EIO;
+	}
 
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
+		window = OCM_WIN_P3P(addr);
+	else
 		window = OCM_WIN(addr);
-		adapter->ahw.ddr_mn_window = window;
-		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
-		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
-		if ((win_read >> 7) != window) {
-			printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
-					"Read OCMwin (0x%x)\n",
-					__func__, window, win_read);
-		}
-		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
 
-	} else if (ADDR_IN_RANGE(addr,
-			NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
-		/* QDR network side */
-		window = MS_WIN(addr);
-		adapter->ahw.qdr_sn_window = window;
-		NXWR32(adapter, adapter->ahw.ms_win_crb, window);
-		win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
-		if (win_read != window) {
-			printk(KERN_INFO "%s: Written MSwin (0x%x) != "
-					"Read MSwin (0x%x)\n",
-					__func__, window, win_read);
-		}
-		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
+	writel(window, adapter->ahw.ocm_win_crb);
+	/* read back to flush */
+	readl(adapter->ahw.ocm_win_crb);
 
-	} else {
-		/*
-		 * peg gdb frequently accesses memory that doesn't exist,
-		 * this limits the chit chat so debugging isn't slowed down.
-		 */
-		if ((netxen_pci_set_window_warning_count++ < 8)
-			|| (netxen_pci_set_window_warning_count%64 == 0)) {
-			printk("%s: Warning:%s Unknown address range!\n",
-					__func__, netxen_nic_driver_name);
+	adapter->ahw.ocm_win = window;
+	*start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
+	return 0;
 }
-		addr = -1UL;
+
+static int
+netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
+		u64 *data, int op)
+{
+	void __iomem *addr, *mem_ptr = NULL;
+	resource_size_t mem_base;
+	int ret = -EIO;
+	u32 start;
+
+	spin_lock(&adapter->ahw.mem_lock);
+
+	ret = adapter->pci_set_window(adapter, off, &start);
+	if (ret != 0)
+		goto unlock;
+
+	addr = pci_base_offset(adapter, start);
+	if (addr)
+		goto noremap;
+
+	mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);
+
+	mem_ptr = ioremap(mem_base, PAGE_SIZE);
+	if (mem_ptr == NULL) {
+		ret = -EIO;
+		goto unlock;
 	}
-	return addr;
+
+	addr = mem_ptr + (start & (PAGE_SIZE - 1));
+
+noremap:
+	if (op == 0)	/* read */
+		*data = readq(addr);
+	else		/* write */
+		writeq(*data, addr);
+
+unlock:
+	spin_unlock(&adapter->ahw.mem_lock);
+
+	if (mem_ptr)
+		iounmap(mem_ptr);
+	return ret;
 }
 
 #define MAX_CTL_CHECK   1000
 
 static int
 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size)
+		u64 off, u64 data)
 {
-	unsigned long   flags;
-	int	     i, j, ret = 0, loop, sz[2], off0;
-	uint32_t      temp;
-	uint64_t      off8, tmpw, word[2] = {0, 0};
+	int j, ret;
+	u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
 	void __iomem *mem_crb;
 
-	if (size != 8)
+	/* Only 64-bit aligned access */
+	if (off & 7)
 		return -EIO;
 
+	/* P2 has different SIU and MIU test agent base addr */
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
 				NETXEN_ADDR_QDR_NET_MAX_P2)) {
-		mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+		mem_crb = pci_base_offset(adapter,
+				NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
+		addr_hi = SIU_TEST_AGT_ADDR_HI;
+		data_lo = SIU_TEST_AGT_WRDATA_LO;
+		data_hi = SIU_TEST_AGT_WRDATA_HI;
+		off_lo = off & SIU_TEST_AGT_ADDR_MASK;
+		off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+		mem_crb = pci_base_offset(adapter,
+				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		addr_hi = MIU_TEST_AGT_ADDR_HI;
+		data_lo = MIU_TEST_AGT_WRDATA_LO;
+		data_hi = MIU_TEST_AGT_WRDATA_HI;
+		off_lo = off & MIU_TEST_AGT_ADDR_MASK;
+		off_hi = 0;
 		goto correct;
 	}
 
-	return -EIO;
-
-correct:
-	off8 = off & 0xfffffff8;
-	off0 = off & 0x7;
-	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
-	sz[1] = size - sz[0];
-	loop = ((off0 + size - 1) >> 3) + 1;
-
-	if ((size != 8) || (off0 != 0))  {
-		for (i = 0; i < loop; i++) {
-			if (adapter->pci_mem_read(adapter,
-				off8 + (i << 3), &word[i], 8))
-				return -1;
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
+		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+		if (adapter->ahw.pci_len0 != 0) {
+			return netxen_nic_pci_mem_access_direct(adapter,
+					off, &data, 1);
 		}
 	}
 
-	switch (size) {
-	case 1:
-		tmpw = *((uint8_t *)data);
-		break;
-	case 2:
-		tmpw = *((uint16_t *)data);
-		break;
-	case 4:
-		tmpw = *((uint32_t *)data);
-		break;
-	case 8:
-	default:
-		tmpw = *((uint64_t *)data);
-		break;
-	}
-	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
-	word[0] |= tmpw << (off0 * 8);
-
-	if (loop == 2) {
-		word[1] &= ~(~0ULL << (sz[1] * 8));
-		word[1] |= tmpw >> (sz[0] * 8);
-	}
-
-	write_lock_irqsave(&adapter->adapter_lock, flags);
-	netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+	return -EIO;
 
-	for (i = 0; i < loop; i++) {
-		writel((uint32_t)(off8 + (i << 3)),
-			(mem_crb+MIU_TEST_AGT_ADDR_LO));
-		writel(0,
-			(mem_crb+MIU_TEST_AGT_ADDR_HI));
-		writel(word[i] & 0xffffffff,
-			(mem_crb+MIU_TEST_AGT_WRDATA_LO));
-		writel((word[i] >> 32) & 0xffffffff,
-			(mem_crb+MIU_TEST_AGT_WRDATA_HI));
-		writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-			(mem_crb+MIU_TEST_AGT_CTRL));
-		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-			(mem_crb+MIU_TEST_AGT_CTRL));
+correct:
+	spin_lock(&adapter->ahw.mem_lock);
+	netxen_nic_pci_set_crbwindow_128M(adapter, 0);
 
-		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = readl(
-			     (mem_crb+MIU_TEST_AGT_CTRL));
-			if ((temp & MIU_TA_CTL_BUSY) == 0)
-				break;
-		}
+	writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(off_hi, (mem_crb + addr_hi));
+	writel(data & 0xffffffff, (mem_crb + data_lo));
+	writel((data >> 32) & 0xffffffff, (mem_crb + data_hi));
+	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
+			(mem_crb + TEST_AGT_CTRL));
 
-		if (j >= MAX_CTL_CHECK) {
-			if (printk_ratelimit())
-				dev_err(&adapter->pdev->dev,
-					"failed to write through agent\n");
-			ret = -1;
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl((mem_crb + TEST_AGT_CTRL));
+		if ((temp & TA_CTL_BUSY) == 0)
 			break;
-		}
 	}
 
-	netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to write through agent\n");
+		ret = -EIO;
+	} else
+		ret = 0;
+
+	netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
+	spin_unlock(&adapter->ahw.mem_lock);
 	return ret;
 }
 
 static int
 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size)
+		u64 off, u64 *data)
 {
-	unsigned long   flags;
-	int	     i, j = 0, k, start, end, loop, sz[2], off0[2];
-	uint32_t      temp;
-	uint64_t      off8, val, word[2] = {0, 0};
+	int j, ret;
+	u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
+	u64 val;
 	void __iomem *mem_crb;
 
-	if (size != 8)
+	/* Only 64-bit aligned access */
+	if (off & 7)
 		return -EIO;
 
+	/* P2 has different SIU and MIU test agent base addr */
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
 				NETXEN_ADDR_QDR_NET_MAX_P2)) {
-		mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+		mem_crb = pci_base_offset(adapter,
+				NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
+		addr_hi = SIU_TEST_AGT_ADDR_HI;
+		data_lo = SIU_TEST_AGT_RDDATA_LO;
+		data_hi = SIU_TEST_AGT_RDDATA_HI;
+		off_lo = off & SIU_TEST_AGT_ADDR_MASK;
+		off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+		mem_crb = pci_base_offset(adapter,
+				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+		addr_hi = MIU_TEST_AGT_ADDR_HI;
+		data_lo = MIU_TEST_AGT_RDDATA_LO;
+		data_hi = MIU_TEST_AGT_RDDATA_HI;
+		off_lo = off & MIU_TEST_AGT_ADDR_MASK;
+		off_hi = 0;
 		goto correct;
 	}
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
+		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+		if (adapter->ahw.pci_len0 != 0) {
+			return netxen_nic_pci_mem_access_direct(adapter,
+					off, data, 0);
+		}
+	}
+
 	return -EIO;
 
 correct:
-	off8 = off & 0xfffffff8;
-	off0[0] = off & 0x7;
-	off0[1] = 0;
-	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
-	sz[1] = size - sz[0];
-	loop = ((off0[0] + size - 1) >> 3) + 1;
-
-	write_lock_irqsave(&adapter->adapter_lock, flags);
-	netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-
-	for (i = 0; i < loop; i++) {
-		writel((uint32_t)(off8 + (i << 3)),
-			(mem_crb+MIU_TEST_AGT_ADDR_LO));
-		writel(0,
-			(mem_crb+MIU_TEST_AGT_ADDR_HI));
-		writel(MIU_TA_CTL_ENABLE,
-			(mem_crb+MIU_TEST_AGT_CTRL));
-		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
-			(mem_crb+MIU_TEST_AGT_CTRL));
+	spin_lock(&adapter->ahw.mem_lock);
+	netxen_nic_pci_set_crbwindow_128M(adapter, 0);
 
-		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = readl(
-			      (mem_crb+MIU_TEST_AGT_CTRL));
-			if ((temp & MIU_TA_CTL_BUSY) == 0)
-				break;
-		}
+	writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(off_hi, (mem_crb + addr_hi));
+	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
 
-		if (j >= MAX_CTL_CHECK) {
-			if (printk_ratelimit())
-				dev_err(&adapter->pdev->dev,
-					"failed to read through agent\n");
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl(mem_crb + TEST_AGT_CTRL);
+		if ((temp & TA_CTL_BUSY) == 0)
 			break;
-		}
-
-		start = off0[i] >> 2;
-		end   = (off0[i] + sz[i] - 1) >> 2;
-		for (k = start; k <= end; k++) {
-			word[i] |= ((uint64_t) readl(
-				    (mem_crb +
-				    MIU_TEST_AGT_RDDATA(k))) << (32*k));
-		}
 	}
 
-	netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
-
-	if (j >= MAX_CTL_CHECK)
-		return -1;
-
-	if (sz[0] == 8) {
-		val = word[0];
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
+		ret = -EIO;
 	} else {
-		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
-			((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
-	}
 
-	switch (size) {
-	case 1:
-		*(uint8_t  *)data = val;
-		break;
-	case 2:
-		*(uint16_t *)data = val;
-		break;
-	case 4:
-		*(uint32_t *)data = val;
-		break;
-	case 8:
-		*(uint64_t *)data = val;
-		break;
+		temp = readl(mem_crb + data_hi);
+		val = ((u64)temp << 32);
+		val |= readl(mem_crb + data_lo);
+		*data = val;
+		ret = 0;
 	}
-	return 0;
+
+	netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
+	spin_unlock(&adapter->ahw.mem_lock);
+
+	return ret;
 }
 
 static int
 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size)
+		u64 off, u64 data)
 {
-	int i, j, ret = 0, loop, sz[2], off0;
-	uint32_t temp;
-	uint64_t off8, tmpw, word[2] = {0, 0};
+	int i, j, ret;
+	u32 temp, off8;
+	u64 stride;
 	void __iomem *mem_crb;
 
-	if (size != 8)
+	/* Only 64-bit aligned access */
+	if (off & 7)
 		return -EIO;
 
+	/* P3 onward, test agent base for MIU and SIU is same */
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
 				NETXEN_ADDR_QDR_NET_MAX_P3)) {
-		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+		mem_crb = netxen_get_ioaddr(adapter,
+				NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+		mem_crb = netxen_get_ioaddr(adapter,
+				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
+		return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);
+
 	return -EIO;
 
 correct:
-	off8 = off & 0xfffffff8;
-	off0 = off & 0x7;
-	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
-	sz[1] = size - sz[0];
-	loop = ((off0 + size - 1) >> 3) + 1;
-
-	if ((size != 8) || (off0 != 0)) {
-		for (i = 0; i < loop; i++) {
-			if (adapter->pci_mem_read(adapter,
-					off8 + (i << 3), &word[i], 8))
-				return -1;
-		}
-	}
-
-	switch (size) {
-	case 1:
-		tmpw = *((uint8_t *)data);
-		break;
-	case 2:
-		tmpw = *((uint16_t *)data);
-		break;
-	case 4:
-		tmpw = *((uint32_t *)data);
-		break;
-	case 8:
-	default:
-		tmpw = *((uint64_t *)data);
-	break;
-	}
+	stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
 
-	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
-	word[0] |= tmpw << (off0 * 8);
+	off8 = off & ~(stride-1);
 
-	if (loop == 2) {
-		word[1] &= ~(~0ULL << (sz[1] * 8));
-		word[1] |= tmpw >> (sz[0] * 8);
-	}
+	spin_lock(&adapter->ahw.mem_lock);
 
-	/*
-	 * don't lock here - write_wx gets the lock if each time
-	 * write_lock_irqsave(&adapter->adapter_lock, flags);
-	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	 */
+	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
 
-	for (i = 0; i < loop; i++) {
-		writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO);
-		writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI);
-		writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO);
-		writel((word[i] >> 32) & 0xffffffff,
-				mem_crb+MIU_TEST_AGT_WRDATA_HI);
-		writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
-				mem_crb+MIU_TEST_AGT_CTRL);
-		writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
-				mem_crb+MIU_TEST_AGT_CTRL);
+	i = 0;
+	if (stride == 16) {
+		writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+		writel((TA_CTL_START | TA_CTL_ENABLE),
+				(mem_crb + TEST_AGT_CTRL));
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
-			if ((temp & MIU_TA_CTL_BUSY) == 0)
+			temp = readl(mem_crb + TEST_AGT_CTRL);
+			if ((temp & TA_CTL_BUSY) == 0)
 				break;
 		}
 
 		if (j >= MAX_CTL_CHECK) {
-			if (printk_ratelimit())
-				dev_err(&adapter->pdev->dev,
-					"failed to write through agent\n");
-			ret = -1;
-			break;
+			ret = -EIO;
+			goto done;
 		}
+
+		i = (off & 0xf) ? 0 : 2;
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i));
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+		i = (off & 0xf) ? 2 : 0;
 	}
 
-	/*
-	 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-	 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	 */
+	writel(data & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i));
+	writel((data >> 32) & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+
+	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
+			(mem_crb + TEST_AGT_CTRL));
+
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl(mem_crb + TEST_AGT_CTRL);
+		if ((temp & TA_CTL_BUSY) == 0)
+			break;
+	}
+
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to write through agent\n");
+		ret = -EIO;
+	} else
+		ret = 0;
+
+done:
+	spin_unlock(&adapter->ahw.mem_lock);
+
 	return ret;
 }
 
 static int
 netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size)
+		u64 off, u64 *data)
 {
-	int i, j = 0, k, start, end, loop, sz[2], off0[2];
-	uint32_t      temp;
-	uint64_t      off8, val, word[2] = {0, 0};
+	int j, ret;
+	u32 temp, off8;
+	u64 val, stride;
 	void __iomem *mem_crb;
 
-	if (size != 8)
+	/* Only 64-bit aligned access */
+	if (off & 7)
 		return -EIO;
 
+	/* P3 onward, test agent base for MIU and SIU is same */
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
 				NETXEN_ADDR_QDR_NET_MAX_P3)) {
-		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+		mem_crb = netxen_get_ioaddr(adapter,
+				NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
 	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+		mem_crb = netxen_get_ioaddr(adapter,
+				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
 		goto correct;
 	}
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+		return netxen_nic_pci_mem_access_direct(adapter,
+				off, data, 0);
+	}
+
 	return -EIO;
 
 correct:
-	off8 = off & 0xfffffff8;
-	off0[0] = off & 0x7;
-	off0[1] = 0;
-	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
-	sz[1] = size - sz[0];
-	loop = ((off0[0] + size - 1) >> 3) + 1;
+	stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
 
-	/*
-	 * don't lock here - write_wx gets the lock if each time
-	 * write_lock_irqsave(&adapter->adapter_lock, flags);
-	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	 */
+	off8 = off & ~(stride-1);
 
-	for (i = 0; i < loop; i++) {
-		writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO);
-		writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI);
-		writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL);
-		writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
-				mem_crb + MIU_TEST_AGT_CTRL);
+	spin_lock(&adapter->ahw.mem_lock);
 
-		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
-			if ((temp & MIU_TA_CTL_BUSY) == 0)
-				break;
-		}
+	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+	writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
 
-		if (j >= MAX_CTL_CHECK) {
-			if (printk_ratelimit())
-				dev_err(&adapter->pdev->dev,
-					"failed to read through agent\n");
+	for (j = 0; j < MAX_CTL_CHECK; j++) {
+		temp = readl(mem_crb + TEST_AGT_CTRL);
+		if ((temp & TA_CTL_BUSY) == 0)
 			break;
-		}
-
-		start = off0[i] >> 2;
-		end   = (off0[i] + sz[i] - 1) >> 2;
-		for (k = start; k <= end; k++) {
-			temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
-			word[i] |= ((uint64_t)temp << (32 * k));
-		}
 	}
 
-	/*
-	 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-	 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	 */
-
-	if (j >= MAX_CTL_CHECK)
-		return -1;
-
-	if (sz[0] == 8) {
-		val = word[0];
+	if (j >= MAX_CTL_CHECK) {
+		if (printk_ratelimit())
+			dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
+		ret = -EIO;
 	} else {
-		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
-		((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
-	}
+		off8 = MIU_TEST_AGT_RDDATA_LO;
+		if ((stride == 16) && (off & 0xf))
+			off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
 
-	switch (size) {
-	case 1:
-		*(uint8_t  *)data = val;
-		break;
-	case 2:
-		*(uint16_t *)data = val;
-		break;
-	case 4:
-		*(uint32_t *)data = val;
-		break;
-	case 8:
-		*(uint64_t *)data = val;
-		break;
+		temp = readl(mem_crb + off8 + 4);
+		val = (u64)temp << 32;
+		val |= readl(mem_crb + off8);
+		*data = val;
+		ret = 0;
 	}
-	return 0;
+
+	spin_unlock(&adapter->ahw.mem_lock);
+
+	return ret;
 }
 
 void
@@ -2037,10 +1938,10 @@ void netxen_nic_set_link_parameters(stru
 			return;
 		}
 
-		if (adapter->phy_read
-		    && adapter->phy_read(adapter,
-			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-			     &status) == 0) {
+		if (adapter->phy_read &&
+		    adapter->phy_read(adapter,
+				      NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+				      &status) == 0) {
 			if (netxen_get_phy_link(status)) {
 				switch (netxen_get_phy_speed(status)) {
 				case 0:
@@ -2067,10 +1968,10 @@ void netxen_nic_set_link_parameters(stru
 					adapter->link_duplex = -1;
 					break;
 				}
-				if (adapter->phy_read
-				    && adapter->phy_read(adapter,
-					     NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-					     &autoneg) != 0)
+				if (adapter->phy_read &&
+				    adapter->phy_read(adapter,
+						      NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+						      &autoneg) != 0)
 					adapter->link_autoneg = autoneg;
 			} else
 				goto link_down;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_init.c linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_init.c
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_init.c	2013-05-03 14:01:02.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_init.c	2013-05-03 12:08:15.000000000 -0400
@@ -46,6 +46,7 @@ static unsigned int crb_addr_xform[NETXE
 static void
 netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 		struct nx_host_rds_ring *rds_ring);
+static int netxen_p3_has_mn(struct netxen_adapter *adapter);
 
 static void crb_addr_transform_setup(void)
 {
@@ -183,6 +184,8 @@ skip_rds:
 
 	tx_ring = adapter->tx_ring;
 	vfree(tx_ring->cmd_buf_arr);
+	kfree(tx_ring);
+	adapter->tx_ring = NULL;
 }
 
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
@@ -437,7 +440,7 @@ int netxen_rom_fast_read(struct netxen_a
 #define NETXEN_BOARDNUM 		0x400c
 #define NETXEN_CHIPNUM			0x4010
 
-int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
+int netxen_pinit_from_rom(struct netxen_adapter *adapter)
 {
 	int addr, val;
 	int i, n, init_delay = 0;
@@ -450,21 +453,6 @@ int netxen_pinit_from_rom(struct netxen_
 	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
 	netxen_rom_unlock(adapter);
 
-	if (verbose) {
-		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
-			printk("P2 ROM board type: 0x%08x\n", val);
-		else
-			printk("Could not read board type\n");
-		if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0)
-			printk("P2 ROM board  num: 0x%08x\n", val);
-		else
-			printk("Could not read board number\n");
-		if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0)
-			printk("P2 ROM chip   num: 0x%08x\n", val);
-		else
-			printk("Could not read chip number\n");
-	}
-
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
 			(n != 0xcafecafe) ||
@@ -486,11 +474,7 @@ int netxen_pinit_from_rom(struct netxen_
 		n &= ~0x80000000;
 	}
 
-	if (n < 1024) {
-		if (verbose)
-			printk(KERN_DEBUG "%s: %d CRB init values found"
-			       " in ROM.\n", netxen_nic_driver_name, n);
-	} else {
+	if (n >= 1024) {
 		printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not"
 		       " initialized.\n", __func__, n);
 		return -EIO;
@@ -502,6 +486,7 @@ int netxen_pinit_from_rom(struct netxen_
 				netxen_nic_driver_name);
 		return -ENOMEM;
 	}
+
 	for (i = 0; i < n; i++) {
 		if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
 		netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
@@ -512,11 +497,8 @@ int netxen_pinit_from_rom(struct netxen_
 		buf[i].addr = addr;
 		buf[i].data = val;
 
-		if (verbose)
-			printk(KERN_DEBUG "%s: PCI:     0x%08x == 0x%08x\n",
-				netxen_nic_driver_name,
-				(u32)netxen_decode_crb_addr(addr), val);
 	}
+
 	for (i = 0; i < n; i++) {
 
 		off = netxen_decode_crb_addr(buf[i].addr);
@@ -526,6 +508,10 @@ int netxen_pinit_from_rom(struct netxen_
 			continue;
 		}
 		off += NETXEN_PCI_CRBSPACE;
+
+		if (off & 1)
+			continue;
+
 		/* skipping cold reboot MAGIC */
 		if (off == NETXEN_CAM_RAM(0x1fc))
 			continue;
@@ -546,7 +532,8 @@ int netxen_pinit_from_rom(struct netxen_
 				continue;
 			if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET)
 				continue;
-			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
+			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) &&
+				!NX_IS_REVISION_P3P(adapter->ahw.revision_id))
 				buf[i].data = 0x1020;
 			/* skip the function enable register */
 			if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION))
@@ -607,6 +594,180 @@ int netxen_pinit_from_rom(struct netxen_
 	return 0;
 }
 
+static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
+{
+	uint32_t i;
+	struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
+	__le32 entries = cpu_to_le32(directory->num_entries);
+
+	for (i = 0; i < entries; i++) {
+
+		__le32 offs = cpu_to_le32(directory->findex) +
+				(i * cpu_to_le32(directory->entry_size));
+		__le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8));
+
+		if (tab_type == section)
+			return (struct uni_table_desc *) &unirom[offs];
+	}
+
+	return NULL;
+}
+
+static int
+nx_set_product_offs(struct netxen_adapter *adapter)
+{
+	struct uni_table_desc *ptab_descr;
+	const u8 *unirom = adapter->fw->data;
+	uint32_t i;
+	__le32 entries;
+
+	int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ?
+			1 : netxen_p3_has_mn(adapter);
+
+	ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL);
+	if (ptab_descr == NULL)
+		return -1;
+
+	entries = cpu_to_le32(ptab_descr->num_entries);
+
+nomn:
+	for (i = 0; i < entries; i++) {
+
+		__le32 flags, file_chiprev, offs;
+		u8 chiprev = adapter->ahw.revision_id;
+		uint32_t flagbit;
+
+		offs = cpu_to_le32(ptab_descr->findex) +
+				(i * cpu_to_le32(ptab_descr->entry_size));
+		flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF));
+		file_chiprev = cpu_to_le32(*((int *)&unirom[offs] +
+							NX_UNI_CHIP_REV_OFF));
+
+		flagbit = mn_present ? 1 : 2;
+
+		if ((chiprev == file_chiprev) &&
+					((1ULL << flagbit) & flags)) {
+			adapter->file_prd_off = offs;
+			return 0;
+		}
+	}
+
+	if (mn_present && NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		mn_present = 0;
+		goto nomn;
+	}
+
+	return -1;
+}
+
+
+static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter,
+			u32 section, u32 idx_offset)
+{
+	const u8 *unirom = adapter->fw->data;
+	int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+								idx_offset));
+	struct uni_table_desc *tab_desc;
+	__le32 offs;
+
+	tab_desc = nx_get_table_desc(unirom, section);
+
+	if (tab_desc == NULL)
+		return NULL;
+
+	offs = cpu_to_le32(tab_desc->findex) +
+			(cpu_to_le32(tab_desc->entry_size) * idx);
+
+	return (struct uni_data_desc *)&unirom[offs];
+}
+
+static u8 *
+nx_get_bootld_offs(struct netxen_adapter *adapter)
+{
+	u32 offs = NETXEN_BOOTLD_START;
+
+	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
+		offs = cpu_to_le32((nx_get_data_desc(adapter,
+					NX_UNI_DIR_SECT_BOOTLD,
+					NX_UNI_BOOTLD_IDX_OFF))->findex);
+
+	return (u8 *)&adapter->fw->data[offs];
+}
+
+static u8 *
+nx_get_fw_offs(struct netxen_adapter *adapter)
+{
+	u32 offs = NETXEN_IMAGE_START;
+
+	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
+		offs = cpu_to_le32((nx_get_data_desc(adapter,
+					NX_UNI_DIR_SECT_FW,
+					NX_UNI_FIRMWARE_IDX_OFF))->findex);
+
+	return (u8 *)&adapter->fw->data[offs];
+}
+
+static __le32
+nx_get_fw_size(struct netxen_adapter *adapter)
+{
+	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE)
+		return cpu_to_le32((nx_get_data_desc(adapter,
+					NX_UNI_DIR_SECT_FW,
+					NX_UNI_FIRMWARE_IDX_OFF))->size);
+	else
+		return cpu_to_le32(
+				*(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]);
+}
+
+static __le32
+nx_get_fw_version(struct netxen_adapter *adapter)
+{
+	struct uni_data_desc *fw_data_desc;
+	const struct firmware *fw = adapter->fw;
+	__le32 major, minor, sub;
+	const u8 *ver_str;
+	int i, ret = 0;
+
+	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
+
+		fw_data_desc = nx_get_data_desc(adapter,
+				NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF);
+		ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) +
+				cpu_to_le32(fw_data_desc->size) - 17;
+
+		for (i = 0; i < 12; i++) {
+			if (!strncmp(&ver_str[i], "REV=", 4)) {
+				ret = sscanf(&ver_str[i+4], "%u.%u.%u ",
+							&major, &minor, &sub);
+				break;
+			}
+		}
+
+		if (ret != 3)
+			return 0;
+
+		return major + (minor << 8) + (sub << 16);
+
+	} else
+		return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+}
+
+static __le32
+nx_get_bios_version(struct netxen_adapter *adapter)
+{
+	const struct firmware *fw = adapter->fw;
+	__le32 bios_ver, prd_off = adapter->file_prd_off;
+
+	if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
+		bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
+						+ NX_UNI_BIOS_VERSION_OFF));
+		return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) +
+							(bios_ver >> 24);
+	} else
+		return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+
+}
+
 int
 netxen_need_fw_reset(struct netxen_adapter *adapter)
 {
@@ -623,7 +784,7 @@ netxen_need_fw_reset(struct netxen_adapt
 	if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
 		return 1;
 
-	old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
 
 	for (i = 0; i < 10; i++) {
 
@@ -646,9 +807,8 @@ netxen_need_fw_reset(struct netxen_adapt
 	/* check if we have got newer or different file firmware */
 	if (adapter->fw) {
 
-		const struct firmware *fw = adapter->fw;
+		val = nx_get_fw_version(adapter);
 
-		val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
 		version = NETXEN_DECODE_VERSION(val);
 
 		major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
@@ -658,7 +818,8 @@ netxen_need_fw_reset(struct netxen_adapt
 		if (version > NETXEN_VERSION_CODE(major, minor, build))
 			return 1;
 
-		if (version == NETXEN_VERSION_CODE(major, minor, build)) {
+		if (version == NETXEN_VERSION_CODE(major, minor, build) &&
+			adapter->fw_type != NX_UNIFIED_ROMIMAGE) {
 
 			val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
 			fw_type = (val & 0x4) ?
@@ -673,7 +834,11 @@ netxen_need_fw_reset(struct netxen_adapt
 }
 
 static char *fw_name[] = {
-	"/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", "flash",
+	NX_P2_MN_ROMIMAGE_NAME,
+	NX_P3_CT_ROMIMAGE_NAME,
+	NX_P3_MN_ROMIMAGE_NAME,
+	NX_UNIFIED_ROMIMAGE_NAME,
+	NX_FLASH_ROMIMAGE_NAME,
 };
 
 int
@@ -695,26 +860,28 @@ netxen_load_firmware(struct netxen_adapt
 
 		size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
 
-		ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+		ptr64 = (u64 *)nx_get_bootld_offs(adapter);
 		flashaddr = NETXEN_BOOTLD_START;
 
 		for (i = 0; i < size; i++) {
 			data = cpu_to_le64(ptr64[i]);
-			adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+
+			if (adapter->pci_mem_write(adapter, flashaddr, data))
+				return -EIO;
+
 			flashaddr += 8;
 		}
 
-		size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
-		size = (__force u32)cpu_to_le32(size) / 8;
+		size = (__force u32)nx_get_fw_size(adapter) / 8;
 
-		ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+		ptr64 = (u64 *)nx_get_fw_offs(adapter);
 		flashaddr = NETXEN_IMAGE_START;
 
 		for (i = 0; i < size; i++) {
 			data = cpu_to_le64(ptr64[i]);
 
 			if (adapter->pci_mem_write(adapter,
-						flashaddr, &data, 8))
+						flashaddr, data))
 				return -EIO;
 
 			flashaddr += 8;
@@ -728,17 +895,17 @@ netxen_load_firmware(struct netxen_adapt
 
 		for (i = 0; i < size; i++) {
 			if (netxen_rom_fast_read(adapter,
-					flashaddr, &lo) != 0)
+					flashaddr, (int *)&lo) != 0)
 				return -EIO;
 			if (netxen_rom_fast_read(adapter,
-					flashaddr + 4, &hi) != 0)
+					flashaddr + 4, (int *)&hi) != 0)
 				return -EIO;
 
 			/* hi, lo are already in host endian byteorder */
 			data = (((u64)hi << 32) | lo);
 
 			if (adapter->pci_mem_write(adapter,
-						flashaddr, &data, 8))
+						flashaddr, data))
 				return -EIO;
 
 			flashaddr += 8;
@@ -746,7 +913,10 @@ netxen_load_firmware(struct netxen_adapt
 	}
 	msleep(1);
 
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
+		NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020);
+		NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e);
+	} else if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
 	else {
 		NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
@@ -757,21 +927,31 @@ netxen_load_firmware(struct netxen_adapt
 }
 
 static int
-netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
+netxen_validate_firmware(struct netxen_adapter *adapter)
 {
 	__le32 val;
-	u32 ver, min_ver, bios;
+	u32 ver, min_ver, bios, min_size;
 	struct pci_dev *pdev = adapter->pdev;
 	const struct firmware *fw = adapter->fw;
+	u8 fw_type = adapter->fw_type;
 
-	if (fw->size < NX_FW_MIN_SIZE)
-		return -EINVAL;
+	if (fw_type == NX_UNIFIED_ROMIMAGE) {
+		if (nx_set_product_offs(adapter))
+			return -EINVAL;
 
-	val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
-	if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+		min_size = NX_UNI_FW_MIN_SIZE;
+	} else {
+		val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+		if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+			return -EINVAL;
+
+		min_size = NX_FW_MIN_SIZE;
+	}
+
+	if (fw->size < min_size)
 		return -EINVAL;
 
-	val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+	val = nx_get_fw_version(adapter);
 
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		min_ver = NETXEN_VERSION_CODE(4, 0, 216);
@@ -783,15 +963,15 @@ netxen_validate_firmware(struct netxen_a
 	if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
 		dev_err(&pdev->dev,
 				"%s: firmware version %d.%d.%d unsupported\n",
-				fwname, _major(ver), _minor(ver), _build(ver));
+		fw_name[fw_type], _major(ver), _minor(ver), _build(ver));
 		return -EINVAL;
 	}
 
-	val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+	val = nx_get_bios_version(adapter);
 	netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
 	if ((__force u32)val != bios) {
 		dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
-				fwname);
+				fw_name[fw_type]);
 		return -EINVAL;
 	}
 
@@ -802,7 +982,7 @@ netxen_validate_firmware(struct netxen_a
 	val = NETXEN_DECODE_VERSION(val);
 	if (val > ver) {
 		dev_info(&pdev->dev, "%s: firmware is older than flash\n",
-				fwname);
+				fw_name[fw_type]);
 		return -EINVAL;
 	}
 
@@ -810,12 +990,51 @@ netxen_validate_firmware(struct netxen_a
 	return 0;
 }
 
+static void
+nx_get_next_fwtype(struct netxen_adapter *adapter)
+{
+	u8 fw_type;
+
+	switch (adapter->fw_type) {
+	case NX_UNKNOWN_ROMIMAGE:
+		fw_type = NX_UNIFIED_ROMIMAGE;
+		break;
+
+	case NX_UNIFIED_ROMIMAGE:
+		if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
+			fw_type = NX_FLASH_ROMIMAGE;
+		else if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+			fw_type = NX_P2_MN_ROMIMAGE;
+		else if (netxen_p3_has_mn(adapter))
+			fw_type = NX_P3_MN_ROMIMAGE;
+		else
+			fw_type = NX_P3_CT_ROMIMAGE;
+		break;
+
+	case NX_P3_MN_ROMIMAGE:
+		fw_type = NX_P3_CT_ROMIMAGE;
+		break;
+
+	case NX_P2_MN_ROMIMAGE:
+	case NX_P3_CT_ROMIMAGE:
+	default:
+		fw_type = NX_FLASH_ROMIMAGE;
+		break;
+	}
+
+	adapter->fw_type = fw_type;
+}
+
 static int
 netxen_p3_has_mn(struct netxen_adapter *adapter)
 {
 	u32 capability, flashed_ver;
 	capability = 0;
 
+	/* NX2031 always had MN */
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 1;
+
 	netxen_rom_fast_read(adapter,
 			NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
 	flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
@@ -831,49 +1050,29 @@ netxen_p3_has_mn(struct netxen_adapter *
 
 void netxen_reject_firmware(struct netxen_adapter *adapter)
 {
-	u8 fw_type;
 	struct pci_dev *pdev = adapter->pdev;
 	int rc = 0;
 
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		fw_type = NX_P2_MN_ROMIMAGE;
-		goto request_fw;
-	}
-
-	fw_type = netxen_p3_has_mn(adapter) ?
-		NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE;
+	adapter->fw_type = NX_UNKNOWN_ROMIMAGE;
 
-request_fw:
-	rc = reject_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
-	if (rc != 0) {
-		if (fw_type == NX_P3_MN_ROMIMAGE) {
-			msleep(1);
-			fw_type = NX_P3_CT_ROMIMAGE;
-			goto request_fw;
-		}
+next:
+	nx_get_next_fwtype(adapter);
 
-		fw_type = NX_FLASH_ROMIMAGE;
+	if (adapter->fw_type == NX_FLASH_ROMIMAGE) {
 		adapter->fw = NULL;
-		goto done;
-	}
-
-	rc = netxen_validate_firmware(adapter, fw_name[fw_type]);
-	if (rc != 0) {
-		release_firmware(adapter->fw);
+	} else {
+		rc = reject_firmware(&adapter->fw,
+				fw_name[adapter->fw_type], &pdev->dev);
+		if (rc != 0)
+			goto next;
 
-		if (fw_type == NX_P3_MN_ROMIMAGE) {
+		rc = netxen_validate_firmware(adapter);
+		if (rc != 0) {
+			release_firmware(adapter->fw);
 			msleep(1);
-			fw_type = NX_P3_CT_ROMIMAGE;
-			goto request_fw;
+			goto next;
 		}
-
-		fw_type = NX_FLASH_ROMIMAGE;
-		adapter->fw = NULL;
-		goto done;
 	}
-
-done:
-	adapter->fw_type = fw_type;
 }
 
 
@@ -1508,10 +1707,8 @@ netxen_post_rx_buffers(struct netxen_ada
 					      (rds_ring->num_desc - 1)));
 			netxen_set_msg_ctxid(msg, adapter->portnum);
 			netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
-			read_lock(&adapter->adapter_lock);
-			writel(msg, DB_NORMALIZE(adapter,
-					    NETXEN_RCV_PRODUCER_OFFSET));
-			read_unlock(&adapter->adapter_lock);
+			NXWRIO(adapter, DB_NORMALIZE(adapter,
+					NETXEN_RCV_PRODUCER_OFFSET), msg);
 		}
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_main.c linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/netxen/netxen_nic_main.c	2013-05-03 14:01:00.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/netxen/netxen_nic_main.c	2013-05-03 12:08:20.000000000 -0400
@@ -34,13 +34,15 @@
 #include <net/ip.h>
 #include <linux/ipv6.h>
 #include <linux/inetdevice.h>
+#include <linux/sysfs.h>
 
-MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
+MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
+/*(DEBLOBBED)*/
 
 char netxen_nic_driver_name[] = "netxen_nic";
-static char netxen_nic_driver_string[] = "NetXen Network Driver version "
+static char netxen_nic_driver_string[] = "QLogic/NetXen Network Driver v"
     NETXEN_NIC_LINUX_VERSIONID;
 
 static int port_mode = NETXEN_PORT_MODE_AUTO_NEG;
@@ -52,7 +54,10 @@ static int use_msi = 1;
 
 static int use_msi_x = 1;
 
-/* Local functions to NetXen NIC driver */
+static int auto_fw_reset = AUTO_FW_RESET_ENABLED;
+module_param(auto_fw_reset, int, 0644);
+MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled");
+
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 static void __devexit netxen_nic_remove(struct pci_dev *pdev);
@@ -73,6 +78,8 @@ static void netxen_nic_poll_controller(s
 
 static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
 static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
+static void netxen_create_diag_entries(struct netxen_adapter *adapter);
+static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
 
 static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
 static int netxen_can_start_firmware(struct netxen_adapter *adapter);
@@ -330,7 +337,7 @@ netxen_check_hw_init(struct netxen_adapt
 		if (!(first_boot & 0x4)) {
 			first_boot |= 0x4;
 			NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
-			first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
+			NXRD32(adapter, NETXEN_PCIE_REG(0x4));
 		}
 
 		/* This is the first boot after power up */
@@ -609,14 +616,12 @@ netxen_setup_pci_map(struct netxen_adapt
 	 * Set the CRB window to invalid. If any register in window 0 is
 	 * accessed it should set the window to 0 and then reset it to 1.
 	 */
-	adapter->curr_window = 255;
-	adapter->ahw.qdr_sn_window = -1;
-	adapter->ahw.ddr_mn_window = -1;
+	adapter->ahw.crb_win = -1;
+	adapter->ahw.ocm_win = -1;
 
 	/* remap phys address */
 	mem_base = pci_resource_start(pdev, 0);	/* 0 is for BAR 0 */
 	mem_len = pci_resource_len(pdev, 0);
-	pci_len0 = 0;
 
 	/* 128 Meg of memory */
 	if (mem_len == NETXEN_PCI_128MB_SIZE) {
@@ -625,6 +630,7 @@ netxen_setup_pci_map(struct netxen_adapt
 				SECOND_PAGE_GROUP_SIZE);
 		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
 				THIRD_PAGE_GROUP_SIZE);
+		pci_len0 = FIRST_PAGE_GROUP_SIZE;
 	} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
 		mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
 		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
@@ -637,19 +643,6 @@ netxen_setup_pci_map(struct netxen_adapt
 			return -EIO;
 		}
 		pci_len0 = mem_len;
-
-		adapter->ahw.ddr_mn_window = 0;
-		adapter->ahw.qdr_sn_window = 0;
-
-		adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE +
-			0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20);
-		adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE +
-			0x100000 + PCIX_SN_WINDOW;
-		if (pci_func < 4)
-			adapter->ahw.ms_win_crb += (pci_func * 0x20);
-		else
-			adapter->ahw.ms_win_crb +=
-					0xA0 + ((pci_func - 4) * 0x10);
 	} else {
 		return -EIO;
 	}
@@ -663,6 +656,15 @@ netxen_setup_pci_map(struct netxen_adapt
 	adapter->ahw.pci_base1 = mem_ptr1;
 	adapter->ahw.pci_base2 = mem_ptr2;
 
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
+		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
+			NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
+
+	} else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
+			NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func)));
+	}
+
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		goto skip_doorbell;
 
@@ -727,7 +729,8 @@ netxen_check_options(struct netxen_adapt
 	if (adapter->portnum == 0) {
 		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
 
-		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+		pr_info("%s: %s Board S/N %s  Chip rev 0x%x\n",
+				module_name(THIS_MODULE),
 				brd_name, serial_num, adapter->ahw.revision_id);
 	}
 
@@ -815,11 +818,11 @@ netxen_start_firmware(struct netxen_adap
 	if (err < 0)
 		goto err_out;
 	if (err == 0)
-		goto ready;
+		goto wait_init;
 
 	if (first_boot != 0x55555555) {
 		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
-		netxen_pinit_from_rom(adapter, 0);
+		netxen_pinit_from_rom(adapter);
 		msleep(1);
 	}
 
@@ -858,9 +861,6 @@ netxen_start_firmware(struct netxen_adap
 		| (_NETXEN_NIC_LINUX_SUBVERSION);
 	NXWR32(adapter, CRB_DRIVER_VERSION, val);
 
-ready:
-	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
-
 wait_init:
 	/* Handshake with the card before we register the devices. */
 	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -869,6 +869,8 @@ wait_init:
 		goto err_out;
 	}
 
+	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
+
 	nx_update_dma_mask(adapter);
 
 	netxen_check_options(adapter);
@@ -943,8 +945,9 @@ netxen_nic_init_coalesce_defaults(struct
 		NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS;
 }
 
+/* with rtnl_lock */
 static int
-netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+__netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 {
 	int err;
 
@@ -985,14 +988,32 @@ netxen_nic_up(struct netxen_adapter *ada
 	return 0;
 }
 
+/* Usage: During resume and firmware recovery module.*/
+
+static inline int
+netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	int err = 0;
+
+	rtnl_lock();
+	if (netif_running(netdev))
+		err = __netxen_nic_up(adapter, netdev);
+	rtnl_unlock();
+
+	return err;
+}
+
+/* with rtnl_lock */
 static void
-netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+__netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 {
 	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
 		return;
 
-	clear_bit(__NX_DEV_UP, &adapter->state);
+	if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state))
+		return;
 
+	smp_mb();
 	spin_lock(&adapter->tx_clean_lock);
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
@@ -1011,6 +1032,17 @@ netxen_nic_down(struct netxen_adapter *a
 	spin_unlock(&adapter->tx_clean_lock);
 }
 
+/* Usage: During suspend and firmware recovery module */
+
+static inline void
+netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	rtnl_lock();
+	if (netif_running(netdev))
+		__netxen_nic_down(adapter, netdev);
+	rtnl_unlock();
+
+}
 
 static int
 netxen_nic_attach(struct netxen_adapter *adapter)
@@ -1119,14 +1151,14 @@ netxen_nic_reset_context(struct netxen_a
 		netif_device_detach(netdev);
 
 		if (netif_running(netdev))
-			netxen_nic_down(adapter, netdev);
+			__netxen_nic_down(adapter, netdev);
 
 		netxen_nic_detach(adapter);
 
 		if (netif_running(netdev)) {
 			err = netxen_nic_attach(adapter);
 			if (!err)
-				err = netxen_nic_up(adapter, netdev);
+				err = __netxen_nic_up(adapter, netdev);
 
 			if (err)
 				goto done;
@@ -1209,16 +1241,10 @@ netxen_nic_probe(struct pci_dev *pdev, c
 	int pci_func_id = PCI_FUNC(pdev->devfn);
 	uint8_t revision_id;
 
-	if (pdev->class != 0x020000) {
-		printk(KERN_DEBUG "NetXen function %d, class %x will not "
-				"be enabled.\n",pci_func_id, pdev->class);
-		return -ENODEV;
-	}
-
 	if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
-		printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+		pr_warning("%s: chip revisions between 0x%x-0x%x"
 				"will not be enabled.\n",
-				NX_P3_A0, NX_P3_B1);
+				module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
 		return -ENODEV;
 	}
 
@@ -1252,7 +1278,9 @@ netxen_nic_probe(struct pci_dev *pdev, c
 	revision_id = pdev->revision;
 	adapter->ahw.revision_id = revision_id;
 
-	rwlock_init(&adapter->adapter_lock);
+	rwlock_init(&adapter->ahw.crb_lock);
+	spin_lock_init(&adapter->ahw.mem_lock);
+
 	spin_lock_init(&adapter->tx_clean_lock);
 	INIT_LIST_HEAD(&adapter->mac_list);
 
@@ -1282,7 +1310,7 @@ netxen_nic_probe(struct pci_dev *pdev, c
 
 	err = netxen_start_firmware(adapter);
 	if (err)
-		goto err_out_iounmap;
+		goto err_out_decr_ref;
 
 	/*
 	 * See if the firmware gave us a virtual-physical port mapping.
@@ -1317,6 +1345,8 @@ netxen_nic_probe(struct pci_dev *pdev, c
 		break;
 	}
 
+	netxen_create_diag_entries(adapter);
+
 	return 0;
 
 err_out_disable_msi:
@@ -1324,6 +1354,7 @@ err_out_disable_msi:
 
 	netxen_free_dummy_dma(adapter);
 
+err_out_decr_ref:
 	nx_decr_dev_ref_cnt(adapter);
 
 err_out_iounmap:
@@ -1369,6 +1400,8 @@ static void __devexit netxen_nic_remove(
 
 	netxen_teardown_intr(adapter);
 
+	netxen_remove_diag_entries(adapter);
+
 	netxen_cleanup_pci_map(adapter);
 
 	netxen_release_firmware(adapter);
@@ -1449,7 +1482,8 @@ netxen_nic_resume(struct pci_dev *pdev)
 	if (err)
 		return err;
 
-	adapter->curr_window = 255;
+	adapter->ahw.crb_win = -1;
+	adapter->ahw.ocm_win = -1;
 
 	err = netxen_start_firmware(adapter);
 	if (err) {
@@ -1494,7 +1528,7 @@ static int netxen_nic_open(struct net_de
 	if (err)
 		return err;
 
-	err = netxen_nic_up(adapter, netdev);
+	err = __netxen_nic_up(adapter, netdev);
 	if (err)
 		goto err_out;
 
@@ -1514,7 +1548,7 @@ static int netxen_nic_close(struct net_d
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 
-	netxen_nic_down(adapter, netdev);
+	__netxen_nic_down(adapter, netdev);
 	return 0;
 }
 
@@ -1861,12 +1895,8 @@ static void netxen_nic_handle_phy_intr(s
 		linkup = (val == XG_LINK_UP_P3);
 	} else {
 		val = NXRD32(adapter, CRB_XG_STATE);
-		if (adapter->ahw.port_type == NETXEN_NIC_GBE)
-			linkup = (val >> port) & 1;
-		else {
-			val = (val >> port*8) & 0xff;
-			linkup = (val == XG_LINK_UP);
-		}
+		val = (val >> port*8) & 0xff;
+		linkup = (val == XG_LINK_UP);
 	}
 
 	netxen_advert_link_change(adapter, linkup);
@@ -1908,7 +1938,7 @@ static void netxen_tx_timeout_task(struc
 		netif_wake_queue(adapter->netdev);
 
 		clear_bit(__NX_RESETTING, &adapter->state);
-
+		return;
 	} else {
 		clear_bit(__NX_RESETTING, &adapter->state);
 		if (!netxen_nic_reset_context(adapter)) {
@@ -1927,7 +1957,7 @@ request_reset:
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
-	struct net_device_stats *stats = &adapter->net_stats;
+	struct net_device_stats *stats = &netdev->stats;
 
 	memset(stats, 0, sizeof(*stats));
 
@@ -2020,7 +2050,7 @@ static int netxen_nic_poll(struct napi_s
 
 	if ((work_done < budget) && tx_complete) {
 		napi_complete(&sds_ring->napi);
-		if (netif_running(adapter->netdev))
+		if (test_bit(__NX_DEV_UP, &adapter->state))
 			netxen_nic_enable_int(sds_ring);
 	}
 
@@ -2184,14 +2214,13 @@ netxen_fwinit_work(struct work_struct *w
 					netxen_fwinit_work, 2 * FW_POLL_DELAY);
 			return;
 		}
-		break;
 
 	case NX_DEV_FAILED:
 	default:
+		nx_incr_dev_ref_cnt(adapter);
 		break;
 	}
 
-	nx_incr_dev_ref_cnt(adapter);
 	clear_bit(__NX_RESETTING, &adapter->state);
 }
 
@@ -2206,25 +2235,31 @@ netxen_detach_work(struct work_struct *w
 
 	netif_device_detach(netdev);
 
-	if (netif_running(netdev))
-		netxen_nic_down(adapter, netdev);
+	netxen_nic_down(adapter, netdev);
 
+	rtnl_lock();
 	netxen_nic_detach(adapter);
+	rtnl_unlock();
 
 	status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
 
-	ref_cnt = nx_decr_dev_ref_cnt(adapter);
-
 	if (status & NX_RCODE_FATAL_ERROR)
-		return;
+		goto err_ret;
 
 	if (adapter->temp == NX_TEMP_PANIC)
-		return;
+		goto err_ret;
+
+	ref_cnt = nx_decr_dev_ref_cnt(adapter);
 
 	delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
 
 	adapter->fw_wait_cnt = 0;
 	netxen_schedule_work(adapter, netxen_fwinit_work, delay);
+
+	return;
+
+err_ret:
+	clear_bit(__NX_RESETTING, &adapter->state);
 }
 
 static int
@@ -2263,7 +2298,8 @@ netxen_check_health(struct netxen_adapte
 	dev_info(&netdev->dev, "firmware hang detected\n");
 
 detach:
-	if (!test_and_set_bit(__NX_RESETTING, &adapter->state))
+	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
+			!test_and_set_bit(__NX_RESETTING, &adapter->state))
 		netxen_schedule_work(adapter, netxen_detach_work, 0);
 	return 1;
 }
@@ -2341,6 +2377,161 @@ static struct device_attribute dev_attr_
        .store = netxen_store_bridged_mode,
 };
 
+static ssize_t
+netxen_store_diag_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+	unsigned long new;
+
+	if (strict_strtoul(buf, 2, &new))
+		return -EINVAL;
+
+	if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
+		adapter->flags ^= NETXEN_NIC_DIAG_ENABLED;
+
+	return len;
+}
+
+static ssize_t
+netxen_show_diag_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n",
+			!!(adapter->flags & NETXEN_NIC_DIAG_ENABLED));
+}
+
+static struct device_attribute dev_attr_diag_mode = {
+	.attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
+	.show = netxen_show_diag_mode,
+	.store = netxen_store_diag_mode,
+};
+
+static int
+netxen_sysfs_validate_crb(struct netxen_adapter *adapter,
+		loff_t offset, size_t size)
+{
+	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
+		return -EIO;
+
+	if ((size != 4) || (offset & 0x3))
+		return  -EINVAL;
+
+	if (offset < NETXEN_PCI_CRBSPACE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static ssize_t
+netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	ret = netxen_sysfs_validate_crb(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	data = NXRD32(adapter, offset);
+	memcpy(buf, &data, size);
+	return size;
+}
+
+static ssize_t
+netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	ret = netxen_sysfs_validate_crb(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	memcpy(&data, buf, size);
+	NXWR32(adapter, offset, data);
+	return size;
+}
+
+static int
+netxen_sysfs_validate_mem(struct netxen_adapter *adapter,
+		loff_t offset, size_t size)
+{
+	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
+		return -EIO;
+
+	if ((size != 8) || (offset & 0x7))
+		return  -EIO;
+
+	return 0;
+}
+
+static ssize_t
+netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+	u64 data;
+	int ret;
+
+	ret = netxen_sysfs_validate_mem(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	if (adapter->pci_mem_read(adapter, offset, &data))
+		return -EIO;
+
+	memcpy(buf, &data, size);
+
+	return size;
+}
+
+ssize_t netxen_sysfs_write_mem(struct kobject *kobj,
+		struct bin_attribute *attr, char *buf,
+		loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct netxen_adapter *adapter = dev_get_drvdata(dev);
+	u64 data;
+	int ret;
+
+	ret = netxen_sysfs_validate_mem(adapter, offset, size);
+	if (ret != 0)
+		return ret;
+
+	memcpy(&data, buf, size);
+
+	if (adapter->pci_mem_write(adapter, offset, data))
+		return -EIO;
+
+	return size;
+}
+
+
+static struct bin_attribute bin_attr_crb = {
+	.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = netxen_sysfs_read_crb,
+	.write = netxen_sysfs_write_crb,
+};
+
+static struct bin_attribute bin_attr_mem = {
+	.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = netxen_sysfs_read_mem,
+	.write = netxen_sysfs_write_mem,
+};
+
+
 static void
 netxen_create_sysfs_entries(struct netxen_adapter *adapter)
 {
@@ -2366,6 +2557,33 @@ netxen_remove_sysfs_entries(struct netxe
 		device_remove_file(dev, &dev_attr_bridged_mode);
 }
 
+static void
+netxen_create_diag_entries(struct netxen_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct device *dev;
+
+	dev = &pdev->dev;
+	if (device_create_file(dev, &dev_attr_diag_mode))
+		dev_info(dev, "failed to create diag_mode sysfs entry\n");
+	if (device_create_bin_file(dev, &bin_attr_crb))
+		dev_info(dev, "failed to create crb sysfs entry\n");
+	if (device_create_bin_file(dev, &bin_attr_mem))
+		dev_info(dev, "failed to create mem sysfs entry\n");
+}
+
+
+static void
+netxen_remove_diag_entries(struct netxen_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct device *dev = &pdev->dev;
+
+	device_remove_file(dev, &dev_attr_diag_mode);
+	device_remove_bin_file(dev, &bin_attr_crb);
+	device_remove_bin_file(dev, &bin_attr_mem);
+}
+
 #ifdef CONFIG_INET
 
 #define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)
@@ -2524,7 +2742,6 @@ static int __init netxen_init_module(voi
 	register_netdevice_notifier(&netxen_netdev_cb);
 	register_inetaddr_notifier(&netxen_inetaddr_cb);
 #endif
-
 	return pci_register_driver(&netxen_driver);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/netx-eth.c linux-libre-2.6.33-gnu1/drivers/net/netx-eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/netx-eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/netx-eth.c	2013-05-03 12:02:48.000000000 -0400
@@ -212,7 +212,7 @@ static int netx_eth_open(struct net_devi
 	struct netx_eth_priv *priv = netdev_priv(ndev);
 
 	if (request_irq
-	    (ndev->irq, &netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
+	    (ndev->irq, netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
 		return -EAGAIN;
 
 	writel(ndev->dev_addr[0] |
@@ -510,3 +510,4 @@ module_exit(netx_eth_cleanup);
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" CARDNAME);
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ni5010.c linux-libre-2.6.33-gnu1/drivers/net/ni5010.c
--- linux-libre-2.6.32-gnu1/drivers/net/ni5010.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ni5010.c	2010-02-24 13:52:17.000000000 -0500
@@ -377,7 +377,7 @@ static int ni5010_open(struct net_device
 
 	PRINTK2((KERN_DEBUG "%s: entering ni5010_open()\n", dev->name));
 
-	if (request_irq(dev->irq, &ni5010_interrupt, 0, boardname, dev)) {
+	if (request_irq(dev->irq, ni5010_interrupt, 0, boardname, dev)) {
 		printk(KERN_WARNING "%s: Cannot get irq %#2x\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ni52.c linux-libre-2.6.33-gnu1/drivers/net/ni52.c
--- linux-libre-2.6.32-gnu1/drivers/net/ni52.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ni52.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,7 +284,7 @@ static int ni52_open(struct net_device *
 	startrecv586(dev);
 	ni_enaint();
 
-	ret = request_irq(dev->irq, &ni52_interrupt, 0, dev->name, dev);
+	ret = request_irq(dev->irq, ni52_interrupt, 0, dev->name, dev);
 	if (ret) {
 		ni_reset586();
 		return ret;
@@ -477,8 +477,8 @@ static int __init ni52_probe1(struct net
 	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = inb(dev->base_addr+i);
 
-	if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
-		 || dev->dev_addr[2] != NI52_ADDR2) {
+	if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 ||
+	    dev->dev_addr[2] != NI52_ADDR2) {
 		retval = -ENODEV;
 		goto out;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ni65.c linux-libre-2.6.33-gnu1/drivers/net/ni65.c
--- linux-libre-2.6.32-gnu1/drivers/net/ni65.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ni65.c	2010-02-24 13:52:17.000000000 -0500
@@ -294,7 +294,7 @@ static void ni65_set_performance(struct
 static int ni65_open(struct net_device *dev)
 {
 	struct priv *p = dev->ml_priv;
-	int irqval = request_irq(dev->irq, &ni65_interrupt,0,
+	int irqval = request_irq(dev->irq, ni65_interrupt,0,
                         cards[p->cardno].cardname,dev);
 	if (irqval) {
 		printk(KERN_ERR "%s: unable to get IRQ %d (irqval=%d).\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/niu.c linux-libre-2.6.33-gnu1/drivers/net/niu.c
--- linux-libre-2.6.32-gnu1/drivers/net/niu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/niu.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,10 +45,6 @@ MODULE_DESCRIPTION("NIU ethernet driver"
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-#ifndef DMA_44BIT_MASK
-#define DMA_44BIT_MASK	0x00000fffffffffffULL
-#endif
-
 #ifndef readq
 static u64 readq(void __iomem *reg)
 {
@@ -2848,7 +2844,7 @@ static int tcam_wait_bit(struct niu *np,
 			break;
 		udelay(1);
 	}
-	if (limit < 0)
+	if (limit <= 0)
 		return -ENODEV;
 
 	return 0;
@@ -7855,10 +7851,13 @@ static void niu_get_strings(struct net_d
 	}
 }
 
-static int niu_get_stats_count(struct net_device *dev)
+static int niu_get_sset_count(struct net_device *dev, int stringset)
 {
 	struct niu *np = netdev_priv(dev);
 
+	if (stringset != ETH_SS_STATS)
+		return -EINVAL;
+
 	return ((np->flags & NIU_FLAGS_XMAC ?
 		 NUM_XMAC_STAT_KEYS :
 		 NUM_BMAC_STAT_KEYS) +
@@ -7978,7 +7977,7 @@ static const struct ethtool_ops niu_etht
 	.get_settings		= niu_get_settings,
 	.set_settings		= niu_set_settings,
 	.get_strings		= niu_get_strings,
-	.get_stats_count	= niu_get_stats_count,
+	.get_sset_count		= niu_get_sset_count,
 	.get_ethtool_stats	= niu_get_ethtool_stats,
 	.phys_id		= niu_phys_id,
 	.get_rxnfc		= niu_get_nfc,
@@ -8144,7 +8143,7 @@ static void __devinit niu_vpd_parse_vers
 	int i;
 
 	for (i = 0; i < len - 5; i++) {
-		if (!strncmp(s + i, "FCode ", 5))
+		if (!strncmp(s + i, "FCode ", 6))
 			break;
 	}
 	if (i >= len - 5)
@@ -9915,7 +9914,7 @@ static int __devinit niu_pci_init_one(st
 		  PCI_EXP_DEVCTL_RELAX_EN);
 	pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
 
-	dma_mask = DMA_44BIT_MASK;
+	dma_mask = DMA_BIT_MASK(44);
 	err = pci_set_dma_mask(pdev, dma_mask);
 	if (!err) {
 		dev->features |= NETIF_F_HIGHDMA;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ns83820.c linux-libre-2.6.33-gnu1/drivers/net/ns83820.c
--- linux-libre-2.6.32-gnu1/drivers/net/ns83820.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ns83820.c	2010-02-24 13:52:17.000000000 -0500
@@ -648,8 +648,8 @@ static void phy_intr(struct net_device *
 		dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n",
 			tbisr, tanar, tanlpar);
 
-		if ( (fullduplex = (tanlpar & TANAR_FULL_DUP)
-		      && (tanar & TANAR_FULL_DUP)) ) {
+		if ( (fullduplex = (tanlpar & TANAR_FULL_DUP) &&
+		      (tanar & TANAR_FULL_DUP)) ) {
 
 			/* both of us are full duplex */
 			writel(readl(dev->base + TXCFG)
@@ -661,12 +661,12 @@ static void phy_intr(struct net_device *
 			writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT,
 			       dev->base + GPIOR);
 
-		} else if(((tanlpar & TANAR_HALF_DUP)
-			   && (tanar & TANAR_HALF_DUP))
-			|| ((tanlpar & TANAR_FULL_DUP)
-			    && (tanar & TANAR_HALF_DUP))
-			|| ((tanlpar & TANAR_HALF_DUP)
-			    && (tanar & TANAR_FULL_DUP))) {
+		} else if (((tanlpar & TANAR_HALF_DUP) &&
+			    (tanar & TANAR_HALF_DUP)) ||
+			   ((tanlpar & TANAR_FULL_DUP) &&
+			    (tanar & TANAR_HALF_DUP)) ||
+			   ((tanlpar & TANAR_HALF_DUP) &&
+			    (tanar & TANAR_FULL_DUP))) {
 
 			/* one or both of us are half duplex */
 			writel((readl(dev->base + TXCFG)
@@ -720,16 +720,16 @@ static void phy_intr(struct net_device *
 
 	newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
 
-	if (newlinkstate & LINK_UP
-	    && dev->linkstate != newlinkstate) {
+	if (newlinkstate & LINK_UP &&
+	    dev->linkstate != newlinkstate) {
 		netif_start_queue(ndev);
 		netif_wake_queue(ndev);
 		printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
 			ndev->name,
 			speeds[speed],
 			fullduplex ? "full" : "half");
-	} else if (newlinkstate & LINK_DOWN
-		   && dev->linkstate != newlinkstate) {
+	} else if (newlinkstate & LINK_DOWN &&
+		   dev->linkstate != newlinkstate) {
 		netif_stop_queue(ndev);
 		printk(KERN_INFO "%s: link now down.\n", ndev->name);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/octeon/Kconfig linux-libre-2.6.33-gnu1/drivers/net/octeon/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/octeon/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/octeon/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,10 @@
+config OCTEON_MGMT_ETHERNET
+	tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)"
+	depends on  CPU_CAVIUM_OCTEON
+	select PHYLIB
+	select MDIO_OCTEON
+	default y
+	help
+	  This option enables the ethernet driver for the management
+	  port on Cavium Networks' Octeon CN57XX, CN56XX, CN55XX,
+	  CN54XX, CN52XX, and CN6XXX chips.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/octeon/Makefile linux-libre-2.6.33-gnu1/drivers/net/octeon/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/octeon/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/octeon/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_OCTEON_MGMT_ETHERNET)	+= octeon_mgmt.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/octeon/octeon_mgmt.c linux-libre-2.6.33-gnu1/drivers/net/octeon/octeon_mgmt.c
--- linux-libre-2.6.32-gnu1/drivers/net/octeon/octeon_mgmt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/octeon/octeon_mgmt.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1176 @@
+/*
+ * 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) 2009 Cavium Networks
+ */
+
+#include <linux/capability.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/phy.h>
+#include <linux/spinlock.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-mixx-defs.h>
+#include <asm/octeon/cvmx-agl-defs.h>
+
+#define DRV_NAME "octeon_mgmt"
+#define DRV_VERSION "2.0"
+#define DRV_DESCRIPTION \
+	"Cavium Networks Octeon MII (management) port Network Driver"
+
+#define OCTEON_MGMT_NAPI_WEIGHT 16
+
+/*
+ * Ring sizes that are powers of two allow for more efficient modulo
+ * opertions.
+ */
+#define OCTEON_MGMT_RX_RING_SIZE 512
+#define OCTEON_MGMT_TX_RING_SIZE 128
+
+/* Allow 8 bytes for vlan and FCS. */
+#define OCTEON_MGMT_RX_HEADROOM (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN)
+
+union mgmt_port_ring_entry {
+	u64 d64;
+	struct {
+		u64    reserved_62_63:2;
+		/* Length of the buffer/packet in bytes */
+		u64    len:14;
+		/* For TX, signals that the packet should be timestamped */
+		u64    tstamp:1;
+		/* The RX error code */
+		u64    code:7;
+#define RING_ENTRY_CODE_DONE 0xf
+#define RING_ENTRY_CODE_MORE 0x10
+		/* Physical address of the buffer */
+		u64    addr:40;
+	} s;
+};
+
+struct octeon_mgmt {
+	struct net_device *netdev;
+	int port;
+	int irq;
+	u64 *tx_ring;
+	dma_addr_t tx_ring_handle;
+	unsigned int tx_next;
+	unsigned int tx_next_clean;
+	unsigned int tx_current_fill;
+	/* The tx_list lock also protects the ring related variables */
+	struct sk_buff_head tx_list;
+
+	/* RX variables only touched in napi_poll.  No locking necessary. */
+	u64 *rx_ring;
+	dma_addr_t rx_ring_handle;
+	unsigned int rx_next;
+	unsigned int rx_next_fill;
+	unsigned int rx_current_fill;
+	struct sk_buff_head rx_list;
+
+	spinlock_t lock;
+	unsigned int last_duplex;
+	unsigned int last_link;
+	struct device *dev;
+	struct napi_struct napi;
+	struct tasklet_struct tx_clean_tasklet;
+	struct phy_device *phydev;
+};
+
+static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
+{
+	int port = p->port;
+	union cvmx_mixx_intena mix_intena;
+	unsigned long flags;
+
+	spin_lock_irqsave(&p->lock, flags);
+	mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+	mix_intena.s.ithena = enable ? 1 : 0;
+	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+	spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
+{
+	int port = p->port;
+	union cvmx_mixx_intena mix_intena;
+	unsigned long flags;
+
+	spin_lock_irqsave(&p->lock, flags);
+	mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+	mix_intena.s.othena = enable ? 1 : 0;
+	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+	spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
+{
+	octeon_mgmt_set_rx_irq(p, 1);
+}
+
+static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
+{
+	octeon_mgmt_set_rx_irq(p, 0);
+}
+
+static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
+{
+	octeon_mgmt_set_tx_irq(p, 1);
+}
+
+static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
+{
+	octeon_mgmt_set_tx_irq(p, 0);
+}
+
+static unsigned int ring_max_fill(unsigned int ring_size)
+{
+	return ring_size - 8;
+}
+
+static unsigned int ring_size_to_bytes(unsigned int ring_size)
+{
+	return ring_size * sizeof(union mgmt_port_ring_entry);
+}
+
+static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+
+	while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
+		unsigned int size;
+		union mgmt_port_ring_entry re;
+		struct sk_buff *skb;
+
+		/* CN56XX pass 1 needs 8 bytes of padding.  */
+		size = netdev->mtu + OCTEON_MGMT_RX_HEADROOM + 8 + NET_IP_ALIGN;
+
+		skb = netdev_alloc_skb(netdev, size);
+		if (!skb)
+			break;
+		skb_reserve(skb, NET_IP_ALIGN);
+		__skb_queue_tail(&p->rx_list, skb);
+
+		re.d64 = 0;
+		re.s.len = size;
+		re.s.addr = dma_map_single(p->dev, skb->data,
+					   size,
+					   DMA_FROM_DEVICE);
+
+		/* Put it in the ring.  */
+		p->rx_ring[p->rx_next_fill] = re.d64;
+		dma_sync_single_for_device(p->dev, p->rx_ring_handle,
+					   ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+					   DMA_BIDIRECTIONAL);
+		p->rx_next_fill =
+			(p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE;
+		p->rx_current_fill++;
+		/* Ring the bell.  */
+		cvmx_write_csr(CVMX_MIXX_IRING2(port), 1);
+	}
+}
+
+static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
+{
+	int port = p->port;
+	union cvmx_mixx_orcnt mix_orcnt;
+	union mgmt_port_ring_entry re;
+	struct sk_buff *skb;
+	int cleaned = 0;
+	unsigned long flags;
+
+	mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+	while (mix_orcnt.s.orcnt) {
+		dma_sync_single_for_cpu(p->dev, p->tx_ring_handle,
+					ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+					DMA_BIDIRECTIONAL);
+
+		spin_lock_irqsave(&p->tx_list.lock, flags);
+
+		re.d64 = p->tx_ring[p->tx_next_clean];
+		p->tx_next_clean =
+			(p->tx_next_clean + 1) % OCTEON_MGMT_TX_RING_SIZE;
+		skb = __skb_dequeue(&p->tx_list);
+
+		mix_orcnt.u64 = 0;
+		mix_orcnt.s.orcnt = 1;
+
+		/* Acknowledge to hardware that we have the buffer.  */
+		cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64);
+		p->tx_current_fill--;
+
+		spin_unlock_irqrestore(&p->tx_list.lock, flags);
+
+		dma_unmap_single(p->dev, re.s.addr, re.s.len,
+				 DMA_TO_DEVICE);
+		dev_kfree_skb_any(skb);
+		cleaned++;
+
+		mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+	}
+
+	if (cleaned && netif_queue_stopped(p->netdev))
+		netif_wake_queue(p->netdev);
+}
+
+static void octeon_mgmt_clean_tx_tasklet(unsigned long arg)
+{
+	struct octeon_mgmt *p = (struct octeon_mgmt *)arg;
+	octeon_mgmt_clean_tx_buffers(p);
+	octeon_mgmt_enable_tx_irq(p);
+}
+
+static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	unsigned long flags;
+	u64 drop, bad;
+
+	/* These reads also clear the count registers.  */
+	drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port));
+	bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port));
+
+	if (drop || bad) {
+		/* Do an atomic update. */
+		spin_lock_irqsave(&p->lock, flags);
+		netdev->stats.rx_errors += bad;
+		netdev->stats.rx_dropped += drop;
+		spin_unlock_irqrestore(&p->lock, flags);
+	}
+}
+
+static void octeon_mgmt_update_tx_stats(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	unsigned long flags;
+
+	union cvmx_agl_gmx_txx_stat0 s0;
+	union cvmx_agl_gmx_txx_stat1 s1;
+
+	/* These reads also clear the count registers.  */
+	s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port));
+	s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port));
+
+	if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) {
+		/* Do an atomic update. */
+		spin_lock_irqsave(&p->lock, flags);
+		netdev->stats.tx_errors += s0.s.xsdef + s0.s.xscol;
+		netdev->stats.collisions += s1.s.scol + s1.s.mcol;
+		spin_unlock_irqrestore(&p->lock, flags);
+	}
+}
+
+/*
+ * Dequeue a receive skb and its corresponding ring entry.  The ring
+ * entry is returned, *pskb is updated to point to the skb.
+ */
+static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p,
+					 struct sk_buff **pskb)
+{
+	union mgmt_port_ring_entry re;
+
+	dma_sync_single_for_cpu(p->dev, p->rx_ring_handle,
+				ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+				DMA_BIDIRECTIONAL);
+
+	re.d64 = p->rx_ring[p->rx_next];
+	p->rx_next = (p->rx_next + 1) % OCTEON_MGMT_RX_RING_SIZE;
+	p->rx_current_fill--;
+	*pskb = __skb_dequeue(&p->rx_list);
+
+	dma_unmap_single(p->dev, re.s.addr,
+			 ETH_FRAME_LEN + OCTEON_MGMT_RX_HEADROOM,
+			 DMA_FROM_DEVICE);
+
+	return re.d64;
+}
+
+
+static int octeon_mgmt_receive_one(struct octeon_mgmt *p)
+{
+	int port = p->port;
+	struct net_device *netdev = p->netdev;
+	union cvmx_mixx_ircnt mix_ircnt;
+	union mgmt_port_ring_entry re;
+	struct sk_buff *skb;
+	struct sk_buff *skb2;
+	struct sk_buff *skb_new;
+	union mgmt_port_ring_entry re2;
+	int rc = 1;
+
+
+	re.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb);
+	if (likely(re.s.code == RING_ENTRY_CODE_DONE)) {
+		/* A good packet, send it up. */
+		skb_put(skb, re.s.len);
+good:
+		skb->protocol = eth_type_trans(skb, netdev);
+		netdev->stats.rx_packets++;
+		netdev->stats.rx_bytes += skb->len;
+		netdev->last_rx = jiffies;
+		netif_receive_skb(skb);
+		rc = 0;
+	} else if (re.s.code == RING_ENTRY_CODE_MORE) {
+		/*
+		 * Packet split across skbs.  This can happen if we
+		 * increase the MTU.  Buffers that are already in the
+		 * rx ring can then end up being too small.  As the rx
+		 * ring is refilled, buffers sized for the new MTU
+		 * will be used and we should go back to the normal
+		 * non-split case.
+		 */
+		skb_put(skb, re.s.len);
+		do {
+			re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2);
+			if (re2.s.code != RING_ENTRY_CODE_MORE
+				&& re2.s.code != RING_ENTRY_CODE_DONE)
+				goto split_error;
+			skb_put(skb2,  re2.s.len);
+			skb_new = skb_copy_expand(skb, 0, skb2->len,
+						  GFP_ATOMIC);
+			if (!skb_new)
+				goto split_error;
+			if (skb_copy_bits(skb2, 0, skb_tail_pointer(skb_new),
+					  skb2->len))
+				goto split_error;
+			skb_put(skb_new, skb2->len);
+			dev_kfree_skb_any(skb);
+			dev_kfree_skb_any(skb2);
+			skb = skb_new;
+		} while (re2.s.code == RING_ENTRY_CODE_MORE);
+		goto good;
+	} else {
+		/* Some other error, discard it. */
+		dev_kfree_skb_any(skb);
+		/*
+		 * Error statistics are accumulated in
+		 * octeon_mgmt_update_rx_stats.
+		 */
+	}
+	goto done;
+split_error:
+	/* Discard the whole mess. */
+	dev_kfree_skb_any(skb);
+	dev_kfree_skb_any(skb2);
+	while (re2.s.code == RING_ENTRY_CODE_MORE) {
+		re2.d64 = octeon_mgmt_dequeue_rx_buffer(p, &skb2);
+		dev_kfree_skb_any(skb2);
+	}
+	netdev->stats.rx_errors++;
+
+done:
+	/* Tell the hardware we processed a packet.  */
+	mix_ircnt.u64 = 0;
+	mix_ircnt.s.ircnt = 1;
+	cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64);
+	return rc;
+
+}
+
+static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
+{
+	int port = p->port;
+	unsigned int work_done = 0;
+	union cvmx_mixx_ircnt mix_ircnt;
+	int rc;
+
+
+	mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+	while (work_done < budget && mix_ircnt.s.ircnt) {
+
+		rc = octeon_mgmt_receive_one(p);
+		if (!rc)
+			work_done++;
+
+		/* Check for more packets. */
+		mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+	}
+
+	octeon_mgmt_rx_fill_ring(p->netdev);
+
+	return work_done;
+}
+
+static int octeon_mgmt_napi_poll(struct napi_struct *napi, int budget)
+{
+	struct octeon_mgmt *p = container_of(napi, struct octeon_mgmt, napi);
+	struct net_device *netdev = p->netdev;
+	unsigned int work_done = 0;
+
+	work_done = octeon_mgmt_receive_packets(p, budget);
+
+	if (work_done < budget) {
+		/* We stopped because no more packets were available. */
+		napi_complete(napi);
+		octeon_mgmt_enable_rx_irq(p);
+	}
+	octeon_mgmt_update_rx_stats(netdev);
+
+	return work_done;
+}
+
+/* Reset the hardware to clean state.  */
+static void octeon_mgmt_reset_hw(struct octeon_mgmt *p)
+{
+	union cvmx_mixx_ctl mix_ctl;
+	union cvmx_mixx_bist mix_bist;
+	union cvmx_agl_gmx_bist agl_gmx_bist;
+
+	mix_ctl.u64 = 0;
+	cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
+	do {
+		mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+	} while (mix_ctl.s.busy);
+	mix_ctl.s.reset = 1;
+	cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
+	cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+	cvmx_wait(64);
+
+	mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port));
+	if (mix_bist.u64)
+		dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n",
+			(unsigned long long)mix_bist.u64);
+
+	agl_gmx_bist.u64 = cvmx_read_csr(CVMX_AGL_GMX_BIST);
+	if (agl_gmx_bist.u64)
+		dev_warn(p->dev, "AGL failed BIST (0x%016llx)\n",
+			 (unsigned long long)agl_gmx_bist.u64);
+}
+
+struct octeon_mgmt_cam_state {
+	u64 cam[6];
+	u64 cam_mask;
+	int cam_index;
+};
+
+static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs,
+				      unsigned char *addr)
+{
+	int i;
+
+	for (i = 0; i < 6; i++)
+		cs->cam[i] |= (u64)addr[i] << (8 * (cs->cam_index));
+	cs->cam_mask |= (1ULL << cs->cam_index);
+	cs->cam_index++;
+}
+
+static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	int i;
+	union cvmx_agl_gmx_rxx_adr_ctl adr_ctl;
+	union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx;
+	unsigned long flags;
+	unsigned int prev_packet_enable;
+	unsigned int cam_mode = 1; /* 1 - Accept on CAM match */
+	unsigned int multicast_mode = 1; /* 1 - Reject all multicast.  */
+	struct octeon_mgmt_cam_state cam_state;
+	struct dev_addr_list *list;
+	struct list_head *pos;
+	int available_cam_entries;
+
+	memset(&cam_state, 0, sizeof(cam_state));
+
+	if ((netdev->flags & IFF_PROMISC) || netdev->dev_addrs.count > 7) {
+		cam_mode = 0;
+		available_cam_entries = 8;
+	} else {
+		/*
+		 * One CAM entry for the primary address, leaves seven
+		 * for the secondary addresses.
+		 */
+		available_cam_entries = 7 - netdev->dev_addrs.count;
+	}
+
+	if (netdev->flags & IFF_MULTICAST) {
+		if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI)
+		    || netdev->mc_count  > available_cam_entries)
+			multicast_mode = 2; /* 1 - Accept all multicast.  */
+		else
+			multicast_mode = 0; /* 0 - Use CAM.  */
+	}
+
+	if (cam_mode == 1) {
+		/* Add primary address. */
+		octeon_mgmt_cam_state_add(&cam_state, netdev->dev_addr);
+		list_for_each(pos, &netdev->dev_addrs.list) {
+			struct netdev_hw_addr *hw_addr;
+			hw_addr = list_entry(pos, struct netdev_hw_addr, list);
+			octeon_mgmt_cam_state_add(&cam_state, hw_addr->addr);
+			list = list->next;
+		}
+	}
+	if (multicast_mode == 0) {
+		i = netdev->mc_count;
+		list = netdev->mc_list;
+		while (i--) {
+			octeon_mgmt_cam_state_add(&cam_state, list->da_addr);
+			list = list->next;
+		}
+	}
+
+
+	spin_lock_irqsave(&p->lock, flags);
+
+	/* Disable packet I/O. */
+	agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	prev_packet_enable = agl_gmx_prtx.s.en;
+	agl_gmx_prtx.s.en = 0;
+	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+
+
+	adr_ctl.u64 = 0;
+	adr_ctl.s.cam_mode = cam_mode;
+	adr_ctl.s.mcst = multicast_mode;
+	adr_ctl.s.bcst = 1;     /* Allow broadcast */
+
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64);
+
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask);
+
+	/* Restore packet I/O. */
+	agl_gmx_prtx.s.en = prev_packet_enable;
+	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+
+	spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
+{
+	struct sockaddr *sa = addr;
+
+	if (!is_valid_ether_addr(sa->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN);
+
+	octeon_mgmt_set_rx_filtering(netdev);
+
+	return 0;
+}
+
+static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
+
+	/*
+	 * Limit the MTU to make sure the ethernet packets are between
+	 * 64 bytes and 16383 bytes.
+	 */
+	if (size_without_fcs < 64 || size_without_fcs > 16383) {
+		dev_warn(p->dev, "MTU must be between %d and %d.\n",
+			 64 - OCTEON_MGMT_RX_HEADROOM,
+			 16383 - OCTEON_MGMT_RX_HEADROOM);
+		return -EINVAL;
+	}
+
+	netdev->mtu = new_mtu;
+
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port),
+		       (size_without_fcs + 7) & 0xfff8);
+
+	return 0;
+}
+
+static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
+{
+	struct net_device *netdev = dev_id;
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	union cvmx_mixx_isr mixx_isr;
+
+	mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port));
+
+	/* Clear any pending interrupts */
+	cvmx_write_csr(CVMX_MIXX_ISR(port),
+		       cvmx_read_csr(CVMX_MIXX_ISR(port)));
+	cvmx_read_csr(CVMX_MIXX_ISR(port));
+
+	if (mixx_isr.s.irthresh) {
+		octeon_mgmt_disable_rx_irq(p);
+		napi_schedule(&p->napi);
+	}
+	if (mixx_isr.s.orthresh) {
+		octeon_mgmt_disable_tx_irq(p);
+		tasklet_schedule(&p->tx_clean_tasklet);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int octeon_mgmt_ioctl(struct net_device *netdev,
+			     struct ifreq *rq, int cmd)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+
+	if (!netif_running(netdev))
+		return -EINVAL;
+
+	if (!p->phydev)
+		return -EINVAL;
+
+	return phy_mii_ioctl(p->phydev, if_mii(rq), cmd);
+}
+
+static void octeon_mgmt_adjust_link(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+	unsigned long flags;
+	int link_changed = 0;
+
+	spin_lock_irqsave(&p->lock, flags);
+	if (p->phydev->link) {
+		if (!p->last_link)
+			link_changed = 1;
+		if (p->last_duplex != p->phydev->duplex) {
+			p->last_duplex = p->phydev->duplex;
+			prtx_cfg.u64 =
+				cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+			prtx_cfg.s.duplex = p->phydev->duplex;
+			cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port),
+				       prtx_cfg.u64);
+		}
+	} else {
+		if (p->last_link)
+			link_changed = -1;
+	}
+	p->last_link = p->phydev->link;
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	if (link_changed != 0) {
+		if (link_changed > 0) {
+			netif_carrier_on(netdev);
+			pr_info("%s: Link is up - %d/%s\n", netdev->name,
+				p->phydev->speed,
+				DUPLEX_FULL == p->phydev->duplex ?
+				"Full" : "Half");
+		} else {
+			netif_carrier_off(netdev);
+			pr_info("%s: Link is down\n", netdev->name);
+		}
+	}
+}
+
+static int octeon_mgmt_init_phy(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	char phy_id[20];
+
+	if (octeon_is_simulation()) {
+		/* No PHYs in the simulator. */
+		netif_carrier_on(netdev);
+		return 0;
+	}
+
+	snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port);
+
+	p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
+				PHY_INTERFACE_MODE_MII);
+
+	if (IS_ERR(p->phydev)) {
+		p->phydev = NULL;
+		return -1;
+	}
+
+	phy_start_aneg(p->phydev);
+
+	return 0;
+}
+
+static int octeon_mgmt_open(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	union cvmx_mixx_ctl mix_ctl;
+	union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode;
+	union cvmx_mixx_oring1 oring1;
+	union cvmx_mixx_iring1 iring1;
+	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+	union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
+	union cvmx_mixx_irhwm mix_irhwm;
+	union cvmx_mixx_orhwm mix_orhwm;
+	union cvmx_mixx_intena mix_intena;
+	struct sockaddr sa;
+
+	/* Allocate ring buffers.  */
+	p->tx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+			     GFP_KERNEL);
+	if (!p->tx_ring)
+		return -ENOMEM;
+	p->tx_ring_handle =
+		dma_map_single(p->dev, p->tx_ring,
+			       ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+			       DMA_BIDIRECTIONAL);
+	p->tx_next = 0;
+	p->tx_next_clean = 0;
+	p->tx_current_fill = 0;
+
+
+	p->rx_ring = kzalloc(ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+			     GFP_KERNEL);
+	if (!p->rx_ring)
+		goto err_nomem;
+	p->rx_ring_handle =
+		dma_map_single(p->dev, p->rx_ring,
+			       ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+			       DMA_BIDIRECTIONAL);
+
+	p->rx_next = 0;
+	p->rx_next_fill = 0;
+	p->rx_current_fill = 0;
+
+	octeon_mgmt_reset_hw(p);
+
+	mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+
+	/* Bring it out of reset if needed. */
+	if (mix_ctl.s.reset) {
+		mix_ctl.s.reset = 0;
+		cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+		do {
+			mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+		} while (mix_ctl.s.reset);
+	}
+
+	agl_gmx_inf_mode.u64 = 0;
+	agl_gmx_inf_mode.s.en = 1;
+	cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+
+	oring1.u64 = 0;
+	oring1.s.obase = p->tx_ring_handle >> 3;
+	oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE;
+	cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64);
+
+	iring1.u64 = 0;
+	iring1.s.ibase = p->rx_ring_handle >> 3;
+	iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
+	cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64);
+
+	/* Disable packet I/O. */
+	prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	prtx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+
+	memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
+	octeon_mgmt_set_mac_address(netdev, &sa);
+
+	octeon_mgmt_change_mtu(netdev, netdev->mtu);
+
+	/*
+	 * Enable the port HW. Packets are not allowed until
+	 * cvmx_mgmt_port_enable() is called.
+	 */
+	mix_ctl.u64 = 0;
+	mix_ctl.s.crc_strip = 1;    /* Strip the ending CRC */
+	mix_ctl.s.en = 1;           /* Enable the port */
+	mix_ctl.s.nbtarb = 0;       /* Arbitration mode */
+	/* MII CB-request FIFO programmable high watermark */
+	mix_ctl.s.mrq_hwm = 1;
+	cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+	    || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+		/*
+		 * Force compensation values, as they are not
+		 * determined properly by HW
+		 */
+		union cvmx_agl_gmx_drv_ctl drv_ctl;
+
+		drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
+		if (port) {
+			drv_ctl.s.byp_en1 = 1;
+			drv_ctl.s.nctl1 = 6;
+			drv_ctl.s.pctl1 = 6;
+		} else {
+			drv_ctl.s.byp_en = 1;
+			drv_ctl.s.nctl = 6;
+			drv_ctl.s.pctl = 6;
+		}
+		cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
+	}
+
+	octeon_mgmt_rx_fill_ring(netdev);
+
+	/* Clear statistics. */
+	/* Clear on read. */
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0);
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0);
+
+	cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1);
+	cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0);
+	cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0);
+
+	/* Clear any pending interrupts */
+	cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port)));
+
+	if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name,
+			netdev)) {
+		dev_err(p->dev, "request_irq(%d) failed.\n", p->irq);
+		goto err_noirq;
+	}
+
+	/* Interrupt every single RX packet */
+	mix_irhwm.u64 = 0;
+	mix_irhwm.s.irhwm = 0;
+	cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64);
+
+	/* Interrupt when we have 5 or more packets to clean.  */
+	mix_orhwm.u64 = 0;
+	mix_orhwm.s.orhwm = 5;
+	cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64);
+
+	/* Enable receive and transmit interrupts */
+	mix_intena.u64 = 0;
+	mix_intena.s.ithena = 1;
+	mix_intena.s.othena = 1;
+	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+
+
+	/* Enable packet I/O. */
+
+	rxx_frm_ctl.u64 = 0;
+	rxx_frm_ctl.s.pre_align = 1;
+	/*
+	 * When set, disables the length check for non-min sized pkts
+	 * with padding in the client data.
+	 */
+	rxx_frm_ctl.s.pad_len = 1;
+	/* When set, disables the length check for VLAN pkts */
+	rxx_frm_ctl.s.vlan_len = 1;
+	/* When set, PREAMBLE checking is  less strict */
+	rxx_frm_ctl.s.pre_free = 1;
+	/* Control Pause Frames can match station SMAC */
+	rxx_frm_ctl.s.ctl_smac = 0;
+	/* Control Pause Frames can match globally assign Multicast address */
+	rxx_frm_ctl.s.ctl_mcst = 1;
+	/* Forward pause information to TX block */
+	rxx_frm_ctl.s.ctl_bck = 1;
+	/* Drop Control Pause Frames */
+	rxx_frm_ctl.s.ctl_drp = 1;
+	/* Strip off the preamble */
+	rxx_frm_ctl.s.pre_strp = 1;
+	/*
+	 * This port is configured to send PREAMBLE+SFD to begin every
+	 * frame.  GMX checks that the PREAMBLE is sent correctly.
+	 */
+	rxx_frm_ctl.s.pre_chk = 1;
+	cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64);
+
+	/* Enable the AGL block */
+	agl_gmx_inf_mode.u64 = 0;
+	agl_gmx_inf_mode.s.en = 1;
+	cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+
+	/* Configure the port duplex and enables */
+	prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	prtx_cfg.s.tx_en = 1;
+	prtx_cfg.s.rx_en = 1;
+	prtx_cfg.s.en = 1;
+	p->last_duplex = 1;
+	prtx_cfg.s.duplex = p->last_duplex;
+	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+
+	p->last_link = 0;
+	netif_carrier_off(netdev);
+
+	if (octeon_mgmt_init_phy(netdev)) {
+		dev_err(p->dev, "Cannot initialize PHY.\n");
+		goto err_noirq;
+	}
+
+	netif_wake_queue(netdev);
+	napi_enable(&p->napi);
+
+	return 0;
+err_noirq:
+	octeon_mgmt_reset_hw(p);
+	dma_unmap_single(p->dev, p->rx_ring_handle,
+			 ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+			 DMA_BIDIRECTIONAL);
+	kfree(p->rx_ring);
+err_nomem:
+	dma_unmap_single(p->dev, p->tx_ring_handle,
+			 ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+			 DMA_BIDIRECTIONAL);
+	kfree(p->tx_ring);
+	return -ENOMEM;
+}
+
+static int octeon_mgmt_stop(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+
+	napi_disable(&p->napi);
+	netif_stop_queue(netdev);
+
+	if (p->phydev)
+		phy_disconnect(p->phydev);
+
+	netif_carrier_off(netdev);
+
+	octeon_mgmt_reset_hw(p);
+
+
+	free_irq(p->irq, netdev);
+
+	/* dma_unmap is a nop on Octeon, so just free everything.  */
+	skb_queue_purge(&p->tx_list);
+	skb_queue_purge(&p->rx_list);
+
+	dma_unmap_single(p->dev, p->rx_ring_handle,
+			 ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE),
+			 DMA_BIDIRECTIONAL);
+	kfree(p->rx_ring);
+
+	dma_unmap_single(p->dev, p->tx_ring_handle,
+			 ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+			 DMA_BIDIRECTIONAL);
+	kfree(p->tx_ring);
+
+
+	return 0;
+}
+
+static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	int port = p->port;
+	union mgmt_port_ring_entry re;
+	unsigned long flags;
+
+	re.d64 = 0;
+	re.s.len = skb->len;
+	re.s.addr = dma_map_single(p->dev, skb->data,
+				   skb->len,
+				   DMA_TO_DEVICE);
+
+	spin_lock_irqsave(&p->tx_list.lock, flags);
+
+	if (unlikely(p->tx_current_fill >=
+		     ring_max_fill(OCTEON_MGMT_TX_RING_SIZE))) {
+		spin_unlock_irqrestore(&p->tx_list.lock, flags);
+
+		dma_unmap_single(p->dev, re.s.addr, re.s.len,
+				 DMA_TO_DEVICE);
+
+		netif_stop_queue(netdev);
+		return NETDEV_TX_BUSY;
+	}
+
+	__skb_queue_tail(&p->tx_list, skb);
+
+	/* Put it in the ring.  */
+	p->tx_ring[p->tx_next] = re.d64;
+	p->tx_next = (p->tx_next + 1) % OCTEON_MGMT_TX_RING_SIZE;
+	p->tx_current_fill++;
+
+	spin_unlock_irqrestore(&p->tx_list.lock, flags);
+
+	dma_sync_single_for_device(p->dev, p->tx_ring_handle,
+				   ring_size_to_bytes(OCTEON_MGMT_TX_RING_SIZE),
+				   DMA_BIDIRECTIONAL);
+
+	netdev->stats.tx_packets++;
+	netdev->stats.tx_bytes += skb->len;
+
+	/* Ring the bell.  */
+	cvmx_write_csr(CVMX_MIXX_ORING2(port), 1);
+
+	netdev->trans_start = jiffies;
+	octeon_mgmt_clean_tx_buffers(p);
+	octeon_mgmt_update_tx_stats(netdev);
+	return NETDEV_TX_OK;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void octeon_mgmt_poll_controller(struct net_device *netdev)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+
+	octeon_mgmt_receive_packets(p, 16);
+	octeon_mgmt_update_rx_stats(netdev);
+	return;
+}
+#endif
+
+static void octeon_mgmt_get_drvinfo(struct net_device *netdev,
+				    struct ethtool_drvinfo *info)
+{
+	strncpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strncpy(info->version, DRV_VERSION, sizeof(info->version));
+	strncpy(info->fw_version, "N/A", sizeof(info->fw_version));
+	strncpy(info->bus_info, "N/A", sizeof(info->bus_info));
+	info->n_stats = 0;
+	info->testinfo_len = 0;
+	info->regdump_len = 0;
+	info->eedump_len = 0;
+}
+
+static int octeon_mgmt_get_settings(struct net_device *netdev,
+				    struct ethtool_cmd *cmd)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+
+	if (p->phydev)
+		return phy_ethtool_gset(p->phydev, cmd);
+
+	return -EINVAL;
+}
+
+static int octeon_mgmt_set_settings(struct net_device *netdev,
+				    struct ethtool_cmd *cmd)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (p->phydev)
+		return phy_ethtool_sset(p->phydev, cmd);
+
+	return -EINVAL;
+}
+
+static const struct ethtool_ops octeon_mgmt_ethtool_ops = {
+	.get_drvinfo = octeon_mgmt_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+	.get_settings = octeon_mgmt_get_settings,
+	.set_settings = octeon_mgmt_set_settings
+};
+
+static const struct net_device_ops octeon_mgmt_ops = {
+	.ndo_open =			octeon_mgmt_open,
+	.ndo_stop =			octeon_mgmt_stop,
+	.ndo_start_xmit =		octeon_mgmt_xmit,
+	.ndo_set_rx_mode = 		octeon_mgmt_set_rx_filtering,
+	.ndo_set_multicast_list =	octeon_mgmt_set_rx_filtering,
+	.ndo_set_mac_address =		octeon_mgmt_set_mac_address,
+	.ndo_do_ioctl = 		octeon_mgmt_ioctl,
+	.ndo_change_mtu =		octeon_mgmt_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller =		octeon_mgmt_poll_controller,
+#endif
+};
+
+static int __init octeon_mgmt_probe(struct platform_device *pdev)
+{
+	struct resource *res_irq;
+	struct net_device *netdev;
+	struct octeon_mgmt *p;
+	int i;
+
+	netdev = alloc_etherdev(sizeof(struct octeon_mgmt));
+	if (netdev == NULL)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, netdev);
+	p = netdev_priv(netdev);
+	netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll,
+		       OCTEON_MGMT_NAPI_WEIGHT);
+
+	p->netdev = netdev;
+	p->dev = &pdev->dev;
+
+	p->port = pdev->id;
+	snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port);
+
+	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res_irq)
+		goto err;
+
+	p->irq = res_irq->start;
+	spin_lock_init(&p->lock);
+
+	skb_queue_head_init(&p->tx_list);
+	skb_queue_head_init(&p->rx_list);
+	tasklet_init(&p->tx_clean_tasklet,
+		     octeon_mgmt_clean_tx_tasklet, (unsigned long)p);
+
+	netdev->netdev_ops = &octeon_mgmt_ops;
+	netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
+
+
+	/* The mgmt ports get the first N MACs.  */
+	for (i = 0; i < 6; i++)
+		netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i];
+	netdev->dev_addr[5] += p->port;
+
+	if (p->port >= octeon_bootinfo->mac_addr_count)
+		dev_err(&pdev->dev,
+			"Error %s: Using MAC outside of the assigned range: "
+			"%02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name,
+			netdev->dev_addr[0], netdev->dev_addr[1],
+			netdev->dev_addr[2], netdev->dev_addr[3],
+			netdev->dev_addr[4], netdev->dev_addr[5]);
+
+	if (register_netdev(netdev))
+		goto err;
+
+	dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
+	return 0;
+err:
+	free_netdev(netdev);
+	return -ENOENT;
+}
+
+static int __exit octeon_mgmt_remove(struct platform_device *pdev)
+{
+	struct net_device *netdev = dev_get_drvdata(&pdev->dev);
+
+	unregister_netdev(netdev);
+	free_netdev(netdev);
+	return 0;
+}
+
+static struct platform_driver octeon_mgmt_driver = {
+	.driver = {
+		.name		= "octeon_mgmt",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= octeon_mgmt_probe,
+	.remove		= __exit_p(octeon_mgmt_remove),
+};
+
+extern void octeon_mdiobus_force_mod_depencency(void);
+
+static int __init octeon_mgmt_mod_init(void)
+{
+	/* Force our mdiobus driver module to be loaded first. */
+	octeon_mdiobus_force_mod_depencency();
+	return platform_driver_register(&octeon_mgmt_driver);
+}
+
+static void __exit octeon_mgmt_mod_exit(void)
+{
+	platform_driver_unregister(&octeon_mgmt_driver);
+}
+
+module_init(octeon_mgmt_mod_init);
+module_exit(octeon_mgmt_mod_exit);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pasemi_mac.c linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/pasemi_mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1216,7 +1216,7 @@ static int pasemi_mac_open(struct net_de
 	snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx",
 		 dev->name);
 
-	ret = request_irq(mac->tx->chan.irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
+	ret = request_irq(mac->tx->chan.irq, pasemi_mac_tx_intr, IRQF_DISABLED,
 			  mac->tx_irq_name, mac->tx);
 	if (ret) {
 		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
@@ -1227,7 +1227,7 @@ static int pasemi_mac_open(struct net_de
 	snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx",
 		 dev->name);
 
-	ret = request_irq(mac->rx->chan.irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
+	ret = request_irq(mac->rx->chan.irq, pasemi_mac_rx_intr, IRQF_DISABLED,
 			  mac->rx_irq_name, mac->rx);
 	if (ret) {
 		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pasemi_mac_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/pasemi_mac_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pasemi_mac_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,6 +77,19 @@ pasemi_mac_ethtool_get_settings(struct n
 	return phy_ethtool_gset(phydev, cmd);
 }
 
+static int
+pasemi_mac_ethtool_set_settings(struct net_device *netdev,
+			       struct ethtool_cmd *cmd)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	struct phy_device *phydev = mac->phydev;
+
+	if (!phydev)
+		return -EOPNOTSUPP;
+
+	return phy_ethtool_sset(phydev, cmd);
+}
+
 static void
 pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
 			       struct ethtool_drvinfo *drvinfo)
@@ -150,6 +163,7 @@ static void pasemi_mac_get_strings(struc
 
 const struct ethtool_ops pasemi_mac_ethtool_ops = {
 	.get_settings		= pasemi_mac_ethtool_get_settings,
+	.set_settings		= pasemi_mac_ethtool_set_settings,
 	.get_drvinfo		= pasemi_mac_ethtool_get_drvinfo,
 	.get_msglevel		= pasemi_mac_ethtool_get_msglevel,
 	.set_msglevel		= pasemi_mac_ethtool_set_msglevel,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pci-skeleton.c linux-libre-2.6.33-gnu1/drivers/net/pci-skeleton.c
--- linux-libre-2.6.32-gnu1/drivers/net/pci-skeleton.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pci-skeleton.c	2010-02-24 13:52:17.000000000 -0500
@@ -1225,8 +1225,8 @@ static void netdrv_timer (unsigned long
 	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
 
 	if (!tp->duplex_lock && mii_lpa != 0xffff) {
-		int duplex = (mii_lpa & LPA_100FULL)
-		    || (mii_lpa & 0x01C0) == 0x0040;
+		int duplex = ((mii_lpa & LPA_100FULL) ||
+			      (mii_lpa & 0x01C0) == 0x0040);
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
 			printk (KERN_INFO
@@ -1612,8 +1612,8 @@ static void netdrv_weird_interrupt (stru
 	    (tp->drv_flags & HAS_LNK_CHNG)) {
 		/* Really link-change on new chips. */
 		int lpar = NETDRV_R16 (NWayLPAR);
-		int duplex = (lpar & 0x0100) || (lpar & 0x01C0) == 0x0040
-				|| tp->duplex_lock;
+		int duplex = ((lpar & 0x0100) || (lpar & 0x01C0) == 0x0040 ||
+			      tp->duplex_lock);
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
 			NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
@@ -1820,8 +1820,8 @@ static void netdrv_set_rx_mode (struct n
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/3c574_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c574_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/3c574_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c574_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,14 +118,6 @@ INT_MODULE_PARM(full_duplex, 0);
 /* Autodetect link polarity reversal? */
 INT_MODULE_PARM(auto_polarity, 1);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -278,7 +270,7 @@ static int tc574_probe(struct pcmcia_dev
 	struct el3_private *lp;
 	struct net_device *dev;
 
-	DEBUG(0, "3c574_attach()\n");
+	dev_dbg(&link->dev, "3c574_attach()\n");
 
 	/* Create the PC card device object. */
 	dev = alloc_etherdev(sizeof(struct el3_private));
@@ -291,10 +283,8 @@ static int tc574_probe(struct pcmcia_dev
 	spin_lock_init(&lp->window_lock);
 	link->io.NumPorts1 = 32;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	link->irq.Handler = &el3_interrupt;
-	link->irq.Instance = dev;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.ConfigIndex = 1;
@@ -319,7 +309,7 @@ static void tc574_detach(struct pcmcia_d
 {
 	struct net_device *dev = link->priv;
 
-	DEBUG(0, "3c574_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "3c574_detach()\n");
 
 	if (link->dev_node)
 		unregister_netdev(dev);
@@ -335,26 +325,23 @@ static void tc574_detach(struct pcmcia_d
 	ethernet device available to the system.
 */
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
 
 static int tc574_config(struct pcmcia_device *link)
 {
 	struct net_device *dev = link->priv;
 	struct el3_private *lp = netdev_priv(dev);
-	tuple_t tuple;
-	__le16 buf[32];
-	int last_fn, last_ret, i, j;
+	int ret, i, j;
 	unsigned int ioaddr;
 	__be16 *phys_addr;
 	char *cardname;
 	__u32 config;
+	u8 *buf;
+	size_t len;
 
 	phys_addr = (__be16 *)dev->dev_addr;
 
-	DEBUG(0, "3c574_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "3c574_config()\n");
 
 	link->io.IOAddrLines = 16;
 	for (i = j = 0; j < 0x400; j += 0x20) {
@@ -363,12 +350,16 @@ static int tc574_config(struct pcmcia_de
 		if (i == 0)
 			break;
 	}
-	if (i != 0) {
-		cs_error(link, RequestIO, i);
+	if (i != 0)
+		goto failed;
+
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
+
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
 		goto failed;
-	}
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 
 	dev->irq = link->irq.AssignedIRQ;
 	dev->base_addr = link->io.BasePort1;
@@ -378,16 +369,14 @@ static int tc574_config(struct pcmcia_de
 	/* The 3c574 normally uses an EEPROM for configuration info, including
 	   the hardware address.  The future products may include a modem chip
 	   and put the address in the CIS. */
-	tuple.Attributes = 0;
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleDataMax = 64;
-	tuple.TupleOffset = 0;
-	tuple.DesiredTuple = 0x88;
-	if (pcmcia_get_first_tuple(link, &tuple) == 0) {
-		pcmcia_get_tuple_data(link, &tuple);
+
+	len = pcmcia_get_tuple(link, 0x88, &buf);
+	if (buf && len >= 6) {
 		for (i = 0; i < 3; i++)
-			phys_addr[i] = htons(le16_to_cpu(buf[i]));
+			phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+		kfree(buf);
 	} else {
+		kfree(buf); /* 0 < len < 6 */
 		EL3WINDOW(0);
 		for (i = 0; i < 3; i++)
 			phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
@@ -435,7 +424,8 @@ static int tc574_config(struct pcmcia_de
 			mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
 			if (mii_status != 0xffff) {
 				lp->phys = phy & 0x1f;
-				DEBUG(0, "  MII transceiver at index %d, status %x.\n",
+				dev_dbg(&link->dev, "  MII transceiver at "
+					"index %d, status %x.\n",
 					  phy, mii_status);
 				if ((mii_status & 0x0040) == 0)
 					mii_preamble_required = 1;
@@ -457,7 +447,7 @@ static int tc574_config(struct pcmcia_de
 	}
 
 	link->dev_node = &lp->node;
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
+	SET_NETDEV_DEV(dev, &link->dev);
 
 	if (register_netdev(dev) != 0) {
 		printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
@@ -478,8 +468,6 @@ static int tc574_config(struct pcmcia_de
 
 	return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
 failed:
 	tc574_release(link);
 	return -ENODEV;
@@ -738,7 +726,7 @@ static int el3_open(struct net_device *d
 	lp->media.expires = jiffies + HZ;
 	add_timer(&lp->media);
 	
-	DEBUG(2, "%s: opened, status %4.4x.\n",
+	dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
 		  dev->name, inw(dev->base_addr + EL3_STATUS));
 	
 	return 0;
@@ -772,7 +760,7 @@ static void pop_tx_status(struct net_dev
 		if (tx_status & 0x30)
 			tc574_wait_for_completion(dev, TxReset);
 		if (tx_status & 0x38) {
-			DEBUG(1, "%s: transmit error: status 0x%02x\n",
+			pr_debug("%s: transmit error: status 0x%02x\n",
 				  dev->name, tx_status);
 			outw(TxEnable, ioaddr + EL3_CMD);
 			dev->stats.tx_aborted_errors++;
@@ -788,7 +776,7 @@ static netdev_tx_t el3_start_xmit(struct
 	struct el3_private *lp = netdev_priv(dev);
 	unsigned long flags;
 
-	DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+	pr_debug("%s: el3_start_xmit(length = %ld) called, "
 		  "status %4.4x.\n", dev->name, (long)skb->len,
 		  inw(ioaddr + EL3_STATUS));
 
@@ -827,7 +815,7 @@ static irqreturn_t el3_interrupt(int irq
 		return IRQ_NONE;
 	ioaddr = dev->base_addr;
 
-	DEBUG(3, "%s: interrupt, status %4.4x.\n",
+	pr_debug("%s: interrupt, status %4.4x.\n",
 		  dev->name, inw(ioaddr + EL3_STATUS));
 
 	spin_lock(&lp->window_lock);
@@ -836,7 +824,7 @@ static irqreturn_t el3_interrupt(int irq
 		   (IntLatch | RxComplete | RxEarly | StatsFull)) {
 		if (!netif_device_present(dev) ||
 			((status & 0xe000) != 0x2000)) {
-			DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
+			pr_debug("%s: Interrupt from dead card\n", dev->name);
 			break;
 		}
 
@@ -846,7 +834,7 @@ static irqreturn_t el3_interrupt(int irq
 			work_budget = el3_rx(dev, work_budget);
 
 		if (status & TxAvailable) {
-			DEBUG(3, "  TX room bit was handled.\n");
+			pr_debug("  TX room bit was handled.\n");
 			/* There's room in the FIFO for a full-sized packet. */
 			outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 			netif_wake_queue(dev);
@@ -886,7 +874,7 @@ static irqreturn_t el3_interrupt(int irq
 		}
 
 		if (--work_budget < 0) {
-			DEBUG(0, "%s: Too much work in interrupt, "
+			pr_debug("%s: Too much work in interrupt, "
 				  "status %4.4x.\n", dev->name, status);
 			/* Clear all interrupts */
 			outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -896,7 +884,7 @@ static irqreturn_t el3_interrupt(int irq
 		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
 	}
 
-	DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+	pr_debug("%s: exiting interrupt, status %4.4x.\n",
 		  dev->name, inw(ioaddr + EL3_STATUS));
 		  
 	spin_unlock(&lp->window_lock);
@@ -924,7 +912,11 @@ static void media_check(unsigned long ar
 	if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
 		if (!lp->fast_poll)
 			printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+
+		local_irq_save(flags);
 		el3_interrupt(dev->irq, dev);
+		local_irq_restore(flags);
+
 		lp->fast_poll = HZ;
 	}
 	if (lp->fast_poll) {
@@ -1003,7 +995,7 @@ static void update_stats(struct net_devi
 	unsigned int ioaddr = dev->base_addr;
 	u8 rx, tx, up;
 
-	DEBUG(2, "%s: updating the statistics.\n", dev->name);
+	pr_debug("%s: updating the statistics.\n", dev->name);
 
 	if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
 		return;
@@ -1039,7 +1031,7 @@ static int el3_rx(struct net_device *dev
 	unsigned int ioaddr = dev->base_addr;
 	short rx_status;
 	
-	DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+	pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
 		  dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
 	while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
 			worklimit > 0) {
@@ -1061,7 +1053,7 @@ static int el3_rx(struct net_device *dev
 
 			skb = dev_alloc_skb(pkt_len+5);
 
-			DEBUG(3, "  Receiving packet size %d status %4.4x.\n",
+			pr_debug("  Receiving packet size %d status %4.4x.\n",
 				  pkt_len, rx_status);
 			if (skb != NULL) {
 				skb_reserve(skb, 2);
@@ -1072,7 +1064,7 @@ static int el3_rx(struct net_device *dev
 				dev->stats.rx_packets++;
 				dev->stats.rx_bytes += pkt_len;
 			} else {
-				DEBUG(1, "%s: couldn't allocate a sk_buff of"
+				pr_debug("%s: couldn't allocate a sk_buff of"
 					  " size %d.\n", dev->name, pkt_len);
 				dev->stats.rx_dropped++;
 			}
@@ -1101,7 +1093,7 @@ static int el3_ioctl(struct net_device *
 	struct mii_ioctl_data *data = if_mii(rq);
 	int phy = lp->phys & 0x1f;
 
-	DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
+	pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
 		  dev->name, rq->ifr_ifrn.ifrn_name, cmd,
 		  data->phy_id, data->reg_num, data->val_in, data->val_out);
 
@@ -1178,7 +1170,7 @@ static int el3_close(struct net_device *
 	struct el3_private *lp = netdev_priv(dev);
 	struct pcmcia_device *link = lp->p_dev;
 
-	DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+	dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
 	
 	if (pcmcia_dev_present(link)) {
 		unsigned long flags;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/3c589_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c589_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/3c589_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/3c589_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -130,14 +130,6 @@ MODULE_LICENSE("GPL");
 /* Special hook for setting if_port when module is loaded */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -189,7 +181,7 @@ static int tc589_probe(struct pcmcia_dev
     struct el3_private *lp;
     struct net_device *dev;
 
-    DEBUG(0, "3c589_attach()\n");
+    dev_dbg(&link->dev, "3c589_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct el3_private));
@@ -202,10 +194,8 @@ static int tc589_probe(struct pcmcia_dev
     spin_lock_init(&lp->lock);
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &el3_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
@@ -231,7 +221,7 @@ static void tc589_detach(struct pcmcia_d
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "3c589_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "3c589_detach\n");
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -249,29 +239,20 @@ static void tc589_detach(struct pcmcia_d
     
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int tc589_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct el3_private *lp = netdev_priv(dev);
-    tuple_t tuple;
-    __le16 buf[32];
     __be16 *phys_addr;
-    int last_fn, last_ret, i, j, multi = 0, fifo;
+    int ret, i, j, multi = 0, fifo;
     unsigned int ioaddr;
     char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+    u8 *buf;
+    size_t len;
     
-    DEBUG(0, "3c589_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "3c589_config\n");
 
     phys_addr = (__be16 *)dev->dev_addr;
-    tuple.Attributes = 0;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-
     /* Is this a 3c562? */
     if (link->manf_id != MANFID_3COM)
 	    printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -287,12 +268,16 @@ static int tc589_config(struct pcmcia_de
 	if (i == 0)
 		break;
     }
-    if (i != 0) {
-	cs_error(link, RequestIO, i);
+    if (i != 0)
 	goto failed;
-    }
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 	
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
@@ -301,12 +286,13 @@ static int tc589_config(struct pcmcia_de
 
     /* The 3c589 has an extra EEPROM for configuration info, including
        the hardware address.  The 3c562 puts the address in the CIS. */
-    tuple.DesiredTuple = 0x88;
-    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
-	pcmcia_get_tuple_data(link, &tuple);
-	for (i = 0; i < 3; i++)
-	    phys_addr[i] = htons(le16_to_cpu(buf[i]));
+    len = pcmcia_get_tuple(link, 0x88, &buf);
+    if (buf && len >= 6) {
+	    for (i = 0; i < 3; i++)
+		    phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+	    kfree(buf);
     } else {
+	kfree(buf); /* 0 < len < 6 */
 	for (i = 0; i < 3; i++)
 	    phys_addr[i] = htons(read_eeprom(ioaddr, i));
 	if (phys_addr[0] == htons(0x6060)) {
@@ -328,7 +314,7 @@ static int tc589_config(struct pcmcia_de
 	printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
     
     link->dev_node = &lp->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
@@ -347,8 +333,6 @@ static int tc589_config(struct pcmcia_de
 	   if_names[dev->if_port]);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     tc589_release(link);
     return -ENODEV;
@@ -511,24 +495,8 @@ static void netdev_get_drvinfo(struct ne
 	sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_drvinfo		= netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 static int el3_config(struct net_device *dev, struct ifmap *map)
@@ -563,7 +531,7 @@ static int el3_open(struct net_device *d
     lp->media.expires = jiffies + HZ;
     add_timer(&lp->media);
 
-    DEBUG(1, "%s: opened, status %4.4x.\n",
+    dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
 	  dev->name, inw(dev->base_addr + EL3_STATUS));
     
     return 0;
@@ -596,7 +564,7 @@ static void pop_tx_status(struct net_dev
 	if (tx_status & 0x30)
 	    tc589_wait_for_completion(dev, TxReset);
 	if (tx_status & 0x38) {
-	    DEBUG(1, "%s: transmit error: status 0x%02x\n",
+	    pr_debug("%s: transmit error: status 0x%02x\n",
 		  dev->name, tx_status);
 	    outw(TxEnable, ioaddr + EL3_CMD);
 	    dev->stats.tx_aborted_errors++;
@@ -612,7 +580,7 @@ static netdev_tx_t el3_start_xmit(struct
     struct el3_private *priv = netdev_priv(dev);
     unsigned long flags;
 
-    DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+    pr_debug("%s: el3_start_xmit(length = %ld) called, "
 	  "status %4.4x.\n", dev->name, (long)skb->len,
 	  inw(ioaddr + EL3_STATUS));
 
@@ -654,14 +622,14 @@ static irqreturn_t el3_interrupt(int irq
 
     ioaddr = dev->base_addr;
 
-    DEBUG(3, "%s: interrupt, status %4.4x.\n",
+    pr_debug("%s: interrupt, status %4.4x.\n",
 	  dev->name, inw(ioaddr + EL3_STATUS));
 
     spin_lock(&lp->lock);    
     while ((status = inw(ioaddr + EL3_STATUS)) &
 	(IntLatch | RxComplete | StatsFull)) {
 	if ((status & 0xe000) != 0x2000) {
-	    DEBUG(1, "%s: interrupt from dead card\n", dev->name);
+	    pr_debug("%s: interrupt from dead card\n", dev->name);
 	    handled = 0;
 	    break;
 	}
@@ -670,7 +638,7 @@ static irqreturn_t el3_interrupt(int irq
 	    el3_rx(dev);
 	
 	if (status & TxAvailable) {
-	    DEBUG(3, "    TX room bit was handled.\n");
+	    pr_debug("    TX room bit was handled.\n");
 	    /* There's room in the FIFO for a full-sized packet. */
 	    outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 	    netif_wake_queue(dev);
@@ -722,7 +690,7 @@ static irqreturn_t el3_interrupt(int irq
 
     lp->last_irq = jiffies;
     spin_unlock(&lp->lock);    
-    DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+    pr_debug("%s: exiting interrupt, status %4.4x.\n",
 	  dev->name, inw(ioaddr + EL3_STATUS));
     return IRQ_RETVAL(handled);
 }
@@ -743,7 +711,11 @@ static void media_check(unsigned long ar
 	(inb(ioaddr + EL3_TIMER) == 0xff)) {
 	if (!lp->fast_poll)
 	    printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name);
+
+	local_irq_save(flags);
 	el3_interrupt(dev->irq, dev);
+	local_irq_restore(flags);
+
 	lp->fast_poll = HZ;
     }
     if (lp->fast_poll) {
@@ -833,7 +805,7 @@ static void update_stats(struct net_devi
 {
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(2, "%s: updating the statistics.\n", dev->name);
+    pr_debug("%s: updating the statistics.\n", dev->name);
     /* Turn off statistics updates while reading. */
     outw(StatsDisable, ioaddr + EL3_CMD);
     /* Switch to the stats window, and read everything. */
@@ -861,7 +833,7 @@ static int el3_rx(struct net_device *dev
     int worklimit = 32;
     short rx_status;
     
-    DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+    pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
 	  dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
     while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
 		    worklimit > 0) {
@@ -883,7 +855,7 @@ static int el3_rx(struct net_device *dev
 	    
 	    skb = dev_alloc_skb(pkt_len+5);
 	    
-	    DEBUG(3, "    Receiving packet size %d status %4.4x.\n",
+	    pr_debug("    Receiving packet size %d status %4.4x.\n",
 		  pkt_len, rx_status);
 	    if (skb != NULL) {
 		skb_reserve(skb, 2);
@@ -894,7 +866,7 @@ static int el3_rx(struct net_device *dev
 		dev->stats.rx_packets++;
 		dev->stats.rx_bytes += pkt_len;
 	    } else {
-		DEBUG(1, "%s: couldn't allocate a sk_buff of"
+		pr_debug("%s: couldn't allocate a sk_buff of"
 		      " size %d.\n", dev->name, pkt_len);
 		dev->stats.rx_dropped++;
 	    }
@@ -935,7 +907,7 @@ static int el3_close(struct net_device *
     struct pcmcia_device *link = lp->p_dev;
     unsigned int ioaddr = dev->base_addr;
     
-    DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
+    dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
 
     if (pcmcia_dev_present(link)) {
 	/* Turn off statistics ASAP.  We update dev->stats below. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/axnet_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/axnet_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/axnet_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/axnet_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,16 +75,6 @@ MODULE_AUTHOR("David Hinds <dahinds@user
 MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#ifdef PCMCIA_DEBUG
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -167,7 +157,7 @@ static int axnet_probe(struct pcmcia_dev
     struct net_device *dev;
     struct ei_device *ei_local;
 
-    DEBUG(0, "axnet_attach()\n");
+    dev_dbg(&link->dev, "axnet_attach()\n");
 
     dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
     if (!dev)
@@ -180,7 +170,6 @@ static int axnet_probe(struct pcmcia_dev
     info->p_dev = link;
     link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -205,7 +194,7 @@ static void axnet_detach(struct pcmcia_d
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "axnet_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -272,9 +261,6 @@ static int get_prom(struct pcmcia_device
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
@@ -284,7 +270,7 @@ static int try_io_port(struct pcmcia_dev
 	    /* for master/slave multifunction cards */
 	    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 	    link->irq.Attributes =
-		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+		IRQ_TYPE_DYNAMIC_SHARING;
 	}
     } else {
 	/* This should be two 16-port windows */
@@ -341,26 +327,29 @@ static int axnet_config(struct pcmcia_de
 {
     struct net_device *dev = link->priv;
     axnet_dev_t *info = PRIV(dev);
-    int i, j, j2, last_ret, last_fn;
+    int i, j, j2, ret;
 
-    DEBUG(0, "axnet_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
 
     /* don't trust the CIS on this; Linksys got it wrong */
     link->conf.Present = 0x63;
-    last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
-    if (last_ret != 0) {
-	cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
+    if (ret != 0)
 	goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
     
     if (link->io.NumPorts2 == 8) {
 	link->conf.Attributes |= CONF_ENABLE_SPKR;
 	link->conf.Status = CCSR_AUDIO_ENA;
     }
     
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
+
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
 
@@ -410,7 +399,7 @@ static int axnet_config(struct pcmcia_de
 
     info->phy_id = (i < 32) ? i : -1;
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
@@ -426,14 +415,12 @@ static int axnet_config(struct pcmcia_de
 	   dev->base_addr, dev->irq,
 	   dev->dev_addr);
     if (info->phy_id != -1) {
-	DEBUG(0, "  MII transceiver at index %d, status %x.\n", info->phy_id, j);
+	dev_dbg(&link->dev, "  MII transceiver at index %d, status %x.\n", info->phy_id, j);
     } else {
 	printk(KERN_NOTICE "  No MII transceivers found!\n");
     }
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     axnet_release(link);
     return -ENODEV;
@@ -543,7 +530,7 @@ static int axnet_open(struct net_device
     struct pcmcia_device *link = info->p_dev;
     unsigned int nic_base = dev->base_addr;
     
-    DEBUG(2, "axnet_open('%s')\n", dev->name);
+    dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
 
     if (!pcmcia_dev_present(link))
 	return -ENODEV;
@@ -572,7 +559,7 @@ static int axnet_close(struct net_device
     axnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
 
-    DEBUG(2, "axnet_close('%s')\n", dev->name);
+    dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
 
     ax_close(dev);
     free_irq(dev->irq, dev);
@@ -741,10 +728,8 @@ static void block_input(struct net_devic
     int xfer_count = count;
     char *buf = skb->data;
 
-#ifdef PCMCIA_DEBUG
     if ((ei_debug > 4) && (count != 4))
-	printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+	    pr_debug("%s: [bi=%d]\n", dev->name, count+4);
     outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
     outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
     outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
@@ -762,10 +747,7 @@ static void block_output(struct net_devi
 {
     unsigned int nic_base = dev->base_addr;
 
-#ifdef PCMCIA_DEBUG
-    if (ei_debug > 4)
-	printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
-#endif
+    pr_debug("%s: [bo=%d]\n", dev->name, count);
 
     /* Round the count up for word writes.  Do we need to do this?
        What effect will an odd byte count have on the 8390?
@@ -1232,8 +1214,8 @@ static irqreturn_t ax_interrupt(int irq,
 	ei_local->irqlock = 1;
    
 	/* !!Assumption!! -- we stay in page 0.	 Don't break this. */
-	while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
-		   && ++nr_serviced < MAX_SERVICE) 
+	while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 &&
+	       ++nr_serviced < MAX_SERVICE)
 	{
 		if (!netif_running(dev) || (interrupts == 0xff)) {
 			if (ei_debug > 1)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/com20020_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/com20020_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/com20020_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/com20020_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,11 +53,7 @@
 
 #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
 
-#ifdef PCMCIA_DEBUG
-
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#ifdef DEBUG
 
 static void regdump(struct net_device *dev)
 {
@@ -92,7 +88,6 @@ static void regdump(struct net_device *d
 
 #else
 
-#define DEBUG(n, args...) do { } while (0)
 static inline void regdump(struct net_device *dev) { }
 
 #endif
@@ -144,7 +139,7 @@ static int com20020_probe(struct pcmcia_
     struct net_device *dev;
     struct arcnet_local *lp;
 
-    DEBUG(0, "com20020_attach()\n");
+    dev_dbg(&p_dev->dev, "com20020_attach()\n");
 
     /* Create new network device */
     info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
@@ -169,11 +164,10 @@ static int com20020_probe(struct pcmcia_
     p_dev->io.NumPorts1 = 16;
     p_dev->io.IOAddrLines = 16;
     p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
-    p_dev->irq.Instance = info->dev = dev;
+    info->dev = dev;
     p_dev->priv = info;
 
     return com20020_config(p_dev);
@@ -198,12 +192,12 @@ static void com20020_detach(struct pcmci
     struct com20020_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
 
-    DEBUG(1,"detach...\n");
+    dev_dbg(&link->dev, "detach...\n");
 
-    DEBUG(0, "com20020_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "com20020_detach\n");
 
     if (link->dev_node) {
-	DEBUG(1,"unregister...\n");
+	dev_dbg(&link->dev, "unregister...\n");
 
 	unregister_netdev(dev);
 
@@ -218,16 +212,16 @@ static void com20020_detach(struct pcmci
     com20020_release(link);
 
     /* Unlink device structure, free bits */
-    DEBUG(1,"unlinking...\n");
+    dev_dbg(&link->dev, "unlinking...\n");
     if (link->priv)
     {
 	dev = info->dev;
 	if (dev)
 	{
-	    DEBUG(1,"kfree...\n");
+	    dev_dbg(&link->dev, "kfree...\n");
 	    free_netdev(dev);
 	}
-	DEBUG(1,"kfree2...\n");
+	dev_dbg(&link->dev, "kfree2...\n");
 	kfree(info);
     }
 
@@ -241,25 +235,22 @@ static void com20020_detach(struct pcmci
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int com20020_config(struct pcmcia_device *link)
 {
     struct arcnet_local *lp;
     com20020_dev_t *info;
     struct net_device *dev;
-    int i, last_ret, last_fn;
+    int i, ret;
     int ioaddr;
 
     info = link->priv;
     dev = info->dev;
 
-    DEBUG(1,"config...\n");
+    dev_dbg(&link->dev, "config...\n");
 
-    DEBUG(0, "com20020_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "com20020_config\n");
 
-    DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
+    dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
     i = -ENODEV;
     if (!link->io.BasePort1)
     {
@@ -276,26 +267,27 @@ static int com20020_config(struct pcmcia
     
     if (i != 0)
     {
-	DEBUG(1,"arcnet: requestIO failed totally!\n");
+	dev_dbg(&link->dev, "requestIO failed totally!\n");
 	goto failed;
     }
 	
     ioaddr = dev->base_addr = link->io.BasePort1;
-    DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
+    dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
 
-    DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
-	   link->irq.AssignedIRQ,
-	   link->irq.IRQInfo1, link->irq.IRQInfo2);
+    dev_dbg(&link->dev, "request IRQ %d\n",
+	    link->irq.AssignedIRQ);
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0)
     {
-	DEBUG(1,"arcnet: requestIRQ failed totally!\n");
+	dev_dbg(&link->dev, "requestIRQ failed totally!\n");
 	goto failed;
     }
 
     dev->irq = link->irq.AssignedIRQ;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     if (com20020_check(dev))
     {
@@ -308,26 +300,25 @@ static int com20020_config(struct pcmcia
     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     i = com20020_found(dev, 0);	/* calls register_netdev */
     
     if (i != 0) {
-	DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
+	dev_printk(KERN_NOTICE, &link->dev,
+		"com20020_cs: com20020_found() failed\n");
 	link->dev_node = NULL;
 	goto failed;
     }
 
     strcpy(info->node.dev_name, dev->name);
 
-    DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
+    dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
            dev->name, dev->base_addr, dev->irq);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
-    DEBUG(1,"com20020_config failed...\n");
+    dev_dbg(&link->dev, "com20020_config failed...\n");
     com20020_release(link);
     return -ENODEV;
 } /* com20020_config */
@@ -342,7 +333,7 @@ failed:
 
 static void com20020_release(struct pcmcia_device *link)
 {
-	DEBUG(0, "com20020_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "com20020_release\n");
 	pcmcia_disable_device(link);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/fmvj18x_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,13 +72,6 @@ MODULE_LICENSE("GPL");
 /* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
 INT_MODULE_PARM(sram_config, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 /*
@@ -245,7 +238,7 @@ static int fmvj18x_probe(struct pcmcia_d
     local_info_t *lp;
     struct net_device *dev;
 
-    DEBUG(0, "fmvj18x_attach()\n");
+    dev_dbg(&link->dev, "fmvj18x_attach()\n");
 
     /* Make up a FMVJ18x specific data structure */
     dev = alloc_etherdev(sizeof(local_info_t));
@@ -262,10 +255,8 @@ static int fmvj18x_probe(struct pcmcia_d
     link->io.IOAddrLines = 5;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &fjn_interrupt;
-    link->irq.Instance = dev;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+    link->irq.Handler = fjn_interrupt;
 
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -285,7 +276,7 @@ static void fmvj18x_detach(struct pcmcia
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "fmvj18x_detach\n");
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -297,9 +288,6 @@ static void fmvj18x_detach(struct pcmcia
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int mfc_try_io_port(struct pcmcia_device *link)
 {
     int i, ret;
@@ -341,39 +329,44 @@ static int ungermann_try_io_port(struct
     return ret;	/* RequestIO failed */
 }
 
+static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
+			   cistpl_cftable_entry_t *cfg,
+			   cistpl_cftable_entry_t *dflt,
+			   unsigned int vcc,
+			   void *priv_data)
+{
+	return 0; /* strange, but that's what the code did already before... */
+}
+
 static int fmvj18x_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     local_info_t *lp = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
-    u_short buf[32];
-    int i, last_fn = 0, last_ret = 0, ret;
+    int i, ret;
     unsigned int ioaddr;
     cardtype_t cardtype;
     char *card_name = "unknown";
-    u_char *node_id;
+    u8 *buf;
+    size_t len;
+    u_char buggybuf[32];
 
-    DEBUG(0, "fmvj18x_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "fmvj18x_config\n");
 
-    tuple.TupleData = (u_char *)buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    tuple.TupleOffset = 0;
-    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+    len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+    kfree(buf);
+
+    if (len) {
 	/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-	CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-	link->conf.ConfigIndex = parse.cftable_entry.index;
+	ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
+	if (ret != 0)
+		goto failed;
+
 	switch (link->manf_id) {
 	case MANFID_TDK:
 	    cardtype = TDK;
-	    if (link->card_id == PRODID_TDK_GN3410
-			|| link->card_id == PRODID_TDK_NP9610
-			|| link->card_id == PRODID_TDK_MN3200) {
+	    if (link->card_id == PRODID_TDK_GN3410 ||
+		link->card_id == PRODID_TDK_NP9610 ||
+		link->card_id == PRODID_TDK_MN3200) {
 		/* MultiFunction Card */
 		link->conf.ConfigBase = 0x800;
 		link->conf.ConfigIndex = 0x47;
@@ -433,17 +426,24 @@ static int fmvj18x_config(struct pcmcia_
 
     if (link->io.NumPorts2 != 0) {
     	link->irq.Attributes =
-		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+		IRQ_TYPE_DYNAMIC_SHARING;
 	ret = mfc_try_io_port(link);
-	if (ret != 0) goto cs_failed;
+	if (ret != 0) goto failed;
     } else if (cardtype == UNGERMANN) {
 	ret = ungermann_try_io_port(link);
-	if (ret != 0) goto cs_failed;
+	if (ret != 0) goto failed;
     } else { 
-	CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+	    ret = pcmcia_request_io(link, &link->io);
+	    if (ret)
+		    goto failed;
     }
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
+
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
 
@@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_
     case CONTEC:
     case NEC:
     case KME:
-	tuple.DesiredTuple = CISTPL_FUNCE;
-	tuple.TupleOffset = 0;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-	tuple.TupleOffset = 0;
-	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
 	if (cardtype == MBH10304) {
-	    /* MBH10304's CIS_FUNCE is corrupted */
-	    node_id = &(tuple.TupleData[5]);
 	    card_name = "FMV-J182";
-	} else {
-	    while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
-		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+
+	    len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+	    if (len < 11) {
+		    kfree(buf);
+		    goto failed;
 	    }
-	    node_id = &(tuple.TupleData[2]);
+	    /* Read MACID from CIS */
+	    for (i = 5; i < 11; i++)
+		    dev->dev_addr[i] = buf[i];
+	    kfree(buf);
+	} else {
+	    if (pcmcia_get_mac_from_cis(link, dev))
+		goto failed;
 	    if( cardtype == TDK ) {
 		card_name = "TDK LAK-CD021";
 	    } else if( cardtype == LA501 ) {
@@ -501,9 +501,6 @@ static int fmvj18x_config(struct pcmcia_
 		card_name = "C-NET(PC)C";
 	    }
 	}
-	/* Read MACID from CIS */
-	for (i = 0; i < 6; i++)
-	    dev->dev_addr[i] = node_id[i];
 	break;
     case UNGERMANN:
 	/* Read MACID from register */
@@ -513,12 +510,12 @@ static int fmvj18x_config(struct pcmcia_
 	break;
     case XXX10304:
 	/* Read MACID from Buggy CIS */
-	if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
+	if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
 	    printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
 	    goto failed;
 	}
 	for (i = 0 ; i < 6; i++) {
-	    dev->dev_addr[i] = tuple.TupleData[i];
+	    dev->dev_addr[i] = buggybuf[i];
 	}
 	card_name = "FMV-J182";
 	break;
@@ -533,7 +530,7 @@ static int fmvj18x_config(struct pcmcia_
 
     lp->cardtype = cardtype;
     link->dev_node = &lp->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
@@ -551,9 +548,6 @@ static int fmvj18x_config(struct pcmcia_
 
     return 0;
     
-cs_failed:
-    /* All Card Services errors end up here */
-    cs_error(link, last_fn, last_ret);
 failed:
     fmvj18x_release(link);
     return -ENODEV;
@@ -571,16 +565,14 @@ static int fmvj18x_get_hwinfo(struct pcm
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-	cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
 	return -1;
-    }
 
     base = ioremap(req.Base, req.Size);
     mem.Page = 0;
     mem.CardOffset = 0;
-    pcmcia_map_mem_page(link->win, &mem);
+    pcmcia_map_mem_page(link, link->win, &mem);
 
     /*
      *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@@ -590,11 +582,11 @@ static int fmvj18x_get_hwinfo(struct pcm
     */ 
     for (i = 0; i < 0x200; i++) {
 	if (readb(base+i*2) == 0x22) {	
-	    if (readb(base+(i-1)*2) == 0xff
-	     && readb(base+(i+5)*2) == 0x04
-	     && readb(base+(i+6)*2) == 0x06
-	     && readb(base+(i+13)*2) == 0xff) 
-		break;
+		if (readb(base+(i-1)*2) == 0xff &&
+		    readb(base+(i+5)*2) == 0x04 &&
+		    readb(base+(i+6)*2) == 0x06 &&
+		    readb(base+(i+13)*2) == 0xff)
+			break;
 	}
     }
 
@@ -605,9 +597,7 @@ static int fmvj18x_get_hwinfo(struct pcm
     }
 
     iounmap(base);
-    j = pcmcia_release_window(link->win);
-    if (j != 0)
-	cs_error(link, ReleaseWindow, j);
+    j = pcmcia_release_window(link, link->win);
     return (i != 0x200) ? 0 : -1;
 
 } /* fmvj18x_get_hwinfo */
@@ -626,11 +616,9 @@ static int fmvj18x_setup_mfc(struct pcmc
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-	cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
 	return -1;
-    }
 
     lp->base = ioremap(req.Base, req.Size);
     if (lp->base == NULL) {
@@ -640,11 +628,10 @@ static int fmvj18x_setup_mfc(struct pcmc
 
     mem.Page = 0;
     mem.CardOffset = 0;
-    i = pcmcia_map_mem_page(link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, &mem);
     if (i != 0) {
 	iounmap(lp->base);
 	lp->base = NULL;
-	cs_error(link, MapMemPage, i);
 	return -1;
     }
     
@@ -671,15 +658,13 @@ static void fmvj18x_release(struct pcmci
     u_char __iomem *tmp;
     int j;
 
-    DEBUG(0, "fmvj18x_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "fmvj18x_release\n");
 
     if (lp->base != NULL) {
 	tmp = lp->base;
 	lp->base = NULL;    /* set NULL before iounmap */
 	iounmap(tmp);
-	j = pcmcia_release_window(link->win);
-	if (j != 0)
-	    cs_error(link, ReleaseWindow, j);
+	j = pcmcia_release_window(link, link->win);
     }
 
     pcmcia_disable_device(link);
@@ -732,6 +717,7 @@ static struct pcmcia_device_id fmvj18x_i
 	PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101),
 	PCMCIA_DEVICE_NULL,
@@ -788,8 +774,8 @@ static irqreturn_t fjn_interrupt(int dum
     outb(tx_stat, ioaddr + TX_STATUS);
     outb(rx_stat, ioaddr + RX_STATUS);
     
-    DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
-    DEBUG(4, "               tx_status %02x.\n", tx_stat);
+    pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
+    pr_debug("               tx_status %02x.\n", tx_stat);
     
     if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
 	/* there is packet(s) in rx buffer */
@@ -809,8 +795,8 @@ static irqreturn_t fjn_interrupt(int dum
 	}
 	netif_wake_queue(dev);
     }
-    DEBUG(4, "%s: exiting interrupt,\n", dev->name);
-    DEBUG(4, "    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
+    pr_debug("%s: exiting interrupt,\n", dev->name);
+    pr_debug("    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
 
     outb(D_TX_INTR, ioaddr + TX_INTR);
     outb(D_RX_INTR, ioaddr + RX_INTR);
@@ -882,7 +868,7 @@ static netdev_tx_t fjn_start_xmit(struct
 	    return NETDEV_TX_BUSY;
 	}
 
-	DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
+	pr_debug("%s: Transmitting a packet of length %lu.\n",
 	      dev->name, (unsigned long)skb->len);
 	dev->stats.tx_bytes += skb->len;
 
@@ -937,7 +923,7 @@ static void fjn_reset(struct net_device
     unsigned int ioaddr = dev->base_addr;
     int i;
 
-    DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
+    pr_debug("fjn_reset(%s) called.\n",dev->name);
 
     /* Reset controller */
     if( sram_config == 0 ) 
@@ -1015,13 +1001,13 @@ static void fjn_rx(struct net_device *de
     unsigned int ioaddr = dev->base_addr;
     int boguscount = 10;	/* 5 -> 10: by agy 19940922 */
 
-    DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
+    pr_debug("%s: in rx_packet(), rx_status %02x.\n",
 	  dev->name, inb(ioaddr + RX_STATUS));
 
     while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
 	u_short status = inw(ioaddr + DATAPORT);
 
-	DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
+	pr_debug("%s: Rxing packet mode %02x status %04x.\n",
 	      dev->name, inb(ioaddr + RX_MODE), status);
 #ifndef final_version
 	if (status == 0) {
@@ -1061,16 +1047,14 @@ static void fjn_rx(struct net_device *de
 		 (pkt_len + 1) >> 1);
 	    skb->protocol = eth_type_trans(skb, dev);
 
-#ifdef PCMCIA_DEBUG
-	    if (pc_debug > 5) {
+	    {
 		int i;
-		printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
-		       dev->name, pkt_len);
+		pr_debug("%s: Rxed packet of length %d: ",
+			dev->name, pkt_len);
 		for (i = 0; i < 14; i++)
-		    printk(" %02x", skb->data[i]);
-		printk(".\n");
+			pr_debug(" %02x", skb->data[i]);
+		pr_debug(".\n");
 	    }
-#endif
 
 	    netif_rx(skb);
 	    dev->stats.rx_packets++;
@@ -1094,7 +1078,7 @@ static void fjn_rx(struct net_device *de
 	}
 
 	if (i > 0)
-	    DEBUG(5, "%s: Exint Rx packet with mode %02x after "
+	    pr_debug("%s: Exint Rx packet with mode %02x after "
 		  "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
     }
 */
@@ -1112,24 +1096,8 @@ static void netdev_get_drvinfo(struct ne
 	sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_drvinfo		= netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 static int fjn_config(struct net_device *dev, struct ifmap *map){
@@ -1141,7 +1109,7 @@ static int fjn_open(struct net_device *d
     struct local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(4, "fjn_open('%s').\n", dev->name);
+    pr_debug("fjn_open('%s').\n", dev->name);
 
     if (!pcmcia_dev_present(link))
 	return -ENODEV;
@@ -1167,7 +1135,7 @@ static int fjn_close(struct net_device *
     struct pcmcia_device *link = lp->p_dev;
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(4, "fjn_close('%s').\n", dev->name);
+    pr_debug("fjn_close('%s').\n", dev->name);
 
     lp->open_time = 0;
     netif_stop_queue(dev);
@@ -1219,8 +1187,8 @@ static void set_rx_mode(struct net_devic
     if (dev->flags & IFF_PROMISC) {
 	memset(mc_filter, 0xff, sizeof(mc_filter));
 	outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-    } else if (dev->mc_count > MC_FILTERBREAK
-	       ||  (dev->flags & IFF_ALLMULTI)) {
+    } else if (dev->mc_count > MC_FILTERBREAK ||
+	       (dev->flags & IFF_ALLMULTI)) {
 	/* Too many to filter perfectly -- accept all multicasts. */
 	memset(mc_filter, 0xff, sizeof(mc_filter));
 	outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/ibmtr_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/ibmtr_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/ibmtr_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/ibmtr_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,17 +69,6 @@
 #define PCMCIA
 #include "../tokenring/ibmtr.c"
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ibmtr_cs.c 1.10   1996/01/06 05:19:00 (Steve Kipisz)\n"
-"           2.2.7  1999/05/03 12:00:00 (Mike Phillips)\n"
-"           2.4.2  2001/30/28 Midnight (Burt Silverman)\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -130,6 +119,12 @@ static const struct ethtool_ops netdev_e
 	.get_drvinfo		= netdev_get_drvinfo,
 };
 
+static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
+	ibmtr_dev_t *info = dev_id;
+	struct net_device *dev = info->dev;
+	return tok_interrupt(irq, dev);
+};
+
 /*======================================================================
 
     ibmtr_attach() creates an "instance" of the driver, allocating
@@ -143,7 +138,7 @@ static int __devinit ibmtr_attach(struct
     ibmtr_dev_t *info;
     struct net_device *dev;
 
-    DEBUG(0, "ibmtr_attach()\n");
+    dev_dbg(&link->dev, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -161,14 +156,13 @@ static int __devinit ibmtr_attach(struct
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &tok_interrupt;
+    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Handler = ibmtr_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Instance = info->dev = dev;
+    info->dev = dev;
 
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
@@ -190,7 +184,7 @@ static void ibmtr_detach(struct pcmcia_d
     struct net_device *dev = info->dev;
      struct tok_info *ti = netdev_priv(dev);
 
-    DEBUG(0, "ibmtr_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "ibmtr_detach\n");
     
     /* 
      * When the card removal interrupt hits tok_interrupt(), 
@@ -217,9 +211,6 @@ static void ibmtr_detach(struct pcmcia_d
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int __devinit ibmtr_config(struct pcmcia_device *link)
 {
     ibmtr_dev_t *info = link->priv;
@@ -227,9 +218,9 @@ static int __devinit ibmtr_config(struct
     struct tok_info *ti = netdev_priv(dev);
     win_req_t req;
     memreq_t mem;
-    int i, last_ret, last_fn;
+    int i, ret;
 
-    DEBUG(0, "ibmtr_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "ibmtr_config\n");
 
     link->conf.ConfigIndex = 0x61;
 
@@ -241,11 +232,15 @@ static int __devinit ibmtr_config(struct
     if (i != 0) {
 	/* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
 	link->io.BasePort1 = 0xA24;
-	CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+	ret = pcmcia_request_io(link, &link->io);
+	if (ret)
+		goto failed;
     }
     dev->base_addr = link->io.BasePort1;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
     dev->irq = link->irq.AssignedIRQ;
     ti->irq = link->irq.AssignedIRQ;
     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
@@ -256,11 +251,15 @@ static int __devinit ibmtr_config(struct
     req.Base = 0; 
     req.Size = 0x2000;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+	    goto failed;
 
     mem.CardOffset = mmiobase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+	    goto failed;
     ti->mmio = ioremap(req.Base, req.Size);
 
     /* Allocate the SRAM memory window */
@@ -269,17 +268,23 @@ static int __devinit ibmtr_config(struct
     req.Base = 0;
     req.Size = sramsize * 1024;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
+    ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
+    if (ret)
+	    goto failed;
 
     mem.CardOffset = srambase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
+    ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+    if (ret)
+	    goto failed;
 
     ti->sram_base = mem.CardOffset >> 12;
     ti->sram_virt = ioremap(req.Base, req.Size);
     ti->sram_phys = req.Base;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     /*  Set up the Token-Ring Controller Configuration Register and
         turn on the card.  Check the "Local Area Network Credit Card
@@ -287,7 +292,7 @@ static int __devinit ibmtr_config(struct
     ibmtr_hw_setup(dev, mmiobase);
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
@@ -305,8 +310,6 @@ static int __devinit ibmtr_config(struct
 	   dev->dev_addr);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     ibmtr_release(link);
     return -ENODEV;
@@ -325,12 +328,12 @@ static void ibmtr_release(struct pcmcia_
 	ibmtr_dev_t *info = link->priv;
 	struct net_device *dev = info->dev;
 
-	DEBUG(0, "ibmtr_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "ibmtr_release\n");
 
 	if (link->win) {
 		struct tok_info *ti = netdev_priv(dev);
 		iounmap(ti->mmio);
-		pcmcia_release_window(info->sram_win_handle);
+		pcmcia_release_window(link, info->sram_win_handle);
 	}
 	pcmcia_disable_device(link);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/nmclan_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/nmclan_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/nmclan_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/nmclan_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -381,13 +381,6 @@ typedef struct _mace_private {
 Private Global Variables
 ---------------------------------------------------------------------------- */
 
-#ifdef PCMCIA_DEBUG
-static char rcsid[] =
-"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
-static char *version =
-DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
-#endif
-
 static const char *if_names[]={
     "Auto", "10baseT", "BNC",
 };
@@ -406,12 +399,6 @@ MODULE_LICENSE("GPL");
 /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 /* ----------------------------------------------------------------------------
 Function Prototypes
@@ -462,8 +449,7 @@ static int nmclan_probe(struct pcmcia_de
     mace_private *lp;
     struct net_device *dev;
 
-    DEBUG(0, "nmclan_attach()\n");
-    DEBUG(1, "%s\n", rcsid);
+    dev_dbg(&link->dev, "nmclan_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(mace_private));
@@ -477,10 +463,8 @@ static int nmclan_probe(struct pcmcia_de
     link->io.NumPorts1 = 32;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &mace_interrupt;
-    link->irq.Instance = dev;
+    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Handler = mace_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
@@ -507,7 +491,7 @@ static void nmclan_detach(struct pcmcia_
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "nmclan_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "nmclan_detach\n");
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -654,37 +638,40 @@ nmclan_config
 	ethernet device available to the system.
 ---------------------------------------------------------------------------- */
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int nmclan_config(struct pcmcia_device *link)
 {
   struct net_device *dev = link->priv;
   mace_private *lp = netdev_priv(dev);
-  tuple_t tuple;
-  u_char buf[64];
-  int i, last_ret, last_fn;
+  u8 *buf;
+  size_t len;
+  int i, ret;
   unsigned int ioaddr;
 
-  DEBUG(0, "nmclan_config(0x%p)\n", link);
+  dev_dbg(&link->dev, "nmclan_config\n");
+
+  ret = pcmcia_request_io(link, &link->io);
+  if (ret)
+	  goto failed;
+  ret = pcmcia_request_irq(link, &link->irq);
+  if (ret)
+	  goto failed;
+  ret = pcmcia_request_configuration(link, &link->conf);
+  if (ret)
+	  goto failed;
 
-  CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-  CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-  CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
   dev->irq = link->irq.AssignedIRQ;
   dev->base_addr = link->io.BasePort1;
 
   ioaddr = dev->base_addr;
 
   /* Read the ethernet address from the CIS. */
-  tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
-  tuple.TupleData = buf;
-  tuple.TupleDataMax = 64;
-  tuple.TupleOffset = 0;
-  tuple.Attributes = 0;
-  CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-  CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-  memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+  len = pcmcia_get_tuple(link, 0x80, &buf);
+  if (!buf || len < ETHER_ADDR_LEN) {
+	  kfree(buf);
+	  goto failed;
+  }
+  memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
+  kfree(buf);
 
   /* Verify configuration by reading the MACE ID. */
   {
@@ -693,7 +680,7 @@ static int nmclan_config(struct pcmcia_d
     sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
     sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
     if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
-      DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
+      dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
 	    sig[0], sig[1]);
     } else {
       printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
@@ -712,7 +699,7 @@ static int nmclan_config(struct pcmcia_d
     printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
 
   link->dev_node = &lp->node;
-  SET_NETDEV_DEV(dev, &handle_to_dev(link));
+  SET_NETDEV_DEV(dev, &link->dev);
 
   i = register_netdev(dev);
   if (i != 0) {
@@ -729,8 +716,6 @@ static int nmclan_config(struct pcmcia_d
 	 dev->dev_addr);
   return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
 failed:
 	nmclan_release(link);
 	return -ENODEV;
@@ -744,7 +729,7 @@ nmclan_release
 ---------------------------------------------------------------------------- */
 static void nmclan_release(struct pcmcia_device *link)
 {
-	DEBUG(0, "nmclan_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "nmclan_release\n");
 	pcmcia_disable_device(link);
 }
 
@@ -795,7 +780,7 @@ static void nmclan_reset(struct net_devi
   /* Reset Xilinx */
   reg.Action = CS_WRITE;
   reg.Offset = CISREG_COR;
-  DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+  dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
 	OrigCorValue);
   reg.Value = COR_SOFT_RESET;
   pcmcia_access_configuration_register(link, &reg);
@@ -872,7 +857,7 @@ static int mace_close(struct net_device
   mace_private *lp = netdev_priv(dev);
   struct pcmcia_device *link = lp->p_dev;
 
-  DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+  dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
 
   /* Mask off all interrupts from the MACE chip. */
   outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
@@ -891,24 +876,8 @@ static void netdev_get_drvinfo(struct ne
 	sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_drvinfo		= netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 /* ----------------------------------------------------------------------------
@@ -946,7 +915,7 @@ static netdev_tx_t mace_start_xmit(struc
 
   netif_stop_queue(dev);
 
-  DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
+  pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
 	dev->name, (long)skb->len);
 
 #if (!TX_INTERRUPTABLE)
@@ -1008,7 +977,7 @@ static irqreturn_t mace_interrupt(int ir
   int IntrCnt = MACE_MAX_IR_ITERATIONS;
 
   if (dev == NULL) {
-    DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
+    pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
 	  irq);
     return IRQ_NONE;
   }
@@ -1031,7 +1000,7 @@ static irqreturn_t mace_interrupt(int ir
   }
 
   if (!netif_device_present(dev)) {
-    DEBUG(2, "%s: interrupt from dead card\n", dev->name);
+    pr_debug("%s: interrupt from dead card\n", dev->name);
     return IRQ_NONE;
   }
 
@@ -1039,7 +1008,7 @@ static irqreturn_t mace_interrupt(int ir
     /* WARNING: MACE_IR is a READ/CLEAR port! */
     status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
 
-    DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
+    pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
 
     if (status & MACE_IR_RCVINT) {
       mace_rx(dev, MACE_MAX_RX_ITERATIONS);
@@ -1158,7 +1127,7 @@ static int mace_rx(struct net_device *de
   ) {
     rx_status = inw(ioaddr + AM2150_RCV);
 
-    DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
+    pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
 	  " 0x%X.\n", dev->name, rx_framecnt, rx_status);
 
     if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
@@ -1185,7 +1154,7 @@ static int mace_rx(struct net_device *de
       lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
         /* rcv collision count */
 
-      DEBUG(3, "    receiving packet size 0x%X rx_status"
+      pr_debug("    receiving packet size 0x%X rx_status"
 	    " 0x%X.\n", pkt_len, rx_status);
 
       skb = dev_alloc_skb(pkt_len+2);
@@ -1204,7 +1173,7 @@ static int mace_rx(struct net_device *de
 	outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
 	continue;
       } else {
-	DEBUG(1, "%s: couldn't allocate a sk_buff of size"
+	pr_debug("%s: couldn't allocate a sk_buff of size"
 	      " %d.\n", dev->name, pkt_len);
 	lp->linux_stats.rx_dropped++;
       }
@@ -1220,28 +1189,28 @@ pr_linux_stats
 ---------------------------------------------------------------------------- */
 static void pr_linux_stats(struct net_device_stats *pstats)
 {
-  DEBUG(2, "pr_linux_stats\n");
-  DEBUG(2, " rx_packets=%-7ld        tx_packets=%ld\n",
+  pr_debug("pr_linux_stats\n");
+  pr_debug(" rx_packets=%-7ld        tx_packets=%ld\n",
 	(long)pstats->rx_packets, (long)pstats->tx_packets);
-  DEBUG(2, " rx_errors=%-7ld         tx_errors=%ld\n",
+  pr_debug(" rx_errors=%-7ld         tx_errors=%ld\n",
 	(long)pstats->rx_errors, (long)pstats->tx_errors);
-  DEBUG(2, " rx_dropped=%-7ld        tx_dropped=%ld\n",
+  pr_debug(" rx_dropped=%-7ld        tx_dropped=%ld\n",
 	(long)pstats->rx_dropped, (long)pstats->tx_dropped);
-  DEBUG(2, " multicast=%-7ld         collisions=%ld\n",
+  pr_debug(" multicast=%-7ld         collisions=%ld\n",
 	(long)pstats->multicast, (long)pstats->collisions);
 
-  DEBUG(2, " rx_length_errors=%-7ld  rx_over_errors=%ld\n",
+  pr_debug(" rx_length_errors=%-7ld  rx_over_errors=%ld\n",
 	(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
-  DEBUG(2, " rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",
+  pr_debug(" rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",
 	(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
-  DEBUG(2, " rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",
+  pr_debug(" rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",
 	(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
 
-  DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
+  pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
 	(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
-  DEBUG(2, " tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",
+  pr_debug(" tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",
 	(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
-  DEBUG(2, " tx_window_errors=%ld\n",
+  pr_debug(" tx_window_errors=%ld\n",
 	(long)pstats->tx_window_errors);
 } /* pr_linux_stats */
 
@@ -1250,48 +1219,48 @@ pr_mace_stats
 ---------------------------------------------------------------------------- */
 static void pr_mace_stats(mace_statistics *pstats)
 {
-  DEBUG(2, "pr_mace_stats\n");
+  pr_debug("pr_mace_stats\n");
 
-  DEBUG(2, " xmtsv=%-7d             uflo=%d\n",
+  pr_debug(" xmtsv=%-7d             uflo=%d\n",
 	pstats->xmtsv, pstats->uflo);
-  DEBUG(2, " lcol=%-7d              more=%d\n",
+  pr_debug(" lcol=%-7d              more=%d\n",
 	pstats->lcol, pstats->more);
-  DEBUG(2, " one=%-7d               defer=%d\n",
+  pr_debug(" one=%-7d               defer=%d\n",
 	pstats->one, pstats->defer);
-  DEBUG(2, " lcar=%-7d              rtry=%d\n",
+  pr_debug(" lcar=%-7d              rtry=%d\n",
 	pstats->lcar, pstats->rtry);
 
   /* MACE_XMTRC */
-  DEBUG(2, " exdef=%-7d             xmtrc=%d\n",
+  pr_debug(" exdef=%-7d             xmtrc=%d\n",
 	pstats->exdef, pstats->xmtrc);
 
   /* RFS1--Receive Status (RCVSTS) */
-  DEBUG(2, " oflo=%-7d              clsn=%d\n",
+  pr_debug(" oflo=%-7d              clsn=%d\n",
 	pstats->oflo, pstats->clsn);
-  DEBUG(2, " fram=%-7d              fcs=%d\n",
+  pr_debug(" fram=%-7d              fcs=%d\n",
 	pstats->fram, pstats->fcs);
 
   /* RFS2--Runt Packet Count (RNTPC) */
   /* RFS3--Receive Collision Count (RCVCC) */
-  DEBUG(2, " rfs_rntpc=%-7d         rfs_rcvcc=%d\n",
+  pr_debug(" rfs_rntpc=%-7d         rfs_rcvcc=%d\n",
 	pstats->rfs_rntpc, pstats->rfs_rcvcc);
 
   /* MACE_IR */
-  DEBUG(2, " jab=%-7d               babl=%d\n",
+  pr_debug(" jab=%-7d               babl=%d\n",
 	pstats->jab, pstats->babl);
-  DEBUG(2, " cerr=%-7d              rcvcco=%d\n",
+  pr_debug(" cerr=%-7d              rcvcco=%d\n",
 	pstats->cerr, pstats->rcvcco);
-  DEBUG(2, " rntpco=%-7d            mpco=%d\n",
+  pr_debug(" rntpco=%-7d            mpco=%d\n",
 	pstats->rntpco, pstats->mpco);
 
   /* MACE_MPC */
-  DEBUG(2, " mpc=%d\n", pstats->mpc);
+  pr_debug(" mpc=%d\n", pstats->mpc);
 
   /* MACE_RNTPC */
-  DEBUG(2, " rntpc=%d\n", pstats->rntpc);
+  pr_debug(" rntpc=%d\n", pstats->rntpc);
 
   /* MACE_RCVCC */
-  DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
+  pr_debug(" rcvcc=%d\n", pstats->rcvcc);
 
 } /* pr_mace_stats */
 
@@ -1360,7 +1329,7 @@ static struct net_device_stats *mace_get
 
   update_stats(dev->base_addr, dev);
 
-  DEBUG(1, "%s: updating the statistics.\n", dev->name);
+  pr_debug("%s: updating the statistics.\n", dev->name);
   pr_linux_stats(&lp->linux_stats);
   pr_mace_stats(&lp->mace_stats);
 
@@ -1427,13 +1396,12 @@ static void BuildLAF(int *ladrf, int *ad
   ladrf[byte] |= (1 << (hashcode & 7));
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 2)
+  if (0)
     printk(KERN_DEBUG "    adr =%pM\n", adr);
   printk(KERN_DEBUG "    hashcode = %d(decimal), ladrf[0:63] =", hashcode);
   for (i = 0; i < 8; i++)
     printk(KERN_CONT " %02X", ladrf[i]);
   printk(KERN_CONT "\n");
-  }
 #endif
 } /* BuildLAF */
 
@@ -1454,12 +1422,12 @@ static void restore_multicast_list(struc
   unsigned int ioaddr = dev->base_addr;
   int i;
 
-  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
+  pr_debug("%s: restoring Rx mode to %d addresses.\n",
 	dev->name, num_addrs);
 
   if (num_addrs > 0) {
 
-    DEBUG(1, "Attempt to restore multicast list detected.\n");
+    pr_debug("Attempt to restore multicast list detected.\n");
 
     mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
     /* Poll ADDRCHG bit */
@@ -1511,11 +1479,11 @@ static void set_multicast_list(struct ne
   struct dev_mc_list *dmi = dev->mc_list;
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 1) {
+  {
     static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
-      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+      pr_debug("%s: setting Rx mode to %d addresses.\n",
 	    dev->name, old);
     }
   }
@@ -1546,7 +1514,7 @@ static void restore_multicast_list(struc
   unsigned int ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
 
-  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
+  pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
 	lp->multicast_num_addrs);
 
   if (dev->flags & IFF_PROMISC) {
@@ -1567,11 +1535,11 @@ static void set_multicast_list(struct ne
   mace_private *lp = netdev_priv(dev);
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 1) {
+  {
     static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
-      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+      pr_debug("%s: setting Rx mode to %d addresses.\n",
 	    dev->name, old);
     }
   }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/pcnet_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/pcnet_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/pcnet_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/pcnet_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,15 +71,6 @@
 
 static const char *if_names[] = { "auto", "10baseT", "10base2"};
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -265,7 +256,7 @@ static int pcnet_probe(struct pcmcia_dev
     pcnet_dev_t *info;
     struct net_device *dev;
 
-    DEBUG(0, "pcnet_attach()\n");
+    dev_dbg(&link->dev, "pcnet_attach()\n");
 
     /* Create new ethernet device */
     dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
@@ -275,7 +266,6 @@ static int pcnet_probe(struct pcmcia_dev
     link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -297,7 +287,7 @@ static void pcnet_detach(struct pcmcia_d
 {
 	struct net_device *dev = link->priv;
 
-	DEBUG(0, "pcnet_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "pcnet_detach\n");
 
 	if (link->dev_node)
 		unregister_netdev(dev);
@@ -326,17 +316,15 @@ static hw_info_t *get_hwinfo(struct pcmc
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-	cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
 	return NULL;
-    }
 
     virt = ioremap(req.Base, req.Size);
     mem.Page = 0;
     for (i = 0; i < NR_INFO; i++) {
 	mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
-	pcmcia_map_mem_page(link->win, &mem);
+	pcmcia_map_mem_page(link, link->win, &mem);
 	base = &virt[hw_info[i].offset & (req.Size-1)];
 	if ((readb(base+0) == hw_info[i].a0) &&
 	    (readb(base+2) == hw_info[i].a1) &&
@@ -348,9 +336,7 @@ static hw_info_t *get_hwinfo(struct pcmc
     }
 
     iounmap(virt);
-    j = pcmcia_release_window(link->win);
-    if (j != 0)
-	cs_error(link, ReleaseWindow, j);
+    j = pcmcia_release_window(link, link->win);
     return (i < NR_INFO) ? hw_info+i : NULL;
 } /* get_hwinfo */
 
@@ -495,9 +481,6 @@ static hw_info_t *get_hwired(struct pcmc
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
@@ -507,7 +490,7 @@ static int try_io_port(struct pcmcia_dev
 	    /* for master/slave multifunction cards */
 	    link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 	    link->irq.Attributes =
-		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+		IRQ_TYPE_DYNAMIC_SHARING;
 	}
     } else {
 	/* This should be two 16-port windows */
@@ -567,19 +550,19 @@ static int pcnet_config(struct pcmcia_de
 {
     struct net_device *dev = link->priv;
     pcnet_dev_t *info = PRIV(dev);
-    int last_ret, last_fn, start_pg, stop_pg, cm_offset;
+    int ret, start_pg, stop_pg, cm_offset;
     int has_shmem = 0;
     hw_info_t *local_hw_info;
 
-    DEBUG(0, "pcnet_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "pcnet_config\n");
 
-    last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
-    if (last_ret) {
-	cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
+    if (ret)
 	goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
 
     if (link->io.NumPorts2 == 8) {
 	link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -589,7 +572,9 @@ static int pcnet_config(struct pcmcia_de
 	(link->card_id == PRODID_IBM_HOME_AND_AWAY))
 	link->conf.ConfigIndex |= 0x10;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
     if (info->flags & HAS_MISC_REG) {
@@ -601,8 +586,8 @@ static int pcnet_config(struct pcmcia_de
 	dev->if_port = 0;
     }
 
-    if ((link->conf.ConfigBase == 0x03c0)
-	&& (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
+    if ((link->conf.ConfigBase == 0x03c0) &&
+	(link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
 	printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
 	printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
 	goto failed;
@@ -660,7 +645,7 @@ static int pcnet_config(struct pcmcia_de
 	mii_phy_probe(dev);
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
@@ -687,8 +672,6 @@ static int pcnet_config(struct pcmcia_de
     printk(" hw_addr %pM\n", dev->dev_addr);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     pcnet_release(link);
     return -ENODEV;
@@ -706,7 +689,7 @@ static void pcnet_release(struct pcmcia_
 {
 	pcnet_dev_t *info = PRIV(link->priv);
 
-	DEBUG(0, "pcnet_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "pcnet_release\n");
 
 	if (info->flags & USE_SHMEM)
 		iounmap(info->base);
@@ -960,7 +943,7 @@ static void mii_phy_probe(struct net_dev
 	phyid = tmp << 16;
 	phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
 	phyid &= MII_PHYID_REV_MASK;
-	DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+	pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
 	if (phyid == AM79C9XX_HOME_PHY) {
 	    info->pna_phy = i;
 	} else if (phyid != AM79C9XX_ETH_PHY) {
@@ -976,7 +959,7 @@ static int pcnet_open(struct net_device
     struct pcmcia_device *link = info->p_dev;
     unsigned int nic_base = dev->base_addr;
 
-    DEBUG(2, "pcnet_open('%s')\n", dev->name);
+    dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
 
     if (!pcmcia_dev_present(link))
 	return -ENODEV;
@@ -1008,7 +991,7 @@ static int pcnet_close(struct net_device
     pcnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
 
-    DEBUG(2, "pcnet_close('%s')\n", dev->name);
+    dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
 
     ei_close(dev);
     free_irq(dev->irq, dev);
@@ -1251,10 +1234,8 @@ static void dma_block_input(struct net_d
     int xfer_count = count;
     char *buf = skb->data;
 
-#ifdef PCMCIA_DEBUG
     if ((ei_debug > 4) && (count != 4))
-	printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+	pr_debug("%s: [bi=%d]\n", dev->name, count+4);
     if (ei_status.dmaing) {
 	printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
 	       "[DMAstat:%1x][irqlock:%1x]\n",
@@ -1495,7 +1476,7 @@ static int setup_shmem_window(struct pcm
     pcnet_dev_t *info = PRIV(dev);
     win_req_t req;
     memreq_t mem;
-    int i, window_size, offset, last_ret, last_fn;
+    int i, window_size, offset, ret;
 
     window_size = (stop_pg - start_pg) << 8;
     if (window_size > 32 * 1024)
@@ -1509,13 +1490,17 @@ static int setup_shmem_window(struct pcm
     req.Attributes |= WIN_USE_WAIT;
     req.Base = 0; req.Size = window_size;
     req.AccessSpeed = mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+	    goto failed;
 
     mem.CardOffset = (start_pg << 8) + cm_offset;
     offset = mem.CardOffset % window_size;
     mem.CardOffset -= offset;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+	    goto failed;
 
     /* Try scribbling on the buffer */
     info->base = ioremap(req.Base, window_size);
@@ -1527,8 +1512,8 @@ static int setup_shmem_window(struct pcm
     pcnet_reset_8390(dev);
     if (i != (TX_PAGES<<8)) {
 	iounmap(info->base);
-	pcmcia_release_window(link->win);
-	info->base = NULL; link->win = NULL;
+	pcmcia_release_window(link, link->win);
+	info->base = NULL; link->win = 0;
 	goto failed;
     }
 
@@ -1549,8 +1534,6 @@ static int setup_shmem_window(struct pcm
     info->flags |= USE_SHMEM;
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     return 1;
 }
@@ -1758,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
 	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
-	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
@@ -1768,6 +1751,13 @@ static struct pcmcia_device_id pcnet_ids
 	PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, pcnet_ids);
+MODULE_FIRMWARE("cis/PCMLM28.cis");
+MODULE_FIRMWARE("cis/DP83903.cis");
+MODULE_FIRMWARE("cis/LA-PCM.cis");
+MODULE_FIRMWARE("cis/PE520.cis");
+MODULE_FIRMWARE("cis/NE2K.cis");
+MODULE_FIRMWARE("cis/PE-200.cis");
+MODULE_FIRMWARE("cis/tamarack.cis");
 
 static struct pcmcia_driver pcnet_driver = {
 	.drv		= {
@@ -1788,7 +1778,6 @@ static int __init init_pcnet_cs(void)
 
 static void __exit exit_pcnet_cs(void)
 {
-    DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/smc91c92_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/smc91c92_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 14:01:33.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 12:08:55.000000000 -0400
@@ -79,14 +79,6 @@ MODULE_LICENSE("GPL");
 */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-static const char *version =
-"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 #define DRV_NAME	"smc91c92_cs"
 #define DRV_VERSION	"1.123"
@@ -126,12 +118,6 @@ struct smc_private {
     int				rx_ovrn;
 };
 
-struct smc_cfg_mem {
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255];
-};
-
 /* Special definitions for Megahertz multifunction cards */
 #define MEGAHERTZ_ISR		0x0380
 
@@ -329,7 +315,7 @@ static int smc91c92_probe(struct pcmcia_
     struct smc_private *smc;
     struct net_device *dev;
 
-    DEBUG(0, "smc91c92_attach()\n");
+    dev_dbg(&link->dev, "smc91c92_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct smc_private));
@@ -343,10 +329,8 @@ static int smc91c92_probe(struct pcmcia_
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &smc_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -377,7 +361,7 @@ static void smc91c92_detach(struct pcmci
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "smc91c92_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_detach\n");
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -408,34 +392,7 @@ static int cvt_ascii_address(struct net_
     return 0;
 }
 
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		cisparse_t *parse)
-{
-	int i;
-
-	i = pcmcia_get_first_tuple(handle, tuple);
-	if (i != 0)
-		return i;
-	i = pcmcia_get_tuple_data(handle, tuple);
-	if (i != 0)
-		return i;
-	return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		cisparse_t *parse)
-{
-	int i;
-
-	if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
-			(i = pcmcia_get_tuple_data(handle, tuple)) != 0)
-		return i;
-	return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
 
     Configuration stuff for Megahertz cards
 
@@ -490,19 +447,14 @@ static int mhz_mfc_config(struct pcmcia_
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    struct smc_cfg_mem *cfg_mem;
     win_req_t req;
     memreq_t mem;
     int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-	    return -ENOMEM;
-
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
-	IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+	IRQ_TYPE_DYNAMIC_SHARING;
     link->io.IOAddrLines = 16;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -510,91 +462,80 @@ static int mhz_mfc_config(struct pcmcia_
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
     if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
-	goto free_cfg_mem;
+	    return -ENODEV;
+
     dev->base_addr = link->io.BasePort1;
 
     /* Allocate a memory window, for accessing the ISR */
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
+    i = pcmcia_request_window(link, &req, &link->win);
     if (i != 0)
-	goto free_cfg_mem;
+	    return -ENODEV;
+
     smc->base = ioremap(req.Base, req.Size);
     mem.CardOffset = mem.Page = 0;
     if (smc->manfid == MANFID_MOTOROLA)
 	mem.CardOffset = link->conf.ConfigBase;
-    i = pcmcia_map_mem_page(link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, &mem);
 
-    if ((i == 0)
-	&& (smc->manfid == MANFID_MEGAHERTZ)
-	&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
-	mhz_3288_power(link);
+    if ((i == 0) &&
+	(smc->manfid == MANFID_MEGAHERTZ) &&
+	(smc->cardid == PRODID_MEGAHERTZ_EM3288))
+	    mhz_3288_power(link);
 
-free_cfg_mem:
-    kfree(cfg_mem);
-    return -ENODEV;
+    return 0;
 }
 
-static int mhz_setup(struct pcmcia_device *link)
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+			      tuple_t *tuple,
+			      void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    u_char *buf, *station_addr;
-    int rc;
+	struct net_device *dev = priv;
+	cisparse_t parse;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-	return -1;
+	if (pcmcia_parse_tuple(tuple, &parse))
+		return -EINVAL;
 
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
+	if ((parse.version_1.ns > 3) &&
+	    (cvt_ascii_address(dev,
+			       (parse.version_1.str + parse.version_1.ofs[3]))))
+		return 0;
 
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
+	return -EINVAL;
+};
+
+static int mhz_setup(struct pcmcia_device *link)
+{
+    struct net_device *dev = link->priv;
+    size_t len;
+    u8 *buf;
+    int rc;
 
     /* Read the station address from the CIS.  It is stored as the last
        (fourth) string in the Version 1 Version/ID tuple. */
-    tuple->DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(link, tuple, parse) != 0) {
-	rc = -1;
-	goto free_cfg_mem;
-    }
+    if ((link->prod_id[3]) &&
+	(cvt_ascii_address(dev, link->prod_id[3]) == 0))
+	    return 0;
+
+    /* Workarounds for broken cards start here. */
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(link, tuple, parse) != 0)
-	first_tuple(link, tuple, parse);
-    if (parse->version_1.ns > 3) {
-	station_addr = parse->version_1.str + parse->version_1.ofs[3];
-	if (cvt_ascii_address(dev, station_addr) == 0) {
-		rc = 0;
-		goto free_cfg_mem;
-	}
-    }
+    if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+	    return 0;
 
     /* Another possibility: for the EM3288, in a special tuple */
-    tuple->DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(link, tuple) != 0) {
-	rc = -1;
-	goto free_cfg_mem;
-    }
-    if (pcmcia_get_tuple_data(link, tuple) != 0) {
-	rc = -1;
-	goto free_cfg_mem;
-    }
-    buf[12] = '\0';
-    if (cvt_ascii_address(dev, buf) == 0) {
-	rc = 0;
-	goto free_cfg_mem;
-   }
     rc = -1;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
-}
+    len = pcmcia_get_tuple(link, 0x81, &buf);
+    if (buf && len >= 13) {
+	    buf[12] = '\0';
+	    if (cvt_ascii_address(dev, buf))
+		    rc = 0;
+    }
+    kfree(buf);
+
+    return rc;
+};
 
 /*======================================================================
 
@@ -684,58 +625,21 @@ static int smc_config(struct pcmcia_devi
     return i;
 }
 
+
 static int smc_setup(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_lan_node_id_t *node_id;
-    u_char *buf, *station_addr;
-    int i, rc;
-
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-	    return -ENOMEM;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
 
     /* Check for a LAN function extension tuple */
-    tuple->DesiredTuple = CISTPL_FUNCE;
-    i = first_tuple(link, tuple, parse);
-    while (i == 0) {
-	if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
-	    break;
-	i = next_tuple(link, tuple, parse);
-    }
-    if (i == 0) {
-	node_id = (cistpl_lan_node_id_t *)parse->funce.data;
-	if (node_id->nb == 6) {
-	    for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = node_id->id[i];
-	    rc = 0;
-	    goto free_cfg_mem;
-	}
-    }
+    if (!pcmcia_get_mac_from_cis(link, dev))
+	    return 0;
+
     /* Try the third string in the Version 1 Version/ID tuple. */
     if (link->prod_id[2]) {
-	station_addr = link->prod_id[2];
-	if (cvt_ascii_address(dev, station_addr) == 0) {
-		rc = 0;
-		goto free_cfg_mem;
-	}
+	    if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+		    return 0;
     }
-
-    rc = -1;
-free_cfg_mem:
-    kfree(cfg_mem);
-    return rc;
+    return -1;
 }
 
 /*====================================================================*/
@@ -749,7 +653,7 @@ static int osi_config(struct pcmcia_devi
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
-	IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+	IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
     link->io.NumPorts1 = 64;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -794,41 +698,31 @@ static int osi_load_firmware(struct pcmc
 	return err;
 }
 
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+			  tuple_t *tuple,
+			  void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    u_char *buf;
-    int i, rc;
+	struct net_device *dev = priv;
+	int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-        return -1;
+	if (tuple->TupleDataLen < 8)
+		return -EINVAL;
+	if (tuple->TupleData[0] != 0x04)
+		return -EINVAL;
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = tuple->TupleData[i+2];
+	return 0;
+};
 
-    tuple = &cfg_mem->tuple;
-    buf = cfg_mem->buf;
 
-    tuple->Attributes = TUPLE_RETURN_COMMON;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+    struct net_device *dev = link->priv;
+    int rc;
 
     /* Read the station address from tuple 0x90, subtuple 0x04 */
-    tuple->DesiredTuple = 0x90;
-    i = pcmcia_get_first_tuple(link, tuple);
-    while (i == 0) {
-	i = pcmcia_get_tuple_data(link, tuple);
-	if ((i != 0) || (buf[0] == 0x04))
-	    break;
-	i = pcmcia_get_next_tuple(link, tuple);
-    }
-    if (i != 0) {
-	rc = -1;
-	goto free_cfg_mem;
-    }
-    for (i = 0; i < 6; i++)
-	dev->dev_addr[i] = buf[i+2];
+    if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+	    return -1;
 
     if (((manfid == MANFID_OSITECH) &&
 	 (cardid == PRODID_OSITECH_SEVEN)) ||
@@ -836,20 +730,17 @@ static int osi_setup(struct pcmcia_devic
 	 (cardid == PRODID_PSION_NET100))) {
 	rc = osi_load_firmware(link);
 	if (rc)
-		goto free_cfg_mem;
+		return rc;
     } else if (manfid == MANFID_OSITECH) {
 	/* Make sure both functions are powered up */
 	set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
 	/* Now, turn on the interrupt for both card functions */
 	set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
-	DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
+	dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
 	      inw(link->io.BasePort1 + OSITECH_AUI_PWR),
 	      inw(link->io.BasePort1 + OSITECH_RESET_ISR));
     }
-    rc = 0;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
+    return 0;
 }
 
 static int smc91c92_suspend(struct pcmcia_device *link)
@@ -959,12 +850,6 @@ static int check_sig(struct pcmcia_devic
 
 ======================================================================*/
 
-#define CS_EXIT_TEST(ret, svc, label)	\
-if (ret != 0) {				\
-	cs_error(link, svc, ret);	\
-	goto label; 			\
-}
-
 static int smc91c92_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
@@ -974,7 +859,7 @@ static int smc91c92_config(struct pcmcia
     unsigned int ioaddr;
     u_long mir;
 
-    DEBUG(0, "smc91c92_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_config\n");
 
     smc->manfid = link->manf_id;
     smc->cardid = link->card_id;
@@ -990,12 +875,15 @@ static int smc91c92_config(struct pcmcia
     } else {
 	i = smc_config(link);
     }
-    CS_EXIT_TEST(i, RequestIO, config_failed);
+    if (i)
+	    goto config_failed;
 
     i = pcmcia_request_irq(link, &link->irq);
-    CS_EXIT_TEST(i, RequestIRQ, config_failed);
+    if (i)
+	    goto config_failed;
     i = pcmcia_request_configuration(link, &link->conf);
-    CS_EXIT_TEST(i, RequestConfiguration, config_failed);
+    if (i)
+	    goto config_failed;
 
     if (smc->manfid == MANFID_MOTOROLA)
 	mot_config(link);
@@ -1074,7 +962,7 @@ static int smc91c92_config(struct pcmcia
     }
 
     link->dev_node = &smc->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
 	printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
@@ -1100,7 +988,7 @@ static int smc91c92_config(struct pcmcia
 
     if (smc->cfg & CFG_MII_SELECT) {
 	if (smc->mii_if.phy_id != -1) {
-	    DEBUG(0, "  MII transceiver at index %d, status %x.\n",
+	    dev_dbg(&link->dev, "  MII transceiver at index %d, status %x.\n",
 		  smc->mii_if.phy_id, j);
 	} else {
     	    printk(KERN_NOTICE "  No MII transceivers found!\n");
@@ -1110,7 +998,7 @@ static int smc91c92_config(struct pcmcia
 
 config_undo:
     unregister_netdev(dev);
-config_failed:			/* CS_EXIT_TEST() calls jump to here... */
+config_failed:
     smc91c92_release(link);
     return -ENODEV;
 } /* smc91c92_config */
@@ -1125,7 +1013,7 @@ config_failed:			/* CS_EXIT_TEST() calls
 
 static void smc91c92_release(struct pcmcia_device *link)
 {
-	DEBUG(0, "smc91c92_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "smc91c92_release\n");
 	if (link->win) {
 		struct net_device *dev = link->priv;
 		struct smc_private *smc = netdev_priv(dev);
@@ -1222,10 +1110,10 @@ static int smc_open(struct net_device *d
     struct smc_private *smc = netdev_priv(dev);
     struct pcmcia_device *link = smc->p_dev;
 
-#ifdef PCMCIA_DEBUG
-    DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
 	  dev->name, dev, inw(dev->base_addr + BANK_SELECT));
-    if (pc_debug > 1) smc_dump(dev);
+#ifdef PCMCIA_DEBUG
+    smc_dump(dev);
 #endif
 
     /* Check that the PCMCIA card is still here. */
@@ -1260,7 +1148,7 @@ static int smc_close(struct net_device *
     struct pcmcia_device *link = smc->p_dev;
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "%s: smc_close(), status %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
 	  dev->name, inw(ioaddr + BANK_SELECT));
 
     netif_stop_queue(dev);
@@ -1327,7 +1215,7 @@ static void smc_hardware_send_packet(str
 	u_char *buf = skb->data;
 	u_int length = skb->len; /* The chip will pad to ethernet min. */
 
-	DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
+	pr_debug("%s: Trying to xmit packet of length %d.\n",
 	      dev->name, length);
 	
 	/* send the packet length: +6 for status word, length, and ctl */
@@ -1382,7 +1270,7 @@ static netdev_tx_t smc_start_xmit(struct
 
     netif_stop_queue(dev);
 
-    DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
+    pr_debug("%s: smc_start_xmit(length = %d) called,"
 	  " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
 
     if (smc->saved_skb) {
@@ -1429,7 +1317,7 @@ static netdev_tx_t smc_start_xmit(struct
     }
 
     /* Otherwise defer until the Tx-space-allocated interrupt. */
-    DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
+    pr_debug("%s: memory allocation deferred.\n", dev->name);
     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
     spin_unlock_irqrestore(&smc->lock, flags);
 
@@ -1494,7 +1382,7 @@ static void smc_eph_irq(struct net_devic
 
     SMC_SELECT_BANK(0);
     ephs = inw(ioaddr + EPH);
-    DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
+    pr_debug("%s: Ethernet protocol handler interrupt, status"
 	  " %4.4x.\n", dev->name, ephs);
     /* Could be a counter roll-over warning: update stats. */
     card_stats = inw(ioaddr + COUNTER);
@@ -1534,7 +1422,7 @@ static irqreturn_t smc_interrupt(int irq
 
     ioaddr = dev->base_addr;
 
-    DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
+    pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
 	  irq, ioaddr);
 
     spin_lock(&smc->lock);
@@ -1543,7 +1431,7 @@ static irqreturn_t smc_interrupt(int irq
     if ((saved_bank & 0xff00) != 0x3300) {
 	/* The device does not exist -- the card could be off-line, or
 	   maybe it has been ejected. */
-	DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
+	pr_debug("%s: SMC91c92 interrupt %d for non-existent"
 	      "/ejected device.\n", dev->name, irq);
 	handled = 0;
 	goto irq_done;
@@ -1557,7 +1445,7 @@ static irqreturn_t smc_interrupt(int irq
 
     do { /* read the status flag, and mask it */
 	status = inw(ioaddr + INTERRUPT) & 0xff;
-	DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
+	pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
 	      status, mask);
 	if ((status & mask) == 0) {
 	    if (bogus_cnt == INTR_WORK)
@@ -1602,7 +1490,7 @@ static irqreturn_t smc_interrupt(int irq
 	    smc_eph_irq(dev);
     } while (--bogus_cnt);
 
-    DEBUG(3, "  Restoring saved registers mask %2.2x bank %4.4x"
+    pr_debug("  Restoring saved registers mask %2.2x bank %4.4x"
 	  " pointer %4.4x.\n", mask, saved_bank, saved_pointer);
 
     /* restore state register */
@@ -1610,7 +1498,7 @@ static irqreturn_t smc_interrupt(int irq
     outw(saved_pointer, ioaddr + POINTER);
     SMC_SELECT_BANK(saved_bank);
 
-    DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
+    pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
 
 irq_done:
 
@@ -1661,7 +1549,7 @@ static void smc_rx(struct net_device *de
     rx_status = inw(ioaddr + DATA_1);
     packet_length = inw(ioaddr + DATA_1) & 0x07ff;
 
-    DEBUG(2, "%s: Receive status %4.4x length %d.\n",
+    pr_debug("%s: Receive status %4.4x length %d.\n",
 	  dev->name, rx_status, packet_length);
 
     if (!(rx_status & RS_ERRORS)) {		
@@ -1672,7 +1560,7 @@ static void smc_rx(struct net_device *de
 	skb = dev_alloc_skb(packet_length+2);
 	
 	if (skb == NULL) {
-	    DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
+	    pr_debug("%s: Low memory, packet dropped.\n", dev->name);
 	    dev->stats.rx_dropped++;
 	    outw(MC_RELEASE, ioaddr + MMU_CMD);
 	    return;
@@ -1832,7 +1720,7 @@ static void smc_reset(struct net_device
     struct smc_private *smc = netdev_priv(dev);
     int i;
 
-    DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
+    pr_debug("%s: smc91c92 reset called.\n", dev->name);
 
     /* The first interaction must be a write to bring the chip out
        of sleep mode. */
@@ -2149,18 +2037,6 @@ static u32 smc_get_link(struct net_devic
 	return ret;
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 smc_get_msglevel(struct net_device *dev)
-{
-	return pc_debug;
-}
-
-static void smc_set_msglevel(struct net_device *dev, u32 val)
-{
-	pc_debug = val;
-}
-#endif
-
 static int smc_nway_reset(struct net_device *dev)
 {
 	struct smc_private *smc = netdev_priv(dev);
@@ -2184,10 +2060,6 @@ static const struct ethtool_ops ethtool_
 	.get_settings = smc_get_settings,
 	.set_settings = smc_set_settings,
 	.get_link = smc_get_link,
-#ifdef PCMCIA_DEBUG
-	.get_msglevel = smc_get_msglevel,
-	.set_msglevel = smc_set_msglevel,
-#endif
 	.nway_reset = smc_nway_reset,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcmcia/xirc2ps_cs.c linux-libre-2.6.33-gnu1/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -211,20 +211,6 @@ enum xirc_cmd { 	    /* Commands */
 
 static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
 
-/****************
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 #define KDBG_XIRC KERN_DEBUG   "xirc2ps_cs: "
 #define KERR_XIRC KERN_ERR     "xirc2ps_cs: "
@@ -359,7 +345,7 @@ static void xirc_tx_timeout(struct net_d
 static void xirc2ps_tx_timeout_task(struct work_struct *work);
 static void set_addresses(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
-static int set_card_type(struct pcmcia_device *link, const void *s);
+static int set_card_type(struct pcmcia_device *link);
 static int do_config(struct net_device *dev, struct ifmap *map);
 static int do_open(struct net_device *dev);
 static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -371,28 +357,6 @@ static void do_powerdown(struct net_devi
 static int do_stop(struct net_device *dev);
 
 /*=============== Helper functions =========================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-	int err;
-
-	if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
-			(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-		err = pcmcia_parse_tuple(tuple, parse);
-	return err;
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-	int err;
-
-	if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
-			(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-		err = pcmcia_parse_tuple(tuple, parse);
-	return err;
-}
-
 #define SelectPage(pgnr)   outb((pgnr), ioaddr + XIRCREG_PR)
 #define GetByte(reg)	   ((unsigned)inb(ioaddr + (reg)))
 #define GetWord(reg)	   ((unsigned)inw(ioaddr + (reg)))
@@ -400,7 +364,7 @@ next_tuple(struct pcmcia_device *handle,
 #define PutWord(reg,value) outw((value), ioaddr+(reg))
 
 /*====== Functions used for debugging =================================*/
-#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
+#if 0 /* reading regs may change system status */
 static void
 PrintRegisters(struct net_device *dev)
 {
@@ -421,9 +385,9 @@ PrintRegisters(struct net_device *dev)
 	    printk("\n");
 	}
 	for (page=0x40 ; page <= 0x5f; page++) {
-	    if (page == 0x43 || (page >= 0x46 && page <= 0x4f)
-		|| (page >= 0x51 && page <=0x5e))
-		continue;
+		if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
+		    (page >= 0x51 && page <=0x5e))
+			continue;
 	    printk(KDBG_XIRC "Register page %2x: ", page);
 	    SelectPage(page);
 	    for (i = 8; i < 16; i++)
@@ -432,7 +396,7 @@ PrintRegisters(struct net_device *dev)
 	}
     }
 }
-#endif /* PCMCIA_DEBUG */
+#endif /* 0 */
 
 /*============== MII Management functions ===============*/
 
@@ -576,7 +540,7 @@ xirc2ps_probe(struct pcmcia_device *link
     struct net_device *dev;
     local_info_t *local;
 
-    DEBUG(0, "attach()\n");
+    dev_dbg(&link->dev, "attach()\n");
 
     /* Allocate the device structure */
     dev = alloc_etherdev(sizeof(local_info_t));
@@ -592,7 +556,6 @@ xirc2ps_probe(struct pcmcia_device *link
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
     link->irq.Handler = xirc2ps_interrupt;
-    link->irq.Instance = dev;
 
     /* Fill in card specific entries */
     dev->netdev_ops = &netdev_ops;
@@ -615,7 +578,7 @@ xirc2ps_detach(struct pcmcia_device *lin
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "detach\n");
 
     if (link->dev_node)
 	unregister_netdev(dev);
@@ -644,17 +607,25 @@ xirc2ps_detach(struct pcmcia_device *lin
  *
  */
 static int
-set_card_type(struct pcmcia_device *link, const void *s)
+set_card_type(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
-  #ifdef PCMCIA_DEBUG
-    unsigned cisrev = ((const unsigned char *)s)[2];
-  #endif
-    unsigned mediaid= ((const unsigned char *)s)[3];
-    unsigned prodid = ((const unsigned char *)s)[4];
+    u8 *buf;
+    unsigned int cisrev, mediaid, prodid;
+    size_t len;
 
-    DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
+    len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
+    if (len < 5) {
+	    dev_err(&link->dev, "invalid CIS -- sorry\n");
+	    return 0;
+    }
+
+    cisrev = buf[2];
+    mediaid = buf[3];
+    prodid = buf[4];
+
+    dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
 	  cisrev, mediaid, prodid);
 
     local->mohawk = 0;
@@ -761,6 +732,26 @@ xirc2ps_config_check(struct pcmcia_devic
 
 }
 
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+			     tuple_t *tuple,
+			     void *priv)
+{
+	struct net_device *dev = priv;
+	int i;
+
+	if (tuple->TupleDataLen != 13)
+		return -EINVAL;
+	if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+		(tuple->TupleData[2] != 6))
+		return -EINVAL;
+	/* another try	(James Lehmer's CE2 version 4.1)*/
+	for (i = 2; i < 6; i++)
+		dev->dev_addr[i] = tuple->TupleData[i+2];
+	return 0;
+};
+
+
 /****************
  * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
  * is received, to configure the PCMCIA socket, and to make the
@@ -772,33 +763,21 @@ xirc2ps_config(struct pcmcia_device * li
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
     unsigned int ioaddr;
-    tuple_t tuple;
-    cisparse_t parse;
-    int err, i;
-    u_char buf[64];
-    cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
+    int err;
+    u8 *buf;
+    size_t len;
 
     local->dingo_ccr = NULL;
 
-    DEBUG(0, "config(0x%p)\n", link);
-
-    /*
-     * This reads the card's CONFIG tuple to find its configuration
-     * registers.
-     */
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
+    dev_dbg(&link->dev, "config\n");
 
     /* Is this a valid	card */
-    tuple.DesiredTuple = CISTPL_MANFID;
-    if ((err=first_tuple(link, &tuple, &parse))) {
+    if (link->has_manf_id == 0) {
 	printk(KNOT_XIRC "manfid not found in CIS\n");
 	goto failure;
     }
 
-    switch(parse.manfid.manf) {
+    switch (link->manf_id) {
       case MANFID_XIRCOM:
 	local->manf_str = "Xircom";
 	break;
@@ -817,65 +796,44 @@ xirc2ps_config(struct pcmcia_device * li
 	break;
       default:
 	printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
-	       (unsigned)parse.manfid.manf);
+	       (unsigned)link->manf_id);
 	goto failure;
     }
-    DEBUG(0, "found %s card\n", local->manf_str);
+    dev_dbg(&link->dev, "found %s card\n", local->manf_str);
 
-    if (!set_card_type(link, buf)) {
+    if (!set_card_type(link)) {
 	printk(KNOT_XIRC "this card is not supported\n");
 	goto failure;
     }
 
     /* get the ethernet address from the CIS */
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    for (err = first_tuple(link, &tuple, &parse); !err;
-			     err = next_tuple(link, &tuple, &parse)) {
-	/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
-	 * the first one with a length of zero the second correct -
-	 * so I skip all entries with length 0 */
-	if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
-	    && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
-	    break;
-    }
-    if (err) { /* not found: try to get the node-id from tuple 0x89 */
-	tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */
-	if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
-		(err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
-	    if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
-		memcpy(&parse, buf, 8);
-	    else
-		err = -1;
-	}
-    }
-    if (err) { /* another try	(James Lehmer's CE2 version 4.1)*/
-	tuple.DesiredTuple = CISTPL_FUNCE;
-	for (err = first_tuple(link, &tuple, &parse); !err;
-				 err = next_tuple(link, &tuple, &parse)) {
-	    if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
-		&& parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
-		buf[1] = 4;
-		memcpy(&parse, buf+1, 8);
-		break;
+    err = pcmcia_get_mac_from_cis(link, dev);
+
+    /* not found: try to get the node-id from tuple 0x89 */
+    if (err) {
+	    len = pcmcia_get_tuple(link, 0x89, &buf);
+	    /* data layout looks like tuple 0x22 */
+	    if (buf && len == 8) {
+		    if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
+			    int i;
+			    for (i = 2; i < 6; i++)
+				    dev->dev_addr[i] = buf[i+2];
+		    } else
+			    err = -1;
 	    }
-	}
+	    kfree(buf);
     }
+
+    if (err)
+	err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
     if (err) {
 	printk(KNOT_XIRC "node-id not found in CIS\n");
 	goto failure;
     }
-    node_id = (cistpl_lan_node_id_t *)parse.funce.data;
-    if (node_id->nb != 6) {
-	printk(KNOT_XIRC "malformed node-id in CIS\n");
-	goto failure;
-    }
-    for (i=0; i < 6; i++)
-	dev->dev_addr[i] = node_id->id[i];
 
     link->io.IOAddrLines =10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     if (local->modem) {
 	int pass;
 
@@ -883,7 +841,7 @@ xirc2ps_config(struct pcmcia_device * li
 	    link->conf.Attributes |= CONF_ENABLE_SPKR;
 	    link->conf.Status |= CCSR_AUDIO_ENA;
 	}
-	link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED ;
+	link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
 	link->io.NumPorts2 = 8;
 	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
 	if (local->dingo) {
@@ -916,10 +874,8 @@ xirc2ps_config(struct pcmcia_device * li
 		goto port_found;
 	}
 	link->io.BasePort1 = 0; /* let CS decide */
-	if ((err=pcmcia_request_io(link, &link->io))) {
-	    cs_error(link, RequestIO, err);
+	if ((err=pcmcia_request_io(link, &link->io)))
 	    goto config_error;
-	}
     }
   port_found:
     if (err)
@@ -929,19 +885,15 @@ xirc2ps_config(struct pcmcia_device * li
      * Now allocate an interrupt line.	Note that this does not
      * actually assign a handler to the interrupt.
      */
-    if ((err=pcmcia_request_irq(link, &link->irq))) {
-	cs_error(link, RequestIRQ, err);
+    if ((err=pcmcia_request_irq(link, &link->irq)))
 	goto config_error;
-    }
 
     /****************
      * This actually configures the PCMCIA socket -- setting up
      * the I/O windows and the interrupt mapping.
      */
-    if ((err=pcmcia_request_configuration(link, &link->conf))) {
-	cs_error(link, RequestConfiguration, err);
+    if ((err=pcmcia_request_configuration(link, &link->conf)))
 	goto config_error;
-    }
 
     if (local->dingo) {
 	conf_reg_t reg;
@@ -956,17 +908,13 @@ xirc2ps_config(struct pcmcia_device * li
 	reg.Action = CS_WRITE;
 	reg.Offset = CISREG_IOBASE_0;
 	reg.Value = link->io.BasePort2 & 0xff;
-	if ((err = pcmcia_access_configuration_register(link, &reg))) {
-	    cs_error(link, AccessConfigurationRegister, err);
+	if ((err = pcmcia_access_configuration_register(link, &reg)))
 	    goto config_error;
-	}
 	reg.Action = CS_WRITE;
 	reg.Offset = CISREG_IOBASE_1;
 	reg.Value = (link->io.BasePort2 >> 8) & 0xff;
-	if ((err = pcmcia_access_configuration_register(link, &reg))) {
-	    cs_error(link, AccessConfigurationRegister, err);
+	if ((err = pcmcia_access_configuration_register(link, &reg)))
 	    goto config_error;
-	}
 
 	/* There is no config entry for the Ethernet part which
 	 * is at 0x0800. So we allocate a window into the attribute
@@ -975,17 +923,14 @@ xirc2ps_config(struct pcmcia_device * li
 	req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
 	req.Base = req.Size = 0;
 	req.AccessSpeed = 0;
-	if ((err = pcmcia_request_window(&link, &req, &link->win))) {
-	    cs_error(link, RequestWindow, err);
+	if ((err = pcmcia_request_window(link, &req, &link->win)))
 	    goto config_error;
-	}
+
 	local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
 	mem.CardOffset = 0x0;
 	mem.Page = 0;
-	if ((err = pcmcia_map_mem_page(link->win, &mem))) {
-	    cs_error(link, MapMemPage, err);
+	if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
 	    goto config_error;
-	}
 
 	/* Setup the CCRs; there are no infos in the CIS about the Ethernet
 	 * part.
@@ -1044,7 +989,7 @@ xirc2ps_config(struct pcmcia_device * li
 	do_reset(dev, 1); /* a kludge to make the cem56 work */
 
     link->dev_node = &local->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if ((err=register_netdev(dev))) {
 	printk(KNOT_XIRC "register_netdev() failed\n");
@@ -1077,7 +1022,7 @@ xirc2ps_config(struct pcmcia_device * li
 static void
 xirc2ps_release(struct pcmcia_device *link)
 {
-	DEBUG(0, "release(0x%p)\n", link);
+	dev_dbg(&link->dev, "release\n");
 
 	if (link->win) {
 		struct net_device *dev = link->priv;
@@ -1144,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	PutByte(XIRCREG_CR, 0);
     }
 
-    DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
+    pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
 
     saved_page = GetByte(XIRCREG_PR);
     /* Read the ISR to see whats the cause for the interrupt.
@@ -1154,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     bytes_rcvd = 0;
   loop_entry:
     if (int_status == 0xff) { /* card may be ejected */
-	DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
+	pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
 	goto leave;
     }
     eth_status = GetByte(XIRCREG_ESR);
@@ -1167,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     PutByte(XIRCREG40_TXST0, 0);
     PutByte(XIRCREG40_TXST1, 0);
 
-    DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
+    pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
 	  dev->name, int_status, eth_status, rx_status, tx_status);
 
     /***** receive section ******/
@@ -1178,14 +1123,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	    /* too many bytes received during this int, drop the rest of the
 	     * packets */
 	    dev->stats.rx_dropped++;
-	    DEBUG(2, "%s: RX drop, too much done\n", dev->name);
+	    pr_debug("%s: RX drop, too much done\n", dev->name);
 	} else if (rsr & PktRxOk) {
 	    struct sk_buff *skb;
 
 	    pktlen = GetWord(XIRCREG0_RBC);
 	    bytes_rcvd += pktlen;
 
-	    DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
+	    pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
 
 	    skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
 	    if (!skb) {
@@ -1253,19 +1198,19 @@ xirc2ps_interrupt(int irq, void *dev_id)
 		    dev->stats.multicast++;
 	    }
 	} else { /* bad packet */
-	    DEBUG(5, "rsr=%#02x\n", rsr);
+	    pr_debug("rsr=%#02x\n", rsr);
 	}
 	if (rsr & PktTooLong) {
 	    dev->stats.rx_frame_errors++;
-	    DEBUG(3, "%s: Packet too long\n", dev->name);
+	    pr_debug("%s: Packet too long\n", dev->name);
 	}
 	if (rsr & CRCErr) {
 	    dev->stats.rx_crc_errors++;
-	    DEBUG(3, "%s: CRC error\n", dev->name);
+	    pr_debug("%s: CRC error\n", dev->name);
 	}
 	if (rsr & AlignErr) {
 	    dev->stats.rx_fifo_errors++; /* okay ? */
-	    DEBUG(3, "%s: Alignment error\n", dev->name);
+	    pr_debug("%s: Alignment error\n", dev->name);
 	}
 
 	/* clear the received/dropped/error packet */
@@ -1277,7 +1222,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     if (rx_status & 0x10) { /* Receive overrun */
 	dev->stats.rx_over_errors++;
 	PutByte(XIRCREG_CR, ClearRxOvrun);
-	DEBUG(3, "receive overrun cleared\n");
+	pr_debug("receive overrun cleared\n");
     }
 
     /***** transmit section ******/
@@ -1290,13 +1235,13 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	if (nn < n) /* rollover */
 	    dev->stats.tx_packets += 256 - n;
 	else if (n == nn) { /* happens sometimes - don't know why */
-	    DEBUG(0, "PTR not changed?\n");
+	    pr_debug("PTR not changed?\n");
 	} else
 	    dev->stats.tx_packets += lp->last_ptr_value - n;
 	netif_wake_queue(dev);
     }
     if (tx_status & 0x0002) {	/* Execessive collissions */
-	DEBUG(0, "tx restarted due to execssive collissions\n");
+	pr_debug("tx restarted due to execssive collissions\n");
 	PutByte(XIRCREG_CR, RestartTx);  /* restart transmitter process */
     }
     if (tx_status & 0x0040)
@@ -1315,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
 		maxrx_bytes = 2000;
 	    else if (maxrx_bytes > 22000)
 		maxrx_bytes = 22000;
-	    DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
+	    pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
 		  maxrx_bytes, bytes_rcvd, duration);
 	} else if (!duration && maxrx_bytes < 22000) {
 	    /* now much faster */
 	    maxrx_bytes += 2000;
 	    if (maxrx_bytes > 22000)
 		maxrx_bytes = 22000;
-	    DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
+	    pr_debug("set maxrx=%u\n", maxrx_bytes);
 	}
     }
 
@@ -1372,7 +1317,7 @@ do_start_xmit(struct sk_buff *skb, struc
     unsigned freespace;
     unsigned pktlen = skb->len;
 
-    DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
+    pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
 	  skb, dev, pktlen);
 
 
@@ -1398,7 +1343,7 @@ do_start_xmit(struct sk_buff *skb, struc
     freespace &= 0x7fff;
     /* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
     okay = pktlen +2 < freespace;
-    DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
+    pr_debug("%s: avail. tx space=%u%s\n",
 	  dev->name, freespace, okay ? " (okay)":" (not enough)");
     if (!okay) { /* not enough space */
 	return NETDEV_TX_BUSY;  /* upper layer may decide to requeue this packet */
@@ -1500,7 +1445,7 @@ do_config(struct net_device *dev, struct
 {
     local_info_t *local = netdev_priv(dev);
 
-    DEBUG(0, "do_config(%p)\n", dev);
+    pr_debug("do_config(%p)\n", dev);
     if (map->port != 255 && map->port != dev->if_port) {
 	if (map->port > 4)
 	    return -EINVAL;
@@ -1527,7 +1472,7 @@ do_open(struct net_device *dev)
     local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_open(%p)\n", dev);
+    dev_dbg(&link->dev, "do_open(%p)\n", dev);
 
     /* Check that the PCMCIA card is still here. */
     /* Physical device present signature. */
@@ -1561,7 +1506,7 @@ do_ioctl(struct net_device *dev, struct
     unsigned int ioaddr = dev->base_addr;
     struct mii_ioctl_data *data = if_mii(rq);
 
-    DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
+    pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
 	  dev->name, rq->ifr_ifrn.ifrn_name, cmd,
 	  data->phy_id, data->reg_num, data->val_in, data->val_out);
 
@@ -1610,7 +1555,7 @@ do_reset(struct net_device *dev, int ful
     unsigned int ioaddr = dev->base_addr;
     unsigned value;
 
-    DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
+    pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
 
     hardreset(dev);
     PutByte(XIRCREG_CR, SoftReset); /* set */
@@ -1648,8 +1593,8 @@ do_reset(struct net_device *dev, int ful
     }
     msleep(40);			     /* wait 40 msec to let it complete */
 
-  #ifdef PCMCIA_DEBUG
-    if (pc_debug) {
+  #if 0
+    {
 	SelectPage(0);
 	value = GetByte(XIRCREG_ESR);	 /* read the ESR */
 	printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
@@ -1666,7 +1611,7 @@ do_reset(struct net_device *dev, int ful
 	value |= DisableLinkPulse;
     PutByte(XIRCREG1_ECR, value);
   #endif
-    DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
+    pr_debug("%s: ECR is: %#02x\n", dev->name, value);
 
     SelectPage(0x42);
     PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
@@ -1844,7 +1789,7 @@ do_powerdown(struct net_device *dev)
 
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "do_powerdown(%p)\n", dev);
+    pr_debug("do_powerdown(%p)\n", dev);
 
     SelectPage(4);
     PutByte(XIRCREG4_GPR1, 0);	     /* clear bit 0: power down */
@@ -1858,7 +1803,7 @@ do_stop(struct net_device *dev)
     local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_stop(%p)\n", dev);
+    dev_dbg(&link->dev, "do_stop(%p)\n", dev);
 
     if (!link)
 	return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pcnet32.c linux-libre-2.6.33-gnu1/drivers/net/pcnet32.c
--- linux-libre-2.6.32-gnu1/drivers/net/pcnet32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pcnet32.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,6 +45,7 @@ static const char *const version =
 #include <linux/crc32.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_ether.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/moduleparam.h>
@@ -1515,8 +1516,8 @@ static void __devinit pcnet32_probe_vlbu
 		if (request_region
 		    (ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) {
 			/* check if there is really a pcnet chip on that ioaddr */
-			if ((inb(ioaddr + 14) == 0x57)
-			    && (inb(ioaddr + 15) == 0x57)) {
+			if ((inb(ioaddr + 14) == 0x57) &&
+			    (inb(ioaddr + 15) == 0x57)) {
 				pcnet32_probe1(ioaddr, 0, NULL);
 			} else {
 				release_region(ioaddr, PCNET32_TOTAL_SIZE);
@@ -1610,8 +1611,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 		a = &pcnet32_wio;
 	} else {
 		pcnet32_dwio_reset(ioaddr);
-		if (pcnet32_dwio_read_csr(ioaddr, 0) == 4
-		    && pcnet32_dwio_check(ioaddr)) {
+		if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 &&
+		    pcnet32_dwio_check(ioaddr)) {
 			a = &pcnet32_dwio;
 		} else {
 			if (pcnet32_debug & NETIF_MSG_PROBE)
@@ -1750,8 +1751,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 	for (i = 0; i < 6; i++)
 		promaddr[i] = inb(ioaddr + i);
 
-	if (memcmp(promaddr, dev->dev_addr, 6)
-	    || !is_valid_ether_addr(dev->dev_addr)) {
+	if (memcmp(promaddr, dev->dev_addr, 6) ||
+	    !is_valid_ether_addr(dev->dev_addr)) {
 		if (is_valid_ether_addr(promaddr)) {
 			if (pcnet32_debug & NETIF_MSG_PROBE) {
 				printk(" warning: CSR address invalid,\n");
@@ -1765,7 +1766,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 
 	/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
 	if (!is_valid_ether_addr(dev->perm_addr))
-		memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+		memset(dev->dev_addr, 0, ETH_ALEN);
 
 	if (pcnet32_debug & NETIF_MSG_PROBE) {
 		printk(" %pM", dev->dev_addr);
@@ -1840,8 +1841,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 	lp->mii = mii;
 	lp->chip_version = chip_version;
 	lp->msg_enable = pcnet32_debug;
-	if ((cards_found >= MAX_UNITS)
-	    || (options[cards_found] >= sizeof(options_mapping)))
+	if ((cards_found >= MAX_UNITS) ||
+	    (options[cards_found] >= sizeof(options_mapping)))
 		lp->options = PCNET32_PORT_ASEL;
 	else
 		lp->options = options_mapping[options[cards_found]];
@@ -1866,8 +1867,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 		goto err_free_ring;
 	}
 	/* detect special T1/E1 WAN card by checking for MAC address */
-	if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
-	    && dev->dev_addr[2] == 0x75)
+	if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 &&
+	    dev->dev_addr[2] == 0x75)
 		lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
 
 	lp->init_block->mode = cpu_to_le16(0x0003);	/* Disable Rx and Tx. */
@@ -2095,7 +2096,7 @@ static int pcnet32_open(struct net_devic
 	int rc;
 	unsigned long flags;
 
-	if (request_irq(dev->irq, &pcnet32_interrupt,
+	if (request_irq(dev->irq, pcnet32_interrupt,
 			lp->shared_irq ? IRQF_SHARED : 0, dev->name,
 			(void *)dev)) {
 		return -EAGAIN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/broadcom.c linux-libre-2.6.33-gnu1/drivers/net/phy/broadcom.c
--- linux-libre-2.6.32-gnu1/drivers/net/phy/broadcom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/broadcom.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/phy.h>
+#include <linux/brcmphy.h>
 
 #define PHY_ID_BCM50610		0x0143bd60
 #define PHY_ID_BCM50610M	0x0143bd70
@@ -24,6 +25,9 @@
 #define BRCM_PHY_MODEL(phydev) \
 	((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
 
+#define BRCM_PHY_REV(phydev) \
+	((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
+
 
 #define MII_BCM54XX_ECR		0x10	/* BCM54xx extended control register */
 #define MII_BCM54XX_ECR_IM	0x1000	/* Interrupt mask */
@@ -94,22 +98,35 @@
 #define BCM_LED_SRC_OFF		0xe	/* Tied high */
 #define BCM_LED_SRC_ON		0xf	/* Tied low */
 
+
 /*
  * BCM5482: Shadow registers
  * Shadow values go into bits [14:10] of register 0x1c to select a shadow
  * register to access.
  */
+/* 00101: Spare Control Register 3 */
+#define BCM54XX_SHD_SCR3		0x05
+#define  BCM54XX_SHD_SCR3_DEF_CLK125	0x0001
+#define  BCM54XX_SHD_SCR3_DLLAPD_DIS	0x0002
+#define  BCM54XX_SHD_SCR3_TRDDAPD	0x0004
+
+/* 01010: Auto Power-Down */
+#define BCM54XX_SHD_APD			0x0a
+#define  BCM54XX_SHD_APD_EN		0x0020
+
 #define BCM5482_SHD_LEDS1	0x0d	/* 01101: LED Selector 1 */
 					/* LED3 / ~LINKSPD[2] selector */
 #define BCM5482_SHD_LEDS1_LED3(src)	((src & 0xf) << 4)
 					/* LED1 / ~LINKSPD[1] selector */
 #define BCM5482_SHD_LEDS1_LED1(src)	((src & 0xf) << 0)
+#define BCM54XX_SHD_RGMII_MODE	0x0b	/* 01011: RGMII Mode Selector */
 #define BCM5482_SHD_SSD		0x14	/* 10100: Secondary SerDes control */
 #define BCM5482_SHD_SSD_LEDM	0x0008	/* SSD LED Mode enable */
 #define BCM5482_SHD_SSD_EN	0x0001	/* SSD enable */
 #define BCM5482_SHD_MODE	0x1f	/* 11111: Mode Control Register */
 #define BCM5482_SHD_MODE_1000BX	0x0001	/* Enable 1000BASE-X registers */
 
+
 /*
  * EXPANSION SHADOW ACCESS REGISTERS.  (PHY REG 0x15, 0x16, and 0x17)
  */
@@ -138,16 +155,6 @@
 #define BCM5482_SSD_SGMII_SLAVE_EN	0x0002	/* Slave mode enable */
 #define BCM5482_SSD_SGMII_SLAVE_AD	0x0001	/* Slave auto-detection */
 
-/*
- * Device flags for PHYs that can be configured for different operating
- * modes.
- */
-#define PHY_BCM_FLAGS_VALID		0x80000000
-#define PHY_BCM_FLAGS_INTF_XAUI		0x00000020
-#define PHY_BCM_FLAGS_INTF_SGMII	0x00000010
-#define PHY_BCM_FLAGS_MODE_1000BX	0x00000002
-#define PHY_BCM_FLAGS_MODE_COPPER	0x00000001
-
 
 /*****************************************************************************/
 /* Fast Ethernet Transceiver definitions. */
@@ -237,53 +244,146 @@ static int bcm54xx_auxctl_write(struct p
 	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
 }
 
+/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
 static int bcm50610_a0_workaround(struct phy_device *phydev)
 {
 	int err;
 
-	err = bcm54xx_auxctl_write(phydev,
-				   MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
-				   MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
-				   MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
-	if (err < 0)
-		return err;
-
-	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
-				MII_BCM54XX_EXP_EXP08_RJCT_2MHZ	|
-				MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE);
-	if (err < 0)
-		goto error;
-
 	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0,
 				MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
 				MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
 	if (err < 0)
-		goto error;
+		return err;
 
 	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3,
 					MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
 	if (err < 0)
-		goto error;
+		return err;
 
 	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75,
 				MII_BCM54XX_EXP_EXP75_VDACCTRL);
 	if (err < 0)
-		goto error;
+		return err;
 
 	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96,
 				MII_BCM54XX_EXP_EXP96_MYST);
 	if (err < 0)
-		goto error;
+		return err;
 
 	err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97,
 				MII_BCM54XX_EXP_EXP97_MYST);
 
+	return err;
+}
+
+static int bcm54xx_phydsp_config(struct phy_device *phydev)
+{
+	int err, err2;
+
+	/* Enable the SMDSP clock */
+	err = bcm54xx_auxctl_write(phydev,
+				   MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+				   MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
+				   MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+	if (err < 0)
+		return err;
+
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
+	    BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) {
+		/* Clear bit 9 to fix a phy interop issue. */
+		err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
+					MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
+		if (err < 0)
+			goto error;
+
+		if (phydev->drv->phy_id == PHY_ID_BCM50610) {
+			err = bcm50610_a0_workaround(phydev);
+			if (err < 0)
+				goto error;
+		}
+	}
+
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
+		int val;
+
+		val = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
+		if (val < 0)
+			goto error;
+
+		val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
+		err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, val);
+	}
+
 error:
-	bcm54xx_auxctl_write(phydev,
-			     MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
-			     MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+	/* Disable the SMDSP clock */
+	err2 = bcm54xx_auxctl_write(phydev,
+				    MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+				    MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
 
-	return err;
+	/* Return the first error reported. */
+	return err ? err : err2;
+}
+
+static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
+{
+	u32 orig;
+	int val;
+	bool clk125en = true;
+
+	/* Abort if we are using an untested phy. */
+	if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
+	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
+	    BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
+		return;
+
+	val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3);
+	if (val < 0)
+		return;
+
+	orig = val;
+
+	if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
+	     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
+	    BRCM_PHY_REV(phydev) >= 0x3) {
+		/*
+		 * Here, bit 0 _disables_ CLK125 when set.
+		 * This bit is set by default.
+		 */
+		clk125en = false;
+	} else {
+		if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
+			/* Here, bit 0 _enables_ CLK125 when set */
+			val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
+			clk125en = false;
+		}
+	}
+
+	if (clk125en == false ||
+	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+		val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
+	else
+		val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
+
+	if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY)
+		val |= BCM54XX_SHD_SCR3_TRDDAPD;
+
+	if (orig != val)
+		bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val);
+
+	val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD);
+	if (val < 0)
+		return;
+
+	orig = val;
+
+	if (clk125en == false ||
+	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+		val |= BCM54XX_SHD_APD_EN;
+	else
+		val &= ~BCM54XX_SHD_APD_EN;
+
+	if (orig != val)
+		bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val);
 }
 
 static int bcm54xx_config_init(struct phy_device *phydev)
@@ -308,38 +408,17 @@ static int bcm54xx_config_init(struct ph
 	if (err < 0)
 		return err;
 
-	if (phydev->drv->phy_id == PHY_ID_BCM50610) {
-		err = bcm50610_a0_workaround(phydev);
-		if (err < 0)
-			return err;
-	}
-
-	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
-		int err2;
-
-		err = bcm54xx_auxctl_write(phydev,
-					   MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
-					   MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
-					   MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
-		if (err < 0)
-			return err;
-
-		reg = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
-		if (reg < 0)
-			goto error;
+	if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
+	     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
+	    (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
+		bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0);
 
-		reg |= MII_BCM54XX_EXP_EXP75_CM_OSC;
-		err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, reg);
+	if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
+	    (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
+	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+		bcm54xx_adjust_rxrefclk(phydev);
 
-error:
-		err2 = bcm54xx_auxctl_write(phydev,
-					    MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
-					    MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
-		if (err)
-			return err;
-		if (err2)
-			return err2;
-	}
+	bcm54xx_phydsp_config(phydev);
 
 	return 0;
 }
@@ -564,9 +643,11 @@ static int brcm_fet_config_init(struct p
 	if (err < 0)
 		goto done;
 
-	/* Enable auto power down */
-	err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
-				       MII_BRCM_FET_SHDW_AS2_APDE);
+	if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
+		/* Enable auto power down */
+		err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
+					       MII_BRCM_FET_SHDW_AS2_APDE);
+	}
 
 done:
 	/* Disable shadow register access */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/Kconfig linux-libre-2.6.33-gnu1/drivers/net/phy/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/phy/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -115,4 +115,15 @@ config MDIO_GPIO
 	  To compile this driver as a module, choose M here: the module
 	  will be called mdio-gpio.
 
+config MDIO_OCTEON
+	tristate "Support for MDIO buses on Octeon SOCs"
+	depends on  CPU_CAVIUM_OCTEON
+	default y
+	help
+
+	  This module provides a driver for the Octeon MDIO busses.
+	  It is required by the Octeon Ethernet device drivers.
+
+	  If in doubt, say Y.
+
 endif # PHYLIB
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/Makefile linux-libre-2.6.33-gnu1/drivers/net/phy/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/phy/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -20,3 +20,4 @@ obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitba
 obj-$(CONFIG_MDIO_GPIO)		+= mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)	+= national.o
 obj-$(CONFIG_STE10XP)		+= ste10Xp.o
+obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/mdio_bus.c linux-libre-2.6.33-gnu1/drivers/net/phy/mdio_bus.c
--- linux-libre-2.6.32-gnu1/drivers/net/phy/mdio_bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/mdio_bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -264,6 +264,8 @@ static int mdio_bus_match(struct device
 		(phydev->phy_id & phydrv->phy_id_mask));
 }
 
+#ifdef CONFIG_PM
+
 static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 {
 	struct device_driver *drv = phydev->dev.driver;
@@ -295,34 +297,88 @@ static bool mdio_bus_phy_may_suspend(str
 	return true;
 }
 
-/* Suspend and resume.  Copied from platform_suspend and
- * platform_resume
- */
-static int mdio_bus_suspend(struct device * dev, pm_message_t state)
+static int mdio_bus_suspend(struct device *dev)
 {
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
 
+	/*
+	 * We must stop the state machine manually, otherwise it stops out of
+	 * control, possibly with the phydev->lock held. Upon resume, netdev
+	 * may call phy routines that try to grab the same lock, and that may
+	 * lead to a deadlock.
+	 */
+	if (phydev->attached_dev)
+		phy_stop_machine(phydev);
+
 	if (!mdio_bus_phy_may_suspend(phydev))
 		return 0;
+
 	return phydrv->suspend(phydev);
 }
 
-static int mdio_bus_resume(struct device * dev)
+static int mdio_bus_resume(struct device *dev)
 {
 	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
+	int ret;
 
 	if (!mdio_bus_phy_may_suspend(phydev))
+		goto no_resume;
+
+	ret = phydrv->resume(phydev);
+	if (ret < 0)
+		return ret;
+
+no_resume:
+	if (phydev->attached_dev)
+		phy_start_machine(phydev, NULL);
+
+	return 0;
+}
+
+static int mdio_bus_restore(struct device *dev)
+{
+	struct phy_device *phydev = to_phy_device(dev);
+	struct net_device *netdev = phydev->attached_dev;
+	int ret;
+
+	if (!netdev)
 		return 0;
-	return phydrv->resume(phydev);
+
+	ret = phy_init_hw(phydev);
+	if (ret < 0)
+		return ret;
+
+	/* The PHY needs to renegotiate. */
+	phydev->link = 0;
+	phydev->state = PHY_UP;
+
+	phy_start_machine(phydev, NULL);
+
+	return 0;
 }
 
+static struct dev_pm_ops mdio_bus_pm_ops = {
+	.suspend = mdio_bus_suspend,
+	.resume = mdio_bus_resume,
+	.freeze = mdio_bus_suspend,
+	.thaw = mdio_bus_resume,
+	.restore = mdio_bus_restore,
+};
+
+#define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops)
+
+#else
+
+#define MDIO_BUS_PM_OPS NULL
+
+#endif /* CONFIG_PM */
+
 struct bus_type mdio_bus_type = {
 	.name		= "mdio_bus",
 	.match		= mdio_bus_match,
-	.suspend	= mdio_bus_suspend,
-	.resume		= mdio_bus_resume,
+	.pm		= MDIO_BUS_PM_OPS,
 };
 EXPORT_SYMBOL(mdio_bus_type);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/mdio-octeon.c linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-octeon.c
--- linux-libre-2.6.32-gnu1/drivers/net/phy/mdio-octeon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/mdio-octeon.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,180 @@
+/*
+ * 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) 2009 Cavium Networks
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-smix-defs.h>
+
+#define DRV_VERSION "1.0"
+#define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver"
+
+struct octeon_mdiobus {
+	struct mii_bus *mii_bus;
+	int unit;
+	int phy_irq[PHY_MAX_ADDR];
+};
+
+static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+	struct octeon_mdiobus *p = bus->priv;
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_rd_dat smi_rd;
+	int timeout = 1000;
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = regnum;
+	cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+
+	do {
+		/*
+		 * Wait 1000 clocks so we don't saturate the RSL bus
+		 * doing reads.
+		 */
+		cvmx_wait(1000);
+		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit));
+	} while (smi_rd.s.pending && --timeout);
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else
+		return -EIO;
+}
+
+static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
+				int regnum, u16 val)
+{
+	struct octeon_mdiobus *p = bus->priv;
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+	int timeout = 1000;
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = regnum;
+	cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+
+	do {
+		/*
+		 * Wait 1000 clocks so we don't saturate the RSL bus
+		 * doing reads.
+		 */
+		cvmx_wait(1000);
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit));
+	} while (smi_wr.s.pending && --timeout);
+
+	if (timeout <= 0)
+		return -EIO;
+
+	return 0;
+}
+
+static int __init octeon_mdiobus_probe(struct platform_device *pdev)
+{
+	struct octeon_mdiobus *bus;
+	int i;
+	int err = -ENOENT;
+
+	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return -ENOMEM;
+
+	/* The platform_device id is our unit number.  */
+	bus->unit = pdev->id;
+
+	bus->mii_bus = mdiobus_alloc();
+
+	if (!bus->mii_bus)
+		goto err;
+
+	/*
+	 * Standard Octeon evaluation boards don't support phy
+	 * interrupts, we need to poll.
+	 */
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		bus->phy_irq[i] = PHY_POLL;
+
+	bus->mii_bus->priv = bus;
+	bus->mii_bus->irq = bus->phy_irq;
+	bus->mii_bus->name = "mdio-octeon";
+	snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit);
+	bus->mii_bus->parent = &pdev->dev;
+
+	bus->mii_bus->read = octeon_mdiobus_read;
+	bus->mii_bus->write = octeon_mdiobus_write;
+
+	dev_set_drvdata(&pdev->dev, bus);
+
+	err = mdiobus_register(bus->mii_bus);
+	if (err)
+		goto err_register;
+
+	dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
+
+	return 0;
+err_register:
+	mdiobus_free(bus->mii_bus);
+
+err:
+	devm_kfree(&pdev->dev, bus);
+	return err;
+}
+
+static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
+{
+	struct octeon_mdiobus *bus;
+
+	bus = dev_get_drvdata(&pdev->dev);
+
+	mdiobus_unregister(bus->mii_bus);
+	mdiobus_free(bus->mii_bus);
+	return 0;
+}
+
+static struct platform_driver octeon_mdiobus_driver = {
+	.driver = {
+		.name		= "mdio-octeon",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= octeon_mdiobus_probe,
+	.remove		= __exit_p(octeon_mdiobus_remove),
+};
+
+void octeon_mdiobus_force_mod_depencency(void)
+{
+	/* Let ethernet drivers force us to be loaded.  */
+}
+EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency);
+
+static int __init octeon_mdiobus_mod_init(void)
+{
+	return platform_driver_register(&octeon_mdiobus_driver);
+}
+
+static void __exit octeon_mdiobus_mod_exit(void)
+{
+	platform_driver_unregister(&octeon_mdiobus_driver);
+}
+
+module_init(octeon_mdiobus_mod_init);
+module_exit(octeon_mdiobus_mod_exit);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/phy.c linux-libre-2.6.33-gnu1/drivers/net/phy/phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/phy/phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -254,12 +254,12 @@ int phy_ethtool_sset(struct phy_device *
 	if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
 		return -EINVAL;
 
-	if (cmd->autoneg == AUTONEG_DISABLE
-			&& ((cmd->speed != SPEED_1000
-					&& cmd->speed != SPEED_100
-					&& cmd->speed != SPEED_10)
-				|| (cmd->duplex != DUPLEX_HALF
-					&& cmd->duplex != DUPLEX_FULL)))
+	if (cmd->autoneg == AUTONEG_DISABLE &&
+	    ((cmd->speed != SPEED_1000 &&
+	      cmd->speed != SPEED_100 &&
+	      cmd->speed != SPEED_10) ||
+	     (cmd->duplex != DUPLEX_HALF &&
+	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
 
 	phydev->autoneg = cmd->autoneg;
@@ -353,9 +353,9 @@ int phy_mii_ioctl(struct phy_device *phy
 
 		phy_write(phydev, mii_data->reg_num, val);
 		
-		if (mii_data->reg_num == MII_BMCR 
-				&& val & BMCR_RESET
-				&& phydev->drv->config_init) {
+		if (mii_data->reg_num == MII_BMCR &&
+		    val & BMCR_RESET &&
+		    phydev->drv->config_init) {
 			phy_scan_fixups(phydev);
 			phydev->drv->config_init(phydev);
 		}
@@ -410,7 +410,6 @@ EXPORT_SYMBOL(phy_start_aneg);
 
 
 static void phy_change(struct work_struct *work);
-static void phy_state_machine(struct work_struct *work);
 
 /**
  * phy_start_machine - start PHY state machine tracking
@@ -430,7 +429,6 @@ void phy_start_machine(struct phy_device
 {
 	phydev->adjust_state = handler;
 
-	INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
 	schedule_delayed_work(&phydev->state_queue, HZ);
 }
 
@@ -761,7 +759,7 @@ EXPORT_SYMBOL(phy_start);
  * phy_state_machine - Handle the state machine
  * @work: work_struct that describes the work to be done
  */
-static void phy_state_machine(struct work_struct *work)
+void phy_state_machine(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct phy_device *phydev =
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/phy/phy_device.c linux-libre-2.6.33-gnu1/drivers/net/phy/phy_device.c
--- linux-libre-2.6.32-gnu1/drivers/net/phy/phy_device.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/phy/phy_device.c	2010-02-24 13:52:17.000000000 -0500
@@ -177,6 +177,7 @@ struct phy_device* phy_device_create(str
 	dev->state = PHY_DOWN;
 
 	mutex_init(&dev->lock);
+	INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
 
 	return dev;
 }
@@ -378,6 +379,20 @@ void phy_disconnect(struct phy_device *p
 }
 EXPORT_SYMBOL(phy_disconnect);
 
+int phy_init_hw(struct phy_device *phydev)
+{
+	int ret;
+
+	if (!phydev->drv || !phydev->drv->config_init)
+		return 0;
+
+	ret = phy_scan_fixups(phydev);
+	if (ret < 0)
+		return ret;
+
+	return phydev->drv->config_init(phydev);
+}
+
 /**
  * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
@@ -425,21 +440,7 @@ int phy_attach_direct(struct net_device
 	/* Do initial configuration here, now that
 	 * we have certain key parameters
 	 * (dev_flags and interface) */
-	if (phydev->drv->config_init) {
-		int err;
-
-		err = phy_scan_fixups(phydev);
-
-		if (err < 0)
-			return err;
-
-		err = phydev->drv->config_init(phydev);
-
-		if (err < 0)
-			return err;
-	}
-
-	return 0;
+	return phy_init_hw(phydev);
 }
 EXPORT_SYMBOL(phy_attach_direct);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/plip.c linux-libre-2.6.33-gnu1/drivers/net/plip.c
--- linux-libre-2.6.32-gnu1/drivers/net/plip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/plip.c	2010-02-24 13:52:17.000000000 -0500
@@ -372,8 +372,8 @@ plip_bh(struct work_struct *work)
 
 	nl->is_deferred = 0;
 	f = connection_state_table[nl->connection];
-	if ((r = (*f)(nl->dev, nl, snd, rcv)) != OK
-	    && (r = plip_bh_timeout_error(nl->dev, nl, snd, rcv, r)) != OK) {
+	if ((r = (*f)(nl->dev, nl, snd, rcv)) != OK &&
+	    (r = plip_bh_timeout_error(nl->dev, nl, snd, rcv, r)) != OK) {
 		nl->is_deferred = 1;
 		schedule_delayed_work(&nl->deferred, 1);
 	}
@@ -416,9 +416,8 @@ plip_bh_timeout_error(struct net_device
 
 		if (error != ERROR) { /* Timeout */
 			nl->timeout_count++;
-			if ((error == HS_TIMEOUT
-			     && nl->timeout_count <= 10)
-			    || nl->timeout_count <= 3) {
+			if ((error == HS_TIMEOUT && nl->timeout_count <= 10) ||
+			    nl->timeout_count <= 3) {
 				spin_unlock_irq(&nl->lock);
 				/* Try again later */
 				return TIMEOUT;
@@ -624,8 +623,8 @@ plip_receive_packet(struct net_device *d
 		if (plip_receive(nibble_timeout, dev,
 				 &rcv->nibble, &rcv->length.b.msb))
 			return TIMEOUT;
-		if (rcv->length.h > dev->mtu + dev->hard_header_len
-		    || rcv->length.h < 8) {
+		if (rcv->length.h > dev->mtu + dev->hard_header_len ||
+		    rcv->length.h < 8) {
 			printk(KERN_WARNING "%s: bogus packet size %d.\n", dev->name, rcv->length.h);
 			return ERROR;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ppp_async.c linux-libre-2.6.33-gnu1/drivers/net/ppp_async.c
--- linux-libre-2.6.32-gnu1/drivers/net/ppp_async.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ppp_async.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,7 +36,7 @@
 
 #define PPP_VERSION	"2.4.2"
 
-#define OBUFSIZE	256
+#define OBUFSIZE	4096
 
 /* Structure for storing local state. */
 struct asyncppp {
@@ -337,10 +337,7 @@ ppp_asynctty_poll(struct tty_struct *tty
 	return 0;
 }
 
-/*
- * This can now be called from hard interrupt level as well
- * as soft interrupt level or mainline.
- */
+/* May sleep, don't call from interrupt level or with interrupts disabled */
 static void
 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
 		  char *cflags, int count)
@@ -561,8 +558,8 @@ ppp_async_encode(struct asyncppp *ap)
 		 * Start of a new packet - insert the leading FLAG
 		 * character if necessary.
 		 */
-		if (islcp || flag_time == 0
-		    || time_after_eq(jiffies, ap->last_xmit + flag_time))
+		if (islcp || flag_time == 0 ||
+		    time_after_eq(jiffies, ap->last_xmit + flag_time))
 			*buf++ = PPP_FLAG;
 		ap->last_xmit = jiffies;
 		fcs = PPP_INITFCS;
@@ -699,8 +696,8 @@ ppp_async_push(struct asyncppp *ap)
 		 */
 		clear_bit(XMIT_BUSY, &ap->xmit_flags);
 		/* any more work to do? if not, exit the loop */
-		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-		      || (!tty_stuffed && ap->tpkt)))
+		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) ||
+		      (!tty_stuffed && ap->tpkt)))
 			break;
 		/* more work to do, see if we can do it now */
 		if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
@@ -757,8 +754,8 @@ scan_ordinary(struct asyncppp *ap, const
 
 	for (i = 0; i < count; ++i) {
 		c = buf[i];
-		if (c == PPP_ESCAPE || c == PPP_FLAG
-		    || (c < 0x20 && (ap->raccm & (1 << c)) != 0))
+		if (c == PPP_ESCAPE || c == PPP_FLAG ||
+		    (c < 0x20 && (ap->raccm & (1 << c)) != 0))
 			break;
 	}
 	return i;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ppp_deflate.c linux-libre-2.6.33-gnu1/drivers/net/ppp_deflate.c
--- linux-libre-2.6.32-gnu1/drivers/net/ppp_deflate.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ppp_deflate.c	2010-02-24 13:52:17.000000000 -0500
@@ -111,11 +111,11 @@ static void *z_comp_alloc(unsigned char
 	struct ppp_deflate_state *state;
 	int w_size;
 
-	if (opt_len != CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
+	if (opt_len != CILEN_DEFLATE ||
+	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
+	    options[1] != CILEN_DEFLATE ||
+	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
+	    options[3] != DEFLATE_CHK_SEQUENCE)
 		return NULL;
 	w_size = DEFLATE_SIZE(options[2]);
 	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
@@ -163,12 +163,12 @@ static int z_comp_init(void *arg, unsign
 {
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
-	if (opt_len < CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || DEFLATE_SIZE(options[2]) != state->w_size
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
+	if (opt_len < CILEN_DEFLATE ||
+	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
+	    options[1] != CILEN_DEFLATE ||
+	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
+	    DEFLATE_SIZE(options[2]) != state->w_size ||
+	    options[3] != DEFLATE_CHK_SEQUENCE)
 		return 0;
 
 	state->seqno = 0;
@@ -330,11 +330,11 @@ static void *z_decomp_alloc(unsigned cha
 	struct ppp_deflate_state *state;
 	int w_size;
 
-	if (opt_len != CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
+	if (opt_len != CILEN_DEFLATE ||
+	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
+	    options[1] != CILEN_DEFLATE ||
+	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
+	    options[3] != DEFLATE_CHK_SEQUENCE)
 		return NULL;
 	w_size = DEFLATE_SIZE(options[2]);
 	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
@@ -381,12 +381,12 @@ static int z_decomp_init(void *arg, unsi
 {
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
-	if (opt_len < CILEN_DEFLATE
-	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
-	    || options[1] != CILEN_DEFLATE
-	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
-	    || DEFLATE_SIZE(options[2]) != state->w_size
-	    || options[3] != DEFLATE_CHK_SEQUENCE)
+	if (opt_len < CILEN_DEFLATE ||
+	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
+	    options[1] != CILEN_DEFLATE ||
+	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
+	    DEFLATE_SIZE(options[2]) != state->w_size ||
+	    options[3] != DEFLATE_CHK_SEQUENCE)
 		return 0;
 
 	state->seqno = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ppp_generic.c linux-libre-2.6.33-gnu1/drivers/net/ppp_generic.c
--- linux-libre-2.6.32-gnu1/drivers/net/ppp_generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ppp_generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -184,7 +184,7 @@ static atomic_t ppp_unit_count = ATOMIC_
 static atomic_t channel_count = ATOMIC_INIT(0);
 
 /* per-net private data for this module */
-static int ppp_net_id;
+static int ppp_net_id __read_mostly;
 struct ppp_net {
 	/* units to ppp mapping */
 	struct idr units_idr;
@@ -425,8 +425,8 @@ static ssize_t ppp_read(struct file *fil
 			 * network traffic (demand mode).
 			 */
 			struct ppp *ppp = PF_TO_PPP(pf);
-			if (ppp->n_channels == 0
-			    && (ppp->flags & SC_LOOP_TRAFFIC) == 0)
+			if (ppp->n_channels == 0 &&
+			    (ppp->flags & SC_LOOP_TRAFFIC) == 0)
 				break;
 		}
 		ret = -EAGAIN;
@@ -511,8 +511,8 @@ static unsigned int ppp_poll(struct file
 	else if (pf->kind == INTERFACE) {
 		/* see comment in ppp_read */
 		struct ppp *ppp = PF_TO_PPP(pf);
-		if (ppp->n_channels == 0
-		    && (ppp->flags & SC_LOOP_TRAFFIC) == 0)
+		if (ppp->n_channels == 0 &&
+		    (ppp->flags & SC_LOOP_TRAFFIC) == 0)
 			mask |= POLLIN | POLLRDNORM;
 	}
 
@@ -864,12 +864,7 @@ static const struct file_operations ppp_
 
 static __net_init int ppp_init_net(struct net *net)
 {
-	struct ppp_net *pn;
-	int err;
-
-	pn = kzalloc(sizeof(*pn), GFP_KERNEL);
-	if (!pn)
-		return -ENOMEM;
+	struct ppp_net *pn = net_generic(net, ppp_net_id);
 
 	idr_init(&pn->units_idr);
 	mutex_init(&pn->all_ppp_mutex);
@@ -879,32 +874,21 @@ static __net_init int ppp_init_net(struc
 
 	spin_lock_init(&pn->all_channels_lock);
 
-	err = net_assign_generic(net, ppp_net_id, pn);
-	if (err) {
-		kfree(pn);
-		return err;
-	}
-
 	return 0;
 }
 
 static __net_exit void ppp_exit_net(struct net *net)
 {
-	struct ppp_net *pn;
+	struct ppp_net *pn = net_generic(net, ppp_net_id);
 
-	pn = net_generic(net, ppp_net_id);
 	idr_destroy(&pn->units_idr);
-	/*
-	 * if someone has cached our net then
-	 * further net_generic call will return NULL
-	 */
-	net_assign_generic(net, ppp_net_id, NULL);
-	kfree(pn);
 }
 
 static struct pernet_operations ppp_net_ops = {
 	.init = ppp_init_net,
 	.exit = ppp_exit_net,
+	.id   = &ppp_net_id,
+	.size = sizeof(struct ppp_net),
 };
 
 #define PPP_MAJOR	108
@@ -917,7 +901,7 @@ static int __init ppp_init(void)
 
 	printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
 
-	err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops);
+	err = register_pernet_device(&ppp_net_ops);
 	if (err) {
 		printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err);
 		goto out;
@@ -943,7 +927,7 @@ static int __init ppp_init(void)
 out_chrdev:
 	unregister_chrdev(PPP_MAJOR, "ppp");
 out_net:
-	unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
+	unregister_pernet_device(&ppp_net_ops);
 out:
 	return err;
 }
@@ -1073,8 +1057,8 @@ ppp_xmit_process(struct ppp *ppp)
 	ppp_xmit_lock(ppp);
 	if (!ppp->closing) {
 		ppp_push(ppp);
-		while (!ppp->xmit_pending
-		       && (skb = skb_dequeue(&ppp->file.xq)))
+		while (!ppp->xmit_pending &&
+		       (skb = skb_dequeue(&ppp->file.xq)))
 			ppp_send_frame(ppp, skb);
 		/* If there's no work left to do, tell the core net
 		   code that we can accept some more. */
@@ -1153,18 +1137,18 @@ ppp_send_frame(struct ppp *ppp, struct s
 		/* the filter instructions are constructed assuming
 		   a four-byte PPP header on each packet */
 		*skb_push(skb, 2) = 1;
-		if (ppp->pass_filter
-		    && sk_run_filter(skb, ppp->pass_filter,
-				     ppp->pass_len) == 0) {
+		if (ppp->pass_filter &&
+		    sk_run_filter(skb, ppp->pass_filter,
+				  ppp->pass_len) == 0) {
 			if (ppp->debug & 1)
 				printk(KERN_DEBUG "PPP: outbound frame not passed\n");
 			kfree_skb(skb);
 			return;
 		}
 		/* if this packet passes the active filter, record the time */
-		if (!(ppp->active_filter
-		      && sk_run_filter(skb, ppp->active_filter,
-				       ppp->active_len) == 0))
+		if (!(ppp->active_filter &&
+		      sk_run_filter(skb, ppp->active_filter,
+				    ppp->active_len) == 0))
 			ppp->last_xmit = jiffies;
 		skb_pull(skb, 2);
 #else
@@ -1218,8 +1202,8 @@ ppp_send_frame(struct ppp *ppp, struct s
 	}
 
 	/* try to do packet compression */
-	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state
-	    && proto != PPP_LCP && proto != PPP_CCP) {
+	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state &&
+	    proto != PPP_LCP && proto != PPP_CCP) {
 		if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
 			if (net_ratelimit())
 				printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
@@ -1593,8 +1577,8 @@ ppp_input(struct ppp_channel *chan, stru
 		/* put it on the channel queue */
 		skb_queue_tail(&pch->file.rq, skb);
 		/* drop old frames if queue too long */
-		while (pch->file.rq.qlen > PPP_MAX_RQLEN
-		       && (skb = skb_dequeue(&pch->file.rq)))
+		while (pch->file.rq.qlen > PPP_MAX_RQLEN &&
+		       (skb = skb_dequeue(&pch->file.rq)))
 			kfree_skb(skb);
 		wake_up_interruptible(&pch->file.rwait);
 	} else {
@@ -1670,8 +1654,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp,
 	 * Note that some decompressors need to see uncompressed frames
 	 * that come in as well as compressed frames.
 	 */
-	if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)
-	    && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
+	if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN) &&
+	    (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
 		skb = ppp_decompress_frame(ppp, skb);
 
 	if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
@@ -1742,8 +1726,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp,
 		/* control or unknown frame - pass it to pppd */
 		skb_queue_tail(&ppp->file.rq, skb);
 		/* limit queue length by dropping old frames */
-		while (ppp->file.rq.qlen > PPP_MAX_RQLEN
-		       && (skb = skb_dequeue(&ppp->file.rq)))
+		while (ppp->file.rq.qlen > PPP_MAX_RQLEN &&
+		       (skb = skb_dequeue(&ppp->file.rq)))
 			kfree_skb(skb);
 		/* wake up any process polling or blocking on read */
 		wake_up_interruptible(&ppp->file.rwait);
@@ -1761,26 +1745,26 @@ ppp_receive_nonmp_frame(struct ppp *ppp,
 				goto err;
 
 			*skb_push(skb, 2) = 0;
-			if (ppp->pass_filter
-			    && sk_run_filter(skb, ppp->pass_filter,
-					     ppp->pass_len) == 0) {
+			if (ppp->pass_filter &&
+			    sk_run_filter(skb, ppp->pass_filter,
+					  ppp->pass_len) == 0) {
 				if (ppp->debug & 1)
 					printk(KERN_DEBUG "PPP: inbound frame "
 					       "not passed\n");
 				kfree_skb(skb);
 				return;
 			}
-			if (!(ppp->active_filter
-			      && sk_run_filter(skb, ppp->active_filter,
-					       ppp->active_len) == 0))
+			if (!(ppp->active_filter &&
+			      sk_run_filter(skb, ppp->active_filter,
+					    ppp->active_len) == 0))
 				ppp->last_recv = jiffies;
 			__skb_pull(skb, 2);
 		} else
 #endif /* CONFIG_PPP_FILTER */
 			ppp->last_recv = jiffies;
 
-		if ((ppp->dev->flags & IFF_UP) == 0
-		    || ppp->npmode[npi] != NPMODE_PASS) {
+		if ((ppp->dev->flags & IFF_UP) == 0 ||
+		    ppp->npmode[npi] != NPMODE_PASS) {
 			kfree_skb(skb);
 		} else {
 			/* chop off protocol */
@@ -2244,13 +2228,13 @@ ppp_set_compress(struct ppp *ppp, unsign
 	unsigned char ccp_option[CCP_MAX_OPTION_LENGTH];
 
 	err = -EFAULT;
-	if (copy_from_user(&data, (void __user *) arg, sizeof(data))
-	    || (data.length <= CCP_MAX_OPTION_LENGTH
-		&& copy_from_user(ccp_option, (void __user *) data.ptr, data.length)))
+	if (copy_from_user(&data, (void __user *) arg, sizeof(data)) ||
+	    (data.length <= CCP_MAX_OPTION_LENGTH &&
+	     copy_from_user(ccp_option, (void __user *) data.ptr, data.length)))
 		goto out;
 	err = -EINVAL;
-	if (data.length > CCP_MAX_OPTION_LENGTH
-	    || ccp_option[1] < 2 || ccp_option[1] > data.length)
+	if (data.length > CCP_MAX_OPTION_LENGTH ||
+	    ccp_option[1] < 2 || ccp_option[1] > data.length)
 		goto out;
 
 	cp = try_then_request_module(
@@ -2835,7 +2819,7 @@ static void __exit ppp_cleanup(void)
 	unregister_chrdev(PPP_MAJOR, "ppp");
 	device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
 	class_destroy(ppp_class);
-	unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
+	unregister_pernet_device(&ppp_net_ops);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ppp_mppe.c linux-libre-2.6.33-gnu1/drivers/net/ppp_mppe.c
--- linux-libre-2.6.32-gnu1/drivers/net/ppp_mppe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ppp_mppe.c	2010-02-24 13:52:17.000000000 -0500
@@ -195,8 +195,8 @@ static void *mppe_alloc(unsigned char *o
 	struct ppp_mppe_state *state;
 	unsigned int digestsize;
 
-	if (optlen != CILEN_MPPE + sizeof(state->master_key)
-	    || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+	if (optlen != CILEN_MPPE + sizeof(state->master_key) ||
+	    options[0] != CI_MPPE || options[1] != CILEN_MPPE)
 		goto out;
 
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -276,8 +276,8 @@ mppe_init(void *arg, unsigned char *opti
 	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
 	unsigned char mppe_opts;
 
-	if (optlen != CILEN_MPPE
-	    || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+	if (optlen != CILEN_MPPE ||
+	    options[0] != CI_MPPE || options[1] != CILEN_MPPE)
 		return 0;
 
 	MPPE_CI_TO_OPTS(&options[2], mppe_opts);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pppoe.c linux-libre-2.6.33-gnu1/drivers/net/pppoe.c
--- linux-libre-2.6.32-gnu1/drivers/net/pppoe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pppoe.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,7 +97,7 @@ static const struct proto_ops pppoe_ops;
 static struct ppp_channel_ops pppoe_chan_ops;
 
 /* per-net private data for this module */
-static int pppoe_net_id;
+static int pppoe_net_id __read_mostly;
 struct pppoe_net {
 	/*
 	 * we could use _single_ hash table for all
@@ -250,20 +250,19 @@ static inline struct pppox_sock *get_ite
 {
 	struct net_device *dev;
 	struct pppoe_net *pn;
-	struct pppox_sock *pppox_sock;
+	struct pppox_sock *pppox_sock = NULL;
 
 	int ifindex;
 
-	dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev);
-	if (!dev)
-		return NULL;
-
-	ifindex = dev->ifindex;
-	pn = net_generic(net, pppoe_net_id);
-	pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid,
+	rcu_read_lock();
+	dev = dev_get_by_name_rcu(net, sp->sa_addr.pppoe.dev);
+	if (dev) {
+		ifindex = dev->ifindex;
+		pn = net_generic(net, pppoe_net_id);
+		pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid,
 				sp->sa_addr.pppoe.remote, ifindex);
-	dev_put(dev);
-
+	}
+	rcu_read_unlock();
 	return pppox_sock;
 }
 
@@ -324,8 +323,8 @@ static void pppoe_flush_dev(struct net_d
 			write_unlock_bh(&pn->hash_lock);
 			lock_sock(sk);
 
-			if (po->pppoe_dev == dev
-			    && sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+			if (po->pppoe_dev == dev &&
+			    sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
 				pppox_unbind_sock(sk);
 				sk->sk_state = PPPOX_ZOMBIE;
 				sk->sk_state_change(sk);
@@ -1140,59 +1139,37 @@ static struct pppox_proto pppoe_proto =
 
 static __net_init int pppoe_init_net(struct net *net)
 {
-	struct pppoe_net *pn;
+	struct pppoe_net *pn = pppoe_pernet(net);
 	struct proc_dir_entry *pde;
-	int err;
-
-	pn = kzalloc(sizeof(*pn), GFP_KERNEL);
-	if (!pn)
-		return -ENOMEM;
 
 	rwlock_init(&pn->hash_lock);
 
-	err = net_assign_generic(net, pppoe_net_id, pn);
-	if (err)
-		goto out;
-
 	pde = proc_net_fops_create(net, "pppoe", S_IRUGO, &pppoe_seq_fops);
 #ifdef CONFIG_PROC_FS
-	if (!pde) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!pde)
+		return -ENOMEM;
 #endif
 
 	return 0;
-
-out:
-	kfree(pn);
-	return err;
 }
 
 static __net_exit void pppoe_exit_net(struct net *net)
 {
-	struct pppoe_net *pn;
-
 	proc_net_remove(net, "pppoe");
-	pn = net_generic(net, pppoe_net_id);
-	/*
-	 * if someone has cached our net then
-	 * further net_generic call will return NULL
-	 */
-	net_assign_generic(net, pppoe_net_id, NULL);
-	kfree(pn);
 }
 
 static struct pernet_operations pppoe_net_ops = {
 	.init = pppoe_init_net,
 	.exit = pppoe_exit_net,
+	.id   = &pppoe_net_id,
+	.size = sizeof(struct pppoe_net),
 };
 
 static int __init pppoe_init(void)
 {
 	int err;
 
-	err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
+	err = register_pernet_device(&pppoe_net_ops);
 	if (err)
 		goto out;
 
@@ -1213,7 +1190,7 @@ static int __init pppoe_init(void)
 out_unregister_pppoe_proto:
 	proto_unregister(&pppoe_sk_proto);
 out_unregister_net_ops:
-	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
+	unregister_pernet_device(&pppoe_net_ops);
 out:
 	return err;
 }
@@ -1225,7 +1202,7 @@ static void __exit pppoe_exit(void)
 	dev_remove_pack(&pppoes_ptype);
 	unregister_pppox_proto(PX_PROTO_OE);
 	proto_unregister(&pppoe_sk_proto);
-	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
+	unregister_pernet_device(&pppoe_net_ops);
 }
 
 module_init(pppoe_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pppol2tp.c linux-libre-2.6.33-gnu1/drivers/net/pppol2tp.c
--- linux-libre-2.6.32-gnu1/drivers/net/pppol2tp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pppol2tp.c	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,7 @@ static struct ppp_channel_ops pppol2tp_c
 static const struct proto_ops pppol2tp_ops;
 
 /* per-net private data for this module */
-static int pppol2tp_net_id;
+static int pppol2tp_net_id __read_mostly;
 struct pppol2tp_net {
 	struct list_head pppol2tp_tunnel_list;
 	rwlock_t pppol2tp_tunnel_list_lock;
@@ -516,7 +516,7 @@ static inline int pppol2tp_verify_udp_ch
 		return 0;
 
 	inet = inet_sk(sk);
-	psum = csum_tcpudp_nofold(inet->saddr, inet->daddr, ulen,
+	psum = csum_tcpudp_nofold(inet->inet_saddr, inet->inet_daddr, ulen,
 				  IPPROTO_UDP, 0);
 
 	if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
@@ -949,8 +949,8 @@ static int pppol2tp_sendmsg(struct kiocb
 	inet = inet_sk(sk_tun);
 	udp_len = hdr_len + sizeof(ppph) + total_len;
 	uh = (struct udphdr *) skb->data;
-	uh->source = inet->sport;
-	uh->dest = inet->dport;
+	uh->source = inet->inet_sport;
+	uh->dest = inet->inet_dport;
 	uh->len = htons(udp_len);
 	uh->check = 0;
 	skb_put(skb, sizeof(struct udphdr));
@@ -978,7 +978,8 @@ static int pppol2tp_sendmsg(struct kiocb
 	else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
 		skb->ip_summed = CHECKSUM_COMPLETE;
 		csum = skb_checksum(skb, 0, udp_len, 0);
-		uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
+		uh->check = csum_tcpudp_magic(inet->inet_saddr,
+					      inet->inet_daddr,
 					      udp_len, IPPROTO_UDP, csum);
 		if (uh->check == 0)
 			uh->check = CSUM_MANGLED_0;
@@ -986,7 +987,8 @@ static int pppol2tp_sendmsg(struct kiocb
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_transport_header(skb) - skb->head;
 		skb->csum_offset = offsetof(struct udphdr, check);
-		uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr,
+		uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
+					       inet->inet_daddr,
 					       udp_len, IPPROTO_UDP, 0);
 	}
 
@@ -1136,8 +1138,8 @@ static int pppol2tp_xmit(struct ppp_chan
 	__skb_push(skb, sizeof(*uh));
 	skb_reset_transport_header(skb);
 	uh = udp_hdr(skb);
-	uh->source = inet->sport;
-	uh->dest = inet->dport;
+	uh->source = inet->inet_sport;
+	uh->dest = inet->inet_dport;
 	uh->len = htons(udp_len);
 	uh->check = 0;
 
@@ -1181,7 +1183,8 @@ static int pppol2tp_xmit(struct ppp_chan
 	else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
 		skb->ip_summed = CHECKSUM_COMPLETE;
 		csum = skb_checksum(skb, 0, udp_len, 0);
-		uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
+		uh->check = csum_tcpudp_magic(inet->inet_saddr,
+					      inet->inet_daddr,
 					      udp_len, IPPROTO_UDP, csum);
 		if (uh->check == 0)
 			uh->check = CSUM_MANGLED_0;
@@ -1189,7 +1192,8 @@ static int pppol2tp_xmit(struct ppp_chan
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_transport_header(skb) - skb->head;
 		skb->csum_offset = offsetof(struct udphdr, check);
-		uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr,
+		uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
+					       inet->inet_daddr,
 					       udp_len, IPPROTO_UDP, 0);
 	}
 
@@ -1533,7 +1537,7 @@ static struct sock *pppol2tp_prepare_tun
 	 * if the tunnel socket goes away.
 	 */
 	tunnel->old_sk_destruct = sk->sk_destruct;
-	sk->sk_destruct = &pppol2tp_tunnel_destruct;
+	sk->sk_destruct = pppol2tp_tunnel_destruct;
 
 	tunnel->sock = sk;
 	sk->sk_allocation = GFP_ATOMIC;
@@ -2601,53 +2605,31 @@ static struct pppox_proto pppol2tp_proto
 
 static __net_init int pppol2tp_init_net(struct net *net)
 {
-	struct pppol2tp_net *pn;
+	struct pppol2tp_net *pn = pppol2tp_pernet(net);
 	struct proc_dir_entry *pde;
-	int err;
-
-	pn = kzalloc(sizeof(*pn), GFP_KERNEL);
-	if (!pn)
-		return -ENOMEM;
 
 	INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
 	rwlock_init(&pn->pppol2tp_tunnel_list_lock);
 
-	err = net_assign_generic(net, pppol2tp_net_id, pn);
-	if (err)
-		goto out;
-
 	pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
 #ifdef CONFIG_PROC_FS
-	if (!pde) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!pde)
+		return -ENOMEM;
 #endif
 
 	return 0;
-
-out:
-	kfree(pn);
-	return err;
 }
 
 static __net_exit void pppol2tp_exit_net(struct net *net)
 {
-	struct pppoe_net *pn;
-
 	proc_net_remove(net, "pppol2tp");
-	pn = net_generic(net, pppol2tp_net_id);
-	/*
-	 * if someone has cached our net then
-	 * further net_generic call will return NULL
-	 */
-	net_assign_generic(net, pppol2tp_net_id, NULL);
-	kfree(pn);
 }
 
 static struct pernet_operations pppol2tp_net_ops = {
 	.init = pppol2tp_init_net,
 	.exit = pppol2tp_exit_net,
+	.id   = &pppol2tp_net_id,
+	.size = sizeof(struct pppol2tp_net),
 };
 
 static int __init pppol2tp_init(void)
@@ -2661,7 +2643,7 @@ static int __init pppol2tp_init(void)
 	if (err)
 		goto out_unregister_pppol2tp_proto;
 
-	err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
+	err = register_pernet_device(&pppol2tp_net_ops);
 	if (err)
 		goto out_unregister_pppox_proto;
 
@@ -2680,7 +2662,7 @@ out_unregister_pppol2tp_proto:
 static void __exit pppol2tp_exit(void)
 {
 	unregister_pppox_proto(PX_PROTO_OL2TP);
-	unregister_pernet_gen_device(pppol2tp_net_id, &pppol2tp_net_ops);
+	unregister_pernet_device(&pppol2tp_net_ops);
 	proto_unregister(&pppol2tp_sk_proto);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/pppox.c linux-libre-2.6.33-gnu1/drivers/net/pppox.c
--- linux-libre-2.6.32-gnu1/drivers/net/pppox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/pppox.c	2010-02-24 13:52:17.000000000 -0500
@@ -104,7 +104,8 @@ int pppox_ioctl(struct socket *sock, uns
 
 EXPORT_SYMBOL(pppox_ioctl);
 
-static int pppox_create(struct net *net, struct socket *sock, int protocol)
+static int pppox_create(struct net *net, struct socket *sock, int protocol,
+			int kern)
 {
 	int rc = -EPROTOTYPE;
 
@@ -125,7 +126,7 @@ out:
 	return rc;
 }
 
-static struct net_proto_family pppox_proto_family = {
+static const struct net_proto_family pppox_proto_family = {
 	.family	= PF_PPPOX,
 	.create	= pppox_create,
 	.owner	= THIS_MODULE,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ppp_synctty.c linux-libre-2.6.33-gnu1/drivers/net/ppp_synctty.c
--- linux-libre-2.6.32-gnu1/drivers/net/ppp_synctty.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ppp_synctty.c	2010-02-24 13:52:17.000000000 -0500
@@ -378,10 +378,7 @@ ppp_sync_poll(struct tty_struct *tty, st
 	return 0;
 }
 
-/*
- * This can now be called from hard interrupt level as well
- * as soft interrupt level or mainline.
- */
+/* May sleep, don't call from interrupt level or with interrupts disabled */
 static void
 ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
 		  char *cflags, int count)
@@ -665,8 +662,8 @@ ppp_sync_push(struct syncppp *ap)
 		}
 		/* haven't made any progress */
 		spin_unlock_bh(&ap->xmit_lock);
-		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-		      || (!tty_stuffed && ap->tpkt)))
+		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) ||
+		      (!tty_stuffed && ap->tpkt)))
 			break;
 		if (!spin_trylock_bh(&ap->xmit_lock))
 			break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_net.c linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.c
--- linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.c	2010-02-24 13:52:17.000000000 -0500
@@ -95,11 +95,11 @@ static void gelic_card_get_ether_port_st
 
 	lv1_net_control(bus_id(card), dev_id(card),
 			GELIC_LV1_GET_ETH_PORT_STATUS,
-			GELIC_LV1_VLAN_TX_ETHERNET, 0, 0,
+			GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
 			&card->ether_port_status, &v2);
 
 	if (inform) {
-		ether_netdev = card->netdev[GELIC_PORT_ETHERNET];
+		ether_netdev = card->netdev[GELIC_PORT_ETHERNET_0];
 		if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
 			netif_carrier_on(ether_netdev);
 		else
@@ -107,6 +107,24 @@ static void gelic_card_get_ether_port_st
 	}
 }
 
+static int gelic_card_set_link_mode(struct gelic_card *card, int mode)
+{
+	int status;
+	u64 v1, v2;
+
+	status = lv1_net_control(bus_id(card), dev_id(card),
+				 GELIC_LV1_SET_NEGOTIATION_MODE,
+				 GELIC_LV1_PHY_ETHERNET_0, mode, 0, &v1, &v2);
+	if (status) {
+		pr_info("%s: failed setting negotiation mode %d\n", __func__,
+			status);
+		return -EBUSY;
+	}
+
+	card->link_mode = mode;
+	return 0;
+}
+
 void gelic_card_up(struct gelic_card *card)
 {
 	pr_debug("%s: called\n", __func__);
@@ -296,7 +314,7 @@ static void gelic_card_reset_chain(struc
  * @card: card structure
  * @descr: descriptor to re-init
  *
- * return 0 on succes, <0 on failure
+ * return 0 on success, <0 on failure
  *
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
@@ -451,14 +469,14 @@ static void gelic_descr_release_tx(struc
 
 static void gelic_card_stop_queues(struct gelic_card *card)
 {
-	netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]);
+	netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET_0]);
 
 	if (card->netdev[GELIC_PORT_WIRELESS])
 		netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]);
 }
 static void gelic_card_wake_queues(struct gelic_card *card)
 {
-	netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]);
+	netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET_0]);
 
 	if (card->netdev[GELIC_PORT_WIRELESS])
 		netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]);
@@ -999,7 +1017,7 @@ static int gelic_card_decode_one_descr(s
 			goto refill;
 		}
 	} else
-		netdev = card->netdev[GELIC_PORT_ETHERNET];
+		netdev = card->netdev[GELIC_PORT_ETHERNET_0];
 
 	if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) ||
 	    (status == GELIC_DESCR_DMA_PROTECTION_ERROR) ||
@@ -1244,14 +1262,58 @@ static int gelic_ether_get_settings(stru
 	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
 			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
 			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+			SUPPORTED_1000baseT_Full;
 	cmd->advertising = cmd->supported;
-	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+	if (card->link_mode & GELIC_LV1_ETHER_AUTO_NEG) {
+		cmd->autoneg = AUTONEG_ENABLE;
+	} else {
+		cmd->autoneg = AUTONEG_DISABLE;
+		cmd->advertising &= ~ADVERTISED_Autoneg;
+	}
 	cmd->port = PORT_TP;
 
 	return 0;
 }
 
+static int gelic_ether_set_settings(struct net_device *netdev,
+				    struct ethtool_cmd *cmd)
+{
+	struct gelic_card *card = netdev_card(netdev);
+	u64 mode;
+	int ret;
+
+	if (cmd->autoneg == AUTONEG_ENABLE) {
+		mode = GELIC_LV1_ETHER_AUTO_NEG;
+	} else {
+		switch (cmd->speed) {
+		case SPEED_10:
+			mode = GELIC_LV1_ETHER_SPEED_10;
+			break;
+		case SPEED_100:
+			mode = GELIC_LV1_ETHER_SPEED_100;
+			break;
+		case SPEED_1000:
+			mode = GELIC_LV1_ETHER_SPEED_1000;
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (cmd->duplex == DUPLEX_FULL)
+			mode |= GELIC_LV1_ETHER_FULL_DUPLEX;
+		else if (cmd->speed == SPEED_1000) {
+			pr_info("1000 half duplex is not supported.\n");
+			return -EINVAL;
+		}
+	}
+
+	ret = gelic_card_set_link_mode(card, mode);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 u32 gelic_net_get_rx_csum(struct net_device *netdev)
 {
 	struct gelic_card *card = netdev_card(netdev);
@@ -1349,6 +1411,7 @@ done:
 static const struct ethtool_ops gelic_ether_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
 	.get_settings	= gelic_ether_get_settings,
+	.set_settings	= gelic_ether_set_settings,
 	.get_link	= ethtool_op_get_link,
 	.get_tx_csum	= ethtool_op_get_tx_csum,
 	.set_tx_csum	= ethtool_op_set_tx_csum,
@@ -1369,7 +1432,7 @@ static void gelic_net_tx_timeout_task(st
 {
 	struct gelic_card *card =
 		container_of(work, struct gelic_card, tx_timeout_task);
-	struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET];
+	struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET_0];
 
 	dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
 
@@ -1531,10 +1594,10 @@ static struct gelic_card * __devinit gel
 	/* gelic_port */
 	port->netdev = *netdev;
 	port->card = card;
-	port->type = GELIC_PORT_ETHERNET;
+	port->type = GELIC_PORT_ETHERNET_0;
 
 	/* gelic_card */
-	card->netdev[GELIC_PORT_ETHERNET] = *netdev;
+	card->netdev[GELIC_PORT_ETHERNET_0] = *netdev;
 
 	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
 	init_waitqueue_head(&card->waitq);
@@ -1554,9 +1617,9 @@ static void __devinit gelic_card_get_vla
 		int tx;
 		int rx;
 	} vlan_id_ix[2] = {
-		[GELIC_PORT_ETHERNET] = {
-			.tx = GELIC_LV1_VLAN_TX_ETHERNET,
-			.rx = GELIC_LV1_VLAN_RX_ETHERNET
+		[GELIC_PORT_ETHERNET_0] = {
+			.tx = GELIC_LV1_VLAN_TX_ETHERNET_0,
+			.rx = GELIC_LV1_VLAN_RX_ETHERNET_0
 		},
 		[GELIC_PORT_WIRELESS] = {
 			.tx = GELIC_LV1_VLAN_TX_WIRELESS,
@@ -1601,7 +1664,7 @@ static void __devinit gelic_card_get_vla
 			i, card->vlan[i].tx, card->vlan[i].rx);
 	}
 
-	if (card->vlan[GELIC_PORT_ETHERNET].tx) {
+	if (card->vlan[GELIC_PORT_ETHERNET_0].tx) {
 		BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx);
 		card->vlan_required = 1;
 	} else
@@ -1657,6 +1720,8 @@ static int __devinit ps3_gelic_driver_pr
 	/* get internal vlan info */
 	gelic_card_get_vlan_info(card);
 
+	card->link_mode = GELIC_LV1_ETHER_AUTO_NEG;
+
 	/* setup interrupt */
 	result = lv1_net_set_interrupt_status_indicator(bus_id(card),
 							dev_id(card),
@@ -1773,6 +1838,9 @@ static int ps3_gelic_driver_remove(struc
 	struct net_device *netdev0;
 	pr_debug("%s: called\n", __func__);
 
+	/* set auto-negotiation */
+	gelic_card_set_link_mode(card, GELIC_LV1_ETHER_AUTO_NEG);
+
 #ifdef CONFIG_GELIC_WIRELESS
 	gelic_wl_driver_remove(card);
 #endif
@@ -1790,7 +1858,7 @@ static int ps3_gelic_driver_remove(struc
 	gelic_card_free_chain(card, card->tx_top);
 	gelic_card_free_chain(card, card->rx_top);
 
-	netdev0 = card->netdev[GELIC_PORT_ETHERNET];
+	netdev0 = card->netdev[GELIC_PORT_ETHERNET_0];
 	/* disconnect event port */
 	free_irq(card->irq, card);
 	netdev0->irq = NO_IRQ;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_net.h linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.h
--- linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_net.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_net.h	2010-02-24 13:52:17.000000000 -0500
@@ -186,7 +186,7 @@ enum gelic_lv1_net_control_code {
 	GELIC_LV1_GET_CHANNEL           = 6,
 	GELIC_LV1_POST_WLAN_CMD		= 9,
 	GELIC_LV1_GET_WLAN_CMD_RESULT	= 10,
-	GELIC_LV1_GET_WLAN_EVENT	= 11
+	GELIC_LV1_GET_WLAN_EVENT	= 11,
 };
 
 /* for GELIC_LV1_SET_WOL */
@@ -217,24 +217,29 @@ enum gelic_lv1_ether_port_status {
 	GELIC_LV1_ETHER_SPEED_10	= 0x0000000000000010L,
 	GELIC_LV1_ETHER_SPEED_100	= 0x0000000000000020L,
 	GELIC_LV1_ETHER_SPEED_1000	= 0x0000000000000040L,
-	GELIC_LV1_ETHER_SPEED_MASK	= 0x0000000000000070L
+	GELIC_LV1_ETHER_SPEED_MASK	= 0x0000000000000070L,
 };
 
 enum gelic_lv1_vlan_index {
 	/* for outgoing packets */
-	GELIC_LV1_VLAN_TX_ETHERNET	= 0x0000000000000002L,
+	GELIC_LV1_VLAN_TX_ETHERNET_0	= 0x0000000000000002L,
 	GELIC_LV1_VLAN_TX_WIRELESS	= 0x0000000000000003L,
+
 	/* for incoming packets */
-	GELIC_LV1_VLAN_RX_ETHERNET	= 0x0000000000000012L,
-	GELIC_LV1_VLAN_RX_WIRELESS	= 0x0000000000000013L
+	GELIC_LV1_VLAN_RX_ETHERNET_0	= 0x0000000000000012L,
+	GELIC_LV1_VLAN_RX_WIRELESS	= 0x0000000000000013L,
+};
+
+enum gelic_lv1_phy {
+	GELIC_LV1_PHY_ETHERNET_0	= 0x0000000000000002L,
 };
 
 /* size of hardware part of gelic descriptor */
 #define GELIC_DESCR_SIZE	(32)
 
 enum gelic_port_type {
-	GELIC_PORT_ETHERNET = 0,
-	GELIC_PORT_WIRELESS = 1,
+	GELIC_PORT_ETHERNET_0	= 0,
+	GELIC_PORT_WIRELESS	= 1,
 	GELIC_PORT_MAX
 };
 
@@ -302,6 +307,8 @@ struct gelic_card {
 	atomic_t users;
 
 	u64 ether_port_status;
+	int link_mode;
+
 	/* original address returned by kzalloc */
 	void *unalign;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_wireless.h linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_wireless.h
--- linux-libre-2.6.32-gnu1/drivers/net/ps3_gelic_wireless.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ps3_gelic_wireless.h	2010-02-24 13:52:17.000000000 -0500
@@ -199,7 +199,7 @@ struct gelic_eurus_rssi_info {
 /* for 'stat' member of gelic_wl_info */
 enum gelic_wl_info_status_bit {
 	GELIC_WL_STAT_CONFIGURED,
-	GELIC_WL_STAT_CH_INFO,   /* ch info aquired */
+	GELIC_WL_STAT_CH_INFO,   /* ch info acquired */
 	GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */
 	GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */
 	GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qla3xxx.c linux-libre-2.6.33-gnu1/drivers/net/qla3xxx.c
--- linux-libre-2.6.32-gnu1/drivers/net/qla3xxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qla3xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -1969,8 +1969,8 @@ static void ql_update_lrg_bufq_prod_inde
 	struct ql_rcv_buf_cb *lrg_buf_cb;
 	struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
 
-	if ((qdev->lrg_buf_free_count >= 8)
-	    && (qdev->lrg_buf_release_cnt >= 16)) {
+	if ((qdev->lrg_buf_free_count >= 8) &&
+	    (qdev->lrg_buf_release_cnt >= 16)) {
 
 		if (qdev->lrg_buf_skb_check)
 			if (!ql_populate_free_queue(qdev))
@@ -1978,8 +1978,8 @@ static void ql_update_lrg_bufq_prod_inde
 
 		lrg_buf_q_ele = qdev->lrg_buf_next_free;
 
-		while ((qdev->lrg_buf_release_cnt >= 16)
-		       && (qdev->lrg_buf_free_count >= 8)) {
+		while ((qdev->lrg_buf_release_cnt >= 16) &&
+		       (qdev->lrg_buf_free_count >= 8)) {
 
 			for (i = 0; i < 8; i++) {
 				lrg_buf_cb =
@@ -3651,7 +3651,7 @@ static int ql_adapter_up(struct ql3_adap
 		ql_sem_unlock(qdev, QL_DRVR_SEM_MASK);
 	} else {
 		printk(KERN_ERR PFX
-		       "%s: Could not aquire driver lock.\n",
+		       "%s: Could not acquire driver lock.\n",
 		       ndev->name);
 		goto err_lock;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_dbg.c linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_dbg.c
--- linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_dbg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_dbg.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,185 @@
 #include "qlge.h"
 
+
+static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf)
+{
+	int status = 0;
+	int i;
+
+	for (i = 0; i < 8; i++, buf++) {
+		ql_write32(qdev, NIC_ETS, i << 29 | 0x08000000);
+		*buf = ql_read32(qdev, NIC_ETS);
+	}
+
+	for (i = 0; i < 2; i++, buf++) {
+		ql_write32(qdev, CNA_ETS, i << 29 | 0x08000000);
+		*buf = ql_read32(qdev, CNA_ETS);
+	}
+
+	return status;
+}
+
+static void ql_get_intr_states(struct ql_adapter *qdev, u32 * buf)
+{
+	int i;
+
+	for (i = 0; i < qdev->rx_ring_count; i++, buf++) {
+		ql_write32(qdev, INTR_EN,
+				qdev->intr_context[i].intr_read_mask);
+		*buf = ql_read32(qdev, INTR_EN);
+	}
+}
+
+static int ql_get_cam_entries(struct ql_adapter *qdev, u32 * buf)
+{
+	int i, status;
+	u32 value[3];
+
+	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status)
+		return status;
+
+	for (i = 0; i < 16; i++) {
+		status = ql_get_mac_addr_reg(qdev,
+					MAC_ADDR_TYPE_CAM_MAC, i, value);
+		if (status) {
+			QPRINTK(qdev, DRV, ERR,
+				"Failed read of mac index register.\n");
+			goto err;
+		}
+		*buf++ = value[0];	/* lower MAC address */
+		*buf++ = value[1];	/* upper MAC address */
+		*buf++ = value[2];	/* output */
+	}
+	for (i = 0; i < 32; i++) {
+		status = ql_get_mac_addr_reg(qdev,
+					MAC_ADDR_TYPE_MULTI_MAC, i, value);
+		if (status) {
+			QPRINTK(qdev, DRV, ERR,
+				"Failed read of mac index register.\n");
+			goto err;
+		}
+		*buf++ = value[0];	/* lower Mcast address */
+		*buf++ = value[1];	/* upper Mcast address */
+	}
+err:
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+	return status;
+}
+
+static int ql_get_routing_entries(struct ql_adapter *qdev, u32 * buf)
+{
+	int status;
+	u32 value, i;
+
+	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+	if (status)
+		return status;
+
+	for (i = 0; i < 16; i++) {
+		status = ql_get_routing_reg(qdev, i, &value);
+		if (status) {
+			QPRINTK(qdev, DRV, ERR,
+				"Failed read of routing index register.\n");
+			goto err;
+		} else {
+			*buf++ = value;
+		}
+	}
+err:
+	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+	return status;
+}
+
+/* Create a coredump segment header */
+static void ql_build_coredump_seg_header(
+		struct mpi_coredump_segment_header *seg_hdr,
+		u32 seg_number, u32 seg_size, u8 *desc)
+{
+	memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
+	seg_hdr->cookie = MPI_COREDUMP_COOKIE;
+	seg_hdr->segNum = seg_number;
+	seg_hdr->segSize = seg_size;
+	memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
+}
+
+void ql_gen_reg_dump(struct ql_adapter *qdev,
+			struct ql_reg_dump *mpi_coredump)
+{
+	int i, status;
+
+
+	memset(&(mpi_coredump->mpi_global_header), 0,
+		sizeof(struct mpi_coredump_global_header));
+	mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
+	mpi_coredump->mpi_global_header.headerSize =
+		sizeof(struct mpi_coredump_global_header);
+	mpi_coredump->mpi_global_header.imageSize =
+		sizeof(struct ql_reg_dump);
+	memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
+		sizeof(mpi_coredump->mpi_global_header.idString));
+
+
+	/* segment 16 */
+	ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
+				MISC_NIC_INFO_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->misc_nic_info),
+				"MISC NIC INFO");
+	mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
+	mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
+	mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
+	mpi_coredump->misc_nic_info.function = qdev->func;
+
+	/* Segment 16, Rev C. Step 18 */
+	ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
+				NIC1_CONTROL_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->nic_regs),
+				"NIC Registers");
+	/* Get generic reg dump */
+	for (i = 0; i < 64; i++)
+		mpi_coredump->nic_regs[i] = ql_read32(qdev, i * sizeof(u32));
+
+	/* Segment 31 */
+	/* Get indexed register values. */
+	ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
+				INTR_STATES_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->intr_states),
+				"INTR States");
+	ql_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
+
+	ql_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
+				CAM_ENTRIES_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->cam_entries),
+				"CAM Entries");
+	status = ql_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
+	if (status)
+		return;
+
+	ql_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
+				ROUTING_WORDS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->nic_routing_words),
+				"Routing Words");
+	status = ql_get_routing_entries(qdev,
+			 &mpi_coredump->nic_routing_words[0]);
+	if (status)
+		return;
+
+	/* Segment 34 (Rev C. step 23) */
+	ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
+				ETS_SEG_NUM,
+				sizeof(struct mpi_coredump_segment_header)
+				+ sizeof(mpi_coredump->ets),
+				"ETS Registers");
+	status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
+	if (status)
+		return;
+}
+
 #ifdef QL_REG_DUMP
 static void ql_dump_intr_states(struct ql_adapter *qdev)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,11 @@
 
 #include "qlge.h"
 
+static const char ql_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Loopback test  (offline)"
+};
+#define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN)
+
 static int ql_update_ring_coalescing(struct ql_adapter *qdev)
 {
 	int i, status = 0;
@@ -132,6 +137,41 @@ static void ql_update_stats(struct ql_ad
 		iter++;
 	}
 
+	/*
+	 * Get Per-priority TX pause frame counter statistics.
+	 */
+	for (i = 0x500; i < 0x540; i += 8) {
+		if (ql_read_xgmac_reg64(qdev, i, &data)) {
+			QPRINTK(qdev, DRV, ERR,
+				"Error reading status register 0x%.04x.\n", i);
+			goto end;
+		} else
+			*iter = data;
+		iter++;
+	}
+
+	/*
+	 * Get Per-priority RX pause frame counter statistics.
+	 */
+	for (i = 0x568; i < 0x5a8; i += 8) {
+		if (ql_read_xgmac_reg64(qdev, i, &data)) {
+			QPRINTK(qdev, DRV, ERR,
+				"Error reading status register 0x%.04x.\n", i);
+			goto end;
+		} else
+			*iter = data;
+		iter++;
+	}
+
+	/*
+	 * Get RX NIC FIFO DROP statistics.
+	 */
+	if (ql_read_xgmac_reg64(qdev, 0x5b8, &data)) {
+		QPRINTK(qdev, DRV, ERR,
+			"Error reading status register 0x%.04x.\n", i);
+		goto end;
+	} else
+		*iter = data;
 end:
 	ql_sem_unlock(qdev, qdev->xg_sem_mask);
 quit:
@@ -185,6 +225,23 @@ static char ql_stats_str_arr[][ETH_GSTRI
 	{"rx_1024_to_1518_pkts"},
 	{"rx_1519_to_max_pkts"},
 	{"rx_len_err_pkts"},
+	{"tx_cbfc_pause_frames0"},
+	{"tx_cbfc_pause_frames1"},
+	{"tx_cbfc_pause_frames2"},
+	{"tx_cbfc_pause_frames3"},
+	{"tx_cbfc_pause_frames4"},
+	{"tx_cbfc_pause_frames5"},
+	{"tx_cbfc_pause_frames6"},
+	{"tx_cbfc_pause_frames7"},
+	{"rx_cbfc_pause_frames0"},
+	{"rx_cbfc_pause_frames1"},
+	{"rx_cbfc_pause_frames2"},
+	{"rx_cbfc_pause_frames3"},
+	{"rx_cbfc_pause_frames4"},
+	{"rx_cbfc_pause_frames5"},
+	{"rx_cbfc_pause_frames6"},
+	{"rx_cbfc_pause_frames7"},
+	{"rx_nic_fifo_drop"},
 };
 
 static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@@ -199,6 +256,8 @@ static void ql_get_strings(struct net_de
 static int ql_get_sset_count(struct net_device *dev, int sset)
 {
 	switch (sset) {
+	case ETH_SS_TEST:
+		return QLGE_TEST_LEN;
 	case ETH_SS_STATS:
 		return ARRAY_SIZE(ql_stats_str_arr);
 	default:
@@ -257,6 +316,23 @@ ql_get_ethtool_stats(struct net_device *
 	*data++ = s->rx_1024_to_1518_pkts;
 	*data++ = s->rx_1519_to_max_pkts;
 	*data++ = s->rx_len_err_pkts;
+	*data++ = s->tx_cbfc_pause_frames0;
+	*data++ = s->tx_cbfc_pause_frames1;
+	*data++ = s->tx_cbfc_pause_frames2;
+	*data++ = s->tx_cbfc_pause_frames3;
+	*data++ = s->tx_cbfc_pause_frames4;
+	*data++ = s->tx_cbfc_pause_frames5;
+	*data++ = s->tx_cbfc_pause_frames6;
+	*data++ = s->tx_cbfc_pause_frames7;
+	*data++ = s->rx_cbfc_pause_frames0;
+	*data++ = s->rx_cbfc_pause_frames1;
+	*data++ = s->rx_cbfc_pause_frames2;
+	*data++ = s->rx_cbfc_pause_frames3;
+	*data++ = s->rx_cbfc_pause_frames4;
+	*data++ = s->rx_cbfc_pause_frames5;
+	*data++ = s->rx_cbfc_pause_frames6;
+	*data++ = s->rx_cbfc_pause_frames7;
+	*data++ = s->rx_nic_fifo_drop;
 }
 
 static int ql_get_settings(struct net_device *ndev,
@@ -302,6 +378,181 @@ static void ql_get_drvinfo(struct net_de
 	drvinfo->eedump_len = 0;
 }
 
+static void ql_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+	/* What we support. */
+	wol->supported = WAKE_MAGIC;
+	/* What we've currently got set. */
+	wol->wolopts = qdev->wol;
+}
+
+static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+	int status;
+
+	if (wol->wolopts & ~WAKE_MAGIC)
+		return -EINVAL;
+	qdev->wol = wol->wolopts;
+
+	QPRINTK(qdev, DRV, INFO, "Set wol option 0x%x on %s\n",
+			 qdev->wol, ndev->name);
+	if (!qdev->wol) {
+		u32 wol = 0;
+		status = ql_mb_wol_mode(qdev, wol);
+		QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
+			(status == 0) ? "cleared sucessfully" : "clear failed",
+			wol, qdev->ndev->name);
+	}
+
+	return 0;
+}
+
+static int ql_phys_id(struct net_device *ndev, u32 data)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+	u32 led_reg, i;
+	int status;
+
+	/* Save the current LED settings */
+	status = ql_mb_get_led_cfg(qdev);
+	if (status)
+		return status;
+	led_reg = qdev->led_config;
+
+	/* Start blinking the led */
+	if (!data || data > 300)
+		data = 300;
+
+	for (i = 0; i < (data * 10); i++)
+		ql_mb_set_led_cfg(qdev, QL_LED_BLINK);
+
+	/* Restore LED settings */
+	status = ql_mb_set_led_cfg(qdev, led_reg);
+	if (status)
+		return status;
+
+	return 0;
+}
+
+static int ql_start_loopback(struct ql_adapter *qdev)
+{
+	if (netif_carrier_ok(qdev->ndev)) {
+		set_bit(QL_LB_LINK_UP, &qdev->flags);
+		netif_carrier_off(qdev->ndev);
+	} else
+		clear_bit(QL_LB_LINK_UP, &qdev->flags);
+	qdev->link_config |= CFG_LOOPBACK_PCS;
+	return ql_mb_set_port_cfg(qdev);
+}
+
+static void ql_stop_loopback(struct ql_adapter *qdev)
+{
+	qdev->link_config &= ~CFG_LOOPBACK_PCS;
+	ql_mb_set_port_cfg(qdev);
+	if (test_bit(QL_LB_LINK_UP, &qdev->flags)) {
+		netif_carrier_on(qdev->ndev);
+		clear_bit(QL_LB_LINK_UP, &qdev->flags);
+	}
+}
+
+static void ql_create_lb_frame(struct sk_buff *skb,
+					unsigned int frame_size)
+{
+	memset(skb->data, 0xFF, frame_size);
+	frame_size &= ~1;
+	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
+	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
+	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+}
+
+void ql_check_lb_frame(struct ql_adapter *qdev,
+					struct sk_buff *skb)
+{
+	unsigned int frame_size = skb->len;
+
+	if ((*(skb->data + 3) == 0xFF) &&
+		(*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+		(*(skb->data + frame_size / 2 + 12) == 0xAF)) {
+			atomic_dec(&qdev->lb_count);
+			return;
+	}
+}
+
+static int ql_run_loopback_test(struct ql_adapter *qdev)
+{
+	int i;
+	netdev_tx_t rc;
+	struct sk_buff *skb;
+	unsigned int size = SMALL_BUF_MAP_SIZE;
+
+	for (i = 0; i < 64; i++) {
+		skb = netdev_alloc_skb(qdev->ndev, size);
+		if (!skb)
+			return -ENOMEM;
+
+		skb->queue_mapping = 0;
+		skb_put(skb, size);
+		ql_create_lb_frame(skb, size);
+		rc = ql_lb_send(skb, qdev->ndev);
+		if (rc != NETDEV_TX_OK)
+			return -EPIPE;
+		atomic_inc(&qdev->lb_count);
+	}
+
+	ql_clean_lb_rx_ring(&qdev->rx_ring[0], 128);
+	return atomic_read(&qdev->lb_count) ? -EIO : 0;
+}
+
+static int ql_loopback_test(struct ql_adapter *qdev, u64 *data)
+{
+	*data = ql_start_loopback(qdev);
+	if (*data)
+		goto out;
+	*data = ql_run_loopback_test(qdev);
+out:
+	ql_stop_loopback(qdev);
+	return *data;
+}
+
+static void ql_self_test(struct net_device *ndev,
+				struct ethtool_test *eth_test, u64 *data)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+
+	if (netif_running(ndev)) {
+		set_bit(QL_SELFTEST, &qdev->flags);
+		if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+			/* Offline tests */
+			if (ql_loopback_test(qdev, &data[0]))
+				eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		} else {
+			/* Online tests */
+			data[0] = 0;
+		}
+		clear_bit(QL_SELFTEST, &qdev->flags);
+	} else {
+		QPRINTK(qdev, DRV, ERR,
+			"%s: is down, Loopback test will fail.\n", ndev->name);
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+	}
+}
+
+static int ql_get_regs_len(struct net_device *ndev)
+{
+	return sizeof(struct ql_reg_dump);
+}
+
+static void ql_get_regs(struct net_device *ndev,
+			struct ethtool_regs *regs, void *p)
+{
+	struct ql_adapter *qdev = netdev_priv(ndev);
+
+	ql_gen_reg_dump(qdev, p);
+}
+
 static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
 	struct ql_adapter *qdev = netdev_priv(dev);
@@ -355,6 +606,37 @@ static int ql_set_coalesce(struct net_de
 	return ql_update_ring_coalescing(qdev);
 }
 
+static void ql_get_pauseparam(struct net_device *netdev,
+			struct ethtool_pauseparam *pause)
+{
+	struct ql_adapter *qdev = netdev_priv(netdev);
+
+	ql_mb_get_port_cfg(qdev);
+	if (qdev->link_config & CFG_PAUSE_STD) {
+		pause->rx_pause = 1;
+		pause->tx_pause = 1;
+	}
+}
+
+static int ql_set_pauseparam(struct net_device *netdev,
+			struct ethtool_pauseparam *pause)
+{
+	struct ql_adapter *qdev = netdev_priv(netdev);
+	int status = 0;
+
+	if ((pause->rx_pause) && (pause->tx_pause))
+		qdev->link_config |= CFG_PAUSE_STD;
+	else if (!pause->rx_pause && !pause->tx_pause)
+		qdev->link_config &= ~CFG_PAUSE_STD;
+	else
+		return -EINVAL;
+
+	status = ql_mb_set_port_cfg(qdev);
+	if (status)
+		return status;
+	return status;
+}
+
 static u32 ql_get_rx_csum(struct net_device *netdev)
 {
 	struct ql_adapter *qdev = netdev_priv(netdev);
@@ -396,9 +678,17 @@ static void ql_set_msglevel(struct net_d
 const struct ethtool_ops qlge_ethtool_ops = {
 	.get_settings = ql_get_settings,
 	.get_drvinfo = ql_get_drvinfo,
+	.get_wol = ql_get_wol,
+	.set_wol = ql_set_wol,
+	.get_regs_len	= ql_get_regs_len,
+	.get_regs = ql_get_regs,
 	.get_msglevel = ql_get_msglevel,
 	.set_msglevel = ql_set_msglevel,
 	.get_link = ethtool_op_get_link,
+	.phys_id		 = ql_phys_id,
+	.self_test		 = ql_self_test,
+	.get_pauseparam		 = ql_get_pauseparam,
+	.set_pauseparam		 = ql_set_pauseparam,
 	.get_rx_csum = ql_get_rx_csum,
 	.set_rx_csum = ql_set_rx_csum,
 	.get_tx_csum = ethtool_op_get_tx_csum,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge.h linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge.h
--- linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,7 @@
  */
 #define DRV_NAME  	"qlge"
 #define DRV_STRING 	"QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION	"v1.00.00-b3"
+#define DRV_VERSION	"v1.00.00.23.00.00-01"
 
 #define PFX "qlge: "
 #define QPRINTK(qdev, nlevel, klevel, fmt, args...)     \
@@ -54,8 +54,10 @@
 #define RX_RING_SHADOW_SPACE	(sizeof(u64) + \
 		MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \
 		MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64))
-#define SMALL_BUFFER_SIZE 256
-#define LARGE_BUFFER_SIZE	PAGE_SIZE
+#define SMALL_BUFFER_SIZE 512
+#define SMALL_BUF_MAP_SIZE (SMALL_BUFFER_SIZE / 2)
+#define LARGE_BUFFER_MAX_SIZE 8192
+#define LARGE_BUFFER_MIN_SIZE 2048
 #define MAX_SPLIT_SIZE 1023
 #define QLGE_SB_PAD 32
 
@@ -795,6 +797,7 @@ enum {
 	MB_WOL_BCAST = (1 << 5),
 	MB_WOL_LINK_UP = (1 << 6),
 	MB_WOL_LINK_DOWN = (1 << 7),
+	MB_WOL_MODE_ON = (1 << 16),		/* Wake on Lan Mode on */
 	MB_CMD_SET_WOL_FLTR = 0x00000111,	/* Wake On Lan Filter */
 	MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
 	MB_CMD_SET_WOL_MAGIC = 0x00000113,	/* Wake On Lan Magic Packet */
@@ -804,12 +807,27 @@ enum {
 	MB_CMD_SET_PORT_CFG = 0x00000122,
 	MB_CMD_GET_PORT_CFG = 0x00000123,
 	MB_CMD_GET_LINK_STS = 0x00000124,
+	MB_CMD_SET_LED_CFG = 0x00000125, /* Set LED Configuration Register */
+		QL_LED_BLINK = 0x03e803e8,
+	MB_CMD_GET_LED_CFG = 0x00000126, /* Get LED Configuration Register */
 	MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
 	MB_SET_MPI_TFK_STOP = (1 << 0),
 	MB_SET_MPI_TFK_RESUME = (1 << 1),
 	MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
 	MB_GET_MPI_TFK_STOPPED = (1 << 0),
 	MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
+	/* Sub-commands for IDC request.
+	 * This describes the reason for the
+	 * IDC request.
+	 */
+	MB_CMD_IOP_NONE = 0x0000,
+	MB_CMD_IOP_PREP_UPDATE_MPI	= 0x0001,
+	MB_CMD_IOP_COMP_UPDATE_MPI	= 0x0002,
+	MB_CMD_IOP_PREP_LINK_DOWN	= 0x0010,
+	MB_CMD_IOP_DVR_START	 = 0x0100,
+	MB_CMD_IOP_FLASH_ACC	 = 0x0101,
+	MB_CMD_IOP_RESTART_MPI	= 0x0102,
+	MB_CMD_IOP_CORE_DUMP_MPI	= 0x0103,
 
 	/* Mailbox Command Status. */
 	MB_CMD_STS_GOOD = 0x00004000,	/* Success. */
@@ -1201,9 +1219,17 @@ struct tx_ring_desc {
 	struct tx_ring_desc *next;
 };
 
+struct page_chunk {
+	struct page *page;	/* master page */
+	char *va;		/* virt addr for this chunk */
+	u64 map;		/* mapping for master */
+	unsigned int offset;	/* offset for this chunk */
+	unsigned int last_flag; /* flag set for last chunk in page */
+};
+
 struct bq_desc {
 	union {
-		struct page *lbq_page;
+		struct page_chunk pg_chunk;
 		struct sk_buff *skb;
 	} p;
 	__le64 *addr;
@@ -1237,6 +1263,9 @@ struct tx_ring {
 	atomic_t queue_stopped;	/* Turns queue off when full. */
 	struct delayed_work tx_work;
 	struct ql_adapter *qdev;
+	u64 tx_packets;
+	u64 tx_bytes;
+	u64 tx_errors;
 };
 
 /*
@@ -1272,6 +1301,7 @@ struct rx_ring {
 	dma_addr_t lbq_base_dma;
 	void *lbq_base_indirect;
 	dma_addr_t lbq_base_indirect_dma;
+	struct page_chunk pg_chunk; /* current page for chunks */
 	struct bq_desc *lbq;	/* array of control blocks */
 	void __iomem *lbq_prod_idx_db_reg;	/* PCI doorbell mem area + 0x18 */
 	u32 lbq_prod_idx;	/* current sw prod idx */
@@ -1302,6 +1332,11 @@ struct rx_ring {
 	struct napi_struct napi;
 	u8 reserved;
 	struct ql_adapter *qdev;
+	u64 rx_packets;
+	u64 rx_multicast;
+	u64 rx_bytes;
+	u64 rx_dropped;
+	u64 rx_errors;
 };
 
 /*
@@ -1363,6 +1398,174 @@ struct nic_stats {
 	u64 rx_1024_to_1518_pkts;
 	u64 rx_1519_to_max_pkts;
 	u64 rx_len_err_pkts;
+	/*
+	 * These stats come from offset 500h to 5C8h
+	 * in the XGMAC register.
+	 */
+	u64 tx_cbfc_pause_frames0;
+	u64 tx_cbfc_pause_frames1;
+	u64 tx_cbfc_pause_frames2;
+	u64 tx_cbfc_pause_frames3;
+	u64 tx_cbfc_pause_frames4;
+	u64 tx_cbfc_pause_frames5;
+	u64 tx_cbfc_pause_frames6;
+	u64 tx_cbfc_pause_frames7;
+	u64 rx_cbfc_pause_frames0;
+	u64 rx_cbfc_pause_frames1;
+	u64 rx_cbfc_pause_frames2;
+	u64 rx_cbfc_pause_frames3;
+	u64 rx_cbfc_pause_frames4;
+	u64 rx_cbfc_pause_frames5;
+	u64 rx_cbfc_pause_frames6;
+	u64 rx_cbfc_pause_frames7;
+	u64 rx_nic_fifo_drop;
+};
+
+/* Address/Length pairs for the coredump. */
+enum {
+	MPI_CORE_REGS_ADDR = 0x00030000,
+	MPI_CORE_REGS_CNT = 127,
+	MPI_CORE_SH_REGS_CNT = 16,
+	TEST_REGS_ADDR = 0x00001000,
+	TEST_REGS_CNT = 23,
+	RMII_REGS_ADDR = 0x00001040,
+	RMII_REGS_CNT = 64,
+	FCMAC1_REGS_ADDR = 0x00001080,
+	FCMAC2_REGS_ADDR = 0x000010c0,
+	FCMAC_REGS_CNT = 64,
+	FC1_MBX_REGS_ADDR = 0x00001100,
+	FC2_MBX_REGS_ADDR = 0x00001240,
+	FC_MBX_REGS_CNT = 64,
+	IDE_REGS_ADDR = 0x00001140,
+	IDE_REGS_CNT = 64,
+	NIC1_MBX_REGS_ADDR = 0x00001180,
+	NIC2_MBX_REGS_ADDR = 0x00001280,
+	NIC_MBX_REGS_CNT = 64,
+	SMBUS_REGS_ADDR = 0x00001200,
+	SMBUS_REGS_CNT = 64,
+	I2C_REGS_ADDR = 0x00001fc0,
+	I2C_REGS_CNT = 64,
+	MEMC_REGS_ADDR = 0x00003000,
+	MEMC_REGS_CNT = 256,
+	PBUS_REGS_ADDR = 0x00007c00,
+	PBUS_REGS_CNT = 256,
+	MDE_REGS_ADDR = 0x00010000,
+	MDE_REGS_CNT = 6,
+	CODE_RAM_ADDR = 0x00020000,
+	CODE_RAM_CNT = 0x2000,
+	MEMC_RAM_ADDR = 0x00100000,
+	MEMC_RAM_CNT = 0x2000,
+};
+
+#define MPI_COREDUMP_COOKIE 0x5555aaaa
+struct mpi_coredump_global_header {
+	u32	cookie;
+	u8	idString[16];
+	u32	timeLo;
+	u32	timeHi;
+	u32	imageSize;
+	u32	headerSize;
+	u8	info[220];
+};
+
+struct mpi_coredump_segment_header {
+	u32	cookie;
+	u32	segNum;
+	u32	segSize;
+	u32	extra;
+	u8	description[16];
+};
+
+/* Reg dump segment numbers. */
+enum {
+	CORE_SEG_NUM = 1,
+	TEST_LOGIC_SEG_NUM = 2,
+	RMII_SEG_NUM = 3,
+	FCMAC1_SEG_NUM = 4,
+	FCMAC2_SEG_NUM = 5,
+	FC1_MBOX_SEG_NUM = 6,
+	IDE_SEG_NUM = 7,
+	NIC1_MBOX_SEG_NUM = 8,
+	SMBUS_SEG_NUM = 9,
+	FC2_MBOX_SEG_NUM = 10,
+	NIC2_MBOX_SEG_NUM = 11,
+	I2C_SEG_NUM = 12,
+	MEMC_SEG_NUM = 13,
+	PBUS_SEG_NUM = 14,
+	MDE_SEG_NUM = 15,
+	NIC1_CONTROL_SEG_NUM = 16,
+	NIC2_CONTROL_SEG_NUM = 17,
+	NIC1_XGMAC_SEG_NUM = 18,
+	NIC2_XGMAC_SEG_NUM = 19,
+	WCS_RAM_SEG_NUM = 20,
+	MEMC_RAM_SEG_NUM = 21,
+	XAUI_AN_SEG_NUM = 22,
+	XAUI_HSS_PCS_SEG_NUM = 23,
+	XFI_AN_SEG_NUM = 24,
+	XFI_TRAIN_SEG_NUM = 25,
+	XFI_HSS_PCS_SEG_NUM = 26,
+	XFI_HSS_TX_SEG_NUM = 27,
+	XFI_HSS_RX_SEG_NUM = 28,
+	XFI_HSS_PLL_SEG_NUM = 29,
+	MISC_NIC_INFO_SEG_NUM = 30,
+	INTR_STATES_SEG_NUM = 31,
+	CAM_ENTRIES_SEG_NUM = 32,
+	ROUTING_WORDS_SEG_NUM = 33,
+	ETS_SEG_NUM = 34,
+	PROBE_DUMP_SEG_NUM = 35,
+	ROUTING_INDEX_SEG_NUM = 36,
+	MAC_PROTOCOL_SEG_NUM = 37,
+	XAUI2_AN_SEG_NUM = 38,
+	XAUI2_HSS_PCS_SEG_NUM = 39,
+	XFI2_AN_SEG_NUM = 40,
+	XFI2_TRAIN_SEG_NUM = 41,
+	XFI2_HSS_PCS_SEG_NUM = 42,
+	XFI2_HSS_TX_SEG_NUM = 43,
+	XFI2_HSS_RX_SEG_NUM = 44,
+	XFI2_HSS_PLL_SEG_NUM = 45,
+	SEM_REGS_SEG_NUM = 50
+
+};
+
+struct ql_nic_misc {
+	u32 rx_ring_count;
+	u32 tx_ring_count;
+	u32 intr_count;
+	u32 function;
+};
+
+struct ql_reg_dump {
+
+	/* segment 0 */
+	struct mpi_coredump_global_header mpi_global_header;
+
+	/* segment 16 */
+	struct mpi_coredump_segment_header nic_regs_seg_hdr;
+	u32 nic_regs[64];
+
+	/* segment 30 */
+	struct mpi_coredump_segment_header misc_nic_seg_hdr;
+	struct ql_nic_misc misc_nic_info;
+
+	/* segment 31 */
+	/* one interrupt state for each CQ */
+	struct mpi_coredump_segment_header intr_states_seg_hdr;
+	u32 intr_states[MAX_CPUS];
+
+	/* segment 32 */
+	/* 3 cam words each for 16 unicast,
+	 * 2 cam words for each of 32 multicast.
+	 */
+	struct mpi_coredump_segment_header cam_entries_seg_hdr;
+	u32 cam_entries[(16 * 3) + (32 * 3)];
+
+	/* segment 33 */
+	struct mpi_coredump_segment_header nic_routing_words_seg_hdr;
+	u32 nic_routing_words[16];
+
+	/* segment 34 */
+	struct mpi_coredump_segment_header ets_seg_hdr;
+	u32 ets[8+2];
 };
 
 /*
@@ -1398,6 +1601,8 @@ enum {
 	QL_ALLMULTI = 6,
 	QL_PORT_CFG = 7,
 	QL_CAM_RT_SET = 8,
+	QL_SELFTEST = 9,
+	QL_LB_LINK_UP = 10,
 };
 
 /* link_status bit definitions */
@@ -1505,6 +1710,7 @@ struct ql_adapter {
 
 	struct rx_ring rx_ring[MAX_RX_RINGS];
 	struct tx_ring tx_ring[MAX_TX_RINGS];
+	unsigned int lbq_buf_order;
 
 	int rx_csum;
 	u32 default_rx_queue;
@@ -1519,11 +1725,11 @@ struct ql_adapter {
 	u32 port_init;
 	u32 link_status;
 	u32 link_config;
+	u32 led_config;
 	u32 max_frame_size;
 
 	union flash_params flash;
 
-	struct net_device_stats stats;
 	struct workqueue_struct *workqueue;
 	struct delayed_work asic_reset_work;
 	struct delayed_work mpi_reset_work;
@@ -1533,6 +1739,7 @@ struct ql_adapter {
 	struct completion ide_completion;
 	struct nic_operations *nic_ops;
 	u16 device_id;
+	atomic_t lb_count;
 };
 
 /*
@@ -1611,10 +1818,22 @@ int ql_mb_get_fw_state(struct ql_adapter
 int ql_cam_route_initialize(struct ql_adapter *qdev);
 int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
 int ql_mb_about_fw(struct ql_adapter *qdev);
+int ql_wol(struct ql_adapter *qdev);
+int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol);
+int ql_mb_wol_mode(struct ql_adapter *qdev, u32 wol);
+int ql_mb_set_led_cfg(struct ql_adapter *qdev, u32 led_config);
+int ql_mb_get_led_cfg(struct ql_adapter *qdev);
 void ql_link_on(struct ql_adapter *qdev);
 void ql_link_off(struct ql_adapter *qdev);
 int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
+int ql_mb_get_port_cfg(struct ql_adapter *qdev);
+int ql_mb_set_port_cfg(struct ql_adapter *qdev);
 int ql_wait_fifo_empty(struct ql_adapter *qdev);
+void ql_gen_reg_dump(struct ql_adapter *qdev,
+			struct ql_reg_dump *mpi_coredump);
+netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev);
+void ql_check_lb_frame(struct ql_adapter *, struct sk_buff *);
+int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget);
 
 #if 1
 #define QL_ALL_DUMP
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_main.c linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -69,9 +69,9 @@ MODULE_PARM_DESC(debug, "Debug level (0=
 #define MSIX_IRQ 0
 #define MSI_IRQ 1
 #define LEG_IRQ 2
-static int irq_type = MSIX_IRQ;
-module_param(irq_type, int, MSIX_IRQ);
-MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
+static int qlge_irq_type = MSIX_IRQ;
+module_param(qlge_irq_type, int, MSIX_IRQ);
+MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
 
 static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
@@ -1025,6 +1025,11 @@ end:
 	return status;
 }
 
+static inline unsigned int ql_lbq_block_size(struct ql_adapter *qdev)
+{
+	return PAGE_SIZE << qdev->lbq_buf_order;
+}
+
 /* Get the next large buffer. */
 static struct bq_desc *ql_get_curr_lbuf(struct rx_ring *rx_ring)
 {
@@ -1036,6 +1041,28 @@ static struct bq_desc *ql_get_curr_lbuf(
 	return lbq_desc;
 }
 
+static struct bq_desc *ql_get_curr_lchunk(struct ql_adapter *qdev,
+		struct rx_ring *rx_ring)
+{
+	struct bq_desc *lbq_desc = ql_get_curr_lbuf(rx_ring);
+
+	pci_dma_sync_single_for_cpu(qdev->pdev,
+					pci_unmap_addr(lbq_desc, mapaddr),
+				    rx_ring->lbq_buf_size,
+					PCI_DMA_FROMDEVICE);
+
+	/* If it's the last chunk of our master page then
+	 * we unmap it.
+	 */
+	if ((lbq_desc->p.pg_chunk.offset + rx_ring->lbq_buf_size)
+					== ql_lbq_block_size(qdev))
+		pci_unmap_page(qdev->pdev,
+				lbq_desc->p.pg_chunk.map,
+				ql_lbq_block_size(qdev),
+				PCI_DMA_FROMDEVICE);
+	return lbq_desc;
+}
+
 /* Get the next small buffer. */
 static struct bq_desc *ql_get_curr_sbuf(struct rx_ring *rx_ring)
 {
@@ -1063,6 +1090,53 @@ static void ql_write_cq_idx(struct rx_ri
 	ql_write_db_reg(rx_ring->cnsmr_idx, rx_ring->cnsmr_idx_db_reg);
 }
 
+static int ql_get_next_chunk(struct ql_adapter *qdev, struct rx_ring *rx_ring,
+						struct bq_desc *lbq_desc)
+{
+	if (!rx_ring->pg_chunk.page) {
+		u64 map;
+		rx_ring->pg_chunk.page = alloc_pages(__GFP_COLD | __GFP_COMP |
+						GFP_ATOMIC,
+						qdev->lbq_buf_order);
+		if (unlikely(!rx_ring->pg_chunk.page)) {
+			QPRINTK(qdev, DRV, ERR,
+				"page allocation failed.\n");
+			return -ENOMEM;
+		}
+		rx_ring->pg_chunk.offset = 0;
+		map = pci_map_page(qdev->pdev, rx_ring->pg_chunk.page,
+					0, ql_lbq_block_size(qdev),
+					PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(qdev->pdev, map)) {
+			__free_pages(rx_ring->pg_chunk.page,
+					qdev->lbq_buf_order);
+			QPRINTK(qdev, DRV, ERR,
+				"PCI mapping failed.\n");
+			return -ENOMEM;
+		}
+		rx_ring->pg_chunk.map = map;
+		rx_ring->pg_chunk.va = page_address(rx_ring->pg_chunk.page);
+	}
+
+	/* Copy the current master pg_chunk info
+	 * to the current descriptor.
+	 */
+	lbq_desc->p.pg_chunk = rx_ring->pg_chunk;
+
+	/* Adjust the master page chunk for next
+	 * buffer get.
+	 */
+	rx_ring->pg_chunk.offset += rx_ring->lbq_buf_size;
+	if (rx_ring->pg_chunk.offset == ql_lbq_block_size(qdev)) {
+		rx_ring->pg_chunk.page = NULL;
+		lbq_desc->p.pg_chunk.last_flag = 1;
+	} else {
+		rx_ring->pg_chunk.va += rx_ring->lbq_buf_size;
+		get_page(rx_ring->pg_chunk.page);
+		lbq_desc->p.pg_chunk.last_flag = 0;
+	}
+	return 0;
+}
 /* Process (refill) a large buffer queue. */
 static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
@@ -1072,39 +1146,28 @@ static void ql_update_lbq(struct ql_adap
 	u64 map;
 	int i;
 
-	while (rx_ring->lbq_free_cnt > 16) {
+	while (rx_ring->lbq_free_cnt > 32) {
 		for (i = 0; i < 16; i++) {
 			QPRINTK(qdev, RX_STATUS, DEBUG,
 				"lbq: try cleaning clean_idx = %d.\n",
 				clean_idx);
 			lbq_desc = &rx_ring->lbq[clean_idx];
-			if (lbq_desc->p.lbq_page == NULL) {
-				QPRINTK(qdev, RX_STATUS, DEBUG,
-					"lbq: getting new page for index %d.\n",
-					lbq_desc->index);
-				lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
-				if (lbq_desc->p.lbq_page == NULL) {
-					rx_ring->lbq_clean_idx = clean_idx;
-					QPRINTK(qdev, RX_STATUS, ERR,
-						"Couldn't get a page.\n");
-					return;
-				}
-				map = pci_map_page(qdev->pdev,
-						   lbq_desc->p.lbq_page,
-						   0, PAGE_SIZE,
-						   PCI_DMA_FROMDEVICE);
-				if (pci_dma_mapping_error(qdev->pdev, map)) {
-					rx_ring->lbq_clean_idx = clean_idx;
-					put_page(lbq_desc->p.lbq_page);
-					lbq_desc->p.lbq_page = NULL;
-					QPRINTK(qdev, RX_STATUS, ERR,
-						"PCI mapping failed.\n");
+			if (ql_get_next_chunk(qdev, rx_ring, lbq_desc)) {
+				QPRINTK(qdev, IFUP, ERR,
+					"Could not get a page chunk.\n");
 					return;
 				}
+
+			map = lbq_desc->p.pg_chunk.map +
+				lbq_desc->p.pg_chunk.offset;
 				pci_unmap_addr_set(lbq_desc, mapaddr, map);
-				pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
+			pci_unmap_len_set(lbq_desc, maplen,
+					rx_ring->lbq_buf_size);
 				*lbq_desc->addr = cpu_to_le64(map);
-			}
+
+			pci_dma_sync_single_for_device(qdev->pdev, map,
+						rx_ring->lbq_buf_size,
+						PCI_DMA_FROMDEVICE);
 			clean_idx++;
 			if (clean_idx == rx_ring->lbq_len)
 				clean_idx = 0;
@@ -1147,7 +1210,7 @@ static void ql_update_sbq(struct ql_adap
 					sbq_desc->index);
 				sbq_desc->p.skb =
 				    netdev_alloc_skb(qdev->ndev,
-						     rx_ring->sbq_buf_size);
+						     SMALL_BUFFER_SIZE);
 				if (sbq_desc->p.skb == NULL) {
 					QPRINTK(qdev, PROBE, ERR,
 						"Couldn't get an skb.\n");
@@ -1157,8 +1220,8 @@ static void ql_update_sbq(struct ql_adap
 				skb_reserve(sbq_desc->p.skb, QLGE_SB_PAD);
 				map = pci_map_single(qdev->pdev,
 						     sbq_desc->p.skb->data,
-						     rx_ring->sbq_buf_size /
-						     2, PCI_DMA_FROMDEVICE);
+						     rx_ring->sbq_buf_size,
+						     PCI_DMA_FROMDEVICE);
 				if (pci_dma_mapping_error(qdev->pdev, map)) {
 					QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
 					rx_ring->sbq_clean_idx = clean_idx;
@@ -1168,7 +1231,7 @@ static void ql_update_sbq(struct ql_adap
 				}
 				pci_unmap_addr_set(sbq_desc, mapaddr, map);
 				pci_unmap_len_set(sbq_desc, maplen,
-						  rx_ring->sbq_buf_size / 2);
+						  rx_ring->sbq_buf_size);
 				*sbq_desc->addr = cpu_to_le64(map);
 			}
 
@@ -1480,27 +1543,24 @@ static struct sk_buff *ql_build_rx_skb(s
 			 * chain it to the header buffer's skb and let
 			 * it rip.
 			 */
-			lbq_desc = ql_get_curr_lbuf(rx_ring);
-			pci_unmap_page(qdev->pdev,
-				       pci_unmap_addr(lbq_desc,
-						      mapaddr),
-				       pci_unmap_len(lbq_desc, maplen),
-				       PCI_DMA_FROMDEVICE);
+			lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
 			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Chaining page to skb.\n");
-			skb_fill_page_desc(skb, 0, lbq_desc->p.lbq_page,
-					   0, length);
+				"Chaining page at offset = %d,"
+				"for %d bytes  to skb.\n",
+				lbq_desc->p.pg_chunk.offset, length);
+			skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page,
+						lbq_desc->p.pg_chunk.offset,
+						length);
 			skb->len += length;
 			skb->data_len += length;
 			skb->truesize += length;
-			lbq_desc->p.lbq_page = NULL;
 		} else {
 			/*
 			 * The headers and data are in a single large buffer. We
 			 * copy it to a new skb and let it go. This can happen with
 			 * jumbo mtu on a non-TCP/UDP frame.
 			 */
-			lbq_desc = ql_get_curr_lbuf(rx_ring);
+			lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
 			skb = netdev_alloc_skb(qdev->ndev, length);
 			if (skb == NULL) {
 				QPRINTK(qdev, PROBE, DEBUG,
@@ -1515,13 +1575,14 @@ static struct sk_buff *ql_build_rx_skb(s
 			skb_reserve(skb, NET_IP_ALIGN);
 			QPRINTK(qdev, RX_STATUS, DEBUG,
 				"%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", length);
-			skb_fill_page_desc(skb, 0, lbq_desc->p.lbq_page,
-					   0, length);
+			skb_fill_page_desc(skb, 0,
+						lbq_desc->p.pg_chunk.page,
+						lbq_desc->p.pg_chunk.offset,
+						length);
 			skb->len += length;
 			skb->data_len += length;
 			skb->truesize += length;
 			length -= length;
-			lbq_desc->p.lbq_page = NULL;
 			__pskb_pull_tail(skb,
 				(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ?
 				VLAN_ETH_HLEN : ETH_HLEN);
@@ -1538,8 +1599,7 @@ static struct sk_buff *ql_build_rx_skb(s
 		 *         frames.  If the MTU goes up we could
 		 *          eventually be in trouble.
 		 */
-		int size, offset, i = 0;
-		__le64 *bq, bq_array[8];
+		int size, i = 0;
 		sbq_desc = ql_get_curr_sbuf(rx_ring);
 		pci_unmap_single(qdev->pdev,
 				 pci_unmap_addr(sbq_desc, mapaddr),
@@ -1558,37 +1618,25 @@ static struct sk_buff *ql_build_rx_skb(s
 			QPRINTK(qdev, RX_STATUS, DEBUG,
 				"%d bytes of headers & data in chain of large.\n", length);
 			skb = sbq_desc->p.skb;
-			bq = &bq_array[0];
-			memcpy(bq, skb->data, sizeof(bq_array));
 			sbq_desc->p.skb = NULL;
 			skb_reserve(skb, NET_IP_ALIGN);
-		} else {
-			QPRINTK(qdev, RX_STATUS, DEBUG,
-				"Headers in small, %d bytes of data in chain of large.\n", length);
-			bq = (__le64 *)sbq_desc->p.skb->data;
 		}
 		while (length > 0) {
-			lbq_desc = ql_get_curr_lbuf(rx_ring);
-			pci_unmap_page(qdev->pdev,
-				       pci_unmap_addr(lbq_desc,
-						      mapaddr),
-				       pci_unmap_len(lbq_desc,
-						     maplen),
-				       PCI_DMA_FROMDEVICE);
-			size = (length < PAGE_SIZE) ? length : PAGE_SIZE;
-			offset = 0;
+			lbq_desc = ql_get_curr_lchunk(qdev, rx_ring);
+			size = (length < rx_ring->lbq_buf_size) ? length :
+				rx_ring->lbq_buf_size;
 
 			QPRINTK(qdev, RX_STATUS, DEBUG,
 				"Adding page %d to skb for %d bytes.\n",
 				i, size);
-			skb_fill_page_desc(skb, i, lbq_desc->p.lbq_page,
-					   offset, size);
+			skb_fill_page_desc(skb, i,
+						lbq_desc->p.pg_chunk.page,
+						lbq_desc->p.pg_chunk.offset,
+						size);
 			skb->len += size;
 			skb->data_len += size;
 			skb->truesize += size;
 			length -= size;
-			lbq_desc->p.lbq_page = NULL;
-			bq++;
 			i++;
 		}
 		__pskb_pull_tail(skb, (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) ?
@@ -1613,6 +1661,7 @@ static void ql_process_mac_rx_intr(struc
 	if (unlikely(!skb)) {
 		QPRINTK(qdev, RX_STATUS, DEBUG,
 			"No skb available, drop packet.\n");
+		rx_ring->rx_dropped++;
 		return;
 	}
 
@@ -1621,6 +1670,7 @@ static void ql_process_mac_rx_intr(struc
 		QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
 					ib_mac_rsp->flags2);
 		dev_kfree_skb_any(skb);
+		rx_ring->rx_errors++;
 		return;
 	}
 
@@ -1629,6 +1679,14 @@ static void ql_process_mac_rx_intr(struc
 	 */
 	if (skb->len > ndev->mtu + ETH_HLEN) {
 		dev_kfree_skb_any(skb);
+		rx_ring->rx_dropped++;
+		return;
+	}
+
+	/* loopback self test for ethtool */
+	if (test_bit(QL_SELFTEST, &qdev->flags)) {
+		ql_check_lb_frame(qdev, skb);
+		dev_kfree_skb_any(skb);
 		return;
 	}
 
@@ -1642,6 +1700,7 @@ static void ql_process_mac_rx_intr(struc
 			IB_MAC_IOCB_RSP_M_REG ? "Registered" : "",
 			(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
 			IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
+		rx_ring->rx_multicast++;
 	}
 	if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) {
 		QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n");
@@ -1673,8 +1732,8 @@ static void ql_process_mac_rx_intr(struc
 		}
 	}
 
-	qdev->stats.rx_packets++;
-	qdev->stats.rx_bytes += skb->len;
+	rx_ring->rx_packets++;
+	rx_ring->rx_bytes += skb->len;
 	skb_record_rx_queue(skb, rx_ring->cq_id);
 	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		if (qdev->vlgrp &&
@@ -1705,8 +1764,8 @@ static void ql_process_mac_tx_intr(struc
 	tx_ring = &qdev->tx_ring[mac_rsp->txq_idx];
 	tx_ring_desc = &tx_ring->q[mac_rsp->tid];
 	ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt);
-	qdev->stats.tx_bytes += (tx_ring_desc->skb)->len;
-	qdev->stats.tx_packets++;
+	tx_ring->tx_bytes += (tx_ring_desc->skb)->len;
+	tx_ring->tx_packets++;
 	dev_kfree_skb(tx_ring_desc->skb);
 	tx_ring_desc->skb = NULL;
 
@@ -1929,7 +1988,7 @@ static int ql_napi_poll_msix(struct napi
 	return work_done;
 }
 
-static void ql_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
+static void qlge_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
@@ -1945,7 +2004,7 @@ static void ql_vlan_rx_register(struct n
 	}
 }
 
-static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
+static void qlge_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	u32 enable_bit = MAC_ADDR_E;
@@ -1961,7 +2020,7 @@ static void ql_vlan_rx_add_vid(struct ne
 	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
 
-static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
+static void qlge_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	u32 enable_bit = 0;
@@ -2046,12 +2105,12 @@ static irqreturn_t qlge_isr(int irq, voi
 	 */
 	var = ql_read32(qdev, ISR1);
 	if (var & intr_context->irq_mask) {
-				QPRINTK(qdev, INTR, INFO,
+		QPRINTK(qdev, INTR, INFO,
 			"Waking handler for rx_ring[0].\n");
 		ql_disable_completion_interrupt(qdev, intr_context->intr);
-					napi_schedule(&rx_ring->napi);
-				work_done++;
-			}
+		napi_schedule(&rx_ring->napi);
+		work_done++;
+	}
 	ql_enable_completion_interrupt(qdev, intr_context->intr);
 	return work_done ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -2149,6 +2208,7 @@ static netdev_tx_t qlge_send(struct sk_b
 			__func__, tx_ring_idx);
 		netif_stop_subqueue(ndev, tx_ring->wq_id);
 		atomic_inc(&tx_ring->queue_stopped);
+		tx_ring->tx_errors++;
 		return NETDEV_TX_BUSY;
 	}
 	tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
@@ -2183,6 +2243,7 @@ static netdev_tx_t qlge_send(struct sk_b
 			NETDEV_TX_OK) {
 		QPRINTK(qdev, TX_QUEUED, ERR,
 				"Could not map the segments.\n");
+		tx_ring->tx_errors++;
 		return NETDEV_TX_BUSY;
 	}
 	QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr);
@@ -2199,6 +2260,7 @@ static netdev_tx_t qlge_send(struct sk_b
 	return NETDEV_TX_OK;
 }
 
+
 static void ql_free_shadow_space(struct ql_adapter *qdev)
 {
 	if (qdev->rx_ring_shadow_reg_area) {
@@ -2285,8 +2347,8 @@ static int ql_alloc_tx_resources(struct
 	    pci_alloc_consistent(qdev->pdev, tx_ring->wq_size,
 				 &tx_ring->wq_base_dma);
 
-	if ((tx_ring->wq_base == NULL)
-		|| tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
+	if ((tx_ring->wq_base == NULL) ||
+	    tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
 		QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
 		return -ENOMEM;
 	}
@@ -2304,20 +2366,29 @@ err:
 
 static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
-	int i;
 	struct bq_desc *lbq_desc;
 
-	for (i = 0; i < rx_ring->lbq_len; i++) {
-		lbq_desc = &rx_ring->lbq[i];
-		if (lbq_desc->p.lbq_page) {
+	uint32_t  curr_idx, clean_idx;
+
+	curr_idx = rx_ring->lbq_curr_idx;
+	clean_idx = rx_ring->lbq_clean_idx;
+	while (curr_idx != clean_idx) {
+		lbq_desc = &rx_ring->lbq[curr_idx];
+
+		if (lbq_desc->p.pg_chunk.last_flag) {
 			pci_unmap_page(qdev->pdev,
-				       pci_unmap_addr(lbq_desc, mapaddr),
-				       pci_unmap_len(lbq_desc, maplen),
+				lbq_desc->p.pg_chunk.map,
+				ql_lbq_block_size(qdev),
 				       PCI_DMA_FROMDEVICE);
-
-			put_page(lbq_desc->p.lbq_page);
-			lbq_desc->p.lbq_page = NULL;
+			lbq_desc->p.pg_chunk.last_flag = 0;
 		}
+
+		put_page(lbq_desc->p.pg_chunk.page);
+		lbq_desc->p.pg_chunk.page = NULL;
+
+		if (++curr_idx == rx_ring->lbq_len)
+			curr_idx = 0;
+
 	}
 }
 
@@ -2615,6 +2686,7 @@ static int ql_start_rx_ring(struct ql_ad
 	/* Set up the shadow registers for this ring. */
 	rx_ring->prod_idx_sh_reg = shadow_reg;
 	rx_ring->prod_idx_sh_reg_dma = shadow_reg_dma;
+	*rx_ring->prod_idx_sh_reg = 0;
 	shadow_reg += sizeof(u64);
 	shadow_reg_dma += sizeof(u64);
 	rx_ring->lbq_base_indirect = shadow_reg;
@@ -2692,7 +2764,7 @@ static int ql_start_rx_ring(struct ql_ad
 		cqicb->sbq_addr =
 		    cpu_to_le64(rx_ring->sbq_base_indirect_dma);
 		cqicb->sbq_buf_size =
-		    cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
+		    cpu_to_le16((u16)(rx_ring->sbq_buf_size));
 		bq_len = (rx_ring->sbq_len == 65536) ? 0 :
 			(u16) rx_ring->sbq_len;
 		cqicb->sbq_len = cpu_to_le16(bq_len);
@@ -2798,7 +2870,7 @@ static void ql_enable_msix(struct ql_ada
 	int i, err;
 
 	/* Get the MSIX vectors. */
-	if (irq_type == MSIX_IRQ) {
+	if (qlge_irq_type == MSIX_IRQ) {
 		/* Try to alloc space for the msix struct,
 		 * if it fails then go to MSI/legacy.
 		 */
@@ -2806,7 +2878,7 @@ static void ql_enable_msix(struct ql_ada
 					    sizeof(struct msix_entry),
 					    GFP_KERNEL);
 		if (!qdev->msi_x_entry) {
-			irq_type = MSI_IRQ;
+			qlge_irq_type = MSI_IRQ;
 			goto msi;
 		}
 
@@ -2829,7 +2901,7 @@ static void ql_enable_msix(struct ql_ada
 			QPRINTK(qdev, IFUP, WARNING,
 				"MSI-X Enable failed, trying MSI.\n");
 			qdev->intr_count = 1;
-			irq_type = MSI_IRQ;
+			qlge_irq_type = MSI_IRQ;
 		} else if (err == 0) {
 			set_bit(QL_MSIX_ENABLED, &qdev->flags);
 			QPRINTK(qdev, IFUP, INFO,
@@ -2840,7 +2912,7 @@ static void ql_enable_msix(struct ql_ada
 	}
 msi:
 	qdev->intr_count = 1;
-	if (irq_type == MSI_IRQ) {
+	if (qlge_irq_type == MSI_IRQ) {
 		if (!pci_enable_msi(qdev->pdev)) {
 			set_bit(QL_MSI_ENABLED, &qdev->flags);
 			QPRINTK(qdev, IFUP, INFO,
@@ -2848,7 +2920,7 @@ msi:
 			return;
 		}
 	}
-	irq_type = LEG_IRQ;
+	qlge_irq_type = LEG_IRQ;
 	QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
 }
 
@@ -3268,7 +3340,7 @@ static int ql_adapter_initialize(struct
 	ql_write32(qdev, FSC, mask | value);
 
 	ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
-		min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
+		min(SMALL_BUF_MAP_SIZE, MAX_SPLIT_SIZE));
 
 	/* Set RX packet routing to use port/pci function on which the
 	 * packet arrived on in addition to usual frame routing.
@@ -3276,6 +3348,22 @@ static int ql_adapter_initialize(struct
 	 * the same MAC address.
 	 */
 	ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
+	/* Reroute all packets to our Interface.
+	 * They may have been routed to MPI firmware
+	 * due to WOL.
+	 */
+	value = ql_read32(qdev, MGMT_RCV_CFG);
+	value &= ~MGMT_RCV_CFG_RM;
+	mask = 0xffff0000;
+
+	/* Sticky reg needs clearing due to WOL. */
+	ql_write32(qdev, MGMT_RCV_CFG, mask);
+	ql_write32(qdev, MGMT_RCV_CFG, mask | value);
+
+	/* Default WOL is enable on Mezz cards */
+	if (qdev->pdev->subsystem_device == 0x0068 ||
+			qdev->pdev->subsystem_device == 0x0180)
+		qdev->wol = WAKE_MAGIC;
 
 	/* Start up the rx queues. */
 	for (i = 0; i < qdev->rx_ring_count; i++) {
@@ -3310,10 +3398,8 @@ static int ql_adapter_initialize(struct
 
 	/* Initialize the port and set the max framesize. */
 	status = qdev->nic_ops->port_initialize(qdev);
-       if (status) {
-              QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
-              return status;
-       }
+	if (status)
+		QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
 
 	/* Set up the MAC address and frame routing filter. */
 	status = ql_cam_route_initialize(qdev);
@@ -3392,6 +3478,52 @@ static void ql_display_dev_info(struct n
 	QPRINTK(qdev, PROBE, INFO, "MAC address %pM\n", ndev->dev_addr);
 }
 
+int ql_wol(struct ql_adapter *qdev)
+{
+	int status = 0;
+	u32 wol = MB_WOL_DISABLE;
+
+	/* The CAM is still intact after a reset, but if we
+	 * are doing WOL, then we may need to program the
+	 * routing regs. We would also need to issue the mailbox
+	 * commands to instruct the MPI what to do per the ethtool
+	 * settings.
+	 */
+
+	if (qdev->wol & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY | WAKE_UCAST |
+			WAKE_MCAST | WAKE_BCAST)) {
+		QPRINTK(qdev, IFDOWN, ERR,
+			"Unsupported WOL paramter. qdev->wol = 0x%x.\n",
+			qdev->wol);
+		return -EINVAL;
+	}
+
+	if (qdev->wol & WAKE_MAGIC) {
+		status = ql_mb_wol_set_magic(qdev, 1);
+		if (status) {
+			QPRINTK(qdev, IFDOWN, ERR,
+				"Failed to set magic packet on %s.\n",
+				qdev->ndev->name);
+			return status;
+		} else
+			QPRINTK(qdev, DRV, INFO,
+				"Enabled magic packet successfully on %s.\n",
+				qdev->ndev->name);
+
+		wol |= MB_WOL_MAGIC_PKT;
+	}
+
+	if (qdev->wol) {
+		wol |= MB_WOL_MODE_ON;
+		status = ql_mb_wol_mode(qdev, wol);
+		QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
+			(status == 0) ? "Sucessfully set" : "Failed", wol,
+			qdev->ndev->name);
+	}
+
+	return status;
+}
+
 static int ql_adapter_down(struct ql_adapter *qdev)
 {
 	int i, status = 0;
@@ -3497,6 +3629,10 @@ static int ql_configure_rings(struct ql_
 	struct rx_ring *rx_ring;
 	struct tx_ring *tx_ring;
 	int cpu_cnt = min(MAX_CPUS, (int)num_online_cpus());
+	unsigned int lbq_buf_len = (qdev->ndev->mtu > 1500) ?
+		LARGE_BUFFER_MAX_SIZE : LARGE_BUFFER_MIN_SIZE;
+
+	qdev->lbq_buf_order = get_order(lbq_buf_len);
 
 	/* In a perfect world we have one RSS ring for each CPU
 	 * and each has it's own vector.  To do that we ask for
@@ -3544,11 +3680,14 @@ static int ql_configure_rings(struct ql_
 			rx_ring->lbq_len = NUM_LARGE_BUFFERS;
 			rx_ring->lbq_size =
 			    rx_ring->lbq_len * sizeof(__le64);
-			rx_ring->lbq_buf_size = LARGE_BUFFER_SIZE;
+			rx_ring->lbq_buf_size = (u16)lbq_buf_len;
+			QPRINTK(qdev, IFUP, DEBUG,
+				"lbq_buf_size %d, order = %d\n",
+				rx_ring->lbq_buf_size, qdev->lbq_buf_order);
 			rx_ring->sbq_len = NUM_SMALL_BUFFERS;
 			rx_ring->sbq_size =
 			    rx_ring->sbq_len * sizeof(__le64);
-			rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2;
+			rx_ring->sbq_buf_size = SMALL_BUF_MAP_SIZE;
 			rx_ring->type = RX_Q;
 		} else {
 			/*
@@ -3575,6 +3714,10 @@ static int qlge_open(struct net_device *
 	int err = 0;
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
+	err = ql_adapter_reset(qdev);
+	if (err)
+		return err;
+
 	err = ql_configure_rings(qdev);
 	if (err)
 		return err;
@@ -3594,14 +3737,63 @@ error_up:
 	return err;
 }
 
+static int ql_change_rx_buffers(struct ql_adapter *qdev)
+{
+	struct rx_ring *rx_ring;
+	int i, status;
+	u32 lbq_buf_len;
+
+	/* Wait for an oustanding reset to complete. */
+	if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) {
+		int i = 3;
+		while (i-- && !test_bit(QL_ADAPTER_UP, &qdev->flags)) {
+			QPRINTK(qdev, IFUP, ERR,
+				 "Waiting for adapter UP...\n");
+			ssleep(1);
+		}
+
+		if (!i) {
+			QPRINTK(qdev, IFUP, ERR,
+			 "Timed out waiting for adapter UP\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	status = ql_adapter_down(qdev);
+	if (status)
+		goto error;
+
+	/* Get the new rx buffer size. */
+	lbq_buf_len = (qdev->ndev->mtu > 1500) ?
+		LARGE_BUFFER_MAX_SIZE : LARGE_BUFFER_MIN_SIZE;
+	qdev->lbq_buf_order = get_order(lbq_buf_len);
+
+	for (i = 0; i < qdev->rss_ring_count; i++) {
+		rx_ring = &qdev->rx_ring[i];
+		/* Set the new size. */
+		rx_ring->lbq_buf_size = lbq_buf_len;
+	}
+
+	status = ql_adapter_up(qdev);
+	if (status)
+		goto error;
+
+	return status;
+error:
+	QPRINTK(qdev, IFUP, ALERT,
+		"Driver up/down cycle failed, closing device.\n");
+	set_bit(QL_ADAPTER_UP, &qdev->flags);
+	dev_close(qdev->ndev);
+	return status;
+}
+
 static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
+	int status;
 
 	if (ndev->mtu == 1500 && new_mtu == 9000) {
 		QPRINTK(qdev, IFUP, ERR, "Changing to jumbo MTU.\n");
-		queue_delayed_work(qdev->workqueue,
-				&qdev->mpi_port_cfg_work, 0);
 	} else if (ndev->mtu == 9000 && new_mtu == 1500) {
 		QPRINTK(qdev, IFUP, ERR, "Changing to normal MTU.\n");
 	} else if ((ndev->mtu == 1500 && new_mtu == 1500) ||
@@ -3609,15 +3801,60 @@ static int qlge_change_mtu(struct net_de
 		return 0;
 	} else
 		return -EINVAL;
+
+	queue_delayed_work(qdev->workqueue,
+			&qdev->mpi_port_cfg_work, 3*HZ);
+
+	if (!netif_running(qdev->ndev)) {
+		ndev->mtu = new_mtu;
+		return 0;
+	}
+
 	ndev->mtu = new_mtu;
-	return 0;
+	status = ql_change_rx_buffers(qdev);
+	if (status) {
+		QPRINTK(qdev, IFUP, ERR,
+			"Changing MTU failed.\n");
+	}
+
+	return status;
 }
 
 static struct net_device_stats *qlge_get_stats(struct net_device
 					       *ndev)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
-	return &qdev->stats;
+	struct rx_ring *rx_ring = &qdev->rx_ring[0];
+	struct tx_ring *tx_ring = &qdev->tx_ring[0];
+	unsigned long pkts, mcast, dropped, errors, bytes;
+	int i;
+
+	/* Get RX stats. */
+	pkts = mcast = dropped = errors = bytes = 0;
+	for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
+			pkts += rx_ring->rx_packets;
+			bytes += rx_ring->rx_bytes;
+			dropped += rx_ring->rx_dropped;
+			errors += rx_ring->rx_errors;
+			mcast += rx_ring->rx_multicast;
+	}
+	ndev->stats.rx_packets = pkts;
+	ndev->stats.rx_bytes = bytes;
+	ndev->stats.rx_dropped = dropped;
+	ndev->stats.rx_errors = errors;
+	ndev->stats.multicast = mcast;
+
+	/* Get TX stats. */
+	pkts = errors = bytes = 0;
+	for (i = 0; i < qdev->tx_ring_count; i++, tx_ring++) {
+			pkts += tx_ring->tx_packets;
+			bytes += tx_ring->tx_bytes;
+			errors += tx_ring->tx_errors;
+	}
+	ndev->stats.tx_packets = pkts;
+	ndev->stats.tx_bytes = bytes;
+	ndev->stats.tx_errors = errors;
+	return &ndev->stats;
 }
 
 static void qlge_set_multicast_list(struct net_device *ndev)
@@ -3714,9 +3951,6 @@ static int qlge_set_mac_address(struct n
 	struct sockaddr *addr = p;
 	int status;
 
-	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);
@@ -3868,8 +4102,7 @@ static int __devinit ql_init_device(stru
 				    struct net_device *ndev, int cards_found)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
-	int pos, err = 0;
-	u16 val16;
+	int err = 0;
 
 	memset((void *)qdev, 0, sizeof(*qdev));
 	err = pci_enable_device(pdev);
@@ -3881,18 +4114,12 @@ static int __devinit ql_init_device(stru
 	qdev->ndev = ndev;
 	qdev->pdev = pdev;
 	pci_set_drvdata(pdev, ndev);
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	if (pos <= 0) {
-		dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
-			"aborting.\n");
-		return pos;
-	} else {
-		pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
-		val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
-		val16 |= (PCI_EXP_DEVCTL_CERE |
-			  PCI_EXP_DEVCTL_NFERE |
-			  PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
-		pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
+
+	/* Set PCIe read request size */
+	err = pcie_set_readrq(pdev, 4096);
+	if (err) {
+		dev_err(&pdev->dev, "Set readrq failed.\n");
+		goto err_out1;
 	}
 
 	err = pci_request_regions(pdev, DRV_NAME);
@@ -3913,7 +4140,7 @@ static int __devinit ql_init_device(stru
 
 	if (err) {
 		dev_err(&pdev->dev, "No usable DMA configuration.\n");
-		goto err_out;
+		goto err_out2;
 	}
 
 	/* Set PCIe reset type for EEH to fundamental. */
@@ -3925,7 +4152,7 @@ static int __devinit ql_init_device(stru
 	if (!qdev->reg_base) {
 		dev_err(&pdev->dev, "Register mapping failed.\n");
 		err = -ENOMEM;
-		goto err_out;
+		goto err_out2;
 	}
 
 	qdev->doorbell_area_size = pci_resource_len(pdev, 3);
@@ -3935,14 +4162,14 @@ static int __devinit ql_init_device(stru
 	if (!qdev->doorbell_area) {
 		dev_err(&pdev->dev, "Doorbell register mapping failed.\n");
 		err = -ENOMEM;
-		goto err_out;
+		goto err_out2;
 	}
 
 	err = ql_get_board_info(qdev);
 	if (err) {
 		dev_err(&pdev->dev, "Register access failed.\n");
 		err = -EIO;
-		goto err_out;
+		goto err_out2;
 	}
 	qdev->msg_enable = netif_msg_init(debug, default_msg);
 	spin_lock_init(&qdev->hw_lock);
@@ -3952,7 +4179,7 @@ static int __devinit ql_init_device(stru
 	err = qdev->nic_ops->get_flash(qdev);
 	if (err) {
 		dev_err(&pdev->dev, "Invalid FLASH.\n");
-		goto err_out;
+		goto err_out2;
 	}
 
 	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
@@ -3985,13 +4212,13 @@ static int __devinit ql_init_device(stru
 			 DRV_NAME, DRV_VERSION);
 	}
 	return 0;
-err_out:
+err_out2:
 	ql_release_all(pdev);
+err_out1:
 	pci_disable_device(pdev);
 	return err;
 }
 
-
 static const struct net_device_ops qlge_netdev_ops = {
 	.ndo_open		= qlge_open,
 	.ndo_stop		= qlge_close,
@@ -4002,9 +4229,9 @@ static const struct net_device_ops qlge_
 	.ndo_set_mac_address	= qlge_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_tx_timeout		= qlge_tx_timeout,
-	.ndo_vlan_rx_register	= ql_vlan_rx_register,
-	.ndo_vlan_rx_add_vid	= ql_vlan_rx_add_vid,
-	.ndo_vlan_rx_kill_vid	= ql_vlan_rx_kill_vid,
+	.ndo_vlan_rx_register	= qlge_vlan_rx_register,
+	.ndo_vlan_rx_add_vid	= qlge_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= qlge_vlan_rx_kill_vid,
 };
 
 static int __devinit qlge_probe(struct pci_dev *pdev,
@@ -4060,10 +4287,21 @@ static int __devinit qlge_probe(struct p
 	}
 	ql_link_off(qdev);
 	ql_display_dev_info(ndev);
+	atomic_set(&qdev->lb_count, 0);
 	cards_found++;
 	return 0;
 }
 
+netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev)
+{
+	return qlge_send(skb, ndev);
+}
+
+int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget)
+{
+	return ql_clean_inbound_rx_ring(rx_ring, budget);
+}
+
 static void __devexit qlge_remove(struct pci_dev *pdev)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
@@ -4193,6 +4431,7 @@ static int qlge_suspend(struct pci_dev *
 			return err;
 	}
 
+	ql_wol(qdev);
 	err = pci_save_state(pdev);
 	if (err)
 		return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_mpi.c linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_mpi.c
--- linux-libre-2.6.32-gnu1/drivers/net/qlge/qlge_mpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/qlge/qlge_mpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,25 +1,5 @@
 #include "qlge.h"
 
-static void ql_display_mb_sts(struct ql_adapter *qdev,
-						struct mbox_params *mbcp)
-{
-	int i;
-	static char *err_sts[] = {
-		"Command Complete",
-		"Command Not Supported",
-		"Host Interface Error",
-		"Checksum Error",
-		"Unused Completion Status",
-		"Test Failed",
-		"Command Parameter Error"};
-
-	QPRINTK(qdev, DRV, DEBUG, "%s.\n",
-		err_sts[mbcp->mbox_out[0] & 0x0000000f]);
-	for (i = 0; i < mbcp->out_count; i++)
-		QPRINTK(qdev, DRV, DEBUG, "mbox_out[%d] = 0x%.08x.\n",
-				i, mbcp->mbox_out[i]);
-}
-
 int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
 {
 	int status;
@@ -317,6 +297,7 @@ static void ql_init_fw_done(struct ql_ad
 	} else {
 		QPRINTK(qdev, DRV, ERR, "Firmware Revision  = 0x%.08x.\n",
 			mbcp->mbox_out[1]);
+		qdev->fw_rev_id = mbcp->mbox_out[1];
 		status = ql_cam_route_initialize(qdev);
 		if (status)
 			QPRINTK(qdev, IFUP, ERR,
@@ -446,6 +427,9 @@ static int ql_mpi_handler(struct ql_adap
 		ql_aen_lost(qdev, mbcp);
 		break;
 
+	case AEN_DCBX_CHG:
+		/* Need to support AEN 8110 */
+		break;
 	default:
 		QPRINTK(qdev, DRV, ERR,
 			"Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
@@ -537,7 +521,6 @@ done:
 					MB_CMD_STS_GOOD) &&
 		((mbcp->mbox_out[0] & 0x0000f000) !=
 					MB_CMD_STS_INTRMDT)) {
-		ql_display_mb_sts(qdev, mbcp);
 		status = -EIO;
 	}
 end:
@@ -655,7 +638,7 @@ int ql_mb_idc_ack(struct ql_adapter *qde
  * for the current port.
  * Most likely will block.
  */
-static int ql_mb_set_port_cfg(struct ql_adapter *qdev)
+int ql_mb_set_port_cfg(struct ql_adapter *qdev)
 {
 	struct mbox_params mbc;
 	struct mbox_params *mbcp = &mbc;
@@ -690,7 +673,7 @@ static int ql_mb_set_port_cfg(struct ql_
  * for the current port.
  * Most likely will block.
  */
-static int ql_mb_get_port_cfg(struct ql_adapter *qdev)
+int ql_mb_get_port_cfg(struct ql_adapter *qdev)
 {
 	struct mbox_params mbc;
 	struct mbox_params *mbcp = &mbc;
@@ -720,6 +703,76 @@ static int ql_mb_get_port_cfg(struct ql_
 	return status;
 }
 
+int ql_mb_wol_mode(struct ql_adapter *qdev, u32 wol)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 2;
+	mbcp->out_count = 1;
+
+	mbcp->mbox_in[0] = MB_CMD_SET_WOL_MODE;
+	mbcp->mbox_in[1] = wol;
+
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed to set WOL mode.\n");
+		status = -EIO;
+	}
+	return status;
+}
+
+int ql_mb_wol_set_magic(struct ql_adapter *qdev, u32 enable_wol)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status;
+	u8 *addr = qdev->ndev->dev_addr;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 8;
+	mbcp->out_count = 1;
+
+	mbcp->mbox_in[0] = MB_CMD_SET_WOL_MAGIC;
+	if (enable_wol) {
+		mbcp->mbox_in[1] = (u32)addr[0];
+		mbcp->mbox_in[2] = (u32)addr[1];
+		mbcp->mbox_in[3] = (u32)addr[2];
+		mbcp->mbox_in[4] = (u32)addr[3];
+		mbcp->mbox_in[5] = (u32)addr[4];
+		mbcp->mbox_in[6] = (u32)addr[5];
+		mbcp->mbox_in[7] = 0;
+	} else {
+		mbcp->mbox_in[1] = 0;
+		mbcp->mbox_in[2] = 1;
+		mbcp->mbox_in[3] = 1;
+		mbcp->mbox_in[4] = 1;
+		mbcp->mbox_in[5] = 1;
+		mbcp->mbox_in[6] = 1;
+		mbcp->mbox_in[7] = 0;
+	}
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed to set WOL mode.\n");
+		status = -EIO;
+	}
+	return status;
+}
+
 /* IDC - Inter Device Communication...
  * Some firmware commands require consent of adjacent FCOE
  * function.  This function waits for the OK, or a
@@ -769,6 +822,61 @@ static int ql_idc_wait(struct ql_adapter
 	return status;
 }
 
+int ql_mb_set_led_cfg(struct ql_adapter *qdev, u32 led_config)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 2;
+	mbcp->out_count = 1;
+
+	mbcp->mbox_in[0] = MB_CMD_SET_LED_CFG;
+	mbcp->mbox_in[1] = led_config;
+
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed to set LED Configuration.\n");
+		status = -EIO;
+	}
+
+	return status;
+}
+
+int ql_mb_get_led_cfg(struct ql_adapter *qdev)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 1;
+	mbcp->out_count = 2;
+
+	mbcp->mbox_in[0] = MB_CMD_GET_LED_CFG;
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed to get LED Configuration.\n");
+		status = -EIO;
+	} else
+		qdev->led_config = mbcp->mbox_out[1];
+
+	return status;
+}
+
 int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
 {
 	struct mbox_params mbc;
@@ -930,8 +1038,11 @@ void ql_mpi_idc_work(struct work_struct
 	int status;
 	struct mbox_params *mbcp = &qdev->idc_mbc;
 	u32 aen;
+	int timeout;
 
+	rtnl_lock();
 	aen = mbcp->mbox_out[1] >> 16;
+	timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
 
 	switch (aen) {
 	default:
@@ -939,22 +1050,61 @@ void ql_mpi_idc_work(struct work_struct
 			"Bug: Unhandled IDC action.\n");
 		break;
 	case MB_CMD_PORT_RESET:
-	case MB_CMD_SET_PORT_CFG:
 	case MB_CMD_STOP_FW:
 		ql_link_off(qdev);
+	case MB_CMD_SET_PORT_CFG:
 		/* Signal the resulting link up AEN
 		 * that the frame routing and mac addr
 		 * needs to be set.
 		 * */
 		set_bit(QL_CAM_RT_SET, &qdev->flags);
-		rtnl_lock();
-		status = ql_mb_idc_ack(qdev);
-		rtnl_unlock();
-		if (status) {
-			QPRINTK(qdev, DRV, ERR,
-			"Bug: No pending IDC!\n");
+		/* Do ACK if required */
+		if (timeout) {
+			status = ql_mb_idc_ack(qdev);
+			if (status)
+				QPRINTK(qdev, DRV, ERR,
+					"Bug: No pending IDC!\n");
+		} else {
+			QPRINTK(qdev, DRV, DEBUG,
+				    "IDC ACK not required\n");
+			status = 0; /* success */
+		}
+		break;
+
+	/* These sub-commands issued by another (FCoE)
+	 * function are requesting to do an operation
+	 * on the shared resource (MPI environment).
+	 * We currently don't issue these so we just
+	 * ACK the request.
+	 */
+	case MB_CMD_IOP_RESTART_MPI:
+	case MB_CMD_IOP_PREP_LINK_DOWN:
+		/* Drop the link, reload the routing
+		 * table when link comes up.
+		 */
+		ql_link_off(qdev);
+		set_bit(QL_CAM_RT_SET, &qdev->flags);
+		/* Fall through. */
+	case MB_CMD_IOP_DVR_START:
+	case MB_CMD_IOP_FLASH_ACC:
+	case MB_CMD_IOP_CORE_DUMP_MPI:
+	case MB_CMD_IOP_PREP_UPDATE_MPI:
+	case MB_CMD_IOP_COMP_UPDATE_MPI:
+	case MB_CMD_IOP_NONE:	/*  an IDC without params */
+		/* Do ACK if required */
+		if (timeout) {
+			status = ql_mb_idc_ack(qdev);
+			if (status)
+				QPRINTK(qdev, DRV, ERR,
+				    "Bug: No pending IDC!\n");
+		} else {
+			QPRINTK(qdev, DRV, DEBUG,
+			    "IDC ACK not required\n");
+			status = 0; /* success */
 		}
+		break;
 	}
+	rtnl_unlock();
 }
 
 void ql_mpi_work(struct work_struct *work)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/r6040.c linux-libre-2.6.33-gnu1/drivers/net/r6040.c
--- linux-libre-2.6.32-gnu1/drivers/net/r6040.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/r6040.c	2010-02-24 13:52:17.000000000 -0500
@@ -842,7 +842,7 @@ static int r6040_open(struct net_device
 	int ret;
 
 	/* Request IRQ and Register interrupt handler */
-	ret = request_irq(dev->irq, &r6040_interrupt,
+	ret = request_irq(dev->irq, r6040_interrupt,
 		IRQF_SHARED, dev->name, dev);
 	if (ret)
 		return ret;
@@ -958,8 +958,7 @@ static void r6040_multicast_list(struct
 	}
 	/* Too many multicast addresses
 	 * accept all traffic */
-	else if ((dev->mc_count > MCAST_MAX)
-		|| (dev->flags & IFF_ALLMULTI))
+	else if ((dev->mc_count > MCAST_MAX) || (dev->flags & IFF_ALLMULTI))
 		reg |= 0x0020;
 
 	iowrite16(reg, ioaddr);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/r8169.c linux-libre-2.6.33-gnu1/drivers/net/r8169.c
--- linux-libre-2.6.32-gnu1/drivers/net/r8169.c	2013-05-03 14:01:06.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/r8169.c	2013-05-03 12:08:24.000000000 -0400
@@ -794,7 +794,7 @@ static int rtl8169_set_wol(struct net_de
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned int i;
-	static struct {
+	static const struct {
 		u32 opt;
 		u16 reg;
 		u8  mask;
@@ -1277,7 +1277,7 @@ static void rtl8169_get_mac_version(stru
 	 *
 	 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
 	 */
-	const struct {
+	static const struct {
 		u32 mask;
 		u32 val;
 		int mac_version;
@@ -1351,7 +1351,7 @@ struct phy_reg {
 	u16 val;
 };
 
-static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len)
+static void rtl_phy_write(void __iomem *ioaddr, const struct phy_reg *regs, int len)
 {
 	while (len-- > 0) {
 		mdio_write(ioaddr, regs->reg, regs->val);
@@ -1361,7 +1361,7 @@ static void rtl_phy_write(void __iomem *
 
 static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x06, 0x006e },
 		{ 0x08, 0x0708 },
@@ -1428,7 +1428,7 @@ static void rtl8169s_hw_phy_config(void
 
 static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0002 },
 		{ 0x01, 0x90d0 },
 		{ 0x1f, 0x0000 }
@@ -1457,7 +1457,7 @@ static void rtl8169scd_hw_phy_config_qui
 static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
 				     void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x04, 0x0000 },
 		{ 0x03, 0x00a1 },
@@ -1504,7 +1504,7 @@ static void rtl8169scd_hw_phy_config(str
 
 static void rtl8169sce_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x04, 0x0000 },
 		{ 0x03, 0x00a1 },
@@ -1557,7 +1557,7 @@ static void rtl8169sce_hw_phy_config(voi
 
 static void rtl8168bb_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x10, 0xf41b },
 		{ 0x1f, 0x0000 }
 	};
@@ -1570,7 +1570,7 @@ static void rtl8168bb_hw_phy_config(void
 
 static void rtl8168bef_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x10, 0xf41b },
 		{ 0x1f, 0x0000 }
@@ -1581,7 +1581,7 @@ static void rtl8168bef_hw_phy_config(voi
 
 static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0000 },
 		{ 0x1d, 0x0f00 },
 		{ 0x1f, 0x0002 },
@@ -1594,7 +1594,7 @@ static void rtl8168cp_1_hw_phy_config(vo
 
 static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x1d, 0x3d98 },
 		{ 0x1f, 0x0000 }
@@ -1609,7 +1609,7 @@ static void rtl8168cp_2_hw_phy_config(vo
 
 static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x12, 0x2300 },
 		{ 0x1f, 0x0002 },
@@ -1638,7 +1638,7 @@ static void rtl8168c_1_hw_phy_config(voi
 
 static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x12, 0x2300 },
 		{ 0x03, 0x802f },
@@ -1666,7 +1666,7 @@ static void rtl8168c_2_hw_phy_config(voi
 
 static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0001 },
 		{ 0x12, 0x2300 },
 		{ 0x1d, 0x3d98 },
@@ -1697,7 +1697,7 @@ static void rtl8168c_4_hw_phy_config(voi
 
 static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0002 },
 		{ 0x10, 0x0008 },
 		{ 0x0d, 0x006c },
@@ -1758,7 +1758,7 @@ static void rtl8168d_3_hw_phy_config(voi
 
 static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
 {
-	struct phy_reg phy_reg_init[] = {
+	static const struct phy_reg phy_reg_init[] = {
 		{ 0x1f, 0x0003 },
 		{ 0x08, 0x441d },
 		{ 0x01, 0x9100 },
@@ -2556,7 +2556,7 @@ static void rtl_set_rx_max_size(void __i
 
 static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
 {
-	struct {
+	static const struct {
 		u32 mac_version;
 		u32 clk;
 		u32 val;
@@ -2680,7 +2680,7 @@ struct ephy_info {
 	u16 bits;
 };
 
-static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
+static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int len)
 {
 	u16 w;
 
@@ -2751,7 +2751,7 @@ static void __rtl_hw_start_8168cp(void _
 
 static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
 {
-	static struct ephy_info e_info_8168cp[] = {
+	static const struct ephy_info e_info_8168cp[] = {
 		{ 0x01, 0,	0x0001 },
 		{ 0x02, 0x0800,	0x1000 },
 		{ 0x03, 0,	0x0042 },
@@ -2795,7 +2795,7 @@ static void rtl_hw_start_8168cp_3(void _
 
 static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev)
 {
-	static struct ephy_info e_info_8168c_1[] = {
+	static const struct ephy_info e_info_8168c_1[] = {
 		{ 0x02, 0x0800,	0x1000 },
 		{ 0x03, 0,	0x0002 },
 		{ 0x06, 0x0080,	0x0000 }
@@ -2812,7 +2812,7 @@ static void rtl_hw_start_8168c_1(void __
 
 static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev)
 {
-	static struct ephy_info e_info_8168c_2[] = {
+	static const struct ephy_info e_info_8168c_2[] = {
 		{ 0x01, 0,	0x0001 },
 		{ 0x03, 0x0400,	0x0220 }
 	};
@@ -2955,7 +2955,7 @@ static void rtl_hw_start_8168(struct net
 
 static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
 {
-	static struct ephy_info e_info_8102e_1[] = {
+	static const struct ephy_info e_info_8102e_1[] = {
 		{ 0x01,	0, 0x6e65 },
 		{ 0x02,	0, 0x091f },
 		{ 0x03,	0, 0xc2f9 },
@@ -3615,13 +3615,12 @@ static inline bool rtl8169_try_rx_copy(s
 	if (pkt_size >= rx_copybreak)
 		goto out;
 
-	skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN);
+	skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
 	if (!skb)
 		goto out;
 
 	pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size,
 				    PCI_DMA_FROMDEVICE);
-	skb_reserve(skb, NET_IP_ALIGN);
 	skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
 	*sk_buff = skb;
 	done = true;
@@ -3932,8 +3931,8 @@ static void rtl_set_rx_mode(struct net_d
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
@@ -4028,7 +4027,7 @@ out:
 	return 0;
 }
 
-static struct dev_pm_ops rtl8169_pm_ops = {
+static const struct dev_pm_ops rtl8169_pm_ops = {
 	.suspend = rtl8169_suspend,
 	.resume = rtl8169_resume,
 	.freeze = rtl8169_suspend,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/rrunner.c linux-libre-2.6.33-gnu1/drivers/net/rrunner.c
--- linux-libre-2.6.32-gnu1/drivers/net/rrunner.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/rrunner.c	2010-02-24 13:52:17.000000000 -0500
@@ -1293,7 +1293,7 @@ static void rr_dump(struct net_device *d
 
 	printk("Error code 0x%x\n", readl(&regs->Fail1));
 
-	index = (((readl(&regs->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;
+	index = (((readl(&regs->EvtPrd) >> 8) & 0xff) - 1) % TX_RING_ENTRIES;
 	cons = rrpriv->dirty_tx;
 	printk("TX ring index %i, TX consumer %i\n",
 	       index, cons);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/s2io.c linux-libre-2.6.33-gnu1/drivers/net/s2io.c
--- linux-libre-2.6.32-gnu1/drivers/net/s2io.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/s2io.c	2010-02-24 13:52:17.000000000 -0500
@@ -3238,7 +3238,7 @@ static u64 s2io_mdio_read(u32 mmd_type,
 
 /**
  *  s2io_chk_xpak_counter - Function to check the status of the xpak counters
- *  @counter      : couter value to be updated
+ *  @counter      : counter value to be updated
  *  @flag         : flag to indicate the status
  *  @type         : counter type
  *  Description:
@@ -3421,7 +3421,7 @@ static int wait_for_cmd_complete(void __
 				break;
 			}
 		} else {
-			if (!(val64 & busy_bit)) {
+			if (val64 & busy_bit) {
 				ret = SUCCESS;
 				break;
 			}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/s6gmac.c linux-libre-2.6.33-gnu1/drivers/net/s6gmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/s6gmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/s6gmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -373,9 +373,9 @@ struct s6gmac {
 static void s6gmac_rx_fillfifo(struct s6gmac *pd)
 {
 	struct sk_buff *skb;
-	while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB)
-			&& (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan))
-			&& (skb = dev_alloc_skb(S6_MAX_FRLEN + 2))) {
+	while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) &&
+	       (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) &&
+	       (skb = dev_alloc_skb(S6_MAX_FRLEN + 2))) {
 		pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb;
 		s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan,
 			pd->io, (u32)skb->data, S6_MAX_FRLEN);
@@ -984,7 +984,7 @@ static int __devinit s6gmac_probe(struct
 	pd->rx_dma = DMA_MASK_DMAC(i);
 	pd->rx_chan = DMA_INDEX_CHNL(i);
 	pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
-	res = request_irq(dev->irq, &s6gmac_interrupt, 0, dev->name, dev);
+	res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev);
 	if (res) {
 		printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq);
 		goto errirq;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sb1000.c linux-libre-2.6.33-gnu1/drivers/net/sb1000.c
--- linux-libre-2.6.32-gnu1/drivers/net/sb1000.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sb1000.c	2010-02-24 13:52:17.000000000 -0500
@@ -973,7 +973,7 @@ sb1000_open(struct net_device *dev)
 	lp->rx_frame_id[1] = 0;
 	lp->rx_frame_id[2] = 0;
 	lp->rx_frame_id[3] = 0;
-	if (request_irq(dev->irq, &sb1000_interrupt, 0, "sb1000", dev)) {
+	if (request_irq(dev->irq, sb1000_interrupt, 0, "sb1000", dev)) {
 		return -EAGAIN;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sb1250-mac.c linux-libre-2.6.33-gnu1/drivers/net/sb1250-mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/sb1250-mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sb1250-mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1476,7 +1476,6 @@ static void sbmac_channel_start(struct s
 		V_MAC_TX_RL_THRSH(4) |
 		V_MAC_RX_PL_THRSH(4) |
 		V_MAC_RX_RD_THRSH(4) |	/* Must be '4' */
-		V_MAC_RX_PL_THRSH(4) |
 		V_MAC_RX_RL_THRSH(8) |
 		0;
 
@@ -2411,7 +2410,7 @@ static int sbmac_open(struct net_device
 	 */
 
 	__raw_readq(sc->sbm_isr);
-	err = request_irq(dev->irq, &sbmac_intr, IRQF_SHARED, dev->name, dev);
+	err = request_irq(dev->irq, sbmac_intr, IRQF_SHARED, dev->name, dev);
 	if (err) {
 		printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name,
 		       dev->irq);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sc92031.c linux-libre-2.6.33-gnu1/drivers/net/sc92031.c
--- linux-libre-2.6.32-gnu1/drivers/net/sc92031.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sc92031.c	2010-02-24 13:52:17.000000000 -0500
@@ -428,9 +428,9 @@ static void _sc92031_set_mar(struct net_
 	void __iomem *port_base = priv->port_base;
 	u32 mar0 = 0, mar1 = 0;
 
-	if ((dev->flags & IFF_PROMISC)
-			|| dev->mc_count > multicast_filter_limit
-			|| (dev->flags & IFF_ALLMULTI))
+	if ((dev->flags & IFF_PROMISC) ||
+	    dev->mc_count > multicast_filter_limit ||
+	    (dev->flags & IFF_ALLMULTI))
 		mar0 = mar1 = 0xffffffff;
 	else if (dev->flags & IFF_MULTICAST) {
 		struct dev_mc_list *mc_list;
@@ -777,10 +777,10 @@ static void _sc92031_rx_tasklet(struct n
 
 		rx_ring_offset = (rx_ring_offset + 4) % RX_BUF_LEN;
 
-		if (unlikely(rx_status == 0
-				|| rx_size > (MAX_ETH_FRAME_SIZE + 4)
-				|| rx_size < 16
-				|| !(rx_status & RxStatesOK))) {
+		if (unlikely(rx_status == 0 ||
+			     rx_size > (MAX_ETH_FRAME_SIZE + 4) ||
+			     rx_size < 16 ||
+			     !(rx_status & RxStatesOK))) {
 			_sc92031_rx_tasklet_error(dev, rx_status, rx_size);
 			break;
 		}
@@ -793,7 +793,7 @@ static void _sc92031_rx_tasklet(struct n
 
 		rx_len -= rx_size_align + 4;
 
-		skb = netdev_alloc_skb(dev, pkt_size + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(dev, pkt_size);
 		if (unlikely(!skb)) {
 			if (printk_ratelimit())
 				printk(KERN_ERR "%s: Couldn't allocate a skb_buff for a packet of size %u\n",
@@ -801,8 +801,6 @@ static void _sc92031_rx_tasklet(struct n
 			goto next;
 		}
 
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		if ((rx_ring_offset + pkt_size) > RX_BUF_LEN) {
 			memcpy(skb_put(skb, RX_BUF_LEN - rx_ring_offset),
 				rx_ring + rx_ring_offset, RX_BUF_LEN - rx_ring_offset);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/seeq8005.c linux-libre-2.6.33-gnu1/drivers/net/seeq8005.c
--- linux-libre-2.6.32-gnu1/drivers/net/seeq8005.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/seeq8005.c	2010-02-24 13:52:17.000000000 -0500
@@ -335,7 +335,7 @@ static int __init seeq8005_probe1(struct
 
 #if 0
 	{
-		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
+		 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
 		 if (irqval) {
 			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 					 dev->irq, irqval);
@@ -367,7 +367,7 @@ static int seeq8005_open(struct net_devi
 	struct net_local *lp = netdev_priv(dev);
 
 	{
-		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
+		 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
 		 if (irqval) {
 			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 					 dev->irq, irqval);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/bitfield.h linux-libre-2.6.33-gnu1/drivers/net/sfc/bitfield.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/bitfield.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/bitfield.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -37,6 +37,8 @@
 #define EFX_DWORD_2_WIDTH 32
 #define EFX_DWORD_3_LBN 96
 #define EFX_DWORD_3_WIDTH 32
+#define EFX_QWORD_0_LBN 0
+#define EFX_QWORD_0_WIDTH 64
 
 /* Specified attribute (e.g. LBN) of the specified field */
 #define EFX_VAL(field, attribute) field ## _ ## attribute
@@ -520,19 +522,6 @@ typedef union efx_oword {
 #define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD32
 #endif
 
-#define EFX_SET_OWORD_FIELD_VER(efx, oword, field, value) do { \
-	if (falcon_rev(efx) >= FALCON_REV_B0) {			   \
-		EFX_SET_OWORD_FIELD((oword), field##_B0, (value)); \
-	} else { \
-		EFX_SET_OWORD_FIELD((oword), field##_A1, (value)); \
-	} \
-} while (0)
-
-#define EFX_QWORD_FIELD_VER(efx, qword, field)	\
-	(falcon_rev(efx) >= FALCON_REV_B0 ?	\
-	 EFX_QWORD_FIELD((qword), field##_B0) :	\
-	 EFX_QWORD_FIELD((qword), field##_A1))
-
 /* Used to avoid compiler warnings about shift range exceeding width
  * of the data types when dma_addr_t is only 32 bits wide.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/boards.c linux-libre-2.6.33-gnu1/drivers/net/sfc/boards.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/boards.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/boards.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,328 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#include "net_driver.h"
-#include "phy.h"
-#include "boards.h"
-#include "efx.h"
-#include "workarounds.h"
-
-/* Macros for unpacking the board revision */
-/* The revision info is in host byte order. */
-#define BOARD_TYPE(_rev) (_rev >> 8)
-#define BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
-#define BOARD_MINOR(_rev) (_rev & 0xf)
-
-/* Blink support. If the PHY has no auto-blink mode so we hang it off a timer */
-#define BLINK_INTERVAL (HZ/2)
-
-static void blink_led_timer(unsigned long context)
-{
-	struct efx_nic *efx = (struct efx_nic *)context;
-	struct efx_blinker *bl = &efx->board_info.blinker;
-	efx->board_info.set_id_led(efx, bl->state);
-	bl->state = !bl->state;
-	if (bl->resubmit)
-		mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
-}
-
-static void board_blink(struct efx_nic *efx, bool blink)
-{
-	struct efx_blinker *blinker = &efx->board_info.blinker;
-
-	/* The rtnl mutex serialises all ethtool ioctls, so
-	 * nothing special needs doing here. */
-	if (blink) {
-		blinker->resubmit = true;
-		blinker->state = false;
-		setup_timer(&blinker->timer, blink_led_timer,
-			    (unsigned long)efx);
-		mod_timer(&blinker->timer, jiffies + BLINK_INTERVAL);
-	} else {
-		blinker->resubmit = false;
-		if (blinker->timer.function)
-			del_timer_sync(&blinker->timer);
-		efx->board_info.init_leds(efx);
-	}
-}
-
-/*****************************************************************************
- * Support for LM87 sensor chip used on several boards
- */
-#define LM87_REG_ALARMS1		0x41
-#define LM87_REG_ALARMS2		0x42
-#define LM87_IN_LIMITS(nr, _min, _max)			\
-	0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
-#define LM87_AIN_LIMITS(nr, _min, _max)			\
-	0x3B + (nr), _max, 0x1A + (nr), _min
-#define LM87_TEMP_INT_LIMITS(_min, _max)		\
-	0x39, _max, 0x3A, _min
-#define LM87_TEMP_EXT1_LIMITS(_min, _max)		\
-	0x37, _max, 0x38, _min
-
-#define LM87_ALARM_TEMP_INT		0x10
-#define LM87_ALARM_TEMP_EXT1		0x20
-
-#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
-
-static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
-			 const u8 *reg_values)
-{
-	struct i2c_client *client = i2c_new_device(&efx->i2c_adap, info);
-	int rc;
-
-	if (!client)
-		return -EIO;
-
-	while (*reg_values) {
-		u8 reg = *reg_values++;
-		u8 value = *reg_values++;
-		rc = i2c_smbus_write_byte_data(client, reg, value);
-		if (rc)
-			goto err;
-	}
-
-	efx->board_info.hwmon_client = client;
-	return 0;
-
-err:
-	i2c_unregister_device(client);
-	return rc;
-}
-
-static void efx_fini_lm87(struct efx_nic *efx)
-{
-	i2c_unregister_device(efx->board_info.hwmon_client);
-}
-
-static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
-{
-	struct i2c_client *client = efx->board_info.hwmon_client;
-	s32 alarms1, alarms2;
-
-	/* If link is up then do not monitor temperature */
-	if (EFX_WORKAROUND_7884(efx) && efx->link_up)
-		return 0;
-
-	alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
-	alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
-	if (alarms1 < 0)
-		return alarms1;
-	if (alarms2 < 0)
-		return alarms2;
-	alarms1 &= mask;
-	alarms2 &= mask >> 8;
-	if (alarms1 || alarms2) {
-		EFX_ERR(efx,
-			"LM87 detected a hardware failure (status %02x:%02x)"
-			"%s%s\n",
-			alarms1, alarms2,
-			(alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "",
-			(alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : "");
-		return -ERANGE;
-	}
-
-	return 0;
-}
-
-#else /* !CONFIG_SENSORS_LM87 */
-
-static inline int
-efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
-	      const u8 *reg_values)
-{
-	return 0;
-}
-static inline void efx_fini_lm87(struct efx_nic *efx)
-{
-}
-static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
-{
-	return 0;
-}
-
-#endif /* CONFIG_SENSORS_LM87 */
-
-/*****************************************************************************
- * Support for the SFE4002
- *
- */
-static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
-
-static const u8 sfe4002_lm87_regs[] = {
-	LM87_IN_LIMITS(0, 0x83, 0x91),		/* 2.5V:  1.8V +/- 5% */
-	LM87_IN_LIMITS(1, 0x51, 0x5a),		/* Vccp1: 1.2V +/- 5% */
-	LM87_IN_LIMITS(2, 0xb6, 0xca),		/* 3.3V:  3.3V +/- 5% */
-	LM87_IN_LIMITS(3, 0xb0, 0xc9),		/* 5V:    4.6-5.2V */
-	LM87_IN_LIMITS(4, 0xb0, 0xe0),		/* 12V:   11-14V */
-	LM87_IN_LIMITS(5, 0x44, 0x4b),		/* Vccp2: 1.0V +/- 5% */
-	LM87_AIN_LIMITS(0, 0xa0, 0xb2),		/* AIN1:  1.66V +/- 5% */
-	LM87_AIN_LIMITS(1, 0x91, 0xa1),		/* AIN2:  1.5V +/- 5% */
-	LM87_TEMP_INT_LIMITS(10, 60),		/* board */
-	LM87_TEMP_EXT1_LIMITS(10, 70),		/* Falcon */
-	0
-};
-
-static struct i2c_board_info sfe4002_hwmon_info = {
-	I2C_BOARD_INFO("lm87", 0x2e),
-	.platform_data	= &sfe4002_lm87_channel,
-};
-
-/****************************************************************************/
-/* LED allocations. Note that on rev A0 boards the schematic and the reality
- * differ: red and green are swapped. Below is the fixed (A1) layout (there
- * are only 3 A0 boards in existence, so no real reason to make this
- * conditional).
- */
-#define SFE4002_FAULT_LED (2)	/* Red */
-#define SFE4002_RX_LED    (0)	/* Green */
-#define SFE4002_TX_LED    (1)	/* Amber */
-
-static void sfe4002_init_leds(struct efx_nic *efx)
-{
-	/* Set the TX and RX LEDs to reflect status and activity, and the
-	 * fault LED off */
-	xfp_set_led(efx, SFE4002_TX_LED,
-		    QUAKE_LED_TXLINK | QUAKE_LED_LINK_ACTSTAT);
-	xfp_set_led(efx, SFE4002_RX_LED,
-		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
-	xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
-}
-
-static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
-{
-	xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
-			QUAKE_LED_OFF);
-}
-
-static int sfe4002_check_hw(struct efx_nic *efx)
-{
-	/* A0 board rev. 4002s report a temperature fault the whole time
-	 * (bad sensor) so we mask it out. */
-	unsigned alarm_mask =
-		(efx->board_info.major == 0 && efx->board_info.minor == 0) ?
-		~LM87_ALARM_TEMP_EXT1 : ~0;
-
-	return efx_check_lm87(efx, alarm_mask);
-}
-
-static int sfe4002_init(struct efx_nic *efx)
-{
-	int rc = efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
-	if (rc)
-		return rc;
-	efx->board_info.monitor = sfe4002_check_hw;
-	efx->board_info.init_leds = sfe4002_init_leds;
-	efx->board_info.set_id_led = sfe4002_set_id_led;
-	efx->board_info.blink = board_blink;
-	efx->board_info.fini = efx_fini_lm87;
-	return 0;
-}
-
-/*****************************************************************************
- * Support for the SFN4112F
- *
- */
-static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
-
-static const u8 sfn4112f_lm87_regs[] = {
-	LM87_IN_LIMITS(0, 0x83, 0x91),		/* 2.5V:  1.8V +/- 5% */
-	LM87_IN_LIMITS(1, 0x51, 0x5a),		/* Vccp1: 1.2V +/- 5% */
-	LM87_IN_LIMITS(2, 0xb6, 0xca),		/* 3.3V:  3.3V +/- 5% */
-	LM87_IN_LIMITS(4, 0xb0, 0xe0),		/* 12V:   11-14V */
-	LM87_IN_LIMITS(5, 0x44, 0x4b),		/* Vccp2: 1.0V +/- 5% */
-	LM87_AIN_LIMITS(1, 0x91, 0xa1),		/* AIN2:  1.5V +/- 5% */
-	LM87_TEMP_INT_LIMITS(10, 60),		/* board */
-	LM87_TEMP_EXT1_LIMITS(10, 70),		/* Falcon */
-	0
-};
-
-static struct i2c_board_info sfn4112f_hwmon_info = {
-	I2C_BOARD_INFO("lm87", 0x2e),
-	.platform_data	= &sfn4112f_lm87_channel,
-};
-
-#define SFN4112F_ACT_LED	0
-#define SFN4112F_LINK_LED	1
-
-static void sfn4112f_init_leds(struct efx_nic *efx)
-{
-	xfp_set_led(efx, SFN4112F_ACT_LED,
-		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
-	xfp_set_led(efx, SFN4112F_LINK_LED,
-		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
-}
-
-static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
-{
-	xfp_set_led(efx, SFN4112F_LINK_LED,
-		    state ? QUAKE_LED_ON : QUAKE_LED_OFF);
-}
-
-static int sfn4112f_check_hw(struct efx_nic *efx)
-{
-	/* Mask out unused sensors */
-	return efx_check_lm87(efx, ~0x48);
-}
-
-static int sfn4112f_init(struct efx_nic *efx)
-{
-	int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
-	if (rc)
-		return rc;
-	efx->board_info.monitor = sfn4112f_check_hw;
-	efx->board_info.init_leds = sfn4112f_init_leds;
-	efx->board_info.set_id_led = sfn4112f_set_id_led;
-	efx->board_info.blink = board_blink;
-	efx->board_info.fini = efx_fini_lm87;
-	return 0;
-}
-
-/* This will get expanded as board-specific details get moved out of the
- * PHY drivers. */
-struct efx_board_data {
-	enum efx_board_type type;
-	const char *ref_model;
-	const char *gen_type;
-	int (*init) (struct efx_nic *nic);
-};
-
-
-static struct efx_board_data board_data[] = {
-	{ EFX_BOARD_SFE4001, "SFE4001", "10GBASE-T adapter", sfe4001_init },
-	{ EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
-	{ EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
-	  sfn4111t_init },
-	{ EFX_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter",
-	  sfn4112f_init },
-};
-
-void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
-{
-	struct efx_board_data *data = NULL;
-	int i;
-
-	efx->board_info.type = BOARD_TYPE(revision_info);
-	efx->board_info.major = BOARD_MAJOR(revision_info);
-	efx->board_info.minor = BOARD_MINOR(revision_info);
-
-	for (i = 0; i < ARRAY_SIZE(board_data); i++)
-		if (board_data[i].type == efx->board_info.type)
-			data = &board_data[i];
-
-	if (data) {
-		EFX_INFO(efx, "board is %s rev %c%d\n",
-			 (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
-			 ? data->ref_model : data->gen_type,
-			 'A' + efx->board_info.major, efx->board_info.minor);
-		efx->board_info.init = data->init;
-	} else {
-		EFX_ERR(efx, "unknown board type %d\n", efx->board_info.type);
-	}
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/boards.h linux-libre-2.6.33-gnu1/drivers/net/sfc/boards.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/boards.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/boards.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_BOARDS_H
-#define EFX_BOARDS_H
-
-/* Board IDs (must fit in 8 bits) */
-enum efx_board_type {
-	EFX_BOARD_SFE4001 = 1,
-	EFX_BOARD_SFE4002 = 2,
-	EFX_BOARD_SFN4111T = 0x51,
-	EFX_BOARD_SFN4112F = 0x52,
-};
-
-extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info);
-
-/* SFE4001 (10GBASE-T) */
-extern int sfe4001_init(struct efx_nic *efx);
-/* SFN4111T (100/1000/10GBASE-T) */
-extern int sfn4111t_init(struct efx_nic *efx);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/efx.c linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/efx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2005-2008 Solarflare Communications Inc.
+ * Copyright 2005-2009 Solarflare Communications 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
@@ -21,12 +21,73 @@
 #include <linux/ethtool.h>
 #include <linux/topology.h>
 #include "net_driver.h"
-#include "ethtool.h"
-#include "tx.h"
-#include "rx.h"
 #include "efx.h"
 #include "mdio_10g.h"
-#include "falcon.h"
+#include "nic.h"
+
+#include "mcdi.h"
+
+/**************************************************************************
+ *
+ * Type name strings
+ *
+ **************************************************************************
+ */
+
+/* Loopback mode names (see LOOPBACK_MODE()) */
+const unsigned int efx_loopback_mode_max = LOOPBACK_MAX;
+const char *efx_loopback_mode_names[] = {
+	[LOOPBACK_NONE]		= "NONE",
+	[LOOPBACK_DATA]		= "DATAPATH",
+	[LOOPBACK_GMAC]		= "GMAC",
+	[LOOPBACK_XGMII]	= "XGMII",
+	[LOOPBACK_XGXS]		= "XGXS",
+	[LOOPBACK_XAUI]  	= "XAUI",
+	[LOOPBACK_GMII] 	= "GMII",
+	[LOOPBACK_SGMII] 	= "SGMII",
+	[LOOPBACK_XGBR]		= "XGBR",
+	[LOOPBACK_XFI]		= "XFI",
+	[LOOPBACK_XAUI_FAR]	= "XAUI_FAR",
+	[LOOPBACK_GMII_FAR]	= "GMII_FAR",
+	[LOOPBACK_SGMII_FAR]	= "SGMII_FAR",
+	[LOOPBACK_XFI_FAR]	= "XFI_FAR",
+	[LOOPBACK_GPHY]		= "GPHY",
+	[LOOPBACK_PHYXS]	= "PHYXS",
+	[LOOPBACK_PCS]	 	= "PCS",
+	[LOOPBACK_PMAPMD] 	= "PMA/PMD",
+	[LOOPBACK_XPORT]	= "XPORT",
+	[LOOPBACK_XGMII_WS]	= "XGMII_WS",
+	[LOOPBACK_XAUI_WS]  	= "XAUI_WS",
+	[LOOPBACK_XAUI_WS_FAR]  = "XAUI_WS_FAR",
+	[LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR",
+	[LOOPBACK_GMII_WS] 	= "GMII_WS",
+	[LOOPBACK_XFI_WS]	= "XFI_WS",
+	[LOOPBACK_XFI_WS_FAR]	= "XFI_WS_FAR",
+	[LOOPBACK_PHYXS_WS]  	= "PHYXS_WS",
+};
+
+/* Interrupt mode names (see INT_MODE())) */
+const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX;
+const char *efx_interrupt_mode_names[] = {
+	[EFX_INT_MODE_MSIX]   = "MSI-X",
+	[EFX_INT_MODE_MSI]    = "MSI",
+	[EFX_INT_MODE_LEGACY] = "legacy",
+};
+
+const unsigned int efx_reset_type_max = RESET_TYPE_MAX;
+const char *efx_reset_type_names[] = {
+	[RESET_TYPE_INVISIBLE]     = "INVISIBLE",
+	[RESET_TYPE_ALL]           = "ALL",
+	[RESET_TYPE_WORLD]         = "WORLD",
+	[RESET_TYPE_DISABLE]       = "DISABLE",
+	[RESET_TYPE_TX_WATCHDOG]   = "TX_WATCHDOG",
+	[RESET_TYPE_INT_ERROR]     = "INT_ERROR",
+	[RESET_TYPE_RX_RECOVERY]   = "RX_RECOVERY",
+	[RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH",
+	[RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH",
+	[RESET_TYPE_TX_SKIP]       = "TX_SKIP",
+	[RESET_TYPE_MC_FAILURE]    = "MC_FAILURE",
+};
 
 #define EFX_MAX_MTU (9 * 1024)
 
@@ -145,7 +206,8 @@ static void efx_fini_channels(struct efx
 
 #define EFX_ASSERT_RESET_SERIALISED(efx)		\
 	do {						\
-		if (efx->state == STATE_RUNNING)	\
+		if ((efx->state == STATE_RUNNING) ||	\
+		    (efx->state == STATE_DISABLED))	\
 			ASSERT_RTNL();			\
 	} while (0)
 
@@ -171,7 +233,7 @@ static int efx_process_channel(struct ef
 		     !channel->enabled))
 		return 0;
 
-	rx_packets = falcon_process_eventq(channel, rx_quota);
+	rx_packets = efx_nic_process_eventq(channel, rx_quota);
 	if (rx_packets == 0)
 		return 0;
 
@@ -203,7 +265,7 @@ static inline void efx_channel_processed
 	channel->work_pending = false;
 	smp_wmb();
 
-	falcon_eventq_read_ack(channel);
+	efx_nic_eventq_read_ack(channel);
 }
 
 /* NAPI poll handler
@@ -228,26 +290,20 @@ static int efx_poll(struct napi_struct *
 		if (channel->used_flags & EFX_USED_BY_RX &&
 		    efx->irq_rx_adaptive &&
 		    unlikely(++channel->irq_count == 1000)) {
-			unsigned old_irq_moderation = channel->irq_moderation;
-
 			if (unlikely(channel->irq_mod_score <
 				     irq_adapt_low_thresh)) {
-				channel->irq_moderation =
-					max_t(int,
-					      channel->irq_moderation -
-					      FALCON_IRQ_MOD_RESOLUTION,
-					      FALCON_IRQ_MOD_RESOLUTION);
+				if (channel->irq_moderation > 1) {
+					channel->irq_moderation -= 1;
+					efx->type->push_irq_moderation(channel);
+				}
 			} else if (unlikely(channel->irq_mod_score >
 					    irq_adapt_high_thresh)) {
-				channel->irq_moderation =
-					min(channel->irq_moderation +
-					    FALCON_IRQ_MOD_RESOLUTION,
-					    efx->irq_rx_moderation);
+				if (channel->irq_moderation <
+				    efx->irq_rx_moderation) {
+					channel->irq_moderation += 1;
+					efx->type->push_irq_moderation(channel);
+				}
 			}
-
-			if (channel->irq_moderation != old_irq_moderation)
-				falcon_set_int_moderation(channel);
-
 			channel->irq_count = 0;
 			channel->irq_mod_score = 0;
 		}
@@ -280,7 +336,7 @@ void efx_process_channel_now(struct efx_
 	BUG_ON(!channel->enabled);
 
 	/* Disable interrupts and wait for ISRs to complete */
-	falcon_disable_interrupts(efx);
+	efx_nic_disable_interrupts(efx);
 	if (efx->legacy_irq)
 		synchronize_irq(efx->legacy_irq);
 	if (channel->irq)
@@ -290,14 +346,14 @@ void efx_process_channel_now(struct efx_
 	napi_disable(&channel->napi_str);
 
 	/* Poll the channel */
-	efx_process_channel(channel, efx->type->evq_size);
+	efx_process_channel(channel, EFX_EVQ_SIZE);
 
 	/* Ack the eventq. This may cause an interrupt to be generated
 	 * when they are reenabled */
 	efx_channel_processed(channel);
 
 	napi_enable(&channel->napi_str);
-	falcon_enable_interrupts(efx);
+	efx_nic_enable_interrupts(efx);
 }
 
 /* Create event queue
@@ -309,7 +365,7 @@ static int efx_probe_eventq(struct efx_c
 {
 	EFX_LOG(channel->efx, "chan %d create event queue\n", channel->channel);
 
-	return falcon_probe_eventq(channel);
+	return efx_nic_probe_eventq(channel);
 }
 
 /* Prepare channel's event queue */
@@ -319,21 +375,21 @@ static void efx_init_eventq(struct efx_c
 
 	channel->eventq_read_ptr = 0;
 
-	falcon_init_eventq(channel);
+	efx_nic_init_eventq(channel);
 }
 
 static void efx_fini_eventq(struct efx_channel *channel)
 {
 	EFX_LOG(channel->efx, "chan %d fini event queue\n", channel->channel);
 
-	falcon_fini_eventq(channel);
+	efx_nic_fini_eventq(channel);
 }
 
 static void efx_remove_eventq(struct efx_channel *channel)
 {
 	EFX_LOG(channel->efx, "chan %d remove event queue\n", channel->channel);
 
-	falcon_remove_eventq(channel);
+	efx_nic_remove_eventq(channel);
 }
 
 /**************************************************************************
@@ -499,7 +555,7 @@ static void efx_fini_channels(struct efx
 	EFX_ASSERT_RESET_SERIALISED(efx);
 	BUG_ON(efx->port_enabled);
 
-	rc = falcon_flush_queues(efx);
+	rc = efx_nic_flush_queues(efx);
 	if (rc)
 		EFX_ERR(efx, "failed to flush queues\n");
 	else
@@ -547,8 +603,10 @@ void efx_schedule_slow_fill(struct efx_r
  * netif_carrier_on/off) of the link status, and also maintains the
  * link status's stop on the port's TX queue.
  */
-static void efx_link_status_changed(struct efx_nic *efx)
+void efx_link_status_changed(struct efx_nic *efx)
 {
+	struct efx_link_state *link_state = &efx->link_state;
+
 	/* SFC Bug 5356: A net_dev notifier is registered, so we must ensure
 	 * that no events are triggered between unregister_netdev() and the
 	 * driver unloading. A more general condition is that NETDEV_CHANGE
@@ -561,19 +619,19 @@ static void efx_link_status_changed(stru
 		return;
 	}
 
-	if (efx->link_up != netif_carrier_ok(efx->net_dev)) {
+	if (link_state->up != netif_carrier_ok(efx->net_dev)) {
 		efx->n_link_state_changes++;
 
-		if (efx->link_up)
+		if (link_state->up)
 			netif_carrier_on(efx->net_dev);
 		else
 			netif_carrier_off(efx->net_dev);
 	}
 
 	/* Status message for kernel log */
-	if (efx->link_up) {
+	if (link_state->up) {
 		EFX_INFO(efx, "link up at %uMbps %s-duplex (MTU %d)%s\n",
-			 efx->link_speed, efx->link_fd ? "full" : "half",
+			 link_state->speed, link_state->fd ? "full" : "half",
 			 efx->net_dev->mtu,
 			 (efx->promiscuous ? " [PROMISC]" : ""));
 	} else {
@@ -582,16 +640,49 @@ static void efx_link_status_changed(stru
 
 }
 
+void efx_link_set_advertising(struct efx_nic *efx, u32 advertising)
+{
+	efx->link_advertising = advertising;
+	if (advertising) {
+		if (advertising & ADVERTISED_Pause)
+			efx->wanted_fc |= (EFX_FC_TX | EFX_FC_RX);
+		else
+			efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
+		if (advertising & ADVERTISED_Asym_Pause)
+			efx->wanted_fc ^= EFX_FC_TX;
+	}
+}
+
+void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type wanted_fc)
+{
+	efx->wanted_fc = wanted_fc;
+	if (efx->link_advertising) {
+		if (wanted_fc & EFX_FC_RX)
+			efx->link_advertising |= (ADVERTISED_Pause |
+						  ADVERTISED_Asym_Pause);
+		else
+			efx->link_advertising &= ~(ADVERTISED_Pause |
+						   ADVERTISED_Asym_Pause);
+		if (wanted_fc & EFX_FC_TX)
+			efx->link_advertising ^= ADVERTISED_Asym_Pause;
+	}
+}
+
 static void efx_fini_port(struct efx_nic *efx);
 
-/* This call reinitialises the MAC to pick up new PHY settings. The
- * caller must hold the mac_lock */
-void __efx_reconfigure_port(struct efx_nic *efx)
+/* Push loopback/power/transmit disable settings to the PHY, and reconfigure
+ * the MAC appropriately. All other PHY configuration changes are pushed
+ * through phy_op->set_settings(), and pushed asynchronously to the MAC
+ * through efx_monitor().
+ *
+ * Callers must hold the mac_lock
+ */
+int __efx_reconfigure_port(struct efx_nic *efx)
 {
-	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+	enum efx_phy_mode phy_mode;
+	int rc;
 
-	EFX_LOG(efx, "reconfiguring MAC from PHY settings on CPU %d\n",
-		raw_smp_processor_id());
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
 
 	/* Serialise the promiscuous flag with efx_set_multicast_list. */
 	if (efx_dev_registered(efx)) {
@@ -599,61 +690,48 @@ void __efx_reconfigure_port(struct efx_n
 		netif_addr_unlock_bh(efx->net_dev);
 	}
 
-	falcon_deconfigure_mac_wrapper(efx);
-
-	/* Reconfigure the PHY, disabling transmit in mac level loopback. */
+	/* Disable PHY transmit in mac level loopbacks */
+	phy_mode = efx->phy_mode;
 	if (LOOPBACK_INTERNAL(efx))
 		efx->phy_mode |= PHY_MODE_TX_DISABLED;
 	else
 		efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
-	efx->phy_op->reconfigure(efx);
 
-	if (falcon_switch_mac(efx))
-		goto fail;
-
-	efx->mac_op->reconfigure(efx);
+	rc = efx->type->reconfigure_port(efx);
 
-	/* Inform kernel of loss/gain of carrier */
-	efx_link_status_changed(efx);
-	return;
+	if (rc)
+		efx->phy_mode = phy_mode;
 
-fail:
-	EFX_ERR(efx, "failed to reconfigure MAC\n");
-	efx->port_enabled = false;
-	efx_fini_port(efx);
+	return rc;
 }
 
 /* Reinitialise the MAC to pick up new PHY settings, even if the port is
  * disabled. */
-void efx_reconfigure_port(struct efx_nic *efx)
+int efx_reconfigure_port(struct efx_nic *efx)
 {
+	int rc;
+
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
 	mutex_lock(&efx->mac_lock);
-	__efx_reconfigure_port(efx);
+	rc = __efx_reconfigure_port(efx);
 	mutex_unlock(&efx->mac_lock);
-}
 
-/* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all()
- * we don't efx_reconfigure_port() if the port is disabled. Care is taken
- * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */
-static void efx_phy_work(struct work_struct *data)
-{
-	struct efx_nic *efx = container_of(data, struct efx_nic, phy_work);
-
-	mutex_lock(&efx->mac_lock);
-	if (efx->port_enabled)
-		__efx_reconfigure_port(efx);
-	mutex_unlock(&efx->mac_lock);
+	return rc;
 }
 
+/* Asynchronous work item for changing MAC promiscuity and multicast
+ * hash.  Avoid a drain/rx_ingress enable by reconfiguring the current
+ * MAC directly. */
 static void efx_mac_work(struct work_struct *data)
 {
 	struct efx_nic *efx = container_of(data, struct efx_nic, mac_work);
 
 	mutex_lock(&efx->mac_lock);
-	if (efx->port_enabled)
-		efx->mac_op->irq(efx);
+	if (efx->port_enabled) {
+		efx->type->push_multicast_hash(efx);
+		efx->mac_op->reconfigure(efx);
+	}
 	mutex_unlock(&efx->mac_lock);
 }
 
@@ -663,14 +741,14 @@ static int efx_probe_port(struct efx_nic
 
 	EFX_LOG(efx, "create port\n");
 
-	/* Connect up MAC/PHY operations table and read MAC address */
-	rc = falcon_probe_port(efx);
-	if (rc)
-		goto err;
-
 	if (phy_flash_cfg)
 		efx->phy_mode = PHY_MODE_SPECIAL;
 
+	/* Connect up MAC/PHY operations table */
+	rc = efx->type->probe_port(efx);
+	if (rc)
+		goto err;
+
 	/* Sanity check MAC address */
 	if (is_valid_ether_addr(efx->mac_address)) {
 		memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN);
@@ -699,29 +777,33 @@ static int efx_init_port(struct efx_nic
 
 	EFX_LOG(efx, "init port\n");
 
-	rc = efx->phy_op->init(efx);
-	if (rc)
-		return rc;
 	mutex_lock(&efx->mac_lock);
-	efx->phy_op->reconfigure(efx);
-	rc = falcon_switch_mac(efx);
-	mutex_unlock(&efx->mac_lock);
+
+	rc = efx->phy_op->init(efx);
 	if (rc)
-		goto fail;
-	efx->mac_op->reconfigure(efx);
+		goto fail1;
 
 	efx->port_initialized = true;
-	efx_stats_enable(efx);
+
+	/* Reconfigure the MAC before creating dma queues (required for
+	 * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
+	efx->mac_op->reconfigure(efx);
+
+	/* Ensure the PHY advertises the correct flow control settings */
+	rc = efx->phy_op->reconfigure(efx);
+	if (rc)
+		goto fail2;
+
+	mutex_unlock(&efx->mac_lock);
 	return 0;
 
-fail:
+fail2:
 	efx->phy_op->fini(efx);
+fail1:
+	mutex_unlock(&efx->mac_lock);
 	return rc;
 }
 
-/* Allow efx_reconfigure_port() to be scheduled, and close the window
- * between efx_stop_port and efx_flush_all whereby a previously scheduled
- * efx_phy_work()/efx_mac_work() may have been cancelled */
 static void efx_start_port(struct efx_nic *efx)
 {
 	EFX_LOG(efx, "start port\n");
@@ -729,15 +811,16 @@ static void efx_start_port(struct efx_ni
 
 	mutex_lock(&efx->mac_lock);
 	efx->port_enabled = true;
-	__efx_reconfigure_port(efx);
-	efx->mac_op->irq(efx);
+
+	/* efx_mac_work() might have been scheduled after efx_stop_port(),
+	 * and then cancelled by efx_flush_all() */
+	efx->type->push_multicast_hash(efx);
+	efx->mac_op->reconfigure(efx);
+
 	mutex_unlock(&efx->mac_lock);
 }
 
-/* Prevent efx_phy_work, efx_mac_work, and efx_monitor() from executing,
- * and efx_set_multicast_list() from scheduling efx_phy_work. efx_phy_work
- * and efx_mac_work may still be scheduled via NAPI processing until
- * efx_flush_all() is called */
+/* Prevent efx_mac_work() and efx_monitor() from working */
 static void efx_stop_port(struct efx_nic *efx)
 {
 	EFX_LOG(efx, "stop port\n");
@@ -760,11 +843,10 @@ static void efx_fini_port(struct efx_nic
 	if (!efx->port_initialized)
 		return;
 
-	efx_stats_disable(efx);
 	efx->phy_op->fini(efx);
 	efx->port_initialized = false;
 
-	efx->link_up = false;
+	efx->link_state.up = false;
 	efx_link_status_changed(efx);
 }
 
@@ -772,7 +854,7 @@ static void efx_remove_port(struct efx_n
 {
 	EFX_LOG(efx, "destroying port\n");
 
-	falcon_remove_port(efx);
+	efx->type->remove_port(efx);
 }
 
 /**************************************************************************
@@ -824,9 +906,8 @@ static int efx_init_io(struct efx_nic *e
 		goto fail2;
 	}
 
-	efx->membase_phys = pci_resource_start(efx->pci_dev,
-					       efx->type->mem_bar);
-	rc = pci_request_region(pci_dev, efx->type->mem_bar, "sfc");
+	efx->membase_phys = pci_resource_start(efx->pci_dev, EFX_MEM_BAR);
+	rc = pci_request_region(pci_dev, EFX_MEM_BAR, "sfc");
 	if (rc) {
 		EFX_ERR(efx, "request for memory BAR failed\n");
 		rc = -EIO;
@@ -835,21 +916,20 @@ static int efx_init_io(struct efx_nic *e
 	efx->membase = ioremap_nocache(efx->membase_phys,
 				       efx->type->mem_map_size);
 	if (!efx->membase) {
-		EFX_ERR(efx, "could not map memory BAR %d at %llx+%x\n",
-			efx->type->mem_bar,
+		EFX_ERR(efx, "could not map memory BAR at %llx+%x\n",
 			(unsigned long long)efx->membase_phys,
 			efx->type->mem_map_size);
 		rc = -ENOMEM;
 		goto fail4;
 	}
-	EFX_LOG(efx, "memory BAR %u at %llx+%x (virtual %p)\n",
-		efx->type->mem_bar, (unsigned long long)efx->membase_phys,
+	EFX_LOG(efx, "memory BAR at %llx+%x (virtual %p)\n",
+		(unsigned long long)efx->membase_phys,
 		efx->type->mem_map_size, efx->membase);
 
 	return 0;
 
  fail4:
-	pci_release_region(efx->pci_dev, efx->type->mem_bar);
+	pci_release_region(efx->pci_dev, EFX_MEM_BAR);
  fail3:
 	efx->membase_phys = 0;
  fail2:
@@ -868,7 +948,7 @@ static void efx_fini_io(struct efx_nic *
 	}
 
 	if (efx->membase_phys) {
-		pci_release_region(efx->pci_dev, efx->type->mem_bar);
+		pci_release_region(efx->pci_dev, EFX_MEM_BAR);
 		efx->membase_phys = 0;
 	}
 
@@ -1011,7 +1091,7 @@ static int efx_probe_nic(struct efx_nic
 	EFX_LOG(efx, "creating NIC\n");
 
 	/* Carry out hardware-type specific initialisation */
-	rc = falcon_probe_nic(efx);
+	rc = efx->type->probe(efx);
 	if (rc)
 		return rc;
 
@@ -1032,7 +1112,7 @@ static void efx_remove_nic(struct efx_ni
 	EFX_LOG(efx, "destroying NIC\n");
 
 	efx_remove_interrupts(efx);
-	falcon_remove_nic(efx);
+	efx->type->remove(efx);
 }
 
 /**************************************************************************
@@ -1112,12 +1192,31 @@ static void efx_start_all(struct efx_nic
 	efx_for_each_channel(channel, efx)
 		efx_start_channel(channel);
 
-	falcon_enable_interrupts(efx);
+	efx_nic_enable_interrupts(efx);
 
-	/* Start hardware monitor if we're in RUNNING */
-	if (efx->state == STATE_RUNNING)
+	/* Switch to event based MCDI completions after enabling interrupts.
+	 * If a reset has been scheduled, then we need to stay in polled mode.
+	 * Rather than serialising efx_mcdi_mode_event() [which sleeps] and
+	 * reset_pending [modified from an atomic context], we instead guarantee
+	 * that efx_mcdi_mode_poll() isn't reverted erroneously */
+	efx_mcdi_mode_event(efx);
+	if (efx->reset_pending != RESET_TYPE_NONE)
+		efx_mcdi_mode_poll(efx);
+
+	/* Start the hardware monitor if there is one. Otherwise (we're link
+	 * event driven), we have to poll the PHY because after an event queue
+	 * flush, we could have a missed a link state change */
+	if (efx->type->monitor != NULL) {
 		queue_delayed_work(efx->workqueue, &efx->monitor_work,
 				   efx_monitor_interval);
+	} else {
+		mutex_lock(&efx->mac_lock);
+		if (efx->phy_op->poll(efx))
+			efx_link_status_changed(efx);
+		mutex_unlock(&efx->mac_lock);
+	}
+
+	efx->type->start_stats(efx);
 }
 
 /* Flush all delayed work. Should only be called when no more delayed work
@@ -1136,8 +1235,6 @@ static void efx_flush_all(struct efx_nic
 
 	/* Stop scheduled port reconfigurations */
 	cancel_work_sync(&efx->mac_work);
-	cancel_work_sync(&efx->phy_work);
-
 }
 
 /* Quiesce hardware and software without bringing the link down.
@@ -1155,8 +1252,13 @@ static void efx_stop_all(struct efx_nic
 	if (!efx->port_enabled)
 		return;
 
+	efx->type->stop_stats(efx);
+
+	/* Switch to MCDI polling on Siena before disabling interrupts */
+	efx_mcdi_mode_poll(efx);
+
 	/* Disable interrupts and wait for ISR to complete */
-	falcon_disable_interrupts(efx);
+	efx_nic_disable_interrupts(efx);
 	if (efx->legacy_irq)
 		synchronize_irq(efx->legacy_irq);
 	efx_for_each_channel(channel, efx) {
@@ -1173,15 +1275,9 @@ static void efx_stop_all(struct efx_nic
 	 * window to loose phy events */
 	efx_stop_port(efx);
 
-	/* Flush efx_phy_work, efx_mac_work, refill_workqueue, monitor_work */
+	/* Flush efx_mac_work(), refill_workqueue, monitor_work */
 	efx_flush_all(efx);
 
-	/* Isolate the MAC from the TX and RX engines, so that queue
-	 * flushes will complete in a timely fashion. */
-	falcon_deconfigure_mac_wrapper(efx);
-	msleep(10); /* Let the Rx FIFO drain */
-	falcon_drain_tx_fifo(efx);
-
 	/* Stop the kernel transmit interface late, so the watchdog
 	 * timer isn't ticking over the flush */
 	if (efx_dev_registered(efx)) {
@@ -1201,41 +1297,39 @@ static void efx_remove_all(struct efx_ni
 	efx_remove_nic(efx);
 }
 
-/* A convinience function to safely flush all the queues */
-void efx_flush_queues(struct efx_nic *efx)
-{
-	EFX_ASSERT_RESET_SERIALISED(efx);
-
-	efx_stop_all(efx);
-
-	efx_fini_channels(efx);
-	efx_init_channels(efx);
-
-	efx_start_all(efx);
-}
-
 /**************************************************************************
  *
  * Interrupt moderation
  *
  **************************************************************************/
 
+static unsigned irq_mod_ticks(int usecs, int resolution)
+{
+	if (usecs <= 0)
+		return 0; /* cannot receive interrupts ahead of time :-) */
+	if (usecs < resolution)
+		return 1; /* never round down to 0 */
+	return usecs / resolution;
+}
+
 /* Set interrupt moderation parameters */
 void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
 			     bool rx_adaptive)
 {
 	struct efx_tx_queue *tx_queue;
 	struct efx_rx_queue *rx_queue;
+	unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION);
+	unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION);
 
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
 	efx_for_each_tx_queue(tx_queue, efx)
-		tx_queue->channel->irq_moderation = tx_usecs;
+		tx_queue->channel->irq_moderation = tx_ticks;
 
 	efx->irq_rx_adaptive = rx_adaptive;
-	efx->irq_rx_moderation = rx_usecs;
+	efx->irq_rx_moderation = rx_ticks;
 	efx_for_each_rx_queue(rx_queue, efx)
-		rx_queue->channel->irq_moderation = rx_usecs;
+		rx_queue->channel->irq_moderation = rx_ticks;
 }
 
 /**************************************************************************
@@ -1250,10 +1344,10 @@ static void efx_monitor(struct work_stru
 {
 	struct efx_nic *efx = container_of(data, struct efx_nic,
 					   monitor_work.work);
-	int rc;
 
 	EFX_TRACE(efx, "hardware monitor executing on CPU %d\n",
 		  raw_smp_processor_id());
+	BUG_ON(efx->type->monitor == NULL);
 
 	/* If the mac_lock is already held then it is likely a port
 	 * reconfiguration is already in place, which will likely do
@@ -1262,15 +1356,7 @@ static void efx_monitor(struct work_stru
 		goto out_requeue;
 	if (!efx->port_enabled)
 		goto out_unlock;
-	rc = efx->board_info.monitor(efx);
-	if (rc) {
-		EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
-			(rc == -ERANGE) ? "reported fault" : "failed");
-		efx->phy_mode |= PHY_MODE_LOW_POWER;
-		falcon_sim_phy_event(efx);
-	}
-	efx->phy_op->poll(efx);
-	efx->mac_op->poll(efx);
+	efx->type->monitor(efx);
 
 out_unlock:
 	mutex_unlock(&efx->mac_lock);
@@ -1374,6 +1460,12 @@ static int efx_net_open(struct net_devic
 		return -EIO;
 	if (efx->phy_mode & PHY_MODE_SPECIAL)
 		return -EBUSY;
+	if (efx_mcdi_poll_reboot(efx) && efx_reset(efx, RESET_TYPE_ALL))
+		return -EIO;
+
+	/* Notify the kernel of the link state polled during driver load,
+	 * before the monitor starts running */
+	efx_link_status_changed(efx);
 
 	efx_start_all(efx);
 	return 0;
@@ -1400,20 +1492,6 @@ static int efx_net_stop(struct net_devic
 	return 0;
 }
 
-void efx_stats_disable(struct efx_nic *efx)
-{
-	spin_lock(&efx->stats_lock);
-	++efx->stats_disable_count;
-	spin_unlock(&efx->stats_lock);
-}
-
-void efx_stats_enable(struct efx_nic *efx)
-{
-	spin_lock(&efx->stats_lock);
-	--efx->stats_disable_count;
-	spin_unlock(&efx->stats_lock);
-}
-
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
 static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 {
@@ -1421,17 +1499,9 @@ static struct net_device_stats *efx_net_
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
 	struct net_device_stats *stats = &net_dev->stats;
 
-	/* Update stats if possible, but do not wait if another thread
-	 * is updating them or if MAC stats fetches are temporarily
-	 * disabled; slightly stale stats are acceptable.
-	 */
-	if (!spin_trylock(&efx->stats_lock))
-		return stats;
-	if (!efx->stats_disable_count) {
-		efx->mac_op->update_stats(efx);
-		falcon_update_nic_stats(efx);
-	}
-	spin_unlock(&efx->stats_lock);
+	spin_lock_bh(&efx->stats_lock);
+	efx->type->update_stats(efx);
+	spin_unlock_bh(&efx->stats_lock);
 
 	stats->rx_packets = mac_stats->rx_packets;
 	stats->tx_packets = mac_stats->tx_packets;
@@ -1490,7 +1560,14 @@ static int efx_change_mtu(struct net_dev
 	EFX_LOG(efx, "changing MTU to %d\n", new_mtu);
 
 	efx_fini_channels(efx);
+
+	mutex_lock(&efx->mac_lock);
+	/* Reconfigure the MAC before enabling the dma queues so that
+	 * the RX buffers don't overflow */
 	net_dev->mtu = new_mtu;
+	efx->mac_op->reconfigure(efx);
+	mutex_unlock(&efx->mac_lock);
+
 	efx_init_channels(efx);
 
 	efx_start_all(efx);
@@ -1514,7 +1591,9 @@ static int efx_set_mac_address(struct ne
 	memcpy(net_dev->dev_addr, new_addr, net_dev->addr_len);
 
 	/* Reconfigure the MAC */
-	efx_reconfigure_port(efx);
+	mutex_lock(&efx->mac_lock);
+	efx->mac_op->reconfigure(efx);
+	mutex_unlock(&efx->mac_lock);
 
 	return 0;
 }
@@ -1525,16 +1604,14 @@ static void efx_set_multicast_list(struc
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct dev_mc_list *mc_list = net_dev->mc_list;
 	union efx_multicast_hash *mc_hash = &efx->multicast_hash;
-	bool promiscuous = !!(net_dev->flags & IFF_PROMISC);
-	bool changed = (efx->promiscuous != promiscuous);
 	u32 crc;
 	int bit;
 	int i;
 
-	efx->promiscuous = promiscuous;
+	efx->promiscuous = !!(net_dev->flags & IFF_PROMISC);
 
 	/* Build multicast hash table */
-	if (promiscuous || (net_dev->flags & IFF_ALLMULTI)) {
+	if (efx->promiscuous || (net_dev->flags & IFF_ALLMULTI)) {
 		memset(mc_hash, 0xff, sizeof(*mc_hash));
 	} else {
 		memset(mc_hash, 0x00, sizeof(*mc_hash));
@@ -1544,17 +1621,17 @@ static void efx_set_multicast_list(struc
 			set_bit_le(bit, mc_hash->byte);
 			mc_list = mc_list->next;
 		}
-	}
-
-	if (!efx->port_enabled)
-		/* Delay pushing settings until efx_start_port() */
-		return;
 
-	if (changed)
-		queue_work(efx->workqueue, &efx->phy_work);
+		/* Broadcast packets go through the multicast hash filter.
+		 * ether_crc_le() of the broadcast address is 0xbe2612ff
+		 * so we always add bit 0xff to the mask.
+		 */
+		set_bit_le(0xff, mc_hash->byte);
+	}
 
-	/* Create and activate new global multicast hash table */
-	falcon_set_multicast_hash(efx);
+	if (efx->port_enabled)
+		queue_work(efx->workqueue, &efx->mac_work);
+	/* Otherwise efx_start_port() will do this */
 }
 
 static const struct net_device_ops efx_netdev_ops = {
@@ -1683,21 +1760,18 @@ static void efx_unregister_netdev(struct
 
 /* Tears down the entire software state and most of the hardware state
  * before reset.  */
-void efx_reset_down(struct efx_nic *efx, enum reset_type method,
-		    struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method)
 {
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
-	efx_stats_disable(efx);
 	efx_stop_all(efx);
 	mutex_lock(&efx->mac_lock);
 	mutex_lock(&efx->spi_lock);
 
-	efx->phy_op->get_settings(efx, ecmd);
-
 	efx_fini_channels(efx);
 	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
 		efx->phy_op->fini(efx);
+	efx->type->fini(efx);
 }
 
 /* This function will always ensure that the locks acquired in
@@ -1705,79 +1779,67 @@ void efx_reset_down(struct efx_nic *efx,
  * that we were unable to reinitialise the hardware, and the
  * driver should be disabled. If ok is false, then the rx and tx
  * engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, enum reset_type method,
-		 struct ethtool_cmd *ecmd, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
 {
 	int rc;
 
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
-	rc = falcon_init_nic(efx);
+	rc = efx->type->init(efx);
 	if (rc) {
 		EFX_ERR(efx, "failed to initialise NIC\n");
-		ok = false;
+		goto fail;
 	}
 
+	if (!ok)
+		goto fail;
+
 	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
-		if (ok) {
-			rc = efx->phy_op->init(efx);
-			if (rc)
-				ok = false;
-		}
-		if (!ok)
-			efx->port_initialized = false;
+		rc = efx->phy_op->init(efx);
+		if (rc)
+			goto fail;
+		if (efx->phy_op->reconfigure(efx))
+			EFX_ERR(efx, "could not restore PHY settings\n");
 	}
 
-	if (ok) {
-		efx_init_channels(efx);
+	efx->mac_op->reconfigure(efx);
 
-		if (efx->phy_op->set_settings(efx, ecmd))
-			EFX_ERR(efx, "could not restore PHY settings\n");
-	}
+	efx_init_channels(efx);
+
+	mutex_unlock(&efx->spi_lock);
+	mutex_unlock(&efx->mac_lock);
+
+	efx_start_all(efx);
+
+	return 0;
+
+fail:
+	efx->port_initialized = false;
 
 	mutex_unlock(&efx->spi_lock);
 	mutex_unlock(&efx->mac_lock);
 
-	if (ok) {
-		efx_start_all(efx);
-		efx_stats_enable(efx);
-	}
 	return rc;
 }
 
-/* Reset the NIC as transparently as possible. Do not reset the PHY
- * Note that the reset may fail, in which case the card will be left
- * in a most-probably-unusable state.
- *
- * This function will sleep.  You cannot reset from within an atomic
- * state; use efx_schedule_reset() instead.
+/* Reset the NIC using the specified method.  Note that the reset may
+ * fail, in which case the card will be left in an unusable state.
  *
- * Grabs the rtnl_lock.
+ * Caller must hold the rtnl_lock.
  */
-static int efx_reset(struct efx_nic *efx)
+int efx_reset(struct efx_nic *efx, enum reset_type method)
 {
-	struct ethtool_cmd ecmd;
-	enum reset_type method = efx->reset_pending;
-	int rc = 0;
-
-	/* Serialise with kernel interfaces */
-	rtnl_lock();
-
-	/* If we're not RUNNING then don't reset. Leave the reset_pending
-	 * flag set so that efx_pci_probe_main will be retried */
-	if (efx->state != STATE_RUNNING) {
-		EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n");
-		goto out_unlock;
-	}
+	int rc, rc2;
+	bool disabled;
 
-	EFX_INFO(efx, "resetting (%d)\n", method);
+	EFX_INFO(efx, "resetting (%s)\n", RESET_TYPE(method));
 
-	efx_reset_down(efx, method, &ecmd);
+	efx_reset_down(efx, method);
 
-	rc = falcon_reset_hw(efx, method);
+	rc = efx->type->reset(efx, method);
 	if (rc) {
 		EFX_ERR(efx, "failed to reset hardware\n");
-		goto out_disable;
+		goto out;
 	}
 
 	/* Allow resets to be rescheduled. */
@@ -1789,25 +1851,22 @@ static int efx_reset(struct efx_nic *efx
 	 * can respond to requests. */
 	pci_set_master(efx->pci_dev);
 
+out:
 	/* Leave device stopped if necessary */
-	if (method == RESET_TYPE_DISABLE) {
-		efx_reset_up(efx, method, &ecmd, false);
-		rc = -EIO;
-	} else {
-		rc = efx_reset_up(efx, method, &ecmd, true);
+	disabled = rc || method == RESET_TYPE_DISABLE;
+	rc2 = efx_reset_up(efx, method, !disabled);
+	if (rc2) {
+		disabled = true;
+		if (!rc)
+			rc = rc2;
 	}
 
-out_disable:
-	if (rc) {
+	if (disabled) {
 		EFX_ERR(efx, "has been disabled\n");
 		efx->state = STATE_DISABLED;
-		dev_close(efx->net_dev);
 	} else {
 		EFX_LOG(efx, "reset complete\n");
 	}
-
-out_unlock:
-	rtnl_unlock();
 	return rc;
 }
 
@@ -1816,9 +1875,19 @@ out_unlock:
  */
 static void efx_reset_work(struct work_struct *data)
 {
-	struct efx_nic *nic = container_of(data, struct efx_nic, reset_work);
+	struct efx_nic *efx = container_of(data, struct efx_nic, reset_work);
 
-	efx_reset(nic);
+	/* If we're not RUNNING then don't reset. Leave the reset_pending
+	 * flag set so that efx_pci_probe_main will be retried */
+	if (efx->state != STATE_RUNNING) {
+		EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n");
+		return;
+	}
+
+	rtnl_lock();
+	if (efx_reset(efx, efx->reset_pending))
+		dev_close(efx->net_dev);
+	rtnl_unlock();
 }
 
 void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
@@ -1843,18 +1912,24 @@ void efx_schedule_reset(struct efx_nic *
 	case RESET_TYPE_TX_SKIP:
 		method = RESET_TYPE_INVISIBLE;
 		break;
+	case RESET_TYPE_MC_FAILURE:
 	default:
 		method = RESET_TYPE_ALL;
 		break;
 	}
 
 	if (method != type)
-		EFX_LOG(efx, "scheduling reset (%d:%d)\n", type, method);
+		EFX_LOG(efx, "scheduling %s reset for %s\n",
+			RESET_TYPE(method), RESET_TYPE(type));
 	else
-		EFX_LOG(efx, "scheduling reset (%d)\n", method);
+		EFX_LOG(efx, "scheduling %s reset\n", RESET_TYPE(method));
 
 	efx->reset_pending = method;
 
+	/* efx_process_channel() will no longer read events once a
+	 * reset is scheduled. So switch back to poll'd MCDI completions. */
+	efx_mcdi_mode_poll(efx);
+
 	queue_work(reset_workqueue, &efx->reset_work);
 }
 
@@ -1867,15 +1942,19 @@ void efx_schedule_reset(struct efx_nic *
 /* PCI device ID table */
 static struct pci_device_id efx_pci_table[] __devinitdata = {
 	{PCI_DEVICE(EFX_VENDID_SFC, FALCON_A_P_DEVID),
-	 .driver_data = (unsigned long) &falcon_a_nic_type},
+	 .driver_data = (unsigned long) &falcon_a1_nic_type},
 	{PCI_DEVICE(EFX_VENDID_SFC, FALCON_B_P_DEVID),
-	 .driver_data = (unsigned long) &falcon_b_nic_type},
+	 .driver_data = (unsigned long) &falcon_b0_nic_type},
+	{PCI_DEVICE(EFX_VENDID_SFC, BETHPAGE_A_P_DEVID),
+	 .driver_data = (unsigned long) &siena_a0_nic_type},
+	{PCI_DEVICE(EFX_VENDID_SFC, SIENA_A_P_DEVID),
+	 .driver_data = (unsigned long) &siena_a0_nic_type},
 	{0}			/* end of list */
 };
 
 /**************************************************************************
  *
- * Dummy PHY/MAC/Board operations
+ * Dummy PHY/MAC operations
  *
  * Can be used for some unimplemented operations
  * Needed so all function pointers are valid and do not have to be tested
@@ -1887,29 +1966,19 @@ int efx_port_dummy_op_int(struct efx_nic
 	return 0;
 }
 void efx_port_dummy_op_void(struct efx_nic *efx) {}
-void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
-
-static struct efx_mac_operations efx_dummy_mac_operations = {
-	.reconfigure	= efx_port_dummy_op_void,
-	.poll		= efx_port_dummy_op_void,
-	.irq		= efx_port_dummy_op_void,
-};
+void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+}
+bool efx_port_dummy_op_poll(struct efx_nic *efx)
+{
+	return false;
+}
 
 static struct efx_phy_operations efx_dummy_phy_operations = {
 	.init		 = efx_port_dummy_op_int,
-	.reconfigure	 = efx_port_dummy_op_void,
-	.poll		 = efx_port_dummy_op_void,
+	.reconfigure	 = efx_port_dummy_op_int,
+	.poll		 = efx_port_dummy_op_poll,
 	.fini		 = efx_port_dummy_op_void,
-	.clear_interrupt = efx_port_dummy_op_void,
-};
-
-static struct efx_board efx_dummy_board_info = {
-	.init		= efx_port_dummy_op_int,
-	.init_leds	= efx_port_dummy_op_void,
-	.set_id_led	= efx_port_dummy_op_blink,
-	.monitor	= efx_port_dummy_op_int,
-	.blink		= efx_port_dummy_op_blink,
-	.fini		= efx_port_dummy_op_void,
 };
 
 /**************************************************************************
@@ -1932,26 +2001,26 @@ static int efx_init_struct(struct efx_ni
 	/* Initialise common structures */
 	memset(efx, 0, sizeof(*efx));
 	spin_lock_init(&efx->biu_lock);
-	spin_lock_init(&efx->phy_lock);
+	mutex_init(&efx->mdio_lock);
 	mutex_init(&efx->spi_lock);
+#ifdef CONFIG_SFC_MTD
+	INIT_LIST_HEAD(&efx->mtd_list);
+#endif
 	INIT_WORK(&efx->reset_work, efx_reset_work);
 	INIT_DELAYED_WORK(&efx->monitor_work, efx_monitor);
 	efx->pci_dev = pci_dev;
 	efx->state = STATE_INIT;
 	efx->reset_pending = RESET_TYPE_NONE;
 	strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
-	efx->board_info = efx_dummy_board_info;
 
 	efx->net_dev = net_dev;
 	efx->rx_checksum_enabled = true;
 	spin_lock_init(&efx->netif_stop_lock);
 	spin_lock_init(&efx->stats_lock);
-	efx->stats_disable_count = 1;
 	mutex_init(&efx->mac_lock);
-	efx->mac_op = &efx_dummy_mac_operations;
+	efx->mac_op = type->default_mac_ops;
 	efx->phy_op = &efx_dummy_phy_operations;
 	efx->mdio.dev = net_dev;
-	INIT_WORK(&efx->phy_work, efx_phy_work);
 	INIT_WORK(&efx->mac_work, efx_mac_work);
 	atomic_set(&efx->netif_stop_count, 1);
 
@@ -1981,17 +2050,9 @@ static int efx_init_struct(struct efx_ni
 
 	efx->type = type;
 
-	/* Sanity-check NIC type */
-	EFX_BUG_ON_PARANOID(efx->type->txd_ring_mask &
-			    (efx->type->txd_ring_mask + 1));
-	EFX_BUG_ON_PARANOID(efx->type->rxd_ring_mask &
-			    (efx->type->rxd_ring_mask + 1));
-	EFX_BUG_ON_PARANOID(efx->type->evq_size &
-			    (efx->type->evq_size - 1));
 	/* As close as we can get to guaranteeing that we don't overflow */
-	EFX_BUG_ON_PARANOID(efx->type->evq_size <
-			    (efx->type->txd_ring_mask + 1 +
-			     efx->type->rxd_ring_mask + 1));
+	BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE);
+
 	EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS);
 
 	/* Higher numbered interrupt modes are less capable! */
@@ -2027,19 +2088,10 @@ static void efx_fini_struct(struct efx_n
  */
 static void efx_pci_remove_main(struct efx_nic *efx)
 {
-	EFX_ASSERT_RESET_SERIALISED(efx);
-
-	/* Skip everything if we never obtained a valid membase */
-	if (!efx->membase)
-		return;
-
+	efx_nic_fini_interrupt(efx);
 	efx_fini_channels(efx);
 	efx_fini_port(efx);
-
-	/* Shutdown the board, then the NIC and board state */
-	efx->board_info.fini(efx);
-	falcon_fini_interrupt(efx);
-
+	efx->type->fini(efx);
 	efx_fini_napi(efx);
 	efx_remove_all(efx);
 }
@@ -2063,9 +2115,6 @@ static void efx_pci_remove(struct pci_de
 	/* Allow any queued efx_resets() to complete */
 	rtnl_unlock();
 
-	if (efx->membase == NULL)
-		goto out;
-
 	efx_unregister_netdev(efx);
 
 	efx_mtd_remove(efx);
@@ -2078,7 +2127,6 @@ static void efx_pci_remove(struct pci_de
 
 	efx_pci_remove_main(efx);
 
-out:
 	efx_fini_io(efx);
 	EFX_LOG(efx, "shutdown successful\n");
 
@@ -2103,39 +2151,31 @@ static int efx_pci_probe_main(struct efx
 	if (rc)
 		goto fail2;
 
-	/* Initialise the board */
-	rc = efx->board_info.init(efx);
-	if (rc) {
-		EFX_ERR(efx, "failed to initialise board\n");
-		goto fail3;
-	}
-
-	rc = falcon_init_nic(efx);
+	rc = efx->type->init(efx);
 	if (rc) {
 		EFX_ERR(efx, "failed to initialise NIC\n");
-		goto fail4;
+		goto fail3;
 	}
 
 	rc = efx_init_port(efx);
 	if (rc) {
 		EFX_ERR(efx, "failed to initialise port\n");
-		goto fail5;
+		goto fail4;
 	}
 
 	efx_init_channels(efx);
 
-	rc = falcon_init_interrupt(efx);
+	rc = efx_nic_init_interrupt(efx);
 	if (rc)
-		goto fail6;
+		goto fail5;
 
 	return 0;
 
- fail6:
+ fail5:
 	efx_fini_channels(efx);
 	efx_fini_port(efx);
- fail5:
  fail4:
-	efx->board_info.fini(efx);
+	efx->type->fini(efx);
  fail3:
 	efx_fini_napi(efx);
  fail2:
@@ -2165,9 +2205,11 @@ static int __devinit efx_pci_probe(struc
 	net_dev = alloc_etherdev(sizeof(*efx));
 	if (!net_dev)
 		return -ENOMEM;
-	net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
+	net_dev->features |= (type->offload_features | NETIF_F_SG |
 			      NETIF_F_HIGHDMA | NETIF_F_TSO |
 			      NETIF_F_GRO);
+	if (type->offload_features & NETIF_F_V6_CSUM)
+		net_dev->features |= NETIF_F_TSO6;
 	/* Mask for features that also apply to VLAN devices */
 	net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
 				   NETIF_F_HIGHDMA | NETIF_F_TSO);
@@ -2219,18 +2261,19 @@ static int __devinit efx_pci_probe(struc
 		goto fail4;
 	}
 
-	/* Switch to the running state before we expose the device to
-	 * the OS.  This is to ensure that the initial gathering of
-	 * MAC stats succeeds. */
+	/* Switch to the running state before we expose the device to the OS,
+	 * so that dev_open()|efx_start_all() will actually start the device */
 	efx->state = STATE_RUNNING;
 
-	efx_mtd_probe(efx); /* allowed to fail */
-
 	rc = efx_register_netdev(efx);
 	if (rc)
 		goto fail5;
 
 	EFX_LOG(efx, "initialisation successful\n");
+
+	rtnl_lock();
+	efx_mtd_probe(efx); /* allowed to fail */
+	rtnl_unlock();
 	return 0;
 
  fail5:
@@ -2241,16 +2284,113 @@ static int __devinit efx_pci_probe(struc
  fail2:
 	efx_fini_struct(efx);
  fail1:
+	WARN_ON(rc > 0);
 	EFX_LOG(efx, "initialisation failed. rc=%d\n", rc);
 	free_netdev(net_dev);
 	return rc;
 }
 
+static int efx_pm_freeze(struct device *dev)
+{
+	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+
+	efx->state = STATE_FINI;
+
+	netif_device_detach(efx->net_dev);
+
+	efx_stop_all(efx);
+	efx_fini_channels(efx);
+
+	return 0;
+}
+
+static int efx_pm_thaw(struct device *dev)
+{
+	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+
+	efx->state = STATE_INIT;
+
+	efx_init_channels(efx);
+
+	mutex_lock(&efx->mac_lock);
+	efx->phy_op->reconfigure(efx);
+	mutex_unlock(&efx->mac_lock);
+
+	efx_start_all(efx);
+
+	netif_device_attach(efx->net_dev);
+
+	efx->state = STATE_RUNNING;
+
+	efx->type->resume_wol(efx);
+
+	return 0;
+}
+
+static int efx_pm_poweroff(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct efx_nic *efx = pci_get_drvdata(pci_dev);
+
+	efx->type->fini(efx);
+
+	efx->reset_pending = RESET_TYPE_NONE;
+
+	pci_save_state(pci_dev);
+	return pci_set_power_state(pci_dev, PCI_D3hot);
+}
+
+/* Used for both resume and restore */
+static int efx_pm_resume(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct efx_nic *efx = pci_get_drvdata(pci_dev);
+	int rc;
+
+	rc = pci_set_power_state(pci_dev, PCI_D0);
+	if (rc)
+		return rc;
+	pci_restore_state(pci_dev);
+	rc = pci_enable_device(pci_dev);
+	if (rc)
+		return rc;
+	pci_set_master(efx->pci_dev);
+	rc = efx->type->reset(efx, RESET_TYPE_ALL);
+	if (rc)
+		return rc;
+	rc = efx->type->init(efx);
+	if (rc)
+		return rc;
+	efx_pm_thaw(dev);
+	return 0;
+}
+
+static int efx_pm_suspend(struct device *dev)
+{
+	int rc;
+
+	efx_pm_freeze(dev);
+	rc = efx_pm_poweroff(dev);
+	if (rc)
+		efx_pm_resume(dev);
+	return rc;
+}
+
+static struct dev_pm_ops efx_pm_ops = {
+	.suspend	= efx_pm_suspend,
+	.resume		= efx_pm_resume,
+	.freeze		= efx_pm_freeze,
+	.thaw		= efx_pm_thaw,
+	.poweroff	= efx_pm_poweroff,
+	.restore	= efx_pm_resume,
+};
+
 static struct pci_driver efx_pci_driver = {
 	.name		= EFX_DRIVER_NAME,
 	.id_table	= efx_pci_table,
 	.probe		= efx_pci_probe,
 	.remove		= efx_pci_remove,
+	.driver.pm	= &efx_pm_ops,
 };
 
 /**************************************************************************
@@ -2314,8 +2454,8 @@ static void __exit efx_exit_module(void)
 module_init(efx_init_module);
 module_exit(efx_exit_module);
 
-MODULE_AUTHOR("Michael Brown <mbrown@fensystems.co.uk> and "
-	      "Solarflare Communications");
+MODULE_AUTHOR("Solarflare Communications and "
+	      "Michael Brown <mbrown@fensystems.co.uk>");
 MODULE_DESCRIPTION("Solarflare Communications network driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, efx_pci_table);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/efx.h linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/efx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/efx.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -18,35 +18,64 @@
 #define FALCON_A_P_DEVID	0x0703
 #define FALCON_A_S_DEVID        0x6703
 #define FALCON_B_P_DEVID        0x0710
+#define BETHPAGE_A_P_DEVID      0x0803
+#define SIENA_A_P_DEVID         0x0813
+
+/* Solarstorm controllers use BAR 0 for I/O space and BAR 2(&3) for memory */
+#define EFX_MEM_BAR 2
 
 /* TX */
-extern netdev_tx_t efx_xmit(struct efx_nic *efx,
-				  struct efx_tx_queue *tx_queue,
-				  struct sk_buff *skb);
+extern int efx_probe_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
+extern netdev_tx_t
+efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
+extern netdev_tx_t
+efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
 extern void efx_stop_queue(struct efx_nic *efx);
 extern void efx_wake_queue(struct efx_nic *efx);
+#define EFX_TXQ_SIZE 1024
+#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1)
 
 /* RX */
-extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
+extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_rx_strategy(struct efx_channel *channel);
+extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
+extern void efx_rx_work(struct work_struct *data);
+extern void __efx_rx_packet(struct efx_channel *channel,
+			    struct efx_rx_buffer *rx_buf, bool checksummed);
 extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 			  unsigned int len, bool checksummed, bool discard);
 extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay);
+#define EFX_RXQ_SIZE 1024
+#define EFX_RXQ_MASK (EFX_RXQ_SIZE - 1)
 
 /* Channels */
 extern void efx_process_channel_now(struct efx_channel *channel);
-extern void efx_flush_queues(struct efx_nic *efx);
+#define EFX_EVQ_SIZE 4096
+#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
 
 /* Ports */
-extern void efx_stats_disable(struct efx_nic *efx);
-extern void efx_stats_enable(struct efx_nic *efx);
-extern void efx_reconfigure_port(struct efx_nic *efx);
-extern void __efx_reconfigure_port(struct efx_nic *efx);
+extern int efx_reconfigure_port(struct efx_nic *efx);
+extern int __efx_reconfigure_port(struct efx_nic *efx);
+
+/* Ethtool support */
+extern int efx_ethtool_get_settings(struct net_device *net_dev,
+				    struct ethtool_cmd *ecmd);
+extern int efx_ethtool_set_settings(struct net_device *net_dev,
+				    struct ethtool_cmd *ecmd);
+extern const struct ethtool_ops efx_ethtool_ops;
 
 /* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
-			   struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
-			struct ethtool_cmd *ecmd, bool ok);
+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);
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
@@ -60,7 +89,9 @@ extern void efx_hex_dump(const u8 *, uns
 /* Dummy PHY ops for PHY drivers */
 extern int efx_port_dummy_op_int(struct efx_nic *efx);
 extern void efx_port_dummy_op_void(struct efx_nic *efx);
-extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink);
+extern void
+efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
+extern bool efx_port_dummy_op_poll(struct efx_nic *efx);
 
 /* MTD */
 #ifdef CONFIG_SFC_MTD
@@ -84,4 +115,8 @@ static inline void efx_schedule_channel(
 	napi_schedule(&channel->napi_str);
 }
 
+extern void efx_link_status_changed(struct efx_nic *efx);
+extern void efx_link_set_advertising(struct efx_nic *efx, u32);
+extern void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type);
+
 #endif /* EFX_EFX_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/enum.h linux-libre-2.6.33-gnu1/drivers/net/sfc/enum.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/enum.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/enum.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications Inc.
+ * Copyright 2007-2009 Solarflare Communications 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
@@ -13,44 +13,101 @@
 /**
  * enum efx_loopback_mode - loopback modes
  * @LOOPBACK_NONE: no loopback
- * @LOOPBACK_GMAC: loopback within GMAC at unspecified level
- * @LOOPBACK_XGMII: loopback within XMAC at XGMII level
- * @LOOPBACK_XGXS: loopback within XMAC at XGXS level
- * @LOOPBACK_XAUI: loopback within XMAC at XAUI level
+ * @LOOPBACK_DATA: data path loopback
+ * @LOOPBACK_GMAC: loopback within GMAC
+ * @LOOPBACK_XGMII: loopback after XMAC
+ * @LOOPBACK_XGXS: loopback within BPX after XGXS
+ * @LOOPBACK_XAUI: loopback within BPX before XAUI serdes
+ * @LOOPBACK_GMII: loopback within BPX after GMAC
+ * @LOOPBACK_SGMII: loopback within BPX within SGMII
+ * @LOOPBACK_XGBR: loopback within BPX within XGBR
+ * @LOOPBACK_XFI: loopback within BPX before XFI serdes
+ * @LOOPBACK_XAUI_FAR: loopback within BPX after XAUI serdes
+ * @LOOPBACK_GMII_FAR: loopback within BPX before SGMII
+ * @LOOPBACK_SGMII_FAR: loopback within BPX after SGMII
+ * @LOOPBACK_XFI_FAR: loopback after XFI serdes
  * @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level
  * @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level
  * @LOOPBACK_PCS: loopback within 10G PHY at PCS level
  * @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level
- * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!)
+ * @LOOPBACK_XPORT: cross port loopback
+ * @LOOPBACK_XGMII_WS: wireside loopback excluding XMAC
+ * @LOOPBACK_XAUI_WS: wireside loopback within BPX within XAUI serdes
+ * @LOOPBACK_XAUI_WS_FAR: wireside loopback within BPX including XAUI serdes
+ * @LOOPBACK_XAUI_WS_NEAR: wireside loopback within BPX excluding XAUI serdes
+ * @LOOPBACK_GMII_WS: wireside loopback excluding GMAC
+ * @LOOPBACK_XFI_WS: wireside loopback excluding XFI serdes
+ * @LOOPBACK_XFI_WS_FAR: wireside loopback including XFI serdes
+ * @LOOPBACK_PHYXS_WS: wireside loopback within 10G PHY at PHYXS level
  */
-/* Please keep in order and up-to-date w.r.t the following two #defines */
+/* Please keep up-to-date w.r.t the following two #defines */
 enum efx_loopback_mode {
 	LOOPBACK_NONE = 0,
-	LOOPBACK_GMAC = 1,
-	LOOPBACK_XGMII = 2,
-	LOOPBACK_XGXS = 3,
-	LOOPBACK_XAUI = 4,
-	LOOPBACK_GPHY = 5,
-	LOOPBACK_PHYXS = 6,
-	LOOPBACK_PCS = 7,
-	LOOPBACK_PMAPMD = 8,
-	LOOPBACK_NETWORK = 9,
+	LOOPBACK_DATA = 1,
+	LOOPBACK_GMAC = 2,
+	LOOPBACK_XGMII = 3,
+	LOOPBACK_XGXS = 4,
+	LOOPBACK_XAUI = 5,
+	LOOPBACK_GMII = 6,
+	LOOPBACK_SGMII = 7,
+	LOOPBACK_XGBR = 8,
+	LOOPBACK_XFI = 9,
+	LOOPBACK_XAUI_FAR = 10,
+	LOOPBACK_GMII_FAR = 11,
+	LOOPBACK_SGMII_FAR = 12,
+	LOOPBACK_XFI_FAR = 13,
+	LOOPBACK_GPHY = 14,
+	LOOPBACK_PHYXS = 15,
+	LOOPBACK_PCS = 16,
+	LOOPBACK_PMAPMD = 17,
+	LOOPBACK_XPORT = 18,
+	LOOPBACK_XGMII_WS = 19,
+	LOOPBACK_XAUI_WS = 20,
+	LOOPBACK_XAUI_WS_FAR = 21,
+	LOOPBACK_XAUI_WS_NEAR = 22,
+	LOOPBACK_GMII_WS = 23,
+	LOOPBACK_XFI_WS = 24,
+	LOOPBACK_XFI_WS_FAR = 25,
+	LOOPBACK_PHYXS_WS = 26,
 	LOOPBACK_MAX
 };
-
 #define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD
 
-extern const char *efx_loopback_mode_names[];
-#define LOOPBACK_MODE_NAME(mode)			\
-	STRING_TABLE_LOOKUP(mode, efx_loopback_mode)
-#define LOOPBACK_MODE(efx)				\
-	LOOPBACK_MODE_NAME(efx->loopback_mode)
-
 /* These loopbacks occur within the controller */
-#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) |     \
-			    (1 << LOOPBACK_XGMII)|     \
-			    (1 << LOOPBACK_XGXS) |     \
-			    (1 << LOOPBACK_XAUI))
+#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_DATA) |		\
+			    (1 << LOOPBACK_GMAC) |		\
+			    (1 << LOOPBACK_XGMII)|		\
+			    (1 << LOOPBACK_XGXS) |		\
+			    (1 << LOOPBACK_XAUI) |		\
+			    (1 << LOOPBACK_GMII) |		\
+			    (1 << LOOPBACK_SGMII) |		\
+			    (1 << LOOPBACK_SGMII) |		\
+			    (1 << LOOPBACK_XGBR) |		\
+			    (1 << LOOPBACK_XFI) |		\
+			    (1 << LOOPBACK_XAUI_FAR) |		\
+			    (1 << LOOPBACK_GMII_FAR) |		\
+			    (1 << LOOPBACK_SGMII_FAR) |		\
+			    (1 << LOOPBACK_XFI_FAR) |		\
+			    (1 << LOOPBACK_XGMII_WS) |		\
+			    (1 << LOOPBACK_XAUI_WS) |		\
+			    (1 << LOOPBACK_XAUI_WS_FAR) |	\
+			    (1 << LOOPBACK_XAUI_WS_NEAR) |	\
+			    (1 << LOOPBACK_GMII_WS) |		\
+			    (1 << LOOPBACK_XFI_WS) |		\
+			    (1 << LOOPBACK_XFI_WS_FAR))
+
+#define LOOPBACKS_WS ((1 << LOOPBACK_XGMII_WS) |		\
+		      (1 << LOOPBACK_XAUI_WS) |			\
+		      (1 << LOOPBACK_XAUI_WS_FAR) |		\
+		      (1 << LOOPBACK_XAUI_WS_NEAR) |		\
+		      (1 << LOOPBACK_GMII_WS) |			\
+		      (1 << LOOPBACK_XFI_WS) |			\
+		      (1 << LOOPBACK_XFI_WS_FAR) |		\
+		      (1 << LOOPBACK_PHYXS_WS))
+
+#define LOOPBACKS_EXTERNAL(_efx)					\
+	((_efx)->loopback_modes & ~LOOPBACKS_INTERNAL &			\
+	 ~(1 << LOOPBACK_NONE))
 
 #define LOOPBACK_MASK(_efx)			\
 	(1 << (_efx)->loopback_mode)
@@ -58,6 +115,9 @@ extern const char *efx_loopback_mode_nam
 #define LOOPBACK_INTERNAL(_efx)				\
 	(!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx)))
 
+#define LOOPBACK_EXTERNAL(_efx)				\
+	(!!(LOOPBACK_MASK(_efx) & LOOPBACKS_EXTERNAL(_efx)))
+
 #define LOOPBACK_CHANGED(_from, _to, _mask)				\
 	(!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask)))
 
@@ -84,6 +144,7 @@ extern const char *efx_loopback_mode_nam
  * @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch
  * @RESET_TYPE_TX_DESC_FETCH: pcie error during tx descriptor fetch
  * @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors
+ * @RESET_TYPE_MC_FAILURE: MC reboot/assertion
  */
 enum reset_type {
 	RESET_TYPE_NONE = -1,
@@ -98,6 +159,7 @@ enum reset_type {
 	RESET_TYPE_RX_DESC_FETCH,
 	RESET_TYPE_TX_DESC_FETCH,
 	RESET_TYPE_TX_SKIP,
+	RESET_TYPE_MC_FAILURE,
 	RESET_TYPE_MAX,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/ethtool.c linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -10,30 +10,15 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
-#include <linux/mdio.h>
 #include <linux/rtnetlink.h>
 #include "net_driver.h"
 #include "workarounds.h"
 #include "selftest.h"
 #include "efx.h"
-#include "ethtool.h"
-#include "falcon.h"
+#include "nic.h"
 #include "spi.h"
 #include "mdio_10g.h"
 
-const char *efx_loopback_mode_names[] = {
-	[LOOPBACK_NONE]		= "NONE",
-	[LOOPBACK_GMAC]		= "GMAC",
-	[LOOPBACK_XGMII]	= "XGMII",
-	[LOOPBACK_XGXS]		= "XGXS",
-	[LOOPBACK_XAUI] 	= "XAUI",
-	[LOOPBACK_GPHY]		= "GPHY",
-	[LOOPBACK_PHYXS]	= "PHYXS",
-	[LOOPBACK_PCS]	 	= "PCS",
-	[LOOPBACK_PMAPMD]	= "PMA/PMD",
-	[LOOPBACK_NETWORK]	= "NETWORK",
-};
-
 struct ethtool_string {
 	char name[ETH_GSTRING_LEN];
 };
@@ -167,6 +152,7 @@ static struct efx_ethtool_stat efx_ethto
 	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc),
 	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err),
 	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err),
+	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch),
 	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc),
 };
 
@@ -187,13 +173,15 @@ static int efx_ethtool_phys_id(struct ne
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
-	efx->board_info.blink(efx, 1);
-	set_current_state(TASK_INTERRUPTIBLE);
-	if (count)
-		schedule_timeout(count * HZ);
-	else
-		schedule();
-	efx->board_info.blink(efx, 0);
+	do {
+		efx->type->set_id_led(efx, EFX_LED_ON);
+		schedule_timeout_interruptible(HZ / 2);
+
+		efx->type->set_id_led(efx, EFX_LED_OFF);
+		schedule_timeout_interruptible(HZ / 2);
+	} while (!signal_pending(current) && --count != 0);
+
+	efx->type->set_id_led(efx, EFX_LED_DEFAULT);
 	return 0;
 }
 
@@ -202,6 +190,7 @@ int efx_ethtool_get_settings(struct net_
 			     struct ethtool_cmd *ecmd)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
+	struct efx_link_state *link_state = &efx->link_state;
 
 	mutex_lock(&efx->mac_lock);
 	efx->phy_op->get_settings(efx, ecmd);
@@ -209,6 +198,13 @@ int efx_ethtool_get_settings(struct net_
 
 	/* Falcon GMAC does not support 1000Mbps HD */
 	ecmd->supported &= ~SUPPORTED_1000baseT_Half;
+	/* Both MACs support pause frames (bidirectional and respond-only) */
+	ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
+	if (LOOPBACK_INTERNAL(efx)) {
+		ecmd->speed = link_state->speed;
+		ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
+	}
 
 	return 0;
 }
@@ -230,9 +226,6 @@ int efx_ethtool_set_settings(struct net_
 	mutex_lock(&efx->mac_lock);
 	rc = efx->phy_op->set_settings(efx, ecmd);
 	mutex_unlock(&efx->mac_lock);
-	if (!rc)
-		efx_reconfigure_port(efx);
-
 	return rc;
 }
 
@@ -243,6 +236,9 @@ static void efx_ethtool_get_drvinfo(stru
 
 	strlcpy(info->driver, EFX_DRIVER_NAME, sizeof(info->driver));
 	strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version));
+	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
+		siena_print_fwver(efx, info->fw_version,
+				  sizeof(info->fw_version));
 	strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
 }
 
@@ -289,7 +285,7 @@ static void efx_fill_test(unsigned int t
 #define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
 #define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
 #define EFX_LOOPBACK_NAME(_mode, _counter)			\
-	"loopback.%s." _counter, LOOPBACK_MODE_NAME(mode)
+	"loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode)
 
 /**
  * efx_fill_loopback_test - fill in a block of loopback self-test entries
@@ -372,9 +368,21 @@ static int efx_ethtool_fill_self_tests(s
 	efx_fill_test(n++, strings, data, &tests->registers,
 		      "core", 0, "registers", NULL);
 
-	for (i = 0; i < efx->phy_op->num_tests; i++)
-		efx_fill_test(n++, strings, data, &tests->phy[i],
-			      "phy", 0, efx->phy_op->test_names[i], NULL);
+	if (efx->phy_op->run_tests != NULL) {
+		EFX_BUG_ON_PARANOID(efx->phy_op->test_name == NULL);
+
+		for (i = 0; true; ++i) {
+			const char *name;
+
+			EFX_BUG_ON_PARANOID(i >= EFX_MAX_PHY_TESTS);
+			name = efx->phy_op->test_name(efx, i);
+			if (name == NULL)
+				break;
+
+			efx_fill_test(n++, strings, data, &tests->phy[i],
+				      "phy", 0, name, NULL);
+		}
+	}
 
 	/* Loopback tests */
 	for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) {
@@ -463,6 +471,36 @@ static void efx_ethtool_get_stats(struct
 	}
 }
 
+static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
+{
+	struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev);
+	unsigned long features;
+
+	features = NETIF_F_TSO;
+	if (efx->type->offload_features & NETIF_F_V6_CSUM)
+		features |= NETIF_F_TSO6;
+
+	if (enable)
+		net_dev->features |= features;
+	else
+		net_dev->features &= ~features;
+
+	return 0;
+}
+
+static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	unsigned long features = efx->type->offload_features & NETIF_F_ALL_CSUM;
+
+	if (enable)
+		net_dev->features |= features;
+	else
+		net_dev->features &= ~features;
+
+	return 0;
+}
+
 static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
@@ -537,7 +575,7 @@ static u32 efx_ethtool_get_link(struct n
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
-	return efx->link_up;
+	return efx->link_state.up;
 }
 
 static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
@@ -562,7 +600,8 @@ static int efx_ethtool_get_eeprom(struct
 	rc = mutex_lock_interruptible(&efx->spi_lock);
 	if (rc)
 		return rc;
-	rc = falcon_spi_read(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
+	rc = falcon_spi_read(efx, spi,
+			     eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
 			     eeprom->len, &len, buf);
 	mutex_unlock(&efx->spi_lock);
 
@@ -585,7 +624,8 @@ static int efx_ethtool_set_eeprom(struct
 	rc = mutex_lock_interruptible(&efx->spi_lock);
 	if (rc)
 		return rc;
-	rc = falcon_spi_write(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
+	rc = falcon_spi_write(efx, spi,
+			      eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
 			      eeprom->len, &len, buf);
 	mutex_unlock(&efx->spi_lock);
 
@@ -618,6 +658,9 @@ static int efx_ethtool_get_coalesce(stru
 	coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
 	coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
 
+	coalesce->tx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION;
+	coalesce->rx_coalesce_usecs_irq *= EFX_IRQ_MOD_RESOLUTION;
+
 	return 0;
 }
 
@@ -656,13 +699,8 @@ static int efx_ethtool_set_coalesce(stru
 	}
 
 	efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive);
-
-	/* Reset channel to pick up new moderation value.  Note that
-	 * this may change the value of the irq_moderation field
-	 * (e.g. to allow for hardware timer granularity).
-	 */
 	efx_for_each_channel(channel, efx)
-		falcon_set_int_moderation(channel);
+		efx->type->push_irq_moderation(channel);
 
 	return 0;
 }
@@ -671,8 +709,12 @@ static int efx_ethtool_set_pauseparam(st
 				      struct ethtool_pauseparam *pause)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	enum efx_fc_type wanted_fc;
+	enum efx_fc_type wanted_fc, old_fc;
+	u32 old_adv;
 	bool reset;
+	int rc = 0;
+
+	mutex_lock(&efx->mac_lock);
 
 	wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
 		     (pause->tx_pause ? EFX_FC_TX : 0) |
@@ -680,14 +722,14 @@ static int efx_ethtool_set_pauseparam(st
 
 	if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
 		EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
-	if (!(efx->phy_op->mmds & MDIO_DEVS_AN) &&
-	    (wanted_fc & EFX_FC_AUTO)) {
-		EFX_LOG(efx, "PHY does not support flow control "
-			"autonegotiation\n");
-		return -EINVAL;
+	if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising) {
+		EFX_LOG(efx, "Autonegotiation is disabled\n");
+		rc = -EINVAL;
+		goto out;
 	}
 
 	/* TX flow control may automatically turn itself off if the
@@ -697,27 +739,40 @@ static int efx_ethtool_set_pauseparam(st
 	 * and fix it be cycling transmit flow control on this end. */
 	reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX);
 	if (EFX_WORKAROUND_11482(efx) && reset) {
-		if (falcon_rev(efx) >= FALCON_REV_B0) {
+		if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
 			/* Recover by resetting the EM block */
-			if (efx->link_up)
-				falcon_drain_tx_fifo(efx);
+			falcon_stop_nic_stats(efx);
+			falcon_drain_tx_fifo(efx);
+			efx->mac_op->reconfigure(efx);
+			falcon_start_nic_stats(efx);
 		} else {
 			/* Schedule a reset to recover */
 			efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
 		}
 	}
 
-	/* Try to push the pause parameters */
-	mutex_lock(&efx->mac_lock);
+	old_adv = efx->link_advertising;
+	old_fc = efx->wanted_fc;
+	efx_link_set_wanted_fc(efx, wanted_fc);
+	if (efx->link_advertising != old_adv ||
+	    (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
+		rc = efx->phy_op->reconfigure(efx);
+		if (rc) {
+			EFX_ERR(efx, "Unable to advertise requested flow "
+				"control setting\n");
+			goto out;
+		}
+	}
 
-	efx->wanted_fc = wanted_fc;
-	if (efx->phy_op->mmds & MDIO_DEVS_AN)
-		mdio45_ethtool_spauseparam_an(&efx->mdio, pause);
-	__efx_reconfigure_port(efx);
+	/* Reconfigure the MAC. The PHY *may* generate a link state change event
+	 * if the user just changed the advertised capabilities, but there's no
+	 * harm doing this twice */
+	efx->mac_op->reconfigure(efx);
 
+out:
 	mutex_unlock(&efx->mac_lock);
 
-	return 0;
+	return rc;
 }
 
 static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
@@ -731,6 +786,50 @@ static void efx_ethtool_get_pauseparam(s
 }
 
 
+static void efx_ethtool_get_wol(struct net_device *net_dev,
+				struct ethtool_wolinfo *wol)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	return efx->type->get_wol(efx, wol);
+}
+
+
+static int efx_ethtool_set_wol(struct net_device *net_dev,
+			       struct ethtool_wolinfo *wol)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	return efx->type->set_wol(efx, wol->wolopts);
+}
+
+extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	enum reset_type method;
+	enum {
+		ETH_RESET_EFX_INVISIBLE = (ETH_RESET_DMA | ETH_RESET_FILTER |
+					   ETH_RESET_OFFLOAD | ETH_RESET_MAC)
+	};
+
+	/* Check for minimal reset flags */
+	if ((*flags & ETH_RESET_EFX_INVISIBLE) != ETH_RESET_EFX_INVISIBLE)
+		return -EINVAL;
+	*flags ^= ETH_RESET_EFX_INVISIBLE;
+	method = RESET_TYPE_INVISIBLE;
+
+	if (*flags & ETH_RESET_PHY) {
+		*flags ^= ETH_RESET_PHY;
+		method = RESET_TYPE_ALL;
+	}
+
+	if ((*flags & efx->type->reset_world_flags) ==
+	    efx->type->reset_world_flags) {
+		*flags ^= efx->type->reset_world_flags;
+		method = RESET_TYPE_WORLD;
+	}
+
+	return efx_reset(efx, method);
+}
+
 const struct ethtool_ops efx_ethtool_ops = {
 	.get_settings		= efx_ethtool_get_settings,
 	.set_settings		= efx_ethtool_set_settings,
@@ -747,11 +846,13 @@ const struct ethtool_ops efx_ethtool_ops
 	.get_rx_csum		= efx_ethtool_get_rx_csum,
 	.set_rx_csum		= efx_ethtool_set_rx_csum,
 	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
+	/* Need to enable/disable IPv6 too */
+	.set_tx_csum		= efx_ethtool_set_tx_csum,
 	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
 	.get_tso		= ethtool_op_get_tso,
-	.set_tso		= ethtool_op_set_tso,
+	/* Need to enable/disable TSO-IPv6 too */
+	.set_tso		= efx_ethtool_set_tso,
 	.get_flags		= ethtool_op_get_flags,
 	.set_flags		= ethtool_op_set_flags,
 	.get_sset_count		= efx_ethtool_get_sset_count,
@@ -759,4 +860,7 @@ const struct ethtool_ops efx_ethtool_ops
 	.get_strings		= efx_ethtool_get_strings,
 	.phys_id		= efx_ethtool_phys_id,
 	.get_ethtool_stats	= efx_ethtool_get_stats,
+	.get_wol                = efx_ethtool_get_wol,
+	.set_wol                = efx_ethtool_set_wol,
+	.reset			= efx_ethtool_reset,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/ethtool.h linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/ethtool.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/ethtool.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005 Fen Systems Ltd.
- * Copyright 2006 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_ETHTOOL_H
-#define EFX_ETHTOOL_H
-
-#include "net_driver.h"
-
-/*
- * Ethtool support
- */
-
-extern int efx_ethtool_get_settings(struct net_device *net_dev,
-				    struct ethtool_cmd *ecmd);
-extern int efx_ethtool_set_settings(struct net_device *net_dev,
-				    struct ethtool_cmd *ecmd);
-
-extern const struct ethtool_ops efx_ethtool_ops;
-
-#endif /* EFX_ETHTOOL_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_boards.c linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_boards.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_boards.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_boards.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,761 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2007-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/rtnetlink.h>
+
+#include "net_driver.h"
+#include "phy.h"
+#include "efx.h"
+#include "nic.h"
+#include "regs.h"
+#include "io.h"
+#include "workarounds.h"
+
+/* Macros for unpacking the board revision */
+/* The revision info is in host byte order. */
+#define FALCON_BOARD_TYPE(_rev) (_rev >> 8)
+#define FALCON_BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
+#define FALCON_BOARD_MINOR(_rev) (_rev & 0xf)
+
+/* Board types */
+#define FALCON_BOARD_SFE4001 0x01
+#define FALCON_BOARD_SFE4002 0x02
+#define FALCON_BOARD_SFN4111T 0x51
+#define FALCON_BOARD_SFN4112F 0x52
+
+/* Board temperature is about 15°C above ambient when air flow is
+ * limited. */
+#define FALCON_BOARD_TEMP_BIAS	15
+
+/* SFC4000 datasheet says: 'The maximum permitted junction temperature
+ * is 125°C; the thermal design of the environment for the SFC4000
+ * should aim to keep this well below 100°C.' */
+#define FALCON_JUNC_TEMP_MAX	90
+
+/*****************************************************************************
+ * Support for LM87 sensor chip used on several boards
+ */
+#define LM87_REG_ALARMS1		0x41
+#define LM87_REG_ALARMS2		0x42
+#define LM87_IN_LIMITS(nr, _min, _max)			\
+	0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
+#define LM87_AIN_LIMITS(nr, _min, _max)			\
+	0x3B + (nr), _max, 0x1A + (nr), _min
+#define LM87_TEMP_INT_LIMITS(_min, _max)		\
+	0x39, _max, 0x3A, _min
+#define LM87_TEMP_EXT1_LIMITS(_min, _max)		\
+	0x37, _max, 0x38, _min
+
+#define LM87_ALARM_TEMP_INT		0x10
+#define LM87_ALARM_TEMP_EXT1		0x20
+
+#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
+
+static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+			 const u8 *reg_values)
+{
+	struct falcon_board *board = falcon_board(efx);
+	struct i2c_client *client = i2c_new_device(&board->i2c_adap, info);
+	int rc;
+
+	if (!client)
+		return -EIO;
+
+	while (*reg_values) {
+		u8 reg = *reg_values++;
+		u8 value = *reg_values++;
+		rc = i2c_smbus_write_byte_data(client, reg, value);
+		if (rc)
+			goto err;
+	}
+
+	board->hwmon_client = client;
+	return 0;
+
+err:
+	i2c_unregister_device(client);
+	return rc;
+}
+
+static void efx_fini_lm87(struct efx_nic *efx)
+{
+	i2c_unregister_device(falcon_board(efx)->hwmon_client);
+}
+
+static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
+{
+	struct i2c_client *client = falcon_board(efx)->hwmon_client;
+	s32 alarms1, alarms2;
+
+	/* If link is up then do not monitor temperature */
+	if (EFX_WORKAROUND_7884(efx) && efx->link_state.up)
+		return 0;
+
+	alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
+	alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
+	if (alarms1 < 0)
+		return alarms1;
+	if (alarms2 < 0)
+		return alarms2;
+	alarms1 &= mask;
+	alarms2 &= mask >> 8;
+	if (alarms1 || alarms2) {
+		EFX_ERR(efx,
+			"LM87 detected a hardware failure (status %02x:%02x)"
+			"%s%s\n",
+			alarms1, alarms2,
+			(alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "",
+			(alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : "");
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
+#else /* !CONFIG_SENSORS_LM87 */
+
+static inline int
+efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+	      const u8 *reg_values)
+{
+	return 0;
+}
+static inline void efx_fini_lm87(struct efx_nic *efx)
+{
+}
+static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
+{
+	return 0;
+}
+
+#endif /* CONFIG_SENSORS_LM87 */
+
+/*****************************************************************************
+ * Support for the SFE4001 and SFN4111T NICs.
+ *
+ * The SFE4001 does not power-up fully at reset due to its high power
+ * consumption.  We control its power via a PCA9539 I/O expander.
+ * Both boards have a MAX6647 temperature monitor which we expose to
+ * the lm90 driver.
+ *
+ * This also provides minimal support for reflashing the PHY, which is
+ * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
+ * On SFE4001 rev A2 and later this is connected to the 3V3X output of
+ * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3.
+ * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
+ * exclusive with the network device being open.
+ */
+
+/**************************************************************************
+ * Support for I2C IO Expander device on SFE4001
+ */
+#define	PCA9539 0x74
+
+#define	P0_IN 0x00
+#define	P0_OUT 0x02
+#define	P0_INVERT 0x04
+#define	P0_CONFIG 0x06
+
+#define	P0_EN_1V0X_LBN 0
+#define	P0_EN_1V0X_WIDTH 1
+#define	P0_EN_1V2_LBN 1
+#define	P0_EN_1V2_WIDTH 1
+#define	P0_EN_2V5_LBN 2
+#define	P0_EN_2V5_WIDTH 1
+#define	P0_EN_3V3X_LBN 3
+#define	P0_EN_3V3X_WIDTH 1
+#define	P0_EN_5V_LBN 4
+#define	P0_EN_5V_WIDTH 1
+#define	P0_SHORTEN_JTAG_LBN 5
+#define	P0_SHORTEN_JTAG_WIDTH 1
+#define	P0_X_TRST_LBN 6
+#define	P0_X_TRST_WIDTH 1
+#define	P0_DSP_RESET_LBN 7
+#define	P0_DSP_RESET_WIDTH 1
+
+#define	P1_IN 0x01
+#define	P1_OUT 0x03
+#define	P1_INVERT 0x05
+#define	P1_CONFIG 0x07
+
+#define	P1_AFE_PWD_LBN 0
+#define	P1_AFE_PWD_WIDTH 1
+#define	P1_DSP_PWD25_LBN 1
+#define	P1_DSP_PWD25_WIDTH 1
+#define	P1_RESERVED_LBN 2
+#define	P1_RESERVED_WIDTH 2
+#define	P1_SPARE_LBN 4
+#define	P1_SPARE_WIDTH 4
+
+/* Temperature Sensor */
+#define MAX664X_REG_RSL		0x02
+#define MAX664X_REG_WLHO	0x0B
+
+static void sfe4001_poweroff(struct efx_nic *efx)
+{
+	struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
+	struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
+
+	/* Turn off all power rails and disable outputs */
+	i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
+	i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff);
+	i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
+
+	/* Clear any over-temperature alert */
+	i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
+}
+
+static int sfe4001_poweron(struct efx_nic *efx)
+{
+	struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
+	struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
+	unsigned int i, j;
+	int rc;
+	u8 out;
+
+	/* Clear any previous over-temperature alert */
+	rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
+	if (rc < 0)
+		return rc;
+
+	/* Enable port 0 and port 1 outputs on IO expander */
+	rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
+	if (rc)
+		return rc;
+	rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
+				       0xff & ~(1 << P1_SPARE_LBN));
+	if (rc)
+		goto fail_on;
+
+	/* If PHY power is on, turn it all off and wait 1 second to
+	 * ensure a full reset.
+	 */
+	rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
+	if (rc < 0)
+		goto fail_on;
+	out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
+		       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
+		       (0 << P0_EN_1V0X_LBN));
+	if (rc != out) {
+		EFX_INFO(efx, "power-cycling PHY\n");
+		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
+		if (rc)
+			goto fail_on;
+		schedule_timeout_uninterruptible(HZ);
+	}
+
+	for (i = 0; i < 20; ++i) {
+		/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
+		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
+			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
+			       (1 << P0_X_TRST_LBN));
+		if (efx->phy_mode & PHY_MODE_SPECIAL)
+			out |= 1 << P0_EN_3V3X_LBN;
+
+		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
+		if (rc)
+			goto fail_on;
+		msleep(10);
+
+		/* Turn on 1V power rail */
+		out &= ~(1 << P0_EN_1V0X_LBN);
+		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
+		if (rc)
+			goto fail_on;
+
+		EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i);
+
+		/* In flash config mode, DSP does not turn on AFE, so
+		 * just wait 1 second.
+		 */
+		if (efx->phy_mode & PHY_MODE_SPECIAL) {
+			schedule_timeout_uninterruptible(HZ);
+			return 0;
+		}
+
+		for (j = 0; j < 10; ++j) {
+			msleep(100);
+
+			/* Check DSP has asserted AFE power line */
+			rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
+			if (rc < 0)
+				goto fail_on;
+			if (rc & (1 << P1_AFE_PWD_LBN))
+				return 0;
+		}
+	}
+
+	EFX_INFO(efx, "timed out waiting for DSP boot\n");
+	rc = -ETIMEDOUT;
+fail_on:
+	sfe4001_poweroff(efx);
+	return rc;
+}
+
+static int sfn4111t_reset(struct efx_nic *efx)
+{
+	struct falcon_board *board = falcon_board(efx);
+	efx_oword_t reg;
+
+	/* GPIO 3 and the GPIO register are shared with I2C, so block that */
+	i2c_lock_adapter(&board->i2c_adap);
+
+	/* Pull RST_N (GPIO 2) low then let it up again, setting the
+	 * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
+	 * output enables; the output levels should always be 0 (low)
+	 * and we rely on external pull-ups. */
+	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true);
+	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
+	msleep(1000);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN,
+			    !!(efx->phy_mode & PHY_MODE_SPECIAL));
+	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
+	msleep(1);
+
+	i2c_unlock_adapter(&board->i2c_adap);
+
+	ssleep(1);
+	return 0;
+}
+
+static ssize_t show_phy_flash_cfg(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+	return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
+}
+
+static ssize_t set_phy_flash_cfg(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+	enum efx_phy_mode old_mode, new_mode;
+	int err;
+
+	rtnl_lock();
+	old_mode = efx->phy_mode;
+	if (count == 0 || *buf == '0')
+		new_mode = old_mode & ~PHY_MODE_SPECIAL;
+	else
+		new_mode = PHY_MODE_SPECIAL;
+	if (old_mode == new_mode) {
+		err = 0;
+	} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
+		err = -EBUSY;
+	} else {
+		/* Reset the PHY, reconfigure the MAC and enable/disable
+		 * MAC stats accordingly. */
+		efx->phy_mode = new_mode;
+		if (new_mode & PHY_MODE_SPECIAL)
+			falcon_stop_nic_stats(efx);
+		if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001)
+			err = sfe4001_poweron(efx);
+		else
+			err = sfn4111t_reset(efx);
+		if (!err)
+			err = efx_reconfigure_port(efx);
+		if (!(new_mode & PHY_MODE_SPECIAL))
+			falcon_start_nic_stats(efx);
+	}
+	rtnl_unlock();
+
+	return err ? err : count;
+}
+
+static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
+
+static void sfe4001_fini(struct efx_nic *efx)
+{
+	struct falcon_board *board = falcon_board(efx);
+
+	EFX_INFO(efx, "%s\n", __func__);
+
+	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+	sfe4001_poweroff(efx);
+	i2c_unregister_device(board->ioexp_client);
+	i2c_unregister_device(board->hwmon_client);
+}
+
+static int sfe4001_check_hw(struct efx_nic *efx)
+{
+	s32 status;
+
+	/* If XAUI link is up then do not monitor */
+	if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
+		return 0;
+
+	/* Check the powered status of the PHY. Lack of power implies that
+	 * the MAX6647 has shut down power to it, probably due to a temp.
+	 * alarm. Reading the power status rather than the MAX6647 status
+	 * directly because the later is read-to-clear and would thus
+	 * start to power up the PHY again when polled, causing us to blip
+	 * the power undesirably.
+	 * We know we can read from the IO expander because we did
+	 * it during power-on. Assume failure now is bad news. */
+	status = i2c_smbus_read_byte_data(falcon_board(efx)->ioexp_client, P1_IN);
+	if (status >= 0 &&
+	    (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
+		return 0;
+
+	/* Use board power control, not PHY power control */
+	sfe4001_poweroff(efx);
+	efx->phy_mode = PHY_MODE_OFF;
+
+	return (status < 0) ? -EIO : -ERANGE;
+}
+
+static struct i2c_board_info sfe4001_hwmon_info = {
+	I2C_BOARD_INFO("max6647", 0x4e),
+};
+
+/* This board uses an I2C expander to provider power to the PHY, which needs to
+ * be turned on before the PHY can be used.
+ * Context: Process context, rtnl lock held
+ */
+static int sfe4001_init(struct efx_nic *efx)
+{
+	struct falcon_board *board = falcon_board(efx);
+	int rc;
+
+#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
+	board->hwmon_client =
+		i2c_new_device(&board->i2c_adap, &sfe4001_hwmon_info);
+#else
+	board->hwmon_client =
+		i2c_new_dummy(&board->i2c_adap, sfe4001_hwmon_info.addr);
+#endif
+	if (!board->hwmon_client)
+		return -EIO;
+
+	/* Raise board/PHY high limit from 85 to 90 degrees Celsius */
+	rc = i2c_smbus_write_byte_data(board->hwmon_client,
+				       MAX664X_REG_WLHO, 90);
+	if (rc)
+		goto fail_hwmon;
+
+	board->ioexp_client = i2c_new_dummy(&board->i2c_adap, PCA9539);
+	if (!board->ioexp_client) {
+		rc = -EIO;
+		goto fail_hwmon;
+	}
+
+	if (efx->phy_mode & PHY_MODE_SPECIAL) {
+		/* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+		 * will fail. */
+		falcon_stop_nic_stats(efx);
+	}
+	rc = sfe4001_poweron(efx);
+	if (rc)
+		goto fail_ioexp;
+
+	rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+	if (rc)
+		goto fail_on;
+
+	EFX_INFO(efx, "PHY is powered on\n");
+	return 0;
+
+fail_on:
+	sfe4001_poweroff(efx);
+fail_ioexp:
+	i2c_unregister_device(board->ioexp_client);
+fail_hwmon:
+	i2c_unregister_device(board->hwmon_client);
+	return rc;
+}
+
+static int sfn4111t_check_hw(struct efx_nic *efx)
+{
+	s32 status;
+
+	/* If XAUI link is up then do not monitor */
+	if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
+		return 0;
+
+	/* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
+	status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client,
+					  MAX664X_REG_RSL);
+	if (status < 0)
+		return -EIO;
+	if (status & 0x57)
+		return -ERANGE;
+	return 0;
+}
+
+static void sfn4111t_fini(struct efx_nic *efx)
+{
+	EFX_INFO(efx, "%s\n", __func__);
+
+	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+	i2c_unregister_device(falcon_board(efx)->hwmon_client);
+}
+
+static struct i2c_board_info sfn4111t_a0_hwmon_info = {
+	I2C_BOARD_INFO("max6647", 0x4e),
+};
+
+static struct i2c_board_info sfn4111t_r5_hwmon_info = {
+	I2C_BOARD_INFO("max6646", 0x4d),
+};
+
+static void sfn4111t_init_phy(struct efx_nic *efx)
+{
+	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
+		if (sft9001_wait_boot(efx) != -EINVAL)
+			return;
+
+		efx->phy_mode = PHY_MODE_SPECIAL;
+		falcon_stop_nic_stats(efx);
+	}
+
+	sfn4111t_reset(efx);
+	sft9001_wait_boot(efx);
+}
+
+static int sfn4111t_init(struct efx_nic *efx)
+{
+	struct falcon_board *board = falcon_board(efx);
+	int rc;
+
+	board->hwmon_client =
+		i2c_new_device(&board->i2c_adap,
+			       (board->minor < 5) ?
+			       &sfn4111t_a0_hwmon_info :
+			       &sfn4111t_r5_hwmon_info);
+	if (!board->hwmon_client)
+		return -EIO;
+
+	rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+	if (rc)
+		goto fail_hwmon;
+
+	if (efx->phy_mode & PHY_MODE_SPECIAL)
+		/* PHY may not generate a 156.25 MHz clock and MAC
+		 * stats fetch will fail. */
+		falcon_stop_nic_stats(efx);
+
+	return 0;
+
+fail_hwmon:
+	i2c_unregister_device(board->hwmon_client);
+	return rc;
+}
+
+/*****************************************************************************
+ * Support for the SFE4002
+ *
+ */
+static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfe4002_lm87_regs[] = {
+	LM87_IN_LIMITS(0, 0x7c, 0x99),		/* 2.5V:  1.8V +/- 10% */
+	LM87_IN_LIMITS(1, 0x4c, 0x5e),		/* Vccp1: 1.2V +/- 10% */
+	LM87_IN_LIMITS(2, 0xac, 0xd4),		/* 3.3V:  3.3V +/- 10% */
+	LM87_IN_LIMITS(3, 0xac, 0xd4),		/* 5V:    5.0V +/- 10% */
+	LM87_IN_LIMITS(4, 0xac, 0xe0),		/* 12V:   10.8-14V */
+	LM87_IN_LIMITS(5, 0x3f, 0x4f),		/* Vccp2: 1.0V +/- 10% */
+	LM87_AIN_LIMITS(0, 0x98, 0xbb),		/* AIN1:  1.66V +/- 10% */
+	LM87_AIN_LIMITS(1, 0x8a, 0xa9),		/* AIN2:  1.5V +/- 10% */
+	LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS),
+	LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
+	0
+};
+
+static struct i2c_board_info sfe4002_hwmon_info = {
+	I2C_BOARD_INFO("lm87", 0x2e),
+	.platform_data	= &sfe4002_lm87_channel,
+};
+
+/****************************************************************************/
+/* LED allocations. Note that on rev A0 boards the schematic and the reality
+ * differ: red and green are swapped. Below is the fixed (A1) layout (there
+ * are only 3 A0 boards in existence, so no real reason to make this
+ * conditional).
+ */
+#define SFE4002_FAULT_LED (2)	/* Red */
+#define SFE4002_RX_LED    (0)	/* Green */
+#define SFE4002_TX_LED    (1)	/* Amber */
+
+static void sfe4002_init_phy(struct efx_nic *efx)
+{
+	/* Set the TX and RX LEDs to reflect status and activity, and the
+	 * fault LED off */
+	falcon_qt202x_set_led(efx, SFE4002_TX_LED,
+			      QUAKE_LED_TXLINK | QUAKE_LED_LINK_ACTSTAT);
+	falcon_qt202x_set_led(efx, SFE4002_RX_LED,
+			      QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
+	falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
+}
+
+static void sfe4002_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+	falcon_qt202x_set_led(
+		efx, SFE4002_FAULT_LED,
+		(mode == EFX_LED_ON) ? QUAKE_LED_ON : QUAKE_LED_OFF);
+}
+
+static int sfe4002_check_hw(struct efx_nic *efx)
+{
+	struct falcon_board *board = falcon_board(efx);
+
+	/* A0 board rev. 4002s report a temperature fault the whole time
+	 * (bad sensor) so we mask it out. */
+	unsigned alarm_mask =
+		(board->major == 0 && board->minor == 0) ?
+		~LM87_ALARM_TEMP_EXT1 : ~0;
+
+	return efx_check_lm87(efx, alarm_mask);
+}
+
+static int sfe4002_init(struct efx_nic *efx)
+{
+	return efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
+}
+
+/*****************************************************************************
+ * Support for the SFN4112F
+ *
+ */
+static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfn4112f_lm87_regs[] = {
+	LM87_IN_LIMITS(0, 0x7c, 0x99),		/* 2.5V:  1.8V +/- 10% */
+	LM87_IN_LIMITS(1, 0x4c, 0x5e),		/* Vccp1: 1.2V +/- 10% */
+	LM87_IN_LIMITS(2, 0xac, 0xd4),		/* 3.3V:  3.3V +/- 10% */
+	LM87_IN_LIMITS(4, 0xac, 0xe0),		/* 12V:   10.8-14V */
+	LM87_IN_LIMITS(5, 0x3f, 0x4f),		/* Vccp2: 1.0V +/- 10% */
+	LM87_AIN_LIMITS(1, 0x8a, 0xa9),		/* AIN2:  1.5V +/- 10% */
+	LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS),
+	LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
+	0
+};
+
+static struct i2c_board_info sfn4112f_hwmon_info = {
+	I2C_BOARD_INFO("lm87", 0x2e),
+	.platform_data	= &sfn4112f_lm87_channel,
+};
+
+#define SFN4112F_ACT_LED	0
+#define SFN4112F_LINK_LED	1
+
+static void sfn4112f_init_phy(struct efx_nic *efx)
+{
+	falcon_qt202x_set_led(efx, SFN4112F_ACT_LED,
+			      QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
+	falcon_qt202x_set_led(efx, SFN4112F_LINK_LED,
+			      QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
+}
+
+static void sfn4112f_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+	int reg;
+
+	switch (mode) {
+	case EFX_LED_OFF:
+		reg = QUAKE_LED_OFF;
+		break;
+	case EFX_LED_ON:
+		reg = QUAKE_LED_ON;
+		break;
+	default:
+		reg = QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT;
+		break;
+	}
+
+	falcon_qt202x_set_led(efx, SFN4112F_LINK_LED, reg);
+}
+
+static int sfn4112f_check_hw(struct efx_nic *efx)
+{
+	/* Mask out unused sensors */
+	return efx_check_lm87(efx, ~0x48);
+}
+
+static int sfn4112f_init(struct efx_nic *efx)
+{
+	return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
+}
+
+static const struct falcon_board_type board_types[] = {
+	{
+		.id		= FALCON_BOARD_SFE4001,
+		.ref_model	= "SFE4001",
+		.gen_type	= "10GBASE-T adapter",
+		.init		= sfe4001_init,
+		.init_phy	= efx_port_dummy_op_void,
+		.fini		= sfe4001_fini,
+		.set_id_led	= tenxpress_set_id_led,
+		.monitor	= sfe4001_check_hw,
+	},
+	{
+		.id		= FALCON_BOARD_SFE4002,
+		.ref_model	= "SFE4002",
+		.gen_type	= "XFP adapter",
+		.init		= sfe4002_init,
+		.init_phy	= sfe4002_init_phy,
+		.fini		= efx_fini_lm87,
+		.set_id_led	= sfe4002_set_id_led,
+		.monitor	= sfe4002_check_hw,
+	},
+	{
+		.id		= FALCON_BOARD_SFN4111T,
+		.ref_model	= "SFN4111T",
+		.gen_type	= "100/1000/10GBASE-T adapter",
+		.init		= sfn4111t_init,
+		.init_phy	= sfn4111t_init_phy,
+		.fini		= sfn4111t_fini,
+		.set_id_led	= tenxpress_set_id_led,
+		.monitor	= sfn4111t_check_hw,
+	},
+	{
+		.id		= FALCON_BOARD_SFN4112F,
+		.ref_model	= "SFN4112F",
+		.gen_type	= "SFP+ adapter",
+		.init		= sfn4112f_init,
+		.init_phy	= sfn4112f_init_phy,
+		.fini		= efx_fini_lm87,
+		.set_id_led	= sfn4112f_set_id_led,
+		.monitor	= sfn4112f_check_hw,
+	},
+};
+
+static const struct falcon_board_type falcon_dummy_board = {
+	.init		= efx_port_dummy_op_int,
+	.init_phy	= efx_port_dummy_op_void,
+	.fini		= efx_port_dummy_op_void,
+	.set_id_led	= efx_port_dummy_op_set_id_led,
+	.monitor	= efx_port_dummy_op_int,
+};
+
+void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
+{
+	struct falcon_board *board = falcon_board(efx);
+	u8 type_id = FALCON_BOARD_TYPE(revision_info);
+	int i;
+
+	board->major = FALCON_BOARD_MAJOR(revision_info);
+	board->minor = FALCON_BOARD_MINOR(revision_info);
+
+	for (i = 0; i < ARRAY_SIZE(board_types); i++)
+		if (board_types[i].id == type_id)
+			board->type = &board_types[i];
+
+	if (board->type) {
+		EFX_INFO(efx, "board is %s rev %c%d\n",
+			 (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
+			 ? board->type->ref_model : board->type->gen_type,
+			 'A' + board->major, board->minor);
+	} else {
+		EFX_ERR(efx, "unknown board type %d\n", type_id);
+		board->type = &falcon_dummy_board;
+	}
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon.c linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -14,66 +14,20 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
 #include <linux/mii.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
 #include "mac.h"
 #include "spi.h"
-#include "falcon.h"
-#include "falcon_hwdefs.h"
-#include "falcon_io.h"
+#include "nic.h"
+#include "regs.h"
+#include "io.h"
 #include "mdio_10g.h"
 #include "phy.h"
-#include "boards.h"
 #include "workarounds.h"
 
-/* Falcon hardware control.
- * Falcon is the internal codename for the SFC4000 controller that is
- * present in SFE400X evaluation boards
- */
-
-/**
- * struct falcon_nic_data - Falcon NIC state
- * @next_buffer_table: First available buffer table id
- * @pci_dev2: The secondary PCI device if present
- * @i2c_data: Operations and state for I2C bit-bashing algorithm
- * @int_error_count: Number of internal errors seen recently
- * @int_error_expire: Time at which error count will be expired
- */
-struct falcon_nic_data {
-	unsigned next_buffer_table;
-	struct pci_dev *pci_dev2;
-	struct i2c_algo_bit_data i2c_data;
-
-	unsigned int_error_count;
-	unsigned long int_error_expire;
-};
-
-/**************************************************************************
- *
- * Configurable values
- *
- **************************************************************************
- */
-
-static int disable_dma_stats;
-
-/* This is set to 16 for a good reason.  In summary, if larger than
- * 16, the descriptor cache holds more than a default socket
- * buffer's worth of packets (for UDP we can only have at most one
- * socket buffer's worth outstanding).  This combined with the fact
- * that we only get 1 TX event per descriptor cache means the NIC
- * goes idle.
- */
-#define TX_DC_ENTRIES 16
-#define TX_DC_ENTRIES_ORDER 0
-#define TX_DC_BASE 0x130000
-
-#define RX_DC_ENTRIES 64
-#define RX_DC_ENTRIES_ORDER 2
-#define RX_DC_BASE 0x100000
+/* Hardware control for SFC4000 (aka Falcon). */
 
 static const unsigned int
 /* "Large" EEPROM device: Atmel AT25640 or similar
@@ -89,104 +43,6 @@ default_flash_type = ((17 << SPI_DEV_TYP
 		      | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN)
 		      | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN));
 
-/* RX FIFO XOFF watermark
- *
- * When the amount of the RX FIFO increases used increases past this
- * watermark send XOFF. Only used if RX flow control is enabled (ethtool -A)
- * This also has an effect on RX/TX arbitration
- */
-static int rx_xoff_thresh_bytes = -1;
-module_param(rx_xoff_thresh_bytes, int, 0644);
-MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold");
-
-/* RX FIFO XON watermark
- *
- * When the amount of the RX FIFO used decreases below this
- * watermark send XON. Only used if TX flow control is enabled (ethtool -A)
- * This also has an effect on RX/TX arbitration
- */
-static int rx_xon_thresh_bytes = -1;
-module_param(rx_xon_thresh_bytes, int, 0644);
-MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
-
-/* TX descriptor ring size - min 512 max 4k */
-#define FALCON_TXD_RING_ORDER TX_DESCQ_SIZE_1K
-#define FALCON_TXD_RING_SIZE 1024
-#define FALCON_TXD_RING_MASK (FALCON_TXD_RING_SIZE - 1)
-
-/* RX descriptor ring size - min 512 max 4k */
-#define FALCON_RXD_RING_ORDER RX_DESCQ_SIZE_1K
-#define FALCON_RXD_RING_SIZE 1024
-#define FALCON_RXD_RING_MASK (FALCON_RXD_RING_SIZE - 1)
-
-/* Event queue size - max 32k */
-#define FALCON_EVQ_ORDER EVQ_SIZE_4K
-#define FALCON_EVQ_SIZE 4096
-#define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1)
-
-/* If FALCON_MAX_INT_ERRORS internal errors occur within
- * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and
- * disable it.
- */
-#define FALCON_INT_ERROR_EXPIRE 3600
-#define FALCON_MAX_INT_ERRORS 5
-
-/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
- */
-#define FALCON_FLUSH_INTERVAL 10
-#define FALCON_FLUSH_POLL_COUNT 100
-
-/**************************************************************************
- *
- * Falcon constants
- *
- **************************************************************************
- */
-
-/* DMA address mask */
-#define FALCON_DMA_MASK DMA_BIT_MASK(46)
-
-/* TX DMA length mask (13-bit) */
-#define FALCON_TX_DMA_MASK (4096 - 1)
-
-/* Size and alignment of special buffers (4KB) */
-#define FALCON_BUF_SIZE 4096
-
-/* Dummy SRAM size code */
-#define SRM_NB_BSZ_ONCHIP_ONLY (-1)
-
-#define FALCON_IS_DUAL_FUNC(efx)		\
-	(falcon_rev(efx) < FALCON_REV_B0)
-
-/**************************************************************************
- *
- * Falcon hardware access
- *
- **************************************************************************/
-
-/* Read the current event from the event queue */
-static inline efx_qword_t *falcon_event(struct efx_channel *channel,
-					unsigned int index)
-{
-	return (((efx_qword_t *) (channel->eventq.addr)) + index);
-}
-
-/* See if an event is present
- *
- * We check both the high and low dword of the event for all ones.  We
- * wrote all ones when we cleared the event, and no valid event can
- * have all ones in either its high or low dwords.  This approach is
- * robust against reordering.
- *
- * Note that using a single 64-bit comparison is incorrect; even
- * though the CPU read will be atomic, the DMA write may not be.
- */
-static inline int falcon_event_present(efx_qword_t *event)
-{
-	return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
-		  EFX_DWORD_IS_ALL_ONES(event->dword[1])));
-}
-
 /**************************************************************************
  *
  * I2C bus - this is a bit-bashing interface using GPIO pins
@@ -200,9 +56,9 @@ static void falcon_setsda(void *data, in
 	struct efx_nic *efx = (struct efx_nic *)data;
 	efx_oword_t reg;
 
-	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, !state);
-	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, !state);
+	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
 }
 
 static void falcon_setscl(void *data, int state)
@@ -210,9 +66,9 @@ static void falcon_setscl(void *data, in
 	struct efx_nic *efx = (struct efx_nic *)data;
 	efx_oword_t reg;
 
-	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, !state);
-	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO0_OEN, !state);
+	efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
 }
 
 static int falcon_getsda(void *data)
@@ -220,8 +76,8 @@ static int falcon_getsda(void *data)
 	struct efx_nic *efx = (struct efx_nic *)data;
 	efx_oword_t reg;
 
-	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
-	return EFX_OWORD_FIELD(reg, GPIO3_IN);
+	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
+	return EFX_OWORD_FIELD(reg, FRF_AB_GPIO3_IN);
 }
 
 static int falcon_getscl(void *data)
@@ -229,8 +85,8 @@ static int falcon_getscl(void *data)
 	struct efx_nic *efx = (struct efx_nic *)data;
 	efx_oword_t reg;
 
-	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
-	return EFX_OWORD_FIELD(reg, GPIO0_IN);
+	efx_reado(efx, &reg, FR_AB_GPIO_CTL);
+	return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN);
 }
 
 static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
@@ -243,1115 +99,39 @@ static struct i2c_algo_bit_data falcon_i
 	.timeout	= DIV_ROUND_UP(HZ, 20),
 };
 
-/**************************************************************************
- *
- * Falcon special buffer handling
- * Special buffers are used for event queues and the TX and RX
- * descriptor rings.
- *
- *************************************************************************/
-
-/*
- * Initialise a Falcon special buffer
- *
- * This will define a buffer (previously allocated via
- * falcon_alloc_special_buffer()) in Falcon's buffer table, allowing
- * it to be used for event queues, descriptor rings etc.
- */
-static void
-falcon_init_special_buffer(struct efx_nic *efx,
-			   struct efx_special_buffer *buffer)
-{
-	efx_qword_t buf_desc;
-	int index;
-	dma_addr_t dma_addr;
-	int i;
-
-	EFX_BUG_ON_PARANOID(!buffer->addr);
-
-	/* Write buffer descriptors to NIC */
-	for (i = 0; i < buffer->entries; i++) {
-		index = buffer->index + i;
-		dma_addr = buffer->dma_addr + (i * 4096);
-		EFX_LOG(efx, "mapping special buffer %d at %llx\n",
-			index, (unsigned long long)dma_addr);
-		EFX_POPULATE_QWORD_4(buf_desc,
-				     IP_DAT_BUF_SIZE, IP_DAT_BUF_SIZE_4K,
-				     BUF_ADR_REGION, 0,
-				     BUF_ADR_FBUF, (dma_addr >> 12),
-				     BUF_OWNER_ID_FBUF, 0);
-		falcon_write_sram(efx, &buf_desc, index);
-	}
-}
-
-/* Unmaps a buffer from Falcon and clears the buffer table entries */
-static void
-falcon_fini_special_buffer(struct efx_nic *efx,
-			   struct efx_special_buffer *buffer)
-{
-	efx_oword_t buf_tbl_upd;
-	unsigned int start = buffer->index;
-	unsigned int end = (buffer->index + buffer->entries - 1);
-
-	if (!buffer->entries)
-		return;
-
-	EFX_LOG(efx, "unmapping special buffers %d-%d\n",
-		buffer->index, buffer->index + buffer->entries - 1);
-
-	EFX_POPULATE_OWORD_4(buf_tbl_upd,
-			     BUF_UPD_CMD, 0,
-			     BUF_CLR_CMD, 1,
-			     BUF_CLR_END_ID, end,
-			     BUF_CLR_START_ID, start);
-	falcon_write(efx, &buf_tbl_upd, BUF_TBL_UPD_REG_KER);
-}
-
-/*
- * Allocate a new Falcon special buffer
- *
- * This allocates memory for a new buffer, clears it and allocates a
- * new buffer ID range.  It does not write into Falcon's buffer table.
- *
- * This call will allocate 4KB buffers, since Falcon can't use 8KB
- * buffers for event queues and descriptor rings.
- */
-static int falcon_alloc_special_buffer(struct efx_nic *efx,
-				       struct efx_special_buffer *buffer,
-				       unsigned int len)
-{
-	struct falcon_nic_data *nic_data = efx->nic_data;
-
-	len = ALIGN(len, FALCON_BUF_SIZE);
-
-	buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
-					    &buffer->dma_addr);
-	if (!buffer->addr)
-		return -ENOMEM;
-	buffer->len = len;
-	buffer->entries = len / FALCON_BUF_SIZE;
-	BUG_ON(buffer->dma_addr & (FALCON_BUF_SIZE - 1));
-
-	/* All zeros is a potentially valid event so memset to 0xff */
-	memset(buffer->addr, 0xff, len);
-
-	/* Select new buffer ID */
-	buffer->index = nic_data->next_buffer_table;
-	nic_data->next_buffer_table += buffer->entries;
-
-	EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x "
-		"(virt %p phys %llx)\n", buffer->index,
-		buffer->index + buffer->entries - 1,
-		(u64)buffer->dma_addr, len,
-		buffer->addr, (u64)virt_to_phys(buffer->addr));
-
-	return 0;
-}
-
-static void falcon_free_special_buffer(struct efx_nic *efx,
-				       struct efx_special_buffer *buffer)
-{
-	if (!buffer->addr)
-		return;
-
-	EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x "
-		"(virt %p phys %llx)\n", buffer->index,
-		buffer->index + buffer->entries - 1,
-		(u64)buffer->dma_addr, buffer->len,
-		buffer->addr, (u64)virt_to_phys(buffer->addr));
-
-	pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr,
-			    buffer->dma_addr);
-	buffer->addr = NULL;
-	buffer->entries = 0;
-}
-
-/**************************************************************************
- *
- * Falcon generic buffer handling
- * These buffers are used for interrupt status and MAC stats
- *
- **************************************************************************/
-
-static int falcon_alloc_buffer(struct efx_nic *efx,
-			       struct efx_buffer *buffer, unsigned int len)
-{
-	buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
-					    &buffer->dma_addr);
-	if (!buffer->addr)
-		return -ENOMEM;
-	buffer->len = len;
-	memset(buffer->addr, 0, len);
-	return 0;
-}
-
-static void falcon_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer)
-{
-	if (buffer->addr) {
-		pci_free_consistent(efx->pci_dev, buffer->len,
-				    buffer->addr, buffer->dma_addr);
-		buffer->addr = NULL;
-	}
-}
-
-/**************************************************************************
- *
- * Falcon TX path
- *
- **************************************************************************/
-
-/* Returns a pointer to the specified transmit descriptor in the TX
- * descriptor queue belonging to the specified channel.
- */
-static inline efx_qword_t *falcon_tx_desc(struct efx_tx_queue *tx_queue,
-					       unsigned int index)
-{
-	return (((efx_qword_t *) (tx_queue->txd.addr)) + index);
-}
-
-/* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */
-static inline void falcon_notify_tx_desc(struct efx_tx_queue *tx_queue)
-{
-	unsigned write_ptr;
-	efx_dword_t reg;
-
-	write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK;
-	EFX_POPULATE_DWORD_1(reg, TX_DESC_WPTR_DWORD, write_ptr);
-	falcon_writel_page(tx_queue->efx, &reg,
-			   TX_DESC_UPD_REG_KER_DWORD, tx_queue->queue);
-}
-
-
-/* For each entry inserted into the software descriptor ring, create a
- * descriptor in the hardware TX descriptor ring (in host memory), and
- * write a doorbell.
- */
-void falcon_push_buffers(struct efx_tx_queue *tx_queue)
-{
-
-	struct efx_tx_buffer *buffer;
-	efx_qword_t *txd;
-	unsigned write_ptr;
-
-	BUG_ON(tx_queue->write_count == tx_queue->insert_count);
-
-	do {
-		write_ptr = tx_queue->write_count & FALCON_TXD_RING_MASK;
-		buffer = &tx_queue->buffer[write_ptr];
-		txd = falcon_tx_desc(tx_queue, write_ptr);
-		++tx_queue->write_count;
-
-		/* Create TX descriptor ring entry */
-		EFX_POPULATE_QWORD_5(*txd,
-				     TX_KER_PORT, 0,
-				     TX_KER_CONT, buffer->continuation,
-				     TX_KER_BYTE_CNT, buffer->len,
-				     TX_KER_BUF_REGION, 0,
-				     TX_KER_BUF_ADR, buffer->dma_addr);
-	} while (tx_queue->write_count != tx_queue->insert_count);
-
-	wmb(); /* Ensure descriptors are written before they are fetched */
-	falcon_notify_tx_desc(tx_queue);
-}
-
-/* Allocate hardware resources for a TX queue */
-int falcon_probe_tx(struct efx_tx_queue *tx_queue)
-{
-	struct efx_nic *efx = tx_queue->efx;
-	return falcon_alloc_special_buffer(efx, &tx_queue->txd,
-					   FALCON_TXD_RING_SIZE *
-					   sizeof(efx_qword_t));
-}
-
-void falcon_init_tx(struct efx_tx_queue *tx_queue)
-{
-	efx_oword_t tx_desc_ptr;
-	struct efx_nic *efx = tx_queue->efx;
-
-	tx_queue->flushed = false;
-
-	/* Pin TX descriptor ring */
-	falcon_init_special_buffer(efx, &tx_queue->txd);
-
-	/* Push TX descriptor ring to card */
-	EFX_POPULATE_OWORD_10(tx_desc_ptr,
-			      TX_DESCQ_EN, 1,
-			      TX_ISCSI_DDIG_EN, 0,
-			      TX_ISCSI_HDIG_EN, 0,
-			      TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index,
-			      TX_DESCQ_EVQ_ID, tx_queue->channel->channel,
-			      TX_DESCQ_OWNER_ID, 0,
-			      TX_DESCQ_LABEL, tx_queue->queue,
-			      TX_DESCQ_SIZE, FALCON_TXD_RING_ORDER,
-			      TX_DESCQ_TYPE, 0,
-			      TX_NON_IP_DROP_DIS_B0, 1);
-
-	if (falcon_rev(efx) >= FALCON_REV_B0) {
-		int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
-		EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
-		EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
-	}
-
-	falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
-			   tx_queue->queue);
-
-	if (falcon_rev(efx) < FALCON_REV_B0) {
-		efx_oword_t reg;
-
-		/* Only 128 bits in this register */
-		BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
-
-		falcon_read(efx, &reg, TX_CHKSM_CFG_REG_KER_A1);
-		if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
-			clear_bit_le(tx_queue->queue, (void *)&reg);
-		else
-			set_bit_le(tx_queue->queue, (void *)&reg);
-		falcon_write(efx, &reg, TX_CHKSM_CFG_REG_KER_A1);
-	}
-}
-
-static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
-{
-	struct efx_nic *efx = tx_queue->efx;
-	efx_oword_t tx_flush_descq;
-
-	/* Post a flush command */
-	EFX_POPULATE_OWORD_2(tx_flush_descq,
-			     TX_FLUSH_DESCQ_CMD, 1,
-			     TX_FLUSH_DESCQ, tx_queue->queue);
-	falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER);
-}
-
-void falcon_fini_tx(struct efx_tx_queue *tx_queue)
-{
-	struct efx_nic *efx = tx_queue->efx;
-	efx_oword_t tx_desc_ptr;
-
-	/* The queue should have been flushed */
-	WARN_ON(!tx_queue->flushed);
-
-	/* Remove TX descriptor ring from card */
-	EFX_ZERO_OWORD(tx_desc_ptr);
-	falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
-			   tx_queue->queue);
-
-	/* Unpin TX descriptor ring */
-	falcon_fini_special_buffer(efx, &tx_queue->txd);
-}
-
-/* Free buffers backing TX queue */
-void falcon_remove_tx(struct efx_tx_queue *tx_queue)
-{
-	falcon_free_special_buffer(tx_queue->efx, &tx_queue->txd);
-}
-
-/**************************************************************************
- *
- * Falcon RX path
- *
- **************************************************************************/
-
-/* Returns a pointer to the specified descriptor in the RX descriptor queue */
-static inline efx_qword_t *falcon_rx_desc(struct efx_rx_queue *rx_queue,
-					       unsigned int index)
-{
-	return (((efx_qword_t *) (rx_queue->rxd.addr)) + index);
-}
-
-/* This creates an entry in the RX descriptor queue */
-static inline void falcon_build_rx_desc(struct efx_rx_queue *rx_queue,
-					unsigned index)
-{
-	struct efx_rx_buffer *rx_buf;
-	efx_qword_t *rxd;
-
-	rxd = falcon_rx_desc(rx_queue, index);
-	rx_buf = efx_rx_buffer(rx_queue, index);
-	EFX_POPULATE_QWORD_3(*rxd,
-			     RX_KER_BUF_SIZE,
-			     rx_buf->len -
-			     rx_queue->efx->type->rx_buffer_padding,
-			     RX_KER_BUF_REGION, 0,
-			     RX_KER_BUF_ADR, rx_buf->dma_addr);
-}
-
-/* This writes to the RX_DESC_WPTR register for the specified receive
- * descriptor ring.
- */
-void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue)
-{
-	efx_dword_t reg;
-	unsigned write_ptr;
-
-	while (rx_queue->notified_count != rx_queue->added_count) {
-		falcon_build_rx_desc(rx_queue,
-				     rx_queue->notified_count &
-				     FALCON_RXD_RING_MASK);
-		++rx_queue->notified_count;
-	}
-
-	wmb();
-	write_ptr = rx_queue->added_count & FALCON_RXD_RING_MASK;
-	EFX_POPULATE_DWORD_1(reg, RX_DESC_WPTR_DWORD, write_ptr);
-	falcon_writel_page(rx_queue->efx, &reg,
-			   RX_DESC_UPD_REG_KER_DWORD, rx_queue->queue);
-}
-
-int falcon_probe_rx(struct efx_rx_queue *rx_queue)
-{
-	struct efx_nic *efx = rx_queue->efx;
-	return falcon_alloc_special_buffer(efx, &rx_queue->rxd,
-					   FALCON_RXD_RING_SIZE *
-					   sizeof(efx_qword_t));
-}
-
-void falcon_init_rx(struct efx_rx_queue *rx_queue)
-{
-	efx_oword_t rx_desc_ptr;
-	struct efx_nic *efx = rx_queue->efx;
-	bool is_b0 = falcon_rev(efx) >= FALCON_REV_B0;
-	bool iscsi_digest_en = is_b0;
-
-	EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n",
-		rx_queue->queue, rx_queue->rxd.index,
-		rx_queue->rxd.index + rx_queue->rxd.entries - 1);
-
-	rx_queue->flushed = false;
-
-	/* Pin RX descriptor ring */
-	falcon_init_special_buffer(efx, &rx_queue->rxd);
-
-	/* Push RX descriptor ring to card */
-	EFX_POPULATE_OWORD_10(rx_desc_ptr,
-			      RX_ISCSI_DDIG_EN, iscsi_digest_en,
-			      RX_ISCSI_HDIG_EN, iscsi_digest_en,
-			      RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index,
-			      RX_DESCQ_EVQ_ID, rx_queue->channel->channel,
-			      RX_DESCQ_OWNER_ID, 0,
-			      RX_DESCQ_LABEL, rx_queue->queue,
-			      RX_DESCQ_SIZE, FALCON_RXD_RING_ORDER,
-			      RX_DESCQ_TYPE, 0 /* kernel queue */ ,
-			      /* For >=B0 this is scatter so disable */
-			      RX_DESCQ_JUMBO, !is_b0,
-			      RX_DESCQ_EN, 1);
-	falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
-			   rx_queue->queue);
-}
-
-static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
-{
-	struct efx_nic *efx = rx_queue->efx;
-	efx_oword_t rx_flush_descq;
-
-	/* Post a flush command */
-	EFX_POPULATE_OWORD_2(rx_flush_descq,
-			     RX_FLUSH_DESCQ_CMD, 1,
-			     RX_FLUSH_DESCQ, rx_queue->queue);
-	falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER);
-}
-
-void falcon_fini_rx(struct efx_rx_queue *rx_queue)
-{
-	efx_oword_t rx_desc_ptr;
-	struct efx_nic *efx = rx_queue->efx;
-
-	/* The queue should already have been flushed */
-	WARN_ON(!rx_queue->flushed);
-
-	/* Remove RX descriptor ring from card */
-	EFX_ZERO_OWORD(rx_desc_ptr);
-	falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
-			   rx_queue->queue);
-
-	/* Unpin RX descriptor ring */
-	falcon_fini_special_buffer(efx, &rx_queue->rxd);
-}
-
-/* Free buffers backing RX queue */
-void falcon_remove_rx(struct efx_rx_queue *rx_queue)
-{
-	falcon_free_special_buffer(rx_queue->efx, &rx_queue->rxd);
-}
-
-/**************************************************************************
- *
- * Falcon event queue processing
- * Event queues are processed by per-channel tasklets.
- *
- **************************************************************************/
-
-/* Update a channel's event queue's read pointer (RPTR) register
- *
- * This writes the EVQ_RPTR_REG register for the specified channel's
- * event queue.
- *
- * Note that EVQ_RPTR_REG contains the index of the "last read" event,
- * whereas channel->eventq_read_ptr contains the index of the "next to
- * read" event.
- */
-void falcon_eventq_read_ack(struct efx_channel *channel)
-{
-	efx_dword_t reg;
-	struct efx_nic *efx = channel->efx;
-
-	EFX_POPULATE_DWORD_1(reg, EVQ_RPTR_DWORD, channel->eventq_read_ptr);
-	falcon_writel_table(efx, &reg, efx->type->evq_rptr_tbl_base,
-			    channel->channel);
-}
-
-/* Use HW to insert a SW defined event */
-void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event)
-{
-	efx_oword_t drv_ev_reg;
-
-	EFX_POPULATE_OWORD_2(drv_ev_reg,
-			     DRV_EV_QID, channel->channel,
-			     DRV_EV_DATA,
-			     EFX_QWORD_FIELD64(*event, WHOLE_EVENT));
-	falcon_write(channel->efx, &drv_ev_reg, DRV_EV_REG_KER);
-}
-
-/* Handle a transmit completion event
- *
- * Falcon batches TX completion events; the message we receive is of
- * the form "complete all TX events up to this index".
- */
-static void falcon_handle_tx_event(struct efx_channel *channel,
-				   efx_qword_t *event)
-{
-	unsigned int tx_ev_desc_ptr;
-	unsigned int tx_ev_q_label;
-	struct efx_tx_queue *tx_queue;
-	struct efx_nic *efx = channel->efx;
-
-	if (likely(EFX_QWORD_FIELD(*event, TX_EV_COMP))) {
-		/* Transmit completion */
-		tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR);
-		tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL);
-		tx_queue = &efx->tx_queue[tx_ev_q_label];
-		channel->irq_mod_score +=
-			(tx_ev_desc_ptr - tx_queue->read_count) &
-			efx->type->txd_ring_mask;
-		efx_xmit_done(tx_queue, tx_ev_desc_ptr);
-	} else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) {
-		/* Rewrite the FIFO write pointer */
-		tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL);
-		tx_queue = &efx->tx_queue[tx_ev_q_label];
-
-		if (efx_dev_registered(efx))
-			netif_tx_lock(efx->net_dev);
-		falcon_notify_tx_desc(tx_queue);
-		if (efx_dev_registered(efx))
-			netif_tx_unlock(efx->net_dev);
-	} else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) &&
-		   EFX_WORKAROUND_10727(efx)) {
-		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
-	} else {
-		EFX_ERR(efx, "channel %d unexpected TX event "
-			EFX_QWORD_FMT"\n", channel->channel,
-			EFX_QWORD_VAL(*event));
-	}
-}
-
-/* Detect errors included in the rx_evt_pkt_ok bit. */
-static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
-				    const efx_qword_t *event,
-				    bool *rx_ev_pkt_ok,
-				    bool *discard)
-{
-	struct efx_nic *efx = rx_queue->efx;
-	bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
-	bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
-	bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
-	bool rx_ev_other_err, rx_ev_pause_frm;
-	bool rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
-	unsigned rx_ev_pkt_type;
-
-	rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
-	rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT);
-	rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, RX_EV_TOBE_DISC);
-	rx_ev_pkt_type = EFX_QWORD_FIELD(*event, RX_EV_PKT_TYPE);
-	rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event,
-						 RX_EV_BUF_OWNER_ID_ERR);
-	rx_ev_ip_frag_err = EFX_QWORD_FIELD(*event, RX_EV_IF_FRAG_ERR);
-	rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event,
-						  RX_EV_IP_HDR_CHKSUM_ERR);
-	rx_ev_tcp_udp_chksum_err = EFX_QWORD_FIELD(*event,
-						   RX_EV_TCP_UDP_CHKSUM_ERR);
-	rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR);
-	rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC);
-	rx_ev_drib_nib = ((falcon_rev(efx) >= FALCON_REV_B0) ?
-			  0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB));
-	rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR);
-
-	/* Every error apart from tobe_disc and pause_frm */
-	rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err |
-			   rx_ev_buf_owner_id_err | rx_ev_eth_crc_err |
-			   rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err);
-
-	/* Count errors that are not in MAC stats.  Ignore expected
-	 * checksum errors during self-test. */
-	if (rx_ev_frm_trunc)
-		++rx_queue->channel->n_rx_frm_trunc;
-	else if (rx_ev_tobe_disc)
-		++rx_queue->channel->n_rx_tobe_disc;
-	else if (!efx->loopback_selftest) {
-		if (rx_ev_ip_hdr_chksum_err)
-			++rx_queue->channel->n_rx_ip_hdr_chksum_err;
-		else if (rx_ev_tcp_udp_chksum_err)
-			++rx_queue->channel->n_rx_tcp_udp_chksum_err;
-	}
-	if (rx_ev_ip_frag_err)
-		++rx_queue->channel->n_rx_ip_frag_err;
-
-	/* The frame must be discarded if any of these are true. */
-	*discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib |
-		    rx_ev_tobe_disc | rx_ev_pause_frm);
-
-	/* TOBE_DISC is expected on unicast mismatches; don't print out an
-	 * error message.  FRM_TRUNC indicates RXDP dropped the packet due
-	 * to a FIFO overflow.
-	 */
-#ifdef EFX_ENABLE_DEBUG
-	if (rx_ev_other_err) {
-		EFX_INFO_RL(efx, " RX queue %d unexpected RX event "
-			    EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
-			    rx_queue->queue, EFX_QWORD_VAL(*event),
-			    rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
-			    rx_ev_ip_hdr_chksum_err ?
-			    " [IP_HDR_CHKSUM_ERR]" : "",
-			    rx_ev_tcp_udp_chksum_err ?
-			    " [TCP_UDP_CHKSUM_ERR]" : "",
-			    rx_ev_eth_crc_err ? " [ETH_CRC_ERR]" : "",
-			    rx_ev_frm_trunc ? " [FRM_TRUNC]" : "",
-			    rx_ev_drib_nib ? " [DRIB_NIB]" : "",
-			    rx_ev_tobe_disc ? " [TOBE_DISC]" : "",
-			    rx_ev_pause_frm ? " [PAUSE]" : "");
-	}
-#endif
-}
-
-/* Handle receive events that are not in-order. */
-static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue,
-				       unsigned index)
-{
-	struct efx_nic *efx = rx_queue->efx;
-	unsigned expected, dropped;
-
-	expected = rx_queue->removed_count & FALCON_RXD_RING_MASK;
-	dropped = ((index + FALCON_RXD_RING_SIZE - expected) &
-		   FALCON_RXD_RING_MASK);
-	EFX_INFO(efx, "dropped %d events (index=%d expected=%d)\n",
-		dropped, index, expected);
-
-	efx_schedule_reset(efx, EFX_WORKAROUND_5676(efx) ?
-			   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
-}
-
-/* Handle a packet received event
- *
- * Falcon silicon gives a "discard" flag if it's a unicast packet with the
- * wrong destination address
- * Also "is multicast" and "matches multicast filter" flags can be used to
- * discard non-matching multicast packets.
- */
-static void falcon_handle_rx_event(struct efx_channel *channel,
-				   const efx_qword_t *event)
-{
-	unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt;
-	unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
-	unsigned expected_ptr;
-	bool rx_ev_pkt_ok, discard = false, checksummed;
-	struct efx_rx_queue *rx_queue;
-	struct efx_nic *efx = channel->efx;
-
-	/* Basic packet information */
-	rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, RX_EV_BYTE_CNT);
-	rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, RX_EV_PKT_OK);
-	rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
-	WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_JUMBO_CONT));
-	WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_SOP) != 1);
-	WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL) != channel->channel);
-
-	rx_queue = &efx->rx_queue[channel->channel];
-
-	rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
-	expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK;
-	if (unlikely(rx_ev_desc_ptr != expected_ptr))
-		falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
-
-	if (likely(rx_ev_pkt_ok)) {
-		/* If packet is marked as OK and packet type is TCP/IPv4 or
-		 * UDP/IPv4, then we can rely on the hardware checksum.
-		 */
-		checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type);
-	} else {
-		falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok,
-					&discard);
-		checksummed = false;
-	}
-
-	/* Detect multicast packets that didn't match the filter */
-	rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT);
-	if (rx_ev_mcast_pkt) {
-		unsigned int rx_ev_mcast_hash_match =
-			EFX_QWORD_FIELD(*event, RX_EV_MCAST_HASH_MATCH);
-
-		if (unlikely(!rx_ev_mcast_hash_match))
-			discard = true;
-	}
-
-	channel->irq_mod_score += 2;
-
-	/* Handle received packet */
-	efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
-		      checksummed, discard);
-}
-
-/* Global events are basically PHY events */
-static void falcon_handle_global_event(struct efx_channel *channel,
-				       efx_qword_t *event)
-{
-	struct efx_nic *efx = channel->efx;
-	bool handled = false;
-
-	if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) ||
-	    EFX_QWORD_FIELD(*event, G_PHY1_INTR) ||
-	    EFX_QWORD_FIELD(*event, XG_PHY_INTR) ||
-	    EFX_QWORD_FIELD(*event, XFP_PHY_INTR)) {
-		efx->phy_op->clear_interrupt(efx);
-		queue_work(efx->workqueue, &efx->phy_work);
-		handled = true;
-	}
-
-	if ((falcon_rev(efx) >= FALCON_REV_B0) &&
-	    EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) {
-		queue_work(efx->workqueue, &efx->mac_work);
-		handled = true;
-	}
-
-	if (EFX_QWORD_FIELD_VER(efx, *event, RX_RECOVERY)) {
-		EFX_ERR(efx, "channel %d seen global RX_RESET "
-			"event. Resetting.\n", channel->channel);
-
-		atomic_inc(&efx->rx_reset);
-		efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
-				   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
-		handled = true;
-	}
-
-	if (!handled)
-		EFX_ERR(efx, "channel %d unknown global event "
-			EFX_QWORD_FMT "\n", channel->channel,
-			EFX_QWORD_VAL(*event));
-}
-
-static void falcon_handle_driver_event(struct efx_channel *channel,
-				       efx_qword_t *event)
-{
-	struct efx_nic *efx = channel->efx;
-	unsigned int ev_sub_code;
-	unsigned int ev_sub_data;
-
-	ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-	ev_sub_data = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_DATA);
-
-	switch (ev_sub_code) {
-	case TX_DESCQ_FLS_DONE_EV_DECODE:
-		EFX_TRACE(efx, "channel %d TXQ %d flushed\n",
-			  channel->channel, ev_sub_data);
-		break;
-	case RX_DESCQ_FLS_DONE_EV_DECODE:
-		EFX_TRACE(efx, "channel %d RXQ %d flushed\n",
-			  channel->channel, ev_sub_data);
-		break;
-	case EVQ_INIT_DONE_EV_DECODE:
-		EFX_LOG(efx, "channel %d EVQ %d initialised\n",
-			channel->channel, ev_sub_data);
-		break;
-	case SRM_UPD_DONE_EV_DECODE:
-		EFX_TRACE(efx, "channel %d SRAM update done\n",
-			  channel->channel);
-		break;
-	case WAKE_UP_EV_DECODE:
-		EFX_TRACE(efx, "channel %d RXQ %d wakeup event\n",
-			  channel->channel, ev_sub_data);
-		break;
-	case TIMER_EV_DECODE:
-		EFX_TRACE(efx, "channel %d RX queue %d timer expired\n",
-			  channel->channel, ev_sub_data);
-		break;
-	case RX_RECOVERY_EV_DECODE:
-		EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. "
-			"Resetting.\n", channel->channel);
-		atomic_inc(&efx->rx_reset);
-		efx_schedule_reset(efx,
-				   EFX_WORKAROUND_6555(efx) ?
-				   RESET_TYPE_RX_RECOVERY :
-				   RESET_TYPE_DISABLE);
-		break;
-	case RX_DSC_ERROR_EV_DECODE:
-		EFX_ERR(efx, "RX DMA Q %d reports descriptor fetch error."
-			" RX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
-		efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH);
-		break;
-	case TX_DSC_ERROR_EV_DECODE:
-		EFX_ERR(efx, "TX DMA Q %d reports descriptor fetch error."
-			" TX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
-		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
-		break;
-	default:
-		EFX_TRACE(efx, "channel %d unknown driver event code %d "
-			  "data %04x\n", channel->channel, ev_sub_code,
-			  ev_sub_data);
-		break;
-	}
-}
-
-int falcon_process_eventq(struct efx_channel *channel, int rx_quota)
-{
-	unsigned int read_ptr;
-	efx_qword_t event, *p_event;
-	int ev_code;
-	int rx_packets = 0;
-
-	read_ptr = channel->eventq_read_ptr;
-
-	do {
-		p_event = falcon_event(channel, read_ptr);
-		event = *p_event;
-
-		if (!falcon_event_present(&event))
-			/* End of events */
-			break;
-
-		EFX_TRACE(channel->efx, "channel %d event is "EFX_QWORD_FMT"\n",
-			  channel->channel, EFX_QWORD_VAL(event));
-
-		/* Clear this event by marking it all ones */
-		EFX_SET_QWORD(*p_event);
-
-		ev_code = EFX_QWORD_FIELD(event, EV_CODE);
-
-		switch (ev_code) {
-		case RX_IP_EV_DECODE:
-			falcon_handle_rx_event(channel, &event);
-			++rx_packets;
-			break;
-		case TX_IP_EV_DECODE:
-			falcon_handle_tx_event(channel, &event);
-			break;
-		case DRV_GEN_EV_DECODE:
-			channel->eventq_magic
-				= EFX_QWORD_FIELD(event, EVQ_MAGIC);
-			EFX_LOG(channel->efx, "channel %d received generated "
-				"event "EFX_QWORD_FMT"\n", channel->channel,
-				EFX_QWORD_VAL(event));
-			break;
-		case GLOBAL_EV_DECODE:
-			falcon_handle_global_event(channel, &event);
-			break;
-		case DRIVER_EV_DECODE:
-			falcon_handle_driver_event(channel, &event);
-			break;
-		default:
-			EFX_ERR(channel->efx, "channel %d unknown event type %d"
-				" (data " EFX_QWORD_FMT ")\n", channel->channel,
-				ev_code, EFX_QWORD_VAL(event));
-		}
-
-		/* Increment read pointer */
-		read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
-
-	} while (rx_packets < rx_quota);
-
-	channel->eventq_read_ptr = read_ptr;
-	return rx_packets;
-}
-
-void falcon_set_int_moderation(struct efx_channel *channel)
+static void falcon_push_irq_moderation(struct efx_channel *channel)
 {
 	efx_dword_t timer_cmd;
 	struct efx_nic *efx = channel->efx;
 
 	/* Set timer register */
 	if (channel->irq_moderation) {
-		/* Round to resolution supported by hardware.  The value we
-		 * program is based at 0.  So actual interrupt moderation
-		 * achieved is ((x + 1) * res).
-		 */
-		channel->irq_moderation -= (channel->irq_moderation %
-					    FALCON_IRQ_MOD_RESOLUTION);
-		if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION)
-			channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION;
 		EFX_POPULATE_DWORD_2(timer_cmd,
-				     TIMER_MODE, TIMER_MODE_INT_HLDOFF,
-				     TIMER_VAL,
-				     channel->irq_moderation /
-				     FALCON_IRQ_MOD_RESOLUTION - 1);
+				     FRF_AB_TC_TIMER_MODE,
+				     FFE_BB_TIMER_MODE_INT_HLDOFF,
+				     FRF_AB_TC_TIMER_VAL,
+				     channel->irq_moderation - 1);
 	} else {
 		EFX_POPULATE_DWORD_2(timer_cmd,
-				     TIMER_MODE, TIMER_MODE_DIS,
-				     TIMER_VAL, 0);
-	}
-	falcon_writel_page_locked(efx, &timer_cmd, TIMER_CMD_REG_KER,
-				  channel->channel);
-
-}
-
-/* Allocate buffer table entries for event queue */
-int falcon_probe_eventq(struct efx_channel *channel)
-{
-	struct efx_nic *efx = channel->efx;
-	unsigned int evq_size;
-
-	evq_size = FALCON_EVQ_SIZE * sizeof(efx_qword_t);
-	return falcon_alloc_special_buffer(efx, &channel->eventq, evq_size);
-}
-
-void falcon_init_eventq(struct efx_channel *channel)
-{
-	efx_oword_t evq_ptr;
-	struct efx_nic *efx = channel->efx;
-
-	EFX_LOG(efx, "channel %d event queue in special buffers %d-%d\n",
-		channel->channel, channel->eventq.index,
-		channel->eventq.index + channel->eventq.entries - 1);
-
-	/* Pin event queue buffer */
-	falcon_init_special_buffer(efx, &channel->eventq);
-
-	/* Fill event queue with all ones (i.e. empty events) */
-	memset(channel->eventq.addr, 0xff, channel->eventq.len);
-
-	/* Push event queue to card */
-	EFX_POPULATE_OWORD_3(evq_ptr,
-			     EVQ_EN, 1,
-			     EVQ_SIZE, FALCON_EVQ_ORDER,
-			     EVQ_BUF_BASE_ID, channel->eventq.index);
-	falcon_write_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base,
-			   channel->channel);
-
-	falcon_set_int_moderation(channel);
-}
-
-void falcon_fini_eventq(struct efx_channel *channel)
-{
-	efx_oword_t eventq_ptr;
-	struct efx_nic *efx = channel->efx;
-
-	/* Remove event queue from card */
-	EFX_ZERO_OWORD(eventq_ptr);
-	falcon_write_table(efx, &eventq_ptr, efx->type->evq_ptr_tbl_base,
-			   channel->channel);
-
-	/* Unpin event queue */
-	falcon_fini_special_buffer(efx, &channel->eventq);
-}
-
-/* Free buffers backing event queue */
-void falcon_remove_eventq(struct efx_channel *channel)
-{
-	falcon_free_special_buffer(channel->efx, &channel->eventq);
-}
-
-
-/* Generates a test event on the event queue.  A subsequent call to
- * process_eventq() should pick up the event and place the value of
- * "magic" into channel->eventq_magic;
- */
-void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
-{
-	efx_qword_t test_event;
-
-	EFX_POPULATE_QWORD_2(test_event,
-			     EV_CODE, DRV_GEN_EV_DECODE,
-			     EVQ_MAGIC, magic);
-	falcon_generate_event(channel, &test_event);
-}
-
-void falcon_sim_phy_event(struct efx_nic *efx)
-{
-	efx_qword_t phy_event;
-
-	EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE);
-	if (EFX_IS10G(efx))
-		EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1);
-	else
-		EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1);
-
-	falcon_generate_event(&efx->channel[0], &phy_event);
-}
-
-/**************************************************************************
- *
- * Flush handling
- *
- **************************************************************************/
-
-
-static void falcon_poll_flush_events(struct efx_nic *efx)
-{
-	struct efx_channel *channel = &efx->channel[0];
-	struct efx_tx_queue *tx_queue;
-	struct efx_rx_queue *rx_queue;
-	unsigned int read_ptr = channel->eventq_read_ptr;
-	unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK;
-
-	do {
-		efx_qword_t *event = falcon_event(channel, read_ptr);
-		int ev_code, ev_sub_code, ev_queue;
-		bool ev_failed;
-
-		if (!falcon_event_present(event))
-			break;
-
-		ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
-		ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-		if (ev_code == DRIVER_EV_DECODE &&
-		    ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) {
-			ev_queue = EFX_QWORD_FIELD(*event,
-						   DRIVER_EV_TX_DESCQ_ID);
-			if (ev_queue < EFX_TX_QUEUE_COUNT) {
-				tx_queue = efx->tx_queue + ev_queue;
-				tx_queue->flushed = true;
-			}
-		} else if (ev_code == DRIVER_EV_DECODE &&
-			   ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) {
-			ev_queue = EFX_QWORD_FIELD(*event,
-						   DRIVER_EV_RX_DESCQ_ID);
-			ev_failed = EFX_QWORD_FIELD(*event,
-						    DRIVER_EV_RX_FLUSH_FAIL);
-			if (ev_queue < efx->n_rx_queues) {
-				rx_queue = efx->rx_queue + ev_queue;
-
-				/* retry the rx flush */
-				if (ev_failed)
-					falcon_flush_rx_queue(rx_queue);
-				else
-					rx_queue->flushed = true;
-			}
-		}
-
-		read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
-	} while (read_ptr != end_ptr);
-}
-
-/* Handle tx and rx flushes at the same time, since they run in
- * parallel in the hardware and there's no reason for us to
- * serialise them */
-int falcon_flush_queues(struct efx_nic *efx)
-{
-	struct efx_rx_queue *rx_queue;
-	struct efx_tx_queue *tx_queue;
-	int i;
-	bool outstanding;
-
-	/* Issue flush requests */
-	efx_for_each_tx_queue(tx_queue, efx) {
-		tx_queue->flushed = false;
-		falcon_flush_tx_queue(tx_queue);
-	}
-	efx_for_each_rx_queue(rx_queue, efx) {
-		rx_queue->flushed = false;
-		falcon_flush_rx_queue(rx_queue);
-	}
-
-	/* Poll the evq looking for flush completions. Since we're not pushing
-	 * any more rx or tx descriptors at this point, we're in no danger of
-	 * overflowing the evq whilst we wait */
-	for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) {
-		msleep(FALCON_FLUSH_INTERVAL);
-		falcon_poll_flush_events(efx);
-
-		/* Check if every queue has been succesfully flushed */
-		outstanding = false;
-		efx_for_each_tx_queue(tx_queue, efx)
-			outstanding |= !tx_queue->flushed;
-		efx_for_each_rx_queue(rx_queue, efx)
-			outstanding |= !rx_queue->flushed;
-		if (!outstanding)
-			return 0;
-	}
-
-	/* Mark the queues as all flushed. We're going to return failure
-	 * leading to a reset, or fake up success anyway. "flushed" now
-	 * indicates that we tried to flush. */
-	efx_for_each_tx_queue(tx_queue, efx) {
-		if (!tx_queue->flushed)
-			EFX_ERR(efx, "tx queue %d flush command timed out\n",
-				tx_queue->queue);
-		tx_queue->flushed = true;
-	}
-	efx_for_each_rx_queue(rx_queue, efx) {
-		if (!rx_queue->flushed)
-			EFX_ERR(efx, "rx queue %d flush command timed out\n",
-				rx_queue->queue);
-		rx_queue->flushed = true;
+				     FRF_AB_TC_TIMER_MODE,
+				     FFE_BB_TIMER_MODE_DIS,
+				     FRF_AB_TC_TIMER_VAL, 0);
 	}
-
-	if (EFX_WORKAROUND_7803(efx))
-		return 0;
-
-	return -ETIMEDOUT;
-}
-
-/**************************************************************************
- *
- * Falcon hardware interrupts
- * The hardware interrupt handler does very little work; all the event
- * queue processing is carried out by per-channel tasklets.
- *
- **************************************************************************/
-
-/* Enable/disable/generate Falcon interrupts */
-static inline void falcon_interrupts(struct efx_nic *efx, int enabled,
-				     int force)
-{
-	efx_oword_t int_en_reg_ker;
-
-	EFX_POPULATE_OWORD_2(int_en_reg_ker,
-			     KER_INT_KER, force,
-			     DRV_INT_EN_KER, enabled);
-	falcon_write(efx, &int_en_reg_ker, INT_EN_REG_KER);
+	BUILD_BUG_ON(FR_AA_TIMER_COMMAND_KER != FR_BZ_TIMER_COMMAND_P0);
+	efx_writed_page_locked(efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0,
+			       channel->channel);
 }
 
-void falcon_enable_interrupts(struct efx_nic *efx)
-{
-	efx_oword_t int_adr_reg_ker;
-	struct efx_channel *channel;
-
-	EFX_ZERO_OWORD(*((efx_oword_t *) efx->irq_status.addr));
-	wmb(); /* Ensure interrupt vector is clear before interrupts enabled */
-
-	/* Program address */
-	EFX_POPULATE_OWORD_2(int_adr_reg_ker,
-			     NORM_INT_VEC_DIS_KER, EFX_INT_MODE_USE_MSI(efx),
-			     INT_ADR_KER, efx->irq_status.dma_addr);
-	falcon_write(efx, &int_adr_reg_ker, INT_ADR_REG_KER);
-
-	/* Enable interrupts */
-	falcon_interrupts(efx, 1, 0);
-
-	/* Force processing of all the channels to get the EVQ RPTRs up to
-	   date */
-	efx_for_each_channel(channel, efx)
-		efx_schedule_channel(channel);
-}
+static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
 
-void falcon_disable_interrupts(struct efx_nic *efx)
+static void falcon_prepare_flush(struct efx_nic *efx)
 {
-	/* Disable interrupts */
-	falcon_interrupts(efx, 0, 0);
-}
+	falcon_deconfigure_mac_wrapper(efx);
 
-/* Generate a Falcon test interrupt
- * Interrupt must already have been enabled, otherwise nasty things
- * may happen.
- */
-void falcon_generate_interrupt(struct efx_nic *efx)
-{
-	falcon_interrupts(efx, 1, 1);
+	/* Wait for the tx and rx fifo's to get to the next packet boundary
+	 * (~1ms without back-pressure), then to drain the remainder of the
+	 * fifo's at data path speeds (negligible), with a healthy margin. */
+	msleep(10);
 }
 
 /* Acknowledge a legacy interrupt from Falcon
@@ -1364,113 +144,17 @@ void falcon_generate_interrupt(struct ef
  *
  * NB most hardware supports MSI interrupts
  */
-static inline void falcon_irq_ack_a1(struct efx_nic *efx)
-{
-	efx_dword_t reg;
-
-	EFX_POPULATE_DWORD_1(reg, INT_ACK_DUMMY_DATA, 0xb7eb7e);
-	falcon_writel(efx, &reg, INT_ACK_REG_KER_A1);
-	falcon_readl(efx, &reg, WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1);
-}
-
-/* Process a fatal interrupt
- * Disable bus mastering ASAP and schedule a reset
- */
-static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
-{
-	struct falcon_nic_data *nic_data = efx->nic_data;
-	efx_oword_t *int_ker = efx->irq_status.addr;
-	efx_oword_t fatal_intr;
-	int error, mem_perr;
-
-	falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER);
-	error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR);
-
-	EFX_ERR(efx, "SYSTEM ERROR " EFX_OWORD_FMT " status "
-		EFX_OWORD_FMT ": %s\n", EFX_OWORD_VAL(*int_ker),
-		EFX_OWORD_VAL(fatal_intr),
-		error ? "disabling bus mastering" : "no recognised error");
-	if (error == 0)
-		goto out;
-
-	/* If this is a memory parity error dump which blocks are offending */
-	mem_perr = EFX_OWORD_FIELD(fatal_intr, MEM_PERR_INT_KER);
-	if (mem_perr) {
-		efx_oword_t reg;
-		falcon_read(efx, &reg, MEM_STAT_REG_KER);
-		EFX_ERR(efx, "SYSTEM ERROR: memory parity error "
-			EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg));
-	}
-
-	/* Disable both devices */
-	pci_clear_master(efx->pci_dev);
-	if (FALCON_IS_DUAL_FUNC(efx))
-		pci_clear_master(nic_data->pci_dev2);
-	falcon_disable_interrupts(efx);
-
-	/* Count errors and reset or disable the NIC accordingly */
-	if (nic_data->int_error_count == 0 ||
-	    time_after(jiffies, nic_data->int_error_expire)) {
-		nic_data->int_error_count = 0;
-		nic_data->int_error_expire =
-			jiffies + FALCON_INT_ERROR_EXPIRE * HZ;
-	}
-	if (++nic_data->int_error_count < FALCON_MAX_INT_ERRORS) {
-		EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
-		efx_schedule_reset(efx, RESET_TYPE_INT_ERROR);
-	} else {
-		EFX_ERR(efx, "SYSTEM ERROR - max number of errors seen."
-			"NIC will be disabled\n");
-		efx_schedule_reset(efx, RESET_TYPE_DISABLE);
-	}
-out:
-	return IRQ_HANDLED;
-}
-
-/* Handle a legacy interrupt from Falcon
- * Acknowledges the interrupt and schedule event queue processing.
- */
-static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id)
+inline void falcon_irq_ack_a1(struct efx_nic *efx)
 {
-	struct efx_nic *efx = dev_id;
-	efx_oword_t *int_ker = efx->irq_status.addr;
-	irqreturn_t result = IRQ_NONE;
-	struct efx_channel *channel;
 	efx_dword_t reg;
-	u32 queues;
-	int syserr;
-
-	/* Read the ISR which also ACKs the interrupts */
-	falcon_readl(efx, &reg, INT_ISR0_B0);
-	queues = EFX_EXTRACT_DWORD(reg, 0, 31);
-
-	/* Check to see if we have a serious error condition */
-	syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT);
-	if (unlikely(syserr))
-		return falcon_fatal_interrupt(efx);
 
-	/* Schedule processing of any interrupting queues */
-	efx_for_each_channel(channel, efx) {
-		if ((queues & 1) ||
-		    falcon_event_present(
-			    falcon_event(channel, channel->eventq_read_ptr))) {
-			efx_schedule_channel(channel);
-			result = IRQ_HANDLED;
-		}
-		queues >>= 1;
-	}
-
-	if (result == IRQ_HANDLED) {
-		efx->last_irq_cpu = raw_smp_processor_id();
-		EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
-			  irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
-	}
-
-	return result;
+	EFX_POPULATE_DWORD_1(reg, FRF_AA_INT_ACK_KER_FIELD, 0xb7eb7e);
+	efx_writed(efx, &reg, FR_AA_INT_ACK_KER);
+	efx_readd(efx, &reg, FR_AA_WORK_AROUND_BROKEN_PCI_READS);
 }
 
 
-static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
+irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
 {
 	struct efx_nic *efx = dev_id;
 	efx_oword_t *int_ker = efx->irq_status.addr;
@@ -1491,15 +175,15 @@ static irqreturn_t falcon_legacy_interru
 		  irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
 
 	/* Check to see if we have a serious error condition */
-	syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT);
+	syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
 	if (unlikely(syserr))
-		return falcon_fatal_interrupt(efx);
+		return efx_nic_fatal_interrupt(efx);
 
 	/* Determine interrupting queues, clear interrupt status
 	 * register and acknowledge the device interrupt.
 	 */
-	BUILD_BUG_ON(INT_EVQS_WIDTH > EFX_MAX_CHANNELS);
-	queues = EFX_OWORD_FIELD(*int_ker, INT_EVQS);
+	BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS);
+	queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q);
 	EFX_ZERO_OWORD(*int_ker);
 	wmb(); /* Ensure the vector is cleared before interrupt ack */
 	falcon_irq_ack_a1(efx);
@@ -1515,126 +199,6 @@ static irqreturn_t falcon_legacy_interru
 
 	return IRQ_HANDLED;
 }
-
-/* Handle an MSI interrupt from Falcon
- *
- * Handle an MSI hardware interrupt.  This routine schedules event
- * queue processing.  No interrupt acknowledgement cycle is necessary.
- * Also, we never need to check that the interrupt is for us, since
- * MSI interrupts cannot be shared.
- */
-static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id)
-{
-	struct efx_channel *channel = dev_id;
-	struct efx_nic *efx = channel->efx;
-	efx_oword_t *int_ker = efx->irq_status.addr;
-	int syserr;
-
-	efx->last_irq_cpu = raw_smp_processor_id();
-	EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
-		  irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
-
-	/* Check to see if we have a serious error condition */
-	syserr = EFX_OWORD_FIELD(*int_ker, FATAL_INT);
-	if (unlikely(syserr))
-		return falcon_fatal_interrupt(efx);
-
-	/* Schedule processing of the channel */
-	efx_schedule_channel(channel);
-
-	return IRQ_HANDLED;
-}
-
-
-/* Setup RSS indirection table.
- * This maps from the hash value of the packet to RXQ
- */
-static void falcon_setup_rss_indir_table(struct efx_nic *efx)
-{
-	int i = 0;
-	unsigned long offset;
-	efx_dword_t dword;
-
-	if (falcon_rev(efx) < FALCON_REV_B0)
-		return;
-
-	for (offset = RX_RSS_INDIR_TBL_B0;
-	     offset < RX_RSS_INDIR_TBL_B0 + 0x800;
-	     offset += 0x10) {
-		EFX_POPULATE_DWORD_1(dword, RX_RSS_INDIR_ENT_B0,
-				     i % efx->n_rx_queues);
-		falcon_writel(efx, &dword, offset);
-		i++;
-	}
-}
-
-/* Hook interrupt handler(s)
- * Try MSI and then legacy interrupts.
- */
-int falcon_init_interrupt(struct efx_nic *efx)
-{
-	struct efx_channel *channel;
-	int rc;
-
-	if (!EFX_INT_MODE_USE_MSI(efx)) {
-		irq_handler_t handler;
-		if (falcon_rev(efx) >= FALCON_REV_B0)
-			handler = falcon_legacy_interrupt_b0;
-		else
-			handler = falcon_legacy_interrupt_a1;
-
-		rc = request_irq(efx->legacy_irq, handler, IRQF_SHARED,
-				 efx->name, efx);
-		if (rc) {
-			EFX_ERR(efx, "failed to hook legacy IRQ %d\n",
-				efx->pci_dev->irq);
-			goto fail1;
-		}
-		return 0;
-	}
-
-	/* Hook MSI or MSI-X interrupt */
-	efx_for_each_channel(channel, efx) {
-		rc = request_irq(channel->irq, falcon_msi_interrupt,
-				 IRQF_PROBE_SHARED, /* Not shared */
-				 channel->name, channel);
-		if (rc) {
-			EFX_ERR(efx, "failed to hook IRQ %d\n", channel->irq);
-			goto fail2;
-		}
-	}
-
-	return 0;
-
- fail2:
-	efx_for_each_channel(channel, efx)
-		free_irq(channel->irq, channel);
- fail1:
-	return rc;
-}
-
-void falcon_fini_interrupt(struct efx_nic *efx)
-{
-	struct efx_channel *channel;
-	efx_oword_t reg;
-
-	/* Disable MSI/MSI-X interrupts */
-	efx_for_each_channel(channel, efx) {
-		if (channel->irq)
-			free_irq(channel->irq, channel);
-	}
-
-	/* ACK legacy interrupt */
-	if (falcon_rev(efx) >= FALCON_REV_B0)
-		falcon_read(efx, &reg, INT_ISR0_B0);
-	else
-		falcon_irq_ack_a1(efx);
-
-	/* Disable legacy interrupt */
-	if (efx->legacy_irq)
-		free_irq(efx->legacy_irq, efx);
-}
-
 /**************************************************************************
  *
  * EEPROM/flash
@@ -1647,8 +211,8 @@ void falcon_fini_interrupt(struct efx_ni
 static int falcon_spi_poll(struct efx_nic *efx)
 {
 	efx_oword_t reg;
-	falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER);
-	return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
+	efx_reado(efx, &reg, FR_AB_EE_SPI_HCMD);
+	return EFX_OWORD_FIELD(reg, FRF_AB_EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
 }
 
 /* Wait for SPI command completion */
@@ -1678,11 +242,10 @@ static int falcon_spi_wait(struct efx_ni
 	}
 }
 
-int falcon_spi_cmd(const struct efx_spi_device *spi,
+int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi,
 		   unsigned int command, int address,
 		   const void *in, void *out, size_t len)
 {
-	struct efx_nic *efx = spi->efx;
 	bool addressed = (address >= 0);
 	bool reading = (out != NULL);
 	efx_oword_t reg;
@@ -1700,27 +263,27 @@ int falcon_spi_cmd(const struct efx_spi_
 
 	/* Program address register, if we have an address */
 	if (addressed) {
-		EFX_POPULATE_OWORD_1(reg, EE_SPI_HADR_ADR, address);
-		falcon_write(efx, &reg, EE_SPI_HADR_REG_KER);
+		EFX_POPULATE_OWORD_1(reg, FRF_AB_EE_SPI_HADR_ADR, address);
+		efx_writeo(efx, &reg, FR_AB_EE_SPI_HADR);
 	}
 
 	/* Program data register, if we have data */
 	if (in != NULL) {
 		memcpy(&reg, in, len);
-		falcon_write(efx, &reg, EE_SPI_HDATA_REG_KER);
+		efx_writeo(efx, &reg, FR_AB_EE_SPI_HDATA);
 	}
 
 	/* Issue read/write command */
 	EFX_POPULATE_OWORD_7(reg,
-			     EE_SPI_HCMD_CMD_EN, 1,
-			     EE_SPI_HCMD_SF_SEL, spi->device_id,
-			     EE_SPI_HCMD_DABCNT, len,
-			     EE_SPI_HCMD_READ, reading,
-			     EE_SPI_HCMD_DUBCNT, 0,
-			     EE_SPI_HCMD_ADBCNT,
+			     FRF_AB_EE_SPI_HCMD_CMD_EN, 1,
+			     FRF_AB_EE_SPI_HCMD_SF_SEL, spi->device_id,
+			     FRF_AB_EE_SPI_HCMD_DABCNT, len,
+			     FRF_AB_EE_SPI_HCMD_READ, reading,
+			     FRF_AB_EE_SPI_HCMD_DUBCNT, 0,
+			     FRF_AB_EE_SPI_HCMD_ADBCNT,
 			     (addressed ? spi->addr_len : 0),
-			     EE_SPI_HCMD_ENC, command);
-	falcon_write(efx, &reg, EE_SPI_HCMD_REG_KER);
+			     FRF_AB_EE_SPI_HCMD_ENC, command);
+	efx_writeo(efx, &reg, FR_AB_EE_SPI_HCMD);
 
 	/* Wait for read/write to complete */
 	rc = falcon_spi_wait(efx);
@@ -1729,7 +292,7 @@ int falcon_spi_cmd(const struct efx_spi_
 
 	/* Read data */
 	if (out != NULL) {
-		falcon_read(efx, &reg, EE_SPI_HDATA_REG_KER);
+		efx_reado(efx, &reg, FR_AB_EE_SPI_HDATA);
 		memcpy(out, &reg, len);
 	}
 
@@ -1751,15 +314,15 @@ efx_spi_munge_command(const struct efx_s
 }
 
 /* Wait up to 10 ms for buffered write completion */
-int falcon_spi_wait_write(const struct efx_spi_device *spi)
+int
+falcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi)
 {
-	struct efx_nic *efx = spi->efx;
 	unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
 	u8 status;
 	int rc;
 
 	for (;;) {
-		rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
+		rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
 				    &status, sizeof(status));
 		if (rc)
 			return rc;
@@ -1775,8 +338,8 @@ int falcon_spi_wait_write(const struct e
 	}
 }
 
-int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
-		    size_t len, size_t *retlen, u8 *buffer)
+int falcon_spi_read(struct efx_nic *efx, const struct efx_spi_device *spi,
+		    loff_t start, size_t len, size_t *retlen, u8 *buffer)
 {
 	size_t block_len, pos = 0;
 	unsigned int command;
@@ -1786,7 +349,7 @@ int falcon_spi_read(const struct efx_spi
 		block_len = min(len - pos, FALCON_SPI_MAX_LEN);
 
 		command = efx_spi_munge_command(spi, SPI_READ, start + pos);
-		rc = falcon_spi_cmd(spi, command, start + pos, NULL,
+		rc = falcon_spi_cmd(efx, spi, command, start + pos, NULL,
 				    buffer + pos, block_len);
 		if (rc)
 			break;
@@ -1805,8 +368,9 @@ int falcon_spi_read(const struct efx_spi
 	return rc;
 }
 
-int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
-		     size_t len, size_t *retlen, const u8 *buffer)
+int
+falcon_spi_write(struct efx_nic *efx, const struct efx_spi_device *spi,
+		 loff_t start, size_t len, size_t *retlen, const u8 *buffer)
 {
 	u8 verify_buffer[FALCON_SPI_MAX_LEN];
 	size_t block_len, pos = 0;
@@ -1814,24 +378,24 @@ int falcon_spi_write(const struct efx_sp
 	int rc = 0;
 
 	while (pos < len) {
-		rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+		rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
 		if (rc)
 			break;
 
 		block_len = min(len - pos,
 				falcon_spi_write_limit(spi, start + pos));
 		command = efx_spi_munge_command(spi, SPI_WRITE, start + pos);
-		rc = falcon_spi_cmd(spi, command, start + pos,
+		rc = falcon_spi_cmd(efx, spi, command, start + pos,
 				    buffer + pos, NULL, block_len);
 		if (rc)
 			break;
 
-		rc = falcon_spi_wait_write(spi);
+		rc = falcon_spi_wait_write(efx, spi);
 		if (rc)
 			break;
 
 		command = efx_spi_munge_command(spi, SPI_READ, start + pos);
-		rc = falcon_spi_cmd(spi, command, start + pos,
+		rc = falcon_spi_cmd(efx, spi, command, start + pos,
 				    NULL, verify_buffer, block_len);
 		if (memcmp(verify_buffer, buffer + pos, block_len)) {
 			rc = -EIO;
@@ -1860,60 +424,70 @@ int falcon_spi_write(const struct efx_sp
  **************************************************************************
  */
 
-static int falcon_reset_macs(struct efx_nic *efx)
+static void falcon_push_multicast_hash(struct efx_nic *efx)
 {
-	efx_oword_t reg;
+	union efx_multicast_hash *mc_hash = &efx->multicast_hash;
+
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
+	efx_writeo(efx, &mc_hash->oword[0], FR_AB_MAC_MC_HASH_REG0);
+	efx_writeo(efx, &mc_hash->oword[1], FR_AB_MAC_MC_HASH_REG1);
+}
+
+static void falcon_reset_macs(struct efx_nic *efx)
+{
+	struct falcon_nic_data *nic_data = efx->nic_data;
+	efx_oword_t reg, mac_ctrl;
 	int count;
 
-	if (falcon_rev(efx) < FALCON_REV_B0) {
+	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) {
 		/* It's not safe to use GLB_CTL_REG to reset the
 		 * macs, so instead use the internal MAC resets
 		 */
 		if (!EFX_IS10G(efx)) {
-			EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1);
-			falcon_write(efx, &reg, GM_CFG1_REG);
+			EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1);
+			efx_writeo(efx, &reg, FR_AB_GM_CFG1);
 			udelay(1000);
 
-			EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0);
-			falcon_write(efx, &reg, GM_CFG1_REG);
+			EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0);
+			efx_writeo(efx, &reg, FR_AB_GM_CFG1);
 			udelay(1000);
-			return 0;
+			return;
 		} else {
-			EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
-			falcon_write(efx, &reg, XM_GLB_CFG_REG);
+			EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1);
+			efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
 
 			for (count = 0; count < 10000; count++) {
-				falcon_read(efx, &reg, XM_GLB_CFG_REG);
-				if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
-					return 0;
+				efx_reado(efx, &reg, FR_AB_XM_GLB_CFG);
+				if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) ==
+				    0)
+					return;
 				udelay(10);
 			}
 
 			EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
-			return -ETIMEDOUT;
 		}
 	}
 
-	/* MAC stats will fail whilst the TX fifo is draining. Serialise
-	 * the drain sequence with the statistics fetch */
-	efx_stats_disable(efx);
+	/* Mac stats will fail whist the TX fifo is draining */
+	WARN_ON(nic_data->stats_disable_count == 0);
 
-	falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
-	falcon_write(efx, &reg, MAC0_CTRL_REG_KER);
+	efx_reado(efx, &mac_ctrl, FR_AB_MAC_CTRL);
+	EFX_SET_OWORD_FIELD(mac_ctrl, FRF_BB_TXFIFO_DRAIN_EN, 1);
+	efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
 
-	falcon_read(efx, &reg, GLB_CTL_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1);
-	EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1);
-	EFX_SET_OWORD_FIELD(reg, RST_EM, 1);
-	falcon_write(efx, &reg, GLB_CTL_REG_KER);
+	efx_reado(efx, &reg, FR_AB_GLB_CTL);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGTX, 1);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_XGRX, 1);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_RST_EM, 1);
+	efx_writeo(efx, &reg, FR_AB_GLB_CTL);
 
 	count = 0;
 	while (1) {
-		falcon_read(efx, &reg, GLB_CTL_REG_KER);
-		if (!EFX_OWORD_FIELD(reg, RST_XGTX) &&
-		    !EFX_OWORD_FIELD(reg, RST_XGRX) &&
-		    !EFX_OWORD_FIELD(reg, RST_EM)) {
+		efx_reado(efx, &reg, FR_AB_GLB_CTL);
+		if (!EFX_OWORD_FIELD(reg, FRF_AB_RST_XGTX) &&
+		    !EFX_OWORD_FIELD(reg, FRF_AB_RST_XGRX) &&
+		    !EFX_OWORD_FIELD(reg, FRF_AB_RST_EM)) {
 			EFX_LOG(efx, "Completed MAC reset after %d loops\n",
 				count);
 			break;
@@ -1926,55 +500,50 @@ static int falcon_reset_macs(struct efx_
 		udelay(10);
 	}
 
-	efx_stats_enable(efx);
-
-	/* If we've reset the EM block and the link is up, then
-	 * we'll have to kick the XAUI link so the PHY can recover */
-	if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
-		falcon_reset_xaui(efx);
-
-	return 0;
+	/* Ensure the correct MAC is selected before statistics
+	 * are re-enabled by the caller */
+	efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL);
 }
 
 void falcon_drain_tx_fifo(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 
-	if ((falcon_rev(efx) < FALCON_REV_B0) ||
+	if ((efx_nic_rev(efx) < EFX_REV_FALCON_B0) ||
 	    (efx->loopback_mode != LOOPBACK_NONE))
 		return;
 
-	falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
+	efx_reado(efx, &reg, FR_AB_MAC_CTRL);
 	/* There is no point in draining more than once */
-	if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0))
+	if (EFX_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN))
 		return;
 
 	falcon_reset_macs(efx);
 }
 
-void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
+static void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 
-	if (falcon_rev(efx) < FALCON_REV_B0)
+	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
 		return;
 
 	/* Isolate the MAC -> RX */
-	falcon_read(efx, &reg, RX_CFG_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0);
-	falcon_write(efx, &reg, RX_CFG_REG_KER);
+	efx_reado(efx, &reg, FR_AZ_RX_CFG);
+	EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0);
+	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
 
-	if (!efx->link_up)
-		falcon_drain_tx_fifo(efx);
+	/* Isolate TX -> MAC */
+	falcon_drain_tx_fifo(efx);
 }
 
 void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
 {
+	struct efx_link_state *link_state = &efx->link_state;
 	efx_oword_t reg;
 	int link_speed;
-	bool tx_fc;
 
-	switch (efx->link_speed) {
+	switch (link_state->speed) {
 	case 10000: link_speed = 3; break;
 	case 1000:  link_speed = 2; break;
 	case 100:   link_speed = 1; break;
@@ -1985,75 +554,139 @@ void falcon_reconfigure_mac_wrapper(stru
 	 * indefinitely held and TX queue can be flushed at any point
 	 * while the link is down. */
 	EFX_POPULATE_OWORD_5(reg,
-			     MAC_XOFF_VAL, 0xffff /* max pause time */,
-			     MAC_BCAD_ACPT, 1,
-			     MAC_UC_PROM, efx->promiscuous,
-			     MAC_LINK_STATUS, 1, /* always set */
-			     MAC_SPEED, link_speed);
+			     FRF_AB_MAC_XOFF_VAL, 0xffff /* max pause time */,
+			     FRF_AB_MAC_BCAD_ACPT, 1,
+			     FRF_AB_MAC_UC_PROM, efx->promiscuous,
+			     FRF_AB_MAC_LINK_STATUS, 1, /* always set */
+			     FRF_AB_MAC_SPEED, link_speed);
 	/* On B0, MAC backpressure can be disabled and packets get
 	 * discarded. */
-	if (falcon_rev(efx) >= FALCON_REV_B0) {
-		EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0,
-				    !efx->link_up);
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+		EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN,
+				    !link_state->up);
 	}
 
-	falcon_write(efx, &reg, MAC0_CTRL_REG_KER);
+	efx_writeo(efx, &reg, FR_AB_MAC_CTRL);
 
 	/* Restore the multicast hash registers. */
-	falcon_set_multicast_hash(efx);
-
-	/* Transmission of pause frames when RX crosses the threshold is
-	 * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL.
-	 * Action on receipt of pause frames is controller by XM_DIS_FCNTL */
-	tx_fc = !!(efx->link_fc & EFX_FC_TX);
-	falcon_read(efx, &reg, RX_CFG_REG_KER);
-	EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc);
+	falcon_push_multicast_hash(efx);
 
+	efx_reado(efx, &reg, FR_AZ_RX_CFG);
+	/* Enable XOFF signal from RX FIFO (we enabled it during NIC
+	 * initialisation but it may read back as 0) */
+	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
 	/* Unisolate the MAC -> RX */
-	if (falcon_rev(efx) >= FALCON_REV_B0)
-		EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1);
-	falcon_write(efx, &reg, RX_CFG_REG_KER);
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1);
+	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
 }
 
-int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
+static void falcon_stats_request(struct efx_nic *efx)
 {
+	struct falcon_nic_data *nic_data = efx->nic_data;
 	efx_oword_t reg;
-	u32 *dma_done;
-	int i;
 
-	if (disable_dma_stats)
-		return 0;
+	WARN_ON(nic_data->stats_pending);
+	WARN_ON(nic_data->stats_disable_count);
 
-	/* Statistics fetch will fail if the MAC is in TX drain */
-	if (falcon_rev(efx) >= FALCON_REV_B0) {
-		efx_oword_t temp;
-		falcon_read(efx, &temp, MAC0_CTRL_REG_KER);
-		if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0))
-			return 0;
-	}
+	if (nic_data->stats_dma_done == NULL)
+		return;	/* no mac selected */
 
-	dma_done = (efx->stats_buffer.addr + done_offset);
-	*dma_done = FALCON_STATS_NOT_DONE;
+	*nic_data->stats_dma_done = FALCON_STATS_NOT_DONE;
+	nic_data->stats_pending = true;
 	wmb(); /* ensure done flag is clear */
 
 	/* Initiate DMA transfer of stats */
 	EFX_POPULATE_OWORD_2(reg,
-			     MAC_STAT_DMA_CMD, 1,
-			     MAC_STAT_DMA_ADR,
+			     FRF_AB_MAC_STAT_DMA_CMD, 1,
+			     FRF_AB_MAC_STAT_DMA_ADR,
 			     efx->stats_buffer.dma_addr);
-	falcon_write(efx, &reg, MAC0_STAT_DMA_REG_KER);
+	efx_writeo(efx, &reg, FR_AB_MAC_STAT_DMA);
 
-	/* Wait for transfer to complete */
-	for (i = 0; i < 400; i++) {
-		if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) {
-			rmb(); /* Ensure the stats are valid. */
-			return 0;
-		}
-		udelay(10);
+	mod_timer(&nic_data->stats_timer, round_jiffies_up(jiffies + HZ / 2));
+}
+
+static void falcon_stats_complete(struct efx_nic *efx)
+{
+	struct falcon_nic_data *nic_data = efx->nic_data;
+
+	if (!nic_data->stats_pending)
+		return;
+
+	nic_data->stats_pending = 0;
+	if (*nic_data->stats_dma_done == FALCON_STATS_DONE) {
+		rmb(); /* read the done flag before the stats */
+		efx->mac_op->update_stats(efx);
+	} else {
+		EFX_ERR(efx, "timed out waiting for statistics\n");
 	}
+}
 
-	EFX_ERR(efx, "timed out waiting for statistics\n");
-	return -ETIMEDOUT;
+static void falcon_stats_timer_func(unsigned long context)
+{
+	struct efx_nic *efx = (struct efx_nic *)context;
+	struct falcon_nic_data *nic_data = efx->nic_data;
+
+	spin_lock(&efx->stats_lock);
+
+	falcon_stats_complete(efx);
+	if (nic_data->stats_disable_count == 0)
+		falcon_stats_request(efx);
+
+	spin_unlock(&efx->stats_lock);
+}
+
+static void falcon_switch_mac(struct efx_nic *efx);
+
+static bool falcon_loopback_link_poll(struct efx_nic *efx)
+{
+	struct efx_link_state old_state = efx->link_state;
+
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+	WARN_ON(!LOOPBACK_INTERNAL(efx));
+
+	efx->link_state.fd = true;
+	efx->link_state.fc = efx->wanted_fc;
+	efx->link_state.up = true;
+
+	if (efx->loopback_mode == LOOPBACK_GMAC)
+		efx->link_state.speed = 1000;
+	else
+		efx->link_state.speed = 10000;
+
+	return !efx_link_state_equal(&efx->link_state, &old_state);
+}
+
+static int falcon_reconfigure_port(struct efx_nic *efx)
+{
+	int rc;
+
+	WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0);
+
+	/* Poll the PHY link state *before* reconfiguring it. This means we
+	 * will pick up the correct speed (in loopback) to select the correct
+	 * MAC.
+	 */
+	if (LOOPBACK_INTERNAL(efx))
+		falcon_loopback_link_poll(efx);
+	else
+		efx->phy_op->poll(efx);
+
+	falcon_stop_nic_stats(efx);
+	falcon_deconfigure_mac_wrapper(efx);
+
+	falcon_switch_mac(efx);
+
+	efx->phy_op->reconfigure(efx);
+	rc = efx->mac_op->reconfigure(efx);
+	BUG_ON(rc);
+
+	falcon_start_nic_stats(efx);
+
+	/* Synchronise efx->link_state with the kernel */
+	efx_link_status_changed(efx);
+
+	return 0;
 }
 
 /**************************************************************************
@@ -2066,18 +699,18 @@ int falcon_dma_stats(struct efx_nic *efx
 /* Wait for GMII access to complete */
 static int falcon_gmii_wait(struct efx_nic *efx)
 {
-	efx_dword_t md_stat;
+	efx_oword_t md_stat;
 	int count;
 
 	/* wait upto 50ms - taken max from datasheet */
 	for (count = 0; count < 5000; count++) {
-		falcon_readl(efx, &md_stat, MD_STAT_REG_KER);
-		if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) {
-			if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 ||
-			    EFX_DWORD_FIELD(md_stat, MD_BSERR) != 0) {
+		efx_reado(efx, &md_stat, FR_AB_MD_STAT);
+		if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) {
+			if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_LNFL) != 0 ||
+			    EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSERR) != 0) {
 				EFX_ERR(efx, "error from GMII access "
-					EFX_DWORD_FMT"\n",
-					EFX_DWORD_VAL(md_stat));
+					EFX_OWORD_FMT"\n",
+					EFX_OWORD_VAL(md_stat));
 				return -EIO;
 			}
 			return 0;
@@ -2099,7 +732,7 @@ static int falcon_mdio_write(struct net_
 	EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
 		    prtad, devad, addr, value);
 
-	spin_lock_bh(&efx->phy_lock);
+	mutex_lock(&efx->mdio_lock);
 
 	/* Check MDIO not currently being accessed */
 	rc = falcon_gmii_wait(efx);
@@ -2107,34 +740,35 @@ static int falcon_mdio_write(struct net_
 		goto out;
 
 	/* Write the address/ID register */
-	EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
-	falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr);
+	efx_writeo(efx, &reg, FR_AB_MD_PHY_ADR);
 
-	EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
-	falcon_write(efx, &reg, MD_ID_REG_KER);
+	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad,
+			     FRF_AB_MD_DEV_ADR, devad);
+	efx_writeo(efx, &reg, FR_AB_MD_ID);
 
 	/* Write data */
-	EFX_POPULATE_OWORD_1(reg, MD_TXD, value);
-	falcon_write(efx, &reg, MD_TXD_REG_KER);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_TXD, value);
+	efx_writeo(efx, &reg, FR_AB_MD_TXD);
 
 	EFX_POPULATE_OWORD_2(reg,
-			     MD_WRC, 1,
-			     MD_GC, 0);
-	falcon_write(efx, &reg, MD_CS_REG_KER);
+			     FRF_AB_MD_WRC, 1,
+			     FRF_AB_MD_GC, 0);
+	efx_writeo(efx, &reg, FR_AB_MD_CS);
 
 	/* Wait for data to be written */
 	rc = falcon_gmii_wait(efx);
 	if (rc) {
 		/* Abort the write operation */
 		EFX_POPULATE_OWORD_2(reg,
-				     MD_WRC, 0,
-				     MD_GC, 1);
-		falcon_write(efx, &reg, MD_CS_REG_KER);
+				     FRF_AB_MD_WRC, 0,
+				     FRF_AB_MD_GC, 1);
+		efx_writeo(efx, &reg, FR_AB_MD_CS);
 		udelay(10);
 	}
 
- out:
-	spin_unlock_bh(&efx->phy_lock);
+out:
+	mutex_unlock(&efx->mdio_lock);
 	return rc;
 }
 
@@ -2146,152 +780,139 @@ static int falcon_mdio_read(struct net_d
 	efx_oword_t reg;
 	int rc;
 
-	spin_lock_bh(&efx->phy_lock);
+	mutex_lock(&efx->mdio_lock);
 
 	/* Check MDIO not currently being accessed */
 	rc = falcon_gmii_wait(efx);
 	if (rc)
 		goto out;
 
-	EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
-	falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_MD_PHY_ADR, addr);
+	efx_writeo(efx, &reg, FR_AB_MD_PHY_ADR);
 
-	EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
-	falcon_write(efx, &reg, MD_ID_REG_KER);
+	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_PRT_ADR, prtad,
+			     FRF_AB_MD_DEV_ADR, devad);
+	efx_writeo(efx, &reg, FR_AB_MD_ID);
 
 	/* Request data to be read */
-	EFX_POPULATE_OWORD_2(reg, MD_RDC, 1, MD_GC, 0);
-	falcon_write(efx, &reg, MD_CS_REG_KER);
+	EFX_POPULATE_OWORD_2(reg, FRF_AB_MD_RDC, 1, FRF_AB_MD_GC, 0);
+	efx_writeo(efx, &reg, FR_AB_MD_CS);
 
 	/* Wait for data to become available */
 	rc = falcon_gmii_wait(efx);
 	if (rc == 0) {
-		falcon_read(efx, &reg, MD_RXD_REG_KER);
-		rc = EFX_OWORD_FIELD(reg, MD_RXD);
+		efx_reado(efx, &reg, FR_AB_MD_RXD);
+		rc = EFX_OWORD_FIELD(reg, FRF_AB_MD_RXD);
 		EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
 			    prtad, devad, addr, rc);
 	} else {
 		/* Abort the read operation */
 		EFX_POPULATE_OWORD_2(reg,
-				     MD_RIC, 0,
-				     MD_GC, 1);
-		falcon_write(efx, &reg, MD_CS_REG_KER);
+				     FRF_AB_MD_RIC, 0,
+				     FRF_AB_MD_GC, 1);
+		efx_writeo(efx, &reg, FR_AB_MD_CS);
 
 		EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
 			prtad, devad, addr, rc);
 	}
 
- out:
-	spin_unlock_bh(&efx->phy_lock);
+out:
+	mutex_unlock(&efx->mdio_lock);
 	return rc;
 }
 
-static int falcon_probe_phy(struct efx_nic *efx)
+static void falcon_clock_mac(struct efx_nic *efx)
 {
-	switch (efx->phy_type) {
-	case PHY_TYPE_SFX7101:
-		efx->phy_op = &falcon_sfx7101_phy_ops;
-		break;
-	case PHY_TYPE_SFT9001A:
-	case PHY_TYPE_SFT9001B:
-		efx->phy_op = &falcon_sft9001_phy_ops;
-		break;
-	case PHY_TYPE_QT2022C2:
-	case PHY_TYPE_QT2025C:
-		efx->phy_op = &falcon_xfp_phy_ops;
-		break;
-	default:
-		EFX_ERR(efx, "Unknown PHY type %d\n",
-			efx->phy_type);
-		return -1;
-	}
-
-	if (efx->phy_op->macs & EFX_XMAC)
-		efx->loopback_modes |= ((1 << LOOPBACK_XGMII) |
-					(1 << LOOPBACK_XGXS) |
-					(1 << LOOPBACK_XAUI));
-	if (efx->phy_op->macs & EFX_GMAC)
-		efx->loopback_modes |= (1 << LOOPBACK_GMAC);
-	efx->loopback_modes |= efx->phy_op->loopbacks;
+	unsigned strap_val;
+	efx_oword_t nic_stat;
 
-	return 0;
+	/* Configure the NIC generated MAC clock correctly */
+	efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
+	strap_val = EFX_IS10G(efx) ? 5 : 3;
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+		EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1);
+		EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val);
+		efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT);
+	} else {
+		/* Falcon A1 does not support 1G/10G speed switching
+		 * and must not be used with a PHY that does. */
+		BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) !=
+		       strap_val);
+	}
 }
 
-int falcon_switch_mac(struct efx_nic *efx)
+static void falcon_switch_mac(struct efx_nic *efx)
 {
 	struct efx_mac_operations *old_mac_op = efx->mac_op;
-	efx_oword_t nic_stat;
-	unsigned strap_val;
-	int rc = 0;
-
-	/* Don't try to fetch MAC stats while we're switching MACs */
-	efx_stats_disable(efx);
-
-	/* Internal loopbacks override the phy speed setting */
-	if (efx->loopback_mode == LOOPBACK_GMAC) {
-		efx->link_speed = 1000;
-		efx->link_fd = true;
-	} else if (LOOPBACK_INTERNAL(efx)) {
-		efx->link_speed = 10000;
-		efx->link_fd = true;
-	}
+	struct falcon_nic_data *nic_data = efx->nic_data;
+	unsigned int stats_done_offset;
 
 	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+	WARN_ON(nic_data->stats_disable_count == 0);
+
 	efx->mac_op = (EFX_IS10G(efx) ?
 		       &falcon_xmac_operations : &falcon_gmac_operations);
 
-	/* Always push the NIC_STAT_REG setting even if the mac hasn't
-	 * changed, because this function is run post online reset */
-	falcon_read(efx, &nic_stat, NIC_STAT_REG);
-	strap_val = EFX_IS10G(efx) ? 5 : 3;
-	if (falcon_rev(efx) >= FALCON_REV_B0) {
-		EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1);
-		EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val);
-		falcon_write(efx, &nic_stat, NIC_STAT_REG);
-	} else {
-		/* Falcon A1 does not support 1G/10G speed switching
-		 * and must not be used with a PHY that does. */
-		BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
-	}
+	if (EFX_IS10G(efx))
+		stats_done_offset = XgDmaDone_offset;
+	else
+		stats_done_offset = GDmaDone_offset;
+	nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset;
 
 	if (old_mac_op == efx->mac_op)
-		goto out;
+		return;
+
+	falcon_clock_mac(efx);
 
 	EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
 	/* Not all macs support a mac-level link state */
-	efx->mac_up = true;
-
-	rc = falcon_reset_macs(efx);
-out:
-	efx_stats_enable(efx);
-	return rc;
+	efx->xmac_poll_required = false;
+	falcon_reset_macs(efx);
 }
 
 /* This call is responsible for hooking in the MAC and PHY operations */
-int falcon_probe_port(struct efx_nic *efx)
+static int falcon_probe_port(struct efx_nic *efx)
 {
 	int rc;
 
-	/* Hook in PHY operations table */
-	rc = falcon_probe_phy(efx);
-	if (rc)
-		return rc;
+	switch (efx->phy_type) {
+	case PHY_TYPE_SFX7101:
+		efx->phy_op = &falcon_sfx7101_phy_ops;
+		break;
+	case PHY_TYPE_SFT9001A:
+	case PHY_TYPE_SFT9001B:
+		efx->phy_op = &falcon_sft9001_phy_ops;
+		break;
+	case PHY_TYPE_QT2022C2:
+	case PHY_TYPE_QT2025C:
+		efx->phy_op = &falcon_qt202x_phy_ops;
+		break;
+	default:
+		EFX_ERR(efx, "Unknown PHY type %d\n",
+			efx->phy_type);
+		return -ENODEV;
+	}
 
-	/* Set up MDIO structure for PHY */
-	efx->mdio.mmds = efx->phy_op->mmds;
-	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+	/* Fill out MDIO structure and loopback modes */
 	efx->mdio.mdio_read = falcon_mdio_read;
 	efx->mdio.mdio_write = falcon_mdio_write;
+	rc = efx->phy_op->probe(efx);
+	if (rc != 0)
+		return rc;
+
+	/* Initial assumption */
+	efx->link_state.speed = 10000;
+	efx->link_state.fd = true;
 
 	/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
-	if (falcon_rev(efx) >= FALCON_REV_B0)
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
 		efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
 	else
 		efx->wanted_fc = EFX_FC_RX;
 
 	/* Allocate buffer for stats */
-	rc = falcon_alloc_buffer(efx, &efx->stats_buffer,
-				 FALCON_MAC_STATS_SIZE);
+	rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
+				  FALCON_MAC_STATS_SIZE);
 	if (rc)
 		return rc;
 	EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n",
@@ -2302,40 +923,20 @@ int falcon_probe_port(struct efx_nic *ef
 	return 0;
 }
 
-void falcon_remove_port(struct efx_nic *efx)
-{
-	falcon_free_buffer(efx, &efx->stats_buffer);
-}
-
-/**************************************************************************
- *
- * Multicast filtering
- *
- **************************************************************************
- */
-
-void falcon_set_multicast_hash(struct efx_nic *efx)
+static void falcon_remove_port(struct efx_nic *efx)
 {
-	union efx_multicast_hash *mc_hash = &efx->multicast_hash;
-
-	/* Broadcast packets go through the multicast hash filter.
-	 * ether_crc_le() of the broadcast address is 0xbe2612ff
-	 * so we always add bit 0xff to the mask.
-	 */
-	set_bit_le(0xff, mc_hash->byte);
-
-	falcon_write(efx, &mc_hash->oword[0], MAC_MCAST_HASH_REG0_KER);
-	falcon_write(efx, &mc_hash->oword[1], MAC_MCAST_HASH_REG1_KER);
+	efx->phy_op->remove(efx);
+	efx_nic_free_buffer(efx, &efx->stats_buffer);
 }
 
-
 /**************************************************************************
  *
  * Falcon test code
  *
  **************************************************************************/
 
-int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
+static int
+falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
 {
 	struct falcon_nvconfig *nvconfig;
 	struct efx_spi_device *spi;
@@ -2351,10 +952,10 @@ int falcon_read_nvram(struct efx_nic *ef
 	region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL);
 	if (!region)
 		return -ENOMEM;
-	nvconfig = region + NVCONFIG_OFFSET;
+	nvconfig = region + FALCON_NVCONFIG_OFFSET;
 
 	mutex_lock(&efx->spi_lock);
-	rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region);
+	rc = falcon_spi_read(efx, spi, 0, FALCON_NVCONFIG_END, NULL, region);
 	mutex_unlock(&efx->spi_lock);
 	if (rc) {
 		EFX_ERR(efx, "Failed to read %s\n",
@@ -2367,7 +968,7 @@ int falcon_read_nvram(struct efx_nic *ef
 	struct_ver = le16_to_cpu(nvconfig->board_struct_ver);
 
 	rc = -EINVAL;
-	if (magic_num != NVCONFIG_BOARD_MAGIC_NUM) {
+	if (magic_num != FALCON_NVCONFIG_BOARD_MAGIC_NUM) {
 		EFX_ERR(efx, "NVRAM bad magic 0x%x\n", magic_num);
 		goto out;
 	}
@@ -2398,107 +999,54 @@ int falcon_read_nvram(struct efx_nic *ef
 	return rc;
 }
 
-/* Registers tested in the falcon register test */
-static struct {
-	unsigned address;
-	efx_oword_t mask;
-} efx_test_registers[] = {
-	{ ADR_REGION_REG_KER,
+static int falcon_test_nvram(struct efx_nic *efx)
+{
+	return falcon_read_nvram(efx, NULL);
+}
+
+static const struct efx_nic_register_test falcon_b0_register_tests[] = {
+	{ FR_AZ_ADR_REGION,
 	  EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) },
-	{ RX_CFG_REG_KER,
+	{ FR_AZ_RX_CFG,
 	  EFX_OWORD32(0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000) },
-	{ TX_CFG_REG_KER,
+	{ FR_AZ_TX_CFG,
 	  EFX_OWORD32(0x7FFF0037, 0x00000000, 0x00000000, 0x00000000) },
-	{ TX_CFG2_REG_KER,
+	{ FR_AZ_TX_RESERVED,
 	  EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) },
-	{ MAC0_CTRL_REG_KER,
+	{ FR_AB_MAC_CTRL,
 	  EFX_OWORD32(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000) },
-	{ SRM_TX_DC_CFG_REG_KER,
+	{ FR_AZ_SRM_TX_DC_CFG,
 	  EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) },
-	{ RX_DC_CFG_REG_KER,
+	{ FR_AZ_RX_DC_CFG,
 	  EFX_OWORD32(0x0000000F, 0x00000000, 0x00000000, 0x00000000) },
-	{ RX_DC_PF_WM_REG_KER,
+	{ FR_AZ_RX_DC_PF_WM,
 	  EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
-	{ DP_CTRL_REG,
+	{ FR_BZ_DP_CTRL,
 	  EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
-	{ GM_CFG2_REG,
+	{ FR_AB_GM_CFG2,
 	  EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) },
-	{ GMF_CFG0_REG,
+	{ FR_AB_GMF_CFG0,
 	  EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_GLB_CFG_REG,
+	{ FR_AB_XM_GLB_CFG,
 	  EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_TX_CFG_REG,
+	{ FR_AB_XM_TX_CFG,
 	  EFX_OWORD32(0x00080164, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_RX_CFG_REG,
+	{ FR_AB_XM_RX_CFG,
 	  EFX_OWORD32(0x07100A0C, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_RX_PARAM_REG,
+	{ FR_AB_XM_RX_PARAM,
 	  EFX_OWORD32(0x00001FF8, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_FC_REG,
+	{ FR_AB_XM_FC,
 	  EFX_OWORD32(0xFFFF0001, 0x00000000, 0x00000000, 0x00000000) },
-	{ XM_ADR_LO_REG,
+	{ FR_AB_XM_ADR_LO,
 	  EFX_OWORD32(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000) },
-	{ XX_SD_CTL_REG,
+	{ FR_AB_XX_SD_CTL,
 	  EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) },
 };
 
-static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b,
-				     const efx_oword_t *mask)
-{
-	return ((a->u64[0] ^ b->u64[0]) & mask->u64[0]) ||
-		((a->u64[1] ^ b->u64[1]) & mask->u64[1]);
-}
-
-int falcon_test_registers(struct efx_nic *efx)
+static int falcon_b0_test_registers(struct efx_nic *efx)
 {
-	unsigned address = 0, i, j;
-	efx_oword_t mask, imask, original, reg, buf;
-
-	/* Falcon should be in loopback to isolate the XMAC from the PHY */
-	WARN_ON(!LOOPBACK_INTERNAL(efx));
-
-	for (i = 0; i < ARRAY_SIZE(efx_test_registers); ++i) {
-		address = efx_test_registers[i].address;
-		mask = imask = efx_test_registers[i].mask;
-		EFX_INVERT_OWORD(imask);
-
-		falcon_read(efx, &original, address);
-
-		/* bit sweep on and off */
-		for (j = 0; j < 128; j++) {
-			if (!EFX_EXTRACT_OWORD32(mask, j, j))
-				continue;
-
-			/* Test this testable bit can be set in isolation */
-			EFX_AND_OWORD(reg, original, mask);
-			EFX_SET_OWORD32(reg, j, j, 1);
-
-			falcon_write(efx, &reg, address);
-			falcon_read(efx, &buf, address);
-
-			if (efx_masked_compare_oword(&reg, &buf, &mask))
-				goto fail;
-
-			/* Test this testable bit can be cleared in isolation */
-			EFX_OR_OWORD(reg, original, mask);
-			EFX_SET_OWORD32(reg, j, j, 0);
-
-			falcon_write(efx, &reg, address);
-			falcon_read(efx, &buf, address);
-
-			if (efx_masked_compare_oword(&reg, &buf, &mask))
-				goto fail;
-		}
-
-		falcon_write(efx, &original, address);
-	}
-
-	return 0;
-
-fail:
-	EFX_ERR(efx, "wrote "EFX_OWORD_FMT" read "EFX_OWORD_FMT
-		" at address 0x%x mask "EFX_OWORD_FMT"\n", EFX_OWORD_VAL(reg),
-		EFX_OWORD_VAL(buf), address, EFX_OWORD_VAL(mask));
-	return -EIO;
+	return efx_nic_test_registers(efx, falcon_b0_register_tests,
+				      ARRAY_SIZE(falcon_b0_register_tests));
 }
 
 /**************************************************************************
@@ -2510,13 +1058,13 @@ fail:
 
 /* Resets NIC to known state.  This routine must be called in process
  * context and is allowed to sleep. */
-int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
+static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
 {
 	struct falcon_nic_data *nic_data = efx->nic_data;
 	efx_oword_t glb_ctl_reg_ker;
 	int rc;
 
-	EFX_LOG(efx, "performing hardware reset (%d)\n", method);
+	EFX_LOG(efx, "performing %s hardware reset\n", RESET_TYPE(method));
 
 	/* Initiate device reset */
 	if (method == RESET_TYPE_WORLD) {
@@ -2526,7 +1074,7 @@ int falcon_reset_hw(struct efx_nic *efx,
 				"function prior to hardware reset\n");
 			goto fail1;
 		}
-		if (FALCON_IS_DUAL_FUNC(efx)) {
+		if (efx_nic_is_dual_func(efx)) {
 			rc = pci_save_state(nic_data->pci_dev2);
 			if (rc) {
 				EFX_ERR(efx, "failed to backup PCI state of "
@@ -2537,29 +1085,31 @@ int falcon_reset_hw(struct efx_nic *efx,
 		}
 
 		EFX_POPULATE_OWORD_2(glb_ctl_reg_ker,
-				     EXT_PHY_RST_DUR, 0x7,
-				     SWRST, 1);
+				     FRF_AB_EXT_PHY_RST_DUR,
+				     FFE_AB_EXT_PHY_RST_DUR_10240US,
+				     FRF_AB_SWRST, 1);
 	} else {
-		int reset_phy = (method == RESET_TYPE_INVISIBLE ?
-				 EXCLUDE_FROM_RESET : 0);
-
 		EFX_POPULATE_OWORD_7(glb_ctl_reg_ker,
-				     EXT_PHY_RST_CTL, reset_phy,
-				     PCIE_CORE_RST_CTL, EXCLUDE_FROM_RESET,
-				     PCIE_NSTCK_RST_CTL, EXCLUDE_FROM_RESET,
-				     PCIE_SD_RST_CTL, EXCLUDE_FROM_RESET,
-				     EE_RST_CTL, EXCLUDE_FROM_RESET,
-				     EXT_PHY_RST_DUR, 0x7 /* 10ms */,
-				     SWRST, 1);
+				     /* exclude PHY from "invisible" reset */
+				     FRF_AB_EXT_PHY_RST_CTL,
+				     method == RESET_TYPE_INVISIBLE,
+				     /* exclude EEPROM/flash and PCIe */
+				     FRF_AB_PCIE_CORE_RST_CTL, 1,
+				     FRF_AB_PCIE_NSTKY_RST_CTL, 1,
+				     FRF_AB_PCIE_SD_RST_CTL, 1,
+				     FRF_AB_EE_RST_CTL, 1,
+				     FRF_AB_EXT_PHY_RST_DUR,
+				     FFE_AB_EXT_PHY_RST_DUR_10240US,
+				     FRF_AB_SWRST, 1);
 	}
-	falcon_write(efx, &glb_ctl_reg_ker, GLB_CTL_REG_KER);
+	efx_writeo(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL);
 
 	EFX_LOG(efx, "waiting for hardware reset\n");
 	schedule_timeout_uninterruptible(HZ / 20);
 
 	/* Restore PCI configuration if needed */
 	if (method == RESET_TYPE_WORLD) {
-		if (FALCON_IS_DUAL_FUNC(efx)) {
+		if (efx_nic_is_dual_func(efx)) {
 			rc = pci_restore_state(nic_data->pci_dev2);
 			if (rc) {
 				EFX_ERR(efx, "failed to restore PCI config for "
@@ -2577,8 +1127,8 @@ int falcon_reset_hw(struct efx_nic *efx,
 	}
 
 	/* Assert that reset complete */
-	falcon_read(efx, &glb_ctl_reg_ker, GLB_CTL_REG_KER);
-	if (EFX_OWORD_FIELD(glb_ctl_reg_ker, SWRST) != 0) {
+	efx_reado(efx, &glb_ctl_reg_ker, FR_AB_GLB_CTL);
+	if (EFX_OWORD_FIELD(glb_ctl_reg_ker, FRF_AB_SWRST) != 0) {
 		rc = -ETIMEDOUT;
 		EFX_ERR(efx, "timed out waiting for hardware reset\n");
 		goto fail5;
@@ -2597,6 +1147,44 @@ fail5:
 	return rc;
 }
 
+static void falcon_monitor(struct efx_nic *efx)
+{
+	bool link_changed;
+	int rc;
+
+	BUG_ON(!mutex_is_locked(&efx->mac_lock));
+
+	rc = falcon_board(efx)->type->monitor(efx);
+	if (rc) {
+		EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
+			(rc == -ERANGE) ? "reported fault" : "failed");
+		efx->phy_mode |= PHY_MODE_LOW_POWER;
+		rc = __efx_reconfigure_port(efx);
+		WARN_ON(rc);
+	}
+
+	if (LOOPBACK_INTERNAL(efx))
+		link_changed = falcon_loopback_link_poll(efx);
+	else
+		link_changed = efx->phy_op->poll(efx);
+
+	if (link_changed) {
+		falcon_stop_nic_stats(efx);
+		falcon_deconfigure_mac_wrapper(efx);
+
+		falcon_switch_mac(efx);
+		rc = efx->mac_op->reconfigure(efx);
+		BUG_ON(rc);
+
+		falcon_start_nic_stats(efx);
+
+		efx_link_status_changed(efx);
+	}
+
+	if (EFX_IS10G(efx))
+		falcon_poll_xmac(efx);
+}
+
 /* Zeroes out the SRAM contents.  This routine must be called in
  * process context and is allowed to sleep.
  */
@@ -2606,16 +1194,16 @@ static int falcon_reset_sram(struct efx_
 	int count;
 
 	/* Set the SRAM wake/sleep GPIO appropriately. */
-	falcon_read(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER);
-	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OEN, 1);
-	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, GPIO1_OUT, 1);
-	falcon_write(efx, &gpio_cfg_reg_ker, GPIO_CTL_REG_KER);
+	efx_reado(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL);
+	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OEN, 1);
+	EFX_SET_OWORD_FIELD(gpio_cfg_reg_ker, FRF_AB_GPIO1_OUT, 1);
+	efx_writeo(efx, &gpio_cfg_reg_ker, FR_AB_GPIO_CTL);
 
 	/* Initiate SRAM reset */
 	EFX_POPULATE_OWORD_2(srm_cfg_reg_ker,
-			     SRAM_OOB_BT_INIT_EN, 1,
-			     SRM_NUM_BANKS_AND_BANK_SIZE, 0);
-	falcon_write(efx, &srm_cfg_reg_ker, SRM_CFG_REG_KER);
+			     FRF_AZ_SRM_INIT_EN, 1,
+			     FRF_AZ_SRM_NB_SZ, 0);
+	efx_writeo(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG);
 
 	/* Wait for SRAM reset to complete */
 	count = 0;
@@ -2626,8 +1214,8 @@ static int falcon_reset_sram(struct efx_
 		schedule_timeout_uninterruptible(HZ / 50);
 
 		/* Check for reset complete */
-		falcon_read(efx, &srm_cfg_reg_ker, SRM_CFG_REG_KER);
-		if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, SRAM_OOB_BT_INIT_EN)) {
+		efx_reado(efx, &srm_cfg_reg_ker, FR_AZ_SRM_CFG);
+		if (!EFX_OWORD_FIELD(srm_cfg_reg_ker, FRF_AZ_SRM_INIT_EN)) {
 			EFX_LOG(efx, "SRAM reset complete\n");
 
 			return 0;
@@ -2663,8 +1251,6 @@ static int falcon_spi_device_init(struct
 		spi_device->block_size =
 			1 << SPI_DEV_TYPE_FIELD(device_type,
 						SPI_DEV_TYPE_BLOCK_SIZE);
-
-		spi_device->efx = efx;
 	} else {
 		spi_device = NULL;
 	}
@@ -2674,7 +1260,6 @@ static int falcon_spi_device_init(struct
 	return 0;
 }
 
-
 static void falcon_remove_spi_devices(struct efx_nic *efx)
 {
 	kfree(efx->spi_eeprom);
@@ -2712,16 +1297,16 @@ static int falcon_probe_nvconfig(struct
 		board_rev = le16_to_cpu(v2->board_revision);
 
 		if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
-			__le32 fl = v3->spi_device_type[EE_SPI_FLASH];
-			__le32 ee = v3->spi_device_type[EE_SPI_EEPROM];
-			rc = falcon_spi_device_init(efx, &efx->spi_flash,
-						    EE_SPI_FLASH,
-						    le32_to_cpu(fl));
+			rc = falcon_spi_device_init(
+				efx, &efx->spi_flash, FFE_AB_SPI_DEVICE_FLASH,
+				le32_to_cpu(v3->spi_device_type
+					    [FFE_AB_SPI_DEVICE_FLASH]));
 			if (rc)
 				goto fail2;
-			rc = falcon_spi_device_init(efx, &efx->spi_eeprom,
-						    EE_SPI_EEPROM,
-						    le32_to_cpu(ee));
+			rc = falcon_spi_device_init(
+				efx, &efx->spi_eeprom, FFE_AB_SPI_DEVICE_EEPROM,
+				le32_to_cpu(v3->spi_device_type
+					    [FFE_AB_SPI_DEVICE_EEPROM]));
 			if (rc)
 				goto fail2;
 		}
@@ -2732,7 +1317,7 @@ static int falcon_probe_nvconfig(struct
 
 	EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
-	efx_set_board_info(efx, board_rev);
+	falcon_probe_board(efx, board_rev);
 
 	kfree(nvconfig);
 	return 0;
@@ -2744,89 +1329,49 @@ static int falcon_probe_nvconfig(struct
 	return rc;
 }
 
-/* Probe the NIC variant (revision, ASIC vs FPGA, function count, port
- * count, port speed).  Set workaround and feature flags accordingly.
- */
-static int falcon_probe_nic_variant(struct efx_nic *efx)
-{
-	efx_oword_t altera_build;
-	efx_oword_t nic_stat;
-
-	falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER);
-	if (EFX_OWORD_FIELD(altera_build, VER_ALL)) {
-		EFX_ERR(efx, "Falcon FPGA not supported\n");
-		return -ENODEV;
-	}
-
-	falcon_read(efx, &nic_stat, NIC_STAT_REG);
-
-	switch (falcon_rev(efx)) {
-	case FALCON_REV_A0:
-	case 0xff:
-		EFX_ERR(efx, "Falcon rev A0 not supported\n");
-		return -ENODEV;
-
-	case FALCON_REV_A1:
-		if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) {
-			EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n");
-			return -ENODEV;
-		}
-		break;
-
-	case FALCON_REV_B0:
-		break;
-
-	default:
-		EFX_ERR(efx, "Unknown Falcon rev %d\n", falcon_rev(efx));
-		return -ENODEV;
-	}
-
-	/* Initial assumed speed */
-	efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000;
-
-	return 0;
-}
-
 /* Probe all SPI devices on the NIC */
 static void falcon_probe_spi_devices(struct efx_nic *efx)
 {
 	efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg;
 	int boot_dev;
 
-	falcon_read(efx, &gpio_ctl, GPIO_CTL_REG_KER);
-	falcon_read(efx, &nic_stat, NIC_STAT_REG);
-	falcon_read(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER);
+	efx_reado(efx, &gpio_ctl, FR_AB_GPIO_CTL);
+	efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
+	efx_reado(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0);
 
-	if (EFX_OWORD_FIELD(gpio_ctl, BOOTED_USING_NVDEVICE)) {
-		boot_dev = (EFX_OWORD_FIELD(nic_stat, SF_PRST) ?
-			    EE_SPI_FLASH : EE_SPI_EEPROM);
+	if (EFX_OWORD_FIELD(gpio_ctl, FRF_AB_GPIO3_PWRUP_VALUE)) {
+		boot_dev = (EFX_OWORD_FIELD(nic_stat, FRF_AB_SF_PRST) ?
+			    FFE_AB_SPI_DEVICE_FLASH : FFE_AB_SPI_DEVICE_EEPROM);
 		EFX_LOG(efx, "Booted from %s\n",
-			boot_dev == EE_SPI_FLASH ? "flash" : "EEPROM");
+			boot_dev == FFE_AB_SPI_DEVICE_FLASH ? "flash" : "EEPROM");
 	} else {
 		/* Disable VPD and set clock dividers to safe
 		 * values for initial programming. */
 		boot_dev = -1;
 		EFX_LOG(efx, "Booted from internal ASIC settings;"
 			" setting SPI config\n");
-		EFX_POPULATE_OWORD_3(ee_vpd_cfg, EE_VPD_EN, 0,
+		EFX_POPULATE_OWORD_3(ee_vpd_cfg, FRF_AB_EE_VPD_EN, 0,
 				     /* 125 MHz / 7 ~= 20 MHz */
-				     EE_SF_CLOCK_DIV, 7,
+				     FRF_AB_EE_SF_CLOCK_DIV, 7,
 				     /* 125 MHz / 63 ~= 2 MHz */
-				     EE_EE_CLOCK_DIV, 63);
-		falcon_write(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER);
+				     FRF_AB_EE_EE_CLOCK_DIV, 63);
+		efx_writeo(efx, &ee_vpd_cfg, FR_AB_EE_VPD_CFG0);
 	}
 
-	if (boot_dev == EE_SPI_FLASH)
-		falcon_spi_device_init(efx, &efx->spi_flash, EE_SPI_FLASH,
+	if (boot_dev == FFE_AB_SPI_DEVICE_FLASH)
+		falcon_spi_device_init(efx, &efx->spi_flash,
+				       FFE_AB_SPI_DEVICE_FLASH,
 				       default_flash_type);
-	if (boot_dev == EE_SPI_EEPROM)
-		falcon_spi_device_init(efx, &efx->spi_eeprom, EE_SPI_EEPROM,
+	if (boot_dev == FFE_AB_SPI_DEVICE_EEPROM)
+		falcon_spi_device_init(efx, &efx->spi_eeprom,
+				       FFE_AB_SPI_DEVICE_EEPROM,
 				       large_eeprom_type);
 }
 
-int falcon_probe_nic(struct efx_nic *efx)
+static int falcon_probe_nic(struct efx_nic *efx)
 {
 	struct falcon_nic_data *nic_data;
+	struct falcon_board *board;
 	int rc;
 
 	/* Allocate storage for hardware specific data */
@@ -2835,15 +1380,33 @@ int falcon_probe_nic(struct efx_nic *efx
 		return -ENOMEM;
 	efx->nic_data = nic_data;
 
-	/* Determine number of ports etc. */
-	rc = falcon_probe_nic_variant(efx);
-	if (rc)
+	rc = -ENODEV;
+
+	if (efx_nic_fpga_ver(efx) != 0) {
+		EFX_ERR(efx, "Falcon FPGA not supported\n");
 		goto fail1;
+	}
 
-	/* Probe secondary function if expected */
-	if (FALCON_IS_DUAL_FUNC(efx)) {
-		struct pci_dev *dev = pci_dev_get(efx->pci_dev);
+	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) {
+		efx_oword_t nic_stat;
+		struct pci_dev *dev;
+		u8 pci_rev = efx->pci_dev->revision;
+
+		if ((pci_rev == 0xff) || (pci_rev == 0)) {
+			EFX_ERR(efx, "Falcon rev A0 not supported\n");
+			goto fail1;
+		}
+		efx_reado(efx, &nic_stat, FR_AB_NIC_STAT);
+		if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) {
+			EFX_ERR(efx, "Falcon rev A1 1G not supported\n");
+			goto fail1;
+		}
+		if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) {
+			EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n");
+			goto fail1;
+		}
 
+		dev = pci_dev_get(efx->pci_dev);
 		while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID,
 					     dev))) {
 			if (dev->bus == efx->pci_dev->bus &&
@@ -2867,7 +1430,7 @@ int falcon_probe_nic(struct efx_nic *efx
 	}
 
 	/* Allocate memory for INT_KER */
-	rc = falcon_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
+	rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
 	if (rc)
 		goto fail4;
 	BUG_ON(efx->irq_status.dma_addr & 0x0f);
@@ -2884,21 +1447,36 @@ int falcon_probe_nic(struct efx_nic *efx
 		goto fail5;
 
 	/* Initialise I2C adapter */
-	efx->i2c_adap.owner = THIS_MODULE;
-	nic_data->i2c_data = falcon_i2c_bit_operations;
-	nic_data->i2c_data.data = efx;
-	efx->i2c_adap.algo_data = &nic_data->i2c_data;
-	efx->i2c_adap.dev.parent = &efx->pci_dev->dev;
-	strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name));
-	rc = i2c_bit_add_bus(&efx->i2c_adap);
+	board = falcon_board(efx);
+	board->i2c_adap.owner = THIS_MODULE;
+	board->i2c_data = falcon_i2c_bit_operations;
+	board->i2c_data.data = efx;
+	board->i2c_adap.algo_data = &board->i2c_data;
+	board->i2c_adap.dev.parent = &efx->pci_dev->dev;
+	strlcpy(board->i2c_adap.name, "SFC4000 GPIO",
+		sizeof(board->i2c_adap.name));
+	rc = i2c_bit_add_bus(&board->i2c_adap);
 	if (rc)
 		goto fail5;
 
+	rc = falcon_board(efx)->type->init(efx);
+	if (rc) {
+		EFX_ERR(efx, "failed to initialise board\n");
+		goto fail6;
+	}
+
+	nic_data->stats_disable_count = 1;
+	setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func,
+		    (unsigned long)efx);
+
 	return 0;
 
+ fail6:
+	BUG_ON(i2c_del_adapter(&board->i2c_adap));
+	memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
  fail5:
 	falcon_remove_spi_devices(efx);
-	falcon_free_buffer(efx, &efx->irq_status);
+	efx_nic_free_buffer(efx, &efx->irq_status);
  fail4:
  fail3:
 	if (nic_data->pci_dev2) {
@@ -2911,166 +1489,147 @@ int falcon_probe_nic(struct efx_nic *efx
 	return rc;
 }
 
+static void falcon_init_rx_cfg(struct efx_nic *efx)
+{
+	/* Prior to Siena the RX DMA engine will split each frame at
+	 * intervals of RX_USR_BUF_SIZE (32-byte units). We set it to
+	 * be so large that that never happens. */
+	const unsigned huge_buf_size = (3 * 4096) >> 5;
+	/* RX control FIFO thresholds (32 entries) */
+	const unsigned ctrl_xon_thr = 20;
+	const unsigned ctrl_xoff_thr = 25;
+	/* RX data FIFO thresholds (256-byte units; size varies) */
+	int data_xon_thr = efx_nic_rx_xon_thresh >> 8;
+	int data_xoff_thr = efx_nic_rx_xoff_thresh >> 8;
+	efx_oword_t reg;
+
+	efx_reado(efx, &reg, FR_AZ_RX_CFG);
+	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) {
+		/* Data FIFO size is 5.5K */
+		if (data_xon_thr < 0)
+			data_xon_thr = 512 >> 8;
+		if (data_xoff_thr < 0)
+			data_xoff_thr = 2048 >> 8;
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_DESC_PUSH_EN, 0);
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_USR_BUF_SIZE,
+				    huge_buf_size);
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, data_xon_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, data_xoff_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_TX_TH, ctrl_xon_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_TX_TH, ctrl_xoff_thr);
+	} else {
+		/* Data FIFO size is 80K; register fields moved */
+		if (data_xon_thr < 0)
+			data_xon_thr = 27648 >> 8; /* ~3*max MTU */
+		if (data_xoff_thr < 0)
+			data_xoff_thr = 54272 >> 8; /* ~80Kb - 3*max MTU */
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_DESC_PUSH_EN, 0);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_USR_BUF_SIZE,
+				    huge_buf_size);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, data_xon_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, data_xoff_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_TX_TH, ctrl_xon_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr);
+		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1);
+	}
+	/* Always enable XOFF signal from RX FIFO.  We enable
+	 * or disable transmission of pause frames at the MAC. */
+	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
+	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
+}
+
 /* This call performs hardware-specific global initialisation, such as
  * defining the descriptor cache sizes and number of RSS channels.
  * It does not set up any buffers, descriptor rings or event queues.
  */
-int falcon_init_nic(struct efx_nic *efx)
+static int falcon_init_nic(struct efx_nic *efx)
 {
 	efx_oword_t temp;
-	unsigned thresh;
 	int rc;
 
 	/* Use on-chip SRAM */
-	falcon_read(efx, &temp, NIC_STAT_REG);
-	EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1);
-	falcon_write(efx, &temp, NIC_STAT_REG);
+	efx_reado(efx, &temp, FR_AB_NIC_STAT);
+	EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1);
+	efx_writeo(efx, &temp, FR_AB_NIC_STAT);
 
 	/* Set the source of the GMAC clock */
-	if (falcon_rev(efx) == FALCON_REV_B0) {
-		falcon_read(efx, &temp, GPIO_CTL_REG_KER);
-		EFX_SET_OWORD_FIELD(temp, GPIO_USE_NIC_CLK, true);
-		falcon_write(efx, &temp, GPIO_CTL_REG_KER);
+	if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
+		efx_reado(efx, &temp, FR_AB_GPIO_CTL);
+		EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true);
+		efx_writeo(efx, &temp, FR_AB_GPIO_CTL);
 	}
 
-	/* Set buffer table mode */
-	EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL);
-	falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER);
+	/* Select the correct MAC */
+	falcon_clock_mac(efx);
 
 	rc = falcon_reset_sram(efx);
 	if (rc)
 		return rc;
 
-	/* Set positions of descriptor caches in SRAM. */
-	EFX_POPULATE_OWORD_1(temp, SRM_TX_DC_BASE_ADR, TX_DC_BASE / 8);
-	falcon_write(efx, &temp, SRM_TX_DC_CFG_REG_KER);
-	EFX_POPULATE_OWORD_1(temp, SRM_RX_DC_BASE_ADR, RX_DC_BASE / 8);
-	falcon_write(efx, &temp, SRM_RX_DC_CFG_REG_KER);
-
-	/* Set TX descriptor cache size. */
-	BUILD_BUG_ON(TX_DC_ENTRIES != (16 << TX_DC_ENTRIES_ORDER));
-	EFX_POPULATE_OWORD_1(temp, TX_DC_SIZE, TX_DC_ENTRIES_ORDER);
-	falcon_write(efx, &temp, TX_DC_CFG_REG_KER);
-
-	/* Set RX descriptor cache size.  Set low watermark to size-8, as
-	 * this allows most efficient prefetching.
-	 */
-	BUILD_BUG_ON(RX_DC_ENTRIES != (16 << RX_DC_ENTRIES_ORDER));
-	EFX_POPULATE_OWORD_1(temp, RX_DC_SIZE, RX_DC_ENTRIES_ORDER);
-	falcon_write(efx, &temp, RX_DC_CFG_REG_KER);
-	EFX_POPULATE_OWORD_1(temp, RX_DC_PF_LWM, RX_DC_ENTRIES - 8);
-	falcon_write(efx, &temp, RX_DC_PF_WM_REG_KER);
-
 	/* Clear the parity enables on the TX data fifos as
 	 * they produce false parity errors because of timing issues
 	 */
 	if (EFX_WORKAROUND_5129(efx)) {
-		falcon_read(efx, &temp, SPARE_REG_KER);
-		EFX_SET_OWORD_FIELD(temp, MEM_PERR_EN_TX_DATA, 0);
-		falcon_write(efx, &temp, SPARE_REG_KER);
+		efx_reado(efx, &temp, FR_AZ_CSR_SPARE);
+		EFX_SET_OWORD_FIELD(temp, FRF_AB_MEM_PERR_EN_TX_DATA, 0);
+		efx_writeo(efx, &temp, FR_AZ_CSR_SPARE);
 	}
 
-	/* Enable all the genuinely fatal interrupts.  (They are still
-	 * masked by the overall interrupt mask, controlled by
-	 * falcon_interrupts()).
-	 *
-	 * Note: All other fatal interrupts are enabled
-	 */
-	EFX_POPULATE_OWORD_3(temp,
-			     ILL_ADR_INT_KER_EN, 1,
-			     RBUF_OWN_INT_KER_EN, 1,
-			     TBUF_OWN_INT_KER_EN, 1);
-	EFX_INVERT_OWORD(temp);
-	falcon_write(efx, &temp, FATAL_INTR_REG_KER);
-
 	if (EFX_WORKAROUND_7244(efx)) {
-		falcon_read(efx, &temp, RX_FILTER_CTL_REG);
-		EFX_SET_OWORD_FIELD(temp, UDP_FULL_SRCH_LIMIT, 8);
-		EFX_SET_OWORD_FIELD(temp, UDP_WILD_SRCH_LIMIT, 8);
-		EFX_SET_OWORD_FIELD(temp, TCP_FULL_SRCH_LIMIT, 8);
-		EFX_SET_OWORD_FIELD(temp, TCP_WILD_SRCH_LIMIT, 8);
-		falcon_write(efx, &temp, RX_FILTER_CTL_REG);
+		efx_reado(efx, &temp, FR_BZ_RX_FILTER_CTL);
+		EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_FULL_SRCH_LIMIT, 8);
+		EFX_SET_OWORD_FIELD(temp, FRF_BZ_UDP_WILD_SRCH_LIMIT, 8);
+		EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_FULL_SRCH_LIMIT, 8);
+		EFX_SET_OWORD_FIELD(temp, FRF_BZ_TCP_WILD_SRCH_LIMIT, 8);
+		efx_writeo(efx, &temp, FR_BZ_RX_FILTER_CTL);
 	}
 
-	falcon_setup_rss_indir_table(efx);
-
+	/* XXX This is documented only for Falcon A0/A1 */
 	/* Setup RX.  Wait for descriptor is broken and must
 	 * be disabled.  RXDP recovery shouldn't be needed, but is.
 	 */
-	falcon_read(efx, &temp, RX_SELF_RST_REG_KER);
-	EFX_SET_OWORD_FIELD(temp, RX_NODESC_WAIT_DIS, 1);
-	EFX_SET_OWORD_FIELD(temp, RX_RECOVERY_EN, 1);
+	efx_reado(efx, &temp, FR_AA_RX_SELF_RST);
+	EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_NODESC_WAIT_DIS, 1);
+	EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_SELF_RST_EN, 1);
 	if (EFX_WORKAROUND_5583(efx))
-		EFX_SET_OWORD_FIELD(temp, RX_ISCSI_DIS, 1);
-	falcon_write(efx, &temp, RX_SELF_RST_REG_KER);
-
-	/* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be
-	 * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q.
-	 */
-	falcon_read(efx, &temp, TX_CFG2_REG_KER);
-	EFX_SET_OWORD_FIELD(temp, TX_RX_SPACER, 0xfe);
-	EFX_SET_OWORD_FIELD(temp, TX_RX_SPACER_EN, 1);
-	EFX_SET_OWORD_FIELD(temp, TX_ONE_PKT_PER_Q, 1);
-	EFX_SET_OWORD_FIELD(temp, TX_CSR_PUSH_EN, 0);
-	EFX_SET_OWORD_FIELD(temp, TX_DIS_NON_IP_EV, 1);
-	/* Enable SW_EV to inherit in char driver - assume harmless here */
-	EFX_SET_OWORD_FIELD(temp, TX_SW_EV_EN, 1);
-	/* Prefetch threshold 2 => fetch when descriptor cache half empty */
-	EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2);
-	/* Squash TX of packets of 16 bytes or less */
-	if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx))
-		EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1);
-	falcon_write(efx, &temp, TX_CFG2_REG_KER);
+		EFX_SET_OWORD_FIELD(temp, FRF_AA_RX_ISCSI_DIS, 1);
+	efx_writeo(efx, &temp, FR_AA_RX_SELF_RST);
 
 	/* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16
 	 * descriptors (which is bad).
 	 */
-	falcon_read(efx, &temp, TX_CFG_REG_KER);
-	EFX_SET_OWORD_FIELD(temp, TX_NO_EOP_DISC_EN, 0);
-	falcon_write(efx, &temp, TX_CFG_REG_KER);
-
-	/* RX config */
-	falcon_read(efx, &temp, RX_CFG_REG_KER);
-	EFX_SET_OWORD_FIELD_VER(efx, temp, RX_DESC_PUSH_EN, 0);
-	if (EFX_WORKAROUND_7575(efx))
-		EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE,
-					(3 * 4096) / 32);
-	if (falcon_rev(efx) >= FALCON_REV_B0)
-		EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1);
+	efx_reado(efx, &temp, FR_AZ_TX_CFG);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
+	efx_writeo(efx, &temp, FR_AZ_TX_CFG);
 
-	/* RX FIFO flow control thresholds */
-	thresh = ((rx_xon_thresh_bytes >= 0) ?
-		  rx_xon_thresh_bytes : efx->type->rx_xon_thresh);
-	EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_MAC_TH, thresh / 256);
-	thresh = ((rx_xoff_thresh_bytes >= 0) ?
-		  rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh);
-	EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_MAC_TH, thresh / 256);
-	/* RX control FIFO thresholds [32 entries] */
-	EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 20);
-	EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 25);
-	falcon_write(efx, &temp, RX_CFG_REG_KER);
+	falcon_init_rx_cfg(efx);
 
 	/* Set destination of both TX and RX Flush events */
-	if (falcon_rev(efx) >= FALCON_REV_B0) {
-		EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0);
-		falcon_write(efx, &temp, DP_CTRL_REG);
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+		EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0);
+		efx_writeo(efx, &temp, FR_BZ_DP_CTRL);
 	}
 
+	efx_nic_init_common(efx);
+
 	return 0;
 }
 
-void falcon_remove_nic(struct efx_nic *efx)
+static void falcon_remove_nic(struct efx_nic *efx)
 {
 	struct falcon_nic_data *nic_data = efx->nic_data;
+	struct falcon_board *board = falcon_board(efx);
 	int rc;
 
+	board->type->fini(efx);
+
 	/* Remove I2C adapter and clear it in preparation for a retry */
-	rc = i2c_del_adapter(&efx->i2c_adap);
+	rc = i2c_del_adapter(&board->i2c_adap);
 	BUG_ON(rc);
-	memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
+	memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
 
 	falcon_remove_spi_devices(efx);
-	falcon_free_buffer(efx, &efx->irq_status);
+	efx_nic_free_buffer(efx, &efx->irq_status);
 
 	falcon_reset_hw(efx, RESET_TYPE_ALL);
 
@@ -3085,12 +1644,86 @@ void falcon_remove_nic(struct efx_nic *e
 	efx->nic_data = NULL;
 }
 
-void falcon_update_nic_stats(struct efx_nic *efx)
+static void falcon_update_nic_stats(struct efx_nic *efx)
 {
+	struct falcon_nic_data *nic_data = efx->nic_data;
 	efx_oword_t cnt;
 
-	falcon_read(efx, &cnt, RX_NODESC_DROP_REG_KER);
-	efx->n_rx_nodesc_drop_cnt += EFX_OWORD_FIELD(cnt, RX_NODESC_DROP_CNT);
+	if (nic_data->stats_disable_count)
+		return;
+
+	efx_reado(efx, &cnt, FR_AZ_RX_NODESC_DROP);
+	efx->n_rx_nodesc_drop_cnt +=
+		EFX_OWORD_FIELD(cnt, FRF_AB_RX_NODESC_DROP_CNT);
+
+	if (nic_data->stats_pending &&
+	    *nic_data->stats_dma_done == FALCON_STATS_DONE) {
+		nic_data->stats_pending = false;
+		rmb(); /* read the done flag before the stats */
+		efx->mac_op->update_stats(efx);
+	}
+}
+
+void falcon_start_nic_stats(struct efx_nic *efx)
+{
+	struct falcon_nic_data *nic_data = efx->nic_data;
+
+	spin_lock_bh(&efx->stats_lock);
+	if (--nic_data->stats_disable_count == 0)
+		falcon_stats_request(efx);
+	spin_unlock_bh(&efx->stats_lock);
+}
+
+void falcon_stop_nic_stats(struct efx_nic *efx)
+{
+	struct falcon_nic_data *nic_data = efx->nic_data;
+	int i;
+
+	might_sleep();
+
+	spin_lock_bh(&efx->stats_lock);
+	++nic_data->stats_disable_count;
+	spin_unlock_bh(&efx->stats_lock);
+
+	del_timer_sync(&nic_data->stats_timer);
+
+	/* Wait enough time for the most recent transfer to
+	 * complete. */
+	for (i = 0; i < 4 && nic_data->stats_pending; i++) {
+		if (*nic_data->stats_dma_done == FALCON_STATS_DONE)
+			break;
+		msleep(1);
+	}
+
+	spin_lock_bh(&efx->stats_lock);
+	falcon_stats_complete(efx);
+	spin_unlock_bh(&efx->stats_lock);
+}
+
+static void falcon_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+	falcon_board(efx)->type->set_id_led(efx, mode);
+}
+
+/**************************************************************************
+ *
+ * Wake on LAN
+ *
+ **************************************************************************
+ */
+
+static void falcon_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol)
+{
+	wol->supported = 0;
+	wol->wolopts = 0;
+	memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int falcon_set_wol(struct efx_nic *efx, u32 type)
+{
+	if (type != 0)
+		return -EINVAL;
+	return 0;
 }
 
 /**************************************************************************
@@ -3100,50 +1733,91 @@ void falcon_update_nic_stats(struct efx_
  **************************************************************************
  */
 
-struct efx_nic_type falcon_a_nic_type = {
-	.mem_bar = 2,
+struct efx_nic_type falcon_a1_nic_type = {
+	.probe = falcon_probe_nic,
+	.remove = falcon_remove_nic,
+	.init = falcon_init_nic,
+	.fini = efx_port_dummy_op_void,
+	.monitor = falcon_monitor,
+	.reset = falcon_reset_hw,
+	.probe_port = falcon_probe_port,
+	.remove_port = falcon_remove_port,
+	.prepare_flush = falcon_prepare_flush,
+	.update_stats = falcon_update_nic_stats,
+	.start_stats = falcon_start_nic_stats,
+	.stop_stats = falcon_stop_nic_stats,
+	.set_id_led = falcon_set_id_led,
+	.push_irq_moderation = falcon_push_irq_moderation,
+	.push_multicast_hash = falcon_push_multicast_hash,
+	.reconfigure_port = falcon_reconfigure_port,
+	.get_wol = falcon_get_wol,
+	.set_wol = falcon_set_wol,
+	.resume_wol = efx_port_dummy_op_void,
+	.test_nvram = falcon_test_nvram,
+	.default_mac_ops = &falcon_xmac_operations,
+
+	.revision = EFX_REV_FALCON_A1,
 	.mem_map_size = 0x20000,
-	.txd_ptr_tbl_base = TX_DESC_PTR_TBL_KER_A1,
-	.rxd_ptr_tbl_base = RX_DESC_PTR_TBL_KER_A1,
-	.buf_tbl_base = BUF_TBL_KER_A1,
-	.evq_ptr_tbl_base = EVQ_PTR_TBL_KER_A1,
-	.evq_rptr_tbl_base = EVQ_RPTR_REG_KER_A1,
-	.txd_ring_mask = FALCON_TXD_RING_MASK,
-	.rxd_ring_mask = FALCON_RXD_RING_MASK,
-	.evq_size = FALCON_EVQ_SIZE,
-	.max_dma_mask = FALCON_DMA_MASK,
-	.tx_dma_mask = FALCON_TX_DMA_MASK,
-	.bug5391_mask = 0xf,
-	.rx_xoff_thresh = 2048,
-	.rx_xon_thresh = 512,
+	.txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER,
+	.rxd_ptr_tbl_base = FR_AA_RX_DESC_PTR_TBL_KER,
+	.buf_tbl_base = FR_AA_BUF_FULL_TBL_KER,
+	.evq_ptr_tbl_base = FR_AA_EVQ_PTR_TBL_KER,
+	.evq_rptr_tbl_base = FR_AA_EVQ_RPTR_KER,
+	.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
 	.rx_buffer_padding = 0x24,
 	.max_interrupt_mode = EFX_INT_MODE_MSI,
 	.phys_addr_channels = 4,
+	.tx_dc_base = 0x130000,
+	.rx_dc_base = 0x100000,
+	.offload_features = NETIF_F_IP_CSUM,
+	.reset_world_flags = ETH_RESET_IRQ,
 };
 
-struct efx_nic_type falcon_b_nic_type = {
-	.mem_bar = 2,
+struct efx_nic_type falcon_b0_nic_type = {
+	.probe = falcon_probe_nic,
+	.remove = falcon_remove_nic,
+	.init = falcon_init_nic,
+	.fini = efx_port_dummy_op_void,
+	.monitor = falcon_monitor,
+	.reset = falcon_reset_hw,
+	.probe_port = falcon_probe_port,
+	.remove_port = falcon_remove_port,
+	.prepare_flush = falcon_prepare_flush,
+	.update_stats = falcon_update_nic_stats,
+	.start_stats = falcon_start_nic_stats,
+	.stop_stats = falcon_stop_nic_stats,
+	.set_id_led = falcon_set_id_led,
+	.push_irq_moderation = falcon_push_irq_moderation,
+	.push_multicast_hash = falcon_push_multicast_hash,
+	.reconfigure_port = falcon_reconfigure_port,
+	.get_wol = falcon_get_wol,
+	.set_wol = falcon_set_wol,
+	.resume_wol = efx_port_dummy_op_void,
+	.test_registers = falcon_b0_test_registers,
+	.test_nvram = falcon_test_nvram,
+	.default_mac_ops = &falcon_xmac_operations,
+
+	.revision = EFX_REV_FALCON_B0,
 	/* Map everything up to and including the RSS indirection
 	 * table.  Don't map MSI-X table, MSI-X PBA since Linux
 	 * requires that they not be mapped.  */
-	.mem_map_size = RX_RSS_INDIR_TBL_B0 + 0x800,
-	.txd_ptr_tbl_base = TX_DESC_PTR_TBL_KER_B0,
-	.rxd_ptr_tbl_base = RX_DESC_PTR_TBL_KER_B0,
-	.buf_tbl_base = BUF_TBL_KER_B0,
-	.evq_ptr_tbl_base = EVQ_PTR_TBL_KER_B0,
-	.evq_rptr_tbl_base = EVQ_RPTR_REG_KER_B0,
-	.txd_ring_mask = FALCON_TXD_RING_MASK,
-	.rxd_ring_mask = FALCON_RXD_RING_MASK,
-	.evq_size = FALCON_EVQ_SIZE,
-	.max_dma_mask = FALCON_DMA_MASK,
-	.tx_dma_mask = FALCON_TX_DMA_MASK,
-	.bug5391_mask = 0,
-	.rx_xoff_thresh = 54272, /* ~80Kb - 3*max MTU */
-	.rx_xon_thresh = 27648,  /* ~3*max MTU */
+	.mem_map_size = (FR_BZ_RX_INDIRECTION_TBL +
+			 FR_BZ_RX_INDIRECTION_TBL_STEP *
+			 FR_BZ_RX_INDIRECTION_TBL_ROWS),
+	.txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
+	.rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL,
+	.buf_tbl_base = FR_BZ_BUF_FULL_TBL,
+	.evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL,
+	.evq_rptr_tbl_base = FR_BZ_EVQ_RPTR,
+	.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
 	.rx_buffer_padding = 0,
 	.max_interrupt_mode = EFX_INT_MODE_MSIX,
 	.phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
 				   * interrupt handler only supports 32
 				   * channels */
+	.tx_dc_base = 0x130000,
+	.rx_dc_base = 0x100000,
+	.offload_features = NETIF_F_IP_CSUM,
+	.reset_world_flags = ETH_RESET_IRQ,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_gmac.c linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_gmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_gmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_gmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -11,11 +11,10 @@
 #include <linux/delay.h>
 #include "net_driver.h"
 #include "efx.h"
-#include "falcon.h"
+#include "nic.h"
 #include "mac.h"
-#include "falcon_hwdefs.h"
-#include "falcon_io.h"
-#include "gmii.h"
+#include "regs.h"
+#include "io.h"
 
 /**************************************************************************
  *
@@ -23,106 +22,109 @@
  *
  *************************************************************************/
 
-static void falcon_reconfigure_gmac(struct efx_nic *efx)
+static int falcon_reconfigure_gmac(struct efx_nic *efx)
 {
+	struct efx_link_state *link_state = &efx->link_state;
 	bool loopback, tx_fc, rx_fc, bytemode;
 	int if_mode;
 	unsigned int max_frame_len;
 	efx_oword_t reg;
 
 	/* Configuration register 1 */
-	tx_fc = (efx->link_fc & EFX_FC_TX) || !efx->link_fd;
-	rx_fc = !!(efx->link_fc & EFX_FC_RX);
+	tx_fc = (link_state->fc & EFX_FC_TX) || !link_state->fd;
+	rx_fc = !!(link_state->fc & EFX_FC_RX);
 	loopback = (efx->loopback_mode == LOOPBACK_GMAC);
-	bytemode = (efx->link_speed == 1000);
+	bytemode = (link_state->speed == 1000);
 
 	EFX_POPULATE_OWORD_5(reg,
-			     GM_LOOP, loopback,
-			     GM_TX_EN, 1,
-			     GM_TX_FC_EN, tx_fc,
-			     GM_RX_EN, 1,
-			     GM_RX_FC_EN, rx_fc);
-	falcon_write(efx, &reg, GM_CFG1_REG);
+			     FRF_AB_GM_LOOP, loopback,
+			     FRF_AB_GM_TX_EN, 1,
+			     FRF_AB_GM_TX_FC_EN, tx_fc,
+			     FRF_AB_GM_RX_EN, 1,
+			     FRF_AB_GM_RX_FC_EN, rx_fc);
+	efx_writeo(efx, &reg, FR_AB_GM_CFG1);
 	udelay(10);
 
 	/* Configuration register 2 */
 	if_mode = (bytemode) ? 2 : 1;
 	EFX_POPULATE_OWORD_5(reg,
-			     GM_IF_MODE, if_mode,
-			     GM_PAD_CRC_EN, 1,
-			     GM_LEN_CHK, 1,
-			     GM_FD, efx->link_fd,
-			     GM_PAMBL_LEN, 0x7/*datasheet recommended */);
+			     FRF_AB_GM_IF_MODE, if_mode,
+			     FRF_AB_GM_PAD_CRC_EN, 1,
+			     FRF_AB_GM_LEN_CHK, 1,
+			     FRF_AB_GM_FD, link_state->fd,
+			     FRF_AB_GM_PAMBL_LEN, 0x7/*datasheet recommended */);
 
-	falcon_write(efx, &reg, GM_CFG2_REG);
+	efx_writeo(efx, &reg, FR_AB_GM_CFG2);
 	udelay(10);
 
 	/* Max frame len register */
 	max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
-	EFX_POPULATE_OWORD_1(reg, GM_MAX_FLEN, max_frame_len);
-	falcon_write(efx, &reg, GM_MAX_FLEN_REG);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_MAX_FLEN, max_frame_len);
+	efx_writeo(efx, &reg, FR_AB_GM_MAX_FLEN);
 	udelay(10);
 
 	/* FIFO configuration register 0 */
 	EFX_POPULATE_OWORD_5(reg,
-			     GMF_FTFENREQ, 1,
-			     GMF_STFENREQ, 1,
-			     GMF_FRFENREQ, 1,
-			     GMF_SRFENREQ, 1,
-			     GMF_WTMENREQ, 1);
-	falcon_write(efx, &reg, GMF_CFG0_REG);
+			     FRF_AB_GMF_FTFENREQ, 1,
+			     FRF_AB_GMF_STFENREQ, 1,
+			     FRF_AB_GMF_FRFENREQ, 1,
+			     FRF_AB_GMF_SRFENREQ, 1,
+			     FRF_AB_GMF_WTMENREQ, 1);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG0);
 	udelay(10);
 
 	/* FIFO configuration register 1 */
 	EFX_POPULATE_OWORD_2(reg,
-			     GMF_CFGFRTH, 0x12,
-			     GMF_CFGXOFFRTX, 0xffff);
-	falcon_write(efx, &reg, GMF_CFG1_REG);
+			     FRF_AB_GMF_CFGFRTH, 0x12,
+			     FRF_AB_GMF_CFGXOFFRTX, 0xffff);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG1);
 	udelay(10);
 
 	/* FIFO configuration register 2 */
 	EFX_POPULATE_OWORD_2(reg,
-			     GMF_CFGHWM, 0x3f,
-			     GMF_CFGLWM, 0xa);
-	falcon_write(efx, &reg, GMF_CFG2_REG);
+			     FRF_AB_GMF_CFGHWM, 0x3f,
+			     FRF_AB_GMF_CFGLWM, 0xa);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG2);
 	udelay(10);
 
 	/* FIFO configuration register 3 */
 	EFX_POPULATE_OWORD_2(reg,
-			     GMF_CFGHWMFT, 0x1c,
-			     GMF_CFGFTTH, 0x08);
-	falcon_write(efx, &reg, GMF_CFG3_REG);
+			     FRF_AB_GMF_CFGHWMFT, 0x1c,
+			     FRF_AB_GMF_CFGFTTH, 0x08);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG3);
 	udelay(10);
 
 	/* FIFO configuration register 4 */
-	EFX_POPULATE_OWORD_1(reg, GMF_HSTFLTRFRM_PAUSE, 1);
-	falcon_write(efx, &reg, GMF_CFG4_REG);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_GMF_HSTFLTRFRM_PAUSE, 1);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG4);
 	udelay(10);
 
 	/* FIFO configuration register 5 */
-	falcon_read(efx, &reg, GMF_CFG5_REG);
-	EFX_SET_OWORD_FIELD(reg, GMF_CFGBYTMODE, bytemode);
-	EFX_SET_OWORD_FIELD(reg, GMF_CFGHDPLX, !efx->link_fd);
-	EFX_SET_OWORD_FIELD(reg, GMF_HSTDRPLT64, !efx->link_fd);
-	EFX_SET_OWORD_FIELD(reg, GMF_HSTFLTRFRMDC_PAUSE, 0);
-	falcon_write(efx, &reg, GMF_CFG5_REG);
+	efx_reado(efx, &reg, FR_AB_GMF_CFG5);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGBYTMODE, bytemode);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !link_state->fd);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !link_state->fd);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE, 0);
+	efx_writeo(efx, &reg, FR_AB_GMF_CFG5);
 	udelay(10);
 
 	/* MAC address */
 	EFX_POPULATE_OWORD_4(reg,
-			     GM_HWADDR_5, efx->net_dev->dev_addr[5],
-			     GM_HWADDR_4, efx->net_dev->dev_addr[4],
-			     GM_HWADDR_3, efx->net_dev->dev_addr[3],
-			     GM_HWADDR_2, efx->net_dev->dev_addr[2]);
-	falcon_write(efx, &reg, GM_ADR1_REG);
+			     FRF_AB_GM_ADR_B0, efx->net_dev->dev_addr[5],
+			     FRF_AB_GM_ADR_B1, efx->net_dev->dev_addr[4],
+			     FRF_AB_GM_ADR_B2, efx->net_dev->dev_addr[3],
+			     FRF_AB_GM_ADR_B3, efx->net_dev->dev_addr[2]);
+	efx_writeo(efx, &reg, FR_AB_GM_ADR1);
 	udelay(10);
 	EFX_POPULATE_OWORD_2(reg,
-			     GM_HWADDR_1, efx->net_dev->dev_addr[1],
-			     GM_HWADDR_0, efx->net_dev->dev_addr[0]);
-	falcon_write(efx, &reg, GM_ADR2_REG);
+			     FRF_AB_GM_ADR_B4, efx->net_dev->dev_addr[1],
+			     FRF_AB_GM_ADR_B5, efx->net_dev->dev_addr[0]);
+	efx_writeo(efx, &reg, FR_AB_GM_ADR2);
 	udelay(10);
 
 	falcon_reconfigure_mac_wrapper(efx);
+
+	return 0;
 }
 
 static void falcon_update_stats_gmac(struct efx_nic *efx)
@@ -130,11 +132,6 @@ static void falcon_update_stats_gmac(str
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
 	unsigned long old_rx_pause, old_tx_pause;
 	unsigned long new_rx_pause, new_tx_pause;
-	int rc;
-
-	rc = falcon_dma_stats(efx, GDmaDone_offset);
-	if (rc)
-		return;
 
 	/* Pause frames are erroneously counted as errors (SFC bug 3269) */
 	old_rx_pause = mac_stats->rx_pause;
@@ -221,9 +218,13 @@ static void falcon_update_stats_gmac(str
 	mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64;
 }
 
+static bool falcon_gmac_check_fault(struct efx_nic *efx)
+{
+	return false;
+}
+
 struct efx_mac_operations falcon_gmac_operations = {
 	.reconfigure	= falcon_reconfigure_gmac,
 	.update_stats	= falcon_update_stats_gmac,
-	.irq		= efx_port_dummy_op_void,
-	.poll		= efx_port_dummy_op_void,
+	.check_fault 	= falcon_gmac_check_fault,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon.h linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_FALCON_H
-#define EFX_FALCON_H
-
-#include "net_driver.h"
-#include "efx.h"
-
-/*
- * Falcon hardware control
- */
-
-enum falcon_revision {
-	FALCON_REV_A0 = 0,
-	FALCON_REV_A1 = 1,
-	FALCON_REV_B0 = 2,
-};
-
-static inline int falcon_rev(struct efx_nic *efx)
-{
-	return efx->pci_dev->revision;
-}
-
-extern struct efx_nic_type falcon_a_nic_type;
-extern struct efx_nic_type falcon_b_nic_type;
-
-/**************************************************************************
- *
- * Externs
- *
- **************************************************************************
- */
-
-/* TX data path */
-extern int falcon_probe_tx(struct efx_tx_queue *tx_queue);
-extern void falcon_init_tx(struct efx_tx_queue *tx_queue);
-extern void falcon_fini_tx(struct efx_tx_queue *tx_queue);
-extern void falcon_remove_tx(struct efx_tx_queue *tx_queue);
-extern void falcon_push_buffers(struct efx_tx_queue *tx_queue);
-
-/* RX data path */
-extern int falcon_probe_rx(struct efx_rx_queue *rx_queue);
-extern void falcon_init_rx(struct efx_rx_queue *rx_queue);
-extern void falcon_fini_rx(struct efx_rx_queue *rx_queue);
-extern void falcon_remove_rx(struct efx_rx_queue *rx_queue);
-extern void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue);
-
-/* Event data path */
-extern int falcon_probe_eventq(struct efx_channel *channel);
-extern void falcon_init_eventq(struct efx_channel *channel);
-extern void falcon_fini_eventq(struct efx_channel *channel);
-extern void falcon_remove_eventq(struct efx_channel *channel);
-extern int falcon_process_eventq(struct efx_channel *channel, int rx_quota);
-extern void falcon_eventq_read_ack(struct efx_channel *channel);
-
-/* Ports */
-extern int falcon_probe_port(struct efx_nic *efx);
-extern void falcon_remove_port(struct efx_nic *efx);
-
-/* MAC/PHY */
-extern int falcon_switch_mac(struct efx_nic *efx);
-extern bool falcon_xaui_link_ok(struct efx_nic *efx);
-extern int falcon_dma_stats(struct efx_nic *efx,
-			    unsigned int done_offset);
-extern void falcon_drain_tx_fifo(struct efx_nic *efx);
-extern void falcon_deconfigure_mac_wrapper(struct efx_nic *efx);
-extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
-
-/* Interrupts and test events */
-extern int falcon_init_interrupt(struct efx_nic *efx);
-extern void falcon_enable_interrupts(struct efx_nic *efx);
-extern void falcon_generate_test_event(struct efx_channel *channel,
-				       unsigned int magic);
-extern void falcon_sim_phy_event(struct efx_nic *efx);
-extern void falcon_generate_interrupt(struct efx_nic *efx);
-extern void falcon_set_int_moderation(struct efx_channel *channel);
-extern void falcon_disable_interrupts(struct efx_nic *efx);
-extern void falcon_fini_interrupt(struct efx_nic *efx);
-
-#define FALCON_IRQ_MOD_RESOLUTION 5
-
-/* Global Resources */
-extern int falcon_probe_nic(struct efx_nic *efx);
-extern int falcon_probe_resources(struct efx_nic *efx);
-extern int falcon_init_nic(struct efx_nic *efx);
-extern int falcon_flush_queues(struct efx_nic *efx);
-extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
-extern void falcon_remove_resources(struct efx_nic *efx);
-extern void falcon_remove_nic(struct efx_nic *efx);
-extern void falcon_update_nic_stats(struct efx_nic *efx);
-extern void falcon_set_multicast_hash(struct efx_nic *efx);
-extern int falcon_reset_xaui(struct efx_nic *efx);
-
-/* Tests */
-struct falcon_nvconfig;
-extern int falcon_read_nvram(struct efx_nic *efx,
-			     struct falcon_nvconfig *nvconfig);
-extern int falcon_test_registers(struct efx_nic *efx);
-
-/**************************************************************************
- *
- * Falcon MAC stats
- *
- **************************************************************************
- */
-
-#define FALCON_STAT_OFFSET(falcon_stat) EFX_VAL(falcon_stat, offset)
-#define FALCON_STAT_WIDTH(falcon_stat) EFX_VAL(falcon_stat, WIDTH)
-
-/* Retrieve statistic from statistics block */
-#define FALCON_STAT(efx, falcon_stat, efx_stat) do {		\
-	if (FALCON_STAT_WIDTH(falcon_stat) == 16)		\
-		(efx)->mac_stats.efx_stat += le16_to_cpu(	\
-			*((__force __le16 *)				\
-			  (efx->stats_buffer.addr +		\
-			   FALCON_STAT_OFFSET(falcon_stat))));	\
-	else if (FALCON_STAT_WIDTH(falcon_stat) == 32)		\
-		(efx)->mac_stats.efx_stat += le32_to_cpu(	\
-			*((__force __le32 *)				\
-			  (efx->stats_buffer.addr +		\
-			   FALCON_STAT_OFFSET(falcon_stat))));	\
-	else							\
-		(efx)->mac_stats.efx_stat += le64_to_cpu(	\
-			*((__force __le64 *)				\
-			  (efx->stats_buffer.addr +		\
-			   FALCON_STAT_OFFSET(falcon_stat))));	\
-	} while (0)
-
-#define FALCON_MAC_STATS_SIZE 0x100
-
-#define MAC_DATA_LBN 0
-#define MAC_DATA_WIDTH 32
-
-extern void falcon_generate_event(struct efx_channel *channel,
-				  efx_qword_t *event);
-
-#endif /* EFX_FALCON_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_hwdefs.h linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_hwdefs.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_hwdefs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_hwdefs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1333 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_FALCON_HWDEFS_H
-#define EFX_FALCON_HWDEFS_H
-
-/*
- * Falcon hardware value definitions.
- * Falcon is the internal codename for the SFC4000 controller that is
- * present in SFE400X evaluation boards
- */
-
-/**************************************************************************
- *
- * Falcon registers
- *
- **************************************************************************
- */
-
-/* Address region register */
-#define ADR_REGION_REG_KER	0x00
-#define ADR_REGION0_LBN	0
-#define ADR_REGION0_WIDTH	18
-#define ADR_REGION1_LBN	32
-#define ADR_REGION1_WIDTH	18
-#define ADR_REGION2_LBN	64
-#define ADR_REGION2_WIDTH	18
-#define ADR_REGION3_LBN	96
-#define ADR_REGION3_WIDTH	18
-
-/* Interrupt enable register */
-#define INT_EN_REG_KER 0x0010
-#define KER_INT_KER_LBN 3
-#define KER_INT_KER_WIDTH 1
-#define DRV_INT_EN_KER_LBN 0
-#define DRV_INT_EN_KER_WIDTH 1
-
-/* Interrupt status address register */
-#define INT_ADR_REG_KER	0x0030
-#define NORM_INT_VEC_DIS_KER_LBN 64
-#define NORM_INT_VEC_DIS_KER_WIDTH 1
-#define INT_ADR_KER_LBN 0
-#define INT_ADR_KER_WIDTH EFX_DMA_TYPE_WIDTH(64) /* not 46 for this one */
-
-/* Interrupt status register (B0 only) */
-#define INT_ISR0_B0 0x90
-#define INT_ISR1_B0 0xA0
-
-/* Interrupt acknowledge register (A0/A1 only) */
-#define INT_ACK_REG_KER_A1 0x0050
-#define INT_ACK_DUMMY_DATA_LBN 0
-#define INT_ACK_DUMMY_DATA_WIDTH 32
-
-/* Interrupt acknowledge work-around register (A0/A1 only )*/
-#define WORK_AROUND_BROKEN_PCI_READS_REG_KER_A1 0x0070
-
-/* SPI host command register */
-#define EE_SPI_HCMD_REG_KER 0x0100
-#define EE_SPI_HCMD_CMD_EN_LBN 31
-#define EE_SPI_HCMD_CMD_EN_WIDTH 1
-#define EE_WR_TIMER_ACTIVE_LBN 28
-#define EE_WR_TIMER_ACTIVE_WIDTH 1
-#define EE_SPI_HCMD_SF_SEL_LBN 24
-#define EE_SPI_HCMD_SF_SEL_WIDTH 1
-#define EE_SPI_EEPROM 0
-#define EE_SPI_FLASH 1
-#define EE_SPI_HCMD_DABCNT_LBN 16
-#define EE_SPI_HCMD_DABCNT_WIDTH 5
-#define EE_SPI_HCMD_READ_LBN 15
-#define EE_SPI_HCMD_READ_WIDTH 1
-#define EE_SPI_READ 1
-#define EE_SPI_WRITE 0
-#define EE_SPI_HCMD_DUBCNT_LBN 12
-#define EE_SPI_HCMD_DUBCNT_WIDTH 2
-#define EE_SPI_HCMD_ADBCNT_LBN 8
-#define EE_SPI_HCMD_ADBCNT_WIDTH 2
-#define EE_SPI_HCMD_ENC_LBN 0
-#define EE_SPI_HCMD_ENC_WIDTH 8
-
-/* SPI host address register */
-#define EE_SPI_HADR_REG_KER 0x0110
-#define EE_SPI_HADR_ADR_LBN 0
-#define EE_SPI_HADR_ADR_WIDTH 24
-
-/* SPI host data register */
-#define EE_SPI_HDATA_REG_KER 0x0120
-
-/* SPI/VPD config register */
-#define EE_VPD_CFG_REG_KER 0x0140
-#define EE_VPD_EN_LBN 0
-#define EE_VPD_EN_WIDTH 1
-#define EE_VPD_EN_AD9_MODE_LBN 1
-#define EE_VPD_EN_AD9_MODE_WIDTH 1
-#define EE_EE_CLOCK_DIV_LBN 112
-#define EE_EE_CLOCK_DIV_WIDTH 7
-#define EE_SF_CLOCK_DIV_LBN 120
-#define EE_SF_CLOCK_DIV_WIDTH 7
-
-/* PCIE CORE ACCESS REG */
-#define PCIE_CORE_ADDR_PCIE_DEVICE_CTRL_STAT 0x68
-#define PCIE_CORE_ADDR_PCIE_LINK_CTRL_STAT 0x70
-#define PCIE_CORE_ADDR_ACK_RPL_TIMER 0x700
-#define PCIE_CORE_ADDR_ACK_FREQ 0x70C
-
-/* NIC status register */
-#define NIC_STAT_REG 0x0200
-#define EE_STRAP_EN_LBN 31
-#define EE_STRAP_EN_WIDTH 1
-#define EE_STRAP_OVR_LBN 24
-#define EE_STRAP_OVR_WIDTH 4
-#define ONCHIP_SRAM_LBN 16
-#define ONCHIP_SRAM_WIDTH 1
-#define SF_PRST_LBN 9
-#define SF_PRST_WIDTH 1
-#define EE_PRST_LBN 8
-#define EE_PRST_WIDTH 1
-#define STRAP_PINS_LBN 0
-#define STRAP_PINS_WIDTH 3
-/* These bit definitions are extrapolated from the list of numerical
- * values for STRAP_PINS.
- */
-#define STRAP_10G_LBN 2
-#define STRAP_10G_WIDTH 1
-#define STRAP_PCIE_LBN 0
-#define STRAP_PCIE_WIDTH 1
-
-#define BOOTED_USING_NVDEVICE_LBN 3
-#define BOOTED_USING_NVDEVICE_WIDTH 1
-
-/* GPIO control register */
-#define GPIO_CTL_REG_KER 0x0210
-#define GPIO_USE_NIC_CLK_LBN (30)
-#define GPIO_USE_NIC_CLK_WIDTH (1)
-#define GPIO_OUTPUTS_LBN   (16)
-#define GPIO_OUTPUTS_WIDTH (4)
-#define GPIO_INPUTS_LBN (8)
-#define GPIO_DIRECTION_LBN (24)
-#define GPIO_DIRECTION_WIDTH (4)
-#define GPIO_DIRECTION_OUT (1)
-#define GPIO_SRAM_SLEEP (1 << 1)
-
-#define GPIO3_OEN_LBN (GPIO_DIRECTION_LBN + 3)
-#define	GPIO3_OEN_WIDTH 1
-#define	GPIO2_OEN_LBN (GPIO_DIRECTION_LBN + 2)
-#define	GPIO2_OEN_WIDTH 1
-#define	GPIO1_OEN_LBN (GPIO_DIRECTION_LBN + 1)
-#define	GPIO1_OEN_WIDTH 1
-#define GPIO0_OEN_LBN (GPIO_DIRECTION_LBN + 0)
-#define	GPIO0_OEN_WIDTH 1
-
-#define	GPIO3_OUT_LBN (GPIO_OUTPUTS_LBN + 3)
-#define	GPIO3_OUT_WIDTH 1
-#define	GPIO2_OUT_LBN (GPIO_OUTPUTS_LBN + 2)
-#define	GPIO2_OUT_WIDTH 1
-#define	GPIO1_OUT_LBN (GPIO_OUTPUTS_LBN + 1)
-#define	GPIO1_OUT_WIDTH 1
-#define	GPIO0_OUT_LBN (GPIO_OUTPUTS_LBN + 0)
-#define	GPIO0_OUT_WIDTH 1
-
-#define GPIO3_IN_LBN (GPIO_INPUTS_LBN + 3)
-#define	GPIO3_IN_WIDTH 1
-#define	GPIO2_IN_WIDTH 1
-#define	GPIO1_IN_WIDTH 1
-#define GPIO0_IN_LBN (GPIO_INPUTS_LBN + 0)
-#define	GPIO0_IN_WIDTH 1
-
-/* Global control register */
-#define GLB_CTL_REG_KER	0x0220
-#define EXT_PHY_RST_CTL_LBN 63
-#define EXT_PHY_RST_CTL_WIDTH 1
-#define PCIE_SD_RST_CTL_LBN 61
-#define PCIE_SD_RST_CTL_WIDTH 1
-
-#define PCIE_NSTCK_RST_CTL_LBN 58
-#define PCIE_NSTCK_RST_CTL_WIDTH 1
-#define PCIE_CORE_RST_CTL_LBN 57
-#define PCIE_CORE_RST_CTL_WIDTH 1
-#define EE_RST_CTL_LBN 49
-#define EE_RST_CTL_WIDTH 1
-#define RST_XGRX_LBN 24
-#define RST_XGRX_WIDTH 1
-#define RST_XGTX_LBN 23
-#define RST_XGTX_WIDTH 1
-#define RST_EM_LBN 22
-#define RST_EM_WIDTH 1
-#define EXT_PHY_RST_DUR_LBN 1
-#define EXT_PHY_RST_DUR_WIDTH 3
-#define SWRST_LBN 0
-#define SWRST_WIDTH 1
-#define INCLUDE_IN_RESET 0
-#define EXCLUDE_FROM_RESET 1
-
-/* Fatal interrupt register */
-#define FATAL_INTR_REG_KER 0x0230
-#define RBUF_OWN_INT_KER_EN_LBN 39
-#define RBUF_OWN_INT_KER_EN_WIDTH 1
-#define TBUF_OWN_INT_KER_EN_LBN 38
-#define TBUF_OWN_INT_KER_EN_WIDTH 1
-#define ILL_ADR_INT_KER_EN_LBN 33
-#define ILL_ADR_INT_KER_EN_WIDTH 1
-#define MEM_PERR_INT_KER_LBN 8
-#define MEM_PERR_INT_KER_WIDTH 1
-#define INT_KER_ERROR_LBN 0
-#define INT_KER_ERROR_WIDTH 12
-
-#define DP_CTRL_REG 0x250
-#define FLS_EVQ_ID_LBN 0
-#define FLS_EVQ_ID_WIDTH 11
-
-#define MEM_STAT_REG_KER 0x260
-
-/* Debug probe register */
-#define DEBUG_BLK_SEL_MISC 7
-#define DEBUG_BLK_SEL_SERDES 6
-#define DEBUG_BLK_SEL_EM 5
-#define DEBUG_BLK_SEL_SR 4
-#define DEBUG_BLK_SEL_EV 3
-#define DEBUG_BLK_SEL_RX 2
-#define DEBUG_BLK_SEL_TX 1
-#define DEBUG_BLK_SEL_BIU 0
-
-/* FPGA build version */
-#define ALTERA_BUILD_REG_KER 0x0300
-#define VER_ALL_LBN 0
-#define VER_ALL_WIDTH 32
-
-/* Spare EEPROM bits register (flash 0x390) */
-#define SPARE_REG_KER 0x310
-#define MEM_PERR_EN_TX_DATA_LBN 72
-#define MEM_PERR_EN_TX_DATA_WIDTH 2
-
-/* Timer table for kernel access */
-#define TIMER_CMD_REG_KER 0x420
-#define TIMER_MODE_LBN 12
-#define TIMER_MODE_WIDTH 2
-#define TIMER_MODE_DIS 0
-#define TIMER_MODE_INT_HLDOFF 2
-#define TIMER_VAL_LBN 0
-#define TIMER_VAL_WIDTH 12
-
-/* Driver generated event register */
-#define DRV_EV_REG_KER 0x440
-#define DRV_EV_QID_LBN 64
-#define DRV_EV_QID_WIDTH 12
-#define DRV_EV_DATA_LBN 0
-#define DRV_EV_DATA_WIDTH 64
-
-/* Buffer table configuration register */
-#define BUF_TBL_CFG_REG_KER 0x600
-#define BUF_TBL_MODE_LBN 3
-#define BUF_TBL_MODE_WIDTH 1
-#define BUF_TBL_MODE_HALF 0
-#define BUF_TBL_MODE_FULL 1
-
-/* SRAM receive descriptor cache configuration register */
-#define SRM_RX_DC_CFG_REG_KER 0x610
-#define SRM_RX_DC_BASE_ADR_LBN 0
-#define SRM_RX_DC_BASE_ADR_WIDTH 21
-
-/* SRAM transmit descriptor cache configuration register */
-#define SRM_TX_DC_CFG_REG_KER 0x620
-#define SRM_TX_DC_BASE_ADR_LBN 0
-#define SRM_TX_DC_BASE_ADR_WIDTH 21
-
-/* SRAM configuration register */
-#define SRM_CFG_REG_KER 0x630
-#define SRAM_OOB_BT_INIT_EN_LBN 3
-#define SRAM_OOB_BT_INIT_EN_WIDTH 1
-#define SRM_NUM_BANKS_AND_BANK_SIZE_LBN 0
-#define SRM_NUM_BANKS_AND_BANK_SIZE_WIDTH 3
-#define SRM_NB_BSZ_1BANKS_2M 0
-#define SRM_NB_BSZ_1BANKS_4M 1
-#define SRM_NB_BSZ_1BANKS_8M 2
-#define SRM_NB_BSZ_DEFAULT 3 /* char driver will set the default */
-#define SRM_NB_BSZ_2BANKS_4M 4
-#define SRM_NB_BSZ_2BANKS_8M 5
-#define SRM_NB_BSZ_2BANKS_16M 6
-#define SRM_NB_BSZ_RESERVED 7
-
-/* Special buffer table update register */
-#define BUF_TBL_UPD_REG_KER 0x0650
-#define BUF_UPD_CMD_LBN 63
-#define BUF_UPD_CMD_WIDTH 1
-#define BUF_CLR_CMD_LBN 62
-#define BUF_CLR_CMD_WIDTH 1
-#define BUF_CLR_END_ID_LBN 32
-#define BUF_CLR_END_ID_WIDTH 20
-#define BUF_CLR_START_ID_LBN 0
-#define BUF_CLR_START_ID_WIDTH 20
-
-/* Receive configuration register */
-#define RX_CFG_REG_KER 0x800
-
-/* B0 */
-#define RX_INGR_EN_B0_LBN 47
-#define RX_INGR_EN_B0_WIDTH 1
-#define RX_DESC_PUSH_EN_B0_LBN 43
-#define RX_DESC_PUSH_EN_B0_WIDTH 1
-#define RX_XON_TX_TH_B0_LBN 33
-#define RX_XON_TX_TH_B0_WIDTH 5
-#define RX_XOFF_TX_TH_B0_LBN 28
-#define RX_XOFF_TX_TH_B0_WIDTH 5
-#define RX_USR_BUF_SIZE_B0_LBN 19
-#define RX_USR_BUF_SIZE_B0_WIDTH 9
-#define RX_XON_MAC_TH_B0_LBN 10
-#define RX_XON_MAC_TH_B0_WIDTH 9
-#define RX_XOFF_MAC_TH_B0_LBN 1
-#define RX_XOFF_MAC_TH_B0_WIDTH 9
-#define RX_XOFF_MAC_EN_B0_LBN 0
-#define RX_XOFF_MAC_EN_B0_WIDTH 1
-
-/* A1 */
-#define RX_DESC_PUSH_EN_A1_LBN 35
-#define RX_DESC_PUSH_EN_A1_WIDTH 1
-#define RX_XON_TX_TH_A1_LBN 25
-#define RX_XON_TX_TH_A1_WIDTH 5
-#define RX_XOFF_TX_TH_A1_LBN 20
-#define RX_XOFF_TX_TH_A1_WIDTH 5
-#define RX_USR_BUF_SIZE_A1_LBN 11
-#define RX_USR_BUF_SIZE_A1_WIDTH 9
-#define RX_XON_MAC_TH_A1_LBN 6
-#define RX_XON_MAC_TH_A1_WIDTH 5
-#define RX_XOFF_MAC_TH_A1_LBN 1
-#define RX_XOFF_MAC_TH_A1_WIDTH 5
-#define RX_XOFF_MAC_EN_A1_LBN 0
-#define RX_XOFF_MAC_EN_A1_WIDTH 1
-
-/* Receive filter control register */
-#define RX_FILTER_CTL_REG 0x810
-#define UDP_FULL_SRCH_LIMIT_LBN 32
-#define UDP_FULL_SRCH_LIMIT_WIDTH 8
-#define NUM_KER_LBN 24
-#define NUM_KER_WIDTH 2
-#define UDP_WILD_SRCH_LIMIT_LBN 16
-#define UDP_WILD_SRCH_LIMIT_WIDTH 8
-#define TCP_WILD_SRCH_LIMIT_LBN 8
-#define TCP_WILD_SRCH_LIMIT_WIDTH 8
-#define TCP_FULL_SRCH_LIMIT_LBN 0
-#define TCP_FULL_SRCH_LIMIT_WIDTH 8
-
-/* RX queue flush register */
-#define RX_FLUSH_DESCQ_REG_KER 0x0820
-#define RX_FLUSH_DESCQ_CMD_LBN 24
-#define RX_FLUSH_DESCQ_CMD_WIDTH 1
-#define RX_FLUSH_DESCQ_LBN 0
-#define RX_FLUSH_DESCQ_WIDTH 12
-
-/* Receive descriptor update register */
-#define RX_DESC_UPD_REG_KER_DWORD (0x830 + 12)
-#define RX_DESC_WPTR_DWORD_LBN 0
-#define RX_DESC_WPTR_DWORD_WIDTH 12
-
-/* Receive descriptor cache configuration register */
-#define RX_DC_CFG_REG_KER 0x840
-#define RX_DC_SIZE_LBN 0
-#define RX_DC_SIZE_WIDTH 2
-
-#define RX_DC_PF_WM_REG_KER 0x850
-#define RX_DC_PF_LWM_LBN 0
-#define RX_DC_PF_LWM_WIDTH 6
-
-/* RX no descriptor drop counter */
-#define RX_NODESC_DROP_REG_KER 0x880
-#define RX_NODESC_DROP_CNT_LBN 0
-#define RX_NODESC_DROP_CNT_WIDTH 16
-
-/* RX black magic register */
-#define RX_SELF_RST_REG_KER 0x890
-#define RX_ISCSI_DIS_LBN 17
-#define RX_ISCSI_DIS_WIDTH 1
-#define RX_NODESC_WAIT_DIS_LBN 9
-#define RX_NODESC_WAIT_DIS_WIDTH 1
-#define RX_RECOVERY_EN_LBN 8
-#define RX_RECOVERY_EN_WIDTH 1
-
-/* TX queue flush register */
-#define TX_FLUSH_DESCQ_REG_KER 0x0a00
-#define TX_FLUSH_DESCQ_CMD_LBN 12
-#define TX_FLUSH_DESCQ_CMD_WIDTH 1
-#define TX_FLUSH_DESCQ_LBN 0
-#define TX_FLUSH_DESCQ_WIDTH 12
-
-/* Transmit descriptor update register */
-#define TX_DESC_UPD_REG_KER_DWORD (0xa10 + 12)
-#define TX_DESC_WPTR_DWORD_LBN 0
-#define TX_DESC_WPTR_DWORD_WIDTH 12
-
-/* Transmit descriptor cache configuration register */
-#define TX_DC_CFG_REG_KER 0xa20
-#define TX_DC_SIZE_LBN 0
-#define TX_DC_SIZE_WIDTH 2
-
-/* Transmit checksum configuration register (A0/A1 only) */
-#define TX_CHKSM_CFG_REG_KER_A1 0xa30
-
-/* Transmit configuration register */
-#define TX_CFG_REG_KER 0xa50
-#define TX_NO_EOP_DISC_EN_LBN 5
-#define TX_NO_EOP_DISC_EN_WIDTH 1
-
-/* Transmit configuration register 2 */
-#define TX_CFG2_REG_KER 0xa80
-#define TX_CSR_PUSH_EN_LBN 89
-#define TX_CSR_PUSH_EN_WIDTH 1
-#define TX_RX_SPACER_LBN 64
-#define TX_RX_SPACER_WIDTH 8
-#define TX_SW_EV_EN_LBN 59
-#define TX_SW_EV_EN_WIDTH 1
-#define TX_RX_SPACER_EN_LBN 57
-#define TX_RX_SPACER_EN_WIDTH 1
-#define TX_PREF_THRESHOLD_LBN 19
-#define TX_PREF_THRESHOLD_WIDTH 2
-#define TX_ONE_PKT_PER_Q_LBN 18
-#define TX_ONE_PKT_PER_Q_WIDTH 1
-#define TX_DIS_NON_IP_EV_LBN 17
-#define TX_DIS_NON_IP_EV_WIDTH 1
-#define TX_FLUSH_MIN_LEN_EN_B0_LBN 7
-#define TX_FLUSH_MIN_LEN_EN_B0_WIDTH 1
-
-/* PHY management transmit data register */
-#define MD_TXD_REG_KER 0xc00
-#define MD_TXD_LBN 0
-#define MD_TXD_WIDTH 16
-
-/* PHY management receive data register */
-#define MD_RXD_REG_KER 0xc10
-#define MD_RXD_LBN 0
-#define MD_RXD_WIDTH 16
-
-/* PHY management configuration & status register */
-#define MD_CS_REG_KER 0xc20
-#define MD_GC_LBN 4
-#define MD_GC_WIDTH 1
-#define MD_RIC_LBN 2
-#define MD_RIC_WIDTH 1
-#define MD_RDC_LBN 1
-#define MD_RDC_WIDTH 1
-#define MD_WRC_LBN 0
-#define MD_WRC_WIDTH 1
-
-/* PHY management PHY address register */
-#define MD_PHY_ADR_REG_KER 0xc30
-#define MD_PHY_ADR_LBN 0
-#define MD_PHY_ADR_WIDTH 16
-
-/* PHY management ID register */
-#define MD_ID_REG_KER 0xc40
-#define MD_PRT_ADR_LBN 11
-#define MD_PRT_ADR_WIDTH 5
-#define MD_DEV_ADR_LBN 6
-#define MD_DEV_ADR_WIDTH 5
-
-/* PHY management status & mask register (DWORD read only) */
-#define MD_STAT_REG_KER 0xc50
-#define MD_BSERR_LBN 2
-#define MD_BSERR_WIDTH 1
-#define MD_LNFL_LBN 1
-#define MD_LNFL_WIDTH 1
-#define MD_BSY_LBN 0
-#define MD_BSY_WIDTH 1
-
-/* Port 0 and 1 MAC stats registers */
-#define MAC0_STAT_DMA_REG_KER 0xc60
-#define MAC_STAT_DMA_CMD_LBN 48
-#define MAC_STAT_DMA_CMD_WIDTH 1
-#define MAC_STAT_DMA_ADR_LBN 0
-#define MAC_STAT_DMA_ADR_WIDTH EFX_DMA_TYPE_WIDTH(46)
-
-/* Port 0 and 1 MAC control registers */
-#define MAC0_CTRL_REG_KER 0xc80
-#define MAC_XOFF_VAL_LBN 16
-#define MAC_XOFF_VAL_WIDTH 16
-#define TXFIFO_DRAIN_EN_B0_LBN 7
-#define TXFIFO_DRAIN_EN_B0_WIDTH 1
-#define MAC_BCAD_ACPT_LBN 4
-#define MAC_BCAD_ACPT_WIDTH 1
-#define MAC_UC_PROM_LBN 3
-#define MAC_UC_PROM_WIDTH 1
-#define MAC_LINK_STATUS_LBN 2
-#define MAC_LINK_STATUS_WIDTH 1
-#define MAC_SPEED_LBN 0
-#define MAC_SPEED_WIDTH 2
-
-/* 10G XAUI XGXS default values */
-#define XX_TXDRV_DEQ_DEFAULT 0xe /* deq=.6 */
-#define XX_TXDRV_DTX_DEFAULT 0x5 /* 1.25 */
-#define XX_SD_CTL_DRV_DEFAULT 0  /* 20mA */
-
-/* Multicast address hash table */
-#define MAC_MCAST_HASH_REG0_KER 0xca0
-#define MAC_MCAST_HASH_REG1_KER 0xcb0
-
-/* GMAC configuration register 1 */
-#define GM_CFG1_REG 0xe00
-#define GM_SW_RST_LBN 31
-#define GM_SW_RST_WIDTH 1
-#define GM_LOOP_LBN 8
-#define GM_LOOP_WIDTH 1
-#define GM_RX_FC_EN_LBN 5
-#define GM_RX_FC_EN_WIDTH 1
-#define GM_TX_FC_EN_LBN 4
-#define GM_TX_FC_EN_WIDTH 1
-#define GM_RX_EN_LBN 2
-#define GM_RX_EN_WIDTH 1
-#define GM_TX_EN_LBN 0
-#define GM_TX_EN_WIDTH 1
-
-/* GMAC configuration register 2 */
-#define GM_CFG2_REG 0xe10
-#define GM_PAMBL_LEN_LBN 12
-#define GM_PAMBL_LEN_WIDTH 4
-#define GM_IF_MODE_LBN 8
-#define GM_IF_MODE_WIDTH 2
-#define GM_LEN_CHK_LBN 4
-#define GM_LEN_CHK_WIDTH 1
-#define GM_PAD_CRC_EN_LBN 2
-#define GM_PAD_CRC_EN_WIDTH 1
-#define GM_FD_LBN 0
-#define GM_FD_WIDTH 1
-
-/* GMAC maximum frame length register */
-#define GM_MAX_FLEN_REG 0xe40
-#define GM_MAX_FLEN_LBN 0
-#define GM_MAX_FLEN_WIDTH 16
-
-/* GMAC station address register 1 */
-#define GM_ADR1_REG 0xf00
-#define GM_HWADDR_5_LBN 24
-#define GM_HWADDR_5_WIDTH 8
-#define GM_HWADDR_4_LBN 16
-#define GM_HWADDR_4_WIDTH 8
-#define GM_HWADDR_3_LBN 8
-#define GM_HWADDR_3_WIDTH 8
-#define GM_HWADDR_2_LBN 0
-#define GM_HWADDR_2_WIDTH 8
-
-/* GMAC station address register 2 */
-#define GM_ADR2_REG 0xf10
-#define GM_HWADDR_1_LBN 24
-#define GM_HWADDR_1_WIDTH 8
-#define GM_HWADDR_0_LBN 16
-#define GM_HWADDR_0_WIDTH 8
-
-/* GMAC FIFO configuration register 0 */
-#define GMF_CFG0_REG 0xf20
-#define GMF_FTFENREQ_LBN 12
-#define GMF_FTFENREQ_WIDTH 1
-#define GMF_STFENREQ_LBN 11
-#define GMF_STFENREQ_WIDTH 1
-#define GMF_FRFENREQ_LBN 10
-#define GMF_FRFENREQ_WIDTH 1
-#define GMF_SRFENREQ_LBN 9
-#define GMF_SRFENREQ_WIDTH 1
-#define GMF_WTMENREQ_LBN 8
-#define GMF_WTMENREQ_WIDTH 1
-
-/* GMAC FIFO configuration register 1 */
-#define GMF_CFG1_REG 0xf30
-#define GMF_CFGFRTH_LBN 16
-#define GMF_CFGFRTH_WIDTH 5
-#define GMF_CFGXOFFRTX_LBN 0
-#define GMF_CFGXOFFRTX_WIDTH 16
-
-/* GMAC FIFO configuration register 2 */
-#define GMF_CFG2_REG 0xf40
-#define GMF_CFGHWM_LBN 16
-#define GMF_CFGHWM_WIDTH 6
-#define GMF_CFGLWM_LBN 0
-#define GMF_CFGLWM_WIDTH 6
-
-/* GMAC FIFO configuration register 3 */
-#define GMF_CFG3_REG 0xf50
-#define GMF_CFGHWMFT_LBN 16
-#define GMF_CFGHWMFT_WIDTH 6
-#define GMF_CFGFTTH_LBN 0
-#define GMF_CFGFTTH_WIDTH 6
-
-/* GMAC FIFO configuration register 4 */
-#define GMF_CFG4_REG 0xf60
-#define GMF_HSTFLTRFRM_PAUSE_LBN 12
-#define GMF_HSTFLTRFRM_PAUSE_WIDTH 12
-
-/* GMAC FIFO configuration register 5 */
-#define GMF_CFG5_REG 0xf70
-#define GMF_CFGHDPLX_LBN 22
-#define GMF_CFGHDPLX_WIDTH 1
-#define GMF_CFGBYTMODE_LBN 19
-#define GMF_CFGBYTMODE_WIDTH 1
-#define GMF_HSTDRPLT64_LBN 18
-#define GMF_HSTDRPLT64_WIDTH 1
-#define GMF_HSTFLTRFRMDC_PAUSE_LBN 12
-#define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1
-
-/* XGMAC address register low */
-#define XM_ADR_LO_REG 0x1200
-#define XM_ADR_3_LBN 24
-#define XM_ADR_3_WIDTH 8
-#define XM_ADR_2_LBN 16
-#define XM_ADR_2_WIDTH 8
-#define XM_ADR_1_LBN 8
-#define XM_ADR_1_WIDTH 8
-#define XM_ADR_0_LBN 0
-#define XM_ADR_0_WIDTH 8
-
-/* XGMAC address register high */
-#define XM_ADR_HI_REG 0x1210
-#define XM_ADR_5_LBN 8
-#define XM_ADR_5_WIDTH 8
-#define XM_ADR_4_LBN 0
-#define XM_ADR_4_WIDTH 8
-
-/* XGMAC global configuration */
-#define XM_GLB_CFG_REG 0x1220
-#define XM_RX_STAT_EN_LBN 11
-#define XM_RX_STAT_EN_WIDTH 1
-#define XM_TX_STAT_EN_LBN 10
-#define XM_TX_STAT_EN_WIDTH 1
-#define XM_RX_JUMBO_MODE_LBN 6
-#define XM_RX_JUMBO_MODE_WIDTH 1
-#define XM_INTCLR_MODE_LBN 3
-#define XM_INTCLR_MODE_WIDTH 1
-#define XM_CORE_RST_LBN 0
-#define XM_CORE_RST_WIDTH 1
-
-/* XGMAC transmit configuration */
-#define XM_TX_CFG_REG 0x1230
-#define XM_IPG_LBN 16
-#define XM_IPG_WIDTH 4
-#define XM_FCNTL_LBN 10
-#define XM_FCNTL_WIDTH 1
-#define XM_TXCRC_LBN 8
-#define XM_TXCRC_WIDTH 1
-#define XM_AUTO_PAD_LBN 5
-#define XM_AUTO_PAD_WIDTH 1
-#define XM_TX_PRMBL_LBN 2
-#define XM_TX_PRMBL_WIDTH 1
-#define XM_TXEN_LBN 1
-#define XM_TXEN_WIDTH 1
-
-/* XGMAC receive configuration */
-#define XM_RX_CFG_REG 0x1240
-#define XM_PASS_CRC_ERR_LBN 25
-#define XM_PASS_CRC_ERR_WIDTH 1
-#define XM_ACPT_ALL_MCAST_LBN 11
-#define XM_ACPT_ALL_MCAST_WIDTH 1
-#define XM_ACPT_ALL_UCAST_LBN 9
-#define XM_ACPT_ALL_UCAST_WIDTH 1
-#define XM_AUTO_DEPAD_LBN 8
-#define XM_AUTO_DEPAD_WIDTH 1
-#define XM_RXEN_LBN 1
-#define XM_RXEN_WIDTH 1
-
-/* XGMAC management interrupt mask register */
-#define XM_MGT_INT_MSK_REG_B0 0x1250
-#define XM_MSK_PRMBLE_ERR_LBN 2
-#define XM_MSK_PRMBLE_ERR_WIDTH 1
-#define XM_MSK_RMTFLT_LBN 1
-#define XM_MSK_RMTFLT_WIDTH 1
-#define XM_MSK_LCLFLT_LBN 0
-#define XM_MSK_LCLFLT_WIDTH 1
-
-/* XGMAC flow control register */
-#define XM_FC_REG 0x1270
-#define XM_PAUSE_TIME_LBN 16
-#define XM_PAUSE_TIME_WIDTH 16
-#define XM_DIS_FCNTL_LBN 0
-#define XM_DIS_FCNTL_WIDTH 1
-
-/* XGMAC pause time count register */
-#define XM_PAUSE_TIME_REG 0x1290
-
-/* XGMAC transmit parameter register */
-#define XM_TX_PARAM_REG 0x012d0
-#define XM_TX_JUMBO_MODE_LBN 31
-#define XM_TX_JUMBO_MODE_WIDTH 1
-#define XM_MAX_TX_FRM_SIZE_LBN 16
-#define XM_MAX_TX_FRM_SIZE_WIDTH 14
-
-/* XGMAC receive parameter register */
-#define XM_RX_PARAM_REG 0x12e0
-#define XM_MAX_RX_FRM_SIZE_LBN 0
-#define XM_MAX_RX_FRM_SIZE_WIDTH 14
-
-/* XGMAC management interrupt status register */
-#define XM_MGT_INT_REG_B0 0x12f0
-#define XM_PRMBLE_ERR 2
-#define XM_PRMBLE_WIDTH 1
-#define XM_RMTFLT_LBN 1
-#define XM_RMTFLT_WIDTH 1
-#define XM_LCLFLT_LBN 0
-#define XM_LCLFLT_WIDTH 1
-
-/* XGXS/XAUI powerdown/reset register */
-#define XX_PWR_RST_REG 0x1300
-
-#define XX_SD_RST_ACT_LBN 16
-#define XX_SD_RST_ACT_WIDTH 1
-#define XX_PWRDND_EN_LBN 15
-#define XX_PWRDND_EN_WIDTH 1
-#define XX_PWRDNC_EN_LBN 14
-#define XX_PWRDNC_EN_WIDTH 1
-#define XX_PWRDNB_EN_LBN 13
-#define XX_PWRDNB_EN_WIDTH 1
-#define XX_PWRDNA_EN_LBN 12
-#define XX_PWRDNA_EN_WIDTH 1
-#define XX_RSTPLLCD_EN_LBN 9
-#define XX_RSTPLLCD_EN_WIDTH 1
-#define XX_RSTPLLAB_EN_LBN 8
-#define XX_RSTPLLAB_EN_WIDTH 1
-#define XX_RESETD_EN_LBN 7
-#define XX_RESETD_EN_WIDTH 1
-#define XX_RESETC_EN_LBN 6
-#define XX_RESETC_EN_WIDTH 1
-#define XX_RESETB_EN_LBN 5
-#define XX_RESETB_EN_WIDTH 1
-#define XX_RESETA_EN_LBN 4
-#define XX_RESETA_EN_WIDTH 1
-#define XX_RSTXGXSRX_EN_LBN 2
-#define XX_RSTXGXSRX_EN_WIDTH 1
-#define XX_RSTXGXSTX_EN_LBN 1
-#define XX_RSTXGXSTX_EN_WIDTH 1
-#define XX_RST_XX_EN_LBN 0
-#define XX_RST_XX_EN_WIDTH 1
-
-/* XGXS/XAUI powerdown/reset control register */
-#define XX_SD_CTL_REG 0x1310
-#define XX_HIDRVD_LBN 15
-#define XX_HIDRVD_WIDTH 1
-#define XX_LODRVD_LBN 14
-#define XX_LODRVD_WIDTH 1
-#define XX_HIDRVC_LBN 13
-#define XX_HIDRVC_WIDTH 1
-#define XX_LODRVC_LBN 12
-#define XX_LODRVC_WIDTH 1
-#define XX_HIDRVB_LBN 11
-#define XX_HIDRVB_WIDTH 1
-#define XX_LODRVB_LBN 10
-#define XX_LODRVB_WIDTH 1
-#define XX_HIDRVA_LBN 9
-#define XX_HIDRVA_WIDTH 1
-#define XX_LODRVA_LBN 8
-#define XX_LODRVA_WIDTH 1
-#define XX_LPBKD_LBN 3
-#define XX_LPBKD_WIDTH 1
-#define XX_LPBKC_LBN 2
-#define XX_LPBKC_WIDTH 1
-#define XX_LPBKB_LBN 1
-#define XX_LPBKB_WIDTH 1
-#define XX_LPBKA_LBN 0
-#define XX_LPBKA_WIDTH 1
-
-#define XX_TXDRV_CTL_REG 0x1320
-#define XX_DEQD_LBN 28
-#define XX_DEQD_WIDTH 4
-#define XX_DEQC_LBN 24
-#define XX_DEQC_WIDTH 4
-#define XX_DEQB_LBN 20
-#define XX_DEQB_WIDTH 4
-#define XX_DEQA_LBN 16
-#define XX_DEQA_WIDTH 4
-#define XX_DTXD_LBN 12
-#define XX_DTXD_WIDTH 4
-#define XX_DTXC_LBN 8
-#define XX_DTXC_WIDTH 4
-#define XX_DTXB_LBN 4
-#define XX_DTXB_WIDTH 4
-#define XX_DTXA_LBN 0
-#define XX_DTXA_WIDTH 4
-
-/* XAUI XGXS core status register */
-#define XX_CORE_STAT_REG 0x1360
-#define XX_FORCE_SIG_LBN 24
-#define XX_FORCE_SIG_WIDTH 8
-#define XX_FORCE_SIG_DECODE_FORCED 0xff
-#define XX_XGXS_LB_EN_LBN 23
-#define XX_XGXS_LB_EN_WIDTH 1
-#define XX_XGMII_LB_EN_LBN 22
-#define XX_XGMII_LB_EN_WIDTH 1
-#define XX_ALIGN_DONE_LBN 20
-#define XX_ALIGN_DONE_WIDTH 1
-#define XX_SYNC_STAT_LBN 16
-#define XX_SYNC_STAT_WIDTH 4
-#define XX_SYNC_STAT_DECODE_SYNCED 0xf
-#define XX_COMMA_DET_LBN 12
-#define XX_COMMA_DET_WIDTH 4
-#define XX_COMMA_DET_DECODE_DETECTED 0xf
-#define XX_COMMA_DET_RESET 0xf
-#define XX_CHARERR_LBN 4
-#define XX_CHARERR_WIDTH 4
-#define XX_CHARERR_RESET 0xf
-#define XX_DISPERR_LBN 0
-#define XX_DISPERR_WIDTH 4
-#define XX_DISPERR_RESET 0xf
-
-/* Receive filter table */
-#define RX_FILTER_TBL0 0xF00000
-
-/* Receive descriptor pointer table */
-#define RX_DESC_PTR_TBL_KER_A1 0x11800
-#define RX_DESC_PTR_TBL_KER_B0 0xF40000
-#define RX_DESC_PTR_TBL_KER_P0 0x900
-#define RX_ISCSI_DDIG_EN_LBN 88
-#define RX_ISCSI_DDIG_EN_WIDTH 1
-#define RX_ISCSI_HDIG_EN_LBN 87
-#define RX_ISCSI_HDIG_EN_WIDTH 1
-#define RX_DESCQ_BUF_BASE_ID_LBN 36
-#define RX_DESCQ_BUF_BASE_ID_WIDTH 20
-#define RX_DESCQ_EVQ_ID_LBN 24
-#define RX_DESCQ_EVQ_ID_WIDTH 12
-#define RX_DESCQ_OWNER_ID_LBN 10
-#define RX_DESCQ_OWNER_ID_WIDTH 14
-#define RX_DESCQ_LABEL_LBN 5
-#define RX_DESCQ_LABEL_WIDTH 5
-#define RX_DESCQ_SIZE_LBN 3
-#define RX_DESCQ_SIZE_WIDTH 2
-#define RX_DESCQ_SIZE_4K 3
-#define RX_DESCQ_SIZE_2K 2
-#define RX_DESCQ_SIZE_1K 1
-#define RX_DESCQ_SIZE_512 0
-#define RX_DESCQ_TYPE_LBN 2
-#define RX_DESCQ_TYPE_WIDTH 1
-#define RX_DESCQ_JUMBO_LBN 1
-#define RX_DESCQ_JUMBO_WIDTH 1
-#define RX_DESCQ_EN_LBN 0
-#define RX_DESCQ_EN_WIDTH 1
-
-/* Transmit descriptor pointer table */
-#define TX_DESC_PTR_TBL_KER_A1 0x11900
-#define TX_DESC_PTR_TBL_KER_B0 0xF50000
-#define TX_DESC_PTR_TBL_KER_P0 0xa40
-#define TX_NON_IP_DROP_DIS_B0_LBN 91
-#define TX_NON_IP_DROP_DIS_B0_WIDTH 1
-#define TX_IP_CHKSM_DIS_B0_LBN 90
-#define TX_IP_CHKSM_DIS_B0_WIDTH 1
-#define TX_TCP_CHKSM_DIS_B0_LBN 89
-#define TX_TCP_CHKSM_DIS_B0_WIDTH 1
-#define TX_DESCQ_EN_LBN 88
-#define TX_DESCQ_EN_WIDTH 1
-#define TX_ISCSI_DDIG_EN_LBN 87
-#define TX_ISCSI_DDIG_EN_WIDTH 1
-#define TX_ISCSI_HDIG_EN_LBN 86
-#define TX_ISCSI_HDIG_EN_WIDTH 1
-#define TX_DESCQ_BUF_BASE_ID_LBN 36
-#define TX_DESCQ_BUF_BASE_ID_WIDTH 20
-#define TX_DESCQ_EVQ_ID_LBN 24
-#define TX_DESCQ_EVQ_ID_WIDTH 12
-#define TX_DESCQ_OWNER_ID_LBN 10
-#define TX_DESCQ_OWNER_ID_WIDTH 14
-#define TX_DESCQ_LABEL_LBN 5
-#define TX_DESCQ_LABEL_WIDTH 5
-#define TX_DESCQ_SIZE_LBN 3
-#define TX_DESCQ_SIZE_WIDTH 2
-#define TX_DESCQ_SIZE_4K 3
-#define TX_DESCQ_SIZE_2K 2
-#define TX_DESCQ_SIZE_1K 1
-#define TX_DESCQ_SIZE_512 0
-#define TX_DESCQ_TYPE_LBN 1
-#define TX_DESCQ_TYPE_WIDTH 2
-
-/* Event queue pointer */
-#define EVQ_PTR_TBL_KER_A1 0x11a00
-#define EVQ_PTR_TBL_KER_B0 0xf60000
-#define EVQ_PTR_TBL_KER_P0 0x500
-#define EVQ_EN_LBN 23
-#define EVQ_EN_WIDTH 1
-#define EVQ_SIZE_LBN 20
-#define EVQ_SIZE_WIDTH 3
-#define EVQ_SIZE_32K 6
-#define EVQ_SIZE_16K 5
-#define EVQ_SIZE_8K 4
-#define EVQ_SIZE_4K 3
-#define EVQ_SIZE_2K 2
-#define EVQ_SIZE_1K 1
-#define EVQ_SIZE_512 0
-#define EVQ_BUF_BASE_ID_LBN 0
-#define EVQ_BUF_BASE_ID_WIDTH 20
-
-/* Event queue read pointer */
-#define EVQ_RPTR_REG_KER_A1 0x11b00
-#define EVQ_RPTR_REG_KER_B0 0xfa0000
-#define EVQ_RPTR_REG_KER_DWORD (EVQ_RPTR_REG_KER + 0)
-#define EVQ_RPTR_DWORD_LBN 0
-#define EVQ_RPTR_DWORD_WIDTH 14
-
-/* RSS indirection table */
-#define RX_RSS_INDIR_TBL_B0 0xFB0000
-#define RX_RSS_INDIR_ENT_B0_LBN 0
-#define RX_RSS_INDIR_ENT_B0_WIDTH 6
-
-/* Special buffer descriptors (full-mode) */
-#define BUF_FULL_TBL_KER_A1 0x8000
-#define BUF_FULL_TBL_KER_B0 0x800000
-#define IP_DAT_BUF_SIZE_LBN 50
-#define IP_DAT_BUF_SIZE_WIDTH 1
-#define IP_DAT_BUF_SIZE_8K 1
-#define IP_DAT_BUF_SIZE_4K 0
-#define BUF_ADR_REGION_LBN 48
-#define BUF_ADR_REGION_WIDTH 2
-#define BUF_ADR_FBUF_LBN 14
-#define BUF_ADR_FBUF_WIDTH 34
-#define BUF_OWNER_ID_FBUF_LBN 0
-#define BUF_OWNER_ID_FBUF_WIDTH 14
-
-/* Transmit descriptor */
-#define TX_KER_PORT_LBN 63
-#define TX_KER_PORT_WIDTH 1
-#define TX_KER_CONT_LBN 62
-#define TX_KER_CONT_WIDTH 1
-#define TX_KER_BYTE_CNT_LBN 48
-#define TX_KER_BYTE_CNT_WIDTH 14
-#define TX_KER_BUF_REGION_LBN 46
-#define TX_KER_BUF_REGION_WIDTH 2
-#define TX_KER_BUF_REGION0_DECODE 0
-#define TX_KER_BUF_REGION1_DECODE 1
-#define TX_KER_BUF_REGION2_DECODE 2
-#define TX_KER_BUF_REGION3_DECODE 3
-#define TX_KER_BUF_ADR_LBN 0
-#define TX_KER_BUF_ADR_WIDTH EFX_DMA_TYPE_WIDTH(46)
-
-/* Receive descriptor */
-#define RX_KER_BUF_SIZE_LBN 48
-#define RX_KER_BUF_SIZE_WIDTH 14
-#define RX_KER_BUF_REGION_LBN 46
-#define RX_KER_BUF_REGION_WIDTH 2
-#define RX_KER_BUF_REGION0_DECODE 0
-#define RX_KER_BUF_REGION1_DECODE 1
-#define RX_KER_BUF_REGION2_DECODE 2
-#define RX_KER_BUF_REGION3_DECODE 3
-#define RX_KER_BUF_ADR_LBN 0
-#define RX_KER_BUF_ADR_WIDTH EFX_DMA_TYPE_WIDTH(46)
-
-/**************************************************************************
- *
- * Falcon events
- *
- **************************************************************************
- */
-
-/* Event queue entries */
-#define EV_CODE_LBN 60
-#define EV_CODE_WIDTH 4
-#define RX_IP_EV_DECODE 0
-#define TX_IP_EV_DECODE 2
-#define DRIVER_EV_DECODE 5
-#define GLOBAL_EV_DECODE 6
-#define DRV_GEN_EV_DECODE 7
-#define WHOLE_EVENT_LBN 0
-#define WHOLE_EVENT_WIDTH 64
-
-/* Receive events */
-#define RX_EV_PKT_OK_LBN 56
-#define RX_EV_PKT_OK_WIDTH 1
-#define RX_EV_PAUSE_FRM_ERR_LBN 55
-#define RX_EV_PAUSE_FRM_ERR_WIDTH 1
-#define RX_EV_BUF_OWNER_ID_ERR_LBN 54
-#define RX_EV_BUF_OWNER_ID_ERR_WIDTH 1
-#define RX_EV_IF_FRAG_ERR_LBN 53
-#define RX_EV_IF_FRAG_ERR_WIDTH 1
-#define RX_EV_IP_HDR_CHKSUM_ERR_LBN 52
-#define RX_EV_IP_HDR_CHKSUM_ERR_WIDTH 1
-#define RX_EV_TCP_UDP_CHKSUM_ERR_LBN 51
-#define RX_EV_TCP_UDP_CHKSUM_ERR_WIDTH 1
-#define RX_EV_ETH_CRC_ERR_LBN 50
-#define RX_EV_ETH_CRC_ERR_WIDTH 1
-#define RX_EV_FRM_TRUNC_LBN 49
-#define RX_EV_FRM_TRUNC_WIDTH 1
-#define RX_EV_DRIB_NIB_LBN 48
-#define RX_EV_DRIB_NIB_WIDTH 1
-#define RX_EV_TOBE_DISC_LBN 47
-#define RX_EV_TOBE_DISC_WIDTH 1
-#define RX_EV_PKT_TYPE_LBN 44
-#define RX_EV_PKT_TYPE_WIDTH 3
-#define RX_EV_PKT_TYPE_ETH_DECODE 0
-#define RX_EV_PKT_TYPE_LLC_DECODE 1
-#define RX_EV_PKT_TYPE_JUMBO_DECODE 2
-#define RX_EV_PKT_TYPE_VLAN_DECODE 3
-#define RX_EV_PKT_TYPE_VLAN_LLC_DECODE 4
-#define RX_EV_PKT_TYPE_VLAN_JUMBO_DECODE 5
-#define RX_EV_HDR_TYPE_LBN 42
-#define RX_EV_HDR_TYPE_WIDTH 2
-#define RX_EV_HDR_TYPE_TCP_IPV4_DECODE 0
-#define RX_EV_HDR_TYPE_UDP_IPV4_DECODE 1
-#define RX_EV_HDR_TYPE_OTHER_IP_DECODE 2
-#define RX_EV_HDR_TYPE_NON_IP_DECODE 3
-#define RX_EV_HDR_TYPE_HAS_CHECKSUMS(hdr_type) \
-	((hdr_type) <= RX_EV_HDR_TYPE_UDP_IPV4_DECODE)
-#define RX_EV_MCAST_HASH_MATCH_LBN 40
-#define RX_EV_MCAST_HASH_MATCH_WIDTH 1
-#define RX_EV_MCAST_PKT_LBN 39
-#define RX_EV_MCAST_PKT_WIDTH 1
-#define RX_EV_Q_LABEL_LBN 32
-#define RX_EV_Q_LABEL_WIDTH 5
-#define RX_EV_JUMBO_CONT_LBN 31
-#define RX_EV_JUMBO_CONT_WIDTH 1
-#define RX_EV_BYTE_CNT_LBN 16
-#define RX_EV_BYTE_CNT_WIDTH 14
-#define RX_EV_SOP_LBN 15
-#define RX_EV_SOP_WIDTH 1
-#define RX_EV_DESC_PTR_LBN 0
-#define RX_EV_DESC_PTR_WIDTH 12
-
-/* Transmit events */
-#define TX_EV_PKT_ERR_LBN 38
-#define TX_EV_PKT_ERR_WIDTH 1
-#define TX_EV_Q_LABEL_LBN 32
-#define TX_EV_Q_LABEL_WIDTH 5
-#define TX_EV_WQ_FF_FULL_LBN 15
-#define TX_EV_WQ_FF_FULL_WIDTH 1
-#define TX_EV_COMP_LBN 12
-#define TX_EV_COMP_WIDTH 1
-#define TX_EV_DESC_PTR_LBN 0
-#define TX_EV_DESC_PTR_WIDTH 12
-
-/* Driver events */
-#define DRIVER_EV_SUB_CODE_LBN 56
-#define DRIVER_EV_SUB_CODE_WIDTH 4
-#define DRIVER_EV_SUB_DATA_LBN 0
-#define DRIVER_EV_SUB_DATA_WIDTH 14
-#define TX_DESCQ_FLS_DONE_EV_DECODE 0
-#define RX_DESCQ_FLS_DONE_EV_DECODE 1
-#define EVQ_INIT_DONE_EV_DECODE 2
-#define EVQ_NOT_EN_EV_DECODE 3
-#define RX_DESCQ_FLSFF_OVFL_EV_DECODE 4
-#define SRM_UPD_DONE_EV_DECODE 5
-#define WAKE_UP_EV_DECODE 6
-#define TX_PKT_NON_TCP_UDP_DECODE 9
-#define TIMER_EV_DECODE 10
-#define RX_RECOVERY_EV_DECODE 11
-#define RX_DSC_ERROR_EV_DECODE 14
-#define TX_DSC_ERROR_EV_DECODE 15
-#define DRIVER_EV_TX_DESCQ_ID_LBN 0
-#define DRIVER_EV_TX_DESCQ_ID_WIDTH 12
-#define DRIVER_EV_RX_FLUSH_FAIL_LBN 12
-#define DRIVER_EV_RX_FLUSH_FAIL_WIDTH 1
-#define DRIVER_EV_RX_DESCQ_ID_LBN 0
-#define DRIVER_EV_RX_DESCQ_ID_WIDTH 12
-#define SRM_CLR_EV_DECODE 0
-#define SRM_UPD_EV_DECODE 1
-#define SRM_ILLCLR_EV_DECODE 2
-
-/* Global events */
-#define RX_RECOVERY_B0_LBN 12
-#define RX_RECOVERY_B0_WIDTH 1
-#define XG_MNT_INTR_B0_LBN 11
-#define XG_MNT_INTR_B0_WIDTH 1
-#define RX_RECOVERY_A1_LBN 11
-#define RX_RECOVERY_A1_WIDTH 1
-#define XFP_PHY_INTR_LBN 10
-#define XFP_PHY_INTR_WIDTH 1
-#define XG_PHY_INTR_LBN 9
-#define XG_PHY_INTR_WIDTH 1
-#define G_PHY1_INTR_LBN 8
-#define G_PHY1_INTR_WIDTH 1
-#define G_PHY0_INTR_LBN 7
-#define G_PHY0_INTR_WIDTH 1
-
-/* Driver-generated test events */
-#define EVQ_MAGIC_LBN 0
-#define EVQ_MAGIC_WIDTH 32
-
-/**************************************************************************
- *
- * Falcon MAC stats
- *
- **************************************************************************
- *
- */
-
-#define GRxGoodOct_offset 0x0
-#define GRxGoodOct_WIDTH 48
-#define GRxBadOct_offset 0x8
-#define GRxBadOct_WIDTH 48
-#define GRxMissPkt_offset 0x10
-#define GRxMissPkt_WIDTH 32
-#define GRxFalseCRS_offset 0x14
-#define GRxFalseCRS_WIDTH 32
-#define GRxPausePkt_offset 0x18
-#define GRxPausePkt_WIDTH 32
-#define GRxBadPkt_offset 0x1C
-#define GRxBadPkt_WIDTH 32
-#define GRxUcastPkt_offset 0x20
-#define GRxUcastPkt_WIDTH 32
-#define GRxMcastPkt_offset 0x24
-#define GRxMcastPkt_WIDTH 32
-#define GRxBcastPkt_offset 0x28
-#define GRxBcastPkt_WIDTH 32
-#define GRxGoodLt64Pkt_offset 0x2C
-#define GRxGoodLt64Pkt_WIDTH 32
-#define GRxBadLt64Pkt_offset 0x30
-#define GRxBadLt64Pkt_WIDTH 32
-#define GRx64Pkt_offset 0x34
-#define GRx64Pkt_WIDTH 32
-#define GRx65to127Pkt_offset 0x38
-#define GRx65to127Pkt_WIDTH 32
-#define GRx128to255Pkt_offset 0x3C
-#define GRx128to255Pkt_WIDTH 32
-#define GRx256to511Pkt_offset 0x40
-#define GRx256to511Pkt_WIDTH 32
-#define GRx512to1023Pkt_offset 0x44
-#define GRx512to1023Pkt_WIDTH 32
-#define GRx1024to15xxPkt_offset 0x48
-#define GRx1024to15xxPkt_WIDTH 32
-#define GRx15xxtoJumboPkt_offset 0x4C
-#define GRx15xxtoJumboPkt_WIDTH 32
-#define GRxGtJumboPkt_offset 0x50
-#define GRxGtJumboPkt_WIDTH 32
-#define GRxFcsErr64to15xxPkt_offset 0x54
-#define GRxFcsErr64to15xxPkt_WIDTH 32
-#define GRxFcsErr15xxtoJumboPkt_offset 0x58
-#define GRxFcsErr15xxtoJumboPkt_WIDTH 32
-#define GRxFcsErrGtJumboPkt_offset 0x5C
-#define GRxFcsErrGtJumboPkt_WIDTH 32
-#define GTxGoodBadOct_offset 0x80
-#define GTxGoodBadOct_WIDTH 48
-#define GTxGoodOct_offset 0x88
-#define GTxGoodOct_WIDTH 48
-#define GTxSglColPkt_offset 0x90
-#define GTxSglColPkt_WIDTH 32
-#define GTxMultColPkt_offset 0x94
-#define GTxMultColPkt_WIDTH 32
-#define GTxExColPkt_offset 0x98
-#define GTxExColPkt_WIDTH 32
-#define GTxDefPkt_offset 0x9C
-#define GTxDefPkt_WIDTH 32
-#define GTxLateCol_offset 0xA0
-#define GTxLateCol_WIDTH 32
-#define GTxExDefPkt_offset 0xA4
-#define GTxExDefPkt_WIDTH 32
-#define GTxPausePkt_offset 0xA8
-#define GTxPausePkt_WIDTH 32
-#define GTxBadPkt_offset 0xAC
-#define GTxBadPkt_WIDTH 32
-#define GTxUcastPkt_offset 0xB0
-#define GTxUcastPkt_WIDTH 32
-#define GTxMcastPkt_offset 0xB4
-#define GTxMcastPkt_WIDTH 32
-#define GTxBcastPkt_offset 0xB8
-#define GTxBcastPkt_WIDTH 32
-#define GTxLt64Pkt_offset 0xBC
-#define GTxLt64Pkt_WIDTH 32
-#define GTx64Pkt_offset 0xC0
-#define GTx64Pkt_WIDTH 32
-#define GTx65to127Pkt_offset 0xC4
-#define GTx65to127Pkt_WIDTH 32
-#define GTx128to255Pkt_offset 0xC8
-#define GTx128to255Pkt_WIDTH 32
-#define GTx256to511Pkt_offset 0xCC
-#define GTx256to511Pkt_WIDTH 32
-#define GTx512to1023Pkt_offset 0xD0
-#define GTx512to1023Pkt_WIDTH 32
-#define GTx1024to15xxPkt_offset 0xD4
-#define GTx1024to15xxPkt_WIDTH 32
-#define GTx15xxtoJumboPkt_offset 0xD8
-#define GTx15xxtoJumboPkt_WIDTH 32
-#define GTxGtJumboPkt_offset 0xDC
-#define GTxGtJumboPkt_WIDTH 32
-#define GTxNonTcpUdpPkt_offset 0xE0
-#define GTxNonTcpUdpPkt_WIDTH 16
-#define GTxMacSrcErrPkt_offset 0xE4
-#define GTxMacSrcErrPkt_WIDTH 16
-#define GTxIpSrcErrPkt_offset 0xE8
-#define GTxIpSrcErrPkt_WIDTH 16
-#define GDmaDone_offset 0xEC
-#define GDmaDone_WIDTH 32
-
-#define XgRxOctets_offset 0x0
-#define XgRxOctets_WIDTH 48
-#define XgRxOctetsOK_offset 0x8
-#define XgRxOctetsOK_WIDTH 48
-#define XgRxPkts_offset 0x10
-#define XgRxPkts_WIDTH 32
-#define XgRxPktsOK_offset 0x14
-#define XgRxPktsOK_WIDTH 32
-#define XgRxBroadcastPkts_offset 0x18
-#define XgRxBroadcastPkts_WIDTH 32
-#define XgRxMulticastPkts_offset 0x1C
-#define XgRxMulticastPkts_WIDTH 32
-#define XgRxUnicastPkts_offset 0x20
-#define XgRxUnicastPkts_WIDTH 32
-#define XgRxUndersizePkts_offset 0x24
-#define XgRxUndersizePkts_WIDTH 32
-#define XgRxOversizePkts_offset 0x28
-#define XgRxOversizePkts_WIDTH 32
-#define XgRxJabberPkts_offset 0x2C
-#define XgRxJabberPkts_WIDTH 32
-#define XgRxUndersizeFCSerrorPkts_offset 0x30
-#define XgRxUndersizeFCSerrorPkts_WIDTH 32
-#define XgRxDropEvents_offset 0x34
-#define XgRxDropEvents_WIDTH 32
-#define XgRxFCSerrorPkts_offset 0x38
-#define XgRxFCSerrorPkts_WIDTH 32
-#define XgRxAlignError_offset 0x3C
-#define XgRxAlignError_WIDTH 32
-#define XgRxSymbolError_offset 0x40
-#define XgRxSymbolError_WIDTH 32
-#define XgRxInternalMACError_offset 0x44
-#define XgRxInternalMACError_WIDTH 32
-#define XgRxControlPkts_offset 0x48
-#define XgRxControlPkts_WIDTH 32
-#define XgRxPausePkts_offset 0x4C
-#define XgRxPausePkts_WIDTH 32
-#define XgRxPkts64Octets_offset 0x50
-#define XgRxPkts64Octets_WIDTH 32
-#define XgRxPkts65to127Octets_offset 0x54
-#define XgRxPkts65to127Octets_WIDTH 32
-#define XgRxPkts128to255Octets_offset 0x58
-#define XgRxPkts128to255Octets_WIDTH 32
-#define XgRxPkts256to511Octets_offset 0x5C
-#define XgRxPkts256to511Octets_WIDTH 32
-#define XgRxPkts512to1023Octets_offset 0x60
-#define XgRxPkts512to1023Octets_WIDTH 32
-#define XgRxPkts1024to15xxOctets_offset 0x64
-#define XgRxPkts1024to15xxOctets_WIDTH 32
-#define XgRxPkts15xxtoMaxOctets_offset 0x68
-#define XgRxPkts15xxtoMaxOctets_WIDTH 32
-#define XgRxLengthError_offset 0x6C
-#define XgRxLengthError_WIDTH 32
-#define XgTxPkts_offset 0x80
-#define XgTxPkts_WIDTH 32
-#define XgTxOctets_offset 0x88
-#define XgTxOctets_WIDTH 48
-#define XgTxMulticastPkts_offset 0x90
-#define XgTxMulticastPkts_WIDTH 32
-#define XgTxBroadcastPkts_offset 0x94
-#define XgTxBroadcastPkts_WIDTH 32
-#define XgTxUnicastPkts_offset 0x98
-#define XgTxUnicastPkts_WIDTH 32
-#define XgTxControlPkts_offset 0x9C
-#define XgTxControlPkts_WIDTH 32
-#define XgTxPausePkts_offset 0xA0
-#define XgTxPausePkts_WIDTH 32
-#define XgTxPkts64Octets_offset 0xA4
-#define XgTxPkts64Octets_WIDTH 32
-#define XgTxPkts65to127Octets_offset 0xA8
-#define XgTxPkts65to127Octets_WIDTH 32
-#define XgTxPkts128to255Octets_offset 0xAC
-#define XgTxPkts128to255Octets_WIDTH 32
-#define XgTxPkts256to511Octets_offset 0xB0
-#define XgTxPkts256to511Octets_WIDTH 32
-#define XgTxPkts512to1023Octets_offset 0xB4
-#define XgTxPkts512to1023Octets_WIDTH 32
-#define XgTxPkts1024to15xxOctets_offset 0xB8
-#define XgTxPkts1024to15xxOctets_WIDTH 32
-#define XgTxPkts1519toMaxOctets_offset 0xBC
-#define XgTxPkts1519toMaxOctets_WIDTH 32
-#define XgTxUndersizePkts_offset 0xC0
-#define XgTxUndersizePkts_WIDTH 32
-#define XgTxOversizePkts_offset 0xC4
-#define XgTxOversizePkts_WIDTH 32
-#define XgTxNonTcpUdpPkt_offset 0xC8
-#define XgTxNonTcpUdpPkt_WIDTH 16
-#define XgTxMacSrcErrPkt_offset 0xCC
-#define XgTxMacSrcErrPkt_WIDTH 16
-#define XgTxIpSrcErrPkt_offset 0xD0
-#define XgTxIpSrcErrPkt_WIDTH 16
-#define XgDmaDone_offset 0xD4
-
-#define FALCON_STATS_NOT_DONE 0x00000000
-#define FALCON_STATS_DONE 0xffffffff
-
-/* Interrupt status register bits */
-#define FATAL_INT_LBN 64
-#define FATAL_INT_WIDTH 1
-#define INT_EVQS_LBN 40
-#define INT_EVQS_WIDTH 4
-
-/**************************************************************************
- *
- * Falcon non-volatile configuration
- *
- **************************************************************************
- */
-
-/* Board configuration v2 (v1 is obsolete; later versions are compatible) */
-struct falcon_nvconfig_board_v2 {
-	__le16 nports;
-	u8 port0_phy_addr;
-	u8 port0_phy_type;
-	u8 port1_phy_addr;
-	u8 port1_phy_type;
-	__le16 asic_sub_revision;
-	__le16 board_revision;
-} __packed;
-
-/* Board configuration v3 extra information */
-struct falcon_nvconfig_board_v3 {
-	__le32 spi_device_type[2];
-} __packed;
-
-/* Bit numbers for spi_device_type */
-#define SPI_DEV_TYPE_SIZE_LBN 0
-#define SPI_DEV_TYPE_SIZE_WIDTH 5
-#define SPI_DEV_TYPE_ADDR_LEN_LBN 6
-#define SPI_DEV_TYPE_ADDR_LEN_WIDTH 2
-#define SPI_DEV_TYPE_ERASE_CMD_LBN 8
-#define SPI_DEV_TYPE_ERASE_CMD_WIDTH 8
-#define SPI_DEV_TYPE_ERASE_SIZE_LBN 16
-#define SPI_DEV_TYPE_ERASE_SIZE_WIDTH 5
-#define SPI_DEV_TYPE_BLOCK_SIZE_LBN 24
-#define SPI_DEV_TYPE_BLOCK_SIZE_WIDTH 5
-#define SPI_DEV_TYPE_FIELD(type, field)					\
-	(((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field)))
-
-#define NVCONFIG_OFFSET 0x300
-
-#define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C
-struct falcon_nvconfig {
-	efx_oword_t ee_vpd_cfg_reg;			/* 0x300 */
-	u8 mac_address[2][8];			/* 0x310 */
-	efx_oword_t pcie_sd_ctl0123_reg;		/* 0x320 */
-	efx_oword_t pcie_sd_ctl45_reg;			/* 0x330 */
-	efx_oword_t pcie_pcs_ctl_stat_reg;		/* 0x340 */
-	efx_oword_t hw_init_reg;			/* 0x350 */
-	efx_oword_t nic_stat_reg;			/* 0x360 */
-	efx_oword_t glb_ctl_reg;			/* 0x370 */
-	efx_oword_t srm_cfg_reg;			/* 0x380 */
-	efx_oword_t spare_reg;				/* 0x390 */
-	__le16 board_magic_num;			/* 0x3A0 */
-	__le16 board_struct_ver;
-	__le16 board_checksum;
-	struct falcon_nvconfig_board_v2 board_v2;
-	efx_oword_t ee_base_page_reg;			/* 0x3B0 */
-	struct falcon_nvconfig_board_v3 board_v3;
-} __packed;
-
-#endif /* EFX_FALCON_HWDEFS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_io.h linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_io.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_FALCON_IO_H
-#define EFX_FALCON_IO_H
-
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
-/**************************************************************************
- *
- * Falcon hardware access
- *
- **************************************************************************
- *
- * Notes on locking strategy:
- *
- * Most Falcon registers require 16-byte (or 8-byte, for SRAM
- * registers) atomic writes which necessitates locking.
- * Under normal operation few writes to the Falcon BAR are made and these
- * registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and TX_DESC_UPD_REG) are special
- * cased to allow 4-byte (hence lockless) accesses.
- *
- * It *is* safe to write to these 4-byte registers in the middle of an
- * access to an 8-byte or 16-byte register.  We therefore use a
- * spinlock to protect accesses to the larger registers, but no locks
- * for the 4-byte registers.
- *
- * A write barrier is needed to ensure that DW3 is written after DW0/1/2
- * due to the way the 16byte registers are "collected" in the Falcon BIU
- *
- * We also lock when carrying out reads, to ensure consistency of the
- * data (made possible since the BIU reads all 128 bits into a cache).
- * Reads are very rare, so this isn't a significant performance
- * impact.  (Most data transferred from NIC to host is DMAed directly
- * into host memory).
- *
- * I/O BAR access uses locks for both reads and writes (but is only provided
- * for testing purposes).
- */
-
-/* Special buffer descriptors (Falcon SRAM) */
-#define BUF_TBL_KER_A1 0x18000
-#define BUF_TBL_KER_B0 0x800000
-
-
-#if BITS_PER_LONG == 64
-#define FALCON_USE_QWORD_IO 1
-#endif
-
-#ifdef FALCON_USE_QWORD_IO
-static inline void _falcon_writeq(struct efx_nic *efx, __le64 value,
-				  unsigned int reg)
-{
-	__raw_writeq((__force u64)value, efx->membase + reg);
-}
-static inline __le64 _falcon_readq(struct efx_nic *efx, unsigned int reg)
-{
-	return (__force __le64)__raw_readq(efx->membase + reg);
-}
-#endif
-
-static inline void _falcon_writel(struct efx_nic *efx, __le32 value,
-				  unsigned int reg)
-{
-	__raw_writel((__force u32)value, efx->membase + reg);
-}
-static inline __le32 _falcon_readl(struct efx_nic *efx, unsigned int reg)
-{
-	return (__force __le32)__raw_readl(efx->membase + reg);
-}
-
-/* Writes to a normal 16-byte Falcon register, locking as appropriate. */
-static inline void falcon_write(struct efx_nic *efx, efx_oword_t *value,
-				unsigned int reg)
-{
-	unsigned long flags;
-
-	EFX_REGDUMP(efx, "writing register %x with " EFX_OWORD_FMT "\n", reg,
-		    EFX_OWORD_VAL(*value));
-
-	spin_lock_irqsave(&efx->biu_lock, flags);
-#ifdef FALCON_USE_QWORD_IO
-	_falcon_writeq(efx, value->u64[0], reg + 0);
-	wmb();
-	_falcon_writeq(efx, value->u64[1], reg + 8);
-#else
-	_falcon_writel(efx, value->u32[0], reg + 0);
-	_falcon_writel(efx, value->u32[1], reg + 4);
-	_falcon_writel(efx, value->u32[2], reg + 8);
-	wmb();
-	_falcon_writel(efx, value->u32[3], reg + 12);
-#endif
-	mmiowb();
-	spin_unlock_irqrestore(&efx->biu_lock, flags);
-}
-
-/* Writes to an 8-byte Falcon SRAM register, locking as appropriate. */
-static inline void falcon_write_sram(struct efx_nic *efx, efx_qword_t *value,
-				     unsigned int index)
-{
-	unsigned int reg = efx->type->buf_tbl_base + (index * sizeof(*value));
-	unsigned long flags;
-
-	EFX_REGDUMP(efx, "writing SRAM register %x with " EFX_QWORD_FMT "\n",
-		    reg, EFX_QWORD_VAL(*value));
-
-	spin_lock_irqsave(&efx->biu_lock, flags);
-#ifdef FALCON_USE_QWORD_IO
-	_falcon_writeq(efx, value->u64[0], reg + 0);
-#else
-	_falcon_writel(efx, value->u32[0], reg + 0);
-	wmb();
-	_falcon_writel(efx, value->u32[1], reg + 4);
-#endif
-	mmiowb();
-	spin_unlock_irqrestore(&efx->biu_lock, flags);
-}
-
-/* Write dword to Falcon register that allows partial writes
- *
- * Some Falcon registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and
- * TX_DESC_UPD_REG) can be written to as a single dword.  This allows
- * for lockless writes.
- */
-static inline void falcon_writel(struct efx_nic *efx, efx_dword_t *value,
-				 unsigned int reg)
-{
-	EFX_REGDUMP(efx, "writing partial register %x with "EFX_DWORD_FMT"\n",
-		    reg, EFX_DWORD_VAL(*value));
-
-	/* No lock required */
-	_falcon_writel(efx, value->u32[0], reg);
-}
-
-/* Read from a Falcon register
- *
- * This reads an entire 16-byte Falcon register in one go, locking as
- * appropriate.  It is essential to read the first dword first, as this
- * prompts Falcon to load the current value into the shadow register.
- */
-static inline void falcon_read(struct efx_nic *efx, efx_oword_t *value,
-			       unsigned int reg)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&efx->biu_lock, flags);
-	value->u32[0] = _falcon_readl(efx, reg + 0);
-	rmb();
-	value->u32[1] = _falcon_readl(efx, reg + 4);
-	value->u32[2] = _falcon_readl(efx, reg + 8);
-	value->u32[3] = _falcon_readl(efx, reg + 12);
-	spin_unlock_irqrestore(&efx->biu_lock, flags);
-
-	EFX_REGDUMP(efx, "read from register %x, got " EFX_OWORD_FMT "\n", reg,
-		    EFX_OWORD_VAL(*value));
-}
-
-/* This reads an 8-byte Falcon SRAM entry in one go. */
-static inline void falcon_read_sram(struct efx_nic *efx, efx_qword_t *value,
-				    unsigned int index)
-{
-	unsigned int reg = efx->type->buf_tbl_base + (index * sizeof(*value));
-	unsigned long flags;
-
-	spin_lock_irqsave(&efx->biu_lock, flags);
-#ifdef FALCON_USE_QWORD_IO
-	value->u64[0] = _falcon_readq(efx, reg + 0);
-#else
-	value->u32[0] = _falcon_readl(efx, reg + 0);
-	rmb();
-	value->u32[1] = _falcon_readl(efx, reg + 4);
-#endif
-	spin_unlock_irqrestore(&efx->biu_lock, flags);
-
-	EFX_REGDUMP(efx, "read from SRAM register %x, got "EFX_QWORD_FMT"\n",
-		    reg, EFX_QWORD_VAL(*value));
-}
-
-/* Read dword from Falcon register that allows partial writes (sic) */
-static inline void falcon_readl(struct efx_nic *efx, efx_dword_t *value,
-				unsigned int reg)
-{
-	value->u32[0] = _falcon_readl(efx, reg);
-	EFX_REGDUMP(efx, "read from register %x, got "EFX_DWORD_FMT"\n",
-		    reg, EFX_DWORD_VAL(*value));
-}
-
-/* Write to a register forming part of a table */
-static inline void falcon_write_table(struct efx_nic *efx, efx_oword_t *value,
-				      unsigned int reg, unsigned int index)
-{
-	falcon_write(efx, value, reg + index * sizeof(efx_oword_t));
-}
-
-/* Read to a register forming part of a table */
-static inline void falcon_read_table(struct efx_nic *efx, efx_oword_t *value,
-				     unsigned int reg, unsigned int index)
-{
-	falcon_read(efx, value, reg + index * sizeof(efx_oword_t));
-}
-
-/* Write to a dword register forming part of a table */
-static inline void falcon_writel_table(struct efx_nic *efx, efx_dword_t *value,
-				       unsigned int reg, unsigned int index)
-{
-	falcon_writel(efx, value, reg + index * sizeof(efx_oword_t));
-}
-
-/* Page-mapped register block size */
-#define FALCON_PAGE_BLOCK_SIZE 0x2000
-
-/* Calculate offset to page-mapped register block */
-#define FALCON_PAGED_REG(page, reg) \
-	((page) * FALCON_PAGE_BLOCK_SIZE + (reg))
-
-/* As for falcon_write(), but for a page-mapped register. */
-static inline void falcon_write_page(struct efx_nic *efx, efx_oword_t *value,
-				     unsigned int reg, unsigned int page)
-{
-	falcon_write(efx, value, FALCON_PAGED_REG(page, reg));
-}
-
-/* As for falcon_writel(), but for a page-mapped register. */
-static inline void falcon_writel_page(struct efx_nic *efx, efx_dword_t *value,
-				      unsigned int reg, unsigned int page)
-{
-	falcon_writel(efx, value, FALCON_PAGED_REG(page, reg));
-}
-
-/* Write dword to Falcon page-mapped register with an extra lock.
- *
- * As for falcon_writel_page(), but for a register that suffers from
- * SFC bug 3181.  If writing to page 0, take out a lock so the BIU
- * collector cannot be confused.
- */
-static inline void falcon_writel_page_locked(struct efx_nic *efx,
-					     efx_dword_t *value,
-					     unsigned int reg,
-					     unsigned int page)
-{
-	unsigned long flags = 0;
-
-	if (page == 0)
-		spin_lock_irqsave(&efx->biu_lock, flags);
-	falcon_writel(efx, value, FALCON_PAGED_REG(page, reg));
-	if (page == 0)
-		spin_unlock_irqrestore(&efx->biu_lock, flags);
-}
-
-#endif /* EFX_FALCON_IO_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_xmac.c linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_xmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/falcon_xmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/falcon_xmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -11,13 +11,12 @@
 #include <linux/delay.h>
 #include "net_driver.h"
 #include "efx.h"
-#include "falcon.h"
-#include "falcon_hwdefs.h"
-#include "falcon_io.h"
+#include "nic.h"
+#include "regs.h"
+#include "io.h"
 #include "mac.h"
 #include "mdio_10g.h"
 #include "phy.h"
-#include "boards.h"
 #include "workarounds.h"
 
 /**************************************************************************
@@ -36,43 +35,47 @@ static void falcon_setup_xaui(struct efx
 	if (efx->phy_type == PHY_TYPE_NONE)
 		return;
 
-	falcon_read(efx, &sdctl, XX_SD_CTL_REG);
-	EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
-	EFX_SET_OWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
-	falcon_write(efx, &sdctl, XX_SD_CTL_REG);
+	efx_reado(efx, &sdctl, FR_AB_XX_SD_CTL);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVD, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVD, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVC, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVC, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVB, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVB, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_HIDRVA, FFE_AB_XX_SD_CTL_DRV_DEF);
+	EFX_SET_OWORD_FIELD(sdctl, FRF_AB_XX_LODRVA, FFE_AB_XX_SD_CTL_DRV_DEF);
+	efx_writeo(efx, &sdctl, FR_AB_XX_SD_CTL);
 
 	EFX_POPULATE_OWORD_8(txdrv,
-			     XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
-			     XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
-			     XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
-			     XX_DEQA, XX_TXDRV_DEQ_DEFAULT,
-			     XX_DTXD, XX_TXDRV_DTX_DEFAULT,
-			     XX_DTXC, XX_TXDRV_DTX_DEFAULT,
-			     XX_DTXB, XX_TXDRV_DTX_DEFAULT,
-			     XX_DTXA, XX_TXDRV_DTX_DEFAULT);
-	falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
+			     FRF_AB_XX_DEQD, FFE_AB_XX_TXDRV_DEQ_DEF,
+			     FRF_AB_XX_DEQC, FFE_AB_XX_TXDRV_DEQ_DEF,
+			     FRF_AB_XX_DEQB, FFE_AB_XX_TXDRV_DEQ_DEF,
+			     FRF_AB_XX_DEQA, FFE_AB_XX_TXDRV_DEQ_DEF,
+			     FRF_AB_XX_DTXD, FFE_AB_XX_TXDRV_DTX_DEF,
+			     FRF_AB_XX_DTXC, FFE_AB_XX_TXDRV_DTX_DEF,
+			     FRF_AB_XX_DTXB, FFE_AB_XX_TXDRV_DTX_DEF,
+			     FRF_AB_XX_DTXA, FFE_AB_XX_TXDRV_DTX_DEF);
+	efx_writeo(efx, &txdrv, FR_AB_XX_TXDRV_CTL);
 }
 
 int falcon_reset_xaui(struct efx_nic *efx)
 {
+	struct falcon_nic_data *nic_data = efx->nic_data;
 	efx_oword_t reg;
 	int count;
 
+	/* Don't fetch MAC statistics over an XMAC reset */
+	WARN_ON(nic_data->stats_disable_count == 0);
+
 	/* Start reset sequence */
-	EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
-	falcon_write(efx, &reg, XX_PWR_RST_REG);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_XX_RST_XX_EN, 1);
+	efx_writeo(efx, &reg, FR_AB_XX_PWR_RST);
 
 	/* Wait up to 10 ms for completion, then reinitialise */
 	for (count = 0; count < 1000; count++) {
-		falcon_read(efx, &reg, XX_PWR_RST_REG);
-		if (EFX_OWORD_FIELD(reg, XX_RST_XX_EN) == 0 &&
-		    EFX_OWORD_FIELD(reg, XX_SD_RST_ACT) == 0) {
+		efx_reado(efx, &reg, FR_AB_XX_PWR_RST);
+		if (EFX_OWORD_FIELD(reg, FRF_AB_XX_RST_XX_EN) == 0 &&
+		    EFX_OWORD_FIELD(reg, FRF_AB_XX_SD_RST_ACT) == 0) {
 			falcon_setup_xaui(efx);
 			return 0;
 		}
@@ -86,117 +89,118 @@ static void falcon_mask_status_intr(stru
 {
 	efx_oword_t reg;
 
-	if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
+	if ((efx_nic_rev(efx) != EFX_REV_FALCON_B0) || LOOPBACK_INTERNAL(efx))
 		return;
 
 	/* We expect xgmii faults if the wireside link is up */
-	if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
+	if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up)
 		return;
 
 	/* We can only use this interrupt to signal the negative edge of
 	 * xaui_align [we have to poll the positive edge]. */
-	if (!efx->mac_up)
+	if (efx->xmac_poll_required)
 		return;
 
 	/* Flush the ISR */
 	if (enable)
-		falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
+		efx_reado(efx, &reg, FR_AB_XM_MGT_INT_MSK);
 
 	EFX_POPULATE_OWORD_2(reg,
-			     XM_MSK_RMTFLT, !enable,
-			     XM_MSK_LCLFLT, !enable);
-	falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
+			     FRF_AB_XM_MSK_RMTFLT, !enable,
+			     FRF_AB_XM_MSK_LCLFLT, !enable);
+	efx_writeo(efx, &reg, FR_AB_XM_MGT_INT_MASK);
 }
 
-/* Get status of XAUI link */
-bool falcon_xaui_link_ok(struct efx_nic *efx)
+static bool falcon_xgxs_link_ok(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 	bool align_done, link_ok = false;
 	int sync_status;
 
-	if (LOOPBACK_INTERNAL(efx))
-		return true;
-
 	/* Read link status */
-	falcon_read(efx, &reg, XX_CORE_STAT_REG);
+	efx_reado(efx, &reg, FR_AB_XX_CORE_STAT);
 
-	align_done = EFX_OWORD_FIELD(reg, XX_ALIGN_DONE);
-	sync_status = EFX_OWORD_FIELD(reg, XX_SYNC_STAT);
-	if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED))
+	align_done = EFX_OWORD_FIELD(reg, FRF_AB_XX_ALIGN_DONE);
+	sync_status = EFX_OWORD_FIELD(reg, FRF_AB_XX_SYNC_STAT);
+	if (align_done && (sync_status == FFE_AB_XX_STAT_ALL_LANES))
 		link_ok = true;
 
 	/* Clear link status ready for next read */
-	EFX_SET_OWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
-	EFX_SET_OWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
-	EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
-	falcon_write(efx, &reg, XX_CORE_STAT_REG);
-
-	/* If the link is up, then check the phy side of the xaui link */
-	if (efx->link_up && link_ok)
-		if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
-			link_ok = efx_mdio_phyxgxs_lane_sync(efx);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_COMMA_DET, FFE_AB_XX_STAT_ALL_LANES);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_CHAR_ERR, FFE_AB_XX_STAT_ALL_LANES);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES);
+	efx_writeo(efx, &reg, FR_AB_XX_CORE_STAT);
 
 	return link_ok;
 }
 
-static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
+static bool falcon_xmac_link_ok(struct efx_nic *efx)
+{
+	/*
+	 * Check MAC's XGXS link status except when using XGMII loopback
+	 * which bypasses the XGXS block.
+	 * If possible, check PHY's XGXS link status except when using
+	 * MAC loopback.
+	 */
+	return (efx->loopback_mode == LOOPBACK_XGMII ||
+		falcon_xgxs_link_ok(efx)) &&
+		(!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) ||
+		 LOOPBACK_INTERNAL(efx) || 
+		 efx_mdio_phyxgxs_lane_sync(efx));
+}
+
+void falcon_reconfigure_xmac_core(struct efx_nic *efx)
 {
 	unsigned int max_frame_len;
 	efx_oword_t reg;
-	bool rx_fc = !!(efx->link_fc & EFX_FC_RX);
+	bool rx_fc = !!(efx->link_state.fc & EFX_FC_RX);
+	bool tx_fc = !!(efx->link_state.fc & EFX_FC_TX);
 
 	/* Configure MAC  - cut-thru mode is hard wired on */
-	EFX_POPULATE_DWORD_3(reg,
-			     XM_RX_JUMBO_MODE, 1,
-			     XM_TX_STAT_EN, 1,
-			     XM_RX_STAT_EN, 1);
-	falcon_write(efx, &reg, XM_GLB_CFG_REG);
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_AB_XM_RX_JUMBO_MODE, 1,
+			     FRF_AB_XM_TX_STAT_EN, 1,
+			     FRF_AB_XM_RX_STAT_EN, 1);
+	efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);
 
 	/* Configure TX */
-	EFX_POPULATE_DWORD_6(reg,
-			     XM_TXEN, 1,
-			     XM_TX_PRMBL, 1,
-			     XM_AUTO_PAD, 1,
-			     XM_TXCRC, 1,
-			     XM_FCNTL, 1,
-			     XM_IPG, 0x3);
-	falcon_write(efx, &reg, XM_TX_CFG_REG);
+	EFX_POPULATE_OWORD_6(reg,
+			     FRF_AB_XM_TXEN, 1,
+			     FRF_AB_XM_TX_PRMBL, 1,
+			     FRF_AB_XM_AUTO_PAD, 1,
+			     FRF_AB_XM_TXCRC, 1,
+			     FRF_AB_XM_FCNTL, tx_fc,
+			     FRF_AB_XM_IPG, 0x3);
+	efx_writeo(efx, &reg, FR_AB_XM_TX_CFG);
 
 	/* Configure RX */
-	EFX_POPULATE_DWORD_5(reg,
-			     XM_RXEN, 1,
-			     XM_AUTO_DEPAD, 0,
-			     XM_ACPT_ALL_MCAST, 1,
-			     XM_ACPT_ALL_UCAST, efx->promiscuous,
-			     XM_PASS_CRC_ERR, 1);
-	falcon_write(efx, &reg, XM_RX_CFG_REG);
+	EFX_POPULATE_OWORD_5(reg,
+			     FRF_AB_XM_RXEN, 1,
+			     FRF_AB_XM_AUTO_DEPAD, 0,
+			     FRF_AB_XM_ACPT_ALL_MCAST, 1,
+			     FRF_AB_XM_ACPT_ALL_UCAST, efx->promiscuous,
+			     FRF_AB_XM_PASS_CRC_ERR, 1);
+	efx_writeo(efx, &reg, FR_AB_XM_RX_CFG);
 
 	/* Set frame length */
 	max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
-	EFX_POPULATE_DWORD_1(reg, XM_MAX_RX_FRM_SIZE, max_frame_len);
-	falcon_write(efx, &reg, XM_RX_PARAM_REG);
-	EFX_POPULATE_DWORD_2(reg,
-			     XM_MAX_TX_FRM_SIZE, max_frame_len,
-			     XM_TX_JUMBO_MODE, 1);
-	falcon_write(efx, &reg, XM_TX_PARAM_REG);
+	EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_MAX_RX_FRM_SIZE, max_frame_len);
+	efx_writeo(efx, &reg, FR_AB_XM_RX_PARAM);
+	EFX_POPULATE_OWORD_2(reg,
+			     FRF_AB_XM_MAX_TX_FRM_SIZE, max_frame_len,
+			     FRF_AB_XM_TX_JUMBO_MODE, 1);
+	efx_writeo(efx, &reg, FR_AB_XM_TX_PARAM);
 
-	EFX_POPULATE_DWORD_2(reg,
-			     XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
-			     XM_DIS_FCNTL, !rx_fc);
-	falcon_write(efx, &reg, XM_FC_REG);
+	EFX_POPULATE_OWORD_2(reg,
+			     FRF_AB_XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
+			     FRF_AB_XM_DIS_FCNTL, !rx_fc);
+	efx_writeo(efx, &reg, FR_AB_XM_FC);
 
 	/* Set MAC address */
-	EFX_POPULATE_DWORD_4(reg,
-			     XM_ADR_0, efx->net_dev->dev_addr[0],
-			     XM_ADR_1, efx->net_dev->dev_addr[1],
-			     XM_ADR_2, efx->net_dev->dev_addr[2],
-			     XM_ADR_3, efx->net_dev->dev_addr[3]);
-	falcon_write(efx, &reg, XM_ADR_LO_REG);
-	EFX_POPULATE_DWORD_2(reg,
-			     XM_ADR_4, efx->net_dev->dev_addr[4],
-			     XM_ADR_5, efx->net_dev->dev_addr[5]);
-	falcon_write(efx, &reg, XM_ADR_HI_REG);
+	memcpy(&reg, &efx->net_dev->dev_addr[0], 4);
+	efx_writeo(efx, &reg, FR_AB_XM_ADR_LO);
+	memcpy(&reg, &efx->net_dev->dev_addr[4], 2);
+	efx_writeo(efx, &reg, FR_AB_XM_ADR_HI);
 }
 
 static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
@@ -212,12 +216,13 @@ static void falcon_reconfigure_xgxs_core
 		bool old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
 		bool reset_xgxs;
 
-		falcon_read(efx, &reg, XX_CORE_STAT_REG);
-		old_xgxs_loopback = EFX_OWORD_FIELD(reg, XX_XGXS_LB_EN);
-		old_xgmii_loopback = EFX_OWORD_FIELD(reg, XX_XGMII_LB_EN);
+		efx_reado(efx, &reg, FR_AB_XX_CORE_STAT);
+		old_xgxs_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN);
+		old_xgmii_loopback =
+			EFX_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN);
 
-		falcon_read(efx, &reg, XX_SD_CTL_REG);
-		old_xaui_loopback = EFX_OWORD_FIELD(reg, XX_LPBKA);
+		efx_reado(efx, &reg, FR_AB_XX_SD_CTL);
+		old_xaui_loopback = EFX_OWORD_FIELD(reg, FRF_AB_XX_LPBKA);
 
 		/* The PHY driver may have turned XAUI off */
 		reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
@@ -228,45 +233,55 @@ static void falcon_reconfigure_xgxs_core
 			falcon_reset_xaui(efx);
 	}
 
-	falcon_read(efx, &reg, XX_CORE_STAT_REG);
-	EFX_SET_OWORD_FIELD(reg, XX_FORCE_SIG,
+	efx_reado(efx, &reg, FR_AB_XX_CORE_STAT);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_FORCE_SIG,
 			    (xgxs_loopback || xaui_loopback) ?
-			    XX_FORCE_SIG_DECODE_FORCED : 0);
-	EFX_SET_OWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
-	EFX_SET_OWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
-	falcon_write(efx, &reg, XX_CORE_STAT_REG);
+			    FFE_AB_XX_FORCE_SIG_ALL_LANES : 0);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGXS_LB_EN, xgxs_loopback);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_XGMII_LB_EN, xgmii_loopback);
+	efx_writeo(efx, &reg, FR_AB_XX_CORE_STAT);
 
-	falcon_read(efx, &reg, XX_SD_CTL_REG);
-	EFX_SET_OWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
-	EFX_SET_OWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
-	EFX_SET_OWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
-	EFX_SET_OWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
-	falcon_write(efx, &reg, XX_SD_CTL_REG);
+	efx_reado(efx, &reg, FR_AB_XX_SD_CTL);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKD, xaui_loopback);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKC, xaui_loopback);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKB, xaui_loopback);
+	EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_LPBKA, xaui_loopback);
+	efx_writeo(efx, &reg, FR_AB_XX_SD_CTL);
 }
 
 
-/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
- * to come back up. Bash it until it comes back up */
-static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
+/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */
+static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries)
 {
-	efx->mac_up = falcon_xaui_link_ok(efx);
+	bool mac_up = falcon_xmac_link_ok(efx);
 
-	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
+	if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS ||
 	    efx_phy_mode_disabled(efx->phy_mode))
 		/* XAUI link is expected to be down */
-		return;
+		return mac_up;
 
-	while (!efx->mac_up && tries) {
+	falcon_stop_nic_stats(efx);
+
+	while (!mac_up && tries) {
 		EFX_LOG(efx, "bashing xaui\n");
 		falcon_reset_xaui(efx);
 		udelay(200);
 
-		efx->mac_up = falcon_xaui_link_ok(efx);
+		mac_up = falcon_xmac_link_ok(efx);
 		--tries;
 	}
+
+	falcon_start_nic_stats(efx);
+
+	return mac_up;
 }
 
-static void falcon_reconfigure_xmac(struct efx_nic *efx)
+static bool falcon_xmac_check_fault(struct efx_nic *efx)
+{
+	return !falcon_xmac_link_ok_retry(efx, 5);
+}
+
+static int falcon_reconfigure_xmac(struct efx_nic *efx)
 {
 	falcon_mask_status_intr(efx, false);
 
@@ -275,18 +290,15 @@ static void falcon_reconfigure_xmac(stru
 
 	falcon_reconfigure_mac_wrapper(efx);
 
-	falcon_check_xaui_link_up(efx, 5);
+	efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5);
 	falcon_mask_status_intr(efx, true);
+
+	return 0;
 }
 
 static void falcon_update_stats_xmac(struct efx_nic *efx)
 {
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
-	int rc;
-
-	rc = falcon_dma_stats(efx, XgDmaDone_offset);
-	if (rc)
-		return;
 
 	/* Update MAC stats from DMAed values */
 	FALCON_STAT(efx, XgRxOctets, rx_bytes);
@@ -344,35 +356,19 @@ static void falcon_update_stats_xmac(str
 		 mac_stats->rx_control * 64);
 }
 
-static void falcon_xmac_irq(struct efx_nic *efx)
-{
-	/* The XGMII link has a transient fault, which indicates either:
-	 *   - there's a transient xgmii fault
-	 *   - falcon's end of the xaui link may need a kick
-	 *   - the wire-side link may have gone down, but the lasi/poll()
-	 *     hasn't noticed yet.
-	 *
-	 * We only want to even bother polling XAUI if we're confident it's
-	 * not (1) or (3). In both cases, the only reliable way to spot this
-	 * is to wait a bit. We do this here by forcing the mac link state
-	 * to down, and waiting for the mac poll to come round and check
-	 */
-	efx->mac_up = false;
-}
-
-static void falcon_poll_xmac(struct efx_nic *efx)
+void falcon_poll_xmac(struct efx_nic *efx)
 {
-	if (!EFX_WORKAROUND_5147(efx) || !efx->link_up || efx->mac_up)
+	if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up ||
+	    !efx->xmac_poll_required)
 		return;
 
 	falcon_mask_status_intr(efx, false);
-	falcon_check_xaui_link_up(efx, 1);
+	efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1);
 	falcon_mask_status_intr(efx, true);
 }
 
 struct efx_mac_operations falcon_xmac_operations = {
 	.reconfigure	= falcon_reconfigure_xmac,
 	.update_stats	= falcon_update_stats_xmac,
-	.irq		= falcon_xmac_irq,
-	.poll		= falcon_poll_xmac,
+	.check_fault	= falcon_xmac_check_fault,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/gmii.h linux-libre-2.6.33-gnu1/drivers/net/sfc/gmii.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/gmii.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/gmii.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_GMII_H
-#define EFX_GMII_H
-
-/*
- * GMII interface
- */
-
-#include <linux/mii.h>
-
-/* GMII registers, excluding registers already defined as MII
- * registers in mii.h
- */
-#define GMII_IER		0x12	/* Interrupt enable register */
-#define GMII_ISR		0x13	/* Interrupt status register */
-
-/* Interrupt enable register */
-#define IER_ANEG_ERR		0x8000	/* Bit 15 - autonegotiation error */
-#define IER_SPEED_CHG		0x4000	/* Bit 14 - speed changed */
-#define IER_DUPLEX_CHG		0x2000	/* Bit 13 - duplex changed */
-#define IER_PAGE_RCVD		0x1000	/* Bit 12 - page received */
-#define IER_ANEG_DONE		0x0800	/* Bit 11 - autonegotiation complete */
-#define IER_LINK_CHG		0x0400	/* Bit 10 - link status changed */
-#define IER_SYM_ERR		0x0200	/* Bit 9 - symbol error */
-#define IER_FALSE_CARRIER	0x0100	/* Bit 8 - false carrier */
-#define IER_FIFO_ERR		0x0080	/* Bit 7 - FIFO over/underflow */
-#define IER_MDIX_CHG		0x0040	/* Bit 6 - MDI crossover changed */
-#define IER_DOWNSHIFT		0x0020	/* Bit 5 - downshift */
-#define IER_ENERGY		0x0010	/* Bit 4 - energy detect */
-#define IER_DTE_POWER		0x0004	/* Bit 2 - DTE power detect */
-#define IER_POLARITY_CHG	0x0002	/* Bit 1 - polarity changed */
-#define IER_JABBER		0x0001	/* Bit 0 - jabber */
-
-/* Interrupt status register */
-#define ISR_ANEG_ERR		0x8000	/* Bit 15 - autonegotiation error */
-#define ISR_SPEED_CHG		0x4000	/* Bit 14 - speed changed */
-#define ISR_DUPLEX_CHG		0x2000	/* Bit 13 - duplex changed */
-#define ISR_PAGE_RCVD		0x1000	/* Bit 12 - page received */
-#define ISR_ANEG_DONE		0x0800	/* Bit 11 - autonegotiation complete */
-#define ISR_LINK_CHG		0x0400	/* Bit 10 - link status changed */
-#define ISR_SYM_ERR		0x0200	/* Bit 9 - symbol error */
-#define ISR_FALSE_CARRIER	0x0100	/* Bit 8 - false carrier */
-#define ISR_FIFO_ERR		0x0080	/* Bit 7 - FIFO over/underflow */
-#define ISR_MDIX_CHG		0x0040	/* Bit 6 - MDI crossover changed */
-#define ISR_DOWNSHIFT		0x0020	/* Bit 5 - downshift */
-#define ISR_ENERGY		0x0010	/* Bit 4 - energy detect */
-#define ISR_DTE_POWER		0x0004	/* Bit 2 - DTE power detect */
-#define ISR_POLARITY_CHG	0x0002	/* Bit 1 - polarity changed */
-#define ISR_JABBER		0x0001	/* Bit 0 - jabber */
-
-#endif /* EFX_GMII_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/io.h linux-libre-2.6.33-gnu1/drivers/net/sfc/io.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/io.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef EFX_IO_H
+#define EFX_IO_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+/**************************************************************************
+ *
+ * NIC register I/O
+ *
+ **************************************************************************
+ *
+ * Notes on locking strategy:
+ *
+ * Most NIC registers require 16-byte (or 8-byte, for SRAM) atomic writes
+ * which necessitates locking.
+ * Under normal operation few writes to NIC registers are made and these
+ * registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and TX_DESC_UPD_REG) are special
+ * cased to allow 4-byte (hence lockless) accesses.
+ *
+ * It *is* safe to write to these 4-byte registers in the middle of an
+ * access to an 8-byte or 16-byte register.  We therefore use a
+ * spinlock to protect accesses to the larger registers, but no locks
+ * for the 4-byte registers.
+ *
+ * A write barrier is needed to ensure that DW3 is written after DW0/1/2
+ * due to the way the 16byte registers are "collected" in the BIU.
+ *
+ * We also lock when carrying out reads, to ensure consistency of the
+ * data (made possible since the BIU reads all 128 bits into a cache).
+ * Reads are very rare, so this isn't a significant performance
+ * impact.  (Most data transferred from NIC to host is DMAed directly
+ * into host memory).
+ *
+ * I/O BAR access uses locks for both reads and writes (but is only provided
+ * for testing purposes).
+ */
+
+#if BITS_PER_LONG == 64
+#define EFX_USE_QWORD_IO 1
+#endif
+
+#ifdef EFX_USE_QWORD_IO
+static inline void _efx_writeq(struct efx_nic *efx, __le64 value,
+				  unsigned int reg)
+{
+	__raw_writeq((__force u64)value, efx->membase + reg);
+}
+static inline __le64 _efx_readq(struct efx_nic *efx, unsigned int reg)
+{
+	return (__force __le64)__raw_readq(efx->membase + reg);
+}
+#endif
+
+static inline void _efx_writed(struct efx_nic *efx, __le32 value,
+				  unsigned int reg)
+{
+	__raw_writel((__force u32)value, efx->membase + reg);
+}
+static inline __le32 _efx_readd(struct efx_nic *efx, unsigned int reg)
+{
+	return (__force __le32)__raw_readl(efx->membase + reg);
+}
+
+/* Writes to a normal 16-byte Efx register, locking as appropriate. */
+static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value,
+			      unsigned int reg)
+{
+	unsigned long flags __attribute__ ((unused));
+
+	EFX_REGDUMP(efx, "writing register %x with " EFX_OWORD_FMT "\n", reg,
+		    EFX_OWORD_VAL(*value));
+
+	spin_lock_irqsave(&efx->biu_lock, flags);
+#ifdef EFX_USE_QWORD_IO
+	_efx_writeq(efx, value->u64[0], reg + 0);
+	wmb();
+	_efx_writeq(efx, value->u64[1], reg + 8);
+#else
+	_efx_writed(efx, value->u32[0], reg + 0);
+	_efx_writed(efx, value->u32[1], reg + 4);
+	_efx_writed(efx, value->u32[2], reg + 8);
+	wmb();
+	_efx_writed(efx, value->u32[3], reg + 12);
+#endif
+	mmiowb();
+	spin_unlock_irqrestore(&efx->biu_lock, flags);
+}
+
+/* Write an 8-byte NIC SRAM entry through the supplied mapping,
+ * locking as appropriate. */
+static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase,
+				   efx_qword_t *value, unsigned int index)
+{
+	unsigned int addr = index * sizeof(*value);
+	unsigned long flags __attribute__ ((unused));
+
+	EFX_REGDUMP(efx, "writing SRAM address %x with " EFX_QWORD_FMT "\n",
+		    addr, EFX_QWORD_VAL(*value));
+
+	spin_lock_irqsave(&efx->biu_lock, flags);
+#ifdef EFX_USE_QWORD_IO
+	__raw_writeq((__force u64)value->u64[0], membase + addr);
+#else
+	__raw_writel((__force u32)value->u32[0], membase + addr);
+	wmb();
+	__raw_writel((__force u32)value->u32[1], membase + addr + 4);
+#endif
+	mmiowb();
+	spin_unlock_irqrestore(&efx->biu_lock, flags);
+}
+
+/* Write dword to NIC register that allows partial writes
+ *
+ * Some registers (EVQ_RPTR_REG, RX_DESC_UPD_REG and
+ * TX_DESC_UPD_REG) can be written to as a single dword.  This allows
+ * for lockless writes.
+ */
+static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value,
+			      unsigned int reg)
+{
+	EFX_REGDUMP(efx, "writing partial register %x with "EFX_DWORD_FMT"\n",
+		    reg, EFX_DWORD_VAL(*value));
+
+	/* No lock required */
+	_efx_writed(efx, value->u32[0], reg);
+}
+
+/* Read from a NIC register
+ *
+ * This reads an entire 16-byte register in one go, locking as
+ * appropriate.  It is essential to read the first dword first, as this
+ * prompts the NIC to load the current value into the shadow register.
+ */
+static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value,
+			     unsigned int reg)
+{
+	unsigned long flags __attribute__ ((unused));
+
+	spin_lock_irqsave(&efx->biu_lock, flags);
+	value->u32[0] = _efx_readd(efx, reg + 0);
+	rmb();
+	value->u32[1] = _efx_readd(efx, reg + 4);
+	value->u32[2] = _efx_readd(efx, reg + 8);
+	value->u32[3] = _efx_readd(efx, reg + 12);
+	spin_unlock_irqrestore(&efx->biu_lock, flags);
+
+	EFX_REGDUMP(efx, "read from register %x, got " EFX_OWORD_FMT "\n", reg,
+		    EFX_OWORD_VAL(*value));
+}
+
+/* Read an 8-byte SRAM entry through supplied mapping,
+ * locking as appropriate. */
+static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase,
+				  efx_qword_t *value, unsigned int index)
+{
+	unsigned int addr = index * sizeof(*value);
+	unsigned long flags __attribute__ ((unused));
+
+	spin_lock_irqsave(&efx->biu_lock, flags);
+#ifdef EFX_USE_QWORD_IO
+	value->u64[0] = (__force __le64)__raw_readq(membase + addr);
+#else
+	value->u32[0] = (__force __le32)__raw_readl(membase + addr);
+	rmb();
+	value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4);
+#endif
+	spin_unlock_irqrestore(&efx->biu_lock, flags);
+
+	EFX_REGDUMP(efx, "read from SRAM address %x, got "EFX_QWORD_FMT"\n",
+		    addr, EFX_QWORD_VAL(*value));
+}
+
+/* Read dword from register that allows partial writes (sic) */
+static inline void efx_readd(struct efx_nic *efx, efx_dword_t *value,
+				unsigned int reg)
+{
+	value->u32[0] = _efx_readd(efx, reg);
+	EFX_REGDUMP(efx, "read from register %x, got "EFX_DWORD_FMT"\n",
+		    reg, EFX_DWORD_VAL(*value));
+}
+
+/* Write to a register forming part of a table */
+static inline void efx_writeo_table(struct efx_nic *efx, efx_oword_t *value,
+				      unsigned int reg, unsigned int index)
+{
+	efx_writeo(efx, value, reg + index * sizeof(efx_oword_t));
+}
+
+/* Read to a register forming part of a table */
+static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
+				     unsigned int reg, unsigned int index)
+{
+	efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
+}
+
+/* Write to a dword register forming part of a table */
+static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value,
+				       unsigned int reg, unsigned int index)
+{
+	efx_writed(efx, value, reg + index * sizeof(efx_oword_t));
+}
+
+/* Page-mapped register block size */
+#define EFX_PAGE_BLOCK_SIZE 0x2000
+
+/* Calculate offset to page-mapped register block */
+#define EFX_PAGED_REG(page, reg) \
+	((page) * EFX_PAGE_BLOCK_SIZE + (reg))
+
+/* As for efx_writeo(), but for a page-mapped register. */
+static inline void efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
+				   unsigned int reg, unsigned int page)
+{
+	efx_writeo(efx, value, EFX_PAGED_REG(page, reg));
+}
+
+/* As for efx_writed(), but for a page-mapped register. */
+static inline void efx_writed_page(struct efx_nic *efx, efx_dword_t *value,
+				   unsigned int reg, unsigned int page)
+{
+	efx_writed(efx, value, EFX_PAGED_REG(page, reg));
+}
+
+/* Write dword to page-mapped register with an extra lock.
+ *
+ * As for efx_writed_page(), but for a register that suffers from
+ * SFC bug 3181. Take out a lock so the BIU collector cannot be
+ * confused. */
+static inline void efx_writed_page_locked(struct efx_nic *efx,
+					  efx_dword_t *value,
+					  unsigned int reg,
+					  unsigned int page)
+{
+	unsigned long flags __attribute__ ((unused));
+
+	if (page == 0) {
+		spin_lock_irqsave(&efx->biu_lock, flags);
+		efx_writed(efx, value, EFX_PAGED_REG(page, reg));
+		spin_unlock_irqrestore(&efx->biu_lock, flags);
+	} else {
+		efx_writed(efx, value, EFX_PAGED_REG(page, reg));
+	}
+}
+
+#endif /* EFX_IO_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/Kconfig linux-libre-2.6.33-gnu1/drivers/net/sfc/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 config SFC
-	tristate "Solarflare Solarstorm SFC4000 support"
+	tristate "Solarflare Solarstorm SFC4000/SFC9000-family support"
 	depends on PCI && INET
 	select MDIO
 	select CRC32
@@ -7,15 +7,16 @@ config SFC
 	select I2C_ALGOBIT
 	help
 	  This driver supports 10-gigabit Ethernet cards based on
-	  the Solarflare Communications Solarstorm SFC4000 controller.
+	  the Solarflare Communications Solarstorm SFC4000 and
+	  SFC9000-family controllers.
 
 	  To compile this driver as a module, choose M here.  The module
 	  will be called sfc.
 config SFC_MTD
-	bool "Solarflare Solarstorm SFC4000 flash MTD support"
+	bool "Solarflare Solarstorm SFC4000/SFC9000-family MTD support"
 	depends on SFC && MTD && !(SFC=y && MTD=m)
 	default y
 	help
-	  This exposes the on-board flash memory as an MTD device (e.g.
-          /dev/mtd1).  This makes it possible to upload new boot code
-          to the NIC.
+	  This exposes the on-board flash memory as MTD devices (e.g.
+	  /dev/mtd1).  This makes it possible to upload new firmware
+	  to the NIC.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mac.h linux-libre-2.6.33-gnu1/drivers/net/sfc/mac.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mac.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -15,5 +15,9 @@
 
 extern struct efx_mac_operations falcon_gmac_operations;
 extern struct efx_mac_operations falcon_xmac_operations;
+extern struct efx_mac_operations efx_mcdi_mac_operations;
+extern void falcon_reconfigure_xmac_core(struct efx_nic *efx);
+extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
+			      u32 dma_len, int enable, int clear);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/Makefile linux-libre-2.6.33-gnu1/drivers/net/sfc/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,7 @@
-sfc-y			+= efx.o falcon.o tx.o rx.o falcon_gmac.o \
-			   falcon_xmac.o selftest.o ethtool.o xfp_phy.o \
-			   mdio_10g.o tenxpress.o boards.o sfe4001.o
+sfc-y			+= efx.o nic.o falcon.o siena.o tx.o rx.o \
+			   falcon_gmac.o falcon_xmac.o mcdi_mac.o \
+			   selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
+			   tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o
 sfc-$(CONFIG_SFC_MTD)	+= mtd.o
 
 obj-$(CONFIG_SFC)	+= sfc.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi.c linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1114 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2008-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/delay.h>
+#include "net_driver.h"
+#include "nic.h"
+#include "io.h"
+#include "regs.h"
+#include "mcdi_pcol.h"
+#include "phy.h"
+
+/**************************************************************************
+ *
+ * Management-Controller-to-Driver Interface
+ *
+ **************************************************************************
+ */
+
+/* Software-defined structure to the shared-memory */
+#define CMD_NOTIFY_PORT0 0
+#define CMD_NOTIFY_PORT1 4
+#define CMD_PDU_PORT0    0x008
+#define CMD_PDU_PORT1    0x108
+#define REBOOT_FLAG_PORT0 0x3f8
+#define REBOOT_FLAG_PORT1 0x3fc
+
+#define MCDI_RPC_TIMEOUT       10 /*seconds */
+
+#define MCDI_PDU(efx)							\
+	(efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0)
+#define MCDI_DOORBELL(efx)						\
+	(efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0)
+#define MCDI_REBOOT_FLAG(efx)						\
+	(efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0)
+
+#define SEQ_MASK							\
+	EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ))
+
+static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
+{
+	struct siena_nic_data *nic_data;
+	EFX_BUG_ON_PARANOID(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
+	nic_data = efx->nic_data;
+	return &nic_data->mcdi;
+}
+
+void efx_mcdi_init(struct efx_nic *efx)
+{
+	struct efx_mcdi_iface *mcdi;
+
+	if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
+		return;
+
+	mcdi = efx_mcdi(efx);
+	init_waitqueue_head(&mcdi->wq);
+	spin_lock_init(&mcdi->iface_lock);
+	atomic_set(&mcdi->state, MCDI_STATE_QUIESCENT);
+	mcdi->mode = MCDI_MODE_POLL;
+
+	(void) efx_mcdi_poll_reboot(efx);
+}
+
+static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
+			    const u8 *inbuf, size_t inlen)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+	unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
+	unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
+	unsigned int i;
+	efx_dword_t hdr;
+	u32 xflags, seqno;
+
+	BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
+	BUG_ON(inlen & 3 || inlen >= 0x100);
+
+	seqno = mcdi->seqno & SEQ_MASK;
+	xflags = 0;
+	if (mcdi->mode == MCDI_MODE_EVENTS)
+		xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+	EFX_POPULATE_DWORD_6(hdr,
+			     MCDI_HEADER_RESPONSE, 0,
+			     MCDI_HEADER_RESYNC, 1,
+			     MCDI_HEADER_CODE, cmd,
+			     MCDI_HEADER_DATALEN, inlen,
+			     MCDI_HEADER_SEQ, seqno,
+			     MCDI_HEADER_XFLAGS, xflags);
+
+	efx_writed(efx, &hdr, pdu);
+
+	for (i = 0; i < inlen; i += 4)
+		_efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i);
+
+	/* Ensure the payload is written out before the header */
+	wmb();
+
+	/* ring the doorbell with a distinctive value */
+	_efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
+}
+
+static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+	unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
+	int i;
+
+	BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
+	BUG_ON(outlen & 3 || outlen >= 0x100);
+
+	for (i = 0; i < outlen; i += 4)
+		*((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
+}
+
+static int efx_mcdi_poll(struct efx_nic *efx)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+	unsigned int time, finish;
+	unsigned int respseq, respcmd, error;
+	unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
+	unsigned int rc, spins;
+	efx_dword_t reg;
+
+	/* Check for a reboot atomically with respect to efx_mcdi_copyout() */
+	rc = -efx_mcdi_poll_reboot(efx);
+	if (rc)
+		goto out;
+
+	/* Poll for completion. Poll quickly (once a us) for the 1st jiffy,
+	 * because generally mcdi responses are fast. After that, back off
+	 * and poll once a jiffy (approximately)
+	 */
+	spins = TICK_USEC;
+	finish = get_seconds() + MCDI_RPC_TIMEOUT;
+
+	while (1) {
+		if (spins != 0) {
+			--spins;
+			udelay(1);
+		} else {
+			schedule_timeout_uninterruptible(1);
+		}
+
+		time = get_seconds();
+
+		rmb();
+		efx_readd(efx, &reg, pdu);
+
+		/* All 1's indicates that shared memory is in reset (and is
+		 * not a valid header). Wait for it to come out reset before
+		 * completing the command */
+		if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) != 0xffffffff &&
+		    EFX_DWORD_FIELD(reg, MCDI_HEADER_RESPONSE))
+			break;
+
+		if (time >= finish)
+			return -ETIMEDOUT;
+	}
+
+	mcdi->resplen = EFX_DWORD_FIELD(reg, MCDI_HEADER_DATALEN);
+	respseq = EFX_DWORD_FIELD(reg, MCDI_HEADER_SEQ);
+	respcmd = EFX_DWORD_FIELD(reg, MCDI_HEADER_CODE);
+	error = EFX_DWORD_FIELD(reg, MCDI_HEADER_ERROR);
+
+	if (error && mcdi->resplen == 0) {
+		EFX_ERR(efx, "MC rebooted\n");
+		rc = EIO;
+	} else if ((respseq ^ mcdi->seqno) & SEQ_MASK) {
+		EFX_ERR(efx, "MC response mismatch tx seq 0x%x rx seq 0x%x\n",
+			respseq, mcdi->seqno);
+		rc = EIO;
+	} else if (error) {
+		efx_readd(efx, &reg, pdu + 4);
+		switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) {
+#define TRANSLATE_ERROR(name)					\
+		case MC_CMD_ERR_ ## name:			\
+			rc = name;				\
+			break
+			TRANSLATE_ERROR(ENOENT);
+			TRANSLATE_ERROR(EINTR);
+			TRANSLATE_ERROR(EACCES);
+			TRANSLATE_ERROR(EBUSY);
+			TRANSLATE_ERROR(EINVAL);
+			TRANSLATE_ERROR(EDEADLK);
+			TRANSLATE_ERROR(ENOSYS);
+			TRANSLATE_ERROR(ETIME);
+#undef TRANSLATE_ERROR
+		default:
+			rc = EIO;
+			break;
+		}
+	} else
+		rc = 0;
+
+out:
+	mcdi->resprc = rc;
+	if (rc)
+		mcdi->resplen = 0;
+
+	/* Return rc=0 like wait_event_timeout() */
+	return 0;
+}
+
+/* Test and clear MC-rebooted flag for this port/function */
+int efx_mcdi_poll_reboot(struct efx_nic *efx)
+{
+	unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx);
+	efx_dword_t reg;
+	uint32_t value;
+
+	if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
+		return false;
+
+	efx_readd(efx, &reg, addr);
+	value = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
+
+	if (value == 0)
+		return 0;
+
+	EFX_ZERO_DWORD(reg);
+	efx_writed(efx, &reg, addr);
+
+	if (value == MC_STATUS_DWORD_ASSERT)
+		return -EINTR;
+	else
+		return -EIO;
+}
+
+static void efx_mcdi_acquire(struct efx_mcdi_iface *mcdi)
+{
+	/* Wait until the interface becomes QUIESCENT and we win the race
+	 * to mark it RUNNING. */
+	wait_event(mcdi->wq,
+		   atomic_cmpxchg(&mcdi->state,
+				  MCDI_STATE_QUIESCENT,
+				  MCDI_STATE_RUNNING)
+		   == MCDI_STATE_QUIESCENT);
+}
+
+static int efx_mcdi_await_completion(struct efx_nic *efx)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+	if (wait_event_timeout(
+		    mcdi->wq,
+		    atomic_read(&mcdi->state) == MCDI_STATE_COMPLETED,
+		    msecs_to_jiffies(MCDI_RPC_TIMEOUT * 1000)) == 0)
+		return -ETIMEDOUT;
+
+	/* Check if efx_mcdi_set_mode() switched us back to polled completions.
+	 * In which case, poll for completions directly. If efx_mcdi_ev_cpl()
+	 * completed the request first, then we'll just end up completing the
+	 * request again, which is safe.
+	 *
+	 * We need an smp_rmb() to synchronise with efx_mcdi_mode_poll(), which
+	 * wait_event_timeout() implicitly provides.
+	 */
+	if (mcdi->mode == MCDI_MODE_POLL)
+		return efx_mcdi_poll(efx);
+
+	return 0;
+}
+
+static bool efx_mcdi_complete(struct efx_mcdi_iface *mcdi)
+{
+	/* If the interface is RUNNING, then move to COMPLETED and wake any
+	 * waiters. If the interface isn't in RUNNING then we've received a
+	 * duplicate completion after we've already transitioned back to
+	 * QUIESCENT. [A subsequent invocation would increment seqno, so would
+	 * have failed the seqno check].
+	 */
+	if (atomic_cmpxchg(&mcdi->state,
+			   MCDI_STATE_RUNNING,
+			   MCDI_STATE_COMPLETED) == MCDI_STATE_RUNNING) {
+		wake_up(&mcdi->wq);
+		return true;
+	}
+
+	return false;
+}
+
+static void efx_mcdi_release(struct efx_mcdi_iface *mcdi)
+{
+	atomic_set(&mcdi->state, MCDI_STATE_QUIESCENT);
+	wake_up(&mcdi->wq);
+}
+
+static void efx_mcdi_ev_cpl(struct efx_nic *efx, unsigned int seqno,
+			    unsigned int datalen, unsigned int errno)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+	bool wake = false;
+
+	spin_lock(&mcdi->iface_lock);
+
+	if ((seqno ^ mcdi->seqno) & SEQ_MASK) {
+		if (mcdi->credits)
+			/* The request has been cancelled */
+			--mcdi->credits;
+		else
+			EFX_ERR(efx, "MC response mismatch tx seq 0x%x rx "
+				"seq 0x%x\n", seqno, mcdi->seqno);
+	} else {
+		mcdi->resprc = errno;
+		mcdi->resplen = datalen;
+
+		wake = true;
+	}
+
+	spin_unlock(&mcdi->iface_lock);
+
+	if (wake)
+		efx_mcdi_complete(mcdi);
+}
+
+/* Issue the given command by writing the data into the shared memory PDU,
+ * ring the doorbell and wait for completion. Copyout the result. */
+int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
+		 const u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen,
+		 size_t *outlen_actual)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+	int rc;
+	BUG_ON(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
+
+	efx_mcdi_acquire(mcdi);
+
+	/* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
+	spin_lock_bh(&mcdi->iface_lock);
+	++mcdi->seqno;
+	spin_unlock_bh(&mcdi->iface_lock);
+
+	efx_mcdi_copyin(efx, cmd, inbuf, inlen);
+
+	if (mcdi->mode == MCDI_MODE_POLL)
+		rc = efx_mcdi_poll(efx);
+	else
+		rc = efx_mcdi_await_completion(efx);
+
+	if (rc != 0) {
+		/* Close the race with efx_mcdi_ev_cpl() executing just too late
+		 * and completing a request we've just cancelled, by ensuring
+		 * that the seqno check therein fails.
+		 */
+		spin_lock_bh(&mcdi->iface_lock);
+		++mcdi->seqno;
+		++mcdi->credits;
+		spin_unlock_bh(&mcdi->iface_lock);
+
+		EFX_ERR(efx, "MC command 0x%x inlen %d mode %d timed out\n",
+			cmd, (int)inlen, mcdi->mode);
+	} else {
+		size_t resplen;
+
+		/* At the very least we need a memory barrier here to ensure
+		 * we pick up changes from efx_mcdi_ev_cpl(). Protect against
+		 * a spurious efx_mcdi_ev_cpl() running concurrently by
+		 * acquiring the iface_lock. */
+		spin_lock_bh(&mcdi->iface_lock);
+		rc = -mcdi->resprc;
+		resplen = mcdi->resplen;
+		spin_unlock_bh(&mcdi->iface_lock);
+
+		if (rc == 0) {
+			efx_mcdi_copyout(efx, outbuf,
+					 min(outlen, mcdi->resplen + 3) & ~0x3);
+			if (outlen_actual != NULL)
+				*outlen_actual = resplen;
+		} else if (cmd == MC_CMD_REBOOT && rc == -EIO)
+			; /* Don't reset if MC_CMD_REBOOT returns EIO */
+		else if (rc == -EIO || rc == -EINTR) {
+			EFX_ERR(efx, "MC fatal error %d\n", -rc);
+			efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
+		} else
+			EFX_ERR(efx, "MC command 0x%x inlen %d failed rc=%d\n",
+				cmd, (int)inlen, -rc);
+	}
+
+	efx_mcdi_release(mcdi);
+	return rc;
+}
+
+void efx_mcdi_mode_poll(struct efx_nic *efx)
+{
+	struct efx_mcdi_iface *mcdi;
+
+	if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
+		return;
+
+	mcdi = efx_mcdi(efx);
+	if (mcdi->mode == MCDI_MODE_POLL)
+		return;
+
+	/* We can switch from event completion to polled completion, because
+	 * mcdi requests are always completed in shared memory. We do this by
+	 * switching the mode to POLL'd then completing the request.
+	 * efx_mcdi_await_completion() will then call efx_mcdi_poll().
+	 *
+	 * We need an smp_wmb() to synchronise with efx_mcdi_await_completion(),
+	 * which efx_mcdi_complete() provides for us.
+	 */
+	mcdi->mode = MCDI_MODE_POLL;
+
+	efx_mcdi_complete(mcdi);
+}
+
+void efx_mcdi_mode_event(struct efx_nic *efx)
+{
+	struct efx_mcdi_iface *mcdi;
+
+	if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
+		return;
+
+	mcdi = efx_mcdi(efx);
+
+	if (mcdi->mode == MCDI_MODE_EVENTS)
+		return;
+
+	/* We can't switch from polled to event completion in the middle of a
+	 * request, because the completion method is specified in the request.
+	 * So acquire the interface to serialise the requestors. We don't need
+	 * to acquire the iface_lock to change the mode here, but we do need a
+	 * write memory barrier ensure that efx_mcdi_rpc() sees it, which
+	 * efx_mcdi_acquire() provides.
+	 */
+	efx_mcdi_acquire(mcdi);
+	mcdi->mode = MCDI_MODE_EVENTS;
+	efx_mcdi_release(mcdi);
+}
+
+static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
+{
+	struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+	/* If there is an outstanding MCDI request, it has been terminated
+	 * either by a BADASSERT or REBOOT event. If the mcdi interface is
+	 * in polled mode, then do nothing because the MC reboot handler will
+	 * set the header correctly. However, if the mcdi interface is waiting
+	 * for a CMDDONE event it won't receive it [and since all MCDI events
+	 * are sent to the same queue, we can't be racing with
+	 * efx_mcdi_ev_cpl()]
+	 *
+	 * There's a race here with efx_mcdi_rpc(), because we might receive
+	 * a REBOOT event *before* the request has been copied out. In polled
+	 * mode (during startup) this is irrelevent, because efx_mcdi_complete()
+	 * is ignored. In event mode, this condition is just an edge-case of
+	 * receiving a REBOOT event after posting the MCDI request. Did the mc
+	 * reboot before or after the copyout? The best we can do always is
+	 * just return failure.
+	 */
+	spin_lock(&mcdi->iface_lock);
+	if (efx_mcdi_complete(mcdi)) {
+		if (mcdi->mode == MCDI_MODE_EVENTS) {
+			mcdi->resprc = rc;
+			mcdi->resplen = 0;
+		}
+	} else
+		/* Nobody was waiting for an MCDI request, so trigger a reset */
+		efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
+
+	spin_unlock(&mcdi->iface_lock);
+}
+
+static unsigned int efx_mcdi_event_link_speed[] = {
+	[MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
+	[MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
+	[MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
+};
+
+
+static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
+{
+	u32 flags, fcntl, speed, lpa;
+
+	speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
+	EFX_BUG_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
+	speed = efx_mcdi_event_link_speed[speed];
+
+	flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
+	fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
+	lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);
+
+	/* efx->link_state is only modified by efx_mcdi_phy_get_link(),
+	 * which is only run after flushing the event queues. Therefore, it
+	 * is safe to modify the link state outside of the mac_lock here.
+	 */
+	efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);
+
+	efx_mcdi_phy_check_fcntl(efx, lpa);
+
+	efx_link_status_changed(efx);
+}
+
+static const char *sensor_names[] = {
+	[MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor",
+	[MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor",
+	[MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling",
+	[MC_CMD_SENSOR_PHY0_TEMP] = "PHY 0 temp. sensor",
+	[MC_CMD_SENSOR_PHY0_COOLING] = "PHY 0 cooling",
+	[MC_CMD_SENSOR_PHY1_TEMP] = "PHY 1 temp. sensor",
+	[MC_CMD_SENSOR_PHY1_COOLING] = "PHY 1 cooling",
+	[MC_CMD_SENSOR_IN_1V0] = "1.0V supply sensor",
+	[MC_CMD_SENSOR_IN_1V2] = "1.2V supply sensor",
+	[MC_CMD_SENSOR_IN_1V8] = "1.8V supply sensor",
+	[MC_CMD_SENSOR_IN_2V5] = "2.5V supply sensor",
+	[MC_CMD_SENSOR_IN_3V3] = "3.3V supply sensor",
+	[MC_CMD_SENSOR_IN_12V0] = "12V supply sensor"
+};
+
+static const char *sensor_status_names[] = {
+	[MC_CMD_SENSOR_STATE_OK] = "OK",
+	[MC_CMD_SENSOR_STATE_WARNING] = "Warning",
+	[MC_CMD_SENSOR_STATE_FATAL] = "Fatal",
+	[MC_CMD_SENSOR_STATE_BROKEN] = "Device failure",
+};
+
+static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
+{
+	unsigned int monitor, state, value;
+	const char *name, *state_txt;
+	monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR);
+	state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE);
+	value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE);
+	/* Deal gracefully with the board having more drivers than we
+	 * know about, but do not expect new sensor states. */
+	name = (monitor >= ARRAY_SIZE(sensor_names))
+				    ? "No sensor name available" :
+				    sensor_names[monitor];
+	EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names));
+	state_txt = sensor_status_names[state];
+
+	EFX_ERR(efx, "Sensor %d (%s) reports condition '%s' for raw value %d\n",
+		monitor, name, state_txt, value);
+}
+
+/* Called from  falcon_process_eventq for MCDI events */
+void efx_mcdi_process_event(struct efx_channel *channel,
+			    efx_qword_t *event)
+{
+	struct efx_nic *efx = channel->efx;
+	int code = EFX_QWORD_FIELD(*event, MCDI_EVENT_CODE);
+	u32 data = EFX_QWORD_FIELD(*event, MCDI_EVENT_DATA);
+
+	switch (code) {
+	case MCDI_EVENT_CODE_BADSSERT:
+		EFX_ERR(efx, "MC watchdog or assertion failure at 0x%x\n", data);
+		efx_mcdi_ev_death(efx, EINTR);
+		break;
+
+	case MCDI_EVENT_CODE_PMNOTICE:
+		EFX_INFO(efx, "MCDI PM event.\n");
+		break;
+
+	case MCDI_EVENT_CODE_CMDDONE:
+		efx_mcdi_ev_cpl(efx,
+				MCDI_EVENT_FIELD(*event, CMDDONE_SEQ),
+				MCDI_EVENT_FIELD(*event, CMDDONE_DATALEN),
+				MCDI_EVENT_FIELD(*event, CMDDONE_ERRNO));
+		break;
+
+	case MCDI_EVENT_CODE_LINKCHANGE:
+		efx_mcdi_process_link_change(efx, event);
+		break;
+	case MCDI_EVENT_CODE_SENSOREVT:
+		efx_mcdi_sensor_event(efx, event);
+		break;
+	case MCDI_EVENT_CODE_SCHEDERR:
+		EFX_INFO(efx, "MC Scheduler error address=0x%x\n", data);
+		break;
+	case MCDI_EVENT_CODE_REBOOT:
+		EFX_INFO(efx, "MC Reboot\n");
+		efx_mcdi_ev_death(efx, EIO);
+		break;
+	case MCDI_EVENT_CODE_MAC_STATS_DMA:
+		/* MAC stats are gather lazily.  We can ignore this. */
+		break;
+
+	default:
+		EFX_ERR(efx, "Unknown MCDI event 0x%x\n", code);
+	}
+}
+
+/**************************************************************************
+ *
+ * Specific request functions
+ *
+ **************************************************************************
+ */
+
+int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build)
+{
+	u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)];
+	size_t outlength;
+	const __le16 *ver_words;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_VERSION_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_VERSION, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlength);
+	if (rc)
+		goto fail;
+
+	if (outlength == MC_CMD_GET_VERSION_V0_OUT_LEN) {
+		*version = 0;
+		*build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE);
+		return 0;
+	}
+
+	if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION);
+	*version = (((u64)le16_to_cpu(ver_words[0]) << 48) |
+		    ((u64)le16_to_cpu(ver_words[1]) << 32) |
+		    ((u64)le16_to_cpu(ver_words[2]) << 16) |
+		    le16_to_cpu(ver_words[3]));
+	*build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE);
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
+			bool *was_attached)
+{
+	u8 inbuf[MC_CMD_DRV_ATTACH_IN_LEN];
+	u8 outbuf[MC_CMD_DRV_ATTACH_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, DRV_ATTACH_IN_NEW_STATE,
+		       driver_operating ? 1 : 0);
+	MCDI_SET_DWORD(inbuf, DRV_ATTACH_IN_UPDATE, 1);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_DRV_ATTACH, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+	if (outlen < MC_CMD_DRV_ATTACH_OUT_LEN)
+		goto fail;
+
+	if (was_attached != NULL)
+		*was_attached = MCDI_DWORD(outbuf, DRV_ATTACH_OUT_OLD_STATE);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
+			   u16 *fw_subtype_list)
+{
+	uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN];
+	size_t outlen;
+	int port_num = efx_port_num(efx);
+	int offset;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_BOARD_CFG, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	offset = (port_num)
+		? MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST
+		: MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST;
+	if (mac_address)
+		memcpy(mac_address, outbuf + offset, ETH_ALEN);
+	if (fw_subtype_list)
+		memcpy(fw_subtype_list,
+		       outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST,
+		       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN);
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d len=%d\n", __func__, rc, (int)outlen);
+
+	return rc;
+}
+
+int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq)
+{
+	u8 inbuf[MC_CMD_LOG_CTRL_IN_LEN];
+	u32 dest = 0;
+	int rc;
+
+	if (uart)
+		dest |= MC_CMD_LOG_CTRL_IN_LOG_DEST_UART;
+	if (evq)
+		dest |= MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ;
+
+	MCDI_SET_DWORD(inbuf, LOG_CTRL_IN_LOG_DEST, dest);
+	MCDI_SET_DWORD(inbuf, LOG_CTRL_IN_LOG_DEST_EVQ, dest_evq);
+
+	BUILD_BUG_ON(MC_CMD_LOG_CTRL_OUT_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_LOG_CTRL, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out)
+{
+	u8 outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_NVRAM_TYPES_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_TYPES, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+	if (outlen < MC_CMD_NVRAM_TYPES_OUT_LEN)
+		goto fail;
+
+	*nvram_types_out = MCDI_DWORD(outbuf, NVRAM_TYPES_OUT_TYPES);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n",
+		__func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
+			size_t *size_out, size_t *erase_size_out,
+			bool *protected_out)
+{
+	u8 inbuf[MC_CMD_NVRAM_INFO_IN_LEN];
+	u8 outbuf[MC_CMD_NVRAM_INFO_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_INFO_IN_TYPE, type);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_INFO, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+	if (outlen < MC_CMD_NVRAM_INFO_OUT_LEN)
+		goto fail;
+
+	*size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE);
+	*erase_size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE);
+	*protected_out = !!(MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) &
+				(1 << MC_CMD_NVRAM_PROTECTED_LBN));
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_update_start(struct efx_nic *efx, unsigned int type)
+{
+	u8 inbuf[MC_CMD_NVRAM_UPDATE_START_IN_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_START_IN_TYPE, type);
+
+	BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_START_OUT_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_START, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
+			loff_t offset, u8 *buffer, size_t length)
+{
+	u8 inbuf[MC_CMD_NVRAM_READ_IN_LEN];
+	u8 outbuf[MC_CMD_NVRAM_READ_OUT_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_TYPE, type);
+	MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_OFFSET, offset);
+	MCDI_SET_DWORD(inbuf, NVRAM_READ_IN_LENGTH, length);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_READ, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	memcpy(buffer, MCDI_PTR(outbuf, NVRAM_READ_OUT_READ_BUFFER), length);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
+			   loff_t offset, const u8 *buffer, size_t length)
+{
+	u8 inbuf[MC_CMD_NVRAM_WRITE_IN_LEN(EFX_MCDI_NVRAM_LEN_MAX)];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_TYPE, type);
+	MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_OFFSET, offset);
+	MCDI_SET_DWORD(inbuf, NVRAM_WRITE_IN_LENGTH, length);
+	memcpy(MCDI_PTR(inbuf, NVRAM_WRITE_IN_WRITE_BUFFER), buffer, length);
+
+	BUILD_BUG_ON(MC_CMD_NVRAM_WRITE_OUT_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_WRITE, inbuf,
+			  ALIGN(MC_CMD_NVRAM_WRITE_IN_LEN(length), 4),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
+			 loff_t offset, size_t length)
+{
+	u8 inbuf[MC_CMD_NVRAM_ERASE_IN_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_TYPE, type);
+	MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_OFFSET, offset);
+	MCDI_SET_DWORD(inbuf, NVRAM_ERASE_IN_LENGTH, length);
+
+	BUILD_BUG_ON(MC_CMD_NVRAM_ERASE_OUT_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_ERASE, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_nvram_update_finish(struct efx_nic *efx, unsigned int type)
+{
+	u8 inbuf[MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, NVRAM_UPDATE_FINISH_IN_TYPE, type);
+
+	BUILD_BUG_ON(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_UPDATE_FINISH, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_handle_assertion(struct efx_nic *efx)
+{
+	union {
+		u8 asserts[MC_CMD_GET_ASSERTS_IN_LEN];
+		u8 reboot[MC_CMD_REBOOT_IN_LEN];
+	} inbuf;
+	u8 assertion[MC_CMD_GET_ASSERTS_OUT_LEN];
+	unsigned int flags, index, ofst;
+	const char *reason;
+	size_t outlen;
+	int retry;
+	int rc;
+
+	/* Check if the MC is in the assertion handler, retrying twice. Once
+	 * because a boot-time assertion might cause this command to fail
+	 * with EINTR. And once again because GET_ASSERTS can race with
+	 * MC_CMD_REBOOT running on the other port. */
+	retry = 2;
+	do {
+		MCDI_SET_DWORD(inbuf.asserts, GET_ASSERTS_IN_CLEAR, 0);
+		rc = efx_mcdi_rpc(efx, MC_CMD_GET_ASSERTS,
+				  inbuf.asserts, MC_CMD_GET_ASSERTS_IN_LEN,
+				  assertion, sizeof(assertion), &outlen);
+	} while ((rc == -EINTR || rc == -EIO) && retry-- > 0);
+
+	if (rc)
+		return rc;
+	if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN)
+		return -EINVAL;
+
+	flags = MCDI_DWORD(assertion, GET_ASSERTS_OUT_GLOBAL_FLAGS);
+	if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
+		return 0;
+
+	/* Reset the hardware atomically such that only one port with succeed.
+	 * This command will succeed if a reboot is no longer required (because
+	 * the other port did it first), but fail with EIO if it succeeds.
+	 */
+	BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
+	MCDI_SET_DWORD(inbuf.reboot, REBOOT_IN_FLAGS,
+		       MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
+	efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf.reboot, MC_CMD_REBOOT_IN_LEN,
+		     NULL, 0, NULL);
+
+	/* Print out the assertion */
+	reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
+		? "system-level assertion"
+		: (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
+		? "thread-level assertion"
+		: (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
+		? "watchdog reset"
+		: "unknown assertion";
+	EFX_ERR(efx, "MCPU %s at PC = 0x%.8x in thread 0x%.8x\n", reason,
+		MCDI_DWORD(assertion, GET_ASSERTS_OUT_SAVED_PC_OFFS),
+		MCDI_DWORD(assertion, GET_ASSERTS_OUT_THREAD_OFFS));
+
+	/* Print out the registers */
+	ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
+	for (index = 1; index < 32; index++) {
+		EFX_ERR(efx, "R%.2d (?): 0x%.8x\n", index,
+			MCDI_DWORD2(assertion, ofst));
+		ofst += sizeof(efx_dword_t);
+	}
+
+	return 0;
+}
+
+void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+	u8 inbuf[MC_CMD_SET_ID_LED_IN_LEN];
+	int rc;
+
+	BUILD_BUG_ON(EFX_LED_OFF != MC_CMD_LED_OFF);
+	BUILD_BUG_ON(EFX_LED_ON != MC_CMD_LED_ON);
+	BUILD_BUG_ON(EFX_LED_DEFAULT != MC_CMD_LED_DEFAULT);
+
+	BUILD_BUG_ON(MC_CMD_SET_ID_LED_OUT_LEN != 0);
+
+	MCDI_SET_DWORD(inbuf, SET_ID_LED_IN_STATE, mode);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_SET_ID_LED, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+}
+
+int efx_mcdi_reset_port(struct efx_nic *efx)
+{
+	int rc = efx_mcdi_rpc(efx, MC_CMD_PORT_RESET, NULL, 0, NULL, 0, NULL);
+	if (rc)
+		EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_reset_mc(struct efx_nic *efx)
+{
+	u8 inbuf[MC_CMD_REBOOT_IN_LEN];
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
+	MCDI_SET_DWORD(inbuf, REBOOT_IN_FLAGS, 0);
+	rc = efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	/* White is black, and up is down */
+	if (rc == -EIO)
+		return 0;
+	if (rc == 0)
+		rc = -EIO;
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
+			    const u8 *mac, int *id_out)
+{
+	u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN];
+	u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, WOL_FILTER_SET_IN_WOL_TYPE, type);
+	MCDI_SET_DWORD(inbuf, WOL_FILTER_SET_IN_FILTER_MODE,
+		       MC_CMD_FILTER_MODE_SIMPLE);
+	memcpy(MCDI_PTR(inbuf, WOL_FILTER_SET_IN_MAGIC_MAC), mac, ETH_ALEN);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_SET, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	if (outlen < MC_CMD_WOL_FILTER_SET_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	*id_out = (int)MCDI_DWORD(outbuf, WOL_FILTER_SET_OUT_FILTER_ID);
+
+	return 0;
+
+fail:
+	*id_out = -1;
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+
+}
+
+
+int
+efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,  const u8 *mac, int *id_out)
+{
+	return efx_mcdi_wol_filter_set(efx, MC_CMD_WOL_TYPE_MAGIC, mac, id_out);
+}
+
+
+int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out)
+{
+	u8 outbuf[MC_CMD_WOL_FILTER_GET_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_GET, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	if (outlen < MC_CMD_WOL_FILTER_GET_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	*id_out = (int)MCDI_DWORD(outbuf, WOL_FILTER_GET_OUT_FILTER_ID);
+
+	return 0;
+
+fail:
+	*id_out = -1;
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+
+int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id)
+{
+	u8 inbuf[MC_CMD_WOL_FILTER_REMOVE_IN_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, WOL_FILTER_REMOVE_IN_FILTER_ID, (u32)id);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_REMOVE, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+
+int efx_mcdi_wol_filter_reset(struct efx_nic *efx)
+{
+	int rc;
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_RESET, NULL, 0, NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi.h linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2008-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef EFX_MCDI_H
+#define EFX_MCDI_H
+
+/**
+ * enum efx_mcdi_state
+ * @MCDI_STATE_QUIESCENT: No pending MCDI requests. If the caller holds the
+ *	mcdi_lock then they are able to move to MCDI_STATE_RUNNING
+ * @MCDI_STATE_RUNNING: There is an MCDI request pending. Only the thread that
+ *	moved into this state is allowed to move out of it.
+ * @MCDI_STATE_COMPLETED: An MCDI request has completed, but the owning thread
+ *	has not yet consumed the result. For all other threads, equivalent to
+ *	MCDI_STATE_RUNNING.
+ */
+enum efx_mcdi_state {
+	MCDI_STATE_QUIESCENT,
+	MCDI_STATE_RUNNING,
+	MCDI_STATE_COMPLETED,
+};
+
+enum efx_mcdi_mode {
+	MCDI_MODE_POLL,
+	MCDI_MODE_EVENTS,
+};
+
+/**
+ * struct efx_mcdi_iface
+ * @state: Interface state. Waited for by mcdi_wq.
+ * @wq: Wait queue for threads waiting for state != STATE_RUNNING
+ * @iface_lock: Protects @credits, @seqno, @resprc, @resplen
+ * @mode: Poll for mcdi completion, or wait for an mcdi_event.
+ *	Serialised by @lock
+ * @seqno: The next sequence number to use for mcdi requests.
+ *	Serialised by @lock
+ * @credits: Number of spurious MCDI completion events allowed before we
+ *	trigger a fatal error. Protected by @lock
+ * @resprc: Returned MCDI completion
+ * @resplen: Returned payload length
+ */
+struct efx_mcdi_iface {
+	atomic_t state;
+	wait_queue_head_t wq;
+	spinlock_t iface_lock;
+	enum efx_mcdi_mode mode;
+	unsigned int credits;
+	unsigned int seqno;
+	unsigned int resprc;
+	size_t resplen;
+};
+
+extern void efx_mcdi_init(struct efx_nic *efx);
+
+extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const u8 *inbuf,
+			size_t inlen, u8 *outbuf, size_t outlen,
+			size_t *outlen_actual);
+
+extern int efx_mcdi_poll_reboot(struct efx_nic *efx);
+extern void efx_mcdi_mode_poll(struct efx_nic *efx);
+extern void efx_mcdi_mode_event(struct efx_nic *efx);
+
+extern void efx_mcdi_process_event(struct efx_channel *channel,
+				   efx_qword_t *event);
+
+#define MCDI_PTR2(_buf, _ofst)						\
+	(((u8 *)_buf) + _ofst)
+#define MCDI_SET_DWORD2(_buf, _ofst, _value)				\
+	EFX_POPULATE_DWORD_1(*((efx_dword_t *)MCDI_PTR2(_buf, _ofst)),	\
+			     EFX_DWORD_0, _value)
+#define MCDI_DWORD2(_buf, _ofst)					\
+	EFX_DWORD_FIELD(*((efx_dword_t *)MCDI_PTR2(_buf, _ofst)),	\
+			EFX_DWORD_0)
+#define MCDI_QWORD2(_buf, _ofst)					\
+	EFX_QWORD_FIELD64(*((efx_qword_t *)MCDI_PTR2(_buf, _ofst)),	\
+			  EFX_QWORD_0)
+
+#define MCDI_PTR(_buf, _ofst)						\
+	MCDI_PTR2(_buf, MC_CMD_ ## _ofst ## _OFST)
+#define MCDI_SET_DWORD(_buf, _ofst, _value)				\
+	MCDI_SET_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST, _value)
+#define MCDI_DWORD(_buf, _ofst)						\
+	MCDI_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST)
+#define MCDI_QWORD(_buf, _ofst)						\
+	MCDI_QWORD2(_buf, MC_CMD_ ## _ofst ## _OFST)
+
+#define MCDI_EVENT_FIELD(_ev, _field)			\
+	EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
+
+extern int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build);
+extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
+			       bool *was_attached_out);
+extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
+				  u16 *fw_subtype_list);
+extern int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart,
+			     u32 dest_evq);
+extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out);
+extern int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
+			       size_t *size_out, size_t *erase_size_out,
+			       bool *protected_out);
+extern int efx_mcdi_nvram_update_start(struct efx_nic *efx,
+				       unsigned int type);
+extern int efx_mcdi_nvram_read(struct efx_nic *efx, unsigned int type,
+			       loff_t offset, u8 *buffer, size_t length);
+extern int efx_mcdi_nvram_write(struct efx_nic *efx, unsigned int type,
+				loff_t offset, const u8 *buffer,
+				size_t length);
+#define EFX_MCDI_NVRAM_LEN_MAX 128
+extern int efx_mcdi_nvram_erase(struct efx_nic *efx, unsigned int type,
+				loff_t offset, size_t length);
+extern int efx_mcdi_nvram_update_finish(struct efx_nic *efx,
+					unsigned int type);
+extern int efx_mcdi_handle_assertion(struct efx_nic *efx);
+extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
+extern int efx_mcdi_reset_port(struct efx_nic *efx);
+extern int efx_mcdi_reset_mc(struct efx_nic *efx);
+extern int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type,
+				   const u8 *mac, int *id_out);
+extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,
+					 const u8 *mac, int *id_out);
+extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out);
+extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id);
+extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx);
+
+#endif /* EFX_MCDI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_mac.c linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_mac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,152 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "efx.h"
+#include "mac.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+
+static int efx_mcdi_set_mac(struct efx_nic *efx)
+{
+	u32 reject, fcntl;
+	u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN];
+
+	memcpy(cmdbytes + MC_CMD_SET_MAC_IN_ADDR_OFST,
+	       efx->net_dev->dev_addr, ETH_ALEN);
+
+	MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_MTU,
+			EFX_MAX_FRAME_LEN(efx->net_dev->mtu));
+	MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_DRAIN, 0);
+
+	/* The MCDI command provides for controlling accept/reject
+	 * of broadcast packets too, but the driver doesn't currently
+	 * expose this. */
+	reject = (efx->promiscuous) ? 0 :
+		(1 << MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN);
+	MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_REJECT, reject);
+
+	switch (efx->wanted_fc) {
+	case EFX_FC_RX | EFX_FC_TX:
+		fcntl = MC_CMD_FCNTL_BIDIR;
+		break;
+	case EFX_FC_RX:
+		fcntl = MC_CMD_FCNTL_RESPOND;
+		break;
+	default:
+		fcntl = MC_CMD_FCNTL_OFF;
+		break;
+	}
+	if (efx->wanted_fc & EFX_FC_AUTO)
+		fcntl = MC_CMD_FCNTL_AUTO;
+
+	MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
+
+	return efx_mcdi_rpc(efx, MC_CMD_SET_MAC, cmdbytes, sizeof(cmdbytes),
+			    NULL, 0, NULL);
+}
+
+static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults)
+{
+	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
+	size_t outlength;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlength);
+	if (rc)
+		goto fail;
+
+	*faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n",
+		__func__, rc);
+	return rc;
+}
+
+int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
+		       u32 dma_len, int enable, int clear)
+{
+	u8 inbuf[MC_CMD_MAC_STATS_IN_LEN];
+	int rc;
+	efx_dword_t *cmd_ptr;
+	int period = 1000;
+	u32 addr_hi;
+	u32 addr_lo;
+
+	BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_LEN != 0);
+
+	addr_lo = ((u64)dma_addr) >> 0;
+	addr_hi = ((u64)dma_addr) >> 32;
+
+	MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_LO, addr_lo);
+	MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi);
+	cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD);
+	if (enable)
+		EFX_POPULATE_DWORD_6(*cmd_ptr,
+				     MC_CMD_MAC_STATS_CMD_DMA, 1,
+				     MC_CMD_MAC_STATS_CMD_CLEAR, clear,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, 1,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0,
+				     MC_CMD_MAC_STATS_CMD_PERIOD_MS, period);
+	else
+		EFX_POPULATE_DWORD_5(*cmd_ptr,
+				     MC_CMD_MAC_STATS_CMD_DMA, 0,
+				     MC_CMD_MAC_STATS_CMD_CLEAR, clear,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, 0,
+				     MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0);
+	MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: %s failed rc=%d\n",
+		__func__, enable ? "enable" : "disable", rc);
+	return rc;
+}
+
+static int efx_mcdi_mac_reconfigure(struct efx_nic *efx)
+{
+	int rc;
+
+	rc = efx_mcdi_set_mac(efx);
+	if (rc != 0)
+		return rc;
+
+	/* Restore the multicast hash registers. */
+	efx->type->push_multicast_hash(efx);
+
+	return 0;
+}
+
+
+static bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
+{
+	u32 faults;
+	int rc = efx_mcdi_get_mac_faults(efx, &faults);
+	return (rc != 0) || (faults != 0);
+}
+
+
+struct efx_mac_operations efx_mcdi_mac_operations = {
+	.reconfigure	= efx_mcdi_mac_reconfigure,
+	.update_stats	= efx_port_dummy_op_void,
+	.check_fault 	= efx_mcdi_mac_check_fault,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_pcol.h linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_pcol.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_pcol.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_pcol.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1580 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+
+#ifndef MCDI_PCOL_H
+#define MCDI_PCOL_H
+
+/* Values to be written into FMCR_CZ_RESET_STATE_REG to control boot. */
+/* Power-on reset state */
+#define MC_FW_STATE_POR (1)
+/* If this is set in MC_RESET_STATE_REG then it should be
+ * possible to jump into IMEM without loading code from flash. */
+#define MC_FW_WARM_BOOT_OK (2)
+/* The MC main image has started to boot. */
+#define MC_FW_STATE_BOOTING (4)
+/* The Scheduler has started. */
+#define MC_FW_STATE_SCHED (8)
+
+/* Values to be written to the per-port status dword in shared
+ * memory on reboot and assert */
+#define MC_STATUS_DWORD_REBOOT (0xb007b007)
+#define MC_STATUS_DWORD_ASSERT (0xdeaddead)
+
+/* The current version of the MCDI protocol.
+ *
+ * Note that the ROM burnt into the card only talks V0, so at the very
+ * least every driver must support version 0 and MCDI_PCOL_VERSION
+ */
+#define MCDI_PCOL_VERSION 1
+
+/**
+ * MCDI version 1
+ *
+ * Each MCDI request starts with an MCDI_HEADER, which is a 32byte
+ * structure, filled in by the client.
+ *
+ *       0       7  8     16    20     22  23  24    31
+ *      | CODE | R | LEN | SEQ | Rsvd | E | R | XFLAGS |
+ *               |                      |   |
+ *               |                      |   \--- Response
+ *               |                      \------- Error
+ *               \------------------------------ Resync (always set)
+ *
+ * The client writes it's request into MC shared memory, and rings the
+ * doorbell. Each request is completed by either by the MC writting
+ * back into shared memory, or by writting out an event.
+ *
+ * All MCDI commands support completion by shared memory response. Each
+ * request may also contain additional data (accounted for by HEADER.LEN),
+ * and some response's may also contain additional data (again, accounted
+ * for by HEADER.LEN).
+ *
+ * Some MCDI commands support completion by event, in which any associated
+ * response data is included in the event.
+ *
+ * The protocol requires one response to be delivered for every request, a
+ * request should not be sent unless the response for the previous request
+ * has been received (either by polling shared memory, or by receiving
+ * an event).
+ */
+
+/** Request/Response structure */
+#define MCDI_HEADER_OFST 0
+#define MCDI_HEADER_CODE_LBN 0
+#define MCDI_HEADER_CODE_WIDTH 7
+#define MCDI_HEADER_RESYNC_LBN 7
+#define MCDI_HEADER_RESYNC_WIDTH 1
+#define MCDI_HEADER_DATALEN_LBN 8
+#define MCDI_HEADER_DATALEN_WIDTH 8
+#define MCDI_HEADER_SEQ_LBN 16
+#define MCDI_HEADER_RSVD_LBN 20
+#define MCDI_HEADER_RSVD_WIDTH 2
+#define MCDI_HEADER_SEQ_WIDTH 4
+#define MCDI_HEADER_ERROR_LBN 22
+#define MCDI_HEADER_ERROR_WIDTH 1
+#define MCDI_HEADER_RESPONSE_LBN 23
+#define MCDI_HEADER_RESPONSE_WIDTH 1
+#define MCDI_HEADER_XFLAGS_LBN 24
+#define MCDI_HEADER_XFLAGS_WIDTH 8
+/* Request response using event */
+#define MCDI_HEADER_XFLAGS_EVREQ 0x01
+
+/* Maximum number of payload bytes */
+#define MCDI_CTL_SDU_LEN_MAX 0xfc
+
+/* The MC can generate events for two reasons:
+ *   - To complete a shared memory request if XFLAGS_EVREQ was set
+ *   - As a notification (link state, i2c event), controlled
+ *     via MC_CMD_LOG_CTRL
+ *
+ * Both events share a common structure:
+ *
+ *  0      32     33      36    44     52     60
+ * | Data | Cont | Level | Src | Code | Rsvd |
+ *           |
+ *           \ There is another event pending in this notification
+ *
+ * If Code==CMDDONE, then the fields are further interpreted as:
+ *
+ *   - LEVEL==INFO    Command succeded
+ *   - LEVEL==ERR     Command failed
+ *
+ *    0     8         16      24     32
+ *   | Seq | Datalen | Errno | Rsvd |
+ *
+ *   These fields are taken directly out of the standard MCDI header, i.e.,
+ *   LEVEL==ERR, Datalen == 0 => Reboot
+ *
+ * Events can be squirted out of the UART (using LOG_CTRL) without a
+ * MCDI header.  An event can be distinguished from a MCDI response by
+ * examining the first byte which is 0xc0.  This corresponds to the
+ * non-existent MCDI command MC_CMD_DEBUG_LOG.
+ *
+ *      0         7        8
+ *     | command | Resync |     = 0xc0
+ *
+ * Since the event is written in big-endian byte order, this works
+ * providing bits 56-63 of the event are 0xc0.
+ *
+ *      56     60  63
+ *     | Rsvd | Code |    = 0xc0
+ *
+ * Which means for convenience the event code is 0xc for all MC
+ * generated events.
+ */
+#define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc
+
+#define MCDI_EVENT_DATA_LBN 0
+#define MCDI_EVENT_DATA_WIDTH 32
+#define MCDI_EVENT_CONT_LBN 32
+#define MCDI_EVENT_CONT_WIDTH 1
+#define MCDI_EVENT_LEVEL_LBN 33
+#define MCDI_EVENT_LEVEL_WIDTH 3
+#define MCDI_EVENT_LEVEL_INFO (0)
+#define MCDI_EVENT_LEVEL_WARN (1)
+#define MCDI_EVENT_LEVEL_ERR (2)
+#define MCDI_EVENT_LEVEL_FATAL (3)
+#define MCDI_EVENT_SRC_LBN 36
+#define MCDI_EVENT_SRC_WIDTH 8
+#define MCDI_EVENT_CODE_LBN 44
+#define MCDI_EVENT_CODE_WIDTH 8
+#define MCDI_EVENT_CODE_BADSSERT (1)
+#define MCDI_EVENT_CODE_PMNOTICE (2)
+#define MCDI_EVENT_CODE_CMDDONE (3)
+#define  MCDI_EVENT_CMDDONE_SEQ_LBN 0
+#define  MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
+#define  MCDI_EVENT_CMDDONE_DATALEN_LBN 8
+#define  MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8
+#define  MCDI_EVENT_CMDDONE_ERRNO_LBN 16
+#define  MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8
+#define MCDI_EVENT_CODE_LINKCHANGE (4)
+#define  MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0
+#define  MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
+#define  MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
+#define  MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
+#define  MCDI_EVENT_LINKCHANGE_SPEED_100M 1
+#define  MCDI_EVENT_LINKCHANGE_SPEED_1G 2
+#define  MCDI_EVENT_LINKCHANGE_SPEED_10G 3
+#define  MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
+#define  MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
+#define  MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
+#define  MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8
+#define MCDI_EVENT_CODE_SENSOREVT (5)
+#define  MCDI_EVENT_SENSOREVT_MONITOR_LBN 0
+#define  MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8
+#define  MCDI_EVENT_SENSOREVT_STATE_LBN 8
+#define  MCDI_EVENT_SENSOREVT_STATE_WIDTH 8
+#define  MCDI_EVENT_SENSOREVT_VALUE_LBN 16
+#define  MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16
+#define MCDI_EVENT_CODE_SCHEDERR (6)
+#define MCDI_EVENT_CODE_REBOOT (7)
+#define MCDI_EVENT_CODE_MAC_STATS_DMA (8)
+#define  MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0
+#define  MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32
+
+/* Non-existent command target */
+#define MC_CMD_ERR_ENOENT 2
+/* assert() has killed the MC */
+#define MC_CMD_ERR_EINTR 4
+/* Caller does not hold required locks */
+#define MC_CMD_ERR_EACCES 13
+/* Resource is currently unavailable (e.g. lock contention) */
+#define MC_CMD_ERR_EBUSY 16
+/* Invalid argument to target */
+#define MC_CMD_ERR_EINVAL 22
+/* Non-recursive resource is already acquired */
+#define MC_CMD_ERR_EDEADLK 35
+/* Operation not implemented */
+#define MC_CMD_ERR_ENOSYS 38
+/* Operation timed out */
+#define MC_CMD_ERR_ETIME 62
+
+#define MC_CMD_ERR_CODE_OFST 0
+
+
+/* MC_CMD_READ32: (debug, variadic out)
+ * Read multiple 32byte words from MC memory
+ */
+#define MC_CMD_READ32 0x01
+#define MC_CMD_READ32_IN_LEN 8
+#define MC_CMD_READ32_IN_ADDR_OFST 0
+#define MC_CMD_READ32_IN_NUMWORDS_OFST 4
+#define MC_CMD_READ32_OUT_LEN(_numwords) \
+	(4 * (_numwords))
+#define MC_CMD_READ32_OUT_BUFFER_OFST 0
+
+/* MC_CMD_WRITE32: (debug, variadic in)
+ * Write multiple 32byte words to MC memory
+ */
+#define MC_CMD_WRITE32 0x02
+#define MC_CMD_WRITE32_IN_LEN(_numwords) (((_numwords) * 4) + 4)
+#define MC_CMD_WRITE32_IN_ADDR_OFST 0
+#define MC_CMD_WRITE32_IN_BUFFER_OFST 4
+#define MC_CMD_WRITE32_OUT_LEN 0
+
+/* MC_CMD_COPYCODE: (debug)
+ * Copy MC code between two locations and jump
+ */
+#define MC_CMD_COPYCODE 0x03
+#define MC_CMD_COPYCODE_IN_LEN 16
+#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0
+#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4
+#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8
+#define MC_CMD_COPYCODE_IN_JUMP_OFST 12
+/* Control should return to the caller rather than jumping */
+#define MC_CMD_COPYCODE_JUMP_NONE 1
+#define MC_CMD_COPYCODE_OUT_LEN 0
+
+/* MC_CMD_SET_FUNC: (debug)
+ * Select function for function-specific commands.
+ */
+#define MC_CMD_SET_FUNC 0x04
+#define MC_CMD_SET_FUNC_IN_LEN 4
+#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0
+#define MC_CMD_SET_FUNC_OUT_LEN 0
+
+/* MC_CMD_GET_BOOT_STATUS:
+ * Get the instruction address from which the MC booted.
+ */
+#define MC_CMD_GET_BOOT_STATUS 0x05
+#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0
+#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8
+#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
+#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
+/* Reboot caused by watchdog */
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_LBN   (0)
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_WIDTH (1)
+/* MC booted from primary flash partition */
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_LBN    (1)
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_WIDTH  (1)
+/* MC booted from backup flash partition */
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_LBN     (2)
+#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_WIDTH   (1)
+
+/* MC_CMD_GET_ASSERTS: (debug, variadic out)
+ * Get (and optionally clear) the current assertion status.
+ *
+ * Only OUT.GLOBAL_FLAGS is guaranteed to exist in the completion
+ * payload. The other fields will only be present if
+ * OUT.GLOBAL_FLAGS != NO_FAILS
+ */
+#define MC_CMD_GET_ASSERTS 0x06
+#define MC_CMD_GET_ASSERTS_IN_LEN 4
+#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0
+#define MC_CMD_GET_ASSERTS_OUT_LEN 140
+/* Assertion status flag */
+#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0
+/*! No assertions have failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 1
+/*! A system-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 2
+/*! A thread-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 3
+/*! The system was reset by the watchdog. */
+#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 4
+/* Failing PC value */
+#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4
+/* Saved GP regs */
+#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8
+#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_LEN 124
+/* Failing thread address */
+#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132
+
+/* MC_CMD_LOG_CTRL:
+ * Determine the output stream for various events and messages
+ */
+#define MC_CMD_LOG_CTRL 0x07
+#define MC_CMD_LOG_CTRL_IN_LEN 8
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART (1)
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ (2)
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4
+#define MC_CMD_LOG_CTRL_OUT_LEN 0
+
+/* MC_CMD_GET_VERSION:
+ * Get version information about the MC firmware
+ */
+#define MC_CMD_GET_VERSION 0x08
+#define MC_CMD_GET_VERSION_IN_LEN 0
+#define MC_CMD_GET_VERSION_V0_OUT_LEN 4
+#define MC_CMD_GET_VERSION_V1_OUT_LEN 32
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0
+/* Reserved version number to indicate "any" version. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff
+/* The version response of a boot ROM awaiting rescue */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000
+#define MC_CMD_GET_VERSION_V1_OUT_PCOL_OFST 4
+/* 128bit mask of functions supported by the current firmware */
+#define MC_CMD_GET_VERSION_V1_OUT_SUPPORTED_FUNCS_OFST 8
+/* The command set exported by the boot ROM (MCDI v0) */
+#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS {		\
+	(1 << MC_CMD_READ32)	|			\
+	(1 << MC_CMD_WRITE32)	|			\
+	(1 << MC_CMD_COPYCODE)	|			\
+	(1 << MC_CMD_GET_VERSION),			\
+	0, 0, 0 }
+#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24
+
+/* Vectors in the boot ROM */
+/* Point to the copycode entry point. */
+#define MC_BOOTROM_COPYCODE_VEC (0x7f4)
+/* Points to the recovery mode entry point. */
+#define MC_BOOTROM_NOFLASH_VEC (0x7f8)
+
+/* Test execution limits */
+#define MC_TESTEXEC_VARIANT_COUNT 16
+#define MC_TESTEXEC_RESULT_COUNT 7
+
+/* MC_CMD_SET_TESTVARS: (debug, variadic in)
+ * Write variant words for test.
+ *
+ * The user supplies a bitmap of the variants they wish to set.
+ * They must ensure that IN.LEN >= 4 + 4 * ffs(BITMAP)
+ */
+#define MC_CMD_SET_TESTVARS 0x09
+#define MC_CMD_SET_TESTVARS_IN_LEN(_numwords)	\
+  (4 + 4*(_numwords))
+#define MC_CMD_SET_TESTVARS_IN_ARGS_BITMAP_OFST 0
+/* Up to MC_TESTEXEC_VARIANT_COUNT of 32byte words start here */
+#define MC_CMD_SET_TESTVARS_IN_ARGS_BUFFER_OFST 4
+#define MC_CMD_SET_TESTVARS_OUT_LEN 0
+
+/* MC_CMD_GET_TESTRCS: (debug, variadic out)
+ * Return result words from test.
+ */
+#define MC_CMD_GET_TESTRCS 0x0a
+#define MC_CMD_GET_TESTRCS_IN_LEN 4
+#define MC_CMD_GET_TESTRCS_IN_NUMWORDS_OFST 0
+#define MC_CMD_GET_TESTRCS_OUT_LEN(_numwords) \
+	(4 * (_numwords))
+#define MC_CMD_GET_TESTRCS_OUT_BUFFER_OFST 0
+
+/* MC_CMD_RUN_TEST: (debug)
+ * Run the test exported by this firmware image
+ */
+#define MC_CMD_RUN_TEST 0x0b
+#define MC_CMD_RUN_TEST_IN_LEN 0
+#define MC_CMD_RUN_TEST_OUT_LEN 0
+
+/* MC_CMD_CSR_READ32: (debug, variadic out)
+ * Read 32bit words from the indirect memory map
+ */
+#define MC_CMD_CSR_READ32 0x0c
+#define MC_CMD_CSR_READ32_IN_LEN 12
+#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0
+#define MC_CMD_CSR_READ32_IN_STEP_OFST 4
+#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8
+#define MC_CMD_CSR_READ32_OUT_LEN(_numwords)	\
+	(((_numwords) * 4) + 4)
+/* IN.NUMWORDS of 32bit words start here */
+#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
+#define MC_CMD_CSR_READ32_OUT_IREG_STATUS_OFST(_numwords)	\
+	((_numwords) * 4)
+
+/* MC_CMD_CSR_WRITE32: (debug, variadic in)
+ * Write 32bit dwords to the indirect memory map
+ */
+#define MC_CMD_CSR_WRITE32 0x0d
+#define MC_CMD_CSR_WRITE32_IN_LEN(_numwords)	\
+	(((_numwords) * 4) + 8)
+#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
+#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4
+/* Multiple 32bit words of data to write start here */
+#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8
+#define MC_CMD_CSR_WRITE32_OUT_LEN 4
+#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0
+
+/* MC_CMD_JTAG_WORK: (debug, fpga only)
+ * Process JTAG work buffer for RBF acceleration.
+ *
+ *  Host: bit count, (up to) 32 words of data to clock out to JTAG
+ *   (bits 1,0=TMS,TDO for first bit; bits 3,2=TMS,TDO for second bit, etc.)
+ *  MC: bit count, (up to) 32 words of data clocked in from JTAG
+ *   (bit 0=TDI for first bit, bit 1=TDI for second bit, etc.; [31:16] unused)
+ */
+#define MC_CMD_JTAG_WORK 0x0e
+
+/* MC_CMD_STACKINFO: (debug, variadic out)
+ * Get stack information
+ *
+ * Host: nothing
+ * MC: (thread ptr, stack size, free space) for each thread in system
+ */
+#define MC_CMD_STACKINFO 0x0f
+
+/* MC_CMD_MDIO_READ:
+ * MDIO register read
+ */
+#define MC_CMD_MDIO_READ 0x10
+#define MC_CMD_MDIO_READ_IN_LEN 16
+#define MC_CMD_MDIO_READ_IN_BUS_OFST 0
+#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4
+#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8
+#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12
+#define MC_CMD_MDIO_READ_OUT_LEN 8
+#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0
+#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4
+
+/* MC_CMD_MDIO_WRITE:
+ * MDIO register write
+ */
+#define MC_CMD_MDIO_WRITE 0x11
+#define MC_CMD_MDIO_WRITE_IN_LEN 20
+#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0
+#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4
+#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8
+#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12
+#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16
+#define MC_CMD_MDIO_WRITE_OUT_LEN 4
+#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0
+
+/* By default all the MCDI MDIO operations perform clause45 mode.
+ * If you want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
+ */
+#define MC_CMD_MDIO_CLAUSE22 32
+
+/* There are two MDIO buses: one for the internal PHY, and one for external
+ * devices.
+ */
+#define MC_CMD_MDIO_BUS_INTERNAL 0
+#define MC_CMD_MDIO_BUS_EXTERNAL 1
+
+/* The MDIO commands return the raw status bits from the MDIO block.  A "good"
+ * transaction should have the DONE bit set and all other bits clear.
+ */
+#define MC_CMD_MDIO_STATUS_GOOD 0x08
+
+
+/* MC_CMD_DBI_WRITE: (debug)
+ * Write DBI register(s)
+ *
+ * Host: address, byte-enables (and VF selection, and cs2 flag),
+ *       value [,address ...]
+ * MC: nothing
+ */
+#define MC_CMD_DBI_WRITE 0x12
+#define MC_CMD_DBI_WRITE_IN_LEN(_numwords)		\
+	(12 * (_numwords))
+#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(_word)		\
+	(((_word) * 12) + 0)
+#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(_word)	\
+	(((_word) * 12) + 4)
+#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(_word)		\
+	(((_word) * 12) + 8)
+#define MC_CMD_DBI_WRITE_OUT_LEN 0
+
+/* MC_CMD_DBI_READ: (debug)
+ * Read DBI register(s)
+ *
+ * Host: address, [,address ...]
+ * MC: value [,value ...]
+ * (note: this does not support reading from VFs, but is retained for backwards
+ * compatibility; see MC_CMD_DBI_READX below)
+ */
+#define MC_CMD_DBI_READ 0x13
+#define MC_CMD_DBI_READ_IN_LEN(_numwords)		\
+	(4 * (_numwords))
+#define MC_CMD_DBI_READ_OUT_LEN(_numwords)		\
+	(4 * (_numwords))
+
+/* MC_CMD_PORT_READ32: (debug)
+ * Read a 32-bit register from the indirect port register map.
+ *
+ * The port to access is implied by the Shared memory channel used.
+ */
+#define MC_CMD_PORT_READ32 0x14
+#define MC_CMD_PORT_READ32_IN_LEN 4
+#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0
+#define MC_CMD_PORT_READ32_OUT_LEN 8
+#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0
+#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4
+
+/* MC_CMD_PORT_WRITE32: (debug)
+ * Write a 32-bit register to the indirect port register map.
+ *
+ * The port to access is implied by the Shared memory channel used.
+ */
+#define MC_CMD_PORT_WRITE32 0x15
+#define MC_CMD_PORT_WRITE32_IN_LEN 8
+#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0
+#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4
+#define MC_CMD_PORT_WRITE32_OUT_LEN 4
+#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0
+
+/* MC_CMD_PORT_READ128: (debug)
+ * Read a 128-bit register from indirect port register map
+ *
+ * The port to access is implied by the Shared memory channel used.
+ */
+#define MC_CMD_PORT_READ128 0x16
+#define MC_CMD_PORT_READ128_IN_LEN 4
+#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0
+#define MC_CMD_PORT_READ128_OUT_LEN 20
+#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0
+#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16
+
+/* MC_CMD_PORT_WRITE128: (debug)
+ * Write a 128-bit register to indirect port register map.
+ *
+ * The port to access is implied by the Shared memory channel used.
+ */
+#define MC_CMD_PORT_WRITE128 0x17
+#define MC_CMD_PORT_WRITE128_IN_LEN 20
+#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0
+#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4
+#define MC_CMD_PORT_WRITE128_OUT_LEN 4
+#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0
+
+/* MC_CMD_GET_BOARD_CFG:
+ * Returns the MC firmware configuration structure
+ *
+ * The FW_SUBTYPE_LIST contains a 16-bit value for each of the 12 types of
+ * NVRAM area.  The values are defined in the firmware/mc/platform/<xxx>.c file
+ * for a specific board type, but otherwise have no meaning to the MC; they
+ * are used by the driver to manage selection of appropriate firmware updates.
+ */
+#define MC_CMD_GET_BOARD_CFG 0x18
+#define MC_CMD_GET_BOARD_CFG_IN_LEN 0
+#define MC_CMD_GET_BOARD_CFG_OUT_LEN 96
+#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
+#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
+#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32
+#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36
+#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64
+#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68
+#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72
+#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 24
+
+/* MC_CMD_DBI_READX: (debug)
+ * Read DBI register(s) -- extended functionality
+ *
+ * Host: vf selection, address, [,vf selection ...]
+ * MC: value [,value ...]
+ */
+#define MC_CMD_DBI_READX 0x19
+#define MC_CMD_DBI_READX_IN_LEN(_numwords)	\
+  (8*(_numwords))
+#define MC_CMD_DBI_READX_OUT_LEN(_numwords)	\
+  (4*(_numwords))
+
+/* MC_CMD_SET_RAND_SEED:
+ * Set the 16byte seed for the MC psuedo-random generator
+ */
+#define MC_CMD_SET_RAND_SEED 0x1a
+#define MC_CMD_SET_RAND_SEED_IN_LEN 16
+#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0
+#define MC_CMD_SET_RAND_SEED_OUT_LEN 0
+
+/* MC_CMD_LTSSM_HIST: (debug)
+ * Retrieve the history of the LTSSM, if the build supports it.
+ *
+ * Host: nothing
+ * MC: variable number of LTSSM values, as bytes
+ * The history is read-to-clear.
+ */
+#define MC_CMD_LTSSM_HIST 0x1b
+
+/* MC_CMD_DRV_ATTACH:
+ * Inform MCPU that this port is managed on the host (i.e. driver active)
+ */
+#define MC_CMD_DRV_ATTACH 0x1c
+#define MC_CMD_DRV_ATTACH_IN_LEN 8
+#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
+#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
+#define MC_CMD_DRV_ATTACH_OUT_LEN 4
+#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0
+
+/* MC_CMD_NCSI_PROD: (debug)
+ * Trigger an NC-SI event (and possibly an AEN in response)
+ */
+#define MC_CMD_NCSI_PROD 0x1d
+#define MC_CMD_NCSI_PROD_IN_LEN 4
+#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0
+#define MC_CMD_NCSI_PROD_LINKCHANGE_LBN 0
+#define MC_CMD_NCSI_PROD_LINKCHANGE_WIDTH 1
+#define MC_CMD_NCSI_PROD_RESET_LBN 1
+#define MC_CMD_NCSI_PROD_RESET_WIDTH 1
+#define MC_CMD_NCSI_PROD_DRVATTACH_LBN 2
+#define MC_CMD_NCSI_PROD_DRVATTACH_WIDTH 1
+#define MC_CMD_NCSI_PROD_OUT_LEN 0
+
+/* Enumeration */
+#define MC_CMD_NCSI_PROD_LINKCHANGE 0
+#define MC_CMD_NCSI_PROD_RESET 1
+#define MC_CMD_NCSI_PROD_DRVATTACH 2
+
+/* MC_CMD_DEVEL: (debug)
+ * Reserved for development
+ */
+#define MC_CMD_DEVEL 0x1e
+
+/* MC_CMD_SHMUART: (debug)
+ * Route UART output to circular buffer in shared memory instead.
+ */
+#define MC_CMD_SHMUART 0x1f
+#define MC_CMD_SHMUART_IN_FLAG_OFST 0
+#define MC_CMD_SHMUART_IN_LEN 4
+#define MC_CMD_SHMUART_OUT_LEN 0
+
+/* MC_CMD_PORT_RESET:
+ * Generic per-port reset. There is no equivalent for per-board reset.
+ *
+ * Locks required: None
+ * Return code: 0, ETIME
+ */
+#define MC_CMD_PORT_RESET 0x20
+#define MC_CMD_PORT_RESET_IN_LEN 0
+#define MC_CMD_PORT_RESET_OUT_LEN 0
+
+/* MC_CMD_RESOURCE_LOCK:
+ * Generic resource lock/unlock interface.
+ *
+ * Locks required: None
+ * Return code: 0,
+ *              EBUSY (if trylock is contended by other port),
+ *              EDEADLK (if trylock is already acquired by this port)
+ *              EINVAL (if unlock doesn't own the lock)
+ */
+#define MC_CMD_RESOURCE_LOCK 0x21
+#define MC_CMD_RESOURCE_LOCK_IN_LEN 8
+#define MC_CMD_RESOURCE_LOCK_IN_ACTION_OFST 0
+#define MC_CMD_RESOURCE_LOCK_ACTION_TRYLOCK 1
+#define MC_CMD_RESOURCE_LOCK_ACTION_UNLOCK 0
+#define MC_CMD_RESOURCE_LOCK_IN_RESOURCE_OFST 4
+#define MC_CMD_RESOURCE_LOCK_I2C 2
+#define MC_CMD_RESOURCE_LOCK_PHY 3
+#define MC_CMD_RESOURCE_LOCK_OUT_LEN 0
+
+/* MC_CMD_SPI_COMMAND: (variadic in, variadic out)
+ * Read/Write to/from the SPI device.
+ *
+ * Locks required: SPI_LOCK
+ * Return code: 0, ETIME, EINVAL, EACCES (if SPI_LOCK is not held)
+ */
+#define MC_CMD_SPI_COMMAND 0x22
+#define MC_CMD_SPI_COMMAND_IN_LEN(_write_bytes)	(12 + (_write_bytes))
+#define MC_CMD_SPI_COMMAND_IN_ARGS_OFST 0
+#define MC_CMD_SPI_COMMAND_IN_ARGS_ADDRESS_OFST 0
+#define MC_CMD_SPI_COMMAND_IN_ARGS_READ_BYTES_OFST 4
+#define MC_CMD_SPI_COMMAND_IN_ARGS_CHIP_SELECT_OFST 8
+/* Data to write here */
+#define MC_CMD_SPI_COMMAND_IN_WRITE_BUFFER_OFST 12
+#define MC_CMD_SPI_COMMAND_OUT_LEN(_read_bytes) (_read_bytes)
+/* Data read here */
+#define MC_CMD_SPI_COMMAND_OUT_READ_BUFFER_OFST 0
+
+/* MC_CMD_I2C_READ_WRITE: (variadic in, variadic out)
+ * Read/Write to/from the I2C bus.
+ *
+ * Locks required: I2C_LOCK
+ * Return code: 0, ETIME, EINVAL, EACCES (if I2C_LOCK is not held)
+ */
+#define MC_CMD_I2C_RW 0x23
+#define MC_CMD_I2C_RW_IN_LEN(_write_bytes) (8 + (_write_bytes))
+#define MC_CMD_I2C_RW_IN_ARGS_OFST 0
+#define MC_CMD_I2C_RW_IN_ARGS_ADDR_OFST 0
+#define MC_CMD_I2C_RW_IN_ARGS_READ_BYTES_OFST 4
+/* Data to write here */
+#define MC_CMD_I2C_RW_IN_WRITE_BUFFER_OFSET 8
+#define MC_CMD_I2C_RW_OUT_LEN(_read_bytes) (_read_bytes)
+/* Data read here */
+#define MC_CMD_I2C_RW_OUT_READ_BUFFER_OFST 0
+
+/* Generic phy capability bitmask */
+#define MC_CMD_PHY_CAP_10HDX_LBN 1
+#define MC_CMD_PHY_CAP_10HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_10FDX_LBN 2
+#define MC_CMD_PHY_CAP_10FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_100HDX_LBN 3
+#define MC_CMD_PHY_CAP_100HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_100FDX_LBN 4
+#define MC_CMD_PHY_CAP_100FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_1000HDX_LBN 5
+#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1
+#define MC_CMD_PHY_CAP_1000FDX_LBN 6
+#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_10000FDX_LBN 7
+#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1
+#define MC_CMD_PHY_CAP_PAUSE_LBN 8
+#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1
+#define MC_CMD_PHY_CAP_ASYM_LBN 9
+#define MC_CMD_PHY_CAP_ASYM_WIDTH 1
+#define MC_CMD_PHY_CAP_AN_LBN 10
+#define MC_CMD_PHY_CAP_AN_WIDTH 1
+
+/* Generic loopback enumeration */
+#define MC_CMD_LOOPBACK_NONE 0
+#define MC_CMD_LOOPBACK_DATA 1
+#define MC_CMD_LOOPBACK_GMAC 2
+#define MC_CMD_LOOPBACK_XGMII 3
+#define MC_CMD_LOOPBACK_XGXS 4
+#define MC_CMD_LOOPBACK_XAUI 5
+#define MC_CMD_LOOPBACK_GMII 6
+#define MC_CMD_LOOPBACK_SGMII 7
+#define MC_CMD_LOOPBACK_XGBR 8
+#define MC_CMD_LOOPBACK_XFI 9
+#define MC_CMD_LOOPBACK_XAUI_FAR 10
+#define MC_CMD_LOOPBACK_GMII_FAR 11
+#define MC_CMD_LOOPBACK_SGMII_FAR 12
+#define MC_CMD_LOOPBACK_XFI_FAR 13
+#define MC_CMD_LOOPBACK_GPHY 14
+#define MC_CMD_LOOPBACK_PHYXS 15
+#define MC_CMD_LOOPBACK_PCS 16
+#define MC_CMD_LOOPBACK_PMAPMD 17
+#define MC_CMD_LOOPBACK_XPORT 18
+#define MC_CMD_LOOPBACK_XGMII_WS 19
+#define MC_CMD_LOOPBACK_XAUI_WS 20
+#define MC_CMD_LOOPBACK_XAUI_WS_FAR 21
+#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 22
+#define MC_CMD_LOOPBACK_GMII_WS 23
+#define MC_CMD_LOOPBACK_XFI_WS 24
+#define MC_CMD_LOOPBACK_XFI_WS_FAR 25
+#define MC_CMD_LOOPBACK_PHYXS_WS 26
+
+/* Generic PHY statistics enumeration */
+#define MC_CMD_OUI 0
+#define MC_CMD_PMA_PMD_LINK_UP 1
+#define MC_CMD_PMA_PMD_RX_FAULT 2
+#define MC_CMD_PMA_PMD_TX_FAULT 3
+#define MC_CMD_PMA_PMD_SIGNAL 4
+#define MC_CMD_PMA_PMD_SNR_A 5
+#define MC_CMD_PMA_PMD_SNR_B 6
+#define MC_CMD_PMA_PMD_SNR_C 7
+#define MC_CMD_PMA_PMD_SNR_D 8
+#define MC_CMD_PCS_LINK_UP 9
+#define MC_CMD_PCS_RX_FAULT 10
+#define MC_CMD_PCS_TX_FAULT 11
+#define MC_CMD_PCS_BER 12
+#define MC_CMD_PCS_BLOCK_ERRORS 13
+#define MC_CMD_PHYXS_LINK_UP 14
+#define MC_CMD_PHYXS_RX_FAULT 15
+#define MC_CMD_PHYXS_TX_FAULT 16
+#define MC_CMD_PHYXS_ALIGN 17
+#define MC_CMD_PHYXS_SYNC 18
+#define MC_CMD_AN_LINK_UP 19
+#define MC_CMD_AN_COMPLETE 20
+#define MC_CMD_AN_10GBT_STATUS 21
+#define MC_CMD_CL22_LINK_UP 22
+#define MC_CMD_PHY_NSTATS 23
+
+/* MC_CMD_GET_PHY_CFG:
+ * Report PHY configuration.  This guarantees to succeed even if the PHY is in
+ * a "zombie" state.
+ *
+ * Locks required: None
+ * Return code: 0
+ */
+#define MC_CMD_GET_PHY_CFG 0x24
+
+#define MC_CMD_GET_PHY_CFG_IN_LEN 0
+#define MC_CMD_GET_PHY_CFG_OUT_LEN 72
+
+#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
+#define MC_CMD_GET_PHY_CFG_PRESENT_LBN 0
+#define MC_CMD_GET_PHY_CFG_PRESENT_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_SHORTBIST_LBN 1
+#define MC_CMD_GET_PHY_CFG_SHORTBIST_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_LONGBIST_LBN 2
+#define MC_CMD_GET_PHY_CFG_LONGBIST_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_LOWPOWER_LBN 3
+#define MC_CMD_GET_PHY_CFG_LOWPOWER_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_POWEROFF_LBN 4
+#define MC_CMD_GET_PHY_CFG_POWEROFF_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_TXDIS_LBN 5
+#define MC_CMD_GET_PHY_CFG_TXDIS_WIDTH 1
+#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
+/* Bitmask of supported capabilities */
+#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
+#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12
+#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16
+/* PHY statistics bitmap */
+#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20
+/* PHY type/name string */
+#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24
+#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20
+#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44
+#define MC_CMD_MEDIA_XAUI 1
+#define MC_CMD_MEDIA_CX4 2
+#define MC_CMD_MEDIA_KX4 3
+#define MC_CMD_MEDIA_XFP 4
+#define MC_CMD_MEDIA_SFP_PLUS 5
+#define MC_CMD_MEDIA_BASE_T 6
+/* MDIO "MMDS" supported */
+#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48
+/* Native clause 22 */
+#define MC_CMD_MMD_CLAUSE22  0
+#define MC_CMD_MMD_CLAUSE45_PMAPMD 1
+#define MC_CMD_MMD_CLAUSE45_WIS 2
+#define MC_CMD_MMD_CLAUSE45_PCS 3
+#define MC_CMD_MMD_CLAUSE45_PHYXS 4
+#define MC_CMD_MMD_CLAUSE45_DTEXS 5
+#define MC_CMD_MMD_CLAUSE45_TC 6
+#define MC_CMD_MMD_CLAUSE45_AN 7
+/* Clause22 proxied over clause45 by PHY */
+#define MC_CMD_MMD_CLAUSE45_C22EXT 29
+#define MC_CMD_MMD_CLAUSE45_VEND1 30
+#define MC_CMD_MMD_CLAUSE45_VEND2 31
+/* PHY stepping version */
+#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
+#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20
+
+/* MC_CMD_START_PHY_BIST:
+ * Start a BIST test on the PHY.
+ *
+ * Locks required: PHY_LOCK if doing a  PHY BIST
+ * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held)
+ */
+#define MC_CMD_START_BIST 0x25
+#define MC_CMD_START_BIST_IN_LEN 4
+#define MC_CMD_START_BIST_TYPE_OFST 0
+
+/* Run the PHY's short BIST */
+#define MC_CMD_PHY_BIST_SHORT  1
+/* Run the PHY's long BIST */
+#define MC_CMD_PHY_BIST_LONG   2
+/* Run BIST on the currently selected BPX Serdes (XAUI or XFI) */
+#define MC_CMD_BPX_SERDES_BIST 3
+
+/* MC_CMD_POLL_PHY_BIST: (variadic output)
+ * Poll for BIST completion
+ *
+ * Returns a single status code, and a binary blob of phy-specific
+ * bist output. If the driver can't succesfully parse the BIST output,
+ * it should still respect the Pass/Fail in OUT.RESULT.
+ *
+ * Locks required: PHY_LOCK  if doing a  PHY BIST
+ * Return code: 0, EACCES (if PHY_LOCK is not held)
+ */
+#define MC_CMD_POLL_BIST 0x26
+#define MC_CMD_POLL_BIST_IN_LEN 0
+#define MC_CMD_POLL_BIST_OUT_LEN UNKNOWN
+#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
+#define MC_CMD_POLL_BIST_RUNNING 1
+#define MC_CMD_POLL_BIST_PASSED 2
+#define MC_CMD_POLL_BIST_FAILED 3
+#define MC_CMD_POLL_BIST_TIMEOUT 4
+#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
+
+/* MC_CMD_PHY_SPI: (variadic in, variadic out)
+ * Read/Write/Erase the PHY SPI device
+ *
+ * Locks required: PHY_LOCK
+ * Return code: 0, ETIME, EINVAL, EACCES (if PHY_LOCK is not held)
+ */
+#define MC_CMD_PHY_SPI 0x27
+#define MC_CMD_PHY_SPI_IN_LEN(_write_bytes) (12 + (_write_bytes))
+#define MC_CMD_PHY_SPI_IN_ARGS_OFST 0
+#define MC_CMD_PHY_SPI_IN_ARGS_ADDR_OFST 0
+#define MC_CMD_PHY_SPI_IN_ARGS_READ_BYTES_OFST 4
+#define MC_CMD_PHY_SPI_IN_ARGS_ERASE_ALL_OFST 8
+/* Data to write here */
+#define MC_CMD_PHY_SPI_IN_WRITE_BUFFER_OFSET 12
+#define MC_CMD_PHY_SPI_OUT_LEN(_read_bytes) (_read_bytes)
+/* Data read here */
+#define MC_CMD_PHY_SPI_OUT_READ_BUFFER_OFST 0
+
+
+/* MC_CMD_GET_LOOPBACK_MODES:
+ * Returns a bitmask of loopback modes evailable at each speed.
+ *
+ * Locks required: None
+ * Return code: 0
+ */
+#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32
+#define MC_CMD_GET_LOOPBACK_MODES_100M_OFST 0
+#define MC_CMD_GET_LOOPBACK_MODES_1G_OFST 8
+#define MC_CMD_GET_LOOPBACK_MODES_10G_OFST 16
+#define MC_CMD_GET_LOOPBACK_MODES_SUGGESTED_OFST 24
+
+/* Flow control enumeration */
+#define MC_CMD_FCNTL_OFF 0
+#define MC_CMD_FCNTL_RESPOND 1
+#define MC_CMD_FCNTL_BIDIR 2
+/* Auto - Use what the link has autonegotiated
+ *      - The driver should modify the advertised capabilities via SET_LINK.CAP
+ *        to control the negotiated flow control mode.
+ *      - Can only be set if the PHY supports PAUSE+ASYM capabilities
+ *      - Never returned by GET_LINK as the value programmed into the MAC
+ */
+#define MC_CMD_FCNTL_AUTO 3
+
+/* Generic mac fault bitmask */
+#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
+#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
+#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1
+#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1
+#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2
+#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1
+
+/* MC_CMD_GET_LINK:
+ * Read the unified MAC/PHY link state
+ *
+ * Locks required: None
+ * Return code: 0, ETIME
+ */
+#define MC_CMD_GET_LINK 0x29
+#define MC_CMD_GET_LINK_IN_LEN 0
+#define MC_CMD_GET_LINK_OUT_LEN 28
+/* near-side and link-partner advertised capabilities */
+#define MC_CMD_GET_LINK_OUT_CAP_OFST 0
+#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
+/* Autonegotiated speed in mbit/s. The link may still be down
+ * even if this reads non-zero */
+#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8
+#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12
+#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16
+/* Whether we have overall link up */
+#define MC_CMD_GET_LINK_LINK_UP_LBN 0
+#define MC_CMD_GET_LINK_LINK_UP_WIDTH 1
+#define MC_CMD_GET_LINK_FULL_DUPLEX_LBN 1
+#define MC_CMD_GET_LINK_FULL_DUPLEX_WIDTH 1
+/* Whether we have link at the layers provided by the BPX */
+#define MC_CMD_GET_LINK_BPX_LINK_LBN 2
+#define MC_CMD_GET_LINK_BPX_LINK_WIDTH 1
+/* Whether the PHY has external link */
+#define MC_CMD_GET_LINK_PHY_LINK_LBN 3
+#define MC_CMD_GET_LINK_PHY_LINK_WIDTH 1
+#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
+#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
+
+/* MC_CMD_SET_LINK:
+ * Write the unified MAC/PHY link configuration
+ *
+ * A loopback speed of "0" is supported, and means
+ * (choose any available speed)
+ *
+ * Locks required: None
+ * Return code: 0, EINVAL, ETIME
+ */
+#define MC_CMD_SET_LINK 0x2a
+#define MC_CMD_SET_LINK_IN_LEN 16
+#define MC_CMD_SET_LINK_IN_CAP_OFST 0
+#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4
+#define MC_CMD_SET_LINK_LOWPOWER_LBN 0
+#define MC_CMD_SET_LINK_LOWPOWER_WIDTH 1
+#define MC_CMD_SET_LINK_POWEROFF_LBN 1
+#define MC_CMD_SET_LINK_POWEROFF_WIDTH 1
+#define MC_CMD_SET_LINK_TXDIS_LBN 2
+#define MC_CMD_SET_LINK_TXDIS_WIDTH 1
+#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
+#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
+#define MC_CMD_SET_LINK_OUT_LEN 0
+
+/* MC_CMD_SET_ID_LED:
+ * Set indentification LED state
+ *
+ * Locks required: None
+ * Return code: 0, EINVAL
+ */
+#define MC_CMD_SET_ID_LED 0x2b
+#define MC_CMD_SET_ID_LED_IN_LEN 4
+#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0
+#define  MC_CMD_LED_OFF 0
+#define  MC_CMD_LED_ON 1
+#define  MC_CMD_LED_DEFAULT 2
+#define MC_CMD_SET_ID_LED_OUT_LEN 0
+
+/* MC_CMD_SET_MAC:
+ * Set MAC configuration
+ *
+ * The MTU is the MTU programmed directly into the XMAC/GMAC
+ * (inclusive of EtherII, VLAN, bug16011 padding)
+ *
+ * Locks required: None
+ * Return code: 0, EINVAL
+ */
+#define MC_CMD_SET_MAC 0x2c
+#define MC_CMD_SET_MAC_IN_LEN 24
+#define MC_CMD_SET_MAC_IN_MTU_OFST 0
+#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4
+#define MC_CMD_SET_MAC_IN_ADDR_OFST 8
+#define MC_CMD_SET_MAC_IN_REJECT_OFST 16
+#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0
+#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1
+#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
+#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
+#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20
+#define MC_CMD_SET_MAC_OUT_LEN 0
+
+/* MC_CMD_PHY_STATS:
+ * Get generic PHY statistics
+ *
+ * This call returns the statistics for a generic PHY, by direct DMA
+ * into host memory, in a sparse array (indexed by the enumerate).
+ * Each value is represented by a 32bit number.
+ *
+ * Locks required: None
+ * Returns: 0, ETIME
+ * Response methods: shared memory, event
+ */
+#define MC_CMD_PHY_STATS 0x2d
+#define MC_CMD_PHY_STATS_IN_LEN 8
+#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0
+#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4
+#define MC_CMD_PHY_STATS_OUT_LEN 0
+
+/* Unified MAC statistics enumeration */
+#define MC_CMD_MAC_GENERATION_START 0
+#define MC_CMD_MAC_TX_PKTS 1
+#define MC_CMD_MAC_TX_PAUSE_PKTS 2
+#define MC_CMD_MAC_TX_CONTROL_PKTS 3
+#define MC_CMD_MAC_TX_UNICAST_PKTS 4
+#define MC_CMD_MAC_TX_MULTICAST_PKTS 5
+#define MC_CMD_MAC_TX_BROADCAST_PKTS 6
+#define MC_CMD_MAC_TX_BYTES 7
+#define MC_CMD_MAC_TX_BAD_BYTES 8
+#define MC_CMD_MAC_TX_LT64_PKTS 9
+#define MC_CMD_MAC_TX_64_PKTS 10
+#define MC_CMD_MAC_TX_65_TO_127_PKTS 11
+#define MC_CMD_MAC_TX_128_TO_255_PKTS 12
+#define MC_CMD_MAC_TX_256_TO_511_PKTS 13
+#define MC_CMD_MAC_TX_512_TO_1023_PKTS 14
+#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 15
+#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 16
+#define MC_CMD_MAC_TX_GTJUMBO_PKTS 17
+#define MC_CMD_MAC_TX_BAD_FCS_PKTS 18
+#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 19
+#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 20
+#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 21
+#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 22
+#define MC_CMD_MAC_TX_DEFERRED_PKTS 23
+#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 24
+#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 25
+#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 26
+#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 27
+#define MC_CMD_MAC_RX_PKTS 28
+#define MC_CMD_MAC_RX_PAUSE_PKTS 29
+#define MC_CMD_MAC_RX_GOOD_PKTS 30
+#define MC_CMD_MAC_RX_CONTROL_PKTS 31
+#define MC_CMD_MAC_RX_UNICAST_PKTS 32
+#define MC_CMD_MAC_RX_MULTICAST_PKTS 33
+#define MC_CMD_MAC_RX_BROADCAST_PKTS 34
+#define MC_CMD_MAC_RX_BYTES 35
+#define MC_CMD_MAC_RX_BAD_BYTES 36
+#define MC_CMD_MAC_RX_64_PKTS 37
+#define MC_CMD_MAC_RX_65_TO_127_PKTS 38
+#define MC_CMD_MAC_RX_128_TO_255_PKTS 39
+#define MC_CMD_MAC_RX_256_TO_511_PKTS 40
+#define MC_CMD_MAC_RX_512_TO_1023_PKTS 41
+#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 42
+#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 43
+#define MC_CMD_MAC_RX_GTJUMBO_PKTS 44
+#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 45
+#define MC_CMD_MAC_RX_BAD_FCS_PKTS 46
+#define MC_CMD_MAC_RX_OVERFLOW_PKTS 47
+#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 48
+#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 49
+#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 50
+#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 51
+#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 52
+#define MC_CMD_MAC_RX_JABBER_PKTS 53
+#define MC_CMD_MAC_RX_NODESC_DROPS 54
+#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 55
+#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 56
+#define MC_CMD_MAC_RX_LANES01_DISP_ERR 57
+#define MC_CMD_MAC_RX_LANES23_DISP_ERR 58
+#define MC_CMD_MAC_RX_MATCH_FAULT 59
+#define MC_CMD_GMAC_DMABUF_START 64
+#define MC_CMD_GMAC_DMABUF_END   95
+/* Insert new members here. */
+#define MC_CMD_MAC_GENERATION_END 96
+#define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1)
+
+/* MC_CMD_MAC_STATS:
+ * Get unified GMAC/XMAC statistics
+ *
+ * This call returns unified statistics maintained by the MC as it
+ * switches between the GMAC and XMAC. The MC will write out all
+ * supported stats.  The driver should zero initialise the buffer to
+ * guarantee consistent results.
+ *
+ * Locks required: None
+ * Returns: 0
+ * Response methods: shared memory, event
+ */
+#define MC_CMD_MAC_STATS 0x2e
+#define MC_CMD_MAC_STATS_IN_LEN 16
+#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0
+#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4
+#define MC_CMD_MAC_STATS_IN_CMD_OFST 8
+#define MC_CMD_MAC_STATS_CMD_DMA_LBN 0
+#define MC_CMD_MAC_STATS_CMD_DMA_WIDTH 1
+#define MC_CMD_MAC_STATS_CMD_CLEAR_LBN 1
+#define MC_CMD_MAC_STATS_CMD_CLEAR_WIDTH 1
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_LBN 2
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_WIDTH 1
+/* Fields only relevent when PERIODIC_CHANGE is set */
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_LBN 3
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_WIDTH 1
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_LBN 4
+#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_WIDTH 1
+#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_LBN 16
+#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_WIDTH 16
+#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12
+
+#define MC_CMD_MAC_STATS_OUT_LEN 0
+
+/* Callisto flags */
+#define MC_CMD_SFT9001_ROBUST_LBN 0
+#define MC_CMD_SFT9001_ROBUST_WIDTH 1
+#define MC_CMD_SFT9001_SHORT_REACH_LBN 1
+#define MC_CMD_SFT9001_SHORT_REACH_WIDTH 1
+
+/* MC_CMD_SFT9001_GET:
+ * Read current callisto specific setting
+ *
+ * Locks required: None
+ * Returns: 0, ETIME
+ */
+#define MC_CMD_SFT9001_GET 0x30
+#define MC_CMD_SFT9001_GET_IN_LEN 0
+#define MC_CMD_SFT9001_GET_OUT_LEN 4
+#define MC_CMD_SFT9001_GET_OUT_FLAGS_OFST 0
+
+/* MC_CMD_SFT9001_SET:
+ * Write current callisto specific setting
+ *
+ * Locks required: None
+ * Returns: 0, ETIME, EINVAL
+ */
+#define MC_CMD_SFT9001_SET 0x31
+#define MC_CMD_SFT9001_SET_IN_LEN 4
+#define MC_CMD_SFT9001_SET_IN_FLAGS_OFST 0
+#define MC_CMD_SFT9001_SET_OUT_LEN 0
+
+
+/* MC_CMD_WOL_FILTER_SET:
+ * Set a WoL filter
+ *
+ * Locks required: None
+ * Returns: 0, EBUSY, EINVAL, ENOSYS
+ */
+#define MC_CMD_WOL_FILTER_SET 0x32
+#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 /* 190 rounded up to a word */
+#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
+#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
+
+/* There is a union at offset 8, following defines overlap due to
+ * this */
+#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
+
+#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST		\
+	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
+
+#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST   \
+	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
+#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST   \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 4)
+#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 8)
+#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 10)
+
+#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST   \
+	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
+#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST   \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 16)
+#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 32)
+#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST \
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 34)
+
+#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST	\
+	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
+#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_OFST		\
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 48)
+#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST	\
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 176)
+#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST	\
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 177)
+#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST	\
+	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 178)
+
+#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4
+#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0
+
+/* WOL Filter types enumeration */
+#define MC_CMD_WOL_TYPE_MAGIC      0x0
+			 /* unused 0x1 */
+#define MC_CMD_WOL_TYPE_WIN_MAGIC  0x2
+#define MC_CMD_WOL_TYPE_IPV4_SYN   0x3
+#define MC_CMD_WOL_TYPE_IPV6_SYN   0x4
+#define MC_CMD_WOL_TYPE_BITMAP     0x5
+#define MC_CMD_WOL_TYPE_MAX        0x6
+
+#define MC_CMD_FILTER_MODE_SIMPLE     0x0
+#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff
+
+/* MC_CMD_WOL_FILTER_REMOVE:
+ * Remove a WoL filter
+ *
+ * Locks required: None
+ * Returns: 0, EINVAL, ENOSYS
+ */
+#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4
+#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0
+#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0
+
+
+/* MC_CMD_WOL_FILTER_RESET:
+ * Reset (i.e. remove all) WoL filters
+ *
+ * Locks required: None
+ * Returns: 0, ENOSYS
+ */
+#define MC_CMD_WOL_FILTER_RESET 0x34
+#define MC_CMD_WOL_FILTER_RESET_IN_LEN 0
+#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0
+
+/* MC_CMD_SET_MCAST_HASH:
+ * Set the MCASH hash value without otherwise
+ * reconfiguring the MAC
+ */
+#define MC_CMD_SET_MCAST_HASH 0x35
+#define MC_CMD_SET_MCAST_HASH_IN_LEN 32
+#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0
+#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16
+#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0
+
+/* MC_CMD_NVRAM_TYPES:
+ * Return bitfield indicating available types of virtual NVRAM partitions
+ *
+ * Locks required: none
+ * Returns: 0
+ */
+#define MC_CMD_NVRAM_TYPES 0x36
+#define MC_CMD_NVRAM_TYPES_IN_LEN 0
+#define MC_CMD_NVRAM_TYPES_OUT_LEN 4
+#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0
+
+/* Supported NVRAM types */
+#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0
+#define MC_CMD_NVRAM_TYPE_MC_FW 1
+#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 2
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 3
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 4
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 5
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 6
+#define MC_CMD_NVRAM_TYPE_EXP_ROM 7
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 8
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 9
+#define MC_CMD_NVRAM_TYPE_PHY_PORT0 10
+#define MC_CMD_NVRAM_TYPE_PHY_PORT1 11
+#define MC_CMD_NVRAM_TYPE_LOG 12
+
+/* MC_CMD_NVRAM_INFO:
+ * Read info about a virtual NVRAM partition
+ *
+ * Locks required: none
+ * Returns: 0, EINVAL (bad type)
+ */
+#define MC_CMD_NVRAM_INFO 0x37
+#define MC_CMD_NVRAM_INFO_IN_LEN 4
+#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_INFO_OUT_LEN 24
+#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0
+#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4
+#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8
+#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
+#define   MC_CMD_NVRAM_PROTECTED_LBN 0
+#define   MC_CMD_NVRAM_PROTECTED_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
+#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20
+
+/* MC_CMD_NVRAM_UPDATE_START:
+ * Start a group of update operations on a virtual NVRAM partition
+ *
+ * Locks required: PHY_LOCK if type==*PHY*
+ * Returns: 0, EINVAL (bad type), EACCES (if PHY_LOCK required and not held)
+ */
+#define MC_CMD_NVRAM_UPDATE_START 0x38
+#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4
+#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0
+
+/* MC_CMD_NVRAM_READ:
+ * Read data from a virtual NVRAM partition
+ *
+ * Locks required: PHY_LOCK if type==*PHY*
+ * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+ */
+#define MC_CMD_NVRAM_READ 0x39
+#define MC_CMD_NVRAM_READ_IN_LEN 12
+#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4
+#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8
+#define MC_CMD_NVRAM_READ_OUT_LEN(_read_bytes) (_read_bytes)
+#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
+
+/* MC_CMD_NVRAM_WRITE:
+ * Write data to a virtual NVRAM partition
+ *
+ * Locks required: PHY_LOCK if type==*PHY*
+ * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+ */
+#define MC_CMD_NVRAM_WRITE 0x3a
+#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4
+#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8
+#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12
+#define MC_CMD_NVRAM_WRITE_IN_LEN(_write_bytes) (12 + _write_bytes)
+#define MC_CMD_NVRAM_WRITE_OUT_LEN 0
+
+/* MC_CMD_NVRAM_ERASE:
+ * Erase sector(s) from a virtual NVRAM partition
+ *
+ * Locks required: PHY_LOCK if type==*PHY*
+ * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+ */
+#define MC_CMD_NVRAM_ERASE 0x3b
+#define MC_CMD_NVRAM_ERASE_IN_LEN 12
+#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4
+#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8
+#define MC_CMD_NVRAM_ERASE_OUT_LEN 0
+
+/* MC_CMD_NVRAM_UPDATE_FINISH:
+ * Finish a group of update operations on a virtual NVRAM partition
+ *
+ * Locks required: PHY_LOCK if type==*PHY*
+ * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+ */
+#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 4
+#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0
+#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0
+
+/* MC_CMD_REBOOT:
+ * Reboot the MC. The AFTER_ASSERTION flag is intended to be used
+ * when the driver notices an assertion failure, to allow two ports to
+ * both recover (semi-)gracefully.
+ *
+ * Locks required: NONE
+ * Returns: Nothing. You get back a response with ERR=1, DATALEN=0
+ */
+#define MC_CMD_REBOOT 0x3d
+#define MC_CMD_REBOOT_IN_LEN 4
+#define MC_CMD_REBOOT_IN_FLAGS_OFST 0
+#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 1
+#define MC_CMD_REBOOT_OUT_LEN 0
+
+/* MC_CMD_SCHEDINFO:
+ * Request scheduler info. from the MC.
+ *
+ * Locks required: NONE
+ * Returns: An array of (timeslice,maximum overrun), one for each thread,
+ * in ascending order of thread address.s
+ */
+#define MC_CMD_SCHEDINFO 0x3e
+#define MC_CMD_SCHEDINFO_IN_LEN 0
+
+
+/* MC_CMD_SET_REBOOT_MODE: (debug)
+ * Set the mode for the next MC reboot.
+ *
+ * Locks required: NONE
+ *
+ * Sets the reboot mode to the specified value.  Returns the old mode.
+ */
+#define MC_CMD_REBOOT_MODE 0x3f
+#define MC_CMD_REBOOT_MODE_IN_LEN 4
+#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0
+#define MC_CMD_REBOOT_MODE_OUT_LEN 4
+#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0
+#define   MC_CMD_REBOOT_MODE_NORMAL 0
+#define   MC_CMD_REBOOT_MODE_SNAPPER 3
+
+/* MC_CMD_DEBUG_LOG:
+ * Null request/response command (debug)
+ * - sequence number is always zero
+ * - only supported on the UART interface
+ * (the same set of bytes is delivered as an
+ * event over PCI)
+ */
+#define MC_CMD_DEBUG_LOG 0x40
+#define MC_CMD_DEBUG_LOG_IN_LEN 0
+#define MC_CMD_DEBUG_LOG_OUT_LEN 0
+
+/* Generic sensor enumeration. Note that a dual port NIC
+ * will EITHER expose PHY_COMMON_TEMP OR PHY0_TEMP and
+ * PHY1_TEMP depending on whether there is a single sensor
+ * in the vicinity of the two port, or one per port.
+ */
+#define MC_CMD_SENSOR_CONTROLLER_TEMP 0		/* degC */
+#define MC_CMD_SENSOR_PHY_COMMON_TEMP 1		/* degC */
+#define MC_CMD_SENSOR_CONTROLLER_COOLING 2	/* bool */
+#define MC_CMD_SENSOR_PHY0_TEMP 3		/* degC */
+#define MC_CMD_SENSOR_PHY0_COOLING 4		/* bool */
+#define MC_CMD_SENSOR_PHY1_TEMP 5		/* degC */
+#define MC_CMD_SENSOR_PHY1_COOLING 6		/* bool */
+#define MC_CMD_SENSOR_IN_1V0 7			/* mV */
+#define MC_CMD_SENSOR_IN_1V2 8			/* mV */
+#define MC_CMD_SENSOR_IN_1V8 9			/* mV */
+#define MC_CMD_SENSOR_IN_2V5 10			/* mV */
+#define MC_CMD_SENSOR_IN_3V3 11			/* mV */
+#define MC_CMD_SENSOR_IN_12V0 12		/* mV */
+
+
+/* Sensor state */
+#define MC_CMD_SENSOR_STATE_OK 0
+#define MC_CMD_SENSOR_STATE_WARNING 1
+#define MC_CMD_SENSOR_STATE_FATAL 2
+#define MC_CMD_SENSOR_STATE_BROKEN 3
+
+/* MC_CMD_SENSOR_INFO:
+ * Returns information about every available sensor.
+ *
+ * Each sensor has a single (16bit) value, and a corresponding state.
+ * The mapping between value and sensor is nominally determined by the
+ * MC, but in practise is implemented as zero (BROKEN), one (TEMPERATURE),
+ * or two (VOLTAGE) ranges per sensor per state.
+ *
+ * This call returns a mask (32bit) of the sensors that are supported
+ * by this platform, then an array (indexed by MC_CMD_SENSOR) of byte
+ * offsets to the per-sensor arrays. Each sensor array has four 16bit
+ * numbers, min1, max1, min2, max2.
+ *
+ * Locks required: None
+ * Returns: 0
+ */
+#define MC_CMD_SENSOR_INFO 0x41
+#define MC_CMD_SENSOR_INFO_IN_LEN 0
+#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
+#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
+	(4 + (_x))
+#define MC_CMD_SENSOR_INFO_OUT_MIN1_OFST(_ofst) \
+	((_ofst) + 0)
+#define MC_CMD_SENSOR_INFO_OUT_MAX1_OFST(_ofst) \
+	((_ofst) + 2)
+#define MC_CMD_SENSOR_INFO_OUT_MIN2_OFST(_ofst) \
+	((_ofst) + 4)
+#define MC_CMD_SENSOR_INFO_OUT_MAX2_OFST(_ofst) \
+	((_ofst) + 6)
+
+/* MC_CMD_READ_SENSORS
+ * Returns the current (value, state) for each sensor
+ *
+ * Returns the current (value, state) [each 16bit] of each sensor supported by
+ * this board, by DMA'ing a sparse array (indexed by the sensor type) into host
+ * memory.
+ *
+ * The MC will send a SENSOREVT event every time any sensor changes state. The
+ * driver is responsible for ensuring that it doesn't miss any events. The board
+ * will function normally if all sensors are in STATE_OK or state_WARNING.
+ * Otherwise the board should not be expected to function.
+ */
+#define MC_CMD_READ_SENSORS 0x42
+#define MC_CMD_READ_SENSORS_IN_LEN 8
+#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
+#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
+#define MC_CMD_READ_SENSORS_OUT_LEN 0
+
+
+/* MC_CMD_GET_PHY_STATE:
+ * Report current state of PHY.  A "zombie" PHY is a PHY that has failed to
+ * boot (e.g. due to missing or corrupted firmware).
+ *
+ * Locks required: None
+ * Return code: 0
+ */
+#define MC_CMD_GET_PHY_STATE 0x43
+
+#define MC_CMD_GET_PHY_STATE_IN_LEN 0
+#define MC_CMD_GET_PHY_STATE_OUT_LEN 4
+#define MC_CMD_GET_PHY_STATE_STATE_OFST 0
+/* PHY state enumeration: */
+#define MC_CMD_PHY_STATE_OK 1
+#define MC_CMD_PHY_STATE_ZOMBIE 2
+
+
+/* 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to
+ * disable 802.Qbb for a given priority. */
+#define MC_CMD_SETUP_8021QBB 0x44
+#define MC_CMD_SETUP_8021QBB_IN_LEN 32
+#define MC_CMD_SETUP_8021QBB_OUT_LEN 0
+#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFFST 0
+
+
+/* MC_CMD_WOL_FILTER_GET:
+ * Retrieve ID of any WoL filters
+ *
+ * Locks required: None
+ * Returns: 0, ENOSYS
+ */
+#define MC_CMD_WOL_FILTER_GET 0x45
+#define MC_CMD_WOL_FILTER_GET_IN_LEN 0
+#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4
+#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0
+
+
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD:
+ * Offload a protocol to NIC for lights-out state
+ *
+ * Locks required: None
+ * Returns: 0, ENOSYS
+ */
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN 16
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
+
+/* There is a union at offset 4, following defines overlap due to
+ * this */
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPMAC_OFST 4
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPIP_OFST 10
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSMAC_OFST 4
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSSNIPV6_OFST 10
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSIPV6_OFST 26
+
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0
+
+
+/* MC_CMD_REMOVE_LIGHTSOUT_PROTOCOL_OFFLOAD:
+ * Offload a protocol to NIC for lights-out state
+ *
+ * Locks required: None
+ * Returns: 0, ENOSYS
+ */
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0
+
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4
+
+/* Lights-out offload protocols enumeration */
+#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1
+#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS  0x2
+
+
+/* MC_CMD_MAC_RESET_RESTORE:
+ * Restore MAC after block reset
+ *
+ * Locks required: None
+ * Returns: 0
+ */
+
+#define MC_CMD_MAC_RESET_RESTORE 0x48
+#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
+#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0
+
+#endif /* MCDI_PCOL_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_phy.c linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mcdi_phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mcdi_phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,574 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+/*
+ * Driver for PHY related operations via MCDI.
+ */
+
+#include "efx.h"
+#include "phy.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+#include "mdio_10g.h"
+
+struct efx_mcdi_phy_cfg {
+	u32 flags;
+	u32 type;
+	u32 supported_cap;
+	u32 channel;
+	u32 port;
+	u32 stats_mask;
+	u8 name[20];
+	u32 media;
+	u32 mmd_mask;
+	u8 revision[20];
+	u32 forced_cap;
+};
+
+static int
+efx_mcdi_get_phy_cfg(struct efx_nic *efx, struct efx_mcdi_phy_cfg *cfg)
+{
+	u8 outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_IN_LEN != 0);
+	BUILD_BUG_ON(MC_CMD_GET_PHY_CFG_OUT_NAME_LEN != sizeof(cfg->name));
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_CFG, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	if (outlen < MC_CMD_GET_PHY_CFG_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	cfg->flags = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_FLAGS);
+	cfg->type = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_TYPE);
+	cfg->supported_cap =
+		MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_SUPPORTED_CAP);
+	cfg->channel = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_CHANNEL);
+	cfg->port = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_PRT);
+	cfg->stats_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_STATS_MASK);
+	memcpy(cfg->name, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_NAME),
+	       sizeof(cfg->name));
+	cfg->media = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MEDIA_TYPE);
+	cfg->mmd_mask = MCDI_DWORD(outbuf, GET_PHY_CFG_OUT_MMD_MASK);
+	memcpy(cfg->revision, MCDI_PTR(outbuf, GET_PHY_CFG_OUT_REVISION),
+	       sizeof(cfg->revision));
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+static int efx_mcdi_set_link(struct efx_nic *efx, u32 capabilities,
+			     u32 flags, u32 loopback_mode,
+			     u32 loopback_speed)
+{
+	u8 inbuf[MC_CMD_SET_LINK_IN_LEN];
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_SET_LINK_OUT_LEN != 0);
+
+	MCDI_SET_DWORD(inbuf, SET_LINK_IN_CAP, capabilities);
+	MCDI_SET_DWORD(inbuf, SET_LINK_IN_FLAGS, flags);
+	MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_MODE, loopback_mode);
+	MCDI_SET_DWORD(inbuf, SET_LINK_IN_LOOPBACK_SPEED, loopback_speed);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_SET_LINK, inbuf, sizeof(inbuf),
+			  NULL, 0, NULL);
+	if (rc)
+		goto fail;
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
+{
+	u8 outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LOOPBACK_MODES, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	if (outlen < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
+		rc = -EMSGSIZE;
+		goto fail;
+	}
+
+	*loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_SUGGESTED);
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_mdio_read(struct efx_nic *efx, unsigned int bus,
+			 unsigned int prtad, unsigned int devad, u16 addr,
+			 u16 *value_out, u32 *status_out)
+{
+	u8 inbuf[MC_CMD_MDIO_READ_IN_LEN];
+	u8 outbuf[MC_CMD_MDIO_READ_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_BUS, bus);
+	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_PRTAD, prtad);
+	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_DEVAD, devad);
+	MCDI_SET_DWORD(inbuf, MDIO_READ_IN_ADDR, addr);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	*value_out = (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
+	*status_out = MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+int efx_mcdi_mdio_write(struct efx_nic *efx, unsigned int bus,
+			  unsigned int prtad, unsigned int devad, u16 addr,
+			  u16 value, u32 *status_out)
+{
+	u8 inbuf[MC_CMD_MDIO_WRITE_IN_LEN];
+	u8 outbuf[MC_CMD_MDIO_WRITE_OUT_LEN];
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_BUS, bus);
+	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_PRTAD, prtad);
+	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_DEVAD, devad);
+	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_ADDR, addr);
+	MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_VALUE, value);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		goto fail;
+
+	*status_out = MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS);
+	return 0;
+
+fail:
+	EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+	return rc;
+}
+
+static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
+{
+	u32 result = 0;
+
+	switch (media) {
+	case MC_CMD_MEDIA_KX4:
+		result |= SUPPORTED_Backplane;
+		if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
+			result |= SUPPORTED_1000baseKX_Full;
+		if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
+			result |= SUPPORTED_10000baseKX4_Full;
+		break;
+
+	case MC_CMD_MEDIA_XFP:
+	case MC_CMD_MEDIA_SFP_PLUS:
+		result |= SUPPORTED_FIBRE;
+		break;
+
+	case MC_CMD_MEDIA_BASE_T:
+		result |= SUPPORTED_TP;
+		if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
+			result |= SUPPORTED_10baseT_Half;
+		if (cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
+			result |= SUPPORTED_10baseT_Full;
+		if (cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
+			result |= SUPPORTED_100baseT_Half;
+		if (cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
+			result |= SUPPORTED_100baseT_Full;
+		if (cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
+			result |= SUPPORTED_1000baseT_Half;
+		if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
+			result |= SUPPORTED_1000baseT_Full;
+		if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
+			result |= SUPPORTED_10000baseT_Full;
+		break;
+	}
+
+	if (cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
+		result |= SUPPORTED_Pause;
+	if (cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+		result |= SUPPORTED_Asym_Pause;
+	if (cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+		result |= SUPPORTED_Autoneg;
+
+	return result;
+}
+
+static u32 ethtool_to_mcdi_cap(u32 cap)
+{
+	u32 result = 0;
+
+	if (cap & SUPPORTED_10baseT_Half)
+		result |= (1 << MC_CMD_PHY_CAP_10HDX_LBN);
+	if (cap & SUPPORTED_10baseT_Full)
+		result |= (1 << MC_CMD_PHY_CAP_10FDX_LBN);
+	if (cap & SUPPORTED_100baseT_Half)
+		result |= (1 << MC_CMD_PHY_CAP_100HDX_LBN);
+	if (cap & SUPPORTED_100baseT_Full)
+		result |= (1 << MC_CMD_PHY_CAP_100FDX_LBN);
+	if (cap & SUPPORTED_1000baseT_Half)
+		result |= (1 << MC_CMD_PHY_CAP_1000HDX_LBN);
+	if (cap & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseKX_Full))
+		result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
+	if (cap & (SUPPORTED_10000baseT_Full | SUPPORTED_10000baseKX4_Full))
+		result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
+	if (cap & SUPPORTED_Pause)
+		result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
+	if (cap & SUPPORTED_Asym_Pause)
+		result |= (1 << MC_CMD_PHY_CAP_ASYM_LBN);
+	if (cap & SUPPORTED_Autoneg)
+		result |= (1 << MC_CMD_PHY_CAP_AN_LBN);
+
+	return result;
+}
+
+static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
+{
+	struct efx_mcdi_phy_cfg *phy_cfg = efx->phy_data;
+	enum efx_phy_mode mode, supported;
+	u32 flags;
+
+	/* TODO: Advertise the capabilities supported by this PHY */
+	supported = 0;
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_TXDIS_LBN))
+		supported |= PHY_MODE_TX_DISABLED;
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_LOWPOWER_LBN))
+		supported |= PHY_MODE_LOW_POWER;
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_POWEROFF_LBN))
+		supported |= PHY_MODE_OFF;
+
+	mode = efx->phy_mode & supported;
+
+	flags = 0;
+	if (mode & PHY_MODE_TX_DISABLED)
+		flags |= (1 << MC_CMD_SET_LINK_TXDIS_LBN);
+	if (mode & PHY_MODE_LOW_POWER)
+		flags |= (1 << MC_CMD_SET_LINK_LOWPOWER_LBN);
+	if (mode & PHY_MODE_OFF)
+		flags |= (1 << MC_CMD_SET_LINK_POWEROFF_LBN);
+
+	return flags;
+}
+
+static u32 mcdi_to_ethtool_media(u32 media)
+{
+	switch (media) {
+	case MC_CMD_MEDIA_XAUI:
+	case MC_CMD_MEDIA_CX4:
+	case MC_CMD_MEDIA_KX4:
+		return PORT_OTHER;
+
+	case MC_CMD_MEDIA_XFP:
+	case MC_CMD_MEDIA_SFP_PLUS:
+		return PORT_FIBRE;
+
+	case MC_CMD_MEDIA_BASE_T:
+		return PORT_TP;
+
+	default:
+		return PORT_OTHER;
+	}
+}
+
+static int efx_mcdi_phy_probe(struct efx_nic *efx)
+{
+	struct efx_mcdi_phy_cfg *phy_data;
+	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
+	u32 caps;
+	int rc;
+
+	/* Initialise and populate phy_data */
+	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
+	if (phy_data == NULL)
+		return -ENOMEM;
+
+	rc = efx_mcdi_get_phy_cfg(efx, phy_data);
+	if (rc != 0)
+		goto fail;
+
+	/* Read initial link advertisement */
+	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
+			  outbuf, sizeof(outbuf), NULL);
+	if (rc)
+		goto fail;
+
+	/* Fill out nic state */
+	efx->phy_data = phy_data;
+	efx->phy_type = phy_data->type;
+
+	efx->mdio_bus = phy_data->channel;
+	efx->mdio.prtad = phy_data->port;
+	efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
+	efx->mdio.mode_support = 0;
+	if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
+		efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
+	if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
+		efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+
+	caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
+	if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
+		efx->link_advertising =
+			mcdi_to_ethtool_cap(phy_data->media, caps);
+	else
+		phy_data->forced_cap = caps;
+
+	/* Assert that we can map efx -> mcdi loopback modes */
+	BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE);
+	BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA);
+	BUILD_BUG_ON(LOOPBACK_GMAC != MC_CMD_LOOPBACK_GMAC);
+	BUILD_BUG_ON(LOOPBACK_XGMII != MC_CMD_LOOPBACK_XGMII);
+	BUILD_BUG_ON(LOOPBACK_XGXS != MC_CMD_LOOPBACK_XGXS);
+	BUILD_BUG_ON(LOOPBACK_XAUI != MC_CMD_LOOPBACK_XAUI);
+	BUILD_BUG_ON(LOOPBACK_GMII != MC_CMD_LOOPBACK_GMII);
+	BUILD_BUG_ON(LOOPBACK_SGMII != MC_CMD_LOOPBACK_SGMII);
+	BUILD_BUG_ON(LOOPBACK_XGBR != MC_CMD_LOOPBACK_XGBR);
+	BUILD_BUG_ON(LOOPBACK_XFI != MC_CMD_LOOPBACK_XFI);
+	BUILD_BUG_ON(LOOPBACK_XAUI_FAR != MC_CMD_LOOPBACK_XAUI_FAR);
+	BUILD_BUG_ON(LOOPBACK_GMII_FAR != MC_CMD_LOOPBACK_GMII_FAR);
+	BUILD_BUG_ON(LOOPBACK_SGMII_FAR != MC_CMD_LOOPBACK_SGMII_FAR);
+	BUILD_BUG_ON(LOOPBACK_XFI_FAR != MC_CMD_LOOPBACK_XFI_FAR);
+	BUILD_BUG_ON(LOOPBACK_GPHY != MC_CMD_LOOPBACK_GPHY);
+	BUILD_BUG_ON(LOOPBACK_PHYXS != MC_CMD_LOOPBACK_PHYXS);
+	BUILD_BUG_ON(LOOPBACK_PCS != MC_CMD_LOOPBACK_PCS);
+	BUILD_BUG_ON(LOOPBACK_PMAPMD != MC_CMD_LOOPBACK_PMAPMD);
+	BUILD_BUG_ON(LOOPBACK_XPORT != MC_CMD_LOOPBACK_XPORT);
+	BUILD_BUG_ON(LOOPBACK_XGMII_WS != MC_CMD_LOOPBACK_XGMII_WS);
+	BUILD_BUG_ON(LOOPBACK_XAUI_WS != MC_CMD_LOOPBACK_XAUI_WS);
+	BUILD_BUG_ON(LOOPBACK_XAUI_WS_FAR != MC_CMD_LOOPBACK_XAUI_WS_FAR);
+	BUILD_BUG_ON(LOOPBACK_XAUI_WS_NEAR != MC_CMD_LOOPBACK_XAUI_WS_NEAR);
+	BUILD_BUG_ON(LOOPBACK_GMII_WS != MC_CMD_LOOPBACK_GMII_WS);
+	BUILD_BUG_ON(LOOPBACK_XFI_WS != MC_CMD_LOOPBACK_XFI_WS);
+	BUILD_BUG_ON(LOOPBACK_XFI_WS_FAR != MC_CMD_LOOPBACK_XFI_WS_FAR);
+	BUILD_BUG_ON(LOOPBACK_PHYXS_WS != MC_CMD_LOOPBACK_PHYXS_WS);
+
+	rc = efx_mcdi_loopback_modes(efx, &efx->loopback_modes);
+	if (rc != 0)
+		goto fail;
+	/* The MC indicates that LOOPBACK_NONE is a valid loopback mode,
+	 * but by convention we don't */
+	efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
+
+	return 0;
+
+fail:
+	kfree(phy_data);
+	return rc;
+}
+
+int efx_mcdi_phy_reconfigure(struct efx_nic *efx)
+{
+	struct efx_mcdi_phy_cfg *phy_cfg = efx->phy_data;
+	u32 caps = (efx->link_advertising ?
+		    ethtool_to_mcdi_cap(efx->link_advertising) :
+		    phy_cfg->forced_cap);
+
+	return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
+				 efx->loopback_mode, 0);
+}
+
+void efx_mcdi_phy_decode_link(struct efx_nic *efx,
+			      struct efx_link_state *link_state,
+			      u32 speed, u32 flags, u32 fcntl)
+{
+	switch (fcntl) {
+	case MC_CMD_FCNTL_AUTO:
+		WARN_ON(1);	/* This is not a link mode */
+		link_state->fc = EFX_FC_AUTO | EFX_FC_TX | EFX_FC_RX;
+		break;
+	case MC_CMD_FCNTL_BIDIR:
+		link_state->fc = EFX_FC_TX | EFX_FC_RX;
+		break;
+	case MC_CMD_FCNTL_RESPOND:
+		link_state->fc = EFX_FC_RX;
+		break;
+	default:
+		WARN_ON(1);
+	case MC_CMD_FCNTL_OFF:
+		link_state->fc = 0;
+		break;
+	}
+
+	link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_LINK_UP_LBN));
+	link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_FULL_DUPLEX_LBN));
+	link_state->speed = speed;
+}
+
+/* Verify that the forced flow control settings (!EFX_FC_AUTO) are
+ * supported by the link partner. Warn the user if this isn't the case
+ */
+void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
+{
+	struct efx_mcdi_phy_cfg *phy_cfg = efx->phy_data;
+	u32 rmtadv;
+
+	/* The link partner capabilities are only relevent if the
+	 * link supports flow control autonegotiation */
+	if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+		return;
+
+	/* If flow control autoneg is supported and enabled, then fine */
+	if (efx->wanted_fc & EFX_FC_AUTO)
+		return;
+
+	rmtadv = 0;
+	if (lpa & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
+		rmtadv |= ADVERTISED_Pause;
+	if (lpa & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+		rmtadv |=  ADVERTISED_Asym_Pause;
+
+	if ((efx->wanted_fc & EFX_FC_TX) && rmtadv == ADVERTISED_Asym_Pause)
+		EFX_ERR(efx, "warning: link partner doesn't support "
+			"pause frames");
+}
+
+static bool efx_mcdi_phy_poll(struct efx_nic *efx)
+{
+	struct efx_link_state old_state = efx->link_state;
+	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
+	int rc;
+
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
+	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
+			  outbuf, sizeof(outbuf), NULL);
+	if (rc) {
+		EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+		efx->link_state.up = false;
+	} else {
+		efx_mcdi_phy_decode_link(
+			efx, &efx->link_state,
+			MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
+			MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
+			MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
+	}
+
+	return !efx_link_state_equal(&efx->link_state, &old_state);
+}
+
+static void efx_mcdi_phy_remove(struct efx_nic *efx)
+{
+	struct efx_mcdi_phy_data *phy_data = efx->phy_data;
+
+	efx->phy_data = NULL;
+	kfree(phy_data);
+}
+
+static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+	struct efx_mcdi_phy_cfg *phy_cfg = efx->phy_data;
+	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
+	int rc;
+
+	ecmd->supported =
+		mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
+	ecmd->advertising = efx->link_advertising;
+	ecmd->speed = efx->link_state.speed;
+	ecmd->duplex = efx->link_state.fd;
+	ecmd->port = mcdi_to_ethtool_media(phy_cfg->media);
+	ecmd->phy_address = phy_cfg->port;
+	ecmd->transceiver = XCVR_INTERNAL;
+	ecmd->autoneg = !!(efx->link_advertising & ADVERTISED_Autoneg);
+	ecmd->mdio_support = (efx->mdio.mode_support &
+			      (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
+
+	BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0);
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
+			  outbuf, sizeof(outbuf), NULL);
+	if (rc) {
+		EFX_ERR(efx, "%s: failed rc=%d\n", __func__, rc);
+		return;
+	}
+	ecmd->lp_advertising =
+		mcdi_to_ethtool_cap(phy_cfg->media,
+				    MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP));
+}
+
+static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+	struct efx_mcdi_phy_cfg *phy_cfg = efx->phy_data;
+	u32 caps;
+	int rc;
+
+	if (ecmd->autoneg) {
+		caps = (ethtool_to_mcdi_cap(ecmd->advertising) |
+			 1 << MC_CMD_PHY_CAP_AN_LBN);
+	} else if (ecmd->duplex) {
+		switch (ecmd->speed) {
+		case 10:    caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN;    break;
+		case 100:   caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;   break;
+		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;  break;
+		case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
+		default:    return -EINVAL;
+		}
+	} else {
+		switch (ecmd->speed) {
+		case 10:    caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN;    break;
+		case 100:   caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN;   break;
+		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN;  break;
+		default:    return -EINVAL;
+		}
+	}
+
+	rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx),
+			       efx->loopback_mode, 0);
+	if (rc)
+		return rc;
+
+	if (ecmd->autoneg) {
+		efx_link_set_advertising(
+			efx, ecmd->advertising | ADVERTISED_Autoneg);
+		phy_cfg->forced_cap = 0;
+	} else {
+		efx_link_set_advertising(efx, 0);
+		phy_cfg->forced_cap = caps;
+	}
+	return 0;
+}
+
+struct efx_phy_operations efx_mcdi_phy_ops = {
+	.probe		= efx_mcdi_phy_probe,
+	.init 	 	= efx_port_dummy_op_int,
+	.reconfigure	= efx_mcdi_phy_reconfigure,
+	.poll		= efx_mcdi_phy_poll,
+	.fini		= efx_port_dummy_op_void,
+	.remove		= efx_mcdi_phy_remove,
+	.get_settings	= efx_mcdi_phy_get_settings,
+	.set_settings	= efx_mcdi_phy_set_settings,
+	.run_tests	= NULL,
+	.test_name	= NULL,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mdio_10g.c linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mdio_10g.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -14,8 +14,8 @@
 #include <linux/delay.h>
 #include "net_driver.h"
 #include "mdio_10g.h"
-#include "boards.h"
 #include "workarounds.h"
+#include "nic.h"
 
 unsigned efx_mdio_id_oui(u32 id)
 {
@@ -174,7 +174,7 @@ bool efx_mdio_links_ok(struct efx_nic *e
 	 * of mmd's */
 	if (LOOPBACK_INTERNAL(efx))
 		return true;
-	else if (efx->loopback_mode == LOOPBACK_NETWORK)
+	else if (LOOPBACK_MASK(efx) & LOOPBACKS_WS)
 		return false;
 	else if (efx_phy_mode_disabled(efx->phy_mode))
 		return false;
@@ -211,7 +211,7 @@ void efx_mdio_phy_reconfigure(struct efx
 			  efx->loopback_mode == LOOPBACK_PCS);
 	efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
 			  MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
-			  efx->loopback_mode == LOOPBACK_NETWORK);
+			  efx->loopback_mode == LOOPBACK_PHYXS_WS);
 }
 
 static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
@@ -249,8 +249,6 @@ void efx_mdio_set_mmds_lpower(struct efx
 int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
 	struct ethtool_cmd prev;
-	u32 required;
-	int reg;
 
 	efx->phy_op->get_settings(efx, &prev);
 
@@ -266,86 +264,74 @@ int efx_mdio_set_settings(struct efx_nic
 		return -EINVAL;
 
 	/* Check that PHY supports these settings */
-	if (ecmd->autoneg) {
-		required = SUPPORTED_Autoneg;
-	} else if (ecmd->duplex) {
-		switch (ecmd->speed) {
-		case SPEED_10:  required = SUPPORTED_10baseT_Full;  break;
-		case SPEED_100: required = SUPPORTED_100baseT_Full; break;
-		default:        return -EINVAL;
-		}
-	} else {
-		switch (ecmd->speed) {
-		case SPEED_10:  required = SUPPORTED_10baseT_Half;  break;
-		case SPEED_100: required = SUPPORTED_100baseT_Half; break;
-		default:        return -EINVAL;
-		}
-	}
-	required |= ecmd->advertising;
-	if (required & ~prev.supported)
+	if (!ecmd->autoneg ||
+	    (ecmd->advertising | SUPPORTED_Autoneg) & ~prev.supported)
 		return -EINVAL;
 
-	if (ecmd->autoneg) {
-		bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
-			    || EFX_WORKAROUND_13204(efx));
+	efx_link_set_advertising(efx, ecmd->advertising | ADVERTISED_Autoneg);
+	efx_mdio_an_reconfigure(efx);
+	return 0;
+}
 
-		/* Set up the base page */
-		reg = ADVERTISE_CSMA;
-		if (ecmd->advertising & ADVERTISED_10baseT_Half)
-			reg |= ADVERTISE_10HALF;
-		if (ecmd->advertising & ADVERTISED_10baseT_Full)
-			reg |= ADVERTISE_10FULL;
-		if (ecmd->advertising & ADVERTISED_100baseT_Half)
-			reg |= ADVERTISE_100HALF;
-		if (ecmd->advertising & ADVERTISED_100baseT_Full)
-			reg |= ADVERTISE_100FULL;
-		if (xnp)
-			reg |= ADVERTISE_RESV;
-		else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
-					      ADVERTISED_1000baseT_Full))
-			reg |= ADVERTISE_NPAGE;
-		reg |= mii_advertise_flowctrl(efx->wanted_fc);
-		efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
+/**
+ * efx_mdio_an_reconfigure - Push advertising flags and restart autonegotiation
+ * @efx:		Efx NIC
+ */
+void efx_mdio_an_reconfigure(struct efx_nic *efx)
+{
+	bool xnp = (efx->link_advertising & ADVERTISED_10000baseT_Full
+		    || EFX_WORKAROUND_13204(efx));
+	int reg;
 
-		/* Set up the (extended) next page if necessary */
-		if (efx->phy_op->set_npage_adv)
-			efx->phy_op->set_npage_adv(efx, ecmd->advertising);
+	WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN));
 
-		/* Enable and restart AN */
-		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
-		reg |= MDIO_AN_CTRL1_ENABLE;
-		if (!(EFX_WORKAROUND_15195(efx) &&
-		      LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
-			reg |= MDIO_AN_CTRL1_RESTART;
-		if (xnp)
-			reg |= MDIO_AN_CTRL1_XNP;
-		else
-			reg &= ~MDIO_AN_CTRL1_XNP;
-		efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
-	} else {
-		/* Disable AN */
-		efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
-				  MDIO_AN_CTRL1_ENABLE, false);
+	/* Set up the base page */
+	reg = ADVERTISE_CSMA;
+	if (efx->link_advertising & ADVERTISED_10baseT_Half)
+		reg |= ADVERTISE_10HALF;
+	if (efx->link_advertising & ADVERTISED_10baseT_Full)
+		reg |= ADVERTISE_10FULL;
+	if (efx->link_advertising & ADVERTISED_100baseT_Half)
+		reg |= ADVERTISE_100HALF;
+	if (efx->link_advertising & ADVERTISED_100baseT_Full)
+		reg |= ADVERTISE_100FULL;
+	if (xnp)
+		reg |= ADVERTISE_RESV;
+	else if (efx->link_advertising & (ADVERTISED_1000baseT_Half |
+					  ADVERTISED_1000baseT_Full))
+		reg |= ADVERTISE_NPAGE;
+	if (efx->link_advertising & ADVERTISED_Pause)
+		reg |= ADVERTISE_PAUSE_CAP;
+	if (efx->link_advertising & ADVERTISED_Asym_Pause)
+		reg |= ADVERTISE_PAUSE_ASYM;
+	efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
 
-		/* Set the basic control bits */
-		reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
-		reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
-		if (ecmd->speed == SPEED_100)
-			reg |= MDIO_PMA_CTRL1_SPEED100;
-		if (ecmd->duplex)
-			reg |= MDIO_CTRL1_FULLDPLX;
-		efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
-	}
+	/* Set up the (extended) next page if necessary */
+	if (efx->phy_op->set_npage_adv)
+		efx->phy_op->set_npage_adv(efx, efx->link_advertising);
 
-	return 0;
+	/* Enable and restart AN */
+	reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+	reg |= MDIO_AN_CTRL1_ENABLE;
+	if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_EXTERNAL(efx)))
+		reg |= MDIO_AN_CTRL1_RESTART;
+	if (xnp)
+		reg |= MDIO_AN_CTRL1_XNP;
+	else
+		reg &= ~MDIO_AN_CTRL1_XNP;
+	efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
 }
 
 enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
 {
-	int lpa;
+	BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
 
-	if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
+	if (!(efx->wanted_fc & EFX_FC_AUTO))
 		return efx->wanted_fc;
-	lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
-	return efx_fc_resolve(efx->wanted_fc, lpa);
+
+	WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN));
+
+	return mii_resolve_flowctrl_fdx(
+		mii_advertise_flowctrl(efx->wanted_fc),
+		efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA));
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mdio_10g.h linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mdio_10g.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mdio_10g.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -17,7 +17,6 @@
  */
 
 #include "efx.h"
-#include "boards.h"
 
 static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; }
 static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
@@ -87,6 +86,9 @@ extern void efx_mdio_set_mmds_lpower(str
 /* Set (some of) the PHY settings over MDIO */
 extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
 
+/* Push advertising flags and restart autonegotiation */
+extern void efx_mdio_an_reconfigure(struct efx_nic *efx);
+
 /* Get pause parameters from AN if available (otherwise return
  * requested pause parameters)
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/mtd.c linux-libre-2.6.33-gnu1/drivers/net/sfc/mtd.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/mtd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/mtd.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,36 +1,79 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
  */
 
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/delay.h>
+#include <linux/rtnetlink.h>
 
 #define EFX_DRIVER_NAME "sfc_mtd"
 #include "net_driver.h"
 #include "spi.h"
 #include "efx.h"
+#include "nic.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
 
 #define EFX_SPI_VERIFY_BUF_LEN 16
 
-struct efx_mtd {
-	const struct efx_spi_device *spi;
+struct efx_mtd_partition {
 	struct mtd_info mtd;
+	union {
+		struct {
+			bool updating;
+			u8 nvram_type;
+			u16 fw_subtype;
+		} mcdi;
+		size_t offset;
+	};
+	const char *type_name;
 	char name[IFNAMSIZ + 20];
 };
 
+struct efx_mtd_ops {
+	int (*read)(struct mtd_info *mtd, loff_t start, size_t len,
+		    size_t *retlen, u8 *buffer);
+	int (*erase)(struct mtd_info *mtd, loff_t start, size_t len);
+	int (*write)(struct mtd_info *mtd, loff_t start, size_t len,
+		     size_t *retlen, const u8 *buffer);
+	int (*sync)(struct mtd_info *mtd);
+};
+
+struct efx_mtd {
+	struct list_head node;
+	struct efx_nic *efx;
+	const struct efx_spi_device *spi;
+	const char *name;
+	const struct efx_mtd_ops *ops;
+	size_t n_parts;
+	struct efx_mtd_partition part[0];
+};
+
+#define efx_for_each_partition(part, efx_mtd)			\
+	for ((part) = &(efx_mtd)->part[0];			\
+	     (part) != &(efx_mtd)->part[(efx_mtd)->n_parts];	\
+	     (part)++)
+
+#define to_efx_mtd_partition(mtd)				\
+	container_of(mtd, struct efx_mtd_partition, mtd)
+
+static int falcon_mtd_probe(struct efx_nic *efx);
+static int siena_mtd_probe(struct efx_nic *efx);
+
 /* SPI utilities */
 
 static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, bool uninterruptible)
 {
 	const struct efx_spi_device *spi = efx_mtd->spi;
-	struct efx_nic *efx = spi->efx;
+	struct efx_nic *efx = efx_mtd->efx;
 	u8 status;
 	int rc, i;
 
@@ -39,7 +82,7 @@ static int efx_spi_slow_wait(struct efx_
 		__set_current_state(uninterruptible ?
 				    TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
 		schedule_timeout(HZ / 10);
-		rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
+		rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
 				    &status, sizeof(status));
 		if (rc)
 			return rc;
@@ -52,32 +95,35 @@ static int efx_spi_slow_wait(struct efx_
 	return -ETIMEDOUT;
 }
 
-static int efx_spi_unlock(const struct efx_spi_device *spi)
+static int
+efx_spi_unlock(struct efx_nic *efx, const struct efx_spi_device *spi)
 {
 	const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
 				SPI_STATUS_BP0);
 	u8 status;
 	int rc;
 
-	rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, &status, sizeof(status));
+	rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
+			    &status, sizeof(status));
 	if (rc)
 		return rc;
 
 	if (!(status & unlock_mask))
 		return 0; /* already unlocked */
 
-	rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+	rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
 	if (rc)
 		return rc;
-	rc = falcon_spi_cmd(spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
+	rc = falcon_spi_cmd(efx, spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
 	if (rc)
 		return rc;
 
 	status &= ~unlock_mask;
-	rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status));
+	rc = falcon_spi_cmd(efx, spi, SPI_WRSR, -1, &status,
+			    NULL, sizeof(status));
 	if (rc)
 		return rc;
-	rc = falcon_spi_wait_write(spi);
+	rc = falcon_spi_wait_write(efx, spi);
 	if (rc)
 		return rc;
 
@@ -87,6 +133,7 @@ static int efx_spi_unlock(const struct e
 static int efx_spi_erase(struct efx_mtd *efx_mtd, loff_t start, size_t len)
 {
 	const struct efx_spi_device *spi = efx_mtd->spi;
+	struct efx_nic *efx = efx_mtd->efx;
 	unsigned pos, block_len;
 	u8 empty[EFX_SPI_VERIFY_BUF_LEN];
 	u8 buffer[EFX_SPI_VERIFY_BUF_LEN];
@@ -98,13 +145,14 @@ static int efx_spi_erase(struct efx_mtd
 	if (spi->erase_command == 0)
 		return -EOPNOTSUPP;
 
-	rc = efx_spi_unlock(spi);
+	rc = efx_spi_unlock(efx, spi);
 	if (rc)
 		return rc;
-	rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+	rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
 	if (rc)
 		return rc;
-	rc = falcon_spi_cmd(spi, spi->erase_command, start, NULL, NULL, 0);
+	rc = falcon_spi_cmd(efx, spi, spi->erase_command, start, NULL,
+			    NULL, 0);
 	if (rc)
 		return rc;
 	rc = efx_spi_slow_wait(efx_mtd, false);
@@ -113,7 +161,8 @@ static int efx_spi_erase(struct efx_mtd
 	memset(empty, 0xff, sizeof(empty));
 	for (pos = 0; pos < len; pos += block_len) {
 		block_len = min(len - pos, sizeof(buffer));
-		rc = falcon_spi_read(spi, start + pos, block_len, NULL, buffer);
+		rc = falcon_spi_read(efx, spi, start + pos, block_len,
+				     NULL, buffer);
 		if (rc)
 			return rc;
 		if (memcmp(empty, buffer, block_len))
@@ -130,140 +179,473 @@ static int efx_spi_erase(struct efx_mtd
 
 /* MTD interface */
 
-static int efx_mtd_read(struct mtd_info *mtd, loff_t start, size_t len,
-			size_t *retlen, u8 *buffer)
+static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
 {
 	struct efx_mtd *efx_mtd = mtd->priv;
+	int rc;
+
+	rc = efx_mtd->ops->erase(mtd, erase->addr, erase->len);
+	if (rc == 0) {
+		erase->state = MTD_ERASE_DONE;
+	} else {
+		erase->state = MTD_ERASE_FAILED;
+		erase->fail_addr = 0xffffffff;
+	}
+	mtd_erase_callback(erase);
+	return rc;
+}
+
+static void efx_mtd_sync(struct mtd_info *mtd)
+{
+	struct efx_mtd *efx_mtd = mtd->priv;
+	struct efx_nic *efx = efx_mtd->efx;
+	int rc;
+
+	rc = efx_mtd->ops->sync(mtd);
+	if (rc)
+		EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc);
+}
+
+static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
+{
+	int rc;
+
+	for (;;) {
+		rc = del_mtd_device(&part->mtd);
+		if (rc != -EBUSY)
+			break;
+		ssleep(1);
+	}
+	WARN_ON(rc);
+}
+
+static void efx_mtd_remove_device(struct efx_mtd *efx_mtd)
+{
+	struct efx_mtd_partition *part;
+
+	efx_for_each_partition(part, efx_mtd)
+		efx_mtd_remove_partition(part);
+	list_del(&efx_mtd->node);
+	kfree(efx_mtd);
+}
+
+static void efx_mtd_rename_device(struct efx_mtd *efx_mtd)
+{
+	struct efx_mtd_partition *part;
+
+	efx_for_each_partition(part, efx_mtd)
+		if (efx_nic_rev(efx_mtd->efx) >= EFX_REV_SIENA_A0)
+			snprintf(part->name, sizeof(part->name),
+				 "%s %s:%02x", efx_mtd->efx->name,
+				 part->type_name, part->mcdi.fw_subtype);
+		else
+			snprintf(part->name, sizeof(part->name),
+				 "%s %s", efx_mtd->efx->name,
+				 part->type_name);
+}
+
+static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd)
+{
+	struct efx_mtd_partition *part;
+
+	efx_mtd->efx = efx;
+
+	efx_mtd_rename_device(efx_mtd);
+
+	efx_for_each_partition(part, efx_mtd) {
+		part->mtd.writesize = 1;
+
+		part->mtd.owner = THIS_MODULE;
+		part->mtd.priv = efx_mtd;
+		part->mtd.name = part->name;
+		part->mtd.erase = efx_mtd_erase;
+		part->mtd.read = efx_mtd->ops->read;
+		part->mtd.write = efx_mtd->ops->write;
+		part->mtd.sync = efx_mtd_sync;
+
+		if (add_mtd_device(&part->mtd))
+			goto fail;
+	}
+
+	list_add(&efx_mtd->node, &efx->mtd_list);
+	return 0;
+
+fail:
+	while (part != &efx_mtd->part[0]) {
+		--part;
+		efx_mtd_remove_partition(part);
+	}
+	/* add_mtd_device() returns 1 if the MTD table is full */
+	return -ENOMEM;
+}
+
+void efx_mtd_remove(struct efx_nic *efx)
+{
+	struct efx_mtd *efx_mtd, *next;
+
+	WARN_ON(efx_dev_registered(efx));
+
+	list_for_each_entry_safe(efx_mtd, next, &efx->mtd_list, node)
+		efx_mtd_remove_device(efx_mtd);
+}
+
+void efx_mtd_rename(struct efx_nic *efx)
+{
+	struct efx_mtd *efx_mtd;
+
+	ASSERT_RTNL();
+
+	list_for_each_entry(efx_mtd, &efx->mtd_list, node)
+		efx_mtd_rename_device(efx_mtd);
+}
+
+int efx_mtd_probe(struct efx_nic *efx)
+{
+	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
+		return siena_mtd_probe(efx);
+	else
+		return falcon_mtd_probe(efx);
+}
+
+/* Implementation of MTD operations for Falcon */
+
+static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
+			   size_t len, size_t *retlen, u8 *buffer)
+{
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
+	struct efx_mtd *efx_mtd = mtd->priv;
 	const struct efx_spi_device *spi = efx_mtd->spi;
-	struct efx_nic *efx = spi->efx;
+	struct efx_nic *efx = efx_mtd->efx;
 	int rc;
 
 	rc = mutex_lock_interruptible(&efx->spi_lock);
 	if (rc)
 		return rc;
-	rc = falcon_spi_read(spi, FALCON_FLASH_BOOTCODE_START + start,
-			     len, retlen, buffer);
+	rc = falcon_spi_read(efx, spi, part->offset + start, len,
+			     retlen, buffer);
 	mutex_unlock(&efx->spi_lock);
 	return rc;
 }
 
-static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
+static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
 {
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
 	struct efx_mtd *efx_mtd = mtd->priv;
-	struct efx_nic *efx = efx_mtd->spi->efx;
+	struct efx_nic *efx = efx_mtd->efx;
 	int rc;
 
 	rc = mutex_lock_interruptible(&efx->spi_lock);
 	if (rc)
 		return rc;
-	rc = efx_spi_erase(efx_mtd, FALCON_FLASH_BOOTCODE_START + erase->addr,
-			   erase->len);
+	rc = efx_spi_erase(efx_mtd, part->offset + start, len);
 	mutex_unlock(&efx->spi_lock);
-
-	if (rc == 0) {
-		erase->state = MTD_ERASE_DONE;
-	} else {
-		erase->state = MTD_ERASE_FAILED;
-		erase->fail_addr = 0xffffffff;
-	}
-	mtd_erase_callback(erase);
 	return rc;
 }
 
-static int efx_mtd_write(struct mtd_info *mtd, loff_t start,
-			 size_t len, size_t *retlen, const u8 *buffer)
+static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
+			    size_t len, size_t *retlen, const u8 *buffer)
 {
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
 	struct efx_mtd *efx_mtd = mtd->priv;
 	const struct efx_spi_device *spi = efx_mtd->spi;
-	struct efx_nic *efx = spi->efx;
+	struct efx_nic *efx = efx_mtd->efx;
 	int rc;
 
 	rc = mutex_lock_interruptible(&efx->spi_lock);
 	if (rc)
 		return rc;
-	rc = falcon_spi_write(spi, FALCON_FLASH_BOOTCODE_START + start,
-			      len, retlen, buffer);
+	rc = falcon_spi_write(efx, spi, part->offset + start, len,
+			      retlen, buffer);
 	mutex_unlock(&efx->spi_lock);
 	return rc;
 }
 
-static void efx_mtd_sync(struct mtd_info *mtd)
+static int falcon_mtd_sync(struct mtd_info *mtd)
 {
 	struct efx_mtd *efx_mtd = mtd->priv;
-	struct efx_nic *efx = efx_mtd->spi->efx;
+	struct efx_nic *efx = efx_mtd->efx;
 	int rc;
 
 	mutex_lock(&efx->spi_lock);
 	rc = efx_spi_slow_wait(efx_mtd, true);
 	mutex_unlock(&efx->spi_lock);
+	return rc;
+}
+
+static struct efx_mtd_ops falcon_mtd_ops = {
+	.read	= falcon_mtd_read,
+	.erase	= falcon_mtd_erase,
+	.write	= falcon_mtd_write,
+	.sync	= falcon_mtd_sync,
+};
+
+static int falcon_mtd_probe(struct efx_nic *efx)
+{
+	struct efx_spi_device *spi = efx->spi_flash;
+	struct efx_mtd *efx_mtd;
+	int rc;
+
+	ASSERT_RTNL();
+
+	if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
+		return -ENODEV;
+
+	efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
+			  GFP_KERNEL);
+	if (!efx_mtd)
+		return -ENOMEM;
+
+	efx_mtd->spi = spi;
+	efx_mtd->name = "flash";
+	efx_mtd->ops = &falcon_mtd_ops;
+
+	efx_mtd->n_parts = 1;
+	efx_mtd->part[0].mtd.type = MTD_NORFLASH;
+	efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH;
+	efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
+	efx_mtd->part[0].mtd.erasesize = spi->erase_size;
+	efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START;
+	efx_mtd->part[0].type_name = "sfc_flash_bootrom";
 
+	rc = efx_mtd_probe_device(efx, efx_mtd);
 	if (rc)
-		EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc);
-	return;
+		kfree(efx_mtd);
+	return rc;
 }
 
-void efx_mtd_remove(struct efx_nic *efx)
+/* Implementation of MTD operations for Siena */
+
+static int siena_mtd_read(struct mtd_info *mtd, loff_t start,
+			  size_t len, size_t *retlen, u8 *buffer)
 {
-	if (efx->spi_flash && efx->spi_flash->mtd) {
-		struct efx_mtd *efx_mtd = efx->spi_flash->mtd;
-		int rc;
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
+	struct efx_mtd *efx_mtd = mtd->priv;
+	struct efx_nic *efx = efx_mtd->efx;
+	loff_t offset = start;
+	loff_t end = min_t(loff_t, start + len, mtd->size);
+	size_t chunk;
+	int rc = 0;
 
-		for (;;) {
-			rc = del_mtd_device(&efx_mtd->mtd);
-			if (rc != -EBUSY)
-				break;
-			ssleep(1);
-		}
-		WARN_ON(rc);
-		kfree(efx_mtd);
+	while (offset < end) {
+		chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
+		rc = efx_mcdi_nvram_read(efx, part->mcdi.nvram_type, offset,
+					 buffer, chunk);
+		if (rc)
+			goto out;
+		offset += chunk;
+		buffer += chunk;
 	}
+out:
+	*retlen = offset - start;
+	return rc;
 }
 
-void efx_mtd_rename(struct efx_nic *efx)
+static int siena_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
 {
-	if (efx->spi_flash && efx->spi_flash->mtd) {
-		struct efx_mtd *efx_mtd = efx->spi_flash->mtd;
-		snprintf(efx_mtd->name, sizeof(efx_mtd->name),
-			 "%s sfc_flash_bootrom", efx->name);
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
+	struct efx_mtd *efx_mtd = mtd->priv;
+	struct efx_nic *efx = efx_mtd->efx;
+	loff_t offset = start & ~((loff_t)(mtd->erasesize - 1));
+	loff_t end = min_t(loff_t, start + len, mtd->size);
+	size_t chunk = part->mtd.erasesize;
+	int rc = 0;
+
+	if (!part->mcdi.updating) {
+		rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
+		if (rc)
+			goto out;
+		part->mcdi.updating = 1;
+	}
+
+	/* The MCDI interface can in fact do multiple erase blocks at once;
+	 * but erasing may be slow, so we make multiple calls here to avoid
+	 * tripping the MCDI RPC timeout. */
+	while (offset < end) {
+		rc = efx_mcdi_nvram_erase(efx, part->mcdi.nvram_type, offset,
+					  chunk);
+		if (rc)
+			goto out;
+		offset += chunk;
 	}
+out:
+	return rc;
 }
 
-int efx_mtd_probe(struct efx_nic *efx)
+static int siena_mtd_write(struct mtd_info *mtd, loff_t start,
+			   size_t len, size_t *retlen, const u8 *buffer)
 {
-	struct efx_spi_device *spi = efx->spi_flash;
-	struct efx_mtd *efx_mtd;
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
+	struct efx_mtd *efx_mtd = mtd->priv;
+	struct efx_nic *efx = efx_mtd->efx;
+	loff_t offset = start;
+	loff_t end = min_t(loff_t, start + len, mtd->size);
+	size_t chunk;
+	int rc = 0;
 
-	if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
+	if (!part->mcdi.updating) {
+		rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
+		if (rc)
+			goto out;
+		part->mcdi.updating = 1;
+	}
+
+	while (offset < end) {
+		chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
+		rc = efx_mcdi_nvram_write(efx, part->mcdi.nvram_type, offset,
+					  buffer, chunk);
+		if (rc)
+			goto out;
+		offset += chunk;
+		buffer += chunk;
+	}
+out:
+	*retlen = offset - start;
+	return rc;
+}
+
+static int siena_mtd_sync(struct mtd_info *mtd)
+{
+	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
+	struct efx_mtd *efx_mtd = mtd->priv;
+	struct efx_nic *efx = efx_mtd->efx;
+	int rc = 0;
+
+	if (part->mcdi.updating) {
+		part->mcdi.updating = 0;
+		rc = efx_mcdi_nvram_update_finish(efx, part->mcdi.nvram_type);
+	}
+
+	return rc;
+}
+
+static struct efx_mtd_ops siena_mtd_ops = {
+	.read	= siena_mtd_read,
+	.erase	= siena_mtd_erase,
+	.write	= siena_mtd_write,
+	.sync	= siena_mtd_sync,
+};
+
+struct siena_nvram_type_info {
+	int port;
+	const char *name;
+};
+
+static struct siena_nvram_type_info siena_nvram_types[] = {
+	[MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO]	= { 0, "sfc_dummy_phy" },
+	[MC_CMD_NVRAM_TYPE_MC_FW]		= { 0, "sfc_mcfw" },
+	[MC_CMD_NVRAM_TYPE_MC_FW_BACKUP]	= { 0, "sfc_mcfw_backup" },
+	[MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0]	= { 0, "sfc_static_cfg" },
+	[MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1]	= { 1, "sfc_static_cfg" },
+	[MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0]	= { 0, "sfc_dynamic_cfg" },
+	[MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1]	= { 1, "sfc_dynamic_cfg" },
+	[MC_CMD_NVRAM_TYPE_EXP_ROM]		= { 0, "sfc_exp_rom" },
+	[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0]	= { 0, "sfc_exp_rom_cfg" },
+	[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1]	= { 1, "sfc_exp_rom_cfg" },
+	[MC_CMD_NVRAM_TYPE_PHY_PORT0]		= { 0, "sfc_phy_fw" },
+	[MC_CMD_NVRAM_TYPE_PHY_PORT1]		= { 1, "sfc_phy_fw" },
+};
+
+static int siena_mtd_probe_partition(struct efx_nic *efx,
+				     struct efx_mtd *efx_mtd,
+				     unsigned int part_id,
+				     unsigned int type)
+{
+	struct efx_mtd_partition *part = &efx_mtd->part[part_id];
+	struct siena_nvram_type_info *info;
+	size_t size, erase_size;
+	bool protected;
+	int rc;
+
+	if (type >= ARRAY_SIZE(siena_nvram_types))
 		return -ENODEV;
 
-	efx_mtd = kzalloc(sizeof(*efx_mtd), GFP_KERNEL);
+	info = &siena_nvram_types[type];
+
+	if (info->port != efx_port_num(efx))
+		return -ENODEV;
+
+	rc = efx_mcdi_nvram_info(efx, type, &size, &erase_size, &protected);
+	if (rc)
+		return rc;
+	if (protected)
+		return -ENODEV; /* hide it */
+
+	part->mcdi.nvram_type = type;
+	part->type_name = info->name;
+
+	part->mtd.type = MTD_NORFLASH;
+	part->mtd.flags = MTD_CAP_NORFLASH;
+	part->mtd.size = size;
+	part->mtd.erasesize = erase_size;
+
+	return 0;
+}
+
+static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
+				     struct efx_mtd *efx_mtd)
+{
+	struct efx_mtd_partition *part;
+	uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN /
+				 sizeof(uint16_t)];
+	int rc;
+
+	rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list);
+	if (rc)
+		return rc;
+
+	efx_for_each_partition(part, efx_mtd)
+		part->mcdi.fw_subtype = fw_subtype_list[part->mcdi.nvram_type];
+
+	return 0;
+}
+
+static int siena_mtd_probe(struct efx_nic *efx)
+{
+	struct efx_mtd *efx_mtd;
+	int rc = -ENODEV;
+	u32 nvram_types;
+	unsigned int type;
+
+	ASSERT_RTNL();
+
+	rc = efx_mcdi_nvram_types(efx, &nvram_types);
+	if (rc)
+		return rc;
+
+	efx_mtd = kzalloc(sizeof(*efx_mtd) +
+			  hweight32(nvram_types) * sizeof(efx_mtd->part[0]),
+			  GFP_KERNEL);
 	if (!efx_mtd)
 		return -ENOMEM;
 
-	efx_mtd->spi = spi;
-	spi->mtd = efx_mtd;
+	efx_mtd->name = "Siena NVRAM manager";
 
-	efx_mtd->mtd.type = MTD_NORFLASH;
-	efx_mtd->mtd.flags = MTD_CAP_NORFLASH;
-	efx_mtd->mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
-	efx_mtd->mtd.erasesize = spi->erase_size;
-	efx_mtd->mtd.writesize = 1;
-	efx_mtd_rename(efx);
+	efx_mtd->ops = &siena_mtd_ops;
 
-	efx_mtd->mtd.owner = THIS_MODULE;
-	efx_mtd->mtd.priv = efx_mtd;
-	efx_mtd->mtd.name = efx_mtd->name;
-	efx_mtd->mtd.erase = efx_mtd_erase;
-	efx_mtd->mtd.read = efx_mtd_read;
-	efx_mtd->mtd.write = efx_mtd_write;
-	efx_mtd->mtd.sync = efx_mtd_sync;
+	type = 0;
+	efx_mtd->n_parts = 0;
 
-	if (add_mtd_device(&efx_mtd->mtd)) {
-		kfree(efx_mtd);
-		spi->mtd = NULL;
-		/* add_mtd_device() returns 1 if the MTD table is full */
-		return -ENOMEM;
+	while (nvram_types != 0) {
+		if (nvram_types & 1) {
+			rc = siena_mtd_probe_partition(efx, efx_mtd,
+						       efx_mtd->n_parts, type);
+			if (rc == 0)
+				efx_mtd->n_parts++;
+			else if (rc != -ENODEV)
+				goto fail;
+		}
+		type++;
+		nvram_types >>= 1;
 	}
 
-	return 0;
+	rc = siena_mtd_get_fw_subtypes(efx, efx_mtd);
+	if (rc)
+		goto fail;
+
+	rc = efx_mtd_probe_device(efx, efx_mtd);
+fail:
+	if (rc)
+		kfree(efx_mtd);
+	return rc;
 }
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/net_driver.h linux-libre-2.6.33-gnu1/drivers/net/sfc/net_driver.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/net_driver.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/net_driver.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2005-2008 Solarflare Communications Inc.
+ * Copyright 2005-2009 Solarflare Communications 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
@@ -38,7 +38,7 @@
 #ifndef EFX_DRIVER_NAME
 #define EFX_DRIVER_NAME	"sfc"
 #endif
-#define EFX_DRIVER_VERSION	"2.3"
+#define EFX_DRIVER_VERSION	"3.0"
 
 #ifdef EFX_ENABLE_DEBUG
 #define EFX_BUG_ON_PARANOID(x) BUG_ON(x)
@@ -113,6 +113,13 @@ struct efx_special_buffer {
 	int entries;
 };
 
+enum efx_flush_state {
+	FLUSH_NONE,
+	FLUSH_PENDING,
+	FLUSH_FAILED,
+	FLUSH_DONE,
+};
+
 /**
  * struct efx_tx_buffer - An Efx TX buffer
  * @skb: The associated socket buffer.
@@ -189,7 +196,7 @@ struct efx_tx_queue {
 	struct efx_nic *nic;
 	struct efx_tx_buffer *buffer;
 	struct efx_special_buffer txd;
-	bool flushed;
+	enum efx_flush_state flushed;
 
 	/* Members used mainly on the completion path */
 	unsigned int read_count ____cacheline_aligned_in_smp;
@@ -284,7 +291,7 @@ struct efx_rx_queue {
 	struct page *buf_page;
 	dma_addr_t buf_dma_addr;
 	char *buf_data;
-	bool flushed;
+	enum efx_flush_state flushed;
 };
 
 /**
@@ -327,7 +334,7 @@ enum efx_rx_alloc_method {
  * @used_flags: Channel is used by net driver
  * @enabled: Channel enabled indicator
  * @irq: IRQ number (MSI and MSI-X only)
- * @irq_moderation: IRQ moderation value (in us)
+ * @irq_moderation: IRQ moderation value (in hardware ticks)
  * @napi_dev: Net device used with NAPI
  * @napi_str: NAPI control structure
  * @reset_work: Scheduled reset work thread
@@ -343,9 +350,9 @@ enum efx_rx_alloc_method {
  * @rx_alloc_push_pages: RX allocation method currently in use for pushing
  *	descriptors
  * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors
- * @n_rx_ip_frag_err: Count of RX IP fragment errors
  * @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors
  * @n_rx_tcp_udp_chksum_err: Count of RX TCP and UDP checksum errors
+ * @n_rx_mcast_mismatch: Count of unmatched multicast frames
  * @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors
  * @n_rx_overlength: Count of RX_OVERLENGTH errors
  * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun
@@ -373,9 +380,9 @@ struct efx_channel {
 	int rx_alloc_push_pages;
 
 	unsigned n_rx_tobe_disc;
-	unsigned n_rx_ip_frag_err;
 	unsigned n_rx_ip_hdr_chksum_err;
 	unsigned n_rx_tcp_udp_chksum_err;
+	unsigned n_rx_mcast_mismatch;
 	unsigned n_rx_frm_trunc;
 	unsigned n_rx_overlength;
 	unsigned n_skbuff_leaks;
@@ -388,53 +395,29 @@ struct efx_channel {
 
 };
 
-/**
- * struct efx_blinker - S/W LED blinking context
- * @state: Current state - on or off
- * @resubmit: Timer resubmission flag
- * @timer: Control timer for blinking
- */
-struct efx_blinker {
-	bool state;
-	bool resubmit;
-	struct timer_list timer;
+enum efx_led_mode {
+	EFX_LED_OFF	= 0,
+	EFX_LED_ON	= 1,
+	EFX_LED_DEFAULT	= 2
 };
 
+#define STRING_TABLE_LOOKUP(val, member) \
+	((val) < member ## _max) ? member ## _names[val] : "(invalid)"
 
-/**
- * struct efx_board - board information
- * @type: Board model type
- * @major: Major rev. ('A', 'B' ...)
- * @minor: Minor rev. (0, 1, ...)
- * @init: Initialisation function
- * @init_leds: Sets up board LEDs. May be called repeatedly.
- * @set_id_led: Turns the identification LED on or off
- * @blink: Starts/stops blinking
- * @monitor: Board-specific health check function
- * @fini: Cleanup function
- * @blinker: used to blink LEDs in software
- * @hwmon_client: I2C client for hardware monitor
- * @ioexp_client: I2C client for power/port control
- */
-struct efx_board {
-	int type;
-	int major;
-	int minor;
-	int (*init) (struct efx_nic *nic);
-	/* As the LEDs are typically attached to the PHY, LEDs
-	 * have a separate init callback that happens later than
-	 * board init. */
-	void (*init_leds)(struct efx_nic *efx);
-	void (*set_id_led) (struct efx_nic *efx, bool state);
-	int (*monitor) (struct efx_nic *nic);
-	void (*blink) (struct efx_nic *efx, bool start);
-	void (*fini) (struct efx_nic *nic);
-	struct efx_blinker blinker;
-	struct i2c_client *hwmon_client, *ioexp_client;
-};
+extern const char *efx_loopback_mode_names[];
+extern const unsigned int efx_loopback_mode_max;
+#define LOOPBACK_MODE(efx) \
+	STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode)
 
-#define STRING_TABLE_LOOKUP(val, member)	\
-	member ## _names[val]
+extern const char *efx_interrupt_mode_names[];
+extern const unsigned int efx_interrupt_mode_max;
+#define INT_MODE(efx) \
+	STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode)
+
+extern const char *efx_reset_type_names[];
+extern const unsigned int efx_reset_type_max;
+#define RESET_TYPE(type) \
+	STRING_TABLE_LOOKUP(type, efx_reset_type)
 
 enum efx_int_mode {
 	/* Be careful if altering to correct macro below */
@@ -445,20 +428,7 @@ enum efx_int_mode {
 };
 #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI)
 
-enum phy_type {
-	PHY_TYPE_NONE = 0,
-	PHY_TYPE_TXC43128 = 1,
-	PHY_TYPE_88E1111 = 2,
-	PHY_TYPE_SFX7101 = 3,
-	PHY_TYPE_QT2022C2 = 4,
-	PHY_TYPE_PM8358 = 6,
-	PHY_TYPE_SFT9001A = 8,
-	PHY_TYPE_QT2025C = 9,
-	PHY_TYPE_SFT9001B = 10,
-	PHY_TYPE_MAX	/* Insert any new items before this */
-};
-
-#define EFX_IS10G(efx) ((efx)->link_speed == 10000)
+#define EFX_IS10G(efx) ((efx)->link_state.speed == 10000)
 
 enum nic_state {
 	STATE_INIT = 0,
@@ -500,73 +470,70 @@ enum efx_fc_type {
 	EFX_FC_AUTO = 4,
 };
 
-/* Supported MAC bit-mask */
-enum efx_mac_type {
-	EFX_GMAC = 1,
-	EFX_XMAC = 2,
+/**
+ * struct efx_link_state - Current state of the link
+ * @up: Link is up
+ * @fd: Link is full-duplex
+ * @fc: Actual flow control flags
+ * @speed: Link speed (Mbps)
+ */
+struct efx_link_state {
+	bool up;
+	bool fd;
+	enum efx_fc_type fc;
+	unsigned int speed;
 };
 
-static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
-					      unsigned int lpa)
+static inline bool efx_link_state_equal(const struct efx_link_state *left,
+					const struct efx_link_state *right)
 {
-	BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
-
-	if (!(wanted_fc & EFX_FC_AUTO))
-		return wanted_fc;
-
-	return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa);
+	return left->up == right->up && left->fd == right->fd &&
+		left->fc == right->fc && left->speed == right->speed;
 }
 
 /**
  * struct efx_mac_operations - Efx MAC operations table
  * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
  * @update_stats: Update statistics
- * @irq: Hardware MAC event callback. Serialised by the mac_lock
- * @poll: Poll for hardware state. Serialised by the mac_lock
+ * @check_fault: Check fault state. True if fault present.
  */
 struct efx_mac_operations {
-	void (*reconfigure) (struct efx_nic *efx);
+	int (*reconfigure) (struct efx_nic *efx);
 	void (*update_stats) (struct efx_nic *efx);
-	void (*irq) (struct efx_nic *efx);
-	void (*poll) (struct efx_nic *efx);
+	bool (*check_fault)(struct efx_nic *efx);
 };
 
 /**
  * struct efx_phy_operations - Efx PHY operations table
+ * @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds,
+ *	efx->loopback_modes.
  * @init: Initialise PHY
  * @fini: Shut down PHY
  * @reconfigure: Reconfigure PHY (e.g. for new link parameters)
- * @clear_interrupt: Clear down interrupt
- * @blink: Blink LEDs
- * @poll: Poll for hardware state. Serialised by the mac_lock.
+ * @poll: Update @link_state and report whether it changed.
+ *	Serialised by the mac_lock.
  * @get_settings: Get ethtool settings. Serialised by the mac_lock.
  * @set_settings: Set ethtool settings. Serialised by the mac_lock.
  * @set_npage_adv: Set abilities advertised in (Extended) Next Page
  *	(only needed where AN bit is set in mmds)
- * @num_tests: Number of PHY-specific tests/results
- * @test_names: Names of the tests/results
+ * @test_name: Get the name of a PHY-specific test/result
  * @run_tests: Run tests and record results as appropriate.
  *	Flags are the ethtool tests flags.
- * @mmds: MMD presence mask
- * @loopbacks: Supported loopback modes mask
  */
 struct efx_phy_operations {
-	enum efx_mac_type macs;
+	int (*probe) (struct efx_nic *efx);
 	int (*init) (struct efx_nic *efx);
 	void (*fini) (struct efx_nic *efx);
-	void (*reconfigure) (struct efx_nic *efx);
-	void (*clear_interrupt) (struct efx_nic *efx);
-	void (*poll) (struct efx_nic *efx);
+	void (*remove) (struct efx_nic *efx);
+	int (*reconfigure) (struct efx_nic *efx);
+	bool (*poll) (struct efx_nic *efx);
 	void (*get_settings) (struct efx_nic *efx,
 			      struct ethtool_cmd *ecmd);
 	int (*set_settings) (struct efx_nic *efx,
 			     struct ethtool_cmd *ecmd);
 	void (*set_npage_adv) (struct efx_nic *efx, u32);
-	u32 num_tests;
-	const char *const *test_names;
+	const char *(*test_name) (struct efx_nic *efx, unsigned int index);
 	int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
-	int mmds;
-	unsigned loopbacks;
 };
 
 /**
@@ -690,36 +657,38 @@ union efx_multicast_hash {
  * @interrupt_mode: Interrupt mode
  * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
  * @irq_rx_moderation: IRQ moderation time for RX event queues
- * @i2c_adap: I2C adapter
- * @board_info: Board-level information
  * @state: Device state flag. Serialised by the rtnl_lock.
  * @reset_pending: Pending reset method (normally RESET_TYPE_NONE)
  * @tx_queue: TX DMA queues
  * @rx_queue: RX DMA queues
  * @channel: Channels
+ * @next_buffer_table: First available buffer table id
  * @n_rx_queues: Number of RX queues
  * @n_channels: Number of channels in use
  * @rx_buffer_len: RX buffer length
  * @rx_buffer_order: Order (log2) of number of pages for each RX buffer
+ * @int_error_count: Number of internal errors seen recently
+ * @int_error_expire: Time at which error count will be expired
  * @irq_status: Interrupt status buffer
  * @last_irq_cpu: Last CPU to handle interrupt.
  *	This register is written with the SMP processor ID whenever an
  *	interrupt is handled.  It is used by falcon_test_interrupt()
  *	to verify that an interrupt has occurred.
  * @spi_flash: SPI flash device
- *	This field will be %NULL if no flash device is present.
+ *	This field will be %NULL if no flash device is present (or for Siena).
  * @spi_eeprom: SPI EEPROM device
- *	This field will be %NULL if no EEPROM device is present.
+ *	This field will be %NULL if no EEPROM device is present (or for Siena).
  * @spi_lock: SPI bus lock
+ * @mtd_list: List of MTDs attached to the NIC
  * @n_rx_nodesc_drop_cnt: RX no descriptor drop count
  * @nic_data: Hardware dependant state
  * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
  *	@port_inhibited, efx_monitor() and efx_reconfigure_port()
  * @port_enabled: Port enabled indicator.
- *	Serialises efx_stop_all(), efx_start_all(), efx_monitor(),
- *	efx_phy_work(), and efx_mac_work() with kernel interfaces. Safe to read
- *	under any one of the rtnl_lock, mac_lock, or netif_tx_lock, but all
- *	three must be held to modify it.
+ *	Serialises efx_stop_all(), efx_start_all(), efx_monitor() and
+ *	efx_mac_work() with kernel interfaces. Safe to read under any
+ *	one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
+ *	be held to modify it.
  * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
  * @port_initialized: Port initialized?
  * @net_dev: Operating system network device. Consider holding the rtnl lock
@@ -731,26 +700,23 @@ union efx_multicast_hash {
  *	&struct net_device_stats.
  * @stats_buffer: DMA buffer for statistics
  * @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_disable_count: Nest count for disabling statistics fetches
  * @mac_op: MAC interface
  * @mac_address: Permanent MAC address
  * @phy_type: PHY type
- * @phy_lock: PHY access lock
+ * @mdio_lock: MDIO lock
  * @phy_op: PHY interface
  * @phy_data: PHY private data (including PHY-specific stats)
  * @mdio: PHY MDIO interface
+ * @mdio_bus: PHY MDIO bus ID (only used by Siena)
  * @phy_mode: PHY operating mode. Serialised by @mac_lock.
- * @mac_up: MAC link state
- * @link_up: Link status
- * @link_fd: Link is full duplex
- * @link_fc: Actualy flow control flags
- * @link_speed: Link speed (Mbps)
+ * @xmac_poll_required: XMAC link state needs polling
+ * @link_advertising: Autonegotiation advertising flags
+ * @link_state: Current state of the link
  * @n_link_state_changes: Number of times the link has changed state
  * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
  * @multicast_hash: Multicast hash table
  * @wanted_fc: Wanted flow control flags
- * @phy_work: work item for dealing with PHY events
- * @mac_work: work item for dealing with MAC events
+ * @mac_work: Work item for changing MAC promiscuity and multicast hash
  * @loopback_mode: Loopback status
  * @loopback_modes: Supported loopback mode bitmask
  * @loopback_selftest: Offline self-test private state
@@ -774,9 +740,6 @@ struct efx_nic {
 	bool irq_rx_adaptive;
 	unsigned int irq_rx_moderation;
 
-	struct i2c_adapter i2c_adap;
-	struct efx_board board_info;
-
 	enum nic_state state;
 	enum reset_type reset_pending;
 
@@ -784,21 +747,29 @@ struct efx_nic {
 	struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
 	struct efx_channel channel[EFX_MAX_CHANNELS];
 
+	unsigned next_buffer_table;
 	int n_rx_queues;
 	int n_channels;
 	unsigned int rx_buffer_len;
 	unsigned int rx_buffer_order;
 
+	unsigned int_error_count;
+	unsigned long int_error_expire;
+
 	struct efx_buffer irq_status;
 	volatile signed int last_irq_cpu;
+	unsigned long irq_zero_count;
 
 	struct efx_spi_device *spi_flash;
 	struct efx_spi_device *spi_eeprom;
 	struct mutex spi_lock;
+#ifdef CONFIG_SFC_MTD
+	struct list_head mtd_list;
+#endif
 
 	unsigned n_rx_nodesc_drop_cnt;
 
-	struct falcon_nic_data *nic_data;
+	void *nic_data;
 
 	struct mutex mac_lock;
 	struct work_struct mac_work;
@@ -815,24 +786,21 @@ struct efx_nic {
 	struct efx_mac_stats mac_stats;
 	struct efx_buffer stats_buffer;
 	spinlock_t stats_lock;
-	unsigned int stats_disable_count;
 
 	struct efx_mac_operations *mac_op;
 	unsigned char mac_address[ETH_ALEN];
 
-	enum phy_type phy_type;
-	spinlock_t phy_lock;
-	struct work_struct phy_work;
+	unsigned int phy_type;
+	struct mutex mdio_lock;
 	struct efx_phy_operations *phy_op;
 	void *phy_data;
 	struct mdio_if_info mdio;
+	unsigned int mdio_bus;
 	enum efx_phy_mode phy_mode;
 
-	bool mac_up;
-	bool link_up;
-	bool link_fd;
-	enum efx_fc_type link_fc;
-	unsigned int link_speed;
+	bool xmac_poll_required;
+	u32 link_advertising;
+	struct efx_link_state link_state;
 	unsigned int n_link_state_changes;
 
 	bool promiscuous;
@@ -841,7 +809,7 @@ struct efx_nic {
 
 	atomic_t rx_reset;
 	enum efx_loopback_mode loopback_mode;
-	unsigned int loopback_modes;
+	u64 loopback_modes;
 
 	void *loopback_selftest;
 };
@@ -860,50 +828,95 @@ static inline const char *efx_dev_name(s
 	return efx_dev_registered(efx) ? efx->name : "";
 }
 
+static inline unsigned int efx_port_num(struct efx_nic *efx)
+{
+	return PCI_FUNC(efx->pci_dev->devfn);
+}
+
 /**
  * struct efx_nic_type - Efx device type definition
- * @mem_bar: Memory BAR number
+ * @probe: Probe the controller
+ * @remove: Free resources allocated by probe()
+ * @init: Initialise the controller
+ * @fini: Shut down the controller
+ * @monitor: Periodic function for polling link state and hardware monitor
+ * @reset: Reset the controller hardware and possibly the PHY.  This will
+ *	be called while the controller is uninitialised.
+ * @probe_port: Probe the MAC and PHY
+ * @remove_port: Free resources allocated by probe_port()
+ * @prepare_flush: Prepare the hardware for flushing the DMA queues
+ * @update_stats: Update statistics not provided by event handling
+ * @start_stats: Start the regular fetching of statistics
+ * @stop_stats: Stop the regular fetching of statistics
+ * @set_id_led: Set state of identifying LED or revert to automatic function
+ * @push_irq_moderation: Apply interrupt moderation value
+ * @push_multicast_hash: Apply multicast hash table
+ * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
+ * @get_wol: Get WoL configuration from driver state
+ * @set_wol: Push WoL configuration to the NIC
+ * @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume)
+ * @test_registers: Test read/write functionality of control registers
+ * @test_nvram: Test validity of NVRAM contents
+ * @default_mac_ops: efx_mac_operations to set at startup
+ * @revision: Hardware architecture revision
  * @mem_map_size: Memory BAR mapped size
  * @txd_ptr_tbl_base: TX descriptor ring base address
  * @rxd_ptr_tbl_base: RX descriptor ring base address
  * @buf_tbl_base: Buffer table base address
  * @evq_ptr_tbl_base: Event queue pointer table base address
  * @evq_rptr_tbl_base: Event queue read-pointer table base address
- * @txd_ring_mask: TX descriptor ring size - 1 (must be a power of two - 1)
- * @rxd_ring_mask: RX descriptor ring size - 1 (must be a power of two - 1)
- * @evq_size: Event queue size (must be a power of two)
  * @max_dma_mask: Maximum possible DMA mask
- * @tx_dma_mask: TX DMA mask
- * @bug5391_mask: Address mask for bug 5391 workaround
- * @rx_xoff_thresh: RX FIFO XOFF watermark (bytes)
- * @rx_xon_thresh: RX FIFO XON watermark (bytes)
  * @rx_buffer_padding: Padding added to each RX buffer
  * @max_interrupt_mode: Highest capability interrupt mode supported
  *	from &enum efx_init_mode.
  * @phys_addr_channels: Number of channels with physically addressed
  *	descriptors
+ * @tx_dc_base: Base address in SRAM of TX queue descriptor caches
+ * @rx_dc_base: Base address in SRAM of RX queue descriptor caches
+ * @offload_features: net_device feature flags for protocol offload
+ *	features implemented in hardware
+ * @reset_world_flags: Flags for additional components covered by
+ *	reset method RESET_TYPE_WORLD
  */
 struct efx_nic_type {
-	unsigned int mem_bar;
+	int (*probe)(struct efx_nic *efx);
+	void (*remove)(struct efx_nic *efx);
+	int (*init)(struct efx_nic *efx);
+	void (*fini)(struct efx_nic *efx);
+	void (*monitor)(struct efx_nic *efx);
+	int (*reset)(struct efx_nic *efx, enum reset_type method);
+	int (*probe_port)(struct efx_nic *efx);
+	void (*remove_port)(struct efx_nic *efx);
+	void (*prepare_flush)(struct efx_nic *efx);
+	void (*update_stats)(struct efx_nic *efx);
+	void (*start_stats)(struct efx_nic *efx);
+	void (*stop_stats)(struct efx_nic *efx);
+	void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
+	void (*push_irq_moderation)(struct efx_channel *channel);
+	void (*push_multicast_hash)(struct efx_nic *efx);
+	int (*reconfigure_port)(struct efx_nic *efx);
+	void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
+	int (*set_wol)(struct efx_nic *efx, u32 type);
+	void (*resume_wol)(struct efx_nic *efx);
+	int (*test_registers)(struct efx_nic *efx);
+	int (*test_nvram)(struct efx_nic *efx);
+	struct efx_mac_operations *default_mac_ops;
+
+	int revision;
 	unsigned int mem_map_size;
 	unsigned int txd_ptr_tbl_base;
 	unsigned int rxd_ptr_tbl_base;
 	unsigned int buf_tbl_base;
 	unsigned int evq_ptr_tbl_base;
 	unsigned int evq_rptr_tbl_base;
-
-	unsigned int txd_ring_mask;
-	unsigned int rxd_ring_mask;
-	unsigned int evq_size;
 	u64 max_dma_mask;
-	unsigned int tx_dma_mask;
-	unsigned bug5391_mask;
-
-	int rx_xoff_thresh;
-	int rx_xon_thresh;
 	unsigned int rx_buffer_padding;
 	unsigned int max_interrupt_mode;
 	unsigned int phys_addr_channels;
+	unsigned int tx_dc_base;
+	unsigned int rx_dc_base;
+	unsigned long offload_features;
+	u32 reset_world_flags;
 };
 
 /**************************************************************************
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/nic.c linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/nic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1585 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include "net_driver.h"
+#include "bitfield.h"
+#include "efx.h"
+#include "nic.h"
+#include "regs.h"
+#include "io.h"
+#include "workarounds.h"
+
+/**************************************************************************
+ *
+ * Configurable values
+ *
+ **************************************************************************
+ */
+
+/* This is set to 16 for a good reason.  In summary, if larger than
+ * 16, the descriptor cache holds more than a default socket
+ * buffer's worth of packets (for UDP we can only have at most one
+ * socket buffer's worth outstanding).  This combined with the fact
+ * that we only get 1 TX event per descriptor cache means the NIC
+ * goes idle.
+ */
+#define TX_DC_ENTRIES 16
+#define TX_DC_ENTRIES_ORDER 1
+
+#define RX_DC_ENTRIES 64
+#define RX_DC_ENTRIES_ORDER 3
+
+/* RX FIFO XOFF watermark
+ *
+ * When the amount of the RX FIFO increases used increases past this
+ * watermark send XOFF. Only used if RX flow control is enabled (ethtool -A)
+ * This also has an effect on RX/TX arbitration
+ */
+int efx_nic_rx_xoff_thresh = -1;
+module_param_named(rx_xoff_thresh_bytes, efx_nic_rx_xoff_thresh, int, 0644);
+MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold");
+
+/* RX FIFO XON watermark
+ *
+ * When the amount of the RX FIFO used decreases below this
+ * watermark send XON. Only used if TX flow control is enabled (ethtool -A)
+ * This also has an effect on RX/TX arbitration
+ */
+int efx_nic_rx_xon_thresh = -1;
+module_param_named(rx_xon_thresh_bytes, efx_nic_rx_xon_thresh, int, 0644);
+MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
+
+/* If EFX_MAX_INT_ERRORS internal errors occur within
+ * EFX_INT_ERROR_EXPIRE seconds, we consider the NIC broken and
+ * disable it.
+ */
+#define EFX_INT_ERROR_EXPIRE 3600
+#define EFX_MAX_INT_ERRORS 5
+
+/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
+ */
+#define EFX_FLUSH_INTERVAL 10
+#define EFX_FLUSH_POLL_COUNT 100
+
+/* Size and alignment of special buffers (4KB) */
+#define EFX_BUF_SIZE 4096
+
+/* Depth of RX flush request fifo */
+#define EFX_RX_FLUSH_COUNT 4
+
+/**************************************************************************
+ *
+ * Solarstorm hardware access
+ *
+ **************************************************************************/
+
+static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value,
+				     unsigned int index)
+{
+	efx_sram_writeq(efx, efx->membase + efx->type->buf_tbl_base,
+			value, index);
+}
+
+/* Read the current event from the event queue */
+static inline efx_qword_t *efx_event(struct efx_channel *channel,
+				     unsigned int index)
+{
+	return (((efx_qword_t *) (channel->eventq.addr)) + index);
+}
+
+/* See if an event is present
+ *
+ * We check both the high and low dword of the event for all ones.  We
+ * wrote all ones when we cleared the event, and no valid event can
+ * have all ones in either its high or low dwords.  This approach is
+ * robust against reordering.
+ *
+ * Note that using a single 64-bit comparison is incorrect; even
+ * though the CPU read will be atomic, the DMA write may not be.
+ */
+static inline int efx_event_present(efx_qword_t *event)
+{
+	return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
+		  EFX_DWORD_IS_ALL_ONES(event->dword[1])));
+}
+
+static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b,
+				     const efx_oword_t *mask)
+{
+	return ((a->u64[0] ^ b->u64[0]) & mask->u64[0]) ||
+		((a->u64[1] ^ b->u64[1]) & mask->u64[1]);
+}
+
+int efx_nic_test_registers(struct efx_nic *efx,
+			   const struct efx_nic_register_test *regs,
+			   size_t n_regs)
+{
+	unsigned address = 0, i, j;
+	efx_oword_t mask, imask, original, reg, buf;
+
+	/* Falcon should be in loopback to isolate the XMAC from the PHY */
+	WARN_ON(!LOOPBACK_INTERNAL(efx));
+
+	for (i = 0; i < n_regs; ++i) {
+		address = regs[i].address;
+		mask = imask = regs[i].mask;
+		EFX_INVERT_OWORD(imask);
+
+		efx_reado(efx, &original, address);
+
+		/* bit sweep on and off */
+		for (j = 0; j < 128; j++) {
+			if (!EFX_EXTRACT_OWORD32(mask, j, j))
+				continue;
+
+			/* Test this testable bit can be set in isolation */
+			EFX_AND_OWORD(reg, original, mask);
+			EFX_SET_OWORD32(reg, j, j, 1);
+
+			efx_writeo(efx, &reg, address);
+			efx_reado(efx, &buf, address);
+
+			if (efx_masked_compare_oword(&reg, &buf, &mask))
+				goto fail;
+
+			/* Test this testable bit can be cleared in isolation */
+			EFX_OR_OWORD(reg, original, mask);
+			EFX_SET_OWORD32(reg, j, j, 0);
+
+			efx_writeo(efx, &reg, address);
+			efx_reado(efx, &buf, address);
+
+			if (efx_masked_compare_oword(&reg, &buf, &mask))
+				goto fail;
+		}
+
+		efx_writeo(efx, &original, address);
+	}
+
+	return 0;
+
+fail:
+	EFX_ERR(efx, "wrote "EFX_OWORD_FMT" read "EFX_OWORD_FMT
+		" at address 0x%x mask "EFX_OWORD_FMT"\n", EFX_OWORD_VAL(reg),
+		EFX_OWORD_VAL(buf), address, EFX_OWORD_VAL(mask));
+	return -EIO;
+}
+
+/**************************************************************************
+ *
+ * Special buffer handling
+ * Special buffers are used for event queues and the TX and RX
+ * descriptor rings.
+ *
+ *************************************************************************/
+
+/*
+ * Initialise a special buffer
+ *
+ * This will define a buffer (previously allocated via
+ * efx_alloc_special_buffer()) in the buffer table, allowing
+ * it to be used for event queues, descriptor rings etc.
+ */
+static void
+efx_init_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
+{
+	efx_qword_t buf_desc;
+	int index;
+	dma_addr_t dma_addr;
+	int i;
+
+	EFX_BUG_ON_PARANOID(!buffer->addr);
+
+	/* Write buffer descriptors to NIC */
+	for (i = 0; i < buffer->entries; i++) {
+		index = buffer->index + i;
+		dma_addr = buffer->dma_addr + (i * 4096);
+		EFX_LOG(efx, "mapping special buffer %d at %llx\n",
+			index, (unsigned long long)dma_addr);
+		EFX_POPULATE_QWORD_3(buf_desc,
+				     FRF_AZ_BUF_ADR_REGION, 0,
+				     FRF_AZ_BUF_ADR_FBUF, dma_addr >> 12,
+				     FRF_AZ_BUF_OWNER_ID_FBUF, 0);
+		efx_write_buf_tbl(efx, &buf_desc, index);
+	}
+}
+
+/* Unmaps a buffer and clears the buffer table entries */
+static void
+efx_fini_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
+{
+	efx_oword_t buf_tbl_upd;
+	unsigned int start = buffer->index;
+	unsigned int end = (buffer->index + buffer->entries - 1);
+
+	if (!buffer->entries)
+		return;
+
+	EFX_LOG(efx, "unmapping special buffers %d-%d\n",
+		buffer->index, buffer->index + buffer->entries - 1);
+
+	EFX_POPULATE_OWORD_4(buf_tbl_upd,
+			     FRF_AZ_BUF_UPD_CMD, 0,
+			     FRF_AZ_BUF_CLR_CMD, 1,
+			     FRF_AZ_BUF_CLR_END_ID, end,
+			     FRF_AZ_BUF_CLR_START_ID, start);
+	efx_writeo(efx, &buf_tbl_upd, FR_AZ_BUF_TBL_UPD);
+}
+
+/*
+ * Allocate a new special buffer
+ *
+ * This allocates memory for a new buffer, clears it and allocates a
+ * new buffer ID range.  It does not write into the buffer table.
+ *
+ * This call will allocate 4KB buffers, since 8KB buffers can't be
+ * used for event queues and descriptor rings.
+ */
+static int efx_alloc_special_buffer(struct efx_nic *efx,
+				    struct efx_special_buffer *buffer,
+				    unsigned int len)
+{
+	len = ALIGN(len, EFX_BUF_SIZE);
+
+	buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
+					    &buffer->dma_addr);
+	if (!buffer->addr)
+		return -ENOMEM;
+	buffer->len = len;
+	buffer->entries = len / EFX_BUF_SIZE;
+	BUG_ON(buffer->dma_addr & (EFX_BUF_SIZE - 1));
+
+	/* All zeros is a potentially valid event so memset to 0xff */
+	memset(buffer->addr, 0xff, len);
+
+	/* Select new buffer ID */
+	buffer->index = efx->next_buffer_table;
+	efx->next_buffer_table += buffer->entries;
+
+	EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x "
+		"(virt %p phys %llx)\n", buffer->index,
+		buffer->index + buffer->entries - 1,
+		(u64)buffer->dma_addr, len,
+		buffer->addr, (u64)virt_to_phys(buffer->addr));
+
+	return 0;
+}
+
+static void
+efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
+{
+	if (!buffer->addr)
+		return;
+
+	EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x "
+		"(virt %p phys %llx)\n", buffer->index,
+		buffer->index + buffer->entries - 1,
+		(u64)buffer->dma_addr, buffer->len,
+		buffer->addr, (u64)virt_to_phys(buffer->addr));
+
+	pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr,
+			    buffer->dma_addr);
+	buffer->addr = NULL;
+	buffer->entries = 0;
+}
+
+/**************************************************************************
+ *
+ * Generic buffer handling
+ * These buffers are used for interrupt status and MAC stats
+ *
+ **************************************************************************/
+
+int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
+			 unsigned int len)
+{
+	buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
+					    &buffer->dma_addr);
+	if (!buffer->addr)
+		return -ENOMEM;
+	buffer->len = len;
+	memset(buffer->addr, 0, len);
+	return 0;
+}
+
+void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer)
+{
+	if (buffer->addr) {
+		pci_free_consistent(efx->pci_dev, buffer->len,
+				    buffer->addr, buffer->dma_addr);
+		buffer->addr = NULL;
+	}
+}
+
+/**************************************************************************
+ *
+ * TX path
+ *
+ **************************************************************************/
+
+/* Returns a pointer to the specified transmit descriptor in the TX
+ * descriptor queue belonging to the specified channel.
+ */
+static inline efx_qword_t *
+efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
+{
+	return (((efx_qword_t *) (tx_queue->txd.addr)) + index);
+}
+
+/* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */
+static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue)
+{
+	unsigned write_ptr;
+	efx_dword_t reg;
+
+	write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+	EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr);
+	efx_writed_page(tx_queue->efx, &reg,
+			FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue);
+}
+
+
+/* For each entry inserted into the software descriptor ring, create a
+ * descriptor in the hardware TX descriptor ring (in host memory), and
+ * write a doorbell.
+ */
+void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
+{
+
+	struct efx_tx_buffer *buffer;
+	efx_qword_t *txd;
+	unsigned write_ptr;
+
+	BUG_ON(tx_queue->write_count == tx_queue->insert_count);
+
+	do {
+		write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+		buffer = &tx_queue->buffer[write_ptr];
+		txd = efx_tx_desc(tx_queue, write_ptr);
+		++tx_queue->write_count;
+
+		/* Create TX descriptor ring entry */
+		EFX_POPULATE_QWORD_4(*txd,
+				     FSF_AZ_TX_KER_CONT, buffer->continuation,
+				     FSF_AZ_TX_KER_BYTE_COUNT, buffer->len,
+				     FSF_AZ_TX_KER_BUF_REGION, 0,
+				     FSF_AZ_TX_KER_BUF_ADDR, buffer->dma_addr);
+	} while (tx_queue->write_count != tx_queue->insert_count);
+
+	wmb(); /* Ensure descriptors are written before they are fetched */
+	efx_notify_tx_desc(tx_queue);
+}
+
+/* Allocate hardware resources for a TX queue */
+int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 ||
+		     EFX_TXQ_SIZE & EFX_TXQ_MASK);
+	return efx_alloc_special_buffer(efx, &tx_queue->txd,
+					EFX_TXQ_SIZE * sizeof(efx_qword_t));
+}
+
+void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
+{
+	efx_oword_t tx_desc_ptr;
+	struct efx_nic *efx = tx_queue->efx;
+
+	tx_queue->flushed = FLUSH_NONE;
+
+	/* Pin TX descriptor ring */
+	efx_init_special_buffer(efx, &tx_queue->txd);
+
+	/* Push TX descriptor ring to card */
+	EFX_POPULATE_OWORD_10(tx_desc_ptr,
+			      FRF_AZ_TX_DESCQ_EN, 1,
+			      FRF_AZ_TX_ISCSI_DDIG_EN, 0,
+			      FRF_AZ_TX_ISCSI_HDIG_EN, 0,
+			      FRF_AZ_TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index,
+			      FRF_AZ_TX_DESCQ_EVQ_ID,
+			      tx_queue->channel->channel,
+			      FRF_AZ_TX_DESCQ_OWNER_ID, 0,
+			      FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue,
+			      FRF_AZ_TX_DESCQ_SIZE,
+			      __ffs(tx_queue->txd.entries),
+			      FRF_AZ_TX_DESCQ_TYPE, 0,
+			      FRF_BZ_TX_NON_IP_DROP_DIS, 1);
+
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
+		int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
+		EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum);
+		EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS,
+				    !csum);
+	}
+
+	efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
+			 tx_queue->queue);
+
+	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) {
+		efx_oword_t reg;
+
+		/* Only 128 bits in this register */
+		BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
+
+		efx_reado(efx, &reg, FR_AA_TX_CHKSM_CFG);
+		if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
+			clear_bit_le(tx_queue->queue, (void *)&reg);
+		else
+			set_bit_le(tx_queue->queue, (void *)&reg);
+		efx_writeo(efx, &reg, FR_AA_TX_CHKSM_CFG);
+	}
+}
+
+static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	efx_oword_t tx_flush_descq;
+
+	tx_queue->flushed = FLUSH_PENDING;
+
+	/* Post a flush command */
+	EFX_POPULATE_OWORD_2(tx_flush_descq,
+			     FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
+			     FRF_AZ_TX_FLUSH_DESCQ, tx_queue->queue);
+	efx_writeo(efx, &tx_flush_descq, FR_AZ_TX_FLUSH_DESCQ);
+}
+
+void efx_nic_fini_tx(struct efx_tx_queue *tx_queue)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	efx_oword_t tx_desc_ptr;
+
+	/* The queue should have been flushed */
+	WARN_ON(tx_queue->flushed != FLUSH_DONE);
+
+	/* Remove TX descriptor ring from card */
+	EFX_ZERO_OWORD(tx_desc_ptr);
+	efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
+			 tx_queue->queue);
+
+	/* Unpin TX descriptor ring */
+	efx_fini_special_buffer(efx, &tx_queue->txd);
+}
+
+/* Free buffers backing TX queue */
+void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
+{
+	efx_free_special_buffer(tx_queue->efx, &tx_queue->txd);
+}
+
+/**************************************************************************
+ *
+ * RX path
+ *
+ **************************************************************************/
+
+/* Returns a pointer to the specified descriptor in the RX descriptor queue */
+static inline efx_qword_t *
+efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
+{
+	return (((efx_qword_t *) (rx_queue->rxd.addr)) + index);
+}
+
+/* This creates an entry in the RX descriptor queue */
+static inline void
+efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index)
+{
+	struct efx_rx_buffer *rx_buf;
+	efx_qword_t *rxd;
+
+	rxd = efx_rx_desc(rx_queue, index);
+	rx_buf = efx_rx_buffer(rx_queue, index);
+	EFX_POPULATE_QWORD_3(*rxd,
+			     FSF_AZ_RX_KER_BUF_SIZE,
+			     rx_buf->len -
+			     rx_queue->efx->type->rx_buffer_padding,
+			     FSF_AZ_RX_KER_BUF_REGION, 0,
+			     FSF_AZ_RX_KER_BUF_ADDR, rx_buf->dma_addr);
+}
+
+/* This writes to the RX_DESC_WPTR register for the specified receive
+ * descriptor ring.
+ */
+void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
+{
+	efx_dword_t reg;
+	unsigned write_ptr;
+
+	while (rx_queue->notified_count != rx_queue->added_count) {
+		efx_build_rx_desc(rx_queue,
+				  rx_queue->notified_count &
+				  EFX_RXQ_MASK);
+		++rx_queue->notified_count;
+	}
+
+	wmb();
+	write_ptr = rx_queue->added_count & EFX_RXQ_MASK;
+	EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr);
+	efx_writed_page(rx_queue->efx, &reg,
+			FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue);
+}
+
+int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
+{
+	struct efx_nic *efx = rx_queue->efx;
+	BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 ||
+		     EFX_RXQ_SIZE & EFX_RXQ_MASK);
+	return efx_alloc_special_buffer(efx, &rx_queue->rxd,
+					EFX_RXQ_SIZE * sizeof(efx_qword_t));
+}
+
+void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
+{
+	efx_oword_t rx_desc_ptr;
+	struct efx_nic *efx = rx_queue->efx;
+	bool is_b0 = efx_nic_rev(efx) >= EFX_REV_FALCON_B0;
+	bool iscsi_digest_en = is_b0;
+
+	EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n",
+		rx_queue->queue, rx_queue->rxd.index,
+		rx_queue->rxd.index + rx_queue->rxd.entries - 1);
+
+	rx_queue->flushed = FLUSH_NONE;
+
+	/* Pin RX descriptor ring */
+	efx_init_special_buffer(efx, &rx_queue->rxd);
+
+	/* Push RX descriptor ring to card */
+	EFX_POPULATE_OWORD_10(rx_desc_ptr,
+			      FRF_AZ_RX_ISCSI_DDIG_EN, iscsi_digest_en,
+			      FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en,
+			      FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index,
+			      FRF_AZ_RX_DESCQ_EVQ_ID,
+			      rx_queue->channel->channel,
+			      FRF_AZ_RX_DESCQ_OWNER_ID, 0,
+			      FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue,
+			      FRF_AZ_RX_DESCQ_SIZE,
+			      __ffs(rx_queue->rxd.entries),
+			      FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ ,
+			      /* For >=B0 this is scatter so disable */
+			      FRF_AZ_RX_DESCQ_JUMBO, !is_b0,
+			      FRF_AZ_RX_DESCQ_EN, 1);
+	efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
+			 rx_queue->queue);
+}
+
+static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
+{
+	struct efx_nic *efx = rx_queue->efx;
+	efx_oword_t rx_flush_descq;
+
+	rx_queue->flushed = FLUSH_PENDING;
+
+	/* Post a flush command */
+	EFX_POPULATE_OWORD_2(rx_flush_descq,
+			     FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
+			     FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue);
+	efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ);
+}
+
+void efx_nic_fini_rx(struct efx_rx_queue *rx_queue)
+{
+	efx_oword_t rx_desc_ptr;
+	struct efx_nic *efx = rx_queue->efx;
+
+	/* The queue should already have been flushed */
+	WARN_ON(rx_queue->flushed != FLUSH_DONE);
+
+	/* Remove RX descriptor ring from card */
+	EFX_ZERO_OWORD(rx_desc_ptr);
+	efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
+			 rx_queue->queue);
+
+	/* Unpin RX descriptor ring */
+	efx_fini_special_buffer(efx, &rx_queue->rxd);
+}
+
+/* Free buffers backing RX queue */
+void efx_nic_remove_rx(struct efx_rx_queue *rx_queue)
+{
+	efx_free_special_buffer(rx_queue->efx, &rx_queue->rxd);
+}
+
+/**************************************************************************
+ *
+ * Event queue processing
+ * Event queues are processed by per-channel tasklets.
+ *
+ **************************************************************************/
+
+/* Update a channel's event queue's read pointer (RPTR) register
+ *
+ * This writes the EVQ_RPTR_REG register for the specified channel's
+ * event queue.
+ *
+ * Note that EVQ_RPTR_REG contains the index of the "last read" event,
+ * whereas channel->eventq_read_ptr contains the index of the "next to
+ * read" event.
+ */
+void efx_nic_eventq_read_ack(struct efx_channel *channel)
+{
+	efx_dword_t reg;
+	struct efx_nic *efx = channel->efx;
+
+	EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, channel->eventq_read_ptr);
+	efx_writed_table(efx, &reg, efx->type->evq_rptr_tbl_base,
+			 channel->channel);
+}
+
+/* Use HW to insert a SW defined event */
+void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
+{
+	efx_oword_t drv_ev_reg;
+
+	BUILD_BUG_ON(FRF_AZ_DRV_EV_DATA_LBN != 0 ||
+		     FRF_AZ_DRV_EV_DATA_WIDTH != 64);
+	drv_ev_reg.u32[0] = event->u32[0];
+	drv_ev_reg.u32[1] = event->u32[1];
+	drv_ev_reg.u32[2] = 0;
+	drv_ev_reg.u32[3] = 0;
+	EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, channel->channel);
+	efx_writeo(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV);
+}
+
+/* Handle a transmit completion event
+ *
+ * The NIC batches TX completion events; the message we receive is of
+ * the form "complete all TX events up to this index".
+ */
+static void
+efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
+{
+	unsigned int tx_ev_desc_ptr;
+	unsigned int tx_ev_q_label;
+	struct efx_tx_queue *tx_queue;
+	struct efx_nic *efx = channel->efx;
+
+	if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) {
+		/* Transmit completion */
+		tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
+		tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
+		tx_queue = &efx->tx_queue[tx_ev_q_label];
+		channel->irq_mod_score +=
+			(tx_ev_desc_ptr - tx_queue->read_count) &
+			EFX_TXQ_MASK;
+		efx_xmit_done(tx_queue, tx_ev_desc_ptr);
+	} else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
+		/* Rewrite the FIFO write pointer */
+		tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
+		tx_queue = &efx->tx_queue[tx_ev_q_label];
+
+		if (efx_dev_registered(efx))
+			netif_tx_lock(efx->net_dev);
+		efx_notify_tx_desc(tx_queue);
+		if (efx_dev_registered(efx))
+			netif_tx_unlock(efx->net_dev);
+	} else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) &&
+		   EFX_WORKAROUND_10727(efx)) {
+		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
+	} else {
+		EFX_ERR(efx, "channel %d unexpected TX event "
+			EFX_QWORD_FMT"\n", channel->channel,
+			EFX_QWORD_VAL(*event));
+	}
+}
+
+/* Detect errors included in the rx_evt_pkt_ok bit. */
+static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
+				 const efx_qword_t *event,
+				 bool *rx_ev_pkt_ok,
+				 bool *discard)
+{
+	struct efx_nic *efx = rx_queue->efx;
+	bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
+	bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
+	bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
+	bool rx_ev_other_err, rx_ev_pause_frm;
+	bool rx_ev_hdr_type, rx_ev_mcast_pkt;
+	unsigned rx_ev_pkt_type;
+
+	rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE);
+	rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT);
+	rx_ev_tobe_disc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC);
+	rx_ev_pkt_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE);
+	rx_ev_buf_owner_id_err = EFX_QWORD_FIELD(*event,
+						 FSF_AZ_RX_EV_BUF_OWNER_ID_ERR);
+	rx_ev_ip_hdr_chksum_err = EFX_QWORD_FIELD(*event,
+						  FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR);
+	rx_ev_tcp_udp_chksum_err = EFX_QWORD_FIELD(*event,
+						   FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR);
+	rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_ETH_CRC_ERR);
+	rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_FRM_TRUNC);
+	rx_ev_drib_nib = ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) ?
+			  0 : EFX_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB));
+	rx_ev_pause_frm = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR);
+
+	/* Every error apart from tobe_disc and pause_frm */
+	rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err |
+			   rx_ev_buf_owner_id_err | rx_ev_eth_crc_err |
+			   rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err);
+
+	/* Count errors that are not in MAC stats.  Ignore expected
+	 * checksum errors during self-test. */
+	if (rx_ev_frm_trunc)
+		++rx_queue->channel->n_rx_frm_trunc;
+	else if (rx_ev_tobe_disc)
+		++rx_queue->channel->n_rx_tobe_disc;
+	else if (!efx->loopback_selftest) {
+		if (rx_ev_ip_hdr_chksum_err)
+			++rx_queue->channel->n_rx_ip_hdr_chksum_err;
+		else if (rx_ev_tcp_udp_chksum_err)
+			++rx_queue->channel->n_rx_tcp_udp_chksum_err;
+	}
+
+	/* The frame must be discarded if any of these are true. */
+	*discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib |
+		    rx_ev_tobe_disc | rx_ev_pause_frm);
+
+	/* TOBE_DISC is expected on unicast mismatches; don't print out an
+	 * error message.  FRM_TRUNC indicates RXDP dropped the packet due
+	 * to a FIFO overflow.
+	 */
+#ifdef EFX_ENABLE_DEBUG
+	if (rx_ev_other_err) {
+		EFX_INFO_RL(efx, " RX queue %d unexpected RX event "
+			    EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
+			    rx_queue->queue, EFX_QWORD_VAL(*event),
+			    rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
+			    rx_ev_ip_hdr_chksum_err ?
+			    " [IP_HDR_CHKSUM_ERR]" : "",
+			    rx_ev_tcp_udp_chksum_err ?
+			    " [TCP_UDP_CHKSUM_ERR]" : "",
+			    rx_ev_eth_crc_err ? " [ETH_CRC_ERR]" : "",
+			    rx_ev_frm_trunc ? " [FRM_TRUNC]" : "",
+			    rx_ev_drib_nib ? " [DRIB_NIB]" : "",
+			    rx_ev_tobe_disc ? " [TOBE_DISC]" : "",
+			    rx_ev_pause_frm ? " [PAUSE]" : "");
+	}
+#endif
+}
+
+/* Handle receive events that are not in-order. */
+static void
+efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index)
+{
+	struct efx_nic *efx = rx_queue->efx;
+	unsigned expected, dropped;
+
+	expected = rx_queue->removed_count & EFX_RXQ_MASK;
+	dropped = (index - expected) & EFX_RXQ_MASK;
+	EFX_INFO(efx, "dropped %d events (index=%d expected=%d)\n",
+		dropped, index, expected);
+
+	efx_schedule_reset(efx, EFX_WORKAROUND_5676(efx) ?
+			   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
+}
+
+/* Handle a packet received event
+ *
+ * The NIC gives a "discard" flag if it's a unicast packet with the
+ * wrong destination address
+ * Also "is multicast" and "matches multicast filter" flags can be used to
+ * discard non-matching multicast packets.
+ */
+static void
+efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
+{
+	unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt;
+	unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
+	unsigned expected_ptr;
+	bool rx_ev_pkt_ok, discard = false, checksummed;
+	struct efx_rx_queue *rx_queue;
+	struct efx_nic *efx = channel->efx;
+
+	/* Basic packet information */
+	rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT);
+	rx_ev_pkt_ok = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_OK);
+	rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE);
+	WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_JUMBO_CONT));
+	WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_SOP) != 1);
+	WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) !=
+		channel->channel);
+
+	rx_queue = &efx->rx_queue[channel->channel];
+
+	rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR);
+	expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK;
+	if (unlikely(rx_ev_desc_ptr != expected_ptr))
+		efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
+
+	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.
+		 */
+		checksummed =
+			likely(efx->rx_checksum_enabled) &&
+			(rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
+			 rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP);
+	} else {
+		efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard);
+		checksummed = false;
+	}
+
+	/* Detect multicast packets that didn't match the filter */
+	rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT);
+	if (rx_ev_mcast_pkt) {
+		unsigned int rx_ev_mcast_hash_match =
+			EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_HASH_MATCH);
+
+		if (unlikely(!rx_ev_mcast_hash_match)) {
+			++channel->n_rx_mcast_mismatch;
+			discard = true;
+		}
+	}
+
+	channel->irq_mod_score += 2;
+
+	/* Handle received packet */
+	efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
+		      checksummed, discard);
+}
+
+/* Global events are basically PHY events */
+static void
+efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
+{
+	struct efx_nic *efx = channel->efx;
+	bool handled = false;
+
+	if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) ||
+	    EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) ||
+	    EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) {
+		/* Ignored */
+		handled = true;
+	}
+
+	if ((efx_nic_rev(efx) >= EFX_REV_FALCON_B0) &&
+	    EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
+		efx->xmac_poll_required = true;
+		handled = true;
+	}
+
+	if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ?
+	    EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) :
+	    EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) {
+		EFX_ERR(efx, "channel %d seen global RX_RESET "
+			"event. Resetting.\n", channel->channel);
+
+		atomic_inc(&efx->rx_reset);
+		efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
+				   RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
+		handled = true;
+	}
+
+	if (!handled)
+		EFX_ERR(efx, "channel %d unknown global event "
+			EFX_QWORD_FMT "\n", channel->channel,
+			EFX_QWORD_VAL(*event));
+}
+
+static void
+efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
+{
+	struct efx_nic *efx = channel->efx;
+	unsigned int ev_sub_code;
+	unsigned int ev_sub_data;
+
+	ev_sub_code = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBCODE);
+	ev_sub_data = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA);
+
+	switch (ev_sub_code) {
+	case FSE_AZ_TX_DESCQ_FLS_DONE_EV:
+		EFX_TRACE(efx, "channel %d TXQ %d flushed\n",
+			  channel->channel, ev_sub_data);
+		break;
+	case FSE_AZ_RX_DESCQ_FLS_DONE_EV:
+		EFX_TRACE(efx, "channel %d RXQ %d flushed\n",
+			  channel->channel, ev_sub_data);
+		break;
+	case FSE_AZ_EVQ_INIT_DONE_EV:
+		EFX_LOG(efx, "channel %d EVQ %d initialised\n",
+			channel->channel, ev_sub_data);
+		break;
+	case FSE_AZ_SRM_UPD_DONE_EV:
+		EFX_TRACE(efx, "channel %d SRAM update done\n",
+			  channel->channel);
+		break;
+	case FSE_AZ_WAKE_UP_EV:
+		EFX_TRACE(efx, "channel %d RXQ %d wakeup event\n",
+			  channel->channel, ev_sub_data);
+		break;
+	case FSE_AZ_TIMER_EV:
+		EFX_TRACE(efx, "channel %d RX queue %d timer expired\n",
+			  channel->channel, ev_sub_data);
+		break;
+	case FSE_AA_RX_RECOVER_EV:
+		EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. "
+			"Resetting.\n", channel->channel);
+		atomic_inc(&efx->rx_reset);
+		efx_schedule_reset(efx,
+				   EFX_WORKAROUND_6555(efx) ?
+				   RESET_TYPE_RX_RECOVERY :
+				   RESET_TYPE_DISABLE);
+		break;
+	case FSE_BZ_RX_DSC_ERROR_EV:
+		EFX_ERR(efx, "RX DMA Q %d reports descriptor fetch error."
+			" RX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
+		efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH);
+		break;
+	case FSE_BZ_TX_DSC_ERROR_EV:
+		EFX_ERR(efx, "TX DMA Q %d reports descriptor fetch error."
+			" TX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
+		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
+		break;
+	default:
+		EFX_TRACE(efx, "channel %d unknown driver event code %d "
+			  "data %04x\n", channel->channel, ev_sub_code,
+			  ev_sub_data);
+		break;
+	}
+}
+
+int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota)
+{
+	unsigned int read_ptr;
+	efx_qword_t event, *p_event;
+	int ev_code;
+	int rx_packets = 0;
+
+	read_ptr = channel->eventq_read_ptr;
+
+	do {
+		p_event = efx_event(channel, read_ptr);
+		event = *p_event;
+
+		if (!efx_event_present(&event))
+			/* End of events */
+			break;
+
+		EFX_TRACE(channel->efx, "channel %d event is "EFX_QWORD_FMT"\n",
+			  channel->channel, EFX_QWORD_VAL(event));
+
+		/* Clear this event by marking it all ones */
+		EFX_SET_QWORD(*p_event);
+
+		ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE);
+
+		switch (ev_code) {
+		case FSE_AZ_EV_CODE_RX_EV:
+			efx_handle_rx_event(channel, &event);
+			++rx_packets;
+			break;
+		case FSE_AZ_EV_CODE_TX_EV:
+			efx_handle_tx_event(channel, &event);
+			break;
+		case FSE_AZ_EV_CODE_DRV_GEN_EV:
+			channel->eventq_magic = EFX_QWORD_FIELD(
+				event, FSF_AZ_DRV_GEN_EV_MAGIC);
+			EFX_LOG(channel->efx, "channel %d received generated "
+				"event "EFX_QWORD_FMT"\n", channel->channel,
+				EFX_QWORD_VAL(event));
+			break;
+		case FSE_AZ_EV_CODE_GLOBAL_EV:
+			efx_handle_global_event(channel, &event);
+			break;
+		case FSE_AZ_EV_CODE_DRIVER_EV:
+			efx_handle_driver_event(channel, &event);
+			break;
+		case FSE_CZ_EV_CODE_MCDI_EV:
+			efx_mcdi_process_event(channel, &event);
+			break;
+		default:
+			EFX_ERR(channel->efx, "channel %d unknown event type %d"
+				" (data " EFX_QWORD_FMT ")\n", channel->channel,
+				ev_code, EFX_QWORD_VAL(event));
+		}
+
+		/* Increment read pointer */
+		read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+
+	} while (rx_packets < rx_quota);
+
+	channel->eventq_read_ptr = read_ptr;
+	return rx_packets;
+}
+
+
+/* Allocate buffer table entries for event queue */
+int efx_nic_probe_eventq(struct efx_channel *channel)
+{
+	struct efx_nic *efx = channel->efx;
+	BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 ||
+		     EFX_EVQ_SIZE & EFX_EVQ_MASK);
+	return efx_alloc_special_buffer(efx, &channel->eventq,
+					EFX_EVQ_SIZE * sizeof(efx_qword_t));
+}
+
+void efx_nic_init_eventq(struct efx_channel *channel)
+{
+	efx_oword_t reg;
+	struct efx_nic *efx = channel->efx;
+
+	EFX_LOG(efx, "channel %d event queue in special buffers %d-%d\n",
+		channel->channel, channel->eventq.index,
+		channel->eventq.index + channel->eventq.entries - 1);
+
+	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
+		EFX_POPULATE_OWORD_3(reg,
+				     FRF_CZ_TIMER_Q_EN, 1,
+				     FRF_CZ_HOST_NOTIFY_MODE, 0,
+				     FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);
+		efx_writeo_table(efx, &reg, FR_BZ_TIMER_TBL, channel->channel);
+	}
+
+	/* Pin event queue buffer */
+	efx_init_special_buffer(efx, &channel->eventq);
+
+	/* Fill event queue with all ones (i.e. empty events) */
+	memset(channel->eventq.addr, 0xff, channel->eventq.len);
+
+	/* Push event queue to card */
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_AZ_EVQ_EN, 1,
+			     FRF_AZ_EVQ_SIZE, __ffs(channel->eventq.entries),
+			     FRF_AZ_EVQ_BUF_BASE_ID, channel->eventq.index);
+	efx_writeo_table(efx, &reg, efx->type->evq_ptr_tbl_base,
+			 channel->channel);
+
+	efx->type->push_irq_moderation(channel);
+}
+
+void efx_nic_fini_eventq(struct efx_channel *channel)
+{
+	efx_oword_t reg;
+	struct efx_nic *efx = channel->efx;
+
+	/* Remove event queue from card */
+	EFX_ZERO_OWORD(reg);
+	efx_writeo_table(efx, &reg, efx->type->evq_ptr_tbl_base,
+			 channel->channel);
+	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
+		efx_writeo_table(efx, &reg, FR_BZ_TIMER_TBL, channel->channel);
+
+	/* Unpin event queue */
+	efx_fini_special_buffer(efx, &channel->eventq);
+}
+
+/* Free buffers backing event queue */
+void efx_nic_remove_eventq(struct efx_channel *channel)
+{
+	efx_free_special_buffer(channel->efx, &channel->eventq);
+}
+
+
+/* Generates a test event on the event queue.  A subsequent call to
+ * process_eventq() should pick up the event and place the value of
+ * "magic" into channel->eventq_magic;
+ */
+void efx_nic_generate_test_event(struct efx_channel *channel, unsigned int magic)
+{
+	efx_qword_t test_event;
+
+	EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE,
+			     FSE_AZ_EV_CODE_DRV_GEN_EV,
+			     FSF_AZ_DRV_GEN_EV_MAGIC, magic);
+	efx_generate_event(channel, &test_event);
+}
+
+/**************************************************************************
+ *
+ * Flush handling
+ *
+ **************************************************************************/
+
+
+static void efx_poll_flush_events(struct efx_nic *efx)
+{
+	struct efx_channel *channel = &efx->channel[0];
+	struct efx_tx_queue *tx_queue;
+	struct efx_rx_queue *rx_queue;
+	unsigned int read_ptr = channel->eventq_read_ptr;
+	unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK;
+
+	do {
+		efx_qword_t *event = efx_event(channel, read_ptr);
+		int ev_code, ev_sub_code, ev_queue;
+		bool ev_failed;
+
+		if (!efx_event_present(event))
+			break;
+
+		ev_code = EFX_QWORD_FIELD(*event, FSF_AZ_EV_CODE);
+		ev_sub_code = EFX_QWORD_FIELD(*event,
+					      FSF_AZ_DRIVER_EV_SUBCODE);
+		if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
+		    ev_sub_code == FSE_AZ_TX_DESCQ_FLS_DONE_EV) {
+			ev_queue = EFX_QWORD_FIELD(*event,
+						   FSF_AZ_DRIVER_EV_SUBDATA);
+			if (ev_queue < EFX_TX_QUEUE_COUNT) {
+				tx_queue = efx->tx_queue + ev_queue;
+				tx_queue->flushed = FLUSH_DONE;
+			}
+		} else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
+			   ev_sub_code == FSE_AZ_RX_DESCQ_FLS_DONE_EV) {
+			ev_queue = EFX_QWORD_FIELD(
+				*event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
+			ev_failed = EFX_QWORD_FIELD(
+				*event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
+			if (ev_queue < efx->n_rx_queues) {
+				rx_queue = efx->rx_queue + ev_queue;
+				rx_queue->flushed =
+					ev_failed ? FLUSH_FAILED : FLUSH_DONE;
+			}
+		}
+
+		/* We're about to destroy the queue anyway, so
+		 * it's ok to throw away every non-flush event */
+		EFX_SET_QWORD(*event);
+
+		read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+	} while (read_ptr != end_ptr);
+
+	channel->eventq_read_ptr = read_ptr;
+}
+
+/* Handle tx and rx flushes at the same time, since they run in
+ * parallel in the hardware and there's no reason for us to
+ * serialise them */
+int efx_nic_flush_queues(struct efx_nic *efx)
+{
+	struct efx_rx_queue *rx_queue;
+	struct efx_tx_queue *tx_queue;
+	int i, tx_pending, rx_pending;
+
+	/* If necessary prepare the hardware for flushing */
+	efx->type->prepare_flush(efx);
+
+	/* Flush all tx queues in parallel */
+	efx_for_each_tx_queue(tx_queue, efx)
+		efx_flush_tx_queue(tx_queue);
+
+	/* The hardware supports four concurrent rx flushes, each of which may
+	 * need to be retried if there is an outstanding descriptor fetch */
+	for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) {
+		rx_pending = tx_pending = 0;
+		efx_for_each_rx_queue(rx_queue, efx) {
+			if (rx_queue->flushed == FLUSH_PENDING)
+				++rx_pending;
+		}
+		efx_for_each_rx_queue(rx_queue, efx) {
+			if (rx_pending == EFX_RX_FLUSH_COUNT)
+				break;
+			if (rx_queue->flushed == FLUSH_FAILED ||
+			    rx_queue->flushed == FLUSH_NONE) {
+				efx_flush_rx_queue(rx_queue);
+				++rx_pending;
+			}
+		}
+		efx_for_each_tx_queue(tx_queue, efx) {
+			if (tx_queue->flushed != FLUSH_DONE)
+				++tx_pending;
+		}
+
+		if (rx_pending == 0 && tx_pending == 0)
+			return 0;
+
+		msleep(EFX_FLUSH_INTERVAL);
+		efx_poll_flush_events(efx);
+	}
+
+	/* Mark the queues as all flushed. We're going to return failure
+	 * leading to a reset, or fake up success anyway */
+	efx_for_each_tx_queue(tx_queue, efx) {
+		if (tx_queue->flushed != FLUSH_DONE)
+			EFX_ERR(efx, "tx queue %d flush command timed out\n",
+				tx_queue->queue);
+		tx_queue->flushed = FLUSH_DONE;
+	}
+	efx_for_each_rx_queue(rx_queue, efx) {
+		if (rx_queue->flushed != FLUSH_DONE)
+			EFX_ERR(efx, "rx queue %d flush command timed out\n",
+				rx_queue->queue);
+		rx_queue->flushed = FLUSH_DONE;
+	}
+
+	if (EFX_WORKAROUND_7803(efx))
+		return 0;
+
+	return -ETIMEDOUT;
+}
+
+/**************************************************************************
+ *
+ * Hardware interrupts
+ * The hardware interrupt handler does very little work; all the event
+ * queue processing is carried out by per-channel tasklets.
+ *
+ **************************************************************************/
+
+/* Enable/disable/generate interrupts */
+static inline void efx_nic_interrupts(struct efx_nic *efx,
+				      bool enabled, bool force)
+{
+	efx_oword_t int_en_reg_ker;
+	unsigned int level = 0;
+
+	if (EFX_WORKAROUND_17213(efx) && !EFX_INT_MODE_USE_MSI(efx))
+		/* Set the level always even if we're generating a test
+		 * interrupt, because our legacy interrupt handler is safe */
+		level = 0x1f;
+
+	EFX_POPULATE_OWORD_3(int_en_reg_ker,
+			     FRF_AZ_KER_INT_LEVE_SEL, level,
+			     FRF_AZ_KER_INT_KER, force,
+			     FRF_AZ_DRV_INT_EN_KER, enabled);
+	efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER);
+}
+
+void efx_nic_enable_interrupts(struct efx_nic *efx)
+{
+	struct efx_channel *channel;
+
+	EFX_ZERO_OWORD(*((efx_oword_t *) efx->irq_status.addr));
+	wmb(); /* Ensure interrupt vector is clear before interrupts enabled */
+
+	/* Enable interrupts */
+	efx_nic_interrupts(efx, true, false);
+
+	/* Force processing of all the channels to get the EVQ RPTRs up to
+	   date */
+	efx_for_each_channel(channel, efx)
+		efx_schedule_channel(channel);
+}
+
+void efx_nic_disable_interrupts(struct efx_nic *efx)
+{
+	/* Disable interrupts */
+	efx_nic_interrupts(efx, false, false);
+}
+
+/* Generate a test interrupt
+ * Interrupt must already have been enabled, otherwise nasty things
+ * may happen.
+ */
+void efx_nic_generate_interrupt(struct efx_nic *efx)
+{
+	efx_nic_interrupts(efx, true, true);
+}
+
+/* Process a fatal interrupt
+ * Disable bus mastering ASAP and schedule a reset
+ */
+irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx)
+{
+	struct falcon_nic_data *nic_data = efx->nic_data;
+	efx_oword_t *int_ker = efx->irq_status.addr;
+	efx_oword_t fatal_intr;
+	int error, mem_perr;
+
+	efx_reado(efx, &fatal_intr, FR_AZ_FATAL_INTR_KER);
+	error = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_FATAL_INTR);
+
+	EFX_ERR(efx, "SYSTEM ERROR " EFX_OWORD_FMT " status "
+		EFX_OWORD_FMT ": %s\n", EFX_OWORD_VAL(*int_ker),
+		EFX_OWORD_VAL(fatal_intr),
+		error ? "disabling bus mastering" : "no recognised error");
+	if (error == 0)
+		goto out;
+
+	/* If this is a memory parity error dump which blocks are offending */
+	mem_perr = EFX_OWORD_FIELD(fatal_intr, FRF_AZ_MEM_PERR_INT_KER);
+	if (mem_perr) {
+		efx_oword_t reg;
+		efx_reado(efx, &reg, FR_AZ_MEM_STAT);
+		EFX_ERR(efx, "SYSTEM ERROR: memory parity error "
+			EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg));
+	}
+
+	/* Disable both devices */
+	pci_clear_master(efx->pci_dev);
+	if (efx_nic_is_dual_func(efx))
+		pci_clear_master(nic_data->pci_dev2);
+	efx_nic_disable_interrupts(efx);
+
+	/* Count errors and reset or disable the NIC accordingly */
+	if (efx->int_error_count == 0 ||
+	    time_after(jiffies, efx->int_error_expire)) {
+		efx->int_error_count = 0;
+		efx->int_error_expire =
+			jiffies + EFX_INT_ERROR_EXPIRE * HZ;
+	}
+	if (++efx->int_error_count < EFX_MAX_INT_ERRORS) {
+		EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
+		efx_schedule_reset(efx, RESET_TYPE_INT_ERROR);
+	} else {
+		EFX_ERR(efx, "SYSTEM ERROR - max number of errors seen."
+			"NIC will be disabled\n");
+		efx_schedule_reset(efx, RESET_TYPE_DISABLE);
+	}
+out:
+	return IRQ_HANDLED;
+}
+
+/* Handle a legacy interrupt
+ * Acknowledges the interrupt and schedule event queue processing.
+ */
+static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
+{
+	struct efx_nic *efx = dev_id;
+	efx_oword_t *int_ker = efx->irq_status.addr;
+	irqreturn_t result = IRQ_NONE;
+	struct efx_channel *channel;
+	efx_dword_t reg;
+	u32 queues;
+	int syserr;
+
+	/* Read the ISR which also ACKs the interrupts */
+	efx_readd(efx, &reg, FR_BZ_INT_ISR0);
+	queues = EFX_EXTRACT_DWORD(reg, 0, 31);
+
+	/* Check to see if we have a serious error condition */
+	syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
+	if (unlikely(syserr))
+		return efx_nic_fatal_interrupt(efx);
+
+	if (queues != 0) {
+		if (EFX_WORKAROUND_15783(efx))
+			efx->irq_zero_count = 0;
+
+		/* Schedule processing of any interrupting queues */
+		efx_for_each_channel(channel, efx) {
+			if (queues & 1)
+				efx_schedule_channel(channel);
+			queues >>= 1;
+		}
+		result = IRQ_HANDLED;
+
+	} else if (EFX_WORKAROUND_15783(efx) &&
+		   efx->irq_zero_count++ == 0) {
+		efx_qword_t *event;
+
+		/* Ensure we rearm all event queues */
+		efx_for_each_channel(channel, efx) {
+			event = efx_event(channel, channel->eventq_read_ptr);
+			if (efx_event_present(event))
+				efx_schedule_channel(channel);
+		}
+
+		result = IRQ_HANDLED;
+	}
+
+	if (result == IRQ_HANDLED) {
+		efx->last_irq_cpu = raw_smp_processor_id();
+		EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
+			  irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
+	}
+
+	return result;
+}
+
+/* Handle an MSI interrupt
+ *
+ * Handle an MSI hardware interrupt.  This routine schedules event
+ * queue processing.  No interrupt acknowledgement cycle is necessary.
+ * Also, we never need to check that the interrupt is for us, since
+ * MSI interrupts cannot be shared.
+ */
+static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
+{
+	struct efx_channel *channel = dev_id;
+	struct efx_nic *efx = channel->efx;
+	efx_oword_t *int_ker = efx->irq_status.addr;
+	int syserr;
+
+	efx->last_irq_cpu = raw_smp_processor_id();
+	EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
+		  irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
+
+	/* Check to see if we have a serious error condition */
+	syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
+	if (unlikely(syserr))
+		return efx_nic_fatal_interrupt(efx);
+
+	/* Schedule processing of the channel */
+	efx_schedule_channel(channel);
+
+	return IRQ_HANDLED;
+}
+
+
+/* Setup RSS indirection table.
+ * This maps from the hash value of the packet to RXQ
+ */
+static void efx_setup_rss_indir_table(struct efx_nic *efx)
+{
+	int i = 0;
+	unsigned long offset;
+	efx_dword_t dword;
+
+	if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
+		return;
+
+	for (offset = FR_BZ_RX_INDIRECTION_TBL;
+	     offset < FR_BZ_RX_INDIRECTION_TBL + 0x800;
+	     offset += 0x10) {
+		EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE,
+				     i % efx->n_rx_queues);
+		efx_writed(efx, &dword, offset);
+		i++;
+	}
+}
+
+/* Hook interrupt handler(s)
+ * Try MSI and then legacy interrupts.
+ */
+int efx_nic_init_interrupt(struct efx_nic *efx)
+{
+	struct efx_channel *channel;
+	int rc;
+
+	if (!EFX_INT_MODE_USE_MSI(efx)) {
+		irq_handler_t handler;
+		if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
+			handler = efx_legacy_interrupt;
+		else
+			handler = falcon_legacy_interrupt_a1;
+
+		rc = request_irq(efx->legacy_irq, handler, IRQF_SHARED,
+				 efx->name, efx);
+		if (rc) {
+			EFX_ERR(efx, "failed to hook legacy IRQ %d\n",
+				efx->pci_dev->irq);
+			goto fail1;
+		}
+		return 0;
+	}
+
+	/* Hook MSI or MSI-X interrupt */
+	efx_for_each_channel(channel, efx) {
+		rc = request_irq(channel->irq, efx_msi_interrupt,
+				 IRQF_PROBE_SHARED, /* Not shared */
+				 channel->name, channel);
+		if (rc) {
+			EFX_ERR(efx, "failed to hook IRQ %d\n", channel->irq);
+			goto fail2;
+		}
+	}
+
+	return 0;
+
+ fail2:
+	efx_for_each_channel(channel, efx)
+		free_irq(channel->irq, channel);
+ fail1:
+	return rc;
+}
+
+void efx_nic_fini_interrupt(struct efx_nic *efx)
+{
+	struct efx_channel *channel;
+	efx_oword_t reg;
+
+	/* Disable MSI/MSI-X interrupts */
+	efx_for_each_channel(channel, efx) {
+		if (channel->irq)
+			free_irq(channel->irq, channel);
+	}
+
+	/* ACK legacy interrupt */
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
+		efx_reado(efx, &reg, FR_BZ_INT_ISR0);
+	else
+		falcon_irq_ack_a1(efx);
+
+	/* Disable legacy interrupt */
+	if (efx->legacy_irq)
+		free_irq(efx->legacy_irq, efx);
+}
+
+u32 efx_nic_fpga_ver(struct efx_nic *efx)
+{
+	efx_oword_t altera_build;
+	efx_reado(efx, &altera_build, FR_AZ_ALTERA_BUILD);
+	return EFX_OWORD_FIELD(altera_build, FRF_AZ_ALTERA_BUILD_VER);
+}
+
+void efx_nic_init_common(struct efx_nic *efx)
+{
+	efx_oword_t temp;
+
+	/* Set positions of descriptor caches in SRAM. */
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR,
+			     efx->type->tx_dc_base / 8);
+	efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG);
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR,
+			     efx->type->rx_dc_base / 8);
+	efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG);
+
+	/* Set TX descriptor cache size. */
+	BUILD_BUG_ON(TX_DC_ENTRIES != (8 << TX_DC_ENTRIES_ORDER));
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_TX_DC_SIZE, TX_DC_ENTRIES_ORDER);
+	efx_writeo(efx, &temp, FR_AZ_TX_DC_CFG);
+
+	/* Set RX descriptor cache size.  Set low watermark to size-8, as
+	 * this allows most efficient prefetching.
+	 */
+	BUILD_BUG_ON(RX_DC_ENTRIES != (8 << RX_DC_ENTRIES_ORDER));
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_SIZE, RX_DC_ENTRIES_ORDER);
+	efx_writeo(efx, &temp, FR_AZ_RX_DC_CFG);
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_RX_DC_PF_LWM, RX_DC_ENTRIES - 8);
+	efx_writeo(efx, &temp, FR_AZ_RX_DC_PF_WM);
+
+	/* Program INT_KER address */
+	EFX_POPULATE_OWORD_2(temp,
+			     FRF_AZ_NORM_INT_VEC_DIS_KER,
+			     EFX_INT_MODE_USE_MSI(efx),
+			     FRF_AZ_INT_ADR_KER, efx->irq_status.dma_addr);
+	efx_writeo(efx, &temp, FR_AZ_INT_ADR_KER);
+
+	/* Enable all the genuinely fatal interrupts.  (They are still
+	 * masked by the overall interrupt mask, controlled by
+	 * falcon_interrupts()).
+	 *
+	 * Note: All other fatal interrupts are enabled
+	 */
+	EFX_POPULATE_OWORD_3(temp,
+			     FRF_AZ_ILL_ADR_INT_KER_EN, 1,
+			     FRF_AZ_RBUF_OWN_INT_KER_EN, 1,
+			     FRF_AZ_TBUF_OWN_INT_KER_EN, 1);
+	EFX_INVERT_OWORD(temp);
+	efx_writeo(efx, &temp, FR_AZ_FATAL_INTR_KER);
+
+	efx_setup_rss_indir_table(efx);
+
+	/* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be
+	 * controlled by the RX FIFO fill level. Set arbitration to one pkt/Q.
+	 */
+	efx_reado(efx, &temp, FR_AZ_TX_RESERVED);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER, 0xfe);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_RX_SPACER_EN, 1);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PUSH_EN, 0);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_DIS_NON_IP_EV, 1);
+	/* Enable SW_EV to inherit in char driver - assume harmless here */
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1);
+	/* Prefetch threshold 2 => fetch when descriptor cache half empty */
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2);
+	/* Disable hardware watchdog which can misfire */
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
+	/* Squash TX of packets of 16 bytes or less */
+	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
+		EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
+	efx_writeo(efx, &temp, FR_AZ_TX_RESERVED);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/nic.h linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/nic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/nic.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,261 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef EFX_NIC_H
+#define EFX_NIC_H
+
+#include <linux/i2c-algo-bit.h>
+#include "net_driver.h"
+#include "efx.h"
+#include "mcdi.h"
+
+/*
+ * Falcon hardware control
+ */
+
+enum {
+	EFX_REV_FALCON_A0 = 0,
+	EFX_REV_FALCON_A1 = 1,
+	EFX_REV_FALCON_B0 = 2,
+	EFX_REV_SIENA_A0 = 3,
+};
+
+static inline int efx_nic_rev(struct efx_nic *efx)
+{
+	return efx->type->revision;
+}
+
+extern u32 efx_nic_fpga_ver(struct efx_nic *efx);
+
+static inline bool efx_nic_has_mc(struct efx_nic *efx)
+{
+	return efx_nic_rev(efx) >= EFX_REV_SIENA_A0;
+}
+/* NIC has two interlinked PCI functions for the same port. */
+static inline bool efx_nic_is_dual_func(struct efx_nic *efx)
+{
+	return efx_nic_rev(efx) < EFX_REV_FALCON_B0;
+}
+
+enum {
+	PHY_TYPE_NONE = 0,
+	PHY_TYPE_TXC43128 = 1,
+	PHY_TYPE_88E1111 = 2,
+	PHY_TYPE_SFX7101 = 3,
+	PHY_TYPE_QT2022C2 = 4,
+	PHY_TYPE_PM8358 = 6,
+	PHY_TYPE_SFT9001A = 8,
+	PHY_TYPE_QT2025C = 9,
+	PHY_TYPE_SFT9001B = 10,
+};
+
+#define FALCON_XMAC_LOOPBACKS			\
+	((1 << LOOPBACK_XGMII) |		\
+	 (1 << LOOPBACK_XGXS) |			\
+	 (1 << LOOPBACK_XAUI))
+
+#define FALCON_GMAC_LOOPBACKS			\
+	(1 << LOOPBACK_GMAC)
+
+/**
+ * struct falcon_board_type - board operations and type information
+ * @id: Board type id, as found in NVRAM
+ * @ref_model: Model number of Solarflare reference design
+ * @gen_type: Generic board type description
+ * @init: Allocate resources and initialise peripheral hardware
+ * @init_phy: Do board-specific PHY initialisation
+ * @fini: Shut down hardware and free resources
+ * @set_id_led: Set state of identifying LED or revert to automatic function
+ * @monitor: Board-specific health check function
+ */
+struct falcon_board_type {
+	u8 id;
+	const char *ref_model;
+	const char *gen_type;
+	int (*init) (struct efx_nic *nic);
+	void (*init_phy) (struct efx_nic *efx);
+	void (*fini) (struct efx_nic *nic);
+	void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
+	int (*monitor) (struct efx_nic *nic);
+};
+
+/**
+ * struct falcon_board - board information
+ * @type: Type of board
+ * @major: Major rev. ('A', 'B' ...)
+ * @minor: Minor rev. (0, 1, ...)
+ * @i2c_adap: I2C adapter for on-board peripherals
+ * @i2c_data: Data for bit-banging algorithm
+ * @hwmon_client: I2C client for hardware monitor
+ * @ioexp_client: I2C client for power/port control
+ */
+struct falcon_board {
+	const struct falcon_board_type *type;
+	int major;
+	int minor;
+	struct i2c_adapter i2c_adap;
+	struct i2c_algo_bit_data i2c_data;
+	struct i2c_client *hwmon_client, *ioexp_client;
+};
+
+/**
+ * struct falcon_nic_data - Falcon NIC state
+ * @pci_dev2: Secondary function of Falcon A
+ * @board: Board state and functions
+ * @stats_disable_count: Nest count for disabling statistics fetches
+ * @stats_pending: Is there a pending DMA of MAC statistics.
+ * @stats_timer: A timer for regularly fetching MAC statistics.
+ * @stats_dma_done: Pointer to the flag which indicates DMA completion.
+ */
+struct falcon_nic_data {
+	struct pci_dev *pci_dev2;
+	struct falcon_board board;
+	unsigned int stats_disable_count;
+	bool stats_pending;
+	struct timer_list stats_timer;
+	u32 *stats_dma_done;
+};
+
+static inline struct falcon_board *falcon_board(struct efx_nic *efx)
+{
+	struct falcon_nic_data *data = efx->nic_data;
+	return &data->board;
+}
+
+/**
+ * struct siena_nic_data - Siena NIC state
+ * @fw_version: Management controller firmware version
+ * @fw_build: Firmware build number
+ * @mcdi: Management-Controller-to-Driver Interface
+ * @wol_filter_id: Wake-on-LAN packet filter id
+ */
+struct siena_nic_data {
+	u64 fw_version;
+	u32 fw_build;
+	struct efx_mcdi_iface mcdi;
+	int wol_filter_id;
+};
+
+extern void siena_print_fwver(struct efx_nic *efx, char *buf, size_t len);
+
+extern struct efx_nic_type falcon_a1_nic_type;
+extern struct efx_nic_type falcon_b0_nic_type;
+extern struct efx_nic_type siena_a0_nic_type;
+
+/**************************************************************************
+ *
+ * Externs
+ *
+ **************************************************************************
+ */
+
+extern void falcon_probe_board(struct efx_nic *efx, u16 revision_info);
+
+/* TX data path */
+extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue);
+extern void efx_nic_init_tx(struct efx_tx_queue *tx_queue);
+extern void efx_nic_fini_tx(struct efx_tx_queue *tx_queue);
+extern void efx_nic_remove_tx(struct efx_tx_queue *tx_queue);
+extern void efx_nic_push_buffers(struct efx_tx_queue *tx_queue);
+
+/* RX data path */
+extern int efx_nic_probe_rx(struct efx_rx_queue *rx_queue);
+extern void efx_nic_init_rx(struct efx_rx_queue *rx_queue);
+extern void efx_nic_fini_rx(struct efx_rx_queue *rx_queue);
+extern void efx_nic_remove_rx(struct efx_rx_queue *rx_queue);
+extern void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue);
+
+/* Event data path */
+extern int efx_nic_probe_eventq(struct efx_channel *channel);
+extern void efx_nic_init_eventq(struct efx_channel *channel);
+extern void efx_nic_fini_eventq(struct efx_channel *channel);
+extern void efx_nic_remove_eventq(struct efx_channel *channel);
+extern int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota);
+extern void efx_nic_eventq_read_ack(struct efx_channel *channel);
+
+/* MAC/PHY */
+extern void falcon_drain_tx_fifo(struct efx_nic *efx);
+extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
+extern int efx_nic_rx_xoff_thresh, efx_nic_rx_xon_thresh;
+
+/* Interrupts and test events */
+extern int efx_nic_init_interrupt(struct efx_nic *efx);
+extern void efx_nic_enable_interrupts(struct efx_nic *efx);
+extern void efx_nic_generate_test_event(struct efx_channel *channel,
+					unsigned int magic);
+extern void efx_nic_generate_interrupt(struct efx_nic *efx);
+extern void efx_nic_disable_interrupts(struct efx_nic *efx);
+extern void efx_nic_fini_interrupt(struct efx_nic *efx);
+extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
+extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id);
+extern void falcon_irq_ack_a1(struct efx_nic *efx);
+
+#define EFX_IRQ_MOD_RESOLUTION 5
+
+/* Global Resources */
+extern int efx_nic_flush_queues(struct efx_nic *efx);
+extern void falcon_start_nic_stats(struct efx_nic *efx);
+extern void falcon_stop_nic_stats(struct efx_nic *efx);
+extern int falcon_reset_xaui(struct efx_nic *efx);
+extern void efx_nic_init_common(struct efx_nic *efx);
+
+int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
+			 unsigned int len);
+void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer);
+
+/* Tests */
+struct efx_nic_register_test {
+	unsigned address;
+	efx_oword_t mask;
+};
+extern int efx_nic_test_registers(struct efx_nic *efx,
+				  const struct efx_nic_register_test *regs,
+				  size_t n_regs);
+
+/**************************************************************************
+ *
+ * Falcon MAC stats
+ *
+ **************************************************************************
+ */
+
+#define FALCON_STAT_OFFSET(falcon_stat) EFX_VAL(falcon_stat, offset)
+#define FALCON_STAT_WIDTH(falcon_stat) EFX_VAL(falcon_stat, WIDTH)
+
+/* Retrieve statistic from statistics block */
+#define FALCON_STAT(efx, falcon_stat, efx_stat) do {		\
+	if (FALCON_STAT_WIDTH(falcon_stat) == 16)		\
+		(efx)->mac_stats.efx_stat += le16_to_cpu(	\
+			*((__force __le16 *)				\
+			  (efx->stats_buffer.addr +		\
+			   FALCON_STAT_OFFSET(falcon_stat))));	\
+	else if (FALCON_STAT_WIDTH(falcon_stat) == 32)		\
+		(efx)->mac_stats.efx_stat += le32_to_cpu(	\
+			*((__force __le32 *)				\
+			  (efx->stats_buffer.addr +		\
+			   FALCON_STAT_OFFSET(falcon_stat))));	\
+	else							\
+		(efx)->mac_stats.efx_stat += le64_to_cpu(	\
+			*((__force __le64 *)				\
+			  (efx->stats_buffer.addr +		\
+			   FALCON_STAT_OFFSET(falcon_stat))));	\
+	} while (0)
+
+#define FALCON_MAC_STATS_SIZE 0x100
+
+#define MAC_DATA_LBN 0
+#define MAC_DATA_WIDTH 32
+
+extern void efx_nic_generate_event(struct efx_channel *channel,
+				   efx_qword_t *event);
+
+extern void falcon_poll_xmac(struct efx_nic *efx);
+
+#endif /* EFX_NIC_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/phy.h linux-libre-2.6.33-gnu1/drivers/net/sfc/phy.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/phy.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/phy.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications Inc.
+ * Copyright 2007-2009 Solarflare Communications 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
@@ -16,16 +16,16 @@
 extern struct efx_phy_operations falcon_sfx7101_phy_ops;
 extern struct efx_phy_operations falcon_sft9001_phy_ops;
 
-extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
+extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
 
 /* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
  * to boot due to corrupt flash, or some other negative error code. */
 extern int sft9001_wait_boot(struct efx_nic *efx);
 
 /****************************************************************************
- * AMCC/Quake QT20xx PHYs
+ * AMCC/Quake QT202x PHYs
  */
-extern struct efx_phy_operations falcon_xfp_phy_ops;
+extern struct efx_phy_operations falcon_qt202x_phy_ops;
 
 /* These PHYs provide various H/W control states for LEDs */
 #define QUAKE_LED_LINK_INVAL	(0)
@@ -39,6 +39,23 @@ extern struct efx_phy_operations falcon_
 #define QUAKE_LED_TXLINK	(0)
 #define QUAKE_LED_RXLINK	(8)
 
-extern void xfp_set_led(struct efx_nic *p, int led, int state);
+extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state);
+
+/****************************************************************************
+ * Siena managed PHYs
+ */
+extern struct efx_phy_operations efx_mcdi_phy_ops;
+
+extern int efx_mcdi_mdio_read(struct efx_nic *efx, unsigned int bus,
+			      unsigned int prtad, unsigned int devad,
+			      u16 addr, u16 *value_out, u32 *status_out);
+extern int efx_mcdi_mdio_write(struct efx_nic *efx, unsigned int bus,
+			       unsigned int prtad, unsigned int devad,
+			       u16 addr, u16 value, u32 *status_out);
+extern void efx_mcdi_phy_decode_link(struct efx_nic *efx,
+				     struct efx_link_state *link_state,
+				     u32 speed, u32 flags, u32 fcntl);
+extern int efx_mcdi_phy_reconfigure(struct efx_nic *efx);
+extern void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/qt202x_phy.c linux-libre-2.6.33-gnu1/drivers/net/sfc/qt202x_phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/qt202x_phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/qt202x_phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,448 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+/*
+ * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
+ */
+
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include "efx.h"
+#include "mdio_10g.h"
+#include "phy.h"
+#include "nic.h"
+
+#define QT202X_REQUIRED_DEVS (MDIO_DEVS_PCS |		\
+			      MDIO_DEVS_PMAPMD |	\
+			      MDIO_DEVS_PHYXS)
+
+#define QT202X_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
+			  (1 << LOOPBACK_PMAPMD) |	\
+			  (1 << LOOPBACK_PHYXS_WS))
+
+/****************************************************************************/
+/* Quake-specific MDIO registers */
+#define MDIO_QUAKE_LED0_REG	(0xD006)
+
+/* QT2025C only */
+#define PCS_FW_HEARTBEAT_REG	0xd7ee
+#define PCS_FW_HEARTB_LBN	0
+#define PCS_FW_HEARTB_WIDTH	8
+#define PCS_FW_PRODUCT_CODE_1	0xd7f0
+#define PCS_FW_VERSION_1	0xd7f3
+#define PCS_FW_BUILD_1		0xd7f6
+#define PCS_UC8051_STATUS_REG	0xd7fd
+#define PCS_UC_STATUS_LBN	0
+#define PCS_UC_STATUS_WIDTH	8
+#define PCS_UC_STATUS_FW_SAVE	0x20
+#define PMA_PMD_FTX_CTRL2_REG	0xc309
+#define PMA_PMD_FTX_STATIC_LBN	13
+#define PMA_PMD_VEND1_REG	0xc001
+#define PMA_PMD_VEND1_LBTXD_LBN	15
+#define PCS_VEND1_REG	   	0xc000
+#define PCS_VEND1_LBTXD_LBN	5
+
+void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode)
+{
+	int addr = MDIO_QUAKE_LED0_REG + led;
+	efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
+}
+
+struct qt202x_phy_data {
+	enum efx_phy_mode phy_mode;
+	bool bug17190_in_bad_state;
+	unsigned long bug17190_timer;
+	u32 firmware_ver;
+};
+
+#define QT2022C2_MAX_RESET_TIME 500
+#define QT2022C2_RESET_WAIT 10
+
+#define QT2025C_MAX_HEARTB_TIME (5 * HZ)
+#define QT2025C_HEARTB_WAIT 100
+#define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10)
+#define QT2025C_FWSTART_WAIT 100
+
+#define BUG17190_INTERVAL (2 * HZ)
+
+static int qt2025c_wait_heartbeat(struct efx_nic *efx)
+{
+	unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME;
+	int reg, old_counter = 0;
+
+	/* Wait for firmware heartbeat to start */
+	for (;;) {
+		int counter;
+		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
+		if (reg < 0)
+			return reg;
+		counter = ((reg >> PCS_FW_HEARTB_LBN) &
+			    ((1 << PCS_FW_HEARTB_WIDTH) - 1));
+		if (old_counter == 0)
+			old_counter = counter;
+		else if (counter != old_counter)
+			break;
+		if (time_after(jiffies, timeout)) {
+			/* Some cables have EEPROMs that conflict with the
+			 * PHY's on-board EEPROM so it cannot load firmware */
+			EFX_ERR(efx, "If an SFP+ direct attach cable is"
+				" connected, please check that it complies"
+				" with the SFP+ specification\n");
+			return -ETIMEDOUT;
+		}
+		msleep(QT2025C_HEARTB_WAIT);
+	}
+
+	return 0;
+}
+
+static int qt2025c_wait_fw_status_good(struct efx_nic *efx)
+{
+	unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME;
+	int reg;
+
+	/* Wait for firmware status to look good */
+	for (;;) {
+		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
+		if (reg < 0)
+			return reg;
+		if ((reg &
+		     ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
+		    PCS_UC_STATUS_FW_SAVE)
+			break;
+		if (time_after(jiffies, timeout))
+			return -ETIMEDOUT;
+		msleep(QT2025C_FWSTART_WAIT);
+	}
+
+	return 0;
+}
+
+static void qt2025c_restart_firmware(struct efx_nic *efx)
+{
+	/* Restart microcontroller execution of firmware from RAM */
+	efx_mdio_write(efx, 3, 0xe854, 0x00c0);
+	efx_mdio_write(efx, 3, 0xe854, 0x0040);
+	msleep(50);
+}
+
+static int qt2025c_wait_reset(struct efx_nic *efx)
+{
+	int rc;
+
+	rc = qt2025c_wait_heartbeat(efx);
+	if (rc != 0)
+		return rc;
+
+	rc = qt2025c_wait_fw_status_good(efx);
+	if (rc == -ETIMEDOUT) {
+		/* Bug 17689: occasionally heartbeat starts but firmware status
+		 * code never progresses beyond 0x00.  Try again, once, after
+		 * restarting execution of the firmware image. */
+		EFX_LOG(efx, "bashing QT2025C microcontroller\n");
+		qt2025c_restart_firmware(efx);
+		rc = qt2025c_wait_heartbeat(efx);
+		if (rc != 0)
+			return rc;
+		rc = qt2025c_wait_fw_status_good(efx);
+	}
+
+	return rc;
+}
+
+static void qt2025c_firmware_id(struct efx_nic *efx)
+{
+	struct qt202x_phy_data *phy_data = efx->phy_data;
+	u8 firmware_id[9];
+	size_t i;
+
+	for (i = 0; i < sizeof(firmware_id); i++)
+		firmware_id[i] = efx_mdio_read(efx, MDIO_MMD_PCS,
+					       PCS_FW_PRODUCT_CODE_1 + i);
+	EFX_INFO(efx, "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n",
+		 (firmware_id[0] << 8) | firmware_id[1], firmware_id[2],
+		 firmware_id[3] >> 4, firmware_id[3] & 0xf,
+		 firmware_id[4], firmware_id[5],
+		 firmware_id[6], firmware_id[7], firmware_id[8]);
+	phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) |
+				 ((firmware_id[3] & 0x0f) << 16) |
+				 (firmware_id[4] << 8) | firmware_id[5];
+}
+
+static void qt2025c_bug17190_workaround(struct efx_nic *efx)
+{
+	struct qt202x_phy_data *phy_data = efx->phy_data;
+
+	/* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD
+	 * layers up, but PCS down (no block_lock).  If we notice this state
+	 * persisting for a couple of seconds, we switch PMA/PMD loopback
+	 * briefly on and then off again, which is normally sufficient to
+	 * recover it.
+	 */
+	if (efx->link_state.up ||
+	    !efx_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) {
+		phy_data->bug17190_in_bad_state = false;
+		return;
+	}
+
+	if (!phy_data->bug17190_in_bad_state) {
+		phy_data->bug17190_in_bad_state = true;
+		phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
+		return;
+	}
+
+	if (time_after_eq(jiffies, phy_data->bug17190_timer)) {
+		EFX_LOG(efx, "bashing QT2025C PMA/PMD\n");
+		efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
+				  MDIO_PMA_CTRL1_LOOPBACK, true);
+		msleep(100);
+		efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1,
+				  MDIO_PMA_CTRL1_LOOPBACK, false);
+		phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL;
+	}
+}
+
+static int qt2025c_select_phy_mode(struct efx_nic *efx)
+{
+	struct qt202x_phy_data *phy_data = efx->phy_data;
+	struct falcon_board *board = falcon_board(efx);
+	int reg, rc, i;
+	uint16_t phy_op_mode;
+
+	/* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+
+	 * Self-Configure mode.  Don't attempt any switching if we encounter
+	 * older firmware. */
+	if (phy_data->firmware_ver < 0x02000100)
+		return 0;
+
+	/* In general we will get optimal behaviour in "SFP+ Self-Configure"
+	 * mode; however, that powers down most of the PHY when no module is
+	 * present, so we must use a different mode (any fixed mode will do)
+	 * to be sure that loopbacks will work. */
+	phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020;
+
+	/* Only change mode if really necessary */
+	reg = efx_mdio_read(efx, 1, 0xc319);
+	if ((reg & 0x0038) == phy_op_mode)
+		return 0;
+	EFX_LOG(efx, "Switching PHY to mode 0x%04x\n", phy_op_mode);
+
+	/* This sequence replicates the register writes configured in the boot
+	 * EEPROM (including the differences between board revisions), except
+	 * that the operating mode is changed, and the PHY is prevented from
+	 * unnecessarily reloading the main firmware image again. */
+	efx_mdio_write(efx, 1, 0xc300, 0x0000);
+	/* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9
+	 * STOPs onto the firmware/module I2C bus to reset it, varies across
+	 * board revisions, as the bus is connected to different GPIO/LED
+	 * outputs on the PHY.) */
+	if (board->major == 0 && board->minor < 2) {
+		efx_mdio_write(efx, 1, 0xc303, 0x4498);
+		for (i = 0; i < 9; i++) {
+			efx_mdio_write(efx, 1, 0xc303, 0x4488);
+			efx_mdio_write(efx, 1, 0xc303, 0x4480);
+			efx_mdio_write(efx, 1, 0xc303, 0x4490);
+			efx_mdio_write(efx, 1, 0xc303, 0x4498);
+		}
+	} else {
+		efx_mdio_write(efx, 1, 0xc303, 0x0920);
+		efx_mdio_write(efx, 1, 0xd008, 0x0004);
+		for (i = 0; i < 9; i++) {
+			efx_mdio_write(efx, 1, 0xc303, 0x0900);
+			efx_mdio_write(efx, 1, 0xd008, 0x0005);
+			efx_mdio_write(efx, 1, 0xc303, 0x0920);
+			efx_mdio_write(efx, 1, 0xd008, 0x0004);
+		}
+		efx_mdio_write(efx, 1, 0xc303, 0x4900);
+	}
+	efx_mdio_write(efx, 1, 0xc303, 0x4900);
+	efx_mdio_write(efx, 1, 0xc302, 0x0004);
+	efx_mdio_write(efx, 1, 0xc316, 0x0013);
+	efx_mdio_write(efx, 1, 0xc318, 0x0054);
+	efx_mdio_write(efx, 1, 0xc319, phy_op_mode);
+	efx_mdio_write(efx, 1, 0xc31a, 0x0098);
+	efx_mdio_write(efx, 3, 0x0026, 0x0e00);
+	efx_mdio_write(efx, 3, 0x0027, 0x0013);
+	efx_mdio_write(efx, 3, 0x0028, 0xa528);
+	efx_mdio_write(efx, 1, 0xd006, 0x000a);
+	efx_mdio_write(efx, 1, 0xd007, 0x0009);
+	efx_mdio_write(efx, 1, 0xd008, 0x0004);
+	/* This additional write is not present in the boot EEPROM.  It
+	 * prevents the PHY's internal boot ROM doing another pointless (and
+	 * slow) reload of the firmware image (the microcontroller's code
+	 * memory is not affected by the microcontroller reset). */
+	efx_mdio_write(efx, 1, 0xc317, 0x00ff);
+	efx_mdio_write(efx, 1, 0xc300, 0x0002);
+	msleep(20);
+
+	/* Restart microcontroller execution of firmware from RAM */
+	qt2025c_restart_firmware(efx);
+
+	/* Wait for the microcontroller to be ready again */
+	rc = qt2025c_wait_reset(efx);
+	if (rc < 0) {
+		EFX_ERR(efx, "PHY microcontroller reset during mode switch "
+				"timed out\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qt202x_reset_phy(struct efx_nic *efx)
+{
+	int rc;
+
+	if (efx->phy_type == PHY_TYPE_QT2025C) {
+		/* Wait for the reset triggered by falcon_reset_hw()
+		 * to complete */
+		rc = qt2025c_wait_reset(efx);
+		if (rc < 0)
+			goto fail;
+	} else {
+		/* Reset the PHYXS MMD. This is documented as doing
+		 * a complete soft reset. */
+		rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+					QT2022C2_MAX_RESET_TIME /
+					QT2022C2_RESET_WAIT,
+					QT2022C2_RESET_WAIT);
+		if (rc < 0)
+			goto fail;
+	}
+
+	/* Wait 250ms for the PHY to complete bootup */
+	msleep(250);
+
+	falcon_board(efx)->type->init_phy(efx);
+
+	return 0;
+
+ fail:
+	EFX_ERR(efx, "PHY reset timed out\n");
+	return rc;
+}
+
+static int qt202x_phy_probe(struct efx_nic *efx)
+{
+	struct qt202x_phy_data *phy_data;
+
+	phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL);
+	if (!phy_data)
+		return -ENOMEM;
+	efx->phy_data = phy_data;
+	phy_data->phy_mode = efx->phy_mode;
+	phy_data->bug17190_in_bad_state = false;
+	phy_data->bug17190_timer = 0;
+
+	efx->mdio.mmds = QT202X_REQUIRED_DEVS;
+	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+	efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
+	return 0;
+}
+
+static int qt202x_phy_init(struct efx_nic *efx)
+{
+	u32 devid;
+	int rc;
+
+	rc = qt202x_reset_phy(efx);
+	if (rc) {
+		EFX_ERR(efx, "PHY init failed\n");
+		return rc;
+	}
+
+	devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
+	EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
+		 devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
+		 efx_mdio_id_rev(devid));
+
+	if (efx->phy_type == PHY_TYPE_QT2025C)
+		qt2025c_firmware_id(efx);
+
+	return 0;
+}
+
+static int qt202x_link_ok(struct efx_nic *efx)
+{
+	return efx_mdio_links_ok(efx, QT202X_REQUIRED_DEVS);
+}
+
+static bool qt202x_phy_poll(struct efx_nic *efx)
+{
+	bool was_up = efx->link_state.up;
+
+	efx->link_state.up = qt202x_link_ok(efx);
+	efx->link_state.speed = 10000;
+	efx->link_state.fd = true;
+	efx->link_state.fc = efx->wanted_fc;
+
+	if (efx->phy_type == PHY_TYPE_QT2025C)
+		qt2025c_bug17190_workaround(efx);
+
+	return efx->link_state.up != was_up;
+}
+
+static int qt202x_phy_reconfigure(struct efx_nic *efx)
+{
+	struct qt202x_phy_data *phy_data = efx->phy_data;
+
+	if (efx->phy_type == PHY_TYPE_QT2025C) {
+		int rc = qt2025c_select_phy_mode(efx);
+		if (rc)
+			return rc;
+
+		/* There are several different register bits which can
+		 * disable TX (and save power) on direct-attach cables
+		 * or optical transceivers, varying somewhat between
+		 * firmware versions.  Only 'static mode' appears to
+		 * cover everything. */
+		mdio_set_flag(
+			&efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
+			PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
+			efx->phy_mode & PHY_MODE_TX_DISABLED ||
+			efx->phy_mode & PHY_MODE_LOW_POWER ||
+			efx->loopback_mode == LOOPBACK_PCS ||
+			efx->loopback_mode == LOOPBACK_PMAPMD);
+	} else {
+		/* Reset the PHY when moving from tx off to tx on */
+		if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
+		    (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
+			qt202x_reset_phy(efx);
+
+		efx_mdio_transmit_disable(efx);
+	}
+
+	efx_mdio_phy_reconfigure(efx);
+
+	phy_data->phy_mode = efx->phy_mode;
+
+	return 0;
+}
+
+static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+	mdio45_ethtool_gset(&efx->mdio, ecmd);
+}
+
+static void qt202x_phy_remove(struct efx_nic *efx)
+{
+	/* Free the context block */
+	kfree(efx->phy_data);
+	efx->phy_data = NULL;
+}
+
+struct efx_phy_operations falcon_qt202x_phy_ops = {
+	.probe		 = qt202x_phy_probe,
+	.init		 = qt202x_phy_init,
+	.reconfigure	 = qt202x_phy_reconfigure,
+	.poll	     	 = qt202x_phy_poll,
+	.fini		 = efx_port_dummy_op_void,
+	.remove	  	 = qt202x_phy_remove,
+	.get_settings	 = qt202x_phy_get_settings,
+	.set_settings	 = efx_mdio_set_settings,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/regs.h linux-libre-2.6.33-gnu1/drivers/net/sfc/regs.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/regs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3168 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef EFX_REGS_H
+#define EFX_REGS_H
+
+/*
+ * Falcon hardware architecture definitions have a name prefix following
+ * the format:
+ *
+ *     F<type>_<min-rev><max-rev>_
+ *
+ * The following <type> strings are used:
+ *
+ *             MMIO register  MC register  Host memory structure
+ * -------------------------------------------------------------
+ * Address     R              MCR
+ * Bitfield    RF             MCRF         SF
+ * Enumerator  FE             MCFE         SE
+ *
+ * <min-rev> is the first revision to which the definition applies:
+ *
+ *     A: Falcon A1 (SFC4000AB)
+ *     B: Falcon B0 (SFC4000BA)
+ *     C: Siena A0 (SFL9021AA)
+ *
+ * If the definition has been changed or removed in later revisions
+ * then <max-rev> is the last revision to which the definition applies;
+ * otherwise it is "Z".
+ */
+
+/**************************************************************************
+ *
+ * Falcon/Siena registers and descriptors
+ *
+ **************************************************************************
+ */
+
+/* ADR_REGION_REG: Address region register */
+#define	FR_AZ_ADR_REGION 0x00000000
+#define	FRF_AZ_ADR_REGION3_LBN 96
+#define	FRF_AZ_ADR_REGION3_WIDTH 18
+#define	FRF_AZ_ADR_REGION2_LBN 64
+#define	FRF_AZ_ADR_REGION2_WIDTH 18
+#define	FRF_AZ_ADR_REGION1_LBN 32
+#define	FRF_AZ_ADR_REGION1_WIDTH 18
+#define	FRF_AZ_ADR_REGION0_LBN 0
+#define	FRF_AZ_ADR_REGION0_WIDTH 18
+
+/* INT_EN_REG_KER: Kernel driver Interrupt enable register */
+#define	FR_AZ_INT_EN_KER 0x00000010
+#define	FRF_AZ_KER_INT_LEVE_SEL_LBN 8
+#define	FRF_AZ_KER_INT_LEVE_SEL_WIDTH 6
+#define	FRF_AZ_KER_INT_CHAR_LBN 4
+#define	FRF_AZ_KER_INT_CHAR_WIDTH 1
+#define	FRF_AZ_KER_INT_KER_LBN 3
+#define	FRF_AZ_KER_INT_KER_WIDTH 1
+#define	FRF_AZ_DRV_INT_EN_KER_LBN 0
+#define	FRF_AZ_DRV_INT_EN_KER_WIDTH 1
+
+/* INT_EN_REG_CHAR: Char Driver interrupt enable register */
+#define	FR_BZ_INT_EN_CHAR 0x00000020
+#define	FRF_BZ_CHAR_INT_LEVE_SEL_LBN 8
+#define	FRF_BZ_CHAR_INT_LEVE_SEL_WIDTH 6
+#define	FRF_BZ_CHAR_INT_CHAR_LBN 4
+#define	FRF_BZ_CHAR_INT_CHAR_WIDTH 1
+#define	FRF_BZ_CHAR_INT_KER_LBN 3
+#define	FRF_BZ_CHAR_INT_KER_WIDTH 1
+#define	FRF_BZ_DRV_INT_EN_CHAR_LBN 0
+#define	FRF_BZ_DRV_INT_EN_CHAR_WIDTH 1
+
+/* INT_ADR_REG_KER: Interrupt host address for Kernel driver */
+#define	FR_AZ_INT_ADR_KER 0x00000030
+#define	FRF_AZ_NORM_INT_VEC_DIS_KER_LBN 64
+#define	FRF_AZ_NORM_INT_VEC_DIS_KER_WIDTH 1
+#define	FRF_AZ_INT_ADR_KER_LBN 0
+#define	FRF_AZ_INT_ADR_KER_WIDTH 64
+
+/* INT_ADR_REG_CHAR: Interrupt host address for Char driver */
+#define	FR_BZ_INT_ADR_CHAR 0x00000040
+#define	FRF_BZ_NORM_INT_VEC_DIS_CHAR_LBN 64
+#define	FRF_BZ_NORM_INT_VEC_DIS_CHAR_WIDTH 1
+#define	FRF_BZ_INT_ADR_CHAR_LBN 0
+#define	FRF_BZ_INT_ADR_CHAR_WIDTH 64
+
+/* INT_ACK_KER: Kernel interrupt acknowledge register */
+#define	FR_AA_INT_ACK_KER 0x00000050
+#define	FRF_AA_INT_ACK_KER_FIELD_LBN 0
+#define	FRF_AA_INT_ACK_KER_FIELD_WIDTH 32
+
+/* INT_ISR0_REG: Function 0 Interrupt Acknowlege Status register */
+#define	FR_BZ_INT_ISR0 0x00000090
+#define	FRF_BZ_INT_ISR_REG_LBN 0
+#define	FRF_BZ_INT_ISR_REG_WIDTH 64
+
+/* HW_INIT_REG: Hardware initialization register */
+#define	FR_AZ_HW_INIT 0x000000c0
+#define	FRF_BB_BDMRD_CPLF_FULL_LBN 124
+#define	FRF_BB_BDMRD_CPLF_FULL_WIDTH 1
+#define	FRF_BB_PCIE_CPL_TIMEOUT_CTRL_LBN 121
+#define	FRF_BB_PCIE_CPL_TIMEOUT_CTRL_WIDTH 3
+#define	FRF_CZ_TX_MRG_TAGS_LBN 120
+#define	FRF_CZ_TX_MRG_TAGS_WIDTH 1
+#define	FRF_AB_TRGT_MASK_ALL_LBN 100
+#define	FRF_AB_TRGT_MASK_ALL_WIDTH 1
+#define	FRF_AZ_DOORBELL_DROP_LBN 92
+#define	FRF_AZ_DOORBELL_DROP_WIDTH 8
+#define	FRF_AB_TX_RREQ_MASK_EN_LBN 76
+#define	FRF_AB_TX_RREQ_MASK_EN_WIDTH 1
+#define	FRF_AB_PE_EIDLE_DIS_LBN 75
+#define	FRF_AB_PE_EIDLE_DIS_WIDTH 1
+#define	FRF_AA_FC_BLOCKING_EN_LBN 45
+#define	FRF_AA_FC_BLOCKING_EN_WIDTH 1
+#define	FRF_BZ_B2B_REQ_EN_LBN 45
+#define	FRF_BZ_B2B_REQ_EN_WIDTH 1
+#define	FRF_AA_B2B_REQ_EN_LBN 44
+#define	FRF_AA_B2B_REQ_EN_WIDTH 1
+#define	FRF_BB_FC_BLOCKING_EN_LBN 44
+#define	FRF_BB_FC_BLOCKING_EN_WIDTH 1
+#define	FRF_AZ_POST_WR_MASK_LBN 40
+#define	FRF_AZ_POST_WR_MASK_WIDTH 4
+#define	FRF_AZ_TLP_TC_LBN 34
+#define	FRF_AZ_TLP_TC_WIDTH 3
+#define	FRF_AZ_TLP_ATTR_LBN 32
+#define	FRF_AZ_TLP_ATTR_WIDTH 2
+#define	FRF_AB_INTB_VEC_LBN 24
+#define	FRF_AB_INTB_VEC_WIDTH 5
+#define	FRF_AB_INTA_VEC_LBN 16
+#define	FRF_AB_INTA_VEC_WIDTH 5
+#define	FRF_AZ_WD_TIMER_LBN 8
+#define	FRF_AZ_WD_TIMER_WIDTH 8
+#define	FRF_AZ_US_DISABLE_LBN 5
+#define	FRF_AZ_US_DISABLE_WIDTH 1
+#define	FRF_AZ_TLP_EP_LBN 4
+#define	FRF_AZ_TLP_EP_WIDTH 1
+#define	FRF_AZ_ATTR_SEL_LBN 3
+#define	FRF_AZ_ATTR_SEL_WIDTH 1
+#define	FRF_AZ_TD_SEL_LBN 1
+#define	FRF_AZ_TD_SEL_WIDTH 1
+#define	FRF_AZ_TLP_TD_LBN 0
+#define	FRF_AZ_TLP_TD_WIDTH 1
+
+/* EE_SPI_HCMD_REG: SPI host command register */
+#define	FR_AB_EE_SPI_HCMD 0x00000100
+#define	FRF_AB_EE_SPI_HCMD_CMD_EN_LBN 31
+#define	FRF_AB_EE_SPI_HCMD_CMD_EN_WIDTH 1
+#define	FRF_AB_EE_WR_TIMER_ACTIVE_LBN 28
+#define	FRF_AB_EE_WR_TIMER_ACTIVE_WIDTH 1
+#define	FRF_AB_EE_SPI_HCMD_SF_SEL_LBN 24
+#define	FRF_AB_EE_SPI_HCMD_SF_SEL_WIDTH 1
+#define	FRF_AB_EE_SPI_HCMD_DABCNT_LBN 16
+#define	FRF_AB_EE_SPI_HCMD_DABCNT_WIDTH 5
+#define	FRF_AB_EE_SPI_HCMD_READ_LBN 15
+#define	FRF_AB_EE_SPI_HCMD_READ_WIDTH 1
+#define	FRF_AB_EE_SPI_HCMD_DUBCNT_LBN 12
+#define	FRF_AB_EE_SPI_HCMD_DUBCNT_WIDTH 2
+#define	FRF_AB_EE_SPI_HCMD_ADBCNT_LBN 8
+#define	FRF_AB_EE_SPI_HCMD_ADBCNT_WIDTH 2
+#define	FRF_AB_EE_SPI_HCMD_ENC_LBN 0
+#define	FRF_AB_EE_SPI_HCMD_ENC_WIDTH 8
+
+/* USR_EV_CFG: User Level Event Configuration register */
+#define	FR_CZ_USR_EV_CFG 0x00000100
+#define	FRF_CZ_USREV_DIS_LBN 16
+#define	FRF_CZ_USREV_DIS_WIDTH 1
+#define	FRF_CZ_DFLT_EVQ_LBN 0
+#define	FRF_CZ_DFLT_EVQ_WIDTH 10
+
+/* EE_SPI_HADR_REG: SPI host address register */
+#define	FR_AB_EE_SPI_HADR 0x00000110
+#define	FRF_AB_EE_SPI_HADR_DUBYTE_LBN 24
+#define	FRF_AB_EE_SPI_HADR_DUBYTE_WIDTH 8
+#define	FRF_AB_EE_SPI_HADR_ADR_LBN 0
+#define	FRF_AB_EE_SPI_HADR_ADR_WIDTH 24
+
+/* EE_SPI_HDATA_REG: SPI host data register */
+#define	FR_AB_EE_SPI_HDATA 0x00000120
+#define	FRF_AB_EE_SPI_HDATA3_LBN 96
+#define	FRF_AB_EE_SPI_HDATA3_WIDTH 32
+#define	FRF_AB_EE_SPI_HDATA2_LBN 64
+#define	FRF_AB_EE_SPI_HDATA2_WIDTH 32
+#define	FRF_AB_EE_SPI_HDATA1_LBN 32
+#define	FRF_AB_EE_SPI_HDATA1_WIDTH 32
+#define	FRF_AB_EE_SPI_HDATA0_LBN 0
+#define	FRF_AB_EE_SPI_HDATA0_WIDTH 32
+
+/* EE_BASE_PAGE_REG: Expansion ROM base mirror register */
+#define	FR_AB_EE_BASE_PAGE 0x00000130
+#define	FRF_AB_EE_EXPROM_MASK_LBN 16
+#define	FRF_AB_EE_EXPROM_MASK_WIDTH 13
+#define	FRF_AB_EE_EXP_ROM_WINDOW_BASE_LBN 0
+#define	FRF_AB_EE_EXP_ROM_WINDOW_BASE_WIDTH 13
+
+/* EE_VPD_CFG0_REG: SPI/VPD configuration register 0 */
+#define	FR_AB_EE_VPD_CFG0 0x00000140
+#define	FRF_AB_EE_SF_FASTRD_EN_LBN 127
+#define	FRF_AB_EE_SF_FASTRD_EN_WIDTH 1
+#define	FRF_AB_EE_SF_CLOCK_DIV_LBN 120
+#define	FRF_AB_EE_SF_CLOCK_DIV_WIDTH 7
+#define	FRF_AB_EE_VPD_WIP_POLL_LBN 119
+#define	FRF_AB_EE_VPD_WIP_POLL_WIDTH 1
+#define	FRF_AB_EE_EE_CLOCK_DIV_LBN 112
+#define	FRF_AB_EE_EE_CLOCK_DIV_WIDTH 7
+#define	FRF_AB_EE_EE_WR_TMR_VALUE_LBN 96
+#define	FRF_AB_EE_EE_WR_TMR_VALUE_WIDTH 16
+#define	FRF_AB_EE_VPDW_LENGTH_LBN 80
+#define	FRF_AB_EE_VPDW_LENGTH_WIDTH 15
+#define	FRF_AB_EE_VPDW_BASE_LBN 64
+#define	FRF_AB_EE_VPDW_BASE_WIDTH 15
+#define	FRF_AB_EE_VPD_WR_CMD_EN_LBN 56
+#define	FRF_AB_EE_VPD_WR_CMD_EN_WIDTH 8
+#define	FRF_AB_EE_VPD_BASE_LBN 32
+#define	FRF_AB_EE_VPD_BASE_WIDTH 24
+#define	FRF_AB_EE_VPD_LENGTH_LBN 16
+#define	FRF_AB_EE_VPD_LENGTH_WIDTH 15
+#define	FRF_AB_EE_VPD_AD_SIZE_LBN 8
+#define	FRF_AB_EE_VPD_AD_SIZE_WIDTH 5
+#define	FRF_AB_EE_VPD_ACCESS_ON_LBN 5
+#define	FRF_AB_EE_VPD_ACCESS_ON_WIDTH 1
+#define	FRF_AB_EE_VPD_ACCESS_BLOCK_LBN 4
+#define	FRF_AB_EE_VPD_ACCESS_BLOCK_WIDTH 1
+#define	FRF_AB_EE_VPD_DEV_SF_SEL_LBN 2
+#define	FRF_AB_EE_VPD_DEV_SF_SEL_WIDTH 1
+#define	FRF_AB_EE_VPD_EN_AD9_MODE_LBN 1
+#define	FRF_AB_EE_VPD_EN_AD9_MODE_WIDTH 1
+#define	FRF_AB_EE_VPD_EN_LBN 0
+#define	FRF_AB_EE_VPD_EN_WIDTH 1
+
+/* EE_VPD_SW_CNTL_REG: VPD access SW control register */
+#define	FR_AB_EE_VPD_SW_CNTL 0x00000150
+#define	FRF_AB_EE_VPD_CYCLE_PENDING_LBN 31
+#define	FRF_AB_EE_VPD_CYCLE_PENDING_WIDTH 1
+#define	FRF_AB_EE_VPD_CYC_WRITE_LBN 28
+#define	FRF_AB_EE_VPD_CYC_WRITE_WIDTH 1
+#define	FRF_AB_EE_VPD_CYC_ADR_LBN 0
+#define	FRF_AB_EE_VPD_CYC_ADR_WIDTH 15
+
+/* EE_VPD_SW_DATA_REG: VPD access SW data register */
+#define	FR_AB_EE_VPD_SW_DATA 0x00000160
+#define	FRF_AB_EE_VPD_CYC_DAT_LBN 0
+#define	FRF_AB_EE_VPD_CYC_DAT_WIDTH 32
+
+/* PBMX_DBG_IADDR_REG: Capture Module address register */
+#define	FR_CZ_PBMX_DBG_IADDR 0x000001f0
+#define	FRF_CZ_PBMX_DBG_IADDR_LBN 0
+#define	FRF_CZ_PBMX_DBG_IADDR_WIDTH 32
+
+/* PCIE_CORE_INDIRECT_REG: Indirect Access to PCIE Core registers */
+#define	FR_BB_PCIE_CORE_INDIRECT 0x000001f0
+#define	FRF_BB_PCIE_CORE_TARGET_DATA_LBN 32
+#define	FRF_BB_PCIE_CORE_TARGET_DATA_WIDTH 32
+#define	FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_LBN 15
+#define	FRF_BB_PCIE_CORE_INDIRECT_ACCESS_DIR_WIDTH 1
+#define	FRF_BB_PCIE_CORE_TARGET_REG_ADRS_LBN 0
+#define	FRF_BB_PCIE_CORE_TARGET_REG_ADRS_WIDTH 12
+
+/* PBMX_DBG_IDATA_REG: Capture Module data register */
+#define	FR_CZ_PBMX_DBG_IDATA 0x000001f8
+#define	FRF_CZ_PBMX_DBG_IDATA_LBN 0
+#define	FRF_CZ_PBMX_DBG_IDATA_WIDTH 64
+
+/* NIC_STAT_REG: NIC status register */
+#define	FR_AB_NIC_STAT 0x00000200
+#define	FRF_BB_AER_DIS_LBN 34
+#define	FRF_BB_AER_DIS_WIDTH 1
+#define	FRF_BB_EE_STRAP_EN_LBN 31
+#define	FRF_BB_EE_STRAP_EN_WIDTH 1
+#define	FRF_BB_EE_STRAP_LBN 24
+#define	FRF_BB_EE_STRAP_WIDTH 4
+#define	FRF_BB_REVISION_ID_LBN 17
+#define	FRF_BB_REVISION_ID_WIDTH 7
+#define	FRF_AB_ONCHIP_SRAM_LBN 16
+#define	FRF_AB_ONCHIP_SRAM_WIDTH 1
+#define	FRF_AB_SF_PRST_LBN 9
+#define	FRF_AB_SF_PRST_WIDTH 1
+#define	FRF_AB_EE_PRST_LBN 8
+#define	FRF_AB_EE_PRST_WIDTH 1
+#define	FRF_AB_ATE_MODE_LBN 3
+#define	FRF_AB_ATE_MODE_WIDTH 1
+#define	FRF_AB_STRAP_PINS_LBN 0
+#define	FRF_AB_STRAP_PINS_WIDTH 3
+
+/* GPIO_CTL_REG: GPIO control register */
+#define	FR_AB_GPIO_CTL 0x00000210
+#define	FRF_AB_GPIO_OUT3_LBN 112
+#define	FRF_AB_GPIO_OUT3_WIDTH 16
+#define	FRF_AB_GPIO_IN3_LBN 104
+#define	FRF_AB_GPIO_IN3_WIDTH 8
+#define	FRF_AB_GPIO_PWRUP_VALUE3_LBN 96
+#define	FRF_AB_GPIO_PWRUP_VALUE3_WIDTH 8
+#define	FRF_AB_GPIO_OUT2_LBN 80
+#define	FRF_AB_GPIO_OUT2_WIDTH 16
+#define	FRF_AB_GPIO_IN2_LBN 72
+#define	FRF_AB_GPIO_IN2_WIDTH 8
+#define	FRF_AB_GPIO_PWRUP_VALUE2_LBN 64
+#define	FRF_AB_GPIO_PWRUP_VALUE2_WIDTH 8
+#define	FRF_AB_GPIO15_OEN_LBN 63
+#define	FRF_AB_GPIO15_OEN_WIDTH 1
+#define	FRF_AB_GPIO14_OEN_LBN 62
+#define	FRF_AB_GPIO14_OEN_WIDTH 1
+#define	FRF_AB_GPIO13_OEN_LBN 61
+#define	FRF_AB_GPIO13_OEN_WIDTH 1
+#define	FRF_AB_GPIO12_OEN_LBN 60
+#define	FRF_AB_GPIO12_OEN_WIDTH 1
+#define	FRF_AB_GPIO11_OEN_LBN 59
+#define	FRF_AB_GPIO11_OEN_WIDTH 1
+#define	FRF_AB_GPIO10_OEN_LBN 58
+#define	FRF_AB_GPIO10_OEN_WIDTH 1
+#define	FRF_AB_GPIO9_OEN_LBN 57
+#define	FRF_AB_GPIO9_OEN_WIDTH 1
+#define	FRF_AB_GPIO8_OEN_LBN 56
+#define	FRF_AB_GPIO8_OEN_WIDTH 1
+#define	FRF_AB_GPIO15_OUT_LBN 55
+#define	FRF_AB_GPIO15_OUT_WIDTH 1
+#define	FRF_AB_GPIO14_OUT_LBN 54
+#define	FRF_AB_GPIO14_OUT_WIDTH 1
+#define	FRF_AB_GPIO13_OUT_LBN 53
+#define	FRF_AB_GPIO13_OUT_WIDTH 1
+#define	FRF_AB_GPIO12_OUT_LBN 52
+#define	FRF_AB_GPIO12_OUT_WIDTH 1
+#define	FRF_AB_GPIO11_OUT_LBN 51
+#define	FRF_AB_GPIO11_OUT_WIDTH 1
+#define	FRF_AB_GPIO10_OUT_LBN 50
+#define	FRF_AB_GPIO10_OUT_WIDTH 1
+#define	FRF_AB_GPIO9_OUT_LBN 49
+#define	FRF_AB_GPIO9_OUT_WIDTH 1
+#define	FRF_AB_GPIO8_OUT_LBN 48
+#define	FRF_AB_GPIO8_OUT_WIDTH 1
+#define	FRF_AB_GPIO15_IN_LBN 47
+#define	FRF_AB_GPIO15_IN_WIDTH 1
+#define	FRF_AB_GPIO14_IN_LBN 46
+#define	FRF_AB_GPIO14_IN_WIDTH 1
+#define	FRF_AB_GPIO13_IN_LBN 45
+#define	FRF_AB_GPIO13_IN_WIDTH 1
+#define	FRF_AB_GPIO12_IN_LBN 44
+#define	FRF_AB_GPIO12_IN_WIDTH 1
+#define	FRF_AB_GPIO11_IN_LBN 43
+#define	FRF_AB_GPIO11_IN_WIDTH 1
+#define	FRF_AB_GPIO10_IN_LBN 42
+#define	FRF_AB_GPIO10_IN_WIDTH 1
+#define	FRF_AB_GPIO9_IN_LBN 41
+#define	FRF_AB_GPIO9_IN_WIDTH 1
+#define	FRF_AB_GPIO8_IN_LBN 40
+#define	FRF_AB_GPIO8_IN_WIDTH 1
+#define	FRF_AB_GPIO15_PWRUP_VALUE_LBN 39
+#define	FRF_AB_GPIO15_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO14_PWRUP_VALUE_LBN 38
+#define	FRF_AB_GPIO14_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO13_PWRUP_VALUE_LBN 37
+#define	FRF_AB_GPIO13_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO12_PWRUP_VALUE_LBN 36
+#define	FRF_AB_GPIO12_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO11_PWRUP_VALUE_LBN 35
+#define	FRF_AB_GPIO11_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO10_PWRUP_VALUE_LBN 34
+#define	FRF_AB_GPIO10_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO9_PWRUP_VALUE_LBN 33
+#define	FRF_AB_GPIO9_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO8_PWRUP_VALUE_LBN 32
+#define	FRF_AB_GPIO8_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_CLK156_OUT_EN_LBN 31
+#define	FRF_AB_CLK156_OUT_EN_WIDTH 1
+#define	FRF_AB_USE_NIC_CLK_LBN 30
+#define	FRF_AB_USE_NIC_CLK_WIDTH 1
+#define	FRF_AB_GPIO5_OEN_LBN 29
+#define	FRF_AB_GPIO5_OEN_WIDTH 1
+#define	FRF_AB_GPIO4_OEN_LBN 28
+#define	FRF_AB_GPIO4_OEN_WIDTH 1
+#define	FRF_AB_GPIO3_OEN_LBN 27
+#define	FRF_AB_GPIO3_OEN_WIDTH 1
+#define	FRF_AB_GPIO2_OEN_LBN 26
+#define	FRF_AB_GPIO2_OEN_WIDTH 1
+#define	FRF_AB_GPIO1_OEN_LBN 25
+#define	FRF_AB_GPIO1_OEN_WIDTH 1
+#define	FRF_AB_GPIO0_OEN_LBN 24
+#define	FRF_AB_GPIO0_OEN_WIDTH 1
+#define	FRF_AB_GPIO7_OUT_LBN 23
+#define	FRF_AB_GPIO7_OUT_WIDTH 1
+#define	FRF_AB_GPIO6_OUT_LBN 22
+#define	FRF_AB_GPIO6_OUT_WIDTH 1
+#define	FRF_AB_GPIO5_OUT_LBN 21
+#define	FRF_AB_GPIO5_OUT_WIDTH 1
+#define	FRF_AB_GPIO4_OUT_LBN 20
+#define	FRF_AB_GPIO4_OUT_WIDTH 1
+#define	FRF_AB_GPIO3_OUT_LBN 19
+#define	FRF_AB_GPIO3_OUT_WIDTH 1
+#define	FRF_AB_GPIO2_OUT_LBN 18
+#define	FRF_AB_GPIO2_OUT_WIDTH 1
+#define	FRF_AB_GPIO1_OUT_LBN 17
+#define	FRF_AB_GPIO1_OUT_WIDTH 1
+#define	FRF_AB_GPIO0_OUT_LBN 16
+#define	FRF_AB_GPIO0_OUT_WIDTH 1
+#define	FRF_AB_GPIO7_IN_LBN 15
+#define	FRF_AB_GPIO7_IN_WIDTH 1
+#define	FRF_AB_GPIO6_IN_LBN 14
+#define	FRF_AB_GPIO6_IN_WIDTH 1
+#define	FRF_AB_GPIO5_IN_LBN 13
+#define	FRF_AB_GPIO5_IN_WIDTH 1
+#define	FRF_AB_GPIO4_IN_LBN 12
+#define	FRF_AB_GPIO4_IN_WIDTH 1
+#define	FRF_AB_GPIO3_IN_LBN 11
+#define	FRF_AB_GPIO3_IN_WIDTH 1
+#define	FRF_AB_GPIO2_IN_LBN 10
+#define	FRF_AB_GPIO2_IN_WIDTH 1
+#define	FRF_AB_GPIO1_IN_LBN 9
+#define	FRF_AB_GPIO1_IN_WIDTH 1
+#define	FRF_AB_GPIO0_IN_LBN 8
+#define	FRF_AB_GPIO0_IN_WIDTH 1
+#define	FRF_AB_GPIO7_PWRUP_VALUE_LBN 7
+#define	FRF_AB_GPIO7_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO6_PWRUP_VALUE_LBN 6
+#define	FRF_AB_GPIO6_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO5_PWRUP_VALUE_LBN 5
+#define	FRF_AB_GPIO5_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO4_PWRUP_VALUE_LBN 4
+#define	FRF_AB_GPIO4_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO3_PWRUP_VALUE_LBN 3
+#define	FRF_AB_GPIO3_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO2_PWRUP_VALUE_LBN 2
+#define	FRF_AB_GPIO2_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO1_PWRUP_VALUE_LBN 1
+#define	FRF_AB_GPIO1_PWRUP_VALUE_WIDTH 1
+#define	FRF_AB_GPIO0_PWRUP_VALUE_LBN 0
+#define	FRF_AB_GPIO0_PWRUP_VALUE_WIDTH 1
+
+/* GLB_CTL_REG: Global control register */
+#define	FR_AB_GLB_CTL 0x00000220
+#define	FRF_AB_EXT_PHY_RST_CTL_LBN 63
+#define	FRF_AB_EXT_PHY_RST_CTL_WIDTH 1
+#define	FRF_AB_XAUI_SD_RST_CTL_LBN 62
+#define	FRF_AB_XAUI_SD_RST_CTL_WIDTH 1
+#define	FRF_AB_PCIE_SD_RST_CTL_LBN 61
+#define	FRF_AB_PCIE_SD_RST_CTL_WIDTH 1
+#define	FRF_AA_PCIX_RST_CTL_LBN 60
+#define	FRF_AA_PCIX_RST_CTL_WIDTH 1
+#define	FRF_BB_BIU_RST_CTL_LBN 60
+#define	FRF_BB_BIU_RST_CTL_WIDTH 1
+#define	FRF_AB_PCIE_STKY_RST_CTL_LBN 59
+#define	FRF_AB_PCIE_STKY_RST_CTL_WIDTH 1
+#define	FRF_AB_PCIE_NSTKY_RST_CTL_LBN 58
+#define	FRF_AB_PCIE_NSTKY_RST_CTL_WIDTH 1
+#define	FRF_AB_PCIE_CORE_RST_CTL_LBN 57
+#define	FRF_AB_PCIE_CORE_RST_CTL_WIDTH 1
+#define	FRF_AB_XGRX_RST_CTL_LBN 56
+#define	FRF_AB_XGRX_RST_CTL_WIDTH 1
+#define	FRF_AB_XGTX_RST_CTL_LBN 55
+#define	FRF_AB_XGTX_RST_CTL_WIDTH 1
+#define	FRF_AB_EM_RST_CTL_LBN 54
+#define	FRF_AB_EM_RST_CTL_WIDTH 1
+#define	FRF_AB_EV_RST_CTL_LBN 53
+#define	FRF_AB_EV_RST_CTL_WIDTH 1
+#define	FRF_AB_SR_RST_CTL_LBN 52
+#define	FRF_AB_SR_RST_CTL_WIDTH 1
+#define	FRF_AB_RX_RST_CTL_LBN 51
+#define	FRF_AB_RX_RST_CTL_WIDTH 1
+#define	FRF_AB_TX_RST_CTL_LBN 50
+#define	FRF_AB_TX_RST_CTL_WIDTH 1
+#define	FRF_AB_EE_RST_CTL_LBN 49
+#define	FRF_AB_EE_RST_CTL_WIDTH 1
+#define	FRF_AB_CS_RST_CTL_LBN 48
+#define	FRF_AB_CS_RST_CTL_WIDTH 1
+#define	FRF_AB_HOT_RST_CTL_LBN 40
+#define	FRF_AB_HOT_RST_CTL_WIDTH 2
+#define	FRF_AB_RST_EXT_PHY_LBN 31
+#define	FRF_AB_RST_EXT_PHY_WIDTH 1
+#define	FRF_AB_RST_XAUI_SD_LBN 30
+#define	FRF_AB_RST_XAUI_SD_WIDTH 1
+#define	FRF_AB_RST_PCIE_SD_LBN 29
+#define	FRF_AB_RST_PCIE_SD_WIDTH 1
+#define	FRF_AA_RST_PCIX_LBN 28
+#define	FRF_AA_RST_PCIX_WIDTH 1
+#define	FRF_BB_RST_BIU_LBN 28
+#define	FRF_BB_RST_BIU_WIDTH 1
+#define	FRF_AB_RST_PCIE_STKY_LBN 27
+#define	FRF_AB_RST_PCIE_STKY_WIDTH 1
+#define	FRF_AB_RST_PCIE_NSTKY_LBN 26
+#define	FRF_AB_RST_PCIE_NSTKY_WIDTH 1
+#define	FRF_AB_RST_PCIE_CORE_LBN 25
+#define	FRF_AB_RST_PCIE_CORE_WIDTH 1
+#define	FRF_AB_RST_XGRX_LBN 24
+#define	FRF_AB_RST_XGRX_WIDTH 1
+#define	FRF_AB_RST_XGTX_LBN 23
+#define	FRF_AB_RST_XGTX_WIDTH 1
+#define	FRF_AB_RST_EM_LBN 22
+#define	FRF_AB_RST_EM_WIDTH 1
+#define	FRF_AB_RST_EV_LBN 21
+#define	FRF_AB_RST_EV_WIDTH 1
+#define	FRF_AB_RST_SR_LBN 20
+#define	FRF_AB_RST_SR_WIDTH 1
+#define	FRF_AB_RST_RX_LBN 19
+#define	FRF_AB_RST_RX_WIDTH 1
+#define	FRF_AB_RST_TX_LBN 18
+#define	FRF_AB_RST_TX_WIDTH 1
+#define	FRF_AB_RST_SF_LBN 17
+#define	FRF_AB_RST_SF_WIDTH 1
+#define	FRF_AB_RST_CS_LBN 16
+#define	FRF_AB_RST_CS_WIDTH 1
+#define	FRF_AB_INT_RST_DUR_LBN 4
+#define	FRF_AB_INT_RST_DUR_WIDTH 3
+#define	FRF_AB_EXT_PHY_RST_DUR_LBN 1
+#define	FRF_AB_EXT_PHY_RST_DUR_WIDTH 3
+#define	FFE_AB_EXT_PHY_RST_DUR_10240US 7
+#define	FFE_AB_EXT_PHY_RST_DUR_5120US 6
+#define	FFE_AB_EXT_PHY_RST_DUR_2560US 5
+#define	FFE_AB_EXT_PHY_RST_DUR_1280US 4
+#define	FFE_AB_EXT_PHY_RST_DUR_640US 3
+#define	FFE_AB_EXT_PHY_RST_DUR_320US 2
+#define	FFE_AB_EXT_PHY_RST_DUR_160US 1
+#define	FFE_AB_EXT_PHY_RST_DUR_80US 0
+#define	FRF_AB_SWRST_LBN 0
+#define	FRF_AB_SWRST_WIDTH 1
+
+/* FATAL_INTR_REG_KER: Fatal interrupt register for Kernel */
+#define	FR_AZ_FATAL_INTR_KER 0x00000230
+#define	FRF_CZ_SRAM_PERR_INT_P_KER_EN_LBN 44
+#define	FRF_CZ_SRAM_PERR_INT_P_KER_EN_WIDTH 1
+#define	FRF_AB_PCI_BUSERR_INT_KER_EN_LBN 43
+#define	FRF_AB_PCI_BUSERR_INT_KER_EN_WIDTH 1
+#define	FRF_CZ_MBU_PERR_INT_KER_EN_LBN 43
+#define	FRF_CZ_MBU_PERR_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_SRAM_OOB_INT_KER_EN_LBN 42
+#define	FRF_AZ_SRAM_OOB_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_BUFID_OOB_INT_KER_EN_LBN 41
+#define	FRF_AZ_BUFID_OOB_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_MEM_PERR_INT_KER_EN_LBN 40
+#define	FRF_AZ_MEM_PERR_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_RBUF_OWN_INT_KER_EN_LBN 39
+#define	FRF_AZ_RBUF_OWN_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_TBUF_OWN_INT_KER_EN_LBN 38
+#define	FRF_AZ_TBUF_OWN_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_RDESCQ_OWN_INT_KER_EN_LBN 37
+#define	FRF_AZ_RDESCQ_OWN_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_TDESCQ_OWN_INT_KER_EN_LBN 36
+#define	FRF_AZ_TDESCQ_OWN_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_EVQ_OWN_INT_KER_EN_LBN 35
+#define	FRF_AZ_EVQ_OWN_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_EVF_OFLO_INT_KER_EN_LBN 34
+#define	FRF_AZ_EVF_OFLO_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_ILL_ADR_INT_KER_EN_LBN 33
+#define	FRF_AZ_ILL_ADR_INT_KER_EN_WIDTH 1
+#define	FRF_AZ_SRM_PERR_INT_KER_EN_LBN 32
+#define	FRF_AZ_SRM_PERR_INT_KER_EN_WIDTH 1
+#define	FRF_CZ_SRAM_PERR_INT_P_KER_LBN 12
+#define	FRF_CZ_SRAM_PERR_INT_P_KER_WIDTH 1
+#define	FRF_AB_PCI_BUSERR_INT_KER_LBN 11
+#define	FRF_AB_PCI_BUSERR_INT_KER_WIDTH 1
+#define	FRF_CZ_MBU_PERR_INT_KER_LBN 11
+#define	FRF_CZ_MBU_PERR_INT_KER_WIDTH 1
+#define	FRF_AZ_SRAM_OOB_INT_KER_LBN 10
+#define	FRF_AZ_SRAM_OOB_INT_KER_WIDTH 1
+#define	FRF_AZ_BUFID_DC_OOB_INT_KER_LBN 9
+#define	FRF_AZ_BUFID_DC_OOB_INT_KER_WIDTH 1
+#define	FRF_AZ_MEM_PERR_INT_KER_LBN 8
+#define	FRF_AZ_MEM_PERR_INT_KER_WIDTH 1
+#define	FRF_AZ_RBUF_OWN_INT_KER_LBN 7
+#define	FRF_AZ_RBUF_OWN_INT_KER_WIDTH 1
+#define	FRF_AZ_TBUF_OWN_INT_KER_LBN 6
+#define	FRF_AZ_TBUF_OWN_INT_KER_WIDTH 1
+#define	FRF_AZ_RDESCQ_OWN_INT_KER_LBN 5
+#define	FRF_AZ_RDESCQ_OWN_INT_KER_WIDTH 1
+#define	FRF_AZ_TDESCQ_OWN_INT_KER_LBN 4
+#define	FRF_AZ_TDESCQ_OWN_INT_KER_WIDTH 1
+#define	FRF_AZ_EVQ_OWN_INT_KER_LBN 3
+#define	FRF_AZ_EVQ_OWN_INT_KER_WIDTH 1
+#define	FRF_AZ_EVF_OFLO_INT_KER_LBN 2
+#define	FRF_AZ_EVF_OFLO_INT_KER_WIDTH 1
+#define	FRF_AZ_ILL_ADR_INT_KER_LBN 1
+#define	FRF_AZ_ILL_ADR_INT_KER_WIDTH 1
+#define	FRF_AZ_SRM_PERR_INT_KER_LBN 0
+#define	FRF_AZ_SRM_PERR_INT_KER_WIDTH 1
+
+/* FATAL_INTR_REG_CHAR: Fatal interrupt register for Char */
+#define	FR_BZ_FATAL_INTR_CHAR 0x00000240
+#define	FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_LBN 44
+#define	FRF_CZ_SRAM_PERR_INT_P_CHAR_EN_WIDTH 1
+#define	FRF_BB_PCI_BUSERR_INT_CHAR_EN_LBN 43
+#define	FRF_BB_PCI_BUSERR_INT_CHAR_EN_WIDTH 1
+#define	FRF_CZ_MBU_PERR_INT_CHAR_EN_LBN 43
+#define	FRF_CZ_MBU_PERR_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_SRAM_OOB_INT_CHAR_EN_LBN 42
+#define	FRF_BZ_SRAM_OOB_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_BUFID_OOB_INT_CHAR_EN_LBN 41
+#define	FRF_BZ_BUFID_OOB_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_MEM_PERR_INT_CHAR_EN_LBN 40
+#define	FRF_BZ_MEM_PERR_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_RBUF_OWN_INT_CHAR_EN_LBN 39
+#define	FRF_BZ_RBUF_OWN_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_TBUF_OWN_INT_CHAR_EN_LBN 38
+#define	FRF_BZ_TBUF_OWN_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_RDESCQ_OWN_INT_CHAR_EN_LBN 37
+#define	FRF_BZ_RDESCQ_OWN_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_TDESCQ_OWN_INT_CHAR_EN_LBN 36
+#define	FRF_BZ_TDESCQ_OWN_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_EVQ_OWN_INT_CHAR_EN_LBN 35
+#define	FRF_BZ_EVQ_OWN_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_EVF_OFLO_INT_CHAR_EN_LBN 34
+#define	FRF_BZ_EVF_OFLO_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_ILL_ADR_INT_CHAR_EN_LBN 33
+#define	FRF_BZ_ILL_ADR_INT_CHAR_EN_WIDTH 1
+#define	FRF_BZ_SRM_PERR_INT_CHAR_EN_LBN 32
+#define	FRF_BZ_SRM_PERR_INT_CHAR_EN_WIDTH 1
+#define	FRF_CZ_SRAM_PERR_INT_P_CHAR_LBN 12
+#define	FRF_CZ_SRAM_PERR_INT_P_CHAR_WIDTH 1
+#define	FRF_BB_PCI_BUSERR_INT_CHAR_LBN 11
+#define	FRF_BB_PCI_BUSERR_INT_CHAR_WIDTH 1
+#define	FRF_CZ_MBU_PERR_INT_CHAR_LBN 11
+#define	FRF_CZ_MBU_PERR_INT_CHAR_WIDTH 1
+#define	FRF_BZ_SRAM_OOB_INT_CHAR_LBN 10
+#define	FRF_BZ_SRAM_OOB_INT_CHAR_WIDTH 1
+#define	FRF_BZ_BUFID_DC_OOB_INT_CHAR_LBN 9
+#define	FRF_BZ_BUFID_DC_OOB_INT_CHAR_WIDTH 1
+#define	FRF_BZ_MEM_PERR_INT_CHAR_LBN 8
+#define	FRF_BZ_MEM_PERR_INT_CHAR_WIDTH 1
+#define	FRF_BZ_RBUF_OWN_INT_CHAR_LBN 7
+#define	FRF_BZ_RBUF_OWN_INT_CHAR_WIDTH 1
+#define	FRF_BZ_TBUF_OWN_INT_CHAR_LBN 6
+#define	FRF_BZ_TBUF_OWN_INT_CHAR_WIDTH 1
+#define	FRF_BZ_RDESCQ_OWN_INT_CHAR_LBN 5
+#define	FRF_BZ_RDESCQ_OWN_INT_CHAR_WIDTH 1
+#define	FRF_BZ_TDESCQ_OWN_INT_CHAR_LBN 4
+#define	FRF_BZ_TDESCQ_OWN_INT_CHAR_WIDTH 1
+#define	FRF_BZ_EVQ_OWN_INT_CHAR_LBN 3
+#define	FRF_BZ_EVQ_OWN_INT_CHAR_WIDTH 1
+#define	FRF_BZ_EVF_OFLO_INT_CHAR_LBN 2
+#define	FRF_BZ_EVF_OFLO_INT_CHAR_WIDTH 1
+#define	FRF_BZ_ILL_ADR_INT_CHAR_LBN 1
+#define	FRF_BZ_ILL_ADR_INT_CHAR_WIDTH 1
+#define	FRF_BZ_SRM_PERR_INT_CHAR_LBN 0
+#define	FRF_BZ_SRM_PERR_INT_CHAR_WIDTH 1
+
+/* DP_CTRL_REG: Datapath control register */
+#define	FR_BZ_DP_CTRL 0x00000250
+#define	FRF_BZ_FLS_EVQ_ID_LBN 0
+#define	FRF_BZ_FLS_EVQ_ID_WIDTH 12
+
+/* MEM_STAT_REG: Memory status register */
+#define	FR_AZ_MEM_STAT 0x00000260
+#define	FRF_AB_MEM_PERR_VEC_LBN 53
+#define	FRF_AB_MEM_PERR_VEC_WIDTH 38
+#define	FRF_AB_MBIST_CORR_LBN 38
+#define	FRF_AB_MBIST_CORR_WIDTH 15
+#define	FRF_AB_MBIST_ERR_LBN 0
+#define	FRF_AB_MBIST_ERR_WIDTH 40
+#define	FRF_CZ_MEM_PERR_VEC_LBN 0
+#define	FRF_CZ_MEM_PERR_VEC_WIDTH 35
+
+/* CS_DEBUG_REG: Debug register */
+#define	FR_AZ_CS_DEBUG 0x00000270
+#define	FRF_AB_GLB_DEBUG2_SEL_LBN 50
+#define	FRF_AB_GLB_DEBUG2_SEL_WIDTH 3
+#define	FRF_AB_DEBUG_BLK_SEL2_LBN 47
+#define	FRF_AB_DEBUG_BLK_SEL2_WIDTH 3
+#define	FRF_AB_DEBUG_BLK_SEL1_LBN 44
+#define	FRF_AB_DEBUG_BLK_SEL1_WIDTH 3
+#define	FRF_AB_DEBUG_BLK_SEL0_LBN 41
+#define	FRF_AB_DEBUG_BLK_SEL0_WIDTH 3
+#define	FRF_CZ_CS_PORT_NUM_LBN 40
+#define	FRF_CZ_CS_PORT_NUM_WIDTH 2
+#define	FRF_AB_MISC_DEBUG_ADDR_LBN 36
+#define	FRF_AB_MISC_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_SERDES_DEBUG_ADDR_LBN 31
+#define	FRF_AB_SERDES_DEBUG_ADDR_WIDTH 5
+#define	FRF_CZ_CS_PORT_FPE_LBN 1
+#define	FRF_CZ_CS_PORT_FPE_WIDTH 35
+#define	FRF_AB_EM_DEBUG_ADDR_LBN 26
+#define	FRF_AB_EM_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_SR_DEBUG_ADDR_LBN 21
+#define	FRF_AB_SR_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_EV_DEBUG_ADDR_LBN 16
+#define	FRF_AB_EV_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_RX_DEBUG_ADDR_LBN 11
+#define	FRF_AB_RX_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_TX_DEBUG_ADDR_LBN 6
+#define	FRF_AB_TX_DEBUG_ADDR_WIDTH 5
+#define	FRF_AB_CS_BIU_DEBUG_ADDR_LBN 1
+#define	FRF_AB_CS_BIU_DEBUG_ADDR_WIDTH 5
+#define	FRF_AZ_CS_DEBUG_EN_LBN 0
+#define	FRF_AZ_CS_DEBUG_EN_WIDTH 1
+
+/* DRIVER_REG: Driver scratch register [0-7] */
+#define	FR_AZ_DRIVER 0x00000280
+#define	FR_AZ_DRIVER_STEP 16
+#define	FR_AZ_DRIVER_ROWS 8
+#define	FRF_AZ_DRIVER_DW0_LBN 0
+#define	FRF_AZ_DRIVER_DW0_WIDTH 32
+
+/* ALTERA_BUILD_REG: Altera build register */
+#define	FR_AZ_ALTERA_BUILD 0x00000300
+#define	FRF_AZ_ALTERA_BUILD_VER_LBN 0
+#define	FRF_AZ_ALTERA_BUILD_VER_WIDTH 32
+
+/* CSR_SPARE_REG: Spare register */
+#define	FR_AZ_CSR_SPARE 0x00000310
+#define	FRF_AB_MEM_PERR_EN_LBN 64
+#define	FRF_AB_MEM_PERR_EN_WIDTH 38
+#define	FRF_CZ_MEM_PERR_EN_LBN 64
+#define	FRF_CZ_MEM_PERR_EN_WIDTH 35
+#define	FRF_AB_MEM_PERR_EN_TX_DATA_LBN 72
+#define	FRF_AB_MEM_PERR_EN_TX_DATA_WIDTH 2
+#define	FRF_AZ_CSR_SPARE_BITS_LBN 0
+#define	FRF_AZ_CSR_SPARE_BITS_WIDTH 32
+
+/* PCIE_SD_CTL0123_REG: PCIE SerDes control register 0 to 3 */
+#define	FR_AB_PCIE_SD_CTL0123 0x00000320
+#define	FRF_AB_PCIE_TESTSIG_H_LBN 96
+#define	FRF_AB_PCIE_TESTSIG_H_WIDTH 19
+#define	FRF_AB_PCIE_TESTSIG_L_LBN 64
+#define	FRF_AB_PCIE_TESTSIG_L_WIDTH 19
+#define	FRF_AB_PCIE_OFFSET_LBN 56
+#define	FRF_AB_PCIE_OFFSET_WIDTH 8
+#define	FRF_AB_PCIE_OFFSETEN_H_LBN 55
+#define	FRF_AB_PCIE_OFFSETEN_H_WIDTH 1
+#define	FRF_AB_PCIE_OFFSETEN_L_LBN 54
+#define	FRF_AB_PCIE_OFFSETEN_L_WIDTH 1
+#define	FRF_AB_PCIE_HIVMODE_H_LBN 53
+#define	FRF_AB_PCIE_HIVMODE_H_WIDTH 1
+#define	FRF_AB_PCIE_HIVMODE_L_LBN 52
+#define	FRF_AB_PCIE_HIVMODE_L_WIDTH 1
+#define	FRF_AB_PCIE_PARRESET_H_LBN 51
+#define	FRF_AB_PCIE_PARRESET_H_WIDTH 1
+#define	FRF_AB_PCIE_PARRESET_L_LBN 50
+#define	FRF_AB_PCIE_PARRESET_L_WIDTH 1
+#define	FRF_AB_PCIE_LPBKWDRV_H_LBN 49
+#define	FRF_AB_PCIE_LPBKWDRV_H_WIDTH 1
+#define	FRF_AB_PCIE_LPBKWDRV_L_LBN 48
+#define	FRF_AB_PCIE_LPBKWDRV_L_WIDTH 1
+#define	FRF_AB_PCIE_LPBK_LBN 40
+#define	FRF_AB_PCIE_LPBK_WIDTH 8
+#define	FRF_AB_PCIE_PARLPBK_LBN 32
+#define	FRF_AB_PCIE_PARLPBK_WIDTH 8
+#define	FRF_AB_PCIE_RXTERMADJ_H_LBN 30
+#define	FRF_AB_PCIE_RXTERMADJ_H_WIDTH 2
+#define	FRF_AB_PCIE_RXTERMADJ_L_LBN 28
+#define	FRF_AB_PCIE_RXTERMADJ_L_WIDTH 2
+#define	FFE_AB_PCIE_RXTERMADJ_MIN15PCNT 3
+#define	FFE_AB_PCIE_RXTERMADJ_PL10PCNT 2
+#define	FFE_AB_PCIE_RXTERMADJ_MIN17PCNT 1
+#define	FFE_AB_PCIE_RXTERMADJ_NOMNL 0
+#define	FRF_AB_PCIE_TXTERMADJ_H_LBN 26
+#define	FRF_AB_PCIE_TXTERMADJ_H_WIDTH 2
+#define	FRF_AB_PCIE_TXTERMADJ_L_LBN 24
+#define	FRF_AB_PCIE_TXTERMADJ_L_WIDTH 2
+#define	FFE_AB_PCIE_TXTERMADJ_MIN15PCNT 3
+#define	FFE_AB_PCIE_TXTERMADJ_PL10PCNT 2
+#define	FFE_AB_PCIE_TXTERMADJ_MIN17PCNT 1
+#define	FFE_AB_PCIE_TXTERMADJ_NOMNL 0
+#define	FRF_AB_PCIE_RXEQCTL_H_LBN 18
+#define	FRF_AB_PCIE_RXEQCTL_H_WIDTH 2
+#define	FRF_AB_PCIE_RXEQCTL_L_LBN 16
+#define	FRF_AB_PCIE_RXEQCTL_L_WIDTH 2
+#define	FFE_AB_PCIE_RXEQCTL_OFF_ALT 3
+#define	FFE_AB_PCIE_RXEQCTL_OFF 2
+#define	FFE_AB_PCIE_RXEQCTL_MIN 1
+#define	FFE_AB_PCIE_RXEQCTL_MAX 0
+#define	FRF_AB_PCIE_HIDRV_LBN 8
+#define	FRF_AB_PCIE_HIDRV_WIDTH 8
+#define	FRF_AB_PCIE_LODRV_LBN 0
+#define	FRF_AB_PCIE_LODRV_WIDTH 8
+
+/* PCIE_SD_CTL45_REG: PCIE SerDes control register 4 and 5 */
+#define	FR_AB_PCIE_SD_CTL45 0x00000330
+#define	FRF_AB_PCIE_DTX7_LBN 60
+#define	FRF_AB_PCIE_DTX7_WIDTH 4
+#define	FRF_AB_PCIE_DTX6_LBN 56
+#define	FRF_AB_PCIE_DTX6_WIDTH 4
+#define	FRF_AB_PCIE_DTX5_LBN 52
+#define	FRF_AB_PCIE_DTX5_WIDTH 4
+#define	FRF_AB_PCIE_DTX4_LBN 48
+#define	FRF_AB_PCIE_DTX4_WIDTH 4
+#define	FRF_AB_PCIE_DTX3_LBN 44
+#define	FRF_AB_PCIE_DTX3_WIDTH 4
+#define	FRF_AB_PCIE_DTX2_LBN 40
+#define	FRF_AB_PCIE_DTX2_WIDTH 4
+#define	FRF_AB_PCIE_DTX1_LBN 36
+#define	FRF_AB_PCIE_DTX1_WIDTH 4
+#define	FRF_AB_PCIE_DTX0_LBN 32
+#define	FRF_AB_PCIE_DTX0_WIDTH 4
+#define	FRF_AB_PCIE_DEQ7_LBN 28
+#define	FRF_AB_PCIE_DEQ7_WIDTH 4
+#define	FRF_AB_PCIE_DEQ6_LBN 24
+#define	FRF_AB_PCIE_DEQ6_WIDTH 4
+#define	FRF_AB_PCIE_DEQ5_LBN 20
+#define	FRF_AB_PCIE_DEQ5_WIDTH 4
+#define	FRF_AB_PCIE_DEQ4_LBN 16
+#define	FRF_AB_PCIE_DEQ4_WIDTH 4
+#define	FRF_AB_PCIE_DEQ3_LBN 12
+#define	FRF_AB_PCIE_DEQ3_WIDTH 4
+#define	FRF_AB_PCIE_DEQ2_LBN 8
+#define	FRF_AB_PCIE_DEQ2_WIDTH 4
+#define	FRF_AB_PCIE_DEQ1_LBN 4
+#define	FRF_AB_PCIE_DEQ1_WIDTH 4
+#define	FRF_AB_PCIE_DEQ0_LBN 0
+#define	FRF_AB_PCIE_DEQ0_WIDTH 4
+
+/* PCIE_PCS_CTL_STAT_REG: PCIE PCS control and status register */
+#define	FR_AB_PCIE_PCS_CTL_STAT 0x00000340
+#define	FRF_AB_PCIE_PRBSERRCOUNT0_H_LBN 52
+#define	FRF_AB_PCIE_PRBSERRCOUNT0_H_WIDTH 4
+#define	FRF_AB_PCIE_PRBSERRCOUNT0_L_LBN 48
+#define	FRF_AB_PCIE_PRBSERRCOUNT0_L_WIDTH 4
+#define	FRF_AB_PCIE_PRBSERR_LBN 40
+#define	FRF_AB_PCIE_PRBSERR_WIDTH 8
+#define	FRF_AB_PCIE_PRBSERRH0_LBN 32
+#define	FRF_AB_PCIE_PRBSERRH0_WIDTH 8
+#define	FRF_AB_PCIE_FASTINIT_H_LBN 15
+#define	FRF_AB_PCIE_FASTINIT_H_WIDTH 1
+#define	FRF_AB_PCIE_FASTINIT_L_LBN 14
+#define	FRF_AB_PCIE_FASTINIT_L_WIDTH 1
+#define	FRF_AB_PCIE_CTCDISABLE_H_LBN 13
+#define	FRF_AB_PCIE_CTCDISABLE_H_WIDTH 1
+#define	FRF_AB_PCIE_CTCDISABLE_L_LBN 12
+#define	FRF_AB_PCIE_CTCDISABLE_L_WIDTH 1
+#define	FRF_AB_PCIE_PRBSSYNC_H_LBN 11
+#define	FRF_AB_PCIE_PRBSSYNC_H_WIDTH 1
+#define	FRF_AB_PCIE_PRBSSYNC_L_LBN 10
+#define	FRF_AB_PCIE_PRBSSYNC_L_WIDTH 1
+#define	FRF_AB_PCIE_PRBSERRACK_H_LBN 9
+#define	FRF_AB_PCIE_PRBSERRACK_H_WIDTH 1
+#define	FRF_AB_PCIE_PRBSERRACK_L_LBN 8
+#define	FRF_AB_PCIE_PRBSERRACK_L_WIDTH 1
+#define	FRF_AB_PCIE_PRBSSEL_LBN 0
+#define	FRF_AB_PCIE_PRBSSEL_WIDTH 8
+
+/* DEBUG_DATA_OUT_REG: Live Debug and Debug 2 out ports */
+#define	FR_BB_DEBUG_DATA_OUT 0x00000350
+#define	FRF_BB_DEBUG2_PORT_LBN 25
+#define	FRF_BB_DEBUG2_PORT_WIDTH 15
+#define	FRF_BB_DEBUG1_PORT_LBN 0
+#define	FRF_BB_DEBUG1_PORT_WIDTH 25
+
+/* EVQ_RPTR_REGP0: Event queue read pointer register */
+#define	FR_BZ_EVQ_RPTR_P0 0x00000400
+#define	FR_BZ_EVQ_RPTR_P0_STEP 8192
+#define	FR_BZ_EVQ_RPTR_P0_ROWS 1024
+/* EVQ_RPTR_REG_KER: Event queue read pointer register */
+#define	FR_AA_EVQ_RPTR_KER 0x00011b00
+#define	FR_AA_EVQ_RPTR_KER_STEP 4
+#define	FR_AA_EVQ_RPTR_KER_ROWS 4
+/* EVQ_RPTR_REG: Event queue read pointer register */
+#define	FR_BZ_EVQ_RPTR 0x00fa0000
+#define	FR_BZ_EVQ_RPTR_STEP 16
+#define	FR_BB_EVQ_RPTR_ROWS 4096
+#define	FR_CZ_EVQ_RPTR_ROWS 1024
+/* EVQ_RPTR_REGP123: Event queue read pointer register */
+#define	FR_BB_EVQ_RPTR_P123 0x01000400
+#define	FR_BB_EVQ_RPTR_P123_STEP 8192
+#define	FR_BB_EVQ_RPTR_P123_ROWS 3072
+#define	FRF_AZ_EVQ_RPTR_VLD_LBN 15
+#define	FRF_AZ_EVQ_RPTR_VLD_WIDTH 1
+#define	FRF_AZ_EVQ_RPTR_LBN 0
+#define	FRF_AZ_EVQ_RPTR_WIDTH 15
+
+/* TIMER_COMMAND_REGP0: Timer Command Registers */
+#define	FR_BZ_TIMER_COMMAND_P0 0x00000420
+#define	FR_BZ_TIMER_COMMAND_P0_STEP 8192
+#define	FR_BZ_TIMER_COMMAND_P0_ROWS 1024
+/* TIMER_COMMAND_REG_KER: Timer Command Registers */
+#define	FR_AA_TIMER_COMMAND_KER 0x00000420
+#define	FR_AA_TIMER_COMMAND_KER_STEP 8192
+#define	FR_AA_TIMER_COMMAND_KER_ROWS 4
+/* TIMER_COMMAND_REGP123: Timer Command Registers */
+#define	FR_BB_TIMER_COMMAND_P123 0x01000420
+#define	FR_BB_TIMER_COMMAND_P123_STEP 8192
+#define	FR_BB_TIMER_COMMAND_P123_ROWS 3072
+#define	FRF_CZ_TC_TIMER_MODE_LBN 14
+#define	FRF_CZ_TC_TIMER_MODE_WIDTH 2
+#define	FRF_AB_TC_TIMER_MODE_LBN 12
+#define	FRF_AB_TC_TIMER_MODE_WIDTH 2
+#define	FRF_CZ_TC_TIMER_VAL_LBN 0
+#define	FRF_CZ_TC_TIMER_VAL_WIDTH 14
+#define	FRF_AB_TC_TIMER_VAL_LBN 0
+#define	FRF_AB_TC_TIMER_VAL_WIDTH 12
+
+/* DRV_EV_REG: Driver generated event register */
+#define	FR_AZ_DRV_EV 0x00000440
+#define	FRF_AZ_DRV_EV_QID_LBN 64
+#define	FRF_AZ_DRV_EV_QID_WIDTH 12
+#define	FRF_AZ_DRV_EV_DATA_LBN 0
+#define	FRF_AZ_DRV_EV_DATA_WIDTH 64
+
+/* EVQ_CTL_REG: Event queue control register */
+#define	FR_AZ_EVQ_CTL 0x00000450
+#define	FRF_CZ_RX_EVQ_WAKEUP_MASK_LBN 15
+#define	FRF_CZ_RX_EVQ_WAKEUP_MASK_WIDTH 10
+#define	FRF_BB_RX_EVQ_WAKEUP_MASK_LBN 15
+#define	FRF_BB_RX_EVQ_WAKEUP_MASK_WIDTH 6
+#define	FRF_AZ_EVQ_OWNERR_CTL_LBN 14
+#define	FRF_AZ_EVQ_OWNERR_CTL_WIDTH 1
+#define	FRF_AZ_EVQ_FIFO_AF_TH_LBN 7
+#define	FRF_AZ_EVQ_FIFO_AF_TH_WIDTH 7
+#define	FRF_AZ_EVQ_FIFO_NOTAF_TH_LBN 0
+#define	FRF_AZ_EVQ_FIFO_NOTAF_TH_WIDTH 7
+
+/* EVQ_CNT1_REG: Event counter 1 register */
+#define	FR_AZ_EVQ_CNT1 0x00000460
+#define	FRF_AZ_EVQ_CNT_PRE_FIFO_LBN 120
+#define	FRF_AZ_EVQ_CNT_PRE_FIFO_WIDTH 7
+#define	FRF_AZ_EVQ_CNT_TOBIU_LBN 100
+#define	FRF_AZ_EVQ_CNT_TOBIU_WIDTH 20
+#define	FRF_AZ_EVQ_TX_REQ_CNT_LBN 80
+#define	FRF_AZ_EVQ_TX_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_RX_REQ_CNT_LBN 60
+#define	FRF_AZ_EVQ_RX_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_EM_REQ_CNT_LBN 40
+#define	FRF_AZ_EVQ_EM_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_CSR_REQ_CNT_LBN 20
+#define	FRF_AZ_EVQ_CSR_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_ERR_REQ_CNT_LBN 0
+#define	FRF_AZ_EVQ_ERR_REQ_CNT_WIDTH 20
+
+/* EVQ_CNT2_REG: Event counter 2 register */
+#define	FR_AZ_EVQ_CNT2 0x00000470
+#define	FRF_AZ_EVQ_UPD_REQ_CNT_LBN 104
+#define	FRF_AZ_EVQ_UPD_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_CLR_REQ_CNT_LBN 84
+#define	FRF_AZ_EVQ_CLR_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_RDY_CNT_LBN 80
+#define	FRF_AZ_EVQ_RDY_CNT_WIDTH 4
+#define	FRF_AZ_EVQ_WU_REQ_CNT_LBN 60
+#define	FRF_AZ_EVQ_WU_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_WET_REQ_CNT_LBN 40
+#define	FRF_AZ_EVQ_WET_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_INIT_REQ_CNT_LBN 20
+#define	FRF_AZ_EVQ_INIT_REQ_CNT_WIDTH 20
+#define	FRF_AZ_EVQ_TM_REQ_CNT_LBN 0
+#define	FRF_AZ_EVQ_TM_REQ_CNT_WIDTH 20
+
+/* USR_EV_REG: Event mailbox register */
+#define	FR_CZ_USR_EV 0x00000540
+#define	FR_CZ_USR_EV_STEP 8192
+#define	FR_CZ_USR_EV_ROWS 1024
+#define	FRF_CZ_USR_EV_DATA_LBN 0
+#define	FRF_CZ_USR_EV_DATA_WIDTH 32
+
+/* BUF_TBL_CFG_REG: Buffer table configuration register */
+#define	FR_AZ_BUF_TBL_CFG 0x00000600
+#define	FRF_AZ_BUF_TBL_MODE_LBN 3
+#define	FRF_AZ_BUF_TBL_MODE_WIDTH 1
+
+/* SRM_RX_DC_CFG_REG: SRAM receive descriptor cache configuration register */
+#define	FR_AZ_SRM_RX_DC_CFG 0x00000610
+#define	FRF_AZ_SRM_CLK_TMP_EN_LBN 21
+#define	FRF_AZ_SRM_CLK_TMP_EN_WIDTH 1
+#define	FRF_AZ_SRM_RX_DC_BASE_ADR_LBN 0
+#define	FRF_AZ_SRM_RX_DC_BASE_ADR_WIDTH 21
+
+/* SRM_TX_DC_CFG_REG: SRAM transmit descriptor cache configuration register */
+#define	FR_AZ_SRM_TX_DC_CFG 0x00000620
+#define	FRF_AZ_SRM_TX_DC_BASE_ADR_LBN 0
+#define	FRF_AZ_SRM_TX_DC_BASE_ADR_WIDTH 21
+
+/* SRM_CFG_REG: SRAM configuration register */
+#define	FR_AZ_SRM_CFG 0x00000630
+#define	FRF_AZ_SRM_OOB_ADR_INTEN_LBN 5
+#define	FRF_AZ_SRM_OOB_ADR_INTEN_WIDTH 1
+#define	FRF_AZ_SRM_OOB_BUF_INTEN_LBN 4
+#define	FRF_AZ_SRM_OOB_BUF_INTEN_WIDTH 1
+#define	FRF_AZ_SRM_INIT_EN_LBN 3
+#define	FRF_AZ_SRM_INIT_EN_WIDTH 1
+#define	FRF_AZ_SRM_NUM_BANK_LBN 2
+#define	FRF_AZ_SRM_NUM_BANK_WIDTH 1
+#define	FRF_AZ_SRM_BANK_SIZE_LBN 0
+#define	FRF_AZ_SRM_BANK_SIZE_WIDTH 2
+
+/* BUF_TBL_UPD_REG: Buffer table update register */
+#define	FR_AZ_BUF_TBL_UPD 0x00000650
+#define	FRF_AZ_BUF_UPD_CMD_LBN 63
+#define	FRF_AZ_BUF_UPD_CMD_WIDTH 1
+#define	FRF_AZ_BUF_CLR_CMD_LBN 62
+#define	FRF_AZ_BUF_CLR_CMD_WIDTH 1
+#define	FRF_AZ_BUF_CLR_END_ID_LBN 32
+#define	FRF_AZ_BUF_CLR_END_ID_WIDTH 20
+#define	FRF_AZ_BUF_CLR_START_ID_LBN 0
+#define	FRF_AZ_BUF_CLR_START_ID_WIDTH 20
+
+/* SRM_UPD_EVQ_REG: Buffer table update register */
+#define	FR_AZ_SRM_UPD_EVQ 0x00000660
+#define	FRF_AZ_SRM_UPD_EVQ_ID_LBN 0
+#define	FRF_AZ_SRM_UPD_EVQ_ID_WIDTH 12
+
+/* SRAM_PARITY_REG: SRAM parity register. */
+#define	FR_AZ_SRAM_PARITY 0x00000670
+#define	FRF_CZ_BYPASS_ECC_LBN 3
+#define	FRF_CZ_BYPASS_ECC_WIDTH 1
+#define	FRF_CZ_SEC_INT_LBN 2
+#define	FRF_CZ_SEC_INT_WIDTH 1
+#define	FRF_CZ_FORCE_SRAM_DOUBLE_ERR_LBN 1
+#define	FRF_CZ_FORCE_SRAM_DOUBLE_ERR_WIDTH 1
+#define	FRF_AB_FORCE_SRAM_PERR_LBN 0
+#define	FRF_AB_FORCE_SRAM_PERR_WIDTH 1
+#define	FRF_CZ_FORCE_SRAM_SINGLE_ERR_LBN 0
+#define	FRF_CZ_FORCE_SRAM_SINGLE_ERR_WIDTH 1
+
+/* RX_CFG_REG: Receive configuration register */
+#define	FR_AZ_RX_CFG 0x00000800
+#define	FRF_CZ_RX_MIN_KBUF_SIZE_LBN 72
+#define	FRF_CZ_RX_MIN_KBUF_SIZE_WIDTH 14
+#define	FRF_CZ_RX_HDR_SPLIT_EN_LBN 71
+#define	FRF_CZ_RX_HDR_SPLIT_EN_WIDTH 1
+#define	FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_LBN 62
+#define	FRF_CZ_RX_HDR_SPLIT_PLD_BUF_SIZE_WIDTH 9
+#define	FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_LBN 53
+#define	FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH 9
+#define	FRF_CZ_RX_PRE_RFF_IPG_LBN 49
+#define	FRF_CZ_RX_PRE_RFF_IPG_WIDTH 4
+#define	FRF_BZ_RX_TCP_SUP_LBN 48
+#define	FRF_BZ_RX_TCP_SUP_WIDTH 1
+#define	FRF_BZ_RX_INGR_EN_LBN 47
+#define	FRF_BZ_RX_INGR_EN_WIDTH 1
+#define	FRF_BZ_RX_IP_HASH_LBN 46
+#define	FRF_BZ_RX_IP_HASH_WIDTH 1
+#define	FRF_BZ_RX_HASH_ALG_LBN 45
+#define	FRF_BZ_RX_HASH_ALG_WIDTH 1
+#define	FRF_BZ_RX_HASH_INSRT_HDR_LBN 44
+#define	FRF_BZ_RX_HASH_INSRT_HDR_WIDTH 1
+#define	FRF_BZ_RX_DESC_PUSH_EN_LBN 43
+#define	FRF_BZ_RX_DESC_PUSH_EN_WIDTH 1
+#define	FRF_BZ_RX_RDW_PATCH_EN_LBN 42
+#define	FRF_BZ_RX_RDW_PATCH_EN_WIDTH 1
+#define	FRF_BB_RX_PCI_BURST_SIZE_LBN 39
+#define	FRF_BB_RX_PCI_BURST_SIZE_WIDTH 3
+#define	FRF_BZ_RX_OWNERR_CTL_LBN 38
+#define	FRF_BZ_RX_OWNERR_CTL_WIDTH 1
+#define	FRF_BZ_RX_XON_TX_TH_LBN 33
+#define	FRF_BZ_RX_XON_TX_TH_WIDTH 5
+#define	FRF_AA_RX_DESC_PUSH_EN_LBN 35
+#define	FRF_AA_RX_DESC_PUSH_EN_WIDTH 1
+#define	FRF_AA_RX_RDW_PATCH_EN_LBN 34
+#define	FRF_AA_RX_RDW_PATCH_EN_WIDTH 1
+#define	FRF_AA_RX_PCI_BURST_SIZE_LBN 31
+#define	FRF_AA_RX_PCI_BURST_SIZE_WIDTH 3
+#define	FRF_BZ_RX_XOFF_TX_TH_LBN 28
+#define	FRF_BZ_RX_XOFF_TX_TH_WIDTH 5
+#define	FRF_AA_RX_OWNERR_CTL_LBN 30
+#define	FRF_AA_RX_OWNERR_CTL_WIDTH 1
+#define	FRF_AA_RX_XON_TX_TH_LBN 25
+#define	FRF_AA_RX_XON_TX_TH_WIDTH 5
+#define	FRF_BZ_RX_USR_BUF_SIZE_LBN 19
+#define	FRF_BZ_RX_USR_BUF_SIZE_WIDTH 9
+#define	FRF_AA_RX_XOFF_TX_TH_LBN 20
+#define	FRF_AA_RX_XOFF_TX_TH_WIDTH 5
+#define	FRF_AA_RX_USR_BUF_SIZE_LBN 11
+#define	FRF_AA_RX_USR_BUF_SIZE_WIDTH 9
+#define	FRF_BZ_RX_XON_MAC_TH_LBN 10
+#define	FRF_BZ_RX_XON_MAC_TH_WIDTH 9
+#define	FRF_AA_RX_XON_MAC_TH_LBN 6
+#define	FRF_AA_RX_XON_MAC_TH_WIDTH 5
+#define	FRF_BZ_RX_XOFF_MAC_TH_LBN 1
+#define	FRF_BZ_RX_XOFF_MAC_TH_WIDTH 9
+#define	FRF_AA_RX_XOFF_MAC_TH_LBN 1
+#define	FRF_AA_RX_XOFF_MAC_TH_WIDTH 5
+#define	FRF_AZ_RX_XOFF_MAC_EN_LBN 0
+#define	FRF_AZ_RX_XOFF_MAC_EN_WIDTH 1
+
+/* RX_FILTER_CTL_REG: Receive filter control registers */
+#define	FR_BZ_RX_FILTER_CTL 0x00000810
+#define	FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_LBN 94
+#define	FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT_WIDTH 8
+#define	FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_LBN 86
+#define	FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT_WIDTH 8
+#define	FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_LBN 85
+#define	FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES_WIDTH 1
+#define	FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_LBN 69
+#define	FRF_CZ_RX_VLAN_MATCH_ETHERTYPE_WIDTH 16
+#define	FRF_CZ_MULTICAST_NOMATCH_Q_ID_LBN 57
+#define	FRF_CZ_MULTICAST_NOMATCH_Q_ID_WIDTH 12
+#define	FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_LBN 56
+#define	FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED_WIDTH 1
+#define	FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_LBN 55
+#define	FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE_WIDTH 1
+#define	FRF_CZ_UNICAST_NOMATCH_Q_ID_LBN 43
+#define	FRF_CZ_UNICAST_NOMATCH_Q_ID_WIDTH 12
+#define	FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_LBN 42
+#define	FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED_WIDTH 1
+#define	FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_LBN 41
+#define	FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE_WIDTH 1
+#define	FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_LBN 40
+#define	FRF_BZ_SCATTER_ENBL_NO_MATCH_Q_WIDTH 1
+#define	FRF_BZ_UDP_FULL_SRCH_LIMIT_LBN 32
+#define	FRF_BZ_UDP_FULL_SRCH_LIMIT_WIDTH 8
+#define	FRF_BZ_NUM_KER_LBN 24
+#define	FRF_BZ_NUM_KER_WIDTH 2
+#define	FRF_BZ_UDP_WILD_SRCH_LIMIT_LBN 16
+#define	FRF_BZ_UDP_WILD_SRCH_LIMIT_WIDTH 8
+#define	FRF_BZ_TCP_WILD_SRCH_LIMIT_LBN 8
+#define	FRF_BZ_TCP_WILD_SRCH_LIMIT_WIDTH 8
+#define	FRF_BZ_TCP_FULL_SRCH_LIMIT_LBN 0
+#define	FRF_BZ_TCP_FULL_SRCH_LIMIT_WIDTH 8
+
+/* RX_FLUSH_DESCQ_REG: Receive flush descriptor queue register */
+#define	FR_AZ_RX_FLUSH_DESCQ 0x00000820
+#define	FRF_AZ_RX_FLUSH_DESCQ_CMD_LBN 24
+#define	FRF_AZ_RX_FLUSH_DESCQ_CMD_WIDTH 1
+#define	FRF_AZ_RX_FLUSH_DESCQ_LBN 0
+#define	FRF_AZ_RX_FLUSH_DESCQ_WIDTH 12
+
+/* RX_DESC_UPD_REGP0: Receive descriptor update register. */
+#define	FR_BZ_RX_DESC_UPD_P0 0x00000830
+#define	FR_BZ_RX_DESC_UPD_P0_STEP 8192
+#define	FR_BZ_RX_DESC_UPD_P0_ROWS 1024
+/* RX_DESC_UPD_REG_KER: Receive descriptor update register. */
+#define	FR_AA_RX_DESC_UPD_KER 0x00000830
+#define	FR_AA_RX_DESC_UPD_KER_STEP 8192
+#define	FR_AA_RX_DESC_UPD_KER_ROWS 4
+/* RX_DESC_UPD_REGP123: Receive descriptor update register. */
+#define	FR_BB_RX_DESC_UPD_P123 0x01000830
+#define	FR_BB_RX_DESC_UPD_P123_STEP 8192
+#define	FR_BB_RX_DESC_UPD_P123_ROWS 3072
+#define	FRF_AZ_RX_DESC_WPTR_LBN 96
+#define	FRF_AZ_RX_DESC_WPTR_WIDTH 12
+#define	FRF_AZ_RX_DESC_PUSH_CMD_LBN 95
+#define	FRF_AZ_RX_DESC_PUSH_CMD_WIDTH 1
+#define	FRF_AZ_RX_DESC_LBN 0
+#define	FRF_AZ_RX_DESC_WIDTH 64
+
+/* RX_DC_CFG_REG: Receive descriptor cache configuration register */
+#define	FR_AZ_RX_DC_CFG 0x00000840
+#define	FRF_AB_RX_MAX_PF_LBN 2
+#define	FRF_AB_RX_MAX_PF_WIDTH 2
+#define	FRF_AZ_RX_DC_SIZE_LBN 0
+#define	FRF_AZ_RX_DC_SIZE_WIDTH 2
+#define	FFE_AZ_RX_DC_SIZE_64 3
+#define	FFE_AZ_RX_DC_SIZE_32 2
+#define	FFE_AZ_RX_DC_SIZE_16 1
+#define	FFE_AZ_RX_DC_SIZE_8 0
+
+/* RX_DC_PF_WM_REG: Receive descriptor cache pre-fetch watermark register */
+#define	FR_AZ_RX_DC_PF_WM 0x00000850
+#define	FRF_AZ_RX_DC_PF_HWM_LBN 6
+#define	FRF_AZ_RX_DC_PF_HWM_WIDTH 6
+#define	FRF_AZ_RX_DC_PF_LWM_LBN 0
+#define	FRF_AZ_RX_DC_PF_LWM_WIDTH 6
+
+/* RX_RSS_TKEY_REG: RSS Toeplitz hash key */
+#define	FR_BZ_RX_RSS_TKEY 0x00000860
+#define	FRF_BZ_RX_RSS_TKEY_HI_LBN 64
+#define	FRF_BZ_RX_RSS_TKEY_HI_WIDTH 64
+#define	FRF_BZ_RX_RSS_TKEY_LO_LBN 0
+#define	FRF_BZ_RX_RSS_TKEY_LO_WIDTH 64
+
+/* RX_NODESC_DROP_REG: Receive dropped packet counter register */
+#define	FR_AZ_RX_NODESC_DROP 0x00000880
+#define	FRF_CZ_RX_NODESC_DROP_CNT_LBN 0
+#define	FRF_CZ_RX_NODESC_DROP_CNT_WIDTH 32
+#define	FRF_AB_RX_NODESC_DROP_CNT_LBN 0
+#define	FRF_AB_RX_NODESC_DROP_CNT_WIDTH 16
+
+/* RX_SELF_RST_REG: Receive self reset register */
+#define	FR_AA_RX_SELF_RST 0x00000890
+#define	FRF_AA_RX_ISCSI_DIS_LBN 17
+#define	FRF_AA_RX_ISCSI_DIS_WIDTH 1
+#define	FRF_AA_RX_SW_RST_REG_LBN 16
+#define	FRF_AA_RX_SW_RST_REG_WIDTH 1
+#define FRF_AA_RX_NODESC_WAIT_DIS_LBN 9
+#define FRF_AA_RX_NODESC_WAIT_DIS_WIDTH 1
+#define	FRF_AA_RX_SELF_RST_EN_LBN 8
+#define	FRF_AA_RX_SELF_RST_EN_WIDTH 1
+#define	FRF_AA_RX_MAX_PF_LAT_LBN 4
+#define	FRF_AA_RX_MAX_PF_LAT_WIDTH 4
+#define	FRF_AA_RX_MAX_LU_LAT_LBN 0
+#define	FRF_AA_RX_MAX_LU_LAT_WIDTH 4
+
+/* RX_DEBUG_REG: undocumented register */
+#define	FR_AZ_RX_DEBUG 0x000008a0
+#define	FRF_AZ_RX_DEBUG_LBN 0
+#define	FRF_AZ_RX_DEBUG_WIDTH 64
+
+/* RX_PUSH_DROP_REG: Receive descriptor push dropped counter register */
+#define	FR_AZ_RX_PUSH_DROP 0x000008b0
+#define	FRF_AZ_RX_PUSH_DROP_CNT_LBN 0
+#define	FRF_AZ_RX_PUSH_DROP_CNT_WIDTH 32
+
+/* RX_RSS_IPV6_REG1: IPv6 RSS Toeplitz hash key low bytes */
+#define	FR_CZ_RX_RSS_IPV6_REG1 0x000008d0
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN 0
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH 128
+
+/* RX_RSS_IPV6_REG2: IPv6 RSS Toeplitz hash key middle bytes */
+#define	FR_CZ_RX_RSS_IPV6_REG2 0x000008e0
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN 0
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH 128
+
+/* RX_RSS_IPV6_REG3: IPv6 RSS Toeplitz hash key upper bytes and IPv6 RSS settings */
+#define	FR_CZ_RX_RSS_IPV6_REG3 0x000008f0
+#define	FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_LBN 66
+#define	FRF_CZ_RX_RSS_IPV6_THASH_ENABLE_WIDTH 1
+#define	FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_LBN 65
+#define	FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE_WIDTH 1
+#define	FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_LBN 64
+#define	FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS_WIDTH 1
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN 0
+#define	FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH 64
+
+/* TX_FLUSH_DESCQ_REG: Transmit flush descriptor queue register */
+#define	FR_AZ_TX_FLUSH_DESCQ 0x00000a00
+#define	FRF_AZ_TX_FLUSH_DESCQ_CMD_LBN 12
+#define	FRF_AZ_TX_FLUSH_DESCQ_CMD_WIDTH 1
+#define	FRF_AZ_TX_FLUSH_DESCQ_LBN 0
+#define	FRF_AZ_TX_FLUSH_DESCQ_WIDTH 12
+
+/* TX_DESC_UPD_REGP0: Transmit descriptor update register. */
+#define	FR_BZ_TX_DESC_UPD_P0 0x00000a10
+#define	FR_BZ_TX_DESC_UPD_P0_STEP 8192
+#define	FR_BZ_TX_DESC_UPD_P0_ROWS 1024
+/* TX_DESC_UPD_REG_KER: Transmit descriptor update register. */
+#define	FR_AA_TX_DESC_UPD_KER 0x00000a10
+#define	FR_AA_TX_DESC_UPD_KER_STEP 8192
+#define	FR_AA_TX_DESC_UPD_KER_ROWS 8
+/* TX_DESC_UPD_REGP123: Transmit descriptor update register. */
+#define	FR_BB_TX_DESC_UPD_P123 0x01000a10
+#define	FR_BB_TX_DESC_UPD_P123_STEP 8192
+#define	FR_BB_TX_DESC_UPD_P123_ROWS 3072
+#define	FRF_AZ_TX_DESC_WPTR_LBN 96
+#define	FRF_AZ_TX_DESC_WPTR_WIDTH 12
+#define	FRF_AZ_TX_DESC_PUSH_CMD_LBN 95
+#define	FRF_AZ_TX_DESC_PUSH_CMD_WIDTH 1
+#define	FRF_AZ_TX_DESC_LBN 0
+#define	FRF_AZ_TX_DESC_WIDTH 95
+
+/* TX_DC_CFG_REG: Transmit descriptor cache configuration register */
+#define	FR_AZ_TX_DC_CFG 0x00000a20
+#define	FRF_AZ_TX_DC_SIZE_LBN 0
+#define	FRF_AZ_TX_DC_SIZE_WIDTH 2
+#define	FFE_AZ_TX_DC_SIZE_32 2
+#define	FFE_AZ_TX_DC_SIZE_16 1
+#define	FFE_AZ_TX_DC_SIZE_8 0
+
+/* TX_CHKSM_CFG_REG: Transmit checksum configuration register */
+#define	FR_AA_TX_CHKSM_CFG 0x00000a30
+#define	FRF_AA_TX_Q_CHKSM_DIS_96_127_LBN 96
+#define	FRF_AA_TX_Q_CHKSM_DIS_96_127_WIDTH 32
+#define	FRF_AA_TX_Q_CHKSM_DIS_64_95_LBN 64
+#define	FRF_AA_TX_Q_CHKSM_DIS_64_95_WIDTH 32
+#define	FRF_AA_TX_Q_CHKSM_DIS_32_63_LBN 32
+#define	FRF_AA_TX_Q_CHKSM_DIS_32_63_WIDTH 32
+#define	FRF_AA_TX_Q_CHKSM_DIS_0_31_LBN 0
+#define	FRF_AA_TX_Q_CHKSM_DIS_0_31_WIDTH 32
+
+/* TX_CFG_REG: Transmit configuration register */
+#define	FR_AZ_TX_CFG 0x00000a50
+#define	FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_LBN 114
+#define	FRF_CZ_TX_CONT_LOOKUP_THRESH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_FILTER_TEST_MODE_BIT_LBN 113
+#define	FRF_CZ_TX_FILTER_TEST_MODE_BIT_WIDTH 1
+#define	FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_LBN 105
+#define	FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_LBN 97
+#define	FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_LBN 89
+#define	FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_LBN 81
+#define	FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_LBN 73
+#define	FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_LBN 65
+#define	FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE_WIDTH 8
+#define	FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_LBN 64
+#define	FRF_CZ_TX_FILTER_ALL_VLAN_ETHERTYPES_BIT_WIDTH 1
+#define	FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_LBN 48
+#define	FRF_CZ_TX_VLAN_MATCH_ETHERTYPE_RANGE_WIDTH 16
+#define	FRF_CZ_TX_FILTER_EN_BIT_LBN 47
+#define	FRF_CZ_TX_FILTER_EN_BIT_WIDTH 1
+#define	FRF_AZ_TX_IP_ID_P0_OFS_LBN 16
+#define	FRF_AZ_TX_IP_ID_P0_OFS_WIDTH 15
+#define	FRF_AZ_TX_NO_EOP_DISC_EN_LBN 5
+#define	FRF_AZ_TX_NO_EOP_DISC_EN_WIDTH 1
+#define	FRF_AZ_TX_P1_PRI_EN_LBN 4
+#define	FRF_AZ_TX_P1_PRI_EN_WIDTH 1
+#define	FRF_AZ_TX_OWNERR_CTL_LBN 2
+#define	FRF_AZ_TX_OWNERR_CTL_WIDTH 1
+#define	FRF_AA_TX_NON_IP_DROP_DIS_LBN 1
+#define	FRF_AA_TX_NON_IP_DROP_DIS_WIDTH 1
+#define	FRF_AZ_TX_IP_ID_REP_EN_LBN 0
+#define	FRF_AZ_TX_IP_ID_REP_EN_WIDTH 1
+
+/* TX_PUSH_DROP_REG: Transmit push dropped register */
+#define	FR_AZ_TX_PUSH_DROP 0x00000a60
+#define	FRF_AZ_TX_PUSH_DROP_CNT_LBN 0
+#define	FRF_AZ_TX_PUSH_DROP_CNT_WIDTH 32
+
+/* TX_RESERVED_REG: Transmit configuration register */
+#define	FR_AZ_TX_RESERVED 0x00000a80
+#define	FRF_AZ_TX_EVT_CNT_LBN 121
+#define	FRF_AZ_TX_EVT_CNT_WIDTH 7
+#define	FRF_AZ_TX_PREF_AGE_CNT_LBN 119
+#define	FRF_AZ_TX_PREF_AGE_CNT_WIDTH 2
+#define	FRF_AZ_TX_RD_COMP_TMR_LBN 96
+#define	FRF_AZ_TX_RD_COMP_TMR_WIDTH 23
+#define	FRF_AZ_TX_PUSH_EN_LBN 89
+#define	FRF_AZ_TX_PUSH_EN_WIDTH 1
+#define	FRF_AZ_TX_PUSH_CHK_DIS_LBN 88
+#define	FRF_AZ_TX_PUSH_CHK_DIS_WIDTH 1
+#define	FRF_AZ_TX_D_FF_FULL_P0_LBN 85
+#define	FRF_AZ_TX_D_FF_FULL_P0_WIDTH 1
+#define	FRF_AZ_TX_DMAR_ST_P0_LBN 81
+#define	FRF_AZ_TX_DMAR_ST_P0_WIDTH 1
+#define	FRF_AZ_TX_DMAQ_ST_LBN 78
+#define	FRF_AZ_TX_DMAQ_ST_WIDTH 1
+#define	FRF_AZ_TX_RX_SPACER_LBN 64
+#define	FRF_AZ_TX_RX_SPACER_WIDTH 8
+#define	FRF_AZ_TX_DROP_ABORT_EN_LBN 60
+#define	FRF_AZ_TX_DROP_ABORT_EN_WIDTH 1
+#define	FRF_AZ_TX_SOFT_EVT_EN_LBN 59
+#define	FRF_AZ_TX_SOFT_EVT_EN_WIDTH 1
+#define	FRF_AZ_TX_PS_EVT_DIS_LBN 58
+#define	FRF_AZ_TX_PS_EVT_DIS_WIDTH 1
+#define	FRF_AZ_TX_RX_SPACER_EN_LBN 57
+#define	FRF_AZ_TX_RX_SPACER_EN_WIDTH 1
+#define	FRF_AZ_TX_XP_TIMER_LBN 52
+#define	FRF_AZ_TX_XP_TIMER_WIDTH 5
+#define	FRF_AZ_TX_PREF_SPACER_LBN 44
+#define	FRF_AZ_TX_PREF_SPACER_WIDTH 8
+#define	FRF_AZ_TX_PREF_WD_TMR_LBN 22
+#define	FRF_AZ_TX_PREF_WD_TMR_WIDTH 22
+#define	FRF_AZ_TX_ONLY1TAG_LBN 21
+#define	FRF_AZ_TX_ONLY1TAG_WIDTH 1
+#define	FRF_AZ_TX_PREF_THRESHOLD_LBN 19
+#define	FRF_AZ_TX_PREF_THRESHOLD_WIDTH 2
+#define	FRF_AZ_TX_ONE_PKT_PER_Q_LBN 18
+#define	FRF_AZ_TX_ONE_PKT_PER_Q_WIDTH 1
+#define	FRF_AZ_TX_DIS_NON_IP_EV_LBN 17
+#define	FRF_AZ_TX_DIS_NON_IP_EV_WIDTH 1
+#define	FRF_AA_TX_DMA_FF_THR_LBN 16
+#define	FRF_AA_TX_DMA_FF_THR_WIDTH 1
+#define	FRF_AZ_TX_DMA_SPACER_LBN 8
+#define	FRF_AZ_TX_DMA_SPACER_WIDTH 8
+#define	FRF_AA_TX_TCP_DIS_LBN 7
+#define	FRF_AA_TX_TCP_DIS_WIDTH 1
+#define	FRF_BZ_TX_FLUSH_MIN_LEN_EN_LBN 7
+#define	FRF_BZ_TX_FLUSH_MIN_LEN_EN_WIDTH 1
+#define	FRF_AA_TX_IP_DIS_LBN 6
+#define	FRF_AA_TX_IP_DIS_WIDTH 1
+#define	FRF_AZ_TX_MAX_CPL_LBN 2
+#define	FRF_AZ_TX_MAX_CPL_WIDTH 2
+#define	FFE_AZ_TX_MAX_CPL_16 3
+#define	FFE_AZ_TX_MAX_CPL_8 2
+#define	FFE_AZ_TX_MAX_CPL_4 1
+#define	FFE_AZ_TX_MAX_CPL_NOLIMIT 0
+#define	FRF_AZ_TX_MAX_PREF_LBN 0
+#define	FRF_AZ_TX_MAX_PREF_WIDTH 2
+#define	FFE_AZ_TX_MAX_PREF_32 3
+#define	FFE_AZ_TX_MAX_PREF_16 2
+#define	FFE_AZ_TX_MAX_PREF_8 1
+#define	FFE_AZ_TX_MAX_PREF_OFF 0
+
+/* TX_PACE_REG: Transmit pace control register */
+#define	FR_BZ_TX_PACE 0x00000a90
+#define	FRF_BZ_TX_PACE_SB_NOT_AF_LBN 19
+#define	FRF_BZ_TX_PACE_SB_NOT_AF_WIDTH 10
+#define	FRF_BZ_TX_PACE_SB_AF_LBN 9
+#define	FRF_BZ_TX_PACE_SB_AF_WIDTH 10
+#define	FRF_BZ_TX_PACE_FB_BASE_LBN 5
+#define	FRF_BZ_TX_PACE_FB_BASE_WIDTH 4
+#define	FRF_BZ_TX_PACE_BIN_TH_LBN 0
+#define	FRF_BZ_TX_PACE_BIN_TH_WIDTH 5
+
+/* TX_PACE_DROP_QID_REG: PACE Drop QID Counter */
+#define	FR_BZ_TX_PACE_DROP_QID 0x00000aa0
+#define	FRF_BZ_TX_PACE_QID_DRP_CNT_LBN 0
+#define	FRF_BZ_TX_PACE_QID_DRP_CNT_WIDTH 16
+
+/* TX_VLAN_REG: Transmit VLAN tag register */
+#define	FR_BB_TX_VLAN 0x00000ae0
+#define	FRF_BB_TX_VLAN_EN_LBN 127
+#define	FRF_BB_TX_VLAN_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN7_PORT1_EN_LBN 125
+#define	FRF_BB_TX_VLAN7_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN7_PORT0_EN_LBN 124
+#define	FRF_BB_TX_VLAN7_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN7_LBN 112
+#define	FRF_BB_TX_VLAN7_WIDTH 12
+#define	FRF_BB_TX_VLAN6_PORT1_EN_LBN 109
+#define	FRF_BB_TX_VLAN6_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN6_PORT0_EN_LBN 108
+#define	FRF_BB_TX_VLAN6_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN6_LBN 96
+#define	FRF_BB_TX_VLAN6_WIDTH 12
+#define	FRF_BB_TX_VLAN5_PORT1_EN_LBN 93
+#define	FRF_BB_TX_VLAN5_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN5_PORT0_EN_LBN 92
+#define	FRF_BB_TX_VLAN5_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN5_LBN 80
+#define	FRF_BB_TX_VLAN5_WIDTH 12
+#define	FRF_BB_TX_VLAN4_PORT1_EN_LBN 77
+#define	FRF_BB_TX_VLAN4_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN4_PORT0_EN_LBN 76
+#define	FRF_BB_TX_VLAN4_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN4_LBN 64
+#define	FRF_BB_TX_VLAN4_WIDTH 12
+#define	FRF_BB_TX_VLAN3_PORT1_EN_LBN 61
+#define	FRF_BB_TX_VLAN3_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN3_PORT0_EN_LBN 60
+#define	FRF_BB_TX_VLAN3_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN3_LBN 48
+#define	FRF_BB_TX_VLAN3_WIDTH 12
+#define	FRF_BB_TX_VLAN2_PORT1_EN_LBN 45
+#define	FRF_BB_TX_VLAN2_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN2_PORT0_EN_LBN 44
+#define	FRF_BB_TX_VLAN2_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN2_LBN 32
+#define	FRF_BB_TX_VLAN2_WIDTH 12
+#define	FRF_BB_TX_VLAN1_PORT1_EN_LBN 29
+#define	FRF_BB_TX_VLAN1_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN1_PORT0_EN_LBN 28
+#define	FRF_BB_TX_VLAN1_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN1_LBN 16
+#define	FRF_BB_TX_VLAN1_WIDTH 12
+#define	FRF_BB_TX_VLAN0_PORT1_EN_LBN 13
+#define	FRF_BB_TX_VLAN0_PORT1_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN0_PORT0_EN_LBN 12
+#define	FRF_BB_TX_VLAN0_PORT0_EN_WIDTH 1
+#define	FRF_BB_TX_VLAN0_LBN 0
+#define	FRF_BB_TX_VLAN0_WIDTH 12
+
+/* TX_IPFIL_PORTEN_REG: Transmit filter control register */
+#define	FR_BZ_TX_IPFIL_PORTEN 0x00000af0
+#define	FRF_BZ_TX_MADR0_FIL_EN_LBN 64
+#define	FRF_BZ_TX_MADR0_FIL_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL31_PORT_EN_LBN 62
+#define	FRF_BB_TX_IPFIL31_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL30_PORT_EN_LBN 60
+#define	FRF_BB_TX_IPFIL30_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL29_PORT_EN_LBN 58
+#define	FRF_BB_TX_IPFIL29_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL28_PORT_EN_LBN 56
+#define	FRF_BB_TX_IPFIL28_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL27_PORT_EN_LBN 54
+#define	FRF_BB_TX_IPFIL27_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL26_PORT_EN_LBN 52
+#define	FRF_BB_TX_IPFIL26_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL25_PORT_EN_LBN 50
+#define	FRF_BB_TX_IPFIL25_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL24_PORT_EN_LBN 48
+#define	FRF_BB_TX_IPFIL24_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL23_PORT_EN_LBN 46
+#define	FRF_BB_TX_IPFIL23_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL22_PORT_EN_LBN 44
+#define	FRF_BB_TX_IPFIL22_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL21_PORT_EN_LBN 42
+#define	FRF_BB_TX_IPFIL21_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL20_PORT_EN_LBN 40
+#define	FRF_BB_TX_IPFIL20_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL19_PORT_EN_LBN 38
+#define	FRF_BB_TX_IPFIL19_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL18_PORT_EN_LBN 36
+#define	FRF_BB_TX_IPFIL18_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL17_PORT_EN_LBN 34
+#define	FRF_BB_TX_IPFIL17_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL16_PORT_EN_LBN 32
+#define	FRF_BB_TX_IPFIL16_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL15_PORT_EN_LBN 30
+#define	FRF_BB_TX_IPFIL15_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL14_PORT_EN_LBN 28
+#define	FRF_BB_TX_IPFIL14_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL13_PORT_EN_LBN 26
+#define	FRF_BB_TX_IPFIL13_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL12_PORT_EN_LBN 24
+#define	FRF_BB_TX_IPFIL12_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL11_PORT_EN_LBN 22
+#define	FRF_BB_TX_IPFIL11_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL10_PORT_EN_LBN 20
+#define	FRF_BB_TX_IPFIL10_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL9_PORT_EN_LBN 18
+#define	FRF_BB_TX_IPFIL9_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL8_PORT_EN_LBN 16
+#define	FRF_BB_TX_IPFIL8_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL7_PORT_EN_LBN 14
+#define	FRF_BB_TX_IPFIL7_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL6_PORT_EN_LBN 12
+#define	FRF_BB_TX_IPFIL6_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL5_PORT_EN_LBN 10
+#define	FRF_BB_TX_IPFIL5_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL4_PORT_EN_LBN 8
+#define	FRF_BB_TX_IPFIL4_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL3_PORT_EN_LBN 6
+#define	FRF_BB_TX_IPFIL3_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL2_PORT_EN_LBN 4
+#define	FRF_BB_TX_IPFIL2_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL1_PORT_EN_LBN 2
+#define	FRF_BB_TX_IPFIL1_PORT_EN_WIDTH 1
+#define	FRF_BB_TX_IPFIL0_PORT_EN_LBN 0
+#define	FRF_BB_TX_IPFIL0_PORT_EN_WIDTH 1
+
+/* TX_IPFIL_TBL: Transmit IP source address filter table */
+#define	FR_BB_TX_IPFIL_TBL 0x00000b00
+#define	FR_BB_TX_IPFIL_TBL_STEP 16
+#define	FR_BB_TX_IPFIL_TBL_ROWS 16
+#define	FRF_BB_TX_IPFIL_MASK_1_LBN 96
+#define	FRF_BB_TX_IPFIL_MASK_1_WIDTH 32
+#define	FRF_BB_TX_IP_SRC_ADR_1_LBN 64
+#define	FRF_BB_TX_IP_SRC_ADR_1_WIDTH 32
+#define	FRF_BB_TX_IPFIL_MASK_0_LBN 32
+#define	FRF_BB_TX_IPFIL_MASK_0_WIDTH 32
+#define	FRF_BB_TX_IP_SRC_ADR_0_LBN 0
+#define	FRF_BB_TX_IP_SRC_ADR_0_WIDTH 32
+
+/* MD_TXD_REG: PHY management transmit data register */
+#define	FR_AB_MD_TXD 0x00000c00
+#define	FRF_AB_MD_TXD_LBN 0
+#define	FRF_AB_MD_TXD_WIDTH 16
+
+/* MD_RXD_REG: PHY management receive data register */
+#define	FR_AB_MD_RXD 0x00000c10
+#define	FRF_AB_MD_RXD_LBN 0
+#define	FRF_AB_MD_RXD_WIDTH 16
+
+/* MD_CS_REG: PHY management configuration & status register */
+#define	FR_AB_MD_CS 0x00000c20
+#define	FRF_AB_MD_RD_EN_CMD_LBN 15
+#define	FRF_AB_MD_RD_EN_CMD_WIDTH 1
+#define	FRF_AB_MD_WR_EN_CMD_LBN 14
+#define	FRF_AB_MD_WR_EN_CMD_WIDTH 1
+#define	FRF_AB_MD_ADDR_CMD_LBN 13
+#define	FRF_AB_MD_ADDR_CMD_WIDTH 1
+#define	FRF_AB_MD_PT_LBN 7
+#define	FRF_AB_MD_PT_WIDTH 3
+#define	FRF_AB_MD_PL_LBN 6
+#define	FRF_AB_MD_PL_WIDTH 1
+#define	FRF_AB_MD_INT_CLR_LBN 5
+#define	FRF_AB_MD_INT_CLR_WIDTH 1
+#define	FRF_AB_MD_GC_LBN 4
+#define	FRF_AB_MD_GC_WIDTH 1
+#define	FRF_AB_MD_PRSP_LBN 3
+#define	FRF_AB_MD_PRSP_WIDTH 1
+#define	FRF_AB_MD_RIC_LBN 2
+#define	FRF_AB_MD_RIC_WIDTH 1
+#define	FRF_AB_MD_RDC_LBN 1
+#define	FRF_AB_MD_RDC_WIDTH 1
+#define	FRF_AB_MD_WRC_LBN 0
+#define	FRF_AB_MD_WRC_WIDTH 1
+
+/* MD_PHY_ADR_REG: PHY management PHY address register */
+#define	FR_AB_MD_PHY_ADR 0x00000c30
+#define	FRF_AB_MD_PHY_ADR_LBN 0
+#define	FRF_AB_MD_PHY_ADR_WIDTH 16
+
+/* MD_ID_REG: PHY management ID register */
+#define	FR_AB_MD_ID 0x00000c40
+#define	FRF_AB_MD_PRT_ADR_LBN 11
+#define	FRF_AB_MD_PRT_ADR_WIDTH 5
+#define	FRF_AB_MD_DEV_ADR_LBN 6
+#define	FRF_AB_MD_DEV_ADR_WIDTH 5
+
+/* MD_STAT_REG: PHY management status & mask register */
+#define	FR_AB_MD_STAT 0x00000c50
+#define	FRF_AB_MD_PINT_LBN 4
+#define	FRF_AB_MD_PINT_WIDTH 1
+#define	FRF_AB_MD_DONE_LBN 3
+#define	FRF_AB_MD_DONE_WIDTH 1
+#define	FRF_AB_MD_BSERR_LBN 2
+#define	FRF_AB_MD_BSERR_WIDTH 1
+#define	FRF_AB_MD_LNFL_LBN 1
+#define	FRF_AB_MD_LNFL_WIDTH 1
+#define	FRF_AB_MD_BSY_LBN 0
+#define	FRF_AB_MD_BSY_WIDTH 1
+
+/* MAC_STAT_DMA_REG: Port MAC statistical counter DMA register */
+#define	FR_AB_MAC_STAT_DMA 0x00000c60
+#define	FRF_AB_MAC_STAT_DMA_CMD_LBN 48
+#define	FRF_AB_MAC_STAT_DMA_CMD_WIDTH 1
+#define	FRF_AB_MAC_STAT_DMA_ADR_LBN 0
+#define	FRF_AB_MAC_STAT_DMA_ADR_WIDTH 48
+
+/* MAC_CTRL_REG: Port MAC control register */
+#define	FR_AB_MAC_CTRL 0x00000c80
+#define	FRF_AB_MAC_XOFF_VAL_LBN 16
+#define	FRF_AB_MAC_XOFF_VAL_WIDTH 16
+#define	FRF_BB_TXFIFO_DRAIN_EN_LBN 7
+#define	FRF_BB_TXFIFO_DRAIN_EN_WIDTH 1
+#define	FRF_AB_MAC_XG_DISTXCRC_LBN 5
+#define	FRF_AB_MAC_XG_DISTXCRC_WIDTH 1
+#define	FRF_AB_MAC_BCAD_ACPT_LBN 4
+#define	FRF_AB_MAC_BCAD_ACPT_WIDTH 1
+#define	FRF_AB_MAC_UC_PROM_LBN 3
+#define	FRF_AB_MAC_UC_PROM_WIDTH 1
+#define	FRF_AB_MAC_LINK_STATUS_LBN 2
+#define	FRF_AB_MAC_LINK_STATUS_WIDTH 1
+#define	FRF_AB_MAC_SPEED_LBN 0
+#define	FRF_AB_MAC_SPEED_WIDTH 2
+#define	FFE_AB_MAC_SPEED_10G 3
+#define	FFE_AB_MAC_SPEED_1G 2
+#define	FFE_AB_MAC_SPEED_100M 1
+#define	FFE_AB_MAC_SPEED_10M 0
+
+/* GEN_MODE_REG: General Purpose mode register (external interrupt mask) */
+#define	FR_BB_GEN_MODE 0x00000c90
+#define	FRF_BB_XFP_PHY_INT_POL_SEL_LBN 3
+#define	FRF_BB_XFP_PHY_INT_POL_SEL_WIDTH 1
+#define	FRF_BB_XG_PHY_INT_POL_SEL_LBN 2
+#define	FRF_BB_XG_PHY_INT_POL_SEL_WIDTH 1
+#define	FRF_BB_XFP_PHY_INT_MASK_LBN 1
+#define	FRF_BB_XFP_PHY_INT_MASK_WIDTH 1
+#define	FRF_BB_XG_PHY_INT_MASK_LBN 0
+#define	FRF_BB_XG_PHY_INT_MASK_WIDTH 1
+
+/* MAC_MC_HASH_REG0: Multicast address hash table */
+#define	FR_AB_MAC_MC_HASH_REG0 0x00000ca0
+#define	FRF_AB_MAC_MCAST_HASH0_LBN 0
+#define	FRF_AB_MAC_MCAST_HASH0_WIDTH 128
+
+/* MAC_MC_HASH_REG1: Multicast address hash table */
+#define	FR_AB_MAC_MC_HASH_REG1 0x00000cb0
+#define	FRF_AB_MAC_MCAST_HASH1_LBN 0
+#define	FRF_AB_MAC_MCAST_HASH1_WIDTH 128
+
+/* GM_CFG1_REG: GMAC configuration register 1 */
+#define	FR_AB_GM_CFG1 0x00000e00
+#define	FRF_AB_GM_SW_RST_LBN 31
+#define	FRF_AB_GM_SW_RST_WIDTH 1
+#define	FRF_AB_GM_SIM_RST_LBN 30
+#define	FRF_AB_GM_SIM_RST_WIDTH 1
+#define	FRF_AB_GM_RST_RX_MAC_CTL_LBN 19
+#define	FRF_AB_GM_RST_RX_MAC_CTL_WIDTH 1
+#define	FRF_AB_GM_RST_TX_MAC_CTL_LBN 18
+#define	FRF_AB_GM_RST_TX_MAC_CTL_WIDTH 1
+#define	FRF_AB_GM_RST_RX_FUNC_LBN 17
+#define	FRF_AB_GM_RST_RX_FUNC_WIDTH 1
+#define	FRF_AB_GM_RST_TX_FUNC_LBN 16
+#define	FRF_AB_GM_RST_TX_FUNC_WIDTH 1
+#define	FRF_AB_GM_LOOP_LBN 8
+#define	FRF_AB_GM_LOOP_WIDTH 1
+#define	FRF_AB_GM_RX_FC_EN_LBN 5
+#define	FRF_AB_GM_RX_FC_EN_WIDTH 1
+#define	FRF_AB_GM_TX_FC_EN_LBN 4
+#define	FRF_AB_GM_TX_FC_EN_WIDTH 1
+#define	FRF_AB_GM_SYNC_RXEN_LBN 3
+#define	FRF_AB_GM_SYNC_RXEN_WIDTH 1
+#define	FRF_AB_GM_RX_EN_LBN 2
+#define	FRF_AB_GM_RX_EN_WIDTH 1
+#define	FRF_AB_GM_SYNC_TXEN_LBN 1
+#define	FRF_AB_GM_SYNC_TXEN_WIDTH 1
+#define	FRF_AB_GM_TX_EN_LBN 0
+#define	FRF_AB_GM_TX_EN_WIDTH 1
+
+/* GM_CFG2_REG: GMAC configuration register 2 */
+#define	FR_AB_GM_CFG2 0x00000e10
+#define	FRF_AB_GM_PAMBL_LEN_LBN 12
+#define	FRF_AB_GM_PAMBL_LEN_WIDTH 4
+#define	FRF_AB_GM_IF_MODE_LBN 8
+#define	FRF_AB_GM_IF_MODE_WIDTH 2
+#define	FFE_AB_IF_MODE_BYTE_MODE 2
+#define	FFE_AB_IF_MODE_NIBBLE_MODE 1
+#define	FRF_AB_GM_HUGE_FRM_EN_LBN 5
+#define	FRF_AB_GM_HUGE_FRM_EN_WIDTH 1
+#define	FRF_AB_GM_LEN_CHK_LBN 4
+#define	FRF_AB_GM_LEN_CHK_WIDTH 1
+#define	FRF_AB_GM_PAD_CRC_EN_LBN 2
+#define	FRF_AB_GM_PAD_CRC_EN_WIDTH 1
+#define	FRF_AB_GM_CRC_EN_LBN 1
+#define	FRF_AB_GM_CRC_EN_WIDTH 1
+#define	FRF_AB_GM_FD_LBN 0
+#define	FRF_AB_GM_FD_WIDTH 1
+
+/* GM_IPG_REG: GMAC IPG register */
+#define	FR_AB_GM_IPG 0x00000e20
+#define	FRF_AB_GM_NONB2B_IPG1_LBN 24
+#define	FRF_AB_GM_NONB2B_IPG1_WIDTH 7
+#define	FRF_AB_GM_NONB2B_IPG2_LBN 16
+#define	FRF_AB_GM_NONB2B_IPG2_WIDTH 7
+#define	FRF_AB_GM_MIN_IPG_ENF_LBN 8
+#define	FRF_AB_GM_MIN_IPG_ENF_WIDTH 8
+#define	FRF_AB_GM_B2B_IPG_LBN 0
+#define	FRF_AB_GM_B2B_IPG_WIDTH 7
+
+/* GM_HD_REG: GMAC half duplex register */
+#define	FR_AB_GM_HD 0x00000e30
+#define	FRF_AB_GM_ALT_BOFF_VAL_LBN 20
+#define	FRF_AB_GM_ALT_BOFF_VAL_WIDTH 4
+#define	FRF_AB_GM_ALT_BOFF_EN_LBN 19
+#define	FRF_AB_GM_ALT_BOFF_EN_WIDTH 1
+#define	FRF_AB_GM_BP_NO_BOFF_LBN 18
+#define	FRF_AB_GM_BP_NO_BOFF_WIDTH 1
+#define	FRF_AB_GM_DIS_BOFF_LBN 17
+#define	FRF_AB_GM_DIS_BOFF_WIDTH 1
+#define	FRF_AB_GM_EXDEF_TX_EN_LBN 16
+#define	FRF_AB_GM_EXDEF_TX_EN_WIDTH 1
+#define	FRF_AB_GM_RTRY_LIMIT_LBN 12
+#define	FRF_AB_GM_RTRY_LIMIT_WIDTH 4
+#define	FRF_AB_GM_COL_WIN_LBN 0
+#define	FRF_AB_GM_COL_WIN_WIDTH 10
+
+/* GM_MAX_FLEN_REG: GMAC maximum frame length register */
+#define	FR_AB_GM_MAX_FLEN 0x00000e40
+#define	FRF_AB_GM_MAX_FLEN_LBN 0
+#define	FRF_AB_GM_MAX_FLEN_WIDTH 16
+
+/* GM_TEST_REG: GMAC test register */
+#define	FR_AB_GM_TEST 0x00000e70
+#define	FRF_AB_GM_MAX_BOFF_LBN 3
+#define	FRF_AB_GM_MAX_BOFF_WIDTH 1
+#define	FRF_AB_GM_REG_TX_FLOW_EN_LBN 2
+#define	FRF_AB_GM_REG_TX_FLOW_EN_WIDTH 1
+#define	FRF_AB_GM_TEST_PAUSE_LBN 1
+#define	FRF_AB_GM_TEST_PAUSE_WIDTH 1
+#define	FRF_AB_GM_SHORT_SLOT_LBN 0
+#define	FRF_AB_GM_SHORT_SLOT_WIDTH 1
+
+/* GM_ADR1_REG: GMAC station address register 1 */
+#define	FR_AB_GM_ADR1 0x00000f00
+#define	FRF_AB_GM_ADR_B0_LBN 24
+#define	FRF_AB_GM_ADR_B0_WIDTH 8
+#define	FRF_AB_GM_ADR_B1_LBN 16
+#define	FRF_AB_GM_ADR_B1_WIDTH 8
+#define	FRF_AB_GM_ADR_B2_LBN 8
+#define	FRF_AB_GM_ADR_B2_WIDTH 8
+#define	FRF_AB_GM_ADR_B3_LBN 0
+#define	FRF_AB_GM_ADR_B3_WIDTH 8
+
+/* GM_ADR2_REG: GMAC station address register 2 */
+#define	FR_AB_GM_ADR2 0x00000f10
+#define	FRF_AB_GM_ADR_B4_LBN 24
+#define	FRF_AB_GM_ADR_B4_WIDTH 8
+#define	FRF_AB_GM_ADR_B5_LBN 16
+#define	FRF_AB_GM_ADR_B5_WIDTH 8
+
+/* GMF_CFG0_REG: GMAC FIFO configuration register 0 */
+#define	FR_AB_GMF_CFG0 0x00000f20
+#define	FRF_AB_GMF_FTFENRPLY_LBN 20
+#define	FRF_AB_GMF_FTFENRPLY_WIDTH 1
+#define	FRF_AB_GMF_STFENRPLY_LBN 19
+#define	FRF_AB_GMF_STFENRPLY_WIDTH 1
+#define	FRF_AB_GMF_FRFENRPLY_LBN 18
+#define	FRF_AB_GMF_FRFENRPLY_WIDTH 1
+#define	FRF_AB_GMF_SRFENRPLY_LBN 17
+#define	FRF_AB_GMF_SRFENRPLY_WIDTH 1
+#define	FRF_AB_GMF_WTMENRPLY_LBN 16
+#define	FRF_AB_GMF_WTMENRPLY_WIDTH 1
+#define	FRF_AB_GMF_FTFENREQ_LBN 12
+#define	FRF_AB_GMF_FTFENREQ_WIDTH 1
+#define	FRF_AB_GMF_STFENREQ_LBN 11
+#define	FRF_AB_GMF_STFENREQ_WIDTH 1
+#define	FRF_AB_GMF_FRFENREQ_LBN 10
+#define	FRF_AB_GMF_FRFENREQ_WIDTH 1
+#define	FRF_AB_GMF_SRFENREQ_LBN 9
+#define	FRF_AB_GMF_SRFENREQ_WIDTH 1
+#define	FRF_AB_GMF_WTMENREQ_LBN 8
+#define	FRF_AB_GMF_WTMENREQ_WIDTH 1
+#define	FRF_AB_GMF_HSTRSTFT_LBN 4
+#define	FRF_AB_GMF_HSTRSTFT_WIDTH 1
+#define	FRF_AB_GMF_HSTRSTST_LBN 3
+#define	FRF_AB_GMF_HSTRSTST_WIDTH 1
+#define	FRF_AB_GMF_HSTRSTFR_LBN 2
+#define	FRF_AB_GMF_HSTRSTFR_WIDTH 1
+#define	FRF_AB_GMF_HSTRSTSR_LBN 1
+#define	FRF_AB_GMF_HSTRSTSR_WIDTH 1
+#define	FRF_AB_GMF_HSTRSTWT_LBN 0
+#define	FRF_AB_GMF_HSTRSTWT_WIDTH 1
+
+/* GMF_CFG1_REG: GMAC FIFO configuration register 1 */
+#define	FR_AB_GMF_CFG1 0x00000f30
+#define	FRF_AB_GMF_CFGFRTH_LBN 16
+#define	FRF_AB_GMF_CFGFRTH_WIDTH 5
+#define	FRF_AB_GMF_CFGXOFFRTX_LBN 0
+#define	FRF_AB_GMF_CFGXOFFRTX_WIDTH 16
+
+/* GMF_CFG2_REG: GMAC FIFO configuration register 2 */
+#define	FR_AB_GMF_CFG2 0x00000f40
+#define	FRF_AB_GMF_CFGHWM_LBN 16
+#define	FRF_AB_GMF_CFGHWM_WIDTH 6
+#define	FRF_AB_GMF_CFGLWM_LBN 0
+#define	FRF_AB_GMF_CFGLWM_WIDTH 6
+
+/* GMF_CFG3_REG: GMAC FIFO configuration register 3 */
+#define	FR_AB_GMF_CFG3 0x00000f50
+#define	FRF_AB_GMF_CFGHWMFT_LBN 16
+#define	FRF_AB_GMF_CFGHWMFT_WIDTH 6
+#define	FRF_AB_GMF_CFGFTTH_LBN 0
+#define	FRF_AB_GMF_CFGFTTH_WIDTH 6
+
+/* GMF_CFG4_REG: GMAC FIFO configuration register 4 */
+#define	FR_AB_GMF_CFG4 0x00000f60
+#define	FRF_AB_GMF_HSTFLTRFRM_LBN 0
+#define	FRF_AB_GMF_HSTFLTRFRM_WIDTH 18
+
+/* GMF_CFG5_REG: GMAC FIFO configuration register 5 */
+#define	FR_AB_GMF_CFG5 0x00000f70
+#define	FRF_AB_GMF_CFGHDPLX_LBN 22
+#define	FRF_AB_GMF_CFGHDPLX_WIDTH 1
+#define	FRF_AB_GMF_SRFULL_LBN 21
+#define	FRF_AB_GMF_SRFULL_WIDTH 1
+#define	FRF_AB_GMF_HSTSRFULLCLR_LBN 20
+#define	FRF_AB_GMF_HSTSRFULLCLR_WIDTH 1
+#define	FRF_AB_GMF_CFGBYTMODE_LBN 19
+#define	FRF_AB_GMF_CFGBYTMODE_WIDTH 1
+#define	FRF_AB_GMF_HSTDRPLT64_LBN 18
+#define	FRF_AB_GMF_HSTDRPLT64_WIDTH 1
+#define	FRF_AB_GMF_HSTFLTRFRMDC_LBN 0
+#define	FRF_AB_GMF_HSTFLTRFRMDC_WIDTH 18
+
+/* TX_SRC_MAC_TBL: Transmit IP source address filter table */
+#define	FR_BB_TX_SRC_MAC_TBL 0x00001000
+#define	FR_BB_TX_SRC_MAC_TBL_STEP 16
+#define	FR_BB_TX_SRC_MAC_TBL_ROWS 16
+#define	FRF_BB_TX_SRC_MAC_ADR_1_LBN 64
+#define	FRF_BB_TX_SRC_MAC_ADR_1_WIDTH 48
+#define	FRF_BB_TX_SRC_MAC_ADR_0_LBN 0
+#define	FRF_BB_TX_SRC_MAC_ADR_0_WIDTH 48
+
+/* TX_SRC_MAC_CTL_REG: Transmit MAC source address filter control */
+#define	FR_BB_TX_SRC_MAC_CTL 0x00001100
+#define	FRF_BB_TX_SRC_DROP_CTR_LBN 16
+#define	FRF_BB_TX_SRC_DROP_CTR_WIDTH 16
+#define	FRF_BB_TX_SRC_FLTR_EN_LBN 15
+#define	FRF_BB_TX_SRC_FLTR_EN_WIDTH 1
+#define	FRF_BB_TX_DROP_CTR_CLR_LBN 12
+#define	FRF_BB_TX_DROP_CTR_CLR_WIDTH 1
+#define	FRF_BB_TX_MAC_QID_SEL_LBN 0
+#define	FRF_BB_TX_MAC_QID_SEL_WIDTH 3
+
+/* XM_ADR_LO_REG: XGMAC address register low */
+#define	FR_AB_XM_ADR_LO 0x00001200
+#define	FRF_AB_XM_ADR_LO_LBN 0
+#define	FRF_AB_XM_ADR_LO_WIDTH 32
+
+/* XM_ADR_HI_REG: XGMAC address register high */
+#define	FR_AB_XM_ADR_HI 0x00001210
+#define	FRF_AB_XM_ADR_HI_LBN 0
+#define	FRF_AB_XM_ADR_HI_WIDTH 16
+
+/* XM_GLB_CFG_REG: XGMAC global configuration */
+#define	FR_AB_XM_GLB_CFG 0x00001220
+#define	FRF_AB_XM_RMTFLT_GEN_LBN 17
+#define	FRF_AB_XM_RMTFLT_GEN_WIDTH 1
+#define	FRF_AB_XM_DEBUG_MODE_LBN 16
+#define	FRF_AB_XM_DEBUG_MODE_WIDTH 1
+#define	FRF_AB_XM_RX_STAT_EN_LBN 11
+#define	FRF_AB_XM_RX_STAT_EN_WIDTH 1
+#define	FRF_AB_XM_TX_STAT_EN_LBN 10
+#define	FRF_AB_XM_TX_STAT_EN_WIDTH 1
+#define	FRF_AB_XM_RX_JUMBO_MODE_LBN 6
+#define	FRF_AB_XM_RX_JUMBO_MODE_WIDTH 1
+#define	FRF_AB_XM_WAN_MODE_LBN 5
+#define	FRF_AB_XM_WAN_MODE_WIDTH 1
+#define	FRF_AB_XM_INTCLR_MODE_LBN 3
+#define	FRF_AB_XM_INTCLR_MODE_WIDTH 1
+#define	FRF_AB_XM_CORE_RST_LBN 0
+#define	FRF_AB_XM_CORE_RST_WIDTH 1
+
+/* XM_TX_CFG_REG: XGMAC transmit configuration */
+#define	FR_AB_XM_TX_CFG 0x00001230
+#define	FRF_AB_XM_TX_PROG_LBN 24
+#define	FRF_AB_XM_TX_PROG_WIDTH 1
+#define	FRF_AB_XM_IPG_LBN 16
+#define	FRF_AB_XM_IPG_WIDTH 4
+#define	FRF_AB_XM_FCNTL_LBN 10
+#define	FRF_AB_XM_FCNTL_WIDTH 1
+#define	FRF_AB_XM_TXCRC_LBN 8
+#define	FRF_AB_XM_TXCRC_WIDTH 1
+#define	FRF_AB_XM_EDRC_LBN 6
+#define	FRF_AB_XM_EDRC_WIDTH 1
+#define	FRF_AB_XM_AUTO_PAD_LBN 5
+#define	FRF_AB_XM_AUTO_PAD_WIDTH 1
+#define	FRF_AB_XM_TX_PRMBL_LBN 2
+#define	FRF_AB_XM_TX_PRMBL_WIDTH 1
+#define	FRF_AB_XM_TXEN_LBN 1
+#define	FRF_AB_XM_TXEN_WIDTH 1
+#define	FRF_AB_XM_TX_RST_LBN 0
+#define	FRF_AB_XM_TX_RST_WIDTH 1
+
+/* XM_RX_CFG_REG: XGMAC receive configuration */
+#define	FR_AB_XM_RX_CFG 0x00001240
+#define	FRF_AB_XM_PASS_LENERR_LBN 26
+#define	FRF_AB_XM_PASS_LENERR_WIDTH 1
+#define	FRF_AB_XM_PASS_CRC_ERR_LBN 25
+#define	FRF_AB_XM_PASS_CRC_ERR_WIDTH 1
+#define	FRF_AB_XM_PASS_PRMBLE_ERR_LBN 24
+#define	FRF_AB_XM_PASS_PRMBLE_ERR_WIDTH 1
+#define	FRF_AB_XM_REJ_BCAST_LBN 20
+#define	FRF_AB_XM_REJ_BCAST_WIDTH 1
+#define	FRF_AB_XM_ACPT_ALL_MCAST_LBN 11
+#define	FRF_AB_XM_ACPT_ALL_MCAST_WIDTH 1
+#define	FRF_AB_XM_ACPT_ALL_UCAST_LBN 9
+#define	FRF_AB_XM_ACPT_ALL_UCAST_WIDTH 1
+#define	FRF_AB_XM_AUTO_DEPAD_LBN 8
+#define	FRF_AB_XM_AUTO_DEPAD_WIDTH 1
+#define	FRF_AB_XM_RXCRC_LBN 3
+#define	FRF_AB_XM_RXCRC_WIDTH 1
+#define	FRF_AB_XM_RX_PRMBL_LBN 2
+#define	FRF_AB_XM_RX_PRMBL_WIDTH 1
+#define	FRF_AB_XM_RXEN_LBN 1
+#define	FRF_AB_XM_RXEN_WIDTH 1
+#define	FRF_AB_XM_RX_RST_LBN 0
+#define	FRF_AB_XM_RX_RST_WIDTH 1
+
+/* XM_MGT_INT_MASK: documentation to be written for sum_XM_MGT_INT_MASK */
+#define	FR_AB_XM_MGT_INT_MASK 0x00001250
+#define	FRF_AB_XM_MSK_STA_INTR_LBN 16
+#define	FRF_AB_XM_MSK_STA_INTR_WIDTH 1
+#define	FRF_AB_XM_MSK_STAT_CNTR_HF_LBN 9
+#define	FRF_AB_XM_MSK_STAT_CNTR_HF_WIDTH 1
+#define	FRF_AB_XM_MSK_STAT_CNTR_OF_LBN 8
+#define	FRF_AB_XM_MSK_STAT_CNTR_OF_WIDTH 1
+#define	FRF_AB_XM_MSK_PRMBLE_ERR_LBN 2
+#define	FRF_AB_XM_MSK_PRMBLE_ERR_WIDTH 1
+#define	FRF_AB_XM_MSK_RMTFLT_LBN 1
+#define	FRF_AB_XM_MSK_RMTFLT_WIDTH 1
+#define	FRF_AB_XM_MSK_LCLFLT_LBN 0
+#define	FRF_AB_XM_MSK_LCLFLT_WIDTH 1
+
+/* XM_FC_REG: XGMAC flow control register */
+#define	FR_AB_XM_FC 0x00001270
+#define	FRF_AB_XM_PAUSE_TIME_LBN 16
+#define	FRF_AB_XM_PAUSE_TIME_WIDTH 16
+#define	FRF_AB_XM_RX_MAC_STAT_LBN 11
+#define	FRF_AB_XM_RX_MAC_STAT_WIDTH 1
+#define	FRF_AB_XM_TX_MAC_STAT_LBN 10
+#define	FRF_AB_XM_TX_MAC_STAT_WIDTH 1
+#define	FRF_AB_XM_MCNTL_PASS_LBN 8
+#define	FRF_AB_XM_MCNTL_PASS_WIDTH 2
+#define	FRF_AB_XM_REJ_CNTL_UCAST_LBN 6
+#define	FRF_AB_XM_REJ_CNTL_UCAST_WIDTH 1
+#define	FRF_AB_XM_REJ_CNTL_MCAST_LBN 5
+#define	FRF_AB_XM_REJ_CNTL_MCAST_WIDTH 1
+#define	FRF_AB_XM_ZPAUSE_LBN 2
+#define	FRF_AB_XM_ZPAUSE_WIDTH 1
+#define	FRF_AB_XM_XMIT_PAUSE_LBN 1
+#define	FRF_AB_XM_XMIT_PAUSE_WIDTH 1
+#define	FRF_AB_XM_DIS_FCNTL_LBN 0
+#define	FRF_AB_XM_DIS_FCNTL_WIDTH 1
+
+/* XM_PAUSE_TIME_REG: XGMAC pause time register */
+#define	FR_AB_XM_PAUSE_TIME 0x00001290
+#define	FRF_AB_XM_TX_PAUSE_CNT_LBN 16
+#define	FRF_AB_XM_TX_PAUSE_CNT_WIDTH 16
+#define	FRF_AB_XM_RX_PAUSE_CNT_LBN 0
+#define	FRF_AB_XM_RX_PAUSE_CNT_WIDTH 16
+
+/* XM_TX_PARAM_REG: XGMAC transmit parameter register */
+#define	FR_AB_XM_TX_PARAM 0x000012d0
+#define	FRF_AB_XM_TX_JUMBO_MODE_LBN 31
+#define	FRF_AB_XM_TX_JUMBO_MODE_WIDTH 1
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_HI_LBN 19
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_HI_WIDTH 11
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_LO_LBN 16
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_LO_WIDTH 3
+#define	FRF_AB_XM_PAD_CHAR_LBN 0
+#define	FRF_AB_XM_PAD_CHAR_WIDTH 8
+
+/* XM_RX_PARAM_REG: XGMAC receive parameter register */
+#define	FR_AB_XM_RX_PARAM 0x000012e0
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_HI_LBN 3
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_HI_WIDTH 11
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_LO_LBN 0
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_LO_WIDTH 3
+
+/* XM_MGT_INT_MSK_REG: XGMAC management interrupt mask register */
+#define	FR_AB_XM_MGT_INT_MSK 0x000012f0
+#define	FRF_AB_XM_STAT_CNTR_OF_LBN 9
+#define	FRF_AB_XM_STAT_CNTR_OF_WIDTH 1
+#define	FRF_AB_XM_STAT_CNTR_HF_LBN 8
+#define	FRF_AB_XM_STAT_CNTR_HF_WIDTH 1
+#define	FRF_AB_XM_PRMBLE_ERR_LBN 2
+#define	FRF_AB_XM_PRMBLE_ERR_WIDTH 1
+#define	FRF_AB_XM_RMTFLT_LBN 1
+#define	FRF_AB_XM_RMTFLT_WIDTH 1
+#define	FRF_AB_XM_LCLFLT_LBN 0
+#define	FRF_AB_XM_LCLFLT_WIDTH 1
+
+/* XX_PWR_RST_REG: XGXS/XAUI powerdown/reset register */
+#define	FR_AB_XX_PWR_RST 0x00001300
+#define	FRF_AB_XX_PWRDND_SIG_LBN 31
+#define	FRF_AB_XX_PWRDND_SIG_WIDTH 1
+#define	FRF_AB_XX_PWRDNC_SIG_LBN 30
+#define	FRF_AB_XX_PWRDNC_SIG_WIDTH 1
+#define	FRF_AB_XX_PWRDNB_SIG_LBN 29
+#define	FRF_AB_XX_PWRDNB_SIG_WIDTH 1
+#define	FRF_AB_XX_PWRDNA_SIG_LBN 28
+#define	FRF_AB_XX_PWRDNA_SIG_WIDTH 1
+#define	FRF_AB_XX_SIM_MODE_LBN 27
+#define	FRF_AB_XX_SIM_MODE_WIDTH 1
+#define	FRF_AB_XX_RSTPLLCD_SIG_LBN 25
+#define	FRF_AB_XX_RSTPLLCD_SIG_WIDTH 1
+#define	FRF_AB_XX_RSTPLLAB_SIG_LBN 24
+#define	FRF_AB_XX_RSTPLLAB_SIG_WIDTH 1
+#define	FRF_AB_XX_RESETD_SIG_LBN 23
+#define	FRF_AB_XX_RESETD_SIG_WIDTH 1
+#define	FRF_AB_XX_RESETC_SIG_LBN 22
+#define	FRF_AB_XX_RESETC_SIG_WIDTH 1
+#define	FRF_AB_XX_RESETB_SIG_LBN 21
+#define	FRF_AB_XX_RESETB_SIG_WIDTH 1
+#define	FRF_AB_XX_RESETA_SIG_LBN 20
+#define	FRF_AB_XX_RESETA_SIG_WIDTH 1
+#define	FRF_AB_XX_RSTXGXSRX_SIG_LBN 18
+#define	FRF_AB_XX_RSTXGXSRX_SIG_WIDTH 1
+#define	FRF_AB_XX_RSTXGXSTX_SIG_LBN 17
+#define	FRF_AB_XX_RSTXGXSTX_SIG_WIDTH 1
+#define	FRF_AB_XX_SD_RST_ACT_LBN 16
+#define	FRF_AB_XX_SD_RST_ACT_WIDTH 1
+#define	FRF_AB_XX_PWRDND_EN_LBN 15
+#define	FRF_AB_XX_PWRDND_EN_WIDTH 1
+#define	FRF_AB_XX_PWRDNC_EN_LBN 14
+#define	FRF_AB_XX_PWRDNC_EN_WIDTH 1
+#define	FRF_AB_XX_PWRDNB_EN_LBN 13
+#define	FRF_AB_XX_PWRDNB_EN_WIDTH 1
+#define	FRF_AB_XX_PWRDNA_EN_LBN 12
+#define	FRF_AB_XX_PWRDNA_EN_WIDTH 1
+#define	FRF_AB_XX_RSTPLLCD_EN_LBN 9
+#define	FRF_AB_XX_RSTPLLCD_EN_WIDTH 1
+#define	FRF_AB_XX_RSTPLLAB_EN_LBN 8
+#define	FRF_AB_XX_RSTPLLAB_EN_WIDTH 1
+#define	FRF_AB_XX_RESETD_EN_LBN 7
+#define	FRF_AB_XX_RESETD_EN_WIDTH 1
+#define	FRF_AB_XX_RESETC_EN_LBN 6
+#define	FRF_AB_XX_RESETC_EN_WIDTH 1
+#define	FRF_AB_XX_RESETB_EN_LBN 5
+#define	FRF_AB_XX_RESETB_EN_WIDTH 1
+#define	FRF_AB_XX_RESETA_EN_LBN 4
+#define	FRF_AB_XX_RESETA_EN_WIDTH 1
+#define	FRF_AB_XX_RSTXGXSRX_EN_LBN 2
+#define	FRF_AB_XX_RSTXGXSRX_EN_WIDTH 1
+#define	FRF_AB_XX_RSTXGXSTX_EN_LBN 1
+#define	FRF_AB_XX_RSTXGXSTX_EN_WIDTH 1
+#define	FRF_AB_XX_RST_XX_EN_LBN 0
+#define	FRF_AB_XX_RST_XX_EN_WIDTH 1
+
+/* XX_SD_CTL_REG: XGXS/XAUI powerdown/reset control register */
+#define	FR_AB_XX_SD_CTL 0x00001310
+#define	FRF_AB_XX_TERMADJ1_LBN 17
+#define	FRF_AB_XX_TERMADJ1_WIDTH 1
+#define	FRF_AB_XX_TERMADJ0_LBN 16
+#define	FRF_AB_XX_TERMADJ0_WIDTH 1
+#define	FRF_AB_XX_HIDRVD_LBN 15
+#define	FRF_AB_XX_HIDRVD_WIDTH 1
+#define	FRF_AB_XX_LODRVD_LBN 14
+#define	FRF_AB_XX_LODRVD_WIDTH 1
+#define	FRF_AB_XX_HIDRVC_LBN 13
+#define	FRF_AB_XX_HIDRVC_WIDTH 1
+#define	FRF_AB_XX_LODRVC_LBN 12
+#define	FRF_AB_XX_LODRVC_WIDTH 1
+#define	FRF_AB_XX_HIDRVB_LBN 11
+#define	FRF_AB_XX_HIDRVB_WIDTH 1
+#define	FRF_AB_XX_LODRVB_LBN 10
+#define	FRF_AB_XX_LODRVB_WIDTH 1
+#define	FRF_AB_XX_HIDRVA_LBN 9
+#define	FRF_AB_XX_HIDRVA_WIDTH 1
+#define	FRF_AB_XX_LODRVA_LBN 8
+#define	FRF_AB_XX_LODRVA_WIDTH 1
+#define	FRF_AB_XX_LPBKD_LBN 3
+#define	FRF_AB_XX_LPBKD_WIDTH 1
+#define	FRF_AB_XX_LPBKC_LBN 2
+#define	FRF_AB_XX_LPBKC_WIDTH 1
+#define	FRF_AB_XX_LPBKB_LBN 1
+#define	FRF_AB_XX_LPBKB_WIDTH 1
+#define	FRF_AB_XX_LPBKA_LBN 0
+#define	FRF_AB_XX_LPBKA_WIDTH 1
+
+/* XX_TXDRV_CTL_REG: XAUI SerDes transmit drive control register */
+#define	FR_AB_XX_TXDRV_CTL 0x00001320
+#define	FRF_AB_XX_DEQD_LBN 28
+#define	FRF_AB_XX_DEQD_WIDTH 4
+#define	FRF_AB_XX_DEQC_LBN 24
+#define	FRF_AB_XX_DEQC_WIDTH 4
+#define	FRF_AB_XX_DEQB_LBN 20
+#define	FRF_AB_XX_DEQB_WIDTH 4
+#define	FRF_AB_XX_DEQA_LBN 16
+#define	FRF_AB_XX_DEQA_WIDTH 4
+#define	FRF_AB_XX_DTXD_LBN 12
+#define	FRF_AB_XX_DTXD_WIDTH 4
+#define	FRF_AB_XX_DTXC_LBN 8
+#define	FRF_AB_XX_DTXC_WIDTH 4
+#define	FRF_AB_XX_DTXB_LBN 4
+#define	FRF_AB_XX_DTXB_WIDTH 4
+#define	FRF_AB_XX_DTXA_LBN 0
+#define	FRF_AB_XX_DTXA_WIDTH 4
+
+/* XX_PRBS_CTL_REG: documentation to be written for sum_XX_PRBS_CTL_REG */
+#define	FR_AB_XX_PRBS_CTL 0x00001330
+#define	FRF_AB_XX_CH3_RX_PRBS_SEL_LBN 30
+#define	FRF_AB_XX_CH3_RX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH3_RX_PRBS_INV_LBN 29
+#define	FRF_AB_XX_CH3_RX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH3_RX_PRBS_CHKEN_LBN 28
+#define	FRF_AB_XX_CH3_RX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH2_RX_PRBS_SEL_LBN 26
+#define	FRF_AB_XX_CH2_RX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH2_RX_PRBS_INV_LBN 25
+#define	FRF_AB_XX_CH2_RX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH2_RX_PRBS_CHKEN_LBN 24
+#define	FRF_AB_XX_CH2_RX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH1_RX_PRBS_SEL_LBN 22
+#define	FRF_AB_XX_CH1_RX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH1_RX_PRBS_INV_LBN 21
+#define	FRF_AB_XX_CH1_RX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH1_RX_PRBS_CHKEN_LBN 20
+#define	FRF_AB_XX_CH1_RX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH0_RX_PRBS_SEL_LBN 18
+#define	FRF_AB_XX_CH0_RX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH0_RX_PRBS_INV_LBN 17
+#define	FRF_AB_XX_CH0_RX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH0_RX_PRBS_CHKEN_LBN 16
+#define	FRF_AB_XX_CH0_RX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH3_TX_PRBS_SEL_LBN 14
+#define	FRF_AB_XX_CH3_TX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH3_TX_PRBS_INV_LBN 13
+#define	FRF_AB_XX_CH3_TX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH3_TX_PRBS_CHKEN_LBN 12
+#define	FRF_AB_XX_CH3_TX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH2_TX_PRBS_SEL_LBN 10
+#define	FRF_AB_XX_CH2_TX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH2_TX_PRBS_INV_LBN 9
+#define	FRF_AB_XX_CH2_TX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH2_TX_PRBS_CHKEN_LBN 8
+#define	FRF_AB_XX_CH2_TX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH1_TX_PRBS_SEL_LBN 6
+#define	FRF_AB_XX_CH1_TX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH1_TX_PRBS_INV_LBN 5
+#define	FRF_AB_XX_CH1_TX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH1_TX_PRBS_CHKEN_LBN 4
+#define	FRF_AB_XX_CH1_TX_PRBS_CHKEN_WIDTH 1
+#define	FRF_AB_XX_CH0_TX_PRBS_SEL_LBN 2
+#define	FRF_AB_XX_CH0_TX_PRBS_SEL_WIDTH 2
+#define	FRF_AB_XX_CH0_TX_PRBS_INV_LBN 1
+#define	FRF_AB_XX_CH0_TX_PRBS_INV_WIDTH 1
+#define	FRF_AB_XX_CH0_TX_PRBS_CHKEN_LBN 0
+#define	FRF_AB_XX_CH0_TX_PRBS_CHKEN_WIDTH 1
+
+/* XX_PRBS_CHK_REG: documentation to be written for sum_XX_PRBS_CHK_REG */
+#define	FR_AB_XX_PRBS_CHK 0x00001340
+#define	FRF_AB_XX_REV_LB_EN_LBN 16
+#define	FRF_AB_XX_REV_LB_EN_WIDTH 1
+#define	FRF_AB_XX_CH3_DEG_DET_LBN 15
+#define	FRF_AB_XX_CH3_DEG_DET_WIDTH 1
+#define	FRF_AB_XX_CH3_LFSR_LOCK_IND_LBN 14
+#define	FRF_AB_XX_CH3_LFSR_LOCK_IND_WIDTH 1
+#define	FRF_AB_XX_CH3_PRBS_FRUN_LBN 13
+#define	FRF_AB_XX_CH3_PRBS_FRUN_WIDTH 1
+#define	FRF_AB_XX_CH3_ERR_CHK_LBN 12
+#define	FRF_AB_XX_CH3_ERR_CHK_WIDTH 1
+#define	FRF_AB_XX_CH2_DEG_DET_LBN 11
+#define	FRF_AB_XX_CH2_DEG_DET_WIDTH 1
+#define	FRF_AB_XX_CH2_LFSR_LOCK_IND_LBN 10
+#define	FRF_AB_XX_CH2_LFSR_LOCK_IND_WIDTH 1
+#define	FRF_AB_XX_CH2_PRBS_FRUN_LBN 9
+#define	FRF_AB_XX_CH2_PRBS_FRUN_WIDTH 1
+#define	FRF_AB_XX_CH2_ERR_CHK_LBN 8
+#define	FRF_AB_XX_CH2_ERR_CHK_WIDTH 1
+#define	FRF_AB_XX_CH1_DEG_DET_LBN 7
+#define	FRF_AB_XX_CH1_DEG_DET_WIDTH 1
+#define	FRF_AB_XX_CH1_LFSR_LOCK_IND_LBN 6
+#define	FRF_AB_XX_CH1_LFSR_LOCK_IND_WIDTH 1
+#define	FRF_AB_XX_CH1_PRBS_FRUN_LBN 5
+#define	FRF_AB_XX_CH1_PRBS_FRUN_WIDTH 1
+#define	FRF_AB_XX_CH1_ERR_CHK_LBN 4
+#define	FRF_AB_XX_CH1_ERR_CHK_WIDTH 1
+#define	FRF_AB_XX_CH0_DEG_DET_LBN 3
+#define	FRF_AB_XX_CH0_DEG_DET_WIDTH 1
+#define	FRF_AB_XX_CH0_LFSR_LOCK_IND_LBN 2
+#define	FRF_AB_XX_CH0_LFSR_LOCK_IND_WIDTH 1
+#define	FRF_AB_XX_CH0_PRBS_FRUN_LBN 1
+#define	FRF_AB_XX_CH0_PRBS_FRUN_WIDTH 1
+#define	FRF_AB_XX_CH0_ERR_CHK_LBN 0
+#define	FRF_AB_XX_CH0_ERR_CHK_WIDTH 1
+
+/* XX_PRBS_ERR_REG: documentation to be written for sum_XX_PRBS_ERR_REG */
+#define	FR_AB_XX_PRBS_ERR 0x00001350
+#define	FRF_AB_XX_CH3_PRBS_ERR_CNT_LBN 24
+#define	FRF_AB_XX_CH3_PRBS_ERR_CNT_WIDTH 8
+#define	FRF_AB_XX_CH2_PRBS_ERR_CNT_LBN 16
+#define	FRF_AB_XX_CH2_PRBS_ERR_CNT_WIDTH 8
+#define	FRF_AB_XX_CH1_PRBS_ERR_CNT_LBN 8
+#define	FRF_AB_XX_CH1_PRBS_ERR_CNT_WIDTH 8
+#define	FRF_AB_XX_CH0_PRBS_ERR_CNT_LBN 0
+#define	FRF_AB_XX_CH0_PRBS_ERR_CNT_WIDTH 8
+
+/* XX_CORE_STAT_REG: XAUI XGXS core status register */
+#define	FR_AB_XX_CORE_STAT 0x00001360
+#define	FRF_AB_XX_FORCE_SIG3_LBN 31
+#define	FRF_AB_XX_FORCE_SIG3_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG3_VAL_LBN 30
+#define	FRF_AB_XX_FORCE_SIG3_VAL_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG2_LBN 29
+#define	FRF_AB_XX_FORCE_SIG2_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG2_VAL_LBN 28
+#define	FRF_AB_XX_FORCE_SIG2_VAL_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG1_LBN 27
+#define	FRF_AB_XX_FORCE_SIG1_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG1_VAL_LBN 26
+#define	FRF_AB_XX_FORCE_SIG1_VAL_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG0_LBN 25
+#define	FRF_AB_XX_FORCE_SIG0_WIDTH 1
+#define	FRF_AB_XX_FORCE_SIG0_VAL_LBN 24
+#define	FRF_AB_XX_FORCE_SIG0_VAL_WIDTH 1
+#define	FRF_AB_XX_XGXS_LB_EN_LBN 23
+#define	FRF_AB_XX_XGXS_LB_EN_WIDTH 1
+#define	FRF_AB_XX_XGMII_LB_EN_LBN 22
+#define	FRF_AB_XX_XGMII_LB_EN_WIDTH 1
+#define	FRF_AB_XX_MATCH_FAULT_LBN 21
+#define	FRF_AB_XX_MATCH_FAULT_WIDTH 1
+#define	FRF_AB_XX_ALIGN_DONE_LBN 20
+#define	FRF_AB_XX_ALIGN_DONE_WIDTH 1
+#define	FRF_AB_XX_SYNC_STAT3_LBN 19
+#define	FRF_AB_XX_SYNC_STAT3_WIDTH 1
+#define	FRF_AB_XX_SYNC_STAT2_LBN 18
+#define	FRF_AB_XX_SYNC_STAT2_WIDTH 1
+#define	FRF_AB_XX_SYNC_STAT1_LBN 17
+#define	FRF_AB_XX_SYNC_STAT1_WIDTH 1
+#define	FRF_AB_XX_SYNC_STAT0_LBN 16
+#define	FRF_AB_XX_SYNC_STAT0_WIDTH 1
+#define	FRF_AB_XX_COMMA_DET_CH3_LBN 15
+#define	FRF_AB_XX_COMMA_DET_CH3_WIDTH 1
+#define	FRF_AB_XX_COMMA_DET_CH2_LBN 14
+#define	FRF_AB_XX_COMMA_DET_CH2_WIDTH 1
+#define	FRF_AB_XX_COMMA_DET_CH1_LBN 13
+#define	FRF_AB_XX_COMMA_DET_CH1_WIDTH 1
+#define	FRF_AB_XX_COMMA_DET_CH0_LBN 12
+#define	FRF_AB_XX_COMMA_DET_CH0_WIDTH 1
+#define	FRF_AB_XX_CGRP_ALIGN_CH3_LBN 11
+#define	FRF_AB_XX_CGRP_ALIGN_CH3_WIDTH 1
+#define	FRF_AB_XX_CGRP_ALIGN_CH2_LBN 10
+#define	FRF_AB_XX_CGRP_ALIGN_CH2_WIDTH 1
+#define	FRF_AB_XX_CGRP_ALIGN_CH1_LBN 9
+#define	FRF_AB_XX_CGRP_ALIGN_CH1_WIDTH 1
+#define	FRF_AB_XX_CGRP_ALIGN_CH0_LBN 8
+#define	FRF_AB_XX_CGRP_ALIGN_CH0_WIDTH 1
+#define	FRF_AB_XX_CHAR_ERR_CH3_LBN 7
+#define	FRF_AB_XX_CHAR_ERR_CH3_WIDTH 1
+#define	FRF_AB_XX_CHAR_ERR_CH2_LBN 6
+#define	FRF_AB_XX_CHAR_ERR_CH2_WIDTH 1
+#define	FRF_AB_XX_CHAR_ERR_CH1_LBN 5
+#define	FRF_AB_XX_CHAR_ERR_CH1_WIDTH 1
+#define	FRF_AB_XX_CHAR_ERR_CH0_LBN 4
+#define	FRF_AB_XX_CHAR_ERR_CH0_WIDTH 1
+#define	FRF_AB_XX_DISPERR_CH3_LBN 3
+#define	FRF_AB_XX_DISPERR_CH3_WIDTH 1
+#define	FRF_AB_XX_DISPERR_CH2_LBN 2
+#define	FRF_AB_XX_DISPERR_CH2_WIDTH 1
+#define	FRF_AB_XX_DISPERR_CH1_LBN 1
+#define	FRF_AB_XX_DISPERR_CH1_WIDTH 1
+#define	FRF_AB_XX_DISPERR_CH0_LBN 0
+#define	FRF_AB_XX_DISPERR_CH0_WIDTH 1
+
+/* RX_DESC_PTR_TBL_KER: Receive descriptor pointer table */
+#define	FR_AA_RX_DESC_PTR_TBL_KER 0x00011800
+#define	FR_AA_RX_DESC_PTR_TBL_KER_STEP 16
+#define	FR_AA_RX_DESC_PTR_TBL_KER_ROWS 4
+/* RX_DESC_PTR_TBL: Receive descriptor pointer table */
+#define	FR_BZ_RX_DESC_PTR_TBL 0x00f40000
+#define	FR_BZ_RX_DESC_PTR_TBL_STEP 16
+#define	FR_BB_RX_DESC_PTR_TBL_ROWS 4096
+#define	FR_CZ_RX_DESC_PTR_TBL_ROWS 1024
+#define	FRF_CZ_RX_HDR_SPLIT_LBN 90
+#define	FRF_CZ_RX_HDR_SPLIT_WIDTH 1
+#define	FRF_AA_RX_RESET_LBN 89
+#define	FRF_AA_RX_RESET_WIDTH 1
+#define	FRF_AZ_RX_ISCSI_DDIG_EN_LBN 88
+#define	FRF_AZ_RX_ISCSI_DDIG_EN_WIDTH 1
+#define	FRF_AZ_RX_ISCSI_HDIG_EN_LBN 87
+#define	FRF_AZ_RX_ISCSI_HDIG_EN_WIDTH 1
+#define	FRF_AZ_RX_DESC_PREF_ACT_LBN 86
+#define	FRF_AZ_RX_DESC_PREF_ACT_WIDTH 1
+#define	FRF_AZ_RX_DC_HW_RPTR_LBN 80
+#define	FRF_AZ_RX_DC_HW_RPTR_WIDTH 6
+#define	FRF_AZ_RX_DESCQ_HW_RPTR_LBN 68
+#define	FRF_AZ_RX_DESCQ_HW_RPTR_WIDTH 12
+#define	FRF_AZ_RX_DESCQ_SW_WPTR_LBN 56
+#define	FRF_AZ_RX_DESCQ_SW_WPTR_WIDTH 12
+#define	FRF_AZ_RX_DESCQ_BUF_BASE_ID_LBN 36
+#define	FRF_AZ_RX_DESCQ_BUF_BASE_ID_WIDTH 20
+#define	FRF_AZ_RX_DESCQ_EVQ_ID_LBN 24
+#define	FRF_AZ_RX_DESCQ_EVQ_ID_WIDTH 12
+#define	FRF_AZ_RX_DESCQ_OWNER_ID_LBN 10
+#define	FRF_AZ_RX_DESCQ_OWNER_ID_WIDTH 14
+#define	FRF_AZ_RX_DESCQ_LABEL_LBN 5
+#define	FRF_AZ_RX_DESCQ_LABEL_WIDTH 5
+#define	FRF_AZ_RX_DESCQ_SIZE_LBN 3
+#define	FRF_AZ_RX_DESCQ_SIZE_WIDTH 2
+#define	FFE_AZ_RX_DESCQ_SIZE_4K 3
+#define	FFE_AZ_RX_DESCQ_SIZE_2K 2
+#define	FFE_AZ_RX_DESCQ_SIZE_1K 1
+#define	FFE_AZ_RX_DESCQ_SIZE_512 0
+#define	FRF_AZ_RX_DESCQ_TYPE_LBN 2
+#define	FRF_AZ_RX_DESCQ_TYPE_WIDTH 1
+#define	FRF_AZ_RX_DESCQ_JUMBO_LBN 1
+#define	FRF_AZ_RX_DESCQ_JUMBO_WIDTH 1
+#define	FRF_AZ_RX_DESCQ_EN_LBN 0
+#define	FRF_AZ_RX_DESCQ_EN_WIDTH 1
+
+/* TX_DESC_PTR_TBL_KER: Transmit descriptor pointer */
+#define	FR_AA_TX_DESC_PTR_TBL_KER 0x00011900
+#define	FR_AA_TX_DESC_PTR_TBL_KER_STEP 16
+#define	FR_AA_TX_DESC_PTR_TBL_KER_ROWS 8
+/* TX_DESC_PTR_TBL: Transmit descriptor pointer */
+#define	FR_BZ_TX_DESC_PTR_TBL 0x00f50000
+#define	FR_BZ_TX_DESC_PTR_TBL_STEP 16
+#define	FR_BB_TX_DESC_PTR_TBL_ROWS 4096
+#define	FR_CZ_TX_DESC_PTR_TBL_ROWS 1024
+#define	FRF_CZ_TX_DPT_Q_MASK_WIDTH_LBN 94
+#define	FRF_CZ_TX_DPT_Q_MASK_WIDTH_WIDTH 2
+#define	FRF_CZ_TX_DPT_ETH_FILT_EN_LBN 93
+#define	FRF_CZ_TX_DPT_ETH_FILT_EN_WIDTH 1
+#define	FRF_CZ_TX_DPT_IP_FILT_EN_LBN 92
+#define	FRF_CZ_TX_DPT_IP_FILT_EN_WIDTH 1
+#define	FRF_BZ_TX_NON_IP_DROP_DIS_LBN 91
+#define	FRF_BZ_TX_NON_IP_DROP_DIS_WIDTH 1
+#define	FRF_BZ_TX_IP_CHKSM_DIS_LBN 90
+#define	FRF_BZ_TX_IP_CHKSM_DIS_WIDTH 1
+#define	FRF_BZ_TX_TCP_CHKSM_DIS_LBN 89
+#define	FRF_BZ_TX_TCP_CHKSM_DIS_WIDTH 1
+#define	FRF_AZ_TX_DESCQ_EN_LBN 88
+#define	FRF_AZ_TX_DESCQ_EN_WIDTH 1
+#define	FRF_AZ_TX_ISCSI_DDIG_EN_LBN 87
+#define	FRF_AZ_TX_ISCSI_DDIG_EN_WIDTH 1
+#define	FRF_AZ_TX_ISCSI_HDIG_EN_LBN 86
+#define	FRF_AZ_TX_ISCSI_HDIG_EN_WIDTH 1
+#define	FRF_AZ_TX_DC_HW_RPTR_LBN 80
+#define	FRF_AZ_TX_DC_HW_RPTR_WIDTH 6
+#define	FRF_AZ_TX_DESCQ_HW_RPTR_LBN 68
+#define	FRF_AZ_TX_DESCQ_HW_RPTR_WIDTH 12
+#define	FRF_AZ_TX_DESCQ_SW_WPTR_LBN 56
+#define	FRF_AZ_TX_DESCQ_SW_WPTR_WIDTH 12
+#define	FRF_AZ_TX_DESCQ_BUF_BASE_ID_LBN 36
+#define	FRF_AZ_TX_DESCQ_BUF_BASE_ID_WIDTH 20
+#define	FRF_AZ_TX_DESCQ_EVQ_ID_LBN 24
+#define	FRF_AZ_TX_DESCQ_EVQ_ID_WIDTH 12
+#define	FRF_AZ_TX_DESCQ_OWNER_ID_LBN 10
+#define	FRF_AZ_TX_DESCQ_OWNER_ID_WIDTH 14
+#define	FRF_AZ_TX_DESCQ_LABEL_LBN 5
+#define	FRF_AZ_TX_DESCQ_LABEL_WIDTH 5
+#define	FRF_AZ_TX_DESCQ_SIZE_LBN 3
+#define	FRF_AZ_TX_DESCQ_SIZE_WIDTH 2
+#define	FFE_AZ_TX_DESCQ_SIZE_4K 3
+#define	FFE_AZ_TX_DESCQ_SIZE_2K 2
+#define	FFE_AZ_TX_DESCQ_SIZE_1K 1
+#define	FFE_AZ_TX_DESCQ_SIZE_512 0
+#define	FRF_AZ_TX_DESCQ_TYPE_LBN 1
+#define	FRF_AZ_TX_DESCQ_TYPE_WIDTH 2
+#define	FRF_AZ_TX_DESCQ_FLUSH_LBN 0
+#define	FRF_AZ_TX_DESCQ_FLUSH_WIDTH 1
+
+/* EVQ_PTR_TBL_KER: Event queue pointer table */
+#define	FR_AA_EVQ_PTR_TBL_KER 0x00011a00
+#define	FR_AA_EVQ_PTR_TBL_KER_STEP 16
+#define	FR_AA_EVQ_PTR_TBL_KER_ROWS 4
+/* EVQ_PTR_TBL: Event queue pointer table */
+#define	FR_BZ_EVQ_PTR_TBL 0x00f60000
+#define	FR_BZ_EVQ_PTR_TBL_STEP 16
+#define	FR_CZ_EVQ_PTR_TBL_ROWS 1024
+#define	FR_BB_EVQ_PTR_TBL_ROWS 4096
+#define	FRF_BZ_EVQ_RPTR_IGN_LBN 40
+#define	FRF_BZ_EVQ_RPTR_IGN_WIDTH 1
+#define	FRF_AB_EVQ_WKUP_OR_INT_EN_LBN 39
+#define	FRF_AB_EVQ_WKUP_OR_INT_EN_WIDTH 1
+#define	FRF_CZ_EVQ_DOS_PROTECT_EN_LBN 39
+#define	FRF_CZ_EVQ_DOS_PROTECT_EN_WIDTH 1
+#define	FRF_AZ_EVQ_NXT_WPTR_LBN 24
+#define	FRF_AZ_EVQ_NXT_WPTR_WIDTH 15
+#define	FRF_AZ_EVQ_EN_LBN 23
+#define	FRF_AZ_EVQ_EN_WIDTH 1
+#define	FRF_AZ_EVQ_SIZE_LBN 20
+#define	FRF_AZ_EVQ_SIZE_WIDTH 3
+#define	FFE_AZ_EVQ_SIZE_32K 6
+#define	FFE_AZ_EVQ_SIZE_16K 5
+#define	FFE_AZ_EVQ_SIZE_8K 4
+#define	FFE_AZ_EVQ_SIZE_4K 3
+#define	FFE_AZ_EVQ_SIZE_2K 2
+#define	FFE_AZ_EVQ_SIZE_1K 1
+#define	FFE_AZ_EVQ_SIZE_512 0
+#define	FRF_AZ_EVQ_BUF_BASE_ID_LBN 0
+#define	FRF_AZ_EVQ_BUF_BASE_ID_WIDTH 20
+
+/* BUF_HALF_TBL_KER: Buffer table in half buffer table mode direct access by driver */
+#define	FR_AA_BUF_HALF_TBL_KER 0x00018000
+#define	FR_AA_BUF_HALF_TBL_KER_STEP 8
+#define	FR_AA_BUF_HALF_TBL_KER_ROWS 4096
+/* BUF_HALF_TBL: Buffer table in half buffer table mode direct access by driver */
+#define	FR_BZ_BUF_HALF_TBL 0x00800000
+#define	FR_BZ_BUF_HALF_TBL_STEP 8
+#define	FR_CZ_BUF_HALF_TBL_ROWS 147456
+#define	FR_BB_BUF_HALF_TBL_ROWS 524288
+#define	FRF_AZ_BUF_ADR_HBUF_ODD_LBN 44
+#define	FRF_AZ_BUF_ADR_HBUF_ODD_WIDTH 20
+#define	FRF_AZ_BUF_OWNER_ID_HBUF_ODD_LBN 32
+#define	FRF_AZ_BUF_OWNER_ID_HBUF_ODD_WIDTH 12
+#define	FRF_AZ_BUF_ADR_HBUF_EVEN_LBN 12
+#define	FRF_AZ_BUF_ADR_HBUF_EVEN_WIDTH 20
+#define	FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_LBN 0
+#define	FRF_AZ_BUF_OWNER_ID_HBUF_EVEN_WIDTH 12
+
+/* BUF_FULL_TBL_KER: Buffer table in full buffer table mode direct access by driver */
+#define	FR_AA_BUF_FULL_TBL_KER 0x00018000
+#define	FR_AA_BUF_FULL_TBL_KER_STEP 8
+#define	FR_AA_BUF_FULL_TBL_KER_ROWS 4096
+/* BUF_FULL_TBL: Buffer table in full buffer table mode direct access by driver */
+#define	FR_BZ_BUF_FULL_TBL 0x00800000
+#define	FR_BZ_BUF_FULL_TBL_STEP 8
+#define	FR_CZ_BUF_FULL_TBL_ROWS 147456
+#define	FR_BB_BUF_FULL_TBL_ROWS 917504
+#define	FRF_AZ_BUF_FULL_UNUSED_LBN 51
+#define	FRF_AZ_BUF_FULL_UNUSED_WIDTH 13
+#define	FRF_AZ_IP_DAT_BUF_SIZE_LBN 50
+#define	FRF_AZ_IP_DAT_BUF_SIZE_WIDTH 1
+#define	FRF_AZ_BUF_ADR_REGION_LBN 48
+#define	FRF_AZ_BUF_ADR_REGION_WIDTH 2
+#define	FFE_AZ_BUF_ADR_REGN3 3
+#define	FFE_AZ_BUF_ADR_REGN2 2
+#define	FFE_AZ_BUF_ADR_REGN1 1
+#define	FFE_AZ_BUF_ADR_REGN0 0
+#define	FRF_AZ_BUF_ADR_FBUF_LBN 14
+#define	FRF_AZ_BUF_ADR_FBUF_WIDTH 34
+#define	FRF_AZ_BUF_OWNER_ID_FBUF_LBN 0
+#define	FRF_AZ_BUF_OWNER_ID_FBUF_WIDTH 14
+
+/* RX_FILTER_TBL0: TCP/IPv4 Receive filter table */
+#define	FR_BZ_RX_FILTER_TBL0 0x00f00000
+#define	FR_BZ_RX_FILTER_TBL0_STEP 32
+#define	FR_BZ_RX_FILTER_TBL0_ROWS 8192
+/* RX_FILTER_TBL1: TCP/IPv4 Receive filter table */
+#define	FR_BB_RX_FILTER_TBL1 0x00f00010
+#define	FR_BB_RX_FILTER_TBL1_STEP 32
+#define	FR_BB_RX_FILTER_TBL1_ROWS 8192
+#define	FRF_BZ_RSS_EN_LBN 110
+#define	FRF_BZ_RSS_EN_WIDTH 1
+#define	FRF_BZ_SCATTER_EN_LBN 109
+#define	FRF_BZ_SCATTER_EN_WIDTH 1
+#define	FRF_BZ_TCP_UDP_LBN 108
+#define	FRF_BZ_TCP_UDP_WIDTH 1
+#define	FRF_BZ_RXQ_ID_LBN 96
+#define	FRF_BZ_RXQ_ID_WIDTH 12
+#define	FRF_BZ_DEST_IP_LBN 64
+#define	FRF_BZ_DEST_IP_WIDTH 32
+#define	FRF_BZ_DEST_PORT_TCP_LBN 48
+#define	FRF_BZ_DEST_PORT_TCP_WIDTH 16
+#define	FRF_BZ_SRC_IP_LBN 16
+#define	FRF_BZ_SRC_IP_WIDTH 32
+#define	FRF_BZ_SRC_TCP_DEST_UDP_LBN 0
+#define	FRF_BZ_SRC_TCP_DEST_UDP_WIDTH 16
+
+/* RX_MAC_FILTER_TBL0: Receive Ethernet filter table */
+#define	FR_CZ_RX_MAC_FILTER_TBL0 0x00f00010
+#define	FR_CZ_RX_MAC_FILTER_TBL0_STEP 32
+#define	FR_CZ_RX_MAC_FILTER_TBL0_ROWS 512
+#define	FRF_CZ_RMFT_RSS_EN_LBN 75
+#define	FRF_CZ_RMFT_RSS_EN_WIDTH 1
+#define	FRF_CZ_RMFT_SCATTER_EN_LBN 74
+#define	FRF_CZ_RMFT_SCATTER_EN_WIDTH 1
+#define	FRF_CZ_RMFT_IP_OVERRIDE_LBN 73
+#define	FRF_CZ_RMFT_IP_OVERRIDE_WIDTH 1
+#define	FRF_CZ_RMFT_RXQ_ID_LBN 61
+#define	FRF_CZ_RMFT_RXQ_ID_WIDTH 12
+#define	FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60
+#define	FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1
+#define	FRF_CZ_RMFT_DEST_MAC_LBN 16
+#define	FRF_CZ_RMFT_DEST_MAC_WIDTH 44
+#define	FRF_CZ_RMFT_VLAN_ID_LBN 0
+#define	FRF_CZ_RMFT_VLAN_ID_WIDTH 12
+
+/* TIMER_TBL: Timer table */
+#define	FR_BZ_TIMER_TBL 0x00f70000
+#define	FR_BZ_TIMER_TBL_STEP 16
+#define	FR_CZ_TIMER_TBL_ROWS 1024
+#define	FR_BB_TIMER_TBL_ROWS 4096
+#define	FRF_CZ_TIMER_Q_EN_LBN 33
+#define	FRF_CZ_TIMER_Q_EN_WIDTH 1
+#define	FRF_CZ_INT_ARMD_LBN 32
+#define	FRF_CZ_INT_ARMD_WIDTH 1
+#define	FRF_CZ_INT_PEND_LBN 31
+#define	FRF_CZ_INT_PEND_WIDTH 1
+#define	FRF_CZ_HOST_NOTIFY_MODE_LBN 30
+#define	FRF_CZ_HOST_NOTIFY_MODE_WIDTH 1
+#define	FRF_CZ_RELOAD_TIMER_VAL_LBN 16
+#define	FRF_CZ_RELOAD_TIMER_VAL_WIDTH 14
+#define	FRF_CZ_TIMER_MODE_LBN 14
+#define	FRF_CZ_TIMER_MODE_WIDTH 2
+#define	FFE_CZ_TIMER_MODE_INT_HLDOFF 3
+#define	FFE_CZ_TIMER_MODE_TRIG_START 2
+#define	FFE_CZ_TIMER_MODE_IMMED_START 1
+#define	FFE_CZ_TIMER_MODE_DIS 0
+#define	FRF_BB_TIMER_MODE_LBN 12
+#define	FRF_BB_TIMER_MODE_WIDTH 2
+#define	FFE_BB_TIMER_MODE_INT_HLDOFF 2
+#define	FFE_BB_TIMER_MODE_TRIG_START 2
+#define	FFE_BB_TIMER_MODE_IMMED_START 1
+#define	FFE_BB_TIMER_MODE_DIS 0
+#define	FRF_CZ_TIMER_VAL_LBN 0
+#define	FRF_CZ_TIMER_VAL_WIDTH 14
+#define	FRF_BB_TIMER_VAL_LBN 0
+#define	FRF_BB_TIMER_VAL_WIDTH 12
+
+/* TX_PACE_TBL: Transmit pacing table */
+#define	FR_BZ_TX_PACE_TBL 0x00f80000
+#define	FR_BZ_TX_PACE_TBL_STEP 16
+#define	FR_CZ_TX_PACE_TBL_ROWS 1024
+#define	FR_BB_TX_PACE_TBL_ROWS 4096
+#define	FRF_BZ_TX_PACE_LBN 0
+#define	FRF_BZ_TX_PACE_WIDTH 5
+
+/* RX_INDIRECTION_TBL: RX Indirection Table */
+#define	FR_BZ_RX_INDIRECTION_TBL 0x00fb0000
+#define	FR_BZ_RX_INDIRECTION_TBL_STEP 16
+#define	FR_BZ_RX_INDIRECTION_TBL_ROWS 128
+#define	FRF_BZ_IT_QUEUE_LBN 0
+#define	FRF_BZ_IT_QUEUE_WIDTH 6
+
+/* TX_FILTER_TBL0: TCP/IPv4 Transmit filter table */
+#define	FR_CZ_TX_FILTER_TBL0 0x00fc0000
+#define	FR_CZ_TX_FILTER_TBL0_STEP 16
+#define	FR_CZ_TX_FILTER_TBL0_ROWS 8192
+#define	FRF_CZ_TIFT_TCP_UDP_LBN 108
+#define	FRF_CZ_TIFT_TCP_UDP_WIDTH 1
+#define	FRF_CZ_TIFT_TXQ_ID_LBN 96
+#define	FRF_CZ_TIFT_TXQ_ID_WIDTH 12
+#define	FRF_CZ_TIFT_DEST_IP_LBN 64
+#define	FRF_CZ_TIFT_DEST_IP_WIDTH 32
+#define	FRF_CZ_TIFT_DEST_PORT_TCP_LBN 48
+#define	FRF_CZ_TIFT_DEST_PORT_TCP_WIDTH 16
+#define	FRF_CZ_TIFT_SRC_IP_LBN 16
+#define	FRF_CZ_TIFT_SRC_IP_WIDTH 32
+#define	FRF_CZ_TIFT_SRC_TCP_DEST_UDP_LBN 0
+#define	FRF_CZ_TIFT_SRC_TCP_DEST_UDP_WIDTH 16
+
+/* TX_MAC_FILTER_TBL0: Transmit Ethernet filter table */
+#define	FR_CZ_TX_MAC_FILTER_TBL0 0x00fe0000
+#define	FR_CZ_TX_MAC_FILTER_TBL0_STEP 16
+#define	FR_CZ_TX_MAC_FILTER_TBL0_ROWS 512
+#define	FRF_CZ_TMFT_TXQ_ID_LBN 61
+#define	FRF_CZ_TMFT_TXQ_ID_WIDTH 12
+#define	FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60
+#define	FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1
+#define	FRF_CZ_TMFT_SRC_MAC_LBN 16
+#define	FRF_CZ_TMFT_SRC_MAC_WIDTH 44
+#define	FRF_CZ_TMFT_VLAN_ID_LBN 0
+#define	FRF_CZ_TMFT_VLAN_ID_WIDTH 12
+
+/* MC_TREG_SMEM: MC Shared Memory */
+#define	FR_CZ_MC_TREG_SMEM 0x00ff0000
+#define	FR_CZ_MC_TREG_SMEM_STEP 4
+#define	FR_CZ_MC_TREG_SMEM_ROWS 512
+#define	FRF_CZ_MC_TREG_SMEM_ROW_LBN 0
+#define	FRF_CZ_MC_TREG_SMEM_ROW_WIDTH 32
+
+/* MSIX_VECTOR_TABLE: MSIX Vector Table */
+#define	FR_BB_MSIX_VECTOR_TABLE 0x00ff0000
+#define	FR_BZ_MSIX_VECTOR_TABLE_STEP 16
+#define	FR_BB_MSIX_VECTOR_TABLE_ROWS 64
+/* MSIX_VECTOR_TABLE: MSIX Vector Table */
+#define	FR_CZ_MSIX_VECTOR_TABLE 0x00000000
+/* FR_BZ_MSIX_VECTOR_TABLE_STEP 16 */
+#define	FR_CZ_MSIX_VECTOR_TABLE_ROWS 1024
+#define	FRF_BZ_MSIX_VECTOR_RESERVED_LBN 97
+#define	FRF_BZ_MSIX_VECTOR_RESERVED_WIDTH 31
+#define	FRF_BZ_MSIX_VECTOR_MASK_LBN 96
+#define	FRF_BZ_MSIX_VECTOR_MASK_WIDTH 1
+#define	FRF_BZ_MSIX_MESSAGE_DATA_LBN 64
+#define	FRF_BZ_MSIX_MESSAGE_DATA_WIDTH 32
+#define	FRF_BZ_MSIX_MESSAGE_ADDRESS_HI_LBN 32
+#define	FRF_BZ_MSIX_MESSAGE_ADDRESS_HI_WIDTH 32
+#define	FRF_BZ_MSIX_MESSAGE_ADDRESS_LO_LBN 0
+#define	FRF_BZ_MSIX_MESSAGE_ADDRESS_LO_WIDTH 32
+
+/* MSIX_PBA_TABLE: MSIX Pending Bit Array */
+#define	FR_BB_MSIX_PBA_TABLE 0x00ff2000
+#define	FR_BZ_MSIX_PBA_TABLE_STEP 4
+#define	FR_BB_MSIX_PBA_TABLE_ROWS 2
+/* MSIX_PBA_TABLE: MSIX Pending Bit Array */
+#define	FR_CZ_MSIX_PBA_TABLE 0x00008000
+/* FR_BZ_MSIX_PBA_TABLE_STEP 4 */
+#define	FR_CZ_MSIX_PBA_TABLE_ROWS 32
+#define	FRF_BZ_MSIX_PBA_PEND_DWORD_LBN 0
+#define	FRF_BZ_MSIX_PBA_PEND_DWORD_WIDTH 32
+
+/* SRM_DBG_REG: SRAM debug access */
+#define	FR_BZ_SRM_DBG 0x03000000
+#define	FR_BZ_SRM_DBG_STEP 8
+#define	FR_CZ_SRM_DBG_ROWS 262144
+#define	FR_BB_SRM_DBG_ROWS 2097152
+#define	FRF_BZ_SRM_DBG_LBN 0
+#define	FRF_BZ_SRM_DBG_WIDTH 64
+
+/* TB_MSIX_PBA_TABLE: MSIX Pending Bit Array */
+#define	FR_CZ_TB_MSIX_PBA_TABLE 0x00008000
+#define	FR_CZ_TB_MSIX_PBA_TABLE_STEP 4
+#define	FR_CZ_TB_MSIX_PBA_TABLE_ROWS 1024
+#define	FRF_CZ_TB_MSIX_PBA_PEND_DWORD_LBN 0
+#define	FRF_CZ_TB_MSIX_PBA_PEND_DWORD_WIDTH 32
+
+/* DRIVER_EV */
+#define	FSF_AZ_DRIVER_EV_SUBCODE_LBN 56
+#define	FSF_AZ_DRIVER_EV_SUBCODE_WIDTH 4
+#define	FSE_BZ_TX_DSC_ERROR_EV 15
+#define	FSE_BZ_RX_DSC_ERROR_EV 14
+#define	FSE_AA_RX_RECOVER_EV 11
+#define	FSE_AZ_TIMER_EV 10
+#define	FSE_AZ_TX_PKT_NON_TCP_UDP 9
+#define	FSE_AZ_WAKE_UP_EV 6
+#define	FSE_AZ_SRM_UPD_DONE_EV 5
+#define	FSE_AB_EVQ_NOT_EN_EV 3
+#define	FSE_AZ_EVQ_INIT_DONE_EV 2
+#define	FSE_AZ_RX_DESCQ_FLS_DONE_EV 1
+#define	FSE_AZ_TX_DESCQ_FLS_DONE_EV 0
+#define	FSF_AZ_DRIVER_EV_SUBDATA_LBN 0
+#define	FSF_AZ_DRIVER_EV_SUBDATA_WIDTH 14
+
+/* EVENT_ENTRY */
+#define	FSF_AZ_EV_CODE_LBN 60
+#define	FSF_AZ_EV_CODE_WIDTH 4
+#define	FSE_CZ_EV_CODE_MCDI_EV 12
+#define	FSE_CZ_EV_CODE_USER_EV 8
+#define	FSE_AZ_EV_CODE_DRV_GEN_EV 7
+#define	FSE_AZ_EV_CODE_GLOBAL_EV 6
+#define	FSE_AZ_EV_CODE_DRIVER_EV 5
+#define	FSE_AZ_EV_CODE_TX_EV 2
+#define	FSE_AZ_EV_CODE_RX_EV 0
+#define	FSF_AZ_EV_DATA_LBN 0
+#define	FSF_AZ_EV_DATA_WIDTH 60
+
+/* GLOBAL_EV */
+#define	FSF_BB_GLB_EV_RX_RECOVERY_LBN 12
+#define	FSF_BB_GLB_EV_RX_RECOVERY_WIDTH 1
+#define	FSF_AA_GLB_EV_RX_RECOVERY_LBN 11
+#define	FSF_AA_GLB_EV_RX_RECOVERY_WIDTH 1
+#define	FSF_BB_GLB_EV_XG_MGT_INTR_LBN 11
+#define	FSF_BB_GLB_EV_XG_MGT_INTR_WIDTH 1
+#define	FSF_AB_GLB_EV_XFP_PHY0_INTR_LBN 10
+#define	FSF_AB_GLB_EV_XFP_PHY0_INTR_WIDTH 1
+#define	FSF_AB_GLB_EV_XG_PHY0_INTR_LBN 9
+#define	FSF_AB_GLB_EV_XG_PHY0_INTR_WIDTH 1
+#define	FSF_AB_GLB_EV_G_PHY0_INTR_LBN 7
+#define	FSF_AB_GLB_EV_G_PHY0_INTR_WIDTH 1
+
+/* LEGACY_INT_VEC */
+#define	FSF_AZ_NET_IVEC_FATAL_INT_LBN 64
+#define	FSF_AZ_NET_IVEC_FATAL_INT_WIDTH 1
+#define	FSF_AZ_NET_IVEC_INT_Q_LBN 40
+#define	FSF_AZ_NET_IVEC_INT_Q_WIDTH 4
+#define	FSF_AZ_NET_IVEC_INT_FLAG_LBN 32
+#define	FSF_AZ_NET_IVEC_INT_FLAG_WIDTH 1
+#define	FSF_AZ_NET_IVEC_EVQ_FIFO_HF_LBN 1
+#define	FSF_AZ_NET_IVEC_EVQ_FIFO_HF_WIDTH 1
+#define	FSF_AZ_NET_IVEC_EVQ_FIFO_AF_LBN 0
+#define	FSF_AZ_NET_IVEC_EVQ_FIFO_AF_WIDTH 1
+
+/* MC_XGMAC_FLTR_RULE_DEF */
+#define	FSF_CZ_MC_XFRC_MODE_LBN 416
+#define	FSF_CZ_MC_XFRC_MODE_WIDTH 1
+#define	FSE_CZ_MC_XFRC_MODE_LAYERED 1
+#define	FSE_CZ_MC_XFRC_MODE_SIMPLE 0
+#define	FSF_CZ_MC_XFRC_HASH_LBN 384
+#define	FSF_CZ_MC_XFRC_HASH_WIDTH 32
+#define	FSF_CZ_MC_XFRC_LAYER4_BYTE_MASK_LBN 256
+#define	FSF_CZ_MC_XFRC_LAYER4_BYTE_MASK_WIDTH 128
+#define	FSF_CZ_MC_XFRC_LAYER3_BYTE_MASK_LBN 128
+#define	FSF_CZ_MC_XFRC_LAYER3_BYTE_MASK_WIDTH 128
+#define	FSF_CZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_LBN 0
+#define	FSF_CZ_MC_XFRC_LAYER2_OR_SIMPLE_BYTE_MASK_WIDTH 128
+
+/* RX_EV */
+#define	FSF_CZ_RX_EV_PKT_NOT_PARSED_LBN 58
+#define	FSF_CZ_RX_EV_PKT_NOT_PARSED_WIDTH 1
+#define	FSF_CZ_RX_EV_IPV6_PKT_LBN 57
+#define	FSF_CZ_RX_EV_IPV6_PKT_WIDTH 1
+#define	FSF_AZ_RX_EV_PKT_OK_LBN 56
+#define	FSF_AZ_RX_EV_PKT_OK_WIDTH 1
+#define	FSF_AZ_RX_EV_PAUSE_FRM_ERR_LBN 55
+#define	FSF_AZ_RX_EV_PAUSE_FRM_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_BUF_OWNER_ID_ERR_LBN 54
+#define	FSF_AZ_RX_EV_BUF_OWNER_ID_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_IP_FRAG_ERR_LBN 53
+#define	FSF_AZ_RX_EV_IP_FRAG_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR_LBN 52
+#define	FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR_LBN 51
+#define	FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_ETH_CRC_ERR_LBN 50
+#define	FSF_AZ_RX_EV_ETH_CRC_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_FRM_TRUNC_LBN 49
+#define	FSF_AZ_RX_EV_FRM_TRUNC_WIDTH 1
+#define	FSF_AA_RX_EV_DRIB_NIB_LBN 49
+#define	FSF_AA_RX_EV_DRIB_NIB_WIDTH 1
+#define	FSF_AZ_RX_EV_TOBE_DISC_LBN 47
+#define	FSF_AZ_RX_EV_TOBE_DISC_WIDTH 1
+#define	FSF_AZ_RX_EV_PKT_TYPE_LBN 44
+#define	FSF_AZ_RX_EV_PKT_TYPE_WIDTH 3
+#define	FSE_AZ_RX_EV_PKT_TYPE_VLAN_JUMBO 5
+#define	FSE_AZ_RX_EV_PKT_TYPE_VLAN_LLC 4
+#define	FSE_AZ_RX_EV_PKT_TYPE_VLAN 3
+#define	FSE_AZ_RX_EV_PKT_TYPE_JUMBO 2
+#define	FSE_AZ_RX_EV_PKT_TYPE_LLC 1
+#define	FSE_AZ_RX_EV_PKT_TYPE_ETH 0
+#define	FSF_AZ_RX_EV_HDR_TYPE_LBN 42
+#define	FSF_AZ_RX_EV_HDR_TYPE_WIDTH 2
+#define	FSE_AZ_RX_EV_HDR_TYPE_OTHER 3
+#define	FSE_AB_RX_EV_HDR_TYPE_IPV4_OTHER 2
+#define	FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_OTHER 2
+#define	FSE_AB_RX_EV_HDR_TYPE_IPV4_UDP 1
+#define	FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP 1
+#define	FSE_AB_RX_EV_HDR_TYPE_IPV4_TCP 0
+#define	FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP 0
+#define	FSF_AZ_RX_EV_DESC_Q_EMPTY_LBN 41
+#define	FSF_AZ_RX_EV_DESC_Q_EMPTY_WIDTH 1
+#define	FSF_AZ_RX_EV_MCAST_HASH_MATCH_LBN 40
+#define	FSF_AZ_RX_EV_MCAST_HASH_MATCH_WIDTH 1
+#define	FSF_AZ_RX_EV_MCAST_PKT_LBN 39
+#define	FSF_AZ_RX_EV_MCAST_PKT_WIDTH 1
+#define	FSF_AA_RX_EV_RECOVERY_FLAG_LBN 37
+#define	FSF_AA_RX_EV_RECOVERY_FLAG_WIDTH 1
+#define	FSF_AZ_RX_EV_Q_LABEL_LBN 32
+#define	FSF_AZ_RX_EV_Q_LABEL_WIDTH 5
+#define	FSF_AZ_RX_EV_JUMBO_CONT_LBN 31
+#define	FSF_AZ_RX_EV_JUMBO_CONT_WIDTH 1
+#define	FSF_AZ_RX_EV_PORT_LBN 30
+#define	FSF_AZ_RX_EV_PORT_WIDTH 1
+#define	FSF_AZ_RX_EV_BYTE_CNT_LBN 16
+#define	FSF_AZ_RX_EV_BYTE_CNT_WIDTH 14
+#define	FSF_AZ_RX_EV_SOP_LBN 15
+#define	FSF_AZ_RX_EV_SOP_WIDTH 1
+#define	FSF_AZ_RX_EV_ISCSI_PKT_OK_LBN 14
+#define	FSF_AZ_RX_EV_ISCSI_PKT_OK_WIDTH 1
+#define	FSF_AZ_RX_EV_ISCSI_DDIG_ERR_LBN 13
+#define	FSF_AZ_RX_EV_ISCSI_DDIG_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_ISCSI_HDIG_ERR_LBN 12
+#define	FSF_AZ_RX_EV_ISCSI_HDIG_ERR_WIDTH 1
+#define	FSF_AZ_RX_EV_DESC_PTR_LBN 0
+#define	FSF_AZ_RX_EV_DESC_PTR_WIDTH 12
+
+/* RX_KER_DESC */
+#define	FSF_AZ_RX_KER_BUF_SIZE_LBN 48
+#define	FSF_AZ_RX_KER_BUF_SIZE_WIDTH 14
+#define	FSF_AZ_RX_KER_BUF_REGION_LBN 46
+#define	FSF_AZ_RX_KER_BUF_REGION_WIDTH 2
+#define	FSF_AZ_RX_KER_BUF_ADDR_LBN 0
+#define	FSF_AZ_RX_KER_BUF_ADDR_WIDTH 46
+
+/* RX_USER_DESC */
+#define	FSF_AZ_RX_USER_2BYTE_OFFSET_LBN 20
+#define	FSF_AZ_RX_USER_2BYTE_OFFSET_WIDTH 12
+#define	FSF_AZ_RX_USER_BUF_ID_LBN 0
+#define	FSF_AZ_RX_USER_BUF_ID_WIDTH 20
+
+/* TX_EV */
+#define	FSF_AZ_TX_EV_PKT_ERR_LBN 38
+#define	FSF_AZ_TX_EV_PKT_ERR_WIDTH 1
+#define	FSF_AZ_TX_EV_PKT_TOO_BIG_LBN 37
+#define	FSF_AZ_TX_EV_PKT_TOO_BIG_WIDTH 1
+#define	FSF_AZ_TX_EV_Q_LABEL_LBN 32
+#define	FSF_AZ_TX_EV_Q_LABEL_WIDTH 5
+#define	FSF_AZ_TX_EV_PORT_LBN 16
+#define	FSF_AZ_TX_EV_PORT_WIDTH 1
+#define	FSF_AZ_TX_EV_WQ_FF_FULL_LBN 15
+#define	FSF_AZ_TX_EV_WQ_FF_FULL_WIDTH 1
+#define	FSF_AZ_TX_EV_BUF_OWNER_ID_ERR_LBN 14
+#define	FSF_AZ_TX_EV_BUF_OWNER_ID_ERR_WIDTH 1
+#define	FSF_AZ_TX_EV_COMP_LBN 12
+#define	FSF_AZ_TX_EV_COMP_WIDTH 1
+#define	FSF_AZ_TX_EV_DESC_PTR_LBN 0
+#define	FSF_AZ_TX_EV_DESC_PTR_WIDTH 12
+
+/* TX_KER_DESC */
+#define	FSF_AZ_TX_KER_CONT_LBN 62
+#define	FSF_AZ_TX_KER_CONT_WIDTH 1
+#define	FSF_AZ_TX_KER_BYTE_COUNT_LBN 48
+#define	FSF_AZ_TX_KER_BYTE_COUNT_WIDTH 14
+#define	FSF_AZ_TX_KER_BUF_REGION_LBN 46
+#define	FSF_AZ_TX_KER_BUF_REGION_WIDTH 2
+#define	FSF_AZ_TX_KER_BUF_ADDR_LBN 0
+#define	FSF_AZ_TX_KER_BUF_ADDR_WIDTH 46
+
+/* TX_USER_DESC */
+#define	FSF_AZ_TX_USER_SW_EV_EN_LBN 48
+#define	FSF_AZ_TX_USER_SW_EV_EN_WIDTH 1
+#define	FSF_AZ_TX_USER_CONT_LBN 46
+#define	FSF_AZ_TX_USER_CONT_WIDTH 1
+#define	FSF_AZ_TX_USER_BYTE_CNT_LBN 33
+#define	FSF_AZ_TX_USER_BYTE_CNT_WIDTH 13
+#define	FSF_AZ_TX_USER_BUF_ID_LBN 13
+#define	FSF_AZ_TX_USER_BUF_ID_WIDTH 20
+#define	FSF_AZ_TX_USER_BYTE_OFS_LBN 0
+#define	FSF_AZ_TX_USER_BYTE_OFS_WIDTH 13
+
+/* USER_EV */
+#define	FSF_CZ_USER_QID_LBN 32
+#define	FSF_CZ_USER_QID_WIDTH 10
+#define	FSF_CZ_USER_EV_REG_VALUE_LBN 0
+#define	FSF_CZ_USER_EV_REG_VALUE_WIDTH 32
+
+/**************************************************************************
+ *
+ * Falcon B0 PCIe core indirect registers
+ *
+ **************************************************************************
+ */
+
+#define FPCR_BB_PCIE_DEVICE_CTRL_STAT 0x68
+
+#define FPCR_BB_PCIE_LINK_CTRL_STAT 0x70
+
+#define FPCR_BB_ACK_RPL_TIMER 0x700
+#define FPCRF_BB_ACK_TL_LBN 0
+#define FPCRF_BB_ACK_TL_WIDTH 16
+#define FPCRF_BB_RPL_TL_LBN 16
+#define FPCRF_BB_RPL_TL_WIDTH 16
+
+#define FPCR_BB_ACK_FREQ 0x70C
+#define FPCRF_BB_ACK_FREQ_LBN 0
+#define FPCRF_BB_ACK_FREQ_WIDTH 7
+
+/**************************************************************************
+ *
+ * Pseudo-registers and fields
+ *
+ **************************************************************************
+ */
+
+/* Interrupt acknowledge work-around register (A0/A1 only) */
+#define FR_AA_WORK_AROUND_BROKEN_PCI_READS 0x0070
+
+/* EE_SPI_HCMD_REG: SPI host command register */
+/* Values for the EE_SPI_HCMD_SF_SEL register field */
+#define FFE_AB_SPI_DEVICE_EEPROM 0
+#define FFE_AB_SPI_DEVICE_FLASH 1
+
+/* NIC_STAT_REG: NIC status register */
+#define FRF_AB_STRAP_10G_LBN 2
+#define FRF_AB_STRAP_10G_WIDTH 1
+#define FRF_AA_STRAP_PCIE_LBN 0
+#define FRF_AA_STRAP_PCIE_WIDTH 1
+
+/* FATAL_INTR_REG_KER: Fatal interrupt register for Kernel */
+#define FRF_AZ_FATAL_INTR_LBN 0
+#define FRF_AZ_FATAL_INTR_WIDTH 12
+
+/* SRM_CFG_REG: SRAM configuration register */
+/* We treat the number of SRAM banks and bank size as a single field */
+#define	FRF_AZ_SRM_NB_SZ_LBN FRF_AZ_SRM_BANK_SIZE_LBN
+#define	FRF_AZ_SRM_NB_SZ_WIDTH \
+	(FRF_AZ_SRM_BANK_SIZE_WIDTH + FRF_AZ_SRM_NUM_BANK_WIDTH)
+#define FFE_AB_SRM_NB1_SZ2M 0
+#define FFE_AB_SRM_NB1_SZ4M 1
+#define FFE_AB_SRM_NB1_SZ8M 2
+#define FFE_AB_SRM_NB_SZ_DEF 3
+#define FFE_AB_SRM_NB2_SZ4M 4
+#define FFE_AB_SRM_NB2_SZ8M 5
+#define FFE_AB_SRM_NB2_SZ16M 6
+#define FFE_AB_SRM_NB_SZ_RES 7
+
+/* RX_DESC_UPD_REGP0: Receive descriptor update register. */
+/* We write just the last dword of these registers */
+#define	FR_AZ_RX_DESC_UPD_DWORD_P0 \
+	(BUILD_BUG_ON_ZERO(FR_AA_RX_DESC_UPD_KER != FR_BZ_RX_DESC_UPD_P0) + \
+	 FR_BZ_RX_DESC_UPD_P0 + 3 * 4)
+#define	FRF_AZ_RX_DESC_WPTR_DWORD_LBN (FRF_AZ_RX_DESC_WPTR_LBN - 3 * 32)
+#define	FRF_AZ_RX_DESC_WPTR_DWORD_WIDTH FRF_AZ_RX_DESC_WPTR_WIDTH
+
+/* TX_DESC_UPD_REGP0: Transmit descriptor update register. */
+#define FR_AZ_TX_DESC_UPD_DWORD_P0 \
+	(BUILD_BUG_ON_ZERO(FR_AA_TX_DESC_UPD_KER != FR_BZ_TX_DESC_UPD_P0) + \
+	 FR_BZ_TX_DESC_UPD_P0 + 3 * 4)
+#define	FRF_AZ_TX_DESC_WPTR_DWORD_LBN (FRF_AZ_TX_DESC_WPTR_LBN - 3 * 32)
+#define	FRF_AZ_TX_DESC_WPTR_DWORD_WIDTH FRF_AZ_TX_DESC_WPTR_WIDTH
+
+/* GMF_CFG4_REG: GMAC FIFO configuration register 4 */
+#define FRF_AB_GMF_HSTFLTRFRM_PAUSE_LBN 12
+#define FRF_AB_GMF_HSTFLTRFRM_PAUSE_WIDTH 1
+
+/* GMF_CFG5_REG: GMAC FIFO configuration register 5 */
+#define FRF_AB_GMF_HSTFLTRFRMDC_PAUSE_LBN 12
+#define FRF_AB_GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1
+
+/* XM_TX_PARAM_REG: XGMAC transmit parameter register */
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_LBN FRF_AB_XM_MAX_TX_FRM_SIZE_LO_LBN
+#define	FRF_AB_XM_MAX_TX_FRM_SIZE_WIDTH (FRF_AB_XM_MAX_TX_FRM_SIZE_HI_WIDTH + \
+					 FRF_AB_XM_MAX_TX_FRM_SIZE_LO_WIDTH)
+
+/* XM_RX_PARAM_REG: XGMAC receive parameter register */
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_LBN FRF_AB_XM_MAX_RX_FRM_SIZE_LO_LBN
+#define	FRF_AB_XM_MAX_RX_FRM_SIZE_WIDTH (FRF_AB_XM_MAX_RX_FRM_SIZE_HI_WIDTH + \
+					 FRF_AB_XM_MAX_RX_FRM_SIZE_LO_WIDTH)
+
+/* XX_TXDRV_CTL_REG: XAUI SerDes transmit drive control register */
+/* Default values */
+#define FFE_AB_XX_TXDRV_DEQ_DEF 0xe /* deq=.6 */
+#define FFE_AB_XX_TXDRV_DTX_DEF 0x5 /* 1.25 */
+#define FFE_AB_XX_SD_CTL_DRV_DEF 0  /* 20mA */
+
+/* XX_CORE_STAT_REG: XAUI XGXS core status register */
+/* XGXS all-lanes status fields */
+#define	FRF_AB_XX_SYNC_STAT_LBN FRF_AB_XX_SYNC_STAT0_LBN
+#define	FRF_AB_XX_SYNC_STAT_WIDTH 4
+#define	FRF_AB_XX_COMMA_DET_LBN FRF_AB_XX_COMMA_DET_CH0_LBN
+#define	FRF_AB_XX_COMMA_DET_WIDTH 4
+#define	FRF_AB_XX_CHAR_ERR_LBN FRF_AB_XX_CHAR_ERR_CH0_LBN
+#define	FRF_AB_XX_CHAR_ERR_WIDTH 4
+#define	FRF_AB_XX_DISPERR_LBN FRF_AB_XX_DISPERR_CH0_LBN
+#define	FRF_AB_XX_DISPERR_WIDTH 4
+#define	FFE_AB_XX_STAT_ALL_LANES 0xf
+#define	FRF_AB_XX_FORCE_SIG_LBN FRF_AB_XX_FORCE_SIG0_VAL_LBN
+#define	FRF_AB_XX_FORCE_SIG_WIDTH 8
+#define	FFE_AB_XX_FORCE_SIG_ALL_LANES 0xff
+
+/* DRIVER_EV */
+/* Sub-fields of an RX flush completion event */
+#define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12
+#define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_WIDTH 1
+#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_LBN 0
+#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_WIDTH 12
+
+/* EVENT_ENTRY */
+/* Magic number field for event test */
+#define FSF_AZ_DRV_GEN_EV_MAGIC_LBN 0
+#define FSF_AZ_DRV_GEN_EV_MAGIC_WIDTH 32
+
+/**************************************************************************
+ *
+ * Falcon MAC stats
+ *
+ **************************************************************************
+ *
+ */
+
+#define GRxGoodOct_offset 0x0
+#define GRxGoodOct_WIDTH 48
+#define GRxBadOct_offset 0x8
+#define GRxBadOct_WIDTH 48
+#define GRxMissPkt_offset 0x10
+#define GRxMissPkt_WIDTH 32
+#define GRxFalseCRS_offset 0x14
+#define GRxFalseCRS_WIDTH 32
+#define GRxPausePkt_offset 0x18
+#define GRxPausePkt_WIDTH 32
+#define GRxBadPkt_offset 0x1C
+#define GRxBadPkt_WIDTH 32
+#define GRxUcastPkt_offset 0x20
+#define GRxUcastPkt_WIDTH 32
+#define GRxMcastPkt_offset 0x24
+#define GRxMcastPkt_WIDTH 32
+#define GRxBcastPkt_offset 0x28
+#define GRxBcastPkt_WIDTH 32
+#define GRxGoodLt64Pkt_offset 0x2C
+#define GRxGoodLt64Pkt_WIDTH 32
+#define GRxBadLt64Pkt_offset 0x30
+#define GRxBadLt64Pkt_WIDTH 32
+#define GRx64Pkt_offset 0x34
+#define GRx64Pkt_WIDTH 32
+#define GRx65to127Pkt_offset 0x38
+#define GRx65to127Pkt_WIDTH 32
+#define GRx128to255Pkt_offset 0x3C
+#define GRx128to255Pkt_WIDTH 32
+#define GRx256to511Pkt_offset 0x40
+#define GRx256to511Pkt_WIDTH 32
+#define GRx512to1023Pkt_offset 0x44
+#define GRx512to1023Pkt_WIDTH 32
+#define GRx1024to15xxPkt_offset 0x48
+#define GRx1024to15xxPkt_WIDTH 32
+#define GRx15xxtoJumboPkt_offset 0x4C
+#define GRx15xxtoJumboPkt_WIDTH 32
+#define GRxGtJumboPkt_offset 0x50
+#define GRxGtJumboPkt_WIDTH 32
+#define GRxFcsErr64to15xxPkt_offset 0x54
+#define GRxFcsErr64to15xxPkt_WIDTH 32
+#define GRxFcsErr15xxtoJumboPkt_offset 0x58
+#define GRxFcsErr15xxtoJumboPkt_WIDTH 32
+#define GRxFcsErrGtJumboPkt_offset 0x5C
+#define GRxFcsErrGtJumboPkt_WIDTH 32
+#define GTxGoodBadOct_offset 0x80
+#define GTxGoodBadOct_WIDTH 48
+#define GTxGoodOct_offset 0x88
+#define GTxGoodOct_WIDTH 48
+#define GTxSglColPkt_offset 0x90
+#define GTxSglColPkt_WIDTH 32
+#define GTxMultColPkt_offset 0x94
+#define GTxMultColPkt_WIDTH 32
+#define GTxExColPkt_offset 0x98
+#define GTxExColPkt_WIDTH 32
+#define GTxDefPkt_offset 0x9C
+#define GTxDefPkt_WIDTH 32
+#define GTxLateCol_offset 0xA0
+#define GTxLateCol_WIDTH 32
+#define GTxExDefPkt_offset 0xA4
+#define GTxExDefPkt_WIDTH 32
+#define GTxPausePkt_offset 0xA8
+#define GTxPausePkt_WIDTH 32
+#define GTxBadPkt_offset 0xAC
+#define GTxBadPkt_WIDTH 32
+#define GTxUcastPkt_offset 0xB0
+#define GTxUcastPkt_WIDTH 32
+#define GTxMcastPkt_offset 0xB4
+#define GTxMcastPkt_WIDTH 32
+#define GTxBcastPkt_offset 0xB8
+#define GTxBcastPkt_WIDTH 32
+#define GTxLt64Pkt_offset 0xBC
+#define GTxLt64Pkt_WIDTH 32
+#define GTx64Pkt_offset 0xC0
+#define GTx64Pkt_WIDTH 32
+#define GTx65to127Pkt_offset 0xC4
+#define GTx65to127Pkt_WIDTH 32
+#define GTx128to255Pkt_offset 0xC8
+#define GTx128to255Pkt_WIDTH 32
+#define GTx256to511Pkt_offset 0xCC
+#define GTx256to511Pkt_WIDTH 32
+#define GTx512to1023Pkt_offset 0xD0
+#define GTx512to1023Pkt_WIDTH 32
+#define GTx1024to15xxPkt_offset 0xD4
+#define GTx1024to15xxPkt_WIDTH 32
+#define GTx15xxtoJumboPkt_offset 0xD8
+#define GTx15xxtoJumboPkt_WIDTH 32
+#define GTxGtJumboPkt_offset 0xDC
+#define GTxGtJumboPkt_WIDTH 32
+#define GTxNonTcpUdpPkt_offset 0xE0
+#define GTxNonTcpUdpPkt_WIDTH 16
+#define GTxMacSrcErrPkt_offset 0xE4
+#define GTxMacSrcErrPkt_WIDTH 16
+#define GTxIpSrcErrPkt_offset 0xE8
+#define GTxIpSrcErrPkt_WIDTH 16
+#define GDmaDone_offset 0xEC
+#define GDmaDone_WIDTH 32
+
+#define XgRxOctets_offset 0x0
+#define XgRxOctets_WIDTH 48
+#define XgRxOctetsOK_offset 0x8
+#define XgRxOctetsOK_WIDTH 48
+#define XgRxPkts_offset 0x10
+#define XgRxPkts_WIDTH 32
+#define XgRxPktsOK_offset 0x14
+#define XgRxPktsOK_WIDTH 32
+#define XgRxBroadcastPkts_offset 0x18
+#define XgRxBroadcastPkts_WIDTH 32
+#define XgRxMulticastPkts_offset 0x1C
+#define XgRxMulticastPkts_WIDTH 32
+#define XgRxUnicastPkts_offset 0x20
+#define XgRxUnicastPkts_WIDTH 32
+#define XgRxUndersizePkts_offset 0x24
+#define XgRxUndersizePkts_WIDTH 32
+#define XgRxOversizePkts_offset 0x28
+#define XgRxOversizePkts_WIDTH 32
+#define XgRxJabberPkts_offset 0x2C
+#define XgRxJabberPkts_WIDTH 32
+#define XgRxUndersizeFCSerrorPkts_offset 0x30
+#define XgRxUndersizeFCSerrorPkts_WIDTH 32
+#define XgRxDropEvents_offset 0x34
+#define XgRxDropEvents_WIDTH 32
+#define XgRxFCSerrorPkts_offset 0x38
+#define XgRxFCSerrorPkts_WIDTH 32
+#define XgRxAlignError_offset 0x3C
+#define XgRxAlignError_WIDTH 32
+#define XgRxSymbolError_offset 0x40
+#define XgRxSymbolError_WIDTH 32
+#define XgRxInternalMACError_offset 0x44
+#define XgRxInternalMACError_WIDTH 32
+#define XgRxControlPkts_offset 0x48
+#define XgRxControlPkts_WIDTH 32
+#define XgRxPausePkts_offset 0x4C
+#define XgRxPausePkts_WIDTH 32
+#define XgRxPkts64Octets_offset 0x50
+#define XgRxPkts64Octets_WIDTH 32
+#define XgRxPkts65to127Octets_offset 0x54
+#define XgRxPkts65to127Octets_WIDTH 32
+#define XgRxPkts128to255Octets_offset 0x58
+#define XgRxPkts128to255Octets_WIDTH 32
+#define XgRxPkts256to511Octets_offset 0x5C
+#define XgRxPkts256to511Octets_WIDTH 32
+#define XgRxPkts512to1023Octets_offset 0x60
+#define XgRxPkts512to1023Octets_WIDTH 32
+#define XgRxPkts1024to15xxOctets_offset 0x64
+#define XgRxPkts1024to15xxOctets_WIDTH 32
+#define XgRxPkts15xxtoMaxOctets_offset 0x68
+#define XgRxPkts15xxtoMaxOctets_WIDTH 32
+#define XgRxLengthError_offset 0x6C
+#define XgRxLengthError_WIDTH 32
+#define XgTxPkts_offset 0x80
+#define XgTxPkts_WIDTH 32
+#define XgTxOctets_offset 0x88
+#define XgTxOctets_WIDTH 48
+#define XgTxMulticastPkts_offset 0x90
+#define XgTxMulticastPkts_WIDTH 32
+#define XgTxBroadcastPkts_offset 0x94
+#define XgTxBroadcastPkts_WIDTH 32
+#define XgTxUnicastPkts_offset 0x98
+#define XgTxUnicastPkts_WIDTH 32
+#define XgTxControlPkts_offset 0x9C
+#define XgTxControlPkts_WIDTH 32
+#define XgTxPausePkts_offset 0xA0
+#define XgTxPausePkts_WIDTH 32
+#define XgTxPkts64Octets_offset 0xA4
+#define XgTxPkts64Octets_WIDTH 32
+#define XgTxPkts65to127Octets_offset 0xA8
+#define XgTxPkts65to127Octets_WIDTH 32
+#define XgTxPkts128to255Octets_offset 0xAC
+#define XgTxPkts128to255Octets_WIDTH 32
+#define XgTxPkts256to511Octets_offset 0xB0
+#define XgTxPkts256to511Octets_WIDTH 32
+#define XgTxPkts512to1023Octets_offset 0xB4
+#define XgTxPkts512to1023Octets_WIDTH 32
+#define XgTxPkts1024to15xxOctets_offset 0xB8
+#define XgTxPkts1024to15xxOctets_WIDTH 32
+#define XgTxPkts1519toMaxOctets_offset 0xBC
+#define XgTxPkts1519toMaxOctets_WIDTH 32
+#define XgTxUndersizePkts_offset 0xC0
+#define XgTxUndersizePkts_WIDTH 32
+#define XgTxOversizePkts_offset 0xC4
+#define XgTxOversizePkts_WIDTH 32
+#define XgTxNonTcpUdpPkt_offset 0xC8
+#define XgTxNonTcpUdpPkt_WIDTH 16
+#define XgTxMacSrcErrPkt_offset 0xCC
+#define XgTxMacSrcErrPkt_WIDTH 16
+#define XgTxIpSrcErrPkt_offset 0xD0
+#define XgTxIpSrcErrPkt_WIDTH 16
+#define XgDmaDone_offset 0xD4
+#define XgDmaDone_WIDTH 32
+
+#define FALCON_STATS_NOT_DONE 0x00000000
+#define FALCON_STATS_DONE 0xffffffff
+
+/**************************************************************************
+ *
+ * Falcon non-volatile configuration
+ *
+ **************************************************************************
+ */
+
+/* Board configuration v2 (v1 is obsolete; later versions are compatible) */
+struct falcon_nvconfig_board_v2 {
+	__le16 nports;
+	u8 port0_phy_addr;
+	u8 port0_phy_type;
+	u8 port1_phy_addr;
+	u8 port1_phy_type;
+	__le16 asic_sub_revision;
+	__le16 board_revision;
+} __packed;
+
+/* Board configuration v3 extra information */
+struct falcon_nvconfig_board_v3 {
+	__le32 spi_device_type[2];
+} __packed;
+
+/* Bit numbers for spi_device_type */
+#define SPI_DEV_TYPE_SIZE_LBN 0
+#define SPI_DEV_TYPE_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_ADDR_LEN_LBN 6
+#define SPI_DEV_TYPE_ADDR_LEN_WIDTH 2
+#define SPI_DEV_TYPE_ERASE_CMD_LBN 8
+#define SPI_DEV_TYPE_ERASE_CMD_WIDTH 8
+#define SPI_DEV_TYPE_ERASE_SIZE_LBN 16
+#define SPI_DEV_TYPE_ERASE_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_BLOCK_SIZE_LBN 24
+#define SPI_DEV_TYPE_BLOCK_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_FIELD(type, field)					\
+	(((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field)))
+
+#define FALCON_NVCONFIG_OFFSET 0x300
+
+#define FALCON_NVCONFIG_BOARD_MAGIC_NUM 0xFA1C
+struct falcon_nvconfig {
+	efx_oword_t ee_vpd_cfg_reg;			/* 0x300 */
+	u8 mac_address[2][8];			/* 0x310 */
+	efx_oword_t pcie_sd_ctl0123_reg;		/* 0x320 */
+	efx_oword_t pcie_sd_ctl45_reg;			/* 0x330 */
+	efx_oword_t pcie_pcs_ctl_stat_reg;		/* 0x340 */
+	efx_oword_t hw_init_reg;			/* 0x350 */
+	efx_oword_t nic_stat_reg;			/* 0x360 */
+	efx_oword_t glb_ctl_reg;			/* 0x370 */
+	efx_oword_t srm_cfg_reg;			/* 0x380 */
+	efx_oword_t spare_reg;				/* 0x390 */
+	__le16 board_magic_num;			/* 0x3A0 */
+	__le16 board_struct_ver;
+	__le16 board_checksum;
+	struct falcon_nvconfig_board_v2 board_v2;
+	efx_oword_t ee_base_page_reg;			/* 0x3B0 */
+	struct falcon_nvconfig_board_v3 board_v3;	/* 0x3C0 */
+} __packed;
+
+#endif /* EFX_REGS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/rx.c linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2005-2008 Solarflare Communications Inc.
+ * Copyright 2005-2009 Solarflare Communications 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
@@ -16,9 +16,8 @@
 #include <net/ip.h>
 #include <net/checksum.h>
 #include "net_driver.h"
-#include "rx.h"
 #include "efx.h"
-#include "falcon.h"
+#include "nic.h"
 #include "selftest.h"
 #include "workarounds.h"
 
@@ -61,7 +60,7 @@
  *   rx_alloc_method = (rx_alloc_level > RX_ALLOC_LEVEL_LRO ?
  *                      RX_ALLOC_METHOD_PAGE : RX_ALLOC_METHOD_SKB)
  */
-static int rx_alloc_method = RX_ALLOC_METHOD_PAGE;
+static int rx_alloc_method = RX_ALLOC_METHOD_AUTO;
 
 #define RX_ALLOC_LEVEL_LRO 0x2000
 #define RX_ALLOC_LEVEL_MAX 0x3000
@@ -293,8 +292,7 @@ static int __efx_fast_push_rx_descriptor
 	 * fill anyway.
 	 */
 	fill_level = (rx_queue->added_count - rx_queue->removed_count);
-	EFX_BUG_ON_PARANOID(fill_level >
-			    rx_queue->efx->type->rxd_ring_mask + 1);
+	EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE);
 
 	/* Don't fill if we don't need to */
 	if (fill_level >= rx_queue->fast_fill_trigger)
@@ -316,8 +314,7 @@ static int __efx_fast_push_rx_descriptor
  retry:
 	/* Recalculate current fill level now that we have the lock */
 	fill_level = (rx_queue->added_count - rx_queue->removed_count);
-	EFX_BUG_ON_PARANOID(fill_level >
-			    rx_queue->efx->type->rxd_ring_mask + 1);
+	EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE);
 	space = rx_queue->fast_fill_limit - fill_level;
 	if (space < EFX_RX_BATCH)
 		goto out_unlock;
@@ -329,8 +326,7 @@ static int __efx_fast_push_rx_descriptor
 
 	do {
 		for (i = 0; i < EFX_RX_BATCH; ++i) {
-			index = (rx_queue->added_count &
-				 rx_queue->efx->type->rxd_ring_mask);
+			index = rx_queue->added_count & EFX_RXQ_MASK;
 			rx_buf = efx_rx_buffer(rx_queue, index);
 			rc = efx_init_rx_buffer(rx_queue, rx_buf);
 			if (unlikely(rc))
@@ -345,7 +341,7 @@ static int __efx_fast_push_rx_descriptor
 
  out:
 	/* Send write pointer to card. */
-	falcon_notify_rx_desc(rx_queue);
+	efx_nic_notify_rx_desc(rx_queue);
 
 	/* If the fast fill is running inside from the refill tasklet, then
 	 * for SMP systems it may be running on a different CPU to
@@ -448,17 +444,23 @@ static void efx_rx_packet_lro(struct efx
 			      bool checksummed)
 {
 	struct napi_struct *napi = &channel->napi_str;
+	gro_result_t gro_result;
 
 	/* Pass the skb/page into the LRO engine */
 	if (rx_buf->page) {
-		struct sk_buff *skb = napi_get_frags(napi);
+		struct page *page = rx_buf->page;
+		struct sk_buff *skb;
 
+		EFX_BUG_ON_PARANOID(rx_buf->skb);
+		rx_buf->page = NULL;
+
+		skb = napi_get_frags(napi);
 		if (!skb) {
-			put_page(rx_buf->page);
-			goto out;
+			put_page(page);
+			return;
 		}
 
-		skb_shinfo(skb)->frags[0].page = rx_buf->page;
+		skb_shinfo(skb)->frags[0].page = page;
 		skb_shinfo(skb)->frags[0].page_offset =
 			efx_rx_buf_offset(rx_buf);
 		skb_shinfo(skb)->frags[0].size = rx_buf->len;
@@ -470,17 +472,24 @@ static void efx_rx_packet_lro(struct efx
 		skb->ip_summed =
 			checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
 
-		napi_gro_frags(napi);
+		skb_record_rx_queue(skb, channel->channel);
 
-out:
-		EFX_BUG_ON_PARANOID(rx_buf->skb);
-		rx_buf->page = NULL;
+		gro_result = napi_gro_frags(napi);
 	} else {
-		EFX_BUG_ON_PARANOID(!rx_buf->skb);
-		EFX_BUG_ON_PARANOID(!checksummed);
+		struct sk_buff *skb = rx_buf->skb;
 
-		napi_gro_receive(napi, rx_buf->skb);
+		EFX_BUG_ON_PARANOID(!skb);
+		EFX_BUG_ON_PARANOID(!checksummed);
 		rx_buf->skb = NULL;
+
+		gro_result = napi_gro_receive(napi, skb);
+	}
+
+	if (gro_result == GRO_NORMAL) {
+		channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
+	} else if (gro_result != GRO_DROP) {
+		channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
+		channel->irq_mod_score += 2;
 	}
 }
 
@@ -558,7 +567,7 @@ void __efx_rx_packet(struct efx_channel
 	if (unlikely(efx->loopback_selftest)) {
 		efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len);
 		efx_free_rx_buffer(efx, rx_buf);
-		goto done;
+		return;
 	}
 
 	if (rx_buf->skb) {
@@ -570,34 +579,28 @@ void __efx_rx_packet(struct efx_channel
 		 * at the ethernet header */
 		rx_buf->skb->protocol = eth_type_trans(rx_buf->skb,
 						       efx->net_dev);
+
+		skb_record_rx_queue(rx_buf->skb, channel->channel);
 	}
 
 	if (likely(checksummed || rx_buf->page)) {
 		efx_rx_packet_lro(channel, rx_buf, checksummed);
-		goto done;
+		return;
 	}
 
 	/* We now own the SKB */
 	skb = rx_buf->skb;
 	rx_buf->skb = NULL;
-
-	EFX_BUG_ON_PARANOID(rx_buf->page);
-	EFX_BUG_ON_PARANOID(rx_buf->skb);
 	EFX_BUG_ON_PARANOID(!skb);
 
 	/* Set the SKB flags */
 	skb->ip_summed = CHECKSUM_NONE;
 
-	skb_record_rx_queue(skb, channel->channel);
-
 	/* Pass the packet up */
 	netif_receive_skb(skb);
 
 	/* Update allocation strategy method */
 	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
-
-done:
-	;
 }
 
 void efx_rx_strategy(struct efx_channel *channel)
@@ -632,12 +635,12 @@ int efx_probe_rx_queue(struct efx_rx_que
 	EFX_LOG(efx, "creating RX queue %d\n", rx_queue->queue);
 
 	/* Allocate RX buffers */
-	rxq_size = (efx->type->rxd_ring_mask + 1) * sizeof(*rx_queue->buffer);
+	rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer);
 	rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL);
 	if (!rx_queue->buffer)
 		return -ENOMEM;
 
-	rc = falcon_probe_rx(rx_queue);
+	rc = efx_nic_probe_rx(rx_queue);
 	if (rc) {
 		kfree(rx_queue->buffer);
 		rx_queue->buffer = NULL;
@@ -647,7 +650,6 @@ int efx_probe_rx_queue(struct efx_rx_que
 
 void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
 {
-	struct efx_nic *efx = rx_queue->efx;
 	unsigned int max_fill, trigger, limit;
 
 	EFX_LOG(rx_queue->efx, "initialising RX queue %d\n", rx_queue->queue);
@@ -660,7 +662,7 @@ void efx_init_rx_queue(struct efx_rx_que
 	rx_queue->min_overfill = -1U;
 
 	/* Initialise limit fields */
-	max_fill = efx->type->rxd_ring_mask + 1 - EFX_RXD_HEAD_ROOM;
+	max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM;
 	trigger = max_fill * min(rx_refill_threshold, 100U) / 100U;
 	limit = max_fill * min(rx_refill_limit, 100U) / 100U;
 
@@ -669,7 +671,7 @@ void efx_init_rx_queue(struct efx_rx_que
 	rx_queue->fast_fill_limit = limit;
 
 	/* Set up RX descriptor ring */
-	falcon_init_rx(rx_queue);
+	efx_nic_init_rx(rx_queue);
 }
 
 void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
@@ -679,11 +681,11 @@ void efx_fini_rx_queue(struct efx_rx_que
 
 	EFX_LOG(rx_queue->efx, "shutting down RX queue %d\n", rx_queue->queue);
 
-	falcon_fini_rx(rx_queue);
+	efx_nic_fini_rx(rx_queue);
 
 	/* Release RX buffers NB start at index 0 not current HW ptr */
 	if (rx_queue->buffer) {
-		for (i = 0; i <= rx_queue->efx->type->rxd_ring_mask; i++) {
+		for (i = 0; i <= EFX_RXQ_MASK; i++) {
 			rx_buf = efx_rx_buffer(rx_queue, i);
 			efx_fini_rx_buffer(rx_queue, rx_buf);
 		}
@@ -704,7 +706,7 @@ void efx_remove_rx_queue(struct efx_rx_q
 {
 	EFX_LOG(rx_queue->efx, "destroying RX queue %d\n", rx_queue->queue);
 
-	falcon_remove_rx(rx_queue);
+	efx_nic_remove_rx(rx_queue);
 
 	kfree(rx_queue->buffer);
 	rx_queue->buffer = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/rx.h linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/rx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/rx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_RX_H
-#define EFX_RX_H
-
-#include "net_driver.h"
-
-int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
-
-void efx_rx_strategy(struct efx_channel *channel);
-void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
-void efx_rx_work(struct work_struct *data);
-void __efx_rx_packet(struct efx_channel *channel,
-		     struct efx_rx_buffer *rx_buf, bool checksummed);
-
-#endif /* EFX_RX_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/selftest.c linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/selftest.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/selftest.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -20,14 +20,12 @@
 #include <linux/rtnetlink.h>
 #include <asm/io.h>
 #include "net_driver.h"
-#include "ethtool.h"
 #include "efx.h"
-#include "falcon.h"
+#include "nic.h"
 #include "selftest.h"
-#include "boards.h"
 #include "workarounds.h"
 #include "spi.h"
-#include "falcon_io.h"
+#include "io.h"
 #include "mdio_10g.h"
 
 /*
@@ -49,7 +47,7 @@ static const unsigned char payload_sourc
 	0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b,
 };
 
-static const char *payload_msg =
+static const char payload_msg[] =
 	"Hello world! This is an Efx loopback test in progress!";
 
 /**
@@ -57,6 +55,7 @@ static const char *payload_msg =
  * @flush:		Drop all packets in efx_loopback_rx_packet
  * @packet_count:	Number of packets being used in this test
  * @skbs:		An array of skbs transmitted
+ * @offload_csum:	Checksums are being offloaded
  * @rx_good:		RX good packet count
  * @rx_bad:		RX bad packet count
  * @payload:		Payload used in tests
@@ -65,10 +64,7 @@ struct efx_loopback_state {
 	bool flush;
 	int packet_count;
 	struct sk_buff **skbs;
-
-	/* Checksums are being offloaded */
 	bool offload_csum;
-
 	atomic_t rx_good;
 	atomic_t rx_bad;
 	struct efx_loopback_payload payload;
@@ -83,10 +79,14 @@ struct efx_loopback_state {
 static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
 {
 	int rc = 0;
-	int devad = __ffs(efx->mdio.mmds);
+	int devad;
 	u16 physid1, physid2;
 
-	if (efx->phy_type == PHY_TYPE_NONE)
+	if (efx->mdio.mode_support & MDIO_SUPPORTS_C45)
+		devad = __ffs(efx->mdio.mmds);
+	else if (efx->mdio.mode_support & MDIO_SUPPORTS_C22)
+		devad = MDIO_DEVAD_NONE;
+	else
 		return 0;
 
 	mutex_lock(&efx->mac_lock);
@@ -104,7 +104,7 @@ static int efx_test_mdio(struct efx_nic
 	}
 
 	if (EFX_IS10G(efx)) {
-		rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
+		rc = efx_mdio_check_mmds(efx, efx->mdio.mmds, 0);
 		if (rc)
 			goto out;
 	}
@@ -117,23 +117,26 @@ out:
 
 static int efx_test_nvram(struct efx_nic *efx, struct efx_self_tests *tests)
 {
-	int rc;
+	int rc = 0;
+
+	if (efx->type->test_nvram) {
+		rc = efx->type->test_nvram(efx);
+		tests->nvram = rc ? -1 : 1;
+	}
 
-	rc = falcon_read_nvram(efx, NULL);
-	tests->nvram = rc ? -1 : 1;
 	return rc;
 }
 
 static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
 {
-	int rc;
+	int rc = 0;
 
-	/* Not supported on A-series silicon */
-	if (falcon_rev(efx) < FALCON_REV_B0)
-		return 0;
+	/* Test register access */
+	if (efx->type->test_registers) {
+		rc = efx->type->test_registers(efx);
+		tests->registers = rc ? -1 : 1;
+	}
 
-	rc = falcon_test_registers(efx);
-	tests->registers = rc ? -1 : 1;
 	return rc;
 }
 
@@ -165,7 +168,7 @@ static int efx_test_interrupts(struct ef
 			goto success;
 	}
 
-	falcon_generate_interrupt(efx);
+	efx_nic_generate_interrupt(efx);
 
 	/* Wait for arrival of test interrupt. */
 	EFX_LOG(efx, "waiting for test interrupt\n");
@@ -177,8 +180,8 @@ static int efx_test_interrupts(struct ef
 	return -ETIMEDOUT;
 
  success:
-	EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n",
-		efx->interrupt_mode, efx->last_irq_cpu);
+	EFX_LOG(efx, "%s test interrupt seen on CPU%d\n", INT_MODE(efx),
+		efx->last_irq_cpu);
 	tests->interrupt = 1;
 	return 0;
 }
@@ -203,7 +206,7 @@ static int efx_test_eventq_irq(struct ef
 	channel->eventq_magic = 0;
 	smp_wmb();
 
-	falcon_generate_test_event(channel, magic);
+	efx_nic_generate_test_event(channel, magic);
 
 	/* Wait for arrival of interrupt */
 	count = 0;
@@ -254,9 +257,6 @@ static int efx_test_phy(struct efx_nic *
 	if (!efx->phy_op->run_tests)
 		return 0;
 
-	EFX_BUG_ON_PARANOID(efx->phy_op->num_tests == 0 ||
-			    efx->phy_op->num_tests > EFX_MAX_PHY_TESTS);
-
 	mutex_lock(&efx->mac_lock);
 	rc = efx->phy_op->run_tests(efx, tests->phy, flags);
 	mutex_unlock(&efx->mac_lock);
@@ -426,7 +426,7 @@ static int efx_begin_loopback(struct efx
 
 		if (efx_dev_registered(efx))
 			netif_tx_lock_bh(efx->net_dev);
-		rc = efx_xmit(efx, tx_queue, skb);
+		rc = efx_enqueue_skb(tx_queue, skb);
 		if (efx_dev_registered(efx))
 			netif_tx_unlock_bh(efx->net_dev);
 
@@ -439,7 +439,6 @@ static int efx_begin_loopback(struct efx
 			kfree_skb(skb);
 			return -EPIPE;
 		}
-		efx->net_dev->trans_start = jiffies;
 	}
 
 	return 0;
@@ -527,7 +526,7 @@ efx_test_loopback(struct efx_tx_queue *t
 
 	for (i = 0; i < 3; i++) {
 		/* Determine how many packets to send */
-		state->packet_count = (efx->type->txd_ring_mask + 1) / 3;
+		state->packet_count = EFX_TXQ_SIZE / 3;
 		state->packet_count = min(1 << (i << 2), state->packet_count);
 		state->skbs = kzalloc(sizeof(state->skbs[0]) *
 				      state->packet_count, GFP_KERNEL);
@@ -568,14 +567,49 @@ efx_test_loopback(struct efx_tx_queue *t
 	return 0;
 }
 
+/* Wait for link up. On Falcon, we would prefer to rely on efx_monitor, but
+ * any contention on the mac lock (via e.g. efx_mac_mcast_work) causes it
+ * to delay and retry. Therefore, it's safer to just poll directly. Wait
+ * for link up and any faults to dissipate. */
+static int efx_wait_for_link(struct efx_nic *efx)
+{
+	struct efx_link_state *link_state = &efx->link_state;
+	int count;
+	bool link_up;
+
+	for (count = 0; count < 40; count++) {
+		schedule_timeout_uninterruptible(HZ / 10);
+
+		if (efx->type->monitor != NULL) {
+			mutex_lock(&efx->mac_lock);
+			efx->type->monitor(efx);
+			mutex_unlock(&efx->mac_lock);
+		} else {
+			struct efx_channel *channel = &efx->channel[0];
+			if (channel->work_pending)
+				efx_process_channel_now(channel);
+		}
+
+		mutex_lock(&efx->mac_lock);
+		link_up = link_state->up;
+		if (link_up)
+			link_up = !efx->mac_op->check_fault(efx);
+		mutex_unlock(&efx->mac_lock);
+
+		if (link_up)
+			return 0;
+	}
+
+	return -ETIMEDOUT;
+}
+
 static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
 			      unsigned int loopback_modes)
 {
 	enum efx_loopback_mode mode;
 	struct efx_loopback_state *state;
 	struct efx_tx_queue *tx_queue;
-	bool link_up;
-	int count, rc = 0;
+	int rc = 0;
 
 	/* Set the port loopback_selftest member. From this point on
 	 * all received packets will be dropped. Mark the state as
@@ -594,46 +628,23 @@ static int efx_test_loopbacks(struct efx
 
 		/* Move the port into the specified loopback mode. */
 		state->flush = true;
+		mutex_lock(&efx->mac_lock);
 		efx->loopback_mode = mode;
-		efx_reconfigure_port(efx);
-
-		/* Wait for the PHY to signal the link is up. Interrupts
-		 * are enabled for PHY's using LASI, otherwise we poll()
-		 * quickly */
-		count = 0;
-		do {
-			struct efx_channel *channel = &efx->channel[0];
-
-			efx->phy_op->poll(efx);
-			schedule_timeout_uninterruptible(HZ / 10);
-			if (channel->work_pending)
-				efx_process_channel_now(channel);
-			/* Wait for PHY events to be processed */
-			flush_workqueue(efx->workqueue);
-			rmb();
-
-			/* We need both the phy and xaui links to be ok.
-			 * rather than relying on the falcon_xmac irq/poll
-			 * regime, just poll xaui directly */
-			link_up = efx->link_up;
-			if (link_up && EFX_IS10G(efx) &&
-			    !falcon_xaui_link_ok(efx))
-				link_up = false;
-
-		} while ((++count < 20) && !link_up);
+		rc = __efx_reconfigure_port(efx);
+		mutex_unlock(&efx->mac_lock);
+		if (rc) {
+			EFX_ERR(efx, "unable to move into %s loopback\n",
+				LOOPBACK_MODE(efx));
+			goto out;
+		}
 
-		/* The link should now be up. If it isn't, there is no point
-		 * in attempting a loopback test */
-		if (!link_up) {
+		rc = efx_wait_for_link(efx);
+		if (rc) {
 			EFX_ERR(efx, "loopback %s never came up\n",
 				LOOPBACK_MODE(efx));
-			rc = -EIO;
 			goto out;
 		}
 
-		EFX_LOG(efx, "link came up in %s loopback in %d iterations\n",
-			LOOPBACK_MODE(efx), count);
-
 		/* Test every TX queue */
 		efx_for_each_tx_queue(tx_queue, efx) {
 			state->offload_csum = (tx_queue->queue ==
@@ -667,7 +678,6 @@ int efx_selftest(struct efx_nic *efx, st
 	enum efx_loopback_mode loopback_mode = efx->loopback_mode;
 	int phy_mode = efx->phy_mode;
 	enum reset_type reset_method = RESET_TYPE_INVISIBLE;
-	struct ethtool_cmd ecmd;
 	struct efx_channel *channel;
 	int rc_test = 0, rc_reset = 0, rc;
 
@@ -720,21 +730,21 @@ int efx_selftest(struct efx_nic *efx, st
 	mutex_unlock(&efx->mac_lock);
 
 	/* free up all consumers of SRAM (including all the queues) */
-	efx_reset_down(efx, reset_method, &ecmd);
+	efx_reset_down(efx, reset_method);
 
 	rc = efx_test_chip(efx, tests);
 	if (rc && !rc_test)
 		rc_test = rc;
 
 	/* reset the chip to recover from the register test */
-	rc_reset = falcon_reset_hw(efx, reset_method);
+	rc_reset = efx->type->reset(efx, reset_method);
 
 	/* Ensure that the phy is powered and out of loopback
 	 * for the bist and loopback tests */
 	efx->phy_mode &= ~PHY_MODE_LOW_POWER;
 	efx->loopback_mode = LOOPBACK_NONE;
 
-	rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
+	rc = efx_reset_up(efx, reset_method, rc_reset == 0);
 	if (rc && !rc_reset)
 		rc_reset = rc;
 
@@ -753,10 +763,12 @@ int efx_selftest(struct efx_nic *efx, st
 		rc_test = rc;
 
 	/* restore the PHY to the previous state */
-	efx->loopback_mode = loopback_mode;
+	mutex_lock(&efx->mac_lock);
 	efx->phy_mode = phy_mode;
 	efx->port_inhibited = false;
-	efx_ethtool_set_settings(efx->net_dev, &ecmd);
+	efx->loopback_mode = loopback_mode;
+	__efx_reconfigure_port(efx);
+	mutex_unlock(&efx->mac_lock);
 
 	return rc_test;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/sfe4001.c linux-libre-2.6.33-gnu1/drivers/net/sfc/sfe4001.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/sfe4001.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/sfe4001.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,435 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-/*****************************************************************************
- * Support for the SFE4001 and SFN4111T NICs.
- *
- * The SFE4001 does not power-up fully at reset due to its high power
- * consumption.  We control its power via a PCA9539 I/O expander.
- * Both boards have a MAX6647 temperature monitor which we expose to
- * the lm90 driver.
- *
- * This also provides minimal support for reflashing the PHY, which is
- * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
- * On SFE4001 rev A2 and later this is connected to the 3V3X output of
- * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3.
- * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
- * exclusive with the network device being open.
- */
-
-#include <linux/delay.h>
-#include <linux/rtnetlink.h>
-#include "net_driver.h"
-#include "efx.h"
-#include "phy.h"
-#include "boards.h"
-#include "falcon.h"
-#include "falcon_hwdefs.h"
-#include "falcon_io.h"
-#include "mac.h"
-#include "workarounds.h"
-
-/**************************************************************************
- *
- * I2C IO Expander device
- *
- **************************************************************************/
-#define	PCA9539 0x74
-
-#define	P0_IN 0x00
-#define	P0_OUT 0x02
-#define	P0_INVERT 0x04
-#define	P0_CONFIG 0x06
-
-#define	P0_EN_1V0X_LBN 0
-#define	P0_EN_1V0X_WIDTH 1
-#define	P0_EN_1V2_LBN 1
-#define	P0_EN_1V2_WIDTH 1
-#define	P0_EN_2V5_LBN 2
-#define	P0_EN_2V5_WIDTH 1
-#define	P0_EN_3V3X_LBN 3
-#define	P0_EN_3V3X_WIDTH 1
-#define	P0_EN_5V_LBN 4
-#define	P0_EN_5V_WIDTH 1
-#define	P0_SHORTEN_JTAG_LBN 5
-#define	P0_SHORTEN_JTAG_WIDTH 1
-#define	P0_X_TRST_LBN 6
-#define	P0_X_TRST_WIDTH 1
-#define	P0_DSP_RESET_LBN 7
-#define	P0_DSP_RESET_WIDTH 1
-
-#define	P1_IN 0x01
-#define	P1_OUT 0x03
-#define	P1_INVERT 0x05
-#define	P1_CONFIG 0x07
-
-#define	P1_AFE_PWD_LBN 0
-#define	P1_AFE_PWD_WIDTH 1
-#define	P1_DSP_PWD25_LBN 1
-#define	P1_DSP_PWD25_WIDTH 1
-#define	P1_RESERVED_LBN 2
-#define	P1_RESERVED_WIDTH 2
-#define	P1_SPARE_LBN 4
-#define	P1_SPARE_WIDTH 4
-
-/* Temperature Sensor */
-#define MAX664X_REG_RSL		0x02
-#define MAX664X_REG_WLHO	0x0B
-
-static void sfe4001_poweroff(struct efx_nic *efx)
-{
-	struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
-	struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
-
-	/* Turn off all power rails and disable outputs */
-	i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
-	i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff);
-	i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
-
-	/* Clear any over-temperature alert */
-	i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
-}
-
-static int sfe4001_poweron(struct efx_nic *efx)
-{
-	struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
-	struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
-	unsigned int i, j;
-	int rc;
-	u8 out;
-
-	/* Clear any previous over-temperature alert */
-	rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
-	if (rc < 0)
-		return rc;
-
-	/* Enable port 0 and port 1 outputs on IO expander */
-	rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
-	if (rc)
-		return rc;
-	rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
-				       0xff & ~(1 << P1_SPARE_LBN));
-	if (rc)
-		goto fail_on;
-
-	/* If PHY power is on, turn it all off and wait 1 second to
-	 * ensure a full reset.
-	 */
-	rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
-	if (rc < 0)
-		goto fail_on;
-	out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
-		       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
-		       (0 << P0_EN_1V0X_LBN));
-	if (rc != out) {
-		EFX_INFO(efx, "power-cycling PHY\n");
-		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
-		if (rc)
-			goto fail_on;
-		schedule_timeout_uninterruptible(HZ);
-	}
-
-	for (i = 0; i < 20; ++i) {
-		/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
-		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
-			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
-			       (1 << P0_X_TRST_LBN));
-		if (efx->phy_mode & PHY_MODE_SPECIAL)
-			out |= 1 << P0_EN_3V3X_LBN;
-
-		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
-		if (rc)
-			goto fail_on;
-		msleep(10);
-
-		/* Turn on 1V power rail */
-		out &= ~(1 << P0_EN_1V0X_LBN);
-		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
-		if (rc)
-			goto fail_on;
-
-		EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i);
-
-		/* In flash config mode, DSP does not turn on AFE, so
-		 * just wait 1 second.
-		 */
-		if (efx->phy_mode & PHY_MODE_SPECIAL) {
-			schedule_timeout_uninterruptible(HZ);
-			return 0;
-		}
-
-		for (j = 0; j < 10; ++j) {
-			msleep(100);
-
-			/* Check DSP has asserted AFE power line */
-			rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
-			if (rc < 0)
-				goto fail_on;
-			if (rc & (1 << P1_AFE_PWD_LBN))
-				return 0;
-		}
-	}
-
-	EFX_INFO(efx, "timed out waiting for DSP boot\n");
-	rc = -ETIMEDOUT;
-fail_on:
-	sfe4001_poweroff(efx);
-	return rc;
-}
-
-static int sfn4111t_reset(struct efx_nic *efx)
-{
-	efx_oword_t reg;
-
-	/* GPIO 3 and the GPIO register are shared with I2C, so block that */
-	i2c_lock_adapter(&efx->i2c_adap);
-
-	/* Pull RST_N (GPIO 2) low then let it up again, setting the
-	 * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
-	 * output enables; the output levels should always be 0 (low)
-	 * and we rely on external pull-ups. */
-	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
-	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
-	msleep(1000);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
-			    !!(efx->phy_mode & PHY_MODE_SPECIAL));
-	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
-	msleep(1);
-
-	i2c_unlock_adapter(&efx->i2c_adap);
-
-	ssleep(1);
-	return 0;
-}
-
-static ssize_t show_phy_flash_cfg(struct device *dev,
-				  struct device_attribute *attr, char *buf)
-{
-	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
-	return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
-}
-
-static ssize_t set_phy_flash_cfg(struct device *dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
-{
-	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
-	enum efx_phy_mode old_mode, new_mode;
-	int err;
-
-	rtnl_lock();
-	old_mode = efx->phy_mode;
-	if (count == 0 || *buf == '0')
-		new_mode = old_mode & ~PHY_MODE_SPECIAL;
-	else
-		new_mode = PHY_MODE_SPECIAL;
-	if (old_mode == new_mode) {
-		err = 0;
-	} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
-		err = -EBUSY;
-	} else {
-		/* Reset the PHY, reconfigure the MAC and enable/disable
-		 * MAC stats accordingly. */
-		efx->phy_mode = new_mode;
-		if (new_mode & PHY_MODE_SPECIAL)
-			efx_stats_disable(efx);
-		if (efx->board_info.type == EFX_BOARD_SFE4001)
-			err = sfe4001_poweron(efx);
-		else
-			err = sfn4111t_reset(efx);
-		efx_reconfigure_port(efx);
-		if (!(new_mode & PHY_MODE_SPECIAL))
-			efx_stats_enable(efx);
-	}
-	rtnl_unlock();
-
-	return err ? err : count;
-}
-
-static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
-
-static void sfe4001_fini(struct efx_nic *efx)
-{
-	EFX_INFO(efx, "%s\n", __func__);
-
-	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
-	sfe4001_poweroff(efx);
-	i2c_unregister_device(efx->board_info.ioexp_client);
-	i2c_unregister_device(efx->board_info.hwmon_client);
-}
-
-static int sfe4001_check_hw(struct efx_nic *efx)
-{
-	s32 status;
-
-	/* If XAUI link is up then do not monitor */
-	if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
-		return 0;
-
-	/* Check the powered status of the PHY. Lack of power implies that
-	 * the MAX6647 has shut down power to it, probably due to a temp.
-	 * alarm. Reading the power status rather than the MAX6647 status
-	 * directly because the later is read-to-clear and would thus
-	 * start to power up the PHY again when polled, causing us to blip
-	 * the power undesirably.
-	 * We know we can read from the IO expander because we did
-	 * it during power-on. Assume failure now is bad news. */
-	status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN);
-	if (status >= 0 &&
-	    (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
-		return 0;
-
-	/* Use board power control, not PHY power control */
-	sfe4001_poweroff(efx);
-	efx->phy_mode = PHY_MODE_OFF;
-
-	return (status < 0) ? -EIO : -ERANGE;
-}
-
-static struct i2c_board_info sfe4001_hwmon_info = {
-	I2C_BOARD_INFO("max6647", 0x4e),
-};
-
-/* This board uses an I2C expander to provider power to the PHY, which needs to
- * be turned on before the PHY can be used.
- * Context: Process context, rtnl lock held
- */
-int sfe4001_init(struct efx_nic *efx)
-{
-	int rc;
-
-#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
-	efx->board_info.hwmon_client =
-		i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
-#else
-	efx->board_info.hwmon_client =
-		i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr);
-#endif
-	if (!efx->board_info.hwmon_client)
-		return -EIO;
-
-	/* Raise board/PHY high limit from 85 to 90 degrees Celsius */
-	rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client,
-				       MAX664X_REG_WLHO, 90);
-	if (rc)
-		goto fail_hwmon;
-
-	efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
-	if (!efx->board_info.ioexp_client) {
-		rc = -EIO;
-		goto fail_hwmon;
-	}
-
-	/* 10Xpress has fixed-function LED pins, so there is no board-specific
-	 * blink code. */
-	efx->board_info.blink = tenxpress_phy_blink;
-
-	efx->board_info.monitor = sfe4001_check_hw;
-	efx->board_info.fini = sfe4001_fini;
-
-	if (efx->phy_mode & PHY_MODE_SPECIAL) {
-		/* PHY won't generate a 156.25 MHz clock and MAC stats fetch
-		 * will fail. */
-		efx_stats_disable(efx);
-	}
-	rc = sfe4001_poweron(efx);
-	if (rc)
-		goto fail_ioexp;
-
-	rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
-	if (rc)
-		goto fail_on;
-
-	EFX_INFO(efx, "PHY is powered on\n");
-	return 0;
-
-fail_on:
-	sfe4001_poweroff(efx);
-fail_ioexp:
-	i2c_unregister_device(efx->board_info.ioexp_client);
-fail_hwmon:
-	i2c_unregister_device(efx->board_info.hwmon_client);
-	return rc;
-}
-
-static int sfn4111t_check_hw(struct efx_nic *efx)
-{
-	s32 status;
-
-	/* If XAUI link is up then do not monitor */
-	if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
-		return 0;
-
-	/* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
-	status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client,
-					  MAX664X_REG_RSL);
-	if (status < 0)
-		return -EIO;
-	if (status & 0x57)
-		return -ERANGE;
-	return 0;
-}
-
-static void sfn4111t_fini(struct efx_nic *efx)
-{
-	EFX_INFO(efx, "%s\n", __func__);
-
-	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
-	i2c_unregister_device(efx->board_info.hwmon_client);
-}
-
-static struct i2c_board_info sfn4111t_a0_hwmon_info = {
-	I2C_BOARD_INFO("max6647", 0x4e),
-};
-
-static struct i2c_board_info sfn4111t_r5_hwmon_info = {
-	I2C_BOARD_INFO("max6646", 0x4d),
-};
-
-int sfn4111t_init(struct efx_nic *efx)
-{
-	int i = 0;
-	int rc;
-
-	efx->board_info.hwmon_client =
-		i2c_new_device(&efx->i2c_adap,
-			       (efx->board_info.minor < 5) ?
-			       &sfn4111t_a0_hwmon_info :
-			       &sfn4111t_r5_hwmon_info);
-	if (!efx->board_info.hwmon_client)
-		return -EIO;
-
-	efx->board_info.blink = tenxpress_phy_blink;
-	efx->board_info.monitor = sfn4111t_check_hw;
-	efx->board_info.fini = sfn4111t_fini;
-
-	rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
-	if (rc)
-		goto fail_hwmon;
-
-	do {
-		if (efx->phy_mode & PHY_MODE_SPECIAL) {
-			/* PHY may not generate a 156.25 MHz clock and MAC
-			 * stats fetch will fail. */
-			efx_stats_disable(efx);
-			sfn4111t_reset(efx);
-		}
-		rc = sft9001_wait_boot(efx);
-		if (rc == 0)
-			return 0;
-		efx->phy_mode = PHY_MODE_SPECIAL;
-	} while (rc == -EINVAL && ++i < 2);
-
-	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
-fail_hwmon:
-	i2c_unregister_device(efx->board_info.hwmon_client);
-	return rc;
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/siena.c linux-libre-2.6.33-gnu1/drivers/net/sfc/siena.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/siena.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/siena.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,605 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include "net_driver.h"
+#include "bitfield.h"
+#include "efx.h"
+#include "nic.h"
+#include "mac.h"
+#include "spi.h"
+#include "regs.h"
+#include "io.h"
+#include "phy.h"
+#include "workarounds.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+
+/* Hardware control for SFC9000 family including SFL9021 (aka Siena). */
+
+static void siena_init_wol(struct efx_nic *efx);
+
+
+static void siena_push_irq_moderation(struct efx_channel *channel)
+{
+	efx_dword_t timer_cmd;
+
+	if (channel->irq_moderation)
+		EFX_POPULATE_DWORD_2(timer_cmd,
+				     FRF_CZ_TC_TIMER_MODE,
+				     FFE_CZ_TIMER_MODE_INT_HLDOFF,
+				     FRF_CZ_TC_TIMER_VAL,
+				     channel->irq_moderation - 1);
+	else
+		EFX_POPULATE_DWORD_2(timer_cmd,
+				     FRF_CZ_TC_TIMER_MODE,
+				     FFE_CZ_TIMER_MODE_DIS,
+				     FRF_CZ_TC_TIMER_VAL, 0);
+	efx_writed_page_locked(channel->efx, &timer_cmd, FR_BZ_TIMER_COMMAND_P0,
+			       channel->channel);
+}
+
+static void siena_push_multicast_hash(struct efx_nic *efx)
+{
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
+	efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH,
+		     efx->multicast_hash.byte, sizeof(efx->multicast_hash),
+		     NULL, 0, NULL);
+}
+
+static int siena_mdio_write(struct net_device *net_dev,
+			    int prtad, int devad, u16 addr, u16 value)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	uint32_t status;
+	int rc;
+
+	rc = efx_mcdi_mdio_write(efx, efx->mdio_bus, prtad, devad,
+				 addr, value, &status);
+	if (rc)
+		return rc;
+	if (status != MC_CMD_MDIO_STATUS_GOOD)
+		return -EIO;
+
+	return 0;
+}
+
+static int siena_mdio_read(struct net_device *net_dev,
+			   int prtad, int devad, u16 addr)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	uint16_t value;
+	uint32_t status;
+	int rc;
+
+	rc = efx_mcdi_mdio_read(efx, efx->mdio_bus, prtad, devad,
+				addr, &value, &status);
+	if (rc)
+		return rc;
+	if (status != MC_CMD_MDIO_STATUS_GOOD)
+		return -EIO;
+
+	return (int)value;
+}
+
+/* This call is responsible for hooking in the MAC and PHY operations */
+static int siena_probe_port(struct efx_nic *efx)
+{
+	int rc;
+
+	/* Hook in PHY operations table */
+	efx->phy_op = &efx_mcdi_phy_ops;
+
+	/* Set up MDIO structure for PHY */
+	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+	efx->mdio.mdio_read = siena_mdio_read;
+	efx->mdio.mdio_write = siena_mdio_write;
+
+	/* Fill out MDIO structure and loopback modes */
+	rc = efx->phy_op->probe(efx);
+	if (rc != 0)
+		return rc;
+
+	/* Initial assumption */
+	efx->link_state.speed = 10000;
+	efx->link_state.fd = true;
+	efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
+
+	/* Allocate buffer for stats */
+	rc = efx_nic_alloc_buffer(efx, &efx->stats_buffer,
+				  MC_CMD_MAC_NSTATS * sizeof(u64));
+	if (rc)
+		return rc;
+	EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n",
+		(u64)efx->stats_buffer.dma_addr,
+		efx->stats_buffer.addr,
+		(u64)virt_to_phys(efx->stats_buffer.addr));
+
+	efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 1);
+
+	return 0;
+}
+
+void siena_remove_port(struct efx_nic *efx)
+{
+	efx->phy_op->remove(efx);
+	efx_nic_free_buffer(efx, &efx->stats_buffer);
+}
+
+static const struct efx_nic_register_test siena_register_tests[] = {
+	{ FR_AZ_ADR_REGION,
+	  EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) },
+	{ FR_CZ_USR_EV_CFG,
+	  EFX_OWORD32(0x000103FF, 0x00000000, 0x00000000, 0x00000000) },
+	{ FR_AZ_RX_CFG,
+	  EFX_OWORD32(0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000) },
+	{ FR_AZ_TX_CFG,
+	  EFX_OWORD32(0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF) },
+	{ FR_AZ_TX_RESERVED,
+	  EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) },
+	{ FR_AZ_SRM_TX_DC_CFG,
+	  EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) },
+	{ FR_AZ_RX_DC_CFG,
+	  EFX_OWORD32(0x00000003, 0x00000000, 0x00000000, 0x00000000) },
+	{ FR_AZ_RX_DC_PF_WM,
+	  EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
+	{ FR_BZ_DP_CTRL,
+	  EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
+	{ FR_BZ_RX_RSS_TKEY,
+	  EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) },
+	{ FR_CZ_RX_RSS_IPV6_REG1,
+	  EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) },
+	{ FR_CZ_RX_RSS_IPV6_REG2,
+	  EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF) },
+	{ FR_CZ_RX_RSS_IPV6_REG3,
+	  EFX_OWORD32(0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000) },
+};
+
+static int siena_test_registers(struct efx_nic *efx)
+{
+	return efx_nic_test_registers(efx, siena_register_tests,
+				      ARRAY_SIZE(siena_register_tests));
+}
+
+/**************************************************************************
+ *
+ * Device reset
+ *
+ **************************************************************************
+ */
+
+static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
+{
+
+	if (method == RESET_TYPE_WORLD)
+		return efx_mcdi_reset_mc(efx);
+	else
+		return efx_mcdi_reset_port(efx);
+}
+
+static int siena_probe_nvconfig(struct efx_nic *efx)
+{
+	int rc;
+
+	rc = efx_mcdi_get_board_cfg(efx, efx->mac_address, NULL);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+static int siena_probe_nic(struct efx_nic *efx)
+{
+	struct siena_nic_data *nic_data;
+	bool already_attached = 0;
+	int rc;
+
+	/* Allocate storage for hardware specific data */
+	nic_data = kzalloc(sizeof(struct siena_nic_data), GFP_KERNEL);
+	if (!nic_data)
+		return -ENOMEM;
+	efx->nic_data = nic_data;
+
+	if (efx_nic_fpga_ver(efx) != 0) {
+		EFX_ERR(efx, "Siena FPGA not supported\n");
+		rc = -ENODEV;
+		goto fail1;
+	}
+
+	efx_mcdi_init(efx);
+
+	/* Recover from a failed assertion before probing */
+	rc = efx_mcdi_handle_assertion(efx);
+	if (rc)
+		goto fail1;
+
+	rc = efx_mcdi_fwver(efx, &nic_data->fw_version, &nic_data->fw_build);
+	if (rc) {
+		EFX_ERR(efx, "Failed to read MCPU firmware version - "
+			"rc %d\n", rc);
+		goto fail1; /* MCPU absent? */
+	}
+
+	/* Let the BMC know that the driver is now in charge of link and
+	 * filter settings. We must do this before we reset the NIC */
+	rc = efx_mcdi_drv_attach(efx, true, &already_attached);
+	if (rc) {
+		EFX_ERR(efx, "Unable to register driver with MCPU\n");
+		goto fail2;
+	}
+	if (already_attached)
+		/* Not a fatal error */
+		EFX_ERR(efx, "Host already registered with MCPU\n");
+
+	/* Now we can reset the NIC */
+	rc = siena_reset_hw(efx, RESET_TYPE_ALL);
+	if (rc) {
+		EFX_ERR(efx, "failed to reset NIC\n");
+		goto fail3;
+	}
+
+	siena_init_wol(efx);
+
+	/* Allocate memory for INT_KER */
+	rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t));
+	if (rc)
+		goto fail4;
+	BUG_ON(efx->irq_status.dma_addr & 0x0f);
+
+	EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n",
+		(unsigned long long)efx->irq_status.dma_addr,
+		efx->irq_status.addr,
+		(unsigned long long)virt_to_phys(efx->irq_status.addr));
+
+	/* Read in the non-volatile configuration */
+	rc = siena_probe_nvconfig(efx);
+	if (rc == -EINVAL) {
+		EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
+		efx->phy_type = PHY_TYPE_NONE;
+		efx->mdio.prtad = MDIO_PRTAD_NONE;
+	} else if (rc) {
+		goto fail5;
+	}
+
+	return 0;
+
+fail5:
+	efx_nic_free_buffer(efx, &efx->irq_status);
+fail4:
+fail3:
+	efx_mcdi_drv_attach(efx, false, NULL);
+fail2:
+fail1:
+	kfree(efx->nic_data);
+	return rc;
+}
+
+/* This call performs hardware-specific global initialisation, such as
+ * defining the descriptor cache sizes and number of RSS channels.
+ * It does not set up any buffers, descriptor rings or event queues.
+ */
+static int siena_init_nic(struct efx_nic *efx)
+{
+	efx_oword_t temp;
+	int rc;
+
+	/* Recover from a failed assertion post-reset */
+	rc = efx_mcdi_handle_assertion(efx);
+	if (rc)
+		return rc;
+
+	/* Squash TX of packets of 16 bytes or less */
+	efx_reado(efx, &temp, FR_AZ_TX_RESERVED);
+	EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
+	efx_writeo(efx, &temp, FR_AZ_TX_RESERVED);
+
+	/* Do not enable TX_NO_EOP_DISC_EN, since it limits packets to 16
+	 * descriptors (which is bad).
+	 */
+	efx_reado(efx, &temp, FR_AZ_TX_CFG);
+	EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
+	EFX_SET_OWORD_FIELD(temp, FRF_CZ_TX_FILTER_EN_BIT, 1);
+	efx_writeo(efx, &temp, FR_AZ_TX_CFG);
+
+	efx_reado(efx, &temp, FR_AZ_RX_CFG);
+	EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_DESC_PUSH_EN, 0);
+	EFX_SET_OWORD_FIELD(temp, FRF_BZ_RX_INGR_EN, 1);
+	efx_writeo(efx, &temp, FR_AZ_RX_CFG);
+
+	if (efx_nic_rx_xoff_thresh >= 0 || efx_nic_rx_xon_thresh >= 0)
+		/* No MCDI operation has been defined to set thresholds */
+		EFX_ERR(efx, "ignoring RX flow control thresholds\n");
+
+	/* Enable event logging */
+	rc = efx_mcdi_log_ctrl(efx, true, false, 0);
+	if (rc)
+		return rc;
+
+	/* Set destination of both TX and RX Flush events */
+	EFX_POPULATE_OWORD_1(temp, FRF_BZ_FLS_EVQ_ID, 0);
+	efx_writeo(efx, &temp, FR_BZ_DP_CTRL);
+
+	EFX_POPULATE_OWORD_1(temp, FRF_CZ_USREV_DIS, 1);
+	efx_writeo(efx, &temp, FR_CZ_USR_EV_CFG);
+
+	efx_nic_init_common(efx);
+	return 0;
+}
+
+static void siena_remove_nic(struct efx_nic *efx)
+{
+	efx_nic_free_buffer(efx, &efx->irq_status);
+
+	siena_reset_hw(efx, RESET_TYPE_ALL);
+
+	/* Relinquish the device back to the BMC */
+	if (efx_nic_has_mc(efx))
+		efx_mcdi_drv_attach(efx, false, NULL);
+
+	/* Tear down the private nic state */
+	kfree(efx->nic_data);
+	efx->nic_data = NULL;
+}
+
+#define STATS_GENERATION_INVALID ((u64)(-1))
+
+static int siena_try_update_nic_stats(struct efx_nic *efx)
+{
+	u64 *dma_stats;
+	struct efx_mac_stats *mac_stats;
+	u64 generation_start;
+	u64 generation_end;
+
+	mac_stats = &efx->mac_stats;
+	dma_stats = (u64 *)efx->stats_buffer.addr;
+
+	generation_end = dma_stats[MC_CMD_MAC_GENERATION_END];
+	if (generation_end == STATS_GENERATION_INVALID)
+		return 0;
+	rmb();
+
+#define MAC_STAT(M, D) \
+	mac_stats->M = dma_stats[MC_CMD_MAC_ ## D]
+
+	MAC_STAT(tx_bytes, TX_BYTES);
+	MAC_STAT(tx_bad_bytes, TX_BAD_BYTES);
+	mac_stats->tx_good_bytes = (mac_stats->tx_bytes -
+				    mac_stats->tx_bad_bytes);
+	MAC_STAT(tx_packets, TX_PKTS);
+	MAC_STAT(tx_bad, TX_BAD_FCS_PKTS);
+	MAC_STAT(tx_pause, TX_PAUSE_PKTS);
+	MAC_STAT(tx_control, TX_CONTROL_PKTS);
+	MAC_STAT(tx_unicast, TX_UNICAST_PKTS);
+	MAC_STAT(tx_multicast, TX_MULTICAST_PKTS);
+	MAC_STAT(tx_broadcast, TX_BROADCAST_PKTS);
+	MAC_STAT(tx_lt64, TX_LT64_PKTS);
+	MAC_STAT(tx_64, TX_64_PKTS);
+	MAC_STAT(tx_65_to_127, TX_65_TO_127_PKTS);
+	MAC_STAT(tx_128_to_255, TX_128_TO_255_PKTS);
+	MAC_STAT(tx_256_to_511, TX_256_TO_511_PKTS);
+	MAC_STAT(tx_512_to_1023, TX_512_TO_1023_PKTS);
+	MAC_STAT(tx_1024_to_15xx, TX_1024_TO_15XX_PKTS);
+	MAC_STAT(tx_15xx_to_jumbo, TX_15XX_TO_JUMBO_PKTS);
+	MAC_STAT(tx_gtjumbo, TX_GTJUMBO_PKTS);
+	mac_stats->tx_collision = 0;
+	MAC_STAT(tx_single_collision, TX_SINGLE_COLLISION_PKTS);
+	MAC_STAT(tx_multiple_collision, TX_MULTIPLE_COLLISION_PKTS);
+	MAC_STAT(tx_excessive_collision, TX_EXCESSIVE_COLLISION_PKTS);
+	MAC_STAT(tx_deferred, TX_DEFERRED_PKTS);
+	MAC_STAT(tx_late_collision, TX_LATE_COLLISION_PKTS);
+	mac_stats->tx_collision = (mac_stats->tx_single_collision +
+				   mac_stats->tx_multiple_collision +
+				   mac_stats->tx_excessive_collision +
+				   mac_stats->tx_late_collision);
+	MAC_STAT(tx_excessive_deferred, TX_EXCESSIVE_DEFERRED_PKTS);
+	MAC_STAT(tx_non_tcpudp, TX_NON_TCPUDP_PKTS);
+	MAC_STAT(tx_mac_src_error, TX_MAC_SRC_ERR_PKTS);
+	MAC_STAT(tx_ip_src_error, TX_IP_SRC_ERR_PKTS);
+	MAC_STAT(rx_bytes, RX_BYTES);
+	MAC_STAT(rx_bad_bytes, RX_BAD_BYTES);
+	mac_stats->rx_good_bytes = (mac_stats->rx_bytes -
+				    mac_stats->rx_bad_bytes);
+	MAC_STAT(rx_packets, RX_PKTS);
+	MAC_STAT(rx_good, RX_GOOD_PKTS);
+	mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good;
+	MAC_STAT(rx_pause, RX_PAUSE_PKTS);
+	MAC_STAT(rx_control, RX_CONTROL_PKTS);
+	MAC_STAT(rx_unicast, RX_UNICAST_PKTS);
+	MAC_STAT(rx_multicast, RX_MULTICAST_PKTS);
+	MAC_STAT(rx_broadcast, RX_BROADCAST_PKTS);
+	MAC_STAT(rx_lt64, RX_UNDERSIZE_PKTS);
+	MAC_STAT(rx_64, RX_64_PKTS);
+	MAC_STAT(rx_65_to_127, RX_65_TO_127_PKTS);
+	MAC_STAT(rx_128_to_255, RX_128_TO_255_PKTS);
+	MAC_STAT(rx_256_to_511, RX_256_TO_511_PKTS);
+	MAC_STAT(rx_512_to_1023, RX_512_TO_1023_PKTS);
+	MAC_STAT(rx_1024_to_15xx, RX_1024_TO_15XX_PKTS);
+	MAC_STAT(rx_15xx_to_jumbo, RX_15XX_TO_JUMBO_PKTS);
+	MAC_STAT(rx_gtjumbo, RX_GTJUMBO_PKTS);
+	mac_stats->rx_bad_lt64 = 0;
+	mac_stats->rx_bad_64_to_15xx = 0;
+	mac_stats->rx_bad_15xx_to_jumbo = 0;
+	MAC_STAT(rx_bad_gtjumbo, RX_JABBER_PKTS);
+	MAC_STAT(rx_overflow, RX_OVERFLOW_PKTS);
+	mac_stats->rx_missed = 0;
+	MAC_STAT(rx_false_carrier, RX_FALSE_CARRIER_PKTS);
+	MAC_STAT(rx_symbol_error, RX_SYMBOL_ERROR_PKTS);
+	MAC_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS);
+	MAC_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS);
+	MAC_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS);
+	mac_stats->rx_good_lt64 = 0;
+
+	efx->n_rx_nodesc_drop_cnt = dma_stats[MC_CMD_MAC_RX_NODESC_DROPS];
+
+#undef MAC_STAT
+
+	rmb();
+	generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
+	if (generation_end != generation_start)
+		return -EAGAIN;
+
+	return 0;
+}
+
+static void siena_update_nic_stats(struct efx_nic *efx)
+{
+	while (siena_try_update_nic_stats(efx) == -EAGAIN)
+		cpu_relax();
+}
+
+static void siena_start_nic_stats(struct efx_nic *efx)
+{
+	u64 *dma_stats = (u64 *)efx->stats_buffer.addr;
+
+	dma_stats[MC_CMD_MAC_GENERATION_END] = STATS_GENERATION_INVALID;
+
+	efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr,
+			   MC_CMD_MAC_NSTATS * sizeof(u64), 1, 0);
+}
+
+static void siena_stop_nic_stats(struct efx_nic *efx)
+{
+	efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 0);
+}
+
+void siena_print_fwver(struct efx_nic *efx, char *buf, size_t len)
+{
+	struct siena_nic_data *nic_data = efx->nic_data;
+	snprintf(buf, len, "%u.%u.%u.%u",
+		 (unsigned int)(nic_data->fw_version >> 48),
+		 (unsigned int)(nic_data->fw_version >> 32 & 0xffff),
+		 (unsigned int)(nic_data->fw_version >> 16 & 0xffff),
+		 (unsigned int)(nic_data->fw_version & 0xffff));
+}
+
+/**************************************************************************
+ *
+ * Wake on LAN
+ *
+ **************************************************************************
+ */
+
+static void siena_get_wol(struct efx_nic *efx, struct ethtool_wolinfo *wol)
+{
+	struct siena_nic_data *nic_data = efx->nic_data;
+
+	wol->supported = WAKE_MAGIC;
+	if (nic_data->wol_filter_id != -1)
+		wol->wolopts = WAKE_MAGIC;
+	else
+		wol->wolopts = 0;
+	memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+
+static int siena_set_wol(struct efx_nic *efx, u32 type)
+{
+	struct siena_nic_data *nic_data = efx->nic_data;
+	int rc;
+
+	if (type & ~WAKE_MAGIC)
+		return -EINVAL;
+
+	if (type & WAKE_MAGIC) {
+		if (nic_data->wol_filter_id != -1)
+			efx_mcdi_wol_filter_remove(efx,
+						   nic_data->wol_filter_id);
+		rc = efx_mcdi_wol_filter_set_magic(efx, efx->mac_address,
+						   &nic_data->wol_filter_id);
+		if (rc)
+			goto fail;
+
+		pci_wake_from_d3(efx->pci_dev, true);
+	} else {
+		rc = efx_mcdi_wol_filter_reset(efx);
+		nic_data->wol_filter_id = -1;
+		pci_wake_from_d3(efx->pci_dev, false);
+		if (rc)
+			goto fail;
+	}
+
+	return 0;
+ fail:
+	EFX_ERR(efx, "%s failed: type=%d rc=%d\n", __func__, type, rc);
+	return rc;
+}
+
+
+static void siena_init_wol(struct efx_nic *efx)
+{
+	struct siena_nic_data *nic_data = efx->nic_data;
+	int rc;
+
+	rc = efx_mcdi_wol_filter_get_magic(efx, &nic_data->wol_filter_id);
+
+	if (rc != 0) {
+		/* If it failed, attempt to get into a synchronised
+		 * state with MC by resetting any set WoL filters */
+		efx_mcdi_wol_filter_reset(efx);
+		nic_data->wol_filter_id = -1;
+	} else if (nic_data->wol_filter_id != -1) {
+		pci_wake_from_d3(efx->pci_dev, true);
+	}
+}
+
+
+/**************************************************************************
+ *
+ * Revision-dependent attributes used by efx.c and nic.c
+ *
+ **************************************************************************
+ */
+
+struct efx_nic_type siena_a0_nic_type = {
+	.probe = siena_probe_nic,
+	.remove = siena_remove_nic,
+	.init = siena_init_nic,
+	.fini = efx_port_dummy_op_void,
+	.monitor = NULL,
+	.reset = siena_reset_hw,
+	.probe_port = siena_probe_port,
+	.remove_port = siena_remove_port,
+	.prepare_flush = efx_port_dummy_op_void,
+	.update_stats = siena_update_nic_stats,
+	.start_stats = siena_start_nic_stats,
+	.stop_stats = siena_stop_nic_stats,
+	.set_id_led = efx_mcdi_set_id_led,
+	.push_irq_moderation = siena_push_irq_moderation,
+	.push_multicast_hash = siena_push_multicast_hash,
+	.reconfigure_port = efx_mcdi_phy_reconfigure,
+	.get_wol = siena_get_wol,
+	.set_wol = siena_set_wol,
+	.resume_wol = siena_init_wol,
+	.test_registers = siena_test_registers,
+	.default_mac_ops = &efx_mcdi_mac_operations,
+
+	.revision = EFX_REV_SIENA_A0,
+	.mem_map_size = (FR_CZ_MC_TREG_SMEM +
+			 FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS),
+	.txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
+	.rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL,
+	.buf_tbl_base = FR_BZ_BUF_FULL_TBL,
+	.evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL,
+	.evq_rptr_tbl_base = FR_BZ_EVQ_RPTR,
+	.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
+	.rx_buffer_padding = 0,
+	.max_interrupt_mode = EFX_INT_MODE_MSIX,
+	.phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
+				   * interrupt handler only supports 32
+				   * channels */
+	.tx_dc_base = 0x88000,
+	.rx_dc_base = 0x68000,
+	.offload_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM,
+	.reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/spi.h linux-libre-2.6.33-gnu1/drivers/net/sfc/spi.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/spi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/spi.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,8 +36,6 @@
 
 /**
  * struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device
- * @efx:		The Efx controller that owns this device
- * @mtd:		MTD state
  * @device_id:		Controller's id for the device
  * @size:		Size (in bytes)
  * @addr_len:		Number of address bytes in read/write commands
@@ -54,10 +52,6 @@
  *	Write commands are limited to blocks with this size and alignment.
  */
 struct efx_spi_device {
-	struct efx_nic *efx;
-#ifdef CONFIG_SFC_MTD
-	void *mtd;
-#endif
 	int device_id;
 	unsigned int size;
 	unsigned int addr_len;
@@ -67,12 +61,16 @@ struct efx_spi_device {
 	unsigned int block_size;
 };
 
-int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command,
+int falcon_spi_cmd(struct efx_nic *efx,
+		   const struct efx_spi_device *spi, unsigned int command,
 		   int address, const void* in, void *out, size_t len);
-int falcon_spi_wait_write(const struct efx_spi_device *spi);
-int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
+int falcon_spi_wait_write(struct efx_nic *efx,
+			  const struct efx_spi_device *spi);
+int falcon_spi_read(struct efx_nic *efx,
+		    const struct efx_spi_device *spi, loff_t start,
 		    size_t len, size_t *retlen, u8 *buffer);
-int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
+int falcon_spi_write(struct efx_nic *efx,
+		     const struct efx_spi_device *spi, loff_t start,
 		     size_t len, size_t *retlen, const u8 *buffer);
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/tenxpress.c linux-libre-2.6.33-gnu1/drivers/net/sfc/tenxpress.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/tenxpress.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/tenxpress.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2007-2008 Solarflare Communications Inc.
+ * Copyright 2007-2009 Solarflare Communications 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
@@ -12,10 +12,9 @@
 #include <linux/seq_file.h>
 #include "efx.h"
 #include "mdio_10g.h"
-#include "falcon.h"
+#include "nic.h"
 #include "phy.h"
-#include "falcon_hwdefs.h"
-#include "boards.h"
+#include "regs.h"
 #include "workarounds.h"
 #include "selftest.h"
 
@@ -31,13 +30,13 @@
 #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |	\
 			   (1 << LOOPBACK_PCS) |	\
 			   (1 << LOOPBACK_PMAPMD) |	\
-			   (1 << LOOPBACK_NETWORK))
+			   (1 << LOOPBACK_PHYXS_WS))
 
 #define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) |	\
 			   (1 << LOOPBACK_PHYXS) |	\
 			   (1 << LOOPBACK_PCS) |	\
 			   (1 << LOOPBACK_PMAPMD) |	\
-			   (1 << LOOPBACK_NETWORK))
+			   (1 << LOOPBACK_PHYXS_WS))
 
 /* We complain if we fail to see the link partner as 10G capable this many
  * times in a row (must be > 1 as sampling the autoneg. registers is racy)
@@ -84,9 +83,9 @@
 #define PMA_PMD_LED_FLASH	(3)
 #define PMA_PMD_LED_MASK	3
 /* All LEDs under hardware control */
-#define PMA_PMD_LED_FULL_AUTO	(0)
+#define SFT9001_PMA_PMD_LED_DEFAULT 0
 /* Green and Amber under hardware control, Red off */
-#define PMA_PMD_LED_DEFAULT	(PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
+#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
 
 #define PMA_PMD_SPEED_ENABLE_REG 49192
 #define PMA_PMD_100TX_ADV_LBN    1
@@ -200,15 +199,20 @@ static ssize_t set_phy_short_reach(struc
 				   const char *buf, size_t count)
 {
 	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+	int rc;
 
 	rtnl_lock();
-	efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
-			  MDIO_PMA_10GBT_TXPWR_SHORT,
-			  count != 0 && *buf != '0');
-	efx_reconfigure_port(efx);
+	if (efx->state != STATE_RUNNING) {
+		rc = -EBUSY;
+	} else {
+		efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
+				  MDIO_PMA_10GBT_TXPWR_SHORT,
+				  count != 0 && *buf != '0');
+		rc = efx_reconfigure_port(efx);
+	}
 	rtnl_unlock();
 
-	return count;
+	return rc < 0 ? rc : (ssize_t)count;
 }
 
 static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
@@ -292,23 +296,68 @@ static int tenxpress_init(struct efx_nic
 		efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
 				  1 << PMA_PMA_LED_ACTIVITY_LBN, true);
 		efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
-			       PMA_PMD_LED_DEFAULT);
+			       SFX7101_PMA_PMD_LED_DEFAULT);
 	}
 
 	return 0;
 }
 
-static int tenxpress_phy_init(struct efx_nic *efx)
+static int tenxpress_phy_probe(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data;
-	int rc = 0;
+	int rc;
 
+	/* Allocate phy private storage */
 	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
 	if (!phy_data)
 		return -ENOMEM;
 	efx->phy_data = phy_data;
 	phy_data->phy_mode = efx->phy_mode;
 
+	/* Create any special files */
+	if (efx->phy_type == PHY_TYPE_SFT9001B) {
+		rc = device_create_file(&efx->pci_dev->dev,
+					&dev_attr_phy_short_reach);
+		if (rc)
+			goto fail;
+	}
+
+	if (efx->phy_type == PHY_TYPE_SFX7101) {
+		efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
+		efx->mdio.mode_support = MDIO_SUPPORTS_C45;
+
+		efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
+
+		efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
+					 ADVERTISED_10000baseT_Full);
+	} else {
+		efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
+		efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+
+		efx->loopback_modes = (SFT9001_LOOPBACKS |
+				       FALCON_XMAC_LOOPBACKS | 
+				       FALCON_GMAC_LOOPBACKS);
+
+		efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
+					 ADVERTISED_10000baseT_Full |
+					 ADVERTISED_1000baseT_Full |
+					 ADVERTISED_100baseT_Full);
+	}
+
+	return 0;
+
+fail:
+	kfree(efx->phy_data);
+	efx->phy_data = NULL;
+	return rc;
+}
+
+static int tenxpress_phy_init(struct efx_nic *efx)
+{
+	int rc;
+
+	falcon_board(efx)->type->init_phy(efx);
+
 	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
 		if (efx->phy_type == PHY_TYPE_SFT9001A) {
 			int reg;
@@ -322,23 +371,20 @@ static int tenxpress_phy_init(struct efx
 
 		rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 		if (rc < 0)
-			goto fail;
+			return rc;
 
 		rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
 		if (rc < 0)
-			goto fail;
+			return rc;
 	}
 
 	rc = tenxpress_init(efx);
 	if (rc < 0)
-		goto fail;
+		return rc;
 
-	if (efx->phy_type == PHY_TYPE_SFT9001B) {
-		rc = device_create_file(&efx->pci_dev->dev,
-					&dev_attr_phy_short_reach);
-		if (rc)
-			goto fail;
-	}
+	/* Reinitialise flow control settings */
+	efx_link_set_wanted_fc(efx, efx->wanted_fc);
+	efx_mdio_an_reconfigure(efx);
 
 	schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
 
@@ -346,11 +392,6 @@ static int tenxpress_phy_init(struct efx
 	falcon_reset_xaui(efx);
 
 	return 0;
-
- fail:
-	kfree(efx->phy_data);
-	efx->phy_data = NULL;
-	return rc;
 }
 
 /* Perform a "special software reset" on the PHY. The caller is
@@ -363,7 +404,7 @@ static int tenxpress_special_reset(struc
 	/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
 	 * a special software reset can glitch the XGMAC sufficiently for stats
 	 * requests to fail. */
-	efx_stats_disable(efx);
+	falcon_stop_nic_stats(efx);
 
 	/* Initiate reset */
 	reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
@@ -385,7 +426,7 @@ static int tenxpress_special_reset(struc
 	/* Wait for the XGXS state machine to churn */
 	mdelay(10);
 out:
-	efx_stats_enable(efx);
+	falcon_start_nic_stats(efx);
 	return rc;
 }
 
@@ -489,133 +530,126 @@ static void tenxpress_low_power(struct e
 			!!(efx->phy_mode & PHY_MODE_LOW_POWER));
 }
 
-static void tenxpress_phy_reconfigure(struct efx_nic *efx)
+static int tenxpress_phy_reconfigure(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data = efx->phy_data;
-	struct ethtool_cmd ecmd;
 	bool phy_mode_change, loop_reset;
 
 	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
 		phy_data->phy_mode = efx->phy_mode;
-		return;
+		return 0;
 	}
 
-	tenxpress_low_power(efx);
-
 	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
 			   phy_data->phy_mode != PHY_MODE_NORMAL);
-	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
+	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
 		      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
 
 	if (loop_reset || phy_mode_change) {
-		int rc;
-
-		efx->phy_op->get_settings(efx, &ecmd);
-
-		if (loop_reset || phy_mode_change) {
-			tenxpress_special_reset(efx);
-
-			/* Reset XAUI if we were in 10G, and are staying
-			 * in 10G. If we're moving into and out of 10G
-			 * then xaui will be reset anyway */
-			if (EFX_IS10G(efx))
-				falcon_reset_xaui(efx);
-		}
+		tenxpress_special_reset(efx);
 
-		rc = efx->phy_op->set_settings(efx, &ecmd);
-		WARN_ON(rc);
+		/* Reset XAUI if we were in 10G, and are staying
+		 * in 10G. If we're moving into and out of 10G
+		 * then xaui will be reset anyway */
+		if (EFX_IS10G(efx))
+			falcon_reset_xaui(efx);
 	}
 
+	tenxpress_low_power(efx);
 	efx_mdio_transmit_disable(efx);
 	efx_mdio_phy_reconfigure(efx);
 	tenxpress_ext_loopback(efx);
+	efx_mdio_an_reconfigure(efx);
 
 	phy_data->loopback_mode = efx->loopback_mode;
 	phy_data->phy_mode = efx->phy_mode;
 
-	if (efx->phy_type == PHY_TYPE_SFX7101) {
-		efx->link_speed = 10000;
-		efx->link_fd = true;
-		efx->link_up = sfx7101_link_ok(efx);
-	} else {
-		efx->phy_op->get_settings(efx, &ecmd);
-		efx->link_speed = ecmd.speed;
-		efx->link_fd = ecmd.duplex == DUPLEX_FULL;
-		efx->link_up = sft9001_link_ok(efx, &ecmd);
-	}
-	efx->link_fc = efx_mdio_get_pause(efx);
+	return 0;
 }
 
-/* Poll PHY for interrupt */
-static void tenxpress_phy_poll(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
+
+/* Poll for link state changes */
+static bool tenxpress_phy_poll(struct efx_nic *efx)
 {
-	struct tenxpress_phy_data *phy_data = efx->phy_data;
-	bool change = false;
+	struct efx_link_state old_state = efx->link_state;
 
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
-		bool link_ok = sfx7101_link_ok(efx);
-		if (link_ok != efx->link_up) {
-			change = true;
-		} else {
-			unsigned int link_fc = efx_mdio_get_pause(efx);
-			if (link_fc != efx->link_fc)
-				change = true;
-		}
-		sfx7101_check_bad_lp(efx, link_ok);
-	} else if (efx->loopback_mode) {
-		bool link_ok = sft9001_link_ok(efx, NULL);
-		if (link_ok != efx->link_up)
-			change = true;
+		efx->link_state.up = sfx7101_link_ok(efx);
+		efx->link_state.speed = 10000;
+		efx->link_state.fd = true;
+		efx->link_state.fc = efx_mdio_get_pause(efx);
+
+		sfx7101_check_bad_lp(efx, efx->link_state.up);
 	} else {
-		int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
-					   MDIO_PMA_LASI_STAT);
-		if (status & MDIO_PMA_LASI_LSALARM)
-			change = true;
-	}
+		struct ethtool_cmd ecmd;
 
-	if (change)
-		falcon_sim_phy_event(efx);
+		/* Check the LASI alarm first */
+		if (efx->loopback_mode == LOOPBACK_NONE &&
+		    !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
+		      MDIO_PMA_LASI_LSALARM))
+			return false;
 
-	if (phy_data->phy_mode != PHY_MODE_NORMAL)
-		return;
+		tenxpress_get_settings(efx, &ecmd);
+
+		efx->link_state.up = sft9001_link_ok(efx, &ecmd);
+		efx->link_state.speed = ecmd.speed;
+		efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
+		efx->link_state.fc = efx_mdio_get_pause(efx);
+	}
+
+	return !efx_link_state_equal(&efx->link_state, &old_state);
 }
 
-static void tenxpress_phy_fini(struct efx_nic *efx)
+static void sfx7101_phy_fini(struct efx_nic *efx)
 {
 	int reg;
 
+	/* Power down the LNPGA */
+	reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
+
+	/* Waiting here ensures that the board fini, which can turn
+	 * off the power to the PHY, won't get run until the LNPGA
+	 * powerdown has been given long enough to complete. */
+	schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
+}
+
+static void tenxpress_phy_remove(struct efx_nic *efx)
+{
 	if (efx->phy_type == PHY_TYPE_SFT9001B)
 		device_remove_file(&efx->pci_dev->dev,
 				   &dev_attr_phy_short_reach);
 
-	if (efx->phy_type == PHY_TYPE_SFX7101) {
-		/* Power down the LNPGA */
-		reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
-		efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
-
-		/* Waiting here ensures that the board fini, which can turn
-		 * off the power to the PHY, won't get run until the LNPGA
-		 * powerdown has been given long enough to complete. */
-		schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
-	}
-
 	kfree(efx->phy_data);
 	efx->phy_data = NULL;
 }
 
 
-/* Set the RX and TX LEDs and Link LED flashing. The other LEDs
- * (which probably aren't wired anyway) are left in AUTO mode */
-void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
+/* Override the RX, TX and link LEDs */
+void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 {
 	int reg;
 
-	if (blink)
-		reg = (PMA_PMD_LED_FLASH << PMA_PMD_LED_TX_LBN) |
-			(PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN) |
-			(PMA_PMD_LED_FLASH << PMA_PMD_LED_LINK_LBN);
-	else
-		reg = PMA_PMD_LED_DEFAULT;
+	switch (mode) {
+	case EFX_LED_OFF:
+		reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
+			(PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
+			(PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
+		break;
+	case EFX_LED_ON:
+		reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
+			(PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
+			(PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
+		break;
+	default:
+		if (efx->phy_type == PHY_TYPE_SFX7101)
+			reg = SFX7101_PMA_PMD_LED_DEFAULT;
+		else
+			reg = SFT9001_PMA_PMD_LED_DEFAULT;
+		break;
+	}
 
 	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
 }
@@ -624,6 +658,13 @@ static const char *const sfx7101_test_na
 	"bist"
 };
 
+static const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index)
+{
+	if (index < ARRAY_SIZE(sfx7101_test_names))
+		return sfx7101_test_names[index];
+	return NULL;
+}
+
 static int
 sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
@@ -635,6 +676,9 @@ sfx7101_run_tests(struct efx_nic *efx, i
 	/* BIST is automatically run after a special software reset */
 	rc = tenxpress_special_reset(efx);
 	results[0] = rc ? -1 : 1;
+
+	efx_mdio_an_reconfigure(efx);
+
 	return rc;
 }
 
@@ -650,14 +694,17 @@ static const char *const sft9001_test_na
 	"cable.pairD.length",
 };
 
+static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index)
+{
+	if (index < ARRAY_SIZE(sft9001_test_names))
+		return sft9001_test_names[index];
+	return NULL;
+}
+
 static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
-	struct ethtool_cmd ecmd;
 	int rc = 0, rc2, i, ctrl_reg, res_reg;
 
-	if (flags & ETH_TEST_FL_OFFLINE)
-		efx->phy_op->get_settings(efx, &ecmd);
-
 	/* Initialise cable diagnostic results to unknown failure */
 	for (i = 1; i < 9; ++i)
 		results[i] = -1;
@@ -709,9 +756,7 @@ out:
 		if (!rc)
 			rc = rc2;
 
-		rc2 = efx->phy_op->set_settings(efx, &ecmd);
-		if (!rc)
-			rc = rc2;
+		efx_mdio_an_reconfigure(efx);
 	}
 
 	return rc;
@@ -758,7 +803,7 @@ tenxpress_get_settings(struct efx_nic *e
 	 * but doesn't advertise the correct speed. So override it */
 	if (efx->loopback_mode == LOOPBACK_GPHY)
 		ecmd->speed = SPEED_1000;
-	else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+	else if (LOOPBACK_EXTERNAL(efx))
 		ecmd->speed = SPEED_10000;
 }
 
@@ -788,35 +833,29 @@ static void sft9001_set_npage_adv(struct
 }
 
 struct efx_phy_operations falcon_sfx7101_phy_ops = {
-	.macs		  = EFX_XMAC,
+	.probe		  = tenxpress_phy_probe,
 	.init             = tenxpress_phy_init,
 	.reconfigure      = tenxpress_phy_reconfigure,
 	.poll             = tenxpress_phy_poll,
-	.fini             = tenxpress_phy_fini,
-	.clear_interrupt  = efx_port_dummy_op_void,
+	.fini             = sfx7101_phy_fini,
+	.remove		  = tenxpress_phy_remove,
 	.get_settings	  = tenxpress_get_settings,
 	.set_settings	  = tenxpress_set_settings,
 	.set_npage_adv    = sfx7101_set_npage_adv,
-	.num_tests	  = ARRAY_SIZE(sfx7101_test_names),
-	.test_names	  = sfx7101_test_names,
+	.test_name	  = sfx7101_test_name,
 	.run_tests	  = sfx7101_run_tests,
-	.mmds             = TENXPRESS_REQUIRED_DEVS,
-	.loopbacks        = SFX7101_LOOPBACKS,
 };
 
 struct efx_phy_operations falcon_sft9001_phy_ops = {
-	.macs		  = EFX_GMAC | EFX_XMAC,
+	.probe		  = tenxpress_phy_probe,
 	.init             = tenxpress_phy_init,
 	.reconfigure      = tenxpress_phy_reconfigure,
 	.poll             = tenxpress_phy_poll,
-	.fini             = tenxpress_phy_fini,
-	.clear_interrupt  = efx_port_dummy_op_void,
+	.fini             = efx_port_dummy_op_void,
+	.remove		  = tenxpress_phy_remove,
 	.get_settings	  = tenxpress_get_settings,
 	.set_settings	  = tenxpress_set_settings,
 	.set_npage_adv    = sft9001_set_npage_adv,
-	.num_tests	  = ARRAY_SIZE(sft9001_test_names),
-	.test_names	  = sft9001_test_names,
+	.test_name	  = sft9001_test_name,
 	.run_tests	  = sft9001_run_tests,
-	.mmds             = TENXPRESS_REQUIRED_DEVS,
-	.loopbacks        = SFT9001_LOOPBACKS,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/tx.c linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2005-2008 Solarflare Communications Inc.
+ * Copyright 2005-2009 Solarflare Communications 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
@@ -12,12 +12,13 @@
 #include <linux/tcp.h>
 #include <linux/ip.h>
 #include <linux/in.h>
+#include <linux/ipv6.h>
+#include <net/ipv6.h>
 #include <linux/if_ether.h>
 #include <linux/highmem.h>
 #include "net_driver.h"
-#include "tx.h"
 #include "efx.h"
-#include "falcon.h"
+#include "nic.h"
 #include "workarounds.h"
 
 /*
@@ -26,8 +27,7 @@
  * The tx_queue descriptor ring fill-level must fall below this value
  * before we restart the netif queue
  */
-#define EFX_NETDEV_TX_THRESHOLD(_tx_queue)	\
-	(_tx_queue->efx->type->txd_ring_mask / 2u)
+#define EFX_TXQ_THRESHOLD (EFX_TXQ_MASK / 2u)
 
 /* We want to be able to nest calls to netif_stop_queue(), since each
  * channel can have an individual stop on the queue.
@@ -125,6 +125,24 @@ static void efx_tsoh_free(struct efx_tx_
 }
 
 
+static inline unsigned
+efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
+{
+	/* Depending on the NIC revision, we can use descriptor
+	 * lengths up to 8K or 8K-1.  However, since PCI Express
+	 * devices must split read requests at 4K boundaries, there is
+	 * little benefit from using descriptors that cross those
+	 * boundaries and we keep things simple by not doing so.
+	 */
+	unsigned len = (~dma_addr & 0xfff) + 1;
+
+	/* Work around hardware bug for unaligned buffers. */
+	if (EFX_WORKAROUND_5391(efx) && (dma_addr & 0xf))
+		len = min_t(unsigned, len, 512 - (dma_addr & 0xf));
+
+	return len;
+}
+
 /*
  * Add a socket buffer to a TX queue
  *
@@ -135,11 +153,13 @@ static void efx_tsoh_free(struct efx_tx_
  * If any DMA mapping fails, any mapped fragments will be unmapped,
  * the queue's insert pointer will be restored to its original value.
  *
+ * This function is split out from efx_hard_start_xmit to allow the
+ * loopback test to direct packets via specific TX queues.
+ *
  * Returns NETDEV_TX_OK or NETDEV_TX_BUSY
  * You must hold netif_tx_lock() to call this function.
  */
-static netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
-					 struct sk_buff *skb)
+netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
 {
 	struct efx_nic *efx = tx_queue->efx;
 	struct pci_dev *pci_dev = efx->pci_dev;
@@ -147,7 +167,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 	skb_frag_t *fragment;
 	struct page *page;
 	int page_offset;
-	unsigned int len, unmap_len = 0, fill_level, insert_ptr, misalign;
+	unsigned int len, unmap_len = 0, fill_level, insert_ptr;
 	dma_addr_t dma_addr, unmap_addr = 0;
 	unsigned int dma_len;
 	bool unmap_single;
@@ -156,7 +176,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 
 	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
 
-	if (skb_shinfo((struct sk_buff *)skb)->gso_size)
+	if (skb_shinfo(skb)->gso_size)
 		return efx_enqueue_skb_tso(tx_queue, skb);
 
 	/* Get size of the initial fragment */
@@ -171,7 +191,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 	}
 
 	fill_level = tx_queue->insert_count - tx_queue->old_read_count;
-	q_space = efx->type->txd_ring_mask - 1 - fill_level;
+	q_space = EFX_TXQ_MASK - 1 - fill_level;
 
 	/* Map for DMA.  Use pci_map_single rather than pci_map_page
 	 * since this is more efficient on machines with sparse
@@ -208,16 +228,14 @@ static netdev_tx_t efx_enqueue_skb(struc
 					&tx_queue->read_count;
 				fill_level = (tx_queue->insert_count
 					      - tx_queue->old_read_count);
-				q_space = (efx->type->txd_ring_mask - 1 -
-					   fill_level);
+				q_space = EFX_TXQ_MASK - 1 - fill_level;
 				if (unlikely(q_space-- <= 0))
 					goto stop;
 				smp_mb();
 				--tx_queue->stopped;
 			}
 
-			insert_ptr = (tx_queue->insert_count &
-				      efx->type->txd_ring_mask);
+			insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
 			buffer = &tx_queue->buffer[insert_ptr];
 			efx_tsoh_free(tx_queue, buffer);
 			EFX_BUG_ON_PARANOID(buffer->tsoh);
@@ -226,14 +244,10 @@ static netdev_tx_t efx_enqueue_skb(struc
 			EFX_BUG_ON_PARANOID(!buffer->continuation);
 			EFX_BUG_ON_PARANOID(buffer->unmap_len);
 
-			dma_len = (((~dma_addr) & efx->type->tx_dma_mask) + 1);
-			if (likely(dma_len > len))
+			dma_len = efx_max_tx_len(efx, dma_addr);
+			if (likely(dma_len >= len))
 				dma_len = len;
 
-			misalign = (unsigned)dma_addr & efx->type->bug5391_mask;
-			if (misalign && dma_len + misalign > 512)
-				dma_len = 512 - misalign;
-
 			/* Fill out per descriptor fields */
 			buffer->len = dma_len;
 			buffer->dma_addr = dma_addr;
@@ -266,7 +280,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 	buffer->continuation = false;
 
 	/* Pass off to hardware */
-	falcon_push_buffers(tx_queue);
+	efx_nic_push_buffers(tx_queue);
 
 	return NETDEV_TX_OK;
 
@@ -276,7 +290,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 		   skb_shinfo(skb)->nr_frags + 1);
 
 	/* Mark the packet as transmitted, and free the SKB ourselves */
-	dev_kfree_skb_any((struct sk_buff *)skb);
+	dev_kfree_skb_any(skb);
 	goto unwind;
 
  stop:
@@ -289,7 +303,7 @@ static netdev_tx_t efx_enqueue_skb(struc
 	/* Work backwards until we hit the original insert pointer value */
 	while (tx_queue->insert_count != tx_queue->write_count) {
 		--tx_queue->insert_count;
-		insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask;
+		insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
 		buffer = &tx_queue->buffer[insert_ptr];
 		efx_dequeue_buffer(tx_queue, buffer);
 		buffer->len = 0;
@@ -318,10 +332,9 @@ static void efx_dequeue_buffers(struct e
 {
 	struct efx_nic *efx = tx_queue->efx;
 	unsigned int stop_index, read_ptr;
-	unsigned int mask = tx_queue->efx->type->txd_ring_mask;
 
-	stop_index = (index + 1) & mask;
-	read_ptr = tx_queue->read_count & mask;
+	stop_index = (index + 1) & EFX_TXQ_MASK;
+	read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
 
 	while (read_ptr != stop_index) {
 		struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
@@ -338,28 +351,10 @@ static void efx_dequeue_buffers(struct e
 		buffer->len = 0;
 
 		++tx_queue->read_count;
-		read_ptr = tx_queue->read_count & mask;
+		read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
 	}
 }
 
-/* Initiate a packet transmission on the specified TX queue.
- * Note that returning anything other than NETDEV_TX_OK will cause the
- * OS to free the skb.
- *
- * This function is split out from efx_hard_start_xmit to allow the
- * loopback test to direct packets via specific TX queues.  It is
- * therefore a non-static inline, so as not to penalise performance
- * for non-loopback transmissions.
- *
- * Context: netif_tx_lock held
- */
-inline netdev_tx_t efx_xmit(struct efx_nic *efx,
-			   struct efx_tx_queue *tx_queue, struct sk_buff *skb)
-{
-	/* Map fragments for DMA and add to TX queue */
-	return efx_enqueue_skb(tx_queue, skb);
-}
-
 /* Initiate a packet transmission.  We use one channel per CPU
  * (sharing when we have more CPUs than channels).  On Falcon, the TX
  * completion events will be directed back to the CPU that transmitted
@@ -383,7 +378,7 @@ netdev_tx_t efx_hard_start_xmit(struct s
 	else
 		tx_queue = &efx->tx_queue[EFX_TX_QUEUE_NO_CSUM];
 
-	return efx_xmit(efx, tx_queue, skb);
+	return efx_enqueue_skb(tx_queue, skb);
 }
 
 void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
@@ -391,7 +386,7 @@ void efx_xmit_done(struct efx_tx_queue *
 	unsigned fill_level;
 	struct efx_nic *efx = tx_queue->efx;
 
-	EFX_BUG_ON_PARANOID(index > efx->type->txd_ring_mask);
+	EFX_BUG_ON_PARANOID(index > EFX_TXQ_MASK);
 
 	efx_dequeue_buffers(tx_queue, index);
 
@@ -401,7 +396,7 @@ void efx_xmit_done(struct efx_tx_queue *
 	smp_mb();
 	if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
 		fill_level = tx_queue->insert_count - tx_queue->read_count;
-		if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) {
+		if (fill_level < EFX_TXQ_THRESHOLD) {
 			EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
 
 			/* Do this under netif_tx_lock(), to avoid racing
@@ -425,15 +420,15 @@ int efx_probe_tx_queue(struct efx_tx_que
 	EFX_LOG(efx, "creating TX queue %d\n", tx_queue->queue);
 
 	/* Allocate software ring */
-	txq_size = (efx->type->txd_ring_mask + 1) * sizeof(*tx_queue->buffer);
+	txq_size = EFX_TXQ_SIZE * sizeof(*tx_queue->buffer);
 	tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
 	if (!tx_queue->buffer)
 		return -ENOMEM;
-	for (i = 0; i <= efx->type->txd_ring_mask; ++i)
+	for (i = 0; i <= EFX_TXQ_MASK; ++i)
 		tx_queue->buffer[i].continuation = true;
 
 	/* Allocate hardware ring */
-	rc = falcon_probe_tx(tx_queue);
+	rc = efx_nic_probe_tx(tx_queue);
 	if (rc)
 		goto fail;
 
@@ -456,7 +451,7 @@ void efx_init_tx_queue(struct efx_tx_que
 	BUG_ON(tx_queue->stopped);
 
 	/* Set up TX descriptor ring */
-	falcon_init_tx(tx_queue);
+	efx_nic_init_tx(tx_queue);
 }
 
 void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
@@ -468,8 +463,7 @@ void efx_release_tx_buffers(struct efx_t
 
 	/* Free any buffers left in the ring */
 	while (tx_queue->read_count != tx_queue->write_count) {
-		buffer = &tx_queue->buffer[tx_queue->read_count &
-					   tx_queue->efx->type->txd_ring_mask];
+		buffer = &tx_queue->buffer[tx_queue->read_count & EFX_TXQ_MASK];
 		efx_dequeue_buffer(tx_queue, buffer);
 		buffer->continuation = true;
 		buffer->len = 0;
@@ -483,7 +477,7 @@ void efx_fini_tx_queue(struct efx_tx_que
 	EFX_LOG(tx_queue->efx, "shutting down TX queue %d\n", tx_queue->queue);
 
 	/* Flush TX queue, remove descriptor ring */
-	falcon_fini_tx(tx_queue);
+	efx_nic_fini_tx(tx_queue);
 
 	efx_release_tx_buffers(tx_queue);
 
@@ -500,7 +494,7 @@ void efx_fini_tx_queue(struct efx_tx_que
 void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
 {
 	EFX_LOG(tx_queue->efx, "destroying TX queue %d\n", tx_queue->queue);
-	falcon_remove_tx(tx_queue);
+	efx_nic_remove_tx(tx_queue);
 
 	kfree(tx_queue->buffer);
 	tx_queue->buffer = NULL;
@@ -539,6 +533,7 @@ void efx_remove_tx_queue(struct efx_tx_q
 #define ETH_HDR_LEN(skb)  (skb_network_header(skb) - (skb)->data)
 #define SKB_TCP_OFF(skb)  PTR_DIFF(tcp_hdr(skb), (skb)->data)
 #define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data)
+#define SKB_IPV6_OFF(skb) PTR_DIFF(ipv6_hdr(skb), (skb)->data)
 
 /**
  * struct tso_state - TSO state for an SKB
@@ -551,6 +546,7 @@ void efx_remove_tx_queue(struct efx_tx_q
  * @unmap_len: Length of SKB fragment
  * @unmap_addr: DMA address of SKB fragment
  * @unmap_single: DMA single vs page mapping flag
+ * @protocol: Network protocol (after any VLAN header)
  * @header_len: Number of bytes of header
  * @full_packet_size: Number of bytes to put in each outgoing segment
  *
@@ -571,6 +567,7 @@ struct tso_state {
 	dma_addr_t unmap_addr;
 	bool unmap_single;
 
+	__be16 protocol;
 	unsigned header_len;
 	int full_packet_size;
 };
@@ -578,9 +575,9 @@ struct tso_state {
 
 /*
  * Verify that our various assumptions about sk_buffs and the conditions
- * under which TSO will be attempted hold true.
+ * under which TSO will be attempted hold true.  Return the protocol number.
  */
-static void efx_tso_check_safe(struct sk_buff *skb)
+static __be16 efx_tso_check_protocol(struct sk_buff *skb)
 {
 	__be16 protocol = skb->protocol;
 
@@ -595,13 +592,22 @@ static void efx_tso_check_safe(struct sk
 		if (protocol == htons(ETH_P_IP))
 			skb_set_transport_header(skb, sizeof(*veh) +
 						 4 * ip_hdr(skb)->ihl);
+		else if (protocol == htons(ETH_P_IPV6))
+			skb_set_transport_header(skb, sizeof(*veh) +
+						 sizeof(struct ipv6hdr));
 	}
 
-	EFX_BUG_ON_PARANOID(protocol != htons(ETH_P_IP));
-	EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
+	if (protocol == htons(ETH_P_IP)) {
+		EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
+	} else {
+		EFX_BUG_ON_PARANOID(protocol != htons(ETH_P_IPV6));
+		EFX_BUG_ON_PARANOID(ipv6_hdr(skb)->nexthdr != NEXTHDR_TCP);
+	}
 	EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data)
 			     + (tcp_hdr(skb)->doff << 2u)) >
 			    skb_headlen(skb));
+
+	return protocol;
 }
 
 
@@ -708,14 +714,14 @@ static int efx_tx_queue_insert(struct ef
 {
 	struct efx_tx_buffer *buffer;
 	struct efx_nic *efx = tx_queue->efx;
-	unsigned dma_len, fill_level, insert_ptr, misalign;
+	unsigned dma_len, fill_level, insert_ptr;
 	int q_space;
 
 	EFX_BUG_ON_PARANOID(len <= 0);
 
 	fill_level = tx_queue->insert_count - tx_queue->old_read_count;
 	/* -1 as there is no way to represent all descriptors used */
-	q_space = efx->type->txd_ring_mask - 1 - fill_level;
+	q_space = EFX_TXQ_MASK - 1 - fill_level;
 
 	while (1) {
 		if (unlikely(q_space-- <= 0)) {
@@ -731,7 +737,7 @@ static int efx_tx_queue_insert(struct ef
 				*(volatile unsigned *)&tx_queue->read_count;
 			fill_level = (tx_queue->insert_count
 				      - tx_queue->old_read_count);
-			q_space = efx->type->txd_ring_mask - 1 - fill_level;
+			q_space = EFX_TXQ_MASK - 1 - fill_level;
 			if (unlikely(q_space-- <= 0)) {
 				*final_buffer = NULL;
 				return 1;
@@ -740,13 +746,13 @@ static int efx_tx_queue_insert(struct ef
 			--tx_queue->stopped;
 		}
 
-		insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask;
+		insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
 		buffer = &tx_queue->buffer[insert_ptr];
 		++tx_queue->insert_count;
 
 		EFX_BUG_ON_PARANOID(tx_queue->insert_count -
 				    tx_queue->read_count >
-				    efx->type->txd_ring_mask);
+				    EFX_TXQ_MASK);
 
 		efx_tsoh_free(tx_queue, buffer);
 		EFX_BUG_ON_PARANOID(buffer->len);
@@ -757,12 +763,7 @@ static int efx_tx_queue_insert(struct ef
 
 		buffer->dma_addr = dma_addr;
 
-		/* Ensure we do not cross a boundary unsupported by H/W */
-		dma_len = (~dma_addr & efx->type->tx_dma_mask) + 1;
-
-		misalign = (unsigned)dma_addr & efx->type->bug5391_mask;
-		if (misalign && dma_len + misalign > 512)
-			dma_len = 512 - misalign;
+		dma_len = efx_max_tx_len(efx, dma_addr);
 
 		/* If there is enough space to send then do so */
 		if (dma_len >= len)
@@ -792,8 +793,7 @@ static void efx_tso_put_header(struct ef
 {
 	struct efx_tx_buffer *buffer;
 
-	buffer = &tx_queue->buffer[tx_queue->insert_count &
-				   tx_queue->efx->type->txd_ring_mask];
+	buffer = &tx_queue->buffer[tx_queue->insert_count & EFX_TXQ_MASK];
 	efx_tsoh_free(tx_queue, buffer);
 	EFX_BUG_ON_PARANOID(buffer->len);
 	EFX_BUG_ON_PARANOID(buffer->unmap_len);
@@ -818,11 +818,9 @@ static void efx_enqueue_unwind(struct ef
 	while (tx_queue->insert_count != tx_queue->write_count) {
 		--tx_queue->insert_count;
 		buffer = &tx_queue->buffer[tx_queue->insert_count &
-					   tx_queue->efx->type->txd_ring_mask];
+					   EFX_TXQ_MASK];
 		efx_tsoh_free(tx_queue, buffer);
 		EFX_BUG_ON_PARANOID(buffer->skb);
-		buffer->len = 0;
-		buffer->continuation = true;
 		if (buffer->unmap_len) {
 			unmap_addr = (buffer->dma_addr + buffer->len -
 				      buffer->unmap_len);
@@ -836,6 +834,8 @@ static void efx_enqueue_unwind(struct ef
 					       PCI_DMA_TODEVICE);
 			buffer->unmap_len = 0;
 		}
+		buffer->len = 0;
+		buffer->continuation = true;
 	}
 }
 
@@ -850,7 +850,10 @@ static void tso_start(struct tso_state *
 			  + PTR_DIFF(tcp_hdr(skb), skb->data));
 	st->full_packet_size = st->header_len + skb_shinfo(skb)->gso_size;
 
-	st->ipv4_id = ntohs(ip_hdr(skb)->id);
+	if (st->protocol == htons(ETH_P_IP))
+		st->ipv4_id = ntohs(ip_hdr(skb)->id);
+	else
+		st->ipv4_id = 0;
 	st->seqnum = ntohl(tcp_hdr(skb)->seq);
 
 	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg);
@@ -965,7 +968,6 @@ static int tso_start_new_packet(struct e
 				struct tso_state *st)
 {
 	struct efx_tso_header *tsoh;
-	struct iphdr *tsoh_iph;
 	struct tcphdr *tsoh_th;
 	unsigned ip_length;
 	u8 *header;
@@ -989,7 +991,6 @@ static int tso_start_new_packet(struct e
 
 	header = TSOH_BUFFER(tsoh);
 	tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb));
-	tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb));
 
 	/* Copy and update the headers. */
 	memcpy(header, skb->data, st->header_len);
@@ -1007,11 +1008,22 @@ static int tso_start_new_packet(struct e
 		tsoh_th->fin = tcp_hdr(skb)->fin;
 		tsoh_th->psh = tcp_hdr(skb)->psh;
 	}
-	tsoh_iph->tot_len = htons(ip_length);
 
-	/* Linux leaves suitable gaps in the IP ID space for us to fill. */
-	tsoh_iph->id = htons(st->ipv4_id);
-	st->ipv4_id++;
+	if (st->protocol == htons(ETH_P_IP)) {
+		struct iphdr *tsoh_iph =
+			(struct iphdr *)(header + SKB_IPV4_OFF(skb));
+
+		tsoh_iph->tot_len = htons(ip_length);
+
+		/* Linux leaves suitable gaps in the IP ID space for us to fill. */
+		tsoh_iph->id = htons(st->ipv4_id);
+		st->ipv4_id++;
+	} else {
+		struct ipv6hdr *tsoh_iph =
+			(struct ipv6hdr *)(header + SKB_IPV6_OFF(skb));
+
+		tsoh_iph->payload_len = htons(ip_length - sizeof(*tsoh_iph));
+	}
 
 	st->packet_space = skb_shinfo(skb)->gso_size;
 	++tx_queue->tso_packets;
@@ -1041,8 +1053,8 @@ static int efx_enqueue_skb_tso(struct ef
 	int frag_i, rc, rc2 = NETDEV_TX_OK;
 	struct tso_state state;
 
-	/* Verify TSO is safe - these checks should never fail. */
-	efx_tso_check_safe(skb);
+	/* Find the packet protocol and sanity-check it */
+	state.protocol = efx_tso_check_protocol(skb);
 
 	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
 
@@ -1092,14 +1104,14 @@ static int efx_enqueue_skb_tso(struct ef
 	}
 
 	/* Pass off to hardware */
-	falcon_push_buffers(tx_queue);
+	efx_nic_push_buffers(tx_queue);
 
 	tx_queue->tso_bursts++;
 	return NETDEV_TX_OK;
 
  mem_err:
 	EFX_ERR(efx, "Out of memory for TSO headers, or PCI mapping error\n");
-	dev_kfree_skb_any((struct sk_buff *)skb);
+	dev_kfree_skb_any(skb);
 	goto unwind;
 
  stop:
@@ -1135,7 +1147,7 @@ static void efx_fini_tso(struct efx_tx_q
 	unsigned i;
 
 	if (tx_queue->buffer) {
-		for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i)
+		for (i = 0; i <= EFX_TXQ_MASK; ++i)
 			efx_tsoh_free(tx_queue, &tx_queue->buffer[i]);
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/tx.h linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/tx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/tx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_TX_H
-#define EFX_TX_H
-
-#include "net_driver.h"
-
-int efx_probe_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
-
-netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
-				      struct net_device *net_dev);
-void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
-
-#endif /* EFX_TX_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/workarounds.h linux-libre-2.6.33-gnu1/drivers/net/sfc/workarounds.h
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/workarounds.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/workarounds.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006-2008 Solarflare Communications Inc.
+ * Copyright 2006-2009 Solarflare Communications 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
@@ -16,7 +16,9 @@
  */
 
 #define EFX_WORKAROUND_ALWAYS(efx) 1
-#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
+#define EFX_WORKAROUND_FALCON_A(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_A1)
+#define EFX_WORKAROUND_FALCON_AB(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_B0)
+#define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0)
 #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
 #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
 				     (efx)->phy_type == PHY_TYPE_SFT9001B)
@@ -27,20 +29,22 @@
 #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
 /* Bit-bashed I2C reads cause performance drop */
 #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
-/* TX pkt parser problem with <= 16 byte TXes */
-#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
  * or a PCIe error (bug 11028) */
 #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
 /* Transmit flow control may get disabled */
-#define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS
-/* Flush events can take a very long time to appear */
-#define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS
+#define EFX_WORKAROUND_11482 EFX_WORKAROUND_FALCON_AB
 /* Truncated IPv4 packets can confuse the TX packet parser */
-#define EFX_WORKAROUND_15592 EFX_WORKAROUND_ALWAYS
+#define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB
+/* Legacy ISR read can return zero once */
+#define EFX_WORKAROUND_15783 EFX_WORKAROUND_SIENA
+/* Legacy interrupt storm when interrupt fifo fills */
+#define EFX_WORKAROUND_17213 EFX_WORKAROUND_SIENA
 
 /* Spurious parity errors in TSORT buffers */
 #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
+/* Unaligned read request >512 bytes after aligning may break TSORT */
+#define EFX_WORKAROUND_5391 EFX_WORKAROUND_FALCON_A
 /* iSCSI parsing errors */
 #define EFX_WORKAROUND_5583 EFX_WORKAROUND_FALCON_A
 /* RX events go missing */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sfc/xfp_phy.c linux-libre-2.6.33-gnu1/drivers/net/sfc/xfp_phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/sfc/xfp_phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sfc/xfp_phy.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,250 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006-2008 Solarflare Communications 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, incorporated herein by reference.
- */
-/*
- * Driver for SFP+ and XFP optical PHYs plus some support specific to the
- * AMCC QT20xx adapters; see www.amcc.com for details
- */
-
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include "efx.h"
-#include "mdio_10g.h"
-#include "phy.h"
-#include "falcon.h"
-
-#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS |	\
-			   MDIO_DEVS_PMAPMD |	\
-			   MDIO_DEVS_PHYXS)
-
-#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
-		       (1 << LOOPBACK_PMAPMD) |		\
-		       (1 << LOOPBACK_NETWORK))
-
-/****************************************************************************/
-/* Quake-specific MDIO registers */
-#define MDIO_QUAKE_LED0_REG	(0xD006)
-
-/* QT2025C only */
-#define PCS_FW_HEARTBEAT_REG	0xd7ee
-#define PCS_FW_HEARTB_LBN	0
-#define PCS_FW_HEARTB_WIDTH	8
-#define PCS_UC8051_STATUS_REG	0xd7fd
-#define PCS_UC_STATUS_LBN	0
-#define PCS_UC_STATUS_WIDTH	8
-#define PCS_UC_STATUS_FW_SAVE	0x20
-#define PMA_PMD_FTX_CTRL2_REG	0xc309
-#define PMA_PMD_FTX_STATIC_LBN	13
-#define PMA_PMD_VEND1_REG	0xc001
-#define PMA_PMD_VEND1_LBTXD_LBN	15
-#define PCS_VEND1_REG	   	0xc000
-#define PCS_VEND1_LBTXD_LBN	5
-
-void xfp_set_led(struct efx_nic *p, int led, int mode)
-{
-	int addr = MDIO_QUAKE_LED0_REG + led;
-	efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
-}
-
-struct xfp_phy_data {
-	enum efx_phy_mode phy_mode;
-};
-
-#define XFP_MAX_RESET_TIME 500
-#define XFP_RESET_WAIT 10
-
-static int qt2025c_wait_reset(struct efx_nic *efx)
-{
-	unsigned long timeout = jiffies + 10 * HZ;
-	int reg, old_counter = 0;
-
-	/* Wait for firmware heartbeat to start */
-	for (;;) {
-		int counter;
-		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
-		if (reg < 0)
-			return reg;
-		counter = ((reg >> PCS_FW_HEARTB_LBN) &
-			    ((1 << PCS_FW_HEARTB_WIDTH) - 1));
-		if (old_counter == 0)
-			old_counter = counter;
-		else if (counter != old_counter)
-			break;
-		if (time_after(jiffies, timeout))
-			return -ETIMEDOUT;
-		msleep(10);
-	}
-
-	/* Wait for firmware status to look good */
-	for (;;) {
-		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
-		if (reg < 0)
-			return reg;
-		if ((reg &
-		     ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
-		    PCS_UC_STATUS_FW_SAVE)
-			break;
-		if (time_after(jiffies, timeout))
-			return -ETIMEDOUT;
-		msleep(100);
-	}
-
-	return 0;
-}
-
-static int xfp_reset_phy(struct efx_nic *efx)
-{
-	int rc;
-
-	if (efx->phy_type == PHY_TYPE_QT2025C) {
-		/* Wait for the reset triggered by falcon_reset_hw()
-		 * to complete */
-		rc = qt2025c_wait_reset(efx);
-		if (rc < 0)
-			goto fail;
-	} else {
-		/* Reset the PHYXS MMD. This is documented as doing
-		 * a complete soft reset. */
-		rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
-					XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
-					XFP_RESET_WAIT);
-		if (rc < 0)
-			goto fail;
-	}
-
-	/* Wait 250ms for the PHY to complete bootup */
-	msleep(250);
-
-	/* Check that all the MMDs we expect are present and responding. We
-	 * expect faults on some if the link is down, but not on the PHY XS */
-	rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
-	if (rc < 0)
-		goto fail;
-
-	efx->board_info.init_leds(efx);
-
-	return rc;
-
- fail:
-	EFX_ERR(efx, "PHY reset timed out\n");
-	return rc;
-}
-
-static int xfp_phy_init(struct efx_nic *efx)
-{
-	struct xfp_phy_data *phy_data;
-	u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
-	int rc;
-
-	phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
-	if (!phy_data)
-		return -ENOMEM;
-	efx->phy_data = phy_data;
-
-	EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
-		 devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
-		 efx_mdio_id_rev(devid));
-
-	phy_data->phy_mode = efx->phy_mode;
-
-	rc = xfp_reset_phy(efx);
-
-	EFX_INFO(efx, "PHY init %s.\n",
-		 rc ? "failed" : "successful");
-	if (rc < 0)
-		goto fail;
-
-	return 0;
-
- fail:
-	kfree(efx->phy_data);
-	efx->phy_data = NULL;
-	return rc;
-}
-
-static void xfp_phy_clear_interrupt(struct efx_nic *efx)
-{
-	/* Read to clear link status alarm */
-	efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT);
-}
-
-static int xfp_link_ok(struct efx_nic *efx)
-{
-	return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS);
-}
-
-static void xfp_phy_poll(struct efx_nic *efx)
-{
-	int link_up = xfp_link_ok(efx);
-	/* Simulate a PHY event if link state has changed */
-	if (link_up != efx->link_up)
-		falcon_sim_phy_event(efx);
-}
-
-static void xfp_phy_reconfigure(struct efx_nic *efx)
-{
-	struct xfp_phy_data *phy_data = efx->phy_data;
-
-	if (efx->phy_type == PHY_TYPE_QT2025C) {
-		/* There are several different register bits which can
-		 * disable TX (and save power) on direct-attach cables
-		 * or optical transceivers, varying somewhat between
-		 * firmware versions.  Only 'static mode' appears to
-		 * cover everything. */
-		mdio_set_flag(
-			&efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
-			PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
-			efx->phy_mode & PHY_MODE_TX_DISABLED ||
-			efx->phy_mode & PHY_MODE_LOW_POWER ||
-			efx->loopback_mode == LOOPBACK_PCS ||
-			efx->loopback_mode == LOOPBACK_PMAPMD);
-	} else {
-		/* Reset the PHY when moving from tx off to tx on */
-		if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
-		    (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
-			xfp_reset_phy(efx);
-
-		efx_mdio_transmit_disable(efx);
-	}
-
-	efx_mdio_phy_reconfigure(efx);
-
-	phy_data->phy_mode = efx->phy_mode;
-	efx->link_up = xfp_link_ok(efx);
-	efx->link_speed = 10000;
-	efx->link_fd = true;
-	efx->link_fc = efx->wanted_fc;
-}
-
-static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
-	mdio45_ethtool_gset(&efx->mdio, ecmd);
-}
-
-static void xfp_phy_fini(struct efx_nic *efx)
-{
-	/* Clobber the LED if it was blinking */
-	efx->board_info.blink(efx, false);
-
-	/* Free the context block */
-	kfree(efx->phy_data);
-	efx->phy_data = NULL;
-}
-
-struct efx_phy_operations falcon_xfp_phy_ops = {
-	.macs		 = EFX_XMAC,
-	.init            = xfp_phy_init,
-	.reconfigure     = xfp_phy_reconfigure,
-	.poll            = xfp_phy_poll,
-	.fini            = xfp_phy_fini,
-	.clear_interrupt = xfp_phy_clear_interrupt,
-	.get_settings    = xfp_phy_get_settings,
-	.set_settings	 = efx_mdio_set_settings,
-	.mmds            = XFP_REQUIRED_DEVS,
-	.loopbacks       = XFP_LOOPBACKS,
-};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sgiseeq.c linux-libre-2.6.33-gnu1/drivers/net/sgiseeq.c
--- linux-libre-2.6.32-gnu1/drivers/net/sgiseeq.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sgiseeq.c	2010-02-24 13:52:17.000000000 -0500
@@ -365,11 +365,10 @@ static inline void sgiseeq_rx(struct net
 					}
 					skb_reserve(newskb, 2);
 				} else {
-					skb = netdev_alloc_skb(dev, len + 2);
-					if (skb) {
-						skb_reserve(skb, 2);
+					skb = netdev_alloc_skb_ip_align(dev, len);
+					if (skb)
 						skb_copy_to_linear_data(skb, rd->skb->data, len);
-					}
+
 					newskb = rd->skb;
 				}
 memory_squeeze:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sh_eth.c linux-libre-2.6.33-gnu1/drivers/net/sh_eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/sh_eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sh_eth.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/phy.h>
 #include <linux/cache.h>
 #include <linux/io.h>
+#include <linux/pm_runtime.h>
 #include <asm/cacheflush.h>
 
 #include "sh_eth.h"
@@ -83,6 +84,8 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.mpr		= 1,
 	.tpauser	= 1,
 	.hw_swap	= 1,
+	.rpadir		= 1,
+	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
 };
 
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
@@ -107,7 +110,7 @@ static void sh_eth_reset(struct net_devi
 		mdelay(1);
 		cnt--;
 	}
-	if (cnt < 0)
+	if (cnt == 0)
 		printk(KERN_ERR "Device reset fail\n");
 
 	/* Table Init */
@@ -174,7 +177,6 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.tpauser	= 1,
 	.bculr		= 1,
 	.hw_swap	= 1,
-	.rpadir		= 1,
 	.no_trimd	= 1,
 	.no_ade		= 1,
 };
@@ -299,16 +301,20 @@ static void update_mac_address(struct ne
  * When you want use this device, you must set MAC address in bootloader.
  *
  */
-static void read_mac_address(struct net_device *ndev)
+static void read_mac_address(struct net_device *ndev, unsigned char *mac)
 {
 	u32 ioaddr = ndev->base_addr;
 
-	ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
-	ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
-	ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
-	ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
-	ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
-	ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
+		memcpy(ndev->dev_addr, mac, 6);
+	} else {
+		ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
+		ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
+		ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
+		ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
+		ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
+		ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+	}
 }
 
 struct bb_info {
@@ -496,6 +502,8 @@ static int sh_eth_ring_init(struct net_d
 	 */
 	mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
 			  (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
+	if (mdp->cd->rpadir)
+		mdp->rx_buf_sz += NET_IP_ALIGN;
 
 	/* Allocate RX and TX skb rings */
 	mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
@@ -710,6 +718,8 @@ static int sh_eth_rx(struct net_device *
 					pkt_len + 2);
 			skb = mdp->rx_skbuff[entry];
 			mdp->rx_skbuff[entry] = NULL;
+			if (mdp->cd->rpadir)
+				skb_reserve(skb, NET_IP_ALIGN);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, ndev);
 			netif_rx(skb);
@@ -1009,7 +1019,9 @@ static int sh_eth_open(struct net_device
 	int ret = 0;
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
-	ret = request_irq(ndev->irq, &sh_eth_interrupt,
+	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)
 				IRQF_SHARED,
 #else
@@ -1045,6 +1057,7 @@ static int sh_eth_open(struct net_device
 
 out_free_irq:
 	free_irq(ndev->irq, ndev);
+	pm_runtime_put_sync(&mdp->pdev->dev);
 	return ret;
 }
 
@@ -1176,6 +1189,8 @@ static int sh_eth_close(struct net_devic
 	ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
 	dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
 
+	pm_runtime_put_sync(&mdp->pdev->dev);
+
 	return 0;
 }
 
@@ -1184,6 +1199,8 @@ static struct net_device_stats *sh_eth_g
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	u32 ioaddr = ndev->base_addr;
 
+	pm_runtime_get_sync(&mdp->pdev->dev);
+
 	mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
 	ctrl_outl(0, ioaddr + TROCR);	/* (write clear) */
 	mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
@@ -1199,6 +1216,8 @@ static struct net_device_stats *sh_eth_g
 	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
 	ctrl_outl(0, ioaddr + CNDCR);	/* (write clear) */
 #endif
+	pm_runtime_put_sync(&mdp->pdev->dev);
+
 	return &mdp->stats;
 }
 
@@ -1407,6 +1426,9 @@ static int sh_eth_drv_probe(struct platf
 
 	mdp = netdev_priv(ndev);
 	spin_lock_init(&mdp->lock);
+	mdp->pdev = pdev;
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_resume(&pdev->dev);
 
 	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
 	/* get PHY ID */
@@ -1428,7 +1450,7 @@ static int sh_eth_drv_probe(struct platf
 	mdp->post_fw = POST_FW >> (devno << 1);
 
 	/* read and set MAC address */
-	read_mac_address(ndev);
+	read_mac_address(ndev, pd->mac_addr);
 
 	/* First device only init */
 	if (!devno) {
@@ -1482,18 +1504,37 @@ static int sh_eth_drv_remove(struct plat
 	sh_mdio_release(ndev);
 	unregister_netdev(ndev);
 	flush_scheduled_work();
-
+	pm_runtime_disable(&pdev->dev);
 	free_netdev(ndev);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
+static int sh_eth_runtime_nop(struct device *dev)
+{
+	/*
+	 * Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_eth_dev_pm_ops = {
+	.runtime_suspend = sh_eth_runtime_nop,
+	.runtime_resume = sh_eth_runtime_nop,
+};
+
 static struct platform_driver sh_eth_driver = {
 	.probe = sh_eth_drv_probe,
 	.remove = sh_eth_drv_remove,
 	.driver = {
 		   .name = CARDNAME,
+		   .pm = &sh_eth_dev_pm_ops,
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sh_eth.h linux-libre-2.6.33-gnu1/drivers/net/sh_eth.h
--- linux-libre-2.6.32-gnu1/drivers/net/sh_eth.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sh_eth.h	2010-02-24 13:52:17.000000000 -0500
@@ -703,6 +703,7 @@ struct sh_eth_cpu_data {
 };
 
 struct sh_eth_private {
+	struct platform_device *pdev;
 	struct sh_eth_cpu_data *cd;
 	dma_addr_t rx_desc_dma;
 	dma_addr_t tx_desc_dma;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sis190.c linux-libre-2.6.33-gnu1/drivers/net/sis190.c
--- linux-libre-2.6.32-gnu1/drivers/net/sis190.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sis190.c	2010-02-24 13:52:17.000000000 -0500
@@ -536,13 +536,12 @@ static bool sis190_try_rx_copy(struct si
 	if (pkt_size >= rx_copybreak)
 		goto out;
 
-	skb = netdev_alloc_skb(tp->dev, pkt_size + 2);
+	skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
 	if (!skb)
 		goto out;
 
 	pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);
-	skb_reserve(skb, 2);
 	skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
 	*sk_buff = skb;
 	done = true;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sis900.c linux-libre-2.6.33-gnu1/drivers/net/sis900.c
--- linux-libre-2.6.32-gnu1/drivers/net/sis900.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sis900.c	2010-02-24 13:52:17.000000000 -0500
@@ -1016,7 +1016,7 @@ sis900_open(struct net_device *net_dev)
 	/* Equalizer workaround Rule */
 	sis630_set_eq(net_dev, sis_priv->chipset_rev);
 
-	ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED,
+	ret = request_irq(net_dev->irq, sis900_interrupt, IRQF_SHARED,
 						net_dev->name, net_dev);
 	if (ret)
 		return ret;
@@ -1760,7 +1760,7 @@ static int sis900_rx(struct net_device *
 				sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
 				PCI_DMA_FROMDEVICE);
 
-			/* refill the Rx buffer, what if there is not enought
+			/* refill the Rx buffer, what if there is not enough
 			 * memory for new socket buffer ?? */
 			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
 				/*
@@ -1775,7 +1775,7 @@ static int sis900_rx(struct net_device *
 			}
 
 			/* This situation should never happen, but due to
-			   some unknow bugs, it is possible that
+			   some unknown bugs, it is possible that
 			   we are working on NULL sk_buff :-( */
 			if (sis_priv->rx_skbuff[entry] == NULL) {
 				if (netif_msg_rx_err(sis_priv))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/skfp/h/smc.h linux-libre-2.6.33-gnu1/drivers/net/skfp/h/smc.h
--- linux-libre-2.6.32-gnu1/drivers/net/skfp/h/smc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/skfp/h/smc.h	2010-02-24 13:52:17.000000000 -0500
@@ -393,10 +393,10 @@ struct smt_config {
 					 */
 	u_long	mac_d_max ;		/* MAC : D_Max timer value */
 
-	u_long lct_short ;		/* LCT : error threshhold */
-	u_long lct_medium ;		/* LCT : error threshhold */
-	u_long lct_long ;		/* LCT : error threshhold */
-	u_long lct_extended ;		/* LCT : error threshhold */
+	u_long lct_short ;		/* LCT : error threshold */
+	u_long lct_medium ;		/* LCT : error threshold */
+	u_long lct_long ;		/* LCT : error threshold */
+	u_long lct_extended ;		/* LCT : error threshold */
 } ;
 
 #ifdef	DEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/skfp/skfddi.c linux-libre-2.6.33-gnu1/drivers/net/skfp/skfddi.c
--- linux-libre-2.6.32-gnu1/drivers/net/skfp/skfddi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/skfp/skfddi.c	2010-02-24 13:52:17.000000000 -0500
@@ -1002,7 +1002,7 @@ static int skfp_ioctl(struct net_device
 		}
 		break;
 	default:
-		printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd);
+		printk("ioctl for %s: unknown cmd: %04x\n", dev->name, ioc.cmd);
 		status = -EOPNOTSUPP;
 
 	}			// switch
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/skge.c linux-libre-2.6.33-gnu1/drivers/net/skge.c
--- linux-libre-2.6.32-gnu1/drivers/net/skge.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/skge.c	2010-02-24 13:52:17.000000000 -0500
@@ -238,8 +238,8 @@ static int skge_set_wol(struct net_devic
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 
-	if ((wol->wolopts & ~wol_supported(hw))
-	    || !device_can_wakeup(&hw->pdev->dev))
+	if ((wol->wolopts & ~wol_supported(hw)) ||
+	    !device_can_wakeup(&hw->pdev->dev))
 		return -EOPNOTSUPP;
 
 	skge->wol = wol->wolopts;
@@ -576,9 +576,10 @@ static void skge_get_pauseparam(struct n
 {
 	struct skge_port *skge = netdev_priv(dev);
 
-	ecmd->rx_pause = (skge->flow_control == FLOW_MODE_SYMMETRIC)
-		|| (skge->flow_control == FLOW_MODE_SYM_OR_REM);
-	ecmd->tx_pause = ecmd->rx_pause || (skge->flow_control == FLOW_MODE_LOC_SEND);
+	ecmd->rx_pause = ((skge->flow_control == FLOW_MODE_SYMMETRIC) ||
+			  (skge->flow_control == FLOW_MODE_SYM_OR_REM));
+	ecmd->tx_pause = (ecmd->rx_pause ||
+			  (skge->flow_control == FLOW_MODE_LOC_SEND));
 
 	ecmd->autoneg = ecmd->rx_pause || ecmd->tx_pause;
 }
@@ -2779,8 +2780,8 @@ static netdev_tx_t skge_xmit_frame(struc
 		/* This seems backwards, but it is what the sk98lin
 		 * does.  Looks like hardware is wrong?
 		 */
-		if (ipip_hdr(skb)->protocol == IPPROTO_UDP
-	            && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
+		if (ipip_hdr(skb)->protocol == IPPROTO_UDP &&
+	            hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
 			control = BMU_TCP_CHECK;
 		else
 			control = BMU_UDP_CHECK;
@@ -2948,8 +2949,8 @@ static void genesis_set_multicast(struct
 	else {
 		memset(filter, 0, sizeof(filter));
 
-		if (skge->flow_status == FLOW_STAT_REM_SEND
-		    || skge->flow_status == FLOW_STAT_SYMMETRIC)
+		if (skge->flow_status == FLOW_STAT_REM_SEND ||
+		    skge->flow_status == FLOW_STAT_SYMMETRIC)
 			genesis_add_filter(filter, pause_mc_addr);
 
 		for (i = 0; list && i < count; i++, list = list->next)
@@ -2972,8 +2973,8 @@ static void yukon_set_multicast(struct n
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 	struct dev_mc_list *list = dev->mc_list;
-	int rx_pause = (skge->flow_status == FLOW_STAT_REM_SEND
-			|| skge->flow_status == FLOW_STAT_SYMMETRIC);
+	int rx_pause = (skge->flow_status == FLOW_STAT_REM_SEND ||
+			skge->flow_status == FLOW_STAT_SYMMETRIC);
 	u16 reg;
 	u8 filter[8];
 
@@ -3071,11 +3072,10 @@ static struct sk_buff *skge_rx_get(struc
 		goto error;
 
 	if (len < RX_COPY_THRESHOLD) {
-		skb = netdev_alloc_skb(dev, len + 2);
+		skb = netdev_alloc_skb_ip_align(dev, len);
 		if (!skb)
 			goto resubmit;
 
-		skb_reserve(skb, 2);
 		pci_dma_sync_single_for_cpu(skge->hw->pdev,
 					    pci_unmap_addr(e, mapaddr),
 					    len, PCI_DMA_FROMDEVICE);
@@ -3086,11 +3086,11 @@ static struct sk_buff *skge_rx_get(struc
 		skge_rx_reuse(e, skge->rx_buf_size);
 	} else {
 		struct sk_buff *nskb;
-		nskb = netdev_alloc_skb(dev, skge->rx_buf_size + NET_IP_ALIGN);
+
+		nskb = netdev_alloc_skb_ip_align(dev, skge->rx_buf_size);
 		if (!nskb)
 			goto resubmit;
 
-		skb_reserve(nskb, NET_IP_ALIGN);
 		pci_unmap_single(skge->hw->pdev,
 				 pci_unmap_addr(e, mapaddr),
 				 pci_unmap_len(e, maplen),
@@ -3948,7 +3948,7 @@ static int __devinit skge_probe(struct p
 	hw->pdev = pdev;
 	spin_lock_init(&hw->hw_lock);
 	spin_lock_init(&hw->phy_lock);
-	tasklet_init(&hw->phy_task, &skge_extirq, (unsigned long) hw);
+	tasklet_init(&hw->phy_task, skge_extirq, (unsigned long) hw);
 
 	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
 	if (!hw->regs) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sky2.c linux-libre-2.6.33-gnu1/drivers/net/sky2.c
--- linux-libre-2.6.32-gnu1/drivers/net/sky2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sky2.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.25"
+#define DRV_VERSION		"1.26"
 #define PFX			DRV_NAME " "
 
 /*
@@ -102,6 +102,7 @@ MODULE_PARM_DESC(disable_msi, "Disable M
 static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E01) }, /* SK-9E21M */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },	/* DGE-560T */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, 	/* DGE-550SX */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) },	/* DGE-560SX */
@@ -139,6 +140,7 @@ static DEFINE_PCI_DEVICE_TABLE(sky2_id_t
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */
 	{ 0 }
 };
 
@@ -372,8 +374,8 @@ static void sky2_phy_init(struct sky2_hw
 			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
 
 			/* downshift on PHY 88E1112 and 88E1149 is changed */
-			if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED)
-			    && (hw->flags & SKY2_HW_NEWER_PHY)) {
+			if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
+			     (hw->flags & SKY2_HW_NEWER_PHY)) {
 				/* set downshift counter to 3x and enable downshift */
 				ctrl &= ~PHY_M_PC_DSC_MSK;
 				ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
@@ -602,13 +604,23 @@ static void sky2_phy_init(struct sky2_hw
 		/* apply workaround for integrated resistors calibration */
 		gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
 		gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
+	} else if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
+		/* apply fixes in PHY AFE */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
+
+		/* apply RDAC termination workaround */
+		gm_phy_write(hw, port, 24, 0x2800);
+		gm_phy_write(hw, port, 23, 0x2001);
+
+		/* set page register back to 0 */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
 	} else if (hw->chip_id != CHIP_ID_YUKON_EX &&
 		   hw->chip_id < CHIP_ID_YUKON_SUPR) {
 		/* no effect on Yukon-XL */
 		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
-		if ( !(sky2->flags & SKY2_FLAG_AUTO_SPEED)
-		     || sky2->speed == SPEED_100) {
+		if (!(sky2->flags & SKY2_FLAG_AUTO_SPEED) ||
+		    sky2->speed == SPEED_100) {
 			/* turn on 100 Mbps LED (LED_LINK100) */
 			ledover |= PHY_M_LED_MO_100(MO_LED_ON);
 		}
@@ -786,8 +798,7 @@ static void sky2_set_tx_stfwd(struct sky
 
 	if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
 	      hw->chip_rev != CHIP_REV_YU_EX_A0) ||
-	     hw->chip_id == CHIP_ID_YUKON_FE_P ||
-	     hw->chip_id == CHIP_ID_YUKON_SUPR) {
+	     hw->chip_id >= CHIP_ID_YUKON_FE_P) {
 		/* Yukon-Extreme B0 and further Extreme devices */
 		/* enable Store & Forward mode for TX */
 
@@ -925,8 +936,14 @@ static void sky2_mac_init(struct sky2_hw
 
 	/* On chips without ram buffer, pause is controled by MAC level */
 	if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
-		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
-		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+		/* Pause threshold is scaled by 8 in bytes */
+		if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+		    hw->chip_rev == CHIP_REV_YU_FE2_A0)
+			reg = 1568 / 8;
+		else
+			reg = 1024 / 8;
+		sky2_write16(hw, SK_REG(port, RX_GMF_UP_THR), reg);
+		sky2_write16(hw, SK_REG(port, RX_GMF_LP_THR), 768 / 8);
 
 		sky2_set_tx_stfwd(hw, port);
 	}
@@ -1008,11 +1025,8 @@ static void sky2_prefetch_init(struct sk
 static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
 {
 	struct sky2_tx_le *le = sky2->tx_le + *slot;
-	struct tx_ring_info *re = sky2->tx_ring + *slot;
 
 	*slot = RING_NEXT(*slot, sky2->tx_ring_size);
-	re->flags = 0;
-	re->skb = NULL;
 	le->ctrl = 0;
 	return le;
 }
@@ -1336,8 +1350,8 @@ static int sky2_rx_start(struct sky2_por
 	/* These chips have no ram buffer?
 	 * MAC Rx RAM Read is controlled by hardware */
 	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
-	    (hw->chip_rev == CHIP_REV_YU_EC_U_A1
-	     || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
+	    (hw->chip_rev == CHIP_REV_YU_EC_U_A1 ||
+	     hw->chip_rev == CHIP_REV_YU_EC_U_B0))
 		sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
 
 	sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
@@ -1397,6 +1411,31 @@ static int sky2_rx_start(struct sky2_por
 
 	/* Tell chip about available buffers */
 	sky2_rx_update(sky2, rxq);
+
+	if (hw->chip_id == CHIP_ID_YUKON_EX ||
+	    hw->chip_id == CHIP_ID_YUKON_SUPR) {
+		/*
+		 * Disable flushing of non ASF packets;
+		 * must be done after initializing the BMUs;
+		 * drivers without ASF support should do this too, otherwise
+		 * it may happen that they cannot run on ASF devices;
+		 * remember that the MAC FIFO isn't reset during initialization.
+		 */
+		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_MACSEC_FLUSH_OFF);
+	}
+
+	if (hw->chip_id >= CHIP_ID_YUKON_SUPR) {
+		/* Enable RX Home Address & Routing Header checksum fix */
+		sky2_write16(hw, SK_REG(sky2->port, RX_GMF_FL_CTRL),
+			     RX_IPV6_SA_MOB_ENA | RX_IPV6_DA_MOB_ENA);
+
+		/* Enable TX Home Address & Routing Header checksum fix */
+		sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST),
+			     TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN);
+	}
+
+
+
 	return 0;
 nomem:
 	sky2_rx_clean(sky2);
@@ -1518,8 +1557,8 @@ static int sky2_up(struct net_device *de
 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
 
 	/* Set almost empty threshold */
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U
-	    && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+	    hw->chip_rev == CHIP_REV_YU_EC_U_A0)
 		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
 
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1580,8 +1619,7 @@ static unsigned tx_le_req(const struct s
 	return count;
 }
 
-static void sky2_tx_unmap(struct pci_dev *pdev,
-			  const struct tx_ring_info *re)
+static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re)
 {
 	if (re->flags & TX_MAP_SINGLE)
 		pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
@@ -1591,6 +1629,7 @@ static void sky2_tx_unmap(struct pci_dev
 		pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
 			       pci_unmap_len(re, maplen),
 			       PCI_DMA_TODEVICE);
+	re->flags = 0;
 }
 
 /*
@@ -1797,6 +1836,7 @@ static void sky2_tx_complete(struct sky2
 			dev->stats.tx_packets++;
 			dev->stats.tx_bytes += skb->len;
 
+			re->skb = NULL;
 			dev_kfree_skb_any(skb);
 
 			sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size);
@@ -1806,7 +1846,8 @@ static void sky2_tx_complete(struct sky2
 	sky2->tx_cons = idx;
 	smp_mb();
 
-	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+	/* Wake unless it's detached, and called e.g. from sky2_down() */
+	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev))
 		netif_wake_queue(dev);
 }
 
@@ -1865,8 +1906,8 @@ static int sky2_down(struct net_device *
 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
 
 	/* Workaround shared GMAC reset */
-	if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
-	      && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+	if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 &&
+	      port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 
 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
@@ -1975,7 +2016,7 @@ static void sky2_link_down(struct sky2_p
 
 	netif_carrier_off(sky2->netdev);
 
-	/* Turn on link LED */
+	/* Turn off link LED */
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
 
 	if (netif_msg_link(sky2))
@@ -2043,8 +2084,8 @@ static int sky2_autoneg_done(struct sky2
 			sky2->flow_status = FC_TX;
 	}
 
-	if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
-	    && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
+	if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 &&
+	    !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
 		sky2->flow_status = FC_NONE;
 
 	if (sky2->flow_status & FC_TX)
@@ -2096,6 +2137,27 @@ out:
 	spin_unlock(&sky2->phy_lock);
 }
 
+/* Special quick link interrupt (Yukon-2 Optima only) */
+static void sky2_qlink_intr(struct sky2_hw *hw)
+{
+	struct sky2_port *sky2 = netdev_priv(hw->dev[0]);
+	u32 imask;
+	u16 phy;
+
+	/* disable irq */
+	imask = sky2_read32(hw, B0_IMSK);
+	imask &= ~Y2_IS_PHY_QLNK;
+	sky2_write32(hw, B0_IMSK, imask);
+
+	/* reset PHY Link Detect */
+	phy = sky2_pci_read16(hw, PSM_CONFIG_REG4);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+	sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+	sky2_link_up(sky2);
+}
+
 /* Transmit timeout is only called if we are running, carrier is up
  * and tx queue is full (stopped).
  */
@@ -2191,9 +2253,8 @@ static struct sk_buff *receive_copy(stru
 {
 	struct sk_buff *skb;
 
-	skb = netdev_alloc_skb(sky2->netdev, length + 2);
+	skb = netdev_alloc_skb_ip_align(sky2->netdev, length);
 	if (likely(skb)) {
-		skb_reserve(skb, 2);
 		pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
 					    length, PCI_DMA_FROMDEVICE);
 		skb_copy_from_linear_data(re->skb, skb->data, length);
@@ -2766,6 +2827,9 @@ static int sky2_poll(struct napi_struct
 	if (status & Y2_IS_IRQ_PHY2)
 		sky2_phy_intr(hw, 1);
 
+	if (status & Y2_IS_PHY_QLNK)
+		sky2_qlink_intr(hw);
+
 	while ((idx = sky2_read16(hw, STAT_PUT_IDX)) != hw->st_idx) {
 		work_done += sky2_status_intr(hw, work_limit - work_done, idx);
 
@@ -2815,6 +2879,7 @@ static u32 sky2_mhz(const struct sky2_hw
 	case CHIP_ID_YUKON_EX:
 	case CHIP_ID_YUKON_SUPR:
 	case CHIP_ID_YUKON_UL_2:
+	case CHIP_ID_YUKON_OPT:
 		return 125;
 
 	case CHIP_ID_YUKON_FE:
@@ -2908,6 +2973,12 @@ static int __devinit sky2_init(struct sk
 			| SKY2_HW_ADV_POWER_CTL;
 		break;
 
+	case CHIP_ID_YUKON_OPT:
+		hw->flags = SKY2_HW_GIGABIT
+			| SKY2_HW_NEW_LE
+			| SKY2_HW_ADV_POWER_CTL;
+		break;
+
 	default:
 		dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
 			hw->chip_id);
@@ -2986,6 +3057,54 @@ static void sky2_reset(struct sky2_hw *h
 			sky2_write16(hw, SK_REG(i, GMAC_CTRL),
 				     GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
 				     | GMC_BYP_RETR_ON);
+
+	}
+
+	if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev > CHIP_REV_YU_SU_B0) {
+		/* enable MACSec clock gating */
+		sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS);
+	}
+
+	if (hw->chip_id == CHIP_ID_YUKON_OPT) {
+		u16 reg;
+		u32 msk;
+
+		if (hw->chip_rev == 0) {
+			/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
+			sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7));
+
+			/* set PHY Link Detect Timer to 1.1 second (11x 100ms) */
+			reg = 10;
+		} else {
+			/* set PHY Link Detect Timer to 0.4 second (4x 100ms) */
+			reg = 3;
+		}
+
+		reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
+
+		/* reset PHY Link Detect */
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		sky2_pci_write16(hw, PSM_CONFIG_REG4,
+				 reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT);
+		sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
+
+
+		/* enable PHY Quick Link */
+		msk = sky2_read32(hw, B0_IMSK);
+		msk |= Y2_IS_PHY_QLNK;
+		sky2_write32(hw, B0_IMSK, msk);
+
+		/* check if PSMv2 was running before */
+		reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
+		if (reg & PCI_EXP_LNKCTL_ASPMC) {
+			int cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+			/* restore the PCIe Link Control register */
+			sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg);
+		}
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		/* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
+		sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
 	}
 
 	/* Clear I2C IRQ noise */
@@ -3120,6 +3239,27 @@ static inline u8 sky2_wol_supported(cons
 	return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
 }
 
+static void sky2_hw_set_wol(struct sky2_hw *hw)
+{
+	int wol = 0;
+	int i;
+
+	for (i = 0; i < hw->ports; i++) {
+		struct net_device *dev = hw->dev[i];
+		struct sky2_port *sky2 = netdev_priv(dev);
+
+		if (sky2->wol)
+			wol = 1;
+	}
+
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
+	    hw->chip_id == CHIP_ID_YUKON_EX ||
+	    hw->chip_id == CHIP_ID_YUKON_FE_P)
+		sky2_write32(hw, B0_CTST, wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
+
+	device_set_wakeup_enable(&hw->pdev->dev, wol);
+}
+
 static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	const struct sky2_port *sky2 = netdev_priv(dev);
@@ -3133,19 +3273,13 @@ static int sky2_set_wol(struct net_devic
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 
-	if ((wol->wolopts & ~sky2_wol_supported(sky2->hw))
-	    || !device_can_wakeup(&hw->pdev->dev))
+	if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
+	    !device_can_wakeup(&hw->pdev->dev))
 		return -EOPNOTSUPP;
 
 	sky2->wol = wol->wolopts;
 
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
-	    hw->chip_id == CHIP_ID_YUKON_EX ||
-	    hw->chip_id == CHIP_ID_YUKON_FE_P)
-		sky2_write32(hw, B0_CTST, sky2->wol
-			     ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
-
-	device_set_wakeup_enable(&hw->pdev->dev, sky2->wol);
+	sky2_hw_set_wol(hw);
 
 	if (!netif_running(dev))
 		sky2_wol_init(sky2);
@@ -4406,9 +4540,11 @@ static const char *sky2_name(u8 chipid,
 		"FE+",		/* 0xb8 */
 		"Supreme",	/* 0xb9 */
 		"UL 2",		/* 0xba */
+		"Unknown",	/* 0xbb */
+		"Optima",	/* 0xbc */
 	};
 
-	if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_UL_2)
+	if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT)
 		strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
 	else
 		snprintf(buf, sz, "(chip %#x)", chipid);
@@ -4575,6 +4711,7 @@ static int __devinit sky2_probe(struct p
 	INIT_WORK(&hw->restart_work, sky2_restart);
 
 	pci_set_drvdata(pdev, hw);
+	pdev->d3_delay = 150;
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sky2.h linux-libre-2.6.33-gnu1/drivers/net/sky2.h
--- linux-libre-2.6.32-gnu1/drivers/net/sky2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sky2.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,13 @@ enum {
 	PCI_DEV_REG5    = 0x88,
 	PCI_CFG_REG_0	= 0x90,
 	PCI_CFG_REG_1	= 0x94,
+
+	PSM_CONFIG_REG0  = 0x98,
+	PSM_CONFIG_REG1	 = 0x9C,
+	PSM_CONFIG_REG2  = 0x160,
+	PSM_CONFIG_REG3  = 0x164,
+	PSM_CONFIG_REG4  = 0x168,
+
 };
 
 /* Yukon-2 */
@@ -48,6 +55,37 @@ enum pci_dev_reg_2 {
 	PCI_USEDATA64	= 1<<0,		/* Use 64Bit Data bus ext */
 };
 
+/*	PCI_OUR_REG_3		32 bit	Our Register 3 (Yukon-ECU only) */
+enum pci_dev_reg_3 {
+	P_CLK_ASF_REGS_DIS	= 1<<18,/* Disable Clock ASF (Yukon-Ext.) */
+	P_CLK_COR_REGS_D0_DIS	= 1<<17,/* Disable Clock Core Regs D0 */
+	P_CLK_MACSEC_DIS	= 1<<17,/* Disable Clock MACSec (Yukon-Ext.) */
+	P_CLK_PCI_REGS_D0_DIS	= 1<<16,/* Disable Clock PCI  Regs D0 */
+	P_CLK_COR_YTB_ARB_DIS	= 1<<15,/* Disable Clock YTB  Arbiter */
+	P_CLK_MAC_LNK1_D3_DIS	= 1<<14,/* Disable Clock MAC  Link1 D3 */
+	P_CLK_COR_LNK1_D0_DIS	= 1<<13,/* Disable Clock Core Link1 D0 */
+	P_CLK_MAC_LNK1_D0_DIS	= 1<<12,/* Disable Clock MAC  Link1 D0 */
+	P_CLK_COR_LNK1_D3_DIS	= 1<<11,/* Disable Clock Core Link1 D3 */
+	P_CLK_PCI_MST_ARB_DIS	= 1<<10,/* Disable Clock PCI  Master Arb. */
+	P_CLK_COR_REGS_D3_DIS	= 1<<9,	/* Disable Clock Core Regs D3 */
+	P_CLK_PCI_REGS_D3_DIS	= 1<<8,	/* Disable Clock PCI  Regs D3 */
+	P_CLK_REF_LNK1_GM_DIS	= 1<<7,	/* Disable Clock Ref. Link1 GMAC */
+	P_CLK_COR_LNK1_GM_DIS	= 1<<6,	/* Disable Clock Core Link1 GMAC */
+	P_CLK_PCI_COMMON_DIS	= 1<<5,	/* Disable Clock PCI  Common */
+	P_CLK_COR_COMMON_DIS	= 1<<4,	/* Disable Clock Core Common */
+	P_CLK_PCI_LNK1_BMU_DIS	= 1<<3,	/* Disable Clock PCI  Link1 BMU */
+	P_CLK_COR_LNK1_BMU_DIS	= 1<<2,	/* Disable Clock Core Link1 BMU */
+	P_CLK_PCI_LNK1_BIU_DIS	= 1<<1,	/* Disable Clock PCI  Link1 BIU */
+	P_CLK_COR_LNK1_BIU_DIS	= 1<<0,	/* Disable Clock Core Link1 BIU */
+	PCIE_OUR3_WOL_D3_COLD_SET = P_CLK_ASF_REGS_DIS |
+				    P_CLK_COR_REGS_D0_DIS |
+				    P_CLK_COR_LNK1_D0_DIS |
+				    P_CLK_MAC_LNK1_D0_DIS |
+				    P_CLK_PCI_MST_ARB_DIS |
+				    P_CLK_COR_COMMON_DIS |
+				    P_CLK_COR_LNK1_BMU_DIS,
+};
+
 /*	PCI_OUR_REG_4		32 bit	Our Register 4 (Yukon-ECU only) */
 enum pci_dev_reg_4 {
 				/* (Link Training & Status State Machine) */
@@ -114,7 +152,7 @@ enum pci_dev_reg_5 {
 				     P_GAT_PCIE_RX_EL_IDLE,
 };
 
-#/*	PCI_CFG_REG_1			32 bit	Config Register 1 (Yukon-Ext only) */
+/*	PCI_CFG_REG_1			32 bit	Config Register 1 (Yukon-Ext only) */
 enum pci_cfg_reg1 {
 	P_CF1_DIS_REL_EVT_RST	= 1<<24, /* Dis. Rel. Event during PCIE reset */
 										/* Bit 23..21: Release Clock on Event */
@@ -145,6 +183,72 @@ enum pci_cfg_reg1 {
 					P_CF1_ENA_TXBMU_WR_IDLE,
 };
 
+/* Yukon-Optima */
+enum {
+	PSM_CONFIG_REG1_AC_PRESENT_STATUS = 1<<31,   /* AC Present Status */
+
+	PSM_CONFIG_REG1_PTP_CLK_SEL	  = 1<<29,   /* PTP Clock Select */
+	PSM_CONFIG_REG1_PTP_MODE	  = 1<<28,   /* PTP Mode */
+
+	PSM_CONFIG_REG1_MUX_PHY_LINK	  = 1<<27,   /* PHY Energy Detect Event */
+
+	PSM_CONFIG_REG1_EN_PIN63_AC_PRESENT = 1<<26,  /* Enable LED_DUPLEX for ac_present */
+	PSM_CONFIG_REG1_EN_PCIE_TIMER	  = 1<<25,    /* Enable PCIe Timer */
+	PSM_CONFIG_REG1_EN_SPU_TIMER	  = 1<<24,    /* Enable SPU Timer */
+	PSM_CONFIG_REG1_POLARITY_AC_PRESENT = 1<<23,  /* AC Present Polarity */
+
+	PSM_CONFIG_REG1_EN_AC_PRESENT	  = 1<<21,    /* Enable AC Present */
+
+	PSM_CONFIG_REG1_EN_GPHY_INT_PSM	= 1<<20,      /* Enable GPHY INT for PSM */
+	PSM_CONFIG_REG1_DIS_PSM_TIMER	= 1<<19,      /* Disable PSM Timer */
+};
+
+/* Yukon-Supreme */
+enum {
+	PSM_CONFIG_REG1_GPHY_ENERGY_STS	= 1<<31, /* GPHY Energy Detect Status */
+
+	PSM_CONFIG_REG1_UART_MODE_MSK	= 3<<29, /* UART_Mode */
+	PSM_CONFIG_REG1_CLK_RUN_ASF	= 1<<28, /* Enable Clock Free Running for ASF Subsystem */
+	PSM_CONFIG_REG1_UART_CLK_DISABLE= 1<<27, /* Disable UART clock */
+	PSM_CONFIG_REG1_VAUX_ONE	= 1<<26, /* Tie internal Vaux to 1'b1 */
+	PSM_CONFIG_REG1_UART_FC_RI_VAL	= 1<<25, /* Default value for UART_RI_n */
+	PSM_CONFIG_REG1_UART_FC_DCD_VAL	= 1<<24, /* Default value for UART_DCD_n */
+	PSM_CONFIG_REG1_UART_FC_DSR_VAL	= 1<<23, /* Default value for UART_DSR_n */
+	PSM_CONFIG_REG1_UART_FC_CTS_VAL	= 1<<22, /* Default value for UART_CTS_n */
+	PSM_CONFIG_REG1_LATCH_VAUX	= 1<<21, /* Enable Latch current Vaux_avlbl */
+	PSM_CONFIG_REG1_FORCE_TESTMODE_INPUT= 1<<20, /* Force Testmode pin as input PAD */
+	PSM_CONFIG_REG1_UART_RST	= 1<<19, /* UART_RST */
+	PSM_CONFIG_REG1_PSM_PCIE_L1_POL	= 1<<18, /* PCIE L1 Event Polarity for PSM */
+	PSM_CONFIG_REG1_TIMER_STAT	= 1<<17, /* PSM Timer Status */
+	PSM_CONFIG_REG1_GPHY_INT	= 1<<16, /* GPHY INT Status */
+	PSM_CONFIG_REG1_FORCE_TESTMODE_ZERO= 1<<15, /* Force internal Testmode as 1'b0 */
+	PSM_CONFIG_REG1_EN_INT_ASPM_CLKREQ = 1<<14, /* ENABLE INT for CLKRUN on ASPM and CLKREQ */
+	PSM_CONFIG_REG1_EN_SND_TASK_ASPM_CLKREQ	= 1<<13, /* ENABLE Snd_task for CLKRUN on ASPM and CLKREQ */
+	PSM_CONFIG_REG1_DIS_CLK_GATE_SND_TASK	= 1<<12, /* Disable CLK_GATE control snd_task */
+	PSM_CONFIG_REG1_DIS_FF_CHIAN_SND_INTA	= 1<<11, /* Disable flip-flop chain for sndmsg_inta */
+
+	PSM_CONFIG_REG1_DIS_LOADER	= 1<<9, /* Disable Loader SM after PSM Goes back to IDLE */
+	PSM_CONFIG_REG1_DO_PWDN		= 1<<8, /* Do Power Down, Start PSM Scheme */
+	PSM_CONFIG_REG1_DIS_PIG		= 1<<7, /* Disable Plug-in-Go SM after PSM Goes back to IDLE */
+	PSM_CONFIG_REG1_DIS_PERST	= 1<<6, /* Disable Internal PCIe Reset after PSM Goes back to IDLE */
+	PSM_CONFIG_REG1_EN_REG18_PD	= 1<<5, /* Enable REG18 Power Down for PSM */
+	PSM_CONFIG_REG1_EN_PSM_LOAD	= 1<<4, /* Disable EEPROM Loader after PSM Goes back to IDLE */
+	PSM_CONFIG_REG1_EN_PSM_HOT_RST	= 1<<3, /* Enable PCIe Hot Reset for PSM */
+	PSM_CONFIG_REG1_EN_PSM_PERST	= 1<<2, /* Enable PCIe Reset Event for PSM */
+	PSM_CONFIG_REG1_EN_PSM_PCIE_L1	= 1<<1, /* Enable PCIe L1 Event for PSM */
+	PSM_CONFIG_REG1_EN_PSM		= 1<<0, /* Enable PSM Scheme */
+};
+
+/*	PSM_CONFIG_REG4				0x0168	PSM Config Register 4 */
+enum {
+						/* PHY Link Detect Timer */
+	PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_MSK = 0xf<<4,
+	PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE = 4,
+
+	PSM_CONFIG_REG4_DEBUG_TIMER	    = 1<<1, /* Debug Timer */
+	PSM_CONFIG_REG4_RST_PHY_LINK_DETECT = 1<<0, /* Reset GPHY Link Detect */
+};
+
 
 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
 			       PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -197,6 +301,9 @@ enum csr_regs {
 	B2_I2C_IRQ	= 0x0168,
 	B2_I2C_SW	= 0x016c,
 
+	Y2_PEX_PHY_DATA = 0x0170,
+	Y2_PEX_PHY_ADDR = 0x0172,
+
 	B3_RAM_ADDR	= 0x0180,
 	B3_RAM_DATA_LO	= 0x0184,
 	B3_RAM_DATA_HI	= 0x0188,
@@ -317,6 +424,10 @@ enum {
 	Y2_IS_CHK_TXS2	= 1<<9,		/* Descriptor error TXS 2 */
 	Y2_IS_CHK_TXA2	= 1<<8,		/* Descriptor error TXA 2 */
 
+	Y2_IS_PSM_ACK	= 1<<7,		/* PSM Acknowledge (Yukon-Optima only) */
+	Y2_IS_PTP_TIST	= 1<<6,		/* PTP Time Stamp (Yukon-Optima only) */
+	Y2_IS_PHY_QLNK	= 1<<5,		/* PHY Quick Link (Yukon-Optima only) */
+
 	Y2_IS_IRQ_PHY1	= 1<<4,		/* Interrupt from PHY 1 */
 	Y2_IS_IRQ_MAC1	= 1<<3,		/* Interrupt from MAC 1 */
 	Y2_IS_CHK_RX1	= 1<<2,		/* Descriptor error Rx 1 */
@@ -435,6 +546,7 @@ enum {
  	CHIP_ID_YUKON_FE_P = 0xb8, /* YUKON-2 FE+ */
 	CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
 	CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */
+	CHIP_ID_YUKON_OPT  = 0xbc, /* YUKON-2 Optima */
 };
 enum yukon_ec_rev {
 	CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
@@ -459,6 +571,8 @@ enum yukon_ex_rev {
 };
 enum yukon_supr_rev {
 	CHIP_REV_YU_SU_A0    = 0,
+	CHIP_REV_YU_SU_B0    = 1,
+	CHIP_REV_YU_SU_B1    = 3,
 };
 
 
@@ -513,6 +627,12 @@ enum {
 	TIM_T_STEP	= 1<<0,	/* Test step */
 };
 
+/*	Y2_PEX_PHY_ADDR/DATA		PEX PHY address and data reg  (Yukon-2 only) */
+enum {
+	PEX_RD_ACCESS	= 1<<31, /* Access Mode Read = 1, Write = 0 */
+	PEX_DB_ACCESS	= 1<<30, /* Access to debug register */
+};
+
 /*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
 					/* Bit 31..19:	reserved */
 #define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
@@ -688,10 +808,11 @@ enum {
 	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
 	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
 	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
-	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
+	RX_GMF_FL_THR	= 0x0c50,/* 16 bit	Rx GMAC FIFO Flush Threshold */
+	RX_GMF_FL_CTRL	= 0x0c52,/* 16 bit	Rx GMAC FIFO Flush Control */
 	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
-	RX_GMF_UP_THR	= 0x0c58,/*  8 bit	Rx Upper Pause Thr (Yukon-EC_U) */
-	RX_GMF_LP_THR	= 0x0c5a,/*  8 bit	Rx Lower Pause Thr (Yukon-EC_U) */
+	RX_GMF_UP_THR	= 0x0c58,/* 16 bit	Rx Upper Pause Thr (Yukon-EC_U) */
+	RX_GMF_LP_THR	= 0x0c5a,/* 16 bit	Rx Lower Pause Thr (Yukon-EC_U) */
 	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
 	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
 
@@ -754,6 +875,42 @@ enum {
 	BMU_TX_CLR_IRQ_TCP	= 1<<11, /* Clear IRQ on TCP segment length mismatch */
 };
 
+/*	TBMU_TEST			0x06B8	Transmit BMU Test Register */
+enum {
+	TBMU_TEST_BMU_TX_CHK_AUTO_OFF		= 1<<31, /* BMU Tx Checksum Auto Calculation Disable */
+	TBMU_TEST_BMU_TX_CHK_AUTO_ON		= 1<<30, /* BMU Tx Checksum Auto Calculation Enable */
+	TBMU_TEST_HOME_ADD_PAD_FIX1_EN		= 1<<29, /* Home Address Paddiing FIX1 Enable */
+	TBMU_TEST_HOME_ADD_PAD_FIX1_DIS		= 1<<28, /* Home Address Paddiing FIX1 Disable */
+	TBMU_TEST_ROUTING_ADD_FIX_EN		= 1<<27, /* Routing Address Fix Enable */
+	TBMU_TEST_ROUTING_ADD_FIX_DIS		= 1<<26, /* Routing Address Fix Disable */
+	TBMU_TEST_HOME_ADD_FIX_EN		= 1<<25, /* Home address checksum fix enable */
+	TBMU_TEST_HOME_ADD_FIX_DIS		= 1<<24, /* Home address checksum fix disable */
+
+	TBMU_TEST_TEST_RSPTR_ON			= 1<<22, /* Testmode Shadow Read Ptr On */
+	TBMU_TEST_TEST_RSPTR_OFF		= 1<<21, /* Testmode Shadow Read Ptr Off */
+	TBMU_TEST_TESTSTEP_RSPTR		= 1<<20, /* Teststep Shadow Read Ptr */
+
+	TBMU_TEST_TEST_RPTR_ON			= 1<<18, /* Testmode Read Ptr On */
+	TBMU_TEST_TEST_RPTR_OFF			= 1<<17, /* Testmode Read Ptr Off */
+	TBMU_TEST_TESTSTEP_RPTR			= 1<<16, /* Teststep Read Ptr */
+
+	TBMU_TEST_TEST_WSPTR_ON			= 1<<14, /* Testmode Shadow Write Ptr On */
+	TBMU_TEST_TEST_WSPTR_OFF		= 1<<13, /* Testmode Shadow Write Ptr Off */
+	TBMU_TEST_TESTSTEP_WSPTR		= 1<<12, /* Teststep Shadow Write Ptr */
+
+	TBMU_TEST_TEST_WPTR_ON			= 1<<10, /* Testmode Write Ptr On */
+	TBMU_TEST_TEST_WPTR_OFF			= 1<<9, /* Testmode Write Ptr Off */
+	TBMU_TEST_TESTSTEP_WPTR			= 1<<8,			/* Teststep Write Ptr */
+
+	TBMU_TEST_TEST_REQ_NB_ON		= 1<<6, /* Testmode Req Nbytes/Addr On */
+	TBMU_TEST_TEST_REQ_NB_OFF		= 1<<5, /* Testmode Req Nbytes/Addr Off */
+	TBMU_TEST_TESTSTEP_REQ_NB		= 1<<4, /* Teststep Req Nbytes/Addr */
+
+	TBMU_TEST_TEST_DONE_IDX_ON		= 1<<2, /* Testmode Done Index On */
+	TBMU_TEST_TEST_DONE_IDX_OFF		= 1<<1, /* Testmode Done Index Off */
+	TBMU_TEST_TESTSTEP_DONE_IDX		= 1<<0,	/* Teststep Done Index */
+};
+
 /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
 /* PREF_UNIT_CTRL	32 bit	Prefetch Control register */
 enum {
@@ -1674,6 +1831,12 @@ enum {
 
 /*	RX_GMF_CTRL_T	32 bit	Rx GMAC FIFO Control/Test */
 enum {
+	RX_GCLKMAC_ENA	= 1<<31,	/* RX MAC Clock Gating Enable */
+	RX_GCLKMAC_OFF	= 1<<30,
+
+	RX_STFW_DIS	= 1<<29,	/* RX Store and Forward Enable */
+	RX_STFW_ENA	= 1<<28,
+
 	RX_TRUNC_ON	= 1<<27,  	/* enable  packet truncation */
 	RX_TRUNC_OFF	= 1<<26, 	/* disable packet truncation */
 	RX_VLAN_STRIP_ON = 1<<25,	/* enable  VLAN stripping */
@@ -1711,6 +1874,20 @@ enum {
 	GMF_RX_CTRL_DEF	= GMF_OPER_ON | GMF_RX_F_FL_ON,
 };
 
+/*	RX_GMF_FL_CTRL	16 bit	Rx GMAC FIFO Flush Control (Yukon-Supreme) */
+enum {
+	RX_IPV6_SA_MOB_ENA	= 1<<9,	/* IPv6 SA Mobility Support Enable */
+	RX_IPV6_SA_MOB_DIS	= 1<<8,	/* IPv6 SA Mobility Support Disable */
+	RX_IPV6_DA_MOB_ENA	= 1<<7,	/* IPv6 DA Mobility Support Enable */
+	RX_IPV6_DA_MOB_DIS	= 1<<6,	/* IPv6 DA Mobility Support Disable */
+	RX_PTR_SYNCDLY_ENA	= 1<<5,	/* Pointers Delay Synch Enable */
+	RX_PTR_SYNCDLY_DIS	= 1<<4,	/* Pointers Delay Synch Disable */
+	RX_ASF_NEWFLAG_ENA	= 1<<3,	/* RX ASF Flag New Logic Enable */
+	RX_ASF_NEWFLAG_DIS	= 1<<2,	/* RX ASF Flag New Logic Disable */
+	RX_FLSH_MISSPKT_ENA	= 1<<1,	/* RX Flush Miss-Packet Enable */
+	RX_FLSH_MISSPKT_DIS	= 1<<0,	/* RX Flush Miss-Packet Disable */
+};
+
 /*	TX_GMF_EA		32 bit	Tx GMAC FIFO End Address */
 enum {
 	TX_DYN_WM_ENA	= 3,	/* Yukon-FE+ specific */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/slip.c linux-libre-2.6.33-gnu1/drivers/net/slip.c
--- linux-libre-2.6.32-gnu1/drivers/net/slip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/slip.c	2010-02-24 13:52:17.000000000 -0500
@@ -80,6 +80,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/if_arp.h>
 #include <linux/if_slip.h>
+#include <linux/compat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include "slip.h"
@@ -955,8 +956,8 @@ static void slip_unesc(struct slip *sl,
 			clear_bit(SLF_KEEPTEST, &sl->flags);
 #endif
 
-		if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
-							&& (sl->rcount > 2))
+		if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+		    (sl->rcount > 2))
 			sl_bump(sl);
 		clear_bit(SLF_ESCAPE, &sl->flags);
 		sl->rcount = 0;
@@ -1038,8 +1039,8 @@ static void slip_unesc6(struct slip *sl,
 			clear_bit(SLF_KEEPTEST, &sl->flags);
 #endif
 
-		if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
-							&& (sl->rcount > 2))
+		if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+		    (sl->rcount > 2))
 			sl_bump(sl);
 		sl->rcount = 0;
 		sl->xbits = 0;
@@ -1169,6 +1170,27 @@ static int slip_ioctl(struct tty_struct
 	}
 }
 
+#ifdef CONFIG_COMPAT
+static long slip_compat_ioctl(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case SIOCGIFNAME:
+	case SIOCGIFENCAP:
+	case SIOCSIFENCAP:
+	case SIOCSIFHWADDR:
+	case SIOCSKEEPALIVE:
+	case SIOCGKEEPALIVE:
+	case SIOCSOUTFILL:
+	case SIOCGOUTFILL:
+		return slip_ioctl(tty, file, cmd,
+				  (unsigned long)compat_ptr(arg));
+	}
+
+	return -ENOIOCTLCMD;
+}
+#endif
+
 /* VSV changes start here */
 #ifdef CONFIG_SLIP_SMART
 /* function do_ioctl called from net/core/dev.c
@@ -1261,6 +1283,9 @@ static struct tty_ldisc_ops sl_ldisc = {
 	.close	 	= slip_close,
 	.hangup	 	= slip_hangup,
 	.ioctl		= slip_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= slip_compat_ioctl,
+#endif
 	.receive_buf	= slip_receive_buf,
 	.write_wakeup	= slip_write_wakeup,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smc911x.c linux-libre-2.6.33-gnu1/drivers/net/smc911x.c
--- linux-libre-2.6.32-gnu1/drivers/net/smc911x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smc911x.c	2010-02-24 13:52:17.000000000 -0500
@@ -1984,7 +1984,7 @@ static int __devinit smc911x_probe(struc
 #endif
 
 	/* Grab the IRQ */
-	retval = request_irq(dev->irq, &smc911x_interrupt,
+	retval = request_irq(dev->irq, smc911x_interrupt,
 			     irq_flags, dev->name, dev);
 	if (retval)
 		goto err_out;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smc9194.c linux-libre-2.6.33-gnu1/drivers/net/smc9194.c
--- linux-libre-2.6.32-gnu1/drivers/net/smc9194.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smc9194.c	2010-02-24 13:52:17.000000000 -0500
@@ -1050,7 +1050,7 @@ static int __init smc_probe(struct net_d
 	memset(netdev_priv(dev), 0, sizeof(struct smc_local));
 
 	/* Grab the IRQ */
-      	retval = request_irq(dev->irq, &smc_interrupt, 0, DRV_NAME, dev);
+      	retval = request_irq(dev->irq, smc_interrupt, 0, DRV_NAME, dev);
       	if (retval) {
 		printk("%s: unable to get IRQ %d (irqval=%d).\n", DRV_NAME,
 			dev->irq, retval);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smc91x.c linux-libre-2.6.33-gnu1/drivers/net/smc91x.c
--- linux-libre-2.6.32-gnu1/drivers/net/smc91x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smc91x.c	2010-02-24 13:52:17.000000000 -0500
@@ -534,9 +534,9 @@ static inline void  smc_rcv(struct net_d
 #define smc_special_lock(lock, flags)		spin_lock_irqsave(lock, flags)
 #define smc_special_unlock(lock, flags) 	spin_unlock_irqrestore(lock, flags)
 #else
-#define smc_special_trylock(lock, flags)	(1)
-#define smc_special_lock(lock, flags)   	do { } while (0)
-#define smc_special_unlock(lock, flags)	do { } while (0)
+#define smc_special_trylock(lock, flags)	(flags == flags)
+#define smc_special_lock(lock, flags)   	do { flags = 0; } while (0)
+#define smc_special_unlock(lock, flags)	do { flags = 0; } while (0)
 #endif
 
 /*
@@ -2031,7 +2031,7 @@ static int __devinit smc_probe(struct ne
 	}
 
 	/* Grab the IRQ */
-	retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev);
+	retval = request_irq(dev->irq, smc_interrupt, irq_flags, dev->name, dev);
       	if (retval)
       		goto err_out;
 
@@ -2365,9 +2365,10 @@ static int __devexit smc_drv_remove(stru
 	return 0;
 }
 
-static int smc_drv_suspend(struct platform_device *dev, pm_message_t state)
+static int smc_drv_suspend(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 
 	if (ndev) {
 		if (netif_running(ndev)) {
@@ -2379,13 +2380,14 @@ static int smc_drv_suspend(struct platfo
 	return 0;
 }
 
-static int smc_drv_resume(struct platform_device *dev)
+static int smc_drv_resume(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 
 	if (ndev) {
 		struct smc_local *lp = netdev_priv(ndev);
-		smc_enable_device(dev);
+		smc_enable_device(pdev);
 		if (netif_running(ndev)) {
 			smc_reset(ndev);
 			smc_enable(ndev);
@@ -2397,14 +2399,18 @@ static int smc_drv_resume(struct platfor
 	return 0;
 }
 
+static struct dev_pm_ops smc_drv_pm_ops = {
+	.suspend	= smc_drv_suspend,
+	.resume		= smc_drv_resume,
+};
+
 static struct platform_driver smc_driver = {
 	.probe		= smc_drv_probe,
 	.remove		= __devexit_p(smc_drv_remove),
-	.suspend	= smc_drv_suspend,
-	.resume		= smc_drv_resume,
 	.driver		= {
 		.name	= CARDNAME,
 		.owner	= THIS_MODULE,
+		.pm	= &smc_drv_pm_ops,
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smc91x.h linux-libre-2.6.33-gnu1/drivers/net/smc91x.h
--- linux-libre-2.6.32-gnu1/drivers/net/smc91x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smc91x.h	2010-02-24 13:52:17.000000000 -0500
@@ -158,8 +158,8 @@ static inline void SMC_outw(u16 val, voi
 #define SMC_outsb(a, r, p, l)	writesb((a) + (r), p, (l))
 #define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
-#elif	defined(CONFIG_MACH_LOGICPD_PXA270) \
-	|| defined(CONFIG_MACH_NOMADIK_8815NHK)
+#elif	defined(CONFIG_MACH_LOGICPD_PXA270) ||	\
+	defined(CONFIG_MACH_NOMADIK_8815NHK)
 
 #define SMC_CAN_USE_8BIT	0
 #define SMC_CAN_USE_16BIT	1
@@ -206,21 +206,6 @@ SMC_outw(u16 val, void __iomem *ioaddr,
 	}
 }
 
-#elif	defined(CONFIG_ARCH_OMAP)
-
-/* We can only do 16-bit reads and writes in the static memory space. */
-#define SMC_CAN_USE_8BIT	0
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	0
-#define SMC_IO_SHIFT		0
-#define SMC_NOWAIT		1
-
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
-#define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
-#define	SMC_IRQ_FLAGS		(-1)	/* from resource */
-
 #elif	defined(CONFIG_SH_SH4202_MICRODEV)
 
 #define SMC_CAN_USE_8BIT	0
@@ -258,9 +243,9 @@ SMC_outw(u16 val, void __iomem *ioaddr,
 #define RPC_LSA_DEFAULT		RPC_LED_TX_RX
 #define RPC_LSB_DEFAULT		RPC_LED_100_10
 
-#elif   defined(CONFIG_MACH_LPD79520) \
-     || defined(CONFIG_MACH_LPD7A400) \
-     || defined(CONFIG_MACH_LPD7A404)
+#elif   defined(CONFIG_MACH_LPD79520) ||	\
+	defined(CONFIG_MACH_LPD7A400) ||	\
+	defined(CONFIG_MACH_LPD7A404)
 
 /* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the
  * way that the CPU handles chip selects and the way that the SMC chip
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smc-mca.c linux-libre-2.6.33-gnu1/drivers/net/smc-mca.c
--- linux-libre-2.6.32-gnu1/drivers/net/smc-mca.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smc-mca.c	2010-02-24 13:52:17.000000000 -0500
@@ -268,9 +268,9 @@ static int __init ultramca_probe(struct
 		}
 	}
 
-	if(!tirq || !tbase
-	   || (irq && irq != tirq)
-	   || (base_addr && tbase != base_addr))
+	if(!tirq || !tbase ||
+	   (irq && irq != tirq) ||
+	   (base_addr && tbase != base_addr))
 		/* FIXME: we're trying to force the ordering of the
 		 * devices here, there should be a way of getting this
 		 * to happen */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smsc911x.c linux-libre-2.6.33-gnu1/drivers/net/smsc911x.c
--- linux-libre-2.6.32-gnu1/drivers/net/smsc911x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smsc911x.c	2010-02-24 13:52:17.000000000 -0500
@@ -748,8 +748,8 @@ static void smsc911x_phy_adjust_link(str
 			 * usage is 10/100 indicator */
 			pdata->gpio_setting = smsc911x_reg_read(pdata,
 				GPIO_CFG);
-			if ((pdata->gpio_setting & GPIO_CFG_LED1_EN_)
-			    && (!pdata->using_extphy)) {
+			if ((pdata->gpio_setting & GPIO_CFG_LED1_EN_) &&
+			    (!pdata->using_extphy)) {
 				/* Force 10/100 LED off, after saving
 				 * orginal GPIO configuration */
 				pdata->gpio_orig_setting = pdata->gpio_setting;
@@ -816,7 +816,7 @@ static int smsc911x_mii_probe(struct net
 	SMSC_TRACE(HW, "Passed Loop Back Test");
 #endif				/* USE_PHY_WORK_AROUND */
 
-	SMSC_TRACE(HW, "phy initialised succesfully");
+	SMSC_TRACE(HW, "phy initialised successfully");
 	return 0;
 }
 
@@ -2071,6 +2071,9 @@ static int __devinit smsc911x_drv_probe(
 	if (is_valid_ether_addr(dev->dev_addr)) {
 		smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 		SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
+	} else if (is_valid_ether_addr(pdata->config.mac)) {
+		memcpy(dev->dev_addr, pdata->config.mac, 6);
+		SMSC_TRACE(PROBE, "MAC Address specified by platform data");
 	} else {
 		/* Try reading mac address from device. if EEPROM is present
 		 * it will already have been set */
@@ -2151,7 +2154,7 @@ static int smsc911x_resume(struct device
 	return (to == 0) ? -EIO : 0;
 }
 
-static struct dev_pm_ops smsc911x_pm_ops = {
+static const struct dev_pm_ops smsc911x_pm_ops = {
 	.suspend	= smsc911x_suspend,
 	.resume		= smsc911x_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smsc911x.h linux-libre-2.6.33-gnu1/drivers/net/smsc911x.h
--- linux-libre-2.6.32-gnu1/drivers/net/smsc911x.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smsc911x.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,7 +30,7 @@
 #define SMSC_NAPI_WEIGHT	16
 
 /* implements a PHY loopback test at initialisation time, to ensure a packet
- * can be succesfully looped back */
+ * can be successfully looped back */
 #define USE_PHY_WORK_AROUND
 
 #define DPRINTK(nlevel, klevel, fmt, args...) \
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/smsc9420.c linux-libre-2.6.33-gnu1/drivers/net/smsc9420.c
--- linux-libre-2.6.32-gnu1/drivers/net/smsc9420.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/smsc9420.c	2010-02-24 13:52:17.000000000 -0500
@@ -1175,7 +1175,7 @@ static int smsc9420_mii_probe(struct net
 		phydev->phy_id);
 
 	phydev = phy_connect(dev, dev_name(&phydev->dev),
-		&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+		smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
 
 	if (IS_ERR(phydev)) {
 		pr_err("%s: Could not attach to PHY\n", dev->name);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/spider_net.c linux-libre-2.6.33-gnu1/drivers/net/spider_net.c
--- linux-libre-2.6.32-gnu1/drivers/net/spider_net.c	2013-05-03 14:01:09.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/spider_net.c	2013-05-03 12:08:30.000000000 -0400
@@ -57,6 +57,7 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de
 MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(VERSION);
+/*(DEBLOBBED)*/
 
 static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT;
 static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT;
@@ -409,7 +410,7 @@ spider_net_free_rx_chain_contents(struct
  * @card: card structure
  * @descr: descriptor to re-init
  *
- * Return 0 on succes, <0 on failure.
+ * Return 0 on success, <0 on failure.
  *
  * Allocates a new rx skb, iommu-maps it and attaches it to the
  * descriptor. Mark the descriptor as activated, ready-to-use.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/starfire.c linux-libre-2.6.33-gnu1/drivers/net/starfire.c
--- linux-libre-2.6.32-gnu1/drivers/net/starfire.c	2013-05-03 13:59:11.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/starfire.c	2013-05-03 12:07:43.000000000 -0400
@@ -927,7 +927,7 @@ static int netdev_open(struct net_device
 
 	/* Do we ever need to reset the chip??? */
 
-	retval = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev);
+	retval = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
 	if (retval)
 		return retval;
 
@@ -1062,7 +1062,7 @@ static int netdev_open(struct net_device
 	if (retval) {
 		printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
 		       FIRMWARE_RX);
-		return retval;
+		goto out_init;
 	}
 	if (fw_rx->size % 4) {
 		printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
@@ -1107,6 +1107,9 @@ out_tx:
 	release_firmware(fw_tx);
 out_rx:
 	release_firmware(fw_rx);
+out_init:
+	if (retval)
+		netdev_close(dev);
 	return retval;
 }
 
@@ -1481,8 +1484,8 @@ static int __netdev_rx(struct net_device
 			printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d, quota %d.\n", pkt_len, *quota);
 		/* Check if the packet is long enough to accept without copying
 		   to a minimally-sized skbuff. */
-		if (pkt_len < rx_copybreak
-		    && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+		if (pkt_len < rx_copybreak &&
+		    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 			skb_reserve(skb, 2);	/* 16 byte align the IP header */
 			pci_dma_sync_single_for_cpu(np->pci_dev,
 						    np->rx_info[entry].mapping,
@@ -1792,8 +1795,8 @@ static void set_rx_mode(struct net_devic
 
 	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		rx_mode |= AcceptAll;
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter;
 	} else if (dev->mc_count <= 14) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/stmmac/gmac.c linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/stmmac/gmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -112,7 +112,7 @@ static void gmac_dma_operation_mode(unsi
 			      " (threshold = %d)\n", txmode);
 		csr6 &= ~DMA_CONTROL_TSF;
 		csr6 &= DMA_CONTROL_TC_TX_MASK;
-		/* Set the transmit threashold */
+		/* Set the transmit threshold */
 		if (txmode <= 32)
 			csr6 |= DMA_CONTROL_TTC_32;
 		else if (txmode <= 64)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/stmmac/gmac.h linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.h
--- linux-libre-2.6.32-gnu1/drivers/net/stmmac/gmac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/stmmac/gmac.h	2010-02-24 13:52:17.000000000 -0500
@@ -154,14 +154,14 @@ enum rx_tx_priority_ratio {
 #define DMA_CONTROL_DT		0x04000000 /* Disable Drop TCP/IP csum error */
 #define DMA_CONTROL_RSF		0x02000000 /* Receive Store and Forward */
 #define DMA_CONTROL_DFF		0x01000000 /* Disaable flushing */
-/* Theshold for Activating the FC */
+/* Threshold for Activating the FC */
 enum rfa {
 	act_full_minus_1 = 0x00800000,
 	act_full_minus_2 = 0x00800200,
 	act_full_minus_3 = 0x00800400,
 	act_full_minus_4 = 0x00800600,
 };
-/* Theshold for Deactivating the FC */
+/* Threshold for Deactivating the FC */
 enum rfd {
 	deac_full_minus_1 = 0x00400000,
 	deac_full_minus_2 = 0x00400800,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/stmmac/stmmac_main.c linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/stmmac/stmmac_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/stmmac/stmmac_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -922,8 +922,7 @@ static void stmmac_dma_interrupt(struct
 		DBG(intr, INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
 		if (unlikely(intr_status & DMA_STATUS_UNF)) {
 			DBG(intr, INFO, "transmit underflow\n");
-			if (unlikely(tc != SF_DMA_MODE)
-			    && (tc <= 256)) {
+			if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
 				/* Try to bump up the threshold */
 				tc += 64;
 				priv->mac_type->ops->dma_mode(ioaddr, tc,
@@ -1024,7 +1023,7 @@ static int stmmac_open(struct net_device
 	}
 
 	/* Request the IRQ lines */
-	ret = request_irq(dev->irq, &stmmac_interrupt,
+	ret = request_irq(dev->irq, stmmac_interrupt,
 			  IRQF_SHARED, dev->name, dev);
 	if (unlikely(ret < 0)) {
 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sun3_82586.c linux-libre-2.6.33-gnu1/drivers/net/sun3_82586.c
--- linux-libre-2.6.32-gnu1/drivers/net/sun3_82586.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sun3_82586.c	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,7 @@ static int sun3_82586_open(struct net_de
 	startrecv586(dev);
 	sun3_enaint();
 
-	ret = request_irq(dev->irq, &sun3_82586_interrupt,0,dev->name,dev);
+	ret = request_irq(dev->irq, sun3_82586_interrupt,0,dev->name,dev);
 	if (ret)
 	{
 		sun3_reset586();
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sunbmac.c linux-libre-2.6.33-gnu1/drivers/net/sunbmac.c
--- linux-libre-2.6.32-gnu1/drivers/net/sunbmac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sunbmac.c	2010-02-24 13:52:17.000000000 -0500
@@ -919,7 +919,7 @@ static int bigmac_open(struct net_device
 	struct bigmac *bp = netdev_priv(dev);
 	int ret;
 
-	ret = request_irq(dev->irq, &bigmac_interrupt, IRQF_SHARED, dev->name, bp);
+	ret = request_irq(dev->irq, bigmac_interrupt, IRQF_SHARED, dev->name, bp);
 	if (ret) {
 		printk(KERN_ERR "BIGMAC: Can't order irq %d to go.\n", dev->irq);
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sundance.c linux-libre-2.6.33-gnu1/drivers/net/sundance.c
--- linux-libre-2.6.32-gnu1/drivers/net/sundance.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sundance.c	2010-02-24 13:52:17.000000000 -0500
@@ -603,8 +603,8 @@ static int __devinit sundance_probe1 (st
 			    strcmp (media[card_idx], "4") == 0) {
 				np->speed = 100;
 				np->mii_if.full_duplex = 1;
-			} else if (strcmp (media[card_idx], "100mbps_hd") == 0
-				   || strcmp (media[card_idx], "3") == 0) {
+			} else if (strcmp (media[card_idx], "100mbps_hd") == 0 ||
+				   strcmp (media[card_idx], "3") == 0) {
 				np->speed = 100;
 				np->mii_if.full_duplex = 0;
 			} else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
@@ -819,7 +819,7 @@ static int netdev_open(struct net_device
 
 	/* Do we need to reset the chip??? */
 
-	i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev);
+	i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
 	if (i)
 		return i;
 
@@ -1079,8 +1079,8 @@ start_tx (struct sk_buff *skb, struct ne
 	tasklet_schedule(&np->tx_tasklet);
 
 	/* On some architectures: explicitly flush cache lines here. */
-	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1
-			&& !netif_queue_stopped(dev)) {
+	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1 &&
+	    !netif_queue_stopped(dev)) {
 		/* do nothing */
 	} else {
 		netif_stop_queue (dev);
@@ -1336,8 +1336,8 @@ static void rx_poll(unsigned long data)
 #endif
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(np->pci_dev,
 							    le32_to_cpu(desc->frag[0].addr),
@@ -1517,8 +1517,8 @@ static void set_rx_mode(struct net_devic
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAll | AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit)
-			   ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sungem.c linux-libre-2.6.33-gnu1/drivers/net/sungem.c
--- linux-libre-2.6.32-gnu1/drivers/net/sungem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sungem.c	2010-02-24 13:52:17.000000000 -0500
@@ -1034,10 +1034,8 @@ static netdev_tx_t gem_start_xmit(struct
 			(csum_stuff_off << 21));
 	}
 
-	local_irq_save(flags);
-	if (!spin_trylock(&gp->tx_lock)) {
+	if (!spin_trylock_irqsave(&gp->tx_lock, flags)) {
 		/* Tell upper layer to requeue */
-		local_irq_restore(flags);
 		return NETDEV_TX_LOCKED;
 	}
 	/* We raced with gem_do_stop() */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sungem.h linux-libre-2.6.33-gnu1/drivers/net/sungem.h
--- linux-libre-2.6.32-gnu1/drivers/net/sungem.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sungem.h	2010-02-24 13:52:17.000000000 -0500
@@ -1031,8 +1031,8 @@ struct gem {
 #endif
 };
 
-#define found_mii_phy(gp) ((gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) \
-				&& gp->phy_mii.def && gp->phy_mii.def->ops)
+#define found_mii_phy(gp) ((gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) && \
+			   gp->phy_mii.def && gp->phy_mii.def->ops)
 
 #define ALIGNED_RX_SKB_ADDR(addr) \
         ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sunhme.c linux-libre-2.6.33-gnu1/drivers/net/sunhme.c
--- linux-libre-2.6.32-gnu1/drivers/net/sunhme.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sunhme.c	2010-02-24 13:52:17.000000000 -0500
@@ -1226,10 +1226,16 @@ static void happy_meal_clean_rings(struc
 			for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
 				txd = &hp->happy_block->happy_meal_txd[i];
 				dma_addr = hme_read_desc32(hp, &txd->tx_addr);
-				dma_unmap_single(hp->dma_dev, dma_addr,
-						 (hme_read_desc32(hp, &txd->tx_flags)
-						  & TXFLAG_SIZE),
-						 DMA_TO_DEVICE);
+				if (!frag)
+					dma_unmap_single(hp->dma_dev, dma_addr,
+							 (hme_read_desc32(hp, &txd->tx_flags)
+							  & TXFLAG_SIZE),
+							 DMA_TO_DEVICE);
+				else
+					dma_unmap_page(hp->dma_dev, dma_addr,
+							 (hme_read_desc32(hp, &txd->tx_flags)
+							  & TXFLAG_SIZE),
+							 DMA_TO_DEVICE);
 
 				if (frag != skb_shinfo(skb)->nr_frags)
 					i++;
@@ -1953,7 +1959,10 @@ static void happy_meal_tx(struct happy_m
 			dma_len = hme_read_desc32(hp, &this->tx_flags);
 
 			dma_len &= TXFLAG_SIZE;
-			dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
+			if (!frag)
+				dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
+			else
+				dma_unmap_page(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
 
 			elem = NEXT_TX(elem);
 			this = &txbase[elem];
@@ -2184,7 +2193,7 @@ static int happy_meal_open(struct net_de
 	 * into a single source which we register handling at probe time.
 	 */
 	if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
-		if (request_irq(dev->irq, &happy_meal_interrupt,
+		if (request_irq(dev->irq, happy_meal_interrupt,
 				IRQF_SHARED, dev->name, (void *)dev)) {
 			HMD(("EAGAIN\n"));
 			printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n",
@@ -3047,9 +3056,9 @@ static int __devinit happy_meal_pci_prob
 		int len;
 
 		if (qfe_slot != -1 &&
-		    (addr = of_get_property(dp,
-					    "local-mac-address", &len)) != NULL
-		    && len == 6) {
+		    (addr = of_get_property(dp, "local-mac-address", &len))
+			!= NULL &&
+		    len == 6) {
 			memcpy(dev->dev_addr, addr, 6);
 		} else {
 			memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sunlance.c linux-libre-2.6.33-gnu1/drivers/net/sunlance.c
--- linux-libre-2.6.32-gnu1/drivers/net/sunlance.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sunlance.c	2010-02-24 13:52:17.000000000 -0500
@@ -923,7 +923,7 @@ static int lance_open(struct net_device
 
 	STOP_LANCE(lp);
 
-	if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED,
+	if (request_irq(dev->irq, lance_interrupt, IRQF_SHARED,
 			lancestr, (void *) dev)) {
 		printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq);
 		return -EAGAIN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/sunqe.c linux-libre-2.6.33-gnu1/drivers/net/sunqe.c
--- linux-libre-2.6.32-gnu1/drivers/net/sunqe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/sunqe.c	2010-02-24 13:52:17.000000000 -0500
@@ -807,7 +807,7 @@ static struct sunqec * __devinit get_qec
 
 			qec_init_once(qecp, op);
 
-			if (request_irq(op->irqs[0], &qec_interrupt,
+			if (request_irq(op->irqs[0], qec_interrupt,
 					IRQF_SHARED, "qec", (void *) qecp)) {
 				printk(KERN_ERR "qec: Can't register irq.\n");
 				goto fail;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tc35815.c linux-libre-2.6.33-gnu1/drivers/net/tc35815.c
--- linux-libre-2.6.32-gnu1/drivers/net/tc35815.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tc35815.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,11 +22,7 @@
  * All Rights Reserved.
  */
 
-#ifdef TC35815_NAPI
-#define DRV_VERSION	"1.38-NAPI"
-#else
-#define DRV_VERSION	"1.38"
-#endif
+#define DRV_VERSION	"1.39"
 static const char *version = "tc35815.c:v" DRV_VERSION "\n";
 #define MODNAME			"tc35815"
 
@@ -54,13 +50,6 @@ static const char *version = "tc35815.c:
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
-/* First, a few definitions that the brave might change. */
-
-#define GATHER_TXINT	/* On-Demand Tx Interrupt */
-#define WORKAROUND_LOSTCAR
-#define WORKAROUND_100HALF_PROMISC
-/* #define TC35815_USE_PACKEDBUFFER */
-
 enum tc35815_chiptype {
 	TC35815CF = 0,
 	TC35815_NWU,
@@ -330,17 +319,10 @@ struct BDesc {
 
 
 /* Some useful constants. */
-#undef NO_CHECK_CARRIER	/* Does not check No-Carrier with TP */
 
-#ifdef NO_CHECK_CARRIER
-#define TX_CTL_CMD	(Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
-	Tx_EnExColl | Tx_EnExDefer | Tx_EnUnder | \
-	Tx_En)	/* maybe  0x7b01 */
-#else
-#define TX_CTL_CMD	(Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
+#define TX_CTL_CMD	(Tx_EnTxPar | Tx_EnLateColl | \
 	Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \
 	Tx_En)	/* maybe  0x7b01 */
-#endif
 /* Do not use Rx_StripCRC -- it causes trouble on BLEx/FDAEx condition */
 #define RX_CTL_CMD	(Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \
 	| Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn) /* maybe 0x6f01 */
@@ -361,13 +343,6 @@ struct BDesc {
 #define TX_THRESHOLD_KEEP_LIMIT 10
 
 /* 16 + RX_BUF_NUM * 8 + RX_FD_NUM * 16 + TX_FD_NUM * 32 <= PAGE_SIZE*FD_PAGE_NUM */
-#ifdef TC35815_USE_PACKEDBUFFER
-#define FD_PAGE_NUM 2
-#define RX_BUF_NUM	8	/* >= 2 */
-#define RX_FD_NUM	250	/* >= 32 */
-#define TX_FD_NUM	128
-#define RX_BUF_SIZE	PAGE_SIZE
-#else /* TC35815_USE_PACKEDBUFFER */
 #define FD_PAGE_NUM 4
 #define RX_BUF_NUM	128	/* < 256 */
 #define RX_FD_NUM	256	/* >= 32 */
@@ -381,7 +356,6 @@ struct BDesc {
 #define RX_BUF_SIZE	\
 	L1_CACHE_ALIGN(ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN + NET_IP_ALIGN)
 #endif
-#endif /* TC35815_USE_PACKEDBUFFER */
 #define RX_FD_RESERVE	(2 / 2)	/* max 2 BD per RxFD */
 #define NAPI_WEIGHT	16
 
@@ -439,11 +413,7 @@ struct tc35815_local {
 	/*
 	 * Transmitting: Batch Mode.
 	 *	1 BD in 1 TxFD.
-	 * Receiving: Packing Mode. (TC35815_USE_PACKEDBUFFER)
-	 *	1 circular FD for Free Buffer List.
-	 *	RX_BUF_NUM BD in Free Buffer FD.
-	 *	One Free Buffer BD has PAGE_SIZE data buffer.
-	 * Or Non-Packing Mode.
+	 * Receiving: Non-Packing Mode.
 	 *	1 circular FD for Free Buffer List.
 	 *	RX_BUF_NUM BD in Free Buffer FD.
 	 *	One Free Buffer BD has ETH_FRAME_LEN data buffer.
@@ -457,21 +427,11 @@ struct tc35815_local {
 	struct RxFD *rfd_limit;
 	struct RxFD *rfd_cur;
 	struct FrFD *fbl_ptr;
-#ifdef TC35815_USE_PACKEDBUFFER
-	unsigned char fbl_curid;
-	void *data_buf[RX_BUF_NUM];		/* packing */
-	dma_addr_t data_buf_dma[RX_BUF_NUM];
-	struct {
-		struct sk_buff *skb;
-		dma_addr_t skb_dma;
-	} tx_skbs[TX_FD_NUM];
-#else
 	unsigned int fbl_count;
 	struct {
 		struct sk_buff *skb;
 		dma_addr_t skb_dma;
 	} tx_skbs[TX_FD_NUM], rx_skbs[RX_BUF_NUM];
-#endif
 	u32 msg_enable;
 	enum tc35815_chiptype chiptype;
 };
@@ -486,51 +446,6 @@ static inline void *fd_bus_to_virt(struc
 	return (void *)((u8 *)lp->fd_buf + (bus - lp->fd_buf_dma));
 }
 #endif
-#ifdef TC35815_USE_PACKEDBUFFER
-static inline void *rxbuf_bus_to_virt(struct tc35815_local *lp, dma_addr_t bus)
-{
-	int i;
-	for (i = 0; i < RX_BUF_NUM; i++) {
-		if (bus >= lp->data_buf_dma[i] &&
-		    bus < lp->data_buf_dma[i] + PAGE_SIZE)
-			return (void *)((u8 *)lp->data_buf[i] +
-					(bus - lp->data_buf_dma[i]));
-	}
-	return NULL;
-}
-
-#define TC35815_DMA_SYNC_ONDEMAND
-static void *alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle)
-{
-#ifdef TC35815_DMA_SYNC_ONDEMAND
-	void *buf;
-	/* pci_map + pci_dma_sync will be more effective than
-	 * pci_alloc_consistent on some archs. */
-	buf = (void *)__get_free_page(GFP_ATOMIC);
-	if (!buf)
-		return NULL;
-	*dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE,
-				     PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(hwdev, *dma_handle)) {
-		free_page((unsigned long)buf);
-		return NULL;
-	}
-	return buf;
-#else
-	return pci_alloc_consistent(hwdev, PAGE_SIZE, dma_handle);
-#endif
-}
-
-static void free_rxbuf_page(struct pci_dev *hwdev, void *buf, dma_addr_t dma_handle)
-{
-#ifdef TC35815_DMA_SYNC_ONDEMAND
-	pci_unmap_single(hwdev, dma_handle, PAGE_SIZE, PCI_DMA_FROMDEVICE);
-	free_page((unsigned long)buf);
-#else
-	pci_free_consistent(hwdev, PAGE_SIZE, buf, dma_handle);
-#endif
-}
-#else /* TC35815_USE_PACKEDBUFFER */
 static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
 				       struct pci_dev *hwdev,
 				       dma_addr_t *dma_handle)
@@ -555,19 +470,14 @@ static void free_rxbuf_skb(struct pci_de
 			 PCI_DMA_FROMDEVICE);
 	dev_kfree_skb_any(skb);
 }
-#endif /* TC35815_USE_PACKEDBUFFER */
 
 /* Index to functions, as function prototypes. */
 
 static int	tc35815_open(struct net_device *dev);
 static int	tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t	tc35815_interrupt(int irq, void *dev_id);
-#ifdef TC35815_NAPI
 static int	tc35815_rx(struct net_device *dev, int limit);
 static int	tc35815_poll(struct napi_struct *napi, int budget);
-#else
-static void	tc35815_rx(struct net_device *dev);
-#endif
 static void	tc35815_txdone(struct net_device *dev);
 static int	tc35815_close(struct net_device *dev);
 static struct	net_device_stats *tc35815_get_stats(struct net_device *dev);
@@ -654,8 +564,6 @@ static void tc_handle_link_change(struct
 		 * TX4939 PCFG.SPEEDn bit will be changed on
 		 * NETDEV_CHANGE event.
 		 */
-
-#if !defined(NO_CHECK_CARRIER) && defined(WORKAROUND_LOSTCAR)
 		/*
 		 * WORKAROUND: enable LostCrS only if half duplex
 		 * operation.
@@ -665,7 +573,6 @@ static void tc_handle_link_change(struct
 		    lp->chiptype != TC35815_TX4939)
 			tc_writel(tc_readl(&tr->Tx_Ctl) | Tx_EnLCarr,
 				  &tr->Tx_Ctl);
-#endif
 
 		lp->speed = phydev->speed;
 		lp->duplex = phydev->duplex;
@@ -674,11 +581,9 @@ static void tc_handle_link_change(struct
 
 	if (phydev->link != lp->link) {
 		if (phydev->link) {
-#ifdef WORKAROUND_100HALF_PROMISC
 			/* delayed promiscuous enabling */
 			if (dev->flags & IFF_PROMISC)
 				tc35815_set_multicast_list(dev);
-#endif
 		} else {
 			lp->speed = 0;
 			lp->duplex = -1;
@@ -923,9 +828,7 @@ static int __devinit tc35815_init_one(st
 	dev->netdev_ops = &tc35815_netdev_ops;
 	dev->ethtool_ops = &tc35815_ethtool_ops;
 	dev->watchdog_timeo = TC35815_TX_TIMEOUT;
-#ifdef TC35815_NAPI
 	netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT);
-#endif
 
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long)ioaddr;
@@ -1007,25 +910,6 @@ tc35815_init_queues(struct net_device *d
 		if (!lp->fd_buf)
 			return -ENOMEM;
 		for (i = 0; i < RX_BUF_NUM; i++) {
-#ifdef TC35815_USE_PACKEDBUFFER
-			lp->data_buf[i] =
-				alloc_rxbuf_page(lp->pci_dev,
-						 &lp->data_buf_dma[i]);
-			if (!lp->data_buf[i]) {
-				while (--i >= 0) {
-					free_rxbuf_page(lp->pci_dev,
-							lp->data_buf[i],
-							lp->data_buf_dma[i]);
-					lp->data_buf[i] = NULL;
-				}
-				pci_free_consistent(lp->pci_dev,
-						    PAGE_SIZE * FD_PAGE_NUM,
-						    lp->fd_buf,
-						    lp->fd_buf_dma);
-				lp->fd_buf = NULL;
-				return -ENOMEM;
-			}
-#else
 			lp->rx_skbs[i].skb =
 				alloc_rxbuf_skb(dev, lp->pci_dev,
 						&lp->rx_skbs[i].skb_dma);
@@ -1043,15 +927,9 @@ tc35815_init_queues(struct net_device *d
 				lp->fd_buf = NULL;
 				return -ENOMEM;
 			}
-#endif
 		}
 		printk(KERN_DEBUG "%s: FD buf %p DataBuf",
 		       dev->name, lp->fd_buf);
-#ifdef TC35815_USE_PACKEDBUFFER
-		printk(" DataBuf");
-		for (i = 0; i < RX_BUF_NUM; i++)
-			printk(" %p", lp->data_buf[i]);
-#endif
 		printk("\n");
 	} else {
 		for (i = 0; i < FD_PAGE_NUM; i++)
@@ -1084,7 +962,6 @@ tc35815_init_queues(struct net_device *d
 	lp->fbl_ptr = (struct FrFD *)fd_addr;
 	lp->fbl_ptr->fd.FDNext = cpu_to_le32(fd_virt_to_bus(lp, lp->fbl_ptr));
 	lp->fbl_ptr->fd.FDCtl = cpu_to_le32(RX_BUF_NUM | FD_CownsFD);
-#ifndef TC35815_USE_PACKEDBUFFER
 	/*
 	 * move all allocated skbs to head of rx_skbs[] array.
 	 * fbl_count mighe not be RX_BUF_NUM if alloc_rxbuf_skb() in
@@ -1102,11 +979,7 @@ tc35815_init_queues(struct net_device *d
 			lp->fbl_count++;
 		}
 	}
-#endif
 	for (i = 0; i < RX_BUF_NUM; i++) {
-#ifdef TC35815_USE_PACKEDBUFFER
-		lp->fbl_ptr->bd[i].BuffData = cpu_to_le32(lp->data_buf_dma[i]);
-#else
 		if (i >= lp->fbl_count) {
 			lp->fbl_ptr->bd[i].BuffData = 0;
 			lp->fbl_ptr->bd[i].BDCtl = 0;
@@ -1114,15 +987,11 @@ tc35815_init_queues(struct net_device *d
 		}
 		lp->fbl_ptr->bd[i].BuffData =
 			cpu_to_le32(lp->rx_skbs[i].skb_dma);
-#endif
 		/* BDID is index of FrFD.bd[] */
 		lp->fbl_ptr->bd[i].BDCtl =
 			cpu_to_le32(BD_CownsBD | (i << BD_RxBDID_SHIFT) |
 				    RX_BUF_SIZE);
 	}
-#ifdef TC35815_USE_PACKEDBUFFER
-	lp->fbl_curid = 0;
-#endif
 
 	printk(KERN_DEBUG "%s: TxFD %p RxFD %p FrFD %p\n",
 	       dev->name, lp->tfd_base, lp->rfd_base, lp->fbl_ptr);
@@ -1196,19 +1065,11 @@ tc35815_free_queues(struct net_device *d
 	lp->fbl_ptr = NULL;
 
 	for (i = 0; i < RX_BUF_NUM; i++) {
-#ifdef TC35815_USE_PACKEDBUFFER
-		if (lp->data_buf[i]) {
-			free_rxbuf_page(lp->pci_dev,
-					lp->data_buf[i], lp->data_buf_dma[i]);
-			lp->data_buf[i] = NULL;
-		}
-#else
 		if (lp->rx_skbs[i].skb) {
 			free_rxbuf_skb(lp->pci_dev, lp->rx_skbs[i].skb,
 				       lp->rx_skbs[i].skb_dma);
 			lp->rx_skbs[i].skb = NULL;
 		}
-#endif
 	}
 	if (lp->fd_buf) {
 		pci_free_consistent(lp->pci_dev, PAGE_SIZE * FD_PAGE_NUM,
@@ -1254,7 +1115,7 @@ dump_rxfd(struct RxFD *fd)
 	return bd_count;
 }
 
-#if defined(DEBUG) || defined(TC35815_USE_PACKEDBUFFER)
+#ifdef DEBUG
 static void
 dump_frfd(struct FrFD *fd)
 {
@@ -1271,9 +1132,7 @@ dump_frfd(struct FrFD *fd)
 		       le32_to_cpu(fd->bd[i].BDCtl));
 	printk("\n");
 }
-#endif
 
-#ifdef DEBUG
 static void
 panic_queues(struct net_device *dev)
 {
@@ -1389,7 +1248,7 @@ tc35815_open(struct net_device *dev)
 	 * This is used if the interrupt line can turned off (shared).
 	 * See 3c503.c for an example of selecting the IRQ at config-time.
 	 */
-	if (request_irq(dev->irq, &tc35815_interrupt, IRQF_SHARED,
+	if (request_irq(dev->irq, tc35815_interrupt, IRQF_SHARED,
 			dev->name, dev))
 		return -EAGAIN;
 
@@ -1400,9 +1259,7 @@ tc35815_open(struct net_device *dev)
 		return -EAGAIN;
 	}
 
-#ifdef TC35815_NAPI
 	napi_enable(&lp->napi);
-#endif
 
 	/* Reset the hardware here. Don't forget to set the station address. */
 	spin_lock_irq(&lp->lock);
@@ -1478,9 +1335,7 @@ static int tc35815_send_packet(struct sk
 			(struct tc35815_regs __iomem *)dev->base_addr;
 		/* Start DMA Transmitter. */
 		txfd->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
-#ifdef GATHER_TXINT
 		txfd->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
-#endif
 		if (netif_msg_tx_queued(lp)) {
 			printk("%s: starting TxFD.\n", dev->name);
 			dump_txfd(txfd);
@@ -1536,11 +1391,7 @@ static void tc35815_fatal_error_interrup
 	tc35815_schedule_restart(dev);
 }
 
-#ifdef TC35815_NAPI
 static int tc35815_do_interrupt(struct net_device *dev, u32 status, int limit)
-#else
-static int tc35815_do_interrupt(struct net_device *dev, u32 status)
-#endif
 {
 	struct tc35815_local *lp = netdev_priv(dev);
 	int ret = -1;
@@ -1579,20 +1430,15 @@ static int tc35815_do_interrupt(struct n
 	/* normal notification */
 	if (status & Int_IntMacRx) {
 		/* Got a packet(s). */
-#ifdef TC35815_NAPI
 		ret = tc35815_rx(dev, limit);
-#else
-		tc35815_rx(dev);
-		ret = 0;
-#endif
 		lp->lstats.rx_ints++;
 	}
 	if (status & Int_IntMacTx) {
 		/* Transmit complete. */
 		lp->lstats.tx_ints++;
 		tc35815_txdone(dev);
-		netif_wake_queue(dev);
-		ret = 0;
+		if (ret < 0)
+			ret = 0;
 	}
 	return ret;
 }
@@ -1607,7 +1453,6 @@ static irqreturn_t tc35815_interrupt(int
 	struct tc35815_local *lp = netdev_priv(dev);
 	struct tc35815_regs __iomem *tr =
 		(struct tc35815_regs __iomem *)dev->base_addr;
-#ifdef TC35815_NAPI
 	u32 dmactl = tc_readl(&tr->DMA_Ctl);
 
 	if (!(dmactl & DMA_IntMask)) {
@@ -1624,22 +1469,6 @@ static irqreturn_t tc35815_interrupt(int
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
-#else
-	int handled;
-	u32 status;
-
-	spin_lock(&lp->lock);
-	status = tc_readl(&tr->Int_Src);
-	/* BLEx, FDAEx will be cleared later */
-	tc_writel(status & ~(Int_BLEx | Int_FDAEx),
-		  &tr->Int_Src);	/* write to clear */
-	handled = tc35815_do_interrupt(dev, status);
-	if (status & (Int_BLEx | Int_FDAEx))
-		tc_writel(status & (Int_BLEx | Int_FDAEx), &tr->Int_Src);
-	(void)tc_readl(&tr->Int_Src);	/* flush */
-	spin_unlock(&lp->lock);
-	return IRQ_RETVAL(handled >= 0);
-#endif /* TC35815_NAPI */
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1652,20 +1481,13 @@ static void tc35815_poll_controller(stru
 #endif
 
 /* We have a good packet(s), get it/them out of the buffers. */
-#ifdef TC35815_NAPI
 static int
 tc35815_rx(struct net_device *dev, int limit)
-#else
-static void
-tc35815_rx(struct net_device *dev)
-#endif
 {
 	struct tc35815_local *lp = netdev_priv(dev);
 	unsigned int fdctl;
 	int i;
-#ifdef TC35815_NAPI
 	int received = 0;
-#endif
 
 	while (!((fdctl = le32_to_cpu(lp->rfd_cur->fd.FDCtl)) & FD_CownsFD)) {
 		int status = le32_to_cpu(lp->rfd_cur->fd.FDStat);
@@ -1684,52 +1506,9 @@ tc35815_rx(struct net_device *dev)
 			struct sk_buff *skb;
 			unsigned char *data;
 			int cur_bd;
-#ifdef TC35815_USE_PACKEDBUFFER
-			int offset;
-#endif
 
-#ifdef TC35815_NAPI
 			if (--limit < 0)
 				break;
-#endif
-#ifdef TC35815_USE_PACKEDBUFFER
-			BUG_ON(bd_count > 2);
-			skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
-			if (skb == NULL) {
-				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
-				       dev->name);
-				dev->stats.rx_dropped++;
-				break;
-			}
-			skb_reserve(skb, NET_IP_ALIGN);
-
-			data = skb_put(skb, pkt_len);
-
-			/* copy from receive buffer */
-			cur_bd = 0;
-			offset = 0;
-			while (offset < pkt_len && cur_bd < bd_count) {
-				int len = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BDCtl) &
-					BD_BuffLength_MASK;
-				dma_addr_t dma = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BuffData);
-				void *rxbuf = rxbuf_bus_to_virt(lp, dma);
-				if (offset + len > pkt_len)
-					len = pkt_len - offset;
-#ifdef TC35815_DMA_SYNC_ONDEMAND
-				pci_dma_sync_single_for_cpu(lp->pci_dev,
-							    dma, len,
-							    PCI_DMA_FROMDEVICE);
-#endif
-				memcpy(data + offset, rxbuf, len);
-#ifdef TC35815_DMA_SYNC_ONDEMAND
-				pci_dma_sync_single_for_device(lp->pci_dev,
-							       dma, len,
-							       PCI_DMA_FROMDEVICE);
-#endif
-				offset += len;
-				cur_bd++;
-			}
-#else /* TC35815_USE_PACKEDBUFFER */
 			BUG_ON(bd_count > 1);
 			cur_bd = (le32_to_cpu(lp->rfd_cur->bd[0].BDCtl)
 				  & BD_RxBDID_MASK) >> BD_RxBDID_SHIFT;
@@ -1757,16 +1536,11 @@ tc35815_rx(struct net_device *dev)
 				memmove(skb->data, skb->data - NET_IP_ALIGN,
 					pkt_len);
 			data = skb_put(skb, pkt_len);
-#endif /* TC35815_USE_PACKEDBUFFER */
 			if (netif_msg_pktdata(lp))
 				print_eth(data);
 			skb->protocol = eth_type_trans(skb, dev);
-#ifdef TC35815_NAPI
 			netif_receive_skb(skb);
 			received++;
-#else
-			netif_rx(skb);
-#endif
 			dev->stats.rx_packets++;
 			dev->stats.rx_bytes += pkt_len;
 		} else {
@@ -1803,19 +1577,11 @@ tc35815_rx(struct net_device *dev)
 			BUG_ON(id >= RX_BUF_NUM);
 #endif
 			/* free old buffers */
-#ifdef TC35815_USE_PACKEDBUFFER
-			while (lp->fbl_curid != id)
-#else
 			lp->fbl_count--;
 			while (lp->fbl_count < RX_BUF_NUM)
-#endif
 			{
-#ifdef TC35815_USE_PACKEDBUFFER
-				unsigned char curid = lp->fbl_curid;
-#else
 				unsigned char curid =
 					(id + 1 + lp->fbl_count) % RX_BUF_NUM;
-#endif
 				struct BDesc *bd = &lp->fbl_ptr->bd[curid];
 #ifdef DEBUG
 				bdctl = le32_to_cpu(bd->BDCtl);
@@ -1826,7 +1592,6 @@ tc35815_rx(struct net_device *dev)
 				}
 #endif
 				/* pass BD to controller */
-#ifndef TC35815_USE_PACKEDBUFFER
 				if (!lp->rx_skbs[curid].skb) {
 					lp->rx_skbs[curid].skb =
 						alloc_rxbuf_skb(dev,
@@ -1836,21 +1601,11 @@ tc35815_rx(struct net_device *dev)
 						break; /* try on next reception */
 					bd->BuffData = cpu_to_le32(lp->rx_skbs[curid].skb_dma);
 				}
-#endif /* TC35815_USE_PACKEDBUFFER */
 				/* Note: BDLength was modified by chip. */
 				bd->BDCtl = cpu_to_le32(BD_CownsBD |
 							(curid << BD_RxBDID_SHIFT) |
 							RX_BUF_SIZE);
-#ifdef TC35815_USE_PACKEDBUFFER
-				lp->fbl_curid = (curid + 1) % RX_BUF_NUM;
-				if (netif_msg_rx_status(lp)) {
-					printk("%s: Entering new FBD %d\n",
-					       dev->name, lp->fbl_curid);
-					dump_frfd(lp->fbl_ptr);
-				}
-#else
 				lp->fbl_count++;
-#endif
 			}
 		}
 
@@ -1882,12 +1637,9 @@ tc35815_rx(struct net_device *dev)
 #endif
 	}
 
-#ifdef TC35815_NAPI
 	return received;
-#endif
 }
 
-#ifdef TC35815_NAPI
 static int tc35815_poll(struct napi_struct *napi, int budget)
 {
 	struct tc35815_local *lp = container_of(napi, struct tc35815_local, napi);
@@ -1924,13 +1676,8 @@ static int tc35815_poll(struct napi_stru
 	}
 	return received;
 }
-#endif
 
-#ifdef NO_CHECK_CARRIER
-#define TX_STA_ERR	(Tx_ExColl|Tx_Under|Tx_Defer|Tx_LateColl|Tx_TxPar|Tx_SQErr)
-#else
 #define TX_STA_ERR	(Tx_ExColl|Tx_Under|Tx_Defer|Tx_NCarr|Tx_LateColl|Tx_TxPar|Tx_SQErr)
-#endif
 
 static void
 tc35815_check_tx_stat(struct net_device *dev, int status)
@@ -1944,16 +1691,12 @@ tc35815_check_tx_stat(struct net_device
 	if (status & Tx_TxColl_MASK)
 		dev->stats.collisions += status & Tx_TxColl_MASK;
 
-#ifndef NO_CHECK_CARRIER
 	/* TX4939 does not have NCarr */
 	if (lp->chiptype == TC35815_TX4939)
 		status &= ~Tx_NCarr;
-#ifdef WORKAROUND_LOSTCAR
 	/* WORKAROUND: ignore LostCrS in full duplex operation */
 	if (!lp->link || lp->duplex == DUPLEX_FULL)
 		status &= ~Tx_NCarr;
-#endif
-#endif
 
 	if (!(status & TX_STA_ERR)) {
 		/* no error. */
@@ -1983,12 +1726,10 @@ tc35815_check_tx_stat(struct net_device
 		dev->stats.tx_fifo_errors++;
 		msg = "Excessive Deferral.";
 	}
-#ifndef NO_CHECK_CARRIER
 	if (status & Tx_NCarr) {
 		dev->stats.tx_carrier_errors++;
 		msg = "Lost Carrier Sense.";
 	}
-#endif
 	if (status & Tx_LateColl) {
 		dev->stats.tx_aborted_errors++;
 		msg = "Late Collision.";
@@ -2044,11 +1785,7 @@ tc35815_txdone(struct net_device *dev)
 			pci_unmap_single(lp->pci_dev, lp->tx_skbs[lp->tfd_end].skb_dma, skb->len, PCI_DMA_TODEVICE);
 			lp->tx_skbs[lp->tfd_end].skb = NULL;
 			lp->tx_skbs[lp->tfd_end].skb_dma = 0;
-#ifdef TC35815_NAPI
 			dev_kfree_skb_any(skb);
-#else
-			dev_kfree_skb_irq(skb);
-#endif
 		}
 		txfd->fd.FDSystem = cpu_to_le32(0xffffffff);
 
@@ -2083,9 +1820,7 @@ tc35815_txdone(struct net_device *dev)
 
 				/* start DMA Transmitter again */
 				txhead->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
-#ifdef GATHER_TXINT
 				txhead->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
-#endif
 				if (netif_msg_tx_queued(lp)) {
 					printk("%s: start TxFD on queue.\n",
 					       dev->name);
@@ -2112,9 +1847,7 @@ tc35815_close(struct net_device *dev)
 	struct tc35815_local *lp = netdev_priv(dev);
 
 	netif_stop_queue(dev);
-#ifdef TC35815_NAPI
 	napi_disable(&lp->napi);
-#endif
 	if (lp->phy_dev)
 		phy_stop(lp->phy_dev);
 	cancel_work_sync(&lp->restart_work);
@@ -2198,14 +1931,12 @@ tc35815_set_multicast_list(struct net_de
 		(struct tc35815_regs __iomem *)dev->base_addr;
 
 	if (dev->flags & IFF_PROMISC) {
-#ifdef WORKAROUND_100HALF_PROMISC
 		/* With some (all?) 100MHalf HUB, controller will hang
 		 * if we enabled promiscuous mode before linkup... */
 		struct tc35815_local *lp = netdev_priv(dev);
 
 		if (!lp->link)
 			return;
-#endif
 		/* Enable promiscuous mode */
 		tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl);
 	} else if ((dev->flags & IFF_ALLMULTI) ||
@@ -2392,9 +2123,6 @@ static void tc35815_chip_init(struct net
 		tc_writel(DMA_BURST_SIZE | DMA_RxAlign_2, &tr->DMA_Ctl);
 	else
 		tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl);
-#ifdef TC35815_USE_PACKEDBUFFER
-	tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize);	/* Packing */
-#endif
 	tc_writel(0, &tr->TxPollCtr);	/* Batch mode */
 	tc_writel(TX_THRESHOLD, &tr->TxThrsh);
 	tc_writel(INT_EN_CMD, &tr->Int_En);
@@ -2412,19 +2140,12 @@ static void tc35815_chip_init(struct net
 	tc_writel(RX_CTL_CMD, &tr->Rx_Ctl);	/* start MAC receiver */
 
 	/* start MAC transmitter */
-#ifndef NO_CHECK_CARRIER
 	/* TX4939 does not have EnLCarr */
 	if (lp->chiptype == TC35815_TX4939)
 		txctl &= ~Tx_EnLCarr;
-#ifdef WORKAROUND_LOSTCAR
 	/* WORKAROUND: ignore LostCrS in full duplex operation */
 	if (!lp->phy_dev || !lp->link || lp->duplex == DUPLEX_FULL)
 		txctl &= ~Tx_EnLCarr;
-#endif
-#endif /* !NO_CHECK_CARRIER */
-#ifdef GATHER_TXINT
-	txctl &= ~Tx_EnComp;	/* disable global tx completion int. */
-#endif
 	tc_writel(txctl, &tr->Tx_Ctl);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tehuti.c linux-libre-2.6.33-gnu1/drivers/net/tehuti.c
--- linux-libre-2.6.32-gnu1/drivers/net/tehuti.c	2013-05-03 14:01:14.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/tehuti.c	2013-05-03 12:08:35.000000000 -0400
@@ -420,7 +420,7 @@ static int bdx_hw_start(struct bdx_priv
 		  GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB);
 
 #define BDX_IRQ_TYPE	((priv->nic->irq_type == IRQ_MSI)?0:IRQF_SHARED)
-	if ((rc = request_irq(priv->pdev->irq, &bdx_isr_napi, BDX_IRQ_TYPE,
+	if ((rc = request_irq(priv->pdev->irq, bdx_isr_napi, BDX_IRQ_TYPE,
 			 ndev->name, ndev)))
 		goto err_irq;
 	bdx_enable_interrupts(priv);
@@ -1784,9 +1784,9 @@ static void bdx_tx_cleanup(struct bdx_pr
 	}
 #endif
 
-	if (unlikely(netif_queue_stopped(priv->ndev)
-		     && netif_carrier_ok(priv->ndev)
-		     && (priv->tx_level >= BDX_MIN_TX_LEVEL))) {
+	if (unlikely(netif_queue_stopped(priv->ndev) &&
+		     netif_carrier_ok(priv->ndev) &&
+		     (priv->tx_level >= BDX_MIN_TX_LEVEL))) {
 		DBG("%s: %s: TX Q WAKE level %d\n",
 		    BDX_DRV_NAME, priv->ndev->name, priv->tx_level);
 		netif_wake_queue(priv->ndev);
@@ -1878,7 +1878,7 @@ static void bdx_tx_push_desc_safe(struct
 			udelay(50);	/* give hw a chance to clean fifo */
 			continue;
 		}
-		avail = MIN(avail, size);
+		avail = min(avail, size);
 		DBG("about to push  %d bytes starting %p size %d\n", avail,
 		    data, size);
 		bdx_tx_push_desc(priv, data, avail);
@@ -2105,12 +2105,6 @@ err_pci:
 }
 
 /****************** Ethtool interface *********************/
-/* get strings for tests */
-static const char
- bdx_test_names[][ETH_GSTRING_LEN] = {
-	"No tests defined"
-};
-
 /* get strings for statistics counters */
 static const char
  bdx_stat_names[][ETH_GSTRING_LEN] = {
@@ -2279,8 +2273,8 @@ bdx_set_coalesce(struct net_device *netd
 	    (((tx_max_coal * BDX_TXF_DESC_SZ) + PCK_TH_MULT - 1)
 	     / PCK_TH_MULT);
 
-	if ((rx_coal > 0x7FFF) || (tx_coal > 0x7FFF)
-	    || (rx_max_coal > 0xF) || (tx_max_coal > 0xF))
+	if ((rx_coal > 0x7FFF) || (tx_coal > 0x7FFF) ||
+	    (rx_max_coal > 0xF) || (tx_max_coal > 0xF))
 		return -EINVAL;
 
 	rdintcm = INT_REG_VAL(rx_coal, GET_INT_COAL_RC(priv->rdintcm),
@@ -2353,8 +2347,8 @@ bdx_set_ringparam(struct net_device *net
 		tx_size = 3;
 
 	/*Is there anything to do? */
-	if ((rx_size == priv->rxf_size)
-	    && (tx_size == priv->txd_size))
+	if ((rx_size == priv->rxf_size) &&
+	    (tx_size == priv->txd_size))
 		return 0;
 
 	priv->rxf_size = rx_size;
@@ -2380,9 +2374,6 @@ bdx_set_ringparam(struct net_device *net
 static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 {
 	switch (stringset) {
-	case ETH_SS_TEST:
-		memcpy(data, *bdx_test_names, sizeof(bdx_test_names));
-		break;
 	case ETH_SS_STATS:
 		memcpy(data, *bdx_stat_names, sizeof(bdx_stat_names));
 		break;
@@ -2390,15 +2381,21 @@ static void bdx_get_strings(struct net_d
 }
 
 /*
- * bdx_get_stats_count - return number of 64bit statistics counters
+ * bdx_get_sset_count - return number of statistics or tests
  * @netdev
  */
-static int bdx_get_stats_count(struct net_device *netdev)
+static int bdx_get_sset_count(struct net_device *netdev, int stringset)
 {
 	struct bdx_priv *priv = netdev_priv(netdev);
-	BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
-		   != sizeof(struct bdx_stats) / sizeof(u64));
-	return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names)	: 0);
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
+			   != sizeof(struct bdx_stats) / sizeof(u64));
+		return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names)	: 0);
+	default:
+		return -EINVAL;
+	}
 }
 
 /*
@@ -2441,7 +2438,7 @@ static void bdx_ethtool_ops(struct net_d
 		.get_sg = ethtool_op_get_sg,
 		.get_tso = ethtool_op_get_tso,
 		.get_strings = bdx_get_strings,
-		.get_stats_count = bdx_get_stats_count,
+		.get_sset_count = bdx_get_sset_count,
 		.get_ethtool_stats = bdx_get_ethtool_stats,
 	};
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tehuti.h linux-libre-2.6.33-gnu1/drivers/net/tehuti.h
--- linux-libre-2.6.32-gnu1/drivers/net/tehuti.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tehuti.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,8 +76,6 @@
 #define FIFO_SIZE  4096
 #define FIFO_EXTRA_SPACE            1024
 
-#define MIN(x, y)  ((x) < (y) ? (x) : (y))
-
 #if BITS_PER_LONG == 64
 #    define H32_64(x)  (u32) ((u64)(x) >> 32)
 #    define L32_64(x)  (u32) ((u64)(x) & 0xffffffff)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tg3.c linux-libre-2.6.33-gnu1/drivers/net/tg3.c
--- linux-libre-2.6.32-gnu1/drivers/net/tg3.c	2013-05-03 14:01:21.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/tg3.c	2013-05-03 12:08:42.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
  * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2009 Broadcom Corporation.
+ * Copyright (C) 2005-2010 Broadcom Corporation.
  *
 /*(DEBLOBBED)*/
 
@@ -61,8 +61,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.102"
-#define DRV_MODULE_RELDATE	"September 1, 2009"
+#define DRV_MODULE_VERSION	"3.106"
+#define DRV_MODULE_RELDATE	"January 12, 2010"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -130,6 +130,12 @@
 #define TG3_RX_STD_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
 #define TG3_RX_JMB_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
 
+#define TG3_RX_STD_BUFF_RING_SIZE \
+	(sizeof(struct ring_info) * TG3_RX_RING_SIZE)
+
+#define TG3_RX_JMB_BUFF_RING_SIZE \
+	(sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
+
 /* minimum number of free TX descriptors required to wake up TX process */
 #define TG3_TX_WAKEUP_THRESH(tnapi)		((tnapi)->tx_pending / 4)
 
@@ -226,6 +232,9 @@ static struct pci_device_id tg3_pci_tbl[
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -387,7 +396,7 @@ static void tg3_write_indirect_mbox(stru
 				       TG3_64BIT_REG_LOW, val);
 		return;
 	}
-	if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
+	if (off == TG3_RX_STD_PROD_IDX_REG) {
 		pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
 				       TG3_64BIT_REG_LOW, val);
 		return;
@@ -928,9 +937,10 @@ static void tg3_mdio_config_5785(struct
 	u32 val;
 	struct phy_device *phydev;
 
-	phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 	switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
 	case TG3_PHY_ID_BCM50610:
+	case TG3_PHY_ID_BCM50610M:
 		val = MAC_PHYCFG2_50610_LED_MODES;
 		break;
 	case TG3_PHY_ID_BCMAC131:
@@ -1018,11 +1028,15 @@ static void tg3_mdio_start(struct tg3 *t
 		else
 			tp->phy_addr = 1;
 
-		is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
+		if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
+			is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
+		else
+			is_serdes = tr32(TG3_CPMU_PHY_STRAP) &
+				    TG3_CPMU_PHY_STRAP_IS_SERDES;
 		if (is_serdes)
 			tp->phy_addr += 7;
 	} else
-		tp->phy_addr = PHY_ADDR;
+		tp->phy_addr = TG3_PHY_MII_ADDR;
 
 	if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
@@ -1053,7 +1067,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 	tp->mdio_bus->read     = &tg3_mdio_read;
 	tp->mdio_bus->write    = &tg3_mdio_write;
 	tp->mdio_bus->reset    = &tg3_mdio_reset;
-	tp->mdio_bus->phy_mask = ~(1 << PHY_ADDR);
+	tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR);
 	tp->mdio_bus->irq      = &tp->mdio_irq[0];
 
 	for (i = 0; i < PHY_MAX_ADDR; i++)
@@ -1075,7 +1089,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 		return i;
 	}
 
-	phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 	if (!phydev || !phydev->drv) {
 		printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
@@ -1087,8 +1101,14 @@ static int tg3_mdio_init(struct tg3 *tp)
 	switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
 	case TG3_PHY_ID_BCM57780:
 		phydev->interface = PHY_INTERFACE_MODE_GMII;
+		phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
 		break;
 	case TG3_PHY_ID_BCM50610:
+	case TG3_PHY_ID_BCM50610M:
+		phydev->dev_flags |= PHY_BRCM_CLEAR_RGMII_MODE |
+				     PHY_BRCM_RX_REFCLK_UNUSED |
+				     PHY_BRCM_DIS_TXCRXC_NOENRGY |
+				     PHY_BRCM_AUTO_PWRDWN_ENABLE;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
 			phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
@@ -1102,6 +1122,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 	case TG3_PHY_ID_RTL8201E:
 	case TG3_PHY_ID_BCMAC131:
 		phydev->interface = PHY_INTERFACE_MODE_MII;
+		phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
 		tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
 		break;
 	}
@@ -1302,7 +1323,7 @@ static void tg3_setup_flow_control(struc
 	u32 old_tx_mode = tp->tx_mode;
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
-		autoneg = tp->mdio_bus->phy_map[PHY_ADDR]->autoneg;
+		autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
 	else
 		autoneg = tp->link_config.autoneg;
 
@@ -1339,7 +1360,7 @@ static void tg3_adjust_link(struct net_d
 	u8 oldflowctrl, linkmesg = 0;
 	u32 mac_mode, lcl_adv, rmt_adv;
 	struct tg3 *tp = netdev_priv(dev);
-	struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+	struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 	spin_lock_bh(&tp->lock);
 
@@ -1354,8 +1375,11 @@ static void tg3_adjust_link(struct net_d
 
 		if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
-		else
+		else if (phydev->speed == SPEED_1000 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
 			mac_mode |= MAC_MODE_PORT_MODE_GMII;
+		else
+			mac_mode |= MAC_MODE_PORT_MODE_MII;
 
 		if (phydev->duplex == DUPLEX_HALF)
 			mac_mode |= MAC_MODE_HALF_DUPLEX;
@@ -1425,7 +1449,7 @@ static int tg3_phy_init(struct tg3 *tp)
 	/* Bring the PHY back to a known state. */
 	tg3_bmcr_reset(tp);
 
-	phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 	/* Attach the MAC to the PHY. */
 	phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
@@ -1452,7 +1476,7 @@ static int tg3_phy_init(struct tg3 *tp)
 				      SUPPORTED_Asym_Pause);
 		break;
 	default:
-		phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+		phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 		return -EINVAL;
 	}
 
@@ -1470,7 +1494,7 @@ static void tg3_phy_start(struct tg3 *tp
 	if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 		return;
 
-	phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+	phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 	if (tp->link_config.phy_is_low_power) {
 		tp->link_config.phy_is_low_power = 0;
@@ -1490,13 +1514,13 @@ static void tg3_phy_stop(struct tg3 *tp)
 	if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 		return;
 
-	phy_stop(tp->mdio_bus->phy_map[PHY_ADDR]);
+	phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 }
 
 static void tg3_phy_fini(struct tg3 *tp)
 {
 	if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-		phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+		phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 		tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
 	}
 }
@@ -2140,6 +2164,26 @@ static void tg3_power_down_phy(struct tg
 		tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
 		udelay(40);
 		return;
+	} else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+		u32 phytest;
+		if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
+			u32 phy;
+
+			tg3_writephy(tp, MII_ADVERTISE, 0);
+			tg3_writephy(tp, MII_BMCR,
+				     BMCR_ANENABLE | BMCR_ANRESTART);
+
+			tg3_writephy(tp, MII_TG3_FET_TEST,
+				     phytest | MII_TG3_FET_SHADOW_EN);
+			if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXMODE4, &phy)) {
+				phy |= MII_TG3_FET_SHDW_AUXMODE4_SBPD;
+				tg3_writephy(tp,
+					     MII_TG3_FET_SHDW_AUXMODE4,
+					     phy);
+			}
+			tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
+		}
+		return;
 	} else if (do_low_power) {
 		tg3_writephy(tp, MII_TG3_EXT_CTRL,
 			     MII_TG3_EXT_CTRL_FORCE_LED_OFF);
@@ -2209,7 +2253,7 @@ static void tg3_nvram_unlock(struct tg3
 static void tg3_enable_nvram_access(struct tg3 *tp)
 {
 	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+	    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
 		u32 nvaccess = tr32(NVRAM_ACCESS);
 
 		tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
@@ -2220,7 +2264,7 @@ static void tg3_enable_nvram_access(stru
 static void tg3_disable_nvram_access(struct tg3 *tp)
 {
 	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+	    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
 		u32 nvaccess = tr32(NVRAM_ACCESS);
 
 		tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
@@ -2465,7 +2509,7 @@ static int tg3_set_power_state(struct tg
 			struct phy_device *phydev;
 			u32 phyid, advertising;
 
-			phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+			phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 			tp->link_config.phy_is_low_power = 1;
 
@@ -3234,15 +3278,6 @@ relink:
 			pci_write_config_word(tp->pdev,
 					      tp->pcie_cap + PCI_EXP_LNKCTL,
 					      newlnkctl);
-	} else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-		u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
-		if (tp->link_config.active_speed == SPEED_100 ||
-		    tp->link_config.active_speed == SPEED_10)
-			newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-		else
-			newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-		if (newreg != oldreg)
-			tw32(TG3_PCIE_LNKCTL, newreg);
 	}
 
 	if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -4311,13 +4346,13 @@ static void tg3_tx(struct tg3_napi *tnap
 	struct netdev_queue *txq;
 	int index = tnapi - tp->napi;
 
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
 		index--;
 
 	txq = netdev_get_tx_queue(tp->dev, index);
 
 	while (sw_idx != hw_idx) {
-		struct tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
+		struct ring_info *ri = &tnapi->tx_buffers[sw_idx];
 		struct sk_buff *skb = ri->skb;
 		int i, tx_bug = 0;
 
@@ -4326,7 +4361,10 @@ static void tg3_tx(struct tg3_napi *tnap
 			return;
 		}
 
-		skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(ri, mapping),
+				 skb_headlen(skb),
+				 PCI_DMA_TODEVICE);
 
 		ri->skb = NULL;
 
@@ -4336,6 +4374,11 @@ static void tg3_tx(struct tg3_napi *tnap
 			ri = &tnapi->tx_buffers[sw_idx];
 			if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
 				tx_bug = 1;
+
+			pci_unmap_page(tp->pdev,
+				       pci_unmap_addr(ri, mapping),
+				       skb_shinfo(skb)->frags[i].size,
+				       PCI_DMA_TODEVICE);
 			sw_idx = NEXT_TX(sw_idx);
 		}
 
@@ -4366,6 +4409,17 @@ static void tg3_tx(struct tg3_napi *tnap
 	}
 }
 
+static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
+{
+	if (!ri->skb)
+		return;
+
+	pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping),
+			 map_sz, PCI_DMA_FROMDEVICE);
+	dev_kfree_skb_any(ri->skb);
+	ri->skb = NULL;
+}
+
 /* Returns size of skb allocated or < 0 on error.
  *
  * We only need to fill in the address because the other members
@@ -4377,16 +4431,14 @@ static void tg3_tx(struct tg3_napi *tnap
  * buffers the cpu only reads the last cacheline of the RX descriptor
  * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
  */
-static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
-			    int src_idx, u32 dest_idx_unmasked)
+static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
+			    u32 opaque_key, u32 dest_idx_unmasked)
 {
-	struct tg3 *tp = tnapi->tp;
 	struct tg3_rx_buffer_desc *desc;
 	struct ring_info *map, *src_map;
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int skb_size, dest_idx;
-	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
 	src_map = NULL;
 	switch (opaque_key) {
@@ -4394,8 +4446,6 @@ static int tg3_alloc_rx_skb(struct tg3_n
 		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
 		desc = &tpr->rx_std[dest_idx];
 		map = &tpr->rx_std_buffers[dest_idx];
-		if (src_idx >= 0)
-			src_map = &tpr->rx_std_buffers[src_idx];
 		skb_size = tp->rx_pkt_map_sz;
 		break;
 
@@ -4403,8 +4453,6 @@ static int tg3_alloc_rx_skb(struct tg3_n
 		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
 		desc = &tpr->rx_jmb[dest_idx].std;
 		map = &tpr->rx_jmb_buffers[dest_idx];
-		if (src_idx >= 0)
-			src_map = &tpr->rx_jmb_buffers[src_idx];
 		skb_size = TG3_RX_JMB_MAP_SZ;
 		break;
 
@@ -4426,13 +4474,14 @@ static int tg3_alloc_rx_skb(struct tg3_n
 
 	mapping = pci_map_single(tp->pdev, skb->data, skb_size,
 				 PCI_DMA_FROMDEVICE);
+	if (pci_dma_mapping_error(tp->pdev, mapping)) {
+		dev_kfree_skb(skb);
+		return -EIO;
+	}
 
 	map->skb = skb;
 	pci_unmap_addr_set(map, mapping, mapping);
 
-	if (src_map != NULL)
-		src_map->skb = NULL;
-
 	desc->addr_hi = ((u64)mapping >> 32);
 	desc->addr_lo = ((u64)mapping & 0xffffffff);
 
@@ -4443,30 +4492,32 @@ static int tg3_alloc_rx_skb(struct tg3_n
  * members of the RX descriptor are invariant.  See notes above
  * tg3_alloc_rx_skb for full details.
  */
-static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
-			   int src_idx, u32 dest_idx_unmasked)
+static void tg3_recycle_rx(struct tg3_napi *tnapi,
+			   struct tg3_rx_prodring_set *dpr,
+			   u32 opaque_key, int src_idx,
+			   u32 dest_idx_unmasked)
 {
 	struct tg3 *tp = tnapi->tp;
 	struct tg3_rx_buffer_desc *src_desc, *dest_desc;
 	struct ring_info *src_map, *dest_map;
 	int dest_idx;
-	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+	struct tg3_rx_prodring_set *spr = &tp->prodring[0];
 
 	switch (opaque_key) {
 	case RXD_OPAQUE_RING_STD:
 		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
-		dest_desc = &tpr->rx_std[dest_idx];
-		dest_map = &tpr->rx_std_buffers[dest_idx];
-		src_desc = &tpr->rx_std[src_idx];
-		src_map = &tpr->rx_std_buffers[src_idx];
+		dest_desc = &dpr->rx_std[dest_idx];
+		dest_map = &dpr->rx_std_buffers[dest_idx];
+		src_desc = &spr->rx_std[src_idx];
+		src_map = &spr->rx_std_buffers[src_idx];
 		break;
 
 	case RXD_OPAQUE_RING_JUMBO:
 		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
-		dest_desc = &tpr->rx_jmb[dest_idx].std;
-		dest_map = &tpr->rx_jmb_buffers[dest_idx];
-		src_desc = &tpr->rx_jmb[src_idx].std;
-		src_map = &tpr->rx_jmb_buffers[src_idx];
+		dest_desc = &dpr->rx_jmb[dest_idx].std;
+		dest_map = &dpr->rx_jmb_buffers[dest_idx];
+		src_desc = &spr->rx_jmb[src_idx].std;
+		src_map = &spr->rx_jmb_buffers[src_idx];
 		break;
 
 	default:
@@ -4478,7 +4529,6 @@ static void tg3_recycle_rx(struct tg3_na
 			   pci_unmap_addr(src_map, mapping));
 	dest_desc->addr_hi = src_desc->addr_hi;
 	dest_desc->addr_lo = src_desc->addr_lo;
-
 	src_map->skb = NULL;
 }
 
@@ -4510,10 +4560,11 @@ static int tg3_rx(struct tg3_napi *tnapi
 {
 	struct tg3 *tp = tnapi->tp;
 	u32 work_mask, rx_std_posted = 0;
+	u32 std_prod_idx, jmb_prod_idx;
 	u32 sw_idx = tnapi->rx_rcb_ptr;
 	u16 hw_idx;
 	int received;
-	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+	struct tg3_rx_prodring_set *tpr = tnapi->prodring;
 
 	hw_idx = *(tnapi->rx_rcb_prod_idx);
 	/*
@@ -4523,7 +4574,10 @@ static int tg3_rx(struct tg3_napi *tnapi
 	rmb();
 	work_mask = 0;
 	received = 0;
+	std_prod_idx = tpr->rx_std_prod_idx;
+	jmb_prod_idx = tpr->rx_jmb_prod_idx;
 	while (sw_idx != hw_idx && budget > 0) {
+		struct ring_info *ri;
 		struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
 		unsigned int len;
 		struct sk_buff *skb;
@@ -4533,16 +4587,16 @@ static int tg3_rx(struct tg3_napi *tnapi
 		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
 		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
 		if (opaque_key == RXD_OPAQUE_RING_STD) {
-			struct ring_info *ri = &tpr->rx_std_buffers[desc_idx];
+			ri = &tp->prodring[0].rx_std_buffers[desc_idx];
 			dma_addr = pci_unmap_addr(ri, mapping);
 			skb = ri->skb;
-			post_ptr = &tpr->rx_std_ptr;
+			post_ptr = &std_prod_idx;
 			rx_std_posted++;
 		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
-			struct ring_info *ri = &tpr->rx_jmb_buffers[desc_idx];
+			ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
 			dma_addr = pci_unmap_addr(ri, mapping);
 			skb = ri->skb;
-			post_ptr = &tpr->rx_jmb_ptr;
+			post_ptr = &jmb_prod_idx;
 		} else
 			goto next_pkt_nopost;
 
@@ -4551,7 +4605,7 @@ static int tg3_rx(struct tg3_napi *tnapi
 		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
 		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
 		drop_it:
-			tg3_recycle_rx(tnapi, opaque_key,
+			tg3_recycle_rx(tnapi, tpr, opaque_key,
 				       desc_idx, *post_ptr);
 		drop_it_no_recycle:
 			/* Other statistics kept track of by card. */
@@ -4562,20 +4616,21 @@ static int tg3_rx(struct tg3_napi *tnapi
 		len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
 		      ETH_FCS_LEN;
 
-		if (len > RX_COPY_THRESHOLD
-			&& tp->rx_offset == NET_IP_ALIGN
-			/* rx_offset will likely not equal NET_IP_ALIGN
-			 * if this is a 5701 card running in PCI-X mode
-			 * [see tg3_get_invariants()]
-			 */
-		) {
+		if (len > RX_COPY_THRESHOLD &&
+		    tp->rx_offset == NET_IP_ALIGN) {
+		    /* rx_offset will likely not equal NET_IP_ALIGN
+		     * if this is a 5701 card running in PCI-X mode
+		     * [see tg3_get_invariants()]
+		     */
 			int skb_size;
 
-			skb_size = tg3_alloc_rx_skb(tnapi, opaque_key,
-						    desc_idx, *post_ptr);
+			skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key,
+						    *post_ptr);
 			if (skb_size < 0)
 				goto drop_it;
 
+			ri->skb = NULL;
+
 			pci_unmap_single(tp->pdev, dma_addr, skb_size,
 					 PCI_DMA_FROMDEVICE);
 
@@ -4583,7 +4638,7 @@ static int tg3_rx(struct tg3_napi *tnapi
 		} else {
 			struct sk_buff *copy_skb;
 
-			tg3_recycle_rx(tnapi, opaque_key,
+			tg3_recycle_rx(tnapi, tpr, opaque_key,
 				       desc_idx, *post_ptr);
 
 			copy_skb = netdev_alloc_skb(tp->dev,
@@ -4633,10 +4688,9 @@ next_pkt:
 		(*post_ptr)++;
 
 		if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
-			u32 idx = *post_ptr % TG3_RX_RING_SIZE;
-
-			tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX +
-				     TG3_64BIT_REG_LOW, idx);
+			tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     tpr->rx_std_prod_idx);
 			work_mask &= ~RXD_OPAQUE_RING_STD;
 			rx_std_posted = 0;
 		}
@@ -4656,33 +4710,45 @@ next_pkt_nopost:
 	tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
 	/* Refill RX ring(s). */
-	if (work_mask & RXD_OPAQUE_RING_STD) {
-		sw_idx = tpr->rx_std_ptr % TG3_RX_RING_SIZE;
-		tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
-			     sw_idx);
-	}
-	if (work_mask & RXD_OPAQUE_RING_JUMBO) {
-		sw_idx = tpr->rx_jmb_ptr % TG3_RX_JUMBO_RING_SIZE;
-		tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
-			     sw_idx);
+	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) || tnapi == &tp->napi[1]) {
+		if (work_mask & RXD_OPAQUE_RING_STD) {
+			tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     tpr->rx_std_prod_idx);
+		}
+		if (work_mask & RXD_OPAQUE_RING_JUMBO) {
+			tpr->rx_jmb_prod_idx = jmb_prod_idx %
+					       TG3_RX_JUMBO_RING_SIZE;
+			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
+				     tpr->rx_jmb_prod_idx);
+		}
+		mmiowb();
+	} else if (work_mask) {
+		/* rx_std_buffers[] and rx_jmb_buffers[] entries must be
+		 * updated before the producer indices can be updated.
+		 */
+		smp_wmb();
+
+		tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
+		tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
+
+		napi_schedule(&tp->napi[1].napi);
 	}
-	mmiowb();
 
 	return received;
 }
 
-static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
+static void tg3_poll_link(struct tg3 *tp)
 {
-	struct tg3 *tp = tnapi->tp;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
-
 	/* handle link change and other phy events */
 	if (!(tp->tg3_flags &
 	      (TG3_FLAG_USE_LINKCHG_REG |
 	       TG3_FLAG_POLL_SERDES))) {
+		struct tg3_hw_status *sblk = tp->napi[0].hw_status;
+
 		if (sblk->status & SD_STATUS_LINK_CHG) {
 			sblk->status = SD_STATUS_UPDATED |
-				(sblk->status & ~SD_STATUS_LINK_CHG);
+				       (sblk->status & ~SD_STATUS_LINK_CHG);
 			spin_lock(&tp->lock);
 			if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 				tw32_f(MAC_STATUS,
@@ -4696,6 +4762,98 @@ static int tg3_poll_work(struct tg3_napi
 			spin_unlock(&tp->lock);
 		}
 	}
+}
+
+static void tg3_rx_prodring_xfer(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *dpr,
+				 struct tg3_rx_prodring_set *spr)
+{
+	u32 si, di, cpycnt, src_prod_idx;
+	int i;
+
+	while (1) {
+		src_prod_idx = spr->rx_std_prod_idx;
+
+		/* Make sure updates to the rx_std_buffers[] entries and the
+		 * standard producer index are seen in the correct order.
+		 */
+		smp_rmb();
+
+		if (spr->rx_std_cons_idx == src_prod_idx)
+			break;
+
+		if (spr->rx_std_cons_idx < src_prod_idx)
+			cpycnt = src_prod_idx - spr->rx_std_cons_idx;
+		else
+			cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx;
+
+		cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx);
+
+		si = spr->rx_std_cons_idx;
+		di = dpr->rx_std_prod_idx;
+
+		memcpy(&dpr->rx_std_buffers[di],
+		       &spr->rx_std_buffers[si],
+		       cpycnt * sizeof(struct ring_info));
+
+		for (i = 0; i < cpycnt; i++, di++, si++) {
+			struct tg3_rx_buffer_desc *sbd, *dbd;
+			sbd = &spr->rx_std[si];
+			dbd = &dpr->rx_std[di];
+			dbd->addr_hi = sbd->addr_hi;
+			dbd->addr_lo = sbd->addr_lo;
+		}
+
+		spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) %
+				       TG3_RX_RING_SIZE;
+		dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) %
+				       TG3_RX_RING_SIZE;
+	}
+
+	while (1) {
+		src_prod_idx = spr->rx_jmb_prod_idx;
+
+		/* Make sure updates to the rx_jmb_buffers[] entries and
+		 * the jumbo producer index are seen in the correct order.
+		 */
+		smp_rmb();
+
+		if (spr->rx_jmb_cons_idx == src_prod_idx)
+			break;
+
+		if (spr->rx_jmb_cons_idx < src_prod_idx)
+			cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
+		else
+			cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx;
+
+		cpycnt = min(cpycnt,
+			     TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx);
+
+		si = spr->rx_jmb_cons_idx;
+		di = dpr->rx_jmb_prod_idx;
+
+		memcpy(&dpr->rx_jmb_buffers[di],
+		       &spr->rx_jmb_buffers[si],
+		       cpycnt * sizeof(struct ring_info));
+
+		for (i = 0; i < cpycnt; i++, di++, si++) {
+			struct tg3_rx_buffer_desc *sbd, *dbd;
+			sbd = &spr->rx_jmb[si].std;
+			dbd = &dpr->rx_jmb[di].std;
+			dbd->addr_hi = sbd->addr_hi;
+			dbd->addr_lo = sbd->addr_lo;
+		}
+
+		spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) %
+				       TG3_RX_JUMBO_RING_SIZE;
+		dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
+				       TG3_RX_JUMBO_RING_SIZE;
+	}
+}
+
+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
+{
+	struct tg3 *tp = tnapi->tp;
 
 	/* run TX completion thread */
 	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
@@ -4711,6 +4869,74 @@ static int tg3_poll_work(struct tg3_napi
 	if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
 		work_done += tg3_rx(tnapi, budget - work_done);
 
+	if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
+		int i;
+		u32 std_prod_idx = tp->prodring[0].rx_std_prod_idx;
+		u32 jmb_prod_idx = tp->prodring[0].rx_jmb_prod_idx;
+
+		for (i = 2; i < tp->irq_cnt; i++)
+			tg3_rx_prodring_xfer(tp, tnapi->prodring,
+					     tp->napi[i].prodring);
+
+		wmb();
+
+		if (std_prod_idx != tp->prodring[0].rx_std_prod_idx) {
+			u32 mbox = TG3_RX_STD_PROD_IDX_REG;
+			tw32_rx_mbox(mbox, tp->prodring[0].rx_std_prod_idx);
+		}
+
+		if (jmb_prod_idx != tp->prodring[0].rx_jmb_prod_idx) {
+			u32 mbox = TG3_RX_JMB_PROD_IDX_REG;
+			tw32_rx_mbox(mbox, tp->prodring[0].rx_jmb_prod_idx);
+		}
+
+		mmiowb();
+	}
+
+	return work_done;
+}
+
+static int tg3_poll_msix(struct napi_struct *napi, int budget)
+{
+	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
+	struct tg3 *tp = tnapi->tp;
+	int work_done = 0;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
+
+	while (1) {
+		work_done = tg3_poll_work(tnapi, work_done, budget);
+
+		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+			goto tx_recovery;
+
+		if (unlikely(work_done >= budget))
+			break;
+
+		/* tp->last_tag is used in tg3_restart_ints() below
+		 * to tell the hw how much work has been processed,
+		 * so we must read it before checking for more work.
+		 */
+		tnapi->last_tag = sblk->status_tag;
+		tnapi->last_irq_tag = tnapi->last_tag;
+		rmb();
+
+		/* check for RX/TX work to do */
+		if (sblk->idx[0].tx_consumer == tnapi->tx_cons &&
+		    *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr) {
+			napi_complete(napi);
+			/* Reenable interrupts. */
+			tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
+			mmiowb();
+			break;
+		}
+	}
+
+	return work_done;
+
+tx_recovery:
+	/* work_done is guaranteed to be less than budget. */
+	napi_complete(napi);
+	schedule_work(&tp->reset_task);
 	return work_done;
 }
 
@@ -4722,6 +4948,8 @@ static int tg3_poll(struct napi_struct *
 	struct tg3_hw_status *sblk = tnapi->hw_status;
 
 	while (1) {
+		tg3_poll_link(tp);
+
 		work_done = tg3_poll_work(tnapi, work_done, budget);
 
 		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
@@ -5084,11 +5312,11 @@ static inline int tg3_40bit_overflow_tes
 static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
 
 /* Workaround 4GB and 40-bit hardware DMA bugs. */
-static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
-				       u32 last_plus_one, u32 *start,
-				       u32 base_flags, u32 mss)
+static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
+				       struct sk_buff *skb, u32 last_plus_one,
+				       u32 *start, u32 base_flags, u32 mss)
 {
-	struct tg3_napi *tnapi = &tp->napi[0];
+	struct tg3 *tp = tnapi->tp;
 	struct sk_buff *new_skb;
 	dma_addr_t new_addr = 0;
 	u32 entry = *start;
@@ -5109,16 +5337,21 @@ static int tigon3_dma_hwbug_workaround(s
 	} else {
 		/* New SKB is guaranteed to be linear. */
 		entry = *start;
-		ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
-		new_addr = skb_shinfo(new_skb)->dma_head;
+		new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
+					  PCI_DMA_TODEVICE);
+		/* Make sure the mapping succeeded */
+		if (pci_dma_mapping_error(tp->pdev, new_addr)) {
+			ret = -1;
+			dev_kfree_skb(new_skb);
+			new_skb = NULL;
 
 		/* Make sure new skb does not cross any 4G boundaries.
 		 * Drop the packet if it does.
 		 */
-		if (ret || tg3_4g_overflow_test(new_addr, new_skb->len)) {
-			if (!ret)
-				skb_dma_unmap(&tp->pdev->dev, new_skb,
-					      DMA_TO_DEVICE);
+		} else if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+			    tg3_4g_overflow_test(new_addr, new_skb->len)) {
+			pci_unmap_single(tp->pdev, new_addr, new_skb->len,
+					 PCI_DMA_TODEVICE);
 			ret = -1;
 			dev_kfree_skb(new_skb);
 			new_skb = NULL;
@@ -5132,15 +5365,28 @@ static int tigon3_dma_hwbug_workaround(s
 	/* Now clean up the sw ring entries. */
 	i = 0;
 	while (entry != last_plus_one) {
+		int len;
+
 		if (i == 0)
-			tnapi->tx_buffers[entry].skb = new_skb;
+			len = skb_headlen(skb);
 		else
+			len = skb_shinfo(skb)->frags[i-1].size;
+
+		pci_unmap_single(tp->pdev,
+				 pci_unmap_addr(&tnapi->tx_buffers[entry],
+						mapping),
+				 len, PCI_DMA_TODEVICE);
+		if (i == 0) {
+			tnapi->tx_buffers[entry].skb = new_skb;
+			pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+					   new_addr);
+		} else {
 			tnapi->tx_buffers[entry].skb = NULL;
+		}
 		entry = NEXT_TX(entry);
 		i++;
 	}
 
-	skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
 	dev_kfree_skb(skb);
 
 	return ret;
@@ -5170,21 +5416,22 @@ static void tg3_set_txd(struct tg3_napi
 }
 
 /* hard_start_xmit for devices that don't have any bugs and
- * support TG3_FLG2_HW_TSO_2 only.
+ * support TG3_FLG2_HW_TSO_2 and TG3_FLG2_HW_TSO_3 only.
  */
 static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 				  struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
 	u32 len, entry, base_flags, mss;
-	struct skb_shared_info *sp;
 	dma_addr_t mapping;
 	struct tg3_napi *tnapi;
 	struct netdev_queue *txq;
+	unsigned int i, last;
+
 
 	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
 	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
 		tnapi++;
 
 	/* We are running in BH disabled context with netif_tx_lock
@@ -5229,7 +5476,7 @@ static netdev_tx_t tg3_start_xmit(struct
 			hdrlen = ip_tcp_len + tcp_opt_len;
 		}
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
 			mss |= (hdrlen & 0xc) << 12;
 			if (hdrlen & 0x10)
 				base_flags |= 0x00000010;
@@ -5251,20 +5498,19 @@ static netdev_tx_t tg3_start_xmit(struct
 			       (vlan_tx_tag_get(skb) << 16));
 #endif
 
-	if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+	len = skb_headlen(skb);
+
+	/* Queue skb data, a.k.a. the main skb fragment. */
+	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(tp->pdev, mapping)) {
 		dev_kfree_skb(skb);
 		goto out_unlock;
 	}
 
-	sp = skb_shinfo(skb);
-
-	mapping = sp->dma_head;
-
 	tnapi->tx_buffers[entry].skb = skb;
+	pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
 
-	len = skb_headlen(skb);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
 	    !mss && skb->len > ETH_DATA_LEN)
 		base_flags |= TXD_FLAG_JMB_PKT;
 
@@ -5275,15 +5521,21 @@ static netdev_tx_t tg3_start_xmit(struct
 
 	/* Now loop through additional data fragments, and queue them. */
 	if (skb_shinfo(skb)->nr_frags > 0) {
-		unsigned int i, last;
-
 		last = skb_shinfo(skb)->nr_frags - 1;
 		for (i = 0; i <= last; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			len = frag->size;
-			mapping = sp->dma_maps[i];
+			mapping = pci_map_page(tp->pdev,
+					       frag->page,
+					       frag->page_offset,
+					       len, PCI_DMA_TODEVICE);
+			if (pci_dma_mapping_error(tp->pdev, mapping))
+				goto dma_error;
+
 			tnapi->tx_buffers[entry].skb = NULL;
+			pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+					   mapping);
 
 			tg3_set_txd(tnapi, entry, mapping, len,
 				    base_flags, (i == last) | (mss << 1));
@@ -5306,6 +5558,27 @@ out_unlock:
 	mmiowb();
 
 	return NETDEV_TX_OK;
+
+dma_error:
+	last = i;
+	entry = tnapi->tx_prod;
+	tnapi->tx_buffers[entry].skb = NULL;
+	pci_unmap_single(tp->pdev,
+			 pci_unmap_addr(&tnapi->tx_buffers[entry], mapping),
+			 skb_headlen(skb),
+			 PCI_DMA_TODEVICE);
+	for (i = 0; i <= last; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		entry = NEXT_TX(entry);
+
+		pci_unmap_page(tp->pdev,
+			       pci_unmap_addr(&tnapi->tx_buffers[entry],
+					      mapping),
+			       frag->size, PCI_DMA_TODEVICE);
+	}
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *,
@@ -5353,12 +5626,17 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 {
 	struct tg3 *tp = netdev_priv(dev);
 	u32 len, entry, base_flags, mss;
-	struct skb_shared_info *sp;
 	int would_hit_hwbug;
 	dma_addr_t mapping;
-	struct tg3_napi *tnapi = &tp->napi[0];
+	struct tg3_napi *tnapi;
+	struct netdev_queue *txq;
+	unsigned int i, last;
 
-	len = skb_headlen(skb);
+
+	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+		tnapi++;
 
 	/* We are running in BH disabled context with netif_tx_lock
 	 * and TX reclaim runs via tp->napi.poll inside of a software
@@ -5366,8 +5644,8 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 	 * no IRQ context deadlocks to worry about either.  Rejoice!
 	 */
 	if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
-		if (!netif_queue_stopped(dev)) {
-			netif_stop_queue(dev);
+		if (!netif_tx_queue_stopped(txq)) {
+			netif_tx_stop_queue(txq);
 
 			/* This is a hard error, log it. */
 			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
@@ -5380,10 +5658,10 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 	base_flags = 0;
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
 		base_flags |= TXD_FLAG_TCPUDP_CSUM;
-	mss = 0;
+
 	if ((mss = skb_shinfo(skb)->gso_size) != 0) {
 		struct iphdr *iph;
-		int tcp_opt_len, ip_tcp_len, hdr_len;
+		u32 tcp_opt_len, ip_tcp_len, hdr_len;
 
 		if (skb_header_cloned(skb) &&
 		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5414,8 +5692,15 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 								 IPPROTO_TCP,
 								 0);
 
-		if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
-		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
+		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+			mss |= (hdr_len & 0xc) << 12;
+			if (hdr_len & 0x10)
+				base_flags |= 0x00000010;
+			base_flags |= (hdr_len & 0x3e0) << 5;
+		} else if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+			mss |= hdr_len << 9;
+		else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
 			if (tcp_opt_len || iph->ihl > 5) {
 				int tsflags;
 
@@ -5437,22 +5722,35 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 			       (vlan_tx_tag_get(skb) << 16));
 #endif
 
-	if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+	if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
+	    !mss && skb->len > ETH_DATA_LEN)
+		base_flags |= TXD_FLAG_JMB_PKT;
+
+	len = skb_headlen(skb);
+
+	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(tp->pdev, mapping)) {
 		dev_kfree_skb(skb);
 		goto out_unlock;
 	}
 
-	sp = skb_shinfo(skb);
-
-	mapping = sp->dma_head;
-
 	tnapi->tx_buffers[entry].skb = skb;
+	pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
 
 	would_hit_hwbug = 0;
 
-	if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+	if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
 		would_hit_hwbug = 1;
-	else if (tg3_4g_overflow_test(mapping, len))
+
+	if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+	    tg3_4g_overflow_test(mapping, len))
+		would_hit_hwbug = 1;
+
+	if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+	    tg3_40bit_overflow_test(tp, mapping, len))
+		would_hit_hwbug = 1;
+
+	if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
 		would_hit_hwbug = 1;
 
 	tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -5462,21 +5760,32 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 
 	/* Now loop through additional data fragments, and queue them. */
 	if (skb_shinfo(skb)->nr_frags > 0) {
-		unsigned int i, last;
-
 		last = skb_shinfo(skb)->nr_frags - 1;
 		for (i = 0; i <= last; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			len = frag->size;
-			mapping = sp->dma_maps[i];
+			mapping = pci_map_page(tp->pdev,
+					       frag->page,
+					       frag->page_offset,
+					       len, PCI_DMA_TODEVICE);
 
 			tnapi->tx_buffers[entry].skb = NULL;
+			pci_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+					   mapping);
+			if (pci_dma_mapping_error(tp->pdev, mapping))
+				goto dma_error;
 
-			if (tg3_4g_overflow_test(mapping, len))
+			if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
+			    len <= 8)
 				would_hit_hwbug = 1;
 
-			if (tg3_40bit_overflow_test(tp, mapping, len))
+			if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+			    tg3_4g_overflow_test(mapping, len))
+				would_hit_hwbug = 1;
+
+			if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+			    tg3_40bit_overflow_test(tp, mapping, len))
 				would_hit_hwbug = 1;
 
 			if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
@@ -5500,7 +5809,7 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 		/* If the workaround fails due to memory/mapping
 		 * failure, silently drop this packet.
 		 */
-		if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one,
+		if (tigon3_dma_hwbug_workaround(tnapi, skb, last_plus_one,
 						&start, base_flags, mss))
 			goto out_unlock;
 
@@ -5508,19 +5817,40 @@ static netdev_tx_t tg3_start_xmit_dma_bu
 	}
 
 	/* Packets are ready, update Tx producer idx local and on card. */
-	tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry);
+	tw32_tx_mbox(tnapi->prodmbox, entry);
 
 	tnapi->tx_prod = entry;
 	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
-		netif_stop_queue(dev);
+		netif_tx_stop_queue(txq);
 		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
-			netif_wake_queue(tp->dev);
+			netif_tx_wake_queue(txq);
 	}
 
 out_unlock:
 	mmiowb();
 
 	return NETDEV_TX_OK;
+
+dma_error:
+	last = i;
+	entry = tnapi->tx_prod;
+	tnapi->tx_buffers[entry].skb = NULL;
+	pci_unmap_single(tp->pdev,
+			 pci_unmap_addr(&tnapi->tx_buffers[entry], mapping),
+			 skb_headlen(skb),
+			 PCI_DMA_TODEVICE);
+	for (i = 0; i <= last; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		entry = NEXT_TX(entry);
+
+		pci_unmap_page(tp->pdev,
+			       pci_unmap_addr(&tnapi->tx_buffers[entry],
+					      mapping),
+			       frag->size, PCI_DMA_TODEVICE);
+	}
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
@@ -5585,36 +5915,33 @@ static void tg3_rx_prodring_free(struct
 				 struct tg3_rx_prodring_set *tpr)
 {
 	int i;
-	struct ring_info *rxp;
 
-	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
-		rxp = &tpr->rx_std_buffers[i];
+	if (tpr != &tp->prodring[0]) {
+		for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
+		     i = (i + 1) % TG3_RX_RING_SIZE)
+			tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
+					tp->rx_pkt_map_sz);
 
-		if (rxp->skb == NULL)
-			continue;
+		if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+			for (i = tpr->rx_jmb_cons_idx;
+			     i != tpr->rx_jmb_prod_idx;
+			     i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) {
+				tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
+						TG3_RX_JMB_MAP_SZ);
+			}
+		}
 
-		pci_unmap_single(tp->pdev,
-				 pci_unmap_addr(rxp, mapping),
-				 tp->rx_pkt_map_sz,
-				 PCI_DMA_FROMDEVICE);
-		dev_kfree_skb_any(rxp->skb);
-		rxp->skb = NULL;
+		return;
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
-			rxp = &tpr->rx_jmb_buffers[i];
-
-			if (rxp->skb == NULL)
-				continue;
+	for (i = 0; i < TG3_RX_RING_SIZE; i++)
+		tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
+				tp->rx_pkt_map_sz);
 
-			pci_unmap_single(tp->pdev,
-					 pci_unmap_addr(rxp, mapping),
-					 TG3_RX_JMB_MAP_SZ,
-					 PCI_DMA_FROMDEVICE);
-			dev_kfree_skb_any(rxp->skb);
-			rxp->skb = NULL;
-		}
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
+			tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
+					TG3_RX_JMB_MAP_SZ);
 	}
 }
 
@@ -5629,7 +5956,19 @@ static int tg3_rx_prodring_alloc(struct
 				 struct tg3_rx_prodring_set *tpr)
 {
 	u32 i, rx_pkt_dma_sz;
-	struct tg3_napi *tnapi = &tp->napi[0];
+
+	tpr->rx_std_cons_idx = 0;
+	tpr->rx_std_prod_idx = 0;
+	tpr->rx_jmb_cons_idx = 0;
+	tpr->rx_jmb_prod_idx = 0;
+
+	if (tpr != &tp->prodring[0]) {
+		memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
+		if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
+			memset(&tpr->rx_jmb_buffers[0], 0,
+			       TG3_RX_JMB_BUFF_RING_SIZE);
+		goto done;
+	}
 
 	/* Zero out all descriptors. */
 	memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
@@ -5656,7 +5995,7 @@ static int tg3_rx_prodring_alloc(struct
 
 	/* Now allocate fresh SKBs for each rx ring. */
 	for (i = 0; i < tp->rx_pending; i++) {
-		if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_STD, -1, i) < 0) {
+		if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
 			printk(KERN_WARNING PFX
 			       "%s: Using a smaller RX standard ring, "
 			       "only %d out of %d buffers were allocated "
@@ -5687,8 +6026,8 @@ static int tg3_rx_prodring_alloc(struct
 		}
 
 		for (i = 0; i < tp->rx_jumbo_pending; i++) {
-			if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_JUMBO,
-					     -1, i) < 0) {
+			if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO,
+					     i) < 0) {
 				printk(KERN_WARNING PFX
 				       "%s: Using a smaller RX jumbo ring, "
 				       "only %d out of %d buffers were "
@@ -5732,8 +6071,7 @@ static void tg3_rx_prodring_fini(struct
 static int tg3_rx_prodring_init(struct tg3 *tp,
 				struct tg3_rx_prodring_set *tpr)
 {
-	tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
-				      TG3_RX_RING_SIZE, GFP_KERNEL);
+	tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
 	if (!tpr->rx_std_buffers)
 		return -ENOMEM;
 
@@ -5743,8 +6081,7 @@ static int tg3_rx_prodring_init(struct t
 		goto err_out;
 
 	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
-		tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
-					      TG3_RX_JUMBO_RING_SIZE,
+		tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
 					      GFP_KERNEL);
 		if (!tpr->rx_jmb_buffers)
 			goto err_out;
@@ -5781,8 +6118,9 @@ static void tg3_free_rings(struct tg3 *t
 			continue;
 
 		for (i = 0; i < TG3_TX_RING_SIZE; ) {
-			struct tx_ring_info *txp;
+			struct ring_info *txp;
 			struct sk_buff *skb;
+			unsigned int k;
 
 			txp = &tnapi->tx_buffers[i];
 			skb = txp->skb;
@@ -5792,17 +6130,29 @@ static void tg3_free_rings(struct tg3 *t
 				continue;
 			}
 
-			skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
-
+			pci_unmap_single(tp->pdev,
+					 pci_unmap_addr(txp, mapping),
+					 skb_headlen(skb),
+					 PCI_DMA_TODEVICE);
 			txp->skb = NULL;
 
-			i += skb_shinfo(skb)->nr_frags + 1;
+			i++;
+
+			for (k = 0; k < skb_shinfo(skb)->nr_frags; k++) {
+				txp = &tnapi->tx_buffers[i & (TG3_TX_RING_SIZE - 1)];
+				pci_unmap_page(tp->pdev,
+					       pci_unmap_addr(txp, mapping),
+					       skb_shinfo(skb)->frags[k].size,
+					       PCI_DMA_TODEVICE);
+				i++;
+			}
 
 			dev_kfree_skb_any(skb);
 		}
-	}
 
-	tg3_rx_prodring_free(tp, &tp->prodring[0]);
+		if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1)
+			tg3_rx_prodring_free(tp, &tp->prodring[j]);
+	}
 }
 
 /* Initialize tx/rx rings for packet processing.
@@ -5836,9 +6186,13 @@ static int tg3_init_rings(struct tg3 *tp
 		tnapi->rx_rcb_ptr = 0;
 		if (tnapi->rx_rcb)
 			memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
+		if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) &&
+			tg3_rx_prodring_alloc(tp, &tp->prodring[i]))
+			return -ENOMEM;
 	}
 
-	return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
+	return 0;
 }
 
 /*
@@ -5882,7 +6236,8 @@ static void tg3_free_consistent(struct t
 		tp->hw_stats = NULL;
 	}
 
-	tg3_rx_prodring_fini(tp, &tp->prodring[0]);
+	for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++)
+		tg3_rx_prodring_fini(tp, &tp->prodring[i]);
 }
 
 /*
@@ -5893,8 +6248,10 @@ static int tg3_alloc_consistent(struct t
 {
 	int i;
 
-	if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
-		return -ENOMEM;
+	for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) {
+		if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
+			goto err_out;
+	}
 
 	tp->hw_stats = pci_alloc_consistent(tp->pdev,
 					    sizeof(struct tg3_hw_stats),
@@ -5917,6 +6274,24 @@ static int tg3_alloc_consistent(struct t
 		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
 		sblk = tnapi->hw_status;
 
+		/* If multivector TSS is enabled, vector 0 does not handle
+		 * tx interrupts.  Don't allocate any resources for it.
+		 */
+		if ((!i && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) ||
+		    (i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))) {
+			tnapi->tx_buffers = kzalloc(sizeof(struct ring_info) *
+						    TG3_TX_RING_SIZE,
+						    GFP_KERNEL);
+			if (!tnapi->tx_buffers)
+				goto err_out;
+
+			tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
+							      TG3_TX_RING_BYTES,
+						       &tnapi->tx_desc_mapping);
+			if (!tnapi->tx_ring)
+				goto err_out;
+		}
+
 		/*
 		 * When RSS is enabled, the status block format changes
 		 * slightly.  The "rx_jumbo_consumer", "reserved",
@@ -5938,6 +6313,11 @@ static int tg3_alloc_consistent(struct t
 			break;
 		}
 
+		if (tp->irq_cnt == 1)
+			tnapi->prodring = &tp->prodring[0];
+		else if (i)
+			tnapi->prodring = &tp->prodring[i - 1];
+
 		/*
 		 * If multivector RSS is enabled, vector 0 does not handle
 		 * rx or tx interrupts.  Don't allocate any resources for it.
@@ -5952,17 +6332,6 @@ static int tg3_alloc_consistent(struct t
 			goto err_out;
 
 		memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
-
-		tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
-					    TG3_TX_RING_SIZE, GFP_KERNEL);
-		if (!tnapi->tx_buffers)
-			goto err_out;
-
-		tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
-						      TG3_TX_RING_BYTES,
-						      &tnapi->tx_desc_mapping);
-		if (!tnapi->tx_ring)
-			goto err_out;
 	}
 
 	return 0;
@@ -6571,10 +6940,35 @@ static int tg3_chip_reset(struct tg3 *tp
 
 	tg3_mdio_start(tp);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+		u8 phy_addr;
+
+		phy_addr = tp->phy_addr;
+		tp->phy_addr = TG3_PHY_PCIE_ADDR;
+
+		tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+			     TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT);
+		val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL |
+		      TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL |
+		      TG3_PCIEPHY_TX0CTRL1_NB_EN;
+		tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val);
+		udelay(10);
+
+		tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+			     TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT);
+		val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN |
+		      TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN;
+		tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val);
+		udelay(10);
+
+		tp->phy_addr = phy_addr;
+	}
+
 	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
 	    tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
 		val = tr32(0x7c00);
 
 		tw32(0x7c00, val | (1 << 25));
@@ -6926,19 +7320,21 @@ static void __tg3_set_coalesce(struct tg
 {
 	int i;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) {
 		tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
 		tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
 		tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
-
-		tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
-		tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
-		tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
 	} else {
 		tw32(HOSTCC_TXCOL_TICKS, 0);
 		tw32(HOSTCC_TXMAX_FRAMES, 0);
 		tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
+	}
 
+	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+		tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
+		tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
+		tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
+	} else {
 		tw32(HOSTCC_RXCOL_TICKS, 0);
 		tw32(HOSTCC_RXMAX_FRAMES, 0);
 		tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
@@ -6961,25 +7357,31 @@ static void __tg3_set_coalesce(struct tg
 
 		reg = HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18;
 		tw32(reg, ec->rx_coalesce_usecs);
-		reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
-		tw32(reg, ec->tx_coalesce_usecs);
 		reg = HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18;
 		tw32(reg, ec->rx_max_coalesced_frames);
-		reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
-		tw32(reg, ec->tx_max_coalesced_frames);
 		reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
 		tw32(reg, ec->rx_max_coalesced_frames_irq);
-		reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
-		tw32(reg, ec->tx_max_coalesced_frames_irq);
+
+		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+			reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
+			tw32(reg, ec->tx_coalesce_usecs);
+			reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
+			tw32(reg, ec->tx_max_coalesced_frames);
+			reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
+			tw32(reg, ec->tx_max_coalesced_frames_irq);
+		}
 	}
 
 	for (; i < tp->irq_max - 1; i++) {
 		tw32(HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18, 0);
-		tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
 		tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
-		tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
 		tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
-		tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+
+		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+			tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
+			tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
+			tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+		}
 	}
 }
 
@@ -6993,6 +7395,8 @@ static void tg3_rings_reset(struct tg3 *
 	/* Disable all transmit rings but the first. */
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
 	else
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
 
@@ -7007,7 +7411,8 @@ static void tg3_rings_reset(struct tg3 *
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
 	else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
 	else
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE;
@@ -7080,17 +7485,19 @@ static void tg3_rings_reset(struct tg3 *
 		/* Clear status block in ram. */
 		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
 
-		tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
-			       (TG3_TX_RING_SIZE <<
-				BDINFO_FLAGS_MAXLEN_SHIFT),
-			       NIC_SRAM_TX_BUFFER_DESC);
+		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,
 			       (TG3_RX_RCB_RING_SIZE(tp) <<
 				BDINFO_FLAGS_MAXLEN_SHIFT), 0);
 
 		stblk += 8;
-		txrcb += TG3_BDINFO_SIZE;
 		rxrcb += TG3_BDINFO_SIZE;
 	}
 }
@@ -7153,15 +7560,9 @@ static int tg3_reset_hw(struct tg3 *tp,
 		tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
 
 		tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
-	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-		val = tr32(TG3_PCIE_LNKCTL);
-		if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
-			val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-		else
-			val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-		tw32(TG3_PCIE_LNKCTL, val);
+		val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+		tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
 	}
 
 	/* This works around an issue with Athlon chipsets on
@@ -7208,9 +7609,13 @@ static int tg3_reset_hw(struct tg3 *tp,
 	if (err)
 		return err;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+		val = tr32(TG3PCI_DMA_RW_CTRL) &
+		      ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
+		tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
+	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
+		   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
 		/* This value is determined during the probe time DMA
 		 * engine test, tg3_test_dma.
 		 */
@@ -7333,8 +7738,9 @@ static int tg3_reset_hw(struct tg3 *tp,
 	     ((u64) tpr->rx_std_mapping >> 32));
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
 	     ((u64) tpr->rx_std_mapping & 0xffffffff));
-	tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
-	     NIC_SRAM_RX_BUFFER_DESC);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+		tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
+		     NIC_SRAM_RX_BUFFER_DESC);
 
 	/* Disable the mini ring */
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
@@ -7357,14 +7763,16 @@ static int tg3_reset_hw(struct tg3 *tp,
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
 			     (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
 			     BDINFO_FLAGS_USE_EXT_RECV);
-			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
-			     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
+			if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+				tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
+				     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
 		} else {
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
 			     BDINFO_FLAGS_DISABLED);
 		}
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 			val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
 			      (RX_STD_MAX_SIZE << 2);
 		else
@@ -7374,16 +7782,15 @@ static int tg3_reset_hw(struct tg3 *tp,
 
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
 
-	tpr->rx_std_ptr = tp->rx_pending;
-	tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
-		     tpr->rx_std_ptr);
+	tpr->rx_std_prod_idx = tp->rx_pending;
+	tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
 
-	tpr->rx_jmb_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
+	tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
 			  tp->rx_jumbo_pending : 0;
-	tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
-		     tpr->rx_jmb_ptr);
+	tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
 		tw32(STD_REPLENISH_LWM, 32);
 		tw32(JMB_REPLENISH_LWM, 16);
 	}
@@ -7444,7 +7851,8 @@ static int tg3_reset_hw(struct tg3 *tp,
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
@@ -7593,6 +8001,9 @@ static int tg3_reset_hw(struct tg3 *tp,
 	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
 		val |= WDMAC_MODE_STATUS_TAG_FIX;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+		val |= WDMAC_MODE_BURST_ALL_DATA;
+
 	tw32_f(WDMAC_MODE, val);
 	udelay(40);
 
@@ -7632,7 +8043,7 @@ static int tg3_reset_hw(struct tg3 *tp,
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
 	val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
 		val |= SNDBDI_MODE_MULTI_TXQ_EN;
 	tw32(SNDBDI_MODE, val);
 	tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
@@ -8056,7 +8467,8 @@ static int tg3_test_interrupt(struct tg3
 	 * Turn off MSI one shot mode.  Otherwise this test has no
 	 * observable way to know whether the interrupt was delivered.
 	 */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
 	    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
 		val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
 		tw32(MSGINT_MODE, val);
@@ -8099,7 +8511,8 @@ static int tg3_test_interrupt(struct tg3
 
 	if (intr_ok) {
 		/* Reenable MSI one shot mode. */
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+		if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+		     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
 		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
 			val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
 			tw32(MSGINT_MODE, val);
@@ -8240,7 +8653,11 @@ static bool tg3_enable_msix(struct tg3 *
 	for (i = 0; i < tp->irq_max; i++)
 		tp->napi[i].irq_vec = msix_ent[i].vector;
 
-	tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+		tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+	} else
+		tp->dev->real_num_tx_queues = 1;
 
 	return true;
 }
@@ -8391,6 +8808,7 @@ static int tg3_open(struct net_device *d
 		}
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 &&
 		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI) &&
 		    (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) {
 			u32 val = tr32(PCIE_TRANSACTION_CFG);
@@ -9231,9 +9649,11 @@ static int tg3_get_settings(struct net_d
 	struct tg3 *tp = netdev_priv(dev);
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+		struct phy_device *phydev;
 		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 			return -EAGAIN;
-		return phy_ethtool_gset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+		return phy_ethtool_gset(phydev, cmd);
 	}
 
 	cmd->supported = (SUPPORTED_Autoneg);
@@ -9272,9 +9692,11 @@ static int tg3_set_settings(struct net_d
 	struct tg3 *tp = netdev_priv(dev);
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+		struct phy_device *phydev;
 		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 			return -EAGAIN;
-		return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+		return phy_ethtool_sset(phydev, cmd);
 	}
 
 	if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -9427,15 +9849,16 @@ static int tg3_set_tso(struct net_device
 		return 0;
 	}
 	if ((dev->features & NETIF_F_IPV6_CSUM) &&
-	    (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)) {
+	    ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
+	     (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) {
 		if (value) {
 			dev->features |= NETIF_F_TSO6;
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+			if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 			    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 			     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 				dev->features |= NETIF_F_TSO_ECN;
 		} else
 			dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
@@ -9457,7 +9880,7 @@ static int tg3_nway_reset(struct net_dev
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 			return -EAGAIN;
-		r = phy_start_aneg(tp->mdio_bus->phy_map[PHY_ADDR]);
+		r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 	} else {
 		u32 bmcr;
 
@@ -9576,7 +9999,7 @@ static int tg3_set_pauseparam(struct net
 			u32 newadv;
 			struct phy_device *phydev;
 
-			phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+			phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
 			if (epause->rx_pause) {
 				if (epause->tx_pause)
@@ -10330,6 +10753,10 @@ static int tg3_run_loopback(struct tg3 *
 		tx_data[i] = (u8) (i & 0xff);
 
 	map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(tp->pdev, map)) {
+		dev_kfree_skb(skb);
+		return -EIO;
+	}
 
 	tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
 	       rnapi->coal_now);
@@ -10350,8 +10777,8 @@ static int tg3_run_loopback(struct tg3 *
 
 	udelay(10);
 
-	/* 250 usec to allow enough time on some 10/100 Mbps devices.  */
-	for (i = 0; i < 25; i++) {
+	/* 350 usec to allow enough time on some 10/100 Mbps devices.  */
+	for (i = 0; i < 35; i++) {
 		tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
 		       coal_now);
 
@@ -10556,9 +10983,11 @@ static int tg3_ioctl(struct net_device *
 	int err;
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+		struct phy_device *phydev;
 		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 			return -EAGAIN;
-		return phy_mii_ioctl(tp->mdio_bus->phy_map[PHY_ADDR], data, cmd);
+		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+		return phy_mii_ioctl(phydev, data, cmd);
 	}
 
 	switch(cmd) {
@@ -10878,7 +11307,7 @@ static void __devinit tg3_get_5752_nvram
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27))
-		tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
 
 	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 	case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
@@ -10919,7 +11348,7 @@ static void __devinit tg3_get_5755_nvram
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27)) {
-		tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
 		protect = 1;
 	}
 
@@ -11013,7 +11442,7 @@ static void __devinit tg3_get_5761_nvram
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27)) {
-		tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
 		protect = 1;
 	}
 
@@ -11274,7 +11703,8 @@ static void __devinit tg3_nvram_init(str
 			tg3_get_5761_nvram_info(tp);
 		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 			tg3_get_5906_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 			tg3_get_57780_nvram_info(tp);
 		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 			tg3_get_5717_nvram_info(tp);
@@ -11515,7 +11945,7 @@ static int tg3_nvram_write_block(struct
 
 		tg3_enable_nvram_access(tp);
 		if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-		    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM))
+		    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM))
 			tw32(NVRAM_WRITE1, 0x406);
 
 		grc_mode = tr32(GRC_MODE);
@@ -11688,7 +12118,8 @@ static void __devinit tg3_get_eeprom_hw_
 
 		tp->phy_id = eeprom_phy_id;
 		if (eeprom_phy_serdes) {
-			if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+			if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 				tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
 			else
 				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
@@ -11999,7 +12430,7 @@ skip_phy_reset:
 
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
-	unsigned char vpd_data[256];   /* in little-endian format */
+	unsigned char vpd_data[TG3_NVM_VPD_LEN];   /* in little-endian format */
 	unsigned int i;
 	u32 magic;
 
@@ -12008,48 +12439,37 @@ static void __devinit tg3_read_partno(st
 		goto out_not_found;
 
 	if (magic == TG3_EEPROM_MAGIC) {
-		for (i = 0; i < 256; i += 4) {
+		for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
 			u32 tmp;
 
 			/* The data is in little-endian format in NVRAM.
 			 * Use the big-endian read routines to preserve
 			 * the byte order as it exists in NVRAM.
 			 */
-			if (tg3_nvram_read_be32(tp, 0x100 + i, &tmp))
+			if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &tmp))
 				goto out_not_found;
 
 			memcpy(&vpd_data[i], &tmp, sizeof(tmp));
 		}
 	} else {
-		int vpd_cap;
-
-		vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD);
-		for (i = 0; i < 256; i += 4) {
-			u32 tmp, j = 0;
-			__le32 v;
-			u16 tmp16;
+		ssize_t cnt;
+		unsigned int pos = 0, i = 0;
 
-			pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR,
-					      i);
-			while (j++ < 100) {
-				pci_read_config_word(tp->pdev, vpd_cap +
-						     PCI_VPD_ADDR, &tmp16);
-				if (tmp16 & 0x8000)
-					break;
-				msleep(1);
-			}
-			if (!(tmp16 & 0x8000))
+		for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
+			cnt = pci_read_vpd(tp->pdev, pos,
+					   TG3_NVM_VPD_LEN - pos,
+					   &vpd_data[pos]);
+			if (cnt == -ETIMEDOUT || -EINTR)
+				cnt = 0;
+			else if (cnt < 0)
 				goto out_not_found;
-
-			pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
-					      &tmp);
-			v = cpu_to_le32(tmp);
-			memcpy(&vpd_data[i], &v, sizeof(v));
 		}
+		if (pos != TG3_NVM_VPD_LEN)
+			goto out_not_found;
 	}
 
 	/* Now parse and find the part number. */
-	for (i = 0; i < 254; ) {
+	for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
 		unsigned char val = vpd_data[i];
 		unsigned int block_end;
 
@@ -12068,7 +12488,7 @@ static void __devinit tg3_read_partno(st
 			      (vpd_data[i + 2] << 8)));
 		i += 3;
 
-		if (block_end > 256)
+		if (block_end > TG3_NVM_VPD_LEN)
 			goto out_not_found;
 
 		while (i < (block_end - 2)) {
@@ -12077,7 +12497,8 @@ static void __devinit tg3_read_partno(st
 				int partno_len = vpd_data[i + 2];
 
 				i += 3;
-				if (partno_len > 24 || (partno_len + i) > 256)
+				if (partno_len > TG3_BPN_SIZE ||
+				    (partno_len + i) > TG3_NVM_VPD_LEN)
 					goto out_not_found;
 
 				memcpy(tp->board_part_number,
@@ -12108,6 +12529,8 @@ out_not_found:
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
 		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
 		strcpy(tp->board_part_number, "BCM57788");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		strcpy(tp->board_part_number, "BCM57765");
 	else
 		strcpy(tp->board_part_number, "none");
 }
@@ -12391,13 +12814,21 @@ static int __devinit tg3_get_invariants(
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
 		u32 prod_id_asic_rev;
 
-		if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717C ||
-		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717S ||
-		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718C ||
-		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718S)
+		if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724)
 			pci_read_config_dword(tp->pdev,
 					      TG3PCI_GEN2_PRODID_ASICREV,
 					      &prod_id_asic_rev);
+		else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
+			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
+			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761 ||
+			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765 ||
+			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
+			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
+			pci_read_config_dword(tp->pdev,
+					      TG3PCI_GEN15_PRODID_ASICREV,
+					      &prod_id_asic_rev);
 		else
 			pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
 					      &prod_id_asic_rev);
@@ -12551,7 +12982,8 @@ static int __devinit tg3_get_invariants(
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
@@ -12577,6 +13009,30 @@ static int __devinit tg3_get_invariants(
 			tp->dev->features |= NETIF_F_IPV6_CSUM;
 	}
 
+	/* Determine TSO capabilities */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
+	else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
+	else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
+		    tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
+			tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
+	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+		   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
+		   tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
+		tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+			tp->fw_needed = FIRMWARE_TG3TSO5;
+		else
+			tp->fw_needed = FIRMWARE_TG3TSO;
+	}
+
+	tp->irq_max = 1;
+
 	if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
 		tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
 		if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
@@ -12588,29 +13044,31 @@ static int __devinit tg3_get_invariants(
 
 		if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-			tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
 			tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
-		} else {
-			tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
-				ASIC_REV_5750 &&
-	     		    tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
-				tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
 		}
-	}
 
-	tp->irq_max = 1;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+			tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+			tp->irq_max = TG3_IRQ_MAX_VECS;
+		}
+	}
 
-#ifdef TG3_NAPI
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
-		tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
-		tp->irq_max = TG3_IRQ_MAX_VECS;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+		tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
+	else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
+		tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
+		tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
 	}
-#endif
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
 
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
 	     (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		 (tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG))
 		tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
 
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
@@ -12803,7 +13261,8 @@ static int __devinit tg3_get_invariants(
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
 	/* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
@@ -12882,7 +13341,8 @@ static int __devinit tg3_get_invariants(
 	    !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -12917,15 +13377,15 @@ static int __devinit tg3_get_invariants(
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
-	if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
-	     tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
-		tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
-
 	err = tg3_mdio_init(tp);
 	if (err)
 		return err;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	    (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 ||
+		 (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
+		return -ENOTSUPP;
+
 	/* Initialize data/descriptor byte/word swapping. */
 	val = tr32(GRC_MODE);
 	val &= GRC_MODE_HOST_STACKUP;
@@ -13211,6 +13671,12 @@ static u32 __devinit tg3_calc_dma_bndry(
 #endif
 #endif
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
+		val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
+		goto out;
+	}
+
 	if (!goal)
 		goto out;
 
@@ -13405,7 +13871,7 @@ static int __devinit tg3_test_dma(struct
 {
 	dma_addr_t buf_dma;
 	u32 *buf, saved_dma_rwctrl;
-	int ret;
+	int ret = 0;
 
 	buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
 	if (!buf) {
@@ -13418,6 +13884,10 @@ static int __devinit tg3_test_dma(struct
 
 	tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
+		goto out;
+
 	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
 		/* DMA read watermark not used on PCIE */
 		tp->dma_rwctrl |= 0x00180000;
@@ -13490,7 +13960,6 @@ static int __devinit tg3_test_dma(struct
 	tg3_switch_clocks(tp);
 #endif
 
-	ret = 0;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
 		goto out;
@@ -13609,7 +14078,8 @@ static void __devinit tg3_init_link_conf
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
 	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) {
 		tp->bufmgr_config.mbuf_read_dma_low_water =
 			DEFAULT_MB_RDMA_LOW_WATER_5705;
 		tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -13669,6 +14139,7 @@ static char * __devinit tg3_phy_string(s
 	case PHY_ID_BCM5756:	return "5722/5756";
 	case PHY_ID_BCM5906:	return "5906";
 	case PHY_ID_BCM5761:	return "5761";
+	case PHY_ID_BCM5717:	return "5717";
 	case PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
 	default:		return "unknown";
@@ -13910,51 +14381,6 @@ static int __devinit tg3_init_one(struct
 	tp->rx_pending = TG3_DEF_RX_RING_PENDING;
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 
-	intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
-	rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
-	sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
-	for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
-		struct tg3_napi *tnapi = &tp->napi[i];
-
-		tnapi->tp = tp;
-		tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
-
-		tnapi->int_mbox = intmbx;
-		if (i < 4)
-			intmbx += 0x8;
-		else
-			intmbx += 0x4;
-
-		tnapi->consmbox = rcvmbx;
-		tnapi->prodmbox = sndmbx;
-
-		if (i)
-			tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
-		else
-			tnapi->coal_now = HOSTCC_MODE_NOW;
-
-		if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
-			break;
-
-		/*
-		 * If we support MSIX, we'll be using RSS.  If we're using
-		 * RSS, the first vector only handles link interrupts and the
-		 * remaining vectors handle rx and tx interrupts.  Reuse the
-		 * mailbox values for the next iteration.  The values we setup
-		 * above are still useful for the single vectored mode.
-		 */
-		if (!i)
-			continue;
-
-		rcvmbx += 0x8;
-
-		if (sndmbx & 0x4)
-			sndmbx -= 0x4;
-		else
-			sndmbx += 0xc;
-	}
-
-	netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
 	dev->irq = pdev->irq;
@@ -13966,8 +14392,8 @@ static int __devinit tg3_init_one(struct
 		goto err_out_iounmap;
 	}
 
-	if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+	if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
+	    tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
 		dev->netdev_ops = &tg3_netdev_ops;
 	else
 		dev->netdev_ops = &tg3_netdev_ops_dma_bug;
@@ -14014,46 +14440,39 @@ static int __devinit tg3_init_one(struct
 
 	tg3_init_bufmgr_config(tp);
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
-		tp->fw_needed = FIRMWARE_TG3;
-
-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+	/* Selectively allow TSO based on operating conditions */
+	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
+	    (tp->fw_needed && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)))
 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
-	}
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
-	    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
-		tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
-	} else {
-		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
-			tp->fw_needed = FIRMWARE_TG3TSO5;
-		else
-			tp->fw_needed = FIRMWARE_TG3TSO;
+	else {
+		tp->tg3_flags2 &= ~(TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG);
+		tp->fw_needed = NULL;
 	}
 
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+		tp->fw_needed = FIRMWARE_TG3;
+
 	/* TSO is on by default on chips that support hardware TSO.
 	 * Firmware TSO on older chips gives lower performance, so it
 	 * is off by default, but can be enabled using ethtool.
 	 */
-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
-		if (dev->features & NETIF_F_IP_CSUM)
-			dev->features |= NETIF_F_TSO;
-		if ((dev->features & NETIF_F_IPV6_CSUM) &&
-		    (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2))
+	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
+	    (dev->features & NETIF_F_IP_CSUM))
+		dev->features |= NETIF_F_TSO;
+
+	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
+	    (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
+		if (dev->features & NETIF_F_IPV6_CSUM)
 			dev->features |= NETIF_F_TSO6;
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+		if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 		     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 			GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 			dev->features |= NETIF_F_TSO_ECN;
 	}
 
-
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
 	    !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
 	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
@@ -14065,7 +14484,7 @@ static int __devinit tg3_init_one(struct
 	if (err) {
 		printk(KERN_ERR PFX "Could not obtain valid ethernet address, "
 		       "aborting.\n");
-		goto err_out_fw;
+		goto err_out_iounmap;
 	}
 
 	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
@@ -14074,7 +14493,7 @@ static int __devinit tg3_init_one(struct
 			printk(KERN_ERR PFX "Cannot map APE registers, "
 			       "aborting.\n");
 			err = -ENOMEM;
-			goto err_out_fw;
+			goto err_out_iounmap;
 		}
 
 		tg3_ape_lock_init(tp);
@@ -14104,6 +14523,53 @@ static int __devinit tg3_init_one(struct
 	tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 	tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
+	intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+	rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+	sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+	for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		tnapi->tp = tp;
+		tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
+
+		tnapi->int_mbox = intmbx;
+		if (i < 4)
+			intmbx += 0x8;
+		else
+			intmbx += 0x4;
+
+		tnapi->consmbox = rcvmbx;
+		tnapi->prodmbox = sndmbx;
+
+		if (i) {
+			tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
+			netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
+		} else {
+			tnapi->coal_now = HOSTCC_MODE_NOW;
+			netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
+		}
+
+		if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+			break;
+
+		/*
+		 * If we support MSIX, we'll be using RSS.  If we're using
+		 * RSS, the first vector only handles link interrupts and the
+		 * remaining vectors handle rx and tx interrupts.  Reuse the
+		 * mailbox values for the next iteration.  The values we setup
+		 * above are still useful for the single vectored mode.
+		 */
+		if (!i)
+			continue;
+
+		rcvmbx += 0x8;
+
+		if (sndmbx & 0x4)
+			sndmbx -= 0x4;
+		else
+			sndmbx += 0xc;
+	}
+
 	tg3_init_coal(tp);
 
 	pci_set_drvdata(pdev, dev);
@@ -14122,13 +14588,14 @@ static int __devinit tg3_init_one(struct
 	       tg3_bus_string(tp, str),
 	       dev->dev_addr);
 
-	if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+	if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+		struct phy_device *phydev;
+		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 		printk(KERN_INFO
 		       "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-		       tp->dev->name,
-		       tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
-		       dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
-	else
+		       tp->dev->name, phydev->drv->name,
+		       dev_name(&phydev->dev));
+	} else
 		printk(KERN_INFO
 		       "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
 		       tp->dev->name, tg3_phy_string(tp),
@@ -14157,10 +14624,6 @@ err_out_apeunmap:
 		tp->aperegs = NULL;
 	}
 
-err_out_fw:
-	if (tp->fw)
-		release_firmware(tp->fw);
-
 err_out_iounmap:
 	if (tp->regs) {
 		iounmap(tp->regs);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tg3.h linux-libre-2.6.33-gnu1/drivers/net/tg3.h
--- linux-libre-2.6.32-gnu1/drivers/net/tg3.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tg3.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,6 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
  * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com)
  * Copyright (C) 2004 Sun Microsystems Inc.
+ * Copyright (C) 2007-2010 Broadcom Corporation.
  */
 
 #ifndef _T3_H
@@ -46,10 +47,15 @@
 #define  TG3PCI_DEVICE_TIGON3_57788	 0x1691
 #define  TG3PCI_DEVICE_TIGON3_5785_G	 0x1699 /* GPHY */
 #define  TG3PCI_DEVICE_TIGON3_5785_F	 0x16a0 /* 10/100 only */
-#define  TG3PCI_DEVICE_TIGON3_5717C	 0x1655
-#define  TG3PCI_DEVICE_TIGON3_5717S	 0x1656
-#define  TG3PCI_DEVICE_TIGON3_5718C	 0x1665
-#define  TG3PCI_DEVICE_TIGON3_5718S	 0x1666
+#define  TG3PCI_DEVICE_TIGON3_5717	 0x1655
+#define  TG3PCI_DEVICE_TIGON3_5718	 0x1656
+#define  TG3PCI_DEVICE_TIGON3_5724	 0x165c
+#define  TG3PCI_DEVICE_TIGON3_57781	 0x16b1
+#define  TG3PCI_DEVICE_TIGON3_57785	 0x16b5
+#define  TG3PCI_DEVICE_TIGON3_57761	 0x16b0
+#define  TG3PCI_DEVICE_TIGON3_57765	 0x16b4
+#define  TG3PCI_DEVICE_TIGON3_57791	 0x16b2
+#define  TG3PCI_DEVICE_TIGON3_57795	 0x16b6
 /* 0x04 --> 0x64 unused */
 #define TG3PCI_MSI_DATA			0x00000064
 /* 0x66 --> 0x68 unused */
@@ -103,6 +109,7 @@
 #define  CHIPREV_ID_5906_A1		 0xc001
 #define  CHIPREV_ID_57780_A0		 0x57780000
 #define  CHIPREV_ID_57780_A1		 0x57780001
+#define  CHIPREV_ID_5717_A0		 0x05717000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -122,6 +129,7 @@
 #define   ASIC_REV_5785			 0x5785
 #define   ASIC_REV_57780		 0x57780
 #define   ASIC_REV_5717			 0x5717
+#define   ASIC_REV_57765		 0x57785
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -141,8 +149,7 @@
 #define   METAL_REV_B1			 0x01
 #define   METAL_REV_B2			 0x02
 #define TG3PCI_DMA_RW_CTRL		0x0000006c
-#define  DMA_RWCTRL_MIN_DMA		 0x000000ff
-#define  DMA_RWCTRL_MIN_DMA_SHIFT	 0
+#define  DMA_RWCTRL_DIS_CACHE_ALIGNMENT  0x00000001
 #define  DMA_RWCTRL_READ_BNDRY_MASK	 0x00000700
 #define  DMA_RWCTRL_READ_BNDRY_DISAB	 0x00000000
 #define  DMA_RWCTRL_READ_BNDRY_16	 0x00000100
@@ -221,6 +228,7 @@
 /* 0xc0 --> 0xf4 unused */
 
 #define TG3PCI_GEN2_PRODID_ASICREV	0x000000f4
+#define TG3PCI_GEN15_PRODID_ASICREV	0x000000fc
 /* 0xf8 --> 0x200 unused */
 
 #define TG3_CORR_ERR_STAT		0x00000110
@@ -242,7 +250,11 @@
 #define MAILBOX_GENERAL_7		0x00000258 /* 64-bit */
 #define MAILBOX_RELOAD_STAT		0x00000260 /* 64-bit */
 #define MAILBOX_RCV_STD_PROD_IDX	0x00000268 /* 64-bit */
+#define TG3_RX_STD_PROD_IDX_REG		(MAILBOX_RCV_STD_PROD_IDX + \
+					 TG3_64BIT_REG_LOW)
 #define MAILBOX_RCV_JUMBO_PROD_IDX	0x00000270 /* 64-bit */
+#define TG3_RX_JMB_PROD_IDX_REG		(MAILBOX_RCV_JUMBO_PROD_IDX + \
+					 TG3_64BIT_REG_LOW)
 #define MAILBOX_RCV_MINI_PROD_IDX	0x00000278 /* 64-bit */
 #define MAILBOX_RCVRET_CON_IDX_0	0x00000280 /* 64-bit */
 #define MAILBOX_RCVRET_CON_IDX_1	0x00000288 /* 64-bit */
@@ -1043,6 +1055,8 @@
 #define  CPMU_MUTEX_REQ_DRIVER		 0x00001000
 #define TG3_CPMU_MUTEX_GNT		0x00003660
 #define  CPMU_MUTEX_GNT_DRIVER		 0x00001000
+#define TG3_CPMU_PHY_STRAP		0x00003664
+#define TG3_CPMU_PHY_STRAP_IS_SERDES	 0x00000020
 /* 0x3664 --> 0x3800 unused */
 
 /* Mbuf cluster free registers */
@@ -1264,8 +1278,9 @@
 #define  WDMAC_MODE_FIFOURUN_ENAB	 0x00000080
 #define  WDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
 #define  WDMAC_MODE_LNGREAD_ENAB	 0x00000200
-#define  WDMAC_MODE_RX_ACCEL	 	 0x00000400
+#define  WDMAC_MODE_RX_ACCEL		 0x00000400
 #define  WDMAC_MODE_STATUS_TAG_FIX	 0x20000000
+#define  WDMAC_MODE_BURST_ALL_DATA	 0xc0000000
 #define WDMAC_STATUS			0x00004c04
 #define  WDMAC_STATUS_TGTABORT		 0x00000004
 #define  WDMAC_STATUS_MSTABORT		 0x00000008
@@ -1809,6 +1824,11 @@
 
 #define TG3_OTP_DEFAULT			0x286c1640
 
+
+/* Hardware Legacy NVRAM layout */
+#define TG3_NVM_VPD_OFF			0x100
+#define TG3_NVM_VPD_LEN			256
+
 /* Hardware Selfboot NVRAM layout */
 #define TG3_NVM_HWSB_CFG1		0x00000004
 #define  TG3_NVM_HWSB_CFG1_MAJMSK	0xf8000000
@@ -1953,10 +1973,34 @@
 #define  NIC_SRAM_MBUF_POOL_BASE5705	0x00010000
 #define  NIC_SRAM_MBUF_POOL_SIZE5705	0x0000e000
 
+
 /* Currently this is fixed. */
-#define PHY_ADDR		0x01
+#define TG3_PHY_PCIE_ADDR		0x00
+#define TG3_PHY_MII_ADDR		0x01
 
-/* Tigon3 specific PHY MII registers. */
+
+/*** Tigon3 specific PHY PCIE registers. ***/
+
+#define TG3_PCIEPHY_BLOCK_ADDR		0x1f
+#define  TG3_PCIEPHY_XGXS_BLK1		0x0801
+#define  TG3_PCIEPHY_TXB_BLK		0x0861
+#define  TG3_PCIEPHY_BLOCK_SHIFT	4
+
+/* TG3_PCIEPHY_TXB_BLK */
+#define TG3_PCIEPHY_TX0CTRL1		0x15
+#define  TG3_PCIEPHY_TX0CTRL1_TXOCM	0x0003
+#define  TG3_PCIEPHY_TX0CTRL1_RDCTL	0x0008
+#define  TG3_PCIEPHY_TX0CTRL1_TXCMV	0x0030
+#define  TG3_PCIEPHY_TX0CTRL1_TKSEL	0x0040
+#define  TG3_PCIEPHY_TX0CTRL1_NB_EN	0x0400
+
+/* TG3_PCIEPHY_XGXS_BLK1 */
+#define TG3_PCIEPHY_PWRMGMT4		0x1a
+#define TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN	0x0038
+#define TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN	0x4000
+
+
+/*** Tigon3 specific PHY MII registers. ***/
 #define  TG3_BMCR_SPEED1000		0x0040
 
 #define MII_TG3_CTRL			0x09 /* 1000-baseT control register */
@@ -2055,6 +2099,9 @@
 #define MII_TG3_FET_SHDW_MISCCTRL	0x10
 #define  MII_TG3_FET_SHDW_MISCCTRL_MDIX	0x4000
 
+#define MII_TG3_FET_SHDW_AUXMODE4	0x1a
+#define MII_TG3_FET_SHDW_AUXMODE4_SBPD	0x0008
+
 #define MII_TG3_FET_SHDW_AUXSTAT2	0x1b
 #define  MII_TG3_FET_SHDW_AUXSTAT2_APD	0x0020
 
@@ -2410,10 +2457,6 @@ struct ring_info {
 	DECLARE_PCI_UNMAP_ADDR(mapping)
 };
 
-struct tx_ring_info {
-	struct sk_buff			*skb;
-};
-
 struct tg3_config_info {
 	u32				flags;
 };
@@ -2542,8 +2585,10 @@ struct tg3_ethtool_stats {
 };
 
 struct tg3_rx_prodring_set {
-	u32				rx_std_ptr;
-	u32				rx_jmb_ptr;
+	u32				rx_std_prod_idx;
+	u32				rx_std_cons_idx;
+	u32				rx_jmb_prod_idx;
+	u32				rx_jmb_cons_idx;
 	struct tg3_rx_buffer_desc	*rx_std;
 	struct tg3_ext_rx_buffer_desc	*rx_jmb;
 	struct ring_info		*rx_std_buffers;
@@ -2571,10 +2616,11 @@ struct tg3_napi {
 	u32				consmbox;
 	u32				rx_rcb_ptr;
 	u16				*rx_rcb_prod_idx;
+	struct tg3_rx_prodring_set	*prodring;
 
 	struct tg3_rx_buffer_desc	*rx_rcb;
 	struct tg3_tx_buffer_desc	*tx_ring;
-	struct tx_ring_info		*tx_buffers;
+	struct ring_info		*tx_buffers;
 
 	dma_addr_t			status_mapping;
 	dma_addr_t			rx_rcb_mapping;
@@ -2654,7 +2700,7 @@ struct tg3 {
 	struct vlan_group		*vlgrp;
 #endif
 
-	struct tg3_rx_prodring_set	prodring[1];
+	struct tg3_rx_prodring_set	prodring[TG3_IRQ_MAX_VECS - 1];
 
 
 	/* begin "everything else" cacheline(s) section */
@@ -2725,7 +2771,7 @@ struct tg3 {
 #define TG3_FLG2_SERDES_PREEMPHASIS	0x00020000
 #define TG3_FLG2_5705_PLUS		0x00040000
 #define TG3_FLG2_5750_PLUS		0x00080000
-#define TG3_FLG2_PROTECTED_NVRAM	0x00100000
+#define TG3_FLG2_HW_TSO_3		0x00100000
 #define TG3_FLG2_USING_MSI		0x00200000
 #define TG3_FLG2_USING_MSIX		0x00400000
 #define TG3_FLG2_USING_MSI_OR_MSIX	(TG3_FLG2_USING_MSI | \
@@ -2737,7 +2783,9 @@ struct tg3 {
 #define TG3_FLG2_ICH_WORKAROUND		0x02000000
 #define TG3_FLG2_5780_CLASS		0x04000000
 #define TG3_FLG2_HW_TSO_2		0x08000000
-#define TG3_FLG2_HW_TSO			(TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
+#define TG3_FLG2_HW_TSO			(TG3_FLG2_HW_TSO_1 | \
+					 TG3_FLG2_HW_TSO_2 | \
+					 TG3_FLG2_HW_TSO_3)
 #define TG3_FLG2_1SHOT_MSI		0x10000000
 #define TG3_FLG2_PHY_JITTER_BUG		0x20000000
 #define TG3_FLG2_NO_FWARE_REPORTED	0x40000000
@@ -2745,6 +2793,7 @@ struct tg3 {
 	u32				tg3_flags3;
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS	0x00000001
 #define TG3_FLG3_ENABLE_APE		0x00000002
+#define TG3_FLG3_PROTECTED_NVRAM	0x00000004
 #define TG3_FLG3_5701_DMA_BUG		0x00000008
 #define TG3_FLG3_USE_PHYLIB		0x00000010
 #define TG3_FLG3_MDIOBUS_INITED		0x00000020
@@ -2756,9 +2805,13 @@ struct tg3 {
 #define TG3_FLG3_PHY_ENABLE_APD		0x00001000
 #define TG3_FLG3_5755_PLUS		0x00002000
 #define TG3_FLG3_NO_NVRAM		0x00004000
-#define TG3_FLG3_TOGGLE_10_100_L1PLLPD	0x00008000
 #define TG3_FLG3_PHY_IS_FET		0x00010000
 #define TG3_FLG3_ENABLE_RSS		0x00020000
+#define TG3_FLG3_ENABLE_TSS		0x00040000
+#define TG3_FLG3_4G_DMA_BNDRY_BUG	0x00080000
+#define TG3_FLG3_40BIT_DMA_LIMIT_BUG	0x00100000
+#define TG3_FLG3_SHORT_DMA_BUG		0x00200000
+#define TG3_FLG3_USE_JUMBO_BDFLAG	0x00400000
 
 	struct timer_list		timer;
 	u16				timer_counter;
@@ -2825,6 +2878,7 @@ struct tg3 {
 #define PHY_ID_BCM5756			0xbc050ed0
 #define PHY_ID_BCM5784			0xbc050fa0
 #define PHY_ID_BCM5761			0xbc050fd0
+#define PHY_ID_BCM5717			0x5c0d8a00
 #define PHY_ID_BCM5906			0xdc00ac40
 #define PHY_ID_BCM8002			0x60010140
 #define PHY_ID_INVALID			0xffffffff
@@ -2834,6 +2888,7 @@ struct tg3 {
 #define PHY_REV_BCM5401_C0		0x6
 #define PHY_REV_BCM5411_X0		0x1 /* Found on Netgear GA302T */
 #define TG3_PHY_ID_BCM50610		0x143bd60
+#define TG3_PHY_ID_BCM50610M	0x143bd70
 #define TG3_PHY_ID_BCMAC131		0x143bc70
 #define TG3_PHY_ID_RTL8211C		0x001cc910
 #define TG3_PHY_ID_RTL8201E		0x00008200
@@ -2846,8 +2901,9 @@ struct tg3 {
 	u32				led_ctrl;
 	u32				phy_otp;
 
-	char				board_part_number[24];
-#define TG3_VER_SIZE 32
+#define TG3_BPN_SIZE			24
+	char				board_part_number[TG3_BPN_SIZE];
+#define TG3_VER_SIZE			ETHTOOL_FWVERS_LEN
 	char				fw_ver[TG3_VER_SIZE];
 	u32				nic_sram_data_cfg;
 	u32				pci_clock_ctrl;
@@ -2865,7 +2921,7 @@ struct tg3 {
 	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
 	 (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \
 	 (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM5761 || \
-	 (X) == PHY_ID_BCM8002)
+	 (X) == PHY_ID_BCM5717 || (X) == PHY_ID_BCM8002)
 
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tlan.c linux-libre-2.6.33-gnu1/drivers/net/tlan.c
--- linux-libre-2.6.32-gnu1/drivers/net/tlan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tlan.c	2010-02-24 13:52:17.000000000 -0500
@@ -1549,7 +1549,8 @@ static u32 TLan_HandleRxEOF( struct net_
 		if (tmpCStat & TLAN_CSTAT_EOC)
 			eoc = 1;
 
-		new_skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+		new_skb = netdev_alloc_skb_ip_align(dev,
+						    TLAN_MAX_FRAME_SIZE + 5);
 		if ( !new_skb )
 			goto drop_and_reuse;
 
@@ -1563,7 +1564,6 @@ static u32 TLan_HandleRxEOF( struct net_
 		skb->protocol = eth_type_trans( skb, dev );
 		netif_rx( skb );
 
-		skb_reserve( new_skb, NET_IP_ALIGN );
 		head_list->buffer[0].address = pci_map_single(priv->pciDev,
 							      new_skb->data,
 							      TLAN_MAX_FRAME_SIZE,
@@ -1755,8 +1755,8 @@ static u32 TLan_HandleStatusCheck( struc
 			     ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
                 		tlphy_ctl |= TLAN_TC_SWAPOL;
                 		TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
-        		} else if ( ( tlphy_sts & TLAN_TS_POLOK )
-				    && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
+			} else if ( ( tlphy_sts & TLAN_TS_POLOK ) &&
+				    ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
                 		tlphy_ctl &= ~TLAN_TC_SWAPOL;
                 		TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
         		}
@@ -1967,13 +1967,12 @@ static void TLan_ResetLists( struct net_
 		list->cStat = TLAN_CSTAT_READY;
 		list->frameSize = TLAN_MAX_FRAME_SIZE;
 		list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
-		skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+		skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
 		if ( !skb ) {
 			pr_err("TLAN: out of memory for received data.\n" );
 			break;
 		}
 
-		skb_reserve( skb, NET_IP_ALIGN );
 		list->buffer[0].address = pci_map_single(priv->pciDev,
 							 skb->data,
 							 TLAN_MAX_FRAME_SIZE,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/3c359.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/3c359.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 14:01:36.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 12:08:58.000000000 -0400
@@ -610,9 +610,8 @@ static int xl_open(struct net_device *de
 
 	u16 switchsettings, switchsettings_eeprom  ;
  
-	if(request_irq(dev->irq, &xl_interrupt, IRQF_SHARED , "3c359", dev)) {
+	if (request_irq(dev->irq, xl_interrupt, IRQF_SHARED , "3c359", dev))
 		return -EAGAIN;
-	}
 
 	/* 
 	 * Read the information from the EEPROM that we need.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/ibmtr.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/ibmtr.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/ibmtr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/ibmtr.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,7 +96,7 @@
  *
  *      Change by Mike Sullivan et al.:
  *      + added turbo card support. No need to use lanaid to configure
- *      the adapter into isa compatiblity mode.
+ *      the adapter into isa compatibility mode.
  *
  *      Changes by Burt Silverman to allow the computer to behave nicely when
  *	a cable is pulled or not in place, or a PCMCIA card is removed hot.
@@ -680,7 +680,7 @@ static int __devinit ibmtr_probe1(struct
 
 	/* The PCMCIA has already got the interrupt line and the io port, 
 	   so no chance of anybody else getting it - MLP */
-	if (request_irq(dev->irq = irq, &tok_interrupt, 0, "ibmtr", dev) != 0) {
+	if (request_irq(dev->irq = irq, tok_interrupt, 0, "ibmtr", dev) != 0) {
 		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",
 					irq);
 		iounmap(t_mmio);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/lanstreamer.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/lanstreamer.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/lanstreamer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/lanstreamer.c	2010-02-24 13:52:17.000000000 -0500
@@ -596,7 +596,7 @@ static int streamer_open(struct net_devi
 	        rc=streamer_reset(dev);
 	}
 
-	if (request_irq(dev->irq, &streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) {
+	if (request_irq(dev->irq, streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) {
 		return -EAGAIN;
 	}
 #if STREAMER_DEBUG
@@ -712,8 +712,8 @@ static int streamer_open(struct net_devi
 					strcat(open_error, " - ");
 					strcat(open_error, open_min_error[(error_code & 0x0f)]);
 
-					if (!streamer_priv->streamer_ring_speed
-					    && ((error_code & 0x0f) == 0x0d)) 
+					if (!streamer_priv->streamer_ring_speed &&
+					    ((error_code & 0x0f) == 0x0d))
 					{
 						printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n", dev->name);
 						printk(KERN_WARNING "%s: Please try again with a specified ring speed \n", dev->name);
@@ -1032,8 +1032,8 @@ static irqreturn_t streamer_interrupt(in
 	sisr = readw(streamer_mmio + SISR);
 
 	while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | 
-		       SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR))
-               && (max_intr > 0)) {
+		       SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR)) &&
+	      (max_intr > 0)) {
 
 		if(sisr & SISR_PAR_ERR) {
 			writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/olympic.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/olympic.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/olympic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/olympic.c	2010-02-24 13:52:17.000000000 -0500
@@ -445,9 +445,9 @@ static int olympic_open(struct net_devic
 
 	olympic_init(dev);
 
-	if(request_irq(dev->irq, &olympic_interrupt, IRQF_SHARED , "olympic", dev)) {
+	if (request_irq(dev->irq, olympic_interrupt, IRQF_SHARED , "olympic",
+			dev))
 		return -EAGAIN;
-	}
 
 #if OLYMPIC_DEBUG
 	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/smctr.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/smctr.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 14:01:40.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 12:09:02.000000000 -0400
@@ -426,7 +426,7 @@ static int smctr_alloc_shared_memory(str
         smctr_malloc(dev, 1L);
 
         /* Allocate Non-MAC receive data buffers.
-         * To guarantee a minimum of 256 contigous memory to
+         * To guarantee a minimum of 256 contiguous memory to
          * UM_Receive_Packet's lookahead pointer, before a page
          * change or ring end is encountered, place each rx buffer on
          * a 256 byte boundary.
@@ -2309,9 +2309,9 @@ static irqreturn_t smctr_interrupt(int i
                                 else
                                 {
                                         if((tp->acb_head->cmd
-                                                == ACB_CMD_READ_TRC_STATUS)
-                                                && (tp->acb_head->subcmd
-                                                == RW_TRC_STATUS_BLOCK))
+					    == ACB_CMD_READ_TRC_STATUS) &&
+					   (tp->acb_head->subcmd
+					    == RW_TRC_STATUS_BLOCK))
                                         {
                                                 if(tp->ptr_bcn_type)
                                                 {
@@ -2331,8 +2331,8 @@ static irqreturn_t smctr_interrupt(int i
                                                         smctr_disable_16bit(dev);
                                                         err = smctr_ring_status_chg(dev);
                                                         smctr_enable_16bit(dev);
-                                                        if((tp->ring_status & REMOVE_RECEIVED)
-                                                                && (tp->config_word0 & NO_AUTOREMOVE))
+                                                        if((tp->ring_status & REMOVE_RECEIVED) &&
+							   (tp->config_word0 & NO_AUTOREMOVE))
                                                         {
                                                                 smctr_issue_remove_cmd(dev);
                                                         }
@@ -2511,9 +2511,9 @@ static int smctr_issue_init_timers_cmd(s
         tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE;
         tp->config_word1 = 0;
 
-        if((tp->media_type == MEDIA_STP_16)
-                || (tp->media_type == MEDIA_UTP_16)
-                || (tp->media_type == MEDIA_STP_16_UTP_16))
+        if((tp->media_type == MEDIA_STP_16) ||
+	   (tp->media_type == MEDIA_UTP_16) ||
+	   (tp->media_type == MEDIA_STP_16_UTP_16))
         {
                 tp->config_word0 |= FREQ_16MB_BIT;
         }
@@ -2556,9 +2556,9 @@ static int smctr_issue_init_timers_cmd(s
                         tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS;
         }
 
-        if((tp->media_type == MEDIA_STP_16)
-                || (tp->media_type == MEDIA_UTP_16)
-                || (tp->media_type == MEDIA_STP_16_UTP_16))
+        if((tp->media_type == MEDIA_STP_16) ||
+	   (tp->media_type == MEDIA_UTP_16) ||
+	   (tp->media_type == MEDIA_STP_16_UTP_16))
         {
                 tp->config_word1 |= INTERFRAME_SPACING_16;
         }
@@ -2568,9 +2568,9 @@ static int smctr_issue_init_timers_cmd(s
         *pTimer_Struc++ = tp->config_word0;
         *pTimer_Struc++ = tp->config_word1;
 
-        if((tp->media_type == MEDIA_STP_4)
-                || (tp->media_type == MEDIA_UTP_4)
-                || (tp->media_type == MEDIA_STP_4_UTP_4))
+        if((tp->media_type == MEDIA_STP_4) ||
+	   (tp->media_type == MEDIA_UTP_4) ||
+	   (tp->media_type == MEDIA_STP_4_UTP_4))
         {
                 *pTimer_Struc++ = 0x00FA;       /* prescale */
                 *pTimer_Struc++ = 0x2710;       /* TPT_limit */
@@ -2990,8 +2990,8 @@ static int smctr_load_firmware(struct ne
 	}
 
         /* Verify the firmware exists and is there in the right amount. */
-        if (!fw->data
-                || (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION))
+        if (!fw->data ||
+	    (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION))
         {
                 err = (UCODE_NOT_PRESENT);
 		goto out;
@@ -3010,9 +3010,8 @@ static int smctr_load_firmware(struct ne
         smctr_enable_16bit(dev);
         smctr_set_page(dev, (__u8 *)tp->ram_access);
 
-        if((smctr_checksum_firmware(dev))
-                || (*(fw->data + UCODE_VERSION_OFFSET)
-                > tp->microcode_version))
+        if((smctr_checksum_firmware(dev)) ||
+	   (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version))
         {
                 smctr_enable_adapter_ctrl_store(dev);
 
@@ -3117,9 +3116,9 @@ static int smctr_lobe_media_test(struct
         }
 
         /* Check if any frames received during test. */
-        if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status)
-                || (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status))
-			goto err;
+        if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) ||
+	   (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status))
+		goto err;
 
         /* Set receive mask to "Promisc" mode. */
         tp->receive_mask = saved_rcv_mask;
@@ -3303,8 +3302,8 @@ static int smctr_make_group_addr(struct
         /* Set Group Address Sub-vector to all zeros if only the
          * Group Address/Functional Address Indicator is set.
          */
-        if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00
-        	&& tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00)
+        if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 &&
+	   tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00)
                 tsv->svv[0] = 0x00;
 
         return (0);
@@ -3876,10 +3875,10 @@ static int smctr_process_rx_packet(MAC_H
         /* NOTE: UNKNOWN MAC frames will NOT be passed up unless
          * ACCEPT_ATT_MAC_FRAMES is set.
          */
-        if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
-                && (xframe == (__u8)0))
-                || ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES)
-                && (xframe == (__u8)1)))
+        if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) &&
+	    (xframe == (__u8)0)) ||
+	   ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) &&
+	    (xframe == (__u8)1)))
         {
                 rmf->vl = SWAP_BYTES(rmf->vl);
 
@@ -3934,8 +3933,8 @@ static int smctr_ram_memory_test(struct
 
                 word_pattern = start_pattern;
 
-                for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1
-                        && (~err); j += 2, word_pattern++)
+                for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 && (~err);
+		    j += 2, word_pattern++)
                 {
                         word_read = *(__u16 *)(pword + j);
                         if(word_read != word_pattern)
@@ -3959,8 +3958,7 @@ static int smctr_ram_memory_test(struct
                 for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2)
                         *(__u16 *)(pword + j) = word_pattern;
 
-                for(j =0; j < (__u32)tp->ram_usable * 1024
-                        && (~err); j += 2)
+                for(j =0; j < (__u32)tp->ram_usable * 1024 && (~err); j += 2)
                 {
                         word_read = *(__u16 *)(pword + j);
                         if(word_read != word_pattern)
@@ -4325,8 +4323,8 @@ static int smctr_restart_tx_chain(struct
         if(smctr_debug > 10)
                 printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name);
 
-        if(tp->num_tx_fcbs_used[queue] != 0
-                && tp->tx_queue_status[queue] == NOT_TRANSMITING)
+        if(tp->num_tx_fcbs_used[queue] != 0 &&
+	   tp->tx_queue_status[queue] == NOT_TRANSMITING)
         {
                 tp->tx_queue_status[queue] = TRANSMITING;
                 err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
@@ -4349,8 +4347,8 @@ static int smctr_ring_status_chg(struct
          */
         if(tp->ring_status_flags == MONITOR_STATE_CHANGED)
         {
-                if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE)
-                        || (tp->monitor_state == MS_STANDBY_MONITOR_STATE))
+                if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) ||
+		   (tp->monitor_state == MS_STANDBY_MONITOR_STATE))
                 {
                         tp->monitor_state_ready = 1;
                 }
@@ -4363,8 +4361,8 @@ static int smctr_ring_status_chg(struct
                         tp->monitor_state_ready = 0;
 
 			/* Ring speed problem, switching to auto mode. */
-			if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE
-				&& !tp->cleanup)
+			if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE &&
+			   !tp->cleanup)
 			{
 				printk(KERN_INFO "%s: Incorrect ring speed switching.\n",
 					dev->name);
@@ -4442,8 +4440,8 @@ static int smctr_rx_frame(struct net_dev
         {
                 err = HARDWARE_FAILED;
 
-                if(((status & 0x007f) == 0)
-                        || ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0))
+                if(((status & 0x007f) == 0) ||
+		   ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0))
                 {
                         /* frame length less the CRC (4 bytes) + FS (1 byte) */
                         rx_size = tp->rx_fcb_curr[queue]->frame_length - 5;
@@ -4538,8 +4536,8 @@ static int smctr_send_dat(struct net_dev
         }
 
         /* Check if GOOD frame Tx'ed. */
-        if(!(fcb->frame_status &  FCB_COMMAND_DONE)
-                || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
+        if(!(fcb->frame_status &  FCB_COMMAND_DONE) ||
+	   fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
         {
                 return (INITIALIZE_FAILED);
         }
@@ -4653,8 +4651,8 @@ static int smctr_send_lobe_media_test(st
         }
 
         /* Check if GOOD frame Tx'ed */
-        if(!(fcb->frame_status & FCB_COMMAND_DONE)
-                || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
+        if(!(fcb->frame_status & FCB_COMMAND_DONE) ||
+	   fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
         {
                 return (LOBE_MEDIA_TEST_FAILED);
         }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tokenring/tms380tr.c linux-libre-2.6.33-gnu1/drivers/net/tokenring/tms380tr.c
--- linux-libre-2.6.32-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 14:01:43.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 12:09:05.000000000 -0400
@@ -729,8 +729,8 @@ static void tms380tr_timer_chk(unsigned
 		return;
 
 	tms380tr_chk_outstanding_cmds(dev);
-	if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies)
-		&& (tp->TplFree != tp->TplBusy))
+	if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies) &&
+	   (tp->TplFree != tp->TplBusy))
 	{
 		/* Anything to send, but stalled too long */
 		tp->LastSendTime = jiffies;
@@ -830,8 +830,8 @@ irqreturn_t tms380tr_interrupt(int irq,
 		}
 
 		/* Reset system interrupt if not already done. */
-		if(irq_type != STS_IRQ_TRANSMIT_STATUS
-			&& irq_type != STS_IRQ_RECEIVE_STATUS) {
+		if(irq_type != STS_IRQ_TRANSMIT_STATUS &&
+		   irq_type != STS_IRQ_RECEIVE_STATUS) {
 			tms380tr_reset_interrupt(dev);
 		}
 
@@ -895,10 +895,10 @@ static unsigned char tms380tr_chk_ssb(st
 
 	/* Check if this interrupt does use the SSB. */
 
-	if(IrqType != STS_IRQ_TRANSMIT_STATUS
-		&& IrqType != STS_IRQ_RECEIVE_STATUS
-		&& IrqType != STS_IRQ_COMMAND_STATUS
-		&& IrqType != STS_IRQ_RING_STATUS)
+	if(IrqType != STS_IRQ_TRANSMIT_STATUS &&
+	   IrqType != STS_IRQ_RECEIVE_STATUS &&
+	   IrqType != STS_IRQ_COMMAND_STATUS &&
+	   IrqType != STS_IRQ_RING_STATUS)
 	{
 		return (1);	/* SSB not involved. */
 	}
@@ -1364,6 +1364,8 @@ static int tms380tr_reset_adapter(struct
 	return (-1);
 }
 
+/*(DEBLOBBED)*/
+
 /*
  * Starts bring up diagnostics of token ring adapter and evaluates
  * diagnostic results.
@@ -1483,8 +1485,8 @@ static int tms380tr_init_adapter(struct
 			/* Mask interesting status bits */
 			Status = SIFREADW(SIFSTS);
 			Status &= STS_MASK;
-		} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0)
-			&& ((Status & STS_ERROR) == 0) && (loop_cnt != 0));
+		} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0) &&
+			((Status & STS_ERROR) == 0) && (loop_cnt != 0));
 
 		if((Status & (STS_INITIALIZE | STS_ERROR | STS_TEST)) == 0)
 		{
@@ -2181,8 +2183,8 @@ static void tms380tr_rcv_status_irq(stru
 				}
 			}
 
-			if(skb && (rpl->SkbStat == SKB_DATA_COPY
-				|| rpl->SkbStat == SKB_DMA_DIRECT))
+			if(skb && (rpl->SkbStat == SKB_DATA_COPY ||
+				   rpl->SkbStat == SKB_DMA_DIRECT))
 			{
 				if(rpl->SkbStat == SKB_DATA_COPY)
 					skb_copy_to_linear_data(skb, ReceiveDataPtr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tsi108_eth.c linux-libre-2.6.33-gnu1/drivers/net/tsi108_eth.c
--- linux-libre-2.6.32-gnu1/drivers/net/tsi108_eth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tsi108_eth.c	2010-02-24 13:52:17.000000000 -0500
@@ -802,13 +802,11 @@ static int tsi108_refill_rx(struct net_d
 		int rx = data->rxhead;
 		struct sk_buff *skb;
 
-		data->rxskbs[rx] = skb = netdev_alloc_skb(dev,
-							  TSI108_RXBUF_SIZE + 2);
+		skb = netdev_alloc_skb_ip_align(dev, TSI108_RXBUF_SIZE);
+		data->rxskbs[rx] = skb;
 		if (!skb)
 			break;
 
-		skb_reserve(skb, 2); /* Align the data on a 4-byte boundary. */
-
 		data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
 							TSI108_RX_SKB_SIZE,
 							DMA_FROM_DEVICE);
@@ -1356,7 +1354,7 @@ static int tsi108_open(struct net_device
 	for (i = 0; i < TSI108_RXRING_LEN; i++) {
 		struct sk_buff *skb;
 
-		skb = netdev_alloc_skb(dev, TSI108_RXBUF_SIZE + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(dev, TSI108_RXBUF_SIZE);
 		if (!skb) {
 			/* Bah.  No memory for now, but maybe we'll get
 			 * some more later.
@@ -1370,8 +1368,6 @@ static int tsi108_open(struct net_device
 		}
 
 		data->rxskbs[i] = skb;
-		/* Align the payload on a 4-byte boundary */
-		skb_reserve(skb, 2);
 		data->rxskbs[i] = skb;
 		data->rxring[i].buf0 = virt_to_phys(data->rxskbs[i]->data);
 		data->rxring[i].misc = TSI108_RX_OWN | TSI108_RX_INT;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/21142.c linux-libre-2.6.33-gnu1/drivers/net/tulip/21142.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/21142.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/21142.c	2010-02-24 13:52:17.000000000 -0500
@@ -209,10 +209,10 @@ void t21142_lnk_change(struct net_device
 			printk(KERN_DEBUG "%s:  Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
 				   dev->name, tp->csr6, ioread32(ioaddr + CSR6),
 				   ioread32(ioaddr + CSR12));
-	} else if ((tp->nwayset  &&  (csr5 & 0x08000000)
-				&& (dev->if_port == 3  ||  dev->if_port == 5)
-				&& (csr12 & 2) == 2) ||
-			   (tp->nway && (csr5 & (TPLnkFail)))) {
+	} else if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
+		    (dev->if_port == 3  ||  dev->if_port == 5) &&
+		    (csr12 & 2) == 2) ||
+		   (tp->nway && (csr5 & (TPLnkFail)))) {
 		/* Link blew? Maybe restart NWay. */
 		del_timer_sync(&tp->timer);
 		t21142_start_nway(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/de2104x.c linux-libre-2.6.33-gnu1/drivers/net/tulip/de2104x.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/de2104x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/de2104x.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,9 +62,9 @@ module_param (debug, int, 0);
 MODULE_PARM_DESC (debug, "de2104x bitmapped message enable number");
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
-        || defined(CONFIG_SPARC) || defined(__ia64__) \
-        || defined(__sh__) || defined(__mips__)
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
+        defined(CONFIG_SPARC) || defined(__ia64__) ||		   \
+        defined(__sh__) || defined(__mips__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 100;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/dmfe.c linux-libre-2.6.33-gnu1/drivers/net/tulip/dmfe.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/dmfe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/dmfe.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,6 +92,10 @@
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
+#ifdef CONFIG_TULIP_DM910X
+#include <linux/of.h>
+#endif
+
 
 /* Board/System/Debug information/definition ---------------- */
 #define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
@@ -377,6 +381,23 @@ static int __devinit dmfe_init_one (stru
 	if (!printed_version++)
 		printk(version);
 
+	/*
+	 *	SPARC on-board DM910x chips should be handled by the main
+	 *	tulip driver, except for early DM9100s.
+	 */
+#ifdef CONFIG_TULIP_DM910X
+	if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) ||
+	    ent->driver_data == PCI_DM9102_ID) {
+		struct device_node *dp = pci_device_to_OF_node(pdev);
+
+		if (dp && of_get_property(dp, "local-mac-address", NULL)) {
+			printk(KERN_INFO DRV_NAME
+			       ": skipping on-board DM910x (use tulip)\n");
+			return -ENODEV;
+		}
+	}
+#endif
+
 	/* Init network device */
 	dev = alloc_etherdev(sizeof(*db));
 	if (dev == NULL)
@@ -543,7 +564,7 @@ static int dmfe_open(struct DEVICE *dev)
 
 	DMFE_DBUG(0, "dmfe_open", 0);
 
-	ret = request_irq(dev->irq, &dmfe_interrupt,
+	ret = request_irq(dev->irq, dmfe_interrupt,
 			  IRQF_SHARED, dev->name, dev);
 	if (ret)
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/eeprom.c linux-libre-2.6.33-gnu1/drivers/net/tulip/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,10 +174,10 @@ void __devinit tulip_parse_eeprom(struct
 		}
 	  /* Do a fix-up based on the vendor half of the station address prefix. */
 	  for (i = 0; eeprom_fixups[i].name; i++) {
-		if (dev->dev_addr[0] == eeprom_fixups[i].addr0
-			&&  dev->dev_addr[1] == eeprom_fixups[i].addr1
-			&&  dev->dev_addr[2] == eeprom_fixups[i].addr2) {
-		  if (dev->dev_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
+		  if (dev->dev_addr[0] == eeprom_fixups[i].addr0 &&
+		      dev->dev_addr[1] == eeprom_fixups[i].addr1 &&
+		      dev->dev_addr[2] == eeprom_fixups[i].addr2) {
+		  if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
 			  i++;			/* An Accton EN1207, not an outlaw Maxtech. */
 		  memcpy(ee_data + 26, eeprom_fixups[i].newtable,
 				 sizeof(eeprom_fixups[i].newtable));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/interrupt.c linux-libre-2.6.33-gnu1/drivers/net/tulip/interrupt.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/interrupt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/interrupt.c	2010-02-24 13:52:17.000000000 -0500
@@ -170,8 +170,8 @@ int tulip_poll(struct napi_struct *napi,
 				      RxDescCollisionSeen |
 				      RxDescRunt |
 				      RxDescDescErr |
-				      RxWholePkt)) != RxWholePkt
-			   || pkt_len > 1518) {
+				      RxWholePkt)) != RxWholePkt ||
+			   pkt_len > 1518) {
 			       if ((status & (RxLengthOver2047 |
 					      RxWholePkt)) != RxWholePkt) {
                                 /* Ingore earlier buffers. */
@@ -201,8 +201,8 @@ int tulip_poll(struct napi_struct *napi,
 
                                /* Check if the packet is long enough to accept without copying
                                   to a minimally-sized skbuff. */
-                               if (pkt_len < tulip_rx_copybreak
-                                   && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                               if (pkt_len < tulip_rx_copybreak &&
+                                   (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
                                        skb_reserve(skb, 2);    /* 16 byte align the IP header */
                                        pci_dma_sync_single_for_cpu(tp->pdev,
 								   tp->rx_buffers[entry].mapping,
@@ -395,8 +395,8 @@ static int tulip_rx(struct net_device *d
 			       RxDescCollisionSeen |
 			       RxDescRunt |
 			       RxDescDescErr |
-			       RxWholePkt))        != RxWholePkt
-		     || pkt_len > 1518) {
+			       RxWholePkt))        != RxWholePkt ||
+		    pkt_len > 1518) {
 			if ((status & (RxLengthOver2047 |
 			     RxWholePkt))         != RxWholePkt) {
 				/* Ingore earlier buffers. */
@@ -425,8 +425,8 @@ static int tulip_rx(struct net_device *d
 
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < tulip_rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < tulip_rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(tp->pdev,
 							    tp->rx_buffers[entry].mapping,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/Kconfig linux-libre-2.6.33-gnu1/drivers/net/tulip/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION
 
 	  If in doubt, say Y.
 
+config TULIP_DM910X
+	def_bool y
+	depends on TULIP && SPARC
+
 config DE4X5
 	tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
 	depends on PCI || EISA
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/media.c linux-libre-2.6.33-gnu1/drivers/net/tulip/media.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/media.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/media.c	2010-02-24 13:52:17.000000000 -0500
@@ -468,8 +468,8 @@ void __devinit tulip_find_mii (struct ne
 		int phy = phyn & 0x1f;
 		int mii_status = tulip_mdio_read (dev, phy, MII_BMSR);
 		if ((mii_status & 0x8301) == 0x8001 ||
-		    ((mii_status & BMSR_100BASE4) == 0
-		     && (mii_status & 0x7800) != 0)) {
+		    ((mii_status & BMSR_100BASE4) == 0 &&
+		     (mii_status & 0x7800) != 0)) {
 			/* preserve Becker logic, gain indentation level */
 		} else {
 			continue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/pnic2.c linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic2.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/pnic2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/pnic2.c	2010-02-24 13:52:17.000000000 -0500
@@ -316,9 +316,9 @@ void pnic2_lnk_change(struct net_device
 		}
 	}
 
-	if ((tp->nwayset  &&  (csr5 & 0x08000000)
-			  && (dev->if_port == 3  ||  dev->if_port == 5)
-			  && (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {
+	if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
+	     (dev->if_port == 3  ||  dev->if_port == 5) &&
+	     (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {
 
 		/* Link blew? Maybe restart NWay. */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/tulip_core.c linux-libre-2.6.33-gnu1/drivers/net/tulip/tulip_core.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/tulip_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/tulip_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,9 +64,9 @@ const char * const medianame[32] = {
 };
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
-	|| defined(CONFIG_SPARC) || defined(__ia64__) \
-	|| defined(__sh__) || defined(__mips__)
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
+	defined(CONFIG_SPARC) || defined(__ia64__) || \
+	defined(__sh__) || defined(__mips__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 100;
@@ -196,9 +196,13 @@ struct tulip_chip_table tulip_tbl[] = {
 	| HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
 
   /* DM910X */
+#ifdef CONFIG_TULIP_DM910X
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
 	tulip_timer, tulip_media_task },
+#else
+  { NULL },
+#endif
 
   /* RS7112 */
   { "Conexant LANfinity", 256, 0x0001ebef,
@@ -228,8 +232,10 @@ static struct pci_device_id tulip_pci_tb
 	{ 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
 	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+#ifdef CONFIG_TULIP_DM910X
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+#endif
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
@@ -243,6 +249,7 @@ static struct pci_device_id tulip_pci_tb
 	{ 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
 	{ 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
+	{ 0x1414, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Microsoft MN-120 */
 	{ 0x1414, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ } /* terminate list */
 };
@@ -449,8 +456,8 @@ media_picked:
 			iowrite32(0x0201B078, ioaddr + 0xB8);
 			next_tick = 1*HZ;
 		}
-	} else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
-			   && ! tp->medialock) {
+	} else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) &&
+		   ! tp->medialock) {
 		dev->if_port = 0;
 		tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
 		iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
@@ -506,7 +513,7 @@ tulip_open(struct net_device *dev)
 
 	tulip_init_ring (dev);
 
-	retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev);
+	retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev);
 	if (retval)
 		goto free_ring;
 
@@ -535,9 +542,9 @@ static void tulip_tx_timeout(struct net_
 		if (tulip_debug > 1)
 			printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
 				   dev->name);
-	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
-			   || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881
-			   || tp->chip_id == DM910X) {
+	} else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 ||
+		   tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 ||
+		   tp->chip_id == DM910X) {
 		printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
 			   "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
 			   dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
@@ -1299,18 +1306,30 @@ static int __devinit tulip_init_one (str
 	}
 
 	/*
-	 *	Early DM9100's need software CRC and the DMFE driver
+	 *	DM910x chips should be handled by the dmfe driver, except
+	 *	on-board chips on SPARC systems.  Also, early DM9100s need
+	 *	software CRC which only the dmfe driver supports.
 	 */
 
-	if (pdev->vendor == 0x1282 && pdev->device == 0x9100)
-	{
-		/* Read Chip revision */
-		if (pdev->revision < 0x30)
-		{
-			printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
+#ifdef CONFIG_TULIP_DM910X
+	if (chip_idx == DM910X) {
+		struct device_node *dp;
+
+		if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
+		    pdev->revision < 0x30) {
+			printk(KERN_INFO PFX
+			       "skipping early DM9100 with Crc bug (use dmfe)\n");
+			return -ENODEV;
+		}
+
+		dp = pci_device_to_OF_node(pdev);
+		if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
+			printk(KERN_INFO PFX
+			       "skipping DM910x expansion card (use dmfe)\n");
 			return -ENODEV;
 		}
 	}
+#endif
 
 	/*
 	 *	Looks for early PCI chipsets where people report hangs
@@ -1538,8 +1557,10 @@ static int __devinit tulip_init_one (str
 		}
 	}
 	/* Lite-On boards have the address byte-swapped. */
-	if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0 || dev->dev_addr[0] == 0x02)
-		&&  dev->dev_addr[1] == 0x00)
+	if ((dev->dev_addr[0] == 0xA0 ||
+	     dev->dev_addr[0] == 0xC0 ||
+	     dev->dev_addr[0] == 0x02) &&
+	    dev->dev_addr[1] == 0x00)
 		for (i = 0; i < 6; i+=2) {
 			char tmp = dev->dev_addr[i];
 			dev->dev_addr[i] = dev->dev_addr[i+1];
@@ -1782,7 +1803,7 @@ static int tulip_resume(struct pci_dev *
 		return retval;
 	}
 
-	if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
+	if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
 		printk (KERN_ERR "tulip: request_irq failed in resume\n");
 		return retval;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/uli526x.c linux-libre-2.6.33-gnu1/drivers/net/tulip/uli526x.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/uli526x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/uli526x.c	2010-02-24 13:52:17.000000000 -0500
@@ -461,7 +461,7 @@ static int uli526x_open(struct net_devic
 	/* Initialize ULI526X board */
 	uli526x_init(dev);
 
-	ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev);
+	ret = request_irq(dev->irq, uli526x_interrupt, IRQF_SHARED, dev->name, dev);
 	if (ret)
 		return ret;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/winbond-840.c linux-libre-2.6.33-gnu1/drivers/net/tulip/winbond-840.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/winbond-840.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/winbond-840.c	2010-02-24 13:52:17.000000000 -0500
@@ -639,7 +639,7 @@ static int netdev_open(struct net_device
 	iowrite32(0x00000001, ioaddr + PCIBusCfg);		/* Reset */
 
 	netif_device_detach(dev);
-	i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev);
+	i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
 	if (i)
 		goto out_err;
 
@@ -1230,8 +1230,8 @@ static int netdev_rx(struct net_device *
 #endif
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
 							    np->rx_skbuff[entry]->len,
@@ -1357,8 +1357,8 @@ static u32 __set_rx_mode(struct net_devi
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = RxAcceptBroadcast | AcceptMulticast | RxAcceptAllPhys
 			| AcceptMyPhys;
-	} else if ((dev->mc_count > multicast_filter_limit)
-			   ||  (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		memset(mc_filter, 0xff, sizeof(mc_filter));
 		rx_mode = RxAcceptBroadcast | AcceptMulticast | AcceptMyPhys;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tulip/xircom_cb.c linux-libre-2.6.33-gnu1/drivers/net/tulip/xircom_cb.c
--- linux-libre-2.6.32-gnu1/drivers/net/tulip/xircom_cb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tulip/xircom_cb.c	2010-02-24 13:52:17.000000000 -0500
@@ -458,7 +458,7 @@ static int xircom_open(struct net_device
 	int retval;
 	enter("xircom_open");
 	printk(KERN_INFO "xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq);
-	retval = request_irq(dev->irq, &xircom_interrupt, IRQF_SHARED, dev->name, dev);
+	retval = request_irq(dev->irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
 	if (retval) {
 		leave("xircom_open - No IRQ");
 		return retval;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/tun.c linux-libre-2.6.33-gnu1/drivers/net/tun.c
--- linux-libre-2.6.32-gnu1/drivers/net/tun.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/tun.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -54,6 +53,7 @@
 #include <linux/miscdevice.h>
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
+#include <linux/compat.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
@@ -849,13 +849,13 @@ static void tun_sock_write_space(struct
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 		wake_up_interruptible_sync(sk->sk_sleep);
 
-	tun = container_of(sk, struct tun_sock, sk)->tun;
+	tun = tun_sk(sk)->tun;
 	kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
 }
 
 static void tun_sock_destruct(struct sock *sk)
 {
-	free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev);
+	free_netdev(tun_sk(sk)->tun->dev);
 }
 
 static struct proto tun_proto = {
@@ -990,7 +990,7 @@ static int tun_set_iff(struct net *net,
 		sk->sk_write_space = tun_sock_write_space;
 		sk->sk_sndbuf = INT_MAX;
 
-		container_of(sk, struct tun_sock, sk)->tun = tun;
+		tun_sk(sk)->tun = tun;
 
 		security_tun_dev_post_create(sk);
 
@@ -1110,8 +1110,8 @@ static int set_offload(struct net_device
 	return 0;
 }
 
-static long tun_chr_ioctl(struct file *file, unsigned int cmd,
-			  unsigned long arg)
+static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+			    unsigned long arg, int ifreq_len)
 {
 	struct tun_file *tfile = file->private_data;
 	struct tun_struct *tun;
@@ -1121,7 +1121,7 @@ static long tun_chr_ioctl(struct file *f
 	int ret;
 
 	if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
-		if (copy_from_user(&ifr, argp, sizeof ifr))
+		if (copy_from_user(&ifr, argp, ifreq_len))
 			return -EFAULT;
 
 	if (cmd == TUNGETFEATURES) {
@@ -1144,7 +1144,7 @@ static long tun_chr_ioctl(struct file *f
 		if (ret)
 			goto unlock;
 
-		if (copy_to_user(argp, &ifr, sizeof(ifr)))
+		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
 		goto unlock;
 	}
@@ -1162,7 +1162,7 @@ static long tun_chr_ioctl(struct file *f
 		if (ret)
 			break;
 
-		if (copy_to_user(argp, &ifr, sizeof(ifr)))
+		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
 		break;
 
@@ -1236,7 +1236,7 @@ static long tun_chr_ioctl(struct file *f
 		/* Get hw addres */
 		memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
 		ifr.ifr_hwaddr.sa_family = tun->dev->type;
-		if (copy_to_user(argp, &ifr, sizeof ifr))
+		if (copy_to_user(argp, &ifr, ifreq_len))
 			ret = -EFAULT;
 		break;
 
@@ -1275,6 +1275,41 @@ unlock:
 	return ret;
 }
 
+static long tun_chr_ioctl(struct file *file,
+			  unsigned int cmd, unsigned long arg)
+{
+	return __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq));
+}
+
+#ifdef CONFIG_COMPAT
+static long tun_chr_compat_ioctl(struct file *file,
+			 unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case TUNSETIFF:
+	case TUNGETIFF:
+	case TUNSETTXFILTER:
+	case TUNGETSNDBUF:
+	case TUNSETSNDBUF:
+	case SIOCGIFHWADDR:
+	case SIOCSIFHWADDR:
+		arg = (unsigned long)compat_ptr(arg);
+		break;
+	default:
+		arg = (compat_ulong_t)arg;
+		break;
+	}
+
+	/*
+	 * compat_ifreq is shorter than ifreq, so we must not access beyond
+	 * the end of that structure. All fields that are used in this
+	 * driver are compatible though, we don't need to convert the
+	 * contents.
+	 */
+	return __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq));
+}
+#endif /* CONFIG_COMPAT */
+
 static int tun_chr_fasync(int fd, struct file *file, int on)
 {
 	struct tun_struct *tun = tun_get(file);
@@ -1285,7 +1320,6 @@ static int tun_chr_fasync(int fd, struct
 
 	DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
 
-	lock_kernel();
 	if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
 		goto out;
 
@@ -1298,7 +1332,6 @@ static int tun_chr_fasync(int fd, struct
 		tun->flags &= ~TUN_FASYNC;
 	ret = 0;
 out:
-	unlock_kernel();
 	tun_put(tun);
 	return ret;
 }
@@ -1306,7 +1339,7 @@ out:
 static int tun_chr_open(struct inode *inode, struct file * file)
 {
 	struct tun_file *tfile;
-	cycle_kernel_lock();
+
 	DBG1(KERN_INFO "tunX: tun_chr_open\n");
 
 	tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
@@ -1359,7 +1392,10 @@ static const struct file_operations tun_
 	.write = do_sync_write,
 	.aio_write = tun_chr_aio_write,
 	.poll	= tun_chr_poll,
-	.unlocked_ioctl = tun_chr_ioctl,
+	.unlocked_ioctl	= tun_chr_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = tun_chr_compat_ioctl,
+#endif
 	.open	= tun_chr_open,
 	.release = tun_chr_close,
 	.fasync = tun_chr_fasync
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/typhoon.c linux-libre-2.6.33-gnu1/drivers/net/typhoon.c
--- linux-libre-2.6.32-gnu1/drivers/net/typhoon.c	2013-05-03 14:01:24.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/typhoon.c	2013-05-03 12:08:45.000000000 -0400
@@ -1769,8 +1769,8 @@ typhoon_rx(struct typhoon *tp, struct ba
 		csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD |
 			TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD);
 		if(csum_bits ==
-		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD)
-		   || csum_bits ==
+		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD) ||
+		   csum_bits ==
 		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
 			new_skb->ip_summed = CHECKSUM_UNNECESSARY;
 		} else
@@ -2151,7 +2151,7 @@ typhoon_open(struct net_device *dev)
 		goto out_sleep;
 	}
 
-	err = request_irq(dev->irq, &typhoon_interrupt, IRQF_SHARED,
+	err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED,
 				dev->name, dev);
 	if(err < 0)
 		goto out_sleep;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ucc_geth.c linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.c
--- linux-libre-2.6.32-gnu1/drivers/net/ucc_geth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.c	2010-02-24 13:52:17.000000000 -0500
@@ -1306,8 +1306,8 @@ static int init_max_rx_buff_len(u16 max_
 				u16 __iomem *mrblr_register)
 {
 	/* max_rx_buf_len value must be a multiple of 128 */
-	if ((max_rx_buf_len == 0)
-	    || (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT))
+	if ((max_rx_buf_len == 0) ||
+	    (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT))
 		return -EINVAL;
 
 	out_be16(mrblr_register, max_rx_buf_len);
@@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth
 
 static void ugeth_quiesce(struct ucc_geth_private *ugeth)
 {
-	/* Wait for and prevent any further xmits. */
+	/* Prevent any further xmits, plus detach the device. */
+	netif_device_detach(ugeth->ndev);
+
+	/* Wait for any current xmits to finish. */
 	netif_tx_disable(ugeth->ndev);
 
 	/* Disable the interrupt to avoid NAPI rescheduling. */
@@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_ge
 {
 	napi_enable(&ugeth->napi);
 	enable_irq(ugeth->ug_info->uf_info.irq);
-	netif_tx_wake_all_queues(ugeth->ndev);
+	netif_device_attach(ugeth->ndev);
 }
 
 /* Called every time the controller might need to be made
@@ -1648,25 +1651,28 @@ static void adjust_link(struct net_devic
 			ugeth->oldspeed = phydev->speed;
 		}
 
-		/*
-		 * To change the MAC configuration we need to disable the
-		 * controller. To do so, we have to either grab ugeth->lock,
-		 * which is a bad idea since 'graceful stop' commands might
-		 * take quite a while, or we can quiesce driver's activity.
-		 */
-		ugeth_quiesce(ugeth);
-		ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
-
-		out_be32(&ug_regs->maccfg2, tempval);
-		out_be32(&uf_regs->upsmr, upsmr);
-
-		ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
-		ugeth_activate(ugeth);
-
 		if (!ugeth->oldlink) {
 			new_state = 1;
 			ugeth->oldlink = 1;
 		}
+
+		if (new_state) {
+			/*
+			 * To change the MAC configuration we need to disable
+			 * the controller. To do so, we have to either grab
+			 * ugeth->lock, which is a bad idea since 'graceful
+			 * stop' commands might take quite a while, or we can
+			 * quiesce driver's activity.
+			 */
+			ugeth_quiesce(ugeth);
+			ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
+			out_be32(&ug_regs->maccfg2, tempval);
+			out_be32(&uf_regs->upsmr, upsmr);
+
+			ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+			ugeth_activate(ugeth);
+		}
 	} else if (ugeth->oldlink) {
 			new_state = 1;
 			ugeth->oldlink = 0;
@@ -2159,8 +2165,8 @@ static int ucc_struct_init(struct ucc_ge
 	}
 
 	if ((ug_info->numStationAddresses !=
-	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1)
-	    && ug_info->rxExtendedFiltering) {
+	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1) &&
+	    ug_info->rxExtendedFiltering) {
 		if (netif_msg_probe(ugeth))
 			ugeth_err("%s: Number of station addresses greater than 1 "
 				  "not allowed in extended parsing mode.",
@@ -2284,9 +2290,9 @@ static int ucc_geth_startup(struct ucc_g
 	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1);
 
 	ugeth->rx_extended_features = ugeth->rx_non_dynamic_extended_features ||
-	    (ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP)
-	    || (ug_info->vlanOperationNonTagged !=
-		UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
+		(ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP) ||
+		(ug_info->vlanOperationNonTagged !=
+		 UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
 
 	init_default_reg_vals(&uf_regs->upsmr,
 			      &ug_regs->maccfg1, &ug_regs->maccfg2);
@@ -2987,11 +2993,11 @@ static int ucc_geth_startup(struct ucc_g
 	ugeth->p_init_enet_param_shadow->rgftgfrxglobal |=
 	    ugeth->rx_glbl_pram_offset | ug_info->riscRx;
 	if ((ug_info->largestexternallookupkeysize !=
-	     QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE)
-	    && (ug_info->largestexternallookupkeysize !=
-		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
-	    && (ug_info->largestexternallookupkeysize !=
-		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
+	     QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE) &&
+	    (ug_info->largestexternallookupkeysize !=
+	     QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES) &&
+	    (ug_info->largestexternallookupkeysize !=
+	     QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
 		if (netif_msg_ifup(ugeth))
 			ugeth_err("%s: Invalid largest External Lookup Key Size.",
 				  __func__);
@@ -3273,13 +3279,12 @@ static int ucc_geth_tx(struct net_device
 		/* Handle the transmitted buffer and release */
 		/* the BD to be used with the current frame  */
 
-		if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
+		skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
+		if (!skb)
 			break;
 
 		dev->stats.tx_packets++;
 
-		skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
-
 		if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
 			     skb_recycle_check(skb,
 				    ugeth->ug_info->uf_info.max_rx_buf_length +
@@ -3601,6 +3606,7 @@ static int ucc_geth_suspend(struct of_de
 	if (!netif_running(ndev))
 		return 0;
 
+	netif_device_detach(ndev);
 	napi_disable(&ugeth->napi);
 
 	/*
@@ -3659,7 +3665,7 @@ static int ucc_geth_resume(struct of_dev
 	phy_start(ugeth->phydev);
 
 	napi_enable(&ugeth->napi);
-	netif_start_queue(ndev);
+	netif_device_attach(ndev);
 
 	return 0;
 }
@@ -3798,7 +3804,7 @@ static int ucc_geth_probe(struct of_devi
 		prop = of_get_property(np, "tx-clock", NULL);
 		if (!prop) {
 			printk(KERN_ERR
-				"ucc_geth: mising tx-clock-name property\n");
+				"ucc_geth: missing tx-clock-name property\n");
 			return -EINVAL;
 		}
 		if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/ucc_geth.h linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.h
--- linux-libre-2.6.32-gnu1/drivers/net/ucc_geth.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/ucc_geth.h	2010-02-24 13:52:17.000000000 -0500
@@ -80,16 +80,16 @@ struct ucc_geth {
 				   frames) received that were between 128
 				   (Including FCS length==4) and 255 octets */
 	u32 txok;		/* Total number of octets residing in frames
-				   that where involved in succesfull
+				   that where involved in successfull
 				   transmission */
 	u16 txcf;		/* Total number of PAUSE control frames
 				   transmitted by this MAC */
 	u8 res4[0x2];
 	u32 tmca;		/* Total number of frames that were transmitted
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
 	u32 tbca;		/* Total number of frames transmitted
-				   succesfully that had destination address
+				   successfully that had destination address
 				   field equal to the broadcast address */
 	u32 rxfok;		/* Total number of frames received OK */
 	u32 rxbok;		/* Total number of octets received OK */
@@ -98,9 +98,9 @@ struct ucc_geth {
 				   HW because it includes octets in frames that
 				   never even reach the UCC */
 	u32 rmca;		/* Total number of frames that were received
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
-	u32 rbca;		/* Total number of frames received succesfully
+	u32 rbca;		/* Total number of frames received successfully
 				   that had destination address equal to the
 				   broadcast address */
 	u32 scar;		/* Statistics carry register */
@@ -759,15 +759,15 @@ struct ucc_geth_hardware_statistics {
 				   frames) received that were between 128
 				   (Including FCS length==4) and 255 octets */
 	u32 txok;		/* Total number of octets residing in frames
-				   that where involved in succesfull
+				   that where involved in successfull
 				   transmission */
 	u16 txcf;		/* Total number of PAUSE control frames
 				   transmitted by this MAC */
 	u32 tmca;		/* Total number of frames that were transmitted
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
 	u32 tbca;		/* Total number of frames transmitted
-				   succesfully that had destination address
+				   successfully that had destination address
 				   field equal to the broadcast address */
 	u32 rxfok;		/* Total number of frames received OK */
 	u32 rxbok;		/* Total number of octets received OK */
@@ -776,9 +776,9 @@ struct ucc_geth_hardware_statistics {
 				   HW because it includes octets in frames that
 				   never even reach the UCC */
 	u32 rmca;		/* Total number of frames that were received
-				   succesfully with the group address bit set
+				   successfully with the group address bit set
 				   that are not broadcast frames */
-	u32 rbca;		/* Total number of frames received succesfully
+	u32 rbca;		/* Total number of frames received successfully
 				   that had destination address equal to the
 				   broadcast address */
 } __attribute__ ((packed));
@@ -838,13 +838,13 @@ struct ucc_geth_hardware_statistics {
 							   using the maximum is
 							   easier */
 #define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT	32
-#define UCC_GETH_SCHEDULER_ALIGNMENT		4	/* This is a guess */
+#define UCC_GETH_SCHEDULER_ALIGNMENT		8	/* This is a guess */
 #define UCC_GETH_TX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_RX_STATISTICS_ALIGNMENT	4	/* This is a guess */
 #define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT	64
 #define UCC_GETH_RX_BD_QUEUES_ALIGNMENT		8	/* This is a guess */
 #define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT	128	/* This is a guess */
-#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4	/* This
+#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 8	/* This
 									   is a
 									   guess
 									 */
@@ -899,16 +899,17 @@ struct ucc_geth_hardware_statistics {
 #define UCC_GETH_UTFS_INIT                      512	/* Tx virtual FIFO size
 							 */
 #define UCC_GETH_UTFET_INIT                     256	/* 1/2 utfs */
-#define UCC_GETH_UTFTT_INIT                     128
+#define UCC_GETH_UTFTT_INIT                     512
 /* Gigabit Ethernet (1000 Mbps) */
 #define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/	/* Rx virtual
 								   FIFO size */
 #define UCC_GETH_URFET_GIGA_INIT                2048/*1024*/	/* 1/2 urfs */
 #define UCC_GETH_URFSET_GIGA_INIT               3072/*1536*/	/* 3/4 urfs */
-#define UCC_GETH_UTFS_GIGA_INIT                 8192/*2048*/	/* Tx virtual
+#define UCC_GETH_UTFS_GIGA_INIT                 4096/*2048*/	/* Tx virtual
+								   FIFO size */
+#define UCC_GETH_UTFET_GIGA_INIT                2048/*1024*/	/* 1/2 utfs */
+#define UCC_GETH_UTFTT_GIGA_INIT                4096/*0x40*/	/* Tx virtual
 								   FIFO size */
-#define UCC_GETH_UTFET_GIGA_INIT                4096/*1024*/	/* 1/2 utfs */
-#define UCC_GETH_UTFTT_GIGA_INIT                0x400/*0x40*/	/* */
 
 #define UCC_GETH_REMODER_INIT                   0	/* bits that must be
 							   set */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/asix.c linux-libre-2.6.33-gnu1/drivers/net/usb/asix.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/asix.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/asix.c	2010-02-24 13:52:17.000000000 -0500
@@ -365,8 +365,8 @@ static struct sk_buff *asix_tx_fixup(str
 
 	padlen = ((skb->len + 4) % 512) ? 0 : 4;
 
-	if ((!skb_cloned(skb))
-	    && ((headroom + tailroom) >= (4 + padlen))) {
+	if ((!skb_cloned(skb)) &&
+	    ((headroom + tailroom) >= (4 + padlen))) {
 		if ((headroom < 4) || (tailroom < padlen)) {
 			skb->data = memmove(skb->head + 4, skb->data, skb->len);
 			skb_set_tail_pointer(skb, skb->len);
@@ -541,8 +541,8 @@ static void asix_set_multicast(struct ne
 
 	if (net->flags & IFF_PROMISC) {
 		rx_ctl |= AX_RX_CTL_PRO;
-	} else if (net->flags & IFF_ALLMULTI
-		   || net->mc_count > AX_MAX_MCAST) {
+	} else if (net->flags & IFF_ALLMULTI ||
+		   net->mc_count > AX_MAX_MCAST) {
 		rx_ctl |= AX_RX_CTL_AMALL;
 	} else if (net->mc_count == 0) {
 		/* just broadcast and directed */
@@ -753,8 +753,8 @@ static void ax88172_set_multicast(struct
 
 	if (net->flags & IFF_PROMISC) {
 		rx_ctl |= 0x01;
-	} else if (net->flags & IFF_ALLMULTI
-		   || net->mc_count > AX_MAX_MCAST) {
+	} else if (net->flags & IFF_ALLMULTI ||
+		   net->mc_count > AX_MAX_MCAST) {
 		rx_ctl |= 0x02;
 	} else if (net->mc_count == 0) {
 		/* just broadcast and directed */
@@ -1327,7 +1327,7 @@ static const struct driver_info ax8817x_
 	.status = asix_status,
 	.link_reset = ax88172_link_reset,
 	.reset = ax88172_link_reset,
-	.flags =  FLAG_ETHER,
+	.flags =  FLAG_ETHER | FLAG_LINK_INTR,
 	.data = 0x00130103,
 };
 
@@ -1337,7 +1337,7 @@ static const struct driver_info dlink_du
 	.status = asix_status,
 	.link_reset = ax88172_link_reset,
 	.reset = ax88172_link_reset,
-	.flags =  FLAG_ETHER,
+	.flags =  FLAG_ETHER | FLAG_LINK_INTR,
 	.data = 0x009f9d9f,
 };
 
@@ -1347,7 +1347,7 @@ static const struct driver_info netgear_
 	.status = asix_status,
 	.link_reset = ax88172_link_reset,
 	.reset = ax88172_link_reset,
-	.flags =  FLAG_ETHER,
+	.flags =  FLAG_ETHER | FLAG_LINK_INTR,
 	.data = 0x00130103,
 };
 
@@ -1357,7 +1357,7 @@ static const struct driver_info hawking_
 	.status = asix_status,
 	.link_reset = ax88172_link_reset,
 	.reset = ax88172_link_reset,
-	.flags =  FLAG_ETHER,
+	.flags =  FLAG_ETHER | FLAG_LINK_INTR,
 	.data = 0x001f1d1f,
 };
 
@@ -1367,7 +1367,7 @@ static const struct driver_info ax88772_
 	.status = asix_status,
 	.link_reset = ax88772_link_reset,
 	.reset = ax88772_link_reset,
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
 	.rx_fixup = asix_rx_fixup,
 	.tx_fixup = asix_tx_fixup,
 };
@@ -1378,7 +1378,7 @@ static const struct driver_info ax88178_
 	.status = asix_status,
 	.link_reset = ax88178_link_reset,
 	.reset = ax88178_link_reset,
-	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR,
 	.rx_fixup = asix_rx_fixup,
 	.tx_fixup = asix_tx_fixup,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/catc.c linux-libre-2.6.33-gnu1/drivers/net/usb/catc.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/catc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/catc.c	2010-02-24 13:52:17.000000000 -0500
@@ -436,8 +436,8 @@ static netdev_tx_t catc_start_xmit(struc
 			clear_bit(TX_RUNNING, &catc->flags);
 	}
 
-	if ((catc->is_f5u011 && catc->tx_ptr)
-	     || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
+	if ((catc->is_f5u011 && catc->tx_ptr) ||
+	    (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
 		netif_stop_queue(netdev);
 
 	spin_unlock_irqrestore(&catc->tx_lock, flags);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/cdc_eem.c linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_eem.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/cdc_eem.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_eem.c	2010-02-24 13:52:17.000000000 -0500
@@ -121,8 +121,8 @@ static struct sk_buff *eem_tx_fixup(stru
 		int	headroom = skb_headroom(skb);
 		int	tailroom = skb_tailroom(skb);
 
-		if ((tailroom >= ETH_FCS_LEN + padlen)
-				&& (headroom >= EEM_HEAD))
+		if ((tailroom >= ETH_FCS_LEN + padlen) &&
+		    (headroom >= EEM_HEAD))
 			goto done;
 
 		if ((headroom + tailroom)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/cdc_ether.c linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_ether.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/cdc_ether.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/cdc_ether.c	2010-02-24 13:52:17.000000000 -0500
@@ -37,23 +37,23 @@
 
 static int is_rndis(struct usb_interface_descriptor *desc)
 {
-	return desc->bInterfaceClass == USB_CLASS_COMM
-		&& desc->bInterfaceSubClass == 2
-		&& desc->bInterfaceProtocol == 0xff;
+	return (desc->bInterfaceClass == USB_CLASS_COMM &&
+		desc->bInterfaceSubClass == 2 &&
+		desc->bInterfaceProtocol == 0xff);
 }
 
 static int is_activesync(struct usb_interface_descriptor *desc)
 {
-	return desc->bInterfaceClass == USB_CLASS_MISC
-		&& desc->bInterfaceSubClass == 1
-		&& desc->bInterfaceProtocol == 1;
+	return (desc->bInterfaceClass == USB_CLASS_MISC &&
+		desc->bInterfaceSubClass == 1 &&
+		desc->bInterfaceProtocol == 1);
 }
 
 static int is_wireless_rndis(struct usb_interface_descriptor *desc)
 {
-	return desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER
-		&& desc->bInterfaceSubClass == 1
-		&& desc->bInterfaceProtocol == 3;
+	return (desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER &&
+		desc->bInterfaceSubClass == 1 &&
+		desc->bInterfaceProtocol == 3);
 }
 
 #else
@@ -116,9 +116,9 @@ int usbnet_generic_cdc_bind(struct usbne
 	/* this assumes that if there's a non-RNDIS vendor variant
 	 * of cdc-acm, it'll fail RNDIS requests cleanly.
 	 */
-	rndis = is_rndis(&intf->cur_altsetting->desc)
-		|| is_activesync(&intf->cur_altsetting->desc)
-		|| is_wireless_rndis(&intf->cur_altsetting->desc);
+	rndis = (is_rndis(&intf->cur_altsetting->desc) ||
+		 is_activesync(&intf->cur_altsetting->desc) ||
+		 is_wireless_rndis(&intf->cur_altsetting->desc));
 
 	memset(info, 0, sizeof *info);
 	info->control = intf;
@@ -279,10 +279,10 @@ next_desc:
 
 		dev->status = &info->control->cur_altsetting->endpoint [0];
 		desc = &dev->status->desc;
-		if (!usb_endpoint_is_int_in(desc)
-				|| (le16_to_cpu(desc->wMaxPacketSize)
-					< sizeof(struct usb_cdc_notification))
-				|| !desc->bInterval) {
+		if (!usb_endpoint_is_int_in(desc) ||
+		    (le16_to_cpu(desc->wMaxPacketSize)
+		     < sizeof(struct usb_cdc_notification)) ||
+		    !desc->bInterval) {
 			dev_dbg(&intf->dev, "bad notification endpoint\n");
 			dev->status = NULL;
 		}
@@ -411,6 +411,12 @@ static int cdc_bind(struct usbnet *dev,
 	return 0;
 }
 
+static int cdc_manage_power(struct usbnet *dev, int on)
+{
+	dev->intf->needs_remote_wakeup = on;
+	return 0;
+}
+
 static const struct driver_info	cdc_info = {
 	.description =	"CDC Ethernet Device",
 	.flags =	FLAG_ETHER,
@@ -418,6 +424,15 @@ static const struct driver_info	cdc_info
 	.bind =		cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
 	.status =	cdc_status,
+	.manage_power =	cdc_manage_power,
+};
+
+static const struct driver_info mbm_info = {
+	.description =	"Mobile Broadband Network Device",
+	.flags =	FLAG_WWAN,
+	.bind = 	cdc_bind,
+	.unbind =	usbnet_cdc_unbind,
+	.status =	cdc_status,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -532,72 +547,77 @@ static const struct usb_device_id	produc
 	/* Ericsson F3507g */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3507g ver. 2 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3607gw */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3607gw ver 2 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3607gw ver 3 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3307 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson F3307 ver 2 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Ericsson C3607w */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
+}, {
+	/* Ericsson C3607w ver 2 */
+	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Toshiba F3507g */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Toshiba F3607gw */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Toshiba F3607gw ver 2 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Dell F3507g */
 	USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Dell F3607gw */
 	USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 	/* Dell F3607gw ver 2 */
 	USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &cdc_info,
+	.driver_info = (unsigned long) &mbm_info,
 },
 	{ },		// END
 };
@@ -610,6 +630,8 @@ static struct usb_driver cdc_driver = {
 	.disconnect =	usbnet_disconnect,
 	.suspend =	usbnet_suspend,
 	.resume =	usbnet_resume,
+	.reset_resume =	usbnet_resume,
+	.supports_autosuspend = 1,
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/cdc-phonet.c linux-libre-2.6.33-gnu1/drivers/net/usb/cdc-phonet.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/cdc-phonet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/cdc-phonet.c	2010-02-24 13:52:17.000000000 -0500
@@ -372,12 +372,12 @@ int usbpn_probe(struct usb_interface *in
 	/* Data interface has one inactive and one active setting */
 	if (data_intf->num_altsetting != 2)
 		return -EINVAL;
-	if (data_intf->altsetting[0].desc.bNumEndpoints == 0
-	 && data_intf->altsetting[1].desc.bNumEndpoints == 2)
+	if (data_intf->altsetting[0].desc.bNumEndpoints == 0 &&
+	    data_intf->altsetting[1].desc.bNumEndpoints == 2)
 		data_desc = data_intf->altsetting + 1;
 	else
-	if (data_intf->altsetting[0].desc.bNumEndpoints == 2
-	 && data_intf->altsetting[1].desc.bNumEndpoints == 0)
+	if (data_intf->altsetting[0].desc.bNumEndpoints == 2 &&
+	    data_intf->altsetting[1].desc.bNumEndpoints == 0)
 		data_desc = data_intf->altsetting;
 	else
 		return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/dm9601.c linux-libre-2.6.33-gnu1/drivers/net/usb/dm9601.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/dm9601.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/dm9601.c	2010-02-24 13:52:17.000000000 -0500
@@ -611,7 +611,7 @@ static int dm9601_link_reset(struct usbn
 
 static const struct driver_info dm9601_info = {
 	.description	= "Davicom DM9601 USB Ethernet",
-	.flags		= FLAG_ETHER,
+	.flags		= FLAG_ETHER | FLAG_LINK_INTR,
 	.bind		= dm9601_bind,
 	.rx_fixup	= dm9601_rx_fixup,
 	.tx_fixup	= dm9601_tx_fixup,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/hso.c linux-libre-2.6.33-gnu1/drivers/net/usb/hso.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/hso.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/hso.c	2010-02-24 13:52:17.000000000 -0500
@@ -286,6 +286,7 @@ struct hso_device {
 	u8 usb_gone;
 	struct work_struct async_get_intf;
 	struct work_struct async_put_intf;
+	struct work_struct reset_device;
 
 	struct usb_device *usb;
 	struct usb_interface *interface;
@@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso
 /* Helper functions */
 static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
 				   struct usb_device *usb, gfp_t gfp);
-static void log_usb_status(int status, const char *function);
+static void handle_usb_error(int status, const char *function,
+			     struct hso_device *hso_dev);
 static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
 						  int type, int dir);
 static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
@@ -350,6 +352,7 @@ static void async_put_intf(struct work_s
 static int hso_put_activity(struct hso_device *hso_dev);
 static int hso_get_activity(struct hso_device *hso_dev);
 static void tiocmget_intr_callback(struct urb *urb);
+static void reset_device(struct work_struct *data);
 /*****************************************************************************/
 /* Helping functions                                                         */
 /*****************************************************************************/
@@ -461,10 +464,17 @@ static const struct usb_device_id hso_id
 	{USB_DEVICE(0x0af0, 0x7501)},		/* GTM 382 */
 	{USB_DEVICE(0x0af0, 0x7601)},		/* GE40x */
 	{USB_DEVICE(0x0af0, 0x7701)},
+	{USB_DEVICE(0x0af0, 0x7706)},
 	{USB_DEVICE(0x0af0, 0x7801)},
 	{USB_DEVICE(0x0af0, 0x7901)},
+	{USB_DEVICE(0x0af0, 0x7A01)},
+	{USB_DEVICE(0x0af0, 0x7A05)},
 	{USB_DEVICE(0x0af0, 0x8200)},
 	{USB_DEVICE(0x0af0, 0x8201)},
+	{USB_DEVICE(0x0af0, 0x8300)},
+	{USB_DEVICE(0x0af0, 0x8302)},
+	{USB_DEVICE(0x0af0, 0x8304)},
+	{USB_DEVICE(0x0af0, 0x8400)},
 	{USB_DEVICE(0x0af0, 0xd035)},
 	{USB_DEVICE(0x0af0, 0xd055)},
 	{USB_DEVICE(0x0af0, 0xd155)},
@@ -473,6 +483,8 @@ static const struct usb_device_id hso_id
 	{USB_DEVICE(0x0af0, 0xd157)},
 	{USB_DEVICE(0x0af0, 0xd257)},
 	{USB_DEVICE(0x0af0, 0xd357)},
+	{USB_DEVICE(0x0af0, 0xd058)},
+	{USB_DEVICE(0x0af0, 0xc100)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, hso_ids);
@@ -602,9 +614,9 @@ static struct hso_serial *get_serial_by_
 	port = hso_mux_to_port(mux);
 
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
-		if (serial_table[i]
-		    && (dev2ser(serial_table[i])->shared_int == shared_int)
-		    && ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) {
+		if (serial_table[i] &&
+		    (dev2ser(serial_table[i])->shared_int == shared_int) &&
+		    ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) {
 			return dev2ser(serial_table[i]);
 		}
 	}
@@ -655,8 +667,8 @@ static void set_serial_by_index(unsigned
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 }
 
-/* log a meaningful explanation of an USB status */
-static void log_usb_status(int status, const char *function)
+static void handle_usb_error(int status, const char *function,
+			     struct hso_device *hso_dev)
 {
 	char *explanation;
 
@@ -685,10 +697,20 @@ static void log_usb_status(int status, c
 	case -EMSGSIZE:
 		explanation = "internal error";
 		break;
+	case -EILSEQ:
+	case -EPROTO:
+	case -ETIME:
+	case -ETIMEDOUT:
+		explanation = "protocol error";
+		if (hso_dev)
+			schedule_work(&hso_dev->reset_device);
+		break;
 	default:
 		explanation = "unknown status";
 		break;
 	}
+
+	/* log a meaningful explanation of an USB status */
 	D1("%s: received USB status - %s (%d)", function, explanation, status);
 }
 
@@ -762,7 +784,7 @@ static void write_bulk_callback(struct u
 	/* log status, but don't act on it, we don't need to resubmit anything
 	 * anyhow */
 	if (status)
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, odev->parent);
 
 	hso_put_activity(odev->parent);
 
@@ -806,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(st
 	result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
 	if (result) {
 		dev_warn(&odev->parent->interface->dev,
-			"failed mux_bulk_tx_urb %d", result);
+			"failed mux_bulk_tx_urb %d\n", result);
 		net->stats.tx_errors++;
 		netif_start_queue(net);
 	} else {
@@ -846,8 +868,8 @@ static void hso_net_tx_timeout(struct ne
 	dev_warn(&net->dev, "Tx timed out.\n");
 
 	/* Tear the waiting frame off the list */
-	if (odev->mux_bulk_tx_urb
-	    && (odev->mux_bulk_tx_urb->status == -EINPROGRESS))
+	if (odev->mux_bulk_tx_urb &&
+	    (odev->mux_bulk_tx_urb->status == -EINPROGRESS))
 		usb_unlink_urb(odev->mux_bulk_tx_urb);
 
 	/* Update statistics */
@@ -998,7 +1020,7 @@ static void read_bulk_callback(struct ur
 
 	/* is al ok?  (Filip: Who's Al ?) */
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, odev->parent);
 		return;
 	}
 
@@ -1019,10 +1041,11 @@ static void read_bulk_callback(struct ur
 	if (odev->parent->port_spec & HSO_INFO_CRC_BUG) {
 		u32 rest;
 		u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
-		rest = urb->actual_length % odev->in_endp->wMaxPacketSize;
-		if (((rest == 5) || (rest == 6))
-		    && !memcmp(((u8 *) urb->transfer_buffer) +
-			       urb->actual_length - 4, crc_check, 4)) {
+		rest = urb->actual_length %
+			le16_to_cpu(odev->in_endp->wMaxPacketSize);
+		if (((rest == 5) || (rest == 6)) &&
+		    !memcmp(((u8 *) urb->transfer_buffer) +
+			    urb->actual_length - 4, crc_check, 4)) {
 			urb->actual_length -= 4;
 		}
 	}
@@ -1053,7 +1076,7 @@ static void read_bulk_callback(struct ur
 	result = usb_submit_urb(urb, GFP_ATOMIC);
 	if (result)
 		dev_warn(&odev->parent->interface->dev,
-			 "%s failed submit mux_bulk_rx_urb %d", __func__,
+			 "%s failed submit mux_bulk_rx_urb %d\n", __func__,
 			 result);
 }
 
@@ -1207,7 +1230,7 @@ static void hso_std_serial_read_bulk_cal
 		D1("serial == NULL");
 		return;
 	} else if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		return;
 	}
 
@@ -1225,10 +1248,10 @@ static void hso_std_serial_read_bulk_cal
 			u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
 			rest =
 			    urb->actual_length %
-			    serial->in_endp->wMaxPacketSize;
-			if (((rest == 5) || (rest == 6))
-			    && !memcmp(((u8 *) urb->transfer_buffer) +
-				       urb->actual_length - 4, crc_check, 4)) {
+			    le16_to_cpu(serial->in_endp->wMaxPacketSize);
+			if (((rest == 5) || (rest == 6)) &&
+			    !memcmp(((u8 *) urb->transfer_buffer) +
+				    urb->actual_length - 4, crc_check, 4)) {
 				urb->actual_length -= 4;
 			}
 		}
@@ -1513,7 +1536,7 @@ static void tiocmget_intr_callback(struc
 	if (!serial)
 		return;
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		return;
 	}
 	tiocmget = serial->tiocmget;
@@ -1700,6 +1723,10 @@ static int hso_serial_tiocmset(struct tt
 		D1("no tty structures");
 		return -EINVAL;
 	}
+
+	if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM)
+		return -EINVAL;
+
 	if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
 
 	spin_lock_irqsave(&serial->serial_lock, flags);
@@ -1838,7 +1865,7 @@ static int mux_device_request(struct hso
 	result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
 	if (result) {
 		dev_err(&ctrl_urb->dev->dev,
-			"%s failed submit ctrl_urb %d type %d", __func__,
+			"%s failed submit ctrl_urb %d type %d\n", __func__,
 			result, type);
 		return result;
 	}
@@ -1888,7 +1915,7 @@ static void intr_callback(struct urb *ur
 
 	/* status check */
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, NULL);
 		return;
 	}
 	D4("\n--- Got intr callback 0x%02X ---", status);
@@ -1905,18 +1932,18 @@ static void intr_callback(struct urb *ur
 			if (serial != NULL) {
 				D1("Pending read interrupt on port %d\n", i);
 				spin_lock(&serial->serial_lock);
-				if (serial->rx_state == RX_IDLE) {
+				if (serial->rx_state == RX_IDLE &&
+					serial->open_count > 0) {
 					/* Setup and send a ctrl req read on
 					 * port i */
-				if (!serial->rx_urb_filled[0]) {
+					if (!serial->rx_urb_filled[0]) {
 						serial->rx_state = RX_SENT;
 						hso_mux_serial_read(serial);
 					} else
 						serial->rx_state = RX_PENDING;
-
 				} else {
-					D1("Already pending a read on "
-					   "port %d\n", i);
+					D1("Already a read pending on "
+					   "port %d or port not open\n", i);
 				}
 				spin_unlock(&serial->serial_lock);
 			}
@@ -1958,7 +1985,7 @@ static void hso_std_serial_write_bulk_ca
 	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		tty_kref_put(tty);
 		return;
 	}
@@ -2014,7 +2041,7 @@ static void ctrl_callback(struct urb *ur
 	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
-		log_usb_status(status, __func__);
+		handle_usb_error(status, __func__, serial->parent);
 		tty_kref_put(tty);
 		return;
 	}
@@ -2358,12 +2385,12 @@ static int hso_serial_common_create(stru
 	serial->tx_data_length = tx_size;
 	serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	if (!serial->tx_data) {
-		dev_err(dev, "%s - Out of memory", __func__);
+		dev_err(dev, "%s - Out of memory\n", __func__);
 		goto exit;
 	}
 	serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
 	if (!serial->tx_buffer) {
-		dev_err(dev, "%s - Out of memory", __func__);
+		dev_err(dev, "%s - Out of memory\n", __func__);
 		goto exit;
 	}
 
@@ -2391,6 +2418,7 @@ static struct hso_device *hso_create_dev
 
 	INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
 	INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
+	INIT_WORK(&hso_dev->reset_device, reset_device);
 
 	return hso_dev;
 }
@@ -2831,13 +2859,14 @@ struct hso_shared_int *hso_create_shared
 
 	mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!mux->shared_intr_urb) {
-		dev_err(&interface->dev, "Could not allocate intr urb?");
+		dev_err(&interface->dev, "Could not allocate intr urb?\n");
 		goto exit;
 	}
-	mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize,
-				       GFP_KERNEL);
+	mux->shared_intr_buf =
+		kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize),
+			GFP_KERNEL);
 	if (!mux->shared_intr_buf) {
-		dev_err(&interface->dev, "Could not allocate intr buf?");
+		dev_err(&interface->dev, "Could not allocate intr buf?\n");
 		goto exit;
 	}
 
@@ -2982,8 +3011,8 @@ static int hso_probe(struct usb_interfac
 
 	case HSO_INTF_BULK:
 		/* It's a regular bulk interface */
-		if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK)
-		    && !disable_net)
+		if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) &&
+		    !disable_net)
 			hso_dev = hso_create_net_device(interface, port_spec);
 		else
 			hso_dev =
@@ -3132,6 +3161,26 @@ out:
 	return result;
 }
 
+static void reset_device(struct work_struct *data)
+{
+	struct hso_device *hso_dev =
+	    container_of(data, struct hso_device, reset_device);
+	struct usb_device *usb = hso_dev->usb;
+	int result;
+
+	if (hso_dev->usb_gone) {
+		D1("No reset during disconnect\n");
+	} else {
+		result = usb_lock_device_for_reset(usb, hso_dev->interface);
+		if (result < 0)
+			D1("unable to lock device for reset: %d\n", result);
+		else {
+			usb_reset_device(usb);
+			usb_unlock_device(usb);
+		}
+	}
+}
+
 static void hso_serial_ref_free(struct kref *ref)
 {
 	struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
@@ -3146,8 +3195,8 @@ static void hso_free_interface(struct us
 	int i;
 
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
-		if (serial_table[i]
-		    && (serial_table[i]->interface == interface)) {
+		if (serial_table[i] &&
+		    (serial_table[i]->interface == interface)) {
 			hso_dev = dev2ser(serial_table[i]);
 			spin_lock_irq(&hso_dev->serial_lock);
 			tty = tty_kref_get(hso_dev->tty);
@@ -3163,8 +3212,8 @@ static void hso_free_interface(struct us
 	}
 
 	for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
-		if (network_table[i]
-		    && (network_table[i]->interface == interface)) {
+		if (network_table[i] &&
+		    (network_table[i]->interface == interface)) {
 			struct rfkill *rfk = dev2net(network_table[i])->rfkill;
 			/* hso_stop_net_device doesn't stop the net queue since
 			 * traffic needs to start it again when suspended */
@@ -3232,13 +3281,13 @@ static int hso_mux_submit_intr_urb(struc
 			 usb_rcvintpipe(usb,
 				shared_int->intr_endp->bEndpointAddress & 0x7F),
 			 shared_int->shared_intr_buf,
-			 shared_int->intr_endp->wMaxPacketSize,
+			 1,
 			 intr_callback, shared_int,
 			 shared_int->intr_endp->bInterval);
 
 	result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
 	if (result)
-		dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__,
+		dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__,
 			result);
 
 	return result;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/kaweth.c linux-libre-2.6.33-gnu1/drivers/net/usb/kaweth.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/kaweth.c	2013-05-03 14:01:46.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/kaweth.c	2013-05-03 12:09:07.000000000 -0400
@@ -468,16 +468,7 @@ static int kaweth_reset(struct kaweth_de
 	int result;
 
 	dbg("kaweth_reset(%p)", kaweth);
-	result = kaweth_control(kaweth,
-				usb_sndctrlpipe(kaweth->dev, 0),
-				USB_REQ_SET_CONFIGURATION,
-				0,
-				kaweth->dev->config[0].desc.bConfigurationValue,
-				0,
-				NULL,
-				0,
-				KAWETH_CONTROL_TIMEOUT);
-
+	result = usb_reset_configuration(kaweth->dev);
 	mdelay(10);
 
 	dbg("kaweth_reset() returns %d.",result);
@@ -722,7 +713,7 @@ static int kaweth_open(struct net_device
 	return 0;
 
 err_out:
-	usb_autopm_enable(kaweth->intf);
+	usb_autopm_put_interface(kaweth->intf);
 	return -EIO;
 }
 
@@ -759,7 +750,7 @@ static int kaweth_close(struct net_devic
 
 	kaweth->status &= ~KAWETH_STATUS_CLOSING;
 
-	usb_autopm_enable(kaweth->intf);
+	usb_autopm_put_interface(kaweth->intf);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/mcs7830.c linux-libre-2.6.33-gnu1/drivers/net/usb/mcs7830.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/mcs7830.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/mcs7830.c	2010-02-24 13:52:17.000000000 -0500
@@ -391,8 +391,8 @@ static void mcs7830_set_multicast(struct
 
 	if (net->flags & IFF_PROMISC) {
 		data->config |= HIF_REG_CONFIG_PROMISCIOUS;
-	} else if (net->flags & IFF_ALLMULTI
-		   || net->mc_count > MCS7830_MAX_MCAST) {
+	} else if (net->flags & IFF_ALLMULTI ||
+		   net->mc_count > MCS7830_MAX_MCAST) {
 		data->config |= HIF_REG_CONFIG_ALLMULTICAST;
 	} else if (net->mc_count == 0) {
 		/* just broadcast and directed */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/rndis_host.c linux-libre-2.6.33-gnu1/drivers/net/usb/rndis_host.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/rndis_host.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/rndis_host.c	2010-02-24 13:52:17.000000000 -0500
@@ -114,8 +114,8 @@ int rndis_command(struct usbnet *dev, st
 	 */
 
 	/* Issue the request; xid is unique, don't bother byteswapping it */
-	if (likely(buf->msg_type != RNDIS_MSG_HALT
-			&& buf->msg_type != RNDIS_MSG_RESET)) {
+	if (likely(buf->msg_type != RNDIS_MSG_HALT &&
+		   buf->msg_type != RNDIS_MSG_RESET)) {
 		xid = dev->xid++;
 		if (!xid)
 			xid = dev->xid++;
@@ -493,9 +493,9 @@ int rndis_rx_fixup(struct usbnet *dev, s
 		data_len = le32_to_cpu(hdr->data_len);
 
 		/* don't choke if we see oob, per-packet data, etc */
-		if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
-				|| skb->len < msg_len
-				|| (data_offset + data_len + 8) > msg_len)) {
+		if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET ||
+			     skb->len < msg_len ||
+			     (data_offset + data_len + 8) > msg_len)) {
 			dev->net->stats.rx_frame_errors++;
 			devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
 				le32_to_cpu(hdr->msg_type),
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/rtl8150.c linux-libre-2.6.33-gnu1/drivers/net/usb/rtl8150.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/rtl8150.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/rtl8150.c	2010-02-24 13:52:17.000000000 -0500
@@ -270,7 +270,7 @@ static int read_mii_word(rtl8150_t * dev
 		get_registers(dev, PHYCNT, 1, data);
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 
-	if (i < MII_TIMEOUT) {
+	if (i <= MII_TIMEOUT) {
 		get_registers(dev, PHYDAT, 2, data);
 		*reg = data[0] | (data[1] << 8);
 		return 0;
@@ -295,7 +295,7 @@ static int write_mii_word(rtl8150_t * de
 		get_registers(dev, PHYCNT, 1, data);
 	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
 
-	if (i < MII_TIMEOUT)
+	if (i <= MII_TIMEOUT)
 		return 0;
 	else
 		return 1;
@@ -324,7 +324,7 @@ static int rtl8150_set_mac_address(struc
 		dbg("%02X:", netdev->dev_addr[i]);
 	dbg("%02X\n", netdev->dev_addr[i]);
 	/* Set the IDR registers. */
-	set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr);
+	set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr);
 #ifdef EEPROM_WRITE
 	{
 	u8 cr;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/smsc95xx.c linux-libre-2.6.33-gnu1/drivers/net/usb/smsc95xx.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/smsc95xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/smsc95xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -748,7 +748,7 @@ static int smsc95xx_phy_initialize(struc
 	mii_nway_restart(&dev->mii);
 
 	if (netif_msg_ifup(dev))
-		devdbg(dev, "phy initialised succesfully");
+		devdbg(dev, "phy initialised successfully");
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/usbnet.c linux-libre-2.6.33-gnu1/drivers/net/usb/usbnet.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/usbnet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/usbnet.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,8 +140,8 @@ int usbnet_get_endpoints(struct usbnet *
 	if (!alt || !in || !out)
 		return -EINVAL;
 
-	if (alt->desc.bAlternateSetting != 0
-			|| !(dev->driver_info->flags & FLAG_NO_SETINT)) {
+	if (alt->desc.bAlternateSetting != 0 ||
+	    !(dev->driver_info->flags & FLAG_NO_SETINT)) {
 		tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber,
 				alt->desc.bAlternateSetting);
 		if (tmp < 0)
@@ -351,9 +351,10 @@ static void rx_submit (struct usbnet *de
 
 	spin_lock_irqsave (&dev->rxq.lock, lockflags);
 
-	if (netif_running (dev->net)
-			&& netif_device_present (dev->net)
-			&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
+	if (netif_running (dev->net) &&
+	    netif_device_present (dev->net) &&
+	    !test_bit (EVENT_RX_HALT, &dev->flags) &&
+	    !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
 		switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
 		case -EPIPE:
 			usbnet_defer_kevent (dev, EVENT_RX_HALT);
@@ -391,8 +392,8 @@ static void rx_submit (struct usbnet *de
 
 static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
 {
-	if (dev->driver_info->rx_fixup
-			&& !dev->driver_info->rx_fixup (dev, skb))
+	if (dev->driver_info->rx_fixup &&
+	    !dev->driver_info->rx_fixup (dev, skb))
 		goto error;
 	// else network stack removes extra byte if we forced a short packet
 
@@ -484,8 +485,8 @@ block:
 	defer_bh(dev, skb, &dev->rxq);
 
 	if (urb) {
-		if (netif_running (dev->net)
-				&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
+		if (netif_running (dev->net) &&
+		    !test_bit (EVENT_RX_HALT, &dev->flags)) {
 			rx_submit (dev, urb, GFP_ATOMIC);
 			return;
 		}
@@ -611,15 +612,39 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs)
 /*-------------------------------------------------------------------------*/
 
 // precondition: never called in_interrupt
+static void usbnet_terminate_urbs(struct usbnet *dev)
+{
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
+	DECLARE_WAITQUEUE(wait, current);
+	int temp;
+
+	/* ensure there are no more active urbs */
+	add_wait_queue(&unlink_wakeup, &wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	dev->wait = &unlink_wakeup;
+	temp = unlink_urbs(dev, &dev->txq) +
+		unlink_urbs(dev, &dev->rxq);
+
+	/* maybe wait for deletions to finish. */
+	while (!skb_queue_empty(&dev->rxq)
+		&& !skb_queue_empty(&dev->txq)
+		&& !skb_queue_empty(&dev->done)) {
+			schedule_timeout(UNLINK_TIMEOUT_MS);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			if (netif_msg_ifdown(dev))
+				devdbg(dev, "waited for %d urb completions",
+					temp);
+	}
+	set_current_state(TASK_RUNNING);
+	dev->wait = NULL;
+	remove_wait_queue(&unlink_wakeup, &wait);
+}
 
 int usbnet_stop (struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 	struct driver_info	*info = dev->driver_info;
-	int			temp;
 	int			retval;
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
-	DECLARE_WAITQUEUE (wait, current);
 
 	netif_stop_queue (net);
 
@@ -641,25 +666,8 @@ int usbnet_stop (struct net_device *net)
 				info->description);
 	}
 
-	if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
-		/* ensure there are no more active urbs */
-		add_wait_queue(&unlink_wakeup, &wait);
-		dev->wait = &unlink_wakeup;
-		temp = unlink_urbs(dev, &dev->txq) +
-			unlink_urbs(dev, &dev->rxq);
-
-		/* maybe wait for deletions to finish. */
-		while (!skb_queue_empty(&dev->rxq)
-				&& !skb_queue_empty(&dev->txq)
-				&& !skb_queue_empty(&dev->done)) {
-			msleep(UNLINK_TIMEOUT_MS);
-			if (netif_msg_ifdown(dev))
-				devdbg(dev, "waited for %d urb completions",
-					temp);
-		}
-		dev->wait = NULL;
-		remove_wait_queue(&unlink_wakeup, &wait);
-	}
+	if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
+		usbnet_terminate_urbs(dev);
 
 	usb_kill_urb(dev->interrupt);
 
@@ -672,7 +680,10 @@ int usbnet_stop (struct net_device *net)
 	dev->flags = 0;
 	del_timer_sync (&dev->delay);
 	tasklet_kill (&dev->bh);
-	usb_autopm_put_interface(dev->intf);
+	if (info->manage_power)
+		info->manage_power(dev, 0);
+	else
+		usb_autopm_put_interface(dev->intf);
 
 	return 0;
 }
@@ -753,6 +764,12 @@ int usbnet_open (struct net_device *net)
 
 	// delay posting reads until we're fully open
 	tasklet_schedule (&dev->bh);
+	if (info->manage_power) {
+		retval = info->manage_power(dev, 1);
+		if (retval < 0)
+			goto done;
+		usb_autopm_put_interface(dev->intf);
+	}
 	return retval;
 done:
 	usb_autopm_put_interface(dev->intf);
@@ -881,11 +898,16 @@ kevent (struct work_struct *work)
 	/* usb_clear_halt() needs a thread context */
 	if (test_bit (EVENT_TX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->txq);
+		status = usb_autopm_get_interface(dev->intf);
+		if (status < 0)
+			goto fail_pipe;
 		status = usb_clear_halt (dev->udev, dev->out);
-		if (status < 0
-				&& status != -EPIPE
-				&& status != -ESHUTDOWN) {
+		usb_autopm_put_interface(dev->intf);
+		if (status < 0 &&
+		    status != -EPIPE &&
+		    status != -ESHUTDOWN) {
 			if (netif_msg_tx_err (dev))
+fail_pipe:
 				deverr (dev, "can't clear tx halt, status %d",
 					status);
 		} else {
@@ -896,11 +918,16 @@ kevent (struct work_struct *work)
 	}
 	if (test_bit (EVENT_RX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->rxq);
+		status = usb_autopm_get_interface(dev->intf);
+		if (status < 0)
+			goto fail_halt;
 		status = usb_clear_halt (dev->udev, dev->in);
-		if (status < 0
-				&& status != -EPIPE
-				&& status != -ESHUTDOWN) {
+		usb_autopm_put_interface(dev->intf);
+		if (status < 0 &&
+		    status != -EPIPE &&
+		    status != -ESHUTDOWN) {
 			if (netif_msg_rx_err (dev))
+fail_halt:
 				deverr (dev, "can't clear rx halt, status %d",
 					status);
 		} else {
@@ -919,7 +946,12 @@ kevent (struct work_struct *work)
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
 		if (urb != NULL) {
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
+			status = usb_autopm_get_interface(dev->intf);
+			if (status < 0)
+				goto fail_lowmem;
 			rx_submit (dev, urb, GFP_KERNEL);
+			usb_autopm_put_interface(dev->intf);
+fail_lowmem:
 			tasklet_schedule (&dev->bh);
 		}
 	}
@@ -929,11 +961,18 @@ kevent (struct work_struct *work)
 		int			retval = 0;
 
 		clear_bit (EVENT_LINK_RESET, &dev->flags);
+		status = usb_autopm_get_interface(dev->intf);
+		if (status < 0)
+			goto skip_reset;
 		if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
+			usb_autopm_put_interface(dev->intf);
+skip_reset:
 			devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s",
 				retval,
 				dev->udev->bus->bus_name, dev->udev->devpath,
 				info->description);
+		} else {
+			usb_autopm_put_interface(dev->intf);
 		}
 	}
 
@@ -971,6 +1010,7 @@ static void tx_complete (struct urb *urb
 		case -EPROTO:
 		case -ETIME:
 		case -EILSEQ:
+			usb_mark_last_busy(dev->udev);
 			if (!timer_pending (&dev->delay)) {
 				mod_timer (&dev->delay,
 					jiffies + THROTTLE_JIFFIES);
@@ -987,6 +1027,7 @@ static void tx_complete (struct urb *urb
 		}
 	}
 
+	usb_autopm_put_interface_async(dev->intf);
 	urb->dev = NULL;
 	entry->state = tx_done;
 	defer_bh(dev, skb, &dev->txq);
@@ -1057,14 +1098,34 @@ netdev_tx_t usbnet_start_xmit (struct sk
 		}
 	}
 
-	spin_lock_irqsave (&dev->txq.lock, flags);
+	spin_lock_irqsave(&dev->txq.lock, flags);
+	retval = usb_autopm_get_interface_async(dev->intf);
+	if (retval < 0) {
+		spin_unlock_irqrestore(&dev->txq.lock, flags);
+		goto drop;
+	}
+
+#ifdef CONFIG_PM
+	/* if this triggers the device is still a sleep */
+	if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
+		/* transmission will be done in resume */
+		usb_anchor_urb(urb, &dev->deferred);
+		/* no use to process more packets */
+		netif_stop_queue(net);
+		spin_unlock_irqrestore(&dev->txq.lock, flags);
+		devdbg(dev, "Delaying transmission for resumption");
+		goto deferred;
+	}
+#endif
 
 	switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
 	case -EPIPE:
 		netif_stop_queue (net);
 		usbnet_defer_kevent (dev, EVENT_TX_HALT);
+		usb_autopm_put_interface_async(dev->intf);
 		break;
 	default:
+		usb_autopm_put_interface_async(dev->intf);
 		if (netif_msg_tx_err (dev))
 			devdbg (dev, "tx: submit urb err %d", retval);
 		break;
@@ -1088,6 +1149,9 @@ drop:
 		devdbg (dev, "> tx, len %d, type 0x%x",
 			length, skb->protocol);
 	}
+#ifdef CONFIG_PM
+deferred:
+#endif
 	return NETDEV_TX_OK;
 }
 EXPORT_SYMBOL_GPL(usbnet_start_xmit);
@@ -1126,10 +1190,10 @@ static void usbnet_bh (unsigned long par
 		}
 
 	// or are we maybe short a few urbs?
-	} else if (netif_running (dev->net)
-			&& netif_device_present (dev->net)
-			&& !timer_pending (&dev->delay)
-			&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
+	} else if (netif_running (dev->net) &&
+		   netif_device_present (dev->net) &&
+		   !timer_pending (&dev->delay) &&
+		   !test_bit (EVENT_RX_HALT, &dev->flags)) {
 		int	temp = dev->rxq.qlen;
 		int	qlen = RX_QLEN (dev);
 
@@ -1210,6 +1274,14 @@ static const struct net_device_ops usbne
 
 // precondition: never called in_interrupt
 
+static struct device_type wlan_type = {
+	.name	= "wlan",
+};
+
+static struct device_type wwan_type = {
+	.name	= "wwan",
+};
+
 int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
@@ -1255,6 +1327,7 @@ usbnet_probe (struct usb_interface *udev
 	dev->bh.func = usbnet_bh;
 	dev->bh.data = (unsigned long) dev;
 	INIT_WORK (&dev->kevent, kevent);
+	init_usb_anchor(&dev->deferred);
 	dev->delay.function = usbnet_bh;
 	dev->delay.data = (unsigned long) dev;
 	init_timer (&dev->delay);
@@ -1289,12 +1362,15 @@ usbnet_probe (struct usb_interface *udev
 		// heuristic:  "usb%d" for links we know are two-host,
 		// else "eth%d" when there's reasonable doubt.  userspace
 		// can rename the link if it knows better.
-		if ((dev->driver_info->flags & FLAG_ETHER) != 0
-				&& (net->dev_addr [0] & 0x02) == 0)
+		if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
+		    (net->dev_addr [0] & 0x02) == 0)
 			strcpy (net->name, "eth%d");
 		/* WLAN devices should always be named "wlan%d" */
 		if ((dev->driver_info->flags & FLAG_WLAN) != 0)
 			strcpy(net->name, "wlan%d");
+		/* WWAN devices should always be named "wwan%d" */
+		if ((dev->driver_info->flags & FLAG_WWAN) != 0)
+			strcpy(net->name, "wwan%d");
 
 		/* maybe the remote can't receive an Ethernet MTU */
 		if (net->mtu > (dev->hard_mtu - net->hard_header_len))
@@ -1322,6 +1398,12 @@ usbnet_probe (struct usb_interface *udev
 	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
 
 	SET_NETDEV_DEV(net, &udev->dev);
+
+	if ((dev->driver_info->flags & FLAG_WLAN) != 0)
+		SET_NETDEV_DEVTYPE(net, &wlan_type);
+	if ((dev->driver_info->flags & FLAG_WWAN) != 0)
+		SET_NETDEV_DEVTYPE(net, &wwan_type);
+
 	status = register_netdev (net);
 	if (status)
 		goto out3;
@@ -1335,9 +1417,11 @@ usbnet_probe (struct usb_interface *udev
 	// ok, it's ready to go.
 	usb_set_intfdata (udev, dev);
 
-	// start as if the link is up
 	netif_device_attach (net);
 
+	if (dev->driver_info->flags & FLAG_LINK_INTR)
+		netif_carrier_off(net);
+
 	return 0;
 
 out3:
@@ -1363,13 +1447,23 @@ int usbnet_suspend (struct usb_interface
 	struct usbnet		*dev = usb_get_intfdata(intf);
 
 	if (!dev->suspend_count++) {
+		spin_lock_irq(&dev->txq.lock);
+		/* don't autosuspend while transmitting */
+		if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) {
+			spin_unlock_irq(&dev->txq.lock);
+			return -EBUSY;
+		} else {
+			set_bit(EVENT_DEV_ASLEEP, &dev->flags);
+			spin_unlock_irq(&dev->txq.lock);
+		}
 		/*
 		 * accelerate emptying of the rx and queues, to avoid
 		 * having everything error out.
 		 */
 		netif_device_detach (dev->net);
-		(void) unlink_urbs (dev, &dev->rxq);
-		(void) unlink_urbs (dev, &dev->txq);
+		usbnet_terminate_urbs(dev);
+		usb_kill_urb(dev->interrupt);
+
 		/*
 		 * reattach so runtime management can use and
 		 * wake the device
@@ -1383,10 +1477,34 @@ EXPORT_SYMBOL_GPL(usbnet_suspend);
 int usbnet_resume (struct usb_interface *intf)
 {
 	struct usbnet		*dev = usb_get_intfdata(intf);
+	struct sk_buff          *skb;
+	struct urb              *res;
+	int                     retval;
 
-	if (!--dev->suspend_count)
-		tasklet_schedule (&dev->bh);
+	if (!--dev->suspend_count) {
+		spin_lock_irq(&dev->txq.lock);
+		while ((res = usb_get_from_anchor(&dev->deferred))) {
 
+			printk(KERN_INFO"%s has delayed data\n", __func__);
+			skb = (struct sk_buff *)res->context;
+			retval = usb_submit_urb(res, GFP_ATOMIC);
+			if (retval < 0) {
+				dev_kfree_skb_any(skb);
+				usb_free_urb(res);
+				usb_autopm_put_interface_async(dev->intf);
+			} else {
+				dev->net->trans_start = jiffies;
+				__skb_queue_tail(&dev->txq, skb);
+			}
+		}
+
+		smp_mb();
+		clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
+		spin_unlock_irq(&dev->txq.lock);
+		if (!(dev->txq.qlen >= TX_QLEN(dev)))
+			netif_start_queue(dev->net);
+		tasklet_schedule (&dev->bh);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(usbnet_resume);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/usb/zaurus.c linux-libre-2.6.33-gnu1/drivers/net/usb/zaurus.c
--- linux-libre-2.6.32-gnu1/drivers/net/usb/zaurus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/usb/zaurus.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,8 +174,8 @@ static int blan_mdlm_bind(struct usbnet
 				goto bad_desc;
 			}
 			/* expect bcdVersion 1.0, ignore */
-			if (memcmp(&desc->bGUID, blan_guid, 16)
-				    && memcmp(&desc->bGUID, safe_guid, 16) ) {
+			if (memcmp(&desc->bGUID, blan_guid, 16) &&
+			    memcmp(&desc->bGUID, safe_guid, 16)) {
 				/* hey, this one might _really_ be MDLM! */
 				dev_dbg(&intf->dev, "MDLM guid\n");
 				goto bad_desc;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/veth.c linux-libre-2.6.33-gnu1/drivers/net/veth.c
--- linux-libre-2.6.32-gnu1/drivers/net/veth.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/veth.c	2010-02-24 13:52:17.000000000 -0500
@@ -153,35 +153,24 @@ static netdev_tx_t veth_xmit(struct sk_b
 	struct net_device *rcv = NULL;
 	struct veth_priv *priv, *rcv_priv;
 	struct veth_net_stats *stats, *rcv_stats;
-	int length, cpu;
-
-	skb_orphan(skb);
+	int length;
 
 	priv = netdev_priv(dev);
 	rcv = priv->peer;
 	rcv_priv = netdev_priv(rcv);
 
-	cpu = smp_processor_id();
-	stats = per_cpu_ptr(priv->stats, cpu);
-	rcv_stats = per_cpu_ptr(rcv_priv->stats, cpu);
+	stats = this_cpu_ptr(priv->stats);
+	rcv_stats = this_cpu_ptr(rcv_priv->stats);
 
 	if (!(rcv->flags & IFF_UP))
 		goto tx_drop;
 
-	if (skb->len > (rcv->mtu + MTU_PAD))
-		goto rx_drop;
-
-        skb->tstamp.tv64 = 0;
-	skb->pkt_type = PACKET_HOST;
-	skb->protocol = eth_type_trans(skb, rcv);
 	if (dev->features & NETIF_F_NO_CSUM)
 		skb->ip_summed = rcv_priv->ip_summed;
 
-	skb->mark = 0;
-	secpath_reset(skb);
-	nf_reset(skb);
-
-	length = skb->len;
+	length = skb->len + ETH_HLEN;
+	if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
+		goto rx_drop;
 
 	stats->tx_bytes += length;
 	stats->tx_packets++;
@@ -189,7 +178,6 @@ static netdev_tx_t veth_xmit(struct sk_b
 	rcv_stats->rx_bytes += length;
 	rcv_stats->rx_packets++;
 
-	netif_rx(skb);
 	return NETDEV_TX_OK;
 
 tx_drop:
@@ -337,7 +325,7 @@ static int veth_validate(struct nlattr *
 
 static struct rtnl_link_ops veth_link_ops;
 
-static int veth_newlink(struct net_device *dev,
+static int veth_newlink(struct net *src_net, struct net_device *dev,
 			 struct nlattr *tb[], struct nlattr *data[])
 {
 	int err;
@@ -345,6 +333,7 @@ static int veth_newlink(struct net_devic
 	struct veth_priv *priv;
 	char ifname[IFNAMSIZ];
 	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
+	struct net *net;
 
 	/*
 	 * create and register peer first
@@ -377,14 +366,22 @@ static int veth_newlink(struct net_devic
 	else
 		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
 
-	peer = rtnl_create_link(dev_net(dev), ifname, &veth_link_ops, tbp);
-	if (IS_ERR(peer))
+	net = rtnl_link_get_net(src_net, tbp);
+	if (IS_ERR(net))
+		return PTR_ERR(net);
+
+	peer = rtnl_create_link(src_net, net, ifname, &veth_link_ops, tbp);
+	if (IS_ERR(peer)) {
+		put_net(net);
 		return PTR_ERR(peer);
+	}
 
 	if (tbp[IFLA_ADDRESS] == NULL)
 		random_ether_addr(peer->dev_addr);
 
 	err = register_netdevice(peer);
+	put_net(net);
+	net = NULL;
 	if (err < 0)
 		goto err_register_peer;
 
@@ -439,7 +436,7 @@ err_register_peer:
 	return err;
 }
 
-static void veth_dellink(struct net_device *dev)
+static void veth_dellink(struct net_device *dev, struct list_head *head)
 {
 	struct veth_priv *priv;
 	struct net_device *peer;
@@ -447,8 +444,8 @@ static void veth_dellink(struct net_devi
 	priv = netdev_priv(dev);
 	peer = priv->peer;
 
-	unregister_netdevice(dev);
-	unregister_netdevice(peer);
+	unregister_netdevice_queue(dev, head);
+	unregister_netdevice_queue(peer, head);
 }
 
 static const struct nla_policy veth_policy[VETH_INFO_MAX + 1];
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/via-rhine.c linux-libre-2.6.33-gnu1/drivers/net/via-rhine.c
--- linux-libre-2.6.32-gnu1/drivers/net/via-rhine.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/via-rhine.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,9 +42,9 @@ static int max_interrupt_work = 20;
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1518 effectively disables this feature. */
-#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
-       || defined(CONFIG_SPARC) || defined(__ia64__) \
-       || defined(__sh__) || defined(__mips__)
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
+	defined(CONFIG_SPARC) || defined(__ia64__) ||		   \
+	defined(__sh__) || defined(__mips__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak;
@@ -102,6 +102,7 @@ static const int multicast_filter_limit
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/workqueue.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -389,6 +390,7 @@ struct rhine_private {
 	struct net_device *dev;
 	struct napi_struct napi;
 	spinlock_t lock;
+	struct work_struct reset_task;
 
 	/* Frequently used values: keep some adjacent for cache effect. */
 	u32 quirks;
@@ -407,6 +409,7 @@ struct rhine_private {
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
+static void rhine_reset_task(struct work_struct *work);
 static void rhine_tx_timeout(struct net_device *dev);
 static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 				  struct net_device *dev);
@@ -775,6 +778,8 @@ static int __devinit rhine_init_one(stru
 	dev->irq = pdev->irq;
 
 	spin_lock_init(&rp->lock);
+	INIT_WORK(&rp->reset_task, rhine_reset_task);
+
 	rp->mii_if.dev = dev;
 	rp->mii_if.mdio_read = mdio_read;
 	rp->mii_if.mdio_write = mdio_write;
@@ -1150,7 +1155,7 @@ static int rhine_open(struct net_device
 	void __iomem *ioaddr = rp->base;
 	int rc;
 
-	rc = request_irq(rp->pdev->irq, &rhine_interrupt, IRQF_SHARED, dev->name,
+	rc = request_irq(rp->pdev->irq, rhine_interrupt, IRQF_SHARED, dev->name,
 			dev);
 	if (rc)
 		return rc;
@@ -1179,22 +1184,18 @@ static int rhine_open(struct net_device
 	return 0;
 }
 
-static void rhine_tx_timeout(struct net_device *dev)
+static void rhine_reset_task(struct work_struct *work)
 {
-	struct rhine_private *rp = netdev_priv(dev);
-	void __iomem *ioaddr = rp->base;
-
-	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
-	       "%4.4x, resetting...\n",
-	       dev->name, ioread16(ioaddr + IntrStatus),
-	       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+	struct rhine_private *rp = container_of(work, struct rhine_private,
+						reset_task);
+	struct net_device *dev = rp->dev;
 
 	/* protect against concurrent rx interrupts */
 	disable_irq(rp->pdev->irq);
 
 	napi_disable(&rp->napi);
 
-	spin_lock(&rp->lock);
+	spin_lock_bh(&rp->lock);
 
 	/* clear all descriptors */
 	free_tbufs(dev);
@@ -1206,7 +1207,7 @@ static void rhine_tx_timeout(struct net_
 	rhine_chip_reset(dev);
 	init_registers(dev);
 
-	spin_unlock(&rp->lock);
+	spin_unlock_bh(&rp->lock);
 	enable_irq(rp->pdev->irq);
 
 	dev->trans_start = jiffies;
@@ -1214,6 +1215,19 @@ static void rhine_tx_timeout(struct net_
 	netif_wake_queue(dev);
 }
 
+static void rhine_tx_timeout(struct net_device *dev)
+{
+	struct rhine_private *rp = netdev_priv(dev);
+	void __iomem *ioaddr = rp->base;
+
+	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
+	       "%4.4x, resetting...\n",
+	       dev->name, ioread16(ioaddr + IntrStatus),
+	       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+
+	schedule_work(&rp->reset_task);
+}
+
 static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
 				  struct net_device *dev)
 {
@@ -1484,15 +1498,15 @@ static int rhine_rx(struct net_device *d
 				}
 			}
 		} else {
-			struct sk_buff *skb;
+			struct sk_buff *skb = NULL;
 			/* Length should omit the CRC */
 			int pkt_len = data_size - 4;
 
 			/* Check if the packet is long enough to accept without
 			   copying to a minimally-sized skbuff. */
-			if (pkt_len < rx_copybreak &&
-				(skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN)) != NULL) {
-				skb_reserve(skb, NET_IP_ALIGN);	/* 16 byte align the IP header */
+			if (pkt_len < rx_copybreak)
+				skb = netdev_alloc_skb_ip_align(dev, pkt_len);
+			if (skb) {
 				pci_dma_sync_single_for_cpu(rp->pdev,
 							    rp->rx_skbuff_dma[entry],
 							    rp->rx_buf_sz,
@@ -1683,8 +1697,8 @@ static void rhine_set_rx_mode(struct net
 		rx_mode = 0x1C;
 		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
 		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
-	} else if ((dev->mc_count > multicast_filter_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > multicast_filter_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
 		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
@@ -1830,10 +1844,11 @@ static int rhine_close(struct net_device
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 
-	spin_lock_irq(&rp->lock);
-
-	netif_stop_queue(dev);
 	napi_disable(&rp->napi);
+	cancel_work_sync(&rp->reset_task);
+	netif_stop_queue(dev);
+
+	spin_lock_irq(&rp->lock);
 
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: Shutting down ethercard, "
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/via-velocity.c linux-libre-2.6.33-gnu1/drivers/net/via-velocity.c
--- linux-libre-2.6.32-gnu1/drivers/net/via-velocity.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/via-velocity.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,6 @@
  *
  * TODO
  *	rx_copybreak/alignment
- *	Scatter gather
  *	More testing
  *
  * The changes are (c) Copyright 2004, Red Hat Inc. <alan@lxorguk.ukuu.org.uk>
@@ -275,7 +274,7 @@ VELOCITY_PARAM(rx_thresh, "Receive fifo
 
 #define DMA_LENGTH_MIN  0
 #define DMA_LENGTH_MAX  7
-#define DMA_LENGTH_DEF  0
+#define DMA_LENGTH_DEF  6
 
 /* DMA_length[] is used for controlling the DMA length
    0: 8 DWORDs
@@ -298,14 +297,6 @@ VELOCITY_PARAM(DMA_length, "DMA length")
 */
 VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
 
-#define TX_CSUM_DEF     1
-/* txcsum_offload[] is used for setting the checksum offload ability of NIC.
-   (We only support RX checksum offload now)
-   0: disable csum_offload[checksum offload
-   1: enable checksum offload. (Default)
-*/
-VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload");
-
 #define FLOW_CNTL_DEF   1
 #define FLOW_CNTL_MIN   1
 #define FLOW_CNTL_MAX   5
@@ -354,21 +345,10 @@ VELOCITY_PARAM(ValPktLen, "Receiving or
 */
 VELOCITY_PARAM(wol_opts, "Wake On Lan options");
 
-#define INT_WORKS_DEF   20
-#define INT_WORKS_MIN   10
-#define INT_WORKS_MAX   64
-
-VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
-
 static int rx_copybreak = 200;
 module_param(rx_copybreak, int, 0644);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 
-#ifdef CONFIG_PM
-static DEFINE_SPINLOCK(velocity_dev_list_lock);
-static LIST_HEAD(velocity_dev_list);
-#endif
-
 /*
  *	Internal board variants. At the moment we have only one
  */
@@ -417,14 +397,6 @@ static void __devexit velocity_remove1(s
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct velocity_info *vptr = netdev_priv(dev);
 
-#ifdef CONFIG_PM
-	unsigned long flags;
-
-	spin_lock_irqsave(&velocity_dev_list_lock, flags);
-	if (!list_empty(&velocity_dev_list))
-		list_del(&vptr->list);
-	spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
-#endif
 	unregister_netdev(dev);
 	iounmap(vptr->mac_regs);
 	pci_release_regions(pdev);
@@ -510,13 +482,11 @@ static void __devinit velocity_get_optio
 	velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
 	velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
 
-	velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
 	velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
 	velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
 	velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
 	velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
 	velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
-	velocity_set_int_opt((int *) &opts->int_works, int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF, "Interrupt service works", devname);
 	opts->numrx = (opts->numrx & ~3);
 }
 
@@ -925,8 +895,8 @@ static int velocity_set_media_mode(struc
 
 	/*
 	   Check if new status is consisent with current status
-	   if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE)
-	   || (mii_status==curr_status)) {
+	   if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) ||
+	       (mii_status==curr_status)) {
 	   vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
 	   vptr->mii_status=check_connection_type(vptr->mac_regs);
 	   VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
@@ -1162,8 +1132,8 @@ static void velocity_set_multi(struct ne
 		writel(0xffffffff, &regs->MARCAM[0]);
 		writel(0xffffffff, &regs->MARCAM[4]);
 		rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
-	} else if ((dev->mc_count > vptr->multicast_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
+	} else if ((dev->mc_count > vptr->multicast_limit) ||
+		   (dev->flags & IFF_ALLMULTI)) {
 		writel(0xffffffff, &regs->MARCAM[0]);
 		writel(0xffffffff, &regs->MARCAM[4]);
 		rx_mode = (RCR_AM | RCR_AB);
@@ -1259,6 +1229,66 @@ static void mii_init(struct velocity_inf
 	}
 }
 
+/**
+ * setup_queue_timers	-	Setup interrupt timers
+ *
+ * Setup interrupt frequency during suppression (timeout if the frame
+ * count isn't filled).
+ */
+static void setup_queue_timers(struct velocity_info *vptr)
+{
+	/* Only for newer revisions */
+	if (vptr->rev_id >= REV_ID_VT3216_A0) {
+		u8 txqueue_timer = 0;
+		u8 rxqueue_timer = 0;
+
+		if (vptr->mii_status & (VELOCITY_SPEED_1000 |
+				VELOCITY_SPEED_100)) {
+			txqueue_timer = vptr->options.txqueue_timer;
+			rxqueue_timer = vptr->options.rxqueue_timer;
+		}
+
+		writeb(txqueue_timer, &vptr->mac_regs->TQETMR);
+		writeb(rxqueue_timer, &vptr->mac_regs->RQETMR);
+	}
+}
+/**
+ * setup_adaptive_interrupts  -  Setup interrupt suppression
+ *
+ * @vptr velocity adapter
+ *
+ * The velocity is able to suppress interrupt during high interrupt load.
+ * This function turns on that feature.
+ */
+static void setup_adaptive_interrupts(struct velocity_info *vptr)
+{
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	u16 tx_intsup = vptr->options.tx_intsup;
+	u16 rx_intsup = vptr->options.rx_intsup;
+
+	/* Setup default interrupt mask (will be changed below) */
+	vptr->int_mask = INT_MASK_DEF;
+
+	/* Set Tx Interrupt Suppression Threshold */
+	writeb(CAMCR_PS0, &regs->CAMCR);
+	if (tx_intsup != 0) {
+		vptr->int_mask &= ~(ISR_PTXI | ISR_PTX0I | ISR_PTX1I |
+				ISR_PTX2I | ISR_PTX3I);
+		writew(tx_intsup, &regs->ISRCTL);
+	} else
+		writew(ISRCTL_TSUPDIS, &regs->ISRCTL);
+
+	/* Set Rx Interrupt Suppression Threshold */
+	writeb(CAMCR_PS1, &regs->CAMCR);
+	if (rx_intsup != 0) {
+		vptr->int_mask &= ~ISR_PRXI;
+		writew(rx_intsup, &regs->ISRCTL);
+	} else
+		writew(ISRCTL_RSUPDIS, &regs->ISRCTL);
+
+	/* Select page to interrupt hold timer */
+	writeb(0, &regs->CAMCR);
+}
 
 /**
  *	velocity_init_registers	-	initialise MAC registers
@@ -1345,7 +1375,7 @@ static void velocity_init_registers(stru
 		 */
 		enable_mii_autopoll(regs);
 
-		vptr->int_mask = INT_MASK_DEF;
+		setup_adaptive_interrupts(vptr);
 
 		writel(vptr->rx.pool_dma, &regs->RDBaseLo);
 		writew(vptr->options.numrx - 1, &regs->RDCSize);
@@ -1483,7 +1513,8 @@ static int velocity_alloc_rx_buf(struct
 	 *	Do the gymnastics to get the buffer head for data at
 	 *	64byte alignment.
 	 */
-	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
+	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);
 
@@ -1602,12 +1633,10 @@ out:
  */
 static int velocity_init_td_ring(struct velocity_info *vptr)
 {
-	dma_addr_t curr;
 	int j;
 
 	/* Init the TD ring entries */
 	for (j = 0; j < vptr->tx.numq; j++) {
-		curr = vptr->tx.pool_dma[j];
 
 		vptr->tx.infos[j] = kcalloc(vptr->options.numtx,
 					    sizeof(struct velocity_td_info),
@@ -1673,21 +1702,27 @@ err_free_dma_rings_0:
  *	Release an transmit buffer. If the buffer was preallocated then
  *	recycle it, if not then unmap the buffer.
  */
-static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
+static void velocity_free_tx_buf(struct velocity_info *vptr,
+		struct velocity_td_info *tdinfo, struct tx_desc *td)
 {
 	struct sk_buff *skb = tdinfo->skb;
-	int i;
-	int pktlen;
 
 	/*
 	 *	Don't unmap the pre-allocated tx_bufs
 	 */
 	if (tdinfo->skb_dma) {
+		int i;
 
-		pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
 		for (i = 0; i < tdinfo->nskb_dma; i++) {
-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE);
-			tdinfo->skb_dma[i] = 0;
+			size_t pktlen = max_t(size_t, skb->len, ETH_ZLEN);
+
+			/* For scatter-gather */
+			if (skb_shinfo(skb)->nr_frags > 0)
+				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);
 		}
 	}
 	dev_kfree_skb_irq(skb);
@@ -1801,6 +1836,8 @@ static void velocity_error(struct veloci
 				BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
 			else
 				BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
+
+			setup_queue_timers(vptr);
 		}
 		/*
 		 *	Get link status from PHYSR0
@@ -1840,13 +1877,12 @@ static void velocity_error(struct veloci
 /**
  *	tx_srv		-	transmit interrupt service
  *	@vptr; Velocity
- *	@status:
  *
  *	Scan the queues looking for transmitted packets that
  *	we can complete and clean up. Update any statistics as
  *	necessary/
  */
-static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+static int velocity_tx_srv(struct velocity_info *vptr)
 {
 	struct tx_desc *td;
 	int qnum;
@@ -1887,7 +1923,7 @@ static int velocity_tx_srv(struct veloci
 				stats->tx_packets++;
 				stats->tx_bytes += tdinfo->skb->len;
 			}
-			velocity_free_tx_buf(vptr, tdinfo);
+			velocity_free_tx_buf(vptr, tdinfo, td);
 			vptr->tx.used[qnum]--;
 		}
 		vptr->tx.tail[qnum] = idx;
@@ -1899,8 +1935,8 @@ 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)
-	    && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
+	if (netif_queue_stopped(vptr->dev) && (full == 0) &&
+	    (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
 		netif_wake_queue(vptr->dev);
 	}
 	return works;
@@ -1949,10 +1985,9 @@ static int velocity_rx_copy(struct sk_bu
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *new_skb;
 
-		new_skb = netdev_alloc_skb(vptr->dev, pkt_size + 2);
+		new_skb = netdev_alloc_skb_ip_align(vptr->dev, pkt_size);
 		if (new_skb) {
 			new_skb->ip_summed = rx_skb[0]->ip_summed;
-			skb_reserve(new_skb, 2);
 			skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
 			*rx_skb = new_skb;
 			ret = 0;
@@ -2054,19 +2089,18 @@ static int velocity_receive_frame(struct
 /**
  *	velocity_rx_srv		-	service RX interrupt
  *	@vptr: velocity
- *	@status: adapter status (unused)
  *
  *	Walk the receive ring of the velocity adapter and remove
  *	any received packets from the receive queue. Hand the ring
  *	slots back to the adapter for reuse.
  */
-static int velocity_rx_srv(struct velocity_info *vptr, int status)
+static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
 {
 	struct net_device_stats *stats = &vptr->dev->stats;
 	int rd_curr = vptr->rx.curr;
 	int works = 0;
 
-	do {
+	while (works < budget_left) {
 		struct rx_desc *rd = vptr->rx.ring + rd_curr;
 
 		if (!vptr->rx.info[rd_curr].skb)
@@ -2097,7 +2131,8 @@ static int velocity_rx_srv(struct veloci
 		rd_curr++;
 		if (rd_curr >= vptr->options.numrx)
 			rd_curr = 0;
-	} while (++works <= 15);
+		works++;
+	}
 
 	vptr->rx.curr = rd_curr;
 
@@ -2108,6 +2143,32 @@ static int velocity_rx_srv(struct veloci
 	return works;
 }
 
+static int velocity_poll(struct napi_struct *napi, int budget)
+{
+	struct velocity_info *vptr = container_of(napi,
+			struct velocity_info, napi);
+	unsigned int rx_done;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vptr->lock, flags);
+	/*
+	 * Do rx and tx twice for performance (taken from the VIA
+	 * out-of-tree driver).
+	 */
+	rx_done = velocity_rx_srv(vptr, budget / 2);
+	velocity_tx_srv(vptr);
+	rx_done += velocity_rx_srv(vptr, budget - rx_done);
+	velocity_tx_srv(vptr);
+
+	/* If budget not fully consumed, exit the polling mode */
+	if (rx_done < budget) {
+		napi_complete(napi);
+		mac_enable_int(vptr->mac_regs);
+	}
+	spin_unlock_irqrestore(&vptr->lock, flags);
+
+	return rx_done;
+}
 
 /**
  *	velocity_intr		-	interrupt callback
@@ -2124,8 +2185,6 @@ static irqreturn_t velocity_intr(int irq
 	struct net_device *dev = dev_instance;
 	struct velocity_info *vptr = netdev_priv(dev);
 	u32 isr_status;
-	int max_count = 0;
-
 
 	spin_lock(&vptr->lock);
 	isr_status = mac_read_isr(vptr->mac_regs);
@@ -2136,32 +2195,20 @@ static irqreturn_t velocity_intr(int irq
 		return IRQ_NONE;
 	}
 
-	mac_disable_int(vptr->mac_regs);
-
-	/*
-	 *	Keep processing the ISR until we have completed
-	 *	processing and the isr_status becomes zero
-	 */
+	/* Ack the interrupt */
+	mac_write_isr(vptr->mac_regs, isr_status);
 
-	while (isr_status != 0) {
-		mac_write_isr(vptr->mac_regs, isr_status);
-		if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
-			velocity_error(vptr, isr_status);
-		if (isr_status & (ISR_PRXI | ISR_PPRXI))
-			max_count += velocity_rx_srv(vptr, isr_status);
-		if (isr_status & (ISR_PTXI | ISR_PPTXI))
-			max_count += velocity_tx_srv(vptr, isr_status);
-		isr_status = mac_read_isr(vptr->mac_regs);
-		if (max_count > vptr->options.int_works) {
-			printk(KERN_WARNING "%s: excessive work at interrupt.\n",
-				dev->name);
-			max_count = 0;
-		}
+	if (likely(napi_schedule_prep(&vptr->napi))) {
+		mac_disable_int(vptr->mac_regs);
+		__napi_schedule(&vptr->napi);
 	}
+
+	if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
+		velocity_error(vptr, isr_status);
+
 	spin_unlock(&vptr->lock);
-	mac_enable_int(vptr->mac_regs);
-	return IRQ_HANDLED;
 
+	return IRQ_HANDLED;
 }
 
 /**
@@ -2186,11 +2233,9 @@ static int velocity_open(struct net_devi
 	/* Ensure chip is running */
 	pci_set_power_state(vptr->pdev, PCI_D0);
 
-	velocity_give_many_rx_descs(vptr);
-
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
-	ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
+	ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
 			  dev->name, dev);
 	if (ret < 0) {
 		/* Power down the chip */
@@ -2199,8 +2244,11 @@ static int velocity_open(struct net_devi
 		goto out;
 	}
 
+	velocity_give_many_rx_descs(vptr);
+
 	mac_enable_int(vptr->mac_regs);
 	netif_start_queue(dev);
+	napi_enable(&vptr->napi);
 	vptr->flags |= VELOCITY_FLAGS_OPENED;
 out:
 	return ret;
@@ -2287,10 +2335,10 @@ static int velocity_change_mtu(struct ne
 
 		dev->mtu = new_mtu;
 
-		velocity_give_many_rx_descs(vptr);
-
 		velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
+		velocity_give_many_rx_descs(vptr);
+
 		mac_enable_int(vptr->mac_regs);
 		netif_start_queue(dev);
 
@@ -2436,6 +2484,7 @@ static int velocity_close(struct net_dev
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 
+	napi_disable(&vptr->napi);
 	netif_stop_queue(dev);
 	velocity_shutdown(vptr);
 
@@ -2470,14 +2519,22 @@ static netdev_tx_t velocity_xmit(struct
 	struct velocity_td_info *tdinfo;
 	unsigned long flags;
 	int pktlen;
-	__le16 len;
-	int index;
+	int index, prev;
+	int i = 0;
 
 	if (skb_padto(skb, ETH_ZLEN))
 		goto out;
-	pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
 
-	len = cpu_to_le16(pktlen);
+	/* The hardware can handle at most 7 memory segments, so merge
+	 * the skb if there are more */
+	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
+		kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	pktlen = skb_shinfo(skb)->nr_frags == 0 ?
+			max_t(unsigned int, skb->len, ETH_ZLEN) :
+				skb_headlen(skb);
 
 	spin_lock_irqsave(&vptr->lock, flags);
 
@@ -2494,11 +2551,24 @@ static netdev_tx_t velocity_xmit(struct
 	 */
 	tdinfo->skb = skb;
 	tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
-	td_ptr->tdesc0.len = len;
+	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;
-	td_ptr->td_buf[0].size = len;
-	tdinfo->nskb_dma = 1;
+	td_ptr->td_buf[0].size = cpu_to_le16(pktlen);
+
+	/* Handle fragments */
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		tdinfo->skb_dma[i + 1] = pci_map_page(vptr->pdev, frag->page,
+				frag->page_offset, frag->size,
+				PCI_DMA_TODEVICE);
+
+		td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
+		td_ptr->td_buf[i + 1].pa_high = 0;
+		td_ptr->td_buf[i + 1].size = cpu_to_le16(frag->size);
+	}
+	tdinfo->nskb_dma = i + 1;
 
 	td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
 
@@ -2510,8 +2580,8 @@ static netdev_tx_t velocity_xmit(struct
 	/*
 	 *	Handle hardware checksum
 	 */
-	if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-				 && (skb->ip_summed == CHECKSUM_PARTIAL)) {
+	if ((dev->features & NETIF_F_IP_CSUM) &&
+	    (skb->ip_summed == CHECKSUM_PARTIAL)) {
 		const struct iphdr *ip = ip_hdr(skb);
 		if (ip->protocol == IPPROTO_TCP)
 			td_ptr->tdesc1.TCR |= TCR0_TCPCK;
@@ -2519,23 +2589,21 @@ static netdev_tx_t velocity_xmit(struct
 			td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
 		td_ptr->tdesc1.TCR |= TCR0_IPCK;
 	}
-	{
 
-		int prev = index - 1;
+	prev = index - 1;
+	if (prev < 0)
+		prev = vptr->options.numtx - 1;
+	td_ptr->tdesc0.len |= OWNED_BY_NIC;
+	vptr->tx.used[qnum]++;
+	vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
 
-		if (prev < 0)
-			prev = vptr->options.numtx - 1;
-		td_ptr->tdesc0.len |= OWNED_BY_NIC;
-		vptr->tx.used[qnum]++;
-		vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
+	if (AVAIL_TD(vptr, qnum) < 1)
+		netif_stop_queue(dev);
 
-		if (AVAIL_TD(vptr, qnum) < 1)
-			netif_stop_queue(dev);
+	td_ptr = &(vptr->tx.rings[qnum][prev]);
+	td_ptr->td_buf[0].size |= TD_QUEUE;
+	mac_tx_queue_wake(vptr->mac_regs, qnum);
 
-		td_ptr = &(vptr->tx.rings[qnum][prev]);
-		td_ptr->td_buf[0].size |= TD_QUEUE;
-		mac_tx_queue_wake(vptr->mac_regs, qnum);
-	}
 	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&vptr->lock, flags);
 out:
@@ -2578,7 +2646,6 @@ static void __devinit velocity_init_info
 	vptr->tx.numq = info->txqueue;
 	vptr->multicast_limit = MCAM_SIZE;
 	spin_lock_init(&vptr->lock);
-	INIT_LIST_HEAD(&vptr->list);
 }
 
 /**
@@ -2755,12 +2822,10 @@ static int __devinit velocity_found1(str
 	dev->irq = pdev->irq;
 	dev->netdev_ops = &velocity_netdev_ops;
 	dev->ethtool_ops = &velocity_ethtool_ops;
+	netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
 
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
-		NETIF_F_HW_VLAN_RX;
-
-	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-		dev->features |= NETIF_F_IP_CSUM;
+		NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
 
 	ret = register_netdev(dev);
 	if (ret < 0)
@@ -2777,15 +2842,6 @@ static int __devinit velocity_found1(str
 	/* and leave the chip powered down */
 
 	pci_set_power_state(pdev, PCI_D3hot);
-#ifdef CONFIG_PM
-	{
-		unsigned long flags;
-
-		spin_lock_irqsave(&velocity_dev_list_lock, flags);
-		list_add(&vptr->list, &velocity_dev_list);
-		spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
-	}
-#endif
 	velocity_nics++;
 out:
 	return ret;
@@ -3040,7 +3096,7 @@ static int velocity_resume(struct pci_de
 	velocity_init_registers(vptr, VELOCITY_INIT_WOL);
 	mac_disable_int(vptr->mac_regs);
 
-	velocity_tx_srv(vptr, 0);
+	velocity_tx_srv(vptr);
 
 	for (i = 0; i < vptr->tx.numq; i++) {
 		if (vptr->tx.used[i])
@@ -3222,15 +3278,117 @@ static void velocity_set_msglevel(struct
 	 msglevel = value;
 }
 
+static int get_pending_timer_val(int val)
+{
+	int mult_bits = val >> 6;
+	int mult = 1;
+
+	switch (mult_bits)
+	{
+	case 1:
+		mult = 4; break;
+	case 2:
+		mult = 16; break;
+	case 3:
+		mult = 64; break;
+	case 0:
+	default:
+		break;
+	}
+
+	return (val & 0x3f) * mult;
+}
+
+static void set_pending_timer_val(int *val, u32 us)
+{
+	u8 mult = 0;
+	u8 shift = 0;
+
+	if (us >= 0x3f) {
+		mult = 1; /* mult with 4 */
+		shift = 2;
+	}
+	if (us >= 0x3f * 4) {
+		mult = 2; /* mult with 16 */
+		shift = 4;
+	}
+	if (us >= 0x3f * 16) {
+		mult = 3; /* mult with 64 */
+		shift = 6;
+	}
+
+	*val = (mult << 6) | ((us >> shift) & 0x3f);
+}
+
+
+static int velocity_get_coalesce(struct net_device *dev,
+		struct ethtool_coalesce *ecmd)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+
+	ecmd->tx_max_coalesced_frames = vptr->options.tx_intsup;
+	ecmd->rx_max_coalesced_frames = vptr->options.rx_intsup;
+
+	ecmd->rx_coalesce_usecs = get_pending_timer_val(vptr->options.rxqueue_timer);
+	ecmd->tx_coalesce_usecs = get_pending_timer_val(vptr->options.txqueue_timer);
+
+	return 0;
+}
+
+static int velocity_set_coalesce(struct net_device *dev,
+		struct ethtool_coalesce *ecmd)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+	int max_us = 0x3f * 64;
+	unsigned long flags;
+
+	/* 6 bits of  */
+	if (ecmd->tx_coalesce_usecs > max_us)
+		return -EINVAL;
+	if (ecmd->rx_coalesce_usecs > max_us)
+		return -EINVAL;
+
+	if (ecmd->tx_max_coalesced_frames > 0xff)
+		return -EINVAL;
+	if (ecmd->rx_max_coalesced_frames > 0xff)
+		return -EINVAL;
+
+	vptr->options.rx_intsup = ecmd->rx_max_coalesced_frames;
+	vptr->options.tx_intsup = ecmd->tx_max_coalesced_frames;
+
+	set_pending_timer_val(&vptr->options.rxqueue_timer,
+			ecmd->rx_coalesce_usecs);
+	set_pending_timer_val(&vptr->options.txqueue_timer,
+			ecmd->tx_coalesce_usecs);
+
+	/* Setup the interrupt suppression and queue timers */
+	spin_lock_irqsave(&vptr->lock, flags);
+	mac_disable_int(vptr->mac_regs);
+	setup_adaptive_interrupts(vptr);
+	setup_queue_timers(vptr);
+
+	mac_write_int_mask(vptr->int_mask, vptr->mac_regs);
+	mac_clear_isr(vptr->mac_regs);
+	mac_enable_int(vptr->mac_regs);
+	spin_unlock_irqrestore(&vptr->lock, flags);
+
+	return 0;
+}
+
 static const struct ethtool_ops velocity_ethtool_ops = {
 	.get_settings	=	velocity_get_settings,
 	.set_settings	=	velocity_set_settings,
 	.get_drvinfo	=	velocity_get_drvinfo,
+	.set_tx_csum	=	ethtool_op_set_tx_csum,
+	.get_tx_csum	=	ethtool_op_get_tx_csum,
 	.get_wol	=	velocity_ethtool_get_wol,
 	.set_wol	=	velocity_ethtool_set_wol,
 	.get_msglevel	=	velocity_get_msglevel,
 	.set_msglevel	=	velocity_set_msglevel,
+	.set_sg 	=	ethtool_op_set_sg,
 	.get_link	=	velocity_get_link,
+	.get_coalesce	=	velocity_get_coalesce,
+	.set_coalesce	=	velocity_set_coalesce,
 	.begin		=	velocity_ethtool_up,
 	.complete	=	velocity_ethtool_down
 };
@@ -3241,20 +3399,10 @@ static int velocity_netdev_event(struct
 {
 	struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
 	struct net_device *dev = ifa->ifa_dev->dev;
-	struct velocity_info *vptr;
-	unsigned long flags;
-
-	if (dev_net(dev) != &init_net)
-		return NOTIFY_DONE;
 
-	spin_lock_irqsave(&velocity_dev_list_lock, flags);
-	list_for_each_entry(vptr, &velocity_dev_list, list) {
-		if (vptr->dev == dev) {
-			velocity_get_ip(vptr);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
+	if (dev_net(dev) == &init_net &&
+	    dev->netdev_ops == &velocity_netdev_ops)
+		velocity_get_ip(netdev_priv(dev));
 
 	return NOTIFY_DONE;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/via-velocity.h linux-libre-2.6.33-gnu1/drivers/net/via-velocity.h
--- linux-libre-2.6.32-gnu1/drivers/net/via-velocity.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/via-velocity.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,9 +29,10 @@
 
 #define VELOCITY_NAME          "via-velocity"
 #define VELOCITY_FULL_DRV_NAM  "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"
-#define VELOCITY_VERSION       "1.14"
+#define VELOCITY_VERSION       "1.15"
 
 #define VELOCITY_IO_SIZE	256
+#define VELOCITY_NAPI_WEIGHT	64
 
 #define PKT_BUF_SZ          1540
 
@@ -1005,7 +1006,8 @@ struct mac_regs {
 
 	volatile __le32 RDBaseLo;	/* 0x38 */
 	volatile __le16 RDIdx;		/* 0x3C */
-	volatile __le16 reserved_3E;
+	volatile u8 TQETMR;		/* 0x3E, VT3216 and above only */
+	volatile u8 RQETMR;		/* 0x3F, VT3216 and above only */
 
 	volatile __le32 TDBaseLo[4];	/* 0x40 */
 
@@ -1421,7 +1423,6 @@ enum velocity_msg_level {
  */
 
 #define     VELOCITY_FLAGS_TAGGING         0x00000001UL
-#define     VELOCITY_FLAGS_TX_CSUM         0x00000002UL
 #define     VELOCITY_FLAGS_RX_CSUM         0x00000004UL
 #define     VELOCITY_FLAGS_IP_ALIGN        0x00000008UL
 #define     VELOCITY_FLAGS_VAL_PKT_LEN     0x00000010UL
@@ -1491,6 +1492,10 @@ struct velocity_opt {
 	int rx_bandwidth_hi;
 	int rx_bandwidth_lo;
 	int rx_bandwidth_en;
+	int rxqueue_timer;
+	int txqueue_timer;
+	int tx_intsup;
+	int rx_intsup;
 	u32 flags;
 };
 
@@ -1499,8 +1504,6 @@ struct velocity_opt {
 #define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
 
 struct velocity_info {
-	struct list_head list;
-
 	struct pci_dev *pdev;
 	struct net_device *dev;
 
@@ -1559,6 +1562,8 @@ struct velocity_info {
 	u32 ticks;
 
 	u8 rev_id;
+
+	struct napi_struct napi;
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/virtio_net.c linux-libre-2.6.33-gnu1/drivers/net/virtio_net.c
--- linux-libre-2.6.32-gnu1/drivers/net/virtio_net.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/virtio_net.c	2010-02-24 13:52:17.000000000 -0500
@@ -282,13 +282,12 @@ static bool try_fill_recv_maxbufs(struct
 	do {
 		struct skb_vnet_hdr *hdr;
 
-		skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
 		if (unlikely(!skb)) {
 			oom = true;
 			break;
 		}
 
-		skb_reserve(skb, NET_IP_ALIGN);
 		skb_put(skb, MAX_PACKET_LEN);
 
 		hdr = skb_vnet_hdr(skb);
@@ -343,14 +342,12 @@ static bool try_fill_recv(struct virtnet
 	do {
 		skb_frag_t *f;
 
-		skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
+		skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
 		if (unlikely(!skb)) {
 			oom = true;
 			break;
 		}
 
-		skb_reserve(skb, NET_IP_ALIGN);
-
 		f = &skb_shinfo(skb)->frags[0];
 		f->page = get_a_page(vi, gfp);
 		if (!f->page) {
@@ -398,8 +395,7 @@ static void refill_work(struct work_stru
 
 	vi = container_of(work, struct virtnet_info, refill.work);
 	napi_disable(&vi->napi);
-	try_fill_recv(vi, GFP_KERNEL);
-	still_empty = (vi->num == 0);
+	still_empty = !try_fill_recv(vi, GFP_KERNEL);
 	napi_enable(&vi->napi);
 
 	/* In theory, this can happen: if we don't get any buffers in
@@ -431,8 +427,8 @@ again:
 	/* Out of packets? */
 	if (received < budget) {
 		napi_complete(napi);
-		if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
-		    && napi_schedule_prep(napi)) {
+		if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) &&
+		    napi_schedule_prep(napi)) {
 			vi->rvq->vq_ops->disable_cb(vi->rvq);
 			__napi_schedule(napi);
 			goto again;
@@ -893,9 +889,9 @@ static int virtnet_probe(struct virtio_d
 	INIT_DELAYED_WORK(&vi->refill, refill_work);
 
 	/* If we can receive ANY GSO packets, we must allocate large ones. */
-	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4)
-	    || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)
-	    || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
+	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
 		vi->big_packets = true;
 
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_defs.h linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_defs.h
--- linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_defs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -90,23 +90,60 @@ enum {
 	VMXNET3_CMD_GET_CONF_INTR
 };
 
+/*
+ *	Little Endian layout of bitfields -
+ *	Byte 0 :	7.....len.....0
+ *	Byte 1 :	rsvd gen 13.len.8
+ *	Byte 2 : 	5.msscof.0 ext1  dtype
+ *	Byte 3 : 	13...msscof...6
+ *
+ *	Big Endian layout of bitfields -
+ *	Byte 0:		13...msscof...6
+ *	Byte 1 : 	5.msscof.0 ext1  dtype
+ *	Byte 2 :	rsvd gen 13.len.8
+ *	Byte 3 :	7.....len.....0
+ *
+ *	Thus, le32_to_cpu on the dword will allow the big endian driver to read
+ *	the bit fields correctly. And cpu_to_le32 will convert bitfields
+ *	bit fields written by big endian driver to format required by device.
+ */
+
 struct Vmxnet3_TxDesc {
-	u64		addr;
+	__le64 addr;
 
-	u32		len:14;
-	u32		gen:1;      /* generation bit */
-	u32		rsvd:1;
-	u32		dtype:1;    /* descriptor type */
-	u32		ext1:1;
-	u32		msscof:14;  /* MSS, checksum offset, flags */
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 msscof:14;  /* MSS, checksum offset, flags */
+	u32 ext1:1;
+	u32 dtype:1;    /* descriptor type */
+	u32 rsvd:1;
+	u32 gen:1;      /* generation bit */
+	u32 len:14;
+#else
+	u32 len:14;
+	u32 gen:1;      /* generation bit */
+	u32 rsvd:1;
+	u32 dtype:1;    /* descriptor type */
+	u32 ext1:1;
+	u32 msscof:14;  /* MSS, checksum offset, flags */
+#endif  /* __BIG_ENDIAN_BITFIELD */
 
-	u32		hlen:10;    /* header len */
-	u32		om:2;       /* offload mode */
-	u32		eop:1;      /* End Of Packet */
-	u32		cq:1;       /* completion request */
-	u32		ext2:1;
-	u32		ti:1;       /* VLAN Tag Insertion */
-	u32		tci:16;     /* Tag to Insert */
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32 tci:16;     /* Tag to Insert */
+	u32 ti:1;       /* VLAN Tag Insertion */
+	u32 ext2:1;
+	u32 cq:1;       /* completion request */
+	u32 eop:1;      /* End Of Packet */
+	u32 om:2;       /* offload mode */
+	u32 hlen:10;    /* header len */
+#else
+	u32 hlen:10;    /* header len */
+	u32 om:2;       /* offload mode */
+	u32 eop:1;      /* End Of Packet */
+	u32 cq:1;       /* completion request */
+	u32 ext2:1;
+	u32 ti:1;       /* VLAN Tag Insertion */
+	u32 tci:16;     /* Tag to Insert */
+#endif  /* __BIG_ENDIAN_BITFIELD */
 };
 
 /* TxDesc.OM values */
@@ -118,6 +155,8 @@ struct Vmxnet3_TxDesc {
 #define VMXNET3_TXD_EOP_SHIFT	12
 #define VMXNET3_TXD_CQ_SHIFT	13
 #define VMXNET3_TXD_GEN_SHIFT	14
+#define VMXNET3_TXD_EOP_DWORD_SHIFT 3
+#define VMXNET3_TXD_GEN_DWORD_SHIFT 2
 
 #define VMXNET3_TXD_CQ		(1 << VMXNET3_TXD_CQ_SHIFT)
 #define VMXNET3_TXD_EOP		(1 << VMXNET3_TXD_EOP_SHIFT)
@@ -130,29 +169,40 @@ struct Vmxnet3_TxDataDesc {
 	u8		data[VMXNET3_HDR_COPY_SIZE];
 };
 
+#define VMXNET3_TCD_GEN_SHIFT	31
+#define VMXNET3_TCD_GEN_SIZE	1
+#define VMXNET3_TCD_TXIDX_SHIFT	0
+#define VMXNET3_TCD_TXIDX_SIZE	12
+#define VMXNET3_TCD_GEN_DWORD_SHIFT	3
 
 struct Vmxnet3_TxCompDesc {
 	u32		txdIdx:12;    /* Index of the EOP TxDesc */
 	u32		ext1:20;
 
-	u32		ext2;
-	u32		ext3;
+	__le32		ext2;
+	__le32		ext3;
 
 	u32		rsvd:24;
 	u32		type:7;       /* completion type */
 	u32		gen:1;        /* generation bit */
 };
 
-
 struct Vmxnet3_RxDesc {
-	u64		addr;
+	__le64		addr;
 
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32		gen:1;        /* Generation bit */
+	u32		rsvd:15;
+	u32		dtype:1;      /* Descriptor type */
+	u32		btype:1;      /* Buffer Type */
+	u32		len:14;
+#else
 	u32		len:14;
 	u32		btype:1;      /* Buffer Type */
 	u32		dtype:1;      /* Descriptor type */
 	u32		rsvd:15;
 	u32		gen:1;        /* Generation bit */
-
+#endif
 	u32		ext1;
 };
 
@@ -164,8 +214,17 @@ struct Vmxnet3_RxDesc {
 #define VMXNET3_RXD_BTYPE_SHIFT  14
 #define VMXNET3_RXD_GEN_SHIFT    31
 
-
 struct Vmxnet3_RxCompDesc {
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32		ext2:1;
+	u32		cnc:1;        /* Checksum Not Calculated */
+	u32		rssType:4;    /* RSS hash type used */
+	u32		rqID:10;      /* rx queue/ring ID */
+	u32		sop:1;        /* Start of Packet */
+	u32		eop:1;        /* End of Packet */
+	u32		ext1:2;
+	u32		rxdIdx:12;    /* Index of the RxDesc */
+#else
 	u32		rxdIdx:12;    /* Index of the RxDesc */
 	u32		ext1:2;
 	u32		eop:1;        /* End of Packet */
@@ -174,14 +233,36 @@ struct Vmxnet3_RxCompDesc {
 	u32		rssType:4;    /* RSS hash type used */
 	u32		cnc:1;        /* Checksum Not Calculated */
 	u32		ext2:1;
+#endif  /* __BIG_ENDIAN_BITFIELD */
 
-	u32		rssHash;      /* RSS hash value */
+	__le32		rssHash;      /* RSS hash value */
 
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32		tci:16;       /* Tag stripped */
+	u32		ts:1;         /* Tag is stripped */
+	u32		err:1;        /* Error */
+	u32		len:14;       /* data length */
+#else
 	u32		len:14;       /* data length */
 	u32		err:1;        /* Error */
 	u32		ts:1;         /* Tag is stripped */
 	u32		tci:16;       /* Tag stripped */
+#endif  /* __BIG_ENDIAN_BITFIELD */
+
 
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32		gen:1;        /* generation bit */
+	u32		type:7;       /* completion type */
+	u32		fcs:1;        /* Frame CRC correct */
+	u32		frg:1;        /* IP Fragment */
+	u32		v4:1;         /* IPv4 */
+	u32		v6:1;         /* IPv6 */
+	u32		ipc:1;        /* IP Checksum Correct */
+	u32		tcp:1;        /* TCP packet */
+	u32		udp:1;        /* UDP packet */
+	u32		tuc:1;        /* TCP/UDP Checksum Correct */
+	u32		csum:16;
+#else
 	u32		csum:16;
 	u32		tuc:1;        /* TCP/UDP Checksum Correct */
 	u32		udp:1;        /* UDP packet */
@@ -193,6 +274,7 @@ struct Vmxnet3_RxCompDesc {
 	u32		fcs:1;        /* Frame CRC correct */
 	u32		type:7;       /* completion type */
 	u32		gen:1;        /* generation bit */
+#endif  /* __BIG_ENDIAN_BITFIELD */
 };
 
 /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
@@ -206,6 +288,8 @@ struct Vmxnet3_RxCompDesc {
 /* csum OK for TCP/UDP pkts over IP */
 #define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
 			     1 << VMXNET3_RCD_IPC_SHIFT)
+#define VMXNET3_TXD_GEN_SIZE 1
+#define VMXNET3_TXD_EOP_SIZE 1
 
 /* value of RxCompDesc.rssType */
 enum {
@@ -219,9 +303,9 @@ enum {
 
 /* a union for accessing all cmd/completion descriptors */
 union Vmxnet3_GenericDesc {
-	u64				qword[2];
-	u32				dword[4];
-	u16				word[8];
+	__le64				qword[2];
+	__le32				dword[4];
+	__le16				word[8];
 	struct Vmxnet3_TxDesc		txd;
 	struct Vmxnet3_RxDesc		rxd;
 	struct Vmxnet3_TxCompDesc	tcd;
@@ -287,18 +371,24 @@ enum {
 
 
 struct Vmxnet3_GOSInfo {
-	u32				gosBits:2;	/* 32-bit or 64-bit? */
-	u32				gosType:4;   /* which guest */
-	u32				gosVer:16;   /* gos version */
-	u32				gosMisc:10;  /* other info about gos */
+#ifdef __BIG_ENDIAN_BITFIELD
+	u32		gosMisc:10;    /* other info about gos */
+	u32		gosVer:16;     /* gos version */
+	u32		gosType:4;     /* which guest */
+	u32		gosBits:2;    /* 32-bit or 64-bit? */
+#else
+	u32		gosBits:2;     /* 32-bit or 64-bit? */
+	u32		gosType:4;     /* which guest */
+	u32		gosVer:16;     /* gos version */
+	u32		gosMisc:10;    /* other info about gos */
+#endif  /* __BIG_ENDIAN_BITFIELD */
 };
 
-
 struct Vmxnet3_DriverInfo {
-	u32				version;
+	__le32				version;
 	struct Vmxnet3_GOSInfo		gos;
-	u32				vmxnet3RevSpt;
-	u32				uptVerSpt;
+	__le32				vmxnet3RevSpt;
+	__le32				uptVerSpt;
 };
 
 
@@ -315,42 +405,42 @@ struct Vmxnet3_DriverInfo {
 
 struct Vmxnet3_MiscConf {
 	struct Vmxnet3_DriverInfo driverInfo;
-	u64		uptFeatures;
-	u64		ddPA;         /* driver data PA */
-	u64		queueDescPA;  /* queue descriptor table PA */
-	u32		ddLen;        /* driver data len */
-	u32		queueDescLen; /* queue desc. table len in bytes */
-	u32		mtu;
-	u16		maxNumRxSG;
+	__le64		uptFeatures;
+	__le64		ddPA;         /* driver data PA */
+	__le64		queueDescPA;  /* queue descriptor table PA */
+	__le32		ddLen;        /* driver data len */
+	__le32		queueDescLen; /* queue desc. table len in bytes */
+	__le32		mtu;
+	__le16		maxNumRxSG;
 	u8		numTxQueues;
 	u8		numRxQueues;
-	u32		reserved[4];
+	__le32		reserved[4];
 };
 
 
 struct Vmxnet3_TxQueueConf {
-	u64		txRingBasePA;
-	u64		dataRingBasePA;
-	u64		compRingBasePA;
-	u64		ddPA;         /* driver data */
-	u64		reserved;
-	u32		txRingSize;   /* # of tx desc */
-	u32		dataRingSize; /* # of data desc */
-	u32		compRingSize; /* # of comp desc */
-	u32		ddLen;        /* size of driver data */
+	__le64		txRingBasePA;
+	__le64		dataRingBasePA;
+	__le64		compRingBasePA;
+	__le64		ddPA;         /* driver data */
+	__le64		reserved;
+	__le32		txRingSize;   /* # of tx desc */
+	__le32		dataRingSize; /* # of data desc */
+	__le32		compRingSize; /* # of comp desc */
+	__le32		ddLen;        /* size of driver data */
 	u8		intrIdx;
 	u8		_pad[7];
 };
 
 
 struct Vmxnet3_RxQueueConf {
-	u64		rxRingBasePA[2];
-	u64		compRingBasePA;
-	u64		ddPA;            /* driver data */
-	u64		reserved;
-	u32		rxRingSize[2];   /* # of rx desc */
-	u32		compRingSize;    /* # of rx comp desc */
-	u32		ddLen;           /* size of driver data */
+	__le64		rxRingBasePA[2];
+	__le64		compRingBasePA;
+	__le64		ddPA;            /* driver data */
+	__le64		reserved;
+	__le32		rxRingSize[2];   /* # of rx desc */
+	__le32		compRingSize;    /* # of rx comp desc */
+	__le32		ddLen;           /* size of driver data */
 	u8		intrIdx;
 	u8		_pad[7];
 };
@@ -381,7 +471,7 @@ struct Vmxnet3_IntrConf {
 	u8		eventIntrIdx;
 	u8		modLevels[VMXNET3_MAX_INTRS];	/* moderation level for
 							 * each intr */
-	u32		reserved[3];
+	__le32		reserved[3];
 };
 
 /* one bit per VLAN ID, the size is in the units of u32	*/
@@ -391,21 +481,21 @@ struct Vmxnet3_IntrConf {
 struct Vmxnet3_QueueStatus {
 	bool		stopped;
 	u8		_pad[3];
-	u32		error;
+	__le32		error;
 };
 
 
 struct Vmxnet3_TxQueueCtrl {
-	u32		txNumDeferred;
-	u32		txThreshold;
-	u64		reserved;
+	__le32		txNumDeferred;
+	__le32		txThreshold;
+	__le64		reserved;
 };
 
 
 struct Vmxnet3_RxQueueCtrl {
 	bool		updateRxProd;
 	u8		_pad[7];
-	u64		reserved;
+	__le64		reserved;
 };
 
 enum {
@@ -417,11 +507,11 @@ enum {
 };
 
 struct Vmxnet3_RxFilterConf {
-	u32		rxMode;       /* VMXNET3_RXM_xxx */
-	u16		mfTableLen;   /* size of the multicast filter table */
-	u16		_pad1;
-	u64		mfTablePA;    /* PA of the multicast filters table */
-	u32		vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
+	__le32		rxMode;       /* VMXNET3_RXM_xxx */
+	__le16		mfTableLen;   /* size of the multicast filter table */
+	__le16		_pad1;
+	__le64		mfTablePA;    /* PA of the multicast filters table */
+	__le32		vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
 };
 
 
@@ -444,7 +534,7 @@ struct Vmxnet3_PM_PktFilter {
 
 
 struct Vmxnet3_PMConf {
-	u16		wakeUpEvents;  /* VMXNET3_PM_WAKEUP_xxx */
+	__le16		wakeUpEvents;  /* VMXNET3_PM_WAKEUP_xxx */
 	u8		numFilters;
 	u8		pad[5];
 	struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
@@ -452,9 +542,9 @@ struct Vmxnet3_PMConf {
 
 
 struct Vmxnet3_VariableLenConfDesc {
-	u32		confVer;
-	u32		confLen;
-	u64		confPA;
+	__le32		confVer;
+	__le32		confLen;
+	__le64		confPA;
 };
 
 
@@ -491,12 +581,12 @@ struct Vmxnet3_DSDevRead {
 
 /* All structures in DriverShared are padded to multiples of 8 bytes */
 struct Vmxnet3_DriverShared {
-	u32				magic;
+	__le32				magic;
 	/* make devRead start at 64bit boundaries */
-	u32					pad;
-	struct Vmxnet3_DSDevRead		devRead;
-	u32					ecr;
-	u32					reserved[5];
+	__le32				pad;
+	struct Vmxnet3_DSDevRead	devRead;
+	__le32				ecr;
+	__le32				reserved[5];
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c
--- linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,12 +24,13 @@
  *
  */
 
+#include <net/ip6_checksum.h>
+
 #include "vmxnet3_int.h"
 
 char vmxnet3_driver_name[] = "vmxnet3";
 #define VMXNET3_DRIVER_DESC "VMware vmxnet3 virtual NIC driver"
 
-
 /*
  * PCI Device ID Table
  * Last entry must be all 0s
@@ -151,11 +152,10 @@ vmxnet3_check_link(struct vmxnet3_adapte
 	}
 }
 
-
 static void
 vmxnet3_process_events(struct vmxnet3_adapter *adapter)
 {
-	u32 events = adapter->shared->ecr;
+	u32 events = le32_to_cpu(adapter->shared->ecr);
 	if (!events)
 		return;
 
@@ -173,7 +173,7 @@ vmxnet3_process_events(struct vmxnet3_ad
 		if (adapter->tqd_start->status.stopped) {
 			printk(KERN_ERR "%s: tq error 0x%x\n",
 			       adapter->netdev->name,
-			       adapter->tqd_start->status.error);
+			       le32_to_cpu(adapter->tqd_start->status.error));
 		}
 		if (adapter->rqd_start->status.stopped) {
 			printk(KERN_ERR "%s: rq error 0x%x\n",
@@ -185,6 +185,106 @@ vmxnet3_process_events(struct vmxnet3_ad
 	}
 }
 
+#ifdef __BIG_ENDIAN_BITFIELD
+/*
+ * The device expects the bitfields in shared structures to be written in
+ * little endian. When CPU is big endian, the following routines are used to
+ * correctly read and write into ABI.
+ * The general technique used here is : double word bitfields are defined in
+ * opposite order for big endian architecture. Then before reading them in
+ * driver the complete double word is translated using le32_to_cpu. Similarly
+ * After the driver writes into bitfields, cpu_to_le32 is used to translate the
+ * double words into required format.
+ * In order to avoid touching bits in shared structure more than once, temporary
+ * descriptors are used. These are passed as srcDesc to following functions.
+ */
+static void vmxnet3_RxDescToCPU(const struct Vmxnet3_RxDesc *srcDesc,
+				struct Vmxnet3_RxDesc *dstDesc)
+{
+	u32 *src = (u32 *)srcDesc + 2;
+	u32 *dst = (u32 *)dstDesc + 2;
+	dstDesc->addr = le64_to_cpu(srcDesc->addr);
+	*dst = le32_to_cpu(*src);
+	dstDesc->ext1 = le32_to_cpu(srcDesc->ext1);
+}
+
+static void vmxnet3_TxDescToLe(const struct Vmxnet3_TxDesc *srcDesc,
+			       struct Vmxnet3_TxDesc *dstDesc)
+{
+	int i;
+	u32 *src = (u32 *)(srcDesc + 1);
+	u32 *dst = (u32 *)(dstDesc + 1);
+
+	/* Working backwards so that the gen bit is set at the end. */
+	for (i = 2; i > 0; i--) {
+		src--;
+		dst--;
+		*dst = cpu_to_le32(*src);
+	}
+}
+
+
+static void vmxnet3_RxCompToCPU(const struct Vmxnet3_RxCompDesc *srcDesc,
+				struct Vmxnet3_RxCompDesc *dstDesc)
+{
+	int i = 0;
+	u32 *src = (u32 *)srcDesc;
+	u32 *dst = (u32 *)dstDesc;
+	for (i = 0; i < sizeof(struct Vmxnet3_RxCompDesc) / sizeof(u32); i++) {
+		*dst = le32_to_cpu(*src);
+		src++;
+		dst++;
+	}
+}
+
+
+/* Used to read bitfield values from double words. */
+static u32 get_bitfield32(const __le32 *bitfield, u32 pos, u32 size)
+{
+	u32 temp = le32_to_cpu(*bitfield);
+	u32 mask = ((1 << size) - 1) << pos;
+	temp &= mask;
+	temp >>= pos;
+	return temp;
+}
+
+
+
+#endif  /* __BIG_ENDIAN_BITFIELD */
+
+#ifdef __BIG_ENDIAN_BITFIELD
+
+#   define VMXNET3_TXDESC_GET_GEN(txdesc) get_bitfield32(((const __le32 *) \
+			txdesc) + VMXNET3_TXD_GEN_DWORD_SHIFT, \
+			VMXNET3_TXD_GEN_SHIFT, VMXNET3_TXD_GEN_SIZE)
+#   define VMXNET3_TXDESC_GET_EOP(txdesc) get_bitfield32(((const __le32 *) \
+			txdesc) + VMXNET3_TXD_EOP_DWORD_SHIFT, \
+			VMXNET3_TXD_EOP_SHIFT, VMXNET3_TXD_EOP_SIZE)
+#   define VMXNET3_TCD_GET_GEN(tcd) get_bitfield32(((const __le32 *)tcd) + \
+			VMXNET3_TCD_GEN_DWORD_SHIFT, VMXNET3_TCD_GEN_SHIFT, \
+			VMXNET3_TCD_GEN_SIZE)
+#   define VMXNET3_TCD_GET_TXIDX(tcd) get_bitfield32((const __le32 *)tcd, \
+			VMXNET3_TCD_TXIDX_SHIFT, VMXNET3_TCD_TXIDX_SIZE)
+#   define vmxnet3_getRxComp(dstrcd, rcd, tmp) do { \
+			(dstrcd) = (tmp); \
+			vmxnet3_RxCompToCPU((rcd), (tmp)); \
+		} while (0)
+#   define vmxnet3_getRxDesc(dstrxd, rxd, tmp) do { \
+			(dstrxd) = (tmp); \
+			vmxnet3_RxDescToCPU((rxd), (tmp)); \
+		} while (0)
+
+#else
+
+#   define VMXNET3_TXDESC_GET_GEN(txdesc) ((txdesc)->gen)
+#   define VMXNET3_TXDESC_GET_EOP(txdesc) ((txdesc)->eop)
+#   define VMXNET3_TCD_GET_GEN(tcd) ((tcd)->gen)
+#   define VMXNET3_TCD_GET_TXIDX(tcd) ((tcd)->txdIdx)
+#   define vmxnet3_getRxComp(dstrcd, rcd, tmp) (dstrcd) = (rcd)
+#   define vmxnet3_getRxDesc(dstrxd, rxd, tmp) (dstrxd) = (rxd)
+
+#endif /* __BIG_ENDIAN_BITFIELD  */
+
 
 static void
 vmxnet3_unmap_tx_buf(struct vmxnet3_tx_buf_info *tbi,
@@ -212,7 +312,7 @@ vmxnet3_unmap_pkt(u32 eop_idx, struct vm
 
 	/* no out of order completion */
 	BUG_ON(tq->buf_info[eop_idx].sop_idx != tq->tx_ring.next2comp);
-	BUG_ON(tq->tx_ring.base[eop_idx].txd.eop != 1);
+	BUG_ON(VMXNET3_TXDESC_GET_EOP(&(tq->tx_ring.base[eop_idx].txd)) != 1);
 
 	skb = tq->buf_info[eop_idx].skb;
 	BUG_ON(skb == NULL);
@@ -246,9 +346,10 @@ vmxnet3_tq_tx_complete(struct vmxnet3_tx
 	union Vmxnet3_GenericDesc *gdesc;
 
 	gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
-	while (gdesc->tcd.gen == tq->comp_ring.gen) {
-		completed += vmxnet3_unmap_pkt(gdesc->tcd.txdIdx, tq,
-					       adapter->pdev, adapter);
+	while (VMXNET3_TCD_GET_GEN(&gdesc->tcd) == tq->comp_ring.gen) {
+		completed += vmxnet3_unmap_pkt(VMXNET3_TCD_GET_TXIDX(
+					       &gdesc->tcd), tq, adapter->pdev,
+					       adapter);
 
 		vmxnet3_comp_ring_adv_next2proc(&tq->comp_ring);
 		gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
@@ -472,9 +573,9 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_r
 		}
 
 		BUG_ON(rbi->dma_addr == 0);
-		gd->rxd.addr = rbi->dma_addr;
-		gd->dword[2] = (ring->gen << VMXNET3_RXD_GEN_SHIFT) | val |
-				rbi->len;
+		gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
+		gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT)
+					   | val | rbi->len);
 
 		num_allocated++;
 		vmxnet3_cmd_ring_adv_next2fill(ring);
@@ -531,10 +632,10 @@ vmxnet3_map_pkt(struct sk_buff *skb, str
 
 	/* no need to map the buffer if headers are copied */
 	if (ctx->copy_size) {
-		ctx->sop_txd->txd.addr = tq->data_ring.basePA +
+		ctx->sop_txd->txd.addr = cpu_to_le64(tq->data_ring.basePA +
 					tq->tx_ring.next2fill *
-					sizeof(struct Vmxnet3_TxDataDesc);
-		ctx->sop_txd->dword[2] = dw2 | ctx->copy_size;
+					sizeof(struct Vmxnet3_TxDataDesc));
+		ctx->sop_txd->dword[2] = cpu_to_le32(dw2 | ctx->copy_size);
 		ctx->sop_txd->dword[3] = 0;
 
 		tbi = tq->buf_info + tq->tx_ring.next2fill;
@@ -542,7 +643,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, str
 
 		dev_dbg(&adapter->netdev->dev,
 			"txd[%u]: 0x%Lx 0x%x 0x%x\n",
-			tq->tx_ring.next2fill, ctx->sop_txd->txd.addr,
+			tq->tx_ring.next2fill,
+			le64_to_cpu(ctx->sop_txd->txd.addr),
 			ctx->sop_txd->dword[2], ctx->sop_txd->dword[3]);
 		vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
 
@@ -570,14 +672,14 @@ vmxnet3_map_pkt(struct sk_buff *skb, str
 		gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
 		BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
 
-		gdesc->txd.addr = tbi->dma_addr;
-		gdesc->dword[2] = dw2 | buf_size;
+		gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
+		gdesc->dword[2] = cpu_to_le32(dw2 | buf_size);
 		gdesc->dword[3] = 0;
 
 		dev_dbg(&adapter->netdev->dev,
 			"txd[%u]: 0x%Lx 0x%x 0x%x\n",
-			tq->tx_ring.next2fill, gdesc->txd.addr,
-			gdesc->dword[2], gdesc->dword[3]);
+			tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
+			le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
 		vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
 		dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
 
@@ -599,14 +701,14 @@ vmxnet3_map_pkt(struct sk_buff *skb, str
 		gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
 		BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
 
-		gdesc->txd.addr = tbi->dma_addr;
-		gdesc->dword[2] = dw2 | frag->size;
+		gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
+		gdesc->dword[2] = cpu_to_le32(dw2 | frag->size);
 		gdesc->dword[3] = 0;
 
 		dev_dbg(&adapter->netdev->dev,
 			"txd[%u]: 0x%llu %u %u\n",
-			tq->tx_ring.next2fill, gdesc->txd.addr,
-			gdesc->dword[2], gdesc->dword[3]);
+			tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
+			le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
 		vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
 		dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
 	}
@@ -751,6 +853,10 @@ vmxnet3_tq_xmit(struct sk_buff *skb, str
 	unsigned long flags;
 	struct vmxnet3_tx_ctx ctx;
 	union Vmxnet3_GenericDesc *gdesc;
+#ifdef __BIG_ENDIAN_BITFIELD
+	/* Use temporary descriptor to avoid touching bits multiple times */
+	union Vmxnet3_GenericDesc tempTxDesc;
+#endif
 
 	/* conservatively estimate # of descriptors to use */
 	count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
@@ -827,16 +933,22 @@ vmxnet3_tq_xmit(struct sk_buff *skb, str
 	vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter);
 
 	/* setup the EOP desc */
-	ctx.eop_txd->dword[3] = VMXNET3_TXD_CQ | VMXNET3_TXD_EOP;
+	ctx.eop_txd->dword[3] = cpu_to_le32(VMXNET3_TXD_CQ | VMXNET3_TXD_EOP);
 
 	/* setup the SOP desc */
+#ifdef __BIG_ENDIAN_BITFIELD
+	gdesc = &tempTxDesc;
+	gdesc->dword[2] = ctx.sop_txd->dword[2];
+	gdesc->dword[3] = ctx.sop_txd->dword[3];
+#else
 	gdesc = ctx.sop_txd;
+#endif
 	if (ctx.mss) {
 		gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
 		gdesc->txd.om = VMXNET3_OM_TSO;
 		gdesc->txd.msscof = ctx.mss;
-		tq->shared->txNumDeferred += (skb->len - gdesc->txd.hlen +
-					     ctx.mss - 1) / ctx.mss;
+		le32_add_cpu(&tq->shared->txNumDeferred, (skb->len -
+			     gdesc->txd.hlen + ctx.mss - 1) / ctx.mss);
 	} else {
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
 			gdesc->txd.hlen = ctx.eth_ip_hdr_size;
@@ -847,7 +959,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, str
 			gdesc->txd.om = 0;
 			gdesc->txd.msscof = 0;
 		}
-		tq->shared->txNumDeferred++;
+		le32_add_cpu(&tq->shared->txNumDeferred, 1);
 	}
 
 	if (vlan_tx_tag_present(skb)) {
@@ -855,19 +967,27 @@ vmxnet3_tq_xmit(struct sk_buff *skb, str
 		gdesc->txd.tci = vlan_tx_tag_get(skb);
 	}
 
-	wmb();
-
-	/* finally flips the GEN bit of the SOP desc */
-	gdesc->dword[2] ^= VMXNET3_TXD_GEN;
+	/* finally flips the GEN bit of the SOP desc. */
+	gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^
+						  VMXNET3_TXD_GEN);
+#ifdef __BIG_ENDIAN_BITFIELD
+	/* Finished updating in bitfields of Tx Desc, so write them in original
+	 * place.
+	 */
+	vmxnet3_TxDescToLe((struct Vmxnet3_TxDesc *)gdesc,
+			   (struct Vmxnet3_TxDesc *)ctx.sop_txd);
+	gdesc = ctx.sop_txd;
+#endif
 	dev_dbg(&adapter->netdev->dev,
 		"txd[%u]: SOP 0x%Lx 0x%x 0x%x\n",
 		(u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd -
-		tq->tx_ring.base), gdesc->txd.addr, gdesc->dword[2],
-		gdesc->dword[3]);
+		tq->tx_ring.base), le64_to_cpu(gdesc->txd.addr),
+		le32_to_cpu(gdesc->dword[2]), le32_to_cpu(gdesc->dword[3]));
 
 	spin_unlock_irqrestore(&tq->tx_lock, flags);
 
-	if (tq->shared->txNumDeferred >= tq->shared->txThreshold) {
+	if (le32_to_cpu(tq->shared->txNumDeferred) >=
+					le32_to_cpu(tq->shared->txThreshold)) {
 		tq->shared->txNumDeferred = 0;
 		VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
 				       tq->tx_ring.next2fill);
@@ -889,9 +1009,8 @@ static netdev_tx_t
 vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-	struct vmxnet3_tx_queue *tq = &adapter->tx_queue;
 
-	return vmxnet3_tq_xmit(skb, tq, adapter, netdev);
+	return vmxnet3_tq_xmit(skb, &adapter->tx_queue, adapter, netdev);
 }
 
 
@@ -902,7 +1021,7 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *
 {
 	if (!gdesc->rcd.cnc && adapter->rxcsum) {
 		/* typical case: TCP/UDP over IP and both csums are correct */
-		if ((gdesc->dword[3] & VMXNET3_RCD_CSUM_OK) ==
+		if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) ==
 							VMXNET3_RCD_CSUM_OK) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
@@ -957,8 +1076,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx
 	u32 num_rxd = 0;
 	struct Vmxnet3_RxCompDesc *rcd;
 	struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
-
-	rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+#ifdef __BIG_ENDIAN_BITFIELD
+	struct Vmxnet3_RxDesc rxCmdDesc;
+	struct Vmxnet3_RxCompDesc rxComp;
+#endif
+	vmxnet3_getRxComp(rcd, &rq->comp_ring.base[rq->comp_ring.next2proc].rcd,
+			  &rxComp);
 	while (rcd->gen == rq->comp_ring.gen) {
 		struct vmxnet3_rx_buf_info *rbi;
 		struct sk_buff *skb;
@@ -976,11 +1099,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx
 
 		idx = rcd->rxdIdx;
 		ring_idx = rcd->rqID == rq->qid ? 0 : 1;
-
-		rxd = &rq->rx_ring[ring_idx].base[idx].rxd;
+		vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd,
+				  &rxCmdDesc);
 		rbi = rq->buf_info[ring_idx] + idx;
 
-		BUG_ON(rxd->addr != rbi->dma_addr || rxd->len != rbi->len);
+		BUG_ON(rxd->addr != rbi->dma_addr ||
+		       rxd->len != rbi->len);
 
 		if (unlikely(rcd->eop && rcd->err)) {
 			vmxnet3_rx_error(rq, rcd, ctx, adapter);
@@ -1078,7 +1202,8 @@ rcd_done:
 		}
 
 		vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
-		rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+		vmxnet3_getRxComp(rcd,
+		     &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp);
 	}
 
 	return num_rxd;
@@ -1094,7 +1219,11 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_que
 
 	for (ring_idx = 0; ring_idx < 2; ring_idx++) {
 		for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
-			rxd = &rq->rx_ring[ring_idx].base[i].rxd;
+#ifdef __BIG_ENDIAN_BITFIELD
+			struct Vmxnet3_RxDesc rxDesc;
+#endif
+			vmxnet3_getRxDesc(rxd,
+				&rq->rx_ring[ring_idx].base[i].rxd, &rxDesc);
 
 			if (rxd->btype == VMXNET3_RXD_BTYPE_HEAD &&
 					rq->buf_info[ring_idx][i].skb) {
@@ -1346,12 +1475,12 @@ vmxnet3_request_irqs(struct vmxnet3_adap
 		err = request_irq(adapter->intr.msix_entries[0].vector,
 				  vmxnet3_intr, 0, adapter->netdev->name,
 				  adapter->netdev);
-	} else
-#endif
-	if (adapter->intr.type == VMXNET3_IT_MSI) {
+	} else if (adapter->intr.type == VMXNET3_IT_MSI) {
 		err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0,
 				  adapter->netdev->name, adapter->netdev);
-	} else {
+	} else
+#endif
+	{
 		err = request_irq(adapter->pdev->irq, vmxnet3_intr,
 				  IRQF_SHARED, adapter->netdev->name,
 				  adapter->netdev);
@@ -1412,6 +1541,22 @@ vmxnet3_free_irqs(struct vmxnet3_adapter
 }
 
 
+inline void set_flag_le16(__le16 *data, u16 flag)
+{
+	*data = cpu_to_le16(le16_to_cpu(*data) | flag);
+}
+
+inline void set_flag_le64(__le64 *data, u64 flag)
+{
+	*data = cpu_to_le64(le64_to_cpu(*data) | flag);
+}
+
+inline void reset_flag_le64(__le64 *data, u64 flag)
+{
+	*data = cpu_to_le64(le64_to_cpu(*data) & ~flag);
+}
+
+
 static void
 vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
@@ -1427,7 +1572,8 @@ vmxnet3_vlan_rx_register(struct net_devi
 			adapter->vlan_grp = grp;
 
 			/* update FEATURES to device */
-			devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+			set_flag_le64(&devRead->misc.uptFeatures,
+				      UPT1_F_RXVLAN);
 			VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 					       VMXNET3_CMD_UPDATE_FEATURE);
 			/*
@@ -1450,7 +1596,7 @@ vmxnet3_vlan_rx_register(struct net_devi
 		struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
 		adapter->vlan_grp = NULL;
 
-		if (devRead->misc.uptFeatures & UPT1_F_RXVLAN) {
+		if (le64_to_cpu(devRead->misc.uptFeatures) & UPT1_F_RXVLAN) {
 			int i;
 
 			for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
@@ -1463,7 +1609,8 @@ vmxnet3_vlan_rx_register(struct net_devi
 					       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
 
 			/* update FEATURES to device */
-			devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
+			reset_flag_le64(&devRead->misc.uptFeatures,
+					UPT1_F_RXVLAN);
 			VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 					       VMXNET3_CMD_UPDATE_FEATURE);
 		}
@@ -1565,9 +1712,10 @@ vmxnet3_set_mc(struct net_device *netdev
 			new_table = vmxnet3_copy_mc(netdev);
 			if (new_table) {
 				new_mode |= VMXNET3_RXM_MCAST;
-				rxConf->mfTableLen = netdev->mc_count *
-						     ETH_ALEN;
-				rxConf->mfTablePA = virt_to_phys(new_table);
+				rxConf->mfTableLen = cpu_to_le16(
+						netdev->mc_count * ETH_ALEN);
+				rxConf->mfTablePA = cpu_to_le64(virt_to_phys(
+						    new_table));
 			} else {
 				printk(KERN_INFO "%s: failed to copy mcast list"
 				       ", setting ALL_MULTI\n", netdev->name);
@@ -1582,7 +1730,7 @@ vmxnet3_set_mc(struct net_device *netdev
 	}
 
 	if (new_mode != rxConf->rxMode) {
-		rxConf->rxMode = new_mode;
+		rxConf->rxMode = cpu_to_le32(new_mode);
 		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 				       VMXNET3_CMD_UPDATE_RX_MODE);
 	}
@@ -1610,63 +1758,69 @@ vmxnet3_setup_driver_shared(struct vmxne
 	memset(shared, 0, sizeof(*shared));
 
 	/* driver settings */
-	shared->magic = VMXNET3_REV1_MAGIC;
-	devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
+	shared->magic = cpu_to_le32(VMXNET3_REV1_MAGIC);
+	devRead->misc.driverInfo.version = cpu_to_le32(
+						VMXNET3_DRIVER_VERSION_NUM);
 	devRead->misc.driverInfo.gos.gosBits = (sizeof(void *) == 4 ?
 				VMXNET3_GOS_BITS_32 : VMXNET3_GOS_BITS_64);
 	devRead->misc.driverInfo.gos.gosType = VMXNET3_GOS_TYPE_LINUX;
-	devRead->misc.driverInfo.vmxnet3RevSpt = 1;
-	devRead->misc.driverInfo.uptVerSpt = 1;
+	*((u32 *)&devRead->misc.driverInfo.gos) = cpu_to_le32(
+				*((u32 *)&devRead->misc.driverInfo.gos));
+	devRead->misc.driverInfo.vmxnet3RevSpt = cpu_to_le32(1);
+	devRead->misc.driverInfo.uptVerSpt = cpu_to_le32(1);
 
-	devRead->misc.ddPA = virt_to_phys(adapter);
-	devRead->misc.ddLen = sizeof(struct vmxnet3_adapter);
+	devRead->misc.ddPA = cpu_to_le64(virt_to_phys(adapter));
+	devRead->misc.ddLen = cpu_to_le32(sizeof(struct vmxnet3_adapter));
 
 	/* set up feature flags */
 	if (adapter->rxcsum)
-		devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
+		set_flag_le64(&devRead->misc.uptFeatures, UPT1_F_RXCSUM);
 
 	if (adapter->lro) {
-		devRead->misc.uptFeatures |= UPT1_F_LRO;
-		devRead->misc.maxNumRxSG = 1 + MAX_SKB_FRAGS;
+		set_flag_le64(&devRead->misc.uptFeatures, UPT1_F_LRO);
+		devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS);
 	}
-	if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX)
-			&& adapter->vlan_grp) {
-		devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+	if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX) &&
+	    adapter->vlan_grp) {
+		set_flag_le64(&devRead->misc.uptFeatures, UPT1_F_RXVLAN);
 	}
 
-	devRead->misc.mtu = adapter->netdev->mtu;
-	devRead->misc.queueDescPA = adapter->queue_desc_pa;
-	devRead->misc.queueDescLen = sizeof(struct Vmxnet3_TxQueueDesc) +
-				     sizeof(struct Vmxnet3_RxQueueDesc);
+	devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
+	devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa);
+	devRead->misc.queueDescLen = cpu_to_le32(
+				     sizeof(struct Vmxnet3_TxQueueDesc) +
+				     sizeof(struct Vmxnet3_RxQueueDesc));
 
 	/* tx queue settings */
 	BUG_ON(adapter->tx_queue.tx_ring.base == NULL);
 
 	devRead->misc.numTxQueues = 1;
 	tqc = &adapter->tqd_start->conf;
-	tqc->txRingBasePA   = adapter->tx_queue.tx_ring.basePA;
-	tqc->dataRingBasePA = adapter->tx_queue.data_ring.basePA;
-	tqc->compRingBasePA = adapter->tx_queue.comp_ring.basePA;
-	tqc->ddPA           = virt_to_phys(adapter->tx_queue.buf_info);
-	tqc->txRingSize     = adapter->tx_queue.tx_ring.size;
-	tqc->dataRingSize   = adapter->tx_queue.data_ring.size;
-	tqc->compRingSize   = adapter->tx_queue.comp_ring.size;
-	tqc->ddLen          = sizeof(struct vmxnet3_tx_buf_info) *
-			      tqc->txRingSize;
+	tqc->txRingBasePA   = cpu_to_le64(adapter->tx_queue.tx_ring.basePA);
+	tqc->dataRingBasePA = cpu_to_le64(adapter->tx_queue.data_ring.basePA);
+	tqc->compRingBasePA = cpu_to_le64(adapter->tx_queue.comp_ring.basePA);
+	tqc->ddPA           = cpu_to_le64(virt_to_phys(
+						adapter->tx_queue.buf_info));
+	tqc->txRingSize     = cpu_to_le32(adapter->tx_queue.tx_ring.size);
+	tqc->dataRingSize   = cpu_to_le32(adapter->tx_queue.data_ring.size);
+	tqc->compRingSize   = cpu_to_le32(adapter->tx_queue.comp_ring.size);
+	tqc->ddLen          = cpu_to_le32(sizeof(struct vmxnet3_tx_buf_info) *
+			      tqc->txRingSize);
 	tqc->intrIdx        = adapter->tx_queue.comp_ring.intr_idx;
 
 	/* rx queue settings */
 	devRead->misc.numRxQueues = 1;
 	rqc = &adapter->rqd_start->conf;
-	rqc->rxRingBasePA[0] = adapter->rx_queue.rx_ring[0].basePA;
-	rqc->rxRingBasePA[1] = adapter->rx_queue.rx_ring[1].basePA;
-	rqc->compRingBasePA  = adapter->rx_queue.comp_ring.basePA;
-	rqc->ddPA            = virt_to_phys(adapter->rx_queue.buf_info);
-	rqc->rxRingSize[0]   = adapter->rx_queue.rx_ring[0].size;
-	rqc->rxRingSize[1]   = adapter->rx_queue.rx_ring[1].size;
-	rqc->compRingSize    = adapter->rx_queue.comp_ring.size;
-	rqc->ddLen           = sizeof(struct vmxnet3_rx_buf_info) *
-			       (rqc->rxRingSize[0] + rqc->rxRingSize[1]);
+	rqc->rxRingBasePA[0] = cpu_to_le64(adapter->rx_queue.rx_ring[0].basePA);
+	rqc->rxRingBasePA[1] = cpu_to_le64(adapter->rx_queue.rx_ring[1].basePA);
+	rqc->compRingBasePA  = cpu_to_le64(adapter->rx_queue.comp_ring.basePA);
+	rqc->ddPA            = cpu_to_le64(virt_to_phys(
+						adapter->rx_queue.buf_info));
+	rqc->rxRingSize[0]   = cpu_to_le32(adapter->rx_queue.rx_ring[0].size);
+	rqc->rxRingSize[1]   = cpu_to_le32(adapter->rx_queue.rx_ring[1].size);
+	rqc->compRingSize    = cpu_to_le32(adapter->rx_queue.comp_ring.size);
+	rqc->ddLen           = cpu_to_le32(sizeof(struct vmxnet3_rx_buf_info) *
+			       (rqc->rxRingSize[0] + rqc->rxRingSize[1]));
 	rqc->intrIdx         = adapter->rx_queue.comp_ring.intr_idx;
 
 	/* intr settings */
@@ -1715,11 +1869,10 @@ vmxnet3_activate_dev(struct vmxnet3_adap
 
 	vmxnet3_setup_driver_shared(adapter);
 
-	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL,
-			       VMXNET3_GET_ADDR_LO(adapter->shared_pa));
-	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH,
-			       VMXNET3_GET_ADDR_HI(adapter->shared_pa));
-
+	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL, VMXNET3_GET_ADDR_LO(
+			       adapter->shared_pa));
+	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH, VMXNET3_GET_ADDR_HI(
+			       adapter->shared_pa));
 	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 			       VMXNET3_CMD_ACTIVATE_DEV);
 	ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
@@ -2425,7 +2578,7 @@ vmxnet3_suspend(struct device *device)
 		memcpy(pmConf->filters[i].pattern, netdev->dev_addr, ETH_ALEN);
 		pmConf->filters[i].mask[0] = 0x3F; /* LSB ETH_ALEN bits */
 
-		pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+		set_flag_le16(&pmConf->wakeUpEvents, VMXNET3_PM_WAKEUP_FILTER);
 		i++;
 	}
 
@@ -2467,19 +2620,21 @@ vmxnet3_suspend(struct device *device)
 		pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
 		in_dev_put(in_dev);
 
-		pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+		set_flag_le16(&pmConf->wakeUpEvents, VMXNET3_PM_WAKEUP_FILTER);
 		i++;
 	}
 
 skip_arp:
 	if (adapter->wol & WAKE_MAGIC)
-		pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_MAGIC;
+		set_flag_le16(&pmConf->wakeUpEvents, VMXNET3_PM_WAKEUP_MAGIC);
 
 	pmConf->numFilters = i;
 
-	adapter->shared->devRead.pmConfDesc.confVer = 1;
-	adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
-	adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+	adapter->shared->devRead.pmConfDesc.confVer = cpu_to_le32(1);
+	adapter->shared->devRead.pmConfDesc.confLen = cpu_to_le32(sizeof(
+								  *pmConf));
+	adapter->shared->devRead.pmConfDesc.confPA = cpu_to_le64(virt_to_phys(
+								 pmConf));
 
 	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 			       VMXNET3_CMD_UPDATE_PMCFG);
@@ -2510,9 +2665,11 @@ vmxnet3_resume(struct device *device)
 	pmConf = adapter->pm_conf;
 	memset(pmConf, 0, sizeof(*pmConf));
 
-	adapter->shared->devRead.pmConfDesc.confVer = 1;
-	adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
-	adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+	adapter->shared->devRead.pmConfDesc.confVer = cpu_to_le32(1);
+	adapter->shared->devRead.pmConfDesc.confLen = cpu_to_le32(sizeof(
+								  *pmConf));
+	adapter->shared->devRead.pmConfDesc.confPA = cpu_to_le32(virt_to_phys(
+								 pmConf));
 
 	netif_device_attach(netdev);
 	pci_set_power_state(pdev, PCI_D0);
@@ -2532,7 +2689,7 @@ vmxnet3_resume(struct device *device)
 	return 0;
 }
 
-static struct dev_pm_ops vmxnet3_pm_ops = {
+static const struct dev_pm_ops vmxnet3_pm_ops = {
 	.suspend = vmxnet3_suspend,
 	.resume = vmxnet3_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_ethtool.c linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -50,11 +50,13 @@ vmxnet3_set_rx_csum(struct net_device *n
 		adapter->rxcsum = val;
 		if (netif_running(netdev)) {
 			if (val)
-				adapter->shared->devRead.misc.uptFeatures |=
-								UPT1_F_RXCSUM;
+				set_flag_le64(
+				&adapter->shared->devRead.misc.uptFeatures,
+				UPT1_F_RXCSUM);
 			else
-				adapter->shared->devRead.misc.uptFeatures &=
-								~UPT1_F_RXCSUM;
+				reset_flag_le64(
+				&adapter->shared->devRead.misc.uptFeatures,
+				UPT1_F_RXCSUM);
 
 			VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 					       VMXNET3_CMD_UPDATE_FEATURE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_int.h linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_int.h
--- linux-libre-2.6.32-gnu1/drivers/net/vmxnet3/vmxnet3_int.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vmxnet3/vmxnet3_int.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,16 +27,11 @@
 #ifndef _VMXNET3_INT_H
 #define _VMXNET3_INT_H
 
-#include <linux/types.h>
 #include <linux/ethtool.h>
 #include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/pci.h>
-#include <linux/ethtool.h>
 #include <linux/compiler.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
@@ -335,14 +330,14 @@ struct vmxnet3_adapter {
 };
 
 #define VMXNET3_WRITE_BAR0_REG(adapter, reg, val)  \
-	writel((val), (adapter)->hw_addr0 + (reg))
+	writel(cpu_to_le32(val), (adapter)->hw_addr0 + (reg))
 #define VMXNET3_READ_BAR0_REG(adapter, reg)        \
-	readl((adapter)->hw_addr0 + (reg))
+	le32_to_cpu(readl((adapter)->hw_addr0 + (reg)))
 
 #define VMXNET3_WRITE_BAR1_REG(adapter, reg, val)  \
-	writel((val), (adapter)->hw_addr1 + (reg))
+	writel(cpu_to_le32(val), (adapter)->hw_addr1 + (reg))
 #define VMXNET3_READ_BAR1_REG(adapter, reg)        \
-	readl((adapter)->hw_addr1 + (reg))
+	le32_to_cpu(readl((adapter)->hw_addr1 + (reg)))
 
 #define VMXNET3_WAKE_QUEUE_THRESHOLD(tq)  (5)
 #define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
@@ -358,6 +353,10 @@ struct vmxnet3_adapter {
 #define VMXNET3_MAX_ETH_HDR_SIZE    22
 #define VMXNET3_MAX_SKB_BUF_SIZE    (3*1024)
 
+void set_flag_le16(__le16 *data, u16 flag);
+void set_flag_le64(__le64 *data, u64 flag);
+void reset_flag_le64(__le64 *data, u64 flag);
+
 int
 vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-config.c linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.c
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-config.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.c	2010-02-24 13:52:17.000000000 -0500
@@ -356,10 +356,8 @@ __vxge_hw_device_access_rights_get(u32 h
 
 	switch (host_type) {
 	case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION:
-		if (func_id == 0) {
-			access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
-					VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
-		}
+		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+				VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
 		break;
 	case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
 		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
@@ -382,6 +380,22 @@ __vxge_hw_device_access_rights_get(u32 h
 	return access_rights;
 }
 /*
+ * __vxge_hw_device_is_privilaged
+ * This routine checks if the device function is privilaged or not
+ */
+
+enum vxge_hw_status
+__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id)
+{
+	if (__vxge_hw_device_access_rights_get(host_type,
+		func_id) &
+		VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)
+		return VXGE_HW_OK;
+	else
+		return VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+}
+
+/*
  * __vxge_hw_device_host_info_get
  * This routine returns the host type assignments
  */
@@ -446,220 +460,6 @@ __vxge_hw_verify_pci_e_info(struct __vxg
 	return VXGE_HW_OK;
 }
 
-enum vxge_hw_status
-__vxge_hw_device_is_privilaged(struct __vxge_hw_device *hldev)
-{
-	if ((hldev->host_type == VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION ||
-	hldev->host_type == VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION ||
-	hldev->host_type == VXGE_HW_NO_MR_SR_VH0_FUNCTION0) &&
-	(hldev->func_id == 0))
-		return VXGE_HW_OK;
-	else
-		return VXGE_HW_ERR_PRIVILAGED_OPEARATION;
-}
-
-/*
- * vxge_hw_wrr_rebalance - Rebalance the RX_WRR and KDFC_WRR calandars.
- * Rebalance the RX_WRR and KDFC_WRR calandars.
- */
-static enum
-vxge_hw_status vxge_hw_wrr_rebalance(struct __vxge_hw_device *hldev)
-{
-	u64 val64;
-	u32 wrr_states[VXGE_HW_WEIGHTED_RR_SERVICE_STATES];
-	u32 i, j, how_often = 1;
-	enum vxge_hw_status status = VXGE_HW_OK;
-
-	status = __vxge_hw_device_is_privilaged(hldev);
-	if (status != VXGE_HW_OK)
-		goto exit;
-
-	/* Reset the priorities assigned to the WRR arbitration
-	phases for the receive traffic */
-	for (i = 0; i < VXGE_HW_WRR_RING_COUNT; i++)
-		writeq(0, ((&hldev->mrpcim_reg->rx_w_round_robin_0) + i));
-
-	/* Reset the transmit FIFO servicing calendar for FIFOs */
-	for (i = 0; i < VXGE_HW_WRR_FIFO_COUNT; i++) {
-		writeq(0, ((&hldev->mrpcim_reg->kdfc_w_round_robin_0) + i));
-		writeq(0, ((&hldev->mrpcim_reg->kdfc_w_round_robin_20) + i));
-	}
-
-	/* Assign WRR priority  0 for all FIFOs */
-	for (i = 1; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-		writeq(VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(0),
-				((&hldev->mrpcim_reg->kdfc_fifo_0_ctrl)  + i));
-
-		writeq(VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(0),
-			((&hldev->mrpcim_reg->kdfc_fifo_17_ctrl) + i));
-	}
-
-	/* Reset to service non-offload doorbells */
-	writeq(0, &hldev->mrpcim_reg->kdfc_entry_type_sel_0);
-	writeq(0, &hldev->mrpcim_reg->kdfc_entry_type_sel_1);
-
-	/* Set priority 0 to all receive queues */
-	writeq(0, &hldev->mrpcim_reg->rx_queue_priority_0);
-	writeq(0, &hldev->mrpcim_reg->rx_queue_priority_1);
-	writeq(0, &hldev->mrpcim_reg->rx_queue_priority_2);
-
-	/* Initialize all the slots as unused */
-	for (i = 0; i < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; i++)
-		wrr_states[i] = -1;
-
-	/* Prepare the Fifo service states */
-	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
-		if (!hldev->config.vp_config[i].min_bandwidth)
-			continue;
-
-		how_often = VXGE_HW_VPATH_BANDWIDTH_MAX /
-				hldev->config.vp_config[i].min_bandwidth;
-		if (how_often) {
-
-			for (j = 0; j < VXGE_HW_WRR_FIFO_SERVICE_STATES;) {
-				if (wrr_states[j] == -1) {
-					wrr_states[j] = i;
-					/* Make sure each fifo is serviced
-					 * atleast once */
-					if (i == j)
-						j += VXGE_HW_MAX_VIRTUAL_PATHS;
-					else
-						j += how_often;
-				} else
-					j++;
-			}
-		}
-	}
-
-	/* Fill the unused slots with 0 */
-	for (j = 0; j < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; j++) {
-		if (wrr_states[j] == -1)
-			wrr_states[j] = 0;
-	}
-
-	/* Assign WRR priority number for FIFOs */
-	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-		writeq(VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(i),
-				((&hldev->mrpcim_reg->kdfc_fifo_0_ctrl) + i));
-
-		writeq(VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(i),
-			((&hldev->mrpcim_reg->kdfc_fifo_17_ctrl) + i));
-	}
-
-	/* Modify the servicing algorithm applied to the 3 types of doorbells.
-	i.e, none-offload, message and offload */
-	writeq(VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_0(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_1(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_2(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_3(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_4(1) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_5(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_6(0) |
-				VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_7(0),
-				&hldev->mrpcim_reg->kdfc_entry_type_sel_0);
-
-	writeq(VXGE_HW_KDFC_ENTRY_TYPE_SEL_1_NUMBER_8(1),
-				&hldev->mrpcim_reg->kdfc_entry_type_sel_1);
-
-	for (i = 0, j = 0; i < VXGE_HW_WRR_FIFO_COUNT; i++) {
-
-		val64 = VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_0(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_1(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_2(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_3(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_4(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_5(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_6(wrr_states[j++]);
-		val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_7(wrr_states[j++]);
-
-		writeq(val64, (&hldev->mrpcim_reg->kdfc_w_round_robin_0 + i));
-		writeq(val64, (&hldev->mrpcim_reg->kdfc_w_round_robin_20 + i));
-	}
-
-	/* Set up the priorities assigned to receive queues */
-	writeq(VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_0(0) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_1(1) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_2(2) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_3(3) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_4(4) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_5(5) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_6(6) |
-			VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_7(7),
-			&hldev->mrpcim_reg->rx_queue_priority_0);
-
-	writeq(VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_8(8) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_9(9) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_10(10) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_11(11) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_12(12) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_13(13) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_14(14) |
-			VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_15(15),
-			&hldev->mrpcim_reg->rx_queue_priority_1);
-
-	writeq(VXGE_HW_RX_QUEUE_PRIORITY_2_RX_Q_NUMBER_16(16),
-				&hldev->mrpcim_reg->rx_queue_priority_2);
-
-	/* Initialize all the slots as unused */
-	for (i = 0; i < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; i++)
-		wrr_states[i] = -1;
-
-	/* Prepare the Ring service states */
-	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
-
-		if (!hldev->config.vp_config[i].min_bandwidth)
-			continue;
-
-		how_often = VXGE_HW_VPATH_BANDWIDTH_MAX /
-				hldev->config.vp_config[i].min_bandwidth;
-
-		if (how_often) {
-			for (j = 0; j < VXGE_HW_WRR_RING_SERVICE_STATES;) {
-				if (wrr_states[j] == -1) {
-					wrr_states[j] = i;
-					/* Make sure each ring is
-					 * serviced atleast once */
-					if (i == j)
-						j += VXGE_HW_MAX_VIRTUAL_PATHS;
-					else
-						j += how_often;
-				} else
-					j++;
-			}
-		}
-	}
-
-	/* Fill the unused slots with 0 */
-	for (j = 0; j < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; j++) {
-		if (wrr_states[j] == -1)
-			wrr_states[j] = 0;
-	}
-
-	for (i = 0, j = 0; i < VXGE_HW_WRR_RING_COUNT; i++) {
-		val64 =  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_0(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_1(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_2(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_3(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_4(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_5(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_6(
-				wrr_states[j++]);
-		val64 |=  VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_7(
-				wrr_states[j++]);
-
-		writeq(val64, ((&hldev->mrpcim_reg->rx_w_round_robin_0) + i));
-	}
-exit:
-	return status;
-}
-
 /*
  * __vxge_hw_device_initialize
  * Initialize Titan-V hardware.
@@ -668,14 +468,14 @@ enum vxge_hw_status __vxge_hw_device_ini
 {
 	enum vxge_hw_status status = VXGE_HW_OK;
 
-	if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev)) {
+	if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type,
+				hldev->func_id)) {
 		/* Validate the pci-e link width and speed */
 		status = __vxge_hw_verify_pci_e_info(hldev);
 		if (status != VXGE_HW_OK)
 			goto exit;
 	}
 
-	vxge_hw_wrr_rebalance(hldev);
 exit:
 	return status;
 }
@@ -953,7 +753,8 @@ vxge_hw_mrpcim_stats_access(struct __vxg
 	u64 val64;
 	enum vxge_hw_status status = VXGE_HW_OK;
 
-	status = __vxge_hw_device_is_privilaged(hldev);
+	status = __vxge_hw_device_is_privilaged(hldev->host_type,
+			hldev->func_id);
 	if (status != VXGE_HW_OK)
 		goto exit;
 
@@ -990,7 +791,8 @@ vxge_hw_device_xmac_aggr_stats_get(struc
 
 	val64 = (u64 *)aggr_stats;
 
-	status = __vxge_hw_device_is_privilaged(hldev);
+	status = __vxge_hw_device_is_privilaged(hldev->host_type,
+			hldev->func_id);
 	if (status != VXGE_HW_OK)
 		goto exit;
 
@@ -1023,7 +825,8 @@ vxge_hw_device_xmac_port_stats_get(struc
 	u32 offset = 0x0;
 	val64 = (u64 *) port_stats;
 
-	status = __vxge_hw_device_is_privilaged(hldev);
+	status = __vxge_hw_device_is_privilaged(hldev->host_type,
+			hldev->func_id);
 	if (status != VXGE_HW_OK)
 		goto exit;
 
@@ -1221,7 +1024,8 @@ enum vxge_hw_status vxge_hw_device_setpa
 		goto exit;
 	}
 
-	status = __vxge_hw_device_is_privilaged(hldev);
+	status = __vxge_hw_device_is_privilaged(hldev->host_type,
+			hldev->func_id);
 	if (status != VXGE_HW_OK)
 		goto exit;
 
@@ -2353,6 +2157,28 @@ exit:
 }
 
 /*
+ * vxge_hw_vpath_strip_fcs_check - Check for FCS strip.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask)
+{
+	struct vxge_hw_vpmgmt_reg       __iomem *vpmgmt_reg;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	int i = 0, j = 0;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (!((vpath_mask) & vxge_mBIT(i)))
+			continue;
+		vpmgmt_reg = hldev->vpmgmt_reg[i];
+		for (j = 0; j < VXGE_HW_MAC_MAX_MAC_PORT_ID; j++) {
+			if (readq(&vpmgmt_reg->rxmac_cfg0_port_vpmgmt_clone[j])
+			& VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS)
+				return VXGE_HW_FAIL;
+		}
+	}
+	return status;
+}
+/*
  * vxge_hw_mgmt_reg_Write - Write Titan register.
  */
 enum vxge_hw_status
@@ -4056,6 +3882,30 @@ __vxge_hw_vpath_tim_configure(struct __v
 	return status;
 }
 
+void
+vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+	struct vxge_hw_vp_config *config;
+	u64 val64;
+
+	vpath = &hldev->virtual_paths[vp_id];
+	vp_reg = vpath->vp_reg;
+	config = vpath->vp_config;
+
+	if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+		val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+		if (config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) {
+			config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE;
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+			writeq(val64,
+			&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+		}
+	}
+	return;
+}
 /*
  * __vxge_hw_vpath_initialize
  * This routine is the final phase of init which initializes the
@@ -4098,8 +3948,6 @@ __vxge_hw_vpath_initialize(struct __vxge
 	if (status != VXGE_HW_OK)
 		goto exit;
 
-	writeq(0, &vp_reg->gendma_int);
-
 	val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl);
 
 	/* Get MRRS value from device control */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-config.h linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.h
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-config.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-config.h	2010-02-24 13:52:17.000000000 -0500
@@ -2201,6 +2201,8 @@ __vxge_hw_vpath_func_id_get(
 enum vxge_hw_status
 __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath);
 
+enum vxge_hw_status
+vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask);
 /**
  * vxge_debug
  * @level: level of debug verbosity.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-main.c linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.c
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.c	2010-02-24 13:52:17.000000000 -0500
@@ -310,7 +310,7 @@ static int vxge_rx_map(void *dtrh, struc
 	dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data,
 				rx_priv->data_size, PCI_DMA_FROMDEVICE);
 
-	if (dma_addr == 0) {
+	if (unlikely(pci_dma_mapping_error(ring->pdev, dma_addr))) {
 		ring->stats.pci_map_fail++;
 		return -EIO;
 	}
@@ -2435,7 +2435,6 @@ static int vxge_add_isr(struct vxgedev *
 	int ret = 0;
 #ifdef CONFIG_PCI_MSI
 	int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0;
-	u64 function_mode = vdev->config.device_hw_info.function_mode;
 	int pci_fun = PCI_FUNC(vdev->pdev->devfn);
 
 	if (vdev->config.intr_type == MSI_X)
@@ -2444,20 +2443,9 @@ static int vxge_add_isr(struct vxgedev *
 	if (ret) {
 		vxge_debug_init(VXGE_ERR,
 			"%s: Enabling MSI-X Failed", VXGE_DRIVER_NAME);
-		if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
-			test_and_set_bit(__VXGE_STATE_CARD_UP,
-				&driver_config->inta_dev_open))
-			return VXGE_HW_FAIL;
-		else {
-			vxge_debug_init(VXGE_ERR,
-				"%s: Defaulting to INTA", VXGE_DRIVER_NAME);
-			vdev->config.intr_type = INTA;
-			vxge_hw_device_set_intr_type(vdev->devh,
-				VXGE_HW_INTR_MODE_IRQLINE);
-			vxge_close_vpaths(vdev, 1);
-			vdev->no_of_vpath = 1;
-			vdev->stats.vpaths_open = 1;
-		}
+		vxge_debug_init(VXGE_ERR,
+			"%s: Defaulting to INTA", VXGE_DRIVER_NAME);
+		vdev->config.intr_type = INTA;
 	}
 
 	if (vdev->config.intr_type == MSI_X) {
@@ -2505,24 +2493,11 @@ static int vxge_add_isr(struct vxgedev *
 					"%s: MSIX - %d  Registration failed",
 					vdev->ndev->name, intr_cnt);
 				vxge_rem_msix_isr(vdev);
-				if ((function_mode ==
-					VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
-					test_and_set_bit(__VXGE_STATE_CARD_UP,
-						&driver_config->inta_dev_open))
-					return VXGE_HW_FAIL;
-				else {
-					vxge_hw_device_set_intr_type(
-						vdev->devh,
-						VXGE_HW_INTR_MODE_IRQLINE);
-						vdev->config.intr_type = INTA;
-					vxge_debug_init(VXGE_ERR,
-						"%s: Defaulting to INTA"
-						, vdev->ndev->name);
-					vxge_close_vpaths(vdev, 1);
-					vdev->no_of_vpath = 1;
-					vdev->stats.vpaths_open = 1;
+				vdev->config.intr_type = INTA;
+				vxge_debug_init(VXGE_ERR,
+					"%s: Defaulting to INTA"
+					, vdev->ndev->name);
 					goto INTA_MODE;
-				}
 			}
 
 			if (irq_req) {
@@ -2535,9 +2510,9 @@ static int vxge_add_isr(struct vxgedev *
 			}
 
 			/* Point to next vpath handler */
-			if (((intr_idx + 1) % VXGE_HW_VPATH_MSIX_ACTIVE == 0)
-				&& (vp_idx < (vdev->no_of_vpath - 1)))
-					vp_idx++;
+			if (((intr_idx + 1) % VXGE_HW_VPATH_MSIX_ACTIVE == 0) &&
+			    (vp_idx < (vdev->no_of_vpath - 1)))
+				vp_idx++;
 		}
 
 		intr_cnt = vdev->max_vpath_supported * 2;
@@ -2555,23 +2530,11 @@ static int vxge_add_isr(struct vxgedev *
 				"%s: MSIX - %d Registration failed",
 				vdev->ndev->name, intr_cnt);
 			vxge_rem_msix_isr(vdev);
-			if ((function_mode ==
-				VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
-				test_and_set_bit(__VXGE_STATE_CARD_UP,
-						&driver_config->inta_dev_open))
-				return VXGE_HW_FAIL;
-			else {
-				vxge_hw_device_set_intr_type(vdev->devh,
-						VXGE_HW_INTR_MODE_IRQLINE);
-				vdev->config.intr_type = INTA;
-				vxge_debug_init(VXGE_ERR,
-					"%s: Defaulting to INTA",
-					vdev->ndev->name);
-				vxge_close_vpaths(vdev, 1);
-				vdev->no_of_vpath = 1;
-				vdev->stats.vpaths_open = 1;
+			vdev->config.intr_type = INTA;
+			vxge_debug_init(VXGE_ERR,
+				"%s: Defaulting to INTA",
+				vdev->ndev->name);
 				goto INTA_MODE;
-			}
 		}
 
 		vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle,
@@ -2584,6 +2547,10 @@ INTA_MODE:
 	snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name);
 
 	if (vdev->config.intr_type == INTA) {
+		vxge_hw_device_set_intr_type(vdev->devh,
+			VXGE_HW_INTR_MODE_IRQLINE);
+		vxge_hw_vpath_tti_ci_set(vdev->devh,
+			vdev->vpaths[0].device_id);
 		ret = request_irq((int) vdev->pdev->irq,
 			vxge_isr_napi,
 			IRQF_SHARED, vdev->desc[0], vdev);
@@ -2688,13 +2655,6 @@ vxge_open(struct net_device *dev)
 	 * initialized */
 	netif_carrier_off(dev);
 
-	/* Check for another device already opn with INTA */
-	if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
-		test_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open)) {
-		ret = -EPERM;
-		goto out0;
-	}
-
 	/* Open VPATHs */
 	status = vxge_open_vpaths(vdev);
 	if (status != VXGE_HW_OK) {
@@ -2983,7 +2943,6 @@ int do_vxge_close(struct net_device *dev
 	vxge_debug_entryexit(VXGE_TRACE,
 		"%s: %s:%d  Exiting...", dev->name, __func__, __LINE__);
 
-	clear_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open);
 	clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state);
 
 	return 0;
@@ -3653,11 +3612,12 @@ static int __devinit vxge_config_vpaths(
 		device_config->vp_config[i].fifo.enable =
 						VXGE_HW_FIFO_ENABLE;
 		device_config->vp_config[i].fifo.max_frags =
-				MAX_SKB_FRAGS;
+				MAX_SKB_FRAGS + 1;
 		device_config->vp_config[i].fifo.memblock_size =
 			VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE;
 
-		txdl_size = MAX_SKB_FRAGS * sizeof(struct vxge_hw_fifo_txd);
+		txdl_size = device_config->vp_config[i].fifo.max_frags *
+				sizeof(struct vxge_hw_fifo_txd);
 		txdl_per_memblock = VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE / txdl_size;
 
 		device_config->vp_config[i].fifo.fifo_blocks =
@@ -4088,9 +4048,10 @@ vxge_probe(struct pci_dev *pdev, const s
 		driver_config->config_dev_cnt = 0;
 		driver_config->total_dev_cnt = 0;
 		driver_config->g_no_cpus = 0;
-		driver_config->vpath_per_dev = max_config_vpath;
 	}
 
+	driver_config->vpath_per_dev = max_config_vpath;
+
 	driver_config->total_dev_cnt++;
 	if (++driver_config->config_dev_cnt > max_config_dev) {
 		ret = 0;
@@ -4126,21 +4087,21 @@ vxge_probe(struct pci_dev *pdev, const s
 		goto _exit0;
 	}
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		vxge_debug_ll_config(VXGE_TRACE,
 			"%s : using 64bit DMA", __func__);
 
 		high_dma = 1;
 
 		if (pci_set_consistent_dma_mask(pdev,
-						0xffffffffffffffffULL)) {
+						DMA_BIT_MASK(64))) {
 			vxge_debug_init(VXGE_ERR,
 				"%s : unable to obtain 64bit DMA for "
 				"consistent allocations", __func__);
 			ret = -ENOMEM;
 			goto _exit1;
 		}
-	} else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		vxge_debug_ll_config(VXGE_TRACE,
 			"%s : using 32bit DMA", __func__);
 	} else {
@@ -4243,6 +4204,15 @@ vxge_probe(struct pci_dev *pdev, const s
 			goto _exit3;
 	}
 
+	/* if FCS stripping is not disabled in MAC fail driver load */
+	if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: FCS stripping is not disabled in MAC"
+			" failing driver load", VXGE_DRIVER_NAME);
+		ret = -EINVAL;
+		goto _exit4;
+	}
+
 	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
 
 	/* set private device info */
@@ -4387,6 +4357,27 @@ vxge_probe(struct pci_dev *pdev, const s
 	}
 
 	kfree(device_config);
+
+	/*
+	 * INTA is shared in multi-function mode. This is unlike the INTA
+	 * implementation in MR mode, where each VH has its own INTA message.
+	 * - INTA is masked (disabled) as long as at least one function sets
+	 * its TITAN_MASK_ALL_INT.ALARM bit.
+	 * - INTA is unmasked (enabled) when all enabled functions have cleared
+	 * their own TITAN_MASK_ALL_INT.ALARM bit.
+	 * The TITAN_MASK_ALL_INT ALARM & TRAFFIC bits are cleared on power up.
+	 * Though this driver leaves the top level interrupts unmasked while
+	 * leaving the required module interrupt bits masked on exit, there
+	 * could be a rougue driver around that does not follow this procedure
+	 * resulting in a failure to generate interrupts. The following code is
+	 * present to prevent such a failure.
+	 */
+
+	if (ll_config.device_hw_info.function_mode ==
+		VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION)
+		if (vdev->config.intr_type == INTA)
+			vxge_hw_device_unmask_all(hldev);
+
 	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d  Exiting...",
 		vdev->ndev->name, __func__, __LINE__);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-main.h linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.h
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-main.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-main.h	2010-02-24 13:52:17.000000000 -0500
@@ -112,7 +112,6 @@ enum vxge_mac_addr_state {
 struct vxge_drv_config {
 	int config_dev_cnt;
 	int total_dev_cnt;
-	unsigned long inta_dev_open;
 	int g_no_cpus;
 	unsigned int vpath_per_dev;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-reg.h linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -4326,10 +4326,6 @@ struct vxge_hw_vpath_reg {
 /*0x011e0*/	u64	umq_bwr_init_byte;
 #define VXGE_HW_UMQ_BWR_INIT_BYTE_COUNT(val) vxge_vBIT(val, 0, 32)
 /*0x011e8*/	u64	gendma_int;
-#define	VXGE_HW_GENDMA_INT_IMMED_ENABLE	vxge_mBIT(6)
-#define	VXGE_HW_GENDMA_INT_EVENT_ENABLE	vxge_mBIT(7)
-#define VXGE_HW_GENDMA_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
-#define VXGE_HW_GENDMA_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
 /*0x011f0*/	u64	umqdmq_ir_init_notify;
 #define	VXGE_HW_UMQDMQ_IR_INIT_NOTIFY_PULSE	vxge_mBIT(3)
 /*0x011f8*/	u64	dmq_init_notify;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-traffic.c linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-traffic.c
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-traffic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-traffic.c	2010-02-24 13:52:17.000000000 -0500
@@ -295,6 +295,8 @@ void vxge_hw_device_intr_enable(struct _
 	u64 val64;
 	u32 val32;
 
+	vxge_hw_device_mask_all(hldev);
+
 	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
 
 		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
@@ -1232,7 +1234,7 @@ void vxge_hw_fifo_txdl_post(struct __vxg
 	vxge_hw_channel_dtr_post(&fifo->channel, txdlh);
 
 	__vxge_hw_non_offload_db_post(fifo,
-		(u64)(size_t)txdl_priv->dma_addr,
+		(u64)txdl_priv->dma_addr,
 		txdl_priv->frags - 1,
 		fifo->no_snoop_bits);
 
@@ -1961,14 +1963,14 @@ enum vxge_hw_status __vxge_hw_vpath_alar
 			val64 = readq(&vp_reg->asic_ntwk_vp_err_reg);
 
 			if (((val64 &
-				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) &&
-			    (!(val64 &
+			      VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) &&
+			     (!(val64 &
 				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) ||
 			    ((val64 &
-				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
-				&& (!(val64 &
+			      VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR) &&
+			     (!(val64 &
 				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
-			))) {
+				     ))) {
 				sw_stats->error_stats.network_sustained_fault++;
 
 				writeq(
@@ -1981,14 +1983,14 @@ enum vxge_hw_status __vxge_hw_vpath_alar
 			}
 
 			if (((val64 &
-				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) &&
-			    (!(val64 &
+			      VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) &&
+			     (!(val64 &
 				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) ||
 			    ((val64 &
-				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
-				&& (!(val64 &
+			      VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR) &&
+			     (!(val64 &
 				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
-			))) {
+				     ))) {
 
 				sw_stats->error_stats.network_sustained_ok++;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-traffic.h linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-traffic.h
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-traffic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-traffic.h	2010-02-24 13:52:17.000000000 -0500
@@ -2389,6 +2389,8 @@ vxge_hw_channel_dtr_free(struct __vxge_h
 
 int
 vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel);
+void
+vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id);
 
 /* ========================== PRIVATE API ================================= */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-version.h linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-version.h
--- linux-libre-2.6.32-gnu1/drivers/net/vxge/vxge-version.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/vxge/vxge-version.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,7 @@
 
 #define VXGE_VERSION_MAJOR	"2"
 #define VXGE_VERSION_MINOR	"0"
-#define VXGE_VERSION_FIX	"5"
-#define VXGE_VERSION_BUILD	"18053"
+#define VXGE_VERSION_FIX	"6"
+#define VXGE_VERSION_BUILD	"18937"
 #define VXGE_VERSION_FOR	"k"
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/cosa.c linux-libre-2.6.33-gnu1/drivers/net/wan/cosa.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/cosa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/cosa.c	2010-02-24 13:52:17.000000000 -0500
@@ -297,8 +297,8 @@ static ssize_t cosa_write(struct file *f
 static unsigned int cosa_poll(struct file *file, poll_table *poll);
 static int cosa_open(struct inode *inode, struct file *file);
 static int cosa_release(struct inode *inode, struct file *file);
-static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg);
+static long cosa_chardev_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg);
 #ifdef COSA_FASYNC_WORKING
 static int cosa_fasync(struct inode *inode, struct file *file, int on);
 #endif
@@ -309,7 +309,7 @@ static const struct file_operations cosa
 	.read		= cosa_read,
 	.write		= cosa_write,
 	.poll		= cosa_poll,
-	.ioctl		= cosa_chardev_ioctl,
+	.unlocked_ioctl	= cosa_chardev_ioctl,
 	.open		= cosa_open,
 	.release	= cosa_release,
 #ifdef COSA_FASYNC_WORKING
@@ -1205,12 +1205,18 @@ static int cosa_net_ioctl(struct net_dev
 	return hdlc_ioctl(dev, ifr, cmd);
 }
 
-static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg)
+static long cosa_chardev_ioctl(struct file *file, unsigned int cmd,
+							unsigned long arg)
 {
 	struct channel_data *channel = file->private_data;
-	struct cosa_data *cosa = channel->cosa;
-	return cosa_ioctl_common(cosa, channel, cmd, arg);
+	struct cosa_data *cosa;
+	long ret;
+
+	lock_kernel();
+	cosa = channel->cosa;
+	ret = cosa_ioctl_common(cosa, channel, cmd, arg);
+	unlock_kernel();
+	return ret;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/dlci.c linux-libre-2.6.33-gnu1/drivers/net/wan/dlci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/dlci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/dlci.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,7 +77,7 @@ static int dlci_header(struct sk_buff *s
 	dlp = netdev_priv(dev);
 
 	hdr.control = FRAD_I_UI;
-	switch(type)
+	switch (type)
 	{
 		case ETH_P_IP:
 			hdr.IP_NLPID = FRAD_P_IP;
@@ -130,7 +130,7 @@ static void dlci_receive(struct sk_buff
 		dev->stats.rx_errors++;
 	}
 	else
-		switch(hdr->IP_NLPID)
+		switch (hdr->IP_NLPID)
 		{
 			case FRAD_P_PADDING:
 				if (hdr->NLPID != FRAD_P_SNAP)
@@ -208,7 +208,7 @@ static int dlci_config(struct net_device
 
 	if (!get)
 	{
-		if(copy_from_user(&config, conf, sizeof(struct dlci_conf)))
+		if (copy_from_user(&config, conf, sizeof(struct dlci_conf)))
 			return -EFAULT;
 		if (config.flags & ~DLCI_VALID_FLAGS)
 			return(-EINVAL);
@@ -222,7 +222,7 @@ static int dlci_config(struct net_device
 
 	if (get)
 	{
-		if(copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf)))
+		if (copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf)))
 			return -EFAULT;
 	}
 
@@ -238,7 +238,7 @@ static int dlci_dev_ioctl(struct net_dev
 
 	dlp = netdev_priv(dev);
 
-	switch(cmd)
+	switch (cmd)
 	{
 		case DLCI_GET_SLAVE:
 			if (!*(short *)(dev->dev_addr))
@@ -417,7 +417,7 @@ static int dlci_ioctl(unsigned int cmd,
 	if (!capable(CAP_NET_ADMIN))
 		return(-EPERM);
 
-	if(copy_from_user(&add, arg, sizeof(struct dlci_add)))
+	if (copy_from_user(&add, arg, sizeof(struct dlci_add)))
 		return -EFAULT;
 
 	switch (cmd)
@@ -426,7 +426,7 @@ static int dlci_ioctl(unsigned int cmd,
 			err = dlci_add(&add);
 
 			if (!err)
-				if(copy_to_user(arg, &add, sizeof(struct dlci_add)))
+				if (copy_to_user(arg, &add, sizeof(struct dlci_add)))
 					return -EFAULT;
 			break;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/dscc4.c linux-libre-2.6.33-gnu1/drivers/net/wan/dscc4.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/dscc4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/dscc4.c	2010-02-24 13:52:17.000000000 -0500
@@ -1128,7 +1128,7 @@ done:
         init_timer(&dpriv->timer);
         dpriv->timer.expires = jiffies + 10*HZ;
         dpriv->timer.data = (unsigned long)dev;
-        dpriv->timer.function = &dscc4_timer;
+	dpriv->timer.function = dscc4_timer;
         add_timer(&dpriv->timer);
 	netif_carrier_on(dev);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/farsync.c linux-libre-2.6.33-gnu1/drivers/net/wan/farsync.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/farsync.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/farsync.c	2010-02-24 13:52:17.000000000 -0500
@@ -1346,8 +1346,8 @@ do_bottom_half_tx(struct fst_card_info *
 
 		dev = port_to_dev(port);
 		while (!(FST_RDB(card, txDescrRing[pi][port->txpos].bits) &
-			 DMA_OWN)
-		       && !(card->dmatx_in_progress)) {
+			 DMA_OWN) &&
+		       !(card->dmatx_in_progress)) {
 			/*
 			 * There doesn't seem to be a txdone event per-se
 			 * We seem to have to deduce it, by checking the DMA_OWN
@@ -1379,8 +1379,8 @@ do_bottom_half_tx(struct fst_card_info *
 				 */
 				FST_WRW(card, txDescrRing[pi][port->txpos].bcnt,
 					cnv_bcnt(skb->len));
-				if ((skb->len < FST_MIN_DMA_LEN)
-				    || (card->family == FST_FAMILY_TXP)) {
+				if ((skb->len < FST_MIN_DMA_LEN) ||
+				    (card->family == FST_FAMILY_TXP)) {
 					/* Enqueue the packet with normal io */
 					memcpy_toio(card->mem +
 						    BUF_OFFSET(txBuffer[pi]
@@ -2030,8 +2030,8 @@ fst_ioctl(struct net_device *dev, struct
 		/* Sanity check the parameters. We don't support partial writes
 		 * when going over the top
 		 */
-		if (wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE
-		    || wrthdr.size + wrthdr.offset > FST_MEMSIZE) {
+		if (wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE ||
+		    wrthdr.size + wrthdr.offset > FST_MEMSIZE) {
 			return -ENXIO;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/hdlc.c linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/hdlc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,7 +57,7 @@ static int hdlc_rcv(struct sk_buff *skb,
 {
 	struct hdlc_device *hdlc = dev_to_hdlc(dev);
 
-	if (dev_net(dev) != &init_net) {
+	if (!net_eq(dev_net(dev), &init_net)) {
 		kfree_skb(skb);
 		return 0;
 	}
@@ -102,7 +102,7 @@ static int hdlc_device_event(struct noti
 	unsigned long flags;
 	int on;
 
-	if (dev_net(dev) != &init_net)
+	if (!net_eq(dev_net(dev), &init_net))
 		return NOTIFY_DONE;
 
 	if (!(dev->priv_flags & IFF_WAN_HDLC))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/hdlc_fr.c linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_fr.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/hdlc_fr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/hdlc_fr.c	2010-02-24 13:52:17.000000000 -0500
@@ -182,7 +182,7 @@ static inline pvc_device* find_pvc(hdlc_
 		if (pvc->dlci == dlci)
 			return pvc;
 		if (pvc->dlci > dlci)
-			return NULL; /* the listed is sorted */
+			return NULL; /* the list is sorted */
 		pvc = pvc->next;
 	}
 
@@ -1214,10 +1214,10 @@ static int fr_ioctl(struct net_device *d
 		return 0;
 
 	case IF_PROTO_FR:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		if(dev->flags & IFF_UP)
+		if (dev->flags & IFF_UP)
 			return -EBUSY;
 
 		if (copy_from_user(&new_settings, fr_s, size))
@@ -1263,7 +1263,7 @@ static int fr_ioctl(struct net_device *d
 		if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
 			return -EINVAL;
 
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
 		if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/hostess_sv11.c linux-libre-2.6.33-gnu1/drivers/net/wan/hostess_sv11.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/hostess_sv11.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/hostess_sv11.c	2010-02-24 13:52:17.000000000 -0500
@@ -218,7 +218,7 @@ static struct z8530_dev *sv11_init(int i
 	/* We want a fast IRQ for this device. Actually we'd like an even faster
 	   IRQ ;) - This is one driver RtLinux is made for */
 
-	if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
+	if (request_irq(irq, z8530_interrupt, IRQF_DISABLED,
 			"Hostess SV11", sv) < 0) {
 		printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq);
 		goto err_irq;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/lmc/lmc_main.c linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/lmc/lmc_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/lmc/lmc_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -927,7 +927,7 @@ static int __devinit lmc_init_one(struct
         sc->lmc_media = &lmc_t1_media;
         break;
     default:
-	printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
+	printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name);
         break;
     }
 
@@ -1028,7 +1028,7 @@ static int lmc_open(struct net_device *d
     lmc_softreset (sc);
 
     /* Since we have to use PCI bus, this should work on x86,alpha,ppc */
-    if (request_irq (dev->irq, &lmc_interrupt, IRQF_SHARED, dev->name, dev)){
+    if (request_irq (dev->irq, lmc_interrupt, IRQF_SHARED, dev->name, dev)){
         printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
         lmc_trace(dev, "lmc_open irq failed out");
         return -EAGAIN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/n2.c linux-libre-2.6.33-gnu1/drivers/net/wan/n2.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/n2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/n2.c	2010-02-24 13:52:17.000000000 -0500
@@ -376,7 +376,7 @@ static int __init n2_run(unsigned long i
 	}
 	card->io = io;
 
-	if (request_irq(irq, &sca_intr, 0, devname, card)) {
+	if (request_irq(irq, sca_intr, 0, devname, card)) {
 		printk(KERN_ERR "n2: could not allocate IRQ\n");
 		n2_destroy_card(card);
 		return(-EBUSY);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/pc300_drv.c linux-libre-2.6.33-gnu1/drivers/net/wan/pc300_drv.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/pc300_drv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/pc300_drv.c	2010-02-24 13:52:17.000000000 -0500
@@ -514,8 +514,8 @@ static int dma_buf_read(pc300_t * card,
 				  RX_BD_ADDR(ch, chan->rx_first_bd));
 	while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
 		nchar = cpc_readw(&ptdescr->len);
-		if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT))
-		    || (nchar > BD_DEF_LEN)) {
+		if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) ||
+		    (nchar > BD_DEF_LEN)) {
 
 			if (nchar > BD_DEF_LEN)
 				status |= DST_RBIT;
@@ -1428,8 +1428,7 @@ static void falc_update_stats(pc300_t *
 
 		if (((conf->media == IF_IFACE_T1) &&
 		     (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) &&
-		     (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN)))
-		    ||
+		     (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) ||
 		    ((conf->media == IF_IFACE_E1) &&
 		     (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) {
 			pfalc->prbs = 2;
@@ -2285,8 +2284,8 @@ static void falc_e1_intr(pc300_t * card,
 		if (gis & GIS_ISR1) {
 			isr1 = cpc_readb(falcbase + F_REG(FISR1, ch));
 			if (isr1 & FISR1_XMB) {
-				if ((pfalc->xmb_cause & 2)
-				    && pfalc->multiframe_mode) {
+				if ((pfalc->xmb_cause & 2) &&
+				    pfalc->multiframe_mode) {
 					if (cpc_readb (falcbase + F_REG(FRS0, ch)) & 
 									(FRS0_LOS | FRS0_AIS | FRS0_LFA)) {
 						cpc_writeb(falcbase + F_REG(XSP, ch),
@@ -2639,9 +2638,9 @@ static int cpc_ioctl(struct net_device *
 						!(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR);
 					/* There is no DSR in HD64572 */
 				}
-				if (!arg
-				    || copy_to_user(arg, &pc300status, sizeof(pc300status_t)))
-						return -EINVAL;
+				if (!arg ||
+				    copy_to_user(arg, &pc300status, sizeof(pc300status_t)))
+					return -EINVAL;
 				return 0;
 			}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/sbni.c linux-libre-2.6.33-gnu1/drivers/net/wan/sbni.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/sbni.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/sbni.c	2010-02-24 13:52:17.000000000 -0500
@@ -195,9 +195,9 @@ static unsigned int  netcard_portlist[ ]
 static inline int __init
 sbni_isa_probe( struct net_device  *dev )
 {
-	if( dev->base_addr > 0x1ff
-	    &&  request_region( dev->base_addr, SBNI_IO_EXTENT, dev->name )
-	    &&  sbni_probe1( dev, dev->base_addr, dev->irq ) )
+	if( dev->base_addr > 0x1ff &&
+	    request_region( dev->base_addr, SBNI_IO_EXTENT, dev->name ) &&
+	    sbni_probe1( dev, dev->base_addr, dev->irq ) )
 
 		return  0;
 	else {
@@ -286,8 +286,8 @@ static int __init sbni_init(struct net_d
 
 	for( i = 0;  netcard_portlist[ i ];  ++i ) {
 		int  ioaddr = netcard_portlist[ i ];
-		if( request_region( ioaddr, SBNI_IO_EXTENT, dev->name )
-		    &&  sbni_probe1( dev, ioaddr, 0 ))
+		if( request_region( ioaddr, SBNI_IO_EXTENT, dev->name ) &&
+		    sbni_probe1( dev, ioaddr, 0 ))
 			return 0;
 	}
 
@@ -306,9 +306,9 @@ sbni_pci_probe( struct net_device  *dev
 		unsigned long  pci_ioaddr;
 		u16  subsys;
 
-		if( pdev->vendor != SBNI_PCI_VENDOR
-		    &&  pdev->device != SBNI_PCI_DEVICE )
-				continue;
+		if( pdev->vendor != SBNI_PCI_VENDOR &&
+		    pdev->device != SBNI_PCI_DEVICE )
+			continue;
 
 		pci_ioaddr = pci_resource_start( pdev, 0 );
 		pci_irq_line = pdev->irq;
@@ -977,8 +977,8 @@ check_fhdr( u32  ioaddr,  u32  *framelen
 	*ack = *framelen & FRAME_ACK_MASK;
 	*is_first = (*framelen & FRAME_FIRST) != 0;
 
-	if( (*framelen &= FRAME_LEN_MASK) < 6
-	    ||  *framelen > SBNI_MAX_FRAME - 3 )
+	if( (*framelen &= FRAME_LEN_MASK) < 6 ||
+	    *framelen > SBNI_MAX_FRAME - 3 )
 		return  0;
 
 	value = inb( ioaddr + DAT );
@@ -1173,10 +1173,10 @@ sbni_open( struct net_device  *dev )
 	if( dev->base_addr < 0x400 ) {		/* ISA only */
 		struct net_device  **p = sbni_cards;
 		for( ;  *p  &&  p < sbni_cards + SBNI_MAX_NUM_CARDS;  ++p )
-			if( (*p)->irq == dev->irq
-			    &&  ((*p)->base_addr == dev->base_addr + 4
-				 ||  (*p)->base_addr == dev->base_addr - 4)
-			    &&  (*p)->flags & IFF_UP ) {
+			if( (*p)->irq == dev->irq &&
+			    ((*p)->base_addr == dev->base_addr + 4 ||
+			     (*p)->base_addr == dev->base_addr - 4) &&
+			    (*p)->flags & IFF_UP ) {
 
 				((struct net_local *) (netdev_priv(*p)))
 					->second = dev;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/sdla.c linux-libre-2.6.33-gnu1/drivers/net/wan/sdla.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/sdla.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/sdla.c	2010-02-24 13:52:17.000000000 -0500
@@ -1457,7 +1457,7 @@ got_type:
 	}
 
 	err = -EAGAIN;
-	if (request_irq(dev->irq, &sdla_isr, 0, dev->name, dev)) 
+	if (request_irq(dev->irq, sdla_isr, 0, dev->name, dev)) 
 		goto fail;
 
 	if (flp->type == SDLA_S507) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/sealevel.c linux-libre-2.6.33-gnu1/drivers/net/wan/sealevel.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/sealevel.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/sealevel.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,8 +84,7 @@ static int sealevel_open(struct net_devi
 	 *	Link layer up.
 	 */
 
-	switch (unit)
-	{
+	switch (unit) {
 		case 0:
 			err = z8530_sync_dma_open(d, slvl->chan);
 			break;
@@ -133,8 +132,7 @@ static int sealevel_close(struct net_dev
 	hdlc_close(d);
 	netif_stop_queue(d);
 
-	switch (unit)
-	{
+	switch (unit) {
 		case 0:
 			z8530_sync_dma_close(d, slvl->chan);
 			break;
@@ -266,7 +264,7 @@ static __init struct slvl_board *slvl_in
 	/* We want a fast IRQ for this device. Actually we'd like an even faster
 	   IRQ ;) - This is one driver RtLinux is made for */
 
-	if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
+	if (request_irq(irq, z8530_interrupt, IRQF_DISABLED,
 			"SeaLevel", dev) < 0) {
 		printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq);
 		goto err_request_irq;
@@ -342,8 +340,7 @@ static void __exit slvl_shutdown(struct
 
 	z8530_shutdown(&b->board);
 
-	for (u = 0; u < 2; u++)
-	{
+	for (u = 0; u < 2; u++) {
 		struct net_device *d = b->dev[u].chan->netdevice;
 		unregister_hdlc_device(d);
 		free_netdev(d);
@@ -391,7 +388,7 @@ static int __init slvl_init_module(void)
 
 static void __exit slvl_cleanup_module(void)
 {
-	if(slvl_unit)
+	if (slvl_unit)
 		slvl_shutdown(slvl_unit);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wan/x25_asy.c linux-libre-2.6.33-gnu1/drivers/net/wan/x25_asy.c
--- linux-libre-2.6.32-gnu1/drivers/net/wan/x25_asy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wan/x25_asy.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #include <linux/lapb.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
+#include <linux/compat.h>
 #include "x25_asy.h"
 
 #include <net/x25device.h>
@@ -656,8 +657,8 @@ static void x25_asy_unesc(struct x25_asy
 
 	switch (s) {
 	case X25_END:
-		if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
-			&& sl->rcount > 2)
+		if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+		    sl->rcount > 2)
 			x25_asy_bump(sl);
 		clear_bit(SLF_ESCAPE, &sl->flags);
 		sl->rcount = 0;
@@ -705,6 +706,21 @@ static int x25_asy_ioctl(struct tty_stru
 	}
 }
 
+#ifdef CONFIG_COMPAT
+static long x25_asy_compat_ioctl(struct tty_struct *tty, struct file *file,
+			 unsigned int cmd,  unsigned long arg)
+{
+	switch (cmd) {
+	case SIOCGIFNAME:
+	case SIOCSIFHWADDR:
+		return x25_asy_ioctl(tty, file, cmd,
+				     (unsigned long)compat_ptr(arg));
+	}
+
+	return -ENOIOCTLCMD;
+}
+#endif
+
 static int x25_asy_open_dev(struct net_device *dev)
 {
 	struct x25_asy *sl = netdev_priv(dev);
@@ -754,6 +770,9 @@ static struct tty_ldisc_ops x25_ldisc =
 	.open		= x25_asy_open_tty,
 	.close		= x25_asy_close_tty,
 	.ioctl		= x25_asy_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= x25_asy_compat_ioctl,
+#endif
 	.receive_buf	= x25_asy_receive_buf,
 	.write_wakeup	= x25_asy_write_wakeup,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/control.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/control.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/control.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/control.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@
  *   i2400m_set_init_config()
  *   i2400m_cmd_get_state()
  * i2400m_dev_shutdown()        Called by i2400m_dev_stop()
- *   i2400m->bus_reset()
+ *   i2400m_reset()
  *
  * i2400m_{cmd,get,set}_*()
  *   i2400m_msg_to_dev()
@@ -82,6 +82,13 @@
 #define D_SUBMODULE control
 #include "debug-levels.h"
 
+int i2400m_passive_mode;	/* 0 (passive mode disabled) by default */
+module_param_named(passive_mode, i2400m_passive_mode, int, 0644);
+MODULE_PARM_DESC(passive_mode,
+		 "If true, the driver will not do any device setup "
+		 "and leave it up to user space, who must be properly "
+		 "setup.");
+
 
 /*
  * Return if a TLV is of a give type and size
@@ -263,7 +270,7 @@ int i2400m_msg_check_status(const struct
 
 	if (status == 0)
 		return 0;
-	if (status > ARRAY_SIZE(ms_to_errno)) {
+	if (status >= ARRAY_SIZE(ms_to_errno)) {
 		str = "unknown status code";
 		result = -EBADR;
 	} else {
@@ -336,7 +343,7 @@ void i2400m_report_tlv_system_state(stru
 		/* Huh? just in case, shut it down */
 		dev_err(dev, "HW BUG? unknown state %u: shutting down\n",
 			i2400m_state);
-		i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+		i2400m_reset(i2400m, I2400M_RT_WARM);
 		break;
 	};
 	d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
@@ -1335,6 +1342,8 @@ int i2400m_dev_initialize(struct i2400m
 	unsigned argc = 0;
 
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
+	if (i2400m_passive_mode)
+		goto out_passive;
 	/* Disable idle mode? (enabled by default) */
 	if (i2400m_idle_mode_disabled) {
 		if (i2400m_le_v1_3(i2400m)) {
@@ -1377,6 +1386,7 @@ int i2400m_dev_initialize(struct i2400m
 	result = i2400m_set_init_config(i2400m, args, argc);
 	if (result < 0)
 		goto error;
+out_passive:
 	/*
 	 * Update state: Here it just calls a get state; parsing the
 	 * result (System State TLV and RF Status TLV [done in the rx
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/debugfs.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,7 @@ int debugfs_i2400m_reset_set(void *data,
 	case I2400M_RT_WARM:
 	case I2400M_RT_COLD:
 	case I2400M_RT_BUS:
-		result = i2400m->bus_reset(i2400m, rt);
+		result = i2400m_reset(i2400m, rt);
 		if (result >= 0)
 			result = 0;
 	default:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/driver.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/driver.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/driver.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/driver.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,8 +41,10 @@
  *     __i2400m_dev_start()
  *
  * i2400m_setup()
+ *   i2400m->bus_setup()
  *   i2400m_bootrom_init()
  *   register_netdev()
+ *   wimax_dev_add()
  *   i2400m_dev_start()
  *     __i2400m_dev_start()
  *       i2400m_dev_bootstrap()
@@ -50,15 +52,15 @@
  *       i2400m->bus_dev_start()
  *       i2400m_firmware_check()
  *       i2400m_check_mac_addr()
- *   wimax_dev_add()
  *
  * i2400m_release()
- *   wimax_dev_rm()
  *   i2400m_dev_stop()
  *     __i2400m_dev_stop()
  *       i2400m_dev_shutdown()
  *       i2400m->bus_dev_stop()
  *       i2400m_tx_release()
+ *   i2400m->bus_release()
+ *   wimax_dev_rm()
  *   unregister_netdev()
  */
 #include "i2400m.h"
@@ -66,6 +68,7 @@
 #include <linux/wimax/i2400m.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/suspend.h>
 
 #define D_SUBMODULE driver
 #include "debug-levels.h"
@@ -90,76 +93,39 @@ MODULE_PARM_DESC(power_save_disabled,
 		 "False by default (so the device is told to do power "
 		 "saving).");
 
-/**
- * i2400m_queue_work - schedule work on a i2400m's queue
- *
- * @i2400m: device descriptor
- *
- * @fn: function to run to execute work. It gets passed a 'struct
- *     work_struct' that is wrapped in a 'struct i2400m_work'. Once
- *     done, you have to (1) i2400m_put(i2400m_work->i2400m) and then
- *     (2) kfree(i2400m_work).
- *
- * @gfp_flags: GFP flags for memory allocation.
- *
- * @pl: pointer to a payload buffer that you want to pass to the _work
- *     function. Use this to pack (for example) a struct with extra
- *     arguments.
- *
- * @pl_size: size of the payload buffer.
- *
- * We do this quite often, so this just saves typing; allocate a
- * wrapper for a i2400m, get a ref to it, pack arguments and launch
- * the work.
- *
- * A usual workflow is:
- *
- * struct my_work_args {
- *         void *something;
- *         int whatever;
- * };
- * ...
- *
- * struct my_work_args my_args = {
- *         .something = FOO,
- *         .whaetever = BLAH
- * };
- * i2400m_queue_work(i2400m, 1, my_work_function, GFP_KERNEL,
- *                   &args, sizeof(args))
- *
- * And now the work function can unpack the arguments and call the
- * real function (or do the job itself):
- *
- * static
- * void my_work_fn((struct work_struct *ws)
- * {
- *         struct i2400m_work *iw =
- *	           container_of(ws, struct i2400m_work, ws);
- *	   struct my_work_args *my_args = (void *) iw->pl;
- *
- *	   my_work(iw->i2400m, my_args->something, my_args->whatevert);
- * }
- */
-int i2400m_queue_work(struct i2400m *i2400m,
-		      void (*fn)(struct work_struct *), gfp_t gfp_flags,
-		      const void *pl, size_t pl_size)
+static char i2400m_debug_params[128];
+module_param_string(debug, i2400m_debug_params, sizeof(i2400m_debug_params),
+		    0644);
+MODULE_PARM_DESC(debug,
+		 "String of space-separated NAME:VALUE pairs, where NAMEs "
+		 "are the different debug submodules and VALUE are the "
+		 "initial debug value to set.");
+
+static char i2400m_barkers_params[128];
+module_param_string(barkers, i2400m_barkers_params,
+		    sizeof(i2400m_barkers_params), 0644);
+MODULE_PARM_DESC(barkers,
+		 "String of comma-separated 32-bit values; each is "
+		 "recognized as the value the device sends as a reboot "
+		 "signal; values are appended to a list--setting one value "
+		 "as zero cleans the existing list and starts a new one.");
+
+static
+struct i2400m_work *__i2400m_work_setup(
+	struct i2400m *i2400m, void (*fn)(struct work_struct *),
+	gfp_t gfp_flags, const void *pl, size_t pl_size)
 {
-	int result;
 	struct i2400m_work *iw;
 
-	BUG_ON(i2400m->work_queue == NULL);
-	result = -ENOMEM;
 	iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags);
 	if (iw == NULL)
-		goto error_kzalloc;
+		return NULL;
 	iw->i2400m = i2400m_get(i2400m);
+	iw->pl_size = pl_size;
 	memcpy(iw->pl, pl, pl_size);
 	INIT_WORK(&iw->ws, fn);
-	result = queue_work(i2400m->work_queue, &iw->ws);
-error_kzalloc:
-	return result;
+	return iw;
 }
-EXPORT_SYMBOL_GPL(i2400m_queue_work);
 
 
 /*
@@ -175,21 +141,19 @@ EXPORT_SYMBOL_GPL(i2400m_queue_work);
  * it should not happen.
  */
 int i2400m_schedule_work(struct i2400m *i2400m,
-			 void (*fn)(struct work_struct *), gfp_t gfp_flags)
+			 void (*fn)(struct work_struct *), gfp_t gfp_flags,
+			 const void *pl, size_t pl_size)
 {
 	int result;
 	struct i2400m_work *iw;
 
 	result = -ENOMEM;
-	iw = kzalloc(sizeof(*iw), gfp_flags);
-	if (iw == NULL)
-		goto error_kzalloc;
-	iw->i2400m = i2400m_get(i2400m);
-	INIT_WORK(&iw->ws, fn);
-	result = schedule_work(&iw->ws);
-	if (result == 0)
-		result = -ENXIO;
-error_kzalloc:
+	iw = __i2400m_work_setup(i2400m, fn, gfp_flags, pl, pl_size);
+	if (iw != NULL) {
+		result = schedule_work(&iw->ws);
+		if (WARN_ON(result == 0))
+			result = -ENXIO;
+	}
 	return result;
 }
 
@@ -291,7 +255,7 @@ int i2400m_op_reset(struct wimax_dev *wi
 	mutex_lock(&i2400m->init_mutex);
 	i2400m->reset_ctx = &ctx;
 	mutex_unlock(&i2400m->init_mutex);
-	result = i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+	result = i2400m_reset(i2400m, I2400M_RT_WARM);
 	if (result < 0)
 		goto out;
 	result = wait_for_completion_timeout(&ctx.completion, 4*HZ);
@@ -420,9 +384,15 @@ retry:
 		dev_err(dev, "cannot create workqueue\n");
 		goto error_create_workqueue;
 	}
-	result = i2400m->bus_dev_start(i2400m);
-	if (result < 0)
-		goto error_bus_dev_start;
+	if (i2400m->bus_dev_start) {
+		result = i2400m->bus_dev_start(i2400m);
+		if (result < 0)
+			goto error_bus_dev_start;
+	}
+	i2400m->ready = 1;
+	wmb();		/* see i2400m->ready's documentation  */
+	/* process pending reports from the device */
+	queue_work(i2400m->work_queue, &i2400m->rx_report_ws);
 	result = i2400m_firmware_check(i2400m);	/* fw versions ok? */
 	if (result < 0)
 		goto error_fw_check;
@@ -430,8 +400,6 @@ retry:
 	result = i2400m_check_mac_addr(i2400m);
 	if (result < 0)
 		goto error_check_mac_addr;
-	i2400m->ready = 1;
-	wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED);
 	result = i2400m_dev_initialize(i2400m);
 	if (result < 0)
 		goto error_dev_initialize;
@@ -443,8 +411,12 @@ retry:
 
 error_dev_initialize:
 error_check_mac_addr:
+	i2400m->ready = 0;
+	wmb();		/* see i2400m->ready's documentation  */
+	flush_workqueue(i2400m->work_queue);
 error_fw_check:
-	i2400m->bus_dev_stop(i2400m);
+	if (i2400m->bus_dev_stop)
+		i2400m->bus_dev_stop(i2400m);
 error_bus_dev_start:
 	destroy_workqueue(i2400m->work_queue);
 error_create_workqueue:
@@ -466,11 +438,15 @@ error_bootstrap:
 static
 int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
 {
-	int result;
+	int result = 0;
 	mutex_lock(&i2400m->init_mutex);	/* Well, start the device */
-	result = __i2400m_dev_start(i2400m, bm_flags);
-	if (result >= 0)
-		i2400m->updown = 1;
+	if (i2400m->updown == 0) {
+		result = __i2400m_dev_start(i2400m, bm_flags);
+		if (result >= 0) {
+			i2400m->updown = 1;
+			wmb();	/* see i2400m->updown's documentation */
+		}
+	}
 	mutex_unlock(&i2400m->init_mutex);
 	return result;
 }
@@ -495,9 +471,20 @@ void __i2400m_dev_stop(struct i2400m *i2
 
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
 	wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
+	i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
+	complete(&i2400m->msg_completion);
+	i2400m_net_wake_stop(i2400m);
 	i2400m_dev_shutdown(i2400m);
-	i2400m->ready = 0;
-	i2400m->bus_dev_stop(i2400m);
+	/*
+	 * Make sure no report hooks are running *before* we stop the
+	 * communication infrastructure with the device.
+	 */
+	i2400m->ready = 0;	/* nobody can queue work anymore */
+	wmb();		/* see i2400m->ready's documentation  */
+	flush_workqueue(i2400m->work_queue);
+
+	if (i2400m->bus_dev_stop)
+		i2400m->bus_dev_stop(i2400m);
 	destroy_workqueue(i2400m->work_queue);
 	i2400m_rx_release(i2400m);
 	i2400m_tx_release(i2400m);
@@ -518,9 +505,136 @@ void i2400m_dev_stop(struct i2400m *i240
 	if (i2400m->updown) {
 		__i2400m_dev_stop(i2400m);
 		i2400m->updown = 0;
+		wmb();	/* see i2400m->updown's documentation  */
+	}
+	mutex_unlock(&i2400m->init_mutex);
+}
+
+
+/*
+ * Listen to PM events to cache the firmware before suspend/hibernation
+ *
+ * When the device comes out of suspend, it might go into reset and
+ * firmware has to be uploaded again. At resume, most of the times, we
+ * can't load firmware images from disk, so we need to cache it.
+ *
+ * i2400m_fw_cache() will allocate a kobject and attach the firmware
+ * to it; that way we don't have to worry too much about the fw loader
+ * hitting a race condition.
+ *
+ * Note: modus operandi stolen from the Orinoco driver; thx.
+ */
+static
+int i2400m_pm_notifier(struct notifier_block *notifier,
+		       unsigned long pm_event,
+		       void *unused)
+{
+	struct i2400m *i2400m =
+		container_of(notifier, struct i2400m, pm_notifier);
+	struct device *dev = i2400m_dev(i2400m);
+
+	d_fnstart(3, dev, "(i2400m %p pm_event %lx)\n", i2400m, pm_event);
+	switch (pm_event) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		i2400m_fw_cache(i2400m);
+		break;
+	case PM_POST_RESTORE:
+		/* Restore from hibernation failed. We need to clean
+		 * up in exactly the same way, so fall through. */
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		i2400m_fw_uncache(i2400m);
+		break;
+
+	case PM_RESTORE_PREPARE:
+	default:
+		break;
+	}
+	d_fnend(3, dev, "(i2400m %p pm_event %lx) = void\n", i2400m, pm_event);
+	return NOTIFY_DONE;
+}
+
+
+/*
+ * pre-reset is called before a device is going on reset
+ *
+ * This has to be followed by a call to i2400m_post_reset(), otherwise
+ * bad things might happen.
+ */
+int i2400m_pre_reset(struct i2400m *i2400m)
+{
+	int result;
+	struct device *dev = i2400m_dev(i2400m);
+
+	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
+	d_printf(1, dev, "pre-reset shut down\n");
+
+	result = 0;
+	mutex_lock(&i2400m->init_mutex);
+	if (i2400m->updown) {
+		netif_tx_disable(i2400m->wimax_dev.net_dev);
+		__i2400m_dev_stop(i2400m);
+		result = 0;
+		/* down't set updown to zero -- this way
+		 * post_reset can restore properly */
+	}
+	mutex_unlock(&i2400m->init_mutex);
+	if (i2400m->bus_release)
+		i2400m->bus_release(i2400m);
+	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
+	return result;
+}
+EXPORT_SYMBOL_GPL(i2400m_pre_reset);
+
+
+/*
+ * Restore device state after a reset
+ *
+ * Do the work needed after a device reset to bring it up to the same
+ * state as it was before the reset.
+ *
+ * NOTE: this requires i2400m->init_mutex taken
+ */
+int i2400m_post_reset(struct i2400m *i2400m)
+{
+	int result = 0;
+	struct device *dev = i2400m_dev(i2400m);
+
+	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
+	d_printf(1, dev, "post-reset start\n");
+	if (i2400m->bus_setup) {
+		result = i2400m->bus_setup(i2400m);
+		if (result < 0) {
+			dev_err(dev, "bus-specific setup failed: %d\n",
+				result);
+			goto error_bus_setup;
+		}
+	}
+	mutex_lock(&i2400m->init_mutex);
+	if (i2400m->updown) {
+		result = __i2400m_dev_start(
+			i2400m, I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT);
+		if (result < 0)
+			goto error_dev_start;
 	}
 	mutex_unlock(&i2400m->init_mutex);
+	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
+	return result;
+
+error_dev_start:
+	if (i2400m->bus_release)
+		i2400m->bus_release(i2400m);
+error_bus_setup:
+	/* even if the device was up, it could not be recovered, so we
+	 * mark it as down. */
+	i2400m->updown = 0;
+	wmb();		/* see i2400m->updown's documentation  */
+	mutex_unlock(&i2400m->init_mutex);
+	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
+	return result;
 }
+EXPORT_SYMBOL_GPL(i2400m_post_reset);
 
 
 /*
@@ -542,56 +656,69 @@ void i2400m_dev_stop(struct i2400m *i240
  *       _stop()], don't do anything, let it fail and handle it.
  *
  * This function is ran always in a thread context
+ *
+ * This function gets passed, as payload to i2400m_work() a 'const
+ * char *' ptr with a "reason" why the reset happened (for messages).
  */
 static
 void __i2400m_dev_reset_handle(struct work_struct *ws)
 {
 	int result;
 	struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
+	const char *reason;
 	struct i2400m *i2400m = iw->i2400m;
 	struct device *dev = i2400m_dev(i2400m);
-	enum wimax_st wimax_state;
 	struct i2400m_reset_ctx *ctx = i2400m->reset_ctx;
 
-	d_fnstart(3, dev, "(ws %p i2400m %p)\n", ws, i2400m);
+	if (WARN_ON(iw->pl_size != sizeof(reason)))
+		reason = "SW BUG: reason n/a";
+	else
+		memcpy(&reason, iw->pl, sizeof(reason));
+
+	d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason);
+
 	result = 0;
 	if (mutex_trylock(&i2400m->init_mutex) == 0) {
 		/* We are still in i2400m_dev_start() [let it fail] or
 		 * i2400m_dev_stop() [we are shutting down anyway, so
 		 * ignore it] or we are resetting somewhere else. */
-		dev_err(dev, "device rebooted\n");
+		dev_err(dev, "device rebooted somewhere else?\n");
 		i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
 		complete(&i2400m->msg_completion);
 		goto out;
 	}
-	wimax_state = wimax_state_get(&i2400m->wimax_dev);
-	if (wimax_state < WIMAX_ST_UNINITIALIZED) {
-		dev_info(dev, "device rebooted: it is down, ignoring\n");
-		goto out_unlock;	/* ifconfig up/down wasn't called */
+	if (i2400m->updown == 0)  {
+		dev_info(dev, "%s: device is down, doing nothing\n", reason);
+		goto out_unlock;
 	}
-	dev_err(dev, "device rebooted: reinitializing driver\n");
+	dev_err(dev, "%s: reinitializing driver\n", reason);
 	__i2400m_dev_stop(i2400m);
-	i2400m->updown = 0;
 	result = __i2400m_dev_start(i2400m,
 				    I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT);
 	if (result < 0) {
-		dev_err(dev, "device reboot: cannot start the device: %d\n",
-			result);
-		result = i2400m->bus_reset(i2400m, I2400M_RT_BUS);
-		if (result >= 0)
-			result = -ENODEV;
-	} else
-		i2400m->updown = 1;
+		i2400m->updown = 0;
+		wmb();		/* see i2400m->updown's documentation  */
+		dev_err(dev, "%s: cannot start the device: %d\n",
+			reason, result);
+		result = -EUCLEAN;
+	}
 out_unlock:
 	if (i2400m->reset_ctx) {
 		ctx->result = result;
 		complete(&ctx->completion);
 	}
 	mutex_unlock(&i2400m->init_mutex);
+	if (result == -EUCLEAN) {
+		/* ops, need to clean up [w/ init_mutex not held] */
+		result = i2400m_reset(i2400m, I2400M_RT_BUS);
+		if (result >= 0)
+			result = -ENODEV;
+	}
 out:
 	i2400m_put(i2400m);
 	kfree(iw);
-	d_fnend(3, dev, "(ws %p i2400m %p) = void\n", ws, i2400m);
+	d_fnend(3, dev, "(ws %p i2400m %p reason %s) = void\n",
+		ws, i2400m, reason);
 	return;
 }
 
@@ -608,16 +735,104 @@ out:
  * reinitializing the driver to handle the reset, calling into the
  * bus-specific functions ops as needed.
  */
-int i2400m_dev_reset_handle(struct i2400m *i2400m)
+int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason)
 {
 	i2400m->boot_mode = 1;
 	wmb();		/* Make sure i2400m_msg_to_dev() sees boot_mode */
 	return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
-				    GFP_ATOMIC);
+				    GFP_ATOMIC, &reason, sizeof(reason));
 }
 EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
 
 
+/*
+ * Alloc the command and ack buffers for boot mode
+ *
+ * Get the buffers needed to deal with boot mode messages.  These
+ * buffers need to be allocated before the sdio recieve irq is setup.
+ */
+static
+int i2400m_bm_buf_alloc(struct i2400m *i2400m)
+{
+	int result;
+
+	result = -ENOMEM;
+	i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
+	if (i2400m->bm_cmd_buf == NULL)
+		goto error_bm_cmd_kzalloc;
+	i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
+	if (i2400m->bm_ack_buf == NULL)
+		goto error_bm_ack_buf_kzalloc;
+	return 0;
+
+error_bm_ack_buf_kzalloc:
+	kfree(i2400m->bm_cmd_buf);
+error_bm_cmd_kzalloc:
+	return result;
+}
+
+
+/*
+ * Free boot mode command and ack buffers.
+ */
+static
+void i2400m_bm_buf_free(struct i2400m *i2400m)
+{
+	kfree(i2400m->bm_ack_buf);
+	kfree(i2400m->bm_cmd_buf);
+}
+
+
+/**
+ * i2400m_init - Initialize a 'struct i2400m' from all zeroes
+ *
+ * This is a bus-generic API call.
+ */
+void i2400m_init(struct i2400m *i2400m)
+{
+	wimax_dev_init(&i2400m->wimax_dev);
+
+	i2400m->boot_mode = 1;
+	i2400m->rx_reorder = 1;
+	init_waitqueue_head(&i2400m->state_wq);
+
+	spin_lock_init(&i2400m->tx_lock);
+	i2400m->tx_pl_min = UINT_MAX;
+	i2400m->tx_size_min = UINT_MAX;
+
+	spin_lock_init(&i2400m->rx_lock);
+	i2400m->rx_pl_min = UINT_MAX;
+	i2400m->rx_size_min = UINT_MAX;
+	INIT_LIST_HEAD(&i2400m->rx_reports);
+	INIT_WORK(&i2400m->rx_report_ws, i2400m_report_hook_work);
+
+	mutex_init(&i2400m->msg_mutex);
+	init_completion(&i2400m->msg_completion);
+
+	mutex_init(&i2400m->init_mutex);
+	/* wake_tx_ws is initialized in i2400m_tx_setup() */
+}
+EXPORT_SYMBOL_GPL(i2400m_init);
+
+
+int i2400m_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
+{
+	struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+
+	/*
+	 * Make sure we stop TXs and down the carrier before
+	 * resetting; this is needed to avoid things like
+	 * i2400m_wake_tx() scheduling stuff in parallel.
+	 */
+	if (net_dev->reg_state == NETREG_REGISTERED) {
+		netif_tx_disable(net_dev);
+		netif_carrier_off(net_dev);
+	}
+	return i2400m->bus_reset(i2400m, rt);
+}
+EXPORT_SYMBOL_GPL(i2400m_reset);
+
+
 /**
  * i2400m_setup - bus-generic setup function for the i2400m device
  *
@@ -625,13 +840,9 @@ EXPORT_SYMBOL_GPL(i2400m_dev_reset_handl
  *
  * Returns: 0 if ok, < 0 errno code on error.
  *
- * Initializes the bus-generic parts of the i2400m driver; the
- * bus-specific parts have been initialized, function pointers filled
- * out by the bus-specific probe function.
- *
- * As well, this registers the WiMAX and net device nodes. Once this
- * function returns, the device is operative and has to be ready to
- * receive and send network traffic and WiMAX control operations.
+ * Sets up basic device comunication infrastructure, boots the ROM to
+ * read the MAC address, registers with the WiMAX and network stacks
+ * and then brings up the device.
  */
 int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
 {
@@ -645,16 +856,21 @@ int i2400m_setup(struct i2400m *i2400m,
 	snprintf(wimax_dev->name, sizeof(wimax_dev->name),
 		 "i2400m-%s:%s", dev->bus->name, dev_name(dev));
 
-	i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
-	if (i2400m->bm_cmd_buf == NULL) {
-		dev_err(dev, "cannot allocate USB command buffer\n");
-		goto error_bm_cmd_kzalloc;
+	result = i2400m_bm_buf_alloc(i2400m);
+	if (result < 0) {
+		dev_err(dev, "cannot allocate bootmode scratch buffers\n");
+		goto error_bm_buf_alloc;
 	}
-	i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
-	if (i2400m->bm_ack_buf == NULL) {
-		dev_err(dev, "cannot allocate USB ack buffer\n");
-		goto error_bm_ack_buf_kzalloc;
+
+	if (i2400m->bus_setup) {
+		result = i2400m->bus_setup(i2400m);
+		if (result < 0) {
+			dev_err(dev, "bus-specific setup failed: %d\n",
+				result);
+			goto error_bus_setup;
+		}
 	}
+
 	result = i2400m_bootrom_init(i2400m, bm_flags);
 	if (result < 0) {
 		dev_err(dev, "read mac addr: bootrom init "
@@ -666,6 +882,9 @@ int i2400m_setup(struct i2400m *i2400m,
 		goto error_read_mac_addr;
 	random_ether_addr(i2400m->src_mac_addr);
 
+	i2400m->pm_notifier.notifier_call = i2400m_pm_notifier;
+	register_pm_notifier(&i2400m->pm_notifier);
+
 	result = register_netdev(net_dev);	/* Okey dokey, bring it up */
 	if (result < 0) {
 		dev_err(dev, "cannot register i2400m network device: %d\n",
@@ -674,18 +893,13 @@ int i2400m_setup(struct i2400m *i2400m,
 	}
 	netif_carrier_off(net_dev);
 
-	result = i2400m_dev_start(i2400m, bm_flags);
-	if (result < 0)
-		goto error_dev_start;
-
 	i2400m->wimax_dev.op_msg_from_user = i2400m_op_msg_from_user;
 	i2400m->wimax_dev.op_rfkill_sw_toggle = i2400m_op_rfkill_sw_toggle;
 	i2400m->wimax_dev.op_reset = i2400m_op_reset;
+
 	result = wimax_dev_add(&i2400m->wimax_dev, net_dev);
 	if (result < 0)
 		goto error_wimax_dev_add;
-	/* User space needs to do some init stuff */
-	wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED);
 
 	/* Now setup all that requires a registered net and wimax device. */
 	result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group);
@@ -693,30 +907,37 @@ int i2400m_setup(struct i2400m *i2400m,
 		dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result);
 		goto error_sysfs_setup;
 	}
+
 	result = i2400m_debugfs_add(i2400m);
 	if (result < 0) {
 		dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result);
 		goto error_debugfs_setup;
 	}
+
+	result = i2400m_dev_start(i2400m, bm_flags);
+	if (result < 0)
+		goto error_dev_start;
 	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
 	return result;
 
+error_dev_start:
+	i2400m_debugfs_rm(i2400m);
 error_debugfs_setup:
 	sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
 			   &i2400m_dev_attr_group);
 error_sysfs_setup:
 	wimax_dev_rm(&i2400m->wimax_dev);
 error_wimax_dev_add:
-	i2400m_dev_stop(i2400m);
-error_dev_start:
 	unregister_netdev(net_dev);
 error_register_netdev:
+	unregister_pm_notifier(&i2400m->pm_notifier);
 error_read_mac_addr:
 error_bootrom_init:
-	kfree(i2400m->bm_ack_buf);
-error_bm_ack_buf_kzalloc:
-	kfree(i2400m->bm_cmd_buf);
-error_bm_cmd_kzalloc:
+	if (i2400m->bus_release)
+		i2400m->bus_release(i2400m);
+error_bus_setup:
+	i2400m_bm_buf_free(i2400m);
+error_bm_buf_alloc:
 	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
 	return result;
 }
@@ -735,14 +956,17 @@ void i2400m_release(struct i2400m *i2400
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
 	netif_stop_queue(i2400m->wimax_dev.net_dev);
 
+	i2400m_dev_stop(i2400m);
+
 	i2400m_debugfs_rm(i2400m);
 	sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
 			   &i2400m_dev_attr_group);
 	wimax_dev_rm(&i2400m->wimax_dev);
-	i2400m_dev_stop(i2400m);
 	unregister_netdev(i2400m->wimax_dev.net_dev);
-	kfree(i2400m->bm_ack_buf);
-	kfree(i2400m->bm_cmd_buf);
+	unregister_pm_notifier(&i2400m->pm_notifier);
+	if (i2400m->bus_release)
+		i2400m->bus_release(i2400m);
+	i2400m_bm_buf_free(i2400m);
 	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
 }
 EXPORT_SYMBOL_GPL(i2400m_release);
@@ -759,6 +983,7 @@ struct d_level D_LEVEL[] = {
 	D_SUBMODULE_DEFINE(netdev),
 	D_SUBMODULE_DEFINE(rfkill),
 	D_SUBMODULE_DEFINE(rx),
+	D_SUBMODULE_DEFINE(sysfs),
 	D_SUBMODULE_DEFINE(tx),
 };
 size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
@@ -767,7 +992,9 @@ size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL
 static
 int __init i2400m_driver_init(void)
 {
-	return 0;
+	d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400m_debug_params,
+		       "i2400m.debug");
+	return i2400m_barker_db_init(i2400m_barkers_params);
 }
 module_init(i2400m_driver_init);
 
@@ -776,6 +1003,7 @@ void __exit i2400m_driver_exit(void)
 {
 	/* for scheds i2400m_dev_reset_handle() */
 	flush_scheduled_work();
+	i2400m_barker_db_exit();
 	return;
 }
 module_exit(i2400m_driver_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/fw.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 14:04:26.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 12:12:01.000000000 -0400
@@ -40,11 +40,9 @@
  *
  * THE PROCEDURE
  *
- * (this is decribed for USB, but for SDIO is similar)
- *
- * The 2400m works in two modes: boot-mode or normal mode. In boot
- * mode we can execute only a handful of commands targeted at
- * uploading the firmware and launching it.
+ * The 2400m and derived devices work in two modes: boot-mode or
+ * normal mode. In boot mode we can execute only a handful of commands
+ * targeted at uploading the firmware and launching it.
  *
  * The 2400m enters boot mode when it is first connected to the
  * system, when it crashes and when you ask it to reboot. There are
@@ -52,18 +50,26 @@
  * firmwares signed with a certain private key, non-signed takes any
  * firmware. Normal hardware takes only signed firmware.
  *
- * Upon entrance to boot mode, the device sends a few zero length
- * packets (ZLPs) on the notification endpoint, then a reboot barker
- * (4 le32 words with value I2400M_{S,N}BOOT_BARKER). We ack it by
- * sending the same barker on the bulk out endpoint. The device acks
- * with a reboot ack barker (4 le32 words with value 0xfeedbabe) and
- * then the device is fully rebooted. At this point we can upload the
- * firmware.
+ * On boot mode, in USB, we write to the device using the bulk out
+ * endpoint and read from it in the notification endpoint. In SDIO we
+ * talk to it via the write address and read from the read address.
+ *
+ * Upon entrance to boot mode, the device sends (preceeded with a few
+ * zero length packets (ZLPs) on the notification endpoint in USB) a
+ * reboot barker (4 le32 words with the same value). We ack it by
+ * sending the same barker to the device. The device acks with a
+ * reboot ack barker (4 le32 words with value I2400M_ACK_BARKER) and
+ * then is fully booted. At this point we can upload the firmware.
+ *
+ * Note that different iterations of the device and EEPROM
+ * configurations will send different [re]boot barkers; these are
+ * collected in i2400m_barker_db along with the firmware
+ * characteristics they require.
  *
  * This process is accomplished by the i2400m_bootrom_init()
  * function. All the device interaction happens through the
  * i2400m_bm_cmd() [boot mode command]. Special return values will
- * indicate if the device resets.
+ * indicate if the device did reset during the process.
  *
  * After this, we read the MAC address and then (if needed)
  * reinitialize the device. We need to read it ahead of time because
@@ -72,11 +78,11 @@
  *
  * We can then upload the firmware file. The file is composed of a BCF
  * header (basic data, keys and signatures) and a list of write
- * commands and payloads. We first upload the header
- * [i2400m_dnload_init()] and then pass the commands and payloads
- * verbatim to the i2400m_bm_cmd() function
- * [i2400m_dnload_bcf()]. Then we tell the device to jump to the new
- * firmware [i2400m_dnload_finalize()].
+ * commands and payloads. Optionally more BCF headers might follow the
+ * main payload. We first upload the header [i2400m_dnload_init()] and
+ * then pass the commands and payloads verbatim to the i2400m_bm_cmd()
+ * function [i2400m_dnload_bcf()]. Then we tell the device to jump to
+ * the new firmware [i2400m_dnload_finalize()].
  *
  * Once firmware is uploaded, we are good to go :)
  *
@@ -99,18 +105,32 @@
  * read an acknolwedgement from it (or an asynchronous notification)
  * from it.
  *
+ * FIRMWARE LOADING
+ *
+ * Note that in some cases, we can't just load a firmware file (for
+ * example, when resuming). For that, we might cache the firmware
+ * file. Thus, when doing the bootstrap, if there is a cache firmware
+ * file, it is used; if not, loading from disk is attempted.
+ *
  * ROADMAP
  *
+ * i2400m_barker_db_init              Called by i2400m_driver_init()
+ *   i2400m_barker_db_add
+ *
+ * i2400m_barker_db_exit              Called by i2400m_driver_exit()
+ *
  * i2400m_dev_bootstrap               Called by __i2400m_dev_start()
  *   reject_firmware
- *   i2400m_fw_check
- *   i2400m_fw_dnload
+ *   i2400m_fw_bootstrap
+ *     i2400m_fw_check
+ *       i2400m_fw_hdr_check
+ *     i2400m_fw_dnload
  *   release_firmware
  *
  * i2400m_fw_dnload
  *   i2400m_bootrom_init
  *     i2400m_bm_cmd
- *     i2400m->bus_reset
+ *     i2400m_reset
  *   i2400m_dnload_init
  *     i2400m_dnload_init_signed
  *     i2400m_dnload_init_nonsigned
@@ -125,9 +145,14 @@
  *   i2400m->bus_bm_cmd_send()
  *   i2400m->bus_bm_wait_for_ack
  *   __i2400m_bm_ack_verify
+ *     i2400m_is_boot_barker
  *
  * i2400m_bm_cmd_prepare              Used by bus-drivers to prep
  *                                    commands before sending
+ *
+ * i2400m_pm_notifier                 Called on Power Management events
+ *   i2400m_fw_cache
+ *   i2400m_fw_uncache
  */
 #include <linux/firmware.h>
 #include <linux/sched.h>
@@ -175,6 +200,240 @@ EXPORT_SYMBOL_GPL(i2400m_bm_cmd_prepare)
 
 
 /*
+ * Database of known barkers.
+ *
+ * A barker is what the device sends indicating he is ready to be
+ * bootloaded. Different versions of the device will send different
+ * barkers. Depending on the barker, it might mean the device wants
+ * some kind of firmware or the other.
+ */
+static struct i2400m_barker_db {
+	__le32 data[4];
+} *i2400m_barker_db;
+static size_t i2400m_barker_db_used, i2400m_barker_db_size;
+
+
+static
+int i2400m_zrealloc_2x(void **ptr, size_t *_count, size_t el_size,
+		       gfp_t gfp_flags)
+{
+	size_t old_count = *_count,
+		new_count = old_count ? 2 * old_count : 2,
+		old_size = el_size * old_count,
+		new_size = el_size * new_count;
+	void *nptr = krealloc(*ptr, new_size, gfp_flags);
+	if (nptr) {
+		/* zero the other half or the whole thing if old_count
+		 * was zero */
+		if (old_size == 0)
+			memset(nptr, 0, new_size);
+		else
+			memset(nptr + old_size, 0, old_size);
+		*_count = new_count;
+		*ptr = nptr;
+		return 0;
+	} else
+		return -ENOMEM;
+}
+
+
+/*
+ * Add a barker to the database
+ *
+ * This cannot used outside of this module and only at at module_init
+ * time. This is to avoid the need to do locking.
+ */
+static
+int i2400m_barker_db_add(u32 barker_id)
+{
+	int result;
+
+	struct i2400m_barker_db *barker;
+	if (i2400m_barker_db_used >= i2400m_barker_db_size) {
+		result = i2400m_zrealloc_2x(
+			(void **) &i2400m_barker_db, &i2400m_barker_db_size,
+			sizeof(i2400m_barker_db[0]), GFP_KERNEL);
+		if (result < 0)
+			return result;
+	}
+	barker = i2400m_barker_db + i2400m_barker_db_used++;
+	barker->data[0] = le32_to_cpu(barker_id);
+	barker->data[1] = le32_to_cpu(barker_id);
+	barker->data[2] = le32_to_cpu(barker_id);
+	barker->data[3] = le32_to_cpu(barker_id);
+	return 0;
+}
+
+
+void i2400m_barker_db_exit(void)
+{
+	kfree(i2400m_barker_db);
+	i2400m_barker_db = NULL;
+	i2400m_barker_db_size = 0;
+	i2400m_barker_db_used = 0;
+}
+
+
+/*
+ * Helper function to add all the known stable barkers to the barker
+ * database.
+ */
+static
+int i2400m_barker_db_known_barkers(void)
+{
+	int result;
+
+	result = i2400m_barker_db_add(I2400M_NBOOT_BARKER);
+	if (result < 0)
+		goto error_add;
+	result = i2400m_barker_db_add(I2400M_SBOOT_BARKER);
+	if (result < 0)
+		goto error_add;
+	result = i2400m_barker_db_add(I2400M_SBOOT_BARKER_6050);
+	if (result < 0)
+		goto error_add;
+error_add:
+       return result;
+}
+
+
+/*
+ * Initialize the barker database
+ *
+ * This can only be used from the module_init function for this
+ * module; this is to avoid the need to do locking.
+ *
+ * @options: command line argument with extra barkers to
+ *     recognize. This is a comma-separated list of 32-bit hex
+ *     numbers. They are appended to the existing list. Setting 0
+ *     cleans the existing list and starts a new one.
+ */
+int i2400m_barker_db_init(const char *_options)
+{
+	int result;
+	char *options = NULL, *options_orig, *token;
+
+	i2400m_barker_db = NULL;
+	i2400m_barker_db_size = 0;
+	i2400m_barker_db_used = 0;
+
+	result = i2400m_barker_db_known_barkers();
+	if (result < 0)
+		goto error_add;
+	/* parse command line options from i2400m.barkers */
+	if (_options != NULL) {
+		unsigned barker;
+
+		options_orig = kstrdup(_options, GFP_KERNEL);
+		if (options_orig == NULL)
+			goto error_parse;
+		options = options_orig;
+
+		while ((token = strsep(&options, ",")) != NULL) {
+			if (*token == '\0')	/* eat joint commas */
+				continue;
+			if (sscanf(token, "%x", &barker) != 1
+			    || barker > 0xffffffff) {
+				printk(KERN_ERR "%s: can't recognize "
+				       "i2400m.barkers value '%s' as "
+				       "a 32-bit number\n",
+				       __func__, token);
+				result = -EINVAL;
+				goto error_parse;
+			}
+			if (barker == 0) {
+				/* clean list and start new */
+				i2400m_barker_db_exit();
+				continue;
+			}
+			result = i2400m_barker_db_add(barker);
+			if (result < 0)
+				goto error_add;
+		}
+		kfree(options_orig);
+	}
+	return 0;
+
+error_parse:
+error_add:
+	kfree(i2400m_barker_db);
+	return result;
+}
+
+
+/*
+ * Recognize a boot barker
+ *
+ * @buf: buffer where the boot barker.
+ * @buf_size: size of the buffer (has to be 16 bytes). It is passed
+ *     here so the function can check it for the caller.
+ *
+ * Note that as a side effect, upon identifying the obtained boot
+ * barker, this function will set i2400m->barker to point to the right
+ * barker database entry. Subsequent calls to the function will result
+ * in verifying that the same type of boot barker is returned when the
+ * device [re]boots (as long as the same device instance is used).
+ *
+ * Return: 0 if @buf matches a known boot barker. -ENOENT if the
+ *     buffer in @buf doesn't match any boot barker in the database or
+ *     -EILSEQ if the buffer doesn't have the right size.
+ */
+int i2400m_is_boot_barker(struct i2400m *i2400m,
+			  const void *buf, size_t buf_size)
+{
+	int result;
+	struct device *dev = i2400m_dev(i2400m);
+	struct i2400m_barker_db *barker;
+	int i;
+
+	result = -ENOENT;
+	if (buf_size != sizeof(i2400m_barker_db[i].data))
+		return result;
+
+	/* Short circuit if we have already discovered the barker
+	 * associated with the device. */
+	if (i2400m->barker
+	    && !memcmp(buf, i2400m->barker, sizeof(i2400m->barker->data))) {
+		unsigned index = (i2400m->barker - i2400m_barker_db)
+			/ sizeof(*i2400m->barker);
+		d_printf(2, dev, "boot barker cache-confirmed #%u/%08x\n",
+			 index, le32_to_cpu(i2400m->barker->data[0]));
+		return 0;
+	}
+
+	for (i = 0; i < i2400m_barker_db_used; i++) {
+		barker = &i2400m_barker_db[i];
+		BUILD_BUG_ON(sizeof(barker->data) != 16);
+		if (memcmp(buf, barker->data, sizeof(barker->data)))
+			continue;
+
+		if (i2400m->barker == NULL) {
+			i2400m->barker = barker;
+			d_printf(1, dev, "boot barker set to #%u/%08x\n",
+				 i, le32_to_cpu(barker->data[0]));
+			if (barker->data[0] == le32_to_cpu(I2400M_NBOOT_BARKER))
+				i2400m->sboot = 0;
+			else
+				i2400m->sboot = 1;
+		} else if (i2400m->barker != barker) {
+			dev_err(dev, "HW inconsistency: device "
+				"reports a different boot barker "
+				"than set (from %08x to %08x)\n",
+				le32_to_cpu(i2400m->barker->data[0]),
+				le32_to_cpu(barker->data[0]));
+			result = -EIO;
+		} else
+			d_printf(2, dev, "boot barker confirmed #%u/%08x\n",
+				 i, le32_to_cpu(barker->data[0]));
+		result = 0;
+		break;
+	}
+	return result;
+}
+EXPORT_SYMBOL_GPL(i2400m_is_boot_barker);
+
+
+/*
  * Verify the ack data received
  *
  * Given a reply to a boot mode command, chew it and verify everything
@@ -204,20 +463,10 @@ ssize_t __i2400m_bm_ack_verify(struct i2
 			opcode, ack_size, sizeof(*ack));
 		goto error_ack_short;
 	}
-	if (ack_size == sizeof(i2400m_NBOOT_BARKER)
-		 && memcmp(ack, i2400m_NBOOT_BARKER, sizeof(*ack)) == 0) {
-		result = -ERESTARTSYS;
-		i2400m->sboot = 0;
-		d_printf(6, dev, "boot-mode cmd %d: "
-			 "HW non-signed boot barker\n", opcode);
-		goto error_reboot;
-	}
-	if (ack_size == sizeof(i2400m_SBOOT_BARKER)
-		 && memcmp(ack, i2400m_SBOOT_BARKER, sizeof(*ack)) == 0) {
+	result = i2400m_is_boot_barker(i2400m, ack, ack_size);
+	if (result >= 0) {
 		result = -ERESTARTSYS;
-		i2400m->sboot = 1;
-		d_printf(6, dev, "boot-mode cmd %d: HW signed reboot barker\n",
-			 opcode);
+		d_printf(6, dev, "boot-mode cmd %d: HW boot barker\n", opcode);
 		goto error_reboot;
 	}
 	if (ack_size == sizeof(i2400m_ACK_BARKER)
@@ -343,7 +592,6 @@ ssize_t i2400m_bm_cmd(struct i2400m *i24
 	BUG_ON(i2400m->boot_mode == 0);
 
 	if (cmd != NULL) {		/* send the command */
-		memcpy(i2400m->bm_cmd_buf, cmd, cmd_size);
 		result = i2400m->bus_bm_cmd_send(i2400m, cmd, cmd_size, flags);
 		if (result < 0)
 			goto error_cmd_send;
@@ -432,8 +680,8 @@ static int i2400m_download_chunk(struct
  * Download a BCF file's sections to the device
  *
  * @i2400m: device descriptor
- * @bcf: pointer to firmware data (followed by the payloads). Assumed
- *       verified and consistent.
+ * @bcf: pointer to firmware data (first header followed by the
+ *     payloads). Assumed verified and consistent.
  * @bcf_len: length (in bytes) of the @bcf buffer.
  *
  * Returns: < 0 errno code on error or the offset to the jump instruction.
@@ -472,14 +720,17 @@ ssize_t i2400m_dnload_bcf(struct i2400m
 			 "downloading section #%zu (@%zu %zu B) to 0x%08x\n",
 			 section, offset, sizeof(*bh) + data_size,
 			 le32_to_cpu(bh->target_addr));
-		if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP) {
-			/* Secure boot needs to stop here */
-			d_printf(5, dev,  "signed jump found @%zu\n", offset);
+		/*
+		 * We look for JUMP cmd from the bootmode header,
+		 * either I2400M_BRH_SIGNED_JUMP for secure boot
+		 * or I2400M_BRH_JUMP for unsecure boot, the last chunk
+		 * should be the bootmode header with JUMP cmd.
+		 */
+		if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP ||
+			i2400m_brh_get_opcode(bh) == I2400M_BRH_JUMP) {
+			d_printf(5, dev,  "jump found @%zu\n", offset);
 			break;
 		}
-		if (offset + section_size == bcf_len)
-			/* Non-secure boot stops here */
-			break;
 		if (offset + section_size > bcf_len) {
 			dev_err(dev, "fw %s: bad section #%zu, "
 				"end (@%zu) beyond EOF (@%zu)\n",
@@ -510,13 +761,30 @@ error_send:
 
 
 /*
+ * Indicate if the device emitted a reboot barker that indicates
+ * "signed boot"
+ */
+static
+unsigned i2400m_boot_is_signed(struct i2400m *i2400m)
+{
+	return likely(i2400m->sboot);
+}
+
+
+/*
  * Do the final steps of uploading firmware
  *
+ * @bcf_hdr: BCF header we are actually using
+ * @bcf: pointer to the firmware image (which matches the first header
+ *     that is followed by the actual payloads).
+ * @offset: [byte] offset into @bcf for the command we need to send.
+ *
  * Depending on the boot mode (signed vs non-signed), different
  * actions need to be taken.
  */
 static
 int i2400m_dnload_finalize(struct i2400m *i2400m,
+			   const struct i2400m_bcf_hdr *bcf_hdr,
 			   const struct i2400m_bcf_hdr *bcf, size_t offset)
 {
 	int ret = 0;
@@ -530,10 +798,14 @@ int i2400m_dnload_finalize(struct i2400m
 
 	d_fnstart(3, dev, "offset %zu\n", offset);
 	cmd = (void *) bcf + offset;
-	if (i2400m->sboot == 0) {
+	if (i2400m_boot_is_signed(i2400m) == 0) {
 		struct i2400m_bootrom_header jump_ack;
 		d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n",
 			le32_to_cpu(cmd->target_addr));
+		cmd_buf = i2400m->bm_cmd_buf;
+		memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
+		cmd = &cmd_buf->cmd;
+		/* now cmd points to the actual bootrom_header in cmd_buf */
 		i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP);
 		cmd->data_size = 0;
 		ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
@@ -544,12 +816,13 @@ int i2400m_dnload_finalize(struct i2400m
 		cmd_buf = i2400m->bm_cmd_buf;
 		memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
 		signature_block_offset =
-			sizeof(*bcf)
-			+ le32_to_cpu(bcf->key_size) * sizeof(u32)
-			+ le32_to_cpu(bcf->exponent_size) * sizeof(u32);
+			sizeof(*bcf_hdr)
+			+ le32_to_cpu(bcf_hdr->key_size) * sizeof(u32)
+			+ le32_to_cpu(bcf_hdr->exponent_size) * sizeof(u32);
 		signature_block_size =
-			le32_to_cpu(bcf->modulus_size) * sizeof(u32);
-		memcpy(cmd_buf->cmd_pl, (void *) bcf + signature_block_offset,
+			le32_to_cpu(bcf_hdr->modulus_size) * sizeof(u32);
+		memcpy(cmd_buf->cmd_pl,
+		       (void *) bcf_hdr + signature_block_offset,
 		       signature_block_size);
 		ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd,
 				    sizeof(cmd_buf->cmd) + signature_block_size,
@@ -565,7 +838,7 @@ int i2400m_dnload_finalize(struct i2400m
  *
  * @i2400m: device descriptor
  * @flags:
- *      I2400M_BRI_SOFT: a reboot notification has been seen
+ *      I2400M_BRI_SOFT: a reboot barker has been seen
  *          already, so don't wait for it.
  *
  *      I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait
@@ -576,17 +849,15 @@ int i2400m_dnload_finalize(struct i2400m
  *
  *     < 0 errno code on error, 0 if ok.
  *
- *     i2400m->sboot set to 0 for unsecure boot process, 1 for secure
- *     boot process.
- *
  * Description:
  *
  * Tries hard enough to put the device in boot-mode. There are two
  * main phases to this:
  *
  * a. (1) send a reboot command and (2) get a reboot barker
- * b. (1) ack the reboot sending a reboot barker and (2) getting an
- *        ack barker in return
+ *
+ * b. (1) echo/ack the reboot sending the reboot barker back and (2)
+ *        getting an ack barker in return
  *
  * We want to skip (a) in some cases [soft]. The state machine is
  * horrible, but it is basically: on each phase, send what has to be
@@ -594,6 +865,16 @@ int i2400m_dnload_finalize(struct i2400m
  * have to backtrack and retry, so we keep a max tries counter for
  * that.
  *
+ * It sucks because we don't know ahead of time which is going to be
+ * the reboot barker (the device might send different ones depending
+ * on its EEPROM config) and once the device reboots and waits for the
+ * echo/ack reboot barker being sent back, it doesn't understand
+ * anything else. So we can be left at the point where we don't know
+ * what to send to it -- cold reset and bus reset seem to have little
+ * effect. So the function iterates (in this case) through all the
+ * known barkers and tries them all until an ACK is
+ * received. Otherwise, it gives up.
+ *
  * If we get a timeout after sending a warm reset, we do it again.
  */
 int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
@@ -602,10 +883,11 @@ int i2400m_bootrom_init(struct i2400m *i
 	struct device *dev = i2400m_dev(i2400m);
 	struct i2400m_bootrom_header *cmd;
 	struct i2400m_bootrom_header ack;
-	int count = I2400M_BOOT_RETRIES;
+	int count = i2400m->bus_bm_retries;
 	int ack_timeout_cnt = 1;
+	unsigned i;
 
-	BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_NBOOT_BARKER));
+	BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data));
 	BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER));
 
 	d_fnstart(4, dev, "(i2400m %p flags 0x%08x)\n", i2400m, flags);
@@ -614,27 +896,59 @@ int i2400m_bootrom_init(struct i2400m *i
 	if (flags & I2400M_BRI_SOFT)
 		goto do_reboot_ack;
 do_reboot:
+	ack_timeout_cnt = 1;
 	if (--count < 0)
 		goto error_timeout;
 	d_printf(4, dev, "device reboot: reboot command [%d # left]\n",
 		 count);
 	if ((flags & I2400M_BRI_NO_REBOOT) == 0)
-		i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+		i2400m_reset(i2400m, I2400M_RT_WARM);
 	result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack),
 			       I2400M_BM_CMD_RAW);
 	flags &= ~I2400M_BRI_NO_REBOOT;
 	switch (result) {
 	case -ERESTARTSYS:
+		/*
+		 * at this point, i2400m_bm_cmd(), through
+		 * __i2400m_bm_ack_process(), has updated
+		 * i2400m->barker and we are good to go.
+		 */
 		d_printf(4, dev, "device reboot: got reboot barker\n");
 		break;
 	case -EISCONN:	/* we don't know how it got here...but we follow it */
 		d_printf(4, dev, "device reboot: got ack barker - whatever\n");
 		goto do_reboot;
-	case -ETIMEDOUT:	/* device has timed out, we might be in boot
-				 * mode already and expecting an ack, let's try
-				 * that */
-		dev_info(dev, "warm reset timed out, trying an ack\n");
-		goto do_reboot_ack;
+	case -ETIMEDOUT:
+		/*
+		 * Device has timed out, we might be in boot mode
+		 * already and expecting an ack; if we don't know what
+		 * the barker is, we just send them all. Cold reset
+		 * and bus reset don't work. Beats me.
+		 */
+		if (i2400m->barker != NULL) {
+			dev_err(dev, "device boot: reboot barker timed out, "
+				"trying (set) %08x echo/ack\n",
+				le32_to_cpu(i2400m->barker->data[0]));
+			goto do_reboot_ack;
+		}
+		for (i = 0; i < i2400m_barker_db_used; i++) {
+			struct i2400m_barker_db *barker = &i2400m_barker_db[i];
+			memcpy(cmd, barker->data, sizeof(barker->data));
+			result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
+					       &ack, sizeof(ack),
+					       I2400M_BM_CMD_RAW);
+			if (result == -EISCONN) {
+				dev_warn(dev, "device boot: got ack barker "
+					 "after sending echo/ack barker "
+					 "#%d/%08x; rebooting j.i.c.\n",
+					 i, le32_to_cpu(barker->data[0]));
+				flags &= ~I2400M_BRI_NO_REBOOT;
+				goto do_reboot;
+			}
+		}
+		dev_err(dev, "device boot: tried all the echo/acks, could "
+			"not get device to respond; giving up");
+		result = -ESHUTDOWN;
 	case -EPROTO:
 	case -ESHUTDOWN:	/* dev is gone */
 	case -EINTR:		/* user cancelled */
@@ -642,6 +956,7 @@ do_reboot:
 	default:
 		dev_err(dev, "device reboot: error %d while waiting "
 			"for reboot barker - rebooting\n", result);
+		d_dump(1, dev, &ack, result);
 		goto do_reboot;
 	}
 	/* At this point we ack back with 4 REBOOT barkers and expect
@@ -650,12 +965,7 @@ do_reboot:
 	 * notification and report it as -EISCONN. */
 do_reboot_ack:
 	d_printf(4, dev, "device reboot ack: sending ack [%d # left]\n", count);
-	if (i2400m->sboot == 0)
-		memcpy(cmd, i2400m_NBOOT_BARKER,
-		       sizeof(i2400m_NBOOT_BARKER));
-	else
-		memcpy(cmd, i2400m_SBOOT_BARKER,
-		       sizeof(i2400m_SBOOT_BARKER));
+	memcpy(cmd, i2400m->barker->data, sizeof(i2400m->barker->data));
 	result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
 			       &ack, sizeof(ack), I2400M_BM_CMD_RAW);
 	switch (result) {
@@ -668,10 +978,8 @@ do_reboot_ack:
 		d_printf(4, dev, "reboot ack: got ack barker - good\n");
 		break;
 	case -ETIMEDOUT:	/* no response, maybe it is the other type? */
-		if (ack_timeout_cnt-- >= 0) {
-			d_printf(4, dev, "reboot ack timedout: "
-				 "trying the other type?\n");
-			i2400m->sboot = !i2400m->sboot;
+		if (ack_timeout_cnt-- < 0) {
+			d_printf(4, dev, "reboot ack timedout: retrying\n");
 			goto do_reboot_ack;
 		} else {
 			dev_err(dev, "reboot ack timedout too long: "
@@ -839,32 +1147,29 @@ int i2400m_dnload_init_signed(struct i24
  * (signed or non-signed).
  */
 static
-int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf)
+int i2400m_dnload_init(struct i2400m *i2400m,
+		       const struct i2400m_bcf_hdr *bcf_hdr)
 {
 	int result;
 	struct device *dev = i2400m_dev(i2400m);
-	u32 module_id = le32_to_cpu(bcf->module_id);
 
-	if (i2400m->sboot == 0
-	    && (module_id & I2400M_BCF_MOD_ID_POKES) == 0) {
-		/* non-signed boot process without pokes */
-		result = i2400m_dnload_init_nonsigned(i2400m);
+	if (i2400m_boot_is_signed(i2400m)) {
+		d_printf(1, dev, "signed boot\n");
+		result = i2400m_dnload_init_signed(i2400m, bcf_hdr);
 		if (result == -ERESTARTSYS)
 			return result;
 		if (result < 0)
-			dev_err(dev, "fw %s: non-signed download "
+			dev_err(dev, "firmware %s: signed boot download "
 				"initialization failed: %d\n",
 				i2400m->fw_name, result);
-	} else if (i2400m->sboot == 0
-		 && (module_id & I2400M_BCF_MOD_ID_POKES)) {
-		/* non-signed boot process with pokes, nothing to do */
-		result = 0;
-	} else {		 /* signed boot process */
-		result = i2400m_dnload_init_signed(i2400m, bcf);
+	} else {
+		/* non-signed boot process without pokes */
+		d_printf(1, dev, "non-signed boot\n");
+		result = i2400m_dnload_init_nonsigned(i2400m);
 		if (result == -ERESTARTSYS)
 			return result;
 		if (result < 0)
-			dev_err(dev, "fw %s: signed boot download "
+			dev_err(dev, "firmware %s: non-signed download "
 				"initialization failed: %d\n",
 				i2400m->fw_name, result);
 	}
@@ -873,74 +1178,201 @@ int i2400m_dnload_init(struct i2400m *i2
 
 
 /*
- * Run quick consistency tests on the firmware file
+ * Run consistency tests on the firmware file and load up headers
  *
  * Check for the firmware being made for the i2400m device,
  * etc...These checks are mostly informative, as the device will make
  * them too; but the driver's response is more informative on what
  * went wrong.
+ *
+ * This will also look at all the headers present on the firmware
+ * file, and update i2400m->fw_bcf_hdr to point to them.
  */
 static
-int i2400m_fw_check(struct i2400m *i2400m,
-		    const struct i2400m_bcf_hdr *bcf,
-		    size_t bcf_size)
+int i2400m_fw_hdr_check(struct i2400m *i2400m,
+			const struct i2400m_bcf_hdr *bcf_hdr,
+			size_t index, size_t offset)
 {
-	int result;
 	struct device *dev = i2400m_dev(i2400m);
+
 	unsigned module_type, header_len, major_version, minor_version,
 		module_id, module_vendor, date, size;
 
-	/* Check hard errors */
-	result = -EINVAL;
-	if (bcf_size < sizeof(*bcf)) {	/* big enough header? */
-		dev_err(dev, "firmware %s too short: "
-			"%zu B vs %zu (at least) expected\n",
-			i2400m->fw_name, bcf_size, sizeof(*bcf));
-		goto error;
-	}
+	module_type = bcf_hdr->module_type;
+	header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len);
+	major_version = (le32_to_cpu(bcf_hdr->header_version) & 0xffff0000)
+		>> 16;
+	minor_version = le32_to_cpu(bcf_hdr->header_version) & 0x0000ffff;
+	module_id = le32_to_cpu(bcf_hdr->module_id);
+	module_vendor = le32_to_cpu(bcf_hdr->module_vendor);
+	date = le32_to_cpu(bcf_hdr->date);
+	size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);
 
-	module_type = bcf->module_type;
-	header_len = sizeof(u32) * le32_to_cpu(bcf->header_len);
-	major_version = le32_to_cpu(bcf->header_version) & 0xffff0000 >> 16;
-	minor_version = le32_to_cpu(bcf->header_version) & 0x0000ffff;
-	module_id = le32_to_cpu(bcf->module_id);
-	module_vendor = le32_to_cpu(bcf->module_vendor);
-	date = le32_to_cpu(bcf->date);
-	size = sizeof(u32) * le32_to_cpu(bcf->size);
+	d_printf(1, dev, "firmware %s #%zd@%08zx: BCF header "
+		 "type:vendor:id 0x%x:%x:%x v%u.%u (%u/%u B) built %08x\n",
+		 i2400m->fw_name, index, offset,
+		 module_type, module_vendor, module_id,
+		 major_version, minor_version, header_len, size, date);
 
-	if (bcf_size != size) {		/* annoyingly paranoid */
-		dev_err(dev, "firmware %s: bad size, got "
-			"%zu B vs %u expected\n",
-			i2400m->fw_name, bcf_size, size);
-		goto error;
+	/* Hard errors */
+	if (major_version != 1) {
+		dev_err(dev, "firmware %s #%zd@%08zx: major header version "
+			"v%u.%u not supported\n",
+			i2400m->fw_name, index, offset,
+			major_version, minor_version);
+		return -EBADF;
 	}
 
-	d_printf(2, dev, "type 0x%x id 0x%x vendor 0x%x; header v%u.%u (%zu B) "
-		 "date %08x (%zu B)\n",
-		 module_type, module_id, module_vendor,
-		 major_version, minor_version, (size_t) header_len,
-		 date, (size_t) size);
-
 	if (module_type != 6) {		/* built for the right hardware? */
-		dev_err(dev, "bad fw %s: unexpected module type 0x%x; "
-			"aborting\n", i2400m->fw_name, module_type);
-		goto error;
+		dev_err(dev, "firmware %s #%zd@%08zx: unexpected module "
+			"type 0x%x; aborting\n",
+			i2400m->fw_name, index, offset,
+			module_type);
+		return -EBADF;
+	}
+
+	if (module_vendor != 0x8086) {
+		dev_err(dev, "firmware %s #%zd@%08zx: unexpected module "
+			"vendor 0x%x; aborting\n",
+			i2400m->fw_name, index, offset, module_vendor);
+		return -EBADF;
 	}
 
-	/* Check soft-er errors */
-	result = 0;
-	if (module_vendor != 0x8086)
-		dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n",
-			i2400m->fw_name, module_vendor);
 	if (date < 0x20080300)
-		dev_err(dev, "bad fw %s? build date too old %08x\n",
-			i2400m->fw_name, date);
-error:
+		dev_warn(dev, "firmware %s #%zd@%08zx: build date %08x "
+			 "too old; unsupported\n",
+			 i2400m->fw_name, index, offset, date);
+	return 0;
+}
+
+
+/*
+ * Run consistency tests on the firmware file and load up headers
+ *
+ * Check for the firmware being made for the i2400m device,
+ * etc...These checks are mostly informative, as the device will make
+ * them too; but the driver's response is more informative on what
+ * went wrong.
+ *
+ * This will also look at all the headers present on the firmware
+ * file, and update i2400m->fw_hdrs to point to them.
+ */
+static
+int i2400m_fw_check(struct i2400m *i2400m, const void *bcf, size_t bcf_size)
+{
+	int result;
+	struct device *dev = i2400m_dev(i2400m);
+	size_t headers = 0;
+	const struct i2400m_bcf_hdr *bcf_hdr;
+	const void *itr, *next, *top;
+	size_t slots = 0, used_slots = 0;
+
+	for (itr = bcf, top = itr + bcf_size;
+	     itr < top;
+	     headers++, itr = next) {
+		size_t leftover, offset, header_len, size;
+
+		leftover = top - itr;
+		offset = itr - (const void *) bcf;
+		if (leftover <= sizeof(*bcf_hdr)) {
+			dev_err(dev, "firmware %s: %zu B left at @%zx, "
+				"not enough for BCF header\n",
+				i2400m->fw_name, leftover, offset);
+			break;
+		}
+		bcf_hdr = itr;
+		/* Only the first header is supposed to be followed by
+		 * payload */
+		header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len);
+		size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);
+		if (headers == 0)
+			next = itr + size;
+		else
+			next = itr + header_len;
+
+		result = i2400m_fw_hdr_check(i2400m, bcf_hdr, headers, offset);
+		if (result < 0)
+			continue;
+		if (used_slots + 1 >= slots) {
+			/* +1 -> we need to account for the one we'll
+			 * occupy and at least an extra one for
+			 * always being NULL */
+			result = i2400m_zrealloc_2x(
+				(void **) &i2400m->fw_hdrs, &slots,
+				sizeof(i2400m->fw_hdrs[0]),
+				GFP_KERNEL);
+			if (result < 0)
+				goto error_zrealloc;
+		}
+		i2400m->fw_hdrs[used_slots] = bcf_hdr;
+		used_slots++;
+	}
+	if (headers == 0) {
+		dev_err(dev, "firmware %s: no usable headers found\n",
+			i2400m->fw_name);
+		result = -EBADF;
+	} else
+		result = 0;
+error_zrealloc:
 	return result;
 }
 
 
 /*
+ * Match a barker to a BCF header module ID
+ *
+ * The device sends a barker which tells the firmware loader which
+ * header in the BCF file has to be used. This does the matching.
+ */
+static
+unsigned i2400m_bcf_hdr_match(struct i2400m *i2400m,
+			      const struct i2400m_bcf_hdr *bcf_hdr)
+{
+	u32 barker = le32_to_cpu(i2400m->barker->data[0])
+		& 0x7fffffff;
+	u32 module_id = le32_to_cpu(bcf_hdr->module_id)
+		& 0x7fffffff;	/* high bit used for something else */
+
+	/* special case for 5x50 */
+	if (barker == I2400M_SBOOT_BARKER && module_id == 0)
+		return 1;
+	if (module_id == barker)
+		return 1;
+	return 0;
+}
+
+static
+const struct i2400m_bcf_hdr *i2400m_bcf_hdr_find(struct i2400m *i2400m)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	const struct i2400m_bcf_hdr **bcf_itr, *bcf_hdr;
+	unsigned i = 0;
+	u32 barker = le32_to_cpu(i2400m->barker->data[0]);
+
+	d_printf(2, dev, "finding BCF header for barker %08x\n", barker);
+	if (barker == I2400M_NBOOT_BARKER) {
+		bcf_hdr = i2400m->fw_hdrs[0];
+		d_printf(1, dev, "using BCF header #%u/%08x for non-signed "
+			 "barker\n", 0, le32_to_cpu(bcf_hdr->module_id));
+		return bcf_hdr;
+	}
+	for (bcf_itr = i2400m->fw_hdrs; *bcf_itr != NULL; bcf_itr++, i++) {
+		bcf_hdr = *bcf_itr;
+		if (i2400m_bcf_hdr_match(i2400m, bcf_hdr)) {
+			d_printf(1, dev, "hit on BCF hdr #%u/%08x\n",
+				 i, le32_to_cpu(bcf_hdr->module_id));
+			return bcf_hdr;
+		} else
+			d_printf(1, dev, "miss on BCF hdr #%u/%08x\n",
+				 i, le32_to_cpu(bcf_hdr->module_id));
+	}
+	dev_err(dev, "cannot find a matching BCF header for barker %08x\n",
+		barker);
+	return NULL;
+}
+
+
+/*
  * Download the firmware to the device
  *
  * @i2400m: device descriptor
@@ -956,14 +1388,16 @@ error:
  */
 static
 int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
-		     size_t bcf_size, enum i2400m_bri flags)
+		     size_t fw_size, enum i2400m_bri flags)
 {
 	int ret = 0;
 	struct device *dev = i2400m_dev(i2400m);
 	int count = i2400m->bus_bm_retries;
+	const struct i2400m_bcf_hdr *bcf_hdr;
+	size_t bcf_size;
 
-	d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
-		  i2400m, bcf, bcf_size);
+	d_fnstart(5, dev, "(i2400m %p bcf %p fw size %zu)\n",
+		  i2400m, bcf, fw_size);
 	i2400m->boot_mode = 1;
 	wmb();		/* Make sure other readers see it */
 hw_reboot:
@@ -985,13 +1419,28 @@ hw_reboot:
 	 * Initialize the download, push the bytes to the device and
 	 * then jump to the new firmware. Note @ret is passed with the
 	 * offset of the jump instruction to _dnload_finalize()
+	 *
+	 * Note we need to use the BCF header in the firmware image
+	 * that matches the barker that the device sent when it
+	 * rebooted, so it has to be passed along.
 	 */
-	ret = i2400m_dnload_init(i2400m, bcf);	/* Init device's dnload */
+	ret = -EBADF;
+	bcf_hdr = i2400m_bcf_hdr_find(i2400m);
+	if (bcf_hdr == NULL)
+		goto error_bcf_hdr_find;
+
+	ret = i2400m_dnload_init(i2400m, bcf_hdr);
 	if (ret == -ERESTARTSYS)
 		goto error_dev_rebooted;
 	if (ret < 0)
 		goto error_dnload_init;
 
+	/*
+	 * bcf_size refers to one header size plus the fw sections size
+	 * indicated by the header,ie. if there are other extended headers
+	 * at the tail, they are not counted
+	 */
+	bcf_size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);
 	ret = i2400m_dnload_bcf(i2400m, bcf, bcf_size);
 	if (ret == -ERESTARTSYS)
 		goto error_dev_rebooted;
@@ -1001,7 +1450,7 @@ hw_reboot:
 		goto error_dnload_bcf;
 	}
 
-	ret = i2400m_dnload_finalize(i2400m, bcf, ret);
+	ret = i2400m_dnload_finalize(i2400m, bcf_hdr, bcf, ret);
 	if (ret == -ERESTARTSYS)
 		goto error_dev_rebooted;
 	if (ret < 0) {
@@ -1018,10 +1467,11 @@ hw_reboot:
 error_dnload_finalize:
 error_dnload_bcf:
 error_dnload_init:
+error_bcf_hdr_find:
 error_bootrom_init:
 error_too_many_reboots:
 	d_fnend(5, dev, "(i2400m %p bcf %p size %zu) = %d\n",
-		i2400m, bcf, bcf_size, ret);
+		i2400m, bcf, fw_size, ret);
 	return ret;
 
 error_dev_rebooted:
@@ -1031,6 +1481,61 @@ error_dev_rebooted:
 	goto hw_reboot;
 }
 
+static
+int i2400m_fw_bootstrap(struct i2400m *i2400m, const struct firmware *fw,
+			enum i2400m_bri flags)
+{
+	int ret;
+	struct device *dev = i2400m_dev(i2400m);
+	const struct i2400m_bcf_hdr *bcf;	/* Firmware data */
+
+	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
+	bcf = (void *) fw->data;
+	ret = i2400m_fw_check(i2400m, bcf, fw->size);
+	if (ret >= 0)
+		ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags);
+	if (ret < 0)
+		dev_err(dev, "%s: cannot use: %d, skipping\n",
+			i2400m->fw_name, ret);
+	kfree(i2400m->fw_hdrs);
+	i2400m->fw_hdrs = NULL;
+	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
+	return ret;
+}
+
+
+/* Refcounted container for firmware data */
+struct i2400m_fw {
+	struct kref kref;
+	const struct firmware *fw;
+};
+
+
+static
+void i2400m_fw_destroy(struct kref *kref)
+{
+	struct i2400m_fw *i2400m_fw =
+		container_of(kref, struct i2400m_fw, kref);
+	release_firmware(i2400m_fw->fw);
+	kfree(i2400m_fw);
+}
+
+
+static
+struct i2400m_fw *i2400m_fw_get(struct i2400m_fw *i2400m_fw)
+{
+	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0)
+		kref_get(&i2400m_fw->kref);
+	return i2400m_fw;
+}
+
+
+static
+void i2400m_fw_put(struct i2400m_fw *i2400m_fw)
+{
+	kref_put(&i2400m_fw->kref, i2400m_fw_destroy);
+}
+
 
 /**
  * i2400m_dev_bootstrap - Bring the device to a known state and upload firmware
@@ -1049,42 +1554,109 @@ error_dev_rebooted:
  */
 int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags)
 {
-	int ret = 0, itr = 0;
+	int ret, itr;
 	struct device *dev = i2400m_dev(i2400m);
-	const struct firmware *fw;
+	struct i2400m_fw *i2400m_fw;
 	const struct i2400m_bcf_hdr *bcf;	/* Firmware data */
+	const struct firmware *fw;
 	const char *fw_name;
 
 	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
 
+	ret = -ENODEV;
+	spin_lock(&i2400m->rx_lock);
+	i2400m_fw = i2400m_fw_get(i2400m->fw_cached);
+	spin_unlock(&i2400m->rx_lock);
+	if (i2400m_fw == (void *) ~0) {
+		dev_err(dev, "can't load firmware now!");
+		goto out;
+	} else if (i2400m_fw != NULL) {
+		dev_info(dev, "firmware %s: loading from cache\n",
+			 i2400m->fw_name);
+		ret = i2400m_fw_bootstrap(i2400m, i2400m_fw->fw, flags);
+		i2400m_fw_put(i2400m_fw);
+		goto out;
+	}
+
 	/* Load firmware files to memory. */
-	itr = 0;
-	while(1) {
+	for (itr = 0, bcf = NULL, ret = -ENOENT; ; itr++) {
 		fw_name = i2400m->bus_fw_names[itr];
 		if (fw_name == NULL) {
 			dev_err(dev, "Could not find a usable firmware image\n");
-			ret = -ENOENT;
-			goto error_no_fw;
+			break;
 		}
+		d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr);
 		ret = reject_firmware(&fw, fw_name, dev);
-		if (ret == 0)
-			break;		/* got it */
-		if (ret < 0)
+		if (ret < 0) {
 			dev_err(dev, "fw %s: cannot load file: %d\n",
 				fw_name, ret);
-		itr++;
+			continue;
+		}
+		i2400m->fw_name = fw_name;
+		ret = i2400m_fw_bootstrap(i2400m, fw, flags);
+		release_firmware(fw);
+		if (ret >= 0)	/* firmware loaded succesfully */
+			break;
+		i2400m->fw_name = NULL;
 	}
-
-	bcf = (void *) fw->data;
-	i2400m->fw_name = fw_name;
-	ret = i2400m_fw_check(i2400m, bcf, fw->size);
-	if (ret < 0)
-		goto error_fw_bad;
-	ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags);
-error_fw_bad:
-	release_firmware(fw);
-error_no_fw:
+out:
 	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(i2400m_dev_bootstrap);
+
+
+void i2400m_fw_cache(struct i2400m *i2400m)
+{
+	int result;
+	struct i2400m_fw *i2400m_fw;
+	struct device *dev = i2400m_dev(i2400m);
+
+	/* if there is anything there, free it -- now, this'd be weird */
+	spin_lock(&i2400m->rx_lock);
+	i2400m_fw = i2400m->fw_cached;
+	spin_unlock(&i2400m->rx_lock);
+	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0) {
+		i2400m_fw_put(i2400m_fw);
+		WARN(1, "%s:%u: still cached fw still present?\n",
+		     __func__, __LINE__);
+	}
+
+	if (i2400m->fw_name == NULL) {
+		dev_err(dev, "firmware n/a: can't cache\n");
+		i2400m_fw = (void *) ~0;
+		goto out;
+	}
+
+	i2400m_fw = kzalloc(sizeof(*i2400m_fw), GFP_ATOMIC);
+	if (i2400m_fw == NULL)
+		goto out;
+	kref_init(&i2400m_fw->kref);
+	result = reject_firmware(&i2400m_fw->fw, i2400m->fw_name, dev);
+	if (result < 0) {
+		dev_err(dev, "firmware %s: failed to cache: %d\n",
+			i2400m->fw_name, result);
+		kfree(i2400m_fw);
+		i2400m_fw = (void *) ~0;
+	} else
+		dev_info(dev, "firmware %s: cached\n", i2400m->fw_name);
+out:
+	spin_lock(&i2400m->rx_lock);
+	i2400m->fw_cached = i2400m_fw;
+	spin_unlock(&i2400m->rx_lock);
+}
+
+
+void i2400m_fw_uncache(struct i2400m *i2400m)
+{
+	struct i2400m_fw *i2400m_fw;
+
+	spin_lock(&i2400m->rx_lock);
+	i2400m_fw = i2400m->fw_cached;
+	i2400m->fw_cached = NULL;
+	spin_unlock(&i2400m->rx_lock);
+
+	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0)
+		i2400m_fw_put(i2400m_fw);
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m.h linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m.h
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m.h	2010-02-24 13:52:17.000000000 -0500
@@ -117,16 +117,30 @@
  * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The
  * i2400m driver will only register with the WiMAX and network stacks;
  * the only access done to the device is to read the MAC address so we
- * can register a network device. This calls i2400m_dev_start() to
- * load firmware, setup communication with the device and configure it
- * for operation.
+ * can register a network device.
  *
- * At this point, control and data communications are possible.
+ * The high-level call flow is:
  *
- * On disconnect/driver unload, the bus-specific disconnect function
- * calls i2400m_release() to undo i2400m_setup(). i2400m_dev_stop()
- * shuts the firmware down and releases resources uses to communicate
- * with the device.
+ * bus_probe()
+ *   i2400m_setup()
+ *     i2400m->bus_setup()
+ *     boot rom initialization / read mac addr
+ *     network / WiMAX stacks registration
+ *     i2400m_dev_start()
+ *       i2400m->bus_dev_start()
+ *       i2400m_dev_initialize()
+ *
+ * The reverse applies for a disconnect() call:
+ *
+ * bus_disconnect()
+ *   i2400m_release()
+ *     i2400m_dev_stop()
+ *       i2400m_dev_shutdown()
+ *       i2400m->bus_dev_stop()
+ *     network / WiMAX stack unregistration
+ *     i2400m->bus_release()
+ *
+ * At this point, control and data communications are possible.
  *
  * While the device is up, it might reset. The bus-specific driver has
  * to catch that situation and call i2400m_dev_reset_handle() to deal
@@ -148,9 +162,6 @@
 
 /* Misc constants */
 enum {
-	/* Firmware uploading */
-	I2400M_BOOT_RETRIES = 3,
-	I3200_BOOT_RETRIES = 3,
 	/* Size of the Boot Mode Command buffer */
 	I2400M_BM_CMD_BUF_SIZE = 16 * 1024,
 	I2400M_BM_ACK_BUF_SIZE = 256,
@@ -197,6 +208,7 @@ enum i2400m_reset_type {
 
 struct i2400m_reset_ctx;
 struct i2400m_roq;
+struct i2400m_barker_db;
 
 /**
  * struct i2400m - descriptor for an Intel 2400m
@@ -204,27 +216,50 @@ struct i2400m_roq;
  * Members marked with [fill] must be filled out/initialized before
  * calling i2400m_setup().
  *
+ * Note the @bus_setup/@bus_release, @bus_dev_start/@bus_dev_release
+ * call pairs are very much doing almost the same, and depending on
+ * the underlying bus, some stuff has to be put in one or the
+ * other. The idea of setup/release is that they setup the minimal
+ * amount needed for loading firmware, where us dev_start/stop setup
+ * the rest needed to do full data/control traffic.
+ *
  * @bus_tx_block_size: [fill] SDIO imposes a 256 block size, USB 16,
  *     so we have a tx_blk_size variable that the bus layer sets to
  *     tell the engine how much of that we need.
  *
  * @bus_pl_size_max: [fill] Maximum payload size.
  *
- * @bus_dev_start: [fill] Function called by the bus-generic code
- *     [i2400m_dev_start()] to setup the bus-specific communications
- *     to the the device. See LIFE CYCLE above.
+ * @bus_setup: [optional fill] Function called by the bus-generic code
+ *     [i2400m_setup()] to setup the basic bus-specific communications
+ *     to the the device needed to load firmware. See LIFE CYCLE above.
  *
  *     NOTE: Doesn't need to upload the firmware, as that is taken
  *     care of by the bus-generic code.
  *
- * @bus_dev_stop: [fill] Function called by the bus-generic code
- *     [i2400m_dev_stop()] to shutdown the bus-specific communications
- *     to the the device. See LIFE CYCLE above.
+ * @bus_release: [optional fill] Function called by the bus-generic
+ *     code [i2400m_release()] to shutdown the basic bus-specific
+ *     communications to the the device needed to load firmware. See
+ *     LIFE CYCLE above.
  *
  *     This function does not need to reset the device, just tear down
  *     all the host resources created to  handle communication with
  *     the device.
  *
+ * @bus_dev_start: [optional fill] Function called by the bus-generic
+ *     code [i2400m_dev_start()] to do things needed to start the
+ *     device. See LIFE CYCLE above.
+ *
+ *     NOTE: Doesn't need to upload the firmware, as that is taken
+ *     care of by the bus-generic code.
+ *
+ * @bus_dev_stop: [optional fill] Function called by the bus-generic
+ *     code [i2400m_dev_stop()] to do things needed for stopping the
+ *     device. See LIFE CYCLE above.
+ *
+ *     This function does not need to reset the device, just tear down
+ *     all the host resources created to handle communication with
+ *     the device.
+ *
  * @bus_tx_kick: [fill] Function called by the bus-generic code to let
  *     the bus-specific code know that there is data available in the
  *     TX FIFO for transmission to the device.
@@ -246,6 +281,9 @@ struct i2400m_roq;
  *     process, so it cannot rely on common infrastructure being laid
  *     out.
  *
+ *     IMPORTANT: don't call reset on RT_BUS with i2400m->init_mutex
+ *     held, as the .pre/.post reset handlers will deadlock.
+ *
  * @bus_bm_retries: [fill] How many times shall a firmware upload /
  *     device initialization be retried? Different models of the same
  *     device might need different values, hence it is set by the
@@ -297,6 +335,27 @@ struct i2400m_roq;
  *     force this to be the first field so that we can get from
  *     netdev_priv() the right pointer.
  *
+ * @updown: the device is up and ready for transmitting control and
+ *     data packets. This implies @ready (communication infrastructure
+ *     with the device is ready) and the device's firmware has been
+ *     loaded and the device initialized.
+ *
+ *     Write to it only inside a i2400m->init_mutex protected area
+ *     followed with a wmb(); rmb() before accesing (unless locked
+ *     inside i2400m->init_mutex). Read access can be loose like that
+ *     [just using rmb()] because the paths that use this also do
+ *     other error checks later on.
+ *
+ * @ready: Communication infrastructure with the device is ready, data
+ *     frames can start to be passed around (this is lighter than
+ *     using the WiMAX state for certain hot paths).
+ *
+ *     Write to it only inside a i2400m->init_mutex protected area
+ *     followed with a wmb(); rmb() before accesing (unless locked
+ *     inside i2400m->init_mutex). Read access can be loose like that
+ *     [just using rmb()] because the paths that use this also do
+ *     other error checks later on.
+ *
  * @rx_reorder: 1 if RX reordering is enabled; this can only be
  *     set at probe time.
  *
@@ -362,6 +421,13 @@ struct i2400m_roq;
  *     delivered. Then the driver can release them to the host. See
  *     drivers/net/i2400m/rx.c for details.
  *
+ * @rx_reports: reports received from the device that couldn't be
+ *     processed because the driver wasn't still ready; when ready,
+ *     they are pulled from here and chewed.
+ *
+ * @rx_reports_ws: Work struct used to kick a scan of the RX reports
+ *     list and to process each.
+ *
  * @src_mac_addr: MAC address used to make ethernet packets be coming
  *     from. This is generated at i2400m_setup() time and used during
  *     the life cycle of the instance. See i2400m_fake_eth_header().
@@ -422,6 +488,25 @@ struct i2400m_roq;
  *
  * @fw_version: version of the firmware interface, Major.minor,
  *     encoded in the high word and low word (major << 16 | minor).
+ *
+ * @fw_hdrs: NULL terminated array of pointers to the firmware
+ *     headers. This is only available during firmware load time.
+ *
+ * @fw_cached: Used to cache firmware when the system goes to
+ *     suspend/standby/hibernation (as on resume we can't read it). If
+ *     NULL, no firmware was cached, read it. If ~0, you can't read
+ *     any firmware files (the system still didn't come out of suspend
+ *     and failed to cache one), so abort; otherwise, a valid cached
+ *     firmware to be used. Access to this variable is protected by
+ *     the spinlock i2400m->rx_lock.
+ *
+ * @barker: barker type that the device uses; this is initialized by
+ *     i2400m_is_boot_barker() the first time it is called. Then it
+ *     won't change during the life cycle of the device and everytime
+ *     a boot barker is received, it is just verified for it being the
+ *     same.
+ *
+ * @pm_notifier: used to register for PM events
  */
 struct i2400m {
 	struct wimax_dev wimax_dev;	/* FIRST! See doc */
@@ -429,7 +514,7 @@ struct i2400m {
 	unsigned updown:1;		/* Network device is up or down */
 	unsigned boot_mode:1;		/* is the device in boot mode? */
 	unsigned sboot:1;		/* signed or unsigned fw boot */
-	unsigned ready:1;		/* all probing steps done */
+	unsigned ready:1;		/* Device comm infrastructure ready */
 	unsigned rx_reorder:1;		/* RX reorder is enabled */
 	u8 trace_msg_from_user;		/* echo rx msgs to 'trace' pipe */
 					/* typed u8 so /sys/kernel/debug/u8 can tweak */
@@ -440,8 +525,10 @@ struct i2400m {
 	size_t bus_pl_size_max;
 	unsigned bus_bm_retries;
 
+	int (*bus_setup)(struct i2400m *);
 	int (*bus_dev_start)(struct i2400m *);
 	void (*bus_dev_stop)(struct i2400m *);
+	void (*bus_release)(struct i2400m *);
 	void (*bus_tx_kick)(struct i2400m *);
 	int (*bus_reset)(struct i2400m *, enum i2400m_reset_type);
 	ssize_t (*bus_bm_cmd_send)(struct i2400m *,
@@ -468,6 +555,8 @@ struct i2400m {
 		rx_num, rx_size_acc, rx_size_min, rx_size_max;
 	struct i2400m_roq *rx_roq;	/* not under rx_lock! */
 	u8 src_mac_addr[ETH_HLEN];
+	struct list_head rx_reports;	/* under rx_lock! */
+	struct work_struct rx_report_ws;
 
 	struct mutex msg_mutex;		/* serialize command execution */
 	struct completion msg_completion;
@@ -487,37 +576,12 @@ struct i2400m {
 	struct dentry *debugfs_dentry;
 	const char *fw_name;		/* name of the current firmware image */
 	unsigned long fw_version;	/* version of the firmware interface */
-};
-
-
-/*
- * Initialize a 'struct i2400m' from all zeroes
- *
- * This is a bus-generic API call.
- */
-static inline
-void i2400m_init(struct i2400m *i2400m)
-{
-	wimax_dev_init(&i2400m->wimax_dev);
-
-	i2400m->boot_mode = 1;
-	i2400m->rx_reorder = 1;
-	init_waitqueue_head(&i2400m->state_wq);
-
-	spin_lock_init(&i2400m->tx_lock);
-	i2400m->tx_pl_min = UINT_MAX;
-	i2400m->tx_size_min = UINT_MAX;
-
-	spin_lock_init(&i2400m->rx_lock);
-	i2400m->rx_pl_min = UINT_MAX;
-	i2400m->rx_size_min = UINT_MAX;
-
-	mutex_init(&i2400m->msg_mutex);
-	init_completion(&i2400m->msg_completion);
+	const struct i2400m_bcf_hdr **fw_hdrs;
+	struct i2400m_fw *fw_cached;	/* protected by rx_lock */
+	struct i2400m_barker_db *barker;
 
-	mutex_init(&i2400m->init_mutex);
-	/* wake_tx_ws is initialized in i2400m_tx_setup() */
-}
+	struct notifier_block pm_notifier;
+};
 
 
 /*
@@ -577,6 +641,14 @@ extern void i2400m_bm_cmd_prepare(struct
 extern int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri);
 extern int i2400m_read_mac_addr(struct i2400m *);
 extern int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri);
+extern int i2400m_is_boot_barker(struct i2400m *, const void *, size_t);
+static inline
+int i2400m_is_d2h_barker(const void *buf)
+{
+	const __le32 *barker = buf;
+	return le32_to_cpu(*barker) == I2400M_D2H_MSG_BARKER;
+}
+extern void i2400m_unknown_barker(struct i2400m *, const void *, size_t);
 
 /* Make/grok boot-rom header commands */
 
@@ -644,6 +716,8 @@ unsigned i2400m_brh_get_signature(const
 /*
  * Driver / device setup and internal functions
  */
+extern void i2400m_init(struct i2400m *);
+extern int i2400m_reset(struct i2400m *, enum i2400m_reset_type);
 extern void i2400m_netdev_setup(struct net_device *net_dev);
 extern int i2400m_sysfs_setup(struct device_driver *);
 extern void i2400m_sysfs_release(struct device_driver *);
@@ -654,10 +728,14 @@ extern void i2400m_tx_release(struct i24
 extern int i2400m_rx_setup(struct i2400m *);
 extern void i2400m_rx_release(struct i2400m *);
 
+extern void i2400m_fw_cache(struct i2400m *);
+extern void i2400m_fw_uncache(struct i2400m *);
+
 extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned,
 			  const void *, int);
 extern void i2400m_net_erx(struct i2400m *, struct sk_buff *,
 			   enum i2400m_cs);
+extern void i2400m_net_wake_stop(struct i2400m *);
 enum i2400m_pt;
 extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
 
@@ -672,14 +750,12 @@ static inline int i2400m_debugfs_add(str
 static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {}
 #endif
 
-/* Called by _dev_start()/_dev_stop() to initialize the device itself */
+/* Initialize/shutdown the device */
 extern int i2400m_dev_initialize(struct i2400m *);
 extern void i2400m_dev_shutdown(struct i2400m *);
 
 extern struct attribute_group i2400m_dev_attr_group;
 
-extern int i2400m_schedule_work(struct i2400m *,
-				void (*)(struct work_struct *), gfp_t);
 
 /* HDI message's payload description handling */
 
@@ -724,7 +800,9 @@ void i2400m_put(struct i2400m *i2400m)
 	dev_put(i2400m->wimax_dev.net_dev);
 }
 
-extern int i2400m_dev_reset_handle(struct i2400m *);
+extern int i2400m_dev_reset_handle(struct i2400m *, const char *);
+extern int i2400m_pre_reset(struct i2400m *);
+extern int i2400m_post_reset(struct i2400m *);
 
 /*
  * _setup()/_release() are called by the probe/disconnect functions of
@@ -737,20 +815,6 @@ extern int i2400m_rx(struct i2400m *, st
 extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *);
 extern void i2400m_tx_msg_sent(struct i2400m *);
 
-static const __le32 i2400m_NBOOT_BARKER[4] = {
-	cpu_to_le32(I2400M_NBOOT_BARKER),
-	cpu_to_le32(I2400M_NBOOT_BARKER),
-	cpu_to_le32(I2400M_NBOOT_BARKER),
-	cpu_to_le32(I2400M_NBOOT_BARKER)
-};
-
-static const __le32 i2400m_SBOOT_BARKER[4] = {
-	cpu_to_le32(I2400M_SBOOT_BARKER),
-	cpu_to_le32(I2400M_SBOOT_BARKER),
-	cpu_to_le32(I2400M_SBOOT_BARKER),
-	cpu_to_le32(I2400M_SBOOT_BARKER)
-};
-
 extern int i2400m_power_save_disabled;
 
 /*
@@ -773,10 +837,12 @@ struct device *i2400m_dev(struct i2400m
 struct i2400m_work {
 	struct work_struct ws;
 	struct i2400m *i2400m;
+	size_t pl_size;
 	u8 pl[0];
 };
-extern int i2400m_queue_work(struct i2400m *,
-			     void (*)(struct work_struct *), gfp_t,
+
+extern int i2400m_schedule_work(struct i2400m *,
+				void (*)(struct work_struct *), gfp_t,
 				const void *, size_t);
 
 extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *,
@@ -789,6 +855,7 @@ extern void i2400m_msg_ack_hook(struct i
 				const struct i2400m_l3l4_hdr *, size_t);
 extern void i2400m_report_hook(struct i2400m *,
 			       const struct i2400m_l3l4_hdr *, size_t);
+extern void i2400m_report_hook_work(struct work_struct *);
 extern int i2400m_cmd_enter_powersave(struct i2400m *);
 extern int i2400m_cmd_get_state(struct i2400m *);
 extern int i2400m_cmd_exit_idle(struct i2400m *);
@@ -849,6 +916,12 @@ void __i2400m_msleep(unsigned ms)
 #endif
 }
 
+
+/* module initialization helpers */
+extern int i2400m_barker_db_init(const char *);
+extern void i2400m_barker_db_exit(void);
+
+
 /* Module parameters */
 
 extern int i2400m_idle_mode_disabled;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m-sdio.h linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m-sdio.h
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m-sdio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m-sdio.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@
 
 /* Host-Device interface for SDIO */
 enum {
+	I2400M_SDIO_BOOT_RETRIES = 3,
 	I2400MS_BLK_SIZE = 256,
 	I2400MS_PL_SIZE_MAX = 0x3E00,
 
@@ -77,9 +78,11 @@ enum {
 	I2400MS_INTR_GET_SIZE_ADDR = 0x2C,
 	/* The number of ticks to wait for the device to signal that
 	 * it is ready */
-	I2400MS_INIT_SLEEP_INTERVAL = 10,
+	I2400MS_INIT_SLEEP_INTERVAL = 100,
 	/* How long to wait for the device to settle after reset */
 	I2400MS_SETTLE_TIME = 40,
+	/* The number of msec to wait for IOR after sending IOE */
+	IWMC3200_IOR_TIMEOUT = 10,
 };
 
 
@@ -97,6 +100,14 @@ enum {
  * @tx_workqueue: workqeueue used for data TX; we don't use the
  *     system's workqueue as that might cause deadlocks with code in
  *     the bus-generic driver.
+ *
+ * @debugfs_dentry: dentry for the SDIO specific debugfs files
+ *
+ *     Note this value is set to NULL upon destruction; this is
+ *     because some routinges use it to determine if we are inside the
+ *     probe() path or some other path. When debugfs is disabled,
+ *     creation sets the dentry to '(void*) -ENODEV', which is valid
+ *     for the test.
  */
 struct i2400ms {
 	struct i2400m i2400m;		/* FIRST! See doc */
@@ -111,6 +122,9 @@ struct i2400ms {
 	wait_queue_head_t bm_wfa_wq;
 	int bm_wait_result;
 	size_t bm_ack_size;
+
+	/* Device is any of the iwmc3200 SKUs */
+	unsigned iwmc3200:1;
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m-usb.h linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m-usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/i2400m-usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/i2400m-usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -88,6 +88,13 @@ struct edc {
 	u16 errorcount;
 };
 
+struct i2400m_endpoint_cfg {
+	unsigned char bulk_out;
+	unsigned char notification;
+	unsigned char reset_cold;
+	unsigned char bulk_in;
+};
+
 static inline void edc_init(struct edc *edc)
 {
 	edc->timestart = jiffies;
@@ -137,15 +144,14 @@ static inline int edc_inc(struct edc *ed
 
 /* Host-Device interface for USB */
 enum {
+	I2400M_USB_BOOT_RETRIES = 3,
 	I2400MU_MAX_NOTIFICATION_LEN = 256,
 	I2400MU_BLK_SIZE = 16,
 	I2400MU_PL_SIZE_MAX = 0x3EFF,
 
-	/* Endpoints */
-	I2400MU_EP_BULK_OUT = 0,
-	I2400MU_EP_NOTIFICATION,
-	I2400MU_EP_RESET_COLD,
-	I2400MU_EP_BULK_IN,
+	/* Device IDs */
+	USB_DEVICE_ID_I6050 = 0x0186,
+	USB_DEVICE_ID_I6050_2 = 0x0188,
 };
 
 
@@ -215,6 +221,7 @@ struct i2400mu {
 	struct usb_device *usb_dev;
 	struct usb_interface *usb_iface;
 	struct edc urb_edc;		/* Error density counter */
+	struct i2400m_endpoint_cfg endpoint_cfg;
 
 	struct urb *notif_urb;
 	struct task_struct *tx_kthread;
@@ -228,6 +235,7 @@ struct i2400mu {
 	u8 rx_size_auto_shrink;
 
 	struct dentry *debugfs_dentry;
+	unsigned i6050:1;	/* 1 if this is a 6050 based SKU */
 };
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,14 @@ config WIMAX_I2400M_SDIO
 
 	  If unsure, it is safe to select M (module).
 
+config WIMAX_IWMC3200_SDIO
+	bool "Intel Wireless Multicom WiMAX Connection 3200 over SDIO"
+	depends on WIMAX_I2400M_SDIO
+	select IWMC3200TOP
+	help
+	  Select if you have a device based on the Intel Multicom WiMAX
+          Connection 3200 over SDIO.
+
 config WIMAX_I2400M_DEBUG_LEVEL
 	int "WiMAX i2400m debug level"
 	depends on WIMAX_I2400M
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/netdev.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/netdev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/netdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/netdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,6 +74,7 @@
  */
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
+#include <linux/ethtool.h>
 #include "i2400m.h"
 
 
@@ -88,7 +89,10 @@ enum {
 	 * The MTU is 1400 or less
 	 */
 	I2400M_MAX_MTU = 1400,
-	I2400M_TX_TIMEOUT = HZ,
+	/* 20 secs? yep, this is the maximum timeout that the device
+	 * might take to get out of IDLE / negotiate it with the base
+	 * station. We add 1sec for good measure. */
+	I2400M_TX_TIMEOUT = 21 * HZ,
 	I2400M_TX_QLEN = 5,
 };
 
@@ -101,22 +105,19 @@ int i2400m_open(struct net_device *net_d
 	struct device *dev = i2400m_dev(i2400m);
 
 	d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m);
-	if (i2400m->ready == 0) {
-		dev_err(dev, "Device is still initializing\n");
-		result = -EBUSY;
-	} else
+	/* Make sure we wait until init is complete... */
+	mutex_lock(&i2400m->init_mutex);
+	if (i2400m->updown)
 		result = 0;
+	else
+		result = -EBUSY;
+	mutex_unlock(&i2400m->init_mutex);
 	d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
 		net_dev, i2400m, result);
 	return result;
 }
 
 
-/*
- *
- * On kernel versions where cancel_work_sync() didn't return anything,
- * we rely on wake_tx_skb() being non-NULL.
- */
 static
 int i2400m_stop(struct net_device *net_dev)
 {
@@ -124,21 +125,7 @@ int i2400m_stop(struct net_device *net_d
 	struct device *dev = i2400m_dev(i2400m);
 
 	d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m);
-	/* See i2400m_hard_start_xmit(), references are taken there
-	 * and here we release them if the work was still
-	 * pending. Note we can't differentiate work not pending vs
-	 * never scheduled, so the NULL check does that. */
-	if (cancel_work_sync(&i2400m->wake_tx_ws) == 0
-	    && i2400m->wake_tx_skb != NULL) {
-		unsigned long flags;
-		struct sk_buff *wake_tx_skb;
-		spin_lock_irqsave(&i2400m->tx_lock, flags);
-		wake_tx_skb = i2400m->wake_tx_skb;	/* compat help */
-		i2400m->wake_tx_skb = NULL;	/* compat help */
-		spin_unlock_irqrestore(&i2400m->tx_lock, flags);
-		i2400m_put(i2400m);
-		kfree_skb(wake_tx_skb);
-	}
+	i2400m_net_wake_stop(i2400m);
 	d_fnend(3, dev, "(net_dev %p [i2400m %p]) = 0\n", net_dev, i2400m);
 	return 0;
 }
@@ -167,6 +154,7 @@ void i2400m_wake_tx_work(struct work_str
 {
 	int result;
 	struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws);
+	struct net_device *net_dev = i2400m->wimax_dev.net_dev;
 	struct device *dev = i2400m_dev(i2400m);
 	struct sk_buff *skb = i2400m->wake_tx_skb;
 	unsigned long flags;
@@ -182,27 +170,36 @@ void i2400m_wake_tx_work(struct work_str
 		dev_err(dev, "WAKE&TX: skb dissapeared!\n");
 		goto out_put;
 	}
+	/* If we have, somehow, lost the connection after this was
+	 * queued, don't do anything; this might be the device got
+	 * reset or just disconnected. */
+	if (unlikely(!netif_carrier_ok(net_dev)))
+		goto out_kfree;
 	result = i2400m_cmd_exit_idle(i2400m);
 	if (result == -EILSEQ)
 		result = 0;
 	if (result < 0) {
 		dev_err(dev, "WAKE&TX: device didn't get out of idle: "
-			"%d\n", result);
-			goto error;
+			"%d - resetting\n", result);
+		i2400m_reset(i2400m, I2400M_RT_BUS);
+		goto error;
 	}
 	result = wait_event_timeout(i2400m->state_wq,
-				    i2400m->state != I2400M_SS_IDLE, 5 * HZ);
+				    i2400m->state != I2400M_SS_IDLE,
+				    net_dev->watchdog_timeo - HZ/2);
 	if (result == 0)
 		result = -ETIMEDOUT;
 	if (result < 0) {
 		dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: "
-			"%d\n", result);
+			"%d - resetting\n", result);
+		i2400m_reset(i2400m, I2400M_RT_BUS);
 		goto error;
 	}
 	msleep(20);	/* device still needs some time or it drops it */
 	result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA);
-	netif_wake_queue(i2400m->wimax_dev.net_dev);
 error:
+	netif_wake_queue(net_dev);
+out_kfree:
 	kfree_skb(skb);	/* refcount transferred by _hard_start_xmit() */
 out_put:
 	i2400m_put(i2400m);
@@ -229,6 +226,38 @@ void i2400m_tx_prep_header(struct sk_buf
 }
 
 
+
+/*
+ * Cleanup resources acquired during i2400m_net_wake_tx()
+ *
+ * This is called by __i2400m_dev_stop and means we have to make sure
+ * the workqueue is flushed from any pending work.
+ */
+void i2400m_net_wake_stop(struct i2400m *i2400m)
+{
+	struct device *dev = i2400m_dev(i2400m);
+
+	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
+	/* See i2400m_hard_start_xmit(), references are taken there
+	 * and here we release them if the work was still
+	 * pending. Note we can't differentiate work not pending vs
+	 * never scheduled, so the NULL check does that. */
+	if (cancel_work_sync(&i2400m->wake_tx_ws) == 0
+	    && i2400m->wake_tx_skb != NULL) {
+		unsigned long flags;
+		struct sk_buff *wake_tx_skb;
+		spin_lock_irqsave(&i2400m->tx_lock, flags);
+		wake_tx_skb = i2400m->wake_tx_skb;	/* compat help */
+		i2400m->wake_tx_skb = NULL;	/* compat help */
+		spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+		i2400m_put(i2400m);
+		kfree_skb(wake_tx_skb);
+	}
+	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
+	return;
+}
+
+
 /*
  * TX an skb to an idle device
  *
@@ -342,6 +371,20 @@ netdev_tx_t i2400m_hard_start_xmit(struc
 	int result;
 
 	d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
+	if (skb_header_cloned(skb)) {
+		/*
+		 * Make tcpdump/wireshark happy -- if they are
+		 * running, the skb is cloned and we will overwrite
+		 * the mac fields in i2400m_tx_prep_header. Expand
+		 * seems to fix this...
+		 */
+		result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+		if (result) {
+			result = NETDEV_TX_BUSY;
+			goto error_expand;
+		}
+	}
+
 	if (i2400m->state == I2400M_SS_IDLE)
 		result = i2400m_net_wake_tx(i2400m, net_dev, skb);
 	else
@@ -352,10 +395,11 @@ netdev_tx_t i2400m_hard_start_xmit(struc
 		net_dev->stats.tx_packets++;
 		net_dev->stats.tx_bytes += skb->len;
 	}
+	result = NETDEV_TX_OK;
+error_expand:
 	kfree_skb(skb);
-
-	d_fnend(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
-	return NETDEV_TX_OK;
+	d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
+	return result;
 }
 
 
@@ -559,6 +603,22 @@ static const struct net_device_ops i2400
 	.ndo_change_mtu = i2400m_change_mtu,
 };
 
+static void i2400m_get_drvinfo(struct net_device *net_dev,
+			       struct ethtool_drvinfo *info)
+{
+	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
+
+	strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
+	strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+	if (net_dev->dev.parent)
+		strncpy(info->bus_info, dev_name(net_dev->dev.parent),
+			sizeof(info->bus_info) - 1);
+}
+
+static const struct ethtool_ops i2400m_ethtool_ops = {
+	.get_drvinfo = i2400m_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+};
 
 /**
  * i2400m_netdev_setup - Setup setup @net_dev's i2400m private data
@@ -580,6 +640,7 @@ void i2400m_netdev_setup(struct net_devi
 		   & ~IFF_MULTICAST);
 	net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
 	net_dev->netdev_ops = &i2400m_netdev_ops;
+	net_dev->ethtool_ops = &i2400m_ethtool_ops;
 	d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
 }
 EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/rx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -158,30 +158,104 @@ struct i2400m_report_hook_args {
 	struct sk_buff *skb_rx;
 	const struct i2400m_l3l4_hdr *l3l4_hdr;
 	size_t size;
+	struct list_head list_node;
 };
 
 
 /*
  * Execute i2400m_report_hook in a workqueue
  *
- * Unpacks arguments from the deferred call, executes it and then
- * drops the references.
+ * Goes over the list of queued reports in i2400m->rx_reports and
+ * processes them.
  *
- * Obvious NOTE: References are needed because we are a separate
- *     thread; otherwise the buffer changes under us because it is
- *     released by the original caller.
+ * NOTE: refcounts on i2400m are not needed because we flush the
+ *     workqueue this runs on (i2400m->work_queue) before destroying
+ *     i2400m.
  */
-static
 void i2400m_report_hook_work(struct work_struct *ws)
 {
-	struct i2400m_work *iw =
-		container_of(ws, struct i2400m_work, ws);
-	struct i2400m_report_hook_args *args = (void *) iw->pl;
-	if (iw->i2400m->ready)
-		i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
-	kfree_skb(args->skb_rx);
-	i2400m_put(iw->i2400m);
-	kfree(iw);
+	struct i2400m *i2400m = container_of(ws, struct i2400m, rx_report_ws);
+	struct device *dev = i2400m_dev(i2400m);
+	struct i2400m_report_hook_args *args, *args_next;
+	LIST_HEAD(list);
+	unsigned long flags;
+
+	while (1) {
+		spin_lock_irqsave(&i2400m->rx_lock, flags);
+		list_splice_init(&i2400m->rx_reports, &list);
+		spin_unlock_irqrestore(&i2400m->rx_lock, flags);
+		if (list_empty(&list))
+			break;
+		else
+			d_printf(1, dev, "processing queued reports\n");
+		list_for_each_entry_safe(args, args_next, &list, list_node) {
+			d_printf(2, dev, "processing queued report %p\n", args);
+			i2400m_report_hook(i2400m, args->l3l4_hdr, args->size);
+			kfree_skb(args->skb_rx);
+			list_del(&args->list_node);
+			kfree(args);
+		}
+	}
+}
+
+
+/*
+ * Flush the list of queued reports
+ */
+static
+void i2400m_report_hook_flush(struct i2400m *i2400m)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	struct i2400m_report_hook_args *args, *args_next;
+	LIST_HEAD(list);
+	unsigned long flags;
+
+	d_printf(1, dev, "flushing queued reports\n");
+	spin_lock_irqsave(&i2400m->rx_lock, flags);
+	list_splice_init(&i2400m->rx_reports, &list);
+	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
+	list_for_each_entry_safe(args, args_next, &list, list_node) {
+		d_printf(2, dev, "flushing queued report %p\n", args);
+		kfree_skb(args->skb_rx);
+		list_del(&args->list_node);
+		kfree(args);
+	}
+}
+
+
+/*
+ * Queue a report for later processing
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the payload (for reference counting)
+ * @l3l4_hdr: pointer to the control
+ * @size: size of the message
+ */
+static
+void i2400m_report_hook_queue(struct i2400m *i2400m, struct sk_buff *skb_rx,
+			      const void *l3l4_hdr, size_t size)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	unsigned long flags;
+	struct i2400m_report_hook_args *args;
+
+	args = kzalloc(sizeof(*args), GFP_NOIO);
+	if (args) {
+		args->skb_rx = skb_get(skb_rx);
+		args->l3l4_hdr = l3l4_hdr;
+		args->size = size;
+		spin_lock_irqsave(&i2400m->rx_lock, flags);
+		list_add_tail(&args->list_node, &i2400m->rx_reports);
+		spin_unlock_irqrestore(&i2400m->rx_lock, flags);
+		d_printf(2, dev, "queued report %p\n", args);
+		rmb();		/* see i2400m->ready's documentation  */
+		if (likely(i2400m->ready))	/* only send if up */
+			queue_work(i2400m->work_queue, &i2400m->rx_report_ws);
+	} else  {
+		if (printk_ratelimit())
+			dev_err(dev, "%s:%u: Can't allocate %zu B\n",
+				__func__, __LINE__, sizeof(*args));
+	}
 }
 
 
@@ -295,21 +369,29 @@ void i2400m_rx_ctl(struct i2400m *i2400m
 		 msg_type, size);
 	d_dump(2, dev, l3l4_hdr, size);
 	if (msg_type & I2400M_MT_REPORT_MASK) {
-		/* These hooks have to be ran serialized; as well, the
-		 * handling might force the execution of commands, and
-		 * that might cause reentrancy issues with
-		 * bus-specific subdrivers and workqueues. So we run
-		 * it in a separate workqueue. */
-		struct i2400m_report_hook_args args = {
-			.skb_rx = skb_rx,
-			.l3l4_hdr = l3l4_hdr,
-			.size = size
-		};
-		if (unlikely(i2400m->ready == 0))	/* only send if up */
-			return;
-		skb_get(skb_rx);
-		i2400m_queue_work(i2400m, i2400m_report_hook_work,
-				  GFP_KERNEL, &args, sizeof(args));
+		/*
+		 * Process each report
+		 *
+		 * - has to be ran serialized as well
+		 *
+		 * - the handling might force the execution of
+		 *   commands. That might cause reentrancy issues with
+		 *   bus-specific subdrivers and workqueues, so the we
+		 *   run it in a separate workqueue.
+		 *
+		 * - when the driver is not yet ready to handle them,
+		 *   they are queued and at some point the queue is
+		 *   restarted [NOTE: we can't queue SKBs directly, as
+		 *   this might be a piece of a SKB, not the whole
+		 *   thing, and this is cheaper than cloning the
+		 *   SKB].
+		 *
+		 * Note we don't do refcounting for the device
+		 * structure; this is because before destroying
+		 * 'i2400m', we make sure to flush the
+		 * i2400m->work_queue, so there are no issues.
+		 */
+		i2400m_report_hook_queue(i2400m, skb_rx, l3l4_hdr, size);
 		if (unlikely(i2400m->trace_msg_from_user))
 			wimax_msg(&i2400m->wimax_dev, "echo",
 				  l3l4_hdr, size, GFP_KERNEL);
@@ -363,8 +445,6 @@ void i2400m_rx_trace(struct i2400m *i240
 		 msg_type & I2400M_MT_REPORT_MASK ? "REPORT" : "CMD/SET/GET",
 		 msg_type, size);
 	d_dump(2, dev, l3l4_hdr, size);
-	if (unlikely(i2400m->ready == 0))	/* only send if up */
-		return;
 	result = wimax_msg(wimax_dev, "trace", l3l4_hdr, size, GFP_KERNEL);
 	if (result < 0)
 		dev_err(dev, "error sending trace to userspace: %d\n",
@@ -748,7 +828,7 @@ void i2400m_roq_queue(struct i2400m *i24
 		dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n",
 			nsn, lbn, roq->ws);
 		i2400m_roq_log_dump(i2400m, roq);
-		i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+		i2400m_reset(i2400m, I2400M_RT_WARM);
 	} else {
 		__i2400m_roq_queue(i2400m, roq, skb, lbn, nsn);
 		i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET,
@@ -814,7 +894,7 @@ void i2400m_roq_queue_update_ws(struct i
 		dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n",
 			nsn, sn, roq->ws);
 		i2400m_roq_log_dump(i2400m, roq);
-		i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+		i2400m_reset(i2400m, I2400M_RT_WARM);
 	} else {
 		/* if the queue is empty, don't bother as we'd queue
 		 * it and inmediately unqueue it -- just deliver it */
@@ -1114,7 +1194,7 @@ error:
  * device. See the file header for the format. Run all checks on the
  * buffer header, then run over each payload's descriptors, verify
  * their consistency and act on each payload's contents.  If
- * everything is succesful, update the device's statistics.
+ * everything is successful, update the device's statistics.
  *
  * Note: You need to set the skb to contain only the length of the
  * received buffer; for that, use skb_trim(skb, RECEIVED_SIZE).
@@ -1194,6 +1274,28 @@ error_msg_hdr_check:
 EXPORT_SYMBOL_GPL(i2400m_rx);
 
 
+void i2400m_unknown_barker(struct i2400m *i2400m,
+			   const void *buf, size_t size)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	char prefix[64];
+	const __le32 *barker = buf;
+	dev_err(dev, "RX: HW BUG? unknown barker %08x, "
+		"dropping %zu bytes\n", le32_to_cpu(*barker), size);
+	snprintf(prefix, sizeof(prefix), "%s %s: ",
+		 dev_driver_string(dev), dev_name(dev));
+	if (size > 64) {
+		print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
+			       8, 4, buf, 64, 0);
+		printk(KERN_ERR "%s... (only first 64 bytes "
+		       "dumped)\n", prefix);
+	} else
+		print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
+			       8, 4, buf, size, 0);
+}
+EXPORT_SYMBOL(i2400m_unknown_barker);
+
+
 /*
  * Initialize the RX queue and infrastructure
  *
@@ -1261,4 +1363,6 @@ void i2400m_rx_release(struct i2400m *i2
 		kfree(i2400m->rx_roq[0].log);
 		kfree(i2400m->rx_roq);
 	}
+	/* at this point, nothing can be received... */
+	i2400m_report_hook_flush(i2400m);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 14:04:28.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 12:12:03.000000000 -0400
@@ -43,18 +43,9 @@
  *     i2400m_release()
  *     free_netdev(net_dev)
  *
- * i2400ms_bus_reset()            Called by i2400m->bus_reset
+ * i2400ms_bus_reset()            Called by i2400m_reset
  *   __i2400ms_reset()
  *     __i2400ms_send_barker()
- *
- * i2400ms_bus_dev_start()        Called by i2400m_dev_start() [who is
- *   i2400ms_tx_setup()           called by i2400m_setup()]
- *   i2400ms_rx_setup()
- *
- * i2400ms_bus_dev_stop()         Called by i2400m_dev_stop() [who is
- *   i2400ms_rx_release()         is called by i2400m_release()]
- *   i2400ms_tx_release()
- *
  */
 
 #include <linux/debugfs.h>
@@ -71,6 +62,14 @@
 static int ioe_timeout = 2;
 module_param(ioe_timeout, int, 0);
 
+static char i2400ms_debug_params[128];
+module_param_string(debug, i2400ms_debug_params, sizeof(i2400ms_debug_params),
+		    0644);
+MODULE_PARM_DESC(debug,
+		 "String of space-separated NAME:VALUE pairs, where NAMEs "
+		 "are the different debug submodules and VALUE are the "
+		 "initial debug value to set.");
+
 /* Our firmware file name list */
 static const char *i2400ms_bus_fw_names[] = {
 #define I2400MS_FW_FILE_NAME "/*(DEBLOBBED)*/"
@@ -95,17 +94,24 @@ static const struct i2400m_poke_table i2
  * when we ask it to explicitly doing). Tries until a timeout is
  * reached.
  *
+ * The @maxtries argument indicates how many times (at most) it should
+ * be tried to enable the function. 0 means forever. This acts along
+ * with the timeout (ie: it'll stop trying as soon as the maximum
+ * number of tries is reached _or_ as soon as the timeout is reached).
+ *
  * The reverse of this is...sdio_disable_function()
  *
  * Returns: 0 if the SDIO function was enabled, < 0 errno code on
  *     error (-ENODEV when it was unable to enable the function).
  */
 static
-int i2400ms_enable_function(struct sdio_func *func)
+int i2400ms_enable_function(struct i2400ms *i2400ms, unsigned maxtries)
 {
+	struct sdio_func *func = i2400ms->func;
 	u64 timeout;
 	int err;
 	struct device *dev = &func->dev;
+	unsigned tries = 0;
 
 	d_fnstart(3, dev, "(func %p)\n", func);
 	/* Setup timeout (FIXME: This needs to read the CIS table to
@@ -115,6 +121,14 @@ int i2400ms_enable_function(struct sdio_
 	err = -ENODEV;
 	while (err != 0 && time_before64(get_jiffies_64(), timeout)) {
 		sdio_claim_host(func);
+		/*
+		 * There is a sillicon bug on the IWMC3200, where the
+		 * IOE timeout will cause problems on Moorestown
+		 * platforms (system hang). We explicitly overwrite
+		 * func->enable_timeout here to work around the issue.
+		 */
+		if (i2400ms->iwmc3200)
+			func->enable_timeout = IWMC3200_IOR_TIMEOUT;
 		err = sdio_enable_func(func);
 		if (0 == err) {
 			sdio_release_host(func);
@@ -122,8 +136,11 @@ int i2400ms_enable_function(struct sdio_
 			goto function_enabled;
 		}
 		d_printf(2, dev, "SDIO function failed to enable: %d\n", err);
-		sdio_disable_func(func);
 		sdio_release_host(func);
+		if (maxtries > 0 && ++tries >= maxtries) {
+			err = -ETIME;
+			break;
+		}
 		msleep(I2400MS_INIT_SLEEP_INTERVAL);
 	}
 	/* If timed out, device is not there yet -- get -ENODEV so
@@ -140,46 +157,99 @@ function_enabled:
 
 
 /*
- * Setup driver resources needed to communicate with the device
+ * Setup minimal device communication infrastructure needed to at
+ * least be able to update the firmware.
  *
- * The fw needs some time to settle, and it was just uploaded,
- * so give it a break first. I'd prefer to just wait for the device to
- * send something, but seems the poking we do to enable SDIO stuff
- * interferes with it, so just give it a break before starting...
+ * Note the ugly trick: if we are in the probe path
+ * (i2400ms->debugfs_dentry == NULL), we only retry function
+ * enablement one, to avoid racing with the iwmc3200 top controller.
  */
 static
-int i2400ms_bus_dev_start(struct i2400m *i2400m)
+int i2400ms_bus_setup(struct i2400m *i2400m)
 {
 	int result;
-	struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
+	struct i2400ms *i2400ms =
+		container_of(i2400m, struct i2400ms, i2400m);
+	struct device *dev = i2400m_dev(i2400m);
 	struct sdio_func *func = i2400ms->func;
-	struct device *dev = &func->dev;
+	int retries;
+
+	sdio_claim_host(func);
+	result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
+	sdio_release_host(func);
+	if (result < 0) {
+		dev_err(dev, "Failed to set block size: %d\n", result);
+		goto error_set_blk_size;
+	}
+
+	if (i2400ms->iwmc3200 && i2400ms->debugfs_dentry == NULL)
+		retries = 1;
+	else
+		retries = 0;
+	result = i2400ms_enable_function(i2400ms, retries);
+	if (result < 0) {
+		dev_err(dev, "Cannot enable SDIO function: %d\n", result);
+		goto error_func_enable;
+	}
 
-	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
-	msleep(200);
 	result = i2400ms_tx_setup(i2400ms);
 	if (result < 0)
 		goto error_tx_setup;
-	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
-	return result;
+	result = i2400ms_rx_setup(i2400ms);
+	if (result < 0)
+		goto error_rx_setup;
+	return 0;
 
-error_tx_setup:
+error_rx_setup:
 	i2400ms_tx_release(i2400ms);
-	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
+error_tx_setup:
+	sdio_claim_host(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+error_func_enable:
+error_set_blk_size:
 	return result;
 }
 
 
+/*
+ * Tear down minimal device communication infrastructure needed to at
+ * least be able to update the firmware.
+ */
 static
-void i2400ms_bus_dev_stop(struct i2400m *i2400m)
+void i2400ms_bus_release(struct i2400m *i2400m)
+{
+	struct i2400ms *i2400ms =
+		container_of(i2400m, struct i2400ms, i2400m);
+	struct sdio_func *func = i2400ms->func;
+
+	i2400ms_rx_release(i2400ms);
+	i2400ms_tx_release(i2400ms);
+	sdio_claim_host(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+}
+
+
+/*
+ * Setup driver resources needed to communicate with the device
+ *
+ * The fw needs some time to settle, and it was just uploaded,
+ * so give it a break first. I'd prefer to just wait for the device to
+ * send something, but seems the poking we do to enable SDIO stuff
+ * interferes with it, so just give it a break before starting...
+ */
+static
+int i2400ms_bus_dev_start(struct i2400m *i2400m)
 {
 	struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
 	struct sdio_func *func = i2400ms->func;
 	struct device *dev = &func->dev;
 
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
-	i2400ms_tx_release(i2400ms);
-	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
+	msleep(200);
+	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, 0);
+	return 0;
 }
 
 
@@ -233,18 +303,17 @@ error_kzalloc:
  * Warm reset:
  *
  * The device will be fully reset internally, but won't be
- * disconnected from the USB bus (so no reenumeration will
+ * disconnected from the bus (so no reenumeration will
  * happen). Firmware upload will be neccessary.
  *
- * The device will send a reboot barker in the notification endpoint
- * that will trigger the driver to reinitialize the state
- * automatically from notif.c:i2400m_notification_grok() into
- * i2400m_dev_bootstrap_delayed().
+ * The device will send a reboot barker that will trigger the driver
+ * to reinitialize the state via __i2400m_dev_reset_handle.
  *
- * Cold and bus (USB) reset:
+ *
+ * Cold and bus reset:
  *
  * The device will be fully reset internally, disconnected from the
- * USB bus an a reenumeration will happen. Firmware upload will be
+ * bus an a reenumeration will happen. Firmware upload will be
  * neccessary. Thus, we don't do any locking or struct
  * reinitialization, as we are going to be fully disconnected and
  * reenumerated.
@@ -283,25 +352,13 @@ int i2400ms_bus_reset(struct i2400m *i24
 					       sizeof(i2400m_COLD_BOOT_BARKER));
 	else if (rt == I2400M_RT_BUS) {
 do_bus_reset:
-		/* call netif_tx_disable() before sending IOE disable,
-		 * so that all the tx from network layer are stopped
-		 * while IOE is being reset. Make sure it is called
-		 * only after register_netdev() was issued.
-		 */
-		if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
-			netif_tx_disable(i2400m->wimax_dev.net_dev);
 
-		i2400ms_rx_release(i2400ms);
-		sdio_claim_host(i2400ms->func);
-		sdio_disable_func(i2400ms->func);
-		sdio_release_host(i2400ms->func);
+		i2400ms_bus_release(i2400m);
 
 		/* Wait for the device to settle */
 		msleep(40);
 
-		result = i2400ms_enable_function(i2400ms->func);
-		if (result >= 0)
-			i2400ms_rx_setup(i2400ms);
+		result =  i2400ms_bus_setup(i2400m);
 	} else
 		BUG();
 	if (result < 0 && rt != I2400M_RT_BUS) {
@@ -350,7 +407,7 @@ int i2400ms_debugfs_add(struct i2400ms *
 	int result;
 	struct dentry *dentry = i2400ms->i2400m.wimax_dev.debugfs_dentry;
 
-	dentry = debugfs_create_dir("i2400m-usb", dentry);
+	dentry = debugfs_create_dir("i2400m-sdio", dentry);
 	result = PTR_ERR(dentry);
 	if (IS_ERR(dentry)) {
 		if (result == -ENODEV)
@@ -367,6 +424,7 @@ int i2400ms_debugfs_add(struct i2400ms *
 
 error:
 	debugfs_remove_recursive(i2400ms->debugfs_dentry);
+	i2400ms->debugfs_dentry = NULL;
 	return result;
 }
 
@@ -425,37 +483,30 @@ int i2400ms_probe(struct sdio_func *func
 
 	i2400m->bus_tx_block_size = I2400MS_BLK_SIZE;
 	i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX;
+	i2400m->bus_setup = i2400ms_bus_setup;
 	i2400m->bus_dev_start = i2400ms_bus_dev_start;
-	i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
+	i2400m->bus_dev_stop = NULL;
+	i2400m->bus_release = i2400ms_bus_release;
 	i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
 	i2400m->bus_reset = i2400ms_bus_reset;
 	/* The iwmc3200-wimax sometimes requires the driver to try
 	 * hard when we paint it into a corner. */
-	i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
+	i2400m->bus_bm_retries = I2400M_SDIO_BOOT_RETRIES;
 	i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
 	i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
 	i2400m->bus_fw_names = i2400ms_bus_fw_names;
 	i2400m->bus_bm_mac_addr_impaired = 1;
 	i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
 
-	sdio_claim_host(func);
-	result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
-	sdio_release_host(func);
-	if (result < 0) {
-		dev_err(dev, "Failed to set block size: %d\n", result);
-		goto error_set_blk_size;
-	}
-
-	result = i2400ms_enable_function(i2400ms->func);
-	if (result < 0) {
-		dev_err(dev, "Cannot enable SDIO function: %d\n", result);
-		goto error_func_enable;
+	switch (func->device) {
+	case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX:
+	case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5:
+		i2400ms->iwmc3200 = 1;
+		break;
+	default:
+		i2400ms->iwmc3200 = 0;
 	}
 
-	result = i2400ms_rx_setup(i2400ms);
-	if (result < 0)
-		goto error_rx_setup;
-
 	result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
 	if (result < 0) {
 		dev_err(dev, "cannot setup device: %d\n", result);
@@ -473,13 +524,6 @@ int i2400ms_probe(struct sdio_func *func
 error_debugfs_add:
 	i2400m_release(i2400m);
 error_setup:
-	i2400ms_rx_release(i2400ms);
-error_rx_setup:
-	sdio_claim_host(func);
-	sdio_disable_func(func);
-	sdio_release_host(func);
-error_func_enable:
-error_set_blk_size:
 	sdio_set_drvdata(func, NULL);
 	free_netdev(net_dev);
 error_alloc_netdev:
@@ -497,12 +541,9 @@ void i2400ms_remove(struct sdio_func *fu
 
 	d_fnstart(3, dev, "SDIO func %p\n", func);
 	debugfs_remove_recursive(i2400ms->debugfs_dentry);
-	i2400ms_rx_release(i2400ms);
+	i2400ms->debugfs_dentry = NULL;
 	i2400m_release(i2400m);
 	sdio_set_drvdata(func, NULL);
-	sdio_claim_host(func);
-	sdio_disable_func(func);
-	sdio_release_host(func);
 	free_netdev(net_dev);
 	d_fnend(3, dev, "SDIO func %p\n", func);
 }
@@ -512,6 +553,8 @@ const struct sdio_device_id i2400ms_sdio
 	/* Intel: i2400m WiMAX (iwmc3200) over SDIO */
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
 		      SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
+		      SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5) },
 	{ /* end: all zeroes */ },
 };
 MODULE_DEVICE_TABLE(sdio, i2400ms_sdio_ids);
@@ -529,6 +572,8 @@ struct sdio_driver i2400m_sdio_driver =
 static
 int __init i2400ms_driver_init(void)
 {
+	d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400ms_debug_params,
+		       "i2400m_sdio.debug");
 	return sdio_register_driver(&i2400m_sdio_driver);
 }
 module_init(i2400ms_driver_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-fw.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-fw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-fw.c	2010-02-24 13:52:17.000000000 -0500
@@ -118,7 +118,8 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i
 	if (cmd_size > I2400M_BM_CMD_BUF_SIZE)
 		goto error_too_big;
 
-	memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size);	/* Prep command */
+	if (_cmd != i2400m->bm_cmd_buf)
+		memmove(i2400m->bm_cmd_buf, _cmd, cmd_size);
 	cmd = i2400m->bm_cmd_buf;
 	if (cmd_size_a > cmd_size)			/* Zero pad space */
 		memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size);
@@ -177,10 +178,6 @@ ssize_t i2400ms_bus_bm_wait_for_ack(stru
 	d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n",
 		  i2400m, ack, ack_size);
 
-	spin_lock(&i2400m->rx_lock);
-	i2400ms->bm_ack_size = -EINPROGRESS;
-	spin_unlock(&i2400m->rx_lock);
-
 	result = wait_event_timeout(i2400ms->bm_wfa_wq,
 				    i2400ms->bm_ack_size != -EINPROGRESS,
 				    2 * HZ);
@@ -199,6 +196,10 @@ ssize_t i2400ms_bus_bm_wait_for_ack(stru
 		size = min(ack_size, i2400ms->bm_ack_size);
 		memcpy(ack, i2400m->bm_ack_buf, size);
 	}
+	/*
+	 * Remember always to clear the bm_ack_size to -EINPROGRESS
+	 * after the RX data is processed
+	 */
 	i2400ms->bm_ack_size = -EINPROGRESS;
 	spin_unlock(&i2400m->rx_lock);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-rx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,6 +53,7 @@
  * i2400ms_irq()
  *   i2400ms_rx()
  *     __i2400ms_rx_get_size()
+ *     i2400m_is_boot_barker()
  *     i2400m_rx()
  *
  * i2400ms_rx_setup()
@@ -138,6 +139,11 @@ void i2400ms_rx(struct i2400ms *i2400ms)
 		ret = rx_size;
 		goto error_get_size;
 	}
+	/*
+	 * Hardware quirk: make sure to clear the INTR status register
+	 * AFTER getting the data transfer size.
+	 */
+	sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret);
 
 	ret = -ENOMEM;
 	skb = alloc_skb(rx_size, GFP_ATOMIC);
@@ -153,25 +159,34 @@ void i2400ms_rx(struct i2400ms *i2400ms)
 	}
 
 	rmb();	/* make sure we get boot_mode from dev_reset_handle */
-	if (i2400m->boot_mode == 1) {
+	if (unlikely(i2400m->boot_mode == 1)) {
 		spin_lock(&i2400m->rx_lock);
 		i2400ms->bm_ack_size = rx_size;
 		spin_unlock(&i2400m->rx_lock);
 		memcpy(i2400m->bm_ack_buf, skb->data, rx_size);
 		wake_up(&i2400ms->bm_wfa_wq);
-		dev_err(dev, "RX: SDIO boot mode message\n");
+		d_printf(5, dev, "RX: SDIO boot mode message\n");
 		kfree_skb(skb);
-	} else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER,
-				    sizeof(i2400m_NBOOT_BARKER))
-			    || !memcmp(skb->data, i2400m_SBOOT_BARKER,
-				       sizeof(i2400m_SBOOT_BARKER)))) {
-		ret = i2400m_dev_reset_handle(i2400m);
+		goto out;
+	}
+	ret = -EIO;
+	if (unlikely(rx_size < sizeof(__le32))) {
+		dev_err(dev, "HW BUG? only %zu bytes received\n", rx_size);
+		goto error_bad_size;
+	}
+	if (likely(i2400m_is_d2h_barker(skb->data))) {
+		skb_put(skb, rx_size);
+		i2400m_rx(i2400m, skb);
+	} else if (unlikely(i2400m_is_boot_barker(i2400m,
+						  skb->data, rx_size))) {
+		ret = i2400m_dev_reset_handle(i2400m, "device rebooted");
 		dev_err(dev, "RX: SDIO reboot barker\n");
 		kfree_skb(skb);
 	} else {
-		skb_put(skb, rx_size);
-		i2400m_rx(i2400m, skb);
+		i2400m_unknown_barker(i2400m, skb->data, rx_size);
+		kfree_skb(skb);
 	}
+out:
 	d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms);
 	return;
 
@@ -179,6 +194,7 @@ error_memcpy_fromio:
 	kfree_skb(skb);
 error_alloc_skb:
 error_get_size:
+error_bad_size:
 	d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret);
 	return;
 }
@@ -209,7 +225,6 @@ void i2400ms_irq(struct sdio_func *func)
 		dev_err(dev, "RX: BUG? got IRQ but no interrupt ready?\n");
 		goto error_no_irq;
 	}
-	sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret);
 	i2400ms_rx(i2400ms);
 error_no_irq:
 	d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms);
@@ -234,6 +249,13 @@ int i2400ms_rx_setup(struct i2400ms *i24
 	init_waitqueue_head(&i2400ms->bm_wfa_wq);
 	spin_lock(&i2400m->rx_lock);
 	i2400ms->bm_wait_result = -EINPROGRESS;
+	/*
+	 * Before we are about to enable the RX interrupt, make sure
+	 * bm_ack_size is cleared to -EINPROGRESS which indicates
+	 * no RX interrupt happened yet or the previous interrupt
+	 * has been handled, we are ready to take the new interrupt
+	 */
+	i2400ms->bm_ack_size = -EINPROGRESS;
 	spin_unlock(&i2400m->rx_lock);
 
 	sdio_claim_host(func);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-tx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/sdio-tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/sdio-tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -149,5 +149,8 @@ int i2400ms_tx_setup(struct i2400ms *i24
 
 void i2400ms_tx_release(struct i2400ms *i2400ms)
 {
-	destroy_workqueue(i2400ms->tx_workqueue);
+	if (i2400ms->tx_workqueue) {
+		destroy_workqueue(i2400ms->tx_workqueue);
+		i2400ms->tx_workqueue = NULL;
+	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/tx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -310,7 +310,7 @@ size_t __i2400m_tx_tail_room(struct i240
 	size_t tail_room;
 	size_t tx_in;
 
-	if (unlikely(i2400m->tx_in) == 0)
+	if (unlikely(i2400m->tx_in == 0))
 		return I2400M_TX_BUF_SIZE;
 	tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
 	tail_room = I2400M_TX_BUF_SIZE - tx_in;
@@ -642,6 +642,9 @@ int i2400m_tx(struct i2400m *i2400m, con
 	 * current one is out of payload slots or we have a singleton,
 	 * close it and start a new one */
 	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	result = -ESHUTDOWN;
+	if (i2400m->tx_buf == NULL)
+		goto error_tx_new;
 try_new:
 	if (unlikely(i2400m->tx_msg == NULL))
 		i2400m_tx_new(i2400m);
@@ -697,7 +700,10 @@ try_new:
 	}
 error_tx_new:
 	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
-	i2400m->bus_tx_kick(i2400m);	/* always kick, might free up space */
+	/* kick in most cases, except when the TX subsys is down, as
+	 * it might free space */
+	if (likely(result != -ESHUTDOWN))
+		i2400m->bus_tx_kick(i2400m);
 	d_fnend(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u) = %d\n",
 		i2400m, buf, buf_len, pl_type, result);
 	return result;
@@ -740,6 +746,9 @@ struct i2400m_msg_hdr *i2400m_tx_msg_get
 
 	d_fnstart(3, dev, "(i2400m %p bus_size %p)\n", i2400m, bus_size);
 	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	tx_msg_moved = NULL;
+	if (i2400m->tx_buf == NULL)
+		goto out_unlock;
 skip:
 	tx_msg_moved = NULL;
 	if (i2400m->tx_in == i2400m->tx_out) {	/* Empty FIFO? */
@@ -829,6 +838,8 @@ void i2400m_tx_msg_sent(struct i2400m *i
 
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
 	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	if (i2400m->tx_buf == NULL)
+		goto out_unlock;
 	i2400m->tx_out += i2400m->tx_msg_size;
 	d_printf(2, dev, "TX: sent %zu b\n", (size_t) i2400m->tx_msg_size);
 	i2400m->tx_msg_size = 0;
@@ -837,6 +848,7 @@ void i2400m_tx_msg_sent(struct i2400m *i
 	n = i2400m->tx_out / I2400M_TX_BUF_SIZE;
 	i2400m->tx_out %= I2400M_TX_BUF_SIZE;
 	i2400m->tx_in -= n * I2400M_TX_BUF_SIZE;
+out_unlock:
 	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
 }
@@ -876,5 +888,9 @@ int i2400m_tx_setup(struct i2400m *i2400
  */
 void i2400m_tx_release(struct i2400m *i2400m)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
 	kfree(i2400m->tx_buf);
+	i2400m->tx_buf = NULL;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 14:04:30.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 12:12:06.000000000 -0400
@@ -58,7 +58,7 @@
  *   i2400mu_rx_release()
  *   i2400mu_tx_release()
  *
- * i2400mu_bus_reset()            Called by i2400m->bus_reset
+ * i2400mu_bus_reset()            Called by i2400m_reset
  *   __i2400mu_reset()
  *     __i2400mu_send_barker()
  *   usb_reset_device()
@@ -71,13 +71,25 @@
 #define D_SUBMODULE usb
 #include "usb-debug-levels.h"
 
+static char i2400mu_debug_params[128];
+module_param_string(debug, i2400mu_debug_params, sizeof(i2400mu_debug_params),
+		    0644);
+MODULE_PARM_DESC(debug,
+		 "String of space-separated NAME:VALUE pairs, where NAMEs "
+		 "are the different debug submodules and VALUE are the "
+		 "initial debug value to set.");
 
 /* Our firmware file name */
-static const char *i2400mu_bus_fw_names[] = {
+static const char *i2400mu_bus_fw_names_5x50[] = {
 #define I2400MU_FW_FILE_NAME_v1_4 "/*(DEBLOBBED)*/"
 	I2400MU_FW_FILE_NAME_v1_4,
-#define I2400MU_FW_FILE_NAME_v1_3 "/*(DEBLOBBED)*/"
-	I2400MU_FW_FILE_NAME_v1_3,
+	NULL,
+};
+
+
+static const char *i2400mu_bus_fw_names_6050[] = {
+#define I6050U_FW_FILE_NAME_v1_5 "/*(DEBLOBBED)*/"
+	I6050U_FW_FILE_NAME_v1_5,
 	NULL,
 };
 
@@ -160,14 +172,59 @@ int __i2400mu_send_barker(struct i2400mu
 	epd = usb_get_epd(i2400mu->usb_iface, endpoint);
 	pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 	memcpy(buffer, barker, barker_size);
+retry:
 	ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size,
-			   &actual_len, HZ);
-	if (ret < 0) {
-		if (ret != -EINVAL)
-			dev_err(dev, "E: barker error: %d\n", ret);
-	} else if (actual_len != barker_size) {
-		dev_err(dev, "E: only %d bytes transmitted\n", actual_len);
-		ret = -EIO;
+			   &actual_len, 200);
+	switch (ret) {
+	case 0:
+		if (actual_len != barker_size) {	/* Too short? drop it */
+			dev_err(dev, "E: %s: short write (%d B vs %zu "
+				"expected)\n",
+				__func__, actual_len, barker_size);
+			ret = -EIO;
+		}
+		break;
+	case -EPIPE:
+		/*
+		 * Stall -- maybe the device is choking with our
+		 * requests. Clear it and give it some time. If they
+		 * happen to often, it might be another symptom, so we
+		 * reset.
+		 *
+		 * No error handling for usb_clear_halt(0; if it
+		 * works, the retry works; if it fails, this switch
+		 * does the error handling for us.
+		 */
+		if (edc_inc(&i2400mu->urb_edc,
+			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+			dev_err(dev, "E: %s: too many stalls in "
+				"URB; resetting device\n", __func__);
+			usb_queue_reset_device(i2400mu->usb_iface);
+			/* fallthrough */
+		} else {
+			usb_clear_halt(i2400mu->usb_dev, pipe);
+			msleep(10);	/* give the device some time */
+			goto retry;
+		}
+	case -EINVAL:			/* while removing driver */
+	case -ENODEV:			/* dev disconnect ... */
+	case -ENOENT:			/* just ignore it */
+	case -ESHUTDOWN:		/* and exit */
+	case -ECONNRESET:
+		ret = -ESHUTDOWN;
+		break;
+	default:			/* Some error? */
+		if (edc_inc(&i2400mu->urb_edc,
+			    EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+			dev_err(dev, "E: %s: maximum errors in URB "
+				"exceeded; resetting device\n",
+				__func__);
+			usb_queue_reset_device(i2400mu->usb_iface);
+		} else {
+			dev_warn(dev, "W: %s: cannot send URB: %d\n",
+				 __func__, ret);
+			goto retry;
+		}
 	}
 	kfree(buffer);
 error_kzalloc:
@@ -232,15 +289,16 @@ int i2400mu_bus_reset(struct i2400m *i24
 
 	d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt);
 	if (rt == I2400M_RT_WARM)
-		result = __i2400mu_send_barker(i2400mu, i2400m_WARM_BOOT_BARKER,
-					       sizeof(i2400m_WARM_BOOT_BARKER),
-					       I2400MU_EP_BULK_OUT);
+		result = __i2400mu_send_barker(
+			i2400mu, i2400m_WARM_BOOT_BARKER,
+			sizeof(i2400m_WARM_BOOT_BARKER),
+			i2400mu->endpoint_cfg.bulk_out);
 	else if (rt == I2400M_RT_COLD)
-		result = __i2400mu_send_barker(i2400mu, i2400m_COLD_BOOT_BARKER,
-					       sizeof(i2400m_COLD_BOOT_BARKER),
-					       I2400MU_EP_RESET_COLD);
+		result = __i2400mu_send_barker(
+			i2400mu, i2400m_COLD_BOOT_BARKER,
+			sizeof(i2400m_COLD_BOOT_BARKER),
+			i2400mu->endpoint_cfg.reset_cold);
 	else if (rt == I2400M_RT_BUS) {
-do_bus_reset:
 		result = usb_reset_device(i2400mu->usb_dev);
 		switch (result) {
 		case 0:
@@ -248,7 +306,7 @@ do_bus_reset:
 		case -ENODEV:
 		case -ENOENT:
 		case -ESHUTDOWN:
-			result = rt == I2400M_RT_WARM ? -ENODEV : 0;
+			result = 0;
 			break;	/* We assume the device is disconnected */
 		default:
 			dev_err(dev, "USB reset failed (%d), giving up!\n",
@@ -261,10 +319,17 @@ do_bus_reset:
 	if (result < 0
 	    && result != -EINVAL	/* device is gone */
 	    && rt != I2400M_RT_BUS) {
+		/*
+		 * Things failed -- resort to lower level reset, that
+		 * we queue in another context; the reason for this is
+		 * that the pre and post reset functionality requires
+		 * the i2400m->init_mutex; RT_WARM and RT_COLD can
+		 * come from areas where i2400m->init_mutex is taken.
+		 */
 		dev_err(dev, "%s reset failed (%d); trying USB reset\n",
 			rt == I2400M_RT_WARM ? "warm" : "cold", result);
-		rt = I2400M_RT_BUS;
-		goto do_bus_reset;
+		usb_queue_reset_device(i2400mu->usb_iface);
+		result = -ENODEV;
 	}
 	d_fnend(3, dev, "(i2400m %p rt %u) = %d\n", i2400m, rt, result);
 	return result;
@@ -402,20 +467,42 @@ int i2400mu_probe(struct usb_interface *
 
 	i2400m->bus_tx_block_size = I2400MU_BLK_SIZE;
 	i2400m->bus_pl_size_max = I2400MU_PL_SIZE_MAX;
+	i2400m->bus_setup = NULL;
 	i2400m->bus_dev_start = i2400mu_bus_dev_start;
 	i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
+	i2400m->bus_release = NULL;
 	i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
 	i2400m->bus_reset = i2400mu_bus_reset;
-	i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
+	i2400m->bus_bm_retries = I2400M_USB_BOOT_RETRIES;
 	i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
 	i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
-	i2400m->bus_fw_names = i2400mu_bus_fw_names;
 	i2400m->bus_bm_mac_addr_impaired = 0;
 
+	switch (id->idProduct) {
+	case USB_DEVICE_ID_I6050:
+	case USB_DEVICE_ID_I6050_2:
+		i2400mu->i6050 = 1;
+		break;
+	default:
+		break;
+	}
+
+	if (i2400mu->i6050) {
+		i2400m->bus_fw_names = i2400mu_bus_fw_names_6050;
+		i2400mu->endpoint_cfg.bulk_out = 0;
+		i2400mu->endpoint_cfg.notification = 3;
+		i2400mu->endpoint_cfg.reset_cold = 2;
+		i2400mu->endpoint_cfg.bulk_in = 1;
+	} else {
+		i2400m->bus_fw_names = i2400mu_bus_fw_names_5x50;
+		i2400mu->endpoint_cfg.bulk_out = 0;
+		i2400mu->endpoint_cfg.notification = 1;
+		i2400mu->endpoint_cfg.reset_cold = 2;
+		i2400mu->endpoint_cfg.bulk_in = 3;
+	}
 #ifdef CONFIG_PM
 	iface->needs_remote_wakeup = 1;		/* autosuspend (15s delay) */
 	device_init_wakeup(dev, 1);
-	usb_autopm_enable(i2400mu->usb_iface);
 	usb_dev->autosuspend_delay = 15 * HZ;
 	usb_dev->autosuspend_disabled = 0;
 #endif
@@ -483,7 +570,10 @@ void i2400mu_disconnect(struct usb_inter
  * So at the end, the three cases require common handling.
  *
  * If at the time of this call the device's firmware is not loaded,
- * nothing has to be done.
+ * nothing has to be done. Note we can be "loose" about not reading
+ * i2400m->updown under i2400m->init_mutex. If it happens to change
+ * inmediately, other parts of the call flow will fail and effectively
+ * catch it.
  *
  * If the firmware is loaded, we need to:
  *
@@ -498,7 +588,7 @@ void i2400mu_disconnect(struct usb_inter
  *
  *    As well, the device might refuse going to sleep for whichever
  *    reason. In this case we just fail. For system suspend/hibernate,
- *    we *can't* fail. We look at usb_dev->auto_pm to see if the
+ *    we *can't* fail. We check PM_EVENT_AUTO to see if the
  *    suspend call comes from the USB stack or from the system and act
  *    in consequence.
  *
@@ -510,18 +600,16 @@ int i2400mu_suspend(struct usb_interface
 	int result = 0;
 	struct device *dev = &iface->dev;
 	struct i2400mu *i2400mu = usb_get_intfdata(iface);
-#ifdef CONFIG_PM
-	struct usb_device *usb_dev = i2400mu->usb_dev;
-#endif
 	unsigned is_autosuspend = 0;
 	struct i2400m *i2400m = &i2400mu->i2400m;
 
 #ifdef CONFIG_PM
-	if (usb_dev->auto_pm > 0)
+	if (pm_msg.event & PM_EVENT_AUTO)
 		is_autosuspend = 1;
 #endif
 
 	d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event);
+	rmb();		/* see i2400m->updown's documentation  */
 	if (i2400m->updown == 0)
 		goto no_firmware;
 	if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) {
@@ -575,6 +663,7 @@ int i2400mu_resume(struct usb_interface
 	struct i2400m *i2400m = &i2400mu->i2400m;
 
 	d_fnstart(3, dev, "(iface %p)\n", iface);
+	rmb();		/* see i2400m->updown's documentation  */
 	if (i2400m->updown == 0) {
 		d_printf(1, dev, "fw was down, no resume neeed\n");
 		goto out;
@@ -591,7 +680,55 @@ out:
 
 
 static
+int i2400mu_reset_resume(struct usb_interface *iface)
+{
+	int result;
+	struct device *dev = &iface->dev;
+	struct i2400mu *i2400mu = usb_get_intfdata(iface);
+	struct i2400m *i2400m = &i2400mu->i2400m;
+
+	d_fnstart(3, dev, "(iface %p)\n", iface);
+	result = i2400m_dev_reset_handle(i2400m, "device reset on resume");
+	d_fnend(3, dev, "(iface %p) = %d\n", iface, result);
+	return result < 0 ? result : 0;
+}
+
+
+/*
+ * Another driver or user space is triggering a reset on the device
+ * which contains the interface passed as an argument. Cease IO and
+ * save any device state you need to restore.
+ *
+ * If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if
+ * you are in atomic context.
+ */
+static
+int i2400mu_pre_reset(struct usb_interface *iface)
+{
+	struct i2400mu *i2400mu = usb_get_intfdata(iface);
+	return i2400m_pre_reset(&i2400mu->i2400m);
+}
+
+
+/*
+ * The reset has completed.  Restore any saved device state and begin
+ * using the device again.
+ *
+ * If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if
+ * you are in atomic context.
+ */
+static
+int i2400mu_post_reset(struct usb_interface *iface)
+{
+	struct i2400mu *i2400mu = usb_get_intfdata(iface);
+	return i2400m_post_reset(&i2400mu->i2400m);
+}
+
+
+static
 struct usb_device_id i2400mu_id_table[] = {
+	{ USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) },
+	{ USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) },
 	{ USB_DEVICE(0x8086, 0x0181) },
 	{ USB_DEVICE(0x8086, 0x1403) },
 	{ USB_DEVICE(0x8086, 0x1405) },
@@ -609,8 +746,11 @@ struct usb_driver i2400mu_driver = {
 	.name = KBUILD_MODNAME,
 	.suspend = i2400mu_suspend,
 	.resume = i2400mu_resume,
+	.reset_resume = i2400mu_reset_resume,
 	.probe = i2400mu_probe,
 	.disconnect = i2400mu_disconnect,
+	.pre_reset = i2400mu_pre_reset,
+	.post_reset = i2400mu_post_reset,
 	.id_table = i2400mu_id_table,
 	.supports_autosuspend = 1,
 };
@@ -618,6 +758,8 @@ struct usb_driver i2400mu_driver = {
 static
 int __init i2400mu_driver_init(void)
 {
+	d_parse_params(D_LEVEL, D_LEVEL_SIZE, i2400mu_debug_params,
+		       "i2400m_usb.debug");
 	return usb_register(&i2400mu_driver);
 }
 module_init(i2400mu_driver_init);
@@ -632,6 +774,7 @@ void __exit i2400mu_driver_exit(void)
 module_exit(i2400mu_driver_exit);
 
 MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
-MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB");
+MODULE_DESCRIPTION("Driver for USB based Intel Wireless WiMAX Connection 2400M "
+		   "(5x50 & 6050)");
 MODULE_LICENSE("GPL");
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-fw.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-fw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-fw.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,10 +99,10 @@ ssize_t i2400mu_tx_bulk_out(struct i2400
 		dev_err(dev, "BM-CMD: can't get autopm: %d\n", result);
 		do_autopm = 0;
 	}
-	epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT);
+	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out);
 	pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 retry:
-	result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, HZ);
+	result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, 200);
 	switch (result) {
 	case 0:
 		if (len != buf_size) {
@@ -113,6 +113,28 @@ retry:
 		}
 		result = len;
 		break;
+	case -EPIPE:
+		/*
+		 * Stall -- maybe the device is choking with our
+		 * requests. Clear it and give it some time. If they
+		 * happen to often, it might be another symptom, so we
+		 * reset.
+		 *
+		 * No error handling for usb_clear_halt(0; if it
+		 * works, the retry works; if it fails, this switch
+		 * does the error handling for us.
+		 */
+		if (edc_inc(&i2400mu->urb_edc,
+			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+			dev_err(dev, "BM-CMD: too many stalls in "
+				"URB; resetting device\n");
+			usb_queue_reset_device(i2400mu->usb_iface);
+			/* fallthrough */
+		} else {
+			usb_clear_halt(i2400mu->usb_dev, pipe);
+			msleep(10);	/* give the device some time */
+			goto retry;
+		}
 	case -EINVAL:			/* while removing driver */
 	case -ENODEV:			/* dev disconnect ... */
 	case -ENOENT:			/* just ignore it */
@@ -135,7 +157,6 @@ retry:
 			result);
 		goto retry;
 	}
-	result = len;
 	if (do_autopm)
 		usb_autopm_put_interface(i2400mu->usb_iface);
 	return result;
@@ -172,7 +193,8 @@ ssize_t i2400mu_bus_bm_cmd_send(struct i
 	result = -E2BIG;
 	if (cmd_size > I2400M_BM_CMD_BUF_SIZE)
 		goto error_too_big;
-	memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size);
+	if (_cmd != i2400m->bm_cmd_buf)
+		memmove(i2400m->bm_cmd_buf, _cmd, cmd_size);
 	cmd = i2400m->bm_cmd_buf;
 	if (cmd_size_a > cmd_size)			/* Zero pad space */
 		memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size);
@@ -226,7 +248,8 @@ int i2400mu_notif_submit(struct i2400mu
 	struct usb_endpoint_descriptor *epd;
 	int pipe;
 
-	epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION);
+	epd = usb_get_epd(i2400mu->usb_iface,
+			  i2400mu->endpoint_cfg.notification);
 	pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 	usb_fill_int_urb(urb, i2400mu->usb_dev, pipe,
 			 i2400m->bm_ack_buf, I2400M_BM_ACK_BUF_SIZE,
@@ -328,8 +351,8 @@ error_dev_gone:
 out:
 	if (do_autopm)
 		usb_autopm_put_interface(i2400mu->usb_iface);
-	d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %zd\n",
-		i2400m, ack, ack_size, result);
+	d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %ld\n",
+		i2400m, ack, ack_size, (long) result);
 	return result;
 
 error_exceeded:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-notif.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-notif.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,7 @@
  *
  * i2400mu_usb_notification_cb()	Called when a URB is ready
  *   i2400mu_notif_grok()
+ *     i2400m_is_boot_barker()
  *     i2400m_dev_reset_handle()
  *     i2400mu_rx_kick()
  */
@@ -87,32 +88,21 @@ int i2400mu_notification_grok(struct i24
 	d_fnstart(4, dev, "(i2400m %p buf %p buf_len %zu)\n",
 		  i2400mu, buf, buf_len);
 	ret = -EIO;
-	if (buf_len < sizeof(i2400m_NBOOT_BARKER))
+	if (buf_len < sizeof(i2400m_ZERO_BARKER))
 		/* Not a bug, just ignore */
 		goto error_bad_size;
-	if (!memcmp(i2400m_NBOOT_BARKER, buf, sizeof(i2400m_NBOOT_BARKER))
-	    || !memcmp(i2400m_SBOOT_BARKER, buf, sizeof(i2400m_SBOOT_BARKER)))
-		ret = i2400m_dev_reset_handle(i2400m);
-	else if (!memcmp(i2400m_ZERO_BARKER, buf, sizeof(i2400m_ZERO_BARKER))) {
+	ret = 0;
+	if (!memcmp(i2400m_ZERO_BARKER, buf, sizeof(i2400m_ZERO_BARKER))) {
 		i2400mu_rx_kick(i2400mu);
-		ret = 0;
-	} else {	/* Unknown or unexpected data in the notif message */
-		char prefix[64];
-		ret = -EIO;
-		dev_err(dev, "HW BUG? Unknown/unexpected data in notification "
-			"message (%zu bytes)\n", buf_len);
-		snprintf(prefix, sizeof(prefix), "%s %s: ",
-			 dev_driver_string(dev), dev_name(dev));
-		if (buf_len > 64) {
-			print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
-				       8, 4, buf, 64, 0);
-			printk(KERN_ERR "%s... (only first 64 bytes "
-			       "dumped)\n", prefix);
-		} else
-			print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
-				       8, 4, buf, buf_len, 0);
+		goto out;
 	}
+	ret = i2400m_is_boot_barker(i2400m, buf, buf_len);
+	if (unlikely(ret >= 0))
+		ret = i2400m_dev_reset_handle(i2400m, "device rebooted");
+	else	/* Unknown or unexpected data in the notif message */
+		i2400m_unknown_barker(i2400m, buf, buf_len);
 error_bad_size:
+out:
 	d_fnend(4, dev, "(i2400m %p buf %p buf_len %zu) = %d\n",
 		i2400mu, buf, buf_len, ret);
 	return ret;
@@ -220,7 +210,8 @@ int i2400mu_notification_setup(struct i2
 		dev_err(dev, "notification: cannot allocate URB\n");
 		goto error_alloc_urb;
 	}
-	epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION);
+	epd = usb_get_epd(i2400mu->usb_iface,
+			  i2400mu->endpoint_cfg.notification);
 	usb_pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 	usb_fill_int_urb(i2400mu->notif_urb, i2400mu->usb_dev, usb_pipe,
 			 buf, I2400MU_MAX_NOTIFICATION_LEN,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-rx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -204,7 +204,7 @@ struct sk_buff *i2400mu_rx(struct i2400m
 		dev_err(dev, "RX: can't get autopm: %d\n", result);
 		do_autopm = 0;
 	}
-	epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_IN);
+	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_in);
 	usb_pipe = usb_rcvbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 retry:
 	rx_size = skb_end_pointer(rx_skb) - rx_skb->data - rx_skb->len;
@@ -214,7 +214,7 @@ retry:
 	}
 	result = usb_bulk_msg(
 		i2400mu->usb_dev, usb_pipe, rx_skb->data + rx_skb->len,
-		rx_size, &read_size, HZ);
+		rx_size, &read_size, 200);
 	usb_mark_last_busy(i2400mu->usb_dev);
 	switch (result) {
 	case 0:
@@ -222,6 +222,26 @@ retry:
 			goto retry;	/* ZLP, just resubmit */
 		skb_put(rx_skb, read_size);
 		break;
+	case -EPIPE:
+		/*
+		 * Stall -- maybe the device is choking with our
+		 * requests. Clear it and give it some time. If they
+		 * happen to often, it might be another symptom, so we
+		 * reset.
+		 *
+		 * No error handling for usb_clear_halt(0; if it
+		 * works, the retry works; if it fails, this switch
+		 * does the error handling for us.
+		 */
+		if (edc_inc(&i2400mu->urb_edc,
+			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+			dev_err(dev, "BM-CMD: too many stalls in "
+				"URB; resetting device\n");
+			goto do_reset;
+		}
+		usb_clear_halt(i2400mu->usb_dev, usb_pipe);
+		msleep(10);	/* give the device some time */
+		goto retry;
 	case -EINVAL:			/* while removing driver */
 	case -ENODEV:			/* dev disconnect ... */
 	case -ENOENT:			/* just ignore it */
@@ -283,6 +303,7 @@ out:
 error_reset:
 	dev_err(dev, "RX: maximum errors in URB exceeded; "
 		"resetting device\n");
+do_reset:
 	usb_queue_reset_device(i2400mu->usb_iface);
 	rx_skb = ERR_PTR(result);
 	goto out;
@@ -316,10 +337,15 @@ int i2400mu_rxd(void *_i2400mu)
 	size_t pending;
 	int rx_size;
 	struct sk_buff *rx_skb;
+	unsigned long flags;
 
 	d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu);
+	spin_lock_irqsave(&i2400m->rx_lock, flags);
+	BUG_ON(i2400mu->rx_kthread != NULL);
+	i2400mu->rx_kthread = current;
+	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 	while (1) {
-		d_printf(2, dev, "TX: waiting for messages\n");
+		d_printf(2, dev, "RX: waiting for messages\n");
 		pending = 0;
 		wait_event_interruptible(
 			i2400mu->rx_wq,
@@ -367,6 +393,9 @@ int i2400mu_rxd(void *_i2400mu)
 	}
 	result = 0;
 out:
+	spin_lock_irqsave(&i2400m->rx_lock, flags);
+	i2400mu->rx_kthread = NULL;
+	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 	d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result);
 	return result;
 
@@ -403,18 +432,33 @@ int i2400mu_rx_setup(struct i2400mu *i24
 	struct i2400m *i2400m = &i2400mu->i2400m;
 	struct device *dev = &i2400mu->usb_iface->dev;
 	struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
+	struct task_struct *kthread;
 
-	i2400mu->rx_kthread = kthread_run(i2400mu_rxd, i2400mu, "%s-rx",
-					  wimax_dev->name);
-	if (IS_ERR(i2400mu->rx_kthread)) {
-		result = PTR_ERR(i2400mu->rx_kthread);
+	kthread = kthread_run(i2400mu_rxd, i2400mu, "%s-rx",
+			      wimax_dev->name);
+	/* the kthread function sets i2400mu->rx_thread */
+	if (IS_ERR(kthread)) {
+		result = PTR_ERR(kthread);
 		dev_err(dev, "RX: cannot start thread: %d\n", result);
 	}
 	return result;
 }
 
+
 void i2400mu_rx_release(struct i2400mu *i2400mu)
 {
-	kthread_stop(i2400mu->rx_kthread);
+	unsigned long flags;
+	struct i2400m *i2400m = &i2400mu->i2400m;
+	struct device *dev = i2400m_dev(i2400m);
+	struct task_struct *kthread;
+
+	spin_lock_irqsave(&i2400m->rx_lock, flags);
+	kthread = i2400mu->rx_kthread;
+	i2400mu->rx_kthread = NULL;
+	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
+	if (kthread)
+		kthread_stop(kthread);
+	else
+		d_printf(1, dev, "RX: kthread had already exited\n");
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-tx.c linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wimax/i2400m/usb-tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wimax/i2400m/usb-tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -101,11 +101,11 @@ int i2400mu_tx(struct i2400mu *i2400mu,
 		dev_err(dev, "TX: can't get autopm: %d\n", result);
 		do_autopm = 0;
 	}
-	epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT);
+	epd = usb_get_epd(i2400mu->usb_iface, i2400mu->endpoint_cfg.bulk_out);
 	usb_pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress);
 retry:
 	result = usb_bulk_msg(i2400mu->usb_dev, usb_pipe,
-			      tx_msg, tx_msg_size, &sent_size, HZ);
+			      tx_msg, tx_msg_size, &sent_size, 200);
 	usb_mark_last_busy(i2400mu->usb_dev);
 	switch (result) {
 	case 0:
@@ -115,6 +115,28 @@ retry:
 			result = -EIO;
 		}
 		break;
+	case -EPIPE:
+		/*
+		 * Stall -- maybe the device is choking with our
+		 * requests. Clear it and give it some time. If they
+		 * happen to often, it might be another symptom, so we
+		 * reset.
+		 *
+		 * No error handling for usb_clear_halt(0; if it
+		 * works, the retry works; if it fails, this switch
+		 * does the error handling for us.
+		 */
+		if (edc_inc(&i2400mu->urb_edc,
+			    10 * EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
+			dev_err(dev, "BM-CMD: too many stalls in "
+				"URB; resetting device\n");
+			usb_queue_reset_device(i2400mu->usb_iface);
+			/* fallthrough */
+		} else {
+			usb_clear_halt(i2400mu->usb_dev, usb_pipe);
+			msleep(10);	/* give the device some time */
+			goto retry;
+		}
 	case -EINVAL:			/* while removing driver */
 	case -ENODEV:			/* dev disconnect ... */
 	case -ENOENT:			/* just ignore it */
@@ -161,9 +183,15 @@ int i2400mu_txd(void *_i2400mu)
 	struct device *dev = &i2400mu->usb_iface->dev;
 	struct i2400m_msg_hdr *tx_msg;
 	size_t tx_msg_size;
+	unsigned long flags;
 
 	d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu);
 
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	BUG_ON(i2400mu->tx_kthread != NULL);
+	i2400mu->tx_kthread = current;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+
 	while (1) {
 		d_printf(2, dev, "TX: waiting for messages\n");
 		tx_msg = NULL;
@@ -183,6 +211,11 @@ int i2400mu_txd(void *_i2400mu)
 		if (result < 0)
 			break;
 	}
+
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	i2400mu->tx_kthread = NULL;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+
 	d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result);
 	return result;
 }
@@ -213,11 +246,13 @@ int i2400mu_tx_setup(struct i2400mu *i24
 	struct i2400m *i2400m = &i2400mu->i2400m;
 	struct device *dev = &i2400mu->usb_iface->dev;
 	struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
+	struct task_struct *kthread;
 
-	i2400mu->tx_kthread = kthread_run(i2400mu_txd, i2400mu, "%s-tx",
-					  wimax_dev->name);
-	if (IS_ERR(i2400mu->tx_kthread)) {
-		result = PTR_ERR(i2400mu->tx_kthread);
+	kthread = kthread_run(i2400mu_txd, i2400mu, "%s-tx",
+			      wimax_dev->name);
+	/* the kthread function sets i2400mu->tx_thread */
+	if (IS_ERR(kthread)) {
+		result = PTR_ERR(kthread);
 		dev_err(dev, "TX: cannot start thread: %d\n", result);
 	}
 	return result;
@@ -225,5 +260,17 @@ int i2400mu_tx_setup(struct i2400mu *i24
 
 void i2400mu_tx_release(struct i2400mu *i2400mu)
 {
-	kthread_stop(i2400mu->tx_kthread);
+	unsigned long flags;
+	struct i2400m *i2400m = &i2400mu->i2400m;
+	struct device *dev = i2400m_dev(i2400m);
+	struct task_struct *kthread;
+
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	kthread = i2400mu->tx_kthread;
+	i2400mu->tx_kthread = NULL;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+	if (kthread)
+		kthread_stop(kthread);
+	else
+		d_printf(1, dev, "TX: kthread had already exited\n");
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/adm8211.c linux-libre-2.6.33-gnu1/drivers/net/wireless/adm8211.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/adm8211.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/adm8211.c	2010-02-24 13:52:17.000000000 -0500
@@ -1538,7 +1538,7 @@ static int adm8211_start(struct ieee8021
 	adm8211_hw_init(dev);
 	adm8211_rf_set_channel(dev, priv->channel);
 
-	retval = request_irq(priv->pdev->irq, &adm8211_interrupt,
+	retval = request_irq(priv->pdev->irq, adm8211_interrupt,
 			     IRQF_SHARED, "adm8211", dev);
 	if (retval) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/airo.c linux-libre-2.6.33-gnu1/drivers/net/wireless/airo.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/airo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/airo.c	2010-02-24 13:52:17.000000000 -0500
@@ -4806,7 +4806,7 @@ static int airo_config_commit(struct net
 
 static inline int sniffing_mode(struct airo_info *ai)
 {
-	return le16_to_cpu(ai->config.rmode & RXMODE_MASK) >=
+	return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
 		le16_to_cpu(RXMODE_RFMON);
 }
 
@@ -5659,7 +5659,8 @@ static int airo_pci_suspend(struct pci_d
 
 	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
 	pci_save_state(pdev);
-	return pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
 }
 
 static int airo_pci_resume(struct pci_dev *pdev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/airo_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/airo_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/airo_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/airo_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,21 +43,6 @@
 
 #include "airo.h"
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -145,11 +130,10 @@ static int airo_probe(struct pcmcia_devi
 {
 	local_info_t *local;
 
-	DEBUG(0, "airo_attach()\n");
+	dev_dbg(&p_dev->dev, "airo_attach()\n");
 
 	/* Interrupt setup */
 	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	p_dev->irq.Handler = NULL;
 
 	/*
@@ -184,7 +168,7 @@ static int airo_probe(struct pcmcia_devi
 
 static void airo_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "airo_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "airo_detach\n");
 
 	airo_release(link);
 
@@ -204,9 +188,6 @@ static void airo_detach(struct pcmcia_de
 
   ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int airo_cs_config_check(struct pcmcia_device *p_dev,
 				cistpl_cftable_entry_t *cfg,
 				cistpl_cftable_entry_t *dflt,
@@ -275,11 +256,11 @@ static int airo_cs_config_check(struct p
 		req->Base = mem->win[0].host_addr;
 		req->Size = mem->win[0].len;
 		req->AccessSpeed = 0;
-		if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+		if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
 			return -ENODEV;
 		map.Page = 0;
 		map.CardOffset = mem->win[0].card_addr;
-		if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+		if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
 			return -ENODEV;
 	}
 	/* If we got this far, we're cool! */
@@ -291,11 +272,11 @@ static int airo_config(struct pcmcia_dev
 {
 	local_info_t *dev;
 	win_req_t *req;
-	int last_fn, last_ret;
+	int ret;
 
 	dev = link->priv;
 
-	DEBUG(0, "airo_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "airo_config\n");
 
 	req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
 	if (!req)
@@ -315,8 +296,8 @@ static int airo_config(struct pcmcia_dev
 	 * and most client drivers will only use the CIS to fill in
 	 * implementation-defined details.
 	 */
-	last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
-	if (last_ret)
+	ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+	if (ret)
 		goto failed;
 
 	/*
@@ -324,21 +305,25 @@ static int airo_config(struct pcmcia_dev
 	  handler to the interrupt, unless the 'Handler' member of the
 	  irq structure is initialized.
 	*/
-	if (link->conf.Attributes & CONF_ENABLE_IRQ)
-		CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		ret = pcmcia_request_irq(link, &link->irq);
+		if (ret)
+			goto failed;
+	}
 
 	/*
 	  This actually configures the PCMCIA socket -- setting up
 	  the I/O windows and the interrupt mapping, and putting the
 	  card and host interface into "Memory and IO" mode.
 	*/
-	CS_CHECK(RequestConfiguration,
-		 pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 	((local_info_t *)link->priv)->eth_dev =
 		init_airo_card(link->irq.AssignedIRQ,
-			       link->io.BasePort1, 1, &handle_to_dev(link));
+			       link->io.BasePort1, 1, &link->dev);
 	if (!((local_info_t *)link->priv)->eth_dev)
-		goto cs_failed;
+		goto failed;
 
 	/*
 	  At this point, the dev_node_t structure(s) need to be
@@ -368,8 +353,6 @@ static int airo_config(struct pcmcia_dev
 	kfree(req);
 	return 0;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
  failed:
 	airo_release(link);
 	kfree(req);
@@ -386,7 +369,7 @@ static int airo_config(struct pcmcia_dev
 
 static void airo_release(struct pcmcia_device *link)
 {
-	DEBUG(0, "airo_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "airo_release\n");
 	pcmcia_disable_device(link);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan.h linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,539 +0,0 @@
-/*
- *  Copyright (C) 1997 Cullen Jennings
- *  Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500	
- *  GNU General Public License applies
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/if_ether.h>	/* For the statistics structure. */
-#include <linux/if_arp.h>	/* For ARPHRD_ETHER */
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-
-//#define ARLAN_DEBUGGING 1
-
-#define ARLAN_PROC_INTERFACE
-#define MAX_ARLANS 4 /* not more than 4 ! */
-#define ARLAN_PROC_SHM_DUMP /* shows all card registers, makes driver way larger */
-
-#define ARLAN_MAX_MULTICAST_ADDRS 16
-#define ARLAN_RCV_CLEAN 	0
-#define ARLAN_RCV_PROMISC 1
-#define ARLAN_RCV_CONTROL 2
-
-#ifdef CONFIG_PROC_FS
-extern int init_arlan_proc(void);
-extern void cleanup_arlan_proc(void);
-#else
-#define init_arlan_proc()	({ 0; })
-#define cleanup_arlan_proc()	do { } while (0)
-#endif
-
-extern struct net_device *arlan_device[MAX_ARLANS];
-extern int	arlan_debug;
-extern int	arlan_entry_debug;
-extern int	arlan_exit_debug;
-extern int	testMemory;
-extern int     arlan_command(struct net_device * dev, int command);
- 
-#define SIDUNKNOWN -1
-#define radioNodeIdUNKNOWN -1
-#define irqUNKNOWN 0
-#define debugUNKNOWN 0
-#define testMemoryUNKNOWN 1
-#define spreadingCodeUNKNOWN 0
-#define channelNumberUNKNOWN 0
-#define channelSetUNKNOWN 0
-#define systemIdUNKNOWN -1
-#define registrationModeUNKNOWN -1
-
-
-#define IFDEBUG( L ) if ( (L) & arlan_debug ) 
-#define ARLAN_FAKE_HDR_LEN 12 
-
-#ifdef ARLAN_DEBUGGING
-	#define DEBUG 1
-	#define ARLAN_ENTRY_EXIT_DEBUGGING 1
-	#define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b)
-#else
-	#define ARLAN_DEBUG(a,b) 
-#endif
-
-#define ARLAN_SHMEM_SIZE	0x2000
-
-struct arlan_shmem
-{
-      /* Header Signature */ 
-      volatile	char textRegion[48];
-      volatile	u_char resetFlag;
-      volatile	u_char  diagnosticInfo;
-      volatile	u_short diagnosticOffset;
-      volatile	u_char _1[12];
-      volatile	u_char lanCardNodeId[6];
-      volatile	u_char broadcastAddress[6];
-      volatile	u_char hardwareType;
-      volatile	u_char majorHardwareVersion;
-      volatile	u_char minorHardwareVersion;
-      volatile	u_char radioModule;// shows EEPROM, can be overridden at 0x111
-      volatile	u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A
-      volatile	u_char _2[47];
-      
-      /* Control/Status Block - 0x0080 */
-      volatile	u_char interruptInProgress; /* not used by lancpu */
-      volatile	u_char cntrlRegImage; /* not used by lancpu */
-      volatile	u_char _3[13];
-      volatile	u_char dumpByte;
-      volatile	u_char commandByte; /* non-zero = active */
-      volatile	u_char commandParameter[15];
-
-      /* Receive Status - 0x00a0 */
-      volatile	u_char rxStatus; /* 1- data, 2-control, 0xff - registr change */
-      volatile	u_char rxFrmType;
-      volatile	u_short rxOffset;
-      volatile	u_short rxLength;
-      volatile	u_char rxSrc[6];
-      volatile	u_char rxBroadcastFlag;
-      volatile	u_char rxQuality;
-      volatile	u_char scrambled;
-      volatile	u_char _4[1];
-      
-      /* Transmit Status - 0x00b0 */
-      volatile	u_char txStatus;
-      volatile	u_char txAckQuality;
-      volatile	u_char numRetries;
-      volatile	u_char _5[14];
-      volatile	u_char registeredRouter[6];
-      volatile	u_char backboneRouter[6];
-      volatile	u_char registrationStatus;
-      volatile	u_char configuredStatusFlag;
-      volatile	u_char _6[1];
-      volatile	u_char ultimateDestAddress[6];
-      volatile	u_char immedDestAddress[6];
-      volatile	u_char immedSrcAddress[6];
-      volatile	u_short rxSequenceNumber;
-      volatile	u_char assignedLocaltalkAddress;
-      volatile	u_char _7[27];
-
-      /* System Parameter Block */
-
-      /* - Driver Parameters (Novell Specific) */
-
-      volatile	u_short txTimeout;
-      volatile	u_short transportTime;
-      volatile	u_char _8[4];
-
-      /* - Configuration Parameters */
-      volatile	u_char irqLevel;
-      volatile	u_char spreadingCode;
-      volatile	u_char channelSet;
-      volatile	u_char channelNumber;
-      volatile	u_short radioNodeId;
-      volatile	u_char _9[2];
-      volatile	u_char scramblingDisable;
-      volatile	u_char radioType;
-      volatile	u_short routerId;
-      volatile	u_char _10[9];
-      volatile	u_char txAttenuation;
-      volatile	u_char systemId[4]; 
-      volatile	u_short globalChecksum;
-      volatile	u_char _11[4];
-      volatile	u_short maxDatagramSize;
-      volatile	u_short maxFrameSize;
-      volatile	u_char maxRetries;
-      volatile	u_char receiveMode;
-      volatile	u_char priority;
-      volatile	u_char rootOrRepeater;
-      volatile	u_char specifiedRouter[6];
-      volatile	u_short fastPollPeriod;
-      volatile	u_char pollDecay;
-      volatile	u_char fastPollDelay[2];
-      volatile	u_char arlThreshold;
-      volatile	u_char arlDecay;
-      volatile	u_char _12[1];
-      volatile	u_short specRouterTimeout;
-      volatile	u_char _13[5];
-
-      /* Scrambled Area */
-      volatile	u_char SID[4];
-      volatile	u_char encryptionKey[12];
-      volatile	u_char _14[2];
-      volatile	u_char waitTime[2];
-      volatile	u_char lParameter[2];
-      volatile	u_char _15[3];
-      volatile	u_short headerSize;
-      volatile	u_short sectionChecksum;
-
-      volatile	u_char registrationMode;
-      volatile	u_char registrationFill;
-      volatile	u_short pollPeriod;
-      volatile	u_short refreshPeriod;
-      volatile	u_char name[16];
-      volatile	u_char NID[6];
-      volatile	u_char localTalkAddress;
-      volatile	u_char codeFormat;
-      volatile	u_char numChannels;
-      volatile	u_char channel1;
-      volatile	u_char channel2;
-      volatile	u_char channel3;
-      volatile	u_char channel4;
-      volatile	u_char SSCode[59];
-
-      volatile	u_char _16[0xC0];
-      volatile	u_short auxCmd;
-      volatile	u_char  dumpPtr[4];
-      volatile	u_char dumpVal;
-      volatile	u_char _17[0x6A];
-      volatile	u_char wireTest;
-      volatile	u_char _18[14];
-
-      /* Statistics Block - 0x0300 */
-      volatile	u_char hostcpuLock;
-      volatile	u_char lancpuLock;
-      volatile	u_char resetTime[18];
-      
-      volatile	u_char numDatagramsTransmitted[4];
-      volatile	u_char numReTransmissions[4];
-      volatile	u_char numFramesDiscarded[4];
-      volatile	u_char numDatagramsReceived[4];
-      volatile	u_char numDuplicateReceivedFrames[4];
-      volatile	u_char numDatagramsDiscarded[4];
-      
-      volatile	u_short maxNumReTransmitDatagram;
-      volatile	u_short maxNumReTransmitFrames;
-      volatile	u_short maxNumConsecutiveDuplicateFrames;
-      /* misaligned here so we have to go to characters */
-     
-      volatile	u_char numBytesTransmitted[4];
-      volatile	u_char numBytesReceived[4];
-      volatile	u_char numCRCErrors[4];
-      volatile	u_char numLengthErrors[4];
-      volatile	u_char numAbortErrors[4];
-      volatile	u_char numTXUnderruns[4];
-      volatile	u_char numRXOverruns[4];
-      volatile	u_char numHoldOffs[4];
-      volatile	u_char numFramesTransmitted[4];
-      volatile	u_char numFramesReceived[4];
-      volatile	u_char numReceiveFramesLost[4];
-      volatile	u_char numRXBufferOverflows[4];
-      volatile	u_char numFramesDiscardedAddrMismatch[4];
-      volatile	u_char numFramesDiscardedSIDMismatch[4];
-      volatile	u_char numPollsTransmistted[4];
-      volatile	u_char numPollAcknowledges[4];
-      volatile	u_char numStatusTimeouts[4];
-      volatile	u_char numNACKReceived[4];
-
-      volatile	u_char _19[0x86];
-
-      volatile	u_char txBuffer[0x800];
-      volatile	u_char rxBuffer[0x800];
-
-      volatile	u_char _20[0x800];
-      volatile	u_char _21[0x3fb];
-      volatile	u_char configStatus;
-      volatile	u_char _22;
-      volatile	u_char progIOCtrl;
-      volatile	u_char shareMBase;
-      volatile	u_char controlRegister;
-};
-
-struct arlan_conf_stru {
-      int spreadingCode;
-      int channelSet;
-      int channelNumber;
-      int scramblingDisable;
-      int txAttenuation;
-      int systemId; 
-      int maxDatagramSize;
-      int maxFrameSize;
-      int maxRetries;
-      int receiveMode;
-      int priority;
-      int rootOrRepeater;
-      int SID;
-      int radioNodeId;
-      int registrationMode;
-      int registrationFill;
-      int localTalkAddress;
-      int codeFormat;
-      int numChannels;
-      int channel1;
-      int channel2;
-      int channel3;
-      int channel4;
-      int txClear;
-      int txRetries;
-      int txRouting;
-      int txScrambled;
-      int rxParameter;
-      int txTimeoutMs;
-      int txAckTimeoutMs;
-      int waitCardTimeout;
-      int	waitTime;
-      int	lParameter;
-      int	_15;
-      int	headerSize;
-      int retries;
-      int tx_delay_ms;
-      int waitReTransmitPacketMaxSize;
-      int ReTransmitPacketMaxSize;
-      int fastReTransCount;
-      int driverRetransmissions;
-      int registrationInterrupts;
-      int hardwareType;
-      int radioType;
-      int writeRadioType;
-      int writeEEPROM;
-      char siteName[17];
-      int measure_rate;
-      int in_speed;
-      int out_speed;
-      int in_speed10;
-      int out_speed10;
-      int in_speed_max;
-      int out_speed_max;
-      int pre_Command_Wait;
-      int rx_tweak1;
-      int rx_tweak2;
-      int tx_queue_len;
-};
-
-extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
-
-struct TxParam
-{
-      volatile	short 		offset;
-      volatile 	short 		length;
-      volatile	u_char 		dest[6];
-      volatile	unsigned	char clear;
-      volatile	unsigned	char retries;
-      volatile	unsigned	char routing;
-      volatile	unsigned	char scrambled;
-};
-
-#define TX_RING_SIZE 2
-/* Information that need to be kept for each board. */
-struct arlan_private {
-      struct arlan_shmem __iomem * card;
-      struct arlan_shmem * conf;
-
-      struct arlan_conf_stru * Conf;	     
-      int	bad;
-      int 	reset;
-      unsigned long lastReset;
-      struct timer_list timer;
-      struct timer_list tx_delay_timer;
-      struct timer_list tx_retry_timer;
-      struct timer_list rx_check_timer;
-
-      int registrationLostCount;
-      int reRegisterExp;
-      int irq_test_done;
-
-      struct TxParam txRing[TX_RING_SIZE];
-      char reTransmitBuff[0x800];
-      int txLast;
-      unsigned ReTransmitRequested;
-      unsigned long tx_done_delayed;
-      unsigned long registrationLastSeen;
-
-      unsigned long	tx_last_sent;
-      unsigned long	tx_last_cleared;
-      unsigned long	retransmissions;
-      unsigned long 	interrupt_ack_requested;
-      spinlock_t	lock;
-      unsigned long	waiting_command_mask;
-      unsigned long 	card_polling_interval;
-      unsigned long 	last_command_buff_free_time;
-
-      int 		under_reset;
-      int 		under_config;
-      int 		rx_command_given;
-      int	 	tx_command_given;
-      unsigned  long	interrupt_processing_active;
-      unsigned long	last_rx_int_ack_time;
-      unsigned long	in_bytes;
-      unsigned long 	out_bytes;
-      unsigned long	in_time;
-      unsigned long	out_time;
-      unsigned long	in_time10;
-      unsigned long	out_time10;
-      unsigned long	in_bytes10;
-      unsigned long 	out_bytes10;
-      int	init_etherdev_alloc;
-};
-
-
-
-#define ARLAN_CLEAR		0x00
-#define ARLAN_RESET 		0x01
-#define ARLAN_CHANNEL_ATTENTION 0x02
-#define ARLAN_INTERRUPT_ENABLE 	0x04
-#define ARLAN_CLEAR_INTERRUPT 	0x08
-#define ARLAN_POWER 		0x40
-#define ARLAN_ACCESS		0x80
-
-#define ARLAN_COM_CONF                0x01
-#define ARLAN_COM_RX_ENABLE           0x03
-#define ARLAN_COM_RX_ABORT            0x04
-#define ARLAN_COM_TX_ENABLE           0x05
-#define ARLAN_COM_TX_ABORT            0x06
-#define ARLAN_COM_NOP		      0x07
-#define ARLAN_COM_STANDBY             0x08
-#define ARLAN_COM_ACTIVATE            0x09
-#define ARLAN_COM_GOTO_SLOW_POLL      0x0a
-#define ARLAN_COM_INT                 0x80
-
-
-#define TXLAST(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[((struct arlan_private *)netdev_priv(dev))->txLast])
-#define TXHEAD(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[0])
-#define TXTAIL(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[1])
-
-#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
-#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
- 
-#define READSHM(to,from,atype) {\
-	atype tmp;\
-	memcpy_fromio(&(tmp),&(from),sizeof(atype));\
-	to = tmp;\
-	}
-
-#define READSHMEM(from,atype)\
-	atype from; \
-	READSHM(from, arlan->from, atype);
-
-#define WRITESHM(to,from,atype) \
-	{ atype tmpSHM = from;\
-	memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
-	}
-
-#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
-	{	atype tmpSHM; \
-		memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
-		IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
-	}
-
-#define WRITESHMB(to, val) \
-	writeb(val,&(to))
-#define READSHMB(to) \
-	readb(&(to))
-#define WRITESHMS(to, val) \
-	writew(val,&(to))
-#define READSHMS(to) \
-	readw(&(to))
-#define WRITESHMI(to, val) \
-	writel(val,&(to))
-#define READSHMI(to) \
-	readl(&(to))
-
-
-
-
-
-#define registrationBad(dev)\
-   ( (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode)    > 0) && \
-     (   READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)    )
-
-
-#define readControlRegister(dev)\
- 	READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
-
-#define writeControlRegister(dev, v){\
-   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage	,((v) &0xF) );\
-   WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister	,(v) 	);}
-
-
-#define arlan_interrupt_lancpu(dev) {\
-   int cr;   \
-   \
-   cr = readControlRegister(dev);\
-   if (cr & ARLAN_CHANNEL_ATTENTION){ \
-      writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
-   }else  \
-      writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
-}
-
-#define clearChannelAttention(dev){ \
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
-#define setHardwareReset(dev) {\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
-#define clearHardwareReset(dev) {\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
-#define setInterruptEnable(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE)  ;}
-#define clearInterruptEnable(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE)  ;}
-#define setClearInterrupt(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT)   ;}
-#define clearClearInterrupt(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
-#define setPowerOff(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define setPowerOn(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER));   }
-#define arlan_lock_card_access(dev){\
-   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define arlan_unlock_card_access(dev){\
-   writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }  
-
-
-
-
-#define ARLAN_COMMAND_RX		0x000001
-#define ARLAN_COMMAND_NOOP		0x000002
-#define ARLAN_COMMAND_NOOPINT		0x000004
-#define ARLAN_COMMAND_TX		0x000008
-#define ARLAN_COMMAND_CONF		0x000010
-#define ARLAN_COMMAND_RESET		0x000020
-#define ARLAN_COMMAND_TX_ABORT		0x000040
-#define ARLAN_COMMAND_RX_ABORT		0x000080
-#define ARLAN_COMMAND_POWERDOWN		0x000100
-#define ARLAN_COMMAND_POWERUP		0x000200
-#define ARLAN_COMMAND_SLOW_POLL 	0x000400
-#define ARLAN_COMMAND_ACTIVATE 		0x000800
-#define ARLAN_COMMAND_INT_ACK		0x001000
-#define ARLAN_COMMAND_INT_ENABLE	0x002000
-#define ARLAN_COMMAND_WAIT_NOW		0x004000
-#define ARLAN_COMMAND_LONG_WAIT_NOW	0x008000
-#define ARLAN_COMMAND_STANDBY		0x010000
-#define ARLAN_COMMAND_INT_RACK		0x020000
-#define ARLAN_COMMAND_INT_RENABLE	0x040000
-#define ARLAN_COMMAND_CONF_WAIT		0x080000
-#define ARLAN_COMMAND_TBUSY_CLEAR	0x100000
-#define ARLAN_COMMAND_CLEAN_AND_CONF	(ARLAN_COMMAND_TX_ABORT\
-					| ARLAN_COMMAND_RX_ABORT\
-					| ARLAN_COMMAND_CONF)
-#define ARLAN_COMMAND_CLEAN_AND_RESET   (ARLAN_COMMAND_TX_ABORT\
-					| ARLAN_COMMAND_RX_ABORT\
-					| ARLAN_COMMAND_RESET)
-
-
- 
-#define ARLAN_DEBUG_CHAIN_LOCKS		0x00001
-#define ARLAN_DEBUG_RESET		0x00002
-#define ARLAN_DEBUG_TIMING		0x00004
-#define ARLAN_DEBUG_CARD_STATE		0x00008
-#define ARLAN_DEBUG_TX_CHAIN		0x00010
-#define ARLAN_DEBUG_MULTICAST		0x00020
-#define ARLAN_DEBUG_HEADER_DUMP		0x00040
-#define ARLAN_DEBUG_INTERRUPT		0x00080
-#define ARLAN_DEBUG_STARTUP		0x00100
-#define ARLAN_DEBUG_SHUTDOWN		0x00200
- 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan-main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan-main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan-main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan-main.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1887 +0,0 @@
-/*
- *  Copyright (C) 1997 Cullen Jennings
- *  Copyright (C) 1998 Elmer Joandiu, elmer@ylenurme.ee
- *  GNU General Public License applies
- * This module provides support for the Arlan 655 card made by Aironet
- */
-
-#include "arlan.h"
-
-#if BITS_PER_LONG != 32
-#  error FIXME: this driver requires a 32-bit platform
-#endif
-
-static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee  Oct'98, http://www.ylenurme.ee/~elmer/655/";
-
-struct net_device *arlan_device[MAX_ARLANS];
-
-static int SID = SIDUNKNOWN;
-static int radioNodeId = radioNodeIdUNKNOWN;
-static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
-int arlan_debug = debugUNKNOWN;
-static int spreadingCode = spreadingCodeUNKNOWN;
-static int channelNumber = channelNumberUNKNOWN;
-static int channelSet = channelSetUNKNOWN;
-static int systemId = systemIdUNKNOWN;
-static int registrationMode = registrationModeUNKNOWN;
-static int keyStart;
-static int tx_delay_ms;
-static int retries = 5;
-static int tx_queue_len = 1;
-static int arlan_EEPROM_bad;
-
-#ifdef ARLAN_DEBUGGING
-
-static int testMemory = testMemoryUNKNOWN;
-static int irq = irqUNKNOWN;
-static int txScrambled = 1;
-static int mdebug;
-
-module_param(irq, int, 0);
-module_param(mdebug, int, 0);
-module_param(testMemory, int, 0);
-module_param(txScrambled, int, 0);
-MODULE_PARM_DESC(irq, "(unused)");
-MODULE_PARM_DESC(testMemory, "(unused)");
-MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
-#endif
-
-module_param_named(debug, arlan_debug, int, 0);
-module_param(spreadingCode, int, 0);
-module_param(channelNumber, int, 0);
-module_param(channelSet, int, 0);
-module_param(systemId, int, 0);
-module_param(registrationMode, int, 0);
-module_param(radioNodeId, int, 0);
-module_param(SID, int, 0);
-module_param(keyStart, int, 0);
-module_param(tx_delay_ms, int, 0);
-module_param(retries, int, 0);
-module_param(tx_queue_len, int, 0);
-module_param_named(EEPROM_bad, arlan_EEPROM_bad, int, 0);
-MODULE_PARM_DESC(debug, "Arlan debug enable (0-1)");
-MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
-#ifdef ARLAN_ENTRY_EXIT_DEBUGGING
-static int arlan_entry_debug;
-static int arlan_exit_debug;
-static int arlan_entry_and_exit_debug;
-module_param_named(entry_debug, arlan_entry_debug, int, 0);
-module_param_named(exit_debug, arlan_exit_debug, int, 0);
-module_param_named(entry_and_exit_debug, arlan_entry_and_exit_debug, int, 0);
-MODULE_PARM_DESC(entry_debug, "Arlan driver function entry debugging");
-MODULE_PARM_DESC(exit_debug, "Arlan driver function exit debugging");
-MODULE_PARM_DESC(entry_and_exit_debug, "Arlan driver function entry and exit debugging");
-#endif
-
-struct arlan_conf_stru arlan_conf[MAX_ARLANS];
-static int arlans_found;
-
-static  int 	arlan_open(struct net_device *dev);
-static  netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev);
-static  irqreturn_t arlan_interrupt(int irq, void *dev_id);
-static  int 	arlan_close(struct net_device *dev);
-static  struct net_device_stats *
-		arlan_statistics		(struct net_device *dev);
-static  void 	arlan_set_multicast		(struct net_device *dev);
-static  int 	arlan_hw_tx			(struct net_device* dev, char *buf, int length );
-static  int	arlan_hw_config			(struct net_device * dev);
-static  void 	arlan_tx_done_interrupt		(struct net_device * dev, int status);
-static  void	arlan_rx_interrupt		(struct net_device * dev, u_char rxStatus, u_short, u_short);
-static  void	arlan_process_interrupt		(struct net_device * dev);
-static	void	arlan_tx_timeout		(struct net_device *dev);
-
-static inline long us2ticks(int us)
-{
-	return us * (1000000 / HZ);
-}
-
-
-#ifdef ARLAN_ENTRY_EXIT_DEBUGGING
-#define ARLAN_DEBUG_ENTRY(name) \
-	{\
-	struct timeval timev;\
-	do_gettimeofday(&timev);\
-		if (arlan_entry_debug || arlan_entry_and_exit_debug)\
-			printk("--->>>" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec));\
-	}
-#define ARLAN_DEBUG_EXIT(name) \
-	{\
-	struct timeval timev;\
-	do_gettimeofday(&timev);\
-		if (arlan_exit_debug || arlan_entry_and_exit_debug)\
-			printk("<<<---" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec) );\
-	}
-#else
-#define ARLAN_DEBUG_ENTRY(name)
-#define ARLAN_DEBUG_EXIT(name)
-#endif
-
-
-#define arlan_interrupt_ack(dev)\
-        clearClearInterrupt(dev);\
-        setClearInterrupt(dev);
-
-static inline int arlan_drop_tx(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	dev->stats.tx_errors++;
-	if (priv->Conf->tx_delay_ms)
-	{
-		priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1;
-	}
-	else
-	{
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_TX;
-		TXHEAD(dev).offset = 0;
-		TXTAIL(dev).offset = 0;
-		priv->txLast = 0;
-		priv->bad = 0;
-		if (!priv->under_reset && !priv->under_config)
-			netif_wake_queue (dev);
-	}
-	return 1;
-}
-
-
-int arlan_command(struct net_device *dev, int command_p)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-	int udelayed = 0;
-	int i = 0;
-	unsigned long flags;
-
-	ARLAN_DEBUG_ENTRY("arlan_command");
-
-	if (priv->card_polling_interval)
-		priv->card_polling_interval = 1;
-
-	if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
-		printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %lx incoming %x \n",
-		jiffies, READSHMB(arlan->commandByte),
-		       priv->waiting_command_mask, command_p);
-
-	priv->waiting_command_mask |= command_p;
-
-	if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
-		if (time_after(jiffies, priv->lastReset + 5 * HZ))
-			priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
-
-	if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK)
-	{
-		arlan_interrupt_ack(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ACK;
-	}
-	if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE)
-	{
-		setInterruptEnable(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ENABLE;
-	}
-
-	/* Card access serializing lock */
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* Check cards status and waiting */
-
-	if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
-	{
-		while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
-		{
-			if (READSHMB(arlan->resetFlag) ||
-				READSHMB(arlan->commandByte))	/* || 
-								   (readControlRegister(dev) & ARLAN_ACCESS))
-								 */
-				udelay(40);
-			else
-				priv->waiting_command_mask &= ~(ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW);
-
-			udelayed++;
-
-			if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW)
-			{
-				if (udelayed * 40 > 1000000)
-				{
-					printk(KERN_ERR "%s long wait too long \n", dev->name);
-					priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
-					break;
-				}
-			}
-			else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW)
-			{
-				if (udelayed * 40 > 1000)
-				{
-					printk(KERN_ERR "%s short wait too long \n", dev->name);
-					goto bad_end;
-				}
-			}
-		}
-	}
-	else
-	{
-		i = 0;
-		while ((READSHMB(arlan->resetFlag) ||
-			READSHMB(arlan->commandByte)) &&
-			conf->pre_Command_Wait > (i++) * 10)
-			udelay(10);
-
-
-		if ((READSHMB(arlan->resetFlag) ||
-			READSHMB(arlan->commandByte)) &&
-			!(priv->waiting_command_mask & ARLAN_COMMAND_RESET))
-		{
-			goto card_busy_end;
-		}
-	}
-	if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
-		priv->under_reset = 1;
-	if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
-		priv->under_config = 1;
-
-	/* Issuing command */
-	arlan_lock_card_access(dev);
-	if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP)
-	{
-	//     if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER))
-		setPowerOn(dev);
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERUP;
-		priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
-		priv->card_polling_interval = HZ / 10;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE)
-	{
-		WRITESHMB(arlan->commandByte, ARLAN_COM_ACTIVATE);
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_ACTIVATE;
-		priv->card_polling_interval = HZ / 10;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT)
-	{
-		if (priv->rx_command_given)
-		{
-			WRITESHMB(arlan->commandByte, ARLAN_COM_RX_ABORT);
-			arlan_interrupt_lancpu(dev);
-			priv->rx_command_given = 0;
-		}
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_RX_ABORT;
-		priv->card_polling_interval = 1;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT)
-	{
-		if (priv->tx_command_given)
-		{
-			WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ABORT);
-			arlan_interrupt_lancpu(dev);
-			priv->tx_command_given = 0;
-		}
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_TX_ABORT;
-		priv->card_polling_interval = 1;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
-	{
-		priv->under_reset=1;
-		netif_stop_queue (dev);
-
-		arlan_drop_tx(dev);
-		if (priv->tx_command_given || priv->rx_command_given)
-		{
-			printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
-		}
-		netif_stop_queue (dev);
-		if (arlan_debug & ARLAN_DEBUG_RESET)
-			printk(KERN_ERR "%s: Doing chip reset\n", dev->name);
-		priv->lastReset = jiffies;
-		WRITESHM(arlan->commandByte, 0, u_char);
-		/* hold card in reset state */
-		setHardwareReset(dev);
-		/* set reset flag and then release reset */
-		WRITESHM(arlan->resetFlag, 0xff, u_char);
-		clearChannelAttention(dev);
-		clearHardwareReset(dev);
-		priv->card_polling_interval = HZ / 4;
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
-		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;
-//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE; 
-//		priv->waiting_command_mask |= ARLAN_COMMAND_RX;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK)
-	{
-		clearHardwareReset(dev);
-		clearClearInterrupt(dev);
-		setClearInterrupt(dev);
-		setInterruptEnable(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RACK;
-		priv->waiting_command_mask |= ARLAN_COMMAND_CONF;
-		priv->under_config = 1;
-		priv->under_reset = 0;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE)
-	{
-		setInterruptEnable(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
-	{
-		if (priv->tx_command_given || priv->rx_command_given)
-		{
-			printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
-		}
-		arlan_drop_tx(dev);
-		setInterruptEnable(dev);
-		arlan_hw_config(dev);
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF;
-		priv->card_polling_interval = HZ / 10;
-//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;   
-//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE; 
-		priv->waiting_command_mask |= ARLAN_COMMAND_CONF_WAIT;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT)
-	{
-		if (READSHMB(arlan->configuredStatusFlag) != 0 &&
-			READSHMB(arlan->diagnosticInfo) == 0xff)
-		{
-			priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT;
-			priv->waiting_command_mask |= ARLAN_COMMAND_RX;
-			priv->waiting_command_mask |= ARLAN_COMMAND_TBUSY_CLEAR;
-			priv->card_polling_interval = HZ / 10;
-			priv->tx_command_given = 0;
-			priv->under_config = 0;
-		}
-		else
-		{
-			priv->card_polling_interval = 1;
-			if (arlan_debug & ARLAN_DEBUG_TIMING)
-				printk(KERN_ERR "configure delayed \n");
-		}
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_RX)
-	{
-		if (!registrationBad(dev))
-		{
-			setInterruptEnable(dev);
-			memset_io(arlan->commandParameter, 0, 0xf);
-			WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE);
-			WRITESHMB(arlan->commandParameter[0], conf->rxParameter);
-			arlan_interrupt_lancpu(dev);
-			priv->rx_command_given = 0; // mnjah, bad
-			priv->waiting_command_mask &= ~ARLAN_COMMAND_RX;
-			priv->card_polling_interval = 1;
-		}
-		else
-			priv->card_polling_interval = 2;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR)
-	{
-		if ( !registrationBad(dev) &&
-		     (netif_queue_stopped(dev) || !netif_running(dev)) )
-			{
-				priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR;
-				netif_wake_queue (dev);
-			}
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_TX)
-	{
-		if (!test_and_set_bit(0, (void *) &priv->tx_command_given))
-		{
-			if (time_after(jiffies, 
-				       priv->tx_last_sent + us2ticks(conf->rx_tweak1))
-			    || time_before(jiffies,
-					   priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2)))
-			{
-				setInterruptEnable(dev);
-				memset_io(arlan->commandParameter, 0, 0xf);
-				WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ENABLE | ARLAN_COM_INT);
-				memcpy_toio(arlan->commandParameter, &TXLAST(dev), 14);
-//				for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i]));
-				priv->tx_last_sent = jiffies;
-				arlan_interrupt_lancpu(dev);
-				priv->tx_command_given = 1;
-				priv->waiting_command_mask &= ~ARLAN_COMMAND_TX;
-				priv->card_polling_interval = 1;
-			}
-			else
-			{
-				priv->tx_command_given = 0;
-				priv->card_polling_interval = 1;
-			}
-		} 
-		else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
-			printk(KERN_ERR "tx command when tx chain locked \n");
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT)
-	{
-		{
-			WRITESHMB(arlan->commandByte, ARLAN_COM_NOP | ARLAN_COM_INT);
-		}
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOPINT;
-		priv->card_polling_interval = HZ / 3;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOP)
-	{
-		WRITESHMB(arlan->commandByte, ARLAN_COM_NOP);
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOP;
-		priv->card_polling_interval = HZ / 3;
-	}
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_SLOW_POLL)
-	{
-		WRITESHMB(arlan->commandByte, ARLAN_COM_GOTO_SLOW_POLL);
-		arlan_interrupt_lancpu(dev);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_SLOW_POLL;
-		priv->card_polling_interval = HZ / 3;
-	} 
-	else if (priv->waiting_command_mask & ARLAN_COMMAND_POWERDOWN)
-	{
-		setPowerOff(dev);
-		if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
-			printk(KERN_WARNING "%s: Arlan Going Standby\n", dev->name);
-		priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERDOWN;
-		priv->card_polling_interval = 3 * HZ;
-	}
-	arlan_unlock_card_access(dev);
-	for (i = 0; READSHMB(arlan->commandByte) && i < 20; i++)
-		udelay(10);
-	if (READSHMB(arlan->commandByte))
-		if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
-			printk(KERN_ERR "card busy leaving command %lx\n", priv->waiting_command_mask);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-	ARLAN_DEBUG_EXIT("arlan_command");
-	priv->last_command_buff_free_time = jiffies;
-	return 0;
-
-card_busy_end:
-	if (time_after(jiffies, priv->last_command_buff_free_time + HZ))
-		priv->waiting_command_mask |= ARLAN_COMMAND_CLEAN_AND_RESET;
-
-	if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
-		printk(KERN_ERR "%s arlan_command card busy end \n", dev->name);
-	spin_unlock_irqrestore(&priv->lock, flags);
-	ARLAN_DEBUG_EXIT("arlan_command");
-	return 1;
-
-bad_end:
-	printk(KERN_ERR "%s arlan_command bad end \n", dev->name);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-	ARLAN_DEBUG_EXIT("arlan_command");
-
-	return -1;
-}
-
-static inline void arlan_command_process(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	int times = 0;
-	while (priv->waiting_command_mask && times < 8)
-	{
-		if (priv->waiting_command_mask)
-		{
-			if (arlan_command(dev, 0))
-				break;
-			times++;
-		}
-		/* if long command, we won't repeat trying */ ;
-		if (priv->card_polling_interval > 1)
-			break;
-		times++;
-	}
-}
-
-
-static inline void arlan_retransmit_now(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-
-	ARLAN_DEBUG_ENTRY("arlan_retransmit_now");
-	if (TXLAST(dev).offset == 0)
-	{
-		if (TXHEAD(dev).offset)
-		{
-			priv->txLast = 0;
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head \n");
-
-		}
-		else if (TXTAIL(dev).offset)
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail \n");
-			priv->txLast = 1;
-		}
-		else
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty");
-		netif_wake_queue (dev);
-		return;
-
-	}
-	arlan_command(dev, ARLAN_COMMAND_TX);
-
-	priv->Conf->driverRetransmissions++;
-	priv->retransmissions++;
-
-	IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("Retransmit %d bytes \n", TXLAST(dev).length);
-
-	ARLAN_DEBUG_EXIT("arlan_retransmit_now");
-}
-
-
-
-static void arlan_registration_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *) data;
-	struct arlan_private *priv = netdev_priv(dev);
-	int bh_mark_needed = 0;
-	int next_tick = 1;
-	long lostTime = ((long)jiffies - (long)priv->registrationLastSeen)
-			* (1000/HZ);
-
-	if (registrationBad(dev))
-	{
-		priv->registrationLostCount++;
-		if (lostTime > 7000 && lostTime < 7200)
-		{
-			printk(KERN_NOTICE "%s registration Lost \n", dev->name);
-		}
-		if (lostTime / priv->reRegisterExp > 2000)
-			arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF);
-		if (lostTime / (priv->reRegisterExp) > 3500)
-			arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
-		if (priv->reRegisterExp < 400)
-			priv->reRegisterExp += 2;
-		if (lostTime > 7200)
-		{
-			next_tick = HZ;
-			arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
-		}
-	}
-	else
-	{
-		if (priv->Conf->registrationMode && lostTime > 10000 &&
-			priv->registrationLostCount)
-		{
-			printk(KERN_NOTICE "%s registration is back after %ld milliseconds\n",
-			       dev->name, lostTime);
-		}
-		priv->registrationLastSeen = jiffies;
-		priv->registrationLostCount = 0;
-		priv->reRegisterExp = 1;
-		if (!netif_running(dev) )
-			netif_wake_queue(dev);
-		if (time_after(priv->tx_last_sent,priv->tx_last_cleared) &&
-		    time_after(jiffies, priv->tx_last_sent * 5*HZ) ){
-			arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);		
-			priv->tx_last_cleared = jiffies;
-		}
-	}
-
-
-	if (!registrationBad(dev) && priv->ReTransmitRequested)
-	{
-		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-			printk(KERN_ERR "Retransmit from timer \n");
-		priv->ReTransmitRequested = 0;
-		arlan_retransmit_now(dev);
-	}
-	if (!registrationBad(dev) &&
-		time_after(jiffies, priv->tx_done_delayed) &&
-		priv->tx_done_delayed != 0)
-	{
-		TXLAST(dev).offset = 0;
-		if (priv->txLast)
-			priv->txLast = 0;
-		else if (TXTAIL(dev).offset)
-			priv->txLast = 1;
-		if (TXLAST(dev).offset)
-		{
-			arlan_retransmit_now(dev);
-			dev->trans_start = jiffies;
-		}
-		if (!(TXHEAD(dev).offset && TXTAIL(dev).offset))
-		{
-			netif_wake_queue (dev);
-		}
-		priv->tx_done_delayed = 0;
-		bh_mark_needed = 1;
-	}
-	if (bh_mark_needed)
-	{
-		netif_wake_queue (dev);
-	}
-	arlan_process_interrupt(dev);
-
-	if (next_tick < priv->card_polling_interval)
-		next_tick = priv->card_polling_interval;
-
-	priv->timer.expires = jiffies + next_tick;
-
-	add_timer(&priv->timer);
-}
-
-
-#ifdef ARLAN_DEBUGGING
-
-static void arlan_print_registers(struct net_device *dev, int line)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem *arlan = priv->card;
-
-	u_char hostcpuLock, lancpuLock, controlRegister, cntrlRegImage,
-		txStatus, rxStatus, interruptInProgress, commandByte;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_print_registers");
-	READSHM(interruptInProgress, arlan->interruptInProgress, u_char);
-	READSHM(hostcpuLock, arlan->hostcpuLock, u_char);
-	READSHM(lancpuLock, arlan->lancpuLock, u_char);
-	READSHM(controlRegister, arlan->controlRegister, u_char);
-	READSHM(cntrlRegImage, arlan->cntrlRegImage, u_char);
-	READSHM(txStatus, arlan->txStatus, u_char);
-	READSHM(rxStatus, arlan->rxStatus, u_char);
-	READSHM(commandByte, arlan->commandByte, u_char);
-
-	printk(KERN_WARNING "line %04d IP %02x HL %02x LL %02x CB %02x CR %02x CRI %02x TX %02x RX %02x\n",
-		line, interruptInProgress, hostcpuLock, lancpuLock, commandByte,
-		controlRegister, cntrlRegImage, txStatus, rxStatus);
-
-	ARLAN_DEBUG_EXIT("arlan_print_registers");
-}
-#endif
-
-
-static int arlan_hw_tx(struct net_device *dev, char *buf, int length)
-{
-	int i;
-
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-
-	int tailStarts = 0x800;
-	int headEnds = 0x0;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_hw_tx");
-	if (TXHEAD(dev).offset)
-		headEnds = (((TXHEAD(dev).offset + TXHEAD(dev).length - offsetof(struct arlan_shmem, txBuffer)) / 64) + 1) * 64;
-	if (TXTAIL(dev).offset)
-		tailStarts = 0x800 - (((TXTAIL(dev).offset - offsetof(struct arlan_shmem, txBuffer)) / 64) + 2) * 64;
-
-
-	if (!TXHEAD(dev).offset && length < tailStarts)
-	{
-		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-			printk(KERN_ERR "TXHEAD insert, tailStart %d\n", tailStarts);
-
-		TXHEAD(dev).offset =
-			offsetof(struct arlan_shmem, txBuffer);
-		TXHEAD(dev).length = length - ARLAN_FAKE_HDR_LEN;
-		for (i = 0; i < 6; i++)
-			TXHEAD(dev).dest[i] = buf[i];
-		TXHEAD(dev).clear = conf->txClear;
-		TXHEAD(dev).retries = conf->txRetries;	/* 0 is use default */
-		TXHEAD(dev).routing = conf->txRouting;
-		TXHEAD(dev).scrambled = conf->txScrambled;
-		memcpy_toio((char __iomem *)arlan + TXHEAD(dev).offset, buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length);
-	}
-	else if (!TXTAIL(dev).offset && length < (0x800 - headEnds))
-	{
-		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-			printk(KERN_ERR "TXTAIL insert, headEnd %d\n", headEnds);
-
-		TXTAIL(dev).offset =
-			offsetof(struct arlan_shmem, txBuffer) + 0x800 - (length / 64 + 2) * 64;
-		TXTAIL(dev).length = length - ARLAN_FAKE_HDR_LEN;
-		for (i = 0; i < 6; i++)
-			TXTAIL(dev).dest[i] = buf[i];
-		TXTAIL(dev).clear = conf->txClear;
-		TXTAIL(dev).retries = conf->txRetries;
-		TXTAIL(dev).routing = conf->txRouting;
-		TXTAIL(dev).scrambled = conf->txScrambled;
-		memcpy_toio(((char __iomem *)arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length);
-	}
-	else
-	{
-		netif_stop_queue (dev);
-		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-			printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds);
-		return -1;
-	}
-	priv->out_bytes += length;
-	priv->out_bytes10 += length;
-	if (conf->measure_rate < 1)
-		conf->measure_rate = 1;
-	if (time_after(jiffies, priv->out_time + conf->measure_rate * HZ))
-	{
-		conf->out_speed = priv->out_bytes / conf->measure_rate;
-		priv->out_bytes = 0;
-		priv->out_time = jiffies;
-	}
-	if (time_after(jiffies, priv->out_time10 + conf->measure_rate * 10*HZ))
-	{
-		conf->out_speed10 = priv->out_bytes10 / (10 * conf->measure_rate);
-		priv->out_bytes10 = 0;
-		priv->out_time10 = jiffies;
-	}
-	if (TXHEAD(dev).offset && TXTAIL(dev).offset)
-	{
-		netif_stop_queue (dev);
-		return 0;
-	}
-	else
-		netif_start_queue (dev);
-
-
-	IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
-		printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name,
-		   (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2], (unsigned char) buf[3],
-		   (unsigned char) buf[4], (unsigned char) buf[5], (unsigned char) buf[6], (unsigned char) buf[7],
-		   (unsigned char) buf[8], (unsigned char) buf[9], (unsigned char) buf[10], (unsigned char) buf[11]);
-
-	IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX command prepare for buffer %d\n", priv->txLast);
-
-	arlan_command(dev, ARLAN_COMMAND_TX);
-
-	priv->tx_last_sent = jiffies;
-
-	IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("%s TX Qued %d bytes \n", dev->name, length);
-
-	ARLAN_DEBUG_EXIT("arlan_hw_tx");
-
-	return 0;
-}
-
-
-static int arlan_hw_config(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-
-	ARLAN_DEBUG_ENTRY("arlan_hw_config");
-
-	printk(KERN_NOTICE "%s arlan configure called \n", dev->name);
-	if (arlan_EEPROM_bad)
-		printk(KERN_NOTICE "arlan configure with eeprom bad option \n");
-
-
-	WRITESHM(arlan->spreadingCode, conf->spreadingCode, u_char);
-	WRITESHM(arlan->channelSet, conf->channelSet, u_char);
-
-	if (arlan_EEPROM_bad)
-		WRITESHM(arlan->defaultChannelSet, conf->channelSet, u_char);
-
-	WRITESHM(arlan->channelNumber, conf->channelNumber, u_char);
-
-	WRITESHM(arlan->scramblingDisable, conf->scramblingDisable, u_char);
-	WRITESHM(arlan->txAttenuation, conf->txAttenuation, u_char);
-
-	WRITESHM(arlan->systemId, conf->systemId, u_int);
-
-	WRITESHM(arlan->maxRetries, conf->maxRetries, u_char);
-	WRITESHM(arlan->receiveMode, conf->receiveMode, u_char);
-	WRITESHM(arlan->priority, conf->priority, u_char);
-	WRITESHM(arlan->rootOrRepeater, conf->rootOrRepeater, u_char);
-	WRITESHM(arlan->SID, conf->SID, u_int);
-
-	WRITESHM(arlan->registrationMode, conf->registrationMode, u_char);
-
-	WRITESHM(arlan->registrationFill, conf->registrationFill, u_char);
-	WRITESHM(arlan->localTalkAddress, conf->localTalkAddress, u_char);
-	WRITESHM(arlan->codeFormat, conf->codeFormat, u_char);
-	WRITESHM(arlan->numChannels, conf->numChannels, u_char);
-	WRITESHM(arlan->channel1, conf->channel1, u_char);
-	WRITESHM(arlan->channel2, conf->channel2, u_char);
-	WRITESHM(arlan->channel3, conf->channel3, u_char);
-	WRITESHM(arlan->channel4, conf->channel4, u_char);
-	WRITESHM(arlan->radioNodeId, conf->radioNodeId, u_short);
-	WRITESHM(arlan->SID, conf->SID, u_int);
-	WRITESHM(arlan->waitTime, conf->waitTime, u_short);
-	WRITESHM(arlan->lParameter, conf->lParameter, u_short);
-	memcpy_toio(&(arlan->_15), &(conf->_15), 3);
-	WRITESHM(arlan->_15, conf->_15, u_short);
-	WRITESHM(arlan->headerSize, conf->headerSize, u_short);
-	if (arlan_EEPROM_bad)
-		WRITESHM(arlan->hardwareType, conf->hardwareType, u_char);
-	WRITESHM(arlan->radioType, conf->radioType, u_char);
-	if (arlan_EEPROM_bad)
-		WRITESHM(arlan->radioModule, conf->radioType, u_char);
-
-	memcpy_toio(arlan->encryptionKey + keyStart, encryptionKey, 8);
-	memcpy_toio(arlan->name, conf->siteName, 16);
-
-	WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_CONF);	/* do configure */
-	memset_io(arlan->commandParameter, 0, 0xf);	/* 0xf */
-	memset_io(arlan->commandParameter + 1, 0, 2);
-	if (conf->writeEEPROM)
-	{
-		  memset_io(arlan->commandParameter, conf->writeEEPROM, 1);
-//		conf->writeEEPROM=0;
-	}
-	if (conf->registrationMode && conf->registrationInterrupts)
-		memset_io(arlan->commandParameter + 3, 1, 1);
-	else
-		memset_io(arlan->commandParameter + 3, 0, 1);
-
-	priv->irq_test_done = 0;
-
-	if (conf->tx_queue_len)
-		dev->tx_queue_len = conf->tx_queue_len;
-	udelay(100);
-
-	ARLAN_DEBUG_EXIT("arlan_hw_config");
-	return 0;
-}
-
-
-static int arlan_read_card_configuration(struct net_device *dev)
-{
-	u_char tlx415;
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-
-	ARLAN_DEBUG_ENTRY("arlan_read_card_configuration");
-
-	if (radioNodeId == radioNodeIdUNKNOWN)
-	{
-		READSHM(conf->radioNodeId, arlan->radioNodeId, u_short);
-	}
-	else
-		conf->radioNodeId = radioNodeId;
-		
-	if (SID == SIDUNKNOWN)
-	{
-		READSHM(conf->SID, arlan->SID, u_int);
-	}
-	else conf->SID = SID;
-		
-	if (spreadingCode == spreadingCodeUNKNOWN)
-	{
-		  READSHM(conf->spreadingCode, arlan->spreadingCode, u_char);
-	}
-	else
-		conf->spreadingCode = spreadingCode;
-		
-	if (channelSet == channelSetUNKNOWN)
-	{
-		READSHM(conf->channelSet, arlan->channelSet, u_char);
-	}
-	else conf->channelSet = channelSet;
-
-	if (channelNumber == channelNumberUNKNOWN)
-	{
-		READSHM(conf->channelNumber, arlan->channelNumber, u_char);
-	}
-	else conf->channelNumber = channelNumber;
-	
-	READSHM(conf->scramblingDisable, arlan->scramblingDisable, u_char);
-	READSHM(conf->txAttenuation, arlan->txAttenuation, u_char);
-	
-	if (systemId == systemIdUNKNOWN)
-	{
-		READSHM(conf->systemId, arlan->systemId, u_int);
-	} 
-	else conf->systemId = systemId;
-	
-	READSHM(conf->maxDatagramSize, arlan->maxDatagramSize, u_short);
-	READSHM(conf->maxFrameSize, arlan->maxFrameSize, u_short);
-	READSHM(conf->maxRetries, arlan->maxRetries, u_char);
-	READSHM(conf->receiveMode, arlan->receiveMode, u_char);
-	READSHM(conf->priority, arlan->priority, u_char);
-	READSHM(conf->rootOrRepeater, arlan->rootOrRepeater, u_char);
-
-	if (SID == SIDUNKNOWN)
-	{
-		  READSHM(conf->SID, arlan->SID, u_int);
-	}
-	else conf->SID = SID;
-	
-	if (registrationMode == registrationModeUNKNOWN)
-	{
-		  READSHM(conf->registrationMode, arlan->registrationMode, u_char);
-	}
-	else conf->registrationMode = registrationMode;
-	
-	READSHM(conf->registrationFill, arlan->registrationFill, u_char);
-	READSHM(conf->localTalkAddress, arlan->localTalkAddress, u_char);
-	READSHM(conf->codeFormat, arlan->codeFormat, u_char);
-	READSHM(conf->numChannels, arlan->numChannels, u_char);
-	READSHM(conf->channel1, arlan->channel1, u_char);
-	READSHM(conf->channel2, arlan->channel2, u_char);
-	READSHM(conf->channel3, arlan->channel3, u_char);
-	READSHM(conf->channel4, arlan->channel4, u_char);
-	READSHM(conf->waitTime, arlan->waitTime, u_short);
-	READSHM(conf->lParameter, arlan->lParameter, u_short);
-	READSHM(conf->_15, arlan->_15, u_short);
-	READSHM(conf->headerSize, arlan->headerSize, u_short);
-	READSHM(conf->hardwareType, arlan->hardwareType, u_char);
-	READSHM(conf->radioType, arlan->radioModule, u_char);
-	
-	if (conf->radioType == 0)
-		conf->radioType = 0xc;
-
-	WRITESHM(arlan->configStatus, 0xA5, u_char);
-	READSHM(tlx415, arlan->configStatus, u_char);
-	
-	if (tlx415 != 0xA5)
-		printk(KERN_INFO "%s tlx415 chip \n", dev->name);
-	
-	conf->txClear = 0;
-	conf->txRetries = 1;
-	conf->txRouting = 1;
-	conf->txScrambled = 0;
-	conf->rxParameter = 1;
-	conf->txTimeoutMs = 4000;
-	conf->waitCardTimeout = 100000;
-	conf->receiveMode = ARLAN_RCV_CLEAN;
-	memcpy_fromio(conf->siteName, arlan->name, 16);
-	conf->siteName[16] = '\0';
-	conf->retries = retries;
-	conf->tx_delay_ms = tx_delay_ms;
-	conf->ReTransmitPacketMaxSize = 200;
-	conf->waitReTransmitPacketMaxSize = 200;
-	conf->txAckTimeoutMs = 900;
-	conf->fastReTransCount = 3;
-
-	ARLAN_DEBUG_EXIT("arlan_read_card_configuration");
-
-	return 0;
-}
-
-
-static int lastFoundAt = 0xbe000;
-
-
-/*
- * This is the real probe routine. Linux has a history of friendly device
- * probes on the ISA bus. A good device probes avoids doing writes, and
- * verifies that the correct device exists and functions.
- */
-#define ARLAN_SHMEM_SIZE	0x2000
-static int __init arlan_check_fingerprint(unsigned long memaddr)
-{
-	static const char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
-	volatile struct arlan_shmem __iomem *arlan = (struct arlan_shmem *) memaddr;
-	unsigned long paddr = virt_to_phys((void *) memaddr);
-	char tempBuf[49];
-
-	ARLAN_DEBUG_ENTRY("arlan_check_fingerprint");
-
-	if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) {
-		// printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr);
-		return -ENODEV;
-	}
-
-	memcpy_fromio(tempBuf, arlan->textRegion, 29);
-	tempBuf[30] = 0;
-
-	/* check for card at this address */
-	if (0 != strncmp(tempBuf, probeText, 29)){
- 		release_mem_region(paddr, ARLAN_SHMEM_SIZE);
-		return -ENODEV;
-	}
-
-//   printk(KERN_INFO "arlan found at 0x%x \n",memaddr);
-	ARLAN_DEBUG_EXIT("arlan_check_fingerprint");
-
-	return 0;
-}
-
-static int arlan_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	struct arlan_conf_stru *conf = priv->Conf;
-
-	ARLAN_DEBUG_ENTRY("arlan_change_mtu");
-	if (new_mtu > 2032)
-		return -EINVAL;
-	dev->mtu = new_mtu;
-	if (new_mtu < 256)
-		new_mtu = 256;	/* cards book suggests 1600 */
-	conf->maxDatagramSize = new_mtu;
-	conf->maxFrameSize = new_mtu + 48;
-
-	arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF);
-	printk(KERN_NOTICE "%s mtu changed to %d \n", dev->name, new_mtu);
-
-	ARLAN_DEBUG_EXIT("arlan_change_mtu");
-
-	return 0;
-}
-
-static int arlan_mac_addr(struct net_device *dev, void *p)
-{
-	struct sockaddr *addr = p;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_mac_addr");
-	return -EINVAL;
-
-	if (netif_running(dev))
-		return -EBUSY;
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-	ARLAN_DEBUG_EXIT("arlan_mac_addr");
-	return 0;
-}
-
-static const struct net_device_ops arlan_netdev_ops = {
-	.ndo_open		= arlan_open,
-	.ndo_stop		= arlan_close,
-	.ndo_start_xmit		= arlan_tx,
-	.ndo_get_stats		= arlan_statistics,
-	.ndo_set_multicast_list = arlan_set_multicast,
-	.ndo_change_mtu		= arlan_change_mtu,
-	.ndo_set_mac_address	= arlan_mac_addr,
-	.ndo_tx_timeout		= arlan_tx_timeout,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-static int __init arlan_setup_device(struct net_device *dev, int num)
-{
-	struct arlan_private *ap = netdev_priv(dev);
-	int err;
-
-	ARLAN_DEBUG_ENTRY("arlan_setup_device");
-
-	ap->conf = (struct arlan_shmem *)(ap+1);
-
-	dev->tx_queue_len = tx_queue_len;
-	dev->netdev_ops = &arlan_netdev_ops;
-	dev->watchdog_timeo = 3*HZ;
-	
-	ap->irq_test_done = 0;
-	ap->Conf = &arlan_conf[num];
-
-	ap->Conf->pre_Command_Wait = 40;
-	ap->Conf->rx_tweak1 = 30;
-	ap->Conf->rx_tweak2 = 0;
-
-
-	err = register_netdev(dev);
-	if (err) {
-		release_mem_region(virt_to_phys((void *) dev->mem_start), 
-			   ARLAN_SHMEM_SIZE);
-		free_netdev(dev);
-		return err;
-	}
-	arlan_device[num] = dev;
-	ARLAN_DEBUG_EXIT("arlan_setup_device");
-	return 0;
-}
-
-static int __init arlan_probe_here(struct net_device *dev, 
-				   unsigned long memaddr)
-{
-	struct arlan_private *ap = netdev_priv(dev);
-
-	ARLAN_DEBUG_ENTRY("arlan_probe_here");
-
-	if (arlan_check_fingerprint(memaddr))
-		return -ENODEV;
-
-	printk(KERN_NOTICE "%s: Arlan found at %llx, \n ", dev->name, 
-	       (u64) virt_to_phys((void*)memaddr));
-
-	ap->card = (void *) memaddr;
-	dev->mem_start = memaddr;
-	dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1;
-
-	if (dev->irq < 2)
-	{
-		READSHM(dev->irq, ap->card->irqLevel, u_char);
-	} else if (dev->irq == 2)
-		dev->irq = 9;
-
-	arlan_read_card_configuration(dev);
-
-	ARLAN_DEBUG_EXIT("arlan_probe_here");
-	return 0;
-}
-
-
-static int arlan_open(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	int ret = 0;
-
-	ARLAN_DEBUG_ENTRY("arlan_open");
-
-	ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev);
-	if (ret)
-	{
-		printk(KERN_ERR "%s: unable to get IRQ %d .\n",
-			dev->name, dev->irq);
-		return ret;
-	}
-
-
-	priv->bad = 0;
-	priv->lastReset = 0;
-	priv->reset = 0;
-	memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6);
-	memset(dev->broadcast, 0xff, 6);
-	dev->tx_queue_len = tx_queue_len;
-	priv->interrupt_processing_active = 0;
-	spin_lock_init(&priv->lock);
-
-	netif_start_queue (dev);
-
-	priv->registrationLostCount = 0;
-	priv->registrationLastSeen = jiffies;
-	priv->txLast = 0;
-	priv->tx_command_given = 0;
-	priv->rx_command_given = 0;
-	
-	priv->reRegisterExp = 1;
-	priv->tx_last_sent = jiffies - 1;
-	priv->tx_last_cleared = jiffies;
-	priv->Conf->writeEEPROM = 0;
-	priv->Conf->registrationInterrupts = 1;
-
-	init_timer(&priv->timer);
-	priv->timer.expires = jiffies + HZ / 10;
-	priv->timer.data = (unsigned long) dev;
-	priv->timer.function = &arlan_registration_timer;	/* timer handler */
-
-	arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW);
-	mdelay(200);
-	add_timer(&priv->timer);
-
-	ARLAN_DEBUG_EXIT("arlan_open");
-	return 0;
-}
-
-
-static void arlan_tx_timeout (struct net_device *dev)
-{
-	printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name);
-	/* Try to restart the adaptor. */
-	arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
-	// dev->trans_start = jiffies;
-	// netif_start_queue (dev);
-}
-
-
-static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev)
-{
-	short length;
-	unsigned char *buf;
-
-	ARLAN_DEBUG_ENTRY("arlan_tx");
-	
-	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-	buf = skb->data;
-
-	if (length + 0x12 > 0x800) {
-		printk(KERN_ERR "TX RING overflow \n");
-		netif_stop_queue (dev);
-	}
-
-	if (arlan_hw_tx(dev, buf, length) == -1)
-		goto bad_end;
-
-	dev->trans_start = jiffies;
-
-	dev_kfree_skb(skb);
-
-	arlan_process_interrupt(dev);
-	ARLAN_DEBUG_EXIT("arlan_tx");
-	return NETDEV_TX_OK;
-
-bad_end:
-	arlan_process_interrupt(dev);
-	netif_stop_queue (dev);
-	ARLAN_DEBUG_EXIT("arlan_tx");
-	return NETDEV_TX_BUSY;
-}
-
-
-static inline int DoNotReTransmitCrap(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	if (TXLAST(dev).length < priv->Conf->ReTransmitPacketMaxSize)
-		return 1;
-	return 0;
-
-}
-
-static inline int DoNotWaitReTransmitCrap(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	if (TXLAST(dev).length < priv->Conf->waitReTransmitPacketMaxSize)
-		return 1;
-	return 0;
-}
-
-static inline void arlan_queue_retransmit(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	ARLAN_DEBUG_ENTRY("arlan_queue_retransmit");
-
-	if (DoNotWaitReTransmitCrap(dev))
-	{
-		  arlan_drop_tx(dev);
-	} else
-		priv->ReTransmitRequested++;
-
-	ARLAN_DEBUG_EXIT("arlan_queue_retransmit");
-}
-
-static inline void RetryOrFail(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	ARLAN_DEBUG_ENTRY("RetryOrFail");
-
-	if (priv->retransmissions > priv->Conf->retries ||
-	    DoNotReTransmitCrap(dev))
-	{
-		arlan_drop_tx(dev);
-	}
-	else if (priv->bad <= priv->Conf->fastReTransCount)
-	{
-		arlan_retransmit_now(dev);
-	}
-	else arlan_queue_retransmit(dev);
-
-	ARLAN_DEBUG_EXIT("RetryOrFail");
-}
-
-
-static void arlan_tx_done_interrupt(struct net_device *dev, int status)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	ARLAN_DEBUG_ENTRY("arlan_tx_done_interrupt");
-
-	priv->tx_last_cleared = jiffies;
-	priv->tx_command_given = 0;
-	switch (status)
-	{
-		case 1:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit OK\n");
-			dev->stats.tx_packets++;
-			priv->bad = 0;
-			priv->reset = 0;
-			priv->retransmissions = 0;
-			if (priv->Conf->tx_delay_ms)
-			{
-				priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1;
-			}
-			else
-			{
-				TXLAST(dev).offset = 0;
-				if (priv->txLast)
-					priv->txLast = 0;
-				else if (TXTAIL(dev).offset)
-					priv->txLast = 1;
-				if (TXLAST(dev).offset)
-				{
-					arlan_retransmit_now(dev);
-					dev->trans_start = jiffies;
-				}
-				if (!TXHEAD(dev).offset || !TXTAIL(dev).offset)
-				{
-					netif_wake_queue (dev);
-				}
-			}
-		}
-		break;
-		
-		case 2:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit timed out\n");
-			priv->bad += 1;
-			//arlan_queue_retransmit(dev);
-			RetryOrFail(dev);
-		}
-		break;
-
-		case 3:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit max retries\n");
-			priv->bad += 1;
-			priv->reset = 0;
-			//arlan_queue_retransmit(dev);
-			RetryOrFail(dev);
-		}
-		break;
-		
-		case 4:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit aborted\n");
-			priv->bad += 1;
-			arlan_queue_retransmit(dev);
-			//RetryOrFail(dev);
-		}
-		break;
-
-		case 5:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit not registered\n");
-			priv->bad += 1;
-			//debug=101;
-			arlan_queue_retransmit(dev);
-		}
-		break;
-
-		case 6:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN) 
-				printk("arlan intr: transmit destination full\n");
-			priv->bad += 1;
-			priv->reset = 0;
-			//arlan_drop_tx(dev);
-			arlan_queue_retransmit(dev);
-		}
-		break;
-
-		case 7:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit unknown ack\n");
-			priv->bad += 1;
-			priv->reset = 0;
-			arlan_queue_retransmit(dev);
-		}
-		break;
-		
-		case 8:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit dest mail box full\n");
-			priv->bad += 1;
-			priv->reset = 0;
-			//arlan_drop_tx(dev);
-			arlan_queue_retransmit(dev);
-		}
-		break;
-
-		case 9:
-		{
-			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
-				printk("arlan intr: transmit root dest not reg.\n");
-			priv->bad += 1;
-			priv->reset = 1;
-			//arlan_drop_tx(dev);
-			arlan_queue_retransmit(dev);
-		}
-		break;
-
-		default:
-		{
-			printk(KERN_ERR "arlan intr: transmit status unknown\n");
-			priv->bad += 1;
-			priv->reset = 1;
-			arlan_drop_tx(dev);
-		}
-	}
-
-	ARLAN_DEBUG_EXIT("arlan_tx_done_interrupt");
-}
-
-
-static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len)
-{
-	char *skbtmp;
-	int i = 0;
-
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_rx_interrupt");
-	// by spec,   not                WRITESHMB(arlan->rxStatus,0x00);
-	// prohibited here              arlan_command(dev, ARLAN_COMMAND_RX);
-
-	if (pkt_len < 10 || pkt_len > 2048)
-	{
-		printk(KERN_WARNING "%s: got too short or long packet, len %d \n", dev->name, pkt_len);
-		return;
-	}
-	if (rxOffset + pkt_len > 0x2000)
-	{
-		printk("%s: got too long packet, len %d offset %x\n", dev->name, pkt_len, rxOffset);
-		return;
-	}
-	priv->in_bytes += pkt_len;
-	priv->in_bytes10 += pkt_len;
-	if (conf->measure_rate < 1)
-		conf->measure_rate = 1;
-	if (time_after(jiffies, priv->in_time + conf->measure_rate * HZ))
-	{
-		conf->in_speed = priv->in_bytes / conf->measure_rate;
-		priv->in_bytes = 0;
-		priv->in_time = jiffies;
-	}
-	if (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ))
-	{
-		conf->in_speed10 = priv->in_bytes10 / (10 * conf->measure_rate);
-		priv->in_bytes10 = 0;
-		priv->in_time10 = jiffies;
-	}
-	DEBUGSHM(1, "arlan rcv pkt rxStatus= %d ", arlan->rxStatus, u_char);
-	switch (rxStatus)
-	{
-		case 1:
-		case 2:
-		case 3:
-		{
-			/* Malloc up new buffer. */
-			struct sk_buff *skb;
-
-			DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short);
-			DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char);
-			DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char);
-
-			/* here we do multicast filtering to avoid slow 8-bit memcopy */
-#ifdef ARLAN_MULTICAST
-			if (!(dev->flags & IFF_ALLMULTI) &&
-				!(dev->flags & IFF_PROMISC) &&
-				dev->mc_list)
-			{
-				char hw_dst_addr[6];
-				struct dev_mc_list *dmi = dev->mc_list;
-				int i;
-
-				memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6);
-				if (hw_dst_addr[0] == 0x01)
-				{
-					if (mdebug)
-						if (hw_dst_addr[1] == 0x00)
-							printk(KERN_ERR "%s mcast 0x0100 \n", dev->name);
-						else if (hw_dst_addr[1] == 0x40)
-							printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name);
-					while (dmi)
-					{
-						if (dmi->dmi_addrlen == 6) {
-							if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)
-								printk(KERN_ERR "%s mcl %pM\n",
-								       dev->name, dmi->dmi_addr);
-							for (i = 0; i < 6; i++)
-								if (dmi->dmi_addr[i] != hw_dst_addr[i])
-									break;
-							if (i == 6)
-								break;
-						} else
-							printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name);
-						dmi = dmi->next;
-					}
-					/* we reach here if multicast filtering is on and packet 
-					 * is multicast and not for receive */
-					goto end_of_interrupt;
-				}
-			}
-#endif				// ARLAN_MULTICAST
-			/* multicast filtering ends here */
-			pkt_len += ARLAN_FAKE_HDR_LEN;
-
-			skb = dev_alloc_skb(pkt_len + 4);
-			if (skb == NULL)
-			{
-				printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
-				dev->stats.rx_dropped++;
-				break;
-			}
-			skb_reserve(skb, 2);
-			skbtmp = skb_put(skb, pkt_len);
-
-			memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN);
-			memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6);
-			memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6);
-			WRITESHMB(arlan->rxStatus, 0x00);
-			arlan_command(dev, ARLAN_COMMAND_RX);
-
-			IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
-			{
-				char immedDestAddress[6];
-				char immedSrcAddress[6];
-				memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6);
-				memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6);
-
-				printk(KERN_WARNING "%s t %pM f %pM imd %pM ims %pM\n",
-				       dev->name, skbtmp,
-				       &skbtmp[6],
-				       immedDestAddress,
-				       immedSrcAddress);
-			}
-			skb->protocol = eth_type_trans(skb, dev);
-			IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
-				if (skb->protocol != 0x608 && skb->protocol != 0x8)
-				{
-					for (i = 0; i <= 22; i++)
-						printk("%02x:", (u_char) skbtmp[i + 12]);
-					printk(KERN_ERR "\n");
-					printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol);
-				}
-			netif_rx(skb);
-			dev->stats.rx_packets++;
-			dev->stats.rx_bytes += pkt_len;
-		}
-		break;
-		
-		default:
-			printk(KERN_ERR "arlan intr: received unknown status\n");
-			dev->stats.rx_crc_errors++;
-			break;
-	}
-	ARLAN_DEBUG_EXIT("arlan_rx_interrupt");
-}
-
-static void arlan_process_interrupt(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	u_char rxStatus = READSHMB(arlan->rxStatus);
-	u_char txStatus = READSHMB(arlan->txStatus);
-	u_short rxOffset = READSHMS(arlan->rxOffset);
-	u_short pkt_len = READSHMS(arlan->rxLength);
-	int interrupt_count = 0;
-
-	ARLAN_DEBUG_ENTRY("arlan_process_interrupt");
-
-	if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active))
-	{
-		if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
-			printk(KERN_ERR "interrupt chain reentering \n");
-		goto end_int_process;
-	}
-	while ((rxStatus || txStatus || priv->interrupt_ack_requested)
-			&& (interrupt_count < 5))
-	{
-		if (rxStatus)
-			priv->last_rx_int_ack_time = jiffies;
-
-		arlan_command(dev, ARLAN_COMMAND_INT_ACK);
-		arlan_command(dev, ARLAN_COMMAND_INT_ENABLE);
-		
-		IFDEBUG(ARLAN_DEBUG_INTERRUPT)
-			printk(KERN_ERR "%s:  got IRQ rx %x tx %x comm %x rxOff %x rxLen %x \n",
-					dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte),
-					rxOffset, pkt_len);
-
-		if (rxStatus == 0 && txStatus == 0)
-		{
-			if (priv->irq_test_done)
-			{
-				if (!registrationBad(dev))
-					IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s unknown interrupt(nop? regLost ?) reason tx %d rx %d ",
-										    dev->name, txStatus, rxStatus);
-			} else {
-				IFDEBUG(ARLAN_DEBUG_INTERRUPT)
-					printk(KERN_INFO "%s irq $%d test OK \n", dev->name, dev->irq);
-
-			}
-			priv->interrupt_ack_requested = 0;
-			goto ends;
-		}
-		if (txStatus != 0)
-		{
-			WRITESHMB(arlan->txStatus, 0x00);
-			arlan_tx_done_interrupt(dev, txStatus);
-			goto ends;
-		}
-		if (rxStatus == 1 || rxStatus == 2)
-		{		/* a packet waiting */
-			arlan_rx_interrupt(dev, rxStatus, rxOffset, pkt_len);
-			goto ends;
-		}
-		if (rxStatus > 2 && rxStatus < 0xff)
-		{
-			WRITESHMB(arlan->rxStatus, 0x00);
-			printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ",
-				dev->name, txStatus, rxStatus);
-			goto ends;
-		}
-		if (rxStatus == 0xff)
-		{
-			WRITESHMB(arlan->rxStatus, 0x00);
-			arlan_command(dev, ARLAN_COMMAND_RX);
-			if (registrationBad(dev))
-				netif_device_detach(dev);
-			if (!registrationBad(dev))
-			{
-				priv->registrationLastSeen = jiffies;
-				if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config)
-					netif_wake_queue (dev);
-			}
-			goto ends;
-		}
-ends:
-
-		arlan_command_process(dev);
-
-		rxStatus = READSHMB(arlan->rxStatus);
-		txStatus = READSHMB(arlan->txStatus);
-		rxOffset = READSHMS(arlan->rxOffset);
-		pkt_len = READSHMS(arlan->rxLength);
-
-
-		priv->irq_test_done = 1;
-
-		interrupt_count++;
-	}
-	priv->interrupt_processing_active = 0;
-
-end_int_process:
-	arlan_command_process(dev);
-
-	ARLAN_DEBUG_EXIT("arlan_process_interrupt");
-	return;
-}
-
-static irqreturn_t arlan_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	u_char rxStatus = READSHMB(arlan->rxStatus);
-	u_char txStatus = READSHMB(arlan->txStatus);
-
-	ARLAN_DEBUG_ENTRY("arlan_interrupt");
-
-
-	if (!rxStatus && !txStatus)
-		priv->interrupt_ack_requested++;
-
-	arlan_process_interrupt(dev);
-	
-	priv->irq_test_done = 1;
-
-	ARLAN_DEBUG_EXIT("arlan_interrupt");
-	return IRQ_HANDLED;
-
-}
-
-
-static int arlan_close(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-
-	ARLAN_DEBUG_ENTRY("arlan_close");
-
-	del_timer_sync(&priv->timer);
-
-	arlan_command(dev, ARLAN_COMMAND_POWERDOWN);
-
-	IFDEBUG(ARLAN_DEBUG_STARTUP)
-		printk(KERN_NOTICE "%s: Closing device\n", dev->name);
-
-	netif_stop_queue(dev);
-	free_irq(dev->irq, dev);
-
-	ARLAN_DEBUG_EXIT("arlan_close");
-	return 0;
-}
-
-#ifdef ARLAN_DEBUGGING
-static long alignLong(volatile u_char * ptr)
-{
-	long ret;
-	memcpy_fromio(&ret, (void *) ptr, 4);
-	return ret;
-}
-#endif
-
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-
-static struct net_device_stats *arlan_statistics(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_statistics");
-
-	/* Update the statistics from the device registers. */
-
-	READSHM(dev->stats.collisions, arlan->numReTransmissions, u_int);
-	READSHM(dev->stats.rx_crc_errors, arlan->numCRCErrors, u_int);
-	READSHM(dev->stats.rx_dropped, arlan->numFramesDiscarded, u_int);
-	READSHM(dev->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int);
-	READSHM(dev->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int);
-	READSHM(dev->stats.rx_over_errors, arlan->numRXOverruns, u_int);
-	READSHM(dev->stats.rx_packets, arlan->numDatagramsReceived, u_int);
-	READSHM(dev->stats.tx_aborted_errors, arlan->numAbortErrors, u_int);
-	READSHM(dev->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int);
-	READSHM(dev->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int);
-	READSHM(dev->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int);
-	READSHM(dev->stats.tx_packets, arlan->numDatagramsTransmitted, u_int);
-	READSHM(dev->stats.tx_window_errors, arlan->numHoldOffs, u_int);
-
-	ARLAN_DEBUG_EXIT("arlan_statistics");
-
-	return &dev->stats;
-}
-
-
-static void arlan_set_multicast(struct net_device *dev)
-{
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	struct arlan_conf_stru *conf = priv->Conf;
-	int board_conf_needed = 0;
-
-
-	ARLAN_DEBUG_ENTRY("arlan_set_multicast");
-
-	if (dev->flags & IFF_PROMISC)
-	{
-		unsigned char recMode;
-		READSHM(recMode, arlan->receiveMode, u_char);
-		conf->receiveMode = (ARLAN_RCV_PROMISC | ARLAN_RCV_CONTROL);
-		if (conf->receiveMode != recMode)
-			board_conf_needed = 1;
-	}
-	else
-	{
-		/* turn off promiscuous mode  */
-		unsigned char recMode;
-		READSHM(recMode, arlan->receiveMode, u_char);
-		conf->receiveMode = ARLAN_RCV_CLEAN | ARLAN_RCV_CONTROL;
-		if (conf->receiveMode != recMode)
-			board_conf_needed = 1;
-	}
-	if (board_conf_needed)
-		arlan_command(dev, ARLAN_COMMAND_CONF);
-
-	ARLAN_DEBUG_EXIT("arlan_set_multicast");
-}
-
-
-struct net_device * __init arlan_probe(int unit)
-{
-	struct net_device *dev;
-	int err;
-	int m;
-
-	ARLAN_DEBUG_ENTRY("arlan_probe");
-
-	if (arlans_found == MAX_ARLANS)
-		return ERR_PTR(-ENODEV);
-
-	/* 
-	 * Reserve space for local data and a copy of the shared memory
-	 * that is used by the /proc interface.
-	 */
-	dev = alloc_etherdev(sizeof(struct arlan_private)
-			     + sizeof(struct arlan_shmem));
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-		
-		if (dev->mem_start) {
-			if (arlan_probe_here(dev, dev->mem_start) == 0)
-				goto found;
-			goto not_found;
-		}
-			
-	}
-
-
-	for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; 
-	     m <= (int)phys_to_virt(0xDE000); 
-	     m += ARLAN_SHMEM_SIZE)
-	{
-		if (arlan_probe_here(dev, m) == 0)
-		{
-			lastFoundAt = (int)virt_to_phys((void*)m);
-			goto found;
-		}
-	}
-
-	if (lastFoundAt == 0xbe000)
-		printk(KERN_ERR "arlan: No Arlan devices found \n");
-
- not_found:
-	free_netdev(dev);
-	return ERR_PTR(-ENODEV);
-
- found:
-	err = arlan_setup_device(dev, arlans_found);
-	if (err)
-		dev = ERR_PTR(err);
-	else if (!arlans_found++)
-		printk(KERN_INFO "Arlan driver %s\n", arlan_version);
-
-	return dev;
-}
-
-#ifdef  MODULE
-int __init init_module(void)
-{
-	int i = 0;
-
-	ARLAN_DEBUG_ENTRY("init_module");
-
-	if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)
-		return -EINVAL;
-
-	for (i = 0; i < MAX_ARLANS; i++) {
-		struct net_device *dev = arlan_probe(i);
-
-		if (IS_ERR(dev)) 
-			return PTR_ERR(dev);
-	}
-	init_arlan_proc();
-	printk(KERN_INFO "Arlan driver %s\n", arlan_version);
-	ARLAN_DEBUG_EXIT("init_module");
-	return 0;
-}
-
-
-void __exit cleanup_module(void)
-{
-	int i = 0;
-	struct net_device *dev;
-
-	ARLAN_DEBUG_ENTRY("cleanup_module");
-
-	IFDEBUG(ARLAN_DEBUG_SHUTDOWN)
-		printk(KERN_INFO "arlan: unloading module\n");
-
-	cleanup_arlan_proc();
-
-	for (i = 0; i < MAX_ARLANS; i++)
-	{
-		dev = arlan_device[i];
-		if (dev) {
-			arlan_command(dev, ARLAN_COMMAND_POWERDOWN );
-
-			unregister_netdev(dev);
-			release_mem_region(virt_to_phys((void *) dev->mem_start), 
-					   ARLAN_SHMEM_SIZE);
-			free_netdev(dev);
-			arlan_device[i] = NULL;
-		}
-	}
-
-	ARLAN_DEBUG_EXIT("cleanup_module");
-}
-
-
-#endif
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan-proc.c linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan-proc.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/arlan-proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/arlan-proc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1253 +0,0 @@
-#include "arlan.h"
-
-#include <linux/sysctl.h>
-
-#ifdef CONFIG_PROC_FS
-
-/* void enableReceive(struct net_device* dev);
-*/
-
-
-
-#define ARLAN_STR_SIZE 	0x2ff0
-#define DEV_ARLAN_INFO 	1
-#define DEV_ARLAN 	1
-#define SARLG(type,var) {\
-	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, READSHMB(priva->card->var));	\
-	}
-
-#define SARLBN(type,var,nn) {\
-	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x",#var);\
-	for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
-	pos += sprintf(arlan_drive_info+pos, "\n");	\
-	}
-
-#define SARLBNpln(type,var,nn) {\
-	for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
-	}
-
-#define SARLSTR(var,nn) {\
-	char tmpStr[400];\
-	int  tmpLn = nn;\
-	if (nn > 399 ) tmpLn = 399; \
-	memcpy(tmpStr,(char *) priva->conf->var,tmpLn);\
-	tmpStr[tmpLn] = 0; \
-	pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s \n",#var,priva->conf->var);\
-	}
-
-#define SARLUC(var)  	SARLG(u_char, var)
-#define SARLUCN(var,nn) SARLBN(u_char,var, nn)
-#define SARLUS(var)	SARLG(u_short, var)
-#define SARLUSN(var,nn)	SARLBN(u_short,var, nn)
-#define SARLUI(var)	SARLG(u_int, var)
-
-#define SARLUSA(var) {\
-	u_short tmpVar;\
-	memcpy(&tmpVar, (short *) priva->conf->var,2); \
-	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
-}
-
-#define SARLUIA(var) {\
-	u_int tmpVar;\
-	memcpy(&tmpVar, (int* )priva->conf->var,4); \
-	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
-}
-
-
-static const char *arlan_diagnostic_info_string(struct net_device *dev)
-{
-
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	u_char diagnosticInfo;
-
-	READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
-
-	switch (diagnosticInfo)
-	{
-		case 0xFF:
-			return "Diagnostic info is OK";
-		case 0xFE:
-			return "ERROR EPROM Checksum error ";
-		case 0xFD:
-			return "ERROR Local Ram Test Failed ";
-		case 0xFC:
-			return "ERROR SCC failure ";
-		case 0xFB:
-			return "ERROR BackBone failure ";
-		case 0xFA:
-			return "ERROR transceiver not found ";
-		case 0xF9:
-			return "ERROR no more address space ";
-		case 0xF8:
-			return "ERROR Checksum error  ";
-		case 0xF7:
-			return "ERROR Missing SS Code";
-		case 0xF6:
-			return "ERROR Invalid config format";
-		case 0xF5:
-			return "ERROR Reserved errorcode F5";
-		case 0xF4:
-			return "ERROR Invalid spreading code/channel number";
-		case 0xF3:
-			return "ERROR Load Code Error";
-		case 0xF2:
-			return "ERROR Reserver errorcode F2 ";
-		case 0xF1:
-			return "ERROR Invalid command receivec by LAN card ";
-		case 0xF0:
-			return "ERROR Invalid parameter found in command ";
-		case 0xEF:
-			return "ERROR On-chip timer failure ";
-		case 0xEE:
-			return "ERROR T410 timer failure ";
-		case 0xED:
-			return "ERROR Too Many TxEnable commands ";
-		case 0xEC:
-			return "ERROR EEPROM error on radio module ";
-		default:
-			return "ERROR unknown Diagnostic info reply code ";
-	  }
-}
-
-static const char *arlan_hardware_type_string(struct net_device *dev)
-{
-	u_char hardwareType;
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-
-	READSHM(hardwareType, arlan->hardwareType, u_char);
-	switch (hardwareType)
-	{
-		case 0x00:
-			return "type A450";
-		case 0x01:
-			return "type A650 ";
-		case 0x04:
-			return "type TMA coproc";
-		case 0x0D:
-			return "type A650E ";
-		case 0x18:
-			return "type TMA coproc Australian";
-		case 0x19:
-			return "type A650A ";
-		case 0x26:
-			return "type TMA coproc European";
-		case 0x2E:
-			return "type A655 ";
-		case 0x2F:
-			return "type A655A ";
-		case 0x30:
-			return "type A655E ";
-		case 0x0B:
-			return "type A670 ";
-		case 0x0C:
-			return "type A670E ";
-		case 0x2D:
-			return "type A670A ";
-		case 0x0F:
-			return "type A411T";
-		case 0x16:
-			return "type A411TA";
-		case 0x1B:
-			return "type A440T";
-		case 0x1C:
-			return "type A412T";
-		case 0x1E:
-			return "type A412TA";
-		case 0x22:
-			return "type A411TE";
-		case 0x24:
-			return "type A412TE";
-		case 0x27:
-			return "type A671T ";
-		case 0x29:
-			return "type A671TA ";
-		case 0x2B:
-			return "type A671TE ";
-		case 0x31:
-			return "type A415T ";
-		case 0x33:
-			return "type A415TA ";
-		case 0x35:
-			return "type A415TE ";
-		case 0x37:
-			return "type A672";
-		case 0x39:
-			return "type A672A ";
-		case 0x3B:
-			return "type A672T";
-		case 0x6B:
-			return "type IC2200";
-		default:
-			return "type A672T";
-	}
-}
-#ifdef ARLAN_DEBUGGING
-static void arlan_print_diagnostic_info(struct net_device *dev)
-{
-	int i;
-	u_char diagnosticInfo;
-	u_short diagnosticOffset;
-	u_char hardwareType;
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-
-	//  ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info");
-
-	if (READSHMB(arlan->configuredStatusFlag) == 0)
-		printk("Arlan: Card NOT configured\n");
-	else
-		printk("Arlan: Card is configured\n");
-
-	READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
-	READSHM(diagnosticOffset, arlan->diagnosticOffset, u_short);
-
-	printk(KERN_INFO "%s\n", arlan_diagnostic_info_string(dev));
-
-	if (diagnosticInfo != 0xff)
-		printk("%s arlan: Diagnostic Offset %d \n", dev->name, diagnosticOffset);
-
-	printk("arlan: LAN CODE ID = ");
-	for (i = 0; i < 6; i++)
-		DEBUGSHM(1, "%03d:", arlan->lanCardNodeId[i], u_char);
-	printk("\n");
-
-	printk("arlan: Arlan BroadCast address  = ");
-	for (i = 0; i < 6; i++)
-		DEBUGSHM(1, "%03d:", arlan->broadcastAddress[i], u_char);
-	printk("\n");
-
-	READSHM(hardwareType, arlan->hardwareType, u_char);
-	printk(KERN_INFO "%s\n", arlan_hardware_type_string(dev));
-
-
-	DEBUGSHM(1, "arlan: channelNumber=%d\n", arlan->channelNumber, u_char);
-	DEBUGSHM(1, "arlan: channelSet=%d\n", arlan->channelSet, u_char);
-	DEBUGSHM(1, "arlan: spreadingCode=%d\n", arlan->spreadingCode, u_char);
-	DEBUGSHM(1, "arlan: radioNodeId=%d\n", arlan->radioNodeId, u_short);
-	DEBUGSHM(1, "arlan: SID	=%d\n", arlan->SID, u_short);
-	DEBUGSHM(1, "arlan: rxOffset=%d\n", arlan->rxOffset, u_short);
-
-	DEBUGSHM(1, "arlan: registration mode is %d\n", arlan->registrationMode, u_char);
-
-	printk("arlan: name= ");
-	IFDEBUG(1)
-	
-	for (i = 0; i < 16; i++)
-	{
-		char c;
-		READSHM(c, arlan->name[i], char);
-		if (c)
-			printk("%c", c);
-	}
-	printk("\n");
-
-//   ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info");
-
-}
-
-
-/******************************		TEST 	MEMORY	**************/
-
-static int arlan_hw_test_memory(struct net_device *dev)
-{
-	u_char *ptr;
-	int i;
-	int memlen = sizeof(struct arlan_shmem) - 0xF;	/* avoid control register */
-	volatile char *arlan_mem = (char *) (dev->mem_start);
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-	char pattern;
-
-	ptr = NULL;
-
-	/* hold card in reset state */
-	setHardwareReset(dev);
-
-	/* test memory */
-	pattern = 0;
-	for (i = 0; i < memlen; i++)
-		WRITESHM(arlan_mem[i], ((u_char) pattern++), u_char);
-
-	pattern = 0;
-	for (i = 0; i < memlen; i++)
-	{
-		char res;
-		READSHM(res, arlan_mem[i], char);
-		if (res != pattern++)
-		{
-			printk(KERN_ERR "Arlan driver memory test 1 failed \n");
-			return -1;
-		}
-	}
-
-	pattern = 0;
-	for (i = 0; i < memlen; i++)
-		WRITESHM(arlan_mem[i], ~(pattern++), char);
-
-	pattern = 0;
-	for (i = 0; i < memlen; i++)
-	{
-		char res;
-		READSHM(res, arlan_mem[i], char);
-		if (res != ~(pattern++))
-		{
-			printk(KERN_ERR "Arlan driver memory test 2 failed \n");
-			return -1;
-		}
-	}
-
-	/* zero memory */
-	for (i = 0; i < memlen; i++)
-		WRITESHM(arlan_mem[i], 0x00, char);
-
-	IFDEBUG(1) printk(KERN_INFO "Arlan: memory tests ok\n");
-
-	/* set reset flag and then release reset */
-	WRITESHM(arlan->resetFlag, 0xff, u_char);
-
-	clearChannelAttention(dev);
-	clearHardwareReset(dev);
-
-	/* wait for reset flag to become zero, we'll wait for two seconds */
-	if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW))
-	{
-		printk(KERN_ERR "%s arlan: failed to come back from memory test\n", dev->name);
-		return -1;
-	}
-	return 0;
-}
-
-static int arlan_setup_card_by_book(struct net_device *dev)
-{
-	u_char irqLevel, configuredStatusFlag;
-	struct arlan_private *priv = netdev_priv(dev);
-	volatile struct arlan_shmem __iomem *arlan = priv->card;
-
-//	ARLAN_DEBUG_ENTRY("arlan_setup_card");
-
-	READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
-
-	IFDEBUG(10)
-	if (configuredStatusFlag != 0)
-		IFDEBUG(10) printk("arlan: CARD IS CONFIGURED\n");
-	else
-		IFDEBUG(10) printk("arlan: card is NOT configured\n");
-
-	if (testMemory || (READSHMB(arlan->diagnosticInfo) != 0xff))
-		if (arlan_hw_test_memory(dev))
-			return -1;
-
-	DEBUGSHM(4, "arlan configuredStatus = %d \n", arlan->configuredStatusFlag, u_char);
-	DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n", arlan->diagnosticInfo, u_char);
-
-	/* issue nop command - no interrupt */
-	arlan_command(dev, ARLAN_COMMAND_NOOP);
-	if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
-		return -1;
-
-	IFDEBUG(50) printk("1st Noop successfully executed !!\n");
-
-	/* try to turn on the arlan interrupts */
-	clearClearInterrupt(dev);
-	setClearInterrupt(dev);
-	setInterruptEnable(dev);
-
-	/* issue nop command - with interrupt */
-
-	arlan_command(dev, ARLAN_COMMAND_NOOPINT);
-	if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
-		return -1;
-
-
-	IFDEBUG(50) printk("2nd Noop successfully executed !!\n");
-
-	READSHM(irqLevel, arlan->irqLevel, u_char)
-	
-	if (irqLevel != dev->irq)
-	{
-		IFDEBUG(1) printk(KERN_WARNING "arlan dip switches set irq to %d\n", irqLevel);
-		printk(KERN_WARNING "device driver irq set to %d - does not match\n", dev->irq);
-		dev->irq = irqLevel;
-	}
-	else
-		IFDEBUG(2) printk("irq level is OK\n");
-
-
-	IFDEBUG(3) arlan_print_diagnostic_info(dev);
-
-	arlan_command(dev, ARLAN_COMMAND_CONF);
-
-	READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
-	if (configuredStatusFlag == 0)
-	{
-		printk(KERN_WARNING "arlan configure failed\n");
-		return -1;
-	}
-	arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
-	arlan_command(dev, ARLAN_COMMAND_RX);
-	arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
-	printk(KERN_NOTICE "%s: arlan driver version %s loaded\n",
-	       dev->name, arlan_version);
-
-//	ARLAN_DEBUG_EXIT("arlan_setup_card");
-
-	return 0;		/* no errors */
-}
-#endif
-
-#ifdef ARLAN_PROC_INTERFACE
-#ifdef ARLAN_PROC_SHM_DUMP
-
-static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0";
-
-static int arlan_sysctl_info(ctl_table * ctl, int write,
-		      void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int i;
-	int retv, pos, devnum;
-	struct arlan_private *priva = NULL;
-	struct net_device *dev;
-	pos = 0;
-	if (write)
-	{
-		printk("wrirte: ");
-		for (i = 0; i < 100; i++)
-			printk("adi %x \n", arlan_drive_info[i]);
-	}
-	if (ctl->procname == NULL || arlan_drive_info == NULL)
-	{
-		printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL \n at arlan module\n ");
-		return -1;
-	}
-	devnum = ctl->procname[5] - '0';
-	if (devnum < 0 || devnum > MAX_ARLANS - 1)
-	{
-		printk(KERN_WARNING "too strange devnum in procfs parse\n ");
-		return -1;
-	}
-	else if (arlan_device[devnum] == NULL)
-	{
-		if (ctl->procname)
-			pos += sprintf(arlan_drive_info + pos, "\t%s\n\n", ctl->procname);
-		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
-		goto final;
-	}
-	else
-		priva = netdev_priv(arlan_device[devnum]);
-
-	if (priva == NULL)
-	{
-		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
-		return -1;
-	}
-	dev = arlan_device[devnum];
-
-	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
-
-	pos = sprintf(arlan_drive_info, "Arlan  info \n");
-	/* Header Signature */
-	SARLSTR(textRegion, 48);
-	SARLUC(resetFlag);
-	pos += sprintf(arlan_drive_info + pos, "diagnosticInfo\t=\t%s \n", arlan_diagnostic_info_string(dev));
-	SARLUC(diagnosticInfo);
-	SARLUS(diagnosticOffset);
-	SARLUCN(_1, 12);
-	SARLUCN(lanCardNodeId, 6);
-	SARLUCN(broadcastAddress, 6);
-	pos += sprintf(arlan_drive_info + pos, "hardwareType =\t  %s \n", arlan_hardware_type_string(dev));
-	SARLUC(hardwareType);
-	SARLUC(majorHardwareVersion);
-	SARLUC(minorHardwareVersion);
-	SARLUC(radioModule);
-	SARLUC(defaultChannelSet);
-	SARLUCN(_2, 47);
-
-	/* Control/Status Block - 0x0080 */
-	SARLUC(interruptInProgress);
-	SARLUC(cntrlRegImage);
-
-	SARLUCN(_3, 14);
-	SARLUC(commandByte);
-	SARLUCN(commandParameter, 15);
-
-	/* Receive Status - 0x00a0 */
-	SARLUC(rxStatus);
-	SARLUC(rxFrmType);
-	SARLUS(rxOffset);
-	SARLUS(rxLength);
-	SARLUCN(rxSrc, 6);
-	SARLUC(rxBroadcastFlag);
-	SARLUC(rxQuality);
-	SARLUC(scrambled);
-	SARLUCN(_4, 1);
-
-	/* Transmit Status - 0x00b0 */
-	SARLUC(txStatus);
-	SARLUC(txAckQuality);
-	SARLUC(numRetries);
-	SARLUCN(_5, 14);
-	SARLUCN(registeredRouter, 6);
-	SARLUCN(backboneRouter, 6);
-	SARLUC(registrationStatus);
-	SARLUC(configuredStatusFlag);
-	SARLUCN(_6, 1);
-	SARLUCN(ultimateDestAddress, 6);
-	SARLUCN(immedDestAddress, 6);
-	SARLUCN(immedSrcAddress, 6);
-	SARLUS(rxSequenceNumber);
-	SARLUC(assignedLocaltalkAddress);
-	SARLUCN(_7, 27);
-
-	/* System Parameter Block */
-
-	/* - Driver Parameters (Novell Specific) */
-
-	SARLUS(txTimeout);
-	SARLUS(transportTime);
-	SARLUCN(_8, 4);
-
-	/* - Configuration Parameters */
-	SARLUC(irqLevel);
-	SARLUC(spreadingCode);
-	SARLUC(channelSet);
-	SARLUC(channelNumber);
-	SARLUS(radioNodeId);
-	SARLUCN(_9, 2);
-	SARLUC(scramblingDisable);
-	SARLUC(radioType);
-	SARLUS(routerId);
-	SARLUCN(_10, 9);
-	SARLUC(txAttenuation);
-	SARLUIA(systemId);
-	SARLUS(globalChecksum);
-	SARLUCN(_11, 4);
-	SARLUS(maxDatagramSize);
-	SARLUS(maxFrameSize);
-	SARLUC(maxRetries);
-	SARLUC(receiveMode);
-	SARLUC(priority);
-	SARLUC(rootOrRepeater);
-	SARLUCN(specifiedRouter, 6);
-	SARLUS(fastPollPeriod);
-	SARLUC(pollDecay);
-	SARLUSA(fastPollDelay);
-	SARLUC(arlThreshold);
-	SARLUC(arlDecay);
-	SARLUCN(_12, 1);
-	SARLUS(specRouterTimeout);
-	SARLUCN(_13, 5);
-
-	/* Scrambled Area */
-	SARLUIA(SID);
-	SARLUCN(encryptionKey, 12);
-	SARLUIA(_14);
-	SARLUSA(waitTime);
-	SARLUSA(lParameter);
-	SARLUCN(_15, 3);
-	SARLUS(headerSize);
-	SARLUS(sectionChecksum);
-
-	SARLUC(registrationMode);
-	SARLUC(registrationFill);
-	SARLUS(pollPeriod);
-	SARLUS(refreshPeriod);
-	SARLSTR(name, 16);
-	SARLUCN(NID, 6);
-	SARLUC(localTalkAddress);
-	SARLUC(codeFormat);
-	SARLUC(numChannels);
-	SARLUC(channel1);
-	SARLUC(channel2);
-	SARLUC(channel3);
-	SARLUC(channel4);
-	SARLUCN(SSCode, 59);
-
-/*      SARLUCN( _16, 0x140);
- */
-	/* Statistics Block - 0x0300 */
-	SARLUC(hostcpuLock);
-	SARLUC(lancpuLock);
-	SARLUCN(resetTime, 18);
-	SARLUIA(numDatagramsTransmitted);
-	SARLUIA(numReTransmissions);
-	SARLUIA(numFramesDiscarded);
-	SARLUIA(numDatagramsReceived);
-	SARLUIA(numDuplicateReceivedFrames);
-	SARLUIA(numDatagramsDiscarded);
-	SARLUS(maxNumReTransmitDatagram);
-	SARLUS(maxNumReTransmitFrames);
-	SARLUS(maxNumConsecutiveDuplicateFrames);
-	/* misaligned here so we have to go to characters */
-	SARLUIA(numBytesTransmitted);
-	SARLUIA(numBytesReceived);
-	SARLUIA(numCRCErrors);
-	SARLUIA(numLengthErrors);
-	SARLUIA(numAbortErrors);
-	SARLUIA(numTXUnderruns);
-	SARLUIA(numRXOverruns);
-	SARLUIA(numHoldOffs);
-	SARLUIA(numFramesTransmitted);
-	SARLUIA(numFramesReceived);
-	SARLUIA(numReceiveFramesLost);
-	SARLUIA(numRXBufferOverflows);
-	SARLUIA(numFramesDiscardedAddrMismatch);
-	SARLUIA(numFramesDiscardedSIDMismatch);
-	SARLUIA(numPollsTransmistted);
-	SARLUIA(numPollAcknowledges);
-	SARLUIA(numStatusTimeouts);
-	SARLUIA(numNACKReceived);
-	SARLUS(auxCmd);
-	SARLUCN(dumpPtr, 4);
-	SARLUC(dumpVal);
-	SARLUC(wireTest);
-	
-	/* next 4 seems too long for procfs, over single page ?
-	SARLUCN( _17, 0x86);
-	SARLUCN( txBuffer, 0x800);
-	SARLUCN( rxBuffer,  0x800); 
-	SARLUCN( _18, 0x0bff);
-	 */
-
-	pos += sprintf(arlan_drive_info + pos, "rxRing\t=\t0x");
-	for (i = 0; i < 0x50; i++)
-		pos += sprintf(arlan_drive_info + pos, "%02x", ((char *) priva->conf)[priva->conf->rxOffset + i]);
-	pos += sprintf(arlan_drive_info + pos, "\n");
-
-	SARLUC(configStatus);
-	SARLUC(_22);
-	SARLUC(progIOCtrl);
-	SARLUC(shareMBase);
-	SARLUC(controlRegister);
-
-	pos += sprintf(arlan_drive_info + pos, " total %d chars\n", pos);
-	if (ctl)
-		if (ctl->procname)
-			pos += sprintf(arlan_drive_info + pos, " driver name : %s\n", ctl->procname);
-final:
-	*lenp = pos;
-
-	if (!write)
-		retv = proc_dostring(ctl, write, buffer, lenp, ppos);
-	else
-	{
-		*lenp = 0;
-		return -1;
-	}
-	return retv;
-}
-
-
-static int arlan_sysctl_info161719(ctl_table * ctl, int write,
-			    void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int i;
-	int retv, pos, devnum;
-	struct arlan_private *priva = NULL;
-
-	pos = 0;
-	devnum = ctl->procname[5] - '0';
-	if (arlan_device[devnum] == NULL)
-	{
-		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
-		goto final;
-	}
-	else
-		priva = netdev_priv(arlan_device[devnum]);
-	if (priva == NULL)
-	{
-		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
-		return -1;
-	}
-	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
-	SARLUCN(_16, 0xC0);
-	SARLUCN(_17, 0x6A);
-	SARLUCN(_18, 14);
-	SARLUCN(_19, 0x86);
-	SARLUCN(_21, 0x3fd);
-
-final:
-	*lenp = pos;
-	retv = proc_dostring(ctl, write, buffer, lenp, ppos);
-	return retv;
-}
-
-static int arlan_sysctl_infotxRing(ctl_table * ctl, int write,
-			    void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int i;
-	int retv, pos, devnum;
-	struct arlan_private *priva = NULL;
-
-	pos = 0;
-	devnum = ctl->procname[5] - '0';
-	if (arlan_device[devnum] == NULL)
-	{
-		  pos += sprintf(arlan_drive_info + pos, "No device found here \n");
-		  goto final;
-	}
-	else
-		priva = netdev_priv(arlan_device[devnum]);
-	if (priva == NULL)
-	{
-		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
-		return -1;
-	}
-	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
-	SARLBNpln(u_char, txBuffer, 0x800);
-final:
-	*lenp = pos;
-	retv = proc_dostring(ctl, write, buffer, lenp, ppos);
-	return retv;
-}
-
-static int arlan_sysctl_inforxRing(ctl_table * ctl, int write,
-			    void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int i;
-	int retv, pos, devnum;
-	struct arlan_private *priva = NULL;
-
-	pos = 0;
-	devnum = ctl->procname[5] - '0';
-	if (arlan_device[devnum] == NULL)
-	{
-		  pos += sprintf(arlan_drive_info + pos, "No device found here \n");
-		  goto final;
-	} else
-		priva = netdev_priv(arlan_device[devnum]);
-	if (priva == NULL)
-	{
-		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
-		return -1;
-	}
-	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
-	SARLBNpln(u_char, rxBuffer, 0x800);
-final:
-	*lenp = pos;
-	retv = proc_dostring(ctl, write, buffer, lenp, ppos);
-	return retv;
-}
-
-static int arlan_sysctl_info18(ctl_table * ctl, int write,
-			void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int i;
-	int retv, pos, devnum;
-	struct arlan_private *priva = NULL;
-
-	pos = 0;
-	devnum = ctl->procname[5] - '0';
-	if (arlan_device[devnum] == NULL)
-	{
-		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
-		goto final;
-	}
-	else
-		priva = netdev_priv(arlan_device[devnum]);
-	if (priva == NULL)
-	{
-		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
-		return -1;
-	}
-	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
-	SARLBNpln(u_char, _18, 0x800);
-
-final:
-	*lenp = pos;
-	retv = proc_dostring(ctl, write, buffer, lenp, ppos);
-	return retv;
-}
-
-
-#endif				/* #ifdef ARLAN_PROC_SHM_DUMP */
-
-
-static char conf_reset_result[200];
-
-static int arlan_configure(ctl_table * ctl, int write,
-		    void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int pos = 0;
-	int devnum = ctl->procname[6] - '0';
-	struct arlan_private *priv;
-
-	if (devnum < 0 || devnum > MAX_ARLANS - 1)
-	{
-		  printk(KERN_WARNING "too strange devnum in procfs parse\n ");
-		  return -1;
-	}
-	else if (arlan_device[devnum] != NULL)
-	{
-		  priv = netdev_priv(arlan_device[devnum]);
-
-		  arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_CONF);
-	}
-	else
-		return -1;
-
-	*lenp = pos;
-	return proc_dostring(ctl, write, buffer, lenp, ppos);
-}
-
-static int arlan_sysctl_reset(ctl_table * ctl, int write,
-		       void __user *buffer, size_t * lenp, loff_t *ppos)
-{
-	int pos = 0;
-	int devnum = ctl->procname[5] - '0';
-	struct arlan_private *priv;
-
-	if (devnum < 0 || devnum > MAX_ARLANS - 1)
-	{
-		  printk(KERN_WARNING "too strange devnum in procfs parse\n ");
-		  return -1;
-	}
-	else if (arlan_device[devnum] != NULL)
-	{
-		priv = netdev_priv(arlan_device[devnum]);
-		arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_RESET);
-
-	} else
-		return -1;
-	*lenp = pos + 3;
-	return proc_dostring(ctl, write, buffer, lenp, ppos);
-}
-
-
-/* Place files in /proc/sys/dev/arlan */
-#define CTBLN(num,card,nam) \
-        { .ctl_name = num,\
-          .procname = #nam,\
-          .data = &(arlan_conf[card].nam),\
-          .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec}
-#ifdef ARLAN_DEBUGGING
-
-#define ARLAN_PROC_DEBUG_ENTRIES \
-        { .ctl_name = 48, .procname = "entry_exit_debug",\
-          .data = &arlan_entry_and_exit_debug,\
-          .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec},\
-	{ .ctl_name = 49, .procname = "debug", .data = &arlan_debug,\
-          .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec},
-#else 
-#define ARLAN_PROC_DEBUG_ENTRIES
-#endif
-
-#define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\
-	CTBLN(1,cardNo,spreadingCode),\
-	CTBLN(2,cardNo, channelNumber),\
-	CTBLN(3,cardNo, scramblingDisable),\
-	CTBLN(4,cardNo, txAttenuation),\
-	CTBLN(5,cardNo, systemId), \
-	CTBLN(6,cardNo, maxDatagramSize),\
-	CTBLN(7,cardNo, maxFrameSize),\
-	CTBLN(8,cardNo, maxRetries),\
-	CTBLN(9,cardNo, receiveMode),\
-	CTBLN(10,cardNo, priority),\
-	CTBLN(11,cardNo, rootOrRepeater),\
-	CTBLN(12,cardNo, SID),\
-	CTBLN(13,cardNo, registrationMode),\
-	CTBLN(14,cardNo, registrationFill),\
-	CTBLN(15,cardNo, localTalkAddress),\
-	CTBLN(16,cardNo, codeFormat),\
-	CTBLN(17,cardNo, numChannels),\
-	CTBLN(18,cardNo, channel1),\
-	CTBLN(19,cardNo, channel2),\
-	CTBLN(20,cardNo, channel3),\
-	CTBLN(21,cardNo, channel4),\
-	CTBLN(22,cardNo, txClear),\
-	CTBLN(23,cardNo, txRetries),\
-	CTBLN(24,cardNo, txRouting),\
-	CTBLN(25,cardNo, txScrambled),\
-	CTBLN(26,cardNo, rxParameter),\
-	CTBLN(27,cardNo, txTimeoutMs),\
-	CTBLN(28,cardNo, waitCardTimeout),\
-	CTBLN(29,cardNo, channelSet), \
-	{.ctl_name = 30, .procname = "name",\
-	 .data = arlan_conf[cardNo].siteName,\
-	 .maxlen = 16, .mode = 0600, .proc_handler = &proc_dostring},\
-	CTBLN(31,cardNo,waitTime),\
-	CTBLN(32,cardNo,lParameter),\
-	CTBLN(33,cardNo,_15),\
-	CTBLN(34,cardNo,headerSize),\
-	CTBLN(36,cardNo,tx_delay_ms),\
-	CTBLN(37,cardNo,retries),\
-	CTBLN(38,cardNo,ReTransmitPacketMaxSize),\
-	CTBLN(39,cardNo,waitReTransmitPacketMaxSize),\
-	CTBLN(40,cardNo,fastReTransCount),\
-	CTBLN(41,cardNo,driverRetransmissions),\
-	CTBLN(42,cardNo,txAckTimeoutMs),\
-	CTBLN(43,cardNo,registrationInterrupts),\
-	CTBLN(44,cardNo,hardwareType),\
-	CTBLN(45,cardNo,radioType),\
-	CTBLN(46,cardNo,writeEEPROM),\
-	CTBLN(47,cardNo,writeRadioType),\
-	ARLAN_PROC_DEBUG_ENTRIES\
-	CTBLN(50,cardNo,in_speed),\
-	CTBLN(51,cardNo,out_speed),\
-	CTBLN(52,cardNo,in_speed10),\
-	CTBLN(53,cardNo,out_speed10),\
-	CTBLN(54,cardNo,in_speed_max),\
-	CTBLN(55,cardNo,out_speed_max),\
-	CTBLN(56,cardNo,measure_rate),\
-	CTBLN(57,cardNo,pre_Command_Wait),\
-	CTBLN(58,cardNo,rx_tweak1),\
-	CTBLN(59,cardNo,rx_tweak2),\
-	CTBLN(60,cardNo,tx_queue_len),\
-
-
-
-static ctl_table arlan_conf_table0[] =
-{
-	ARLAN_SYSCTL_TABLE_TOTAL(0)
-
-#ifdef ARLAN_PROC_SHM_DUMP
-	{
-		.ctl_name	= 150,
-		.procname	= "arlan0-txRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_infotxRing,
-	},
-	{
-		.ctl_name	= 151,
-		.procname	= "arlan0-rxRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_inforxRing,
-	},
-	{
-		.ctl_name	= 152,
-		.procname	= "arlan0-18",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info18,
-	},
-	{
-		.ctl_name	= 153,
-		.procname	= "arlan0-ring",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info161719,
-	},
-	{
-		.ctl_name	= 154,
-		.procname	= "arlan0-shm-cpy",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info,
-	},
-#endif
-	{
-		.ctl_name	= 155,
-		.procname	= "config0",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_configure
-	},
-	{
-		.ctl_name	= 156,
-		.procname	= "reset0",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_reset,
-	},
-	{ .ctl_name = 0 }
-};
-
-static ctl_table arlan_conf_table1[] =
-{
-
-	ARLAN_SYSCTL_TABLE_TOTAL(1)
-
-#ifdef ARLAN_PROC_SHM_DUMP
-	{
-		.ctl_name	= 150,
-		.procname	= "arlan1-txRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_infotxRing,
-	},
-	{
-		.ctl_name	= 151,
-		.procname	= "arlan1-rxRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_inforxRing,
-	},
-	{
-		.ctl_name	= 152,
-		.procname	= "arlan1-18",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info18,
-	},
-	{
-		.ctl_name	= 153,
-		.procname	= "arlan1-ring",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info161719,
-	},
-	{
-		.ctl_name	= 154,
-		.procname	= "arlan1-shm-cpy",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info,
-	},
-#endif
-	{
-		.ctl_name	= 155,
-		.procname	= "config1",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_configure,
-	},
-	{
-		.ctl_name	= 156,
-		.procname	= "reset1",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_reset,
-	},
-	{ .ctl_name = 0 }
-};
-
-static ctl_table arlan_conf_table2[] =
-{
-
-	ARLAN_SYSCTL_TABLE_TOTAL(2)
-
-#ifdef ARLAN_PROC_SHM_DUMP
-	{
-		.ctl_name	= 150,
-		.procname	= "arlan2-txRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_infotxRing,
-	},
-	{
-		.ctl_name	= 151,
-		.procname	= "arlan2-rxRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_inforxRing,
-	},
-	{
-		.ctl_name	= 152,
-		.procname	= "arlan2-18",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info18,
-	},
-	{
-		.ctl_name	= 153,
-		.procname	= "arlan2-ring",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info161719,
-	},
-	{
-		.ctl_name	= 154,
-		.procname	= "arlan2-shm-cpy",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info,
-	},
-#endif
-	{
-		.ctl_name	= 155,
-		.procname	= "config2",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_configure,
-	},
-	{
-		.ctl_name	= 156,
-		.procname	= "reset2",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_reset,
-	},
-	{ .ctl_name = 0 }
-};
-
-static ctl_table arlan_conf_table3[] =
-{
-
-	ARLAN_SYSCTL_TABLE_TOTAL(3)
-
-#ifdef ARLAN_PROC_SHM_DUMP
-	{
-		.ctl_name	= 150,
-		.procname	= "arlan3-txRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_infotxRing,
-	},
-	{
-		.ctl_name	= 151,
-		.procname	= "arlan3-rxRing",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_inforxRing,
-	},
-	{
-		.ctl_name	= 152,
-		.procname	= "arlan3-18",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info18,
-	},
-	{
-		.ctl_name	= 153,
-		.procname	= "arlan3-ring",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info161719,
-	},
-	{
-		.ctl_name	= 154,
-		.procname	= "arlan3-shm-cpy",
-		.data		= &arlan_drive_info,
-		.maxlen		= ARLAN_STR_SIZE,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_info,
-	},
-#endif
-	{
-		.ctl_name	= 155,
-		.procname	= "config3",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_configure,
-	},
-	{
-		.ctl_name	= 156,
-		.procname	= "reset3",
-		.data		= &conf_reset_result,
-		.maxlen		= 100,
-		.mode		= 0400,
-		.proc_handler	= &arlan_sysctl_reset,
-	},
-	{ .ctl_name = 0 }
-};
-
-
-
-static ctl_table arlan_table[] =
-{
-	{
-		.ctl_name	= 0,
-		.procname	= "arlan0",
-		.maxlen		= 0,
-		.mode		= 0600,
-		.child		= arlan_conf_table0,
-	},
-	{
-		.ctl_name	= 0,
-		.procname	= "arlan1",
-		.maxlen		= 0,
-		.mode		= 0600,
-		.child		= arlan_conf_table1,
-	},
-	{
-		.ctl_name	= 0,
-		.procname	= "arlan2",
-		.maxlen		= 0,
-		.mode		= 0600,
-		.child		= arlan_conf_table2,
-	},
-	{
-		.ctl_name	= 0,
-		.procname	= "arlan3",
-		.maxlen		= 0,
-		.mode		= 0600,
-		.child		= arlan_conf_table3,
-	},
-	{ .ctl_name = 0 }
-};
-
-#else
-
-static ctl_table arlan_table[MAX_ARLANS + 1] =
-{
-	{ .ctl_name = 0 }
-};
-#endif
-
-
-// static int mmtu = 1234;
-
-static ctl_table arlan_root_table[] =
-{
-	{
-		.ctl_name	= CTL_ARLAN,
-		.procname	= "arlan",
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= arlan_table,
-	},
-	{ .ctl_name = 0 }
-};
-
-/* Make sure that /proc/sys/dev is there */
-//static ctl_table arlan_device_root_table[] =
-//{
-//	{CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table},
-//	{0}
-//};
-
-
-static struct ctl_table_header *arlan_device_sysctl_header;
-
-int __init init_arlan_proc(void)
-{
-
-	int i = 0;
-	if (arlan_device_sysctl_header)
-		return 0;
-	for (i = 0; i < MAX_ARLANS && arlan_device[i]; i++)
-		arlan_table[i].ctl_name = i + 1;
-	arlan_device_sysctl_header = register_sysctl_table(arlan_root_table);
-	if (!arlan_device_sysctl_header)
-		return -1;
-
-	return 0;
-
-}
-
-void __exit cleanup_arlan_proc(void)
-{
-	unregister_sysctl_table(arlan_device_sysctl_header);
-	arlan_device_sysctl_header = NULL;
-
-}
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/at76c50x-usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/at76c50x-usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/at76c50x-usb.c	2013-05-03 14:01:52.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/at76c50x-usb.c	2013-05-03 12:09:14.000000000 -0400
@@ -121,6 +121,7 @@ static struct fwentry firmwares[] = {
 	[BOARD_505A] = { "/*(DEBLOBBED)*/" },
 	[BOARD_505AMX] = { "/*(DEBLOBBED)*/" },
 };
+/*(DEBLOBBED)*/
 
 #define USB_DEVICE_DATA(__ops)	.driver_info = (kernel_ulong_t)(__ops)
 
@@ -524,20 +525,6 @@ static char *hex2str(void *buf, int len)
 	return ret;
 }
 
-#define MAC2STR_BUFFERS 4
-
-static inline char *mac2str(u8 *mac)
-{
-	static atomic_t a = ATOMIC_INIT(0);
-	static char bufs[MAC2STR_BUFFERS][6 * 3];
-	char *str;
-
-	str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
-	sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
-		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-	return str;
-}
-
 /* LED trigger */
 static int tx_activity;
 static void at76_ledtrig_tx_timerfunc(unsigned long data);
@@ -973,13 +960,13 @@ static void at76_dump_mib_mac_addr(struc
 		goto exit;
 	}
 
-	at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
+	at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %pM res 0x%x 0x%x",
 		 wiphy_name(priv->hw->wiphy),
-		 mac2str(m->mac_addr), m->res[0], m->res[1]);
+		 m->mac_addr, m->res[0], m->res[1]);
 	for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
-		at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
+		at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %pM, "
 			 "status %d", wiphy_name(priv->hw->wiphy), i,
-			 mac2str(m->group_addr[i]), m->group_addr_status[i]);
+			 m->group_addr[i], m->group_addr_status[i]);
 exit:
 	kfree(m);
 }
@@ -1042,7 +1029,7 @@ static void at76_dump_mib_mac_mgmt(struc
 	at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
 		 "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
 		 "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
-		 "current_bssid %s current_essid %s current_bss_type %d "
+		 "current_bssid %pM current_essid %s current_bss_type %d "
 		 "pm_mode %d ibss_change %d res %d "
 		 "multi_domain_capability_implemented %d "
 		 "international_roaming %d country_string %.3s",
@@ -1051,7 +1038,7 @@ static void at76_dump_mib_mac_mgmt(struc
 		 le16_to_cpu(m->medium_occupancy_limit),
 		 le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
 		 m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
-		 m->CFP_period, mac2str(m->current_bssid),
+		 m->CFP_period, m->current_bssid,
 		 hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
 		 m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
 		 m->res, m->multi_domain_capability_implemented,
@@ -1080,7 +1067,7 @@ static void at76_dump_mib_mac(struct at7
 		 "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
 		 "scan_type %d scan_channel %d probe_delay %u "
 		 "min_channel_time %d max_channel_time %d listen_int %d "
-		 "desired_ssid %s desired_bssid %s desired_bsstype %d",
+		 "desired_ssid %s desired_bssid %pM desired_bsstype %d",
 		 wiphy_name(priv->hw->wiphy),
 		 le32_to_cpu(m->max_tx_msdu_lifetime),
 		 le32_to_cpu(m->max_rx_lifetime),
@@ -1092,7 +1079,7 @@ static void at76_dump_mib_mac(struct at7
 		 le16_to_cpu(m->max_channel_time),
 		 le16_to_cpu(m->listen_interval),
 		 hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
-		 mac2str(m->desired_bssid), m->desired_bsstype);
+		 m->desired_bssid, m->desired_bsstype);
 exit:
 	kfree(m);
 }
@@ -1194,6 +1181,9 @@ static int at76_start_monitor(struct at7
 	scan.channel = priv->channel;
 	scan.scan_type = SCAN_TYPE_PASSIVE;
 	scan.international_scan = 0;
+	scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+	scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+	scan.probe_delay = cpu_to_le16(0);
 
 	ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
 	if (ret >= 0)
@@ -2217,6 +2207,8 @@ static struct ieee80211_supported_band a
 static int at76_init_new_device(struct at76_priv *priv,
 				struct usb_interface *interface)
 {
+	struct wiphy *wiphy;
+	size_t len;
 	int ret;
 
 	/* set up the endpoint information */
@@ -2254,6 +2246,7 @@ static int at76_init_new_device(struct a
 	priv->device_unplugged = 0;
 
 	/* mac80211 initialisation */
+	wiphy = priv->hw->wiphy;
 	priv->hw->wiphy->max_scan_ssids = 1;
 	priv->hw->wiphy->max_scan_ie_len = 0;
 	priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
@@ -2265,6 +2258,13 @@ static int at76_init_new_device(struct a
 	SET_IEEE80211_DEV(priv->hw, &interface->dev);
 	SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
+	len = sizeof(wiphy->fw_version);
+	snprintf(wiphy->fw_version, len, "%d.%d.%d-%d",
+		 priv->fw_version.major, priv->fw_version.minor,
+		 priv->fw_version.patch, priv->fw_version.build);
+
+	wiphy->hw_version = priv->board_type;
+
 	ret = ieee80211_register_hw(priv->hw);
 	if (ret) {
 		printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
@@ -2274,9 +2274,9 @@ static int at76_init_new_device(struct a
 
 	priv->mac80211_registered = 1;
 
-	printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+	printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n",
 	       wiphy_name(priv->hw->wiphy),
-	       dev_name(&interface->dev), mac2str(priv->mac_addr),
+	       dev_name(&interface->dev), priv->mac_addr,
 	       priv->fw_version.major, priv->fw_version.minor,
 	       priv->fw_version.patch, priv->fw_version.build);
 	printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/ar9170.h	2010-02-24 13:52:17.000000000 -0500
@@ -172,8 +172,6 @@ struct ar9170 {
 
 	/* interface mode settings */
 	struct ieee80211_vif *vif;
-	u8 mac_addr[ETH_ALEN];
-	u8 bssid[ETH_ALEN];
 
 	/* beaconing */
 	struct sk_buff *beacon;
@@ -204,6 +202,8 @@ struct ar9170 {
 	u8 power_2G_ht20[8];
 	u8 power_2G_ht40[8];
 
+	u8 phy_heavy_clip;
+
 #ifdef CONFIG_AR9170_LEDS
 	struct delayed_work led_work;
 	struct ar9170_led leds[AR9170_NUM_LEDS];
@@ -231,7 +231,7 @@ struct ar9170 {
 	struct sk_buff_head tx_status_ampdu;
 	spinlock_t tx_ampdu_list_lock;
 	struct list_head tx_ampdu_list;
-	unsigned int tx_ampdu_pending;
+	atomic_t tx_ampdu_pending;
 
 	/* rxstream mpdu merge */
 	struct ar9170_rxstream_mpdu_merge rx_mpdu;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/cmd.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/cmd.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/cmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/cmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar,
 	return err;
 }
 
-static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
-			    const u32 *regs, u32 *out)
+int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
 {
 	int i, err;
 	__le32 *offs, *res;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/cmd.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/cmd.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/cmd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/cmd.h	2010-02-24 13:52:17.000000000 -0500
@@ -44,6 +44,7 @@
 int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
 int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
 int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
+int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out);
 int ar9170_echo_test(struct ar9170 *ar, u32 v);
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -152,14 +152,14 @@ enum ar9170_cmd {
 #define		AR9170_MAC_REG_FTF_BIT14		BIT(14)
 #define		AR9170_MAC_REG_FTF_BIT15		BIT(15)
 #define		AR9170_MAC_REG_FTF_BAR			BIT(24)
-#define		AR9170_MAC_REG_FTF_BIT25		BIT(25)
+#define		AR9170_MAC_REG_FTF_BA			BIT(25)
 #define		AR9170_MAC_REG_FTF_PSPOLL		BIT(26)
 #define		AR9170_MAC_REG_FTF_RTS			BIT(27)
 #define		AR9170_MAC_REG_FTF_CTS			BIT(28)
 #define		AR9170_MAC_REG_FTF_ACK			BIT(29)
 #define		AR9170_MAC_REG_FTF_CFE			BIT(30)
 #define		AR9170_MAC_REG_FTF_CFE_ACK		BIT(31)
-#define		AR9170_MAC_REG_FTF_DEFAULTS		0x0500ffff
+#define		AR9170_MAC_REG_FTF_DEFAULTS		0x0700ffff
 #define		AR9170_MAC_REG_FTF_MONITOR		0xfd00ffff
 
 #define AR9170_MAC_REG_RX_TOTAL			(AR9170_MAC_REG_BASE + 0x6A0)
@@ -311,6 +311,8 @@ struct ar9170_tx_control {
 
 #define AR9170_TX_PHY_SHORT_GI			0x80000000
 
+#define AR5416_MAX_RATE_POWER                   63
+
 struct ar9170_rx_head {
 	u8 plcp[12];
 } __packed;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config AR9170_USB
 	tristate "Atheros AR9170 802.11n USB support"
-	depends on USB && MAC80211 && WLAN_80211
+	depends on USB && MAC80211
 	select FW_LOADER
 	help
 	  This is a driver for the Atheros "otus" 802.11n USB devices.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/mac.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,9 @@
  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#include <asm/unaligned.h>
+
 #include "ar9170.h"
 #include "cmd.h"
 
@@ -227,11 +230,8 @@ static int ar9170_set_mac_reg(struct ar9
 
 	ar9170_regwrite_begin(ar);
 
-	ar9170_regwrite(reg,
-			(mac[3] << 24) | (mac[2] << 16) |
-			(mac[1] << 8) | mac[0]);
-
-	ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
+	ar9170_regwrite(reg, get_unaligned_le32(mac));
+	ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
 
 	ar9170_regwrite_finish();
 
@@ -311,13 +311,14 @@ static int ar9170_set_promiscouous(struc
 
 int ar9170_set_operating_mode(struct ar9170 *ar)
 {
+	struct ath_common *common = &ar->common;
 	u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
 	u8 *mac_addr, *bssid;
 	int err;
 
 	if (ar->vif) {
-		mac_addr = ar->mac_addr;
-		bssid = ar->bssid;
+		mac_addr = common->macaddr;
+		bssid = common->curbssid;
 
 		switch (ar->vif->type) {
 		case NL80211_IFTYPE_MESH_POINT:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -414,9 +414,9 @@ static void ar9170_tx_ampdu_callback(str
 
 	skb_queue_tail(&ar->tx_status_ampdu, skb);
 	ar9170_tx_fake_ampdu_status(ar);
-	ar->tx_ampdu_pending--;
 
-	if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending)
+	if (atomic_dec_and_test(&ar->tx_ampdu_pending) &&
+	    !list_empty(&ar->tx_ampdu_list))
 		ar9170_tx_ampdu(ar);
 }
 
@@ -850,6 +850,7 @@ static int ar9170_rx_mac_status(struct a
 		}
 		break;
 
+	case AR9170_RX_STATUS_MODULATION_DUPOFDM:
 	case AR9170_RX_STATUS_MODULATION_OFDM:
 		switch (head->plcp[0] & 0xf) {
 		case 0xb:
@@ -897,8 +898,7 @@ static int ar9170_rx_mac_status(struct a
 		status->flag |= RX_FLAG_HT;
 		break;
 
-	case AR9170_RX_STATUS_MODULATION_DUPOFDM:
-		/* XXX */
+	default:
 		if (ar9170_nag_limiter(ar))
 			printk(KERN_ERR "%s: invalid modulation\n",
 			       wiphy_name(ar->hw->wiphy));
@@ -1248,6 +1248,7 @@ static int ar9170_op_start(struct ieee80
 	ar->global_ampdu_density = 6;
 	ar->global_ampdu_factor = 3;
 
+	atomic_set(&ar->tx_ampdu_pending, 0);
 	ar->bad_hw_nagger = jiffies;
 
 	err = ar->open(ar);
@@ -1773,7 +1774,7 @@ static void ar9170_tx(struct ar9170 *ar)
 					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
 
 			if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
-				ar->tx_ampdu_pending++;
+				atomic_inc(&ar->tx_ampdu_pending);
 
 #ifdef AR9170_QUEUE_DEBUG
 			printk(KERN_DEBUG "%s: send frame q:%d =>\n",
@@ -1784,7 +1785,7 @@ static void ar9170_tx(struct ar9170 *ar)
 			err = ar->tx(ar, skb);
 			if (unlikely(err)) {
 				if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
-					ar->tx_ampdu_pending--;
+					atomic_dec(&ar->tx_ampdu_pending);
 
 				frames_failed++;
 				dev_kfree_skb_any(skb);
@@ -1931,7 +1932,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw
 	if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 		bool run = ar9170_tx_ampdu_queue(ar, skb);
 
-		if (run || !ar->tx_ampdu_pending)
+		if (run || !atomic_read(&ar->tx_ampdu_pending))
 			ar9170_tx_ampdu(ar);
 	} else {
 		unsigned int queue = skb_get_queue_mapping(skb);
@@ -1952,6 +1953,7 @@ static int ar9170_op_add_interface(struc
 				   struct ieee80211_if_init_conf *conf)
 {
 	struct ar9170 *ar = hw->priv;
+	struct ath_common *common = &ar->common;
 	int err = 0;
 
 	mutex_lock(&ar->mutex);
@@ -1962,7 +1964,7 @@ static int ar9170_op_add_interface(struc
 	}
 
 	ar->vif = conf->vif;
-	memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
+	memcpy(common->macaddr, conf->mac_addr, ETH_ALEN);
 
 	if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
 		ar->rx_software_decryption = true;
@@ -2131,12 +2133,13 @@ static void ar9170_op_bss_info_changed(s
 				       u32 changed)
 {
 	struct ar9170 *ar = hw->priv;
+	struct ath_common *common = &ar->common;
 	int err = 0;
 
 	mutex_lock(&ar->mutex);
 
 	if (changed & BSS_CHANGED_BSSID) {
-		memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
+		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
 		err = ar9170_set_operating_mode(ar);
 		if (err)
 			goto out;
@@ -2190,22 +2193,30 @@ static u64 ar9170_op_get_tsf(struct ieee
 {
 	struct ar9170 *ar = hw->priv;
 	int err;
-	u32 tsf_low;
-	u32 tsf_high;
 	u64 tsf;
+#define NR 3
+	static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
+				    AR9170_MAC_REG_TSF_L,
+				    AR9170_MAC_REG_TSF_H };
+	u32 val[NR];
+	int loops = 0;
 
 	mutex_lock(&ar->mutex);
-	err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
-	if (!err)
-		err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
+
+	while (loops++ < 10) {
+		err = ar9170_read_mreg(ar, NR, addr, val);
+		if (err || val[0] == val[2])
+			break;
+	}
+
 	mutex_unlock(&ar->mutex);
 
 	if (WARN_ON(err))
 		return 0;
-
-	tsf = tsf_high;
-	tsf = (tsf << 32) | tsf_low;
+	tsf = val[0];
+	tsf = (tsf << 32) | val[1];
 	return tsf;
+#undef NR
 }
 
 static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -2430,6 +2441,7 @@ static int ar9170_conf_tx(struct ieee802
 }
 
 static int ar9170_ampdu_action(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
 			       enum ieee80211_ampdu_mlme_action action,
 			       struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
@@ -2459,7 +2471,7 @@ static int ar9170_ampdu_action(struct ie
 		tid_info->state = AR9170_TID_STATE_PROGRESS;
 		tid_info->active = false;
 		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
-		ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		break;
 
 	case IEEE80211_AMPDU_TX_STOP:
@@ -2469,7 +2481,7 @@ static int ar9170_ampdu_action(struct ie
 		tid_info->active = false;
 		skb_queue_purge(&tid_info->queue);
 		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
-		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 		break;
 
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/phy.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -1239,9 +1239,6 @@ static u8 ar9170_get_max_edge_power(stru
 				    struct ar9170_calctl_edges edges[],
 				    u32 freq)
 {
-/* TODO: move somewhere else */
-#define AR5416_MAX_RATE_POWER        63
-
 	int i;
 	u8 rc = AR5416_MAX_RATE_POWER;
 	u8 f;
@@ -1259,10 +1256,11 @@ static u8 ar9170_get_max_edge_power(stru
 			break;
 		}
 		if (i > 0 && f < edges[i].channel) {
-			if (f > edges[i-1].channel &&
-			    edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
+			if (f > edges[i - 1].channel &&
+			    edges[i - 1].power_flags &
+			    AR9170_CALCTL_EDGE_FLAGS) {
 				/* lower channel has the inband flag set */
-				rc = edges[i-1].power_flags &
+				rc = edges[i - 1].power_flags &
 					~AR9170_CALCTL_EDGE_FLAGS;
 			}
 			break;
@@ -1270,18 +1268,48 @@ static u8 ar9170_get_max_edge_power(stru
 	}
 
 	if (i == AR5416_NUM_BAND_EDGES) {
-		if (f > edges[i-1].channel &&
-		    edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
+		if (f > edges[i - 1].channel &&
+		    edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
 			/* lower channel has the inband flag set */
-			rc = edges[i-1].power_flags &
+			rc = edges[i - 1].power_flags &
 				~AR9170_CALCTL_EDGE_FLAGS;
 		}
 	}
 	return rc;
 }
 
-/* calculate the conformance test limits and apply them to ar->power*
- * (derived from otus hal/hpmain.c, line 3706 ff.)
+static u8 ar9170_get_heavy_clip(struct ar9170 *ar,
+				struct ar9170_calctl_edges edges[],
+				u32 freq, enum ar9170_bw bw)
+{
+	u8 f;
+	int i;
+	u8 rc = 0;
+
+	if (freq < 3000)
+		f = freq - 2300;
+	else
+		f = (freq - 4800) / 5;
+
+	if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE)
+		rc |= 0xf0;
+
+	for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
+		if (edges[i].channel == 0xff)
+			break;
+		if (f == edges[i].channel) {
+			if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
+				rc |= 0x0f;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * calculate the conformance test limits and the heavy clip parameter
+ * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706)
  */
 static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
 {
@@ -1295,7 +1323,8 @@ static void ar9170_calc_ctl(struct ar917
 		int pwr_cal_len;
 	} *modes;
 
-	/* order is relevant in the mode_list_*: we fall back to the
+	/*
+	 * order is relevant in the mode_list_*: we fall back to the
 	 * lower indices if any mode is missed in the EEPROM.
 	 */
 	struct ctl_modes mode_list_2ghz[] = {
@@ -1313,7 +1342,10 @@ static void ar9170_calc_ctl(struct ar917
 
 #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
 
-	/* TODO: investigate the differences between OTUS'
+	ar->phy_heavy_clip = 0;
+
+	/*
+	 * TODO: investigate the differences between OTUS'
 	 * hpreg.c::zfHpGetRegulatoryDomain() and
 	 * ath/regd.c::ath_regd_get_band_ctl() -
 	 * e.g. for FCC3_WORLD the OTUS procedure
@@ -1347,6 +1379,15 @@ static void ar9170_calc_ctl(struct ar917
 		if (ctl_idx < AR5416_NUM_CTLS) {
 			int f_off = 0;
 
+			/* determine heav clip parameter from
+			   the 11G edges array */
+			if (modes[i].ctl_mode == CTL_11G) {
+				ar->phy_heavy_clip =
+					ar9170_get_heavy_clip(ar,
+							      EDGES(ctl_idx, 1),
+							      freq, bw);
+			}
+
 			/* adjust freq for 40MHz */
 			if (modes[i].ctl_mode == CTL_2GHT40 ||
 			    modes[i].ctl_mode == CTL_5GHT40) {
@@ -1360,13 +1401,15 @@ static void ar9170_calc_ctl(struct ar917
 				ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
 							  freq+f_off);
 
-			/* TODO: check if the regulatory max. power is
+			/*
+			 * TODO: check if the regulatory max. power is
 			 *  controlled by cfg80211 for DFS
 			 * (hpmain applies it to max_power itself for DFS freq)
 			 */
 
 		} else {
-			/* Workaround in otus driver, hpmain.c, line 3906:
+			/*
+			 * Workaround in otus driver, hpmain.c, line 3906:
 			 * if no data for 5GHT20 are found, take the
 			 * legacy 5G value.
 			 * We extend this here to fallback from any other *HT or
@@ -1390,6 +1433,19 @@ static void ar9170_calc_ctl(struct ar917
 						       modes[i].max_power);
 		}
 	}
+
+	if (ar->phy_heavy_clip & 0xf0) {
+		ar->power_2G_ht40[0]--;
+		ar->power_2G_ht40[1]--;
+		ar->power_2G_ht40[2]--;
+	}
+	if (ar->phy_heavy_clip & 0xf) {
+		ar->power_2G_ht20[0]++;
+		ar->power_2G_ht20[1]++;
+		ar->power_2G_ht20[2]++;
+	}
+
+
 #undef EDGES
 }
 
@@ -1499,8 +1555,6 @@ static int ar9170_set_power_cal(struct a
 	/* calc. conformance test limits and apply to ar->power*[] */
 	ar9170_calc_ctl(ar, freq, bw);
 
-	/* TODO: (heavy clip) regulatory domain power level fine-tuning. */
-
 	/* set ACK/CTS TX power */
 	ar9170_regwrite_begin(ar);
 
@@ -1643,6 +1697,17 @@ int ar9170_set_channel(struct ar9170 *ar
 	if (err)
 		return err;
 
+	if (ar->phy_heavy_clip) {
+		err = ar9170_write_reg(ar, 0x1c59e0,
+				       0x200 | ar->phy_heavy_clip);
+		if (err) {
+			if (ar9170_nag_limiter(ar))
+				printk(KERN_ERR "%s: failed to set "
+				       "heavy clip\n",
+				       wiphy_name(ar->hw->wiphy));
+		}
+	}
+
 	for (i = 0; i < 2; i++) {
 		ar->noise[i] = ar9170_calc_noise_dbm(
 				(le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,8 +68,10 @@ static struct usb_device_id ar9170_usb_i
 	{ USB_DEVICE(0x0cf3, 0x1002) },
 	/* Cace Airpcap NX */
 	{ USB_DEVICE(0xcace, 0x0300) },
-	/* D-Link DWA 160A */
+	/* D-Link DWA 160 A1 */
 	{ USB_DEVICE(0x07d1, 0x3c10) },
+	/* D-Link DWA 160 A2 */
+	{ USB_DEVICE(0x07d1, 0x3a09) },
 	/* Netgear WNDA3100 */
 	{ USB_DEVICE(0x0846, 0x9010) },
 	/* Netgear WN111 v2 */
@@ -108,15 +110,15 @@ static void ar9170_usb_submit_urb(struct
 		return ;
 
 	spin_lock_irqsave(&aru->tx_urb_lock, flags);
-	if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) {
+	if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
 		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
 		return ;
 	}
-	aru->tx_submitted_urbs++;
+	atomic_inc(&aru->tx_submitted_urbs);
 
 	urb = usb_get_from_anchor(&aru->tx_pending);
 	if (!urb) {
-		aru->tx_submitted_urbs--;
+		atomic_dec(&aru->tx_submitted_urbs);
 		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
 
 		return ;
@@ -133,7 +135,7 @@ static void ar9170_usb_submit_urb(struct
 				err);
 
 		usb_unanchor_urb(urb);
-		aru->tx_submitted_urbs--;
+		atomic_dec(&aru->tx_submitted_urbs);
 		ar9170_tx_callback(&aru->common, urb->context);
 	}
 
@@ -151,7 +153,7 @@ static void ar9170_usb_tx_urb_complete_f
 		return ;
 	}
 
-	aru->tx_submitted_urbs--;
+	atomic_dec(&aru->tx_submitted_urbs);
 
 	ar9170_tx_callback(&aru->common, skb);
 
@@ -794,7 +796,7 @@ static int ar9170_usb_probe(struct usb_i
 	spin_lock_init(&aru->tx_urb_lock);
 
 	aru->tx_pending_urbs = 0;
-	aru->tx_submitted_urbs = 0;
+	atomic_set(&aru->tx_submitted_urbs, 0);
 
 	aru->common.stop = ar9170_usb_stop;
 	aru->common.flush = ar9170_usb_flush;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/usb.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ar9170/usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ar9170/usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,7 @@ struct ar9170_usb {
 	bool req_one_stage_fw;
 
 	spinlock_t tx_urb_lock;
-	unsigned int tx_submitted_urbs;
+	atomic_t tx_submitted_urbs;
 	unsigned int tx_pending_urbs;
 
 	struct completion cmd_wait;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/ath5k.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
  * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
  * and clean up common bits, then introduce set/get functions in eeprom.c */
 #include "eeprom.h"
+#include "../ath.h"
 
 /* PCI IDs */
 #define PCI_DEVICE_ID_ATHEROS_AR5210 		0x0007 /* AR5210 */
@@ -165,13 +166,6 @@
 #define AR5K_INI_VAL_XR			0
 #define AR5K_INI_VAL_MAX		5
 
-/* Used for BSSID etc manipulation */
-#define AR5K_LOW_ID(_a)(				\
-(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24	\
-)
-
-#define AR5K_HIGH_ID(_a)	((_a)[4] | (_a)[5] << 8)
-
 /*
  * Some tuneable values (these should be changeable by the user)
  * TODO: Make use of them and add more options OR use debug/configfs
@@ -204,6 +198,7 @@
 #define AR5K_TUNE_CWMAX_11B			1023
 #define AR5K_TUNE_CWMAX_XR			7
 #define AR5K_TUNE_NOISE_FLOOR			-72
+#define AR5K_TUNE_CCA_MAX_GOOD_VALUE		-95
 #define AR5K_TUNE_MAX_TXPOWER			63
 #define AR5K_TUNE_DEFAULT_TXPOWER		25
 #define AR5K_TUNE_TPC_TXPOWER			false
@@ -1012,6 +1007,14 @@ struct ath5k_capabilities {
 	} cap_queues;
 };
 
+/* size of noise floor history (keep it a power of two) */
+#define ATH5K_NF_CAL_HIST_MAX	8
+struct ath5k_nfcal_hist
+{
+	s16 index;				/* current index into nfval */
+	s16 nfval[ATH5K_NF_CAL_HIST_MAX];	/* last few noise floors */
+};
+
 
 /***************************************\
   HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1027,6 +1030,7 @@ struct ath5k_capabilities {
 /* TODO: Clean up and merge with ath5k_softc */
 struct ath5k_hw {
 	u32			ah_magic;
+	struct ath_common       common;
 
 	struct ath5k_softc	*ah_sc;
 	void __iomem		*ah_iobase;
@@ -1067,14 +1071,6 @@ struct ath5k_hw {
 	u8			ah_def_ant;
 	bool			ah_software_retry;
 
-	u8			ah_sta_id[ETH_ALEN];
-
-	/* Current BSSID we are trying to assoc to / create.
-	 * This is passed by mac80211 on config_interface() and cached here for
-	 * use in resets */
-	u8			ah_bssid[ETH_ALEN];
-	u8			ah_bssid_mask[ETH_ALEN];
-
 	int			ah_gpio_npins;
 
 	struct ath5k_capabilities ah_capabilities;
@@ -1125,6 +1121,8 @@ struct ath5k_hw {
 		struct ieee80211_channel r_last_channel;
 	} ah_radar;
 
+	struct ath5k_nfcal_hist ah_nfcal_hist;
+
 	/* noise floor from last periodic calibration */
 	s32			ah_noise_floor;
 
@@ -1160,7 +1158,7 @@ struct ath5k_hw {
  */
 
 /* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc);
+extern int ath5k_hw_attach(struct ath5k_softc *sc);
 extern void ath5k_hw_detach(struct ath5k_hw *ah);
 
 /* LED functions */
@@ -1203,10 +1201,9 @@ extern bool ath5k_eeprom_is_hb63(struct
 /* Protocol Control Unit Functions */
 extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
 /* BSSID Functions */
-extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
 extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
+extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
+extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
 /* Receive start/stop functions */
 extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
 extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
@@ -1288,8 +1285,10 @@ extern int ath5k_hw_rfgain_opt_init(stru
 extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
 extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
 /* PHY calibration */
+void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
 extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
 extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
 extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
 /* Spur mitigation */
 bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
@@ -1329,17 +1328,21 @@ static inline unsigned int ath5k_hw_cloc
 	return turbo ? (clock / 80) : (clock / 40);
 }
 
-/*
- * Read from a register
- */
+static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
+{
+        return &ah->common;
+}
+
+static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
+{
+        return &(ath5k_hw_common(ah)->regulatory);
+}
+
 static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
 {
 	return ioread32(ah->ah_iobase + reg);
 }
 
-/*
- * Write to a register
- */
 static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
 {
 	iowrite32(val, ah->ah_iobase + reg);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/attach.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/attach.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/attach.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/attach.c	2010-02-24 13:52:17.000000000 -0500
@@ -101,25 +101,15 @@ static int ath5k_hw_post(struct ath5k_hw
  * -ENODEV if the device is not supported or prints an error msg if something
  * else went wrong.
  */
-struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
+int ath5k_hw_attach(struct ath5k_softc *sc)
 {
-	struct ath5k_hw *ah;
+	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	struct pci_dev *pdev = sc->pdev;
 	struct ath5k_eeprom_info *ee;
 	int ret;
 	u32 srev;
 
-	/*If we passed the test malloc a ath5k_hw struct*/
-	ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
-	if (ah == NULL) {
-		ret = -ENOMEM;
-		ATH5K_ERR(sc, "out of memory\n");
-		goto err;
-	}
-
-	ah->ah_sc = sc;
-	ah->ah_iobase = sc->iobase;
-
 	/*
 	 * HW information
 	 */
@@ -278,12 +268,12 @@ struct ath5k_hw *ath5k_hw_attach(struct
 		goto err_free;
 	}
 
+	ee = &ah->ah_capabilities.cap_eeprom;
+
 	/*
 	 * Write PCI-E power save settings
 	 */
 	if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-		struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-
 		ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
 		ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
 
@@ -321,7 +311,6 @@ struct ath5k_hw *ath5k_hw_attach(struct
 	}
 
 	/* Crypto settings */
-	ee = &ah->ah_capabilities.cap_eeprom;
 	ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
 		(ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
 		 !AR5K_EEPROM_AES_DIS(ee->ee_misc5));
@@ -336,20 +325,21 @@ struct ath5k_hw *ath5k_hw_attach(struct
 	ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
 
 	/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
-	memset(ah->ah_bssid, 0xff, ETH_ALEN);
-	ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+	memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
+	ath5k_hw_set_associd(ah);
 	ath5k_hw_set_opmode(ah);
 
 	ath5k_hw_rfgain_opt_init(ah);
 
+	ath5k_hw_init_nfcal_hist(ah);
+
 	/* turn on HW LEDs */
 	ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
 
-	return ah;
+	return 0;
 err_free:
 	kfree(ah);
-err:
-	return ERR_PTR(ret);
+	return ret;
 }
 
 /**
@@ -369,5 +359,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah
 	ath5k_eeprom_detach(ah);
 
 	/* assume interrupts are down */
-	kfree(ah);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/base.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.c	2010-02-24 13:52:17.000000000 -0500
@@ -195,12 +195,13 @@ static int __devinit	ath5k_pci_probe(str
 				const struct pci_device_id *id);
 static void __devexit	ath5k_pci_remove(struct pci_dev *pdev);
 #ifdef CONFIG_PM
-static int		ath5k_pci_suspend(struct pci_dev *pdev,
-					pm_message_t state);
-static int		ath5k_pci_resume(struct pci_dev *pdev);
+static int		ath5k_pci_suspend(struct device *dev);
+static int		ath5k_pci_resume(struct device *dev);
+
+SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
+#define ATH5K_PM_OPS	(&ath5k_pm_ops)
 #else
-#define ath5k_pci_suspend NULL
-#define ath5k_pci_resume NULL
+#define ATH5K_PM_OPS	NULL
 #endif /* CONFIG_PM */
 
 static struct pci_driver ath5k_pci_driver = {
@@ -208,8 +209,7 @@ static struct pci_driver ath5k_pci_drive
 	.id_table	= ath5k_pci_id_table,
 	.probe		= ath5k_pci_probe,
 	.remove		= __devexit_p(ath5k_pci_remove),
-	.suspend	= ath5k_pci_suspend,
-	.resume		= ath5k_pci_resume,
+	.driver.pm	= ATH5K_PM_OPS,
 };
 
 
@@ -323,10 +323,13 @@ static inline void ath5k_txbuf_free(stru
 static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
 				struct ath5k_buf *bf)
 {
+	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
+
 	BUG_ON(!bf);
 	if (!bf->skb)
 		return;
-	pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+	pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
 			PCI_DMA_FROMDEVICE);
 	dev_kfree_skb_any(bf->skb);
 	bf->skb = NULL;
@@ -437,6 +440,22 @@ ath5k_chip_name(enum ath5k_srev_type typ
 
 	return name;
 }
+static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
+{
+	struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+	return ath5k_hw_reg_read(ah, reg_offset);
+}
+
+static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
+{
+	struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+	ath5k_hw_reg_write(ah, val, reg_offset);
+}
+
+static const struct ath_ops ath5k_common_ops = {
+	.read = ath5k_ioread32,
+	.write = ath5k_iowrite32,
+};
 
 static int __devinit
 ath5k_pci_probe(struct pci_dev *pdev,
@@ -444,6 +463,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 {
 	void __iomem *mem;
 	struct ath5k_softc *sc;
+	struct ath_common *common;
 	struct ieee80211_hw *hw;
 	int ret;
 	u8 csz;
@@ -547,7 +567,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	__set_bit(ATH_STAT_INVALID, sc->status);
 
 	sc->iobase = mem; /* So we can unmap it on detach */
-	sc->common.cachelsz = csz << 2; /* convert to bytes */
 	sc->opmode = NL80211_IFTYPE_STATION;
 	sc->bintval = 1000;
 	mutex_init(&sc->lock);
@@ -565,13 +584,28 @@ ath5k_pci_probe(struct pci_dev *pdev,
 		goto err_free;
 	}
 
-	/* Initialize device */
-	sc->ah = ath5k_hw_attach(sc);
-	if (IS_ERR(sc->ah)) {
-		ret = PTR_ERR(sc->ah);
+	/*If we passed the test malloc a ath5k_hw struct*/
+	sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+	if (!sc->ah) {
+		ret = -ENOMEM;
+		ATH5K_ERR(sc, "out of memory\n");
 		goto err_irq;
 	}
 
+	sc->ah->ah_sc = sc;
+	sc->ah->ah_iobase = sc->iobase;
+	common = ath5k_hw_common(sc->ah);
+	common->ops = &ath5k_common_ops;
+	common->ah = sc->ah;
+	common->hw = hw;
+	common->cachelsz = csz << 2; /* convert to bytes */
+
+	/* Initialize device */
+	ret = ath5k_hw_attach(sc);
+	if (ret) {
+		goto err_free_ah;
+	}
+
 	/* set up multi-rate retry capabilities */
 	if (sc->ah->ah_version == AR5K_AR5212) {
 		hw->max_rates = 4;
@@ -640,6 +674,8 @@ err_ah:
 	ath5k_hw_detach(sc->ah);
 err_irq:
 	free_irq(pdev->irq, sc);
+err_free_ah:
+	kfree(sc->ah);
 err_free:
 	ieee80211_free_hw(hw);
 err_map:
@@ -661,6 +697,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
 	ath5k_debug_finish_device(sc);
 	ath5k_detach(pdev, hw);
 	ath5k_hw_detach(sc->ah);
+	kfree(sc->ah);
 	free_irq(pdev->irq, sc);
 	pci_iounmap(pdev, sc->iobase);
 	pci_release_region(pdev, 0);
@@ -669,33 +706,20 @@ ath5k_pci_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
-static int
-ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ath5k_pci_suspend(struct device *dev)
 {
-	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
 	struct ath5k_softc *sc = hw->priv;
 
 	ath5k_led_off(sc);
-
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, PCI_D3hot);
-
 	return 0;
 }
 
-static int
-ath5k_pci_resume(struct pci_dev *pdev)
+static int ath5k_pci_resume(struct device *dev)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 	struct ath5k_softc *sc = hw->priv;
-	int err;
-
-	pci_restore_state(pdev);
-
-	err = pci_enable_device(pdev);
-	if (err)
-		return err;
 
 	/*
 	 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -718,7 +742,7 @@ static int ath5k_reg_notifier(struct wip
 {
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct ath5k_softc *sc = hw->priv;
-	struct ath_regulatory *regulatory = &sc->common.regulatory;
+	struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
 
 	return ath_reg_notifier_apply(wiphy, request, regulatory);
 }
@@ -728,7 +752,7 @@ ath5k_attach(struct pci_dev *pdev, struc
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
-	struct ath_regulatory *regulatory = &sc->common.regulatory;
+	struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
 	u8 mac[ETH_ALEN] = {};
 	int ret;
 
@@ -815,7 +839,7 @@ ath5k_attach(struct pci_dev *pdev, struc
 
 	SET_IEEE80211_PERM_ADDR(hw, mac);
 	/* All MAC address bits matter for ACKs */
-	memset(sc->bssidmask, 0xff, ETH_ALEN);
+	memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
 	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 
 	regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
@@ -1152,24 +1176,26 @@ ath5k_hw_to_driver_rix(struct ath5k_soft
 static
 struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
 {
+	struct ath_common *common = ath5k_hw_common(sc->ah);
 	struct sk_buff *skb;
 
 	/*
 	 * Allocate buffer with headroom_needed space for the
 	 * fake physical layer header at the start.
 	 */
-	skb = ath_rxbuf_alloc(&sc->common,
-			      sc->rxbufsize + sc->common.cachelsz - 1,
+	skb = ath_rxbuf_alloc(common,
+			      common->rx_bufsize,
 			      GFP_ATOMIC);
 
 	if (!skb) {
 		ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
-				sc->rxbufsize + sc->common.cachelsz - 1);
+				common->rx_bufsize);
 		return NULL;
 	}
 
 	*skb_addr = pci_map_single(sc->pdev,
-		skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+				   skb->data, common->rx_bufsize,
+				   PCI_DMA_FROMDEVICE);
 	if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
 		ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
 		dev_kfree_skb(skb);
@@ -1605,13 +1631,14 @@ static int
 ath5k_rx_start(struct ath5k_softc *sc)
 {
 	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	struct ath5k_buf *bf;
 	int ret;
 
-	sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
+	common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
 
-	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
-		sc->common.cachelsz, sc->rxbufsize);
+	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
+		  common->cachelsz, common->rx_bufsize);
 
 	spin_lock_bh(&sc->rxbuflock);
 	sc->rxlink = NULL;
@@ -1656,6 +1683,8 @@ static unsigned int
 ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
 		struct sk_buff *skb, struct ath5k_rx_status *rs)
 {
+	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	struct ieee80211_hdr *hdr = (void *)skb->data;
 	unsigned int keyix, hlen;
 
@@ -1672,7 +1701,7 @@ ath5k_rx_decrypted(struct ath5k_softc *s
 	    skb->len >= hlen + 4) {
 		keyix = skb->data[hlen + 3] >> 6;
 
-		if (test_bit(keyix, sc->keymap))
+		if (test_bit(keyix, common->keymap))
 			return RX_FLAG_DECRYPTED;
 	}
 
@@ -1684,13 +1713,14 @@ static void
 ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
 		     struct ieee80211_rx_status *rxs)
 {
+	struct ath_common *common = ath5k_hw_common(sc->ah);
 	u64 tsf, bc_tstamp;
 	u32 hw_tu;
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
 
 	if (ieee80211_is_beacon(mgmt->frame_control) &&
 	    le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
-	    memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
+	    memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
 		/*
 		 * Received an IBSS beacon with the same BSSID. Hardware *must*
 		 * have updated the local TSF. We have to work around various
@@ -1745,6 +1775,8 @@ ath5k_tasklet_rx(unsigned long data)
 	struct sk_buff *skb, *next_skb;
 	dma_addr_t next_skb_addr;
 	struct ath5k_softc *sc = (void *)data;
+	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	struct ath5k_buf *bf;
 	struct ath5k_desc *ds;
 	int ret;
@@ -1822,7 +1854,7 @@ accept:
 		if (!next_skb)
 			goto next;
 
-		pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+		pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
 				PCI_DMA_FROMDEVICE);
 		skb_put(skb, rs.rs_datalen);
 
@@ -1871,17 +1903,6 @@ accept:
 		rxs->noise = sc->ah->ah_noise_floor;
 		rxs->signal = rxs->noise + rs.rs_rssi;
 
-		/* An rssi of 35 indicates you should be able use
-		 * 54 Mbps reliably. A more elaborate scheme can be used
-		 * here but it requires a map of SNR/throughput for each
-		 * possible mode used */
-		rxs->qual = rs.rs_rssi * 100 / 35;
-
-		/* rssi can be more than 35 though, anything above that
-		 * should be considered at 100% */
-		if (rxs->qual > 100)
-			rxs->qual = 100;
-
 		rxs->antenna = rs.rs_antenna;
 		rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
 		rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
@@ -2349,6 +2370,9 @@ ath5k_init(struct ath5k_softc *sc)
 	 */
 	ath5k_stop_locked(sc);
 
+	/* Set PHY calibration interval */
+	ah->ah_cal_intval = ath5k_calinterval;
+
 	/*
 	 * The basic interface to setting the hardware in a good
 	 * state is ``reset''.  On return the hardware is known to
@@ -2376,10 +2400,6 @@ ath5k_init(struct ath5k_softc *sc)
 
 	/* Set ack to be sent at low bit-rates */
 	ath5k_hw_set_ack_bitrate_high(ah, false);
-
-	/* Set PHY calibration inteval */
-	ah->ah_cal_intval = ath5k_calinterval;
-
 	ret = 0;
 done:
 	mmiowb();
@@ -3008,6 +3028,8 @@ ath5k_set_key(struct ieee80211_hw *hw, e
 	      struct ieee80211_key_conf *key)
 {
 	struct ath5k_softc *sc = hw->priv;
+	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	int ret = 0;
 
 	if (modparam_nohwcrypt)
@@ -3040,14 +3062,14 @@ ath5k_set_key(struct ieee80211_hw *hw, e
 			ATH5K_ERR(sc, "can't set the key\n");
 			goto unlock;
 		}
-		__set_bit(key->keyidx, sc->keymap);
+		__set_bit(key->keyidx, common->keymap);
 		key->hw_key_idx = key->keyidx;
 		key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
 			       IEEE80211_KEY_FLAG_GENERATE_MMIC);
 		break;
 	case DISABLE_KEY:
 		ath5k_hw_reset_key(sc->ah, key->keyidx);
-		__clear_bit(key->keyidx, sc->keymap);
+		__clear_bit(key->keyidx, common->keymap);
 		break;
 	default:
 		ret = -EINVAL;
@@ -3176,6 +3198,7 @@ static void ath5k_bss_info_changed(struc
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	unsigned long flags;
 
 	mutex_lock(&sc->lock);
@@ -3184,10 +3207,9 @@ static void ath5k_bss_info_changed(struc
 
 	if (changes & BSS_CHANGED_BSSID) {
 		/* Cache for later use during resets */
-		memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
-		/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
-		 * a clean way of letting us retrieve this yet. */
-		ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+		common->curaid = 0;
+		ath5k_hw_set_associd(ah);
 		mmiowb();
 	}
 
@@ -3200,6 +3222,14 @@ static void ath5k_bss_info_changed(struc
 			set_beacon_filter(hw, sc->assoc);
 		ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
 			AR5K_LED_ASSOC : AR5K_LED_INIT);
+		if (bss_conf->assoc) {
+			ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+				  "Bss Info ASSOC %d, bssid: %pM\n",
+				  bss_conf->aid, common->curbssid);
+			common->curaid = bss_conf->aid;
+			ath5k_hw_set_associd(ah);
+			/* Once ANI is available you would start it here */
+		}
 	}
 
 	if (changes & BSS_CHANGED_BEACON) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/base.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/base.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,7 +36,7 @@
  */
 
 /*
- * Defintions for the Atheros Wireless LAN controller driver.
+ * Definitions for the Atheros Wireless LAN controller driver.
  */
 #ifndef _DEV_ATH_ATHVAR_H
 #define _DEV_ATH_ATHVAR_H
@@ -115,7 +115,6 @@ struct ath5k_rfkill {
  * associated with an instance of a device */
 struct ath5k_softc {
 	struct pci_dev		*pdev;		/* for dma mapping */
-	struct ath_common	common;
 	void __iomem		*iobase;	/* address of the device */
 	struct mutex		lock;		/* dev-level lock */
 	struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
@@ -154,8 +153,6 @@ struct ath5k_softc {
 
 	enum ath5k_int		imask;		/* interrupt mask copy */
 
-	DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
-
 	u8			bssidmask[ETH_ALEN];
 
 	unsigned int		led_pin,	/* GPIO pin for driving LED */
@@ -193,7 +190,7 @@ struct ath5k_softc {
 	struct ath5k_txq	*cabq;		/* content after beacon */
 
 	int 			power_level;	/* Requested tx power in dbm */
-	bool			assoc;		/* assocate state */
+	bool			assoc;		/* associate state */
 	bool			enable_beacon;	/* true if beacons are on */
 };
 
@@ -202,15 +199,4 @@ struct ath5k_softc {
 #define ath5k_hw_hasveol(_ah) \
 	(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
 
-static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
-{
-	return &ah->ah_sc->common;
-}
-
-static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
-{
-	return &(ath5k_hw_common(ah)->regulatory);
-
-}
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,6 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	int ret;
 	u16 val;
+	u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
 
 	/*
 	 * Read values from EEPROM and store them in the capability structure
@@ -111,20 +112,44 @@ ath5k_eeprom_init_header(struct ath5k_hw
 	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
 		return 0;
 
-#ifdef notyet
 	/*
 	 * Validate the checksum of the EEPROM date. There are some
 	 * devices with invalid EEPROMs.
 	 */
-	for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
+	AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
+	if (val) {
+		eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
+			   AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
+		AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
+		eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
+
+		/*
+		 * Fail safe check to prevent stupid loops due
+		 * to busted EEPROMs. XXX: This value is likely too
+		 * big still, waiting on a better value.
+		 */
+		if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
+			ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
+				  "%d (0x%04x) max expected: %d (0x%04x)\n",
+				  eep_max, eep_max,
+				  3 * AR5K_EEPROM_INFO_MAX,
+				  3 * AR5K_EEPROM_INFO_MAX);
+			return -EIO;
+		}
+	}
+
+	for (cksum = 0, offset = 0; offset < eep_max; offset++) {
 		AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
 		cksum ^= val;
 	}
 	if (cksum != AR5K_EEPROM_INFO_CKSUM) {
-		ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
+		ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
+			  "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
+			  cksum, eep_max,
+			  eep_max == AR5K_EEPROM_INFO_MAX ?
+				"default size" : "custom size");
 		return -EIO;
 	}
-#endif
 
 	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
 	    ee_ant_gain);
@@ -1492,7 +1517,7 @@ ath5k_eeprom_read_target_rate_pwr_info(s
  * This info is used to calibrate the baseband power table. Imagine
  * that for each channel there is a power curve that's hw specific
  * (depends on amplifier etc) and we try to "correct" this curve using
- * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * offsets we pass on to phy chip (baseband -> before amplifier) so that
  * it can use accurate power values when setting tx power (takes amplifier's
  * performance on each channel into account).
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/eeprom.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/eeprom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/eeprom.h	2010-02-24 13:52:17.000000000 -0500
@@ -37,6 +37,14 @@
 #define AR5K_EEPROM_RFKILL_POLARITY_S	1
 
 #define AR5K_EEPROM_REG_DOMAIN		0x00bf	/* EEPROM regdom */
+
+/* FLASH(EEPROM) Defines for AR531X chips */
+#define AR5K_EEPROM_SIZE_LOWER		0x1b /* size info -- lower */
+#define AR5K_EEPROM_SIZE_UPPER		0x1c /* size info -- upper */
+#define AR5K_EEPROM_SIZE_UPPER_MASK	0xfff0
+#define AR5K_EEPROM_SIZE_UPPER_SHIFT	4
+#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT	12
+
 #define AR5K_EEPROM_CHECKSUM		0x00c0	/* EEPROM checksum */
 #define AR5K_EEPROM_INFO_BASE		0x00c0	/* EEPROM header */
 #define AR5K_EEPROM_INFO_MAX		(0x400 - AR5K_EEPROM_INFO_BASE)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/initvals.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/initvals.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/initvals.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/initvals.c	2010-02-24 13:52:17.000000000 -0500
@@ -560,8 +560,8 @@ static const struct ath5k_ini ar5212_ini
 	{ AR5K_SLEEP0,		0x0002aaaa },
 	{ AR5K_SLEEP1,		0x02005555 },
 	{ AR5K_SLEEP2,		0x00000000 },
-	{ AR5K_BSS_IDM0,	0xffffffff },
-	{ AR5K_BSS_IDM1,	0x0000ffff },
+	{ AR_BSSMSKL,		0xffffffff },
+	{ AR_BSSMSKU,		0x0000ffff },
 	{ AR5K_TXPC,		0x00000000 },
 	{ AR5K_PROFCNT_TX,	0x00000000 },
 	{ AR5K_PROFCNT_RX,	0x00000000 },
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config ATH5K
 	tristate "Atheros 5xxx wireless cards support"
-	depends on PCI && MAC80211 && WLAN_80211
+	depends on PCI && MAC80211
 	select MAC80211_LEDS
 	select LEDS_CLASS
 	select NEW_LEDS
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/led.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/led.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/led.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/led.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,8 @@ static const struct pci_device_id ath5k_
 	{ ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
 	/* Acer Aspire One A150 (maximlevitsky@gmail.com) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
+	/* Acer Aspire One AO531h AO751h (keng-yu.lin@canonical.com) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe00d), ATH_LED(3, 0) },
 	/* Acer Ferrari 5000 (russ.dill@gmail.com) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
 	/* E-machines E510 (tuliom@gmail.com) */
@@ -77,6 +79,8 @@ static const struct pci_device_id ath5k_
 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
 	/* IBM-specific AR5212 (all others) */
 	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+	/* Dell Vostro A860 (shahar@shahar-or.co.il) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0112), ATH_LED(3, 0) },
 	{ }
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/pcu.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/pcu.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/pcu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/pcu.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,8 @@
 * Protocol Control Unit Functions *
 \*********************************/
 
+#include <asm/unaligned.h>
+
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
@@ -44,6 +46,7 @@
  */
 int ath5k_hw_set_opmode(struct ath5k_hw *ah)
 {
+	struct ath_common *common = ath5k_hw_common(ah);
 	u32 pcu_reg, beacon_reg, low_id, high_id;
 
 
@@ -95,8 +98,8 @@ int ath5k_hw_set_opmode(struct ath5k_hw
 	/*
 	 * Set PCU registers
 	 */
-	low_id = AR5K_LOW_ID(ah->ah_sta_id);
-	high_id = AR5K_HIGH_ID(ah->ah_sta_id);
+	low_id = get_unaligned_le32(common->macaddr);
+	high_id = get_unaligned_le16(common->macaddr + 4);
 	ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
 	ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
 
@@ -238,28 +241,6 @@ int ath5k_hw_set_cts_timeout(struct ath5
 	return 0;
 }
 
-
-/****************\
-* BSSID handling *
-\****************/
-
-/**
- * ath5k_hw_get_lladdr - Get station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Initialize ah->ah_sta_id using the mac address provided
- * (just a memcpy).
- *
- * TODO: Remove it once we merge ath5k_softc and ath5k_hw
- */
-void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
-{
-	ATH5K_TRACE(ah->ah_sc);
-	memcpy(mac, ah->ah_sta_id, ETH_ALEN);
-}
-
 /**
  * ath5k_hw_set_lladdr - Set station id
  *
@@ -270,17 +251,18 @@ void ath5k_hw_get_lladdr(struct ath5k_hw
  */
 int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
 {
+	struct ath_common *common = ath5k_hw_common(ah);
 	u32 low_id, high_id;
 	u32 pcu_reg;
 
 	ATH5K_TRACE(ah->ah_sc);
 	/* Set new station ID */
-	memcpy(ah->ah_sta_id, mac, ETH_ALEN);
+	memcpy(common->macaddr, mac, ETH_ALEN);
 
 	pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
 
-	low_id = AR5K_LOW_ID(mac);
-	high_id = AR5K_HIGH_ID(mac);
+	low_id = get_unaligned_le32(mac);
+	high_id = get_unaligned_le16(mac + 4);
 
 	ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
 	ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
@@ -297,159 +279,51 @@ int ath5k_hw_set_lladdr(struct ath5k_hw
  *
  * Sets the BSSID which trigers the "SME Join" operation
  */
-void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
+void ath5k_hw_set_associd(struct ath5k_hw *ah)
 {
-	u32 low_id, high_id;
+	struct ath_common *common = ath5k_hw_common(ah);
 	u16 tim_offset = 0;
 
 	/*
 	 * Set simple BSSID mask on 5212
 	 */
-	if (ah->ah_version == AR5K_AR5212) {
-		ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
-							AR5K_BSS_IDM0);
-		ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
-							AR5K_BSS_IDM1);
-	}
+	if (ah->ah_version == AR5K_AR5212)
+		ath_hw_setbssidmask(common);
 
 	/*
 	 * Set BSSID which triggers the "SME Join" operation
 	 */
-	low_id = AR5K_LOW_ID(bssid);
-	high_id = AR5K_HIGH_ID(bssid);
-	ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
-	ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
-				AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
+	ath5k_hw_reg_write(ah,
+			   get_unaligned_le32(common->curbssid),
+			   AR5K_BSS_ID0);
+	ath5k_hw_reg_write(ah,
+			   get_unaligned_le16(common->curbssid + 4) |
+			   ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
+			   AR5K_BSS_ID1);
 
-	if (assoc_id == 0) {
+	if (common->curaid == 0) {
 		ath5k_hw_disable_pspoll(ah);
 		return;
 	}
 
 	AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
-			tim_offset ? tim_offset + 4 : 0);
+			    tim_offset ? tim_offset + 4 : 0);
 
 	ath5k_hw_enable_pspoll(ah, NULL, 0);
 }
 
-/**
- * ath5k_hw_set_bssid_mask - filter out bssids we listen
- *
- * @ah: the &struct ath5k_hw
- * @mask: the bssid_mask, a u8 array of size ETH_ALEN
- *
- * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
- * which bits of the interface's MAC address should be looked at when trying
- * to decide which packets to ACK. In station mode and AP mode with a single
- * BSS every bit matters since we lock to only one BSS. In AP mode with
- * multiple BSSes (virtual interfaces) not every bit matters because hw must
- * accept frames for all BSSes and so we tweak some bits of our mac address
- * in order to have multiple BSSes.
- *
- * NOTE: This is a simple filter and does *not* filter out all
- * relevant frames. Some frames that are not for us might get ACKed from us
- * by PCU because they just match the mask.
- *
- * When handling multiple BSSes you can get the BSSID mask by computing the
- * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
- *
- * When you do this you are essentially computing the common bits of all your
- * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
- * the MAC address to obtain the relevant bits and compare the result with
- * (frame's BSSID & mask) to see if they match.
- */
-/*
- * Simple example: on your card you have have two BSSes you have created with
- * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
- * There is another BSSID-03 but you are not part of it. For simplicity's sake,
- * assuming only 4 bits for a mac address and for BSSIDs you can then have:
- *
- *                  \
- * MAC:                0001 |
- * BSSID-01:   0100 | --> Belongs to us
- * BSSID-02:   1001 |
- *                  /
- * -------------------
- * BSSID-03:   0110  | --> External
- * -------------------
- *
- * Our bssid_mask would then be:
- *
- *             On loop iteration for BSSID-01:
- *             ~(0001 ^ 0100)  -> ~(0101)
- *                             ->   1010
- *             bssid_mask      =    1010
- *
- *             On loop iteration for BSSID-02:
- *             bssid_mask &= ~(0001   ^   1001)
- *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
- *             bssid_mask =   (1010)  & ~(1001)
- *             bssid_mask =   (1010)  &  (0110)
- *             bssid_mask =   0010
- *
- * A bssid_mask of 0010 means "only pay attention to the second least
- * significant bit". This is because its the only bit common
- * amongst the MAC and all BSSIDs we support. To findout what the real
- * common bit is we can simply "&" the bssid_mask now with any BSSID we have
- * or our MAC address (we assume the hardware uses the MAC address).
- *
- * Now, suppose there's an incoming frame for BSSID-03:
- *
- * IFRAME-01:  0110
- *
- * An easy eye-inspeciton of this already should tell you that this frame
- * will not pass our check. This is beacuse the bssid_mask tells the
- * hardware to only look at the second least significant bit and the
- * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
- * as 1, which does not match 0.
- *
- * So with IFRAME-01 we *assume* the hardware will do:
- *
- *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
- *  --> allow = (0010) == 0000 ? 1 : 0;
- *  --> allow = 0
- *
- *  Lets now test a frame that should work:
- *
- * IFRAME-02:  0001 (we should allow)
- *
- *     allow = (0001 & 1010) == 1010
- *
- *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
- *  --> allow = (0010) == (0010)
- *  --> allow = 1
- *
- * Other examples:
- *
- * IFRAME-03:  0100 --> allowed
- * IFRAME-04:  1001 --> allowed
- * IFRAME-05:  1101 --> allowed but its not for us!!!
- *
- */
-int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
+void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
 {
-	u32 low_id, high_id;
+	struct ath_common *common = ath5k_hw_common(ah);
 	ATH5K_TRACE(ah->ah_sc);
 
 	/* Cache bssid mask so that we can restore it
 	 * on reset */
-	memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
-	if (ah->ah_version == AR5K_AR5212) {
-		low_id = AR5K_LOW_ID(mask);
-		high_id = AR5K_HIGH_ID(mask);
-
-		ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
-		ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
-
-		return 0;
-	}
-
-	return -EIO;
+	memcpy(common->bssidmask, mask, ETH_ALEN);
+	if (ah->ah_version == AR5K_AR5212)
+		ath_hw_setbssidmask(common);
 }
 
-
 /************\
 * RX Control *
 \************/
@@ -1157,14 +1031,17 @@ int ath5k_hw_set_key_lladdr(struct ath5k
 	 /* Invalid entry (key table overflow) */
 	AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
 
-	/* MAC may be NULL if it's a broadcast key. In this case no need to
-	 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
+	/*
+	 * MAC may be NULL if it's a broadcast key. In this case no need to
+	 * to compute get_unaligned_le32 and get_unaligned_le16 as we
+	 * already know it.
+	 */
 	if (!mac) {
 		low_id = 0xffffffff;
 		high_id = 0xffff | AR5K_KEYTABLE_VALID;
 	} else {
-		low_id = AR5K_LOW_ID(mac);
-		high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
+		low_id = get_unaligned_le32(mac);
+		high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
 	}
 
 	ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/phy.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -117,7 +117,7 @@ static unsigned int ath5k_hw_rfb_op(stru
 
 /*
  * This code is used to optimize rf gain on different environments
- * (temprature mostly) based on feedback from a power detector.
+ * (temperature mostly) based on feedback from a power detector.
  *
  * It's only used on RF5111 and RF5112, later RF chips seem to have
  * auto adjustment on hw -notice they have a much smaller BANK 7 and
@@ -1124,77 +1124,148 @@ ath5k_hw_calibration_poll(struct ath5k_h
 		ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
 		AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
 	}
+}
 
+static int sign_extend(int val, const int nbits)
+{
+	int order = BIT(nbits-1);
+	return (val ^ order) - order;
 }
 
-/**
- * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
- *
- * @ah: struct ath5k_hw pointer we are operating on
- * @freq: the channel frequency, just used for error logging
- *
- * This function performs a noise floor calibration of the PHY and waits for
- * it to complete. Then the noise floor value is compared to some maximum
- * noise floor we consider valid.
- *
- * Note that this is different from what the madwifi HAL does: it reads the
- * noise floor and afterwards initiates the calibration. Since the noise floor
- * calibration can take some time to finish, depending on the current channel
- * use, that avoids the occasional timeout warnings we are seeing now.
- *
- * See the following link for an Atheros patent on noise floor calibration:
- * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
- * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
+static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
+{
+	s32 val;
+
+	val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
+	return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9);
+}
+
+void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
+{
+	int i;
+
+	ah->ah_nfcal_hist.index = 0;
+	for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
+		ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
+}
+
+static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
+{
+	struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
+	hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX-1);
+	hist->nfval[hist->index] = noise_floor;
+}
+
+static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
+{
+	s16 sort[ATH5K_NF_CAL_HIST_MAX];
+	s16 tmp;
+	int i, j;
+
+	memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
+	for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
+		for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
+			if (sort[j] > sort[j-1]) {
+				tmp = sort[j];
+				sort[j] = sort[j-1];
+				sort[j-1] = tmp;
+			}
+		}
+	}
+	for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
+		ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+			"cal %d:%d\n", i, sort[i]);
+	}
+	return sort[(ATH5K_NF_CAL_HIST_MAX-1) / 2];
+}
+
+/*
+ * When we tell the hardware to perform a noise floor calibration
+ * by setting the AR5K_PHY_AGCCTL_NF bit, it will periodically
+ * sample-and-hold the minimum noise level seen at the antennas.
+ * This value is then stored in a ring buffer of recently measured
+ * noise floor values so we have a moving window of the last few
+ * samples.
  *
- * XXX: Since during noise floor calibration antennas are detached according to
- * the patent, we should stop tx queues here.
+ * The median of the values in the history is then loaded into the
+ * hardware for its own use for RSSI and CCA measurements.
  */
-int
-ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
+void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
 {
-	int ret;
-	unsigned int i;
-	s32 noise_floor;
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	u32 val;
+	s16 nf, threshold;
+	u8 ee_mode;
 
-	/*
-	 * Enable noise floor calibration
-	 */
-	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-				AR5K_PHY_AGCCTL_NF);
+	/* keep last value if calibration hasn't completed */
+	if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
+		ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+			"NF did not complete in calibration window\n");
 
-	ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-			AR5K_PHY_AGCCTL_NF, 0, false);
-	if (ret) {
-		ATH5K_ERR(ah->ah_sc,
-			"noise floor calibration timeout (%uMHz)\n", freq);
-		return -EAGAIN;
+		return;
 	}
 
-	/* Wait until the noise floor is calibrated and read the value */
-	for (i = 20; i > 0; i--) {
-		mdelay(1);
-		noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
-		noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
-		if (noise_floor & AR5K_PHY_NF_ACTIVE) {
-			noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
-
-			if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
-				break;
-		}
+	switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
+	case CHANNEL_A:
+	case CHANNEL_T:
+	case CHANNEL_XR:
+		ee_mode = AR5K_EEPROM_MODE_11A;
+		break;
+	case CHANNEL_G:
+	case CHANNEL_TG:
+		ee_mode = AR5K_EEPROM_MODE_11G;
+		break;
+	default:
+	case CHANNEL_B:
+		ee_mode = AR5K_EEPROM_MODE_11B;
+		break;
 	}
 
-	ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
-		"noise floor %d\n", noise_floor);
 
-	if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
-		ATH5K_ERR(ah->ah_sc,
-			"noise floor calibration failed (%uMHz)\n", freq);
-		return -EAGAIN;
+	/* completed NF calibration, test threshold */
+	nf = ath5k_hw_read_measured_noise_floor(ah);
+	threshold = ee->ee_noise_floor_thr[ee_mode];
+
+	if (nf > threshold) {
+		ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+			"noise floor failure detected; "
+			"read %d, threshold %d\n",
+			nf, threshold);
+
+		nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
 	}
 
-	ah->ah_noise_floor = noise_floor;
+	ath5k_hw_update_nfcal_hist(ah, nf);
+	nf = ath5k_hw_get_median_noise_floor(ah);
 
-	return 0;
+	/* load noise floor (in .5 dBm) so the hardware will use it */
+	val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M;
+	val |= (nf * 2) & AR5K_PHY_NF_M;
+	ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
+
+	AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
+		~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE));
+
+	ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
+		0, false);
+
+	/*
+	 * Load a high max CCA Power value (-50 dBm in .5 dBm units)
+	 * so that we're not capped by the median we just loaded.
+	 * This will be used as the initial value for the next noise
+	 * floor calibration.
+	 */
+	val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M);
+	ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
+	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+		AR5K_PHY_AGCCTL_NF_EN |
+		AR5K_PHY_AGCCTL_NF_NOUPDATE |
+		AR5K_PHY_AGCCTL_NF);
+
+	ah->ah_noise_floor = nf;
+
+	ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+		"noise floor calibrated: %d\n", nf);
 }
 
 /*
@@ -1287,7 +1358,7 @@ static int ath5k_hw_rf5110_calibrate(str
 		return ret;
 	}
 
-	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+	ath5k_hw_update_noise_floor(ah);
 
 	/*
 	 * Re-enable RX/TX and beacons
@@ -1328,7 +1399,7 @@ static int ath5k_hw_rf511x_calibrate(str
 	if (i_coffd == 0 || q_coffd == 0)
 		goto done;
 
-	i_coff = ((-iq_corr) / i_coffd) & 0x3f;
+	i_coff = ((-iq_corr) / i_coffd);
 
 	/* Boundary check */
 	if (i_coff > 31)
@@ -1336,7 +1407,7 @@ static int ath5k_hw_rf511x_calibrate(str
 	if (i_coff < -32)
 		i_coff = -32;
 
-	q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
+	q_coff = (((s32)i_pwr / q_coffd) - 128);
 
 	/* Boundary check */
 	if (q_coff > 15)
@@ -1360,7 +1431,7 @@ done:
 	 * since noise floor calibration interrupts rx path while I/Q
 	 * calibration doesn't. We don't need to run noise floor calibration
 	 * as often as I/Q calibration.*/
-	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+	ath5k_hw_update_noise_floor(ah);
 
 	/* Initiate a gain_F calibration */
 	ath5k_hw_request_rfgain_probe(ah);
@@ -2675,7 +2746,7 @@ ath5k_setup_channel_powertable(struct at
 		/* Fill curves in reverse order
 		 * from lower power (max gain)
 		 * to higher power. Use curve -> idx
-		 * backmaping we did on eeprom init */
+		 * backmapping we did on eeprom init */
 		u8 idx = pdg_curve_to_idx[pdg];
 
 		/* Grab the needed curves by index */
@@ -2777,7 +2848,7 @@ ath5k_setup_channel_powertable(struct at
 	/* Now we have a set of curves for this
 	 * channel on tmpL (x range is table_max - table_min
 	 * and y values are tmpL[pdg][]) sorted in the same
-	 * order as EEPROM (because we've used the backmaping).
+	 * order as EEPROM (because we've used the backmapping).
 	 * So for RF5112 it's from higher power to lower power
 	 * and for RF2413 it's from lower power to higher power.
 	 * For RF5111 we only have one curve. */
@@ -2954,8 +3025,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, st
 		ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
 		return -EINVAL;
 	}
-	if (txpower == 0)
-		txpower = AR5K_TUNE_DEFAULT_TXPOWER;
 
 	/* Reset TX power values */
 	memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,7 @@
  * released by Atheros and on various debug messages found on the net.
  */
 
-
+#include "../reg.h"
 
 /*====MAC DMA REGISTERS====*/
 
@@ -1650,12 +1650,6 @@
 #define AR5K_SLEEP2_DTIM_PER_S		16
 
 /*
- * BSSID mask registers
- */
-#define AR5K_BSS_IDM0			0x80e0	/* Upper bits */
-#define AR5K_BSS_IDM1			0x80e4	/* Lower bits */
-
-/*
  * TX power control (TPC) register
  *
  * XXX: PCDAC steps (0.5dbm) or DBM ?
@@ -2039,17 +2033,14 @@
 #define	AR5K_PHY_AGCCTL_NF_NOUPDATE	0x00020000	/* Don't update nf automaticaly */
 
 /*
- * PHY noise floor status register
+ * PHY noise floor status register (CCA = Clear Channel Assessment)
  */
 #define AR5K_PHY_NF			0x9864			/* Register address */
-#define AR5K_PHY_NF_M			0x000001ff	/* Noise floor mask */
-#define AR5K_PHY_NF_ACTIVE		0x00000100	/* Noise floor calibration still active */
-#define AR5K_PHY_NF_RVAL(_n)		(((_n) >> 19) & AR5K_PHY_NF_M)
-#define AR5K_PHY_NF_AVAL(_n)		(-((_n) ^ AR5K_PHY_NF_M) + 1)
-#define AR5K_PHY_NF_SVAL(_n)		(((_n) & AR5K_PHY_NF_M) | (1 << 9))
+#define AR5K_PHY_NF_M			0x000001ff	/* Noise floor, written to hardware in 1/2 dBm units */
+#define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
 #define	AR5K_PHY_NF_THRESH62		0x0007f000	/* Thresh62 -check ANI patent- (field) */
 #define	AR5K_PHY_NF_THRESH62_S		12
-#define	AR5K_PHY_NF_MINCCA_PWR		0x0ff80000	/* ??? */
+#define	AR5K_PHY_NF_MINCCA_PWR		0x0ff80000	/* Minimum measured noise level, read from hardware in 1 dBm units */
 #define	AR5K_PHY_NF_MINCCA_PWR_S	19
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/reset.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reset.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath5k/reset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath5k/reset.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,8 @@
   Reset functions and helpers
 \*****************************/
 
+#include <asm/unaligned.h>
+
 #include <linux/pci.h> 		/* To determine if a card is pci-e */
 #include <linux/log2.h>
 #include "ath5k.h"
@@ -870,6 +872,7 @@ static void ath5k_hw_commit_eeprom_setti
 int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	struct ieee80211_channel *channel, bool change_channel)
 {
+	struct ath_common *common = ath5k_hw_common(ah);
 	u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
 	u32 phy_tst1;
 	u8 mode, freq, ee_mode, ant[2];
@@ -1171,10 +1174,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
 
 	/* Restore sta_id flags and preserve our mac address*/
-	ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
-						AR5K_STA_ID0);
-	ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
-						AR5K_STA_ID1);
+	ath5k_hw_reg_write(ah,
+			   get_unaligned_le32(common->macaddr),
+			   AR5K_STA_ID0);
+	ath5k_hw_reg_write(ah,
+			   staid1_flags | get_unaligned_le16(common->macaddr + 4),
+			   AR5K_STA_ID1);
 
 
 	/*
@@ -1182,8 +1187,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	 */
 
 	/* Restore bssid and bssid mask */
-	/* XXX: add ah->aid once mac80211 gives this to us */
-	ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+	ath5k_hw_set_associd(ah);
 
 	/* Set PCU config */
 	ath5k_hw_set_opmode(ah);
@@ -1289,7 +1293,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	 * out and/or noise floor calibration might timeout.
 	 */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-				AR5K_PHY_AGCCTL_CAL);
+				AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
 
 	/* At the same time start I/Q calibration for QAM constellation
 	 * -no need for CCK- */
@@ -1310,21 +1314,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			channel->center_freq);
 	}
 
-	/*
-	 * If we run NF calibration before AGC, it always times out.
-	 * Binary HAL starts NF and AGC calibration at the same time
-	 * and only waits for AGC to finish. Also if AGC or NF cal.
-	 * times out, reset doesn't fail on binary HAL. I believe
-	 * that's wrong because since rx path is routed to a detector,
-	 * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
-	 * enables noise floor calibration after offset calibration and if noise
-	 * floor calibration fails, reset fails. I believe that's
-	 * a better approach, we just need to find a polling interval
-	 * that suits best, even if reset continues we need to make
-	 * sure that rx path is ready.
-	 */
-	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
 	/* Restore antenna mode */
 	ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ahb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ahb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ahb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ahb.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,27 +22,29 @@
 #include "ath9k.h"
 
 /* return bus cachesize in 4B word units */
-static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
 {
 	*csz = L1_CACHE_BYTES >> 2;
 }
 
-static void ath_ahb_cleanup(struct ath_softc *sc)
+static void ath_ahb_cleanup(struct ath_common *common)
 {
+	struct ath_softc *sc = (struct ath_softc *)common->priv;
 	iounmap(sc->mem);
 }
 
-static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 {
-	struct ath_softc *sc = ah->ah_sc;
+	struct ath_softc *sc = (struct ath_softc *)common->priv;
 	struct platform_device *pdev = to_platform_device(sc->dev);
 	struct ath9k_platform_data *pdata;
 
 	pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
 	if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"%s: flash read failed, offset %08x is out of range\n",
-				__func__, off);
+		ath_print(common, ATH_DBG_FATAL,
+			  "%s: flash read failed, offset %08x "
+			  "is out of range\n",
+			  __func__, off);
 		return false;
 	}
 
@@ -67,6 +69,7 @@ static int ath_ahb_probe(struct platform
 	int irq;
 	int ret = 0;
 	struct ath_hw *ah;
+	char hw_name[64];
 
 	if (!pdev->dev.platform_data) {
 		dev_err(&pdev->dev, "no platform data specified\n");
@@ -116,10 +119,9 @@ static int ath_ahb_probe(struct platform
 	sc->hw = hw;
 	sc->dev = &pdev->dev;
 	sc->mem = mem;
-	sc->bus_ops = &ath_ahb_bus_ops;
 	sc->irq = irq;
 
-	ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0);
+	ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize device\n");
 		goto err_free_hw;
@@ -132,14 +134,11 @@ static int ath_ahb_probe(struct platform
 	}
 
 	ah = sc->sc_ah;
+	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
 	printk(KERN_INFO
-	       "%s: Atheros AR%s MAC/BB Rev:%x, "
-	       "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+	       "%s: %s mem=0x%lx, irq=%d\n",
 	       wiphy_name(hw->wiphy),
-	       ath_mac_bb_name(ah->hw_version.macVersion),
-	       ah->hw_version.macRev,
-	       ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-	       ah->hw_version.phyRev,
+	       hw_name,
 	       (unsigned long)mem, irq);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ani.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ani.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ani.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ani.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
 					struct ath9k_channel *chan)
@@ -31,8 +31,8 @@ static int ath9k_hw_get_ani_channel_idx(
 		}
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"No more channel states left. Using channel 0\n");
+	ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
+		  "No more channel states left. Using channel 0\n");
 
 	return 0;
 }
@@ -41,16 +41,17 @@ static bool ath9k_hw_ani_control(struct
 				 enum ath9k_ani_cmd cmd, int param)
 {
 	struct ar5416AniState *aniState = ah->curani;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	switch (cmd & ah->ani_function) {
 	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
 		u32 level = param;
 
 		if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"level out of range (%u > %u)\n",
-				level,
-				(unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
 			return false;
 		}
 
@@ -152,10 +153,10 @@ static bool ath9k_hw_ani_control(struct
 		u32 level = param;
 
 		if (level >= ARRAY_SIZE(firstep)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"level out of range (%u > %u)\n",
-				level,
-				(unsigned) ARRAY_SIZE(firstep));
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(firstep));
 			return false;
 		}
 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
@@ -174,11 +175,10 @@ static bool ath9k_hw_ani_control(struct
 		u32 level = param;
 
 		if (level >= ARRAY_SIZE(cycpwrThr1)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"level out of range (%u > %u)\n",
-				level,
-				(unsigned)
-				ARRAY_SIZE(cycpwrThr1));
+			ath_print(common, ATH_DBG_ANI,
+				  "level out of range (%u > %u)\n",
+				  level,
+				  (unsigned) ARRAY_SIZE(cycpwrThr1));
 			return false;
 		}
 		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
@@ -194,25 +194,28 @@ static bool ath9k_hw_ani_control(struct
 	case ATH9K_ANI_PRESENT:
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"invalid cmd %u\n", cmd);
+		ath_print(common, ATH_DBG_ANI,
+			  "invalid cmd %u\n", cmd);
 		return false;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-		"ofdmWeakSigDetectOff=%d\n",
-		aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
-		!aniState->ofdmWeakSigDetectOff);
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"cckWeakSigThreshold=%d, "
-		"firstepLevel=%d, listenTime=%d\n",
-		aniState->cckWeakSigThreshold, aniState->firstepLevel,
-		aniState->listenTime);
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+	ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
+	ath_print(common, ATH_DBG_ANI,
+		  "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+		  "ofdmWeakSigDetectOff=%d\n",
+		  aniState->noiseImmunityLevel,
+		  aniState->spurImmunityLevel,
+		  !aniState->ofdmWeakSigDetectOff);
+	ath_print(common, ATH_DBG_ANI,
+		  "cckWeakSigThreshold=%d, "
+		  "firstepLevel=%d, listenTime=%d\n",
+		  aniState->cckWeakSigThreshold,
+		  aniState->firstepLevel,
+		  aniState->listenTime);
+	ath_print(common, ATH_DBG_ANI,
 		"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-		aniState->cycleCount, aniState->ofdmPhyErrCount,
+		aniState->cycleCount,
+		aniState->ofdmPhyErrCount,
 		aniState->cckPhyErrCount);
 
 	return true;
@@ -231,6 +234,7 @@ static void ath9k_hw_update_mibstats(str
 static void ath9k_ani_restart(struct ath_hw *ah)
 {
 	struct ar5416AniState *aniState;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	if (!DO_ANI(ah))
 		return;
@@ -240,24 +244,24 @@ static void ath9k_ani_restart(struct ath
 
 	if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
 		aniState->ofdmPhyErrBase = 0;
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"OFDM Trigger is too high for hw counters\n");
+		ath_print(common, ATH_DBG_ANI,
+			  "OFDM Trigger is too high for hw counters\n");
 	} else {
 		aniState->ofdmPhyErrBase =
 			AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
 	}
 	if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
 		aniState->cckPhyErrBase = 0;
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"CCK Trigger is too high for hw counters\n");
+		ath_print(common, ATH_DBG_ANI,
+			  "CCK Trigger is too high for hw counters\n");
 	} else {
 		aniState->cckPhyErrBase =
 			AR_PHY_COUNTMAX - aniState->cckTrigHigh;
 	}
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Writing ofdmbase=%u   cckbase=%u\n",
-		aniState->ofdmPhyErrBase,
-		aniState->cckPhyErrBase);
+	ath_print(common, ATH_DBG_ANI,
+		  "Writing ofdmbase=%u   cckbase=%u\n",
+		  aniState->ofdmPhyErrBase,
+		  aniState->cckPhyErrBase);
 	REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
 	REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
 	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
@@ -271,7 +275,7 @@ static void ath9k_ani_restart(struct ath
 
 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 	struct ar5416AniState *aniState;
 	int32_t rssi;
 
@@ -343,7 +347,7 @@ static void ath9k_hw_ani_ofdm_err_trigge
 
 static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 	struct ar5416AniState *aniState;
 	int32_t rssi;
 
@@ -464,6 +468,7 @@ void ath9k_ani_reset(struct ath_hw *ah)
 {
 	struct ar5416AniState *aniState;
 	struct ath9k_channel *chan = ah->curchan;
+	struct ath_common *common = ath9k_hw_common(ah);
 	int index;
 
 	if (!DO_ANI(ah))
@@ -475,8 +480,8 @@ void ath9k_ani_reset(struct ath_hw *ah)
 
 	if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
 	    && ah->opmode != NL80211_IFTYPE_ADHOC) {
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Reset ANI state opmode %u\n", ah->opmode);
+		ath_print(common, ATH_DBG_ANI,
+			  "Reset ANI state opmode %u\n", ah->opmode);
 		ah->stats.ast_ani_reset++;
 
 		if (ah->opmode == NL80211_IFTYPE_AP) {
@@ -543,6 +548,7 @@ void ath9k_hw_ani_monitor(struct ath_hw
 			  struct ath9k_channel *chan)
 {
 	struct ar5416AniState *aniState;
+	struct ath_common *common = ath9k_hw_common(ah);
 	int32_t listenTime;
 	u32 phyCnt1, phyCnt2;
 	u32 ofdmPhyErrCnt, cckPhyErrCnt;
@@ -569,20 +575,22 @@ void ath9k_hw_ani_monitor(struct ath_hw
 	if (phyCnt1 < aniState->ofdmPhyErrBase ||
 	    phyCnt2 < aniState->cckPhyErrBase) {
 		if (phyCnt1 < aniState->ofdmPhyErrBase) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"phyCnt1 0x%x, resetting "
-				"counter value to 0x%x\n",
-				phyCnt1, aniState->ofdmPhyErrBase);
+			ath_print(common, ATH_DBG_ANI,
+				  "phyCnt1 0x%x, resetting "
+				  "counter value to 0x%x\n",
+				  phyCnt1,
+				  aniState->ofdmPhyErrBase);
 			REG_WRITE(ah, AR_PHY_ERR_1,
 				  aniState->ofdmPhyErrBase);
 			REG_WRITE(ah, AR_PHY_ERR_MASK_1,
 				  AR_PHY_ERR_OFDM_TIMING);
 		}
 		if (phyCnt2 < aniState->cckPhyErrBase) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"phyCnt2 0x%x, resetting "
-				"counter value to 0x%x\n",
-				phyCnt2, aniState->cckPhyErrBase);
+			ath_print(common, ATH_DBG_ANI,
+				  "phyCnt2 0x%x, resetting "
+				  "counter value to 0x%x\n",
+				  phyCnt2,
+				  aniState->cckPhyErrBase);
 			REG_WRITE(ah, AR_PHY_ERR_2,
 				  aniState->cckPhyErrBase);
 			REG_WRITE(ah, AR_PHY_ERR_MASK_2,
@@ -621,10 +629,13 @@ void ath9k_hw_ani_monitor(struct ath_hw
 		}
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_ani_monitor);
 
 void ath9k_enable_mib_counters(struct ath_hw *ah)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n");
 
 	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
@@ -640,7 +651,10 @@ void ath9k_enable_mib_counters(struct at
 /* Freeze the MIB counters, get the stats and then clear them */
 void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n");
+
 	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
 	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 	REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
@@ -653,6 +667,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct
 				  u32 *rxf_pcnt,
 				  u32 *txf_pcnt)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	static u32 cycles, rx_clear, rx_frame, tx_frame;
 	u32 good = 1;
 
@@ -662,8 +677,8 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct
 	u32 cc = REG_READ(ah, AR_CCCNT);
 
 	if (cycles == 0 || cycles > cc) {
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"cycle counter wrap. ExtBusy = 0\n");
+		ath_print(common, ATH_DBG_ANI,
+			  "cycle counter wrap. ExtBusy = 0\n");
 		good = 0;
 	} else {
 		u32 cc_d = cc - cycles;
@@ -742,6 +757,7 @@ void ath9k_hw_procmibevent(struct ath_hw
 		ath9k_ani_restart(ah);
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_procmibevent);
 
 void ath9k_hw_ani_setup(struct ath_hw *ah)
 {
@@ -762,9 +778,10 @@ void ath9k_hw_ani_setup(struct ath_hw *a
 
 void ath9k_hw_ani_init(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int i;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Initialize ANI\n");
+	ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
 
 	memset(ah->ani, 0, sizeof(ah->ani));
 	for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
@@ -786,11 +803,11 @@ void ath9k_hw_ani_init(struct ath_hw *ah
 			AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Setting OfdmErrBase = 0x%08x\n",
-		ah->ani[0].ofdmPhyErrBase);
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-		ah->ani[0].cckPhyErrBase);
+	ath_print(common, ATH_DBG_ANI,
+		  "Setting OfdmErrBase = 0x%08x\n",
+		  ah->ani[0].ofdmPhyErrBase);
+	ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
+		  ah->ani[0].cckPhyErrBase);
 
 	REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
 	REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
@@ -803,7 +820,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah
 
 void ath9k_hw_ani_disable(struct ath_hw *ah)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n");
+	ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n");
 
 	ath9k_hw_disable_mib_counters(ah);
 	REG_WRITE(ah, AR_PHY_ERR_1, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/ath9k.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,24 +19,25 @@
 
 #include <linux/etherdevice.h>
 #include <linux/device.h>
-#include <net/mac80211.h>
 #include <linux/leds.h>
 
-#include "hw.h"
-#include "rc.h"
 #include "debug.h"
-#include "../ath.h"
-#include "btcoex.h"
+#include "common.h"
+
+/*
+ * Header for the ath9k.ko driver core *only* -- hw code nor any other driver
+ * should rely on this file or its contents.
+ */
 
 struct ath_node;
 
 /* Macro to expand scalars to 64-bit objects */
 
-#define	ito64(x) (sizeof(x) == 8) ?			\
+#define	ito64(x) (sizeof(x) == 1) ?			\
 	(((unsigned long long int)(x)) & (0xff)) :	\
-	(sizeof(x) == 16) ?				\
+	(sizeof(x) == 2) ?				\
 	(((unsigned long long int)(x)) & 0xffff) :	\
-	((sizeof(x) == 32) ?				\
+	((sizeof(x) == 4) ?				\
 	 (((unsigned long long int)(x)) & 0xffffffff) : \
 	 (unsigned long long int)(x))
 
@@ -54,15 +55,11 @@ struct ath_node;
 
 #define A_MAX(a, b) ((a) > (b) ? (a) : (b))
 
-#define ASSERT(exp) BUG_ON(!(exp))
-
 #define TSF_TO_TU(_h,_l) \
 	((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
 #define	ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
 
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
 struct ath_config {
 	u32 ath_aggr_prot;
 	u16 txpowlimit;
@@ -103,18 +100,6 @@ enum buffer_type {
 	BUF_XRETRY		= BIT(5),
 };
 
-struct ath_buf_state {
-	int bfs_nframes;
-	u16 bfs_al;
-	u16 bfs_frmlen;
-	int bfs_seqno;
-	int bfs_tidno;
-	int bfs_retries;
-	u8 bf_type;
-	u32 bfs_keyix;
-	enum ath9k_key_type bfs_keytype;
-};
-
 #define bf_nframes      	bf_state.bfs_nframes
 #define bf_al           	bf_state.bfs_al
 #define bf_frmlen       	bf_state.bfs_frmlen
@@ -129,21 +114,6 @@ struct ath_buf_state {
 #define bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
 #define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
 
-struct ath_buf {
-	struct list_head list;
-	struct ath_buf *bf_lastbf;	/* last buf of this unit (a frame or
-					   an aggregate) */
-	struct ath_buf *bf_next;	/* next subframe in the aggregate */
-	struct sk_buff *bf_mpdu;	/* enclosing frame structure */
-	struct ath_desc *bf_desc;	/* virtual addr of desc */
-	dma_addr_t bf_daddr;		/* physical addr of desc */
-	dma_addr_t bf_buf_addr;		/* physical addr of data buffer */
-	bool bf_stale;
-	u16 bf_flags;
-	struct ath_buf_state bf_state;
-	dma_addr_t bf_dmacontext;
-};
-
 struct ath_descdma {
 	struct ath_desc *dd_desc;
 	dma_addr_t dd_desc_paddr;
@@ -163,13 +133,9 @@ void ath_descdma_cleanup(struct ath_soft
 
 #define ATH_MAX_ANTENNA         3
 #define ATH_RXBUF               512
-#define WME_NUM_TID             16
 #define ATH_TXBUF               512
 #define ATH_TXMAXTRY            13
 #define ATH_MGT_TXMAXTRY        4
-#define WME_BA_BMP_SIZE         64
-#define WME_MAX_BA              WME_BA_BMP_SIZE
-#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
 
 #define TID_TO_WME_AC(_tid)				\
 	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
@@ -177,12 +143,6 @@ void ath_descdma_cleanup(struct ath_soft
 	 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI :	\
 	 WME_AC_VO)
 
-#define WME_AC_BE   0
-#define WME_AC_BK   1
-#define WME_AC_VI   2
-#define WME_AC_VO   3
-#define WME_NUM_AC  4
-
 #define ADDBA_EXCHANGE_ATTEMPTS    10
 #define ATH_AGGR_DELIM_SZ          4
 #define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
@@ -191,7 +151,6 @@ void ath_descdma_cleanup(struct ath_soft
 /* minimum h/w qdepth to be sustained to maximize aggregation */
 #define ATH_AGGR_MIN_QDEPTH        2
 #define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
 
 #define IEEE80211_SEQ_SEQ_SHIFT    4
 #define IEEE80211_SEQ_MAX          4096
@@ -238,18 +197,8 @@ struct ath_txq {
 	struct list_head axq_q;
 	spinlock_t axq_lock;
 	u32 axq_depth;
-	u8 axq_aggr_depth;
 	bool stopped;
 	bool axq_tx_inprogress;
-	struct ath_buf *axq_linkbuf;
-
-	/* first desc of the last descriptor that contains CTS */
-	struct ath_desc *axq_lastdsWithCTS;
-
-	/* final desc of the gating desc that determines whether
-	   lastdsWithCTS has been DMA'ed or not */
-	struct ath_desc *axq_gatingds;
-
 	struct list_head axq_acq;
 };
 
@@ -257,30 +206,6 @@ struct ath_txq {
 #define AGGR_ADDBA_COMPLETE  BIT(2)
 #define AGGR_ADDBA_PROGRESS  BIT(3)
 
-struct ath_atx_tid {
-	struct list_head list;
-	struct list_head buf_q;
-	struct ath_node *an;
-	struct ath_atx_ac *ac;
-	struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
-	u16 seq_start;
-	u16 seq_next;
-	u16 baw_size;
-	int tidno;
-	int baw_head;	/* first un-acked tx buffer */
-	int baw_tail;	/* next unused tx buffer slot */
-	int sched;
-	int paused;
-	u8 state;
-};
-
-struct ath_atx_ac {
-	int sched;
-	int qnum;
-	struct list_head list;
-	struct list_head tid_q;
-};
-
 struct ath_tx_control {
 	struct ath_txq *txq;
 	int if_id;
@@ -291,30 +216,6 @@ struct ath_tx_control {
 #define ATH_TX_XRETRY       0x02
 #define ATH_TX_BAR          0x04
 
-#define ATH_RSSI_LPF_LEN 		10
-#define RSSI_LPF_THRESHOLD		-20
-#define ATH9K_RSSI_BAD			0x80
-#define ATH_RSSI_EP_MULTIPLIER     (1<<7)
-#define ATH_EP_MUL(x, mul)         ((x) * (mul))
-#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
-#define ATH_LPF_RSSI(x, y, len) \
-    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
-#define ATH_RSSI_LPF(x, y) do {                     			\
-    if ((y) >= RSSI_LPF_THRESHOLD)                         		\
-	x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);  	\
-} while (0)
-#define ATH_EP_RND(x, mul) 						\
-	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-
-struct ath_node {
-	struct ath_softc *an_sc;
-	struct ath_atx_tid tid[WME_NUM_TID];
-	struct ath_atx_ac ac[WME_NUM_AC];
-	u16 maxampdu;
-	u8 mpdudensity;
-	int last_rssi;
-};
-
 struct ath_tx {
 	u16 seq_no;
 	u32 txqsetup;
@@ -329,7 +230,6 @@ struct ath_rx {
 	u8 defant;
 	u8 rxotherant;
 	u32 *rxlink;
-	int bufsize;
 	unsigned int rxfilter;
 	spinlock_t rxflushlock;
 	spinlock_t rxbuflock;
@@ -427,9 +327,9 @@ struct ath_beacon {
 
 void ath_beacon_tasklet(unsigned long data);
 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
-int ath_beaconq_setup(struct ath_hw *ah);
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+int ath_beaconq_config(struct ath_softc *sc);
 
 /*******/
 /* ANI */
@@ -441,14 +341,24 @@ void ath_beacon_return(struct ath_softc
 #define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
 #define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
-struct ath_ani {
-	bool caldone;
-	int16_t noise_floor;
-	unsigned int longcal_timer;
-	unsigned int shortcal_timer;
-	unsigned int resetcal_timer;
-	unsigned int checkani_timer;
-	struct timer_list timer;
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+	ATH_BTCOEX_NO_STOMP,
+	ATH_BTCOEX_STOMP_ALL,
+	ATH_BTCOEX_STOMP_LOW,
+	ATH_BTCOEX_STOMP_NONE
+};
+
+struct ath_btcoex {
+	bool hw_timer_enabled;
+	spinlock_t btcoex_lock;
+	struct timer_list period_timer; /* Timer for BT period */
+	u32 bt_priority_cnt;
+	unsigned long bt_priority_time;
+	int bt_stomp_type; /* Types of BT stomping */
+	u32 btcoex_no_stomp; /* in usec */
+	u32 btcoex_period; /* in usec */
+	struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
 };
 
 /********************/
@@ -484,25 +394,13 @@ struct ath_led {
  * Used when PCI device not fully initialized by bootrom/BIOS
 */
 #define DEFAULT_CACHELINE       32
-#define	ATH_DEFAULT_NOISE_FLOOR -95
 #define ATH_REGCLASSIDS_MAX     10
 #define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
 #define ATH_MAX_SW_RETRIES      10
 #define ATH_CHAN_MAX            255
 #define IEEE80211_WEP_NKID      4       /* number of key ids */
 
-/*
- * The key cache is used for h/w cipher state and also for
- * tracking station state such as the current tx antenna.
- * We also setup a mapping table between key cache slot indices
- * and station state to short-circuit node lookups on rx.
- * Different parts have different size key caches.  We handle
- * up to ATH_KEYMAX entries (could dynamically allocate state).
- */
-#define	ATH_KEYMAX	        128     /* max key cache size we handle */
-
 #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER   0x127
 #define ATH_RATE_DUMMY_MARKER   0
 
 #define SC_OP_INVALID           BIT(0)
@@ -522,23 +420,17 @@ struct ath_led {
 #define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
 #define SC_OP_WAIT_FOR_TX_ACK   BIT(18)
 #define SC_OP_BEACON_SYNC       BIT(19)
-#define SC_OP_BTCOEX_ENABLED    BIT(20)
 #define SC_OP_BT_PRIORITY_DETECTED BIT(21)
-
-struct ath_bus_ops {
-	void		(*read_cachesize)(struct ath_softc *sc, int *csz);
-	void		(*cleanup)(struct ath_softc *sc);
-	bool		(*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
-};
+#define SC_OP_NULLFUNC_COMPLETED BIT(22)
+#define SC_OP_PS_ENABLED	BIT(23)
 
 struct ath_wiphy;
+struct ath_rate_table;
 
 struct ath_softc {
 	struct ieee80211_hw *hw;
 	struct device *dev;
 
-	struct ath_common common;
-
 	spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
 	struct ath_wiphy *pri_wiphy;
 	struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
@@ -565,32 +457,21 @@ struct ath_softc {
 	spinlock_t sc_pm_lock;
 	struct mutex mutex;
 
-	u8 curbssid[ETH_ALEN];
-	u8 bssidmask[ETH_ALEN];
 	u32 intrstatus;
 	u32 sc_flags; /* SC_OP_* */
 	u16 curtxpow;
-	u16 curaid;
 	u8 nbcnvifs;
 	u16 nvifs;
-	u8 tx_chainmask;
-	u8 rx_chainmask;
-	u32 keymax;
-	DECLARE_BITMAP(keymap, ATH_KEYMAX);
-	u8 splitmic;
 	bool ps_enabled;
 	unsigned long ps_usecount;
 	enum ath9k_int imask;
-	enum ath9k_ht_extprotspacing ht_extprotspacing;
-	enum ath9k_ht_macmode tx_chan_width;
 
 	struct ath_config config;
 	struct ath_rx rx;
 	struct ath_tx tx;
 	struct ath_beacon beacon;
-	struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
-	const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
 	const struct ath_rate_table *cur_rate_table;
+	enum wireless_mode cur_rate_mode;
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
 	struct ath_led radio_led;
@@ -605,14 +486,12 @@ struct ath_softc {
 
 	int beacon_interval;
 
-	struct ath_ani ani;
-#ifdef CONFIG_ATH9K_DEBUG
+#ifdef CONFIG_ATH9K_DEBUGFS
 	struct ath9k_debug debug;
 #endif
-	struct ath_bus_ops *bus_ops;
 	struct ath_beacon_config cur_beacon_conf;
 	struct delayed_work tx_complete_work;
-	struct ath_btcoex_info btcoex_info;
+	struct ath_btcoex btcoex;
 };
 
 struct ath_wiphy {
@@ -625,6 +504,7 @@ struct ath_wiphy {
 		ATH_WIPHY_PAUSED,
 		ATH_WIPHY_SCAN,
 	} state;
+	bool idle;
 	int chan_idx;
 	int chan_is_ht;
 };
@@ -634,31 +514,22 @@ int ath_get_hal_qnum(u16 queue, struct a
 int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
 int ath_cabq_update(struct ath_softc *);
 
-static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
-{
-	return &ah->ah_sc->common;
-}
-
-static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
-{
-	return &(ath9k_hw_common(ah)->regulatory);
-}
-
-static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 {
-	sc->bus_ops->read_cachesize(sc, csz);
+	common->bus_ops->read_cachesize(common, csz);
 }
 
-static inline void ath_bus_cleanup(struct ath_softc *sc)
+static inline void ath_bus_cleanup(struct ath_common *common)
 {
-	sc->bus_ops->cleanup(sc);
+	common->bus_ops->cleanup(common);
 }
 
 extern struct ieee80211_ops ath9k_ops;
 
 irqreturn_t ath_isr(int irq, void *dev);
 void ath_cleanup(struct ath_softc *sc);
-int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid);
+int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+		    const struct ath_bus_ops *bus_ops);
 void ath_detach(struct ath_softc *sc);
 const char *ath_mac_bb_name(u32 mac_bb_version);
 const char *ath_rf_name(u16 rf_version);
@@ -668,8 +539,9 @@ void ath9k_update_ichannel(struct ath_so
 void ath_update_chainmask(struct ath_softc *sc, int is_ht);
 int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 		    struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
+
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
@@ -705,9 +577,10 @@ void ath9k_wiphy_pause_all_forced(struct
 bool ath9k_wiphy_scanning(struct ath_softc *sc);
 void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
-void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
-unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
 
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/beacon.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/beacon.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/beacon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/beacon.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,10 +23,12 @@
  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
  *  settings and channel width min/max
 */
-static int ath_beaconq_config(struct ath_softc *sc)
+int ath_beaconq_config(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ath9k_tx_queue_info qi;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath9k_tx_queue_info qi, qi_be;
+	int qnum;
 
 	ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
 	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -36,14 +38,17 @@ static int ath_beaconq_config(struct ath
 		qi.tqi_cwmax = 0;
 	} else {
 		/* Adhoc mode; important thing is to use 2x cwmin. */
-		qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
-		qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
-		qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
+		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA,
+				       ATH9K_WME_AC_BE);
+		ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+		qi.tqi_aifs = qi_be.tqi_aifs;
+		qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
+		qi.tqi_cwmax = qi_be.tqi_cwmax;
 	}
 
 	if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to update h/w beacon queue parameters\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to update h/w beacon queue parameters\n");
 		return 0;
 	} else {
 		ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
@@ -61,11 +66,12 @@ static void ath_beacon_setup(struct ath_
 {
 	struct sk_buff *skb = bf->bf_mpdu;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_desc *ds;
 	struct ath9k_11n_rate_series series[4];
-	const struct ath_rate_table *rt;
 	int flags, antenna, ctsrate = 0, ctsduration = 0;
-	u8 rate;
+	struct ieee80211_supported_band *sband;
+	u8 rate = 0;
 
 	ds = bf->bf_desc;
 	flags = ATH9K_TXDESC_NOACK;
@@ -89,10 +95,10 @@ static void ath_beacon_setup(struct ath_
 
 	ds->ds_data = bf->bf_buf_addr;
 
-	rt = sc->cur_rate_table;
-	rate = rt->info[0].ratecode;
+	sband = &sc->sbands[common->hw->conf.channel->band];
+	rate = sband->bitrates[0].hw_value;
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-		rate |= rt->info[0].short_preamble;
+		rate |= sband->bitrates[0].hw_value_short;
 
 	ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
 			       ATH9K_PKT_TYPE_BEACON,
@@ -108,7 +114,7 @@ static void ath_beacon_setup(struct ath_
 	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
 	series[0].Tries = 1;
 	series[0].Rate = rate;
-	series[0].ChSel = sc->tx_chainmask;
+	series[0].ChSel = common->tx_chainmask;
 	series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
 	ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
 				     series, 4, 0);
@@ -119,6 +125,7 @@ static struct ath_buf *ath_beacon_genera
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_buf *bf;
 	struct ath_vif *avp;
 	struct sk_buff *skb;
@@ -172,7 +179,8 @@ static struct ath_buf *ath_beacon_genera
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
-		DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "dma_mapping_error on beaconing\n");
 		return NULL;
 	}
 
@@ -192,8 +200,8 @@ static struct ath_buf *ath_beacon_genera
 
 	if (skb && cabq_depth) {
 		if (sc->nvifs > 1) {
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"Flushing previous cabq traffic\n");
+			ath_print(common, ATH_DBG_BEACON,
+				  "Flushing previous cabq traffic\n");
 			ath_draintxq(sc, cabq, false);
 		}
 	}
@@ -216,6 +224,7 @@ static void ath_beacon_start_adhoc(struc
 				   struct ieee80211_vif *vif)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_buf *bf;
 	struct ath_vif *avp;
 	struct sk_buff *skb;
@@ -233,25 +242,14 @@ static void ath_beacon_start_adhoc(struc
 	/* NB: caller is known to have already stopped tx dma */
 	ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
 	ath9k_hw_txstart(ah, sc->beacon.beaconq);
-	DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
-		sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
-}
-
-int ath_beaconq_setup(struct ath_hw *ah)
-{
-	struct ath9k_tx_queue_info qi;
-
-	memset(&qi, 0, sizeof(qi));
-	qi.tqi_aifs = 1;
-	qi.tqi_cwmin = 0;
-	qi.tqi_cwmax = 0;
-	/* NB: don't enable any interrupts */
-	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
+	ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
+		  sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
 }
 
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 {
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_vif *avp;
 	struct ath_buf *bf;
 	struct sk_buff *skb;
@@ -309,7 +307,7 @@ int ath_beacon_alloc(struct ath_wiphy *a
 	/* NB: the beacon data buffer must be 32-bit aligned. */
 	skb = ieee80211_beacon_get(sc->hw, vif);
 	if (skb == NULL) {
-		DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
+		ath_print(common, ATH_DBG_BEACON, "cannot get skb\n");
 		return -ENOMEM;
 	}
 
@@ -333,9 +331,10 @@ int ath_beacon_alloc(struct ath_wiphy *a
 		tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
 		avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
 
-		DPRINTF(sc, ATH_DBG_BEACON,
-			"stagger beacons, bslot %d intval %u tsfadjust %llu\n",
-			avp->av_bslot, intval, (unsigned long long)tsfadjust);
+		ath_print(common, ATH_DBG_BEACON,
+			  "stagger beacons, bslot %d intval "
+			  "%u tsfadjust %llu\n",
+			  avp->av_bslot, intval, (unsigned long long)tsfadjust);
 
 		((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
 			avp->tsf_adjust;
@@ -349,8 +348,8 @@ int ath_beacon_alloc(struct ath_wiphy *a
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"dma_mapping_error on beacon alloc\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "dma_mapping_error on beacon alloc\n");
 		return -ENOMEM;
 	}
 
@@ -386,6 +385,7 @@ void ath_beacon_tasklet(unsigned long da
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_buf *bf = NULL;
 	struct ieee80211_vif *vif;
 	struct ath_wiphy *aphy;
@@ -405,12 +405,12 @@ void ath_beacon_tasklet(unsigned long da
 		sc->beacon.bmisscnt++;
 
 		if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"missed %u consecutive beacons\n",
-				sc->beacon.bmisscnt);
+			ath_print(common, ATH_DBG_BEACON,
+				  "missed %u consecutive beacons\n",
+				  sc->beacon.bmisscnt);
 		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"beacon is officially stuck\n");
+			ath_print(common, ATH_DBG_BEACON,
+				  "beacon is officially stuck\n");
 			sc->sc_flags |= SC_OP_TSF_RESET;
 			ath_reset(sc, false);
 		}
@@ -419,9 +419,9 @@ void ath_beacon_tasklet(unsigned long da
 	}
 
 	if (sc->beacon.bmisscnt != 0) {
-		DPRINTF(sc, ATH_DBG_BEACON,
-			"resume beacon xmit after %u misses\n",
-			sc->beacon.bmisscnt);
+		ath_print(common, ATH_DBG_BEACON,
+			  "resume beacon xmit after %u misses\n",
+			  sc->beacon.bmisscnt);
 		sc->beacon.bmisscnt = 0;
 	}
 
@@ -447,9 +447,9 @@ void ath_beacon_tasklet(unsigned long da
 	vif = sc->beacon.bslot[slot];
 	aphy = sc->beacon.bslot_aphy[slot];
 
-	DPRINTF(sc, ATH_DBG_BEACON,
-		"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
-		slot, tsf, tsftu, intval, vif);
+	ath_print(common, ATH_DBG_BEACON,
+		  "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+		  slot, tsf, tsftu, intval, vif);
 
 	bfaddr = 0;
 	if (vif) {
@@ -490,7 +490,7 @@ void ath_beacon_tasklet(unsigned long da
 		 * are still pending on the queue.
 		 */
 		if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
-			DPRINTF(sc, ATH_DBG_FATAL,
+			ath_print(common, ATH_DBG_FATAL,
 				"beacon queue %u did not stop?\n", sc->beacon.beaconq);
 		}
 
@@ -502,6 +502,19 @@ void ath_beacon_tasklet(unsigned long da
 	}
 }
 
+static void ath9k_beacon_init(struct ath_softc *sc,
+			      u32 next_beacon,
+			      u32 beacon_period)
+{
+	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+		ath9k_ps_wakeup(sc);
+
+	ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
+
+	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+		ath9k_ps_restore(sc);
+}
+
 /*
  * For multi-bss ap support beacons are either staggered evenly over N slots or
  * burst together.  For the former arrange for the SWBA to be delivered for each
@@ -534,7 +547,7 @@ static void ath_beacon_config_ap(struct
 	/* Set the computed AP beacon timers */
 
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
-	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
@@ -555,6 +568,7 @@ static void ath_beacon_config_ap(struct
 static void ath_beacon_config_sta(struct ath_softc *sc,
 				  struct ath_beacon_config *conf)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath9k_beacon_state bs;
 	int dtimperiod, dtimcount, sleepduration;
 	int cfpperiod, cfpcount;
@@ -651,11 +665,11 @@ static void ath_beacon_config_sta(struct
 	/* TSF out of range threshold fixed at 1 second */
 	bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
 
-	DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
-	DPRINTF(sc, ATH_DBG_BEACON,
-		"bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
-		bs.bs_bmissthreshold, bs.bs_sleepduration,
-		bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+	ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+	ath_print(common, ATH_DBG_BEACON,
+		  "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+		  bs.bs_bmissthreshold, bs.bs_sleepduration,
+		  bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
 
 	/* Set the computed STA beacon timers */
 
@@ -669,6 +683,7 @@ static void ath_beacon_config_adhoc(stru
 				    struct ath_beacon_config *conf,
 				    struct ieee80211_vif *vif)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	u64 tsf;
 	u32 tsftu, intval, nexttbtt;
 
@@ -689,9 +704,9 @@ static void ath_beacon_config_adhoc(stru
 		nexttbtt += intval;
 	} while (nexttbtt < tsftu);
 
-	DPRINTF(sc, ATH_DBG_BEACON,
-		"IBSS nexttbtt %u intval %u (%u)\n",
-		nexttbtt, intval, conf->beacon_interval);
+	ath_print(common, ATH_DBG_BEACON,
+		  "IBSS nexttbtt %u intval %u (%u)\n",
+		  nexttbtt, intval, conf->beacon_interval);
 
 	/*
 	 * In IBSS mode enable the beacon timers but only enable SWBA interrupts
@@ -707,7 +722,7 @@ static void ath_beacon_config_adhoc(stru
 	/* Set the computed ADHOC beacon timers */
 
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
-	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
@@ -719,6 +734,7 @@ static void ath_beacon_config_adhoc(stru
 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
 {
 	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	enum nl80211_iftype iftype;
 
 	/* Setup the beacon configuration parameters */
@@ -759,8 +775,8 @@ void ath_beacon_config(struct ath_softc
 		ath_beacon_config_sta(sc, cur_conf);
 		break;
 	default:
-		DPRINTF(sc, ATH_DBG_CONFIG,
-			"Unsupported beaconing mode\n");
+		ath_print(common, ATH_DBG_CONFIG,
+			  "Unsupported beaconing mode\n");
 		return;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/btcoex.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/btcoex.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,10 +14,26 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
-static const struct ath_btcoex_config ath_bt_config = { 0, true, true,
-			ATH_BT_COEX_MODE_SLOTTED, true, true, 2, 5, true };
+enum ath_bt_mode {
+	ATH_BT_COEX_MODE_LEGACY,        /* legacy rx_clear mode */
+	ATH_BT_COEX_MODE_UNSLOTTED,     /* untimed/unslotted mode */
+	ATH_BT_COEX_MODE_SLOTTED,       /* slotted mode */
+	ATH_BT_COEX_MODE_DISALBED,      /* coexistence disabled */
+};
+
+struct ath_btcoex_config {
+	u8 bt_time_extend;
+	bool bt_txstate_extend;
+	bool bt_txframe_extend;
+	enum ath_bt_mode bt_mode; /* coexistence mode */
+	bool bt_quiet_collision;
+	bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
+	u8 bt_priority_time;
+	u8 bt_first_slot_time;
+	bool bt_hold_rx_clear;
+};
 
 static const u16 ath_subsysid_tbl[] = {
 	AR9280_COEX2WIRE_SUBSYSID,
@@ -29,141 +45,38 @@ static const u16 ath_subsysid_tbl[] = {
  * Checks the subsystem id of the device to see if it
  * supports btcoex
  */
-bool ath_btcoex_supported(u16 subsysid)
+bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
 {
 	int i;
 
-	if (!subsysid)
+	if (!ah->hw_version.subsysid)
 		return false;
 
 	for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
-		if (subsysid == ath_subsysid_tbl[i])
+		if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
 			return true;
 
 	return false;
 }
 
-/*
- * Detects if there is any priority bt traffic
- */
-static void ath_detect_bt_priority(struct ath_softc *sc)
-{
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
-
-	if (ath9k_hw_gpio_get(sc->sc_ah, btinfo->btpriority_gpio))
-		btinfo->bt_priority_cnt++;
-
-	if (time_after(jiffies, btinfo->bt_priority_time +
-			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
-		if (btinfo->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
-			DPRINTF(sc, ATH_DBG_BTCOEX,
-				"BT priority traffic detected");
-			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
-		} else {
-			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-		}
-
-		btinfo->bt_priority_cnt = 0;
-		btinfo->bt_priority_time = jiffies;
-	}
-}
-
-/*
- * Configures appropriate weight based on stomp type.
- */
-static void ath_btcoex_bt_stomp(struct ath_softc *sc,
-				struct ath_btcoex_info *btinfo,
-				int stomp_type)
-{
-
-	switch (stomp_type) {
-	case ATH_BTCOEX_STOMP_ALL:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_ALL_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_LOW:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_LOW_WLAN_WGHT);
-		break;
-	case ATH_BTCOEX_STOMP_NONE:
-		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
-				      AR_STOMP_NONE_WLAN_WGHT);
-		break;
-	default:
-		DPRINTF(sc, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
-		break;
-	}
-
-	ath9k_hw_btcoex_enable(sc->sc_ah);
-}
-
-/*
- * This is the master bt coex timer which runs for every
- * 45ms, bt traffic will be given priority during 55% of this
- * period while wlan gets remaining 45%
- */
-
-static void ath_btcoex_period_timer(unsigned long data)
-{
-	struct ath_softc *sc = (struct ath_softc *) data;
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
-
-	ath_detect_bt_priority(sc);
-
-	spin_lock_bh(&btinfo->btcoex_lock);
-
-	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
-
-	spin_unlock_bh(&btinfo->btcoex_lock);
-
-	if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
-		if (btinfo->hw_timer_enabled)
-			ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
-
-		ath_gen_timer_start(sc->sc_ah,
-			btinfo->no_stomp_timer,
-			(ath9k_hw_gettsf32(sc->sc_ah) +
-				btinfo->btcoex_no_stomp),
-				btinfo->btcoex_no_stomp * 10);
-		btinfo->hw_timer_enabled = true;
-	}
-
-	mod_timer(&btinfo->period_timer, jiffies +
-				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
-}
-
-/*
- * Generic tsf based hw timer which configures weight
- * registers to time slice between wlan and bt traffic
- */
-
-static void ath_btcoex_no_stomp_timer(void *arg)
-{
-	struct ath_softc *sc = (struct ath_softc *)arg;
-	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
-
-	DPRINTF(sc, ATH_DBG_BTCOEX, "no stomp timer running \n");
-
-	spin_lock_bh(&btinfo->btcoex_lock);
-
-	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
-		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
-	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
-
-	spin_unlock_bh(&btinfo->btcoex_lock);
-}
-
-static int ath_init_btcoex_info(struct ath_hw *hw,
-				struct ath_btcoex_info *btcoex_info)
+void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
 {
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+	const struct ath_btcoex_config ath_bt_config = {
+		.bt_time_extend = 0,
+		.bt_txstate_extend = true,
+		.bt_txframe_extend = true,
+		.bt_mode = ATH_BT_COEX_MODE_SLOTTED,
+		.bt_quiet_collision = true,
+		.bt_rxclear_polarity = true,
+		.bt_priority_time = 2,
+		.bt_first_slot_time = 5,
+		.bt_hold_rx_clear = true,
+	};
 	u32 i;
-	int qnum;
 
-	qnum = ath_tx_get_qnum(hw->ah_sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
-
-	btcoex_info->bt_coex_mode =
-		(btcoex_info->bt_coex_mode & AR_BT_QCU_THRESH) |
+	btcoex_hw->bt_coex_mode =
+		(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
 		SM(ath_bt_config.bt_time_extend, AR_BT_TIME_EXTEND) |
 		SM(ath_bt_config.bt_txstate_extend, AR_BT_TXSTATE_EXTEND) |
 		SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
@@ -174,167 +87,141 @@ static int ath_init_btcoex_info(struct a
 		SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
 		SM(qnum, AR_BT_QCU_THRESH);
 
-	btcoex_info->bt_coex_mode2 =
+	btcoex_hw->bt_coex_mode2 =
 		SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
 		SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
 		AR_BT_DISABLE_BT_ANT;
 
-	btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
-
-	btcoex_info->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
-
-	btcoex_info->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
-		btcoex_info->btcoex_period / 100;
-
 	for (i = 0; i < 32; i++)
-		hw->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
+		ah->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
+}
+EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
 
-	setup_timer(&btcoex_info->period_timer, ath_btcoex_period_timer,
-			(unsigned long) hw->ah_sc);
+void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
+{
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(hw,
-			ath_btcoex_no_stomp_timer,
-			ath_btcoex_no_stomp_timer,
-			(void *)hw->ah_sc, AR_FIRST_NDP_TIMER);
+	/* connect bt_active to baseband */
+	REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+		     AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
 
-	if (btcoex_info->no_stomp_timer == NULL)
-		return -ENOMEM;
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
 
-	spin_lock_init(&btcoex_info->btcoex_lock);
+	/* Set input mux for bt_active to gpio pin */
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+		      AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+		      btcoex_hw->btactive_gpio);
 
-	return 0;
+	/* Configure the desired gpio port for input */
+	ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btactive_gpio);
 }
+EXPORT_SYMBOL(ath9k_hw_btcoex_init_2wire);
 
-int ath9k_hw_btcoex_init(struct ath_hw *ah)
+void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
-	int ret = 0;
-
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
-		/* connect bt_active to baseband */
-		REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
-				 AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+	/* btcoex 3-wire */
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+			(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
+			 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
 
-		/* Set input mux for bt_active to gpio pin */
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-				btcoex_info->btactive_gpio);
+	/* Set input mux for bt_prority_async and
+	 *                  bt_active_async to GPIO pins */
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+			AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+			btcoex_hw->btactive_gpio);
 
-		/* Configure the desired gpio port for input */
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
-	} else {
-		/* btcoex 3-wire */
-		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
-				 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
+	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+			AR_GPIO_INPUT_MUX1_BT_PRIORITY,
+			btcoex_hw->btpriority_gpio);
 
-		/* Set input mux for bt_prority_async and
-		 *                  bt_active_async to GPIO pins */
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-				btcoex_info->btactive_gpio);
+	/* Configure the desired GPIO ports for input */
 
-		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-				AR_GPIO_INPUT_MUX1_BT_PRIORITY,
-				btcoex_info->btpriority_gpio);
+	ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btactive_gpio);
+	ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btpriority_gpio);
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);
 
-		/* Configure the desired GPIO ports for input */
+static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
+{
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
-		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
+	/* Configure the desired GPIO port for TX_FRAME output */
+	ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
+			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
 
-		ret = ath_init_btcoex_info(ah, btcoex_info);
-	}
+void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
+				u32 bt_weight,
+				u32 wlan_weight)
+{
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	return ret;
+	btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+				     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
 }
+EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
 
-void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
-		/* Configure the desired GPIO port for TX_FRAME output */
-		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
-				AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
-	} else {
-		/*
-		 * Program coex mode and weight registers to
-		 * enable coex 3-wire
-		 */
-		REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_info->bt_coex_mode);
-		REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_info->bt_coex_weights);
-		REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_info->bt_coex_mode2);
+	/*
+	 * Program coex mode and weight registers to
+	 * enable coex 3-wire
+	 */
+	REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
+	REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
+	REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
 
-		REG_RMW_FIELD(ah, AR_QUIET1,
-				AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
-		REG_RMW_FIELD(ah, AR_PCU_MISC,
-				AR_PCU_BT_ANT_PREVENT_RX, 0);
+	REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+	REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
 
-		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
-				AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+	ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
+			    AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+}
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+
+	switch (btcoex_hw->scheme) {
+	case ATH_BTCOEX_CFG_NONE:
+		break;
+	case ATH_BTCOEX_CFG_2WIRE:
+		ath9k_hw_btcoex_enable_2wire(ah);
+		break;
+	case ATH_BTCOEX_CFG_3WIRE:
+		ath9k_hw_btcoex_enable_3wire(ah);
+		break;
 	}
 
 	REG_RMW(ah, AR_GPIO_PDPU,
-		(0x2 << (btcoex_info->btactive_gpio * 2)),
-		(0x3 << (btcoex_info->btactive_gpio * 2)));
+		(0x2 << (btcoex_hw->btactive_gpio * 2)),
+		(0x3 << (btcoex_hw->btactive_gpio * 2)));
 
-	ah->ah_sc->sc_flags |= SC_OP_BTCOEX_ENABLED;
+	ah->btcoex_hw.enabled = true;
 }
+EXPORT_SYMBOL(ath9k_hw_btcoex_enable);
 
 void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 {
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	ath9k_hw_set_gpio(ah, btcoex_info->wlanactive_gpio, 0);
+	ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);
 
-	ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+	ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
 			AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 
-	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) {
+	if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
 		REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
 		REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
 		REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
 	}
 
-	ah->ah_sc->sc_flags &= ~SC_OP_BTCOEX_ENABLED;
-}
-
-/*
- * Pause btcoex timer and bt duty cycle timer
- */
-void ath_btcoex_timer_pause(struct ath_softc *sc,
-			    struct ath_btcoex_info *btinfo)
-{
-
-	del_timer_sync(&btinfo->period_timer);
-
-	if (btinfo->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
-
-	btinfo->hw_timer_enabled = false;
-}
-
-/*
- * (Re)start btcoex timers
- */
-void ath_btcoex_timer_resume(struct ath_softc *sc,
-			     struct ath_btcoex_info *btinfo)
-{
-
-	DPRINTF(sc, ATH_DBG_BTCOEX, "Starting btcoex timers");
-
-	/* make sure duty cycle timer is also stopped when resuming */
-	if (btinfo->hw_timer_enabled)
-		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
-
-	btinfo->bt_priority_cnt = 0;
-	btinfo->bt_priority_time = jiffies;
-	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
-
-	mod_timer(&btinfo->period_timer, jiffies);
+	ah->btcoex_hw.enabled = false;
 }
+EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/btcoex.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,8 @@
 #ifndef BTCOEX_H
 #define BTCOEX_H
 
+#include "hw.h"
+
 #define ATH_WLANACTIVE_GPIO	5
 #define ATH_BTACTIVE_GPIO	6
 #define ATH_BTPRIORITY_GPIO	7
@@ -34,67 +36,25 @@ enum ath_btcoex_scheme {
 	ATH_BTCOEX_CFG_3WIRE,
 };
 
-enum ath_stomp_type {
-	ATH_BTCOEX_NO_STOMP,
-	ATH_BTCOEX_STOMP_ALL,
-	ATH_BTCOEX_STOMP_LOW,
-	ATH_BTCOEX_STOMP_NONE
-};
-
-enum ath_bt_mode {
-	ATH_BT_COEX_MODE_LEGACY,	/* legacy rx_clear mode */
-	ATH_BT_COEX_MODE_UNSLOTTED,	/* untimed/unslotted mode */
-	ATH_BT_COEX_MODE_SLOTTED,	/* slotted mode */
-	ATH_BT_COEX_MODE_DISALBED,	/* coexistence disabled */
-};
-
-struct ath_btcoex_config {
-	u8 bt_time_extend;
-	bool bt_txstate_extend;
-	bool bt_txframe_extend;
-	enum ath_bt_mode bt_mode; /* coexistence mode */
-	bool bt_quiet_collision;
-	bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
-	u8 bt_priority_time;
-	u8 bt_first_slot_time;
-	bool bt_hold_rx_clear;
-};
-
-struct ath_btcoex_info {
-	enum ath_btcoex_scheme btcoex_scheme;
+struct ath_btcoex_hw {
+	enum ath_btcoex_scheme scheme;
+	bool enabled;
 	u8 wlanactive_gpio;
 	u8 btactive_gpio;
 	u8 btpriority_gpio;
-	u8 bt_duty_cycle; 	/* BT duty cycle in percentage */
-	int bt_stomp_type; 	/* Types of BT stomping */
 	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
 	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
 	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
-	u32 btcoex_no_stomp;   /* in usec */
-	u32 btcoex_period;     	/* in usec */
-	u32 bt_priority_cnt;
-	unsigned long bt_priority_time;
-	bool hw_timer_enabled;
-	spinlock_t btcoex_lock;
-	struct timer_list period_timer;      /* Timer for BT period */
-	struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
 };
 
-bool ath_btcoex_supported(u16 subsysid);
-int ath9k_hw_btcoex_init(struct ath_hw *ah);
+bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
+void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
+void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
+void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
+void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
+				u32 bt_weight,
+				u32 wlan_weight);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
-void ath_btcoex_timer_resume(struct ath_softc *sc,
-			     struct ath_btcoex_info *btinfo);
-void ath_btcoex_timer_pause(struct ath_softc *sc,
-			    struct ath_btcoex_info *btinfo);
-
-static inline void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
-					 u32 bt_weight,
-					 u32 wlan_weight)
-{
-	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
-				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
-}
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/calib.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/calib.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/calib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/calib.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 /* We can tune this as we go by monitoring really low values */
 #define ATH9K_NF_TOO_LOW	-60
@@ -26,11 +26,11 @@
 static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
 {
 	if (nf > ATH9K_NF_TOO_LOW) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"noise floor value detected (%d) is "
-			"lower than what we think is a "
-			"reasonable value (%d)\n",
-			nf, ATH9K_NF_TOO_LOW);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "noise floor value detected (%d) is "
+			  "lower than what we think is a "
+			  "reasonable value (%d)\n",
+			  nf, ATH9K_NF_TOO_LOW);
 		return false;
 	}
 	return true;
@@ -89,6 +89,7 @@ static void ath9k_hw_update_nfcal_hist_b
 static void ath9k_hw_do_getnf(struct ath_hw *ah,
 			      int16_t nfarray[NUM_NF_READINGS])
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int16_t nf;
 
 	if (AR_SREV_9280_10_OR_LATER(ah))
@@ -98,8 +99,8 @@ static void ath9k_hw_do_getnf(struct ath
 
 	if (nf & 0x100)
 		nf = 0 - ((nf ^ 0x1ff) + 1);
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-		"NF calibrated [ctl] [chain 0] is %d\n", nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ctl] [chain 0] is %d\n", nf);
 	nfarray[0] = nf;
 
 	if (!AR_SREV_9285(ah)) {
@@ -112,8 +113,8 @@ static void ath9k_hw_do_getnf(struct ath
 
 		if (nf & 0x100)
 			nf = 0 - ((nf ^ 0x1ff) + 1);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"NF calibrated [ctl] [chain 1] is %d\n", nf);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "NF calibrated [ctl] [chain 1] is %d\n", nf);
 		nfarray[1] = nf;
 
 		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
@@ -121,8 +122,8 @@ static void ath9k_hw_do_getnf(struct ath
 					AR_PHY_CH2_MINCCA_PWR);
 			if (nf & 0x100)
 				nf = 0 - ((nf ^ 0x1ff) + 1);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"NF calibrated [ctl] [chain 2] is %d\n", nf);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "NF calibrated [ctl] [chain 2] is %d\n", nf);
 			nfarray[2] = nf;
 		}
 	}
@@ -136,8 +137,8 @@ static void ath9k_hw_do_getnf(struct ath
 
 	if (nf & 0x100)
 		nf = 0 - ((nf ^ 0x1ff) + 1);
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-		"NF calibrated [ext] [chain 0] is %d\n", nf);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "NF calibrated [ext] [chain 0] is %d\n", nf);
 	nfarray[3] = nf;
 
 	if (!AR_SREV_9285(ah)) {
@@ -150,8 +151,8 @@ static void ath9k_hw_do_getnf(struct ath
 
 		if (nf & 0x100)
 			nf = 0 - ((nf ^ 0x1ff) + 1);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"NF calibrated [ext] [chain 1] is %d\n", nf);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "NF calibrated [ext] [chain 1] is %d\n", nf);
 		nfarray[4] = nf;
 
 		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
@@ -159,8 +160,8 @@ static void ath9k_hw_do_getnf(struct ath
 					AR_PHY_CH2_EXT_MINCCA_PWR);
 			if (nf & 0x100)
 				nf = 0 - ((nf ^ 0x1ff) + 1);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"NF calibrated [ext] [chain 2] is %d\n", nf);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "NF calibrated [ext] [chain 2] is %d\n", nf);
 			nfarray[5] = nf;
 		}
 	}
@@ -188,6 +189,8 @@ static bool getNoiseFloorThresh(struct a
 static void ath9k_hw_setup_calibration(struct ath_hw *ah,
 				       struct ath9k_cal_list *currCal)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+
 	REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
 		      AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
 		      currCal->calData->calCountMax);
@@ -195,23 +198,23 @@ static void ath9k_hw_setup_calibration(s
 	switch (currCal->calData->calType) {
 	case IQ_MISMATCH_CAL:
 		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"starting IQ Mismatch Calibration\n");
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting IQ Mismatch Calibration\n");
 		break;
 	case ADC_GAIN_CAL:
 		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"starting ADC Gain Calibration\n");
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting ADC Gain Calibration\n");
 		break;
 	case ADC_DC_CAL:
 		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"starting ADC DC Calibration\n");
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting ADC DC Calibration\n");
 		break;
 	case ADC_DC_INIT_CAL:
 		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"starting Init ADC DC Calibration\n");
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "starting Init ADC DC Calibration\n");
 		break;
 	}
 
@@ -278,7 +281,7 @@ static bool ath9k_hw_per_calibration(str
 static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
 				     enum ath9k_cal_types calType)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 
 	switch (calType & ah->supp_cals) {
 	case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
@@ -304,11 +307,11 @@ static void ath9k_hw_iqcal_collect(struc
 			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
 		ah->totalIqCorrMeas[i] +=
 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-			ah->cal_samples, i, ah->totalPowerMeasI[i],
-			ah->totalPowerMeasQ[i],
-			ah->totalIqCorrMeas[i]);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+			  ah->cal_samples, i, ah->totalPowerMeasI[i],
+			  ah->totalPowerMeasQ[i],
+			  ah->totalIqCorrMeas[i]);
 	}
 }
 
@@ -326,14 +329,14 @@ static void ath9k_hw_adc_gaincal_collect
 		ah->totalAdcQEvenPhase[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-			"oddq=0x%08x; evenq=0x%08x;\n",
-			ah->cal_samples, i,
-			ah->totalAdcIOddPhase[i],
-			ah->totalAdcIEvenPhase[i],
-			ah->totalAdcQOddPhase[i],
-			ah->totalAdcQEvenPhase[i]);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+			  "oddq=0x%08x; evenq=0x%08x;\n",
+			  ah->cal_samples, i,
+			  ah->totalAdcIOddPhase[i],
+			  ah->totalAdcIEvenPhase[i],
+			  ah->totalAdcQOddPhase[i],
+			  ah->totalAdcQEvenPhase[i]);
 	}
 }
 
@@ -351,19 +354,20 @@ static void ath9k_hw_adc_dccal_collect(s
 		ah->totalAdcDcOffsetQEvenPhase[i] +=
 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-			"oddq=0x%08x; evenq=0x%08x;\n",
-			ah->cal_samples, i,
-			ah->totalAdcDcOffsetIOddPhase[i],
-			ah->totalAdcDcOffsetIEvenPhase[i],
-			ah->totalAdcDcOffsetQOddPhase[i],
-			ah->totalAdcDcOffsetQEvenPhase[i]);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+			  "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+			  "oddq=0x%08x; evenq=0x%08x;\n",
+			  ah->cal_samples, i,
+			  ah->totalAdcDcOffsetIOddPhase[i],
+			  ah->totalAdcDcOffsetIEvenPhase[i],
+			  ah->totalAdcDcOffsetQOddPhase[i],
+			  ah->totalAdcDcOffsetQEvenPhase[i]);
 	}
 }
 
 static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 powerMeasQ, powerMeasI, iqCorrMeas;
 	u32 qCoffDenom, iCoffDenom;
 	int32_t qCoff, iCoff;
@@ -374,13 +378,13 @@ static void ath9k_hw_iqcalibrate(struct
 		powerMeasQ = ah->totalPowerMeasQ[i];
 		iqCorrMeas = ah->totalIqCorrMeas[i];
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Starting IQ Cal and Correction for Chain %d\n",
-			i);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Starting IQ Cal and Correction for Chain %d\n",
+			  i);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Orignal: Chn %diq_corr_meas = 0x%08x\n",
-			i, ah->totalIqCorrMeas[i]);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+			  i, ah->totalIqCorrMeas[i]);
 
 		iqCorrNeg = 0;
 
@@ -389,27 +393,28 @@ static void ath9k_hw_iqcalibrate(struct
 			iqCorrNeg = 1;
 		}
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
-			iqCorrNeg);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+		ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+			  iqCorrNeg);
 
 		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
 		qCoffDenom = powerMeasQ / 64;
 
-		if (powerMeasQ != 0) {
+		if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
+		    (qCoffDenom != 0)) {
 			iCoff = iqCorrMeas / iCoffDenom;
 			qCoff = powerMeasI / qCoffDenom - 64;
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"Chn %d iCoff = 0x%08x\n", i, iCoff);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"Chn %d qCoff = 0x%08x\n", i, qCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d iCoff = 0x%08x\n", i, iCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d qCoff = 0x%08x\n", i, qCoff);
 
 			iCoff = iCoff & 0x3f;
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
 			if (iqCorrNeg == 0x0)
 				iCoff = 0x40 - iCoff;
 
@@ -418,9 +423,9 @@ static void ath9k_hw_iqcalibrate(struct
 			else if (qCoff <= -16)
 				qCoff = 16;
 
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
-				i, iCoff, qCoff);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+				  i, iCoff, qCoff);
 
 			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 				      AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
@@ -428,9 +433,9 @@ static void ath9k_hw_iqcalibrate(struct
 			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
 				      AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
 				      qCoff);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"IQ Cal and Correction done for Chain %d\n",
-				i);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "IQ Cal and Correction done for Chain %d\n",
+				  i);
 		}
 	}
 
@@ -440,6 +445,7 @@ static void ath9k_hw_iqcalibrate(struct
 
 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
 	u32 qGainMismatch, iGainMismatch, val, i;
 
@@ -449,21 +455,21 @@ static void ath9k_hw_adc_gaincal_calibra
 		qOddMeasOffset = ah->totalAdcQOddPhase[i];
 		qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Starting ADC Gain Cal for Chain %d\n", i);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Starting ADC Gain Cal for Chain %d\n", i);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-			iOddMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_even_i = 0x%08x\n", i,
-			iEvenMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-			qOddMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_even_q = 0x%08x\n", i,
-			qEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+			  iOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+			  iEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+			  qOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+			  qEvenMeasOffset);
 
 		if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
 			iGainMismatch =
@@ -473,20 +479,20 @@ static void ath9k_hw_adc_gaincal_calibra
 				((qOddMeasOffset * 32) /
 				 qEvenMeasOffset) & 0x3f;
 
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"Chn %d gain_mismatch_i = 0x%08x\n", i,
-				iGainMismatch);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"Chn %d gain_mismatch_q = 0x%08x\n", i,
-				qGainMismatch);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d gain_mismatch_i = 0x%08x\n", i,
+				  iGainMismatch);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "Chn %d gain_mismatch_q = 0x%08x\n", i,
+				  qGainMismatch);
 
 			val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 			val &= 0xfffff000;
 			val |= (qGainMismatch) | (iGainMismatch << 6);
 			REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"ADC Gain Cal done for Chain %d\n", i);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "ADC Gain Cal done for Chain %d\n", i);
 		}
 	}
 
@@ -497,6 +503,7 @@ static void ath9k_hw_adc_gaincal_calibra
 
 static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 iOddMeasOffset, iEvenMeasOffset, val, i;
 	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
 	const struct ath9k_percal_data *calData =
@@ -510,41 +517,41 @@ static void ath9k_hw_adc_dccal_calibrate
 		qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
 		qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Starting ADC DC Offset Cal for Chain %d\n", i);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			   "Starting ADC DC Offset Cal for Chain %d\n", i);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_odd_i = %d\n", i,
-			iOddMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_even_i = %d\n", i,
-			iEvenMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_odd_q = %d\n", i,
-			qOddMeasOffset);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d pwr_meas_even_q = %d\n", i,
-			qEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_i = %d\n", i,
+			  iOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_i = %d\n", i,
+			  iEvenMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_odd_q = %d\n", i,
+			  qOddMeasOffset);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d pwr_meas_even_q = %d\n", i,
+			  qEvenMeasOffset);
 
 		iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
 			       numSamples) & 0x1ff;
 		qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
 			       numSamples) & 0x1ff;
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-			iDcMismatch);
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
-			qDcMismatch);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+			  iDcMismatch);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+			  qDcMismatch);
 
 		val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
 		val &= 0xc0000fff;
 		val |= (qDcMismatch << 12) | (iDcMismatch << 21);
 		REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"ADC DC Offset Cal done for Chain %d\n", i);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "ADC DC Offset Cal done for Chain %d\n", i);
 	}
 
 	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
@@ -555,7 +562,8 @@ static void ath9k_hw_adc_dccal_calibrate
 /* This is done for the currently configured channel */
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_conf *conf = &common->hw->conf;
 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
 
 	if (!ah->curchan)
@@ -568,24 +576,25 @@ bool ath9k_hw_reset_calvalid(struct ath_
 		return true;
 
 	if (currCal->calState != CAL_DONE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"Calibration state incorrect, %d\n",
-			currCal->calState);
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "Calibration state incorrect, %d\n",
+			  currCal->calState);
 		return true;
 	}
 
 	if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
 		return true;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-		"Resetting Cal %d state for channel %u\n",
-		currCal->calData->calType, conf->channel->center_freq);
+	ath_print(common, ATH_DBG_CALIBRATE,
+		  "Resetting Cal %d state for channel %u\n",
+		  currCal->calData->calType, conf->channel->center_freq);
 
 	ah->curchan->CalValid &= ~currCal->calData->calType;
 	currCal->calState = CAL_WAITING;
 
 	return false;
 }
+EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
 
 void ath9k_hw_start_nfcal(struct ath_hw *ah)
 {
@@ -645,11 +654,11 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 
-	for (j = 0; j < 1000; j++) {
+	for (j = 0; j < 5; j++) {
 		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
 		     AR_PHY_AGC_CONTROL_NF) == 0)
 			break;
-		udelay(10);
+		udelay(50);
 	}
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
@@ -665,6 +674,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
 int16_t ath9k_hw_getnf(struct ath_hw *ah,
 		       struct ath9k_channel *chan)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int16_t nf, nfThresh;
 	int16_t nfarray[NUM_NF_READINGS] = { 0 };
 	struct ath9k_nfcal_hist *h;
@@ -672,8 +682,8 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
 
 	chan->channelFlags &= (~CHANNEL_CW_INT);
 	if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"NF did not complete in calibration window\n");
+		ath_print(common, ATH_DBG_CALIBRATE,
+			  "NF did not complete in calibration window\n");
 		nf = 0;
 		chan->rawNoiseFloor = nf;
 		return chan->rawNoiseFloor;
@@ -682,10 +692,10 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
 		nf = nfarray[0];
 		if (getNoiseFloorThresh(ah, c->band, &nfThresh)
 		    && nf > nfThresh) {
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"noise floor failed detected; "
-				"detected %d, threshold %d\n",
-				nf, nfThresh);
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "noise floor failed detected; "
+				  "detected %d, threshold %d\n",
+				  nf, nfThresh);
 			chan->channelFlags |= CHANNEL_CW_INT;
 		}
 	}
@@ -737,51 +747,73 @@ s16 ath9k_hw_getchan_noise(struct ath_hw
 
 	return nf;
 }
+EXPORT_SYMBOL(ath9k_hw_getchan_noise);
 
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
 {
-	u32 rddata, i;
-	int delta, currPDADC, regval, slope;
+	u32 rddata;
+	int32_t delta, currPDADC, slope;
 
 	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 
+	if (ah->initPDADC == 0 || currPDADC == 0) {
+		/*
+		 * Zero value indicates that no frames have been transmitted yet,
+		 * can't do temperature compensation until frames are transmitted.
+		 */
+		return;
+	} else {
+		slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
+
+		if (slope == 0) { /* to avoid divide by zero case */
+			delta = 0;
+		} else {
+			delta = ((currPDADC - ah->initPDADC)*4) / slope;
+		}
+		REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+		REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+	}
+}
+
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+{
+	u32 rddata, i;
+	int delta, currPDADC, regval;
 
 	if (OLC_FOR_AR9287_10_LATER) {
+		ath9k_olc_temp_compensation_9287(ah);
+	} else {
+		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
 		if (ah->initPDADC == 0 || currPDADC == 0) {
 			return;
 		} else {
-			slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
-			if (slope == 0)
-				delta = 0;
+			if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+				delta = (currPDADC - ah->initPDADC + 4) / 8;
 			else
-				delta = ((currPDADC - ah->initPDADC)*4) / slope;
-			REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
-					AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-			REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
-					AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
-		}
-	} else {
-		if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-			delta = (currPDADC - ah->initPDADC + 4) / 8;
-		else
-			delta = (currPDADC - ah->initPDADC + 5) / 10;
+				delta = (currPDADC - ah->initPDADC + 5) / 10;
 
-		if (delta != ah->PDADCdelta) {
-			ah->PDADCdelta = delta;
-			for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-				regval = ah->originalGain[i] - delta;
-				if (regval < 0)
-					regval = 0;
+			if (delta != ah->PDADCdelta) {
+				ah->PDADCdelta = delta;
+				for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+					regval = ah->originalGain[i] - delta;
+					if (regval < 0)
+						regval = 0;
 
-				REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
-						AR_PHY_TX_GAIN, regval);
+					REG_RMW_FIELD(ah,
+						      AR_PHY_TX_GAIN_TBL1 + i * 4,
+						      AR_PHY_TX_GAIN, regval);
+				}
 			}
 		}
 	}
 }
 
-static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)
+static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 	u32 regVal;
 	unsigned int i;
@@ -845,7 +877,7 @@ static void ath9k_hw_9271_pa_cal(struct
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
 
 	/* find off_6_1; */
-	for (i = 6; i >= 0; i--) {
+	for (i = 6; i > 0; i--) {
 		regVal = REG_READ(ah, 0x7834);
 		regVal |= (1 << (20 + i));
 		REG_WRITE(ah, 0x7834, regVal);
@@ -857,10 +889,19 @@ static void ath9k_hw_9271_pa_cal(struct
 		REG_WRITE(ah, 0x7834, regVal);
 	}
 
-	/*  Empirical offset correction  */
-#if 0
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20);
-#endif
+	regVal = (regVal >>20) & 0x7f;
+
+	/* Update PA cal info */
+	if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
+		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+			ah->pacal_info.max_skipcount =
+				2 * ah->pacal_info.max_skipcount;
+		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+	} else {
+		ah->pacal_info.max_skipcount = 1;
+		ah->pacal_info.skipcount = 0;
+		ah->pacal_info.prev_offset = regVal;
+	}
 
 	regVal = REG_READ(ah, 0x7834);
 	regVal |= 0x1;
@@ -875,7 +916,7 @@ static void ath9k_hw_9271_pa_cal(struct
 
 static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
 {
-
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 regVal;
 	int i, offset, offs_6_1, offs_0;
 	u32 ccomp_org, reg_field;
@@ -889,7 +930,7 @@ static inline void ath9k_hw_9285_pa_cal(
 		{ 0x7838, 0 },
 	};
 
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+	ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
 
 	/* PA CAL is not needed for high power solution */
 	if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
@@ -1011,7 +1052,7 @@ bool ath9k_hw_calibrate(struct ath_hw *a
 	if (longcal) {
 		/* Do periodic PAOffset Cal */
 		if (AR_SREV_9271(ah))
-			ath9k_hw_9271_pa_cal(ah);
+			ath9k_hw_9271_pa_cal(ah, false);
 		else if (AR_SREV_9285_11_OR_LATER(ah)) {
 			if (!ah->pacal_info.skipcount)
 				ath9k_hw_9285_pa_cal(ah, false);
@@ -1036,9 +1077,13 @@ bool ath9k_hw_calibrate(struct ath_hw *a
 
 	return iscaldone;
 }
+EXPORT_SYMBOL(ath9k_hw_calibrate);
 
+/* Carrier leakage Calibration fix */
 static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+
 	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
 	if (IS_CHAN_HT20(chan)) {
 		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
@@ -1049,9 +1094,9 @@ static bool ar9285_clc(struct ath_hw *ah
 		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
 		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
 				  AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
-				"calibration failed to complete in "
-				"1ms; noisy ??\n");
+			ath_print(common, ATH_DBG_CALIBRATE, "offset "
+				  "calibration failed to complete in "
+				  "1ms; noisy ??\n");
 			return false;
 		}
 		REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
@@ -1064,8 +1109,8 @@ static bool ar9285_clc(struct ath_hw *ah
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
 	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
 			  0, AH_WAIT_TIMEOUT)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
-				"failed to complete in 1ms; noisy ??\n");
+		ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
+			  "failed to complete in 1ms; noisy ??\n");
 		return false;
 	}
 
@@ -1078,7 +1123,9 @@ static bool ar9285_clc(struct ath_hw *ah
 
 bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 {
-	if (AR_SREV_9285_12_OR_LATER(ah)) {
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
 		if (!ar9285_clc(ah, chan))
 			return false;
 	} else {
@@ -1098,9 +1145,9 @@ bool ath9k_hw_init_cal(struct ath_hw *ah
 		/* Poll for offset calibration complete */
 		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
 				   0, AH_WAIT_TIMEOUT)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"offset calibration failed to complete in 1ms; "
-				"noisy environment?\n");
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "offset calibration failed to "
+				  "complete in 1ms; noisy environment?\n");
 			return false;
 		}
 
@@ -1114,7 +1161,9 @@ bool ath9k_hw_init_cal(struct ath_hw *ah
 	}
 
 	/* Do PA Calibration */
-	if (AR_SREV_9285_11_OR_LATER(ah))
+	if (AR_SREV_9271(ah))
+		ath9k_hw_9271_pa_cal(ah, true);
+	else if (AR_SREV_9285_11_OR_LATER(ah))
 		ath9k_hw_9285_pa_cal(ah, true);
 
 	/* Do NF Calibration after DC offset and other calibrations */
@@ -1128,20 +1177,20 @@ bool ath9k_hw_init_cal(struct ath_hw *ah
 		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
 			INIT_CAL(&ah->adcgain_caldata);
 			INSERT_CAL(ah, &ah->adcgain_caldata);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"enabling ADC Gain Calibration.\n");
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling ADC Gain Calibration.\n");
 		}
 		if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
 			INIT_CAL(&ah->adcdc_caldata);
 			INSERT_CAL(ah, &ah->adcdc_caldata);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"enabling ADC DC Calibration.\n");
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling ADC DC Calibration.\n");
 		}
 		if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
 			INIT_CAL(&ah->iq_caldata);
 			INSERT_CAL(ah, &ah->iq_caldata);
-			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-				"enabling IQ Calibration.\n");
+			ath_print(common, ATH_DBG_CALIBRATE,
+				  "enabling IQ Calibration.\n");
 		}
 
 		ah->cal_list_curr = ah->cal_list;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/calib.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/calib.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/calib.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/calib.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,8 @@
 #ifndef CALIB_H
 #define CALIB_H
 
+#include "hw.h"
+
 extern const struct ath9k_percal_data iq_cal_multi_sample;
 extern const struct ath9k_percal_data iq_cal_single_sample;
 extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/common.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/common.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/common.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2009 Atheros Communications 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.
+ */
+
+/*
+ * Module for common driver code between ath9k and ath9k_htc
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "common.h"
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
+MODULE_LICENSE("Dual BSD/GPL");
+
+/* Common RX processing */
+
+/* Assumes you've already done the endian to CPU conversion */
+static bool ath9k_rx_accept(struct ath_common *common,
+			    struct sk_buff *skb,
+			    struct ieee80211_rx_status *rxs,
+			    struct ath_rx_status *rx_stats,
+			    bool *decrypt_error)
+{
+	struct ath_hw *ah = common->ah;
+	struct ieee80211_hdr *hdr;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = hdr->frame_control;
+
+	if (!rx_stats->rs_datalen)
+		return false;
+        /*
+         * rs_status follows rs_datalen so if rs_datalen is too large
+         * we can take a hint that hardware corrupted it, so ignore
+         * those frames.
+         */
+	if (rx_stats->rs_datalen > common->rx_bufsize)
+		return false;
+
+	/*
+	 * rs_more indicates chained descriptors which can be used
+	 * to link buffers together for a sort of scatter-gather
+	 * operation.
+	 *
+	 * The rx_stats->rs_status will not be set until the end of the
+	 * chained descriptors so it can be ignored if rs_more is set. The
+	 * rs_more will be false at the last element of the chained
+	 * descriptors.
+	 */
+	if (!rx_stats->rs_more && rx_stats->rs_status != 0) {
+		if (rx_stats->rs_status & ATH9K_RXERR_CRC)
+			rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
+		if (rx_stats->rs_status & ATH9K_RXERR_PHY)
+			return false;
+
+		if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
+			*decrypt_error = true;
+		} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+			if (ieee80211_is_ctl(fc))
+				/*
+				 * Sometimes, we get invalid
+				 * MIC failures on valid control frames.
+				 * Remove these mic errors.
+				 */
+				rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
+			else
+				rxs->flag |= RX_FLAG_MMIC_ERROR;
+		}
+		/*
+		 * Reject error frames with the exception of
+		 * decryption and MIC failures. For monitor mode,
+		 * we also ignore the CRC error.
+		 */
+		if (ah->opmode == NL80211_IFTYPE_MONITOR) {
+			if (rx_stats->rs_status &
+			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
+			      ATH9K_RXERR_CRC))
+				return false;
+		} else {
+			if (rx_stats->rs_status &
+			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+static u8 ath9k_process_rate(struct ath_common *common,
+			     struct ieee80211_hw *hw,
+			     struct ath_rx_status *rx_stats,
+			     struct ieee80211_rx_status *rxs,
+			     struct sk_buff *skb)
+{
+	struct ieee80211_supported_band *sband;
+	enum ieee80211_band band;
+	unsigned int i = 0;
+
+	band = hw->conf.channel->band;
+	sband = hw->wiphy->bands[band];
+
+	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;
+		return rx_stats->rs_rate & 0x7f;
+	}
+
+	for (i = 0; i < sband->n_bitrates; i++) {
+		if (sband->bitrates[i].hw_value == rx_stats->rs_rate)
+			return i;
+		if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
+			rxs->flag |= RX_FLAG_SHORTPRE;
+			return i;
+		}
+	}
+
+	/* No valid hardware bitrate found -- we should not get here */
+	ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
+		  "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
+	if ((common->debug_mask & ATH_DBG_XMIT))
+		print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len);
+
+        return 0;
+}
+
+static void ath9k_process_rssi(struct ath_common *common,
+			       struct ieee80211_hw *hw,
+			       struct sk_buff *skb,
+			       struct ath_rx_status *rx_stats)
+{
+	struct ath_hw *ah = common->ah;
+	struct ieee80211_sta *sta;
+	struct ieee80211_hdr *hdr;
+	struct ath_node *an;
+	int last_rssi = ATH_RSSI_DUMMY_MARKER;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = hdr->frame_control;
+
+	rcu_read_lock();
+	/*
+	 * XXX: use ieee80211_find_sta! This requires quite a bit of work
+	 * under the current ath9k virtual wiphy implementation as we have
+	 * no way of tying a vif to wiphy. Typically vifs are attached to
+	 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
+	 * wiphy you'd have to iterate over every wiphy and each sdata.
+	 */
+	sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
+	if (sta) {
+		an = (struct ath_node *) sta->drv_priv;
+		if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
+		   !rx_stats->rs_moreaggr)
+			ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
+		last_rssi = an->last_rssi;
+	}
+	rcu_read_unlock();
+
+	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+		rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
+					      ATH_RSSI_EP_MULTIPLIER);
+	if (rx_stats->rs_rssi < 0)
+		rx_stats->rs_rssi = 0;
+
+	/* Update Beacon RSSI, this is used by ANI. */
+	if (ieee80211_is_beacon(fc))
+		ah->stats.avgbrssi = rx_stats->rs_rssi;
+}
+
+/*
+ * For Decrypt or Demic errors, we only mark packet status here and always push
+ * up the frame up to let mac80211 handle the actual error case, be it no
+ * decryption key or real decryption error. This let us keep statistics there.
+ */
+int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
+				struct ieee80211_hw *hw,
+				struct sk_buff *skb,
+				struct ath_rx_status *rx_stats,
+				struct ieee80211_rx_status *rx_status,
+				bool *decrypt_error)
+{
+	struct ath_hw *ah = common->ah;
+
+	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+	if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error))
+		return -EINVAL;
+
+	ath9k_process_rssi(common, hw, skb, rx_stats);
+
+	rx_status->rate_idx = ath9k_process_rate(common, hw,
+						 rx_stats, rx_status, skb);
+	rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp);
+	rx_status->band = hw->conf.channel->band;
+	rx_status->freq = hw->conf.channel->center_freq;
+	rx_status->noise = common->ani.noise_floor;
+	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
+	rx_status->antenna = rx_stats->rs_antenna;
+	rx_status->flag |= RX_FLAG_TSFT;
+
+	return 0;
+}
+EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess);
+
+void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
+				  struct sk_buff *skb,
+				  struct ath_rx_status *rx_stats,
+				  struct ieee80211_rx_status *rxs,
+				  bool decrypt_error)
+{
+	struct ath_hw *ah = common->ah;
+	struct ieee80211_hdr *hdr;
+	int hdrlen, padpos, padsize;
+	u8 keyix;
+	__le16 fc;
+
+	/* see if any padding is done by the hw and remove it */
+	hdr = (struct ieee80211_hdr *) skb->data;
+	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+	fc = hdr->frame_control;
+	padpos = ath9k_cmn_padpos(hdr->frame_control);
+
+	/* The MAC header is padded to have 32-bit boundary if the
+	 * packet payload is non-zero. The general calculation for
+	 * padsize would take into account odd header lengths:
+	 * padsize = (4 - padpos % 4) % 4; However, since only
+	 * even-length headers are used, padding can only be 0 or 2
+	 * bytes and we can optimize this a bit. In addition, we must
+	 * not try to remove padding from short control frames that do
+	 * not have payload. */
+	padsize = padpos & 3;
+	if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
+		memmove(skb->data + padsize, skb->data, padpos);
+		skb_pull(skb, padsize);
+	}
+
+	keyix = rx_stats->rs_keyix;
+
+	if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
+		rxs->flag |= RX_FLAG_DECRYPTED;
+	} else if (ieee80211_has_protected(fc)
+		   && !decrypt_error && skb->len >= hdrlen + 4) {
+		keyix = skb->data[hdrlen + 3] >> 6;
+
+		if (test_bit(keyix, common->keymap))
+			rxs->flag |= RX_FLAG_DECRYPTED;
+	}
+	if (ah->sw_mgmt_crypto &&
+	    (rxs->flag & RX_FLAG_DECRYPTED) &&
+	    ieee80211_is_mgmt(fc))
+		/* Use software decrypt for management frames. */
+		rxs->flag &= ~RX_FLAG_DECRYPTED;
+}
+EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
+
+int ath9k_cmn_padpos(__le16 frame_control)
+{
+	int padpos = 24;
+	if (ieee80211_has_a4(frame_control)) {
+		padpos += ETH_ALEN;
+	}
+	if (ieee80211_is_data_qos(frame_control)) {
+		padpos += IEEE80211_QOS_CTL_LEN;
+	}
+
+	return padpos;
+}
+EXPORT_SYMBOL(ath9k_cmn_padpos);
+
+static int __init ath9k_cmn_init(void)
+{
+	return 0;
+}
+module_init(ath9k_cmn_init);
+
+static void __exit ath9k_cmn_exit(void)
+{
+	return;
+}
+module_exit(ath9k_cmn_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/common.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/common.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/common.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2009 Atheros Communications 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 <net/mac80211.h>
+
+#include "../ath.h"
+#include "../debug.h"
+
+#include "hw.h"
+
+/* Common header for Atheros 802.11n base driver cores */
+
+#define WME_NUM_TID             16
+#define WME_BA_BMP_SIZE         64
+#define WME_MAX_BA              WME_BA_BMP_SIZE
+#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
+
+#define WME_AC_BE   0
+#define WME_AC_BK   1
+#define WME_AC_VI   2
+#define WME_AC_VO   3
+#define WME_NUM_AC  4
+
+#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RSSI_LPF_LEN 		10
+#define RSSI_LPF_THRESHOLD		-20
+#define ATH_RSSI_EP_MULTIPLIER     (1<<7)
+#define ATH_EP_MUL(x, mul)         ((x) * (mul))
+#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
+#define ATH_LPF_RSSI(x, y, len) \
+    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
+#define ATH_RSSI_LPF(x, y) do {                     			\
+    if ((y) >= RSSI_LPF_THRESHOLD)                         		\
+	x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);  	\
+} while (0)
+#define ATH_EP_RND(x, mul) 						\
+	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+
+struct ath_atx_ac {
+	int sched;
+	int qnum;
+	struct list_head list;
+	struct list_head tid_q;
+};
+
+struct ath_buf_state {
+	int bfs_nframes;
+	u16 bfs_al;
+	u16 bfs_frmlen;
+	int bfs_seqno;
+	int bfs_tidno;
+	int bfs_retries;
+	u8 bf_type;
+	u32 bfs_keyix;
+	enum ath9k_key_type bfs_keytype;
+};
+
+struct ath_buf {
+	struct list_head list;
+	struct ath_buf *bf_lastbf;	/* last buf of this unit (a frame or
+					   an aggregate) */
+	struct ath_buf *bf_next;	/* next subframe in the aggregate */
+	struct sk_buff *bf_mpdu;	/* enclosing frame structure */
+	struct ath_desc *bf_desc;	/* virtual addr of desc */
+	dma_addr_t bf_daddr;		/* physical addr of desc */
+	dma_addr_t bf_buf_addr;		/* physical addr of data buffer */
+	bool bf_stale;
+	bool bf_isnullfunc;
+	u16 bf_flags;
+	struct ath_buf_state bf_state;
+	dma_addr_t bf_dmacontext;
+	struct ath_wiphy *aphy;
+};
+
+struct ath_atx_tid {
+	struct list_head list;
+	struct list_head buf_q;
+	struct ath_node *an;
+	struct ath_atx_ac *ac;
+	struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+	u16 seq_start;
+	u16 seq_next;
+	u16 baw_size;
+	int tidno;
+	int baw_head;   /* first un-acked tx buffer */
+	int baw_tail;   /* next unused tx buffer slot */
+	int sched;
+	int paused;
+	u8 state;
+};
+
+struct ath_node {
+	struct ath_common *common;
+	struct ath_atx_tid tid[WME_NUM_TID];
+	struct ath_atx_ac ac[WME_NUM_AC];
+	u16 maxampdu;
+	u8 mpdudensity;
+	int last_rssi;
+};
+
+int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
+				struct ieee80211_hw *hw,
+				struct sk_buff *skb,
+				struct ath_rx_status *rx_stats,
+				struct ieee80211_rx_status *rx_status,
+				bool *decrypt_error);
+
+void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
+				  struct sk_buff *skb,
+				  struct ath_rx_status *rx_stats,
+				  struct ieee80211_rx_status *rxs,
+				  bool decrypt_error);
+
+int ath9k_cmn_padpos(__le16 frame_control);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/debug.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,40 +18,30 @@
 
 #include "ath9k.h"
 
-static unsigned int ath9k_debug = DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
+#define REG_WRITE_D(_ah, _reg, _val) \
+	ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
+#define REG_READ_D(_ah, _reg) \
+	ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
 
 static struct dentry *ath9k_debugfs_root;
 
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
-{
-	if (!sc)
-		return;
-
-	if (sc->debug.debug_mask & dbg_mask) {
-		va_list args;
-
-		va_start(args, fmt);
-		printk(KERN_DEBUG "ath9k: ");
-		vprintk(fmt, args);
-		va_end(args);
-	}
-}
-
 static int ath9k_debugfs_open(struct inode *inode, struct file *file)
 {
 	file->private_data = inode->i_private;
 	return 0;
 }
 
+#ifdef CONFIG_ATH_DEBUG
+
 static ssize_t read_file_debug(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;
 
-	len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
+	len = snprintf(buf, sizeof(buf), "0x%08x\n", common->debug_mask);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -59,6 +49,7 @@ static ssize_t write_file_debug(struct f
 			     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 mask;
 	char buf[32];
 	ssize_t len;
@@ -71,7 +62,7 @@ static ssize_t write_file_debug(struct f
 	if (strict_strtoul(buf, 0, &mask))
 		return -EINVAL;
 
-	sc->debug.debug_mask = mask;
+	common->debug_mask = mask;
 	return count;
 }
 
@@ -82,6 +73,8 @@ static const struct file_operations fops
 	.owner = THIS_MODULE
 };
 
+#endif
+
 static ssize_t read_file_dma(struct file *file, char __user *user_buf,
 			     size_t count, loff_t *ppos)
 {
@@ -95,7 +88,7 @@ static ssize_t read_file_dma(struct file
 
 	ath9k_ps_wakeup(sc);
 
-	REG_WRITE(ah, AR_MACMISC,
+	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)));
@@ -107,7 +100,7 @@ static ssize_t read_file_dma(struct file
 		if (i % 4 == 0)
 			len += snprintf(buf + len, sizeof(buf) - len, "\n");
 
-		val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
+		val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
 		len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
 				i, val[i]);
 	}
@@ -157,9 +150,9 @@ static ssize_t read_file_dma(struct file
 		(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
 
 	len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
-			REG_READ(ah, AR_OBS_BUS_1));
+			REG_READ_D(ah, AR_OBS_BUS_1));
 	len += snprintf(buf + len, sizeof(buf) - len,
-			"AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
+			"AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
 
 	ath9k_ps_restore(sc);
 
@@ -266,18 +259,11 @@ static const struct file_operations fops
 	.owner = THIS_MODULE
 };
 
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
 {
-	struct ath_tx_info_priv *tx_info_priv = NULL;
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_tx_rate *rates = tx_info->status.rates;
-	int final_ts_idx, idx;
 	struct ath_rc_stats *stats;
 
-	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-	final_ts_idx = tx_info_priv->tx.ts_rateindex;
-	idx = rates[final_ts_idx].idx;
-	stats = &sc->debug.stats.rcstats[idx];
+	stats = &sc->debug.stats.rcstats[final_rate];
 	stats->success++;
 }
 
@@ -376,12 +362,12 @@ static ssize_t read_file_wiphy(struct fi
 				aphy->chan_idx, aphy->chan_is_ht);
 	}
 
-	put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
-	put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
+	put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
+	put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"addr: %pM\n", addr);
-	put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
-	put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
+	put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr);
+	put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"addrmask: %pM\n", addr);
 
@@ -568,9 +554,10 @@ static const struct file_operations fops
 	.owner = THIS_MODULE
 };
 
-int ath9k_init_debug(struct ath_softc *sc)
+int ath9k_init_debug(struct ath_hw *ah)
 {
-	sc->debug.debug_mask = ath9k_debug;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
 
 	if (!ath9k_debugfs_root)
 		return -ENOENT;
@@ -580,10 +567,12 @@ int ath9k_init_debug(struct ath_softc *s
 	if (!sc->debug.debugfs_phy)
 		goto err;
 
+#ifdef CONFIG_ATH_DEBUG
 	sc->debug.debugfs_debug = debugfs_create_file("debug",
 		S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
 	if (!sc->debug.debugfs_debug)
 		goto err;
+#endif
 
 	sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
 				       sc->debug.debugfs_phy, sc, &fops_dma);
@@ -619,12 +608,15 @@ int ath9k_init_debug(struct ath_softc *s
 
 	return 0;
 err:
-	ath9k_exit_debug(sc);
+	ath9k_exit_debug(ah);
 	return -ENOMEM;
 }
 
-void ath9k_exit_debug(struct ath_softc *sc)
+void ath9k_exit_debug(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+
 	debugfs_remove(sc->debug.debugfs_xmit);
 	debugfs_remove(sc->debug.debugfs_wiphy);
 	debugfs_remove(sc->debug.debugfs_rcstat);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/debug.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/debug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/debug.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,36 +17,19 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
-enum ATH_DEBUG {
-	ATH_DBG_RESET		= 0x00000001,
-	ATH_DBG_QUEUE		= 0x00000002,
-	ATH_DBG_EEPROM		= 0x00000004,
-	ATH_DBG_CALIBRATE	= 0x00000008,
-	ATH_DBG_INTERRUPT	= 0x00000010,
-	ATH_DBG_REGULATORY	= 0x00000020,
-	ATH_DBG_ANI		= 0x00000040,
-	ATH_DBG_XMIT		= 0x00000080,
-	ATH_DBG_BEACON		= 0x00000100,
-	ATH_DBG_CONFIG		= 0x00000200,
-	ATH_DBG_FATAL		= 0x00000400,
-	ATH_DBG_PS		= 0x00000800,
-	ATH_DBG_HWTIMER		= 0x00001000,
-	ATH_DBG_BTCOEX		= 0x00002000,
-	ATH_DBG_ANY		= 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
+#include "hw.h"
+#include "rc.h"
 
 struct ath_txq;
 struct ath_buf;
 
-#ifdef CONFIG_ATH9K_DEBUG
+#ifdef CONFIG_ATH9K_DEBUGFS
 #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
 #else
 #define TX_STAT_INC(q, c) do { } while (0)
 #endif
 
-#ifdef CONFIG_ATH9K_DEBUG
+#ifdef CONFIG_ATH9K_DEBUGFS
 
 /**
  * struct ath_interrupt_stats - Contains statistics about interrupts
@@ -140,7 +123,6 @@ struct ath_stats {
 };
 
 struct ath9k_debug {
-	int debug_mask;
 	struct dentry *debugfs_phy;
 	struct dentry *debugfs_debug;
 	struct dentry *debugfs_dma;
@@ -151,13 +133,13 @@ struct ath9k_debug {
 	struct ath_stats stats;
 };
 
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
-int ath9k_init_debug(struct ath_softc *sc);
-void ath9k_exit_debug(struct ath_softc *sc);
+int ath9k_init_debug(struct ath_hw *ah);
+void ath9k_exit_debug(struct ath_hw *ah);
+
 int ath9k_debug_create_root(void);
 void ath9k_debug_remove_root(void);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
 		       struct ath_buf *bf);
 void ath_debug_stat_retries(struct ath_softc *sc, int rix,
@@ -165,17 +147,12 @@ void ath_debug_stat_retries(struct ath_s
 
 #else
 
-static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
-			   const char *fmt, ...)
-{
-}
-
-static inline int ath9k_init_debug(struct ath_softc *sc)
+static inline int ath9k_init_debug(struct ath_hw *ah)
 {
 	return 0;
 }
 
-static inline void ath9k_exit_debug(struct ath_softc *sc)
+static inline void ath9k_exit_debug(struct ath_hw *ah)
 {
 }
 
@@ -194,7 +171,7 @@ static inline void ath_debug_stat_interr
 }
 
 static inline void ath_debug_stat_rc(struct ath_softc *sc,
-				     struct sk_buff *skb)
+				     int final_rate)
 {
 }
 
@@ -209,6 +186,6 @@ static inline void ath_debug_stat_retrie
 {
 }
 
-#endif /* CONFIG_ATH9K_DEBUG */
+#endif /* CONFIG_ATH9K_DEBUGFS */
 
 #endif /* DEBUG_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_4k.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_4k.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_4k.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
 {
@@ -29,20 +29,21 @@ static int ath9k_hw_4k_get_eeprom_rev(st
 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
 {
 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+	struct ath_common *common = ath9k_hw_common(ah);
 	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
 	int addr, eep_start_loc = 0;
 
 	eep_start_loc = 64;
 
 	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Reading from EEPROM, not flash\n");
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Reading from EEPROM, not flash\n");
 	}
 
 	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
-		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			       "Unable to read eeprom region \n");
+		if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Unable to read eeprom region \n");
 			return false;
 		}
 		eep_data++;
@@ -55,6 +56,7 @@ static bool ath9k_hw_4k_fill_eeprom(stru
 static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
 {
 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ar5416_eeprom_4k *eep =
 		(struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
 	u16 *eepdata, temp, magic, magic2;
@@ -64,15 +66,15 @@ static int ath9k_hw_4k_check_eeprom(stru
 
 
 	if (!ath9k_hw_use_flash(ah)) {
-		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+		if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
 					 &magic)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Reading Magic # failed\n");
+			ath_print(common, ATH_DBG_FATAL,
+				  "Reading Magic # failed\n");
 			return false;
 		}
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Read Magic = 0x%04X\n", magic);
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Read Magic = 0x%04X\n", magic);
 
 		if (magic != AR5416_EEPROM_MAGIC) {
 			magic2 = swab16(magic);
@@ -87,16 +89,16 @@ static int ath9k_hw_4k_check_eeprom(stru
 					eepdata++;
 				}
 			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"Invalid EEPROM Magic. "
-					"endianness mismatch.\n");
+				ath_print(common, ATH_DBG_FATAL,
+					  "Invalid EEPROM Magic. "
+					  "endianness mismatch.\n");
 				return -EINVAL;
 			}
 		}
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-		need_swap ? "True" : "False");
+	ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+		  need_swap ? "True" : "False");
 
 	if (need_swap)
 		el = swab16(ah->eeprom.map4k.baseEepHeader.length);
@@ -117,8 +119,8 @@ static int ath9k_hw_4k_check_eeprom(stru
 		u32 integer;
 		u16 word;
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing\n");
+		ath_print(common, ATH_DBG_EEPROM,
+			  "EEPROM Endianness is not native.. Changing\n");
 
 		word = swab16(eep->baseEepHeader.length);
 		eep->baseEepHeader.length = word;
@@ -160,9 +162,9 @@ static int ath9k_hw_4k_check_eeprom(stru
 
 	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
 	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-			sum, ah->eep_ops->get_eeprom_ver(ah));
+		ath_print(common, ATH_DBG_FATAL,
+			  "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+			  sum, ah->eep_ops->get_eeprom_ver(ah));
 		return -EINVAL;
 	}
 
@@ -208,6 +210,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct
 		return pBase->rxMask;
 	case EEP_FRAC_N_5G:
 		return 0;
+	case EEP_PWR_TABLE_OFFSET:
+		return AR5416_PWR_TABLE_OFFSET_DB;
 	default:
 		return 0;
 	}
@@ -385,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_ta
 				  struct ath9k_channel *chan,
 				  int16_t *pTxPowerIndexOffset)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
 	struct cal_data_per_freq_4k *pRawDataset;
 	u8 *pCalBChans = NULL;
@@ -470,21 +475,21 @@ static void ath9k_hw_set_4k_power_cal_ta
 					((pdadcValues[4 * j + 3] & 0xFF) << 24);
 				REG_WRITE(ah, regOffset, reg32);
 
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC (%d,%4x): %4.4x %8.8x\n",
-					i, regChainOffset, regOffset,
-					reg32);
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC: Chain %d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d |\n",
-					i, 4 * j, pdadcValues[4 * j],
-					4 * j + 1, pdadcValues[4 * j + 1],
-					4 * j + 2, pdadcValues[4 * j + 2],
-					4 * j + 3,
-					pdadcValues[4 * j + 3]);
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PDADC (%d,%4x): %4.4x %8.8x\n",
+					  i, regChainOffset, regOffset,
+					  reg32);
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PDADC: Chain %d | "
+					  "PDADC %3d Value %3d | "
+					  "PDADC %3d Value %3d | "
+					  "PDADC %3d Value %3d | "
+					  "PDADC %3d Value %3d |\n",
+					  i, 4 * j, pdadcValues[4 * j],
+					  4 * j + 1, pdadcValues[4 * j + 1],
+					  4 * j + 2, pdadcValues[4 * j + 2],
+					  4 * j + 3,
+					  pdadcValues[4 * j + 3]);
 
 				regOffset += 4;
 			}
@@ -750,7 +755,7 @@ static void ath9k_hw_4k_set_txpower(stru
 
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
 		for (i = 0; i < Ar5416RateSize; i++)
-			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
 	}
 
 	/* OFDM power per rate */
@@ -1107,6 +1112,10 @@ static void ath9k_hw_4k_set_board_values
 
 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 		      pModal->txEndToRxOn);
+
+	if (AR_SREV_9271_10(ah))
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+			      pModal->txEndToRxOn);
 	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
 		      pModal->thresh62);
 	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
@@ -1148,20 +1157,21 @@ static u16 ath9k_hw_4k_get_spur_channel(
 {
 #define EEP_MAP4K_SPURCHAN \
 	(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	u16 spur_val = AR_NO_SPUR;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Getting spur idx %d is2Ghz. %d val %x\n",
-		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+	ath_print(common, ATH_DBG_ANI,
+		  "Getting spur idx %d is2Ghz. %d val %x\n",
+		  i, is2GHz, ah->config.spurchans[i][is2GHz]);
 
 	switch (ah->config.spurmode) {
 	case SPUR_DISABLE:
 		break;
 	case SPUR_ENABLE_IOCTL:
 		spur_val = ah->config.spurchans[i][is2GHz];
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Getting spur val from new loc. %d\n", spur_val);
+		ath_print(common, ATH_DBG_ANI,
+			  "Getting spur val from new loc. %d\n", spur_val);
 		break;
 	case SPUR_ENABLE_EEPROM:
 		spur_val = EEP_MAP4K_SPURCHAN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_9287.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_9287.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_9287.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_9287.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
 {
@@ -29,20 +29,22 @@ static int ath9k_hw_AR9287_get_eeprom_re
 static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
 {
 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	struct ath_common *common = ath9k_hw_common(ah);
 	u16 *eep_data;
 	int addr, eep_start_loc = AR9287_EEP_START_LOC;
 	eep_data = (u16 *)eep;
 
 	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Reading from EEPROM, not flash\n");
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Reading from EEPROM, not flash\n");
 	}
 
 	for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
 			addr++)	{
-		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"Unable to read eeprom region \n");
+		if (!ath9k_hw_nvram_read(common,
+					 addr + eep_start_loc, eep_data)) {
+			ath_print(common, ATH_DBG_EEPROM,
+				  "Unable to read eeprom region \n");
 			return false;
 		}
 		eep_data++;
@@ -57,17 +59,18 @@ static int ath9k_hw_AR9287_check_eeprom(
 	int i, addr;
 	bool need_swap = false;
 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	if (!ath9k_hw_use_flash(ah)) {
-		if (!ath9k_hw_nvram_read
-		    (ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Reading Magic # failed\n");
+		if (!ath9k_hw_nvram_read(common,
+					 AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+			ath_print(common, ATH_DBG_FATAL,
+				  "Reading Magic # failed\n");
 			return false;
 		}
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"Read Magic = 0x%04X\n", magic);
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Read Magic = 0x%04X\n", magic);
 		if (magic != AR5416_EEPROM_MAGIC) {
 			magic2 = swab16(magic);
 
@@ -83,15 +86,15 @@ static int ath9k_hw_AR9287_check_eeprom(
 					eepdata++;
 				}
 			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"Invalid EEPROM Magic. "
-					"endianness mismatch.\n");
+				ath_print(common, ATH_DBG_FATAL,
+					  "Invalid EEPROM Magic. "
+					  "endianness mismatch.\n");
 				return -EINVAL;
 			}
 		}
 	}
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
-		"True" : "False");
+	ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
+		  "True" : "False");
 
 	if (need_swap)
 		el = swab16(ah->eeprom.map9287.baseEepHeader.length);
@@ -148,9 +151,9 @@ static int ath9k_hw_AR9287_check_eeprom(
 
 	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
 	    || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-			 sum, ah->eep_ops->get_eeprom_ver(ah));
+		ath_print(common, ATH_DBG_FATAL,
+			  "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+			   sum, ah->eep_ops->get_eeprom_ver(ah));
 		return -EINVAL;
 	}
 
@@ -436,6 +439,7 @@ static void ath9k_hw_set_AR9287_power_ca
 						struct ath9k_channel *chan,
 						int16_t *pTxPowerIndexOffset)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct cal_data_per_freq_ar9287 *pRawDataset;
 	struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
 	u8  *pCalBChans = NULL;
@@ -564,24 +568,25 @@ static void ath9k_hw_set_AR9287_power_ca
 						  & 0xFF) << 24) ;
 					REG_WRITE(ah, regOffset, reg32);
 
-					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-						"PDADC (%d,%4x): %4.4x %8.8x\n",
-						i, regChainOffset, regOffset,
-						reg32);
+					ath_print(common, ATH_DBG_EEPROM,
+						  "PDADC (%d,%4x): %4.4x "
+						  "%8.8x\n",
+						  i, regChainOffset, regOffset,
+						  reg32);
 
-					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-						"PDADC: Chain %d | "
-						"PDADC %3d Value %3d | "
-						"PDADC %3d Value %3d | "
-						"PDADC %3d Value %3d | "
-						"PDADC %3d Value %3d |\n",
-						i, 4 * j, pdadcValues[4 * j],
-						4 * j + 1,
-						pdadcValues[4 * j + 1],
-						4 * j + 2,
-						pdadcValues[4 * j + 2],
-						4 * j + 3,
-						pdadcValues[4 * j + 3]);
+					ath_print(common, ATH_DBG_EEPROM,
+						  "PDADC: Chain %d | "
+						  "PDADC %3d Value %3d | "
+						  "PDADC %3d Value %3d | "
+						  "PDADC %3d Value %3d | "
+						  "PDADC %3d Value %3d |\n",
+						  i, 4 * j, pdadcValues[4 * j],
+						  4 * j + 1,
+						  pdadcValues[4 * j + 1],
+						  4 * j + 2,
+						  pdadcValues[4 * j + 2],
+						  4 * j + 3,
+						  pdadcValues[4 * j + 3]);
 
 					regOffset += 4;
 				}
@@ -831,6 +836,7 @@ static void ath9k_hw_AR9287_set_txpower(
 {
 #define INCREASE_MAXPOW_BY_TWO_CHAIN     6
 #define INCREASE_MAXPOW_BY_THREE_CHAIN   10
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
 	struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
@@ -966,8 +972,8 @@ static void ath9k_hw_AR9287_set_txpower(
 			INCREASE_MAXPOW_BY_THREE_CHAIN;
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Invalid chainmask configuration\n");
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Invalid chainmask configuration\n");
 		break;
 	}
 }
@@ -1138,19 +1144,20 @@ static u16 ath9k_hw_AR9287_get_spur_chan
 {
 #define EEP_MAP9287_SPURCHAN \
 	(ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
+	struct ath_common *common = ath9k_hw_common(ah);
 	u16 spur_val = AR_NO_SPUR;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Getting spur idx %d is2Ghz. %d val %x\n",
-		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+	ath_print(common, ATH_DBG_ANI,
+		  "Getting spur idx %d is2Ghz. %d val %x\n",
+		  i, is2GHz, ah->config.spurchans[i][is2GHz]);
 
 	switch (ah->config.spurmode) {
 	case SPUR_DISABLE:
 		break;
 	case SPUR_ENABLE_IOCTL:
 		spur_val = ah->config.spurchans[i][is2GHz];
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		       "Getting spur val from new loc. %d\n", spur_val);
+		ath_print(common, ATH_DBG_ANI,
+			  "Getting spur val from new loc. %d\n", spur_val);
 		break;
 	case SPUR_ENABLE_EEPROM:
 		spur_val = EEP_MAP9287_SPURCHAN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
 {
@@ -83,11 +83,9 @@ bool ath9k_hw_get_lower_upper_index(u8 t
 	return false;
 }
 
-bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
 {
-	struct ath_softc *sc = ah->ah_sc;
-
-	return sc->bus_ops->eeprom_read(ah, off, data);
+	return common->bus_ops->eeprom_read(common, off, data);
 }
 
 void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_def.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_def.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom_def.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom_def.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static void ath9k_get_txgain_index(struct ath_hw *ah,
 		struct ath9k_channel *chan,
@@ -89,14 +89,15 @@ static int ath9k_hw_def_get_eeprom_rev(s
 static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
 {
 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+	struct ath_common *common = ath9k_hw_common(ah);
 	u16 *eep_data = (u16 *)&ah->eeprom.def;
 	int addr, ar5416_eep_start_loc = 0x100;
 
 	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
-		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+		if (!ath9k_hw_nvram_read(common, addr + ar5416_eep_start_loc,
 					 eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Unable to read eeprom region\n");
+			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+				  "Unable to read eeprom region\n");
 			return false;
 		}
 		eep_data++;
@@ -109,19 +110,20 @@ static int ath9k_hw_def_check_eeprom(str
 {
 	struct ar5416_eeprom_def *eep =
 		(struct ar5416_eeprom_def *) &ah->eeprom.def;
+	struct ath_common *common = ath9k_hw_common(ah);
 	u16 *eepdata, temp, magic, magic2;
 	u32 sum = 0, el;
 	bool need_swap = false;
 	int i, addr, size;
 
-	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+	if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+		ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n");
 		return false;
 	}
 
 	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Read Magic = 0x%04X\n", magic);
+		ath_print(common, ATH_DBG_EEPROM,
+			  "Read Magic = 0x%04X\n", magic);
 
 		if (magic != AR5416_EEPROM_MAGIC) {
 			magic2 = swab16(magic);
@@ -137,16 +139,16 @@ static int ath9k_hw_def_check_eeprom(str
 					eepdata++;
 				}
 			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"Invalid EEPROM Magic. "
-					"Endianness mismatch.\n");
+				ath_print(common, ATH_DBG_FATAL,
+					  "Invalid EEPROM Magic. "
+					  "Endianness mismatch.\n");
 				return -EINVAL;
 			}
 		}
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-		need_swap ? "True" : "False");
+	ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
+		  need_swap ? "True" : "False");
 
 	if (need_swap)
 		el = swab16(ah->eeprom.def.baseEepHeader.length);
@@ -167,8 +169,8 @@ static int ath9k_hw_def_check_eeprom(str
 		u32 integer, j;
 		u16 word;
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing.\n");
+		ath_print(common, ATH_DBG_EEPROM,
+			  "EEPROM Endianness is not native.. Changing.\n");
 
 		word = swab16(eep->baseEepHeader.length);
 		eep->baseEepHeader.length = word;
@@ -214,8 +216,8 @@ static int ath9k_hw_def_check_eeprom(str
 
 	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
 	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+		ath_print(common, ATH_DBG_FATAL,
+			  "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
 			sum, ah->eep_ops->get_eeprom_ver(ah));
 		return -EINVAL;
 	}
@@ -289,6 +291,11 @@ static u32 ath9k_hw_def_get_eeprom(struc
 			return pBase->frac_n_5g;
 		else
 			return 0;
+	case EEP_PWR_TABLE_OFFSET:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21)
+			return pBase->pwr_table_offset;
+		else
+			return AR5416_PWR_TABLE_OFFSET_DB;
 	default:
 		return 0;
 	}
@@ -739,6 +746,76 @@ static void ath9k_hw_get_def_gain_bounda
 	return;
 }
 
+static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
+				u16 *gb,
+				u16 numXpdGain,
+				u16 pdGainOverlap_t2,
+				int8_t pwr_table_offset,
+				int16_t *diff)
+
+{
+	u16 k;
+
+	/* Prior to writing the boundaries or the pdadc vs. power table
+	 * into the chip registers the default starting point on the pdadc
+	 * vs. power table needs to be checked and the curve boundaries
+	 * adjusted accordingly
+	 */
+	if (AR_SREV_9280_20_OR_LATER(ah)) {
+		u16 gb_limit;
+
+		if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
+			/* get the difference in dB */
+			*diff = (u16)(pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB);
+			/* get the number of half dB steps */
+			*diff *= 2;
+			/* change the original gain boundary settings
+			 * by the number of half dB steps
+			 */
+			for (k = 0; k < numXpdGain; k++)
+				gb[k] = (u16)(gb[k] - *diff);
+		}
+		/* Because of a hardware limitation, ensure the gain boundary
+		 * is not larger than (63 - overlap)
+		 */
+		gb_limit = (u16)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2);
+
+		for (k = 0; k < numXpdGain; k++)
+			gb[k] = (u16)min(gb_limit, gb[k]);
+	}
+
+	return *diff;
+}
+
+static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
+				      int8_t pwr_table_offset,
+				      int16_t diff,
+				      u8 *pdadcValues)
+{
+#define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
+	u16 k;
+
+	/* If this is a board that has a pwrTableOffset that differs from
+	 * the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
+	 * pdadc vs pwr table needs to be adjusted prior to writing to the
+	 * chip.
+	 */
+	if (AR_SREV_9280_20_OR_LATER(ah)) {
+		if (AR5416_PWR_TABLE_OFFSET_DB != pwr_table_offset) {
+			/* shift the table to start at the new offset */
+			for (k = 0; k < (u16)NUM_PDADC(diff); k++ ) {
+				pdadcValues[k] = pdadcValues[k + diff];
+			}
+
+			/* fill the back of the table */
+			for (k = (u16)NUM_PDADC(diff); k < NUM_PDADC(0); k++) {
+				pdadcValues[k] = pdadcValues[NUM_PDADC(diff)];
+			}
+		}
+	}
+#undef NUM_PDADC
+}
+
 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
 				  struct ath9k_channel *chan,
 				  int16_t *pTxPowerIndexOffset)
@@ -746,7 +823,7 @@ static void ath9k_hw_set_def_power_cal_t
 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
 #define SM_PDGAIN_B(x, y) \
 		SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
-
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
 	struct cal_data_per_freq *pRawDataset;
 	u8 *pCalBChans = NULL;
@@ -754,15 +831,18 @@ static void ath9k_hw_set_def_power_cal_t
 	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
 	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
 	u16 numPiers, i, j;
-	int16_t tMinCalPower;
+	int16_t tMinCalPower, diff = 0;
 	u16 numXpdGain, xpdMask;
 	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
 	u32 reg32, regOffset, regChainOffset;
 	int16_t modalIdx;
+	int8_t pwr_table_offset;
 
 	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
 	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
 
+	pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
+
 	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 	    AR5416_EEP_MINOR_VER_2) {
 		pdGainOverlap_t2 =
@@ -842,6 +922,13 @@ static void ath9k_hw_set_def_power_cal_t
 							numXpdGain);
 			}
 
+			diff = ath9k_change_gain_boundary_setting(ah,
+							   gainBoundaries,
+							   numXpdGain,
+							   pdGainOverlap_t2,
+							   pwr_table_offset,
+							   &diff);
+
 			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
 				if (OLC_FOR_AR9280_20_LATER) {
 					REG_WRITE(ah,
@@ -862,6 +949,10 @@ static void ath9k_hw_set_def_power_cal_t
 				}
 			}
 
+
+			ath9k_adjust_pdadc_values(ah, pwr_table_offset,
+						  diff, pdadcValues);
+
 			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
 			for (j = 0; j < 32; j++) {
 				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
@@ -870,20 +961,20 @@ static void ath9k_hw_set_def_power_cal_t
 					((pdadcValues[4 * j + 3] & 0xFF) << 24);
 				REG_WRITE(ah, regOffset, reg32);
 
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC (%d,%4x): %4.4x %8.8x\n",
-					i, regChainOffset, regOffset,
-					reg32);
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC: Chain %d | PDADC %3d "
-					"Value %3d | PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | PDADC %3d "
-					"Value %3d |\n",
-					i, 4 * j, pdadcValues[4 * j],
-					4 * j + 1, pdadcValues[4 * j + 1],
-					4 * j + 2, pdadcValues[4 * j + 2],
-					4 * j + 3,
-					pdadcValues[4 * j + 3]);
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PDADC (%d,%4x): %4.4x %8.8x\n",
+					  i, regChainOffset, regOffset,
+					  reg32);
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PDADC: Chain %d | PDADC %3d "
+					  "Value %3d | PDADC %3d Value %3d | "
+					  "PDADC %3d Value %3d | PDADC %3d "
+					  "Value %3d |\n",
+					  i, 4 * j, pdadcValues[4 * j],
+					  4 * j + 1, pdadcValues[4 * j + 1],
+					  4 * j + 2, pdadcValues[4 * j + 2],
+					  4 * j + 3,
+					  pdadcValues[4 * j + 3]);
 
 				regOffset += 4;
 			}
@@ -1197,8 +1288,13 @@ static void ath9k_hw_def_set_txpower(str
 	}
 
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		for (i = 0; i < Ar5416RateSize; i++)
-			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+		for (i = 0; i < Ar5416RateSize; i++) {
+			int8_t pwr_table_offset;
+
+			pwr_table_offset = ah->eep_ops->get_eeprom(ah,
+							EEP_PWR_TABLE_OFFSET);
+			ratesArray[i] -= pwr_table_offset * 2;
+		}
 	}
 
 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
@@ -1297,7 +1393,7 @@ static void ath9k_hw_def_set_txpower(str
 
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		regulatory->max_power_level =
-			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+			ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2;
 	else
 		regulatory->max_power_level = ratesArray[i];
 
@@ -1311,8 +1407,8 @@ static void ath9k_hw_def_set_txpower(str
 		regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Invalid chainmask configuration\n");
+		ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
+			  "Invalid chainmask configuration\n");
 		break;
 	}
 }
@@ -1349,20 +1445,21 @@ static u16 ath9k_hw_def_get_spur_channel
 {
 #define EEP_DEF_SPURCHAN \
 	(ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	u16 spur_val = AR_NO_SPUR;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Getting spur idx %d is2Ghz. %d val %x\n",
-		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+	ath_print(common, ATH_DBG_ANI,
+		  "Getting spur idx %d is2Ghz. %d val %x\n",
+		  i, is2GHz, ah->config.spurchans[i][is2GHz]);
 
 	switch (ah->config.spurmode) {
 	case SPUR_DISABLE:
 		break;
 	case SPUR_ENABLE_IOCTL:
 		spur_val = ah->config.spurchans[i][is2GHz];
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Getting spur val from new loc. %d\n", spur_val);
+		ath_print(common, ATH_DBG_ANI,
+			  "Getting spur val from new loc. %d\n", spur_val);
 		break;
 	case SPUR_ENABLE_EEPROM:
 		spur_val = EEP_DEF_SPURCHAN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/eeprom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/eeprom.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 #ifndef EEPROM_H
 #define EEPROM_H
 
+#include "../ath.h"
 #include <net/cfg80211.h>
 
 #define AH_USE_EEPROM   0x1
@@ -133,6 +134,7 @@
 #define AR5416_EEP_MINOR_VER_17      0x11
 #define AR5416_EEP_MINOR_VER_19      0x13
 #define AR5416_EEP_MINOR_VER_20      0x14
+#define AR5416_EEP_MINOR_VER_21      0x15
 #define AR5416_EEP_MINOR_VER_22      0x16
 
 #define AR5416_NUM_5G_CAL_PIERS         8
@@ -153,7 +155,7 @@
 #define AR5416_BCHAN_UNUSED             0xFF
 #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
 #define AR5416_MAX_CHAINS               3
-#define AR5416_PWR_TABLE_OFFSET         -5
+#define AR5416_PWR_TABLE_OFFSET_DB     -5
 
 /* Rx gain type values */
 #define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
@@ -301,7 +303,7 @@ struct base_eep_header {
 	u8 txGainType;
 	u8 rcChainMask;
 	u8 desiredScaleCCK;
-	u8 power_table_offset;
+	u8 pwr_table_offset;
 	u8 frac_n_5g;
 	u8 futureBase_3[21];
 } __packed;
@@ -638,6 +640,7 @@ struct ar9287_eeprom {
 } __packed;
 
 enum reg_ext_bitmap {
+	REG_EXT_FCC_MIDBAND = 0,
 	REG_EXT_JAPAN_MIDBAND = 1,
 	REG_EXT_FCC_DFS_HT40 = 2,
 	REG_EXT_JAPAN_NONDFS_HT40 = 3,
@@ -684,7 +687,7 @@ int16_t ath9k_hw_interpolate(u16 target,
 			     int16_t targetRight);
 bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
 				    u16 *indexL, u16 *indexR);
-bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
+bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data);
 void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
 			     u8 *pVpdList, u16 numIntercepts,
 			     u8 *pRetVpdList);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/hw.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/hw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,9 +16,9 @@
 
 #include <linux/io.h>
 #include <asm/unaligned.h>
-#include <linux/pci.h>
 
-#include "ath9k.h"
+#include "hw.h"
+#include "rc.h"
 #include "initvals.h"
 
 #define ATH9K_CLOCK_RATE_CCK		22
@@ -26,13 +26,27 @@
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-			      enum ath9k_ht_macmode macmode);
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
 static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
 			      struct ar5416_eeprom_def *pEepData,
 			      u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static int __init ath9k_init(void)
+{
+	return 0;
+}
+module_init(ath9k_init);
+
+static void __exit ath9k_exit(void)
+{
+	return;
+}
+module_exit(ath9k_exit);
 
 /********************/
 /* Helper Functions */
@@ -40,7 +54,7 @@ static void ath9k_hw_spur_mitigate(struc
 
 static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 
 	if (!ah->curchan) /* should really check for CCK instead */
 		return clks / ATH9K_CLOCK_RATE_CCK;
@@ -52,7 +66,7 @@ static u32 ath9k_hw_mac_usec(struct ath_
 
 static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 
 	if (conf_is_ht40(conf))
 		return ath9k_hw_mac_usec(ah, clks) / 2;
@@ -62,7 +76,7 @@ static u32 ath9k_hw_mac_to_usec(struct a
 
 static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 
 	if (!ah->curchan) /* should really check for CCK instead */
 		return usecs *ATH9K_CLOCK_RATE_CCK;
@@ -73,7 +87,7 @@ static u32 ath9k_hw_mac_clks(struct ath_
 
 static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
 {
-	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 
 	if (conf_is_ht40(conf))
 		return ath9k_hw_mac_clks(ah, usecs) * 2;
@@ -81,38 +95,6 @@ static u32 ath9k_hw_mac_to_clks(struct a
 		return ath9k_hw_mac_clks(ah, usecs);
 }
 
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
-	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-		unsigned long flags;
-		spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-		iowrite32(val, ah->ah_sc->mem + reg_offset);
-		spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-	} else
-		iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
-	u32 val;
-	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-		unsigned long flags;
-		spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-		val = ioread32(ah->ah_sc->mem + reg_offset);
-		spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-	} else
-		val = ioread32(ah->ah_sc->mem + reg_offset);
-	return val;
-}
-
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
 {
 	int i;
@@ -126,12 +108,13 @@ bool ath9k_hw_wait(struct ath_hw *ah, u3
 		udelay(AH_TIME_QUANTUM);
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-		"timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
-		timeout, reg, REG_READ(ah, reg), mask, val);
+	ath_print(ath9k_hw_common(ah), ATH_DBG_ANY,
+		  "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+		  timeout, reg, REG_READ(ah, reg), mask, val);
 
 	return false;
 }
+EXPORT_SYMBOL(ath9k_hw_wait);
 
 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
 {
@@ -165,22 +148,19 @@ bool ath9k_get_channel_edges(struct ath_
 }
 
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-			   const struct ath_rate_table *rates,
+			   u8 phy, int kbps,
 			   u32 frameLen, u16 rateix,
 			   bool shortPreamble)
 {
 	u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
-	u32 kbps;
-
-	kbps = rates->info[rateix].ratekbps;
 
 	if (kbps == 0)
 		return 0;
 
-	switch (rates->info[rateix].phy) {
+	switch (phy) {
 	case WLAN_RC_PHY_CCK:
 		phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
-		if (shortPreamble && rates->info[rateix].short_preamble)
+		if (shortPreamble)
 			phyTime >>= 1;
 		numBits = frameLen << 3;
 		txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
@@ -210,15 +190,15 @@ u16 ath9k_hw_computetxtime(struct ath_hw
 		}
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Unknown phy %u (rate ix %u)\n",
-			rates->info[rateix].phy, rateix);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "Unknown phy %u (rate ix %u)\n", phy, rateix);
 		txTime = 0;
 		break;
 	}
 
 	return txTime;
 }
+EXPORT_SYMBOL(ath9k_hw_computetxtime);
 
 void ath9k_hw_get_channel_centers(struct ath_hw *ah,
 				  struct ath9k_channel *chan,
@@ -245,10 +225,9 @@ void ath9k_hw_get_channel_centers(struct
 
 	centers->ctl_center =
 		centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
+	/* 25 MHz spacing is supported by hw but not on upper layers */
 	centers->ext_center =
-		centers->synth_center + (extoff *
-			 ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
-			  HT40_CHANNEL_CENTER_SHIFT : 15));
+		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
 }
 
 /******************/
@@ -317,6 +296,7 @@ static void ath9k_hw_disablepcie(struct
 
 static bool ath9k_hw_chip_test(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
 	u32 regHold[2];
 	u32 patternData[4] = { 0x55555555,
@@ -335,10 +315,11 @@ static bool ath9k_hw_chip_test(struct at
 			REG_WRITE(ah, addr, wrData);
 			rdData = REG_READ(ah, addr);
 			if (rdData != wrData) {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"address test failed "
-					"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-					addr, wrData, rdData);
+				ath_print(common, ATH_DBG_FATAL,
+					  "address test failed "
+					  "addr: 0x%08x - wr:0x%08x != "
+					  "rd:0x%08x\n",
+					  addr, wrData, rdData);
 				return false;
 			}
 		}
@@ -347,10 +328,11 @@ static bool ath9k_hw_chip_test(struct at
 			REG_WRITE(ah, addr, wrData);
 			rdData = REG_READ(ah, addr);
 			if (wrData != rdData) {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"address test failed "
-					"addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-					addr, wrData, rdData);
+				ath_print(common, ATH_DBG_FATAL,
+					  "address test failed "
+					  "addr: 0x%08x - wr:0x%08x != "
+					  "rd:0x%08x\n",
+					  addr, wrData, rdData);
 				return false;
 			}
 		}
@@ -404,8 +386,6 @@ static void ath9k_hw_init_config(struct
 	ah->config.cck_trig_high = 200;
 	ah->config.cck_trig_low = 100;
 	ah->config.enable_ani = 1;
-	ah->config.diversity_control = ATH9K_ANT_VARIABLE;
-	ah->config.antenna_switch_swap = 0;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 		ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -433,6 +413,7 @@ static void ath9k_hw_init_config(struct
 	if (num_possible_cpus() > 1)
 		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
 }
+EXPORT_SYMBOL(ath9k_hw_init);
 
 static void ath9k_hw_init_defaults(struct ath_hw *ah)
 {
@@ -459,27 +440,9 @@ static void ath9k_hw_init_defaults(struc
 	ah->acktimeout = (u32) -1;
 	ah->ctstimeout = (u32) -1;
 	ah->globaltxtimeout = (u32) -1;
-
-	ah->gbeacon_rate = 0;
-
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
-static int ath9k_hw_rfattach(struct ath_hw *ah)
-{
-	bool rfStatus = false;
-	int ecode = 0;
-
-	rfStatus = ath9k_hw_init_rf(ah, &ecode);
-	if (!rfStatus) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"RF setup failed, status: %u\n", ecode);
-		return ecode;
-	}
-
-	return 0;
-}
-
 static int ath9k_hw_rf_claim(struct ath_hw *ah)
 {
 	u32 val;
@@ -497,9 +460,9 @@ static int ath9k_hw_rf_claim(struct ath_
 	case AR_RAD2122_SREV_MAJOR:
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Radio Chip Rev 0x%02X not supported\n",
-			val & AR_RADIO_SREV_MAJOR);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "Radio Chip Rev 0x%02X not supported\n",
+			  val & AR_RADIO_SREV_MAJOR);
 		return -EOPNOTSUPP;
 	}
 
@@ -510,6 +473,7 @@ static int ath9k_hw_rf_claim(struct ath_
 
 static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 sum;
 	int i;
 	u16 eeval;
@@ -518,8 +482,8 @@ static int ath9k_hw_init_macaddr(struct
 	for (i = 0; i < 3; i++) {
 		eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
 		sum += eeval;
-		ah->macaddr[2 * i] = eeval >> 8;
-		ah->macaddr[2 * i + 1] = eeval & 0xff;
+		common->macaddr[2 * i] = eeval >> 8;
+		common->macaddr[2 * i + 1] = eeval & 0xff;
 	}
 	if (sum == 0 || sum == 0xffff * 3)
 		return -EADDRNOTAVAIL;
@@ -590,12 +554,20 @@ static int ath9k_hw_post_init(struct ath
 	if (ecode != 0)
 		return ecode;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
-		ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
+	ath_print(ath9k_hw_common(ah), ATH_DBG_CONFIG,
+		  "Eeprom VER: %d, REV: %d\n",
+		  ah->eep_ops->get_eeprom_ver(ah),
+		  ah->eep_ops->get_eeprom_rev(ah));
 
-	ecode = ath9k_hw_rfattach(ah);
-	if (ecode != 0)
-		return ecode;
+        if (!AR_SREV_9280_10_OR_LATER(ah)) {
+		ecode = ath9k_hw_rf_alloc_ext_banks(ah);
+		if (ecode) {
+			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+				  "Failed allocating banks for "
+				  "external radio\n");
+			return ecode;
+		}
+	}
 
 	if (!AR_SREV_9100(ah)) {
 		ath9k_hw_ani_setup(ah);
@@ -617,6 +589,7 @@ static bool ath9k_hw_devid_supported(u16
 	case AR9285_DEVID_PCIE:
 	case AR5416_DEVID_AR9287_PCI:
 	case AR5416_DEVID_AR9287_PCIE:
+	case AR9271_USB:
 		return true;
 	default:
 		break;
@@ -634,9 +607,8 @@ static bool ath9k_hw_macversion_supporte
 	case AR_SREV_VERSION_9280:
 	case AR_SREV_VERSION_9285:
 	case AR_SREV_VERSION_9287:
-		return true;
-	/* Not yet */
 	case AR_SREV_VERSION_9271:
+		return true;
 	default:
 		break;
 	}
@@ -670,10 +642,13 @@ static void ath9k_hw_init_cal_settings(s
 static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9271(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0,
-			       ARRAY_SIZE(ar9271Modes_9271_1_0), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0,
-			       ARRAY_SIZE(ar9271Common_9271_1_0), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
+			       ARRAY_SIZE(ar9271Modes_9271), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
+			       ARRAY_SIZE(ar9271Common_9271), 2);
+		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
+			       ar9271Modes_9271_1_0_only,
+			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
 		return;
 	}
 
@@ -880,12 +855,11 @@ static void ath9k_hw_init_mode_gain_regs
 	}
 }
 
-static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
+static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
 {
 	u32 i, j;
 
-	if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
-	    test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
+	if (ah->hw_version.devid == AR9280_DEVID_PCI) {
 
 		/* EEPROM Fixup */
 		for (i = 0; i < ah->iniModes.ia_rows; i++) {
@@ -905,21 +879,27 @@ static void ath9k_hw_init_11a_eeprom_fix
 
 int ath9k_hw_init(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int r = 0;
 
-	if (!ath9k_hw_devid_supported(ah->hw_version.devid))
+	if (!ath9k_hw_devid_supported(ah->hw_version.devid)) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unsupported device ID: 0x%0x\n",
+			  ah->hw_version.devid);
 		return -EOPNOTSUPP;
+	}
 
 	ath9k_hw_init_defaults(ah);
 	ath9k_hw_init_config(ah);
 
 	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Couldn't reset chip\n");
 		return -EIO;
 	}
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+		ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
 		return -EIO;
 	}
 
@@ -934,14 +914,19 @@ int ath9k_hw_init(struct ath_hw *ah)
 		}
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+	ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
 		ah->config.serialize_regmode);
 
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+		ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
+	else
+		ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
+
 	if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Mac Chip Rev 0x%02x.%x is not supported by "
-			"this driver\n", ah->hw_version.macVersion,
-			ah->hw_version.macRev);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Mac Chip Rev 0x%02x.%x is not supported by "
+			  "this driver\n", ah->hw_version.macVersion,
+			  ah->hw_version.macRev);
 		return -EOPNOTSUPP;
 	}
 
@@ -959,8 +944,14 @@ int ath9k_hw_init(struct ath_hw *ah)
 	ath9k_hw_init_cal_settings(ah);
 
 	ah->ani_function = ATH9K_ANI_ALL;
-	if (AR_SREV_9280_10_OR_LATER(ah))
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
 		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+		ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
+		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate;
+	} else {
+		ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
+		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate;
+	}
 
 	ath9k_hw_init_mode_regs(ah);
 
@@ -969,18 +960,31 @@ int ath9k_hw_init(struct ath_hw *ah)
 	else
 		ath9k_hw_disablepcie(ah);
 
+	/* Support for Japan ch.14 (2484) spread */
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniCckfirNormal,
+		       ar9287Common_normal_cck_fir_coeff_92871_1,
+		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2);
+		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+		       ar9287Common_japan_2484_cck_fir_coeff_92871_1,
+		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2);
+	}
+
 	r = ath9k_hw_post_init(ah);
 	if (r)
 		return r;
 
 	ath9k_hw_init_mode_gain_regs(ah);
-	ath9k_hw_fill_cap_info(ah);
-	ath9k_hw_init_11a_eeprom_fix(ah);
+	r = ath9k_hw_fill_cap_info(ah);
+	if (r)
+		return r;
+
+	ath9k_hw_init_eeprom_fix(ah);
 
 	r = ath9k_hw_init_macaddr(ah);
 	if (r) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Failed to initialize MAC address\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Failed to initialize MAC address\n");
 		return r;
 	}
 
@@ -991,6 +995,8 @@ int ath9k_hw_init(struct ath_hw *ah)
 
 	ath9k_init_nfcal_hist_buffer(ah);
 
+	common->state = ATH_HW_INITIALIZED;
+
 	return 0;
 }
 
@@ -1027,6 +1033,22 @@ static void ath9k_hw_init_qos(struct ath
 	REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
 }
 
+static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
+{
+	u32 lcr;
+	u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
+
+	lcr = REG_READ(ah , 0x5100c);
+	lcr |= 0x80;
+
+	REG_WRITE(ah, 0x5100c, lcr);
+	REG_WRITE(ah, 0x51004, (baud_divider >> 8));
+	REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
+
+	lcr &= ~0x80;
+	REG_WRITE(ah, 0x5100c, lcr);
+}
+
 static void ath9k_hw_init_pll(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
@@ -1090,6 +1112,26 @@ static void ath9k_hw_init_pll(struct ath
 	}
 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
+	/* Switch the core clock for ar9271 to 117Mhz */
+	if (AR_SREV_9271(ah)) {
+		if ((pll == 0x142c) || (pll == 0x2850) ) {
+			udelay(500);
+			/* set CLKOBS to output AHB clock */
+			REG_WRITE(ah, 0x7020, 0xe);
+			/*
+			 * 0x304: 117Mhz, ahb_ratio: 1x1
+			 * 0x306: 40Mhz, ahb_ratio: 1x1
+			 */
+			REG_WRITE(ah, 0x50040, 0x304);
+			/*
+			 * makes adjustments for the baud dividor to keep the
+			 * targetted baud rate based on the used core clock.
+			 */
+			ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
+						    AR9271_TARGET_BAUD_RATE);
+		}
+	}
+
 	udelay(RTC_PLL_SETTLE_DELAY);
 
 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
@@ -1107,7 +1149,7 @@ static void ath9k_hw_init_chain_masks(st
 		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
 			    AR_PHY_SWAP_ALT_CHAIN);
 	case 0x3:
-		if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
+		if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
 			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
 			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
 			break;
@@ -1164,7 +1206,8 @@ static void ath9k_hw_init_interrupt_mask
 static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
 {
 	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "bad ack timeout %u\n", us);
 		ah->acktimeout = (u32) -1;
 		return false;
 	} else {
@@ -1178,7 +1221,8 @@ static bool ath9k_hw_set_ack_timeout(str
 static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
 {
 	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "bad cts timeout %u\n", us);
 		ah->ctstimeout = (u32) -1;
 		return false;
 	} else {
@@ -1192,8 +1236,8 @@ static bool ath9k_hw_set_cts_timeout(str
 static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
 {
 	if (tu > 0xFFFF) {
-		DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
-			"bad global tx timeout %u\n", tu);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
+			  "bad global tx timeout %u\n", tu);
 		ah->globaltxtimeout = (u32) -1;
 		return false;
 	} else {
@@ -1205,8 +1249,8 @@ static bool ath9k_hw_set_global_txtimeou
 
 static void ath9k_hw_init_user_settings(struct ath_hw *ah)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
-		ah->misc_mode);
+	ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+		  ah->misc_mode);
 
 	if (ah->misc_mode != 0)
 		REG_WRITE(ah, AR_PCU_MISC,
@@ -1229,14 +1273,23 @@ const char *ath9k_hw_probe(u16 vendorid,
 
 void ath9k_hw_detach(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (common->state <= ATH_HW_INITIALIZED)
+		goto free_hw;
+
 	if (!AR_SREV_9100(ah))
 		ath9k_hw_ani_disable(ah);
 
-	ath9k_hw_rf_free(ah);
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+
+free_hw:
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		ath9k_hw_rf_free_ext_banks(ah);
 	kfree(ah);
 	ah = NULL;
 }
+EXPORT_SYMBOL(ath9k_hw_detach);
 
 /*******/
 /* INI */
@@ -1254,7 +1307,8 @@ static void ath9k_hw_override_ini(struct
 		 * AR9271 1.1
 		 */
 		if (AR_SREV_9271_10(ah)) {
-			val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | AR_PHY_SPECTRAL_SCAN_ENABLE;
+			val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
+			      AR_PHY_SPECTRAL_SCAN_ENABLE;
 			REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
 		}
 		else if (AR_SREV_9271_11(ah))
@@ -1298,28 +1352,29 @@ static u32 ath9k_hw_def_ini_fixup(struct
 			      u32 reg, u32 value)
 {
 	struct base_eep_header *pBase = &(pEepData->baseEepHeader);
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	switch (ah->hw_version.devid) {
 	case AR9280_DEVID_PCI:
 		if (reg == 0x7894) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			ath_print(common, ATH_DBG_EEPROM,
 				"ini VAL: %x  EEPROM: %x\n", value,
 				(pBase->version & 0xff));
 
 			if ((pBase->version & 0xff) > 0x0a) {
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PWDCLKIND: %d\n",
-					pBase->pwdclkind);
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PWDCLKIND: %d\n",
+					  pBase->pwdclkind);
 				value &= ~AR_AN_TOP2_PWDCLKIND;
 				value |= AR_AN_TOP2_PWDCLKIND &
 					(pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
 			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PWDCLKIND Earlier Rev\n");
+				ath_print(common, ATH_DBG_EEPROM,
+					  "PWDCLKIND Earlier Rev\n");
 			}
 
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"final ini VAL: %x\n", value);
+			ath_print(common, ATH_DBG_EEPROM,
+				  "final ini VAL: %x\n", value);
 		}
 		break;
 	}
@@ -1374,8 +1429,7 @@ static u32 ath9k_regd_get_ctl(struct ath
 }
 
 static int ath9k_hw_process_ini(struct ath_hw *ah,
-				struct ath9k_channel *chan,
-				enum ath9k_ht_macmode macmode)
+				struct ath9k_channel *chan)
 {
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	int i, regWrites = 0;
@@ -1469,7 +1523,11 @@ static int ath9k_hw_process_ini(struct a
 		DO_DELAY(regWrites);
 	}
 
-	ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
+	ath9k_hw_write_regs(ah, freqIndex, regWrites);
+
+	if (AR_SREV_9271_10(ah))
+		REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
+				modesIndex, regWrites);
 
 	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
 		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
@@ -1477,7 +1535,7 @@ static int ath9k_hw_process_ini(struct a
 	}
 
 	ath9k_hw_override_ini(ah, chan);
-	ath9k_hw_set_regs(ah, chan, macmode);
+	ath9k_hw_set_regs(ah, chan);
 	ath9k_hw_init_chain_masks(ah);
 
 	if (OLC_FOR_AR9280_20_LATER)
@@ -1491,8 +1549,8 @@ static int ath9k_hw_process_ini(struct a
 				 (u32) regulatory->power_limit));
 
 	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"ar5416SetRfRegs failed\n");
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "ar5416SetRfRegs failed\n");
 		return -EIO;
 	}
 
@@ -1697,16 +1755,14 @@ static bool ath9k_hw_set_reset(struct at
 
 	REG_WRITE(ah, AR_RTC_RC, 0);
 	if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-			"RTC stuck in MAC reset\n");
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "RTC stuck in MAC reset\n");
 		return false;
 	}
 
 	if (!AR_SREV_9100(ah))
 		REG_WRITE(ah, AR_RC, 0);
 
-	ath9k_hw_init_pll(ah, NULL);
-
 	if (AR_SREV_9100(ah))
 		udelay(50);
 
@@ -1734,7 +1790,8 @@ static bool ath9k_hw_set_reset_power_on(
 			   AR_RTC_STATUS_M,
 			   AR_RTC_STATUS_ON,
 			   AH_WAIT_TIMEOUT)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "RTC not waking up\n");
 		return false;
 	}
 
@@ -1759,8 +1816,7 @@ static bool ath9k_hw_set_reset_reg(struc
 	}
 }
 
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-			      enum ath9k_ht_macmode macmode)
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u32 phymode;
 	u32 enableDacFifo = 0;
@@ -1779,12 +1835,10 @@ static void ath9k_hw_set_regs(struct ath
 		    (chan->chanmode == CHANNEL_G_HT40PLUS))
 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
-		if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
-			phymode |= AR_PHY_FC_DYN2040_EXT_CH;
 	}
 	REG_WRITE(ah, AR_PHY_TURBO, phymode);
 
-	ath9k_hw_set11nmac2040(ah, macmode);
+	ath9k_hw_set11nmac2040(ah);
 
 	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
 	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
@@ -1810,17 +1864,19 @@ static bool ath9k_hw_chip_reset(struct a
 }
 
 static bool ath9k_hw_channel_change(struct ath_hw *ah,
-				    struct ath9k_channel *chan,
-				    enum ath9k_ht_macmode macmode)
+				    struct ath9k_channel *chan)
 {
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_channel *channel = chan->chan;
 	u32 synthDelay, qnum;
+	int r;
 
 	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
 		if (ath9k_hw_numtxpending(ah, qnum)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-				"Transmit frames pending on queue %d\n", qnum);
+			ath_print(common, ATH_DBG_QUEUE,
+				  "Transmit frames pending on "
+				  "queue %d\n", qnum);
 			return false;
 		}
 	}
@@ -1828,21 +1884,18 @@ static bool ath9k_hw_channel_change(stru
 	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
 	if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
 			   AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Could not kill baseband RX\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Could not kill baseband RX\n");
 		return false;
 	}
 
-	ath9k_hw_set_regs(ah, chan, macmode);
+	ath9k_hw_set_regs(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		ath9k_hw_ar9280_set_channel(ah, chan);
-	} else {
-		if (!(ath9k_hw_set_channel(ah, chan))) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Failed to set channel\n");
-			return false;
-		}
+	r = ah->ath9k_hw_rf_set_freq(ah, chan);
+	if (r) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Failed to set channel\n");
+		return false;
 	}
 
 	ah->eep_ops->set_txpower(ah, chan,
@@ -1865,10 +1918,7 @@ static bool ath9k_hw_channel_change(stru
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_9280_spur_mitigate(ah, chan);
-	else
-		ath9k_hw_spur_mitigate(ah, chan);
+	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
 
 	if (!chan->oneTimeCalsDone)
 		chan->oneTimeCalsDone = true;
@@ -1876,457 +1926,6 @@ static bool ath9k_hw_channel_change(stru
 	return true;
 }
 
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int bb_spur = AR_NO_SPUR;
-	int freq;
-	int bin, cur_bin;
-	int bb_spur_off, spur_subchannel_sd;
-	int spur_freq_sd;
-	int spur_delta_phase;
-	int denominator;
-	int upper, lower, cur_vit_mask;
-	int tmp, newVal;
-	int i;
-	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	int inc[4] = { 0, 100, 0, 0 };
-	struct chan_centers centers;
-
-	int8_t mask_m[123];
-	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
-	int cur_bb_spur;
-	bool is2GHz = IS_CHAN_2GHZ(chan);
-
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	ah->config.spurmode = SPUR_ENABLE_EEPROM;
-	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-
-		if (is2GHz)
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-		else
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-		if (AR_NO_SPUR == cur_bb_spur)
-			break;
-		cur_bb_spur = cur_bb_spur - freq;
-
-		if (IS_CHAN_HT40(chan)) {
-			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-				bb_spur = cur_bb_spur;
-				break;
-			}
-		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-			bb_spur = cur_bb_spur;
-			break;
-		}
-	}
-
-	if (AR_NO_SPUR == bb_spur) {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-		return;
-	} else {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-	}
-
-	bin = bb_spur * 320;
-
-	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-	if (IS_CHAN_HT40(chan)) {
-		if (bb_spur < 0) {
-			spur_subchannel_sd = 1;
-			bb_spur_off = bb_spur + 10;
-		} else {
-			spur_subchannel_sd = 0;
-			bb_spur_off = bb_spur - 10;
-		}
-	} else {
-		spur_subchannel_sd = 0;
-		bb_spur_off = bb_spur;
-	}
-
-	if (IS_CHAN_HT40(chan))
-		spur_delta_phase =
-			((bb_spur * 262144) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-	else
-		spur_delta_phase =
-			((bb_spur * 524288) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int bb_spur = AR_NO_SPUR;
-	int bin, cur_bin;
-	int spur_freq_sd;
-	int spur_delta_phase;
-	int denominator;
-	int upper, lower, cur_vit_mask;
-	int tmp, new;
-	int i;
-	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	int inc[4] = { 0, 100, 0, 0 };
-
-	int8_t mask_m[123];
-	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
-	int cur_bb_spur;
-	bool is2GHz = IS_CHAN_2GHZ(chan);
-
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-		if (AR_NO_SPUR == cur_bb_spur)
-			break;
-		cur_bb_spur = cur_bb_spur - (chan->channel * 10);
-		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
-			bb_spur = cur_bb_spur;
-			break;
-		}
-	}
-
-	if (AR_NO_SPUR == bb_spur)
-		return;
-
-	bin = bb_spur * 32;
-
-	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-		     AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-		     AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-		     AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
-
-	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-	       AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-	       AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-	       AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-	       SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-	REG_WRITE(ah, AR_PHY_SPUR_REG, new);
-
-	spur_delta_phase = ((bb_spur * 524288) / 100) &
-		AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
-	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
-
-	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-	       SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-	REG_WRITE(ah, AR_PHY_TIMING11, new);
-
-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
 static void ath9k_enable_rfkill(struct ath_hw *ah)
 {
 	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
@@ -2342,17 +1941,16 @@ static void ath9k_enable_rfkill(struct a
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		    bool bChannelChange)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 saveLedState;
-	struct ath_softc *sc = ah->ah_sc;
 	struct ath9k_channel *curchan = ah->curchan;
 	u32 saveDefAntenna;
 	u32 macStaId1;
 	u64 tsf = 0;
 	int i, rx_chainmask, r;
 
-	ah->extprotspacing = sc->ht_extprotspacing;
-	ah->txchainmask = sc->tx_chainmask;
-	ah->rxchainmask = sc->rx_chainmask;
+	ah->txchainmask = common->tx_chainmask;
+	ah->rxchainmask = common->rx_chainmask;
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return -EIO;
@@ -2369,7 +1967,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	     !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) ||
 	     IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
 
-		if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+		if (ath9k_hw_channel_change(ah, chan)) {
 			ath9k_hw_loadnf(ah, ah->curchan);
 			ath9k_hw_start_nfcal(ah);
 			return 0;
@@ -2400,7 +1998,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	}
 
 	if (!ath9k_hw_chip_reset(ah, chan)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
+		ath_print(common, ATH_DBG_FATAL, "Chip reset failed\n");
 		return -EINVAL;
 	}
 
@@ -2429,7 +2027,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
 				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
 	}
-	r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+	r = ath9k_hw_process_ini(ah, chan);
 	if (r)
 		return r;
 
@@ -2453,17 +2051,11 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_9280_spur_mitigate(ah, chan);
-	else
-		ath9k_hw_spur_mitigate(ah, chan);
-
+	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
 	ah->eep_ops->set_board_values(ah, chan);
 
-	ath9k_hw_decrease_chain_power(ah, chan);
-
-	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
-	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
+	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
+	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
 		  | macStaId1
 		  | AR_STA_ID1_RTS_USE_DEF
 		  | (ah->config.
@@ -2471,24 +2063,19 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 		  | ah->sta_id1_defaults);
 	ath9k_hw_set_operating_mode(ah, ah->opmode);
 
-	REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-	REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+	ath_hw_setbssidmask(common);
 
 	REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
 
-	REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-	REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-		  ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+	ath9k_hw_write_associd(ah);
 
 	REG_WRITE(ah, AR_ISR, ~0);
 
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_ar9280_set_channel(ah, chan);
-	else
-		if (!(ath9k_hw_set_channel(ah, chan)))
-			return -EIO;
+	r = ah->ath9k_hw_rf_set_freq(ah, chan);
+	if (r)
+		return r;
 
 	for (i = 0; i < AR_NUM_DCU; i++)
 		REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
@@ -2558,13 +2145,13 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 		u32 mask;
 		mask = REG_READ(ah, AR_CFG);
 		if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+			ath_print(common, ATH_DBG_RESET,
 				"CFG Byte Swap Set 0x%x\n", mask);
 		} else {
 			mask =
 				INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
 			REG_WRITE(ah, AR_CFG, mask);
-			DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+			ath_print(common, ATH_DBG_RESET,
 				"Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
 		}
 	} else {
@@ -2577,11 +2164,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 #endif
 	}
 
-	if (ah->ah_sc->sc_flags & SC_OP_BTCOEX_ENABLED)
+	if (ah->btcoex_hw.enabled)
 		ath9k_hw_btcoex_enable(ah);
 
 	return 0;
 }
+EXPORT_SYMBOL(ath9k_hw_reset);
 
 /************************/
 /* Key Cache Management */
@@ -2592,8 +2180,8 @@ bool ath9k_hw_keyreset(struct ath_hw *ah
 	u32 keyType;
 
 	if (entry >= ah->caps.keycache_size) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"keychache entry %u out of range\n", entry);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "keychache entry %u out of range\n", entry);
 		return false;
 	}
 
@@ -2620,14 +2208,15 @@ bool ath9k_hw_keyreset(struct ath_hw *ah
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_keyreset);
 
 bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
 {
 	u32 macHi, macLo;
 
 	if (entry >= ah->caps.keycache_size) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"keychache entry %u out of range\n", entry);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "keychache entry %u out of range\n", entry);
 		return false;
 	}
 
@@ -2648,18 +2237,20 @@ bool ath9k_hw_keysetmac(struct ath_hw *a
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_keysetmac);
 
 bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
 				 const struct ath9k_keyval *k,
 				 const u8 *mac)
 {
 	const struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 key0, key1, key2, key3, key4;
 	u32 keyType;
 
 	if (entry >= pCap->keycache_size) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"keycache entry %u out of range\n", entry);
+		ath_print(common, ATH_DBG_FATAL,
+			  "keycache entry %u out of range\n", entry);
 		return false;
 	}
 
@@ -2669,9 +2260,9 @@ bool ath9k_hw_set_keycache_entry(struct
 		break;
 	case ATH9K_CIPHER_AES_CCM:
 		if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-				"AES-CCM not supported by mac rev 0x%x\n",
-				ah->hw_version.macRev);
+			ath_print(common, ATH_DBG_ANY,
+				  "AES-CCM not supported by mac rev 0x%x\n",
+				  ah->hw_version.macRev);
 			return false;
 		}
 		keyType = AR_KEYTABLE_TYPE_CCM;
@@ -2680,15 +2271,15 @@ bool ath9k_hw_set_keycache_entry(struct
 		keyType = AR_KEYTABLE_TYPE_TKIP;
 		if (ATH9K_IS_MIC_ENABLED(ah)
 		    && entry + 64 >= pCap->keycache_size) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-				"entry %u inappropriate for TKIP\n", entry);
+			ath_print(common, ATH_DBG_ANY,
+				  "entry %u inappropriate for TKIP\n", entry);
 			return false;
 		}
 		break;
 	case ATH9K_CIPHER_WEP:
 		if (k->kv_len < WLAN_KEY_LEN_WEP40) {
-			DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-				"WEP key length %u too small\n", k->kv_len);
+			ath_print(common, ATH_DBG_ANY,
+				  "WEP key length %u too small\n", k->kv_len);
 			return false;
 		}
 		if (k->kv_len <= WLAN_KEY_LEN_WEP40)
@@ -2702,8 +2293,8 @@ bool ath9k_hw_set_keycache_entry(struct
 		keyType = AR_KEYTABLE_TYPE_CLR;
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"cipher %u not supported\n", k->kv_type);
+		ath_print(common, ATH_DBG_FATAL,
+			  "cipher %u not supported\n", k->kv_type);
 		return false;
 	}
 
@@ -2845,6 +2436,7 @@ bool ath9k_hw_set_keycache_entry(struct
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_set_keycache_entry);
 
 bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
 {
@@ -2855,6 +2447,7 @@ bool ath9k_hw_keyisvalid(struct ath_hw *
 	}
 	return false;
 }
+EXPORT_SYMBOL(ath9k_hw_keyisvalid);
 
 /******************************/
 /* Power Management (Chipset) */
@@ -2869,8 +2462,9 @@ static void ath9k_set_power_sleep(struct
 		if (!AR_SREV_9100(ah))
 			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
-		REG_CLR_BIT(ah, (AR_RTC_RESET),
-			    AR_RTC_RESET_EN);
+		if(!AR_SREV_5416(ah))
+			REG_CLR_BIT(ah, (AR_RTC_RESET),
+				    AR_RTC_RESET_EN);
 	}
 }
 
@@ -2902,6 +2496,7 @@ static bool ath9k_hw_set_power_awake(str
 					   ATH9K_RESET_POWER_ON) != true) {
 				return false;
 			}
+			ath9k_hw_init_pll(ah, NULL);
 		}
 		if (AR_SREV_9100(ah))
 			REG_SET_BIT(ah, AR_RTC_RESET,
@@ -2920,8 +2515,9 @@ static bool ath9k_hw_set_power_awake(str
 				    AR_RTC_FORCE_WAKE_EN);
 		}
 		if (i == 0) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
+			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+				  "Failed to wakeup in %uus\n",
+				  POWER_UP_TIME / 20);
 			return false;
 		}
 	}
@@ -2931,9 +2527,9 @@ static bool ath9k_hw_set_power_awake(str
 	return true;
 }
 
-static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
-				     enum ath9k_power_mode mode)
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	int status = true, setChip = true;
 	static const char *modes[] = {
 		"AWAKE",
@@ -2945,8 +2541,8 @@ static bool ath9k_hw_setpower_nolock(str
 	if (ah->power_mode == mode)
 		return status;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
-		modes[ah->power_mode], modes[mode]);
+	ath_print(common, ATH_DBG_RESET, "%s -> %s\n",
+		  modes[ah->power_mode], modes[mode]);
 
 	switch (mode) {
 	case ATH9K_PM_AWAKE:
@@ -2960,59 +2556,15 @@ static bool ath9k_hw_setpower_nolock(str
 		ath9k_set_power_network_sleep(ah, setChip);
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Unknown power mode %u\n", mode);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unknown power mode %u\n", mode);
 		return false;
 	}
 	ah->power_mode = mode;
 
 	return status;
 }
-
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
-{
-	unsigned long flags;
-	bool ret;
-
-	spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
-	ret = ath9k_hw_setpower_nolock(ah, mode);
-	spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
-
-	return ret;
-}
-
-void ath9k_ps_wakeup(struct ath_softc *sc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sc->sc_pm_lock, flags);
-	if (++sc->ps_usecount != 1)
-		goto unlock;
-
-	ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
-
- unlock:
-	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-}
-
-void ath9k_ps_restore(struct ath_softc *sc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sc->sc_pm_lock, flags);
-	if (--sc->ps_usecount != 0)
-		goto unlock;
-
-	if (sc->ps_enabled &&
-	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-			      SC_OP_WAIT_FOR_CAB |
-			      SC_OP_WAIT_FOR_PSPOLL_DATA |
-			      SC_OP_WAIT_FOR_TX_ACK)))
-		ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-
- unlock:
-	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-}
+EXPORT_SYMBOL(ath9k_hw_setpower);
 
 /*
  * Helper for ASPM support.
@@ -3145,6 +2697,7 @@ void ath9k_hw_configpcipowersave(struct
 		}
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_configpcipowersave);
 
 /**********************/
 /* Interrupt Handling */
@@ -3168,6 +2721,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
 
 	return false;
 }
+EXPORT_SYMBOL(ath9k_hw_intrpend);
 
 bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 {
@@ -3176,6 +2730,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah,
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	u32 sync_cause = 0;
 	bool fatal_int = false;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	if (!AR_SREV_9100(ah)) {
 		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -3249,8 +2804,8 @@ bool ath9k_hw_getisr(struct ath_hw *ah,
 		}
 
 		if (isr & AR_ISR_RXORN) {
-			DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-				"receive FIFO overrun interrupt\n");
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "receive FIFO overrun interrupt\n");
 		}
 
 		if (!AR_SREV_9100(ah)) {
@@ -3292,25 +2847,25 @@ bool ath9k_hw_getisr(struct ath_hw *ah,
 
 		if (fatal_int) {
 			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-				DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-					"received PCI FATAL interrupt\n");
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI FATAL interrupt\n");
 			}
 			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-				DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-					"received PCI PERR interrupt\n");
+				ath_print(common, ATH_DBG_ANY,
+					  "received PCI PERR interrupt\n");
 			}
 			*masked |= ATH9K_INT_FATAL;
 		}
 		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-			DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-				"AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
 			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
 			REG_WRITE(ah, AR_RC, 0);
 			*masked |= ATH9K_INT_FATAL;
 		}
 		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
-			DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-				"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+			ath_print(common, ATH_DBG_INTERRUPT,
+				  "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
 		}
 
 		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
@@ -3319,17 +2874,19 @@ bool ath9k_hw_getisr(struct ath_hw *ah,
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_getisr);
 
 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 {
 	u32 omask = ah->mask_reg;
 	u32 mask, mask2;
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
 
-	DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+	ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
 
 	if (omask & ATH9K_INT_GLOBAL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n");
+		ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
 		REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
 		(void) REG_READ(ah, AR_IER);
 		if (!AR_SREV_9100(ah)) {
@@ -3386,7 +2943,7 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 			mask2 |= AR_IMR_S2_CST;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+	ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
 	REG_WRITE(ah, AR_IMR, mask);
 	mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
 					   AR_IMR_S2_DTIM |
@@ -3406,7 +2963,7 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 	}
 
 	if (ints & ATH9K_INT_GLOBAL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n");
+		ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
 		REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
 		if (!AR_SREV_9100(ah)) {
 			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
@@ -3419,12 +2976,13 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 			REG_WRITE(ah, AR_INTR_SYNC_MASK,
 				  AR_INTR_SYNC_DEFAULT);
 		}
-		DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-			 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+		ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+			  REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
 	}
 
 	return omask;
 }
+EXPORT_SYMBOL(ath9k_hw_set_interrupts);
 
 /*******************/
 /* Beacon Handling */
@@ -3467,9 +3025,9 @@ void ath9k_hw_beaconinit(struct ath_hw *
 			AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
-			"%s: unsupported opmode: %d\n",
-			__func__, ah->opmode);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
+			  "%s: unsupported opmode: %d\n",
+			  __func__, ah->opmode);
 		return;
 		break;
 	}
@@ -3481,18 +3039,19 @@ void ath9k_hw_beaconinit(struct ath_hw *
 
 	beacon_period &= ~ATH9K_BEACON_ENA;
 	if (beacon_period & ATH9K_BEACON_RESET_TSF) {
-		beacon_period &= ~ATH9K_BEACON_RESET_TSF;
 		ath9k_hw_reset_tsf(ah);
 	}
 
 	REG_SET_BIT(ah, AR_TIMER_MODE, flags);
 }
+EXPORT_SYMBOL(ath9k_hw_beaconinit);
 
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs)
 {
 	u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
 
@@ -3518,10 +3077,10 @@ void ath9k_hw_set_sta_beacon_timers(stru
 	else
 		nextTbtt = bs->bs_nexttbtt;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
-	DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
-	DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
-	DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
+	ath_print(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
+	ath_print(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
+	ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
+	ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
 
 	REG_WRITE(ah, AR_NEXT_DTIM,
 		  TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
@@ -3549,16 +3108,18 @@ void ath9k_hw_set_sta_beacon_timers(stru
 	/* TSF Out of Range Threshold */
 	REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
 }
+EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
 
 /*******************/
 /* HW Capabilities */
 /*******************/
 
-void ath9k_hw_fill_cap_info(struct ath_hw *ah)
+int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
 	u16 capField = 0, eeval;
 
@@ -3579,11 +3140,17 @@ void ath9k_hw_fill_cap_info(struct ath_h
 			regulatory->current_rd += 5;
 		else if (regulatory->current_rd == 0x41)
 			regulatory->current_rd = 0x43;
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"regdomain mapped to 0x%x\n", regulatory->current_rd);
+		ath_print(common, ATH_DBG_REGULATORY,
+			  "regdomain mapped to 0x%x\n", regulatory->current_rd);
 	}
 
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+	if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "no band has been marked as supported in EEPROM.\n");
+		return -EINVAL;
+	}
+
 	bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
 
 	if (eeval & AR5416_OPFLAGS_11A) {
@@ -3670,7 +3237,11 @@ void ath9k_hw_fill_cap_info(struct ath_h
 		pCap->keycache_size = AR_KEYTABLE_SIZE;
 
 	pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-	pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
+	else
+		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
 
 	if (AR_SREV_9285_10_OR_LATER(ah))
 		pCap->num_gpio_pins = AR9285_NUM_GPIO;
@@ -3719,7 +3290,10 @@ void ath9k_hw_fill_cap_info(struct ath_h
 			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
 	}
 
-	pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
+	/* Advertise midband for AR5416 with FCC midband set in eeprom */
+	if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) &&
+	    AR_SREV_5416(ah))
+		pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
 
 	pCap->num_antcfg_5ghz =
 		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
@@ -3727,19 +3301,21 @@ void ath9k_hw_fill_cap_info(struct ath_h
 		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
 
 	if (AR_SREV_9280_10_OR_LATER(ah) &&
-	    ath_btcoex_supported(ah->hw_version.subsysid)) {
-		btcoex_info->btactive_gpio = ATH_BTACTIVE_GPIO;
-		btcoex_info->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
+	    ath9k_hw_btcoex_supported(ah)) {
+		btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
+		btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
 
 		if (AR_SREV_9285(ah)) {
-			btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_3WIRE;
-			btcoex_info->btpriority_gpio = ATH_BTPRIORITY_GPIO;
+			btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
 		} else {
-			btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_2WIRE;
+			btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
 		}
 	} else {
-		btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_NONE;
+		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
 	}
+
+	return 0;
 }
 
 bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -3812,6 +3388,7 @@ bool ath9k_hw_getcapability(struct ath_h
 		return false;
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_getcapability);
 
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 setting, int *status)
@@ -3845,6 +3422,7 @@ bool ath9k_hw_setcapability(struct ath_h
 		return false;
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_setcapability);
 
 /****************************/
 /* GPIO / RFKILL / Antennae */
@@ -3882,7 +3460,7 @@ void ath9k_hw_cfg_gpio_input(struct ath_
 {
 	u32 gpio_shift;
 
-	ASSERT(gpio < ah->caps.num_gpio_pins);
+	BUG_ON(gpio >= ah->caps.num_gpio_pins);
 
 	gpio_shift = gpio << 1;
 
@@ -3891,6 +3469,7 @@ void ath9k_hw_cfg_gpio_input(struct ath_
 		(AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
 		(AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
+EXPORT_SYMBOL(ath9k_hw_cfg_gpio_input);
 
 u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
 {
@@ -3909,6 +3488,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah,
 	else
 		return MS_REG_READ(AR, gpio) != 0;
 }
+EXPORT_SYMBOL(ath9k_hw_gpio_get);
 
 void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
 			 u32 ah_signal_type)
@@ -3924,67 +3504,26 @@ void ath9k_hw_cfg_output(struct ath_hw *
 		(AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
 		(AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
+EXPORT_SYMBOL(ath9k_hw_cfg_output);
 
 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
 {
 	REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
 		AR_GPIO_BIT(gpio));
 }
+EXPORT_SYMBOL(ath9k_hw_set_gpio);
 
 u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
 {
 	return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
 }
+EXPORT_SYMBOL(ath9k_hw_getdefantenna);
 
 void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
 {
 	REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
 }
-
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-			       enum ath9k_ant_setting settings,
-			       struct ath9k_channel *chan,
-			       u8 *tx_chainmask,
-			       u8 *rx_chainmask,
-			       u8 *antenna_cfgd)
-{
-	static u8 tx_chainmask_cfg, rx_chainmask_cfg;
-
-	if (AR_SREV_9280(ah)) {
-		if (!tx_chainmask_cfg) {
-
-			tx_chainmask_cfg = *tx_chainmask;
-			rx_chainmask_cfg = *rx_chainmask;
-		}
-
-		switch (settings) {
-		case ATH9K_ANT_FIXED_A:
-			*tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-			*rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-			*antenna_cfgd = true;
-			break;
-		case ATH9K_ANT_FIXED_B:
-			if (ah->caps.tx_chainmask >
-			    ATH9K_ANTENNA1_CHAINMASK) {
-				*tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-			}
-			*rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-			*antenna_cfgd = true;
-			break;
-		case ATH9K_ANT_VARIABLE:
-			*tx_chainmask = tx_chainmask_cfg;
-			*rx_chainmask = rx_chainmask_cfg;
-			*antenna_cfgd = true;
-			break;
-		default:
-			break;
-		}
-	} else {
-		ah->config.diversity_control = settings;
-	}
-
-	return true;
-}
+EXPORT_SYMBOL(ath9k_hw_setantenna);
 
 /*********************/
 /* General Operation */
@@ -4002,6 +3541,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *
 
 	return bits;
 }
+EXPORT_SYMBOL(ath9k_hw_getrxfilter);
 
 void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
 {
@@ -4023,19 +3563,30 @@ void ath9k_hw_setrxfilter(struct ath_hw
 		REG_WRITE(ah, AR_RXCFG,
 			  REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
 }
+EXPORT_SYMBOL(ath9k_hw_setrxfilter);
 
 bool ath9k_hw_phy_disable(struct ath_hw *ah)
 {
-	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
+	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+		return false;
+
+	ath9k_hw_init_pll(ah, NULL);
+	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_phy_disable);
 
 bool ath9k_hw_disable(struct ath_hw *ah)
 {
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return false;
 
-	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
+	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD))
+		return false;
+
+	ath9k_hw_init_pll(ah, NULL);
+	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_disable);
 
 void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
 {
@@ -4052,35 +3603,36 @@ void ath9k_hw_set_txpowerlimit(struct at
 				 min((u32) MAX_RATE_POWER,
 				 (u32) regulatory->power_limit));
 }
+EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
 
 void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
 {
-	memcpy(ah->macaddr, mac, ETH_ALEN);
+	memcpy(ath9k_hw_common(ah)->macaddr, mac, ETH_ALEN);
 }
+EXPORT_SYMBOL(ath9k_hw_setmac);
 
 void ath9k_hw_setopmode(struct ath_hw *ah)
 {
 	ath9k_hw_set_operating_mode(ah, ah->opmode);
 }
+EXPORT_SYMBOL(ath9k_hw_setopmode);
 
 void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
 {
 	REG_WRITE(ah, AR_MCAST_FIL0, filter0);
 	REG_WRITE(ah, AR_MCAST_FIL1, filter1);
 }
+EXPORT_SYMBOL(ath9k_hw_setmcastfilter);
 
-void ath9k_hw_setbssidmask(struct ath_softc *sc)
+void ath9k_hw_write_associd(struct ath_hw *ah)
 {
-	REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-	REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
-}
+	struct ath_common *common = ath9k_hw_common(ah);
 
-void ath9k_hw_write_associd(struct ath_softc *sc)
-{
-	REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-	REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-		  ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+	REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(common->curbssid));
+	REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(common->curbssid + 4) |
+		  ((common->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
 }
+EXPORT_SYMBOL(ath9k_hw_write_associd);
 
 u64 ath9k_hw_gettsf64(struct ath_hw *ah)
 {
@@ -4091,24 +3643,25 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah)
 
 	return tsf;
 }
+EXPORT_SYMBOL(ath9k_hw_gettsf64);
 
 void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
 {
 	REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
 	REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
 }
+EXPORT_SYMBOL(ath9k_hw_settsf64);
 
 void ath9k_hw_reset_tsf(struct ath_hw *ah)
 {
-	ath9k_ps_wakeup(ah->ah_sc);
 	if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
 			   AH_TSF_WRITE_TIMEOUT))
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-			"AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
 
 	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
-	ath9k_ps_restore(ah->ah_sc);
 }
+EXPORT_SYMBOL(ath9k_hw_reset_tsf);
 
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
 {
@@ -4117,11 +3670,28 @@ void ath9k_hw_set_tsfadjust(struct ath_h
 	else
 		ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
 }
+EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);
+
+/*
+ *  Extend 15-bit time stamp from rx descriptor to
+ *  a full 64-bit TSF using the current h/w TSF.
+*/
+u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
+{
+	u64 tsf;
+
+	tsf = ath9k_hw_gettsf64(ah);
+	if ((tsf & 0x7fff) < rstamp)
+		tsf -= 0x8000;
+	return (tsf & ~0x7fff) | rstamp;
+}
+EXPORT_SYMBOL(ath9k_hw_extend_tsf);
 
 bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
 	if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
+			  "bad slot time %u\n", us);
 		ah->slottime = (u32) -1;
 		return false;
 	} else {
@@ -4130,13 +3700,14 @@ bool ath9k_hw_setslottime(struct ath_hw
 		return true;
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_setslottime);
 
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
+void ath9k_hw_set11nmac2040(struct ath_hw *ah)
 {
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 	u32 macmode;
 
-	if (mode == ATH9K_HT_MACMODE_2040 &&
-	    !ah->config.cwm_ignore_extcca)
+	if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca)
 		macmode = AR_2040_JOINED_RX_CLEAR;
 	else
 		macmode = 0;
@@ -4193,6 +3764,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah)
 {
 	return REG_READ(ah, AR_TSF_L32);
 }
+EXPORT_SYMBOL(ath9k_hw_gettsf32);
 
 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 					  void (*trigger)(void *),
@@ -4206,8 +3778,9 @@ struct ath_gen_timer *ath_gen_timer_allo
 	timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
 
 	if (timer == NULL) {
-		printk(KERN_DEBUG "Failed to allocate memory"
-		       "for hw timer[%d]\n", timer_index);
+		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+			  "Failed to allocate memory"
+			  "for hw timer[%d]\n", timer_index);
 		return NULL;
 	}
 
@@ -4220,10 +3793,12 @@ struct ath_gen_timer *ath_gen_timer_allo
 
 	return timer;
 }
+EXPORT_SYMBOL(ath_gen_timer_alloc);
 
-void ath_gen_timer_start(struct ath_hw *ah,
-			 struct ath_gen_timer *timer,
-			 u32 timer_next, u32 timer_period)
+void ath9k_hw_gen_timer_start(struct ath_hw *ah,
+			      struct ath_gen_timer *timer,
+			      u32 timer_next,
+			      u32 timer_period)
 {
 	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
 	u32 tsf;
@@ -4234,8 +3809,9 @@ void ath_gen_timer_start(struct ath_hw *
 
 	tsf = ath9k_hw_gettsf32(ah);
 
-	DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER, "curent tsf %x period %x"
-		"timer_next %x\n", tsf, timer_period, timer_next);
+	ath_print(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
+		  "curent tsf %x period %x"
+		  "timer_next %x\n", tsf, timer_period, timer_next);
 
 	/*
 	 * Pull timer_next forward if the current TSF already passed it
@@ -4258,15 +3834,10 @@ void ath_gen_timer_start(struct ath_hw *
 	REG_SET_BIT(ah, AR_IMR_S5,
 		(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
 		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
-
-	if ((ah->ah_sc->imask & ATH9K_INT_GENTIMER) == 0) {
-		ath9k_hw_set_interrupts(ah, 0);
-		ah->ah_sc->imask |= ATH9K_INT_GENTIMER;
-		ath9k_hw_set_interrupts(ah, ah->ah_sc->imask);
-	}
 }
+EXPORT_SYMBOL(ath9k_hw_gen_timer_start);
 
-void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
+void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
 {
 	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
 
@@ -4285,14 +3856,8 @@ void ath_gen_timer_stop(struct ath_hw *a
 		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
 
 	clear_bit(timer->index, &timer_table->timer_mask.timer_bits);
-
-	/* if no timer is enabled, turn off interrupt mask */
-	if (timer_table->timer_mask.val == 0) {
-		ath9k_hw_set_interrupts(ah, 0);
-		ah->ah_sc->imask &= ~ATH9K_INT_GENTIMER;
-		ath9k_hw_set_interrupts(ah, ah->ah_sc->imask);
-	}
 }
+EXPORT_SYMBOL(ath9k_hw_gen_timer_stop);
 
 void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer)
 {
@@ -4302,6 +3867,7 @@ void ath_gen_timer_free(struct ath_hw *a
 	timer_table->timers[timer->index] = NULL;
 	kfree(timer);
 }
+EXPORT_SYMBOL(ath_gen_timer_free);
 
 /*
  * Generic Timer Interrupts handling
@@ -4310,6 +3876,7 @@ void ath_gen_timer_isr(struct ath_hw *ah
 {
 	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
 	struct ath_gen_timer *timer;
+	struct ath_common *common = ath9k_hw_common(ah);
 	u32 trigger_mask, thresh_mask, index;
 
 	/* get hardware generic timer interrupt status */
@@ -4324,8 +3891,8 @@ void ath_gen_timer_isr(struct ath_hw *ah
 		index = rightmost_index(timer_table, &thresh_mask);
 		timer = timer_table->timers[index];
 		BUG_ON(!timer);
-		DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER,
-			"TSF overflow for Gen timer %d\n", index);
+		ath_print(common, ATH_DBG_HWTIMER,
+			  "TSF overflow for Gen timer %d\n", index);
 		timer->overflow(timer->arg);
 	}
 
@@ -4333,21 +3900,95 @@ void ath_gen_timer_isr(struct ath_hw *ah
 		index = rightmost_index(timer_table, &trigger_mask);
 		timer = timer_table->timers[index];
 		BUG_ON(!timer);
-		DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER,
-			"Gen timer[%d] trigger\n", index);
+		ath_print(common, ATH_DBG_HWTIMER,
+			  "Gen timer[%d] trigger\n", index);
 		timer->trigger(timer->arg);
 	}
 }
+EXPORT_SYMBOL(ath_gen_timer_isr);
+
+static struct {
+	u32 version;
+	const char * name;
+} ath_mac_bb_names[] = {
+	/* Devices with external radios */
+	{ AR_SREV_VERSION_5416_PCI,	"5416" },
+	{ AR_SREV_VERSION_5416_PCIE,	"5418" },
+	{ AR_SREV_VERSION_9100,		"9100" },
+	{ AR_SREV_VERSION_9160,		"9160" },
+	/* Single-chip solutions */
+	{ AR_SREV_VERSION_9280,		"9280" },
+	{ AR_SREV_VERSION_9285,		"9285" },
+	{ AR_SREV_VERSION_9287,         "9287" },
+	{ AR_SREV_VERSION_9271,         "9271" },
+};
+
+/* For devices with external radios */
+static struct {
+	u16 version;
+	const char * name;
+} ath_rf_names[] = {
+	{ 0,				"5133" },
+	{ AR_RAD5133_SREV_MAJOR,	"5133" },
+	{ AR_RAD5122_SREV_MAJOR,	"5122" },
+	{ AR_RAD2133_SREV_MAJOR,	"2133" },
+	{ AR_RAD2122_SREV_MAJOR,	"2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version)
+{
+	int i;
+
+	for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
+		if (ath_mac_bb_names[i].version == mac_bb_version) {
+			return ath_mac_bb_names[i].name;
+		}
+	}
+
+	return "????";
+}
 
 /*
- * Primitive to disable ASPM
+ * Return the RF name. "????" is returned if the RF is unknown.
+ * Used for devices with external radios.
  */
-void ath_pcie_aspm_disable(struct ath_softc *sc)
+static const char *ath9k_hw_rf_name(u16 rf_version)
 {
-	struct pci_dev *pdev = to_pci_dev(sc->dev);
-	u8 aspm;
+	int i;
 
-	pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
-	aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
-	pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
+	for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
+		if (ath_rf_names[i].version == rf_version) {
+			return ath_rf_names[i].name;
+		}
+	}
+
+	return "????";
+}
+
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len)
+{
+	int used;
+
+	/* chipsets >= AR9280 are single-chip */
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		used = snprintf(hw_name, len,
+			       "Atheros AR%s Rev:%x",
+			       ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+			       ah->hw_version.macRev);
+	}
+	else {
+		used = snprintf(hw_name, len,
+			       "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x",
+			       ath9k_hw_mac_bb_name(ah->hw_version.macVersion),
+			       ah->hw_version.macRev,
+			       ath9k_hw_rf_name((ah->hw_version.analog5GhzRev &
+						AR_RADIO_SREV_MAJOR)),
+			       ah->hw_version.phyRev);
+	}
+
+	hw_name[used] = '\0';
 }
+EXPORT_SYMBOL(ath9k_hw_name);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -27,17 +27,24 @@
 #include "calib.h"
 #include "reg.h"
 #include "phy.h"
+#include "btcoex.h"
 
 #include "../regd.h"
+#include "../debug.h"
 
 #define ATHEROS_VENDOR_ID	0x168c
+
 #define AR5416_DEVID_PCI	0x0023
 #define AR5416_DEVID_PCIE	0x0024
 #define AR9160_DEVID_PCI	0x0027
 #define AR9280_DEVID_PCI	0x0029
 #define AR9280_DEVID_PCIE	0x002a
 #define AR9285_DEVID_PCIE	0x002b
+
 #define AR5416_AR9100_DEVID	0x000b
+
+#define AR9271_USB             0x9271
+
 #define	AR_SUBVENDOR_ID_NOG	0x0e11
 #define AR_SUBVENDOR_ID_NEW_A	0x7065
 #define AR5416_MAGIC		0x19641014
@@ -49,9 +56,18 @@
 #define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa
 #define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab
 
+#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
+
+#define	ATH_DEFAULT_NOISE_FLOOR -95
+
+#define ATH9K_RSSI_BAD			-128
+
 /* Register read/write primitives */
-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
+#define REG_WRITE(_ah, _reg, _val) \
+	ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
+
+#define REG_READ(_ah, _reg) \
+	ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
 
 #define SM(_v, _f)  (((_v) << _f##_S) & _f)
 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
@@ -91,7 +107,7 @@
 #define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
 
 #define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        1000
+#define RTC_PLL_SETTLE_DELAY        100
 #define COEF_SCALE_S                24
 #define HT40_CHANNEL_CENTER_SHIFT   10
 
@@ -132,12 +148,6 @@ enum wireless_mode {
 	ATH9K_MODE_MAX,
 };
 
-enum ath9k_ant_setting {
-	ATH9K_ANT_VARIABLE = 0,
-	ATH9K_ANT_FIXED_A,
-	ATH9K_ANT_FIXED_B
-};
-
 enum ath9k_hw_caps {
 	ATH9K_HW_CAP_MIC_AESCCM                 = BIT(0),
 	ATH9K_HW_CAP_MIC_CKIP                   = BIT(1),
@@ -201,8 +211,6 @@ struct ath9k_ops_config {
 	u32 cck_trig_high;
 	u32 cck_trig_low;
 	u32 enable_ani;
-	enum ath9k_ant_setting diversity_control;
-	u16 antenna_switch_swap;
 	int serialize_regmode;
 	bool intr_mitigation;
 #define SPUR_DISABLE        	0
@@ -218,6 +226,7 @@ struct ath9k_ops_config {
 #define AR_SPUR_FEEQ_BOUND_HT20 10
 	int spurmode;
 	u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+	u8 max_txtrig_level;
 };
 
 enum ath9k_int {
@@ -407,7 +416,7 @@ struct ath9k_hw_version {
  * Using de Bruijin sequence to to look up 1's index in a 32 bit number
  * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
  */
-#define debruijn32 0x077CB531UL
+#define debruijn32 0x077CB531U
 
 struct ath_gen_timer_configuration {
 	u32 next_addr;
@@ -433,7 +442,8 @@ struct ath_gen_timer_table {
 };
 
 struct ath_hw {
-	struct ath_softc *ah_sc;
+	struct ieee80211_hw *hw;
+	struct ath_common common;
 	struct ath9k_hw_version hw_version;
 	struct ath9k_ops_config config;
 	struct ath9k_hw_capabilities caps;
@@ -450,7 +460,6 @@ struct ath_hw {
 
 	bool sw_mgmt_crypto;
 	bool is_pciexpress;
-	u8 macaddr[ETH_ALEN];
 	u16 tx_trig_level;
 	u16 rfsilent;
 	u32 rfkill_gpio;
@@ -523,7 +532,14 @@ struct ath_hw {
 		DONT_USE_32KHZ,
 	} enable_32kHz_clock;
 
-	/* RF */
+	/* Callback for radio frequency change */
+	int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
+
+	/* Callback for baseband spur frequency */
+	void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
+					    struct ath9k_channel *chan);
+
+	/* Used to program the radio on non single-chip devices */
 	u32 *analogBank0Data;
 	u32 *analogBank1Data;
 	u32 *analogBank2Data;
@@ -540,7 +556,6 @@ struct ath_hw {
 	u32 acktimeout;
 	u32 ctstimeout;
 	u32 globaltxtimeout;
-	u8 gbeacon_rate;
 
 	/* ANI */
 	u32 proc_phyerr;
@@ -553,8 +568,10 @@ struct ath_hw {
 	int firpwr[5];
 	enum ath9k_ani_cmd ani_function;
 
+	/* Bluetooth coexistance */
+	struct ath_btcoex_hw btcoex_hw;
+
 	u32 intr_txqs;
-	enum ath9k_ht_extprotspacing extprotspacing;
 	u8 txchainmask;
 	u8 rxchainmask;
 
@@ -578,20 +595,32 @@ struct ath_hw {
 	struct ar5416IniArray iniModesAdditional;
 	struct ar5416IniArray iniModesRxGain;
 	struct ar5416IniArray iniModesTxGain;
+	struct ar5416IniArray iniModes_9271_1_0_only;
+	struct ar5416IniArray iniCckfirNormal;
+	struct ar5416IniArray iniCckfirJapan2484;
 
 	u32 intr_gen_timer_trigger;
 	u32 intr_gen_timer_thresh;
 	struct ath_gen_timer_table hw_gen_timers;
 };
 
+static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
+{
+	return &ah->common;
+}
+
+static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
+{
+	return &(ath9k_hw_common(ah)->regulatory);
+}
+
 /* Initialization, Detach, Reset */
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_detach(struct ath_hw *ah);
 int ath9k_hw_init(struct ath_hw *ah);
-void ath9k_hw_rf_free(struct ath_hw *ah);
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		   bool bChannelChange);
-void ath9k_hw_fill_cap_info(struct ath_hw *ah);
+int ath9k_hw_fill_cap_info(struct ath_hw *ah);
 bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 *result);
 bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -613,18 +642,13 @@ void ath9k_hw_cfg_output(struct ath_hw *
 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
 u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
 void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-			       enum ath9k_ant_setting settings,
-			       struct ath9k_channel *chan,
-			       u8 *tx_chainmask, u8 *rx_chainmask,
-			       u8 *antenna_cfgd);
 
 /* General Operation */
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
 u32 ath9k_hw_reverse_bits(u32 val, u32 n);
 bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-			   const struct ath_rate_table *rates,
+			   u8 phy, int kbps,
 			   u32 frameLen, u16 rateix, bool shortPreamble);
 void ath9k_hw_get_channel_centers(struct ath_hw *ah,
 				  struct ath9k_channel *chan,
@@ -637,19 +661,21 @@ void ath9k_hw_set_txpowerlimit(struct at
 void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
 void ath9k_hw_setopmode(struct ath_hw *ah);
 void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
-void ath9k_hw_setbssidmask(struct ath_softc *sc);
-void ath9k_hw_write_associd(struct ath_softc *sc);
+void ath9k_hw_setbssidmask(struct ath_hw *ah);
+void ath9k_hw_write_associd(struct ath_hw *ah);
 u64 ath9k_hw_gettsf64(struct ath_hw *ah);
 void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
 bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs);
-bool ath9k_hw_setpower(struct ath_hw *ah,
-		       enum ath9k_power_mode mode);
+
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
+
 void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
 
 /* Interrupt Handling */
@@ -663,16 +689,20 @@ struct ath_gen_timer *ath_gen_timer_allo
 					  void (*overflow)(void *),
 					  void *arg,
 					  u8 timer_index);
-void ath_gen_timer_start(struct ath_hw *ah, struct ath_gen_timer *timer,
-			 u32 timer_next, u32 timer_period);
-void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
+void ath9k_hw_gen_timer_start(struct ath_hw *ah,
+			      struct ath_gen_timer *timer,
+			      u32 timer_next,
+			      u32 timer_period);
+void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
+
 void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
 void ath_gen_timer_isr(struct ath_hw *hw);
 u32 ath9k_hw_gettsf32(struct ath_hw *ah);
 
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
+
 #define ATH_PCIE_CAP_LINK_CTRL	0x70
 #define ATH_PCIE_CAP_LINK_L0S	1
 #define ATH_PCIE_CAP_LINK_L1	2
 
-void ath_pcie_aspm_disable(struct ath_softc *sc);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/initvals.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/initvals.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/initvals.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/initvals.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,6 +21,8 @@ static const u32 ar5416Modes[][6] = {
     { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
     { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
     { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
     { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
@@ -31,11 +33,11 @@ static const u32 ar5416Modes[][6] = {
     { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e0, 0x6c48b4e0, 0x6c48b0de, 0x6c48b0de, 0x6c48b0de },
+    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
     { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
+    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
     { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
     { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
     { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
@@ -46,10 +48,10 @@ static const u32 ar5416Modes[][6] = {
     { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
     { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
     { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
+    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
     { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
+    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@@ -199,7 +201,6 @@ static const u32 ar5416Common[][2] = {
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -215,7 +216,6 @@ static const u32 ar5416Common[][2] = {
     { 0x00008178, 0x00000100 },
     { 0x0000817c, 0x00000000 },
     { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
     { 0x000081ec, 0x00000000 },
     { 0x000081f0, 0x00000000 },
     { 0x000081f4, 0x00000000 },
@@ -246,6 +246,7 @@ static const u32 ar5416Common[][2] = {
     { 0x00008258, 0x00000000 },
     { 0x0000825c, 0x400000ff },
     { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8000010 },
     { 0x00008270, 0x00000000 },
     { 0x00008274, 0x40000000 },
     { 0x00008278, 0x003e4180 },
@@ -406,9 +407,9 @@ static const u32 ar5416Common[][2] = {
     { 0x0000a25c, 0x0f0f0f01 },
     { 0x0000a260, 0xdfa91f01 },
     { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000c26c, 0x0e79e5c6 },
     { 0x0000d270, 0x00820820 },
     { 0x0000a278, 0x1ce739ce },
     { 0x0000a27c, 0x051701ce },
@@ -2551,26 +2552,27 @@ static const u32 ar9280Modes_9280_2[][6]
     { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e },
     { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
     { 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e },
     { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009850, 0x6c4000e2, 0x6c4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
+    { 0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
     { 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
     { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
     { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
     { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
     { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016 },
     { 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
     { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010 },
     { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
     { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
     { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
+    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
     { 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c },
     { 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00 },
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
@@ -2585,8 +2587,10 @@ static const u32 ar9280Modes_9280_2[][6]
     { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
     { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
     { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000 },
     { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+    { 0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000 },
     { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
 };
@@ -2813,7 +2817,6 @@ static const u32 ar9280Common_9280_2[][2
     { 0x00009958, 0x2108ecff },
     { 0x00009940, 0x14750604 },
     { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
     { 0x00009970, 0x190fb515 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
@@ -2849,7 +2852,6 @@ static const u32 ar9280Common_9280_2[][2
     { 0x0000a22c, 0x233f7180 },
     { 0x0000a234, 0x20202020 },
     { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c88000 },
     { 0x0000a240, 0x38490a20 },
     { 0x0000a244, 0x00007bb6 },
     { 0x0000a248, 0x0fff3ffc },
@@ -2859,8 +2861,8 @@ static const u32 ar9280Common_9280_2[][2
     { 0x0000a25c, 0x0f0f0f01 },
     { 0x0000a260, 0xdfa91f01 },
     { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
     { 0x0000d270, 0x00820820 },
     { 0x0000a278, 0x1ce739ce },
     { 0x0000d35c, 0x07ffffef },
@@ -2874,7 +2876,6 @@ static const u32 ar9280Common_9280_2[][2
     { 0x0000d37c, 0x7fffffe2 },
     { 0x0000d380, 0x7f3c7bba },
     { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
     { 0x0000a38c, 0x20202020 },
     { 0x0000a390, 0x20202020 },
     { 0x0000a394, 0x1ce739ce },
@@ -2940,7 +2941,7 @@ static const u32 ar9280Modes_fast_clock_
     { 0x0000801c, 0x148ec02b, 0x148ec057 },
     { 0x00008318, 0x000044c0, 0x00008980 },
     { 0x00009820, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000f0f, 0x00000f0f },
+    { 0x00009824, 0x01000f0f, 0x01000f0f },
     { 0x00009828, 0x0b020001, 0x0b020001 },
     { 0x00009834, 0x00000f0f, 0x00000f0f },
     { 0x00009844, 0x03721821, 0x03721821 },
@@ -3348,6 +3349,8 @@ static const u32 ar9280Modes_backoff_13d
 };
 
 static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
+    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002 },
     { 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008 },
@@ -3376,11 +3379,11 @@ static const u32 ar9280Modes_high_power_
     { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
     { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
     { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
-    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
 };
 
 static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
+    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
     { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
@@ -3409,8 +3412,6 @@ static const u32 ar9280Modes_original_tx
     { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
     { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
     { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
-    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
 };
 
 static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
@@ -5918,9 +5919,6 @@ static const u_int32_t ar9287Common_9287
     { 0x000099ec, 0x0cc80caa },
     { 0x000099f0, 0x00000000 },
     { 0x000099fc, 0x00001042 },
-    { 0x0000a1f4, 0x00fffeff },
-    { 0x0000a1f8, 0x00f5f9ff },
-    { 0x0000a1fc, 0xb79f6427 },
     { 0x0000a208, 0x803e4788 },
     { 0x0000a210, 0x4080a333 },
     { 0x0000a214, 0x40206c10 },
@@ -5980,7 +5978,7 @@ static const u_int32_t ar9287Common_9287
     { 0x0000b3f4, 0x00000000 },
     { 0x0000a7d8, 0x000003f1 },
     { 0x00007800, 0x00000800 },
-    { 0x00007804, 0x6c35ffc2 },
+    { 0x00007804, 0x6c35ffd2 },
     { 0x00007808, 0x6db6c000 },
     { 0x0000780c, 0x6db6cb30 },
     { 0x00007810, 0x6db6cb6c },
@@ -6000,7 +5998,7 @@ static const u_int32_t ar9287Common_9287
     { 0x00007848, 0x934934a8 },
     { 0x00007850, 0x00000000 },
     { 0x00007854, 0x00000800 },
-    { 0x00007858, 0x6c35ffc2 },
+    { 0x00007858, 0x6c35ffd2 },
     { 0x0000785c, 0x6db6c000 },
     { 0x00007860, 0x6db6cb30 },
     { 0x00007864, 0x6db6cb6c },
@@ -6027,6 +6025,22 @@ static const u_int32_t ar9287Common_9287
     { 0x000078b8, 0x2a850160 },
 };
 
+/*
+ * For Japanese regulatory requirements, 2484 MHz requires the following three
+ * registers be programmed differently from the channel between 2412 and 2472 MHz.
+ */
+static const u_int32_t ar9287Common_normal_cck_fir_coeff_92871_1[][2] = {
+    { 0x0000a1f4, 0x00fffeff },
+    { 0x0000a1f8, 0x00f5f9ff },
+    { 0x0000a1fc, 0xb79f6427 },
+};
+
+static const u_int32_t ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = {
+    { 0x0000a1f4, 0x00000000 },
+    { 0x0000a1f8, 0xefff0301 },
+    { 0x0000a1fc, 0xca9228ee },
+};
+
 static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@@ -6365,8 +6379,8 @@ static const u_int32_t ar9287PciePhy_clk
 };
 
 
-/* AR9271 initialization values automaticaly created: 03/23/09 */
-static const u_int32_t ar9271Modes_9271_1_0[][6] = {
+/* AR9271 initialization values automaticaly created: 06/04/09 */
+static const u_int32_t ar9271Modes_9271[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -6376,8 +6390,8 @@ static const u_int32_t ar9271Modes_9271_
     { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e },
+    { 0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001 },
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
     { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
@@ -6391,6 +6405,7 @@ static const u_int32_t ar9271Modes_9271_
     { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
     { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310 },
     { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
     { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
     { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
@@ -6401,7 +6416,7 @@ static const u_int32_t ar9271Modes_9271_
     { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@@ -6690,7 +6705,7 @@ static const u_int32_t ar9271Modes_9271_
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
-static const u_int32_t ar9271Common_9271_1_0[][2] = {
+static const u_int32_t ar9271Common_9271[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020045 },
     { 0x00000034, 0x00000005 },
@@ -6786,7 +6801,7 @@ static const u_int32_t ar9271Common_9271
     { 0x0000803c, 0x00000000 },
     { 0x00008048, 0x00000000 },
     { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x02000000 },
+    { 0x00008058, 0x00000000 },
     { 0x0000805c, 0x000fc78f },
     { 0x00008060, 0x0000000f },
     { 0x00008064, 0x00000000 },
@@ -6817,7 +6832,7 @@ static const u_int32_t ar9271Common_9271
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04814 },
+    { 0x00008120, 0x08f04810 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -6864,7 +6879,7 @@ static const u_int32_t ar9271Common_9271
     { 0x00008258, 0x00000000 },
     { 0x0000825c, 0x400000ff },
     { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
+    { 0x00008264, 0x88a00010 },
     { 0x00008270, 0x00000000 },
     { 0x00008274, 0x40000000 },
     { 0x00008278, 0x003e4180 },
@@ -6896,7 +6911,7 @@ static const u_int32_t ar9271Common_9271
     { 0x00007814, 0x924934a8 },
     { 0x0000781c, 0x00000000 },
     { 0x00007820, 0x00000c04 },
-    { 0x00007824, 0x00d86bff },
+    { 0x00007824, 0x00d8abff },
     { 0x00007828, 0x66964300 },
     { 0x0000782c, 0x8db6d961 },
     { 0x00007830, 0x8db6d96c },
@@ -6930,7 +6945,6 @@ static const u_int32_t ar9271Common_9271
     { 0x00009904, 0x00000000 },
     { 0x00009908, 0x00000000 },
     { 0x0000990c, 0x00000000 },
-    { 0x00009910, 0x30002310 },
     { 0x0000991c, 0x10000fff },
     { 0x00009920, 0x04900000 },
     { 0x00009928, 0x00000001 },
@@ -6944,7 +6958,7 @@ static const u_int32_t ar9271Common_9271
     { 0x00009954, 0x5f3ca3de },
     { 0x00009958, 0x0108ecff },
     { 0x00009968, 0x000003ce },
-    { 0x00009970, 0x192bb515 },
+    { 0x00009970, 0x192bb514 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
     { 0x0000997c, 0x00000000 },
@@ -7031,3 +7045,8 @@ static const u_int32_t ar9271Common_9271
     { 0x0000d380, 0x7f3c7bba },
     { 0x0000d384, 0xf3307ff0 },
 };
+
+static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
+    { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,16 @@
+config ATH9K_HW
+	tristate
+config ATH9K_COMMON
+	tristate
+
 config ATH9K
 	tristate "Atheros 802.11n wireless cards support"
-	depends on PCI && MAC80211 && WLAN_80211
+	depends on PCI && MAC80211
+	select ATH9K_HW
 	select MAC80211_LEDS
 	select LEDS_CLASS
 	select NEW_LEDS
+	select ATH9K_COMMON
 	---help---
 	  This module adds support for wireless adapters based on
 	  Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
@@ -16,13 +23,12 @@ config ATH9K
 
 	  If you choose to build a module, it'll be called ath9k.
 
-config ATH9K_DEBUG
+config ATH9K_DEBUGFS
 	bool "Atheros ath9k debugging"
-	depends on ATH9K
+	depends on ATH9K && DEBUG_FS
 	---help---
-	  Say Y, if you need ath9k to display debug messages.
-	  Pass the debug mask as a module parameter:
+	  Say Y, if you need access to ath9k's statistics for
+	  interrupts, rate control, etc.
 
-	  modprobe ath9k debug=0x00000200
+	  Also required for changing debug message flags at run time.
 
-	  Look in ath9k/debug.h for possible debug masks
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/mac.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,16 +14,16 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+#include "hw.h"
 
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
 					struct ath9k_tx_queue_info *qi)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-		"tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
-		ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
-		ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
-		ah->txurn_interrupt_mask);
+	ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT,
+		  "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+		  ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+		  ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+		  ah->txurn_interrupt_mask);
 
 	REG_WRITE(ah, AR_IMR_S0,
 		  SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
@@ -39,17 +39,21 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah,
 {
 	return REG_READ(ah, AR_QTXDP(q));
 }
+EXPORT_SYMBOL(ath9k_hw_gettxbuf);
 
 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
 {
 	REG_WRITE(ah, AR_QTXDP(q), txdp);
 }
+EXPORT_SYMBOL(ath9k_hw_puttxbuf);
 
 void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
+	ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE,
+		  "Enable TXE on queue: %u\n", q);
 	REG_WRITE(ah, AR_Q_TXE, 1 << q);
 }
+EXPORT_SYMBOL(ath9k_hw_txstart);
 
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
 {
@@ -64,13 +68,39 @@ u32 ath9k_hw_numtxpending(struct ath_hw
 
 	return npend;
 }
+EXPORT_SYMBOL(ath9k_hw_numtxpending);
 
+/**
+ * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
+ *
+ * @ah: atheros hardware struct
+ * @bIncTrigLevel: whether or not the frame trigger level should be updated
+ *
+ * The frame trigger level specifies the minimum number of bytes,
+ * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
+ * before the PCU will initiate sending the frame on the air. This can
+ * mean we initiate transmit before a full frame is on the PCU TX FIFO.
+ * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
+ * first)
+ *
+ * Caution must be taken to ensure to set the frame trigger level based
+ * on the DMA request size. For example if the DMA request size is set to
+ * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
+ * there need to be enough space in the tx FIFO for the requested transfer
+ * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
+ * the threshold to a value beyond 6, then the transmit will hang.
+ *
+ * Current dual   stream devices have a PCU TX FIFO size of 8 KB.
+ * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
+ * there is a hardware issue which forces us to use 2 KB instead so the
+ * frame trigger level must not exceed 2 KB for these chipsets.
+ */
 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
 {
 	u32 txcfg, curLevel, newLevel;
 	enum ath9k_int omask;
 
-	if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
+	if (ah->tx_trig_level >= ah->config.max_txtrig_level)
 		return false;
 
 	omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
@@ -79,7 +109,7 @@ bool ath9k_hw_updatetxtriglevel(struct a
 	curLevel = MS(txcfg, AR_FTRIG);
 	newLevel = curLevel;
 	if (bIncTrigLevel) {
-		if (curLevel < MAX_TX_FIFO_THRESHOLD)
+		if (curLevel < ah->config.max_txtrig_level)
 			newLevel++;
 	} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
 		newLevel--;
@@ -93,27 +123,28 @@ bool ath9k_hw_updatetxtriglevel(struct a
 
 	return newLevel != curLevel;
 }
+EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
 
 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
 {
 #define ATH9K_TX_STOP_DMA_TIMEOUT	4000    /* usec */
 #define ATH9K_TIME_QUANTUM		100     /* usec */
-
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 	u32 tsfLow, j, wait;
 	u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
 
 	if (q >= pCap->total_queues) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
-			"invalid queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
+			  "invalid queue: %u\n", q);
 		return false;
 	}
 
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
-			"inactive queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, "
+			  "inactive queue: %u\n", q);
 		return false;
 	}
 
@@ -126,9 +157,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *a
 	}
 
 	if (ath9k_hw_numtxpending(ah, q)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-			"%s: Num of pending TX Frames %d on Q %d\n",
-			__func__, ath9k_hw_numtxpending(ah, q), q);
+		ath_print(common, ATH_DBG_QUEUE,
+			  "%s: Num of pending TX Frames %d on Q %d\n",
+			  __func__, ath9k_hw_numtxpending(ah, q), q);
 
 		for (j = 0; j < 2; j++) {
 			tsfLow = REG_READ(ah, AR_TSF_L32);
@@ -142,9 +173,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *a
 			if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
 				break;
 
-			DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-				"TSF has moved while trying to set "
-				"quiet time TSF: 0x%08x\n", tsfLow);
+			ath_print(common, ATH_DBG_QUEUE,
+				  "TSF has moved while trying to set "
+				  "quiet time TSF: 0x%08x\n", tsfLow);
 		}
 
 		REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
@@ -155,9 +186,9 @@ bool ath9k_hw_stoptxdma(struct ath_hw *a
 		wait = wait_time;
 		while (ath9k_hw_numtxpending(ah, q)) {
 			if ((--wait) == 0) {
-				DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-					"Failed to stop TX DMA in 100 "
-					"msec after killing last frame\n");
+				ath_print(common, ATH_DBG_FATAL,
+					  "Failed to stop TX DMA in 100 "
+					  "msec after killing last frame\n");
 				break;
 			}
 			udelay(ATH9K_TIME_QUANTUM);
@@ -172,6 +203,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *a
 #undef ATH9K_TX_STOP_DMA_TIMEOUT
 #undef ATH9K_TIME_QUANTUM
 }
+EXPORT_SYMBOL(ath9k_hw_stoptxdma);
 
 void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
@@ -198,6 +230,7 @@ void ath9k_hw_filltxdesc(struct ath_hw *
 	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 }
+EXPORT_SYMBOL(ath9k_hw_filltxdesc);
 
 void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
 {
@@ -209,6 +242,7 @@ void ath9k_hw_cleartxdesc(struct ath_hw
 	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 }
+EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
 
 int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
 {
@@ -222,6 +256,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *a
 	ds->ds_txstat.ts_status = 0;
 	ds->ds_txstat.ts_flags = 0;
 
+	if (ads->ds_txstatus1 & AR_FrmXmitOK)
+		ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
 	if (ads->ds_txstatus1 & AR_ExcessiveRetries)
 		ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
 	if (ads->ds_txstatus1 & AR_Filtered)
@@ -284,6 +320,7 @@ int ath9k_hw_txprocdesc(struct ath_hw *a
 
 	return 0;
 }
+EXPORT_SYMBOL(ath9k_hw_txprocdesc);
 
 void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
 			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
@@ -319,6 +356,7 @@ void ath9k_hw_set11n_txdesc(struct ath_h
 		ads->ds_ctl11 = 0;
 	}
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
 
 void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
 				  struct ath_desc *lastds,
@@ -374,6 +412,7 @@ void ath9k_hw_set11n_ratescenario(struct
 	last_ads->ds_ctl2 = ads->ds_ctl2;
 	last_ads->ds_ctl3 = ads->ds_ctl3;
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
 
 void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
 				u32 aggrLen)
@@ -384,6 +423,7 @@ void ath9k_hw_set11n_aggr_first(struct a
 	ads->ds_ctl6 &= ~AR_AggrLen;
 	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
 
 void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
 				 u32 numDelims)
@@ -398,6 +438,7 @@ void ath9k_hw_set11n_aggr_middle(struct
 	ctl6 |= SM(numDelims, AR_PadDelim);
 	ads->ds_ctl6 = ctl6;
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
 
 void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
 {
@@ -407,6 +448,7 @@ void ath9k_hw_set11n_aggr_last(struct at
 	ads->ds_ctl1 &= ~AR_MoreAggr;
 	ads->ds_ctl6 &= ~AR_PadDelim;
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
 
 void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
 {
@@ -414,6 +456,7 @@ void ath9k_hw_clr11n_aggr(struct ath_hw
 
 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
+EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
 
 void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
 				   u32 burstDuration)
@@ -423,6 +466,7 @@ void ath9k_hw_set11n_burstduration(struc
 	ads->ds_ctl2 &= ~AR_BurstDur;
 	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
 }
+EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
 
 void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
 				     u32 vmf)
@@ -440,28 +484,30 @@ void ath9k_hw_gettxintrtxqs(struct ath_h
 	*txqs &= ah->intr_txqs;
 	ah->intr_txqs &= ~(*txqs);
 }
+EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs);
 
 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
 			    const struct ath9k_tx_queue_info *qinfo)
 {
 	u32 cw;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
 	if (q >= pCap->total_queues) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
-			"invalid queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
+			  "invalid queue: %u\n", q);
 		return false;
 	}
 
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
-			"inactive queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, "
+			  "inactive queue: %u\n", q);
 		return false;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
+	ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
 
 	qi->tqi_ver = qinfo->tqi_ver;
 	qi->tqi_subtype = qinfo->tqi_subtype;
@@ -510,23 +556,25 @@ bool ath9k_hw_set_txq_props(struct ath_h
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_set_txq_props);
 
 bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
 			    struct ath9k_tx_queue_info *qinfo)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
 	if (q >= pCap->total_queues) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
-			"invalid queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
+			  "invalid queue: %u\n", q);
 		return false;
 	}
 
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
-			"inactive queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, "
+			  "inactive queue: %u\n", q);
 		return false;
 	}
 
@@ -547,10 +595,12 @@ bool ath9k_hw_get_txq_props(struct ath_h
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_get_txq_props);
 
 int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
 			  const struct ath9k_tx_queue_info *qinfo)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info *qi;
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	int q;
@@ -574,23 +624,23 @@ int ath9k_hw_setuptxqueue(struct ath_hw
 			    ATH9K_TX_QUEUE_INACTIVE)
 				break;
 		if (q == pCap->total_queues) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"No available TX queue\n");
+			ath_print(common, ATH_DBG_FATAL,
+				  "No available TX queue\n");
 			return -1;
 		}
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
-			type);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Invalid TX queue type: %u\n", type);
 		return -1;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
+	ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
 
 	qi = &ah->txq[q];
 	if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"TX queue: %u already active\n", q);
+		ath_print(common, ATH_DBG_FATAL,
+			  "TX queue: %u already active\n", q);
 		return -1;
 	}
 	memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -613,25 +663,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw
 
 	return q;
 }
+EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
 
 bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info *qi;
 
 	if (q >= pCap->total_queues) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
-			"invalid queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
+			  "invalid queue: %u\n", q);
 		return false;
 	}
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
-			"inactive queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Release TXQ, "
+			  "inactive queue: %u\n", q);
 		return false;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
+	ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
 
 	qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
 	ah->txok_interrupt_mask &= ~(1 << q);
@@ -643,28 +695,30 @@ bool ath9k_hw_releasetxqueue(struct ath_
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
 
 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *chan = ah->curchan;
 	struct ath9k_tx_queue_info *qi;
 	u32 cwMin, chanCwMin, value;
 
 	if (q >= pCap->total_queues) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
-			"invalid queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
+			  "invalid queue: %u\n", q);
 		return false;
 	}
 
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
-			"inactive queue: %u\n", q);
+		ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, "
+			  "inactive queue: %u\n", q);
 		return true;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
+	ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
 
 	if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
 		if (chan && IS_CHAN_B(chan))
@@ -799,6 +853,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_resettxqueue);
 
 int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 			u32 pa, struct ath_desc *nds, u64 tsf)
@@ -880,6 +935,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
 
 	return 0;
 }
+EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
 
 void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags)
@@ -895,7 +951,15 @@ void ath9k_hw_setuprxdesc(struct ath_hw
 	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
 		memset(&(ads->u), 0, sizeof(ads->u));
 }
+EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
 
+/*
+ * This can stop or re-enables RX.
+ *
+ * If bool is set this will kill any frame which is currently being
+ * transferred between the MAC and baseband and also prevent any new
+ * frames from getting started.
+ */
 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
 {
 	u32 reg;
@@ -911,8 +975,9 @@ bool ath9k_hw_setrxabort(struct ath_hw *
 				     AR_DIAG_RX_ABORT));
 
 			reg = REG_READ(ah, AR_OBS_BUS_1);
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
+			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+				  "RX failed to go idle in 10 ms RXSM=0x%x\n",
+				  reg);
 
 			return false;
 		}
@@ -923,16 +988,19 @@ bool ath9k_hw_setrxabort(struct ath_hw *
 
 	return true;
 }
+EXPORT_SYMBOL(ath9k_hw_setrxabort);
 
 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
 {
 	REG_WRITE(ah, AR_RXDP, rxdp);
 }
+EXPORT_SYMBOL(ath9k_hw_putrxbuf);
 
 void ath9k_hw_rxena(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_CR, AR_CR_RXE);
 }
+EXPORT_SYMBOL(ath9k_hw_rxena);
 
 void ath9k_hw_startpcureceive(struct ath_hw *ah)
 {
@@ -942,6 +1010,7 @@ void ath9k_hw_startpcureceive(struct ath
 
 	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 }
+EXPORT_SYMBOL(ath9k_hw_startpcureceive);
 
 void ath9k_hw_stoppcurecv(struct ath_hw *ah)
 {
@@ -949,12 +1018,13 @@ void ath9k_hw_stoppcurecv(struct ath_hw
 
 	ath9k_hw_disable_mib_counters(ah);
 }
+EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
 
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
 {
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
 #define AH_RX_TIME_QUANTUM     100     /* usec */
-
+	struct ath_common *common = ath9k_hw_common(ah);
 	int i;
 
 	REG_WRITE(ah, AR_CR, AR_CR_RXD);
@@ -967,12 +1037,12 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 	}
 
 	if (i == 0) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"DMA failed to stop in %d ms "
-			"AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-			AH_RX_STOP_DMA_TIMEOUT / 1000,
-			REG_READ(ah, AR_CR),
-			REG_READ(ah, AR_DIAG_SW));
+		ath_print(common, ATH_DBG_FATAL,
+			  "DMA failed to stop in %d ms "
+			  "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+			  AH_RX_STOP_DMA_TIMEOUT / 1000,
+			  REG_READ(ah, AR_CR),
+			  REG_READ(ah, AR_DIAG_SW));
 		return false;
 	} else {
 		return true;
@@ -981,3 +1051,17 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 #undef AH_RX_TIME_QUANTUM
 #undef AH_RX_STOP_DMA_TIMEOUT
 }
+EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
+
+int ath9k_hw_beaconq_setup(struct ath_hw *ah)
+{
+	struct ath9k_tx_queue_info qi;
+
+	memset(&qi, 0, sizeof(qi));
+	qi.tqi_aifs = 1;
+	qi.tqi_cwmin = 0;
+	qi.tqi_cwmax = 0;
+	/* NB: don't enable any interrupts */
+	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
+}
+EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/mac.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/mac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/mac.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,6 +76,10 @@
 #define ATH9K_TXERR_FIFO           0x04
 #define ATH9K_TXERR_XTXOP          0x08
 #define ATH9K_TXERR_TIMER_EXPIRED  0x10
+#define ATH9K_TX_ACKED		   0x20
+#define ATH9K_TXERR_MASK						\
+	(ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO |	\
+	 ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
 
 #define ATH9K_TX_BA                0x01
 #define ATH9K_TX_PWRMGMT           0x02
@@ -85,9 +89,15 @@
 #define ATH9K_TX_SW_ABORTED        0x40
 #define ATH9K_TX_SW_FILTERED       0x80
 
+/* 64 bytes */
 #define MIN_TX_FIFO_THRESHOLD   0x1
+
+/*
+ * Single stream device AR9285 and AR9271 require 2 KB
+ * to work around a hardware issue, all other devices
+ * have can use the max 4 KB limit.
+ */
 #define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
 
 struct ath_tx_status {
 	u32 ts_tstamp;
@@ -380,6 +390,11 @@ struct ar5416_desc {
 #define AR_TxBaStatus       0x40000000
 #define AR_TxStatusRsvd01   0x80000000
 
+/*
+ * AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
+ * transmitted successfully. If clear, no ACK or BA was received to indicate
+ * successful transmission when we were expecting an ACK or BA.
+ */
 #define AR_FrmXmitOK            0x00000001
 #define AR_ExcessiveRetries     0x00000002
 #define AR_FIFOUnderrun         0x00000004
@@ -614,19 +629,8 @@ enum ath9k_cipher {
 	ATH9K_CIPHER_MIC = 127
 };
 
-enum ath9k_ht_macmode {
-	ATH9K_HT_MACMODE_20 = 0,
-	ATH9K_HT_MACMODE_2040 = 1,
-};
-
-enum ath9k_ht_extprotspacing {
-	ATH9K_HT_EXTPROTSPACING_20 = 0,
-	ATH9K_HT_EXTPROTSPACING_25 = 1,
-};
-
 struct ath_hw;
 struct ath9k_channel;
-struct ath_rate_table;
 
 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
@@ -677,5 +681,6 @@ void ath9k_hw_rxena(struct ath_hw *ah);
 void ath9k_hw_startpcureceive(struct ath_hw *ah);
 void ath9k_hw_stoppcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
 #endif /* MAC_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@
 
 #include <linux/nl80211.h>
 #include "ath9k.h"
+#include "btcoex.h"
 
 static char *dev_info = "ath9k";
 
@@ -28,6 +29,10 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
 
+static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
+module_param_named(debug, ath9k_debug, uint, 0);
+MODULE_PARM_DESC(debug, "Debugging mask");
+
 /* We use the hw_value as an index into our private channel structure */
 
 #define CHAN2G(_freq, _idx)  { \
@@ -99,37 +104,55 @@ static struct ieee80211_channel ath9k_5g
 	CHAN5G(5825, 37), /* Channel 165 */
 };
 
+/* Atheros hardware rate code addition for short premble */
+#define SHPCHECK(__hw_rate, __flags) \
+	((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
+
+#define RATE(_bitrate, _hw_rate, _flags) {              \
+	.bitrate        = (_bitrate),                   \
+	.flags          = (_flags),                     \
+	.hw_value       = (_hw_rate),                   \
+	.hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
+}
+
+static struct ieee80211_rate ath9k_legacy_rates[] = {
+	RATE(10, 0x1b, 0),
+	RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(60, 0x0b, 0),
+	RATE(90, 0x0f, 0),
+	RATE(120, 0x0a, 0),
+	RATE(180, 0x0e, 0),
+	RATE(240, 0x09, 0),
+	RATE(360, 0x0d, 0),
+	RATE(480, 0x08, 0),
+	RATE(540, 0x0c, 0),
+};
+
 static void ath_cache_conf_rate(struct ath_softc *sc,
 				struct ieee80211_conf *conf)
 {
 	switch (conf->channel->band) {
 	case IEEE80211_BAND_2GHZ:
 		if (conf_is_ht20(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+			sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
 		else if (conf_is_ht40_minus(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
 		else if (conf_is_ht40_plus(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+			sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
 		else
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11G];
+			sc->cur_rate_mode = ATH9K_MODE_11G;
 		break;
 	case IEEE80211_BAND_5GHZ:
 		if (conf_is_ht20(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+			sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
 		else if (conf_is_ht40_minus(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
 		else if (conf_is_ht40_plus(conf))
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+			sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
 		else
-			sc->cur_rate_table =
-			  sc->hw_rate_table[ATH9K_MODE_11A];
+			sc->cur_rate_mode = ATH9K_MODE_11A;
 		break;
 	default:
 		BUG_ON(1);
@@ -185,50 +208,6 @@ static u8 parse_mpdudensity(u8 mpdudensi
 	}
 }
 
-static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
-{
-	const struct ath_rate_table *rate_table = NULL;
-	struct ieee80211_supported_band *sband;
-	struct ieee80211_rate *rate;
-	int i, maxrates;
-
-	switch (band) {
-	case IEEE80211_BAND_2GHZ:
-		rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
-		break;
-	case IEEE80211_BAND_5GHZ:
-		rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
-		break;
-	default:
-		break;
-	}
-
-	if (rate_table == NULL)
-		return;
-
-	sband = &sc->sbands[band];
-	rate = sc->rates[band];
-
-	if (rate_table->rate_cnt > ATH_RATE_MAX)
-		maxrates = ATH_RATE_MAX;
-	else
-		maxrates = rate_table->rate_cnt;
-
-	for (i = 0; i < maxrates; i++) {
-		rate[i].bitrate = rate_table->info[i].ratekbps / 100;
-		rate[i].hw_value = rate_table->info[i].ratecode;
-		if (rate_table->info[i].short_preamble) {
-			rate[i].hw_value_short = rate_table->info[i].ratecode |
-				rate_table->info[i].short_preamble;
-			rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
-		}
-		sband->n_bitrates++;
-
-		DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
-			rate[i].bitrate / 10, rate[i].hw_value);
-	}
-}
-
 static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
 						struct ieee80211_hw *hw)
 {
@@ -242,6 +221,51 @@ static struct ath9k_channel *ath_get_cur
 	return channel;
 }
 
+static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
+{
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	ret = ath9k_hw_setpower(sc->sc_ah, mode);
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+
+	return ret;
+}
+
+void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (++sc->ps_usecount != 1)
+		goto unlock;
+
+	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
+void ath9k_ps_restore(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (--sc->ps_usecount != 0)
+		goto unlock;
+
+	if (sc->ps_enabled &&
+	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+			      SC_OP_WAIT_FOR_CAB |
+			      SC_OP_WAIT_FOR_PSPOLL_DATA |
+			      SC_OP_WAIT_FOR_TX_ACK)))
+		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
 /*
  * Set/change channels.  If the channel is really being changed, it's done
  * by reseting the chip.  To accomplish this we must first cleanup any pending
@@ -251,6 +275,8 @@ int ath_set_channel(struct ath_softc *sc
 		    struct ath9k_channel *hchan)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_conf *conf = &common->hw->conf;
 	bool fastcc = true, stopped;
 	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
@@ -280,19 +306,19 @@ int ath_set_channel(struct ath_softc *sc
 	if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
 		fastcc = false;
 
-	DPRINTF(sc, ATH_DBG_CONFIG,
-		"(%u MHz) -> (%u MHz), chanwidth: %d\n",
-		sc->sc_ah->curchan->channel,
-		channel->center_freq, sc->tx_chan_width);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
+		  sc->sc_ah->curchan->channel,
+		  channel->center_freq, conf_is_ht40(conf));
 
 	spin_lock_bh(&sc->sc_resetlock);
 
 	r = ath9k_hw_reset(ah, hchan, fastcc);
 	if (r) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset channel (%u Mhz) "
-			"reset status %d\n",
-			channel->center_freq, r);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to reset channel (%u Mhz) "
+			  "reset status %d\n",
+			  channel->center_freq, r);
 		spin_unlock_bh(&sc->sc_resetlock);
 		goto ps_restore;
 	}
@@ -301,8 +327,8 @@ int ath_set_channel(struct ath_softc *sc
 	sc->sc_flags &= ~SC_OP_FULL_RESET;
 
 	if (ath_startrecv(sc) != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to restart recv logic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to restart recv logic\n");
 		r = -EIO;
 		goto ps_restore;
 	}
@@ -327,6 +353,7 @@ static void ath_ani_calibrate(unsigned l
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	bool longcal = false;
 	bool shortcal = false;
 	bool aniflag = false;
@@ -351,33 +378,34 @@ static void ath_ani_calibrate(unsigned l
 	ath9k_ps_wakeup(sc);
 
 	/* Long calibration runs independently of short calibration. */
-	if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
 		longcal = true;
-		DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
-		sc->ani.longcal_timer = timestamp;
+		ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+		common->ani.longcal_timer = timestamp;
 	}
 
 	/* Short calibration applies only while caldone is false */
-	if (!sc->ani.caldone) {
-		if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
+	if (!common->ani.caldone) {
+		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
 			shortcal = true;
-			DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
-			sc->ani.shortcal_timer = timestamp;
-			sc->ani.resetcal_timer = timestamp;
+			ath_print(common, ATH_DBG_ANI,
+				  "shortcal @%lu\n", jiffies);
+			common->ani.shortcal_timer = timestamp;
+			common->ani.resetcal_timer = timestamp;
 		}
 	} else {
-		if ((timestamp - sc->ani.resetcal_timer) >=
+		if ((timestamp - common->ani.resetcal_timer) >=
 		    ATH_RESTART_CALINTERVAL) {
-			sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
-			if (sc->ani.caldone)
-				sc->ani.resetcal_timer = timestamp;
+			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
+			if (common->ani.caldone)
+				common->ani.resetcal_timer = timestamp;
 		}
 	}
 
 	/* Verify whether we must check ANI */
-	if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+	if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
 		aniflag = true;
-		sc->ani.checkani_timer = timestamp;
+		common->ani.checkani_timer = timestamp;
 	}
 
 	/* Skip all processing if there's nothing to do. */
@@ -388,16 +416,21 @@ static void ath_ani_calibrate(unsigned l
 
 		/* Perform calibration if necessary */
 		if (longcal || shortcal) {
-			sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan,
-						     sc->rx_chainmask, longcal);
+			common->ani.caldone =
+				ath9k_hw_calibrate(ah,
+						   ah->curchan,
+						   common->rx_chainmask,
+						   longcal);
 
 			if (longcal)
-				sc->ani.noise_floor = ath9k_hw_getchan_noise(ah,
+				common->ani.noise_floor = ath9k_hw_getchan_noise(ah,
 								     ah->curchan);
 
-			DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n",
-				ah->curchan->channel, ah->curchan->channelFlags,
-				sc->ani.noise_floor);
+			ath_print(common, ATH_DBG_ANI,
+				  " calibrate chan %u/%x nf: %d\n",
+				  ah->curchan->channel,
+				  ah->curchan->channelFlags,
+				  common->ani.noise_floor);
 		}
 	}
 
@@ -413,21 +446,21 @@ set_timer:
 	cal_interval = ATH_LONG_CALINTERVAL;
 	if (sc->sc_ah->config.enable_ani)
 		cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
-	if (!sc->ani.caldone)
+	if (!common->ani.caldone)
 		cal_interval = min(cal_interval, (u32)short_cal_interval);
 
-	mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+	mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
 }
 
-static void ath_start_ani(struct ath_softc *sc)
+static void ath_start_ani(struct ath_common *common)
 {
 	unsigned long timestamp = jiffies_to_msecs(jiffies);
 
-	sc->ani.longcal_timer = timestamp;
-	sc->ani.shortcal_timer = timestamp;
-	sc->ani.checkani_timer = timestamp;
+	common->ani.longcal_timer = timestamp;
+	common->ani.shortcal_timer = timestamp;
+	common->ani.checkani_timer = timestamp;
 
-	mod_timer(&sc->ani.timer,
+	mod_timer(&common->ani.timer,
 		  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
 }
 
@@ -439,17 +472,22 @@ static void ath_start_ani(struct ath_sof
  */
 void ath_update_chainmask(struct ath_softc *sc, int is_ht)
 {
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
 	if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
-	    (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) {
-		sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
-		sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
+	    (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
+		common->tx_chainmask = ah->caps.tx_chainmask;
+		common->rx_chainmask = ah->caps.rx_chainmask;
 	} else {
-		sc->tx_chainmask = 1;
-		sc->rx_chainmask = 1;
+		common->tx_chainmask = 1;
+		common->rx_chainmask = 1;
 	}
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
-		sc->tx_chainmask, sc->rx_chainmask);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "tx chmask: %d, rx chmask: %d\n",
+		  common->tx_chainmask,
+		  common->rx_chainmask);
 }
 
 static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -478,6 +516,9 @@ static void ath_node_detach(struct ath_s
 static void ath9k_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
 	u32 status = sc->intrstatus;
 
 	ath9k_ps_wakeup(sc);
@@ -502,16 +543,17 @@ static void ath9k_tasklet(unsigned long
 		 * TSF sync does not look correct; remain awake to sync with
 		 * the next Beacon.
 		 */
-		DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
+		ath_print(common, ATH_DBG_PS,
+			  "TSFOOR - Sync with next Beacon\n");
 		sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
 	}
 
-	if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 		if (status & ATH9K_INT_GENTIMER)
 			ath_gen_timer_isr(sc->sc_ah);
 
 	/* re-enable hardware interrupt */
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 	ath9k_ps_restore(sc);
 }
 
@@ -602,7 +644,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 		if (status & ATH9K_INT_TIM_TIMER) {
 			/* Clear RxAbort bit so that we can
 			 * receive frames */
-			ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			ath9k_hw_setrxabort(sc->sc_ah, 0);
 			sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
 		}
@@ -664,10 +706,11 @@ static u32 ath_get_extchanmode(struct at
 	return chanmode;
 }
 
-static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
+static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
 			   struct ath9k_keyval *hk, const u8 *addr,
 			   bool authenticator)
 {
+	struct ath_hw *ah = common->ah;
 	const u8 *key_rxmic;
 	const u8 *key_txmic;
 
@@ -687,42 +730,42 @@ static int ath_setkey_tkip(struct ath_so
 			memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
 			memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
 		}
-		return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+		return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
 	}
-	if (!sc->splitmic) {
+	if (!common->splitmic) {
 		/* TX and RX keys share the same key cache entry. */
 		memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
 		memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
-		return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+		return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
 	}
 
 	/* Separate key cache entries for TX and RX */
 
 	/* TX key goes at first index, RX key at +32. */
 	memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-	if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+	if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
 		/* TX MIC entry failed. No need to proceed further */
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Setting TX MIC Key Failed\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Setting TX MIC Key Failed\n");
 		return 0;
 	}
 
 	memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
 	/* XXX delete tx key on failure? */
-	return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
+	return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
 }
 
-static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
+static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
 {
 	int i;
 
-	for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-		if (test_bit(i, sc->keymap) ||
-		    test_bit(i + 64, sc->keymap))
+	for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
+		if (test_bit(i, common->keymap) ||
+		    test_bit(i + 64, common->keymap))
 			continue; /* At least one part of TKIP key allocated */
-		if (sc->splitmic &&
-		    (test_bit(i + 32, sc->keymap) ||
-		     test_bit(i + 64 + 32, sc->keymap)))
+		if (common->splitmic &&
+		    (test_bit(i + 32, common->keymap) ||
+		     test_bit(i + 64 + 32, common->keymap)))
 			continue; /* At least one part of TKIP key allocated */
 
 		/* Found a free slot for a TKIP key */
@@ -731,60 +774,60 @@ static int ath_reserve_key_cache_slot_tk
 	return -1;
 }
 
-static int ath_reserve_key_cache_slot(struct ath_softc *sc)
+static int ath_reserve_key_cache_slot(struct ath_common *common)
 {
 	int i;
 
 	/* First, try to find slots that would not be available for TKIP. */
-	if (sc->splitmic) {
-		for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
-			if (!test_bit(i, sc->keymap) &&
-			    (test_bit(i + 32, sc->keymap) ||
-			     test_bit(i + 64, sc->keymap) ||
-			     test_bit(i + 64 + 32, sc->keymap)))
+	if (common->splitmic) {
+		for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
+			if (!test_bit(i, common->keymap) &&
+			    (test_bit(i + 32, common->keymap) ||
+			     test_bit(i + 64, common->keymap) ||
+			     test_bit(i + 64 + 32, common->keymap)))
 				return i;
-			if (!test_bit(i + 32, sc->keymap) &&
-			    (test_bit(i, sc->keymap) ||
-			     test_bit(i + 64, sc->keymap) ||
-			     test_bit(i + 64 + 32, sc->keymap)))
+			if (!test_bit(i + 32, common->keymap) &&
+			    (test_bit(i, common->keymap) ||
+			     test_bit(i + 64, common->keymap) ||
+			     test_bit(i + 64 + 32, common->keymap)))
 				return i + 32;
-			if (!test_bit(i + 64, sc->keymap) &&
-			    (test_bit(i , sc->keymap) ||
-			     test_bit(i + 32, sc->keymap) ||
-			     test_bit(i + 64 + 32, sc->keymap)))
+			if (!test_bit(i + 64, common->keymap) &&
+			    (test_bit(i , common->keymap) ||
+			     test_bit(i + 32, common->keymap) ||
+			     test_bit(i + 64 + 32, common->keymap)))
 				return i + 64;
-			if (!test_bit(i + 64 + 32, sc->keymap) &&
-			    (test_bit(i, sc->keymap) ||
-			     test_bit(i + 32, sc->keymap) ||
-			     test_bit(i + 64, sc->keymap)))
+			if (!test_bit(i + 64 + 32, common->keymap) &&
+			    (test_bit(i, common->keymap) ||
+			     test_bit(i + 32, common->keymap) ||
+			     test_bit(i + 64, common->keymap)))
 				return i + 64 + 32;
 		}
 	} else {
-		for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-			if (!test_bit(i, sc->keymap) &&
-			    test_bit(i + 64, sc->keymap))
+		for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
+			if (!test_bit(i, common->keymap) &&
+			    test_bit(i + 64, common->keymap))
 				return i;
-			if (test_bit(i, sc->keymap) &&
-			    !test_bit(i + 64, sc->keymap))
+			if (test_bit(i, common->keymap) &&
+			    !test_bit(i + 64, common->keymap))
 				return i + 64;
 		}
 	}
 
 	/* No partially used TKIP slots, pick any available slot */
-	for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
+	for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
 		/* Do not allow slots that could be needed for TKIP group keys
 		 * to be used. This limitation could be removed if we know that
 		 * TKIP will not be used. */
 		if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
 			continue;
-		if (sc->splitmic) {
+		if (common->splitmic) {
 			if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
 				continue;
 			if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
 				continue;
 		}
 
-		if (!test_bit(i, sc->keymap))
+		if (!test_bit(i, common->keymap))
 			return i; /* Found a free slot for a key */
 	}
 
@@ -792,11 +835,12 @@ static int ath_reserve_key_cache_slot(st
 	return -1;
 }
 
-static int ath_key_config(struct ath_softc *sc,
+static int ath_key_config(struct ath_common *common,
 			  struct ieee80211_vif *vif,
 			  struct ieee80211_sta *sta,
 			  struct ieee80211_key_conf *key)
 {
+	struct ath_hw *ah = common->ah;
 	struct ath9k_keyval hk;
 	const u8 *mac = NULL;
 	int ret = 0;
@@ -842,54 +886,57 @@ static int ath_key_config(struct ath_sof
 		mac = sta->addr;
 
 		if (key->alg == ALG_TKIP)
-			idx = ath_reserve_key_cache_slot_tkip(sc);
+			idx = ath_reserve_key_cache_slot_tkip(common);
 		else
-			idx = ath_reserve_key_cache_slot(sc);
+			idx = ath_reserve_key_cache_slot(common);
 		if (idx < 0)
 			return -ENOSPC; /* no free key cache entries */
 	}
 
 	if (key->alg == ALG_TKIP)
-		ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+		ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
 				      vif->type == NL80211_IFTYPE_AP);
 	else
-		ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
+		ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
 
 	if (!ret)
 		return -EIO;
 
-	set_bit(idx, sc->keymap);
+	set_bit(idx, common->keymap);
 	if (key->alg == ALG_TKIP) {
-		set_bit(idx + 64, sc->keymap);
-		if (sc->splitmic) {
-			set_bit(idx + 32, sc->keymap);
-			set_bit(idx + 64 + 32, sc->keymap);
+		set_bit(idx + 64, common->keymap);
+		if (common->splitmic) {
+			set_bit(idx + 32, common->keymap);
+			set_bit(idx + 64 + 32, common->keymap);
 		}
 	}
 
 	return idx;
 }
 
-static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
+static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
 {
-	ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
+	struct ath_hw *ah = common->ah;
+
+	ath9k_hw_keyreset(ah, key->hw_key_idx);
 	if (key->hw_key_idx < IEEE80211_WEP_NKID)
 		return;
 
-	clear_bit(key->hw_key_idx, sc->keymap);
+	clear_bit(key->hw_key_idx, common->keymap);
 	if (key->alg != ALG_TKIP)
 		return;
 
-	clear_bit(key->hw_key_idx + 64, sc->keymap);
-	if (sc->splitmic) {
-		clear_bit(key->hw_key_idx + 32, sc->keymap);
-		clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
+	clear_bit(key->hw_key_idx + 64, common->keymap);
+	if (common->splitmic) {
+		clear_bit(key->hw_key_idx + 32, common->keymap);
+		clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
 	}
 }
 
 static void setup_ht_cap(struct ath_softc *sc,
 			 struct ieee80211_sta_ht_cap *ht_info)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	u8 tx_streams, rx_streams;
 
 	ht_info->ht_supported = true;
@@ -903,12 +950,15 @@ static void setup_ht_cap(struct ath_soft
 
 	/* set up supported mcs set */
 	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-	tx_streams = !(sc->tx_chainmask & (sc->tx_chainmask - 1)) ? 1 : 2;
-	rx_streams = !(sc->rx_chainmask & (sc->rx_chainmask - 1)) ? 1 : 2;
+	tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
+		     1 : 2;
+	rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
+		     1 : 2;
 
 	if (tx_streams != rx_streams) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n",
-			tx_streams, rx_streams);
+		ath_print(common, ATH_DBG_CONFIG,
+			  "TX streams %d, RX streams: %d\n",
+			  tx_streams, rx_streams);
 		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
 		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
 				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
@@ -925,14 +975,17 @@ static void ath9k_bss_assoc_info(struct
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *bss_conf)
 {
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	if (bss_conf->assoc) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
-			bss_conf->aid, sc->curbssid);
+		ath_print(common, ATH_DBG_CONFIG,
+			  "Bss Info ASSOC %d, bssid: %pM\n",
+			   bss_conf->aid, common->curbssid);
 
 		/* New association, store aid */
-		sc->curaid = bss_conf->aid;
-		ath9k_hw_write_associd(sc);
+		common->curaid = bss_conf->aid;
+		ath9k_hw_write_associd(ah);
 
 		/*
 		 * Request a re-configuration of Beacon related timers
@@ -947,12 +1000,12 @@ static void ath9k_bss_assoc_info(struct
 		/* Reset rssi stats */
 		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 
-		ath_start_ani(sc);
+		ath_start_ani(common);
 	} else {
-		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
-		sc->curaid = 0;
+		ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
+		common->curaid = 0;
 		/* Stop ANI */
-		del_timer_sync(&sc->ani.timer);
+		del_timer_sync(&common->ani.timer);
 	}
 }
 
@@ -1042,8 +1095,8 @@ static int ath_register_led(struct ath_s
 
 	ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
 	if (ret)
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Failed to register led:%s", led->name);
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Failed to register led:%s", led->name);
 	else
 		led->registered = 1;
 	return ret;
@@ -1124,10 +1177,11 @@ fail:
 	ath_deinit_leds(sc);
 }
 
-void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
@@ -1139,17 +1193,17 @@ void ath_radio_enable(struct ath_softc *
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, ah->curchan, false);
 	if (r) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset channel %u (%uMhz) ",
-			"reset status %d\n",
-			channel->center_freq, r);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to reset channel %u (%uMhz) ",
+			  "reset status %d\n",
+			  channel->center_freq, r);
 	}
 	spin_unlock_bh(&sc->sc_resetlock);
 
 	ath_update_txpow(sc);
 	if (ath_startrecv(sc) != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to restart recv logic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to restart recv logic\n");
 		return;
 	}
 
@@ -1164,18 +1218,18 @@ void ath_radio_enable(struct ath_softc *
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
-	ieee80211_wake_queues(sc->hw);
+	ieee80211_wake_queues(hw);
 	ath9k_ps_restore(sc);
 }
 
-void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
-	ieee80211_stop_queues(sc->hw);
+	ieee80211_stop_queues(hw);
 
 	/* Disable LED */
 	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
@@ -1189,22 +1243,22 @@ void ath_radio_disable(struct ath_softc
 	ath_flushrecv(sc);		/* flush recv queue */
 
 	if (!ah->curchan)
-		ah->curchan = ath_get_curchannel(sc, sc->hw);
+		ah->curchan = ath_get_curchannel(sc, hw);
 
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, ah->curchan, false);
 	if (r) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset channel %u (%uMhz) "
-			"reset status %d\n",
-			channel->center_freq, r);
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Unable to reset channel %u (%uMhz) "
+			  "reset status %d\n",
+			  channel->center_freq, r);
 	}
 	spin_unlock_bh(&sc->sc_resetlock);
 
 	ath9k_hw_phy_disable(ah);
 	ath9k_hw_configpcipowersave(ah, 1, 1);
 	ath9k_ps_restore(sc);
-	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 }
 
 /*******************/
@@ -1236,23 +1290,26 @@ static void ath_start_rfkill_poll(struct
 		wiphy_rfkill_start_polling(sc->hw->wiphy);
 }
 
-void ath_cleanup(struct ath_softc *sc)
+static void ath9k_uninit_hw(struct ath_softc *sc)
 {
-	ath_detach(sc);
-	free_irq(sc->irq, sc);
-	ath_bus_cleanup(sc);
-	kfree(sc->sec_wiphy);
-	ieee80211_free_hw(sc->hw);
+	struct ath_hw *ah = sc->sc_ah;
+
+	BUG_ON(!ah);
+
+	ath9k_exit_debug(ah);
+	ath9k_hw_detach(ah);
+	sc->sc_ah = NULL;
 }
 
-void ath_detach(struct ath_softc *sc)
+static void ath_clean_core(struct ath_softc *sc)
 {
 	struct ieee80211_hw *hw = sc->hw;
+	struct ath_hw *ah = sc->sc_ah;
 	int i = 0;
 
 	ath9k_ps_wakeup(sc);
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
+	dev_dbg(sc->dev, "Detach ATH hw\n");
 
 	ath_deinit_leds(sc);
 	wiphy_rfkill_stop_polling(sc->hw->wiphy);
@@ -1273,20 +1330,36 @@ void ath_detach(struct ath_softc *sc)
 	tasklet_kill(&sc->bcon_tasklet);
 
 	if (!(sc->sc_flags & SC_OP_INVALID))
-		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+		ath9k_setpower(sc, ATH9K_PM_AWAKE);
 
 	/* cleanup tx queues */
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	if ((sc->btcoex_info.no_stomp_timer) &&
-	    sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-		ath_gen_timer_free(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
+	if ((sc->btcoex.no_stomp_timer) &&
+	    ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
+}
 
-	ath9k_hw_detach(sc->sc_ah);
-	sc->sc_ah = NULL;
-	ath9k_exit_debug(sc);
+void ath_detach(struct ath_softc *sc)
+{
+	ath_clean_core(sc);
+	ath9k_uninit_hw(sc);
+}
+
+void ath_cleanup(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	ath_clean_core(sc);
+	free_irq(sc->irq, sc);
+	ath_bus_cleanup(common);
+	kfree(sc->sec_wiphy);
+	ieee80211_free_hw(sc->hw);
+
+	ath9k_uninit_hw(sc);
 }
 
 static int ath9k_reg_notifier(struct wiphy *wiphy,
@@ -1295,29 +1368,245 @@ static int ath9k_reg_notifier(struct wip
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
-	struct ath_regulatory *reg = &sc->common.regulatory;
+	struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
 
 	return ath_reg_notifier_apply(wiphy, request, reg);
 }
 
 /*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
+		btcoex->bt_priority_cnt++;
+
+	if (time_after(jiffies, btcoex->bt_priority_time +
+			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
+				  "BT priority traffic detected");
+			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
+		} else {
+			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+		}
+
+		btcoex->bt_priority_cnt = 0;
+		btcoex->bt_priority_time = jiffies;
+	}
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
+				  enum ath_stomp_type stomp_type)
+{
+	struct ath_hw *ah = sc->sc_ah;
+
+	switch (stomp_type) {
+	case ATH_BTCOEX_STOMP_ALL:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_ALL_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_LOW:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_LOW_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_NONE:
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_NONE_WLAN_WGHT);
+		break;
+	default:
+		ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+			  "Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(ah);
+}
+
+static void ath9k_gen_timer_start(struct ath_hw *ah,
+				  struct ath_gen_timer *timer,
+				  u32 timer_next,
+				  u32 timer_period)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+	ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
+
+	if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		sc->imask |= ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, sc->imask);
+	}
+}
+
+static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+
+	ath9k_hw_gen_timer_stop(ah, timer);
+
+	/* if no timer is enabled, turn off interrupt mask */
+	if (timer_table->timer_mask.val == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		sc->imask &= ~ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, sc->imask);
+	}
+}
+
+/*
+ * This is the master bt coex timer which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+static void ath_btcoex_period_timer(unsigned long data)
+{
+	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+
+	ath_detect_bt_priority(sc);
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+
+	if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
+		if (btcoex->hw_timer_enabled)
+			ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+		ath9k_gen_timer_start(ah,
+				      btcoex->no_stomp_timer,
+				      (ath9k_hw_gettsf32(ah) +
+				       btcoex->btcoex_no_stomp),
+				       btcoex->btcoex_no_stomp * 10);
+		btcoex->hw_timer_enabled = true;
+	}
+
+	mod_timer(&btcoex->period_timer, jiffies +
+				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
+}
+
+/*
+ * Generic tsf based hw timer which configures weight
+ * registers to time slice between wlan and bt traffic
+ */
+static void ath_btcoex_no_stomp_timer(void *arg)
+{
+	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_btcoex *btcoex = &sc->btcoex;
+
+	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+		  "no stomp timer running \n");
+
+	spin_lock_bh(&btcoex->btcoex_lock);
+
+	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
+	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+		ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
+
+	spin_unlock_bh(&btcoex->btcoex_lock);
+}
+
+static int ath_init_btcoex_timer(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+
+	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
+	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+		btcoex->btcoex_period / 100;
+
+	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
+			(unsigned long) sc);
+
+	spin_lock_init(&btcoex->btcoex_lock);
+
+	btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
+			ath_btcoex_no_stomp_timer,
+			ath_btcoex_no_stomp_timer,
+			(void *) sc, AR_FIRST_NDP_TIMER);
+
+	if (!btcoex->no_stomp_timer)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
+{
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+		unsigned long flags;
+		spin_lock_irqsave(&sc->sc_serial_rw, flags);
+		iowrite32(val, sc->mem + reg_offset);
+		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+	} else
+		iowrite32(val, sc->mem + reg_offset);
+}
+
+static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
+{
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+	u32 val;
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+		unsigned long flags;
+		spin_lock_irqsave(&sc->sc_serial_rw, flags);
+		val = ioread32(sc->mem + reg_offset);
+		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+	} else
+		val = ioread32(sc->mem + reg_offset);
+	return val;
+}
+
+static const struct ath_ops ath9k_common_ops = {
+	.read = ath9k_ioread32,
+	.write = ath9k_iowrite32,
+};
+
+/*
  * Initialize and fill ath_softc, ath_sofct is the
  * "Software Carrier" struct. Historically it has existed
  * to allow the separation between hardware specific
  * variables (now in ath_hw) and driver specific variables.
  */
-static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
+static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
+			  const struct ath_bus_ops *bus_ops)
 {
 	struct ath_hw *ah = NULL;
+	struct ath_common *common;
 	int r = 0, i;
 	int csz = 0;
+	int qnum;
 
 	/* XXX: hardware will not be ready until ath_open() being called */
 	sc->sc_flags |= SC_OP_INVALID;
 
-	if (ath9k_init_debug(sc) < 0)
-		printk(KERN_ERR "Unable to create debugfs files\n");
-
 	spin_lock_init(&sc->wiphy_lock);
 	spin_lock_init(&sc->sc_resetlock);
 	spin_lock_init(&sc->sc_serial_rw);
@@ -1328,75 +1617,80 @@ static int ath_init_softc(u16 devid, str
 	tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
 		     (unsigned long)sc);
 
-	/*
-	 * Cache line size is used to size and align various
-	 * structures used to communicate with the hardware.
-	 */
-	ath_read_cachesize(sc, &csz);
-	/* XXX assert csz is non-zero */
-	sc->common.cachelsz = csz << 2;	/* convert to bytes */
-
 	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-	if (!ah) {
-		r = -ENOMEM;
-		goto bad_no_ah;
-	}
+	if (!ah)
+		return -ENOMEM;
 
-	ah->ah_sc = sc;
 	ah->hw_version.devid = devid;
 	ah->hw_version.subsysid = subsysid;
 	sc->sc_ah = ah;
 
+	common = ath9k_hw_common(ah);
+	common->ops = &ath9k_common_ops;
+	common->bus_ops = bus_ops;
+	common->ah = ah;
+	common->hw = sc->hw;
+	common->priv = sc;
+	common->debug_mask = ath9k_debug;
+
+	/*
+	 * Cache line size is used to size and align various
+	 * structures used to communicate with the hardware.
+	 */
+	ath_read_cachesize(common, &csz);
+	/* XXX assert csz is non-zero */
+	common->cachelsz = csz << 2;	/* convert to bytes */
+
 	r = ath9k_hw_init(ah);
 	if (r) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to initialize hardware; "
-			"initialization status: %d\n", r);
-		goto bad;
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to initialize hardware; "
+			  "initialization status: %d\n", r);
+		goto bad_free_hw;
+	}
+
+	if (ath9k_init_debug(ah) < 0) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to create debugfs files\n");
+		goto bad_free_hw;
 	}
 
 	/* Get the hardware key cache size. */
-	sc->keymax = ah->caps.keycache_size;
-	if (sc->keymax > ATH_KEYMAX) {
-		DPRINTF(sc, ATH_DBG_ANY,
-			"Warning, using only %u entries in %u key cache\n",
-			ATH_KEYMAX, sc->keymax);
-		sc->keymax = ATH_KEYMAX;
+	common->keymax = ah->caps.keycache_size;
+	if (common->keymax > ATH_KEYMAX) {
+		ath_print(common, ATH_DBG_ANY,
+			  "Warning, using only %u entries in %u key cache\n",
+			  ATH_KEYMAX, common->keymax);
+		common->keymax = ATH_KEYMAX;
 	}
 
 	/*
 	 * Reset the key cache since some parts do not
 	 * reset the contents on initial power up.
 	 */
-	for (i = 0; i < sc->keymax; i++)
+	for (i = 0; i < common->keymax; i++)
 		ath9k_hw_keyreset(ah, (u16) i);
 
 	/* default to MONITOR mode */
 	sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
 
-	/* Setup rate tables */
-
-	ath_rate_attach(sc);
-	ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
-	ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
-
 	/*
 	 * Allocate hardware transmit queues: one queue for
 	 * beacon frames and one data queue for each QoS
 	 * priority.  Note that the hal handles reseting
 	 * these queues at the needed time.
 	 */
-	sc->beacon.beaconq = ath_beaconq_setup(ah);
+	sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah);
 	if (sc->beacon.beaconq == -1) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup a beacon xmit queue\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup a beacon xmit queue\n");
 		r = -EIO;
 		goto bad2;
 	}
 	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
 	if (sc->beacon.cabq == NULL) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup CAB xmit queue\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup CAB xmit queue\n");
 		r = -EIO;
 		goto bad2;
 	}
@@ -1410,27 +1704,27 @@ static int ath_init_softc(u16 devid, str
 	/* Setup data queues */
 	/* NB: ensure BK queue is the lowest priority h/w queue */
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup xmit queue for BK traffic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for BK traffic\n");
 		r = -EIO;
 		goto bad2;
 	}
 
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup xmit queue for BE traffic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for BE traffic\n");
 		r = -EIO;
 		goto bad2;
 	}
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup xmit queue for VI traffic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for VI traffic\n");
 		r = -EIO;
 		goto bad2;
 	}
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to setup xmit queue for VO traffic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to setup xmit queue for VO traffic\n");
 		r = -EIO;
 		goto bad2;
 	}
@@ -1438,8 +1732,8 @@ static int ath_init_softc(u16 devid, str
 	/* Initializes the noise floor to a reasonable default value.
 	 * Later on this will be updated during ANI processing. */
 
-	sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-	setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
+	common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+	setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
 
 	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
 				   ATH9K_CIPHER_TKIP, NULL)) {
@@ -1465,7 +1759,7 @@ static int ath_init_softc(u16 devid, str
 				      ATH9K_CIPHER_MIC, NULL)
 	    && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
 				      0, NULL))
-		sc->splitmic = 1;
+		common->splitmic = 1;
 
 	/* turn on mcast key search if possible */
 	if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
@@ -1480,14 +1774,14 @@ static int ath_init_softc(u16 devid, str
 		sc->sc_flags |= SC_OP_RXAGGR;
 	}
 
-	sc->tx_chainmask = ah->caps.tx_chainmask;
-	sc->rx_chainmask = ah->caps.rx_chainmask;
+	common->tx_chainmask = ah->caps.tx_chainmask;
+	common->rx_chainmask = ah->caps.rx_chainmask;
 
 	ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
 	sc->rx.defant = ath9k_hw_getdefantenna(ah);
 
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-		memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
+		memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
 
 	sc->beacon.slottime = ATH9K_SLOT_TIME_9;	/* default to short slot time */
 
@@ -1499,26 +1793,45 @@ static int ath_init_softc(u16 devid, str
 
 	/* setup channels and rates */
 
-	sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
-	sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
-		sc->rates[IEEE80211_BAND_2GHZ];
-	sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
-	sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
-		ARRAY_SIZE(ath9k_2ghz_chantable);
+	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
+		sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
+		sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+		sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+			ARRAY_SIZE(ath9k_2ghz_chantable);
+		sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
+		sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
+			ARRAY_SIZE(ath9k_legacy_rates);
+	}
 
 	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
 		sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
-		sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
-			sc->rates[IEEE80211_BAND_5GHZ];
 		sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
 		sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
 			ARRAY_SIZE(ath9k_5ghz_chantable);
+		sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
+			ath9k_legacy_rates + 4;
+		sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
+			ARRAY_SIZE(ath9k_legacy_rates) - 4;
 	}
 
-	if (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) {
-		r = ath9k_hw_btcoex_init(ah);
+	switch (ah->btcoex_hw.scheme) {
+	case ATH_BTCOEX_CFG_NONE:
+		break;
+	case ATH_BTCOEX_CFG_2WIRE:
+		ath9k_hw_btcoex_init_2wire(ah);
+		break;
+	case ATH_BTCOEX_CFG_3WIRE:
+		ath9k_hw_btcoex_init_3wire(ah);
+		r = ath_init_btcoex_timer(sc);
 		if (r)
 			goto bad2;
+		qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+		ath9k_hw_init_btcoex_hw(ah, qnum);
+		sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+		break;
+	default:
+		WARN_ON(1);
+		break;
 	}
 
 	return 0;
@@ -1527,12 +1840,9 @@ bad2:
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-bad:
-	ath9k_hw_detach(ah);
-	sc->sc_ah = NULL;
-bad_no_ah:
-	ath9k_exit_debug(sc);
 
+bad_free_hw:
+	ath9k_uninit_hw(sc);
 	return r;
 }
 
@@ -1555,7 +1865,7 @@ void ath_set_hw_capab(struct ath_softc *
 		BIT(NL80211_IFTYPE_ADHOC) |
 		BIT(NL80211_IFTYPE_MESH_POINT);
 
-	hw->wiphy->ps_default = false;
+	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
 	hw->queues = 4;
 	hw->max_rates = 4;
@@ -1568,43 +1878,53 @@ void ath_set_hw_capab(struct ath_softc *
 
 	hw->rate_control_algorithm = "ath9k_rate_control";
 
-	hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-		&sc->sbands[IEEE80211_BAND_2GHZ];
+	if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
+		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+			&sc->sbands[IEEE80211_BAND_2GHZ];
 	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			&sc->sbands[IEEE80211_BAND_5GHZ];
 }
 
 /* Device driver core initialization */
-int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid)
+int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+		    const struct ath_bus_ops *bus_ops)
 {
 	struct ieee80211_hw *hw = sc->hw;
+	struct ath_common *common;
+	struct ath_hw *ah;
 	int error = 0, i;
 	struct ath_regulatory *reg;
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+	dev_dbg(sc->dev, "Attach ATH hw\n");
 
-	error = ath_init_softc(devid, sc, subsysid);
+	error = ath_init_softc(devid, sc, subsysid, bus_ops);
 	if (error != 0)
 		return error;
 
+	ah = sc->sc_ah;
+	common = ath9k_hw_common(ah);
+
 	/* get mac address from hardware and set in mac80211 */
 
-	SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
 
 	ath_set_hw_capab(sc, hw);
 
-	error = ath_regd_init(&sc->common.regulatory, sc->hw->wiphy,
+	error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
 			      ath9k_reg_notifier);
 	if (error)
 		return error;
 
-	reg = &sc->common.regulatory;
+	reg = &common->regulatory;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-		setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-		if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-			setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+		if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes))
+			setup_ht_cap(sc,
+				     &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+		if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes))
+			setup_ht_cap(sc,
+				     &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
 	}
 
 	/* initialize tx/rx engine */
@@ -1641,9 +1961,7 @@ error_attach:
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	ath9k_hw_detach(sc->sc_ah);
-	sc->sc_ah = NULL;
-	ath9k_exit_debug(sc);
+	ath9k_uninit_hw(sc);
 
 	return error;
 }
@@ -1651,9 +1969,13 @@ error_attach:
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_hw *hw = sc->hw;
 	int r;
 
+	/* Stop ANI */
+	del_timer_sync(&common->ani.timer);
+
 	ath9k_hw_set_interrupts(ah, 0);
 	ath_drain_all_txq(sc, retry_tx);
 	ath_stoprecv(sc);
@@ -1662,12 +1984,13 @@ int ath_reset(struct ath_softc *sc, bool
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
 	if (r)
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset hardware; reset status %d\n", r);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to reset hardware; reset status %d\n", r);
 	spin_unlock_bh(&sc->sc_resetlock);
 
 	if (ath_startrecv(sc) != 0)
-		DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to start recv logic\n");
 
 	/*
 	 * We may be doing a reset in response to a request
@@ -1694,6 +2017,9 @@ int ath_reset(struct ath_softc *sc, bool
 		}
 	}
 
+	/* Start ANI */
+	ath_start_ani(common);
+
 	return r;
 }
 
@@ -1710,19 +2036,20 @@ int ath_descdma_setup(struct ath_softc *
 	((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
 #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
 #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
-
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_desc *ds;
 	struct ath_buf *bf;
 	int i, bsize, error;
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
-		name, nbuf, ndesc);
+	ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+		  name, nbuf, ndesc);
 
 	INIT_LIST_HEAD(head);
 	/* ath_desc must be a multiple of DWORDs */
 	if ((sizeof(struct ath_desc) % 4) != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
-		ASSERT((sizeof(struct ath_desc) % 4) == 0);
+		ath_print(common, ATH_DBG_FATAL,
+			  "ath_desc not DWORD aligned\n");
+		BUG_ON((sizeof(struct ath_desc) % 4) != 0);
 		error = -ENOMEM;
 		goto fail;
 	}
@@ -1755,9 +2082,9 @@ int ath_descdma_setup(struct ath_softc *
 		goto fail;
 	}
 	ds = dd->dd_desc;
-	DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
-		name, ds, (u32) dd->dd_desc_len,
-		ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+	ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+		  name, ds, (u32) dd->dd_desc_len,
+		  ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
 
 	/* allocate buffers */
 	bsize = sizeof(struct ath_buf) * nbuf;
@@ -1780,7 +2107,7 @@ int ath_descdma_setup(struct ath_softc *
 			 * descriptor fetch.
 			 */
 			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
-				ASSERT((caddr_t) bf->bf_desc <
+				BUG_ON((caddr_t) bf->bf_desc >=
 				       ((caddr_t) dd->dd_desc +
 					dd->dd_desc_len));
 
@@ -1884,31 +2211,50 @@ void ath9k_update_ichannel(struct ath_so
 		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
 	}
 
-	sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-
-	if (conf_is_ht(conf)) {
-		if (conf_is_ht40(conf))
-			sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
-
+	if (conf_is_ht(conf))
 		ichan->chanmode = ath_get_extchanmode(sc, chan,
 					    conf->channel_type);
-	}
 }
 
 /**********************/
 /* mac80211 callbacks */
 /**********************/
 
+/*
+ * (Re)start btcoex timers
+ */
+static void ath9k_btcoex_timer_resume(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+		  "Starting btcoex timers");
+
+	/* make sure duty cycle timer is also stopped when resuming */
+	if (btcoex->hw_timer_enabled)
+		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
+
+	btcoex->bt_priority_cnt = 0;
+	btcoex->bt_priority_time = jiffies;
+	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+
+	mod_timer(&btcoex->period_timer, jiffies);
+}
+
 static int ath9k_start(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_channel *curchan = hw->conf.channel;
 	struct ath9k_channel *init_channel;
 	int r;
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
-		"initial channel: %d MHz\n", curchan->center_freq);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Starting driver with initial channel: %d MHz\n",
+		  curchan->center_freq);
 
 	mutex_lock(&sc->mutex);
 
@@ -1940,7 +2286,7 @@ static int ath9k_start(struct ieee80211_
 	init_channel = ath_get_curchannel(sc, hw);
 
 	/* Reset SERDES registers */
-	ath9k_hw_configpcipowersave(sc->sc_ah, 0, 0);
+	ath9k_hw_configpcipowersave(ah, 0, 0);
 
 	/*
 	 * The basic interface to setting the hardware in a good
@@ -1950,12 +2296,12 @@ static int ath9k_start(struct ieee80211_
 	 * and then setup of the interrupt mask.
 	 */
 	spin_lock_bh(&sc->sc_resetlock);
-	r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+	r = ath9k_hw_reset(ah, init_channel, false);
 	if (r) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset hardware; reset status %d "
-			"(freq %u MHz)\n", r,
-			curchan->center_freq);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to reset hardware; reset status %d "
+			  "(freq %u MHz)\n", r,
+			  curchan->center_freq);
 		spin_unlock_bh(&sc->sc_resetlock);
 		goto mutex_unlock;
 	}
@@ -1975,7 +2321,8 @@ static int ath9k_start(struct ieee80211_
 	 * here except setup the interrupt mask.
 	 */
 	if (ath_startrecv(sc) != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to start recv logic\n");
 		r = -EIO;
 		goto mutex_unlock;
 	}
@@ -1985,10 +2332,10 @@ static int ath9k_start(struct ieee80211_
 		| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
 		| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
 		sc->imask |= ATH9K_INT_GTT;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
 		sc->imask |= ATH9K_INT_CST;
 
 	ath_cache_conf_rate(sc, &hw->conf);
@@ -1997,21 +2344,22 @@ static int ath9k_start(struct ieee80211_
 
 	/* Disable BMISS interrupt when we're not associated */
 	sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 
 	ieee80211_wake_queues(hw);
 
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 
-	if ((sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) &&
-	    !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) {
-		ath_btcoex_set_weight(&sc->btcoex_info, AR_BT_COEX_WGHT,
-				      AR_STOMP_LOW_WLAN_WGHT);
-		ath9k_hw_btcoex_enable(sc->sc_ah);
+	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
+	    !ah->btcoex_hw.enabled) {
+		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+					   AR_STOMP_LOW_WLAN_WGHT);
+		ath9k_hw_btcoex_enable(ah);
 
-		ath_pcie_aspm_disable(sc);
-		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_resume(sc, &sc->btcoex_info);
+		if (common->bus_ops->bt_coex_prep)
+			common->bus_ops->bt_coex_prep(common);
+		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+			ath9k_btcoex_timer_resume(sc);
 	}
 
 mutex_unlock:
@@ -2026,17 +2374,19 @@ static int ath9k_tx(struct ieee80211_hw
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_tx_control txctl;
-	int hdrlen, padsize;
+	int padpos, padsize;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 
 	if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
-		printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
-		       "%d\n", wiphy_name(hw->wiphy), aphy->state);
+		ath_print(common, ATH_DBG_XMIT,
+			  "ath9k: %s: TX in unexpected wiphy state "
+			  "%d\n", wiphy_name(hw->wiphy), aphy->state);
 		goto exit;
 	}
 
 	if (sc->ps_enabled) {
-		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 		/*
 		 * mac80211 does not set PM field for normal data frames, so we
 		 * need to update that based on the current PS mode.
@@ -2044,8 +2394,8 @@ static int ath9k_tx(struct ieee80211_hw
 		if (ieee80211_is_data(hdr->frame_control) &&
 		    !ieee80211_is_nullfunc(hdr->frame_control) &&
 		    !ieee80211_has_pm(hdr->frame_control)) {
-			DPRINTF(sc, ATH_DBG_PS, "Add PM=1 for a TX frame "
-				"while in PS mode\n");
+			ath_print(common, ATH_DBG_PS, "Add PM=1 for a TX frame "
+				  "while in PS mode\n");
 			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
 		}
 	}
@@ -2056,15 +2406,15 @@ static int ath9k_tx(struct ieee80211_hw
 		 * power save mode. Need to wake up hardware for the TX to be
 		 * completed and if needed, also for RX of buffered frames.
 		 */
-		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 		ath9k_ps_wakeup(sc);
 		ath9k_hw_setrxabort(sc->sc_ah, 0);
 		if (ieee80211_is_pspoll(hdr->frame_control)) {
-			DPRINTF(sc, ATH_DBG_PS, "Sending PS-Poll to pick a "
-				"buffered frame\n");
+			ath_print(common, ATH_DBG_PS,
+				  "Sending PS-Poll to pick a buffered frame\n");
 			sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA;
 		} else {
-			DPRINTF(sc, ATH_DBG_PS, "Wake up to complete TX\n");
+			ath_print(common, ATH_DBG_PS,
+				  "Wake up to complete TX\n");
 			sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK;
 		}
 		/*
@@ -2083,7 +2433,6 @@ static int ath9k_tx(struct ieee80211_hw
 	 * BSSes.
 	 */
 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
 			sc->tx.seq_no += 0x10;
 		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -2091,13 +2440,13 @@ static int ath9k_tx(struct ieee80211_hw
 	}
 
 	/* Add the padding after the header if this is not already done */
-	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-	if (hdrlen & 3) {
-		padsize = hdrlen % 4;
+	padpos = ath9k_cmn_padpos(hdr->frame_control);
+	padsize = padpos & 3;
+	if (padsize && skb->len>padpos) {
 		if (skb_headroom(skb) < padsize)
 			return -1;
 		skb_push(skb, padsize);
-		memmove(skb->data, skb->data + padsize, hdrlen);
+		memmove(skb->data, skb->data + padsize, padpos);
 	}
 
 	/* Check if a tx queue is available */
@@ -2106,10 +2455,10 @@ static int ath9k_tx(struct ieee80211_hw
 	if (!txctl.txq)
 		goto exit;
 
-	DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
+	ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
 
 	if (ath_tx_start(hw, skb, &txctl) != 0) {
-		DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
+		ath_print(common, ATH_DBG_XMIT, "TX failed\n");
 		goto exit;
 	}
 
@@ -2119,10 +2468,28 @@ exit:
 	return 0;
 }
 
+/*
+ * Pause btcoex timer and bt duty cycle timer
+ */
+static void ath9k_btcoex_timer_pause(struct ath_softc *sc)
+{
+	struct ath_btcoex *btcoex = &sc->btcoex;
+	struct ath_hw *ah = sc->sc_ah;
+
+	del_timer_sync(&btcoex->period_timer);
+
+	if (btcoex->hw_timer_enabled)
+		ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
+
+	btcoex->hw_timer_enabled = false;
+}
+
 static void ath9k_stop(struct ieee80211_hw *hw)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 
 	mutex_lock(&sc->mutex);
 
@@ -2137,7 +2504,7 @@ static void ath9k_stop(struct ieee80211_
 	}
 
 	if (sc->sc_flags & SC_OP_INVALID) {
-		DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
+		ath_print(common, ATH_DBG_ANY, "Device not present\n");
 		mutex_unlock(&sc->mutex);
 		return;
 	}
@@ -2147,33 +2514,39 @@ static void ath9k_stop(struct ieee80211_
 		return; /* another wiphy still in use */
 	}
 
-	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
-		ath9k_hw_btcoex_disable(sc->sc_ah);
-		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
-			ath_btcoex_timer_pause(sc, &sc->btcoex_info);
+	/* Ensure HW is awake when we try to shut it down. */
+	ath9k_ps_wakeup(sc);
+
+	if (ah->btcoex_hw.enabled) {
+		ath9k_hw_btcoex_disable(ah);
+		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+			ath9k_btcoex_timer_pause(sc);
 	}
 
 	/* make sure h/w will not generate any interrupt
 	 * before setting the invalid flag. */
-	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	ath9k_hw_set_interrupts(ah, 0);
 
 	if (!(sc->sc_flags & SC_OP_INVALID)) {
 		ath_drain_all_txq(sc, false);
 		ath_stoprecv(sc);
-		ath9k_hw_phy_disable(sc->sc_ah);
+		ath9k_hw_phy_disable(ah);
 	} else
 		sc->rx.rxlink = NULL;
 
 	/* disable HAL and put h/w to sleep */
-	ath9k_hw_disable(sc->sc_ah);
-	ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1);
-	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_hw_disable(ah);
+	ath9k_hw_configpcipowersave(ah, 1, 1);
+	ath9k_ps_restore(sc);
+
+	/* Finally, put the chip in FULL SLEEP mode */
+	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 
 	sc->sc_flags |= SC_OP_INVALID;
 
 	mutex_unlock(&sc->mutex);
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
+	ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
 }
 
 static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -2181,6 +2554,7 @@ static int ath9k_add_interface(struct ie
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_vif *avp = (void *)conf->vif->drv_priv;
 	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
 	int ret = 0;
@@ -2207,13 +2581,14 @@ static int ath9k_add_interface(struct ie
 		ic_opmode = conf->type;
 		break;
 	default:
-		DPRINTF(sc, ATH_DBG_FATAL,
+		ath_print(common, ATH_DBG_FATAL,
 			"Interface type %d not yet supported\n", conf->type);
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Attach a VIF of type: %d\n", ic_opmode);
 
 	/* Set the VIF opmode */
 	avp->av_opmode = ic_opmode;
@@ -2251,7 +2626,7 @@ static int ath9k_add_interface(struct ie
 	if (conf->type == NL80211_IFTYPE_AP    ||
 	    conf->type == NL80211_IFTYPE_ADHOC ||
 	    conf->type == NL80211_IFTYPE_MONITOR)
-		ath_start_ani(sc);
+		ath_start_ani(common);
 
 out:
 	mutex_unlock(&sc->mutex);
@@ -2263,24 +2638,27 @@ static void ath9k_remove_interface(struc
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_vif *avp = (void *)conf->vif->drv_priv;
 	int i;
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
+	ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
 
 	mutex_lock(&sc->mutex);
 
 	/* Stop ANI */
-	del_timer_sync(&sc->ani.timer);
+	del_timer_sync(&common->ani.timer);
 
 	/* Reclaim beacon resources */
 	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+		ath9k_ps_wakeup(sc);
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-		ath_beacon_return(sc, avp);
+		ath9k_ps_restore(sc);
 	}
 
+	ath_beacon_return(sc, avp);
 	sc->sc_flags &= ~SC_OP_BEACONS;
 
 	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
@@ -2301,32 +2679,55 @@ static int ath9k_config(struct ieee80211
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ath_hw *ah = sc->sc_ah;
-	bool all_wiphys_idle = false, disable_radio = false;
+	bool disable_radio;
 
 	mutex_lock(&sc->mutex);
 
-	/* Leave this as the first check */
+	/*
+	 * Leave this as the first check because we need to turn on the
+	 * radio if it was disabled before prior to processing the rest
+	 * of the changes. Likewise we must only disable the radio towards
+	 * the end.
+	 */
 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		bool enable_radio;
+		bool all_wiphys_idle;
+		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
 		spin_lock_bh(&sc->wiphy_lock);
 		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
+		ath9k_set_wiphy_idle(aphy, idle);
+
+		if (!idle && all_wiphys_idle)
+			enable_radio = true;
+
+		/*
+		 * After we unlock here its possible another wiphy
+		 * can be re-renabled so to account for that we will
+		 * only disable the radio toward the end of this routine
+		 * if by then all wiphys are still idle.
+		 */
 		spin_unlock_bh(&sc->wiphy_lock);
 
-		if (conf->flags & IEEE80211_CONF_IDLE){
-			if (all_wiphys_idle)
-				disable_radio = true;
-		}
-		else if (all_wiphys_idle) {
-			ath_radio_enable(sc);
-			DPRINTF(sc, ATH_DBG_CONFIG,
-				"not-idle: enabling radio\n");
+		if (enable_radio) {
+			ath_radio_enable(sc, hw);
+			ath_print(common, ATH_DBG_CONFIG,
+				  "not-idle: enabling radio\n");
 		}
 	}
 
+	/*
+	 * We just prepare to enable PS. We have to wait until our AP has
+	 * ACK'd our null data frame to disable RX otherwise we'll ignore
+	 * those ACKs and end up retransmitting the same null data frames.
+	 * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode.
+	 */
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
 		if (conf->flags & IEEE80211_CONF_PS) {
+			sc->sc_flags |= SC_OP_PS_ENABLED;
 			if (!(ah->caps.hw_caps &
 			      ATH9K_HW_CAP_AUTOSLEEP)) {
 				if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
@@ -2334,12 +2735,21 @@ static int ath9k_config(struct ieee80211
 					ath9k_hw_set_interrupts(sc->sc_ah,
 							sc->imask);
 				}
-				ath9k_hw_setrxabort(sc->sc_ah, 1);
 			}
-			sc->ps_enabled = true;
+			/*
+			 * At this point we know hardware has received an ACK
+			 * of a previously sent null data frame.
+			 */
+			if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) {
+				sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
+				sc->ps_enabled = true;
+				ath9k_hw_setrxabort(sc->sc_ah, 1);
+                        }
 		} else {
 			sc->ps_enabled = false;
-			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+			sc->sc_flags &= ~(SC_OP_PS_ENABLED |
+					  SC_OP_NULLFUNC_COMPLETED);
+			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			if (!(ah->caps.hw_caps &
 			      ATH9K_HW_CAP_AUTOSLEEP)) {
 				ath9k_hw_setrxabort(sc->sc_ah, 0);
@@ -2374,8 +2784,8 @@ static int ath9k_config(struct ieee80211
 			goto skip_chan_change;
 		}
 
-		DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
-			curchan->center_freq);
+		ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+			  curchan->center_freq);
 
 		/* XXX: remove me eventualy */
 		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
@@ -2383,7 +2793,8 @@ static int ath9k_config(struct ieee80211
 		ath_update_chainmask(sc, conf_is_ht(conf));
 
 		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
-			DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
+			ath_print(common, ATH_DBG_FATAL,
+				  "Unable to set channel\n");
 			mutex_unlock(&sc->mutex);
 			return -EINVAL;
 		}
@@ -2393,9 +2804,13 @@ skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		sc->config.txpowlimit = 2 * conf->power_level;
 
+	spin_lock_bh(&sc->wiphy_lock);
+	disable_radio = ath9k_all_wiphys_idle(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+
 	if (disable_radio) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n");
-		ath_radio_disable(sc);
+		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
+		ath_radio_disable(sc, hw);
 	}
 
 	mutex_unlock(&sc->mutex);
@@ -2431,7 +2846,8 @@ static void ath9k_configure_filter(struc
 	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
 	ath9k_ps_restore(sc);
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", rfilt);
+	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+		  "Set HW RX filter: 0x%x\n", rfilt);
 }
 
 static void ath9k_sta_notify(struct ieee80211_hw *hw,
@@ -2459,6 +2875,7 @@ static int ath9k_conf_tx(struct ieee8021
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath9k_tx_queue_info qi;
 	int ret = 0, qnum;
 
@@ -2475,15 +2892,19 @@ static int ath9k_conf_tx(struct ieee8021
 	qi.tqi_burstTime = params->txop;
 	qnum = ath_get_hal_qnum(queue, sc);
 
-	DPRINTF(sc, ATH_DBG_CONFIG,
-		"Configure tx [queue/halq] [%d/%d],  "
-		"aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
-		queue, qnum, params->aifs, params->cw_min,
-		params->cw_max, params->txop);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Configure tx [queue/halq] [%d/%d],  "
+		  "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+		  queue, qnum, params->aifs, params->cw_min,
+		  params->cw_max, params->txop);
 
 	ret = ath_txq_update(sc, qnum, &qi);
 	if (ret)
-		DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
+		ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
+
+	if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
+		if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret)
+			ath_beaconq_config(sc);
 
 	mutex_unlock(&sc->mutex);
 
@@ -2498,6 +2919,7 @@ static int ath9k_set_key(struct ieee8021
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	int ret = 0;
 
 	if (modparam_nohwcrypt)
@@ -2505,11 +2927,11 @@ static int ath9k_set_key(struct ieee8021
 
 	mutex_lock(&sc->mutex);
 	ath9k_ps_wakeup(sc);
-	DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
+	ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
 
 	switch (cmd) {
 	case SET_KEY:
-		ret = ath_key_config(sc, vif, sta, key);
+		ret = ath_key_config(common, vif, sta, key);
 		if (ret >= 0) {
 			key->hw_key_idx = ret;
 			/* push IV and Michael MIC generation to stack */
@@ -2522,7 +2944,7 @@ static int ath9k_set_key(struct ieee8021
 		}
 		break;
 	case DISABLE_KEY:
-		ath_key_delete(sc, key);
+		ath_key_delete(common, key);
 		break;
 	default:
 		ret = -EINVAL;
@@ -2542,94 +2964,67 @@ static void ath9k_bss_info_changed(struc
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
-	u32 rfilt = 0;
-	int error, i;
+	int error;
 
 	mutex_lock(&sc->mutex);
 
-	/*
-	 * TODO: Need to decide which hw opmode to use for
-	 *       multi-interface cases
-	 * XXX: This belongs into add_interface!
-	 */
-	if (vif->type == NL80211_IFTYPE_AP &&
-	    ah->opmode != NL80211_IFTYPE_AP) {
-		ah->opmode = NL80211_IFTYPE_STATION;
-		ath9k_hw_setopmode(ah);
-		memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
-		sc->curaid = 0;
-		ath9k_hw_write_associd(sc);
-		/* Request full reset to get hw opmode changed properly */
-		sc->sc_flags |= SC_OP_FULL_RESET;
-	}
+	if (changed & BSS_CHANGED_BSSID) {
+		/* Set BSSID */
+		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
+		common->curaid = 0;
+		ath9k_hw_write_associd(ah);
 
-	if ((changed & BSS_CHANGED_BSSID) &&
-	    !is_zero_ether_addr(bss_conf->bssid)) {
-		switch (vif->type) {
-		case NL80211_IFTYPE_STATION:
-		case NL80211_IFTYPE_ADHOC:
-		case NL80211_IFTYPE_MESH_POINT:
-			/* Set BSSID */
-			memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
-			memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
-			sc->curaid = 0;
-			ath9k_hw_write_associd(sc);
+		/* Set aggregation protection mode parameters */
+		sc->config.ath_aggr_prot = 0;
 
-			/* Set aggregation protection mode parameters */
-			sc->config.ath_aggr_prot = 0;
+		/* Only legacy IBSS for now */
+		if (vif->type == NL80211_IFTYPE_ADHOC)
+			ath_update_chainmask(sc, 0);
 
-			DPRINTF(sc, ATH_DBG_CONFIG,
-				"RX filter 0x%x bssid %pM aid 0x%x\n",
-				rfilt, sc->curbssid, sc->curaid);
+		ath_print(common, ATH_DBG_CONFIG,
+			  "BSSID: %pM aid: 0x%x\n",
+			  common->curbssid, common->curaid);
 
-			/* need to reconfigure the beacon */
-			sc->sc_flags &= ~SC_OP_BEACONS ;
+		/* need to reconfigure the beacon */
+		sc->sc_flags &= ~SC_OP_BEACONS ;
+	}
 
-			break;
-		default:
-			break;
-		}
+	/* Enable transmission of beacons (AP, IBSS, MESH) */
+	if ((changed & BSS_CHANGED_BEACON) ||
+	    ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
+		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+		error = ath_beacon_alloc(aphy, vif);
+		if (!error)
+			ath_beacon_config(sc, vif);
 	}
 
-	if ((vif->type == NL80211_IFTYPE_ADHOC) ||
-	    (vif->type == NL80211_IFTYPE_AP) ||
-	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-		if ((changed & BSS_CHANGED_BEACON) ||
-		    (changed & BSS_CHANGED_BEACON_ENABLED &&
-		     bss_conf->enable_beacon)) {
-			/*
-			 * Allocate and setup the beacon frame.
-			 *
-			 * Stop any previous beacon DMA.  This may be
-			 * necessary, for example, when an ibss merge
-			 * causes reconfiguration; we may be called
-			 * with beacon transmission active.
-			 */
-			ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+	/* Disable transmission of beacons */
+	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
+		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
 
+	if (changed & BSS_CHANGED_BEACON_INT) {
+		sc->beacon_interval = bss_conf->beacon_int;
+		/*
+		 * In case of AP mode, the HW TSF has to be reset
+		 * when the beacon interval changes.
+		 */
+		if (vif->type == NL80211_IFTYPE_AP) {
+			sc->sc_flags |= SC_OP_TSF_RESET;
+			ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
 			error = ath_beacon_alloc(aphy, vif);
 			if (!error)
 				ath_beacon_config(sc, vif);
+		} else {
+			ath_beacon_config(sc, vif);
 		}
 	}
 
-	/* Check for WLAN_CAPABILITY_PRIVACY ? */
-	if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
-		for (i = 0; i < IEEE80211_WEP_NKID; i++)
-			if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
-				ath9k_hw_keysetmac(sc->sc_ah,
-						   (u16)i,
-						   sc->curbssid);
-	}
-
-	/* Only legacy IBSS for now */
-	if (vif->type == NL80211_IFTYPE_ADHOC)
-		ath_update_chainmask(sc, 0);
-
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
-			bss_conf->use_short_preamble);
+		ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+			  bss_conf->use_short_preamble);
 		if (bss_conf->use_short_preamble)
 			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
 		else
@@ -2637,8 +3032,8 @@ static void ath9k_bss_info_changed(struc
 	}
 
 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
-			bss_conf->use_cts_prot);
+		ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+			  bss_conf->use_cts_prot);
 		if (bss_conf->use_cts_prot &&
 		    hw->conf.channel->band != IEEE80211_BAND_5GHZ)
 			sc->sc_flags |= SC_OP_PROTECT_ENABLE;
@@ -2647,23 +3042,11 @@ static void ath9k_bss_info_changed(struc
 	}
 
 	if (changed & BSS_CHANGED_ASSOC) {
-		DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+		ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
 			bss_conf->assoc);
 		ath9k_bss_assoc_info(sc, vif, bss_conf);
 	}
 
-	/*
-	 * The HW TSF has to be reset when the beacon interval changes.
-	 * We set the flag here, and ath_beacon_config_ap() would take this
-	 * into account when it gets called through the subsequent
-	 * config_interface() call - with IFCC_BEACON in the changed field.
-	 */
-
-	if (changed & BSS_CHANGED_BEACON_INT) {
-		sc->sc_flags |= SC_OP_TSF_RESET;
-		sc->beacon_interval = bss_conf->beacon_int;
-	}
-
 	mutex_unlock(&sc->mutex);
 }
 
@@ -2696,11 +3079,16 @@ static void ath9k_reset_tsf(struct ieee8
 	struct ath_softc *sc = aphy->sc;
 
 	mutex_lock(&sc->mutex);
+
+	ath9k_ps_wakeup(sc);
 	ath9k_hw_reset_tsf(sc->sc_ah);
+	ath9k_ps_restore(sc);
+
 	mutex_unlock(&sc->mutex);
 }
 
 static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
 			      enum ieee80211_ampdu_mlme_action action,
 			      struct ieee80211_sta *sta,
 			      u16 tid, u16 *ssn)
@@ -2717,18 +3105,25 @@ static int ath9k_ampdu_action(struct iee
 	case IEEE80211_AMPDU_RX_STOP:
 		break;
 	case IEEE80211_AMPDU_TX_START:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_start(sc, sta, tid, ssn);
-		ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+		ath9k_ps_restore(sc);
 		break;
 	case IEEE80211_AMPDU_TX_STOP:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_stop(sc, sta, tid);
-		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+		ath9k_ps_restore(sc);
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_resume(sc, sta, tid);
+		ath9k_ps_restore(sc);
 		break;
 	default:
-		DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Unknown AMPDU action\n");
 	}
 
 	return ret;
@@ -2796,64 +3191,6 @@ struct ieee80211_ops ath9k_ops = {
 	.rfkill_poll        = ath9k_rfkill_poll_state,
 };
 
-static struct {
-	u32 version;
-	const char * name;
-} ath_mac_bb_names[] = {
-	{ AR_SREV_VERSION_5416_PCI,	"5416" },
-	{ AR_SREV_VERSION_5416_PCIE,	"5418" },
-	{ AR_SREV_VERSION_9100,		"9100" },
-	{ AR_SREV_VERSION_9160,		"9160" },
-	{ AR_SREV_VERSION_9280,		"9280" },
-	{ AR_SREV_VERSION_9285,		"9285" },
-	{ AR_SREV_VERSION_9287,         "9287" }
-};
-
-static struct {
-	u16 version;
-	const char * name;
-} ath_rf_names[] = {
-	{ 0,				"5133" },
-	{ AR_RAD5133_SREV_MAJOR,	"5133" },
-	{ AR_RAD5122_SREV_MAJOR,	"5122" },
-	{ AR_RAD2133_SREV_MAJOR,	"2133" },
-	{ AR_RAD2122_SREV_MAJOR,	"2122" }
-};
-
-/*
- * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
- */
-const char *
-ath_mac_bb_name(u32 mac_bb_version)
-{
-	int i;
-
-	for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
-		if (ath_mac_bb_names[i].version == mac_bb_version) {
-			return ath_mac_bb_names[i].name;
-		}
-	}
-
-	return "????";
-}
-
-/*
- * Return the RF name. "????" is returned if the RF is unknown.
- */
-const char *
-ath_rf_name(u16 rf_version)
-{
-	int i;
-
-	for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
-		if (ath_rf_names[i].version == rf_version) {
-			return ath_rf_names[i].name;
-		}
-	}
-
-	return "????";
-}
-
 static int __init ath9k_init(void)
 {
 	int error;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,22 +1,28 @@
-ath9k-y +=	hw.o \
-		eeprom.o \
-		eeprom_def.o \
-		eeprom_4k.o \
-		eeprom_9287.o \
-		mac.o \
-		calib.o \
-		ani.o \
-		phy.o \
-		beacon.o \
+ath9k-y +=	beacon.o \
 		main.o \
 		recv.o \
 		xmit.o \
 		virtual.o \
-		rc.o \
-		btcoex.o
+		rc.o
 
 ath9k-$(CONFIG_PCI) += pci.o
 ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
-ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
+ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
+
+ath9k_hw-y:=	hw.o \
+		eeprom.o \
+		eeprom_def.o \
+		eeprom_4k.o \
+		eeprom_9287.o \
+		calib.o \
+		ani.o \
+		phy.o \
+		btcoex.o \
+		mac.o \
+
+obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
+
+obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
+ath9k_common-y:=	common.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,8 +31,9 @@ static struct pci_device_id ath_pci_id_t
 };
 
 /* return bus cachesize in 4B word units */
-static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
 {
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
 	u8 u8tmp;
 
 	pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, &u8tmp);
@@ -48,8 +49,9 @@ static void ath_pci_read_cachesize(struc
 		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
 }
 
-static void ath_pci_cleanup(struct ath_softc *sc)
+static void ath_pci_cleanup(struct ath_common *common)
 {
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
 	struct pci_dev *pdev = to_pci_dev(sc->dev);
 
 	pci_iounmap(pdev, sc->mem);
@@ -57,9 +59,11 @@ static void ath_pci_cleanup(struct ath_s
 	pci_release_region(pdev, 0);
 }
 
-static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 {
-	(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+	struct ath_hw *ah = (struct ath_hw *) common->ah;
+
+	common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
 
 	if (!ath9k_hw_wait(ah,
 			   AR_EEPROM_STATUS_DATA,
@@ -69,16 +73,34 @@ static bool ath_pci_eeprom_read(struct a
 		return false;
 	}
 
-	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+	*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
 		   AR_EEPROM_STATUS_DATA_VAL);
 
 	return true;
 }
 
-static struct ath_bus_ops ath_pci_bus_ops = {
+/*
+ * Bluetooth coexistance requires disabling ASPM.
+ */
+static void ath_pci_bt_coex_prep(struct ath_common *common)
+{
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
+	struct pci_dev *pdev = to_pci_dev(sc->dev);
+	u8 aspm;
+
+	if (!pdev->is_pcie)
+		return;
+
+	pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
+	aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
+	pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
+}
+
+static const struct ath_bus_ops ath_pci_bus_ops = {
 	.read_cachesize = ath_pci_read_cachesize,
 	.cleanup = ath_pci_cleanup,
 	.eeprom_read = ath_pci_eeprom_read,
+	.bt_coex_prep = ath_pci_bt_coex_prep,
 };
 
 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -92,6 +114,7 @@ static int ath_pci_probe(struct pci_dev
 	u32 val;
 	int ret = 0;
 	struct ath_hw *ah;
+	char hw_name[64];
 
 	if (pci_enable_device(pdev))
 		return -EIO;
@@ -177,10 +200,9 @@ static int ath_pci_probe(struct pci_dev
 	sc->hw = hw;
 	sc->dev = &pdev->dev;
 	sc->mem = mem;
-	sc->bus_ops = &ath_pci_bus_ops;
 
 	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
-	ret = ath_init_device(id->device, sc, subsysid);
+	ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize device\n");
 		goto bad3;
@@ -197,14 +219,11 @@ static int ath_pci_probe(struct pci_dev
 	sc->irq = pdev->irq;
 
 	ah = sc->sc_ah;
+	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
 	printk(KERN_INFO
-	       "%s: Atheros AR%s MAC/BB Rev:%x "
-	       "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+	       "%s: %s mem=0x%lx, irq=%d\n",
 	       wiphy_name(hw->wiphy),
-	       ath_mac_bb_name(ah->hw_version.macVersion),
-	       ah->hw_version.macRev,
-	       ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-	       ah->hw_version.phyRev,
+	       hw_name,
 	       (unsigned long)mem, pdev->irq);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/phy.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/phy.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,90 +14,70 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "ath9k.h"
+/**
+ * DOC: Programming Atheros 802.11n analog front end radios
+ *
+ * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
+ * devices have either an external AR2133 analog front end radio for single
+ * band 2.4 GHz communication or an AR5133 analog front end radio for dual
+ * band 2.4 GHz / 5 GHz communication.
+ *
+ * All devices after the AR5416 and AR5418 family starting with the AR9280
+ * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
+ * into a single-chip and require less programming.
+ *
+ * The following single-chips exist with a respective embedded radio:
+ *
+ * AR9280 - 11n dual-band 2x2 MIMO for PCIe
+ * AR9281 - 11n single-band 1x2 MIMO for PCIe
+ * AR9285 - 11n single-band 1x1 for PCIe
+ * AR9287 - 11n single-band 2x2 MIMO for PCIe
+ *
+ * AR9220 - 11n dual-band 2x2 MIMO for PCI
+ * AR9223 - 11n single-band 2x2 MIMO for PCI
+ *
+ * AR9287 - 11n single-band 1x1 MIMO for USB
+ */
 
-void
-ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
-		    int regWrites)
-{
-	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-}
+#include "hw.h"
 
-bool
-ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+/**
+ * ath9k_hw_write_regs - ??
+ *
+ * @ah: atheros hardware structure
+ * @freqIndex:
+ * @regWrites:
+ *
+ * Used for both the chipsets with an external AR2133/AR5133 radios and
+ * single-chip devices.
+ */
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
 {
-	u32 channelSel = 0;
-	u32 bModeSynth = 0;
-	u32 aModeRefSel = 0;
-	u32 reg32 = 0;
-	u16 freq;
-	struct chan_centers centers;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	if (freq < 4800) {
-		u32 txctl;
-
-		if (((freq - 2192) % 5) == 0) {
-			channelSel = ((freq - 672) * 2 - 3040) / 10;
-			bModeSynth = 0;
-		} else if (((freq - 2224) % 5) == 0) {
-			channelSel = ((freq - 704) * 2 - 3040) / 10;
-			bModeSynth = 1;
-		} else {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Invalid channel %u MHz\n", freq);
-			return false;
-		}
-
-		channelSel = (channelSel << 2) & 0xff;
-		channelSel = ath9k_hw_reverse_bits(channelSel, 8);
-
-		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-		if (freq == 2484) {
-
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-		} else {
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
-		}
-
-	} else if ((freq % 20) == 0 && freq >= 5120) {
-		channelSel =
-		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
-		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else if ((freq % 10) == 0) {
-		channelSel =
-		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
-		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
-			aModeRefSel = ath9k_hw_reverse_bits(2, 2);
-		else
-			aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else if ((freq % 5) == 0) {
-		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
-		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Invalid channel %u MHz\n", freq);
-		return false;
-	}
-
-	reg32 =
-	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
-	    (1 << 5) | 0x1;
-
-	REG_WRITE(ah, AR_PHY(0x37), reg32);
-
-	ah->curchan = chan;
-	ah->curchan_rad_index = -1;
-
-	return true;
+	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 }
 
-void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-				 struct ath9k_channel *chan)
+/**
+ * ath9k_hw_ar9280_set_channel - set channel on single-chip device
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * This is the function to change channel on single-chip devices, that is
+ * all devices after ar9280.
+ *
+ * This function takes the channel value in MHz and sets
+ * hardware channel value. Assumes writes have been enabled to analog bus.
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ */
+int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u16 bMode, fracMode, aModeRefSel = 0;
 	u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
@@ -110,22 +90,34 @@ void ath9k_hw_ar9280_set_channel(struct
 	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
 	reg32 &= 0xc0000000;
 
-	if (freq < 4800) {
+	if (freq < 4800) { /* 2 GHz, fractional mode */
 		u32 txctl;
+		int regWrites = 0;
 
 		bMode = 1;
 		fracMode = 1;
 		aModeRefSel = 0;
 		channelSel = (freq * 0x10000) / 15;
 
-		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-		if (freq == 2484) {
-
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+		if (AR_SREV_9287_11_OR_LATER(ah)) {
+			if (freq == 2484) {
+				/* Enable channel spreading for channel 14 */
+				REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
+						1, regWrites);
+			} else {
+				REG_WRITE_ARRAY(&ah->iniCckfirNormal,
+						1, regWrites);
+			}
 		} else {
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+			txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+			if (freq == 2484) {
+				/* Enable channel spreading for channel 14 */
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+					  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+			} else {
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+					  txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
+			}
 		}
 	} else {
 		bMode = 0;
@@ -143,10 +135,15 @@ void ath9k_hw_ar9280_set_channel(struct
 		case 1:
 		default:
 			aModeRefSel = 0;
+			/*
+			 * Enable 2G (fractional) mode for channels
+			 * which are 5MHz spaced.
+			 */
 			fracMode = 1;
 			refDivA = 1;
 			channelSel = (freq * 0x8000) / 15;
 
+			/* RefDivA setting */
 			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
 				      AR_AN_SYNTH9_REFDIVA, refDivA);
 
@@ -168,12 +165,284 @@ void ath9k_hw_ar9280_set_channel(struct
 
 	ah->curchan = chan;
 	ah->curchan_rad_index = -1;
+
+	return 0;
 }
 
-static void
-ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-			   u32 numBits, u32 firstBit,
-			   u32 column)
+/**
+ * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int freq;
+	int bin, cur_bin;
+	int bb_spur_off, spur_subchannel_sd;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, newVal;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+	struct chan_centers centers;
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	bool is2GHz = IS_CHAN_2GHZ(chan);
+
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	ah->config.spurmode = SPUR_ENABLE_EEPROM;
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+
+		if (is2GHz)
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+		else
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - freq;
+
+		if (IS_CHAN_HT40(chan)) {
+			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+				bb_spur = cur_bb_spur;
+				break;
+			}
+		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur) {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+		return;
+	} else {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+	}
+
+	bin = bb_spur * 320;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+	if (IS_CHAN_HT40(chan)) {
+		if (bb_spur < 0) {
+			spur_subchannel_sd = 1;
+			bb_spur_off = bb_spur + 10;
+		} else {
+			spur_subchannel_sd = 0;
+			bb_spur_off = bb_spur - 10;
+		}
+	} else {
+		spur_subchannel_sd = 0;
+		bb_spur_off = bb_spur;
+	}
+
+	if (IS_CHAN_HT40(chan))
+		spur_delta_phase =
+			((bb_spur * 262144) /
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+	else
+		spur_delta_phase =
+			((bb_spur * 524288) /
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp_v = abs(cur_vit_mask - bin);
+
+			if (tmp_v < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28)
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28)
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28)
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28)
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+/* All code below is for non single-chip solutions */
+
+/**
+ * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
+ * @rfbuf:
+ * @reg32:
+ * @numBits:
+ * @firstBit:
+ * @column:
+ *
+ * Performs analog "swizzling" of parameters into their location.
+ * Used on external AR2133/AR5133 radios.
+ */
+static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+				       u32 numBits, u32 firstBit,
+				       u32 column)
 {
 	u32 tmp32, mask, arrayEntry, lastBit;
 	int32_t bitPosition, bitsLeft;
@@ -197,26 +466,466 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u
 	}
 }
 
-bool
-ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-		     u16 modesIndex)
+/*
+ * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
+ * rf_pwd_icsyndiv.
+ *
+ * Theoretical Rules:
+ *   if 2 GHz band
+ *      if forceBiasAuto
+ *         if synth_freq < 2412
+ *            bias = 0
+ *         else if 2412 <= synth_freq <= 2422
+ *            bias = 1
+ *         else // synth_freq > 2422
+ *            bias = 2
+ *      else if forceBias > 0
+ *         bias = forceBias & 7
+ *      else
+ *         no change, use value from ini file
+ *   else
+ *      no change, invalid band
+ *
+ *  1st Mod:
+ *    2422 also uses value of 2
+ *    <approved>
+ *
+ *  2nd Mod:
+ *    Less than 2412 uses value of 0, 2412 and above uses value of 2
+ */
+static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 tmp_reg;
+	int reg_writes = 0;
+	u32 new_bias = 0;
+
+	if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
+		return;
+	}
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	if (synth_freq < 2412)
+		new_bias = 0;
+	else if (synth_freq < 2422)
+		new_bias = 1;
+	else
+		new_bias = 2;
+
+	/* pre-reverse this field */
+	tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
+
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Force rf_pwd_icsyndiv to %1d on %4d\n",
+		  new_bias, synth_freq);
+
+	/* swizzle rf_pwd_icsyndiv */
+	ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
+
+	/* write Bank 6 with new params */
+	REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
+}
+
+/**
+ * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
+ * @ah: atheros hardware stucture
+ * @chan:
+ *
+ * For the external AR2133/AR5133 radios, takes the MHz channel value and set
+ * the channel value. Assumes writes enabled to analog bus and bank6 register
+ * cache in ah->analogBank6Data.
+ */
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 channelSel = 0;
+	u32 bModeSynth = 0;
+	u32 aModeRefSel = 0;
+	u32 reg32 = 0;
+	u16 freq;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	if (freq < 4800) {
+		u32 txctl;
+
+		if (((freq - 2192) % 5) == 0) {
+			channelSel = ((freq - 672) * 2 - 3040) / 10;
+			bModeSynth = 0;
+		} else if (((freq - 2224) % 5) == 0) {
+			channelSel = ((freq - 704) * 2 - 3040) / 10;
+			bModeSynth = 1;
+		} else {
+			ath_print(common, ATH_DBG_FATAL,
+				  "Invalid channel %u MHz\n", freq);
+			return -EINVAL;
+		}
+
+		channelSel = (channelSel << 2) & 0xff;
+		channelSel = ath9k_hw_reverse_bits(channelSel, 8);
+
+		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+		if (freq == 2484) {
+
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+		} else {
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+		}
+
+	} else if ((freq % 20) == 0 && freq >= 5120) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 10) == 0) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
+		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+			aModeRefSel = ath9k_hw_reverse_bits(2, 2);
+		else
+			aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 5) == 0) {
+		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Invalid channel %u MHz\n", freq);
+		return -EINVAL;
+	}
+
+	ath9k_hw_force_bias(ah, freq);
+
+	reg32 =
+	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+	    (1 << 5) | 0x1;
+
+	REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
+
+	return 0;
+}
+
+/**
+ * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For non single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int bin, cur_bin;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, new;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	bool is2GHz = IS_CHAN_2GHZ(chan);
+
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur)
+		return;
+
+	bin = bb_spur * 32;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+		     AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+		     AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+		     AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
+
+	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+	       AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+	       AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+	       AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+	       SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, new);
+
+	spur_delta_phase = ((bb_spur * 524288) / 100) &
+		AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
+
+	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+	       SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, new);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp_v = abs(cur_vit_mask - bin);
+
+			if (tmp_v < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28)
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28)
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28)
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28)
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+/**
+ * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
+ * @ah: atheros hardware structure
+ *
+ * Only required for older devices with external AR2133/AR5133 radios.
+ */
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+{
+#define ATH_ALLOC_BANK(bank, size) do { \
+		bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
+		if (!bank) { \
+			ath_print(common, ATH_DBG_FATAL, \
+				  "Cannot allocate RF banks\n"); \
+			return -ENOMEM; \
+		} \
+	} while (0);
+
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
+	ATH_ALLOC_BANK(ah->addac5416_21,
+		       ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
+	ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
+
+	return 0;
+#undef ATH_ALLOC_BANK
+}
+
+
+/**
+ * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
+ * @ah: atheros hardware struture
+ * For the external AR2133/AR5133 radios banks.
+ */
+void
+ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
+{
+#define ATH_FREE_BANK(bank) do { \
+		kfree(bank); \
+		bank = NULL; \
+	} while (0);
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	ATH_FREE_BANK(ah->analogBank0Data);
+	ATH_FREE_BANK(ah->analogBank1Data);
+	ATH_FREE_BANK(ah->analogBank2Data);
+	ATH_FREE_BANK(ah->analogBank3Data);
+	ATH_FREE_BANK(ah->analogBank6Data);
+	ATH_FREE_BANK(ah->analogBank6TPCData);
+	ATH_FREE_BANK(ah->analogBank7Data);
+	ATH_FREE_BANK(ah->addac5416_21);
+	ATH_FREE_BANK(ah->bank6Temp);
+
+#undef ATH_FREE_BANK
+}
+
+/* *
+ * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
+ * @ah: atheros hardware structure
+ * @chan:
+ * @modesIndex:
+ *
+ * Used for the external AR2133/AR5133 radios.
+ *
+ * Reads the EEPROM header info from the device structure and programs
+ * all rf registers. This routine requires access to the analog
+ * rf device. This is not required for single-chip devices.
+ */
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+			  u16 modesIndex)
 {
 	u32 eepMinorRev;
 	u32 ob5GHz = 0, db5GHz = 0;
 	u32 ob2GHz = 0, db2GHz = 0;
 	int regWrites = 0;
 
+	/*
+	 * Software does not need to program bank data
+	 * for single chip devices, that is AR9280 or anything
+	 * after that.
+	 */
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		return true;
 
+	/* Setup rf parameters */
 	eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
 
+	/* Setup Bank 0 Write */
 	RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
 
+	/* Setup Bank 1 Write */
 	RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
 
+	/* Setup Bank 2 Write */
 	RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
 
+	/* Setup Bank 6 Write */
 	RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
 		      modesIndex);
 	{
@@ -227,6 +936,7 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah,
 		}
 	}
 
+	/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
 	if (eepMinorRev >= 2) {
 		if (IS_CHAN_2GHZ(chan)) {
 			ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
@@ -245,8 +955,10 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah,
 		}
 	}
 
+	/* Setup Bank 7 Setup */
 	RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
 
+	/* Write Analog registers */
 	REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
 			   regWrites);
 	REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
@@ -262,137 +974,3 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah,
 
 	return true;
 }
-
-void
-ath9k_hw_rf_free(struct ath_hw *ah)
-{
-#define ATH_FREE_BANK(bank) do { \
-		kfree(bank); \
-		bank = NULL; \
-	} while (0);
-
-	ATH_FREE_BANK(ah->analogBank0Data);
-	ATH_FREE_BANK(ah->analogBank1Data);
-	ATH_FREE_BANK(ah->analogBank2Data);
-	ATH_FREE_BANK(ah->analogBank3Data);
-	ATH_FREE_BANK(ah->analogBank6Data);
-	ATH_FREE_BANK(ah->analogBank6TPCData);
-	ATH_FREE_BANK(ah->analogBank7Data);
-	ATH_FREE_BANK(ah->addac5416_21);
-	ATH_FREE_BANK(ah->bank6Temp);
-#undef ATH_FREE_BANK
-}
-
-bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
-{
-	if (!AR_SREV_9280_10_OR_LATER(ah)) {
-		ah->analogBank0Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank0.ia_rows), GFP_KERNEL);
-		ah->analogBank1Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank1.ia_rows), GFP_KERNEL);
-		ah->analogBank2Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank2.ia_rows), GFP_KERNEL);
-		ah->analogBank3Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank3.ia_rows), GFP_KERNEL);
-		ah->analogBank6Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6.ia_rows), GFP_KERNEL);
-		ah->analogBank6TPCData =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6TPC.ia_rows), GFP_KERNEL);
-		ah->analogBank7Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank7.ia_rows), GFP_KERNEL);
-
-		if (ah->analogBank0Data == NULL
-		    || ah->analogBank1Data == NULL
-		    || ah->analogBank2Data == NULL
-		    || ah->analogBank3Data == NULL
-		    || ah->analogBank6Data == NULL
-		    || ah->analogBank6TPCData == NULL
-		    || ah->analogBank7Data == NULL) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Cannot allocate RF banks\n");
-			*status = -ENOMEM;
-			return false;
-		}
-
-		ah->addac5416_21 =
-		    kzalloc((sizeof(u32) *
-			     ah->iniAddac.ia_rows *
-			     ah->iniAddac.ia_columns), GFP_KERNEL);
-		if (ah->addac5416_21 == NULL) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Cannot allocate addac5416_21\n");
-			*status = -ENOMEM;
-			return false;
-		}
-
-		ah->bank6Temp =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6.ia_rows), GFP_KERNEL);
-		if (ah->bank6Temp == NULL) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Cannot allocate bank6Temp\n");
-			*status = -ENOMEM;
-			return false;
-		}
-	}
-
-	return true;
-}
-
-void
-ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int i, regWrites = 0;
-	u32 bank6SelMask;
-	u32 *bank6Temp = ah->bank6Temp;
-
-	switch (ah->config.diversity_control) {
-	case ATH9K_ANT_FIXED_A:
-		bank6SelMask =
-		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_0 : REDUCE_CHAIN_1;
-		break;
-	case ATH9K_ANT_FIXED_B:
-		bank6SelMask =
-		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_1 : REDUCE_CHAIN_0;
-		break;
-	case ATH9K_ANT_VARIABLE:
-		return;
-		break;
-	default:
-		return;
-		break;
-	}
-
-	for (i = 0; i < ah->iniBank6.ia_rows; i++)
-		bank6Temp[i] = ah->analogBank6Data[i];
-
-	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
-
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
-
-	REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
-
-	REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
-#ifdef ALTER_SWITCH
-	REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
-		  (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
-		  | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
-#endif
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/phy.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/phy.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/phy.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,20 +17,23 @@
 #ifndef PHY_H
 #define PHY_H
 
-void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-				 struct ath9k_channel
-				 *chan);
-bool ath9k_hw_set_channel(struct ath_hw *ah,
-			  struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
-			 u32 freqIndex, int regWrites);
+/* Common between single chip and non single-chip solutions */
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites);
+
+/* Single chip radio settings */
+int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+/* Routines below are for non single-chip solutions */
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
+void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
+
 bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 			  struct ath9k_channel *chan,
 			  u16 modesIndex);
-void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
-				   struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hw *ah,
-		      int *status);
 
 #define AR_PHY_BASE     0x9800
 #define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
@@ -45,6 +48,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_FC_DYN2040_EN        0x00000004
 #define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
 #define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
+/* For 25 MHz channel spacing -- not used but supported by hw */
 #define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
 #define AR_PHY_FC_HT_EN             0x00000040
 #define AR_PHY_FC_SHORT_GI_40       0x00000080
@@ -185,8 +189,20 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_PLL_CTL_44_2133  0xeb
 #define AR_PHY_PLL_CTL_40_2133  0xea
 
-#define AR_PHY_SPECTRAL_SCAN		0x9912
-#define AR_PHY_SPECTRAL_SCAN_ENABLE	0x1
+#define AR_PHY_SPECTRAL_SCAN			0x9910  /* AR9280 spectral scan configuration register */
+#define	AR_PHY_SPECTRAL_SCAN_ENABLE		0x1
+#define AR_PHY_SPECTRAL_SCAN_ENA		0x00000001  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ENA_S		0  /* Enable spectral scan, reg 68, bit 0 */
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE		0x00000002  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S		1  /* Activate spectral scan reg 68, bit 1*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD		0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S	4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD		0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S		8
+#define AR_PHY_SPECTRAL_SCAN_COUNT		0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S		16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT	0x01000000  /* Short repeat, reg 68, bit 24*/
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S	24  /* Short repeat, reg 68, bit 24*/
 
 #define AR_PHY_RX_DELAY           0x9914
 #define AR_PHY_SEARCH_START_DELAY 0x9918
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/rc.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/rc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,133 +19,92 @@
 
 static const struct ath_rate_table ar5416_11na_ratetable = {
 	42,
+	8, /* MCS start */
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0x0b, 0x00, 12,
-			0, 0, 0, 0, 0, 0 },
+			5400, 0, 12, 0, 0, 0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800,  0x0f, 0x00, 18,
-			0, 1, 1, 1, 1, 0 },
+			7800,  1, 18, 0, 1, 1, 1, 1 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 0x0a, 0x00, 24,
-			2, 2, 2, 2, 2, 0 },
+			10000, 2, 24, 2, 2, 2, 2, 2 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 0x0e, 0x00, 36,
-			2,  3, 3, 3, 3, 0 },
+			13900, 3, 36, 2, 3, 3, 3, 3 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 0x09, 0x00, 48,
-			4,  4, 4, 4, 4, 0 },
+			17300, 4, 48, 4, 4, 4, 4, 4 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 0x0d, 0x00, 72,
-			4,  5, 5, 5, 5, 0 },
+			23000, 5, 72, 4, 5, 5, 5, 5 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 0x08, 0x00, 96,
-			4,  6, 6, 6, 6, 0 },
+			27400, 6, 96, 4, 6, 6, 6, 6 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 0x0c, 0x00, 108,
-			4,  7, 7, 7, 7, 0 },
+			29300, 7, 108, 4, 7, 7, 7, 7 },
 		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0x80, 0x00, 0,
-			0, 8, 24, 8, 24, 3216 },
+			6400, 0, 0, 0, 8, 24, 8, 24 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 0x81, 0x00, 1,
-			2, 9, 25, 9, 25, 6434 },
+			12700, 1, 1, 2, 9, 25, 9, 25 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 0x82, 0x00, 2,
-			2, 10, 26, 10, 26, 9650 },
+			18800, 2, 2, 2, 10, 26, 10, 26 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 0x83, 0x00, 3,
-			4,  11, 27, 11, 27, 12868 },
+			25000, 3, 3, 4, 11, 27, 11, 27 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 0x84, 0x00, 4,
-			4,  12, 28, 12, 28, 19304 },
+			36700, 4, 4, 4, 12, 28, 12, 28 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 0x85, 0x00, 5,
-			4,  13, 29, 13, 29, 25740 },
+			48100, 5, 5, 4, 13, 29, 13, 29 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 0x86, 0x00, 6,
-			4,  14, 30, 14, 30,  28956 },
+			53500, 6, 6, 4, 14, 30, 14, 30 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 0x87, 0x00, 7,
-			4,  15, 31, 15, 32, 32180 },
+			59000, 7, 7, 4, 15, 31, 15, 32 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 0x88, 0x00,
-			8, 3, 16, 33, 16, 33, 6430 },
+			12700, 8, 8, 3, 16, 33, 16, 33 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 0x89, 0x00, 9,
-			2, 17, 34, 17, 34, 12860 },
+			24800, 9, 9, 2, 17, 34, 17, 34 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 0x8a, 0x00, 10,
-			2, 18, 35, 18, 35, 19300 },
+			36600, 10, 10, 2, 18, 35, 18, 35 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 0x8b, 0x00, 11,
-			4,  19, 36, 19, 36, 25736 },
+			48100, 11, 11, 4, 19, 36, 19, 36 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 0x8c, 0x00, 12,
-			4,  20, 37, 20, 37, 38600 },
+			69500, 12, 12, 4, 20, 37, 20, 37 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 0x8d, 0x00, 13,
-			4,  21, 38, 21, 38, 51472 },
+			89500, 13, 13, 4, 21, 38, 21, 38 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 0x8e, 0x00, 14,
-			4,  22, 39, 22, 39, 57890 },
+			98900, 14, 14, 4, 22, 39, 22, 39 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 0x8f, 0x00, 15,
-			4,  23, 40, 23, 41, 64320 },
+			108300, 15, 15, 4, 23, 40, 23, 41 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0x80, 0x00, 0,
-			0, 8, 24, 24, 24, 6684 },
+			13200, 0, 0, 0, 8, 24, 24, 24 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 0x81, 0x00, 1,
-			2, 9, 25, 25, 25, 13368 },
+			25900, 1, 1, 2, 9, 25, 25, 25 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 0x82, 0x00, 2,
-			2, 10, 26, 26, 26, 20052 },
+			38600, 2, 2, 2, 10, 26, 26, 26 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 0x83, 0x00, 3,
-			4,  11, 27, 27, 27, 26738 },
+			49800, 3, 3, 4, 11, 27, 27, 27 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 0x84, 0x00, 4,
-			4,  12, 28, 28, 28, 40104 },
+			72200, 4, 4, 4, 12, 28, 28, 28 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 0x85, 0x00, 5,
-			4,  13, 29, 29, 29, 53476 },
+			92900, 5, 5, 4, 13, 29, 29, 29 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 0x86, 0x00, 6,
-			4,  14, 30, 30, 30, 60156 },
+			102700, 6, 6, 4, 14, 30, 30, 30 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 0x87, 0x00, 7,
-			4,  15, 31, 32, 32, 66840 },
+			112000, 7, 7, 4, 15, 31, 32, 32 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 0x87, 0x00, 7,
-			4,  15, 31, 32, 32, 74200 },
+			122000, 7, 7, 4, 15, 31, 32, 32 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 0x88, 0x00, 8,
-			0, 16, 33, 33, 33, 13360 },
+			25800, 8, 8, 0, 16, 33, 33, 33 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 0x89, 0x00, 9,
-			2, 17, 34, 34, 34, 26720 },
+			49800, 9, 9, 2, 17, 34, 34, 34 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 0x8a, 0x00, 10,
-			2, 18, 35, 35, 35, 40080 },
+			71900, 10, 10, 2, 18, 35, 35, 35 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 0x8b, 0x00, 11,
-			4,  19, 36, 36, 36, 53440 },
+			92500, 11, 11, 4, 19, 36, 36, 36 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 0x8c, 0x00, 12,
-			4,  20, 37, 37, 37, 80160 },
+			130300, 12, 12, 4, 20, 37, 37, 37 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 0x8d, 0x00, 13,
-			4,  21, 38, 38, 38, 106880 },
+			162800, 13, 13, 4, 21, 38, 38, 38 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 0x8e, 0x00, 14,
-			4,  22, 39, 39, 39, 120240 },
+			178200, 14, 14, 4, 22, 39, 39, 39 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 0x8f, 0x00, 15,
-			4,  23, 40, 41, 41, 133600 },
+			192100, 15, 15, 4, 23, 40, 41, 41 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 0x8f, 0x00, 15,
-			4,  23, 40, 41, 41, 148400 },
+			207000, 15, 15, 4, 23, 40, 41, 41 },
 	},
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
@@ -156,177 +115,125 @@ static const struct ath_rate_table ar541
 
 static const struct ath_rate_table ar5416_11ng_ratetable = {
 	46,
+	12, /* MCS start */
 	{
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0x1b, 0x00, 2,
-			0, 0, 0, 0, 0, 0 },
+			900, 0, 2, 0, 0, 0, 0, 0 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1900, 0x1a, 0x04, 4,
-			1, 1, 1, 1, 1, 0 },
+			1900, 1, 4, 1, 1, 1, 1, 1 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4900, 0x19, 0x04, 11,
-			2, 2, 2, 2, 2, 0 },
+			4900, 2, 11, 2, 2, 2, 2, 2 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			8100, 0x18, 0x04, 22,
-			3, 3, 3, 3, 3, 0 },
+			8100, 3, 22, 3, 3, 3, 3, 3 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0x0b, 0x00, 12,
-			4, 4, 4, 4, 4, 0 },
+			5400, 4, 12, 4, 4, 4, 4, 4 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 0x0f, 0x00, 18,
-			4, 5, 5, 5, 5, 0 },
+			7800, 5, 18, 4, 5, 5, 5, 5 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10100, 0x0a, 0x00, 24,
-			6, 6, 6, 6, 6, 0 },
+			10100, 6, 24, 6, 6, 6, 6, 6 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			14100,  0x0e, 0x00, 36,
-			6, 7, 7, 7, 7, 0 },
+			14100, 7, 36, 6, 7, 7, 7, 7 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17700, 0x09, 0x00, 48,
-			8,  8, 8, 8, 8, 0 },
+			17700, 8, 48, 8, 8, 8, 8, 8 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23700, 0x0d, 0x00, 72,
-			8,  9, 9, 9, 9, 0 },
+			23700, 9, 72, 8, 9, 9, 9, 9 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 0x08, 0x00, 96,
-			8,  10, 10, 10, 10, 0 },
+			27400, 10, 96, 8, 10, 10, 10, 10 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			30900, 0x0c, 0x00, 108,
-			8,  11, 11, 11, 11, 0 },
+			30900, 11, 108, 8, 11, 11, 11, 11 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0x80, 0x00, 0,
-			4, 12, 28, 12, 28, 3216 },
+			6400, 0, 0, 4, 12, 28, 12, 28 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 0x81, 0x00, 1,
-			6, 13, 29, 13, 29, 6434 },
+			12700, 1, 1, 6, 13, 29, 13, 29 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 0x82, 0x00, 2,
-			6, 14, 30, 14, 30, 9650 },
+			18800, 2, 2, 6, 14, 30, 14, 30 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 0x83, 0x00, 3,
-			8,  15, 31, 15, 31, 12868 },
+			25000, 3, 3, 8, 15, 31, 15, 31 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 0x84, 0x00, 4,
-			8,  16, 32, 16, 32, 19304 },
+			36700, 4, 4, 8, 16, 32, 16, 32 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 0x85, 0x00, 5,
-			8,  17, 33, 17, 33, 25740 },
+			48100, 5, 5, 8, 17, 33, 17, 33 },
 		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 0x86, 0x00, 6,
-			8,  18, 34, 18, 34, 28956 },
+			53500, 6, 6, 8, 18, 34, 18, 34 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 0x87, 0x00, 7,
-			8,  19, 35, 19, 36, 32180 },
+			59000, 7, 7, 8, 19, 35, 19, 36 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 0x88, 0x00, 8,
-			4, 20, 37, 20, 37, 6430 },
+			12700, 8, 8, 4, 20, 37, 20, 37 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 0x89, 0x00, 9,
-			6, 21, 38, 21, 38, 12860 },
+			24800, 9, 9, 6, 21, 38, 21, 38 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 0x8a, 0x00, 10,
-			6, 22, 39, 22, 39, 19300 },
+			36600, 10, 10, 6, 22, 39, 22, 39 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 0x8b, 0x00, 11,
-			8,  23, 40, 23, 40, 25736 },
+			48100, 11, 11, 8, 23, 40, 23, 40 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 0x8c, 0x00, 12,
-			8,  24, 41, 24, 41, 38600 },
+			69500, 12, 12, 8, 24, 41, 24, 41 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 0x8d, 0x00, 13,
-			8,  25, 42, 25, 42, 51472 },
+			89500, 13, 13, 8, 25, 42, 25, 42 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 0x8e, 0x00, 14,
-			8,  26, 43, 26, 44, 57890 },
+			98900, 14, 14, 8, 26, 43, 26, 44 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 0x8f, 0x00, 15,
-			8,  27, 44, 27, 45, 64320 },
+			108300, 15, 15, 8, 27, 44, 27, 45 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0x80, 0x00, 0,
-			8, 12, 28, 28, 28, 6684 },
+			13200, 0, 0, 8, 12, 28, 28, 28 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 0x81, 0x00, 1,
-			8, 13, 29, 29, 29, 13368 },
+			25900, 1, 1, 8, 13, 29, 29, 29 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 0x82, 0x00, 2,
-			8, 14, 30, 30, 30, 20052 },
+			38600, 2, 2, 8, 14, 30, 30, 30 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 0x83, 0x00, 3,
-			8,  15, 31, 31, 31, 26738 },
+			49800, 3, 3, 8,  15, 31, 31, 31 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 0x84, 0x00, 4,
-			8,  16, 32, 32, 32, 40104 },
+			72200, 4, 4, 8, 16, 32, 32, 32 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 0x85, 0x00, 5,
-			8,  17, 33, 33, 33, 53476 },
+			92900, 5, 5, 8, 17, 33, 33, 33 },
 		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 0x86, 0x00, 6,
-			8,  18, 34, 34, 34, 60156 },
+			102700, 6, 6, 8, 18, 34, 34, 34 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 0x87, 0x00, 7,
-			8,  19, 35, 36, 36, 66840 },
+			112000, 7, 7, 8, 19, 35, 36, 36 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 0x87, 0x00, 7,
-			8,  19, 35, 36, 36, 74200 },
+			122000, 7, 7, 8, 19, 35, 36, 36 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 0x88, 0x00, 8,
-			8, 20, 37, 37, 37, 13360 },
+			25800, 8, 8, 8, 20, 37, 37, 37 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 0x89, 0x00, 9,
-			8, 21, 38, 38, 38, 26720 },
+			49800, 9, 9, 8, 21, 38, 38, 38 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 0x8a, 0x00, 10,
-			8, 22, 39, 39, 39, 40080 },
+			71900, 10, 10, 8, 22, 39, 39, 39 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 0x8b, 0x00, 11,
-			8,  23, 40, 40, 40, 53440 },
+			92500, 11, 11, 8, 23, 40, 40, 40 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 0x8c, 0x00, 12,
-			8,  24, 41, 41, 41, 80160 },
+			130300, 12, 12, 8, 24, 41, 41, 41 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 0x8d, 0x00, 13,
-			8,  25, 42, 42, 42, 106880 },
+			162800, 13, 13, 8, 25, 42, 42, 42 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 0x8e, 0x00, 14,
-			8,  26, 43, 43, 43, 120240 },
+			178200, 14, 14, 8, 26, 43, 43, 43 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 0x8f, 0x00, 15,
-			8,  27, 44, 45, 45, 133600 },
+			192100, 15, 15, 8, 27, 44, 45, 45 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 0x8f, 0x00, 15,
-			8,  27, 44, 45, 45, 148400 },
-		},
+			207000, 15, 15, 8, 27, 44, 45, 45 },
+	},
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
 };
 
 static const struct ath_rate_table ar5416_11a_ratetable = {
 	8,
+	0,
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0x0b, 0x00, (0x80|12),
-			0, 0, 0 },
+			5400, 0, 12, 0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 0x0f, 0x00, 18,
-			0, 1, 0 },
+			7800,  1, 18, 0, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 0x0a, 0x00, (0x80|24),
-			2, 2, 0 },
+			10000, 2, 24, 2, 2, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 0x0e, 0x00, 36,
-			2, 3, 0 },
+			13900, 3, 36, 2, 3, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 0x09, 0x00, (0x80|48),
-			4,  4, 0 },
+			17300, 4, 48, 4, 4, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 0x0d, 0x00, 72,
-			4,  5, 0 },
+			23000, 5, 72, 4, 5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 0x08, 0x00, 96,
-			4,  6, 0 },
+			27400, 6, 96, 4, 6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 0x0c, 0x00, 108,
-			4,  7, 0 },
+			29300, 7, 108, 4, 7, 0 },
 	},
 	50,  /* probe interval */
 	0,   /* Phy rates allowed initially */
@@ -334,48 +241,51 @@ static const struct ath_rate_table ar541
 
 static const struct ath_rate_table ar5416_11g_ratetable = {
 	12,
+	0,
 	{
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0x1b, 0x00, 2,
-			0, 0, 0 },
+			900, 0, 2, 0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1900, 0x1a, 0x04, 4,
-			1, 1, 0 },
+			1900, 1, 4, 1, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4900, 0x19, 0x04, 11,
-			2, 2, 0 },
+			4900, 2, 11, 2, 2, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			8100, 0x18, 0x04, 22,
-			3, 3, 0 },
+			8100, 3, 22, 3, 3, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0x0b, 0x00, 12,
-			4, 4, 0 },
+			5400, 4, 12, 4, 4, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 0x0f, 0x00, 18,
-			4, 5, 0 },
+			7800, 5, 18, 4, 5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 0x0a, 0x00, 24,
-			6, 6, 0 },
+			10000, 6, 24, 6, 6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 0x0e, 0x00, 36,
-			6, 7, 0 },
+			13900, 7, 36, 6, 7, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 0x09, 0x00, 48,
-			8,  8, 0 },
+			17300, 8, 48, 8, 8, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 0x0d, 0x00, 72,
-			8,  9, 0 },
+			23000, 9, 72, 8, 9, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 0x08, 0x00, 96,
-			8,  10, 0 },
+			27400, 10, 96, 8, 10, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 0x0c, 0x00, 108,
-			8,  11, 0 },
+			29300, 11, 108, 8, 11, 0 },
 	},
 	50,  /* probe interval */
 	0,   /* Phy rates allowed initially */
 };
 
+static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
+	[ATH9K_MODE_11A] = &ar5416_11a_ratetable,
+	[ATH9K_MODE_11G] = &ar5416_11g_ratetable,
+	[ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
+	[ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
+	[ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
+	[ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
+	[ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
+	[ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
+};
+
+static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
+				struct ieee80211_tx_rate *rate);
+
 static inline int8_t median(int8_t a, int8_t b, int8_t c)
 {
 	if (a >= b) {
@@ -425,7 +335,7 @@ static void ath_rc_init_valid_txmask(str
 static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
 					   u8 index, int valid_tx_rate)
 {
-	ASSERT(index <= ath_rc_priv->rate_table_size);
+	BUG_ON(index > ath_rc_priv->rate_table_size);
 	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
 }
 
@@ -534,7 +444,7 @@ static u8 ath_rc_setvalid_rates(struct a
 			 * capflag matches one of the validity
 			 * (VALID/VALID_20/VALID_40) flags */
 
-			if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
+			if ((rate == dot11rate) &&
 			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
 			     WLAN_RC_CAP_MODE(capflag)) &&
 			    !WLAN_RC_PHY_HT(phy)) {
@@ -576,8 +486,7 @@ static u8 ath_rc_setvalid_htrates(struct
 			u8 rate = rateset->rs_rates[i];
 			u8 dot11rate = rate_table->info[j].dot11rate;
 
-			if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
-			    !WLAN_RC_PHY_HT(phy) ||
+			if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
 			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
 				continue;
 
@@ -696,18 +605,20 @@ static void ath_rc_rate_set_series(const
 				   u8 tries, u8 rix, int rtsctsenable)
 {
 	rate->count = tries;
-	rate->idx = rix;
+	rate->idx = rate_table->info[rix].ratecode;
 
 	if (txrc->short_preamble)
 		rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
 	if (txrc->rts || rtsctsenable)
 		rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
-	if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
-		rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
-	if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
-		rate->flags |= IEEE80211_TX_RC_SHORT_GI;
-	if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
+
+	if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
 		rate->flags |= IEEE80211_TX_RC_MCS;
+		if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
+			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+		if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
+			rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+	}
 }
 
 static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
@@ -720,7 +631,7 @@ static void ath_rc_rate_set_rtscts(struc
 	/* get the cix for the lowest valid rix */
 	for (i = 3; i >= 0; i--) {
 		if (rates[i].count && (rates[i].idx >= 0)) {
-			rix = rates[i].idx;
+			rix = ath_rc_get_rateindex(rate_table, &rates[i]);
 			break;
 		}
 	}
@@ -859,12 +770,12 @@ static void ath_get_rate(void *priv, str
 static bool ath_rc_update_per(struct ath_softc *sc,
 			      const struct ath_rate_table *rate_table,
 			      struct ath_rate_priv *ath_rc_priv,
-			      struct ath_tx_info_priv *tx_info_priv,
+				  struct ieee80211_tx_info *tx_info,
 			      int tx_rate, int xretries, int retries,
 			      u32 now_msec)
 {
 	bool state_change = false;
-	int count;
+	int count, n_bad_frames;
 	u8 last_per;
 	static u32 nretry_to_per_lookup[10] = {
 		100 * 0 / 1,
@@ -880,6 +791,7 @@ static bool ath_rc_update_per(struct ath
 	};
 
 	last_per = ath_rc_priv->per[tx_rate];
+	n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len;
 
 	if (xretries) {
 		if (xretries == 1) {
@@ -907,7 +819,7 @@ static bool ath_rc_update_per(struct ath
 		if (retries >= count)
 			retries = count - 1;
 
-		if (tx_info_priv->n_bad_frames) {
+		if (n_bad_frames) {
 			/* new_PER = 7/8*old_PER + 1/8*(currentPER)
 			 * Assuming that n_frames is not 0.  The current PER
 			 * from the retries is 100 * retries / (retries+1),
@@ -920,14 +832,14 @@ static bool ath_rc_update_per(struct ath
 			 * the above PER.  The expression below is a
 			 * simplified version of the sum of these two terms.
 			 */
-			if (tx_info_priv->n_frames > 0) {
-				int n_frames, n_bad_frames;
+			if (tx_info->status.ampdu_len > 0) {
+				int n_frames, n_bad_tries;
 				u8 cur_per, new_per;
 
-				n_bad_frames = retries * tx_info_priv->n_frames +
-					tx_info_priv->n_bad_frames;
-				n_frames = tx_info_priv->n_frames * (retries + 1);
-				cur_per = (100 * n_bad_frames / n_frames) >> 3;
+				n_bad_tries = retries * tx_info->status.ampdu_len +
+					n_bad_frames;
+				n_frames = tx_info->status.ampdu_len * (retries + 1);
+				cur_per = (100 * n_bad_tries / n_frames) >> 3;
 				new_per = (u8)(last_per - (last_per >> 3) + cur_per);
 				ath_rc_priv->per[tx_rate] = new_per;
 			}
@@ -943,8 +855,7 @@ static bool ath_rc_update_per(struct ath
 		 * this was a probe.  Otherwise, ignore the probe.
 		 */
 		if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
-			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
-				tx_info_priv->n_frames) {
+			if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) {
 				/*
 				 * Since we probed with just a single attempt,
 				 * any retries means the probe failed.  Also,
@@ -969,7 +880,7 @@ static bool ath_rc_update_per(struct ath
 				 * Since this probe succeeded, we allow the next
 				 * probe twice as soon.  This allows the maxRate
 				 * to move up faster if the probes are
-				 * succesful.
+				 * successful.
 				 */
 				ath_rc_priv->probe_time =
 					now_msec - rate_table->probe_interval / 2;
@@ -1003,7 +914,7 @@ static bool ath_rc_update_per(struct ath
 
 static void ath_rc_update_ht(struct ath_softc *sc,
 			     struct ath_rate_priv *ath_rc_priv,
-			     struct ath_tx_info_priv *tx_info_priv,
+			     struct ieee80211_tx_info *tx_info,
 			     int tx_rate, int xretries, int retries)
 {
 	u32 now_msec = jiffies_to_msecs(jiffies);
@@ -1020,7 +931,7 @@ static void ath_rc_update_ht(struct ath_
 
 	/* Update PER first */
 	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
-					 tx_info_priv, tx_rate, xretries,
+					 tx_info, tx_rate, xretries,
 					 retries, now_msec);
 
 	/*
@@ -1080,15 +991,19 @@ static int ath_rc_get_rateindex(const st
 {
 	int rix;
 
+	if (!(rate->flags & IEEE80211_TX_RC_MCS))
+		return rate->idx;
+
+	rix = rate->idx + rate_table->mcs_start;
 	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
-		rix = rate_table->info[rate->idx].ht_index;
+		rix = rate_table->info[rix].ht_index;
 	else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
-		rix = rate_table->info[rate->idx].sgi_index;
+		rix = rate_table->info[rix].sgi_index;
 	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-		rix = rate_table->info[rate->idx].cw40index;
+		rix = rate_table->info[rix].cw40index;
 	else
-		rix = rate_table->info[rate->idx].base_index;
+		rix = rate_table->info[rix].base_index;
 
 	return rix;
 }
@@ -1098,7 +1013,6 @@ static void ath_rc_tx_status(struct ath_
 			     struct ieee80211_tx_info *tx_info,
 			     int final_ts_idx, int xretries, int long_retry)
 {
-	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
 	const struct ath_rate_table *rate_table;
 	struct ieee80211_tx_rate *rates = tx_info->status.rates;
 	u8 flags;
@@ -1124,9 +1038,8 @@ static void ath_rc_tx_status(struct ath_
 					return;
 
 				rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-				ath_rc_update_ht(sc, ath_rc_priv,
-						tx_info_priv, rix,
-						xretries ? 1 : 2,
+				ath_rc_update_ht(sc, ath_rc_priv, tx_info,
+						rix, xretries ? 1 : 2,
 						rates[i].count);
 			}
 		}
@@ -1149,8 +1062,7 @@ static void ath_rc_tx_status(struct ath_
 		return;
 
 	rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-	ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
-			 xretries, long_retry);
+	ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry);
 }
 
 static const
@@ -1160,6 +1072,7 @@ struct ath_rate_table *ath_choose_rate_t
 					     bool is_cw_40)
 {
 	int mode = 0;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	switch(band) {
 	case IEEE80211_BAND_2GHZ:
@@ -1177,14 +1090,17 @@ struct ath_rate_table *ath_choose_rate_t
 			mode = ATH9K_MODE_11NA_HT40PLUS;
 		break;
 	default:
-		DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
+		ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
 		return NULL;
 	}
 
 	BUG_ON(mode >= ATH9K_MODE_MAX);
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
-	return sc->hw_rate_table[mode];
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Choosing rate table for mode: %d\n", mode);
+
+	sc->cur_rate_mode = mode;
+	return hw_rate_table[mode];
 }
 
 static void ath_rc_init(struct ath_softc *sc,
@@ -1194,14 +1110,10 @@ static void ath_rc_init(struct ath_softc
 			const struct ath_rate_table *rate_table)
 {
 	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
 	u8 i, j, k, hi = 0, hthi = 0;
 
-	if (!rate_table) {
-		DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
-		return;
-	}
-
 	/* Initial rate table size. Will change depending
 	 * on the working rate set */
 	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1239,7 +1151,7 @@ static void ath_rc_init(struct ath_softc
 
 	ath_rc_priv->rate_table_size = hi + 1;
 	ath_rc_priv->rate_max_phy = 0;
-	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
+	BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
 
 	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
 		for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
@@ -1253,16 +1165,17 @@ static void ath_rc_init(struct ath_softc
 
 		ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
 	}
-	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
-	ASSERT(k <= RATE_TABLE_SIZE);
+	BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
+	BUG_ON(k > RATE_TABLE_SIZE);
 
 	ath_rc_priv->max_valid_rate = k;
 	ath_rc_sort_validrates(rate_table, ath_rc_priv);
 	ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
 	sc->cur_rate_table = rate_table;
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
-		ath_rc_priv->ht_cap);
+	ath_print(common, ATH_DBG_CONFIG,
+		  "RC Initialized with capabilities: 0x%x\n",
+		  ath_rc_priv->ht_cap);
 }
 
 static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1296,44 +1209,52 @@ static void ath_tx_status(void *priv, st
 {
 	struct ath_softc *sc = priv;
 	struct ath_rate_priv *ath_rc_priv = priv_sta;
-	struct ath_tx_info_priv *tx_info_priv = NULL;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hdr *hdr;
-	int final_ts_idx, tx_status = 0, is_underrun = 0;
+	int final_ts_idx = 0, tx_status = 0, is_underrun = 0;
+	int long_retry = 0;
 	__le16 fc;
+	int i;
 
 	hdr = (struct ieee80211_hdr *)skb->data;
 	fc = hdr->frame_control;
-	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-	final_ts_idx = tx_info_priv->tx.ts_rateindex;
+	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+		struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
+		if (!rate->count)
+			break;
+
+		final_ts_idx = i;
+		long_retry = rate->count - 1;
+	}
 
 	if (!priv_sta || !ieee80211_is_data(fc) ||
-	    !tx_info_priv->update_rc)
-		goto exit;
+	    !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC))
+		return;
 
-	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
-		goto exit;
+	if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
+		return;
 
 	/*
-	 * If underrun error is seen assume it as an excessive retry only
-	 * if prefetch trigger level have reached the max (0x3f for 5416)
-	 * Adjust the long retry as if the frame was tried hw->max_rate_tries
-	 * times. This affects how ratectrl updates PER for the failed rate.
+	 * If an underrun error is seen assume it as an excessive retry only
+	 * if max frame trigger level has been reached (2 KB for singel stream,
+	 * and 4 KB for dual stream). Adjust the long retry as if the frame was
+	 * tried hw->max_rate_tries times to affect how ratectrl updates PER for
+	 * the failed rate. In case of congestion on the bus penalizing these
+	 * type of underruns should help hardware actually transmit new frames
+	 * successfully by eventually preferring slower rates. This itself
+	 * should also alleviate congestion on the bus.
 	 */
-	if (tx_info_priv->tx.ts_flags &
-	    (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
-	    ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
+	if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
+	    (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
 		tx_status = 1;
 		is_underrun = 1;
 	}
 
-	if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
-	    (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
+	if (tx_info->pad[0] & ATH_TX_INFO_XRETRY)
 		tx_status = 1;
 
 	ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
-			 (is_underrun) ? sc->hw->max_rate_tries :
-			 tx_info_priv->tx.ts_longretry);
+			 (is_underrun) ? sc->hw->max_rate_tries : long_retry);
 
 	/* Check if aggregation has to be enabled for this tid */
 	if (conf_is_ht(&sc->hw->conf) &&
@@ -1347,13 +1268,12 @@ static void ath_tx_status(void *priv, st
 			an = (struct ath_node *)sta->drv_priv;
 
 			if(ath_tx_aggr_check(sc, an, tid))
-				ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
+				ieee80211_start_tx_ba_session(sta, tid);
 		}
 	}
 
-	ath_debug_stat_rc(sc, skb);
-exit:
-	kfree(tx_info_priv);
+	ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
+		&tx_info->status.rates[final_ts_idx]));
 }
 
 static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1361,7 +1281,7 @@ static void ath_rate_init(void *priv, st
 {
 	struct ath_softc *sc = priv;
 	struct ath_rate_priv *ath_rc_priv = priv_sta;
-	const struct ath_rate_table *rate_table = NULL;
+	const struct ath_rate_table *rate_table;
 	bool is_cw40, is_sgi40;
 	int i, j = 0;
 
@@ -1393,11 +1313,9 @@ static void ath_rate_init(void *priv, st
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
 		rate_table = ath_choose_rate_table(sc, sband->band,
-						   sta->ht_cap.ht_supported,
-						   is_cw40);
-	} else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-		/* cur_rate_table would be set on init through config() */
-		rate_table = sc->cur_rate_table;
+		                      sta->ht_cap.ht_supported, is_cw40);
+	} else {
+		rate_table = hw_rate_table[sc->cur_rate_mode];
 	}
 
 	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
@@ -1438,9 +1356,10 @@ static void ath_rate_update(void *priv,
 						   oper_cw40, oper_sgi40);
 			ath_rc_init(sc, priv_sta, sband, sta, rate_table);
 
-			DPRINTF(sc, ATH_DBG_CONFIG,
-				"Operating HT Bandwidth changed to: %d\n",
-				sc->hw->conf.channel_type);
+			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+				  "Operating HT Bandwidth changed to: %d\n",
+				  sc->hw->conf.channel_type);
+			sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
 		}
 	}
 }
@@ -1463,8 +1382,8 @@ static void *ath_rate_alloc_sta(void *pr
 
 	rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
 	if (!rate_priv) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to allocate private rc structure\n");
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Unable to allocate private rc structure\n");
 		return NULL;
 	}
 
@@ -1493,26 +1412,6 @@ static struct rate_control_ops ath_rate_
 	.free_sta = ath_rate_free_sta,
 };
 
-void ath_rate_attach(struct ath_softc *sc)
-{
-	sc->hw_rate_table[ATH9K_MODE_11A] =
-		&ar5416_11a_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11G] =
-		&ar5416_11g_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
-		&ar5416_11na_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
-		&ar5416_11ng_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
-		&ar5416_11na_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
-		&ar5416_11na_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
-		&ar5416_11ng_ratetable;
-	sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
-		&ar5416_11ng_ratetable;
-}
-
 int ath_rate_control_register(void)
 {
 	return ieee80211_rate_control_register(&ath_rate_ops);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/rc.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/rc.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,8 @@
 #ifndef RC_H
 #define RC_H
 
+#include "hw.h"
+
 struct ath_softc;
 
 #define ATH_RATE_MAX     30
@@ -102,6 +104,7 @@ enum {
  */
 struct ath_rate_table {
 	int rate_cnt;
+	int mcs_start;
 	struct {
 		int valid;
 		int valid_single_stream;
@@ -109,14 +112,12 @@ struct ath_rate_table {
 		u32 ratekbps;
 		u32 user_ratekbps;
 		u8 ratecode;
-		u8 short_preamble;
 		u8 dot11rate;
 		u8 ctrl_rate;
 		u8 base_index;
 		u8 cw40index;
 		u8 sgi_index;
 		u8 ht_index;
-		u32 max_4ms_framelen;
 	} info[RATE_TABLE_SIZE];
 	u32 probe_interval;
 	u8 initial_ratemax;
@@ -165,26 +166,18 @@ struct ath_rate_priv {
 	struct ath_rate_softc *asc;
 };
 
+#define ATH_TX_INFO_FRAME_TYPE_INTERNAL	(1 << 0)
+#define ATH_TX_INFO_FRAME_TYPE_PAUSE	(1 << 1)
+#define ATH_TX_INFO_UPDATE_RC		(1 << 2)
+#define ATH_TX_INFO_XRETRY		(1 << 3)
+#define ATH_TX_INFO_UNDERRUN		(1 << 4)
+
 enum ath9k_internal_frame_type {
 	ATH9K_NOT_INTERNAL,
 	ATH9K_INT_PAUSE,
 	ATH9K_INT_UNPAUSE
 };
 
-struct ath_tx_info_priv {
-	struct ath_wiphy *aphy;
-	struct ath_tx_status tx;
-	int n_frames;
-	int n_bad_frames;
-	bool update_rc;
-	enum ath9k_internal_frame_type frame_type;
-};
-
-#define ATH_TX_INFO_PRIV(tx_info) \
-	((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
-
-void ath_rate_attach(struct ath_softc *sc);
-u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
 int ath_rate_control_register(void);
 void ath_rate_control_unregister(void);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/recv.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/recv.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/recv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/recv.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,7 @@ static struct ieee80211_hw * ath_get_vir
 static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_desc *ds;
 	struct sk_buff *skb;
 
@@ -59,14 +60,16 @@ static void ath_rx_buf_link(struct ath_s
 
 	/* virtual addr of the beginning of the buffer. */
 	skb = bf->bf_mpdu;
-	ASSERT(skb != NULL);
+	BUG_ON(skb == NULL);
 	ds->ds_vdata = skb->data;
 
-	/* setup rx descriptors. The rx.bufsize here tells the harware
+	/*
+	 * setup rx descriptors. The rx_bufsize here tells the hardware
 	 * how much data it can DMA to us and that we are prepared
-	 * to process */
+	 * to process
+	 */
 	ath9k_hw_setuprxdesc(ah, ds,
-			     sc->rx.bufsize,
+			     common->rx_bufsize,
 			     0);
 
 	if (sc->rx.rxlink == NULL)
@@ -86,192 +89,11 @@ static void ath_setdefantenna(struct ath
 	sc->rx.rxotherant = 0;
 }
 
-/*
- *  Extend 15-bit time stamp from rx descriptor to
- *  a full 64-bit TSF using the current h/w TSF.
-*/
-static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
-{
-	u64 tsf;
-
-	tsf = ath9k_hw_gettsf64(sc->sc_ah);
-	if ((tsf & 0x7fff) < rstamp)
-		tsf -= 0x8000;
-	return (tsf & ~0x7fff) | rstamp;
-}
-
-/*
- * For Decrypt or Demic errors, we only mark packet status here and always push
- * up the frame up to let mac80211 handle the actual error case, be it no
- * decryption key or real decryption error. This let us keep statistics there.
- */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
-			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
-			  struct ath_softc *sc)
-{
-	struct ieee80211_hdr *hdr;
-	u8 ratecode;
-	__le16 fc;
-	struct ieee80211_hw *hw;
-	struct ieee80211_sta *sta;
-	struct ath_node *an;
-	int last_rssi = ATH_RSSI_DUMMY_MARKER;
-
-
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
-	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-	hw = ath_get_virt_hw(sc, hdr);
-
-	if (ds->ds_rxstat.rs_more) {
-		/*
-		 * Frame spans multiple descriptors; this cannot happen yet
-		 * as we don't support jumbograms. If not in monitor mode,
-		 * discard the frame. Enable this if you want to see
-		 * error frames in Monitor mode.
-		 */
-		if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
-			goto rx_next;
-	} else if (ds->ds_rxstat.rs_status != 0) {
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
-			rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
-			goto rx_next;
-
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
-			*decrypt_error = true;
-		} else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
-			if (ieee80211_is_ctl(fc))
-				/*
-				 * Sometimes, we get invalid
-				 * MIC failures on valid control frames.
-				 * Remove these mic errors.
-				 */
-				ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
-			else
-				rx_status->flag |= RX_FLAG_MMIC_ERROR;
-		}
-		/*
-		 * Reject error frames with the exception of
-		 * decryption and MIC failures. For monitor mode,
-		 * we also ignore the CRC error.
-		 */
-		if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-			if (ds->ds_rxstat.rs_status &
-			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
-			      ATH9K_RXERR_CRC))
-				goto rx_next;
-		} else {
-			if (ds->ds_rxstat.rs_status &
-			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
-				goto rx_next;
-			}
-		}
-	}
-
-	ratecode = ds->ds_rxstat.rs_rate;
-
-	if (ratecode & 0x80) {
-		/* HT rate */
-		rx_status->flag |= RX_FLAG_HT;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
-			rx_status->flag |= RX_FLAG_40MHZ;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
-			rx_status->flag |= RX_FLAG_SHORT_GI;
-		rx_status->rate_idx = ratecode & 0x7f;
-	} else {
-		int i = 0, cur_band, n_rates;
-
-		cur_band = hw->conf.channel->band;
-		n_rates = sc->sbands[cur_band].n_bitrates;
-
-		for (i = 0; i < n_rates; i++) {
-			if (sc->sbands[cur_band].bitrates[i].hw_value ==
-			    ratecode) {
-				rx_status->rate_idx = i;
-				break;
-			}
-
-			if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
-			    ratecode) {
-				rx_status->rate_idx = i;
-				rx_status->flag |= RX_FLAG_SHORTPRE;
-				break;
-			}
-		}
-	}
-
-	rcu_read_lock();
-	sta = ieee80211_find_sta(sc->hw, hdr->addr2);
-	if (sta) {
-		an = (struct ath_node *) sta->drv_priv;
-		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-		   !ds->ds_rxstat.rs_moreaggr)
-			ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
-		last_rssi = an->last_rssi;
-	}
-	rcu_read_unlock();
-
-	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-		ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
-					ATH_RSSI_EP_MULTIPLIER);
-	if (ds->ds_rxstat.rs_rssi < 0)
-		ds->ds_rxstat.rs_rssi = 0;
-	else if (ds->ds_rxstat.rs_rssi > 127)
-		ds->ds_rxstat.rs_rssi = 127;
-
-	/* Update Beacon RSSI, this is used by ANI. */
-	if (ieee80211_is_beacon(fc))
-		sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
-
-	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
-	rx_status->band = hw->conf.channel->band;
-	rx_status->freq = hw->conf.channel->center_freq;
-	rx_status->noise = sc->ani.noise_floor;
-	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
-	rx_status->antenna = ds->ds_rxstat.rs_antenna;
-
-	/*
-	 * Theory for reporting quality:
-	 *
-	 * At a hardware RSSI of 45 you will be able to use MCS 7  reliably.
-	 * At a hardware RSSI of 45 you will be able to use MCS 15 reliably.
-	 * At a hardware RSSI of 35 you should be able use 54 Mbps reliably.
-	 *
-	 * MCS 7  is the highets MCS index usable by a 1-stream device.
-	 * MCS 15 is the highest MCS index usable by a 2-stream device.
-	 *
-	 * All ath9k devices are either 1-stream or 2-stream.
-	 *
-	 * How many bars you see is derived from the qual reporting.
-	 *
-	 * A more elaborate scheme can be used here but it requires tables
-	 * of SNR/throughput for each possible mode used. For the MCS table
-	 * you can refer to the wireless wiki:
-	 *
-	 * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
-	 *
-	 */
-	if (conf_is_ht(&hw->conf))
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
-	else
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
-
-	/* rssi can be more than 45 though, anything above that
-	 * should be considered at 100% */
-	if (rx_status->qual > 100)
-		rx_status->qual = 100;
-
-	rx_status->flag |= RX_FLAG_TSFT;
-
-	return 1;
-rx_next:
-	return 0;
-}
-
 static void ath_opmode_init(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
 	u32 rfilt, mfilt[2];
 
 	/* configure rx filter */
@@ -280,13 +102,13 @@ static void ath_opmode_init(struct ath_s
 
 	/* configure bssid mask */
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-		ath9k_hw_setbssidmask(sc);
+		ath_hw_setbssidmask(common);
 
 	/* configure operational mode */
 	ath9k_hw_setopmode(ah);
 
 	/* Handle any link-level address change. */
-	ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
+	ath9k_hw_setmac(ah, common->macaddr);
 
 	/* calculate and install multicast filter */
 	mfilt[0] = mfilt[1] = ~0;
@@ -295,6 +117,7 @@ static void ath_opmode_init(struct ath_s
 
 int ath_rx_init(struct ath_softc *sc, int nbufs)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct sk_buff *skb;
 	struct ath_buf *bf;
 	int error = 0;
@@ -303,24 +126,24 @@ int ath_rx_init(struct ath_softc *sc, in
 	sc->sc_flags &= ~SC_OP_RXFLUSH;
 	spin_lock_init(&sc->rx.rxbuflock);
 
-	sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-				 min(sc->common.cachelsz, (u16)64));
+	common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+				     min(common->cachelsz, (u16)64));
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-		sc->common.cachelsz, sc->rx.bufsize);
+	ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+		  common->cachelsz, common->rx_bufsize);
 
 	/* Initialize rx descriptors */
 
 	error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
 				  "rx", nbufs, 1);
 	if (error != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"failed to allocate rx descriptors: %d\n", error);
+		ath_print(common, ATH_DBG_FATAL,
+			  "failed to allocate rx descriptors: %d\n", error);
 		goto err;
 	}
 
 	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-		skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_KERNEL);
+		skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
 		if (skb == NULL) {
 			error = -ENOMEM;
 			goto err;
@@ -328,14 +151,14 @@ int ath_rx_init(struct ath_softc *sc, in
 
 		bf->bf_mpdu = skb;
 		bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
-						 sc->rx.bufsize,
+						 common->rx_bufsize,
 						 DMA_FROM_DEVICE);
 		if (unlikely(dma_mapping_error(sc->dev,
 					       bf->bf_buf_addr))) {
 			dev_kfree_skb_any(skb);
 			bf->bf_mpdu = NULL;
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"dma_mapping_error() on RX init\n");
+			ath_print(common, ATH_DBG_FATAL,
+				  "dma_mapping_error() on RX init\n");
 			error = -ENOMEM;
 			goto err;
 		}
@@ -352,6 +175,8 @@ err:
 
 void ath_rx_cleanup(struct ath_softc *sc)
 {
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct sk_buff *skb;
 	struct ath_buf *bf;
 
@@ -359,7 +184,7 @@ void ath_rx_cleanup(struct ath_softc *sc
 		skb = bf->bf_mpdu;
 		if (skb) {
 			dma_unmap_single(sc->dev, bf->bf_buf_addr,
-					 sc->rx.bufsize, DMA_FROM_DEVICE);
+					 common->rx_bufsize, DMA_FROM_DEVICE);
 			dev_kfree_skb(skb);
 		}
 	}
@@ -420,7 +245,10 @@ u32 ath_calcrxfilter(struct ath_softc *s
 	else
 		rfilt |= ATH9K_RX_FILTER_BEACON;
 
-	if (sc->rx.rxfilter & FIF_PSPOLL)
+	if ((AR_SREV_9280_10_OR_LATER(sc->sc_ah) ||
+	    AR_SREV_9285_10_OR_LATER(sc->sc_ah)) &&
+	    (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+	    (sc->rx.rxfilter & FIF_PSPOLL))
 		rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
 	if (conf_is_ht(&sc->hw->conf))
@@ -527,20 +355,22 @@ static bool ath_beacon_dtim_pending_cab(
 static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ieee80211_mgmt *mgmt;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	if (skb->len < 24 + 8 + 2 + 2)
 		return;
 
 	mgmt = (struct ieee80211_mgmt *)skb->data;
-	if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
+	if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
 		return; /* not from our current AP */
 
 	sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
 
 	if (sc->sc_flags & SC_OP_BEACON_SYNC) {
 		sc->sc_flags &= ~SC_OP_BEACON_SYNC;
-		DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
-			"timestamp from the AP\n");
+		ath_print(common, ATH_DBG_PS,
+			  "Reconfigure Beacon timers based on "
+			  "timestamp from the AP\n");
 		ath_beacon_config(sc, NULL);
 	}
 
@@ -552,8 +382,8 @@ static void ath_rx_ps_beacon(struct ath_
 		 * a backup trigger for returning into NETWORK SLEEP state,
 		 * so we are waiting for it as well.
 		 */
-		DPRINTF(sc, ATH_DBG_PS, "Received DTIM beacon indicating "
-			"buffered broadcast/multicast frame(s)\n");
+		ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
+			  "buffered broadcast/multicast frame(s)\n");
 		sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON;
 		return;
 	}
@@ -565,13 +395,15 @@ static void ath_rx_ps_beacon(struct ath_
 		 * been delivered.
 		 */
 		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
-		DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
+		ath_print(common, ATH_DBG_PS,
+			  "PS wait for CAB frames timed out\n");
 	}
 }
 
 static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 
 	hdr = (struct ieee80211_hdr *)skb->data;
 
@@ -589,14 +421,15 @@ static void ath_rx_ps(struct ath_softc *
 		 * point.
 		 */
 		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
-		DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
-			"sleep\n");
+		ath_print(common, ATH_DBG_PS,
+			  "All PS CAB frames received, back to sleep\n");
 	} else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
 		   !is_multicast_ether_addr(hdr->addr1) &&
 		   !ieee80211_has_morefrags(hdr->frame_control)) {
 		sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA;
-		DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
-			"received PS-Poll data (0x%x)\n",
+		ath_print(common, ATH_DBG_PS,
+			  "Going back to sleep after having received "
+			  "PS-Poll data (0x%x)\n",
 			sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
 					SC_OP_WAIT_FOR_CAB |
 					SC_OP_WAIT_FOR_PSPOLL_DATA |
@@ -604,8 +437,9 @@ static void ath_rx_ps(struct ath_softc *
 	}
 }
 
-static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
-				    struct ieee80211_rx_status *rx_status)
+static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
+				    struct ath_softc *sc, struct sk_buff *skb,
+				    struct ieee80211_rx_status *rxs)
 {
 	struct ieee80211_hdr *hdr;
 
@@ -625,19 +459,14 @@ static void ath_rx_send_to_mac80211(stru
 			if (aphy == NULL)
 				continue;
 			nskb = skb_copy(skb, GFP_ATOMIC);
-			if (nskb) {
-				memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
-					sizeof(*rx_status));
-				ieee80211_rx(aphy->hw, nskb);
-			}
+			if (!nskb)
+				continue;
+			ieee80211_rx(aphy->hw, nskb);
 		}
-		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
 		ieee80211_rx(sc->hw, skb);
-	} else {
+	} else
 		/* Deliver unicast frames based on receiver address */
-		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
-		ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
-	}
+		ieee80211_rx(hw, skb);
 }
 
 int ath_rx_tasklet(struct ath_softc *sc, int flush)
@@ -648,14 +477,20 @@ int ath_rx_tasklet(struct ath_softc *sc,
 
 	struct ath_buf *bf;
 	struct ath_desc *ds;
+	struct ath_rx_status *rx_stats;
 	struct sk_buff *skb = NULL, *requeue_skb;
-	struct ieee80211_rx_status rx_status;
+	struct ieee80211_rx_status *rxs;
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	/*
+	 * The hw can techncically differ from common->hw when using ath9k
+	 * virtual wiphy so to account for that we iterate over the active
+	 * wiphys and find the appropriate wiphy and therefore hw.
+	 */
+	struct ieee80211_hw *hw = NULL;
 	struct ieee80211_hdr *hdr;
-	int hdrlen, padsize, retval;
+	int retval;
 	bool decrypt_error = false;
-	u8 keyix;
-	__le16 fc;
 
 	spin_lock_bh(&sc->rx.rxbuflock);
 
@@ -727,9 +562,15 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		 * 2. requeueing the same buffer to h/w
 		 */
 		dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
-				sc->rx.bufsize,
+				common->rx_bufsize,
 				DMA_FROM_DEVICE);
 
+		hdr = (struct ieee80211_hdr *) skb->data;
+		rxs =  IEEE80211_SKB_RXCB(skb);
+
+		hw = ath_get_virt_hw(sc, hdr);
+		rx_stats = &ds->ds_rxstat;
+
 		/*
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
@@ -737,19 +578,14 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		if (flush)
 			goto requeue;
 
-		if (!ds->ds_rxstat.rs_datalen)
-			goto requeue;
-
-		/* The status portion of the descriptor could get corrupted. */
-		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
-			goto requeue;
-
-		if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+		retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, rx_stats,
+						     rxs, &decrypt_error);
+		if (retval)
 			goto requeue;
 
 		/* Ensure we always have an skb to requeue once we are done
 		 * processing the current buffer's skb */
-		requeue_skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_ATOMIC);
+		requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
 
 		/* If there is no memory we ignore the current RX'd frame,
 		 * tell hardware it can give us a new frame using the old
@@ -760,60 +596,26 @@ int ath_rx_tasklet(struct ath_softc *sc,
 
 		/* Unmap the frame */
 		dma_unmap_single(sc->dev, bf->bf_buf_addr,
-				 sc->rx.bufsize,
+				 common->rx_bufsize,
 				 DMA_FROM_DEVICE);
 
-		skb_put(skb, ds->ds_rxstat.rs_datalen);
-
-		/* see if any padding is done by the hw and remove it */
-		hdr = (struct ieee80211_hdr *)skb->data;
-		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-		fc = hdr->frame_control;
-
-		/* The MAC header is padded to have 32-bit boundary if the
-		 * packet payload is non-zero. The general calculation for
-		 * padsize would take into account odd header lengths:
-		 * padsize = (4 - hdrlen % 4) % 4; However, since only
-		 * even-length headers are used, padding can only be 0 or 2
-		 * bytes and we can optimize this a bit. In addition, we must
-		 * not try to remove padding from short control frames that do
-		 * not have payload. */
-		padsize = hdrlen & 3;
-		if (padsize && hdrlen >= 24) {
-			memmove(skb->data + padsize, skb->data, hdrlen);
-			skb_pull(skb, padsize);
-		}
-
-		keyix = ds->ds_rxstat.rs_keyix;
-
-		if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
-			rx_status.flag |= RX_FLAG_DECRYPTED;
-		} else if (ieee80211_has_protected(fc)
-			   && !decrypt_error && skb->len >= hdrlen + 4) {
-			keyix = skb->data[hdrlen + 3] >> 6;
+		skb_put(skb, rx_stats->rs_datalen);
 
-			if (test_bit(keyix, sc->keymap))
-				rx_status.flag |= RX_FLAG_DECRYPTED;
-		}
-		if (ah->sw_mgmt_crypto &&
-		    (rx_status.flag & RX_FLAG_DECRYPTED) &&
-		    ieee80211_is_mgmt(fc)) {
-			/* Use software decrypt for management frames. */
-			rx_status.flag &= ~RX_FLAG_DECRYPTED;
-		}
+		ath9k_cmn_rx_skb_postprocess(common, skb, rx_stats,
+					     rxs, decrypt_error);
 
 		/* We will now give hardware our shiny new allocated skb */
 		bf->bf_mpdu = requeue_skb;
 		bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
-					 sc->rx.bufsize,
-					 DMA_FROM_DEVICE);
+						 common->rx_bufsize,
+						 DMA_FROM_DEVICE);
 		if (unlikely(dma_mapping_error(sc->dev,
 			  bf->bf_buf_addr))) {
 			dev_kfree_skb_any(requeue_skb);
 			bf->bf_mpdu = NULL;
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"dma_mapping_error() on RX\n");
-			ath_rx_send_to_mac80211(sc, skb, &rx_status);
+			ath_print(common, ATH_DBG_FATAL,
+				  "dma_mapping_error() on RX\n");
+			ath_rx_send_to_mac80211(hw, sc, skb, rxs);
 			break;
 		}
 		bf->bf_dmacontext = bf->bf_buf_addr;
@@ -824,7 +626,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		 */
 		if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
 			if (++sc->rx.rxotherant >= 3)
-				ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+				ath_setdefantenna(sc, rx_stats->rs_antenna);
 		} else {
 			sc->rx.rxotherant = 0;
 		}
@@ -834,7 +636,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
 					     SC_OP_WAIT_FOR_PSPOLL_DATA)))
 			ath_rx_ps(sc, skb);
 
-		ath_rx_send_to_mac80211(sc, skb, &rx_status);
+		ath_rx_send_to_mac80211(hw, sc, skb, rxs);
 
 requeue:
 		list_move_tail(&bf->list, &sc->rx.rxbuf);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,8 @@
 #ifndef REG_H
 #define REG_H
 
+#include "../reg.h"
+
 #define AR_CR                0x0008
 #define AR_CR_RXE            0x00000004
 #define AR_CR_RXD            0x00000020
@@ -969,10 +971,10 @@ enum {
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF        0x00000080
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00000400
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    10
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00001000
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    1
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
@@ -1330,13 +1332,22 @@ enum {
 #define AR_MCAST_FIL0       0x8040
 #define AR_MCAST_FIL1       0x8044
 
+/*
+ * AR_DIAG_SW - Register which can be used for diagnostics and testing purposes.
+ *
+ * The force RX abort (AR_DIAG_RX_ABORT, bit 25) can be used in conjunction with
+ * RX block (AR_DIAG_RX_DIS, bit 5) to help fast channel change to shut down
+ * receive. The force RX abort bit will kill any frame which is currently being
+ * transferred between the MAC and baseband. The RX block bit (AR_DIAG_RX_DIS)
+ * will prevent any new frames from getting started.
+ */
 #define AR_DIAG_SW                  0x8048
 #define AR_DIAG_CACHE_ACK           0x00000001
 #define AR_DIAG_ACK_DIS             0x00000002
 #define AR_DIAG_CTS_DIS             0x00000004
 #define AR_DIAG_ENCRYPT_DIS         0x00000008
 #define AR_DIAG_DECRYPT_DIS         0x00000010
-#define AR_DIAG_RX_DIS              0x00000020
+#define AR_DIAG_RX_DIS              0x00000020 /* RX block */
 #define AR_DIAG_LOOP_BACK           0x00000040
 #define AR_DIAG_CORR_FCS            0x00000080
 #define AR_DIAG_CHAN_INFO           0x00000100
@@ -1345,12 +1356,12 @@ enum {
 #define AR_DIAG_FRAME_NV0           0x00020000
 #define AR_DIAG_OBS_PT_SEL1         0x000C0000
 #define AR_DIAG_OBS_PT_SEL1_S       18
-#define AR_DIAG_FORCE_RX_CLEAR      0x00100000
+#define AR_DIAG_FORCE_RX_CLEAR      0x00100000 /* force rx_clear high */
 #define AR_DIAG_IGNORE_VIRT_CS      0x00200000
 #define AR_DIAG_FORCE_CH_IDLE_HIGH  0x00400000
 #define AR_DIAG_EIFS_CTRL_ENA       0x00800000
 #define AR_DIAG_DUAL_CHAIN_INFO     0x01000000
-#define AR_DIAG_RX_ABORT            0x02000000
+#define AR_DIAG_RX_ABORT            0x02000000 /* Force RX abort */
 #define AR_DIAG_SATURATE_CYCLE_CNT  0x04000000
 #define AR_DIAG_OBS_PT_SEL2         0x08000000
 #define AR_DIAG_RX_CLEAR_CTL_LOW    0x10000000
@@ -1421,9 +1432,6 @@ enum {
 #define AR_SLEEP2_BEACON_TIMEOUT    0xFFE00000
 #define AR_SLEEP2_BEACON_TIMEOUT_S  21
 
-#define AR_BSSMSKL            0x80e0
-#define AR_BSSMSKU            0x80e4
-
 #define AR_TPC                 0x80e8
 #define AR_TPC_ACK             0x0000003f
 #define AR_TPC_ACK_S           0x00
@@ -1705,4 +1713,7 @@ enum {
 #define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
 #define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
 
+#define AR9271_CORE_CLOCK	117   /* clock to 117Mhz */
+#define AR9271_TARGET_BAUD_RATE	19200 /* 115200 */
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/virtual.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/virtual.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/virtual.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/virtual.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,7 @@ void ath9k_set_bssid_mask(struct ieee802
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath9k_vif_iter_data iter_data;
 	int i, j;
 	u8 mask[ETH_ALEN];
@@ -51,7 +52,7 @@ void ath9k_set_bssid_mask(struct ieee802
 	 */
 	iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
 	if (iter_data.addr) {
-		memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+		memcpy(iter_data.addr, common->macaddr, ETH_ALEN);
 		iter_data.count = 1;
 	} else
 		iter_data.count = 0;
@@ -86,20 +87,21 @@ void ath9k_set_bssid_mask(struct ieee802
 	kfree(iter_data.addr);
 
 	/* Invert the mask and configure hardware */
-	sc->bssidmask[0] = ~mask[0];
-	sc->bssidmask[1] = ~mask[1];
-	sc->bssidmask[2] = ~mask[2];
-	sc->bssidmask[3] = ~mask[3];
-	sc->bssidmask[4] = ~mask[4];
-	sc->bssidmask[5] = ~mask[5];
+	common->bssidmask[0] = ~mask[0];
+	common->bssidmask[1] = ~mask[1];
+	common->bssidmask[2] = ~mask[2];
+	common->bssidmask[3] = ~mask[3];
+	common->bssidmask[4] = ~mask[4];
+	common->bssidmask[5] = ~mask[5];
 
-	ath9k_hw_setbssidmask(sc);
+	ath_hw_setbssidmask(common);
 }
 
 int ath9k_wiphy_add(struct ath_softc *sc)
 {
 	int i, error;
 	struct ath_wiphy *aphy;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_hw *hw;
 	u8 addr[ETH_ALEN];
 
@@ -138,7 +140,7 @@ int ath9k_wiphy_add(struct ath_softc *sc
 	sc->sec_wiphy[i] = aphy;
 	spin_unlock_bh(&sc->wiphy_lock);
 
-	memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+	memcpy(addr, common->macaddr, ETH_ALEN);
 	addr[0] |= 0x02; /* Locally managed address */
 	/*
 	 * XOR virtual wiphy index into the least significant bits to generate
@@ -296,6 +298,7 @@ static void ath9k_wiphy_unpause_channel(
 void ath9k_wiphy_chan_work(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_wiphy *aphy = sc->next_wiphy;
 
 	if (aphy == NULL)
@@ -311,6 +314,10 @@ void ath9k_wiphy_chan_work(struct work_s
 	/* XXX: remove me eventually */
 	ath9k_update_ichannel(sc, aphy->hw,
 			      &sc->sc_ah->channels[sc->chan_idx]);
+
+	/* sync hw configuration for hw code */
+	common->hw = aphy->hw;
+
 	ath_update_chainmask(sc, sc->chan_is_ht);
 	if (ath_set_channel(sc, aphy->hw,
 			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
@@ -331,13 +338,11 @@ void ath9k_wiphy_chan_work(struct work_s
 void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct ath_wiphy *aphy = hw->priv;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
 
-	if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
+	if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) &&
 	    aphy->state == ATH_WIPHY_PAUSING) {
-		if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+		if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) {
 			printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
 			       "frame\n", wiphy_name(hw->wiphy));
 			/*
@@ -356,9 +361,6 @@ void ath9k_tx_status(struct ieee80211_hw
 		}
 	}
 
-	kfree(tx_info_priv);
-	tx_info->rate_driver_data[0] = NULL;
-
 	dev_kfree_skb(skb);
 }
 
@@ -519,8 +521,9 @@ int ath9k_wiphy_select(struct ath_wiphy
 			 * frame being completed)
 			 */
 			spin_unlock_bh(&sc->wiphy_lock);
-			ath_radio_disable(sc);
-			ath_radio_enable(sc);
+			ath_radio_disable(sc, aphy->hw);
+			ath_radio_enable(sc, aphy->hw);
+			/* Only the primary wiphy hw is used for queuing work */
 			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 			return -EBUSY; /* previous select still in progress */
@@ -666,15 +669,78 @@ void ath9k_wiphy_set_scheduler(struct at
 bool ath9k_all_wiphys_idle(struct ath_softc *sc)
 {
 	unsigned int i;
-	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+	if (!sc->pri_wiphy->idle)
 		return false;
-	}
 	for (i = 0; i < sc->num_sec_wiphy; i++) {
 		struct ath_wiphy *aphy = sc->sec_wiphy[i];
 		if (!aphy)
 			continue;
-		if (aphy->state != ATH_WIPHY_INACTIVE)
+		if (!aphy->idle)
 			return false;
 	}
 	return true;
 }
+
+/* caller must hold wiphy_lock */
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
+{
+	struct ath_softc *sc = aphy->sc;
+
+	aphy->idle = idle;
+	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+		  "Marking %s as %s\n",
+		  wiphy_name(aphy->hw->wiphy),
+		  idle ? "idle" : "not-idle");
+}
+/* Only bother starting a queue on an active virtual wiphy */
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Start the primary wiphy */
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
+		ieee80211_wake_queue(hw, skb_queue);
+		goto unlock;
+	}
+
+	/* Now start the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		if (aphy->state != ATH_WIPHY_ACTIVE)
+			continue;
+
+		hw = aphy->hw;
+		ieee80211_wake_queue(hw, skb_queue);
+		break;
+	}
+
+unlock:
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Stop the primary wiphy */
+	ieee80211_stop_queue(hw, skb_queue);
+
+	/* Now stop the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		hw = aphy->hw;
+		ieee80211_stop_queue(hw, skb_queue);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/xmit.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath9k/xmit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath9k/xmit.c	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,29 @@ static int ath_tx_num_badfrms(struct ath
 static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
 			     int nbad, int txok, bool update_rc);
 
+enum {
+	MCS_DEFAULT,
+	MCS_HT40,
+	MCS_HT40_SGI,
+};
+
+static int ath_max_4ms_framelen[3][16] = {
+	[MCS_DEFAULT] = {
+		3216,  6434,  9650,  12868, 19304, 25740,  28956,  32180,
+		6430,  12860, 19300, 25736, 38600, 51472,  57890,  64320,
+	},
+	[MCS_HT40] = {
+		6684,  13368, 20052, 26738, 40104, 53476,  60156,  66840,
+		13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600,
+	},
+	[MCS_HT40_SGI] = {
+		/* TODO: Only MCS 7 and 15 updated, recalculate the rest */
+		6684,  13368, 20052, 26738, 40104, 53476,  60156,  74200,
+		13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400,
+	}
+};
+
+
 /*********************/
 /* Aggregation logic */
 /*********************/
@@ -107,7 +130,7 @@ static void ath_tx_resume_tid(struct ath
 {
 	struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
 
-	ASSERT(tid->paused > 0);
+	BUG_ON(tid->paused <= 0);
 	spin_lock_bh(&txq->axq_lock);
 
 	tid->paused--;
@@ -131,7 +154,7 @@ static void ath_tx_flush_tid(struct ath_
 	struct list_head bf_head;
 	INIT_LIST_HEAD(&bf_head);
 
-	ASSERT(tid->paused > 0);
+	BUG_ON(tid->paused <= 0);
 	spin_lock_bh(&txq->axq_lock);
 
 	tid->paused--;
@@ -143,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
 
 	while (!list_empty(&tid->buf_q)) {
 		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-		ASSERT(!bf_isretried(bf));
+		BUG_ON(bf_isretried(bf));
 		list_move_tail(&bf->list, &bf_head);
 		ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
 	}
@@ -178,7 +201,7 @@ static void ath_tx_addto_baw(struct ath_
 	index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
 	cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
 
-	ASSERT(tid->tx_buf[cindex] == NULL);
+	BUG_ON(tid->tx_buf[cindex] != NULL);
 	tid->tx_buf[cindex] = bf;
 
 	if (index >= ((tid->baw_tail - tid->baw_head) &
@@ -251,6 +274,7 @@ static struct ath_buf* ath_clone_txbuf(s
 
 	ATH_TXBUF_RESET(tbf);
 
+	tbf->aphy = bf->aphy;
 	tbf->bf_mpdu = bf->bf_mpdu;
 	tbf->bf_buf_addr = bf->bf_buf_addr;
 	*(tbf->bf_desc) = *(bf->bf_desc);
@@ -267,7 +291,9 @@ static void ath_tx_complete_aggr(struct
 	struct ath_node *an = NULL;
 	struct sk_buff *skb;
 	struct ieee80211_sta *sta;
+	struct ieee80211_hw *hw;
 	struct ieee80211_hdr *hdr;
+	struct ieee80211_tx_info *tx_info;
 	struct ath_atx_tid *tid = NULL;
 	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
 	struct ath_desc *ds = bf_last->bf_desc;
@@ -280,9 +306,13 @@ static void ath_tx_complete_aggr(struct
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
 
+	tx_info = IEEE80211_SKB_CB(skb);
+	hw = bf->aphy->hw;
+
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+	/* XXX: use ieee80211_find_sta! */
+	sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
@@ -358,7 +388,7 @@ static void ath_tx_complete_aggr(struct
 			else
 				INIT_LIST_HEAD(&bf_head);
 		} else {
-			ASSERT(!list_empty(bf_q));
+			BUG_ON(list_empty(bf_q));
 			list_move_tail(&bf->list, &bf_head);
 		}
 
@@ -452,11 +482,9 @@ static void ath_tx_complete_aggr(struct
 static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 			   struct ath_atx_tid *tid)
 {
-	const struct ath_rate_table *rate_table = sc->cur_rate_table;
 	struct sk_buff *skb;
 	struct ieee80211_tx_info *tx_info;
 	struct ieee80211_tx_rate *rates;
-	struct ath_tx_info_priv *tx_info_priv;
 	u32 max_4ms_framelen, frmlen;
 	u16 aggr_limit, legacy = 0;
 	int i;
@@ -464,7 +492,6 @@ static u32 ath_lookup_rate(struct ath_so
 	skb = bf->bf_mpdu;
 	tx_info = IEEE80211_SKB_CB(skb);
 	rates = tx_info->control.rates;
-	tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
 
 	/*
 	 * Find the lowest frame length among the rate series that will have a
@@ -475,12 +502,20 @@ static u32 ath_lookup_rate(struct ath_so
 
 	for (i = 0; i < 4; i++) {
 		if (rates[i].count) {
-			if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) {
+			int modeidx;
+			if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) {
 				legacy = 1;
 				break;
 			}
 
-			frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+			if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+				modeidx = MCS_HT40_SGI;
+			else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+				modeidx = MCS_HT40;
+			else
+				modeidx = MCS_DEFAULT;
+
+			frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
 			max_4ms_framelen = min(max_4ms_framelen, frmlen);
 		}
 	}
@@ -518,12 +553,11 @@ static u32 ath_lookup_rate(struct ath_so
 static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 				  struct ath_buf *bf, u16 frmlen)
 {
-	const struct ath_rate_table *rt = sc->cur_rate_table;
 	struct sk_buff *skb = bf->bf_mpdu;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	u32 nsymbits, nsymbols;
 	u16 minlen;
-	u8 rc, flags, rix;
+	u8 flags, rix;
 	int width, half_gi, ndelim, mindelim;
 
 	/* Select standard number of delimiters based on frame length alone */
@@ -553,7 +587,6 @@ static int ath_compute_num_delims(struct
 
 	rix = tx_info->control.rates[0].idx;
 	flags = tx_info->control.rates[0].flags;
-	rc = rt->info[rix].ratecode;
 	width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
 	half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
 
@@ -565,7 +598,7 @@ static int ath_compute_num_delims(struct
 	if (nsymbols == 0)
 		nsymbols = 1;
 
-	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+	nsymbits = bits_per_symbol[rix][width];
 	minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
 
 	if (frmlen < minlen) {
@@ -694,7 +727,6 @@ static void ath_tx_sched_aggr(struct ath
 		/* anchor last desc of aggregate */
 		ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
 
-		txq->axq_aggr_depth++;
 		ath_tx_txqaddbuf(sc, txq, &bf_q);
 		TX_STAT_INC(txq->axq_qnum, a_aggr);
 
@@ -815,6 +847,7 @@ static void ath_txq_drain_pending_buffer
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info qi;
 	int qnum;
 
@@ -854,9 +887,9 @@ struct ath_txq *ath_txq_setup(struct ath
 		return NULL;
 	}
 	if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"qnum %u out of range, max %u!\n",
-			qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
+		ath_print(common, ATH_DBG_FATAL,
+			  "qnum %u out of range, max %u!\n",
+			  qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
 		ath9k_hw_releasetxqueue(ah, qnum);
 		return NULL;
 	}
@@ -869,8 +902,6 @@ struct ath_txq *ath_txq_setup(struct ath
 		INIT_LIST_HEAD(&txq->axq_acq);
 		spin_lock_init(&txq->axq_lock);
 		txq->axq_depth = 0;
-		txq->axq_aggr_depth = 0;
-		txq->axq_linkbuf = NULL;
 		txq->axq_tx_inprogress = false;
 		sc->tx.txqsetup |= 1<<qnum;
 	}
@@ -884,9 +915,9 @@ int ath_tx_get_qnum(struct ath_softc *sc
 	switch (qtype) {
 	case ATH9K_TX_QUEUE_DATA:
 		if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"HAL AC %u out of range, max %zu!\n",
-				haltype, ARRAY_SIZE(sc->tx.hwq_map));
+			ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+				  "HAL AC %u out of range, max %zu!\n",
+				  haltype, ARRAY_SIZE(sc->tx.hwq_map));
 			return -1;
 		}
 		qnum = sc->tx.hwq_map[haltype];
@@ -906,18 +937,19 @@ int ath_tx_get_qnum(struct ath_softc *sc
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ath_txq *txq = NULL;
+	u16 skb_queue = skb_get_queue_mapping(skb);
 	int qnum;
 
-	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+	qnum = ath_get_hal_qnum(skb_queue, sc);
 	txq = &sc->tx.txq[qnum];
 
 	spin_lock_bh(&txq->axq_lock);
 
 	if (txq->axq_depth >= (ATH_TXBUF - 20)) {
-		DPRINTF(sc, ATH_DBG_XMIT,
-			"TX queue: %d is full, depth: %d\n",
-			qnum, txq->axq_depth);
-		ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
+			  "TX queue: %d is full, depth: %d\n",
+			  qnum, txq->axq_depth);
+		ath_mac80211_stop_queue(sc, skb_queue);
 		txq->stopped = 1;
 		spin_unlock_bh(&txq->axq_lock);
 		return NULL;
@@ -945,7 +977,7 @@ int ath_txq_update(struct ath_softc *sc,
 		return 0;
 	}
 
-	ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
+	BUG_ON(sc->tx.txq[qnum].axq_qnum != qnum);
 
 	ath9k_hw_get_txq_props(ah, qnum, &qi);
 	qi.tqi_aifs = qinfo->tqi_aifs;
@@ -955,8 +987,8 @@ int ath_txq_update(struct ath_softc *sc,
 	qi.tqi_readyTime = qinfo->tqi_readyTime;
 
 	if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to update hardware queue %u!\n", qnum);
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "Unable to update hardware queue %u!\n", qnum);
 		error = -EIO;
 	} else {
 		ath9k_hw_resettxqueue(ah, qnum);
@@ -1004,7 +1036,6 @@ void ath_draintxq(struct ath_softc *sc,
 
 		if (list_empty(&txq->axq_q)) {
 			txq->axq_link = NULL;
-			txq->axq_linkbuf = NULL;
 			spin_unlock_bh(&txq->axq_lock);
 			break;
 		}
@@ -1055,6 +1086,7 @@ void ath_draintxq(struct ath_softc *sc,
 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_txq *txq;
 	int i, npend = 0;
 
@@ -1076,14 +1108,15 @@ void ath_drain_all_txq(struct ath_softc
 	if (npend) {
 		int r;
 
-		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to stop TxDMA. Reset HAL!\n");
 
 		spin_lock_bh(&sc->sc_resetlock);
-		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
 		if (r)
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to reset hardware; reset status %d\n",
-				r);
+			ath_print(common, ATH_DBG_FATAL,
+				  "Unable to reset hardware; reset status %d\n",
+				  r);
 		spin_unlock_bh(&sc->sc_resetlock);
 	}
 
@@ -1147,8 +1180,8 @@ int ath_tx_setup(struct ath_softc *sc, i
 	struct ath_txq *txq;
 
 	if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"HAL AC %u out of range, max %zu!\n",
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "HAL AC %u out of range, max %zu!\n",
 			 haltype, ARRAY_SIZE(sc->tx.hwq_map));
 		return 0;
 	}
@@ -1172,6 +1205,7 @@ static void ath_tx_txqaddbuf(struct ath_
 			     struct list_head *head)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_buf *bf;
 
 	/*
@@ -1186,21 +1220,20 @@ static void ath_tx_txqaddbuf(struct ath_
 
 	list_splice_tail_init(head, &txq->axq_q);
 	txq->axq_depth++;
-	txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
 
-	DPRINTF(sc, ATH_DBG_QUEUE,
-		"qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+	ath_print(common, ATH_DBG_QUEUE,
+		  "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
 
 	if (txq->axq_link == NULL) {
 		ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-		DPRINTF(sc, ATH_DBG_XMIT,
-			"TXDP[%u] = %llx (%p)\n",
-			txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+		ath_print(common, ATH_DBG_XMIT,
+			  "TXDP[%u] = %llx (%p)\n",
+			  txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
 	} else {
 		*txq->axq_link = bf->bf_daddr;
-		DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
-			txq->axq_qnum, txq->axq_link,
-			ito64(bf->bf_daddr), bf->bf_desc);
+		ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
+			  txq->axq_qnum, txq->axq_link,
+			  ito64(bf->bf_daddr), bf->bf_desc);
 	}
 	txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
 	ath9k_hw_txstart(ah, txq->axq_qnum);
@@ -1381,17 +1414,9 @@ static void assign_aggr_tid_seqno(struct
 	 * For HT capable stations, we save tidno for later use.
 	 * We also override seqno set by upper layer with the one
 	 * in tx aggregation state.
-	 *
-	 * If fragmentation is on, the sequence number is
-	 * not overridden, since it has been
-	 * incremented by the fragmentation routine.
-	 *
-	 * FIXME: check if the fragmentation threshold exceeds
-	 * IEEE80211 max.
 	 */
 	tid = ATH_AN_2_TID(an, bf->bf_tidno);
-	hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
-			IEEE80211_SEQ_SEQ_SHIFT);
+	hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
 	bf->bf_seqno = tid->seq_next;
 	INCR(tid->seq_next, IEEE80211_SEQ_MAX);
 }
@@ -1420,22 +1445,14 @@ static int setup_tx_flags(struct ath_sof
 static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
 			    int width, int half_gi, bool shortPreamble)
 {
-	const struct ath_rate_table *rate_table = sc->cur_rate_table;
 	u32 nbits, nsymbits, duration, nsymbols;
-	u8 rc;
 	int streams, pktlen;
 
 	pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
-	rc = rate_table->info[rix].ratecode;
-
-	/* for legacy rates, use old function to compute packet duration */
-	if (!IS_HT_RATE(rc))
-		return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
-					      rix, shortPreamble);
 
 	/* find number of symbols: PLCP + data */
 	nbits = (pktlen << 3) + OFDM_PLCP_BITS;
-	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+	nsymbits = bits_per_symbol[rix][width];
 	nsymbols = (nbits + nsymbits - 1) / nsymbits;
 
 	if (!half_gi)
@@ -1444,7 +1461,7 @@ static u32 ath_pkt_duration(struct ath_s
 		duration = SYMBOL_TIME_HALFGI(nsymbols);
 
 	/* addup duration for legacy/ht training and signal fields */
-	streams = HT_RC_2_STREAMS(rc);
+	streams = HT_RC_2_STREAMS(rix);
 	duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
 
 	return duration;
@@ -1452,11 +1469,12 @@ static u32 ath_pkt_duration(struct ath_s
 
 static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
 {
-	const struct ath_rate_table *rt = sc->cur_rate_table;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath9k_11n_rate_series series[4];
 	struct sk_buff *skb;
 	struct ieee80211_tx_info *tx_info;
 	struct ieee80211_tx_rate *rates;
+	const struct ieee80211_rate *rate;
 	struct ieee80211_hdr *hdr;
 	int i, flags = 0;
 	u8 rix = 0, ctsrate = 0;
@@ -1475,11 +1493,10 @@ static void ath_buf_set_rate(struct ath_
 	 * checking the BSS's global flag.
 	 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
 	 */
+	rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
+	ctsrate = rate->hw_value;
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-		ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
-			rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
-	else
-		ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
+		ctsrate |= rate->hw_value_short;
 
 	/*
 	 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
@@ -1502,18 +1519,15 @@ static void ath_buf_set_rate(struct ath_
 		flags &= ~(ATH9K_TXDESC_RTSENA);
 
 	for (i = 0; i < 4; i++) {
+		bool is_40, is_sgi, is_sp;
+		int phy;
+
 		if (!rates[i].count || (rates[i].idx < 0))
 			continue;
 
 		rix = rates[i].idx;
 		series[i].Tries = rates[i].count;
-		series[i].ChSel = sc->tx_chainmask;
-
-		if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-			series[i].Rate = rt->info[rix].ratecode |
-				rt->info[rix].short_preamble;
-		else
-			series[i].Rate = rt->info[rix].ratecode;
+		series[i].ChSel = common->tx_chainmask;
 
 		if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
 			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
@@ -1522,10 +1536,36 @@ static void ath_buf_set_rate(struct ath_
 		if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
 			series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
 
-		series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
-			 (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
-			 (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
-			 (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
+		is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
+		is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
+		is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+
+		if (rates[i].flags & IEEE80211_TX_RC_MCS) {
+			/* MCS rates */
+			series[i].Rate = rix | 0x80;
+			series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+				 is_40, is_sgi, is_sp);
+			continue;
+		}
+
+		/* legcay rates */
+		if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
+		    !(rate->flags & IEEE80211_RATE_ERP_G))
+			phy = WLAN_RC_PHY_CCK;
+		else
+			phy = WLAN_RC_PHY_OFDM;
+
+		rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
+		series[i].Rate = rate->hw_value;
+		if (rate->hw_value_short) {
+			if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+				series[i].Rate |= rate->hw_value_short;
+		} else {
+			is_sp = false;
+		}
+
+		series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
+			phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
 	}
 
 	/* set dur_update_en for l-sig computation except for PS-Poll frames */
@@ -1546,24 +1586,36 @@ static int ath_tx_setup_buffer(struct ie
 	struct ath_softc *sc = aphy->sc;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	struct ath_tx_info_priv *tx_info_priv;
 	int hdrlen;
 	__le16 fc;
+	int padpos, padsize;
 
-	tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
-	if (unlikely(!tx_info_priv))
-		return -ENOMEM;
-	tx_info->rate_driver_data[0] = tx_info_priv;
-	tx_info_priv->aphy = aphy;
-	tx_info_priv->frame_type = txctl->frame_type;
+	tx_info->pad[0] = 0;
+	switch (txctl->frame_type) {
+	case ATH9K_NOT_INTERNAL:
+		break;
+	case ATH9K_INT_PAUSE:
+		tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE;
+		/* fall through */
+	case ATH9K_INT_UNPAUSE:
+		tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL;
+		break;
+	}
 	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 	fc = hdr->frame_control;
 
 	ATH_TXBUF_RESET(bf);
 
-	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+	bf->aphy = aphy;
+	bf->bf_frmlen = skb->len + FCS_LEN;
+	/* Remove the padding size from bf_frmlen, if any */
+	padpos = ath9k_cmn_padpos(hdr->frame_control);
+	padsize = padpos & 3;
+	if (padsize && skb->len>padpos+padsize) {
+		bf->bf_frmlen -= padsize;
+	}
 
-	if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+	if (conf_is_ht(&hw->conf))
 		bf->bf_state.bf_type |= BUF_HT;
 
 	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
@@ -1576,7 +1628,8 @@ static int ath_tx_setup_buffer(struct ie
 		bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
 	}
 
-	if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+	if (ieee80211_is_data_qos(fc) && bf_isht(bf) &&
+	    (sc->sc_flags & SC_OP_TXAGGR))
 		assign_aggr_tid_seqno(skb, bf);
 
 	bf->bf_mpdu = skb;
@@ -1585,13 +1638,20 @@ static int ath_tx_setup_buffer(struct ie
 					   skb->len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
 		bf->bf_mpdu = NULL;
-		kfree(tx_info_priv);
-		tx_info->rate_driver_data[0] = NULL;
-		DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
+			  "dma_mapping_error() on TX\n");
 		return -ENOMEM;
 	}
 
 	bf->bf_buf_addr = bf->bf_dmacontext;
+
+	/* tag if this is a nullfunc frame to enable PS when AP acks it */
+	if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
+		bf->bf_isnullfunc = true;
+		sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
+	} else
+		bf->bf_isnullfunc = false;
+
 	return 0;
 }
 
@@ -1641,7 +1701,7 @@ static void ath_tx_start_dma(struct ath_
 			goto tx_done;
 		}
 
-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+		if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
 			/*
 			 * Try aggregation if it's a unicast data frame
 			 * and the destination is HT capable.
@@ -1669,12 +1729,13 @@ int ath_tx_start(struct ieee80211_hw *hw
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_buf *bf;
 	int r;
 
 	bf = ath_tx_get_buffer(sc);
 	if (!bf) {
-		DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+		ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n");
 		return -1;
 	}
 
@@ -1682,7 +1743,7 @@ int ath_tx_start(struct ieee80211_hw *hw
 	if (unlikely(r)) {
 		struct ath_txq *txq = txctl->txq;
 
-		DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
+		ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
 
 		/* upon ath_tx_processq() this TX queue will be resumed, we
 		 * guarantee this will happen by knowing beforehand that
@@ -1690,8 +1751,7 @@ int ath_tx_start(struct ieee80211_hw *hw
 		 * on the queue */
 		spin_lock_bh(&txq->axq_lock);
 		if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-			ieee80211_stop_queue(sc->hw,
-				skb_get_queue_mapping(skb));
+			ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
 			txq->stopped = 1;
 		}
 		spin_unlock_bh(&txq->axq_lock);
@@ -1712,7 +1772,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
-	int hdrlen, padsize;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	int padpos, padsize;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ath_tx_control txctl;
 
@@ -1724,7 +1786,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw
 	 * BSSes.
 	 */
 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
 			sc->tx.seq_no += 0x10;
 		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -1732,24 +1793,26 @@ void ath_tx_cabq(struct ieee80211_hw *hw
 	}
 
 	/* Add the padding after the header if this is not already done */
-	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-	if (hdrlen & 3) {
-		padsize = hdrlen % 4;
+	padpos = ath9k_cmn_padpos(hdr->frame_control);
+	padsize = padpos & 3;
+	if (padsize && skb->len>padpos) {
 		if (skb_headroom(skb) < padsize) {
-			DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
+			ath_print(common, ATH_DBG_XMIT,
+				  "TX CABQ padding failed\n");
 			dev_kfree_skb_any(skb);
 			return;
 		}
 		skb_push(skb, padsize);
-		memmove(skb->data, skb->data + padsize, hdrlen);
+		memmove(skb->data, skb->data + padsize, padpos);
 	}
 
 	txctl.txq = sc->beacon.cabq;
 
-	DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
+	ath_print(common, ATH_DBG_XMIT,
+		  "transmitting CABQ packet, skb: %p\n", skb);
 
 	if (ath_tx_start(hw, skb, &txctl) != 0) {
-		DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+		ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n");
 		goto exit;
 	}
 
@@ -1763,26 +1826,18 @@ exit:
 /*****************/
 
 static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-			    int tx_flags)
+			    struct ath_wiphy *aphy, int tx_flags)
 {
 	struct ieee80211_hw *hw = sc->hw;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-	int hdrlen, padsize;
-	int frame_type = ATH9K_NOT_INTERNAL;
-
-	DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
+	int padpos, padsize;
 
-	if (tx_info_priv) {
-		hw = tx_info_priv->aphy->hw;
-		frame_type = tx_info_priv->frame_type;
-	}
+	ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
 
-	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
-	    tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
-		kfree(tx_info_priv);
-		tx_info->rate_driver_data[0] = NULL;
-	}
+	if (aphy)
+		hw = aphy->hw;
 
 	if (tx_flags & ATH_TX_BAR)
 		tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
@@ -1792,31 +1847,32 @@ static void ath_tx_complete(struct ath_s
 		tx_info->flags |= IEEE80211_TX_STAT_ACK;
 	}
 
-	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-	padsize = hdrlen & 3;
-	if (padsize && hdrlen >= 24) {
+	padpos = ath9k_cmn_padpos(hdr->frame_control);
+	padsize = padpos & 3;
+	if (padsize && skb->len>padpos+padsize) {
 		/*
 		 * Remove MAC header padding before giving the frame back to
 		 * mac80211.
 		 */
-		memmove(skb->data + padsize, skb->data, hdrlen);
+		memmove(skb->data + padsize, skb->data, padpos);
 		skb_pull(skb, padsize);
 	}
 
 	if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) {
 		sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK;
-		DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
-			"received TX status (0x%x)\n",
+		ath_print(common, ATH_DBG_PS,
+			  "Going back to sleep after having "
+			  "received TX status (0x%x)\n",
 			sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
 					SC_OP_WAIT_FOR_CAB |
 					SC_OP_WAIT_FOR_PSPOLL_DATA |
 					SC_OP_WAIT_FOR_TX_ACK));
 	}
 
-	if (frame_type == ATH9K_NOT_INTERNAL)
-		ieee80211_tx_status(hw, skb);
-	else
+	if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
 		ath9k_tx_status(hw, skb);
+	else
+		ieee80211_tx_status(hw, skb);
 }
 
 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
@@ -1839,7 +1895,7 @@ static void ath_tx_complete_buf(struct a
 	}
 
 	dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
-	ath_tx_complete(sc, skb, tx_flags);
+	ath_tx_complete(sc, skb, bf->aphy, tx_flags);
 	ath_debug_stat_tx(sc, txq, bf);
 
 	/*
@@ -1887,8 +1943,7 @@ static void ath_tx_rc_status(struct ath_
 	struct sk_buff *skb = bf->bf_mpdu;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-	struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
+	struct ieee80211_hw *hw = bf->aphy->hw;
 	u8 i, tx_rateindex;
 
 	if (txok)
@@ -1897,22 +1952,29 @@ static void ath_tx_rc_status(struct ath_
 	tx_rateindex = ds->ds_txstat.ts_rateindex;
 	WARN_ON(tx_rateindex >= hw->max_rates);
 
-	tx_info_priv->update_rc = update_rc;
+	if (update_rc)
+		tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC;
 	if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
 		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 
 	if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
 	    (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
 		if (ieee80211_is_data(hdr->frame_control)) {
-			memcpy(&tx_info_priv->tx, &ds->ds_txstat,
-			       sizeof(tx_info_priv->tx));
-			tx_info_priv->n_frames = bf->bf_nframes;
-			tx_info_priv->n_bad_frames = nbad;
+			if (ds->ds_txstat.ts_flags &
+			    (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
+				tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
+			if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) ||
+			    (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO))
+				tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
+			tx_info->status.ampdu_len = bf->bf_nframes;
+			tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
 		}
 	}
 
-	for (i = tx_rateindex + 1; i < hw->max_rates; i++)
+	for (i = tx_rateindex + 1; i < hw->max_rates; i++) {
 		tx_info->status.rates[i].count = 0;
+		tx_info->status.rates[i].idx = -1;
+	}
 
 	tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
 }
@@ -1926,7 +1988,7 @@ static void ath_wake_mac80211_queue(stru
 	    sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
 		qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
 		if (qnum != -1) {
-			ieee80211_wake_queue(sc->hw, qnum);
+			ath_mac80211_start_queue(sc, qnum);
 			txq->stopped = 0;
 		}
 	}
@@ -1936,21 +1998,21 @@ static void ath_wake_mac80211_queue(stru
 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 {
 	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_buf *bf, *lastbf, *bf_held = NULL;
 	struct list_head bf_head;
 	struct ath_desc *ds;
 	int txok;
 	int status;
 
-	DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
-		txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
-		txq->axq_link);
+	ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+		  txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+		  txq->axq_link);
 
 	for (;;) {
 		spin_lock_bh(&txq->axq_lock);
 		if (list_empty(&txq->axq_q)) {
 			txq->axq_link = NULL;
-			txq->axq_linkbuf = NULL;
 			spin_unlock_bh(&txq->axq_lock);
 			break;
 		}
@@ -1984,10 +2046,19 @@ static void ath_tx_processq(struct ath_s
 			spin_unlock_bh(&txq->axq_lock);
 			break;
 		}
-		if (bf->bf_desc == txq->axq_lastdsWithCTS)
-			txq->axq_lastdsWithCTS = NULL;
-		if (ds == txq->axq_gatingds)
-			txq->axq_gatingds = NULL;
+
+		/*
+		 * We now know the nullfunc frame has been ACKed so we
+		 * can disable RX.
+		 */
+		if (bf->bf_isnullfunc &&
+		    (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
+			if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
+				sc->ps_enabled = true;
+				ath9k_hw_setrxabort(sc->sc_ah, 1);
+			} else
+				sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
+		}
 
 		/*
 		 * Remove ath_buf's of the same transmit unit from txq,
@@ -2001,10 +2072,7 @@ static void ath_tx_processq(struct ath_s
 				&txq->axq_q, lastbf->list.prev);
 
 		txq->axq_depth--;
-		if (bf_isaggr(bf))
-			txq->axq_aggr_depth--;
-
-		txok = (ds->ds_txstat.ts_status == 0);
+		txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK);
 		txq->axq_tx_inprogress = false;
 		spin_unlock_bh(&txq->axq_lock);
 
@@ -2064,8 +2132,11 @@ static void ath_tx_complete_poll_work(st
 		}
 
 	if (needreset) {
-		DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n");
+		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
+			  "tx hung, resetting the chip\n");
+		ath9k_ps_wakeup(sc);
 		ath_reset(sc, false);
+		ath9k_ps_restore(sc);
 	}
 
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
@@ -2093,6 +2164,7 @@ void ath_tx_tasklet(struct ath_softc *sc
 
 int ath_tx_init(struct ath_softc *sc, int nbufs)
 {
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	int error = 0;
 
 	spin_lock_init(&sc->tx.txbuflock);
@@ -2100,16 +2172,16 @@ int ath_tx_init(struct ath_softc *sc, in
 	error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
 				  "tx", nbufs, 1);
 	if (error != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Failed to allocate tx descriptors: %d\n", error);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Failed to allocate tx descriptors: %d\n", error);
 		goto err;
 	}
 
 	error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
 				  "beacon", ATH_BCBUF, 1);
 	if (error != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Failed to allocate beacon descriptors: %d\n", error);
+		ath_print(common, ATH_DBG_FATAL,
+			  "Failed to allocate beacon descriptors: %d\n", error);
 		goto err;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/ath.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/ath.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,35 @@
 #define ATH_H
 
 #include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <net/mac80211.h>
+
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches.  We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define	ATH_KEYMAX	        128     /* max key cache size we handle */
+
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct ath_ani {
+	bool caldone;
+	int16_t noise_floor;
+	unsigned int longcal_timer;
+	unsigned int shortcal_timer;
+	unsigned int resetcal_timer;
+	unsigned int checkani_timer;
+	struct timer_list timer;
+};
+
+enum ath_device_state {
+	ATH_HW_UNAVAILABLE,
+	ATH_HW_INITIALIZED,
+};
 
 struct reg_dmn_pair_mapping {
 	u16 regDmnEnum;
@@ -36,13 +65,53 @@ struct ath_regulatory {
 	struct reg_dmn_pair_mapping *regpair;
 };
 
+struct ath_ops {
+	unsigned int (*read)(void *, u32 reg_offset);
+        void (*write)(void *, u32 val, u32 reg_offset);
+};
+
+struct ath_common;
+
+struct ath_bus_ops {
+	void		(*read_cachesize)(struct ath_common *common, int *csz);
+	void		(*cleanup)(struct ath_common *common);
+	bool		(*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+	void		(*bt_coex_prep)(struct ath_common *common);
+};
+
 struct ath_common {
+	void *ah;
+	void *priv;
+	struct ieee80211_hw *hw;
+	int debug_mask;
+	enum ath_device_state state;
+
+	struct ath_ani ani;
+
 	u16 cachelsz;
+	u16 curaid;
+	u8 macaddr[ETH_ALEN];
+	u8 curbssid[ETH_ALEN];
+	u8 bssidmask[ETH_ALEN];
+
+	u8 tx_chainmask;
+	u8 rx_chainmask;
+
+	u32 rx_bufsize;
+
+	u32 keymax;
+	DECLARE_BITMAP(keymap, ATH_KEYMAX);
+	u8 splitmic;
+
 	struct ath_regulatory regulatory;
+	const struct ath_ops *ops;
+	const struct ath_bus_ops *bus_ops;
 };
 
 struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
 				u32 len,
 				gfp_t gfp_mask);
 
+void ath_hw_setbssidmask(struct ath_common *common);
+
 #endif /* ATH_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/debug.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2009 Atheros Communications 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 "ath.h"
+#include "debug.h"
+
+void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
+{
+	va_list args;
+
+	if (likely(!(common->debug_mask & dbg_mask)))
+		return;
+
+	va_start(args, fmt);
+	printk(KERN_DEBUG "ath: ");
+	vprintk(fmt, args);
+	va_end(args);
+}
+EXPORT_SYMBOL(ath_print);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/debug.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/debug.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications 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 ATH_DEBUG_H
+#define ATH_DEBUG_H
+
+#include "ath.h"
+
+/**
+ * enum ath_debug_level - atheros wireless debug level
+ *
+ * @ATH_DBG_RESET: reset processing
+ * @ATH_DBG_QUEUE: hardware queue management
+ * @ATH_DBG_EEPROM: eeprom processing
+ * @ATH_DBG_CALIBRATE: periodic calibration
+ * @ATH_DBG_INTERRUPT: interrupt processing
+ * @ATH_DBG_REGULATORY: regulatory processing
+ * @ATH_DBG_ANI: adaptive noise immunitive processing
+ * @ATH_DBG_XMIT: basic xmit operation
+ * @ATH_DBG_BEACON: beacon handling
+ * @ATH_DBG_CONFIG: configuration of the hardware
+ * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
+ * @ATH_DBG_PS: power save processing
+ * @ATH_DBG_HWTIMER: hardware timer handling
+ * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_ANY: enable all debugging
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. Each driver has its own method for enabling debugging and
+ * modifying debug level states -- but this is typically done through a
+ * module parameter 'debug' along with a respective 'debug' debugfs file
+ * entry.
+ */
+enum ATH_DEBUG {
+	ATH_DBG_RESET		= 0x00000001,
+	ATH_DBG_QUEUE		= 0x00000002,
+	ATH_DBG_EEPROM		= 0x00000004,
+	ATH_DBG_CALIBRATE	= 0x00000008,
+	ATH_DBG_INTERRUPT	= 0x00000010,
+	ATH_DBG_REGULATORY	= 0x00000020,
+	ATH_DBG_ANI		= 0x00000040,
+	ATH_DBG_XMIT		= 0x00000080,
+	ATH_DBG_BEACON		= 0x00000100,
+	ATH_DBG_CONFIG		= 0x00000200,
+	ATH_DBG_FATAL		= 0x00000400,
+	ATH_DBG_PS		= 0x00000800,
+	ATH_DBG_HWTIMER		= 0x00001000,
+	ATH_DBG_BTCOEX		= 0x00002000,
+	ATH_DBG_ANY		= 0xffffffff
+};
+
+#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH_DEBUG
+void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...);
+#else
+static inline void ath_print(struct ath_common *common,
+			     int dbg_mask,
+			     const char *fmt, ...)
+{
+}
+#endif /* CONFIG_ATH_DEBUG */
+
+#endif /* ATH_DEBUG_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/hw.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/hw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2009 Atheros Communications 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 <asm/unaligned.h>
+
+#include "ath.h"
+#include "reg.h"
+
+#define REG_READ	common->ops->read
+#define REG_WRITE	common->ops->write
+
+/**
+ * ath_hw_set_bssid_mask - filter out bssids we listen
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode and AP mode with a single
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
+ * accept frames for all BSSes and so we tweak some bits of our mac address
+ * in order to have multiple BSSes.
+ *
+ * NOTE: This is a simple filter and does *not* filter out all
+ * relevant frames. Some frames that are not for us might get ACKed from us
+ * by PCU because they just match the mask.
+ *
+ * When handling multiple BSSes you can get the BSSID mask by computing the
+ * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
+ *
+ * When you do this you are essentially computing the common bits of all your
+ * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
+ * the MAC address to obtain the relevant bits and compare the result with
+ * (frame's BSSID & mask) to see if they match.
+ *
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ *                  \
+ * MAC:        0001 |
+ * BSSID-01:   0100 | --> Belongs to us
+ * BSSID-02:   1001 |
+ *                  /
+ * -------------------
+ * BSSID-03:   0110  | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ *             On loop iteration for BSSID-01:
+ *             ~(0001 ^ 0100)  -> ~(0101)
+ *                             ->   1010
+ *             bssid_mask      =    1010
+ *
+ *             On loop iteration for BSSID-02:
+ *             bssid_mask &= ~(0001   ^   1001)
+ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
+ *             bssid_mask =   (1010)  & ~(1001)
+ *             bssid_mask =   (1010)  &  (0110)
+ *             bssid_mask =   0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01:  0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is beacuse the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ *  --> allow = (0010) == 0000 ? 1 : 0;
+ *  --> allow = 0
+ *
+ *  Lets now test a frame that should work:
+ *
+ * IFRAME-02:  0001 (we should allow)
+ *
+ *     allow = (0001 & 1010) == 1010
+ *
+ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
+ *  --> allow = (0010) == (0010)
+ *  --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03:  0100 --> allowed
+ * IFRAME-04:  1001 --> allowed
+ * IFRAME-05:  1101 --> allowed but its not for us!!!
+ *
+ */
+void ath_hw_setbssidmask(struct ath_common *common)
+{
+	void *ah = common->ah;
+
+	REG_WRITE(ah, get_unaligned_le32(common->bssidmask), AR_BSSMSKL);
+	REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
+}
+EXPORT_SYMBOL(ath_hw_setbssidmask);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,5 @@
 menuconfig ATH_COMMON
 	tristate "Atheros Wireless Cards"
-	depends on WLAN_80211
 	depends on CFG80211
 	---help---
 	  This will enable the support for the Atheros wireless drivers.
@@ -16,7 +15,15 @@ menuconfig ATH_COMMON
 	  http://wireless.kernel.org/en/users/Drivers/Atheros
 
 if ATH_COMMON
+
+config ATH_DEBUG
+	bool "Atheros wireless debugging"
+	---help---
+	  Say Y, if you want to debug atheros wireless drivers.
+	  Right now only ath9k makes use of this.
+
 source "drivers/net/wireless/ath/ath5k/Kconfig"
 source "drivers/net/wireless/ath/ath9k/Kconfig"
 source "drivers/net/wireless/ath/ar9170/Kconfig"
+
 endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,11 @@
 obj-$(CONFIG_ATH5K)		+= ath5k/
-obj-$(CONFIG_ATH9K)		+= ath9k/
+obj-$(CONFIG_ATH9K_HW)		+= ath9k/
 obj-$(CONFIG_AR9170_USB)        += ar9170/
 
 obj-$(CONFIG_ATH_COMMON)	+= ath.o
-ath-objs 		:= main.o regd.o
+
+ath-objs :=	main.o \
+		regd.o \
+		hw.o
+
+ath-$(CONFIG_ATH_DEBUG) += debug.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.c	2010-02-24 13:52:17.000000000 -0500
@@ -450,7 +450,7 @@ ath_regd_init_wiphy(struct ath_regulator
 	const struct ieee80211_regdomain *regd;
 
 	wiphy->reg_notifier = reg_notifier;
-	wiphy->strict_regulatory = true;
+	wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
 
 	if (ath_is_world_regd(reg)) {
 		/*
@@ -458,8 +458,7 @@ ath_regd_init_wiphy(struct ath_regulator
 		 * saved on the wiphy orig_* parameters
 		 */
 		regd = ath_world_regdomain(reg);
-		wiphy->custom_regulatory = true;
-		wiphy->strict_regulatory = false;
+		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 	} else {
 		/*
 		 * This gets applied in the case of the absense of CRDA,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd_common.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd_common.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -288,13 +288,16 @@ static struct country_code_to_enum_rd al
 	{CTRY_DEFAULT, FCC1_FCCA, "CO"},
 	{CTRY_ALBANIA, NULL1_WORLD, "AL"},
 	{CTRY_ALGERIA, NULL1_WORLD, "DZ"},
-	{CTRY_ARGENTINA, APL3_WORLD, "AR"},
+	{CTRY_ARGENTINA, FCC3_WORLD, "AR"},
 	{CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+	{CTRY_ARUBA, ETSI1_WORLD, "AW"},
 	{CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
 	{CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
 	{CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
 	{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
 	{CTRY_BAHRAIN, APL6_WORLD, "BH"},
+	{CTRY_BANGLADESH, NULL1_WORLD, "BD"},
+	{CTRY_BARBADOS, FCC2_WORLD, "BB"},
 	{CTRY_BELARUS, ETSI1_WORLD, "BY"},
 	{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
 	{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
@@ -304,13 +307,14 @@ static struct country_code_to_enum_rd al
 	{CTRY_BRAZIL, FCC3_WORLD, "BR"},
 	{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
 	{CTRY_BULGARIA, ETSI6_WORLD, "BG"},
-	{CTRY_CANADA, FCC2_FCCA, "CA"},
+	{CTRY_CAMBODIA, ETSI1_WORLD, "KH"},
+	{CTRY_CANADA, FCC3_FCCA, "CA"},
 	{CTRY_CANADA2, FCC6_FCCA, "CA"},
 	{CTRY_CHILE, APL6_WORLD, "CL"},
 	{CTRY_CHINA, APL1_WORLD, "CN"},
 	{CTRY_COLOMBIA, FCC1_FCCA, "CO"},
 	{CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
-	{CTRY_CROATIA, ETSI3_WORLD, "HR"},
+	{CTRY_CROATIA, ETSI1_WORLD, "HR"},
 	{CTRY_CYPRUS, ETSI1_WORLD, "CY"},
 	{CTRY_CZECH, ETSI3_WORLD, "CZ"},
 	{CTRY_DENMARK, ETSI1_WORLD, "DK"},
@@ -324,18 +328,22 @@ static struct country_code_to_enum_rd al
 	{CTRY_GEORGIA, ETSI4_WORLD, "GE"},
 	{CTRY_GERMANY, ETSI1_WORLD, "DE"},
 	{CTRY_GREECE, ETSI1_WORLD, "GR"},
+	{CTRY_GREENLAND, ETSI1_WORLD, "GL"},
+	{CTRY_GRENEDA, FCC3_FCCA, "GD"},
+	{CTRY_GUAM, FCC1_FCCA, "GU"},
 	{CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+	{CTRY_HAITI, ETSI1_WORLD, "HT"},
 	{CTRY_HONDURAS, NULL1_WORLD, "HN"},
-	{CTRY_HONG_KONG, FCC2_WORLD, "HK"},
+	{CTRY_HONG_KONG, FCC3_WORLD, "HK"},
 	{CTRY_HUNGARY, ETSI1_WORLD, "HU"},
 	{CTRY_ICELAND, ETSI1_WORLD, "IS"},
 	{CTRY_INDIA, APL6_WORLD, "IN"},
-	{CTRY_INDONESIA, APL1_WORLD, "ID"},
+	{CTRY_INDONESIA, NULL1_WORLD, "ID"},
 	{CTRY_IRAN, APL1_WORLD, "IR"},
 	{CTRY_IRELAND, ETSI1_WORLD, "IE"},
 	{CTRY_ISRAEL, NULL1_WORLD, "IL"},
 	{CTRY_ITALY, ETSI1_WORLD, "IT"},
-	{CTRY_JAMAICA, ETSI1_WORLD, "JM"},
+	{CTRY_JAMAICA, FCC3_WORLD, "JM"},
 
 	{CTRY_JAPAN, MKK1_MKKA, "JP"},
 	{CTRY_JAPAN1, MKK1_MKKB, "JP"},
@@ -402,7 +410,7 @@ static struct country_code_to_enum_rd al
 	{CTRY_KOREA_ROC, APL9_WORLD, "KR"},
 	{CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
 	{CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
-	{CTRY_KUWAIT, NULL1_WORLD, "KW"},
+	{CTRY_KUWAIT, ETSI3_WORLD, "KW"},
 	{CTRY_LATVIA, ETSI1_WORLD, "LV"},
 	{CTRY_LEBANON, NULL1_WORLD, "LB"},
 	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
@@ -414,13 +422,13 @@ static struct country_code_to_enum_rd al
 	{CTRY_MALTA, ETSI1_WORLD, "MT"},
 	{CTRY_MEXICO, FCC1_FCCA, "MX"},
 	{CTRY_MONACO, ETSI4_WORLD, "MC"},
-	{CTRY_MOROCCO, NULL1_WORLD, "MA"},
+	{CTRY_MOROCCO, APL4_WORLD, "MA"},
 	{CTRY_NEPAL, APL1_WORLD, "NP"},
 	{CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
 	{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
 	{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
 	{CTRY_NORWAY, ETSI1_WORLD, "NO"},
-	{CTRY_OMAN, APL6_WORLD, "OM"},
+	{CTRY_OMAN, FCC3_WORLD, "OM"},
 	{CTRY_PAKISTAN, NULL1_WORLD, "PK"},
 	{CTRY_PANAMA, FCC1_FCCA, "PA"},
 	{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
@@ -429,7 +437,7 @@ static struct country_code_to_enum_rd al
 	{CTRY_POLAND, ETSI1_WORLD, "PL"},
 	{CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
 	{CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
-	{CTRY_QATAR, NULL1_WORLD, "QA"},
+	{CTRY_QATAR, APL1_WORLD, "QA"},
 	{CTRY_ROMANIA, NULL1_WORLD, "RO"},
 	{CTRY_RUSSIA, NULL1_WORLD, "RU"},
 	{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
@@ -445,7 +453,7 @@ static struct country_code_to_enum_rd al
 	{CTRY_SYRIA, NULL1_WORLD, "SY"},
 	{CTRY_TAIWAN, APL3_FCCA, "TW"},
 	{CTRY_THAILAND, FCC3_WORLD, "TH"},
-	{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
+	{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
 	{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
 	{CTRY_TURKEY, ETSI3_WORLD, "TR"},
 	{CTRY_UKRAINE, NULL1_WORLD, "UA"},
@@ -456,7 +464,7 @@ static struct country_code_to_enum_rd al
 	 * would need to assign new special alpha2 to CRDA db as with the world
 	 * regdomain and use another alpha2 */
 	{CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
-	{CTRY_URUGUAY, APL2_WORLD, "UY"},
+	{CTRY_URUGUAY, FCC3_WORLD, "UY"},
 	{CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
 	{CTRY_VENEZUELA, APL2_ETSIC, "VE"},
 	{CTRY_VIET_NAM, NULL1_WORLD, "VN"},
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/regd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/regd.h	2010-02-24 13:52:17.000000000 -0500
@@ -65,10 +65,13 @@ enum CountryCode {
 	CTRY_ALGERIA = 12,
 	CTRY_ARGENTINA = 32,
 	CTRY_ARMENIA = 51,
+	CTRY_ARUBA = 533,
 	CTRY_AUSTRALIA = 36,
 	CTRY_AUSTRIA = 40,
 	CTRY_AZERBAIJAN = 31,
 	CTRY_BAHRAIN = 48,
+	CTRY_BANGLADESH = 50,
+	CTRY_BARBADOS = 52,
 	CTRY_BELARUS = 112,
 	CTRY_BELGIUM = 56,
 	CTRY_BELIZE = 84,
@@ -77,6 +80,7 @@ enum CountryCode {
 	CTRY_BRAZIL = 76,
 	CTRY_BRUNEI_DARUSSALAM = 96,
 	CTRY_BULGARIA = 100,
+	CTRY_CAMBODIA = 116,
 	CTRY_CANADA = 124,
 	CTRY_CHILE = 152,
 	CTRY_CHINA = 156,
@@ -97,7 +101,11 @@ enum CountryCode {
 	CTRY_GEORGIA = 268,
 	CTRY_GERMANY = 276,
 	CTRY_GREECE = 300,
+	CTRY_GREENLAND = 304,
+	CTRY_GRENEDA = 308,
+	CTRY_GUAM = 316,
 	CTRY_GUATEMALA = 320,
+	CTRY_HAITI = 332,
 	CTRY_HONDURAS = 340,
 	CTRY_HONG_KONG = 344,
 	CTRY_HUNGARY = 348,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ath/reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ath/reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications 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 ATH_REGISTERS_H
+#define ATH_REGISTERS_H
+
+/*
+ * BSSID mask registers. See ath_hw_set_bssid_mask()
+ * for detailed documentation about these registers.
+ */
+#define AR_BSSMSKL		0x80e0
+#define AR_BSSMSKU		0x80e4
+
+#endif /* ATH_REGISTERS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/atmel.c linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/atmel.c	2013-05-03 14:01:49.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel.c	2013-05-03 12:09:11.000000000 -0400
@@ -99,6 +99,7 @@ static struct {
 	{ ATMEL_FW_TYPE_506,		"/*(DEBLOBBED)*/",	"bin" },
 	{ ATMEL_FW_TYPE_NONE,		NULL,			NULL }
 };
+/*(DEBLOBBED)*/
 
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/atmel_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/atmel_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/atmel_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,22 +55,6 @@
 
 #include "atmel.h"
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -155,11 +139,10 @@ static int atmel_probe(struct pcmcia_dev
 {
 	local_info_t *local;
 
-	DEBUG(0, "atmel_attach()\n");
+	dev_dbg(&p_dev->dev, "atmel_attach()\n");
 
 	/* Interrupt setup */
 	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	p_dev->irq.Handler = NULL;
 
 	/*
@@ -194,7 +177,7 @@ static int atmel_probe(struct pcmcia_dev
 
 static void atmel_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "atmel_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "atmel_detach\n");
 
 	atmel_release(link);
 
@@ -209,9 +192,6 @@ static void atmel_detach(struct pcmcia_d
 
   ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /* Call-back function to interrogate PCMCIA-specific information
    about the current existance of the card */
 static int card_present(void *arg)
@@ -275,13 +255,13 @@ static int atmel_config_check(struct pcm
 static int atmel_config(struct pcmcia_device *link)
 {
 	local_info_t *dev;
-	int last_fn, last_ret;
+	int ret;
 	struct pcmcia_device_id *did;
 
 	dev = link->priv;
-	did = dev_get_drvdata(&handle_to_dev(link));
+	did = dev_get_drvdata(&link->dev);
 
-	DEBUG(0, "atmel_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "atmel_config\n");
 
 	/*
 	  In this loop, we scan the CIS for configuration table entries,
@@ -303,31 +283,36 @@ static int atmel_config(struct pcmcia_de
 	  handler to the interrupt, unless the 'Handler' member of the
 	  irq structure is initialized.
 	*/
-	if (link->conf.Attributes & CONF_ENABLE_IRQ)
-		CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		ret = pcmcia_request_irq(link, &link->irq);
+		if (ret)
+			goto failed;
+	}
 
 	/*
 	  This actually configures the PCMCIA socket -- setting up
 	  the I/O windows and the interrupt mapping, and putting the
 	  card and host interface into "Memory and IO" mode.
 	*/
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	if (link->irq.AssignedIRQ == 0) {
 		printk(KERN_ALERT
 		       "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
-		goto cs_failed;
+		goto failed;
 	}
 
 	((local_info_t*)link->priv)->eth_dev =
 		init_atmel_card(link->irq.AssignedIRQ,
 				link->io.BasePort1,
 				did ? did->driver_info : ATMEL_FW_TYPE_NONE,
-				&handle_to_dev(link),
+				&link->dev,
 				card_present,
 				link);
 	if (!((local_info_t*)link->priv)->eth_dev)
-			goto cs_failed;
+			goto failed;
 
 
 	/*
@@ -340,8 +325,6 @@ static int atmel_config(struct pcmcia_de
 
 	return 0;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
  failed:
 	atmel_release(link);
 	return -ENODEV;
@@ -359,7 +342,7 @@ static void atmel_release(struct pcmcia_
 {
 	struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
 
-	DEBUG(0, "atmel_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "atmel_release\n");
 
 	if (dev)
 		stop_atmel_card(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/b43.h linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/b43.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/b43.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/b43.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,8 +26,6 @@
 # define B43_DEBUG	0
 #endif
 
-#define B43_RX_MAX_SSI			60
-
 /* MMIO offsets */
 #define B43_MMIO_DMA0_REASON		0x20
 #define B43_MMIO_DMA0_IRQ_MASK		0x24
@@ -117,6 +115,7 @@
 #define B43_MMIO_TSF_2			0x636	/* core rev < 3 only */
 #define B43_MMIO_TSF_3			0x638	/* core rev < 3 only */
 #define B43_MMIO_RNG			0x65A
+#define B43_MMIO_IFSSLOT		0x684	/* Interframe slot time */
 #define B43_MMIO_IFSCTL			0x688 /* Interframe space control */
 #define  B43_MMIO_IFSCTL_USE_EDCF	0x0004
 #define B43_MMIO_POWERUP_DELAY		0x6A8
@@ -749,12 +748,6 @@ struct b43_wldev {
 #endif
 };
 
-/*
- * Include goes here to avoid a dependency problem.
- * A better fix would be to integrate xmit.h into b43.h.
- */
-#include "xmit.h"
-
 /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
 struct b43_wl {
 	/* Pointer to the active wireless device on this chip */
@@ -830,13 +823,9 @@ struct b43_wl {
 	struct b43_leds leds;
 
 #ifdef CONFIG_B43_PIO
-	/*
-	 * RX/TX header/tail buffers used by the frame transmit functions.
-	 */
-	struct b43_rxhdr_fw4 rxhdr;
-	struct b43_txhdr txhdr;
-	u8 rx_tail[4];
-	u8 tx_tail[4];
+	/* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
+	u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
+	u8 pio_tailspace[4] __attribute__((__aligned__(8)));
 #endif /* CONFIG_B43_PIO */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/dma.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -770,7 +770,7 @@ static void free_all_descbuffers(struct
 	for (i = 0; i < ring->nr_slots; i++) {
 		desc = ring->ops->idx2desc(ring, i, &meta);
 
-		if (!meta->skb) {
+		if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) {
 			B43_WARN_ON(!ring->tx);
 			continue;
 		}
@@ -822,7 +822,7 @@ struct b43_dmaring *b43_setup_dmaring(st
 				      enum b43_dmatype type)
 {
 	struct b43_dmaring *ring;
-	int err;
+	int i, err;
 	dma_addr_t dma_test;
 
 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
@@ -837,6 +837,8 @@ struct b43_dmaring *b43_setup_dmaring(st
 			     GFP_KERNEL);
 	if (!ring->meta)
 		goto err_kfree_ring;
+	for (i = 0; i < ring->nr_slots; i++)
+		ring->meta->skb = B43_DMA_PTR_POISON;
 
 	ring->type = type;
 	ring->dev = dev;
@@ -1147,28 +1149,29 @@ struct b43_dmaring *parse_cookie(struct
 	case 0x5000:
 		ring = dma->tx_ring_mcast;
 		break;
-	default:
-		B43_WARN_ON(1);
 	}
 	*slot = (cookie & 0x0FFF);
-	B43_WARN_ON(!(ring && *slot >= 0 && *slot < ring->nr_slots));
+	if (unlikely(!ring || *slot < 0 || *slot >= ring->nr_slots)) {
+		b43dbg(dev->wl, "TX-status contains "
+		       "invalid cookie: 0x%04X\n", cookie);
+		return NULL;
+	}
 
 	return ring;
 }
 
 static int dma_tx_fragment(struct b43_dmaring *ring,
-			   struct sk_buff **in_skb)
+			   struct sk_buff *skb)
 {
-	struct sk_buff *skb = *in_skb;
 	const struct b43_dma_ops *ops = ring->ops;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct b43_private_tx_info *priv_info = b43_get_priv_tx_info(info);
 	u8 *header;
 	int slot, old_top_slot, old_used_slots;
 	int err;
 	struct b43_dmadesc_generic *desc;
 	struct b43_dmadesc_meta *meta;
 	struct b43_dmadesc_meta *meta_hdr;
-	struct sk_buff *bounce_skb;
 	u16 cookie;
 	size_t hdrsize = b43_txhdr_size(ring->dev);
 
@@ -1212,34 +1215,28 @@ static int dma_tx_fragment(struct b43_dm
 
 	meta->skb = skb;
 	meta->is_last_fragment = 1;
+	priv_info->bouncebuffer = NULL;
 
 	meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
 	/* create a bounce buffer in zone_dma on mapping failure. */
 	if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
-		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
-		if (!bounce_skb) {
+		priv_info->bouncebuffer = kmalloc(skb->len, GFP_ATOMIC | GFP_DMA);
+		if (!priv_info->bouncebuffer) {
 			ring->current_slot = old_top_slot;
 			ring->used_slots = old_used_slots;
 			err = -ENOMEM;
 			goto out_unmap_hdr;
 		}
+		memcpy(priv_info->bouncebuffer, skb->data, skb->len);
 
-		memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
-		memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb));
-		bounce_skb->dev = skb->dev;
-		skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb));
-		info = IEEE80211_SKB_CB(bounce_skb);
-
-		dev_kfree_skb_any(skb);
-		skb = bounce_skb;
-		*in_skb = bounce_skb;
-		meta->skb = skb;
-		meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+		meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1);
 		if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
+			kfree(priv_info->bouncebuffer);
+			priv_info->bouncebuffer = NULL;
 			ring->current_slot = old_top_slot;
 			ring->used_slots = old_used_slots;
 			err = -EIO;
-			goto out_free_bounce;
+			goto out_unmap_hdr;
 		}
 	}
 
@@ -1256,8 +1253,6 @@ static int dma_tx_fragment(struct b43_dm
 	ops->poke_tx(ring, next_slot(ring, slot));
 	return 0;
 
-out_free_bounce:
-	dev_kfree_skb_any(skb);
 out_unmap_hdr:
 	unmap_descbuffer(ring, meta_hdr->dmaaddr,
 			 hdrsize, 1);
@@ -1362,11 +1357,7 @@ int b43_dma_tx(struct b43_wldev *dev, st
 	 * static, so we don't need to store it per frame. */
 	ring->queue_prio = skb_get_queue_mapping(skb);
 
-	/* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
-	 * into the skb data or cb now. */
-	hdr = NULL;
-	info = NULL;
-	err = dma_tx_fragment(ring, &skb);
+	err = dma_tx_fragment(ring, skb);
 	if (unlikely(err == -ENOKEY)) {
 		/* Drop this packet, as we don't have the encryption key
 		 * anymore and must not transmit it unencrypted. */
@@ -1400,30 +1391,63 @@ void b43_dma_handle_txstatus(struct b43_
 	struct b43_dmaring *ring;
 	struct b43_dmadesc_generic *desc;
 	struct b43_dmadesc_meta *meta;
-	int slot;
+	int slot, firstused;
 	bool frame_succeed;
 
 	ring = parse_cookie(dev, status->cookie, &slot);
 	if (unlikely(!ring))
 		return;
-
 	B43_WARN_ON(!ring->tx);
+
+	/* Sanity check: TX packets are processed in-order on one ring.
+	 * Check if the slot deduced from the cookie really is the first
+	 * used slot. */
+	firstused = ring->current_slot - ring->used_slots + 1;
+	if (firstused < 0)
+		firstused = ring->nr_slots + firstused;
+	if (unlikely(slot != firstused)) {
+		/* This possibly is a firmware bug and will result in
+		 * malfunction, memory leaks and/or stall of DMA functionality. */
+		b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
+		       "Expected %d, but got %d\n",
+		       ring->index, firstused, slot);
+		return;
+	}
+
 	ops = ring->ops;
 	while (1) {
-		B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
+		B43_WARN_ON(slot < 0 || slot >= ring->nr_slots);
 		desc = ops->idx2desc(ring, slot, &meta);
 
-		if (meta->skb)
-			unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len,
-					 1);
-		else
+		if (b43_dma_ptr_is_poisoned(meta->skb)) {
+			b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) "
+			       "on ring %d\n",
+			       slot, firstused, ring->index);
+			break;
+		}
+		if (meta->skb) {
+			struct b43_private_tx_info *priv_info =
+				b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
+
+			unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
+			kfree(priv_info->bouncebuffer);
+			priv_info->bouncebuffer = NULL;
+		} else {
 			unmap_descbuffer(ring, meta->dmaaddr,
 					 b43_txhdr_size(dev), 1);
+		}
 
 		if (meta->is_last_fragment) {
 			struct ieee80211_tx_info *info;
 
-			BUG_ON(!meta->skb);
+			if (unlikely(!meta->skb)) {
+				/* This is a scatter-gather fragment of a frame, so
+				 * the skb pointer must not be NULL. */
+				b43dbg(dev->wl, "TX status unexpected NULL skb "
+				       "at slot %d (first=%d) on ring %d\n",
+				       slot, firstused, ring->index);
+				break;
+			}
 
 			info = IEEE80211_SKB_CB(meta->skb);
 
@@ -1441,20 +1465,29 @@ void b43_dma_handle_txstatus(struct b43_
 #endif /* DEBUG */
 			ieee80211_tx_status(dev->wl->hw, meta->skb);
 
-			/* skb is freed by ieee80211_tx_status() */
-			meta->skb = NULL;
+			/* skb will be freed by ieee80211_tx_status().
+			 * Poison our pointer. */
+			meta->skb = B43_DMA_PTR_POISON;
 		} else {
 			/* No need to call free_descriptor_buffer here, as
 			 * this is only the txhdr, which is not allocated.
 			 */
-			B43_WARN_ON(meta->skb);
+			if (unlikely(meta->skb)) {
+				b43dbg(dev->wl, "TX status unexpected non-NULL skb "
+				       "at slot %d (first=%d) on ring %d\n",
+				       slot, firstused, ring->index);
+				break;
+			}
 		}
 
 		/* Everything unmapped and free'd. So it's not used anymore. */
 		ring->used_slots--;
 
-		if (meta->is_last_fragment)
+		if (meta->is_last_fragment) {
+			/* This is the last scatter-gather
+			 * fragment of the frame. We are done. */
 			break;
+		}
 		slot = next_slot(ring, slot);
 	}
 	if (ring->stopped) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/dma.h linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/dma.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/dma.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 #ifndef B43_DMA_H_
 #define B43_DMA_H_
 
-#include <linux/ieee80211.h>
+#include <linux/err.h>
 
 #include "b43.h"
 
@@ -165,6 +165,10 @@ struct b43_dmadesc_generic {
 #define B43_RXRING_SLOTS		64
 #define B43_DMA0_RX_BUFFERSIZE		IEEE80211_MAX_FRAME_LEN
 
+/* Pointer poison */
+#define B43_DMA_PTR_POISON		((void *)ERR_PTR(-ENOMEM))
+#define b43_dma_ptr_is_poisoned(ptr)	(unlikely((ptr) == B43_DMA_PTR_POISON))
+
 
 struct sk_buff;
 struct b43_private;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config B43
 	tristate "Broadcom 43xx wireless support (mac80211 stack)"
-	depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
+	depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
 	select SSB
 	select FW_LOADER
 	---help---
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/leds.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/leds.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -246,6 +246,7 @@ static void b43_led_get_sprominfo(struct
 			*behaviour = B43_LED_OFF;
 			break;
 		default:
+			*behaviour = B43_LED_OFF;
 			B43_WARN_ON(1);
 			return;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 14:01:56.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 12:09:17.000000000 -0400
@@ -628,10 +628,17 @@ static void b43_upload_card_macaddress(s
 static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
 {
 	/* slot_time is in usec. */
-	if (dev->phy.type != B43_PHYTYPE_G)
+	/* This test used to exit for all but a G PHY. */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
 		return;
-	b43_write16(dev, 0x684, 510 + slot_time);
-	b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+	b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
+	/* Shared memory location 0x0010 is the slot time and should be
+	 * set to slot_time; however, this register is initially 0 and changing
+	 * the value adversely affects the transmit rate for BCM4311
+	 * devices. Until this behavior is unterstood, delete this step
+	 *
+	 * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+	 */
 }
 
 static void b43_short_slot_timing_enable(struct b43_wldev *dev)
@@ -1784,7 +1791,10 @@ static void b43_do_interrupt_thread(stru
 			       dma_reason[0], dma_reason[1],
 			       dma_reason[2], dma_reason[3],
 			       dma_reason[4], dma_reason[5]);
-			b43_controller_restart(dev, "DMA error");
+			b43err(dev->wl, "This device does not support DMA "
+			       "on your system. Please use PIO instead.\n");
+			b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in "
+			       "your kernel configuration.\n");
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -2957,7 +2967,7 @@ static void do_periodic_work(struct b43_
 /* Periodic work locking policy:
  * 	The whole periodic work handler is protected by
  * 	wl->mutex. If another lock is needed somewhere in the
- * 	pwork callchain, it's aquired in-place, where it's needed.
+ * 	pwork callchain, it's acquired in-place, where it's needed.
  */
 static void b43_periodic_work_handler(struct work_struct *work)
 {
@@ -3575,7 +3585,7 @@ static int b43_op_config(struct ieee8021
 	if (conf->channel->hw_value != phy->channel)
 		b43_switch_channel(dev, conf->channel->hw_value);
 
-	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
 
 	/* Adjust the desired TX power level. */
 	if (conf->power_level != 0) {
@@ -4671,7 +4681,7 @@ static int b43_wireless_core_attach(stru
 {
 	struct b43_wl *wl = dev->wl;
 	struct ssb_bus *bus = dev->dev->bus;
-	struct pci_dev *pdev = bus->host_pci;
+	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
 	int err;
 	bool have_2ghz_phy = 0, have_5ghz_phy = 0;
 	u32 tmp;
@@ -4804,7 +4814,7 @@ static int b43_one_core_attach(struct ss
 
 	if (!list_empty(&wl->devlist)) {
 		/* We are not the first core on this chip. */
-		pdev = dev->bus->host_pci;
+		pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
 		/* Only special chips support more than one wireless
 		 * core, although some of the other chips have more than
 		 * one wireless core as well. Check for this and
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/pcmcia.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pcmcia.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/pcmcia.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pcmcia.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(st
 	struct ssb_bus *ssb;
 	win_req_t win;
 	memreq_t mem;
-	tuple_t tuple;
-	cisparse_t parse;
 	int err = -ENOMEM;
 	int res = 0;
-	unsigned char buf[64];
 
 	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
 	if (!ssb)
 		goto out_error;
 
 	err = -ENODEV;
-	tuple.DesiredTuple = CISTPL_CONFIG;
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
-	res = pcmcia_get_first_tuple(dev, &tuple);
-	if (res != 0)
-		goto err_kfree_ssb;
-	res = pcmcia_get_tuple_data(dev, &tuple);
-	if (res != 0)
-		goto err_kfree_ssb;
-	res = pcmcia_parse_tuple(&tuple, &parse);
-	if (res != 0)
-		goto err_kfree_ssb;
 
-	dev->conf.ConfigBase = parse.config.base;
-	dev->conf.Present = parse.config.rmask[0];
 	dev->conf.Attributes = CONF_ENABLE_IRQ;
 	dev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -107,20 +87,18 @@ static int __devinit b43_pcmcia_probe(st
 	win.Base = 0;
 	win.Size = SSB_CORE_SIZE;
 	win.AccessSpeed = 250;
-	res = pcmcia_request_window(&dev, &win, &dev->win);
+	res = pcmcia_request_window(dev, &win, &dev->win);
 	if (res != 0)
 		goto err_kfree_ssb;
 
 	mem.CardOffset = 0;
 	mem.Page = 0;
-	res = pcmcia_map_mem_page(dev->win, &mem);
+	res = pcmcia_map_mem_page(dev, dev->win, &mem);
 	if (res != 0)
 		goto err_disable;
 
 	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-	dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	dev->irq.Handler = NULL; /* The handler is registered later. */
-	dev->irq.Instance = NULL;
 	res = pcmcia_request_irq(dev, &dev->irq);
 	if (res != 0)
 		goto err_disable;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/phy_lp.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/phy_lp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,6 +67,7 @@ static void b43_lpphy_op_prepare_structs
 	struct b43_phy_lp *lpphy = phy->lp;
 
 	memset(lpphy, 0, sizeof(*lpphy));
+	lpphy->antenna = B43_ANTENNA_DEFAULT;
 
 	//TODO
 }
@@ -751,11 +752,17 @@ static void lpphy_clear_deaf(struct b43_
 	}
 }
 
+static void lpphy_set_trsw_over(struct b43_wldev *dev, bool tx, bool rx)
+{
+	u16 trsw = (tx << 1) | rx;
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, trsw);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
+}
+
 static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
 {
 	lpphy_set_deaf(dev, user);
-	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1);
-	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
+	lpphy_set_trsw_over(dev, false, true);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7);
@@ -790,6 +797,60 @@ static void lpphy_restore_crs(struct b43
 
 struct lpphy_tx_gains { u16 gm, pga, pad, dac; };
 
+static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
+{
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
+	if (dev->phy.rev >= 2) {
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
+			b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
+		}
+	} else {
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
+	}
+}
+
+static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
+{
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
+	if (dev->phy.rev >= 2) {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
+			b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
+		}
+	} else {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
+	}
+}
+
+static void lpphy_disable_tx_gain_override(struct b43_wldev *dev)
+{
+	if (dev->phy.rev < 2)
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
+	else {
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F);
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF);
+	}
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF);
+}
+
+static void lpphy_enable_tx_gain_override(struct b43_wldev *dev)
+{
+	if (dev->phy.rev < 2)
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
+	else {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x80);
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x4000);
+	}
+	b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x40);
+}
+
 static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev)
 {
 	struct lpphy_tx_gains gains;
@@ -819,6 +880,17 @@ static void lpphy_set_dac_gain(struct b4
 	b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl);
 }
 
+static u16 lpphy_get_pa_gain(struct b43_wldev *dev)
+{
+	return b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F;
+}
+
+static void lpphy_set_pa_gain(struct b43_wldev *dev, u16 gain)
+{
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 0xE03F, gain << 6);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 0x80FF, gain << 8);
+}
+
 static void lpphy_set_tx_gains(struct b43_wldev *dev,
 			       struct lpphy_tx_gains gains)
 {
@@ -829,25 +901,22 @@ static void lpphy_set_tx_gains(struct b4
 		b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
 				0xF800, rf_gain);
 	} else {
-		pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0;
-		pa_gain <<= 2;
+		pa_gain = lpphy_get_pa_gain(dev);
 		b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
 			      (gains.pga << 8) | gains.gm);
+		/*
+		 * SPEC FIXME The spec calls for (pa_gain << 8) here, but that
+		 * conflicts with the spec for set_pa_gain! Vendor driver bug?
+		 */
 		b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
-				0x8000, gains.pad | pa_gain);
+				0x8000, gains.pad | (pa_gain << 6));
 		b43_phy_write(dev, B43_PHY_OFDM(0xFC),
 			      (gains.pga << 8) | gains.gm);
 		b43_phy_maskset(dev, B43_PHY_OFDM(0xFD),
-				0x8000, gains.pad | pa_gain);
+				0x8000, gains.pad | (pa_gain << 8));
 	}
 	lpphy_set_dac_gain(dev, gains.dac);
-	if (dev->phy.rev < 2) {
-		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF, 1 << 8);
-	} else {
-		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
-		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
-	}
-	b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
+	lpphy_enable_tx_gain_override(dev);
 }
 
 static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
@@ -887,38 +956,6 @@ static void lpphy_rev2plus_set_rx_gain(s
 	}
 }
 
-static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
-{
-	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
-	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
-	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
-	if (dev->phy.rev >= 2) {
-		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
-		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
-			b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
-		}
-	} else {
-		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
-	}
-}
-
-static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
-{
-	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
-	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
-	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
-	if (dev->phy.rev >= 2) {
-		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
-		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
-			b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
-		}
-	} else {
-		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
-	}
-}
-
 static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain)
 {
 	if (dev->phy.rev < 2)
@@ -1003,8 +1040,7 @@ static int lpphy_loopback(struct b43_wld
 
 	memset(&iq_est, 0, sizeof(iq_est));
 
-	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x3);
-	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
+	lpphy_set_trsw_over(dev, true, true);
 	b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1);
 	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE);
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800);
@@ -1126,7 +1162,7 @@ static void lpphy_set_tx_power_control(s
 			b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
 					0x8FFF, ((u16)lpphy->tssi_npt << 16));
 			//TODO Set "TSSI Transmit Count" variable to total transmitted frame count
-			//TODO Disable TX gain override
+			lpphy_disable_tx_gain_override(dev);
 			lpphy->tx_pwr_idx_over = -1;
 		}
 	}
@@ -1312,15 +1348,73 @@ static void lpphy_calibrate_rc(struct b4
 	}
 }
 
+static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
+{
+	if (dev->phy.rev >= 2)
+		return; // rev2+ doesn't support antenna diversity
+
+	if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1))
+		return;
+
+	b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
+
+	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2);
+	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1);
+
+	b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
+
+	dev->phy.lp->antenna = antenna;
+}
+
+static void lpphy_set_tx_iqcc(struct b43_wldev *dev, u16 a, u16 b)
+{
+	u16 tmp[2];
+
+	tmp[0] = a;
+	tmp[1] = b;
+	b43_lptab_write_bulk(dev, B43_LPTAB16(0, 80), 2, tmp);
+}
+
 static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct lpphy_tx_gains gains;
+	u32 iq_comp, tx_gain, coeff, rf_power;
 
 	lpphy->tx_pwr_idx_over = index;
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
 	if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
 		lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
-
-	//TODO
+	if (dev->phy.rev >= 2) {
+		iq_comp = b43_lptab_read(dev, B43_LPTAB32(7, index + 320));
+		tx_gain = b43_lptab_read(dev, B43_LPTAB32(7, index + 192));
+		gains.pad = (tx_gain >> 16) & 0xFF;
+		gains.gm = tx_gain & 0xFF;
+		gains.pga = (tx_gain >> 8) & 0xFF;
+		gains.dac = (iq_comp >> 28) & 0xFF;
+		lpphy_set_tx_gains(dev, gains);
+	} else {
+		iq_comp = b43_lptab_read(dev, B43_LPTAB32(10, index + 320));
+		tx_gain = b43_lptab_read(dev, B43_LPTAB32(10, index + 192));
+		b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
+				0xF800, (tx_gain >> 4) & 0x7FFF);
+		lpphy_set_dac_gain(dev, tx_gain & 0x7);
+		lpphy_set_pa_gain(dev, (tx_gain >> 24) & 0x7F);
+	}
+	lpphy_set_bb_mult(dev, (iq_comp >> 20) & 0xFF);
+	lpphy_set_tx_iqcc(dev, (iq_comp >> 10) & 0x3FF, iq_comp & 0x3FF);
+	if (dev->phy.rev >= 2) {
+		coeff = b43_lptab_read(dev, B43_LPTAB32(7, index + 448));
+	} else {
+		coeff = b43_lptab_read(dev, B43_LPTAB32(10, index + 448));
+	}
+	b43_lptab_write(dev, B43_LPTAB16(0, 85), coeff & 0xFFFF);
+	if (dev->phy.rev >= 2) {
+		rf_power = b43_lptab_read(dev, B43_LPTAB32(7, index + 576));
+		b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00,
+				rf_power & 0xFFFF);//SPEC FIXME mask & set != 0
+	}
+	lpphy_enable_tx_gain_override(dev);
 }
 
 static void lpphy_btcoex_override(struct b43_wldev *dev)
@@ -1329,58 +1423,45 @@ static void lpphy_btcoex_override(struct
 	b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
 }
 
-static void lpphy_pr41573_workaround(struct b43_wldev *dev)
+static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
+					 bool blocked)
 {
-	struct b43_phy_lp *lpphy = dev->phy.lp;
-	u32 *saved_tab;
-	const unsigned int saved_tab_size = 256;
-	enum b43_lpphy_txpctl_mode txpctl_mode;
-	s8 tx_pwr_idx_over;
-	u16 tssi_npt, tssi_idx;
-
-	saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
-	if (!saved_tab) {
-		b43err(dev->wl, "PR41573 failed. Out of memory!\n");
-		return;
-	}
-
-	lpphy_read_tx_pctl_mode_from_hardware(dev);
-	txpctl_mode = lpphy->txpctl_mode;
-	tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
-	tssi_npt = lpphy->tssi_npt;
-	tssi_idx = lpphy->tssi_idx;
-
-	if (dev->phy.rev < 2) {
-		b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
-				    saved_tab_size, saved_tab);
+	//TODO check MAC control register
+	if (blocked) {
+		if (dev->phy.rev >= 2) {
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x83FF);
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00);
+			b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0x80FF);
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xDFFF);
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0808);
+		} else {
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xE0FF);
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00);
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFCFF);
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0018);
+		}
 	} else {
-		b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
-				    saved_tab_size, saved_tab);
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xE0FF);
+		if (dev->phy.rev >= 2)
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xF7F7);
+		else
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFE7);
 	}
-	//TODO
-
-	kfree(saved_tab);
 }
 
-static void lpphy_calibration(struct b43_wldev *dev)
+/* This was previously called lpphy_japan_filter */
+static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	enum b43_lpphy_txpctl_mode saved_pctl_mode;
-
-	b43_mac_suspend(dev);
-
-	lpphy_btcoex_override(dev);
-	lpphy_read_tx_pctl_mode_from_hardware(dev);
-	saved_pctl_mode = lpphy->txpctl_mode;
-	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
-	//TODO Perform transmit power table I/Q LO calibration
-	if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
-		lpphy_pr41573_workaround(dev);
-	//TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
-	lpphy_set_tx_power_control(dev, saved_pctl_mode);
-	//TODO Perform I/Q calibration with a single control value set
+	u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
 
-	b43_mac_enable(dev);
+	if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
+		b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
+		if ((dev->phy.rev == 1) && (lpphy->rc_cap))
+			lpphy_set_rc_cap(dev);
+	} else {
+		b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
+	}
 }
 
 static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode)
@@ -1489,6 +1570,473 @@ static void lpphy_tx_pctl_init(struct b4
 	}
 }
 
+static void lpphy_pr41573_workaround(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u32 *saved_tab;
+	const unsigned int saved_tab_size = 256;
+	enum b43_lpphy_txpctl_mode txpctl_mode;
+	s8 tx_pwr_idx_over;
+	u16 tssi_npt, tssi_idx;
+
+	saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
+	if (!saved_tab) {
+		b43err(dev->wl, "PR41573 failed. Out of memory!\n");
+		return;
+	}
+
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
+	txpctl_mode = lpphy->txpctl_mode;
+	tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
+	tssi_npt = lpphy->tssi_npt;
+	tssi_idx = lpphy->tssi_idx;
+
+	if (dev->phy.rev < 2) {
+		b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
+				    saved_tab_size, saved_tab);
+	} else {
+		b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
+				    saved_tab_size, saved_tab);
+	}
+	//FIXME PHY reset
+	lpphy_table_init(dev); //FIXME is table init needed?
+	lpphy_baseband_init(dev);
+	lpphy_tx_pctl_init(dev);
+	b43_lpphy_op_software_rfkill(dev, false);
+	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+	if (dev->phy.rev < 2) {
+		b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0x140),
+				     saved_tab_size, saved_tab);
+	} else {
+		b43_lptab_write_bulk(dev, B43_LPTAB32(7, 0x140),
+				     saved_tab_size, saved_tab);
+	}
+	b43_write16(dev, B43_MMIO_CHANNEL, lpphy->channel);
+	lpphy->tssi_npt = tssi_npt;
+	lpphy->tssi_idx = tssi_idx;
+	lpphy_set_analog_filter(dev, lpphy->channel);
+	if (tx_pwr_idx_over != -1)
+		lpphy_set_tx_power_by_index(dev, tx_pwr_idx_over);
+	if (lpphy->rc_cap)
+		lpphy_set_rc_cap(dev);
+	b43_lpphy_op_set_rx_antenna(dev, lpphy->antenna);
+	lpphy_set_tx_power_control(dev, txpctl_mode);
+	kfree(saved_tab);
+}
+
+struct lpphy_rx_iq_comp { u8 chan; s8 c1, c0; };
+
+static const struct lpphy_rx_iq_comp lpphy_5354_iq_table[] = {
+	{ .chan = 1, .c1 = -66, .c0 = 15, },
+	{ .chan = 2, .c1 = -66, .c0 = 15, },
+	{ .chan = 3, .c1 = -66, .c0 = 15, },
+	{ .chan = 4, .c1 = -66, .c0 = 15, },
+	{ .chan = 5, .c1 = -66, .c0 = 15, },
+	{ .chan = 6, .c1 = -66, .c0 = 15, },
+	{ .chan = 7, .c1 = -66, .c0 = 14, },
+	{ .chan = 8, .c1 = -66, .c0 = 14, },
+	{ .chan = 9, .c1 = -66, .c0 = 14, },
+	{ .chan = 10, .c1 = -66, .c0 = 14, },
+	{ .chan = 11, .c1 = -66, .c0 = 14, },
+	{ .chan = 12, .c1 = -66, .c0 = 13, },
+	{ .chan = 13, .c1 = -66, .c0 = 13, },
+	{ .chan = 14, .c1 = -66, .c0 = 13, },
+};
+
+static const struct lpphy_rx_iq_comp lpphy_rev0_1_iq_table[] = {
+	{ .chan = 1, .c1 = -64, .c0 = 13, },
+	{ .chan = 2, .c1 = -64, .c0 = 13, },
+	{ .chan = 3, .c1 = -64, .c0 = 13, },
+	{ .chan = 4, .c1 = -64, .c0 = 13, },
+	{ .chan = 5, .c1 = -64, .c0 = 12, },
+	{ .chan = 6, .c1 = -64, .c0 = 12, },
+	{ .chan = 7, .c1 = -64, .c0 = 12, },
+	{ .chan = 8, .c1 = -64, .c0 = 12, },
+	{ .chan = 9, .c1 = -64, .c0 = 12, },
+	{ .chan = 10, .c1 = -64, .c0 = 11, },
+	{ .chan = 11, .c1 = -64, .c0 = 11, },
+	{ .chan = 12, .c1 = -64, .c0 = 11, },
+	{ .chan = 13, .c1 = -64, .c0 = 11, },
+	{ .chan = 14, .c1 = -64, .c0 = 10, },
+	{ .chan = 34, .c1 = -62, .c0 = 24, },
+	{ .chan = 38, .c1 = -62, .c0 = 24, },
+	{ .chan = 42, .c1 = -62, .c0 = 24, },
+	{ .chan = 46, .c1 = -62, .c0 = 23, },
+	{ .chan = 36, .c1 = -62, .c0 = 24, },
+	{ .chan = 40, .c1 = -62, .c0 = 24, },
+	{ .chan = 44, .c1 = -62, .c0 = 23, },
+	{ .chan = 48, .c1 = -62, .c0 = 23, },
+	{ .chan = 52, .c1 = -62, .c0 = 23, },
+	{ .chan = 56, .c1 = -62, .c0 = 22, },
+	{ .chan = 60, .c1 = -62, .c0 = 22, },
+	{ .chan = 64, .c1 = -62, .c0 = 22, },
+	{ .chan = 100, .c1 = -62, .c0 = 16, },
+	{ .chan = 104, .c1 = -62, .c0 = 16, },
+	{ .chan = 108, .c1 = -62, .c0 = 15, },
+	{ .chan = 112, .c1 = -62, .c0 = 14, },
+	{ .chan = 116, .c1 = -62, .c0 = 14, },
+	{ .chan = 120, .c1 = -62, .c0 = 13, },
+	{ .chan = 124, .c1 = -62, .c0 = 12, },
+	{ .chan = 128, .c1 = -62, .c0 = 12, },
+	{ .chan = 132, .c1 = -62, .c0 = 12, },
+	{ .chan = 136, .c1 = -62, .c0 = 11, },
+	{ .chan = 140, .c1 = -62, .c0 = 10, },
+	{ .chan = 149, .c1 = -61, .c0 = 9, },
+	{ .chan = 153, .c1 = -61, .c0 = 9, },
+	{ .chan = 157, .c1 = -61, .c0 = 9, },
+	{ .chan = 161, .c1 = -61, .c0 = 8, },
+	{ .chan = 165, .c1 = -61, .c0 = 8, },
+	{ .chan = 184, .c1 = -62, .c0 = 25, },
+	{ .chan = 188, .c1 = -62, .c0 = 25, },
+	{ .chan = 192, .c1 = -62, .c0 = 25, },
+	{ .chan = 196, .c1 = -62, .c0 = 25, },
+	{ .chan = 200, .c1 = -62, .c0 = 25, },
+	{ .chan = 204, .c1 = -62, .c0 = 25, },
+	{ .chan = 208, .c1 = -62, .c0 = 25, },
+	{ .chan = 212, .c1 = -62, .c0 = 25, },
+	{ .chan = 216, .c1 = -62, .c0 = 26, },
+};
+
+static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = {
+	.chan = 0,
+	.c1 = -64,
+	.c0 = 0,
+};
+
+static u8 lpphy_nbits(s32 val)
+{
+	u32 tmp = abs(val);
+	u8 nbits = 0;
+
+	while (tmp != 0) {
+		nbits++;
+		tmp >>= 1;
+	}
+
+	return nbits;
+}
+
+static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
+{
+	struct lpphy_iq_est iq_est;
+	u16 c0, c1;
+	int prod, ipwr, qpwr, prod_msb, q_msb, tmp1, tmp2, tmp3, tmp4, ret;
+
+	c1 = b43_phy_read(dev, B43_LPPHY_RX_COMP_COEFF_S);
+	c0 = c1 >> 8;
+	c1 |= 0xFF;
+
+	b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, 0x00C0);
+	b43_phy_mask(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF);
+
+	ret = lpphy_rx_iq_est(dev, samples, 32, &iq_est);
+	if (!ret)
+		goto out;
+
+	prod = iq_est.iq_prod;
+	ipwr = iq_est.i_pwr;
+	qpwr = iq_est.q_pwr;
+
+	if (ipwr + qpwr < 2) {
+		ret = 0;
+		goto out;
+	}
+
+	prod_msb = lpphy_nbits(prod);
+	q_msb = lpphy_nbits(qpwr);
+	tmp1 = prod_msb - 20;
+
+	if (tmp1 >= 0) {
+		tmp3 = ((prod << (30 - prod_msb)) + (ipwr >> (1 + tmp1))) /
+			(ipwr >> tmp1);
+	} else {
+		tmp3 = ((prod << (30 - prod_msb)) + (ipwr << (-1 - tmp1))) /
+			(ipwr << -tmp1);
+	}
+
+	tmp2 = q_msb - 11;
+
+	if (tmp2 >= 0)
+		tmp4 = (qpwr << (31 - q_msb)) / (ipwr >> tmp2);
+	else
+		tmp4 = (qpwr << (31 - q_msb)) / (ipwr << -tmp2);
+
+	tmp4 -= tmp3 * tmp3;
+	tmp4 = -int_sqrt(tmp4);
+
+	c0 = tmp3 >> 3;
+	c1 = tmp4 >> 4;
+
+out:
+	b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, c1);
+	b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF, c0 << 8);
+	return ret;
+}
+
+/* Complex number using 2 32-bit signed integers */
+typedef struct {s32 i, q;} lpphy_c32;
+
+static lpphy_c32 lpphy_cordic(int theta)
+{
+	u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
+		      58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
+		      229, 115, 57, 29, };
+	int i, tmp, signx = 1, angle = 0;
+	lpphy_c32 ret = { .i = 39797, .q = 0, };
+
+	theta = clamp_t(int, theta, -180, 180);
+
+	if (theta > 90) {
+		theta -= 180;
+		signx = -1;
+	} else if (theta < -90) {
+		theta += 180;
+		signx = -1;
+	}
+
+	for (i = 0; i <= 17; i++) {
+		if (theta > angle) {
+			tmp = ret.i - (ret.q >> i);
+			ret.q += ret.i >> i;
+			ret.i = tmp;
+			angle += arctg[i];
+		} else {
+			tmp = ret.i + (ret.q >> i);
+			ret.q -= ret.i >> i;
+			ret.i = tmp;
+			angle -= arctg[i];
+		}
+	}
+
+	ret.i *= signx;
+	ret.q *= signx;
+
+	return ret;
+}
+
+static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
+			      u16 wait)
+{
+	b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL,
+			0xFFC0, samples - 1);
+	if (loops != 0xFFFF)
+		loops--;
+	b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000, loops);
+	b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, 0x3F, wait << 6);
+	b43_phy_set(dev, B43_LPPHY_A_PHY_CTL_ADDR, 0x1);
+}
+
+//SPEC FIXME what does a negative freq mean?
+static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 buf[64];
+	int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
+	lpphy_c32 sample;
+
+	lpphy->tx_tone_freq = freq;
+
+	if (freq) {
+		/* Find i for which abs(freq) integrally divides 20000 * i */
+		for (i = 1; samples * abs(freq) != 20000 * i; i++) {
+			samples = (20000 * i) / abs(freq);
+			if(B43_WARN_ON(samples > 63))
+				return;
+		}
+	} else {
+		samples = 2;
+	}
+
+	for (i = 0; i < samples; i++) {
+		sample = lpphy_cordic(angle);
+		angle += rotation;
+		buf[i] = ((sample.i * max) & 0xFF) << 8;
+		buf[i] |= (sample.q * max) & 0xFF;
+	}
+
+	b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
+
+	lpphy_run_samples(dev, samples, 0xFFFF, 0);
+}
+
+static void lpphy_stop_tx_tone(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	int i;
+
+	lpphy->tx_tone_freq = 0;
+
+	b43_phy_mask(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000);
+	for (i = 0; i < 31; i++) {
+		if (!(b43_phy_read(dev, B43_LPPHY_A_PHY_CTL_ADDR) & 0x1))
+			break;
+		udelay(100);
+	}
+}
+
+
+static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
+			   int mode, bool useindex, u8 index)
+{
+	//TODO
+}
+
+static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct ssb_bus *bus = dev->dev->bus;
+	struct lpphy_tx_gains gains, oldgains;
+	int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
+
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
+	old_txpctl = lpphy->txpctl_mode;
+	old_afe_ovr = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40;
+	if (old_afe_ovr)
+		oldgains = lpphy_get_tx_gains(dev);
+	old_rf = b43_phy_read(dev, B43_LPPHY_RF_PWR_OVERRIDE) & 0xFF;
+	old_bbmult = lpphy_get_bb_mult(dev);
+
+	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+
+	if (bus->chip_id == 0x4325 && bus->chip_rev == 0)
+		lpphy_papd_cal(dev, gains, 0, 1, 30);
+	else
+		lpphy_papd_cal(dev, gains, 0, 1, 65);
+
+	if (old_afe_ovr)
+		lpphy_set_tx_gains(dev, oldgains);
+	lpphy_set_bb_mult(dev, old_bbmult);
+	lpphy_set_tx_power_control(dev, old_txpctl);
+	b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, old_rf);
+}
+
+static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
+			    bool rx, bool pa, struct lpphy_tx_gains *gains)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct ssb_bus *bus = dev->dev->bus;
+	const struct lpphy_rx_iq_comp *iqcomp = NULL;
+	struct lpphy_tx_gains nogains, oldgains;
+	u16 tmp;
+	int i, ret;
+
+	memset(&nogains, 0, sizeof(nogains));
+	memset(&oldgains, 0, sizeof(oldgains));
+
+	if (bus->chip_id == 0x5354) {
+		for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) {
+			if (lpphy_5354_iq_table[i].chan == lpphy->channel) {
+				iqcomp = &lpphy_5354_iq_table[i];
+			}
+		}
+	} else if (dev->phy.rev >= 2) {
+		iqcomp = &lpphy_rev2plus_iq_comp;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(lpphy_rev0_1_iq_table); i++) {
+			if (lpphy_rev0_1_iq_table[i].chan == lpphy->channel) {
+				iqcomp = &lpphy_rev0_1_iq_table[i];
+			}
+		}
+	}
+
+	if (B43_WARN_ON(!iqcomp))
+		return 0;
+
+	b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, iqcomp->c1);
+	b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S,
+			0x00FF, iqcomp->c0 << 8);
+
+	if (noise) {
+		tx = true;
+		rx = false;
+		pa = false;
+	}
+
+	lpphy_set_trsw_over(dev, tx, rx);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8);
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0,
+				0xFFF7, pa << 3);
+	} else {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x20);
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0,
+				0xFFDF, pa << 5);
+	}
+
+	tmp = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40;
+
+	if (noise)
+		lpphy_set_rx_gain(dev, 0x2D5D);
+	else {
+		if (tmp)
+			oldgains = lpphy_get_tx_gains(dev);
+		if (!gains)
+			gains = &nogains;
+		lpphy_set_tx_gains(dev, *gains);
+	}
+
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE);
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x800);
+	lpphy_set_deaf(dev, false);
+	if (noise)
+		ret = lpphy_calc_rx_iq_comp(dev, 0xFFF0);
+	else {
+		lpphy_start_tx_tone(dev, 4000, 100);
+		ret = lpphy_calc_rx_iq_comp(dev, 0x4000);
+		lpphy_stop_tx_tone(dev);
+	}
+	lpphy_clear_deaf(dev, false);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFC);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFF7);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFDF);
+	if (!noise) {
+		if (tmp)
+			lpphy_set_tx_gains(dev, oldgains);
+		else
+			lpphy_disable_tx_gain_override(dev);
+	}
+	lpphy_disable_rx_gain_override(dev);
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE);
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xF7FF);
+	return ret;
+}
+
+static void lpphy_calibration(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	enum b43_lpphy_txpctl_mode saved_pctl_mode;
+	bool full_cal = false;
+
+	if (lpphy->full_calib_chan != lpphy->channel) {
+		full_cal = true;
+		lpphy->full_calib_chan = lpphy->channel;
+	}
+
+	b43_mac_suspend(dev);
+
+	lpphy_btcoex_override(dev);
+	if (dev->phy.rev >= 2)
+		lpphy_save_dig_flt_state(dev);
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
+	saved_pctl_mode = lpphy->txpctl_mode;
+	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+	//TODO Perform transmit power table I/Q LO calibration
+	if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
+		lpphy_pr41573_workaround(dev);
+	if ((dev->phy.rev >= 2) && full_cal) {
+		lpphy_papd_cal_txpwr(dev);
+	}
+	lpphy_set_tx_power_control(dev, saved_pctl_mode);
+	if (dev->phy.rev >= 2)
+		lpphy_restore_dig_flt_state(dev);
+	lpphy_rx_iq_cal(dev, true, true, false, false, NULL);
+
+	b43_mac_enable(dev);
+}
+
 static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
 {
 	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
@@ -1533,12 +2081,6 @@ static void b43_lpphy_op_radio_write(str
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
-static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
-					 bool blocked)
-{
-	//TODO
-}
-
 struct b206x_channel {
 	u8 channel;
 	u16 freq;
@@ -2004,22 +2546,6 @@ static int lpphy_b2062_tune(struct b43_w
 	return err;
 }
 
-
-/* This was previously called lpphy_japan_filter */
-static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
-{
-	struct b43_phy_lp *lpphy = dev->phy.lp;
-	u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
-
-	if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
-		b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
-		if ((dev->phy.rev == 1) && (lpphy->rc_cap))
-			lpphy_set_rc_cap(dev);
-	} else {
-		b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
-	}
-}
-
 static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
 {
 	u16 tmp;
@@ -2204,18 +2730,6 @@ static int b43_lpphy_op_init(struct b43_
 	return 0;
 }
 
-static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
-{
-	if (dev->phy.rev >= 2)
-		return; // rev2+ doesn't support antenna diversity
-
-	if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1))
-		return;
-
-	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2);
-	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1);
-}
-
 static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev)
 {
 	//TODO
@@ -2238,6 +2752,11 @@ void b43_lpphy_op_switch_analog(struct b
        }
 }
 
+static void b43_lpphy_op_pwork_15sec(struct b43_wldev *dev)
+{
+	//TODO
+}
+
 const struct b43_phy_operations b43_phyops_lp = {
 	.allocate		= b43_lpphy_op_allocate,
 	.free			= b43_lpphy_op_free,
@@ -2255,4 +2774,6 @@ const struct b43_phy_operations b43_phyo
 	.set_rx_antenna		= b43_lpphy_op_set_rx_antenna,
 	.recalc_txpower		= b43_lpphy_op_recalc_txpower,
 	.adjust_txpower		= b43_lpphy_op_adjust_txpower,
+	.pwork_15sec		= b43_lpphy_op_pwork_15sec,
+	.pwork_60sec		= lpphy_calibration,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/phy_lp.h linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/phy_lp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/phy_lp.h	2010-02-24 13:52:17.000000000 -0500
@@ -286,6 +286,7 @@
 #define B43_LPPHY_TR_LOOKUP_6			B43_PHY_OFDM(0xC8) /* TR Lookup 6 */
 #define B43_LPPHY_TR_LOOKUP_7			B43_PHY_OFDM(0xC9) /* TR Lookup 7 */
 #define B43_LPPHY_TR_LOOKUP_8			B43_PHY_OFDM(0xCA) /* TR Lookup 8 */
+#define B43_LPPHY_RF_PWR_OVERRIDE		B43_PHY_OFDM(0xD3) /* RF power override */
 
 
 
@@ -871,12 +872,12 @@ struct b43_phy_lp {
 	u8 rssi_gs;
 
 	/* RC cap */
-	u8 rc_cap; /* FIXME initial value? */
+	u8 rc_cap;
 	/* BX arch */
 	u8 bx_arch;
 
 	/* Full calibration channel */
-	u8 full_calib_chan; /* FIXME initial value? */
+	u8 full_calib_chan;
 
 	/* Transmit iqlocal best coeffs */
 	bool tx_iqloc_best_coeffs_valid;
@@ -891,6 +892,12 @@ struct b43_phy_lp {
 
 	/* The channel we are tuned to */
 	u8 channel;
+
+	/* The active antenna diversity mode */
+	int antenna;
+
+	/* Frequency of the active TX tone */
+	int tx_tone_freq;
 };
 
 enum tssi_mux_mode {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/pio.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/pio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/pio.c	2010-02-24 13:52:17.000000000 -0500
@@ -342,12 +342,15 @@ static u16 tx_write_2byte_queue(struct b
 			q->mmio_base + B43_PIO_TXDATA,
 			sizeof(u16));
 	if (data_len & 1) {
+		u8 *tail = wl->pio_tailspace;
+		BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
+
 		/* Write the last byte. */
 		ctl &= ~B43_PIO_TXCTL_WRITEHI;
 		b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-		wl->tx_tail[0] = data[data_len - 1];
-		wl->tx_tail[1] = 0;
-		ssb_block_write(dev->dev, wl->tx_tail, 2,
+		tail[0] = data[data_len - 1];
+		tail[1] = 0;
+		ssb_block_write(dev->dev, tail, 2,
 				q->mmio_base + B43_PIO_TXDATA,
 				sizeof(u16));
 	}
@@ -393,31 +396,31 @@ static u32 tx_write_4byte_queue(struct b
 			q->mmio_base + B43_PIO8_TXDATA,
 			sizeof(u32));
 	if (data_len & 3) {
-		wl->tx_tail[3] = 0;
+		u8 *tail = wl->pio_tailspace;
+		BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
+
+		memset(tail, 0, 4);
 		/* Write the last few bytes. */
 		ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
 			 B43_PIO8_TXCTL_24_31);
 		switch (data_len & 3) {
 		case 3:
 			ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
-			wl->tx_tail[0] = data[data_len - 3];
-			wl->tx_tail[1] = data[data_len - 2];
-			wl->tx_tail[2] = data[data_len - 1];
+			tail[0] = data[data_len - 3];
+			tail[1] = data[data_len - 2];
+			tail[2] = data[data_len - 1];
 			break;
 		case 2:
 			ctl |= B43_PIO8_TXCTL_8_15;
-			wl->tx_tail[0] = data[data_len - 2];
-			wl->tx_tail[1] = data[data_len - 1];
-			wl->tx_tail[2] = 0;
+			tail[0] = data[data_len - 2];
+			tail[1] = data[data_len - 1];
 			break;
 		case 1:
-			wl->tx_tail[0] = data[data_len - 1];
-			wl->tx_tail[1] = 0;
-			wl->tx_tail[2] = 0;
+			tail[0] = data[data_len - 1];
 			break;
 		}
 		b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-		ssb_block_write(dev->dev, wl->tx_tail, 4,
+		ssb_block_write(dev->dev, tail, 4,
 				q->mmio_base + B43_PIO8_TXDATA,
 				sizeof(u32));
 	}
@@ -456,6 +459,7 @@ static int pio_tx_frame(struct b43_pio_t
 	int err;
 	unsigned int hdrlen;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace;
 
 	B43_WARN_ON(list_empty(&q->packets_list));
 	pack = list_entry(q->packets_list.next,
@@ -463,7 +467,9 @@ static int pio_tx_frame(struct b43_pio_t
 
 	cookie = generate_cookie(q, pack);
 	hdrlen = b43_txhdr_size(dev);
-	err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
+	BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr));
+	B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen);
+	err = b43_generate_txhdr(dev, (u8 *)txhdr, skb,
 				 info, cookie);
 	if (err)
 		return err;
@@ -477,9 +483,9 @@ static int pio_tx_frame(struct b43_pio_t
 
 	pack->skb = skb;
 	if (q->rev >= 8)
-		pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
+		pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen);
 	else
-		pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
+		pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen);
 
 	/* Remove it from the list of available packet slots.
 	 * It will be put back when we receive the status report. */
@@ -625,8 +631,11 @@ static bool pio_rx_frame(struct b43_pio_
 	unsigned int i, padding;
 	struct sk_buff *skb;
 	const char *err_msg = NULL;
+	struct b43_rxhdr_fw4 *rxhdr =
+		(struct b43_rxhdr_fw4 *)wl->pio_scratchspace;
 
-	memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
+	BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr));
+	memset(rxhdr, 0, sizeof(*rxhdr));
 
 	/* Check if we have data and wait for it to get ready. */
 	if (q->rev >= 8) {
@@ -664,16 +673,16 @@ data_ready:
 
 	/* Get the preamble (RX header) */
 	if (q->rev >= 8) {
-		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
+		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 	} else {
-		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
+		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 	}
 	/* Sanity checks. */
-	len = le16_to_cpu(wl->rxhdr.frame_len);
+	len = le16_to_cpu(rxhdr->frame_len);
 	if (unlikely(len > 0x700)) {
 		err_msg = "len > 0x700";
 		goto rx_error;
@@ -683,7 +692,7 @@ data_ready:
 		goto rx_error;
 	}
 
-	macstat = le32_to_cpu(wl->rxhdr.mac_status);
+	macstat = le32_to_cpu(rxhdr->mac_status);
 	if (macstat & B43_RX_MAC_FCSERR) {
 		if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
 			/* Drop frames with failed FCS. */
@@ -708,22 +717,25 @@ data_ready:
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 		if (len & 3) {
+			u8 *tail = wl->pio_tailspace;
+			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
+
 			/* Read the last few bytes. */
-			ssb_block_read(dev->dev, wl->rx_tail, 4,
+			ssb_block_read(dev->dev, tail, 4,
 				       q->mmio_base + B43_PIO8_RXDATA,
 				       sizeof(u32));
 			switch (len & 3) {
 			case 3:
-				skb->data[len + padding - 3] = wl->rx_tail[0];
-				skb->data[len + padding - 2] = wl->rx_tail[1];
-				skb->data[len + padding - 1] = wl->rx_tail[2];
+				skb->data[len + padding - 3] = tail[0];
+				skb->data[len + padding - 2] = tail[1];
+				skb->data[len + padding - 1] = tail[2];
 				break;
 			case 2:
-				skb->data[len + padding - 2] = wl->rx_tail[0];
-				skb->data[len + padding - 1] = wl->rx_tail[1];
+				skb->data[len + padding - 2] = tail[0];
+				skb->data[len + padding - 1] = tail[1];
 				break;
 			case 1:
-				skb->data[len + padding - 1] = wl->rx_tail[0];
+				skb->data[len + padding - 1] = tail[0];
 				break;
 			}
 		}
@@ -732,22 +744,29 @@ data_ready:
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 		if (len & 1) {
+			u8 *tail = wl->pio_tailspace;
+			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
+
 			/* Read the last byte. */
-			ssb_block_read(dev->dev, wl->rx_tail, 2,
+			ssb_block_read(dev->dev, tail, 2,
 				       q->mmio_base + B43_PIO_RXDATA,
 				       sizeof(u16));
-			skb->data[len + padding - 1] = wl->rx_tail[0];
+			skb->data[len + padding - 1] = tail[0];
 		}
 	}
 
-	b43_rx(q->dev, skb, &wl->rxhdr);
+	b43_rx(q->dev, skb, rxhdr);
 
 	return 1;
 
 rx_error:
 	if (err_msg)
 		b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg);
-	b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
+	if (q->rev >= 8)
+		b43_piorx_write32(q, B43_PIO8_RXCTL, B43_PIO8_RXCTL_DATARDY);
+	else
+		b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
+
 	return 1;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/rfkill.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/rfkill.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/rfkill.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/rfkill.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,8 +33,14 @@ bool b43_is_hw_radio_enabled(struct b43_
 		      & B43_MMIO_RADIO_HWENABLED_HI_MASK))
 			return 1;
 	} else {
-		if (b43_status(dev) >= B43_STAT_STARTED &&
-		    b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
+		/* To prevent CPU fault on PPC, do not read a register
+		 * unless the interface is started; however, on resume
+		 * for hibernation, this routine is entered early. When
+		 * that happens, unconditionally return TRUE.
+		 */
+		if (b43_status(dev) < B43_STAT_STARTED)
+			return 1;
+		if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
 		    & B43_MMIO_RADIO_HWENABLED_LO_MASK)
 			return 1;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/xmit.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/xmit.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/xmit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/xmit.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
 
 */
 
-#include "b43.h"
+#include "xmit.h"
 #include "phy_common.h"
 #include "dma.h"
 #include "pio.h"
@@ -621,7 +621,6 @@ void b43_rx(struct b43_wldev *dev, struc
 						  (phystat0 & B43_RX_PHYST0_OFDM),
 						  (phystat0 & B43_RX_PHYST0_GAINCTL),
 						  (phystat3 & B43_RX_PHYST3_TRSTATE));
-		status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
 	}
 
 	if (phystat0 & B43_RX_PHYST0_OFDM)
@@ -690,10 +689,7 @@ void b43_rx(struct b43_wldev *dev, struc
 	}
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-
-	local_bh_disable();
-	ieee80211_rx(dev->wl->hw, skb);
-	local_bh_enable();
+	ieee80211_rx_ni(dev->wl->hw, skb);
 
 #if B43_DEBUG
 	dev->rx_count++;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/xmit.h linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/xmit.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43/xmit.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43/xmit.h	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,8 @@
 #define B43_XMIT_H_
 
 #include "main.h"
+#include <net/mac80211.h>
+
 
 #define _b43_declare_plcp_hdr(size) \
 	struct b43_plcp_hdr##size {		\
@@ -332,4 +334,21 @@ static inline u8 b43_kidx_to_raw(struct
 	return raw_kidx;
 }
 
+/* struct b43_private_tx_info - TX info private to b43.
+ * The structure is placed in (struct ieee80211_tx_info *)->rate_driver_data
+ *
+ * @bouncebuffer: DMA Bouncebuffer (if used)
+ */
+struct b43_private_tx_info {
+	void *bouncebuffer;
+};
+
+static inline struct b43_private_tx_info *
+b43_get_priv_tx_info(struct ieee80211_tx_info *info)
+{
+	BUILD_BUG_ON(sizeof(struct b43_private_tx_info) >
+		     sizeof(info->rate_driver_data));
+	return (struct b43_private_tx_info *)info->rate_driver_data;
+}
+
 #endif /* B43_XMIT_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/b43legacy.h linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/b43legacy.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/b43legacy.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/b43legacy.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,8 +29,6 @@
 
 #define B43legacy_IRQWAIT_MAX_RETRIES	20
 
-#define B43legacy_RX_MAX_SSI		60 /* best guess at max ssi */
-
 /* MMIO offsets */
 #define B43legacy_MMIO_DMA0_REASON	0x20
 #define B43legacy_MMIO_DMA0_IRQ_MASK	0x24
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/dma.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -1240,8 +1240,9 @@ struct b43legacy_dmaring *parse_cookie(s
 }
 
 static int dma_tx_fragment(struct b43legacy_dmaring *ring,
-			    struct sk_buff *skb)
+			    struct sk_buff **in_skb)
 {
+	struct sk_buff *skb = *in_skb;
 	const struct b43legacy_dma_ops *ops = ring->ops;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	u8 *header;
@@ -1305,8 +1306,14 @@ static int dma_tx_fragment(struct b43leg
 		}
 
 		memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
+		memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb));
+		bounce_skb->dev = skb->dev;
+		skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb));
+		info = IEEE80211_SKB_CB(bounce_skb);
+
 		dev_kfree_skb_any(skb);
 		skb = bounce_skb;
+		*in_skb = bounce_skb;
 		meta->skb = skb;
 		meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
 		if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
@@ -1360,8 +1367,10 @@ int b43legacy_dma_tx(struct b43legacy_wl
 		     struct sk_buff *skb)
 {
 	struct b43legacy_dmaring *ring;
+	struct ieee80211_hdr *hdr;
 	int err = 0;
 	unsigned long flags;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 	ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
 	spin_lock_irqsave(&ring->lock, flags);
@@ -1386,7 +1395,11 @@ int b43legacy_dma_tx(struct b43legacy_wl
 		goto out_unlock;
 	}
 
-	err = dma_tx_fragment(ring, skb);
+	/* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
+	 * into the skb data or cb now. */
+	hdr = NULL;
+	info = NULL;
+	err = dma_tx_fragment(ring, &skb);
 	if (unlikely(err == -ENOKEY)) {
 		/* Drop this packet, as we don't have the encryption key
 		 * anymore and must not transmit it unencrypted. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config B43LEGACY
 	tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)"
-	depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
+	depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
 	select SSB
 	select FW_LOADER
 	---help---
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 14:01:59.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 12:09:21.000000000 -0400
@@ -2275,7 +2275,7 @@ static void do_periodic_work(struct b43l
 /* Periodic work locking policy:
  * 	The whole periodic work handler is protected by
  * 	wl->mutex. If another lock is needed somewhere in the
- * 	pwork callchain, it's aquired in-place, where it's needed.
+ * 	pwork callchain, it's acquired in-place, where it's needed.
  */
 static void b43legacy_periodic_work_handler(struct work_struct *work)
 {
@@ -2675,7 +2675,7 @@ static int b43legacy_op_dev_config(struc
 	if (conf->channel->hw_value != phy->channel)
 		b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
 
-	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
 
 	/* Adjust the desired TX power level. */
 	if (conf->power_level != 0) {
@@ -3591,7 +3591,7 @@ static int b43legacy_wireless_core_attac
 {
 	struct b43legacy_wl *wl = dev->wl;
 	struct ssb_bus *bus = dev->dev->bus;
-	struct pci_dev *pdev = bus->host_pci;
+	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
 	int err;
 	int have_bphy = 0;
 	int have_gphy = 0;
@@ -3705,7 +3705,7 @@ static int b43legacy_one_core_attach(str
 
 	if (!list_empty(&wl->devlist)) {
 		/* We are not the first core on this chip. */
-		pdev = dev->bus->host_pci;
+		pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
 		/* Only special chips support more than one wireless
 		 * core, although some of the other chips have more than
 		 * one wireless core as well. Check for this and
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/rfkill.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/rfkill.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/rfkill.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/rfkill.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,6 +34,13 @@ bool b43legacy_is_hw_radio_enabled(struc
 		      & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
 			return 1;
 	} else {
+		/* To prevent CPU fault on PPC, do not read a register
+		 * unless the interface is started; however, on resume
+		 * for hibernation, this routine is entered early. When
+		 * that happens, unconditionally return TRUE.
+		 */
+		if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
+			return 1;
 		if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO)
 		    & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK)
 			return 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/xmit.c linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/xmit.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/b43legacy/xmit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/b43legacy/xmit.c	2010-02-24 13:52:17.000000000 -0500
@@ -549,7 +549,6 @@ void b43legacy_rx(struct b43legacy_wldev
 				      (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
 				      (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
 	status.noise = dev->stats.link_noise;
-	status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI;
 	/* change to support A PHY */
 	if (phystat0 & B43legacy_RX_PHYST0_OFDM)
 		status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/hostap/hostap_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/hostap/hostap_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/hostap_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struc
 	conf_reg_t reg;
 	struct hostap_interface *iface = netdev_priv(dev);
 	local_info_t *local = iface->local;
-	tuple_t tuple;
-	cisparse_t *parse = NULL;
-	u_char buf[64];
 	struct hostap_cs_priv *hw_priv = local->hw_priv;
 
 	if (hw_priv->link->io.NumPorts1 < 0x42) {
@@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struc
 		goto done;
 	}
 
-	parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
-	if (parse == NULL) {
-		ret = -ENOMEM;
-		goto done;
-	}
-
-	tuple.Attributes = TUPLE_RETURN_COMMON;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
 	if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
 		/* No SanDisk manfid found */
 		ret = -ENODEV;
 		goto done;
 	}
 
-	tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
-	if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
-	    pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
-	    pcmcia_parse_tuple(&tuple, parse) ||
-		parse->longlink_mfc.nfn < 2) {
+	if (hw_priv->link->socket->functions < 2) {
 		/* No multi-function links found */
 		ret = -ENODEV;
 		goto done;
@@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struc
 	udelay(10);
 
 done:
-	kfree(parse);
 	return ret;
 }
 
@@ -529,10 +510,6 @@ static void prism2_detach(struct pcmcia_
 }
 
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-
 /* run after a CARD_INSERTION event is received to configure the PCMCIA
  * socket and make the device available to the system */
 
@@ -624,7 +601,6 @@ static int prism2_config(struct pcmcia_d
 	struct hostap_interface *iface;
 	local_info_t *local;
 	int ret = 1;
-	int last_fn, last_ret;
 	struct hostap_cs_priv *hw_priv;
 
 	PDEBUG(DEBUG_FLOW, "prism2_config()\n");
@@ -636,19 +612,18 @@ static int prism2_config(struct pcmcia_d
 	}
 
 	/* Look for an appropriate configuration table entry in the CIS */
-	last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
-	if (last_ret) {
+	ret = pcmcia_loop_config(link, prism2_config_check, NULL);
+	if (ret) {
 		if (!ignore_cis_vcc)
 			printk(KERN_ERR "GetNextTuple(): No matching "
 			       "CIS configuration.  Maybe you need the "
 			       "ignore_cis_vcc=1 parameter.\n");
-		cs_error(link, RequestIO, last_ret);
 		goto failed;
 	}
 
 	/* Need to allocate net_device before requesting IRQ handler */
 	dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
-				     &handle_to_dev(link));
+				     &link->dev);
 	if (dev == NULL)
 		goto failed;
 	link->priv = dev;
@@ -666,13 +641,11 @@ static int prism2_config(struct pcmcia_d
 	 * irq structure is initialized.
 	 */
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-		link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
-				       IRQ_HANDLE_PRESENT;
-		link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+		link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 		link->irq.Handler = prism2_interrupt;
-		link->irq.Instance = dev;
-		CS_CHECK(RequestIRQ,
-			 pcmcia_request_irq(link, &link->irq));
+		ret = pcmcia_request_irq(link, &link->irq);
+		if (ret)
+			goto failed;
 	}
 
 	/*
@@ -680,8 +653,9 @@ static int prism2_config(struct pcmcia_d
 	 * the I/O windows and the interrupt mapping, and putting the
 	 * card and host interface into "Memory and IO" mode.
 	 */
-	CS_CHECK(RequestConfiguration,
-		 pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	dev->irq = link->irq.AssignedIRQ;
 	dev->base_addr = link->io.BasePort1;
@@ -714,9 +688,6 @@ static int prism2_config(struct pcmcia_d
 	}
 	return ret;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
-
  failed:
 	kfree(hw_priv);
 	prism2_release((u_long)link);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/hostap/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/hostap/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/hostap/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,8 @@
 config HOSTAP
 	tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
-	depends on WLAN_80211
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	select CRYPTO
 	select CRYPTO_ARC4
 	select CRYPTO_ECB
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/i82586.h linux-libre-2.6.33-gnu1/drivers/net/wireless/i82586.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/i82586.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/i82586.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,413 +0,0 @@
-/*
- * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
- *
- * See:
- *	Intel Microcommunications 1991
- *	p1-1 to p1-37
- *	Intel order No. 231658
- *	ISBN 1-55512-119-5
- *
- *     Unfortunately, the above chapter mentions neither
- * the System Configuration Pointer (SCP) nor the
- * Intermediate System Configuration Pointer (ISCP),
- * so we probably need to look elsewhere for the
- * whole story -- some recommend the "Intel LAN
- * Components manual" but I have neither a copy
- * nor a full reference.  But "elsewhere" may be
- * in the same publication...
- *     The description of a later device, the
- * "82596CA High-Performance 32-Bit Local Area Network
- * Coprocessor", (ibid. p1-38 to p1-109) does mention
- * the SCP and ISCP and also has an i82586 compatibility
- * mode.  Even more useful is "AP-235 An 82586 Data Link
- * Driver" (ibid. p1-337 to p1-417).
- */
-
-#define	I82586_MEMZ	(64 * 1024)
-
-#define	I82586_SCP_ADDR	(I82586_MEMZ - sizeof(scp_t))
-
-#define	ADDR_LEN	6
-#define	I82586NULL	0xFFFF
-
-#define	toff(t,p,f) 	(unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * System Configuration Pointer (SCP).
- */
-typedef struct scp_t	scp_t;
-struct scp_t
-{
-	unsigned short	scp_sysbus;	/* 82586 bus width:	*/
-#define		SCP_SY_16BBUS	(0x0 << 0)	/* 16 bits */
-#define		SCP_SY_8BBUS	(0x1 << 0)	/*  8 bits. */
-	unsigned short	scp_junk[2];	/* Unused */
-	unsigned short	scp_iscpl;	/* lower 16 bits of ISCP_ADDR */
-	unsigned short	scp_iscph;	/* upper 16 bits of ISCP_ADDR */
-};
-
-/*
- * Intermediate System Configuration Pointer (ISCP).
- */
-typedef struct iscp_t	iscp_t;
-struct iscp_t
-{
-	unsigned short	iscp_busy;	/* set by CPU before first CA,	*/
-					/* cleared by 82586 after read.	*/
-	unsigned short	iscp_offset;	/* offset of SCB		*/
-	unsigned short	iscp_basel;	/* base of SCB			*/
-	unsigned short	iscp_baseh;	/*  "				*/
-};
-
-/*
- * System Control Block (SCB).
- *	The 82586 writes its status to scb_status and then
- *	raises an interrupt to alert the CPU.
- *	The CPU writes a command to scb_command and
- *	then issues a Channel Attention (CA) to alert the 82586.
- */
-typedef struct scb_t	scb_t;
-struct scb_t
-{
-	unsigned short	scb_status;	/* Status of 82586		*/
-#define		SCB_ST_INT	(0xF << 12)	/* Some of:		*/
-#define		SCB_ST_CX	(0x1 << 15)	/* Cmd completed	*/
-#define		SCB_ST_FR	(0x1 << 14)	/* Frame received	*/
-#define		SCB_ST_CNA	(0x1 << 13)	/* Cmd unit not active	*/
-#define		SCB_ST_RNR	(0x1 << 12)	/* Rcv unit not ready	*/
-#define		SCB_ST_JUNK0	(0x1 << 11)	/* 0			*/
-#define		SCB_ST_CUS	(0x7 <<  8)	/* Cmd unit status	*/
-#define			SCB_ST_CUS_IDLE	(0 << 8)	/* Idle		*/
-#define			SCB_ST_CUS_SUSP	(1 << 8)	/* Suspended	*/
-#define			SCB_ST_CUS_ACTV	(2 << 8)	/* Active	*/
-#define		SCB_ST_JUNK1	(0x1 <<  7)	/* 0			*/
-#define		SCB_ST_RUS	(0x7 <<  4)	/* Rcv unit status	*/
-#define			SCB_ST_RUS_IDLE	(0 << 4)	/* Idle		*/
-#define			SCB_ST_RUS_SUSP	(1 << 4)	/* Suspended	*/
-#define			SCB_ST_RUS_NRES	(2 << 4)	/* No resources	*/
-#define			SCB_ST_RUS_RDY	(4 << 4)	/* Ready	*/
-	unsigned short	scb_command;	/* Next command			*/
-#define		SCB_CMD_ACK_CX	(0x1 << 15)	/* Ack cmd completion	*/
-#define		SCB_CMD_ACK_FR	(0x1 << 14)	/* Ack frame received	*/
-#define		SCB_CMD_ACK_CNA	(0x1 << 13)	/* Ack CU not active	*/
-#define		SCB_CMD_ACK_RNR	(0x1 << 12)	/* Ack RU not ready	*/
-#define		SCB_CMD_JUNKX	(0x1 << 11)	/* Unused		*/
-#define		SCB_CMD_CUC	(0x7 <<  8)	/* Command Unit command	*/
-#define			SCB_CMD_CUC_NOP	(0 << 8)	/* Nop		*/
-#define			SCB_CMD_CUC_GO	(1 << 8)	/* Start cbl_offset */
-#define			SCB_CMD_CUC_RES	(2 << 8)	/* Resume execution */
-#define			SCB_CMD_CUC_SUS	(3 << 8)	/* Suspend   "	*/
-#define			SCB_CMD_CUC_ABT	(4 << 8)	/* Abort     "	*/
-#define		SCB_CMD_RESET	(0x1 <<  7)	/* Reset chip (hardware) */
-#define		SCB_CMD_RUC	(0x7 <<  4)	/* Receive Unit command	*/
-#define			SCB_CMD_RUC_NOP	(0 << 4)	/* Nop		*/
-#define			SCB_CMD_RUC_GO	(1 << 4)	/* Start rfa_offset */
-#define			SCB_CMD_RUC_RES	(2 << 4)	/* Resume reception */
-#define			SCB_CMD_RUC_SUS	(3 << 4)	/* Suspend   "	*/
-#define			SCB_CMD_RUC_ABT	(4 << 4)	/* Abort     "	*/
-	unsigned short	scb_cbl_offset;	/* Offset of first command unit	*/
-					/* Action Command		*/
-	unsigned short	scb_rfa_offset;	/* Offset of first Receive	*/
-					/* Frame Descriptor in the	*/
-					/* Receive Frame Area		*/
-	unsigned short	scb_crcerrs;	/* Properly aligned frames	*/
-					/* received with a CRC error	*/
-	unsigned short	scb_alnerrs;	/* Misaligned frames received	*/
-					/* with a CRC error		*/
-	unsigned short	scb_rscerrs;	/* Frames lost due to no space	*/
-	unsigned short	scb_ovrnerrs;	/* Frames lost due to slow bus	*/
-};
-
-#define	scboff(p,f) 	toff(scb_t, p, f)
-
-/*
- * The eight Action Commands.
- */
-typedef enum acmd_e	acmd_e;
-enum acmd_e
-{
-	acmd_nop	= 0,	/* Do nothing				*/
-	acmd_ia_setup	= 1,	/* Load an (ethernet) address into the	*/
-				/* 82586				*/
-	acmd_configure	= 2,	/* Update the 82586 operating parameters */
-	acmd_mc_setup	= 3,	/* Load a list of (ethernet) multicast	*/
-				/* addresses into the 82586		*/
-	acmd_transmit	= 4,	/* Transmit a frame			*/
-	acmd_tdr	= 5,	/* Perform a Time Domain Reflectometer	*/
-				/* test on the serial link		*/
-	acmd_dump	= 6,	/* Copy 82586 registers to memory	*/
-	acmd_diagnose	= 7,	/* Run an internal self test		*/
-};
-
-/*
- * Generic Action Command header.
- */
-typedef struct ach_t	ach_t;
-struct ach_t
-{
-	unsigned short	ac_status;		/* Command status:	*/
-#define		AC_SFLD_C	(0x1 << 15)	/* Command completed	*/
-#define		AC_SFLD_B	(0x1 << 14)	/* Busy executing	*/
-#define		AC_SFLD_OK	(0x1 << 13)	/* Completed error free	*/
-#define		AC_SFLD_A	(0x1 << 12)	/* Command aborted	*/
-#define		AC_SFLD_FAIL	(0x1 << 11)	/* Selftest failed	*/
-#define		AC_SFLD_S10	(0x1 << 10)	/* No carrier sense	*/
-						/* during transmission	*/
-#define		AC_SFLD_S9	(0x1 <<  9)	/* Tx unsuccessful:	*/
-						/* (stopped) lost CTS	*/
-#define		AC_SFLD_S8	(0x1 <<  8)	/* Tx unsuccessful:	*/
-						/* (stopped) slow DMA	*/
-#define		AC_SFLD_S7	(0x1 <<  7)	/* Tx deferred:		*/
-						/* other link traffic	*/
-#define		AC_SFLD_S6	(0x1 <<  6)	/* Heart Beat: collision */
-						/* detect after last tx	*/
-#define		AC_SFLD_S5	(0x1 <<  5)	/* Tx stopped:		*/
-						/* excessive collisions	*/
-#define		AC_SFLD_MAXCOL	(0xF <<  0)	/* Collision count  	*/
-	unsigned short	ac_command;		/* Command specifier:	*/
-#define		AC_CFLD_EL	(0x1 << 15)	/* End of command list	*/
-#define		AC_CFLD_S	(0x1 << 14)	/* Suspend on completion */
-#define		AC_CFLD_I	(0x1 << 13)	/* Interrupt on completion */
-#define		AC_CFLD_CMD	(0x7 <<  0)	/* acmd_e		*/
-	unsigned short	ac_link;		/* Next Action Command	*/
-};
-
-#define	acoff(p,f) 	toff(ach_t, p, f)
-
-/*
- * The Nop Action Command.
- */
-typedef struct ac_nop_t	ac_nop_t;
-struct ac_nop_t
-{
-	ach_t	nop_h;
-};
-
-/*
- * The IA-Setup Action Command.
- */
-typedef struct ac_ias_t	ac_ias_t;
-struct ac_ias_t
-{
-	ach_t		ias_h;
-	unsigned char	ias_addr[ADDR_LEN]; /* The (ethernet) address	*/
-};
-
-/*
- * The Configure Action Command.
- */
-typedef struct ac_cfg_t	ac_cfg_t;
-struct ac_cfg_t
-{
-	ach_t		cfg_h;
-	unsigned char	cfg_byte_cnt;	/* Size foll data: 4-12	*/
-#define	AC_CFG_BYTE_CNT(v)	(((v) & 0xF) << 0)
-	unsigned char	cfg_fifolim;	/* FIFO threshold	*/
-#define	AC_CFG_FIFOLIM(v)	(((v) & 0xF) << 0)
-	unsigned char	cfg_byte8;
-#define	AC_CFG_SAV_BF(v) 	(((v) & 0x1) << 7)	/* Save rxd bad frames	*/
-#define	AC_CFG_SRDY(v) 		(((v) & 0x1) << 6)	/* SRDY/ARDY pin means	*/
-							/* external sync.	*/
-	unsigned char	cfg_byte9;
-#define	AC_CFG_ELPBCK(v)	(((v) & 0x1) << 7)	/* External loopback	*/
-#define	AC_CFG_ILPBCK(v)	(((v) & 0x1) << 6)	/* Internal loopback	*/
-#define	AC_CFG_PRELEN(v)	(((v) & 0x3) << 4)	/* Preamble length	*/
-#define		AC_CFG_PLEN_2		0		/*  2 bytes	*/
-#define		AC_CFG_PLEN_4		1		/*  4 bytes	*/
-#define		AC_CFG_PLEN_8		2		/*  8 bytes	*/
-#define		AC_CFG_PLEN_16		3		/* 16 bytes	*/
-#define	AC_CFG_ALOC(v)		(((v) & 0x1) << 3)	/* Addr/len data is	*/
-							/* explicit in buffers	*/
-#define	AC_CFG_ADDRLEN(v)	(((v) & 0x7) << 0)	/* Bytes per address	*/
-	unsigned char	cfg_byte10;
-#define	AC_CFG_BOFMET(v)	(((v) & 0x1) << 7)	/* Use alternate expo.	*/
-							/* backoff method	*/
-#define	AC_CFG_ACR(v)		(((v) & 0x7) << 4)	/* Accelerated cont. res. */
-#define	AC_CFG_LINPRIO(v)	(((v) & 0x7) << 0)	/* Linear priority	*/
-	unsigned char	cfg_ifs;	/* Interframe spacing		*/
-	unsigned char	cfg_slotl;	/* Slot time (low byte)		*/
-	unsigned char	cfg_byte13;
-#define	AC_CFG_RETRYNUM(v)	(((v) & 0xF) << 4)	/* Max. collision retry	*/
-#define	AC_CFG_SLTTMHI(v)	(((v) & 0x7) << 0)	/* Slot time (high bits) */
-	unsigned char	cfg_byte14;
-#define	AC_CFG_FLGPAD(v)	(((v) & 0x1) << 7)	/* Pad with HDLC flags	*/
-#define	AC_CFG_BTSTF(v)		(((v) & 0x1) << 6)	/* Do HDLC bitstuffing	*/
-#define	AC_CFG_CRC16(v)		(((v) & 0x1) << 5)	/* 16 bit CCITT CRC	*/
-#define	AC_CFG_NCRC(v)		(((v) & 0x1) << 4)	/* Insert no CRC	*/
-#define	AC_CFG_TNCRS(v)		(((v) & 0x1) << 3)	/* Tx even if no carrier */
-#define	AC_CFG_MANCH(v)		(((v) & 0x1) << 2)	/* Manchester coding	*/
-#define	AC_CFG_BCDIS(v)		(((v) & 0x1) << 1)	/* Disable broadcast	*/
-#define	AC_CFG_PRM(v)		(((v) & 0x1) << 0)	/* Promiscuous mode	*/
-	unsigned char	cfg_byte15;
-#define	AC_CFG_ICDS(v)		(((v) & 0x1) << 7)	/* Internal collision	*/
-							/* detect source	*/
-#define	AC_CFG_CDTF(v)		(((v) & 0x7) << 4)	/* Collision detect	*/
-							/* filter in bit times	*/
-#define	AC_CFG_ICSS(v)		(((v) & 0x1) << 3)	/* Internal carrier	*/
-							/* sense source		*/
-#define	AC_CFG_CSTF(v)		(((v) & 0x7) << 0)	/* Carrier sense	*/
-							/* filter in bit times	*/
-	unsigned short	cfg_min_frm_len;
-#define	AC_CFG_MNFRM(v)		(((v) & 0xFF) << 0)	/* Min. bytes/frame (<= 255) */
-};
-
-/*
- * The MC-Setup Action Command.
- */
-typedef struct ac_mcs_t	ac_mcs_t;
-struct ac_mcs_t
-{
-	ach_t		mcs_h;
-	unsigned short	mcs_cnt;	/* No. of bytes of MC addresses	*/
-#if 0
-	unsigned char	mcs_data[ADDR_LEN]; /* The first MC address ..	*/
-	...
-#endif
-};
-
-#define I82586_MAX_MULTICAST_ADDRESSES	128	/* Hardware hashed filter */
-
-/*
- * The Transmit Action Command.
- */
-typedef struct ac_tx_t	ac_tx_t;
-struct ac_tx_t
-{
-	ach_t		tx_h;
-	unsigned short	tx_tbd_offset;	/* Address of list of buffers.	*/
-#if	0
-Linux packets are passed down with the destination MAC address
-and length/type field already prepended to the data,
-so we do not need to insert it.  Consistent with this
-we must also set the AC_CFG_ALOC(..) flag during the
-ac_cfg_t action command.
-	unsigned char	tx_addr[ADDR_LEN]; /* The frame dest. address	*/
-	unsigned short	tx_length;	/* The frame length		*/
-#endif	/* 0 */
-};
-
-/*
- * The Time Domain Reflectometer Action Command.
- */
-typedef struct ac_tdr_t	ac_tdr_t;
-struct ac_tdr_t
-{
-	ach_t		tdr_h;
-	unsigned short	tdr_result;	/* Result.	*/
-#define		AC_TDR_LNK_OK	(0x1 << 15)	/* No link problem	*/
-#define		AC_TDR_XCVR_PRB	(0x1 << 14)	/* Txcvr cable problem	*/
-#define		AC_TDR_ET_OPN	(0x1 << 13)	/* Open on the link	*/
-#define		AC_TDR_ET_SRT	(0x1 << 12)	/* Short on the link	*/
-#define		AC_TDR_TIME	(0x7FF << 0)	/* Distance to problem	*/
-						/* site	in transmit	*/
-						/* clock cycles		*/
-};
-
-/*
- * The Dump Action Command.
- */
-typedef struct ac_dmp_t	ac_dmp_t;
-struct ac_dmp_t
-{
-	ach_t		dmp_h;
-	unsigned short	dmp_offset;	/* Result.	*/
-};
-
-/*
- * Size of the result of the dump command.
- */
-#define	DUMPBYTES	170
-
-/*
- * The Diagnose Action Command.
- */
-typedef struct ac_dgn_t	ac_dgn_t;
-struct ac_dgn_t
-{
-	ach_t		dgn_h;
-};
-
-/*
- * Transmit Buffer Descriptor (TBD).
- */
-typedef struct tbd_t	tbd_t;
-struct tbd_t
-{
-	unsigned short	tbd_status;		/* Written by the CPU	*/
-#define		TBD_STATUS_EOF	(0x1 << 15)	/* This TBD is the	*/
-						/* last for this frame	*/
-#define		TBD_STATUS_ACNT	(0x3FFF << 0)	/* Actual count of data	*/
-						/* bytes in this buffer	*/
-	unsigned short	tbd_next_bd_offset;	/* Next in list		*/
-	unsigned short	tbd_bufl;		/* Buffer address (low)	*/
-	unsigned short	tbd_bufh;		/*    "	     "	(high)	*/
-};
-
-/*
- * Receive Buffer Descriptor (RBD).
- */
-typedef struct rbd_t	rbd_t;
-struct rbd_t
-{
-	unsigned short	rbd_status;		/* Written by the 82586	*/
-#define		RBD_STATUS_EOF	(0x1 << 15)	/* This RBD is the	*/
-						/* last for this frame	*/
-#define		RBD_STATUS_F	(0x1 << 14)	/* ACNT field is valid	*/
-#define		RBD_STATUS_ACNT	(0x3FFF << 0)	/* Actual no. of data	*/
-						/* bytes in this buffer	*/
-	unsigned short	rbd_next_rbd_offset;	/* Next rbd in list	*/
-	unsigned short	rbd_bufl;		/* Data pointer (low)	*/
-	unsigned short	rbd_bufh;		/*  "	   "    (high)	*/
-	unsigned short	rbd_el_size;		/* EL+Data buf. size	*/
-#define		RBD_EL	(0x1 << 15)		/* This BD is the	*/
-						/* last in the list	*/
-#define		RBD_SIZE (0x3FFF << 0)		/* No. of bytes the	*/
-						/* buffer can hold	*/
-};
-
-#define	rbdoff(p,f) 	toff(rbd_t, p, f)
-
-/*
- * Frame Descriptor (FD).
- */
-typedef struct fd_t	fd_t;
-struct fd_t
-{
-	unsigned short	fd_status;		/* Written by the 82586	*/
-#define		FD_STATUS_C	(0x1 << 15)	/* Completed storing frame */
-#define		FD_STATUS_B	(0x1 << 14)	/* FD was consumed by RU */
-#define		FD_STATUS_OK	(0x1 << 13)	/* Frame rxd successfully */
-#define		FD_STATUS_S11	(0x1 << 11)	/* CRC error		*/
-#define		FD_STATUS_S10	(0x1 << 10)	/* Alignment error	*/
-#define		FD_STATUS_S9	(0x1 <<  9)	/* Ran out of resources	*/
-#define		FD_STATUS_S8	(0x1 <<  8)	/* Rx DMA overrun	*/
-#define		FD_STATUS_S7	(0x1 <<  7)	/* Frame too short	*/
-#define		FD_STATUS_S6	(0x1 <<  6)	/* No EOF flag		*/
-	unsigned short	fd_command;		/* Command		*/
-#define		FD_COMMAND_EL	(0x1 << 15)	/* Last FD in list	*/
-#define		FD_COMMAND_S	(0x1 << 14)	/* Suspend RU after rx	*/
-	unsigned short	fd_link_offset;		/* Next FD		*/
-	unsigned short	fd_rbd_offset;		/* First RBD (data)	*/
-						/* Prepared by CPU,	*/
-						/* updated by 82586	*/
-#if	0
-I think the rest is unused since we
-have set AC_CFG_ALOC(..).  However, just
-in case, we leave the space.
-#endif	/* 0 */
-	unsigned char	fd_dest[ADDR_LEN];	/* Destination address	*/
-						/* Written by 82586	*/
-	unsigned char	fd_src[ADDR_LEN];	/* Source address	*/
-						/* Written by 82586	*/
-	unsigned short	fd_length;		/* Frame length or type	*/
-						/* Written by 82586	*/
-};
-
-#define	fdoff(p,f) 	toff(fd_t, p, f)
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * For more details, see wavelan.c.
- */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/i82593.h linux-libre-2.6.33-gnu1/drivers/net/wireless/i82593.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/i82593.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/i82593.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,229 +0,0 @@
-/*
- * Definitions for Intel 82593 CSMA/CD Core LAN Controller
- * The definitions are taken from the 1992 users manual with Intel
- * order number 297125-001.
- *
- * /usr/src/pc/RCS/i82593.h,v 1.1 1996/07/17 15:23:12 root Exp
- *
- * Copyright 1994, Anders Klemets <klemets@it.kth.se>
- *
- * HISTORY
- * i82593.h,v
- * Revision 1.4  2005/11/4  09:15:00  baroniunas
- * Modified copyright with permission of author as follows:
- *
- *   "If I82539.H is the only file with my copyright statement
- *    that is included in the Source Forge project, then you have
- *    my approval to change the copyright statement to be a GPL
- *    license, in the way you proposed on October 10."
- *
- * Revision 1.1  1996/07/17 15:23:12  root
- * Initial revision
- *
- * Revision 1.3  1995/04/05  15:13:58  adj
- * Initial alpha release
- *
- * Revision 1.2  1994/06/16  23:57:31  klemets
- * Mirrored all the fields in the configuration block.
- *
- * Revision 1.1  1994/06/02  20:25:34  klemets
- * Initial revision
- *
- *
- */
-#ifndef	_I82593_H
-#define	_I82593_H
-
-/* Intel 82593 CSMA/CD Core LAN Controller */
-
-/* Port 0 Command Register definitions */
-
-/* Execution operations */
-#define OP0_NOP			0	/* CHNL = 0 */
-#define OP0_SWIT_TO_PORT_1	0	/* CHNL = 1 */
-#define OP0_IA_SETUP		1
-#define OP0_CONFIGURE		2
-#define OP0_MC_SETUP		3
-#define OP0_TRANSMIT		4
-#define OP0_TDR			5
-#define OP0_DUMP		6
-#define OP0_DIAGNOSE		7
-#define OP0_TRANSMIT_NO_CRC	9
-#define OP0_RETRANSMIT		12
-#define OP0_ABORT		13
-/* Reception operations */
-#define OP0_RCV_ENABLE		8
-#define OP0_RCV_DISABLE		10
-#define OP0_STOP_RCV		11
-/* Status pointer control operations */
-#define OP0_FIX_PTR		15	/* CHNL = 1 */
-#define OP0_RLS_PTR		15	/* CHNL = 0 */
-#define OP0_RESET		14
-
-#define CR0_CHNL		(1 << 4)	/* 0=Channel 0, 1=Channel 1 */
-#define CR0_STATUS_0		0x00
-#define CR0_STATUS_1		0x20
-#define CR0_STATUS_2		0x40
-#define CR0_STATUS_3		0x60
-#define CR0_INT_ACK		(1 << 7)	/* 0=No ack, 1=acknowledge */
-
-/* Port 0 Status Register definitions */
-
-#define SR0_NO_RESULT		0		/* dummy */
-#define SR0_EVENT_MASK		0x0f
-#define SR0_IA_SETUP_DONE	1
-#define SR0_CONFIGURE_DONE	2
-#define SR0_MC_SETUP_DONE	3
-#define SR0_TRANSMIT_DONE	4
-#define SR0_TDR_DONE		5
-#define SR0_DUMP_DONE		6
-#define SR0_DIAGNOSE_PASSED	7
-#define SR0_TRANSMIT_NO_CRC_DONE 9
-#define SR0_RETRANSMIT_DONE	12
-#define SR0_EXECUTION_ABORTED	13
-#define SR0_END_OF_FRAME	8
-#define SR0_RECEPTION_ABORTED	10
-#define SR0_DIAGNOSE_FAILED	15
-#define SR0_STOP_REG_HIT	11
-
-#define SR0_CHNL		(1 << 4)
-#define SR0_EXECUTION		(1 << 5)
-#define SR0_RECEPTION		(1 << 6)
-#define SR0_INTERRUPT		(1 << 7)
-#define SR0_BOTH_RX_TX		(SR0_EXECUTION | SR0_RECEPTION)
-
-#define SR3_EXEC_STATE_MASK	0x03
-#define SR3_EXEC_IDLE		0
-#define SR3_TX_ABORT_IN_PROGRESS 1
-#define SR3_EXEC_ACTIVE		2
-#define SR3_ABORT_IN_PROGRESS	3
-#define SR3_EXEC_CHNL		(1 << 2)
-#define SR3_STP_ON_NO_RSRC	(1 << 3)
-#define SR3_RCVING_NO_RSRC	(1 << 4)
-#define SR3_RCV_STATE_MASK	0x60
-#define SR3_RCV_IDLE		0x00
-#define SR3_RCV_READY		0x20
-#define SR3_RCV_ACTIVE		0x40
-#define SR3_RCV_STOP_IN_PROG	0x60
-#define SR3_RCV_CHNL		(1 << 7)
-
-/* Port 1 Command Register definitions */
-
-#define OP1_NOP			0
-#define OP1_SWIT_TO_PORT_0	1
-#define OP1_INT_DISABLE		2
-#define OP1_INT_ENABLE		3
-#define OP1_SET_TS		5
-#define OP1_RST_TS		7
-#define OP1_POWER_DOWN		8
-#define OP1_RESET_RING_MNGMT	11
-#define OP1_RESET		14
-#define OP1_SEL_RST		15
-
-#define CR1_STATUS_4		0x00
-#define CR1_STATUS_5		0x20
-#define CR1_STATUS_6		0x40
-#define CR1_STOP_REG_UPDATE	(1 << 7)
-
-/* Receive frame status bits */
-
-#define	RX_RCLD			(1 << 0)
-#define RX_IA_MATCH		(1 << 1)
-#define	RX_NO_AD_MATCH		(1 << 2)
-#define RX_NO_SFD		(1 << 3)
-#define RX_SRT_FRM		(1 << 7)
-#define RX_OVRRUN		(1 << 8)
-#define RX_ALG_ERR		(1 << 10)
-#define RX_CRC_ERR		(1 << 11)
-#define RX_LEN_ERR		(1 << 12)
-#define RX_RCV_OK		(1 << 13)
-#define RX_TYP_LEN		(1 << 15)
-
-/* Transmit status bits */
-
-#define TX_NCOL_MASK		0x0f
-#define TX_FRTL			(1 << 4)
-#define TX_MAX_COL		(1 << 5)
-#define TX_HRT_BEAT		(1 << 6)
-#define TX_DEFER		(1 << 7)
-#define TX_UND_RUN		(1 << 8)
-#define TX_LOST_CTS		(1 << 9)
-#define TX_LOST_CRS		(1 << 10)
-#define TX_LTCOL		(1 << 11)
-#define TX_OK			(1 << 13)
-#define TX_COLL			(1 << 15)
-
-struct i82593_conf_block {
-  u_char fifo_limit : 4,
-  	 forgnesi   : 1,
-  	 fifo_32    : 1,
-  	 d6mod      : 1,
-  	 throttle_enb : 1;
-  u_char throttle   : 6,
-	 cntrxint   : 1,
-	 contin	    : 1;
-  u_char addr_len   : 3,
-  	 acloc 	    : 1,
- 	 preamb_len : 2,
-  	 loopback   : 2;
-  u_char lin_prio   : 3,
-	 tbofstop   : 1,
-	 exp_prio   : 3,
-	 bof_met    : 1;
-  u_char	    : 4,
-	 ifrm_spc   : 4;
-  u_char	    : 5,
-	 slottim_low : 3;
-  u_char slottim_hi : 3,
-		    : 1,
-	 max_retr   : 4;
-  u_char prmisc     : 1,
-	 bc_dis     : 1,
-  		    : 1,
-	 crs_1	    : 1,
-	 nocrc_ins  : 1,
-	 crc_1632   : 1,
-  	 	    : 1,
-  	 crs_cdt    : 1;
-  u_char cs_filter  : 3,
-	 crs_src    : 1,
-	 cd_filter  : 3,
-		    : 1;
-  u_char	    : 2,
-  	 min_fr_len : 6;
-  u_char lng_typ    : 1,
-	 lng_fld    : 1,
-	 rxcrc_xf   : 1,
-	 artx	    : 1,
-	 sarec	    : 1,
-	 tx_jabber  : 1,	/* why is this called max_len in the manual? */
-	 hash_1	    : 1,
-  	 lbpkpol    : 1;
-  u_char	    : 6,
-  	 fdx	    : 1,
-  	  	    : 1;
-  u_char dummy_6    : 6,	/* supposed to be ones */
-  	 mult_ia    : 1,
-  	 dis_bof    : 1;
-  u_char dummy_1    : 1,	/* supposed to be one */
-	 tx_ifs_retrig : 2,
-	 mc_all     : 1,
-	 rcv_mon    : 2,
-	 frag_acpt  : 1,
-  	 tstrttrs   : 1;
-  u_char fretx	    : 1,
-	 runt_eop   : 1,
-	 hw_sw_pin  : 1,
-	 big_endn   : 1,
-	 syncrqs    : 1,
-	 sttlen     : 1,
-	 tx_eop     : 1,
-  	 rx_eop	    : 1;
-  u_char rbuf_size  : 5,
-	 rcvstop    : 1,
-  	 	    : 2;
-};
-
-#define I82593_MAX_MULTICAST_ADDRESSES	128	/* Hardware hashed filter */
-
-#endif /* _I82593_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 14:02:06.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 12:09:38.000000000 -0400
@@ -296,6 +296,33 @@ static const char *command_types[] = {
 };
 #endif
 
+#define WEXT_USECHANNELS 1
+
+static const long ipw2100_frequencies[] = {
+	2412, 2417, 2422, 2427,
+	2432, 2437, 2442, 2447,
+	2452, 2457, 2462, 2467,
+	2472, 2484
+};
+
+#define FREQ_COUNT	ARRAY_SIZE(ipw2100_frequencies)
+
+static const long ipw2100_rates_11b[] = {
+	1000000,
+	2000000,
+	5500000,
+	11000000
+};
+
+static struct ieee80211_rate ipw2100_bg_rates[] = {
+	{ .bitrate = 10 },
+	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+};
+
+#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
+
 /* Pre-decl until we get the code solid and then we can clean it up */
 static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
 static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -551,7 +578,7 @@ static int ipw2100_get_ordinal(struct ip
 		/* get number of entries */
 		field_count = *(((u16 *) & field_info) + 1);
 
-		/* abort if no enought memory */
+		/* abort if no enough memory */
 		total_length = field_len * field_count;
 		if (total_length > *len) {
 			*len = total_length;
@@ -1141,6 +1168,7 @@ static int rf_kill_active(struct ipw2100
 	int i;
 
 	if (!(priv->hw_features & HW_FEATURE_RFKILL)) {
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
 		priv->status &= ~STATUS_RF_KILL_HW;
 		return 0;
 	}
@@ -1151,10 +1179,13 @@ static int rf_kill_active(struct ipw2100
 		value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1);
 	}
 
-	if (value == 0)
+	if (value == 0) {
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
 		priv->status |= STATUS_RF_KILL_HW;
-	else
+	} else {
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
 		priv->status &= ~STATUS_RF_KILL_HW;
+	}
 
 	return (value == 0);
 }
@@ -1814,13 +1845,6 @@ static int ipw2100_up(struct ipw2100_pri
 	return rc;
 }
 
-/* Called by register_netdev() */
-static int ipw2100_net_init(struct net_device *dev)
-{
-	struct ipw2100_priv *priv = libipw_priv(dev);
-	return ipw2100_up(priv, 1);
-}
-
 static void ipw2100_down(struct ipw2100_priv *priv)
 {
 	unsigned long flags;
@@ -1875,6 +1899,64 @@ static void ipw2100_down(struct ipw2100_
 	netif_stop_queue(priv->net_dev);
 }
 
+/* Called by register_netdev() */
+static int ipw2100_net_init(struct net_device *dev)
+{
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
+	struct wireless_dev *wdev = &priv->ieee->wdev;
+	int ret;
+	int i;
+
+	ret = ipw2100_up(priv, 1);
+	if (ret)
+		return ret;
+
+	memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
+
+	/* fill-out priv->ieee->bg_band */
+	if (geo->bg_channels) {
+		struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
+
+		bg_band->band = IEEE80211_BAND_2GHZ;
+		bg_band->n_channels = geo->bg_channels;
+		bg_band->channels =
+			kzalloc(geo->bg_channels *
+				sizeof(struct ieee80211_channel), GFP_KERNEL);
+		/* translate geo->bg to bg_band.channels */
+		for (i = 0; i < geo->bg_channels; i++) {
+			bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			bg_band->channels[i].center_freq = geo->bg[i].freq;
+			bg_band->channels[i].hw_value = geo->bg[i].channel;
+			bg_band->channels[i].max_power = geo->bg[i].max_power;
+			if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_PASSIVE_SCAN;
+			if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_NO_IBSS;
+			if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_RADAR;
+			/* No equivalent for LIBIPW_CH_80211H_RULES,
+			   LIBIPW_CH_UNIFORM_SPREADING, or
+			   LIBIPW_CH_B_ONLY... */
+		}
+		/* point at bitrate info */
+		bg_band->bitrates = ipw2100_bg_rates;
+		bg_band->n_bitrates = RATE_COUNT;
+
+		wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
+	}
+
+	set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+	if (wiphy_register(wdev->wiphy)) {
+		ipw2100_down(priv);
+		return -EIO;
+	}
+	return 0;
+}
+
 static void ipw2100_reset_adapter(struct work_struct *work)
 {
 	struct ipw2100_priv *priv =
@@ -2090,6 +2172,7 @@ static void isr_indicate_rf_kill(struct
 		       priv->net_dev->name);
 
 	/* RF_KILL is now enabled (else we wouldn't be here) */
+	wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
 	priv->status |= STATUS_RF_KILL_HW;
 
 	/* Make sure the RF Kill check timer is running */
@@ -3044,7 +3127,7 @@ static void ipw2100_tx_send_data(struct
 			     IPW_MAX_BDS)) {
 			/* TODO: Support merging buffers if more than
 			 * IPW_MAX_BDS are used */
-			IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded.  "
+			IPW_DEBUG_INFO("%s: Maximum BD threshold exceeded.  "
 				       "Increase fragmentation level.\n",
 				       priv->net_dev->name);
 		}
@@ -6029,7 +6112,7 @@ static struct net_device *ipw2100_alloc_
 	struct ipw2100_priv *priv;
 	struct net_device *dev;
 
-	dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
+	dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
 	if (!dev)
 		return NULL;
 	priv = libipw_priv(dev);
@@ -6342,7 +6425,7 @@ static int ipw2100_pci_init_one(struct p
 		sysfs_remove_group(&pci_dev->dev.kobj,
 				   &ipw2100_attribute_group);
 
-		free_ieee80211(dev);
+		free_ieee80211(dev, 0);
 		pci_set_drvdata(pci_dev, NULL);
 	}
 
@@ -6400,7 +6483,10 @@ static void __devexit ipw2100_pci_remove
 		if (dev->base_addr)
 			iounmap((void __iomem *)dev->base_addr);
 
-		free_ieee80211(dev);
+		/* wiphy_unregister needs to be here, before free_ieee80211 */
+		wiphy_unregister(priv->ieee->wdev.wiphy);
+		kfree(priv->ieee->bg_band.channels);
+		free_ieee80211(dev, 0);
 	}
 
 	pci_release_regions(pci_dev);
@@ -6487,6 +6573,16 @@ static int ipw2100_resume(struct pci_dev
 }
 #endif
 
+static void ipw2100_shutdown(struct pci_dev *pci_dev)
+{
+	struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
+
+	/* Take down the device; powers it off, etc. */
+	ipw2100_down(priv);
+
+	pci_disable_device(pci_dev);
+}
+
 #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
 
 static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
@@ -6550,6 +6646,7 @@ static struct pci_driver ipw2100_pci_dri
 	.suspend = ipw2100_suspend,
 	.resume = ipw2100_resume,
 #endif
+	.shutdown = ipw2100_shutdown,
 };
 
 /**
@@ -6601,26 +6698,6 @@ static void __exit ipw2100_exit(void)
 module_init(ipw2100_init);
 module_exit(ipw2100_exit);
 
-#define WEXT_USECHANNELS 1
-
-static const long ipw2100_frequencies[] = {
-	2412, 2417, 2422, 2427,
-	2432, 2437, 2442, 2447,
-	2452, 2457, 2462, 2467,
-	2472, 2484
-};
-
-#define FREQ_COUNT	ARRAY_SIZE(ipw2100_frequencies)
-
-static const long ipw2100_rates_11b[] = {
-	1000000,
-	2000000,
-	5500000,
-	11000000
-};
-
-#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
-
 static int ipw2100_wx_get_name(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
@@ -6820,7 +6897,7 @@ static int ipw2100_wx_get_range(struct n
 	range->max_qual.updated = 7;	/* Updated all three */
 
 	range->avg_qual.qual = 70;	/* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 	range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
@@ -8448,6 +8525,12 @@ static int ipw2100_get_firmware(struct i
 	return 0;
 }
 
+/*(DEBLOBBED)*/
+#ifdef CONFIG_IPW2100_MONITOR
+/*(DEBLOBBED)*/
+#endif
+/*(DEBLOBBED)*/
+
 static void ipw2100_release_firmware(struct ipw2100_priv *priv,
 				     struct ipw2100_fw *fw)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 14:02:12.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 12:09:44.000000000 -0400
@@ -81,6 +81,11 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
+#ifdef CONFIG_IPW2200_MONITOR
+/*(DEBLOBBED)*/
+#endif
+/*(DEBLOBBED)*/
 
 static int cmdlog = 0;
 static int debug = 0;
@@ -104,6 +109,25 @@ static int antenna = CFG_SYS_ANTENNA_BOT
 static int rtap_iface = 0;     /* def: 0 -- do not create rtap interface */
 #endif
 
+static struct ieee80211_rate ipw2200_rates[] = {
+	{ .bitrate = 10 },
+	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60 },
+	{ .bitrate = 90 },
+	{ .bitrate = 120 },
+	{ .bitrate = 180 },
+	{ .bitrate = 240 },
+	{ .bitrate = 360 },
+	{ .bitrate = 480 },
+	{ .bitrate = 540 }
+};
+
+#define ipw2200_a_rates		(ipw2200_rates + 4)
+#define ipw2200_num_a_rates	8
+#define ipw2200_bg_rates	(ipw2200_rates + 0)
+#define ipw2200_num_bg_rates	12
 
 #ifdef CONFIG_IPW2200_QOS
 static int qos_enable = 0;
@@ -768,7 +792,7 @@ static int ipw_get_ordinal(struct ipw_pr
 		/* get number of entries */
 		field_count = *(((u16 *) & field_info) + 1);
 
-		/* abort if not enought memory */
+		/* abort if not enough memory */
 		total_len = field_len * field_count;
 		if (total_len > *len) {
 			*len = total_len;
@@ -1734,10 +1758,13 @@ static DEVICE_ATTR(direct_dword, S_IWUSR
 
 static int rf_kill_active(struct ipw_priv *priv)
 {
-	if (0 == (ipw_read32(priv, 0x30) & 0x10000))
+	if (0 == (ipw_read32(priv, 0x30) & 0x10000)) {
 		priv->status |= STATUS_RF_KILL_HW;
-	else
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
+	} else {
 		priv->status &= ~STATUS_RF_KILL_HW;
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
+	}
 
 	return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
 }
@@ -2020,6 +2047,7 @@ static void ipw_irq_tasklet(struct ipw_p
 	if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
 		IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
 		priv->status |= STATUS_RF_KILL_HW;
+		wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
 		wake_up_interruptible(&priv->wait_command_queue);
 		priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
 		cancel_delayed_work(&priv->request_scan);
@@ -7732,7 +7760,7 @@ static void ipw_rebuild_decrypted_skb(st
 	case SEC_LEVEL_0:
 		break;
 	default:
-		printk(KERN_ERR "Unknow security level %d\n",
+		printk(KERN_ERR "Unknown security level %d\n",
 		       priv->ieee->sec.level);
 		break;
 	}
@@ -8655,24 +8683,6 @@ static int ipw_sw_reset(struct ipw_priv
  *
  */
 
-static int ipw_wx_get_name(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu, char *extra)
-{
-	struct ipw_priv *priv = libipw_priv(dev);
-	mutex_lock(&priv->mutex);
-	if (priv->status & STATUS_RF_KILL_MASK)
-		strcpy(wrqu->name, "radio off");
-	else if (!(priv->status & STATUS_ASSOCIATED))
-		strcpy(wrqu->name, "unassociated");
-	else
-		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
-			 ipw_modes[priv->assoc_request.ieee_mode]);
-	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
-	mutex_unlock(&priv->mutex);
-	return 0;
-}
-
 static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
 {
 	if (channel == 0) {
@@ -8916,7 +8926,7 @@ static int ipw_wx_get_range(struct net_d
 	range->max_qual.updated = 7;	/* Updated all three */
 
 	range->avg_qual.qual = 70;
-	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
 	range->avg_qual.level = 0;	/* FIXME to real average level */
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
@@ -9972,7 +9982,7 @@ static int ipw_wx_sw_reset(struct net_de
 /* Rebase the WE IOCTLs to zero for the handler array */
 #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
 static iw_handler ipw_wx_handlers[] = {
-	IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
+	IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
 	IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
 	IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
 	IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -10289,7 +10299,7 @@ static int ipw_tx_skb(struct ipw_priv *p
 		case SEC_LEVEL_0:
 			break;
 		default:
-			printk(KERN_ERR "Unknow security level %d\n",
+			printk(KERN_ERR "Unknown security level %d\n",
 			       priv->ieee->sec.level);
 			break;
 		}
@@ -11275,6 +11285,7 @@ static int ipw_up(struct ipw_priv *priv)
 		if (!(priv->config & CFG_CUSTOM_MAC))
 			eeprom_parse_mac(priv, priv->mac_addr);
 		memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
+		memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
 
 		for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
 			if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
@@ -11416,16 +11427,100 @@ static void ipw_bg_down(struct work_stru
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
+	int i, rc = 0;
 	struct ipw_priv *priv = libipw_priv(dev);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
+	struct wireless_dev *wdev = &priv->ieee->wdev;
 	mutex_lock(&priv->mutex);
 
 	if (ipw_up(priv)) {
-		mutex_unlock(&priv->mutex);
-		return -EIO;
+		rc = -EIO;
+		goto out;
 	}
 
+	memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
+
+	/* fill-out priv->ieee->bg_band */
+	if (geo->bg_channels) {
+		struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
+
+		bg_band->band = IEEE80211_BAND_2GHZ;
+		bg_band->n_channels = geo->bg_channels;
+		bg_band->channels =
+			kzalloc(geo->bg_channels *
+				sizeof(struct ieee80211_channel), GFP_KERNEL);
+		/* translate geo->bg to bg_band.channels */
+		for (i = 0; i < geo->bg_channels; i++) {
+			bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			bg_band->channels[i].center_freq = geo->bg[i].freq;
+			bg_band->channels[i].hw_value = geo->bg[i].channel;
+			bg_band->channels[i].max_power = geo->bg[i].max_power;
+			if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_PASSIVE_SCAN;
+			if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_NO_IBSS;
+			if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_RADAR;
+			/* No equivalent for LIBIPW_CH_80211H_RULES,
+			   LIBIPW_CH_UNIFORM_SPREADING, or
+			   LIBIPW_CH_B_ONLY... */
+		}
+		/* point at bitrate info */
+		bg_band->bitrates = ipw2200_bg_rates;
+		bg_band->n_bitrates = ipw2200_num_bg_rates;
+
+		wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
+	}
+
+	/* fill-out priv->ieee->a_band */
+	if (geo->a_channels) {
+		struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
+
+		a_band->band = IEEE80211_BAND_5GHZ;
+		a_band->n_channels = geo->a_channels;
+		a_band->channels =
+			kzalloc(geo->a_channels *
+				sizeof(struct ieee80211_channel), GFP_KERNEL);
+		/* translate geo->bg to a_band.channels */
+		for (i = 0; i < geo->a_channels; i++) {
+			a_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			a_band->channels[i].center_freq = geo->a[i].freq;
+			a_band->channels[i].hw_value = geo->a[i].channel;
+			a_band->channels[i].max_power = geo->a[i].max_power;
+			if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_PASSIVE_SCAN;
+			if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_NO_IBSS;
+			if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_RADAR;
+			/* No equivalent for LIBIPW_CH_80211H_RULES,
+			   LIBIPW_CH_UNIFORM_SPREADING, or
+			   LIBIPW_CH_B_ONLY... */
+		}
+		/* point at bitrate info */
+		a_band->bitrates = ipw2200_a_rates;
+		a_band->n_bitrates = ipw2200_num_a_rates;
+
+		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
+	}
+
+	set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+
+	/* With that information in place, we can now register the wiphy... */
+	if (wiphy_register(wdev->wiphy)) {
+		rc = -EIO;
+		goto out;
+	}
+
+out:
 	mutex_unlock(&priv->mutex);
-	return 0;
+	return rc;
 }
 
 /* PCI driver stuff */
@@ -11556,7 +11651,7 @@ static int ipw_prom_alloc(struct ipw_pri
 	if (priv->prom_net_dev)
 		return -EPERM;
 
-	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
+	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
 	if (priv->prom_net_dev == NULL)
 		return -ENOMEM;
 
@@ -11575,7 +11670,7 @@ static int ipw_prom_alloc(struct ipw_pri
 
 	rc = register_netdev(priv->prom_net_dev);
 	if (rc) {
-		free_ieee80211(priv->prom_net_dev);
+		free_ieee80211(priv->prom_net_dev, 1);
 		priv->prom_net_dev = NULL;
 		return rc;
 	}
@@ -11589,7 +11684,7 @@ static void ipw_prom_free(struct ipw_pri
 		return;
 
 	unregister_netdev(priv->prom_net_dev);
-	free_ieee80211(priv->prom_net_dev);
+	free_ieee80211(priv->prom_net_dev, 1);
 
 	priv->prom_net_dev = NULL;
 }
@@ -11617,7 +11712,7 @@ static int __devinit ipw_pci_probe(struc
 	struct ipw_priv *priv;
 	int i;
 
-	net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
+	net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
 	if (net_dev == NULL) {
 		err = -ENOMEM;
 		goto out;
@@ -11765,7 +11860,7 @@ static int __devinit ipw_pci_probe(struc
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
       out_free_ieee80211:
-	free_ieee80211(priv->net_dev);
+	free_ieee80211(priv->net_dev, 0);
       out:
 	return err;
 }
@@ -11832,7 +11927,11 @@ static void __devexit ipw_pci_remove(str
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	free_ieee80211(priv->net_dev);
+	/* wiphy_unregister needs to be here, before free_ieee80211 */
+	wiphy_unregister(priv->ieee->wdev.wiphy);
+	kfree(priv->ieee->a_band.channels);
+	kfree(priv->ieee->bg_band.channels);
+	free_ieee80211(priv->net_dev, 0);
 	free_firmware();
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -4,8 +4,10 @@
 
 config IPW2100
 	tristate "Intel PRO/Wireless 2100 Network Connection"
-	depends on PCI && WLAN_80211 && CFG80211
+	depends on PCI && CFG80211
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	select FW_LOADER
 	select LIB80211
 	select LIBIPW
@@ -63,8 +65,10 @@ config IPW2100_DEBUG
 
 config IPW2200
 	tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-	depends on PCI && WLAN_80211 && CFG80211
+	depends on PCI && CFG80211 && CFG80211_WEXT
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	select FW_LOADER
 	select LIB80211
 	select LIBIPW
@@ -150,8 +154,9 @@ config IPW2200_DEBUG
 
 config LIBIPW
 	tristate
-	depends on PCI && WLAN_80211 && CFG80211
+	depends on PCI && CFG80211
 	select WIRELESS_EXT
+	select WEXT_SPY
 	select CRYPTO
 	select CRYPTO_ARC4
 	select CRYPTO_ECB
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/libipw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/libipw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <linux/ieee80211.h>
 
 #include <net/lib80211.h>
+#include <net/cfg80211.h>
 
 #define LIBIPW_VERSION "git-1.1.13"
 
@@ -783,12 +784,15 @@ struct libipw_geo {
 
 struct libipw_device {
 	struct net_device *dev;
+	struct wireless_dev wdev;
 	struct libipw_security sec;
 
 	/* Bookkeeping structures */
 	struct libipw_stats ieee_stats;
 
 	struct libipw_geo geo;
+	struct ieee80211_supported_band bg_band;
+	struct ieee80211_supported_band a_band;
 
 	/* Probe / Beacon management */
 	struct list_head network_free_list;
@@ -1014,8 +1018,8 @@ static inline int libipw_is_cck_rate(u8
 }
 
 /* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
+extern void free_ieee80211(struct net_device *dev, int monitor);
+extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
 extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
 
 extern void libipw_networks_age(struct libipw_device *ieee,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,6 +62,9 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
+struct cfg80211_ops libipw_config_ops = { };
+void *libipw_wiphy_privid = &libipw_wiphy_privid;
+
 static int libipw_networks_allocate(struct libipw_device *ieee)
 {
 	if (ieee->networks)
@@ -140,7 +143,7 @@ int libipw_change_mtu(struct net_device
 }
 EXPORT_SYMBOL(libipw_change_mtu);
 
-struct net_device *alloc_ieee80211(int sizeof_priv)
+struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
 {
 	struct libipw_device *ieee;
 	struct net_device *dev;
@@ -157,10 +160,31 @@ struct net_device *alloc_ieee80211(int s
 
 	ieee->dev = dev;
 
+	if (!monitor) {
+		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
+		if (!ieee->wdev.wiphy) {
+			LIBIPW_ERROR("Unable to allocate wiphy.\n");
+			goto failed_free_netdev;
+		}
+
+		ieee->dev->ieee80211_ptr = &ieee->wdev;
+		ieee->wdev.iftype = NL80211_IFTYPE_STATION;
+
+		/* Fill-out wiphy structure bits we know...  Not enough info
+		   here to call set_wiphy_dev or set MAC address or channel info
+		   -- have to do that in ->ndo_init... */
+		ieee->wdev.wiphy->privid = libipw_wiphy_privid;
+
+		ieee->wdev.wiphy->max_scan_ssids = 1;
+		ieee->wdev.wiphy->max_scan_ie_len = 0;
+		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+						| BIT(NL80211_IFTYPE_ADHOC);
+	}
+
 	err = libipw_networks_allocate(ieee);
 	if (err) {
 		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
-		goto failed_free_netdev;
+		goto failed_free_wiphy;
 	}
 	libipw_networks_initialize(ieee);
 
@@ -175,7 +199,7 @@ struct net_device *alloc_ieee80211(int s
 	ieee->host_decrypt = 1;
 	ieee->host_mc_decrypt = 1;
 
-	/* Host fragementation in Open mode. Default is enabled.
+	/* Host fragmentation in Open mode. Default is enabled.
 	 * Note: host fragmentation is always enabled if host encryption
 	 * is enabled. For cards can do hardware encryption, they must do
 	 * hardware fragmentation as well. So we don't need a variable
@@ -193,19 +217,27 @@ struct net_device *alloc_ieee80211(int s
 
 	return dev;
 
+failed_free_wiphy:
+	if (!monitor)
+		wiphy_free(ieee->wdev.wiphy);
 failed_free_netdev:
 	free_netdev(dev);
 failed:
 	return NULL;
 }
 
-void free_ieee80211(struct net_device *dev)
+void free_ieee80211(struct net_device *dev, int monitor)
 {
 	struct libipw_device *ieee = netdev_priv(dev);
 
 	lib80211_crypt_info_free(&ieee->crypt_info);
 
 	libipw_networks_free(ieee);
+
+	/* free cfg80211 resources */
+	if (!monitor)
+		wiphy_free(ieee->wdev.wiphy);
+
 	free_netdev(dev);
 }
 
@@ -216,17 +248,22 @@ u32 libipw_debug_level = 0;
 EXPORT_SYMBOL_GPL(libipw_debug_level);
 static struct proc_dir_entry *libipw_proc = NULL;
 
-static int show_debug_level(char *page, char **start, off_t offset,
-			    int count, int *eof, void *data)
+static int debug_level_proc_show(struct seq_file *m, void *v)
 {
-	return snprintf(page, count, "0x%08X\n", libipw_debug_level);
+	seq_printf(m, "0x%08X\n", libipw_debug_level);
+	return 0;
 }
 
-static int store_debug_level(struct file *file, const char __user * buffer,
-			     unsigned long count, void *data)
+static int debug_level_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, debug_level_proc_show, NULL);
+}
+
+static ssize_t debug_level_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	char buf[] = "0x00000000\n";
-	unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
+	size_t len = min(sizeof(buf) - 1, count);
 	unsigned long val;
 
 	if (copy_from_user(buf, buffer, len))
@@ -240,6 +277,15 @@ static int store_debug_level(struct file
 
 	return strnlen(buf, len);
 }
+
+static const struct file_operations debug_level_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= debug_level_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= debug_level_proc_write,
+};
 #endif				/* CONFIG_LIBIPW_DEBUG */
 
 static int __init libipw_init(void)
@@ -254,16 +300,13 @@ static int __init libipw_init(void)
 				" proc directory\n");
 		return -EIO;
 	}
-	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
-			      libipw_proc);
+	e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
+			&debug_level_proc_fops);
 	if (!e) {
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
 		libipw_proc = NULL;
 		return -EIO;
 	}
-	e->read_proc = show_debug_level;
-	e->write_proc = store_debug_level;
-	e->data = NULL;
 #endif				/* CONFIG_LIBIPW_DEBUG */
 
 	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-05-03 14:02:30.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-05-03 12:10:02.000000000 -0400
@@ -44,6 +44,7 @@
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
 #include "iwl-5000-hw.h"
+#include "iwl-agn-led.h"
 
 /* Highest firmware API version supported */
 #define IWL1000_UCODE_API_MAX 3
@@ -76,7 +77,10 @@ static void iwl1000_set_ct_threshold(str
 /* NIC configuration for 1000 series */
 static void iwl1000_nic_config(struct iwl_priv *priv)
 {
-	iwl5000_nic_config(priv);
+	/* set CSR_HW_CONFIG_REG for uCode use */
+	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
+		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
 	/* Setting digital SVR for 1000 card to 1.32V */
 	/* locking is acquired in iwl_set_bits_mask_prph() function */
@@ -106,9 +110,8 @@ static struct iwl_lib_ops iwl1000_lib =
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
-		.reset = iwl5000_apm_reset,
-		.stop = iwl5000_apm_stop,
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
 		.config = iwl1000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
 	},
@@ -142,6 +145,7 @@ static struct iwl_ops iwl1000_ops = {
 	.lib = &iwl1000_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
+	.led = &iwlagn_led_ops,
 };
 
 struct iwl_cfg iwl1000_bgn_cfg = {
@@ -152,15 +156,50 @@ struct iwl_cfg iwl1000_bgn_cfg = {
 	.sku = IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl1000_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.support_ct_kill_exit = true,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
+struct iwl_cfg iwl1000_bg_cfg = {
+	.name = "1000 Series BG",
+	.fw_name_pre = IWL1000_FW_PRE,
+	.ucode_api_max = IWL1000_UCODE_API_MAX,
+	.ucode_api_min = IWL1000_UCODE_API_MIN,
+	.sku = IWL_SKU_G,
+	.ops = &iwl1000_ops,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
+	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_A,
+	.valid_rx_ant = ANT_AB,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
+	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
+	.shadow_ram_support = false,
+	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.support_ct_kill_exit = true,
+};
+
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 14:02:16.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 12:09:48.000000000 -0400
@@ -42,7 +42,6 @@
 #include <linux/if_arp.h>
 
 #include <net/ieee80211_radiotap.h>
-#include <net/lib80211.h>
 #include <net/mac80211.h>
 
 #include <asm/div64.h>
@@ -77,11 +76,9 @@
 #define VS
 #endif
 
-#define IWL39_VERSION "1.2.26k" VD VS
+#define DRV_VERSION  IWLWIFI_VERSION VD VS
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
-#define DRV_VERSION     IWL39_VERSION
-
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
@@ -90,7 +87,6 @@ MODULE_LICENSE("GPL");
 
  /* module parameters */
 struct iwl_mod_params iwl3945_mod_params = {
-	.num_of_queues = IWL39_NUM_QUEUES, /* Not used */
 	.sw_crypto = 1,
 	.restart_fw = 1,
 	/* the rest are 0 by default */
@@ -368,13 +364,13 @@ static void iwl3945_build_tx_cmd_hwcrypt
 				      struct sk_buff *skb_frag,
 				      int sta_id)
 {
-	struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+	struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 	struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
 
 	switch (keyinfo->alg) {
 	case ALG_CCMP:
-		tx->sec_ctl = TX_CMD_SEC_CCM;
-		memcpy(tx->key, keyinfo->key, keyinfo->keylen);
+		tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
+		memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen);
 		IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
 		break;
 
@@ -382,13 +378,13 @@ static void iwl3945_build_tx_cmd_hwcrypt
 		break;
 
 	case ALG_WEP:
-		tx->sec_ctl = TX_CMD_SEC_WEP |
+		tx_cmd->sec_ctl = TX_CMD_SEC_WEP |
 		    (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
 
 		if (keyinfo->keylen == 13)
-			tx->sec_ctl |= TX_CMD_SEC_KEY128;
+			tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
 
-		memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
+		memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen);
 
 		IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
 			     "with key %d\n", info->control.hw_key->hw_key_idx);
@@ -408,12 +404,11 @@ static void iwl3945_build_tx_cmd_basic(s
 				  struct ieee80211_tx_info *info,
 				  struct ieee80211_hdr *hdr, u8 std_id)
 {
-	struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
-	__le32 tx_flags = tx->tx_flags;
+	struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+	__le32 tx_flags = tx_cmd->tx_flags;
 	__le16 fc = hdr->frame_control;
-	u8 rc_flags = info->control.rates[0].flags;
 
-	tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+	tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
 		tx_flags |= TX_CMD_FLG_ACK_MSK;
 		if (ieee80211_is_mgmt(fc))
@@ -426,25 +421,19 @@ static void iwl3945_build_tx_cmd_basic(s
 		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 	}
 
-	tx->sta_id = std_id;
+	tx_cmd->sta_id = std_id;
 	if (ieee80211_has_morefrags(fc))
 		tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
 
 	if (ieee80211_is_data_qos(fc)) {
 		u8 *qc = ieee80211_get_qos_ctl(hdr);
-		tx->tid_tspec = qc[0] & 0xf;
+		tx_cmd->tid_tspec = qc[0] & 0xf;
 		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
 	} else {
 		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 	}
 
-	if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-		tx_flags |= TX_CMD_FLG_RTS_MSK;
-		tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-	} else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-		tx_flags &= ~TX_CMD_FLG_RTS_MSK;
-		tx_flags |= TX_CMD_FLG_CTS_MSK;
-	}
+	priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
 
 	if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
 		tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
@@ -452,19 +441,16 @@ static void iwl3945_build_tx_cmd_basic(s
 	tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
 	if (ieee80211_is_mgmt(fc)) {
 		if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
-			tx->timeout.pm_frame_timeout = cpu_to_le16(3);
+			tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
 		else
-			tx->timeout.pm_frame_timeout = cpu_to_le16(2);
+			tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
 	} else {
-		tx->timeout.pm_frame_timeout = 0;
-#ifdef CONFIG_IWLWIFI_LEDS
-		priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
-#endif
+		tx_cmd->timeout.pm_frame_timeout = 0;
 	}
 
-	tx->driver_txop = 0;
-	tx->tx_flags = tx_flags;
-	tx->next_frame_len = 0;
+	tx_cmd->driver_txop = 0;
+	tx_cmd->tx_flags = tx_flags;
+	tx_cmd->next_frame_len = 0;
 }
 
 /*
@@ -474,7 +460,7 @@ static int iwl3945_tx_skb(struct iwl_pri
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct iwl3945_tx_cmd *tx;
+	struct iwl3945_tx_cmd *tx_cmd;
 	struct iwl_tx_queue *txq = NULL;
 	struct iwl_queue *q = NULL;
 	struct iwl_device_cmd *out_cmd;
@@ -562,6 +548,9 @@ static int iwl3945_tx_skb(struct iwl_pri
 	txq = &priv->txq[txq_id];
 	q = &txq->q;
 
+	if ((iwl_queue_space(q) < q->high_mark))
+		goto drop;
+
 	spin_lock_irqsave(&priv->lock, flags);
 
 	idx = get_cmd_index(q, q->write_ptr, 0);
@@ -573,9 +562,9 @@ static int iwl3945_tx_skb(struct iwl_pri
 	/* Init first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[idx];
 	out_meta = &txq->meta[idx];
-	tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
+	tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
-	memset(tx, 0, sizeof(*tx));
+	memset(tx_cmd, 0, sizeof(*tx_cmd));
 
 	/*
 	 * Set up the Tx-command (not MAC!) header.
@@ -588,7 +577,7 @@ static int iwl3945_tx_skb(struct iwl_pri
 				INDEX_TO_SEQ(q->write_ptr)));
 
 	/* Copy MAC header from skb into command buffer */
-	memcpy(tx->hdr, hdr, hdr_len);
+	memcpy(tx_cmd->hdr, hdr, hdr_len);
 
 
 	if (info->control.hw_key)
@@ -602,12 +591,12 @@ static int iwl3945_tx_skb(struct iwl_pri
 
 	/* Total # bytes to be transmitted */
 	len = (u16)skb->len;
-	tx->len = cpu_to_le16(len);
+	tx_cmd->len = cpu_to_le16(len);
 
 	iwl_dbg_log_tx_data_frame(priv, len, hdr);
 	iwl_update_stats(priv, true, fc, len);
-	tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
-	tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+	tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+	tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
 
 	if (!ieee80211_has_morefrags(hdr->frame_control)) {
 		txq->need_update = 1;
@@ -620,9 +609,9 @@ static int iwl3945_tx_skb(struct iwl_pri
 
 	IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
 		     le16_to_cpu(out_cmd->hdr.sequence));
-	IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags));
-	iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
-	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
+	IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
+	iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd));
+	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr,
 			   ieee80211_hdrlen(fc));
 
 	/*
@@ -758,7 +747,7 @@ static int iwl3945_get_measurement(struc
 			       u8 type)
 {
 	struct iwl_spectrum_cmd spectrum;
-	struct iwl_rx_packet *res;
+	struct iwl_rx_packet *pkt;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
 		.data = (void *)&spectrum,
@@ -803,18 +792,18 @@ static int iwl3945_get_measurement(struc
 	if (rc)
 		return rc;
 
-	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
 		rc = -EIO;
 	}
 
-	spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
+	spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status);
 	switch (spectrum_resp_status) {
 	case 0:		/* Command will be handled */
-		if (res->u.spectrum.id != 0xff) {
+		if (pkt->u.spectrum.id != 0xff) {
 			IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
-						res->u.spectrum.id);
+						pkt->u.spectrum.id);
 			priv->measurement_status &= ~MEASUREMENT_READY;
 		}
 		priv->measurement_status |= MEASUREMENT_ACTIVE;
@@ -826,7 +815,7 @@ static int iwl3945_get_measurement(struc
 		break;
 	}
 
-	dev_kfree_skb_any(cmd.reply_skb);
+	iwl_free_pages(priv, cmd.reply_page);
 
 	return rc;
 }
@@ -835,7 +824,7 @@ static int iwl3945_get_measurement(struc
 static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
 			       struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_alive_resp *palive;
 	struct delayed_work *pwork;
 
@@ -872,7 +861,7 @@ static void iwl3945_rx_reply_add_sta(str
 				 struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 #endif
 
 	IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
@@ -908,7 +897,7 @@ static void iwl3945_rx_beacon_notif(stru
 				struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
 	u8 rate = beacon->beacon_notify_hdr.rate;
 
@@ -931,7 +920,7 @@ static void iwl3945_rx_beacon_notif(stru
 static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
 				    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
 
@@ -1095,7 +1084,7 @@ static int iwl3945_rx_queue_restock(stru
 		list_del(element);
 
 		/* Point to Rx buffer via next RBD in circular buffer */
-		rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
+		rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma);
 		rxq->queue[rxq->write] = rxb;
 		rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
 		rxq->free_count--;
@@ -1135,8 +1124,9 @@ static void iwl3945_rx_allocate(struct i
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
-	struct sk_buff *skb;
+	struct page *page;
 	unsigned long flags;
+	gfp_t gfp_mask = priority;
 
 	while (1) {
 		spin_lock_irqsave(&rxq->lock, flags);
@@ -1148,10 +1138,14 @@ static void iwl3945_rx_allocate(struct i
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		if (rxq->free_count > RX_LOW_WATERMARK)
-			priority |= __GFP_NOWARN;
+			gfp_mask |= __GFP_NOWARN;
+
+		if (priv->hw_params.rx_page_order > 0)
+			gfp_mask |= __GFP_COMP;
+
 		/* Alloc a new receive buffer */
-		skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
-		if (!skb) {
+		page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
+		if (!page) {
 			if (net_ratelimit())
 				IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
 			if ((rxq->free_count <= RX_LOW_WATERMARK) &&
@@ -1168,7 +1162,7 @@ static void iwl3945_rx_allocate(struct i
 		spin_lock_irqsave(&rxq->lock, flags);
 		if (list_empty(&rxq->rx_used)) {
 			spin_unlock_irqrestore(&rxq->lock, flags);
-			dev_kfree_skb_any(skb);
+			__free_pages(page, priv->hw_params.rx_page_order);
 			return;
 		}
 		element = rxq->rx_used.next;
@@ -1176,26 +1170,18 @@ static void iwl3945_rx_allocate(struct i
 		list_del(element);
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
-		rxb->skb = skb;
-
-		/* If radiotap head is required, reserve some headroom here.
-		 * The physical head count is a variable rx_stats->phy_count.
-		 * We reserve 4 bytes here. Plus these extra bytes, the
-		 * headroom of the physical head should be enough for the
-		 * radiotap head that iwl3945 supported. See iwl3945_rt.
-		 */
-		skb_reserve(rxb->skb, 4);
-
+		rxb->page = page;
 		/* Get physical address of RB/SKB */
-		rxb->real_dma_addr = pci_map_single(priv->pci_dev,
-						rxb->skb->data,
-						priv->hw_params.rx_buf_size,
-						PCI_DMA_FROMDEVICE);
+		rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
 
 		spin_lock_irqsave(&rxq->lock, flags);
+
 		list_add_tail(&rxb->list, &rxq->rx_free);
-		priv->alloc_rxb_skb++;
 		rxq->free_count++;
+		priv->alloc_rxb_page++;
+
 		spin_unlock_irqrestore(&rxq->lock, flags);
 	}
 }
@@ -1211,14 +1197,12 @@ void iwl3945_rx_queue_reset(struct iwl_p
 	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].skb != NULL) {
-			pci_unmap_single(priv->pci_dev,
-					 rxq->pool[i].real_dma_addr,
-					 priv->hw_params.rx_buf_size,
-					 PCI_DMA_FROMDEVICE);
-			priv->alloc_rxb_skb--;
-			dev_kfree_skb(rxq->pool[i].skb);
-			rxq->pool[i].skb = NULL;
+		if (rxq->pool[i].page != NULL) {
+			pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			__iwl_free_pages(priv, rxq->pool[i].page);
+			rxq->pool[i].page = NULL;
 		}
 		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
 	}
@@ -1226,8 +1210,8 @@ void iwl3945_rx_queue_reset(struct iwl_p
 	/* Set us so that we have processed and used all buffers, but have
 	 * not restocked the Rx queue with fresh buffers */
 	rxq->read = rxq->write = 0;
-	rxq->free_count = 0;
 	rxq->write_actual = 0;
+	rxq->free_count = 0;
 	spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
@@ -1260,12 +1244,12 @@ static void iwl3945_rx_queue_free(struct
 {
 	int i;
 	for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
-		if (rxq->pool[i].skb != NULL) {
-			pci_unmap_single(priv->pci_dev,
-					 rxq->pool[i].real_dma_addr,
-					 priv->hw_params.rx_buf_size,
-					 PCI_DMA_FROMDEVICE);
-			dev_kfree_skb(rxq->pool[i].skb);
+		if (rxq->pool[i].page != NULL) {
+			pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			__iwl_free_pages(priv, rxq->pool[i].page);
+			rxq->pool[i].page = NULL;
 		}
 	}
 
@@ -1315,47 +1299,6 @@ int iwl3945_calc_db_from_ratio(int sig_r
 	return (int)ratio2dB[sig_ratio];
 }
 
-#define PERFECT_RSSI (-20) /* dBm */
-#define WORST_RSSI (-95)   /* dBm */
-#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
-
-/* Calculate an indication of rx signal quality (a percentage, not dBm!).
- * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
- *   about formulas used below. */
-int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
-{
-	int sig_qual;
-	int degradation = PERFECT_RSSI - rssi_dbm;
-
-	/* If we get a noise measurement, use signal-to-noise ratio (SNR)
-	 * as indicator; formula is (signal dbm - noise dbm).
-	 * SNR at or above 40 is a great signal (100%).
-	 * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
-	 * Weakest usable signal is usually 10 - 15 dB SNR. */
-	if (noise_dbm) {
-		if (rssi_dbm - noise_dbm >= 40)
-			return 100;
-		else if (rssi_dbm < noise_dbm)
-			return 0;
-		sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
-
-	/* Else use just the signal level.
-	 * This formula is a least squares fit of data points collected and
-	 *   compared with a reference system that had a percentage (%) display
-	 *   for signal quality. */
-	} else
-		sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
-			    (15 * RSSI_RANGE + 62 * degradation)) /
-			   (RSSI_RANGE * RSSI_RANGE);
-
-	if (sig_qual > 100)
-		sig_qual = 100;
-	else if (sig_qual < 1)
-		sig_qual = 0;
-
-	return sig_qual;
-}
-
 /**
  * iwl3945_rx_handle - Main entry function for receiving responses from uCode
  *
@@ -1381,7 +1324,7 @@ static void iwl3945_rx_handle(struct iwl
 	i = rxq->read;
 
 	/* calculate total frames need to be restock after handling RX */
-	total_empty = r - priv->rxq.write_actual;
+	total_empty = r - rxq->write_actual;
 	if (total_empty < 0)
 		total_empty += RX_QUEUE_SIZE;
 
@@ -1401,10 +1344,13 @@ static void iwl3945_rx_handle(struct iwl
 
 		rxq->queue[i] = NULL;
 
-		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-				priv->hw_params.rx_buf_size,
-				PCI_DMA_FROMDEVICE);
-		pkt = (struct iwl_rx_packet *)rxb->skb->data;
+		pci_unmap_page(priv->pci_dev, rxb->page_dma,
+			       PAGE_SIZE << priv->hw_params.rx_page_order,
+			       PCI_DMA_FROMDEVICE);
+		pkt = rxb_addr(rxb);
+
+		trace_iwlwifi_dev_rx(priv, pkt,
+			le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 		/* Reclaim a command buffer only if this packet is a response
 		 *   to a (driver-originated) command.
@@ -1422,44 +1368,55 @@ static void iwl3945_rx_handle(struct iwl
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
 			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i,
 				get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 		} else {
 			/* No handling needed */
-			IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n",
+			IWL_DEBUG_RX(priv,
+				"r %d i %d No handler needed for %s, 0x%02x\n",
 				r, i, get_cmd_string(pkt->hdr.cmd),
 				pkt->hdr.cmd);
 		}
 
+		/*
+		 * XXX: After here, we should always check rxb->page
+		 * against NULL before touching it or its virtual
+		 * memory (pkt). Because some rx_handler might have
+		 * already taken or freed the pages.
+		 */
+
 		if (reclaim) {
-			/* Invoke any callbacks, transfer the skb to caller, and
-			 * fire off the (possibly) blocking iwl_send_cmd()
+			/* Invoke any callbacks, transfer the buffer to caller,
+			 * and fire off the (possibly) blocking iwl_send_cmd()
 			 * as we reclaim the driver command queue */
-			if (rxb && rxb->skb)
+			if (rxb->page)
 				iwl_tx_cmd_complete(priv, rxb);
 			else
 				IWL_WARN(priv, "Claim null rxb?\n");
 		}
 
-		/* For now we just don't re-use anything.  We can tweak this
-		 * later to try and re-use notification packets and SKBs that
-		 * fail to Rx correctly */
-		if (rxb->skb != NULL) {
-			priv->alloc_rxb_skb--;
-			dev_kfree_skb_any(rxb->skb);
-			rxb->skb = NULL;
-		}
-
+		/* Reuse the page if possible. For notification packets and
+		 * SKBs that fail to Rx correctly, add them back into the
+		 * rx_free list for reuse later. */
 		spin_lock_irqsave(&rxq->lock, flags);
-		list_add_tail(&rxb->list, &priv->rxq.rx_used);
+		if (rxb->page != NULL) {
+			rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
+				0, PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			list_add_tail(&rxb->list, &rxq->rx_free);
+			rxq->free_count++;
+		} else
+			list_add_tail(&rxb->list, &rxq->rx_used);
+
 		spin_unlock_irqrestore(&rxq->lock, flags);
+
 		i = (i + 1) & RX_QUEUE_MASK;
 		/* If there are a lot of unused frames,
 		 * restock the Rx queue so ucode won't assert. */
 		if (fill_rx) {
 			count++;
 			if (count >= 8) {
-				priv->rxq.read = i;
+				rxq->read = i;
 				iwl3945_rx_replenish_now(priv);
 				count = 0;
 			}
@@ -1467,7 +1424,7 @@ static void iwl3945_rx_handle(struct iwl
 	}
 
 	/* Backtrack one entry */
-	priv->rxq.read = i;
+	rxq->read = i;
 	if (fill_rx)
 		iwl3945_rx_replenish_now(priv);
 	else
@@ -1482,7 +1439,6 @@ static inline void iwl_synchronize_irq(s
 	tasklet_kill(&priv->irq_tasklet);
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
 static const char *desc_lookup(int i)
 {
 	switch (i) {
@@ -1551,8 +1507,9 @@ void iwl3945_dump_nic_error_log(struct i
 			"%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
 			desc_lookup(desc), desc, time, blink1, blink2,
 			ilink1, ilink2, data1);
+		trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0,
+					0, blink1, blink2, ilink1, ilink2);
 	}
-
 }
 
 #define EVENT_START_OFFSET  (6 * sizeof(u32))
@@ -1569,6 +1526,7 @@ static void iwl3945_print_event_log(stru
 	u32 event_size;	/* 2 u32s, or 3 u32s if timestamp recorded */
 	u32 ptr;        /* SRAM byte address of log data */
 	u32 ev, time, data; /* event log data */
+	unsigned long reg_flags;
 
 	if (num_events == 0)
 		return;
@@ -1582,25 +1540,71 @@ static void iwl3945_print_event_log(stru
 
 	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
+	/* Make sure device is powered up for SRAM reads */
+	spin_lock_irqsave(&priv->reg_lock, reg_flags);
+	iwl_grab_nic_access(priv);
+
+	/* Set starting address; reads will auto-increment */
+	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+	rmb();
+
 	/* "time" is actually "data" for mode 0 (no timestamp).
 	 * place event id # at far right for easier visual parsing. */
 	for (i = 0; i < num_events; i++) {
-		ev = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
-		time = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
+		ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
 			IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+			trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
 		} else {
-			data = iwl_read_targ_mem(priv, ptr);
-			ptr += sizeof(u32);
+			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 			IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
+			trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
 		}
 	}
+
+	/* Allow device to power down */
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
-void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
+/**
+ * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
+ */
+static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
+				      u32 num_wraps, u32 next_entry,
+				      u32 size, u32 mode)
+{
+	/*
+	 * display the newest DEFAULT_LOG_ENTRIES entries
+	 * i.e the entries just before the next ont that uCode would fill.
+	 */
+	if (num_wraps) {
+		if (next_entry < size) {
+			iwl3945_print_event_log(priv,
+					capacity - (size - next_entry),
+					size - next_entry, mode);
+			iwl3945_print_event_log(priv, 0,
+				    next_entry, mode);
+		} else
+			iwl3945_print_event_log(priv, next_entry - size,
+				    size, mode);
+	} else {
+		if (next_entry < size)
+			iwl3945_print_event_log(priv, 0, next_entry, mode);
+		else
+			iwl3945_print_event_log(priv, next_entry - size,
+					    size, mode);
+	}
+}
+
+/* For sanity check only.  Actual size is determined by uCode, typ. 512 */
+#define IWL3945_MAX_EVENT_LOG_SIZE (512)
+
+#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
+
+void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
 {
 	u32 base;       /* SRAM byte address of event log header */
 	u32 capacity;   /* event log capacity in # entries */
@@ -1621,6 +1625,18 @@ void iwl3945_dump_nic_event_log(struct i
 	num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
 	next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
+	if (capacity > IWL3945_MAX_EVENT_LOG_SIZE) {
+		IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
+			capacity, IWL3945_MAX_EVENT_LOG_SIZE);
+		capacity = IWL3945_MAX_EVENT_LOG_SIZE;
+	}
+
+	if (next_entry > IWL3945_MAX_EVENT_LOG_SIZE) {
+		IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
+			next_entry, IWL3945_MAX_EVENT_LOG_SIZE);
+		next_entry = IWL3945_MAX_EVENT_LOG_SIZE;
+	}
+
 	size = num_wraps ? capacity : next_entry;
 
 	/* bail out if nothing in log */
@@ -1629,30 +1645,40 @@ void iwl3945_dump_nic_event_log(struct i
 		return;
 	}
 
-	IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
-		  size, num_wraps);
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log)
+		size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES)
+			? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size;
+#else
+	size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES)
+		? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size;
+#endif
 
-	/* if uCode has wrapped back to top of log, start at the oldest entry,
-	 * i.e the next one that uCode would fill. */
-	if (num_wraps)
-		iwl3945_print_event_log(priv, next_entry,
-				    capacity - next_entry, mode);
+	IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n",
+		  size);
 
-	/* (then/else) start at top of log */
-	iwl3945_print_event_log(priv, 0, next_entry, mode);
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
+		/* if uCode has wrapped back to top of log,
+		 * start at the oldest entry,
+		 * i.e the next one that uCode would fill.
+		 */
+		if (num_wraps)
+			iwl3945_print_event_log(priv, next_entry,
+				    capacity - next_entry, mode);
 
-}
+		/* (then/else) start at top of log */
+		iwl3945_print_event_log(priv, 0, next_entry, mode);
+	} else
+		iwl3945_print_last_event_logs(priv, capacity, num_wraps,
+					next_entry, size, mode);
 #else
-void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
-{
-}
+	iwl3945_print_last_event_logs(priv, capacity, num_wraps,
+				next_entry, size, mode);
+#endif
 
-void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
-{
 }
 
-#endif
-
 static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 {
 	u32 inta, handled = 0;
@@ -1685,6 +1711,8 @@ static void iwl3945_irq_tasklet(struct i
 	}
 #endif
 
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
 	 * atomic, make sure that inta covers all the interrupts that
 	 * we've discovered, even if FH interrupt came in just after
@@ -1706,8 +1734,6 @@ static void iwl3945_irq_tasklet(struct i
 
 		handled |= CSR_INT_BIT_HW_ERR;
 
-		spin_unlock_irqrestore(&priv->lock, flags);
-
 		return;
 	}
 
@@ -1799,7 +1825,6 @@ static void iwl3945_irq_tasklet(struct i
 			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
 	}
 #endif
-	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
@@ -2158,6 +2183,14 @@ static int iwl3945_read_ucode(struct iwl
 		IWL_UCODE_API(priv->ucode_ver),
 		IWL_UCODE_SERIAL(priv->ucode_ver));
 
+	snprintf(priv->hw->wiphy->fw_version,
+		 sizeof(priv->hw->wiphy->fw_version),
+		 "%u.%u.%u.%u",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver));
+
 	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
 		       priv->ucode_ver);
 	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -2458,7 +2491,7 @@ static void iwl3945_alive_start(struct i
 	priv->active_rate = priv->rates_mask;
 	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-	iwl_power_update_mode(priv, false);
+	iwl_power_update_mode(priv, true);
 
 	if (iwl_is_associated(priv)) {
 		struct iwl3945_rxon_cmd *active_rxon =
@@ -2479,7 +2512,7 @@ static void iwl3945_alive_start(struct i
 
 	iwl3945_reg_txpower_periodic(priv);
 
-	iwl3945_led_register(priv);
+	iwl_leds_init(priv);
 
 	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
 	set_bit(STATUS_READY, &priv->status);
@@ -2517,7 +2550,6 @@ static void __iwl3945_down(struct iwl_pr
 	if (!exit_pending)
 		set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	iwl3945_led_unregister(priv);
 	iwl_clear_stations_table(priv);
 
 	/* Unblock any waiting calls */
@@ -2563,23 +2595,15 @@ static void __iwl3945_down(struct iwl_pr
 			test_bit(STATUS_EXIT_PENDING, &priv->status) <<
 				STATUS_EXIT_PENDING;
 
-	priv->cfg->ops->lib->apm_ops.reset(priv);
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	iwl3945_hw_txq_ctx_stop(priv);
 	iwl3945_hw_rxq_stop(priv);
 
-	iwl_write_prph(priv, APMG_CLK_DIS_REG,
-				APMG_CLK_VAL_DMA_CLK_RQT);
-
+	/* Power-down device's busmaster DMA clocks */
+	iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 	udelay(5);
 
-	if (exit_pending)
-		priv->cfg->ops->lib->apm_ops.stop(priv);
-	else
-		priv->cfg->ops->lib->apm_ops.reset(priv);
+	/* Stop the device, and put it in low power state */
+	priv->cfg->ops->lib->apm_ops.stop(priv);
 
  exit:
 	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
@@ -2724,19 +2748,34 @@ static void iwl3945_bg_alive_start(struc
 	mutex_unlock(&priv->mutex);
 }
 
+/*
+ * 3945 cannot interrupt driver when hardware rf kill switch toggles;
+ * driver must poll CSR_GP_CNTRL_REG register for change.  This register
+ * *is* readable even when device has been SW_RESET into low power mode
+ * (e.g. during RF KILL).
+ */
 static void iwl3945_rfkill_poll(struct work_struct *data)
 {
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, rfkill_poll.work);
+	bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status);
+	bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL)
+			& CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
 
-	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-		clear_bit(STATUS_RF_KILL_HW, &priv->status);
-	else
-		set_bit(STATUS_RF_KILL_HW, &priv->status);
+	if (new_rfkill != old_rfkill) {
+		if (new_rfkill)
+			set_bit(STATUS_RF_KILL_HW, &priv->status);
+		else
+			clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
-	wiphy_rfkill_set_hw_state(priv->hw->wiphy,
-			test_bit(STATUS_RF_KILL_HW, &priv->status));
+		wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill);
+
+		IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+				new_rfkill ? "disable radio" : "enable radio");
+	}
 
+	/* Keep this running, even if radio now enabled.  This will be
+	 * cancelled in mac_start() if system decides to start again */
 	queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
 			   round_jiffies_relative(2 * HZ));
 
@@ -3152,6 +3191,8 @@ static int iwl3945_mac_start(struct ieee
 	 * no need to poll the killswitch state anymore */
 	cancel_delayed_work(&priv->rfkill_poll);
 
+	iwl_led_start(priv);
+
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
@@ -3606,7 +3647,7 @@ static ssize_t show_statistics(struct de
 		return -EAGAIN;
 
 	mutex_lock(&priv->mutex);
-	rc = iwl_send_statistics_request(priv, 0);
+	rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
 	mutex_unlock(&priv->mutex);
 
 	if (rc) {
@@ -3784,7 +3825,6 @@ static int iwl3945_init_drv(struct iwl_p
 	priv->retry_rate = 1;
 	priv->ibss_beacon = NULL;
 
-	spin_lock_init(&priv->lock);
 	spin_lock_init(&priv->sta_lock);
 	spin_lock_init(&priv->hcmd_lock);
 
@@ -3795,7 +3835,6 @@ static int iwl3945_init_drv(struct iwl_p
 	/* Clear the driver's (not device's) station table */
 	iwl_clear_stations_table(priv);
 
-	priv->data_retry_limit = -1;
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
 	priv->band = IEEE80211_BAND_2GHZ;
@@ -3854,18 +3893,18 @@ static int iwl3945_setup_mac(struct iwl_
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		    IEEE80211_HW_NOISE_DBM |
-		    IEEE80211_HW_SPECTRUM_MGMT |
-		    IEEE80211_HW_SUPPORTS_PS |
-		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+		    IEEE80211_HW_SPECTRUM_MGMT;
+
+	if (!priv->cfg->broken_powersave)
+		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->wiphy->custom_regulatory = true;
-
-	/* Firmware does not support this */
-	hw->wiphy->disable_beacon_hints = true;
+	hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+			    WIPHY_FLAG_DISABLE_BEACON_HINTS;
 
 	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
 	/* we create the 802.11 header and a zero-length SSID element */
@@ -3977,17 +4016,11 @@ static int iwl3945_pci_probe(struct pci_
 	 * PCI Tx retries from interfering with C3 CPU state */
 	pci_write_config_byte(pdev, 0x41, 0x00);
 
-	/* this spin lock will be used in apm_ops.init and EEPROM access
+	/* these spin locks will be used in apm_ops.init and EEPROM access
 	 * we should init now
 	 */
 	spin_lock_init(&priv->reg_lock);
-
-	/* amp init */
-	err = priv->cfg->ops->lib->apm_ops.init(priv);
-	if (err < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out_iounmap;
-	}
+	spin_lock_init(&priv->lock);
 
 	/***********************
 	 * 4. Read EEPROM
@@ -4054,6 +4087,7 @@ static int iwl3945_pci_probe(struct pci_
 			     &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
 	iwl3945_setup_deferred_work(priv);
 	iwl3945_setup_rx_handlers(priv);
+	iwl_power_initialize(priv);
 
 	/*********************************
 	 * 8. Setup and Register mac80211
@@ -4124,6 +4158,15 @@ static void __devexit iwl3945_pci_remove
 		iwl3945_down(priv);
 	}
 
+	/*
+	 * Make sure device is reset to low power before unloading driver.
+	 * This may be redundant with iwl_down(), but there are paths to
+	 * run iwl_down() without calling apm_ops.stop(), and there are
+	 * paths to avoid running iwl_down() at all before leaving driver.
+	 * This (inexpensive) call *makes sure* device is reset.
+	 */
+	priv->cfg->ops->lib->apm_ops.stop(priv);
+
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
 	 */
@@ -4226,18 +4269,19 @@ static void __exit iwl3945_exit(void)
 
 /*(DEBLOBBED)*/
 
-module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
+module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
+module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO);
 MODULE_PARM_DESC(swcrypto,
 		 "using software crypto (default 1 [software])\n");
 #ifdef CONFIG_IWLWIFI_DEBUG
-module_param_named(debug, iwl_debug_level, uint, 0644);
+module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "debug output mask");
 #endif
-module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
+		   int, S_IRUGO);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
 
 module_exit(iwl3945_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,8 @@
 #include "iwl-eeprom.h"
 #include "iwl-helpers.h"
 #include "iwl-core.h"
-#include "iwl-agn-rs.h"
+#include "iwl-led.h"
+#include "iwl-3945-led.h"
 
 #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
 	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,   \
@@ -293,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(str
 static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
 			    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
@@ -353,16 +354,12 @@ static void iwl3945_rx_reply_tx(struct i
 void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
 		struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(struct iwl3945_notif_statistics),
 		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 	memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
-
-	iwl3945_led_background(priv);
-
-	priv->last_statistics_time = jiffies;
 }
 
 /******************************************************************************
@@ -545,14 +542,18 @@ static void iwl3945_pass_packet_to_mac80
 				   struct iwl_rx_mem_buffer *rxb,
 				   struct ieee80211_rx_status *stats)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
 	struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
 	struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
-	short len = le16_to_cpu(rx_hdr->len);
+	u16 len = le16_to_cpu(rx_hdr->len);
+	struct sk_buff *skb;
+	int ret;
+	__le16 fc = hdr->frame_control;
 
 	/* We received data from the HW, so stop the watchdog */
-	if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+	if (unlikely(len + IWL39_RX_FRAME_SIZE >
+		     PAGE_SIZE << priv->hw_params.rx_page_order)) {
 		IWL_DEBUG_DROP(priv, "Corruption detected!\n");
 		return;
 	}
@@ -564,24 +565,50 @@ static void iwl3945_pass_packet_to_mac80
 		return;
 	}
 
-	skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt);
-	/* Set the size of the skb to the size of the frame */
-	skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
+	skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
+	if (!skb) {
+		IWL_ERR(priv, "alloc_skb failed\n");
+		return;
+	}
 
 	if (!iwl3945_mod_params.sw_crypto)
 		iwl_set_decrypted_flag(priv,
-				       (struct ieee80211_hdr *)rxb->skb->data,
+				       (struct ieee80211_hdr *)rxb_addr(rxb),
 				       le32_to_cpu(rx_end->status), stats);
 
-#ifdef CONFIG_IWLWIFI_LEDS
-	if (ieee80211_is_data(hdr->frame_control))
-		priv->rxtxpackets += len;
-#endif
-	iwl_update_stats(priv, false, hdr->frame_control, len);
+	skb_reserve(skb, IWL_LINK_HDR_MAX);
+	skb_add_rx_frag(skb, 0, rxb->page,
+			(void *)rx_hdr->payload - (void *)pkt, len);
 
-	memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
-	ieee80211_rx_irqsafe(priv->hw, rxb->skb);
-	rxb->skb = NULL;
+	/* mac80211 currently doesn't support paged SKB. Convert it to
+	 * linear SKB for management frame and data frame requires
+	 * software decryption or software defragementation. */
+	if (ieee80211_is_mgmt(fc) ||
+	    ieee80211_has_protected(fc) ||
+	    ieee80211_has_morefrags(fc) ||
+	    le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
+		ret = skb_linearize(skb);
+	else
+		ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
+			0 : -ENOMEM;
+
+	if (ret) {
+		kfree_skb(skb);
+		goto out;
+	}
+
+	/*
+	 * XXX: We cannot touch the page and its virtual memory (pkt) after
+	 * here. It might have already been freed by the above skb change.
+	 */
+
+	iwl_update_stats(priv, false, fc, len);
+	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
+
+	ieee80211_rx(priv->hw, skb);
+ out:
+	priv->alloc_rxb_page--;
+	rxb->page = NULL;
 }
 
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@ -591,7 +618,7 @@ static void iwl3945_rx_reply_rx(struct i
 {
 	struct ieee80211_hdr *header;
 	struct ieee80211_rx_status rx_status;
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
 	struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
 	struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
@@ -654,19 +681,13 @@ static void iwl3945_rx_reply_rx(struct i
 		snr = rx_stats_sig_avg / rx_stats_noise_diff;
 		rx_status.noise = rx_status.signal -
 					iwl3945_calc_db_from_ratio(snr);
-		rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal,
-							 rx_status.noise);
-
-	/* If noise info not available, calculate signal quality indicator (%)
-	 *   using just the dBm signal level. */
 	} else {
 		rx_status.noise = priv->last_rx_noise;
-		rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0);
 	}
 
 
-	IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
-			rx_status.signal, rx_status.noise, rx_status.qual,
+	IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n",
+			rx_status.signal, rx_status.noise,
 			rx_stats_sig_avg, rx_stats_noise_diff);
 
 	header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
@@ -791,29 +812,31 @@ void iwl3945_hw_build_tx_cmd_rate(struct
 	u8 data_retry_limit;
 	__le32 tx_flags;
 	__le16 fc = hdr->frame_control;
-	struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+	struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 
 	rate = iwl3945_rates[rate_index].plcp;
-	tx_flags = tx->tx_flags;
+	tx_flags = tx_cmd->tx_flags;
 
 	/* We need to figure out how to get the sta->supp_rates while
 	 * in this running context */
 	rate_mask = IWL_RATES_MASK;
 
+
+	/* Set retry limit on DATA packets and Probe Responses*/
+	if (ieee80211_is_probe_resp(fc))
+		data_retry_limit = 3;
+	else
+		data_retry_limit = IWL_DEFAULT_TX_RETRY;
+	tx_cmd->data_retry_limit = data_retry_limit;
+
 	if (tx_id >= IWL_CMD_QUEUE_NUM)
 		rts_retry_limit = 3;
 	else
 		rts_retry_limit = 7;
 
-	if (ieee80211_is_probe_resp(fc)) {
-		data_retry_limit = 3;
-		if (data_retry_limit < rts_retry_limit)
-			rts_retry_limit = data_retry_limit;
-	} else
-		data_retry_limit = IWL_DEFAULT_TX_RETRY;
-
-	if (priv->data_retry_limit != -1)
-		data_retry_limit = priv->data_retry_limit;
+	if (data_retry_limit < rts_retry_limit)
+		rts_retry_limit = data_retry_limit;
+	tx_cmd->rts_retry_limit = rts_retry_limit;
 
 	if (ieee80211_is_mgmt(fc)) {
 		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
@@ -831,22 +854,20 @@ void iwl3945_hw_build_tx_cmd_rate(struct
 		}
 	}
 
-	tx->rts_retry_limit = rts_retry_limit;
-	tx->data_retry_limit = data_retry_limit;
-	tx->rate = rate;
-	tx->tx_flags = tx_flags;
+	tx_cmd->rate = rate;
+	tx_cmd->tx_flags = tx_flags;
 
 	/* OFDM */
-	tx->supp_rates[0] =
+	tx_cmd->supp_rates[0] =
 	   ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
 
 	/* CCK */
-	tx->supp_rates[1] = (rate_mask & 0xF);
+	tx_cmd->supp_rates[1] = (rate_mask & 0xF);
 
 	IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
 		       "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
-		       tx->rate, le32_to_cpu(tx->tx_flags),
-		       tx->supp_rates[1], tx->supp_rates[0]);
+		       tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags),
+		       tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
 }
 
 u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
@@ -962,6 +983,11 @@ static int iwl3945_txq_ctx_reset(struct
 
 	iwl3945_hw_txq_ctx_free(priv);
 
+	/* allocate tx queue structure */
+	rc = iwl_alloc_txq_mem(priv);
+	if (rc)
+		return rc;
+
 	/* Tx CMD queue */
 	rc = iwl3945_tx_reset(priv);
 	if (rc)
@@ -986,41 +1012,25 @@ static int iwl3945_txq_ctx_reset(struct
 	return rc;
 }
 
+
+/*
+ * Start up 3945's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * NOTE:  This does not load uCode nor start the embedded processor
+ */
 static int iwl3945_apm_init(struct iwl_priv *priv)
 {
-	int ret;
-
-	iwl_power_initialize(priv);
-
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* set "initialization complete" bit to move adapter
-	* D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			    CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
-						APMG_CLK_VAL_BSM_CLK_RQT);
+	int ret = iwl_apm_init(priv);
 
-	udelay(20);
+	/* Clear APMG (NIC's internal power management) interrupts */
+	iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+	iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);
 
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+	/* Reset radio chip */
+	iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
+	udelay(5);
+	iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
 
-out:
 	return ret;
 }
 
@@ -1145,12 +1155,16 @@ void iwl3945_hw_txq_ctx_free(struct iwl_
 	int txq_id;
 
 	/* Tx queues */
-	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-		if (txq_id == IWL_CMD_QUEUE_NUM)
-			iwl_cmd_queue_free(priv);
-		else
-			iwl_tx_queue_free(priv, txq_id);
+	if (priv->txq)
+		for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
+		     txq_id++)
+			if (txq_id == IWL_CMD_QUEUE_NUM)
+				iwl_cmd_queue_free(priv);
+			else
+				iwl_tx_queue_free(priv, txq_id);
 
+	/* free tx queue structure */
+	iwl_free_txq_mem(priv);
 }
 
 void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -1159,6 +1173,7 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_
 
 	/* stop SCD */
 	iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
+	iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0);
 
 	/* reset TFD queues */
 	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
@@ -1171,85 +1186,6 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_
 	iwl3945_hw_txq_ctx_free(priv);
 }
 
-static int iwl3945_apm_stop_master(struct iwl_priv *priv)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* set stop master bit */
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
-
-	iwl_poll_direct_bit(priv, CSR_RESET,
-			    CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-
-	if (ret < 0)
-		goto out;
-
-out:
-	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO(priv, "stop master\n");
-
-	return ret;
-}
-
-static void iwl3945_apm_stop(struct iwl_priv *priv)
-{
-	unsigned long flags;
-
-	iwl3945_apm_stop_master(priv);
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-	/* clear "init complete"  move adapter D0A* --> D0U state */
-	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int iwl3945_apm_reset(struct iwl_priv *priv)
-{
-	iwl3945_apm_stop_master(priv);
-
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-	udelay(10);
-
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-
-	iwl_write_prph(priv, APMG_CLK_CTRL_REG,
-				APMG_CLK_VAL_BSM_CLK_RQT);
-
-	iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
-	iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
-					0xFFFFFFFF);
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_EN_REG,
-				APMG_CLK_VAL_DMA_CLK_RQT |
-				APMG_CLK_VAL_BSM_CLK_RQT);
-	udelay(10);
-
-	iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
-				APMG_PS_CTRL_VAL_RESET_REQ);
-	udelay(5);
-	iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
-				APMG_PS_CTRL_VAL_RESET_REQ);
-
-	/* Clear the 'host command active' bit... */
-	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	return 0;
-}
-
 /**
  * iwl3945_hw_reg_adjust_power_by_temp
  * return index delta into power gain settings table
@@ -1858,7 +1794,7 @@ int iwl3945_hw_reg_set_txpower(struct iw
 static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
 {
 	int rc = 0;
-	struct iwl_rx_packet *res = NULL;
+	struct iwl_rx_packet *pkt;
 	struct iwl3945_rxon_assoc_cmd rxon_assoc;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_RXON_ASSOC,
@@ -1887,14 +1823,13 @@ static int iwl3945_send_rxon_assoc(struc
 	if (rc)
 		return rc;
 
-	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
 		rc = -EIO;
 	}
 
-	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.reply_skb);
+	iwl_free_pages(priv, cmd.reply_page);
 
 	return rc;
 }
@@ -2042,12 +1977,6 @@ static int iwl3945_commit_rxon(struct iw
 	return 0;
 }
 
-/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
-{
-	return 0;
-}
-
 /**
  * iwl3945_reg_txpower_periodic -  called when time to check our temperature.
  *
@@ -2557,11 +2486,10 @@ int iwl3945_hw_set_hw_params(struct iwl_
 	}
 
 	/* Assign number of Usable TX queues */
-	priv->hw_params.max_txq_num = IWL39_NUM_QUEUES;
+	priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
 
 	priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
-	priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
-	priv->hw_params.max_pkt_size = 2342;
+	priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
 	priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
 	priv->hw_params.max_stations = IWL3945_STATION_COUNT;
@@ -2844,8 +2772,7 @@ static struct iwl_lib_ops iwl3945_lib =
 	.dump_nic_error_log = iwl3945_dump_nic_error_log,
 	.apm_ops = {
 		.init = iwl3945_apm_init,
-		.reset = iwl3945_apm_reset,
-		.stop = iwl3945_apm_stop,
+		.stop = iwl_apm_stop,
 		.config = iwl3945_nic_config,
 		.set_pwr_src = iwl3945_set_pwr_src,
 	},
@@ -2874,6 +2801,7 @@ static struct iwl_lib_ops iwl3945_lib =
 static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
 	.get_hcmd_size = iwl3945_get_hcmd_size,
 	.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+	.rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
 };
 
 static struct iwl_ops iwl3945_ops = {
@@ -2881,6 +2809,7 @@ static struct iwl_ops iwl3945_ops = {
 	.lib = &iwl3945_lib,
 	.hcmd = &iwl3945_hcmd,
 	.utils = &iwl3945_hcmd_utils,
+	.led = &iwl3945_led_ops,
 };
 
 static struct iwl_cfg iwl3945_bg_cfg = {
@@ -2892,9 +2821,15 @@ static struct iwl_cfg iwl3945_bg_cfg = {
 	.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
 	.ops = &iwl3945_ops,
+	.num_of_queues = IWL39_NUM_QUEUES,
 	.mod_params = &iwl3945_mod_params,
+	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = true,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
+	.led_compensation = 64,
+	.broken_powersave = true,
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2906,9 +2841,12 @@ static struct iwl_cfg iwl3945_abg_cfg =
 	.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
 	.ops = &iwl3945_ops,
+	.num_of_queues = IWL39_NUM_QUEUES,
 	.mod_params = &iwl3945_mod_params,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
+	.led_compensation = 64,
+	.broken_powersave = true,
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 14:02:18.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 12:09:50.000000000 -0400
@@ -46,7 +46,7 @@ extern struct pci_device_id iwl3945_hw_c
 #include "iwl-debug.h"
 #include "iwl-power.h"
 #include "iwl-dev.h"
-#include "iwl-3945-led.h"
+#include "iwl-led.h"
 
 /* Highest firmware API version supported */
 #define IWL3945_UCODE_API_MAX 2
@@ -74,8 +74,41 @@ extern struct pci_device_id iwl3945_hw_c
 /* Module parameters accessible from iwl-*.c */
 extern struct iwl_mod_params iwl3945_mod_params;
 
+struct iwl3945_rate_scale_data {
+	u64 data;
+	s32 success_counter;
+	s32 success_ratio;
+	s32 counter;
+	s32 average_tpt;
+	unsigned long stamp;
+};
+
+struct iwl3945_rs_sta {
+	spinlock_t lock;
+	struct iwl_priv *priv;
+	s32 *expected_tpt;
+	unsigned long last_partial_flush;
+	unsigned long last_flush;
+	u32 flush_time;
+	u32 last_tx_packets;
+	u32 tx_packets;
+	u8 tgg;
+	u8 flush_pending;
+	u8 start_rate;
+	u8 ibss_sta_added;
+	struct timer_list rate_scale_flush;
+	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
+#ifdef CONFIG_MAC80211_DEBUGFS
+	struct dentry *rs_sta_dbgfs_stats_table_file;
+#endif
+
+	/* used to be in sta_info */
+	int last_txrate_idx;
+};
+
+
 struct iwl3945_sta_priv {
-	struct iwl3945_rs_sta *rs_sta;
+	struct iwl3945_rs_sta rs_sta;
 };
 
 enum iwl3945_antenna {
@@ -130,12 +163,6 @@ struct iwl3945_frame {
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
 
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
 #define SUP_RATE_11A_MAX_NUM_CHANNELS  8
 #define SUP_RATE_11B_MAX_NUM_CHANNELS  4
 #define SUP_RATE_11G_MAX_NUM_CHANNELS  12
@@ -194,22 +221,12 @@ struct iwl3945_ibss_seq {
  * for use by iwl-*.c
  *
  *****************************************************************************/
-extern int iwl3945_power_init_handle(struct iwl_priv *priv);
-extern int iwl3945_eeprom_init(struct iwl_priv *priv);
 extern int iwl3945_calc_db_from_ratio(int sig_ratio);
-extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
-			     struct iwl_tx_queue *txq, int count, u32 id);
 extern void iwl3945_rx_replenish(void *data);
 extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
-extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
-			    const void *data);
-extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
-					 struct iwl_host_cmd *cmd);
 extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
 					struct ieee80211_hdr *hdr,int left);
-extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv);
+extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
 extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
 
 /*
@@ -280,8 +297,6 @@ extern void iwl3945_config_ap(struct iwl
  */
 extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
 
-extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
-
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,12 +71,6 @@
 
 #include "iwl-eeprom.h"
 
-/*
- * uCode queue management definitions ...
- * Queue #4 is the command queue for 3945 and 4965.
- */
-#define IWL_CMD_QUEUE_NUM	4
-
 /* Time constants */
 #define SHORT_SLOT_TIME 9
 #define LONG_SLOT_TIME 20
@@ -254,12 +248,6 @@ struct iwl3945_eeprom {
 #define TFD_CTL_PAD_SET(n)         (n << 28)
 #define TFD_CTL_PAD_GET(ctl)       (ctl >> 28)
 
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
 /* Sizes and addresses for instruction and data memory (SRAM) in
  * 3945's embedded processor.  Driver access is via HBUS_TARG_MEM_* regs. */
 #define IWL39_RTC_INST_LOWER_BOUND		(0x000000)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,8 +24,6 @@
  *
  *****************************************************************************/
 
-#ifdef CONFIG_IWLWIFI_LEDS
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -43,388 +41,51 @@
 #include "iwl-3945.h"
 #include "iwl-core.h"
 #include "iwl-dev.h"
+#include "iwl-3945-led.h"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static const char *led_type_str[] = {
-	__stringify(IWL_LED_TRG_TX),
-	__stringify(IWL_LED_TRG_RX),
-	__stringify(IWL_LED_TRG_ASSOC),
-	__stringify(IWL_LED_TRG_RADIO),
-	NULL
-};
-#endif /* CONFIG_IWLWIFI_DEBUG */
-
-static const struct {
-	u16 brightness;
-	u8 on_time;
-	u8 off_time;
-} blink_tbl[] =
-{
-	{300, 25, 25},
-	{200, 40, 40},
-	{100, 55, 55},
-	{70, 65, 65},
-	{50, 75, 75},
-	{20, 85, 85},
-	{15, 95, 95 },
-	{10, 110, 110},
-	{5, 130, 130},
-	{0, 167, 167},
-	/* SOLID_ON */
-	{-1, IWL_LED_SOLID, 0}
-};
-
-#define IWL_1MB_RATE (128 * 1024)
-#define IWL_LED_THRESHOLD (16)
-#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
-#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
-
-static void iwl3945_led_cmd_callback(struct iwl_priv *priv,
-				     struct iwl_device_cmd *cmd,
-				     struct sk_buff *skb)
-{
-}
-
-static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
-{
-	return fls(0x000000FF & (u32)brightness);
-}
 
 /* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv,
-			    struct iwl_led_cmd *led_cmd)
+static int iwl3945_send_led_cmd(struct iwl_priv *priv,
+				struct iwl_led_cmd *led_cmd)
 {
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_LEDS_CMD,
 		.len = sizeof(struct iwl_led_cmd),
 		.data = led_cmd,
 		.flags = CMD_ASYNC,
-		.callback = iwl3945_led_cmd_callback,
+		.callback = NULL,
 	};
 
 	return iwl_send_cmd(priv, &cmd);
 }
 
-
-
-/* Set led on command */
-static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
-			       unsigned int idx)
-{
-	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
-		.interval = IWL_DEF_LED_INTRVL
-	};
-
-	BUG_ON(idx > IWL_MAX_BLINK_TBL);
-
-	led_cmd.on = blink_tbl[idx].on_time;
-	led_cmd.off = blink_tbl[idx].off_time;
-
-	return iwl_send_led_cmd(priv, &led_cmd);
-}
-
-
 /* Set led on command */
-static int iwl3945_led_on(struct iwl_priv *priv, int led_id)
+static int iwl3945_led_on(struct iwl_priv *priv)
 {
 	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
+		.id = IWL_LED_LINK,
 		.on = IWL_LED_SOLID,
 		.off = 0,
 		.interval = IWL_DEF_LED_INTRVL
 	};
-	return iwl_send_led_cmd(priv, &led_cmd);
+	return iwl3945_send_led_cmd(priv, &led_cmd);
 }
 
 /* Set led off command */
-static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
+static int iwl3945_led_off(struct iwl_priv *priv)
 {
 	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
+		.id = IWL_LED_LINK,
 		.on = 0,
 		.off = 0,
 		.interval = IWL_DEF_LED_INTRVL
 	};
-	IWL_DEBUG_LED(priv, "led off %d\n", led_id);
-	return iwl_send_led_cmd(priv, &led_cmd);
-}
-
-/*
- *  Set led on in case of association
- *  */
-static int iwl3945_led_associate(struct iwl_priv *priv, int led_id)
-{
-	IWL_DEBUG_LED(priv, "Associated\n");
-
-	priv->allow_blinking = 1;
-	return iwl3945_led_on(priv, led_id);
-}
-/* Set Led off in case of disassociation */
-static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
-{
-	IWL_DEBUG_LED(priv, "Disassociated\n");
-
-	priv->allow_blinking = 0;
-
-	return 0;
-}
-
-/*
- * brightness call back function for Tx/Rx LED
- */
-static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
-{
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
-	    !test_bit(STATUS_READY, &priv->status))
-		return 0;
-
-
-	/* start counting Tx/Rx bytes */
-	if (!priv->last_blink_time && priv->allow_blinking)
-		priv->last_blink_time = jiffies;
-	return 0;
-}
-
-/*
- * brightness call back for association and radio
- */
-static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
-				enum led_brightness brightness)
-{
-	struct iwl_led *led = container_of(led_cdev,
-					   struct iwl_led, led_dev);
-	struct iwl_priv *priv = led->priv;
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
-			led_type_str[led->type], brightness);
-
-	switch (brightness) {
-	case LED_FULL:
-		if (led->led_on)
-			led->led_on(priv, IWL_LED_LINK);
-		break;
-	case LED_OFF:
-		if (led->led_off)
-			led->led_off(priv, IWL_LED_LINK);
-		break;
-	default:
-		if (led->led_pattern) {
-			int idx = iwl3945_brightness_to_idx(brightness);
-			led->led_pattern(priv, IWL_LED_LINK, idx);
-		}
-		break;
-	}
-}
-
-/*
- * Register led class with the system
- */
-static int iwl3945_led_register_led(struct iwl_priv *priv,
-				   struct iwl_led *led,
-				   enum led_type type, u8 set_led,
-				   char *trigger)
-{
-	struct device *device = wiphy_dev(priv->hw->wiphy);
-	int ret;
-
-	led->led_dev.name = led->name;
-	led->led_dev.brightness_set = iwl3945_led_brightness_set;
-	led->led_dev.default_trigger = trigger;
-
-	led->priv = priv;
-	led->type = type;
-
-	ret = led_classdev_register(device, &led->led_dev);
-	if (ret) {
-		IWL_ERR(priv, "Error: failed to register led handler.\n");
-		return ret;
-	}
-
-	led->registered = 1;
-
-	if (set_led && led->led_on)
-		led->led_on(priv, IWL_LED_LINK);
-	return 0;
-}
-
-
-/*
- * calculate blink rate according to last 2 sec Tx/Rx activities
- */
-static inline u8 get_blink_rate(struct iwl_priv *priv)
-{
-	int index;
-	s64 tpt = priv->rxtxpackets;
-
-	if (tpt < 0)
-		tpt = -tpt;
-
-	IWL_DEBUG_LED(priv, "tpt %lld \n", (long long)tpt);
-
-	if (!priv->allow_blinking)
-		index = IWL_MAX_BLINK_TBL;
-	else
-		for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
-			if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
-				break;
-
-	IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", index);
-	return index;
-}
-
-/*
- * this function called from handler. Since setting Led command can
- * happen very frequent we postpone led command to be called from
- * REPLY handler so we know ucode is up
- */
-void iwl3945_led_background(struct iwl_priv *priv)
-{
-	u8 blink_idx;
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		priv->last_blink_time = 0;
-		return;
-	}
-	if (iwl_is_rfkill(priv)) {
-		priv->last_blink_time = 0;
-		return;
-	}
-
-	if (!priv->allow_blinking) {
-		priv->last_blink_time = 0;
-		if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
-			priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
-			iwl3945_led_pattern(priv, IWL_LED_LINK,
-					    IWL_SOLID_BLINK_IDX);
-		}
-		return;
-	}
-	if (!priv->last_blink_time ||
-	    !time_after(jiffies, priv->last_blink_time +
-			msecs_to_jiffies(1000)))
-		return;
-
-	blink_idx = get_blink_rate(priv);
-
-	/* call only if blink rate change */
-	if (blink_idx != priv->last_blink_rate)
-		iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx);
-
-	priv->last_blink_time = jiffies;
-	priv->last_blink_rate = blink_idx;
-	priv->rxtxpackets = 0;
-}
-
-
-/* Register all led handler */
-int iwl3945_led_register(struct iwl_priv *priv)
-{
-	char *trigger;
-	int ret;
-
-	priv->last_blink_rate = 0;
-	priv->rxtxpackets = 0;
-	priv->led_tpt = 0;
-	priv->last_blink_time = 0;
-	priv->allow_blinking = 0;
-
-	trigger = ieee80211_get_radio_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
-		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
-		 wiphy_name(priv->hw->wiphy));
-
-	priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
-	priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
-	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
-
-	ret = iwl3945_led_register_led(priv,
-				   &priv->led[IWL_LED_TRG_RADIO],
-				   IWL_LED_TRG_RADIO, 1, trigger);
-
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_assoc_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
-		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl3945_led_register_led(priv,
-				   &priv->led[IWL_LED_TRG_ASSOC],
-				   IWL_LED_TRG_ASSOC, 0, trigger);
-
-	/* for assoc always turn led on */
-	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_associate;
-	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_disassociate;
-	priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
-
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_rx_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_RX].name,
-		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl3945_led_register_led(priv,
-				   &priv->led[IWL_LED_TRG_RX],
-				   IWL_LED_TRG_RX, 0, trigger);
-
-	priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
-	priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
-	priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
-
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_tx_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_TX].name,
-		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl3945_led_register_led(priv,
-				   &priv->led[IWL_LED_TRG_TX],
-				   IWL_LED_TRG_TX, 0, trigger);
-
-	priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
-	priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
-	priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
-
-	if (ret)
-		goto exit_fail;
-
-	return 0;
-
-exit_fail:
-	iwl3945_led_unregister(priv);
-	return ret;
-}
-
-
-/* unregister led class */
-static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
-{
-	if (!led->registered)
-		return;
-
-	led_classdev_unregister(&led->led_dev);
-
-	if (set_led)
-		led->led_dev.brightness_set(&led->led_dev, LED_OFF);
-	led->registered = 0;
-}
-
-/* Unregister all led handlers */
-void iwl3945_led_unregister(struct iwl_priv *priv)
-{
-	iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
-	iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
-	iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
-	iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
+	IWL_DEBUG_LED(priv, "led off\n");
+	return iwl3945_send_led_cmd(priv, &led_cmd);
 }
 
-#endif
+const struct iwl_led_ops iwl3945_led_ops = {
+	.cmd = iwl3945_send_led_cmd,
+	.on = iwl3945_led_on,
+	.off = iwl3945_led_off,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,23 +24,9 @@
  *
  *****************************************************************************/
 
-#ifndef IWL3945_LEDS_H
-#define IWL3945_LEDS_H
-
-struct iwl_priv;
-
-#ifdef CONFIG_IWLWIFI_LEDS
-
-#include "iwl-led.h"
-
-extern int iwl3945_led_register(struct iwl_priv *priv);
-extern void iwl3945_led_unregister(struct iwl_priv *priv);
-extern void iwl3945_led_background(struct iwl_priv *priv);
+#ifndef __iwl_3945_led_h__
+#define __iwl_3945_led_h__
 
-#else
-static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
-static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
-static inline void iwl3945_led_background(struct iwl_priv *priv) {}
+extern const struct iwl_led_ops iwl3945_led_ops;
 
-#endif /* IWLWIFI_LEDS*/
-#endif /* IWL3945_LEDS_H */
+#endif /* __iwl_3945_led_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,38 +42,6 @@
 
 #define RS_NAME "iwl-3945-rs"
 
-struct iwl3945_rate_scale_data {
-	u64 data;
-	s32 success_counter;
-	s32 success_ratio;
-	s32 counter;
-	s32 average_tpt;
-	unsigned long stamp;
-};
-
-struct iwl3945_rs_sta {
-	spinlock_t lock;
-	struct iwl_priv *priv;
-	s32 *expected_tpt;
-	unsigned long last_partial_flush;
-	unsigned long last_flush;
-	u32 flush_time;
-	u32 last_tx_packets;
-	u32 tx_packets;
-	u8 tgg;
-	u8 flush_pending;
-	u8 start_rate;
-	u8 ibss_sta_added;
-	struct timer_list rate_scale_flush;
-	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
-#ifdef CONFIG_MAC80211_DEBUGFS
-	struct dentry *rs_sta_dbgfs_stats_table_file;
-#endif
-
-	/* used to be in sta_info */
-	int last_txrate_idx;
-};
-
 static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
 	7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
 };
@@ -370,6 +338,28 @@ static void rs_rate_init(void *priv_r, s
 
 	IWL_DEBUG_RATE(priv, "enter\n");
 
+	spin_lock_init(&rs_sta->lock);
+
+	rs_sta->priv = priv;
+
+	rs_sta->start_rate = IWL_RATE_INVALID;
+
+	/* default to just 802.11b */
+	rs_sta->expected_tpt = iwl3945_expected_tpt_b;
+
+	rs_sta->last_partial_flush = jiffies;
+	rs_sta->last_flush = jiffies;
+	rs_sta->flush_time = IWL_RATE_FLUSH;
+	rs_sta->last_tx_packets = 0;
+	rs_sta->ibss_sta_added = 0;
+
+	init_timer(&rs_sta->rate_scale_flush);
+	rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
+	rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush;
+
+	for (i = 0; i < IWL_RATE_COUNT_3945; i++)
+		iwl3945_clear_window(&rs_sta->win[i]);
+
 	/* TODO: what is a good starting rate for STA? About middle? Maybe not
 	 * the lowest or the highest rate.. Could consider using RSSI from
 	 * previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -409,45 +399,11 @@ static void *rs_alloc_sta(void *iwl_priv
 {
 	struct iwl3945_rs_sta *rs_sta;
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
-	struct iwl_priv *priv = iwl_priv;
-	int i;
-
-	/*
-	 * XXX: If it's using sta->drv_priv anyway, it might
-	 *	as well just put all the information there.
-	 */
+	struct iwl_priv *priv __maybe_unused = iwl_priv;
 
 	IWL_DEBUG_RATE(priv, "enter\n");
 
-	rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
-	if (!rs_sta) {
-		IWL_DEBUG_RATE(priv, "leave: ENOMEM\n");
-		return NULL;
-	}
-
-	psta->rs_sta = rs_sta;
-
-	spin_lock_init(&rs_sta->lock);
-
-	rs_sta->priv = priv;
-
-	rs_sta->start_rate = IWL_RATE_INVALID;
-
-	/* default to just 802.11b */
-	rs_sta->expected_tpt = iwl3945_expected_tpt_b;
-
-	rs_sta->last_partial_flush = jiffies;
-	rs_sta->last_flush = jiffies;
-	rs_sta->flush_time = IWL_RATE_FLUSH;
-	rs_sta->last_tx_packets = 0;
-	rs_sta->ibss_sta_added = 0;
-
-	init_timer(&rs_sta->rate_scale_flush);
-	rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
-	rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
-
-	for (i = 0; i < IWL_RATE_COUNT_3945; i++)
-		iwl3945_clear_window(&rs_sta->win[i]);
+	rs_sta = &psta->rs_sta;
 
 	IWL_DEBUG_RATE(priv, "leave\n");
 
@@ -458,14 +414,11 @@ static void rs_free_sta(void *iwl_priv,
 			void *priv_sta)
 {
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
-	struct iwl3945_rs_sta *rs_sta = priv_sta;
+	struct iwl3945_rs_sta *rs_sta = &psta->rs_sta;
 	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
-	psta->rs_sta = NULL;
-
 	IWL_DEBUG_RATE(priv, "enter\n");
 	del_timer_sync(&rs_sta->rate_scale_flush);
-	kfree(rs_sta);
 	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
@@ -960,14 +913,15 @@ void iwl3945_rate_scale_init(struct ieee
 
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+	sta = ieee80211_find_sta(priv->vif,
+				 priv->stations[sta_id].sta.sta.addr);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
 	}
 
 	psta = (void *) sta->drv_priv;
-	rs_sta = psta->rs_sta;
+	rs_sta = &psta->rs_sta;
 
 	spin_lock_irqsave(&rs_sta->lock, flags);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 14:02:24.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 12:09:56.000000000 -0400
@@ -45,6 +45,7 @@
 #include "iwl-helpers.h"
 #include "iwl-calib.h"
 #include "iwl-sta.h"
+#include "iwl-agn-led.h"
 
 static int iwl4965_send_tx_power(struct iwl_priv *priv);
 static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -62,8 +63,6 @@ static int iwl4965_hw_get_temperature(st
 
 /* module parameters */
 static struct iwl_mod_params iwl4965_mod_params = {
-	.num_of_queues = IWL49_NUM_QUEUES,
-	.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
 	.amsdu_size_8K = 1,
 	.restart_fw = 1,
 	/* the rest are 0 by default */
@@ -319,63 +318,13 @@ static void iwl4965_txq_set_sched(struct
 	iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
 }
 
-static int iwl4965_apm_init(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* set "initialization complete" bit to move adapter
-	 * D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/* wait for clock stabilization */
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
-						APMG_CLK_VAL_BSM_CLK_RQT);
-
-	udelay(20);
-
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-out:
-	return ret;
-}
-
-
 static void iwl4965_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	u16 radio_cfg;
-	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	lctl = iwl_pcie_link_ctl(priv);
-
-	/* HW bug W/A - negligible power consumption */
-	/* L1-ASPM is enabled by BIOS */
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* L1-ASPM enabled: disable L0S  */
-		iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-	else
-		/* L1-ASPM disabled: enable L0S */
-		iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-
 	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 
 	/* write radio config values to register */
@@ -396,79 +345,6 @@ static void iwl4965_nic_config(struct iw
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static int iwl4965_apm_stop_master(struct iwl_priv *priv)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* set stop master bit */
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
-
-	iwl_poll_direct_bit(priv, CSR_RESET,
-			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO(priv, "stop master\n");
-
-	return 0;
-}
-
-static void iwl4965_apm_stop(struct iwl_priv *priv)
-{
-	unsigned long flags;
-
-	iwl4965_apm_stop_master(priv);
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-	/* clear "init complete"  move adapter D0A* --> D0U state */
-	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int iwl4965_apm_reset(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl4965_apm_stop_master(priv);
-
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-
-	/* FIXME: put here L1A -L0S w/a */
-
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0)
-		goto out;
-
-	udelay(10);
-
-	/* Enable DMA and BSM Clock */
-	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
-					      APMG_CLK_VAL_BSM_CLK_RQT);
-
-	udelay(10);
-
-	/* disable L1A */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-	wake_up_interruptible(&priv->wait_command_queue);
-
-out:
-	return ret;
-}
-
 /* Reset differential Rx gains in NIC to prepare for chain noise calibration.
  * Called after every association, but this runs only once!
  *  ... once chain noise is calibrated the first time, it's good forever.  */
@@ -496,14 +372,15 @@ static void iwl4965_chain_noise_reset(st
 static void iwl4965_gain_computation(struct iwl_priv *priv,
 		u32 *average_noise,
 		u16 min_average_noise_antenna_i,
-		u32 min_average_noise)
+		u32 min_average_noise,
+		u8 default_chain)
 {
 	int i, ret;
 	struct iwl_chain_noise_data *data = &priv->chain_noise_data;
 
 	data->delta_gain_code[min_average_noise_antenna_i] = 0;
 
-	for (i = 0; i < NUM_RX_CHAINS; i++) {
+	for (i = default_chain; i < NUM_RX_CHAINS; i++) {
 		s32 delta_g = 0;
 
 		if (!(data->disconn_array[i]) &&
@@ -557,18 +434,6 @@ static void iwl4965_gain_computation(str
 	data->beacon_count = 0;
 }
 
-static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
-			__le32 *tx_flags)
-{
-	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-		*tx_flags |= TX_CMD_FLG_RTS_MSK;
-		*tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-	} else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-		*tx_flags &= ~TX_CMD_FLG_RTS_MSK;
-		*tx_flags |= TX_CMD_FLG_CTS_MSK;
-	}
-}
-
 static void iwl4965_bg_txpower_work(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -663,7 +528,8 @@ static int iwl4965_alive_notify(struct i
 		iwl_write_targ_mem(priv, a, 0);
 	for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
 		iwl_write_targ_mem(priv, a, 0);
-	for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
+	for (; a < priv->scd_base_addr +
+	       IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
 		iwl_write_targ_mem(priv, a, 0);
 
 	/* Tel 4965 where to find Tx byte count tables */
@@ -748,6 +614,10 @@ static struct iwl_sensitivity_ranges iwl
 
 	.nrg_th_cck = 100,
 	.nrg_th_ofdm = 100,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
 };
 
 static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
@@ -764,19 +634,16 @@ static void iwl4965_set_ct_threshold(str
  */
 static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
 {
+	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
+		priv->cfg->num_of_queues =
+			priv->cfg->mod_params->num_of_queues;
 
-	if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
-	    (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
-		IWL_ERR(priv,
-			"invalid queues_num, should be between %d and %d\n",
-			IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
-		return -EINVAL;
-	}
-
-	priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+	priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
-			IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
+			priv->cfg->num_of_queues *
+			sizeof(struct iwl4965_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
 	priv->hw_params.max_stations = IWL4965_STATION_COUNT;
 	priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
@@ -787,10 +654,10 @@ static int iwl4965_hw_set_hw_params(stru
 
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
 
-	priv->hw_params.tx_chains_num = 2;
-	priv->hw_params.rx_chains_num = 2;
-	priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
-	priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
+	priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
 		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
@@ -1337,7 +1204,7 @@ static int iwl4965_fill_txpower_tbl(stru
 	iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
 
 	/* calculate tx gain adjustment based on power supply voltage */
-	voltage = priv->calib_info->voltage;
+	voltage = le16_to_cpu(priv->calib_info->voltage);
 	init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
 	voltage_compensation =
 	    iwl4965_get_voltage_compensation(voltage, init_voltage);
@@ -1567,14 +1434,13 @@ static int iwl4965_send_rxon_assoc(struc
 	return ret;
 }
 
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
 static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
 	int rc;
 	u8 band = 0;
 	bool is_ht40 = false;
 	u8 ctrl_chan_high = 0;
-	struct iwl4965_channel_switch_cmd cmd = { 0 };
+	struct iwl4965_channel_switch_cmd cmd;
 	const struct iwl_channel_info *ch_info;
 
 	band = priv->band == IEEE80211_BAND_2GHZ;
@@ -1584,19 +1450,22 @@ static int iwl4965_hw_channel_switch(str
 	is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
 
 	if (is_ht40 &&
-	    (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+	    (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 		ctrl_chan_high = 1;
 
 	cmd.band = band;
 	cmd.expect_beacon = 0;
 	cmd.channel = cpu_to_le16(channel);
-	cmd.rxon_flags = priv->active_rxon.flags;
-	cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+	cmd.rxon_flags = priv->staging_rxon.flags;
+	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
 	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
 	if (ch_info)
 		cmd.expect_beacon = is_channel_radar(ch_info);
-	else
-		cmd.expect_beacon = 1;
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
 
 	rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
 				      ctrl_chan_high, &cmd.tx_power);
@@ -1605,10 +1474,11 @@ static int iwl4965_hw_channel_switch(str
 		return rc;
 	}
 
-	rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
-	return rc;
+	priv->switch_rxon.channel = cpu_to_le16(channel);
+	priv->switch_rxon.switch_in_progress = true;
+
+	return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
 }
-#endif
 
 /**
  * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
@@ -1805,11 +1675,13 @@ static int iwl4965_txq_agg_disable(struc
 				   u16 ssn_idx, u8 tx_fifo)
 {
 	if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
-	    (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
+	    (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
+	     <= txq_id)) {
 		IWL_WARN(priv,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWL49_FIRST_AMPDU_QUEUE,
-			IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
+			IWL49_FIRST_AMPDU_QUEUE +
+			priv->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -1870,11 +1742,13 @@ static int iwl4965_txq_agg_enable(struct
 	u16 ra_tid;
 
 	if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
-	    (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
+	    (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
+	     <= txq_id)) {
 		IWL_WARN(priv,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWL49_FIRST_AMPDU_QUEUE,
-			IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
+			IWL49_FIRST_AMPDU_QUEUE +
+			priv->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -1944,8 +1818,9 @@ static u16 iwl4965_build_addsta_hcmd(con
 	addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
 	addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
 	addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
+	addsta->sleep_tx_count = cmd->sleep_tx_count;
 	addsta->reserved1 = cpu_to_le16(0);
-	addsta->reserved2 = cpu_to_le32(0);
+	addsta->reserved2 = cpu_to_le16(0);
 
 	return (u16)sizeof(struct iwl4965_addsta_cmd);
 }
@@ -1991,8 +1866,7 @@ static int iwl4965_tx_status_reply_tx(st
 		info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
 		info->status.rates[0].count = tx_resp->failure_frame + 1;
 		info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-		info->flags |= iwl_is_tx_success(status) ?
-			IEEE80211_TX_STAT_ACK : 0;
+		info->flags |= iwl_tx_status_to_mac80211(status);
 		iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
 		/* FIXME: code repetition end */
 
@@ -2078,7 +1952,7 @@ static int iwl4965_tx_status_reply_tx(st
 static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
@@ -2087,7 +1961,7 @@ static void iwl4965_rx_reply_tx(struct i
 	struct ieee80211_tx_info *info;
 	struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
 	u32  status = le32_to_cpu(tx_resp->u.status);
-	int tid = MAX_TID_COUNT;
+	int uninitialized_var(tid);
 	int sta_id;
 	int freed;
 	u8 *qc = NULL;
@@ -2134,7 +2008,7 @@ static void iwl4965_rx_reply_tx(struct i
 			IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
 					   "%d index %d\n", scd_ssn , index);
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 			if (priv->mac80211_registered &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2147,8 +2021,7 @@ static void iwl4965_rx_reply_tx(struct i
 		}
 	} else {
 		info->status.rates[0].count = tx_resp->failure_frame + 1;
-		info->flags |= iwl_is_tx_success(status) ?
-					IEEE80211_TX_STAT_ACK : 0;
+		info->flags |= iwl_tx_status_to_mac80211(status);
 		iwl_hwrate_to_tx_control(priv,
 					le32_to_cpu(tx_resp->rate_n_flags),
 					info);
@@ -2279,7 +2152,7 @@ static struct iwl_hcmd_utils_ops iwl4965
 	.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
 	.chain_noise_reset = iwl4965_chain_noise_reset,
 	.gain_computation = iwl4965_gain_computation,
-	.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
+	.rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
 	.calc_rssi = iwl4965_calc_rssi,
 };
 
@@ -2301,10 +2174,10 @@ static struct iwl_lib_ops iwl4965_lib =
 	.load_ucode = iwl4965_load_bsm,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.set_channel_switch = iwl4965_hw_channel_switch,
 	.apm_ops = {
-		.init = iwl4965_apm_init,
-		.reset = iwl4965_apm_reset,
-		.stop = iwl4965_apm_stop,
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
 		.config = iwl4965_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
 	},
@@ -2340,6 +2213,7 @@ static struct iwl_ops iwl4965_ops = {
 	.lib = &iwl4965_lib,
 	.hcmd = &iwl4965_hcmd,
 	.utils = &iwl4965_hcmd_utils,
+	.led = &iwlagn_led_ops,
 };
 
 struct iwl_cfg iwl4965_agn_cfg = {
@@ -2352,30 +2226,41 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
 	.ops = &iwl4965_ops,
+	.num_of_queues = IWL49_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl4965_mod_params,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_ABC,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = true,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
 	.broken_powersave = true,
+	.led_compensation = 61,
+	.chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
 /* Module firmware */
 /*(DEBLOBBED)*/
 
-module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
+module_param_named(antenna, iwl4965_mod_params.antenna, int, S_IRUGO);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
+module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
 module_param_named(
-	disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
+	disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, S_IRUGO);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 
-module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
+module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
 /* 11n */
-module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
+module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO);
 MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
-module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444);
+module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K,
+		   int, S_IRUGO);
 MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
 
-module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444);
+module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,12 +76,9 @@
 
 /*
  * uCode queue management definitions ...
- * Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4.
  * The first queue used for block-ack aggregation is #7 (4965 only).
  * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7.
  */
-#define IWL_CMD_QUEUE_NUM       4
-#define IWL_CMD_FIFO_NUM        4
 #define IWL49_FIRST_AMPDU_QUEUE	7
 
 /* Time constants */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 14:02:26.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 12:09:58.000000000 -0400
@@ -43,6 +43,7 @@
 #include "iwl-io.h"
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
+#include "iwl-agn-led.h"
 #include "iwl-5000-hw.h"
 #include "iwl-6000-hw.h"
 
@@ -72,157 +73,18 @@ static const u16 iwl5000_default_queue_t
 	IWL_TX_FIFO_HCCA_2
 };
 
-/* FIXME: same implementation as 4965 */
-static int iwl5000_apm_stop_master(struct iwl_priv *priv)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* set stop master bit */
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
-
-	iwl_poll_direct_bit(priv, CSR_RESET,
-				  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO(priv, "stop master\n");
-
-	return 0;
-}
-
-
-int iwl5000_apm_init(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-		    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* Set FH wait threshold to maximum (HW error during stress W/A) */
-	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
-
-	/* enable HAP INTA to move device L1a -> L0s */
-	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
-
-	if (priv->cfg->need_pll_cfg)
-		iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
-
-	/* set "initialization complete" bit to move adapter
-	 * D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/* wait for clock stabilization */
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		return ret;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-
-	udelay(20);
-
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-	return ret;
-}
-
-/* FIXME: this is identical to 4965 */
-void iwl5000_apm_stop(struct iwl_priv *priv)
-{
-	unsigned long flags;
-
-	iwl5000_apm_stop_master(priv);
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-
-	/* clear "init complete"  move adapter D0A* --> D0U state */
-	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-
-int iwl5000_apm_reset(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl5000_apm_stop_master(priv);
-
-	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-
-
-	/* FIXME: put here L1A -L0S w/a */
-
-	if (priv->cfg->need_pll_cfg)
-		iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
-
-	/* set "initialization complete" bit to move adapter
-	 * D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/* wait for clock stabilization */
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-
-	udelay(20);
-
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-out:
-
-	return ret;
-}
-
-
-/* NIC configuration for 5000 series and up */
+/* NIC configuration for 5000 series */
 void iwl5000_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	u16 radio_cfg;
-	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	lctl = iwl_pcie_link_ctl(priv);
-
-	/* HW bug W/A */
-	/* L1-ASPM is enabled by BIOS */
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* L1-APSM enabled: disable L0S  */
-		iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-	else
-		/* L1-ASPM disabled: enable L0S */
-		iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-
 	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 
 	/* write radio config values to register */
-	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_5000_RF_CFG_TYPE_MAX)
+	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX)
 		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
 			    EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
@@ -302,19 +164,22 @@ u16 iwl5000_eeprom_calib_version(struct
 static void iwl5000_gain_computation(struct iwl_priv *priv,
 		u32 average_noise[NUM_RX_CHAINS],
 		u16 min_average_noise_antenna_i,
-		u32 min_average_noise)
+		u32 min_average_noise,
+		u8 default_chain)
 {
 	int i;
 	s32 delta_g;
 	struct iwl_chain_noise_data *data = &priv->chain_noise_data;
 
-	/* Find Gain Code for the antennas B and C */
-	for (i = 1; i < NUM_RX_CHAINS; i++) {
+	/*
+	 * Find Gain Code for the chains based on "default chain"
+	 */
+	for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
 		if ((data->disconn_array[i])) {
 			data->delta_gain_code[i] = 0;
 			continue;
 		}
-		delta_g = (1000 * ((s32)average_noise[0] -
+		delta_g = (1000 * ((s32)average_noise[default_chain] -
 			(s32)average_noise[i])) / 1500;
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
@@ -407,6 +272,10 @@ static struct iwl_sensitivity_ranges iwl
 	.auto_corr_max_cck_mrc = 400,
 	.nrg_th_cck = 95,
 	.nrg_th_ofdm = 95,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
 };
 
 static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
@@ -429,6 +298,10 @@ static struct iwl_sensitivity_ranges iwl
 	.auto_corr_max_cck_mrc = 400,
 	.nrg_th_cck = 95,
 	.nrg_th_ofdm = 95,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
 };
 
 const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
@@ -460,14 +333,15 @@ static void iwl5000_set_ct_threshold(str
 static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
 {
 	struct iwl_calib_xtal_freq_cmd cmd;
-	u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
+	__le16 *xtal_calib =
+		(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
 
 	cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
 	cmd.hdr.first_group = 0;
 	cmd.hdr.groups_num = 1;
 	cmd.hdr.data_valid = 1;
-	cmd.cap_pin1 = (u8)xtal_calib[0];
-	cmd.cap_pin2 = (u8)xtal_calib[1];
+	cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
+	cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
 	return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
 			     (u8 *)&cmd, sizeof(cmd));
 }
@@ -493,7 +367,7 @@ static int iwl5000_send_calib_cfg(struct
 static void iwl5000_rx_calib_result(struct iwl_priv *priv,
 			     struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
 	int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 	int index;
@@ -719,16 +593,6 @@ static void iwl5000_tx_queue_set_status(
 		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
-static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
-{
-	struct iwl_wimax_coex_cmd coex_cmd;
-
-	memset(&coex_cmd, 0, sizeof(coex_cmd));
-
-	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
-				sizeof(coex_cmd), &coex_cmd);
-}
-
 int iwl5000_alive_notify(struct iwl_priv *priv)
 {
 	u32 a;
@@ -746,7 +610,8 @@ int iwl5000_alive_notify(struct iwl_priv
 	for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
 		a += 4)
 		iwl_write_targ_mem(priv, a, 0);
-	for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
+	for (; a < priv->scd_base_addr +
+	       IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
 		iwl_write_targ_mem(priv, a, 0);
 
 	iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
@@ -798,9 +663,13 @@ int iwl5000_alive_notify(struct iwl_priv
 		iwl_txq_ctx_activate(priv, i);
 		iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
 	}
-	/* TODO - need to initialize those FIFOs inside the loop above,
-	 * not only mark them as active */
-	iwl_txq_ctx_activate(priv, 4);
+
+	/*
+	 * TODO - need to initialize these queues and map them to FIFOs
+	 * in the loop above, not only mark them as active. We do this
+	 * because we want the first aggregation queue to be queue #10,
+	 * but do not use 8 or 9 otherwise yet.
+	 */
 	iwl_txq_ctx_activate(priv, 7);
 	iwl_txq_ctx_activate(priv, 8);
 	iwl_txq_ctx_activate(priv, 9);
@@ -808,7 +677,7 @@ int iwl5000_alive_notify(struct iwl_priv
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 
-	iwl5000_send_wimax_coex(priv);
+	iwl_send_wimax_coex(priv);
 
 	iwl5000_set_Xtal_calib(priv);
 	iwl_send_calib_results(priv);
@@ -818,32 +687,22 @@ int iwl5000_alive_notify(struct iwl_priv
 
 int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 {
-	if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
-	    (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
-		IWL_ERR(priv,
-			"invalid queues_num, should be between %d and %d\n",
-			IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
-		return -EINVAL;
-	}
+	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
+		priv->cfg->num_of_queues =
+			priv->cfg->mod_params->num_of_queues;
 
-	priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+	priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
 	priv->hw_params.scd_bc_tbls_size =
-			IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
+			priv->cfg->num_of_queues *
+			sizeof(struct iwl5000_scd_bc_tbl);
 	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
 	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
 	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
 
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_6x00:
-	case CSR_HW_REV_TYPE_6x50:
-		priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
-		priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
-		break;
-	default:
-		priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
-		priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
-	}
+	priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
+	priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
 
 	priv->hw_params.max_bsm_size = 0;
 	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
@@ -989,11 +848,13 @@ int iwl5000_txq_agg_enable(struct iwl_pr
 	u16 ra_tid;
 
 	if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
-	    (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
+	    (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
+	     <= txq_id)) {
 		IWL_WARN(priv,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWL50_FIRST_AMPDU_QUEUE,
-			IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
+			IWL50_FIRST_AMPDU_QUEUE +
+			priv->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -1047,11 +908,13 @@ int iwl5000_txq_agg_disable(struct iwl_p
 				   u16 ssn_idx, u8 tx_fifo)
 {
 	if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
-	    (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
+	    (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
+	     <= txq_id)) {
 		IWL_ERR(priv,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWL50_FIRST_AMPDU_QUEUE,
-			IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
+			IWL50_FIRST_AMPDU_QUEUE +
+			priv->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -1132,8 +995,7 @@ static int iwl5000_tx_status_reply_tx(st
 		info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
 		info->status.rates[0].count = tx_resp->failure_frame + 1;
 		info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-		info->flags |= iwl_is_tx_success(status) ?
-					IEEE80211_TX_STAT_ACK : 0;
+		info->flags |= iwl_tx_status_to_mac80211(status);
 		iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
 
 		/* FIXME: code repetition end */
@@ -1218,7 +1080,7 @@ static int iwl5000_tx_status_reply_tx(st
 static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
@@ -1263,7 +1125,7 @@ static void iwl5000_rx_reply_tx(struct i
 					scd_ssn , index, txq_id, txq->swq_id);
 
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 			if (priv->mac80211_registered &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -1278,8 +1140,7 @@ static void iwl5000_rx_reply_tx(struct i
 		BUG_ON(txq_id != txq->swq_id);
 
 		info->status.rates[0].count = tx_resp->failure_frame + 1;
-		info->flags |= iwl_is_tx_success(status) ?
-					IEEE80211_TX_STAT_ACK : 0;
+		info->flags |= iwl_tx_status_to_mac80211(status);
 		iwl_hwrate_to_tx_control(priv,
 					le32_to_cpu(tx_resp->rate_n_flags),
 					info);
@@ -1292,16 +1153,14 @@ static void iwl5000_rx_reply_tx(struct i
 				   tx_resp->failure_frame);
 
 		freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-		if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+		iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 		if (priv->mac80211_registered &&
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
 			iwl_wake_queue(priv, txq_id);
 	}
 
-	if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-		iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+	iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
 		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
@@ -1389,6 +1248,22 @@ int  iwl5000_send_tx_power(struct iwl_pr
 
 	/* half dBm need to multiply */
 	tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
+
+	if (priv->tx_power_lmt_in_half_dbm &&
+	    priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
+		/*
+		 * For the newer devices which using enhanced/extend tx power
+		 * table in EEPROM, the format is in half dBm. driver need to
+		 * convert to dBm format before report to mac80211.
+		 * By doing so, there is a possibility of 1/2 dBm resolution
+		 * lost. driver will perform "round-up" operation before
+		 * reporting, but it will cause 1/2 dBm tx power over the
+		 * regulatory limit. Perform the checking here, if the
+		 * "tx_power_user_lmt" is higher than EEPROM value (in
+		 * half-dBm format), lower the tx power based on EEPROM
+		 */
+		tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
+	}
 	tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
 	tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
 
@@ -1459,6 +1334,24 @@ int iwl5000_calc_rssi(struct iwl_priv *p
 	return max_rssi - agc - IWL49_RSSI_OFFSET;
 }
 
+static int iwl5000_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
+{
+	struct iwl_tx_ant_config_cmd tx_ant_cmd = {
+	  .valid = cpu_to_le32(valid_tx_ant),
+	};
+
+	if (IWL_UCODE_API(priv->ucode_ver) > 1) {
+		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
+		return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
+					sizeof(struct iwl_tx_ant_config_cmd),
+					&tx_ant_cmd);
+	} else {
+		IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
+		return -EOPNOTSUPP;
+	}
+}
+
+
 #define IWL5000_UCODE_GET(item)						\
 static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
 				    u32 api_ver)			\
@@ -1497,10 +1390,43 @@ IWL5000_UCODE_GET(init_size);
 IWL5000_UCODE_GET(init_data_size);
 IWL5000_UCODE_GET(boot_size);
 
+static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+{
+	struct iwl5000_channel_switch_cmd cmd;
+	const struct iwl_channel_info *ch_info;
+	struct iwl_host_cmd hcmd = {
+		.id = REPLY_CHANNEL_SWITCH,
+		.len = sizeof(cmd),
+		.flags = CMD_SIZE_HUGE,
+		.data = &cmd,
+	};
+
+	IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
+		priv->active_rxon.channel, channel);
+	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
+	cmd.channel = cpu_to_le16(channel);
+	cmd.rxon_flags = priv->staging_rxon.flags;
+	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
+	ch_info = iwl_get_channel_info(priv, priv->band, channel);
+	if (ch_info)
+		cmd.expect_beacon = is_channel_radar(ch_info);
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
+	priv->switch_rxon.channel = cpu_to_le16(channel);
+	priv->switch_rxon.switch_in_progress = true;
+
+	return iwl_send_cmd_sync(priv, &hcmd);
+}
+
 struct iwl_hcmd_ops iwl5000_hcmd = {
 	.rxon_assoc = iwl5000_send_rxon_assoc,
 	.commit_rxon = iwl_commit_rxon,
 	.set_rxon_chain = iwl_set_rxon_chain,
+	.set_tx_ant = iwl5000_send_tx_ant_config,
 };
 
 struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@ -1543,10 +1469,10 @@ struct iwl_lib_ops iwl5000_lib = {
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
-		.reset = iwl5000_apm_reset,
-		.stop = iwl5000_apm_stop,
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
 	},
@@ -1595,10 +1521,10 @@ static struct iwl_lib_ops iwl5150_lib =
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
-		.reset = iwl5000_apm_reset,
-		.stop = iwl5000_apm_stop,
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
 	},
@@ -1627,11 +1553,12 @@ static struct iwl_lib_ops iwl5150_lib =
 	 },
 };
 
-struct iwl_ops iwl5000_ops = {
+static struct iwl_ops iwl5000_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl5000_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
+	.led = &iwlagn_led_ops,
 };
 
 static struct iwl_ops iwl5150_ops = {
@@ -1639,11 +1566,10 @@ static struct iwl_ops iwl5150_ops = {
 	.lib = &iwl5150_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
+	.led = &iwlagn_led_ops,
 };
 
 struct iwl_mod_params iwl50_mod_params = {
-	.num_of_queues = IWL50_NUM_QUEUES,
-	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.amsdu_size_8K = 1,
 	.restart_fw = 1,
 	/* the rest are 0 by default */
@@ -1660,28 +1586,43 @@ struct iwl_cfg iwl5300_agn_cfg = {
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
-struct iwl_cfg iwl5100_bg_cfg = {
-	.name = "5100BG",
+struct iwl_cfg iwl5100_bgn_cfg = {
+	.name = "5100BGN",
 	.fw_name_pre = IWL5000_FW_PRE,
 	.ucode_api_max = IWL5000_UCODE_API_MAX,
 	.ucode_api_min = IWL5000_UCODE_API_MIN,
-	.sku = IWL_SKU_G,
+	.sku = IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl5000_ops,
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
@@ -1694,11 +1635,16 @@ struct iwl_cfg iwl5100_abg_cfg = {
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
-	.ht_greenfield_support = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
@@ -1711,11 +1657,19 @@ struct iwl_cfg iwl5100_agn_cfg = {
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
@@ -1728,11 +1682,19 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
 struct iwl_cfg iwl5150_agn_cfg = {
@@ -1745,23 +1707,54 @@ struct iwl_cfg iwl5150_agn_cfg = {
 	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+};
+
+struct iwl_cfg iwl5150_abg_cfg = {
+	.name = "5150ABG",
+	.fw_name_pre = IWL5150_FW_PRE,
+	.ucode_api_max = IWL5150_UCODE_API_MAX,
+	.ucode_api_min = IWL5150_UCODE_API_MIN,
+	.sku = IWL_SKU_A|IWL_SKU_G,
+	.ops = &iwl5150_ops,
+	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_A,
+	.valid_rx_ant = ANT_AB,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 };
 
 /*(DEBLOBBED)*/
 
-module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
+module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO);
 MODULE_PARM_DESC(swcrypto50,
 		  "using software crypto engine (default 0 [hardware])\n");
-module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
+module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO);
 MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
-module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
+module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO);
 MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
-module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444);
+module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K,
+		   int, S_IRUGO);
 MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
-module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444);
+module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -92,11 +92,15 @@
 
 static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
 {
-	u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
-						       EEPROM_5000_TEMPERATURE);
-	/* offset =  temperature -  voltage / coef */
-	s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
-	return offset;
+	u16 temperature, voltage;
+	__le16 *temp_calib =
+		(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+
+	temperature = le16_to_cpu(temp_calib[0]);
+	voltage = le16_to_cpu(temp_calib[1]);
+
+	/* offset = temp - volt / coeff */
+	return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
 }
 
 /* Fixed (non-configurable) rx data from phy */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-05-03 14:02:28.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-05-03 12:10:00.000000000 -0400
@@ -44,14 +44,16 @@
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
 #include "iwl-5000-hw.h"
+#include "iwl-6000-hw.h"
+#include "iwl-agn-led.h"
 
 /* Highest firmware API version supported */
 #define IWL6000_UCODE_API_MAX 4
 #define IWL6050_UCODE_API_MAX 4
 
 /* Lowest firmware API version supported */
-#define IWL6000_UCODE_API_MIN 1
-#define IWL6050_UCODE_API_MIN 1
+#define IWL6000_UCODE_API_MIN 4
+#define IWL6050_UCODE_API_MIN 4
 
 #define IWL6000_FW_PRE "/*(DEBLOBBED)*/"
 #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE /*(DEBLOBBED)*/
@@ -71,14 +73,24 @@ static void iwl6000_set_ct_threshold(str
 /* NIC configuration for 6000 series */
 static void iwl6000_nic_config(struct iwl_priv *priv)
 {
-	iwl5000_nic_config(priv);
+	u16 radio_cfg;
+
+	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
+
+	/* write radio config values to register */
+	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX)
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+			    EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
+			    EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
+			    EEPROM_RF_CFG_DASH_MSK(radio_cfg));
+
+	/* set CSR_HW_CONFIG_REG for uCode use */
+	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
+		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
 	/* no locking required for register write */
-	if (priv->cfg->pa_type == IWL_PA_HYBRID) {
-		/* 2x2 hybrid phy type */
-		iwl_write32(priv, CSR_GP_DRIVER_REG,
-			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
-	} else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
+	if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
 		/* 2x2 IPA phy type */
 		iwl_write32(priv, CSR_GP_DRIVER_REG,
 			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
@@ -86,8 +98,109 @@ static void iwl6000_nic_config(struct iw
 	/* else do nothing, uCode configured */
 }
 
+static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
+	.min_nrg_cck = 97,
+	.max_nrg_cck = 0, /* not used, set to 0 */
+	.auto_corr_min_ofdm = 80,
+	.auto_corr_min_ofdm_mrc = 128,
+	.auto_corr_min_ofdm_x1 = 105,
+	.auto_corr_min_ofdm_mrc_x1 = 192,
+
+	.auto_corr_max_ofdm = 145,
+	.auto_corr_max_ofdm_mrc = 232,
+	.auto_corr_max_ofdm_x1 = 145,
+	.auto_corr_max_ofdm_mrc_x1 = 232,
+
+	.auto_corr_min_cck = 125,
+	.auto_corr_max_cck = 175,
+	.auto_corr_min_cck_mrc = 160,
+	.auto_corr_max_cck_mrc = 310,
+	.nrg_th_cck = 97,
+	.nrg_th_ofdm = 100,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
+};
+
+static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
+{
+	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
+		priv->cfg->num_of_queues =
+			priv->cfg->mod_params->num_of_queues;
+
+	priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
+	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
+	priv->hw_params.scd_bc_tbls_size =
+			priv->cfg->num_of_queues *
+			sizeof(struct iwl5000_scd_bc_tbl);
+	priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
+	priv->hw_params.max_stations = IWL5000_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+
+	priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
+	priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
+
+	priv->hw_params.max_bsm_size = 0;
+	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
+					BIT(IEEE80211_BAND_5GHZ);
+	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
+	priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
+
+	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
+
+	/* Set initial sensitivity parameters */
+	/* Set initial calibration set */
+	priv->hw_params.sens = &iwl6000_sensitivity;
+	priv->hw_params.calib_init_cfg =
+			BIT(IWL_CALIB_XTAL)		|
+			BIT(IWL_CALIB_LO)		|
+			BIT(IWL_CALIB_TX_IQ) 		|
+			BIT(IWL_CALIB_BASE_BAND);
+	return 0;
+}
+
+static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+{
+	struct iwl6000_channel_switch_cmd cmd;
+	const struct iwl_channel_info *ch_info;
+	struct iwl_host_cmd hcmd = {
+		.id = REPLY_CHANNEL_SWITCH,
+		.len = sizeof(cmd),
+		.flags = CMD_SIZE_HUGE,
+		.data = &cmd,
+	};
+
+	IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
+		priv->active_rxon.channel, channel);
+
+	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
+	cmd.channel = cpu_to_le16(channel);
+	cmd.rxon_flags = priv->staging_rxon.flags;
+	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
+	ch_info = iwl_get_channel_info(priv, priv->band, channel);
+	if (ch_info)
+		cmd.expect_beacon = is_channel_radar(ch_info);
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
+	priv->switch_rxon.channel = cpu_to_le16(channel);
+	priv->switch_rxon.switch_in_progress = true;
+
+	return iwl_send_cmd_sync(priv, &hcmd);
+}
+
 static struct iwl_lib_ops iwl6000_lib = {
-	.set_hw_params = iwl5000_hw_set_hw_params,
+	.set_hw_params = iwl6000_hw_set_hw_params,
 	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
 	.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
 	.txq_set_sched = iwl5000_txq_set_sched,
@@ -106,10 +219,10 @@ static struct iwl_lib_ops iwl6000_lib =
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl6000_hw_channel_switch,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
-		.reset = iwl5000_apm_reset,
-		.stop = iwl5000_apm_stop,
+		.init = iwl_apm_init,
+		.stop = iwl_apm_stop,
 		.config = iwl6000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
 	},
@@ -139,25 +252,33 @@ static struct iwl_lib_ops iwl6000_lib =
 	 },
 };
 
-static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+static struct iwl_ops iwl6000_ops = {
+	.ucode = &iwl5000_ucode,
+	.lib = &iwl6000_lib,
+	.hcmd = &iwl5000_hcmd,
+	.utils = &iwl5000_hcmd_utils,
+	.led = &iwlagn_led_ops,
+};
+
+static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
 	.get_hcmd_size = iwl5000_get_hcmd_size,
 	.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
 	.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
 	.calc_rssi = iwl5000_calc_rssi,
 };
 
-static struct iwl_ops iwl6000_ops = {
+static struct iwl_ops iwl6050_ops = {
 	.ucode = &iwl5000_ucode,
 	.lib = &iwl6000_lib,
 	.hcmd = &iwl5000_hcmd,
-	.utils = &iwl6000_hcmd_utils,
+	.utils = &iwl6050_hcmd_utils,
+	.led = &iwlagn_led_ops,
 };
 
-
 /*
- * "h": Hybrid configuration, use both internal and external Power Amplifier
+ * "i": Internal configuration, use internal Power Amplifier
  */
-struct iwl_cfg iwl6000h_2agn_cfg = {
+struct iwl_cfg iwl6000i_2agn_cfg = {
 	.name = "6000 Series 2x2 AGN",
 	.fw_name_pre = IWL6000_FW_PRE,
 	.ucode_api_max = IWL6000_UCODE_API_MAX,
@@ -165,41 +286,85 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
-	.valid_tx_ant = ANT_AB,
-	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
-	.pa_type = IWL_PA_HYBRID,
+	.valid_tx_ant = ANT_BC,
+	.valid_rx_ant = ANT_BC,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
+	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
-/*
- * "i": Internal configuration, use internal Power Amplifier
- */
-struct iwl_cfg iwl6000i_2agn_cfg = {
-	.name = "6000 Series 2x2 AGN",
+struct iwl_cfg iwl6000i_2abg_cfg = {
+	.name = "6000 Series 2x2 ABG",
 	.fw_name_pre = IWL6000_FW_PRE,
 	.ucode_api_max = IWL6000_UCODE_API_MAX,
 	.ucode_api_min = IWL6000_UCODE_API_MIN,
-	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+	.sku = IWL_SKU_A|IWL_SKU_G,
 	.ops = &iwl6000_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.ht_greenfield_support = true,
-	.use_rts_for_ht = true, /* use rts/cts protection */
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+};
+
+struct iwl_cfg iwl6000i_2bg_cfg = {
+	.name = "6000 Series 2x2 BG",
+	.fw_name_pre = IWL6000_FW_PRE,
+	.ucode_api_max = IWL6000_UCODE_API_MAX,
+	.ucode_api_min = IWL6000_UCODE_API_MIN,
+	.sku = IWL_SKU_G,
+	.ops = &iwl6000_ops,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
+	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_BC,
+	.valid_rx_ant = ANT_BC,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
+	.pa_type = IWL_PA_INTERNAL,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -208,61 +373,89 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.ucode_api_max = IWL6050_UCODE_API_MAX,
 	.ucode_api_min = IWL6050_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
-	.ops = &iwl6000_ops,
+	.ops = &iwl6050_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
-	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC,
 };
 
-struct iwl_cfg iwl6000_3agn_cfg = {
-	.name = "6000 Series 3x3 AGN",
-	.fw_name_pre = IWL6000_FW_PRE,
-	.ucode_api_max = IWL6000_UCODE_API_MAX,
-	.ucode_api_min = IWL6000_UCODE_API_MIN,
-	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
-	.ops = &iwl6000_ops,
+struct iwl_cfg iwl6050_2abg_cfg = {
+	.name = "6050 Series 2x2 ABG",
+	.fw_name_pre = IWL6050_FW_PRE,
+	.ucode_api_max = IWL6050_UCODE_API_MAX,
+	.ucode_api_min = IWL6050_UCODE_API_MIN,
+	.sku = IWL_SKU_A|IWL_SKU_G,
+	.ops = &iwl6050_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
-	.valid_tx_ant = ANT_ABC,
-	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = false,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_AB,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
-	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
 	.ht_greenfield_support = true,
-	.use_rts_for_ht = true, /* use rts/cts protection */
+	.led_compensation = 51,
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
 };
 
-struct iwl_cfg iwl6050_3agn_cfg = {
-	.name = "6050 Series 3x3 AGN",
-	.fw_name_pre = IWL6050_FW_PRE,
-	.ucode_api_max = IWL6050_UCODE_API_MAX,
-	.ucode_api_min = IWL6050_UCODE_API_MIN,
+struct iwl_cfg iwl6000_3agn_cfg = {
+	.name = "6000 Series 3x3 AGN",
+	.fw_name_pre = IWL6000_FW_PRE,
+	.ucode_api_max = IWL6000_UCODE_API_MAX,
+	.ucode_api_min = IWL6000_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
-	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.num_of_queues = IWL50_NUM_QUEUES,
+	.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.ht_greenfield_support = true,
+	.led_compensation = 51,
 	.use_rts_for_ht = true, /* use rts/cts protection */
+	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+	.supports_idle = true,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 };
 
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 14:02:21.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 12:09:53.000000000 -0400
@@ -123,6 +123,17 @@ int iwl_commit_rxon(struct iwl_priv *pri
 		return -EINVAL;
 	}
 
+	/*
+	 * receive commit_rxon request
+	 * abort any previous channel switch if still in process
+	 */
+	if (priv->switch_rxon.switch_in_progress &&
+	    (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
+		IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+		      le16_to_cpu(priv->switch_rxon.channel));
+		priv->switch_rxon.switch_in_progress = false;
+	}
+
 	/* If we don't need to send a full RXON, we can use
 	 * iwl_rxon_assoc_cmd which is used to reconfigure filter
 	 * and other flags for the current radio configuration. */
@@ -134,6 +145,7 @@ int iwl_commit_rxon(struct iwl_priv *pri
 		}
 
 		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+		iwl_print_rx_config_cmd(priv);
 		return 0;
 	}
 
@@ -191,11 +203,7 @@ int iwl_commit_rxon(struct iwl_priv *pri
 	priv->start_calib = 0;
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
-						IWL_INVALID_STATION) {
-		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
-		return -EIO;
-	}
+	iwl_add_bcast_station(priv);
 
 	/* If we have set the ASSOC_MSK and we are in BSS mode then
 	 * add the IWL_AP_ID to the station rate table */
@@ -233,6 +241,7 @@ int iwl_commit_rxon(struct iwl_priv *pri
 		}
 		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 	}
+	iwl_print_rx_config_cmd(priv);
 
 	iwl_init_sensitivity(priv);
 
@@ -302,7 +311,7 @@ static void iwl_free_frame(struct iwl_pr
 	list_add(&frame->list, &priv->free_frames);
 }
 
-static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
+static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
 					  struct ieee80211_hdr *hdr,
 					  int left)
 {
@@ -319,34 +328,74 @@ static unsigned int iwl_fill_beacon_fram
 	return priv->ibss_beacon->len;
 }
 
+/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
+static void iwl_set_beacon_tim(struct iwl_priv *priv,
+		struct iwl_tx_beacon_cmd *tx_beacon_cmd,
+		u8 *beacon, u32 frame_size)
+{
+	u16 tim_idx;
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
+
+	/*
+	 * The index is relative to frame start but we start looking at the
+	 * variable-length part of the beacon.
+	 */
+	tim_idx = mgmt->u.beacon.variable - beacon;
+
+	/* Parse variable-length elements of beacon to find WLAN_EID_TIM */
+	while ((tim_idx < (frame_size - 2)) &&
+			(beacon[tim_idx] != WLAN_EID_TIM))
+		tim_idx += beacon[tim_idx+1] + 2;
+
+	/* If TIM field was found, set variables */
+	if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
+		tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx);
+		tx_beacon_cmd->tim_size = beacon[tim_idx+1];
+	} else
+		IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
+}
+
 static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
-				       struct iwl_frame *frame, u8 rate)
+				       struct iwl_frame *frame)
 {
 	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
-	unsigned int frame_size;
+	u32 frame_size;
+	u32 rate_flags;
+	u32 rate;
+	/*
+	 * We have to set up the TX command, the TX Beacon command, and the
+	 * beacon contents.
+	 */
 
+	/* Initialize memory */
 	tx_beacon_cmd = &frame->u.beacon;
 	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
-	tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
-	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
+	/* Set up TX beacon contents */
 	frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
 				sizeof(frame->u) - sizeof(*tx_beacon_cmd));
+	if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
+		return 0;
 
-	BUG_ON(frame_size > MAX_MPDU_SIZE);
+	/* Set up TX command fields */
 	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
+	tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+	tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
+		TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
 
-	if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
-		tx_beacon_cmd->tx.rate_n_flags =
-			iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
-	else
-		tx_beacon_cmd->tx.rate_n_flags =
-			iwl_hw_set_rate_n_flags(rate, 0);
+	/* Set up TX beacon command fields */
+	iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
+			frame_size);
 
-	tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
-				     TX_CMD_FLG_TSF_MSK |
-				     TX_CMD_FLG_STA_RATE_MSK;
+	/* Set up packet rate and flags */
+	rate = iwl_rate_get_lowest_plcp(priv);
+	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
+	rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
+	if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE))
+		rate_flags |= RATE_MCS_CCK_MSK;
+	tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
+			rate_flags);
 
 	return sizeof(*tx_beacon_cmd) + frame_size;
 }
@@ -355,19 +404,20 @@ static int iwl_send_beacon_cmd(struct iw
 	struct iwl_frame *frame;
 	unsigned int frame_size;
 	int rc;
-	u8 rate;
 
 	frame = iwl_get_free_frame(priv);
-
 	if (!frame) {
 		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
 			  "command.\n");
 		return -ENOMEM;
 	}
 
-	rate = iwl_rate_get_lowest_plcp(priv);
-
-	frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
+	frame_size = iwl_hw_get_beacon_cmd(priv, frame);
+	if (!frame_size) {
+		IWL_ERR(priv, "Error configuring the beacon command\n");
+		iwl_free_frame(priv, frame);
+		return -EINVAL;
+	}
 
 	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
 			      &frame->u.cmd[0]);
@@ -525,7 +575,7 @@ int iwl_hw_tx_queue_init(struct iwl_priv
 static void iwl_rx_reply_alive(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_alive_resp *palive;
 	struct delayed_work *pwork;
 
@@ -604,14 +654,14 @@ static void iwl_bg_statistics_periodic(u
 	if (!iwl_is_ready_rf(priv))
 		return;
 
-	iwl_send_statistics_request(priv, CMD_ASYNC);
+	iwl_send_statistics_request(priv, CMD_ASYNC, false);
 }
 
 static void iwl_rx_beacon_notif(struct iwl_priv *priv,
 				struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl4965_beacon_notif *beacon =
 		(struct iwl4965_beacon_notif *)pkt->u.raw;
 	u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
@@ -635,7 +685,7 @@ static void iwl_rx_beacon_notif(struct i
 static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 				    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
 
@@ -721,7 +771,7 @@ static void iwl_setup_rx_handlers(struct
 	 * statistics request from the host as well as for the periodic
 	 * statistics notifications (after received beacons) from the uCode.
 	 */
-	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
+	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
 	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
 
 	iwl_setup_spectrum_handlers(priv);
@@ -770,7 +820,7 @@ void iwl_rx_handle(struct iwl_priv *priv
 		IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
 
 	/* calculate total frames need to be restock after handling RX */
-	total_empty = r - priv->rxq.write_actual;
+	total_empty = r - rxq->write_actual;
 	if (total_empty < 0)
 		total_empty += RX_QUEUE_SIZE;
 
@@ -787,10 +837,13 @@ void iwl_rx_handle(struct iwl_priv *priv
 
 		rxq->queue[i] = NULL;
 
-		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-				 priv->hw_params.rx_buf_size + 256,
-				 PCI_DMA_FROMDEVICE);
-		pkt = (struct iwl_rx_packet *)rxb->skb->data;
+		pci_unmap_page(priv->pci_dev, rxb->page_dma,
+			       PAGE_SIZE << priv->hw_params.rx_page_order,
+			       PCI_DMA_FROMDEVICE);
+		pkt = rxb_addr(rxb);
+
+		trace_iwlwifi_dev_rx(priv, pkt,
+			le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 		/* Reclaim a command buffer only if this packet is a response
 		 *   to a (driver-originated) command.
@@ -812,8 +865,8 @@ void iwl_rx_handle(struct iwl_priv *priv
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
 			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
 				i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 		} else {
 			/* No handling needed */
 			IWL_DEBUG_RX(priv,
@@ -822,35 +875,45 @@ void iwl_rx_handle(struct iwl_priv *priv
 				pkt->hdr.cmd);
 		}
 
+		/*
+		 * XXX: After here, we should always check rxb->page
+		 * against NULL before touching it or its virtual
+		 * memory (pkt). Because some rx_handler might have
+		 * already taken or freed the pages.
+		 */
+
 		if (reclaim) {
-			/* Invoke any callbacks, transfer the skb to caller, and
-			 * fire off the (possibly) blocking iwl_send_cmd()
+			/* Invoke any callbacks, transfer the buffer to caller,
+			 * and fire off the (possibly) blocking iwl_send_cmd()
 			 * as we reclaim the driver command queue */
-			if (rxb && rxb->skb)
+			if (rxb->page)
 				iwl_tx_cmd_complete(priv, rxb);
 			else
 				IWL_WARN(priv, "Claim null rxb?\n");
 		}
 
-		/* For now we just don't re-use anything.  We can tweak this
-		 * later to try and re-use notification packets and SKBs that
-		 * fail to Rx correctly */
-		if (rxb->skb != NULL) {
-			priv->alloc_rxb_skb--;
-			dev_kfree_skb_any(rxb->skb);
-			rxb->skb = NULL;
-		}
-
+		/* Reuse the page if possible. For notification packets and
+		 * SKBs that fail to Rx correctly, add them back into the
+		 * rx_free list for reuse later. */
 		spin_lock_irqsave(&rxq->lock, flags);
-		list_add_tail(&rxb->list, &priv->rxq.rx_used);
+		if (rxb->page != NULL) {
+			rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
+				0, PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			list_add_tail(&rxb->list, &rxq->rx_free);
+			rxq->free_count++;
+		} else
+			list_add_tail(&rxb->list, &rxq->rx_used);
+
 		spin_unlock_irqrestore(&rxq->lock, flags);
+
 		i = (i + 1) & RX_QUEUE_MASK;
 		/* If there are a lot of unused frames,
 		 * restock the Rx queue so ucode wont assert. */
 		if (fill_rx) {
 			count++;
 			if (count >= 8) {
-				priv->rxq.read = i;
+				rxq->read = i;
 				iwl_rx_replenish_now(priv);
 				count = 0;
 			}
@@ -858,7 +921,7 @@ void iwl_rx_handle(struct iwl_priv *priv
 	}
 
 	/* Backtrack one entry */
-	priv->rxq.read = i;
+	rxq->read = i;
 	if (fill_rx)
 		iwl_rx_replenish_now(priv);
 	else
@@ -878,6 +941,7 @@ static void iwl_irq_tasklet_legacy(struc
 	u32 inta, handled = 0;
 	u32 inta_fh;
 	unsigned long flags;
+	u32 i;
 #ifdef CONFIG_IWLWIFI_DEBUG
 	u32 inta_mask;
 #endif
@@ -905,6 +969,8 @@ static void iwl_irq_tasklet_legacy(struc
 	}
 #endif
 
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
 	 * atomic, make sure that inta covers all the interrupts that
 	 * we've discovered, even if FH interrupt came in just after
@@ -926,8 +992,6 @@ static void iwl_irq_tasklet_legacy(struc
 
 		handled |= CSR_INT_BIT_HW_ERR;
 
-		spin_unlock_irqrestore(&priv->lock, flags);
-
 		return;
 	}
 
@@ -995,19 +1059,17 @@ static void iwl_irq_tasklet_legacy(struc
 		handled |= CSR_INT_BIT_SW_ERR;
 	}
 
-	/* uCode wakes up after power-down sleep */
+	/*
+	 * uCode wakes up after power-down sleep.
+	 * Tell device about any new tx or host commands enqueued,
+	 * and about any Rx buffers made available while asleep.
+	 */
 	if (inta & CSR_INT_BIT_WAKEUP) {
 		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
 		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-		iwl_txq_update_write_ptr(priv, &priv->txq[0]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[1]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[2]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[3]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[4]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[5]);
-
+		for (i = 0; i < priv->hw_params.max_txq_num; i++)
+			iwl_txq_update_write_ptr(priv, &priv->txq[i]);
 		priv->isr_stats.wakeup++;
-
 		handled |= CSR_INT_BIT_WAKEUP;
 	}
 
@@ -1020,11 +1082,12 @@ static void iwl_irq_tasklet_legacy(struc
 		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
 	}
 
+	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
-		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
 		priv->isr_stats.tx++;
 		handled |= CSR_INT_BIT_FH_TX;
-		/* FH finished to write, send event */
+		/* Wake up uCode load routine, now that load is complete */
 		priv->ucode_write_complete = 1;
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
@@ -1054,7 +1117,6 @@ static void iwl_irq_tasklet_legacy(struc
 			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
 	}
 #endif
-	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /* tasklet for iwlagn interrupt */
@@ -1063,6 +1125,7 @@ static void iwl_irq_tasklet(struct iwl_p
 	u32 inta = 0;
 	u32 handled = 0;
 	unsigned long flags;
+	u32 i;
 #ifdef CONFIG_IWLWIFI_DEBUG
 	u32 inta_mask;
 #endif
@@ -1084,6 +1147,9 @@ static void iwl_irq_tasklet(struct iwl_p
 				inta, inta_mask);
 	}
 #endif
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* saved interrupt in inta variable now we can reset priv->inta */
 	priv->inta = 0;
 
@@ -1099,8 +1165,6 @@ static void iwl_irq_tasklet(struct iwl_p
 
 		handled |= CSR_INT_BIT_HW_ERR;
 
-		spin_unlock_irqrestore(&priv->lock, flags);
-
 		return;
 	}
 
@@ -1172,12 +1236,8 @@ static void iwl_irq_tasklet(struct iwl_p
 	if (inta & CSR_INT_BIT_WAKEUP) {
 		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
 		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-		iwl_txq_update_write_ptr(priv, &priv->txq[0]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[1]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[2]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[3]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[4]);
-		iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+		for (i = 0; i < priv->hw_params.max_txq_num; i++)
+			iwl_txq_update_write_ptr(priv, &priv->txq[i]);
 
 		priv->isr_stats.wakeup++;
 
@@ -1206,26 +1266,36 @@ static void iwl_irq_tasklet(struct iwl_p
 		 * 3- update RX shared data to indicate last write index.
 		 * 4- send interrupt.
 		 * This could lead to RX race, driver could receive RX interrupt
-		 * but the shared data changes does not reflect this.
-		 * this could lead to RX race, RX periodic will solve this race
+		 * but the shared data changes does not reflect this;
+		 * periodic interrupt will detect any dangling Rx activity.
 		 */
-		iwl_write32(priv, CSR_INT_PERIODIC_REG,
+
+		/* Disable periodic interrupt; we use it as just a one-shot. */
+		iwl_write8(priv, CSR_INT_PERIODIC_REG,
 			    CSR_INT_PERIODIC_DIS);
 		iwl_rx_handle(priv);
-		/* Only set RX periodic if real RX is received. */
+
+		/*
+		 * Enable periodic interrupt in 8 msec only if we received
+		 * real RX interrupt (instead of just periodic int), to catch
+		 * any dangling Rx interrupt.  If it was just the periodic
+		 * interrupt, there was no dangling Rx activity, and no need
+		 * to extend the periodic interrupt; one-shot is enough.
+		 */
 		if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
-			iwl_write32(priv, CSR_INT_PERIODIC_REG,
+			iwl_write8(priv, CSR_INT_PERIODIC_REG,
 				    CSR_INT_PERIODIC_ENA);
 
 		priv->isr_stats.rx++;
 	}
 
+	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
 		iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
-		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
 		priv->isr_stats.tx++;
 		handled |= CSR_INT_BIT_FH_TX;
-		/* FH finished to write, send event */
+		/* Wake up uCode load routine, now that load is complete */
 		priv->ucode_write_complete = 1;
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
@@ -1240,14 +1310,10 @@ static void iwl_irq_tasklet(struct iwl_p
 			 inta & ~priv->inta_mask);
 	}
 
-
 	/* Re-enable all interrupts */
 	/* only Re-enable if diabled by irq */
 	if (test_bit(STATUS_INT_ENABLED, &priv->status))
 		iwl_enable_interrupts(priv);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 }
 
 
@@ -1367,6 +1433,14 @@ static int iwl_read_ucode(struct iwl_pri
 	       IWL_UCODE_API(priv->ucode_ver),
 	       IWL_UCODE_SERIAL(priv->ucode_ver));
 
+	snprintf(priv->hw->wiphy->fw_version,
+		 sizeof(priv->hw->wiphy->fw_version),
+		 "%u.%u.%u.%u",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver));
+
 	if (build)
 		IWL_DEBUG_INFO(priv, "Build %u\n", build);
 
@@ -1531,7 +1605,6 @@ static int iwl_read_ucode(struct iwl_pri
 	return ret;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
 static const char *desc_lookup_text[] = {
 	"OK",
 	"FAIL",
@@ -1589,7 +1662,9 @@ void iwl_dump_nic_error_log(struct iwl_p
 		base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
-		IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
+		IWL_ERR(priv,
+			"Not valid error log pointer 0x%08X for %s uCode\n",
+			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
 		return;
 	}
 
@@ -1611,6 +1686,9 @@ void iwl_dump_nic_error_log(struct iwl_p
 	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
 	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
 
+	trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
+				      blink1, blink2, ilink1, ilink2);
+
 	IWL_ERR(priv, "Desc                               Time       "
 		"data1      data2      line\n");
 	IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
@@ -1635,6 +1713,7 @@ static void iwl_print_event_log(struct i
 	u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
 	u32 ptr;        /* SRAM byte address of log data */
 	u32 ev, time, data; /* event log data */
+	unsigned long reg_flags;
 
 	if (num_events == 0)
 		return;
@@ -1650,26 +1729,72 @@ static void iwl_print_event_log(struct i
 
 	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
+	/* Make sure device is powered up for SRAM reads */
+	spin_lock_irqsave(&priv->reg_lock, reg_flags);
+	iwl_grab_nic_access(priv);
+
+	/* Set starting address; reads will auto-increment */
+	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+	rmb();
+
 	/* "time" is actually "data" for mode 0 (no timestamp).
 	* place event id # at far right for easier visual parsing. */
 	for (i = 0; i < num_events; i++) {
-		ev = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
-		time = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
+		ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
+			trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
 			IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
 		} else {
-			data = iwl_read_targ_mem(priv, ptr);
-			ptr += sizeof(u32);
+			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 			IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
 					time, data, ev);
+			trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
 		}
 	}
+
+	/* Allow device to power down */
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
-void iwl_dump_nic_event_log(struct iwl_priv *priv)
+/**
+ * iwl_print_last_event_logs - Dump the newest # of event log to syslog
+ */
+static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
+				      u32 num_wraps, u32 next_entry,
+				      u32 size, u32 mode)
+{
+	/*
+	 * display the newest DEFAULT_LOG_ENTRIES entries
+	 * i.e the entries just before the next ont that uCode would fill.
+	 */
+	if (num_wraps) {
+		if (next_entry < size) {
+			iwl_print_event_log(priv,
+					capacity - (size - next_entry),
+					size - next_entry, mode);
+			iwl_print_event_log(priv, 0,
+				    next_entry, mode);
+		} else
+			iwl_print_event_log(priv, next_entry - size,
+				    size, mode);
+	} else {
+		if (next_entry < size)
+			iwl_print_event_log(priv, 0, next_entry, mode);
+		else
+			iwl_print_event_log(priv, next_entry - size,
+					    size, mode);
+	}
+}
+
+/* For sanity check only.  Actual size is determined by uCode, typ. 512 */
+#define MAX_EVENT_LOG_SIZE (512)
+
+#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
+
+void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
 {
 	u32 base;       /* SRAM byte address of event log header */
 	u32 capacity;   /* event log capacity in # entries */
@@ -1684,7 +1809,9 @@ void iwl_dump_nic_event_log(struct iwl_p
 		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 
 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
-		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
+		IWL_ERR(priv,
+			"Invalid event log pointer 0x%08X for %s uCode\n",
+			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
 		return;
 	}
 
@@ -1694,6 +1821,18 @@ void iwl_dump_nic_event_log(struct iwl_p
 	num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
 	next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
+	if (capacity > MAX_EVENT_LOG_SIZE) {
+		IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
+			capacity, MAX_EVENT_LOG_SIZE);
+		capacity = MAX_EVENT_LOG_SIZE;
+	}
+
+	if (next_entry > MAX_EVENT_LOG_SIZE) {
+		IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
+			next_entry, MAX_EVENT_LOG_SIZE);
+		next_entry = MAX_EVENT_LOG_SIZE;
+	}
+
 	size = num_wraps ? capacity : next_entry;
 
 	/* bail out if nothing in log */
@@ -1702,19 +1841,37 @@ void iwl_dump_nic_event_log(struct iwl_p
 		return;
 	}
 
-	IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
-			size, num_wraps);
-
-	/* if uCode has wrapped back to top of log, start at the oldest entry,
-	 * i.e the next one that uCode would fill. */
-	if (num_wraps)
-		iwl_print_event_log(priv, next_entry,
-					capacity - next_entry, mode);
-	/* (then/else) start at top of log */
-	iwl_print_event_log(priv, 0, next_entry, mode);
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (!(iwl_get_debug_level(priv) & 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);
 
-}
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
+		/*
+		 * if uCode has wrapped back to top of log,
+		 * start at the oldest entry,
+		 * i.e the next one that uCode would fill.
+		 */
+		if (num_wraps)
+			iwl_print_event_log(priv, next_entry,
+					    capacity - next_entry, mode);
+		/* (then/else) start at top of log */
+		iwl_print_event_log(priv, 0, next_entry, mode);
+	} else
+		iwl_print_last_event_logs(priv, capacity, num_wraps,
+					next_entry, size, mode);
+#else
+	iwl_print_last_event_logs(priv, capacity, num_wraps,
+				next_entry, size, mode);
 #endif
+}
 
 /**
  * iwl_alive_start - called after REPLY_ALIVE notification received
@@ -1763,6 +1920,10 @@ static void iwl_alive_start(struct iwl_p
 	priv->active_rate = priv->rates_mask;
 	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
+	/* Configure Tx antenna selection based on H/W config */
+	if (priv->cfg->ops->hcmd->set_tx_ant)
+		priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
+
 	if (iwl_is_associated(priv)) {
 		struct iwl_rxon_cmd *active_rxon =
 				(struct iwl_rxon_cmd *)&priv->active_rxon;
@@ -1790,7 +1951,7 @@ static void iwl_alive_start(struct iwl_p
 	/* At this point, the NIC is initialized and operational */
 	iwl_rf_kill_ct_config(priv);
 
-	iwl_leds_register(priv);
+	iwl_leds_init(priv);
 
 	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
 	set_bit(STATUS_READY, &priv->status);
@@ -1828,8 +1989,6 @@ static void __iwl_down(struct iwl_priv *
 	if (!exit_pending)
 		set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	iwl_leds_unregister(priv);
-
 	iwl_clear_stations_table(priv);
 
 	/* Unblock any waiting calls */
@@ -1877,24 +2036,20 @@ static void __iwl_down(struct iwl_priv *
 
 	/* device going down, Stop using ICT table */
 	iwl_disable_ict(priv);
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl_clear_bit(priv, CSR_GP_CNTRL,
-			 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-	spin_unlock_irqrestore(&priv->lock, flags);
 
 	iwl_txq_ctx_stop(priv);
 	iwl_rxq_stop(priv);
 
-	iwl_write_prph(priv, APMG_CLK_DIS_REG,
-				APMG_CLK_VAL_DMA_CLK_RQT);
-
+	/* Power-down device's busmaster DMA clocks */
+	iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 	udelay(5);
 
-	/* FIXME: apm_ops.suspend(priv) */
-	if (exit_pending)
-		priv->cfg->ops->lib->apm_ops.stop(priv);
-	else
-		priv->cfg->ops->lib->apm_ops.reset(priv);
+	/* Make sure (redundant) we've released our request to stay awake */
+	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+	/* Stop the device, and put it in low power state */
+	priv->cfg->ops->lib->apm_ops.stop(priv);
+
  exit:
 	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
@@ -2281,6 +2436,67 @@ void iwl_post_associate(struct iwl_priv
 
 #define UCODE_READY_TIMEOUT	(4 * HZ)
 
+/*
+ * Not a mac80211 entry point function, but it fits in with all the
+ * other mac80211 functions grouped here.
+ */
+static int iwl_setup_mac(struct iwl_priv *priv)
+{
+	int ret;
+	struct ieee80211_hw *hw = priv->hw;
+	hw->rate_control_algorithm = "iwl-agn-rs";
+
+	/* Tell mac80211 our characteristics */
+	hw->flags = IEEE80211_HW_SIGNAL_DBM |
+		    IEEE80211_HW_NOISE_DBM |
+		    IEEE80211_HW_AMPDU_AGGREGATION |
+		    IEEE80211_HW_SPECTRUM_MGMT;
+
+	if (!priv->cfg->broken_powersave)
+		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+
+	hw->sta_data_size = sizeof(struct iwl_station_priv);
+	hw->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) |
+		BIT(NL80211_IFTYPE_ADHOC);
+
+	hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+			    WIPHY_FLAG_DISABLE_BEACON_HINTS;
+
+	/*
+	 * For now, disable PS by default because it affects
+	 * RX performance significantly.
+	 */
+	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
+	/* we create the 802.11 header and a zero-length SSID element */
+	hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
+
+	/* Default value; 4 EDCA QOS priorities */
+	hw->queues = 4;
+
+	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
+
+	if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+		priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+			&priv->bands[IEEE80211_BAND_2GHZ];
+	if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+		priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+			&priv->bands[IEEE80211_BAND_5GHZ];
+
+	ret = ieee80211_register_hw(priv->hw);
+	if (ret) {
+		IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
+		return ret;
+	}
+	priv->mac80211_registered = 1;
+
+	return 0;
+}
+
+
 static int iwl_mac_start(struct ieee80211_hw *hw)
 {
 	struct iwl_priv *priv = hw->priv;
@@ -2328,6 +2544,8 @@ static int iwl_mac_start(struct ieee8021
 		}
 	}
 
+	iwl_led_start(priv);
+
 out:
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2404,6 +2622,10 @@ void iwl_config_ap(struct iwl_priv *priv
 			IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
 					"Attempting to continue.\n");
 
+		/* AP has all antennas */
+		priv->chain_noise_data.active_chains =
+			priv->hw_params.valid_rx_ant;
+		iwl_set_rxon_ht(priv, &priv->current_ht_config);
 		if (priv->cfg->ops->hcmd->set_rxon_chain)
 			priv->cfg->ops->hcmd->set_rxon_chain(priv);
 
@@ -2432,10 +2654,11 @@ void iwl_config_ap(struct iwl_priv *priv
 		/* restore RXON assoc */
 		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		iwlcore_commit_rxon(priv);
+		iwl_reset_qos(priv);
 		spin_lock_irqsave(&priv->lock, flags);
 		iwl_activate_qos(priv, 1);
 		spin_unlock_irqrestore(&priv->lock, flags);
-		iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
+		iwl_add_bcast_station(priv);
 	}
 	iwl_send_beacon_cmd(priv);
 
@@ -2527,6 +2750,7 @@ static int iwl_mac_set_key(struct ieee80
 }
 
 static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif,
 			     enum ieee80211_ampdu_mlme_action action,
 			     struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
@@ -2580,6 +2804,45 @@ static int iwl_mac_get_stats(struct ieee
 	return 0;
 }
 
+static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       enum sta_notify_cmd cmd,
+			       struct ieee80211_sta *sta)
+{
+	struct iwl_priv *priv = hw->priv;
+	struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+	int sta_id;
+
+	/*
+	 * TODO: We really should use this callback to
+	 *	 actually maintain the station table in
+	 *	 the device.
+	 */
+
+	switch (cmd) {
+	case STA_NOTIFY_ADD:
+		atomic_set(&sta_priv->pending_frames, 0);
+		if (vif->type == NL80211_IFTYPE_AP)
+			sta_priv->client = true;
+		break;
+	case STA_NOTIFY_SLEEP:
+		WARN_ON(!sta_priv->client);
+		sta_priv->asleep = true;
+		if (atomic_read(&sta_priv->pending_frames) > 0)
+			ieee80211_sta_block_awake(hw, sta, true);
+		break;
+	case STA_NOTIFY_AWAKE:
+		WARN_ON(!sta_priv->client);
+		sta_priv->asleep = false;
+		sta_id = iwl_find_station(priv, sta->addr);
+		if (sta_id != IWL_INVALID_STATION)
+			iwl_sta_modify_ps_wake(priv, sta_id);
+		break;
+	default:
+		break;
+	}
+}
+
 /*****************************************************************************
  *
  * sysfs attributes
@@ -2774,7 +3037,7 @@ static ssize_t show_statistics(struct de
 		return -EAGAIN;
 
 	mutex_lock(&priv->mutex);
-	rc = iwl_send_statistics_request(priv, 0);
+	rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
 	mutex_unlock(&priv->mutex);
 
 	if (rc) {
@@ -2799,6 +3062,40 @@ static ssize_t show_statistics(struct de
 
 static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
 
+static ssize_t show_rts_ht_protection(struct device *d,
+			     struct device_attribute *attr, char *buf)
+{
+	struct iwl_priv *priv = dev_get_drvdata(d);
+
+	return sprintf(buf, "%s\n",
+		priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self");
+}
+
+static ssize_t store_rts_ht_protection(struct device *d,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct iwl_priv *priv = dev_get_drvdata(d);
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		IWL_INFO(priv, "Input is not in decimal form.\n");
+	else {
+		if (!iwl_is_associated(priv))
+			priv->cfg->use_rts_for_ht = val ? true : false;
+		else
+			IWL_ERR(priv, "Sta associated with AP - "
+				"Change protection mechanism is not allowed\n");
+		ret = count;
+	}
+	return ret;
+}
+
+static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO,
+			show_rts_ht_protection, store_rts_ht_protection);
+
 
 /*****************************************************************************
  *
@@ -2849,12 +3146,102 @@ static void iwl_cancel_deferred_work(str
 	del_timer_sync(&priv->statistics_periodic);
 }
 
+static void iwl_init_hw_rates(struct iwl_priv *priv,
+			      struct ieee80211_rate *rates)
+{
+	int i;
+
+	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
+		rates[i].bitrate = iwl_rates[i].ieee * 5;
+		rates[i].hw_value = i; /* Rate scaling will work on indexes */
+		rates[i].hw_value_short = i;
+		rates[i].flags = 0;
+		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
+			/*
+			 * If CCK != 1M then set short preamble rate flag.
+			 */
+			rates[i].flags |=
+				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
+					0 : IEEE80211_RATE_SHORT_PREAMBLE;
+		}
+	}
+}
+
+static int iwl_init_drv(struct iwl_priv *priv)
+{
+	int ret;
+
+	priv->ibss_beacon = NULL;
+
+	spin_lock_init(&priv->sta_lock);
+	spin_lock_init(&priv->hcmd_lock);
+
+	INIT_LIST_HEAD(&priv->free_frames);
+
+	mutex_init(&priv->mutex);
+
+	/* Clear the driver's (not device's) station table */
+	iwl_clear_stations_table(priv);
+
+	priv->ieee_channels = NULL;
+	priv->ieee_rates = NULL;
+	priv->band = IEEE80211_BAND_2GHZ;
+
+	priv->iw_mode = NL80211_IFTYPE_STATION;
+
+	/* Choose which receivers/antennas to use */
+	if (priv->cfg->ops->hcmd->set_rxon_chain)
+		priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+	iwl_init_scan_params(priv);
+
+	iwl_reset_qos(priv);
+
+	priv->qos_data.qos_active = 0;
+	priv->qos_data.qos_cap.val = 0;
+
+	priv->rates_mask = IWL_RATES_MASK;
+	/* Set the tx_power_user_lmt to the lowest power level
+	 * this value will get overwritten by channel max power avg
+	 * from eeprom */
+	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
+
+	ret = iwl_init_channel_map(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+		goto err;
+	}
+
+	ret = iwlcore_init_geos(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+		goto err_free_channel_map;
+	}
+	iwl_init_hw_rates(priv, priv->ieee_rates);
+
+	return 0;
+
+err_free_channel_map:
+	iwl_free_channel_map(priv);
+err:
+	return ret;
+}
+
+static void iwl_uninit_drv(struct iwl_priv *priv)
+{
+	iwl_calib_free_results(priv);
+	iwlcore_free_geos(priv);
+	iwl_free_channel_map(priv);
+	kfree(priv->scan);
+}
+
 static struct attribute *iwl_sysfs_entries[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
 	&dev_attr_statistics.attr,
 	&dev_attr_temperature.attr,
 	&dev_attr_tx_power.attr,
+	&dev_attr_rts_ht_protection.attr,
 #ifdef CONFIG_IWLWIFI_DEBUG
 	&dev_attr_debug_level.attr,
 #endif
@@ -2882,7 +3269,8 @@ static struct ieee80211_ops iwl_hw_ops =
 	.reset_tsf = iwl_mac_reset_tsf,
 	.bss_info_changed = iwl_bss_info_changed,
 	.ampdu_action = iwl_mac_ampdu_action,
-	.hw_scan = iwl_mac_hw_scan
+	.hw_scan = iwl_mac_hw_scan,
+	.sta_notify = iwl_mac_sta_notify,
 };
 
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -2972,10 +3360,11 @@ static int iwl_pci_probe(struct pci_dev
 		(unsigned long long) pci_resource_len(pdev, 0));
 	IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
 
-	/* this spin lock will be used in apm_ops.init and EEPROM access
+	/* these spin locks will be used in apm_ops.init and EEPROM access
 	 * we should init now
 	 */
 	spin_lock_init(&priv->reg_lock);
+	spin_lock_init(&priv->lock);
 	iwl_hw_detect(priv);
 	IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
 		priv->cfg->name, priv->hw_rev);
@@ -2990,12 +3379,6 @@ static int iwl_pci_probe(struct pci_dev
 		goto out_iounmap;
 	}
 
-	/* amp init */
-	err = priv->cfg->ops->lib->apm_ops.init(priv);
-	if (err < 0) {
-		IWL_ERR(priv, "Failed to init APMG\n");
-		goto out_iounmap;
-	}
 	/*****************
 	 * 4. Read EEPROM
 	 *****************/
@@ -3141,6 +3524,15 @@ static void __devexit iwl_pci_remove(str
 		iwl_down(priv);
 	}
 
+	/*
+	 * Make sure device is reset to low power before unloading driver.
+	 * This may be redundant with iwl_down(), but there are paths to
+	 * run iwl_down() without calling apm_ops.stop(), and there are
+	 * paths to avoid running iwl_down() at all before leaving driver.
+	 * This (inexpensive) call *makes sure* device is reset.
+	 */
+	priv->cfg->ops->lib->apm_ops.stop(priv);
+
 	iwl_tt_exit(priv);
 
 	/* make sure we flush any pending irq or
@@ -3203,37 +3595,97 @@ static struct pci_device_id iwl_hw_card_
 	{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
 #endif /* CONFIG_IWL4965 */
 #ifdef CONFIG_IWL5000
-	{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
-	{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
-	{IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)},
-	{IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)},
-	{IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)},
-	{IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)},
-	{IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)},
-	{IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)},
-	{IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)},
-	{IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)},
-/* 5350 WiFi/WiMax */
-	{IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)},
-	{IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)},
-	{IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)},
-/* 5150 Wifi/WiMax */
-	{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
-	{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
-/* 6000/6050 Series */
-	{IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
+/* 5100 Series WiFi */
+	{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 */
+	{IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */
+
+/* 5300 Series WiFi */
+	{IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */
+
+/* 5350 Series WiFi/WiMax */
+	{IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */
+
+/* 5150 Series Wifi/WiMax */
+	{IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */
+	{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(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */
+	{IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */
+
+/* 6x00 Series */
+	{IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)},
+	{IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)},
+	{IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)},
+	{IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
+
+/* 6x50 WiFi/WiMax Series */
+	{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)},
+	{IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)},
+	{IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
+
 /* 1000 Series WiFi */
-	{IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
 #endif /* CONFIG_IWL5000 */
 
 	{0}
@@ -3288,9 +3740,9 @@ module_exit(iwl_exit);
 module_init(iwl_init);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-module_param_named(debug50, iwl_debug_level, uint, 0444);
+module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
 MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
-module_param_named(debug, iwl_debug_level, uint, 0644);
+module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "debug output mask");
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2009 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 LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-commands.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-agn-led.h"
+
+/* Send led command */
+static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
+{
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_LEDS_CMD,
+		.len = sizeof(struct iwl_led_cmd),
+		.data = led_cmd,
+		.flags = CMD_ASYNC,
+		.callback = NULL,
+	};
+	u32 reg;
+
+	reg = iwl_read32(priv, CSR_LED_REG);
+	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
+		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+
+	return iwl_send_cmd(priv, &cmd);
+}
+
+/* Set led register off */
+static int iwl_led_on_reg(struct iwl_priv *priv)
+{
+	IWL_DEBUG_LED(priv, "led on\n");
+	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+	return 0;
+}
+
+/* Set led register off */
+static int iwl_led_off_reg(struct iwl_priv *priv)
+{
+	IWL_DEBUG_LED(priv, "LED Reg off\n");
+	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
+	return 0;
+}
+
+const struct iwl_led_ops iwlagn_led_ops = {
+	.cmd = iwl_send_led_cmd,
+	.on = iwl_led_on_reg,
+	.off = iwl_led_off_reg,
+};
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-led.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2009 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 LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#ifndef __iwl_agn_led_h__
+#define __iwl_agn_led_h__
+
+extern const struct iwl_led_ops iwlagn_led_ops;
+
+#endif /* __iwl_agn_led_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,104 +75,6 @@ static const u8 ant_toggle_lookup[] = {
 	/*ANT_ABC  -> */ ANT_ABC,
 };
 
-/**
- * struct iwl_rate_scale_data -- tx success history for one rate
- */
-struct iwl_rate_scale_data {
-	u64 data;		/* bitmap of successful frames */
-	s32 success_counter;	/* number of frames successful */
-	s32 success_ratio;	/* per-cent * 128  */
-	s32 counter;		/* number of frames attempted */
-	s32 average_tpt;	/* success ratio * expected throughput */
-	unsigned long stamp;
-};
-
-/**
- * struct iwl_scale_tbl_info -- tx params and success history for all rates
- *
- * There are two of these in struct iwl_lq_sta,
- * one for "active", and one for "search".
- */
-struct iwl_scale_tbl_info {
-	enum iwl_table_type lq_type;
-	u8 ant_type;
-	u8 is_SGI;	/* 1 = short guard interval */
-	u8 is_ht40;	/* 1 = 40 MHz channel width */
-	u8 is_dup;	/* 1 = duplicated data streams */
-	u8 action;	/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
-	u8 max_search;	/* maximun number of tables we can search */
-	s32 *expected_tpt;	/* throughput metrics; expected_tpt_G, etc. */
-	u32 current_rate;  /* rate_n_flags, uCode API format */
-	struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
-};
-
-struct iwl_traffic_load {
-	unsigned long time_stamp;	/* age of the oldest statistics */
-	u32 packet_count[TID_QUEUE_MAX_SIZE];   /* packet count in this time
-						 * slice */
-	u32 total;			/* total num of packets during the
-					 * last TID_MAX_TIME_DIFF */
-	u8 queue_count;			/* number of queues that has
-					 * been used since the last cleanup */
-	u8 head;			/* start of the circular buffer */
-};
-
-/**
- * struct iwl_lq_sta -- driver's rate scaling private structure
- *
- * Pointer to this gets passed back and forth between driver and mac80211.
- */
-struct iwl_lq_sta {
-	u8 active_tbl;		/* index of active table, range 0-1 */
-	u8 enable_counter;	/* indicates HT mode */
-	u8 stay_in_tbl;		/* 1: disallow, 0: allow search for new mode */
-	u8 search_better_tbl;	/* 1: currently trying alternate mode */
-	s32 last_tpt;
-
-	/* The following determine when to search for a new mode */
-	u32 table_count_limit;
-	u32 max_failure_limit;	/* # failed frames before new search */
-	u32 max_success_limit;	/* # successful frames before new search */
-	u32 table_count;
-	u32 total_failed;	/* total failed frames, any/all rates */
-	u32 total_success;	/* total successful frames, any/all rates */
-	u64 flush_timer;	/* time staying in mode before new search */
-
-	u8 action_counter;	/* # mode-switch actions tried */
-	u8 is_green;
-	u8 is_dup;
-	enum ieee80211_band band;
-	u8 ibss_sta_added;
-
-	/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
-	u32 supp_rates;
-	u16 active_legacy_rate;
-	u16 active_siso_rate;
-	u16 active_mimo2_rate;
-	u16 active_mimo3_rate;
-	u16 active_rate_basic;
-	s8 max_rate_idx;     /* Max rate set by user */
-	u8 missed_rate_counter;
-
-	struct iwl_link_quality_cmd lq;
-	struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
-	struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
-	u8 tx_agg_tid_en;
-#ifdef CONFIG_MAC80211_DEBUGFS
-	struct dentry *rs_sta_dbgfs_scale_table_file;
-	struct dentry *rs_sta_dbgfs_stats_table_file;
-	struct dentry *rs_sta_dbgfs_rate_scale_data_file;
-	struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
-	u32 dbg_fixed_rate;
-#endif
-	struct iwl_priv *drv;
-
-	/* used to be in sta_info */
-	int last_txrate_idx;
-	/* last tx rate_n_flags */
-	u32 last_rate_n_flags;
-};
-
 static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct sk_buff *skb,
 				   struct ieee80211_sta *sta,
@@ -190,84 +92,78 @@ static void rs_dbgfs_set_mcs(struct iwl_
 {}
 #endif
 
-/*
- * Expected throughput metrics for following rates:
- * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
- * "G" is the only table that supports CCK (the first 4 rates).
+/**
+ * The following tables contain the expected throughput metrics for all rates
+ *
+ *	1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
+ *
+ * where invalid entries are zeros.
+ *
+ * CCK rates are only valid in legacy table and will only be used in G
+ * (2.4 GHz) band.
  */
 
-static s32 expected_tpt_A[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
-};
-
-static s32 expected_tpt_G[IWL_RATE_COUNT] = {
-	7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 186
-};
-
-static s32 expected_tpt_siso20MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 42, 42, 76, 102, 124, 159, 183, 193, 202
-};
-
-static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
-};
-
-static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
-};
-
-static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
-};
-
-static s32 expected_tpt_siso40MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 77, 77, 127, 160, 184, 220, 242, 250, 257
-};
-
-static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
+static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
+	7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0
 };
 
-static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
+static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0, 42, 0,  76, 102, 124, 158, 183, 193, 202}, /* Norm */
+	{0, 0, 0, 0, 46, 0,  82, 110, 132, 167, 192, 202, 210}, /* SGI */
+	{0, 0, 0, 0, 48, 0,  93, 135, 176, 251, 319, 351, 381}, /* AGG */
+	{0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */
 };
 
-static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
+static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0,  77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */
+	{0, 0, 0, 0,  83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */
+	{0, 0, 0, 0,  96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */
+	{0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */
 };
 
-/* Expected throughput metric MIMO3 */
-static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268
+static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0,  74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */
+	{0, 0, 0, 0,  81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */
+	{0, 0, 0, 0,  92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */
+	{0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/
 };
 
-static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273
+static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */
+	{0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */
+	{0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */
+	{0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */
 };
 
-static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297
+static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0,  99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */
+	{0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */
+	{0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */
+	{0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */
 };
 
-static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = {
-	0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300
+static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {
+	{0, 0, 0, 0, 152, 0, 211, 239, 255, 279,  290,  294,  297}, /* Norm */
+	{0, 0, 0, 0, 160, 0, 219, 245, 261, 284,  294,  297,  300}, /* SGI */
+	{0, 0, 0, 0, 254, 0, 443, 584, 695, 868,  984, 1030, 1070}, /* AGG */
+	{0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */
 };
 
 /* mbps, mcs */
-const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
-  {"1", ""},
-  {"2", ""},
-  {"5.5", ""},
-  {"11", ""},
-  {"6", "BPSK 1/2"},
-  {"9", "BPSK 1/2"},
-  {"12", "QPSK 1/2"},
-  {"18", "QPSK 3/4"},
-  {"24", "16QAM 1/2"},
-  {"36", "16QAM 3/4"},
-  {"48", "64QAM 2/3"},
-  {"54", "64QAM 3/4"},
-  {"60", "64QAM 5/6"}
+static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
+	{  "1", "BPSK DSSS"},
+	{  "2", "QPSK DSSS"},
+	{"5.5", "BPSK CCK"},
+	{ "11", "QPSK CCK"},
+	{  "6", "BPSK 1/2"},
+	{  "9", "BPSK 1/2"},
+	{ "12", "QPSK 1/2"},
+	{ "18", "QPSK 3/4"},
+	{ "24", "16QAM 1/2"},
+	{ "36", "16QAM 3/4"},
+	{ "48", "64QAM 2/3"},
+	{ "54", "64QAM 3/4"},
+	{ "60", "64QAM 5/6"},
 };
 
 #define MCS_INDEX_PER_STREAM	(8)
@@ -405,7 +301,7 @@ static void rs_tl_turn_on_agg_for_tid(st
 	if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
 		IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
 				sta->addr, tid);
-		ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
+		ieee80211_start_tx_ba_session(sta, tid);
 	}
 }
 
@@ -444,7 +340,7 @@ static inline int get_num_of_ant_from_ra
  * packets.
  */
 static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
-			      int scale_index, s32 tpt, int retries,
+			      int scale_index, s32 tpt, int attempts,
 			      int successes)
 {
 	struct iwl_rate_scale_data *window = NULL;
@@ -454,7 +350,7 @@ static int rs_collect_tx_data(struct iwl
 	if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
 		return -EINVAL;
 
-	/* Select data for current tx bit rate */
+	/* Select window for current tx bit rate */
 	window = &(windows[scale_index]);
 
 	/*
@@ -465,7 +361,7 @@ static int rs_collect_tx_data(struct iwl
 	 * subtract "1" from the success counter (this is the main reason
 	 * we keep these bitmaps!).
 	 */
-	while (retries > 0) {
+	while (attempts > 0) {
 		if (window->counter >= IWL_RATE_MAX_WINDOW) {
 
 			/* remove earliest */
@@ -480,17 +376,17 @@ static int rs_collect_tx_data(struct iwl
 		/* Increment frames-attempted counter */
 		window->counter++;
 
-		/* Shift bitmap by one frame (throw away oldest history),
-		 * OR in "1", and increment "success" if this
-		 * frame was successful. */
+		/* Shift bitmap by one frame to throw away oldest history */
 		window->data <<= 1;
+
+		/* Mark the most recent #successes attempts as successful */
 		if (successes > 0) {
 			window->success_counter++;
 			window->data |= 0x1;
 			successes--;
 		}
 
-		retries--;
+		attempts--;
 	}
 
 	/* Calculate current success ratio, avoid divide-by-0! */
@@ -671,7 +567,7 @@ static int rs_toggle_antenna(u32 valid_a
  * there are no non-GF stations present in the BSS.
  */
 static inline u8 rs_use_green(struct ieee80211_sta *sta,
-			      struct iwl_ht_info *ht_conf)
+			      struct iwl_ht_config *ht_conf)
 {
 	return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
 		!(ht_conf->non_GF_STA_present);
@@ -821,27 +717,45 @@ out:
 }
 
 /*
+ * Simple function to compare two rate scale table types
+ */
+static bool table_type_matches(struct iwl_scale_tbl_info *a,
+			       struct iwl_scale_tbl_info *b)
+{
+	return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
+		(a->is_SGI == b->is_SGI);
+}
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+	if (tbl->expected_tpt)
+		return tbl->expected_tpt[rs_index];
+	return 0;
+}
+
+/*
  * mac80211 sends us Tx status
  */
 static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 			 struct ieee80211_sta *sta, void *priv_sta,
 			 struct sk_buff *skb)
 {
-	int status;
-	u8 retries;
-	int rs_index, mac_index, index = 0;
+	int legacy_success;
+	int retries;
+	int rs_index, mac_index, i;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_link_quality_cmd *table;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct iwl_rate_scale_data *window = NULL;
-	struct iwl_rate_scale_data *search_win = NULL;
 	enum mac80211_rate_control_flags mac_flags;
 	u32 tx_rate;
 	struct iwl_scale_tbl_info tbl_type;
-	struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
-	u8 active_index = 0;
+	struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
 	s32 tpt = 0;
 
 	IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -850,30 +764,14 @@ static void rs_tx_status(void *priv_r, s
 	    info->flags & IEEE80211_TX_CTL_NO_ACK)
 		return;
 
-	/* This packet was aggregated but doesn't carry rate scale info */
+	/* This packet was aggregated but doesn't carry status info */
 	if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
 	    !(info->flags & IEEE80211_TX_STAT_AMPDU))
 		return;
 
-	if (info->flags & IEEE80211_TX_STAT_AMPDU)
-		retries = 0;
-	else
-		retries = info->status.rates[0].count - 1;
-
-	if (retries > 15)
-		retries = 15;
-
 	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
 	    !lq_sta->ibss_sta_added)
-		goto out;
-
-	table = &lq_sta->lq;
-	active_index = lq_sta->active_tbl;
-
-	curr_tbl = &(lq_sta->lq_info[active_index]);
-	search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
-	window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
-	search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
+		return;
 
 	/*
 	 * Ignore this Tx frame response if its initial rate doesn't match
@@ -883,6 +781,7 @@ static void rs_tx_status(void *priv_r, s
 	 * to check "search" mode, or a prior "search" mode after we've moved
 	 * to a new "search" mode (which might become the new "active" mode).
 	 */
+	table = &lq_sta->lq;
 	tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
 	rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
 	if (priv->band == IEEE80211_BAND_5GHZ)
@@ -901,7 +800,7 @@ static void rs_tx_status(void *priv_r, s
 		if (priv->band == IEEE80211_BAND_2GHZ)
 			mac_index += IWL_FIRST_OFDM_RATE;
 	}
-
+	/* Here we actually compare this rate to the latest LQ command */
 	if ((mac_index < 0) ||
 	    (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
 	    (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
@@ -911,124 +810,106 @@ static void rs_tx_status(void *priv_r, s
 	    (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
 	    (rs_index != mac_index)) {
 		IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
-		/* the last LQ command could failed so the LQ in ucode not
-		 * the same in driver sync up
+		/*
+		 * Since rates mis-match, the last LQ command may have failed.
+		 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
+		 * ... driver.
 		 */
 		lq_sta->missed_rate_counter++;
 		if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
 			lq_sta->missed_rate_counter = 0;
 			iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 		}
-		goto out;
-	}
-
-	lq_sta->missed_rate_counter = 0;
-	/* Update frame history window with "failure" for each Tx retry. */
-	while (retries) {
-		/* Look up the rate and other info used for each tx attempt.
-		 * Each tx attempt steps one entry deeper in the rate table. */
-		tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
-		rs_get_tbl_info_from_mcs(tx_rate, priv->band,
-					  &tbl_type, &rs_index);
-
-		/* If type matches "search" table,
-		 * add failure to "search" history */
-		if ((tbl_type.lq_type == search_tbl->lq_type) &&
-		    (tbl_type.ant_type == search_tbl->ant_type) &&
-		    (tbl_type.is_SGI == search_tbl->is_SGI)) {
-			if (search_tbl->expected_tpt)
-				tpt = search_tbl->expected_tpt[rs_index];
-			else
-				tpt = 0;
-			rs_collect_tx_data(search_win, rs_index, tpt, 1, 0);
-
-		/* Else if type matches "current/active" table,
-		 * add failure to "current/active" history */
-		} else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
-			   (tbl_type.ant_type == curr_tbl->ant_type) &&
-			   (tbl_type.is_SGI == curr_tbl->is_SGI)) {
-			if (curr_tbl->expected_tpt)
-				tpt = curr_tbl->expected_tpt[rs_index];
-			else
-				tpt = 0;
-			rs_collect_tx_data(window, rs_index, tpt, 1, 0);
-		}
-
-		/* If not searching for a new mode, increment failed counter
-		 * ... this helps determine when to start searching again */
-		if (lq_sta->stay_in_tbl)
-			lq_sta->total_failed++;
-		--retries;
-		index++;
+		/* Regardless, ignore this status info for outdated rate */
+		return;
+	} else
+		/* Rate did match, so reset the missed_rate_counter */
+		lq_sta->missed_rate_counter = 0;
 
+	/* Figure out if rate scale algorithm is in active or search table */
+	if (table_type_matches(&tbl_type,
+				&(lq_sta->lq_info[lq_sta->active_tbl]))) {
+		curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+		other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
+	} else if (table_type_matches(&tbl_type,
+				&lq_sta->lq_info[1 - lq_sta->active_tbl])) {
+		curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
+		other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+	} else {
+		IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
+		return;
 	}
+	window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
 
 	/*
-	 * Find (by rate) the history window to update with final Tx attempt;
-	 * if Tx was successful first try, use original rate,
-	 * else look up the rate that was, finally, successful.
+	 * Updating the frame history depends on whether packets were
+	 * aggregated.
+	 *
+	 * For aggregation, all packets were transmitted at the same rate, the
+	 * first index into rate scale table.
 	 */
-	tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
-	lq_sta->last_rate_n_flags = tx_rate;
-	rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
+	if (info->flags & IEEE80211_TX_STAT_AMPDU) {
+		tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
+		rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
+				&rs_index);
+		tpt = get_expected_tpt(curr_tbl, rs_index);
+		rs_collect_tx_data(window, rs_index, tpt,
+				   info->status.ampdu_ack_len,
+				   info->status.ampdu_ack_map);
 
-	/* Update frame history window with "success" if Tx got ACKed ... */
-	status = !!(info->flags & IEEE80211_TX_STAT_ACK);
+		/* Update success/fail counts if not searching for new mode */
+		if (lq_sta->stay_in_tbl) {
+			lq_sta->total_success += info->status.ampdu_ack_map;
+			lq_sta->total_failed += (info->status.ampdu_ack_len -
+					info->status.ampdu_ack_map);
+		}
+	} else {
+	/*
+	 * For legacy, update frame history with for each Tx retry.
+	 */
+		retries = info->status.rates[0].count - 1;
+		/* HW doesn't send more than 15 retries */
+		retries = min(retries, 15);
 
-	/* If type matches "search" table,
-	 * add final tx status to "search" history */
-	if ((tbl_type.lq_type == search_tbl->lq_type) &&
-	    (tbl_type.ant_type == search_tbl->ant_type) &&
-	    (tbl_type.is_SGI == search_tbl->is_SGI)) {
-		if (search_tbl->expected_tpt)
-			tpt = search_tbl->expected_tpt[rs_index];
-		else
-			tpt = 0;
-		if (info->flags & IEEE80211_TX_STAT_AMPDU)
-			rs_collect_tx_data(search_win, rs_index, tpt,
-					   info->status.ampdu_ack_len,
-					   info->status.ampdu_ack_map);
-		else
-			rs_collect_tx_data(search_win, rs_index, tpt,
-					   1, status);
-	/* Else if type matches "current/active" table,
-	 * add final tx status to "current/active" history */
-	} else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
-		   (tbl_type.ant_type == curr_tbl->ant_type) &&
-		   (tbl_type.is_SGI == curr_tbl->is_SGI)) {
-		if (curr_tbl->expected_tpt)
-			tpt = curr_tbl->expected_tpt[rs_index];
-		else
-			tpt = 0;
-		if (info->flags & IEEE80211_TX_STAT_AMPDU)
-			rs_collect_tx_data(window, rs_index, tpt,
-					   info->status.ampdu_ack_len,
-					   info->status.ampdu_ack_map);
-		else
-			rs_collect_tx_data(window, rs_index, tpt,
-					   1, status);
-	}
+		/* The last transmission may have been successful */
+		legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
+		/* Collect data for each rate used during failed TX attempts */
+		for (i = 0; i <= retries; ++i) {
+			tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags);
+			rs_get_tbl_info_from_mcs(tx_rate, priv->band,
+					&tbl_type, &rs_index);
+			/*
+			 * Only collect stats if retried rate is in the same RS
+			 * table as active/search.
+			 */
+			if (table_type_matches(&tbl_type, curr_tbl))
+				tpt = get_expected_tpt(curr_tbl, rs_index);
+			else if (table_type_matches(&tbl_type, other_tbl))
+				tpt = get_expected_tpt(other_tbl, rs_index);
+			else
+				continue;
 
-	/* If not searching for new mode, increment success/failed counter
-	 * ... these help determine when to start searching again */
-	if (lq_sta->stay_in_tbl) {
-		if (info->flags & IEEE80211_TX_STAT_AMPDU) {
-			lq_sta->total_success += info->status.ampdu_ack_map;
-			lq_sta->total_failed +=
-			     (info->status.ampdu_ack_len - info->status.ampdu_ack_map);
-		} else {
-			if (status)
-				lq_sta->total_success++;
+			/* Constants mean 1 transmission, 0 successes */
+			if (i < retries)
+				rs_collect_tx_data(window, rs_index, tpt, 1,
+						0);
 			else
-				lq_sta->total_failed++;
+				rs_collect_tx_data(window, rs_index, tpt, 1,
+						legacy_success);
+		}
+
+		/* Update success/fail counts if not searching for new mode */
+		if (lq_sta->stay_in_tbl) {
+			lq_sta->total_success += legacy_success;
+			lq_sta->total_failed += retries + (1 - legacy_success);
 		}
 	}
+	/* The last TX rate is cached in lq_sta; it's set in if/else above */
+	lq_sta->last_rate_n_flags = tx_rate;
 
 	/* See if there's a better rate or modulation mode to try. */
 	if (sta && sta->supp_rates[sband->band])
 		rs_rate_scale_perform(priv, skb, sta, lq_sta);
-out:
-	return;
 }
 
 /*
@@ -1066,43 +947,45 @@ static void rs_set_stay_in_table(struct
 static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
 				      struct iwl_scale_tbl_info *tbl)
 {
+	/* Used to choose among HT tables */
+	s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
+
+	/* Check for invalid LQ type */
+	if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) {
+		tbl->expected_tpt = expected_tpt_legacy;
+		return;
+	}
+
+	/* Legacy rates have only one table */
 	if (is_legacy(tbl->lq_type)) {
-		if (!is_a_band(tbl->lq_type))
-			tbl->expected_tpt = expected_tpt_G;
-		else
-			tbl->expected_tpt = expected_tpt_A;
-	} else if (is_siso(tbl->lq_type)) {
-		if (tbl->is_ht40 && !lq_sta->is_dup)
-			if (tbl->is_SGI)
-				tbl->expected_tpt = expected_tpt_siso40MHzSGI;
-			else
-				tbl->expected_tpt = expected_tpt_siso40MHz;
-		else if (tbl->is_SGI)
-			tbl->expected_tpt = expected_tpt_siso20MHzSGI;
-		else
-			tbl->expected_tpt = expected_tpt_siso20MHz;
-	} else if (is_mimo2(tbl->lq_type)) {
-		if (tbl->is_ht40 && !lq_sta->is_dup)
-			if (tbl->is_SGI)
-				tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI;
-			else
-				tbl->expected_tpt = expected_tpt_mimo2_40MHz;
-		else if (tbl->is_SGI)
-			tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI;
-		else
-			tbl->expected_tpt = expected_tpt_mimo2_20MHz;
-	} else if (is_mimo3(tbl->lq_type)) {
-		if (tbl->is_ht40 && !lq_sta->is_dup)
-			if (tbl->is_SGI)
-				tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI;
-			else
-				tbl->expected_tpt = expected_tpt_mimo3_40MHz;
-		else if (tbl->is_SGI)
-			tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI;
-		else
-			tbl->expected_tpt = expected_tpt_mimo3_20MHz;
-	} else
-		tbl->expected_tpt = expected_tpt_G;
+		tbl->expected_tpt = expected_tpt_legacy;
+		return;
+	}
+
+	/* Choose among many HT tables depending on number of streams
+	 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation
+	 * status */
+	if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
+		ht_tbl_pointer = expected_tpt_siso20MHz;
+	else if (is_siso(tbl->lq_type))
+		ht_tbl_pointer = expected_tpt_siso40MHz;
+	else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
+		ht_tbl_pointer = expected_tpt_mimo2_20MHz;
+	else if (is_mimo2(tbl->lq_type))
+		ht_tbl_pointer = expected_tpt_mimo2_40MHz;
+	else if (is_mimo3(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
+		ht_tbl_pointer = expected_tpt_mimo3_20MHz;
+	else /* if (is_mimo3(tbl->lq_type)) <-- must be true */
+		ht_tbl_pointer = expected_tpt_mimo3_40MHz;
+
+	if (!tbl->is_SGI && !lq_sta->is_agg)		/* Normal */
+		tbl->expected_tpt = ht_tbl_pointer[0];
+	else if (tbl->is_SGI && !lq_sta->is_agg)	/* SGI */
+		tbl->expected_tpt = ht_tbl_pointer[1];
+	else if (!tbl->is_SGI && lq_sta->is_agg)	/* AGG */
+		tbl->expected_tpt = ht_tbl_pointer[2];
+	else						/* AGG+SGI */
+		tbl->expected_tpt = ht_tbl_pointer[3];
 }
 
 /*
@@ -2077,6 +1960,14 @@ static void rs_rate_scale_perform(struct
 	lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
 
 	tid = rs_tl_add_packet(lq_sta, hdr);
+	if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) {
+		tid_data = &priv->stations[lq_sta->lq.sta_id].tid[tid];
+		if (tid_data->agg.state == IWL_AGG_OFF)
+			lq_sta->is_agg = 0;
+		else
+			lq_sta->is_agg = 1;
+	} else
+		lq_sta->is_agg = 0;
 
 	/*
 	 * Select rate-scale / modulation-mode table to work with in
@@ -2177,10 +2068,10 @@ static void rs_rate_scale_perform(struct
 
 		goto out;
 	}
-
 	/* Else we have enough samples; calculate estimate of
 	 * actual average throughput */
 
+	/* Sanity-check TPT calculations */
 	BUG_ON(window->average_tpt != ((window->success_ratio *
 			tbl->expected_tpt[index] + 64) / 128));
 
@@ -2584,22 +2475,13 @@ static void *rs_alloc_sta(void *priv_rat
 			  gfp_t gfp)
 {
 	struct iwl_lq_sta *lq_sta;
+	struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
 	struct iwl_priv *priv;
-	int i, j;
 
 	priv = (struct iwl_priv *)priv_rate;
 	IWL_DEBUG_RATE(priv, "create station rate scale window\n");
 
-	lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
-
-	if (lq_sta == NULL)
-		return NULL;
-	lq_sta->lq.sta_id = 0xff;
-
-
-	for (j = 0; j < LQ_SIZE; j++)
-		for (i = 0; i < IWL_RATE_COUNT; i++)
-			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
+	lq_sta = &sta_priv->lq_sta;
 
 	return lq_sta;
 }
@@ -2613,6 +2495,12 @@ static void rs_rate_init(void *priv_r, s
 	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 
+	lq_sta->lq.sta_id = 0xff;
+
+	for (j = 0; j < LQ_SIZE; j++)
+		for (i = 0; i < IWL_RATE_COUNT; i++)
+			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
+
 	lq_sta->flush_timer = 0;
 	lq_sta->supp_rates = sta->supp_rates[sband->band];
 	for (j = 0; j < LQ_SIZE; j++)
@@ -2690,6 +2578,7 @@ static void rs_rate_init(void *priv_r, s
 	lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
 	if (sband->band == IEEE80211_BAND_5GHZ)
 		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
+	lq_sta->is_agg = 0;
 
 	rs_initialize_lq(priv, conf, sta, lq_sta);
 }
@@ -2808,7 +2697,7 @@ static void rs_fill_link_cmd(struct iwl_
 		repeat_rate--;
 	}
 
-	lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
+	lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
 	lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
 	lq_cmd->agg_params.agg_time_limit =
 		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
@@ -2827,11 +2716,9 @@ static void rs_free(void *priv_rate)
 static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
 			void *priv_sta)
 {
-	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_priv *priv __maybe_unused = priv_r;
 
 	IWL_DEBUG_RATE(priv, "enter\n");
-	kfree(lq_sta);
 	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
@@ -2942,8 +2829,9 @@ static ssize_t rs_sta_dbgfs_scale_table_
 		   ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
 		   desc += sprintf(buff+desc, " %s",
 		   (tbl->is_ht40) ? "40MHz" : "20MHz");
-		   desc += sprintf(buff+desc, " %s %s\n", (tbl->is_SGI) ? "SGI" : "",
-		   (lq_sta->is_green) ? "GF enabled" : "");
+		   desc += sprintf(buff+desc, " %s %s %s\n", (tbl->is_SGI) ? "SGI" : "",
+		   (lq_sta->is_green) ? "GF enabled" : "",
+		   (lq_sta->is_agg) ? "AGG on" : "");
 	}
 	desc += sprintf(buff+desc, "last tx rate=0x%X\n",
 		lq_sta->last_rate_n_flags);
@@ -3076,16 +2964,16 @@ static void rs_add_debugfs(void *priv, v
 {
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	lq_sta->rs_sta_dbgfs_scale_table_file =
-		debugfs_create_file("rate_scale_table", 0600, dir,
+		debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
 				lq_sta, &rs_sta_dbgfs_scale_table_ops);
 	lq_sta->rs_sta_dbgfs_stats_table_file =
-		debugfs_create_file("rate_stats_table", 0600, dir,
+		debugfs_create_file("rate_stats_table", S_IRUSR, dir,
 			lq_sta, &rs_sta_dbgfs_stats_table_ops);
 	lq_sta->rs_sta_dbgfs_rate_scale_data_file =
-		debugfs_create_file("rate_scale_data", 0600, dir,
+		debugfs_create_file("rate_scale_data", S_IRUSR, dir,
 			lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
 	lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
-		debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
+		debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
 		&lq_sta->tx_agg_tid_en);
 
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,6 +54,7 @@ struct iwl3945_rate_info {
 	u8 prev_table_rs;	/* prev in rate table cmd */
 };
 
+
 /*
  * These serve as indexes into
  * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -335,6 +336,106 @@ struct iwl_rate_mcs_info {
 	char	mcs[IWL_MAX_MCS_DISPLAY_SIZE];
 };
 
+/**
+ * struct iwl_rate_scale_data -- tx success history for one rate
+ */
+struct iwl_rate_scale_data {
+	u64 data;		/* bitmap of successful frames */
+	s32 success_counter;	/* number of frames successful */
+	s32 success_ratio;	/* per-cent * 128  */
+	s32 counter;		/* number of frames attempted */
+	s32 average_tpt;	/* success ratio * expected throughput */
+	unsigned long stamp;
+};
+
+/**
+ * struct iwl_scale_tbl_info -- tx params and success history for all rates
+ *
+ * There are two of these in struct iwl_lq_sta,
+ * one for "active", and one for "search".
+ */
+struct iwl_scale_tbl_info {
+	enum iwl_table_type lq_type;
+	u8 ant_type;
+	u8 is_SGI;	/* 1 = short guard interval */
+	u8 is_ht40;	/* 1 = 40 MHz channel width */
+	u8 is_dup;	/* 1 = duplicated data streams */
+	u8 action;	/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
+	u8 max_search;	/* maximun number of tables we can search */
+	s32 *expected_tpt;	/* throughput metrics; expected_tpt_G, etc. */
+	u32 current_rate;  /* rate_n_flags, uCode API format */
+	struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
+};
+
+struct iwl_traffic_load {
+	unsigned long time_stamp;	/* age of the oldest statistics */
+	u32 packet_count[TID_QUEUE_MAX_SIZE];   /* packet count in this time
+						 * slice */
+	u32 total;			/* total num of packets during the
+					 * last TID_MAX_TIME_DIFF */
+	u8 queue_count;			/* number of queues that has
+					 * been used since the last cleanup */
+	u8 head;			/* start of the circular buffer */
+};
+
+/**
+ * struct iwl_lq_sta -- driver's rate scaling private structure
+ *
+ * Pointer to this gets passed back and forth between driver and mac80211.
+ */
+struct iwl_lq_sta {
+	u8 active_tbl;		/* index of active table, range 0-1 */
+	u8 enable_counter;	/* indicates HT mode */
+	u8 stay_in_tbl;		/* 1: disallow, 0: allow search for new mode */
+	u8 search_better_tbl;	/* 1: currently trying alternate mode */
+	s32 last_tpt;
+
+	/* The following determine when to search for a new mode */
+	u32 table_count_limit;
+	u32 max_failure_limit;	/* # failed frames before new search */
+	u32 max_success_limit;	/* # successful frames before new search */
+	u32 table_count;
+	u32 total_failed;	/* total failed frames, any/all rates */
+	u32 total_success;	/* total successful frames, any/all rates */
+	u64 flush_timer;	/* time staying in mode before new search */
+
+	u8 action_counter;	/* # mode-switch actions tried */
+	u8 is_green;
+	u8 is_dup;
+	enum ieee80211_band band;
+	u8 ibss_sta_added;
+
+	/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
+	u32 supp_rates;
+	u16 active_legacy_rate;
+	u16 active_siso_rate;
+	u16 active_mimo2_rate;
+	u16 active_mimo3_rate;
+	u16 active_rate_basic;
+	s8 max_rate_idx;     /* Max rate set by user */
+	u8 missed_rate_counter;
+
+	struct iwl_link_quality_cmd lq;
+	struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
+	struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
+	u8 tx_agg_tid_en;
+#ifdef CONFIG_MAC80211_DEBUGFS
+	struct dentry *rs_sta_dbgfs_scale_table_file;
+	struct dentry *rs_sta_dbgfs_stats_table_file;
+	struct dentry *rs_sta_dbgfs_rate_scale_data_file;
+	struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
+	u32 dbg_fixed_rate;
+#endif
+	struct iwl_priv *drv;
+
+	/* used to be in sta_info */
+	int last_txrate_idx;
+	/* last tx rate_n_flags */
+	u32 last_rate_n_flags;
+	/* packets destined for this STA are aggregated */
+	u8 is_agg;
+};
+
 static inline u8 num_of_ant(u8 mask)
 {
 	return  !!((mask) & ANT_A) +
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2010-02-24 13:52:17.000000000 -0500
@@ -132,6 +132,7 @@ void iwl_calib_free_results(struct iwl_p
 		priv->calib_results[i].buf_len = 0;
 	}
 }
+EXPORT_SYMBOL(iwl_calib_free_results);
 
 /*****************************************************************************
  * RUNTIME calibrations framework
@@ -447,11 +448,11 @@ static int iwl_sensitivity_write(struct
 				cpu_to_le16((u16)data->nrg_th_ofdm);
 
 	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
-				cpu_to_le16(190);
+				cpu_to_le16(data->barker_corr_th_min);
 	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
-				cpu_to_le16(390);
+				cpu_to_le16(data->barker_corr_th_min_mrc);
 	cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
-				cpu_to_le16(62);
+				cpu_to_le16(data->nrg_th_cca);
 
 	IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
 			data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
@@ -516,7 +517,7 @@ void iwl_init_sensitivity(struct iwl_pri
 	for (i = 0; i < NRG_NUM_PREV_STAT_L; i++)
 		data->nrg_silence_rssi[i] = 0;
 
-	data->auto_corr_ofdm = 90;
+	data->auto_corr_ofdm =  ranges->auto_corr_min_ofdm;
 	data->auto_corr_ofdm_mrc = ranges->auto_corr_min_ofdm_mrc;
 	data->auto_corr_ofdm_x1  = ranges->auto_corr_min_ofdm_x1;
 	data->auto_corr_ofdm_mrc_x1 = ranges->auto_corr_min_ofdm_mrc_x1;
@@ -524,6 +525,9 @@ void iwl_init_sensitivity(struct iwl_pri
 	data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc;
 	data->nrg_th_cck = ranges->nrg_th_cck;
 	data->nrg_th_ofdm = ranges->nrg_th_ofdm;
+	data->barker_corr_th_min = ranges->barker_corr_th_min;
+	data->barker_corr_th_min_mrc = ranges->barker_corr_th_min_mrc;
+	data->nrg_th_cca = ranges->nrg_th_cca;
 
 	data->last_bad_plcp_cnt_ofdm = 0;
 	data->last_fa_cnt_ofdm = 0;
@@ -643,6 +647,15 @@ void iwl_sensitivity_calibration(struct
 }
 EXPORT_SYMBOL(iwl_sensitivity_calibration);
 
+static inline u8 find_first_chain(u8 mask)
+{
+	if (mask & ANT_A)
+		return CHAIN_A;
+	if (mask & ANT_B)
+		return CHAIN_B;
+	return CHAIN_C;
+}
+
 /*
  * Accumulate 20 beacons of signal and noise statistics for each of
  *   3 receivers/antennas/rx-chains, then figure out:
@@ -675,14 +688,17 @@ void iwl_chain_noise_calibration(struct
 	u8 num_tx_chains;
 	unsigned long flags;
 	struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general);
+	u8 first_chain;
 
 	if (priv->disable_chain_noise_cal)
 		return;
 
 	data = &(priv->chain_noise_data);
 
-	/* Accumulate just the first 20 beacons after the first association,
-	 *   then we're done forever. */
+	/*
+	 * Accumulate just the first "chain_noise_num_beacons" after
+	 * the first association, then we're done forever.
+	 */
 	if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
 		if (data->state == IWL_CHAIN_NOISE_ALIVE)
 			IWL_DEBUG_CALIB(priv, "Wait for noise calib reset\n");
@@ -710,7 +726,10 @@ void iwl_chain_noise_calibration(struct
 		return;
 	}
 
-	/* Accumulate beacon statistics values across 20 beacons */
+	/*
+	 *  Accumulate beacon statistics values across
+	 * "chain_noise_num_beacons"
+	 */
 	chain_noise_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) &
 				IN_BAND_FILTER;
 	chain_noise_b = le32_to_cpu(rx_info->beacon_silence_rssi_b) &
@@ -741,16 +760,19 @@ void iwl_chain_noise_calibration(struct
 	IWL_DEBUG_CALIB(priv, "chain_noise: a %d b %d c %d\n",
 			chain_noise_a, chain_noise_b, chain_noise_c);
 
-	/* If this is the 20th beacon, determine:
+	/* If this is the "chain_noise_num_beacons", determine:
 	 * 1)  Disconnected antennas (using signal strengths)
 	 * 2)  Differential gain (using silence noise) to balance receivers */
-	if (data->beacon_count != CAL_NUM_OF_BEACONS)
+	if (data->beacon_count != priv->cfg->chain_noise_num_beacons)
 		return;
 
 	/* Analyze signal for disconnected antenna */
-	average_sig[0] = (data->chain_signal_a) / CAL_NUM_OF_BEACONS;
-	average_sig[1] = (data->chain_signal_b) / CAL_NUM_OF_BEACONS;
-	average_sig[2] = (data->chain_signal_c) / CAL_NUM_OF_BEACONS;
+	average_sig[0] =
+		(data->chain_signal_a) / priv->cfg->chain_noise_num_beacons;
+	average_sig[1] =
+		(data->chain_signal_b) / priv->cfg->chain_noise_num_beacons;
+	average_sig[2] =
+		(data->chain_signal_c) / priv->cfg->chain_noise_num_beacons;
 
 	if (average_sig[0] >= average_sig[1]) {
 		max_average_sig = average_sig[0];
@@ -803,13 +825,17 @@ void iwl_chain_noise_calibration(struct
 			/* there is a Tx antenna connected */
 			break;
 		if (num_tx_chains == priv->hw_params.tx_chains_num &&
-		data->disconn_array[i]) {
-			/* This is the last TX antenna and is also
-			 * disconnected connect it anyway */
-			data->disconn_array[i] = 0;
-			active_chains |= ant_msk;
-			IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - "
-				"declare %d as connected\n", i);
+		    data->disconn_array[i]) {
+			/*
+			 * If all chains are disconnected
+			 * connect the first valid tx chain
+			 */
+			first_chain =
+				find_first_chain(priv->cfg->valid_tx_ant);
+			data->disconn_array[first_chain] = 0;
+			active_chains |= BIT(first_chain);
+			IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - declare %d as connected\n",
+					first_chain);
 			break;
 		}
 	}
@@ -820,9 +846,12 @@ void iwl_chain_noise_calibration(struct
 			active_chains);
 
 	/* Analyze noise for rx balance */
-	average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
-	average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
-	average_noise[2] = ((data->chain_noise_c)/CAL_NUM_OF_BEACONS);
+	average_noise[0] =
+		((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons);
+	average_noise[1] =
+		((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons);
+	average_noise[2] =
+		((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons);
 
 	for (i = 0; i < NUM_RX_CHAINS; i++) {
 		if (!(data->disconn_array[i]) &&
@@ -843,7 +872,8 @@ void iwl_chain_noise_calibration(struct
 
 	if (priv->cfg->ops->utils->gain_computation)
 		priv->cfg->ops->utils->gain_computation(priv, average_noise,
-			min_average_noise_antenna_i, min_average_noise);
+				min_average_noise_antenna_i, min_average_noise,
+				find_first_chain(priv->cfg->valid_rx_ant));
 
 	/* Some power changes may have been made during the calibration.
 	 * Update and commit the RXON
@@ -870,7 +900,7 @@ void iwl_reset_run_time_calib(struct iwl
 
 	/* Ask for statistics now, the uCode will send notification
 	 * periodically after association */
-	iwl_send_statistics_request(priv, CMD_ASYNC);
+	iwl_send_statistics_request(priv, CMD_ASYNC, true);
 }
 EXPORT_SYMBOL(iwl_reset_run_time_calib);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2010-02-24 13:52:17.000000000 -0500
@@ -109,11 +109,12 @@ enum {
 	REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
 
 	/* WiMAX coexistence */
-	COEX_PRIORITY_TABLE_CMD = 0x5a,	/*5000 only */
+	COEX_PRIORITY_TABLE_CMD = 0x5a,	/* for 5000 series and up */
 	COEX_MEDIUM_NOTIFICATION = 0x5b,
 	COEX_EVENT_CMD = 0x5c,
 
 	/* Calibration */
+	TEMPERATURE_NOTIFICATION = 0x62,
 	CALIBRATION_CFG_CMD = 0x65,
 	CALIBRATION_RES_NOTIFICATION = 0x66,
 	CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
@@ -148,7 +149,7 @@ enum {
 	QUIET_NOTIFICATION = 0x96,		/* not used */
 	REPLY_TX_PWR_TABLE_CMD = 0x97,
 	REPLY_TX_POWER_DBM_CMD_V1 = 0x98,	/* old version of API */
-	TX_ANT_CONFIGURATION_CMD = 0x98,	/* not used */
+	TX_ANT_CONFIGURATION_CMD = 0x98,
 	MEASURE_ABORT_NOTIFICATION = 0x99,	/* not used */
 
 	/* Bluetooth device coexistence config command */
@@ -353,6 +354,9 @@ struct iwl3945_power_per_rate {
 #define POWER_TABLE_NUM_HT_OFDM_ENTRIES		32
 #define POWER_TABLE_CCK_ENTRY			32
 
+#define IWL_PWR_NUM_HT_OFDM_ENTRIES		24
+#define IWL_PWR_CCK_ENTRIES			2
+
 /**
  * union iwl4965_tx_power_dual_stream
  *
@@ -411,6 +415,16 @@ struct iwl5000_tx_power_dbm_cmd {
 	u8 reserved;
 } __attribute__ ((packed));
 
+/**
+ * Command TX_ANT_CONFIGURATION_CMD = 0x98
+ * This command is used to configure valid Tx antenna.
+ * By default uCode concludes the valid antenna according to the radio flavor.
+ * This command enables the driver to override/modify this conclusion.
+ */
+struct iwl_tx_ant_config_cmd {
+	__le32 valid;
+} __attribute__ ((packed));
+
 /******************************************************************************
  * (0a)
  * Alive and Error Commands & Responses:
@@ -793,7 +807,7 @@ struct iwl3945_channel_switch_cmd {
 	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
 } __attribute__ ((packed));
 
-struct iwl_channel_switch_cmd {
+struct iwl4965_channel_switch_cmd {
 	u8 band;
 	u8 expect_beacon;
 	__le16 channel;
@@ -803,6 +817,48 @@ struct iwl_channel_switch_cmd {
 	struct iwl4965_tx_power_db tx_power;
 } __attribute__ ((packed));
 
+/**
+ * struct iwl5000_channel_switch_cmd
+ * @band: 0- 5.2GHz, 1- 2.4GHz
+ * @expect_beacon: 0- resume transmits after channel switch
+ *		   1- wait for beacon to resume transmits
+ * @channel: new channel number
+ * @rxon_flags: Rx on flags
+ * @rxon_filter_flags: filtering parameters
+ * @switch_time: switch time in extended beacon format
+ * @reserved: reserved bytes
+ */
+struct iwl5000_channel_switch_cmd {
+	u8 band;
+	u8 expect_beacon;
+	__le16 channel;
+	__le32 rxon_flags;
+	__le32 rxon_filter_flags;
+	__le32 switch_time;
+	__le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES];
+} __attribute__ ((packed));
+
+/**
+ * struct iwl6000_channel_switch_cmd
+ * @band: 0- 5.2GHz, 1- 2.4GHz
+ * @expect_beacon: 0- resume transmits after channel switch
+ *		   1- wait for beacon to resume transmits
+ * @channel: new channel number
+ * @rxon_flags: Rx on flags
+ * @rxon_filter_flags: filtering parameters
+ * @switch_time: switch time in extended beacon format
+ * @reserved: reserved bytes
+ */
+struct iwl6000_channel_switch_cmd {
+	u8 band;
+	u8 expect_beacon;
+	__le16 channel;
+	__le32 rxon_flags;
+	__le32 rxon_filter_flags;
+	__le32 switch_time;
+	__le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES];
+} __attribute__ ((packed));
+
 /*
  * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
  */
@@ -921,6 +977,7 @@ struct iwl_qosparam_cmd {
 #define	STA_MODIFY_TX_RATE_MSK		0x04
 #define STA_MODIFY_ADDBA_TID_MSK	0x08
 #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 */
@@ -1051,7 +1108,14 @@ struct iwl4965_addsta_cmd {
 	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
 	__le16 add_immediate_ba_ssn;
 
-	__le32 reserved2;
+	/*
+	 * Number of packets OK to transmit to station even though
+	 * it is asleep -- used to synchronise PS-poll and u-APSD
+	 * responses while ucode keeps track of STA sleep state.
+	 */
+	__le16 sleep_tx_count;
+
+	__le16 reserved2;
 } __attribute__ ((packed));
 
 /* 5000 */
@@ -1082,7 +1146,14 @@ struct iwl_addsta_cmd {
 	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
 	__le16 add_immediate_ba_ssn;
 
-	__le32 reserved2;
+	/*
+	 * Number of packets OK to transmit to station even though
+	 * it is asleep -- used to synchronise PS-poll and u-APSD
+	 * responses while ucode keeps track of STA sleep state.
+	 */
+	__le16 sleep_tx_count;
+
+	__le16 reserved2;
 } __attribute__ ((packed));
 
 
@@ -1634,6 +1705,21 @@ enum {
 	TX_ABORT_REQUIRED_MSK = 0x80000000,	/* bits 31:31 */
 };
 
+static inline u32 iwl_tx_status_to_mac80211(u32 status)
+{
+	status &= TX_STATUS_MSK;
+
+	switch (status) {
+	case TX_STATUS_SUCCESS:
+	case TX_STATUS_DIRECT_DONE:
+		return IEEE80211_TX_STAT_ACK;
+	case TX_STATUS_FAIL_DEST_PS:
+		return IEEE80211_TX_STAT_TX_FILTERED;
+	default:
+		return 0;
+	}
+}
+
 static inline bool iwl_is_tx_success(u32 status)
 {
 	status &= TX_STATUS_MSK;
@@ -2162,6 +2248,19 @@ struct iwl_link_quality_cmd {
 	__le32 reserved2;
 } __attribute__ ((packed));
 
+#define BT_COEX_DISABLE (0x0)
+#define BT_COEX_MODE_2W (0x1)
+#define BT_COEX_MODE_3W (0x2)
+#define BT_COEX_MODE_4W (0x3)
+
+#define BT_LEAD_TIME_MIN (0x0)
+#define BT_LEAD_TIME_DEF (0x1E)
+#define BT_LEAD_TIME_MAX (0xFF)
+
+#define BT_MAX_KILL_MIN (0x1)
+#define BT_MAX_KILL_DEF (0x5)
+#define BT_MAX_KILL_MAX (0xFF)
+
 /*
  * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
  *
@@ -2497,9 +2596,10 @@ struct iwl_scan_channel {
 /**
  * struct iwl_ssid_ie - directed scan network information element
  *
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl_scan_channel; each channel may select different ssids from
- * among the 4 entries.  SSID IEs get transmitted in reverse order of entry.
+ * Up to 20 of these may appear in REPLY_SCAN_CMD (Note: Only 4 are in
+ * 3945 SCAN api), selected by "type" bit field in struct iwl_scan_channel;
+ * each channel may select different ssids from among the 20 (4) entries.
+ * SSID IEs get transmitted in reverse order of entry.
  */
 struct iwl_ssid_ie {
 	u8 id;
@@ -3001,6 +3101,10 @@ struct statistics_general {
 	__le32 reserved3;
 } __attribute__ ((packed));
 
+#define UCODE_STATISTICS_CLEAR_MSK		(0x1 << 0)
+#define UCODE_STATISTICS_FREQUENCY_MSK		(0x1 << 1)
+#define UCODE_STATISTICS_NARROW_BAND_MSK	(0x1 << 2)
+
 /*
  * REPLY_STATISTICS_CMD = 0x9c,
  * 3945 and 4965 identical.
@@ -3237,12 +3341,6 @@ struct iwl_missed_beacon_notif {
  *   Lower values mean higher energy; this means making sure that the value
  *   in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy".
  *
- * Driver should set the following entries to fixed values:
- *
- *   HD_MIN_ENERGY_OFDM_DET_INDEX               100
- *   HD_BARKER_CORR_TH_ADD_MIN_INDEX            190
- *   HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX        390
- *   HD_OFDM_ENERGY_TH_IN_INDEX                  62
  */
 
 /*
@@ -3440,30 +3538,134 @@ struct iwl_led_cmd {
 } __attribute__ ((packed));
 
 /*
- * Coexistence WIFI/WIMAX  Command
- * COEX_PRIORITY_TABLE_CMD = 0x5a
- *
+ * station priority table entries
+ * also used as potential "events" value for both
+ * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD
  */
+
+/*
+ * COEX events entry flag masks
+ * RP - Requested Priority
+ * WP - Win Medium Priority: priority assigned when the contention has been won
+ */
+#define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG        (0x1)
+#define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG        (0x2)
+#define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG  (0x4)
+
+#define COEX_CU_UNASSOC_IDLE_RP               4
+#define COEX_CU_UNASSOC_MANUAL_SCAN_RP        4
+#define COEX_CU_UNASSOC_AUTO_SCAN_RP          4
+#define COEX_CU_CALIBRATION_RP                4
+#define COEX_CU_PERIODIC_CALIBRATION_RP       4
+#define COEX_CU_CONNECTION_ESTAB_RP           4
+#define COEX_CU_ASSOCIATED_IDLE_RP            4
+#define COEX_CU_ASSOC_MANUAL_SCAN_RP          4
+#define COEX_CU_ASSOC_AUTO_SCAN_RP            4
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_RP         4
+#define COEX_CU_RF_ON_RP                      6
+#define COEX_CU_RF_OFF_RP                     4
+#define COEX_CU_STAND_ALONE_DEBUG_RP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_RP           4
+#define COEX_CU_RSRVD1_RP                     4
+#define COEX_CU_RSRVD2_RP                     4
+
+#define COEX_CU_UNASSOC_IDLE_WP               3
+#define COEX_CU_UNASSOC_MANUAL_SCAN_WP        3
+#define COEX_CU_UNASSOC_AUTO_SCAN_WP          3
+#define COEX_CU_CALIBRATION_WP                3
+#define COEX_CU_PERIODIC_CALIBRATION_WP       3
+#define COEX_CU_CONNECTION_ESTAB_WP           3
+#define COEX_CU_ASSOCIATED_IDLE_WP            3
+#define COEX_CU_ASSOC_MANUAL_SCAN_WP          3
+#define COEX_CU_ASSOC_AUTO_SCAN_WP            3
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_WP         3
+#define COEX_CU_RF_ON_WP                      3
+#define COEX_CU_RF_OFF_WP                     3
+#define COEX_CU_STAND_ALONE_DEBUG_WP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_WP           3
+#define COEX_CU_RSRVD1_WP                     3
+#define COEX_CU_RSRVD2_WP                     3
+
+#define COEX_UNASSOC_IDLE_FLAGS                     0
+#define COEX_UNASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_UNASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_CALIBRATION_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_PERIODIC_CALIBRATION_FLAGS             0
+/*
+ * COEX_CONNECTION_ESTAB:
+ * we need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CONNECTION_ESTAB_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_ASSOCIATED_IDLE_FLAGS                  0
+#define COEX_ASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_ACTIVE_LEVEL_FLAGS               0
+#define COEX_RF_ON_FLAGS                            0
+#define COEX_RF_OFF_FLAGS                           0
+#define COEX_STAND_ALONE_DEBUG_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_IPAN_ASSOC_LEVEL_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_RSRVD1_FLAGS                           0
+#define COEX_RSRVD2_FLAGS                           0
+/*
+ * COEX_CU_RF_ON is the event wrapping all radio ownership.
+ * We need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CU_RF_ON_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+
+
 enum {
+	/* un-association part */
 	COEX_UNASSOC_IDLE		= 0,
 	COEX_UNASSOC_MANUAL_SCAN	= 1,
 	COEX_UNASSOC_AUTO_SCAN		= 2,
+	/* calibration */
 	COEX_CALIBRATION		= 3,
 	COEX_PERIODIC_CALIBRATION	= 4,
+	/* connection */
 	COEX_CONNECTION_ESTAB		= 5,
+	/* association part */
 	COEX_ASSOCIATED_IDLE		= 6,
 	COEX_ASSOC_MANUAL_SCAN		= 7,
 	COEX_ASSOC_AUTO_SCAN		= 8,
 	COEX_ASSOC_ACTIVE_LEVEL		= 9,
+	/* RF ON/OFF */
 	COEX_RF_ON			= 10,
 	COEX_RF_OFF			= 11,
 	COEX_STAND_ALONE_DEBUG		= 12,
+	/* IPAN */
 	COEX_IPAN_ASSOC_LEVEL		= 13,
+	/* reserved */
 	COEX_RSRVD1			= 14,
 	COEX_RSRVD2			= 15,
 	COEX_NUM_OF_EVENTS		= 16
 };
 
+/*
+ * Coexistence WIFI/WIMAX  Command
+ * COEX_PRIORITY_TABLE_CMD = 0x5a
+ *
+ */
 struct iwl_wimax_coex_event_entry {
 	u8 request_prio;
 	u8 win_medium_prio;
@@ -3488,6 +3690,55 @@ struct iwl_wimax_coex_cmd {
 	struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS];
 } __attribute__ ((packed));
 
+/*
+ * Coexistence MEDIUM NOTIFICATION
+ * COEX_MEDIUM_NOTIFICATION = 0x5b
+ *
+ * notification from uCode to host to indicate medium changes
+ *
+ */
+/*
+ * status field
+ * bit 0 - 2: medium status
+ * bit 3: medium change indication
+ * bit 4 - 31: reserved
+ */
+/* status option values, (0 - 2 bits) */
+#define COEX_MEDIUM_BUSY	(0x0) /* radio belongs to WiMAX */
+#define COEX_MEDIUM_ACTIVE	(0x1) /* radio belongs to WiFi */
+#define COEX_MEDIUM_PRE_RELEASE	(0x2) /* received radio release */
+#define COEX_MEDIUM_MSK		(0x7)
+
+/* send notification status (1 bit) */
+#define COEX_MEDIUM_CHANGED	(0x8)
+#define COEX_MEDIUM_CHANGED_MSK	(0x8)
+#define COEX_MEDIUM_SHIFT	(3)
+
+struct iwl_coex_medium_notification {
+	__le32 status;
+	__le32 events;
+} __attribute__ ((packed));
+
+/*
+ * Coexistence EVENT  Command
+ * COEX_EVENT_CMD = 0x5c
+ *
+ * send from host to uCode for coex event request.
+ */
+/* flags options */
+#define COEX_EVENT_REQUEST_MSK	(0x1)
+
+struct iwl_coex_event_cmd {
+	u8 flags;
+	u8 event;
+	__le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl_coex_event_resp {
+	__le32 status;
+} __attribute__ ((packed));
+
+
 /******************************************************************************
  * (13)
  * Union of all expected notifications/responses:
@@ -3495,6 +3746,16 @@ struct iwl_wimax_coex_cmd {
  *****************************************************************************/
 
 struct iwl_rx_packet {
+	/*
+	 * The first 4 bytes of the RX frame header contain both the RX frame
+	 * size and some flags.
+	 * Bit fields:
+	 * 31:    flag flush RB request
+	 * 30:    flag ignore TC (terminal counter) request
+	 * 29:    flag fast IRQ request
+	 * 28-14: Reserved
+	 * 13-00: RX frame size
+	 */
 	__le32 len_n_flags;
 	struct iwl_cmd_header hdr;
 	union {
@@ -3514,6 +3775,8 @@ struct iwl_rx_packet {
 		struct iwl_notif_statistics stats;
 		struct iwl_compressed_ba_resp compressed_ba;
 		struct iwl_missed_beacon_notif missed_beacon;
+		struct iwl_coex_medium_notification coex_medium_notif;
+		struct iwl_coex_event_resp coex_event;
 		__le32 status;
 		u8 raw[0];
 	} u;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,37 @@ MODULE_VERSION(IWLWIFI_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
+static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
+	{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
+	 0, COEX_UNASSOC_IDLE_FLAGS},
+	{COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
+	 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
+	 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
+	 0, COEX_CALIBRATION_FLAGS},
+	{COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
+	 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+	{COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
+	 0, COEX_CONNECTION_ESTAB_FLAGS},
+	{COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
+	 0, COEX_ASSOCIATED_IDLE_FLAGS},
+	{COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
+	 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
+	 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
+	 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+	{COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
+	{COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
+	{COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
+	 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+	{COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
+	 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+	{COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
+	{COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
+};
+
 #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
 	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
 				    IWL_RATE_SISO_##s##M_PLCP, \
@@ -178,6 +209,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *pr
 	}
 	return ant;
 }
+EXPORT_SYMBOL(iwl_toggle_tx_ant);
 
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(iwl_bcast_addr);
@@ -224,7 +256,10 @@ int iwl_hw_nic_init(struct iwl_priv *pri
 	/* nic_init */
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->cfg->ops->lib->apm_ops.init(priv);
-	iwl_write32(priv, CSR_INT_COALESCING, 512 / 32);
+
+	/* Set interrupt coalescing timer to 512 usecs */
+	iwl_write8(priv, CSR_INT_COALESCING, 512 / 32);
+
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
@@ -416,8 +451,7 @@ static void iwlcore_init_ht_hw_capab(con
 		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
 	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
 	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
-			     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
-
+			     (priv->cfg->sm_ps_mode << 2));
 	max_bit_rate = MAX_BIT_RATE_20_MHZ;
 	if (priv->hw_params.ht40_channel & BIT(band)) {
 		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -452,28 +486,6 @@ static void iwlcore_init_ht_hw_capab(con
 	}
 }
 
-static void iwlcore_init_hw_rates(struct iwl_priv *priv,
-			      struct ieee80211_rate *rates)
-{
-	int i;
-
-	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
-		rates[i].bitrate = iwl_rates[i].ieee * 5;
-		rates[i].hw_value = i; /* Rate scaling will work on indexes */
-		rates[i].hw_value_short = i;
-		rates[i].flags = 0;
-		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
-			/*
-			 * If CCK != 1M then set short preamble rate flag.
-			 */
-			rates[i].flags |=
-				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
-					0 : IEEE80211_RATE_SHORT_PREAMBLE;
-		}
-	}
-}
-
-
 /**
  * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
  */
@@ -605,11 +617,27 @@ void iwlcore_free_geos(struct iwl_priv *
 }
 EXPORT_SYMBOL(iwlcore_free_geos);
 
+/*
+ *  iwlcore_rts_tx_cmd_flag: Set rts/cts. 3945 and 4965 only share this
+ *  function.
+ */
+void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+				__le32 *tx_flags)
+{
+	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+		*tx_flags |= TX_CMD_FLG_RTS_MSK;
+		*tx_flags &= ~TX_CMD_FLG_CTS_MSK;
+	} else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+		*tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+		*tx_flags |= TX_CMD_FLG_CTS_MSK;
+	}
+}
+EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
+
 static bool is_single_rx_stream(struct iwl_priv *priv)
 {
 	return !priv->current_ht_config.is_ht ||
-	       ((priv->current_ht_config.mcs.rx_mask[1] == 0) &&
-		(priv->current_ht_config.mcs.rx_mask[2] == 0));
+	       priv->current_ht_config.single_chain_sufficient;
 }
 
 static u8 iwl_is_channel_extension(struct iwl_priv *priv,
@@ -635,10 +663,9 @@ static u8 iwl_is_channel_extension(struc
 u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
 			 struct ieee80211_sta_ht_cap *sta_ht_inf)
 {
-	struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
+	struct iwl_ht_config *ht_conf = &priv->current_ht_config;
 
-	if ((!iwl_ht_conf->is_ht) ||
-	    (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ))
+	if (!ht_conf->is_ht || !ht_conf->is_40mhz)
 		return 0;
 
 	/* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
@@ -654,7 +681,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_pri
 #endif
 	return iwl_is_channel_extension(priv, priv->band,
 			le16_to_cpu(priv->staging_rxon.channel),
-			iwl_ht_conf->extension_chan_offset);
+			ht_conf->extension_chan_offset);
 }
 EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
 
@@ -878,11 +905,11 @@ u8 iwl_rate_get_lowest_plcp(struct iwl_p
 }
 EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
 
-void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
 {
 	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
 
-	if (!ht_info->is_ht) {
+	if (!ht_conf->is_ht) {
 		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
 			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
 			RXON_FLG_HT40_PROT_MSK |
@@ -893,7 +920,7 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
 	/* FIXME: if the definition of ht_protection changed, the "translation"
 	 * will be needed for rxon->flags
 	 */
-	rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
+	rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
 
 	/* Set up channel bandwidth:
 	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
@@ -902,10 +929,10 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
 			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
 	if (iwl_is_ht40_tx_allowed(priv, NULL)) {
 		/* pure ht40 */
-		if (ht_info->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+		if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
 			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
 			/* Note: control channel is opposite of extension channel */
-			switch (ht_info->extension_chan_offset) {
+			switch (ht_conf->extension_chan_offset) {
 			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
 				rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
 				break;
@@ -915,7 +942,7 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
 			}
 		} else {
 			/* Note: control channel is opposite of extension channel */
-			switch (ht_info->extension_chan_offset) {
+			switch (ht_conf->extension_chan_offset) {
 			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
 				rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
 				rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
@@ -938,14 +965,10 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
 	if (priv->cfg->ops->hcmd->set_rxon_chain)
 		priv->cfg->ops->hcmd->set_rxon_chain(priv);
 
-	IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
-			"rxon flags 0x%X operation mode :0x%X "
+	IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
 			"extension channel offset 0x%x\n",
-			ht_info->mcs.rx_mask[0],
-			ht_info->mcs.rx_mask[1],
-			ht_info->mcs.rx_mask[2],
-			le32_to_cpu(rxon->flags), ht_info->ht_protection,
-			ht_info->extension_chan_offset);
+			le32_to_cpu(rxon->flags), ht_conf->ht_protection,
+			ht_conf->extension_chan_offset);
 	return;
 }
 EXPORT_SYMBOL(iwl_set_rxon_ht);
@@ -955,44 +978,50 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
 #define IWL_NUM_IDLE_CHAINS_DUAL	2
 #define IWL_NUM_IDLE_CHAINS_SINGLE	1
 
-/* Determine how many receiver/antenna chains to use.
- * More provides better reception via diversity.  Fewer saves power.
+/*
+ * Determine how many receiver/antenna chains to use.
+ *
+ * More provides better reception via diversity.  Fewer saves power
+ * at the expense of throughput, but only when not in powersave to
+ * start with.
+ *
  * MIMO (dual stream) requires at least 2, but works better with 3.
  * This does not determine *which* chains to use, just how many.
  */
 static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 {
-	bool is_single = is_single_rx_stream(priv);
-	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-
 	/* # of Rx chains to use when expecting MIMO. */
-	if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
-						 WLAN_HT_CAP_SM_PS_STATIC)))
+	if (is_single_rx_stream(priv))
 		return IWL_NUM_RX_CHAINS_SINGLE;
 	else
 		return IWL_NUM_RX_CHAINS_MULTIPLE;
 }
 
+/*
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
+ */
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-	int idle_cnt;
+	int idle_cnt = active_cnt;
 	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+
 	/* # Rx chains when idling and maybe trying to save power */
-	switch (priv->current_ht_config.sm_ps) {
+	switch (priv->cfg->sm_ps_mode) {
 	case WLAN_HT_CAP_SM_PS_STATIC:
+		idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
+		break;
 	case WLAN_HT_CAP_SM_PS_DYNAMIC:
 		idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
-					IWL_NUM_IDLE_CHAINS_SINGLE;
+			IWL_NUM_IDLE_CHAINS_SINGLE;
 		break;
 	case WLAN_HT_CAP_SM_PS_DISABLED:
-		idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
 		break;
 	case WLAN_HT_CAP_SM_PS_INVALID:
 	default:
-		IWL_ERR(priv, "invalid mimo ps mode %d\n",
-			   priv->current_ht_config.sm_ps);
+		IWL_ERR(priv, "invalid sm_ps mode %u\n",
+			priv->cfg->sm_ps_mode);
 		WARN_ON(1);
-		idle_cnt = -1;
 		break;
 	}
 	return idle_cnt;
@@ -1005,7 +1034,7 @@ static u8 iwl_count_chain_bitmap(u32 cha
 	res = (chain_bitmap & BIT(0)) >> 0;
 	res += (chain_bitmap & BIT(1)) >> 1;
 	res += (chain_bitmap & BIT(2)) >> 2;
-	res += (chain_bitmap & BIT(4)) >> 4;
+	res += (chain_bitmap & BIT(3)) >> 3;
 	return res;
 }
 
@@ -1281,18 +1310,28 @@ static void iwl_set_rate(struct iwl_priv
 
 void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
 	struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
-	IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n",
-		      le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
-	rxon->channel = csa->channel;
-	priv->staging_rxon.channel = csa->channel;
+
+	if (priv->switch_rxon.switch_in_progress) {
+		if (!le32_to_cpu(csa->status) &&
+		    (csa->channel == priv->switch_rxon.channel)) {
+			rxon->channel = csa->channel;
+			priv->staging_rxon.channel = csa->channel;
+			IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
+			      le16_to_cpu(csa->channel));
+		} else
+			IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+			      le16_to_cpu(csa->channel));
+
+		priv->switch_rxon.switch_in_progress = false;
+	}
 }
 EXPORT_SYMBOL(iwl_rx_csa);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 {
 	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
 
@@ -1310,6 +1349,7 @@ static void iwl_print_rx_config_cmd(stru
 	IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
 	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
+EXPORT_SYMBOL(iwl_print_rx_config_cmd);
 #endif
 /**
  * iwl_irq_handle_error - called for HW or SW error interrupt from card
@@ -1322,12 +1362,11 @@ void iwl_irq_handle_error(struct iwl_pri
 	/* Cancel currently queued command. */
 	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
+	priv->cfg->ops->lib->dump_nic_error_log(priv);
+	priv->cfg->ops->lib->dump_nic_event_log(priv, false);
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) {
-		priv->cfg->ops->lib->dump_nic_error_log(priv);
-		priv->cfg->ops->lib->dump_nic_event_log(priv);
+	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
 		iwl_print_rx_config_cmd(priv);
-	}
 #endif
 
 	wake_up_interruptible(&priv->wait_command_queue);
@@ -1346,6 +1385,160 @@ void iwl_irq_handle_error(struct iwl_pri
 }
 EXPORT_SYMBOL(iwl_irq_handle_error);
 
+int iwl_apm_stop_master(struct iwl_priv *priv)
+{
+	int ret = 0;
+
+	/* stop device's busmaster DMA activity */
+	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+	ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
+			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+	if (ret)
+		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
+
+	IWL_DEBUG_INFO(priv, "stop master\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(iwl_apm_stop_master);
+
+void iwl_apm_stop(struct iwl_priv *priv)
+{
+	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
+
+	/* Stop device's DMA activity */
+	iwl_apm_stop_master(priv);
+
+	/* Reset the entire device */
+	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+	udelay(10);
+
+	/*
+	 * Clear "initialization complete" bit to move adapter from
+	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
+	 */
+	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+}
+EXPORT_SYMBOL(iwl_apm_stop);
+
+
+/*
+ * Start up NIC's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * NOTE:  This does not load uCode nor start the embedded processor
+ */
+int iwl_apm_init(struct iwl_priv *priv)
+{
+	int ret = 0;
+	u16 lctl;
+
+	IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
+
+	/*
+	 * Use "set_bit" below rather than "write", to preserve any hardware
+	 * bits already set by default after reset.
+	 */
+
+	/* Disable L0S exit timer (platform NMI Work/Around) */
+	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+	/*
+	 * Disable L0s without affecting L1;
+	 *  don't wait for ICH L0s (ICH bug W/A)
+	 */
+	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+	/* Set FH wait threshold to maximum (HW error during stress W/A) */
+	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
+
+	/*
+	 * Enable HAP INTA (interrupt from management bus) to
+	 * wake device's PCI Express link L1a -> L0s
+	 * NOTE:  This is no-op for 3945 (non-existant bit)
+	 */
+	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
+
+	/*
+	 * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition.
+	 * Check if BIOS (or OS) enabled L1-ASPM on this device.
+	 * If so (likely), disable L0S, so device moves directly L0->L1;
+	 *    costs negligible amount of power savings.
+	 * If not (unlikely), enable L0S, so there is at least some
+	 *    power savings, even without L1.
+	 */
+	if (priv->cfg->set_l0s) {
+		lctl = iwl_pcie_link_ctl(priv);
+		if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+					PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+			/* L1-ASPM enabled; disable(!) L0S  */
+			iwl_set_bit(priv, CSR_GIO_REG,
+					CSR_GIO_REG_VAL_L0S_ENABLED);
+			IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
+		} else {
+			/* L1-ASPM disabled; enable(!) L0S */
+			iwl_clear_bit(priv, CSR_GIO_REG,
+					CSR_GIO_REG_VAL_L0S_ENABLED);
+			IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
+		}
+	}
+
+	/* Configure analog phase-lock-loop before activating to D0A */
+	if (priv->cfg->pll_cfg_val)
+		iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
+
+	/*
+	 * Set "initialization complete" bit to move adapter from
+	 * D0U* --> D0A* (powered-up active) state.
+	 */
+	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+	/*
+	 * Wait for clock stabilization; once stabilized, access to
+	 * device-internal resources is supported, e.g. iwl_write_prph()
+	 * and accesses to uCode SRAM.
+	 */
+	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+	if (ret < 0) {
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
+		goto out;
+	}
+
+	/*
+	 * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
+	 * BSM (Boostrap State Machine) is only in 3945 and 4965;
+	 * later devices (i.e. 5000 and later) have non-volatile SRAM,
+	 * and don't need BSM to restore data after power-saving sleep.
+	 *
+	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
+	 * do not disable clocks.  This preserves any hardware bits already
+	 * set by default in "CLK_CTRL_REG" after reset.
+	 */
+	if (priv->cfg->use_bsm)
+		iwl_write_prph(priv, APMG_CLK_EN_REG,
+			APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
+	else
+		iwl_write_prph(priv, APMG_CLK_EN_REG,
+			APMG_CLK_VAL_DMA_CLK_RQT);
+	udelay(20);
+
+	/* Disable L1-Active */
+	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL(iwl_apm_init);
+
+
+
 void iwl_configure_filter(struct ieee80211_hw *hw,
 			  unsigned int changed_flags,
 			  unsigned int *total_flags,
@@ -1393,73 +1586,14 @@ void iwl_configure_filter(struct ieee802
 }
 EXPORT_SYMBOL(iwl_configure_filter);
 
-int iwl_setup_mac(struct iwl_priv *priv)
-{
-	int ret;
-	struct ieee80211_hw *hw = priv->hw;
-	hw->rate_control_algorithm = "iwl-agn-rs";
-
-	/* Tell mac80211 our characteristics */
-	hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		    IEEE80211_HW_NOISE_DBM |
-		    IEEE80211_HW_AMPDU_AGGREGATION |
-		    IEEE80211_HW_SPECTRUM_MGMT;
-
-	if (!priv->cfg->broken_powersave)
-		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
-			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
-
-	hw->wiphy->interface_modes =
-		BIT(NL80211_IFTYPE_STATION) |
-		BIT(NL80211_IFTYPE_ADHOC);
-
-	hw->wiphy->custom_regulatory = true;
-
-	/* Firmware does not support this */
-	hw->wiphy->disable_beacon_hints = true;
-
-	/*
-	 * For now, disable PS by default because it affects
-	 * RX performance significantly.
-	 */
-	hw->wiphy->ps_default = false;
-
-	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
-	/* we create the 802.11 header and a zero-length SSID element */
-	hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
-
-	/* Default value; 4 EDCA QOS priorities */
-	hw->queues = 4;
-
-	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
-
-	if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
-		priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-			&priv->bands[IEEE80211_BAND_2GHZ];
-	if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
-		priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
-			&priv->bands[IEEE80211_BAND_5GHZ];
-
-	ret = ieee80211_register_hw(priv->hw);
-	if (ret) {
-		IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
-		return ret;
-	}
-	priv->mac80211_registered = 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(iwl_setup_mac);
-
 int iwl_set_hw_params(struct iwl_priv *priv)
 {
 	priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
 	if (priv->cfg->mod_params->amsdu_size_8K)
-		priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K;
+		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
 	else
-		priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
-	priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
+		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
 
 	priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
 
@@ -1471,71 +1605,6 @@ int iwl_set_hw_params(struct iwl_priv *p
 }
 EXPORT_SYMBOL(iwl_set_hw_params);
 
-int iwl_init_drv(struct iwl_priv *priv)
-{
-	int ret;
-
-	priv->ibss_beacon = NULL;
-
-	spin_lock_init(&priv->lock);
-	spin_lock_init(&priv->sta_lock);
-	spin_lock_init(&priv->hcmd_lock);
-
-	INIT_LIST_HEAD(&priv->free_frames);
-
-	mutex_init(&priv->mutex);
-
-	/* Clear the driver's (not device's) station table */
-	iwl_clear_stations_table(priv);
-
-	priv->data_retry_limit = -1;
-	priv->ieee_channels = NULL;
-	priv->ieee_rates = NULL;
-	priv->band = IEEE80211_BAND_2GHZ;
-
-	priv->iw_mode = NL80211_IFTYPE_STATION;
-
-	priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
-
-	/* Choose which receivers/antennas to use */
-	if (priv->cfg->ops->hcmd->set_rxon_chain)
-		priv->cfg->ops->hcmd->set_rxon_chain(priv);
-
-	iwl_init_scan_params(priv);
-
-	iwl_reset_qos(priv);
-
-	priv->qos_data.qos_active = 0;
-	priv->qos_data.qos_cap.val = 0;
-
-	priv->rates_mask = IWL_RATES_MASK;
-	/* Set the tx_power_user_lmt to the lowest power level
-	 * this value will get overwritten by channel max power avg
-	 * from eeprom */
-	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
-
-	ret = iwl_init_channel_map(priv);
-	if (ret) {
-		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
-		goto err;
-	}
-
-	ret = iwlcore_init_geos(priv);
-	if (ret) {
-		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
-		goto err_free_channel_map;
-	}
-	iwlcore_init_hw_rates(priv, priv->ieee_rates);
-
-	return 0;
-
-err_free_channel_map:
-	iwl_free_channel_map(priv);
-err:
-	return ret;
-}
-EXPORT_SYMBOL(iwl_init_drv);
-
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
 	int ret = 0;
@@ -1583,15 +1652,6 @@ int iwl_set_tx_power(struct iwl_priv *pr
 }
 EXPORT_SYMBOL(iwl_set_tx_power);
 
-void iwl_uninit_drv(struct iwl_priv *priv)
-{
-	iwl_calib_free_results(priv);
-	iwlcore_free_geos(priv);
-	iwl_free_channel_map(priv);
-	kfree(priv->scan);
-}
-EXPORT_SYMBOL(iwl_uninit_drv);
-
 #define ICT_COUNT (PAGE_SIZE/sizeof(u32))
 
 /* Free dram table */
@@ -1915,9 +1975,9 @@ EXPORT_SYMBOL(iwl_isr_legacy);
 int iwl_send_bt_config(struct iwl_priv *priv)
 {
 	struct iwl_bt_cmd bt_cmd = {
-		.flags = 3,
-		.lead_time = 0xAA,
-		.max_kill = 1,
+		.flags = BT_COEX_MODE_4W,
+		.lead_time = BT_LEAD_TIME_DEF,
+		.max_kill = BT_MAX_KILL_DEF,
 		.kill_ack_mask = 0,
 		.kill_cts_mask = 0,
 	};
@@ -1927,16 +1987,21 @@ int iwl_send_bt_config(struct iwl_priv *
 }
 EXPORT_SYMBOL(iwl_send_bt_config);
 
-int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
+int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
 {
-	u32 stat_flags = 0;
-	struct iwl_host_cmd cmd = {
-		.id = REPLY_STATISTICS_CMD,
-		.flags = flags,
-		.len = sizeof(stat_flags),
-		.data = (u8 *) &stat_flags,
+	struct iwl_statistics_cmd statistics_cmd = {
+		.configuration_flags =
+			clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
 	};
-	return iwl_send_cmd(priv, &cmd);
+
+	if (flags & CMD_ASYNC)
+		return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD,
+					       sizeof(struct iwl_statistics_cmd),
+					       &statistics_cmd, NULL);
+	else
+		return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+					sizeof(struct iwl_statistics_cmd),
+					&statistics_cmd);
 }
 EXPORT_SYMBOL(iwl_send_statistics_request);
 
@@ -2077,10 +2142,7 @@ void iwl_rf_kill_ct_config(struct iwl_pr
 	spin_unlock_irqrestore(&priv->lock, flags);
 	priv->thermal_throttle.ct_kill_toggle = false;
 
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_1000:
-	case CSR_HW_REV_TYPE_6x00:
-	case CSR_HW_REV_TYPE_6x50:
+	if (priv->cfg->support_ct_kill_exit) {
 		adv_cmd.critical_temperature_enter =
 			cpu_to_le32(priv->hw_params.ct_kill_threshold);
 		adv_cmd.critical_temperature_exit =
@@ -2097,8 +2159,7 @@ void iwl_rf_kill_ct_config(struct iwl_pr
 					"exit is %d\n",
 				       priv->hw_params.ct_kill_threshold,
 				       priv->hw_params.ct_kill_exit_threshold);
-		break;
-	default:
+	} else {
 		cmd.critical_temperature_R =
 			cpu_to_le32(priv->hw_params.ct_kill_threshold);
 
@@ -2111,7 +2172,6 @@ void iwl_rf_kill_ct_config(struct iwl_pr
 					"succeeded, "
 					"critical temperature is %d\n",
 					priv->hw_params.ct_kill_threshold);
-		break;
 	}
 }
 EXPORT_SYMBOL(iwl_rf_kill_ct_config);
@@ -2143,7 +2203,7 @@ void iwl_rx_pm_sleep_notif(struct iwl_pr
 			   struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
 	IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
 		     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
@@ -2154,7 +2214,7 @@ EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
 void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
 				      struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 	IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
 			"notification for %s:\n", len,
@@ -2166,7 +2226,7 @@ EXPORT_SYMBOL(iwl_rx_pm_debug_statistics
 void iwl_rx_reply_error(struct iwl_priv *priv,
 			struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
 	IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
 		"seq 0x%04X ser 0x%08X\n",
@@ -2228,46 +2288,77 @@ int iwl_mac_conf_tx(struct ieee80211_hw
 EXPORT_SYMBOL(iwl_mac_conf_tx);
 
 static void iwl_ht_conf(struct iwl_priv *priv,
-			    struct ieee80211_bss_conf *bss_conf)
+			struct ieee80211_bss_conf *bss_conf)
 {
-	struct ieee80211_sta_ht_cap *ht_conf;
-	struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+	struct iwl_ht_config *ht_conf = &priv->current_ht_config;
 	struct ieee80211_sta *sta;
 
 	IWL_DEBUG_MAC80211(priv, "enter: \n");
 
-	if (!iwl_conf->is_ht)
+	if (!ht_conf->is_ht)
 		return;
 
+	ht_conf->ht_protection =
+		bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+	ht_conf->non_GF_STA_present =
+		!!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 
-	/*
-	 * It is totally wrong to base global information on something
-	 * that is valid only when associated, alas, this driver works
-	 * that way and I don't know how to fix it.
-	 */
-
-	rcu_read_lock();
-	sta = ieee80211_find_sta(priv->hw, priv->bssid);
-	if (!sta) {
-		rcu_read_unlock();
-		return;
-	}
-	ht_conf = &sta->ht_cap;
-
-	iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+	ht_conf->single_chain_sufficient = false;
 
-	memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
+	switch (priv->iw_mode) {
+	case NL80211_IFTYPE_STATION:
+		rcu_read_lock();
+		sta = ieee80211_find_sta(priv->vif, priv->bssid);
+		if (sta) {
+			struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+			int maxstreams;
 
-	iwl_conf->ht_protection =
-		bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
-	iwl_conf->non_GF_STA_present =
-		!!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+			maxstreams = (ht_cap->mcs.tx_params &
+				      IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+					>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+			maxstreams += 1;
 
-	rcu_read_unlock();
+			if ((ht_cap->mcs.rx_mask[1] == 0) &&
+			    (ht_cap->mcs.rx_mask[2] == 0))
+				ht_conf->single_chain_sufficient = true;
+			if (maxstreams <= 1)
+				ht_conf->single_chain_sufficient = true;
+		} else {
+			/*
+			 * If at all, this can only happen through a race
+			 * when the AP disconnects us while we're still
+			 * setting up the connection, in that case mac80211
+			 * will soon tell us about that.
+			 */
+			ht_conf->single_chain_sufficient = true;
+		}
+		rcu_read_unlock();
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		ht_conf->single_chain_sufficient = true;
+		break;
+	default:
+		break;
+	}
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
+static inline void iwl_set_no_assoc(struct iwl_priv *priv)
+{
+	priv->assoc_id = 0;
+	iwl_led_disassociate(priv);
+	/*
+	 * inform the ucode that there is no longer an
+	 * association and that no more packets should be
+	 * sent
+	 */
+	priv->staging_rxon.filter_flags &=
+		~RXON_FILTER_ASSOC_MSK;
+	priv->staging_rxon.assoc_id = 0;
+	iwlcore_commit_rxon(priv);
+}
+
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
 			  struct ieee80211_vif *vif,
@@ -2387,6 +2478,8 @@ void iwl_bss_info_changed(struct ieee802
 			priv->timestamp = bss_conf->timestamp;
 			priv->assoc_capability = bss_conf->assoc_capability;
 
+			iwl_led_associate(priv);
+
 			/*
 			 * We have just associated, don't start scan too early
 			 * leave time for EAPOL exchange to complete.
@@ -2398,8 +2491,7 @@ void iwl_bss_info_changed(struct ieee802
 			if (!iwl_is_rfkill(priv))
 				priv->cfg->ops->lib->post_associate(priv);
 		} else
-			priv->assoc_id = 0;
-
+			iwl_set_no_assoc(priv);
 	}
 
 	if (changes && iwl_is_associated(priv) && priv->assoc_id) {
@@ -2414,6 +2506,16 @@ void iwl_bss_info_changed(struct ieee802
 		}
 	}
 
+	if (changes & BSS_CHANGED_BEACON_ENABLED) {
+		if (vif->bss_conf.enable_beacon) {
+			memcpy(priv->staging_rxon.bssid_addr,
+			       bss_conf->bssid, ETH_ALEN);
+			memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+			iwlcore_config_ap(priv);
+		} else
+			iwl_set_no_assoc(priv);
+	}
+
 	mutex_unlock(&priv->mutex);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2570,7 +2672,7 @@ int iwl_mac_config(struct ieee80211_hw *
 	struct iwl_priv *priv = hw->priv;
 	const struct iwl_channel_info *ch_info;
 	struct ieee80211_conf *conf = &hw->conf;
-	struct iwl_ht_info *ht_conf = &priv->current_ht_config;
+	struct iwl_ht_config *ht_conf = &priv->current_ht_config;
 	unsigned long flags = 0;
 	int ret = 0;
 	u16 ch;
@@ -2620,21 +2722,18 @@ int iwl_mac_config(struct ieee80211_hw *
 			if (conf_is_ht40_minus(conf)) {
 				ht_conf->extension_chan_offset =
 					IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-				ht_conf->supported_chan_width =
-					IWL_CHANNEL_WIDTH_40MHZ;
+				ht_conf->is_40mhz = true;
 			} else if (conf_is_ht40_plus(conf)) {
 				ht_conf->extension_chan_offset =
 					IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-				ht_conf->supported_chan_width =
-					IWL_CHANNEL_WIDTH_40MHZ;
+				ht_conf->is_40mhz = true;
 			} else {
 				ht_conf->extension_chan_offset =
 					IEEE80211_HT_PARAM_CHA_SEC_NONE;
-				ht_conf->supported_chan_width =
-					IWL_CHANNEL_WIDTH_20MHZ;
+				ht_conf->is_40mhz = false;
 			}
 		} else
-			ht_conf->supported_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
+			ht_conf->is_40mhz = false;
 		/* Default to no protection. Protection mode will later be set
 		 * from BSS config in iwl_ht_conf */
 		ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
@@ -2646,9 +2745,26 @@ int iwl_mac_config(struct ieee80211_hw *
 			priv->staging_rxon.flags = 0;
 
 		iwl_set_rxon_channel(priv, conf->channel);
+		iwl_set_rxon_ht(priv, ht_conf);
 
 		iwl_set_flags_for_band(priv, conf->channel->band);
 		spin_unlock_irqrestore(&priv->lock, flags);
+		if (iwl_is_associated(priv) &&
+		    (le16_to_cpu(priv->active_rxon.channel) != ch) &&
+		    priv->cfg->ops->lib->set_channel_switch) {
+			iwl_set_rate(priv);
+			/*
+			 * at this point, staging_rxon has the
+			 * configuration for channel switch
+			 */
+			ret = priv->cfg->ops->lib->set_channel_switch(priv,
+				ch);
+			if (!ret) {
+				iwl_print_rx_config_cmd(priv);
+				goto out;
+			}
+			priv->switch_rxon.switch_in_progress = false;
+		}
  set_ch_out:
 		/* The list of supported rates and rate mask can be different
 		 * for each band; since the band may have changed, reset
@@ -2656,7 +2772,8 @@ int iwl_mac_config(struct ieee80211_hw *
 		iwl_set_rate(priv);
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_PS) {
+	if (changed & (IEEE80211_CONF_CHANGE_PS |
+			IEEE80211_CONF_CHANGE_IDLE)) {
 		ret = iwl_power_update_mode(priv, false);
 		if (ret)
 			IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
@@ -2740,7 +2857,7 @@ void iwl_mac_reset_tsf(struct ieee80211_
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	spin_lock_irqsave(&priv->lock, flags);
-	memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
+	memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	iwl_reset_qos(priv);
@@ -2792,6 +2909,55 @@ void iwl_mac_reset_tsf(struct ieee80211_
 }
 EXPORT_SYMBOL(iwl_mac_reset_tsf);
 
+int iwl_alloc_txq_mem(struct iwl_priv *priv)
+{
+	if (!priv->txq)
+		priv->txq = kzalloc(
+			sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
+			GFP_KERNEL);
+	if (!priv->txq) {
+		IWL_ERR(priv, "Not enough memory for txq \n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(iwl_alloc_txq_mem);
+
+void iwl_free_txq_mem(struct iwl_priv *priv)
+{
+	kfree(priv->txq);
+	priv->txq = NULL;
+}
+EXPORT_SYMBOL(iwl_free_txq_mem);
+
+int iwl_send_wimax_coex(struct iwl_priv *priv)
+{
+	struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
+
+	if (priv->cfg->support_wimax_coexist) {
+		/* UnMask wake up src at associated sleep */
+		coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
+
+		/* UnMask wake up src at unassociated sleep */
+		coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
+		memcpy(coex_cmd.sta_prio, cu_priorities,
+			sizeof(struct iwl_wimax_coex_event_entry) *
+			 COEX_NUM_OF_EVENTS);
+
+		/* enabling the coexistence feature */
+		coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
+
+		/* enabling the priorities tables */
+		coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
+	} else {
+		/* coexistence is disabled */
+		memset(&coex_cmd, 0, sizeof(coex_cmd));
+	}
+	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+				sizeof(coex_cmd), &coex_cmd);
+}
+EXPORT_SYMBOL(iwl_send_wimax_coex);
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 
 #define IWL_TRAFFIC_DUMP_SIZE	(IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
@@ -2929,15 +3095,11 @@ const char *get_ctrl_string(int cmd)
 	}
 }
 
-void iwl_clear_tx_stats(struct iwl_priv *priv)
+void iwl_clear_traffic_stats(struct iwl_priv *priv)
 {
 	memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
-
-}
-
-void iwl_clear_rx_stats(struct iwl_priv *priv)
-{
 	memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
+	priv->led_tpt = 0;
 }
 
 /*
@@ -3030,6 +3192,7 @@ void iwl_update_stats(struct iwl_priv *p
 		stats->data_cnt++;
 		stats->data_bytes += len;
 	}
+	iwl_leds_background(priv);
 }
 EXPORT_SYMBOL(iwl_update_stats);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,6 +63,8 @@
 #ifndef __iwl_core_h__
 #define __iwl_core_h__
 
+#include <generated/utsrelease.h>
+
 /************************
  * forward declarations *
  ************************/
@@ -70,7 +72,7 @@ struct iwl_host_cmd;
 struct iwl_cmd;
 
 
-#define IWLWIFI_VERSION "1.3.27k"
+#define IWLWIFI_VERSION UTS_RELEASE "-k"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
@@ -89,6 +91,7 @@ struct iwl_hcmd_ops {
 	int (*rxon_assoc)(struct iwl_priv *priv);
 	int (*commit_rxon)(struct iwl_priv *priv);
 	void (*set_rxon_chain)(struct iwl_priv *priv);
+	int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
 };
 
 struct iwl_hcmd_utils_ops {
@@ -97,7 +100,8 @@ struct iwl_hcmd_utils_ops {
 	void (*gain_computation)(struct iwl_priv *priv,
 			u32 *average_noise,
 			u16 min_average_noise_antennat_i,
-			u32 min_average_noise);
+			u32 min_average_noise,
+			u8 default_chain);
 	void (*chain_noise_reset)(struct iwl_priv *priv);
 	void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
 			__le32 *tx_flags);
@@ -107,7 +111,6 @@ struct iwl_hcmd_utils_ops {
 
 struct iwl_apm_ops {
 	int (*init)(struct iwl_priv *priv);
-	int (*reset)(struct iwl_priv *priv);
 	void (*stop)(struct iwl_priv *priv);
 	void (*config)(struct iwl_priv *priv);
 	int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
@@ -166,8 +169,9 @@ struct iwl_lib_ops {
 	int (*is_valid_rtc_data_addr)(u32 addr);
 	/* 1st ucode load */
 	int (*load_ucode)(struct iwl_priv *priv);
-	void (*dump_nic_event_log)(struct iwl_priv *priv);
+	void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log);
 	void (*dump_nic_error_log)(struct iwl_priv *priv);
+	int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
 	/* power management */
 	struct iwl_apm_ops apm_ops;
 
@@ -185,18 +189,24 @@ struct iwl_lib_ops {
 	struct iwl_temp_ops temp_ops;
 };
 
+struct iwl_led_ops {
+	int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
+	int (*on)(struct iwl_priv *priv);
+	int (*off)(struct iwl_priv *priv);
+};
+
 struct iwl_ops {
 	const struct iwl_ucode_ops *ucode;
 	const struct iwl_lib_ops *lib;
 	const struct iwl_hcmd_ops *hcmd;
 	const struct iwl_hcmd_utils_ops *utils;
+	const struct iwl_led_ops *led;
 };
 
 struct iwl_mod_params {
 	int sw_crypto;		/* def: 0 = using hardware encryption */
 	int disable_hw_scan;	/* def: 0 = use h/w scan */
 	int num_of_queues;	/* def: HW dependent */
-	int num_of_ampdu_queues;/* def: HW dependent */
 	int disable_11n;	/* def: 0 = 11n capabilities enabled */
 	int amsdu_size_8K;	/* def: 1 = enable 8K amsdu size */
 	int antenna;  		/* def: 0 = both antennas (use diversity) */
@@ -213,7 +223,15 @@ struct iwl_mod_params {
  * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @max_ll_items: max number of OTP blocks
  * @shadow_ram_support: shadow support for OTP memory
+ * @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
  * @use_rts_for_ht: use rts/cts protection for HT traffic
+ * @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
+ * @sm_ps_mode: spatial multiplexing power save mode
+ * @support_wimax_coexist: support wimax/wifi co-exist
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -245,18 +263,32 @@ struct iwl_cfg {
 	int eeprom_size;
 	u16  eeprom_ver;
 	u16  eeprom_calib_ver;
+	int num_of_queues;	/* def: HW dependent */
+	int num_of_ampdu_queues;/* def: HW dependent */
 	const struct iwl_ops *ops;
 	const struct iwl_mod_params *mod_params;
 	u8   valid_tx_ant;
 	u8   valid_rx_ant;
-	bool need_pll_cfg;
+
+	/* for iwl_apm_init() */
+	u32 pll_cfg_val;
+	bool set_l0s;
+	bool use_bsm;
+
 	bool use_isr_legacy;
 	enum iwl_pa_type pa_type;
 	const u16 max_ll_items;
 	const bool shadow_ram_support;
 	const bool ht_greenfield_support;
+	u16 led_compensation;
 	const bool broken_powersave;
 	bool use_rts_for_ht;
+	int chain_noise_num_beacons;
+	const bool supports_idle;
+	bool adv_thermal_throttle;
+	bool support_ct_kill_exit;
+	u8 sm_ps_mode;
+	const bool support_wimax_coexist;
 };
 
 /***************************
@@ -275,7 +307,7 @@ int iwl_check_rxon_cmd(struct iwl_priv *
 int iwl_full_rxon_required(struct iwl_priv *priv);
 void iwl_set_rxon_chain(struct iwl_priv *priv);
 int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
-void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
 u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
 			 struct ieee80211_sta_ht_cap *sta_ht_inf);
 void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
@@ -289,10 +321,7 @@ void iwl_configure_filter(struct ieee802
 			  unsigned int changed_flags,
 			  unsigned int *total_flags, u64 multicast);
 int iwl_hw_nic_init(struct iwl_priv *priv);
-int iwl_setup_mac(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
-int iwl_init_drv(struct iwl_priv *priv);
-void iwl_uninit_drv(struct iwl_priv *priv);
 bool iwl_is_monitor_mode(struct iwl_priv *priv);
 void iwl_post_associate(struct iwl_priv *priv);
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
@@ -311,6 +340,11 @@ void iwl_config_ap(struct iwl_priv *priv
 int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
 			 struct ieee80211_tx_queue_stats *stats);
 void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
+int iwl_alloc_txq_mem(struct iwl_priv *priv);
+void iwl_free_txq_mem(struct iwl_priv *priv);
+void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+				__le32 *tx_flags);
+int iwl_send_wimax_coex(struct iwl_priv *priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_alloc_traffic_mem(struct iwl_priv *priv);
 void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -321,8 +355,7 @@ void iwl_dbg_log_rx_data_frame(struct iw
 				u16 length, struct ieee80211_hdr *header);
 const char *get_mgmt_string(int cmd);
 const char *get_ctrl_string(int cmd);
-void iwl_clear_tx_stats(struct iwl_priv *priv);
-void iwl_clear_rx_stats(struct iwl_priv *priv);
+void iwl_clear_traffic_stats(struct iwl_priv *priv);
 void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
 		      u16 len);
 #else
@@ -358,6 +391,7 @@ static inline void iwl_update_stats(stru
 		/* data */
 		stats->data_bytes += len;
 	}
+	iwl_leds_background(priv);
 }
 #endif
 /*****************************************************
@@ -393,6 +427,8 @@ void iwl_rx_missed_beacon_notif(struct i
 			       struct iwl_rx_mem_buffer *rxb);
 void iwl_rx_statistics(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb);
+void iwl_reply_statistics(struct iwl_priv *priv,
+			  struct iwl_rx_mem_buffer *rxb);
 void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 
 /* TX helpers */
@@ -410,6 +446,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv
 int iwl_hw_tx_queue_init(struct iwl_priv *priv,
 			 struct iwl_tx_queue *txq);
 int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+			    int sta_id, int tid, int freed);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 		      int slots_num, u32 txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
@@ -511,7 +549,7 @@ int iwl_send_cmd_pdu_async(struct iwl_pr
 			   const void *data,
 			   void (*callback)(struct iwl_priv *priv,
 					    struct iwl_device_cmd *cmd,
-					    struct sk_buff *skb));
+					    struct iwl_rx_packet *pkt));
 
 int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
 
@@ -544,15 +582,12 @@ int iwl_pci_resume(struct pci_dev *pdev)
 /*****************************************************
 *  Error Handling Debugging
 ******************************************************/
-#ifdef CONFIG_IWLWIFI_DEBUG
-void iwl_dump_nic_event_log(struct iwl_priv *priv);
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
+void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
+#ifdef CONFIG_IWLWIFI_DEBUG
+void iwl_print_rx_config_cmd(struct iwl_priv *priv);
 #else
-static inline void iwl_dump_nic_event_log(struct iwl_priv *priv)
-{
-}
-
-static inline void iwl_dump_nic_error_log(struct iwl_priv *priv)
+static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 {
 }
 #endif
@@ -571,6 +606,7 @@ void iwlcore_free_geos(struct iwl_priv *
 #define STATUS_HCMD_SYNC_ACTIVE	1	/* sync host command in progress */
 #define STATUS_INT_ENABLED	2
 #define STATUS_RF_KILL_HW	3
+#define STATUS_CT_KILL		4
 #define STATUS_INIT		5
 #define STATUS_ALIVE		6
 #define STATUS_READY		7
@@ -615,6 +651,11 @@ static inline int iwl_is_rfkill(struct i
 	return iwl_is_rfkill_hw(priv);
 }
 
+static inline int iwl_is_ctkill(struct iwl_priv *priv)
+{
+	return test_bit(STATUS_CT_KILL, &priv->status);
+}
+
 static inline int iwl_is_ready_rf(struct iwl_priv *priv)
 {
 
@@ -626,7 +667,8 @@ static inline int iwl_is_ready_rf(struct
 
 extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
 extern int iwl_send_bt_config(struct iwl_priv *priv);
-extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
+extern int iwl_send_statistics_request(struct iwl_priv *priv,
+				       u8 flags, bool clear);
 extern int iwl_verify_ucode(struct iwl_priv *priv);
 extern int iwl_send_lq_cmd(struct iwl_priv *priv,
 		struct iwl_link_quality_cmd *lq, u8 flags);
@@ -636,6 +678,9 @@ extern void iwl_rx_reply_rx_phy(struct i
 				    struct iwl_rx_mem_buffer *rxb);
 void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 					   struct iwl_rx_mem_buffer *rxb);
+void iwl_apm_stop(struct iwl_priv *priv);
+int iwl_apm_stop_master(struct iwl_priv *priv);
+int iwl_apm_init(struct iwl_priv *priv);
 
 void iwl_setup_rxon_timing(struct iwl_priv *priv);
 static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
@@ -655,5 +700,4 @@ static inline const struct ieee80211_sup
 {
 	return priv->hw->wiphy->bands[band];
 }
-
 #endif /* __iwl_core_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2010-02-24 13:52:17.000000000 -0500
@@ -62,11 +62,28 @@
  *****************************************************************************/
 #ifndef __iwl_csr_h__
 #define __iwl_csr_h__
-/*=== CSR (control and status registers) ===*/
+/*
+ * CSR (control and status registers)
+ *
+ * CSR registers are mapped directly into PCI bus space, and are accessible
+ * whenever platform supplies power to device, even when device is in
+ * low power states due to driver-invoked device resets
+ * (e.g. CSR_RESET_REG_FLAG_SW_RESET) or uCode-driven power-saving modes.
+ *
+ * Use iwl_write32() and iwl_read32() family to access these registers;
+ * these provide simple PCI bus access, without waking up the MAC.
+ * Do not use iwl_write_direct32() family for these registers;
+ * no need to "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ.
+ * The MAC (uCode processor, etc.) does not need to be powered up for accessing
+ * the CSR registers.
+ *
+ * NOTE:  Device does need to be awake in order to read this memory
+ *        via CSR_EEPROM and CSR_OTP registers
+ */
 #define CSR_BASE    (0x000)
 
 #define CSR_HW_IF_CONFIG_REG    (CSR_BASE+0x000) /* hardware interface config */
-#define CSR_INT_COALESCING     (CSR_BASE+0x004) /* accum ints, 32-usec units */
+#define CSR_INT_COALESCING      (CSR_BASE+0x004) /* accum ints, 32-usec units */
 #define CSR_INT                 (CSR_BASE+0x008) /* host interrupt status/ack */
 #define CSR_INT_MASK            (CSR_BASE+0x00c) /* host interrupt enable */
 #define CSR_FH_INT_STATUS       (CSR_BASE+0x010) /* busmaster int status/ack*/
@@ -74,43 +91,66 @@
 #define CSR_RESET               (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
 #define CSR_GP_CNTRL            (CSR_BASE+0x024)
 
+/* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */
+#define CSR_INT_PERIODIC_REG	(CSR_BASE+0x005)
+
 /*
  * Hardware revision info
  * Bit fields:
  * 31-8:  Reserved
- *  7-4:  Type of device:  0x0 = 4965, 0xd = 3945
+ *  7-4:  Type of device:  see CSR_HW_REV_TYPE_xxx definitions
  *  3-2:  Revision step:  0 = A, 1 = B, 2 = C, 3 = D
- *  1-0:  "Dash" value, as in A-1, etc.
+ *  1-0:  "Dash" (-) value, as in A-1, etc.
  *
  * NOTE:  Revision step affects calculation of CCK txpower for 4965.
+ * NOTE:  See also CSR_HW_REV_WA_REG (work-around for bug in 4965).
  */
 #define CSR_HW_REV              (CSR_BASE+0x028)
 
-/* EEPROM reads */
+/*
+ * EEPROM and OTP (one-time-programmable) memory reads
+ *
+ * NOTE:  Device must be awake, initialized via apm_ops.init(),
+ *        in order to read.
+ */
 #define CSR_EEPROM_REG          (CSR_BASE+0x02c)
 #define CSR_EEPROM_GP           (CSR_BASE+0x030)
 #define CSR_OTP_GP_REG   	(CSR_BASE+0x034)
+
 #define CSR_GIO_REG		(CSR_BASE+0x03C)
 #define CSR_GP_UCODE_REG	(CSR_BASE+0x048)
 #define CSR_GP_DRIVER_REG	(CSR_BASE+0x050)
+
+/*
+ * UCODE-DRIVER GP (general purpose) mailbox registers.
+ * SET/CLR registers set/clear bit(s) if "1" is written.
+ */
 #define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
 #define CSR_UCODE_DRV_GP1_SET   (CSR_BASE+0x058)
 #define CSR_UCODE_DRV_GP1_CLR   (CSR_BASE+0x05c)
 #define CSR_UCODE_DRV_GP2       (CSR_BASE+0x060)
+
 #define CSR_LED_REG             (CSR_BASE+0x094)
 #define CSR_DRAM_INT_TBL_REG	(CSR_BASE+0x0A0)
+
+/* GIO Chicken Bits (PCI Express bus link power management) */
 #define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
 
-#define CSR_INT_PERIODIC_REG	(CSR_BASE+0x005)
 /* Analog phase-lock-loop configuration  */
 #define CSR_ANA_PLL_CFG         (CSR_BASE+0x20c)
+
 /*
- * Indicates hardware rev, to determine CCK backoff for txpower calculation.
+ * CSR Hardware Revision Workaround Register.  Indicates hardware rev;
+ * "step" determines CCK backoff for txpower calculation.  Used for 4965 only.
+ * See also CSR_HW_REV register.
  * Bit fields:
  *  3-2:  0 = A, 1 = B, 2 = C, 3 = D step
+ *  1-0:  "Dash" (-) value, as in C-1, etc.
  */
-#define CSR_HW_REV_WA_REG	(CSR_BASE+0x22C)
-#define CSR_DBG_HPET_MEM_REG	(CSR_BASE+0x240)
+#define CSR_HW_REV_WA_REG		(CSR_BASE+0x22C)
+
+#define CSR_DBG_HPET_MEM_REG		(CSR_BASE+0x240)
+#define CSR_DBG_LINK_PWR_MGMT_REG	(CSR_BASE+0x250)
 
 /* Bits for CSR_HW_IF_CONFIG_REG */
 #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R	(0x00000010)
@@ -125,14 +165,14 @@
 #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
 #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
 
-#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A		(0x00080000)
-#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM		(0x00200000)
-#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY		(0x00400000)
-#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE	(0x02000000)
-#define CSR_HW_IF_CONFIG_REG_PREPARE			(0x08000000)
+#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A	(0x00080000)
+#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM	(0x00200000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY	(0x00400000) /* PCI_OWN_SEM */
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */
+#define CSR_HW_IF_CONFIG_REG_PREPARE		  (0x08000000) /* WAKE_ME */
 
-#define CSR_INT_PERIODIC_DIS			(0x00)
-#define CSR_INT_PERIODIC_ENA			(0xFF)
+#define CSR_INT_PERIODIC_DIS			(0x00) /* disable periodic int*/
+#define CSR_INT_PERIODIC_ENA			(0xFF) /* 255*32 usec ~ 8 msec*/
 
 /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
  * acknowledged (reset) by host writing "1" to flagged bits. */
@@ -195,8 +235,46 @@
 #define CSR_RESET_REG_FLAG_SW_RESET                  (0x00000080)
 #define CSR_RESET_REG_FLAG_MASTER_DISABLED           (0x00000100)
 #define CSR_RESET_REG_FLAG_STOP_MASTER               (0x00000200)
+#define CSR_RESET_LINK_PWR_MGMT_DISABLED             (0x80000000)
 
-/* GP (general purpose) CONTROL */
+/*
+ * GP (general purpose) CONTROL REGISTER
+ * Bit fields:
+ *    27:  HW_RF_KILL_SW
+ *         Indicates state of (platform's) hardware RF-Kill switch
+ * 26-24:  POWER_SAVE_TYPE
+ *         Indicates current power-saving mode:
+ *         000 -- No power saving
+ *         001 -- MAC power-down
+ *         010 -- PHY (radio) power-down
+ *         011 -- Error
+ *   9-6:  SYS_CONFIG
+ *         Indicates current system configuration, reflecting pins on chip
+ *         as forced high/low by device circuit board.
+ *     4:  GOING_TO_SLEEP
+ *         Indicates MAC is entering a power-saving sleep power-down.
+ *         Not a good time to access device-internal resources.
+ *     3:  MAC_ACCESS_REQ
+ *         Host sets this to request and maintain MAC wakeup, to allow host
+ *         access to device-internal resources.  Host must wait for
+ *         MAC_CLOCK_READY (and !GOING_TO_SLEEP) before accessing non-CSR
+ *         device registers.
+ *     2:  INIT_DONE
+ *         Host sets this to put device into fully operational D0 power mode.
+ *         Host resets this after SW_RESET to put device into low power mode.
+ *     0:  MAC_CLOCK_READY
+ *         Indicates MAC (ucode processor, etc.) is powered up and can run.
+ *         Internal resources are accessible.
+ *         NOTE:  This does not indicate that the processor is actually running.
+ *         NOTE:  This does not indicate that 4965 or 3945 has completed
+ *                init or post-power-down restore of internal SRAM memory.
+ *                Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
+ *                SRAM is restored and uCode is in normal operation mode.
+ *                Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
+ *                do not need to save/restore it.
+ *         NOTE:  After device reset, this bit remains "0" until host sets
+ *                INIT_DONE
+ */
 #define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY        (0x00000001)
 #define CSR_GP_CNTRL_REG_FLAG_INIT_DONE              (0x00000004)
 #define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ         (0x00000008)
@@ -229,18 +307,58 @@
 #define CSR_EEPROM_REG_MSK_DATA		(0xFFFF0000)
 
 /* EEPROM GP */
-#define CSR_EEPROM_GP_VALID_MSK		(0x00000007)
-#define CSR_EEPROM_GP_BAD_SIGNATURE	(0x00000000)
+#define CSR_EEPROM_GP_VALID_MSK		(0x00000007) /* signature */
 #define CSR_EEPROM_GP_IF_OWNER_MSK	(0x00000180)
+#define CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP	(0x00000000)
+#define CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP		(0x00000001)
+#define CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K		(0x00000002)
+#define CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K		(0x00000004)
+
+/* One-time-programmable memory general purpose reg */
 #define CSR_OTP_GP_REG_DEVICE_SELECT	(0x00010000) /* 0 - EEPROM, 1 - OTP */
 #define CSR_OTP_GP_REG_OTP_ACCESS_MODE	(0x00020000) /* 0 - absolute, 1 - relative */
 #define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK          (0x00100000) /* bit 20 */
 #define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK        (0x00200000) /* bit 21 */
 
+/* GP REG */
+#define CSR_GP_REG_POWER_SAVE_STATUS_MSK            (0x03000000) /* bit 24/25 */
+#define CSR_GP_REG_NO_POWER_SAVE            (0x00000000)
+#define CSR_GP_REG_MAC_POWER_SAVE           (0x01000000)
+#define CSR_GP_REG_PHY_POWER_SAVE           (0x02000000)
+#define CSR_GP_REG_POWER_SAVE_ERROR         (0x03000000)
+
+
 /* CSR GIO */
 #define CSR_GIO_REG_VAL_L0S_ENABLED	(0x00000002)
 
-/* UCODE DRV GP */
+/*
+ * UCODE-DRIVER GP (general purpose) mailbox register 1
+ * Host driver and uCode write and/or read this register to communicate with
+ * each other.
+ * Bit fields:
+ *     4:  UCODE_DISABLE
+ *         Host sets this to request permanent halt of uCode, same as
+ *         sending CARD_STATE command with "halt" bit set.
+ *     3:  CT_KILL_EXIT
+ *         Host sets this to request exit from CT_KILL state, i.e. host thinks
+ *         device temperature is low enough to continue normal operation.
+ *     2:  CMD_BLOCKED
+ *         Host sets this during RF KILL power-down sequence (HW, SW, CT KILL)
+ *         to release uCode to clear all Tx and command queues, enter
+ *         unassociated mode, and power down.
+ *         NOTE:  Some devices also use HBUS_TARG_MBX_C register for this bit.
+ *     1:  SW_BIT_RFKILL
+ *         Host sets this when issuing CARD_STATE command to request
+ *         device sleep.
+ *     0:  MAC_SLEEP
+ *         uCode sets this when preparing a power-saving power-down.
+ *         uCode resets this when power-up is complete and SRAM is sane.
+ *         NOTE:  3945/4965 saves internal SRAM data to host when powering down,
+ *                and must restore this data after powering back up.
+ *                MAC_SLEEP is the best indication that restore is complete.
+ *                Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
+ *                do not need to save/restore it.
+ */
 #define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP             (0x00000001)
 #define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
 #define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
@@ -253,7 +371,7 @@
 #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA	    (0x00000002)
 
 
-/* GI Chicken Bits */
+/* GIO Chicken Bits (PCI Express bus link power management) */
 #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
 #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER  (0x20000000)
 
@@ -273,8 +391,23 @@
 #define CSR_DRAM_INT_TBL_ENABLE		(1 << 31)
 #define CSR_DRAM_INIT_TBL_WRAP_CHECK	(1 << 27)
 
-/*=== HBUS (Host-side Bus) ===*/
+/*
+ * HBUS (Host-side Bus)
+ *
+ * HBUS registers are mapped directly into PCI bus space, but are used
+ * to indirectly access device's internal memory or registers that
+ * may be powered-down.
+ *
+ * Use iwl_write_direct32()/iwl_read_direct32() family for these registers;
+ * host must "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
+ * to make sure the MAC (uCode processor, etc.) is powered up for accessing
+ * internal resources.
+ *
+ * Do not use iwl_write32()/iwl_read32() family to access these registers;
+ * these provide only simple PCI bus access, without waking up the MAC.
+ */
 #define HBUS_BASE	(0x400)
+
 /*
  * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
  * structures, error log, event log, verifying uCode load).
@@ -289,6 +422,10 @@
 #define HBUS_TARG_MEM_WDAT      (HBUS_BASE+0x018)
 #define HBUS_TARG_MEM_RDAT      (HBUS_BASE+0x01c)
 
+/* Mailbox C, used as workaround alternative to CSR_UCODE_DRV_GP1 mailbox */
+#define HBUS_TARG_MBX_C         (HBUS_BASE+0x030)
+#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED         (0x00000004)
+
 /*
  * Registers for accessing device's internal peripheral registers
  * (e.g. SCD, BSM, etc.).  First write to address register,
@@ -303,16 +440,12 @@
 #define HBUS_TARG_PRPH_RDAT     (HBUS_BASE+0x050)
 
 /*
- * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
+ * Per-Tx-queue write pointer (index, really!)
  * Indicates index to next TFD that driver will fill (1 past latest filled).
  * Bit usage:
  *  0-7:  queue write index
  * 11-8:  queue selector
  */
 #define HBUS_TARG_WRPTR         (HBUS_BASE+0x060)
-#define HBUS_TARG_MBX_C         (HBUS_BASE+0x030)
-
-#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED         (0x00000004)
-
 
 #endif /* !__iwl_csr_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,9 +47,9 @@
 		goto err; 						\
 } while (0)
 
-#define DEBUGFS_ADD_FILE(name, parent) do {                             \
+#define DEBUGFS_ADD_FILE(name, parent, mode) do {                       \
 	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_file(#name, S_IWUSR | S_IRUSR,                   \
+	debugfs_create_file(#name, mode,                                \
 				dbgfs->dir_##parent, priv,              \
 				&iwl_dbgfs_##name##_ops);               \
 	if (!(dbgfs->dbgfs_##parent##_files.file_##name))               \
@@ -131,21 +131,22 @@ static ssize_t iwl_dbgfs_tx_statistics_r
 
 	int cnt;
 	ssize_t ret;
-	const size_t bufsz = 100 + sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
+	const size_t bufsz = 100 +
+		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
 	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
 		pos += scnprintf(buf + pos, bufsz - pos,
-				 "\t%s\t\t: %u\n",
+				 "\t%25s\t\t: %u\n",
 				 get_mgmt_string(cnt),
 				 priv->tx_stats.mgmt[cnt]);
 	}
 	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
 	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
 		pos += scnprintf(buf + pos, bufsz - pos,
-				 "\t%s\t\t: %u\n",
+				 "\t%25s\t\t: %u\n",
 				 get_ctrl_string(cnt),
 				 priv->tx_stats.ctrl[cnt]);
 	}
@@ -159,7 +160,7 @@ static ssize_t iwl_dbgfs_tx_statistics_r
 	return ret;
 }
 
-static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file,
+static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
 					const char __user *user_buf,
 					size_t count, loff_t *ppos)
 {
@@ -174,8 +175,7 @@ static ssize_t iwl_dbgfs_tx_statistics_w
 		return -EFAULT;
 	if (sscanf(buf, "%x", &clear_flag) != 1)
 		return -EFAULT;
-	if (clear_flag == 1)
-		iwl_clear_tx_stats(priv);
+	iwl_clear_traffic_stats(priv);
 
 	return count;
 }
@@ -190,7 +190,7 @@ static ssize_t iwl_dbgfs_rx_statistics_r
 	int cnt;
 	ssize_t ret;
 	const size_t bufsz = 100 +
-		sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
+		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -198,14 +198,14 @@ static ssize_t iwl_dbgfs_rx_statistics_r
 	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
 	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
 		pos += scnprintf(buf + pos, bufsz - pos,
-				 "\t%s\t\t: %u\n",
+				 "\t%25s\t\t: %u\n",
 				 get_mgmt_string(cnt),
 				 priv->rx_stats.mgmt[cnt]);
 	}
 	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
 	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
 		pos += scnprintf(buf + pos, bufsz - pos,
-				 "\t%s\t\t: %u\n",
+				 "\t%25s\t\t: %u\n",
 				 get_ctrl_string(cnt),
 				 priv->rx_stats.ctrl[cnt]);
 	}
@@ -220,26 +220,6 @@ static ssize_t iwl_dbgfs_rx_statistics_r
 	return ret;
 }
 
-static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file,
-					const char __user *user_buf,
-					size_t count, loff_t *ppos)
-{
-	struct iwl_priv *priv = file->private_data;
-	u32 clear_flag;
-	char buf[8];
-	int buf_size;
-
-	memset(buf, 0, sizeof(buf));
-	buf_size = min(count, sizeof(buf) -  1);
-	if (copy_from_user(buf, user_buf, buf_size))
-		return -EFAULT;
-	if (sscanf(buf, "%x", &clear_flag) != 1)
-		return -EFAULT;
-	if (clear_flag == 1)
-		iwl_clear_rx_stats(priv);
-	return count;
-}
-
 #define BYTE1_MASK 0x000000ff;
 #define BYTE2_MASK 0x0000ffff;
 #define BYTE3_MASK 0x00ffffff;
@@ -248,13 +228,29 @@ static ssize_t iwl_dbgfs_sram_read(struc
 					size_t count, loff_t *ppos)
 {
 	u32 val;
-	char buf[1024];
+	char *buf;
 	ssize_t ret;
 	int i;
 	int pos = 0;
 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-	const size_t bufsz = sizeof(buf);
+	size_t bufsz;
 
+	/* default is to dump the entire data segment */
+	if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) {
+		priv->dbgfs->sram_offset = 0x800000;
+		if (priv->ucode_type == UCODE_INIT)
+			priv->dbgfs->sram_len = priv->ucode_init_data.len;
+		else
+			priv->dbgfs->sram_len = priv->ucode_data.len;
+	}
+	bufsz =  30 + priv->dbgfs->sram_len * sizeof(char) * 10;
+	buf = kmalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
+			priv->dbgfs->sram_len);
+	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
+			priv->dbgfs->sram_offset);
 	for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
 		val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
 					priv->dbgfs->sram_len - i);
@@ -271,11 +267,14 @@ static ssize_t iwl_dbgfs_sram_read(struc
 				break;
 			}
 		}
+		if (!(i % 16))
+			pos += scnprintf(buf + pos, bufsz - pos, "\n");
 		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
 	}
 	pos += scnprintf(buf + pos, bufsz - pos, "\n");
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
 	return ret;
 }
 
@@ -335,8 +334,6 @@ static ssize_t iwl_dbgfs_stations_read(s
 			pos += scnprintf(buf + pos, bufsz - pos,
 					"flags: 0x%x\n",
 					station->sta.station_flags_msk);
-			pos += scnprintf(buf + pos, bufsz - pos,
-					"ps_status: %u\n", station->ps_status);
 			pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
 			pos += scnprintf(buf + pos, bufsz - pos,
 					"seq_num\t\ttxq_id");
@@ -383,6 +380,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct
 	int pos = 0, ofs = 0, buf_size = 0;
 	const u8 *ptr;
 	char *buf;
+	u16 eeprom_ver;
 	size_t eeprom_len = priv->cfg->eeprom_size;
 	buf_size = 4 * eeprom_len + 256;
 
@@ -403,9 +401,11 @@ static ssize_t iwl_dbgfs_nvm_read(struct
 		IWL_ERR(priv, "Can not allocate Buffer\n");
 		return -ENOMEM;
 	}
-	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",
+	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
+			"version: 0x%x\n",
 			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
-			? "OTP" : "EEPROM");
+			 ? "OTP" : "EEPROM", eeprom_ver);
 	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
 		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
 		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
@@ -436,7 +436,7 @@ static ssize_t iwl_dbgfs_log_event_write
 	if (sscanf(buf, "%d", &event_log_flag) != 1)
 		return -EFAULT;
 	if (event_log_flag == 1)
-		priv->cfg->ops->lib->dump_nic_event_log(priv);
+		priv->cfg->ops->lib->dump_nic_event_log(priv, true);
 
 	return count;
 }
@@ -532,6 +532,8 @@ static ssize_t iwl_dbgfs_status_read(str
 		test_bit(STATUS_INT_ENABLED, &priv->status));
 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
 		test_bit(STATUS_RF_KILL_HW, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
+		test_bit(STATUS_CT_KILL, &priv->status));
 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
 		test_bit(STATUS_INIT, &priv->status));
 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
@@ -672,7 +674,6 @@ static ssize_t iwl_dbgfs_qos_read(struct
 	return ret;
 }
 
-#ifdef CONFIG_IWLWIFI_LEDS
 static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
 				  size_t count, loff_t *ppos)
 {
@@ -697,7 +698,6 @@ static ssize_t iwl_dbgfs_led_read(struct
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	return ret;
 }
-#endif
 
 static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
 				char __user *user_buf,
@@ -798,15 +798,20 @@ static ssize_t iwl_dbgfs_sleep_level_ove
 	 * valid here. However, let's not confuse them and present
 	 * IWL_POWER_INDEX_1 as "1", not "0".
 	 */
-	if (value > 0)
+	if (value == 0)
+		return -EINVAL;
+	else if (value > 0)
 		value -= 1;
 
 	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
 		return -EINVAL;
 
+	if (!iwl_is_ready_rf(priv))
+		return -EAGAIN;
+
 	priv->power_data.debug_sleep_level_override = value;
 
-	iwl_power_update_mode(priv, false);
+	iwl_power_update_mode(priv, true);
 
 	return count;
 }
@@ -861,9 +866,7 @@ DEBUGFS_READ_FILE_OPS(channels);
 DEBUGFS_READ_FILE_OPS(status);
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(qos);
-#ifdef CONFIG_IWLWIFI_LEDS
 DEBUGFS_READ_FILE_OPS(led);
-#endif
 DEBUGFS_READ_FILE_OPS(thermal_throttling);
 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
@@ -881,10 +884,14 @@ static ssize_t iwl_dbgfs_traffic_log_rea
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	char *buf;
 	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
-		(IWL_MAX_NUM_QUEUES * 32 * 8) + 400;
+		(priv->cfg->num_of_queues * 32 * 8) + 400;
 	const u8 *ptr;
 	ssize_t ret;
 
+	if (!priv->txq) {
+		IWL_ERR(priv, "txq not ready\n");
+		return -EAGAIN;
+	}
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf) {
 		IWL_ERR(priv, "Can not allocate buffer\n");
@@ -976,8 +983,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(s
 	int pos = 0;
 	int cnt;
 	int ret;
-	const size_t bufsz = sizeof(char) * 60 * IWL_MAX_NUM_QUEUES;
+	const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues;
 
+	if (!priv->txq) {
+		IWL_ERR(priv, "txq not ready\n");
+		return -EAGAIN;
+	}
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -1028,10 +1039,6 @@ static ssize_t iwl_dbgfs_rx_queue_read(s
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
-#define UCODE_STATISTICS_CLEAR_MSK		(0x1 << 0)
-#define UCODE_STATISTICS_FREQUENCY_MSK		(0x1 << 1)
-#define UCODE_STATISTICS_NARROW_BAND_MSK	(0x1 << 2)
-
 static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
 				     int bufsz)
 {
@@ -1068,17 +1075,17 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_
 		sizeof(struct statistics_rx_non_phy) * 20 +
 		sizeof(struct statistics_rx_ht_phy) * 20 + 400;
 	ssize_t ret;
-	struct statistics_rx_phy *ofdm;
-	struct statistics_rx_phy *cck;
-	struct statistics_rx_non_phy *general;
-	struct statistics_rx_ht_phy *ht;
+	struct statistics_rx_phy *ofdm, *accum_ofdm;
+	struct statistics_rx_phy *cck, *accum_cck;
+	struct statistics_rx_non_phy *general, *accum_general;
+	struct statistics_rx_ht_phy *ht, *accum_ht;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	/* make request to uCode to retrieve statistics information */
 	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, 0);
+	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
 	mutex_unlock(&priv->mutex);
 
 	if (ret) {
@@ -1100,155 +1107,268 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_
 	cck = &priv->statistics.rx.cck;
 	general = &priv->statistics.rx.general;
 	ht = &priv->statistics.rx.ofdm_ht;
+	accum_ofdm = &priv->accum_statistics.rx.ofdm;
+	accum_cck = &priv->accum_statistics.rx.cck;
+	accum_general = &priv->accum_statistics.rx.general;
+	accum_ht = &priv->accum_statistics.rx.ofdm_ht;
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n",
-			 le32_to_cpu(ofdm->ina_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n",
-			 le32_to_cpu(ofdm->fina_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
-			 le32_to_cpu(ofdm->plcp_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
-			 le32_to_cpu(ofdm->crc32_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
-			 le32_to_cpu(ofdm->overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
-			 le32_to_cpu(ofdm->early_overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
-			 le32_to_cpu(ofdm->crc32_good));
-	pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n",
-			 le32_to_cpu(ofdm->false_alarm_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n",
-			 le32_to_cpu(ofdm->fina_sync_err_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n",
-			 le32_to_cpu(ofdm->sfd_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n",
-			 le32_to_cpu(ofdm->fina_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n",
-			 le32_to_cpu(ofdm->unresponded_rts));
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"rxe_frame_limit_overrun: %u\n",
-			le32_to_cpu(ofdm->rxe_frame_limit_overrun));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n",
-			 le32_to_cpu(ofdm->sent_ack_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n",
-			 le32_to_cpu(ofdm->sent_cts_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n",
-			 le32_to_cpu(ofdm->sent_ba_rsp_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n",
-			 le32_to_cpu(ofdm->dsp_self_kill));
-	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
-			 le32_to_cpu(ofdm->mh_format_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n",
-			 le32_to_cpu(ofdm->re_acq_main_rssi_sum));
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "overrun_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->overrun_err),
+			 accum_ofdm->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "early_overrun_err:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->early_overrun_err),
+			 accum_ofdm->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->crc32_good),
+			 accum_ofdm->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "false_alarm_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->false_alarm_cnt),
+			 accum_ofdm->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->fina_sync_err_cnt),
+			 accum_ofdm->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sfd_timeout:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->sfd_timeout),
+			 accum_ofdm->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "fina_timeout:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->fina_timeout),
+			 accum_ofdm->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "unresponded_rts:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->unresponded_rts),
+			 accum_ofdm->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+			 accum_ofdm->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->sent_ack_cnt),
+			 accum_ofdm->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->sent_cts_cnt),
+			 accum_ofdm->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+			 accum_ofdm->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->dsp_self_kill),
+			 accum_ofdm->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->mh_format_err),
+			 accum_ofdm->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
+			 accum_ofdm->re_acq_main_rssi_sum);
 
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n",
-			 le32_to_cpu(cck->ina_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n",
-			 le32_to_cpu(cck->fina_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
-			 le32_to_cpu(cck->plcp_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
-			 le32_to_cpu(cck->crc32_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
-			 le32_to_cpu(cck->overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
-			 le32_to_cpu(cck->early_overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
-			 le32_to_cpu(cck->crc32_good));
-	pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n",
-			 le32_to_cpu(cck->false_alarm_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n",
-			 le32_to_cpu(cck->fina_sync_err_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n",
-			 le32_to_cpu(cck->sfd_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n",
-			 le32_to_cpu(cck->fina_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n",
-			 le32_to_cpu(cck->unresponded_rts));
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"rxe_frame_limit_overrun: %u\n",
-			le32_to_cpu(cck->rxe_frame_limit_overrun));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n",
-			 le32_to_cpu(cck->sent_ack_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n",
-			 le32_to_cpu(cck->sent_cts_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n",
-			 le32_to_cpu(cck->sent_ba_rsp_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n",
-			 le32_to_cpu(cck->dsp_self_kill));
-	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
-			 le32_to_cpu(cck->mh_format_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n",
-			 le32_to_cpu(cck->re_acq_main_rssi_sum));
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "overrun_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->overrun_err),
+			 accum_cck->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "early_overrun_err:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->early_overrun_err),
+			 accum_cck->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "false_alarm_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->false_alarm_cnt),
+			 accum_cck->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->fina_sync_err_cnt),
+			 accum_cck->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sfd_timeout:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->sfd_timeout),
+			 accum_cck->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "fina_timeout:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->fina_timeout),
+			 accum_cck->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "unresponded_rts:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->unresponded_rts),
+			 accum_cck->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->rxe_frame_limit_overrun),
+			 accum_cck->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->sent_ack_cnt),
+			 accum_cck->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->sent_cts_cnt),
+			 accum_cck->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->sent_ba_rsp_cnt),
+			 accum_cck->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->dsp_self_kill),
+			 accum_cck->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->mh_format_err),
+			 accum_cck->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
+			 le32_to_cpu(cck->re_acq_main_rssi_sum),
+			 accum_cck->re_acq_main_rssi_sum);
 
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts: %u\n",
-			 le32_to_cpu(general->bogus_cts));
-	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack: %u\n",
-			 le32_to_cpu(general->bogus_ack));
-	pos += scnprintf(buf + pos, bufsz - pos, "non_bssid_frames: %u\n",
-			 le32_to_cpu(general->non_bssid_frames));
-	pos += scnprintf(buf + pos, bufsz - pos, "filtered_frames: %u\n",
-			 le32_to_cpu(general->filtered_frames));
-	pos += scnprintf(buf + pos, bufsz - pos, "non_channel_beacons: %u\n",
-			 le32_to_cpu(general->non_channel_beacons));
-	pos += scnprintf(buf + pos, bufsz - pos, "channel_beacons: %u\n",
-			 le32_to_cpu(general->channel_beacons));
-	pos += scnprintf(buf + pos, bufsz - pos, "num_missed_bcon: %u\n",
-			 le32_to_cpu(general->num_missed_bcon));
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"adc_rx_saturation_time: %u\n",
-			le32_to_cpu(general->adc_rx_saturation_time));
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->bogus_cts),
+			 accum_general->bogus_cts);
+	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->bogus_ack),
+			 accum_general->bogus_ack);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"ina_detection_search_time: %u\n",
-			le32_to_cpu(general->ina_detection_search_time));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_a: %u\n",
-			 le32_to_cpu(general->beacon_silence_rssi_a));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_b: %u\n",
-			 le32_to_cpu(general->beacon_silence_rssi_b));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_c: %u\n",
-			 le32_to_cpu(general->beacon_silence_rssi_c));
+			 "non_bssid_frames:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->non_bssid_frames),
+			 accum_general->non_bssid_frames);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"interference_data_flag: %u\n",
-			le32_to_cpu(general->interference_data_flag));
-	pos += scnprintf(buf + pos, bufsz - pos, "channel_load: %u\n",
-			 le32_to_cpu(general->channel_load));
-	pos += scnprintf(buf + pos, bufsz - pos, "dsp_false_alarms: %u\n",
-			 le32_to_cpu(general->dsp_false_alarms));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_a: %u\n",
-			 le32_to_cpu(general->beacon_rssi_a));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_b: %u\n",
-			 le32_to_cpu(general->beacon_rssi_b));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_c: %u\n",
-			 le32_to_cpu(general->beacon_rssi_c));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_a: %u\n",
-			 le32_to_cpu(general->beacon_energy_a));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_b: %u\n",
-			 le32_to_cpu(general->beacon_energy_b));
-	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_c: %u\n",
-			 le32_to_cpu(general->beacon_energy_c));
+			 "filtered_frames:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->filtered_frames),
+			 accum_general->filtered_frames);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "non_channel_beacons:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->non_channel_beacons),
+			 accum_general->non_channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "channel_beacons:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->channel_beacons),
+			 accum_general->channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "num_missed_bcon:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->num_missed_bcon),
+			 accum_general->num_missed_bcon);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"adc_rx_saturation_time:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->adc_rx_saturation_time),
+			 accum_general->adc_rx_saturation_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"ina_detect_search_tm:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->ina_detection_search_time),
+			 accum_general->ina_detection_search_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_silence_rssi_a:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_a),
+			 accum_general->beacon_silence_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_silence_rssi_b:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_b),
+			 accum_general->beacon_silence_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_silence_rssi_c:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_c),
+			 accum_general->beacon_silence_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"interference_data_flag:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->interference_data_flag),
+			 accum_general->interference_data_flag);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "channel_load:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->channel_load),
+			 accum_general->channel_load);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "dsp_false_alarms:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->dsp_false_alarms),
+			 accum_general->dsp_false_alarms);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_rssi_a:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_rssi_a),
+			 accum_general->beacon_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_rssi_b:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_rssi_b),
+			 accum_general->beacon_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_rssi_c:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_rssi_c),
+			 accum_general->beacon_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_energy_a:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_energy_a),
+			 accum_general->beacon_energy_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_energy_b:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_energy_b),
+			 accum_general->beacon_energy_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "beacon_energy_c:\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->beacon_energy_c),
+			 accum_general->beacon_energy_c);
 
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
-			 le32_to_cpu(ht->plcp_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
-			 le32_to_cpu(ht->overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
-			 le32_to_cpu(ht->early_overrun_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
-			 le32_to_cpu(ht->crc32_good));
-	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
-			 le32_to_cpu(ht->crc32_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
-			 le32_to_cpu(ht->mh_format_err));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg_crc32_good: %u\n",
-			 le32_to_cpu(ht->agg_crc32_good));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg_mpdu_cnt: %u\n",
-			 le32_to_cpu(ht->agg_mpdu_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt: %u\n",
-			 le32_to_cpu(ht->agg_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "overrun_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "early_overrun_err:\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->early_overrun_err),
+			 accum_ht->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "mh_format_err:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->mh_format_err),
+			 accum_ht->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg_crc32_good:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->agg_crc32_good),
+			 accum_ht->agg_crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->agg_mpdu_cnt),
+			 accum_ht->agg_mpdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
@@ -1264,14 +1384,14 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_
 	char *buf;
 	int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
 	ssize_t ret;
-	struct statistics_tx *tx;
+	struct statistics_tx *tx, *accum_tx;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	/* make request to uCode to retrieve statistics information */
 	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, 0);
+	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
 	mutex_unlock(&priv->mutex);
 
 	if (ret) {
@@ -1290,62 +1410,107 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_
 	 * might not reflect the current uCode activity
 	 */
 	tx = &priv->statistics.tx;
+	accum_tx = &priv->accum_statistics.tx;
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "preamble: %u\n",
-			 le32_to_cpu(tx->preamble_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "rx_detected_cnt: %u\n",
-			 le32_to_cpu(tx->rx_detected_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_defer_cnt: %u\n",
-			 le32_to_cpu(tx->bt_prio_defer_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_kill_cnt: %u\n",
-			 le32_to_cpu(tx->bt_prio_kill_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "few_bytes_cnt: %u\n",
-			 le32_to_cpu(tx->few_bytes_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout: %u\n",
-			 le32_to_cpu(tx->cts_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "ack_timeout: %u\n",
-			 le32_to_cpu(tx->ack_timeout));
-	pos += scnprintf(buf + pos, bufsz - pos, "expected_ack_cnt: %u\n",
-			 le32_to_cpu(tx->expected_ack_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "actual_ack_cnt: %u\n",
-			 le32_to_cpu(tx->actual_ack_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "dump_msdu_cnt: %u\n",
-			 le32_to_cpu(tx->dump_msdu_cnt));
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"burst_abort_next_frame_mismatch_cnt: %u\n",
-			le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt));
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->preamble_cnt),
+			 accum_tx->preamble_cnt);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"burst_abort_missing_next_frame_cnt: %u\n",
-			le32_to_cpu(tx->burst_abort_missing_next_frame_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout_collision: %u\n",
-			 le32_to_cpu(tx->cts_timeout_collision));
+			 "rx_detected_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->rx_detected_cnt),
+			 accum_tx->rx_detected_cnt);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"ack_or_ba_timeout_collision: %u\n",
-			le32_to_cpu(tx->ack_or_ba_timeout_collision));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg ba_timeout: %u\n",
-			 le32_to_cpu(tx->agg.ba_timeout));
+			 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->bt_prio_defer_cnt),
+			 accum_tx->bt_prio_defer_cnt);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg ba_reschedule_frames: %u\n",
-			le32_to_cpu(tx->agg.ba_reschedule_frames));
+			 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->bt_prio_kill_cnt),
+			 accum_tx->bt_prio_kill_cnt);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg scd_query_agg_frame_cnt: %u\n",
-			le32_to_cpu(tx->agg.scd_query_agg_frame_cnt));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_no_agg: %u\n",
-			 le32_to_cpu(tx->agg.scd_query_no_agg));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_agg: %u\n",
-			 le32_to_cpu(tx->agg.scd_query_agg));
+			 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->few_bytes_cnt),
+			 accum_tx->few_bytes_cnt);
 	pos += scnprintf(buf + pos, bufsz - pos,
-			"agg scd_query_mismatch: %u\n",
-			le32_to_cpu(tx->agg.scd_query_mismatch));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg frame_not_ready: %u\n",
-			 le32_to_cpu(tx->agg.frame_not_ready));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg underrun: %u\n",
-			 le32_to_cpu(tx->agg.underrun));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg bt_prio_kill: %u\n",
-			 le32_to_cpu(tx->agg.bt_prio_kill));
-	pos += scnprintf(buf + pos, bufsz - pos, "agg rx_ba_rsp_cnt: %u\n",
-			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt));
+			 "cts_timeout:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "ack_timeout:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->ack_timeout),
+			 accum_tx->ack_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "expected_ack_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->expected_ack_cnt),
+			 accum_tx->expected_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->actual_ack_cnt),
+			 accum_tx->actual_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->dump_msdu_cnt),
+			 accum_tx->dump_msdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "abort_nxt_frame_mismatch:"
+			 "\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+			 accum_tx->burst_abort_next_frame_mismatch_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "abort_missing_nxt_frame:"
+			 "\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+			 accum_tx->burst_abort_missing_next_frame_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "cts_timeout_collision:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->cts_timeout_collision),
+			 accum_tx->cts_timeout_collision);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"ack_ba_timeout_collision:\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
+			 accum_tx->ack_or_ba_timeout_collision);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg ba_timeout:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.ba_timeout),
+			 accum_tx->agg.ba_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg ba_resched_frames:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.ba_reschedule_frames),
+			 accum_tx->agg.ba_reschedule_frames);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg scd_query_agg_frame:\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+			 accum_tx->agg.scd_query_agg_frame_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.scd_query_no_agg),
+			 accum_tx->agg.scd_query_no_agg);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg scd_query_agg:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.scd_query_agg),
+			 accum_tx->agg.scd_query_agg);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg scd_query_mismatch:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.scd_query_mismatch),
+			 accum_tx->agg.scd_query_mismatch);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg frame_not_ready:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.frame_not_ready),
+			 accum_tx->agg.frame_not_ready);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg underrun:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.underrun),
+			 accum_tx->agg.underrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg bt_prio_kill:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.bt_prio_kill),
+			 accum_tx->agg.bt_prio_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
+			 accum_tx->agg.rx_ba_rsp_cnt);
 
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
@@ -1361,16 +1526,16 @@ static ssize_t iwl_dbgfs_ucode_general_s
 	char *buf;
 	int bufsz = sizeof(struct statistics_general) * 4 + 250;
 	ssize_t ret;
-	struct statistics_general *general;
-	struct statistics_dbg *dbg;
-	struct statistics_div *div;
+	struct statistics_general *general, *accum_general;
+	struct statistics_dbg *dbg, *accum_dbg;
+	struct statistics_div *div, *accum_div;
 
 	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	/* make request to uCode to retrieve statistics information */
 	mutex_lock(&priv->mutex);
-	ret = iwl_send_statistics_request(priv, 0);
+	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
 	mutex_unlock(&priv->mutex);
 
 	if (ret) {
@@ -1391,34 +1556,53 @@ static ssize_t iwl_dbgfs_ucode_general_s
 	general = &priv->statistics.general;
 	dbg = &priv->statistics.general.dbg;
 	div = &priv->statistics.general.div;
+	accum_general = &priv->accum_statistics.general;
+	accum_dbg = &priv->accum_statistics.general.dbg;
+	accum_div = &priv->accum_statistics.general.div;
 	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
 	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "temperature: %u\n",
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n",
 			 le32_to_cpu(general->temperature));
-	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m: %u\n",
+	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n",
 			 le32_to_cpu(general->temperature_m));
-	pos += scnprintf(buf + pos, bufsz - pos, "burst_check: %u\n",
-			 le32_to_cpu(dbg->burst_check));
-	pos += scnprintf(buf + pos, bufsz - pos, "burst_count: %u\n",
-			 le32_to_cpu(dbg->burst_count));
-	pos += scnprintf(buf + pos, bufsz - pos, "sleep_time: %u\n",
-			 le32_to_cpu(general->sleep_time));
-	pos += scnprintf(buf + pos, bufsz - pos, "slots_out: %u\n",
-			 le32_to_cpu(general->slots_out));
-	pos += scnprintf(buf + pos, bufsz - pos, "slots_idle: %u\n",
-			 le32_to_cpu(general->slots_idle));
-	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp: %u\n",
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "burst_check:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(dbg->burst_check),
+			 accum_dbg->burst_check);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "burst_count:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(dbg->burst_count),
+			 accum_dbg->burst_count);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "sleep_time:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->sleep_time),
+			 accum_general->sleep_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "slots_out:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->slots_out),
+			 accum_general->slots_out);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "slots_idle:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->slots_idle),
+			 accum_general->slots_idle);
+	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
 			 le32_to_cpu(general->ttl_timestamp));
-	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a: %u\n",
-			 le32_to_cpu(div->tx_on_a));
-	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b: %u\n",
-			 le32_to_cpu(div->tx_on_b));
-	pos += scnprintf(buf + pos, bufsz - pos, "exec_time: %u\n",
-			 le32_to_cpu(div->exec_time));
-	pos += scnprintf(buf + pos, bufsz - pos, "probe_time: %u\n",
-			 le32_to_cpu(div->probe_time));
-	pos += scnprintf(buf + pos, bufsz - pos, "rx_enable_counter: %u\n",
-			 le32_to_cpu(general->rx_enable_counter));
+	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a);
+	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "exec_time:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(div->exec_time), accum_div->exec_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "probe_time:\t\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(div->probe_time), accum_div->probe_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "rx_enable_counter:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(general->rx_enable_counter),
+			 accum_general->rx_enable_counter);
 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	kfree(buf);
 	return ret;
@@ -1579,7 +1763,7 @@ static ssize_t iwl_dbgfs_tx_power_read(s
 	else {
 		/* make request to uCode to retrieve statistics information */
 		mutex_lock(&priv->mutex);
-		ret = iwl_send_statistics_request(priv, 0);
+		ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
 		mutex_unlock(&priv->mutex);
 
 		if (ret) {
@@ -1614,8 +1798,55 @@ static ssize_t iwl_dbgfs_tx_power_read(s
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
-DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
-DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
+static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
+						    char __user *user_buf,
+						    size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	char buf[60];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+	u32 pwrsave_status;
+
+	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
+			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
+	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
+		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
+		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
+		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
+		"error");
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int clear;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &clear) != 1)
+		return -EFAULT;
+
+	/* make request to uCode to retrieve statistics information */
+	mutex_lock(&priv->mutex);
+	iwl_send_statistics_request(priv, CMD_SYNC, true);
+	mutex_unlock(&priv->mutex);
+
+	return count;
+}
+
+DEBUGFS_READ_FILE_OPS(rx_statistics);
+DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_READ_FILE_OPS(tx_queue);
@@ -1625,6 +1856,9 @@ DEBUGFS_READ_FILE_OPS(ucode_general_stat
 DEBUGFS_READ_FILE_OPS(sensitivity);
 DEBUGFS_READ_FILE_OPS(chain_noise);
 DEBUGFS_READ_FILE_OPS(tx_power);
+DEBUGFS_READ_FILE_OPS(power_save_status);
+DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
+DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
 
 /*
  * Create the debugfs files and directories
@@ -1653,33 +1887,34 @@ int iwl_dbgfs_register(struct iwl_priv *
 	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
 	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
 	DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
-	DEBUGFS_ADD_FILE(nvm, data);
-	DEBUGFS_ADD_FILE(sram, data);
-	DEBUGFS_ADD_FILE(log_event, data);
-	DEBUGFS_ADD_FILE(stations, data);
-	DEBUGFS_ADD_FILE(channels, data);
-	DEBUGFS_ADD_FILE(status, data);
-	DEBUGFS_ADD_FILE(interrupt, data);
-	DEBUGFS_ADD_FILE(qos, data);
-#ifdef CONFIG_IWLWIFI_LEDS
-	DEBUGFS_ADD_FILE(led, data);
-#endif
-	DEBUGFS_ADD_FILE(sleep_level_override, data);
-	DEBUGFS_ADD_FILE(current_sleep_command, data);
-	DEBUGFS_ADD_FILE(thermal_throttling, data);
-	DEBUGFS_ADD_FILE(disable_ht40, data);
-	DEBUGFS_ADD_FILE(rx_statistics, debug);
-	DEBUGFS_ADD_FILE(tx_statistics, debug);
-	DEBUGFS_ADD_FILE(traffic_log, debug);
-	DEBUGFS_ADD_FILE(rx_queue, debug);
-	DEBUGFS_ADD_FILE(tx_queue, debug);
-	DEBUGFS_ADD_FILE(tx_power, debug);
+	DEBUGFS_ADD_FILE(nvm, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(log_event, data, S_IWUSR);
+	DEBUGFS_ADD_FILE(stations, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(channels, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(status, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(qos, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(led, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR);
+	DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR);
+	DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR);
+	DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR);
+	DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR);
 	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
-		DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
-		DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
-		DEBUGFS_ADD_FILE(ucode_general_stats, debug);
-		DEBUGFS_ADD_FILE(sensitivity, debug);
-		DEBUGFS_ADD_FILE(chain_noise, debug);
+		DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR);
+		DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR);
 	}
 	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
 	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
@@ -1716,9 +1951,7 @@ void iwl_dbgfs_unregister(struct iwl_pri
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
-#ifdef CONFIG_IWLWIFI_LEDS
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
-#endif
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
 	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
@@ -1728,6 +1961,11 @@ void iwl_dbgfs_unregister(struct iwl_pri
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_clear_ucode_statistics);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_clear_traffic_statistics);
 	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
 		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
 			file_ucode_rx_stats);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2010-02-24 13:52:17.000000000 -0500
@@ -84,9 +84,7 @@ struct iwl_debugfs {
 		struct dentry *file_interrupt;
 		struct dentry *file_qos;
 		struct dentry *file_thermal_throttling;
-#ifdef CONFIG_IWLWIFI_LEDS
 		struct dentry *file_led;
-#endif
 		struct dentry *file_disable_ht40;
 		struct dentry *file_sleep_level_override;
 		struct dentry *file_current_sleep_command;
@@ -108,6 +106,9 @@ struct iwl_debugfs {
 		struct dentry *file_sensitivity;
 		struct dentry *file_chain_noise;
 		struct dentry *file_tx_power;
+		struct dentry *file_power_save_status;
+		struct dentry *file_clear_ucode_statistics;
+		struct dentry *file_clear_traffic_statistics;
 	} dbgfs_debug_files;
 	u32 sram_offset;
 	u32 sram_len;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2010-02-24 13:52:17.000000000 -0500
@@ -43,7 +43,6 @@
 #include "iwl-debug.h"
 #include "iwl-4965-hw.h"
 #include "iwl-3945-hw.h"
-#include "iwl-3945-led.h"
 #include "iwl-led.h"
 #include "iwl-power.h"
 #include "iwl-agn-rs.h"
@@ -53,21 +52,23 @@ extern struct iwl_cfg iwl4965_agn_cfg;
 extern struct iwl_cfg iwl5300_agn_cfg;
 extern struct iwl_cfg iwl5100_agn_cfg;
 extern struct iwl_cfg iwl5350_agn_cfg;
-extern struct iwl_cfg iwl5100_bg_cfg;
+extern struct iwl_cfg iwl5100_bgn_cfg;
 extern struct iwl_cfg iwl5100_abg_cfg;
 extern struct iwl_cfg iwl5150_agn_cfg;
-extern struct iwl_cfg iwl6000h_2agn_cfg;
+extern struct iwl_cfg iwl5150_abg_cfg;
 extern struct iwl_cfg iwl6000i_2agn_cfg;
+extern struct iwl_cfg iwl6000i_2abg_cfg;
+extern struct iwl_cfg iwl6000i_2bg_cfg;
 extern struct iwl_cfg iwl6000_3agn_cfg;
 extern struct iwl_cfg iwl6050_2agn_cfg;
-extern struct iwl_cfg iwl6050_3agn_cfg;
+extern struct iwl_cfg iwl6050_2abg_cfg;
 extern struct iwl_cfg iwl1000_bgn_cfg;
+extern struct iwl_cfg iwl1000_bg_cfg;
 
 struct iwl_tx_queue;
 
 /* shared structures from iwl-5000.c */
 extern struct iwl_mod_params iwl50_mod_params;
-extern struct iwl_ops iwl5000_ops;
 extern struct iwl_ucode_ops iwl5000_ucode;
 extern struct iwl_lib_ops iwl5000_lib;
 extern struct iwl_hcmd_ops iwl5000_hcmd;
@@ -81,9 +82,6 @@ extern void iwl5000_rts_tx_cmd_flag(stru
 				    __le32 *tx_flags);
 extern int iwl5000_calc_rssi(struct iwl_priv *priv,
 			     struct iwl_rx_phy_res *rx_resp);
-extern int iwl5000_apm_init(struct iwl_priv *priv);
-extern void iwl5000_apm_stop(struct iwl_priv *priv);
-extern int iwl5000_apm_reset(struct iwl_priv *priv);
 extern void iwl5000_nic_config(struct iwl_priv *priv);
 extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
 extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
@@ -144,12 +142,13 @@ extern void iwl5000_temperature(struct i
 #define	DEFAULT_LONG_RETRY_LIMIT  4U
 
 struct iwl_rx_mem_buffer {
-	dma_addr_t real_dma_addr;
-	dma_addr_t aligned_dma_addr;
-	struct sk_buff *skb;
+	dma_addr_t page_dma;
+	struct page *page;
 	struct list_head list;
 };
 
+#define rxb_addr(r) page_address(r->page)
+
 /* defined below */
 struct iwl_device_cmd;
 
@@ -165,7 +164,7 @@ struct iwl_cmd_meta {
 	 */
 	void (*callback)(struct iwl_priv *priv,
 			 struct iwl_device_cmd *cmd,
-			 struct sk_buff *skb);
+			 struct iwl_rx_packet *pkt);
 
 	/* The CMD_SIZE_HUGE flag bit indicates that the command
 	 * structure is stored at the end of the shared queue memory. */
@@ -293,9 +292,6 @@ struct iwl_channel_info {
 
 	/* HT40 channel info */
 	s8 ht40_max_power_avg;	/* (dBm) regul. eeprom, normal Tx, any rate */
-	s8 ht40_curr_txpow;	/* (dBm) regulatory/spectrum/user (not h/w) */
-	s8 ht40_min_power;	/* always 0 */
-	s8 ht40_scan_power;	/* (dBm) eeprom, direct scans, any rate */
 	u8 ht40_flags;		/* flags copied from EEPROM */
 	u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
 
@@ -321,6 +317,13 @@ struct iwl_channel_info {
  * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */
 #define IWL_MIN_NUM_QUEUES	10
 
+/*
+ * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00,
+ * the driver maps it into the appropriate device FIFO for the
+ * uCode.
+ */
+#define IWL_CMD_QUEUE_NUM	4
+
 /* Power management (not Tx power) structures */
 
 enum iwl_pwr_src {
@@ -356,7 +359,14 @@ enum {
 	CMD_WANT_SKB = (1 << 2),
 };
 
-#define IWL_CMD_MAX_PAYLOAD 320
+#define DEF_CMD_PAYLOAD_SIZE 320
+
+/*
+ * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
+ * SNAP header and alignment. It should also be big enough for 802.11
+ * control frames.
+ */
+#define IWL_LINK_HDR_MAX 64
 
 /**
  * struct iwl_device_cmd
@@ -373,7 +383,8 @@ struct iwl_device_cmd {
 		u16 val16;
 		u32 val32;
 		struct iwl_tx_cmd tx;
-		u8 payload[IWL_CMD_MAX_PAYLOAD];
+		struct iwl6000_channel_switch_cmd chswitch;
+		u8 payload[DEF_CMD_PAYLOAD_SIZE];
 	} __attribute__ ((packed)) cmd;
 } __attribute__ ((packed));
 
@@ -382,21 +393,15 @@ struct iwl_device_cmd {
 
 struct iwl_host_cmd {
 	const void *data;
-	struct sk_buff *reply_skb;
+	unsigned long reply_page;
 	void (*callback)(struct iwl_priv *priv,
 			 struct iwl_device_cmd *cmd,
-			 struct sk_buff *skb);
+			 struct iwl_rx_packet *pkt);
 	u32 flags;
 	u16 len;
 	u8 id;
 };
 
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
 #define SUP_RATE_11A_MAX_NUM_CHANNELS  8
 #define SUP_RATE_11B_MAX_NUM_CHANNELS  4
 #define SUP_RATE_11G_MAX_NUM_CHANNELS  12
@@ -502,12 +507,11 @@ union iwl_ht_rate_supp {
 #define CFG_HT_MPDU_DENSITY_4USEC   (0x5)
 #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
 
-struct iwl_ht_info {
+struct iwl_ht_config {
 	/* self configuration data */
-	u8 is_ht;
-	u8 supported_chan_width;
-	u8 sm_ps;
-	struct ieee80211_mcs_info mcs;
+	bool is_ht;
+	bool is_40mhz;
+	bool single_chain_sufficient;
 	/* BSS related data */
 	u8 extension_chan_offset;
 	u8 ht_protection;
@@ -541,26 +545,27 @@ struct iwl_qos_info {
 	struct iwl_qosparam_cmd def_qos_parm;
 };
 
-#define STA_PS_STATUS_WAKE             0
-#define STA_PS_STATUS_SLEEP            1
-
-
-struct iwl3945_station_entry {
-	struct iwl3945_addsta_cmd sta;
-	struct iwl_tid_data tid[MAX_TID_COUNT];
-	u8 used;
-	u8 ps_status;
-	struct iwl_hw_key keyinfo;
-};
-
 struct iwl_station_entry {
 	struct iwl_addsta_cmd sta;
 	struct iwl_tid_data tid[MAX_TID_COUNT];
 	u8 used;
-	u8 ps_status;
 	struct iwl_hw_key keyinfo;
 };
 
+/*
+ * iwl_station_priv: Driver's private station information
+ *
+ * When mac80211 creates a station it reserves some space (hw->sta_data_size)
+ * in the structure for use by driver. This structure is places in that
+ * space.
+ */
+struct iwl_station_priv {
+	struct iwl_lq_sta lq_sta;
+	atomic_t pending_frames;
+	bool client;
+	bool asleep;
+};
+
 /* one for each uCode image (inst/data, boot/init/runtime) */
 struct fw_desc {
 	void *v_addr;		/* access by driver */
@@ -622,6 +627,10 @@ struct iwl_sensitivity_ranges {
 	u16 auto_corr_max_cck_mrc;
 	u16 auto_corr_min_cck;
 	u16 auto_corr_min_cck_mrc;
+
+	u16 barker_corr_th_min;
+	u16 barker_corr_th_min_mrc;
+	u16 nrg_th_cca;
 };
 
 
@@ -639,7 +648,7 @@ struct iwl_sensitivity_ranges {
  * @valid_tx/rx_ant: usable antennas
  * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
  * @max_rxq_log: Log-base-2 of max_rxq_size
- * @rx_buf_size: Rx buffer size
+ * @rx_page_order: Rx buffer page order
  * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
  * @max_stations:
  * @bcast_sta_id:
@@ -662,9 +671,8 @@ struct iwl_hw_params {
 	u8  valid_rx_ant;
 	u16 max_rxq_size;
 	u16 max_rxq_log;
-	u32 rx_buf_size;
+	u32 rx_page_order;
 	u32 rx_wrt_ptr_reg;
-	u32 max_pkt_size;
 	u8  max_stations;
 	u8  bcast_sta_id;
 	u8  ht40_channel;
@@ -703,7 +711,7 @@ extern void iwl_txq_ctx_stop(struct iwl_
 extern int iwl_queue_space(const struct iwl_queue *q);
 static inline int iwl_queue_used(const struct iwl_queue *q, int i)
 {
-	return q->write_ptr > q->read_ptr ?
+	return q->write_ptr >= q->read_ptr ?
 		(i >= q->read_ptr && i < q->write_ptr) :
 		!(i < q->read_ptr && i >= q->write_ptr);
 }
@@ -711,7 +719,11 @@ static inline int iwl_queue_used(const s
 
 static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
 {
-	/* This is for scan command, the big buffer at end of command array */
+	/*
+	 * This is for init calibration result and scan command which
+	 * required buffer > TFD_MAX_PAYLOAD_SIZE,
+	 * the big buffer at end of command array
+	 */
 	if (is_huge)
 		return q->n_window;	/* must be power of 2 */
 
@@ -726,9 +738,6 @@ struct iwl_dma_ptr {
 	size_t size;
 };
 
-#define IWL_CHANNEL_WIDTH_20MHZ   0
-#define IWL_CHANNEL_WIDTH_40MHZ   1
-
 #define IWL_OPERATION_MODE_AUTO     0
 #define IWL_OPERATION_MODE_HT_ONLY  1
 #define IWL_OPERATION_MODE_MIXED    2
@@ -741,7 +750,8 @@ struct iwl_dma_ptr {
 
 /* Sensitivity and chain noise calibration */
 #define INITIALIZATION_VALUE		0xFFFF
-#define CAL_NUM_OF_BEACONS		20
+#define IWL4965_CAL_NUM_BEACONS		20
+#define IWL_CAL_NUM_BEACONS		16
 #define MAXIMUM_ALLOWED_PATHLOSS	15
 
 #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3
@@ -845,6 +855,10 @@ struct iwl_sensitivity_data {
 	s32 nrg_auto_corr_silence_diff;
 	u32 num_in_cck_no_fa;
 	u32 nrg_th_ofdm;
+
+	u16 barker_corr_th_min;
+	u16 barker_corr_th_min_mrc;
+	u16 nrg_th_cca;
 };
 
 /* Chain noise (differential Rx gain) calib data */
@@ -894,13 +908,11 @@ enum iwl_access_mode {
 /**
  * enum iwl_pa_type - Power Amplifier type
  * @IWL_PA_SYSTEM:  based on uCode configuration
- * @IWL_PA_HYBRID: use both Internal and external PA
  * @IWL_PA_INTERNAL: use Internal only
  */
 enum iwl_pa_type {
 	IWL_PA_SYSTEM = 0,
-	IWL_PA_HYBRID = 1,
-	IWL_PA_INTERNAL = 2,
+	IWL_PA_INTERNAL = 1,
 };
 
 /* interrupt statistics */
@@ -961,7 +973,16 @@ struct traffic_stats {
 };
 #endif
 
-#define IWL_MAX_NUM_QUEUES	20 /* FIXME: do dynamic allocation */
+/*
+ * iwl_switch_rxon: "channel switch" structure
+ *
+ * @ switch_in_progress: channel switch in progress
+ * @ channel: new channel
+ */
+struct iwl_switch_rxon {
+	bool switch_in_progress;
+	__le16 channel;
+};
 
 struct iwl_priv {
 
@@ -976,7 +997,7 @@ struct iwl_priv {
 	int frames_count;
 
 	enum ieee80211_band band;
-	int alloc_rxb_skb;
+	int alloc_rxb_page;
 
 	void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
 				       struct iwl_rx_mem_buffer *rxb);
@@ -1056,21 +1077,18 @@ struct iwl_priv {
 	const struct iwl_rxon_cmd active_rxon;
 	struct iwl_rxon_cmd staging_rxon;
 
-	struct iwl_rxon_cmd recovery_rxon;
+	struct iwl_switch_rxon switch_rxon;
 
 	/* 1st responses from initialize and runtime uCode images.
 	 * 4965's initialize alive response contains some calibration data. */
 	struct iwl_init_alive_resp card_alive_init;
 	struct iwl_alive_resp card_alive;
 
-#ifdef CONFIG_IWLWIFI_LEDS
 	unsigned long last_blink_time;
 	u8 last_blink_rate;
 	u8 allow_blinking;
 	u64 led_tpt;
-	struct iwl_led led[IWL_LED_TRG_MAX];
-	unsigned int rxtxpackets;
-#endif
+
 	u16 active_rate;
 	u16 active_rate_basic;
 
@@ -1080,11 +1098,10 @@ struct iwl_priv {
 	struct iwl_chain_noise_data chain_noise_data;
 	__le16 sensitivity_tbl[HD_TABLE_SIZE];
 
-	struct iwl_ht_info current_ht_config;
+	struct iwl_ht_config current_ht_config;
 	u8 last_phy_res[100];
 
 	/* Rate scaling data */
-	s8 data_retry_limit;
 	u8 retry_rate;
 
 	wait_queue_head_t wait_command_queue;
@@ -1093,7 +1110,7 @@ struct iwl_priv {
 
 	/* Rx and Tx DMA processing queues */
 	struct iwl_rx_queue rxq;
-	struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
+	struct iwl_tx_queue *txq;
 	unsigned long txq_ctx_active_msk;
 	struct iwl_dma_ptr  kw;	/* keep warm address */
 	struct iwl_dma_ptr  scd_bc_tbls;
@@ -1116,7 +1133,9 @@ struct iwl_priv {
 	struct iwl_tt_mgmt thermal_throttle;
 
 	struct iwl_notif_statistics statistics;
-	unsigned long last_statistics_time;
+#ifdef CONFIG_IWLWIFI_DEBUG
+	struct iwl_notif_statistics accum_statistics;
+#endif
 
 	/* context information */
 	u16 rates_mask;
@@ -1149,7 +1168,7 @@ struct iwl_priv {
 	u32 last_beacon_time;
 	u64 last_tsf;
 
-	/* eeprom */
+	/* eeprom -- this is in the card's little endian byte order */
 	u8 *eeprom;
 	int    nvm_device_type;
 	struct iwl_eeprom_calib_info *calib_info;
@@ -1216,6 +1235,7 @@ struct iwl_priv {
 	/* TX Power */
 	s8 tx_power_user_lmt;
 	s8 tx_power_device_lmt;
+	s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */
 
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1333,4 +1353,15 @@ static inline int is_channel_ibss(const
 	return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
 }
 
+static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page)
+{
+	__free_pages(page, priv->hw_params.rx_page_order);
+	priv->alloc_rxb_page--;
+}
+
+static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page)
+{
+	free_pages(page, priv->hw_params.rx_page_order);
+	priv->alloc_rxb_page--;
+}
 #endif				/* __iwl_dev_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009 - 2010 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 LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+
+/* sparse doesn't like tracepoint macros */
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "iwl-devtrace.h"
+
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
+EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-devtrace.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009 - 2010 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 LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define __IWLWIFI_DEVICE_TRACE
+
+#include <linux/tracepoint.h>
+#include "iwl-dev.h"
+
+#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#endif
+
+#define PRIV_ENTRY	__field(struct iwl_priv *, priv)
+#define PRIV_ASSIGN	__entry->priv = priv
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM iwlwifi_io
+
+TRACE_EVENT(iwlwifi_dev_ioread32,
+	TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val),
+	TP_ARGS(priv, offs, val),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__field(u32, offs)
+		__field(u32, val)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->offs = offs;
+		__entry->val = val;
+	),
+	TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val)
+);
+
+TRACE_EVENT(iwlwifi_dev_iowrite8,
+	TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val),
+	TP_ARGS(priv, offs, val),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__field(u32, offs)
+		__field(u8, val)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->offs = offs;
+		__entry->val = val;
+	),
+	TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+);
+
+TRACE_EVENT(iwlwifi_dev_iowrite32,
+	TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val),
+	TP_ARGS(priv, offs, val),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__field(u32, offs)
+		__field(u32, val)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->offs = offs;
+		__entry->val = val;
+	),
+	TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+);
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM iwlwifi
+
+TRACE_EVENT(iwlwifi_dev_hcmd,
+	TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags),
+	TP_ARGS(priv, hcmd, len, flags),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__dynamic_array(u8, hcmd, len)
+		__field(u32, flags)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		memcpy(__get_dynamic_array(hcmd), hcmd, len);
+		__entry->flags = flags;
+	),
+	TP_printk("[%p] hcmd %#.2x (%ssync)",
+		  __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0],
+		  __entry->flags & CMD_ASYNC ? "a" : "")
+);
+
+TRACE_EVENT(iwlwifi_dev_rx,
+	TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len),
+	TP_ARGS(priv, rxbuf, len),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__dynamic_array(u8, rxbuf, len)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		memcpy(__get_dynamic_array(rxbuf), rxbuf, len);
+	),
+	TP_printk("[%p] RX cmd %#.2x",
+		  __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4])
+);
+
+TRACE_EVENT(iwlwifi_dev_tx,
+	TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen,
+		 void *buf0, size_t buf0_len,
+		 void *buf1, size_t buf1_len),
+	TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+
+		__field(size_t, framelen)
+		__dynamic_array(u8, tfd, tfdlen)
+
+		/*
+		 * Do not insert between or below these items,
+		 * we want to keep the frame together (except
+		 * for the possible padding).
+		 */
+		__dynamic_array(u8, buf0, buf0_len)
+		__dynamic_array(u8, buf1, buf1_len)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->framelen = buf0_len + buf1_len;
+		memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
+		memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
+		memcpy(__get_dynamic_array(buf1), buf1, buf0_len);
+	),
+	TP_printk("[%p] TX %.2x (%zu bytes)",
+		  __entry->priv,
+		  ((u8 *)__get_dynamic_array(buf0))[0],
+		  __entry->framelen)
+);
+
+TRACE_EVENT(iwlwifi_dev_ucode_error,
+	TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time,
+		 u32 data1, u32 data2, u32 line, u32 blink1,
+		 u32 blink2, u32 ilink1, u32 ilink2),
+	TP_ARGS(priv, desc, time, data1, data2, line,
+		blink1, blink2, ilink1, ilink2),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+		__field(u32, desc)
+		__field(u32, time)
+		__field(u32, data1)
+		__field(u32, data2)
+		__field(u32, line)
+		__field(u32, blink1)
+		__field(u32, blink2)
+		__field(u32, ilink1)
+		__field(u32, ilink2)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->desc = desc;
+		__entry->time = time;
+		__entry->data1 = data1;
+		__entry->data2 = data2;
+		__entry->line = line;
+		__entry->blink1 = blink1;
+		__entry->blink2 = blink2;
+		__entry->ilink1 = ilink1;
+		__entry->ilink2 = ilink2;
+	),
+	TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, "
+		  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X",
+		  __entry->priv, __entry->desc, __entry->time, __entry->data1,
+		  __entry->data2, __entry->line, __entry->blink1,
+		  __entry->blink2, __entry->ilink1, __entry->ilink2)
+);
+
+TRACE_EVENT(iwlwifi_dev_ucode_event,
+	TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
+	TP_ARGS(priv, time, data, ev),
+	TP_STRUCT__entry(
+		PRIV_ENTRY
+
+		__field(u32, time)
+		__field(u32, data)
+		__field(u32, ev)
+	),
+	TP_fast_assign(
+		PRIV_ASSIGN;
+		__entry->time = time;
+		__entry->data = data;
+		__entry->ev = ev;
+	),
+	TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
+		  __entry->priv, __entry->time, __entry->data, __entry->ev)
+);
+#endif /* __IWLWIFI_DEVICE_TRACE */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE iwl-devtrace
+#include <trace/define_trace.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -215,12 +215,35 @@ static const struct iwl_txpwr_section en
 
 int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 {
-	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
-	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
-		return -ENOENT;
+	u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
+	int ret = 0;
+
+	IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp);
+	switch (gp) {
+	case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
+		if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
+			IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n",
+				gp);
+			ret = -ENOENT;
+		}
+		break;
+	case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K:
+	case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K:
+		if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) {
+			IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp);
+			ret = -ENOENT;
+		}
+		break;
+	case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP:
+	default:
+		IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, "
+			"EEPROM_GP=0x%08x\n",
+			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+			? "OTP" : "EEPROM", gp);
+		ret = -ENOENT;
+		break;
 	}
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
 
@@ -283,7 +306,8 @@ int iwlcore_eeprom_acquire_semaphore(str
 			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 
 		/* See if we got it */
-		ret = iwl_poll_direct_bit(priv, CSR_HW_IF_CONFIG_REG,
+		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
 				EEPROM_SEM_TIMEOUT);
 		if (ret >= 0) {
@@ -322,7 +346,8 @@ static int iwl_init_otp_access(struct iw
 		     CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
 	/* wait for clock to be ready */
-	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+				  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 				  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 				  25000);
 	if (ret < 0)
@@ -333,11 +358,19 @@ static int iwl_init_otp_access(struct iw
 		udelay(5);
 		iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
 				    APMG_PS_CTRL_VAL_RESET_REQ);
+
+		/*
+		 * CSR auto clock gate disable bit -
+		 * this is only applicable for HW with OTP shadow RAM
+		 */
+		if (priv->cfg->shadow_ram_support)
+			iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG,
+				CSR_RESET_LINK_PWR_MGMT_DISABLED);
 	}
 	return ret;
 }
 
-static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
+static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data)
 {
 	int ret = 0;
 	u32 r;
@@ -345,7 +378,8 @@ static int iwl_read_otp_word(struct iwl_
 
 	_iwl_write32(priv, CSR_EEPROM_REG,
 		     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-	ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+	ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
+				  CSR_EEPROM_REG_READ_VALID_MSK,
 				  CSR_EEPROM_REG_READ_VALID_MSK,
 				  IWL_EEPROM_ACCESS_TIMEOUT);
 	if (ret < 0) {
@@ -370,7 +404,7 @@ static int iwl_read_otp_word(struct iwl_
 				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
 		IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
 	}
-	*eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
+	*eeprom_data = cpu_to_le16(r >> 16);
 	return 0;
 }
 
@@ -379,7 +413,8 @@ static int iwl_read_otp_word(struct iwl_
  */
 static bool iwl_is_otp_empty(struct iwl_priv *priv)
 {
-	u16 next_link_addr = 0, link_value;
+	u16 next_link_addr = 0;
+	__le16 link_value;
 	bool is_empty = false;
 
 	/* locate the beginning of OTP link list */
@@ -409,7 +444,8 @@ static bool iwl_is_otp_empty(struct iwl_
 static int iwl_find_otp_image(struct iwl_priv *priv,
 					u16 *validblockaddr)
 {
-	u16 next_link_addr = 0, link_value = 0, valid_addr;
+	u16 next_link_addr = 0, valid_addr;
+	__le16 link_value = 0;
 	int usedblocks = 0;
 
 	/* set addressing mode to absolute to traverse the link list */
@@ -429,7 +465,7 @@ static int iwl_find_otp_image(struct iwl
 		 * check for more block on the link list
 		 */
 		valid_addr = next_link_addr;
-		next_link_addr = link_value * sizeof(u16);
+		next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
 		IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
 			       usedblocks, next_link_addr);
 		if (iwl_read_otp_word(priv, next_link_addr, &link_value))
@@ -463,7 +499,7 @@ static int iwl_find_otp_image(struct iwl
  */
 int iwl_eeprom_init(struct iwl_priv *priv)
 {
-	u16 *e;
+	__le16 *e;
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
 	int sz;
 	int ret;
@@ -482,7 +518,9 @@ int iwl_eeprom_init(struct iwl_priv *pri
 		ret = -ENOMEM;
 		goto alloc_err;
 	}
-	e = (u16 *)priv->eeprom;
+	e = (__le16 *)priv->eeprom;
+
+	priv->cfg->ops->lib->apm_ops.init(priv);
 
 	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
 	if (ret < 0) {
@@ -498,7 +536,9 @@ int iwl_eeprom_init(struct iwl_priv *pri
 		ret = -ENOENT;
 		goto err;
 	}
+
 	if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
+
 		ret = iwl_init_otp_access(priv);
 		if (ret) {
 			IWL_ERR(priv, "Failed to initialize OTP access.\n");
@@ -521,7 +561,7 @@ int iwl_eeprom_init(struct iwl_priv *pri
 		}
 		for (addr = validblockaddr; addr < validblockaddr + sz;
 		     addr += sizeof(u16)) {
-			u16 eeprom_data;
+			__le16 eeprom_data;
 
 			ret = iwl_read_otp_word(priv, addr, &eeprom_data);
 			if (ret)
@@ -537,7 +577,8 @@ int iwl_eeprom_init(struct iwl_priv *pri
 			_iwl_write32(priv, CSR_EEPROM_REG,
 				     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
 
-			ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+			ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
+						  CSR_EEPROM_REG_READ_VALID_MSK,
 						  CSR_EEPROM_REG_READ_VALID_MSK,
 						  IWL_EEPROM_ACCESS_TIMEOUT);
 			if (ret < 0) {
@@ -545,7 +586,7 @@ int iwl_eeprom_init(struct iwl_priv *pri
 				goto done;
 			}
 			r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
-			e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+			e[addr / 2] = cpu_to_le16(r >> 16);
 		}
 	}
 	ret = 0;
@@ -554,6 +595,8 @@ done:
 err:
 	if (ret)
 		iwl_eeprom_free(priv);
+	/* Reset chip to save power until we load uCode during "up". */
+	priv->cfg->ops->lib->apm_ops.stop(priv);
 alloc_err:
 	return ret;
 }
@@ -705,11 +748,9 @@ static int iwl_mod_ht40_chan_info(struct
 
 	ch_info->ht40_eeprom = *eeprom_ch;
 	ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg;
-	ch_info->ht40_curr_txpow = eeprom_ch->max_power_avg;
-	ch_info->ht40_min_power = 0;
-	ch_info->ht40_scan_power = eeprom_ch->max_power_avg;
 	ch_info->ht40_flags = eeprom_ch->flags;
-	ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
+	if (eeprom_ch->flags & EEPROM_CHANNEL_VALID)
+		ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
 
 	return 0;
 }
@@ -719,7 +760,8 @@ static int iwl_mod_ht40_chan_info(struct
  *     find the highest tx power from all chains for the channel
  */
 static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
-		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element)
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int element, s8 *max_txpower_in_half_dbm)
 {
 	s8 max_txpower_avg = 0; /* (dBm) */
 
@@ -751,10 +793,14 @@ static s8 iwl_get_max_txpower_avg(struct
 	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
 		max_txpower_avg = enhanced_txpower[element].mimo3_max;
 
-	/* max. tx power in EEPROM is in 1/2 dBm format
-	 * convert from 1/2 dBm to dBm
+	/*
+	 * max. tx power in EEPROM is in 1/2 dBm format
+	 * convert from 1/2 dBm to dBm (round-up convert)
+	 * but we also do not want to loss 1/2 dBm resolution which
+	 * will impact performance
 	 */
-	return max_txpower_avg >> 1;
+	*max_txpower_in_half_dbm = max_txpower_avg;
+	return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
 }
 
 /**
@@ -763,7 +809,7 @@ static s8 iwl_get_max_txpower_avg(struct
  */
 static s8 iwl_update_common_txpower(struct iwl_priv *priv,
 		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-		int section, int element)
+		int section, int element, s8 *max_txpower_in_half_dbm)
 {
 	struct iwl_channel_info *ch_info;
 	int ch;
@@ -777,25 +823,25 @@ static s8 iwl_update_common_txpower(stru
 	if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
 		is_ht40 = true;
 	max_txpower_avg =
-		iwl_get_max_txpower_avg(priv, enhanced_txpower, element);
+		iwl_get_max_txpower_avg(priv, enhanced_txpower,
+					element, max_txpower_in_half_dbm);
+
 	ch_info = priv->channel_info;
 
 	for (ch = 0; ch < priv->channel_count; ch++) {
 		/* find matching band and update tx power if needed */
 		if ((ch_info->band == enhinfo[section].band) &&
-		    (ch_info->max_power_avg < max_txpower_avg) && (!is_ht40)) {
+		    (ch_info->max_power_avg < max_txpower_avg) &&
+		    (!is_ht40)) {
 			/* Update regulatory-based run-time data */
 			ch_info->max_power_avg = ch_info->curr_txpow =
-			    max_txpower_avg;
+				max_txpower_avg;
 			ch_info->scan_power = max_txpower_avg;
 		}
 		if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
-		    ch_info->ht40_max_power_avg &&
 		    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
 			/* Update regulatory-based run-time data */
 			ch_info->ht40_max_power_avg = max_txpower_avg;
-			ch_info->ht40_curr_txpow = max_txpower_avg;
-			ch_info->ht40_scan_power = max_txpower_avg;
 		}
 		ch_info++;
 	}
@@ -808,7 +854,7 @@ static s8 iwl_update_common_txpower(stru
  */
 static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
 		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
-		int section, int element)
+		int section, int element, s8 *max_txpower_in_half_dbm)
 {
 	struct iwl_channel_info *ch_info;
 	int ch;
@@ -817,7 +863,8 @@ static s8 iwl_update_channel_txpower(str
 
 	channel = enhinfo[section].iwl_eeprom_section_channel[element];
 	max_txpower_avg =
-		iwl_get_max_txpower_avg(priv, enhanced_txpower, element);
+		iwl_get_max_txpower_avg(priv, enhanced_txpower,
+					element, max_txpower_in_half_dbm);
 
 	ch_info = priv->channel_info;
 	for (ch = 0; ch < priv->channel_count; ch++) {
@@ -831,12 +878,9 @@ static s8 iwl_update_channel_txpower(str
 				ch_info->scan_power = max_txpower_avg;
 			}
 			if ((enhinfo[section].is_ht40) &&
-			    (ch_info->ht40_max_power_avg) &&
 			    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
 				/* Update regulatory-based run-time data */
 				ch_info->ht40_max_power_avg = max_txpower_avg;
-				ch_info->ht40_curr_txpow = max_txpower_avg;
-				ch_info->ht40_scan_power = max_txpower_avg;
 			}
 			break;
 		}
@@ -855,6 +899,7 @@ void iwlcore_eeprom_enhanced_txpower(str
 	struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
 	u32 offset;
 	s8 max_txpower_avg; /* (dBm) */
+	s8 max_txpower_in_half_dbm; /* (half-dBm) */
 
 	/* Loop through all the sections
 	 * adjust bands and channel's max tx power
@@ -867,20 +912,43 @@ void iwlcore_eeprom_enhanced_txpower(str
 		enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
 				iwl_eeprom_query_addr(priv, offset);
 
+		/*
+		 * check for valid entry -
+		 * different version of EEPROM might contain different set
+		 * of enhanced tx power table
+		 * always check for valid entry before process
+		 * the information
+		 */
+		if (!enhanced_txpower->common || enhanced_txpower->reserved)
+			continue;
+
 		for (element = 0; element < eeprom_section_count; element++) {
 			if (enhinfo[section].is_common)
 				max_txpower_avg =
 					iwl_update_common_txpower(priv,
-					enhanced_txpower, section, element);
+						enhanced_txpower, section,
+						element,
+						&max_txpower_in_half_dbm);
 			else
 				max_txpower_avg =
 					iwl_update_channel_txpower(priv,
-					enhanced_txpower, section, element);
+						enhanced_txpower, section,
+						element,
+						&max_txpower_in_half_dbm);
 
 			/* Update the tx_power_user_lmt to the highest power
 			 * supported by any channel */
 			if (max_txpower_avg > priv->tx_power_user_lmt)
 				priv->tx_power_user_lmt = max_txpower_avg;
+
+			/*
+			 * Update the tx_power_lmt_in_half_dbm to
+			 * the highest power supported by any channel
+			 */
+			if (max_txpower_in_half_dbm >
+			    priv->tx_power_lmt_in_half_dbm)
+				priv->tx_power_lmt_in_half_dbm =
+					max_txpower_in_half_dbm;
 		}
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,6 +63,8 @@
 #ifndef __iwl_eeprom_h__
 #define __iwl_eeprom_h__
 
+#include <net/mac80211.h>
+
 struct iwl_priv;
 
 /*
@@ -125,19 +127,21 @@ struct iwl_eeprom_channel {
  *    Enhanced regulatory tx power portion of eeprom image can be broken down
  *    into individual structures; each one is 8 bytes in size and contain the
  *    following information
+ * @common: (desc + channel) not used by driver, should _NOT_ be "zero"
  * @chain_a_max_pwr: chain a max power in 1/2 dBm
  * @chain_b_max_pwr: chain b max power in 1/2 dBm
  * @chain_c_max_pwr: chain c max power in 1/2 dBm
+ * @reserved: not used, should be "zero"
  * @mimo2_max_pwr: mimo2 max power in 1/2 dBm
  * @mimo3_max_pwr: mimo3 max power in 1/2 dBm
  *
  */
 struct iwl_eeprom_enhanced_txpwr {
-	u16 reserved;
+	__le16 common;
 	s8 chain_a_max;
 	s8 chain_b_max;
 	s8 chain_c_max;
-	s8 reserved1;
+	s8 reserved;
 	s8 mimo2_max;
 	s8 mimo3_max;
 } __attribute__ ((packed));
@@ -256,6 +260,15 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_5050_TX_POWER_VERSION    (4)
 #define EEPROM_5050_EEPROM_VERSION	(0x21E)
 
+/* 1000 Specific */
+#define EEPROM_1000_EEPROM_VERSION	(0x15C)
+
+/* 6x00 Specific */
+#define EEPROM_6000_EEPROM_VERSION	(0x434)
+
+/* 6x50 Specific */
+#define EEPROM_6050_EEPROM_VERSION	(0x532)
+
 /* OTP */
 /* lower blocks contain EEPROM image and calibration data */
 #define OTP_LOW_IMAGE_SIZE		(2 * 512 * sizeof(u16)) /* 2 KB */
@@ -347,7 +360,7 @@ struct iwl_eeprom_calib_subband_info {
 struct iwl_eeprom_calib_info {
 	u8 saturation_power24;	/* half-dBm (e.g. "34" = 17 dBm) */
 	u8 saturation_power52;	/* half-dBm */
-	s16 voltage;		/* signed */
+	__le16 voltage;		/* signed */
 	struct iwl_eeprom_calib_subband_info
 		band_info[EEPROM_TX_POWER_BANDS];
 } __attribute__ ((packed));
@@ -370,12 +383,10 @@ struct iwl_eeprom_calib_info {
 #define EEPROM_BOARD_PBA_NUMBER             (2*0x3B+1)	/* 9  bytes */
 #define EEPROM_VERSION                      (2*0x44)	/* 2  bytes */
 #define EEPROM_SKU_CAP                      (2*0x45)	/* 1  bytes */
-#define EEPROM_LEDS_MODE                    (2*0x45+1)	/* 1  bytes */
 #define EEPROM_OEM_MODE                     (2*0x46)	/* 2  bytes */
 #define EEPROM_WOWLAN_MODE                  (2*0x47)	/* 2  bytes */
 #define EEPROM_RADIO_CONFIG                 (2*0x48)	/* 2  bytes */
 #define EEPROM_3945_M_VERSION               (2*0x4A)	/* 1  bytes */
-#define EEPROM_ANTENNA_SWITCH_TYPE          (2*0x4A+1)	/* 1  bytes */
 
 /* The following masks are to be applied on EEPROM_RADIO_CONFIG */
 #define EEPROM_RF_CFG_TYPE_MSK(x)   (x & 0x3)         /* bits 0-1   */
@@ -387,7 +398,12 @@ struct iwl_eeprom_calib_info {
 
 #define EEPROM_3945_RF_CFG_TYPE_MAX  0x0
 #define EEPROM_4965_RF_CFG_TYPE_MAX  0x1
-#define EEPROM_5000_RF_CFG_TYPE_MAX  0x3
+
+/* Radio Config for 5000 and up */
+#define EEPROM_RF_CONFIG_TYPE_R3x3	0x0
+#define EEPROM_RF_CONFIG_TYPE_R2x2	0x1
+#define EEPROM_RF_CONFIG_TYPE_R1x2	0x2
+#define EEPROM_RF_CONFIG_TYPE_MAX	0x3
 
 /*
  * Per-channel regulatory data.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,6 +56,8 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(REPLY_LEDS_CMD);
 		IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
 		IWL_CMD(COEX_PRIORITY_TABLE_CMD);
+		IWL_CMD(COEX_MEDIUM_NOTIFICATION);
+		IWL_CMD(COEX_EVENT_CMD);
 		IWL_CMD(RADAR_NOTIFICATION);
 		IWL_CMD(REPLY_QUIET_CMD);
 		IWL_CMD(REPLY_CHANNEL_SWITCH);
@@ -93,6 +95,8 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(CALIBRATION_RES_NOTIFICATION);
 		IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
 		IWL_CMD(REPLY_TX_POWER_DBM_CMD);
+		IWL_CMD(TEMPERATURE_NOTIFICATION);
+		IWL_CMD(TX_ANT_CONFIGURATION_CMD);
 	default:
 		return "UNKNOWN";
 
@@ -104,17 +108,8 @@ EXPORT_SYMBOL(get_cmd_string);
 
 static void iwl_generic_cmd_callback(struct iwl_priv *priv,
 				     struct iwl_device_cmd *cmd,
-				     struct sk_buff *skb)
+				     struct iwl_rx_packet *pkt)
 {
-	struct iwl_rx_packet *pkt = NULL;
-
-	if (!skb) {
-		IWL_ERR(priv, "Error: Response NULL in %s.\n",
-				get_cmd_string(cmd->hdr.cmd));
-		return;
-	}
-
-	pkt = (struct iwl_rx_packet *)skb->data;
 	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
 			get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
@@ -205,18 +200,18 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 	}
 
 	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n",
+		IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n",
 			       get_cmd_string(cmd->id));
 		ret = -ECANCELED;
 		goto fail;
 	}
 	if (test_bit(STATUS_FW_ERROR, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
+		IWL_ERR(priv, "Command %s failed: FW Error\n",
 			       get_cmd_string(cmd->id));
 		ret = -EIO;
 		goto fail;
 	}
-	if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) {
+	if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
 		IWL_ERR(priv, "Error: Response NULL in '%s'\n",
 			  get_cmd_string(cmd->id));
 		ret = -EIO;
@@ -238,9 +233,9 @@ cancel:
 							~CMD_WANT_SKB;
 	}
 fail:
-	if (cmd->reply_skb) {
-		dev_kfree_skb_any(cmd->reply_skb);
-		cmd->reply_skb = NULL;
+	if (cmd->reply_page) {
+		iwl_free_pages(priv, cmd->reply_page);
+		cmd->reply_page = 0;
 	}
 out:
 	clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
@@ -273,7 +268,7 @@ int iwl_send_cmd_pdu_async(struct iwl_pr
 			   u8 id, u16 len, const void *data,
 			   void (*callback)(struct iwl_priv *priv,
 					    struct iwl_device_cmd *cmd,
-					    struct sk_buff *skb))
+					    struct iwl_rx_packet *pkt))
 {
 	struct iwl_host_cmd cmd = {
 		.id = id,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 
 #include "iwl-debug.h"
+#include "iwl-devtrace.h"
 
 /*
  * IO, register, and NIC memory access functions
@@ -61,7 +62,32 @@
  *
  */
 
-#define _iwl_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
+static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
+{
+	trace_iwlwifi_dev_iowrite8(priv, ofs, val);
+	iowrite8(val, priv->hw_base + ofs);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
+				 u32 ofs, u8 val)
+{
+	IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
+	_iwl_write8(priv, ofs, val);
+}
+#define iwl_write8(priv, ofs, val) \
+	__iwl_write8(__FILE__, __LINE__, priv, ofs, val)
+#else
+#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
+#endif
+
+
+static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
+{
+	trace_iwlwifi_dev_iowrite32(priv, ofs, val);
+	iowrite32(val, priv->hw_base + ofs);
+}
+
 #ifdef CONFIG_IWLWIFI_DEBUG
 static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
 				 u32 ofs, u32 val)
@@ -75,7 +101,13 @@ static inline void __iwl_write32(const c
 #define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
 #endif
 
-#define _iwl_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
+static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
+{
+	u32 val = ioread32(priv->hw_base + ofs);
+	trace_iwlwifi_dev_ioread32(priv, ofs, val);
+	return val;
+}
+
 #ifdef CONFIG_IWLWIFI_DEBUG
 static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
 {
@@ -188,6 +220,26 @@ static inline int _iwl_grab_nic_access(s
 
 	/* this bit wakes up the NIC */
 	_iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+	/*
+	 * These bits say the device is running, and should keep running for
+	 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
+	 * but they do not indicate that embedded SRAM is restored yet;
+	 * 3945 and 4965 have volatile SRAM, and must save/restore contents
+	 * to/from host DRAM when sleeping/waking for power-saving.
+	 * Each direction takes approximately 1/4 millisecond; with this
+	 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
+	 * series of register accesses are expected (e.g. reading Event Log),
+	 * to keep device from sleeping.
+	 *
+	 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
+	 * SRAM is okay/restored.  We don't check that here because this call
+	 * is just for hardware register access; but GP1 MAC_SLEEP check is a
+	 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
+	 *
+	 * 5000 series and later (including 1000 series) have non-volatile SRAM,
+	 * and do not save/restore SRAM when power cycling.
+	 */
 	ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
 			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
 			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,15 +42,11 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static const char *led_type_str[] = {
-	__stringify(IWL_LED_TRG_TX),
-	__stringify(IWL_LED_TRG_RX),
-	__stringify(IWL_LED_TRG_ASSOC),
-	__stringify(IWL_LED_TRG_RADIO),
-	NULL
-};
-#endif /* CONFIG_IWLWIFI_DEBUG */
+/* default: IWL_LED_BLINK(0) using blinking index table */
+static int led_mode;
+module_param(led_mode, int, S_IRUGO);
+MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
+			   "(default 0)\n");
 
 
 static const struct {
@@ -65,11 +61,11 @@ static const struct {
 	{70, 65, 65},
 	{50, 75, 75},
 	{20, 85, 85},
-	{15, 95, 95 },
-	{10, 110, 110},
-	{5, 130, 130},
+	{10, 95, 95},
+	{5, 110, 110},
+	{1, 130, 130},
 	{0, 167, 167},
-/* SOLID_ON */
+	/* SOLID_ON */
 	{-1, IWL_LED_SOLID, 0}
 };
 
@@ -78,191 +74,74 @@ static const struct {
 #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */
 #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
 
-/*  [0-256] -> [0..8] FIXME: we need [0..10] */
-static inline int iwl_brightness_to_idx(enum led_brightness brightness)
-{
-	return fls(0x000000FF & (u32)brightness);
-}
-
-/* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
+/*
+ * Adjust led blink rate to compensate on a MAC Clock difference on every HW
+ * Led blink rate analysis showed an average deviation of 0% on 3945,
+ * 5% on 4965 HW and 20% on 5000 series and up.
+ * Need to compensate on the led on/off time per HW according to the deviation
+ * to achieve the desired led frequency
+ * The calculation is: (100-averageDeviation)/100 * blinkTime
+ * For code efficiency the calculation will be:
+ *     compensation = (100 - averageDeviation) * 64 / 100
+ *     NewBlinkTime = (compensation * BlinkTime) / 64
+ */
+static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
+				    u8 time, u16 compensation)
 {
-	struct iwl_host_cmd cmd = {
-		.id = REPLY_LEDS_CMD,
-		.len = sizeof(struct iwl_led_cmd),
-		.data = led_cmd,
-		.flags = CMD_ASYNC,
-		.callback = NULL,
-	};
-	u32 reg;
-
-	reg = iwl_read32(priv, CSR_LED_REG);
-	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
-		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+	if (!compensation) {
+		IWL_ERR(priv, "undefined blink compensation: "
+			"use pre-defined blinking time\n");
+		return time;
+	}
 
-	return iwl_send_cmd(priv, &cmd);
+	return (u8)((time * compensation) >> 6);
 }
 
 /* Set led pattern command */
-static int iwl_led_pattern(struct iwl_priv *priv, int led_id,
-			       unsigned int idx)
+static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx)
 {
 	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
+		.id = IWL_LED_LINK,
 		.interval = IWL_DEF_LED_INTRVL
 	};
 
 	BUG_ON(idx > IWL_MAX_BLINK_TBL);
 
-	led_cmd.on = blink_tbl[idx].on_time;
-	led_cmd.off = blink_tbl[idx].off_time;
-
-	return iwl_send_led_cmd(priv, &led_cmd);
-}
-
-/* Set led register off */
-static int iwl_led_on_reg(struct iwl_priv *priv, int led_id)
-{
-	IWL_DEBUG_LED(priv, "led on %d\n", led_id);
-	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
-	return 0;
-}
-
-#if 0
-/* Set led on command */
-static int iwl_led_on(struct iwl_priv *priv, int led_id)
-{
-	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
-		.on = IWL_LED_SOLID,
-		.off = 0,
-		.interval = IWL_DEF_LED_INTRVL
-	};
-	return iwl_send_led_cmd(priv, &led_cmd);
-}
+	IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n",
+			priv->cfg->led_compensation);
+	led_cmd.on =
+		iwl_blink_compensation(priv, blink_tbl[idx].on_time,
+					priv->cfg->led_compensation);
+	led_cmd.off =
+		iwl_blink_compensation(priv, blink_tbl[idx].off_time,
+					priv->cfg->led_compensation);
 
-/* Set led off command */
-int iwl_led_off(struct iwl_priv *priv, int led_id)
-{
-	struct iwl_led_cmd led_cmd = {
-		.id = led_id,
-		.on = 0,
-		.off = 0,
-		.interval = IWL_DEF_LED_INTRVL
-	};
-	IWL_DEBUG_LED(priv, "led off %d\n", led_id);
-	return iwl_send_led_cmd(priv, &led_cmd);
+	return priv->cfg->ops->led->cmd(priv, &led_cmd);
 }
-#endif
-
 
-/* Set led register off */
-static int iwl_led_off_reg(struct iwl_priv *priv, int led_id)
+int iwl_led_start(struct iwl_priv *priv)
 {
-	IWL_DEBUG_LED(priv, "LED Reg off\n");
-	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
-	return 0;
+	return priv->cfg->ops->led->on(priv);
 }
+EXPORT_SYMBOL(iwl_led_start);
 
-/*
- * Set led register in case of disassociation according to rfkill state
- */
-static int iwl_led_associate(struct iwl_priv *priv, int led_id)
+int iwl_led_associate(struct iwl_priv *priv)
 {
 	IWL_DEBUG_LED(priv, "Associated\n");
-	priv->allow_blinking = 1;
-	return iwl_led_on_reg(priv, led_id);
-}
-static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
-{
-	priv->allow_blinking = 0;
-
-	return 0;
-}
-
-/*
- * brightness call back function for Tx/Rx LED
- */
-static int iwl_led_associated(struct iwl_priv *priv, int led_id)
-{
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
-	    !test_bit(STATUS_READY, &priv->status))
-		return 0;
-
+	if (led_mode == IWL_LED_BLINK)
+		priv->allow_blinking = 1;
+	priv->last_blink_time = jiffies;
 
-	/* start counting Tx/Rx bytes */
-	if (!priv->last_blink_time && priv->allow_blinking)
-		priv->last_blink_time = jiffies;
 	return 0;
 }
 
-/*
- * brightness call back for association and radio
- */
-static void iwl_led_brightness_set(struct led_classdev *led_cdev,
-				       enum led_brightness brightness)
-{
-	struct iwl_led *led = container_of(led_cdev, struct iwl_led, led_dev);
-	struct iwl_priv *priv = led->priv;
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-
-	IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
-			led_type_str[led->type], brightness);
-	switch (brightness) {
-	case LED_FULL:
-		if (led->led_on)
-			led->led_on(priv, IWL_LED_LINK);
-		break;
-	case LED_OFF:
-		if (led->led_off)
-			led->led_off(priv, IWL_LED_LINK);
-		break;
-	default:
-		if (led->led_pattern) {
-			int idx = iwl_brightness_to_idx(brightness);
-			led->led_pattern(priv, IWL_LED_LINK, idx);
-		}
-		break;
-	}
-}
-
-
-
-/*
- * Register led class with the system
- */
-static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
-				   enum led_type type, u8 set_led,
-				   char *trigger)
+int iwl_led_disassociate(struct iwl_priv *priv)
 {
-	struct device *device = wiphy_dev(priv->hw->wiphy);
-	int ret;
-
-	led->led_dev.name = led->name;
-	led->led_dev.brightness_set = iwl_led_brightness_set;
-	led->led_dev.default_trigger = trigger;
-
-	led->priv = priv;
-	led->type = type;
-
-	ret = led_classdev_register(device, &led->led_dev);
-	if (ret) {
-		IWL_ERR(priv, "Error: failed to register led handler.\n");
-		return ret;
-	}
-
-	led->registered = 1;
-
-	if (set_led && led->led_on)
-		led->led_on(priv, IWL_LED_LINK);
+	priv->allow_blinking = 0;
 
 	return 0;
 }
 
-
 /*
  * calculate blink rate according to last second Tx/Rx activities
  */
@@ -288,7 +167,7 @@ static int iwl_get_blink_rate(struct iwl
 		i = IWL_MAX_BLINK_TBL;
 	else
 		for (i = 0; i < IWL_MAX_BLINK_TBL; i++)
-			if (tpt  > (blink_tbl[i].tpt * IWL_1MB_RATE))
+			if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
 				break;
 
 	IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
@@ -317,8 +196,7 @@ void iwl_leds_background(struct iwl_priv
 		priv->last_blink_time = 0;
 		if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
 			priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
-			iwl_led_pattern(priv, IWL_LED_LINK,
-					    IWL_SOLID_BLINK_IDX);
+			iwl_led_pattern(priv, IWL_SOLID_BLINK_IDX);
 		}
 		return;
 	}
@@ -331,111 +209,17 @@ void iwl_leds_background(struct iwl_priv
 
 	/* call only if blink rate change */
 	if (blink_idx != priv->last_blink_rate)
-		iwl_led_pattern(priv, IWL_LED_LINK, blink_idx);
+		iwl_led_pattern(priv, blink_idx);
 
 	priv->last_blink_time = jiffies;
 	priv->last_blink_rate = blink_idx;
 }
+EXPORT_SYMBOL(iwl_leds_background);
 
-/* Register all led handler */
-int iwl_leds_register(struct iwl_priv *priv)
+void iwl_leds_init(struct iwl_priv *priv)
 {
-	char *trigger;
-	int ret;
-
 	priv->last_blink_rate = 0;
-	priv->led_tpt = 0;
 	priv->last_blink_time = 0;
 	priv->allow_blinking = 0;
-
-	trigger = ieee80211_get_radio_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
-		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
-		 wiphy_name(priv->hw->wiphy));
-
-	priv->led[IWL_LED_TRG_RADIO].led_on = iwl_led_on_reg;
-	priv->led[IWL_LED_TRG_RADIO].led_off = iwl_led_off_reg;
-	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
-
-	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
-				   IWL_LED_TRG_RADIO, 1, trigger);
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_assoc_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
-		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
-				   IWL_LED_TRG_ASSOC, 0, trigger);
-
-	/* for assoc always turn led on */
-	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
-	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
-	priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
-
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_rx_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_RX].name,
-		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
-				   IWL_LED_TRG_RX, 0, trigger);
-
-	priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
-	priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
-	priv->led[IWL_LED_TRG_RX].led_pattern = iwl_led_pattern;
-
-	if (ret)
-		goto exit_fail;
-
-	trigger = ieee80211_get_tx_led_name(priv->hw);
-	snprintf(priv->led[IWL_LED_TRG_TX].name,
-		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
-		 wiphy_name(priv->hw->wiphy));
-
-	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
-				   IWL_LED_TRG_TX, 0, trigger);
-
-	priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
-	priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
-	priv->led[IWL_LED_TRG_TX].led_pattern = iwl_led_pattern;
-
-	if (ret)
-		goto exit_fail;
-
-	return 0;
-
-exit_fail:
-	iwl_leds_unregister(priv);
-	return ret;
-}
-EXPORT_SYMBOL(iwl_leds_register);
-
-/* unregister led class */
-static void iwl_leds_unregister_led(struct iwl_led *led, u8 set_led)
-{
-	if (!led->registered)
-		return;
-
-	led_classdev_unregister(&led->led_dev);
-
-	if (set_led)
-		led->led_dev.brightness_set(&led->led_dev, LED_OFF);
-	led->registered = 0;
-}
-
-/* Unregister all led handlers */
-void iwl_leds_unregister(struct iwl_priv *priv)
-{
-	iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
-	iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
-	iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
-	iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
 }
-EXPORT_SYMBOL(iwl_leds_unregister);
-
+EXPORT_SYMBOL(iwl_leds_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,9 +30,6 @@
 
 struct iwl_priv;
 
-#ifdef CONFIG_IWLWIFI_LEDS
-#include <linux/leds.h>
-
 #define IWL_LED_SOLID 11
 #define IWL_LED_NAME_LEN 31
 #define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
@@ -47,38 +44,23 @@ enum led_type {
 	IWL_LED_TRG_RADIO,
 	IWL_LED_TRG_MAX,
 };
-#endif
-
-#ifdef CONFIG_IWLWIFI_LEDS
 
-struct iwl_led {
-	struct iwl_priv *priv;
-	struct led_classdev led_dev;
-	char name[32];
-
-	int (*led_on) (struct iwl_priv *priv, int led_id);
-	int (*led_off) (struct iwl_priv *priv, int led_id);
-	int (*led_pattern) (struct iwl_priv *priv, int led_id, unsigned int idx);
-
-	enum led_type type;
-	unsigned int registered;
+/*
+ * LED mode
+ *    IWL_LED_BLINK:    adjust led blink rate based on blink table
+ *    IWL_LED_RF_STATE: turn LED on/off based on RF state
+ *			LED ON  = RF ON
+ *			LED OFF = RF OFF
+ */
+enum iwl_led_mode {
+	IWL_LED_BLINK,
+	IWL_LED_RF_STATE,
 };
 
-int iwl_leds_register(struct iwl_priv *priv);
-void iwl_leds_unregister(struct iwl_priv *priv);
+void iwl_leds_init(struct iwl_priv *priv);
 void iwl_leds_background(struct iwl_priv *priv);
+int iwl_led_start(struct iwl_priv *priv);
+int iwl_led_associate(struct iwl_priv *priv);
+int iwl_led_disassociate(struct iwl_priv *priv);
 
-#else
-static inline int iwl_leds_register(struct iwl_priv *priv)
-{
-	return 0;
-}
-static inline void iwl_leds_unregister(struct iwl_priv *priv)
-{
-}
-static inline void iwl_leds_background(struct iwl_priv *priv)
-{
-}
-
-#endif /* CONFIG_IWLWIFI_LEDS */
 #endif /* __iwl_leds_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(no_sleep_autoadjust,
 
 struct iwl_power_vec_entry {
 	struct iwl_powertable_cmd cmd;
-	u8 no_dtim;
+	u8 no_dtim;	/* number of skip dtim */
 };
 
 #define IWL_DTIM_RANGE_0_MAX	2
@@ -83,8 +83,9 @@ struct iwl_power_vec_entry {
 				     cpu_to_le32(X4)}
 /* default power management (not Tx power) table values */
 /* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */
+/* DTIM 0 - 2 */
 static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
-	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
+	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1},
@@ -93,15 +94,17 @@ static const struct iwl_power_vec_entry
 
 
 /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
+/* DTIM 3 - 10 */
 static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1},
-	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
+	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10)}, 2}
 };
 
 /* for DTIM period > IWL_DTIM_RANGE_1_MAX */
+/* DTIM 11 - */
 static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -115,13 +118,15 @@ static void iwl_static_sleep_cmd(struct
 				 enum iwl_power_level lvl, int period)
 {
 	const struct iwl_power_vec_entry *table;
-	int max_sleep, i;
-	bool skip;
+	int max_sleep[IWL_POWER_VEC_SIZE] = { 0 };
+	int i;
+	u8 skip;
+	u32 slp_itrvl;
 
 	table = range_2;
-	if (period < IWL_DTIM_RANGE_1_MAX)
+	if (period <= IWL_DTIM_RANGE_1_MAX)
 		table = range_1;
-	if (period < IWL_DTIM_RANGE_0_MAX)
+	if (period <= IWL_DTIM_RANGE_0_MAX)
 		table = range_0;
 
 	BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
@@ -129,34 +134,60 @@ static void iwl_static_sleep_cmd(struct
 	*cmd = table[lvl].cmd;
 
 	if (period == 0) {
-		skip = false;
+		skip = 0;
 		period = 1;
+		for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
+			max_sleep[i] =  1;
+
 	} else {
-		skip = !!table[lvl].no_dtim;
+		skip = table[lvl].no_dtim;
+		for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
+			max_sleep[i] = le32_to_cpu(cmd->sleep_interval[i]);
+		max_sleep[IWL_POWER_VEC_SIZE - 1] = skip + 1;
 	}
 
-	if (skip) {
-		__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
-		max_sleep = le32_to_cpu(slp_itrvl);
-		if (max_sleep == 0xFF)
-			max_sleep = period * (skip + 1);
-		else if (max_sleep > period)
-			max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
+	slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]);
+	/* figure out the listen interval based on dtim period and skip */
+	if (slp_itrvl == 0xFF)
+		cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] =
+			cpu_to_le32(period * (skip + 1));
+
+	slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]);
+	if (slp_itrvl > period)
+		cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] =
+			cpu_to_le32((slp_itrvl / period) * period);
+
+	if (skip)
 		cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
-	} else {
-		max_sleep = period;
+	else
 		cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
-	}
 
-	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
-		if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
-			cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
+	slp_itrvl = le32_to_cpu(cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]);
+	if (slp_itrvl > IWL_CONN_MAX_LISTEN_INTERVAL)
+		cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1] =
+			cpu_to_le32(IWL_CONN_MAX_LISTEN_INTERVAL);
+
+	/* enforce max sleep interval */
+	for (i = IWL_POWER_VEC_SIZE - 1; i >= 0 ; i--) {
+		if (le32_to_cpu(cmd->sleep_interval[i]) >
+		    (max_sleep[i] * period))
+			cmd->sleep_interval[i] =
+				cpu_to_le32(max_sleep[i] * period);
+		if (i != (IWL_POWER_VEC_SIZE - 1)) {
+			if (le32_to_cpu(cmd->sleep_interval[i]) >
+			    le32_to_cpu(cmd->sleep_interval[i+1]))
+				cmd->sleep_interval[i] =
+					cmd->sleep_interval[i+1];
+		}
+	}
 
 	if (priv->power_data.pci_pm)
 		cmd->flags |= IWL_POWER_PCI_PM_MSK;
 	else
 		cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
 
+	IWL_DEBUG_POWER(priv, "numSkipDtim = %u, dtimPeriod = %d\n",
+			skip, period);
 	IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
 }
 
@@ -165,26 +196,26 @@ static void iwl_static_sleep_cmd(struct
  *=============================================================================
  *                 Condition Nxt State  Condition Nxt State Condition Nxt State
  *-----------------------------------------------------------------------------
- *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
- *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
- *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
+ *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A
+ *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_0
+ *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_1
  *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
  *=============================================================================
  */
 static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
 	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
-	{IWL_TI_1, 105, CT_KILL_THRESHOLD},
-	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+	{IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
 };
 static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
 	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
-	{IWL_TI_2, 110, CT_KILL_THRESHOLD},
-	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+	{IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
 };
 static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
 	{IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
-	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
-	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
 };
 static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
 	{IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
@@ -294,6 +325,9 @@ int iwl_power_update_mode(struct iwl_pri
 
 	if (priv->cfg->broken_powersave)
 		iwl_power_sleep_cam_cmd(priv, &cmd);
+	else if (priv->cfg->supports_idle &&
+		 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+		iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
 	else if (tt->state >= IWL_TI_1)
 		iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
 	else if (!enabled)
@@ -348,6 +382,23 @@ bool iwl_ht_enabled(struct iwl_priv *pri
 }
 EXPORT_SYMBOL(iwl_ht_enabled);
 
+bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
+{
+	s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */
+	bool within_margin = false;
+
+	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
+		temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+	if (!priv->thermal_throttle.advanced_tt)
+		within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+				CT_KILL_THRESHOLD_LEGACY) ? true : false;
+	else
+		within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+				CT_KILL_THRESHOLD) ? true : false;
+	return within_margin;
+}
+
 enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
 {
 	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
@@ -372,6 +423,7 @@ enum iwl_antenna_ok iwl_rx_ant_restricti
 }
 
 #define CT_KILL_EXIT_DURATION (5)	/* 5 seconds duration */
+#define CT_KILL_WAITING_DURATION (300)	/* 300ms duration */
 
 /*
  * toggle the bit to wake up uCode and check the temperature
@@ -409,6 +461,7 @@ static void iwl_tt_check_exit_ct_kill(un
 		/* Reschedule the ct_kill timer to occur in
 		 * CT_KILL_EXIT_DURATION seconds to ensure we get a
 		 * thermal update */
+		IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
 		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
 			  CT_KILL_EXIT_DURATION * HZ);
 	}
@@ -432,6 +485,33 @@ static void iwl_perform_ct_kill_task(str
 	}
 }
 
+static void iwl_tt_ready_for_ct_kill(unsigned long data)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)data;
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	/* temperature timer expired, ready to go into CT_KILL state */
+	if (tt->state != IWL_TI_CT_KILL) {
+		IWL_DEBUG_POWER(priv, "entering CT_KILL state when temperature timer expired\n");
+		tt->state = IWL_TI_CT_KILL;
+		set_bit(STATUS_CT_KILL, &priv->status);
+		iwl_perform_ct_kill_task(priv, true);
+	}
+}
+
+static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
+{
+	IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
+	/* make request to retrieve statistics information */
+	iwl_send_statistics_request(priv, CMD_SYNC, false);
+	/* Reschedule the ct_kill wait timer */
+	mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
+		 jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
+}
+
 #define IWL_MINIMAL_POWER_THRESHOLD		(CT_KILL_THRESHOLD_LEGACY)
 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_2	(100)
 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_1	(90)
@@ -445,7 +525,7 @@ static void iwl_perform_ct_kill_task(str
  *	Throttle early enough to lower the power consumption before
  *	drastic steps are needed
  */
-static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
+static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
 {
 	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 	enum iwl_tt_state old_state;
@@ -474,6 +554,8 @@ static void iwl_legacy_tt_handler(struct
 #ifdef CONFIG_IWLWIFI_DEBUG
 	tt->tt_previous_temp = temp;
 #endif
+	/* stop ct_kill_waiting_tm timer */
+	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
 	if (tt->state != old_state) {
 		switch (tt->state) {
 		case IWL_TI_0:
@@ -494,17 +576,28 @@ static void iwl_legacy_tt_handler(struct
 			break;
 		}
 		mutex_lock(&priv->mutex);
-		if (iwl_power_update_mode(priv, true)) {
+		if (old_state == IWL_TI_CT_KILL)
+			clear_bit(STATUS_CT_KILL, &priv->status);
+		if (tt->state != IWL_TI_CT_KILL &&
+		    iwl_power_update_mode(priv, true)) {
 			/* TT state not updated
 			 * try again during next temperature read
 			 */
+			if (old_state == IWL_TI_CT_KILL)
+				set_bit(STATUS_CT_KILL, &priv->status);
 			tt->state = old_state;
 			IWL_ERR(priv, "Cannot update power mode, "
 					"TT state not updated\n");
 		} else {
-			if (tt->state == IWL_TI_CT_KILL)
-				iwl_perform_ct_kill_task(priv, true);
-			else if (old_state == IWL_TI_CT_KILL &&
+			if (tt->state == IWL_TI_CT_KILL) {
+				if (force) {
+					set_bit(STATUS_CT_KILL, &priv->status);
+					iwl_perform_ct_kill_task(priv, true);
+				} else {
+					iwl_prepare_ct_kill_task(priv);
+					tt->state = old_state;
+				}
+			} else if (old_state == IWL_TI_CT_KILL &&
 				 tt->state != IWL_TI_CT_KILL)
 				iwl_perform_ct_kill_task(priv, false);
 			IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
@@ -531,13 +624,13 @@ static void iwl_legacy_tt_handler(struct
  *=============================================================================
  *                 Condition Nxt State  Condition Nxt State Condition Nxt State
  *-----------------------------------------------------------------------------
- *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
- *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
- *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
+ *     IWL_TI_0     T >= 114   CT_KILL  114>T>=105   TI_1      N/A      N/A
+ *     IWL_TI_1     T >= 114   CT_KILL  114>T>=110   TI_2     T<=95     TI_0
+ *     IWL_TI_2     T >= 114   CT_KILL                        T<=100    TI_1
  *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
  *=============================================================================
  */
-static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
+static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
 {
 	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 	int i;
@@ -582,6 +675,8 @@ static void iwl_advance_tt_handler(struc
 			break;
 		}
 	}
+	/* stop ct_kill_waiting_tm timer */
+	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
 	if (changed) {
 		struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
 
@@ -613,12 +708,17 @@ static void iwl_advance_tt_handler(struc
 			iwl_set_rxon_ht(priv, &priv->current_ht_config);
 		}
 		mutex_lock(&priv->mutex);
-		if (iwl_power_update_mode(priv, true)) {
+		if (old_state == IWL_TI_CT_KILL)
+			clear_bit(STATUS_CT_KILL, &priv->status);
+		if (tt->state != IWL_TI_CT_KILL &&
+		    iwl_power_update_mode(priv, true)) {
 			/* TT state not updated
 			 * try again during next temperature read
 			 */
 			IWL_ERR(priv, "Cannot update power mode, "
 					"TT state not updated\n");
+			if (old_state == IWL_TI_CT_KILL)
+				set_bit(STATUS_CT_KILL, &priv->status);
 			tt->state = old_state;
 		} else {
 			IWL_DEBUG_POWER(priv,
@@ -626,9 +726,15 @@ static void iwl_advance_tt_handler(struc
 					tt->state);
 			if (old_state != IWL_TI_CT_KILL &&
 			    tt->state == IWL_TI_CT_KILL) {
-				IWL_DEBUG_POWER(priv, "Enter IWL_TI_CT_KILL\n");
-				iwl_perform_ct_kill_task(priv, true);
-
+				if (force) {
+					IWL_DEBUG_POWER(priv,
+						"Enter IWL_TI_CT_KILL\n");
+					set_bit(STATUS_CT_KILL, &priv->status);
+					iwl_perform_ct_kill_task(priv, true);
+				} else {
+					iwl_prepare_ct_kill_task(priv);
+					tt->state = old_state;
+				}
 			} else if (old_state == IWL_TI_CT_KILL &&
 				  tt->state != IWL_TI_CT_KILL) {
 				IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
@@ -665,10 +771,11 @@ static void iwl_bg_ct_enter(struct work_
 			      "- ucode going to sleep!\n");
 		if (!priv->thermal_throttle.advanced_tt)
 			iwl_legacy_tt_handler(priv,
-					      IWL_MINIMAL_POWER_THRESHOLD);
+					      IWL_MINIMAL_POWER_THRESHOLD,
+					      true);
 		else
 			iwl_advance_tt_handler(priv,
-					       CT_KILL_THRESHOLD + 1);
+					       CT_KILL_THRESHOLD + 1, true);
 	}
 }
 
@@ -695,11 +802,18 @@ static void iwl_bg_ct_exit(struct work_s
 		IWL_ERR(priv,
 			"Device temperature below critical"
 			"- ucode awake!\n");
+		/*
+		 * exit from CT_KILL state
+		 * reset the current temperature reading
+		 */
+		priv->temperature = 0;
 		if (!priv->thermal_throttle.advanced_tt)
 			iwl_legacy_tt_handler(priv,
-					IWL_REDUCED_PERFORMANCE_THRESHOLD_2);
+					      IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
+					      true);
 		else
-			iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD);
+			iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
+					       true);
 	}
 }
 
@@ -735,9 +849,9 @@ static void iwl_bg_tt_work(struct work_s
 		temp = KELVIN_TO_CELSIUS(priv->temperature);
 
 	if (!priv->thermal_throttle.advanced_tt)
-		iwl_legacy_tt_handler(priv, temp);
+		iwl_legacy_tt_handler(priv, temp, false);
 	else
-		iwl_advance_tt_handler(priv, temp);
+		iwl_advance_tt_handler(priv, temp, false);
 }
 
 void iwl_tt_handler(struct iwl_priv *priv)
@@ -768,16 +882,18 @@ void iwl_tt_initialize(struct iwl_priv *
 	tt->state = IWL_TI_0;
 	init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
 	priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
-	priv->thermal_throttle.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
-
+	priv->thermal_throttle.ct_kill_exit_tm.function =
+		iwl_tt_check_exit_ct_kill;
+	init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
+	priv->thermal_throttle.ct_kill_waiting_tm.data = (unsigned long)priv;
+	priv->thermal_throttle.ct_kill_waiting_tm.function =
+		iwl_tt_ready_for_ct_kill;
 	/* setup deferred ct kill work */
 	INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
 	INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
 	INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
 
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_6x00:
-	case CSR_HW_REV_TYPE_6x50:
+	if (priv->cfg->adv_thermal_throttle) {
 		IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
 		tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
 					 IWL_TI_STATE_MAX, GFP_KERNEL);
@@ -810,11 +926,9 @@ void iwl_tt_initialize(struct iwl_priv *
 				&restriction_range[0], size);
 			priv->thermal_throttle.advanced_tt = true;
 		}
-		break;
-	default:
+	} else {
 		IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
 		priv->thermal_throttle.advanced_tt = false;
-		break;
 	}
 }
 EXPORT_SYMBOL(iwl_tt_initialize);
@@ -826,6 +940,8 @@ void iwl_tt_exit(struct iwl_priv *priv)
 
 	/* stop ct_kill_exit_tm timer if activated */
 	del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+	/* stop ct_kill_waiting_tm timer if activated */
+	del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
 	cancel_work_sync(&priv->tt_work);
 	cancel_work_sync(&priv->ct_enter);
 	cancel_work_sync(&priv->ct_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2010-02-24 13:52:17.000000000 -0500
@@ -33,6 +33,7 @@
 #define IWL_ABSOLUTE_ZERO		0
 #define IWL_ABSOLUTE_MAX		0xFFFFFFFF
 #define IWL_TT_INCREASE_MARGIN	5
+#define IWL_TT_CT_KILL_MARGIN	3
 
 enum iwl_antenna_ok {
 	IWL_ANT_OK_NONE,
@@ -110,6 +111,7 @@ struct iwl_tt_mgmt {
 	struct iwl_tt_restriction *restriction;
 	struct iwl_tt_trans *transaction;
 	struct timer_list ct_kill_exit_tm;
+	struct timer_list ct_kill_waiting_tm;
 };
 
 enum iwl_power_level {
@@ -129,6 +131,7 @@ struct iwl_power_mgr {
 
 int iwl_power_update_mode(struct iwl_priv *priv, bool force);
 bool iwl_ht_enabled(struct iwl_priv *priv);
+bool iwl_within_ct_kill_margin(struct iwl_priv *priv);
 enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
 enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
 void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2010-02-24 13:52:17.000000000 -0500
@@ -254,7 +254,8 @@
  * device.  A queue maps to only one (selectable by driver) Tx DMA channel,
  * but one DMA channel may take input from several queues.
  *
- * Tx DMA channels have dedicated purposes.  For 4965, they are used as follows:
+ * Tx DMA channels have dedicated purposes.  For 4965, they are used as follows
+ * (cf. default_queue_to_tx_fifo in iwl-4965.c):
  *
  * 0 -- EDCA BK (background) frames, lowest priority
  * 1 -- EDCA BE (best effort) frames, normal priority
@@ -265,9 +266,21 @@
  * 6 -- HCCA long frames
  * 7 -- not used by driver (device-internal only)
  *
+ * For 5000 series and up, they are used slightly differently
+ * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
+ *
+ * 0 -- EDCA BK (background) frames, lowest priority
+ * 1 -- EDCA BE (best effort) frames, normal priority
+ * 2 -- EDCA VI (video) frames, higher priority
+ * 3 -- EDCA VO (voice) and management frames, highest priority
+ * 4 -- (TBD)
+ * 5 -- HCCA short frames
+ * 6 -- HCCA long frames
+ * 7 -- Commands
+ *
  * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
- * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to
- * support 11n aggregation via EDCA DMA channels.
+ * In addition, driver can map the remaining queues to Tx DMA/FIFO
+ * channels 0-3 to support 11n aggregation via EDCA DMA channels.
  *
  * The driver sets up each queue to work in one of two modes:
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -140,6 +140,8 @@ int iwl_rx_queue_update_write_ptr(struct
 		reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
 
 		if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+			IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n",
+				      reg);
 			iwl_set_bit(priv, CSR_GP_CNTRL,
 				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 			goto exit_unlock;
@@ -200,7 +202,7 @@ int iwl_rx_queue_restock(struct iwl_priv
 		list_del(element);
 
 		/* Point to Rx buffer via next RBD in circular buffer */
-		rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->aligned_dma_addr);
+		rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->page_dma);
 		rxq->queue[rxq->write] = rxb;
 		rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
 		rxq->free_count--;
@@ -239,8 +241,9 @@ void iwl_rx_allocate(struct iwl_priv *pr
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
-	struct sk_buff *skb;
+	struct page *page;
 	unsigned long flags;
+	gfp_t gfp_mask = priority;
 
 	while (1) {
 		spin_lock_irqsave(&rxq->lock, flags);
@@ -251,30 +254,35 @@ void iwl_rx_allocate(struct iwl_priv *pr
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		if (rxq->free_count > RX_LOW_WATERMARK)
-			priority |= __GFP_NOWARN;
-		/* Alloc a new receive buffer */
-		skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
-						priority);
+			gfp_mask |= __GFP_NOWARN;
 
-		if (!skb) {
+		if (priv->hw_params.rx_page_order > 0)
+			gfp_mask |= __GFP_COMP;
+
+		/* Alloc a new receive buffer */
+		page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
+		if (!page) {
 			if (net_ratelimit())
-				IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
+				IWL_DEBUG_INFO(priv, "alloc_pages failed, "
+					       "order: %d\n",
+					       priv->hw_params.rx_page_order);
+
 			if ((rxq->free_count <= RX_LOW_WATERMARK) &&
 			    net_ratelimit())
-				IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n",
+				IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
 					 priority == GFP_ATOMIC ?  "GFP_ATOMIC" : "GFP_KERNEL",
 					 rxq->free_count);
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
 			 * more buffers it will schedule replenish */
-			break;
+			return;
 		}
 
 		spin_lock_irqsave(&rxq->lock, flags);
 
 		if (list_empty(&rxq->rx_used)) {
 			spin_unlock_irqrestore(&rxq->lock, flags);
-			dev_kfree_skb_any(skb);
+			__free_pages(page, priv->hw_params.rx_page_order);
 			return;
 		}
 		element = rxq->rx_used.next;
@@ -283,24 +291,21 @@ void iwl_rx_allocate(struct iwl_priv *pr
 
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
-		rxb->skb = skb;
-		/* Get physical address of RB/SKB */
-		rxb->real_dma_addr = pci_map_single(
-					priv->pci_dev,
-					rxb->skb->data,
-					priv->hw_params.rx_buf_size + 256,
-					PCI_DMA_FROMDEVICE);
+		rxb->page = page;
+		/* Get physical address of the RB */
+		rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
 		/* dma address must be no more than 36 bits */
-		BUG_ON(rxb->real_dma_addr & ~DMA_BIT_MASK(36));
+		BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
 		/* and also 256 byte aligned! */
-		rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256);
-		skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr);
+		BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
 
 		spin_lock_irqsave(&rxq->lock, flags);
 
 		list_add_tail(&rxb->list, &rxq->rx_free);
 		rxq->free_count++;
-		priv->alloc_rxb_skb++;
+		priv->alloc_rxb_page++;
 
 		spin_unlock_irqrestore(&rxq->lock, flags);
 	}
@@ -336,12 +341,12 @@ void iwl_rx_queue_free(struct iwl_priv *
 {
 	int i;
 	for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
-		if (rxq->pool[i].skb != NULL) {
-			pci_unmap_single(priv->pci_dev,
-					 rxq->pool[i].real_dma_addr,
-					 priv->hw_params.rx_buf_size + 256,
-					 PCI_DMA_FROMDEVICE);
-			dev_kfree_skb(rxq->pool[i].skb);
+		if (rxq->pool[i].page != NULL) {
+			pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			__iwl_free_pages(priv, rxq->pool[i].page);
+			rxq->pool[i].page = NULL;
 		}
 	}
 
@@ -405,14 +410,12 @@ void iwl_rx_queue_reset(struct iwl_priv
 	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].skb != NULL) {
-			pci_unmap_single(priv->pci_dev,
-					 rxq->pool[i].real_dma_addr,
-					 priv->hw_params.rx_buf_size + 256,
-					 PCI_DMA_FROMDEVICE);
-			priv->alloc_rxb_skb--;
-			dev_kfree_skb(rxq->pool[i].skb);
-			rxq->pool[i].skb = NULL;
+		if (rxq->pool[i].page != NULL) {
+			pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
+				PAGE_SIZE << priv->hw_params.rx_page_order,
+				PCI_DMA_FROMDEVICE);
+			__iwl_free_pages(priv, rxq->pool[i].page);
+			rxq->pool[i].page = NULL;
 		}
 		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
 	}
@@ -470,7 +473,8 @@ int iwl_rx_init(struct iwl_priv *priv, s
 			   (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
 			   (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
-	iwl_write32(priv, CSR_INT_COALESCING, 0x40);
+	/* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */
+	iwl_write8(priv, CSR_INT_COALESCING, 0x40);
 
 	return 0;
 }
@@ -491,7 +495,7 @@ void iwl_rx_missed_beacon_notif(struct i
 				struct iwl_rx_mem_buffer *rxb)
 
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_missed_beacon_notif *missed_beacon;
 
 	missed_beacon = &pkt->u.missed_beacon;
@@ -548,13 +552,51 @@ static void iwl_rx_calc_noise(struct iwl
 			priv->last_rx_noise);
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+/*
+ *  based on the assumption of all statistics counter are in DWORD
+ *  FIXME: This function is for debugging, do not deal with
+ *  the case of counters roll-over.
+ */
+static void iwl_accumulative_statistics(struct iwl_priv *priv,
+					__le32 *stats)
+{
+	int i;
+	__le32 *prev_stats;
+	u32 *accum_stats;
+
+	prev_stats = (__le32 *)&priv->statistics;
+	accum_stats = (u32 *)&priv->accum_statistics;
+
+	for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
+	     i += sizeof(__le32), stats++, prev_stats++, accum_stats++)
+		if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats))
+			*accum_stats += (le32_to_cpu(*stats) -
+				le32_to_cpu(*prev_stats));
+
+	/* reset accumulative statistics for "no-counter" type statistics */
+	priv->accum_statistics.general.temperature =
+		priv->statistics.general.temperature;
+	priv->accum_statistics.general.temperature_m =
+		priv->statistics.general.temperature_m;
+	priv->accum_statistics.general.ttl_timestamp =
+		priv->statistics.general.ttl_timestamp;
+	priv->accum_statistics.tx.tx_power.ant_a =
+		priv->statistics.tx.tx_power.ant_a;
+	priv->accum_statistics.tx.tx_power.ant_b =
+		priv->statistics.tx.tx_power.ant_b;
+	priv->accum_statistics.tx.tx_power.ant_c =
+		priv->statistics.tx.tx_power.ant_c;
+}
+#endif
+
 #define REG_RECALIB_PERIOD (60)
 
 void iwl_rx_statistics(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb)
 {
 	int change;
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(priv->statistics),
@@ -566,6 +608,9 @@ void iwl_rx_statistics(struct iwl_priv *
 		    STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
 		   (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+	iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
+#endif
 	memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
 
 	set_bit(STATUS_STATISTICS, &priv->status);
@@ -582,54 +627,28 @@ void iwl_rx_statistics(struct iwl_priv *
 		iwl_rx_calc_noise(priv);
 		queue_work(priv->workqueue, &priv->run_time_calib_work);
 	}
-
-	iwl_leds_background(priv);
-
 	if (priv->cfg->ops->lib->temp_ops.temperature && change)
 		priv->cfg->ops->lib->temp_ops.temperature(priv);
 }
 EXPORT_SYMBOL(iwl_rx_statistics);
 
-#define PERFECT_RSSI (-20) /* dBm */
-#define WORST_RSSI (-95)   /* dBm */
-#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
-
-/* Calculate an indication of rx signal quality (a percentage, not dBm!).
- * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
- *   about formulas used below. */
-static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
+void iwl_reply_statistics(struct iwl_priv *priv,
+			      struct iwl_rx_mem_buffer *rxb)
 {
-	int sig_qual;
-	int degradation = PERFECT_RSSI - rssi_dbm;
-
-	/* If we get a noise measurement, use signal-to-noise ratio (SNR)
-	 * as indicator; formula is (signal dbm - noise dbm).
-	 * SNR at or above 40 is a great signal (100%).
-	 * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
-	 * Weakest usable signal is usually 10 - 15 dB SNR. */
-	if (noise_dbm) {
-		if (rssi_dbm - noise_dbm >= 40)
-			return 100;
-		else if (rssi_dbm < noise_dbm)
-			return 0;
-		sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
-
-	/* Else use just the signal level.
-	 * This formula is a least squares fit of data points collected and
-	 *   compared with a reference system that had a percentage (%) display
-	 *   for signal quality. */
-	} else
-		sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
-			    (15 * RSSI_RANGE + 62 * degradation)) /
-			   (RSSI_RANGE * RSSI_RANGE);
-
-	if (sig_qual > 100)
-		sig_qual = 100;
-	else if (sig_qual < 1)
-		sig_qual = 0;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
-	return sig_qual;
+	if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
+		memset(&priv->statistics, 0,
+			sizeof(struct iwl_notif_statistics));
+#ifdef CONFIG_IWLWIFI_DEBUG
+		memset(&priv->accum_statistics, 0,
+			sizeof(struct iwl_notif_statistics));
+#endif
+		IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
+	}
+	iwl_rx_statistics(priv, rxb);
 }
+EXPORT_SYMBOL(iwl_reply_statistics);
 
 /* Calc max signal level (dBm) among 3 possible receivers */
 static inline int iwl_calc_rssi(struct iwl_priv *priv,
@@ -878,6 +897,10 @@ static void iwl_pass_packet_to_mac80211(
 					struct iwl_rx_mem_buffer *rxb,
 					struct ieee80211_rx_status *stats)
 {
+	struct sk_buff *skb;
+	int ret = 0;
+	__le16 fc = hdr->frame_control;
+
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
 		IWL_DEBUG_DROP_LIMIT(priv,
@@ -890,15 +913,47 @@ static void iwl_pass_packet_to_mac80211(
 	    iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
 		return;
 
-	/* Resize SKB from mac header to end of packet */
-	skb_reserve(rxb->skb, (void *)hdr - (void *)rxb->skb->data);
-	skb_put(rxb->skb, len);
+	skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
+	if (!skb) {
+		IWL_ERR(priv, "alloc_skb failed\n");
+		return;
+	}
 
-	iwl_update_stats(priv, false, hdr->frame_control, len);
-	memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
-	ieee80211_rx_irqsafe(priv->hw, rxb->skb);
-	priv->alloc_rxb_skb--;
-	rxb->skb = NULL;
+	skb_reserve(skb, IWL_LINK_HDR_MAX);
+	skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+
+	/* mac80211 currently doesn't support paged SKB. Convert it to
+	 * linear SKB for management frame and data frame requires
+	 * software decryption or software defragementation. */
+	if (ieee80211_is_mgmt(fc) ||
+	    ieee80211_has_protected(fc) ||
+	    ieee80211_has_morefrags(fc) ||
+	    le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
+	    (ieee80211_is_data_qos(fc) &&
+	     *ieee80211_get_qos_ctl(hdr) &
+	     IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
+		ret = skb_linearize(skb);
+	else
+		ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
+			 0 : -ENOMEM;
+
+	if (ret) {
+		kfree_skb(skb);
+		goto out;
+	}
+
+	/*
+	 * XXX: We cannot touch the page and its virtual memory (hdr) after
+	 * here. It might have already been freed by the above skb change.
+	 */
+
+	iwl_update_stats(priv, false, fc, len);
+	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
+
+	ieee80211_rx(priv->hw, skb);
+ out:
+	priv->alloc_rxb_page--;
+	rxb->page = NULL;
 }
 
 /* This is necessary only for a number of statistics, see the caller. */
@@ -926,13 +981,12 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 {
 	struct ieee80211_hdr *header;
 	struct ieee80211_rx_status rx_status;
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_rx_phy_res *phy_res;
 	__le32 rx_pkt_status;
 	struct iwl4965_rx_mpdu_res_start *amsdu;
 	u32 len;
 	u32 ampdu_status;
-	u16 fc;
 	u32 rate_n_flags;
 
 	/**
@@ -1009,11 +1063,8 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 	if (iwl_is_associated(priv) &&
 	    !test_bit(STATUS_SCANNING, &priv->status)) {
 		rx_status.noise = priv->last_rx_noise;
-		rx_status.qual = iwl_calc_sig_qual(rx_status.signal,
-							 rx_status.noise);
 	} else {
 		rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-		rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0);
 	}
 
 	/* Reset beacon noise level if not associated. */
@@ -1026,8 +1077,8 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 		iwl_dbg_report_frame(priv, phy_res, len, header, 1);
 #endif
 	iwl_dbg_log_rx_data_frame(priv, len, header);
-	IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
-		rx_status.signal, rx_status.noise, rx_status.qual,
+	IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n",
+		rx_status.signal, rx_status.noise,
 		(unsigned long long)rx_status.mactime);
 
 	/*
@@ -1065,20 +1116,8 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 		priv->last_tsf = le64_to_cpu(phy_res->timestamp);
 	}
 
-	fc = le16_to_cpu(header->frame_control);
-	switch (fc & IEEE80211_FCTL_FTYPE) {
-	case IEEE80211_FTYPE_MGMT:
-	case IEEE80211_FTYPE_DATA:
-		if (priv->iw_mode == NL80211_IFTYPE_AP)
-			iwl_update_ps_mode(priv, fc  & IEEE80211_FCTL_PM,
-						header->addr2);
-		/* fall through */
-	default:
-		iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
-				rxb, &rx_status);
-		break;
-
-	}
+	iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
+				    rxb, &rx_status);
 }
 EXPORT_SYMBOL(iwl_rx_reply_rx);
 
@@ -1087,7 +1126,7 @@ EXPORT_SYMBOL(iwl_rx_reply_rx);
 void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
 				    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	priv->last_phy_res[0] = 1;
 	memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
 	       sizeof(struct iwl_rx_phy_res));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,6 @@
  *****************************************************************************/
 #include <linux/types.h>
 #include <linux/etherdevice.h>
-#include <net/lib80211.h>
 #include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
@@ -112,7 +111,7 @@ EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 static int iwl_send_scan_abort(struct iwl_priv *priv)
 {
 	int ret = 0;
-	struct iwl_rx_packet *res;
+	struct iwl_rx_packet *pkt;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_ABORT_CMD,
 		.flags = CMD_WANT_SKB,
@@ -132,21 +131,20 @@ static int iwl_send_scan_abort(struct iw
 		return ret;
 	}
 
-	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
-	if (res->u.status != CAN_ABORT_STATUS) {
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->u.status != CAN_ABORT_STATUS) {
 		/* The scan abort will return 1 for success or
 		 * 2 for "failure".  A failure condition can be
 		 * due to simply not being in an active scan which
 		 * can occur if we send the scan abort before we
 		 * the microcode has notified us that a scan is
 		 * completed. */
-		IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status);
+		IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
 		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 		clear_bit(STATUS_SCAN_HW, &priv->status);
 	}
 
-	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.reply_skb);
+	iwl_free_pages(priv, cmd.reply_page);
 
 	return ret;
 }
@@ -156,7 +154,7 @@ static void iwl_rx_reply_scan(struct iwl
 			      struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_scanreq_notification *notif =
 	    (struct iwl_scanreq_notification *)pkt->u.raw;
 
@@ -168,7 +166,7 @@ static void iwl_rx_reply_scan(struct iwl
 static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
 				    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_scanstart_notification *notif =
 	    (struct iwl_scanstart_notification *)pkt->u.raw;
 	priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
@@ -187,7 +185,7 @@ static void iwl_rx_scan_results_notif(st
 				      struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_scanresults_notification *notif =
 	    (struct iwl_scanresults_notification *)pkt->u.raw;
 
@@ -214,7 +212,7 @@ static void iwl_rx_scan_complete_notif(s
 				       struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
 
 	IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
@@ -402,6 +400,7 @@ void iwl_init_scan_params(struct iwl_pri
 	if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
 		priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
 }
+EXPORT_SYMBOL(iwl_init_scan_params);
 
 static int iwl_scan_initiate(struct iwl_priv *priv)
 {
@@ -581,6 +580,7 @@ static void iwl_bg_request_scan(struct w
 	u8 rate;
 	bool is_active = false;
 	int  chan_mod;
+	u8 active_chains;
 
 	conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -734,9 +734,22 @@ static void iwl_bg_request_scan(struct w
 	rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
 	scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
 
+	/* In power save mode use one chain, otherwise use all chains */
+	if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+		/* rx_ant has been set to all valid chains previously */
+		active_chains = rx_ant &
+				((u8)(priv->chain_noise_data.active_chains));
+		if (!active_chains)
+			active_chains = rx_ant;
+
+		IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
+				priv->chain_noise_data.active_chains);
+
+		rx_ant = first_antenna(active_chains);
+	}
 	/* MIMO is not used here, but value is required */
-	rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
-	rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+	rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+	rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
 	rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
 	rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
 	scan->rx_chain = cpu_to_le16(rx_chain);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	2010-02-24 13:52:17.000000000 -0500
@@ -177,7 +177,7 @@ static int iwl_get_measurement(struct iw
 static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
 					  struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
 
 	if (!report->state) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,32 +99,25 @@ static void iwl_sta_ucode_activate(struc
 
 static void iwl_add_sta_callback(struct iwl_priv *priv,
 				 struct iwl_device_cmd *cmd,
-				 struct sk_buff *skb)
+				 struct iwl_rx_packet *pkt)
 {
-	struct iwl_rx_packet *res = NULL;
 	struct iwl_addsta_cmd *addsta =
 		(struct iwl_addsta_cmd *)cmd->cmd.payload;
 	u8 sta_id = addsta->sta.sta_id;
 
-	if (!skb) {
-		IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
-		return;
-	}
-
-	res = (struct iwl_rx_packet *)skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  res->hdr.flags);
+			  pkt->hdr.flags);
 		return;
 	}
 
-	switch (res->u.add_sta.status) {
+	switch (pkt->u.add_sta.status) {
 	case ADD_STA_SUCCESS_MSK:
 		iwl_sta_ucode_activate(priv, sta_id);
 		 /* fall through */
 	default:
 		IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
-			     res->u.add_sta.status);
+			     pkt->u.add_sta.status);
 		break;
 	}
 }
@@ -132,7 +125,7 @@ static void iwl_add_sta_callback(struct
 int iwl_send_add_sta(struct iwl_priv *priv,
 		     struct iwl_addsta_cmd *sta, u8 flags)
 {
-	struct iwl_rx_packet *res = NULL;
+	struct iwl_rx_packet *pkt = NULL;
 	int ret = 0;
 	u8 data[sizeof(*sta)];
 	struct iwl_host_cmd cmd = {
@@ -152,15 +145,15 @@ int iwl_send_add_sta(struct iwl_priv *pr
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
 
-	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  res->hdr.flags);
+			  pkt->hdr.flags);
 		ret = -EIO;
 	}
 
 	if (ret == 0) {
-		switch (res->u.add_sta.status) {
+		switch (pkt->u.add_sta.status) {
 		case ADD_STA_SUCCESS_MSK:
 			iwl_sta_ucode_activate(priv, sta->sta.sta_id);
 			IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
@@ -171,9 +164,7 @@ int iwl_send_add_sta(struct iwl_priv *pr
 			break;
 		}
 	}
-
-	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.reply_skb);
+	iwl_free_pages(priv, cmd.reply_page);
 
 	return ret;
 }
@@ -189,6 +180,11 @@ static void iwl_set_ht_add_station(struc
 		goto done;
 
 	mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
+	IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
+			"static" :
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
+			"dynamic" : "disabled");
 
 	sta_flags = priv->stations[index].sta.station_flags;
 
@@ -301,7 +297,7 @@ u8 iwl_add_station(struct iwl_priv *priv
 }
 EXPORT_SYMBOL(iwl_add_station);
 
-static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
+static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr)
 {
 	unsigned long flags;
 	u8 sta_id = iwl_find_station(priv, addr);
@@ -324,26 +320,19 @@ static void iwl_sta_ucode_deactivate(str
 
 static void iwl_remove_sta_callback(struct iwl_priv *priv,
 				    struct iwl_device_cmd *cmd,
-				    struct sk_buff *skb)
+				    struct iwl_rx_packet *pkt)
 {
-	struct iwl_rx_packet *res = NULL;
 	struct iwl_rem_sta_cmd *rm_sta =
-		 (struct iwl_rem_sta_cmd *)cmd->cmd.payload;
-	const char *addr = rm_sta->addr;
-
-	if (!skb) {
-		IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
-		return;
-	}
+			(struct iwl_rem_sta_cmd *)cmd->cmd.payload;
+	const u8 *addr = rm_sta->addr;
 
-	res = (struct iwl_rx_packet *)skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
-		res->hdr.flags);
+		pkt->hdr.flags);
 		return;
 	}
 
-	switch (res->u.rem_sta.status) {
+	switch (pkt->u.rem_sta.status) {
 	case REM_STA_SUCCESS_MSK:
 		iwl_sta_ucode_deactivate(priv, addr);
 		break;
@@ -356,7 +345,7 @@ static void iwl_remove_sta_callback(stru
 static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
 				   u8 flags)
 {
-	struct iwl_rx_packet *res = NULL;
+	struct iwl_rx_packet *pkt;
 	int ret;
 
 	struct iwl_rem_sta_cmd rm_sta_cmd;
@@ -381,15 +370,15 @@ static int iwl_send_remove_station(struc
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
 
-	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
-			  res->hdr.flags);
+			  pkt->hdr.flags);
 		ret = -EIO;
 	}
 
 	if (!ret) {
-		switch (res->u.rem_sta.status) {
+		switch (pkt->u.rem_sta.status) {
 		case REM_STA_SUCCESS_MSK:
 			iwl_sta_ucode_deactivate(priv, addr);
 			IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
@@ -400,9 +389,7 @@ static int iwl_send_remove_station(struc
 			break;
 		}
 	}
-
-	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.reply_skb);
+	iwl_free_pages(priv, cmd.reply_page);
 
 	return ret;
 }
@@ -1026,7 +1013,7 @@ int iwl_rxon_add_station(struct iwl_priv
 	 */
 	if (priv->current_ht_config.is_ht) {
 		rcu_read_lock();
-		sta = ieee80211_find_sta(priv->hw, addr);
+		sta = ieee80211_find_sta(priv->vif, addr);
 		if (sta) {
 			memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
 			cur_ht_config = &ht_config;
@@ -1044,6 +1031,68 @@ int iwl_rxon_add_station(struct iwl_priv
 EXPORT_SYMBOL(iwl_rxon_add_station);
 
 /**
+ * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table
+ *
+ * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
+ *       calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
+ *       which requires station table entry to exist).
+ */
+static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
+{
+	int i, r;
+	struct iwl_link_quality_cmd link_cmd = {
+		.reserved1 = 0,
+	};
+	u32 rate_flags;
+
+	/* Set up the rate scaling to start at selected rate, fall back
+	 * all the way down to 1M in IEEE order, and then spin on 1M */
+	if (priv->band == IEEE80211_BAND_5GHZ)
+		r = IWL_RATE_6M_INDEX;
+	else
+		r = IWL_RATE_1M_INDEX;
+
+	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+		rate_flags = 0;
+		if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+			rate_flags |= RATE_MCS_CCK_MSK;
+
+		rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+				RATE_MCS_ANT_POS;
+
+		link_cmd.rs_table[i].rate_n_flags =
+			iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+		r = iwl_get_prev_ieee_rate(r);
+	}
+
+	link_cmd.general_params.single_stream_ant_msk =
+				first_antenna(priv->hw_params.valid_tx_ant);
+	link_cmd.general_params.dual_stream_ant_msk = 3;
+	link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+	link_cmd.agg_params.agg_time_limit =
+		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+	/* Update the rate scaling for control frame Tx to AP */
+	link_cmd.sta_id = priv->hw_params.bcast_sta_id;
+
+	iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
+			       sizeof(link_cmd), &link_cmd, NULL);
+}
+
+
+/**
+ * iwl_add_bcast_station - add broadcast station into station table.
+ */
+void iwl_add_bcast_station(struct iwl_priv *priv)
+{
+	iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
+
+	/* Set up default rate scaling table in device's station table */
+	iwl_sta_init_bcast_lq(priv);
+}
+EXPORT_SYMBOL(iwl_add_bcast_station);
+
+/**
  * iwl_get_sta_id - Find station's index within station table
  *
  * If new IBSS station, create new entry in station table
@@ -1163,7 +1212,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv
 }
 EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
 
-static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
 {
 	unsigned long flags;
 
@@ -1171,27 +1220,26 @@ static void iwl_sta_modify_ps_wake(struc
 	priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
 	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
 	priv->stations[sta_id].sta.sta.modify_mask = 0;
+	priv->stations[sta_id].sta.sleep_tx_count = 0;
 	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
 	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 }
+EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
 
-void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
 {
-	/* FIXME: need locking over ps_status ??? */
-	u8 sta_id = iwl_find_station(priv, addr);
+	unsigned long flags;
 
-	if (sta_id != IWL_INVALID_STATION) {
-		u8 sta_awake = priv->stations[sta_id].
-				ps_status == STA_PS_STATUS_WAKE;
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+	priv->stations[sta_id].sta.sta.modify_mask =
+					STA_MODIFY_SLEEP_TX_COUNT_MSK;
+	priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
+	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-		if (sta_awake && ps_bit)
-			priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
-		else if (!sta_awake && !ps_bit) {
-			iwl_sta_modify_ps_wake(priv, sta_id);
-			priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
-		}
-	}
+	iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 }
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2010-02-24 13:52:17.000000000 -0500
@@ -52,6 +52,7 @@ void iwl_update_tkip_key(struct iwl_priv
 			const u8 *addr, u32 iv32, u16 *phase1key);
 
 int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
+void iwl_add_bcast_station(struct iwl_priv *priv);
 int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
 void iwl_clear_stations_table(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
@@ -65,5 +66,6 @@ void iwl_sta_tx_modify_enable_tid(struct
 int iwl_sta_rx_agg_start(struct iwl_priv *priv,
 			 const u8 *addr, int tid, u16 ssn);
 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
-void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr);
+void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
+void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
 #endif /* __iwl_sta_h__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -97,7 +97,8 @@ int iwl_txq_update_write_ptr(struct iwl_
 		reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
 
 		if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-			IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
+			IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
+				      txq_id, reg);
 			iwl_set_bit(priv, CSR_GP_CNTRL,
 				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 			return ret;
@@ -119,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_
 EXPORT_SYMBOL(iwl_txq_update_write_ptr);
 
 
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+			    int sta_id, int tid, int freed)
+{
+	if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
+		priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+	else {
+		IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+			priv->stations[sta_id].tid[tid].tfds_in_queue,
+			freed);
+		priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
+	}
+}
+EXPORT_SYMBOL(iwl_free_tfds_in_queue);
+
 /**
  * iwl_tx_queue_free - Deallocate DMA queue.
  * @txq: Transmit queue to deallocate.
@@ -132,7 +147,7 @@ void iwl_tx_queue_free(struct iwl_priv *
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
 	struct pci_dev *dev = priv->pci_dev;
-	int i, len;
+	int i;
 
 	if (q->n_bd == 0)
 		return;
@@ -142,8 +157,6 @@ void iwl_tx_queue_free(struct iwl_priv *
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
 		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 
-	len = sizeof(struct iwl_device_cmd) * q->n_window;
-
 	/* De-alloc array of command/tx buffers */
 	for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
 		kfree(txq->cmd[i]);
@@ -181,14 +194,11 @@ void iwl_cmd_queue_free(struct iwl_priv
 	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 	struct iwl_queue *q = &txq->q;
 	struct pci_dev *dev = priv->pci_dev;
-	int i, len;
+	int i;
 
 	if (q->n_bd == 0)
 		return;
 
-	len = sizeof(struct iwl_device_cmd) * q->n_window;
-	len += IWL_MAX_SCAN_SIZE;
-
 	/* De-alloc array of command/tx buffers */
 	for (i = 0; i <= TFD_CMD_SLOTS; i++)
 		kfree(txq->cmd[i]);
@@ -370,8 +380,13 @@ int iwl_tx_queue_init(struct iwl_priv *p
 
 	txq->need_update = 0;
 
-	/* aggregation TX queues will get their ID when aggregation begins */
-	if (txq_id <= IWL_TX_FIFO_AC3)
+	/*
+	 * Aggregation TX queues will get their ID when aggregation begins;
+	 * they overwrite the setting done here. The command FIFO doesn't
+	 * need an swq_id so don't set one to catch errors, all others can
+	 * be set up to the identity mapping.
+	 */
+	if (txq_id != IWL_CMD_QUEUE_NUM)
 		txq->swq_id = txq_id;
 
 	/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -406,15 +421,20 @@ void iwl_hw_txq_ctx_free(struct iwl_priv
 	int txq_id;
 
 	/* Tx queues */
-	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-		if (txq_id == IWL_CMD_QUEUE_NUM)
-			iwl_cmd_queue_free(priv);
-		else
-			iwl_tx_queue_free(priv, txq_id);
-
+	if (priv->txq) {
+		for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
+		     txq_id++)
+			if (txq_id == IWL_CMD_QUEUE_NUM)
+				iwl_cmd_queue_free(priv);
+			else
+				iwl_tx_queue_free(priv, txq_id);
+	}
 	iwl_free_dma_ptr(priv, &priv->kw);
 
 	iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
+
+	/* free tx queue structure */
+	iwl_free_txq_mem(priv);
 }
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
@@ -446,6 +466,12 @@ int iwl_txq_ctx_reset(struct iwl_priv *p
 		IWL_ERR(priv, "Keep Warm allocation failed\n");
 		goto error_kw;
 	}
+
+	/* allocate tx queue structure */
+	ret = iwl_alloc_txq_mem(priv);
+	if (ret)
+		goto error;
+
 	spin_lock_irqsave(&priv->lock, flags);
 
 	/* Turn off all Tx DMA fifos */
@@ -582,9 +608,7 @@ static void iwl_tx_cmd_build_rate(struct
 	u8 rate_plcp;
 
 	/* Set retry limit on DATA packets and Probe Responses*/
-	if (priv->data_retry_limit != -1)
-		data_retry_limit = priv->data_retry_limit;
-	else if (ieee80211_is_probe_resp(fc))
+	if (ieee80211_is_probe_resp(fc))
 		data_retry_limit = 3;
 	else
 		data_retry_limit = IWL_DEFAULT_TX_RETRY;
@@ -701,6 +725,8 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sta *sta = info->control.sta;
+	struct iwl_station_priv *sta_priv = NULL;
 	struct iwl_tx_queue *txq;
 	struct iwl_queue *q;
 	struct iwl_device_cmd *out_cmd;
@@ -710,7 +736,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	dma_addr_t phys_addr;
 	dma_addr_t txcmd_phys;
 	dma_addr_t scratch_phys;
-	u16 len, len_org;
+	u16 len, len_org, firstlen, secondlen;
 	u16 seq_number = 0;
 	__le16 fc;
 	u8 hdr_len;
@@ -763,6 +789,24 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 	IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
 
+	if (sta)
+		sta_priv = (void *)sta->drv_priv;
+
+	if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
+	    sta_priv->asleep) {
+		WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
+		/*
+		 * This sends an asynchronous command to the device,
+		 * but we can rely on it being processed before the
+		 * next frame is processed -- and the next frame to
+		 * this station is the one that will consume this
+		 * counter.
+		 * For now set the counter to just 1 since we do not
+		 * support uAPSD yet.
+		 */
+		iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
+	}
+
 	txq_id = skb_get_queue_mapping(skb);
 	if (ieee80211_is_data_qos(fc)) {
 		qc = ieee80211_get_qos_ctl(hdr);
@@ -843,7 +887,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 		sizeof(struct iwl_cmd_header) + hdr_len;
 
 	len_org = len;
-	len = (len + 3) & ~3;
+	firstlen = len = (len + 3) & ~3;
 
 	if (len_org != len)
 		len_org = 1;
@@ -877,7 +921,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
-	len = skb->len - hdr_len;
+	secondlen = len = skb->len - hdr_len;
 	if (len) {
 		phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
 					   len, PCI_DMA_TODEVICE);
@@ -911,11 +955,28 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
 				       len, PCI_DMA_BIDIRECTIONAL);
 
+	trace_iwlwifi_dev_tx(priv,
+			     &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
+			     sizeof(struct iwl_tfd),
+			     &out_cmd->hdr, firstlen,
+			     skb->data + hdr_len, secondlen);
+
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 	ret = iwl_txq_update_write_ptr(priv, txq);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	/*
+	 * At this point the frame is "transmitted" successfully
+	 * and we will get a TX status notification eventually,
+	 * regardless of the value of ret. "ret" only indicates
+	 * whether or not we should update the write pointer.
+	 */
+
+	/* avoid atomic ops if it isn't an associated client */
+	if (sta_priv && sta_priv->client)
+		atomic_inc(&sta_priv->pending_frames);
+
 	if (ret)
 		return ret;
 
@@ -970,13 +1031,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
 	       !(cmd->flags & CMD_SIZE_HUGE));
 
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
+	if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
+		IWL_WARN(priv, "Not sending command - %s KILL\n",
+			 iwl_is_rfkill(priv) ? "RF" : "CT");
 		return -EIO;
 	}
 
 	if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
-		IWL_ERR(priv, "No space for Tx\n");
+		IWL_ERR(priv, "No space in command queue\n");
+		if (iwl_within_ct_kill_margin(priv))
+			iwl_tt_enter_ct_kill(priv);
+		else {
+			IWL_ERR(priv, "Restarting adapter due to queue full\n");
+			queue_work(priv->workqueue, &priv->restart);
+		}
 		return -ENOSPC;
 	}
 
@@ -1039,6 +1107,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	pci_unmap_addr_set(out_meta, mapping, phys_addr);
 	pci_unmap_len_set(out_meta, len, fix_size);
 
+	trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
+
 	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
 						   phys_addr, fix_size, 1,
 						   U32_PAD(cmd->len));
@@ -1051,12 +1121,31 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	return ret ? ret : idx;
 }
 
+static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_sta *sta;
+	struct iwl_station_priv *sta_priv;
+
+	sta = ieee80211_find_sta(priv->vif, hdr->addr1);
+	if (sta) {
+		sta_priv = (void *)sta->drv_priv;
+		/* avoid atomic ops if this isn't a client */
+		if (sta_priv->client &&
+		    atomic_dec_return(&sta_priv->pending_frames) == 0)
+			ieee80211_sta_block_awake(priv->hw, sta, false);
+	}
+
+	ieee80211_tx_status_irqsafe(priv->hw, skb);
+}
+
 int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 {
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
 	struct iwl_tx_info *tx_info;
 	int nfreed = 0;
+	struct ieee80211_hdr *hdr;
 
 	if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
 		IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
@@ -1070,14 +1159,17 @@ int iwl_tx_queue_reclaim(struct iwl_priv
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
 		tx_info = &txq->txb[txq->q.read_ptr];
-		ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
+		iwl_tx_status(priv, tx_info->skb[0]);
+
+		hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
+		if (hdr && ieee80211_is_data_qos(hdr->frame_control))
+			nfreed++;
 		tx_info->skb[0] = NULL;
 
 		if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
 			priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
 
 		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
-		nfreed++;
 	}
 	return nfreed;
 }
@@ -1105,11 +1197,6 @@ static void iwl_hcmd_queue_reclaim(struc
 		return;
 	}
 
-	pci_unmap_single(priv->pci_dev,
-		pci_unmap_addr(&txq->meta[cmd_idx], mapping),
-		pci_unmap_len(&txq->meta[cmd_idx], len),
-		PCI_DMA_BIDIRECTIONAL);
-
 	for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
@@ -1132,7 +1219,7 @@ static void iwl_hcmd_queue_reclaim(struc
  */
 void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
@@ -1157,12 +1244,17 @@ void iwl_tx_cmd_complete(struct iwl_priv
 	cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
 	meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
 
+	pci_unmap_single(priv->pci_dev,
+			 pci_unmap_addr(meta, mapping),
+			 pci_unmap_len(meta, len),
+			 PCI_DMA_BIDIRECTIONAL);
+
 	/* Input error checking is done when commands are added to queue. */
 	if (meta->flags & CMD_WANT_SKB) {
-		meta->source->reply_skb = rxb->skb;
-		rxb->skb = NULL;
+		meta->source->reply_page = (unsigned long)rxb_addr(rxb);
+		rxb->page = NULL;
 	} else if (meta->callback)
-		meta->callback(priv, cmd, rxb->skb);
+		meta->callback(priv, cmd, pkt);
 
 	iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
 
@@ -1240,7 +1332,7 @@ int iwl_tx_agg_start(struct iwl_priv *pr
 	if (tid_data->tfds_in_queue == 0) {
 		IWL_DEBUG_HT(priv, "HW queue is empty\n");
 		tid_data->agg.state = IWL_AGG_ON;
-		ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+		ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
 	} else {
 		IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
 			     tid_data->tfds_in_queue);
@@ -1280,7 +1372,7 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 	if (priv->stations[sta_id].tid[tid].agg.state ==
 				IWL_EMPTYING_HW_QUEUE_ADDBA) {
 		IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
-		ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+		ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
 		priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
 		return 0;
 	}
@@ -1313,7 +1405,7 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 	if (ret)
 		return ret;
 
-	ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+	ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
 
 	return 0;
 }
@@ -1337,7 +1429,7 @@ int iwl_txq_check_empty(struct iwl_priv
 			priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
 							     ssn, tx_fifo);
 			tid_data->agg.state = IWL_AGG_OFF;
-			ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid);
+			ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
 		}
 		break;
 	case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1345,7 +1437,7 @@ int iwl_txq_check_empty(struct iwl_priv
 		if (tid_data->tfds_in_queue == 0) {
 			IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
 			tid_data->agg.state = IWL_AGG_ON;
-			ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid);
+			ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
 		}
 		break;
 	}
@@ -1409,7 +1501,7 @@ static int iwl_tx_status_reply_compresse
 
 	info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
 	memset(&info->status, 0, sizeof(info->status));
-	info->flags = IEEE80211_TX_STAT_ACK;
+	info->flags |= IEEE80211_TX_STAT_ACK;
 	info->flags |= IEEE80211_TX_STAT_AMPDU;
 	info->status.ampdu_ack_map = successes;
 	info->status.ampdu_ack_len = agg->frame_count;
@@ -1429,7 +1521,7 @@ static int iwl_tx_status_reply_compresse
 void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 					   struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
 	struct iwl_tx_queue *txq = NULL;
 	struct iwl_ht_agg *agg;
@@ -1485,7 +1577,7 @@ void iwl_rx_reply_compressed_ba(struct i
 	if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
 		/* calculate mac80211 ampdu sw queue to wake */
 		int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
-		priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+		iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 		if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 		    priv->mac80211_registered &&
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,17 +1,7 @@
 config IWLWIFI
 	tristate "Intel Wireless Wifi"
-	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-	select LIB80211
+	depends on PCI && MAC80211 && EXPERIMENTAL
 	select FW_LOADER
-	select MAC80211_LEDS if IWLWIFI_LEDS
-	select LEDS_CLASS if IWLWIFI_LEDS
-
-config IWLWIFI_LEDS
-	bool "Enable LED support in iwlagn and iwl3945 drivers"
-	depends on IWLWIFI
-	default y
-	---help---
-	  Select this if you want LED support.
 
 config IWLWIFI_SPECTRUM_MEASUREMENT
 	bool "Enable Spectrum Measurement in iwlagn driver"
@@ -50,6 +40,24 @@ config IWLWIFI_DEBUGFS
         ---help---
 	  Enable creation of debugfs files for the iwlwifi drivers.
 
+config IWLWIFI_DEVICE_TRACING
+	bool "iwlwifi device access tracing"
+	depends on IWLWIFI
+	depends on EVENT_TRACING
+	help
+	  Say Y here to trace all commands, including TX frames and IO
+	  accesses, sent to the device. If you say yes, iwlwifi will
+	  register with the ftrace framework for event tracing and dump
+	  all this information to the ringbuffer, you may need to
+	  increase the ringbuffer size. See the ftrace documentation
+	  for more information.
+
+	  When tracing is not enabled, this option still has some
+	  (though rather small) overhead.
+
+	  If unsure, say Y so we can help you better when problems
+	  occur.
+
 config IWLAGN
 	tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
 	depends on IWLWIFI
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwlwifi/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwlwifi/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,20 +1,22 @@
 obj-$(CONFIG_IWLWIFI)	+= iwlcore.o
 iwlcore-objs 		:= iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
 iwlcore-objs 		+= iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
-iwlcore-objs 		+= iwl-scan.o
+iwlcore-objs 		+= iwl-scan.o iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
-iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
+iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+
+CFLAGS_iwl-devtrace.o := -I$(src)
 
+# AGN
 obj-$(CONFIG_IWLAGN)	+= iwlagn.o
-iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o
+iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
 
 iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
 iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
 iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
 iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
 
+# 3945
 obj-$(CONFIG_IWL3945)	+= iwl3945.o
 iwl3945-objs		:= iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
-
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-02-24 13:52:17.000000000 -0500
@@ -405,39 +405,21 @@ static int iwm_cfg80211_join_ibss(struct
 {
 	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
 	struct ieee80211_channel *chan = params->channel;
-	struct cfg80211_bss *bss;
 
 	if (!test_bit(IWM_STATUS_READY, &iwm->status))
 		return -EIO;
 
-	/* UMAC doesn't support creating IBSS network with specified bssid.
-	 * This should be removed after we have join only mode supported. */
+	/* UMAC doesn't support creating or joining an IBSS network
+	 * with specified bssid. */
 	if (params->bssid)
 		return -EOPNOTSUPP;
 
-	bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
-				params->ssid, params->ssid_len);
-	if (!bss) {
-		iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
-		schedule_timeout_interruptible(2 * HZ);
-		bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
-					params->ssid, params->ssid_len);
-	}
-	/* IBSS join only mode is not supported by UMAC ATM */
-	if (bss) {
-		cfg80211_put_bss(bss);
-		return -EOPNOTSUPP;
-	}
-
 	iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
 	iwm->umac_profile->ibss.band = chan->band;
 	iwm->umac_profile->ibss.channel = iwm->channel;
 	iwm->umac_profile->ssid.ssid_len = params->ssid_len;
 	memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
 
-	if (params->bssid)
-		memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
-
 	return iwm_send_mlme_profile(iwm);
 }
 
@@ -490,12 +472,12 @@ static int iwm_set_wpa_version(struct iw
 		return 0;
 	}
 
+	if (wpa_version & NL80211_WPA_VERSION_1)
+		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
+
 	if (wpa_version & NL80211_WPA_VERSION_2)
 		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
 
-	if (wpa_version & NL80211_WPA_VERSION_1)
-		iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
-
 	return 0;
 }
 
@@ -646,6 +628,13 @@ static int iwm_cfg80211_connect(struct w
 		iwm->default_key = sme->key_idx;
 	}
 
+	/* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
+	if ((iwm->umac_profile->sec.flags &
+	     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
+	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
+			iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
+	}
+
 	ret = iwm_send_mlme_profile(iwm);
 
 	if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
@@ -682,10 +671,24 @@ static int iwm_cfg80211_disconnect(struc
 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
 				    enum tx_power_setting type, int dbm)
 {
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+	int ret;
+
 	switch (type) {
 	case TX_POWER_AUTOMATIC:
 		return 0;
+	case TX_POWER_FIXED:
+		if (!test_bit(IWM_STATUS_READY, &iwm->status))
+			return 0;
+
+		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+					      CFG_TX_PWR_LIMIT_USR, dbm * 2);
+		if (ret < 0)
+			return ret;
+
+		return iwm_tx_power_trigger(iwm);
 	default:
+		IWM_ERR(iwm, "Unsupported power type: %d\n", type);
 		return -EOPNOTSUPP;
 	}
 
@@ -696,7 +699,7 @@ static int iwm_cfg80211_get_txpower(stru
 {
 	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
 
-	*dbm = iwm->txpower;
+	*dbm = iwm->txpower >> 1;
 
 	return 0;
 }
@@ -722,6 +725,33 @@ static int iwm_cfg80211_set_power_mgmt(s
 				       CFG_POWER_INDEX, iwm->conf.power_index);
 }
 
+int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+			   struct cfg80211_pmksa *pmksa)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
+}
+
+int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+			   struct cfg80211_pmksa *pmksa)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
+}
+
+int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+	struct cfg80211_pmksa pmksa;
+
+	memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
+
+	return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
+}
+
+
 static struct cfg80211_ops iwm_cfg80211_ops = {
 	.change_virtual_intf = iwm_cfg80211_change_iface,
 	.add_key = iwm_cfg80211_add_key,
@@ -738,6 +768,9 @@ static struct cfg80211_ops iwm_cfg80211_
 	.set_tx_power = iwm_cfg80211_set_txpower,
 	.get_tx_power = iwm_cfg80211_get_txpower,
 	.set_power_mgmt = iwm_cfg80211_set_power_mgmt,
+	.set_pmksa = iwm_cfg80211_set_pmksa,
+	.del_pmksa = iwm_cfg80211_del_pmksa,
+	.flush_pmksa = iwm_cfg80211_flush_pmksa,
 };
 
 static const u32 cipher_suites[] = {
@@ -783,6 +816,7 @@ struct wireless_dev *iwm_wdev_alloc(int
 
 	set_wiphy_dev(wdev->wiphy, dev);
 	wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
+	wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
 	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 				       BIT(NL80211_IFTYPE_ADHOC);
 	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,6 +77,11 @@ int iwm_send_wifi_if_cmd(struct iwm_priv
 	int ret;
 	u8 oid = hdr->oid;
 
+	if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
+		IWM_ERR(iwm, "Interface is not ready yet");
+		return -EAGAIN;
+	}
+
 	umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
 	umac_cmd.resp = resp;
 
@@ -94,6 +99,10 @@ int iwm_send_wifi_if_cmd(struct iwm_priv
 	return ret;
 }
 
+static int modparam_wiwi = COEX_MODE_CM;
+module_param_named(wiwi, modparam_wiwi, int, 0644);
+MODULE_PARM_DESC(wiwi, "Wifi-WiMAX coexistence: 1=SA, 2=XOR, 3=CM (default)");
+
 static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
 {
 	{4, 3, 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -117,18 +126,18 @@ static struct coex_event iwm_sta_xor_pri
 static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
 {
 	{1, 1, 0, COEX_UNASSOC_IDLE_FLAGS},
-	{4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+	{4, 4, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
 	{3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
-	{5, 5, 0, COEX_CALIBRATION_FLAGS},
+	{6, 6, 0, COEX_CALIBRATION_FLAGS},
 	{3, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
-	{5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS},
+	{6, 5, 0, COEX_CONNECTION_ESTAB_FLAGS},
 	{4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
 	{4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
 	{4, 4, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
 	{4, 4, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
 	{1, 1, 0, COEX_RF_ON_FLAGS},
 	{1, 1, 0, COEX_RF_OFF_FLAGS},
-	{6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+	{7, 7, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
 	{5, 4, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
 	{1, 1, 0, COEX_RSRVD1_FLAGS},
 	{1, 1, 0, COEX_RSRVD2_FLAGS}
@@ -143,7 +152,7 @@ int iwm_send_prio_table(struct iwm_priv
 
 	coex_table_cmd.flags = COEX_FLAGS_STA_TABLE_VALID_MSK;
 
-	switch (iwm->conf.coexist_mode) {
+	switch (modparam_wiwi) {
 	case COEX_MODE_XOR:
 	case COEX_MODE_CM:
 		coex_enabled = 1;
@@ -168,7 +177,7 @@ int iwm_send_prio_table(struct iwm_priv
 					COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK |
 					COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK;
 
-		switch (iwm->conf.coexist_mode) {
+		switch (modparam_wiwi) {
 		case COEX_MODE_XOR:
 			memcpy(coex_table_cmd.sta_prio, iwm_sta_xor_prio_tbl,
 			       sizeof(iwm_sta_xor_prio_tbl));
@@ -179,7 +188,7 @@ int iwm_send_prio_table(struct iwm_priv
 			break;
 		default:
 			IWM_ERR(iwm, "Invalid coex_mode 0x%x\n",
-				iwm->conf.coexist_mode);
+				modparam_wiwi);
 			break;
 		}
 	} else
@@ -187,7 +196,7 @@ int iwm_send_prio_table(struct iwm_priv
 
 	return iwm_send_lmac_ptrough_cmd(iwm, COEX_PRIORITY_TABLE_CMD,
 				&coex_table_cmd,
-				sizeof(struct iwm_coex_prio_table_cmd), 1);
+				sizeof(struct iwm_coex_prio_table_cmd), 0);
 }
 
 int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
@@ -275,6 +284,17 @@ int iwm_send_calib_results(struct iwm_pr
 	return ret;
 }
 
+int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit)
+{
+	struct iwm_ct_kill_cfg_cmd cmd;
+
+	cmd.entry_threshold = entry;
+	cmd.exit_threshold = exit;
+
+	return iwm_send_lmac_ptrough_cmd(iwm, REPLY_CT_KILL_CONFIG_CMD, &cmd,
+					 sizeof(struct iwm_ct_kill_cfg_cmd), 0);
+}
+
 int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
 {
 	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
@@ -380,7 +400,7 @@ int iwm_send_umac_config(struct iwm_priv
 		return ret;
 
 	ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
-				      CFG_COEX_MODE, iwm->conf.coexist_mode);
+				      CFG_COEX_MODE, modparam_wiwi);
 	if (ret < 0)
 		return ret;
 
@@ -778,11 +798,24 @@ int iwm_invalidate_mlme_profile(struct i
 		return ret;
 
 	ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-				(iwm->umac_profile_active == 0), 2 * HZ);
+				(iwm->umac_profile_active == 0), 5 * HZ);
 
 	return ret ? 0 : -EBUSY;
 }
 
+int iwm_tx_power_trigger(struct iwm_priv *iwm)
+{
+	struct iwm_umac_pwr_trigger pwr_trigger;
+
+	pwr_trigger.hdr.oid = UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER;
+	pwr_trigger.hdr.buf_size =
+		cpu_to_le16(sizeof(struct iwm_umac_pwr_trigger) -
+			    sizeof(struct iwm_umac_wifi_if));
+
+
+	return iwm_send_wifi_if_cmd(iwm, &pwr_trigger, sizeof(pwr_trigger), 1);
+}
+
 int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
 {
 	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
@@ -900,3 +933,62 @@ int iwm_target_reset(struct iwm_priv *iw
 
 	return iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
 }
+
+int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm,
+				 struct iwm_umac_notif_stop_resume_tx *ntf)
+{
+	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+	struct iwm_umac_cmd umac_cmd;
+	struct iwm_umac_cmd_stop_resume_tx stp_res_cmd;
+	struct iwm_sta_info *sta_info;
+	u8 sta_id = STA_ID_N_COLOR_ID(ntf->sta_id);
+	int i;
+
+	sta_info = &iwm->sta_table[sta_id];
+	if (!sta_info->valid) {
+		IWM_ERR(iwm, "Invalid STA: %d\n", sta_id);
+		return -EINVAL;
+	}
+
+	umac_cmd.id = UMAC_CMD_OPCODE_STOP_RESUME_STA_TX;
+	umac_cmd.resp = 0;
+
+	stp_res_cmd.flags = ntf->flags;
+	stp_res_cmd.sta_id = ntf->sta_id;
+	stp_res_cmd.stop_resume_tid_msk = ntf->stop_resume_tid_msk;
+	for (i = 0; i < IWM_UMAC_TID_NR; i++)
+		stp_res_cmd.last_seq_num[i] =
+			sta_info->tid_info[i].last_seq_num;
+
+	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &stp_res_cmd,
+				 sizeof(struct iwm_umac_cmd_stop_resume_tx));
+
+}
+
+int iwm_send_pmkid_update(struct iwm_priv *iwm,
+			  struct cfg80211_pmksa *pmksa, u32 command)
+{
+	struct iwm_umac_pmkid_update update;
+	int ret;
+
+	memset(&update, 0, sizeof(struct iwm_umac_pmkid_update));
+
+	update.hdr.oid = UMAC_WIFI_IF_CMD_PMKID_UPDATE;
+	update.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_pmkid_update) -
+					  sizeof(struct iwm_umac_wifi_if));
+
+	update.command = cpu_to_le32(command);
+	if (pmksa->bssid)
+		memcpy(&update.bssid, pmksa->bssid, ETH_ALEN);
+	if (pmksa->pmkid)
+		memcpy(&update.pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
+
+	ret = iwm_send_wifi_if_cmd(iwm, &update,
+				   sizeof(struct iwm_umac_pmkid_update), 0);
+	if (ret) {
+		IWM_ERR(iwm, "PMKID update command failed\n");
+		return ret;
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/commands.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/commands.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/commands.h	2010-02-24 13:52:17.000000000 -0500
@@ -102,7 +102,6 @@ enum {
 	CFG_SCAN_NUM_PASSIVE_CHAN_PER_PARTIAL_SCAN,
 	CFG_TLC_SUPPORTED_TX_HT_RATES,
 	CFG_TLC_SUPPORTED_TX_RATES,
-	CFG_TLC_VALID_ANTENNA,
 	CFG_TLC_SPATIAL_STREAM_SUPPORTED,
 	CFG_TLC_RETRY_PER_RATE,
 	CFG_TLC_RETRY_PER_HT_RATE,
@@ -136,6 +135,10 @@ enum {
 	CFG_TLC_RENEW_ADDBA_DELAY,
 	CFG_TLC_NUM_OF_MULTISEC_TO_COUN_LOAD,
 	CFG_TLC_IS_STABLE_IN_HT,
+	CFG_TLC_SR_SIC_1ST_FAIL,
+	CFG_TLC_SR_SIC_1ST_PASS,
+	CFG_TLC_SR_SIC_TOTAL_FAIL,
+	CFG_TLC_SR_SIC_TOTAL_PASS,
 	CFG_RLC_CHAIN_CTRL,
 	CFG_TRK_TABLE_OP_MODE,
 	CFG_TRK_TABLE_RSSI_THRESHOLD,
@@ -147,6 +150,58 @@ enum {
 	CFG_MLME_DBG_NOTIF_BLOCK,
 	CFG_BT_OFF_BECONS_INTERVALS,
 	CFG_BT_FRAG_DURATION,
+	CFG_ACTIVE_CHAINS,
+	CFG_CALIB_CTRL,
+	CFG_CAPABILITY_SUPPORTED_HT_RATES,
+	CFG_HT_MAC_PARAM_INFO,
+	CFG_MIMO_PS_MODE,
+	CFG_HT_DEFAULT_CAPABILIES_INFO,
+	CFG_LED_SC_RESOLUTION_FACTOR,
+	CFG_PTAM_ENERGY_CCK_DET_DEFAULT,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_DEFAULT,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_DEFAULT,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_DEFAULT,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_DEFAULT,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_DEFAULT,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_DEFAULT,
+	CFG_PTAM_ENERGY_CCK_DET_MIN_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_MIN_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MIN_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_MIN_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MIN_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_MIN_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MIN_VAL,
+	CFG_PTAM_ENERGY_CCK_DET_MAX_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_MAX_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MAX_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_MAX_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MAX_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_MAX_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MAX_VAL,
+	CFG_PTAM_ENERGY_CCK_DET_STEP_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_MRC_STEP_VAL,
+	CFG_PTAM_CORR40_4_TH_ADD_MIN_STEP_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_MRC_STEP_VAL,
+	CFG_PTAM_CORR32_4_TH_ADD_MIN_STEP_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_MRC_STEP_VAL,
+	CFG_PTAM_CORR32_1_TH_ADD_MIN_STEP_VAL,
+	CFG_PTAM_LINK_SENS_FA_OFDM_MAX,
+	CFG_PTAM_LINK_SENS_FA_OFDM_MIN,
+	CFG_PTAM_LINK_SENS_FA_CCK_MAX,
+	CFG_PTAM_LINK_SENS_FA_CCK_MIN,
+	CFG_PTAM_LINK_SENS_NRG_DIFF,
+	CFG_PTAM_LINK_SENS_NRG_MARGIN,
+	CFG_PTAM_LINK_SENS_MAX_NUMBER_OF_TIMES_IN_CCK_NO_FA,
+	CFG_PTAM_LINK_SENS_AUTO_CORR_MAX_TH_CCK,
+	CFG_AGG_MGG_TID_LOAD_ADDBA_THRESHOLD,
+	CFG_AGG_MGG_TID_LOAD_DELBA_THRESHOLD,
+	CFG_AGG_MGG_ADDBA_BUF_SIZE,
+	CFG_AGG_MGG_ADDBA_INACTIVE_TIMEOUT,
+	CFG_AGG_MGG_ADDBA_DEBUG_FLAGS,
+	CFG_SCAN_PERIODIC_RSSI_HIGH_THRESHOLD,
+	CFG_SCAN_PERIODIC_COEF_RSSI_HIGH,
+	CFG_11D_ENABLED,
+	CFG_11H_FEATURE_FLAGS,
 
 	/* <-- LAST --> */
 	CFG_TBL_FIX_LAST
@@ -155,7 +210,8 @@ enum {
 /* variable size table */
 enum {
 	CFG_NET_ADDR = 0,
-	CFG_PROFILE,
+	CFG_LED_PATTERN_TABLE,
+
 	/* <-- LAST --> */
 	CFG_TBL_VAR_LAST
 };
@@ -288,6 +344,9 @@ struct iwm_umac_cmd_scan_request {
 /* iwm_umac_security.flag is WSC mode on -- bits [2:2] */
 #define UMAC_SEC_FLG_WSC_ON_POS		2
 #define UMAC_SEC_FLG_WSC_ON_SEED	1
+#define UMAC_SEC_FLG_WSC_ON_MSK         (UMAC_SEC_FLG_WSC_ON_SEED << \
+					 UMAC_SEC_FLG_WSC_ON_POS)
+
 
 /* Legacy profile can use only WEP40 and WEP104 for encryption and
  * OPEN or PSK for authentication */
@@ -382,10 +441,35 @@ struct iwm_umac_tx_key_id {
 	u8 reserved[3];
 } __attribute__ ((packed));
 
+struct iwm_umac_pwr_trigger {
+	struct iwm_umac_wifi_if hdr;
+	__le32 reseved;
+} __attribute__ ((packed));
+
 struct iwm_umac_cmd_stats_req {
 	__le32 flags;
 } __attribute__ ((packed));
 
+struct iwm_umac_cmd_stop_resume_tx {
+	u8 flags;
+	u8 sta_id;
+	__le16 stop_resume_tid_msk;
+	__le16 last_seq_num[IWM_UMAC_TID_NR];
+	u16 reserved;
+} __attribute__ ((packed));
+
+#define IWM_CMD_PMKID_ADD   1
+#define IWM_CMD_PMKID_DEL   2
+#define IWM_CMD_PMKID_FLUSH 3
+
+struct iwm_umac_pmkid_update {
+	struct iwm_umac_wifi_if hdr;
+	__le32 command;
+	u8 bssid[ETH_ALEN];
+	__le16 reserved;
+	u8 pmkid[WLAN_PMKID_LEN];
+} __attribute__ ((packed));
+
 /* LMAC commands */
 int iwm_read_mac(struct iwm_priv *iwm, u8 *mac);
 int iwm_send_prio_table(struct iwm_priv *iwm);
@@ -393,6 +477,7 @@ int iwm_send_init_calib_cfg(struct iwm_p
 int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
 int iwm_send_calib_results(struct iwm_priv *iwm);
 int iwm_store_rxiq_calib_result(struct iwm_priv *iwm);
+int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit);
 
 /* UMAC commands */
 int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
@@ -407,11 +492,16 @@ int iwm_invalidate_mlme_profile(struct i
 int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
 int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
 int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key);
+int iwm_tx_power_trigger(struct iwm_priv *iwm);
 int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags);
 int iwm_send_umac_channel_list(struct iwm_priv *iwm);
 int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
 		   int ssid_num);
 int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len);
+int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm,
+				 struct iwm_umac_notif_stop_resume_tx *ntf);
+int iwm_send_pmkid_update(struct iwm_priv *iwm,
+			  struct cfg80211_pmksa *pmksa, u32 command);
 
 /* UDMA commands */
 int iwm_target_reset(struct iwm_priv *iwm);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -158,6 +158,29 @@ static ssize_t iwm_debugfs_txq_read(stru
 		}
 
 		spin_unlock_irqrestore(&txq->queue.lock, flags);
+
+		spin_lock_irqsave(&txq->stopped_queue.lock, flags);
+
+		len += snprintf(buf + len, buf_len - len,
+				"\tStopped Queue len:   %d\n",
+				skb_queue_len(&txq->stopped_queue));
+		for (j = 0; j < skb_queue_len(&txq->stopped_queue); j++) {
+			struct iwm_tx_info *tx_info;
+
+			skb = skb->next;
+			tx_info = skb_to_tx_info(skb);
+
+			len += snprintf(buf + len, buf_len - len,
+					"\tSKB #%d\n", j);
+			len += snprintf(buf + len, buf_len - len,
+					"\t\tsta:   %d\n", tx_info->sta);
+			len += snprintf(buf + len, buf_len - len,
+					"\t\tcolor: %d\n", tx_info->color);
+			len += snprintf(buf + len, buf_len - len,
+					"\t\ttid:   %d\n", tx_info->tid);
+		}
+
+		spin_unlock_irqrestore(&txq->stopped_queue.lock, flags);
 	}
 
 	ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,6 +66,10 @@ static struct iwm_eeprom_entry eeprom_ma
 	[IWM_EEPROM_SKU_CAP] =
 	{"SKU capabilities", IWM_EEPROM_SKU_CAP_OFF, IWM_EEPROM_SKU_CAP_LEN},
 
+	[IWM_EEPROM_FAT_CHANNELS_CAP] =
+	{"HT channels capabilities", IWM_EEPROM_FAT_CHANNELS_CAP_OFF,
+	 IWM_EEPROM_FAT_CHANNELS_CAP_LEN},
+
 	[IWM_EEPROM_CALIB_RXIQ_OFFSET] =
 	{"RX IQ offset", IWM_EEPROM_CALIB_RXIQ_OFF, IWM_EEPROM_INDIRECT_LEN},
 
@@ -146,6 +150,52 @@ u8 *iwm_eeprom_access(struct iwm_priv *i
 	return iwm->eeprom + eeprom_map[eeprom_id].offset;
 }
 
+int iwm_eeprom_fat_channels(struct iwm_priv *iwm)
+{
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
+	struct ieee80211_supported_band *band;
+	u16 *channels, i;
+
+	channels = (u16 *)iwm_eeprom_access(iwm, IWM_EEPROM_FAT_CHANNELS_CAP);
+	if (IS_ERR(channels))
+		return PTR_ERR(channels);
+
+	band = wiphy->bands[IEEE80211_BAND_2GHZ];
+	band->ht_cap.ht_supported = true;
+
+	for (i = 0; i < IWM_EEPROM_FAT_CHANNELS_24; i++)
+		if (!(channels[i] & IWM_EEPROM_FAT_CHANNEL_ENABLED))
+			band->ht_cap.ht_supported = false;
+
+	band = wiphy->bands[IEEE80211_BAND_5GHZ];
+	band->ht_cap.ht_supported = true;
+	for (i = IWM_EEPROM_FAT_CHANNELS_24; i < IWM_EEPROM_FAT_CHANNELS; i++)
+		if (!(channels[i] & IWM_EEPROM_FAT_CHANNEL_ENABLED))
+			band->ht_cap.ht_supported = false;
+
+	return 0;
+}
+
+u32 iwm_eeprom_wireless_mode(struct iwm_priv *iwm)
+{
+	u16 sku_cap;
+	u32 wireless_mode = 0;
+
+	sku_cap = *((u16 *)iwm_eeprom_access(iwm, IWM_EEPROM_SKU_CAP));
+
+	if (sku_cap & IWM_EEPROM_SKU_CAP_BAND_24GHZ)
+		wireless_mode |= WIRELESS_MODE_11G;
+
+	if (sku_cap & IWM_EEPROM_SKU_CAP_BAND_52GHZ)
+		wireless_mode |= WIRELESS_MODE_11A;
+
+	if (sku_cap & IWM_EEPROM_SKU_CAP_11N_ENABLE)
+		wireless_mode |= WIRELESS_MODE_11N;
+
+	return wireless_mode;
+}
+
+
 int iwm_eeprom_init(struct iwm_priv *iwm)
 {
 	int i, ret = 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/eeprom.h	2010-02-24 13:52:17.000000000 -0500
@@ -48,6 +48,7 @@ enum {
 	IWM_EEPROM_CARD_ID,
 	IWM_EEPROM_RADIO_CONF,
 	IWM_EEPROM_SKU_CAP,
+	IWM_EEPROM_FAT_CHANNELS_CAP,
 
 	IWM_EEPROM_INDIRECT_OFFSET,
 	IWM_EEPROM_CALIB_RXIQ_OFFSET = IWM_EEPROM_INDIRECT_OFFSET,
@@ -58,14 +59,15 @@ enum {
 	IWM_EEPROM_LAST,
 };
 
-#define IWM_EEPROM_SIG_OFF             0x00
-#define IWM_EEPROM_VERSION_OFF        (0x54 << 1)
-#define IWM_EEPROM_OEM_HW_VERSION_OFF (0x56 << 1)
-#define IWM_EEPROM_MAC_VERSION_OFF    (0x30 << 1)
-#define IWM_EEPROM_CARD_ID_OFF        (0x5d << 1)
-#define IWM_EEPROM_RADIO_CONF_OFF     (0x58 << 1)
-#define IWM_EEPROM_SKU_CAP_OFF        (0x55 << 1)
-#define IWM_EEPROM_CALIB_CONFIG_OFF   (0x7c << 1)
+#define IWM_EEPROM_SIG_OFF                 0x00
+#define IWM_EEPROM_VERSION_OFF            (0x54 << 1)
+#define IWM_EEPROM_OEM_HW_VERSION_OFF     (0x56 << 1)
+#define IWM_EEPROM_MAC_VERSION_OFF        (0x30 << 1)
+#define IWM_EEPROM_CARD_ID_OFF            (0x5d << 1)
+#define IWM_EEPROM_RADIO_CONF_OFF         (0x58 << 1)
+#define IWM_EEPROM_SKU_CAP_OFF            (0x55 << 1)
+#define IWM_EEPROM_CALIB_CONFIG_OFF       (0x7c << 1)
+#define IWM_EEPROM_FAT_CHANNELS_CAP_OFF   (0xde << 1)
 
 #define IWM_EEPROM_SIG_LEN              4
 #define IWM_EEPROM_VERSION_LEN          2
@@ -74,6 +76,7 @@ enum {
 #define IWM_EEPROM_CARD_ID_LEN          2
 #define IWM_EEPROM_RADIO_CONF_LEN       2
 #define IWM_EEPROM_SKU_CAP_LEN          2
+#define IWM_EEPROM_FAT_CHANNELS_CAP_LEN 40
 #define IWM_EEPROM_INDIRECT_LEN		2
 
 #define IWM_MAX_EEPROM_DATA_LEN         240
@@ -87,6 +90,14 @@ enum {
 #define IWM_EEPROM_SKU_CAP_BAND_52GHZ           (1 << 5)
 #define IWM_EEPROM_SKU_CAP_11N_ENABLE           (1 << 6)
 
+#define IWM_EEPROM_FAT_CHANNELS 20
+/* 2.4 gHz FAT primary channels: 1, 2, 3, 4, 5, 6, 7, 8, 9 */
+#define IWM_EEPROM_FAT_CHANNELS_24 9
+/* 5.2 gHz FAT primary channels: 36,44,52,60,100,108,116,124,132,149,157 */
+#define IWM_EEPROM_FAT_CHANNELS_52 11
+
+#define IWM_EEPROM_FAT_CHANNEL_ENABLED (1 << 0)
+
 enum {
 	IWM_EEPROM_CALIB_CAL_HDR,
 	IWM_EEPROM_CALIB_TX_POWER,
@@ -110,5 +121,7 @@ struct iwm_eeprom_entry {
 int iwm_eeprom_init(struct iwm_priv *iwm);
 void iwm_eeprom_exit(struct iwm_priv *iwm);
 u8 *iwm_eeprom_access(struct iwm_priv *iwm, u8 eeprom_id);
+int iwm_eeprom_fat_channels(struct iwm_priv *iwm);
+u32 iwm_eeprom_wireless_mode(struct iwm_priv *iwm);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/fw.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/fw.c	2013-05-03 14:02:30.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/fw.c	2013-05-03 12:10:02.000000000 -0400
@@ -217,6 +217,13 @@ static int iwm_load_img(struct iwm_priv
 		 IWM_BUILD_YEAR(build_date), IWM_BUILD_MONTH(build_date),
 		 IWM_BUILD_DAY(build_date));
 
+	if (!strcmp(img_name, iwm->bus_ops->umac_name))
+		sprintf(iwm->umac_version, "%02X.%02X",
+			ver->major, ver->minor);
+
+	if (!strcmp(img_name, iwm->bus_ops->lmac_name))
+		sprintf(iwm->lmac_version, "%02X.%02X",
+			ver->major, ver->minor);
 
  err_release_fw:
 	release_firmware(fw);
@@ -398,6 +405,8 @@ int iwm_load_fw(struct iwm_priv *iwm)
 	iwm_send_prio_table(iwm);
 	iwm_send_calib_results(iwm);
 	iwm_send_periodic_calib_cfg(iwm, periodic_calib_map);
+	iwm_send_ct_kill_cfg(iwm, iwm->conf.ct_kill_entry,
+			     iwm->conf.ct_kill_exit);
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/hal.c	2010-02-24 13:52:17.000000000 -0500
@@ -411,7 +411,7 @@ static void iwm_build_lmac_hdr(struct iw
 /*
  * iwm_hal_send_host_cmd(): sends commands to the UMAC or the LMAC.
  * Sending command to the LMAC is equivalent to sending a
- * regular UMAC command with the LMAC passtrough or the LMAC
+ * regular UMAC command with the LMAC passthrough or the LMAC
  * wrapper UMAC command IDs.
  */
 int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/iwm.h	2010-02-24 13:52:17.000000000 -0500
@@ -65,6 +65,8 @@ struct iwm_conf {
 	u32 sdio_ior_timeout;
 	unsigned long calib_map;
 	unsigned long expected_calib_map;
+	u8 ct_kill_entry;
+	u8 ct_kill_exit;
 	bool reset_on_fatal_err;
 	bool auto_connect;
 	bool wimax_not_present;
@@ -79,7 +81,6 @@ struct iwm_conf {
 	u32 assoc_timeout;
 	u32 roam_timeout;
 	u32 wireless_mode;
-	u32 coexist_mode;
 
 	u8 ibss_band;
 	u8 ibss_channel;
@@ -129,11 +130,18 @@ struct iwm_notif {
 	unsigned long buf_size;
 };
 
+struct iwm_tid_info {
+	__le16 last_seq_num;
+	bool stopped;
+	struct mutex mutex;
+};
+
 struct iwm_sta_info {
 	u8 addr[ETH_ALEN];
 	bool valid;
 	bool qos;
 	u8 color;
+	struct iwm_tid_info tid_info[IWM_UMAC_TID_NR];
 };
 
 struct iwm_tx_info {
@@ -183,6 +191,8 @@ struct iwm_key {
 struct iwm_tx_queue {
 	int id;
 	struct sk_buff_head queue;
+	struct sk_buff_head stopped_queue;
+	spinlock_t lock;
 	struct workqueue_struct *wq;
 	struct work_struct worker;
 	u8 concat_buf[IWM_HAL_CONCATENATE_BUF_SIZE];
@@ -258,7 +268,7 @@ struct iwm_priv {
 
 	struct sk_buff_head rx_list;
 	struct list_head rx_tickets;
-	struct list_head rx_packets[IWM_RX_ID_HASH];
+	struct list_head rx_packets[IWM_RX_ID_HASH + 1];
 	struct workqueue_struct *rx_wq;
 	struct work_struct rx_worker;
 
@@ -276,12 +286,14 @@ struct iwm_priv {
 	struct iw_statistics wstats;
 	struct delayed_work stats_request;
 	struct delayed_work disconnect;
+	struct delayed_work ct_kill_delay;
 
 	struct iwm_debugfs dbg;
 
 	u8 *eeprom;
 	struct timer_list watchdog;
 	struct work_struct reset_worker;
+	struct work_struct auth_retry_worker;
 	struct mutex mutex;
 
 	u8 *req_ie;
@@ -290,6 +302,8 @@ struct iwm_priv {
 	int resp_ie_len;
 
 	struct iwm_fw_error_hdr *last_fw_err;
+	char umac_version[8];
+	char lmac_version[8];
 
 	char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
 };
@@ -335,6 +349,7 @@ int iwm_up(struct iwm_priv *iwm);
 int iwm_down(struct iwm_priv *iwm);
 
 /* TX API */
+int iwm_tid_to_queue(u16 tid);
 void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages);
 void iwm_tx_worker(struct work_struct *work);
 int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,9 @@
 config IWM
 	tristate "Intel Wireless Multicomm 3200 WiFi driver"
-	depends on MMC && WLAN_80211 && EXPERIMENTAL
+	depends on MMC && EXPERIMENTAL
 	depends on CFG80211
 	select FW_LOADER
+	select IWMC3200TOP
 	help
 	  The Intel Wireless Multicomm 3200 hardware is a combo
 	  card with GPS, Bluetooth, WiMax and 802.11 radios. It
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/lmac.h	2010-02-24 13:52:17.000000000 -0500
@@ -187,6 +187,14 @@ struct iwm_coex_prio_table_cmd {
 				     COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
 				     COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
 
+/* CT kill config command */
+struct iwm_ct_kill_cfg_cmd {
+	u32 exit_threshold;
+	u32 reserved;
+	u32 entry_threshold;
+} __attribute__ ((packed));
+
+
 /* LMAC OP CODES */
 #define REPLY_PAD			0x0
 #define REPLY_ALIVE			0x1
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,9 +64,10 @@ static struct iwm_conf def_iwm_conf = {
 				  BIT(PHY_CALIBRATE_TX_IQ_CMD)	|
 				  BIT(PHY_CALIBRATE_RX_IQ_CMD)	|
 				  BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+	.ct_kill_entry		= 110,
+	.ct_kill_exit		= 110,
 	.reset_on_fatal_err	= 1,
 	.auto_connect		= 1,
-	.wimax_not_present	= 0,
 	.enable_qos		= 1,
 	.mode			= UMAC_MODE_BSS,
 
@@ -78,8 +79,8 @@ static struct iwm_conf def_iwm_conf = {
 
 	.assoc_timeout		= 2,
 	.roam_timeout		= 10,
-	.wireless_mode		= WIRELESS_MODE_11A | WIRELESS_MODE_11G,
-	.coexist_mode		= COEX_MODE_CM,
+	.wireless_mode		= WIRELESS_MODE_11A | WIRELESS_MODE_11G |
+				  WIRELESS_MODE_11N,
 
 	/* IBSS */
 	.ibss_band		= UMAC_BAND_2GHZ,
@@ -92,6 +93,10 @@ static int modparam_reset;
 module_param_named(reset, modparam_reset, bool, 0644);
 MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
 
+static int modparam_wimax_enable = 1;
+module_param_named(wimax_enable, modparam_wimax_enable, bool, 0644);
+MODULE_PARM_DESC(wimax_enable, "Enable wimax core (default 1 [wimax enabled])");
+
 int iwm_mode_to_nl80211_iftype(int mode)
 {
 	switch (mode) {
@@ -134,6 +139,17 @@ static void iwm_disconnect_work(struct w
 	cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
 }
 
+static void iwm_ct_kill_work(struct work_struct *work)
+{
+	struct iwm_priv *iwm =
+		container_of(work, struct iwm_priv, ct_kill_delay.work);
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
+
+	IWM_INFO(iwm, "CT kill delay timeout\n");
+
+	wiphy_rfkill_set_hw_state(wiphy, false);
+}
+
 static int __iwm_up(struct iwm_priv *iwm);
 static int __iwm_down(struct iwm_priv *iwm);
 
@@ -195,6 +211,33 @@ static void iwm_reset_worker(struct work
 	mutex_unlock(&iwm->mutex);
 }
 
+static void iwm_auth_retry_worker(struct work_struct *work)
+{
+	struct iwm_priv *iwm;
+	int i, ret;
+
+	iwm = container_of(work, struct iwm_priv, auth_retry_worker);
+	if (iwm->umac_profile_active) {
+		ret = iwm_invalidate_mlme_profile(iwm);
+		if (ret < 0)
+			return;
+	}
+
+	iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+
+	ret = iwm_send_mlme_profile(iwm);
+	if (ret < 0)
+		return;
+
+	for (i = 0; i < IWM_NUM_KEYS; i++)
+		if (iwm->keys[i].key_len)
+			iwm_set_key(iwm, 0, &iwm->keys[i]);
+
+	iwm_set_tx_key(iwm, iwm->default_key);
+}
+
+
+
 static void iwm_watchdog(unsigned long data)
 {
 	struct iwm_priv *iwm = (struct iwm_priv *)data;
@@ -207,7 +250,7 @@ static void iwm_watchdog(unsigned long d
 
 int iwm_priv_init(struct iwm_priv *iwm)
 {
-	int i;
+	int i, j;
 	char name[32];
 
 	iwm->status = 0;
@@ -226,7 +269,9 @@ int iwm_priv_init(struct iwm_priv *iwm)
 	iwm->scan_id = 1;
 	INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
 	INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
+	INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
 	INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
+	INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
 	INIT_LIST_HEAD(&iwm->bss_list);
 
 	skb_queue_head_init(&iwm->rx_list);
@@ -249,6 +294,8 @@ int iwm_priv_init(struct iwm_priv *iwm)
 			return -EAGAIN;
 
 		skb_queue_head_init(&iwm->txq[i].queue);
+		skb_queue_head_init(&iwm->txq[i].stopped_queue);
+		spin_lock_init(&iwm->txq[i].lock);
 	}
 
 	for (i = 0; i < IWM_NUM_KEYS; i++)
@@ -256,6 +303,12 @@ int iwm_priv_init(struct iwm_priv *iwm)
 
 	iwm->default_key = -1;
 
+	for (i = 0; i < IWM_STA_TABLE_NUM; i++)
+		for (j = 0; j < IWM_UMAC_TID_NR; j++) {
+			mutex_init(&iwm->sta_table[i].tid_info[j].mutex);
+			iwm->sta_table[i].tid_info[j].stopped = false;
+		}
+
 	init_timer(&iwm->watchdog);
 	iwm->watchdog.function = iwm_watchdog;
 	iwm->watchdog.data = (unsigned long)iwm;
@@ -436,7 +489,7 @@ static int iwm_config_boot_params(struct
 	int ret;
 
 	/* check Wimax is off and config debug monitor */
-	if (iwm->conf.wimax_not_present) {
+	if (!modparam_wimax_enable) {
 		u32 data1 = 0x1f;
 		u32 addr1 = 0x606BE258;
 
@@ -529,6 +582,7 @@ void iwm_link_off(struct iwm_priv *iwm)
 
 	for (i = 0; i < IWM_TX_QUEUES; i++) {
 		skb_queue_purge(&iwm->txq[i].queue);
+		skb_queue_purge(&iwm->txq[i].stopped_queue);
 
 		iwm->txq[i].concat_count = 0;
 		iwm->txq[i].concat_ptr = iwm->txq[i].concat_buf;
@@ -587,6 +641,8 @@ static int __iwm_up(struct iwm_priv *iwm
 {
 	int ret;
 	struct iwm_notif *notif_reboot, *notif_ack = NULL;
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
+	u32 wireless_mode;
 
 	ret = iwm_bus_enable(iwm);
 	if (ret) {
@@ -638,6 +694,8 @@ static int __iwm_up(struct iwm_priv *iwm
 		IWM_ERR(iwm, "MAC reading failed\n");
 		goto err_disable;
 	}
+	memcpy(iwm_to_ndev(iwm)->perm_addr, iwm_to_ndev(iwm)->dev_addr,
+		ETH_ALEN);
 
 	/* We can load the FWs */
 	ret = iwm_load_fw(iwm);
@@ -646,6 +704,30 @@ static int __iwm_up(struct iwm_priv *iwm
 		goto err_disable;
 	}
 
+	ret = iwm_eeprom_fat_channels(iwm);
+	if (ret) {
+		IWM_ERR(iwm, "Couldnt read HT channels EEPROM entries\n");
+		goto err_fw;
+	}
+
+	/*
+	 * Read our SKU capabilities.
+	 * If it's valid, we AND the configured wireless mode with the
+	 * device EEPROM value as the current profile wireless mode.
+	 */
+	wireless_mode = iwm_eeprom_wireless_mode(iwm);
+	if (wireless_mode) {
+		iwm->conf.wireless_mode &= wireless_mode;
+		if (iwm->umac_profile)
+			iwm->umac_profile->wireless_mode =
+					iwm->conf.wireless_mode;
+	} else
+		IWM_ERR(iwm, "Wrong SKU capabilities: 0x%x\n",
+			*((u16 *)iwm_eeprom_access(iwm, IWM_EEPROM_SKU_CAP)));
+
+	snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "L%s_U%s",
+		 iwm->lmac_version, iwm->umac_version);
+
 	/* We configure the UMAC and enable the wifi module */
 	ret = iwm_send_umac_config(iwm,
 			cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/netdev.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,6 +76,14 @@ static int iwm_stop(struct net_device *n
  */
 static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
 
+int iwm_tid_to_queue(u16 tid)
+{
+	if (tid > IWM_UMAC_TID_NR - 2)
+		return -EINVAL;
+
+	return iwm_1d_to_queue[tid];
+}
+
 static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
 	skb->priority = cfg80211_classify8021d(skb);
@@ -152,6 +160,7 @@ void iwm_if_free(struct iwm_priv *iwm)
 	if (!iwm_to_ndev(iwm))
 		return;
 
+	cancel_delayed_work_sync(&iwm->ct_kill_delay);
 	free_netdev(iwm_to_ndev(iwm));
 	iwm_priv_deinit(iwm);
 	kfree(iwm->umac_profile);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -423,7 +423,9 @@ static int iwm_ntf_rx_ticket(struct iwm_
 			if (IS_ERR(ticket_node))
 				return PTR_ERR(ticket_node);
 
-			IWM_DBG_RX(iwm, DBG, "TICKET RELEASE(%d)\n",
+			IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
+				   ticket->action ==  IWM_RX_TICKET_RELEASE ?
+				   "RELEASE" : "DROP",
 				   ticket->id);
 			list_add_tail(&ticket_node->node, &iwm->rx_tickets);
 
@@ -500,6 +502,18 @@ static int iwm_mlme_assoc_start(struct i
 	return 0;
 }
 
+static u8 iwm_is_open_wep_profile(struct iwm_priv *iwm)
+{
+	if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
+	     iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
+	    (iwm->umac_profile->sec.ucast_cipher ==
+	     iwm->umac_profile->sec.mcast_cipher) &&
+	    (iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN))
+	       return 1;
+
+       return 0;
+}
+
 static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
 				   unsigned long buf_size,
 				   struct iwm_wifi_cmd *cmd)
@@ -565,11 +579,17 @@ static int iwm_mlme_assoc_complete(struc
 			goto ibss;
 
 		if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
-			cfg80211_connect_result(iwm_to_ndev(iwm),
-						complete->bssid,
-						NULL, 0, NULL, 0,
-						WLAN_STATUS_UNSPECIFIED_FAILURE,
-						GFP_KERNEL);
+			if (!iwm_is_open_wep_profile(iwm)) {
+				cfg80211_connect_result(iwm_to_ndev(iwm),
+					       complete->bssid,
+					       NULL, 0, NULL, 0,
+					       WLAN_STATUS_UNSPECIFIED_FAILURE,
+					       GFP_KERNEL);
+			} else {
+				/* Let's try shared WEP auth */
+				IWM_ERR(iwm, "Trying WEP shared auth\n");
+				schedule_work(&iwm->auth_retry_worker);
+			}
 		else
 			cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
 					      GFP_KERNEL);
@@ -713,6 +733,19 @@ static int iwm_mlme_update_sta_table(str
 	return 0;
 }
 
+static int iwm_mlme_medium_lost(struct iwm_priv *iwm, u8 *buf,
+				unsigned long buf_size,
+				struct iwm_wifi_cmd *cmd)
+{
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
+
+	IWM_DBG_NTF(iwm, DBG, "WiFi/WiMax coexistence radio is OFF\n");
+
+	wiphy_rfkill_set_hw_state(wiphy, true);
+
+	return 0;
+}
+
 static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
 				     unsigned long buf_size,
 				     struct iwm_wifi_cmd *cmd)
@@ -761,7 +794,7 @@ static int iwm_mlme_update_bss_table(str
 	}
 
 	bss->bss = kzalloc(bss_len, GFP_KERNEL);
-	if (!bss) {
+	if (!bss->bss) {
 		kfree(bss);
 		IWM_ERR(iwm, "Couldn't allocate bss\n");
 		return -ENOMEM;
@@ -899,6 +932,8 @@ static int iwm_ntf_mlme(struct iwm_priv
 	case WIFI_IF_NTFY_EXTENDED_IE_REQUIRED:
 		IWM_DBG_MLME(iwm, DBG, "Extended IE required\n");
 		break;
+	case WIFI_IF_NTFY_RADIO_PREEMPTION:
+		return iwm_mlme_medium_lost(iwm, buf, buf_size, cmd);
 	case WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED:
 		return iwm_mlme_update_bss_table(iwm, buf, buf_size, cmd);
 	case WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED:
@@ -1052,12 +1087,83 @@ static int iwm_ntf_channel_info_list(str
 	return 0;
 }
 
+static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf,
+				  unsigned long buf_size,
+				  struct iwm_wifi_cmd *cmd)
+{
+	struct iwm_umac_notif_stop_resume_tx *stp_res_tx =
+		(struct iwm_umac_notif_stop_resume_tx *)buf;
+	struct iwm_sta_info *sta_info;
+	struct iwm_tid_info *tid_info;
+	u8 sta_id = STA_ID_N_COLOR_ID(stp_res_tx->sta_id);
+	u16 tid_msk = le16_to_cpu(stp_res_tx->stop_resume_tid_msk);
+	int bit, ret = 0;
+	bool stop = false;
+
+	IWM_DBG_NTF(iwm, DBG, "stop/resume notification:\n"
+		    "\tflags:       0x%x\n"
+		    "\tSTA id:      %d\n"
+		    "\tTID bitmask: 0x%x\n",
+		    stp_res_tx->flags, stp_res_tx->sta_id,
+		    stp_res_tx->stop_resume_tid_msk);
+
+	if (stp_res_tx->flags & UMAC_STOP_TX_FLAG)
+		stop = true;
+
+	sta_info = &iwm->sta_table[sta_id];
+	if (!sta_info->valid) {
+		IWM_ERR(iwm, "Stoping an invalid STA: %d %d\n",
+			sta_id, stp_res_tx->sta_id);
+		return -EINVAL;
+	}
+
+	for_each_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
+		tid_info = &sta_info->tid_info[bit];
+
+		mutex_lock(&tid_info->mutex);
+		tid_info->stopped = stop;
+		mutex_unlock(&tid_info->mutex);
+
+		if (!stop) {
+			struct iwm_tx_queue *txq;
+			int queue = iwm_tid_to_queue(bit);
+
+			if (queue < 0)
+				continue;
+
+			txq = &iwm->txq[queue];
+			/*
+			 * If we resume, we have to move our SKBs
+			 * back to the tx queue and queue some work.
+			 */
+			spin_lock_bh(&txq->lock);
+			skb_queue_splice_init(&txq->queue, &txq->stopped_queue);
+			spin_unlock_bh(&txq->lock);
+
+			queue_work(txq->wq, &txq->worker);
+		}
+
+	}
+
+	/* We send an ACK only for the stop case */
+	if (stop)
+		ret = iwm_send_umac_stop_resume_tx(iwm, stp_res_tx);
+
+	return ret;
+}
+
 static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
 				   unsigned long buf_size,
 				   struct iwm_wifi_cmd *cmd)
 {
-	struct iwm_umac_wifi_if *hdr =
-			(struct iwm_umac_wifi_if *)cmd->buf.payload;
+	struct iwm_umac_wifi_if *hdr;
+
+	if (cmd == NULL) {
+		IWM_ERR(iwm, "Couldn't find expected wifi command\n");
+		return -EINVAL;
+	}
+
+	hdr = (struct iwm_umac_wifi_if *)cmd->buf.payload;
 
 	IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
 		    "oid is 0x%x\n", hdr->oid);
@@ -1079,6 +1185,7 @@ static int iwm_ntf_wifi_if_wrapper(struc
 	return 0;
 }
 
+#define CT_KILL_DELAY (30 * HZ)
 static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
 			      unsigned long buf_size, struct iwm_wifi_cmd *cmd)
 {
@@ -1091,7 +1198,20 @@ static int iwm_ntf_card_state(struct iwm
 		 flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
 		 flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
 
-	wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED);
+	if (flags & IWM_CARD_STATE_CTKILL_DISABLED) {
+		/*
+		 * We got a CTKILL event: We bring the interface down in
+		 * oder to cool the device down, and try to bring it up
+		 * 30 seconds later. If it's still too hot, we'll go through
+		 * this code path again.
+		 */
+		cancel_delayed_work_sync(&iwm->ct_kill_delay);
+		schedule_delayed_work(&iwm->ct_kill_delay, CT_KILL_DELAY);
+	}
+
+	wiphy_rfkill_set_hw_state(wiphy, flags &
+				  (IWM_CARD_STATE_HW_DISABLED |
+				   IWM_CARD_STATE_CTKILL_DISABLED));
 
 	return 0;
 }
@@ -1282,6 +1402,14 @@ int iwm_rx_handle(struct iwm_priv *iwm,
 
 	switch (le32_to_cpu(hdr->cmd)) {
 	case UMAC_REBOOT_BARKER:
+		if (test_bit(IWM_STATUS_READY, &iwm->status)) {
+			IWM_ERR(iwm, "Unexpected BARKER\n");
+
+			schedule_work(&iwm->reset_worker);
+
+			return 0;
+		}
+
 		return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
 				      IWM_SRC_UDMA, buf, buf_size);
 	case UMAC_ACK_BARKER:
@@ -1308,6 +1436,7 @@ static const iwm_handler iwm_umac_handle
 	[UMAC_NOTIFY_OPCODE_STATS]		= iwm_ntf_statistics,
 	[UMAC_CMD_OPCODE_EEPROM_PROXY]		= iwm_ntf_eeprom_proxy,
 	[UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST]	= iwm_ntf_channel_info_list,
+	[UMAC_CMD_OPCODE_STOP_RESUME_STA_TX]	= iwm_ntf_stop_resume_tx,
 	[REPLY_RX_MPDU_CMD]			= iwm_ntf_rx_packet,
 	[UMAC_CMD_OPCODE_WIFI_IF_WRAPPER]	= iwm_ntf_wifi_if_wrapper,
 };
@@ -1444,11 +1573,12 @@ static void iwm_rx_process_packet(struct
 		}
 		break;
 	case IWM_RX_TICKET_DROP:
-		IWM_DBG_RX(iwm, DBG, "DROP packet\n");
+		IWM_DBG_RX(iwm, DBG, "DROP packet: 0x%x\n",
+			   le16_to_cpu(ticket_node->ticket->flags));
 		kfree_skb(packet->skb);
 		break;
 	default:
-		IWM_ERR(iwm, "Unknow ticket action: %d\n",
+		IWM_ERR(iwm, "Unknown ticket action: %d\n",
 			le16_to_cpu(ticket_node->ticket->action));
 		kfree_skb(packet->skb);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c	2013-05-03 14:02:32.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/sdio.c	2013-05-03 12:10:04.000000000 -0400
@@ -224,8 +224,6 @@ static int if_sdio_disable(struct iwm_pr
 	struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
 	int ret;
 
-	iwm_reset(iwm);
-
 	sdio_claim_host(hw->func);
 	sdio_writeb(hw->func, 0, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
 	if (ret < 0)
@@ -237,6 +235,8 @@ static int if_sdio_disable(struct iwm_pr
 
 	iwm_sdio_rx_free(hw);
 
+	iwm_reset(iwm);
+
 	IWM_DBG_SDIO(iwm, INFO, "IWM SDIO disable\n");
 
 	return 0;
@@ -399,6 +399,7 @@ static struct iwm_if_ops if_sdio_ops = {
 	.calib_lmac_name = "/*(DEBLOBBED)*/",
 	.lmac_name = "/*(DEBLOBBED)*/",
 };
+/*(DEBLOBBED)*/
 
 static int iwm_sdio_probe(struct sdio_func *func,
 			  const struct sdio_device_id *id)
@@ -493,8 +494,10 @@ static void iwm_sdio_remove(struct sdio_
 }
 
 static const struct sdio_device_id iwm_sdio_ids[] = {
-	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
-		      SDIO_DEVICE_ID_INTEL_IWMC3200WIFI) },
+	/* Global/AGN SKU */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1403) },
+	/* BGN SKU */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1408) },
 	{ /* end: all zeroes */	},
 };
 MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -329,7 +329,7 @@ static int iwm_tx_build_packet(struct iw
 
 	memcpy(buf + sizeof(*hdr), skb->data, skb->len);
 
-	return 0;
+	return umac_cmd.seq_num;
 }
 
 static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
@@ -354,16 +354,15 @@ static int iwm_tx_send_concat_packets(st
 	return ret;
 }
 
-#define CONFIG_IWM_TX_CONCATENATED 1
-
 void iwm_tx_worker(struct work_struct *work)
 {
 	struct iwm_priv *iwm;
 	struct iwm_tx_info *tx_info = NULL;
 	struct sk_buff *skb;
-	int cmdlen, ret;
 	struct iwm_tx_queue *txq;
-	int pool_id;
+	struct iwm_sta_info *sta_info;
+	struct iwm_tid_info *tid_info;
+	int cmdlen, ret, pool_id;
 
 	txq = container_of(work, struct iwm_tx_queue, worker);
 	iwm = container_of(txq, struct iwm_priv, txq[txq->id]);
@@ -373,19 +372,46 @@ void iwm_tx_worker(struct work_struct *w
 	while (!test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
 	       !skb_queue_empty(&txq->queue)) {
 
+		spin_lock_bh(&txq->lock);
 		skb = skb_dequeue(&txq->queue);
+		spin_unlock_bh(&txq->lock);
+
 		tx_info = skb_to_tx_info(skb);
+		sta_info = &iwm->sta_table[tx_info->sta];
+		if (!sta_info->valid) {
+			IWM_ERR(iwm, "Trying to send a frame to unknown STA\n");
+			kfree_skb(skb);
+			continue;
+		}
+
+		tid_info = &sta_info->tid_info[tx_info->tid];
+
+		mutex_lock(&tid_info->mutex);
+
+		/*
+		 * If the RAxTID is stopped, we queue the skb to the stopped
+		 * queue.
+		 * Whenever we'll get a UMAC notification to resume the tx flow
+		 * for this RAxTID, we'll merge back the stopped queue into the
+		 * regular queue. See iwm_ntf_stop_resume_tx() from rx.c.
+		 */
+		if (tid_info->stopped) {
+			IWM_DBG_TX(iwm, DBG, "%dx%d stopped\n",
+				   tx_info->sta, tx_info->tid);
+			spin_lock_bh(&txq->lock);
+			skb_queue_tail(&txq->stopped_queue, skb);
+			spin_unlock_bh(&txq->lock);
+
+			mutex_unlock(&tid_info->mutex);
+			continue;
+		}
+
 		cmdlen = IWM_UDMA_HDR_LEN + skb->len;
 
 		IWM_DBG_TX(iwm, DBG, "Tx frame on queue %d: skb: 0x%p, sta: "
 			   "%d, color: %d\n", txq->id, skb, tx_info->sta,
 			   tx_info->color);
 
-#if !CONFIG_IWM_TX_CONCATENATED
-		/* temporarily keep this to comparing the performance */
-		ret = iwm_send_packet(iwm, skb, pool_id);
-#else
-
 		if (txq->concat_count + cmdlen > IWM_HAL_CONCATENATE_BUF_SIZE)
 			iwm_tx_send_concat_packets(iwm, txq);
 
@@ -393,14 +419,21 @@ void iwm_tx_worker(struct work_struct *w
 		if (ret) {
 			IWM_DBG_TX(iwm, DBG, "not enough tx_credit for queue "
 				   "%d, Tx worker stopped\n", txq->id);
+			spin_lock_bh(&txq->lock);
 			skb_queue_head(&txq->queue, skb);
+			spin_unlock_bh(&txq->lock);
+
+			mutex_unlock(&tid_info->mutex);
 			break;
 		}
 
 		txq->concat_ptr = txq->concat_buf + txq->concat_count;
-		iwm_tx_build_packet(iwm, skb, pool_id, txq->concat_ptr);
+		tid_info->last_seq_num =
+			iwm_tx_build_packet(iwm, skb, pool_id, txq->concat_ptr);
 		txq->concat_count += ALIGN(cmdlen, 16);
-#endif
+
+		mutex_unlock(&tid_info->mutex);
+
 		kfree_skb(skb);
 	}
 
@@ -419,14 +452,14 @@ int iwm_xmit_frame(struct sk_buff *skb,
 	struct iwm_priv *iwm = ndev_to_iwm(netdev);
 	struct net_device *ndev = iwm_to_ndev(iwm);
 	struct wireless_dev *wdev = iwm_to_wdev(iwm);
-	u8 *dst_addr;
 	struct iwm_tx_info *tx_info;
 	struct iwm_tx_queue *txq;
 	struct iwm_sta_info *sta_info;
-	u8 sta_id;
+	u8 *dst_addr, sta_id;
 	u16 queue;
 	int ret;
 
+
 	if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
 		IWM_DBG_TX(iwm, DBG, "LINK: stop netif_all_queues: "
 			   "not associated\n");
@@ -440,7 +473,8 @@ int iwm_xmit_frame(struct sk_buff *skb,
 	txq = &iwm->txq[queue];
 
 	/* No free space for Tx, tx_worker is too slow */
-	if (skb_queue_len(&txq->queue) > IWM_TX_LIST_SIZE) {
+	if ((skb_queue_len(&txq->queue) > IWM_TX_LIST_SIZE) ||
+	    (skb_queue_len(&txq->stopped_queue) > IWM_TX_LIST_SIZE)) {
 		IWM_DBG_TX(iwm, DBG, "LINK: stop netif_subqueue[%d]\n", queue);
 		netif_stop_subqueue(netdev, queue);
 		return NETDEV_TX_BUSY;
@@ -477,7 +511,9 @@ int iwm_xmit_frame(struct sk_buff *skb,
 	else
 		tx_info->tid = IWM_UMAC_MGMT_TID;
 
+	spin_lock_bh(&iwm->txq[queue].lock);
 	skb_queue_tail(&iwm->txq[queue].queue, skb);
+	spin_unlock_bh(&iwm->txq[queue].lock);
 
 	queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/umac.h linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/umac.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/iwmc3200wifi/umac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/iwmc3200wifi/umac.h	2010-02-24 13:52:17.000000000 -0500
@@ -83,6 +83,20 @@ struct iwm_udma_out_wifi_hdr {
 	((UMAC_HDI_ACT_TBL_IDX_RA_UMAC << UMAC_HDI_ACT_TBL_IDX_RA_POS) |\
 	(UMAC_HDI_ACT_TBL_IDX_TID_LMAC << UMAC_HDI_ACT_TBL_IDX_TID_POS))
 
+/* STA ID and color */
+#define STA_ID_SEED                        (0x0f)
+#define STA_ID_POS                         (0)
+#define STA_ID_MSK                         (STA_ID_SEED << STA_ID_POS)
+
+#define STA_COLOR_SEED                     (0x7)
+#define STA_COLOR_POS                      (4)
+#define STA_COLOR_MSK                      (STA_COLOR_SEED << STA_COLOR_POS)
+
+#define STA_ID_N_COLOR_COLOR(id_n_color) \
+	(((id_n_color) & STA_COLOR_MSK) >> STA_COLOR_POS)
+#define STA_ID_N_COLOR_ID(id_n_color) \
+	(((id_n_color) & STA_ID_MSK) >> STA_ID_POS)
+
 /* iwm_umac_notif_alive.page_grp_state Group number -- bits [3:0] */
 #define UMAC_ALIVE_PAGE_STS_GRP_NUM_POS		0
 #define UMAC_ALIVE_PAGE_STS_GRP_NUM_SEED	0xF
@@ -260,6 +274,9 @@ struct iwm_udma_out_wifi_hdr {
 #define UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST	0x16
 #define UMAC_CMD_OPCODE_SET_PARAM_LIST		0x17
 #define UMAC_CMD_OPCODE_GET_PARAM_LIST		0x18
+#define UMAC_CMD_OPCODE_STOP_RESUME_STA_TX      0x19
+#define UMAC_CMD_OPCODE_TEST_BLOCK_ACK          0x1A
+
 #define UMAC_CMD_OPCODE_BASE_WRAPPER            0xFA
 #define UMAC_CMD_OPCODE_LMAC_WRAPPER            0xFB
 #define UMAC_CMD_OPCODE_HW_TEST_WRAPPER         0xFC
@@ -281,6 +298,7 @@ struct iwm_udma_out_wifi_hdr {
 #define UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID                0x1B
 #define UMAC_WIFI_IF_CMD_SET_HOST_EXTENDED_IE            0x1C
 #define UMAC_WIFI_IF_CMD_GET_SUPPORTED_CHANNELS          0x1E
+#define UMAC_WIFI_IF_CMD_PMKID_UPDATE                    0x1F
 #define UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER                  0x20
 
 /* UMAC WiFi interface ports */
@@ -687,19 +705,24 @@ struct iwm_umac_notif_rx_ticket {
 /* Tx/Rx rates window (number of max of last update window per second) */
 #define UMAC_NTF_RATE_SAMPLE_NR	4
 
+/* Max numbers of bits required to go through all antennae in bitmasks */
+#define UMAC_PHY_NUM_CHAINS     3
+
 #define IWM_UMAC_MGMT_TID	8
-#define IWM_UMAC_TID_NR		8
+#define IWM_UMAC_TID_NR		9 /* 8 TIDs + MGMT */
 
 struct iwm_umac_notif_stats {
 	struct iwm_umac_wifi_in_hdr hdr;
 	__le32 flags;
 	__le32 timestamp;
-	__le16 tid_load[IWM_UMAC_TID_NR + 2]; /* 1 non-QoS + 1 dword align */
+	__le16 tid_load[IWM_UMAC_TID_NR + 1]; /* 1 non-QoS + 1 dword align */
 	__le16 tx_rate[UMAC_NTF_RATE_SAMPLE_NR];
 	__le16 rx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+	__le32 chain_energy[UMAC_PHY_NUM_CHAINS];
 	s32 rssi_dbm;
 	s32 noise_dbm;
 	__le32 supp_rates;
+	__le32 supp_ht_rates;
 	__le32 missed_beacons;
 	__le32 rx_beacons;
 	__le32 rx_dir_pkts;
@@ -737,6 +760,20 @@ struct iwm_umac_notif_stats {
 	__le32 roam_ap_loadblance;
 } __attribute__ ((packed));
 
+#define UMAC_STOP_TX_FLAG    0x1
+#define UMAC_RESUME_TX_FLAG  0x2
+
+#define LAST_SEQ_NUM_INVALID     0xFFFF
+
+struct iwm_umac_notif_stop_resume_tx {
+	struct iwm_umac_wifi_in_hdr hdr;
+	u8 flags; /* UMAC_*_TX_FLAG_* */
+	u8 sta_id;
+	__le16 stop_resume_tid_msk; /* tid bitmask */
+} __attribute__ ((packed));
+
+#define UMAC_MAX_NUM_PMKIDS 4
+
 /* WiFi interface wrapper header */
 struct iwm_umac_wifi_if {
 	u8 oid;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
 menuconfig WLAN
 	bool "Wireless LAN"
 	depends on !S390
+	select WIRELESS
 	default y
 	---help---
 	  This section contains all the pre 802.11 and 802.11 wireless
@@ -15,114 +16,12 @@ menuconfig WLAN
 
 if WLAN
 
-menuconfig WLAN_PRE80211
-	bool "Wireless LAN (pre-802.11)"
-	depends on NETDEVICES
-	---help---
-	  Say Y if you have any pre-802.11 wireless LAN hardware.
-
-	  This option does not affect the kernel build, it only
-	  lets you choose drivers.
-
-config STRIP
-	tristate "STRIP (Metricom starmode radio IP)"
-	depends on INET && WLAN_PRE80211
-	select WIRELESS_EXT
-	---help---
-	  Say Y if you have a Metricom radio and intend to use Starmode Radio
-	  IP. STRIP is a radio protocol developed for the MosquitoNet project
-	  to send Internet traffic using Metricom radios.  Metricom radios are
-	  small, battery powered, 100kbit/sec packet radio transceivers, about
-	  the size and weight of a cellular telephone. (You may also have heard
-	  them called "Metricom modems" but we avoid the term "modem" because
-	  it misleads many people into thinking that you can plug a Metricom
-	  modem into a phone line and use it as a modem.)
-
-	  You can use STRIP on any Linux machine with a serial port, although
-	  it is obviously most useful for people with laptop computers. If you
-	  think you might get a Metricom radio in the future, there is no harm
-	  in saying Y to STRIP now, except that it makes the kernel a bit
-	  bigger.
-
-	  To compile this as a module, choose M here: the module will be
-	  called strip.
-
-config ARLAN
-	tristate "Aironet Arlan 655 & IC2200 DS support"
-	depends on ISA && !64BIT && WLAN_PRE80211
-	select WIRELESS_EXT
-	---help---
-	  Aironet makes Arlan, a class of wireless LAN adapters. These use the
-	  www.Telxon.com chip, which is also used on several similar cards.
-	  This driver is tested on the 655 and IC2200 series cards. Look at
-	  <http://www.ylenurme.ee/~elmer/655/> for the latest information.
-
-	  The driver is built as two modules, arlan and arlan-proc. The latter
-	  is the /proc interface and is not needed most of time.
-
-	  On some computers the card ends up in non-valid state after some
-	  time. Use a ping-reset script to clear it.
-
-config WAVELAN
-	tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
-	depends on ISA && WLAN_PRE80211
-	select WIRELESS_EXT
-	---help---
-	  The Lucent WaveLAN (formerly NCR and AT&T; or DEC RoamAbout DS) is
-	  a Radio LAN (wireless Ethernet-like Local Area Network) using the
-	  radio frequencies 900 MHz and 2.4 GHz.
-
-	  If you want to use an ISA WaveLAN card under Linux, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. Some more specific
-	  information is contained in
-	  <file:Documentation/networking/wavelan.txt> and in the source code
-	  <file:drivers/net/wireless/wavelan.p.h>.
-
-	  You will also need the wireless tools package available from
-	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-	  Please read the man pages contained therein.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called wavelan.
-
-config PCMCIA_WAVELAN
-	tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
-	depends on PCMCIA && WLAN_PRE80211
-	select WIRELESS_EXT
-	help
-	  Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
-	  (PC-card) wireless Ethernet networking card to your computer.  This
-	  driver is for the non-IEEE-802.11 Wavelan cards.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called wavelan_cs.  If unsure, say N.
-
-config PCMCIA_NETWAVE
-	tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
-	depends on PCMCIA && WLAN_PRE80211
-	select WIRELESS_EXT
-	help
-	  Say Y here if you intend to attach this type of PCMCIA (PC-card)
-	  wireless Ethernet networking card to your computer.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called netwave_cs.  If unsure, say N.
-
-
-menuconfig WLAN_80211
-	bool "Wireless LAN (IEEE 802.11)"
-	depends on NETDEVICES
-	---help---
-	  Say Y if you have any 802.11 wireless LAN hardware.
-
-	  This option does not affect the kernel build, it only
-	  lets you choose drivers.
-
 config PCMCIA_RAYCS
 	tristate "Aviator/Raytheon 2.4GHz wireless support"
-	depends on PCMCIA && WLAN_80211
+	depends on PCMCIA
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	---help---
 	  Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
 	  (PC-card) wireless Ethernet networking card to your computer.
@@ -132,49 +31,9 @@ config PCMCIA_RAYCS
 	  To compile this driver as a module, choose M here: the module will be
 	  called ray_cs.  If unsure, say N.
 
-config LIBERTAS
-	tristate "Marvell 8xxx Libertas WLAN driver support"
-	depends on WLAN_80211
-	select WIRELESS_EXT
-	select LIB80211
-	select FW_LOADER
-	---help---
-	  A library for Marvell Libertas 8xxx devices.
-
-config LIBERTAS_USB
-	tristate "Marvell Libertas 8388 USB 802.11b/g cards"
-	depends on LIBERTAS && USB
-	---help---
-	  A driver for Marvell Libertas 8388 USB devices.
-
-config LIBERTAS_CS
-	tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
-	depends on LIBERTAS && PCMCIA
-	select FW_LOADER
-	---help---
-	  A driver for Marvell Libertas 8385 CompactFlash devices.
-
-config LIBERTAS_SDIO
-	tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
-	depends on LIBERTAS && MMC
-	---help---
-	  A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
-
-config LIBERTAS_SPI
-	tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
-	depends on LIBERTAS && SPI
-	---help---
-	  A driver for Marvell Libertas 8686 SPI devices.
-
-config LIBERTAS_DEBUG
-	bool "Enable full debugging output in the Libertas module."
-	depends on LIBERTAS
-	---help---
-	  Debugging support.
-
 config LIBERTAS_THINFIRM
 	tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware"
-	depends on WLAN_80211 && MAC80211
+	depends on MAC80211
 	select FW_LOADER
 	---help---
 	  A library for Marvell Libertas 8xxx devices using thinfirm.
@@ -187,9 +46,11 @@ config LIBERTAS_THINFIRM_USB
 
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
-	depends on ISA_DMA_API && WLAN_80211 && (PCI || BROKEN)
+	depends on ISA_DMA_API && (PCI || BROKEN)
 	select WIRELESS_EXT
 	select CRYPTO
+	select WEXT_SPY
+	select WEXT_PRIV
 	---help---
 	  This is the standard Linux driver to support Cisco/Aironet ISA and
 	  PCI 802.11 wireless cards.
@@ -205,8 +66,9 @@ config AIRO
 
 config ATMEL
       tristate "Atmel at76c50x chipset  802.11b support"
-      depends on (PCI || PCMCIA) && WLAN_80211
+      depends on (PCI || PCMCIA)
       select WIRELESS_EXT
+      select WEXT_PRIV
       select FW_LOADER
       select CRC32
        ---help---
@@ -239,7 +101,7 @@ config PCMCIA_ATMEL
 
 config AT76C50X_USB
         tristate "Atmel at76c503/at76c505/at76c505a USB cards"
-        depends on MAC80211 && WLAN_80211 && USB
+        depends on MAC80211 && USB
         select FW_LOADER
         ---help---
           Enable support for USB Wireless devices using Atmel at76c503,
@@ -247,8 +109,9 @@ config AT76C50X_USB
 
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
-	depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
+	depends on PCMCIA && (BROKEN || !M32R)
 	select WIRELESS_EXT
+	select WEXT_SPY
 	select CRYPTO
 	select CRYPTO_AES
 	---help---
@@ -266,18 +129,21 @@ config AIRO_CS
 	  Cisco Linux utilities can be used to configure the card.
 
 config PCMCIA_WL3501
-      tristate "Planet WL3501 PCMCIA cards"
-      depends on EXPERIMENTAL && PCMCIA && WLAN_80211
-      select WIRELESS_EXT
-       ---help---
-         A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
-	 It has basic support for Linux wireless extensions and initial
-	 micro support for ethtool.
+	tristate "Planet WL3501 PCMCIA cards"
+	depends on EXPERIMENTAL && PCMCIA
+	select WIRELESS_EXT
+	select WEXT_SPY
+	help
+	  A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
+	  It has basic support for Linux wireless extensions and initial
+	  micro support for ethtool.
 
 config PRISM54
 	tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)'
-	depends on PCI && EXPERIMENTAL && WLAN_80211
+	depends on PCI && EXPERIMENTAL
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	select FW_LOADER
 	---help---
 	  This enables support for FullMAC PCI/Cardbus prism54 devices. This
@@ -298,8 +164,9 @@ config PRISM54
 
 config USB_ZD1201
 	tristate "USB ZD1201 based Wireless device support"
-	depends on USB && WLAN_80211
+	depends on USB
 	select WIRELESS_EXT
+	select WEXT_PRIV
 	select FW_LOADER
 	---help---
 	  Say Y if you want to use wireless LAN adapters based on the ZyDAS
@@ -316,7 +183,7 @@ config USB_ZD1201
 
 config USB_NET_RNDIS_WLAN
 	tristate "Wireless RNDIS USB support"
-	depends on USB && WLAN_80211 && EXPERIMENTAL
+	depends on USB && EXPERIMENTAL
 	depends on CFG80211
 	select USB_USBNET
 	select USB_NET_CDCETHER
@@ -344,7 +211,7 @@ config USB_NET_RNDIS_WLAN
 
 config RTL8180
 	tristate "Realtek 8180/8185 PCI support"
-	depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && PCI && EXPERIMENTAL
 	select EEPROM_93CX6
 	---help---
 	  This is a driver for RTL8180 and RTL8185 based cards.
@@ -400,7 +267,7 @@ config RTL8180
 
 config RTL8187
 	tristate "Realtek 8187 and 8187B USB support"
-	depends on MAC80211 && USB && WLAN_80211
+	depends on MAC80211 && USB
 	select EEPROM_93CX6
 	---help---
 	  This is a driver for RTL8187 and RTL8187B based cards.
@@ -429,7 +296,7 @@ config RTL8187_LEDS
 
 config ADM8211
 	tristate "ADMtek ADM8211 support"
-	depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && PCI && EXPERIMENTAL
 	select CRC32
 	select EEPROM_93CX6
 	---help---
@@ -456,7 +323,7 @@ config ADM8211
 
 config MAC80211_HWSIM
 	tristate "Simulated radio testing tool for mac80211"
-	depends on MAC80211 && WLAN_80211
+	depends on MAC80211
 	---help---
 	  This driver is a developer testing tool that can be used to test
 	  IEEE 802.11 networking stack (mac80211) functionality. This is not
@@ -469,24 +336,25 @@ config MAC80211_HWSIM
 
 config MWL8K
 	tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
-	depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && PCI && EXPERIMENTAL
 	---help---
 	  This driver supports Marvell TOPDOG 802.11 wireless cards.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called mwl8k.  If unsure, say N.
 
-source "drivers/net/wireless/p54/Kconfig"
 source "drivers/net/wireless/ath/Kconfig"
-source "drivers/net/wireless/ipw2x00/Kconfig"
-source "drivers/net/wireless/iwlwifi/Kconfig"
-source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/b43/Kconfig"
 source "drivers/net/wireless/b43legacy/Kconfig"
-source "drivers/net/wireless/zd1211rw/Kconfig"
-source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/hostap/Kconfig"
+source "drivers/net/wireless/ipw2x00/Kconfig"
+source "drivers/net/wireless/iwlwifi/Kconfig"
+source "drivers/net/wireless/iwmc3200wifi/Kconfig"
+source "drivers/net/wireless/libertas/Kconfig"
 source "drivers/net/wireless/orinoco/Kconfig"
+source "drivers/net/wireless/p54/Kconfig"
+source "drivers/net/wireless/rt2x00/Kconfig"
 source "drivers/net/wireless/wl12xx/Kconfig"
-source "drivers/net/wireless/iwmc3200wifi/Kconfig"
+source "drivers/net/wireless/zd1211rw/Kconfig"
 
 endif # WLAN
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/11d.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/11d.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/11d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/11d.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,696 +0,0 @@
-/**
-  * This file contains functions for 802.11D.
-  */
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-#include <linux/wireless.h>
-
-#include "host.h"
-#include "decl.h"
-#include "11d.h"
-#include "dev.h"
-#include "wext.h"
-
-#define TX_PWR_DEFAULT	10
-
-static struct region_code_mapping region_code_mapping[] = {
-	{"US ", 0x10},		/* US FCC      */
-	{"CA ", 0x10},		/* IC Canada   */
-	{"SG ", 0x10},		/* Singapore   */
-	{"EU ", 0x30},		/* ETSI        */
-	{"AU ", 0x30},		/* Australia   */
-	{"KR ", 0x30},		/* Republic Of Korea */
-	{"ES ", 0x31},		/* Spain       */
-	{"FR ", 0x32},		/* France      */
-	{"JP ", 0x40},		/* Japan       */
-};
-
-/* Following 2 structure defines the supported channels */
-static struct chan_freq_power channel_freq_power_UN_BG[] = {
-	{1, 2412, TX_PWR_DEFAULT},
-	{2, 2417, TX_PWR_DEFAULT},
-	{3, 2422, TX_PWR_DEFAULT},
-	{4, 2427, TX_PWR_DEFAULT},
-	{5, 2432, TX_PWR_DEFAULT},
-	{6, 2437, TX_PWR_DEFAULT},
-	{7, 2442, TX_PWR_DEFAULT},
-	{8, 2447, TX_PWR_DEFAULT},
-	{9, 2452, TX_PWR_DEFAULT},
-	{10, 2457, TX_PWR_DEFAULT},
-	{11, 2462, TX_PWR_DEFAULT},
-	{12, 2467, TX_PWR_DEFAULT},
-	{13, 2472, TX_PWR_DEFAULT},
-	{14, 2484, TX_PWR_DEFAULT}
-};
-
-static u8 lbs_region_2_code(u8 *region)
-{
-	u8 i;
-
-	for (i = 0; i < COUNTRY_CODE_LEN && region[i]; i++)
-		region[i] = toupper(region[i]);
-
-	for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
-		if (!memcmp(region, region_code_mapping[i].region,
-			    COUNTRY_CODE_LEN))
-			return (region_code_mapping[i].code);
-	}
-
-	/* default is US */
-	return (region_code_mapping[0].code);
-}
-
-static u8 *lbs_code_2_region(u8 code)
-{
-	u8 i;
-
-	for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
-		if (region_code_mapping[i].code == code)
-			return (region_code_mapping[i].region);
-	}
-	/* default is US */
-	return (region_code_mapping[0].region);
-}
-
-/**
- *  @brief This function finds the nrchan-th chan after the firstchan
- *  @param band       band
- *  @param firstchan  first channel number
- *  @param nrchan   number of channels
- *  @return 	      the nrchan-th chan number
-*/
-static u8 lbs_get_chan_11d(u8 firstchan, u8 nrchan, u8 *chan)
-/*find the nrchan-th chan after the firstchan*/
-{
-	u8 i;
-	struct chan_freq_power *cfp;
-	u8 cfp_no;
-
-	cfp = channel_freq_power_UN_BG;
-	cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG);
-
-	for (i = 0; i < cfp_no; i++) {
-		if ((cfp + i)->channel == firstchan) {
-			lbs_deb_11d("firstchan found\n");
-			break;
-		}
-	}
-
-	if (i < cfp_no) {
-		/*if beyond the boundary */
-		if (i + nrchan < cfp_no) {
-			*chan = (cfp + i + nrchan)->channel;
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  @brief This function Checks if chan txpwr is learned from AP/IBSS
- *  @param chan                 chan number
- *  @param parsed_region_chan   pointer to parsed_region_chan_11d
- *  @return 	                TRUE; FALSE
-*/
-static u8 lbs_channel_known_11d(u8 chan,
-			  struct parsed_region_chan_11d * parsed_region_chan)
-{
-	struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr;
-	u8 nr_chan = parsed_region_chan->nr_chan;
-	u8 i = 0;
-
-	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)chanpwr,
-		sizeof(struct chan_power_11d) * nr_chan);
-
-	for (i = 0; i < nr_chan; i++) {
-		if (chan == chanpwr[i].chan) {
-			lbs_deb_11d("found chan %d\n", chan);
-			return 1;
-		}
-	}
-
-	lbs_deb_11d("chan %d not found\n", chan);
-	return 0;
-}
-
-u32 lbs_chan_2_freq(u8 chan)
-{
-	struct chan_freq_power *cf;
-	u16 i;
-	u32 freq = 0;
-
-	cf = channel_freq_power_UN_BG;
-
-	for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) {
-		if (chan == cf[i].channel)
-			freq = cf[i].freq;
-	}
-
-	return freq;
-}
-
-static int generate_domain_info_11d(struct parsed_region_chan_11d
-				  *parsed_region_chan,
-				  struct lbs_802_11d_domain_reg *domaininfo)
-{
-	u8 nr_subband = 0;
-
-	u8 nr_chan = parsed_region_chan->nr_chan;
-	u8 nr_parsedchan = 0;
-
-	u8 firstchan = 0, nextchan = 0, maxpwr = 0;
-
-	u8 i, flag = 0;
-
-	memcpy(domaininfo->countrycode, parsed_region_chan->countrycode,
-	       COUNTRY_CODE_LEN);
-
-	lbs_deb_11d("nrchan %d\n", nr_chan);
-	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (char *)parsed_region_chan,
-		sizeof(struct parsed_region_chan_11d));
-
-	for (i = 0; i < nr_chan; i++) {
-		if (!flag) {
-			flag = 1;
-			nextchan = firstchan =
-			    parsed_region_chan->chanpwr[i].chan;
-			maxpwr = parsed_region_chan->chanpwr[i].pwr;
-			nr_parsedchan = 1;
-			continue;
-		}
-
-		if (parsed_region_chan->chanpwr[i].chan == nextchan + 1 &&
-		    parsed_region_chan->chanpwr[i].pwr == maxpwr) {
-			nextchan++;
-			nr_parsedchan++;
-		} else {
-			domaininfo->subband[nr_subband].firstchan = firstchan;
-			domaininfo->subband[nr_subband].nrchan =
-			    nr_parsedchan;
-			domaininfo->subband[nr_subband].maxtxpwr = maxpwr;
-			nr_subband++;
-			nextchan = firstchan =
-			    parsed_region_chan->chanpwr[i].chan;
-			maxpwr = parsed_region_chan->chanpwr[i].pwr;
-		}
-	}
-
-	if (flag) {
-		domaininfo->subband[nr_subband].firstchan = firstchan;
-		domaininfo->subband[nr_subband].nrchan = nr_parsedchan;
-		domaininfo->subband[nr_subband].maxtxpwr = maxpwr;
-		nr_subband++;
-	}
-	domaininfo->nr_subband = nr_subband;
-
-	lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
-	lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
-		COUNTRY_CODE_LEN + 1 +
-		sizeof(struct ieee_subbandset) * nr_subband);
-	return 0;
-}
-
-/**
- *  @brief This function generates parsed_region_chan from Domain Info learned from AP/IBSS
- *  @param region_chan          pointer to struct region_channel
- *  @param *parsed_region_chan  pointer to parsed_region_chan_11d
- *  @return 	                N/A
-*/
-static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_chan,
-					  struct parsed_region_chan_11d *
-					  parsed_region_chan)
-{
-	u8 i;
-	struct chan_freq_power *cfp;
-
-	if (region_chan == NULL) {
-		lbs_deb_11d("region_chan is NULL\n");
-		return;
-	}
-
-	cfp = region_chan->CFP;
-	if (cfp == NULL) {
-		lbs_deb_11d("cfp is NULL \n");
-		return;
-	}
-
-	parsed_region_chan->band = region_chan->band;
-	parsed_region_chan->region = region_chan->region;
-	memcpy(parsed_region_chan->countrycode,
-	       lbs_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
-
-	lbs_deb_11d("region 0x%x, band %d\n", parsed_region_chan->region,
-	       parsed_region_chan->band);
-
-	for (i = 0; i < region_chan->nrcfp; i++, cfp++) {
-		parsed_region_chan->chanpwr[i].chan = cfp->channel;
-		parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower;
-		lbs_deb_11d("chan %d, pwr %d\n",
-		       parsed_region_chan->chanpwr[i].chan,
-		       parsed_region_chan->chanpwr[i].pwr);
-	}
-	parsed_region_chan->nr_chan = region_chan->nrcfp;
-
-	lbs_deb_11d("nrchan %d\n", parsed_region_chan->nr_chan);
-
-	return;
-}
-
-/**
- *  @brief generate parsed_region_chan from Domain Info learned from AP/IBSS
- *  @param region               region ID
- *  @param band                 band
- *  @param chan                 chan
- *  @return 	                TRUE;FALSE
-*/
-static u8 lbs_region_chan_supported_11d(u8 region, u8 chan)
-{
-	struct chan_freq_power *cfp;
-	int cfp_no;
-	u8 idx;
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	cfp = lbs_get_region_cfp_table(region, &cfp_no);
-	if (cfp == NULL)
-		return 0;
-
-	for (idx = 0; idx < cfp_no; idx++) {
-		if (chan == (cfp + idx)->channel) {
-			/* If Mrvl Chip Supported? */
-			if ((cfp + idx)->unsupported) {
-				ret = 0;
-			} else {
-				ret = 1;
-			}
-			goto done;
-		}
-	}
-
-	/*chan is not in the region table */
-
-done:
-	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
-	return ret;
-}
-
-/**
- *  @brief This function checks if chan txpwr is learned from AP/IBSS
- *  @param chan                 chan number
- *  @param parsed_region_chan   pointer to parsed_region_chan_11d
- *  @return 	                0
-*/
-static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo,
-				 u8 band,
-				 struct parsed_region_chan_11d *parsed_region_chan)
-{
-	u8 nr_subband, nrchan;
-	u8 lastchan, firstchan;
-	u8 region;
-	u8 curchan = 0;
-
-	u8 idx = 0;		/*chan index in parsed_region_chan */
-
-	u8 j, i;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	/*validation Rules:
-	   1. valid region Code
-	   2. First Chan increment
-	   3. channel range no overlap
-	   4. channel is valid?
-	   5. channel is supported by region?
-	   6. Others
-	 */
-
-	lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
-
-	if ((*(countryinfo->countrycode)) == 0
-	    || (countryinfo->header.len <= COUNTRY_CODE_LEN)) {
-		/* No region Info or Wrong region info: treat as No 11D info */
-		goto done;
-	}
-
-	/*Step1: check region_code */
-	parsed_region_chan->region = region =
-	    lbs_region_2_code(countryinfo->countrycode);
-
-	lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region);
-	lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode,
-		COUNTRY_CODE_LEN);
-
-	parsed_region_chan->band = band;
-
-	memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
-	       COUNTRY_CODE_LEN);
-
-	nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) /
-	    sizeof(struct ieee_subbandset);
-
-	for (j = 0, lastchan = 0; j < nr_subband; j++) {
-
-		if (countryinfo->subband[j].firstchan <= lastchan) {
-			/*Step2&3. Check First Chan Num increment and no overlap */
-			lbs_deb_11d("chan %d>%d, overlap\n",
-			       countryinfo->subband[j].firstchan, lastchan);
-			continue;
-		}
-
-		firstchan = countryinfo->subband[j].firstchan;
-		nrchan = countryinfo->subband[j].nrchan;
-
-		for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) {
-			/*step4: channel is supported? */
-
-			if (!lbs_get_chan_11d(firstchan, i, &curchan)) {
-				/* Chan is not found in UN table */
-				lbs_deb_11d("chan is not supported: %d \n", i);
-				break;
-			}
-
-			lastchan = curchan;
-
-			if (lbs_region_chan_supported_11d(region, curchan)) {
-				/*step5: Check if curchan is supported by mrvl in region */
-				parsed_region_chan->chanpwr[idx].chan = curchan;
-				parsed_region_chan->chanpwr[idx].pwr =
-				    countryinfo->subband[j].maxtxpwr;
-				idx++;
-			} else {
-				/*not supported and ignore the chan */
-				lbs_deb_11d(
-				       "i %d, chan %d unsupported in region %x, band %d\n",
-				       i, curchan, region, band);
-			}
-		}
-
-		/*Step6: Add other checking if any */
-
-	}
-
-	parsed_region_chan->nr_chan = idx;
-
-	lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan);
-	lbs_deb_hex(LBS_DEB_11D, "parsed_region_chan", (u8 *) parsed_region_chan,
-		2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx);
-
-done:
-	lbs_deb_enter(LBS_DEB_11D);
-	return 0;
-}
-
-/**
- *  @brief This function calculates the scan type for channels
- *  @param chan                 chan number
- *  @param parsed_region_chan   pointer to parsed_region_chan_11d
- *  @return 	                PASSIVE if chan is unknown; ACTIVE if chan is known
-*/
-u8 lbs_get_scan_type_11d(u8 chan,
-			  struct parsed_region_chan_11d * parsed_region_chan)
-{
-	u8 scan_type = CMD_SCAN_TYPE_PASSIVE;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	if (lbs_channel_known_11d(chan, parsed_region_chan)) {
-		lbs_deb_11d("found, do active scan\n");
-		scan_type = CMD_SCAN_TYPE_ACTIVE;
-	} else {
-		lbs_deb_11d("not found, do passive scan\n");
-	}
-
-	lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type);
-	return scan_type;
-
-}
-
-void lbs_init_11d(struct lbs_private *priv)
-{
-	priv->enable11d = 0;
-	memset(&(priv->parsed_region_chan), 0,
-	       sizeof(struct parsed_region_chan_11d));
-	return;
-}
-
-/**
- *  @brief This function sets DOMAIN INFO to FW
- *  @param priv       pointer to struct lbs_private
- *  @return 	      0; -1
-*/
-static int set_domain_info_11d(struct lbs_private *priv)
-{
-	int ret;
-
-	if (!priv->enable11d) {
-		lbs_deb_11d("dnld domain Info with 11d disabled\n");
-		return 0;
-	}
-
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
-				    CMD_ACT_SET,
-				    CMD_OPTION_WAITFORRSP, 0, NULL);
-	if (ret)
-		lbs_deb_11d("fail to dnld domain info\n");
-
-	return ret;
-}
-
-/**
- *  @brief This function setups scan channels
- *  @param priv       pointer to struct lbs_private
- *  @param band       band
- *  @return 	      0
-*/
-int lbs_set_universaltable(struct lbs_private *priv, u8 band)
-{
-	u16 size = sizeof(struct chan_freq_power);
-	u16 i = 0;
-
-	memset(priv->universal_channel, 0,
-	       sizeof(priv->universal_channel));
-
-	priv->universal_channel[i].nrcfp =
-	    sizeof(channel_freq_power_UN_BG) / size;
-	lbs_deb_11d("BG-band nrcfp %d\n",
-	       priv->universal_channel[i].nrcfp);
-
-	priv->universal_channel[i].CFP = channel_freq_power_UN_BG;
-	priv->universal_channel[i].valid = 1;
-	priv->universal_channel[i].region = UNIVERSAL_REGION_CODE;
-	priv->universal_channel[i].band = band;
-	i++;
-
-	return 0;
-}
-
-/**
- *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
- *  @param priv       pointer to struct lbs_private
- *  @param cmd        pointer to cmd buffer
- *  @param cmdno      cmd ID
- *  @param cmdOption  cmd action
- *  @return 	      0
-*/
-int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
-				 struct cmd_ds_command *cmd, u16 cmdno,
-				 u16 cmdoption)
-{
-	struct cmd_ds_802_11d_domain_info *pdomaininfo =
-	    &cmd->params.domaininfo;
-	struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
-	u8 nr_subband = priv->domainreg.nr_subband;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	lbs_deb_11d("nr_subband=%x\n", nr_subband);
-
-	cmd->command = cpu_to_le16(cmdno);
-	pdomaininfo->action = cpu_to_le16(cmdoption);
-	if (cmdoption == CMD_ACT_GET) {
-		cmd->size =
-		    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
-		lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
-			le16_to_cpu(cmd->size));
-		goto done;
-	}
-
-	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
-	memcpy(domain->countrycode, priv->domainreg.countrycode,
-	       sizeof(domain->countrycode));
-
-	domain->header.len =
-	    cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) +
-			     sizeof(domain->countrycode));
-
-	if (nr_subband) {
-		memcpy(domain->subband, priv->domainreg.subband,
-		       nr_subband * sizeof(struct ieee_subbandset));
-
-		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
-					     le16_to_cpu(domain->header.len) +
-					     sizeof(struct mrvl_ie_header) +
-					     S_DS_GEN);
-	} else {
-		cmd->size =
-		    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
-	}
-
-	lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, le16_to_cpu(cmd->size));
-
-done:
-	lbs_deb_enter(LBS_DEB_11D);
-	return 0;
-}
-
-/**
- *  @brief This function parses countryinfo from AP and download country info to FW
- *  @param priv    pointer to struct lbs_private
- *  @param resp    pointer to command response buffer
- *  @return 	   0; -1
- */
-int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
-	struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
-	u16 action = le16_to_cpu(domaininfo->action);
-	s16 ret = 0;
-	u8 nr_subband = 0;
-
-	lbs_deb_enter(LBS_DEB_11D);
-
-	lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
-		(int)le16_to_cpu(resp->size));
-
-	nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
-		      sizeof(struct ieee_subbandset);
-
-	lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
-
-	if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) {
-		lbs_deb_11d("Invalid Numrer of Subband returned!!\n");
-		return -1;
-	}
-
-	switch (action) {
-	case CMD_ACT_SET:	/*Proc Set action */
-		break;
-
-	case CMD_ACT_GET:
-		break;
-	default:
-		lbs_deb_11d("Invalid action:%d\n", domaininfo->action);
-		ret = -1;
-		break;
-	}
-
-	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
-	return ret;
-}
-
-/**
- *  @brief This function parses countryinfo from AP and download country info to FW
- *  @param priv    pointer to struct lbs_private
- *  @return 	   0; -1
- */
-int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
-                                        struct bss_descriptor * bss)
-{
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_11D);
-	if (priv->enable11d) {
-		memset(&priv->parsed_region_chan, 0,
-		       sizeof(struct parsed_region_chan_11d));
-		ret = parse_domain_info_11d(&bss->countryinfo, 0,
-					       &priv->parsed_region_chan);
-
-		if (ret == -1) {
-			lbs_deb_11d("error parsing domain_info from AP\n");
-			goto done;
-		}
-
-		memset(&priv->domainreg, 0,
-		       sizeof(struct lbs_802_11d_domain_reg));
-		generate_domain_info_11d(&priv->parsed_region_chan,
-				      &priv->domainreg);
-
-		ret = set_domain_info_11d(priv);
-
-		if (ret) {
-			lbs_deb_11d("error setting domain info\n");
-			goto done;
-		}
-	}
-	ret = 0;
-
-done:
-	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
-	return ret;
-}
-
-/**
- *  @brief This function generates 11D info from user specified regioncode and download to FW
- *  @param priv    pointer to struct lbs_private
- *  @return 	   0; -1
- */
-int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv)
-{
-	int ret;
-	struct region_channel *region_chan;
-	u8 j;
-
-	lbs_deb_enter(LBS_DEB_11D);
-	lbs_deb_11d("curbssparams.band %d\n", priv->curbssparams.band);
-
-	if (priv->enable11d) {
-		/* update parsed_region_chan_11; dnld domaininf to FW */
-
-		for (j = 0; j < ARRAY_SIZE(priv->region_channel); j++) {
-			region_chan = &priv->region_channel[j];
-
-			lbs_deb_11d("%d region_chan->band %d\n", j,
-			       region_chan->band);
-
-			if (!region_chan || !region_chan->valid
-			    || !region_chan->CFP)
-				continue;
-			if (region_chan->band != priv->curbssparams.band)
-				continue;
-			break;
-		}
-
-		if (j >= ARRAY_SIZE(priv->region_channel)) {
-			lbs_deb_11d("region_chan not found, band %d\n",
-			       priv->curbssparams.band);
-			ret = -1;
-			goto done;
-		}
-
-		memset(&priv->parsed_region_chan, 0,
-		       sizeof(struct parsed_region_chan_11d));
-		lbs_generate_parsed_region_chan_11d(region_chan,
-						     &priv->
-						     parsed_region_chan);
-
-		memset(&priv->domainreg, 0,
-		       sizeof(struct lbs_802_11d_domain_reg));
-		generate_domain_info_11d(&priv->parsed_region_chan,
-					 &priv->domainreg);
-
-		ret = set_domain_info_11d(priv);
-
-		if (ret) {
-			lbs_deb_11d("error setting domain info\n");
-			goto done;
-		}
-
-	}
-	ret = 0;
-
-done:
-	lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
-	return ret;
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/11d.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/11d.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/11d.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/11d.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-/**
-  * This header file contains data structures and
-  * function declarations of 802.11d
-  */
-#ifndef _LBS_11D_
-#define _LBS_11D_
-
-#include "types.h"
-#include "defs.h"
-
-#define UNIVERSAL_REGION_CODE			0xff
-
-/** (Beaconsize(256)-5(IEId,len,contrystr(3))/3(FirstChan,NoOfChan,MaxPwr)
- */
-#define MRVDRV_MAX_SUBBAND_802_11D		83
-
-#define COUNTRY_CODE_LEN			3
-#define MAX_NO_OF_CHAN 				40
-
-struct cmd_ds_command;
-
-/** Data structure for Country IE*/
-struct ieee_subbandset {
-	u8 firstchan;
-	u8 nrchan;
-	u8 maxtxpwr;
-} __attribute__ ((packed));
-
-struct ieee_ie_country_info_set {
-	struct ieee_ie_header header;
-
-	u8 countrycode[COUNTRY_CODE_LEN];
-	struct ieee_subbandset subband[1];
-};
-
-struct ieee_ie_country_info_full_set {
-	struct ieee_ie_header header;
-
-	u8 countrycode[COUNTRY_CODE_LEN];
-	struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
-} __attribute__ ((packed));
-
-struct mrvl_ie_domain_param_set {
-	struct mrvl_ie_header header;
-
-	u8 countrycode[COUNTRY_CODE_LEN];
-	struct ieee_subbandset subband[1];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11d_domain_info {
-	__le16 action;
-	struct mrvl_ie_domain_param_set domain;
-} __attribute__ ((packed));
-
-/** domain regulatory information */
-struct lbs_802_11d_domain_reg {
-	/** country Code*/
-	u8 countrycode[COUNTRY_CODE_LEN];
-	/** No. of subband*/
-	u8 nr_subband;
-	struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
-};
-
-struct chan_power_11d {
-	u8 chan;
-	u8 pwr;
-} __attribute__ ((packed));
-
-struct parsed_region_chan_11d {
-	u8 band;
-	u8 region;
-	s8 countrycode[COUNTRY_CODE_LEN];
-	struct chan_power_11d chanpwr[MAX_NO_OF_CHAN];
-	u8 nr_chan;
-} __attribute__ ((packed));
-
-struct region_code_mapping {
-	u8 region[COUNTRY_CODE_LEN];
-	u8 code;
-};
-
-struct lbs_private;
-
-u8 lbs_get_scan_type_11d(u8 chan,
-			  struct parsed_region_chan_11d *parsed_region_chan);
-
-u32 lbs_chan_2_freq(u8 chan);
-
-void lbs_init_11d(struct lbs_private *priv);
-
-int lbs_set_universaltable(struct lbs_private *priv, u8 band);
-
-int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
-				 struct cmd_ds_command *cmd, u16 cmdno,
-				 u16 cmdOption);
-
-int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp);
-
-struct bss_descriptor;
-int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
-                                        struct bss_descriptor * bss);
-
-int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/assoc.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/assoc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,13 @@ static const u8 bssid_off[ETH_ALEN]  __a
  */
 #define CAPINFO_MASK	(~(0xda00))
 
+/**
+ * 802.11b/g supported bitrates (in 500Kb/s units)
+ */
+u8 lbs_bg_rates[MAX_RATES] =
+    { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
+0x00, 0x00 };
+
 
 /**
  *  @brief This function finds common rates between rates and card rates.
@@ -147,6 +154,397 @@ static int lbs_set_authentication(struct
 }
 
 
+int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
+			   struct assoc_request *assoc)
+{
+	struct cmd_ds_802_11_set_wep cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+	cmd.action = cpu_to_le16(cmd_action);
+
+	if (cmd_action == CMD_ACT_ADD) {
+		int i;
+
+		/* default tx key index */
+		cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
+					   CMD_WEP_KEY_INDEX_MASK);
+
+		/* Copy key types and material to host command structure */
+		for (i = 0; i < 4; i++) {
+			struct enc_key *pkey = &assoc->wep_keys[i];
+
+			switch (pkey->len) {
+			case KEY_LEN_WEP_40:
+				cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
+				memmove(cmd.keymaterial[i], pkey->key, pkey->len);
+				lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
+				break;
+			case KEY_LEN_WEP_104:
+				cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
+				memmove(cmd.keymaterial[i], pkey->key, pkey->len);
+				lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
+				break;
+			case 0:
+				break;
+			default:
+				lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
+					    i, pkey->len);
+				ret = -1;
+				goto done;
+				break;
+			}
+		}
+	} else if (cmd_action == CMD_ACT_REMOVE) {
+		/* ACT_REMOVE clears _all_ WEP keys */
+
+		/* default tx key index */
+		cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
+					   CMD_WEP_KEY_INDEX_MASK);
+		lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
+	}
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
+done:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
+			      uint16_t *enable)
+{
+	struct cmd_ds_802_11_enable_rsn cmd;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(cmd_action);
+
+	if (cmd_action == CMD_ACT_GET)
+		cmd.enable = 0;
+	else {
+		if (*enable)
+			cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
+		else
+			cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
+		lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
+	}
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
+	if (!ret && cmd_action == CMD_ACT_GET)
+		*enable = le16_to_cpu(cmd.enable);
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
+		struct enc_key *key)
+{
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (key->flags & KEY_INFO_WPA_ENABLED)
+		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
+	if (key->flags & KEY_INFO_WPA_UNICAST)
+		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
+	if (key->flags & KEY_INFO_WPA_MCAST)
+		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
+
+	keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+	keyparam->keytypeid = cpu_to_le16(key->type);
+	keyparam->keylen = cpu_to_le16(key->len);
+	memcpy(keyparam->key, key->key, key->len);
+
+	/* Length field doesn't include the {type,length} header */
+	keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
+	lbs_deb_leave(LBS_DEB_CMD);
+}
+
+int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
+				struct assoc_request *assoc)
+{
+	struct cmd_ds_802_11_key_material cmd;
+	int ret = 0;
+	int index = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	cmd.action = cpu_to_le16(cmd_action);
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+	if (cmd_action == CMD_ACT_GET) {
+		cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2);
+	} else {
+		memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
+
+		if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
+			set_one_wpa_key(&cmd.keyParamSet[index],
+					&assoc->wpa_unicast_key);
+			index++;
+		}
+
+		if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
+			set_one_wpa_key(&cmd.keyParamSet[index],
+					&assoc->wpa_mcast_key);
+			index++;
+		}
+
+		/* The common header and as many keys as we included */
+		cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
+						    keyParamSet[index]));
+	}
+	ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
+	/* Copy the returned key to driver private data */
+	if (!ret && cmd_action == CMD_ACT_GET) {
+		void *buf_ptr = cmd.keyParamSet;
+		void *resp_end = &(&cmd)[1];
+
+		while (buf_ptr < resp_end) {
+			struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
+			struct enc_key *key;
+			uint16_t param_set_len = le16_to_cpu(keyparam->length);
+			uint16_t key_len = le16_to_cpu(keyparam->keylen);
+			uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
+			uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
+			void *end;
+
+			end = (void *)keyparam + sizeof(keyparam->type)
+				+ sizeof(keyparam->length) + param_set_len;
+
+			/* Make sure we don't access past the end of the IEs */
+			if (end > resp_end)
+				break;
+
+			if (key_flags & KEY_INFO_WPA_UNICAST)
+				key = &priv->wpa_unicast_key;
+			else if (key_flags & KEY_INFO_WPA_MCAST)
+				key = &priv->wpa_mcast_key;
+			else
+				break;
+
+			/* Copy returned key into driver */
+			memset(key, 0, sizeof(struct enc_key));
+			if (key_len > sizeof(key->key))
+				break;
+			key->type = key_type;
+			key->flags = key_flags;
+			key->len = key_len;
+			memcpy(key->key, keyparam->key, key->len);
+
+			buf_ptr = end + 1;
+		}
+	}
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
+{
+/*		Bit  	Rate
+*		15:13 Reserved
+*		12    54 Mbps
+*		11    48 Mbps
+*		10    36 Mbps
+*		9     24 Mbps
+*		8     18 Mbps
+*		7     12 Mbps
+*		6     9 Mbps
+*		5     6 Mbps
+*		4     Reserved
+*		3     11 Mbps
+*		2     5.5 Mbps
+*		1     2 Mbps
+*		0     1 Mbps
+**/
+
+	uint16_t ratemask;
+	int i = lbs_data_rate_to_fw_index(rate);
+	if (lower_rates_ok)
+		ratemask = (0x1fef >> (12 - i));
+	else
+		ratemask = (1 << i);
+	return cpu_to_le16(ratemask);
+}
+
+int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
+				      uint16_t cmd_action)
+{
+	struct cmd_ds_802_11_rate_adapt_rateset cmd;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (!priv->cur_rate && !priv->enablehwauto)
+		return -EINVAL;
+
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+	cmd.action = cpu_to_le16(cmd_action);
+	cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
+	cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
+	if (!ret && cmd_action == CMD_ACT_GET) {
+		priv->ratebitmap = le16_to_cpu(cmd.bitmap);
+		priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
+	}
+
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Set the data rate
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param rate  	The desired data rate, or 0 to clear a locked rate
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
+{
+	struct cmd_ds_802_11_data_rate cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+	if (rate > 0) {
+		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
+		cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
+		if (cmd.rates[0] == 0) {
+			lbs_deb_cmd("DATA_RATE: invalid requested rate of"
+				" 0x%02X\n", rate);
+			ret = 0;
+			goto out;
+		}
+		lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
+	} else {
+		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
+		lbs_deb_cmd("DATA_RATE: setting auto\n");
+	}
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
+	if (ret)
+		goto out;
+
+	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd));
+
+	/* FIXME: get actual rates FW can do if this command actually returns
+	 * all data rates supported.
+	 */
+	priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
+	lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+
+int lbs_cmd_802_11_rssi(struct lbs_private *priv,
+				struct cmd_ds_command *cmd)
+{
+
+	lbs_deb_enter(LBS_DEB_CMD);
+	cmd->command = cpu_to_le16(CMD_802_11_RSSI);
+	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) +
+		sizeof(struct cmd_header));
+	cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
+
+	/* reset Beacon SNR/NF/RSSI values */
+	priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
+	priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
+	priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
+	priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
+	priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
+	priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+int lbs_ret_802_11_rssi(struct lbs_private *priv,
+				struct cmd_ds_command *resp)
+{
+	struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	/* store the non average value */
+	priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
+	priv->NF[TYPE_BEACON][TYPE_NOAVG] =
+		get_unaligned_le16(&rssirsp->noisefloor);
+
+	priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
+	priv->NF[TYPE_BEACON][TYPE_AVG] =
+		get_unaligned_le16(&rssirsp->avgnoisefloor);
+
+	priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
+	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
+		     priv->NF[TYPE_BEACON][TYPE_NOAVG]);
+
+	priv->RSSI[TYPE_BEACON][TYPE_AVG] =
+	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
+		     priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
+
+	lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
+	       priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
+	       priv->RSSI[TYPE_BEACON][TYPE_AVG]);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+
+int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
+				struct cmd_ds_command *cmd,
+				u16 cmd_action)
+{
+	struct cmd_ds_802_11_beacon_control
+		*bcn_ctrl = &cmd->params.bcn_ctrl;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+	cmd->size =
+	    cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
+			     + sizeof(struct cmd_header));
+	cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
+
+	bcn_ctrl->action = cpu_to_le16(cmd_action);
+	bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
+	bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
+					struct cmd_ds_command *resp)
+{
+	struct cmd_ds_802_11_beacon_control *bcn_ctrl =
+	    &resp->params.bcn_ctrl;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (bcn_ctrl->action == CMD_ACT_GET) {
+		priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
+		priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
+	}
+
+	lbs_deb_enter(LBS_DEB_CMD);
+	return 0;
+}
+
+
+
 static int lbs_assoc_post(struct lbs_private *priv,
 			  struct cmd_ds_802_11_associate_response *resp)
 {
@@ -226,7 +624,7 @@ static int lbs_assoc_post(struct lbs_pri
 	priv->connect_status = LBS_CONNECTED;
 
 	/* Update current SSID and BSSID */
-	memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+	memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN);
 	priv->curbssparams.ssid_len = bss->ssid_len;
 	memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
 
@@ -369,12 +767,7 @@ static int lbs_associate(struct lbs_priv
 				   (u16)(pos - (u8 *) &cmd.iebuf));
 
 	/* update curbssparams */
-	priv->curbssparams.channel = bss->phy.ds.channel;
-
-	if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
-		ret = -1;
-		goto done;
-	}
+	priv->channel = bss->phy.ds.channel;
 
 	ret = lbs_cmd_with_response(priv, command, &cmd);
 	if (ret == 0) {
@@ -472,7 +865,7 @@ static int lbs_adhoc_post(struct lbs_pri
 	memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
 
 	/* Set the new SSID to current SSID */
-	memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+	memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN);
 	priv->curbssparams.ssid_len = bss->ssid_len;
 
 	netif_carrier_on(priv->dev);
@@ -487,7 +880,7 @@ static int lbs_adhoc_post(struct lbs_pri
 	lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
 		     print_ssid(ssid, bss->ssid, bss->ssid_len),
 		     priv->curbssparams.bssid,
-		     priv->curbssparams.channel);
+		     priv->channel);
 
 done:
 	lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
@@ -560,7 +953,7 @@ static int lbs_adhoc_join(struct lbs_pri
 	lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
 
 	priv->adhoccreate = 0;
-	priv->curbssparams.channel = bss->channel;
+	priv->channel = bss->channel;
 
 	/* Build the join command */
 	memset(&cmd, 0, sizeof(cmd));
@@ -633,11 +1026,6 @@ static int lbs_adhoc_join(struct lbs_pri
 		}
 	}
 
-	if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
-		ret = -1;
-		goto out;
-	}
-
 	ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
 	if (ret == 0) {
 		ret = lbs_adhoc_post(priv,
@@ -737,12 +1125,6 @@ static int lbs_adhoc_start(struct lbs_pr
 	lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n",
 	       cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]);
 
-	if (lbs_create_dnld_countryinfo_11d(priv)) {
-		lbs_deb_join("ADHOC_START: dnld_countryinfo_11d failed\n");
-		ret = -1;
-		goto out;
-	}
-
 	lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n",
 		     assoc_req->channel, assoc_req->band);
 
@@ -1099,7 +1481,7 @@ static int assoc_helper_essid(struct lbs
 			/* else send START command */
 			lbs_deb_assoc("SSID not found, creating adhoc network\n");
 			memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
-				IW_ESSID_MAX_SIZE);
+				IEEE80211_MAX_SSID_LEN);
 			assoc_req->bss.ssid_len = assoc_req->ssid_len;
 			lbs_adhoc_start(priv, assoc_req);
 		}
@@ -1185,7 +1567,8 @@ static int assoc_helper_mode(struct lbs_
 	}
 
 	priv->mode = assoc_req->mode;
-	ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, assoc_req->mode);
+	ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE,
+		assoc_req->mode == IW_MODE_ADHOC ? 2 : 1);
 
 done:
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -1205,7 +1588,7 @@ static int assoc_helper_channel(struct l
 		goto done;
 	}
 
-	if (assoc_req->channel == priv->curbssparams.channel)
+	if (assoc_req->channel == priv->channel)
 		goto done;
 
 	if (priv->mesh_dev) {
@@ -1217,7 +1600,7 @@ static int assoc_helper_channel(struct l
 	}
 
 	lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
-		      priv->curbssparams.channel, assoc_req->channel);
+		      priv->channel, assoc_req->channel);
 
 	ret = lbs_set_channel(priv, assoc_req->channel);
 	if (ret < 0)
@@ -1232,7 +1615,7 @@ static int assoc_helper_channel(struct l
 		goto done;
 	}
 
-	if (assoc_req->channel != priv->curbssparams.channel) {
+	if (assoc_req->channel != priv->channel) {
 		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
 		              assoc_req->channel);
 		goto restore_mesh;
@@ -1253,7 +1636,7 @@ static int assoc_helper_channel(struct l
  restore_mesh:
 	if (priv->mesh_dev)
 		lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-				priv->curbssparams.channel);
+				priv->channel);
 
  done:
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -1475,7 +1858,7 @@ static int should_stop_adhoc(struct lbs_
 	}
 
 	if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
-		if (assoc_req->channel != priv->curbssparams.channel)
+		if (assoc_req->channel != priv->channel)
 			return 1;
 	}
 
@@ -1557,7 +1940,7 @@ static int lbs_find_best_network_ssid(st
 
 	found = lbs_find_best_ssid_in_list(priv, preferred_mode);
 	if (found && (found->ssid_len > 0)) {
-		memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
+		memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN);
 		*out_ssid_len = found->ssid_len;
 		*out_mode = found->mode;
 		ret = 0;
@@ -1775,12 +2158,12 @@ struct assoc_request *lbs_get_associatio
 	assoc_req = priv->pending_assoc_req;
 	if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
 		memcpy(&assoc_req->ssid, &priv->curbssparams.ssid,
-		       IW_ESSID_MAX_SIZE);
+		       IEEE80211_MAX_SSID_LEN);
 		assoc_req->ssid_len = priv->curbssparams.ssid_len;
 	}
 
 	if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
-		assoc_req->channel = priv->curbssparams.channel;
+		assoc_req->channel = priv->channel;
 
 	if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
 		assoc_req->band = priv->curbssparams.band;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/assoc.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/assoc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/assoc.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,126 @@
 #ifndef _LBS_ASSOC_H_
 #define _LBS_ASSOC_H_
 
-#include "dev.h"
+
+#include "defs.h"
+#include "host.h"
+
+
+struct lbs_private;
+
+/*
+ * In theory, the IE is limited to the IE length, 255,
+ * but in practice 64 bytes are enough.
+ */
+#define MAX_WPA_IE_LEN 64
+
+
+
+struct lbs_802_11_security {
+	u8 WPAenabled;
+	u8 WPA2enabled;
+	u8 wep_enabled;
+	u8 auth_mode;
+	u32 key_mgmt;
+};
+
+/** Current Basic Service Set State Structure */
+struct current_bss_params {
+	/** bssid */
+	u8 bssid[ETH_ALEN];
+	/** ssid */
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 ssid_len;
+
+	/** band */
+	u8 band;
+	/** channel is directly in priv->channel */
+	/** zero-terminated array of supported data rates */
+	u8 rates[MAX_RATES + 1];
+};
+
+/**
+ *  @brief Structure used to store information for each beacon/probe response
+ */
+struct bss_descriptor {
+	u8 bssid[ETH_ALEN];
+
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 ssid_len;
+
+	u16 capability;
+	u32 rssi;
+	u32 channel;
+	u16 beaconperiod;
+	__le16 atimwindow;
+
+	/* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
+	u8 mode;
+
+	/* zero-terminated array of supported data rates */
+	u8 rates[MAX_RATES + 1];
+
+	unsigned long last_scanned;
+
+	union ieee_phy_param_set phy;
+	union ieee_ss_param_set ss;
+
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8 rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+	u8 mesh;
+
+	struct list_head list;
+};
+
+/** Association request
+ *
+ * Encapsulates all the options that describe a specific assocation request
+ * or configuration of the wireless card's radio, mode, and security settings.
+ */
+struct assoc_request {
+#define ASSOC_FLAG_SSID			1
+#define ASSOC_FLAG_CHANNEL		2
+#define ASSOC_FLAG_BAND			3
+#define ASSOC_FLAG_MODE			4
+#define ASSOC_FLAG_BSSID		5
+#define ASSOC_FLAG_WEP_KEYS		6
+#define ASSOC_FLAG_WEP_TX_KEYIDX	7
+#define ASSOC_FLAG_WPA_MCAST_KEY	8
+#define ASSOC_FLAG_WPA_UCAST_KEY	9
+#define ASSOC_FLAG_SECINFO		10
+#define ASSOC_FLAG_WPA_IE		11
+	unsigned long flags;
+
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 ssid_len;
+	u8 channel;
+	u8 band;
+	u8 mode;
+	u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
+
+	/** WEP keys */
+	struct enc_key wep_keys[4];
+	u16 wep_tx_keyidx;
+
+	/** WPA keys */
+	struct enc_key wpa_mcast_key;
+	struct enc_key wpa_unicast_key;
+
+	struct lbs_802_11_security secinfo;
+
+	/** WPA Information Elements*/
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	u8 wpa_ie_len;
+
+	/* BSS to associate with for infrastructure of Ad-Hoc join */
+	struct bss_descriptor bss;
+};
+
+
+extern u8 lbs_bg_rates[MAX_RATES];
 
 void lbs_association_worker(struct work_struct *work);
 struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
@@ -13,4 +132,24 @@ int lbs_adhoc_stop(struct lbs_private *p
 int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
 				 u8 bssid[ETH_ALEN], u16 reason);
 
+int lbs_cmd_802_11_rssi(struct lbs_private *priv,
+				struct cmd_ds_command *cmd);
+int lbs_ret_802_11_rssi(struct lbs_private *priv,
+				struct cmd_ds_command *resp);
+
+int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
+				struct cmd_ds_command *cmd,
+				u16 cmd_action);
+int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
+					struct cmd_ds_command *resp);
+
+int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
+			   struct assoc_request *assoc);
+
+int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
+			      uint16_t *enable);
+
+int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
+				struct assoc_request *assoc);
+
 #endif /* _LBS_ASSOC_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cfg.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cfg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,198 @@
+/*
+ * Implement cfg80211 ("iw") support.
+ *
+ * Copyright (C) 2009 M&N Solutions GmbH, 61191 Rosbach, Germany
+ * Holger Schurig <hs4233@mail.mn-solutions.de>
+ *
+ */
+
+#include <net/cfg80211.h>
+
+#include "cfg.h"
+#include "cmd.h"
+
+
+#define CHAN2G(_channel, _freq, _flags) {        \
+	.band             = IEEE80211_BAND_2GHZ, \
+	.center_freq      = (_freq),             \
+	.hw_value         = (_channel),          \
+	.flags            = (_flags),            \
+	.max_antenna_gain = 0,                   \
+	.max_power        = 30,                  \
+}
+
+static struct ieee80211_channel lbs_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),
+};
+
+#define RATETAB_ENT(_rate, _rateid, _flags) { \
+	.bitrate  = (_rate),                  \
+	.hw_value = (_rateid),                \
+	.flags    = (_flags),                 \
+}
+
+
+static struct ieee80211_rate lbs_rates[] = {
+	RATETAB_ENT(10,  0x1,   0),
+	RATETAB_ENT(20,  0x2,   0),
+	RATETAB_ENT(55,  0x4,   0),
+	RATETAB_ENT(110, 0x8,   0),
+	RATETAB_ENT(60,  0x10,  0),
+	RATETAB_ENT(90,  0x20,  0),
+	RATETAB_ENT(120, 0x40,  0),
+	RATETAB_ENT(180, 0x80,  0),
+	RATETAB_ENT(240, 0x100, 0),
+	RATETAB_ENT(360, 0x200, 0),
+	RATETAB_ENT(480, 0x400, 0),
+	RATETAB_ENT(540, 0x800, 0),
+};
+
+static struct ieee80211_supported_band lbs_band_2ghz = {
+	.channels = lbs_2ghz_channels,
+	.n_channels = ARRAY_SIZE(lbs_2ghz_channels),
+	.bitrates = lbs_rates,
+	.n_bitrates = ARRAY_SIZE(lbs_rates),
+};
+
+
+static const u32 cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+};
+
+
+
+static int lbs_cfg_set_channel(struct wiphy *wiphy,
+	struct ieee80211_channel *chan,
+	enum nl80211_channel_type channel_type)
+{
+	struct lbs_private *priv = wiphy_priv(wiphy);
+	int ret = -ENOTSUPP;
+
+	lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", chan->center_freq, channel_type);
+
+	if (channel_type != NL80211_CHAN_NO_HT)
+		goto out;
+
+	ret = lbs_set_channel(priv, chan->hw_value);
+
+ out:
+	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	return ret;
+}
+
+
+
+
+static struct cfg80211_ops lbs_cfg80211_ops = {
+	.set_channel = lbs_cfg_set_channel,
+};
+
+
+/*
+ * At this time lbs_private *priv doesn't even exist, so we just allocate
+ * memory and don't initialize the wiphy further. This is postponed until we
+ * can talk to the firmware and happens at registration time in
+ * lbs_cfg_wiphy_register().
+ */
+struct wireless_dev *lbs_cfg_alloc(struct device *dev)
+{
+	int ret = 0;
+	struct wireless_dev *wdev;
+
+	lbs_deb_enter(LBS_DEB_CFG80211);
+
+	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+	if (!wdev) {
+		dev_err(dev, "cannot allocate wireless device\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
+	if (!wdev->wiphy) {
+		dev_err(dev, "cannot allocate wiphy\n");
+		ret = -ENOMEM;
+		goto err_wiphy_new;
+	}
+
+	lbs_deb_leave(LBS_DEB_CFG80211);
+	return wdev;
+
+ err_wiphy_new:
+	kfree(wdev);
+	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	return ERR_PTR(ret);
+}
+
+
+/*
+ * This function get's called after lbs_setup_firmware() determined the
+ * firmware capabities. So we can setup the wiphy according to our
+ * hardware/firmware.
+ */
+int lbs_cfg_register(struct lbs_private *priv)
+{
+	struct wireless_dev *wdev = priv->wdev;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_CFG80211);
+
+	wdev->wiphy->max_scan_ssids = 1;
+	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	/* TODO: BIT(NL80211_IFTYPE_ADHOC); */
+	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+	/* TODO: honor priv->regioncode */
+	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
+
+	/*
+	 * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have
+	 * never seen a firmware without WPA
+	 */
+	wdev->wiphy->cipher_suites = cipher_suites;
+	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+	ret = wiphy_register(wdev->wiphy);
+	if (ret < 0)
+		lbs_pr_err("cannot register wiphy device\n");
+
+	ret = register_netdev(priv->dev);
+	if (ret)
+		lbs_pr_err("cannot register network device\n");
+
+	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	return ret;
+}
+
+
+void lbs_cfg_free(struct lbs_private *priv)
+{
+	struct wireless_dev *wdev = priv->wdev;
+
+	lbs_deb_enter(LBS_DEB_CFG80211);
+
+	if (!wdev)
+		return;
+
+	if (wdev->wiphy) {
+		wiphy_unregister(wdev->wiphy);
+		wiphy_free(wdev->wiphy);
+	}
+	kfree(wdev);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cfg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cfg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cfg.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,16 @@
+#ifndef __LBS_CFG80211_H__
+#define __LBS_CFG80211_H__
+
+#include "dev.h"
+
+struct wireless_dev *lbs_cfg_alloc(struct device *dev);
+int lbs_cfg_register(struct lbs_private *priv);
+void lbs_cfg_free(struct lbs_private *priv);
+
+int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
+	u8 ssid_len);
+int lbs_scan_networks(struct lbs_private *priv, int full_scan);
+void lbs_cfg_scan_worker(struct work_struct *work);
+
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmd.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,21 +3,20 @@
   * It prepares command and sends it to firmware when it is ready.
   */
 
-#include <net/iw_handler.h>
-#include <net/lib80211.h>
 #include <linux/kfifo.h>
 #include <linux/sched.h>
+
 #include "host.h"
-#include "hostcmd.h"
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
 #include "assoc.h"
 #include "wext.h"
+#include "scan.h"
 #include "cmd.h"
 
-static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
 
+static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
 
 /**
  *  @brief Simple callback that copies response back into command
@@ -77,6 +76,30 @@ static u8 is_command_allowed_in_ps(u16 c
 }
 
 /**
+ *  @brief This function checks if the command is allowed.
+ *
+ *  @param priv         A pointer to lbs_private structure
+ *  @return             allowed or not allowed.
+ */
+
+static int lbs_is_cmd_allowed(struct lbs_private *priv)
+{
+	int ret = 1;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (!priv->is_auto_deep_sleep_enabled) {
+		if (priv->is_deep_sleep) {
+			lbs_deb_cmd("command not allowed in deep sleep\n");
+			ret = 0;
+		}
+	}
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return ret;
+}
+
+/**
  *  @brief Updates the hardware details like MAC address and regulatory region
  *
  *  @param priv    	A pointer to struct lbs_private structure
@@ -169,11 +192,6 @@ int lbs_update_hw_spec(struct lbs_privat
 		goto out;
 	}
 
-	if (lbs_set_universaltable(priv, 0)) {
-		ret = -1;
-		goto out;
-	}
-
 out:
 	lbs_deb_leave(LBS_DEB_CMD);
 	return ret;
@@ -222,7 +240,7 @@ static int lbs_cmd_802_11_ps_mode(struct
 
 	cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
 	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
-				S_DS_GEN);
+				sizeof(struct cmd_header));
 	psm->action = cpu_to_le16(cmd_action);
 	psm->multipledtim = 0;
 	switch (cmd_action) {
@@ -251,33 +269,6 @@ static int lbs_cmd_802_11_ps_mode(struct
 	return 0;
 }
 
-int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
-				      uint16_t cmd_action, uint16_t *timeout)
-{
-	struct cmd_ds_802_11_inactivity_timeout cmd;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	cmd.hdr.command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT);
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
-	cmd.action = cpu_to_le16(cmd_action);
-
-	if (cmd_action == CMD_ACT_SET)
-		cmd.timeout = cpu_to_le16(*timeout);
-	else
-		cmd.timeout = 0;
-
-	ret = lbs_cmd_with_response(priv, CMD_802_11_INACTIVITY_TIMEOUT, &cmd);
-
-	if (!ret)
-		*timeout = le16_to_cpu(cmd.timeout);
-
-	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-	return 0;
-}
-
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
 				struct sleep_params *sp)
 {
@@ -320,190 +311,53 @@ int lbs_cmd_802_11_sleep_params(struct l
 	return 0;
 }
 
-int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
-			   struct assoc_request *assoc)
+static int lbs_wait_for_ds_awake(struct lbs_private *priv)
 {
-	struct cmd_ds_802_11_set_wep cmd;
 	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
-	cmd.action = cpu_to_le16(cmd_action);
-
-	if (cmd_action == CMD_ACT_ADD) {
-		int i;
-
-		/* default tx key index */
-		cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
-					   CMD_WEP_KEY_INDEX_MASK);
-
-		/* Copy key types and material to host command structure */
-		for (i = 0; i < 4; i++) {
-			struct enc_key *pkey = &assoc->wep_keys[i];
-
-			switch (pkey->len) {
-			case KEY_LEN_WEP_40:
-				cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
-				memmove(cmd.keymaterial[i], pkey->key, pkey->len);
-				lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
-				break;
-			case KEY_LEN_WEP_104:
-				cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
-				memmove(cmd.keymaterial[i], pkey->key, pkey->len);
-				lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
-				break;
-			case 0:
-				break;
-			default:
-				lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
-					    i, pkey->len);
-				ret = -1;
-				goto done;
-				break;
-			}
+	if (priv->is_deep_sleep) {
+		if (!wait_event_interruptible_timeout(priv->ds_awake_q,
+					!priv->is_deep_sleep, (10 * HZ))) {
+			lbs_pr_err("ds_awake_q: timer expired\n");
+			ret = -1;
 		}
-	} else if (cmd_action == CMD_ACT_REMOVE) {
-		/* ACT_REMOVE clears _all_ WEP keys */
-
-		/* default tx key index */
-		cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
-					   CMD_WEP_KEY_INDEX_MASK);
-		lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
 	}
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
-done:
 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
 	return ret;
 }
 
-int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
-			      uint16_t *enable)
-{
-	struct cmd_ds_802_11_enable_rsn cmd;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-	cmd.action = cpu_to_le16(cmd_action);
-
-	if (cmd_action == CMD_ACT_GET)
-		cmd.enable = 0;
-	else {
-		if (*enable)
-			cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
-		else
-			cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
-		lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
-	}
-
-	ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
-	if (!ret && cmd_action == CMD_ACT_GET)
-		*enable = le16_to_cpu(cmd.enable);
-
-	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-	return ret;
-}
-
-static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
-                            struct enc_key *key)
-{
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	if (key->flags & KEY_INFO_WPA_ENABLED)
-		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
-	if (key->flags & KEY_INFO_WPA_UNICAST)
-		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
-	if (key->flags & KEY_INFO_WPA_MCAST)
-		keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
-
-	keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
-	keyparam->keytypeid = cpu_to_le16(key->type);
-	keyparam->keylen = cpu_to_le16(key->len);
-	memcpy(keyparam->key, key->key, key->len);
-
-	/* Length field doesn't include the {type,length} header */
-	keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
-	lbs_deb_leave(LBS_DEB_CMD);
-}
-
-int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
-				struct assoc_request *assoc)
+int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
 {
-	struct cmd_ds_802_11_key_material cmd;
-	int ret = 0;
-	int index = 0;
+	int ret =  0;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
-	cmd.action = cpu_to_le16(cmd_action);
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
-	if (cmd_action == CMD_ACT_GET) {
-		cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2);
-	} else {
-		memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
-
-		if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
-			set_one_wpa_key(&cmd.keyParamSet[index],
-					&assoc->wpa_unicast_key);
-			index++;
-		}
-
-		if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
-			set_one_wpa_key(&cmd.keyParamSet[index],
-					&assoc->wpa_mcast_key);
-			index++;
+	if (deep_sleep) {
+		if (priv->is_deep_sleep != 1) {
+			lbs_deb_cmd("deep sleep: sleep\n");
+			BUG_ON(!priv->enter_deep_sleep);
+			ret = priv->enter_deep_sleep(priv);
+			if (!ret) {
+				netif_stop_queue(priv->dev);
+				netif_carrier_off(priv->dev);
+			}
+		} else {
+			lbs_pr_err("deep sleep: already enabled\n");
 		}
-
-		/* The common header and as many keys as we included */
-		cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
-						    keyParamSet[index]));
-	}
-	ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
-	/* Copy the returned key to driver private data */
-	if (!ret && cmd_action == CMD_ACT_GET) {
-		void *buf_ptr = cmd.keyParamSet;
-		void *resp_end = &(&cmd)[1];
-
-		while (buf_ptr < resp_end) {
-			struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
-			struct enc_key *key;
-			uint16_t param_set_len = le16_to_cpu(keyparam->length);
-			uint16_t key_len = le16_to_cpu(keyparam->keylen);
-			uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
-			uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
-			void *end;
-
-			end = (void *)keyparam + sizeof(keyparam->type)
-				+ sizeof(keyparam->length) + param_set_len;
-
-			/* Make sure we don't access past the end of the IEs */
-			if (end > resp_end)
-				break;
-
-			if (key_flags & KEY_INFO_WPA_UNICAST)
-				key = &priv->wpa_unicast_key;
-			else if (key_flags & KEY_INFO_WPA_MCAST)
-				key = &priv->wpa_mcast_key;
-			else
-				break;
-
-			/* Copy returned key into driver */
-			memset(key, 0, sizeof(struct enc_key));
-			if (key_len > sizeof(key->key))
-				break;
-			key->type = key_type;
-			key->flags = key_flags;
-			key->len = key_len;
-			memcpy(key->key, keyparam->key, key->len);
-
-			buf_ptr = end + 1;
+	} else {
+		if (priv->is_deep_sleep) {
+			lbs_deb_cmd("deep sleep: wakeup\n");
+			BUG_ON(!priv->exit_deep_sleep);
+			ret = priv->exit_deep_sleep(priv);
+			if (!ret) {
+				ret = lbs_wait_for_ds_awake(priv);
+				if (ret)
+					lbs_pr_err("deep sleep: wakeup"
+							"failed\n");
+			}
 		}
 	}
 
@@ -535,7 +389,7 @@ int lbs_set_snmp_mib(struct lbs_private
 	switch (oid) {
 	case SNMP_MIB_OID_BSS_TYPE:
 		cmd.bufsize = cpu_to_le16(sizeof(u8));
-		cmd.value[0] = (val == IW_MODE_ADHOC) ? 2 : 1;
+		cmd.value[0] = val;
 		break;
 	case SNMP_MIB_OID_11D_ENABLE:
 	case SNMP_MIB_OID_FRAG_THRESHOLD:
@@ -588,13 +442,7 @@ int lbs_get_snmp_mib(struct lbs_private
 
 	switch (le16_to_cpu(cmd.bufsize)) {
 	case sizeof(u8):
-		if (oid == SNMP_MIB_OID_BSS_TYPE) {
-			if (cmd.value[0] == 2)
-				*out_val = IW_MODE_ADHOC;
-			else
-				*out_val = IW_MODE_INFRA;
-		} else
-			*out_val = cmd.value[0];
+		*out_val = cmd.value[0];
 		break;
 	case sizeof(u16):
 		*out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
@@ -681,7 +529,7 @@ static int lbs_cmd_802_11_monitor_mode(s
 	cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE);
 	cmd->size =
 	    cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) +
-			     S_DS_GEN);
+			     sizeof(struct cmd_header));
 
 	monitor->action = cpu_to_le16(cmd_action);
 	if (cmd_action == CMD_ACT_SET) {
@@ -692,111 +540,6 @@ static int lbs_cmd_802_11_monitor_mode(s
 	return 0;
 }
 
-static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
-{
-/*		Bit  	Rate
-*		15:13 Reserved
-*		12    54 Mbps
-*		11    48 Mbps
-*		10    36 Mbps
-*		9     24 Mbps
-*		8     18 Mbps
-*		7     12 Mbps
-*		6     9 Mbps
-*		5     6 Mbps
-*		4     Reserved
-*		3     11 Mbps
-*		2     5.5 Mbps
-*		1     2 Mbps
-*		0     1 Mbps
-**/
-
-	uint16_t ratemask;
-	int i = lbs_data_rate_to_fw_index(rate);
-	if (lower_rates_ok)
-		ratemask = (0x1fef >> (12 - i));
-	else
-		ratemask = (1 << i);
-	return cpu_to_le16(ratemask);
-}
-
-int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
-				      uint16_t cmd_action)
-{
-	struct cmd_ds_802_11_rate_adapt_rateset cmd;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	if (!priv->cur_rate && !priv->enablehwauto)
-		return -EINVAL;
-
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
-	cmd.action = cpu_to_le16(cmd_action);
-	cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
-	cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
-	ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
-	if (!ret && cmd_action == CMD_ACT_GET) {
-		priv->ratebitmap = le16_to_cpu(cmd.bitmap);
-		priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
-	}
-
-	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_cmd_802_11_rate_adapt_rateset);
-
-/**
- *  @brief Set the data rate
- *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param rate  	The desired data rate, or 0 to clear a locked rate
- *
- *  @return 	   	0 on success, error on failure
- */
-int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
-{
-	struct cmd_ds_802_11_data_rate cmd;
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
-	if (rate > 0) {
-		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
-		cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
-		if (cmd.rates[0] == 0) {
-			lbs_deb_cmd("DATA_RATE: invalid requested rate of"
-			            " 0x%02X\n", rate);
-			ret = 0;
-			goto out;
-		}
-		lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
-	} else {
-		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
-		lbs_deb_cmd("DATA_RATE: setting auto\n");
-	}
-
-	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
-	if (ret)
-		goto out;
-
-	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
-
-	/* FIXME: get actual rates FW can do if this command actually returns
-	 * all data rates supported.
-	 */
-	priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
-	lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
-
-out:
-	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-	return ret;
-}
-
 /**
  *  @brief Get the radio channel
  *
@@ -804,7 +547,7 @@ out:
  *
  *  @return 	   	The channel on success, error on failure
  */
-int lbs_get_channel(struct lbs_private *priv)
+static int lbs_get_channel(struct lbs_private *priv)
 {
 	struct cmd_ds_802_11_rf_channel cmd;
 	int ret = 0;
@@ -836,7 +579,7 @@ int lbs_update_channel(struct lbs_privat
 
 	ret = lbs_get_channel(priv);
 	if (ret > 0) {
-		priv->curbssparams.channel = ret;
+		priv->channel = ret;
 		ret = 0;
 	}
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -855,7 +598,7 @@ int lbs_set_channel(struct lbs_private *
 {
 	struct cmd_ds_802_11_rf_channel cmd;
 #ifdef DEBUG
-	u8 old_channel = priv->curbssparams.channel;
+	u8 old_channel = priv->channel;
 #endif
 	int ret = 0;
 
@@ -870,36 +613,15 @@ int lbs_set_channel(struct lbs_private *
 	if (ret)
 		goto out;
 
-	priv->curbssparams.channel = (uint8_t) le16_to_cpu(cmd.channel);
+	priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
 	lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
-		priv->curbssparams.channel);
+		priv->channel);
 
 out:
 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
 	return ret;
 }
 
-static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
-				struct cmd_ds_command *cmd)
-{
-
-	lbs_deb_enter(LBS_DEB_CMD);
-	cmd->command = cpu_to_le16(CMD_802_11_RSSI);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
-	cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
-
-	/* reset Beacon SNR/NF/RSSI values */
-	priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
-	priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
-	priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
-	priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
-	priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
-	priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
 static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
 			       u8 cmd_action, void *pdata_buf)
 {
@@ -916,7 +638,7 @@ static int lbs_cmd_reg_access(struct cmd
 
 			cmdptr->size =
 			    cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
-					+ S_DS_GEN);
+					+ sizeof(struct cmd_header));
 			macreg =
 			    (struct cmd_ds_mac_reg_access *)&cmdptr->params.
 			    macreg;
@@ -935,7 +657,7 @@ static int lbs_cmd_reg_access(struct cmd
 			cmdptr->size =
 			    cpu_to_le16(sizeof
 					     (struct cmd_ds_bbp_reg_access)
-					     + S_DS_GEN);
+					     + sizeof(struct cmd_header));
 			bbpreg =
 			    (struct cmd_ds_bbp_reg_access *)&cmdptr->params.
 			    bbpreg;
@@ -954,7 +676,7 @@ static int lbs_cmd_reg_access(struct cmd
 			cmdptr->size =
 			    cpu_to_le16(sizeof
 					     (struct cmd_ds_rf_reg_access) +
-					     S_DS_GEN);
+					     sizeof(struct cmd_header));
 			rfreg =
 			    (struct cmd_ds_rf_reg_access *)&cmdptr->params.
 			    rfreg;
@@ -974,192 +696,6 @@ static int lbs_cmd_reg_access(struct cmd
 	return 0;
 }
 
-static int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
-			       u16 cmd_action, void *pdata_buf)
-{
-	struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
-	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
-	cmd->command = cpu_to_le16(CMD_BT_ACCESS);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN);
-	cmd->result = 0;
-	bt_access->action = cpu_to_le16(cmd_action);
-
-	switch (cmd_action) {
-	case CMD_ACT_BT_ACCESS_ADD:
-		memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
-		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", bt_access->addr1, 6);
-		break;
-	case CMD_ACT_BT_ACCESS_DEL:
-		memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
-		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", bt_access->addr1, 6);
-		break;
-	case CMD_ACT_BT_ACCESS_LIST:
-		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
-		break;
-	case CMD_ACT_BT_ACCESS_RESET:
-		break;
-	case CMD_ACT_BT_ACCESS_SET_INVERT:
-		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
-		break;
-	case CMD_ACT_BT_ACCESS_GET_INVERT:
-		break;
-	default:
-		break;
-	}
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
-static int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
-			       u16 cmd_action, void *pdata_buf)
-{
-	struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
-	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
-	cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN);
-	cmd->result = 0;
-
-	if (pdata_buf)
-		memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
-	else
-		memset(fwt_access, 0, sizeof(*fwt_access));
-
-	fwt_access->action = cpu_to_le16(cmd_action);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
-		    struct cmd_ds_mesh_access *cmd)
-{
-	int ret;
-
-	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
-	cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
-	cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
-	cmd->hdr.result = 0;
-
-	cmd->action = cpu_to_le16(cmd_action);
-
-	ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return ret;
-}
-
-static int __lbs_mesh_config_send(struct lbs_private *priv,
-				  struct cmd_ds_mesh_config *cmd,
-				  uint16_t action, uint16_t type)
-{
-	int ret;
-	u16 command = CMD_MESH_CONFIG_OLD;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	/*
-	 * Command id is 0xac for v10 FW along with mesh interface
-	 * id in bits 14-13-12.
-	 */
-	if (priv->mesh_fw_ver == MESH_FW_NEW)
-		command = CMD_MESH_CONFIG |
-			  (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
-
-	cmd->hdr.command = cpu_to_le16(command);
-	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
-	cmd->hdr.result = 0;
-
-	cmd->type = cpu_to_le16(type);
-	cmd->action = cpu_to_le16(action);
-
-	ret = lbs_cmd_with_response(priv, command, cmd);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return ret;
-}
-
-int lbs_mesh_config_send(struct lbs_private *priv,
-			 struct cmd_ds_mesh_config *cmd,
-			 uint16_t action, uint16_t type)
-{
-	int ret;
-
-	if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
-		return -EOPNOTSUPP;
-
-	ret = __lbs_mesh_config_send(priv, cmd, action, type);
-	return ret;
-}
-
-/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
- * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
- * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
- * lbs_mesh_config_send.
- */
-int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
-{
-	struct cmd_ds_mesh_config cmd;
-	struct mrvl_meshie *ie;
-	DECLARE_SSID_BUF(ssid);
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.channel = cpu_to_le16(chan);
-	ie = (struct mrvl_meshie *)cmd.data;
-
-	switch (action) {
-	case CMD_ACT_MESH_CONFIG_START:
-		ie->id = WLAN_EID_GENERIC;
-		ie->val.oui[0] = 0x00;
-		ie->val.oui[1] = 0x50;
-		ie->val.oui[2] = 0x43;
-		ie->val.type = MARVELL_MESH_IE_TYPE;
-		ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
-		ie->val.version = MARVELL_MESH_IE_VERSION;
-		ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
-		ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
-		ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
-		ie->val.mesh_id_len = priv->mesh_ssid_len;
-		memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
-		ie->len = sizeof(struct mrvl_meshie_val) -
-			IW_ESSID_MAX_SIZE + priv->mesh_ssid_len;
-		cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
-		break;
-	case CMD_ACT_MESH_CONFIG_STOP:
-		break;
-	default:
-		return -1;
-	}
-	lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
-		    action, priv->mesh_tlv, chan,
-		    print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
-
-	return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
-}
-
-static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
-				struct cmd_ds_command *cmd,
-				u16 cmd_action)
-{
-	struct cmd_ds_802_11_beacon_control
-		*bcn_ctrl = &cmd->params.bcn_ctrl;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-	cmd->size =
-	    cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
-			     + S_DS_GEN);
-	cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
-
-	bcn_ctrl->action = cpu_to_le16(cmd_action);
-	bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
-	bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
 static void lbs_queue_cmd(struct lbs_private *priv,
 			  struct cmd_ctrl_node *cmdnode)
 {
@@ -1243,8 +779,17 @@ static void lbs_submit_command(struct lb
 		timeo = HZ/4;
 	}
 
-	/* Setup the timer after transmit command */
-	mod_timer(&priv->command_timer, jiffies + timeo);
+	if (command == CMD_802_11_DEEP_SLEEP) {
+		if (priv->is_auto_deep_sleep_enabled) {
+			priv->wakeup_dev_required = 1;
+			priv->dnld_sent = 0;
+		}
+		priv->is_deep_sleep = 1;
+		lbs_complete_command(priv, cmdnode, 0);
+	} else {
+		/* Setup the timer after transmit command */
+		mod_timer(&priv->command_timer, jiffies + timeo);
+	}
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
@@ -1391,6 +936,11 @@ int lbs_prepare_and_send_command(struct
 		goto done;
 	}
 
+	if (!lbs_is_cmd_allowed(priv)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
 	cmdnode = lbs_get_cmd_ctrl_node(priv);
 
 	if (cmdnode == NULL) {
@@ -1441,7 +991,7 @@ int lbs_prepare_and_send_command(struct
 
 		cmdptr->command = cpu_to_le16(cmd_no);
 		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
-					   S_DS_GEN);
+					   sizeof(struct cmd_header));
 
 		memmove(&cmdptr->params.afc,
 			pdata_buf, sizeof(struct cmd_ds_802_11_afc));
@@ -1449,45 +999,17 @@ int lbs_prepare_and_send_command(struct
 		ret = 0;
 		goto done;
 
-	case CMD_802_11D_DOMAIN_INFO:
-		ret = lbs_cmd_802_11d_domain_info(priv, cmdptr,
-						   cmd_no, cmd_action);
-		break;
-
 	case CMD_802_11_TPC_CFG:
 		cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
 		cmdptr->size =
 		    cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
-				     S_DS_GEN);
+				     sizeof(struct cmd_header));
 
 		memmove(&cmdptr->params.tpccfg,
 			pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg));
 
 		ret = 0;
 		break;
-	case CMD_802_11_LED_GPIO_CTRL:
-		{
-			struct mrvl_ie_ledgpio *gpio =
-			    (struct mrvl_ie_ledgpio*)
-			    cmdptr->params.ledgpio.data;
-
-			memmove(&cmdptr->params.ledgpio,
-				pdata_buf,
-				sizeof(struct cmd_ds_802_11_led_ctrl));
-
-			cmdptr->command =
-			    cpu_to_le16(CMD_802_11_LED_GPIO_CTRL);
-
-#define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
-			cmdptr->size =
-			    cpu_to_le16(le16_to_cpu(gpio->header.len)
-				+ S_DS_GEN
-				+ ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
-			gpio->header.len = gpio->header.len;
-
-			ret = 0;
-			break;
-		}
 
 	case CMD_BT_ACCESS:
 		ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
@@ -1497,15 +1019,13 @@ int lbs_prepare_and_send_command(struct
 		ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
 		break;
 
-	case CMD_GET_TSF:
-		cmdptr->command = cpu_to_le16(CMD_GET_TSF);
-		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
-					   S_DS_GEN);
-		ret = 0;
-		break;
 	case CMD_802_11_BEACON_CTRL:
 		ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
 		break;
+	case CMD_802_11_DEEP_SLEEP:
+		cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP);
+		cmdptr->size = cpu_to_le16(sizeof(struct cmd_header));
+		break;
 	default:
 		lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no);
 		ret = -1;
@@ -1823,30 +1343,6 @@ done:
 	return ret;
 }
 
-void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
-{
-	union iwreq_data iwrq;
-	u8 buf[50];
-
-	lbs_deb_enter(LBS_DEB_WEXT);
-
-	memset(&iwrq, 0, sizeof(union iwreq_data));
-	memset(buf, 0, sizeof(buf));
-
-	snprintf(buf, sizeof(buf) - 1, "%s", str);
-
-	iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
-
-	/* Send Event to upper layer */
-	lbs_deb_wext("event indication string %s\n", (char *)buf);
-	lbs_deb_wext("event indication length %d\n", iwrq.data.length);
-	lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);
-
-	wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
-
-	lbs_deb_leave(LBS_DEB_WEXT);
-}
-
 static void lbs_send_confirmsleep(struct lbs_private *priv)
 {
 	unsigned long flags;
@@ -1869,7 +1365,7 @@ static void lbs_send_confirmsleep(struct
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
 	/* If nothing to do, go back to sleep (?) */
-	if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
+	if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
 		priv->psstate = PS_STATE_SLEEP;
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1943,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_pri
 	}
 
 	/* Pending events or command responses? */
-	if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
+	if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
 		allowed = 0;
 		lbs_deb_host("pending events or command responses\n");
 	}
@@ -2024,7 +1520,7 @@ int lbs_set_power_adapt_cfg(struct lbs_p
 }
 
 
-static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
 	uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
 	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	unsigned long callback_arg)
@@ -2039,6 +1535,11 @@ static struct cmd_ctrl_node *__lbs_cmd_a
 		goto done;
 	}
 
+	if (!lbs_is_cmd_allowed(priv)) {
+		cmdnode = ERR_PTR(-EBUSY);
+		goto done;
+	}
+
 	cmdnode = lbs_get_cmd_ctrl_node(priv);
 	if (cmdnode == NULL) {
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
@@ -2117,5 +1618,3 @@ done:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(__lbs_cmd);
-
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmd.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmd.h	2010-02-24 13:52:17.000000000 -0500
@@ -3,11 +3,30 @@
 #ifndef _LBS_CMD_H_
 #define _LBS_CMD_H_
 
-#include "hostcmd.h"
+#include "host.h"
 #include "dev.h"
 
+
+/* Command & response transfer between host and card */
+
+struct cmd_ctrl_node {
+	struct list_head list;
+	int result;
+	/* command response */
+	int (*callback)(struct lbs_private *,
+			unsigned long,
+			struct cmd_header *);
+	unsigned long callback_arg;
+	/* command data */
+	struct cmd_header *cmdbuf;
+	/* wait queue */
+	u16 cmdwaitqwoken;
+	wait_queue_head_t cmdwait_q;
+};
+
+
 /* lbs_cmd() infers the size of the buffer to copy data back into, from
-   the size of the target of the pointer. Since the command to be sent 
+   the size of the target of the pointer. Since the command to be sent
    may often be smaller, that size is set in cmd->size by the caller.*/
 #define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg)	({		\
 	uint16_t __sz = le16_to_cpu((cmd)->hdr.size);		\
@@ -18,6 +37,11 @@
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
 
+int lbs_prepare_and_send_command(struct lbs_private *priv,
+	u16 cmd_no,
+	u16 cmd_action,
+	u16 wait_option, u32 cmd_oid, void *pdata_buf);
+
 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
 	struct cmd_header *in_cmd, int in_cmd_size);
 
@@ -26,62 +50,93 @@ int __lbs_cmd(struct lbs_private *priv,
 	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	      unsigned long callback_arg);
 
-int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
-		int8_t p1, int8_t p2);
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
+	uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
+	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+	unsigned long callback_arg);
 
-int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
-		int8_t p2, int usesnr);
+int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
+		     struct cmd_header *resp);
 
-int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
-		int8_t p1, int8_t p2);
+int lbs_allocate_cmd_buffer(struct lbs_private *priv);
+int lbs_free_cmd_buffer(struct lbs_private *priv);
 
-int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
-		int8_t p2, int usesnr);
+int lbs_execute_next_command(struct lbs_private *priv);
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			  int result);
+int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
 
-int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
-		     struct cmd_header *resp);
 
-int lbs_update_hw_spec(struct lbs_private *priv);
+/* From cmdresp.c */
 
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
-		    struct cmd_ds_mesh_access *cmd);
+void lbs_mac_event_disconnected(struct lbs_private *priv);
 
-int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
 
-int lbs_get_channel(struct lbs_private *priv);
+
+/* Events */
+
+int lbs_process_event(struct lbs_private *priv, u32 event);
+
+
+/* Actual commands */
+
+int lbs_update_hw_spec(struct lbs_private *priv);
+
 int lbs_set_channel(struct lbs_private *priv, u8 channel);
 
-int lbs_mesh_config_send(struct lbs_private *priv,
-			 struct cmd_ds_mesh_config *cmd,
-			 uint16_t action, uint16_t type);
-int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
+int lbs_update_channel(struct lbs_private *priv);
 
 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 		struct wol_config *p_wol_config);
-int lbs_suspend(struct lbs_private *priv);
-void lbs_resume(struct lbs_private *priv);
 
-int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
-				      uint16_t cmd_action);
-int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
-				      uint16_t cmd_action, uint16_t *timeout);
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
 				struct sleep_params *sp);
-int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
-			   struct assoc_request *assoc);
-int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
-			      uint16_t *enable);
-int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
-				struct assoc_request *assoc);
 
-int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
-		     s16 *maxlevel);
-int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
+void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
+
+void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
+
+void lbs_ps_confirm_sleep(struct lbs_private *priv);
 
 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
 
+void lbs_set_mac_control(struct lbs_private *priv);
+
+int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
+		     s16 *maxlevel);
+
 int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val);
 
 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val);
 
+
+/* Mesh related */
+
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+		    struct cmd_ds_mesh_access *cmd);
+
+int lbs_mesh_config_send(struct lbs_private *priv,
+			 struct cmd_ds_mesh_config *cmd,
+			 uint16_t action, uint16_t type);
+
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
+
+
+/* Commands only used in wext.c, assoc. and scan.c */
+
+int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
+		int8_t p1, int8_t p2);
+
+int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
+		int8_t p2, int usesnr);
+
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
+
+int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
+				      uint16_t cmd_action);
+
+int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
+
+int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
+
 #endif /* _LBS_CMD_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmdresp.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmdresp.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/cmdresp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/cmdresp.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 
 #include "host.h"
 #include "decl.h"
+#include "cmd.h"
 #include "defs.h"
 #include "dev.h"
 #include "assoc.h"
@@ -26,23 +27,17 @@
  */
 void lbs_mac_event_disconnected(struct lbs_private *priv)
 {
-	union iwreq_data wrqu;
-
 	if (priv->connect_status != LBS_CONNECTED)
 		return;
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
-	memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
 	/*
 	 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
 	 * It causes problem in the Supplicant
 	 */
-
 	msleep_interruptible(1000);
-	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+	lbs_send_disconnect_notification(priv);
 
 	/* report disconnect to upper layer */
 	netif_stop_queue(priv->dev);
@@ -67,7 +62,7 @@ void lbs_mac_event_disconnected(struct l
 	 * no longer valid.
 	 */
 	memset(&priv->curbssparams.bssid, 0, ETH_ALEN);
-	memset(&priv->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
+	memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN);
 	priv->curbssparams.ssid_len = 0;
 
 	if (priv->psstate != PS_STATE_FULL_POWER) {
@@ -78,32 +73,6 @@ void lbs_mac_event_disconnected(struct l
 	lbs_deb_leave(LBS_DEB_ASSOC);
 }
 
-/**
- *  @brief This function handles MIC failure event.
- *
- *  @param priv    A pointer to struct lbs_private structure
- *  @para  event   the event id
- *  @return 	   n/a
- */
-static void handle_mic_failureevent(struct lbs_private *priv, u32 event)
-{
-	char buf[50];
-
-	lbs_deb_enter(LBS_DEB_CMD);
-	memset(buf, 0, sizeof(buf));
-
-	sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
-
-	if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) {
-		strcat(buf, "unicast ");
-	} else {
-		strcat(buf, "multicast ");
-	}
-
-	lbs_send_iwevcustom_event(priv, buf);
-	lbs_deb_leave(LBS_DEB_CMD);
-}
-
 static int lbs_ret_reg_access(struct lbs_private *priv,
 			       u16 type, struct cmd_ds_command *resp)
 {
@@ -147,53 +116,6 @@ static int lbs_ret_reg_access(struct lbs
 	return ret;
 }
 
-static int lbs_ret_802_11_rssi(struct lbs_private *priv,
-				struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	/* store the non average value */
-	priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
-	priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
-
-	priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
-	priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
-
-	priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
-	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
-		     priv->NF[TYPE_BEACON][TYPE_NOAVG]);
-
-	priv->RSSI[TYPE_BEACON][TYPE_AVG] =
-	    CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
-		     priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
-
-	lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
-	       priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
-	       priv->RSSI[TYPE_BEACON][TYPE_AVG]);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
-static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv,
-					struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11_beacon_control *bcn_ctrl =
-	    &resp->params.bcn_ctrl;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	if (bcn_ctrl->action == CMD_ACT_GET) {
-		priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
-		priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
-	}
-
-	lbs_deb_enter(LBS_DEB_CMD);
-	return 0;
-}
-
 static inline int handle_cmd_response(struct lbs_private *priv,
 				      struct cmd_header *cmd_response)
 {
@@ -227,29 +149,13 @@ static inline int handle_cmd_response(st
 		ret = lbs_ret_802_11_rssi(priv, resp);
 		break;
 
-	case CMD_RET(CMD_802_11D_DOMAIN_INFO):
-		ret = lbs_ret_802_11d_domain_info(resp);
-		break;
-
 	case CMD_RET(CMD_802_11_TPC_CFG):
 		spin_lock_irqsave(&priv->driver_lock, flags);
 		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
 			sizeof(struct cmd_ds_802_11_tpc_cfg));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
-	case CMD_RET(CMD_802_11_LED_GPIO_CTRL):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.ledgpio,
-			sizeof(struct cmd_ds_802_11_led_ctrl));
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		break;
 
-	case CMD_RET(CMD_GET_TSF):
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		memcpy((void *)priv->cur_cmd->callback_arg,
-		       &resp->params.gettsf.tsfvalue, sizeof(u64));
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		break;
 	case CMD_RET(CMD_BT_ACCESS):
 		spin_lock_irqsave(&priv->driver_lock, flags);
 		if (priv->cur_cmd->callback_arg)
@@ -505,9 +411,21 @@ int lbs_process_event(struct lbs_private
 
 	case MACREG_INT_CODE_HOST_AWAKE:
 		lbs_deb_cmd("EVENT: host awake\n");
+		if (priv->reset_deep_sleep_wakeup)
+			priv->reset_deep_sleep_wakeup(priv);
+		priv->is_deep_sleep = 0;
 		lbs_send_confirmwake(priv);
 		break;
 
+	case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
+		if (priv->reset_deep_sleep_wakeup)
+			priv->reset_deep_sleep_wakeup(priv);
+		lbs_deb_cmd("EVENT: ds awake\n");
+		priv->is_deep_sleep = 0;
+		priv->wakeup_dev_required = 0;
+		wake_up_interruptible(&priv->ds_awake_q);
+		break;
+
 	case MACREG_INT_CODE_PS_AWAKE:
 		lbs_deb_cmd("EVENT: ps awake\n");
 		/* handle unexpected PS AWAKE event */
@@ -533,12 +451,12 @@ int lbs_process_event(struct lbs_private
 
 	case MACREG_INT_CODE_MIC_ERR_UNICAST:
 		lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
-		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
+		lbs_send_mic_failureevent(priv, event);
 		break;
 
 	case MACREG_INT_CODE_MIC_ERR_MULTICAST:
 		lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
-		handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
+		lbs_send_mic_failureevent(priv, event);
 		break;
 
 	case MACREG_INT_CODE_MIB_CHANGED:
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/debugfs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -451,10 +451,12 @@ static ssize_t lbs_rdmac_read(struct fil
 				CMD_MAC_REG_ACCESS, 0,
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
-	pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
+	if (!ret) {
+		pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
 				priv->mac_offset, priv->offsetvalue.value);
 
-	ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+	}
 	free_page(addr);
 	return ret;
 }
@@ -514,7 +516,8 @@ static ssize_t lbs_wrmac_write(struct fi
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
 
-	res = count;
+	if (!res)
+		res = count;
 out_unlock:
 	free_page(addr);
 	return res;
@@ -539,10 +542,12 @@ static ssize_t lbs_rdbbp_read(struct fil
 				CMD_BBP_REG_ACCESS, 0,
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
-	pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
+	if (!ret) {
+		pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
 				priv->bbp_offset, priv->offsetvalue.value);
 
-	ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+	}
 	free_page(addr);
 
 	return ret;
@@ -603,7 +608,8 @@ static ssize_t lbs_wrbbp_write(struct fi
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
 
-	res = count;
+	if (!res)
+		res = count;
 out_unlock:
 	free_page(addr);
 	return res;
@@ -628,10 +634,12 @@ static ssize_t lbs_rdrf_read(struct file
 				CMD_RF_REG_ACCESS, 0,
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
-	pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
+	if (!ret) {
+		pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
 				priv->rf_offset, priv->offsetvalue.value);
 
-	ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+		ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+	}
 	free_page(addr);
 
 	return ret;
@@ -692,7 +700,8 @@ static ssize_t lbs_wrrf_write(struct fil
 				CMD_OPTION_WAITFORRSP, 0, &offval);
 	mdelay(10);
 
-	res = count;
+	if (!res)
+		res = count;
 out_unlock:
 	free_page(addr);
 	return res;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/decl.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/decl.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/decl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/decl.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,71 +8,46 @@
 
 #include <linux/netdevice.h>
 
-#include "defs.h"
 
-/** Function Prototype Declaration */
 struct lbs_private;
 struct sk_buff;
 struct net_device;
-struct cmd_ctrl_node;
-struct cmd_ds_command;
 
-void lbs_set_mac_control(struct lbs_private *priv);
-
-void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count);
-
-int lbs_free_cmd_buffer(struct lbs_private *priv);
 
-int lbs_prepare_and_send_command(struct lbs_private *priv,
-	u16 cmd_no,
-	u16 cmd_action,
-	u16 wait_option, u32 cmd_oid, void *pdata_buf);
-
-int lbs_allocate_cmd_buffer(struct lbs_private *priv);
-int lbs_execute_next_command(struct lbs_private *priv);
-int lbs_process_event(struct lbs_private *priv, u32 event);
-void lbs_queue_event(struct lbs_private *priv, u32 event);
-void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
+/* ethtool.c */
+extern const struct ethtool_ops lbs_ethtool_ops;
 
-u32 lbs_fw_index_to_data_rate(u8 index);
-u8 lbs_data_rate_to_fw_index(u32 rate);
 
-/** The proc fs interface */
-int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
-void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
-			  int result);
+/* tx.c */
+void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count);
 netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb,
 				struct net_device *dev);
-int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
 
+/* rx.c */
 int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
 
-void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
-void lbs_ps_confirm_sleep(struct lbs_private *priv);
-void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
-
-struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
-	struct lbs_private *priv,
-	u8 band,
-	u16 channel);
-
-void lbs_mac_event_disconnected(struct lbs_private *priv);
-
-void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str);
-
-/* persistcfg.c */
-void lbs_persist_config_init(struct net_device *net);
-void lbs_persist_config_remove(struct net_device *net);
 
 /* main.c */
-struct chan_freq_power *lbs_get_region_cfp_table(u8 region,
-	int *cfp_no);
 struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
 void lbs_remove_card(struct lbs_private *priv);
 int lbs_start_card(struct lbs_private *priv);
 void lbs_stop_card(struct lbs_private *priv);
 void lbs_host_to_card_done(struct lbs_private *priv);
 
-int lbs_update_channel(struct lbs_private *priv);
+int lbs_set_mac_address(struct net_device *dev, void *addr);
+void lbs_set_multicast_list(struct net_device *dev);
+
+int lbs_suspend(struct lbs_private *priv);
+void lbs_resume(struct lbs_private *priv);
+
+void lbs_queue_event(struct lbs_private *priv, u32 event);
+void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
+
+int lbs_enter_auto_deep_sleep(struct lbs_private *priv);
+int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
+
+u32 lbs_fw_index_to_data_rate(u8 index);
+u8 lbs_data_rate_to_fw_index(u32 rate);
+
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/defs.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/defs.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/defs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@
 #define LBS_DEB_SDIO	0x00400000
 #define LBS_DEB_SYSFS	0x00800000
 #define LBS_DEB_SPI	0x01000000
+#define LBS_DEB_CFG80211 0x02000000
 
 extern unsigned int lbs_debug;
 
@@ -86,6 +87,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \
 #define lbs_deb_sdio(fmt, args...)      LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
 #define lbs_deb_sysfs(fmt, args...)     LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
 #define lbs_deb_spi(fmt, args...)       LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
+#define lbs_deb_cfg80211(fmt, args...)  LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
 
 #define lbs_pr_info(format, args...) \
 	printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -320,7 +322,6 @@ static inline void lbs_deb_hex(unsigned
 extern const char lbs_driver_version[];
 extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
 
-extern u8 lbs_bg_rates[MAX_RATES];
 
 /** ENUM definition*/
 /** SNRNF_TYPE */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/dev.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/dev.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/dev.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/dev.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,75 +6,11 @@
 #ifndef _LBS_DEV_H_
 #define _LBS_DEV_H_
 
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <linux/ethtool.h>
-#include <linux/debugfs.h>
-
-#include "defs.h"
-#include "hostcmd.h"
-
-extern const struct ethtool_ops lbs_ethtool_ops;
-
-#define	MAX_BSSID_PER_CHANNEL		16
-
-#define NR_TX_QUEUE			3
-
-/* For the extended Scan */
-#define MAX_EXTENDED_SCAN_BSSID_LIST    MAX_BSSID_PER_CHANNEL * \
-						MRVDRV_MAX_CHANNEL_SIZE + 1
-
-#define	MAX_REGION_CHANNEL_NUM	2
-
-/** Chan-freq-TxPower mapping table*/
-struct chan_freq_power {
-	/** channel Number		*/
-	u16 channel;
-	/** frequency of this channel	*/
-	u32 freq;
-	/** Max allowed Tx power level	*/
-	u16 maxtxpower;
-	/** TRUE:channel unsupported;  FLASE:supported*/
-	u8 unsupported;
-};
-
-/** region-band mapping table*/
-struct region_channel {
-	/** TRUE if this entry is valid		     */
-	u8 valid;
-	/** region code for US, Japan ...	     */
-	u8 region;
-	/** band B/G/A, used for BAND_CONFIG cmd	     */
-	u8 band;
-	/** Actual No. of elements in the array below */
-	u8 nrcfp;
-	/** chan-freq-txpower mapping table*/
-	struct chan_freq_power *CFP;
-};
-
-struct lbs_802_11_security {
-	u8 WPAenabled;
-	u8 WPA2enabled;
-	u8 wep_enabled;
-	u8 auth_mode;
-	u32 key_mgmt;
-};
-
-/** Current Basic Service Set State Structure */
-struct current_bss_params {
-	/** bssid */
-	u8 bssid[ETH_ALEN];
-	/** ssid */
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
+#include "mesh.h"
+#include "scan.h"
+#include "assoc.h"
 
-	/** band */
-	u8 band;
-	/** channel */
-	u8 channel;
-	/** zero-terminated array of supported data rates */
-	u8 rates[MAX_RATES + 1];
-};
+#include <linux/kfifo.h>
 
 /** sleep_params */
 struct sleep_params {
@@ -86,205 +22,176 @@ struct sleep_params {
 	uint16_t sp_reserved;
 };
 
-/* Mesh statistics */
-struct lbs_mesh_stats {
-	u32	fwd_bcast_cnt;		/* Fwd: Broadcast counter */
-	u32	fwd_unicast_cnt;	/* Fwd: Unicast counter */
-	u32	fwd_drop_ttl;		/* Fwd: TTL zero */
-	u32	fwd_drop_rbt;		/* Fwd: Recently Broadcasted */
-	u32	fwd_drop_noroute; 	/* Fwd: No route to Destination */
-	u32	fwd_drop_nobuf;		/* Fwd: Run out of internal buffers */
-	u32	drop_blind;		/* Rx:  Dropped by blinding table */
-	u32	tx_failed_cnt;		/* Tx:  Failed transmissions */
-};
 
 /** Private structure for the MV device */
 struct lbs_private {
-	int mesh_open;
-	int mesh_fw_ver;
-	int infra_open;
-	int mesh_autostart_enabled;
-
-	char name[DEV_NAME_LEN];
 
-	void *card;
+	/* Basic networking */
 	struct net_device *dev;
+	u32 connect_status;
+	int infra_open;
+	struct work_struct mcast_work;
+	u32 nr_of_multicastmacaddr;
+	u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
 
+	/* CFG80211 */
+	struct wireless_dev *wdev;
+
+	/* Mesh */
 	struct net_device *mesh_dev; /* Virtual device */
+	u32 mesh_connect_status;
+	struct lbs_mesh_stats mstats;
+	int mesh_open;
+	int mesh_fw_ver;
+	int mesh_autostart_enabled;
+	uint16_t mesh_tlv;
+	u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 mesh_ssid_len;
+	struct work_struct sync_channel;
+
+	/* Monitor mode */
 	struct net_device *rtap_net_dev;
+	u32 monitormode;
 
-	struct iw_statistics wstats;
-	struct lbs_mesh_stats mstats;
+	/* Debugfs */
 	struct dentry *debugfs_dir;
 	struct dentry *debugfs_debug;
 	struct dentry *debugfs_files[6];
-
 	struct dentry *events_dir;
 	struct dentry *debugfs_events_files[6];
-
 	struct dentry *regs_dir;
 	struct dentry *debugfs_regs_files[6];
 
+	/* Hardware debugging */
 	u32 mac_offset;
 	u32 bbp_offset;
 	u32 rf_offset;
+	struct lbs_offset_value offsetvalue;
 
-	/* Download sent:
-	   bit0 1/0=data_sent/data_tx_done,
-	   bit1 1/0=cmd_sent/cmd_tx_done,
-	   all other bits reserved 0 */
-	u8 dnld_sent;
-
-	/** thread to service interrupts */
-	struct task_struct *main_thread;
-	wait_queue_head_t waitq;
-	struct workqueue_struct *work_thread;
-
-	struct work_struct mcast_work;
+	/* Power management */
+	u16 psmode;
+	u32 psstate;
+	u8 needtowakeup;
 
-	/** Scanning */
-	struct delayed_work scan_work;
-	struct delayed_work assoc_work;
-	struct work_struct sync_channel;
-	/* remember which channel was scanned last, != 0 if currently scanning */
-	int scan_channel;
-	u8 scan_ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 scan_ssid_len;
+	/* Deep sleep */
+	int is_deep_sleep;
+	int is_auto_deep_sleep_enabled;
+	int wakeup_dev_required;
+	int is_activity_detected;
+	int auto_deep_sleep_timeout; /* in ms */
+	wait_queue_head_t ds_awake_q;
+	struct timer_list auto_deepsleep_timer;
 
-	/** Hardware access */
+	/* Hardware access */
+	void *card;
+	u8 fw_ready;
+	u8 surpriseremoved;
 	int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
 	void (*reset_card) (struct lbs_private *priv);
+	int (*enter_deep_sleep) (struct lbs_private *priv);
+	int (*exit_deep_sleep) (struct lbs_private *priv);
+	int (*reset_deep_sleep_wakeup) (struct lbs_private *priv);
 
-	/* Wake On LAN */
-	uint32_t wol_criteria;
-	uint8_t wol_gpio;
-	uint8_t wol_gap;
-
-	/** Wlan adapter data structure*/
-	/** STATUS variables */
+	/* Adapter info (from EEPROM) */
 	u32 fwrelease;
 	u32 fwcapinfo;
+	u16 regioncode;
+	u8 current_addr[ETH_ALEN];
 
-	struct mutex lock;
-
-	/* TX packet ready to be sent... */
-	int tx_pending_len;		/* -1 while building packet */
-
-	u8 tx_pending_buf[LBS_UPLD_SIZE];
-	/* protected by hard_start_xmit serialization */
-
-	/** command-related variables */
+	/* Command download */
+	u8 dnld_sent;
+	/* bit0 1/0=data_sent/data_tx_done,
+	   bit1 1/0=cmd_sent/cmd_tx_done,
+	   all other bits reserved 0 */
 	u16 seqnum;
-
 	struct cmd_ctrl_node *cmd_array;
-	/** Current command */
 	struct cmd_ctrl_node *cur_cmd;
-	int cur_cmd_retcode;
-	/** command Queues */
-	/** Free command buffers */
-	struct list_head cmdfreeq;
-	/** Pending command buffers */
-	struct list_head cmdpendingq;
-
+	struct list_head cmdfreeq;    /* free command buffers */
+	struct list_head cmdpendingq; /* pending command buffers */
 	wait_queue_head_t cmd_pending;
+	struct timer_list command_timer;
+	int nr_retries;
+	int cmd_timed_out;
 
 	/* Command responses sent from the hardware to the driver */
+	int cur_cmd_retcode;
 	u8 resp_idx;
 	u8 resp_buf[2][LBS_UPLD_SIZE];
 	u32 resp_len[2];
 
 	/* Events sent from hardware to driver */
-	struct kfifo *event_fifo;
-
-	/* nickname */
-	u8 nodename[16];
-
-	/** spin locks */
-	spinlock_t driver_lock;
-
-	/** Timers */
-	struct timer_list command_timer;
-	int nr_retries;
-	int cmd_timed_out;
-
-	/** current ssid/bssid related parameters*/
-	struct current_bss_params curbssparams;
-
-	uint16_t mesh_tlv;
-	u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 mesh_ssid_len;
-
-	/* IW_MODE_* */
-	u8 mode;
-
-	/* Scan results list */
-	struct list_head network_list;
-	struct list_head network_free_list;
-	struct bss_descriptor *networks;
-
-	u16 beacon_period;
-	u8 beacon_enable;
-	u8 adhoccreate;
-
-	/** capability Info used in Association, start, join */
-	u16 capability;
+	struct kfifo event_fifo;
 
-	/** MAC address information */
-	u8 current_addr[ETH_ALEN];
-	u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
-	u32 nr_of_multicastmacaddr;
+	/** thread to service interrupts */
+	struct task_struct *main_thread;
+	wait_queue_head_t waitq;
+	struct workqueue_struct *work_thread;
 
-	/** 802.11 statistics */
-//	struct cmd_DS_802_11_GET_STAT wlan802_11Stat;
+	/** Encryption stuff */
+	struct lbs_802_11_security secinfo;
+	struct enc_key wpa_mcast_key;
+	struct enc_key wpa_unicast_key;
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	u8 wpa_ie_len;
+	u16 wep_tx_keyidx;
+	struct enc_key wep_keys[4];
 
-	uint16_t enablehwauto;
-	uint16_t ratebitmap;
+	/* Wake On LAN */
+	uint32_t wol_criteria;
+	uint8_t wol_gpio;
+	uint8_t wol_gap;
 
+	/* Transmitting */
+	int tx_pending_len;		/* -1 while building packet */
+	u8 tx_pending_buf[LBS_UPLD_SIZE];
+	/* protected by hard_start_xmit serialization */
 	u8 txretrycount;
-
-	/** Tx-related variables (for single packet tx) */
 	struct sk_buff *currenttxskb;
 
-	/** NIC Operation characteristics */
+	/* Locks */
+	struct mutex lock;
+	spinlock_t driver_lock;
+
+	/* NIC/link operation characteristics */
 	u16 mac_control;
-	u32 connect_status;
-	u32 mesh_connect_status;
-	u16 regioncode;
+	u8 radio_on;
+	u8 channel;
 	s16 txpower_cur;
 	s16 txpower_min;
 	s16 txpower_max;
 
-	/** POWER MANAGEMENT AND PnP SUPPORT */
-	u8 surpriseremoved;
-
-	u16 psmode;		/* Wlan802_11PowermodeCAM=disable
-				   Wlan802_11PowermodeMAX_PSP=enable */
-	u32 psstate;
-	u8 needtowakeup;
+	/** Scanning */
+	struct delayed_work scan_work;
+	int scan_channel;
+	/* remember which channel was scanned last, != 0 if currently scanning */
+	u8 scan_ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 scan_ssid_len;
 
+	/* Associating */
+	struct delayed_work assoc_work;
+	struct current_bss_params curbssparams;
+	u8 mode;
+	struct list_head network_list;
+	struct list_head network_free_list;
+	struct bss_descriptor *networks;
 	struct assoc_request * pending_assoc_req;
 	struct assoc_request * in_progress_assoc_req;
+	u16 capability;
+	uint16_t enablehwauto;
+	uint16_t ratebitmap;
 
-	/** Encryption parameter */
-	struct lbs_802_11_security secinfo;
-
-	/** WEP keys */
-	struct enc_key wep_keys[4];
-	u16 wep_tx_keyidx;
-
-	/** WPA keys */
-	struct enc_key wpa_mcast_key;
-	struct enc_key wpa_unicast_key;
-
-/*
- * In theory, the IE is limited to the IE length, 255,
- * but in practice 64 bytes are enough.
- */
-#define MAX_WPA_IE_LEN 64
+	/* ADHOC */
+	u16 beacon_period;
+	u8 beacon_enable;
+	u8 adhoccreate;
 
-	/** WPA Information Elements*/
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	u8 wpa_ie_len;
+	/* WEXT */
+	char name[DEV_NAME_LEN];
+	u8 nodename[16];
+	struct iw_statistics wstats;
+	u8 cur_rate;
+#define	MAX_REGION_CHANNEL_NUM	2
+	struct region_channel region_channel[MAX_REGION_CHANNEL_NUM];
 
 	/** Requested Signal Strength*/
 	u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
@@ -294,116 +201,8 @@ struct lbs_private {
 	u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
 	u16 nextSNRNF;
 	u16 numSNRNF;
-
-	u8 radio_on;
-
-	/** data rate stuff */
-	u8 cur_rate;
-
-	/** RF calibration data */
-
-#define	MAX_REGION_CHANNEL_NUM	2
-	/** region channel data */
-	struct region_channel region_channel[MAX_REGION_CHANNEL_NUM];
-
-	struct region_channel universal_channel[MAX_REGION_CHANNEL_NUM];
-
-	/** 11D and Domain Regulatory Data */
-	struct lbs_802_11d_domain_reg domainreg;
-	struct parsed_region_chan_11d parsed_region_chan;
-
-	/** FSM variable for 11d support */
-	u32 enable11d;
-
-	/**	MISCELLANEOUS */
-	struct lbs_offset_value offsetvalue;
-
-	u32 monitormode;
-	u8 fw_ready;
 };
 
 extern struct cmd_confirm_sleep confirm_sleep;
 
-/**
- *  @brief Structure used to store information for each beacon/probe response
- */
-struct bss_descriptor {
-	u8 bssid[ETH_ALEN];
-
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-
-	u16 capability;
-	u32 rssi;
-	u32 channel;
-	u16 beaconperiod;
-	__le16 atimwindow;
-
-	/* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
-	u8 mode;
-
-	/* zero-terminated array of supported data rates */
-	u8 rates[MAX_RATES + 1];
-
-	unsigned long last_scanned;
-
-	union ieee_phy_param_set phy;
-	union ieee_ss_param_set ss;
-
-	struct ieee_ie_country_info_full_set countryinfo;
-
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	size_t wpa_ie_len;
-	u8 rsn_ie[MAX_WPA_IE_LEN];
-	size_t rsn_ie_len;
-
-	u8 mesh;
-
-	struct list_head list;
-};
-
-/** Association request
- *
- * Encapsulates all the options that describe a specific assocation request
- * or configuration of the wireless card's radio, mode, and security settings.
- */
-struct assoc_request {
-#define ASSOC_FLAG_SSID			1
-#define ASSOC_FLAG_CHANNEL		2
-#define ASSOC_FLAG_BAND			3
-#define ASSOC_FLAG_MODE			4
-#define ASSOC_FLAG_BSSID		5
-#define ASSOC_FLAG_WEP_KEYS		6
-#define ASSOC_FLAG_WEP_TX_KEYIDX	7
-#define ASSOC_FLAG_WPA_MCAST_KEY	8
-#define ASSOC_FLAG_WPA_UCAST_KEY	9
-#define ASSOC_FLAG_SECINFO		10
-#define ASSOC_FLAG_WPA_IE		11
-	unsigned long flags;
-
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-	u8 channel;
-	u8 band;
-	u8 mode;
-	u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
-
-	/** WEP keys */
-	struct enc_key wep_keys[4];
-	u16 wep_tx_keyidx;
-
-	/** WPA keys */
-	struct enc_key wpa_mcast_key;
-	struct enc_key wpa_unicast_key;
-
-	struct lbs_802_11_security secinfo;
-
-	/** WPA Information Elements*/
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	u8 wpa_ie_len;
-
-	/* BSS to associate with for infrastructure of Ad-Hoc join */
-	struct bss_descriptor bss;
-};
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/ethtool.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/ethtool.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/ethtool.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/ethtool.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,17 +8,8 @@
 #include "dev.h"
 #include "wext.h"
 #include "cmd.h"
+#include "mesh.h"
 
-static const char * mesh_stat_strings[]= {
-			"drop_duplicate_bcast",
-			"drop_ttl_zero",
-			"drop_no_fwd_route",
-			"drop_no_buffers",
-			"fwded_unicast_cnt",
-			"fwded_bcast_cnt",
-			"drop_blind_table",
-			"tx_failed_cnt"
-};
 
 static void lbs_ethtool_get_drvinfo(struct net_device *dev,
 					 struct ethtool_drvinfo *info)
@@ -73,73 +64,6 @@ out:
         return ret;
 }
 
-static void lbs_ethtool_get_stats(struct net_device *dev,
-				  struct ethtool_stats *stats, uint64_t *data)
-{
-	struct lbs_private *priv = dev->ml_priv;
-	struct cmd_ds_mesh_access mesh_access;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_ETHTOOL);
-
-	/* Get Mesh Statistics */
-	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
-
-	if (ret) {
-		memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
-		return;
-	}
-
-	priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
-	priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
-	priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
-	priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
-	priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
-	priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
-	priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
-	priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
-
-	data[0] = priv->mstats.fwd_drop_rbt;
-	data[1] = priv->mstats.fwd_drop_ttl;
-	data[2] = priv->mstats.fwd_drop_noroute;
-	data[3] = priv->mstats.fwd_drop_nobuf;
-	data[4] = priv->mstats.fwd_unicast_cnt;
-	data[5] = priv->mstats.fwd_bcast_cnt;
-	data[6] = priv->mstats.drop_blind;
-	data[7] = priv->mstats.tx_failed_cnt;
-
-	lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
-
-static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
-{
-	struct lbs_private *priv = dev->ml_priv;
-
-	if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
-		return MESH_STATS_NUM;
-
-	return -EOPNOTSUPP;
-}
-
-static void lbs_ethtool_get_strings(struct net_device *dev,
-				    uint32_t stringset, uint8_t *s)
-{
-	int i;
-
-	lbs_deb_enter(LBS_DEB_ETHTOOL);
-
-	switch (stringset) {
-        case ETH_SS_STATS:
-		for (i=0; i < MESH_STATS_NUM; i++) {
-			memcpy(s + i * ETH_GSTRING_LEN,
-					mesh_stat_strings[i],
-					ETH_GSTRING_LEN);
-		}
-		break;
-        }
-	lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
-
 static void lbs_ethtool_get_wol(struct net_device *dev,
 				struct ethtool_wolinfo *wol)
 {
@@ -190,9 +114,9 @@ const struct ethtool_ops lbs_ethtool_ops
 	.get_drvinfo = lbs_ethtool_get_drvinfo,
 	.get_eeprom =  lbs_ethtool_get_eeprom,
 	.get_eeprom_len = lbs_ethtool_get_eeprom_len,
-	.get_sset_count = lbs_ethtool_get_sset_count,
-	.get_ethtool_stats = lbs_ethtool_get_stats,
-	.get_strings = lbs_ethtool_get_strings,
+	.get_sset_count = lbs_mesh_ethtool_get_sset_count,
+	.get_ethtool_stats = lbs_mesh_ethtool_get_stats,
+	.get_strings = lbs_mesh_ethtool_get_strings,
 	.get_wol = lbs_ethtool_get_wol,
 	.set_wol = lbs_ethtool_set_wol,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/hostcmd.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/hostcmd.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/hostcmd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/hostcmd.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,800 +0,0 @@
-/*
- * This file contains the function prototypes, data structure
- * and defines for all the host/station commands
- */
-#ifndef _LBS_HOSTCMD_H
-#define _LBS_HOSTCMD_H
-
-#include <linux/wireless.h>
-#include "11d.h"
-#include "types.h"
-
-/* 802.11-related definitions */
-
-/* TxPD descriptor */
-struct txpd {
-	/* union to cope up with later FW revisions */
-	union {
-		/* Current Tx packet status */
-		__le32 tx_status;
-		struct {
-			/* BSS type: client, AP, etc. */
-			u8 bss_type;
-			/* BSS number */
-			u8 bss_num;
-			/* Reserved */
-			__le16 reserved;
-		} bss;
-	} u;
-	/* Tx control */
-	__le32 tx_control;
-	__le32 tx_packet_location;
-	/* Tx packet length */
-	__le16 tx_packet_length;
-	/* First 2 byte of destination MAC address */
-	u8 tx_dest_addr_high[2];
-	/* Last 4 byte of destination MAC address */
-	u8 tx_dest_addr_low[4];
-	/* Pkt Priority */
-	u8 priority;
-	/* Pkt Trasnit Power control */
-	u8 powermgmt;
-	/* Amount of time the packet has been queued in the driver (units = 2ms) */
-	u8 pktdelay_2ms;
-	/* reserved */
-	u8 reserved1;
-} __attribute__ ((packed));
-
-/* RxPD Descriptor */
-struct rxpd {
-	/* union to cope up with later FW revisions */
-	union {
-		/* Current Rx packet status */
-		__le16 status;
-		struct {
-			/* BSS type: client, AP, etc. */
-			u8 bss_type;
-			/* BSS number */
-			u8 bss_num;
-		} __attribute__ ((packed)) bss;
-	} __attribute__ ((packed)) u;
-
-	/* SNR */
-	u8 snr;
-
-	/* Tx control */
-	u8 rx_control;
-
-	/* Pkt length */
-	__le16 pkt_len;
-
-	/* Noise Floor */
-	u8 nf;
-
-	/* Rx Packet Rate */
-	u8 rx_rate;
-
-	/* Pkt addr */
-	__le32 pkt_ptr;
-
-	/* Next Rx RxPD addr */
-	__le32 next_rxpd_ptr;
-
-	/* Pkt Priority */
-	u8 priority;
-	u8 reserved[3];
-} __attribute__ ((packed));
-
-struct cmd_header {
-	__le16 command;
-	__le16 size;
-	__le16 seqnum;
-	__le16 result;
-} __attribute__ ((packed));
-
-struct cmd_ctrl_node {
-	struct list_head list;
-	int result;
-	/* command response */
-	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
-	unsigned long callback_arg;
-	/* command data */
-	struct cmd_header *cmdbuf;
-	/* wait queue */
-	u16 cmdwaitqwoken;
-	wait_queue_head_t cmdwait_q;
-};
-
-/* Generic structure to hold all key types. */
-struct enc_key {
-	u16 len;
-	u16 flags;  /* KEY_INFO_* from defs.h */
-	u16 type; /* KEY_TYPE_* from defs.h */
-	u8 key[32];
-};
-
-/* lbs_offset_value */
-struct lbs_offset_value {
-	u32 offset;
-	u32 value;
-} __attribute__ ((packed));
-
-/* Define general data structure */
-/* cmd_DS_GEN */
-struct cmd_ds_gen {
-	__le16 command;
-	__le16 size;
-	__le16 seqnum;
-	__le16 result;
-	void *cmdresp[0];
-} __attribute__ ((packed));
-
-#define S_DS_GEN sizeof(struct cmd_ds_gen)
-
-
-/*
- * Define data structure for CMD_GET_HW_SPEC
- * This structure defines the response for the GET_HW_SPEC command
- */
-struct cmd_ds_get_hw_spec {
-	struct cmd_header hdr;
-
-	/* HW Interface version number */
-	__le16 hwifversion;
-	/* HW version number */
-	__le16 version;
-	/* Max number of TxPD FW can handle */
-	__le16 nr_txpd;
-	/* Max no of Multicast address */
-	__le16 nr_mcast_adr;
-	/* MAC address */
-	u8 permanentaddr[6];
-
-	/* region Code */
-	__le16 regioncode;
-
-	/* Number of antenna used */
-	__le16 nr_antenna;
-
-	/* FW release number, example 0x01030304 = 2.3.4p1 */
-	__le32 fwrelease;
-
-	/* Base Address of TxPD queue */
-	__le32 wcb_base;
-	/* Read Pointer of RxPd queue */
-	__le32 rxpd_rdptr;
-
-	/* Write Pointer of RxPd queue */
-	__le32 rxpd_wrptr;
-
-	/*FW/HW capability */
-	__le32 fwcapinfo;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_subscribe_event {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 events;
-
-	/* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a
-	 * number of TLVs. From the v5.1 manual, those TLVs would add up to
-	 * 40 bytes. However, future firmware might add additional TLVs, so I
-	 * bump this up a bit.
-	 */
-	uint8_t tlv[128];
-} __attribute__ ((packed));
-
-/*
- * This scan handle Country Information IE(802.11d compliant)
- * Define data structure for CMD_802_11_SCAN
- */
-struct cmd_ds_802_11_scan {
-	struct cmd_header hdr;
-
-	uint8_t bsstype;
-	uint8_t bssid[ETH_ALEN];
-	uint8_t tlvbuffer[0];
-#if 0
-	mrvlietypes_ssidparamset_t ssidParamSet;
-	mrvlietypes_chanlistparamset_t ChanListParamSet;
-	mrvlietypes_ratesparamset_t OpRateSet;
-#endif
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_scan_rsp {
-	struct cmd_header hdr;
-
-	__le16 bssdescriptsize;
-	uint8_t nr_sets;
-	uint8_t bssdesc_and_tlvbuffer[0];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_get_log {
-	struct cmd_header hdr;
-
-	__le32 mcasttxframe;
-	__le32 failed;
-	__le32 retry;
-	__le32 multiretry;
-	__le32 framedup;
-	__le32 rtssuccess;
-	__le32 rtsfailure;
-	__le32 ackfailure;
-	__le32 rxfrag;
-	__le32 mcastrxframe;
-	__le32 fcserror;
-	__le32 txframe;
-	__le32 wepundecryptable;
-} __attribute__ ((packed));
-
-struct cmd_ds_mac_control {
-	struct cmd_header hdr;
-	__le16 action;
-	u16 reserved;
-} __attribute__ ((packed));
-
-struct cmd_ds_mac_multicast_adr {
-	struct cmd_header hdr;
-	__le16 action;
-	__le16 nr_of_adrs;
-	u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
-} __attribute__ ((packed));
-
-struct cmd_ds_gspi_bus_config {
-	struct cmd_header hdr;
-	__le16 action;
-	__le16 bus_delay_mode;
-	__le16 host_time_delay_to_read_port;
-	__le16 host_time_delay_to_read_register;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_authenticate {
-	struct cmd_header hdr;
-
-	u8 bssid[ETH_ALEN];
-	u8 authtype;
-	u8 reserved[10];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_deauthenticate {
-	struct cmd_header hdr;
-
-	u8 macaddr[ETH_ALEN];
-	__le16 reasoncode;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_associate {
-	struct cmd_header hdr;
-
-	u8 bssid[6];
-	__le16 capability;
-	__le16 listeninterval;
-	__le16 bcnperiod;
-	u8 dtimperiod;
-	u8 iebuf[512];    /* Enough for required and most optional IEs */
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_associate_response {
-	struct cmd_header hdr;
-
-	__le16 capability;
-	__le16 statuscode;
-	__le16 aid;
-	u8 iebuf[512];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_set_wep {
-	struct cmd_header hdr;
-
-	/* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
-	__le16 action;
-
-	/* key Index selected for Tx */
-	__le16 keyindex;
-
-	/* 40, 128bit or TXWEP */
-	uint8_t keytype[4];
-	uint8_t keymaterial[4][16];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_3_get_stat {
-	__le32 xmitok;
-	__le32 rcvok;
-	__le32 xmiterror;
-	__le32 rcverror;
-	__le32 rcvnobuffer;
-	__le32 rcvcrcerror;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_get_stat {
-	__le32 txfragmentcnt;
-	__le32 mcasttxframecnt;
-	__le32 failedcnt;
-	__le32 retrycnt;
-	__le32 Multipleretrycnt;
-	__le32 rtssuccesscnt;
-	__le32 rtsfailurecnt;
-	__le32 ackfailurecnt;
-	__le32 frameduplicatecnt;
-	__le32 rxfragmentcnt;
-	__le32 mcastrxframecnt;
-	__le32 fcserrorcnt;
-	__le32 bcasttxframecnt;
-	__le32 bcastrxframecnt;
-	__le32 txbeacon;
-	__le32 rxbeacon;
-	__le32 wepundecryptable;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_snmp_mib {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 oid;
-	__le16 bufsize;
-	u8 value[128];
-} __attribute__ ((packed));
-
-struct cmd_ds_mac_reg_map {
-	__le16 buffersize;
-	u8 regmap[128];
-	__le16 reserved;
-} __attribute__ ((packed));
-
-struct cmd_ds_bbp_reg_map {
-	__le16 buffersize;
-	u8 regmap[128];
-	__le16 reserved;
-} __attribute__ ((packed));
-
-struct cmd_ds_rf_reg_map {
-	__le16 buffersize;
-	u8 regmap[64];
-	__le16 reserved;
-} __attribute__ ((packed));
-
-struct cmd_ds_mac_reg_access {
-	__le16 action;
-	__le16 offset;
-	__le32 value;
-} __attribute__ ((packed));
-
-struct cmd_ds_bbp_reg_access {
-	__le16 action;
-	__le16 offset;
-	u8 value;
-	u8 reserved[3];
-} __attribute__ ((packed));
-
-struct cmd_ds_rf_reg_access {
-	__le16 action;
-	__le16 offset;
-	u8 value;
-	u8 reserved[3];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_radio_control {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 control;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_beacon_control {
-	__le16 action;
-	__le16 beacon_enable;
-	__le16 beacon_period;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_sleep_params {
-	struct cmd_header hdr;
-
-	/* ACT_GET/ACT_SET */
-	__le16 action;
-
-	/* Sleep clock error in ppm */
-	__le16 error;
-
-	/* Wakeup offset in usec */
-	__le16 offset;
-
-	/* Clock stabilization time in usec */
-	__le16 stabletime;
-
-	/* control periodic calibration */
-	uint8_t calcontrol;
-
-	/* control the use of external sleep clock */
-	uint8_t externalsleepclk;
-
-	/* reserved field, should be set to zero */
-	__le16 reserved;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_inactivity_timeout {
-	struct cmd_header hdr;
-
-	/* ACT_GET/ACT_SET */
-	__le16 action;
-
-	/* Inactivity timeout in msec */
-	__le16 timeout;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rf_channel {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 channel;
-	__le16 rftype;      /* unused */
-	__le16 reserved;    /* unused */
-	u8 channellist[32]; /* unused */
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rssi {
-	/* weighting factor */
-	__le16 N;
-
-	__le16 reserved_0;
-	__le16 reserved_1;
-	__le16 reserved_2;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rssi_rsp {
-	__le16 SNR;
-	__le16 noisefloor;
-	__le16 avgSNR;
-	__le16 avgnoisefloor;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_mac_address {
-	struct cmd_header hdr;
-
-	__le16 action;
-	u8 macadd[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rf_tx_power {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 curlevel;
-	s8 maxlevel;
-	s8 minlevel;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rf_antenna {
-	__le16 action;
-
-	/* Number of antennas or 0xffff(diversity) */
-	__le16 antennamode;
-
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_monitor_mode {
-	__le16 action;
-	__le16 mode;
-} __attribute__ ((packed));
-
-struct cmd_ds_set_boot2_ver {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 version;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_fw_wake_method {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 method;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_sleep_period {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 period;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_ps_mode {
-	__le16 action;
-	__le16 nullpktinterval;
-	__le16 multipledtim;
-	__le16 reserved;
-	__le16 locallisteninterval;
-} __attribute__ ((packed));
-
-struct cmd_confirm_sleep {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 nullpktinterval;
-	__le16 multipledtim;
-	__le16 reserved;
-	__le16 locallisteninterval;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_data_rate {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 reserved;
-	u8 rates[MAX_RATES];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_rate_adapt_rateset {
-	struct cmd_header hdr;
-	__le16 action;
-	__le16 enablehwauto;
-	__le16 bitmap;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_ad_hoc_start {
-	struct cmd_header hdr;
-
-	u8 ssid[IW_ESSID_MAX_SIZE];
-	u8 bsstype;
-	__le16 beaconperiod;
-	u8 dtimperiod;   /* Reserved on v9 and later */
-	struct ieee_ie_ibss_param_set ibss;
-	u8 reserved1[4];
-	struct ieee_ie_ds_param_set ds;
-	u8 reserved2[4];
-	__le16 probedelay;  /* Reserved on v9 and later */
-	__le16 capability;
-	u8 rates[MAX_RATES];
-	u8 tlv_memory_size_pad[100];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_ad_hoc_result {
-	struct cmd_header hdr;
-
-	u8 pad[3];
-	u8 bssid[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct adhoc_bssdesc {
-	u8 bssid[ETH_ALEN];
-	u8 ssid[IW_ESSID_MAX_SIZE];
-	u8 type;
-	__le16 beaconperiod;
-	u8 dtimperiod;
-	__le64 timestamp;
-	__le64 localtime;
-	struct ieee_ie_ds_param_set ds;
-	u8 reserved1[4];
-	struct ieee_ie_ibss_param_set ibss;
-	u8 reserved2[4];
-	__le16 capability;
-	u8 rates[MAX_RATES];
-
-	/* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
-	 * Adhoc join command and will cause a binary layout mismatch with
-	 * the firmware
-	 */
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_ad_hoc_join {
-	struct cmd_header hdr;
-
-	struct adhoc_bssdesc bss;
-	__le16 failtimeout;   /* Reserved on v9 and later */
-	__le16 probedelay;    /* Reserved on v9 and later */
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_ad_hoc_stop {
-	struct cmd_header hdr;
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_enable_rsn {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le16 enable;
-} __attribute__ ((packed));
-
-struct MrvlIEtype_keyParamSet {
-	/* type ID */
-	__le16 type;
-
-	/* length of Payload */
-	__le16 length;
-
-	/* type of key: WEP=0, TKIP=1, AES=2 */
-	__le16 keytypeid;
-
-	/* key control Info specific to a keytypeid */
-	__le16 keyinfo;
-
-	/* length of key */
-	__le16 keylen;
-
-	/* key material of size keylen */
-	u8 key[32];
-} __attribute__ ((packed));
-
-#define MAX_WOL_RULES 		16
-
-struct host_wol_rule {
-	uint8_t rule_no;
-	uint8_t rule_ops;
-	__le16 sig_offset;
-	__le16 sig_length;
-	__le16 reserve;
-	__be32 sig_mask;
-	__be32 signature;
-} __attribute__ ((packed));
-
-struct wol_config {
-	uint8_t action;
-	uint8_t pattern;
-	uint8_t no_rules_in_cmd;
-	uint8_t result;
-	struct host_wol_rule rule[MAX_WOL_RULES];
-} __attribute__ ((packed));
-
-struct cmd_ds_host_sleep {
-	struct cmd_header hdr;
-	__le32 criteria;
-	uint8_t gpio;
-	uint16_t gap;
-	struct wol_config wol_conf;
-} __attribute__ ((packed));
-
-
-
-struct cmd_ds_802_11_key_material {
-	struct cmd_header hdr;
-
-	__le16 action;
-	struct MrvlIEtype_keyParamSet keyParamSet[2];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_eeprom_access {
-	struct cmd_header hdr;
-	__le16 action;
-	__le16 offset;
-	__le16 len;
-	/* firmware says it returns a maximum of 20 bytes */
-#define LBS_EEPROM_READ_LEN 20
-	u8 value[LBS_EEPROM_READ_LEN];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_tpc_cfg {
-	struct cmd_header hdr;
-
-	__le16 action;
-	uint8_t enable;
-	int8_t P0;
-	int8_t P1;
-	int8_t P2;
-	uint8_t usesnr;
-} __attribute__ ((packed));
-
-
-struct cmd_ds_802_11_pa_cfg {
-	struct cmd_header hdr;
-
-	__le16 action;
-	uint8_t enable;
-	int8_t P0;
-	int8_t P1;
-	int8_t P2;
-} __attribute__ ((packed));
-
-
-struct cmd_ds_802_11_led_ctrl {
-	__le16 action;
-	__le16 numled;
-	u8 data[256];
-} __attribute__ ((packed));
-
-struct cmd_ds_802_11_afc {
-	__le16 afc_auto;
-	union {
-		struct {
-			__le16 threshold;
-			__le16 period;
-		};
-		struct {
-			__le16 timing_offset; /* signed */
-			__le16 carrier_offset; /* signed */
-		};
-	};
-} __attribute__ ((packed));
-
-struct cmd_tx_rate_query {
-	__le16 txrate;
-} __attribute__ ((packed));
-
-struct cmd_ds_get_tsf {
-	__le64 tsfvalue;
-} __attribute__ ((packed));
-
-struct cmd_ds_bt_access {
-	__le16 action;
-	__le32 id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct cmd_ds_fwt_access {
-	__le16 action;
-	__le32 id;
-	u8 valid;
-	u8 da[ETH_ALEN];
-	u8 dir;
-	u8 ra[ETH_ALEN];
-	__le32 ssn;
-	__le32 dsn;
-	__le32 metric;
-	u8 rate;
-	u8 hopcount;
-	u8 ttl;
-	__le32 expiration;
-	u8 sleepmode;
-	__le32 snr;
-	__le32 references;
-	u8 prec[ETH_ALEN];
-} __attribute__ ((packed));
-
-
-struct cmd_ds_mesh_config {
-	struct cmd_header hdr;
-
-        __le16 action;
-        __le16 channel;
-        __le16 type;
-        __le16 length;
-        u8 data[128];   /* last position reserved */
-} __attribute__ ((packed));
-
-
-struct cmd_ds_mesh_access {
-	struct cmd_header hdr;
-
-	__le16 action;
-	__le32 data[32];	/* last position reserved */
-} __attribute__ ((packed));
-
-/* Number of stats counters returned by the firmware */
-#define MESH_STATS_NUM 8
-
-struct cmd_ds_command {
-	/* command header */
-	__le16 command;
-	__le16 size;
-	__le16 seqnum;
-	__le16 result;
-
-	/* command Body */
-	union {
-		struct cmd_ds_802_11_ps_mode psmode;
-		struct cmd_ds_802_11_get_stat gstat;
-		struct cmd_ds_802_3_get_stat gstat_8023;
-		struct cmd_ds_802_11_rf_antenna rant;
-		struct cmd_ds_802_11_monitor_mode monitor;
-		struct cmd_ds_802_11_rssi rssi;
-		struct cmd_ds_802_11_rssi_rsp rssirsp;
-		struct cmd_ds_mac_reg_access macreg;
-		struct cmd_ds_bbp_reg_access bbpreg;
-		struct cmd_ds_rf_reg_access rfreg;
-
-		struct cmd_ds_802_11d_domain_info domaininfo;
-		struct cmd_ds_802_11d_domain_info domaininforesp;
-
-		struct cmd_ds_802_11_tpc_cfg tpccfg;
-		struct cmd_ds_802_11_afc afc;
-		struct cmd_ds_802_11_led_ctrl ledgpio;
-
-		struct cmd_tx_rate_query txrate;
-		struct cmd_ds_bt_access bt;
-		struct cmd_ds_fwt_access fwt;
-		struct cmd_ds_get_tsf gettsf;
-		struct cmd_ds_802_11_beacon_control bcn_ctrl;
-	} params;
-} __attribute__ ((packed));
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/host.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/host.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/host.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/host.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,201 +1,190 @@
 /**
-  * This file contains definitions of WLAN commands.
+  * This file function prototypes, data structure
+  * and  definitions for all the host/station commands
   */
 
 #ifndef _LBS_HOST_H_
 #define _LBS_HOST_H_
 
-/** PUBLIC DEFINITIONS */
-#define DEFAULT_AD_HOC_CHANNEL			6
-#define	DEFAULT_AD_HOC_CHANNEL_A		36
+#include "types.h"
+#include "defs.h"
 
-#define CMD_OPTION_WAITFORRSP			0x0002
+#define DEFAULT_AD_HOC_CHANNEL                  6
+
+#define CMD_OPTION_WAITFORRSP                   0x0002
 
 /** Host command IDs */
 
 /* Return command are almost always the same as the host command, but with
  * bit 15 set high.  There are a few exceptions, though...
  */
-#define CMD_RET(cmd)			(0x8000 | cmd)
+#define CMD_RET(cmd)                            (0x8000 | cmd)
 
 /* Return command convention exceptions: */
-#define CMD_RET_802_11_ASSOCIATE		0x8012
+#define CMD_RET_802_11_ASSOCIATE                0x8012
 
 /* Command codes */
-#define CMD_GET_HW_SPEC				0x0003
-#define	CMD_EEPROM_UPDATE			0x0004
-#define CMD_802_11_RESET			0x0005
-#define	CMD_802_11_SCAN				0x0006
-#define CMD_802_11_GET_LOG			0x000b
-#define CMD_MAC_MULTICAST_ADR			0x0010
-#define CMD_802_11_AUTHENTICATE			0x0011
-#define CMD_802_11_EEPROM_ACCESS		0x0059
-#define CMD_802_11_ASSOCIATE			0x0050
-#define CMD_802_11_SET_WEP			0x0013
-#define CMD_802_11_GET_STAT			0x0014
-#define CMD_802_3_GET_STAT			0x0015
-#define CMD_802_11_SNMP_MIB			0x0016
-#define CMD_MAC_REG_MAP				0x0017
-#define CMD_BBP_REG_MAP				0x0018
-#define CMD_MAC_REG_ACCESS			0x0019
-#define CMD_BBP_REG_ACCESS			0x001a
-#define CMD_RF_REG_ACCESS			0x001b
-#define CMD_802_11_RADIO_CONTROL		0x001c
-#define CMD_802_11_RF_CHANNEL			0x001d
-#define CMD_802_11_RF_TX_POWER			0x001e
-#define CMD_802_11_RSSI				0x001f
-#define CMD_802_11_RF_ANTENNA			0x0020
-#define CMD_802_11_PS_MODE			0x0021
-#define CMD_802_11_DATA_RATE			0x0022
-#define CMD_RF_REG_MAP				0x0023
-#define CMD_802_11_DEAUTHENTICATE		0x0024
-#define CMD_802_11_REASSOCIATE			0x0025
-#define CMD_MAC_CONTROL				0x0028
-#define CMD_802_11_AD_HOC_START			0x002b
-#define CMD_802_11_AD_HOC_JOIN			0x002c
-#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS	0x002e
-#define CMD_802_11_ENABLE_RSN			0x002f
-#define CMD_802_11_SET_AFC			0x003c
-#define CMD_802_11_GET_AFC			0x003d
-#define CMD_802_11_AD_HOC_STOP			0x0040
-#define CMD_802_11_HOST_SLEEP_CFG		0x0043
-#define CMD_802_11_WAKEUP_CONFIRM		0x0044
-#define CMD_802_11_HOST_SLEEP_ACTIVATE		0x0045
-#define CMD_802_11_BEACON_STOP			0x0049
-#define CMD_802_11_MAC_ADDRESS			0x004d
-#define CMD_802_11_LED_GPIO_CTRL		0x004e
-#define CMD_802_11_EEPROM_ACCESS		0x0059
-#define CMD_802_11_BAND_CONFIG			0x0058
-#define CMD_GSPI_BUS_CONFIG			0x005a
-#define CMD_802_11D_DOMAIN_INFO			0x005b
-#define CMD_802_11_KEY_MATERIAL			0x005e
-#define CMD_802_11_SLEEP_PARAMS			0x0066
-#define CMD_802_11_INACTIVITY_TIMEOUT		0x0067
-#define CMD_802_11_SLEEP_PERIOD			0x0068
-#define CMD_802_11_TPC_CFG			0x0072
-#define CMD_802_11_PA_CFG			0x0073
-#define CMD_802_11_FW_WAKE_METHOD		0x0074
-#define CMD_802_11_SUBSCRIBE_EVENT		0x0075
-#define CMD_802_11_RATE_ADAPT_RATESET		0x0076
-#define CMD_802_11_TX_RATE_QUERY		0x007f
-#define	CMD_GET_TSF				0x0080
-#define CMD_BT_ACCESS				0x0087
-#define CMD_FWT_ACCESS				0x0095
-#define CMD_802_11_MONITOR_MODE			0x0098
-#define CMD_MESH_ACCESS				0x009b
-#define CMD_MESH_CONFIG_OLD			0x00a3
-#define CMD_MESH_CONFIG				0x00ac
-#define	CMD_SET_BOOT2_VER			0x00a5
-#define	CMD_FUNC_INIT				0x00a9
-#define	CMD_FUNC_SHUTDOWN			0x00aa
-#define CMD_802_11_BEACON_CTRL			0x00b0
+#define CMD_GET_HW_SPEC                         0x0003
+#define CMD_EEPROM_UPDATE                       0x0004
+#define CMD_802_11_RESET                        0x0005
+#define CMD_802_11_SCAN                         0x0006
+#define CMD_802_11_GET_LOG                      0x000b
+#define CMD_MAC_MULTICAST_ADR                   0x0010
+#define CMD_802_11_AUTHENTICATE                 0x0011
+#define CMD_802_11_EEPROM_ACCESS                0x0059
+#define CMD_802_11_ASSOCIATE                    0x0050
+#define CMD_802_11_SET_WEP                      0x0013
+#define CMD_802_11_GET_STAT                     0x0014
+#define CMD_802_3_GET_STAT                      0x0015
+#define CMD_802_11_SNMP_MIB                     0x0016
+#define CMD_MAC_REG_MAP                         0x0017
+#define CMD_BBP_REG_MAP                         0x0018
+#define CMD_MAC_REG_ACCESS                      0x0019
+#define CMD_BBP_REG_ACCESS                      0x001a
+#define CMD_RF_REG_ACCESS                       0x001b
+#define CMD_802_11_RADIO_CONTROL                0x001c
+#define CMD_802_11_RF_CHANNEL                   0x001d
+#define CMD_802_11_RF_TX_POWER                  0x001e
+#define CMD_802_11_RSSI                         0x001f
+#define CMD_802_11_RF_ANTENNA                   0x0020
+#define CMD_802_11_PS_MODE                      0x0021
+#define CMD_802_11_DATA_RATE                    0x0022
+#define CMD_RF_REG_MAP                          0x0023
+#define CMD_802_11_DEAUTHENTICATE               0x0024
+#define CMD_802_11_REASSOCIATE                  0x0025
+#define CMD_MAC_CONTROL                         0x0028
+#define CMD_802_11_AD_HOC_START                 0x002b
+#define CMD_802_11_AD_HOC_JOIN                  0x002c
+#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS       0x002e
+#define CMD_802_11_ENABLE_RSN                   0x002f
+#define CMD_802_11_SET_AFC                      0x003c
+#define CMD_802_11_GET_AFC                      0x003d
+#define CMD_802_11_DEEP_SLEEP                   0x003e
+#define CMD_802_11_AD_HOC_STOP                  0x0040
+#define CMD_802_11_HOST_SLEEP_CFG               0x0043
+#define CMD_802_11_WAKEUP_CONFIRM               0x0044
+#define CMD_802_11_HOST_SLEEP_ACTIVATE          0x0045
+#define CMD_802_11_BEACON_STOP                  0x0049
+#define CMD_802_11_MAC_ADDRESS                  0x004d
+#define CMD_802_11_LED_GPIO_CTRL                0x004e
+#define CMD_802_11_EEPROM_ACCESS                0x0059
+#define CMD_802_11_BAND_CONFIG                  0x0058
+#define CMD_GSPI_BUS_CONFIG                     0x005a
+#define CMD_802_11D_DOMAIN_INFO                 0x005b
+#define CMD_802_11_KEY_MATERIAL                 0x005e
+#define CMD_802_11_SLEEP_PARAMS                 0x0066
+#define CMD_802_11_INACTIVITY_TIMEOUT           0x0067
+#define CMD_802_11_SLEEP_PERIOD                 0x0068
+#define CMD_802_11_TPC_CFG                      0x0072
+#define CMD_802_11_PA_CFG                       0x0073
+#define CMD_802_11_FW_WAKE_METHOD               0x0074
+#define CMD_802_11_SUBSCRIBE_EVENT              0x0075
+#define CMD_802_11_RATE_ADAPT_RATESET           0x0076
+#define CMD_802_11_TX_RATE_QUERY                0x007f
+#define CMD_GET_TSF                             0x0080
+#define CMD_BT_ACCESS                           0x0087
+#define CMD_FWT_ACCESS                          0x0095
+#define CMD_802_11_MONITOR_MODE                 0x0098
+#define CMD_MESH_ACCESS                         0x009b
+#define CMD_MESH_CONFIG_OLD                     0x00a3
+#define CMD_MESH_CONFIG                         0x00ac
+#define CMD_SET_BOOT2_VER                       0x00a5
+#define CMD_FUNC_INIT                           0x00a9
+#define CMD_FUNC_SHUTDOWN                       0x00aa
+#define CMD_802_11_BEACON_CTRL                  0x00b0
 
 /* For the IEEE Power Save */
-#define CMD_SUBCMD_ENTER_PS		0x0030
-#define CMD_SUBCMD_EXIT_PS		0x0031
-#define CMD_SUBCMD_SLEEP_CONFIRMED	0x0034
-#define CMD_SUBCMD_FULL_POWERDOWN	0x0035
-#define CMD_SUBCMD_FULL_POWERUP		0x0036
+#define CMD_SUBCMD_ENTER_PS                     0x0030
+#define CMD_SUBCMD_EXIT_PS                      0x0031
+#define CMD_SUBCMD_SLEEP_CONFIRMED              0x0034
+#define CMD_SUBCMD_FULL_POWERDOWN               0x0035
+#define CMD_SUBCMD_FULL_POWERUP                 0x0036
 
-#define CMD_ENABLE_RSN			0x0001
-#define CMD_DISABLE_RSN			0x0000
+#define CMD_ENABLE_RSN                          0x0001
+#define CMD_DISABLE_RSN                         0x0000
 
-#define CMD_ACT_GET			0x0000
-#define CMD_ACT_SET			0x0001
-#define CMD_ACT_GET_AES			0x0002
-#define CMD_ACT_SET_AES			0x0003
-#define CMD_ACT_REMOVE_AES		0x0004
+#define CMD_ACT_GET                             0x0000
+#define CMD_ACT_SET                             0x0001
 
 /* Define action or option for CMD_802_11_SET_WEP */
-#define CMD_ACT_ADD			0x0002
-#define CMD_ACT_REMOVE			0x0004
-#define CMD_ACT_USE_DEFAULT		0x0008
-
-#define CMD_TYPE_WEP_40_BIT		0x01
-#define CMD_TYPE_WEP_104_BIT		0x02
+#define CMD_ACT_ADD                             0x0002
+#define CMD_ACT_REMOVE                          0x0004
 
-#define CMD_NUM_OF_WEP_KEYS		4
+#define CMD_TYPE_WEP_40_BIT                     0x01
+#define CMD_TYPE_WEP_104_BIT                    0x02
 
-#define CMD_WEP_KEY_INDEX_MASK		0x3fff
+#define CMD_NUM_OF_WEP_KEYS                     4
 
-/* Define action or option for CMD_802_11_RESET */
-#define CMD_ACT_HALT			0x0003
+#define CMD_WEP_KEY_INDEX_MASK                  0x3fff
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_BSS_TYPE_BSS		0x0001
-#define CMD_BSS_TYPE_IBSS		0x0002
-#define CMD_BSS_TYPE_ANY		0x0003
+#define CMD_BSS_TYPE_BSS                        0x0001
+#define CMD_BSS_TYPE_IBSS                       0x0002
+#define CMD_BSS_TYPE_ANY                        0x0003
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_SCAN_TYPE_ACTIVE		0x0000
-#define CMD_SCAN_TYPE_PASSIVE		0x0001
+#define CMD_SCAN_TYPE_ACTIVE                    0x0000
+#define CMD_SCAN_TYPE_PASSIVE                   0x0001
 
-#define CMD_SCAN_RADIO_TYPE_BG		0
+#define CMD_SCAN_RADIO_TYPE_BG                  0
 
-#define	CMD_SCAN_PROBE_DELAY_TIME	0
+#define CMD_SCAN_PROBE_DELAY_TIME               0
 
 /* Define action or option for CMD_MAC_CONTROL */
-#define CMD_ACT_MAC_RX_ON			0x0001
-#define CMD_ACT_MAC_TX_ON			0x0002
-#define CMD_ACT_MAC_LOOPBACK_ON			0x0004
-#define CMD_ACT_MAC_WEP_ENABLE			0x0008
-#define CMD_ACT_MAC_INT_ENABLE			0x0010
-#define CMD_ACT_MAC_MULTICAST_ENABLE		0x0020
-#define CMD_ACT_MAC_BROADCAST_ENABLE		0x0040
-#define CMD_ACT_MAC_PROMISCUOUS_ENABLE		0x0080
-#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE	0x0100
-#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE	0x0400
+#define CMD_ACT_MAC_RX_ON                       0x0001
+#define CMD_ACT_MAC_TX_ON                       0x0002
+#define CMD_ACT_MAC_LOOPBACK_ON                 0x0004
+#define CMD_ACT_MAC_WEP_ENABLE                  0x0008
+#define CMD_ACT_MAC_INT_ENABLE                  0x0010
+#define CMD_ACT_MAC_MULTICAST_ENABLE            0x0020
+#define CMD_ACT_MAC_BROADCAST_ENABLE            0x0040
+#define CMD_ACT_MAC_PROMISCUOUS_ENABLE          0x0080
+#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE        0x0100
+#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE    0x0400
 
 /* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
-#define CMD_SUBSCRIBE_RSSI_LOW		0x0001
-#define CMD_SUBSCRIBE_SNR_LOW		0x0002
-#define CMD_SUBSCRIBE_FAILCOUNT		0x0004
-#define CMD_SUBSCRIBE_BCNMISS		0x0008
-#define CMD_SUBSCRIBE_RSSI_HIGH		0x0010
-#define CMD_SUBSCRIBE_SNR_HIGH		0x0020
+#define CMD_SUBSCRIBE_RSSI_LOW                  0x0001
+#define CMD_SUBSCRIBE_SNR_LOW                   0x0002
+#define CMD_SUBSCRIBE_FAILCOUNT                 0x0004
+#define CMD_SUBSCRIBE_BCNMISS                   0x0008
+#define CMD_SUBSCRIBE_RSSI_HIGH                 0x0010
+#define CMD_SUBSCRIBE_SNR_HIGH                  0x0020
 
-#define RADIO_PREAMBLE_LONG	0x00
-#define RADIO_PREAMBLE_SHORT	0x02
-#define RADIO_PREAMBLE_AUTO	0x04
+#define RADIO_PREAMBLE_LONG                     0x00
+#define RADIO_PREAMBLE_SHORT                    0x02
+#define RADIO_PREAMBLE_AUTO                     0x04
 
 /* Define action or option for CMD_802_11_RF_CHANNEL */
-#define CMD_OPT_802_11_RF_CHANNEL_GET	0x00
-#define CMD_OPT_802_11_RF_CHANNEL_SET	0x01
+#define CMD_OPT_802_11_RF_CHANNEL_GET           0x00
+#define CMD_OPT_802_11_RF_CHANNEL_SET           0x01
 
 /* Define action or option for CMD_802_11_DATA_RATE */
-#define CMD_ACT_SET_TX_AUTO		0x0000
-#define CMD_ACT_SET_TX_FIX_RATE		0x0001
-#define CMD_ACT_GET_TX_RATE		0x0002
-
-#define CMD_ACT_SET_RX			0x0001
-#define	CMD_ACT_SET_TX			0x0002
-#define CMD_ACT_SET_BOTH		0x0003
-#define	CMD_ACT_GET_RX			0x0004
-#define CMD_ACT_GET_TX			0x0008
-#define	CMD_ACT_GET_BOTH		0x000c
+#define CMD_ACT_SET_TX_AUTO                     0x0000
+#define CMD_ACT_SET_TX_FIX_RATE                 0x0001
+#define CMD_ACT_GET_TX_RATE                     0x0002
 
 /* Define action or option for CMD_802_11_PS_MODE */
-#define CMD_TYPE_CAM			0x0000
-#define	CMD_TYPE_MAX_PSP		0x0001
-#define CMD_TYPE_FAST_PSP		0x0002
+#define CMD_TYPE_CAM                            0x0000
+#define CMD_TYPE_MAX_PSP                        0x0001
+#define CMD_TYPE_FAST_PSP                       0x0002
 
 /* Options for CMD_802_11_FW_WAKE_METHOD */
-#define CMD_WAKE_METHOD_UNCHANGED	0x0000
-#define CMD_WAKE_METHOD_COMMAND_INT	0x0001
-#define CMD_WAKE_METHOD_GPIO		0x0002
+#define CMD_WAKE_METHOD_UNCHANGED               0x0000
+#define CMD_WAKE_METHOD_COMMAND_INT             0x0001
+#define CMD_WAKE_METHOD_GPIO                    0x0002
 
 /* Object IDs for CMD_802_11_SNMP_MIB */
-#define SNMP_MIB_OID_BSS_TYPE		0x0000
-#define SNMP_MIB_OID_OP_RATE_SET	0x0001
-#define SNMP_MIB_OID_BEACON_PERIOD	0x0002  /* Reserved on v9+ */
-#define SNMP_MIB_OID_DTIM_PERIOD	0x0003  /* Reserved on v9+ */
-#define SNMP_MIB_OID_ASSOC_TIMEOUT	0x0004  /* Reserved on v9+ */
-#define SNMP_MIB_OID_RTS_THRESHOLD	0x0005
-#define SNMP_MIB_OID_SHORT_RETRY_LIMIT	0x0006
-#define SNMP_MIB_OID_LONG_RETRY_LIMIT	0x0007
-#define SNMP_MIB_OID_FRAG_THRESHOLD	0x0008
-#define SNMP_MIB_OID_11D_ENABLE		0x0009
-#define SNMP_MIB_OID_11H_ENABLE		0x000A
+#define SNMP_MIB_OID_BSS_TYPE                   0x0000
+#define SNMP_MIB_OID_OP_RATE_SET                0x0001
+#define SNMP_MIB_OID_BEACON_PERIOD              0x0002  /* Reserved on v9+ */
+#define SNMP_MIB_OID_DTIM_PERIOD                0x0003  /* Reserved on v9+ */
+#define SNMP_MIB_OID_ASSOC_TIMEOUT              0x0004  /* Reserved on v9+ */
+#define SNMP_MIB_OID_RTS_THRESHOLD              0x0005
+#define SNMP_MIB_OID_SHORT_RETRY_LIMIT          0x0006
+#define SNMP_MIB_OID_LONG_RETRY_LIMIT           0x0007
+#define SNMP_MIB_OID_FRAG_THRESHOLD             0x0008
+#define SNMP_MIB_OID_11D_ENABLE                 0x0009
+#define SNMP_MIB_OID_11H_ENABLE                 0x000A
 
 /* Define action or option for CMD_BT_ACCESS */
 enum cmd_bt_access_opts {
@@ -302,4 +291,672 @@ enum cmd_mesh_config_types {
 #define MACREG_INT_CODE_MESH_AUTO_STARTED	35
 #define MACREG_INT_CODE_FIRMWARE_READY		48
 
+
+/* 802.11-related definitions */
+
+/* TxPD descriptor */
+struct txpd {
+	/* union to cope up with later FW revisions */
+	union {
+		/* Current Tx packet status */
+		__le32 tx_status;
+		struct {
+			/* BSS type: client, AP, etc. */
+			u8 bss_type;
+			/* BSS number */
+			u8 bss_num;
+			/* Reserved */
+			__le16 reserved;
+		} bss;
+	} u;
+	/* Tx control */
+	__le32 tx_control;
+	__le32 tx_packet_location;
+	/* Tx packet length */
+	__le16 tx_packet_length;
+	/* First 2 byte of destination MAC address */
+	u8 tx_dest_addr_high[2];
+	/* Last 4 byte of destination MAC address */
+	u8 tx_dest_addr_low[4];
+	/* Pkt Priority */
+	u8 priority;
+	/* Pkt Trasnit Power control */
+	u8 powermgmt;
+	/* Amount of time the packet has been queued (units = 2ms) */
+	u8 pktdelay_2ms;
+	/* reserved */
+	u8 reserved1;
+} __attribute__ ((packed));
+
+/* RxPD Descriptor */
+struct rxpd {
+	/* union to cope up with later FW revisions */
+	union {
+		/* Current Rx packet status */
+		__le16 status;
+		struct {
+			/* BSS type: client, AP, etc. */
+			u8 bss_type;
+			/* BSS number */
+			u8 bss_num;
+		} __attribute__ ((packed)) bss;
+	} __attribute__ ((packed)) u;
+
+	/* SNR */
+	u8 snr;
+
+	/* Tx control */
+	u8 rx_control;
+
+	/* Pkt length */
+	__le16 pkt_len;
+
+	/* Noise Floor */
+	u8 nf;
+
+	/* Rx Packet Rate */
+	u8 rx_rate;
+
+	/* Pkt addr */
+	__le32 pkt_ptr;
+
+	/* Next Rx RxPD addr */
+	__le32 next_rxpd_ptr;
+
+	/* Pkt Priority */
+	u8 priority;
+	u8 reserved[3];
+} __attribute__ ((packed));
+
+struct cmd_header {
+	__le16 command;
+	__le16 size;
+	__le16 seqnum;
+	__le16 result;
+} __attribute__ ((packed));
+
+/* Generic structure to hold all key types. */
+struct enc_key {
+	u16 len;
+	u16 flags;  /* KEY_INFO_* from defs.h */
+	u16 type; /* KEY_TYPE_* from defs.h */
+	u8 key[32];
+};
+
+/* lbs_offset_value */
+struct lbs_offset_value {
+	u32 offset;
+	u32 value;
+} __attribute__ ((packed));
+
+/*
+ * Define data structure for CMD_GET_HW_SPEC
+ * This structure defines the response for the GET_HW_SPEC command
+ */
+struct cmd_ds_get_hw_spec {
+	struct cmd_header hdr;
+
+	/* HW Interface version number */
+	__le16 hwifversion;
+	/* HW version number */
+	__le16 version;
+	/* Max number of TxPD FW can handle */
+	__le16 nr_txpd;
+	/* Max no of Multicast address */
+	__le16 nr_mcast_adr;
+	/* MAC address */
+	u8 permanentaddr[6];
+
+	/* region Code */
+	__le16 regioncode;
+
+	/* Number of antenna used */
+	__le16 nr_antenna;
+
+	/* FW release number, example 0x01030304 = 2.3.4p1 */
+	__le32 fwrelease;
+
+	/* Base Address of TxPD queue */
+	__le32 wcb_base;
+	/* Read Pointer of RxPd queue */
+	__le32 rxpd_rdptr;
+
+	/* Write Pointer of RxPd queue */
+	__le32 rxpd_wrptr;
+
+	/*FW/HW capability */
+	__le32 fwcapinfo;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_subscribe_event {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 events;
+
+	/* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a
+	 * number of TLVs. From the v5.1 manual, those TLVs would add up to
+	 * 40 bytes. However, future firmware might add additional TLVs, so I
+	 * bump this up a bit.
+	 */
+	uint8_t tlv[128];
+} __attribute__ ((packed));
+
+/*
+ * This scan handle Country Information IE(802.11d compliant)
+ * Define data structure for CMD_802_11_SCAN
+ */
+struct cmd_ds_802_11_scan {
+	struct cmd_header hdr;
+
+	uint8_t bsstype;
+	uint8_t bssid[ETH_ALEN];
+	uint8_t tlvbuffer[0];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_scan_rsp {
+	struct cmd_header hdr;
+
+	__le16 bssdescriptsize;
+	uint8_t nr_sets;
+	uint8_t bssdesc_and_tlvbuffer[0];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_get_log {
+	struct cmd_header hdr;
+
+	__le32 mcasttxframe;
+	__le32 failed;
+	__le32 retry;
+	__le32 multiretry;
+	__le32 framedup;
+	__le32 rtssuccess;
+	__le32 rtsfailure;
+	__le32 ackfailure;
+	__le32 rxfrag;
+	__le32 mcastrxframe;
+	__le32 fcserror;
+	__le32 txframe;
+	__le32 wepundecryptable;
+} __attribute__ ((packed));
+
+struct cmd_ds_mac_control {
+	struct cmd_header hdr;
+	__le16 action;
+	u16 reserved;
+} __attribute__ ((packed));
+
+struct cmd_ds_mac_multicast_adr {
+	struct cmd_header hdr;
+	__le16 action;
+	__le16 nr_of_adrs;
+	u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_authenticate {
+	struct cmd_header hdr;
+
+	u8 bssid[ETH_ALEN];
+	u8 authtype;
+	u8 reserved[10];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_deauthenticate {
+	struct cmd_header hdr;
+
+	u8 macaddr[ETH_ALEN];
+	__le16 reasoncode;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_associate {
+	struct cmd_header hdr;
+
+	u8 bssid[6];
+	__le16 capability;
+	__le16 listeninterval;
+	__le16 bcnperiod;
+	u8 dtimperiod;
+	u8 iebuf[512];    /* Enough for required and most optional IEs */
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_associate_response {
+	struct cmd_header hdr;
+
+	__le16 capability;
+	__le16 statuscode;
+	__le16 aid;
+	u8 iebuf[512];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_set_wep {
+	struct cmd_header hdr;
+
+	/* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
+	__le16 action;
+
+	/* key Index selected for Tx */
+	__le16 keyindex;
+
+	/* 40, 128bit or TXWEP */
+	uint8_t keytype[4];
+	uint8_t keymaterial[4][16];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_snmp_mib {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 oid;
+	__le16 bufsize;
+	u8 value[128];
+} __attribute__ ((packed));
+
+struct cmd_ds_mac_reg_access {
+	__le16 action;
+	__le16 offset;
+	__le32 value;
+} __attribute__ ((packed));
+
+struct cmd_ds_bbp_reg_access {
+	__le16 action;
+	__le16 offset;
+	u8 value;
+	u8 reserved[3];
+} __attribute__ ((packed));
+
+struct cmd_ds_rf_reg_access {
+	__le16 action;
+	__le16 offset;
+	u8 value;
+	u8 reserved[3];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_radio_control {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 control;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_beacon_control {
+	__le16 action;
+	__le16 beacon_enable;
+	__le16 beacon_period;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_sleep_params {
+	struct cmd_header hdr;
+
+	/* ACT_GET/ACT_SET */
+	__le16 action;
+
+	/* Sleep clock error in ppm */
+	__le16 error;
+
+	/* Wakeup offset in usec */
+	__le16 offset;
+
+	/* Clock stabilization time in usec */
+	__le16 stabletime;
+
+	/* control periodic calibration */
+	uint8_t calcontrol;
+
+	/* control the use of external sleep clock */
+	uint8_t externalsleepclk;
+
+	/* reserved field, should be set to zero */
+	__le16 reserved;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_rf_channel {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 channel;
+	__le16 rftype;      /* unused */
+	__le16 reserved;    /* unused */
+	u8 channellist[32]; /* unused */
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_rssi {
+	/* weighting factor */
+	__le16 N;
+
+	__le16 reserved_0;
+	__le16 reserved_1;
+	__le16 reserved_2;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_rssi_rsp {
+	__le16 SNR;
+	__le16 noisefloor;
+	__le16 avgSNR;
+	__le16 avgnoisefloor;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_mac_address {
+	struct cmd_header hdr;
+
+	__le16 action;
+	u8 macadd[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_rf_tx_power {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 curlevel;
+	s8 maxlevel;
+	s8 minlevel;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_monitor_mode {
+	__le16 action;
+	__le16 mode;
+} __attribute__ ((packed));
+
+struct cmd_ds_set_boot2_ver {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 version;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_fw_wake_method {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 method;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_ps_mode {
+	__le16 action;
+	__le16 nullpktinterval;
+	__le16 multipledtim;
+	__le16 reserved;
+	__le16 locallisteninterval;
+} __attribute__ ((packed));
+
+struct cmd_confirm_sleep {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 nullpktinterval;
+	__le16 multipledtim;
+	__le16 reserved;
+	__le16 locallisteninterval;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_data_rate {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 reserved;
+	u8 rates[MAX_RATES];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_rate_adapt_rateset {
+	struct cmd_header hdr;
+	__le16 action;
+	__le16 enablehwauto;
+	__le16 bitmap;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_ad_hoc_start {
+	struct cmd_header hdr;
+
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 bsstype;
+	__le16 beaconperiod;
+	u8 dtimperiod;   /* Reserved on v9 and later */
+	struct ieee_ie_ibss_param_set ibss;
+	u8 reserved1[4];
+	struct ieee_ie_ds_param_set ds;
+	u8 reserved2[4];
+	__le16 probedelay;  /* Reserved on v9 and later */
+	__le16 capability;
+	u8 rates[MAX_RATES];
+	u8 tlv_memory_size_pad[100];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_ad_hoc_result {
+	struct cmd_header hdr;
+
+	u8 pad[3];
+	u8 bssid[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct adhoc_bssdesc {
+	u8 bssid[ETH_ALEN];
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 type;
+	__le16 beaconperiod;
+	u8 dtimperiod;
+	__le64 timestamp;
+	__le64 localtime;
+	struct ieee_ie_ds_param_set ds;
+	u8 reserved1[4];
+	struct ieee_ie_ibss_param_set ibss;
+	u8 reserved2[4];
+	__le16 capability;
+	u8 rates[MAX_RATES];
+
+	/* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
+	 * Adhoc join command and will cause a binary layout mismatch with
+	 * the firmware
+	 */
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_ad_hoc_join {
+	struct cmd_header hdr;
+
+	struct adhoc_bssdesc bss;
+	__le16 failtimeout;   /* Reserved on v9 and later */
+	__le16 probedelay;    /* Reserved on v9 and later */
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_ad_hoc_stop {
+	struct cmd_header hdr;
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_enable_rsn {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 enable;
+} __attribute__ ((packed));
+
+struct MrvlIEtype_keyParamSet {
+	/* type ID */
+	__le16 type;
+
+	/* length of Payload */
+	__le16 length;
+
+	/* type of key: WEP=0, TKIP=1, AES=2 */
+	__le16 keytypeid;
+
+	/* key control Info specific to a keytypeid */
+	__le16 keyinfo;
+
+	/* length of key */
+	__le16 keylen;
+
+	/* key material of size keylen */
+	u8 key[32];
+} __attribute__ ((packed));
+
+#define MAX_WOL_RULES 		16
+
+struct host_wol_rule {
+	uint8_t rule_no;
+	uint8_t rule_ops;
+	__le16 sig_offset;
+	__le16 sig_length;
+	__le16 reserve;
+	__be32 sig_mask;
+	__be32 signature;
+} __attribute__ ((packed));
+
+struct wol_config {
+	uint8_t action;
+	uint8_t pattern;
+	uint8_t no_rules_in_cmd;
+	uint8_t result;
+	struct host_wol_rule rule[MAX_WOL_RULES];
+} __attribute__ ((packed));
+
+struct cmd_ds_host_sleep {
+	struct cmd_header hdr;
+	__le32 criteria;
+	uint8_t gpio;
+	uint16_t gap;
+	struct wol_config wol_conf;
+} __attribute__ ((packed));
+
+
+
+struct cmd_ds_802_11_key_material {
+	struct cmd_header hdr;
+
+	__le16 action;
+	struct MrvlIEtype_keyParamSet keyParamSet[2];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_eeprom_access {
+	struct cmd_header hdr;
+	__le16 action;
+	__le16 offset;
+	__le16 len;
+	/* firmware says it returns a maximum of 20 bytes */
+#define LBS_EEPROM_READ_LEN 20
+	u8 value[LBS_EEPROM_READ_LEN];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_tpc_cfg {
+	struct cmd_header hdr;
+
+	__le16 action;
+	uint8_t enable;
+	int8_t P0;
+	int8_t P1;
+	int8_t P2;
+	uint8_t usesnr;
+} __attribute__ ((packed));
+
+
+struct cmd_ds_802_11_pa_cfg {
+	struct cmd_header hdr;
+
+	__le16 action;
+	uint8_t enable;
+	int8_t P0;
+	int8_t P1;
+	int8_t P2;
+} __attribute__ ((packed));
+
+
+struct cmd_ds_802_11_led_ctrl {
+	__le16 action;
+	__le16 numled;
+	u8 data[256];
+} __attribute__ ((packed));
+
+struct cmd_ds_802_11_afc {
+	__le16 afc_auto;
+	union {
+		struct {
+			__le16 threshold;
+			__le16 period;
+		};
+		struct {
+			__le16 timing_offset; /* signed */
+			__le16 carrier_offset; /* signed */
+		};
+	};
+} __attribute__ ((packed));
+
+struct cmd_tx_rate_query {
+	__le16 txrate;
+} __attribute__ ((packed));
+
+struct cmd_ds_get_tsf {
+	__le64 tsfvalue;
+} __attribute__ ((packed));
+
+struct cmd_ds_bt_access {
+	__le16 action;
+	__le32 id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct cmd_ds_fwt_access {
+	__le16 action;
+	__le32 id;
+	u8 valid;
+	u8 da[ETH_ALEN];
+	u8 dir;
+	u8 ra[ETH_ALEN];
+	__le32 ssn;
+	__le32 dsn;
+	__le32 metric;
+	u8 rate;
+	u8 hopcount;
+	u8 ttl;
+	__le32 expiration;
+	u8 sleepmode;
+	__le32 snr;
+	__le32 references;
+	u8 prec[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct cmd_ds_mesh_config {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le16 channel;
+	__le16 type;
+	__le16 length;
+	u8 data[128];	/* last position reserved */
+} __attribute__ ((packed));
+
+struct cmd_ds_mesh_access {
+	struct cmd_header hdr;
+
+	__le16 action;
+	__le32 data[32];	/* last position reserved */
+} __attribute__ ((packed));
+
+/* Number of stats counters returned by the firmware */
+#define MESH_STATS_NUM 8
+
+struct cmd_ds_command {
+	/* command header */
+	__le16 command;
+	__le16 size;
+	__le16 seqnum;
+	__le16 result;
+
+	/* command Body */
+	union {
+		struct cmd_ds_802_11_ps_mode psmode;
+		struct cmd_ds_802_11_monitor_mode monitor;
+		struct cmd_ds_802_11_rssi rssi;
+		struct cmd_ds_802_11_rssi_rsp rssirsp;
+		struct cmd_ds_mac_reg_access macreg;
+		struct cmd_ds_bbp_reg_access bbpreg;
+		struct cmd_ds_rf_reg_access rfreg;
+
+		struct cmd_ds_802_11_tpc_cfg tpccfg;
+		struct cmd_ds_802_11_afc afc;
+		struct cmd_ds_802_11_led_ctrl ledgpio;
+
+		struct cmd_ds_bt_access bt;
+		struct cmd_ds_fwt_access fwt;
+		struct cmd_ds_802_11_beacon_control bcn_ctrl;
+	} params;
+} __attribute__ ((packed));
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 14:02:34.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 12:10:08.000000000 -0400
@@ -48,6 +48,7 @@
 MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
 MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 
 
 
@@ -590,7 +591,7 @@ static int if_cs_prog_helper(struct if_c
 
 	/* TODO: make firmware file configurable */
 	ret = reject_firmware(&fw, "/*(DEBLOBBED)*/",
-		&handle_to_dev(card->p_dev));
+		&card->p_dev->dev);
 	if (ret) {
 		lbs_pr_err("can't load helper firmware\n");
 		ret = -ENODEV;
@@ -663,7 +664,7 @@ static int if_cs_prog_real(struct if_cs_
 
 	/* TODO: make firmware file configurable */
 	ret = reject_firmware(&fw, "/*(DEBLOBBED)*/",
-		&handle_to_dev(card->p_dev));
+		&card->p_dev->dev);
 	if (ret) {
 		lbs_pr_err("can't load firmware\n");
 		ret = -ENODEV;
@@ -793,18 +794,37 @@ static void if_cs_release(struct pcmcia_
  * configure the card at this point -- we wait until we receive a card
  * insertion event.
  */
+
+static int if_cs_ioprobe(struct pcmcia_device *p_dev,
+			 cistpl_cftable_entry_t *cfg,
+			 cistpl_cftable_entry_t *dflt,
+			 unsigned int vcc,
+			 void *priv_data)
+{
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+	/* Do we need to allocate an interrupt? */
+	if (cfg->irq.IRQInfo1)
+		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+	/* IO window settings */
+	if (cfg->io.nwin != 1) {
+		lbs_pr_err("wrong CIS (check number of IO windows)\n");
+		return -ENODEV;
+	}
+
+	/* This reserves IO space but doesn't actually enable it */
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int if_cs_probe(struct pcmcia_device *p_dev)
 {
 	int ret = -ENOMEM;
 	unsigned int prod_id;
 	struct lbs_private *priv;
 	struct if_cs_card *card;
-	/* CIS parsing */
-	tuple_t tuple;
-	cisparse_t parse;
-	cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-	cistpl_io_t *io = &cfg->io;
-	u_char buf[64];
 
 	lbs_deb_enter(LBS_DEB_CS);
 
@@ -818,48 +838,15 @@ static int if_cs_probe(struct pcmcia_dev
 
 	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	p_dev->irq.Handler = NULL;
-	p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
 
 	p_dev->conf.Attributes = 0;
 	p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
-	    (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
-	    (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
-	{
-		lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
-		goto out1;
-	}
-
-	p_dev->conf.ConfigIndex = cfg->index;
-
-	/* Do we need to allocate an interrupt? */
-	if (cfg->irq.IRQInfo1) {
-		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-	}
-
-	/* IO window settings */
-	if (cfg->io.nwin != 1) {
-		lbs_pr_err("wrong CIS (check number of IO windows)\n");
-		ret = -ENODEV;
+	if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
+		lbs_pr_err("error in pcmcia_loop_config\n");
 		goto out1;
 	}
-	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-	p_dev->io.BasePort1 = io->win[0].base;
-	p_dev->io.NumPorts1 = io->win[0].len;
 
-	/* This reserves IO space but doesn't actually enable it */
-	ret = pcmcia_request_io(p_dev, &p_dev->io);
-	if (ret) {
-		lbs_pr_err("error in pcmcia_request_io\n");
-		goto out1;
-	}
 
 	/*
 	 * Allocate an interrupt line.  Note that this does not assign
@@ -946,6 +933,9 @@ static int if_cs_probe(struct pcmcia_dev
 	card->priv = priv;
 	priv->card = card;
 	priv->hw_host_to_card = if_cs_host_to_card;
+	priv->enter_deep_sleep = NULL;
+	priv->exit_deep_sleep = NULL;
+	priv->reset_deep_sleep_wakeup = NULL;
 	priv->fw_ready = 1;
 
 	/* Now actually get the IRQ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_sdio.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 14:02:36.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 12:10:10.000000000 -0400
@@ -96,6 +96,7 @@ static struct if_sdio_model if_sdio_mode
 		.helper = "/*(DEBLOBBED)*/",
 	},
 };
+/*(DEBLOBBED)*/
 
 struct if_sdio_packet {
 	struct if_sdio_packet	*next;
@@ -828,6 +829,58 @@ out:
 	return ret;
 }
 
+static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
+{
+	int ret = -1;
+	struct cmd_header cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	lbs_deb_sdio("send DEEP_SLEEP command\n");
+	ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
+			lbs_cmd_copyback, (unsigned long) &cmd);
+	if (ret)
+		lbs_pr_err("DEEP_SLEEP cmd failed\n");
+
+	mdelay(200);
+	return ret;
+}
+
+static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
+{
+	struct if_sdio_card *card = priv->card;
+	int ret = -1;
+
+	lbs_deb_enter(LBS_DEB_SDIO);
+	sdio_claim_host(card->func);
+
+	sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
+	if (ret)
+		lbs_pr_err("sdio_writeb failed!\n");
+
+	sdio_release_host(card->func);
+	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+	return ret;
+}
+
+static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
+{
+	struct if_sdio_card *card = priv->card;
+	int ret = -1;
+
+	lbs_deb_enter(LBS_DEB_SDIO);
+	sdio_claim_host(card->func);
+
+	sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
+	if (ret)
+		lbs_pr_err("sdio_writeb failed!\n");
+
+	sdio_release_host(card->func);
+	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+	return ret;
+
+}
+
 /*******************************************************************/
 /* SDIO callbacks                                                  */
 /*******************************************************************/
@@ -856,6 +909,7 @@ static void if_sdio_interrupt(struct sdi
 	 * Ignore the define name, this really means the card has
 	 * successfully received the command.
 	 */
+	card->priv->is_activity_detected = 1;
 	if (cause & IF_SDIO_H_INT_DNLD)
 		lbs_host_to_card_done(card->priv);
 
@@ -931,7 +985,7 @@ static int if_sdio_probe(struct sdio_fun
 	}
 
 	if (i == ARRAY_SIZE(if_sdio_models)) {
-		lbs_pr_err("unkown card model 0x%x\n", card->model);
+		lbs_pr_err("unknown card model 0x%x\n", card->model);
 		ret = -ENODEV;
 		goto free;
 	}
@@ -995,6 +1049,9 @@ static int if_sdio_probe(struct sdio_fun
 
 	priv->card = card;
 	priv->hw_host_to_card = if_sdio_host_to_card;
+	priv->enter_deep_sleep = if_sdio_enter_deep_sleep;
+	priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
+	priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
 
 	priv->fw_ready = 1;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_sdio.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_sdio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_sdio.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,5 +51,6 @@
 #define IF_SDIO_EVENT           0x80fc
 
 #define IF_SDIO_BLOCK_SIZE	256
-
+#define CONFIGURATION_REG               0x03
+#define HOST_POWER_UP                   (0x1U << 1)
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_spi.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_spi.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_spi.c	2013-05-03 14:02:38.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_spi.c	2013-05-03 12:10:13.000000000 -0400
@@ -32,12 +32,6 @@
 #include "dev.h"
 #include "if_spi.h"
 
-struct if_spi_packet {
-	struct list_head		list;
-	u16				blen;
-	u8				buffer[0] __attribute__((aligned(4)));
-};
-
 struct if_spi_card {
 	struct spi_device		*spi;
 	struct lbs_private		*priv;
@@ -66,33 +60,10 @@ struct if_spi_card {
 	struct semaphore		spi_thread_terminated;
 
 	u8				cmd_buffer[IF_SPI_CMD_BUF_SIZE];
-
-	/* A buffer of incoming packets from libertas core.
-	 * Since we can't sleep in hw_host_to_card, we have to buffer
-	 * them. */
-	struct list_head		cmd_packet_list;
-	struct list_head		data_packet_list;
-
-	/* Protects cmd_packet_list and data_packet_list */
-	spinlock_t			buffer_lock;
 };
 
 static void free_if_spi_card(struct if_spi_card *card)
 {
-	struct list_head *cursor, *next;
-	struct if_spi_packet *packet;
-
-	BUG_ON(card->run_thread);
-	list_for_each_safe(cursor, next, &card->cmd_packet_list) {
-		packet = container_of(cursor, struct if_spi_packet, list);
-		list_del(&packet->list);
-		kfree(packet);
-	}
-	list_for_each_safe(cursor, next, &card->data_packet_list) {
-		packet = container_of(cursor, struct if_spi_packet, list);
-		list_del(&packet->list);
-		kfree(packet);
-	}
 	spi_set_drvdata(card->spi, NULL);
 	kfree(card);
 }
@@ -774,40 +745,6 @@ out:
 	return err;
 }
 
-/* Move data or a command from the host to the card. */
-static void if_spi_h2c(struct if_spi_card *card,
-			struct if_spi_packet *packet, int type)
-{
-	int err = 0;
-	u16 int_type, port_reg;
-
-	switch (type) {
-	case MVMS_DAT:
-		int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
-		port_reg = IF_SPI_DATA_RDWRPORT_REG;
-		break;
-	case MVMS_CMD:
-		int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
-		port_reg = IF_SPI_CMD_RDWRPORT_REG;
-		break;
-	default:
-		lbs_pr_err("can't transfer buffer of type %d\n", type);
-		err = -EINVAL;
-		goto out;
-	}
-
-	/* Write the data to the card */
-	err = spu_write(card, port_reg, packet->buffer, packet->blen);
-	if (err)
-		goto out;
-
-out:
-	kfree(packet);
-
-	if (err)
-		lbs_pr_err("%s: error %d\n", __func__, err);
-}
-
 /* Inform the host about a card event */
 static void if_spi_e2h(struct if_spi_card *card)
 {
@@ -837,8 +774,6 @@ static int lbs_spi_thread(void *data)
 	int err;
 	struct if_spi_card *card = data;
 	u16 hiStatus;
-	unsigned long flags;
-	struct if_spi_packet *packet;
 
 	while (1) {
 		/* Wait to be woken up by one of two things.  First, our ISR
@@ -877,43 +812,9 @@ static int lbs_spi_thread(void *data)
 		if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
 		   (card->priv->psstate != PS_STATE_FULL_POWER &&
 		    (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
-			/* This means two things. First of all,
-			 * if there was a previous command sent, the card has
-			 * successfully received it.
-			 * Secondly, it is now ready to download another
-			 * command.
-			 */
 			lbs_host_to_card_done(card->priv);
-
-			/* Do we have any command packets from the host to
-			 * send? */
-			packet = NULL;
-			spin_lock_irqsave(&card->buffer_lock, flags);
-			if (!list_empty(&card->cmd_packet_list)) {
-				packet = (struct if_spi_packet *)(card->
-						cmd_packet_list.next);
-				list_del(&packet->list);
-			}
-			spin_unlock_irqrestore(&card->buffer_lock, flags);
-
-			if (packet)
-				if_spi_h2c(card, packet, MVMS_CMD);
 		}
-		if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
-			/* Do we have any data packets from the host to
-			 * send? */
-			packet = NULL;
-			spin_lock_irqsave(&card->buffer_lock, flags);
-			if (!list_empty(&card->data_packet_list)) {
-				packet = (struct if_spi_packet *)(card->
-						data_packet_list.next);
-				list_del(&packet->list);
-			}
-			spin_unlock_irqrestore(&card->buffer_lock, flags);
 
-			if (packet)
-				if_spi_h2c(card, packet, MVMS_DAT);
-		}
 		if (hiStatus & IF_SPI_HIST_CARD_EVENT)
 			if_spi_e2h(card);
 
@@ -942,40 +843,18 @@ static int if_spi_host_to_card(struct lb
 				u8 type, u8 *buf, u16 nb)
 {
 	int err = 0;
-	unsigned long flags;
 	struct if_spi_card *card = priv->card;
-	struct if_spi_packet *packet;
-	u16 blen;
 
 	lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
 
-	if (nb == 0) {
-		lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
-		err = -EINVAL;
-		goto out;
-	}
-	blen = ALIGN(nb, 4);
-	packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
-	if (!packet) {
-		err = -ENOMEM;
-		goto out;
-	}
-	packet->blen = blen;
-	memcpy(packet->buffer, buf, nb);
-	memset(packet->buffer + nb, 0, blen - nb);
+	nb = ALIGN(nb, 4);
 
 	switch (type) {
 	case MVMS_CMD:
-		priv->dnld_sent = DNLD_CMD_SENT;
-		spin_lock_irqsave(&card->buffer_lock, flags);
-		list_add_tail(&packet->list, &card->cmd_packet_list);
-		spin_unlock_irqrestore(&card->buffer_lock, flags);
+		err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, buf, nb);
 		break;
 	case MVMS_DAT:
-		priv->dnld_sent = DNLD_DATA_SENT;
-		spin_lock_irqsave(&card->buffer_lock, flags);
-		list_add_tail(&packet->list, &card->data_packet_list);
-		spin_unlock_irqrestore(&card->buffer_lock, flags);
+		err = spu_write(card, IF_SPI_DATA_RDWRPORT_REG, buf, nb);
 		break;
 	default:
 		lbs_pr_err("can't transfer buffer of type %d", type);
@@ -983,9 +862,6 @@ static int if_spi_host_to_card(struct lb
 		break;
 	}
 
-	/* Wake up the spi thread */
-	up(&card->spi_ready);
-out:
 	lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
 	return err;
 }
@@ -1026,6 +902,7 @@ static int if_spi_calculate_fw_names(u16
 		 chip_id_to_device_name[i].name);
 	return 0;
 }
+/*(DEBLOBBED)*/
 
 static int __devinit if_spi_probe(struct spi_device *spi)
 {
@@ -1062,9 +939,6 @@ static int __devinit if_spi_probe(struct
 
 	sema_init(&card->spi_ready, 0);
 	sema_init(&card->spi_thread_terminated, 0);
-	INIT_LIST_HEAD(&card->cmd_packet_list);
-	INIT_LIST_HEAD(&card->data_packet_list);
-	spin_lock_init(&card->buffer_lock);
 
 	/* Initialize the SPI Interface Unit */
 	err = spu_init(card, pdata->use_dummy_writes);
@@ -1117,6 +991,9 @@ static int __devinit if_spi_probe(struct
 	card->priv = priv;
 	priv->card = card;
 	priv->hw_host_to_card = if_spi_host_to_card;
+	priv->enter_deep_sleep = NULL;
+	priv->exit_deep_sleep = NULL;
+	priv->reset_deep_sleep_wakeup = NULL;
 	priv->fw_ready = 1;
 
 	/* Initialize interrupt handling stuff. */
@@ -1138,6 +1015,9 @@ static int __devinit if_spi_probe(struct
 		goto terminate_thread;
 	}
 
+	/* poke the IRQ handler so that we don't miss the first interrupt */
+	up(&card->spi_ready);
+
 	/* Start the card.
 	 * This will call register_netdev, and we'll start
 	 * getting interrupts... */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/if_usb.c	2013-05-03 14:02:40.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/if_usb.c	2013-05-03 12:10:15.000000000 -0400
@@ -28,6 +28,8 @@
 static char *lbs_fw_name = "/*(DEBLOBBED)*/";
 module_param_named(fw_name, lbs_fw_name, charp, 0644);
 
+/*(DEBLOBBED)*/
+
 static struct usb_device_id if_usb_table[] = {
 	/* Enter the device signature inside */
 	{ USB_DEVICE(0x1286, 0x2001) },
@@ -290,6 +292,9 @@ static int if_usb_probe(struct usb_inter
 	cardp->priv->fw_ready = 1;
 
 	priv->hw_host_to_card = if_usb_host_to_card;
+	priv->enter_deep_sleep = NULL;
+	priv->exit_deep_sleep = NULL;
+	priv->reset_deep_sleep_wakeup = NULL;
 #ifdef CONFIG_OLPC
 	if (machine_is_olpc())
 		priv->reset_card = if_usb_reset_olpc_card;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,39 @@
+config LIBERTAS
+	tristate "Marvell 8xxx Libertas WLAN driver support"
+	depends on CFG80211
+	select WIRELESS_EXT
+	select WEXT_SPY
+	select LIB80211
+	select FW_LOADER
+	---help---
+	  A library for Marvell Libertas 8xxx devices.
+
+config LIBERTAS_USB
+	tristate "Marvell Libertas 8388 USB 802.11b/g cards"
+	depends on LIBERTAS && USB
+	---help---
+	  A driver for Marvell Libertas 8388 USB devices.
+
+config LIBERTAS_CS
+	tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
+	depends on LIBERTAS && PCMCIA
+	---help---
+	  A driver for Marvell Libertas 8385 CompactFlash devices.
+
+config LIBERTAS_SDIO
+	tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
+	depends on LIBERTAS && MMC
+	---help---
+	  A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
+
+config LIBERTAS_SPI
+	tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
+	depends on LIBERTAS && SPI
+	---help---
+	  A driver for Marvell Libertas 8686 SPI devices.
+
+config LIBERTAS_DEBUG
+	bool "Enable full debugging output in the Libertas module."
+	depends on LIBERTAS
+	---help---
+	  Debugging support.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,11 +14,13 @@
 #include <linux/stddef.h>
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "host.h"
 #include "decl.h"
 #include "dev.h"
 #include "wext.h"
+#include "cfg.h"
 #include "debugfs.h"
 #include "scan.h"
 #include "assoc.h"
@@ -43,119 +45,6 @@ module_param_named(libertas_debug, lbs_d
 struct cmd_confirm_sleep confirm_sleep;
 
 
-#define LBS_TX_PWR_DEFAULT		20	/*100mW */
-#define LBS_TX_PWR_US_DEFAULT		20	/*100mW */
-#define LBS_TX_PWR_JP_DEFAULT		16	/*50mW */
-#define LBS_TX_PWR_FR_DEFAULT		20	/*100mW */
-#define LBS_TX_PWR_EMEA_DEFAULT	20	/*100mW */
-
-/* Format { channel, frequency (MHz), maxtxpower } */
-/* band: 'B/G', region: USA FCC/Canada IC */
-static struct chan_freq_power channel_freq_power_US_BG[] = {
-	{1, 2412, LBS_TX_PWR_US_DEFAULT},
-	{2, 2417, LBS_TX_PWR_US_DEFAULT},
-	{3, 2422, LBS_TX_PWR_US_DEFAULT},
-	{4, 2427, LBS_TX_PWR_US_DEFAULT},
-	{5, 2432, LBS_TX_PWR_US_DEFAULT},
-	{6, 2437, LBS_TX_PWR_US_DEFAULT},
-	{7, 2442, LBS_TX_PWR_US_DEFAULT},
-	{8, 2447, LBS_TX_PWR_US_DEFAULT},
-	{9, 2452, LBS_TX_PWR_US_DEFAULT},
-	{10, 2457, LBS_TX_PWR_US_DEFAULT},
-	{11, 2462, LBS_TX_PWR_US_DEFAULT}
-};
-
-/* band: 'B/G', region: Europe ETSI */
-static struct chan_freq_power channel_freq_power_EU_BG[] = {
-	{1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
-	{2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
-	{3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
-	{4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
-	{5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
-	{6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
-	{7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
-	{8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
-	{9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
-	{10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
-	{11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
-	{12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
-	{13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
-};
-
-/* band: 'B/G', region: Spain */
-static struct chan_freq_power channel_freq_power_SPN_BG[] = {
-	{10, 2457, LBS_TX_PWR_DEFAULT},
-	{11, 2462, LBS_TX_PWR_DEFAULT}
-};
-
-/* band: 'B/G', region: France */
-static struct chan_freq_power channel_freq_power_FR_BG[] = {
-	{10, 2457, LBS_TX_PWR_FR_DEFAULT},
-	{11, 2462, LBS_TX_PWR_FR_DEFAULT},
-	{12, 2467, LBS_TX_PWR_FR_DEFAULT},
-	{13, 2472, LBS_TX_PWR_FR_DEFAULT}
-};
-
-/* band: 'B/G', region: Japan */
-static struct chan_freq_power channel_freq_power_JPN_BG[] = {
-	{1, 2412, LBS_TX_PWR_JP_DEFAULT},
-	{2, 2417, LBS_TX_PWR_JP_DEFAULT},
-	{3, 2422, LBS_TX_PWR_JP_DEFAULT},
-	{4, 2427, LBS_TX_PWR_JP_DEFAULT},
-	{5, 2432, LBS_TX_PWR_JP_DEFAULT},
-	{6, 2437, LBS_TX_PWR_JP_DEFAULT},
-	{7, 2442, LBS_TX_PWR_JP_DEFAULT},
-	{8, 2447, LBS_TX_PWR_JP_DEFAULT},
-	{9, 2452, LBS_TX_PWR_JP_DEFAULT},
-	{10, 2457, LBS_TX_PWR_JP_DEFAULT},
-	{11, 2462, LBS_TX_PWR_JP_DEFAULT},
-	{12, 2467, LBS_TX_PWR_JP_DEFAULT},
-	{13, 2472, LBS_TX_PWR_JP_DEFAULT},
-	{14, 2484, LBS_TX_PWR_JP_DEFAULT}
-};
-
-/**
- * the structure for channel, frequency and power
- */
-struct region_cfp_table {
-	u8 region;
-	struct chan_freq_power *cfp_BG;
-	int cfp_no_BG;
-};
-
-/**
- * the structure for the mapping between region and CFP
- */
-static struct region_cfp_table region_cfp_table[] = {
-	{0x10,			/*US FCC */
-	 channel_freq_power_US_BG,
-	 ARRAY_SIZE(channel_freq_power_US_BG),
-	 }
-	,
-	{0x20,			/*CANADA IC */
-	 channel_freq_power_US_BG,
-	 ARRAY_SIZE(channel_freq_power_US_BG),
-	 }
-	,
-	{0x30, /*EU*/ channel_freq_power_EU_BG,
-	 ARRAY_SIZE(channel_freq_power_EU_BG),
-	 }
-	,
-	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
-	 ARRAY_SIZE(channel_freq_power_SPN_BG),
-	 }
-	,
-	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
-	 ARRAY_SIZE(channel_freq_power_FR_BG),
-	 }
-	,
-	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
-	 ARRAY_SIZE(channel_freq_power_JPN_BG),
-	 }
-	,
-/*Add new region here */
-};
-
 /**
  * the table to keep region code
  */
@@ -163,13 +52,6 @@ u16 lbs_region_code_to_index[MRVDRV_MAX_
     { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
 
 /**
- * 802.11b/g supported bitrates (in 500Kb/s units)
- */
-u8 lbs_bg_rates[MAX_RATES] =
-    { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
-0x00, 0x00 };
-
-/**
  * FW rate table.  FW refers to rates by their index in this table, not by the
  * rate value itself.  Values of 0x00 are
  * reserved positions.
@@ -212,107 +94,9 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
 	return 0;
 }
 
-/**
- * Attributes exported through sysfs
- */
-
-/**
- * @brief Get function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_get(struct device *dev,
-		struct device_attribute *attr, char * buf)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_access mesh_access;
-	int ret;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-
-	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
-}
-
-/**
- * @brief Set function for sysfs attribute anycast_mask
- */
-static ssize_t lbs_anycast_set(struct device *dev,
-		struct device_attribute *attr, const char * buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_access mesh_access;
-	uint32_t datum;
-	int ret;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-	sscanf(buf, "%x", &datum);
-	mesh_access.data[0] = cpu_to_le32(datum);
-
-	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_access mesh_access;
-	int ret;
-	u32 retry_limit;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-	mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
-
-	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
-			&mesh_access);
-	if (ret)
-		return ret;
-
-	retry_limit = le32_to_cpu(mesh_access.data[1]);
-	return snprintf(buf, 10, "%d\n", retry_limit);
-}
-
-/**
- * @brief Set function for sysfs attribute prb_rsp_limit
- */
-static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_access mesh_access;
-	int ret;
-	unsigned long retry_limit;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-	mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
-
-	if (!strict_strtoul(buf, 10, &retry_limit))
-		return -ENOTSUPP;
-	if (retry_limit > 15)
-		return -ENOTSUPP;
-
-	mesh_access.data[1] = cpu_to_le32(retry_limit);
-
-	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
-			&mesh_access);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
 
 static int lbs_add_rtap(struct lbs_private *priv);
 static void lbs_remove_rtap(struct lbs_private *priv);
-static int lbs_add_mesh(struct lbs_private *priv);
-static void lbs_remove_mesh(struct lbs_private *priv);
 
 
 /**
@@ -378,74 +162,7 @@ static ssize_t lbs_rtap_set(struct devic
 static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
 
 /**
- * Get function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_get(struct device *dev,
-		struct device_attribute *attr, char * buf)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
-}
-
-/**
- *  Set function for sysfs attribute mesh
- */
-static ssize_t lbs_mesh_set(struct device *dev,
-		struct device_attribute *attr, const char * buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	int enable;
-	int ret, action = CMD_ACT_MESH_CONFIG_STOP;
-
-	sscanf(buf, "%x", &enable);
-	enable = !!enable;
-	if (enable == !!priv->mesh_dev)
-		return count;
-	if (enable)
-		action = CMD_ACT_MESH_CONFIG_START;
-	ret = lbs_mesh_config(priv, action, priv->curbssparams.channel);
-	if (ret)
-		return ret;
-
-	if (enable)
-		lbs_add_mesh(priv);
-	else
-		lbs_remove_mesh(priv);
-
-	return count;
-}
-
-/**
- * lbs_mesh attribute to be exported per ethX interface
- * through sysfs (/sys/class/net/ethX/lbs_mesh)
- */
-static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
-
-/**
- * anycast_mask attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/anycast_mask)
- */
-static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
-
-/**
- * prb_rsp_limit attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
- */
-static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
-		lbs_prb_rsp_limit_set);
-
-static struct attribute *lbs_mesh_sysfs_entries[] = {
-	&dev_attr_anycast_mask.attr,
-	&dev_attr_prb_rsp_limit.attr,
-	NULL,
-};
-
-static struct attribute_group lbs_mesh_attr_group = {
-	.attrs = lbs_mesh_sysfs_entries,
-};
-
-/**
- *  @brief This function opens the ethX or mshX interface
+ *  @brief This function opens the ethX interface
  *
  *  @param dev     A pointer to net_device structure
  *  @return 	   0 or -EBUSY if monitor mode active
@@ -464,18 +181,12 @@ static int lbs_dev_open(struct net_devic
 		goto out;
 	}
 
-	if (dev == priv->mesh_dev) {
-		priv->mesh_open = 1;
-		priv->mesh_connect_status = LBS_CONNECTED;
-		netif_carrier_on(dev);
-	} else {
-		priv->infra_open = 1;
+	priv->infra_open = 1;
 
-		if (priv->connect_status == LBS_CONNECTED)
-			netif_carrier_on(dev);
-		else
-			netif_carrier_off(dev);
-	}
+	if (priv->connect_status == LBS_CONNECTED)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
 
 	if (!priv->tx_pending_len)
 		netif_wake_queue(dev);
@@ -487,33 +198,6 @@ static int lbs_dev_open(struct net_devic
 }
 
 /**
- *  @brief This function closes the mshX interface
- *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0
- */
-static int lbs_mesh_stop(struct net_device *dev)
-{
-	struct lbs_private *priv = dev->ml_priv;
-
-	lbs_deb_enter(LBS_DEB_MESH);
-	spin_lock_irq(&priv->driver_lock);
-
-	priv->mesh_open = 0;
-	priv->mesh_connect_status = LBS_DISCONNECTED;
-
-	netif_stop_queue(dev);
-	netif_carrier_off(dev);
-
-	spin_unlock_irq(&priv->driver_lock);
-
-	schedule_work(&priv->mcast_work);
-
-	lbs_deb_leave(LBS_DEB_MESH);
-	return 0;
-}
-
-/**
  *  @brief This function closes the ethX interface
  *
  *  @param dev     A pointer to net_device structure
@@ -574,15 +258,17 @@ void lbs_host_to_card_done(struct lbs_pr
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
 	/* Wake main thread if commands are pending */
-	if (!priv->cur_cmd || priv->tx_pending_len > 0)
-		wake_up_interruptible(&priv->waitq);
+	if (!priv->cur_cmd || priv->tx_pending_len > 0) {
+		if (!priv->wakeup_dev_required)
+			wake_up_interruptible(&priv->waitq);
+	}
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 	lbs_deb_leave(LBS_DEB_THREAD);
 }
 EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
 
-static int lbs_set_mac_address(struct net_device *dev, void *addr)
+int lbs_set_mac_address(struct net_device *dev, void *addr)
 {
 	int ret = 0;
 	struct lbs_private *priv = dev->ml_priv;
@@ -716,7 +402,7 @@ static void lbs_set_mcast_worker(struct
 	lbs_deb_leave(LBS_DEB_NET);
 }
 
-static void lbs_set_multicast_list(struct net_device *dev)
+void lbs_set_multicast_list(struct net_device *dev)
 {
 	struct lbs_private *priv = dev->ml_priv;
 
@@ -770,9 +456,10 @@ static int lbs_thread(void *data)
 			shouldsleep = 0;	/* We have a command response */
 		else if (priv->cur_cmd)
 			shouldsleep = 1;	/* Can't send a command; one already running */
-		else if (!list_empty(&priv->cmdpendingq))
+		else if (!list_empty(&priv->cmdpendingq) &&
+					!(priv->wakeup_dev_required))
 			shouldsleep = 0;	/* We have a command to send */
-		else if (__kfifo_len(priv->event_fifo))
+		else if (kfifo_len(&priv->event_fifo))
 			shouldsleep = 0;	/* We have an event to process */
 		else
 			shouldsleep = 1;	/* No command */
@@ -822,6 +509,29 @@ static int lbs_thread(void *data)
 		}
 		spin_unlock_irq(&priv->driver_lock);
 
+		/* Process hardware events, e.g. card removed, link lost */
+		spin_lock_irq(&priv->driver_lock);
+		while (kfifo_len(&priv->event_fifo)) {
+			u32 event;
+
+			if (kfifo_out(&priv->event_fifo,
+				(unsigned char *) &event, sizeof(event)) !=
+				sizeof(event))
+					break;
+			spin_unlock_irq(&priv->driver_lock);
+			lbs_process_event(priv, event);
+			spin_lock_irq(&priv->driver_lock);
+		}
+		spin_unlock_irq(&priv->driver_lock);
+
+		if (priv->wakeup_dev_required) {
+			lbs_deb_thread("Waking up device...\n");
+			/* Wake up device */
+			if (priv->exit_deep_sleep(priv))
+				lbs_deb_thread("Wakeup device failed\n");
+			continue;
+		}
+
 		/* command timeout stuff */
 		if (priv->cmd_timed_out && priv->cur_cmd) {
 			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
@@ -849,18 +559,7 @@ static int lbs_thread(void *data)
 		}
 		priv->cmd_timed_out = 0;
 
-		/* Process hardware events, e.g. card removed, link lost */
-		spin_lock_irq(&priv->driver_lock);
-		while (__kfifo_len(priv->event_fifo)) {
-			u32 event;
 
-			__kfifo_get(priv->event_fifo, (unsigned char *) &event,
-				sizeof(event));
-			spin_unlock_irq(&priv->driver_lock);
-			lbs_process_event(priv, event);
-			spin_lock_irq(&priv->driver_lock);
-		}
-		spin_unlock_irq(&priv->driver_lock);
 
 		if (!priv->fw_ready)
 			continue;
@@ -894,6 +593,9 @@ static int lbs_thread(void *data)
 		    (priv->psstate == PS_STATE_PRE_SLEEP))
 			continue;
 
+		if (priv->is_deep_sleep)
+			continue;
+
 		/* Execute the next command */
 		if (!priv->dnld_sent && !priv->cur_cmd)
 			lbs_execute_next_command(priv);
@@ -928,6 +630,7 @@ static int lbs_thread(void *data)
 	}
 
 	del_timer(&priv->command_timer);
+	del_timer(&priv->auto_deepsleep_timer);
 	wake_up_all(&priv->cmd_pending);
 
 	lbs_deb_leave(LBS_DEB_THREAD);
@@ -1050,6 +753,62 @@ out:
 	lbs_deb_leave(LBS_DEB_CMD);
 }
 
+/**
+ *  This function put the device back to deep sleep mode when timer expires
+ *  and no activity (command, event, data etc.) is detected.
+ */
+static void auto_deepsleep_timer_fn(unsigned long data)
+{
+	struct lbs_private *priv = (struct lbs_private *)data;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (priv->is_activity_detected) {
+		priv->is_activity_detected = 0;
+	} else {
+		if (priv->is_auto_deep_sleep_enabled &&
+				(!priv->wakeup_dev_required) &&
+				(priv->connect_status != LBS_CONNECTED)) {
+			lbs_deb_main("Entering auto deep sleep mode...\n");
+			ret = lbs_prepare_and_send_command(priv,
+					CMD_802_11_DEEP_SLEEP, 0,
+					0, 0, NULL);
+			if (ret)
+				lbs_pr_err("Enter Deep Sleep command failed\n");
+		}
+	}
+	mod_timer(&priv->auto_deepsleep_timer , jiffies +
+				(priv->auto_deep_sleep_timeout * HZ)/1000);
+	lbs_deb_leave(LBS_DEB_CMD);
+}
+
+int lbs_enter_auto_deep_sleep(struct lbs_private *priv)
+{
+	lbs_deb_enter(LBS_DEB_SDIO);
+
+	priv->is_auto_deep_sleep_enabled = 1;
+	if (priv->is_deep_sleep)
+		priv->wakeup_dev_required = 1;
+	mod_timer(&priv->auto_deepsleep_timer ,
+			jiffies + (priv->auto_deep_sleep_timeout * HZ)/1000);
+
+	lbs_deb_leave(LBS_DEB_SDIO);
+	return 0;
+}
+
+int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
+{
+	lbs_deb_enter(LBS_DEB_SDIO);
+
+	priv->is_auto_deep_sleep_enabled = 0;
+	priv->auto_deep_sleep_timeout = 0;
+	del_timer(&priv->auto_deepsleep_timer);
+
+	lbs_deb_leave(LBS_DEB_SDIO);
+	return 0;
+}
+
 static void lbs_sync_channel_worker(struct work_struct *work)
 {
 	struct lbs_private *priv = container_of(work, struct lbs_private,
@@ -1092,18 +851,24 @@ static int lbs_init_adapter(struct lbs_p
 	priv->mesh_connect_status = LBS_DISCONNECTED;
 	priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 	priv->mode = IW_MODE_INFRA;
-	priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
+	priv->channel = DEFAULT_AD_HOC_CHANNEL;
 	priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
 	priv->radio_on = 1;
 	priv->enablehwauto = 1;
 	priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
 	priv->psmode = LBS802_11POWERMODECAM;
 	priv->psstate = PS_STATE_FULL_POWER;
+	priv->is_deep_sleep = 0;
+	priv->is_auto_deep_sleep_enabled = 0;
+	priv->wakeup_dev_required = 0;
+	init_waitqueue_head(&priv->ds_awake_q);
 
 	mutex_init(&priv->lock);
 
 	setup_timer(&priv->command_timer, command_timer_fn,
 		(unsigned long)priv);
+	setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
+			(unsigned long)priv);
 
 	INIT_LIST_HEAD(&priv->cmdfreeq);
 	INIT_LIST_HEAD(&priv->cmdpendingq);
@@ -1121,10 +886,9 @@ static int lbs_init_adapter(struct lbs_p
 	priv->resp_len[0] = priv->resp_len[1] = 0;
 
 	/* Create the event FIFO */
-	priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL);
-	if (IS_ERR(priv->event_fifo)) {
+	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
+	if (ret) {
 		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
-		ret = -ENOMEM;
 		goto out;
 	}
 
@@ -1139,9 +903,9 @@ static void lbs_free_adapter(struct lbs_
 	lbs_deb_enter(LBS_DEB_MAIN);
 
 	lbs_free_cmd_buffer(priv);
-	if (priv->event_fifo)
-		kfifo_free(priv->event_fifo);
+	kfifo_free(&priv->event_fifo);
 	del_timer(&priv->command_timer);
+	del_timer(&priv->auto_deepsleep_timer);
 	kfree(priv->networks);
 	priv->networks = NULL;
 
@@ -1168,31 +932,41 @@ static const struct net_device_ops lbs_n
  */
 struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 {
-	struct net_device *dev = NULL;
+	struct net_device *dev;
+	struct wireless_dev *wdev;
 	struct lbs_private *priv = NULL;
 
 	lbs_deb_enter(LBS_DEB_MAIN);
 
 	/* Allocate an Ethernet device and register it */
-	dev = alloc_etherdev(sizeof(struct lbs_private));
-	if (!dev) {
-		lbs_pr_err("init wlanX device failed\n");
+	wdev = lbs_cfg_alloc(dmdev);
+	if (IS_ERR(wdev)) {
+		lbs_pr_err("cfg80211 init failed\n");
 		goto done;
 	}
-	priv = netdev_priv(dev);
-	dev->ml_priv = priv;
+	/* TODO? */
+	wdev->iftype = NL80211_IFTYPE_STATION;
+	priv = wdev_priv(wdev);
+	priv->wdev = wdev;
 
 	if (lbs_init_adapter(priv)) {
 		lbs_pr_err("failed to initialize adapter structure.\n");
-		goto err_init_adapter;
+		goto err_wdev;
 	}
 
+	//TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
+	dev = alloc_netdev(0, "wlan%d", ether_setup);
+	if (!dev) {
+		dev_err(dmdev, "no memory for network device instance\n");
+		goto err_adapter;
+	}
+
+	dev->ieee80211_ptr = wdev;
+	dev->ml_priv = priv;
+	SET_NETDEV_DEV(dev, dmdev);
+	wdev->netdev = dev;
 	priv->dev = dev;
-	priv->card = card;
-	priv->mesh_open = 0;
-	priv->infra_open = 0;
 
-	/* Setup the OS Interface to our functions */
  	dev->netdev_ops = &lbs_netdev_ops;
 	dev->watchdog_timeo = 5 * HZ;
 	dev->ethtool_ops = &lbs_ethtool_ops;
@@ -1201,7 +975,13 @@ struct lbs_private *lbs_add_card(void *c
 #endif
 	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
 
-	SET_NETDEV_DEV(dev, dmdev);
+
+	// TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ??
+
+
+	priv->card = card;
+	priv->infra_open = 0;
+
 
 	priv->rtap_net_dev = NULL;
 	strcpy(dev->name, "wlan%d");
@@ -1211,7 +991,7 @@ struct lbs_private *lbs_add_card(void *c
 	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
 	if (IS_ERR(priv->main_thread)) {
 		lbs_deb_thread("Error creating main thread.\n");
-		goto err_init_adapter;
+		goto err_ndev;
 	}
 
 	priv->work_thread = create_singlethread_workqueue("lbs_worker");
@@ -1220,6 +1000,7 @@ struct lbs_private *lbs_add_card(void *c
 	INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
 	INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
 
+	priv->mesh_open = 0;
 	sprintf(priv->mesh_ssid, "mesh");
 	priv->mesh_ssid_len = 4;
 
@@ -1228,9 +1009,15 @@ struct lbs_private *lbs_add_card(void *c
 
 	goto done;
 
-err_init_adapter:
-	lbs_free_adapter(priv);
+ err_ndev:
 	free_netdev(dev);
+
+ err_adapter:
+	lbs_free_adapter(priv);
+
+ err_wdev:
+	lbs_cfg_free(priv);
+
 	priv = NULL;
 
 done:
@@ -1243,7 +1030,6 @@ EXPORT_SYMBOL_GPL(lbs_add_card);
 void lbs_remove_card(struct lbs_private *priv)
 {
 	struct net_device *dev = priv->dev;
-	union iwreq_data wrqu;
 
 	lbs_deb_enter(LBS_DEB_MAIN);
 
@@ -1268,15 +1054,19 @@ void lbs_remove_card(struct lbs_private
 		lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
 	}
 
-	memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+	lbs_send_disconnect_notification(priv);
+
+	if (priv->is_deep_sleep) {
+		priv->is_deep_sleep = 0;
+		wake_up_interruptible(&priv->ds_awake_q);
+	}
 
 	/* Stop the thread servicing the interrupts */
 	priv->surpriseremoved = 1;
 	kthread_stop(priv->main_thread);
 
 	lbs_free_adapter(priv);
+	lbs_cfg_free(priv);
 
 	priv->dev = NULL;
 	free_netdev(dev);
@@ -1298,60 +1088,19 @@ int lbs_start_card(struct lbs_private *p
 	if (ret)
 		goto done;
 
-	/* init 802.11d */
-	lbs_init_11d(priv);
-
-	if (register_netdev(dev)) {
-		lbs_pr_err("cannot register ethX device\n");
+	if (lbs_cfg_register(priv)) {
+		lbs_pr_err("cannot register device\n");
 		goto done;
 	}
 
 	lbs_update_channel(priv);
 
-	/* Check mesh FW version and appropriately send the mesh start
-	 * command
+	/*
+	 * While rtap isn't related to mesh, only mesh-enabled
+	 * firmware implements the rtap functionality via
+	 * CMD_802_11_MONITOR_MODE.
 	 */
-	if (priv->mesh_fw_ver == MESH_FW_OLD) {
-		/* Enable mesh, if supported, and work out which TLV it uses.
-		   0x100 + 291 is an unofficial value used in 5.110.20.pXX
-		   0x100 + 37 is the official value used in 5.110.21.pXX
-		   but we check them in that order because 20.pXX doesn't
-		   give an error -- it just silently fails. */
-
-		/* 5.110.20.pXX firmware will fail the command if the channel
-		   doesn't match the existing channel. But only if the TLV
-		   is correct. If the channel is wrong, _BOTH_ versions will
-		   give an error to 0x100+291, and allow 0x100+37 to succeed.
-		   It's just that 5.110.20.pXX will not have done anything
-		   useful */
-
-		priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
-		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-				    priv->curbssparams.channel)) {
-			priv->mesh_tlv = TLV_TYPE_MESH_ID;
-			if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-					    priv->curbssparams.channel))
-				priv->mesh_tlv = 0;
-		}
-	} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
-		/* 10.0.0.pXX new firmwares should succeed with TLV
-		 * 0x100+37; Do not invoke command with old TLV.
-		 */
-		priv->mesh_tlv = TLV_TYPE_MESH_ID;
-		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-				    priv->curbssparams.channel))
-			priv->mesh_tlv = 0;
-	}
-	if (priv->mesh_tlv) {
-		lbs_add_mesh(priv);
-
-		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-			lbs_pr_err("cannot register lbs_mesh attribute\n");
-
-		/* While rtap isn't related to mesh, only mesh-enabled
-		 * firmware implements the rtap functionality via
-		 * CMD_802_11_MONITOR_MODE.
-		 */
+	if (lbs_init_mesh(priv)) {
 		if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
 			lbs_pr_err("cannot register lbs_rtap attribute\n");
 	}
@@ -1385,13 +1134,12 @@ void lbs_stop_card(struct lbs_private *p
 	netif_carrier_off(dev);
 
 	lbs_debugfs_remove_one(priv);
-	if (priv->mesh_tlv) {
-		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+	if (lbs_deinit_mesh(priv))
 		device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
-	}
 
 	/* Delete the timeout of the currently processing command */
 	del_timer_sync(&priv->command_timer);
+	del_timer_sync(&priv->auto_deepsleep_timer);
 
 	/* Flush pending command nodes */
 	spin_lock_irqsave(&priv->driver_lock, flags);
@@ -1420,157 +1168,6 @@ out:
 EXPORT_SYMBOL_GPL(lbs_stop_card);
 
 
-static const struct net_device_ops mesh_netdev_ops = {
-	.ndo_open		= lbs_dev_open,
-	.ndo_stop 		= lbs_mesh_stop,
-	.ndo_start_xmit		= lbs_hard_start_xmit,
-	.ndo_set_mac_address	= lbs_set_mac_address,
-	.ndo_set_multicast_list = lbs_set_multicast_list,
-};
-
-/**
- * @brief This function adds mshX interface
- *
- *  @param priv    A pointer to the struct lbs_private structure
- *  @return 	   0 if successful, -X otherwise
- */
-static int lbs_add_mesh(struct lbs_private *priv)
-{
-	struct net_device *mesh_dev = NULL;
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_MESH);
-
-	/* Allocate a virtual mesh device */
-	if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
-		lbs_deb_mesh("init mshX device failed\n");
-		ret = -ENOMEM;
-		goto done;
-	}
-	mesh_dev->ml_priv = priv;
-	priv->mesh_dev = mesh_dev;
-
-	mesh_dev->netdev_ops = &mesh_netdev_ops;
-	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
-	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
-			sizeof(priv->dev->dev_addr));
-
-	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
-
-#ifdef	WIRELESS_EXT
-	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
-#endif
-	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-	/* Register virtual mesh interface */
-	ret = register_netdev(mesh_dev);
-	if (ret) {
-		lbs_pr_err("cannot register mshX virtual interface\n");
-		goto err_free;
-	}
-
-	ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
-	if (ret)
-		goto err_unregister;
-
-	lbs_persist_config_init(mesh_dev);
-
-	/* Everything successful */
-	ret = 0;
-	goto done;
-
-err_unregister:
-	unregister_netdev(mesh_dev);
-
-err_free:
-	free_netdev(mesh_dev);
-
-done:
-	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-	return ret;
-}
-
-static void lbs_remove_mesh(struct lbs_private *priv)
-{
-	struct net_device *mesh_dev;
-
-
-	mesh_dev = priv->mesh_dev;
-	if (!mesh_dev)
-		return;
-
-	lbs_deb_enter(LBS_DEB_MESH);
-	netif_stop_queue(mesh_dev);
-	netif_carrier_off(mesh_dev);
-	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
-	lbs_persist_config_remove(mesh_dev);
-	unregister_netdev(mesh_dev);
-	priv->mesh_dev = NULL;
-	free_netdev(mesh_dev);
-	lbs_deb_leave(LBS_DEB_MESH);
-}
-
-/**
- *  @brief This function finds the CFP in
- *  region_cfp_table based on region and band parameter.
- *
- *  @param region  The region code
- *  @param band	   The band
- *  @param cfp_no  A pointer to CFP number
- *  @return 	   A pointer to CFP
- */
-struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
-{
-	int i, end;
-
-	lbs_deb_enter(LBS_DEB_MAIN);
-
-	end = ARRAY_SIZE(region_cfp_table);
-
-	for (i = 0; i < end ; i++) {
-		lbs_deb_main("region_cfp_table[i].region=%d\n",
-			region_cfp_table[i].region);
-		if (region_cfp_table[i].region == region) {
-			*cfp_no = region_cfp_table[i].cfp_no_BG;
-			lbs_deb_leave(LBS_DEB_MAIN);
-			return region_cfp_table[i].cfp_BG;
-		}
-	}
-
-	lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
-	return NULL;
-}
-
-int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
-{
-	int ret = 0;
-	int i = 0;
-
-	struct chan_freq_power *cfp;
-	int cfp_no;
-
-	lbs_deb_enter(LBS_DEB_MAIN);
-
-	memset(priv->region_channel, 0, sizeof(priv->region_channel));
-
-	cfp = lbs_get_region_cfp_table(region, &cfp_no);
-	if (cfp != NULL) {
-		priv->region_channel[i].nrcfp = cfp_no;
-		priv->region_channel[i].CFP = cfp;
-	} else {
-		lbs_deb_main("wrong region code %#x in band B/G\n",
-		       region);
-		ret = -1;
-		goto out;
-	}
-	priv->region_channel[i].valid = 1;
-	priv->region_channel[i].region = region;
-	priv->region_channel[i].band = band;
-	i++;
-out:
-	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
-	return ret;
-}
-
 void lbs_queue_event(struct lbs_private *priv, u32 event)
 {
 	unsigned long flags;
@@ -1581,7 +1178,7 @@ void lbs_queue_event(struct lbs_private
 	if (priv->psstate == PS_STATE_SLEEP)
 		priv->psstate = PS_STATE_AWAKE;
 
-	__kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32));
+	kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
 	wake_up_interruptible(&priv->waitq);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,15 @@
-libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o	\
-		 debugfs.o persistcfg.o ethtool.o assoc.o
+libertas-y += assoc.o
+libertas-y += cfg.o
+libertas-y += cmd.o
+libertas-y += cmdresp.o
+libertas-y += debugfs.o
+libertas-y += ethtool.o
+libertas-y += main.o
+libertas-y += mesh.o
+libertas-y += rx.o
+libertas-y += scan.o
+libertas-y += tx.o
+libertas-y += wext.o
 
 usb8xxx-objs += if_usb.o
 libertas_cs-objs += if_cs.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/mesh.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/mesh.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1141 @@
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/kthread.h>
+#include <linux/kfifo.h>
+
+#include "mesh.h"
+#include "decl.h"
+#include "cmd.h"
+
+
+/***************************************************************************
+ * Mesh sysfs support
+ */
+
+/**
+ * Attributes exported through sysfs
+ */
+
+/**
+ * @brief Get function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_get(struct device *dev,
+		struct device_attribute *attr, char * buf)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_access mesh_access;
+	int ret;
+
+	memset(&mesh_access, 0, sizeof(mesh_access));
+
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
+}
+
+/**
+ * @brief Set function for sysfs attribute anycast_mask
+ */
+static ssize_t lbs_anycast_set(struct device *dev,
+		struct device_attribute *attr, const char * buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_access mesh_access;
+	uint32_t datum;
+	int ret;
+
+	memset(&mesh_access, 0, sizeof(mesh_access));
+	sscanf(buf, "%x", &datum);
+	mesh_access.data[0] = cpu_to_le32(datum);
+
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_access mesh_access;
+	int ret;
+	u32 retry_limit;
+
+	memset(&mesh_access, 0, sizeof(mesh_access));
+	mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
+
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+			&mesh_access);
+	if (ret)
+		return ret;
+
+	retry_limit = le32_to_cpu(mesh_access.data[1]);
+	return snprintf(buf, 10, "%d\n", retry_limit);
+}
+
+/**
+ * @brief Set function for sysfs attribute prb_rsp_limit
+ */
+static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_access mesh_access;
+	int ret;
+	unsigned long retry_limit;
+
+	memset(&mesh_access, 0, sizeof(mesh_access));
+	mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
+
+	if (!strict_strtoul(buf, 10, &retry_limit))
+		return -ENOTSUPP;
+	if (retry_limit > 15)
+		return -ENOTSUPP;
+
+	mesh_access.data[1] = cpu_to_le32(retry_limit);
+
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
+			&mesh_access);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * Get function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_get(struct device *dev,
+		struct device_attribute *attr, char * buf)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
+}
+
+/**
+ *  Set function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_set(struct device *dev,
+		struct device_attribute *attr, const char * buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	int enable;
+	int ret, action = CMD_ACT_MESH_CONFIG_STOP;
+
+	sscanf(buf, "%x", &enable);
+	enable = !!enable;
+	if (enable == !!priv->mesh_dev)
+		return count;
+	if (enable)
+		action = CMD_ACT_MESH_CONFIG_START;
+	ret = lbs_mesh_config(priv, action, priv->channel);
+	if (ret)
+		return ret;
+
+	if (enable)
+		lbs_add_mesh(priv);
+	else
+		lbs_remove_mesh(priv);
+
+	return count;
+}
+
+/**
+ * lbs_mesh attribute to be exported per ethX interface
+ * through sysfs (/sys/class/net/ethX/lbs_mesh)
+ */
+static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
+
+/**
+ * anycast_mask attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/anycast_mask)
+ */
+static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
+
+/**
+ * prb_rsp_limit attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
+ */
+static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
+		lbs_prb_rsp_limit_set);
+
+static struct attribute *lbs_mesh_sysfs_entries[] = {
+	&dev_attr_anycast_mask.attr,
+	&dev_attr_prb_rsp_limit.attr,
+	NULL,
+};
+
+static struct attribute_group lbs_mesh_attr_group = {
+	.attrs = lbs_mesh_sysfs_entries,
+};
+
+
+
+/***************************************************************************
+ * Initializing and starting, stopping mesh
+ */
+
+/*
+ * Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+int lbs_init_mesh(struct lbs_private *priv)
+{
+	struct net_device *dev = priv->dev;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+
+	if (priv->mesh_fw_ver == MESH_FW_OLD) {
+		/* Enable mesh, if supported, and work out which TLV it uses.
+		   0x100 + 291 is an unofficial value used in 5.110.20.pXX
+		   0x100 + 37 is the official value used in 5.110.21.pXX
+		   but we check them in that order because 20.pXX doesn't
+		   give an error -- it just silently fails. */
+
+		/* 5.110.20.pXX firmware will fail the command if the channel
+		   doesn't match the existing channel. But only if the TLV
+		   is correct. If the channel is wrong, _BOTH_ versions will
+		   give an error to 0x100+291, and allow 0x100+37 to succeed.
+		   It's just that 5.110.20.pXX will not have done anything
+		   useful */
+
+		priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
+		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+				    priv->channel)) {
+			priv->mesh_tlv = TLV_TYPE_MESH_ID;
+			if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+					    priv->channel))
+				priv->mesh_tlv = 0;
+		}
+	} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+		/* 10.0.0.pXX new firmwares should succeed with TLV
+		 * 0x100+37; Do not invoke command with old TLV.
+		 */
+		priv->mesh_tlv = TLV_TYPE_MESH_ID;
+		if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+				    priv->channel))
+			priv->mesh_tlv = 0;
+	}
+	if (priv->mesh_tlv) {
+		lbs_add_mesh(priv);
+
+		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+			lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+		ret = 1;
+	}
+
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+	return ret;
+}
+
+
+int lbs_deinit_mesh(struct lbs_private *priv)
+{
+	struct net_device *dev = priv->dev;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+
+	if (priv->mesh_tlv) {
+		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+		ret = 1;
+	}
+
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+	return ret;
+}
+
+
+/**
+ *  @brief This function closes the mshX interface
+ *
+ *  @param dev     A pointer to net_device structure
+ *  @return 	   0
+ */
+static int lbs_mesh_stop(struct net_device *dev)
+{
+	struct lbs_private *priv = dev->ml_priv;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+	spin_lock_irq(&priv->driver_lock);
+
+	priv->mesh_open = 0;
+	priv->mesh_connect_status = LBS_DISCONNECTED;
+
+	netif_stop_queue(dev);
+	netif_carrier_off(dev);
+
+	spin_unlock_irq(&priv->driver_lock);
+
+	schedule_work(&priv->mcast_work);
+
+	lbs_deb_leave(LBS_DEB_MESH);
+	return 0;
+}
+
+/**
+ *  @brief This function opens the mshX interface
+ *
+ *  @param dev     A pointer to net_device structure
+ *  @return 	   0 or -EBUSY if monitor mode active
+ */
+static int lbs_mesh_dev_open(struct net_device *dev)
+{
+	struct lbs_private *priv = dev->ml_priv;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_NET);
+
+	spin_lock_irq(&priv->driver_lock);
+
+	if (priv->monitormode) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	priv->mesh_open = 1;
+	priv->mesh_connect_status = LBS_CONNECTED;
+	netif_carrier_on(dev);
+
+	if (!priv->tx_pending_len)
+		netif_wake_queue(dev);
+ out:
+
+	spin_unlock_irq(&priv->driver_lock);
+	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+	return ret;
+}
+
+static const struct net_device_ops mesh_netdev_ops = {
+	.ndo_open		= lbs_mesh_dev_open,
+	.ndo_stop 		= lbs_mesh_stop,
+	.ndo_start_xmit		= lbs_hard_start_xmit,
+	.ndo_set_mac_address	= lbs_set_mac_address,
+	.ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
+/**
+ * @brief This function adds mshX interface
+ *
+ *  @param priv    A pointer to the struct lbs_private structure
+ *  @return 	   0 if successful, -X otherwise
+ */
+int lbs_add_mesh(struct lbs_private *priv)
+{
+	struct net_device *mesh_dev = NULL;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+
+	/* Allocate a virtual mesh device */
+	mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
+	if (!mesh_dev) {
+		lbs_deb_mesh("init mshX device failed\n");
+		ret = -ENOMEM;
+		goto done;
+	}
+	mesh_dev->ml_priv = priv;
+	priv->mesh_dev = mesh_dev;
+
+	mesh_dev->netdev_ops = &mesh_netdev_ops;
+	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
+	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
+
+	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
+
+#ifdef	WIRELESS_EXT
+	mesh_dev->wireless_handlers = &mesh_handler_def;
+#endif
+	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+	/* Register virtual mesh interface */
+	ret = register_netdev(mesh_dev);
+	if (ret) {
+		lbs_pr_err("cannot register mshX virtual interface\n");
+		goto err_free;
+	}
+
+	ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+	if (ret)
+		goto err_unregister;
+
+	lbs_persist_config_init(mesh_dev);
+
+	/* Everything successful */
+	ret = 0;
+	goto done;
+
+err_unregister:
+	unregister_netdev(mesh_dev);
+
+err_free:
+	free_netdev(mesh_dev);
+
+done:
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+	return ret;
+}
+
+void lbs_remove_mesh(struct lbs_private *priv)
+{
+	struct net_device *mesh_dev;
+
+	mesh_dev = priv->mesh_dev;
+	if (!mesh_dev)
+		return;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+	netif_stop_queue(mesh_dev);
+	netif_carrier_off(mesh_dev);
+	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+	lbs_persist_config_remove(mesh_dev);
+	unregister_netdev(mesh_dev);
+	priv->mesh_dev = NULL;
+	free_netdev(mesh_dev);
+	lbs_deb_leave(LBS_DEB_MESH);
+}
+
+
+
+/***************************************************************************
+ * Sending and receiving
+ */
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+	struct net_device *dev, struct rxpd *rxpd)
+{
+	if (priv->mesh_dev) {
+		if (priv->mesh_fw_ver == MESH_FW_OLD) {
+			if (rxpd->rx_control & RxPD_MESH_FRAME)
+				dev = priv->mesh_dev;
+		} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+			if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
+				dev = priv->mesh_dev;
+		}
+	}
+	return dev;
+}
+
+
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+	struct net_device *dev, struct txpd *txpd)
+{
+	if (dev == priv->mesh_dev) {
+		if (priv->mesh_fw_ver == MESH_FW_OLD)
+			txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+		else if (priv->mesh_fw_ver == MESH_FW_NEW)
+			txpd->u.bss.bss_num = MESH_IFACE_ID;
+	}
+}
+
+
+/***************************************************************************
+ * Mesh command handling
+ */
+
+int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
+			       u16 cmd_action, void *pdata_buf)
+{
+	struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
+	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+	cmd->command = cpu_to_le16(CMD_BT_ACCESS);
+	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) +
+		sizeof(struct cmd_header));
+	cmd->result = 0;
+	bt_access->action = cpu_to_le16(cmd_action);
+
+	switch (cmd_action) {
+	case CMD_ACT_BT_ACCESS_ADD:
+		memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
+		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
+			bt_access->addr1, 6);
+		break;
+	case CMD_ACT_BT_ACCESS_DEL:
+		memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
+		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
+			bt_access->addr1, 6);
+		break;
+	case CMD_ACT_BT_ACCESS_LIST:
+		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
+		break;
+	case CMD_ACT_BT_ACCESS_RESET:
+		break;
+	case CMD_ACT_BT_ACCESS_SET_INVERT:
+		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
+		break;
+	case CMD_ACT_BT_ACCESS_GET_INVERT:
+		break;
+	default:
+		break;
+	}
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
+			       u16 cmd_action, void *pdata_buf)
+{
+	struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
+	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+	cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
+	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) +
+		sizeof(struct cmd_header));
+	cmd->result = 0;
+
+	if (pdata_buf)
+		memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
+	else
+		memset(fwt_access, 0, sizeof(*fwt_access));
+
+	fwt_access->action = cpu_to_le16(cmd_action);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+		    struct cmd_ds_mesh_access *cmd)
+{
+	int ret;
+
+	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+	cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
+	cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
+	cmd->hdr.result = 0;
+
+	cmd->action = cpu_to_le16(cmd_action);
+
+	ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return ret;
+}
+
+static int __lbs_mesh_config_send(struct lbs_private *priv,
+				  struct cmd_ds_mesh_config *cmd,
+				  uint16_t action, uint16_t type)
+{
+	int ret;
+	u16 command = CMD_MESH_CONFIG_OLD;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	/*
+	 * Command id is 0xac for v10 FW along with mesh interface
+	 * id in bits 14-13-12.
+	 */
+	if (priv->mesh_fw_ver == MESH_FW_NEW)
+		command = CMD_MESH_CONFIG |
+			  (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+	cmd->hdr.command = cpu_to_le16(command);
+	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
+	cmd->hdr.result = 0;
+
+	cmd->type = cpu_to_le16(type);
+	cmd->action = cpu_to_le16(action);
+
+	ret = lbs_cmd_with_response(priv, command, cmd);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return ret;
+}
+
+int lbs_mesh_config_send(struct lbs_private *priv,
+			 struct cmd_ds_mesh_config *cmd,
+			 uint16_t action, uint16_t type)
+{
+	int ret;
+
+	if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
+		return -EOPNOTSUPP;
+
+	ret = __lbs_mesh_config_send(priv, cmd, action, type);
+	return ret;
+}
+
+/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
+ * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
+ * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
+ * lbs_mesh_config_send.
+ */
+int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
+{
+	struct cmd_ds_mesh_config cmd;
+	struct mrvl_meshie *ie;
+	DECLARE_SSID_BUF(ssid);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.channel = cpu_to_le16(chan);
+	ie = (struct mrvl_meshie *)cmd.data;
+
+	switch (action) {
+	case CMD_ACT_MESH_CONFIG_START:
+		ie->id = WLAN_EID_GENERIC;
+		ie->val.oui[0] = 0x00;
+		ie->val.oui[1] = 0x50;
+		ie->val.oui[2] = 0x43;
+		ie->val.type = MARVELL_MESH_IE_TYPE;
+		ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
+		ie->val.version = MARVELL_MESH_IE_VERSION;
+		ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
+		ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
+		ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
+		ie->val.mesh_id_len = priv->mesh_ssid_len;
+		memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
+		ie->len = sizeof(struct mrvl_meshie_val) -
+			IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
+		cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
+		break;
+	case CMD_ACT_MESH_CONFIG_STOP:
+		break;
+	default:
+		return -1;
+	}
+	lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
+		    action, priv->mesh_tlv, chan,
+		    print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
+
+	return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
+}
+
+
+
+/***************************************************************************
+ * Persistent configuration support
+ */
+
+static int mesh_get_default_parameters(struct device *dev,
+				       struct mrvl_mesh_defaults *defs)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_config cmd;
+	int ret;
+
+	memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
+				   CMD_TYPE_MESH_GET_DEFAULTS);
+
+	if (ret)
+		return -EOPNOTSUPP;
+
+	memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
+
+	return 0;
+}
+
+/**
+ * @brief Get function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_get(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
+}
+
+/**
+ * @brief Set function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_config cmd;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if ((ret != 1) || (datum > 1))
+		return -EINVAL;
+
+	*((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
+	cmd.length = cpu_to_le16(sizeof(uint32_t));
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_BOOTFLAG);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute boottime
+ */
+static ssize_t boottime_get(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 12, "%d\n", defs.boottime);
+}
+
+/**
+ * @brief Set function for sysfs attribute boottime
+ */
+static ssize_t boottime_set(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_config cmd;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if ((ret != 1) || (datum > 255))
+		return -EINVAL;
+
+	/* A too small boot time will result in the device booting into
+	 * standalone (no-host) mode before the host can take control of it,
+	 * so the change will be hard to revert.  This may be a desired
+	 * feature (e.g to configure a very fast boot time for devices that
+	 * will not be attached to a host), but dangerous.  So I'm enforcing a
+	 * lower limit of 20 seconds:  remove and recompile the driver if this
+	 * does not work for you.
+	 */
+	datum = (datum < 20) ? 20 : datum;
+	cmd.data[0] = datum;
+	cmd.length = cpu_to_le16(sizeof(uint8_t));
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_BOOTTIME);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute channel
+ */
+static ssize_t channel_get(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel));
+}
+
+/**
+ * @brief Set function for sysfs attribute channel
+ */
+static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	struct cmd_ds_mesh_config cmd;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if (ret != 1 || datum < 1 || datum > 11)
+		return -EINVAL;
+
+	*((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
+	cmd.length = cpu_to_le16(sizeof(uint16_t));
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_DEF_CHANNEL);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int maxlen;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
+		lbs_pr_err("inconsistent mesh ID length");
+		defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
+	}
+
+	/* SSID not null terminated: reserve room for \0 + \n */
+	maxlen = defs.meshie.val.mesh_id_len + 2;
+	maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
+
+	defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
+
+	return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct cmd_ds_mesh_config cmd;
+	struct mrvl_mesh_defaults defs;
+	struct mrvl_meshie *ie;
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	int len;
+	int ret;
+
+	if (count < 2 || count > IEEE80211_MAX_SSID_LEN + 1)
+		return -EINVAL;
+
+	memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+	ie = (struct mrvl_meshie *) &cmd.data[0];
+
+	/* fetch all other Information Element parameters */
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+	/* transfer IE elements */
+	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+
+	len = count - 1;
+	memcpy(ie->val.mesh_id, buf, len);
+	/* SSID len */
+	ie->val.mesh_id_len = len;
+	/* IE len */
+	ie->len = sizeof(struct mrvl_meshie_val) - IEEE80211_MAX_SSID_LEN + len;
+
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_MESH_IE);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_get(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_set(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct cmd_ds_mesh_config cmd;
+	struct mrvl_mesh_defaults defs;
+	struct mrvl_meshie *ie;
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if ((ret != 1) || (datum > 255))
+		return -EINVAL;
+
+	/* fetch all other Information Element parameters */
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+	/* transfer IE elements */
+	ie = (struct mrvl_meshie *) &cmd.data[0];
+	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+	/* update protocol id */
+	ie->val.active_protocol_id = datum;
+
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_MESH_IE);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_get(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct cmd_ds_mesh_config cmd;
+	struct mrvl_mesh_defaults defs;
+	struct mrvl_meshie *ie;
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if ((ret != 1) || (datum > 255))
+		return -EINVAL;
+
+	/* fetch all other Information Element parameters */
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+	/* transfer IE elements */
+	ie = (struct mrvl_meshie *) &cmd.data[0];
+	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+	/* update metric id */
+	ie->val.active_metric_id = datum;
+
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_MESH_IE);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute capability
+ */
+static ssize_t capability_get(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mrvl_mesh_defaults defs;
+	int ret;
+
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	if (ret)
+		return ret;
+
+	return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
+}
+
+/**
+ * @brief Set function for sysfs attribute capability
+ */
+static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct cmd_ds_mesh_config cmd;
+	struct mrvl_mesh_defaults defs;
+	struct mrvl_meshie *ie;
+	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+	uint32_t datum;
+	int ret;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ret = sscanf(buf, "%d", &datum);
+	if ((ret != 1) || (datum > 255))
+		return -EINVAL;
+
+	/* fetch all other Information Element parameters */
+	ret = mesh_get_default_parameters(dev, &defs);
+
+	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+	/* transfer IE elements */
+	ie = (struct mrvl_meshie *) &cmd.data[0];
+	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+	/* update value */
+	ie->val.mesh_capability = datum;
+
+	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+				   CMD_TYPE_MESH_SET_MESH_IE);
+	if (ret)
+		return ret;
+
+	return strlen(buf);
+}
+
+
+static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
+static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
+static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
+static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
+static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
+static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
+static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
+
+static struct attribute *boot_opts_attrs[] = {
+	&dev_attr_bootflag.attr,
+	&dev_attr_boottime.attr,
+	&dev_attr_channel.attr,
+	NULL
+};
+
+static struct attribute_group boot_opts_group = {
+	.name = "boot_options",
+	.attrs = boot_opts_attrs,
+};
+
+static struct attribute *mesh_ie_attrs[] = {
+	&dev_attr_mesh_id.attr,
+	&dev_attr_protocol_id.attr,
+	&dev_attr_metric_id.attr,
+	&dev_attr_capability.attr,
+	NULL
+};
+
+static struct attribute_group mesh_ie_group = {
+	.name = "mesh_ie",
+	.attrs = mesh_ie_attrs,
+};
+
+void lbs_persist_config_init(struct net_device *dev)
+{
+	int ret;
+	ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
+	ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+void lbs_persist_config_remove(struct net_device *dev)
+{
+	sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
+	sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+
+
+/***************************************************************************
+ * Ethtool related
+ */
+
+static const char *mesh_stat_strings[] = {
+			"drop_duplicate_bcast",
+			"drop_ttl_zero",
+			"drop_no_fwd_route",
+			"drop_no_buffers",
+			"fwded_unicast_cnt",
+			"fwded_bcast_cnt",
+			"drop_blind_table",
+			"tx_failed_cnt"
+};
+
+void lbs_mesh_ethtool_get_stats(struct net_device *dev,
+	struct ethtool_stats *stats, uint64_t *data)
+{
+	struct lbs_private *priv = dev->ml_priv;
+	struct cmd_ds_mesh_access mesh_access;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_ETHTOOL);
+
+	/* Get Mesh Statistics */
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
+
+	if (ret) {
+		memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
+		return;
+	}
+
+	priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
+	priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
+	priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
+	priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
+	priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
+	priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
+	priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
+	priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
+
+	data[0] = priv->mstats.fwd_drop_rbt;
+	data[1] = priv->mstats.fwd_drop_ttl;
+	data[2] = priv->mstats.fwd_drop_noroute;
+	data[3] = priv->mstats.fwd_drop_nobuf;
+	data[4] = priv->mstats.fwd_unicast_cnt;
+	data[5] = priv->mstats.fwd_bcast_cnt;
+	data[6] = priv->mstats.drop_blind;
+	data[7] = priv->mstats.tx_failed_cnt;
+
+	lbs_deb_enter(LBS_DEB_ETHTOOL);
+}
+
+int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+	struct lbs_private *priv = dev->ml_priv;
+
+	if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
+		return MESH_STATS_NUM;
+
+	return -EOPNOTSUPP;
+}
+
+void lbs_mesh_ethtool_get_strings(struct net_device *dev,
+	uint32_t stringset, uint8_t *s)
+{
+	int i;
+
+	lbs_deb_enter(LBS_DEB_ETHTOOL);
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < MESH_STATS_NUM; i++) {
+			memcpy(s + i * ETH_GSTRING_LEN,
+					mesh_stat_strings[i],
+					ETH_GSTRING_LEN);
+		}
+		break;
+	}
+	lbs_deb_enter(LBS_DEB_ETHTOOL);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/mesh.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/mesh.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/mesh.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,78 @@
+/**
+  * Contains all definitions needed for the Libertas' MESH implementation.
+  */
+#ifndef _LBS_MESH_H_
+#define _LBS_MESH_H_
+
+
+#include <net/iw_handler.h>
+#include <net/lib80211.h>
+
+
+/* Mesh statistics */
+struct lbs_mesh_stats {
+	u32	fwd_bcast_cnt;		/* Fwd: Broadcast counter */
+	u32	fwd_unicast_cnt;	/* Fwd: Unicast counter */
+	u32	fwd_drop_ttl;		/* Fwd: TTL zero */
+	u32	fwd_drop_rbt;		/* Fwd: Recently Broadcasted */
+	u32	fwd_drop_noroute; 	/* Fwd: No route to Destination */
+	u32	fwd_drop_nobuf;		/* Fwd: Run out of internal buffers */
+	u32	drop_blind;		/* Rx:  Dropped by blinding table */
+	u32	tx_failed_cnt;		/* Tx:  Failed transmissions */
+};
+
+
+struct net_device;
+struct lbs_private;
+
+int lbs_init_mesh(struct lbs_private *priv);
+int lbs_deinit_mesh(struct lbs_private *priv);
+
+int lbs_add_mesh(struct lbs_private *priv);
+void lbs_remove_mesh(struct lbs_private *priv);
+
+
+/* Sending / Receiving */
+
+struct rxpd;
+struct txpd;
+
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+	struct net_device *dev, struct rxpd *rxpd);
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+	struct net_device *dev, struct txpd *txpd);
+
+
+/* Command handling */
+
+struct cmd_ds_command;
+
+int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
+	u16 cmd_action, void *pdata_buf);
+int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
+	u16 cmd_action, void *pdata_buf);
+
+
+/* Persistent configuration */
+
+void lbs_persist_config_init(struct net_device *net);
+void lbs_persist_config_remove(struct net_device *net);
+
+
+/* WEXT handler */
+
+extern struct iw_handler_def mesh_handler_def;
+
+
+/* Ethtool statistics */
+
+struct ethtool_stats;
+
+void lbs_mesh_ethtool_get_stats(struct net_device *dev,
+	struct ethtool_stats *stats, uint64_t *data);
+int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset);
+void lbs_mesh_ethtool_get_strings(struct net_device *dev,
+	uint32_t stringset, uint8_t *s);
+
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/persistcfg.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/persistcfg.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/persistcfg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/persistcfg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,453 +0,0 @@
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/etherdevice.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/kthread.h>
-#include <linux/kfifo.h>
-
-#include "host.h"
-#include "decl.h"
-#include "dev.h"
-#include "wext.h"
-#include "debugfs.h"
-#include "scan.h"
-#include "assoc.h"
-#include "cmd.h"
-
-static int mesh_get_default_parameters(struct device *dev,
-				       struct mrvl_mesh_defaults *defs)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_config cmd;
-	int ret;
-
-	memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
-				   CMD_TYPE_MESH_GET_DEFAULTS);
-
-	if (ret)
-		return -EOPNOTSUPP;
-
-	memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
-
-	return 0;
-}
-
-/**
- * @brief Get function for sysfs attribute bootflag
- */
-static ssize_t bootflag_get(struct device *dev,
-			    struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
-}
-
-/**
- * @brief Set function for sysfs attribute bootflag
- */
-static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_config cmd;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if ((ret != 1) || (datum > 1))
-		return -EINVAL;
-
-	*((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
-	cmd.length = cpu_to_le16(sizeof(uint32_t));
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_BOOTFLAG);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute boottime
- */
-static ssize_t boottime_get(struct device *dev,
-			    struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 12, "%d\n", defs.boottime);
-}
-
-/**
- * @brief Set function for sysfs attribute boottime
- */
-static ssize_t boottime_set(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_config cmd;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if ((ret != 1) || (datum > 255))
-		return -EINVAL;
-
-	/* A too small boot time will result in the device booting into
-	 * standalone (no-host) mode before the host can take control of it,
-	 * so the change will be hard to revert.  This may be a desired
-	 * feature (e.g to configure a very fast boot time for devices that
-	 * will not be attached to a host), but dangerous.  So I'm enforcing a
-	 * lower limit of 20 seconds:  remove and recompile the driver if this
-	 * does not work for you.
-	 */
-	datum = (datum < 20) ? 20 : datum;
-	cmd.data[0] = datum;
-	cmd.length = cpu_to_le16(sizeof(uint8_t));
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_BOOTTIME);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute channel
- */
-static ssize_t channel_get(struct device *dev,
-			   struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel));
-}
-
-/**
- * @brief Set function for sysfs attribute channel
- */
-static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
-			   const char *buf, size_t count)
-{
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	struct cmd_ds_mesh_config cmd;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if (ret != 1 || datum < 1 || datum > 11)
-		return -EINVAL;
-
-	*((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
-	cmd.length = cpu_to_le16(sizeof(uint16_t));
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_DEF_CHANNEL);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute mesh_id
- */
-static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int maxlen;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	if (defs.meshie.val.mesh_id_len > IW_ESSID_MAX_SIZE) {
-		lbs_pr_err("inconsistent mesh ID length");
-		defs.meshie.val.mesh_id_len = IW_ESSID_MAX_SIZE;
-	}
-
-	/* SSID not null terminated: reserve room for \0 + \n */
-	maxlen = defs.meshie.val.mesh_id_len + 2;
-	maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
-
-	defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
-
-	return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
-}
-
-/**
- * @brief Set function for sysfs attribute mesh_id
- */
-static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
-			   const char *buf, size_t count)
-{
-	struct cmd_ds_mesh_config cmd;
-	struct mrvl_mesh_defaults defs;
-	struct mrvl_meshie *ie;
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	int len;
-	int ret;
-
-	if (count < 2 || count > IW_ESSID_MAX_SIZE + 1)
-		return -EINVAL;
-
-	memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
-	ie = (struct mrvl_meshie *) &cmd.data[0];
-
-	/* fetch all other Information Element parameters */
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
-	/* transfer IE elements */
-	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-
-	len = count - 1;
-	memcpy(ie->val.mesh_id, buf, len);
-	/* SSID len */
-	ie->val.mesh_id_len = len;
-	/* IE len */
-	ie->len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
-
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_MESH_IE);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute protocol_id
- */
-static ssize_t protocol_id_get(struct device *dev,
-			       struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
-}
-
-/**
- * @brief Set function for sysfs attribute protocol_id
- */
-static ssize_t protocol_id_set(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct cmd_ds_mesh_config cmd;
-	struct mrvl_mesh_defaults defs;
-	struct mrvl_meshie *ie;
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if ((ret != 1) || (datum > 255))
-		return -EINVAL;
-
-	/* fetch all other Information Element parameters */
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
-	/* transfer IE elements */
-	ie = (struct mrvl_meshie *) &cmd.data[0];
-	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-	/* update protocol id */
-	ie->val.active_protocol_id = datum;
-
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_MESH_IE);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute metric_id
- */
-static ssize_t metric_id_get(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
-}
-
-/**
- * @brief Set function for sysfs attribute metric_id
- */
-static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
-			     const char *buf, size_t count)
-{
-	struct cmd_ds_mesh_config cmd;
-	struct mrvl_mesh_defaults defs;
-	struct mrvl_meshie *ie;
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if ((ret != 1) || (datum > 255))
-		return -EINVAL;
-
-	/* fetch all other Information Element parameters */
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
-	/* transfer IE elements */
-	ie = (struct mrvl_meshie *) &cmd.data[0];
-	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-	/* update metric id */
-	ie->val.active_metric_id = datum;
-
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_MESH_IE);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-/**
- * @brief Get function for sysfs attribute capability
- */
-static ssize_t capability_get(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct mrvl_mesh_defaults defs;
-	int ret;
-
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	if (ret)
-		return ret;
-
-	return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
-}
-
-/**
- * @brief Set function for sysfs attribute capability
- */
-static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
-			      const char *buf, size_t count)
-{
-	struct cmd_ds_mesh_config cmd;
-	struct mrvl_mesh_defaults defs;
-	struct mrvl_meshie *ie;
-	struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-	uint32_t datum;
-	int ret;
-
-	memset(&cmd, 0, sizeof(cmd));
-	ret = sscanf(buf, "%d", &datum);
-	if ((ret != 1) || (datum > 255))
-		return -EINVAL;
-
-	/* fetch all other Information Element parameters */
-	ret = mesh_get_default_parameters(dev, &defs);
-
-	cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
-	/* transfer IE elements */
-	ie = (struct mrvl_meshie *) &cmd.data[0];
-	memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-	/* update value */
-	ie->val.mesh_capability = datum;
-
-	ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-				   CMD_TYPE_MESH_SET_MESH_IE);
-	if (ret)
-		return ret;
-
-	return strlen(buf);
-}
-
-
-static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
-static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
-static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
-static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
-static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
-static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
-static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
-
-static struct attribute *boot_opts_attrs[] = {
-	&dev_attr_bootflag.attr,
-	&dev_attr_boottime.attr,
-	&dev_attr_channel.attr,
-	NULL
-};
-
-static struct attribute_group boot_opts_group = {
-	.name = "boot_options",
-	.attrs = boot_opts_attrs,
-};
-
-static struct attribute *mesh_ie_attrs[] = {
-	&dev_attr_mesh_id.attr,
-	&dev_attr_protocol_id.attr,
-	&dev_attr_metric_id.attr,
-	&dev_attr_capability.attr,
-	NULL
-};
-
-static struct attribute_group mesh_ie_group = {
-	.name = "mesh_ie",
-	.attrs = mesh_ie_attrs,
-};
-
-void lbs_persist_config_init(struct net_device *dev)
-{
-	int ret;
-	ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
-	ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
-}
-
-void lbs_persist_config_remove(struct net_device *dev)
-{
-	sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
-	sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/README linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/README
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/README	2013-05-03 14:02:42.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/README	2013-05-03 12:10:17.000000000 -0400
@@ -1,5 +1,5 @@
 ================================================================================
-			README for USB8388
+			README for Libertas
 
  (c) Copyright © 2003-2006, Marvell International Ltd.
  All Rights Reserved
@@ -226,4 +226,28 @@ setuserscan
     All entries in the scan table (not just the new scan data when keep=1)
     will be displayed upon completion by use of the getscantable ioctl.
 
+========================
+IWCONFIG COMMANDS
+========================
+power period
+
+	This command is used to configure the station in deep sleep mode /
+	auto deep sleep mode.
+
+	The timer is implemented to monitor the activities (command, event,
+	etc.). When an activity is detected station will exit from deep
+	sleep mode automatically and restart the timer. At timer expiry
+	(no activity for defined time period) the deep sleep mode is entered
+	automatically.
+
+	Note: this command is for SDIO interface only.
+
+	Usage:
+	To enable deep sleep mode do:
+		iwconfig wlan0 power period 0
+	To enable auto deep sleep mode with idle time period 5 seconds do:
+		iwconfig wlan0 power period 5
+	To disable deep sleep/auto deep sleep mode do:
+		iwconfig wlan0 power period -1
+
 ==============================================================================
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/rx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,7 @@
 #include <linux/etherdevice.h>
 #include <linux/types.h>
 
-#include "hostcmd.h"
+#include "host.h"
 #include "radiotap.h"
 #include "decl.h"
 #include "dev.h"
@@ -160,15 +160,8 @@ int lbs_process_rxed_packet(struct lbs_p
 	p_rx_pd = (struct rxpd *) skb->data;
 	p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
 		le32_to_cpu(p_rx_pd->pkt_ptr));
-	if (priv->mesh_dev) {
-		if (priv->mesh_fw_ver == MESH_FW_OLD) {
-			if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
-				dev = priv->mesh_dev;
-		} else if (priv->mesh_fw_ver == MESH_FW_NEW) {
-			if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
-				dev = priv->mesh_dev;
-		}
-	}
+
+	dev = lbs_mesh_set_dev(priv, dev, p_rx_pd);
 
 	lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
 		 min_t(unsigned int, skb->len, 100));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/scan.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/scan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,18 +12,19 @@
 #include <net/lib80211.h>
 
 #include "host.h"
-#include "decl.h"
 #include "dev.h"
 #include "scan.h"
+#include "assoc.h"
+#include "wext.h"
 #include "cmd.h"
 
 //! Approximate amount of data needed to pass a scan result back to iwlist
 #define MAX_SCAN_CELL_SIZE  (IW_EV_ADDR_LEN             \
-                             + IW_ESSID_MAX_SIZE        \
+                             + IEEE80211_MAX_SSID_LEN   \
                              + IW_EV_UINT_LEN           \
                              + IW_EV_FREQ_LEN           \
                              + IW_EV_QUAL_LEN           \
-                             + IW_ESSID_MAX_SIZE        \
+                             + IEEE80211_MAX_SSID_LEN   \
                              + IW_EV_PARAM_LEN          \
                              + 40)	/* 40 for WPAIE */
 
@@ -121,6 +122,189 @@ static inline int is_same_network(struct
 
 
 
+/*********************************************************************/
+/*                                                                   */
+/* Region channel support                                            */
+/*                                                                   */
+/*********************************************************************/
+
+#define LBS_TX_PWR_DEFAULT		20	/*100mW */
+#define LBS_TX_PWR_US_DEFAULT		20	/*100mW */
+#define LBS_TX_PWR_JP_DEFAULT		16	/*50mW */
+#define LBS_TX_PWR_FR_DEFAULT		20	/*100mW */
+#define LBS_TX_PWR_EMEA_DEFAULT	20	/*100mW */
+
+/* Format { channel, frequency (MHz), maxtxpower } */
+/* band: 'B/G', region: USA FCC/Canada IC */
+static struct chan_freq_power channel_freq_power_US_BG[] = {
+	{1, 2412, LBS_TX_PWR_US_DEFAULT},
+	{2, 2417, LBS_TX_PWR_US_DEFAULT},
+	{3, 2422, LBS_TX_PWR_US_DEFAULT},
+	{4, 2427, LBS_TX_PWR_US_DEFAULT},
+	{5, 2432, LBS_TX_PWR_US_DEFAULT},
+	{6, 2437, LBS_TX_PWR_US_DEFAULT},
+	{7, 2442, LBS_TX_PWR_US_DEFAULT},
+	{8, 2447, LBS_TX_PWR_US_DEFAULT},
+	{9, 2452, LBS_TX_PWR_US_DEFAULT},
+	{10, 2457, LBS_TX_PWR_US_DEFAULT},
+	{11, 2462, LBS_TX_PWR_US_DEFAULT}
+};
+
+/* band: 'B/G', region: Europe ETSI */
+static struct chan_freq_power channel_freq_power_EU_BG[] = {
+	{1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
+	{2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
+	{3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
+	{4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
+	{5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
+	{6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
+	{7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
+	{8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
+	{9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
+	{10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
+	{11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
+	{12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
+	{13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
+};
+
+/* band: 'B/G', region: Spain */
+static struct chan_freq_power channel_freq_power_SPN_BG[] = {
+	{10, 2457, LBS_TX_PWR_DEFAULT},
+	{11, 2462, LBS_TX_PWR_DEFAULT}
+};
+
+/* band: 'B/G', region: France */
+static struct chan_freq_power channel_freq_power_FR_BG[] = {
+	{10, 2457, LBS_TX_PWR_FR_DEFAULT},
+	{11, 2462, LBS_TX_PWR_FR_DEFAULT},
+	{12, 2467, LBS_TX_PWR_FR_DEFAULT},
+	{13, 2472, LBS_TX_PWR_FR_DEFAULT}
+};
+
+/* band: 'B/G', region: Japan */
+static struct chan_freq_power channel_freq_power_JPN_BG[] = {
+	{1, 2412, LBS_TX_PWR_JP_DEFAULT},
+	{2, 2417, LBS_TX_PWR_JP_DEFAULT},
+	{3, 2422, LBS_TX_PWR_JP_DEFAULT},
+	{4, 2427, LBS_TX_PWR_JP_DEFAULT},
+	{5, 2432, LBS_TX_PWR_JP_DEFAULT},
+	{6, 2437, LBS_TX_PWR_JP_DEFAULT},
+	{7, 2442, LBS_TX_PWR_JP_DEFAULT},
+	{8, 2447, LBS_TX_PWR_JP_DEFAULT},
+	{9, 2452, LBS_TX_PWR_JP_DEFAULT},
+	{10, 2457, LBS_TX_PWR_JP_DEFAULT},
+	{11, 2462, LBS_TX_PWR_JP_DEFAULT},
+	{12, 2467, LBS_TX_PWR_JP_DEFAULT},
+	{13, 2472, LBS_TX_PWR_JP_DEFAULT},
+	{14, 2484, LBS_TX_PWR_JP_DEFAULT}
+};
+
+/**
+ * the structure for channel, frequency and power
+ */
+struct region_cfp_table {
+	u8 region;
+	struct chan_freq_power *cfp_BG;
+	int cfp_no_BG;
+};
+
+/**
+ * the structure for the mapping between region and CFP
+ */
+static struct region_cfp_table region_cfp_table[] = {
+	{0x10,			/*US FCC */
+	 channel_freq_power_US_BG,
+	 ARRAY_SIZE(channel_freq_power_US_BG),
+	 }
+	,
+	{0x20,			/*CANADA IC */
+	 channel_freq_power_US_BG,
+	 ARRAY_SIZE(channel_freq_power_US_BG),
+	 }
+	,
+	{0x30, /*EU*/ channel_freq_power_EU_BG,
+	 ARRAY_SIZE(channel_freq_power_EU_BG),
+	 }
+	,
+	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
+	 ARRAY_SIZE(channel_freq_power_SPN_BG),
+	 }
+	,
+	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
+	 ARRAY_SIZE(channel_freq_power_FR_BG),
+	 }
+	,
+	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
+	 ARRAY_SIZE(channel_freq_power_JPN_BG),
+	 }
+	,
+/*Add new region here */
+};
+
+/**
+ *  @brief This function finds the CFP in
+ *  region_cfp_table based on region and band parameter.
+ *
+ *  @param region  The region code
+ *  @param band	   The band
+ *  @param cfp_no  A pointer to CFP number
+ *  @return 	   A pointer to CFP
+ */
+static struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
+{
+	int i, end;
+
+	lbs_deb_enter(LBS_DEB_MAIN);
+
+	end = ARRAY_SIZE(region_cfp_table);
+
+	for (i = 0; i < end ; i++) {
+		lbs_deb_main("region_cfp_table[i].region=%d\n",
+			region_cfp_table[i].region);
+		if (region_cfp_table[i].region == region) {
+			*cfp_no = region_cfp_table[i].cfp_no_BG;
+			lbs_deb_leave(LBS_DEB_MAIN);
+			return region_cfp_table[i].cfp_BG;
+		}
+	}
+
+	lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
+	return NULL;
+}
+
+int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
+{
+	int ret = 0;
+	int i = 0;
+
+	struct chan_freq_power *cfp;
+	int cfp_no;
+
+	lbs_deb_enter(LBS_DEB_MAIN);
+
+	memset(priv->region_channel, 0, sizeof(priv->region_channel));
+
+	cfp = lbs_get_region_cfp_table(region, &cfp_no);
+	if (cfp != NULL) {
+		priv->region_channel[i].nrcfp = cfp_no;
+		priv->region_channel[i].CFP = cfp;
+	} else {
+		lbs_deb_main("wrong region code %#x in band B/G\n",
+		       region);
+		ret = -1;
+		goto out;
+	}
+	priv->region_channel[i].valid = 1;
+	priv->region_channel[i].region = region;
+	priv->region_channel[i].band = band;
+	i++;
+out:
+	lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+	return ret;
+}
+
+
+
 
 /*********************************************************************/
 /*                                                                   */
@@ -161,31 +345,15 @@ static int lbs_scan_create_channel_list(
 	scantype = CMD_SCAN_TYPE_ACTIVE;
 
 	for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
-		if (priv->enable11d && (priv->connect_status != LBS_CONNECTED)
-		    && (priv->mesh_connect_status != LBS_CONNECTED)) {
-			/* Scan all the supported chan for the first scan */
-			if (!priv->universal_channel[rgnidx].valid)
-				continue;
-			scanregion = &priv->universal_channel[rgnidx];
-
-			/* clear the parsed_region_chan for the first scan */
-			memset(&priv->parsed_region_chan, 0x00,
-			       sizeof(priv->parsed_region_chan));
-		} else {
-			if (!priv->region_channel[rgnidx].valid)
-				continue;
-			scanregion = &priv->region_channel[rgnidx];
-		}
+		if (!priv->region_channel[rgnidx].valid)
+			continue;
+		scanregion = &priv->region_channel[rgnidx];
 
 		for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) {
 			struct chanscanparamset *chan = &scanchanlist[chanidx];
 
 			cfp = scanregion->CFP + nextchan;
 
-			if (priv->enable11d)
-				scantype = lbs_get_scan_type_11d(cfp->channel,
-								 &priv->parsed_region_chan);
-
 			if (scanregion->band == BAND_B || scanregion->band == BAND_G)
 				chan->radiotype = CMD_SCAN_RADIO_TYPE_BG;
 
@@ -399,11 +567,8 @@ int lbs_scan_networks(struct lbs_private
 	chan_count = lbs_scan_create_channel_list(priv, chan_list);
 
 	netif_stop_queue(priv->dev);
-	netif_carrier_off(priv->dev);
-	if (priv->mesh_dev) {
+	if (priv->mesh_dev)
 		netif_stop_queue(priv->mesh_dev);
-		netif_carrier_off(priv->mesh_dev);
-	}
 
 	/* Prepare to continue an interrupted scan */
 	lbs_deb_scan("chan_count %d, scan_channel %d\n",
@@ -467,16 +632,13 @@ out2:
 	priv->scan_channel = 0;
 
 out:
-	if (priv->connect_status == LBS_CONNECTED) {
-		netif_carrier_on(priv->dev);
-		if (!priv->tx_pending_len)
-			netif_wake_queue(priv->dev);
-	}
-	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
-		netif_carrier_on(priv->mesh_dev);
-		if (!priv->tx_pending_len)
-			netif_wake_queue(priv->mesh_dev);
-	}
+	if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len)
+		netif_wake_queue(priv->dev);
+
+	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) &&
+	    !priv->tx_pending_len)
+		netif_wake_queue(priv->mesh_dev);
+
 	kfree(chan_list);
 
 	lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
@@ -519,7 +681,6 @@ static int lbs_process_bss(struct bss_de
 	struct ieee_ie_cf_param_set *cf;
 	struct ieee_ie_ibss_param_set *ibss;
 	DECLARE_SSID_BUF(ssid);
-	struct ieee_ie_country_info_set *pcountryinfo;
 	uint8_t *pos, *end, *p;
 	uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
 	uint16_t beaconsize = 0;
@@ -642,26 +803,6 @@ static int lbs_process_bss(struct bss_de
 			lbs_deb_scan("got IBSS IE\n");
 			break;
 
-		case WLAN_EID_COUNTRY:
-			pcountryinfo = (struct ieee_ie_country_info_set *) pos;
-			lbs_deb_scan("got COUNTRY IE\n");
-			if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
-			    || pcountryinfo->header.len > 254) {
-				lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
-					     __func__,
-					     pcountryinfo->header.len,
-					     sizeof(pcountryinfo->countrycode));
-				ret = -1;
-				goto done;
-			}
-
-			memcpy(&bss->countryinfo, pcountryinfo,
-				pcountryinfo->header.len + 2);
-			lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
-				    (uint8_t *) pcountryinfo,
-				    (int) (pcountryinfo->header.len + 2));
-			break;
-
 		case WLAN_EID_EXT_SUPP_RATES:
 			/* only process extended supported rate if data rate is
 			 * already found. Data rate IE should come before
@@ -812,7 +953,7 @@ static inline char *lbs_translate_scan(s
 	/* SSID */
 	iwe.cmd = SIOCGIWESSID;
 	iwe.u.data.flags = 1;
-	iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
+	iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IEEE80211_MAX_SSID_LEN);
 	start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
 
 	/* Mode */
@@ -1022,9 +1163,12 @@ int lbs_get_scan(struct net_device *dev,
 		return -EAGAIN;
 
 	/* Update RSSI if current BSS is a locally created ad-hoc BSS */
-	if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
-		lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
-					     CMD_OPTION_WAITFORRSP, 0, NULL);
+	if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) {
+		err = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+				CMD_OPTION_WAITFORRSP, 0, NULL);
+		if (err)
+			goto out;
+	}
 
 	mutex_lock(&priv->lock);
 	list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
@@ -1058,7 +1202,7 @@ int lbs_get_scan(struct net_device *dev,
 
 	dwrq->length = (ev - extra);
 	dwrq->flags = 0;
-
+out:
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err);
 	return err;
 }
@@ -1141,11 +1285,11 @@ static int lbs_ret_80211_scan(struct lbs
 	/* The size of the TLV buffer is equal to the entire command response
 	 *   size (scanrespsize) minus the fixed fields (sizeof()'s), the
 	 *   BSS Descriptions (bssdescriptsize as bytesLef) and the command
-	 *   response header (S_DS_GEN)
+	 *   response header (sizeof(struct cmd_header))
 	 */
 	tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize)
 				     + sizeof(scanresp->nr_sets)
-				     + S_DS_GEN);
+				     + sizeof(struct cmd_header));
 
 	/*
 	 *  Process each scan response returned (scanresp->nr_sets). Save
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/scan.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/scan.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/scan.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,8 +9,36 @@
 
 #include <net/iw_handler.h>
 
+struct lbs_private;
+
 #define MAX_NETWORK_COUNT 128
 
+/** Chan-freq-TxPower mapping table*/
+struct chan_freq_power {
+	/** channel Number		*/
+	u16 channel;
+	/** frequency of this channel	*/
+	u32 freq;
+	/** Max allowed Tx power level	*/
+	u16 maxtxpower;
+	/** TRUE:channel unsupported;  FLASE:supported*/
+	u8 unsupported;
+};
+
+/** region-band mapping table*/
+struct region_channel {
+	/** TRUE if this entry is valid		     */
+	u8 valid;
+	/** region code for US, Japan ...	     */
+	u8 region;
+	/** band B/G/A, used for BAND_CONFIG cmd	     */
+	u8 band;
+	/** Actual No. of elements in the array below */
+	u8 nrcfp;
+	/** chan-freq-txpower mapping table*/
+	struct chan_freq_power *CFP;
+};
+
 /**
  *  @brief Maximum number of channels that can be sent in a setuserscan ioctl
  */
@@ -18,6 +46,8 @@
 
 int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
 
+int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
+
 int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
 				u8 ssid_len);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/tx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -5,7 +5,7 @@
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
 
-#include "hostcmd.h"
+#include "host.h"
 #include "radiotap.h"
 #include "decl.h"
 #include "defs.h"
@@ -131,12 +131,7 @@ netdev_tx_t lbs_hard_start_xmit(struct s
 	txpd->tx_packet_length = cpu_to_le16(pkt_len);
 	txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
 
-	if (dev == priv->mesh_dev) {
-		if (priv->mesh_fw_ver == MESH_FW_OLD)
-			txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
-		else if (priv->mesh_fw_ver == MESH_FW_NEW)
-			txpd->u.bss.bss_num = MESH_IFACE_ID;
-	}
+	lbs_mesh_set_txpd(priv, dev, txpd);
 
 	lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/types.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/types.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/types.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/types.h	2010-02-24 13:52:17.000000000 -0500
@@ -5,8 +5,8 @@
 #define _LBS_TYPES_H_
 
 #include <linux/if_ether.h>
+#include <linux/ieee80211.h>
 #include <asm/byteorder.h>
-#include <linux/wireless.h>
 
 struct ieee_ie_header {
 	u8 id;
@@ -247,7 +247,7 @@ struct mrvl_meshie_val {
 	uint8_t active_metric_id;
 	uint8_t mesh_capability;
 	uint8_t mesh_id_len;
-	uint8_t mesh_id[IW_ESSID_MAX_SIZE];
+	uint8_t mesh_id[IEEE80211_MAX_SSID_LEN];
 } __attribute__ ((packed));
 
 struct mrvl_meshie {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/wext.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/wext.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,6 +45,63 @@ static inline void lbs_cancel_associatio
 	priv->pending_assoc_req = NULL;
 }
 
+void lbs_send_disconnect_notification(struct lbs_private *priv)
+{
+	union iwreq_data wrqu;
+
+	memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
+{
+	union iwreq_data iwrq;
+	u8 buf[50];
+
+	lbs_deb_enter(LBS_DEB_WEXT);
+
+	memset(&iwrq, 0, sizeof(union iwreq_data));
+	memset(buf, 0, sizeof(buf));
+
+	snprintf(buf, sizeof(buf) - 1, "%s", str);
+
+	iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
+
+	/* Send Event to upper layer */
+	lbs_deb_wext("event indication string %s\n", (char *)buf);
+	lbs_deb_wext("event indication length %d\n", iwrq.data.length);
+	lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);
+
+	wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
+
+	lbs_deb_leave(LBS_DEB_WEXT);
+}
+
+/**
+ *  @brief This function handles MIC failure event.
+ *
+ *  @param priv    A pointer to struct lbs_private structure
+ *  @para  event   the event id
+ *  @return 	   n/a
+ */
+void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
+{
+	char buf[50];
+
+	lbs_deb_enter(LBS_DEB_CMD);
+	memset(buf, 0, sizeof(buf));
+
+	sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
+
+	if (event == MACREG_INT_CODE_MIC_ERR_UNICAST)
+		strcat(buf, "unicast ");
+	else
+		strcat(buf, "multicast ");
+
+	lbs_send_iwevcustom_event(priv, buf);
+	lbs_deb_leave(LBS_DEB_CMD);
+}
 
 /**
  *  @brief Find the channel frequency power info with specific channel
@@ -66,8 +123,6 @@ struct chan_freq_power *lbs_find_cfp_by_
 	for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
 		rc = &priv->region_channel[j];
 
-		if (priv->enable11d)
-			rc = &priv->universal_channel[j];
 		if (!rc->valid || !rc->CFP)
 			continue;
 		if (rc->band != band)
@@ -107,8 +162,6 @@ static struct chan_freq_power *find_cfp_
 	for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
 		rc = &priv->region_channel[j];
 
-		if (priv->enable11d)
-			rc = &priv->universal_channel[j];
 		if (!rc->valid || !rc->CFP)
 			continue;
 		if (rc->band != band)
@@ -169,12 +222,12 @@ static int lbs_get_freq(struct net_devic
 	lbs_deb_enter(LBS_DEB_WEXT);
 
 	cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
-					   priv->curbssparams.channel);
+					   priv->channel);
 
 	if (!cfp) {
-		if (priv->curbssparams.channel)
+		if (priv->channel)
 			lbs_deb_wext("invalid channel %d\n",
-			       priv->curbssparams.channel);
+			       priv->channel);
 		return -EINVAL;
 	}
 
@@ -547,8 +600,6 @@ static int lbs_get_range(struct net_devi
 	struct chan_freq_power *cfp;
 	u8 rates[MAX_RATES + 1];
 
-	u8 flag = 0;
-
 	lbs_deb_enter(LBS_DEB_WEXT);
 
 	dwrq->length = sizeof(struct iw_range);
@@ -570,52 +621,21 @@ static int lbs_get_range(struct net_devi
 
 	range->scan_capa = IW_SCAN_CAPA_ESSID;
 
-	if (priv->enable11d &&
-	    (priv->connect_status == LBS_CONNECTED ||
-	    priv->mesh_connect_status == LBS_CONNECTED)) {
-		u8 chan_no;
-		u8 band;
-
-		struct parsed_region_chan_11d *parsed_region_chan =
-		    &priv->parsed_region_chan;
-
-		if (parsed_region_chan == NULL) {
-			lbs_deb_wext("11d: parsed_region_chan is NULL\n");
-			goto out;
-		}
-		band = parsed_region_chan->band;
-		lbs_deb_wext("band %d, nr_char %d\n", band,
-		       parsed_region_chan->nr_chan);
-
+	for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
+	     && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+		cfp = priv->region_channel[j].CFP;
 		for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
-		     && (i < parsed_region_chan->nr_chan); i++) {
-			chan_no = parsed_region_chan->chanpwr[i].chan;
-			lbs_deb_wext("chan_no %d\n", chan_no);
-			range->freq[range->num_frequency].i = (long)chan_no;
+		     && priv->region_channel[j].valid
+		     && cfp
+		     && (i < priv->region_channel[j].nrcfp); i++) {
+			range->freq[range->num_frequency].i =
+			    (long)cfp->channel;
 			range->freq[range->num_frequency].m =
-			    (long)lbs_chan_2_freq(chan_no) * 100000;
+			    (long)cfp->freq * 100000;
 			range->freq[range->num_frequency].e = 1;
+			cfp++;
 			range->num_frequency++;
 		}
-		flag = 1;
-	}
-	if (!flag) {
-		for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
-		     && (j < ARRAY_SIZE(priv->region_channel)); j++) {
-			cfp = priv->region_channel[j].CFP;
-			for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
-			     && priv->region_channel[j].valid
-			     && cfp
-			     && (i < priv->region_channel[j].nrcfp); i++) {
-				range->freq[range->num_frequency].i =
-				    (long)cfp->channel;
-				range->freq[range->num_frequency].m =
-				    (long)cfp->freq * 100000;
-				range->freq[range->num_frequency].e = 1;
-				cfp++;
-				range->num_frequency++;
-			}
-		}
 	}
 
 	lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n",
@@ -700,7 +720,6 @@ static int lbs_get_range(struct net_devi
 		                  | IW_ENC_CAPA_CIPHER_CCMP;
 	}
 
-out:
 	lbs_deb_leave(LBS_DEB_WEXT);
 	return 0;
 }
@@ -709,6 +728,7 @@ static int lbs_set_power(struct net_devi
 			  struct iw_param *vwrq, char *extra)
 {
 	struct lbs_private *priv = dev->ml_priv;
+	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -737,8 +757,54 @@ static int lbs_set_power(struct net_devi
 		       "setting power timeout is not supported\n");
 		return -EINVAL;
 	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
-		lbs_deb_wext("setting power period not supported\n");
-		return -EINVAL;
+		vwrq->value = vwrq->value / 1000;
+		if (!priv->enter_deep_sleep) {
+			lbs_pr_err("deep sleep feature is not implemented "
+					"for this interface driver\n");
+			return -EINVAL;
+		}
+
+		if (priv->connect_status == LBS_CONNECTED) {
+			if ((priv->is_auto_deep_sleep_enabled) &&
+						(vwrq->value == -1000)) {
+				lbs_exit_auto_deep_sleep(priv);
+				return 0;
+			} else {
+				lbs_pr_err("can't use deep sleep cmd in "
+						"connected state\n");
+				return -EINVAL;
+			}
+		}
+
+		if ((vwrq->value < 0) && (vwrq->value != -1000)) {
+			lbs_pr_err("unknown option\n");
+			return -EINVAL;
+		}
+
+		if (vwrq->value > 0) {
+			if (!priv->is_auto_deep_sleep_enabled) {
+				priv->is_activity_detected = 0;
+				priv->auto_deep_sleep_timeout = vwrq->value;
+				lbs_enter_auto_deep_sleep(priv);
+			} else {
+				priv->auto_deep_sleep_timeout = vwrq->value;
+				lbs_deb_debugfs("auto deep sleep: "
+						"already enabled\n");
+			}
+			return 0;
+		} else {
+			if (priv->is_auto_deep_sleep_enabled) {
+				lbs_exit_auto_deep_sleep(priv);
+				/* Try to exit deep sleep if auto */
+				/*deep sleep disabled */
+				ret = lbs_set_deep_sleep(priv, 0);
+			}
+			if (vwrq->value == 0)
+				ret = lbs_set_deep_sleep(priv, 1);
+			else if (vwrq->value == -1000)
+				ret = lbs_set_deep_sleep(priv, 0);
+			return ret;
+		}
 	}
 
 	if (priv->psmode != LBS802_11POWERMODECAM) {
@@ -752,6 +818,7 @@ static int lbs_set_power(struct net_devi
 	}
 
 	lbs_deb_leave(LBS_DEB_WEXT);
+
 	return 0;
 }
 
@@ -785,7 +852,7 @@ static struct iw_statistics *lbs_get_wir
 	u32 rssi_qual;
 	u32 tx_qual;
 	u32 quality = 0;
-	int stats_valid = 0;
+	int ret, stats_valid = 0;
 	u8 rssi;
 	u32 tx_retries;
 	struct cmd_ds_802_11_get_log log;
@@ -834,7 +901,9 @@ static struct iw_statistics *lbs_get_wir
 
 	memset(&log, 0, sizeof(log));
 	log.hdr.size = cpu_to_le16(sizeof(log));
-	lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log);
+	if (ret)
+		goto out;
 
 	tx_retries = le32_to_cpu(log.retry);
 
@@ -862,8 +931,10 @@ static struct iw_statistics *lbs_get_wir
 	stats_valid = 1;
 
 	/* update stats asynchronously for future calls */
-	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+	ret = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
 					0, 0, NULL);
+	if (ret)
+		lbs_pr_err("RSSI command failed\n");
 out:
 	if (!stats_valid) {
 		priv->wstats.miss.beacon = 0;
@@ -973,7 +1044,7 @@ static int lbs_mesh_set_freq(struct net_
 		goto out;
 	}
 
-	if (fwrq->m != priv->curbssparams.channel) {
+	if (fwrq->m != priv->channel) {
 		lbs_deb_wext("mesh channel change forces eth disconnect\n");
 		if (priv->mode == IW_MODE_INFRA)
 			lbs_cmd_80211_deauthenticate(priv,
@@ -1000,6 +1071,7 @@ static int lbs_set_rate(struct net_devic
 	u8 rates[MAX_RATES + 1];
 
 	lbs_deb_enter(LBS_DEB_WEXT);
+
 	lbs_deb_wext("vwrq->value %d\n", vwrq->value);
 	lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed);
 
@@ -1953,10 +2025,8 @@ static int lbs_get_essid(struct net_devi
 	if (priv->connect_status == LBS_CONNECTED) {
 		memcpy(extra, priv->curbssparams.ssid,
 		       priv->curbssparams.ssid_len);
-		extra[priv->curbssparams.ssid_len] = '\0';
 	} else {
 		memset(extra, 0, 32);
-		extra[priv->curbssparams.ssid_len] = '\0';
 	}
 	/*
 	 * If none, we may want to get the one that was set
@@ -1975,7 +2045,7 @@ static int lbs_set_essid(struct net_devi
 {
 	struct lbs_private *priv = dev->ml_priv;
 	int ret = 0;
-	u8 ssid[IW_ESSID_MAX_SIZE];
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len = 0;
 	struct assoc_request * assoc_req;
 	int in_ssid_len = dwrq->length;
@@ -1989,7 +2059,7 @@ static int lbs_set_essid(struct net_devi
 	}
 
 	/* Check the size of the string */
-	if (in_ssid_len > IW_ESSID_MAX_SIZE) {
+	if (in_ssid_len > IEEE80211_MAX_SSID_LEN) {
 		ret = -E2BIG;
 		goto out;
 	}
@@ -2020,7 +2090,7 @@ out:
 			ret = -ENOMEM;
 		} else {
 			/* Copy the SSID to the association request */
-			memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
+			memcpy(&assoc_req->ssid, &ssid, IEEE80211_MAX_SSID_LEN);
 			assoc_req->ssid_len = ssid_len;
 			set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 			lbs_postpone_association_work(priv);
@@ -2071,7 +2141,7 @@ static int lbs_mesh_set_essid(struct net
 	}
 
 	/* Check the size of the string */
-	if (dwrq->length > IW_ESSID_MAX_SIZE) {
+	if (dwrq->length > IEEE80211_MAX_SSID_LEN) {
 		ret = -E2BIG;
 		goto out;
 	}
@@ -2086,7 +2156,7 @@ static int lbs_mesh_set_essid(struct net
 	}
 
 	lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-			priv->curbssparams.channel);
+			priv->channel);
  out:
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/wext.h linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas/wext.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas/wext.h	2010-02-24 13:52:17.000000000 -0500
@@ -4,7 +4,14 @@
 #ifndef	_LBS_WEXT_H_
 #define	_LBS_WEXT_H_
 
+void lbs_send_disconnect_notification(struct lbs_private *priv);
+void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
+
+struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
+	struct lbs_private *priv,
+	u8 band,
+	u16 channel);
+
 extern struct iw_handler_def lbs_handler_def;
-extern struct iw_handler_def mesh_handler_def;
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas_tf/if_usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/if_usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas_tf/if_usb.c	2013-05-03 14:02:44.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/if_usb.c	2013-05-03 12:10:19.000000000 -0400
@@ -23,6 +23,8 @@
 static char *lbtf_fw_name = "/*(DEBLOBBED)*/";
 module_param_named(fw_name, lbtf_fw_name, charp, 0644);
 
+/*(DEBLOBBED)*/
+
 static struct usb_device_id if_usb_table[] = {
 	/* Enter the device signature inside */
 	{ USB_DEVICE(0x1286, 0x2001) },
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas_tf/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/libertas_tf/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/libertas_tf/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -495,7 +495,6 @@ int lbtf_rx(struct lbtf_private *priv, s
 	stats.band = IEEE80211_BAND_2GHZ;
 	stats.signal = prxpd->snr;
 	stats.noise = prxpd->nf;
-	stats.qual = prxpd->snr - prxpd->nf;
 	/* Marvell rate index has a hole at value 4 */
 	if (prxpd->rx_rate > 4)
 		--prxpd->rx_rate;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/mac80211_hwsim.c linux-libre-2.6.33-gnu1/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/mac80211_hwsim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/mac80211_hwsim.c	2010-02-24 13:52:17.000000000 -0500
@@ -284,7 +284,7 @@ struct mac80211_hwsim_data {
 	struct ieee80211_channel *channel;
 	unsigned long beacon_int; /* in jiffies unit */
 	unsigned int rx_filter;
-	int started;
+	bool started, idle;
 	struct timer_list beacon_timer;
 	enum ps_mode {
 		PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
@@ -365,6 +365,49 @@ static void mac80211_hwsim_monitor_rx(st
 }
 
 
+static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr)
+{
+	struct mac80211_hwsim_data *data = hw->priv;
+	struct sk_buff *skb;
+	struct hwsim_radiotap_hdr *hdr;
+	u16 flags;
+	struct ieee80211_hdr *hdr11;
+
+	if (!netif_running(hwsim_mon))
+		return;
+
+	skb = dev_alloc_skb(100);
+	if (skb == NULL)
+		return;
+
+	hdr = (struct hwsim_radiotap_hdr *) skb_put(skb, sizeof(*hdr));
+	hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+	hdr->hdr.it_pad = 0;
+	hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
+	hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+					  (1 << IEEE80211_RADIOTAP_CHANNEL));
+	hdr->rt_flags = 0;
+	hdr->rt_rate = 0;
+	hdr->rt_channel = cpu_to_le16(data->channel->center_freq);
+	flags = IEEE80211_CHAN_2GHZ;
+	hdr->rt_chbitmask = cpu_to_le16(flags);
+
+	hdr11 = (struct ieee80211_hdr *) skb_put(skb, 10);
+	hdr11->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+					   IEEE80211_STYPE_ACK);
+	hdr11->duration_id = cpu_to_le16(0);
+	memcpy(hdr11->addr1, addr, ETH_ALEN);
+
+	skb->dev = hwsim_mon;
+	skb_set_mac_header(skb, 0);
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = htons(ETH_P_802_2);
+	memset(skb->cb, 0, sizeof(skb->cb));
+	netif_rx(skb);
+}
+
+
 static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
 			   struct sk_buff *skb)
 {
@@ -402,6 +445,12 @@ static bool mac80211_hwsim_tx_frame(stru
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_rx_status rx_status;
 
+	if (data->idle) {
+		printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n",
+		       wiphy_name(hw->wiphy));
+		return false;
+	}
+
 	memset(&rx_status, 0, sizeof(rx_status));
 	/* TODO: set mactime */
 	rx_status.freq = data->channel->center_freq;
@@ -428,7 +477,8 @@ static bool mac80211_hwsim_tx_frame(stru
 		if (data == data2)
 			continue;
 
-		if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
+		if (data2->idle || !data2->started ||
+		    !hwsim_ps_rx_ok(data2, skb) ||
 		    !data->channel || !data2->channel ||
 		    data->channel->center_freq != data2->channel->center_freq ||
 		    !(data->group & data2->group))
@@ -464,6 +514,10 @@ static int mac80211_hwsim_tx(struct ieee
 	}
 
 	ack = mac80211_hwsim_tx_frame(hw, skb);
+	if (ack && skb->len >= 16) {
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+		mac80211_hwsim_monitor_ack(hw, hdr->addr2);
+	}
 
 	txi = IEEE80211_SKB_CB(skb);
 
@@ -571,6 +625,8 @@ static int mac80211_hwsim_config(struct
 	       !!(conf->flags & IEEE80211_CONF_IDLE),
 	       !!(conf->flags & IEEE80211_CONF_PS));
 
+	data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
+
 	data->channel = conf->channel;
 	if (!data->started || !data->beacon_int)
 		del_timer(&data->beacon_timer);
@@ -1045,19 +1101,20 @@ static int __init init_mac80211_hwsim(vo
 				sband->channels = data->channels_2ghz;
 				sband->n_channels =
 					ARRAY_SIZE(hwsim_channels_2ghz);
+				sband->bitrates = data->rates;
+				sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
 				break;
 			case IEEE80211_BAND_5GHZ:
 				sband->channels = data->channels_5ghz;
 				sband->n_channels =
 					ARRAY_SIZE(hwsim_channels_5ghz);
+				sband->bitrates = data->rates + 4;
+				sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
 				break;
 			default:
 				break;
 			}
 
-			sband->bitrates = data->rates;
-			sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
-
 			sband->ht_cap.ht_supported = true;
 			sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
 				IEEE80211_HT_CAP_GRN_FLD |
@@ -1089,46 +1146,46 @@ static int __init init_mac80211_hwsim(vo
 			break;
 		case HWSIM_REGTEST_WORLD_ROAM:
 			if (i == 0) {
-				hw->wiphy->custom_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 				wiphy_apply_custom_regulatory(hw->wiphy,
 					&hwsim_world_regdom_custom_01);
 			}
 			break;
 		case HWSIM_REGTEST_CUSTOM_WORLD:
-			hw->wiphy->custom_regulatory = true;
+			hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 			wiphy_apply_custom_regulatory(hw->wiphy,
 				&hwsim_world_regdom_custom_01);
 			break;
 		case HWSIM_REGTEST_CUSTOM_WORLD_2:
 			if (i == 0) {
-				hw->wiphy->custom_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 				wiphy_apply_custom_regulatory(hw->wiphy,
 					&hwsim_world_regdom_custom_01);
 			} else if (i == 1) {
-				hw->wiphy->custom_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 				wiphy_apply_custom_regulatory(hw->wiphy,
 					&hwsim_world_regdom_custom_02);
 			}
 			break;
 		case HWSIM_REGTEST_STRICT_ALL:
-			hw->wiphy->strict_regulatory = true;
+			hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
 			break;
 		case HWSIM_REGTEST_STRICT_FOLLOW:
 		case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
 			if (i == 0)
-				hw->wiphy->strict_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
 			break;
 		case HWSIM_REGTEST_ALL:
 			if (i == 0) {
-				hw->wiphy->custom_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 				wiphy_apply_custom_regulatory(hw->wiphy,
 					&hwsim_world_regdom_custom_01);
 			} else if (i == 1) {
-				hw->wiphy->custom_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 				wiphy_apply_custom_regulatory(hw->wiphy,
 					&hwsim_world_regdom_custom_02);
 			} else if (i == 4)
-				hw->wiphy->strict_regulatory = true;
+				hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
 			break;
 		default:
 			break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,16 +5,6 @@
 obj-$(CONFIG_IPW2100) += ipw2x00/
 obj-$(CONFIG_IPW2200) += ipw2x00/
 
-obj-$(CONFIG_STRIP) += strip.o
-obj-$(CONFIG_ARLAN) += arlan.o 
-
-arlan-objs := arlan-main.o arlan-proc.o
-
-# Obsolete cards
-obj-$(CONFIG_WAVELAN)		+= wavelan.o
-obj-$(CONFIG_PCMCIA_NETWAVE)	+= netwave_cs.o
-obj-$(CONFIG_PCMCIA_WAVELAN)	+= wavelan_cs.o
-
 obj-$(CONFIG_HERMES)		+= orinoco/
 
 obj-$(CONFIG_AIRO)		+= airo.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/mwl8k.c linux-libre-2.6.33-gnu1/drivers/net/wireless/mwl8k.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/mwl8k.c	2013-05-03 14:02:47.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/mwl8k.c	2013-05-03 12:10:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/pci.h>
@@ -27,18 +28,6 @@
 #define MWL8K_NAME	KBUILD_MODNAME
 #define MWL8K_VERSION	"0.10"
 
-MODULE_DESCRIPTION(MWL8K_DESC);
-MODULE_VERSION(MWL8K_VERSION);
-MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
-MODULE_LICENSE("GPL");
-
-static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
-	{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = 8687, },
-	{ PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = 8687, },
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, mwl8k_table);
-
 /* Register definitions */
 #define MWL8K_HIU_GEN_PTR			0x00000c10
 #define  MWL8K_MODE_STA				 0x0000005a
@@ -88,72 +77,90 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
 				 MWL8K_A2H_INT_RX_READY | \
 				 MWL8K_A2H_INT_TX_DONE)
 
-/* WME stream classes */
-#define WME_AC_BE	0		/* best effort */
-#define WME_AC_BK	1		/* background */
-#define WME_AC_VI	2		/* video */
-#define WME_AC_VO	3		/* voice */
-
 #define MWL8K_RX_QUEUES		1
 #define MWL8K_TX_QUEUES		4
 
+struct rxd_ops {
+	int rxd_size;
+	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
+	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
+	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
+			   __le16 *qos);
+};
+
+struct mwl8k_device_info {
+	char *part_name;
+	char *helper_image;
+	char *fw_image;
+	struct rxd_ops *rxd_ops;
+	u16 modes;
+};
+
 struct mwl8k_rx_queue {
-	int rx_desc_count;
+	int rxd_count;
 
 	/* hw receives here */
-	int rx_head;
+	int head;
 
 	/* refill descs here */
-	int rx_tail;
+	int tail;
 
-	struct mwl8k_rx_desc *rx_desc_area;
-	dma_addr_t rx_desc_dma;
-	struct sk_buff **rx_skb;
+	void *rxd;
+	dma_addr_t rxd_dma;
+	struct {
+		struct sk_buff *skb;
+		DECLARE_PCI_UNMAP_ADDR(dma)
+	} *buf;
 };
 
 struct mwl8k_tx_queue {
 	/* hw transmits here */
-	int tx_head;
+	int head;
 
 	/* sw appends here */
-	int tx_tail;
+	int tail;
 
-	struct ieee80211_tx_queue_stats tx_stats;
-	struct mwl8k_tx_desc *tx_desc_area;
-	dma_addr_t tx_desc_dma;
-	struct sk_buff **tx_skb;
+	struct ieee80211_tx_queue_stats stats;
+	struct mwl8k_tx_desc *txd;
+	dma_addr_t txd_dma;
+	struct sk_buff **skb;
 };
 
 /* Pointers to the firmware data and meta information about it.  */
 struct mwl8k_firmware {
-	/* Microcode */
-	struct firmware *ucode;
-
 	/* Boot helper code */
 	struct firmware *helper;
+
+	/* Microcode */
+	struct firmware *ucode;
 };
 
 struct mwl8k_priv {
+	void __iomem *sram;
 	void __iomem *regs;
 	struct ieee80211_hw *hw;
 
 	struct pci_dev *pdev;
-	u8 name[16];
+
+	struct mwl8k_device_info *device_info;
+	bool ap_fw;
+	struct rxd_ops *rxd_ops;
 
 	/* firmware files and meta data */
 	struct mwl8k_firmware fw;
-	u32 part_num;
 
 	/* firmware access */
 	struct mutex fw_mutex;
 	struct task_struct *fw_mutex_owner;
 	int fw_mutex_depth;
-	struct completion *tx_wait;
 	struct completion *hostcmd_wait;
 
 	/* lock held over TX and TX reap */
 	spinlock_t tx_lock;
 
+	/* TX quiesce completion, protected by fw_mutex and tx_lock */
+	struct completion *tx_wait;
+
 	struct ieee80211_vif *vif;
 
 	struct ieee80211_channel *current_channel;
@@ -178,10 +185,11 @@ struct mwl8k_priv {
 	/* PHY parameters */
 	struct ieee80211_supported_band band;
 	struct ieee80211_channel channels[14];
-	struct ieee80211_rate rates[12];
+	struct ieee80211_rate rates[14];
 
 	bool radio_on;
 	bool radio_short_preamble;
+	bool sniffer_enabled;
 	bool wmm_enabled;
 
 	/* XXX need to convert this to handle multiple interfaces */
@@ -199,9 +207,6 @@ struct mwl8k_priv {
 
 	/* Tasklet to reclaim TX descriptors and buffers after tx */
 	struct tasklet_struct tx_reclaim_task;
-
-	/* Work thread to serialize configuration requests */
-	struct workqueue_struct *config_wq;
 };
 
 /* Per interface specific private data */
@@ -216,15 +221,6 @@ struct mwl8k_vif {
 	u8	bssid[ETH_ALEN];
 	u8	mac_addr[ETH_ALEN];
 
-	/*
-	 * Subset of supported legacy rates.
-	 * Intersection of AP and STA supported rates.
-	 */
-	struct ieee80211_rate legacy_rates[12];
-
-	/* number of supported legacy rates */
-	u8	legacy_nrates;
-
 	 /* Index into station database.Returned by update_sta_db call */
 	u8	peer_id;
 
@@ -252,15 +248,21 @@ static const struct ieee80211_rate mwl8k
 	{ .bitrate = 10, .hw_value = 2, },
 	{ .bitrate = 20, .hw_value = 4, },
 	{ .bitrate = 55, .hw_value = 11, },
+	{ .bitrate = 110, .hw_value = 22, },
+	{ .bitrate = 220, .hw_value = 44, },
 	{ .bitrate = 60, .hw_value = 12, },
 	{ .bitrate = 90, .hw_value = 18, },
-	{ .bitrate = 110, .hw_value = 22, },
 	{ .bitrate = 120, .hw_value = 24, },
 	{ .bitrate = 180, .hw_value = 36, },
 	{ .bitrate = 240, .hw_value = 48, },
 	{ .bitrate = 360, .hw_value = 72, },
 	{ .bitrate = 480, .hw_value = 96, },
 	{ .bitrate = 540, .hw_value = 108, },
+	{ .bitrate = 720, .hw_value = 144, },
+};
+
+static const u8 mwl8k_rateids[12] = {
+	2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108,
 };
 
 /* Set or get info from Firmware */
@@ -270,10 +272,12 @@ static const struct ieee80211_rate mwl8k
 /* Firmware command codes */
 #define MWL8K_CMD_CODE_DNLD		0x0001
 #define MWL8K_CMD_GET_HW_SPEC		0x0003
+#define MWL8K_CMD_SET_HW_SPEC		0x0004
 #define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
 #define MWL8K_CMD_GET_STAT		0x0014
 #define MWL8K_CMD_RADIO_CONTROL		0x001c
 #define MWL8K_CMD_RF_TX_POWER		0x001e
+#define MWL8K_CMD_RF_ANTENNA		0x0020
 #define MWL8K_CMD_SET_PRE_SCAN		0x0107
 #define MWL8K_CMD_SET_POST_SCAN		0x0108
 #define MWL8K_CMD_SET_RF_CHANNEL	0x010a
@@ -287,6 +291,7 @@ static const struct ieee80211_rate mwl8k
 #define MWL8K_CMD_MIMO_CONFIG		0x0125
 #define MWL8K_CMD_USE_FIXED_RATE	0x0126
 #define MWL8K_CMD_ENABLE_SNIFFER	0x0150
+#define MWL8K_CMD_SET_MAC_ADDR		0x0202
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
 #define MWL8K_CMD_UPDATE_STADB		0x1123
 
@@ -299,10 +304,12 @@ static const char *mwl8k_cmd_name(u16 cm
 	switch (cmd & ~0x8000) {
 		MWL8K_CMDNAME(CODE_DNLD);
 		MWL8K_CMDNAME(GET_HW_SPEC);
+		MWL8K_CMDNAME(SET_HW_SPEC);
 		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
 		MWL8K_CMDNAME(GET_STAT);
 		MWL8K_CMDNAME(RADIO_CONTROL);
 		MWL8K_CMDNAME(RF_TX_POWER);
+		MWL8K_CMDNAME(RF_ANTENNA);
 		MWL8K_CMDNAME(SET_PRE_SCAN);
 		MWL8K_CMDNAME(SET_POST_SCAN);
 		MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -316,6 +323,7 @@ static const char *mwl8k_cmd_name(u16 cm
 		MWL8K_CMDNAME(MIMO_CONFIG);
 		MWL8K_CMDNAME(USE_FIXED_RATE);
 		MWL8K_CMDNAME(ENABLE_SNIFFER);
+		MWL8K_CMDNAME(SET_MAC_ADDR);
 		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
 		MWL8K_CMDNAME(UPDATE_STADB);
 	default:
@@ -353,41 +361,35 @@ static void mwl8k_release_firmware(struc
 
 /* Request fw image */
 static int mwl8k_request_fw(struct mwl8k_priv *priv,
-				const char *fname, struct firmware **fw)
+			    const char *fname, struct firmware **fw)
 {
 	/* release current image */
 	if (*fw != NULL)
 		mwl8k_release_fw(fw);
 
 	return reject_firmware((const struct firmware **)fw,
-						fname, &priv->pdev->dev);
+				fname, &priv->pdev->dev);
 }
 
-static int mwl8k_reject_firmware(struct mwl8k_priv *priv, u32 part_num)
+static int mwl8k_reject_firmware(struct mwl8k_priv *priv)
 {
-	u8 filename[64];
+	struct mwl8k_device_info *di = priv->device_info;
 	int rc;
 
-	priv->part_num = part_num;
-
-	snprintf(filename, sizeof(filename),
-		 "/*(DEBLOBBED)*/", priv->part_num);
-
-	rc = mwl8k_request_fw(priv, filename, &priv->fw.helper);
-	if (rc) {
-		printk(KERN_ERR
-			"%s Error requesting helper firmware file %s\n",
-			pci_name(priv->pdev), filename);
-		return rc;
+	if (di->helper_image != NULL) {
+		rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw.helper);
+		if (rc) {
+			printk(KERN_ERR "%s: Error requesting helper "
+			       "firmware file %s\n", pci_name(priv->pdev),
+			       di->helper_image);
+			return rc;
+		}
 	}
 
-	snprintf(filename, sizeof(filename),
-		 "/*(DEBLOBBED)*/", priv->part_num);
-
-	rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
+	rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw.ucode);
 	if (rc) {
-		printk(KERN_ERR "%s Error requesting firmware file %s\n",
-					pci_name(priv->pdev), filename);
+		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
+		       pci_name(priv->pdev), di->fw_image);
 		mwl8k_release_fw(&priv->fw.helper);
 		return rc;
 	}
@@ -395,6 +397,8 @@ static int mwl8k_reject_firmware(struct
 	return 0;
 }
 
+/*(DEBLOBBED)*/
+
 struct mwl8k_cmd_pkt {
 	__le16	code;
 	__le16	length;
@@ -434,6 +438,7 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv
 			break;
 		}
 
+		cond_resched();
 		udelay(1);
 	} while (--loops);
 
@@ -542,43 +547,61 @@ static int mwl8k_feed_fw_image(struct mw
 	return rc;
 }
 
-static int mwl8k_load_firmware(struct mwl8k_priv *priv)
+static int mwl8k_load_firmware(struct ieee80211_hw *hw)
 {
-	int loops, rc;
+	struct mwl8k_priv *priv = hw->priv;
+	struct firmware *fw = priv->fw.ucode;
+	struct mwl8k_device_info *di = priv->device_info;
+	int rc;
+	int loops;
 
-	const u8 *ucode = priv->fw.ucode->data;
-	size_t ucode_len = priv->fw.ucode->size;
-	const u8 *helper = priv->fw.helper->data;
-	size_t helper_len = priv->fw.helper->size;
+	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
+		struct firmware *helper = priv->fw.helper;
 
-	if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) {
-		rc = mwl8k_load_fw_image(priv, helper, helper_len);
+		if (helper == NULL) {
+			printk(KERN_ERR "%s: helper image needed but none "
+			       "given\n", pci_name(priv->pdev));
+			return -EINVAL;
+		}
+
+		rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
 		if (rc) {
 			printk(KERN_ERR "%s: unable to load firmware "
-				"helper image\n", pci_name(priv->pdev));
+			       "helper image\n", pci_name(priv->pdev));
 			return rc;
 		}
-		msleep(1);
+		msleep(5);
 
-		rc = mwl8k_feed_fw_image(priv, ucode, ucode_len);
+		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
 	} else {
-		rc = mwl8k_load_fw_image(priv, ucode, ucode_len);
+		rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
 	}
 
 	if (rc) {
-		printk(KERN_ERR "%s: unable to load firmware data\n",
-			pci_name(priv->pdev));
+		printk(KERN_ERR "%s: unable to load firmware image\n",
+		       pci_name(priv->pdev));
 		return rc;
 	}
 
-	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
-	msleep(1);
+	if (di->modes & BIT(NL80211_IFTYPE_AP))
+		iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
+	else
+		iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
 
-	loops = 200000;
+	loops = 500000;
 	do {
-		if (ioread32(priv->regs + MWL8K_HIU_INT_CODE)
-						== MWL8K_FWSTA_READY)
+		u32 ready_code;
+
+		ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
+		if (ready_code == MWL8K_FWAP_READY) {
+			priv->ap_fw = 1;
+			break;
+		} else if (ready_code == MWL8K_FWSTA_READY) {
+			priv->ap_fw = 0;
 			break;
+		}
+
+		cond_resched();
 		udelay(1);
 	} while (--loops);
 
@@ -605,9 +628,6 @@ struct ewc_ht_info {
 /* Peer Entry flags - used to define the type of the peer node */
 #define MWL8K_PEER_TYPE_ACCESSPOINT	2
 
-#define MWL8K_IEEE_LEGACY_DATA_RATES	12
-#define MWL8K_MCS_BITMAP_SIZE		16
-
 struct peer_capability_info {
 	/* Peer type - AP vs. STA.  */
 	__u8	peer_type;
@@ -624,10 +644,10 @@ struct peer_capability_info {
 	struct ewc_ht_info	ewc_info;
 
 	/* Legacy rate table. Intersection of our rates and peer rates.  */
-	__u8	legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES];
+	__u8	legacy_rates[12];
 
 	/* HT rate table. Intersection of our rates and peer rates.  */
-	__u8	ht_rates[MWL8K_MCS_BITMAP_SIZE];
+	__u8	ht_rates[16];
 	__u8	pad[16];
 
 	/* If set, interoperability mode, no proprietary extensions.  */
@@ -678,69 +698,167 @@ static inline u16 mwl8k_qos_setbit_qlen(
 struct mwl8k_dma_data {
 	__le16 fwlen;
 	struct ieee80211_hdr wh;
+	char data[0];
 } __attribute__((packed));
 
 /* Routines to add/remove DMA header from skb.  */
-static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
+static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
 {
-	struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data;
-	void *dst, *src = &tr->wh;
-	int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
-	u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
+	struct mwl8k_dma_data *tr;
+	int hdrlen;
 
-	dst = (void *)tr + space;
-	if (dst != src) {
-		memmove(dst, src, hdrlen);
-		skb_pull(skb, space);
+	tr = (struct mwl8k_dma_data *)skb->data;
+	hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
+
+	if (hdrlen != sizeof(tr->wh)) {
+		if (ieee80211_is_data_qos(tr->wh.frame_control)) {
+			memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
+			*((__le16 *)(tr->data - 2)) = qos;
+		} else {
+			memmove(tr->data - hdrlen, &tr->wh, hdrlen);
+		}
 	}
+
+	if (hdrlen != sizeof(*tr))
+		skb_pull(skb, sizeof(*tr) - hdrlen);
 }
 
 static inline void mwl8k_add_dma_header(struct sk_buff *skb)
 {
 	struct ieee80211_hdr *wh;
-	u32 hdrlen, pktlen;
+	int hdrlen;
 	struct mwl8k_dma_data *tr;
 
+	/*
+	 * Add a firmware DMA header; the firmware requires that we
+	 * present a 2-byte payload length followed by a 4-address
+	 * header (without QoS field), followed (optionally) by any
+	 * WEP/ExtIV header (but only filled in for CCMP).
+	 */
 	wh = (struct ieee80211_hdr *)skb->data;
+
 	hdrlen = ieee80211_hdrlen(wh->frame_control);
-	pktlen = skb->len;
+	if (hdrlen != sizeof(*tr))
+		skb_push(skb, sizeof(*tr) - hdrlen);
 
-	/*
-	 * Copy up/down the 802.11 header; the firmware requires
-	 * we present a 2-byte payload length followed by a
-	 * 4-address header (w/o QoS), followed (optionally) by
-	 * any WEP/ExtIV header (but only filled in for CCMP).
-	 */
-	if (hdrlen != sizeof(struct mwl8k_dma_data))
-		skb_push(skb, sizeof(struct mwl8k_dma_data) - hdrlen);
+	if (ieee80211_is_data_qos(wh->frame_control))
+		hdrlen -= 2;
 
 	tr = (struct mwl8k_dma_data *)skb->data;
 	if (wh != &tr->wh)
 		memmove(&tr->wh, wh, hdrlen);
-
-	/* Clear addr4 */
-	memset(tr->wh.addr4, 0, ETH_ALEN);
+	if (hdrlen != sizeof(tr->wh))
+		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
 
 	/*
 	 * Firmware length is the length of the fully formed "802.11
 	 * payload".  That is, everything except for the 802.11 header.
 	 * This includes all crypto material including the MIC.
 	 */
-	tr->fwlen = cpu_to_le16(pktlen - hdrlen);
+	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr));
 }
 
 
 /*
- * Packet reception.
+ * Packet reception for 88w8366.
  */
-#define MWL8K_RX_CTRL_OWNED_BY_HOST	0x02
+struct mwl8k_rxd_8366 {
+	__le16 pkt_len;
+	__u8 sq2;
+	__u8 rate;
+	__le32 pkt_phys_addr;
+	__le32 next_rxd_phys_addr;
+	__le16 qos_control;
+	__le16 htsig2;
+	__le32 hw_rssi_info;
+	__le32 hw_noise_floor_info;
+	__u8 noise_floor;
+	__u8 pad0[3];
+	__u8 rssi;
+	__u8 rx_status;
+	__u8 channel;
+	__u8 rx_ctrl;
+} __attribute__((packed));
 
-struct mwl8k_rx_desc {
+#define MWL8K_8366_RATE_INFO_MCS_FORMAT		0x80
+#define MWL8K_8366_RATE_INFO_40MHZ		0x40
+#define MWL8K_8366_RATE_INFO_RATEID(x)		((x) & 0x3f)
+
+#define MWL8K_8366_RX_CTRL_OWNED_BY_HOST	0x80
+
+static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr)
+{
+	struct mwl8k_rxd_8366 *rxd = _rxd;
+
+	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
+	rxd->rx_ctrl = MWL8K_8366_RX_CTRL_OWNED_BY_HOST;
+}
+
+static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len)
+{
+	struct mwl8k_rxd_8366 *rxd = _rxd;
+
+	rxd->pkt_len = cpu_to_le16(len);
+	rxd->pkt_phys_addr = cpu_to_le32(addr);
+	wmb();
+	rxd->rx_ctrl = 0;
+}
+
+static int
+mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status,
+		       __le16 *qos)
+{
+	struct mwl8k_rxd_8366 *rxd = _rxd;
+
+	if (!(rxd->rx_ctrl & MWL8K_8366_RX_CTRL_OWNED_BY_HOST))
+		return -1;
+	rmb();
+
+	memset(status, 0, sizeof(*status));
+
+	status->signal = -rxd->rssi;
+	status->noise = -rxd->noise_floor;
+
+	if (rxd->rate & MWL8K_8366_RATE_INFO_MCS_FORMAT) {
+		status->flag |= RX_FLAG_HT;
+		if (rxd->rate & MWL8K_8366_RATE_INFO_40MHZ)
+			status->flag |= RX_FLAG_40MHZ;
+		status->rate_idx = MWL8K_8366_RATE_INFO_RATEID(rxd->rate);
+	} else {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(mwl8k_rates); i++) {
+			if (mwl8k_rates[i].hw_value == rxd->rate) {
+				status->rate_idx = i;
+				break;
+			}
+		}
+	}
+
+	status->band = IEEE80211_BAND_2GHZ;
+	status->freq = ieee80211_channel_to_frequency(rxd->channel);
+
+	*qos = rxd->qos_control;
+
+	return le16_to_cpu(rxd->pkt_len);
+}
+
+static struct rxd_ops rxd_8366_ops = {
+	.rxd_size	= sizeof(struct mwl8k_rxd_8366),
+	.rxd_init	= mwl8k_rxd_8366_init,
+	.rxd_refill	= mwl8k_rxd_8366_refill,
+	.rxd_process	= mwl8k_rxd_8366_process,
+};
+
+/*
+ * Packet reception for 88w8687.
+ */
+struct mwl8k_rxd_8687 {
 	__le16 pkt_len;
 	__u8 link_quality;
 	__u8 noise_level;
 	__le32 pkt_phys_addr;
-	__le32 next_rx_desc_phys_addr;
+	__le32 next_rxd_phys_addr;
 	__le16 qos_control;
 	__le16 rate_info;
 	__le32 pad0[4];
@@ -752,6 +870,78 @@ struct mwl8k_rx_desc {
 	__u8 pad2[2];
 } __attribute__((packed));
 
+#define MWL8K_8687_RATE_INFO_SHORTPRE		0x8000
+#define MWL8K_8687_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
+#define MWL8K_8687_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
+#define MWL8K_8687_RATE_INFO_40MHZ		0x0004
+#define MWL8K_8687_RATE_INFO_SHORTGI		0x0002
+#define MWL8K_8687_RATE_INFO_MCS_FORMAT		0x0001
+
+#define MWL8K_8687_RX_CTRL_OWNED_BY_HOST	0x02
+
+static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr)
+{
+	struct mwl8k_rxd_8687 *rxd = _rxd;
+
+	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
+	rxd->rx_ctrl = MWL8K_8687_RX_CTRL_OWNED_BY_HOST;
+}
+
+static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len)
+{
+	struct mwl8k_rxd_8687 *rxd = _rxd;
+
+	rxd->pkt_len = cpu_to_le16(len);
+	rxd->pkt_phys_addr = cpu_to_le32(addr);
+	wmb();
+	rxd->rx_ctrl = 0;
+}
+
+static int
+mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status,
+		       __le16 *qos)
+{
+	struct mwl8k_rxd_8687 *rxd = _rxd;
+	u16 rate_info;
+
+	if (!(rxd->rx_ctrl & MWL8K_8687_RX_CTRL_OWNED_BY_HOST))
+		return -1;
+	rmb();
+
+	rate_info = le16_to_cpu(rxd->rate_info);
+
+	memset(status, 0, sizeof(*status));
+
+	status->signal = -rxd->rssi;
+	status->noise = -rxd->noise_level;
+	status->antenna = MWL8K_8687_RATE_INFO_ANTSELECT(rate_info);
+	status->rate_idx = MWL8K_8687_RATE_INFO_RATEID(rate_info);
+
+	if (rate_info & MWL8K_8687_RATE_INFO_SHORTPRE)
+		status->flag |= RX_FLAG_SHORTPRE;
+	if (rate_info & MWL8K_8687_RATE_INFO_40MHZ)
+		status->flag |= RX_FLAG_40MHZ;
+	if (rate_info & MWL8K_8687_RATE_INFO_SHORTGI)
+		status->flag |= RX_FLAG_SHORT_GI;
+	if (rate_info & MWL8K_8687_RATE_INFO_MCS_FORMAT)
+		status->flag |= RX_FLAG_HT;
+
+	status->band = IEEE80211_BAND_2GHZ;
+	status->freq = ieee80211_channel_to_frequency(rxd->channel);
+
+	*qos = rxd->qos_control;
+
+	return le16_to_cpu(rxd->pkt_len);
+}
+
+static struct rxd_ops rxd_8687_ops = {
+	.rxd_size	= sizeof(struct mwl8k_rxd_8687),
+	.rxd_init	= mwl8k_rxd_8687_init,
+	.rxd_refill	= mwl8k_rxd_8687_refill,
+	.rxd_process	= mwl8k_rxd_8687_process,
+};
+
+
 #define MWL8K_RX_DESCS		256
 #define MWL8K_RX_MAXSZ		3800
 
@@ -762,43 +952,44 @@ static int mwl8k_rxq_init(struct ieee802
 	int size;
 	int i;
 
-	rxq->rx_desc_count = 0;
-	rxq->rx_head = 0;
-	rxq->rx_tail = 0;
+	rxq->rxd_count = 0;
+	rxq->head = 0;
+	rxq->tail = 0;
 
-	size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc);
+	size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
 
-	rxq->rx_desc_area =
-		pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma);
-	if (rxq->rx_desc_area == NULL) {
+	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
+	if (rxq->rxd == NULL) {
 		printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
-		       priv->name);
+		       wiphy_name(hw->wiphy));
 		return -ENOMEM;
 	}
-	memset(rxq->rx_desc_area, 0, size);
+	memset(rxq->rxd, 0, size);
 
-	rxq->rx_skb = kmalloc(MWL8K_RX_DESCS *
-				sizeof(*rxq->rx_skb), GFP_KERNEL);
-	if (rxq->rx_skb == NULL) {
+	rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
+	if (rxq->buf == NULL) {
 		printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
-			priv->name);
-		pci_free_consistent(priv->pdev, size,
-				    rxq->rx_desc_area, rxq->rx_desc_dma);
+		       wiphy_name(hw->wiphy));
+		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
 		return -ENOMEM;
 	}
-	memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb));
+	memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf));
 
 	for (i = 0; i < MWL8K_RX_DESCS; i++) {
-		struct mwl8k_rx_desc *rx_desc;
+		int desc_size;
+		void *rxd;
 		int nexti;
+		dma_addr_t next_dma_addr;
 
-		rx_desc = rxq->rx_desc_area + i;
-		nexti = (i + 1) % MWL8K_RX_DESCS;
+		desc_size = priv->rxd_ops->rxd_size;
+		rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
 
-		rx_desc->next_rx_desc_phys_addr =
-			cpu_to_le32(rxq->rx_desc_dma
-						+ nexti * sizeof(*rx_desc));
-		rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST;
+		nexti = i + 1;
+		if (nexti == MWL8K_RX_DESCS)
+			nexti = 0;
+		next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
+
+		priv->rxd_ops->rxd_init(rxd, next_dma_addr);
 	}
 
 	return 0;
@@ -811,27 +1002,28 @@ static int rxq_refill(struct ieee80211_h
 	int refilled;
 
 	refilled = 0;
-	while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) {
+	while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
 		struct sk_buff *skb;
+		dma_addr_t addr;
 		int rx;
+		void *rxd;
 
 		skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
 		if (skb == NULL)
 			break;
 
-		rxq->rx_desc_count++;
-
-		rx = rxq->rx_tail;
-		rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
+		addr = pci_map_single(priv->pdev, skb->data,
+				      MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
 
-		rxq->rx_desc_area[rx].pkt_phys_addr =
-			cpu_to_le32(pci_map_single(priv->pdev, skb->data,
-					MWL8K_RX_MAXSZ, DMA_FROM_DEVICE));
+		rxq->rxd_count++;
+		rx = rxq->tail++;
+		if (rxq->tail == MWL8K_RX_DESCS)
+			rxq->tail = 0;
+		rxq->buf[rx].skb = skb;
+		pci_unmap_addr_set(&rxq->buf[rx], dma, addr);
 
-		rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ);
-		rxq->rx_skb[rx] = skb;
-		wmb();
-		rxq->rx_desc_area[rx].rx_ctrl = 0;
+		rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
+		priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
 
 		refilled++;
 	}
@@ -847,24 +1039,24 @@ static void mwl8k_rxq_deinit(struct ieee
 	int i;
 
 	for (i = 0; i < MWL8K_RX_DESCS; i++) {
-		if (rxq->rx_skb[i] != NULL) {
-			unsigned long addr;
+		if (rxq->buf[i].skb != NULL) {
+			pci_unmap_single(priv->pdev,
+					 pci_unmap_addr(&rxq->buf[i], dma),
+					 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+			pci_unmap_addr_set(&rxq->buf[i], dma, 0);
 
-			addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr);
-			pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ,
-					 PCI_DMA_FROMDEVICE);
-			kfree_skb(rxq->rx_skb[i]);
-			rxq->rx_skb[i] = NULL;
+			kfree_skb(rxq->buf[i].skb);
+			rxq->buf[i].skb = NULL;
 		}
 	}
 
-	kfree(rxq->rx_skb);
-	rxq->rx_skb = NULL;
+	kfree(rxq->buf);
+	rxq->buf = NULL;
 
 	pci_free_consistent(priv->pdev,
-			    MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc),
-			    rxq->rx_desc_area, rxq->rx_desc_dma);
-	rxq->rx_desc_area = NULL;
+			    MWL8K_RX_DESCS * priv->rxd_ops->rxd_size,
+			    rxq->rxd, rxq->rxd_dma);
+	rxq->rxd = NULL;
 }
 
 
@@ -880,9 +1072,11 @@ mwl8k_capture_bssid(struct mwl8k_priv *p
 		!compare_ether_addr(wh->addr3, priv->capture_bssid);
 }
 
-static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
-							struct sk_buff *skb)
+static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
+				     struct sk_buff *skb)
 {
+	struct mwl8k_priv *priv = hw->priv;
+
 	priv->capture_beacon = false;
 	memset(priv->capture_bssid, 0, ETH_ALEN);
 
@@ -893,8 +1087,7 @@ static inline void mwl8k_save_beacon(str
 	 */
 	priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
 	if (priv->beacon_skb != NULL)
-		queue_work(priv->config_wq,
-				&priv->finalize_join_worker);
+		ieee80211_queue_work(hw, &priv->finalize_join_worker);
 }
 
 static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
@@ -904,53 +1097,47 @@ static int rxq_process(struct ieee80211_
 	int processed;
 
 	processed = 0;
-	while (rxq->rx_desc_count && limit--) {
-		struct mwl8k_rx_desc *rx_desc;
+	while (rxq->rxd_count && limit--) {
 		struct sk_buff *skb;
+		void *rxd;
+		int pkt_len;
 		struct ieee80211_rx_status status;
-		unsigned long addr;
-		struct ieee80211_hdr *wh;
+		__le16 qos;
 
-		rx_desc = rxq->rx_desc_area + rxq->rx_head;
-		if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST))
+		skb = rxq->buf[rxq->head].skb;
+		if (skb == NULL)
 			break;
-		rmb();
 
-		skb = rxq->rx_skb[rxq->rx_head];
-		if (skb == NULL)
+		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
+
+		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos);
+		if (pkt_len < 0)
 			break;
-		rxq->rx_skb[rxq->rx_head] = NULL;
 
-		rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
-		rxq->rx_desc_count--;
+		rxq->buf[rxq->head].skb = NULL;
 
-		addr = le32_to_cpu(rx_desc->pkt_phys_addr);
-		pci_unmap_single(priv->pdev, addr,
-					MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+		pci_unmap_single(priv->pdev,
+				 pci_unmap_addr(&rxq->buf[rxq->head], dma),
+				 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+		pci_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
 
-		skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
-		mwl8k_remove_dma_header(skb);
+		rxq->head++;
+		if (rxq->head == MWL8K_RX_DESCS)
+			rxq->head = 0;
 
-		wh = (struct ieee80211_hdr *)skb->data;
+		rxq->rxd_count--;
+
+		skb_put(skb, pkt_len);
+		mwl8k_remove_dma_header(skb, qos);
 
 		/*
-		 * Check for pending join operation. save a copy of
-		 * the beacon and schedule a tasklet to send finalize
-		 * join command to the firmware.
+		 * Check for a pending join operation.  Save a
+		 * copy of the beacon and schedule a tasklet to
+		 * send a FINALIZE_JOIN command to the firmware.
 		 */
-		if (mwl8k_capture_bssid(priv, wh))
-			mwl8k_save_beacon(priv, skb);
+		if (mwl8k_capture_bssid(priv, (void *)skb->data))
+			mwl8k_save_beacon(hw, skb);
 
-		memset(&status, 0, sizeof(status));
-		status.mactime = 0;
-		status.signal = -rx_desc->rssi;
-		status.noise = -rx_desc->noise_level;
-		status.qual = rx_desc->link_quality;
-		status.antenna = 1;
-		status.rate_idx = 1;
-		status.flag = 0;
-		status.band = IEEE80211_BAND_2GHZ;
-		status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
 		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 		ieee80211_rx_irqsafe(hw, skb);
 
@@ -965,24 +1152,10 @@ static int rxq_process(struct ieee80211_
  * Packet transmission.
  */
 
-/* Transmit queue assignment.  */
-enum {
-	MWL8K_WME_AC_BK	= 0,		/* background access */
-	MWL8K_WME_AC_BE	= 1,		/* best effort access */
-	MWL8K_WME_AC_VI	= 2,		/* video access */
-	MWL8K_WME_AC_VO	= 3,		/* voice access */
-};
-
 /* Transmit packet ACK policy */
 #define MWL8K_TXD_ACK_POLICY_NORMAL		0
 #define MWL8K_TXD_ACK_POLICY_BLOCKACK		3
 
-#define GET_TXQ(_ac) (\
-		((_ac) == WME_AC_VO) ? MWL8K_WME_AC_VO : \
-		((_ac) == WME_AC_VI) ? MWL8K_WME_AC_VI : \
-		((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
-		MWL8K_WME_AC_BE)
-
 #define MWL8K_TXD_STATUS_OK			0x00000001
 #define MWL8K_TXD_STATUS_OK_RETRY		0x00000002
 #define MWL8K_TXD_STATUS_OK_MORE_RETRY		0x00000004
@@ -997,7 +1170,7 @@ struct mwl8k_tx_desc {
 	__le32 pkt_phys_addr;
 	__le16 pkt_len;
 	__u8 dest_MAC_addr[ETH_ALEN];
-	__le32 next_tx_desc_phys_addr;
+	__le32 next_txd_phys_addr;
 	__le32 reserved;
 	__le16 rate_info;
 	__u8 peer_id;
@@ -1013,44 +1186,40 @@ static int mwl8k_txq_init(struct ieee802
 	int size;
 	int i;
 
-	memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats));
-	txq->tx_stats.limit = MWL8K_TX_DESCS;
-	txq->tx_head = 0;
-	txq->tx_tail = 0;
+	memset(&txq->stats, 0, sizeof(struct ieee80211_tx_queue_stats));
+	txq->stats.limit = MWL8K_TX_DESCS;
+	txq->head = 0;
+	txq->tail = 0;
 
 	size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
 
-	txq->tx_desc_area =
-		pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma);
-	if (txq->tx_desc_area == NULL) {
+	txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
+	if (txq->txd == NULL) {
 		printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
-		       priv->name);
+		       wiphy_name(hw->wiphy));
 		return -ENOMEM;
 	}
-	memset(txq->tx_desc_area, 0, size);
+	memset(txq->txd, 0, size);
 
-	txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb),
-								GFP_KERNEL);
-	if (txq->tx_skb == NULL) {
+	txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
+	if (txq->skb == NULL) {
 		printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
-		       priv->name);
-		pci_free_consistent(priv->pdev, size,
-				    txq->tx_desc_area, txq->tx_desc_dma);
+		       wiphy_name(hw->wiphy));
+		pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
 		return -ENOMEM;
 	}
-	memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb));
+	memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb));
 
 	for (i = 0; i < MWL8K_TX_DESCS; i++) {
 		struct mwl8k_tx_desc *tx_desc;
 		int nexti;
 
-		tx_desc = txq->tx_desc_area + i;
+		tx_desc = txq->txd + i;
 		nexti = (i + 1) % MWL8K_TX_DESCS;
 
 		tx_desc->status = 0;
-		tx_desc->next_tx_desc_phys_addr =
-			cpu_to_le32(txq->tx_desc_dma +
-						nexti * sizeof(*tx_desc));
+		tx_desc->next_txd_phys_addr =
+			cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc));
 	}
 
 	return 0;
@@ -1065,109 +1234,106 @@ static inline void mwl8k_tx_start(struct
 	ioread32(priv->regs + MWL8K_HIU_INT_CODE);
 }
 
-static inline int mwl8k_txq_busy(struct mwl8k_priv *priv)
-{
-	return priv->pending_tx_pkts;
-}
-
-struct mwl8k_txq_info {
-	u32 fw_owned;
-	u32 drv_owned;
-	u32 unused;
-	u32 len;
-	u32 head;
-	u32 tail;
-};
-
-static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
-				struct mwl8k_txq_info *txinfo)
+static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
 {
-	int count, desc, status;
-	struct mwl8k_tx_queue *txq;
-	struct mwl8k_tx_desc *tx_desc;
-	int ndescs = 0;
+	struct mwl8k_priv *priv = hw->priv;
+	int i;
 
-	memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info));
+	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+		struct mwl8k_tx_queue *txq = priv->txq + i;
+		int fw_owned = 0;
+		int drv_owned = 0;
+		int unused = 0;
+		int desc;
 
-	spin_lock_bh(&priv->tx_lock);
-	for (count = 0; count < MWL8K_TX_QUEUES; count++) {
-		txq = priv->txq + count;
-		txinfo[count].len = txq->tx_stats.len;
-		txinfo[count].head = txq->tx_head;
-		txinfo[count].tail = txq->tx_tail;
 		for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
-			tx_desc = txq->tx_desc_area + desc;
-			status = le32_to_cpu(tx_desc->status);
+			struct mwl8k_tx_desc *tx_desc = txq->txd + desc;
+			u32 status;
 
+			status = le32_to_cpu(tx_desc->status);
 			if (status & MWL8K_TXD_STATUS_FW_OWNED)
-				txinfo[count].fw_owned++;
+				fw_owned++;
 			else
-				txinfo[count].drv_owned++;
+				drv_owned++;
 
 			if (tx_desc->pkt_len == 0)
-				txinfo[count].unused++;
+				unused++;
 		}
-	}
-	spin_unlock_bh(&priv->tx_lock);
 
-	return ndescs;
+		printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
+		       "fw_owned=%d drv_owned=%d unused=%d\n",
+		       wiphy_name(hw->wiphy), i,
+		       txq->stats.len, txq->head, txq->tail,
+		       fw_owned, drv_owned, unused);
+	}
 }
 
 /*
- * Must be called with hw->fw_mutex held and tx queues stopped.
+ * Must be called with priv->fw_mutex held and tx queues stopped.
  */
+#define MWL8K_TX_WAIT_TIMEOUT_MS	1000
+
 static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	DECLARE_COMPLETION_ONSTACK(cmd_wait);
-	u32 count;
-	unsigned long timeout;
+	DECLARE_COMPLETION_ONSTACK(tx_wait);
+	int retry;
+	int rc;
 
 	might_sleep();
 
-	spin_lock_bh(&priv->tx_lock);
-	count = mwl8k_txq_busy(priv);
-	if (count) {
-		priv->tx_wait = &cmd_wait;
-		if (priv->radio_on)
-			mwl8k_tx_start(priv);
-	}
-	spin_unlock_bh(&priv->tx_lock);
+	/*
+	 * The TX queues are stopped at this point, so this test
+	 * doesn't need to take ->tx_lock.
+	 */
+	if (!priv->pending_tx_pkts)
+		return 0;
 
-	if (count) {
-		struct mwl8k_txq_info txinfo[MWL8K_TX_QUEUES];
-		int index;
-		int newcount;
+	retry = 0;
+	rc = 0;
 
-		timeout = wait_for_completion_timeout(&cmd_wait,
-					msecs_to_jiffies(5000));
-		if (timeout)
-			return 0;
+	spin_lock_bh(&priv->tx_lock);
+	priv->tx_wait = &tx_wait;
+	while (!rc) {
+		int oldcount;
+		unsigned long timeout;
+
+		oldcount = priv->pending_tx_pkts;
 
-		spin_lock_bh(&priv->tx_lock);
-		priv->tx_wait = NULL;
-		newcount = mwl8k_txq_busy(priv);
 		spin_unlock_bh(&priv->tx_lock);
+		timeout = wait_for_completion_timeout(&tx_wait,
+			    msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
+		spin_lock_bh(&priv->tx_lock);
 
-		printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n",
-		       __func__, __LINE__, count, newcount);
+		if (timeout) {
+			WARN_ON(priv->pending_tx_pkts);
+			if (retry) {
+				printk(KERN_NOTICE "%s: tx rings drained\n",
+				       wiphy_name(hw->wiphy));
+			}
+			break;
+		}
 
-		mwl8k_scan_tx_ring(priv, txinfo);
-		for (index = 0; index < MWL8K_TX_QUEUES; index++)
-			printk(KERN_ERR
-				"TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
-					index,
-					txinfo[index].len,
-					txinfo[index].head,
-					txinfo[index].tail,
-					txinfo[index].fw_owned,
-					txinfo[index].drv_owned,
-					txinfo[index].unused);
+		if (priv->pending_tx_pkts < oldcount) {
+			printk(KERN_NOTICE "%s: timeout waiting for tx "
+			       "rings to drain (%d -> %d pkts), retrying\n",
+			       wiphy_name(hw->wiphy), oldcount,
+			       priv->pending_tx_pkts);
+			retry = 1;
+			continue;
+		}
 
-		return -ETIMEDOUT;
+		priv->tx_wait = NULL;
+
+		printk(KERN_ERR "%s: tx rings stuck for %d ms\n",
+		       wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS);
+		mwl8k_dump_tx_rings(hw);
+
+		rc = -ETIMEDOUT;
 	}
+	spin_unlock_bh(&priv->tx_lock);
 
-	return 0;
+	return rc;
 }
 
 #define MWL8K_TXD_SUCCESS(status)				\
@@ -1181,7 +1347,7 @@ static void mwl8k_txq_reclaim(struct iee
 	struct mwl8k_tx_queue *txq = priv->txq + index;
 	int wake = 0;
 
-	while (txq->tx_stats.len > 0) {
+	while (txq->stats.len > 0) {
 		int tx;
 		struct mwl8k_tx_desc *tx_desc;
 		unsigned long addr;
@@ -1190,8 +1356,8 @@ static void mwl8k_txq_reclaim(struct iee
 		struct ieee80211_tx_info *info;
 		u32 status;
 
-		tx = txq->tx_head;
-		tx_desc = txq->tx_desc_area + tx;
+		tx = txq->head;
+		tx_desc = txq->txd + tx;
 
 		status = le32_to_cpu(tx_desc->status);
 
@@ -1202,20 +1368,20 @@ static void mwl8k_txq_reclaim(struct iee
 				~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
 		}
 
-		txq->tx_head = (tx + 1) % MWL8K_TX_DESCS;
-		BUG_ON(txq->tx_stats.len == 0);
-		txq->tx_stats.len--;
+		txq->head = (tx + 1) % MWL8K_TX_DESCS;
+		BUG_ON(txq->stats.len == 0);
+		txq->stats.len--;
 		priv->pending_tx_pkts--;
 
 		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
 		size = le16_to_cpu(tx_desc->pkt_len);
-		skb = txq->tx_skb[tx];
-		txq->tx_skb[tx] = NULL;
+		skb = txq->skb[tx];
+		txq->skb[tx] = NULL;
 
 		BUG_ON(skb == NULL);
 		pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
 
-		mwl8k_remove_dma_header(skb);
+		mwl8k_remove_dma_header(skb, tx_desc->qos_control);
 
 		/* Mark descriptor as unused */
 		tx_desc->pkt_phys_addr = 0;
@@ -1243,13 +1409,13 @@ static void mwl8k_txq_deinit(struct ieee
 
 	mwl8k_txq_reclaim(hw, index, 1);
 
-	kfree(txq->tx_skb);
-	txq->tx_skb = NULL;
+	kfree(txq->skb);
+	txq->skb = NULL;
 
 	pci_free_consistent(priv->pdev,
 			    MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
-			    txq->tx_desc_area, txq->tx_desc_dma);
-	txq->tx_desc_area = NULL;
+			    txq->txd, txq->txd_dma);
+	txq->txd = NULL;
 }
 
 static int
@@ -1317,7 +1483,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 
 	if (pci_dma_mapping_error(priv->pdev, dma)) {
 		printk(KERN_DEBUG "%s: failed to dma map skb, "
-			"dropping TX frame.\n", priv->name);
+		       "dropping TX frame.\n", wiphy_name(hw->wiphy));
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -1326,10 +1492,10 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 
 	txq = priv->txq + index;
 
-	BUG_ON(txq->tx_skb[txq->tx_tail] != NULL);
-	txq->tx_skb[txq->tx_tail] = skb;
+	BUG_ON(txq->skb[txq->tail] != NULL);
+	txq->skb[txq->tail] = skb;
 
-	tx = txq->tx_desc_area + txq->tx_tail;
+	tx = txq->txd + txq->tail;
 	tx->data_rate = txdatarate;
 	tx->tx_priority = index;
 	tx->qos_control = cpu_to_le16(qos);
@@ -1340,15 +1506,15 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 	wmb();
 	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
 
-	txq->tx_stats.count++;
-	txq->tx_stats.len++;
+	txq->stats.count++;
+	txq->stats.len++;
 	priv->pending_tx_pkts++;
 
-	txq->tx_tail++;
-	if (txq->tx_tail == MWL8K_TX_DESCS)
-		txq->tx_tail = 0;
+	txq->tail++;
+	if (txq->tail == MWL8K_TX_DESCS)
+		txq->tail = 0;
 
-	if (txq->tx_head == txq->tx_tail)
+	if (txq->head == txq->tail)
 		ieee80211_stop_queue(hw, index);
 
 	mwl8k_tx_start(priv);
@@ -1417,8 +1583,8 @@ static void mwl8k_fw_unlock(struct ieee8
  * Command processing.
  */
 
-/* Timeout firmware commands after 2000ms */
-#define MWL8K_CMD_TIMEOUT_MS	2000
+/* Timeout firmware commands after 10s */
+#define MWL8K_CMD_TIMEOUT_MS	10000
 
 static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
 {
@@ -1431,7 +1597,7 @@ static int mwl8k_post_cmd(struct ieee802
 	unsigned long timeout = 0;
 	u8 buf[32];
 
-	cmd->result = 0xFFFF;
+	cmd->result = 0xffff;
 	dma_size = le16_to_cpu(cmd->length);
 	dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
 				  PCI_DMA_BIDIRECTIONAL);
@@ -1464,26 +1630,35 @@ static int mwl8k_post_cmd(struct ieee802
 
 	if (!timeout) {
 		printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
-		       priv->name,
+		       wiphy_name(hw->wiphy),
 		       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
 		       MWL8K_CMD_TIMEOUT_MS);
 		rc = -ETIMEDOUT;
 	} else {
+		int ms;
+
+		ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout);
+
 		rc = cmd->result ? -EINVAL : 0;
 		if (rc)
 			printk(KERN_ERR "%s: Command %s error 0x%x\n",
-			       priv->name,
+			       wiphy_name(hw->wiphy),
 			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
 			       le16_to_cpu(cmd->result));
+		else if (ms > 2000)
+			printk(KERN_NOTICE "%s: Command %s took %d ms\n",
+			       wiphy_name(hw->wiphy),
+			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+			       ms);
 	}
 
 	return rc;
 }
 
 /*
- * GET_HW_SPEC.
+ * CMD_GET_HW_SPEC (STA version).
  */
-struct mwl8k_cmd_get_hw_spec {
+struct mwl8k_cmd_get_hw_spec_sta {
 	struct mwl8k_cmd_pkt header;
 	__u8 hw_rev;
 	__u8 host_interface;
@@ -1499,13 +1674,13 @@ struct mwl8k_cmd_get_hw_spec {
 	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
 	__le32 caps2;
 	__le32 num_tx_desc_per_queue;
-	__le32 total_rx_desc;
+	__le32 total_rxd;
 } __attribute__((packed));
 
-static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
+static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_cmd_get_hw_spec *cmd;
+	struct mwl8k_cmd_get_hw_spec_sta *cmd;
 	int rc;
 	int i;
 
@@ -1518,20 +1693,91 @@ static int mwl8k_cmd_get_hw_spec(struct
 
 	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
 	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
-	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
+	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
 	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
-		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma);
+		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
 	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
-	cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS);
+	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+
+	if (!rc) {
+		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
+		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
+		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
+		priv->hw_rev = cmd->hw_rev;
+	}
+
+	kfree(cmd);
+	return rc;
+}
+
+/*
+ * CMD_GET_HW_SPEC (AP version).
+ */
+struct mwl8k_cmd_get_hw_spec_ap {
+	struct mwl8k_cmd_pkt header;
+	__u8 hw_rev;
+	__u8 host_interface;
+	__le16 num_wcb;
+	__le16 num_mcaddrs;
+	__u8 perm_addr[ETH_ALEN];
+	__le16 region_code;
+	__le16 num_antenna;
+	__le32 fw_rev;
+	__le32 wcbbase0;
+	__le32 rxwrptr;
+	__le32 rxrdptr;
+	__le32 ps_cookie;
+	__le32 wcbbase1;
+	__le32 wcbbase2;
+	__le32 wcbbase3;
+} __attribute__((packed));
+
+static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_get_hw_spec_ap *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
+	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 
 	if (!rc) {
+		int off;
+
 		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
 		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
 		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
 		priv->hw_rev = cmd->hw_rev;
+
+		off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
+		iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
+
+		off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
+		iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
+
+		off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
+		iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
+
+		off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
+		iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off);
+
+		off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
+		iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off);
+
+		off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
+		iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off);
 	}
 
 	kfree(cmd);
@@ -1539,6 +1785,58 @@ static int mwl8k_cmd_get_hw_spec(struct
 }
 
 /*
+ * CMD_SET_HW_SPEC.
+ */
+struct mwl8k_cmd_set_hw_spec {
+	struct mwl8k_cmd_pkt header;
+	__u8 hw_rev;
+	__u8 host_interface;
+	__le16 num_mcaddrs;
+	__u8 perm_addr[ETH_ALEN];
+	__le16 region_code;
+	__le32 fw_rev;
+	__le32 ps_cookie;
+	__le32 caps;
+	__le32 rx_queue_ptr;
+	__le32 num_tx_queues;
+	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+	__le32 flags;
+	__le32 num_tx_desc_per_queue;
+	__le32 total_rxd;
+} __attribute__((packed));
+
+#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT	0x00000080
+
+static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_set_hw_spec *cmd;
+	int rc;
+	int i;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
+	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
+	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
+	cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT);
+	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
+	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
  * CMD_MAC_MULTICAST_ADR.
  */
 struct mwl8k_cmd_mac_multicast_adr {
@@ -1548,19 +1846,23 @@ struct mwl8k_cmd_mac_multicast_adr {
 	__u8 addr[0][ETH_ALEN];
 };
 
-#define MWL8K_ENABLE_RX_MULTICAST 0x000F
+#define MWL8K_ENABLE_RX_DIRECTED	0x0001
+#define MWL8K_ENABLE_RX_MULTICAST	0x0002
+#define MWL8K_ENABLE_RX_ALL_MULTICAST	0x0004
+#define MWL8K_ENABLE_RX_BROADCAST	0x0008
 
 static struct mwl8k_cmd_pkt *
-__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
 			      int mc_count, struct dev_addr_list *mclist)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_mac_multicast_adr *cmd;
 	int size;
-	int i;
 
-	if (mc_count > priv->num_mcaddrs)
-		mc_count = priv->num_mcaddrs;
+	if (allmulti || mc_count > priv->num_mcaddrs) {
+		allmulti = 1;
+		mc_count = 0;
+	}
 
 	size = sizeof(*cmd) + mc_count * ETH_ALEN;
 
@@ -1570,16 +1872,24 @@ __mwl8k_cmd_mac_multicast_adr(struct iee
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
 	cmd->header.length = cpu_to_le16(size);
-	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
-	cmd->numaddr = cpu_to_le16(mc_count);
+	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED |
+				  MWL8K_ENABLE_RX_BROADCAST);
 
-	for (i = 0; i < mc_count && mclist; i++) {
-		if (mclist->da_addrlen != ETH_ALEN) {
-			kfree(cmd);
-			return NULL;
+	if (allmulti) {
+		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
+	} else if (mc_count) {
+		int i;
+
+		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
+		cmd->numaddr = cpu_to_le16(mc_count);
+		for (i = 0; i < mc_count && mclist; i++) {
+			if (mclist->da_addrlen != ETH_ALEN) {
+				kfree(cmd);
+				return NULL;
+			}
+			memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
+			mclist = mclist->next;
 		}
-		memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
-		mclist = mclist->next;
 	}
 
 	return &cmd->header;
@@ -1590,7 +1900,6 @@ __mwl8k_cmd_mac_multicast_adr(struct iee
  */
 struct mwl8k_cmd_802_11_get_stat {
 	struct mwl8k_cmd_pkt header;
-	__le16 action;
 	__le32 stats[64];
 } __attribute__((packed));
 
@@ -1611,7 +1920,6 @@ static int mwl8k_cmd_802_11_get_stat(str
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = cpu_to_le16(MWL8K_CMD_GET);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	if (!rc) {
@@ -1727,6 +2035,39 @@ static int mwl8k_cmd_802_11_rf_tx_power(
 }
 
 /*
+ * CMD_RF_ANTENNA.
+ */
+struct mwl8k_cmd_rf_antenna {
+	struct mwl8k_cmd_pkt header;
+	__le16 antenna;
+	__le16 mode;
+} __attribute__((packed));
+
+#define MWL8K_RF_ANTENNA_RX		1
+#define MWL8K_RF_ANTENNA_TX		2
+
+static int
+mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
+{
+	struct mwl8k_cmd_rf_antenna *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->antenna = cpu_to_le16(antenna);
+	cmd->mode = cpu_to_le16(mask);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
  * CMD_SET_PRE_SCAN.
  */
 struct mwl8k_cmd_set_pre_scan {
@@ -1904,6 +2245,46 @@ static int mwl8k_enable_sniffer(struct i
 }
 
 /*
+ * CMD_SET_MAC_ADDR.
+ */
+struct mwl8k_cmd_set_mac_addr {
+	struct mwl8k_cmd_pkt header;
+	union {
+		struct {
+			__le16 mac_type;
+			__u8 mac_addr[ETH_ALEN];
+		} mbss;
+		__u8 mac_addr[ETH_ALEN];
+	};
+} __attribute__((packed));
+
+static int mwl8k_set_mac_addr(struct ieee80211_hw *hw, u8 *mac)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_set_mac_addr *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	if (priv->ap_fw) {
+		cmd->mbss.mac_type = 0;
+		memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
+	} else {
+		memcpy(cmd->mac_addr, mac, ETH_ALEN);
+	}
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+
+/*
  * CMD_SET_RATEADAPT_MODE.
  */
 struct mwl8k_cmd_set_rate_adapt_mode {
@@ -2005,17 +2386,34 @@ struct mwl8k_cmd_set_edca_params {
 	/* TX opportunity in units of 32 us */
 	__le16 txop;
 
-	/* Log exponent of max contention period: 0...15*/
-	__u8 log_cw_max;
+	union {
+		struct {
+			/* Log exponent of max contention period: 0...15 */
+			__le32 log_cw_max;
 
-	/* Log exponent of min contention period: 0...15 */
-	__u8 log_cw_min;
+			/* Log exponent of min contention period: 0...15 */
+			__le32 log_cw_min;
 
-	/* Adaptive interframe spacing in units of 32us */
-	__u8 aifs;
+			/* Adaptive interframe spacing in units of 32us */
+			__u8 aifs;
 
-	/* TX queue to configure */
-	__u8 txq;
+			/* TX queue to configure */
+			__u8 txq;
+		} ap;
+		struct {
+			/* Log exponent of max contention period: 0...15 */
+			__u8 log_cw_max;
+
+			/* Log exponent of min contention period: 0...15 */
+			__u8 log_cw_min;
+
+			/* Adaptive interframe spacing in units of 32us */
+			__u8 aifs;
+
+			/* TX queue to configure */
+			__u8 txq;
+		} sta;
+	};
 } __attribute__((packed));
 
 #define MWL8K_SET_EDCA_CW	0x01
@@ -2031,6 +2429,7 @@ mwl8k_set_edca_params(struct ieee80211_h
 		__u16 cw_min, __u16 cw_max,
 		__u8 aifs, __u16 txop)
 {
+	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_set_edca_params *cmd;
 	int rc;
 
@@ -2038,14 +2437,27 @@ mwl8k_set_edca_params(struct ieee80211_h
 	if (cmd == NULL)
 		return -ENOMEM;
 
+	/*
+	 * Queues 0 (BE) and 1 (BK) are swapped in hardware for
+	 * this call.
+	 */
+	qnum ^= !(qnum >> 1);
+
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
 	cmd->txop = cpu_to_le16(txop);
-	cmd->log_cw_max = (u8)ilog2(cw_max + 1);
-	cmd->log_cw_min = (u8)ilog2(cw_min + 1);
-	cmd->aifs = aifs;
-	cmd->txq = qnum;
+	if (priv->ap_fw) {
+		cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1));
+		cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1));
+		cmd->ap.aifs = aifs;
+		cmd->ap.txq = qnum;
+	} else {
+		cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1);
+		cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1);
+		cmd->sta.aifs = aifs;
+		cmd->sta.txq = qnum;
+	}
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2056,8 +2468,6 @@ mwl8k_set_edca_params(struct ieee80211_h
 /*
  * CMD_FINALIZE_JOIN.
  */
-
-/* FJ beacon buffer size is compiled into the firmware.  */
 #define MWL8K_FJ_BEACON_MAXLEN	128
 
 struct mwl8k_cmd_finalize_join {
@@ -2067,17 +2477,13 @@ struct mwl8k_cmd_finalize_join {
 } __attribute__((packed));
 
 static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
-				__u16 framelen, __u16 dtim)
+			       int framelen, int dtim)
 {
 	struct mwl8k_cmd_finalize_join *cmd;
 	struct ieee80211_mgmt *payload = frame;
-	u16 hdrlen;
-	u32 payload_len;
+	int payload_len;
 	int rc;
 
-	if (frame == NULL)
-		return -EINVAL;
-
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
@@ -2086,24 +2492,17 @@ static int mwl8k_finalize_join(struct ie
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
 
-	hdrlen = ieee80211_hdrlen(payload->frame_control);
-
-	payload_len = framelen > hdrlen ? framelen - hdrlen : 0;
-
-	/* XXX TBD Might just have to abort and return an error */
-	if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
-		printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
-			"sent to firmware. Sz=%u MAX=%u\n", __func__,
-			payload_len, MWL8K_FJ_BEACON_MAXLEN);
-
-	if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
+	payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
+	if (payload_len < 0)
+		payload_len = 0;
+	else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
 		payload_len = MWL8K_FJ_BEACON_MAXLEN;
 
-	if (payload && payload_len)
-		memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
+	memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
+
 	return rc;
 }
 
@@ -2132,9 +2531,7 @@ static int mwl8k_cmd_update_sta_db(struc
 	struct ieee80211_bss_conf *info = &mv_vif->bss_info;
 	struct mwl8k_cmd_update_sta_db *cmd;
 	struct peer_capability_info *peer_info;
-	struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
 	int rc;
-	__u8 count, *rates;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
@@ -2153,13 +2550,11 @@ static int mwl8k_cmd_update_sta_db(struc
 		/* Build peer_info block */
 		peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
 		peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
+		memcpy(peer_info->legacy_rates, mwl8k_rateids,
+		       sizeof(mwl8k_rateids));
 		peer_info->interop = 1;
 		peer_info->amsdu_enabled = 0;
 
-		rates = peer_info->legacy_rates;
-		for (count = 0; count < mv_vif->legacy_nrates; count++)
-			rates[count] = bitrates[count].hw_value;
-
 		rc = mwl8k_post_cmd(hw, &cmd->header);
 		if (rc == 0)
 			mv_vif->peer_id = peer_info->station_id;
@@ -2182,8 +2577,6 @@ static int mwl8k_cmd_update_sta_db(struc
 /*
  * CMD_SET_AID.
  */
-#define MWL8K_RATE_INDEX_MAX_ARRAY			14
-
 #define MWL8K_FRAME_PROT_DISABLED			0x00
 #define MWL8K_FRAME_PROT_11G				0x07
 #define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY		0x02
@@ -2196,7 +2589,7 @@ struct mwl8k_cmd_update_set_aid {
 	 /* AP's MAC address (BSSID) */
 	__u8	bssid[ETH_ALEN];
 	__le16	protection_mode;
-	__u8	supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+	__u8	supp_rates[14];
 } __attribute__((packed));
 
 static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
@@ -2205,8 +2598,6 @@ static int mwl8k_cmd_set_aid(struct ieee
 	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
 	struct ieee80211_bss_conf *info = &mv_vif->bss_info;
 	struct mwl8k_cmd_update_set_aid *cmd;
-	struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
-	int count;
 	u16 prot_mode;
 	int rc;
 
@@ -2238,8 +2629,7 @@ static int mwl8k_cmd_set_aid(struct ieee
 	}
 	cmd->protection_mode = cpu_to_le16(prot_mode);
 
-	for (count = 0; count < mv_vif->legacy_nrates; count++)
-		cmd->supp_rates[count] = bitrates[count].hw_value;
+	memcpy(cmd->supp_rates, mwl8k_rateids, sizeof(mwl8k_rateids));
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2252,20 +2642,17 @@ static int mwl8k_cmd_set_aid(struct ieee
  */
 struct mwl8k_cmd_update_rateset {
 	struct	mwl8k_cmd_pkt header;
-	__u8	legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+	__u8	legacy_rates[14];
 
 	/* Bitmap for supported MCS codes.  */
-	__u8	mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES];
-	__u8	reserved[MWL8K_IEEE_LEGACY_DATA_RATES];
+	__u8	mcs_set[16];
+	__u8	reserved[16];
 } __attribute__((packed));
 
 static int mwl8k_update_rateset(struct ieee80211_hw *hw,
 		struct ieee80211_vif *vif)
 {
-	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
 	struct mwl8k_cmd_update_rateset *cmd;
-	struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
-	int count;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2274,9 +2661,7 @@ static int mwl8k_update_rateset(struct i
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-
-	for (count = 0; count < mv_vif->legacy_nrates; count++)
-		cmd->legacy_rates[count] = bitrates[count].hw_value;
+	memcpy(cmd->legacy_rates, mwl8k_rateids, sizeof(mwl8k_rateids));
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2341,9 +2726,10 @@ static int mwl8k_cmd_use_fixed_rate(stru
 	cmd->rate_type = cpu_to_le32(rate_type);
 
 	if (rate_table != NULL) {
-		/* Copy over each field manually so
-		* that bitflipping can be done
-		*/
+		/*
+		 * Copy over each field manually so that endian
+		 * conversion can be done.
+		 */
 		cmd->rate_table.allow_rate_drop =
 				cpu_to_le32(rate_table->allow_rate_drop);
 		cmd->rate_table.num_rates =
@@ -2399,7 +2785,7 @@ static irqreturn_t mwl8k_interrupt(int i
 
 	if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
 		if (!mutex_is_locked(&priv->fw_mutex) &&
-		    priv->radio_on && mwl8k_txq_busy(priv))
+		    priv->radio_on && priv->pending_tx_pkts)
 			mwl8k_tx_start(priv);
 	}
 
@@ -2418,7 +2804,7 @@ static int mwl8k_tx(struct ieee80211_hw
 
 	if (priv->current_channel == NULL) {
 		printk(KERN_DEBUG "%s: dropped TX frame since radio "
-		       "disabled\n", priv->name);
+		       "disabled\n", wiphy_name(hw->wiphy));
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -2433,11 +2819,11 @@ static int mwl8k_start(struct ieee80211_
 	struct mwl8k_priv *priv = hw->priv;
 	int rc;
 
-	rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       priv->name);
+		       wiphy_name(hw->wiphy));
 		return -EIO;
 	}
 
@@ -2451,12 +2837,17 @@ static int mwl8k_start(struct ieee80211_
 	if (!rc) {
 		rc = mwl8k_cmd_802_11_radio_enable(hw);
 
-		if (!rc)
-			rc = mwl8k_cmd_set_pre_scan(hw);
+		if (!priv->ap_fw) {
+			if (!rc)
+				rc = mwl8k_enable_sniffer(hw, 0);
 
-		if (!rc)
-			rc = mwl8k_cmd_set_post_scan(hw,
-					"\x00\x00\x00\x00\x00\x00");
+			if (!rc)
+				rc = mwl8k_cmd_set_pre_scan(hw);
+
+			if (!rc)
+				rc = mwl8k_cmd_set_post_scan(hw,
+						"\x00\x00\x00\x00\x00\x00");
+		}
 
 		if (!rc)
 			rc = mwl8k_cmd_setrateadaptmode(hw, 0);
@@ -2464,9 +2855,6 @@ static int mwl8k_start(struct ieee80211_
 		if (!rc)
 			rc = mwl8k_set_wmm(hw, 0);
 
-		if (!rc)
-			rc = mwl8k_enable_sniffer(hw, 0);
-
 		mwl8k_fw_unlock(hw);
 	}
 
@@ -2500,9 +2888,6 @@ static void mwl8k_stop(struct ieee80211_
 	/* Stop tx reclaim tasklet */
 	tasklet_disable(&priv->tx_reclaim_task);
 
-	/* Stop config thread */
-	flush_workqueue(priv->config_wq);
-
 	/* Return all skbs to mac80211 */
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
 		mwl8k_txq_reclaim(hw, i, 1);
@@ -2526,21 +2911,29 @@ static int mwl8k_add_interface(struct ie
 	if (conf->type != NL80211_IFTYPE_STATION)
 		return -EINVAL;
 
+	/*
+	 * Reject interface creation if sniffer mode is active, as
+	 * STA operation is mutually exclusive with hardware sniffer
+	 * mode.
+	 */
+	if (priv->sniffer_enabled) {
+		printk(KERN_INFO "%s: unable to create STA "
+		       "interface due to sniffer mode being enabled\n",
+		       wiphy_name(hw->wiphy));
+		return -EINVAL;
+	}
+
 	/* Clean out driver private area */
 	mwl8k_vif = MWL8K_VIF(conf->vif);
 	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
 
-	/* Save the mac address */
+	/* Set and save the mac address */
+	mwl8k_set_mac_addr(hw, conf->mac_addr);
 	memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
 
 	/* Back pointer to parent config block */
 	mwl8k_vif->priv = priv;
 
-	/* Setup initial PHY parameters */
-	memcpy(mwl8k_vif->legacy_rates,
-		priv->rates, sizeof(mwl8k_vif->legacy_rates));
-	mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
-
 	/* Set Initial sequence number to zero */
 	mwl8k_vif->seqno = 0;
 
@@ -2558,6 +2951,8 @@ static void mwl8k_remove_interface(struc
 	if (priv->vif == NULL)
 		return;
 
+	mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
+
 	priv->vif = NULL;
 }
 
@@ -2593,8 +2988,13 @@ static int mwl8k_config(struct ieee80211
 	if (rc)
 		goto out;
 
-	if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
-		rc = -EINVAL;
+	if (priv->ap_fw) {
+		rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
+		if (!rc)
+			rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
+	} else {
+		rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
+	}
 
 out:
 	mwl8k_fw_unlock(hw);
@@ -2611,9 +3011,6 @@ static void mwl8k_bss_info_changed(struc
 	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
 	int rc;
 
-	if (changed & BSS_CHANGED_BSSID)
-		memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
-
 	if ((changed & BSS_CHANGED_ASSOC) == 0)
 		return;
 
@@ -2627,6 +3024,8 @@ static void mwl8k_bss_info_changed(struc
 		memcpy(&mwl8k_vif->bss_info, info,
 			sizeof(struct ieee80211_bss_conf));
 
+		memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
+
 		/* Install rates */
 		rc = mwl8k_update_rateset(hw, vif);
 		if (rc)
@@ -2681,32 +3080,110 @@ static u64 mwl8k_prepare_multicast(struc
 {
 	struct mwl8k_cmd_pkt *cmd;
 
-	cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
+	/*
+	 * Synthesize and return a command packet that programs the
+	 * hardware multicast address filter.  At this point we don't
+	 * know whether FIF_ALLMULTI is being requested, but if it is,
+	 * we'll end up throwing this packet away and creating a new
+	 * one in mwl8k_configure_filter().
+	 */
+	cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist);
 
 	return (unsigned long)cmd;
 }
 
+static int
+mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
+			       unsigned int changed_flags,
+			       unsigned int *total_flags)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	/*
+	 * Hardware sniffer mode is mutually exclusive with STA
+	 * operation, so refuse to enable sniffer mode if a STA
+	 * interface is active.
+	 */
+	if (priv->vif != NULL) {
+		if (net_ratelimit())
+			printk(KERN_INFO "%s: not enabling sniffer "
+			       "mode because STA interface is active\n",
+			       wiphy_name(hw->wiphy));
+		return 0;
+	}
+
+	if (!priv->sniffer_enabled) {
+		if (mwl8k_enable_sniffer(hw, 1))
+			return 0;
+		priv->sniffer_enabled = true;
+	}
+
+	*total_flags &=	FIF_PROMISC_IN_BSS | FIF_ALLMULTI |
+			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL |
+			FIF_OTHER_BSS;
+
+	return 1;
+}
+
 static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 				   unsigned int changed_flags,
 				   unsigned int *total_flags,
 				   u64 multicast)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_cmd_pkt *multicast_adr_cmd;
+	struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast;
+
+	/*
+	 * AP firmware doesn't allow fine-grained control over
+	 * the receive filter.
+	 */
+	if (priv->ap_fw) {
+		*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
+		kfree(cmd);
+		return;
+	}
+
+	/*
+	 * Enable hardware sniffer mode if FIF_CONTROL or
+	 * FIF_OTHER_BSS is requested.
+	 */
+	if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) &&
+	    mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
+		kfree(cmd);
+		return;
+	}
 
 	/* Clear unsupported feature flags */
-	*total_flags &= FIF_BCN_PRBRESP_PROMISC;
+	*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
 
-	if (mwl8k_fw_lock(hw))
+	if (mwl8k_fw_lock(hw)) {
+		kfree(cmd);
 		return;
+	}
+
+	if (priv->sniffer_enabled) {
+		mwl8k_enable_sniffer(hw, 0);
+		priv->sniffer_enabled = false;
+	}
 
 	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
+			/*
+			 * Disable the BSS filter.
+			 */
 			mwl8k_cmd_set_pre_scan(hw);
-		else {
+		} else {
 			u8 *bssid;
 
-			bssid = "\x00\x00\x00\x00\x00\x00";
+			/*
+			 * Enable the BSS filter.
+			 *
+			 * If there is an active STA interface, use that
+			 * interface's BSSID, otherwise use a dummy one
+			 * (where the OUI part needs to be nonzero for
+			 * the BSSID to be accepted by POST_SCAN).
+			 */
+			bssid = "\x01\x00\x00\x00\x00\x00";
 			if (priv->vif != NULL)
 				bssid = MWL8K_VIF(priv->vif)->bssid;
 
@@ -2714,10 +3191,20 @@ static void mwl8k_configure_filter(struc
 		}
 	}
 
-	multicast_adr_cmd = (void *)(unsigned long)multicast;
-	if (multicast_adr_cmd != NULL) {
-		mwl8k_post_cmd(hw, multicast_adr_cmd);
-		kfree(multicast_adr_cmd);
+	/*
+	 * If FIF_ALLMULTI is being requested, throw away the command
+	 * packet that ->prepare_multicast() built and replace it with
+	 * a command packet that enables reception of all multicast
+	 * packets.
+	 */
+	if (*total_flags & FIF_ALLMULTI) {
+		kfree(cmd);
+		cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL);
+	}
+
+	if (cmd != NULL) {
+		mwl8k_post_cmd(hw, cmd);
+		kfree(cmd);
 	}
 
 	mwl8k_fw_unlock(hw);
@@ -2762,7 +3249,7 @@ static int mwl8k_get_tx_stats(struct iee
 	spin_lock_bh(&priv->tx_lock);
 	for (index = 0; index < MWL8K_TX_QUEUES; index++) {
 		txq = priv->txq + index;
-		memcpy(&stats[index], &txq->tx_stats,
+		memcpy(&stats[index], &txq->stats,
 			sizeof(struct ieee80211_tx_queue_stats));
 	}
 	spin_unlock_bh(&priv->tx_lock);
@@ -2802,7 +3289,7 @@ static void mwl8k_tx_reclaim_handler(uns
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
 		mwl8k_txq_reclaim(hw, i, 0);
 
-	if (priv->tx_wait != NULL && mwl8k_txq_busy(priv) == 0) {
+	if (priv->tx_wait != NULL && !priv->pending_tx_pkts) {
 		complete(priv->tx_wait);
 		priv->tx_wait = NULL;
 	}
@@ -2822,6 +3309,36 @@ static void mwl8k_finalize_join_worker(s
 	priv->beacon_skb = NULL;
 }
 
+enum {
+	MWL8687 = 0,
+	MWL8366,
+};
+
+static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
+	{
+		.part_name	= "88w8687",
+		.helper_image	= "/*(DEBLOBBED)*/",
+		.fw_image	= "/*(DEBLOBBED)*/",
+		.rxd_ops	= &rxd_8687_ops,
+		.modes		= BIT(NL80211_IFTYPE_STATION),
+	},
+	{
+		.part_name	= "88w8366",
+		.helper_image	= "/*(DEBLOBBED)*/",
+		.fw_image	= "/*(DEBLOBBED)*/",
+		.rxd_ops	= &rxd_8366_ops,
+		.modes		= 0,
+	},
+};
+
+static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+	{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
+	{ PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
+	{ PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
+
 static int __devinit mwl8k_probe(struct pci_dev *pdev,
 				 const struct pci_device_id *id)
 {
@@ -2847,7 +3364,7 @@ static int __devinit mwl8k_probe(struct
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
 		       MWL8K_NAME);
-		return rc;
+		goto err_disable_device;
 	}
 
 	pci_set_master(pdev);
@@ -2862,17 +3379,34 @@ static int __devinit mwl8k_probe(struct
 	priv = hw->priv;
 	priv->hw = hw;
 	priv->pdev = pdev;
+	priv->device_info = &mwl8k_info_tbl[id->driver_data];
+	priv->rxd_ops = priv->device_info->rxd_ops;
+	priv->sniffer_enabled = false;
 	priv->wmm_enabled = false;
 	priv->pending_tx_pkts = 0;
-	strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
 
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 	pci_set_drvdata(pdev, hw);
 
+	priv->sram = pci_iomap(pdev, 0, 0x10000);
+	if (priv->sram == NULL) {
+		printk(KERN_ERR "%s: Cannot map device SRAM\n",
+		       wiphy_name(hw->wiphy));
+		goto err_iounmap;
+	}
+
+	/*
+	 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
+	 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
+	 */
 	priv->regs = pci_iomap(pdev, 1, 0x10000);
 	if (priv->regs == NULL) {
-		printk(KERN_ERR "%s: Cannot map device memory\n", priv->name);
-		goto err_iounmap;
+		priv->regs = pci_iomap(pdev, 2, 0x10000);
+		if (priv->regs == NULL) {
+			printk(KERN_ERR "%s: Cannot map device registers\n",
+			       wiphy_name(hw->wiphy));
+			goto err_iounmap;
+		}
 	}
 
 	memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
@@ -2897,7 +3431,7 @@ static int __devinit mwl8k_probe(struct
 
 	hw->queues = MWL8K_TX_QUEUES;
 
-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	hw->wiphy->interface_modes = priv->device_info->modes;
 
 	/* Set rssi and noise values to dBm */
 	hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
@@ -2916,11 +3450,6 @@ static int __devinit mwl8k_probe(struct
 			mwl8k_tx_reclaim_handler, (unsigned long)hw);
 	tasklet_disable(&priv->tx_reclaim_task);
 
-	/* Config workthread */
-	priv->config_wq = create_singlethread_workqueue("mwl8k_config");
-	if (priv->config_wq == NULL)
-		goto err_iounmap;
-
 	/* Power management cookie */
 	priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
 	if (priv->cookie == NULL)
@@ -2934,11 +3463,12 @@ static int __devinit mwl8k_probe(struct
 	mutex_init(&priv->fw_mutex);
 	priv->fw_mutex_owner = NULL;
 	priv->fw_mutex_depth = 0;
-	priv->tx_wait = NULL;
 	priv->hostcmd_wait = NULL;
 
 	spin_lock_init(&priv->tx_lock);
 
+	priv->tx_wait = NULL;
+
 	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
 		rc = mwl8k_txq_init(hw, i);
 		if (rc)
@@ -2950,11 +3480,11 @@ static int __devinit mwl8k_probe(struct
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
 	iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
 
-	rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       priv->name);
+		       wiphy_name(hw->wiphy));
 		goto err_free_queues;
 	}
 
@@ -2962,16 +3492,18 @@ static int __devinit mwl8k_probe(struct
 	mwl8k_hw_reset(priv);
 
 	/* Ask userland hotplug daemon for the device firmware */
-	rc = mwl8k_reject_firmware(priv, (u32)id->driver_data);
+	rc = mwl8k_reject_firmware(priv);
 	if (rc) {
-		printk(KERN_ERR "%s: Firmware files not found\n", priv->name);
+		printk(KERN_ERR "%s: Firmware files not found\n",
+		       wiphy_name(hw->wiphy));
 		goto err_free_irq;
 	}
 
 	/* Load firmware into hardware */
-	rc = mwl8k_load_firmware(priv);
+	rc = mwl8k_load_firmware(hw);
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot start firmware\n", priv->name);
+		printk(KERN_ERR "%s: Cannot start firmware\n",
+		       wiphy_name(hw->wiphy));
 		goto err_stop_firmware;
 	}
 
@@ -2986,16 +3518,31 @@ static int __devinit mwl8k_probe(struct
 	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 
 	/* Get config data, mac addrs etc */
-	rc = mwl8k_cmd_get_hw_spec(hw);
+	if (priv->ap_fw) {
+		rc = mwl8k_cmd_get_hw_spec_ap(hw);
+		if (!rc)
+			rc = mwl8k_cmd_set_hw_spec(hw);
+	} else {
+		rc = mwl8k_cmd_get_hw_spec_sta(hw);
+	}
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name);
+		printk(KERN_ERR "%s: Cannot initialise firmware\n",
+		       wiphy_name(hw->wiphy));
 		goto err_stop_firmware;
 	}
 
 	/* Turn radio off */
 	rc = mwl8k_cmd_802_11_radio_disable(hw);
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot disable\n", priv->name);
+		printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
+		goto err_stop_firmware;
+	}
+
+	/* Clear MAC address */
+	rc = mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot clear MAC address\n",
+		       wiphy_name(hw->wiphy));
 		goto err_stop_firmware;
 	}
 
@@ -3005,13 +3552,15 @@ static int __devinit mwl8k_probe(struct
 
 	rc = ieee80211_register_hw(hw);
 	if (rc) {
-		printk(KERN_ERR "%s: Cannot register device\n", priv->name);
+		printk(KERN_ERR "%s: Cannot register device\n",
+		       wiphy_name(hw->wiphy));
 		goto err_stop_firmware;
 	}
 
-	printk(KERN_INFO "%s: 88w%u v%d, %pM, firmware version %u.%u.%u.%u\n",
-	       wiphy_name(hw->wiphy), priv->part_num, priv->hw_rev,
-	       hw->wiphy->perm_addr,
+	printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
+	       wiphy_name(hw->wiphy), priv->device_info->part_name,
+	       priv->hw_rev, hw->wiphy->perm_addr,
+	       priv->ap_fw ? "AP" : "STA",
 	       (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
 	       (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
 
@@ -3038,14 +3587,16 @@ err_iounmap:
 	if (priv->regs != NULL)
 		pci_iounmap(pdev, priv->regs);
 
-	if (priv->config_wq != NULL)
-		destroy_workqueue(priv->config_wq);
+	if (priv->sram != NULL)
+		pci_iounmap(pdev, priv->sram);
 
 	pci_set_drvdata(pdev, NULL);
 	ieee80211_free_hw(hw);
 
 err_free_reg:
 	pci_release_regions(pdev);
+
+err_disable_device:
 	pci_disable_device(pdev);
 
 	return rc;
@@ -3073,9 +3624,6 @@ static void __devexit mwl8k_remove(struc
 	/* Remove tx reclaim tasklet */
 	tasklet_kill(&priv->tx_reclaim_task);
 
-	/* Stop config thread */
-	destroy_workqueue(priv->config_wq);
-
 	/* Stop hardware */
 	mwl8k_hw_reset(priv);
 
@@ -3088,10 +3636,10 @@ static void __devexit mwl8k_remove(struc
 
 	mwl8k_rxq_deinit(hw, 0);
 
-	pci_free_consistent(priv->pdev, 4,
-				priv->cookie, priv->cookie_dma);
+	pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
 
 	pci_iounmap(pdev, priv->regs);
+	pci_iounmap(pdev, priv->sram);
 	pci_set_drvdata(pdev, NULL);
 	ieee80211_free_hw(hw);
 	pci_release_regions(pdev);
@@ -3100,7 +3648,7 @@ static void __devexit mwl8k_remove(struc
 
 static struct pci_driver mwl8k_driver = {
 	.name		= MWL8K_NAME,
-	.id_table	= mwl8k_table,
+	.id_table	= mwl8k_pci_id_table,
 	.probe		= mwl8k_probe,
 	.remove		= __devexit_p(mwl8k_remove),
 	.shutdown	= __devexit_p(mwl8k_shutdown),
@@ -3118,3 +3666,8 @@ static void __exit mwl8k_exit(void)
 
 module_init(mwl8k_init);
 module_exit(mwl8k_exit);
+
+MODULE_DESCRIPTION(MWL8K_DESC);
+MODULE_VERSION(MWL8K_VERSION);
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/netwave_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/netwave_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/netwave_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/netwave_cs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1389 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      netwave_cs.c
- * Version:       0.4.1
- * Description:   Netwave AirSurfer Wireless LAN PC Card driver
- * Status:        Experimental.
- * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
- *                Dag Brattli <dagb@cs.uit.no>
- *                David Hinds <dahinds@users.sourceforge.net>
- * Created at:    A long time ago!
- * Modified at:   Mon Nov 10 11:54:37 1997
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1997 University of Tromsø, Norway
- *
- * Revision History:
- *
- *   08-Nov-97 15:14:47   John Markus Bjørndalen <johnm@cs.uit.no>
- *    - Fixed some bugs in netwave_rx and cleaned it up a bit. 
- *      (One of the bugs would have destroyed packets when receiving
- *      multiple packets per interrupt). 
- *    - Cleaned up parts of newave_hw_xmit. 
- *    - A few general cleanups. 
- *   24-Oct-97 13:17:36   Dag Brattli <dagb@cs.uit.no>
- *    - Fixed netwave_rx receive function (got updated docs)
- *   Others:
- *    - Changed name from xircnw to netwave, take a look at 
- *      http://www.netwave-wireless.com
- *    - Some reorganizing of the code
- *    - Removed possible race condition between interrupt handler and transmit
- *      function
- *    - Started to add wireless extensions, but still needs some coding
- *    - Added watchdog for better handling of transmission timeouts 
- *      (hopefully this works better)
- ********************************************************************/
-
-/* To have statistics (just packets sent) define this */
-#undef NETWAVE_STATS
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/mem_op.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define NETWAVE_REGOFF         0x8000
-/* The Netwave IO registers, offsets to iobase */
-#define NETWAVE_REG_COR        0x0
-#define NETWAVE_REG_CCSR       0x2
-#define NETWAVE_REG_ASR        0x4
-#define NETWAVE_REG_IMR        0xa
-#define NETWAVE_REG_PMR        0xc
-#define NETWAVE_REG_IOLOW      0x6
-#define NETWAVE_REG_IOHI       0x7
-#define NETWAVE_REG_IOCONTROL  0x8
-#define NETWAVE_REG_DATA       0xf
-/* The Netwave Extended IO registers, offsets to RamBase */
-#define NETWAVE_EREG_ASCC      0x114
-#define NETWAVE_EREG_RSER      0x120
-#define NETWAVE_EREG_RSERW     0x124
-#define NETWAVE_EREG_TSER      0x130
-#define NETWAVE_EREG_TSERW     0x134
-#define NETWAVE_EREG_CB        0x100
-#define NETWAVE_EREG_SPCQ      0x154
-#define NETWAVE_EREG_SPU       0x155
-#define NETWAVE_EREG_LIF       0x14e
-#define NETWAVE_EREG_ISPLQ     0x156
-#define NETWAVE_EREG_HHC       0x158
-#define NETWAVE_EREG_NI        0x16e
-#define NETWAVE_EREG_MHS       0x16b
-#define NETWAVE_EREG_TDP       0x140
-#define NETWAVE_EREG_RDP       0x150
-#define NETWAVE_EREG_PA        0x160
-#define NETWAVE_EREG_EC        0x180
-#define NETWAVE_EREG_CRBP      0x17a
-#define NETWAVE_EREG_ARW       0x166
-
-/*
- * Commands used in the extended command buffer
- * NETWAVE_EREG_CB (0x100-0x10F) 
- */
-#define NETWAVE_CMD_NOP        0x00
-#define NETWAVE_CMD_SRC        0x01
-#define NETWAVE_CMD_STC        0x02
-#define NETWAVE_CMD_AMA        0x03
-#define NETWAVE_CMD_DMA        0x04
-#define NETWAVE_CMD_SAMA       0x05
-#define NETWAVE_CMD_ER         0x06
-#define NETWAVE_CMD_DR         0x07
-#define NETWAVE_CMD_TL         0x08
-#define NETWAVE_CMD_SRP        0x09
-#define NETWAVE_CMD_SSK        0x0a
-#define NETWAVE_CMD_SMD        0x0b
-#define NETWAVE_CMD_SAPD       0x0c
-#define NETWAVE_CMD_SSS        0x11
-/* End of Command marker */
-#define NETWAVE_CMD_EOC        0x00
-
-/* ASR register bits */
-#define NETWAVE_ASR_RXRDY   0x80
-#define NETWAVE_ASR_TXBA    0x01
-
-#define TX_TIMEOUT		((32*HZ)/100)
-
-static const unsigned int imrConfRFU1 = 0x10; /* RFU interrupt mask, keep high */
-static const unsigned int imrConfIENA = 0x02; /* Interrupt enable */
-
-static const unsigned int corConfIENA   = 0x01; /* Interrupt enable */
-static const unsigned int corConfLVLREQ = 0x40; /* Keep high */
-
-static const unsigned int rxConfRxEna  = 0x80; /* Receive Enable */
-static const unsigned int rxConfMAC    = 0x20; /* MAC host receive mode*/ 
-static const unsigned int rxConfPro    = 0x10; /* Promiscuous */
-static const unsigned int rxConfAMP    = 0x08; /* Accept Multicast Packets */
-static const unsigned int rxConfBcast  = 0x04; /* Accept Broadcast Packets */
-
-static const unsigned int txConfTxEna  = 0x80; /* Transmit Enable */
-static const unsigned int txConfMAC    = 0x20; /* Host sends MAC mode */
-static const unsigned int txConfEUD    = 0x10; /* Enable Uni-Data packets */
-static const unsigned int txConfKey    = 0x02; /* Scramble data packets */
-static const unsigned int txConfLoop   = 0x01; /* Loopback mode */
-
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
-/* Choose the domain, default is 0x100 */
-static u_int  domain = 0x100;
-
-/* Scramble key, range from 0x0 to 0xffff.  
- * 0x0 is no scrambling. 
- */
-static u_int  scramble_key = 0x0;
-
-/* Shared memory speed, in ns. The documentation states that 
- * the card should not be read faster than every 400ns. 
- * This timing should be provided by the HBA. If it becomes a 
- * problem, try setting mem_speed to 400. 
- */
-static int mem_speed;
-
-module_param(domain, int, 0);
-module_param(scramble_key, int, 0);
-module_param(mem_speed, int, 0);
-
-/*====================================================================*/
-
-/* PCMCIA (Card Services) related functions */
-static void netwave_release(struct pcmcia_device *link);     /* Card removal */
-static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card
-													   insertion */
-static void netwave_detach(struct pcmcia_device *p_dev);    /* Destroy instance */
-
-/* Hardware configuration */
-static void netwave_doreset(unsigned int iobase, u_char __iomem *ramBase);
-static void netwave_reset(struct net_device *dev);
-
-/* Misc device stuff */
-static int netwave_open(struct net_device *dev);  /* Open the device */
-static int netwave_close(struct net_device *dev); /* Close the device */
-
-/* Packet transmission and Packet reception */
-static netdev_tx_t netwave_start_xmit( struct sk_buff *skb,
-					     struct net_device *dev);
-static int netwave_rx( struct net_device *dev);
-
-/* Interrupt routines */
-static irqreturn_t netwave_interrupt(int irq, void *dev_id);
-static void netwave_watchdog(struct net_device *);
-
-/* Wireless extensions */
-static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
-
-static void set_multicast_list(struct net_device *dev);
-
-/*
-   A struct pcmcia_device structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a struct pcmcia_device structure can be used to point to
-   a device-specific private data structure, like this.
-
-   A driver needs to provide a dev_node_t structure for each device
-   on a card.  In some cases, there is only one device per card (for
-   example, ethernet cards, modems).  In other cases, there may be
-   many actual or logical devices (SCSI adapters, memory cards with
-   multiple partitions).  The dev_node_t structures need to be kept
-   in a linked list starting at the 'dev' field of a struct pcmcia_device
-   structure.  We allocate them in the card's private data structure,
-   because they generally can't be allocated dynamically.
-*/
-
-static const struct iw_handler_def	netwave_handler_def;
-
-#define SIOCGIPSNAP	SIOCIWFIRSTPRIV	+ 1	/* Site Survey Snapshot */
-
-#define MAX_ESA 10
-
-typedef struct net_addr {
-    u_char addr48[6];
-} net_addr;
-
-struct site_survey {
-    u_short length;
-    u_char  struct_revision;
-    u_char  roaming_state;
-	
-    u_char  sp_existsFlag;
-    u_char  sp_link_quality;
-    u_char  sp_max_link_quality;
-    u_char  linkQualityGoodFairBoundary;
-    u_char  linkQualityFairPoorBoundary;
-    u_char  sp_utilization;
-    u_char  sp_goodness;
-    u_char  sp_hotheadcount;
-    u_char  roaming_condition;
-	
-    net_addr sp;
-    u_char   numAPs;
-    net_addr nearByAccessPoints[MAX_ESA];
-};	
-   
-typedef struct netwave_private {
-	struct pcmcia_device	*p_dev;
-    spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
-    dev_node_t node;
-    u_char     __iomem *ramBase;
-    int        timeoutCounter;
-    int        lastExec;
-    struct timer_list      watchdog;	/* To avoid blocking state */
-    struct site_survey     nss;
-    struct iw_statistics   iw_stats;    /* Wireless stats */
-} netwave_private;
-
-/*
- * The Netwave card is little-endian, so won't work for big endian
- * systems.
- */
-static inline unsigned short get_uint16(u_char __iomem *staddr) 
-{
-    return readw(staddr); /* Return only 16 bits */
-}
-
-static inline short get_int16(u_char __iomem * staddr)
-{
-    return readw(staddr);
-}
-
-/* 
- * Wait until the WOC (Write Operation Complete) bit in the 
- * ASR (Adapter Status Register) is asserted. 
- * This should have aborted if it takes too long time. 
- */
-static inline void wait_WOC(unsigned int iobase)
-{
-    /* Spin lock */
-    while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; 
-}
-
-static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, 
-			     unsigned int iobase) {
-    u_short resultBuffer;
-
-    /* if time since last snapshot is > 1 sec. (100 jiffies?)  then take 
-     * new snapshot, else return cached data. This is the recommended rate.  
-     */
-    if ( jiffies - priv->lastExec > 100) { 
-	/* Take site survey  snapshot */ 
-	/*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
-	  priv->lastExec); */
-	wait_WOC(iobase); 
-	writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0); 
-	writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); 
-	wait_WOC(iobase); 
-
-	/* Get result and copy to cach */ 
-	resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP); 
-	copy_from_pc( &priv->nss, ramBase+resultBuffer, 
-		      sizeof(struct site_survey)); 
-    } 
-}
-
-/*
- * Function netwave_get_wireless_stats (dev)
- *
- *    Wireless extensions statistics
- *
- */
-static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
-{	
-    unsigned long flags;
-    unsigned int iobase = dev->base_addr;
-    netwave_private *priv = netdev_priv(dev);
-    u_char __iomem *ramBase = priv->ramBase;
-    struct iw_statistics* wstats;
-	
-    wstats = &priv->iw_stats;
-
-    spin_lock_irqsave(&priv->spinlock, flags);
-	
-    netwave_snapshot( priv, ramBase, iobase);
-
-    wstats->status = priv->nss.roaming_state;
-    wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ); 
-    wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
-    wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
-    wstats->discard.nwid = 0L;
-    wstats->discard.code = 0L;
-    wstats->discard.misc = 0L;
-
-    spin_unlock_irqrestore(&priv->spinlock, flags);
-    
-    return &priv->iw_stats;
-}
-
-static const struct net_device_ops netwave_netdev_ops = {
-	.ndo_open	 	= netwave_open,
-	.ndo_stop		= netwave_close,
-	.ndo_start_xmit		= netwave_start_xmit,
-	.ndo_set_multicast_list = set_multicast_list,
-	.ndo_tx_timeout		= netwave_watchdog,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/*
- * Function netwave_attach (void)
- *
- *     Creates an "instance" of the driver, allocating local data 
- *     structures for one device.  The device is registered with Card 
- *     Services.
- *
- *     The dev_link structure is initialized, but we don't actually
- *     configure the card at this point -- we wait until we receive a
- *     card insertion event.
- */
-static int netwave_probe(struct pcmcia_device *link)
-{
-    struct net_device *dev;
-    netwave_private *priv;
-
-    DEBUG(0, "netwave_attach()\n");
-
-    /* Initialize the struct pcmcia_device structure */
-    dev = alloc_etherdev(sizeof(netwave_private));
-    if (!dev)
-	return -ENOMEM;
-    priv = netdev_priv(dev);
-    priv->p_dev = link;
-    link->priv = dev;
-
-    /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    /* link->io.NumPorts2 = 16; 
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
-    link->io.IOAddrLines = 5;
-    
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &netwave_interrupt;
-    
-    /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-
-    /* Netwave private struct init. link/dev/node already taken care of,
-     * other stuff zero'd - Jean II */
-    spin_lock_init(&priv->spinlock);
-
-    /* Netwave specific entries in the device structure */
-    dev->netdev_ops = &netwave_netdev_ops;
-    /* wireless extensions */
-    dev->wireless_handlers = &netwave_handler_def;
-
-    dev->watchdog_timeo = TX_TIMEOUT;
-
-    link->irq.Instance = dev;
-
-    return netwave_pcmcia_config( link);
-} /* netwave_attach */
-
-/*
- * Function netwave_detach (link)
- *
- *    This deletes a driver "instance".  The device is de-registered
- *    with Card Services.  If it has been released, all local data
- *    structures are freed.  Otherwise, the structures will be freed
- *    when the device is released.
- */
-static void netwave_detach(struct pcmcia_device *link)
-{
-	struct net_device *dev = link->priv;
-
-	DEBUG(0, "netwave_detach(0x%p)\n", link);
-
-	netwave_release(link);
-
-	if (link->dev_node)
-		unregister_netdev(dev);
-
-	free_netdev(dev);
-} /* netwave_detach */
-
-/*
- * Wireless Handler : get protocol name
- */
-static int netwave_get_name(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	strcpy(wrqu->name, "Netwave");
-	return 0;
-}
-
-/*
- * Wireless Handler : set Network ID
- */
-static int netwave_set_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long flags;
-	unsigned int iobase = dev->base_addr;
-	netwave_private *priv = netdev_priv(dev);
-	u_char __iomem *ramBase = priv->ramBase;
-
-	/* Disable interrupts & save flags */
-	spin_lock_irqsave(&priv->spinlock, flags);
-
-	if(!wrqu->nwid.disabled) {
-	    domain = wrqu->nwid.value;
-	    printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", 
-		    (domain >> 8) & 0x01, domain & 0xff);
-	    wait_WOC(iobase);
-	    writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
-	    writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
-	    writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
-	    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-	}
-
-	/* ReEnable interrupts & restore flags */
-	spin_unlock_irqrestore(&priv->spinlock, flags);
-    
-	return 0;
-}
-
-/*
- * Wireless Handler : get Network ID
- */
-static int netwave_get_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	wrqu->nwid.value = domain;
-	wrqu->nwid.disabled = 0;
-	wrqu->nwid.fixed = 1;
-	return 0;
-}
-
-/*
- * Wireless Handler : set scramble key
- */
-static int netwave_set_scramble(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu,
-				char *key)
-{
-	unsigned long flags;
-	unsigned int iobase = dev->base_addr;
-	netwave_private *priv = netdev_priv(dev);
-	u_char __iomem *ramBase = priv->ramBase;
-
-	/* Disable interrupts & save flags */
-	spin_lock_irqsave(&priv->spinlock, flags);
-
-	scramble_key = (key[0] << 8) | key[1];
-	wait_WOC(iobase);
-	writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
-	writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
-	writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
-	writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-
-	/* ReEnable interrupts & restore flags */
-	spin_unlock_irqrestore(&priv->spinlock, flags);
-    
-	return 0;
-}
-
-/*
- * Wireless Handler : get scramble key
- */
-static int netwave_get_scramble(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu,
-				char *key)
-{
-	key[1] = scramble_key & 0xff;
-	key[0] = (scramble_key>>8) & 0xff;
-	wrqu->encoding.flags = IW_ENCODE_ENABLED;
-	wrqu->encoding.length = 2;
-	return 0;
-}
-
-/*
- * Wireless Handler : get mode
- */
-static int netwave_get_mode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	if(domain & 0x100)
-		wrqu->mode = IW_MODE_INFRA;
-	else
-		wrqu->mode = IW_MODE_ADHOC;
-
-	return 0;
-}
-
-/*
- * Wireless Handler : get range info
- */
-static int netwave_get_range(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	struct iw_range *range = (struct iw_range *) extra;
-	int ret = 0;
-
-	/* Set the length (very important for backward compatibility) */
-	wrqu->data.length = sizeof(struct iw_range);
-
-	/* Set all the info we don't care or don't know about to zero */
-	memset(range, 0, sizeof(struct iw_range));
-
-	/* Set the Wireless Extension versions */
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 9;	/* Nothing for us in v10 and v11 */
-		   
-	/* Set information in the range struct */
-	range->throughput = 450 * 1000;	/* don't argue on this ! */
-	range->min_nwid = 0x0000;
-	range->max_nwid = 0x01FF;
-
-	range->num_channels = range->num_frequency = 0;
-		   
-	range->sensitivity = 0x3F;
-	range->max_qual.qual = 255;
-	range->max_qual.level = 255;
-	range->max_qual.noise = 0;
-		   
-	range->num_bitrates = 1;
-	range->bitrate[0] = 1000000;	/* 1 Mb/s */
-
-	range->encoding_size[0] = 2;		/* 16 bits scrambling */
-	range->num_encoding_sizes = 1;
-	range->max_encoding_tokens = 1;	/* Only one key possible */
-
-	return ret;
-}
-
-/*
- * Wireless Private Handler : get snapshot
- */
-static int netwave_get_snap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long flags;
-	unsigned int iobase = dev->base_addr;
-	netwave_private *priv = netdev_priv(dev);
-	u_char __iomem *ramBase = priv->ramBase;
-
-	/* Disable interrupts & save flags */
-	spin_lock_irqsave(&priv->spinlock, flags);
-
-	/* Take snapshot of environment */
-	netwave_snapshot( priv, ramBase, iobase);
-	wrqu->data.length = priv->nss.length;
-	memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
-
-	priv->lastExec = jiffies;
-
-	/* ReEnable interrupts & restore flags */
-	spin_unlock_irqrestore(&priv->spinlock, flags);
-    
-	return(0);
-}
-
-/*
- * Structures to export the Wireless Handlers
- *     This is the stuff that are treated the wireless extensions (iwconfig)
- */
-
-static const struct iw_priv_args netwave_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { SIOCGIPSNAP, 0, 
-    IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey), 
-    "getsitesurvey" },
-};
-
-static const iw_handler		netwave_handler[] =
-{
-	NULL,				/* SIOCSIWNAME */
-	netwave_get_name,		/* SIOCGIWNAME */
-	netwave_set_nwid,		/* SIOCSIWNWID */
-	netwave_get_nwid,		/* SIOCGIWNWID */
-	NULL,				/* SIOCSIWFREQ */
-	NULL,				/* SIOCGIWFREQ */
-	NULL,				/* SIOCSIWMODE */
-	netwave_get_mode,		/* SIOCGIWMODE */
-	NULL,				/* SIOCSIWSENS */
-	NULL,				/* SIOCGIWSENS */
-	NULL,				/* SIOCSIWRANGE */
-	netwave_get_range,		/* SIOCGIWRANGE */
-	NULL,				/* SIOCSIWPRIV */
-	NULL,				/* SIOCGIWPRIV */
-	NULL,				/* SIOCSIWSTATS */
-	NULL,				/* SIOCGIWSTATS */
-	NULL,				/* SIOCSIWSPY */
-	NULL,				/* SIOCGIWSPY */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWAP */
-	NULL,				/* SIOCGIWAP */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCGIWAPLIST */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWESSID */
-	NULL,				/* SIOCGIWESSID */
-	NULL,				/* SIOCSIWNICKN */
-	NULL,				/* SIOCGIWNICKN */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWRATE */
-	NULL,				/* SIOCGIWRATE */
-	NULL,				/* SIOCSIWRTS */
-	NULL,				/* SIOCGIWRTS */
-	NULL,				/* SIOCSIWFRAG */
-	NULL,				/* SIOCGIWFRAG */
-	NULL,				/* SIOCSIWTXPOW */
-	NULL,				/* SIOCGIWTXPOW */
-	NULL,				/* SIOCSIWRETRY */
-	NULL,				/* SIOCGIWRETRY */
-	netwave_set_scramble,		/* SIOCSIWENCODE */
-	netwave_get_scramble,		/* SIOCGIWENCODE */
-};
-
-static const iw_handler		netwave_private_handler[] =
-{
-	NULL,				/* SIOCIWFIRSTPRIV */
-	netwave_get_snap,		/* SIOCIWFIRSTPRIV + 1 */
-};
-
-static const struct iw_handler_def	netwave_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(netwave_handler),
-	.num_private	= ARRAY_SIZE(netwave_private_handler),
-	.num_private_args = ARRAY_SIZE(netwave_private_args),
-	.standard	= (iw_handler *) netwave_handler,
-	.private	= (iw_handler *) netwave_private_handler,
-	.private_args	= (struct iw_priv_args *) netwave_private_args,
-	.get_wireless_stats = netwave_get_wireless_stats,
-};
-
-/*
- * Function netwave_pcmcia_config (link)
- *
- *     netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION 
- *     event is received, to configure the PCMCIA socket, and to make the
- *     device available to the system. 
- *
- */
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-static int netwave_pcmcia_config(struct pcmcia_device *link) {
-    struct net_device *dev = link->priv;
-    netwave_private *priv = netdev_priv(dev);
-    int i, j, last_ret, last_fn;
-    win_req_t req;
-    memreq_t mem;
-    u_char __iomem *ramBase = NULL;
-
-    DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
-
-    /*
-     *  Try allocating IO ports.  This tries a few fixed addresses.
-     *  If you want, you can also read the card's config table to
-     *  pick addresses -- see the serial driver for an example.
-     */
-    for (i = j = 0x0; j < 0x400; j += 0x20) {
-	link->io.BasePort1 = j ^ 0x300;
-	i = pcmcia_request_io(link, &link->io);
-	if (i == 0)
-		break;
-    }
-    if (i != 0) {
-	cs_error(link, RequestIO, i);
-	goto failed;
-    }
-
-    /*
-     *  Now allocate an interrupt line.  Note that this does not
-     *  actually assign a handler to the interrupt.
-     */
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
-    /*
-     *  This actually configures the PCMCIA socket -- setting up
-     *  the I/O windows and the interrupt mapping.
-     */
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
-
-    /*
-     *  Allocate a 32K memory window.  Note that the struct pcmcia_device
-     *  structure provides space for one window handle -- if your
-     *  device needs several windows, you'll need to keep track of
-     *  the handles in your private data structure, dev->priv.
-     */
-    DEBUG(1, "Setting mem speed of %d\n", mem_speed);
-
-    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
-    req.Base = 0; req.Size = 0x8000;
-    req.AccessSpeed = mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
-    mem.CardOffset = 0x20000; mem.Page = 0; 
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
-
-    /* Store base address of the common window frame */
-    ramBase = ioremap(req.Base, 0x8000);
-    priv->ramBase = ramBase;
-
-    dev->irq = link->irq.AssignedIRQ;
-    dev->base_addr = link->io.BasePort1;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
-
-    if (register_netdev(dev) != 0) {
-	printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
-	goto failed;
-    }
-
-    strcpy(priv->node.dev_name, dev->name);
-    link->dev_node = &priv->node;
-
-    /* Reset card before reading physical address */
-    netwave_doreset(dev->base_addr, ramBase);
-
-    /* Read the ethernet address and fill in the Netwave registers. */
-    for (i = 0; i < 6; i++) 
-	dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
-
-    printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
-	   "id %c%c, hw_addr %pM\n",
-	   dev->name, dev->base_addr, dev->irq,
-	   (u_long) ramBase,
-	   (int) readb(ramBase+NETWAVE_EREG_NI),
-	   (int) readb(ramBase+NETWAVE_EREG_NI+1),
-	   dev->dev_addr);
-
-    /* get revision words */
-    printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", 
-	   get_uint16(ramBase + NETWAVE_EREG_ARW),
-	   get_uint16(ramBase + NETWAVE_EREG_ARW+2));
-    return 0;
-
-cs_failed:
-    cs_error(link, last_fn, last_ret);
-failed:
-    netwave_release(link);
-    return -ENODEV;
-} /* netwave_pcmcia_config */
-
-/*
- * Function netwave_release (arg)
- *
- *    After a card is removed, netwave_release() will unregister the net
- *    device, and release the PCMCIA configuration.  If the device is
- *    still open, this will be postponed until it is closed.
- */
-static void netwave_release(struct pcmcia_device *link)
-{
-	struct net_device *dev = link->priv;
-	netwave_private *priv = netdev_priv(dev);
-
-	DEBUG(0, "netwave_release(0x%p)\n", link);
-
-	pcmcia_disable_device(link);
-	if (link->win)
-		iounmap(priv->ramBase);
-}
-
-static int netwave_suspend(struct pcmcia_device *link)
-{
-	struct net_device *dev = link->priv;
-
-	if (link->open)
-		netif_device_detach(dev);
-
-	return 0;
-}
-
-static int netwave_resume(struct pcmcia_device *link)
-{
-	struct net_device *dev = link->priv;
-
-	if (link->open) {
-		netwave_reset(dev);
-		netif_device_attach(dev);
-	}
-
-	return 0;
-}
-
-
-/*
- * Function netwave_doreset (ioBase, ramBase)
- *
- *    Proper hardware reset of the card.
- */
-static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase)
-{
-    /* Reset card */
-    wait_WOC(ioBase);
-    outb(0x80, ioBase + NETWAVE_REG_PMR);
-    writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
-    outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
-}
-
-/*
- * Function netwave_reset (dev)
- *
- *    Reset and restore all of the netwave registers 
- */
-static void netwave_reset(struct net_device *dev) {
-    /* u_char state; */
-    netwave_private *priv = netdev_priv(dev);
-    u_char __iomem *ramBase = priv->ramBase;
-    unsigned int iobase = dev->base_addr;
-
-    DEBUG(0, "netwave_reset: Done with hardware reset\n");
-
-    priv->timeoutCounter = 0;
-
-    /* Reset card */
-    netwave_doreset(iobase, ramBase);
-    printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
-	
-    /* Write a NOP to check the card */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
-	
-    /* Set receive conf */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
-    
-    /* Set transmit conf */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
-    
-    /* Now set the MU Domain */
-    printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
-    writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-	
-    /* Set scramble key */
-    printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
-    writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-
-    /* Enable interrupts, bit 4 high to keep unused
-     * source from interrupting us, bit 2 high to 
-     * set interrupt enable, 567 to enable TxDN, 
-     * RxErr and RxRdy
-     */
-    wait_WOC(iobase);
-    outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
-
-    /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
-     * waitWOC
-     * skriv 80 til d000:3688
-     * sjekk om det ble 80
-     */
-    
-    /* Enable Receiver */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
-	
-    /* Set the IENA bit in COR */
-    wait_WOC(iobase);
-    outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
-}
-
-/*
- * Function netwave_hw_xmit (data, len, dev)    
- */
-static int netwave_hw_xmit(unsigned char* data, int len,
-			   struct net_device* dev) {
-    unsigned long flags;
-    unsigned int TxFreeList,
-	         curBuff,
-	         MaxData, 
-                 DataOffset;
-    int tmpcount; 
-	
-    netwave_private *priv = netdev_priv(dev);
-    u_char __iomem * ramBase = priv->ramBase;
-    unsigned int iobase = dev->base_addr;
-
-    /* Disable interrupts & save flags */
-    spin_lock_irqsave(&priv->spinlock, flags);
-
-    /* Check if there are transmit buffers available */
-    wait_WOC(iobase);
-    if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
-	/* No buffers available */
-	printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
-	       dev->name);
-	spin_unlock_irqrestore(&priv->spinlock, flags);
-	return 1;
-    }
-
-    dev->stats.tx_bytes += len;
-
-    DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
-	  readb(ramBase + NETWAVE_EREG_SPCQ),
-	  readb(ramBase + NETWAVE_EREG_SPU),
-	  readb(ramBase + NETWAVE_EREG_LIF),
-	  readb(ramBase + NETWAVE_EREG_ISPLQ));
-
-    /* Now try to insert it into the adapters free memory */
-    wait_WOC(iobase);
-    TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
-    MaxData    = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
-    DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
-	
-    DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
-	  TxFreeList, MaxData, DataOffset);
-
-    /* Copy packet to the adapter fragment buffers */
-    curBuff = TxFreeList; 
-    tmpcount = 0; 
-    while (tmpcount < len) {
-	int tmplen = len - tmpcount; 
-	copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount, 
-		   (tmplen < MaxData) ? tmplen : MaxData);
-	tmpcount += MaxData;
-			
-	/* Advance to next buffer */
-	curBuff = get_uint16(ramBase + curBuff);
-    }
-    
-    /* Now issue transmit list */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
-    writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
-
-    spin_unlock_irqrestore(&priv->spinlock, flags);
-    return 0;
-}
-
-static netdev_tx_t netwave_start_xmit(struct sk_buff *skb,
-					    struct net_device *dev) {
-	/* This flag indicate that the hardware can't perform a transmission.
-	 * Theoritically, NET3 check it before sending a packet to the driver,
-	 * but in fact it never do that and pool continuously.
-	 * As the watchdog will abort too long transmissions, we are quite safe...
-	 */
-
-    netif_stop_queue(dev);
-
-    {
-	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-	unsigned char* buf = skb->data;
-	
-	if (netwave_hw_xmit( buf, length, dev) == 1) {
-	    /* Some error, let's make them call us another time? */
-	    netif_start_queue(dev);
-	}
-	dev->trans_start = jiffies;
-    }
-    dev_kfree_skb(skb);
-    
-    return NETDEV_TX_OK;
-} /* netwave_start_xmit */
-
-/*
- * Function netwave_interrupt (irq, dev_id)
- *
- *    This function is the interrupt handler for the Netwave card. This
- *    routine will be called whenever: 
- *	  1. A packet is received.
- *	  2. A packet has successfully been transferred and the unit is
- *	     ready to transmit another packet.
- *	  3. A command has completed execution.
- */
-static irqreturn_t netwave_interrupt(int irq, void* dev_id)
-{
-    unsigned int iobase;
-    u_char __iomem *ramBase;
-    struct net_device *dev = (struct net_device *)dev_id;
-    struct netwave_private *priv = netdev_priv(dev);
-    struct pcmcia_device *link = priv->p_dev;
-    int i;
-    
-    if (!netif_device_present(dev))
-	return IRQ_NONE;
-    
-    iobase = dev->base_addr;
-    ramBase = priv->ramBase;
-	
-    /* Now find what caused the interrupt, check while interrupts ready */
-    for (i = 0; i < 10; i++) {
-	u_char status;
-		
-	wait_WOC(iobase);	
-	if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
-	    break; /* None of the interrupt sources asserted (normal exit) */
-	
-        status = inb(iobase + NETWAVE_REG_ASR);
-		
-	if (!pcmcia_dev_present(link)) {
-	    DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
-		  "from removed or suspended card!\n", status);
-	    break;
-	}
-		
-	/* RxRdy */
-	if (status & 0x80) {
-	    netwave_rx(dev);
-	    /* wait_WOC(iobase); */
-	    /* RxRdy cannot be reset directly by the host */
-	}
-	/* RxErr */
-	if (status & 0x40) {
-	    u_char rser;
-			
-	    rser = readb(ramBase + NETWAVE_EREG_RSER);			
-	    
-	    if (rser & 0x04) {
-		++dev->stats.rx_dropped;
-		++dev->stats.rx_crc_errors;
-	    }
-	    if (rser & 0x02)
-		++dev->stats.rx_frame_errors;
-			
-	    /* Clear the RxErr bit in RSER. RSER+4 is the
-	     * write part. Also clear the RxCRC (0x04) and 
-	     * RxBig (0x02) bits if present */
-	    wait_WOC(iobase);
-	    writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
-
-	    /* Write bit 6 high to ASCC to clear RxErr in ASR,
-	     * WOC must be set first! 
-	     */
-	    wait_WOC(iobase);
-	    writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
-
-	    /* Remember to count up dev->stats on error packets */
-	    ++dev->stats.rx_errors;
-	}
-	/* TxDN */
-	if (status & 0x20) {
-	    int txStatus;
-
-	    txStatus = readb(ramBase + NETWAVE_EREG_TSER);
-	    DEBUG(3, "Transmit done. TSER = %x id %x\n", 
-		  txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
-	    
-	    if (txStatus & 0x20) {
-		/* Transmitting was okay, clear bits */
-		wait_WOC(iobase);
-		writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
-		++dev->stats.tx_packets;
-	    }
-			
-	    if (txStatus & 0xd0) {
-		if (txStatus & 0x80) {
-		    ++dev->stats.collisions; /* Because of /proc/net/dev*/
-		    /* ++dev->stats.tx_aborted_errors; */
-		    /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
-		}
-		if (txStatus & 0x40) 
-		    ++dev->stats.tx_carrier_errors;
-		/* 0x80 TxGU Transmit giveup - nine times and no luck
-		 * 0x40 TxNOAP No access point. Discarded packet.
-		 * 0x10 TxErr Transmit error. Always set when 
-		 *      TxGU and TxNOAP is set. (Those are the only ones
-		 *      to set TxErr).
-		 */
-		DEBUG(3, "netwave_interrupt: TxDN with error status %x\n", 
-		      txStatus);
-		
-		/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
-		wait_WOC(iobase);
-		writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
-		++dev->stats.tx_errors;
-	    }
-	    DEBUG(3, "New status is TSER %x ASR %x\n",
-		  readb(ramBase + NETWAVE_EREG_TSER),
-		  inb(iobase + NETWAVE_REG_ASR));
-
-	    netif_wake_queue(dev);
-	}
-	/* TxBA, this would trigger on all error packets received */
-	/* if (status & 0x01) {
-	   DEBUG(4, "Transmit buffers available, %x\n", status);
-	   }
-	   */
-    }
-    /* Handled if we looped at least one time - Jean II */
-    return IRQ_RETVAL(i);
-} /* netwave_interrupt */
-
-/*
- * Function netwave_watchdog (a)
- *
- *    Watchdog : when we start a transmission, we set a timer in the
- *    kernel.  If the transmission complete, this timer is disabled. If
- *    it expire, we reset the card.
- *
- */
-static void netwave_watchdog(struct net_device *dev) {
-
-    DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
-    netwave_reset(dev);
-    dev->trans_start = jiffies;
-    netif_wake_queue(dev);
-} /* netwave_watchdog */
-
-static int netwave_rx(struct net_device *dev)
-{
-    netwave_private *priv = netdev_priv(dev);
-    u_char __iomem *ramBase = priv->ramBase;
-    unsigned int iobase = dev->base_addr;
-    u_char rxStatus;
-    struct sk_buff *skb = NULL;
-    unsigned int curBuffer,
-		rcvList;
-    int rcvLen;
-    int tmpcount = 0;
-    int dataCount, dataOffset;
-    int i;
-    u_char *ptr;
-	
-    DEBUG(3, "xinw_rx: Receiving ... \n");
-
-    /* Receive max 10 packets for now. */
-    for (i = 0; i < 10; i++) {
-	/* Any packets? */
-	wait_WOC(iobase);
-	rxStatus = readb(ramBase + NETWAVE_EREG_RSER);		
-	if ( !( rxStatus & 0x80)) /* No more packets */
-	    break;
-		
-	/* Check if multicast/broadcast or other */
-	/* multicast = (rxStatus & 0x20);  */
-		
-	/* The receive list pointer and length of the packet */
-	wait_WOC(iobase);
-	rcvLen  = get_int16( ramBase + NETWAVE_EREG_RDP);
-	rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
-		
-	if (rcvLen < 0) {
-	    printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n", 
-		   rcvLen);
-	    return 0;
-	}
-		
-	skb = dev_alloc_skb(rcvLen+5);
-	if (skb == NULL) {
-	    DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
-		  "length %d\n", rcvLen);
-	    ++dev->stats.rx_dropped;
-	    /* Tell the adapter to skip the packet */
-	    wait_WOC(iobase);
-	    writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
-	    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
-	    return 0;
-	}
-
-	skb_reserve( skb, 2);  /* Align IP on 16 byte */
-	skb_put( skb, rcvLen);
-
-	/* Copy packet fragments to the skb data area */
-	ptr = (u_char*) skb->data;
-	curBuffer = rcvList;
-	tmpcount = 0; 
-	while ( tmpcount < rcvLen) {
-	    /* Get length and offset of current buffer */
-	    dataCount  = get_uint16( ramBase+curBuffer+2);
-	    dataOffset = get_uint16( ramBase+curBuffer+4);
-		
-	    copy_from_pc( ptr + tmpcount,
-			  ramBase+curBuffer+dataOffset, dataCount);
-
-	    tmpcount += dataCount;
-		
-	    /* Point to next buffer */
-	    curBuffer = get_uint16(ramBase + curBuffer);
-	}
-	
-	skb->protocol = eth_type_trans(skb,dev);
-	/* Queue packet for network layer */
-	netif_rx(skb);
-
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += rcvLen;
-
-	/* Got the packet, tell the adapter to skip it */
-	wait_WOC(iobase);
-	writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
-	writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
-	DEBUG(3, "Packet reception ok\n");
-    }
-    return 0;
-}
-
-static int netwave_open(struct net_device *dev) {
-    netwave_private *priv = netdev_priv(dev);
-    struct pcmcia_device *link = priv->p_dev;
-
-    DEBUG(1, "netwave_open: starting.\n");
-    
-    if (!pcmcia_dev_present(link))
-	return -ENODEV;
-
-    link->open++;
-
-    netif_start_queue(dev);
-    netwave_reset(dev);
-	
-    return 0;
-}
-
-static int netwave_close(struct net_device *dev) {
-    netwave_private *priv = netdev_priv(dev);
-    struct pcmcia_device *link = priv->p_dev;
-
-    DEBUG(1, "netwave_close: finishing.\n");
-
-    link->open--;
-    netif_stop_queue(dev);
-
-    return 0;
-}
-
-static struct pcmcia_device_id netwave_ids[] = {
-	PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
-	PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
-
-static struct pcmcia_driver netwave_driver = {
-	.owner		= THIS_MODULE,
-	.drv		= {
-		.name	= "netwave_cs",
-	},
-	.probe		= netwave_probe,
-	.remove		= netwave_detach,
-	.id_table       = netwave_ids,
-	.suspend	= netwave_suspend,
-	.resume		= netwave_resume,
-};
-
-static int __init init_netwave_cs(void)
-{
-	return pcmcia_register_driver(&netwave_driver);
-}
-
-static void __exit exit_netwave_cs(void)
-{
-	pcmcia_unregister_driver(&netwave_driver);
-}
-
-module_init(init_netwave_cs);
-module_exit(exit_netwave_cs);
-
-/* Set or clear the multicast filter for this adaptor.
-   num_addrs == -1	Promiscuous mode, receive all packets
-   num_addrs == 0	Normal mode, clear multicast list
-   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
-   best-effort filtering.
- */
-static void set_multicast_list(struct net_device *dev)
-{
-    unsigned int iobase = dev->base_addr;
-    netwave_private *priv = netdev_priv(dev);
-    u_char __iomem * ramBase = priv->ramBase;
-    u_char  rcvMode = 0;
-   
-#ifdef PCMCIA_DEBUG
-    if (pc_debug > 2) {
-	static int old;
-	if (old != dev->mc_count) {
-	    old = dev->mc_count;
-	    DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
-		  dev->name, dev->mc_count);
-	}
-    }
-#endif
-	
-    if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
-	/* Multicast Mode */
-	rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
-    } else if (dev->flags & IFF_PROMISC) {
-	/* Promiscous mode */
-	rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
-    } else {
-	/* Normal mode */
-	rcvMode = rxConfRxEna + rxConfBcast;
-    }
-	
-    /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
-    /* Now set receive mode */
-    wait_WOC(iobase);
-    writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
-    writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
-    writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
-}
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/fw.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/fw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/fw.c	2013-05-03 14:02:01.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/fw.c	2013-05-03 12:09:23.000000000 -0400
@@ -28,6 +28,7 @@ static const struct fw_info orinoco_fw[]
 	{ NULL, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", 0, 1024 },
 	{ "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", NULL, 0x00003100, 512 }
 };
+/*(DEBLOBBED)*/
 
 /* Structure used to access fields in FW
  * Make sure LE decoding macros are used
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hermes_dld.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hermes_dld.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hermes_dld.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hermes_dld.c	2010-02-24 13:52:17.000000000 -0500
@@ -427,7 +427,7 @@ int hermesi_program_init(hermes_t *hw, u
 	if (err)
 		return err;
 
-	pr_debug(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
+	pr_debug(PFX "Enabling volatile, EP 0x%08x\n", offset);
 	err = hermes_doicmd_wait(hw,
 				 HERMES_PROGRAM_ENABLE_VOLATILE,
 				 offset & 0xFFFFu,
@@ -550,7 +550,7 @@ static const struct {							\
 
 #define DEFAULT_PDR(pid) default_pdr_data_##pid
 
-/*  HWIF Compatiblity */
+/*  HWIF Compatibility */
 DEFINE_DEFAULT_PDR(0x0005, 10, "\x00\x00\x06\x00\x01\x00\x01\x00\x01\x00");
 
 /* PPPPSign */
@@ -656,7 +656,7 @@ int hermes_apply_pda_with_defaults(herme
 					 record_id + 1, pdi);
 			}
 			break;
-		case 0x5: /*  HWIF Compatiblity */
+		case 0x5: /*  HWIF Compatibility */
 			default_pdi = (struct pdi *) &DEFAULT_PDR(0x0005);
 			break;
 		case 0x108: /* PPPPSign */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hw.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,8 +60,15 @@ static inline fwtype_t determine_firmwar
 /* Set priv->firmware type, determine firmware properties
  * This function can be called before we have registerred with netdev,
  * so all errors go out with dev_* rather than printk
+ *
+ * If non-NULL stores a firmware description in fw_name.
+ * If non-NULL stores a HW version in hw_ver
+ *
+ * These are output via generic cfg80211 ethtool support.
  */
-int determine_fw_capabilities(struct orinoco_private *priv)
+int determine_fw_capabilities(struct orinoco_private *priv,
+			      char *fw_name, size_t fw_name_len,
+			      u32 *hw_ver)
 {
 	struct device *dev = priv->dev;
 	hermes_t *hw = &priv->hw;
@@ -85,6 +92,12 @@ int determine_fw_capabilities(struct ori
 	dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n",
 		 nic_id.id, nic_id.variant, nic_id.major, nic_id.minor);
 
+	if (hw_ver)
+		*hw_ver = (((nic_id.id & 0xff) << 24) |
+			   ((nic_id.variant & 0xff) << 16) |
+			   ((nic_id.major & 0xff) << 8) |
+			   (nic_id.minor & 0xff));
+
 	priv->firmware_type = determine_firmware_type(&nic_id);
 
 	/* Get the firmware version */
@@ -135,8 +148,9 @@ int determine_fw_capabilities(struct ori
 	case FIRMWARE_TYPE_AGERE:
 		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
 		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+		if (fw_name)
+			snprintf(fw_name, fw_name_len, "Lucent/Agere %d.%02d",
+				 sta_id.major, sta_id.minor);
 
 		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
 
@@ -185,8 +199,8 @@ int determine_fw_capabilities(struct ori
 			tmp[SYMBOL_MAX_VER_LEN] = '\0';
 		}
 
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Symbol %s", tmp);
+		if (fw_name)
+			snprintf(fw_name, fw_name_len, "Symbol %s", tmp);
 
 		priv->has_ibss = (firmver >= 0x20000);
 		priv->has_wep = (firmver >= 0x15012);
@@ -224,9 +238,9 @@ int determine_fw_capabilities(struct ori
 		 * different and less well tested */
 		/* D-Link MAC : 00:40:05:* */
 		/* Addtron MAC : 00:90:D1:* */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
-			 sta_id.variant);
+		if (fw_name)
+			snprintf(fw_name, fw_name_len, "Intersil %d.%d.%d",
+				 sta_id.major, sta_id.minor, sta_id.variant);
 
 		firmver = ((unsigned long)sta_id.major << 16) |
 			((unsigned long)sta_id.minor << 8) | sta_id.variant;
@@ -245,7 +259,8 @@ int determine_fw_capabilities(struct ori
 		}
 		break;
 	}
-	dev_info(dev, "Firmware determined as %s\n", priv->fw_name);
+	if (fw_name)
+		dev_info(dev, "Firmware determined as %s\n", fw_name);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hw.h linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,8 @@
 struct orinoco_private;
 struct dev_addr_list;
 
-int determine_fw_capabilities(struct orinoco_private *priv);
+int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name,
+			      size_t fw_name_len, u32 *hw_ver);
 int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr);
 int orinoco_hw_allocate_fid(struct orinoco_private *priv);
 int orinoco_get_bitratemode(int bitrate, int automatic);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,8 +1,10 @@
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
-	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
-	depends on CFG80211
+	depends on (PPC_PMAC || PCI || PCMCIA)
+	depends on CFG80211 && CFG80211_WEXT
 	select WIRELESS_EXT
+	select WEXT_SPY
+	select WEXT_PRIV
 	select FW_LOADER
 	select CRYPTO
 	select CRYPTO_MICHAEL_MIC
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -83,7 +83,6 @@
 #include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/ethtool.h>
 #include <linux/suspend.h>
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
@@ -162,8 +161,6 @@ static const u8 encaps_hdr[] = {0xaa, 0x
 				 | HERMES_EV_WTERR | HERMES_EV_INFO \
 				 | HERMES_EV_INFDROP)
 
-static const struct ethtool_ops orinoco_ethtool_ops;
-
 /********************************************************************/
 /* Data types                                                       */
 /********************************************************************/
@@ -1994,7 +1991,9 @@ int orinoco_init(struct orinoco_private
 		goto out;
 	}
 
-	err = determine_fw_capabilities(priv);
+	err = determine_fw_capabilities(priv, wiphy->fw_version,
+					sizeof(wiphy->fw_version),
+					&wiphy->hw_version);
 	if (err != 0) {
 		dev_err(dev, "Incompatible firmware, aborting\n");
 		goto out;
@@ -2010,7 +2009,9 @@ int orinoco_init(struct orinoco_private
 			priv->do_fw_download = 0;
 
 		/* Check firmware version again */
-		err = determine_fw_capabilities(priv);
+		err = determine_fw_capabilities(priv, wiphy->fw_version,
+						sizeof(wiphy->fw_version),
+						&wiphy->hw_version);
 		if (err != 0) {
 			dev_err(dev, "Incompatible firmware, aborting\n");
 			goto out;
@@ -2212,7 +2213,6 @@ int orinoco_if_add(struct orinoco_privat
 	dev->ieee80211_ptr = wdev;
 	dev->netdev_ops = &orinoco_netdev_ops;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
-	dev->ethtool_ops = &orinoco_ethtool_ops;
 	dev->wireless_handlers = &orinoco_handler_def;
 #ifdef WIRELESS_SPY
 	dev->wireless_data = &priv->wireless_data;
@@ -2225,6 +2225,7 @@ int orinoco_if_add(struct orinoco_privat
 	netif_carrier_off(dev);
 
 	memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
+	memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
 
 	dev->base_addr = base_addr;
 	dev->irq = irq;
@@ -2348,27 +2349,6 @@ void orinoco_down(struct orinoco_private
 }
 EXPORT_SYMBOL(orinoco_down);
 
-static void orinoco_get_drvinfo(struct net_device *dev,
-				struct ethtool_drvinfo *info)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-
-	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
-	strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
-	strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
-	if (dev->dev.parent)
-		strncpy(info->bus_info, dev_name(dev->dev.parent),
-			sizeof(info->bus_info) - 1);
-	else
-		snprintf(info->bus_info, sizeof(info->bus_info) - 1,
-			 "PCMCIA %p", priv->hw.iobase);
-}
-
-static const struct ethtool_ops orinoco_ethtool_ops = {
-	.get_drvinfo = orinoco_get_drvinfo,
-	.get_link = ethtool_op_get_link,
-};
-
 /********************************************************************/
 /* Module initialization                                            */
 /********************************************************************/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *l
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+	priv = alloc_orinocodev(sizeof(*card), &link->dev,
 				orinoco_cs_hard_reset, NULL);
 	if (!priv)
 		return -ENOMEM;
@@ -120,10 +120,8 @@ orinoco_cs_probe(struct pcmcia_device *l
 	link->priv = priv;
 
 	/* Interrupt setup */
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -160,12 +158,6 @@ static void orinoco_cs_detach(struct pcm
  * device available to the system.
  */
 
-#define CS_CHECK(fn, ret) do { \
-	last_fn = (fn); \
-	if ((last_ret = (ret)) != 0) \
-		goto cs_failed; \
-} while (0)
-
 static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
 				   cistpl_cftable_entry_t *cfg,
 				   cistpl_cftable_entry_t *dflt,
@@ -240,7 +232,7 @@ orinoco_cs_config(struct pcmcia_device *
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
 	hermes_t *hw = &priv->hw;
-	int last_fn, last_ret;
+	int ret;
 	void __iomem *mem;
 
 	/*
@@ -257,13 +249,12 @@ orinoco_cs_config(struct pcmcia_device *
 	 * and most client drivers will only use the CIS to fill in
 	 * implementation-defined details.
 	 */
-	last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
-	if (last_ret) {
+	ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
+	if (ret) {
 		if (!ignore_cis_vcc)
 			printk(KERN_ERR PFX "GetNextTuple(): No matching "
 			       "CIS configuration.  Maybe you need the "
 			       "ignore_cis_vcc=1 parameter.\n");
-		cs_error(link, RequestIO, last_ret);
 		goto failed;
 	}
 
@@ -272,14 +263,16 @@ orinoco_cs_config(struct pcmcia_device *
 	 * a handler to the interrupt, unless the 'Handler' member of
 	 * the irq structure is initialized.
 	 */
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
 
 	/* We initialize the hermes structure before completing PCMCIA
 	 * configuration just in case the interrupt handler gets
 	 * called. */
 	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
 	if (!mem)
-		goto cs_failed;
+		goto failed;
 
 	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
@@ -288,8 +281,9 @@ orinoco_cs_config(struct pcmcia_device *
 	 * the I/O windows and the interrupt mapping, and putting the
 	 * card and host interface into "Memory and IO" mode.
 	 */
-	CS_CHECK(RequestConfiguration,
-		 pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	/* Ok, we have the configuration, prepare to register the netdev */
 	card->node.major = card->node.minor = 0;
@@ -315,9 +309,6 @@ orinoco_cs_config(struct pcmcia_device *
 				       * net_device has been registered */
 	return 0;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
-
  failed:
 	orinoco_cs_release(link);
 	return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/orinoco.h linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/orinoco.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/orinoco.h	2010-02-24 13:52:17.000000000 -0500
@@ -93,7 +93,6 @@ struct orinoco_private {
 
 	/* Capabilities of the hardware/firmware */
 	fwtype_t firmware_type;
-	char fw_name[32];
 	int ibss_port;
 	int nicbuf_size;
 	u16 channel_mask;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,9 +73,6 @@ static void spectrum_cs_release(struct p
 #define HCR_MEM16	0x10	/* memory width bit, should be preserved */
 
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /*
  * Reset the card using configuration registers COR and CCSR.
  * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
@@ -83,7 +80,7 @@ static void spectrum_cs_release(struct p
 static int
 spectrum_reset(struct pcmcia_device *link, int idle)
 {
-	int last_ret, last_fn;
+	int ret;
 	conf_reg_t reg;
 	u_int save_cor;
 
@@ -95,23 +92,26 @@ spectrum_reset(struct pcmcia_device *lin
 	reg.Function = 0;
 	reg.Action = CS_READ;
 	reg.Offset = CISREG_COR;
-	CS_CHECK(AccessConfigurationRegister,
-		 pcmcia_access_configuration_register(link, &reg));
+	ret = pcmcia_access_configuration_register(link, &reg);
+	if (ret)
+		goto failed;
 	save_cor = reg.Value;
 
 	/* Soft-Reset card */
 	reg.Action = CS_WRITE;
 	reg.Offset = CISREG_COR;
 	reg.Value = (save_cor | COR_SOFT_RESET);
-	CS_CHECK(AccessConfigurationRegister,
-		 pcmcia_access_configuration_register(link, &reg));
+	ret = pcmcia_access_configuration_register(link, &reg);
+	if (ret)
+		goto failed;
 	udelay(1000);
 
 	/* Read CCSR */
 	reg.Action = CS_READ;
 	reg.Offset = CISREG_CCSR;
-	CS_CHECK(AccessConfigurationRegister,
-		 pcmcia_access_configuration_register(link, &reg));
+	ret = pcmcia_access_configuration_register(link, &reg);
+	if (ret)
+		goto failed;
 
 	/*
 	 * Start or stop the firmware.  Memory width bit should be
@@ -120,21 +120,22 @@ spectrum_reset(struct pcmcia_device *lin
 	reg.Action = CS_WRITE;
 	reg.Offset = CISREG_CCSR;
 	reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
-	CS_CHECK(AccessConfigurationRegister,
-		 pcmcia_access_configuration_register(link, &reg));
+	ret = pcmcia_access_configuration_register(link, &reg);
+	if (ret)
+		goto failed;
 	udelay(1000);
 
 	/* Restore original COR configuration index */
 	reg.Action = CS_WRITE;
 	reg.Offset = CISREG_COR;
 	reg.Value = (save_cor & ~COR_SOFT_RESET);
-	CS_CHECK(AccessConfigurationRegister,
-		 pcmcia_access_configuration_register(link, &reg));
+	ret = pcmcia_access_configuration_register(link, &reg);
+	if (ret)
+		goto failed;
 	udelay(1000);
 	return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
+failed:
 	return -ENODEV;
 }
 
@@ -181,7 +182,7 @@ spectrum_cs_probe(struct pcmcia_device *
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+	priv = alloc_orinocodev(sizeof(*card), &link->dev,
 				spectrum_cs_hard_reset,
 				spectrum_cs_stop_firmware);
 	if (!priv)
@@ -193,10 +194,8 @@ spectrum_cs_probe(struct pcmcia_device *
 	link->priv = priv;
 
 	/* Interrupt setup */
-	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -307,7 +306,7 @@ spectrum_cs_config(struct pcmcia_device
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
 	hermes_t *hw = &priv->hw;
-	int last_fn, last_ret;
+	int ret;
 	void __iomem *mem;
 
 	/*
@@ -324,13 +323,12 @@ spectrum_cs_config(struct pcmcia_device
 	 * and most client drivers will only use the CIS to fill in
 	 * implementation-defined details.
 	 */
-	last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
-	if (last_ret) {
+	ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
+	if (ret) {
 		if (!ignore_cis_vcc)
 			printk(KERN_ERR PFX "GetNextTuple(): No matching "
 			       "CIS configuration.  Maybe you need the "
 			       "ignore_cis_vcc=1 parameter.\n");
-		cs_error(link, RequestIO, last_ret);
 		goto failed;
 	}
 
@@ -339,14 +337,16 @@ spectrum_cs_config(struct pcmcia_device
 	 * a handler to the interrupt, unless the 'Handler' member of
 	 * the irq structure is initialized.
 	 */
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
 
 	/* We initialize the hermes structure before completing PCMCIA
 	 * configuration just in case the interrupt handler gets
 	 * called. */
 	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
 	if (!mem)
-		goto cs_failed;
+		goto failed;
 
 	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
@@ -355,8 +355,9 @@ spectrum_cs_config(struct pcmcia_device
 	 * the I/O windows and the interrupt mapping, and putting the
 	 * card and host interface into "Memory and IO" mode.
 	 */
-	CS_CHECK(RequestConfiguration,
-		 pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	/* Ok, we have the configuration, prepare to register the netdev */
 	card->node.major = card->node.minor = 0;
@@ -386,9 +387,6 @@ spectrum_cs_config(struct pcmcia_device
 				       * net_device has been registered */
 	return 0;
 
- cs_failed:
-	cs_error(link, last_fn, last_ret);
-
  failed:
 	spectrum_cs_release(link);
 	return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/wext.c linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/wext.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/orinoco/wext.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/orinoco/wext.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #define MAX_RID_LEN 1024
 
 /* Helper routine to record keys
- * Do not call from interrupt context */
+ * It is called under orinoco_lock so it may not sleep */
 static int orinoco_set_key(struct orinoco_private *priv, int index,
 			   enum orinoco_alg alg, const u8 *key, int key_len,
 			   const u8 *seq, int seq_len)
@@ -32,14 +32,14 @@ static int orinoco_set_key(struct orinoc
 	kzfree(priv->keys[index].seq);
 
 	if (key_len) {
-		priv->keys[index].key = kzalloc(key_len, GFP_KERNEL);
+		priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC);
 		if (!priv->keys[index].key)
 			goto nomem;
 	} else
 		priv->keys[index].key = NULL;
 
 	if (seq_len) {
-		priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL);
+		priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC);
 		if (!priv->keys[index].seq)
 			goto free_key;
 	} else
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/eeprom.c linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -126,7 +126,7 @@ static int p54_generate_band(struct ieee
 	int ret = -ENOMEM;
 
 	if ((!list->entries) || (!list->band_channel_num[band]))
-		return 0;
+		return -EINVAL;
 
 	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
 	if (!tmp)
@@ -158,6 +158,7 @@ static int p54_generate_band(struct ieee
 			       (list->channels[i].data & CHAN_HAS_CURVE ? "" :
 				" [curve data]"),
 			       list->channels[i].index, list->channels[i].freq);
+			continue;
 		}
 
 		tmp->channels[j].band = list->channels[i].band;
@@ -165,7 +166,16 @@ static int p54_generate_band(struct ieee
 		j++;
 	}
 
-	tmp->n_channels = list->band_channel_num[band];
+	if (j == 0) {
+		printk(KERN_ERR "%s: Disabling totally damaged %s band.\n",
+		       wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ?
+		       "2 GHz" : "5 GHz");
+
+		ret = -ENODATA;
+		goto err_out;
+	}
+
+	tmp->n_channels = j;
 	old = priv->band_table[band];
 	priv->band_table[band] = tmp;
 	if (old) {
@@ -228,13 +238,13 @@ static int p54_generate_channel_lists(st
 	struct p54_common *priv = dev->priv;
 	struct p54_channel_list *list;
 	unsigned int i, j, max_channel_num;
-	int ret = -ENOMEM;
+	int ret = 0;
 	u16 freq;
 
 	if ((priv->iq_autocal_len != priv->curve_data->entries) ||
 	    (priv->iq_autocal_len != priv->output_limit->entries))
-		printk(KERN_ERR "%s: EEPROM is damaged... you may not be able"
-				"to use all channels with this device.\n",
+		printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. "
+				"You may not be able to use all channels.\n",
 				wiphy_name(dev->wiphy));
 
 	max_channel_num = max_t(unsigned int, priv->output_limit->entries,
@@ -243,8 +253,10 @@ static int p54_generate_channel_lists(st
 				priv->curve_data->entries);
 
 	list = kzalloc(sizeof(*list), GFP_KERNEL);
-	if (!list)
+	if (!list) {
+		ret = -ENOMEM;
 		goto free;
+	}
 
 	list->max_entries = max_channel_num;
 	list->channels = kzalloc(sizeof(struct p54_channel_entry) *
@@ -282,13 +294,8 @@ static int p54_generate_channel_lists(st
 	     p54_compare_channels, NULL);
 
 	for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
-		if (list->band_channel_num[i]) {
-			ret = p54_generate_band(dev, list, i);
-			if (ret)
-				goto free;
-
+		if (p54_generate_band(dev, list, i) == 0)
 			j++;
-		}
 	}
 	if (j == 0) {
 		/* no useable band available. */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config P54_COMMON
 	tristate "Softmac Prism54 support"
-	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && EXPERIMENTAL
 	select FW_LOADER
 	---help---
 	  This is common code for isl38xx/stlc45xx based modules.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/main.c	2010-02-24 13:52:17.000000000 -0500
@@ -579,7 +579,7 @@ struct ieee80211_hw *p54_init_common(siz
 	 * For now, disable PS by default because it affects
 	 * link stability significantly.
 	 */
-	dev->wiphy->ps_default = false;
+	dev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
 	mutex_init(&priv->conf_mutex);
 	mutex_init(&priv->eeprom_mutex);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/p54pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 14:03:16.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 12:10:52.000000000 -0400
@@ -197,6 +197,14 @@ static void p54p_check_rx_ring(struct ie
 			i %= ring_limit;
 			continue;
 		}
+
+		if (unlikely(len > priv->common.rx_mtu)) {
+			if (net_ratelimit())
+				dev_err(&priv->pdev->dev, "rx'd frame size "
+					"exceeds length threshold.\n");
+
+			len = priv->common.rx_mtu;
+		}
 		skb_put(skb, len);
 
 		if (p54_rx(dev, skb)) {
@@ -411,7 +419,7 @@ static int p54p_open(struct ieee80211_hw
 	int err;
 
 	init_completion(&priv->boot_comp);
-	err = request_irq(priv->pdev->irq, &p54p_interrupt,
+	err = request_irq(priv->pdev->irq, p54p_interrupt,
 			  IRQF_SHARED, "p54pci", dev);
 	if (err) {
 		dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/isl_ioctl.c linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/isl_ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -1897,7 +1897,7 @@ prism54_get_mac(struct net_device *ndev,
 	return 0;
 }
 
-/* Setting policy also clears the MAC acl, even if we don't change the defaut
+/* Setting policy also clears the MAC acl, even if we don't change the default
  * policy
  */
 
@@ -2323,7 +2323,7 @@ prism54_process_trap_helper(islpci_priva
 
 	case DOT11_OID_BEACON:
 		send_formatted_event(priv,
-				     "Received a beacon from an unkown AP",
+				     "Received a beacon from an unknown AP",
 				     mlme, 0);
 		break;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/islpci_dev.c linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_dev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 14:03:24.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 12:11:00.000000000 -0400
@@ -41,6 +41,7 @@
 #define ISL3877_IMAGE_FILE	"/*(DEBLOBBED)*/"
 #define ISL3886_IMAGE_FILE	"/*(DEBLOBBED)*/"
 #define ISL3890_IMAGE_FILE	"/*(DEBLOBBED)*/"
+/*(DEBLOBBED)*/
 
 static int prism54_bring_down(islpci_private *);
 static int islpci_alloc_memory(islpci_private *);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2010-02-24 13:52:17.000000000 -0500
@@ -181,7 +181,7 @@ prism54_probe(struct pci_dev *pdev, cons
 	isl38xx_disable_interrupts(priv->device_base);
 
 	/* request for the interrupt before uploading the firmware */
-	rvalue = request_irq(pdev->irq, &islpci_interrupt,
+	rvalue = request_irq(pdev->irq, islpci_interrupt,
 			     IRQF_SHARED, ndev->name, priv);
 
 	if (rvalue) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/ray_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/ray_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/ray_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/ray_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,25 +71,7 @@ typedef u_char mac_addr[ETH_ALEN];	/* Ha
 #include "rayctl.h"
 #include "ray_cs.h"
 
-/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
 
-#ifdef RAYLINK_DEBUG
-#define PCMCIA_DEBUG RAYLINK_DEBUG
-#endif
-#ifdef PCMCIA_DEBUG
-static int ray_debug;
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
-#else
-#define DEBUG(n, args...)
-#endif
 /** Prototypes based on PCMCIA skeleton driver *******************************/
 static int ray_config(struct pcmcia_device *link);
 static void ray_release(struct pcmcia_device *link);
@@ -325,7 +307,7 @@ static int ray_probe(struct pcmcia_devic
 	ray_dev_t *local;
 	struct net_device *dev;
 
-	DEBUG(1, "ray_attach()\n");
+	dev_dbg(&p_dev->dev, "ray_attach()\n");
 
 	/* Allocate space for private device-specific data */
 	dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -341,8 +323,7 @@ static int ray_probe(struct pcmcia_devic
 	p_dev->io.IOAddrLines = 5;
 
 	/* Interrupt setup. For PCMCIA, driver takes what's given */
-	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	p_dev->irq.Handler = &ray_interrupt;
 
 	/* General socket configuration */
@@ -351,13 +332,12 @@ static int ray_probe(struct pcmcia_devic
 	p_dev->conf.ConfigIndex = 1;
 
 	p_dev->priv = dev;
-	p_dev->irq.Instance = dev;
 
 	local->finder = p_dev;
 	local->card_status = CARD_INSERTED;
 	local->authentication_state = UNAUTHENTICATED;
 	local->num_multi = 0;
-	DEBUG(2, "ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
+	dev_dbg(&p_dev->dev, "ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
 	      p_dev, dev, local, &ray_interrupt);
 
 	/* Raylink entries in the device structure */
@@ -370,7 +350,7 @@ static int ray_probe(struct pcmcia_devic
 #endif /* WIRELESS_SPY */
 
 
-	DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+	dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
 	netif_stop_queue(dev);
 
 	init_timer(&local->timer);
@@ -393,7 +373,7 @@ static void ray_detach(struct pcmcia_dev
 	struct net_device *dev;
 	ray_dev_t *local;
 
-	DEBUG(1, "ray_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "ray_detach\n");
 
 	this_device = NULL;
 	dev = link->priv;
@@ -408,7 +388,7 @@ static void ray_detach(struct pcmcia_dev
 			unregister_netdev(dev);
 		free_netdev(dev);
 	}
-	DEBUG(2, "ray_cs ray_detach ending\n");
+	dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
 } /* ray_detach */
 
 /*=============================================================================
@@ -416,19 +396,17 @@ static void ray_detach(struct pcmcia_dev
     is received, to configure the PCMCIA socket, and to make the
     ethernet device available to the system.
 =============================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 #define MAX_TUPLE_SIZE 128
 static int ray_config(struct pcmcia_device *link)
 {
-	int last_fn = 0, last_ret = 0;
+	int ret = 0;
 	int i;
 	win_req_t req;
 	memreq_t mem;
 	struct net_device *dev = (struct net_device *)link->priv;
 	ray_dev_t *local = netdev_priv(dev);
 
-	DEBUG(1, "ray_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "ray_config\n");
 
 	/* Determine card type and firmware version */
 	printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
@@ -440,14 +418,17 @@ static int ray_config(struct pcmcia_devi
 	/* Now allocate an interrupt line.  Note that this does not
 	   actually assign a handler to the interrupt.
 	 */
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
 	dev->irq = link->irq.AssignedIRQ;
 
 	/* This actually configures the PCMCIA socket -- setting up
 	   the I/O windows and the interrupt mapping.
 	 */
-	CS_CHECK(RequestConfiguration,
-		 pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 /*** Set up 32k window for shared memory (transmit and control) ************/
 	req.Attributes =
@@ -455,10 +436,14 @@ static int ray_config(struct pcmcia_devi
 	req.Base = 0;
 	req.Size = 0x8000;
 	req.AccessSpeed = ray_mem_speed;
-	CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+	ret = pcmcia_request_window(link, &req, &link->win);
+	if (ret)
+		goto failed;
 	mem.CardOffset = 0x0000;
 	mem.Page = 0;
-	CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+	ret = pcmcia_map_mem_page(link, link->win, &mem);
+	if (ret)
+		goto failed;
 	local->sram = ioremap(req.Base, req.Size);
 
 /*** Set up 16k window for shared memory (receive buffer) ***************/
@@ -467,11 +452,14 @@ static int ray_config(struct pcmcia_devi
 	req.Base = 0;
 	req.Size = 0x4000;
 	req.AccessSpeed = ray_mem_speed;
-	CS_CHECK(RequestWindow,
-		 pcmcia_request_window(&link, &req, &local->rmem_handle));
+	ret = pcmcia_request_window(link, &req, &local->rmem_handle);
+	if (ret)
+		goto failed;
 	mem.CardOffset = 0x8000;
 	mem.Page = 0;
-	CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+	ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem);
+	if (ret)
+		goto failed;
 	local->rmem = ioremap(req.Base, req.Size);
 
 /*** Set up window for attribute memory ***********************************/
@@ -480,22 +468,25 @@ static int ray_config(struct pcmcia_devi
 	req.Base = 0;
 	req.Size = 0x1000;
 	req.AccessSpeed = ray_mem_speed;
-	CS_CHECK(RequestWindow,
-		 pcmcia_request_window(&link, &req, &local->amem_handle));
+	ret = pcmcia_request_window(link, &req, &local->amem_handle);
+	if (ret)
+		goto failed;
 	mem.CardOffset = 0x0000;
 	mem.Page = 0;
-	CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+	ret = pcmcia_map_mem_page(link, local->amem_handle, &mem);
+	if (ret)
+		goto failed;
 	local->amem = ioremap(req.Base, req.Size);
 
-	DEBUG(3, "ray_config sram=%p\n", local->sram);
-	DEBUG(3, "ray_config rmem=%p\n", local->rmem);
-	DEBUG(3, "ray_config amem=%p\n", local->amem);
+	dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
+	dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
+	dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem);
 	if (ray_init(dev) < 0) {
 		ray_release(link);
 		return -ENODEV;
 	}
 
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
+	SET_NETDEV_DEV(dev, &link->dev);
 	i = register_netdev(dev);
 	if (i != 0) {
 		printk("ray_config register_netdev() failed\n");
@@ -511,9 +502,7 @@ static int ray_config(struct pcmcia_devi
 
 	return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
-
+failed:
 	ray_release(link);
 	return -ENODEV;
 } /* ray_config */
@@ -543,9 +532,9 @@ static int ray_init(struct net_device *d
 	struct ccs __iomem *pccs;
 	ray_dev_t *local = netdev_priv(dev);
 	struct pcmcia_device *link = local->finder;
-	DEBUG(1, "ray_init(0x%p)\n", dev);
+	dev_dbg(&link->dev, "ray_init(0x%p)\n", dev);
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(0, "ray_init - device not present\n");
+		dev_dbg(&link->dev, "ray_init - device not present\n");
 		return -1;
 	}
 
@@ -567,13 +556,13 @@ static int ray_init(struct net_device *d
 	local->fw_ver = local->startup_res.firmware_version[0];
 	local->fw_bld = local->startup_res.firmware_version[1];
 	local->fw_var = local->startup_res.firmware_version[2];
-	DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver,
+	dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver,
 	      local->fw_bld);
 
 	local->tib_length = 0x20;
 	if ((local->fw_ver == 5) && (local->fw_bld >= 30))
 		local->tib_length = local->startup_res.tib_length;
-	DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length);
+	dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length);
 	/* Initialize CCS's to buffer free state */
 	pccs = ccs_base(local);
 	for (i = 0; i < NUMBER_OF_CCS; i++) {
@@ -592,7 +581,7 @@ static int ray_init(struct net_device *d
 
 	clear_interrupt(local);	/* Clear any interrupt from the card */
 	local->card_status = CARD_AWAITING_PARAM;
-	DEBUG(2, "ray_init ending\n");
+	dev_dbg(&link->dev, "ray_init ending\n");
 	return 0;
 } /* ray_init */
 
@@ -605,9 +594,9 @@ static int dl_startup_params(struct net_
 	struct ccs __iomem *pccs;
 	struct pcmcia_device *link = local->finder;
 
-	DEBUG(1, "dl_startup_params entered\n");
+	dev_dbg(&link->dev, "dl_startup_params entered\n");
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+		dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n");
 		return -1;
 	}
 
@@ -625,7 +614,7 @@ static int dl_startup_params(struct net_
 	local->dl_param_ccs = ccsindex;
 	pccs = ccs_base(local) + ccsindex;
 	writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
-	DEBUG(2, "dl_startup_params start ccsindex = %d\n",
+	dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n",
 	      local->dl_param_ccs);
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
@@ -641,7 +630,7 @@ static int dl_startup_params(struct net_
 	local->timer.data = (long)local;
 	local->timer.function = &verify_dl_startup;
 	add_timer(&local->timer);
-	DEBUG(2,
+	dev_dbg(&link->dev,
 	      "ray_cs dl_startup_params started timer for verify_dl_startup\n");
 	return 0;
 } /* dl_startup_params */
@@ -717,11 +706,11 @@ static void verify_dl_startup(u_long dat
 	struct pcmcia_device *link = local->finder;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+		dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n");
 		return;
 	}
-#ifdef PCMCIA_DEBUG
-	if (pc_debug > 2) {
+#if 0
+	{
 		int i;
 		printk(KERN_DEBUG
 		       "verify_dl_startup parameters sent via ccs %d:\n",
@@ -760,7 +749,7 @@ static void start_net(u_long data)
 	int ccsindex;
 	struct pcmcia_device *link = local->finder;
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs start_net - device not present\n");
+		dev_dbg(&link->dev, "ray_cs start_net - device not present\n");
 		return;
 	}
 	/* Fill in the CCS fields for the ECF */
@@ -771,7 +760,7 @@ static void start_net(u_long data)
 	writeb(0, &pccs->var.start_network.update_param);
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(1, "ray start net failed - card not ready for intr\n");
+		dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 		return;
 	}
@@ -790,7 +779,7 @@ static void join_net(u_long data)
 	struct pcmcia_device *link = local->finder;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs join_net - device not present\n");
+		dev_dbg(&link->dev, "ray_cs join_net - device not present\n");
 		return;
 	}
 	/* Fill in the CCS fields for the ECF */
@@ -802,7 +791,7 @@ static void join_net(u_long data)
 	writeb(0, &pccs->var.join_network.net_initiated);
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(1, "ray join net failed - card not ready for intr\n");
+		dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 		return;
 	}
@@ -821,7 +810,7 @@ static void ray_release(struct pcmcia_de
 	ray_dev_t *local = netdev_priv(dev);
 	int i;
 
-	DEBUG(1, "ray_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "ray_release\n");
 
 	del_timer(&local->timer);
 
@@ -829,15 +818,15 @@ static void ray_release(struct pcmcia_de
 	iounmap(local->rmem);
 	iounmap(local->amem);
 	/* Do bother checking to see if these succeed or not */
-	i = pcmcia_release_window(local->amem_handle);
+	i = pcmcia_release_window(link, local->amem_handle);
 	if (i != 0)
-		DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
-	i = pcmcia_release_window(local->rmem_handle);
+		dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i);
+	i = pcmcia_release_window(link, local->rmem_handle);
 	if (i != 0)
-		DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+		dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i);
 	pcmcia_disable_device(link);
 
-	DEBUG(2, "ray_release ending\n");
+	dev_dbg(&link->dev, "ray_release ending\n");
 }
 
 static int ray_suspend(struct pcmcia_device *link)
@@ -871,9 +860,9 @@ static int ray_dev_init(struct net_devic
 	ray_dev_t *local = netdev_priv(dev);
 	struct pcmcia_device *link = local->finder;
 
-	DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+	dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev);
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_dev_init - device not present\n");
+		dev_dbg(&link->dev, "ray_dev_init - device not present\n");
 		return -1;
 	}
 #ifdef RAY_IMMEDIATE_INIT
@@ -887,7 +876,7 @@ static int ray_dev_init(struct net_devic
 	/* Postpone the card init so that we can still configure the card,
 	 * for example using the Wireless Extensions. The init will happen
 	 * in ray_open() - Jean II */
-	DEBUG(1,
+	dev_dbg(&link->dev,
 	      "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
 	      local->card_status);
 #endif /* RAY_IMMEDIATE_INIT */
@@ -896,7 +885,7 @@ static int ray_dev_init(struct net_devic
 	memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
 	memset(dev->broadcast, 0xff, ETH_ALEN);
 
-	DEBUG(2, "ray_dev_init ending\n");
+	dev_dbg(&link->dev, "ray_dev_init ending\n");
 	return 0;
 }
 
@@ -906,9 +895,9 @@ static int ray_dev_config(struct net_dev
 	ray_dev_t *local = netdev_priv(dev);
 	struct pcmcia_device *link = local->finder;
 	/* Dummy routine to satisfy device structure */
-	DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
+	dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_dev_config - device not present\n");
+		dev_dbg(&link->dev, "ray_dev_config - device not present\n");
 		return -1;
 	}
 
@@ -924,14 +913,14 @@ static netdev_tx_t ray_dev_start_xmit(st
 	short length = skb->len;
 
 	if (!pcmcia_dev_present(link)) {
-		DEBUG(2, "ray_dev_start_xmit - device not present\n");
+		dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n");
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
-	DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
+	dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
 	if (local->authentication_state == NEED_TO_AUTH) {
-		DEBUG(0, "ray_cs Sending authentication request.\n");
+		dev_dbg(&link->dev, "ray_cs Sending authentication request.\n");
 		if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
 			local->authentication_state = AUTHENTICATED;
 			netif_stop_queue(dev);
@@ -971,7 +960,7 @@ static int ray_hw_xmit(unsigned char *da
 	struct tx_msg __iomem *ptx;	/* Address of xmit buffer in PC space */
 	short int addr;		/* Address of xmit buffer in card space */
 
-	DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
+	pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
 	if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
 		printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
 		       len);
@@ -979,9 +968,9 @@ static int ray_hw_xmit(unsigned char *da
 	}
 	switch (ccsindex = get_free_tx_ccs(local)) {
 	case ECCSBUSY:
-		DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
+		pr_debug("ray_hw_xmit tx_ccs table busy\n");
 	case ECCSFULL:
-		DEBUG(2, "ray_hw_xmit No free tx ccs\n");
+		pr_debug("ray_hw_xmit No free tx ccs\n");
 	case ECARDGONE:
 		netif_stop_queue(dev);
 		return XMIT_NO_CCS;
@@ -1018,12 +1007,12 @@ static int ray_hw_xmit(unsigned char *da
 	writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
 	writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
 	writeb(0, &pccs->var.tx_request.antenna);
-	DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n",
+	pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n",
 	      local->net_default_tx_rate);
 
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n");
+		pr_debug("ray_hw_xmit failed - ECF not ready for intr\n");
 /* TBD very inefficient to copy packet to buffer, and then not
    send it, but the alternative is to queue the messages and that
    won't be done for a while.  Maybe set tbusy until a CCS is free?
@@ -1040,7 +1029,7 @@ static int translate_frame(ray_dev_t *lo
 {
 	__be16 proto = ((struct ethhdr *)data)->h_proto;
 	if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
-		DEBUG(3, "ray_cs translate_frame DIX II\n");
+		pr_debug("ray_cs translate_frame DIX II\n");
 		/* Copy LLC header to card buffer */
 		memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
 		memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
@@ -1056,9 +1045,9 @@ static int translate_frame(ray_dev_t *lo
 			    len - ETH_HLEN);
 		return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
 	} else { /* already  802 type, and proto is length */
-		DEBUG(3, "ray_cs translate_frame 802\n");
+		pr_debug("ray_cs translate_frame 802\n");
 		if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
-			DEBUG(3, "ray_cs translate_frame evil IPX\n");
+			pr_debug("ray_cs translate_frame evil IPX\n");
 			memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
 			return 0 - ETH_HLEN;
 		}
@@ -1603,7 +1592,7 @@ static int ray_open(struct net_device *d
 	struct pcmcia_device *link;
 	link = local->finder;
 
-	DEBUG(1, "ray_open('%s')\n", dev->name);
+	dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
 
 	if (link->open == 0)
 		local->num_multi = 0;
@@ -1613,7 +1602,7 @@ static int ray_open(struct net_device *d
 	if (local->card_status == CARD_AWAITING_PARAM) {
 		int i;
 
-		DEBUG(1, "ray_open: doing init now !\n");
+		dev_dbg(&link->dev, "ray_open: doing init now !\n");
 
 		/* Download startup parameters */
 		if ((i = dl_startup_params(dev)) < 0) {
@@ -1629,7 +1618,7 @@ static int ray_open(struct net_device *d
 	else
 		netif_start_queue(dev);
 
-	DEBUG(2, "ray_open ending\n");
+	dev_dbg(&link->dev, "ray_open ending\n");
 	return 0;
 } /* end ray_open */
 
@@ -1640,7 +1629,7 @@ static int ray_dev_close(struct net_devi
 	struct pcmcia_device *link;
 	link = local->finder;
 
-	DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+	dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
 
 	link->open--;
 	netif_stop_queue(dev);
@@ -1656,7 +1645,7 @@ static int ray_dev_close(struct net_devi
 /*===========================================================================*/
 static void ray_reset(struct net_device *dev)
 {
-	DEBUG(1, "ray_reset entered\n");
+	pr_debug("ray_reset entered\n");
 	return;
 }
 
@@ -1669,17 +1658,17 @@ static int interrupt_ecf(ray_dev_t *loca
 	struct pcmcia_device *link = local->finder;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+		dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
 		return -1;
 	}
-	DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
+	dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
 
 	while (i &&
 	       (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
 		ECF_INTR_SET))
 		i--;
 	if (i == 0) {
-		DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n");
+		dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
 		return -1;
 	}
 	/* Fill the mailbox, then kick the card */
@@ -1698,12 +1687,12 @@ static int get_free_tx_ccs(ray_dev_t *lo
 	struct pcmcia_device *link = local->finder;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n");
+		dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
 		return ECARDGONE;
 	}
 
 	if (test_and_set_bit(0, &local->tx_ccs_lock)) {
-		DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+		dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
 		return ECCSBUSY;
 	}
 
@@ -1716,7 +1705,7 @@ static int get_free_tx_ccs(ray_dev_t *lo
 		}
 	}
 	local->tx_ccs_lock = 0;
-	DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+	dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
 	return ECCSFULL;
 } /* get_free_tx_ccs */
 
@@ -1730,11 +1719,11 @@ static int get_free_ccs(ray_dev_t *local
 	struct pcmcia_device *link = local->finder;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs get_free_ccs - device not present\n");
+		dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
 		return ECARDGONE;
 	}
 	if (test_and_set_bit(0, &local->ccs_lock)) {
-		DEBUG(1, "ray_cs ccs_lock busy\n");
+		dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
 		return ECCSBUSY;
 	}
 
@@ -1747,7 +1736,7 @@ static int get_free_ccs(ray_dev_t *local
 		}
 	}
 	local->ccs_lock = 0;
-	DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+	dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
 	return ECCSFULL;
 } /* get_free_ccs */
 
@@ -1823,7 +1812,7 @@ static struct net_device_stats *ray_get_
 	struct pcmcia_device *link = local->finder;
 	struct status __iomem *p = local->sram + STATUS_BASE;
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs net_device_stats - device not present\n");
+		dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
 		return &local->stats;
 	}
 	if (readb(&p->mrx_overflow_for_host)) {
@@ -1856,12 +1845,12 @@ static void ray_update_parm(struct net_d
 	struct ccs __iomem *pccs;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_update_parm - device not present\n");
+		dev_dbg(&link->dev, "ray_update_parm - device not present\n");
 		return;
 	}
 
 	if ((ccsindex = get_free_ccs(local)) < 0) {
-		DEBUG(0, "ray_update_parm - No free ccs\n");
+		dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
 		return;
 	}
 	pccs = ccs_base(local) + ccsindex;
@@ -1874,7 +1863,7 @@ static void ray_update_parm(struct net_d
 	}
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+		dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 	}
 }
@@ -1891,12 +1880,12 @@ static void ray_update_multi_list(struct
 	void __iomem *p = local->sram + HOST_TO_ECF_BASE;
 
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_update_multi_list - device not present\n");
+		dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
 		return;
 	} else
-		DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+		dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
 	if ((ccsindex = get_free_ccs(local)) < 0) {
-		DEBUG(1, "ray_update_multi - No free ccs\n");
+		dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
 		return;
 	}
 	pccs = ccs_base(local) + ccsindex;
@@ -1910,7 +1899,7 @@ static void ray_update_multi_list(struct
 		for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
 		     dmip = &dmi->next) {
 			memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
 			      dmi->dmi_addr[0], dmi->dmi_addr[1],
 			      dmi->dmi_addr[2], dmi->dmi_addr[3],
@@ -1921,12 +1910,12 @@ static void ray_update_multi_list(struct
 		if (i > 256 / ADDRLEN)
 			i = 256 / ADDRLEN;
 		writeb((UCHAR) i, &pccs->var);
-		DEBUG(1, "ray_cs update_multi %d addresses in list\n", i);
+		dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
 		/* Interrupt the firmware to process the command */
 		local->num_multi = i;
 	}
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(1,
+		dev_dbg(&link->dev,
 		      "ray_cs update_multi failed - ECF not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 	}
@@ -1938,11 +1927,11 @@ static void set_multicast_list(struct ne
 	ray_dev_t *local = netdev_priv(dev);
 	UCHAR promisc;
 
-	DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev);
+	pr_debug("ray_cs set_multicast_list(%p)\n", dev);
 
 	if (dev->flags & IFF_PROMISC) {
 		if (local->sparm.b5.a_promiscuous_mode == 0) {
-			DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+			pr_debug("ray_cs set_multicast_list promisc on\n");
 			local->sparm.b5.a_promiscuous_mode = 1;
 			promisc = 1;
 			ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1950,7 +1939,7 @@ static void set_multicast_list(struct ne
 		}
 	} else {
 		if (local->sparm.b5.a_promiscuous_mode == 1) {
-			DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+			pr_debug("ray_cs set_multicast_list promisc off\n");
 			local->sparm.b5.a_promiscuous_mode = 0;
 			promisc = 0;
 			ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1984,19 +1973,19 @@ static irqreturn_t ray_interrupt(int irq
 	if (dev == NULL)	/* Note that we want interrupts with dev->start == 0 */
 		return IRQ_NONE;
 
-	DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev);
+	pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
 
 	local = netdev_priv(dev);
 	link = (struct pcmcia_device *)local->finder;
 	if (!pcmcia_dev_present(link)) {
-		DEBUG(2,
-		      "ray_cs interrupt from device not present or suspended.\n");
+		pr_debug(
+			"ray_cs interrupt from device not present or suspended.\n");
 		return IRQ_NONE;
 	}
 	rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
 
 	if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
-		DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+		dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
 		clear_interrupt(local);
 		return IRQ_HANDLED;
 	}
@@ -2008,33 +1997,33 @@ static irqreturn_t ray_interrupt(int irq
 		case CCS_DOWNLOAD_STARTUP_PARAMS:	/* Happens in firmware someday */
 			del_timer(&local->timer);
 			if (status == CCS_COMMAND_COMPLETE) {
-				DEBUG(1,
+				dev_dbg(&link->dev,
 				      "ray_cs interrupt download_startup_parameters OK\n");
 			} else {
-				DEBUG(1,
+				dev_dbg(&link->dev,
 				      "ray_cs interrupt download_startup_parameters fail\n");
 			}
 			break;
 		case CCS_UPDATE_PARAMS:
-			DEBUG(1, "ray_cs interrupt update params done\n");
+			dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
 			if (status != CCS_COMMAND_COMPLETE) {
 				tmp =
 				    readb(&pccs->var.update_param.
 					  failure_cause);
-				DEBUG(0,
+				dev_dbg(&link->dev,
 				      "ray_cs interrupt update params failed - reason %d\n",
 				      tmp);
 			}
 			break;
 		case CCS_REPORT_PARAMS:
-			DEBUG(1, "ray_cs interrupt report params done\n");
+			dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
 			break;
 		case CCS_UPDATE_MULTICAST_LIST:	/* Note that this CCS isn't returned */
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_cs interrupt CCS Update Multicast List done\n");
 			break;
 		case CCS_UPDATE_POWER_SAVINGS_MODE:
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_cs interrupt update power save mode done\n");
 			break;
 		case CCS_START_NETWORK:
@@ -2043,11 +2032,11 @@ static irqreturn_t ray_interrupt(int irq
 				if (readb
 				    (&pccs->var.start_network.net_initiated) ==
 				    1) {
-					DEBUG(0,
+					dev_dbg(&link->dev,
 					      "ray_cs interrupt network \"%s\" started\n",
 					      local->sparm.b4.a_current_ess_id);
 				} else {
-					DEBUG(0,
+					dev_dbg(&link->dev,
 					      "ray_cs interrupt network \"%s\" joined\n",
 					      local->sparm.b4.a_current_ess_id);
 				}
@@ -2075,12 +2064,12 @@ static irqreturn_t ray_interrupt(int irq
 				local->timer.expires = jiffies + HZ * 5;
 				local->timer.data = (long)local;
 				if (status == CCS_START_NETWORK) {
-					DEBUG(0,
+					dev_dbg(&link->dev,
 					      "ray_cs interrupt network \"%s\" start failed\n",
 					      local->sparm.b4.a_current_ess_id);
 					local->timer.function = &start_net;
 				} else {
-					DEBUG(0,
+					dev_dbg(&link->dev,
 					      "ray_cs interrupt network \"%s\" join failed\n",
 					      local->sparm.b4.a_current_ess_id);
 					local->timer.function = &join_net;
@@ -2091,19 +2080,19 @@ static irqreturn_t ray_interrupt(int irq
 		case CCS_START_ASSOCIATION:
 			if (status == CCS_COMMAND_COMPLETE) {
 				local->card_status = CARD_ASSOC_COMPLETE;
-				DEBUG(0, "ray_cs association successful\n");
+				dev_dbg(&link->dev, "ray_cs association successful\n");
 			} else {
-				DEBUG(0, "ray_cs association failed,\n");
+				dev_dbg(&link->dev, "ray_cs association failed,\n");
 				local->card_status = CARD_ASSOC_FAILED;
 				join_net((u_long) local);
 			}
 			break;
 		case CCS_TX_REQUEST:
 			if (status == CCS_COMMAND_COMPLETE) {
-				DEBUG(3,
+				dev_dbg(&link->dev,
 				      "ray_cs interrupt tx request complete\n");
 			} else {
-				DEBUG(1,
+				dev_dbg(&link->dev,
 				      "ray_cs interrupt tx request failed\n");
 			}
 			if (!sniffer)
@@ -2111,21 +2100,21 @@ static irqreturn_t ray_interrupt(int irq
 			netif_wake_queue(dev);
 			break;
 		case CCS_TEST_MEMORY:
-			DEBUG(1, "ray_cs interrupt mem test done\n");
+			dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
 			break;
 		case CCS_SHUTDOWN:
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
 			break;
 		case CCS_DUMP_MEMORY:
-			DEBUG(1, "ray_cs interrupt dump memory done\n");
+			dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
 			break;
 		case CCS_START_TIMER:
-			DEBUG(2,
+			dev_dbg(&link->dev,
 			      "ray_cs interrupt DING - raylink timer expired\n");
 			break;
 		default:
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
 			      rcsindex, cmd);
 		}
@@ -2139,7 +2128,7 @@ static irqreturn_t ray_interrupt(int irq
 			ray_rx(dev, local, prcs);
 			break;
 		case REJOIN_NET_COMPLETE:
-			DEBUG(1, "ray_cs interrupt rejoin net complete\n");
+			dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
 			local->card_status = CARD_ACQ_COMPLETE;
 			/* do we need to clear tx buffers CCS's? */
 			if (local->sparm.b4.a_network_type == ADHOC) {
@@ -2149,7 +2138,7 @@ static irqreturn_t ray_interrupt(int irq
 				memcpy_fromio(&local->bss_id,
 					      prcs->var.rejoin_net_complete.
 					      bssid, ADDRLEN);
-				DEBUG(1,
+				dev_dbg(&link->dev,
 				      "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
 				      local->bss_id[0], local->bss_id[1],
 				      local->bss_id[2], local->bss_id[3],
@@ -2159,15 +2148,15 @@ static irqreturn_t ray_interrupt(int irq
 			}
 			break;
 		case ROAMING_INITIATED:
-			DEBUG(1, "ray_cs interrupt roaming initiated\n");
+			dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
 			netif_stop_queue(dev);
 			local->card_status = CARD_DOING_ACQ;
 			break;
 		case JAPAN_CALL_SIGN_RXD:
-			DEBUG(1, "ray_cs interrupt japan call sign rx\n");
+			dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
 			break;
 		default:
-			DEBUG(1,
+			dev_dbg(&link->dev,
 			      "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
 			      rcsindex,
 			      (unsigned int)readb(&prcs->interrupt_id));
@@ -2186,7 +2175,7 @@ static void ray_rx(struct net_device *de
 	int rx_len;
 	unsigned int pkt_addr;
 	void __iomem *pmsg;
-	DEBUG(4, "ray_rx process rx packet\n");
+	pr_debug("ray_rx process rx packet\n");
 
 	/* Calculate address of packet within Rx buffer */
 	pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
@@ -2199,28 +2188,28 @@ static void ray_rx(struct net_device *de
 	pmsg = local->rmem + pkt_addr;
 	switch (readb(pmsg)) {
 	case DATA_TYPE:
-		DEBUG(4, "ray_rx data type\n");
+		pr_debug("ray_rx data type\n");
 		rx_data(dev, prcs, pkt_addr, rx_len);
 		break;
 	case AUTHENTIC_TYPE:
-		DEBUG(4, "ray_rx authentic type\n");
+		pr_debug("ray_rx authentic type\n");
 		if (sniffer)
 			rx_data(dev, prcs, pkt_addr, rx_len);
 		else
 			rx_authenticate(local, prcs, pkt_addr, rx_len);
 		break;
 	case DEAUTHENTIC_TYPE:
-		DEBUG(4, "ray_rx deauth type\n");
+		pr_debug("ray_rx deauth type\n");
 		if (sniffer)
 			rx_data(dev, prcs, pkt_addr, rx_len);
 		else
 			rx_deauthenticate(local, prcs, pkt_addr, rx_len);
 		break;
 	case NULL_MSG_TYPE:
-		DEBUG(3, "ray_cs rx NULL msg\n");
+		pr_debug("ray_cs rx NULL msg\n");
 		break;
 	case BEACON_TYPE:
-		DEBUG(4, "ray_rx beacon type\n");
+		pr_debug("ray_rx beacon type\n");
 		if (sniffer)
 			rx_data(dev, prcs, pkt_addr, rx_len);
 
@@ -2233,7 +2222,7 @@ static void ray_rx(struct net_device *de
 		ray_get_stats(dev);
 		break;
 	default:
-		DEBUG(0, "ray_cs unknown pkt type %2x\n",
+		pr_debug("ray_cs unknown pkt type %2x\n",
 		      (unsigned int)readb(pmsg));
 		break;
 	}
@@ -2262,7 +2251,7 @@ static void rx_data(struct net_device *d
 			    rx_len >
 			    (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
 			     FCS_LEN)) {
-				DEBUG(0,
+				pr_debug(
 				      "ray_cs invalid packet length %d received \n",
 				      rx_len);
 				return;
@@ -2273,17 +2262,17 @@ static void rx_data(struct net_device *d
 			    rx_len >
 			    (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
 			     FCS_LEN)) {
-				DEBUG(0,
+				pr_debug(
 				      "ray_cs invalid packet length %d received \n",
 				      rx_len);
 				return;
 			}
 		}
 	}
-	DEBUG(4, "ray_cs rx_data packet\n");
+	pr_debug("ray_cs rx_data packet\n");
 	/* If fragmented packet, verify sizes of fragments add up */
 	if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
-		DEBUG(1, "ray_cs rx'ed fragment\n");
+		pr_debug("ray_cs rx'ed fragment\n");
 		tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
 		    + readb(&prcs->var.rx_packet.totalpacketlength[1]);
 		total_len = tmp;
@@ -2301,7 +2290,7 @@ static void rx_data(struct net_device *d
 		} while (1);
 
 		if (tmp < 0) {
-			DEBUG(0,
+			pr_debug(
 			      "ray_cs rx_data fragment lengths don't add up\n");
 			local->stats.rx_dropped++;
 			release_frag_chain(local, prcs);
@@ -2313,7 +2302,7 @@ static void rx_data(struct net_device *d
 
 	skb = dev_alloc_skb(total_len + 5);
 	if (skb == NULL) {
-		DEBUG(0, "ray_cs rx_data could not allocate skb\n");
+		pr_debug("ray_cs rx_data could not allocate skb\n");
 		local->stats.rx_dropped++;
 		if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
 			release_frag_chain(local, prcs);
@@ -2321,7 +2310,7 @@ static void rx_data(struct net_device *d
 	}
 	skb_reserve(skb, 2);	/* Align IP on 16 byte (TBD check this) */
 
-	DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
+	pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
 	      rx_len);
 
 /************************/
@@ -2354,7 +2343,7 @@ static void rx_data(struct net_device *d
 	tmp = 17;
 	if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
 		prcslink = prcs;
-		DEBUG(1, "ray_cs rx_data in fragment loop\n");
+		pr_debug("ray_cs rx_data in fragment loop\n");
 		do {
 			prcslink = rcs_base(local)
 			    +
@@ -2426,8 +2415,8 @@ static void untranslate(ray_dev_t *local
 	memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
 	memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
 
-#ifdef PCMCIA_DEBUG
-	if (pc_debug > 3) {
+#if 0
+	if {
 		print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
 			       DUMP_PREFIX_NONE, 16, 1,
 			       skb->data, 64, true);
@@ -2441,7 +2430,7 @@ static void untranslate(ray_dev_t *local
 
 	if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
 		/* not a snap type so leave it alone */
-		DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+		pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
 		      psnap->dsap, psnap->ssap, psnap->ctrl);
 
 		delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
@@ -2450,7 +2439,7 @@ static void untranslate(ray_dev_t *local
 	} else { /* Its a SNAP */
 		if (memcmp(psnap->org, org_bridge, 3) == 0) {
 		/* EtherII and nuke the LLC */
-			DEBUG(3, "ray_cs untranslate Bridge encap\n");
+			pr_debug("ray_cs untranslate Bridge encap\n");
 			delta = RX_MAC_HEADER_LENGTH
 			    + sizeof(struct snaphdr_t) - ETH_HLEN;
 			peth = (struct ethhdr *)(skb->data + delta);
@@ -2459,14 +2448,14 @@ static void untranslate(ray_dev_t *local
 			switch (ntohs(type)) {
 			case ETH_P_IPX:
 			case ETH_P_AARP:
-				DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n");
+				pr_debug("ray_cs untranslate RFC IPX/AARP\n");
 				delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
 				peth = (struct ethhdr *)(skb->data + delta);
 				peth->h_proto =
 				    htons(len - RX_MAC_HEADER_LENGTH);
 				break;
 			default:
-				DEBUG(3, "ray_cs untranslate RFC default\n");
+				pr_debug("ray_cs untranslate RFC default\n");
 				delta = RX_MAC_HEADER_LENGTH +
 				    sizeof(struct snaphdr_t) - ETH_HLEN;
 				peth = (struct ethhdr *)(skb->data + delta);
@@ -2482,12 +2471,12 @@ static void untranslate(ray_dev_t *local
 	}
 /* TBD reserve  skb_reserve(skb, delta); */
 	skb_pull(skb, delta);
-	DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta,
+	pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
 	      skb->data);
 	memcpy(peth->h_dest, destaddr, ADDRLEN);
 	memcpy(peth->h_source, srcaddr, ADDRLEN);
-#ifdef PCMCIA_DEBUG
-	if (pc_debug > 3) {
+#if 0
+	{
 		int i;
 		printk(KERN_DEBUG "skb->data after untranslate:");
 		for (i = 0; i < 64; i++)
@@ -2529,7 +2518,7 @@ static void release_frag_chain(ray_dev_t
 	while (tmp--) {
 		writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
 		if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
-			DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n",
+			pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
 			      rcsindex);
 			break;
 		}
@@ -2543,9 +2532,9 @@ static void release_frag_chain(ray_dev_t
 static void authenticate(ray_dev_t *local)
 {
 	struct pcmcia_device *link = local->finder;
-	DEBUG(0, "ray_cs Starting authentication.\n");
+	dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs authenticate - device not present\n");
+		dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
 		return;
 	}
 
@@ -2573,11 +2562,11 @@ static void rx_authenticate(ray_dev_t *l
 	copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
 	/* if we are trying to get authenticated */
 	if (local->sparm.b4.a_network_type == ADHOC) {
-		DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
+		pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
 		      msg->var[0], msg->var[1], msg->var[2], msg->var[3],
 		      msg->var[4], msg->var[5]);
 		if (msg->var[2] == 1) {
-			DEBUG(0, "ray_cs Sending authentication response.\n");
+			pr_debug("ray_cs Sending authentication response.\n");
 			if (!build_auth_frame
 			    (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
 				local->authentication_state = NEED_TO_AUTH;
@@ -2591,13 +2580,13 @@ static void rx_authenticate(ray_dev_t *l
 			/* Verify authentication sequence #2 and success */
 			if (msg->var[2] == 2) {
 				if ((msg->var[3] | msg->var[4]) == 0) {
-					DEBUG(1, "Authentication successful\n");
+					pr_debug("Authentication successful\n");
 					local->card_status = CARD_AUTH_COMPLETE;
 					associate(local);
 					local->authentication_state =
 					    AUTHENTICATED;
 				} else {
-					DEBUG(0, "Authentication refused\n");
+					pr_debug("Authentication refused\n");
 					local->card_status = CARD_AUTH_REFUSED;
 					join_net((u_long) local);
 					local->authentication_state =
@@ -2617,22 +2606,22 @@ static void associate(ray_dev_t *local)
 	struct net_device *dev = link->priv;
 	int ccsindex;
 	if (!(pcmcia_dev_present(link))) {
-		DEBUG(2, "ray_cs associate - device not present\n");
+		dev_dbg(&link->dev, "ray_cs associate - device not present\n");
 		return;
 	}
 	/* If no tx buffers available, return */
 	if ((ccsindex = get_free_ccs(local)) < 0) {
 /* TBD should never be here but... what if we are? */
-		DEBUG(1, "ray_cs associate - No free ccs\n");
+		dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
 		return;
 	}
-	DEBUG(1, "ray_cs Starting association with access point\n");
+	dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
 	pccs = ccs_base(local) + ccsindex;
 	/* fill in the CCS */
 	writeb(CCS_START_ASSOCIATION, &pccs->cmd);
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n");
+		dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 
 		del_timer(&local->timer);
@@ -2655,7 +2644,7 @@ static void rx_deauthenticate(ray_dev_t
 /*  UCHAR buff[256];
     struct rx_msg *msg = (struct rx_msg *)buff;
 */
-	DEBUG(0, "Deauthentication frame received\n");
+	pr_debug("Deauthentication frame received\n");
 	local->authentication_state = UNAUTHENTICATED;
 	/* Need to reauthenticate or rejoin depending on reason code */
 /*  copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
@@ -2823,7 +2812,7 @@ static int build_auth_frame(ray_dev_t *l
 
 	/* If no tx buffers available, return */
 	if ((ccsindex = get_free_tx_ccs(local)) < 0) {
-		DEBUG(1, "ray_cs send authenticate - No free tx ccs\n");
+		pr_debug("ray_cs send authenticate - No free tx ccs\n");
 		return -1;
 	}
 
@@ -2855,7 +2844,7 @@ static int build_auth_frame(ray_dev_t *l
 
 	/* Interrupt the firmware to process the command */
 	if (interrupt_ecf(local, ccsindex)) {
-		DEBUG(1,
+		pr_debug(
 		      "ray_cs send authentication request failed - ECF not ready for intr\n");
 		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 		return -1;
@@ -2865,18 +2854,8 @@ static int build_auth_frame(ray_dev_t *l
 
 /*===========================================================================*/
 #ifdef CONFIG_PROC_FS
-static void raycs_write(const char *name, write_proc_t *w, void *data)
-{
-	struct proc_dir_entry *entry =
-	    create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
-	if (entry) {
-		entry->write_proc = w;
-		entry->data = data;
-	}
-}
-
-static int write_essid(struct file *file, const char __user *buffer,
-		       unsigned long count, void *data)
+static ssize_t ray_cs_essid_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	static char proc_essid[33];
 	unsigned int len = count;
@@ -2890,8 +2869,13 @@ static int write_essid(struct file *file
 	return count;
 }
 
-static int write_int(struct file *file, const char __user *buffer,
-		     unsigned long count, void *data)
+static const struct file_operations ray_cs_essid_proc_fops = {
+	.owner		= THIS_MODULE,
+	.write		= ray_cs_essid_proc_write,
+};
+
+static ssize_t int_proc_write(struct file *file, const char __user *buffer,
+			      size_t count, loff_t *pos)
 {
 	static char proc_number[10];
 	char *p;
@@ -2914,9 +2898,14 @@ static int write_int(struct file *file,
 		nr = nr * 10 + c;
 		p++;
 	} while (--len);
-	*(int *)data = nr;
+	*(int *)PDE(file->f_path.dentry->d_inode)->data = nr;
 	return count;
 }
+
+static const struct file_operations int_proc_fops = {
+	.owner		= THIS_MODULE,
+	.write		= int_proc_write,
+};
 #endif
 
 static struct pcmcia_device_id ray_ids[] = {
@@ -2942,18 +2931,18 @@ static int __init init_ray_cs(void)
 {
 	int rc;
 
-	DEBUG(1, "%s\n", rcsid);
+	pr_debug("%s\n", rcsid);
 	rc = pcmcia_register_driver(&ray_driver);
-	DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+	pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
 	      rc);
 
 #ifdef CONFIG_PROC_FS
 	proc_mkdir("driver/ray_cs", NULL);
 
 	proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
-	raycs_write("driver/ray_cs/essid", write_essid, NULL);
-	raycs_write("driver/ray_cs/net_type", write_int, &net_type);
-	raycs_write("driver/ray_cs/translate", write_int, &translate);
+	proc_create("driver/ray_cs/essid", S_IWUSR, NULL, &ray_cs_essid_proc_fops);
+	proc_create_data("driver/ray_cs/net_type", S_IWUSR, NULL, &int_proc_fops, &net_type);
+	proc_create_data("driver/ray_cs/translate", S_IWUSR, NULL, &int_proc_fops, &translate);
 #endif
 	if (translate != 0)
 		translate = 1;
@@ -2964,7 +2953,7 @@ static int __init init_ray_cs(void)
 
 static void __exit exit_ray_cs(void)
 {
-	DEBUG(0, "ray_cs: cleanup_module\n");
+	pr_debug("ray_cs: cleanup_module\n");
 
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("driver/ray_cs/ray_cs", NULL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rndis_wlan.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rndis_wlan.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rndis_wlan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rndis_wlan.c	2010-02-24 13:52:17.000000000 -0500
@@ -83,11 +83,11 @@ MODULE_PARM_DESC(roamdelta,
 	"set roaming tendency: 0=aggressive, 1=moderate, "
 				"2=conservative (default: moderate)");
 
-static int modparam_workaround_interval = 500;
+static int modparam_workaround_interval;
 module_param_named(workaround_interval, modparam_workaround_interval,
 							int, 0444);
 MODULE_PARM_DESC(workaround_interval,
-	"set stall workaround interval in msecs (default: 500)");
+	"set stall workaround interval in msecs (0=disabled) (default: 0)");
 
 
 /* various RNDIS OID defs */
@@ -733,12 +733,13 @@ static int rndis_query_oid(struct usbnet
 			le32_to_cpu(u.get_c->status));
 
 	if (ret == 0) {
+		memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
+
 		ret = le32_to_cpu(u.get_c->len);
 		if (ret > *len)
 			*len = ret;
-		memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
-		ret = rndis_error_status(u.get_c->status);
 
+		ret = rndis_error_status(u.get_c->status);
 		if (ret < 0)
 			devdbg(dev, "rndis_query_oid(%s): device returned "
 				"error,  0x%08x (%d)", oid_to_string(oid),
@@ -1072,6 +1073,8 @@ static int set_auth_mode(struct usbnet *
 		auth_mode = NDIS_80211_AUTH_SHARED;
 	else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
 		auth_mode = NDIS_80211_AUTH_OPEN;
+	else if (auth_type == NL80211_AUTHTYPE_AUTOMATIC)
+		auth_mode = NDIS_80211_AUTH_AUTO_SWITCH;
 	else
 		return -ENOTSUPP;
 
@@ -2547,7 +2550,7 @@ static void rndis_device_poller(struct w
 	/* Workaround transfer stalls on poor quality links.
 	 * TODO: find right way to fix these stalls (as stalls do not happen
 	 * with ndiswrapper/windows driver). */
-	if (priv->last_qual <= 25) {
+	if (priv->param_workaround_interval > 0 && priv->last_qual <= 25) {
 		/* Decrease stats worker interval to catch stalls.
 		 * faster. Faster than 400-500ms causes packet loss,
 		 * Slower doesn't catch stalls fast enough.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 menuconfig RT2X00
 	tristate "Ralink driver support"
-	depends on MAC80211 && WLAN_80211
+	depends on MAC80211
 	---help---
 	  This will enable the support for the Ralink drivers,
 	  developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
@@ -53,6 +53,36 @@ config RT61PCI
 
 	  When compiled as a module, this driver will be called rt61pci.
 
+config RT2800PCI_PCI
+	tristate
+	depends on PCI
+	default y
+
+config RT2800PCI_SOC
+	tristate
+	depends on RALINK_RT288X || RALINK_RT305X
+	default y
+
+config RT2800PCI
+	tristate "Ralink rt2800 (PCI/PCMCIA) support (VERY EXPERIMENTAL)"
+	depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL
+	select RT2800_LIB
+	select RT2X00_LIB_PCI if RT2800PCI_PCI
+	select RT2X00_LIB_SOC if RT2800PCI_SOC
+	select RT2X00_LIB_HT
+	select RT2X00_LIB_FIRMWARE
+	select RT2X00_LIB_CRYPTO
+	select CRC_CCITT
+	select EEPROM_93CX6
+	---help---
+	  This adds support for rt2800 wireless chipset family.
+	  Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT3052
+
+	  This driver is non-functional at the moment and is intended for
+	  developers.
+
+	  When compiled as a module, this driver will be called "rt2800pci.ko".
+
 config RT2500USB
 	tristate "Ralink rt2500 (USB) support"
 	depends on USB
@@ -78,8 +108,9 @@ config RT73USB
 	  When compiled as a module, this driver will be called rt73usb.
 
 config RT2800USB
-	tristate "Ralink rt2800 (USB) support"
+	tristate "Ralink rt2800 (USB) support (EXPERIMENTAL)"
 	depends on USB && EXPERIMENTAL
+	select RT2800_LIB
 	select RT2X00_LIB_USB
 	select RT2X00_LIB_HT
 	select RT2X00_LIB_FIRMWARE
@@ -89,12 +120,23 @@ config RT2800USB
 	  This adds experimental support for rt2800 wireless chipset family.
 	  Supported chips: RT2770, RT2870 & RT3070.
 
+	  Known issues:
+	  - support for RT2870 chips doesn't work with 802.11n APs yet
+	  - support for RT3070 chips is non-functional at the moment
+
 	  When compiled as a module, this driver will be called "rt2800usb.ko".
 
+config RT2800_LIB
+	tristate
+
 config RT2X00_LIB_PCI
 	tristate
 	select RT2X00_LIB
 
+config RT2X00_LIB_SOC
+	tristate
+	select RT2X00_LIB
+
 config RT2X00_LIB_USB
 	tristate
 	select RT2X00_LIB
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/Makefile linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Makefile
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -11,10 +11,13 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_HT)	+= rt2
 
 obj-$(CONFIG_RT2X00_LIB)		+= rt2x00lib.o
 obj-$(CONFIG_RT2X00_LIB_PCI)		+= rt2x00pci.o
+obj-$(CONFIG_RT2X00_LIB_SOC)		+= rt2x00soc.o
 obj-$(CONFIG_RT2X00_LIB_USB)		+= rt2x00usb.o
+obj-$(CONFIG_RT2800_LIB)		+= rt2800lib.o
 obj-$(CONFIG_RT2400PCI)			+= rt2400pci.o
 obj-$(CONFIG_RT2500PCI)			+= rt2500pci.o
 obj-$(CONFIG_RT61PCI)			+= rt61pci.o
+obj-$(CONFIG_RT2800PCI)			+= rt2800pci.o
 obj-$(CONFIG_RT2500USB)			+= rt2500usb.o
 obj-$(CONFIG_RT73USB)			+= rt73usb.o
 obj-$(CONFIG_RT2800USB)			+= rt2800usb.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -1341,6 +1341,7 @@ static int rt2400pci_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
 	rt2x00_set_chip_rf(rt2x00dev, value, reg);
+	rt2x00_print_chip(rt2x00dev);
 
 	if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
 	    !rt2x00_rf(&rt2x00dev->chip, RF2421)) {
@@ -1431,7 +1432,6 @@ static int rt2400pci_probe_hw_mode(struc
 			       IEEE80211_HW_SIGNAL_DBM |
 			       IEEE80211_HW_SUPPORTS_PS |
 			       IEEE80211_HW_PS_NULLFUNC_STACK;
-	rt2x00dev->hw->extra_tx_headroom = 0;
 
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1622,20 +1622,21 @@ static const struct data_queue_desc rt24
 };
 
 static const struct rt2x00_ops rt2400pci_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 1,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt2400pci_queue_rx,
-	.tx		= &rt2400pci_queue_tx,
-	.bcn		= &rt2400pci_queue_bcn,
-	.atim		= &rt2400pci_queue_atim,
-	.lib		= &rt2400pci_rt2x00_ops,
-	.hw		= &rt2400pci_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 1,
+	.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,
+	.lib			= &rt2400pci_rt2x00_ops,
+	.hw			= &rt2400pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt2400pci_rt2x00debug,
+	.debugfs		= &rt2400pci_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		100
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -1505,6 +1505,7 @@ static int rt2500pci_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
 	rt2x00_set_chip_rf(rt2x00dev, value, reg);
+	rt2x00_print_chip(rt2x00dev);
 
 	if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
 	    !rt2x00_rf(&rt2x00dev->chip, RF2523) &&
@@ -1732,8 +1733,6 @@ static int rt2500pci_probe_hw_mode(struc
 			       IEEE80211_HW_SUPPORTS_PS |
 			       IEEE80211_HW_PS_NULLFUNC_STACK;
 
-	rt2x00dev->hw->extra_tx_headroom = 0;
-
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
 				rt2x00_eeprom_addr(rt2x00dev,
@@ -1921,20 +1920,21 @@ static const struct data_queue_desc rt25
 };
 
 static const struct rt2x00_ops rt2500pci_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 1,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt2500pci_queue_rx,
-	.tx		= &rt2500pci_queue_tx,
-	.bcn		= &rt2500pci_queue_bcn,
-	.atim		= &rt2500pci_queue_atim,
-	.lib		= &rt2500pci_rt2x00_ops,
-	.hw		= &rt2500pci_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 1,
+	.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,
+	.lib			= &rt2500pci_rt2x00_ops,
+	.hw			= &rt2500pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt2500pci_rt2x00debug,
+	.debugfs		= &rt2500pci_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -46,7 +46,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		121
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -716,139 +716,6 @@ static void rt2500usb_reset_tuner(struct
 }
 
 /*
- * NOTE: This function is directly ported from legacy driver, but
- * despite it being declared it was never called. Although link tuning
- * sounds like a good idea, and usually works well for the other drivers,
- * it does _not_ work with rt2500usb. Enabling this function will result
- * in TX capabilities only until association kicks in. Immediately
- * after the successful association all TX frames will be kept in the
- * hardware queue and never transmitted.
- */
-#if 0
-static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
-	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-	u16 bbp_thresh;
-	u16 vgc_bound;
-	u16 sens;
-	u16 r24;
-	u16 r25;
-	u16 r61;
-	u16 r17_sens;
-	u8 r17;
-	u8 up_bound;
-	u8 low_bound;
-
-	/*
-	 * Read current r17 value, as well as the sensitivity values
-	 * for the r17 register.
-	 */
-	rt2500usb_bbp_read(rt2x00dev, 17, &r17);
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound);
-	up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER);
-	low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER);
-
-	/*
-	 * If we are not associated, we should go straight to the
-	 * dynamic CCA tuning.
-	 */
-	if (!rt2x00dev->intf_associated)
-		goto dynamic_cca_tune;
-
-	/*
-	 * Determine the BBP tuning threshold and correctly
-	 * set BBP 24, 25 and 61.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &bbp_thresh);
-	bbp_thresh = rt2x00_get_field16(bbp_thresh, EEPROM_BBPTUNE_THRESHOLD);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &r24);
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &r25);
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &r61);
-
-	if ((rssi + bbp_thresh) > 0) {
-		r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_HIGH);
-		r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_HIGH);
-		r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_HIGH);
-	} else {
-		r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_LOW);
-		r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_LOW);
-		r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_LOW);
-	}
-
-	rt2500usb_bbp_write(rt2x00dev, 24, r24);
-	rt2500usb_bbp_write(rt2x00dev, 25, r25);
-	rt2500usb_bbp_write(rt2x00dev, 61, r61);
-
-	/*
-	 * A too low RSSI will cause too much false CCA which will
-	 * then corrupt the R17 tuning. To remidy this the tuning should
-	 * be stopped (While making sure the R17 value will not exceed limits)
-	 */
-	if (rssi >= -40) {
-		if (r17 != 0x60)
-			rt2500usb_bbp_write(rt2x00dev, 17, 0x60);
-		return;
-	}
-
-	/*
-	 * Special big-R17 for short distance
-	 */
-	if (rssi >= -58) {
-		sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_LOW);
-		if (r17 != sens)
-			rt2500usb_bbp_write(rt2x00dev, 17, sens);
-		return;
-	}
-
-	/*
-	 * Special mid-R17 for middle distance
-	 */
-	if (rssi >= -74) {
-		sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_HIGH);
-		if (r17 != sens)
-			rt2500usb_bbp_write(rt2x00dev, 17, sens);
-		return;
-	}
-
-	/*
-	 * Leave short or middle distance condition, restore r17
-	 * to the dynamic tuning range.
-	 */
-	low_bound = 0x32;
-	if (rssi < -77)
-		up_bound -= (-77 - rssi);
-
-	if (up_bound < low_bound)
-		up_bound = low_bound;
-
-	if (r17 > up_bound) {
-		rt2500usb_bbp_write(rt2x00dev, 17, up_bound);
-		rt2x00dev->link.vgc_level = up_bound;
-		return;
-	}
-
-dynamic_cca_tune:
-
-	/*
-	 * R17 is inside the dynamic tuning range,
-	 * start tuning the link based on the false cca counter.
-	 */
-	if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
-		rt2500usb_bbp_write(rt2x00dev, 17, ++r17);
-		rt2x00dev->link.vgc_level = r17;
-	} else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
-		rt2500usb_bbp_write(rt2x00dev, 17, --r17);
-		rt2x00dev->link.vgc_level = r17;
-	}
-}
-#else
-#define rt2500usb_link_tuner	NULL
-#endif
-
-/*
  * Initialization functions.
  */
 static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
@@ -1542,6 +1409,7 @@ static int rt2500usb_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
+	rt2x00_print_chip(rt2x00dev);
 
 	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) ||
 	    rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
@@ -1788,8 +1656,6 @@ static int rt2500usb_probe_hw_mode(struc
 	    IEEE80211_HW_SUPPORTS_PS |
 	    IEEE80211_HW_PS_NULLFUNC_STACK;
 
-	rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
-
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
 				rt2x00_eeprom_addr(rt2x00dev,
@@ -1910,7 +1776,6 @@ static const struct rt2x00lib_ops rt2500
 	.rfkill_poll		= rt2500usb_rfkill_poll,
 	.link_stats		= rt2500usb_link_stats,
 	.reset_tuner		= rt2500usb_reset_tuner,
-	.link_tuner		= rt2500usb_link_tuner,
 	.write_tx_desc		= rt2500usb_write_tx_desc,
 	.write_tx_data		= rt2x00usb_write_tx_data,
 	.write_beacon		= rt2500usb_write_beacon,
@@ -1956,20 +1821,21 @@ static const struct data_queue_desc rt25
 };
 
 static const struct rt2x00_ops rt2500usb_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 1,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt2500usb_queue_rx,
-	.tx		= &rt2500usb_queue_tx,
-	.bcn		= &rt2500usb_queue_bcn,
-	.atim		= &rt2500usb_queue_atim,
-	.lib		= &rt2500usb_rt2x00_ops,
-	.hw		= &rt2500usb_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 1,
+	.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,
+	.lib			= &rt2500usb_rt2x00_ops,
+	.hw			= &rt2500usb_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt2500usb_rt2x00debug,
+	.debugfs		= &rt2500usb_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -46,7 +46,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1852 @@
+/*
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
+	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
+	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>
+	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>
+	<http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2800
+	Abstract: Data structures and registers for the rt2800 modules.
+	Supported chipsets: RT2800E, RT2800ED & RT2800U.
+ */
+
+#ifndef RT2800_H
+#define RT2800_H
+
+/*
+ * RF chip defines.
+ *
+ * RF2820 2.4G 2T3R
+ * RF2850 2.4G/5G 2T3R
+ * RF2720 2.4G 1T2R
+ * RF2750 2.4G/5G 1T2R
+ * RF3020 2.4G 1T1R
+ * RF2020 2.4G B/G
+ * RF3021 2.4G 1T2R
+ * RF3022 2.4G 2T2R
+ * RF3052 2.4G 2T2R
+ */
+#define RF2820				0x0001
+#define RF2850				0x0002
+#define RF2720				0x0003
+#define RF2750				0x0004
+#define RF3020				0x0005
+#define RF2020				0x0006
+#define RF3021				0x0007
+#define RF3022				0x0008
+#define RF3052				0x0009
+
+/*
+ * Chipset version.
+ */
+#define RT2860C_VERSION			0x28600100
+#define RT2860D_VERSION			0x28600101
+#define RT2880E_VERSION			0x28720200
+#define RT2883_VERSION			0x28830300
+#define RT3070_VERSION			0x30700200
+
+/*
+ * Signal information.
+ * Default offset is required for RSSI <-> dBm conversion.
+ */
+#define DEFAULT_RSSI_OFFSET		120 /* FIXME */
+
+/*
+ * Register layout information.
+ */
+#define CSR_REG_BASE			0x1000
+#define CSR_REG_SIZE			0x0800
+#define EEPROM_BASE			0x0000
+#define EEPROM_SIZE			0x0110
+#define BBP_BASE			0x0000
+#define BBP_SIZE			0x0080
+#define RF_BASE				0x0004
+#define RF_SIZE				0x0010
+
+/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES			4
+
+/*
+ * USB registers.
+ */
+
+/*
+ * INT_SOURCE_CSR: Interrupt source register.
+ * Write one to clear corresponding bit.
+ * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
+ */
+#define INT_SOURCE_CSR			0x0200
+#define INT_SOURCE_CSR_RXDELAYINT	FIELD32(0x00000001)
+#define INT_SOURCE_CSR_TXDELAYINT	FIELD32(0x00000002)
+#define INT_SOURCE_CSR_RX_DONE		FIELD32(0x00000004)
+#define INT_SOURCE_CSR_AC0_DMA_DONE	FIELD32(0x00000008)
+#define INT_SOURCE_CSR_AC1_DMA_DONE	FIELD32(0x00000010)
+#define INT_SOURCE_CSR_AC2_DMA_DONE	FIELD32(0x00000020)
+#define INT_SOURCE_CSR_AC3_DMA_DONE	FIELD32(0x00000040)
+#define INT_SOURCE_CSR_HCCA_DMA_DONE	FIELD32(0x00000080)
+#define INT_SOURCE_CSR_MGMT_DMA_DONE	FIELD32(0x00000100)
+#define INT_SOURCE_CSR_MCU_COMMAND	FIELD32(0x00000200)
+#define INT_SOURCE_CSR_RXTX_COHERENT	FIELD32(0x00000400)
+#define INT_SOURCE_CSR_TBTT		FIELD32(0x00000800)
+#define INT_SOURCE_CSR_PRE_TBTT		FIELD32(0x00001000)
+#define INT_SOURCE_CSR_TX_FIFO_STATUS	FIELD32(0x00002000)
+#define INT_SOURCE_CSR_AUTO_WAKEUP	FIELD32(0x00004000)
+#define INT_SOURCE_CSR_GPTIMER		FIELD32(0x00008000)
+#define INT_SOURCE_CSR_RX_COHERENT	FIELD32(0x00010000)
+#define INT_SOURCE_CSR_TX_COHERENT	FIELD32(0x00020000)
+
+/*
+ * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF.
+ */
+#define INT_MASK_CSR			0x0204
+#define INT_MASK_CSR_RXDELAYINT		FIELD32(0x00000001)
+#define INT_MASK_CSR_TXDELAYINT		FIELD32(0x00000002)
+#define INT_MASK_CSR_RX_DONE		FIELD32(0x00000004)
+#define INT_MASK_CSR_AC0_DMA_DONE	FIELD32(0x00000008)
+#define INT_MASK_CSR_AC1_DMA_DONE	FIELD32(0x00000010)
+#define INT_MASK_CSR_AC2_DMA_DONE	FIELD32(0x00000020)
+#define INT_MASK_CSR_AC3_DMA_DONE	FIELD32(0x00000040)
+#define INT_MASK_CSR_HCCA_DMA_DONE	FIELD32(0x00000080)
+#define INT_MASK_CSR_MGMT_DMA_DONE	FIELD32(0x00000100)
+#define INT_MASK_CSR_MCU_COMMAND	FIELD32(0x00000200)
+#define INT_MASK_CSR_RXTX_COHERENT	FIELD32(0x00000400)
+#define INT_MASK_CSR_TBTT		FIELD32(0x00000800)
+#define INT_MASK_CSR_PRE_TBTT		FIELD32(0x00001000)
+#define INT_MASK_CSR_TX_FIFO_STATUS	FIELD32(0x00002000)
+#define INT_MASK_CSR_AUTO_WAKEUP	FIELD32(0x00004000)
+#define INT_MASK_CSR_GPTIMER		FIELD32(0x00008000)
+#define INT_MASK_CSR_RX_COHERENT	FIELD32(0x00010000)
+#define INT_MASK_CSR_TX_COHERENT	FIELD32(0x00020000)
+
+/*
+ * WPDMA_GLO_CFG
+ */
+#define WPDMA_GLO_CFG 			0x0208
+#define WPDMA_GLO_CFG_ENABLE_TX_DMA	FIELD32(0x00000001)
+#define WPDMA_GLO_CFG_TX_DMA_BUSY    	FIELD32(0x00000002)
+#define WPDMA_GLO_CFG_ENABLE_RX_DMA	FIELD32(0x00000004)
+#define WPDMA_GLO_CFG_RX_DMA_BUSY	FIELD32(0x00000008)
+#define WPDMA_GLO_CFG_WP_DMA_BURST_SIZE	FIELD32(0x00000030)
+#define WPDMA_GLO_CFG_TX_WRITEBACK_DONE	FIELD32(0x00000040)
+#define WPDMA_GLO_CFG_BIG_ENDIAN	FIELD32(0x00000080)
+#define WPDMA_GLO_CFG_RX_HDR_SCATTER	FIELD32(0x0000ff00)
+#define WPDMA_GLO_CFG_HDR_SEG_LEN	FIELD32(0xffff0000)
+
+/*
+ * WPDMA_RST_IDX
+ */
+#define WPDMA_RST_IDX 			0x020c
+#define WPDMA_RST_IDX_DTX_IDX0		FIELD32(0x00000001)
+#define WPDMA_RST_IDX_DTX_IDX1		FIELD32(0x00000002)
+#define WPDMA_RST_IDX_DTX_IDX2		FIELD32(0x00000004)
+#define WPDMA_RST_IDX_DTX_IDX3		FIELD32(0x00000008)
+#define WPDMA_RST_IDX_DTX_IDX4		FIELD32(0x00000010)
+#define WPDMA_RST_IDX_DTX_IDX5		FIELD32(0x00000020)
+#define WPDMA_RST_IDX_DRX_IDX0		FIELD32(0x00010000)
+
+/*
+ * DELAY_INT_CFG
+ */
+#define DELAY_INT_CFG			0x0210
+#define DELAY_INT_CFG_RXMAX_PTIME	FIELD32(0x000000ff)
+#define DELAY_INT_CFG_RXMAX_PINT	FIELD32(0x00007f00)
+#define DELAY_INT_CFG_RXDLY_INT_EN	FIELD32(0x00008000)
+#define DELAY_INT_CFG_TXMAX_PTIME	FIELD32(0x00ff0000)
+#define DELAY_INT_CFG_TXMAX_PINT	FIELD32(0x7f000000)
+#define DELAY_INT_CFG_TXDLY_INT_EN	FIELD32(0x80000000)
+
+/*
+ * WMM_AIFSN_CFG: Aifsn for each EDCA AC
+ * AIFSN0: AC_BE
+ * AIFSN1: AC_BK
+ * AIFSN2: AC_VI
+ * AIFSN3: AC_VO
+ */
+#define WMM_AIFSN_CFG			0x0214
+#define WMM_AIFSN_CFG_AIFSN0		FIELD32(0x0000000f)
+#define WMM_AIFSN_CFG_AIFSN1		FIELD32(0x000000f0)
+#define WMM_AIFSN_CFG_AIFSN2		FIELD32(0x00000f00)
+#define WMM_AIFSN_CFG_AIFSN3		FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMIN_CSR: CWmin for each EDCA AC
+ * CWMIN0: AC_BE
+ * CWMIN1: AC_BK
+ * CWMIN2: AC_VI
+ * CWMIN3: AC_VO
+ */
+#define WMM_CWMIN_CFG			0x0218
+#define WMM_CWMIN_CFG_CWMIN0		FIELD32(0x0000000f)
+#define WMM_CWMIN_CFG_CWMIN1		FIELD32(0x000000f0)
+#define WMM_CWMIN_CFG_CWMIN2		FIELD32(0x00000f00)
+#define WMM_CWMIN_CFG_CWMIN3		FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMAX_CSR: CWmax for each EDCA AC
+ * CWMAX0: AC_BE
+ * CWMAX1: AC_BK
+ * CWMAX2: AC_VI
+ * CWMAX3: AC_VO
+ */
+#define WMM_CWMAX_CFG			0x021c
+#define WMM_CWMAX_CFG_CWMAX0		FIELD32(0x0000000f)
+#define WMM_CWMAX_CFG_CWMAX1		FIELD32(0x000000f0)
+#define WMM_CWMAX_CFG_CWMAX2		FIELD32(0x00000f00)
+#define WMM_CWMAX_CFG_CWMAX3		FIELD32(0x0000f000)
+
+/*
+ * AC_TXOP0: AC_BK/AC_BE TXOP register
+ * AC0TXOP: AC_BK in unit of 32us
+ * AC1TXOP: AC_BE in unit of 32us
+ */
+#define WMM_TXOP0_CFG			0x0220
+#define WMM_TXOP0_CFG_AC0TXOP		FIELD32(0x0000ffff)
+#define WMM_TXOP0_CFG_AC1TXOP		FIELD32(0xffff0000)
+
+/*
+ * AC_TXOP1: AC_VO/AC_VI TXOP register
+ * AC2TXOP: AC_VI in unit of 32us
+ * AC3TXOP: AC_VO in unit of 32us
+ */
+#define WMM_TXOP1_CFG			0x0224
+#define WMM_TXOP1_CFG_AC2TXOP		FIELD32(0x0000ffff)
+#define WMM_TXOP1_CFG_AC3TXOP		FIELD32(0xffff0000)
+
+/*
+ * GPIO_CTRL_CFG:
+ */
+#define GPIO_CTRL_CFG			0x0228
+#define GPIO_CTRL_CFG_BIT0		FIELD32(0x00000001)
+#define GPIO_CTRL_CFG_BIT1		FIELD32(0x00000002)
+#define GPIO_CTRL_CFG_BIT2		FIELD32(0x00000004)
+#define GPIO_CTRL_CFG_BIT3		FIELD32(0x00000008)
+#define GPIO_CTRL_CFG_BIT4		FIELD32(0x00000010)
+#define GPIO_CTRL_CFG_BIT5		FIELD32(0x00000020)
+#define GPIO_CTRL_CFG_BIT6		FIELD32(0x00000040)
+#define GPIO_CTRL_CFG_BIT7		FIELD32(0x00000080)
+#define GPIO_CTRL_CFG_BIT8		FIELD32(0x00000100)
+
+/*
+ * MCU_CMD_CFG
+ */
+#define MCU_CMD_CFG			0x022c
+
+/*
+ * AC_BK register offsets
+ */
+#define TX_BASE_PTR0			0x0230
+#define TX_MAX_CNT0			0x0234
+#define TX_CTX_IDX0			0x0238
+#define TX_DTX_IDX0			0x023c
+
+/*
+ * AC_BE register offsets
+ */
+#define TX_BASE_PTR1			0x0240
+#define TX_MAX_CNT1			0x0244
+#define TX_CTX_IDX1			0x0248
+#define TX_DTX_IDX1			0x024c
+
+/*
+ * AC_VI register offsets
+ */
+#define TX_BASE_PTR2			0x0250
+#define TX_MAX_CNT2			0x0254
+#define TX_CTX_IDX2			0x0258
+#define TX_DTX_IDX2			0x025c
+
+/*
+ * AC_VO register offsets
+ */
+#define TX_BASE_PTR3			0x0260
+#define TX_MAX_CNT3			0x0264
+#define TX_CTX_IDX3			0x0268
+#define TX_DTX_IDX3			0x026c
+
+/*
+ * HCCA register offsets
+ */
+#define TX_BASE_PTR4			0x0270
+#define TX_MAX_CNT4			0x0274
+#define TX_CTX_IDX4			0x0278
+#define TX_DTX_IDX4			0x027c
+
+/*
+ * MGMT register offsets
+ */
+#define TX_BASE_PTR5			0x0280
+#define TX_MAX_CNT5			0x0284
+#define TX_CTX_IDX5			0x0288
+#define TX_DTX_IDX5			0x028c
+
+/*
+ * RX register offsets
+ */
+#define RX_BASE_PTR			0x0290
+#define RX_MAX_CNT			0x0294
+#define RX_CRX_IDX			0x0298
+#define RX_DRX_IDX			0x029c
+
+/*
+ * PBF_SYS_CTRL
+ * HOST_RAM_WRITE: enable Host program ram write selection
+ */
+#define PBF_SYS_CTRL			0x0400
+#define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
+#define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
+
+/*
+ * HOST-MCU shared memory
+ */
+#define HOST_CMD_CSR			0x0404
+#define HOST_CMD_CSR_HOST_COMMAND	FIELD32(0x000000ff)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define PBF_CFG				0x0408
+#define PBF_MAX_PCNT			0x040c
+#define PBF_CTRL			0x0410
+#define PBF_INT_STA			0x0414
+#define PBF_INT_ENA			0x0418
+
+/*
+ * BCN_OFFSET0:
+ */
+#define BCN_OFFSET0			0x042c
+#define BCN_OFFSET0_BCN0		FIELD32(0x000000ff)
+#define BCN_OFFSET0_BCN1		FIELD32(0x0000ff00)
+#define BCN_OFFSET0_BCN2		FIELD32(0x00ff0000)
+#define BCN_OFFSET0_BCN3		FIELD32(0xff000000)
+
+/*
+ * BCN_OFFSET1:
+ */
+#define BCN_OFFSET1			0x0430
+#define BCN_OFFSET1_BCN4		FIELD32(0x000000ff)
+#define BCN_OFFSET1_BCN5		FIELD32(0x0000ff00)
+#define BCN_OFFSET1_BCN6		FIELD32(0x00ff0000)
+#define BCN_OFFSET1_BCN7		FIELD32(0xff000000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define TXRXQ_PCNT			0x0438
+#define PBF_DBG				0x043c
+
+/*
+ * RF registers
+ */
+#define	RF_CSR_CFG			0x0500
+#define RF_CSR_CFG_DATA			FIELD32(0x000000ff)
+#define RF_CSR_CFG_REGNUM		FIELD32(0x00001f00)
+#define RF_CSR_CFG_WRITE		FIELD32(0x00010000)
+#define RF_CSR_CFG_BUSY			FIELD32(0x00020000)
+
+/*
+ * EFUSE_CSR: RT30x0 EEPROM
+ */
+#define EFUSE_CTRL			0x0580
+#define EFUSE_CTRL_ADDRESS_IN		FIELD32(0x03fe0000)
+#define EFUSE_CTRL_MODE			FIELD32(0x000000c0)
+#define EFUSE_CTRL_KICK			FIELD32(0x40000000)
+#define EFUSE_CTRL_PRESENT		FIELD32(0x80000000)
+
+/*
+ * EFUSE_DATA0
+ */
+#define EFUSE_DATA0			0x0590
+
+/*
+ * EFUSE_DATA1
+ */
+#define EFUSE_DATA1			0x0594
+
+/*
+ * EFUSE_DATA2
+ */
+#define EFUSE_DATA2			0x0598
+
+/*
+ * EFUSE_DATA3
+ */
+#define EFUSE_DATA3			0x059c
+
+/*
+ * MAC Control/Status Registers(CSR).
+ * Some values are set in TU, whereas 1 TU == 1024 us.
+ */
+
+/*
+ * MAC_CSR0: ASIC revision number.
+ * ASIC_REV: 0
+ * ASIC_VER: 2860 or 2870
+ */
+#define MAC_CSR0			0x1000
+#define MAC_CSR0_ASIC_REV		FIELD32(0x0000ffff)
+#define MAC_CSR0_ASIC_VER		FIELD32(0xffff0000)
+
+/*
+ * MAC_SYS_CTRL:
+ */
+#define MAC_SYS_CTRL			0x1004
+#define MAC_SYS_CTRL_RESET_CSR		FIELD32(0x00000001)
+#define MAC_SYS_CTRL_RESET_BBP		FIELD32(0x00000002)
+#define MAC_SYS_CTRL_ENABLE_TX		FIELD32(0x00000004)
+#define MAC_SYS_CTRL_ENABLE_RX		FIELD32(0x00000008)
+#define MAC_SYS_CTRL_CONTINUOUS_TX	FIELD32(0x00000010)
+#define MAC_SYS_CTRL_LOOPBACK		FIELD32(0x00000020)
+#define MAC_SYS_CTRL_WLAN_HALT		FIELD32(0x00000040)
+#define MAC_SYS_CTRL_RX_TIMESTAMP	FIELD32(0x00000080)
+
+/*
+ * MAC_ADDR_DW0: STA MAC register 0
+ */
+#define MAC_ADDR_DW0			0x1008
+#define MAC_ADDR_DW0_BYTE0		FIELD32(0x000000ff)
+#define MAC_ADDR_DW0_BYTE1		FIELD32(0x0000ff00)
+#define MAC_ADDR_DW0_BYTE2		FIELD32(0x00ff0000)
+#define MAC_ADDR_DW0_BYTE3		FIELD32(0xff000000)
+
+/*
+ * MAC_ADDR_DW1: STA MAC register 1
+ * UNICAST_TO_ME_MASK:
+ * Used to mask off bits from byte 5 of the MAC address
+ * to determine the UNICAST_TO_ME bit for RX frames.
+ * The full mask is complemented by BSS_ID_MASK:
+ *    MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK
+ */
+#define MAC_ADDR_DW1			0x100c
+#define MAC_ADDR_DW1_BYTE4		FIELD32(0x000000ff)
+#define MAC_ADDR_DW1_BYTE5		FIELD32(0x0000ff00)
+#define MAC_ADDR_DW1_UNICAST_TO_ME_MASK	FIELD32(0x00ff0000)
+
+/*
+ * MAC_BSSID_DW0: BSSID register 0
+ */
+#define MAC_BSSID_DW0			0x1010
+#define MAC_BSSID_DW0_BYTE0		FIELD32(0x000000ff)
+#define MAC_BSSID_DW0_BYTE1		FIELD32(0x0000ff00)
+#define MAC_BSSID_DW0_BYTE2		FIELD32(0x00ff0000)
+#define MAC_BSSID_DW0_BYTE3		FIELD32(0xff000000)
+
+/*
+ * MAC_BSSID_DW1: BSSID register 1
+ * BSS_ID_MASK:
+ *     0: 1-BSSID mode (BSS index = 0)
+ *     1: 2-BSSID mode (BSS index: Byte5, bit 0)
+ *     2: 4-BSSID mode (BSS index: byte5, bit 0 - 1)
+ *     3: 8-BSSID mode (BSS index: byte5, bit 0 - 2)
+ * This mask is used to mask off bits 0, 1 and 2 of byte 5 of the
+ * BSSID. This will make sure that those bits will be ignored
+ * when determining the MY_BSS of RX frames.
+ */
+#define MAC_BSSID_DW1			0x1014
+#define MAC_BSSID_DW1_BYTE4		FIELD32(0x000000ff)
+#define MAC_BSSID_DW1_BYTE5		FIELD32(0x0000ff00)
+#define MAC_BSSID_DW1_BSS_ID_MASK	FIELD32(0x00030000)
+#define MAC_BSSID_DW1_BSS_BCN_NUM	FIELD32(0x001c0000)
+
+/*
+ * MAX_LEN_CFG: Maximum frame length register.
+ * MAX_MPDU: rt2860b max 16k bytes
+ * MAX_PSDU: Maximum PSDU length
+ *	(power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+ */
+#define MAX_LEN_CFG			0x1018
+#define MAX_LEN_CFG_MAX_MPDU		FIELD32(0x00000fff)
+#define MAX_LEN_CFG_MAX_PSDU		FIELD32(0x00003000)
+#define MAX_LEN_CFG_MIN_PSDU		FIELD32(0x0000c000)
+#define MAX_LEN_CFG_MIN_MPDU		FIELD32(0x000f0000)
+
+/*
+ * BBP_CSR_CFG: BBP serial control register
+ * VALUE: Register value to program into BBP
+ * REG_NUM: Selected BBP register
+ * READ_CONTROL: 0 write BBP, 1 read BBP
+ * BUSY: ASIC is busy executing BBP commands
+ * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks
+ * BBP_RW_MODE: 0 serial, 1 paralell
+ */
+#define BBP_CSR_CFG			0x101c
+#define BBP_CSR_CFG_VALUE		FIELD32(0x000000ff)
+#define BBP_CSR_CFG_REGNUM		FIELD32(0x0000ff00)
+#define BBP_CSR_CFG_READ_CONTROL	FIELD32(0x00010000)
+#define BBP_CSR_CFG_BUSY		FIELD32(0x00020000)
+#define BBP_CSR_CFG_BBP_PAR_DUR		FIELD32(0x00040000)
+#define BBP_CSR_CFG_BBP_RW_MODE		FIELD32(0x00080000)
+
+/*
+ * RF_CSR_CFG0: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * BITWIDTH: Selected RF register
+ * STANDBYMODE: 0 high when standby, 1 low when standby
+ * SEL: 0 RF_LE0 activate, 1 RF_LE1 activate
+ * BUSY: ASIC is busy executing RF commands
+ */
+#define RF_CSR_CFG0			0x1020
+#define RF_CSR_CFG0_REGID_AND_VALUE	FIELD32(0x00ffffff)
+#define RF_CSR_CFG0_BITWIDTH		FIELD32(0x1f000000)
+#define RF_CSR_CFG0_REG_VALUE_BW	FIELD32(0x1fffffff)
+#define RF_CSR_CFG0_STANDBYMODE		FIELD32(0x20000000)
+#define RF_CSR_CFG0_SEL			FIELD32(0x40000000)
+#define RF_CSR_CFG0_BUSY		FIELD32(0x80000000)
+
+/*
+ * RF_CSR_CFG1: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ *        0: 3 system clock cycle (37.5usec)
+ *        1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG1			0x1024
+#define RF_CSR_CFG1_REGID_AND_VALUE	FIELD32(0x00ffffff)
+#define RF_CSR_CFG1_RFGAP		FIELD32(0x1f000000)
+
+/*
+ * RF_CSR_CFG2: RF control register
+ * VALUE: Register value to program into RF
+ */
+#define RF_CSR_CFG2			0x1028
+#define RF_CSR_CFG2_VALUE		FIELD32(0x00ffffff)
+
+/*
+ * LED_CFG: LED control
+ * color LED's:
+ *   0: off
+ *   1: blinking upon TX2
+ *   2: periodic slow blinking
+ *   3: always on
+ * LED polarity:
+ *   0: active low
+ *   1: active high
+ */
+#define LED_CFG				0x102c
+#define LED_CFG_ON_PERIOD		FIELD32(0x000000ff)
+#define LED_CFG_OFF_PERIOD		FIELD32(0x0000ff00)
+#define LED_CFG_SLOW_BLINK_PERIOD	FIELD32(0x003f0000)
+#define LED_CFG_R_LED_MODE		FIELD32(0x03000000)
+#define LED_CFG_G_LED_MODE		FIELD32(0x0c000000)
+#define LED_CFG_Y_LED_MODE		FIELD32(0x30000000)
+#define LED_CFG_LED_POLAR		FIELD32(0x40000000)
+
+/*
+ * XIFS_TIME_CFG: MAC timing
+ * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
+ * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
+ * OFDM_XIFS_TIME: unit 1us. Applied after OFDM RX
+ *	when MAC doesn't reference BBP signal BBRXEND
+ * EIFS: unit 1us
+ * BB_RXEND_ENABLE: reference RXEND signal to begin XIFS defer
+ *
+ */
+#define XIFS_TIME_CFG			0x1100
+#define XIFS_TIME_CFG_CCKM_SIFS_TIME	FIELD32(0x000000ff)
+#define XIFS_TIME_CFG_OFDM_SIFS_TIME	FIELD32(0x0000ff00)
+#define XIFS_TIME_CFG_OFDM_XIFS_TIME	FIELD32(0x000f0000)
+#define XIFS_TIME_CFG_EIFS		FIELD32(0x1ff00000)
+#define XIFS_TIME_CFG_BB_RXEND_ENABLE	FIELD32(0x20000000)
+
+/*
+ * BKOFF_SLOT_CFG:
+ */
+#define BKOFF_SLOT_CFG			0x1104
+#define BKOFF_SLOT_CFG_SLOT_TIME	FIELD32(0x000000ff)
+#define BKOFF_SLOT_CFG_CC_DELAY_TIME	FIELD32(0x0000ff00)
+
+/*
+ * NAV_TIME_CFG:
+ */
+#define NAV_TIME_CFG			0x1108
+#define NAV_TIME_CFG_SIFS		FIELD32(0x000000ff)
+#define NAV_TIME_CFG_SLOT_TIME		FIELD32(0x0000ff00)
+#define NAV_TIME_CFG_EIFS		FIELD32(0x01ff0000)
+#define NAV_TIME_ZERO_SIFS		FIELD32(0x02000000)
+
+/*
+ * CH_TIME_CFG: count as channel busy
+ */
+#define CH_TIME_CFG     	        0x110c
+
+/*
+ * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
+ */
+#define PBF_LIFE_TIMER     	        0x1110
+
+/*
+ * BCN_TIME_CFG:
+ * BEACON_INTERVAL: in unit of 1/16 TU
+ * TSF_TICKING: Enable TSF auto counting
+ * TSF_SYNC: Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ * BEACON_GEN: Enable beacon generator
+ */
+#define BCN_TIME_CFG			0x1114
+#define BCN_TIME_CFG_BEACON_INTERVAL	FIELD32(0x0000ffff)
+#define BCN_TIME_CFG_TSF_TICKING	FIELD32(0x00010000)
+#define BCN_TIME_CFG_TSF_SYNC		FIELD32(0x00060000)
+#define BCN_TIME_CFG_TBTT_ENABLE	FIELD32(0x00080000)
+#define BCN_TIME_CFG_BEACON_GEN		FIELD32(0x00100000)
+#define BCN_TIME_CFG_TX_TIME_COMPENSATE	FIELD32(0xf0000000)
+
+/*
+ * TBTT_SYNC_CFG:
+ */
+#define TBTT_SYNC_CFG			0x1118
+
+/*
+ * TSF_TIMER_DW0: Local lsb TSF timer, read-only
+ */
+#define TSF_TIMER_DW0			0x111c
+#define TSF_TIMER_DW0_LOW_WORD		FIELD32(0xffffffff)
+
+/*
+ * TSF_TIMER_DW1: Local msb TSF timer, read-only
+ */
+#define TSF_TIMER_DW1			0x1120
+#define TSF_TIMER_DW1_HIGH_WORD		FIELD32(0xffffffff)
+
+/*
+ * TBTT_TIMER: TImer remains till next TBTT, read-only
+ */
+#define TBTT_TIMER			0x1124
+
+/*
+ * INT_TIMER_CFG:
+ */
+#define INT_TIMER_CFG			0x1128
+
+/*
+ * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
+ */
+#define INT_TIMER_EN			0x112c
+
+/*
+ * CH_IDLE_STA: channel idle time
+ */
+#define CH_IDLE_STA			0x1130
+
+/*
+ * CH_BUSY_STA: channel busy time
+ */
+#define CH_BUSY_STA			0x1134
+
+/*
+ * MAC_STATUS_CFG:
+ * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
+ *	if 1 or higher one of the 2 registers is busy.
+ */
+#define MAC_STATUS_CFG			0x1200
+#define MAC_STATUS_CFG_BBP_RF_BUSY	FIELD32(0x00000003)
+
+/*
+ * PWR_PIN_CFG:
+ */
+#define PWR_PIN_CFG			0x1204
+
+/*
+ * AUTOWAKEUP_CFG: Manual power control / status register
+ * TBCN_BEFORE_WAKE: ForceWake has high privilege than PutToSleep when both set
+ * AUTOWAKE: 0:sleep, 1:awake
+ */
+#define AUTOWAKEUP_CFG			0x1208
+#define AUTOWAKEUP_CFG_AUTO_LEAD_TIME	FIELD32(0x000000ff)
+#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE	FIELD32(0x00007f00)
+#define AUTOWAKEUP_CFG_AUTOWAKE		FIELD32(0x00008000)
+
+/*
+ * EDCA_AC0_CFG:
+ */
+#define EDCA_AC0_CFG			0x1300
+#define EDCA_AC0_CFG_TX_OP		FIELD32(0x000000ff)
+#define EDCA_AC0_CFG_AIFSN		FIELD32(0x00000f00)
+#define EDCA_AC0_CFG_CWMIN		FIELD32(0x0000f000)
+#define EDCA_AC0_CFG_CWMAX		FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC1_CFG:
+ */
+#define EDCA_AC1_CFG			0x1304
+#define EDCA_AC1_CFG_TX_OP		FIELD32(0x000000ff)
+#define EDCA_AC1_CFG_AIFSN		FIELD32(0x00000f00)
+#define EDCA_AC1_CFG_CWMIN		FIELD32(0x0000f000)
+#define EDCA_AC1_CFG_CWMAX		FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC2_CFG:
+ */
+#define EDCA_AC2_CFG			0x1308
+#define EDCA_AC2_CFG_TX_OP		FIELD32(0x000000ff)
+#define EDCA_AC2_CFG_AIFSN		FIELD32(0x00000f00)
+#define EDCA_AC2_CFG_CWMIN		FIELD32(0x0000f000)
+#define EDCA_AC2_CFG_CWMAX		FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC3_CFG:
+ */
+#define EDCA_AC3_CFG			0x130c
+#define EDCA_AC3_CFG_TX_OP		FIELD32(0x000000ff)
+#define EDCA_AC3_CFG_AIFSN		FIELD32(0x00000f00)
+#define EDCA_AC3_CFG_CWMIN		FIELD32(0x0000f000)
+#define EDCA_AC3_CFG_CWMAX		FIELD32(0x000f0000)
+
+/*
+ * EDCA_TID_AC_MAP:
+ */
+#define EDCA_TID_AC_MAP			0x1310
+
+/*
+ * TX_PWR_CFG_0:
+ */
+#define TX_PWR_CFG_0			0x1314
+#define TX_PWR_CFG_0_1MBS		FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_2MBS		FIELD32(0x000000f0)
+#define TX_PWR_CFG_0_55MBS		FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_11MBS		FIELD32(0x0000f000)
+#define TX_PWR_CFG_0_6MBS		FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_9MBS		FIELD32(0x00f00000)
+#define TX_PWR_CFG_0_12MBS		FIELD32(0x0f000000)
+#define TX_PWR_CFG_0_18MBS		FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_1:
+ */
+#define TX_PWR_CFG_1			0x1318
+#define TX_PWR_CFG_1_24MBS		FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_36MBS		FIELD32(0x000000f0)
+#define TX_PWR_CFG_1_48MBS		FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_54MBS		FIELD32(0x0000f000)
+#define TX_PWR_CFG_1_MCS0		FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_MCS1		FIELD32(0x00f00000)
+#define TX_PWR_CFG_1_MCS2		FIELD32(0x0f000000)
+#define TX_PWR_CFG_1_MCS3		FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_2:
+ */
+#define TX_PWR_CFG_2			0x131c
+#define TX_PWR_CFG_2_MCS4		FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_MCS5		FIELD32(0x000000f0)
+#define TX_PWR_CFG_2_MCS6		FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_MCS7		FIELD32(0x0000f000)
+#define TX_PWR_CFG_2_MCS8		FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_MCS9		FIELD32(0x00f00000)
+#define TX_PWR_CFG_2_MCS10		FIELD32(0x0f000000)
+#define TX_PWR_CFG_2_MCS11		FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_3:
+ */
+#define TX_PWR_CFG_3			0x1320
+#define TX_PWR_CFG_3_MCS12		FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_MCS13		FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_MCS14		FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_MCS15		FIELD32(0x0000f000)
+#define TX_PWR_CFG_3_UKNOWN1		FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_UKNOWN2		FIELD32(0x00f00000)
+#define TX_PWR_CFG_3_UKNOWN3		FIELD32(0x0f000000)
+#define TX_PWR_CFG_3_UKNOWN4		FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_4:
+ */
+#define TX_PWR_CFG_4			0x1324
+#define TX_PWR_CFG_4_UKNOWN5		FIELD32(0x0000000f)
+#define TX_PWR_CFG_4_UKNOWN6		FIELD32(0x000000f0)
+#define TX_PWR_CFG_4_UKNOWN7		FIELD32(0x00000f00)
+#define TX_PWR_CFG_4_UKNOWN8		FIELD32(0x0000f000)
+
+/*
+ * TX_PIN_CFG:
+ */
+#define TX_PIN_CFG			0x1328
+#define TX_PIN_CFG_PA_PE_A0_EN		FIELD32(0x00000001)
+#define TX_PIN_CFG_PA_PE_G0_EN		FIELD32(0x00000002)
+#define TX_PIN_CFG_PA_PE_A1_EN		FIELD32(0x00000004)
+#define TX_PIN_CFG_PA_PE_G1_EN		FIELD32(0x00000008)
+#define TX_PIN_CFG_PA_PE_A0_POL		FIELD32(0x00000010)
+#define TX_PIN_CFG_PA_PE_G0_POL		FIELD32(0x00000020)
+#define TX_PIN_CFG_PA_PE_A1_POL		FIELD32(0x00000040)
+#define TX_PIN_CFG_PA_PE_G1_POL		FIELD32(0x00000080)
+#define TX_PIN_CFG_LNA_PE_A0_EN		FIELD32(0x00000100)
+#define TX_PIN_CFG_LNA_PE_G0_EN		FIELD32(0x00000200)
+#define TX_PIN_CFG_LNA_PE_A1_EN		FIELD32(0x00000400)
+#define TX_PIN_CFG_LNA_PE_G1_EN		FIELD32(0x00000800)
+#define TX_PIN_CFG_LNA_PE_A0_POL	FIELD32(0x00001000)
+#define TX_PIN_CFG_LNA_PE_G0_POL	FIELD32(0x00002000)
+#define TX_PIN_CFG_LNA_PE_A1_POL	FIELD32(0x00004000)
+#define TX_PIN_CFG_LNA_PE_G1_POL	FIELD32(0x00008000)
+#define TX_PIN_CFG_RFTR_EN		FIELD32(0x00010000)
+#define TX_PIN_CFG_RFTR_POL		FIELD32(0x00020000)
+#define TX_PIN_CFG_TRSW_EN		FIELD32(0x00040000)
+#define TX_PIN_CFG_TRSW_POL		FIELD32(0x00080000)
+
+/*
+ * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
+ */
+#define TX_BAND_CFG			0x132c
+#define TX_BAND_CFG_HT40_PLUS		FIELD32(0x00000001)
+#define TX_BAND_CFG_A			FIELD32(0x00000002)
+#define TX_BAND_CFG_BG			FIELD32(0x00000004)
+
+/*
+ * TX_SW_CFG0:
+ */
+#define TX_SW_CFG0			0x1330
+
+/*
+ * TX_SW_CFG1:
+ */
+#define TX_SW_CFG1			0x1334
+
+/*
+ * TX_SW_CFG2:
+ */
+#define TX_SW_CFG2			0x1338
+
+/*
+ * TXOP_THRES_CFG:
+ */
+#define TXOP_THRES_CFG			0x133c
+
+/*
+ * TXOP_CTRL_CFG:
+ */
+#define TXOP_CTRL_CFG			0x1340
+
+/*
+ * TX_RTS_CFG:
+ * RTS_THRES: unit:byte
+ * RTS_FBK_EN: enable rts rate fallback
+ */
+#define TX_RTS_CFG			0x1344
+#define TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT	FIELD32(0x000000ff)
+#define TX_RTS_CFG_RTS_THRES		FIELD32(0x00ffff00)
+#define TX_RTS_CFG_RTS_FBK_EN		FIELD32(0x01000000)
+
+/*
+ * TX_TIMEOUT_CFG:
+ * MPDU_LIFETIME: expiration time = 2^(9+MPDU LIFE TIME) us
+ * RX_ACK_TIMEOUT: unit:slot. Used for TX procedure
+ * TX_OP_TIMEOUT: TXOP timeout value for TXOP truncation.
+ *                it is recommended that:
+ *                (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ */
+#define TX_TIMEOUT_CFG			0x1348
+#define TX_TIMEOUT_CFG_MPDU_LIFETIME	FIELD32(0x000000f0)
+#define TX_TIMEOUT_CFG_RX_ACK_TIMEOUT	FIELD32(0x0000ff00)
+#define TX_TIMEOUT_CFG_TX_OP_TIMEOUT	FIELD32(0x00ff0000)
+
+/*
+ * TX_RTY_CFG:
+ * SHORT_RTY_LIMIT: short retry limit
+ * LONG_RTY_LIMIT: long retry limit
+ * LONG_RTY_THRE: Long retry threshoold
+ * NON_AGG_RTY_MODE: Non-Aggregate MPDU retry mode
+ *                   0:expired by retry limit, 1: expired by mpdu life timer
+ * AGG_RTY_MODE: Aggregate MPDU retry mode
+ *               0:expired by retry limit, 1: expired by mpdu life timer
+ * TX_AUTO_FB_ENABLE: Tx retry PHY rate auto fallback enable
+ */
+#define TX_RTY_CFG			0x134c
+#define TX_RTY_CFG_SHORT_RTY_LIMIT	FIELD32(0x000000ff)
+#define TX_RTY_CFG_LONG_RTY_LIMIT	FIELD32(0x0000ff00)
+#define TX_RTY_CFG_LONG_RTY_THRE	FIELD32(0x0fff0000)
+#define TX_RTY_CFG_NON_AGG_RTY_MODE	FIELD32(0x10000000)
+#define TX_RTY_CFG_AGG_RTY_MODE		FIELD32(0x20000000)
+#define TX_RTY_CFG_TX_AUTO_FB_ENABLE	FIELD32(0x40000000)
+
+/*
+ * TX_LINK_CFG:
+ * REMOTE_MFB_LIFETIME: remote MFB life time. unit: 32us
+ * MFB_ENABLE: TX apply remote MFB 1:enable
+ * REMOTE_UMFS_ENABLE: remote unsolicit  MFB enable
+ *                     0: not apply remote remote unsolicit (MFS=7)
+ * TX_MRQ_EN: MCS request TX enable
+ * TX_RDG_EN: RDG TX enable
+ * TX_CF_ACK_EN: Piggyback CF-ACK enable
+ * REMOTE_MFB: remote MCS feedback
+ * REMOTE_MFS: remote MCS feedback sequence number
+ */
+#define TX_LINK_CFG			0x1350
+#define TX_LINK_CFG_REMOTE_MFB_LIFETIME	FIELD32(0x000000ff)
+#define TX_LINK_CFG_MFB_ENABLE		FIELD32(0x00000100)
+#define TX_LINK_CFG_REMOTE_UMFS_ENABLE	FIELD32(0x00000200)
+#define TX_LINK_CFG_TX_MRQ_EN		FIELD32(0x00000400)
+#define TX_LINK_CFG_TX_RDG_EN		FIELD32(0x00000800)
+#define TX_LINK_CFG_TX_CF_ACK_EN	FIELD32(0x00001000)
+#define TX_LINK_CFG_REMOTE_MFB		FIELD32(0x00ff0000)
+#define TX_LINK_CFG_REMOTE_MFS		FIELD32(0xff000000)
+
+/*
+ * HT_FBK_CFG0:
+ */
+#define HT_FBK_CFG0			0x1354
+#define HT_FBK_CFG0_HTMCS0FBK		FIELD32(0x0000000f)
+#define HT_FBK_CFG0_HTMCS1FBK		FIELD32(0x000000f0)
+#define HT_FBK_CFG0_HTMCS2FBK		FIELD32(0x00000f00)
+#define HT_FBK_CFG0_HTMCS3FBK		FIELD32(0x0000f000)
+#define HT_FBK_CFG0_HTMCS4FBK		FIELD32(0x000f0000)
+#define HT_FBK_CFG0_HTMCS5FBK		FIELD32(0x00f00000)
+#define HT_FBK_CFG0_HTMCS6FBK		FIELD32(0x0f000000)
+#define HT_FBK_CFG0_HTMCS7FBK		FIELD32(0xf0000000)
+
+/*
+ * HT_FBK_CFG1:
+ */
+#define HT_FBK_CFG1			0x1358
+#define HT_FBK_CFG1_HTMCS8FBK		FIELD32(0x0000000f)
+#define HT_FBK_CFG1_HTMCS9FBK		FIELD32(0x000000f0)
+#define HT_FBK_CFG1_HTMCS10FBK		FIELD32(0x00000f00)
+#define HT_FBK_CFG1_HTMCS11FBK		FIELD32(0x0000f000)
+#define HT_FBK_CFG1_HTMCS12FBK		FIELD32(0x000f0000)
+#define HT_FBK_CFG1_HTMCS13FBK		FIELD32(0x00f00000)
+#define HT_FBK_CFG1_HTMCS14FBK		FIELD32(0x0f000000)
+#define HT_FBK_CFG1_HTMCS15FBK		FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG0:
+ */
+#define LG_FBK_CFG0			0x135c
+#define LG_FBK_CFG0_OFDMMCS0FBK		FIELD32(0x0000000f)
+#define LG_FBK_CFG0_OFDMMCS1FBK		FIELD32(0x000000f0)
+#define LG_FBK_CFG0_OFDMMCS2FBK		FIELD32(0x00000f00)
+#define LG_FBK_CFG0_OFDMMCS3FBK		FIELD32(0x0000f000)
+#define LG_FBK_CFG0_OFDMMCS4FBK		FIELD32(0x000f0000)
+#define LG_FBK_CFG0_OFDMMCS5FBK		FIELD32(0x00f00000)
+#define LG_FBK_CFG0_OFDMMCS6FBK		FIELD32(0x0f000000)
+#define LG_FBK_CFG0_OFDMMCS7FBK		FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG1:
+ */
+#define LG_FBK_CFG1			0x1360
+#define LG_FBK_CFG0_CCKMCS0FBK		FIELD32(0x0000000f)
+#define LG_FBK_CFG0_CCKMCS1FBK		FIELD32(0x000000f0)
+#define LG_FBK_CFG0_CCKMCS2FBK		FIELD32(0x00000f00)
+#define LG_FBK_CFG0_CCKMCS3FBK		FIELD32(0x0000f000)
+
+/*
+ * CCK_PROT_CFG: CCK Protection
+ * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
+ * PROTECT_CTRL: Protection control frame type for CCK TX
+ *               0:none, 1:RTS/CTS, 2:CTS-to-self
+ * PROTECT_NAV: TXOP protection type for CCK TX
+ *              0:none, 1:ShortNAVprotect, 2:LongNAVProtect
+ * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM40: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF40: CCK TXOP allowance, 0:disallow
+ * RTS_TH_EN: RTS threshold enable on CCK TX
+ */
+#define CCK_PROT_CFG			0x1364
+#define CCK_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define CCK_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define CCK_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define CCK_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * OFDM_PROT_CFG: OFDM Protection
+ */
+#define OFDM_PROT_CFG			0x1368
+#define OFDM_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define OFDM_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define OFDM_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define OFDM_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * MM20_PROT_CFG: MM20 Protection
+ */
+#define MM20_PROT_CFG			0x136c
+#define MM20_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define MM20_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define MM20_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define MM20_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * MM40_PROT_CFG: MM40 Protection
+ */
+#define MM40_PROT_CFG			0x1370
+#define MM40_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define MM40_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define MM40_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define MM40_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * GF20_PROT_CFG: GF20 Protection
+ */
+#define GF20_PROT_CFG			0x1374
+#define GF20_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define GF20_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define GF20_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define GF20_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * GF40_PROT_CFG: GF40 Protection
+ */
+#define GF40_PROT_CFG			0x1378
+#define GF40_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
+#define GF40_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
+#define GF40_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
+#define GF40_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
+
+/*
+ * EXP_CTS_TIME:
+ */
+#define EXP_CTS_TIME			0x137c
+
+/*
+ * EXP_ACK_TIME:
+ */
+#define EXP_ACK_TIME			0x1380
+
+/*
+ * RX_FILTER_CFG: RX configuration register.
+ */
+#define RX_FILTER_CFG			0x1400
+#define RX_FILTER_CFG_DROP_CRC_ERROR	FIELD32(0x00000001)
+#define RX_FILTER_CFG_DROP_PHY_ERROR	FIELD32(0x00000002)
+#define RX_FILTER_CFG_DROP_NOT_TO_ME	FIELD32(0x00000004)
+#define RX_FILTER_CFG_DROP_NOT_MY_BSSD	FIELD32(0x00000008)
+#define RX_FILTER_CFG_DROP_VER_ERROR	FIELD32(0x00000010)
+#define RX_FILTER_CFG_DROP_MULTICAST	FIELD32(0x00000020)
+#define RX_FILTER_CFG_DROP_BROADCAST	FIELD32(0x00000040)
+#define RX_FILTER_CFG_DROP_DUPLICATE	FIELD32(0x00000080)
+#define RX_FILTER_CFG_DROP_CF_END_ACK	FIELD32(0x00000100)
+#define RX_FILTER_CFG_DROP_CF_END	FIELD32(0x00000200)
+#define RX_FILTER_CFG_DROP_ACK		FIELD32(0x00000400)
+#define RX_FILTER_CFG_DROP_CTS		FIELD32(0x00000800)
+#define RX_FILTER_CFG_DROP_RTS		FIELD32(0x00001000)
+#define RX_FILTER_CFG_DROP_PSPOLL	FIELD32(0x00002000)
+#define RX_FILTER_CFG_DROP_BA		FIELD32(0x00004000)
+#define RX_FILTER_CFG_DROP_BAR		FIELD32(0x00008000)
+#define RX_FILTER_CFG_DROP_CNTL		FIELD32(0x00010000)
+
+/*
+ * AUTO_RSP_CFG:
+ * AUTORESPONDER: 0: disable, 1: enable
+ * BAC_ACK_POLICY: 0:long, 1:short preamble
+ * CTS_40_MMODE: Response CTS 40MHz duplicate mode
+ * CTS_40_MREF: Response CTS 40MHz duplicate mode
+ * AR_PREAMBLE: Auto responder preamble 0:long, 1:short preamble
+ * DUAL_CTS_EN: Power bit value in control frame
+ * ACK_CTS_PSM_BIT:Power bit value in control frame
+ */
+#define AUTO_RSP_CFG			0x1404
+#define AUTO_RSP_CFG_AUTORESPONDER	FIELD32(0x00000001)
+#define AUTO_RSP_CFG_BAC_ACK_POLICY	FIELD32(0x00000002)
+#define AUTO_RSP_CFG_CTS_40_MMODE	FIELD32(0x00000004)
+#define AUTO_RSP_CFG_CTS_40_MREF	FIELD32(0x00000008)
+#define AUTO_RSP_CFG_AR_PREAMBLE	FIELD32(0x00000010)
+#define AUTO_RSP_CFG_DUAL_CTS_EN	FIELD32(0x00000040)
+#define AUTO_RSP_CFG_ACK_CTS_PSM_BIT	FIELD32(0x00000080)
+
+/*
+ * LEGACY_BASIC_RATE:
+ */
+#define LEGACY_BASIC_RATE		0x1408
+
+/*
+ * HT_BASIC_RATE:
+ */
+#define HT_BASIC_RATE			0x140c
+
+/*
+ * HT_CTRL_CFG:
+ */
+#define HT_CTRL_CFG			0x1410
+
+/*
+ * SIFS_COST_CFG:
+ */
+#define SIFS_COST_CFG			0x1414
+
+/*
+ * RX_PARSER_CFG:
+ * Set NAV for all received frames
+ */
+#define RX_PARSER_CFG			0x1418
+
+/*
+ * TX_SEC_CNT0:
+ */
+#define TX_SEC_CNT0			0x1500
+
+/*
+ * RX_SEC_CNT0:
+ */
+#define RX_SEC_CNT0			0x1504
+
+/*
+ * CCMP_FC_MUTE:
+ */
+#define CCMP_FC_MUTE			0x1508
+
+/*
+ * TXOP_HLDR_ADDR0:
+ */
+#define TXOP_HLDR_ADDR0			0x1600
+
+/*
+ * TXOP_HLDR_ADDR1:
+ */
+#define TXOP_HLDR_ADDR1			0x1604
+
+/*
+ * TXOP_HLDR_ET:
+ */
+#define TXOP_HLDR_ET			0x1608
+
+/*
+ * QOS_CFPOLL_RA_DW0:
+ */
+#define QOS_CFPOLL_RA_DW0		0x160c
+
+/*
+ * QOS_CFPOLL_RA_DW1:
+ */
+#define QOS_CFPOLL_RA_DW1		0x1610
+
+/*
+ * QOS_CFPOLL_QC:
+ */
+#define QOS_CFPOLL_QC			0x1614
+
+/*
+ * RX_STA_CNT0: RX PLCP error count & RX CRC error count
+ */
+#define RX_STA_CNT0			0x1700
+#define RX_STA_CNT0_CRC_ERR		FIELD32(0x0000ffff)
+#define RX_STA_CNT0_PHY_ERR		FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT1: RX False CCA count & RX LONG frame count
+ */
+#define RX_STA_CNT1			0x1704
+#define RX_STA_CNT1_FALSE_CCA		FIELD32(0x0000ffff)
+#define RX_STA_CNT1_PLCP_ERR		FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT2:
+ */
+#define RX_STA_CNT2			0x1708
+#define RX_STA_CNT2_RX_DUPLI_COUNT	FIELD32(0x0000ffff)
+#define RX_STA_CNT2_RX_FIFO_OVERFLOW	FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT0: TX Beacon count
+ */
+#define TX_STA_CNT0			0x170c
+#define TX_STA_CNT0_TX_FAIL_COUNT	FIELD32(0x0000ffff)
+#define TX_STA_CNT0_TX_BEACON_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT1: TX tx count
+ */
+#define TX_STA_CNT1			0x1710
+#define TX_STA_CNT1_TX_SUCCESS		FIELD32(0x0000ffff)
+#define TX_STA_CNT1_TX_RETRANSMIT	FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT2: TX tx count
+ */
+#define TX_STA_CNT2			0x1714
+#define TX_STA_CNT2_TX_ZERO_LEN_COUNT	FIELD32(0x0000ffff)
+#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_STA_FIFO: TX Result for specific PID status fifo register
+ */
+#define TX_STA_FIFO			0x1718
+#define TX_STA_FIFO_VALID		FIELD32(0x00000001)
+#define TX_STA_FIFO_PID_TYPE		FIELD32(0x0000001e)
+#define TX_STA_FIFO_TX_SUCCESS		FIELD32(0x00000020)
+#define TX_STA_FIFO_TX_AGGRE		FIELD32(0x00000040)
+#define TX_STA_FIFO_TX_ACK_REQUIRED	FIELD32(0x00000080)
+#define TX_STA_FIFO_WCID		FIELD32(0x0000ff00)
+#define TX_STA_FIFO_SUCCESS_RATE	FIELD32(0xffff0000)
+#define TX_STA_FIFO_MCS			FIELD32(0x007f0000)
+#define TX_STA_FIFO_PHYMODE		FIELD32(0xc0000000)
+
+/*
+ * TX_AGG_CNT: Debug counter
+ */
+#define TX_AGG_CNT			0x171c
+#define TX_AGG_CNT_NON_AGG_TX_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT_AGG_TX_COUNT		FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT0:
+ */
+#define TX_AGG_CNT0			0x1720
+#define TX_AGG_CNT0_AGG_SIZE_1_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT0_AGG_SIZE_2_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT1:
+ */
+#define TX_AGG_CNT1			0x1724
+#define TX_AGG_CNT1_AGG_SIZE_3_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT1_AGG_SIZE_4_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT2:
+ */
+#define TX_AGG_CNT2			0x1728
+#define TX_AGG_CNT2_AGG_SIZE_5_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT2_AGG_SIZE_6_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT3:
+ */
+#define TX_AGG_CNT3			0x172c
+#define TX_AGG_CNT3_AGG_SIZE_7_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT3_AGG_SIZE_8_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT4:
+ */
+#define TX_AGG_CNT4			0x1730
+#define TX_AGG_CNT4_AGG_SIZE_9_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT4_AGG_SIZE_10_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT5:
+ */
+#define TX_AGG_CNT5			0x1734
+#define TX_AGG_CNT5_AGG_SIZE_11_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT5_AGG_SIZE_12_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT6:
+ */
+#define TX_AGG_CNT6			0x1738
+#define TX_AGG_CNT6_AGG_SIZE_13_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT6_AGG_SIZE_14_COUNT	FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT7:
+ */
+#define TX_AGG_CNT7			0x173c
+#define TX_AGG_CNT7_AGG_SIZE_15_COUNT	FIELD32(0x0000ffff)
+#define TX_AGG_CNT7_AGG_SIZE_16_COUNT	FIELD32(0xffff0000)
+
+/*
+ * MPDU_DENSITY_CNT:
+ * TX_ZERO_DEL: TX zero length delimiter count
+ * RX_ZERO_DEL: RX zero length delimiter count
+ */
+#define MPDU_DENSITY_CNT		0x1740
+#define MPDU_DENSITY_CNT_TX_ZERO_DEL	FIELD32(0x0000ffff)
+#define MPDU_DENSITY_CNT_RX_ZERO_DEL	FIELD32(0xffff0000)
+
+/*
+ * Security key table memory.
+ * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
+ * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
+ * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
+ * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
+ * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry
+ * SHARED_KEY_MODE_BASE: 4-byte * 16-entry
+ */
+#define MAC_WCID_BASE			0x1800
+#define PAIRWISE_KEY_TABLE_BASE		0x4000
+#define MAC_IVEIV_TABLE_BASE		0x6000
+#define MAC_WCID_ATTRIBUTE_BASE		0x6800
+#define SHARED_KEY_TABLE_BASE		0x6c00
+#define SHARED_KEY_MODE_BASE		0x7000
+
+#define MAC_WCID_ENTRY(__idx) \
+	( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+#define PAIRWISE_KEY_ENTRY(__idx) \
+	( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define MAC_IVEIV_ENTRY(__idx) \
+	( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) )
+#define MAC_WCID_ATTR_ENTRY(__idx) \
+	( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+#define SHARED_KEY_ENTRY(__idx) \
+	( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define SHARED_KEY_MODE_ENTRY(__idx) \
+	( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+
+struct mac_wcid_entry {
+	u8 mac[6];
+	u8 reserved[2];
+} __attribute__ ((packed));
+
+struct hw_key_entry {
+	u8 key[16];
+	u8 tx_mic[8];
+	u8 rx_mic[8];
+} __attribute__ ((packed));
+
+struct mac_iveiv_entry {
+	u8 iv[8];
+} __attribute__ ((packed));
+
+/*
+ * MAC_WCID_ATTRIBUTE:
+ */
+#define MAC_WCID_ATTRIBUTE_KEYTAB	FIELD32(0x00000001)
+#define MAC_WCID_ATTRIBUTE_CIPHER	FIELD32(0x0000000e)
+#define MAC_WCID_ATTRIBUTE_BSS_IDX	FIELD32(0x00000070)
+#define MAC_WCID_ATTRIBUTE_RX_WIUDF	FIELD32(0x00000380)
+
+/*
+ * SHARED_KEY_MODE:
+ */
+#define SHARED_KEY_MODE_BSS0_KEY0	FIELD32(0x00000007)
+#define SHARED_KEY_MODE_BSS0_KEY1	FIELD32(0x00000070)
+#define SHARED_KEY_MODE_BSS0_KEY2	FIELD32(0x00000700)
+#define SHARED_KEY_MODE_BSS0_KEY3	FIELD32(0x00007000)
+#define SHARED_KEY_MODE_BSS1_KEY0	FIELD32(0x00070000)
+#define SHARED_KEY_MODE_BSS1_KEY1	FIELD32(0x00700000)
+#define SHARED_KEY_MODE_BSS1_KEY2	FIELD32(0x07000000)
+#define SHARED_KEY_MODE_BSS1_KEY3	FIELD32(0x70000000)
+
+/*
+ * HOST-MCU communication
+ */
+
+/*
+ * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ */
+#define H2M_MAILBOX_CSR			0x7010
+#define H2M_MAILBOX_CSR_ARG0		FIELD32(0x000000ff)
+#define H2M_MAILBOX_CSR_ARG1		FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CSR_CMD_TOKEN	FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CSR_OWNER		FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_CID:
+ */
+#define H2M_MAILBOX_CID			0x7014
+#define H2M_MAILBOX_CID_CMD0		FIELD32(0x000000ff)
+#define H2M_MAILBOX_CID_CMD1		FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CID_CMD2		FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CID_CMD3		FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_STATUS:
+ */
+#define H2M_MAILBOX_STATUS		0x701c
+
+/*
+ * H2M_INT_SRC:
+ */
+#define H2M_INT_SRC			0x7024
+
+/*
+ * H2M_BBP_AGENT:
+ */
+#define H2M_BBP_AGENT			0x7028
+
+/*
+ * MCU_LEDCS: LED control for MCU Mailbox.
+ */
+#define MCU_LEDCS_LED_MODE		FIELD8(0x1f)
+#define MCU_LEDCS_POLARITY		FIELD8(0x01)
+
+/*
+ * HW_CS_CTS_BASE:
+ * Carrier-sense CTS frame base address.
+ * It's where mac stores carrier-sense frame for carrier-sense function.
+ */
+#define HW_CS_CTS_BASE			0x7700
+
+/*
+ * HW_DFS_CTS_BASE:
+ * DFS CTS frame base address. It's where mac stores CTS frame for DFS.
+ */
+#define HW_DFS_CTS_BASE			0x7780
+
+/*
+ * TXRX control registers - base address 0x3000
+ */
+
+/*
+ * TXRX_CSR1:
+ * rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+ */
+#define TXRX_CSR1			0x77d0
+
+/*
+ * HW_DEBUG_SETTING_BASE:
+ * since NULL frame won't be that long (256 byte)
+ * We steal 16 tail bytes to save debugging settings
+ */
+#define HW_DEBUG_SETTING_BASE		0x77f0
+#define HW_DEBUG_SETTING_BASE2		0x7770
+
+/*
+ * HW_BEACON_BASE
+ * In order to support maximum 8 MBSS and its maximum length
+ * is 512 bytes for each beacon
+ * Three section discontinue memory segments will be used.
+ * 1. The original region for BCN 0~3
+ * 2. Extract memory from FCE table for BCN 4~5
+ * 3. Extract memory from Pair-wise key table for BCN 6~7
+ *    It occupied those memory of wcid 238~253 for BCN 6
+ *    and wcid 222~237 for BCN 7
+ *
+ * IMPORTANT NOTE: Not sure why legacy driver does this,
+ * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
+ */
+#define HW_BEACON_BASE0			0x7800
+#define HW_BEACON_BASE1			0x7a00
+#define HW_BEACON_BASE2			0x7c00
+#define HW_BEACON_BASE3			0x7e00
+#define HW_BEACON_BASE4			0x7200
+#define HW_BEACON_BASE5			0x7400
+#define HW_BEACON_BASE6			0x5dc0
+#define HW_BEACON_BASE7			0x5bc0
+
+#define HW_BEACON_OFFSET(__index) \
+	( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
+	  (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
+	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+
+/*
+ * BBP registers.
+ * The wordsize of the BBP is 8 bits.
+ */
+
+/*
+ * BBP 1: TX Antenna
+ */
+#define BBP1_TX_POWER			FIELD8(0x07)
+#define BBP1_TX_ANTENNA			FIELD8(0x18)
+
+/*
+ * BBP 3: RX Antenna
+ */
+#define BBP3_RX_ANTENNA			FIELD8(0x18)
+#define BBP3_HT40_PLUS			FIELD8(0x20)
+
+/*
+ * BBP 4: Bandwidth
+ */
+#define BBP4_TX_BF			FIELD8(0x01)
+#define BBP4_BANDWIDTH			FIELD8(0x18)
+
+/*
+ * RFCSR registers
+ * The wordsize of the RFCSR is 8 bits.
+ */
+
+/*
+ * RFCSR 6:
+ */
+#define RFCSR6_R			FIELD8(0x03)
+
+/*
+ * RFCSR 7:
+ */
+#define RFCSR7_RF_TUNING		FIELD8(0x01)
+
+/*
+ * RFCSR 12:
+ */
+#define RFCSR12_TX_POWER		FIELD8(0x1f)
+
+/*
+ * RFCSR 22:
+ */
+#define RFCSR22_BASEBAND_LOOPBACK	FIELD8(0x01)
+
+/*
+ * RFCSR 23:
+ */
+#define RFCSR23_FREQ_OFFSET		FIELD8(0x7f)
+
+/*
+ * RFCSR 30:
+ */
+#define RFCSR30_RF_CALIBRATION		FIELD8(0x80)
+
+/*
+ * RF registers
+ */
+
+/*
+ * RF 2
+ */
+#define RF2_ANTENNA_RX2			FIELD32(0x00000040)
+#define RF2_ANTENNA_TX1			FIELD32(0x00004000)
+#define RF2_ANTENNA_RX1			FIELD32(0x00020000)
+
+/*
+ * RF 3
+ */
+#define RF3_TXPOWER_G			FIELD32(0x00003e00)
+#define RF3_TXPOWER_A_7DBM_BOOST	FIELD32(0x00000200)
+#define RF3_TXPOWER_A			FIELD32(0x00003c00)
+
+/*
+ * RF 4
+ */
+#define RF4_TXPOWER_G			FIELD32(0x000007c0)
+#define RF4_TXPOWER_A_7DBM_BOOST	FIELD32(0x00000040)
+#define RF4_TXPOWER_A			FIELD32(0x00000780)
+#define RF4_FREQ_OFFSET			FIELD32(0x001f8000)
+#define RF4_HT40			FIELD32(0x00200000)
+
+/*
+ * EEPROM content.
+ * The wordsize of the EEPROM is 16 bits.
+ */
+
+/*
+ * EEPROM Version
+ */
+#define EEPROM_VERSION			0x0001
+#define EEPROM_VERSION_FAE		FIELD16(0x00ff)
+#define EEPROM_VERSION_VERSION		FIELD16(0xff00)
+
+/*
+ * HW MAC address.
+ */
+#define EEPROM_MAC_ADDR_0		0x0002
+#define EEPROM_MAC_ADDR_BYTE0		FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE1		FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_1		0x0003
+#define EEPROM_MAC_ADDR_BYTE2		FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE3		FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_2		0x0004
+#define EEPROM_MAC_ADDR_BYTE4		FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE5		FIELD16(0xff00)
+
+/*
+ * EEPROM ANTENNA config
+ * RXPATH: 1: 1R, 2: 2R, 3: 3R
+ * TXPATH: 1: 1T, 2: 2T
+ */
+#define	EEPROM_ANTENNA			0x001a
+#define EEPROM_ANTENNA_RXPATH		FIELD16(0x000f)
+#define EEPROM_ANTENNA_TXPATH		FIELD16(0x00f0)
+#define EEPROM_ANTENNA_RF_TYPE		FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC config
+ * CARDBUS_ACCEL: 0 - enable, 1 - disable
+ */
+#define	EEPROM_NIC			0x001b
+#define EEPROM_NIC_HW_RADIO		FIELD16(0x0001)
+#define EEPROM_NIC_DYNAMIC_TX_AGC	FIELD16(0x0002)
+#define EEPROM_NIC_EXTERNAL_LNA_BG	FIELD16(0x0004)
+#define EEPROM_NIC_EXTERNAL_LNA_A	FIELD16(0x0008)
+#define EEPROM_NIC_CARDBUS_ACCEL	FIELD16(0x0010)
+#define EEPROM_NIC_BW40M_SB_BG		FIELD16(0x0020)
+#define EEPROM_NIC_BW40M_SB_A		FIELD16(0x0040)
+#define EEPROM_NIC_WPS_PBC		FIELD16(0x0080)
+#define EEPROM_NIC_BW40M_BG		FIELD16(0x0100)
+#define EEPROM_NIC_BW40M_A		FIELD16(0x0200)
+
+/*
+ * EEPROM frequency
+ */
+#define	EEPROM_FREQ			0x001d
+#define EEPROM_FREQ_OFFSET		FIELD16(0x00ff)
+#define EEPROM_FREQ_LED_MODE		FIELD16(0x7f00)
+#define EEPROM_FREQ_LED_POLARITY	FIELD16(0x1000)
+
+/*
+ * EEPROM LED
+ * POLARITY_RDY_G: Polarity RDY_G setting.
+ * POLARITY_RDY_A: Polarity RDY_A setting.
+ * POLARITY_ACT: Polarity ACT setting.
+ * POLARITY_GPIO_0: Polarity GPIO0 setting.
+ * POLARITY_GPIO_1: Polarity GPIO1 setting.
+ * POLARITY_GPIO_2: Polarity GPIO2 setting.
+ * POLARITY_GPIO_3: Polarity GPIO3 setting.
+ * POLARITY_GPIO_4: Polarity GPIO4 setting.
+ * LED_MODE: Led mode.
+ */
+#define EEPROM_LED1			0x001e
+#define EEPROM_LED2			0x001f
+#define EEPROM_LED3			0x0020
+#define EEPROM_LED_POLARITY_RDY_BG	FIELD16(0x0001)
+#define EEPROM_LED_POLARITY_RDY_A	FIELD16(0x0002)
+#define EEPROM_LED_POLARITY_ACT		FIELD16(0x0004)
+#define EEPROM_LED_POLARITY_GPIO_0	FIELD16(0x0008)
+#define EEPROM_LED_POLARITY_GPIO_1	FIELD16(0x0010)
+#define EEPROM_LED_POLARITY_GPIO_2	FIELD16(0x0020)
+#define EEPROM_LED_POLARITY_GPIO_3	FIELD16(0x0040)
+#define EEPROM_LED_POLARITY_GPIO_4	FIELD16(0x0080)
+#define EEPROM_LED_LED_MODE		FIELD16(0x1f00)
+
+/*
+ * EEPROM LNA
+ */
+#define EEPROM_LNA			0x0022
+#define EEPROM_LNA_BG			FIELD16(0x00ff)
+#define EEPROM_LNA_A0			FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG offset
+ */
+#define EEPROM_RSSI_BG			0x0023
+#define EEPROM_RSSI_BG_OFFSET0		FIELD16(0x00ff)
+#define EEPROM_RSSI_BG_OFFSET1		FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG2 offset
+ */
+#define EEPROM_RSSI_BG2			0x0024
+#define EEPROM_RSSI_BG2_OFFSET2		FIELD16(0x00ff)
+#define EEPROM_RSSI_BG2_LNA_A1		FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A offset
+ */
+#define EEPROM_RSSI_A			0x0025
+#define EEPROM_RSSI_A_OFFSET0		FIELD16(0x00ff)
+#define EEPROM_RSSI_A_OFFSET1		FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A2 offset
+ */
+#define EEPROM_RSSI_A2			0x0026
+#define EEPROM_RSSI_A2_OFFSET2		FIELD16(0x00ff)
+#define EEPROM_RSSI_A2_LNA_A2		FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
+ *	This is delta in 40MHZ.
+ * VALUE: Tx Power dalta value (MAX=4)
+ * TYPE: 1: Plus the delta value, 0: minus the delta value
+ * TXPOWER: Enable:
+ */
+#define EEPROM_TXPOWER_DELTA		0x0028
+#define EEPROM_TXPOWER_DELTA_VALUE	FIELD16(0x003f)
+#define EEPROM_TXPOWER_DELTA_TYPE	FIELD16(0x0040)
+#define EEPROM_TXPOWER_DELTA_TXPOWER	FIELD16(0x0080)
+
+/*
+ * EEPROM TXPOWER 802.11BG
+ */
+#define	EEPROM_TXPOWER_BG1		0x0029
+#define	EEPROM_TXPOWER_BG2		0x0030
+#define EEPROM_TXPOWER_BG_SIZE		7
+#define EEPROM_TXPOWER_BG_1		FIELD16(0x00ff)
+#define EEPROM_TXPOWER_BG_2		FIELD16(0xff00)
+
+/*
+ * EEPROM TXPOWER 802.11A
+ */
+#define EEPROM_TXPOWER_A1		0x003c
+#define EEPROM_TXPOWER_A2		0x0053
+#define EEPROM_TXPOWER_A_SIZE		6
+#define EEPROM_TXPOWER_A_1		FIELD16(0x00ff)
+#define EEPROM_TXPOWER_A_2		FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower byrate: 20MHZ power
+ */
+#define EEPROM_TXPOWER_BYRATE		0x006f
+
+/*
+ * EEPROM BBP.
+ */
+#define	EEPROM_BBP_START		0x0078
+#define EEPROM_BBP_SIZE			16
+#define EEPROM_BBP_VALUE		FIELD16(0x00ff)
+#define EEPROM_BBP_REG_ID		FIELD16(0xff00)
+
+/*
+ * MCU mailbox commands.
+ */
+#define MCU_SLEEP			0x30
+#define MCU_WAKEUP			0x31
+#define MCU_RADIO_OFF			0x35
+#define MCU_CURRENT			0x36
+#define MCU_LED				0x50
+#define MCU_LED_STRENGTH		0x51
+#define MCU_LED_1			0x52
+#define MCU_LED_2			0x53
+#define MCU_LED_3			0x54
+#define MCU_RADAR			0x60
+#define MCU_BOOT_SIGNAL			0x72
+#define MCU_BBP_SIGNAL			0x80
+#define MCU_POWER_SAVE			0x83
+
+/*
+ * MCU mailbox tokens
+ */
+#define TOKEN_WAKUP			3
+
+/*
+ * DMA descriptor defines.
+ */
+#define TXWI_DESC_SIZE			( 4 * sizeof(__le32) )
+#define RXWI_DESC_SIZE			( 4 * sizeof(__le32) )
+
+/*
+ * TX WI structure
+ */
+
+/*
+ * Word0
+ * FRAG: 1 To inform TKIP engine this is a fragment.
+ * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
+ * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
+ * BW: Channel bandwidth 20MHz or 40 MHz
+ * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ */
+#define TXWI_W0_FRAG			FIELD32(0x00000001)
+#define TXWI_W0_MIMO_PS			FIELD32(0x00000002)
+#define TXWI_W0_CF_ACK			FIELD32(0x00000004)
+#define TXWI_W0_TS			FIELD32(0x00000008)
+#define TXWI_W0_AMPDU			FIELD32(0x00000010)
+#define TXWI_W0_MPDU_DENSITY		FIELD32(0x000000e0)
+#define TXWI_W0_TX_OP			FIELD32(0x00000300)
+#define TXWI_W0_MCS			FIELD32(0x007f0000)
+#define TXWI_W0_BW			FIELD32(0x00800000)
+#define TXWI_W0_SHORT_GI		FIELD32(0x01000000)
+#define TXWI_W0_STBC			FIELD32(0x06000000)
+#define TXWI_W0_IFS			FIELD32(0x08000000)
+#define TXWI_W0_PHYMODE			FIELD32(0xc0000000)
+
+/*
+ * Word1
+ */
+#define TXWI_W1_ACK			FIELD32(0x00000001)
+#define TXWI_W1_NSEQ			FIELD32(0x00000002)
+#define TXWI_W1_BW_WIN_SIZE		FIELD32(0x000000fc)
+#define TXWI_W1_WIRELESS_CLI_ID		FIELD32(0x0000ff00)
+#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
+#define TXWI_W1_PACKETID		FIELD32(0xf0000000)
+
+/*
+ * Word2
+ */
+#define TXWI_W2_IV			FIELD32(0xffffffff)
+
+/*
+ * Word3
+ */
+#define TXWI_W3_EIV			FIELD32(0xffffffff)
+
+/*
+ * RX WI structure
+ */
+
+/*
+ * Word0
+ */
+#define RXWI_W0_WIRELESS_CLI_ID		FIELD32(0x000000ff)
+#define RXWI_W0_KEY_INDEX		FIELD32(0x00000300)
+#define RXWI_W0_BSSID			FIELD32(0x00001c00)
+#define RXWI_W0_UDF			FIELD32(0x0000e000)
+#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
+#define RXWI_W0_TID			FIELD32(0xf0000000)
+
+/*
+ * Word1
+ */
+#define RXWI_W1_FRAG			FIELD32(0x0000000f)
+#define RXWI_W1_SEQUENCE		FIELD32(0x0000fff0)
+#define RXWI_W1_MCS			FIELD32(0x007f0000)
+#define RXWI_W1_BW			FIELD32(0x00800000)
+#define RXWI_W1_SHORT_GI		FIELD32(0x01000000)
+#define RXWI_W1_STBC			FIELD32(0x06000000)
+#define RXWI_W1_PHYMODE			FIELD32(0xc0000000)
+
+/*
+ * Word2
+ */
+#define RXWI_W2_RSSI0			FIELD32(0x000000ff)
+#define RXWI_W2_RSSI1			FIELD32(0x0000ff00)
+#define RXWI_W2_RSSI2			FIELD32(0x00ff0000)
+
+/*
+ * Word3
+ */
+#define RXWI_W3_SNR0			FIELD32(0x000000ff)
+#define RXWI_W3_SNR1			FIELD32(0x0000ff00)
+
+/*
+ * Macros for converting txpower from EEPROM to mac80211 value
+ * and from mac80211 value to register value.
+ */
+#define MIN_G_TXPOWER	0
+#define MIN_A_TXPOWER	-7
+#define MAX_G_TXPOWER	31
+#define MAX_A_TXPOWER	15
+#define DEFAULT_TXPOWER	5
+
+#define TXPOWER_G_FROM_DEV(__txpower) \
+	((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_G_TO_DEV(__txpower) \
+	clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
+
+#define TXPOWER_A_FROM_DEV(__txpower) \
+	((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_A_TO_DEV(__txpower) \
+	clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+
+#endif /* RT2800_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,2289 @@
+/*
+	Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+	Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com>
+
+	Based on the original rt2800pci.c and rt2800usb.c.
+	  Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	  Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
+	  Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	  Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
+	  Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	  Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>
+	  Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	  <http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2800lib
+	Abstract: rt2800 generic device routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE)
+#include "rt2x00usb.h"
+#endif
+#include "rt2800lib.h"
+#include "rt2800.h"
+#include "rt2800usb.h"
+
+MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
+MODULE_DESCRIPTION("rt2800 library");
+MODULE_LICENSE("GPL");
+
+/*
+ * Register access.
+ * All access to the CSR registers will go through the methods
+ * rt2800_register_read and rt2800_register_write.
+ * BBP and RF register require indirect register access,
+ * and use the CSR registers BBPCSR and RFCSR to achieve this.
+ * These indirect registers work with busy bits,
+ * and we will try maximal REGISTER_BUSY_COUNT times to access
+ * the register while taking a REGISTER_BUSY_DELAY us delay
+ * between each attampt. When the busy bit is still set at that time,
+ * the access attempt is considered to have failed,
+ * and we will print an error.
+ * The _lock versions must be used if you already hold the csr_mutex
+ */
+#define WAIT_FOR_BBP(__dev, __reg) \
+	rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RFCSR(__dev, __reg) \
+	rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+	rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+#define WAIT_FOR_MCU(__dev, __reg) \
+	rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \
+			    H2M_MAILBOX_CSR_OWNER, (__reg))
+
+static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
+			     const unsigned int word, const u8 value)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the BBP becomes available, afterwards we
+	 * can safely write the new data into the register.
+	 */
+	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+		reg = 0;
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_VALUE, value);
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
+		if (rt2x00_intf_is_pci(rt2x00dev))
+			rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
+
+		rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+	}
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev,
+			    const unsigned int word, u8 *value)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the BBP becomes available, afterwards we
+	 * can safely write the read request into the register.
+	 * After the data has been written, we wait until hardware
+	 * returns the correct value, if at any time the register
+	 * doesn't become available in time, reg will be 0xffffffff
+	 * which means we return 0xff to the caller.
+	 */
+	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+		reg = 0;
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
+		if (rt2x00_intf_is_pci(rt2x00dev))
+			rt2x00_set_field32(&reg, BBP_CSR_CFG_BBP_RW_MODE, 1);
+
+		rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+		WAIT_FOR_BBP(rt2x00dev, &reg);
+	}
+
+	*value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+			       const unsigned int word, const u8 value)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the RFCSR becomes available, afterwards we
+	 * can safely write the new data into the register.
+	 */
+	if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+		reg = 0;
+		rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+		rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+		rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+		rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+		rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+	}
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+			      const unsigned int word, u8 *value)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the RFCSR becomes available, afterwards we
+	 * can safely write the read request into the register.
+	 * After the data has been written, we wait until hardware
+	 * returns the correct value, if at any time the register
+	 * doesn't become available in time, reg will be 0xffffffff
+	 * which means we return 0xff to the caller.
+	 */
+	if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+		reg = 0;
+		rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+		rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+		rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+		rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+
+		WAIT_FOR_RFCSR(rt2x00dev, &reg);
+	}
+
+	*value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
+			    const unsigned int word, const u32 value)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the RF becomes available, afterwards we
+	 * can safely write the new data into the register.
+	 */
+	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+		reg = 0;
+		rt2x00_set_field32(&reg, RF_CSR_CFG0_REG_VALUE_BW, value);
+		rt2x00_set_field32(&reg, RF_CSR_CFG0_STANDBYMODE, 0);
+		rt2x00_set_field32(&reg, RF_CSR_CFG0_SEL, 0);
+		rt2x00_set_field32(&reg, RF_CSR_CFG0_BUSY, 1);
+
+		rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
+		rt2x00_rf_write(rt2x00dev, word, value);
+	}
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
+			const u8 command, const u8 token,
+			const u8 arg0, const u8 arg1)
+{
+	u32 reg;
+
+	/*
+	 * RT2880 and RT3052 don't support MCU requests.
+	 */
+	if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
+	    rt2x00_rt(&rt2x00dev->chip, RT3052))
+		return;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	/*
+	 * Wait until the MCU becomes available, afterwards we
+	 * can safely write the new data into the register.
+	 */
+	if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
+		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
+		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
+		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
+		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+		rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
+
+		reg = 0;
+		rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
+		rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+	}
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+EXPORT_SYMBOL_GPL(rt2800_mcu_request);
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+const struct rt2x00debug rt2800_rt2x00debug = {
+	.owner	= THIS_MODULE,
+	.csr	= {
+		.read		= rt2800_register_read,
+		.write		= rt2800_register_write,
+		.flags		= RT2X00DEBUGFS_OFFSET,
+		.word_base	= CSR_REG_BASE,
+		.word_size	= sizeof(u32),
+		.word_count	= CSR_REG_SIZE / sizeof(u32),
+	},
+	.eeprom	= {
+		.read		= rt2x00_eeprom_read,
+		.write		= rt2x00_eeprom_write,
+		.word_base	= EEPROM_BASE,
+		.word_size	= sizeof(u16),
+		.word_count	= EEPROM_SIZE / sizeof(u16),
+	},
+	.bbp	= {
+		.read		= rt2800_bbp_read,
+		.write		= rt2800_bbp_write,
+		.word_base	= BBP_BASE,
+		.word_size	= sizeof(u8),
+		.word_count	= BBP_SIZE / sizeof(u8),
+	},
+	.rf	= {
+		.read		= rt2x00_rf_read,
+		.write		= rt2800_rf_write,
+		.word_base	= RF_BASE,
+		.word_size	= sizeof(u32),
+		.word_count	= RF_SIZE / sizeof(u32),
+	},
+};
+EXPORT_SYMBOL_GPL(rt2800_rt2x00debug);
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+
+int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+	return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
+}
+EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
+
+#ifdef CONFIG_RT2X00_LIB_LEDS
+static void rt2800_brightness_set(struct led_classdev *led_cdev,
+				  enum led_brightness brightness)
+{
+	struct rt2x00_led *led =
+	    container_of(led_cdev, struct rt2x00_led, led_dev);
+	unsigned int enabled = brightness != LED_OFF;
+	unsigned int bg_mode =
+	    (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
+	unsigned int polarity =
+		rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+				   EEPROM_FREQ_LED_POLARITY);
+	unsigned int ledmode =
+		rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+				   EEPROM_FREQ_LED_MODE);
+
+	if (led->type == LED_TYPE_RADIO) {
+		rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+				      enabled ? 0x20 : 0);
+	} else if (led->type == LED_TYPE_ASSOC) {
+		rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+				      enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+	} else if (led->type == LED_TYPE_QUALITY) {
+		/*
+		 * The brightness is divided into 6 levels (0 - 5),
+		 * The specs tell us the following levels:
+		 *	0, 1 ,3, 7, 15, 31
+		 * to determine the level in a simple way we can simply
+		 * work with bitshifting:
+		 *	(1 << level) - 1
+		 */
+		rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+				      (1 << brightness / (LED_FULL / 6)) - 1,
+				      polarity);
+	}
+}
+
+static int rt2800_blink_set(struct led_classdev *led_cdev,
+			    unsigned long *delay_on, unsigned long *delay_off)
+{
+	struct rt2x00_led *led =
+	    container_of(led_cdev, struct rt2x00_led, led_dev);
+	u32 reg;
+
+	rt2800_register_read(led->rt2x00dev, LED_CFG, &reg);
+	rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
+	rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
+	rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
+	rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
+	rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
+	rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
+	rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
+	rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
+
+	return 0;
+}
+
+void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
+		     struct rt2x00_led *led, enum led_type type)
+{
+	led->rt2x00dev = rt2x00dev;
+	led->type = type;
+	led->led_dev.brightness_set = rt2800_brightness_set;
+	led->led_dev.blink_set = rt2800_blink_set;
+	led->flags = LED_INITIALIZED;
+}
+EXPORT_SYMBOL_GPL(rt2800_init_led);
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+/*
+ * Configuration handlers.
+ */
+static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
+				    struct rt2x00lib_crypto *crypto,
+				    struct ieee80211_key_conf *key)
+{
+	struct mac_wcid_entry wcid_entry;
+	struct mac_iveiv_entry iveiv_entry;
+	u32 offset;
+	u32 reg;
+
+	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
+
+	rt2800_register_read(rt2x00dev, offset, &reg);
+	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+			   !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+			   (crypto->cmd == SET_KEY) * crypto->cipher);
+	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+			   (crypto->cmd == SET_KEY) * crypto->bssidx);
+	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+	rt2800_register_write(rt2x00dev, offset, reg);
+
+	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+	memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+	if ((crypto->cipher == CIPHER_TKIP) ||
+	    (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+	    (crypto->cipher == CIPHER_AES))
+		iveiv_entry.iv[3] |= 0x20;
+	iveiv_entry.iv[3] |= key->keyidx << 6;
+	rt2800_register_multiwrite(rt2x00dev, offset,
+				      &iveiv_entry, sizeof(iveiv_entry));
+
+	offset = MAC_WCID_ENTRY(key->hw_key_idx);
+
+	memset(&wcid_entry, 0, sizeof(wcid_entry));
+	if (crypto->cmd == SET_KEY)
+		memcpy(&wcid_entry, crypto->address, ETH_ALEN);
+	rt2800_register_multiwrite(rt2x00dev, offset,
+				      &wcid_entry, sizeof(wcid_entry));
+}
+
+int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
+			     struct rt2x00lib_crypto *crypto,
+			     struct ieee80211_key_conf *key)
+{
+	struct hw_key_entry key_entry;
+	struct rt2x00_field32 field;
+	u32 offset;
+	u32 reg;
+
+	if (crypto->cmd == SET_KEY) {
+		key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
+
+		memcpy(key_entry.key, crypto->key,
+		       sizeof(key_entry.key));
+		memcpy(key_entry.tx_mic, crypto->tx_mic,
+		       sizeof(key_entry.tx_mic));
+		memcpy(key_entry.rx_mic, crypto->rx_mic,
+		       sizeof(key_entry.rx_mic));
+
+		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+		rt2800_register_multiwrite(rt2x00dev, offset,
+					      &key_entry, sizeof(key_entry));
+	}
+
+	/*
+	 * The cipher types are stored over multiple registers
+	 * starting with SHARED_KEY_MODE_BASE each word will have
+	 * 32 bits and contains the cipher types for 2 bssidx each.
+	 * Using the correct defines correctly will cause overhead,
+	 * so just calculate the correct offset.
+	 */
+	field.bit_offset = 4 * (key->hw_key_idx % 8);
+	field.bit_mask = 0x7 << field.bit_offset;
+
+	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+	rt2800_register_read(rt2x00dev, offset, &reg);
+	rt2x00_set_field32(&reg, field,
+			   (crypto->cmd == SET_KEY) * crypto->cipher);
+	rt2800_register_write(rt2x00dev, offset, reg);
+
+	/*
+	 * Update WCID information
+	 */
+	rt2800_config_wcid_attr(rt2x00dev, crypto, key);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_config_shared_key);
+
+int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
+			       struct rt2x00lib_crypto *crypto,
+			       struct ieee80211_key_conf *key)
+{
+	struct hw_key_entry key_entry;
+	u32 offset;
+
+	if (crypto->cmd == SET_KEY) {
+		/*
+		 * 1 pairwise key is possible per AID, this means that the AID
+		 * equals our hw_key_idx. Make sure the WCID starts _after_ the
+		 * last possible shared key entry.
+		 */
+		if (crypto->aid > (256 - 32))
+			return -ENOSPC;
+
+		key->hw_key_idx = 32 + crypto->aid;
+
+		memcpy(key_entry.key, crypto->key,
+		       sizeof(key_entry.key));
+		memcpy(key_entry.tx_mic, crypto->tx_mic,
+		       sizeof(key_entry.tx_mic));
+		memcpy(key_entry.rx_mic, crypto->rx_mic,
+		       sizeof(key_entry.rx_mic));
+
+		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+		rt2800_register_multiwrite(rt2x00dev, offset,
+					      &key_entry, sizeof(key_entry));
+	}
+
+	/*
+	 * Update WCID information
+	 */
+	rt2800_config_wcid_attr(rt2x00dev, crypto, key);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_config_pairwise_key);
+
+void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
+			  const unsigned int filter_flags)
+{
+	u32 reg;
+
+	/*
+	 * Start configuration steps.
+	 * Note that the version error will always be dropped
+	 * and broadcast frames will always be accepted since
+	 * there is no filter for it at this time.
+	 */
+	rt2800_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR,
+			   !(filter_flags & FIF_FCSFAIL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
+			   !(filter_flags & FIF_PLCPFAIL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
+			   !(filter_flags & FIF_PROMISC_IN_BSS));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
+			   !(filter_flags & FIF_ALLMULTI));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
+			   !(filter_flags & FIF_CONTROL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
+			   !(filter_flags & FIF_CONTROL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK,
+			   !(filter_flags & FIF_CONTROL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS,
+			   !(filter_flags & FIF_CONTROL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
+			   !(filter_flags & FIF_CONTROL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
+			   !(filter_flags & FIF_PSPOLL));
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
+	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
+			   !(filter_flags & FIF_CONTROL));
+	rt2800_register_write(rt2x00dev, RX_FILTER_CFG, reg);
+}
+EXPORT_SYMBOL_GPL(rt2800_config_filter);
+
+void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
+			struct rt2x00intf_conf *conf, const unsigned int flags)
+{
+	unsigned int beacon_base;
+	u32 reg;
+
+	if (flags & CONFIG_UPDATE_TYPE) {
+		/*
+		 * Clear current synchronisation setup.
+		 * For the Beacon base registers we only need to clear
+		 * the first byte since that byte contains the VALID and OWNER
+		 * bits which (when set to 0) will invalidate the entire beacon.
+		 */
+		beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
+		rt2800_register_write(rt2x00dev, beacon_base, 0);
+
+		/*
+		 * Enable synchronisation.
+		 */
+		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE,
+				   (conf->sync == TSF_SYNC_BEACON));
+		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+	}
+
+	if (flags & CONFIG_UPDATE_MAC) {
+		reg = le32_to_cpu(conf->mac[1]);
+		rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+		conf->mac[1] = cpu_to_le32(reg);
+
+		rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
+					      conf->mac, sizeof(conf->mac));
+	}
+
+	if (flags & CONFIG_UPDATE_BSSID) {
+		reg = le32_to_cpu(conf->bssid[1]);
+		rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0);
+		rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
+		conf->bssid[1] = cpu_to_le32(reg);
+
+		rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
+					      conf->bssid, sizeof(conf->bssid));
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800_config_intf);
+
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
+	rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+			   !!erp->short_preamble);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+			   !!erp->short_preamble);
+	rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+			   erp->cts_protection ? 2 : 0);
+	rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+				 erp->basic_rates);
+	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+	rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+	rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
+	rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
+	rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+	rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
+	rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
+	rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
+	rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+	rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
+	rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+			   erp->beacon_int * 16);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+}
+EXPORT_SYMBOL_GPL(rt2800_config_erp);
+
+void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
+{
+	u8 r1;
+	u8 r3;
+
+	rt2800_bbp_read(rt2x00dev, 1, &r1);
+	rt2800_bbp_read(rt2x00dev, 3, &r3);
+
+	/*
+	 * Configure the TX antenna.
+	 */
+	switch ((int)ant->tx) {
+	case 1:
+		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
+		if (rt2x00_intf_is_pci(rt2x00dev))
+			rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
+		break;
+	case 2:
+		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+		break;
+	case 3:
+		/* Do nothing */
+		break;
+	}
+
+	/*
+	 * Configure the RX antenna.
+	 */
+	switch ((int)ant->rx) {
+	case 1:
+		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
+		break;
+	case 2:
+		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+		break;
+	case 3:
+		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
+		break;
+	}
+
+	rt2800_bbp_write(rt2x00dev, 3, r3);
+	rt2800_bbp_write(rt2x00dev, 1, r1);
+}
+EXPORT_SYMBOL_GPL(rt2800_config_ant);
+
+static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
+				   struct rt2x00lib_conf *libconf)
+{
+	u16 eeprom;
+	short lna_gain;
+
+	if (libconf->rf.channel <= 14) {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
+	} else if (libconf->rf.channel <= 64) {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+	} else if (libconf->rf.channel <= 128) {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
+	} else {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
+	}
+
+	rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
+				       struct ieee80211_conf *conf,
+				       struct rf_channel *rf,
+				       struct channel_info *info)
+{
+	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+	if (rt2x00dev->default_ant.tx == 1)
+		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
+
+	if (rt2x00dev->default_ant.rx == 1) {
+		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
+		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+	} else if (rt2x00dev->default_ant.rx == 2)
+		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+
+	if (rf->channel > 14) {
+		/*
+		 * When TX power is below 0, we should increase it by 7 to
+		 * make it a positive value (Minumum value is -7).
+		 * However this means that values between 0 and 7 have
+		 * double meaning, and we should set a 7DBm boost flag.
+		 */
+		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
+				   (info->tx_power1 >= 0));
+
+		if (info->tx_power1 < 0)
+			info->tx_power1 += 7;
+
+		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
+				   TXPOWER_A_TO_DEV(info->tx_power1));
+
+		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
+				   (info->tx_power2 >= 0));
+
+		if (info->tx_power2 < 0)
+			info->tx_power2 += 7;
+
+		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
+				   TXPOWER_A_TO_DEV(info->tx_power2));
+	} else {
+		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
+				   TXPOWER_G_TO_DEV(info->tx_power1));
+		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
+				   TXPOWER_G_TO_DEV(info->tx_power2));
+	}
+
+	rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
+
+	rt2800_rf_write(rt2x00dev, 1, rf->rf1);
+	rt2800_rf_write(rt2x00dev, 2, rf->rf2);
+	rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt2800_rf_write(rt2x00dev, 4, rf->rf4);
+
+	udelay(200);
+
+	rt2800_rf_write(rt2x00dev, 1, rf->rf1);
+	rt2800_rf_write(rt2x00dev, 2, rf->rf2);
+	rt2800_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+	rt2800_rf_write(rt2x00dev, 4, rf->rf4);
+
+	udelay(200);
+
+	rt2800_rf_write(rt2x00dev, 1, rf->rf1);
+	rt2800_rf_write(rt2x00dev, 2, rf->rf2);
+	rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt2800_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
+				       struct ieee80211_conf *conf,
+				       struct rf_channel *rf,
+				       struct channel_info *info)
+{
+	u8 rfcsr;
+
+	rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
+	rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+			  TXPOWER_G_TO_DEV(info->tx_power1));
+	rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+	rt2800_rfcsr_write(rt2x00dev, 24,
+			      rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+	rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+}
+
+static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+				  struct ieee80211_conf *conf,
+				  struct rf_channel *rf,
+				  struct channel_info *info)
+{
+	u32 reg;
+	unsigned int tx_pin;
+	u8 bbp;
+
+	if ((rt2x00_rt(&rt2x00dev->chip, RT3070) ||
+	     rt2x00_rt(&rt2x00dev->chip, RT3090)) &&
+	    (rt2x00_rf(&rt2x00dev->chip, RF2020) ||
+	     rt2x00_rf(&rt2x00dev->chip, RF3020) ||
+	     rt2x00_rf(&rt2x00dev->chip, RF3021) ||
+	     rt2x00_rf(&rt2x00dev->chip, RF3022)))
+		rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
+	else
+		rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info);
+
+	/*
+	 * Change BBP settings
+	 */
+	rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+	rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+	rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+	rt2800_bbp_write(rt2x00dev, 86, 0);
+
+	if (rf->channel <= 14) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+			rt2800_bbp_write(rt2x00dev, 82, 0x62);
+			rt2800_bbp_write(rt2x00dev, 75, 0x46);
+		} else {
+			rt2800_bbp_write(rt2x00dev, 82, 0x84);
+			rt2800_bbp_write(rt2x00dev, 75, 0x50);
+		}
+	} else {
+		rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+
+		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+			rt2800_bbp_write(rt2x00dev, 75, 0x46);
+		else
+			rt2800_bbp_write(rt2x00dev, 75, 0x50);
+	}
+
+	rt2800_register_read(rt2x00dev, TX_BAND_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
+	rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
+	rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
+	rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
+
+	tx_pin = 0;
+
+	/* Turn on unused PA or LNA when not using 1T or 1R */
+	if (rt2x00dev->default_ant.tx != 1) {
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+	}
+
+	/* Turn on unused PA or LNA when not using 1T or 1R */
+	if (rt2x00dev->default_ant.rx != 1) {
+		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);
+	}
+
+	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);
+	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);
+
+	rt2800_bbp_read(rt2x00dev, 4, &bbp);
+	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+	rt2800_bbp_write(rt2x00dev, 4, bbp);
+
+	rt2800_bbp_read(rt2x00dev, 3, &bbp);
+	rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
+	rt2800_bbp_write(rt2x00dev, 3, bbp);
+
+	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+		if (conf_is_ht40(conf)) {
+			rt2800_bbp_write(rt2x00dev, 69, 0x1a);
+			rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+			rt2800_bbp_write(rt2x00dev, 73, 0x16);
+		} else {
+			rt2800_bbp_write(rt2x00dev, 69, 0x16);
+			rt2800_bbp_write(rt2x00dev, 70, 0x08);
+			rt2800_bbp_write(rt2x00dev, 73, 0x11);
+		}
+	}
+
+	msleep(1);
+}
+
+static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
+				  const int txpower)
+{
+	u32 reg;
+	u32 value = TXPOWER_G_TO_DEV(txpower);
+	u8 r1;
+
+	rt2800_bbp_read(rt2x00dev, 1, &r1);
+	rt2x00_set_field8(&reg, BBP1_TX_POWER, 0);
+	rt2800_bbp_write(rt2x00dev, 1, r1);
+
+	rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value);
+	rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
+
+	rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, &reg);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value);
+	rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
+
+	rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, &reg);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value);
+	rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
+
+	rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, &reg);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value);
+	rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
+
+	rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, &reg);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value);
+	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value);
+	rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
+}
+
+static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+				      struct rt2x00lib_conf *libconf)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT,
+			   libconf->conf->short_frame_max_tx_count);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
+			   libconf->conf->long_frame_max_tx_count);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
+	rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
+	rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
+}
+
+static void rt2800_config_ps(struct rt2x00_dev *rt2x00dev,
+			     struct rt2x00lib_conf *libconf)
+{
+	enum dev_state state =
+	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
+		STATE_SLEEP : STATE_AWAKE;
+	u32 reg;
+
+	if (state == STATE_SLEEP) {
+		rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
+
+		rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
+				   libconf->conf->listen_interval - 1);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
+		rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+
+		rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+	} else {
+		rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+
+		rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
+		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
+		rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+	}
+}
+
+void rt2800_config(struct rt2x00_dev *rt2x00dev,
+		   struct rt2x00lib_conf *libconf,
+		   const unsigned int flags)
+{
+	/* Always recalculate LNA gain before changing configuration */
+	rt2800_config_lna_gain(rt2x00dev, libconf);
+
+	if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
+		rt2800_config_channel(rt2x00dev, libconf->conf,
+				      &libconf->rf, &libconf->channel);
+	if (flags & IEEE80211_CONF_CHANGE_POWER)
+		rt2800_config_txpower(rt2x00dev, libconf->conf->power_level);
+	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+		rt2800_config_retry_limit(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt2800_config_ps(rt2x00dev, libconf);
+}
+EXPORT_SYMBOL_GPL(rt2800_config);
+
+/*
+ * Link tuning
+ */
+void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
+{
+	u32 reg;
+
+	/*
+	 * Update FCS error count from register.
+	 */
+	rt2800_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+	qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
+}
+EXPORT_SYMBOL_GPL(rt2800_link_stats);
+
+static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+		if (rt2x00_intf_is_usb(rt2x00dev) &&
+		    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
+			return 0x1c + (2 * rt2x00dev->lna_gain);
+		else
+			return 0x2e + rt2x00dev->lna_gain;
+	}
+
+	if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+		return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
+	else
+		return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
+}
+
+static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
+				  struct link_qual *qual, u8 vgc_level)
+{
+	if (qual->vgc_level != vgc_level) {
+		rt2800_bbp_write(rt2x00dev, 66, vgc_level);
+		qual->vgc_level = vgc_level;
+		qual->vgc_level_reg = vgc_level;
+	}
+}
+
+void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
+{
+	rt2800_set_vgc(rt2x00dev, qual, rt2800_get_default_vgc(rt2x00dev));
+}
+EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
+
+void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
+		       const u32 count)
+{
+	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
+		return;
+
+	/*
+	 * When RSSI is better then -80 increase VGC level with 0x10
+	 */
+	rt2800_set_vgc(rt2x00dev, qual,
+		       rt2800_get_default_vgc(rt2x00dev) +
+		       ((qual->rssi > -80) * 0x10));
+}
+EXPORT_SYMBOL_GPL(rt2800_link_tuner);
+
+/*
+ * Initialization functions.
+ */
+int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	unsigned int i;
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		/*
+		 * Wait until BBP and RF are ready.
+		 */
+		for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+			rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+			if (reg && reg != ~0)
+				break;
+			msleep(1);
+		}
+
+		if (i == REGISTER_BUSY_COUNT) {
+			ERROR(rt2x00dev, "Unstable hardware.\n");
+			return -EBUSY;
+		}
+
+		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+		rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
+				      reg & ~0x00002000);
+	} else if (rt2x00_intf_is_pci(rt2x00dev))
+		rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE)
+		rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+					    USB_MODE_RESET, REGISTER_TIMEOUT);
+#endif
+	}
+
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
+	rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
+
+	rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
+	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
+
+	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+	if (rt2x00_intf_is_usb(rt2x00dev) &&
+	    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+	} else {
+		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+	}
+
+	rt2800_register_read(rt2x00dev, TX_LINK_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
+	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
+	rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
+	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
+	rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
+	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
+	if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
+	    rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
+		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
+	else
+		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
+	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
+	rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
+
+	rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
+
+	rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
+	rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
+	rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+	rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+	rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+	rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+	rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+	rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+	rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+
+		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
+		rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
+		rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+	}
+
+	rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
+
+	rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
+			   IEEE80211_MAX_RTS_THRESHOLD);
+	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
+	rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+	rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
+	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+	/*
+	 * ASIC will keep garbage value after boot, clear encryption keys.
+	 */
+	for (i = 0; i < 4; i++)
+		rt2800_register_write(rt2x00dev,
+					 SHARED_KEY_MODE_ENTRY(i), 0);
+
+	for (i = 0; i < 256; i++) {
+		u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+		rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
+					      wcid, sizeof(wcid));
+
+		rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
+		rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+	}
+
+	/*
+	 * Clear all beacons
+	 * For the Beacon base registers we only need to clear
+	 * the first byte since that byte contains the VALID and OWNER
+	 * bits which (when set to 0) will invalidate the entire beacon.
+	 */
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
+	rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg);
+		rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
+		rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
+	}
+
+	rt2800_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
+	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
+	rt2800_register_write(rt2x00dev, HT_FBK_CFG0, reg);
+
+	rt2800_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
+	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
+	rt2800_register_write(rt2x00dev, HT_FBK_CFG1, reg);
+
+	rt2800_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 9);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
+	rt2800_register_write(rt2x00dev, LG_FBK_CFG0, reg);
+
+	rt2800_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
+	rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
+
+	/*
+	 * We must clear the error counters.
+	 * These registers are cleared on read,
+	 * so we may pass a useless variable to store the value.
+	 */
+	rt2800_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+	rt2800_register_read(rt2x00dev, RX_STA_CNT1, &reg);
+	rt2800_register_read(rt2x00dev, RX_STA_CNT2, &reg);
+	rt2800_register_read(rt2x00dev, TX_STA_CNT0, &reg);
+	rt2800_register_read(rt2x00dev, TX_STA_CNT1, &reg);
+	rt2800_register_read(rt2x00dev, TX_STA_CNT2, &reg);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_init_registers);
+
+static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u32 reg;
+
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
+		if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
+			return 0;
+
+		udelay(REGISTER_BUSY_DELAY);
+	}
+
+	ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
+	return -EACCES;
+}
+
+static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u8 value;
+
+	/*
+	 * BBP was enabled after firmware was loaded,
+	 * but we need to reactivate it now.
+	 */
+	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	msleep(1);
+
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_bbp_read(rt2x00dev, 0, &value);
+		if ((value != 0xff) && (value != 0x00))
+			return 0;
+		udelay(REGISTER_BUSY_DELAY);
+	}
+
+	ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
+	return -EACCES;
+}
+
+int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u16 eeprom;
+	u8 reg_id;
+	u8 value;
+
+	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);
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+	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, 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);
+
+	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+		rt2800_bbp_write(rt2x00dev, 69, 0x16);
+		rt2800_bbp_write(rt2x00dev, 73, 0x12);
+	}
+
+	if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION)
+		rt2800_bbp_write(rt2x00dev, 84, 0x19);
+
+	if (rt2x00_intf_is_usb(rt2x00dev) &&
+	    rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+		rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+		rt2800_bbp_write(rt2x00dev, 84, 0x99);
+		rt2800_bbp_write(rt2x00dev, 105, 0x05);
+	}
+
+	if (rt2x00_rt(&rt2x00dev->chip, RT3052)) {
+		rt2800_bbp_write(rt2x00dev, 31, 0x08);
+		rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+		rt2800_bbp_write(rt2x00dev, 80, 0x08);
+	}
+
+	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+
+		if (eeprom != 0xffff && eeprom != 0x0000) {
+			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
+			value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
+			rt2800_bbp_write(rt2x00dev, reg_id, value);
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_init_bbp);
+
+static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
+				bool bw40, u8 rfcsr24, u8 filter_target)
+{
+	unsigned int i;
+	u8 bbp;
+	u8 rfcsr;
+	u8 passband;
+	u8 stopband;
+	u8 overtuned = 0;
+
+	rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
+
+	rt2800_bbp_read(rt2x00dev, 4, &bbp);
+	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
+	rt2800_bbp_write(rt2x00dev, 4, bbp);
+
+	rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
+	rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+	/*
+	 * Set power & frequency of passband test tone
+	 */
+	rt2800_bbp_write(rt2x00dev, 24, 0);
+
+	for (i = 0; i < 100; i++) {
+		rt2800_bbp_write(rt2x00dev, 25, 0x90);
+		msleep(1);
+
+		rt2800_bbp_read(rt2x00dev, 55, &passband);
+		if (passband)
+			break;
+	}
+
+	/*
+	 * Set power & frequency of stopband test tone
+	 */
+	rt2800_bbp_write(rt2x00dev, 24, 0x06);
+
+	for (i = 0; i < 100; i++) {
+		rt2800_bbp_write(rt2x00dev, 25, 0x90);
+		msleep(1);
+
+		rt2800_bbp_read(rt2x00dev, 55, &stopband);
+
+		if ((passband - stopband) <= filter_target) {
+			rfcsr24++;
+			overtuned += ((passband - stopband) == filter_target);
+		} else
+			break;
+
+		rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
+	}
+
+	rfcsr24 -= !!overtuned;
+
+	rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
+	return rfcsr24;
+}
+
+int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+{
+	u8 rfcsr;
+	u8 bbp;
+
+	if (rt2x00_intf_is_usb(rt2x00dev) &&
+	    rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+		return 0;
+
+	if (rt2x00_intf_is_pci(rt2x00dev)) {
+		if (!rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+		    !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
+		    !rt2x00_rf(&rt2x00dev->chip, RF3022))
+			return 0;
+	}
+
+	/*
+	 * Init RF calibration.
+	 */
+	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+	msleep(1);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
+		rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
+		rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
+		rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
+		rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
+		rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
+		rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
+		rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
+		rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
+		rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
+		rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
+		rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
+		rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
+		rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
+		rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
+		rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
+		rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+		rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
+		rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
+	} else if (rt2x00_intf_is_pci(rt2x00dev)) {
+		rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
+		rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
+		rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
+		rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
+		rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
+		rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
+		rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
+		rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
+		rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
+		rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
+		rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
+		rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
+		rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
+		rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
+		rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
+		rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
+		rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
+		rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
+		rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
+		rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
+		rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
+		rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
+		rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
+		rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
+		rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
+		rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
+		rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
+		rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
+		rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
+		rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
+	}
+
+	/*
+	 * Set RX Filter calibration for 20MHz and 40MHz
+	 */
+	rt2x00dev->calibration[0] =
+	    rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+	rt2x00dev->calibration[1] =
+	    rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+
+	/*
+	 * Set back to initial state
+	 */
+	rt2800_bbp_write(rt2x00dev, 24, 0);
+
+	rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+	rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+	/*
+	 * set BBP back to BW20
+	 */
+	rt2800_bbp_read(rt2x00dev, 4, &bbp);
+	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+	rt2800_bbp_write(rt2x00dev, 4, bbp);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
+
+int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, EFUSE_CTRL, &reg);
+
+	return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT);
+}
+EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
+
+static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
+{
+	u32 reg;
+
+	mutex_lock(&rt2x00dev->csr_mutex);
+
+	rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, &reg);
+	rt2x00_set_field32(&reg, EFUSE_CTRL_ADDRESS_IN, i);
+	rt2x00_set_field32(&reg, EFUSE_CTRL_MODE, 0);
+	rt2x00_set_field32(&reg, EFUSE_CTRL_KICK, 1);
+	rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg);
+
+	/* Wait until the EEPROM has been loaded */
+	rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, &reg);
+
+	/* Apparently the data is read from end to start */
+	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3,
+					(u32 *)&rt2x00dev->eeprom[i]);
+	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2,
+					(u32 *)&rt2x00dev->eeprom[i + 2]);
+	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1,
+					(u32 *)&rt2x00dev->eeprom[i + 4]);
+	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0,
+					(u32 *)&rt2x00dev->eeprom[i + 6]);
+
+	mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+
+	for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8)
+		rt2800_efuse_read(rt2x00dev, i);
+}
+EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
+
+int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+	u16 word;
+	u8 *mac;
+	u8 default_lna_gain;
+
+	/*
+	 * Start validation of the data that has been read.
+	 */
+	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+	if (!is_valid_ether_addr(mac)) {
+		random_ether_addr(mac);
+		EEPROM(rt2x00dev, "MAC: %pM\n", mac);
+	}
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+	if (word == 0xffff) {
+		rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+		rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
+		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
+	} else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
+		/*
+		 * There is a max of 2 RX streams for RT28x0 series
+		 */
+		if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
+			rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+	}
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+	if (word == 0xffff) {
+		rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+		EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
+	}
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+	if ((word & 0x00ff) == 0x00ff) {
+		rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
+		rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
+				   LED_MODE_TXRX_ACTIVITY);
+		rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+		EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
+	}
+
+	/*
+	 * During the LNA validation we are going to use
+	 * lna0 as correct value. Note that EEPROM_LNA
+	 * is never validated.
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+	default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
+	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+	if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+	    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+				   default_lna_gain);
+	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
+	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+	if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+	    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+		rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+				   default_lna_gain);
+	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
+
+int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	u16 value;
+	u16 eeprom;
+
+	/*
+	 * Read EEPROM word for configuration.
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+	/*
+	 * Identify RF chipset.
+	 */
+	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+	rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+
+	rt2x00_set_chip_rf(rt2x00dev, value, reg);
+
+	if (rt2x00_intf_is_usb(rt2x00dev)) {
+		struct rt2x00_chip *chip = &rt2x00dev->chip;
+
+		/*
+		 * The check for rt2860 is not a typo, some rt2870 hardware
+		 * identifies itself as rt2860 in the CSR register.
+		 */
+		if (rt2x00_check_rev(chip, 0xfff00000, 0x28600000) ||
+		    rt2x00_check_rev(chip, 0xfff00000, 0x28700000) ||
+		    rt2x00_check_rev(chip, 0xfff00000, 0x28800000)) {
+			rt2x00_set_chip_rt(rt2x00dev, RT2870);
+		} else if (rt2x00_check_rev(chip, 0xffff0000, 0x30700000)) {
+			rt2x00_set_chip_rt(rt2x00dev, RT3070);
+		} else {
+			ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+			return -ENODEV;
+		}
+	}
+	rt2x00_print_chip(rt2x00dev);
+
+	if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF2020) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
+	    !rt2x00_rf(&rt2x00dev->chip, RF3022)) {
+		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Identify default antenna configuration.
+	 */
+	rt2x00dev->default_ant.tx =
+	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+	rt2x00dev->default_ant.rx =
+	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+
+	/*
+	 * Read frequency offset and RF programming sequence.
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+
+	/*
+	 * Read external LNA informations.
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+	/*
+	 * Detect if this device has an hardware controlled radio.
+	 */
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+
+	/*
+	 * Store led settings, for correct led behaviour.
+	 */
+#ifdef CONFIG_RT2X00_LIB_LEDS
+	rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg);
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_init_eeprom);
+
+/*
+ * RF value list for rt28x0
+ * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
+ */
+static const struct rf_channel rf_vals[] = {
+	{ 1,  0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
+	{ 2,  0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
+	{ 3,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
+	{ 4,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
+	{ 5,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
+	{ 6,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
+	{ 7,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
+	{ 8,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
+	{ 9,  0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
+	{ 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
+	{ 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
+	{ 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
+	{ 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
+	{ 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
+
+	/* 802.11 UNI / HyperLan 2 */
+	{ 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
+	{ 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
+	{ 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
+	{ 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
+	{ 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
+	{ 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
+	{ 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
+	{ 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
+	{ 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
+	{ 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
+	{ 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
+	{ 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
+
+	/* 802.11 HyperLan 2 */
+	{ 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
+	{ 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
+	{ 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
+	{ 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
+	{ 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
+	{ 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
+	{ 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
+	{ 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
+	{ 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
+	{ 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
+	{ 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
+	{ 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
+	{ 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
+	{ 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
+	{ 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
+	{ 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
+
+	/* 802.11 UNII */
+	{ 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
+	{ 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
+	{ 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
+	{ 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
+	{ 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
+	{ 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
+	{ 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
+	{ 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
+	{ 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
+	{ 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
+	{ 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
+
+	/* 802.11 Japan */
+	{ 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
+	{ 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
+	{ 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
+	{ 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
+	{ 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
+	{ 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
+	{ 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
+};
+
+/*
+ * RF value list for rt3070
+ * Supports: 2.4 GHz
+ */
+static const struct rf_channel rf_vals_302x[] = {
+	{1,  241, 2, 2 },
+	{2,  241, 2, 7 },
+	{3,  242, 2, 2 },
+	{4,  242, 2, 7 },
+	{5,  243, 2, 2 },
+	{6,  243, 2, 7 },
+	{7,  244, 2, 2 },
+	{8,  244, 2, 7 },
+	{9,  245, 2, 2 },
+	{10, 245, 2, 7 },
+	{11, 246, 2, 2 },
+	{12, 246, 2, 7 },
+	{13, 247, 2, 2 },
+	{14, 248, 2, 4 },
+};
+
+int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2x00_chip *chip = &rt2x00dev->chip;
+	struct hw_mode_spec *spec = &rt2x00dev->spec;
+	struct channel_info *info;
+	char *tx_power1;
+	char *tx_power2;
+	unsigned int i;
+	u16 eeprom;
+
+	/*
+	 * Disable powersaving as default on PCI devices.
+	 */
+	if (rt2x00_intf_is_pci(rt2x00dev))
+		rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	/*
+	 * Initialize all hw fields.
+	 */
+	rt2x00dev->hw->flags =
+	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+	    IEEE80211_HW_SIGNAL_DBM |
+	    IEEE80211_HW_SUPPORTS_PS |
+	    IEEE80211_HW_PS_NULLFUNC_STACK;
+
+	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
+	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
+				rt2x00_eeprom_addr(rt2x00dev,
+						   EEPROM_MAC_ADDR_0));
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+	/*
+	 * Initialize hw_mode information.
+	 */
+	spec->supported_bands = SUPPORT_BAND_2GHZ;
+	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
+	if (rt2x00_rf(chip, RF2820) ||
+	    rt2x00_rf(chip, RF2720) ||
+	    (rt2x00_intf_is_pci(rt2x00dev) && rt2x00_rf(chip, RF3052))) {
+		spec->num_channels = 14;
+		spec->channels = rf_vals;
+	} else if (rt2x00_rf(chip, RF2850) || rt2x00_rf(chip, RF2750)) {
+		spec->supported_bands |= SUPPORT_BAND_5GHZ;
+		spec->num_channels = ARRAY_SIZE(rf_vals);
+		spec->channels = rf_vals;
+	} else if (rt2x00_rf(chip, RF3020) ||
+		   rt2x00_rf(chip, RF2020) ||
+		   rt2x00_rf(chip, RF3021) ||
+		   rt2x00_rf(chip, RF3022)) {
+		spec->num_channels = ARRAY_SIZE(rf_vals_302x);
+		spec->channels = rf_vals_302x;
+	}
+
+	/*
+	 * Initialize HT information.
+	 */
+	if (!rt2x00_rf(chip, RF2020))
+		spec->ht.ht_supported = true;
+	else
+		spec->ht.ht_supported = false;
+
+	spec->ht.cap =
+	    IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+	    IEEE80211_HT_CAP_GRN_FLD |
+	    IEEE80211_HT_CAP_SGI_20 |
+	    IEEE80211_HT_CAP_SGI_40 |
+	    IEEE80211_HT_CAP_TX_STBC |
+	    IEEE80211_HT_CAP_RX_STBC;
+	spec->ht.ampdu_factor = 3;
+	spec->ht.ampdu_density = 4;
+	spec->ht.mcs.tx_params =
+	    IEEE80211_HT_MCS_TX_DEFINED |
+	    IEEE80211_HT_MCS_TX_RX_DIFF |
+	    ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+		IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+
+	switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+	case 3:
+		spec->ht.mcs.rx_mask[2] = 0xff;
+	case 2:
+		spec->ht.mcs.rx_mask[1] = 0xff;
+	case 1:
+		spec->ht.mcs.rx_mask[0] = 0xff;
+		spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
+		break;
+	}
+
+	/*
+	 * Create channel information array
+	 */
+	info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	spec->channels_info = info;
+
+	tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+	tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+
+	for (i = 0; i < 14; i++) {
+		info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
+		info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+	}
+
+	if (spec->num_channels > 14) {
+		tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+		tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+
+		for (i = 14; i < spec->num_channels; i++) {
+			info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
+			info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode);
+
+/*
+ * IEEE80211 stack callback functions.
+ */
+static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
+				u32 *iv32, u16 *iv16)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct mac_iveiv_entry iveiv_entry;
+	u32 offset;
+
+	offset = MAC_IVEIV_ENTRY(hw_key_idx);
+	rt2800_register_multiread(rt2x00dev, offset,
+				      &iveiv_entry, sizeof(iveiv_entry));
+
+	memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16));
+	memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32));
+}
+
+static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	u32 reg;
+	bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
+
+	rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
+	rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+	rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
+	rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+	return 0;
+}
+
+static int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+			  const struct ieee80211_tx_queue_params *params)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct data_queue *queue;
+	struct rt2x00_field32 field;
+	int retval;
+	u32 reg;
+	u32 offset;
+
+	/*
+	 * First pass the configuration through rt2x00lib, that will
+	 * update the queue settings and validate the input. After that
+	 * we are free to update the registers based on the value
+	 * in the queue parameter.
+	 */
+	retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+	if (retval)
+		return retval;
+
+	/*
+	 * We only need to perform additional register initialization
+	 * for WMM queues/
+	 */
+	if (queue_idx >= 4)
+		return 0;
+
+	queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+	/* Update WMM TXOP register */
+	offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
+	field.bit_offset = (queue_idx & 1) * 16;
+	field.bit_mask = 0xffff << field.bit_offset;
+
+	rt2800_register_read(rt2x00dev, offset, &reg);
+	rt2x00_set_field32(&reg, field, queue->txop);
+	rt2800_register_write(rt2x00dev, offset, reg);
+
+	/* Update WMM registers */
+	field.bit_offset = queue_idx * 4;
+	field.bit_mask = 0xf << field.bit_offset;
+
+	rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
+	rt2x00_set_field32(&reg, field, queue->aifs);
+	rt2800_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
+	rt2x00_set_field32(&reg, field, queue->cw_min);
+	rt2800_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
+	rt2x00_set_field32(&reg, field, queue->cw_max);
+	rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
+
+	/* Update EDCA registers */
+	offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
+
+	rt2800_register_read(rt2x00dev, offset, &reg);
+	rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
+	rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
+	rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
+	rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
+	rt2800_register_write(rt2x00dev, offset, reg);
+
+	return 0;
+}
+
+static u64 rt2800_get_tsf(struct ieee80211_hw *hw)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	u64 tsf;
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
+	tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
+	rt2800_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
+	tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
+
+	return tsf;
+}
+
+const struct ieee80211_ops rt2800_mac80211_ops = {
+	.tx			= rt2x00mac_tx,
+	.start			= rt2x00mac_start,
+	.stop			= rt2x00mac_stop,
+	.add_interface		= rt2x00mac_add_interface,
+	.remove_interface	= rt2x00mac_remove_interface,
+	.config			= rt2x00mac_config,
+	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
+	.set_key		= rt2x00mac_set_key,
+	.get_stats		= rt2x00mac_get_stats,
+	.get_tkip_seq		= rt2800_get_tkip_seq,
+	.set_rts_threshold	= rt2800_set_rts_threshold,
+	.bss_info_changed	= rt2x00mac_bss_info_changed,
+	.conf_tx		= rt2800_conf_tx,
+	.get_tx_stats		= rt2x00mac_get_tx_stats,
+	.get_tsf		= rt2800_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
+};
+EXPORT_SYMBOL_GPL(rt2800_mac80211_ops);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800lib.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,151 @@
+/*
+	Copyright (C) 2009 Bartlomiej Zolnierkiewicz
+
+	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 RT2800LIB_H
+#define RT2800LIB_H
+
+struct rt2800_ops {
+	void (*register_read)(struct rt2x00_dev *rt2x00dev,
+			      const unsigned int offset, u32 *value);
+	void (*register_read_lock)(struct rt2x00_dev *rt2x00dev,
+				   const unsigned int offset, u32 *value);
+	void (*register_write)(struct rt2x00_dev *rt2x00dev,
+			       const unsigned int offset, u32 value);
+	void (*register_write_lock)(struct rt2x00_dev *rt2x00dev,
+				    const unsigned int offset, u32 value);
+
+	void (*register_multiread)(struct rt2x00_dev *rt2x00dev,
+				   const unsigned int offset,
+				   void *value, const u32 length);
+	void (*register_multiwrite)(struct rt2x00_dev *rt2x00dev,
+				    const unsigned int offset,
+				    const void *value, const u32 length);
+
+	int (*regbusy_read)(struct rt2x00_dev *rt2x00dev,
+			    const unsigned int offset,
+			    const struct rt2x00_field32 field, u32 *reg);
+};
+
+static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
+					const unsigned int offset,
+					u32 *value)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_read(rt2x00dev, offset, value);
+}
+
+static inline void rt2800_register_read_lock(struct rt2x00_dev *rt2x00dev,
+					     const unsigned int offset,
+					     u32 *value)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_read_lock(rt2x00dev, offset, value);
+}
+
+static inline void rt2800_register_write(struct rt2x00_dev *rt2x00dev,
+					 const unsigned int offset,
+					 u32 value)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_write(rt2x00dev, offset, value);
+}
+
+static inline void rt2800_register_write_lock(struct rt2x00_dev *rt2x00dev,
+					      const unsigned int offset,
+					      u32 value)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_write_lock(rt2x00dev, offset, value);
+}
+
+static inline void rt2800_register_multiread(struct rt2x00_dev *rt2x00dev,
+					     const unsigned int offset,
+					     void *value, const u32 length)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_multiread(rt2x00dev, offset, value, length);
+}
+
+static inline void rt2800_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+					      const unsigned int offset,
+					      const void *value,
+					      const u32 length)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	rt2800ops->register_multiwrite(rt2x00dev, offset, value, length);
+}
+
+static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev,
+				      const unsigned int offset,
+				      const struct rt2x00_field32 field,
+				      u32 *reg)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
+}
+
+void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
+			const u8 command, const u8 token,
+			const u8 arg0, const u8 arg1);
+
+extern const struct rt2x00debug rt2800_rt2x00debug;
+
+int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
+void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
+		     struct rt2x00_led *led, enum led_type type);
+int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
+			     struct rt2x00lib_crypto *crypto,
+			     struct ieee80211_key_conf *key);
+int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
+			       struct rt2x00lib_crypto *crypto,
+			       struct ieee80211_key_conf *key);
+void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
+			  const unsigned int filter_flags);
+void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
+			struct rt2x00intf_conf *conf, const unsigned int flags);
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp);
+void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant);
+void rt2800_config(struct rt2x00_dev *rt2x00dev,
+		   struct rt2x00lib_conf *libconf,
+		   const unsigned int flags);
+void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
+void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
+void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
+		       const u32 count);
+
+int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
+int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
+int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
+
+int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
+void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
+int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev);
+int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev);
+int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev);
+
+extern const struct ieee80211_ops rt2800_mac80211_ops;
+
+#endif /* RT2800LIB_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.c	2013-05-03 12:11:15.000000000 -0400
@@ -0,0 +1,1322 @@
+/*
+	Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
+	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
+	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>
+	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>
+	<http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2800pci
+	Abstract: rt2800pci device specific routines.
+	Supported chipsets: RT2800E & RT2800ED.
+ */
+
+#include <linux/crc-ccitt.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/eeprom_93cx6.h>
+
+#include "rt2x00.h"
+#include "rt2x00pci.h"
+#include "rt2x00soc.h"
+#include "rt2800lib.h"
+#include "rt2800.h"
+#include "rt2800pci.h"
+
+#ifdef CONFIG_RT2800PCI_PCI_MODULE
+#define CONFIG_RT2800PCI_PCI
+#endif
+
+#ifdef CONFIG_RT2800PCI_WISOC_MODULE
+#define CONFIG_RT2800PCI_WISOC
+#endif
+
+/*
+ * Allow hardware encryption to be disabled.
+ */
+static int modparam_nohwcrypt = 1;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
+{
+	unsigned int i;
+	u32 reg;
+
+	for (i = 0; i < 200; i++) {
+		rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+
+		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
+		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
+		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD2) == token) ||
+		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD3) == token))
+			break;
+
+		udelay(REGISTER_BUSY_DELAY);
+	}
+
+	if (i == 200)
+		ERROR(rt2x00dev, "MCU request failed, no response from hardware\n");
+
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+}
+
+#ifdef CONFIG_RT2800PCI_WISOC
+static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+{
+	u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
+
+	memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+}
+#else
+static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+{
+}
+#endif /* CONFIG_RT2800PCI_WISOC */
+
+#ifdef CONFIG_RT2800PCI_PCI
+static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
+{
+	struct rt2x00_dev *rt2x00dev = eeprom->data;
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+
+	eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN);
+	eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT);
+	eeprom->reg_data_clock =
+	    !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK);
+	eeprom->reg_chip_select =
+	    !!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT);
+}
+
+static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
+{
+	struct rt2x00_dev *rt2x00dev = eeprom->data;
+	u32 reg = 0;
+
+	rt2x00_set_field32(&reg, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in);
+	rt2x00_set_field32(&reg, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out);
+	rt2x00_set_field32(&reg, E2PROM_CSR_DATA_CLOCK,
+			   !!eeprom->reg_data_clock);
+	rt2x00_set_field32(&reg, E2PROM_CSR_CHIP_SELECT,
+			   !!eeprom->reg_chip_select);
+
+	rt2800_register_write(rt2x00dev, E2PROM_CSR, reg);
+}
+
+static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
+{
+	struct eeprom_93cx6 eeprom;
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+
+	eeprom.data = rt2x00dev;
+	eeprom.register_read = rt2800pci_eepromregister_read;
+	eeprom.register_write = rt2800pci_eepromregister_write;
+	eeprom.width = !rt2x00_get_field32(reg, E2PROM_CSR_TYPE) ?
+	    PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
+	eeprom.reg_data_in = 0;
+	eeprom.reg_data_out = 0;
+	eeprom.reg_data_clock = 0;
+	eeprom.reg_chip_select = 0;
+
+	eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
+			       EEPROM_SIZE / sizeof(u16));
+}
+
+static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
+{
+	return rt2800_efuse_detect(rt2x00dev);
+}
+
+static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_read_eeprom_efuse(rt2x00dev);
+}
+#else
+static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
+{
+}
+
+static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
+{
+	return 0;
+}
+
+static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
+{
+}
+#endif /* CONFIG_RT2800PCI_PCI */
+
+/*
+ * Firmware functions
+ */
+static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+	return FIRMWARE_RT2860;
+}
+
+static int rt2800pci_check_firmware(struct rt2x00_dev *rt2x00dev,
+				    const u8 *data, const size_t len)
+{
+	u16 fw_crc;
+	u16 crc;
+
+	/*
+	 * Only support 8kb firmware files.
+	 */
+	if (len != 8192)
+		return FW_BAD_LENGTH;
+
+	/*
+	 * The last 2 bytes in the firmware array are the crc checksum itself,
+	 * this means that we should never pass those 2 bytes to the crc
+	 * algorithm.
+	 */
+	fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+	/*
+	 * Use the crc ccitt algorithm.
+	 * This will return the same value as the legacy driver which
+	 * used bit ordering reversion on the both the firmware bytes
+	 * before input input as well as on the final output.
+	 * Obviously using crc ccitt directly is much more efficient.
+	 */
+	crc = crc_ccitt(~0, data, len - 2);
+
+	/*
+	 * There is a small difference between the crc-itu-t + bitrev and
+	 * the crc-ccitt crc calculation. In the latter method the 2 bytes
+	 * will be swapped, use swab16 to convert the crc to the correct
+	 * value.
+	 */
+	crc = swab16(crc);
+
+	return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
+}
+
+static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev,
+				   const u8 *data, const size_t len)
+{
+	unsigned int i;
+	u32 reg;
+
+	/*
+	 * Wait for stable hardware.
+	 */
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+		if (reg && reg != ~0)
+			break;
+		msleep(1);
+	}
+
+	if (i == REGISTER_BUSY_COUNT) {
+		ERROR(rt2x00dev, "Unstable hardware.\n");
+		return -EBUSY;
+	}
+
+	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
+	rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);
+
+	/*
+	 * Disable DMA, will be reenabled later when enabling
+	 * the radio.
+	 */
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+	/*
+	 * enable Host program ram write selection
+	 */
+	reg = 0;
+	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+
+	/*
+	 * Write firmware to device.
+	 */
+	rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+				      data, len);
+
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
+
+	/*
+	 * Wait for device to stabilize.
+	 */
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
+			break;
+		msleep(1);
+	}
+
+	if (i == REGISTER_BUSY_COUNT) {
+		ERROR(rt2x00dev, "PBF system register not ready.\n");
+		return -EBUSY;
+	}
+
+	/*
+	 * Disable interrupts
+	 */
+	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF);
+
+	/*
+	 * Initialize BBP R/W access agent
+	 */
+	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+
+	return 0;
+}
+
+/*
+ * Initialization functions.
+ */
+static bool rt2800pci_get_entry_state(struct queue_entry *entry)
+{
+	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+	u32 word;
+
+	if (entry->queue->qid == QID_RX) {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+
+		return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE));
+	} else {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+
+		return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE));
+	}
+}
+
+static void rt2800pci_clear_entry(struct queue_entry *entry)
+{
+	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+	u32 word;
+
+	if (entry->queue->qid == QID_RX) {
+		rt2x00_desc_read(entry_priv->desc, 0, &word);
+		rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma);
+		rt2x00_desc_write(entry_priv->desc, 0, word);
+
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+		rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
+		rt2x00_desc_write(entry_priv->desc, 1, word);
+	} else {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+		rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
+		rt2x00_desc_write(entry_priv->desc, 1, word);
+	}
+}
+
+static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
+{
+	struct queue_entry_priv_pci *entry_priv;
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+
+	/*
+	 * Initialize registers.
+	 */
+	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
+	rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
+	rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit);
+	rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0);
+	rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0);
+
+	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
+	rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
+	rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit);
+	rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0);
+	rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0);
+
+	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
+	rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
+	rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit);
+	rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0);
+	rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0);
+
+	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
+	rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
+	rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit);
+	rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0);
+	rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0);
+
+	entry_priv = rt2x00dev->rx->entries[0].priv_data;
+	rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
+	rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit);
+	rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1);
+	rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0);
+
+	/*
+	 * Enable global DMA configuration
+	 */
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+	rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0);
+
+	return 0;
+}
+
+/*
+ * Device state switch handlers.
+ */
+static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
+				enum dev_state state)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
+			   (state == STATE_RADIO_RX_ON) ||
+			   (state == STATE_RADIO_RX_ON_LINK));
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+}
+
+static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
+				 enum dev_state state)
+{
+	int mask = (state == STATE_RADIO_IRQ_ON);
+	u32 reg;
+
+	/*
+	 * When interrupts are being enabled, the interrupt registers
+	 * should clear the register to assure a clean state.
+	 */
+	if (state == STATE_RADIO_IRQ_ON) {
+		rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+		rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+	}
+
+	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, mask);
+	rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, mask);
+	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+}
+
+static int rt2800pci_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u32 reg;
+
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
+		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
+			return 0;
+
+		msleep(1);
+	}
+
+	ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
+	return -EACCES;
+}
+
+static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	u16 word;
+
+	/*
+	 * Initialize all registers.
+	 */
+	if (unlikely(rt2800pci_wait_wpdma_ready(rt2x00dev) ||
+		     rt2800pci_init_queues(rt2x00dev) ||
+		     rt2800_init_registers(rt2x00dev) ||
+		     rt2800pci_wait_wpdma_ready(rt2x00dev) ||
+		     rt2800_init_bbp(rt2x00dev) ||
+		     rt2800_init_rfcsr(rt2x00dev)))
+		return -EIO;
+
+	/*
+	 * Send signal to firmware during boot time.
+	 */
+	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+
+	/*
+	 * Enable RX.
+	 */
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	/*
+	 * Initialize LED control
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+	rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+			      word & 0xff, (word >> 8) & 0xff);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+	rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+			      word & 0xff, (word >> 8) & 0xff);
+
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+	rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+			      word & 0xff, (word >> 8) & 0xff);
+
+	return 0;
+}
+
+static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+	rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280);
+
+	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+
+	/* Wait for DMA, ignore error */
+	rt2800pci_wait_wpdma_ready(rt2x00dev);
+}
+
+static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
+			       enum dev_state state)
+{
+	/*
+	 * Always put the device to sleep (even when we intend to wakeup!)
+	 * if the device is booting and wasn't asleep it will return
+	 * failure when attempting to wakeup.
+	 */
+	rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+
+	if (state == STATE_AWAKE) {
+		rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0);
+		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
+	}
+
+	return 0;
+}
+
+static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
+				      enum dev_state state)
+{
+	int retval = 0;
+
+	switch (state) {
+	case STATE_RADIO_ON:
+		/*
+		 * Before the radio can be enabled, the device first has
+		 * to be woken up. After that it needs a bit of time
+		 * to be fully awake and then the radio can be enabled.
+		 */
+		rt2800pci_set_state(rt2x00dev, STATE_AWAKE);
+		msleep(1);
+		retval = rt2800pci_enable_radio(rt2x00dev);
+		break;
+	case STATE_RADIO_OFF:
+		/*
+		 * After the radio has been disabled, the device should
+		 * be put to sleep for powersaving.
+		 */
+		rt2800pci_disable_radio(rt2x00dev);
+		rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
+		break;
+	case STATE_RADIO_RX_ON:
+	case STATE_RADIO_RX_ON_LINK:
+	case STATE_RADIO_RX_OFF:
+	case STATE_RADIO_RX_OFF_LINK:
+		rt2800pci_toggle_rx(rt2x00dev, state);
+		break;
+	case STATE_RADIO_IRQ_ON:
+	case STATE_RADIO_IRQ_OFF:
+		rt2800pci_toggle_irq(rt2x00dev, state);
+		break;
+	case STATE_DEEP_SLEEP:
+	case STATE_SLEEP:
+	case STATE_STANDBY:
+	case STATE_AWAKE:
+		retval = rt2800pci_set_state(rt2x00dev, state);
+		break;
+	default:
+		retval = -ENOTSUPP;
+		break;
+	}
+
+	if (unlikely(retval))
+		ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+		      state, retval);
+
+	return retval;
+}
+
+/*
+ * TX descriptor initialization
+ */
+static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
+				    struct sk_buff *skb,
+				    struct txentry_desc *txdesc)
+{
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+	__le32 *txd = skbdesc->desc;
+	__le32 *txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom);
+	u32 word;
+
+	/*
+	 * Initialize TX Info descriptor
+	 */
+	rt2x00_desc_read(txwi, 0, &word);
+	rt2x00_set_field32(&word, TXWI_W0_FRAG,
+			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+	rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
+	rt2x00_set_field32(&word, TXWI_W0_TS,
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_AMPDU,
+			   test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
+	rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
+	rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
+	rt2x00_set_field32(&word, TXWI_W0_BW,
+			   test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
+			   test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
+	rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
+	rt2x00_desc_write(txwi, 0, word);
+
+	rt2x00_desc_read(txwi, 1, &word);
+	rt2x00_set_field32(&word, TXWI_W1_ACK,
+			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W1_NSEQ,
+			   test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+	rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
+	rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
+			   test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
+			   txdesc->key_idx : 0xff);
+	rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
+			   skb->len - txdesc->l2pad);
+	rt2x00_set_field32(&word, TXWI_W1_PACKETID,
+			   skbdesc->entry->queue->qid + 1);
+	rt2x00_desc_write(txwi, 1, word);
+
+	/*
+	 * Always write 0 to IV/EIV fields, hardware will insert the IV
+	 * from the IVEIV register when TXD_W3_WIV is set to 0.
+	 * When TXD_W3_WIV is set to 1 it will use the IV data
+	 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
+	 * crypto entry in the registers should be used to encrypt the frame.
+	 */
+	_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
+	_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+
+	/*
+	 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
+	 * must contains a TXWI structure + 802.11 header + padding + 802.11
+	 * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and
+	 * SD_PTR1/SD_LEN1 contains 802.11 header + padding + 802.11
+	 * data. It means that LAST_SEC0 is always 0.
+	 */
+
+	/*
+	 * Initialize TX descriptor
+	 */
+	rt2x00_desc_read(txd, 0, &word);
+	rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma);
+	rt2x00_desc_write(txd, 0, word);
+
+	rt2x00_desc_read(txd, 1, &word);
+	rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len);
+	rt2x00_set_field32(&word, TXD_W1_LAST_SEC1,
+			   !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,
+			   rt2x00dev->ops->extra_tx_headroom);
+	rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
+	rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
+	rt2x00_desc_write(txd, 1, word);
+
+	rt2x00_desc_read(txd, 2, &word);
+	rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
+			   skbdesc->skb_dma + rt2x00dev->ops->extra_tx_headroom);
+	rt2x00_desc_write(txd, 2, word);
+
+	rt2x00_desc_read(txd, 3, &word);
+	rt2x00_set_field32(&word, TXD_W3_WIV,
+			   !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
+	rt2x00_set_field32(&word, TXD_W3_QSEL, 2);
+	rt2x00_desc_write(txd, 3, word);
+}
+
+/*
+ * TX data initialization
+ */
+static void rt2800pci_write_beacon(struct queue_entry *entry)
+{
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+	unsigned int beacon_base;
+	u32 reg;
+
+	/*
+	 * Disable beaconing while we are reloading the beacon data,
+	 * otherwise we might be sending out invalid data.
+	 */
+	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+	/*
+	 * Write entire beacon with descriptor to register.
+	 */
+	beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+	rt2800_register_multiwrite(rt2x00dev,
+				      beacon_base,
+				      skbdesc->desc, skbdesc->desc_len);
+	rt2800_register_multiwrite(rt2x00dev,
+				      beacon_base + skbdesc->desc_len,
+				      entry->skb->data, entry->skb->len);
+
+	/*
+	 * Clean up beacon skb.
+	 */
+	dev_kfree_skb_any(entry->skb);
+	entry->skb = NULL;
+}
+
+static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+				    const enum data_queue_qid queue_idx)
+{
+	struct data_queue *queue;
+	unsigned int idx, qidx = 0;
+	u32 reg;
+
+	if (queue_idx == QID_BEACON) {
+		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
+			rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+			rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+			rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+			rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		}
+		return;
+	}
+
+	if (queue_idx > QID_HCCA && queue_idx != QID_MGMT)
+		return;
+
+	queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+	idx = queue->index[Q_INDEX];
+
+	if (queue_idx == QID_MGMT)
+		qidx = 5;
+	else
+		qidx = queue_idx;
+
+	rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx);
+}
+
+static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+				    const enum data_queue_qid qid)
+{
+	u32 reg;
+
+	if (qid == QID_BEACON) {
+		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
+		return;
+	}
+
+	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK));
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI));
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO));
+	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+}
+
+/*
+ * RX control handlers
+ */
+static void rt2800pci_fill_rxdone(struct queue_entry *entry,
+				  struct rxdone_entry_desc *rxdesc)
+{
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+	__le32 *rxd = entry_priv->desc;
+	__le32 *rxwi = (__le32 *)entry->skb->data;
+	u32 rxd3;
+	u32 rxwi0;
+	u32 rxwi1;
+	u32 rxwi2;
+	u32 rxwi3;
+
+	rt2x00_desc_read(rxd, 3, &rxd3);
+	rt2x00_desc_read(rxwi, 0, &rxwi0);
+	rt2x00_desc_read(rxwi, 1, &rxwi1);
+	rt2x00_desc_read(rxwi, 2, &rxwi2);
+	rt2x00_desc_read(rxwi, 3, &rxwi3);
+
+	if (rt2x00_get_field32(rxd3, RXD_W3_CRC_ERROR))
+		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+
+	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+		/*
+		 * Unfortunately we don't know the cipher type used during
+		 * decryption. This prevents us from correct providing
+		 * correct statistics through debugfs.
+		 */
+		rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+		rxdesc->cipher_status =
+		    rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
+	}
+
+	if (rt2x00_get_field32(rxd3, RXD_W3_DECRYPTED)) {
+		/*
+		 * Hardware has stripped IV/EIV data from 802.11 frame during
+		 * decryption. Unfortunately the descriptor doesn't contain
+		 * any fields with the EIV/IV data either, so they can't
+		 * be restored by rt2x00lib.
+		 */
+		rxdesc->flags |= RX_FLAG_IV_STRIPPED;
+
+		if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
+			rxdesc->flags |= RX_FLAG_DECRYPTED;
+		else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
+			rxdesc->flags |= RX_FLAG_MMIC_ERROR;
+	}
+
+	if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS))
+		rxdesc->dev_flags |= RXDONE_MY_BSS;
+
+	if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) {
+		rxdesc->dev_flags |= RXDONE_L2PAD;
+		skbdesc->flags |= SKBDESC_L2_PADDED;
+	}
+
+	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
+		rxdesc->flags |= RX_FLAG_SHORT_GI;
+
+	if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
+		rxdesc->flags |= RX_FLAG_40MHZ;
+
+	/*
+	 * Detect RX rate, always use MCS as signal type.
+	 */
+	rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
+	rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
+	rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
+
+	/*
+	 * Mask of 0x8 bit to remove the short preamble flag.
+	 */
+	if (rxdesc->rate_mode == RATE_MODE_CCK)
+		rxdesc->signal &= ~0x8;
+
+	rxdesc->rssi =
+	    (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
+	     rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
+
+	rxdesc->noise =
+	    (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
+	     rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
+
+	rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+
+	/*
+	 * Set RX IDX in register to inform hardware that we have handled
+	 * this entry and it is available for reuse again.
+	 */
+	rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
+
+	/*
+	 * Remove TXWI descriptor from start of buffer.
+	 */
+	skb_pull(entry->skb, RXWI_DESC_SIZE);
+	skb_trim(entry->skb, rxdesc->size);
+}
+
+/*
+ * Interrupt functions.
+ */
+static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
+{
+	struct data_queue *queue;
+	struct queue_entry *entry;
+	struct queue_entry *entry_done;
+	struct queue_entry_priv_pci *entry_priv;
+	struct txdone_entry_desc txdesc;
+	u32 word;
+	u32 reg;
+	u32 old_reg;
+	unsigned int type;
+	unsigned int index;
+	u16 mcs, real_mcs;
+
+	/*
+	 * During each loop we will compare the freshly read
+	 * TX_STA_FIFO register value with the value read from
+	 * the previous loop. If the 2 values are equal then
+	 * we should stop processing because the chance it
+	 * quite big that the device has been unplugged and
+	 * we risk going into an endless loop.
+	 */
+	old_reg = 0;
+
+	while (1) {
+		rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
+		if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
+			break;
+
+		if (old_reg == reg)
+			break;
+		old_reg = reg;
+
+		/*
+		 * Skip this entry when it contains an invalid
+		 * queue identication number.
+		 */
+		type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
+		if (type >= QID_RX)
+			continue;
+
+		queue = rt2x00queue_get_queue(rt2x00dev, type);
+		if (unlikely(!queue))
+			continue;
+
+		/*
+		 * Skip this entry when it contains an invalid
+		 * index number.
+		 */
+		index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1;
+		if (unlikely(index >= queue->limit))
+			continue;
+
+		entry = &queue->entries[index];
+		entry_priv = entry->priv_data;
+		rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word);
+
+		entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+		while (entry != entry_done) {
+			/*
+			 * Catch up.
+			 * Just report any entries we missed as failed.
+			 */
+			WARNING(rt2x00dev,
+				"TX status report missed for entry %d\n",
+				entry_done->entry_idx);
+
+			txdesc.flags = 0;
+			__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
+			txdesc.retry = 0;
+
+			rt2x00lib_txdone(entry_done, &txdesc);
+			entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+		}
+
+		/*
+		 * Obtain the status about this packet.
+		 */
+		txdesc.flags = 0;
+		if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS))
+			__set_bit(TXDONE_SUCCESS, &txdesc.flags);
+		else
+			__set_bit(TXDONE_FAILURE, &txdesc.flags);
+
+		/*
+		 * Ralink has a retry mechanism using a global fallback
+		 * table. We setup this fallback table to try immediate
+		 * lower rate for all rates. In the TX_STA_FIFO,
+		 * the MCS field contains the MCS used for the successfull
+		 * transmission. If the first transmission succeed,
+		 * we have mcs == tx_mcs. On the second transmission,
+		 * we have mcs = tx_mcs - 1. So the number of
+		 * retry is (tx_mcs - mcs).
+		 */
+		mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
+		real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
+		__set_bit(TXDONE_FALLBACK, &txdesc.flags);
+		txdesc.retry = mcs - min(mcs, real_mcs);
+
+		rt2x00lib_txdone(entry, &txdesc);
+	}
+}
+
+static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
+{
+	struct rt2x00_dev *rt2x00dev = dev_instance;
+	u32 reg;
+
+	/* Read status and ACK all interrupts */
+	rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+	rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+
+	if (!reg)
+		return IRQ_NONE;
+
+	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+		return IRQ_HANDLED;
+
+	/*
+	 * 1 - Rx ring done interrupt.
+	 */
+	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE))
+		rt2x00pci_rxdone(rt2x00dev);
+
+	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
+		rt2800pci_txdone(rt2x00dev);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Device probe functions.
+ */
+static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+	/*
+	 * Read EEPROM into buffer
+	 */
+	switch (rt2x00dev->chip.rt) {
+	case RT2880:
+	case RT3052:
+		rt2800pci_read_eeprom_soc(rt2x00dev);
+		break;
+	default:
+		if (rt2800pci_efuse_detect(rt2x00dev))
+			rt2800pci_read_eeprom_efuse(rt2x00dev);
+		else
+			rt2800pci_read_eeprom_pci(rt2x00dev);
+		break;
+	}
+
+	return rt2800_validate_eeprom(rt2x00dev);
+}
+
+static const struct rt2800_ops rt2800pci_rt2800_ops = {
+	.register_read		= rt2x00pci_register_read,
+	.register_read_lock	= rt2x00pci_register_read, /* same for PCI */
+	.register_write		= rt2x00pci_register_write,
+	.register_write_lock	= rt2x00pci_register_write, /* same for PCI */
+
+	.register_multiread	= rt2x00pci_register_multiread,
+	.register_multiwrite	= rt2x00pci_register_multiwrite,
+
+	.regbusy_read		= rt2x00pci_regbusy_read,
+};
+
+static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
+{
+	int retval;
+
+	rt2x00dev->priv = (void *)&rt2800pci_rt2800_ops;
+
+	/*
+	 * Allocate eeprom data.
+	 */
+	retval = rt2800pci_validate_eeprom(rt2x00dev);
+	if (retval)
+		return retval;
+
+	retval = rt2800_init_eeprom(rt2x00dev);
+	if (retval)
+		return retval;
+
+	/*
+	 * Initialize hw specifications.
+	 */
+	retval = rt2800_probe_hw_mode(rt2x00dev);
+	if (retval)
+		return retval;
+
+	/*
+	 * This device has multiple filters for control frames
+	 * and has a separate filter for PS Poll frames.
+	 */
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+
+	/*
+	 * This device requires firmware.
+	 */
+	if (!rt2x00_rt(&rt2x00dev->chip, RT2880) &&
+	    !rt2x00_rt(&rt2x00dev->chip, RT3052))
+		__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
+	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+	if (!modparam_nohwcrypt)
+		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
+
+	/*
+	 * Set the rssi offset.
+	 */
+	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+
+	return 0;
+}
+
+static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
+	.irq_handler		= rt2800pci_interrupt,
+	.probe_hw		= rt2800pci_probe_hw,
+	.get_firmware_name	= rt2800pci_get_firmware_name,
+	.check_firmware		= rt2800pci_check_firmware,
+	.load_firmware		= rt2800pci_load_firmware,
+	.initialize		= rt2x00pci_initialize,
+	.uninitialize		= rt2x00pci_uninitialize,
+	.get_entry_state	= rt2800pci_get_entry_state,
+	.clear_entry		= rt2800pci_clear_entry,
+	.set_device_state	= rt2800pci_set_device_state,
+	.rfkill_poll		= rt2800_rfkill_poll,
+	.link_stats		= rt2800_link_stats,
+	.reset_tuner		= rt2800_reset_tuner,
+	.link_tuner		= rt2800_link_tuner,
+	.write_tx_desc		= rt2800pci_write_tx_desc,
+	.write_tx_data		= rt2x00pci_write_tx_data,
+	.write_beacon		= rt2800pci_write_beacon,
+	.kick_tx_queue		= rt2800pci_kick_tx_queue,
+	.kill_tx_queue		= rt2800pci_kill_tx_queue,
+	.fill_rxdone		= rt2800pci_fill_rxdone,
+	.config_shared_key	= rt2800_config_shared_key,
+	.config_pairwise_key	= rt2800_config_pairwise_key,
+	.config_filter		= rt2800_config_filter,
+	.config_intf		= rt2800_config_intf,
+	.config_erp		= rt2800_config_erp,
+	.config_ant		= rt2800_config_ant,
+	.config			= rt2800_config,
+};
+
+static const struct data_queue_desc rt2800pci_queue_rx = {
+	.entry_num		= RX_ENTRIES,
+	.data_size		= AGGREGATION_SIZE,
+	.desc_size		= RXD_DESC_SIZE,
+	.priv_size		= sizeof(struct queue_entry_priv_pci),
+};
+
+static const struct data_queue_desc rt2800pci_queue_tx = {
+	.entry_num		= TX_ENTRIES,
+	.data_size		= AGGREGATION_SIZE,
+	.desc_size		= TXD_DESC_SIZE,
+	.priv_size		= sizeof(struct queue_entry_priv_pci),
+};
+
+static const struct data_queue_desc rt2800pci_queue_bcn = {
+	.entry_num		= 8 * BEACON_ENTRIES,
+	.data_size		= 0, /* No DMA required for beacons */
+	.desc_size		= TXWI_DESC_SIZE,
+	.priv_size		= sizeof(struct queue_entry_priv_pci),
+};
+
+static const struct rt2x00_ops rt2800pci_ops = {
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 8,
+	.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,
+	.lib			= &rt2800pci_rt2x00_ops,
+	.hw			= &rt2800_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+	.debugfs		= &rt2800_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
+/*
+ * RT2800pci module information.
+ */
+static struct pci_device_id rt2800pci_device_table[] = {
+	{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0701), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0781), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3090), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3091), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3092), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ 0, }
+};
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards");
+#ifdef CONFIG_RT2800PCI_PCI
+/*(DEBLOBBED)*/
+MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
+#endif /* CONFIG_RT2800PCI_PCI */
+MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_RT2800PCI_WISOC
+#if defined(CONFIG_RALINK_RT288X)
+__rt2x00soc_probe(RT2880, &rt2800pci_ops);
+#elif defined(CONFIG_RALINK_RT305X)
+__rt2x00soc_probe(RT3052, &rt2800pci_ops);
+#endif
+
+static struct platform_driver rt2800soc_driver = {
+	.driver		= {
+		.name		= "rt2800_wmac",
+		.owner		= THIS_MODULE,
+		.mod_name	= KBUILD_MODNAME,
+	},
+	.probe		= __rt2x00soc_probe,
+	.remove		= __devexit_p(rt2x00soc_remove),
+	.suspend	= rt2x00soc_suspend,
+	.resume		= rt2x00soc_resume,
+};
+#endif /* CONFIG_RT2800PCI_WISOC */
+
+#ifdef CONFIG_RT2800PCI_PCI
+static struct pci_driver rt2800pci_driver = {
+	.name		= KBUILD_MODNAME,
+	.id_table	= rt2800pci_device_table,
+	.probe		= rt2x00pci_probe,
+	.remove		= __devexit_p(rt2x00pci_remove),
+	.suspend	= rt2x00pci_suspend,
+	.resume		= rt2x00pci_resume,
+};
+#endif /* CONFIG_RT2800PCI_PCI */
+
+static int __init rt2800pci_init(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_RT2800PCI_WISOC
+	ret = platform_driver_register(&rt2800soc_driver);
+	if (ret)
+		return ret;
+#endif
+#ifdef CONFIG_RT2800PCI_PCI
+	ret = pci_register_driver(&rt2800pci_driver);
+	if (ret) {
+#ifdef CONFIG_RT2800PCI_WISOC
+		platform_driver_unregister(&rt2800soc_driver);
+#endif
+		return ret;
+	}
+#endif
+
+	return ret;
+}
+
+static void __exit rt2800pci_exit(void)
+{
+#ifdef CONFIG_RT2800PCI_PCI
+	pci_unregister_driver(&rt2800pci_driver);
+#endif
+#ifdef CONFIG_RT2800PCI_WISOC
+	platform_driver_unregister(&rt2800soc_driver);
+#endif
+}
+
+module_init(rt2800pci_init);
+module_exit(rt2800pci_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800pci.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800pci.h	2013-05-03 12:11:12.000000000 -0400
@@ -0,0 +1,159 @@
+/*
+	Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
+	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
+	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>
+	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>
+	<http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2800pci
+	Abstract: Data structures and registers for the rt2800pci module.
+	Supported chipsets: RT2800E & RT2800ED.
+ */
+
+#ifndef RT2800PCI_H
+#define RT2800PCI_H
+
+/*
+ * PCI registers.
+ */
+
+/*
+ * E2PROM_CSR: EEPROM control register.
+ * RELOAD: Write 1 to reload eeprom content.
+ * TYPE: 0: 93c46, 1:93c66.
+ * LOAD_STATUS: 1:loading, 0:done.
+ */
+#define E2PROM_CSR			0x0004
+#define E2PROM_CSR_DATA_CLOCK		FIELD32(0x00000001)
+#define E2PROM_CSR_CHIP_SELECT		FIELD32(0x00000002)
+#define E2PROM_CSR_DATA_IN		FIELD32(0x00000004)
+#define E2PROM_CSR_DATA_OUT		FIELD32(0x00000008)
+#define E2PROM_CSR_TYPE			FIELD32(0x00000030)
+#define E2PROM_CSR_LOAD_STATUS		FIELD32(0x00000040)
+#define E2PROM_CSR_RELOAD		FIELD32(0x00000080)
+
+/*
+ * Queue register offset macros
+ */
+#define TX_QUEUE_REG_OFFSET		0x10
+#define TX_BASE_PTR(__x)		TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)
+#define TX_MAX_CNT(__x)			TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)
+#define TX_CTX_IDX(__x)			TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
+#define TX_DTX_IDX(__x)			TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)
+
+/*
+ * 8051 firmware image.
+ */
+#define FIRMWARE_RT2860			"/*(DEBLOBBED)*/"
+#define FIRMWARE_IMAGE_BASE		0x2000
+
+/*
+ * DMA descriptor defines.
+ */
+#define TXD_DESC_SIZE			( 4 * sizeof(__le32) )
+#define RXD_DESC_SIZE			( 4 * sizeof(__le32) )
+
+/*
+ * TX descriptor format for TX, PRIO and Beacon Ring.
+ */
+
+/*
+ * Word0
+ */
+#define TXD_W0_SD_PTR0			FIELD32(0xffffffff)
+
+/*
+ * Word1
+ */
+#define TXD_W1_SD_LEN1			FIELD32(0x00003fff)
+#define TXD_W1_LAST_SEC1		FIELD32(0x00004000)
+#define TXD_W1_BURST			FIELD32(0x00008000)
+#define TXD_W1_SD_LEN0			FIELD32(0x3fff0000)
+#define TXD_W1_LAST_SEC0		FIELD32(0x40000000)
+#define TXD_W1_DMA_DONE			FIELD32(0x80000000)
+
+/*
+ * Word2
+ */
+#define TXD_W2_SD_PTR1			FIELD32(0xffffffff)
+
+/*
+ * Word3
+ * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ *       0:MGMT, 1:HCCA 2:EDCA
+ */
+#define TXD_W3_WIV			FIELD32(0x01000000)
+#define TXD_W3_QSEL			FIELD32(0x06000000)
+#define TXD_W3_TCO			FIELD32(0x20000000)
+#define TXD_W3_UCO			FIELD32(0x40000000)
+#define TXD_W3_ICO			FIELD32(0x80000000)
+
+/*
+ * RX descriptor format for RX Ring.
+ */
+
+/*
+ * Word0
+ */
+#define RXD_W0_SDP0			FIELD32(0xffffffff)
+
+/*
+ * Word1
+ */
+#define RXD_W1_SDL1			FIELD32(0x00003fff)
+#define RXD_W1_SDL0			FIELD32(0x3fff0000)
+#define RXD_W1_LS0			FIELD32(0x40000000)
+#define RXD_W1_DMA_DONE			FIELD32(0x80000000)
+
+/*
+ * Word2
+ */
+#define RXD_W2_SDP1			FIELD32(0xffffffff)
+
+/*
+ * Word3
+ * AMSDU: RX with 802.3 header, not 802.11 header.
+ * DECRYPTED: This frame is being decrypted.
+ */
+#define RXD_W3_BA			FIELD32(0x00000001)
+#define RXD_W3_DATA			FIELD32(0x00000002)
+#define RXD_W3_NULLDATA			FIELD32(0x00000004)
+#define RXD_W3_FRAG			FIELD32(0x00000008)
+#define RXD_W3_UNICAST_TO_ME		FIELD32(0x00000010)
+#define RXD_W3_MULTICAST		FIELD32(0x00000020)
+#define RXD_W3_BROADCAST		FIELD32(0x00000040)
+#define RXD_W3_MY_BSS			FIELD32(0x00000080)
+#define RXD_W3_CRC_ERROR		FIELD32(0x00000100)
+#define RXD_W3_CIPHER_ERROR		FIELD32(0x00000600)
+#define RXD_W3_AMSDU			FIELD32(0x00000800)
+#define RXD_W3_HTC			FIELD32(0x00001000)
+#define RXD_W3_RSSI			FIELD32(0x00002000)
+#define RXD_W3_L2PAD			FIELD32(0x00004000)
+#define RXD_W3_AMPDU			FIELD32(0x00008000)
+#define RXD_W3_DECRYPTED		FIELD32(0x00010000)
+#define RXD_W3_PLCP_SIGNAL		FIELD32(0x00020000)
+#define RXD_W3_PLCP_RSSI		FIELD32(0x00040000)
+
+#endif /* RT2800PCI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c	2013-05-03 14:03:40.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.c	2013-05-03 12:11:19.000000000 -0400
@@ -1,5 +1,9 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -34,6 +38,8 @@
 
 #include "rt2x00.h"
 #include "rt2x00usb.h"
+#include "rt2800lib.h"
+#include "rt2800.h"
 #include "rt2800usb.h"
 
 /*
@@ -44,1027 +50,6 @@ module_param_named(nohwcrypt, modparam_n
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
 /*
- * Register access.
- * All access to the CSR registers will go through the methods
- * rt2x00usb_register_read and rt2x00usb_register_write.
- * BBP and RF register require indirect register access,
- * and use the CSR registers BBPCSR and RFCSR to achieve this.
- * These indirect registers work with busy bits,
- * and we will try maximal REGISTER_BUSY_COUNT times to access
- * the register while taking a REGISTER_BUSY_DELAY us delay
- * between each attampt. When the busy bit is still set at that time,
- * the access attempt is considered to have failed,
- * and we will print an error.
- * The _lock versions must be used if you already hold the csr_mutex
- */
-#define WAIT_FOR_BBP(__dev, __reg) \
-	rt2x00usb_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
-#define WAIT_FOR_RFCSR(__dev, __reg) \
-	rt2x00usb_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
-#define WAIT_FOR_RF(__dev, __reg) \
-	rt2x00usb_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
-#define WAIT_FOR_MCU(__dev, __reg) \
-	rt2x00usb_regbusy_read((__dev), H2M_MAILBOX_CSR, \
-			       H2M_MAILBOX_CSR_OWNER, (__reg))
-
-static void rt2800usb_bbp_write(struct rt2x00_dev *rt2x00dev,
-				const unsigned int word, const u8 value)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the BBP becomes available, afterwards we
-	 * can safely write the new data into the register.
-	 */
-	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
-		reg = 0;
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_VALUE, value);
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
-
-		rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
-	}
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-static void rt2800usb_bbp_read(struct rt2x00_dev *rt2x00dev,
-			       const unsigned int word, u8 *value)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the BBP becomes available, afterwards we
-	 * can safely write the read request into the register.
-	 * After the data has been written, we wait until hardware
-	 * returns the correct value, if at any time the register
-	 * doesn't become available in time, reg will be 0xffffffff
-	 * which means we return 0xff to the caller.
-	 */
-	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
-		reg = 0;
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
-		rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
-
-		rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
-
-		WAIT_FOR_BBP(rt2x00dev, &reg);
-	}
-
-	*value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-static void rt2800usb_rfcsr_write(struct rt2x00_dev *rt2x00dev,
-				  const unsigned int word, const u8 value)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the RFCSR becomes available, afterwards we
-	 * can safely write the new data into the register.
-	 */
-	if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
-		reg = 0;
-		rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
-		rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
-		rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
-		rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
-
-		rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-	}
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-static void rt2800usb_rfcsr_read(struct rt2x00_dev *rt2x00dev,
-				 const unsigned int word, u8 *value)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the RFCSR becomes available, afterwards we
-	 * can safely write the read request into the register.
-	 * After the data has been written, we wait until hardware
-	 * returns the correct value, if at any time the register
-	 * doesn't become available in time, reg will be 0xffffffff
-	 * which means we return 0xff to the caller.
-	 */
-	if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
-		reg = 0;
-		rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
-		rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
-		rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
-
-		rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
-
-		WAIT_FOR_RFCSR(rt2x00dev, &reg);
-	}
-
-	*value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-static void rt2800usb_rf_write(struct rt2x00_dev *rt2x00dev,
-			       const unsigned int word, const u32 value)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the RF becomes available, afterwards we
-	 * can safely write the new data into the register.
-	 */
-	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
-		reg = 0;
-		rt2x00_set_field32(&reg, RF_CSR_CFG0_REG_VALUE_BW, value);
-		rt2x00_set_field32(&reg, RF_CSR_CFG0_STANDBYMODE, 0);
-		rt2x00_set_field32(&reg, RF_CSR_CFG0_SEL, 0);
-		rt2x00_set_field32(&reg, RF_CSR_CFG0_BUSY, 1);
-
-		rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
-		rt2x00_rf_write(rt2x00dev, word, value);
-	}
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-static void rt2800usb_mcu_request(struct rt2x00_dev *rt2x00dev,
-				  const u8 command, const u8 token,
-				  const u8 arg0, const u8 arg1)
-{
-	u32 reg;
-
-	mutex_lock(&rt2x00dev->csr_mutex);
-
-	/*
-	 * Wait until the MCU becomes available, afterwards we
-	 * can safely write the new data into the register.
-	 */
-	if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
-		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
-		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
-		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
-		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
-		rt2x00usb_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
-
-		reg = 0;
-		rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
-		rt2x00usb_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
-	}
-
-	mutex_unlock(&rt2x00dev->csr_mutex);
-}
-
-#ifdef CONFIG_RT2X00_LIB_DEBUGFS
-static const struct rt2x00debug rt2800usb_rt2x00debug = {
-	.owner	= THIS_MODULE,
-	.csr	= {
-		.read		= rt2x00usb_register_read,
-		.write		= rt2x00usb_register_write,
-		.flags		= RT2X00DEBUGFS_OFFSET,
-		.word_base	= CSR_REG_BASE,
-		.word_size	= sizeof(u32),
-		.word_count	= CSR_REG_SIZE / sizeof(u32),
-	},
-	.eeprom	= {
-		.read		= rt2x00_eeprom_read,
-		.write		= rt2x00_eeprom_write,
-		.word_base	= EEPROM_BASE,
-		.word_size	= sizeof(u16),
-		.word_count	= EEPROM_SIZE / sizeof(u16),
-	},
-	.bbp	= {
-		.read		= rt2800usb_bbp_read,
-		.write		= rt2800usb_bbp_write,
-		.word_base	= BBP_BASE,
-		.word_size	= sizeof(u8),
-		.word_count	= BBP_SIZE / sizeof(u8),
-	},
-	.rf	= {
-		.read		= rt2x00_rf_read,
-		.write		= rt2800usb_rf_write,
-		.word_base	= RF_BASE,
-		.word_size	= sizeof(u32),
-		.word_count	= RF_SIZE / sizeof(u32),
-	},
-};
-#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
-
-static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
-{
-	u32 reg;
-
-	rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
-	return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
-}
-
-#ifdef CONFIG_RT2X00_LIB_LEDS
-static void rt2800usb_brightness_set(struct led_classdev *led_cdev,
-				     enum led_brightness brightness)
-{
-	struct rt2x00_led *led =
-	    container_of(led_cdev, struct rt2x00_led, led_dev);
-	unsigned int enabled = brightness != LED_OFF;
-	unsigned int bg_mode =
-	    (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
-	unsigned int polarity =
-		rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
-				   EEPROM_FREQ_LED_POLARITY);
-	unsigned int ledmode =
-		rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
-				   EEPROM_FREQ_LED_MODE);
-
-	if (led->type == LED_TYPE_RADIO) {
-		rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
-				      enabled ? 0x20 : 0);
-	} else if (led->type == LED_TYPE_ASSOC) {
-		rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
-				      enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
-	} else if (led->type == LED_TYPE_QUALITY) {
-		/*
-		 * The brightness is divided into 6 levels (0 - 5),
-		 * The specs tell us the following levels:
-		 *	0, 1 ,3, 7, 15, 31
-		 * to determine the level in a simple way we can simply
-		 * work with bitshifting:
-		 *	(1 << level) - 1
-		 */
-		rt2800usb_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
-				      (1 << brightness / (LED_FULL / 6)) - 1,
-				      polarity);
-	}
-}
-
-static int rt2800usb_blink_set(struct led_classdev *led_cdev,
-			       unsigned long *delay_on,
-			       unsigned long *delay_off)
-{
-	struct rt2x00_led *led =
-	    container_of(led_cdev, struct rt2x00_led, led_dev);
-	u32 reg;
-
-	rt2x00usb_register_read(led->rt2x00dev, LED_CFG, &reg);
-	rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
-	rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
-	rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
-	rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
-	rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 12);
-	rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
-	rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
-	rt2x00usb_register_write(led->rt2x00dev, LED_CFG, reg);
-
-	return 0;
-}
-
-static void rt2800usb_init_led(struct rt2x00_dev *rt2x00dev,
-			       struct rt2x00_led *led,
-			       enum led_type type)
-{
-	led->rt2x00dev = rt2x00dev;
-	led->type = type;
-	led->led_dev.brightness_set = rt2800usb_brightness_set;
-	led->led_dev.blink_set = rt2800usb_blink_set;
-	led->flags = LED_INITIALIZED;
-}
-#endif /* CONFIG_RT2X00_LIB_LEDS */
-
-/*
- * Configuration handlers.
- */
-static void rt2800usb_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
-				       struct rt2x00lib_crypto *crypto,
-				       struct ieee80211_key_conf *key)
-{
-	struct mac_wcid_entry wcid_entry;
-	struct mac_iveiv_entry iveiv_entry;
-	u32 offset;
-	u32 reg;
-
-	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
-
-	rt2x00usb_register_read(rt2x00dev, offset, &reg);
-	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
-			   !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
-	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
-			   (crypto->cmd == SET_KEY) * crypto->cipher);
-	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
-			   (crypto->cmd == SET_KEY) * crypto->bssidx);
-	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
-	rt2x00usb_register_write(rt2x00dev, offset, reg);
-
-	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
-
-	memset(&iveiv_entry, 0, sizeof(iveiv_entry));
-	if ((crypto->cipher == CIPHER_TKIP) ||
-	    (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
-	    (crypto->cipher == CIPHER_AES))
-		iveiv_entry.iv[3] |= 0x20;
-	iveiv_entry.iv[3] |= key->keyidx << 6;
-	rt2x00usb_register_multiwrite(rt2x00dev, offset,
-				      &iveiv_entry, sizeof(iveiv_entry));
-
-	offset = MAC_WCID_ENTRY(key->hw_key_idx);
-
-	memset(&wcid_entry, 0, sizeof(wcid_entry));
-	if (crypto->cmd == SET_KEY)
-		memcpy(&wcid_entry, crypto->address, ETH_ALEN);
-	rt2x00usb_register_multiwrite(rt2x00dev, offset,
-				      &wcid_entry, sizeof(wcid_entry));
-}
-
-static int rt2800usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
-				       struct rt2x00lib_crypto *crypto,
-				       struct ieee80211_key_conf *key)
-{
-	struct hw_key_entry key_entry;
-	struct rt2x00_field32 field;
-	int timeout;
-	u32 offset;
-	u32 reg;
-
-	if (crypto->cmd == SET_KEY) {
-		key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
-
-		memcpy(key_entry.key, crypto->key,
-		       sizeof(key_entry.key));
-		memcpy(key_entry.tx_mic, crypto->tx_mic,
-		       sizeof(key_entry.tx_mic));
-		memcpy(key_entry.rx_mic, crypto->rx_mic,
-		       sizeof(key_entry.rx_mic));
-
-		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
-		timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
-		rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-						    USB_VENDOR_REQUEST_OUT,
-						    offset, &key_entry,
-						    sizeof(key_entry),
-						    timeout);
-	}
-
-	/*
-	 * The cipher types are stored over multiple registers
-	 * starting with SHARED_KEY_MODE_BASE each word will have
-	 * 32 bits and contains the cipher types for 2 bssidx each.
-	 * Using the correct defines correctly will cause overhead,
-	 * so just calculate the correct offset.
-	 */
-	field.bit_offset = 4 * (key->hw_key_idx % 8);
-	field.bit_mask = 0x7 << field.bit_offset;
-
-	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
-
-	rt2x00usb_register_read(rt2x00dev, offset, &reg);
-	rt2x00_set_field32(&reg, field,
-			   (crypto->cmd == SET_KEY) * crypto->cipher);
-	rt2x00usb_register_write(rt2x00dev, offset, reg);
-
-	/*
-	 * Update WCID information
-	 */
-	rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
-
-	return 0;
-}
-
-static int rt2800usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
-					 struct rt2x00lib_crypto *crypto,
-					 struct ieee80211_key_conf *key)
-{
-	struct hw_key_entry key_entry;
-	int timeout;
-	u32 offset;
-
-	if (crypto->cmd == SET_KEY) {
-		/*
-		 * 1 pairwise key is possible per AID, this means that the AID
-		 * equals our hw_key_idx. Make sure the WCID starts _after_ the
-		 * last possible shared key entry.
-		 */
-		if (crypto->aid > (256 - 32))
-			return -ENOSPC;
-
-		key->hw_key_idx = 32 + crypto->aid;
-
-		memcpy(key_entry.key, crypto->key,
-		       sizeof(key_entry.key));
-		memcpy(key_entry.tx_mic, crypto->tx_mic,
-		       sizeof(key_entry.tx_mic));
-		memcpy(key_entry.rx_mic, crypto->rx_mic,
-		       sizeof(key_entry.rx_mic));
-
-		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
-		timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
-		rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
-						    USB_VENDOR_REQUEST_OUT,
-						    offset, &key_entry,
-						    sizeof(key_entry),
-						    timeout);
-	}
-
-	/*
-	 * Update WCID information
-	 */
-	rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
-
-	return 0;
-}
-
-static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev,
-				    const unsigned int filter_flags)
-{
-	u32 reg;
-
-	/*
-	 * Start configuration steps.
-	 * Note that the version error will always be dropped
-	 * and broadcast frames will always be accepted since
-	 * there is no filter for it at this time.
-	 */
-	rt2x00usb_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR,
-			   !(filter_flags & FIF_FCSFAIL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
-			   !(filter_flags & FIF_PLCPFAIL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
-			   !(filter_flags & FIF_PROMISC_IN_BSS));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
-			   !(filter_flags & FIF_ALLMULTI));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
-			   !(filter_flags & FIF_PSPOLL));
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
-	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
-			   !(filter_flags & FIF_CONTROL));
-	rt2x00usb_register_write(rt2x00dev, RX_FILTER_CFG, reg);
-}
-
-static void rt2800usb_config_intf(struct rt2x00_dev *rt2x00dev,
-				  struct rt2x00_intf *intf,
-				  struct rt2x00intf_conf *conf,
-				  const unsigned int flags)
-{
-	unsigned int beacon_base;
-	u32 reg;
-
-	if (flags & CONFIG_UPDATE_TYPE) {
-		/*
-		 * Clear current synchronisation setup.
-		 * For the Beacon base registers we only need to clear
-		 * the first byte since that byte contains the VALID and OWNER
-		 * bits which (when set to 0) will invalidate the entire beacon.
-		 */
-		beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-		rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
-
-		/*
-		 * Enable synchronisation.
-		 */
-		rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
-		rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-	}
-
-	if (flags & CONFIG_UPDATE_MAC) {
-		reg = le32_to_cpu(conf->mac[1]);
-		rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
-		conf->mac[1] = cpu_to_le32(reg);
-
-		rt2x00usb_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
-					      conf->mac, sizeof(conf->mac));
-	}
-
-	if (flags & CONFIG_UPDATE_BSSID) {
-		reg = le32_to_cpu(conf->bssid[1]);
-		rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0);
-		rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
-		conf->bssid[1] = cpu_to_le32(reg);
-
-		rt2x00usb_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
-					      conf->bssid, sizeof(conf->bssid));
-	}
-}
-
-static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
-				 struct rt2x00lib_erp *erp)
-{
-	u32 reg;
-
-	rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
-	rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
-			   !!erp->short_preamble);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
-			   !!erp->short_preamble);
-	rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
-			   erp->cts_protection ? 2 : 0);
-	rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
-
-	rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE,
-				 erp->basic_rates);
-	rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
-
-	rt2x00usb_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
-	rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
-	rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
-	rt2x00usb_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
-	rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
-	rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
-	rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
-	rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
-	rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
-	rt2x00usb_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
-			   erp->beacon_int * 16);
-	rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-}
-
-static void rt2800usb_config_ant(struct rt2x00_dev *rt2x00dev,
-				 struct antenna_setup *ant)
-{
-	u8 r1;
-	u8 r3;
-
-	rt2800usb_bbp_read(rt2x00dev, 1, &r1);
-	rt2800usb_bbp_read(rt2x00dev, 3, &r3);
-
-	/*
-	 * Configure the TX antenna.
-	 */
-	switch ((int)ant->tx) {
-	case 1:
-		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
-		break;
-	case 2:
-		rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
-		break;
-	case 3:
-		/* Do nothing */
-		break;
-	}
-
-	/*
-	 * Configure the RX antenna.
-	 */
-	switch ((int)ant->rx) {
-	case 1:
-		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
-		break;
-	case 2:
-		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
-		break;
-	case 3:
-		rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
-		break;
-	}
-
-	rt2800usb_bbp_write(rt2x00dev, 3, r3);
-	rt2800usb_bbp_write(rt2x00dev, 1, r1);
-}
-
-static void rt2800usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
-				      struct rt2x00lib_conf *libconf)
-{
-	u16 eeprom;
-	short lna_gain;
-
-	if (libconf->rf.channel <= 14) {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
-	} else if (libconf->rf.channel <= 64) {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
-	} else if (libconf->rf.channel <= 128) {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
-	} else {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
-		lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
-	}
-
-	rt2x00dev->lna_gain = lna_gain;
-}
-
-static void rt2800usb_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
-					  struct ieee80211_conf *conf,
-					  struct rf_channel *rf,
-					  struct channel_info *info)
-{
-	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
-
-	if (rt2x00dev->default_ant.tx == 1)
-		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
-
-	if (rt2x00dev->default_ant.rx == 1) {
-		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
-		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
-	} else if (rt2x00dev->default_ant.rx == 2)
-		rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
-
-	if (rf->channel > 14) {
-		/*
-		 * When TX power is below 0, we should increase it by 7 to
-		 * make it a positive value (Minumum value is -7).
-		 * However this means that values between 0 and 7 have
-		 * double meaning, and we should set a 7DBm boost flag.
-		 */
-		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
-				   (info->tx_power1 >= 0));
-
-		if (info->tx_power1 < 0)
-			info->tx_power1 += 7;
-
-		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
-				   TXPOWER_A_TO_DEV(info->tx_power1));
-
-		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
-				   (info->tx_power2 >= 0));
-
-		if (info->tx_power2 < 0)
-			info->tx_power2 += 7;
-
-		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
-				   TXPOWER_A_TO_DEV(info->tx_power2));
-	} else {
-		rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
-				   TXPOWER_G_TO_DEV(info->tx_power1));
-		rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
-				   TXPOWER_G_TO_DEV(info->tx_power2));
-	}
-
-	rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
-
-	rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
-	rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
-	rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-	rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
-
-	udelay(200);
-
-	rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
-	rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
-	rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
-	rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
-
-	udelay(200);
-
-	rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
-	rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
-	rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-	rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
-}
-
-static void rt2800usb_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
-					  struct ieee80211_conf *conf,
-					  struct rf_channel *rf,
-					  struct channel_info *info)
-{
-	u8 rfcsr;
-
-	rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf1);
-	rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf3);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 6, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
-	rt2800usb_rfcsr_write(rt2x00dev, 6, rfcsr);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 12, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
-			  TXPOWER_G_TO_DEV(info->tx_power1));
-	rt2800usb_rfcsr_write(rt2x00dev, 12, rfcsr);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
-	rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
-
-	rt2800usb_rfcsr_write(rt2x00dev, 24,
-			      rt2x00dev->calibration[conf_is_ht40(conf)]);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
-	rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
-}
-
-static void rt2800usb_config_channel(struct rt2x00_dev *rt2x00dev,
-				     struct ieee80211_conf *conf,
-				     struct rf_channel *rf,
-				     struct channel_info *info)
-{
-	u32 reg;
-	unsigned int tx_pin;
-	u8 bbp;
-
-	if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
-		rt2800usb_config_channel_rt2x(rt2x00dev, conf, rf, info);
-	else
-		rt2800usb_config_channel_rt3x(rt2x00dev, conf, rf, info);
-
-	/*
-	 * Change BBP settings
-	 */
-	rt2800usb_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
-	rt2800usb_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-	rt2800usb_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
-	rt2800usb_bbp_write(rt2x00dev, 86, 0);
-
-	if (rf->channel <= 14) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
-			rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
-			rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
-		} else {
-			rt2800usb_bbp_write(rt2x00dev, 82, 0x84);
-			rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
-		}
-	} else {
-		rt2800usb_bbp_write(rt2x00dev, 82, 0xf2);
-
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
-			rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
-		else
-			rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
-	}
-
-	rt2x00usb_register_read(rt2x00dev, TX_BAND_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
-	rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
-	rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
-	rt2x00usb_register_write(rt2x00dev, TX_BAND_CFG, reg);
-
-	tx_pin = 0;
-
-	/* Turn on unused PA or LNA when not using 1T or 1R */
-	if (rt2x00dev->default_ant.tx != 1) {
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
-	}
-
-	/* Turn on unused PA or LNA when not using 1T or 1R */
-	if (rt2x00dev->default_ant.rx != 1) {
-		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);
-	}
-
-	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);
-	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);
-
-	rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-
-	rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
-	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
-	rt2800usb_bbp_write(rt2x00dev, 4, bbp);
-
-	rt2800usb_bbp_read(rt2x00dev, 3, &bbp);
-	rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
-	rt2800usb_bbp_write(rt2x00dev, 3, bbp);
-
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
-		if (conf_is_ht40(conf)) {
-			rt2800usb_bbp_write(rt2x00dev, 69, 0x1a);
-			rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
-			rt2800usb_bbp_write(rt2x00dev, 73, 0x16);
-		} else {
-			rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
-			rt2800usb_bbp_write(rt2x00dev, 70, 0x08);
-			rt2800usb_bbp_write(rt2x00dev, 73, 0x11);
-		}
-	}
-
-	msleep(1);
-}
-
-static void rt2800usb_config_txpower(struct rt2x00_dev *rt2x00dev,
-				     const int txpower)
-{
-	u32 reg;
-	u32 value = TXPOWER_G_TO_DEV(txpower);
-	u8 r1;
-
-	rt2800usb_bbp_read(rt2x00dev, 1, &r1);
-	rt2x00_set_field8(&reg, BBP1_TX_POWER, 0);
-	rt2800usb_bbp_write(rt2x00dev, 1, r1);
-
-	rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value);
-	rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
-
-	rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_1, &reg);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value);
-	rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
-
-	rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_2, &reg);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value);
-	rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
-
-	rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_3, &reg);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value);
-	rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
-
-	rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_4, &reg);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value);
-	rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value);
-	rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
-}
-
-static void rt2800usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
-					 struct rt2x00lib_conf *libconf)
-{
-	u32 reg;
-
-	rt2x00usb_register_read(rt2x00dev, TX_RTY_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT,
-			   libconf->conf->short_frame_max_tx_count);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
-			   libconf->conf->long_frame_max_tx_count);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
-	rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
-	rt2x00usb_register_write(rt2x00dev, TX_RTY_CFG, reg);
-}
-
-static void rt2800usb_config_ps(struct rt2x00_dev *rt2x00dev,
-				struct rt2x00lib_conf *libconf)
-{
-	enum dev_state state =
-	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
-		STATE_SLEEP : STATE_AWAKE;
-	u32 reg;
-
-	if (state == STATE_SLEEP) {
-		rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
-
-		rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
-				   libconf->conf->listen_interval - 1);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
-		rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
-
-		rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
-	} else {
-		rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
-
-		rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
-		rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
-		rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
-	}
-}
-
-static void rt2800usb_config(struct rt2x00_dev *rt2x00dev,
-			     struct rt2x00lib_conf *libconf,
-			     const unsigned int flags)
-{
-	/* Always recalculate LNA gain before changing configuration */
-	rt2800usb_config_lna_gain(rt2x00dev, libconf);
-
-	if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
-		rt2800usb_config_channel(rt2x00dev, libconf->conf,
-					 &libconf->rf, &libconf->channel);
-	if (flags & IEEE80211_CONF_CHANGE_POWER)
-		rt2800usb_config_txpower(rt2x00dev, libconf->conf->power_level);
-	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
-		rt2800usb_config_retry_limit(rt2x00dev, libconf);
-	if (flags & IEEE80211_CONF_CHANGE_PS)
-		rt2800usb_config_ps(rt2x00dev, libconf);
-}
-
-/*
- * Link tuning
- */
-static void rt2800usb_link_stats(struct rt2x00_dev *rt2x00dev,
-				 struct link_qual *qual)
-{
-	u32 reg;
-
-	/*
-	 * Update FCS error count from register.
-	 */
-	rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
-	qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
-}
-
-static u8 rt2800usb_get_default_vgc(struct rt2x00_dev *rt2x00dev)
-{
-	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
-		if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
-			return 0x1c + (2 * rt2x00dev->lna_gain);
-		else
-			return 0x2e + rt2x00dev->lna_gain;
-	}
-
-	if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
-		return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
-	else
-		return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
-}
-
-static inline void rt2800usb_set_vgc(struct rt2x00_dev *rt2x00dev,
-				     struct link_qual *qual, u8 vgc_level)
-{
-	if (qual->vgc_level != vgc_level) {
-		rt2800usb_bbp_write(rt2x00dev, 66, vgc_level);
-		qual->vgc_level = vgc_level;
-		qual->vgc_level_reg = vgc_level;
-	}
-}
-
-static void rt2800usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
-				  struct link_qual *qual)
-{
-	rt2800usb_set_vgc(rt2x00dev, qual,
-			  rt2800usb_get_default_vgc(rt2x00dev));
-}
-
-static void rt2800usb_link_tuner(struct rt2x00_dev *rt2x00dev,
-				 struct link_qual *qual, const u32 count)
-{
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
-		return;
-
-	/*
-	 * When RSSI is better then -80 increase VGC level with 0x10
-	 */
-	rt2800usb_set_vgc(rt2x00dev, qual,
-			  rt2800usb_get_default_vgc(rt2x00dev) +
-			  ((qual->rssi > -80) * 0x10));
-}
-
-/*
  * Firmware functions
  */
 static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -1172,7 +157,7 @@ static int rt2800usb_load_firmware(struc
 	 * Wait for stable hardware.
 	 */
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
 		if (reg && reg != ~0)
 			break;
 		msleep(1);
@@ -1192,8 +177,8 @@ static int rt2800usb_load_firmware(struc
 					    data + offset, length,
 					    REGISTER_TIMEOUT32(length));
 
-	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
-	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 
 	/*
 	 * Send firmware request to device to load firmware,
@@ -1208,18 +193,18 @@ static int rt2800usb_load_firmware(struc
 	}
 
 	msleep(10);
-	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
 
 	/*
 	 * Send signal to firmware during boot time.
 	 */
-	rt2800usb_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
 
 	if ((chipset == 0x3070) ||
 	    (chipset == 0x3071) ||
 	    (chipset == 0x3572)) {
 		udelay(200);
-		rt2800usb_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+		rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
 		udelay(10);
 	}
 
@@ -1227,7 +212,7 @@ static int rt2800usb_load_firmware(struc
 	 * Wait for device to stabilize.
 	 */
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
 		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
 			break;
 		msleep(1);
@@ -1241,531 +226,9 @@ static int rt2800usb_load_firmware(struc
 	/*
 	 * Initialize firmware.
 	 */
-	rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-	msleep(1);
-
-	return 0;
-}
-
-/*
- * Initialization functions.
- */
-static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
-{
-	u32 reg;
-	unsigned int i;
-
-	/*
-	 * Wait untill BBP and RF are ready.
-	 */
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
-		if (reg && reg != ~0)
-			break;
-		msleep(1);
-	}
-
-	if (i == REGISTER_BUSY_COUNT) {
-		ERROR(rt2x00dev, "Unstable hardware.\n");
-		return -EBUSY;
-	}
-
-	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
-
-	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
-	rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
-
-	rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
-				    USB_MODE_RESET, REGISTER_TIMEOUT);
-
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
-
-	rt2x00usb_register_read(rt2x00dev, BCN_OFFSET0, &reg);
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
-	rt2x00usb_register_write(rt2x00dev, BCN_OFFSET0, reg);
-
-	rt2x00usb_register_read(rt2x00dev, BCN_OFFSET1, &reg);
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
-	rt2x00usb_register_write(rt2x00dev, BCN_OFFSET1, reg);
-
-	rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
-	rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
-
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
-
-	rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
-	rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
-	if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
-		rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
-		rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
-		rt2x00usb_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
-	} else {
-		rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
-		rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
-	}
-
-	rt2x00usb_register_read(rt2x00dev, TX_LINK_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
-	rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
-	rt2x00usb_register_write(rt2x00dev, TX_LINK_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
-	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
-	rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
-	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
-	if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
-	    rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
-		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
-	else
-		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
-	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
-	rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
-	rt2x00usb_register_write(rt2x00dev, MAX_LEN_CFG, reg);
-
-	rt2x00usb_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
-
-	rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
-	rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
-	rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
-	rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
-	rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
-	rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
-	rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
-	rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
-	rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
-
-	rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
-
-	rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
-	rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
-	rt2x00usb_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
-	rt2x00usb_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
-
-	rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
-	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
-			   IEEE80211_MAX_RTS_THRESHOLD);
-	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
-	rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
-
-	rt2x00usb_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
-	rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-
-	/*
-	 * ASIC will keep garbage value after boot, clear encryption keys.
-	 */
-	for (i = 0; i < 4; i++)
-		rt2x00usb_register_write(rt2x00dev,
-					 SHARED_KEY_MODE_ENTRY(i), 0);
-
-	for (i = 0; i < 256; i++) {
-		u32 wcid[2] = { 0xffffffff, 0x00ffffff };
-		rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
-					      wcid, sizeof(wcid));
-
-		rt2x00usb_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
-		rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
-	}
-
-	/*
-	 * Clear all beacons
-	 * For the Beacon base registers we only need to clear
-	 * the first byte since that byte contains the VALID and OWNER
-	 * bits which (when set to 0) will invalidate the entire beacon.
-	 */
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
-	rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
-
-	rt2x00usb_register_read(rt2x00dev, USB_CYC_CFG, &reg);
-	rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
-	rt2x00usb_register_write(rt2x00dev, USB_CYC_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
-	rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
-	rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG0, reg);
-
-	rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
-	rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
-	rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG1, reg);
-
-	rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 9);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
-	rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG0, reg);
-
-	rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
-	rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG1, reg);
-
-	/*
-	 * We must clear the error counters.
-	 * These registers are cleared on read,
-	 * so we may pass a useless variable to store the value.
-	 */
-	rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
-	rt2x00usb_register_read(rt2x00dev, RX_STA_CNT1, &reg);
-	rt2x00usb_register_read(rt2x00dev, RX_STA_CNT2, &reg);
-	rt2x00usb_register_read(rt2x00dev, TX_STA_CNT0, &reg);
-	rt2x00usb_register_read(rt2x00dev, TX_STA_CNT1, &reg);
-	rt2x00usb_register_read(rt2x00dev, TX_STA_CNT2, &reg);
-
-	return 0;
-}
-
-static int rt2800usb_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
-{
-	unsigned int i;
-	u32 reg;
-
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00usb_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
-		if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
-			return 0;
-
-		udelay(REGISTER_BUSY_DELAY);
-	}
-
-	ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
-	return -EACCES;
-}
-
-static int rt2800usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
-{
-	unsigned int i;
-	u8 value;
-
-	/*
-	 * BBP was enabled after firmware was loaded,
-	 * but we need to reactivate it now.
-	 */
-	rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-	msleep(1);
-
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2800usb_bbp_read(rt2x00dev, 0, &value);
-		if ((value != 0xff) && (value != 0x00))
-			return 0;
-		udelay(REGISTER_BUSY_DELAY);
-	}
-
-	ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
-	return -EACCES;
-}
-
-static int rt2800usb_init_bbp(struct rt2x00_dev *rt2x00dev)
-{
-	unsigned int i;
-	u16 eeprom;
-	u8 reg_id;
-	u8 value;
-
-	if (unlikely(rt2800usb_wait_bbp_rf_ready(rt2x00dev) ||
-		     rt2800usb_wait_bbp_ready(rt2x00dev)))
-		return -EACCES;
-
-	rt2800usb_bbp_write(rt2x00dev, 65, 0x2c);
-	rt2800usb_bbp_write(rt2x00dev, 66, 0x38);
-	rt2800usb_bbp_write(rt2x00dev, 69, 0x12);
-	rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
-	rt2800usb_bbp_write(rt2x00dev, 73, 0x10);
-	rt2800usb_bbp_write(rt2x00dev, 81, 0x37);
-	rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
-	rt2800usb_bbp_write(rt2x00dev, 83, 0x6a);
-	rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
-	rt2800usb_bbp_write(rt2x00dev, 86, 0x00);
-	rt2800usb_bbp_write(rt2x00dev, 91, 0x04);
-	rt2800usb_bbp_write(rt2x00dev, 92, 0x00);
-	rt2800usb_bbp_write(rt2x00dev, 103, 0x00);
-	rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
-
-	if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
-		rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
-		rt2800usb_bbp_write(rt2x00dev, 73, 0x12);
-	}
-
-	if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION) {
-		rt2800usb_bbp_write(rt2x00dev, 84, 0x19);
-	}
-
-	if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
-		rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
-		rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
-		rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
-	}
-
-	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
-
-		if (eeprom != 0xffff && eeprom != 0x0000) {
-			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
-			value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
-			rt2800usb_bbp_write(rt2x00dev, reg_id, value);
-		}
-	}
-
-	return 0;
-}
-
-static u8 rt2800usb_init_rx_filter(struct rt2x00_dev *rt2x00dev,
-				   bool bw40, u8 rfcsr24, u8 filter_target)
-{
-	unsigned int i;
-	u8 bbp;
-	u8 rfcsr;
-	u8 passband;
-	u8 stopband;
-	u8 overtuned = 0;
-
-	rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
-
-	rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
-	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
-	rt2800usb_bbp_write(rt2x00dev, 4, bbp);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
-	rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
-
-	/*
-	 * Set power & frequency of passband test tone
-	 */
-	rt2800usb_bbp_write(rt2x00dev, 24, 0);
-
-	for (i = 0; i < 100; i++) {
-		rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
-		msleep(1);
-
-		rt2800usb_bbp_read(rt2x00dev, 55, &passband);
-		if (passband)
-			break;
-	}
-
-	/*
-	 * Set power & frequency of stopband test tone
-	 */
-	rt2800usb_bbp_write(rt2x00dev, 24, 0x06);
-
-	for (i = 0; i < 100; i++) {
-		rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
-		msleep(1);
-
-		rt2800usb_bbp_read(rt2x00dev, 55, &stopband);
-
-		if ((passband - stopband) <= filter_target) {
-			rfcsr24++;
-			overtuned += ((passband - stopband) == filter_target);
-		} else
-			break;
-
-		rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
-	}
-
-	rfcsr24 -= !!overtuned;
-
-	rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
-	return rfcsr24;
-}
-
-static int rt2800usb_init_rfcsr(struct rt2x00_dev *rt2x00dev)
-{
-	u8 rfcsr;
-	u8 bbp;
-
-	if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
-		return 0;
-
-	/*
-	 * Init RF calibration.
-	 */
-	rt2800usb_rfcsr_read(rt2x00dev, 30, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
-	rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
 	msleep(1);
-	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
-	rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
-
-	rt2800usb_rfcsr_write(rt2x00dev, 4, 0x40);
-	rt2800usb_rfcsr_write(rt2x00dev, 5, 0x03);
-	rt2800usb_rfcsr_write(rt2x00dev, 6, 0x02);
-	rt2800usb_rfcsr_write(rt2x00dev, 7, 0x70);
-	rt2800usb_rfcsr_write(rt2x00dev, 9, 0x0f);
-	rt2800usb_rfcsr_write(rt2x00dev, 10, 0x71);
-	rt2800usb_rfcsr_write(rt2x00dev, 11, 0x21);
-	rt2800usb_rfcsr_write(rt2x00dev, 12, 0x7b);
-	rt2800usb_rfcsr_write(rt2x00dev, 14, 0x90);
-	rt2800usb_rfcsr_write(rt2x00dev, 15, 0x58);
-	rt2800usb_rfcsr_write(rt2x00dev, 16, 0xb3);
-	rt2800usb_rfcsr_write(rt2x00dev, 17, 0x92);
-	rt2800usb_rfcsr_write(rt2x00dev, 18, 0x2c);
-	rt2800usb_rfcsr_write(rt2x00dev, 19, 0x02);
-	rt2800usb_rfcsr_write(rt2x00dev, 20, 0xba);
-	rt2800usb_rfcsr_write(rt2x00dev, 21, 0xdb);
-	rt2800usb_rfcsr_write(rt2x00dev, 24, 0x16);
-	rt2800usb_rfcsr_write(rt2x00dev, 25, 0x01);
-	rt2800usb_rfcsr_write(rt2x00dev, 27, 0x03);
-	rt2800usb_rfcsr_write(rt2x00dev, 29, 0x1f);
-
-	/*
-	 * Set RX Filter calibration for 20MHz and 40MHz
-	 */
-	rt2x00dev->calibration[0] =
-	    rt2800usb_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
-	rt2x00dev->calibration[1] =
-	    rt2800usb_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
-
-	/*
-	 * Set back to initial state
-	 */
-	rt2800usb_bbp_write(rt2x00dev, 24, 0);
-
-	rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
-	rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
-
-	/*
-	 * set BBP back to BW20
-	 */
-	rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
-	rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
-	rt2800usb_bbp_write(rt2x00dev, 4, bbp);
 
 	return 0;
 }
@@ -1778,11 +241,11 @@ static void rt2800usb_toggle_rx(struct r
 {
 	u32 reg;
 
-	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
 			   (state == STATE_RADIO_RX_ON) ||
 			   (state == STATE_RADIO_RX_ON_LINK));
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 }
 
 static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
@@ -1791,7 +254,7 @@ static int rt2800usb_wait_wpdma_ready(st
 	u32 reg;
 
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+		rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 		if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
 		    !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
 			return 0;
@@ -1812,25 +275,25 @@ static int rt2800usb_enable_radio(struct
 	 * Initialize all registers.
 	 */
 	if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
-		     rt2800usb_init_registers(rt2x00dev) ||
-		     rt2800usb_init_bbp(rt2x00dev) ||
-		     rt2800usb_init_rfcsr(rt2x00dev)))
+		     rt2800_init_registers(rt2x00dev) ||
+		     rt2800_init_bbp(rt2x00dev) ||
+		     rt2800_init_rfcsr(rt2x00dev)))
 		return -EIO;
 
-	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 
 	udelay(50);
 
-	rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
-	rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 
 
-	rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+	rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
 	/* Don't use bulk in aggregation when working with USB 1.1 */
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
@@ -1844,26 +307,26 @@ static int rt2800usb_enable_radio(struct
 			   ((RX_ENTRIES * 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);
-	rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
+	rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
 
-	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 
 	/*
 	 * Initialize LED control
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
-	rt2800usb_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+	rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
 			      word & 0xff, (word >> 8) & 0xff);
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
-	rt2800usb_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+	rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
 			      word & 0xff, (word >> 8) & 0xff);
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
-	rt2800usb_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+	rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
 			      word & 0xff, (word >> 8) & 0xff);
 
 	return 0;
@@ -1873,14 +336,14 @@ static void rt2800usb_disable_radio(stru
 {
 	u32 reg;
 
-	rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
-	rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 
-	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
-	rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-	rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, 0);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+	rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
 
 	/* Wait for DMA, ignore error */
 	rt2800usb_wait_wpdma_ready(rt2x00dev);
@@ -1892,9 +355,9 @@ static int rt2800usb_set_state(struct rt
 			       enum dev_state state)
 {
 	if (state == STATE_AWAKE)
-		rt2800usb_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+		rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
 	else
-		rt2800usb_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
 
 	return 0;
 }
@@ -2048,9 +511,9 @@ static void rt2800usb_write_beacon(struc
 	 * Disable beaconing while we are reloading the beacon data,
 	 * otherwise we might be sending out invalid data.
 	 */
-	rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
-	rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+	rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
 	/*
 	 * Write entire beacon with descriptor to register.
@@ -2093,12 +556,12 @@ static void rt2800usb_kick_tx_queue(stru
 		return;
 	}
 
-	rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+	rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 	if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-		rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 	}
 }
 
@@ -2124,7 +587,7 @@ static void rt2800usb_fill_rxdone(struct
 	 */
 	memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
 	rxd = (__le32 *)skbdesc->desc;
-	rxwi = &rxd[RXD_DESC_SIZE / sizeof(__le32)];
+	rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)];
 
 	/*
 	 * It is now safe to read the descriptor on all architectures.
@@ -2135,16 +598,16 @@ static void rt2800usb_fill_rxdone(struct
 	rt2x00_desc_read(rxwi, 2, &rxwi2);
 	rt2x00_desc_read(rxwi, 3, &rxwi3);
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
+	if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR))
 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
 
 	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
 		rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
 		rxdesc->cipher_status =
-		    rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+		    rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR);
 	}
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
+	if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) {
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
 		 * decryption. Unfortunately the descriptor doesn't contain
@@ -2159,10 +622,10 @@ static void rt2800usb_fill_rxdone(struct
 			rxdesc->flags |= RX_FLAG_MMIC_ERROR;
 	}
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
+	if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) {
+	if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) {
 		rxdesc->dev_flags |= RXDONE_L2PAD;
 		skbdesc->flags |= SKBDESC_L2_PADDED;
 	}
@@ -2208,402 +671,33 @@ static void rt2800usb_fill_rxdone(struct
  */
 static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 {
-	u16 word;
-	u8 *mac;
-	u8 default_lna_gain;
-
-	rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);
-
-	/*
-	 * Start validation of the data that has been read.
-	 */
-	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
-	if (!is_valid_ether_addr(mac)) {
-		random_ether_addr(mac);
-		EEPROM(rt2x00dev, "MAC: %pM\n", mac);
-	}
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
-	if (word == 0xffff) {
-		rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
-		rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
-		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
-		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
-	} else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
-		/*
-		 * There is a max of 2 RX streams for RT2870 series
-		 */
-		if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
-			rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
-	}
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
-	if (word == 0xffff) {
-		rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
-		EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
-	}
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
-	if ((word & 0x00ff) == 0x00ff) {
-		rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
-		rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
-				   LED_MODE_TXRX_ACTIVITY);
-		rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
-		EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
-	}
-
-	/*
-	 * During the LNA validation we are going to use
-	 * lna0 as correct value. Note that EEPROM_LNA
-	 * is never validated.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
-	default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
-	if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
-	    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
-		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
-				   default_lna_gain);
-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
-	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
-		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
-	if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
-	    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
-		rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
-				   default_lna_gain);
-	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
-
-	return 0;
-}
-
-static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
-{
-	u32 reg;
-	u16 value;
-	u16 eeprom;
-
-	/*
-	 * Read EEPROM word for configuration.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
-
-	/*
-	 * Identify RF chipset.
-	 */
-	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
-	rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
-	rt2x00_set_chip(rt2x00dev, RT2870, value, reg);
-
-	/*
-	 * The check for rt2860 is not a typo, some rt2870 hardware
-	 * identifies itself as rt2860 in the CSR register.
-	 */
-	if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) &&
-	    !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) &&
-	    !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) &&
-	    !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) {
-		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
-		return -ENODEV;
-	}
-
-	if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
-	    !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
-		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Identify default antenna configuration.
-	 */
-	rt2x00dev->default_ant.tx =
-	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
-	rt2x00dev->default_ant.rx =
-	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
-
-	/*
-	 * Read frequency offset and RF programming sequence.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
-	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
-
-	/*
-	 * Read external LNA informations.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
-
-	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
-		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
-		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
-
-	/*
-	 * Detect if this device has an hardware controlled radio.
-	 */
-	if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-
-	/*
-	 * Store led settings, for correct led behaviour.
-	 */
-#ifdef CONFIG_RT2X00_LIB_LEDS
-	rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
-	rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
-	rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ,
-			   &rt2x00dev->led_mcu_reg);
-#endif /* CONFIG_RT2X00_LIB_LEDS */
+	if (rt2800_efuse_detect(rt2x00dev))
+		rt2800_read_eeprom_efuse(rt2x00dev);
+	else
+		rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
+				      EEPROM_SIZE);
 
-	return 0;
+	return rt2800_validate_eeprom(rt2x00dev);
 }
 
-/*
- * RF value list for rt2870
- * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
- */
-static const struct rf_channel rf_vals[] = {
-	{ 1,  0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
-	{ 2,  0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
-	{ 3,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
-	{ 4,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
-	{ 5,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
-	{ 6,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
-	{ 7,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
-	{ 8,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
-	{ 9,  0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
-	{ 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
-	{ 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
-	{ 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
-	{ 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
-	{ 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
-
-	/* 802.11 UNI / HyperLan 2 */
-	{ 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
-	{ 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
-	{ 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
-	{ 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
-	{ 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
-	{ 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
-	{ 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
-	{ 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
-	{ 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
-	{ 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
-	{ 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
-	{ 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
-
-	/* 802.11 HyperLan 2 */
-	{ 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
-	{ 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
-	{ 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
-	{ 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
-	{ 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
-	{ 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
-	{ 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
-	{ 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
-	{ 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
-	{ 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
-	{ 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
-	{ 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
-	{ 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
-	{ 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
-	{ 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
-	{ 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
-
-	/* 802.11 UNII */
-	{ 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
-	{ 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
-	{ 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
-	{ 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
-	{ 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
-	{ 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
-	{ 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
-	{ 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
-	{ 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
-	{ 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
-	{ 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
+static const struct rt2800_ops rt2800usb_rt2800_ops = {
+	.register_read		= rt2x00usb_register_read,
+	.register_read_lock	= rt2x00usb_register_read_lock,
+	.register_write		= rt2x00usb_register_write,
+	.register_write_lock	= rt2x00usb_register_write_lock,
 
-	/* 802.11 Japan */
-	{ 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
-	{ 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
-	{ 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
-	{ 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
-	{ 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
-	{ 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
-	{ 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
-};
+	.register_multiread	= rt2x00usb_register_multiread,
+	.register_multiwrite	= rt2x00usb_register_multiwrite,
 
-/*
- * RF value list for rt3070
- * Supports: 2.4 GHz
- */
-static const struct rf_channel rf_vals_3070[] = {
-	{1,  241, 2, 2 },
-	{2,  241, 2, 7 },
-	{3,  242, 2, 2 },
-	{4,  242, 2, 7 },
-	{5,  243, 2, 2 },
-	{6,  243, 2, 7 },
-	{7,  244, 2, 2 },
-	{8,  244, 2, 7 },
-	{9,  245, 2, 2 },
-	{10, 245, 2, 7 },
-	{11, 246, 2, 2 },
-	{12, 246, 2, 7 },
-	{13, 247, 2, 2 },
-	{14, 248, 2, 4 },
+	.regbusy_read		= rt2x00usb_regbusy_read,
 };
 
-static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
-{
-	struct hw_mode_spec *spec = &rt2x00dev->spec;
-	struct channel_info *info;
-	char *tx_power1;
-	char *tx_power2;
-	unsigned int i;
-	u16 eeprom;
-
-	/*
-	 * Initialize all hw fields.
-	 */
-	rt2x00dev->hw->flags =
-	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-	    IEEE80211_HW_SIGNAL_DBM |
-	    IEEE80211_HW_SUPPORTS_PS |
-	    IEEE80211_HW_PS_NULLFUNC_STACK;
-	rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
-
-	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
-	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
-				rt2x00_eeprom_addr(rt2x00dev,
-						   EEPROM_MAC_ADDR_0));
-
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
-
-	/*
-	 * Initialize HT information.
-	 */
-	spec->ht.ht_supported = true;
-	spec->ht.cap =
-	    IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-	    IEEE80211_HT_CAP_GRN_FLD |
-	    IEEE80211_HT_CAP_SGI_20 |
-	    IEEE80211_HT_CAP_SGI_40 |
-	    IEEE80211_HT_CAP_TX_STBC |
-	    IEEE80211_HT_CAP_RX_STBC |
-	    IEEE80211_HT_CAP_PSMP_SUPPORT;
-	spec->ht.ampdu_factor = 3;
-	spec->ht.ampdu_density = 4;
-	spec->ht.mcs.tx_params =
-	    IEEE80211_HT_MCS_TX_DEFINED |
-	    IEEE80211_HT_MCS_TX_RX_DIFF |
-	    ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
-		IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
-
-	switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
-	case 3:
-		spec->ht.mcs.rx_mask[2] = 0xff;
-	case 2:
-		spec->ht.mcs.rx_mask[1] = 0xff;
-	case 1:
-		spec->ht.mcs.rx_mask[0] = 0xff;
-		spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
-		break;
-	}
-
-	/*
-	 * Initialize hw_mode information.
-	 */
-	spec->supported_bands = SUPPORT_BAND_2GHZ;
-	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-
-	if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF2720)) {
-		spec->num_channels = 14;
-		spec->channels = rf_vals;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
-		   rt2x00_rf(&rt2x00dev->chip, RF2750)) {
-		spec->supported_bands |= SUPPORT_BAND_5GHZ;
-		spec->num_channels = ARRAY_SIZE(rf_vals);
-		spec->channels = rf_vals;
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF3020) ||
-		   rt2x00_rf(&rt2x00dev->chip, RF2020)) {
-		spec->num_channels = ARRAY_SIZE(rf_vals_3070);
-		spec->channels = rf_vals_3070;
-	}
-
-	/*
-	 * Create channel information array
-	 */
-	info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	spec->channels_info = info;
-
-	tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
-	tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
-
-	for (i = 0; i < 14; i++) {
-		info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
-		info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
-	}
-
-	if (spec->num_channels > 14) {
-		tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
-		tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
-
-		for (i = 14; i < spec->num_channels; i++) {
-			info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
-			info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
-		}
-	}
-
-	return 0;
-}
-
 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
 
+	rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops;
+
 	/*
 	 * Allocate eeprom data.
 	 */
@@ -2611,14 +705,14 @@ static int rt2800usb_probe_hw(struct rt2
 	if (retval)
 		return retval;
 
-	retval = rt2800usb_init_eeprom(rt2x00dev);
+	retval = rt2800_init_eeprom(rt2x00dev);
 	if (retval)
 		return retval;
 
 	/*
 	 * Initialize hw specifications.
 	 */
-	retval = rt2800usb_probe_hw_mode(rt2x00dev);
+	retval = rt2800_probe_hw_mode(rt2x00dev);
 	if (retval)
 		return retval;
 
@@ -2645,162 +739,6 @@ static int rt2800usb_probe_hw(struct rt2
 	return 0;
 }
 
-/*
- * IEEE80211 stack callback functions.
- */
-static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
-				   u32 *iv32, u16 *iv16)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct mac_iveiv_entry iveiv_entry;
-	u32 offset;
-
-	offset = MAC_IVEIV_ENTRY(hw_key_idx);
-	rt2x00usb_register_multiread(rt2x00dev, offset,
-				      &iveiv_entry, sizeof(iveiv_entry));
-
-	memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16));
-	memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32));
-}
-
-static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	u32 reg;
-	bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
-
-	rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
-	rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
-	rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
-	rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
-
-	return 0;
-}
-
-static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
-			     const struct ieee80211_tx_queue_params *params)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct data_queue *queue;
-	struct rt2x00_field32 field;
-	int retval;
-	u32 reg;
-	u32 offset;
-
-	/*
-	 * First pass the configuration through rt2x00lib, that will
-	 * update the queue settings and validate the input. After that
-	 * we are free to update the registers based on the value
-	 * in the queue parameter.
-	 */
-	retval = rt2x00mac_conf_tx(hw, queue_idx, params);
-	if (retval)
-		return retval;
-
-	/*
-	 * We only need to perform additional register initialization
-	 * for WMM queues/
-	 */
-	if (queue_idx >= 4)
-		return 0;
-
-	queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
-
-	/* Update WMM TXOP register */
-	offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
-	field.bit_offset = (queue_idx & 1) * 16;
-	field.bit_mask = 0xffff << field.bit_offset;
-
-	rt2x00usb_register_read(rt2x00dev, offset, &reg);
-	rt2x00_set_field32(&reg, field, queue->txop);
-	rt2x00usb_register_write(rt2x00dev, offset, reg);
-
-	/* Update WMM registers */
-	field.bit_offset = queue_idx * 4;
-	field.bit_mask = 0xf << field.bit_offset;
-
-	rt2x00usb_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
-	rt2x00_set_field32(&reg, field, queue->aifs);
-	rt2x00usb_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
-	rt2x00_set_field32(&reg, field, queue->cw_min);
-	rt2x00usb_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
-
-	rt2x00usb_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
-	rt2x00_set_field32(&reg, field, queue->cw_max);
-	rt2x00usb_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
-
-	/* Update EDCA registers */
-	offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
-
-	rt2x00usb_register_read(rt2x00dev, offset, &reg);
-	rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
-	rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
-	rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
-	rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
-	rt2x00usb_register_write(rt2x00dev, offset, reg);
-
-	return 0;
-}
-
-static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	u64 tsf;
-	u32 reg;
-
-	rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
-	tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
-	rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
-	tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
-
-	return tsf;
-}
-
-static const struct ieee80211_ops rt2800usb_mac80211_ops = {
-	.tx			= rt2x00mac_tx,
-	.start			= rt2x00mac_start,
-	.stop			= rt2x00mac_stop,
-	.add_interface		= rt2x00mac_add_interface,
-	.remove_interface	= rt2x00mac_remove_interface,
-	.config			= rt2x00mac_config,
-	.configure_filter	= rt2x00mac_configure_filter,
-	.set_tim		= rt2x00mac_set_tim,
-	.set_key		= rt2x00mac_set_key,
-	.get_stats		= rt2x00mac_get_stats,
-	.get_tkip_seq		= rt2800usb_get_tkip_seq,
-	.set_rts_threshold	= rt2800usb_set_rts_threshold,
-	.bss_info_changed	= rt2x00mac_bss_info_changed,
-	.conf_tx		= rt2800usb_conf_tx,
-	.get_tx_stats		= rt2x00mac_get_tx_stats,
-	.get_tsf		= rt2800usb_get_tsf,
-	.rfkill_poll		= rt2x00mac_rfkill_poll,
-};
-
 static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
 	.probe_hw		= rt2800usb_probe_hw,
 	.get_firmware_name	= rt2800usb_get_firmware_name,
@@ -2810,10 +748,10 @@ static const struct rt2x00lib_ops rt2800
 	.uninitialize		= rt2x00usb_uninitialize,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.set_device_state	= rt2800usb_set_device_state,
-	.rfkill_poll		= rt2800usb_rfkill_poll,
-	.link_stats		= rt2800usb_link_stats,
-	.reset_tuner		= rt2800usb_reset_tuner,
-	.link_tuner		= rt2800usb_link_tuner,
+	.rfkill_poll		= rt2800_rfkill_poll,
+	.link_stats		= rt2800_link_stats,
+	.reset_tuner		= rt2800_reset_tuner,
+	.link_tuner		= rt2800_link_tuner,
 	.write_tx_desc		= rt2800usb_write_tx_desc,
 	.write_tx_data		= rt2x00usb_write_tx_data,
 	.write_beacon		= rt2800usb_write_beacon,
@@ -2821,19 +759,19 @@ static const struct rt2x00lib_ops rt2800
 	.kick_tx_queue		= rt2800usb_kick_tx_queue,
 	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt2800usb_fill_rxdone,
-	.config_shared_key	= rt2800usb_config_shared_key,
-	.config_pairwise_key	= rt2800usb_config_pairwise_key,
-	.config_filter		= rt2800usb_config_filter,
-	.config_intf		= rt2800usb_config_intf,
-	.config_erp		= rt2800usb_config_erp,
-	.config_ant		= rt2800usb_config_ant,
-	.config			= rt2800usb_config,
+	.config_shared_key	= rt2800_config_shared_key,
+	.config_pairwise_key	= rt2800_config_pairwise_key,
+	.config_filter		= rt2800_config_filter,
+	.config_intf		= rt2800_config_intf,
+	.config_erp		= rt2800_config_erp,
+	.config_ant		= rt2800_config_ant,
+	.config			= rt2800_config,
 };
 
 static const struct data_queue_desc rt2800usb_queue_rx = {
 	.entry_num		= RX_ENTRIES,
 	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= RXD_DESC_SIZE + RXWI_DESC_SIZE,
+	.desc_size		= RXINFO_DESC_SIZE + RXWI_DESC_SIZE,
 	.priv_size		= sizeof(struct queue_entry_priv_usb),
 };
 
@@ -2852,19 +790,20 @@ static const struct data_queue_desc rt28
 };
 
 static const struct rt2x00_ops rt2800usb_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 8,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt2800usb_queue_rx,
-	.tx		= &rt2800usb_queue_tx,
-	.bcn		= &rt2800usb_queue_bcn,
-	.lib		= &rt2800usb_rt2x00_ops,
-	.hw		= &rt2800usb_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.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,
+	.hw			= &rt2800_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt2800usb_rt2x00debug,
+	.debugfs		= &rt2800_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
@@ -2886,17 +825,23 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Amit */
 	{ USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Askey */
+	{ USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* ASUS */
 	{ USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* AzureWave */
 	{ USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Belkin */
 	{ USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2905,6 +850,8 @@ static struct usb_device_id rt2800usb_de
 	/* Buffalo */
 	{ USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Cisco */
+	{ USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Conceptronic */
 	{ USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2920,6 +867,8 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* D-Link */
@@ -2931,18 +880,24 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Edimax */
 	{ USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Encore */
 	{ USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* EnGenius */
 	{ USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Gemtek */
 	{ USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2956,7 +911,10 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* I-O DATA */
+	{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* LevelOne */
 	{ USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2964,6 +922,7 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Logitec */
 	{ USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2971,8 +930,18 @@ static struct usb_device_id rt2800usb_de
 	/* Motorola */
 	{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* MSI */
+	{ USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Ovislink */
 	{ USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+	/* Para */
+	{ USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Pegatron */
 	{ USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2988,8 +957,6 @@ static struct usb_device_id rt2800usb_de
 	/* Quanta */
 	{ USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Ralink */
-	{ USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3013,7 +980,12 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* SMC */
 	{ USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3022,6 +994,8 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Sparklan */
@@ -3039,6 +1013,7 @@ static struct usb_device_id rt2800usb_de
 	{ USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
 	{ USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
 	/* Zyxel */
 	{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h	2013-05-03 14:03:37.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2800usb.h	2013-05-03 12:11:16.000000000 -0400
@@ -1,5 +1,9 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+	Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -28,288 +32,10 @@
 #define RT2800USB_H
 
 /*
- * RF chip defines.
- *
- * RF2820 2.4G 2T3R
- * RF2850 2.4G/5G 2T3R
- * RF2720 2.4G 1T2R
- * RF2750 2.4G/5G 1T2R
- * RF3020 2.4G 1T1R
- * RF2020 2.4G B/G
- * RF3021 2.4G 1T2R
- * RF3022 2.4G 2T2R
- * RF3052 2.4G 2T2R
- */
-#define RF2820				0x0001
-#define RF2850				0x0002
-#define RF2720				0x0003
-#define RF2750				0x0004
-#define RF3020				0x0005
-#define RF2020				0x0006
-#define RF3021				0x0007
-#define RF3022				0x0008
-#define RF3052				0x0009
-
-/*
- * RT2870 version
- */
-#define RT2860C_VERSION			0x28600100
-#define RT2860D_VERSION			0x28600101
-#define RT2880E_VERSION			0x28720200
-#define RT2883_VERSION			0x28830300
-#define RT3070_VERSION			0x30700200
-
-/*
- * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
- */
-#define DEFAULT_RSSI_OFFSET		120 /* FIXME */
-
-/*
- * Register layout information.
- */
-#define CSR_REG_BASE			0x1000
-#define CSR_REG_SIZE			0x0800
-#define EEPROM_BASE			0x0000
-#define EEPROM_SIZE			0x0110
-#define BBP_BASE			0x0000
-#define BBP_SIZE			0x0080
-#define RF_BASE				0x0004
-#define RF_SIZE				0x0010
-
-/*
- * Number of TX queues.
- */
-#define NUM_TX_QUEUES			4
-
-/*
  * USB registers.
  */
 
 /*
- * HOST-MCU shared memory
- */
-#define HOST_CMD_CSR			0x0404
-#define HOST_CMD_CSR_HOST_COMMAND	FIELD32(0x000000ff)
-
-/*
- * INT_SOURCE_CSR: Interrupt source register.
- * Write one to clear corresponding bit.
- * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
- */
-#define INT_SOURCE_CSR			0x0200
-#define INT_SOURCE_CSR_RXDELAYINT	FIELD32(0x00000001)
-#define INT_SOURCE_CSR_TXDELAYINT	FIELD32(0x00000002)
-#define INT_SOURCE_CSR_RX_DONE		FIELD32(0x00000004)
-#define INT_SOURCE_CSR_AC0_DMA_DONE	FIELD32(0x00000008)
-#define INT_SOURCE_CSR_AC1_DMA_DONE	FIELD32(0x00000010)
-#define INT_SOURCE_CSR_AC2_DMA_DONE	FIELD32(0x00000020)
-#define INT_SOURCE_CSR_AC3_DMA_DONE	FIELD32(0x00000040)
-#define INT_SOURCE_CSR_HCCA_DMA_DONE	FIELD32(0x00000080)
-#define INT_SOURCE_CSR_MGMT_DMA_DONE	FIELD32(0x00000100)
-#define INT_SOURCE_CSR_MCU_COMMAND	FIELD32(0x00000200)
-#define INT_SOURCE_CSR_RXTX_COHERENT	FIELD32(0x00000400)
-#define INT_SOURCE_CSR_TBTT		FIELD32(0x00000800)
-#define INT_SOURCE_CSR_PRE_TBTT		FIELD32(0x00001000)
-#define INT_SOURCE_CSR_TX_FIFO_STATUS	FIELD32(0x00002000)
-#define INT_SOURCE_CSR_AUTO_WAKEUP	FIELD32(0x00004000)
-#define INT_SOURCE_CSR_GPTIMER		FIELD32(0x00008000)
-#define INT_SOURCE_CSR_RX_COHERENT	FIELD32(0x00010000)
-#define INT_SOURCE_CSR_TX_COHERENT	FIELD32(0x00020000)
-
-/*
- * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF.
- */
-#define INT_MASK_CSR			0x0204
-#define INT_MASK_CSR_RXDELAYINT		FIELD32(0x00000001)
-#define INT_MASK_CSR_TXDELAYINT		FIELD32(0x00000002)
-#define INT_MASK_CSR_RX_DONE		FIELD32(0x00000004)
-#define INT_MASK_CSR_AC0_DMA_DONE	FIELD32(0x00000008)
-#define INT_MASK_CSR_AC1_DMA_DONE	FIELD32(0x00000010)
-#define INT_MASK_CSR_AC2_DMA_DONE	FIELD32(0x00000020)
-#define INT_MASK_CSR_AC3_DMA_DONE	FIELD32(0x00000040)
-#define INT_MASK_CSR_HCCA_DMA_DONE	FIELD32(0x00000080)
-#define INT_MASK_CSR_MGMT_DMA_DONE	FIELD32(0x00000100)
-#define INT_MASK_CSR_MCU_COMMAND	FIELD32(0x00000200)
-#define INT_MASK_CSR_RXTX_COHERENT	FIELD32(0x00000400)
-#define INT_MASK_CSR_TBTT		FIELD32(0x00000800)
-#define INT_MASK_CSR_PRE_TBTT		FIELD32(0x00001000)
-#define INT_MASK_CSR_TX_FIFO_STATUS	FIELD32(0x00002000)
-#define INT_MASK_CSR_AUTO_WAKEUP	FIELD32(0x00004000)
-#define INT_MASK_CSR_GPTIMER		FIELD32(0x00008000)
-#define INT_MASK_CSR_RX_COHERENT	FIELD32(0x00010000)
-#define INT_MASK_CSR_TX_COHERENT	FIELD32(0x00020000)
-
-/*
- * WPDMA_GLO_CFG
- */
-#define WPDMA_GLO_CFG 			0x0208
-#define WPDMA_GLO_CFG_ENABLE_TX_DMA	FIELD32(0x00000001)
-#define WPDMA_GLO_CFG_TX_DMA_BUSY    	FIELD32(0x00000002)
-#define WPDMA_GLO_CFG_ENABLE_RX_DMA	FIELD32(0x00000004)
-#define WPDMA_GLO_CFG_RX_DMA_BUSY	FIELD32(0x00000008)
-#define WPDMA_GLO_CFG_WP_DMA_BURST_SIZE	FIELD32(0x00000030)
-#define WPDMA_GLO_CFG_TX_WRITEBACK_DONE	FIELD32(0x00000040)
-#define WPDMA_GLO_CFG_BIG_ENDIAN	FIELD32(0x00000080)
-#define WPDMA_GLO_CFG_RX_HDR_SCATTER	FIELD32(0x0000ff00)
-#define WPDMA_GLO_CFG_HDR_SEG_LEN	FIELD32(0xffff0000)
-
-/*
- * WPDMA_RST_IDX
- */
-#define WPDMA_RST_IDX 			0x020c
-#define WPDMA_RST_IDX_DTX_IDX0		FIELD32(0x00000001)
-#define WPDMA_RST_IDX_DTX_IDX1		FIELD32(0x00000002)
-#define WPDMA_RST_IDX_DTX_IDX2		FIELD32(0x00000004)
-#define WPDMA_RST_IDX_DTX_IDX3		FIELD32(0x00000008)
-#define WPDMA_RST_IDX_DTX_IDX4		FIELD32(0x00000010)
-#define WPDMA_RST_IDX_DTX_IDX5		FIELD32(0x00000020)
-#define WPDMA_RST_IDX_DRX_IDX0		FIELD32(0x00010000)
-
-/*
- * DELAY_INT_CFG
- */
-#define DELAY_INT_CFG			0x0210
-#define DELAY_INT_CFG_RXMAX_PTIME	FIELD32(0x000000ff)
-#define DELAY_INT_CFG_RXMAX_PINT	FIELD32(0x00007f00)
-#define DELAY_INT_CFG_RXDLY_INT_EN	FIELD32(0x00008000)
-#define DELAY_INT_CFG_TXMAX_PTIME	FIELD32(0x00ff0000)
-#define DELAY_INT_CFG_TXMAX_PINT	FIELD32(0x7f000000)
-#define DELAY_INT_CFG_TXDLY_INT_EN	FIELD32(0x80000000)
-
-/*
- * WMM_AIFSN_CFG: Aifsn for each EDCA AC
- * AIFSN0: AC_BE
- * AIFSN1: AC_BK
- * AIFSN1: AC_VI
- * AIFSN1: AC_VO
- */
-#define WMM_AIFSN_CFG			0x0214
-#define WMM_AIFSN_CFG_AIFSN0		FIELD32(0x0000000f)
-#define WMM_AIFSN_CFG_AIFSN1		FIELD32(0x000000f0)
-#define WMM_AIFSN_CFG_AIFSN2		FIELD32(0x00000f00)
-#define WMM_AIFSN_CFG_AIFSN3		FIELD32(0x0000f000)
-
-/*
- * WMM_CWMIN_CSR: CWmin for each EDCA AC
- * CWMIN0: AC_BE
- * CWMIN1: AC_BK
- * CWMIN1: AC_VI
- * CWMIN1: AC_VO
- */
-#define WMM_CWMIN_CFG			0x0218
-#define WMM_CWMIN_CFG_CWMIN0		FIELD32(0x0000000f)
-#define WMM_CWMIN_CFG_CWMIN1		FIELD32(0x000000f0)
-#define WMM_CWMIN_CFG_CWMIN2		FIELD32(0x00000f00)
-#define WMM_CWMIN_CFG_CWMIN3		FIELD32(0x0000f000)
-
-/*
- * WMM_CWMAX_CSR: CWmax for each EDCA AC
- * CWMAX0: AC_BE
- * CWMAX1: AC_BK
- * CWMAX1: AC_VI
- * CWMAX1: AC_VO
- */
-#define WMM_CWMAX_CFG			0x021c
-#define WMM_CWMAX_CFG_CWMAX0		FIELD32(0x0000000f)
-#define WMM_CWMAX_CFG_CWMAX1		FIELD32(0x000000f0)
-#define WMM_CWMAX_CFG_CWMAX2		FIELD32(0x00000f00)
-#define WMM_CWMAX_CFG_CWMAX3		FIELD32(0x0000f000)
-
-/*
- * AC_TXOP0: AC_BK/AC_BE TXOP register
- * AC0TXOP: AC_BK in unit of 32us
- * AC1TXOP: AC_BE in unit of 32us
- */
-#define WMM_TXOP0_CFG			0x0220
-#define WMM_TXOP0_CFG_AC0TXOP		FIELD32(0x0000ffff)
-#define WMM_TXOP0_CFG_AC1TXOP		FIELD32(0xffff0000)
-
-/*
- * AC_TXOP1: AC_VO/AC_VI TXOP register
- * AC2TXOP: AC_VI in unit of 32us
- * AC3TXOP: AC_VO in unit of 32us
- */
-#define WMM_TXOP1_CFG			0x0224
-#define WMM_TXOP1_CFG_AC2TXOP		FIELD32(0x0000ffff)
-#define WMM_TXOP1_CFG_AC3TXOP		FIELD32(0xffff0000)
-
-/*
- * GPIO_CTRL_CFG:
- */
-#define GPIO_CTRL_CFG			0x0228
-#define GPIO_CTRL_CFG_BIT0		FIELD32(0x00000001)
-#define GPIO_CTRL_CFG_BIT1		FIELD32(0x00000002)
-#define GPIO_CTRL_CFG_BIT2		FIELD32(0x00000004)
-#define GPIO_CTRL_CFG_BIT3		FIELD32(0x00000008)
-#define GPIO_CTRL_CFG_BIT4		FIELD32(0x00000010)
-#define GPIO_CTRL_CFG_BIT5		FIELD32(0x00000020)
-#define GPIO_CTRL_CFG_BIT6		FIELD32(0x00000040)
-#define GPIO_CTRL_CFG_BIT7		FIELD32(0x00000080)
-#define GPIO_CTRL_CFG_BIT8		FIELD32(0x00000100)
-
-/*
- * MCU_CMD_CFG
- */
-#define MCU_CMD_CFG			0x022c
-
-/*
- * AC_BK register offsets
- */
-#define TX_BASE_PTR0			0x0230
-#define TX_MAX_CNT0			0x0234
-#define TX_CTX_IDX0			0x0238
-#define TX_DTX_IDX0			0x023c
-
-/*
- * AC_BE register offsets
- */
-#define TX_BASE_PTR1			0x0240
-#define TX_MAX_CNT1			0x0244
-#define TX_CTX_IDX1			0x0248
-#define TX_DTX_IDX1			0x024c
-
-/*
- * AC_VI register offsets
- */
-#define TX_BASE_PTR2			0x0250
-#define TX_MAX_CNT2			0x0254
-#define TX_CTX_IDX2			0x0258
-#define TX_DTX_IDX2			0x025c
-
-/*
- * AC_VO register offsets
- */
-#define TX_BASE_PTR3			0x0260
-#define TX_MAX_CNT3			0x0264
-#define TX_CTX_IDX3			0x0268
-#define TX_DTX_IDX3			0x026c
-
-/*
- * HCCA register offsets
- */
-#define TX_BASE_PTR4			0x0270
-#define TX_MAX_CNT4			0x0274
-#define TX_CTX_IDX4			0x0278
-#define TX_DTX_IDX4			0x027c
-
-/*
- * MGMT register offsets
- */
-#define TX_BASE_PTR5			0x0280
-#define TX_MAX_CNT5			0x0284
-#define TX_CTX_IDX5			0x0288
-#define TX_DTX_IDX5			0x028c
-
-/*
- * RX register offsets
- */
-#define RX_BASE_PTR			0x0290
-#define RX_MAX_CNT			0x0294
-#define RX_CRX_IDX			0x0298
-#define RX_DRX_IDX			0x029c
-
-/*
  * USB_DMA_CFG
  * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
  * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
@@ -343,1448 +69,16 @@
 #define USB_CYC_CFG_CLOCK_CYCLE		FIELD32(0x000000ff)
 
 /*
- * PBF_SYS_CTRL
- * HOST_RAM_WRITE: enable Host program ram write selection
- */
-#define PBF_SYS_CTRL			0x0400
-#define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
-#define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
-
-/*
- * PBF registers
- * Most are for debug. Driver doesn't touch PBF register.
- */
-#define PBF_CFG				0x0408
-#define PBF_MAX_PCNT			0x040c
-#define PBF_CTRL			0x0410
-#define PBF_INT_STA			0x0414
-#define PBF_INT_ENA			0x0418
-
-/*
- * BCN_OFFSET0:
- */
-#define BCN_OFFSET0			0x042c
-#define BCN_OFFSET0_BCN0		FIELD32(0x000000ff)
-#define BCN_OFFSET0_BCN1		FIELD32(0x0000ff00)
-#define BCN_OFFSET0_BCN2		FIELD32(0x00ff0000)
-#define BCN_OFFSET0_BCN3		FIELD32(0xff000000)
-
-/*
- * BCN_OFFSET1:
- */
-#define BCN_OFFSET1			0x0430
-#define BCN_OFFSET1_BCN4		FIELD32(0x000000ff)
-#define BCN_OFFSET1_BCN5		FIELD32(0x0000ff00)
-#define BCN_OFFSET1_BCN6		FIELD32(0x00ff0000)
-#define BCN_OFFSET1_BCN7		FIELD32(0xff000000)
-
-/*
- * PBF registers
- * Most are for debug. Driver doesn't touch PBF register.
- */
-#define TXRXQ_PCNT			0x0438
-#define PBF_DBG				0x043c
-
-/*
- * RF registers
- */
-#define	RF_CSR_CFG			0x0500
-#define RF_CSR_CFG_DATA			FIELD32(0x000000ff)
-#define RF_CSR_CFG_REGNUM		FIELD32(0x00001f00)
-#define RF_CSR_CFG_WRITE		FIELD32(0x00010000)
-#define RF_CSR_CFG_BUSY			FIELD32(0x00020000)
-
-/*
- * MAC Control/Status Registers(CSR).
- * Some values are set in TU, whereas 1 TU == 1024 us.
- */
-
-/*
- * MAC_CSR0: ASIC revision number.
- * ASIC_REV: 0
- * ASIC_VER: 2870
- */
-#define MAC_CSR0			0x1000
-#define MAC_CSR0_ASIC_REV		FIELD32(0x0000ffff)
-#define MAC_CSR0_ASIC_VER		FIELD32(0xffff0000)
-
-/*
- * MAC_SYS_CTRL:
- */
-#define MAC_SYS_CTRL			0x1004
-#define MAC_SYS_CTRL_RESET_CSR		FIELD32(0x00000001)
-#define MAC_SYS_CTRL_RESET_BBP		FIELD32(0x00000002)
-#define MAC_SYS_CTRL_ENABLE_TX		FIELD32(0x00000004)
-#define MAC_SYS_CTRL_ENABLE_RX		FIELD32(0x00000008)
-#define MAC_SYS_CTRL_CONTINUOUS_TX	FIELD32(0x00000010)
-#define MAC_SYS_CTRL_LOOPBACK		FIELD32(0x00000020)
-#define MAC_SYS_CTRL_WLAN_HALT		FIELD32(0x00000040)
-#define MAC_SYS_CTRL_RX_TIMESTAMP	FIELD32(0x00000080)
-
-/*
- * MAC_ADDR_DW0: STA MAC register 0
- */
-#define MAC_ADDR_DW0			0x1008
-#define MAC_ADDR_DW0_BYTE0		FIELD32(0x000000ff)
-#define MAC_ADDR_DW0_BYTE1		FIELD32(0x0000ff00)
-#define MAC_ADDR_DW0_BYTE2		FIELD32(0x00ff0000)
-#define MAC_ADDR_DW0_BYTE3		FIELD32(0xff000000)
-
-/*
- * MAC_ADDR_DW1: STA MAC register 1
- * UNICAST_TO_ME_MASK:
- * Used to mask off bits from byte 5 of the MAC address
- * to determine the UNICAST_TO_ME bit for RX frames.
- * The full mask is complemented by BSS_ID_MASK:
- *    MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK
- */
-#define MAC_ADDR_DW1			0x100c
-#define MAC_ADDR_DW1_BYTE4		FIELD32(0x000000ff)
-#define MAC_ADDR_DW1_BYTE5		FIELD32(0x0000ff00)
-#define MAC_ADDR_DW1_UNICAST_TO_ME_MASK	FIELD32(0x00ff0000)
-
-/*
- * MAC_BSSID_DW0: BSSID register 0
- */
-#define MAC_BSSID_DW0			0x1010
-#define MAC_BSSID_DW0_BYTE0		FIELD32(0x000000ff)
-#define MAC_BSSID_DW0_BYTE1		FIELD32(0x0000ff00)
-#define MAC_BSSID_DW0_BYTE2		FIELD32(0x00ff0000)
-#define MAC_BSSID_DW0_BYTE3		FIELD32(0xff000000)
-
-/*
- * MAC_BSSID_DW1: BSSID register 1
- * BSS_ID_MASK:
- *     0: 1-BSSID mode (BSS index = 0)
- *     1: 2-BSSID mode (BSS index: Byte5, bit 0)
- *     2: 4-BSSID mode (BSS index: byte5, bit 0 - 1)
- *     3: 8-BSSID mode (BSS index: byte5, bit 0 - 2)
- * This mask is used to mask off bits 0, 1 and 2 of byte 5 of the
- * BSSID. This will make sure that those bits will be ignored
- * when determining the MY_BSS of RX frames.
- */
-#define MAC_BSSID_DW1			0x1014
-#define MAC_BSSID_DW1_BYTE4		FIELD32(0x000000ff)
-#define MAC_BSSID_DW1_BYTE5		FIELD32(0x0000ff00)
-#define MAC_BSSID_DW1_BSS_ID_MASK	FIELD32(0x00030000)
-#define MAC_BSSID_DW1_BSS_BCN_NUM	FIELD32(0x001c0000)
-
-/*
- * MAX_LEN_CFG: Maximum frame length register.
- * MAX_MPDU: rt2860b max 16k bytes
- * MAX_PSDU: Maximum PSDU length
- *	(power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
- */
-#define MAX_LEN_CFG			0x1018
-#define MAX_LEN_CFG_MAX_MPDU		FIELD32(0x00000fff)
-#define MAX_LEN_CFG_MAX_PSDU		FIELD32(0x00003000)
-#define MAX_LEN_CFG_MIN_PSDU		FIELD32(0x0000c000)
-#define MAX_LEN_CFG_MIN_MPDU		FIELD32(0x000f0000)
-
-/*
- * BBP_CSR_CFG: BBP serial control register
- * VALUE: Register value to program into BBP
- * REG_NUM: Selected BBP register
- * READ_CONTROL: 0 write BBP, 1 read BBP
- * BUSY: ASIC is busy executing BBP commands
- * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks
- * BBP_RW_MODE: 0 serial, 1 paralell
- */
-#define BBP_CSR_CFG			0x101c
-#define BBP_CSR_CFG_VALUE		FIELD32(0x000000ff)
-#define BBP_CSR_CFG_REGNUM		FIELD32(0x0000ff00)
-#define BBP_CSR_CFG_READ_CONTROL	FIELD32(0x00010000)
-#define BBP_CSR_CFG_BUSY		FIELD32(0x00020000)
-#define BBP_CSR_CFG_BBP_PAR_DUR		FIELD32(0x00040000)
-#define BBP_CSR_CFG_BBP_RW_MODE		FIELD32(0x00080000)
-
-/*
- * RF_CSR_CFG0: RF control register
- * REGID_AND_VALUE: Register value to program into RF
- * BITWIDTH: Selected RF register
- * STANDBYMODE: 0 high when standby, 1 low when standby
- * SEL: 0 RF_LE0 activate, 1 RF_LE1 activate
- * BUSY: ASIC is busy executing RF commands
- */
-#define RF_CSR_CFG0			0x1020
-#define RF_CSR_CFG0_REGID_AND_VALUE	FIELD32(0x00ffffff)
-#define RF_CSR_CFG0_BITWIDTH		FIELD32(0x1f000000)
-#define RF_CSR_CFG0_REG_VALUE_BW	FIELD32(0x1fffffff)
-#define RF_CSR_CFG0_STANDBYMODE		FIELD32(0x20000000)
-#define RF_CSR_CFG0_SEL			FIELD32(0x40000000)
-#define RF_CSR_CFG0_BUSY		FIELD32(0x80000000)
-
-/*
- * RF_CSR_CFG1: RF control register
- * REGID_AND_VALUE: Register value to program into RF
- * RFGAP: Gap between BB_CONTROL_RF and RF_LE
- *        0: 3 system clock cycle (37.5usec)
- *        1: 5 system clock cycle (62.5usec)
- */
-#define RF_CSR_CFG1			0x1024
-#define RF_CSR_CFG1_REGID_AND_VALUE	FIELD32(0x00ffffff)
-#define RF_CSR_CFG1_RFGAP		FIELD32(0x1f000000)
-
-/*
- * RF_CSR_CFG2: RF control register
- * VALUE: Register value to program into RF
- * RFGAP: Gap between BB_CONTROL_RF and RF_LE
- *        0: 3 system clock cycle (37.5usec)
- *        1: 5 system clock cycle (62.5usec)
- */
-#define RF_CSR_CFG2			0x1028
-#define RF_CSR_CFG2_VALUE		FIELD32(0x00ffffff)
-
-/*
- * LED_CFG: LED control
- * color LED's:
- *   0: off
- *   1: blinking upon TX2
- *   2: periodic slow blinking
- *   3: always on
- * LED polarity:
- *   0: active low
- *   1: active high
- */
-#define LED_CFG				0x102c
-#define LED_CFG_ON_PERIOD		FIELD32(0x000000ff)
-#define LED_CFG_OFF_PERIOD		FIELD32(0x0000ff00)
-#define LED_CFG_SLOW_BLINK_PERIOD	FIELD32(0x003f0000)
-#define LED_CFG_R_LED_MODE		FIELD32(0x03000000)
-#define LED_CFG_G_LED_MODE		FIELD32(0x0c000000)
-#define LED_CFG_Y_LED_MODE		FIELD32(0x30000000)
-#define LED_CFG_LED_POLAR		FIELD32(0x40000000)
-
-/*
- * XIFS_TIME_CFG: MAC timing
- * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
- * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
- * OFDM_XIFS_TIME: unit 1us. Applied after OFDM RX
- *	when MAC doesn't reference BBP signal BBRXEND
- * EIFS: unit 1us
- * BB_RXEND_ENABLE: reference RXEND signal to begin XIFS defer
- *
- */
-#define XIFS_TIME_CFG			0x1100
-#define XIFS_TIME_CFG_CCKM_SIFS_TIME	FIELD32(0x000000ff)
-#define XIFS_TIME_CFG_OFDM_SIFS_TIME	FIELD32(0x0000ff00)
-#define XIFS_TIME_CFG_OFDM_XIFS_TIME	FIELD32(0x000f0000)
-#define XIFS_TIME_CFG_EIFS		FIELD32(0x1ff00000)
-#define XIFS_TIME_CFG_BB_RXEND_ENABLE	FIELD32(0x20000000)
-
-/*
- * BKOFF_SLOT_CFG:
- */
-#define BKOFF_SLOT_CFG			0x1104
-#define BKOFF_SLOT_CFG_SLOT_TIME	FIELD32(0x000000ff)
-#define BKOFF_SLOT_CFG_CC_DELAY_TIME	FIELD32(0x0000ff00)
-
-/*
- * NAV_TIME_CFG:
- */
-#define NAV_TIME_CFG			0x1108
-#define NAV_TIME_CFG_SIFS		FIELD32(0x000000ff)
-#define NAV_TIME_CFG_SLOT_TIME		FIELD32(0x0000ff00)
-#define NAV_TIME_CFG_EIFS		FIELD32(0x01ff0000)
-#define NAV_TIME_ZERO_SIFS		FIELD32(0x02000000)
-
-/*
- * CH_TIME_CFG: count as channel busy
- */
-#define CH_TIME_CFG     	        0x110c
-
-/*
- * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
- */
-#define PBF_LIFE_TIMER     	        0x1110
-
-/*
- * BCN_TIME_CFG:
- * BEACON_INTERVAL: in unit of 1/16 TU
- * TSF_TICKING: Enable TSF auto counting
- * TSF_SYNC: Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
- * BEACON_GEN: Enable beacon generator
- */
-#define BCN_TIME_CFG			0x1114
-#define BCN_TIME_CFG_BEACON_INTERVAL	FIELD32(0x0000ffff)
-#define BCN_TIME_CFG_TSF_TICKING	FIELD32(0x00010000)
-#define BCN_TIME_CFG_TSF_SYNC		FIELD32(0x00060000)
-#define BCN_TIME_CFG_TBTT_ENABLE	FIELD32(0x00080000)
-#define BCN_TIME_CFG_BEACON_GEN		FIELD32(0x00100000)
-#define BCN_TIME_CFG_TX_TIME_COMPENSATE	FIELD32(0xf0000000)
-
-/*
- * TBTT_SYNC_CFG:
- */
-#define TBTT_SYNC_CFG			0x1118
-
-/*
- * TSF_TIMER_DW0: Local lsb TSF timer, read-only
- */
-#define TSF_TIMER_DW0			0x111c
-#define TSF_TIMER_DW0_LOW_WORD		FIELD32(0xffffffff)
-
-/*
- * TSF_TIMER_DW1: Local msb TSF timer, read-only
- */
-#define TSF_TIMER_DW1			0x1120
-#define TSF_TIMER_DW1_HIGH_WORD		FIELD32(0xffffffff)
-
-/*
- * TBTT_TIMER: TImer remains till next TBTT, read-only
- */
-#define TBTT_TIMER			0x1124
-
-/*
- * INT_TIMER_CFG:
- */
-#define INT_TIMER_CFG			0x1128
-
-/*
- * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
- */
-#define INT_TIMER_EN			0x112c
-
-/*
- * CH_IDLE_STA: channel idle time
- */
-#define CH_IDLE_STA			0x1130
-
-/*
- * CH_BUSY_STA: channel busy time
- */
-#define CH_BUSY_STA			0x1134
-
-/*
- * MAC_STATUS_CFG:
- * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
- *	if 1 or higher one of the 2 registers is busy.
- */
-#define MAC_STATUS_CFG			0x1200
-#define MAC_STATUS_CFG_BBP_RF_BUSY	FIELD32(0x00000003)
-
-/*
- * PWR_PIN_CFG:
- */
-#define PWR_PIN_CFG			0x1204
-
-/*
- * AUTOWAKEUP_CFG: Manual power control / status register
- * TBCN_BEFORE_WAKE: ForceWake has high privilege than PutToSleep when both set
- * AUTOWAKE: 0:sleep, 1:awake
- */
-#define AUTOWAKEUP_CFG			0x1208
-#define AUTOWAKEUP_CFG_AUTO_LEAD_TIME	FIELD32(0x000000ff)
-#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE	FIELD32(0x00007f00)
-#define AUTOWAKEUP_CFG_AUTOWAKE		FIELD32(0x00008000)
-
-/*
- * EDCA_AC0_CFG:
- */
-#define EDCA_AC0_CFG			0x1300
-#define EDCA_AC0_CFG_TX_OP		FIELD32(0x000000ff)
-#define EDCA_AC0_CFG_AIFSN		FIELD32(0x00000f00)
-#define EDCA_AC0_CFG_CWMIN		FIELD32(0x0000f000)
-#define EDCA_AC0_CFG_CWMAX		FIELD32(0x000f0000)
-
-/*
- * EDCA_AC1_CFG:
- */
-#define EDCA_AC1_CFG			0x1304
-#define EDCA_AC1_CFG_TX_OP		FIELD32(0x000000ff)
-#define EDCA_AC1_CFG_AIFSN		FIELD32(0x00000f00)
-#define EDCA_AC1_CFG_CWMIN		FIELD32(0x0000f000)
-#define EDCA_AC1_CFG_CWMAX		FIELD32(0x000f0000)
-
-/*
- * EDCA_AC2_CFG:
- */
-#define EDCA_AC2_CFG			0x1308
-#define EDCA_AC2_CFG_TX_OP		FIELD32(0x000000ff)
-#define EDCA_AC2_CFG_AIFSN		FIELD32(0x00000f00)
-#define EDCA_AC2_CFG_CWMIN		FIELD32(0x0000f000)
-#define EDCA_AC2_CFG_CWMAX		FIELD32(0x000f0000)
-
-/*
- * EDCA_AC3_CFG:
- */
-#define EDCA_AC3_CFG			0x130c
-#define EDCA_AC3_CFG_TX_OP		FIELD32(0x000000ff)
-#define EDCA_AC3_CFG_AIFSN		FIELD32(0x00000f00)
-#define EDCA_AC3_CFG_CWMIN		FIELD32(0x0000f000)
-#define EDCA_AC3_CFG_CWMAX		FIELD32(0x000f0000)
-
-/*
- * EDCA_TID_AC_MAP:
- */
-#define EDCA_TID_AC_MAP			0x1310
-
-/*
- * TX_PWR_CFG_0:
- */
-#define TX_PWR_CFG_0			0x1314
-#define TX_PWR_CFG_0_1MBS		FIELD32(0x0000000f)
-#define TX_PWR_CFG_0_2MBS		FIELD32(0x000000f0)
-#define TX_PWR_CFG_0_55MBS		FIELD32(0x00000f00)
-#define TX_PWR_CFG_0_11MBS		FIELD32(0x0000f000)
-#define TX_PWR_CFG_0_6MBS		FIELD32(0x000f0000)
-#define TX_PWR_CFG_0_9MBS		FIELD32(0x00f00000)
-#define TX_PWR_CFG_0_12MBS		FIELD32(0x0f000000)
-#define TX_PWR_CFG_0_18MBS		FIELD32(0xf0000000)
-
-/*
- * TX_PWR_CFG_1:
- */
-#define TX_PWR_CFG_1			0x1318
-#define TX_PWR_CFG_1_24MBS		FIELD32(0x0000000f)
-#define TX_PWR_CFG_1_36MBS		FIELD32(0x000000f0)
-#define TX_PWR_CFG_1_48MBS		FIELD32(0x00000f00)
-#define TX_PWR_CFG_1_54MBS		FIELD32(0x0000f000)
-#define TX_PWR_CFG_1_MCS0		FIELD32(0x000f0000)
-#define TX_PWR_CFG_1_MCS1		FIELD32(0x00f00000)
-#define TX_PWR_CFG_1_MCS2		FIELD32(0x0f000000)
-#define TX_PWR_CFG_1_MCS3		FIELD32(0xf0000000)
-
-/*
- * TX_PWR_CFG_2:
- */
-#define TX_PWR_CFG_2			0x131c
-#define TX_PWR_CFG_2_MCS4		FIELD32(0x0000000f)
-#define TX_PWR_CFG_2_MCS5		FIELD32(0x000000f0)
-#define TX_PWR_CFG_2_MCS6		FIELD32(0x00000f00)
-#define TX_PWR_CFG_2_MCS7		FIELD32(0x0000f000)
-#define TX_PWR_CFG_2_MCS8		FIELD32(0x000f0000)
-#define TX_PWR_CFG_2_MCS9		FIELD32(0x00f00000)
-#define TX_PWR_CFG_2_MCS10		FIELD32(0x0f000000)
-#define TX_PWR_CFG_2_MCS11		FIELD32(0xf0000000)
-
-/*
- * TX_PWR_CFG_3:
- */
-#define TX_PWR_CFG_3			0x1320
-#define TX_PWR_CFG_3_MCS12		FIELD32(0x0000000f)
-#define TX_PWR_CFG_3_MCS13		FIELD32(0x000000f0)
-#define TX_PWR_CFG_3_MCS14		FIELD32(0x00000f00)
-#define TX_PWR_CFG_3_MCS15		FIELD32(0x0000f000)
-#define TX_PWR_CFG_3_UKNOWN1		FIELD32(0x000f0000)
-#define TX_PWR_CFG_3_UKNOWN2		FIELD32(0x00f00000)
-#define TX_PWR_CFG_3_UKNOWN3		FIELD32(0x0f000000)
-#define TX_PWR_CFG_3_UKNOWN4		FIELD32(0xf0000000)
-
-/*
- * TX_PWR_CFG_4:
- */
-#define TX_PWR_CFG_4			0x1324
-#define TX_PWR_CFG_4_UKNOWN5		FIELD32(0x0000000f)
-#define TX_PWR_CFG_4_UKNOWN6		FIELD32(0x000000f0)
-#define TX_PWR_CFG_4_UKNOWN7		FIELD32(0x00000f00)
-#define TX_PWR_CFG_4_UKNOWN8		FIELD32(0x0000f000)
-
-/*
- * TX_PIN_CFG:
- */
-#define TX_PIN_CFG			0x1328
-#define TX_PIN_CFG_PA_PE_A0_EN		FIELD32(0x00000001)
-#define TX_PIN_CFG_PA_PE_G0_EN		FIELD32(0x00000002)
-#define TX_PIN_CFG_PA_PE_A1_EN		FIELD32(0x00000004)
-#define TX_PIN_CFG_PA_PE_G1_EN		FIELD32(0x00000008)
-#define TX_PIN_CFG_PA_PE_A0_POL		FIELD32(0x00000010)
-#define TX_PIN_CFG_PA_PE_G0_POL		FIELD32(0x00000020)
-#define TX_PIN_CFG_PA_PE_A1_POL		FIELD32(0x00000040)
-#define TX_PIN_CFG_PA_PE_G1_POL		FIELD32(0x00000080)
-#define TX_PIN_CFG_LNA_PE_A0_EN		FIELD32(0x00000100)
-#define TX_PIN_CFG_LNA_PE_G0_EN		FIELD32(0x00000200)
-#define TX_PIN_CFG_LNA_PE_A1_EN		FIELD32(0x00000400)
-#define TX_PIN_CFG_LNA_PE_G1_EN		FIELD32(0x00000800)
-#define TX_PIN_CFG_LNA_PE_A0_POL	FIELD32(0x00001000)
-#define TX_PIN_CFG_LNA_PE_G0_POL	FIELD32(0x00002000)
-#define TX_PIN_CFG_LNA_PE_A1_POL	FIELD32(0x00004000)
-#define TX_PIN_CFG_LNA_PE_G1_POL	FIELD32(0x00008000)
-#define TX_PIN_CFG_RFTR_EN		FIELD32(0x00010000)
-#define TX_PIN_CFG_RFTR_POL		FIELD32(0x00020000)
-#define TX_PIN_CFG_TRSW_EN		FIELD32(0x00040000)
-#define TX_PIN_CFG_TRSW_POL		FIELD32(0x00080000)
-
-/*
- * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
- */
-#define TX_BAND_CFG			0x132c
-#define TX_BAND_CFG_HT40_PLUS		FIELD32(0x00000001)
-#define TX_BAND_CFG_A			FIELD32(0x00000002)
-#define TX_BAND_CFG_BG			FIELD32(0x00000004)
-
-/*
- * TX_SW_CFG0:
- */
-#define TX_SW_CFG0			0x1330
-
-/*
- * TX_SW_CFG1:
- */
-#define TX_SW_CFG1			0x1334
-
-/*
- * TX_SW_CFG2:
- */
-#define TX_SW_CFG2			0x1338
-
-/*
- * TXOP_THRES_CFG:
- */
-#define TXOP_THRES_CFG			0x133c
-
-/*
- * TXOP_CTRL_CFG:
- */
-#define TXOP_CTRL_CFG			0x1340
-
-/*
- * TX_RTS_CFG:
- * RTS_THRES: unit:byte
- * RTS_FBK_EN: enable rts rate fallback
- */
-#define TX_RTS_CFG			0x1344
-#define TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT	FIELD32(0x000000ff)
-#define TX_RTS_CFG_RTS_THRES		FIELD32(0x00ffff00)
-#define TX_RTS_CFG_RTS_FBK_EN		FIELD32(0x01000000)
-
-/*
- * TX_TIMEOUT_CFG:
- * MPDU_LIFETIME: expiration time = 2^(9+MPDU LIFE TIME) us
- * RX_ACK_TIMEOUT: unit:slot. Used for TX procedure
- * TX_OP_TIMEOUT: TXOP timeout value for TXOP truncation.
- *                it is recommended that:
- *                (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
- */
-#define TX_TIMEOUT_CFG			0x1348
-#define TX_TIMEOUT_CFG_MPDU_LIFETIME	FIELD32(0x000000f0)
-#define TX_TIMEOUT_CFG_RX_ACK_TIMEOUT	FIELD32(0x0000ff00)
-#define TX_TIMEOUT_CFG_TX_OP_TIMEOUT	FIELD32(0x00ff0000)
-
-/*
- * TX_RTY_CFG:
- * SHORT_RTY_LIMIT: short retry limit
- * LONG_RTY_LIMIT: long retry limit
- * LONG_RTY_THRE: Long retry threshoold
- * NON_AGG_RTY_MODE: Non-Aggregate MPDU retry mode
- *                   0:expired by retry limit, 1: expired by mpdu life timer
- * AGG_RTY_MODE: Aggregate MPDU retry mode
- *               0:expired by retry limit, 1: expired by mpdu life timer
- * TX_AUTO_FB_ENABLE: Tx retry PHY rate auto fallback enable
- */
-#define TX_RTY_CFG			0x134c
-#define TX_RTY_CFG_SHORT_RTY_LIMIT	FIELD32(0x000000ff)
-#define TX_RTY_CFG_LONG_RTY_LIMIT	FIELD32(0x0000ff00)
-#define TX_RTY_CFG_LONG_RTY_THRE	FIELD32(0x0fff0000)
-#define TX_RTY_CFG_NON_AGG_RTY_MODE	FIELD32(0x10000000)
-#define TX_RTY_CFG_AGG_RTY_MODE		FIELD32(0x20000000)
-#define TX_RTY_CFG_TX_AUTO_FB_ENABLE	FIELD32(0x40000000)
-
-/*
- * TX_LINK_CFG:
- * REMOTE_MFB_LIFETIME: remote MFB life time. unit: 32us
- * MFB_ENABLE: TX apply remote MFB 1:enable
- * REMOTE_UMFS_ENABLE: remote unsolicit  MFB enable
- *                     0: not apply remote remote unsolicit (MFS=7)
- * TX_MRQ_EN: MCS request TX enable
- * TX_RDG_EN: RDG TX enable
- * TX_CF_ACK_EN: Piggyback CF-ACK enable
- * REMOTE_MFB: remote MCS feedback
- * REMOTE_MFS: remote MCS feedback sequence number
- */
-#define TX_LINK_CFG			0x1350
-#define TX_LINK_CFG_REMOTE_MFB_LIFETIME	FIELD32(0x000000ff)
-#define TX_LINK_CFG_MFB_ENABLE		FIELD32(0x00000100)
-#define TX_LINK_CFG_REMOTE_UMFS_ENABLE	FIELD32(0x00000200)
-#define TX_LINK_CFG_TX_MRQ_EN		FIELD32(0x00000400)
-#define TX_LINK_CFG_TX_RDG_EN		FIELD32(0x00000800)
-#define TX_LINK_CFG_TX_CF_ACK_EN	FIELD32(0x00001000)
-#define TX_LINK_CFG_REMOTE_MFB		FIELD32(0x00ff0000)
-#define TX_LINK_CFG_REMOTE_MFS		FIELD32(0xff000000)
-
-/*
- * HT_FBK_CFG0:
- */
-#define HT_FBK_CFG0			0x1354
-#define HT_FBK_CFG0_HTMCS0FBK		FIELD32(0x0000000f)
-#define HT_FBK_CFG0_HTMCS1FBK		FIELD32(0x000000f0)
-#define HT_FBK_CFG0_HTMCS2FBK		FIELD32(0x00000f00)
-#define HT_FBK_CFG0_HTMCS3FBK		FIELD32(0x0000f000)
-#define HT_FBK_CFG0_HTMCS4FBK		FIELD32(0x000f0000)
-#define HT_FBK_CFG0_HTMCS5FBK		FIELD32(0x00f00000)
-#define HT_FBK_CFG0_HTMCS6FBK		FIELD32(0x0f000000)
-#define HT_FBK_CFG0_HTMCS7FBK		FIELD32(0xf0000000)
-
-/*
- * HT_FBK_CFG1:
- */
-#define HT_FBK_CFG1			0x1358
-#define HT_FBK_CFG1_HTMCS8FBK		FIELD32(0x0000000f)
-#define HT_FBK_CFG1_HTMCS9FBK		FIELD32(0x000000f0)
-#define HT_FBK_CFG1_HTMCS10FBK		FIELD32(0x00000f00)
-#define HT_FBK_CFG1_HTMCS11FBK		FIELD32(0x0000f000)
-#define HT_FBK_CFG1_HTMCS12FBK		FIELD32(0x000f0000)
-#define HT_FBK_CFG1_HTMCS13FBK		FIELD32(0x00f00000)
-#define HT_FBK_CFG1_HTMCS14FBK		FIELD32(0x0f000000)
-#define HT_FBK_CFG1_HTMCS15FBK		FIELD32(0xf0000000)
-
-/*
- * LG_FBK_CFG0:
- */
-#define LG_FBK_CFG0			0x135c
-#define LG_FBK_CFG0_OFDMMCS0FBK		FIELD32(0x0000000f)
-#define LG_FBK_CFG0_OFDMMCS1FBK		FIELD32(0x000000f0)
-#define LG_FBK_CFG0_OFDMMCS2FBK		FIELD32(0x00000f00)
-#define LG_FBK_CFG0_OFDMMCS3FBK		FIELD32(0x0000f000)
-#define LG_FBK_CFG0_OFDMMCS4FBK		FIELD32(0x000f0000)
-#define LG_FBK_CFG0_OFDMMCS5FBK		FIELD32(0x00f00000)
-#define LG_FBK_CFG0_OFDMMCS6FBK		FIELD32(0x0f000000)
-#define LG_FBK_CFG0_OFDMMCS7FBK		FIELD32(0xf0000000)
-
-/*
- * LG_FBK_CFG1:
- */
-#define LG_FBK_CFG1			0x1360
-#define LG_FBK_CFG0_CCKMCS0FBK		FIELD32(0x0000000f)
-#define LG_FBK_CFG0_CCKMCS1FBK		FIELD32(0x000000f0)
-#define LG_FBK_CFG0_CCKMCS2FBK		FIELD32(0x00000f00)
-#define LG_FBK_CFG0_CCKMCS3FBK		FIELD32(0x0000f000)
-
-/*
- * CCK_PROT_CFG: CCK Protection
- * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
- * PROTECT_CTRL: Protection control frame type for CCK TX
- *               0:none, 1:RTS/CTS, 2:CTS-to-self
- * PROTECT_NAV: TXOP protection type for CCK TX
- *              0:none, 1:ShortNAVprotect, 2:LongNAVProtect
- * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
- * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
- * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
- * TX_OP_ALLOW_MM40: CCK TXOP allowance, 0:disallow
- * TX_OP_ALLOW_GF20: CCK TXOP allowance, 0:disallow
- * TX_OP_ALLOW_GF40: CCK TXOP allowance, 0:disallow
- * RTS_TH_EN: RTS threshold enable on CCK TX
- */
-#define CCK_PROT_CFG			0x1364
-#define CCK_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define CCK_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define CCK_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define CCK_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define CCK_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * OFDM_PROT_CFG: OFDM Protection
- */
-#define OFDM_PROT_CFG			0x1368
-#define OFDM_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define OFDM_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define OFDM_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define OFDM_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define OFDM_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * MM20_PROT_CFG: MM20 Protection
- */
-#define MM20_PROT_CFG			0x136c
-#define MM20_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define MM20_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define MM20_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define MM20_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define MM20_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * MM40_PROT_CFG: MM40 Protection
- */
-#define MM40_PROT_CFG			0x1370
-#define MM40_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define MM40_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define MM40_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define MM40_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define MM40_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * GF20_PROT_CFG: GF20 Protection
- */
-#define GF20_PROT_CFG			0x1374
-#define GF20_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define GF20_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define GF20_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define GF20_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define GF20_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * GF40_PROT_CFG: GF40 Protection
- */
-#define GF40_PROT_CFG			0x1378
-#define GF40_PROT_CFG_PROTECT_RATE	FIELD32(0x0000ffff)
-#define GF40_PROT_CFG_PROTECT_CTRL	FIELD32(0x00030000)
-#define GF40_PROT_CFG_PROTECT_NAV	FIELD32(0x000c0000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_CCK	FIELD32(0x00100000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM	FIELD32(0x00200000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_MM20	FIELD32(0x00400000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_MM40	FIELD32(0x00800000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_GF20	FIELD32(0x01000000)
-#define GF40_PROT_CFG_TX_OP_ALLOW_GF40	FIELD32(0x02000000)
-#define GF40_PROT_CFG_RTS_TH_EN		FIELD32(0x04000000)
-
-/*
- * EXP_CTS_TIME:
- */
-#define EXP_CTS_TIME			0x137c
-
-/*
- * EXP_ACK_TIME:
- */
-#define EXP_ACK_TIME			0x1380
-
-/*
- * RX_FILTER_CFG: RX configuration register.
- */
-#define RX_FILTER_CFG			0x1400
-#define RX_FILTER_CFG_DROP_CRC_ERROR	FIELD32(0x00000001)
-#define RX_FILTER_CFG_DROP_PHY_ERROR	FIELD32(0x00000002)
-#define RX_FILTER_CFG_DROP_NOT_TO_ME	FIELD32(0x00000004)
-#define RX_FILTER_CFG_DROP_NOT_MY_BSSD	FIELD32(0x00000008)
-#define RX_FILTER_CFG_DROP_VER_ERROR	FIELD32(0x00000010)
-#define RX_FILTER_CFG_DROP_MULTICAST	FIELD32(0x00000020)
-#define RX_FILTER_CFG_DROP_BROADCAST	FIELD32(0x00000040)
-#define RX_FILTER_CFG_DROP_DUPLICATE	FIELD32(0x00000080)
-#define RX_FILTER_CFG_DROP_CF_END_ACK	FIELD32(0x00000100)
-#define RX_FILTER_CFG_DROP_CF_END	FIELD32(0x00000200)
-#define RX_FILTER_CFG_DROP_ACK		FIELD32(0x00000400)
-#define RX_FILTER_CFG_DROP_CTS		FIELD32(0x00000800)
-#define RX_FILTER_CFG_DROP_RTS		FIELD32(0x00001000)
-#define RX_FILTER_CFG_DROP_PSPOLL	FIELD32(0x00002000)
-#define RX_FILTER_CFG_DROP_BA		FIELD32(0x00004000)
-#define RX_FILTER_CFG_DROP_BAR		FIELD32(0x00008000)
-#define RX_FILTER_CFG_DROP_CNTL		FIELD32(0x00010000)
-
-/*
- * AUTO_RSP_CFG:
- * AUTORESPONDER: 0: disable, 1: enable
- * BAC_ACK_POLICY: 0:long, 1:short preamble
- * CTS_40_MMODE: Response CTS 40MHz duplicate mode
- * CTS_40_MREF: Response CTS 40MHz duplicate mode
- * AR_PREAMBLE: Auto responder preamble 0:long, 1:short preamble
- * DUAL_CTS_EN: Power bit value in control frame
- * ACK_CTS_PSM_BIT:Power bit value in control frame
- */
-#define AUTO_RSP_CFG			0x1404
-#define AUTO_RSP_CFG_AUTORESPONDER	FIELD32(0x00000001)
-#define AUTO_RSP_CFG_BAC_ACK_POLICY	FIELD32(0x00000002)
-#define AUTO_RSP_CFG_CTS_40_MMODE	FIELD32(0x00000004)
-#define AUTO_RSP_CFG_CTS_40_MREF	FIELD32(0x00000008)
-#define AUTO_RSP_CFG_AR_PREAMBLE	FIELD32(0x00000010)
-#define AUTO_RSP_CFG_DUAL_CTS_EN	FIELD32(0x00000040)
-#define AUTO_RSP_CFG_ACK_CTS_PSM_BIT	FIELD32(0x00000080)
-
-/*
- * LEGACY_BASIC_RATE:
- */
-#define LEGACY_BASIC_RATE		0x1408
-
-/*
- * HT_BASIC_RATE:
- */
-#define HT_BASIC_RATE			0x140c
-
-/*
- * HT_CTRL_CFG:
- */
-#define HT_CTRL_CFG			0x1410
-
-/*
- * SIFS_COST_CFG:
- */
-#define SIFS_COST_CFG			0x1414
-
-/*
- * RX_PARSER_CFG:
- * Set NAV for all received frames
- */
-#define RX_PARSER_CFG			0x1418
-
-/*
- * TX_SEC_CNT0:
- */
-#define TX_SEC_CNT0			0x1500
-
-/*
- * RX_SEC_CNT0:
- */
-#define RX_SEC_CNT0			0x1504
-
-/*
- * CCMP_FC_MUTE:
- */
-#define CCMP_FC_MUTE			0x1508
-
-/*
- * TXOP_HLDR_ADDR0:
- */
-#define TXOP_HLDR_ADDR0			0x1600
-
-/*
- * TXOP_HLDR_ADDR1:
- */
-#define TXOP_HLDR_ADDR1			0x1604
-
-/*
- * TXOP_HLDR_ET:
- */
-#define TXOP_HLDR_ET			0x1608
-
-/*
- * QOS_CFPOLL_RA_DW0:
- */
-#define QOS_CFPOLL_RA_DW0		0x160c
-
-/*
- * QOS_CFPOLL_RA_DW1:
- */
-#define QOS_CFPOLL_RA_DW1		0x1610
-
-/*
- * QOS_CFPOLL_QC:
- */
-#define QOS_CFPOLL_QC			0x1614
-
-/*
- * RX_STA_CNT0: RX PLCP error count & RX CRC error count
- */
-#define RX_STA_CNT0			0x1700
-#define RX_STA_CNT0_CRC_ERR		FIELD32(0x0000ffff)
-#define RX_STA_CNT0_PHY_ERR		FIELD32(0xffff0000)
-
-/*
- * RX_STA_CNT1: RX False CCA count & RX LONG frame count
- */
-#define RX_STA_CNT1			0x1704
-#define RX_STA_CNT1_FALSE_CCA		FIELD32(0x0000ffff)
-#define RX_STA_CNT1_PLCP_ERR		FIELD32(0xffff0000)
-
-/*
- * RX_STA_CNT2:
- */
-#define RX_STA_CNT2			0x1708
-#define RX_STA_CNT2_RX_DUPLI_COUNT	FIELD32(0x0000ffff)
-#define RX_STA_CNT2_RX_FIFO_OVERFLOW	FIELD32(0xffff0000)
-
-/*
- * TX_STA_CNT0: TX Beacon count
- */
-#define TX_STA_CNT0			0x170c
-#define TX_STA_CNT0_TX_FAIL_COUNT	FIELD32(0x0000ffff)
-#define TX_STA_CNT0_TX_BEACON_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_STA_CNT1: TX tx count
- */
-#define TX_STA_CNT1			0x1710
-#define TX_STA_CNT1_TX_SUCCESS		FIELD32(0x0000ffff)
-#define TX_STA_CNT1_TX_RETRANSMIT	FIELD32(0xffff0000)
-
-/*
- * TX_STA_CNT2: TX tx count
- */
-#define TX_STA_CNT2			0x1714
-#define TX_STA_CNT2_TX_ZERO_LEN_COUNT	FIELD32(0x0000ffff)
-#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_STA_FIFO: TX Result for specific PID status fifo register
- */
-#define TX_STA_FIFO			0x1718
-#define TX_STA_FIFO_VALID		FIELD32(0x00000001)
-#define TX_STA_FIFO_PID_TYPE		FIELD32(0x0000001e)
-#define TX_STA_FIFO_TX_SUCCESS		FIELD32(0x00000020)
-#define TX_STA_FIFO_TX_AGGRE		FIELD32(0x00000040)
-#define TX_STA_FIFO_TX_ACK_REQUIRED	FIELD32(0x00000080)
-#define TX_STA_FIFO_WCID		FIELD32(0x0000ff00)
-#define TX_STA_FIFO_SUCCESS_RATE	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT: Debug counter
- */
-#define TX_AGG_CNT			0x171c
-#define TX_AGG_CNT_NON_AGG_TX_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT_AGG_TX_COUNT		FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT0:
- */
-#define TX_AGG_CNT0			0x1720
-#define TX_AGG_CNT0_AGG_SIZE_1_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT0_AGG_SIZE_2_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT1:
- */
-#define TX_AGG_CNT1			0x1724
-#define TX_AGG_CNT1_AGG_SIZE_3_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT1_AGG_SIZE_4_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT2:
- */
-#define TX_AGG_CNT2			0x1728
-#define TX_AGG_CNT2_AGG_SIZE_5_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT2_AGG_SIZE_6_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT3:
- */
-#define TX_AGG_CNT3			0x172c
-#define TX_AGG_CNT3_AGG_SIZE_7_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT3_AGG_SIZE_8_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT4:
- */
-#define TX_AGG_CNT4			0x1730
-#define TX_AGG_CNT4_AGG_SIZE_9_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT4_AGG_SIZE_10_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT5:
- */
-#define TX_AGG_CNT5			0x1734
-#define TX_AGG_CNT5_AGG_SIZE_11_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT5_AGG_SIZE_12_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT6:
- */
-#define TX_AGG_CNT6			0x1738
-#define TX_AGG_CNT6_AGG_SIZE_13_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT6_AGG_SIZE_14_COUNT	FIELD32(0xffff0000)
-
-/*
- * TX_AGG_CNT7:
- */
-#define TX_AGG_CNT7			0x173c
-#define TX_AGG_CNT7_AGG_SIZE_15_COUNT	FIELD32(0x0000ffff)
-#define TX_AGG_CNT7_AGG_SIZE_16_COUNT	FIELD32(0xffff0000)
-
-/*
- * MPDU_DENSITY_CNT:
- * TX_ZERO_DEL: TX zero length delimiter count
- * RX_ZERO_DEL: RX zero length delimiter count
- */
-#define MPDU_DENSITY_CNT		0x1740
-#define MPDU_DENSITY_CNT_TX_ZERO_DEL	FIELD32(0x0000ffff)
-#define MPDU_DENSITY_CNT_RX_ZERO_DEL	FIELD32(0xffff0000)
-
-/*
- * Security key table memory.
- * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
- * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
- * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
- * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
- * SHARED_KEY_TABLE_BASE: 32 bytes * 32-entry
- * SHARED_KEY_MODE_BASE: 4 bits * 32-entry
- */
-#define MAC_WCID_BASE			0x1800
-#define PAIRWISE_KEY_TABLE_BASE		0x4000
-#define MAC_IVEIV_TABLE_BASE		0x6000
-#define MAC_WCID_ATTRIBUTE_BASE		0x6800
-#define SHARED_KEY_TABLE_BASE		0x6c00
-#define SHARED_KEY_MODE_BASE		0x7000
-
-#define MAC_WCID_ENTRY(__idx) \
-	( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
-#define PAIRWISE_KEY_ENTRY(__idx) \
-	( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
-#define MAC_IVEIV_ENTRY(__idx) \
-	( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) )
-#define MAC_WCID_ATTR_ENTRY(__idx) \
-	( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
-#define SHARED_KEY_ENTRY(__idx) \
-	( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
-#define SHARED_KEY_MODE_ENTRY(__idx) \
-	( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
-
-struct mac_wcid_entry {
-	u8 mac[6];
-	u8 reserved[2];
-} __attribute__ ((packed));
-
-struct hw_key_entry {
-	u8 key[16];
-	u8 tx_mic[8];
-	u8 rx_mic[8];
-} __attribute__ ((packed));
-
-struct mac_iveiv_entry {
-	u8 iv[8];
-} __attribute__ ((packed));
-
-/*
- * MAC_WCID_ATTRIBUTE:
- */
-#define MAC_WCID_ATTRIBUTE_KEYTAB	FIELD32(0x00000001)
-#define MAC_WCID_ATTRIBUTE_CIPHER	FIELD32(0x0000000e)
-#define MAC_WCID_ATTRIBUTE_BSS_IDX	FIELD32(0x00000070)
-#define MAC_WCID_ATTRIBUTE_RX_WIUDF	FIELD32(0x00000380)
-
-/*
- * SHARED_KEY_MODE:
- */
-#define SHARED_KEY_MODE_BSS0_KEY0	FIELD32(0x00000007)
-#define SHARED_KEY_MODE_BSS0_KEY1	FIELD32(0x00000070)
-#define SHARED_KEY_MODE_BSS0_KEY2	FIELD32(0x00000700)
-#define SHARED_KEY_MODE_BSS0_KEY3	FIELD32(0x00007000)
-#define SHARED_KEY_MODE_BSS1_KEY0	FIELD32(0x00070000)
-#define SHARED_KEY_MODE_BSS1_KEY1	FIELD32(0x00700000)
-#define SHARED_KEY_MODE_BSS1_KEY2	FIELD32(0x07000000)
-#define SHARED_KEY_MODE_BSS1_KEY3	FIELD32(0x70000000)
-
-/*
- * HOST-MCU communication
- */
-
-/*
- * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
- */
-#define H2M_MAILBOX_CSR			0x7010
-#define H2M_MAILBOX_CSR_ARG0		FIELD32(0x000000ff)
-#define H2M_MAILBOX_CSR_ARG1		FIELD32(0x0000ff00)
-#define H2M_MAILBOX_CSR_CMD_TOKEN	FIELD32(0x00ff0000)
-#define H2M_MAILBOX_CSR_OWNER		FIELD32(0xff000000)
-
-/*
- * H2M_MAILBOX_CID:
- */
-#define H2M_MAILBOX_CID			0x7014
-#define H2M_MAILBOX_CID_CMD0		FIELD32(0x000000ff)
-#define H2M_MAILBOX_CID_CMD1		FIELD32(0x0000ff00)
-#define H2M_MAILBOX_CID_CMD2		FIELD32(0x00ff0000)
-#define H2M_MAILBOX_CID_CMD3		FIELD32(0xff000000)
-
-/*
- * H2M_MAILBOX_STATUS:
- */
-#define H2M_MAILBOX_STATUS		0x701c
-
-/*
- * H2M_INT_SRC:
- */
-#define H2M_INT_SRC			0x7024
-
-/*
- * H2M_BBP_AGENT:
- */
-#define H2M_BBP_AGENT			0x7028
-
-/*
- * MCU_LEDCS: LED control for MCU Mailbox.
- */
-#define MCU_LEDCS_LED_MODE		FIELD8(0x1f)
-#define MCU_LEDCS_POLARITY		FIELD8(0x01)
-
-/*
- * HW_CS_CTS_BASE:
- * Carrier-sense CTS frame base address.
- * It's where mac stores carrier-sense frame for carrier-sense function.
- */
-#define HW_CS_CTS_BASE			0x7700
-
-/*
- * HW_DFS_CTS_BASE:
- * FS CTS frame base address. It's where mac stores CTS frame for DFS.
- */
-#define HW_DFS_CTS_BASE			0x7780
-
-/*
- * TXRX control registers - base address 0x3000
- */
-
-/*
- * TXRX_CSR1:
- * rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
- */
-#define TXRX_CSR1			0x77d0
-
-/*
- * HW_DEBUG_SETTING_BASE:
- * since NULL frame won't be that long (256 byte)
- * We steal 16 tail bytes to save debugging settings
- */
-#define HW_DEBUG_SETTING_BASE		0x77f0
-#define HW_DEBUG_SETTING_BASE2		0x7770
-
-/*
- * HW_BEACON_BASE
- * In order to support maximum 8 MBSS and its maximum length
- * is 512 bytes for each beacon
- * Three section discontinue memory segments will be used.
- * 1. The original region for BCN 0~3
- * 2. Extract memory from FCE table for BCN 4~5
- * 3. Extract memory from Pair-wise key table for BCN 6~7
- *    It occupied those memory of wcid 238~253 for BCN 6
- *    and wcid 222~237 for BCN 7
- *
- * IMPORTANT NOTE: Not sure why legacy driver does this,
- * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
- */
-#define HW_BEACON_BASE0			0x7800
-#define HW_BEACON_BASE1			0x7a00
-#define HW_BEACON_BASE2			0x7c00
-#define HW_BEACON_BASE3			0x7e00
-#define HW_BEACON_BASE4			0x7200
-#define HW_BEACON_BASE5			0x7400
-#define HW_BEACON_BASE6			0x5dc0
-#define HW_BEACON_BASE7			0x5bc0
-
-#define HW_BEACON_OFFSET(__index) \
-	( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
-	  (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
-	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
-
-/*
  * 8051 firmware image.
  */
 #define FIRMWARE_RT2870			"/*(DEBLOBBED)*/"
 #define FIRMWARE_IMAGE_BASE		0x3000
 
 /*
- * BBP registers.
- * The wordsize of the BBP is 8 bits.
- */
-
-/*
- * BBP 1: TX Antenna
- */
-#define BBP1_TX_POWER			FIELD8(0x07)
-#define BBP1_TX_ANTENNA			FIELD8(0x18)
-
-/*
- * BBP 3: RX Antenna
- */
-#define BBP3_RX_ANTENNA			FIELD8(0x18)
-#define BBP3_HT40_PLUS			FIELD8(0x20)
-
-/*
- * BBP 4: Bandwidth
- */
-#define BBP4_TX_BF			FIELD8(0x01)
-#define BBP4_BANDWIDTH			FIELD8(0x18)
-
-/*
- * RFCSR registers
- * The wordsize of the RFCSR is 8 bits.
- */
-
-/*
- * RFCSR 6:
- */
-#define RFCSR6_R			FIELD8(0x03)
-
-/*
- * RFCSR 7:
- */
-#define RFCSR7_RF_TUNING		FIELD8(0x01)
-
-/*
- * RFCSR 12:
- */
-#define RFCSR12_TX_POWER		FIELD8(0x1f)
-
-/*
- * RFCSR 22:
- */
-#define RFCSR22_BASEBAND_LOOPBACK	FIELD8(0x01)
-
-/*
- * RFCSR 23:
- */
-#define RFCSR23_FREQ_OFFSET		FIELD8(0x7f)
-
-/*
- * RFCSR 30:
- */
-#define RFCSR30_RF_CALIBRATION		FIELD8(0x80)
-
-/*
- * RF registers
- */
-
-/*
- * RF 2
- */
-#define RF2_ANTENNA_RX2			FIELD32(0x00000040)
-#define RF2_ANTENNA_TX1			FIELD32(0x00004000)
-#define RF2_ANTENNA_RX1			FIELD32(0x00020000)
-
-/*
- * RF 3
- */
-#define RF3_TXPOWER_G			FIELD32(0x00003e00)
-#define RF3_TXPOWER_A_7DBM_BOOST	FIELD32(0x00000200)
-#define RF3_TXPOWER_A			FIELD32(0x00003c00)
-
-/*
- * RF 4
- */
-#define RF4_TXPOWER_G			FIELD32(0x000007c0)
-#define RF4_TXPOWER_A_7DBM_BOOST	FIELD32(0x00000040)
-#define RF4_TXPOWER_A			FIELD32(0x00000780)
-#define RF4_FREQ_OFFSET			FIELD32(0x001f8000)
-#define RF4_HT40			FIELD32(0x00200000)
-
-/*
- * EEPROM content.
- * The wordsize of the EEPROM is 16 bits.
- */
-
-/*
- * EEPROM Version
- */
-#define EEPROM_VERSION			0x0001
-#define EEPROM_VERSION_FAE		FIELD16(0x00ff)
-#define EEPROM_VERSION_VERSION		FIELD16(0xff00)
-
-/*
- * HW MAC address.
- */
-#define EEPROM_MAC_ADDR_0		0x0002
-#define EEPROM_MAC_ADDR_BYTE0		FIELD16(0x00ff)
-#define EEPROM_MAC_ADDR_BYTE1		FIELD16(0xff00)
-#define EEPROM_MAC_ADDR_1		0x0003
-#define EEPROM_MAC_ADDR_BYTE2		FIELD16(0x00ff)
-#define EEPROM_MAC_ADDR_BYTE3		FIELD16(0xff00)
-#define EEPROM_MAC_ADDR_2		0x0004
-#define EEPROM_MAC_ADDR_BYTE4		FIELD16(0x00ff)
-#define EEPROM_MAC_ADDR_BYTE5		FIELD16(0xff00)
-
-/*
- * EEPROM ANTENNA config
- * RXPATH: 1: 1R, 2: 2R, 3: 3R
- * TXPATH: 1: 1T, 2: 2T
- */
-#define	EEPROM_ANTENNA			0x001a
-#define EEPROM_ANTENNA_RXPATH		FIELD16(0x000f)
-#define EEPROM_ANTENNA_TXPATH		FIELD16(0x00f0)
-#define EEPROM_ANTENNA_RF_TYPE		FIELD16(0x0f00)
-
-/*
- * EEPROM NIC config
- * CARDBUS_ACCEL: 0 - enable, 1 - disable
- */
-#define	EEPROM_NIC			0x001b
-#define EEPROM_NIC_HW_RADIO		FIELD16(0x0001)
-#define EEPROM_NIC_DYNAMIC_TX_AGC	FIELD16(0x0002)
-#define EEPROM_NIC_EXTERNAL_LNA_BG	FIELD16(0x0004)
-#define EEPROM_NIC_EXTERNAL_LNA_A	FIELD16(0x0008)
-#define EEPROM_NIC_CARDBUS_ACCEL	FIELD16(0x0010)
-#define EEPROM_NIC_BW40M_SB_BG		FIELD16(0x0020)
-#define EEPROM_NIC_BW40M_SB_A		FIELD16(0x0040)
-#define EEPROM_NIC_WPS_PBC		FIELD16(0x0080)
-#define EEPROM_NIC_BW40M_BG		FIELD16(0x0100)
-#define EEPROM_NIC_BW40M_A		FIELD16(0x0200)
-
-/*
- * EEPROM frequency
- */
-#define	EEPROM_FREQ			0x001d
-#define EEPROM_FREQ_OFFSET		FIELD16(0x00ff)
-#define EEPROM_FREQ_LED_MODE		FIELD16(0x7f00)
-#define EEPROM_FREQ_LED_POLARITY	FIELD16(0x1000)
-
-/*
- * EEPROM LED
- * POLARITY_RDY_G: Polarity RDY_G setting.
- * POLARITY_RDY_A: Polarity RDY_A setting.
- * POLARITY_ACT: Polarity ACT setting.
- * POLARITY_GPIO_0: Polarity GPIO0 setting.
- * POLARITY_GPIO_1: Polarity GPIO1 setting.
- * POLARITY_GPIO_2: Polarity GPIO2 setting.
- * POLARITY_GPIO_3: Polarity GPIO3 setting.
- * POLARITY_GPIO_4: Polarity GPIO4 setting.
- * LED_MODE: Led mode.
- */
-#define EEPROM_LED1			0x001e
-#define EEPROM_LED2			0x001f
-#define EEPROM_LED3			0x0020
-#define EEPROM_LED_POLARITY_RDY_BG	FIELD16(0x0001)
-#define EEPROM_LED_POLARITY_RDY_A	FIELD16(0x0002)
-#define EEPROM_LED_POLARITY_ACT		FIELD16(0x0004)
-#define EEPROM_LED_POLARITY_GPIO_0	FIELD16(0x0008)
-#define EEPROM_LED_POLARITY_GPIO_1	FIELD16(0x0010)
-#define EEPROM_LED_POLARITY_GPIO_2	FIELD16(0x0020)
-#define EEPROM_LED_POLARITY_GPIO_3	FIELD16(0x0040)
-#define EEPROM_LED_POLARITY_GPIO_4	FIELD16(0x0080)
-#define EEPROM_LED_LED_MODE		FIELD16(0x1f00)
-
-/*
- * EEPROM LNA
- */
-#define EEPROM_LNA			0x0022
-#define EEPROM_LNA_BG			FIELD16(0x00ff)
-#define EEPROM_LNA_A0			FIELD16(0xff00)
-
-/*
- * EEPROM RSSI BG offset
- */
-#define EEPROM_RSSI_BG			0x0023
-#define EEPROM_RSSI_BG_OFFSET0		FIELD16(0x00ff)
-#define EEPROM_RSSI_BG_OFFSET1		FIELD16(0xff00)
-
-/*
- * EEPROM RSSI BG2 offset
- */
-#define EEPROM_RSSI_BG2			0x0024
-#define EEPROM_RSSI_BG2_OFFSET2		FIELD16(0x00ff)
-#define EEPROM_RSSI_BG2_LNA_A1		FIELD16(0xff00)
-
-/*
- * EEPROM RSSI A offset
- */
-#define EEPROM_RSSI_A			0x0025
-#define EEPROM_RSSI_A_OFFSET0		FIELD16(0x00ff)
-#define EEPROM_RSSI_A_OFFSET1		FIELD16(0xff00)
-
-/*
- * EEPROM RSSI A2 offset
- */
-#define EEPROM_RSSI_A2			0x0026
-#define EEPROM_RSSI_A2_OFFSET2		FIELD16(0x00ff)
-#define EEPROM_RSSI_A2_LNA_A2		FIELD16(0xff00)
-
-/*
- * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
- *	This is delta in 40MHZ.
- * VALUE: Tx Power dalta value (MAX=4)
- * TYPE: 1: Plus the delta value, 0: minus the delta value
- * TXPOWER: Enable:
- */
-#define EEPROM_TXPOWER_DELTA		0x0028
-#define EEPROM_TXPOWER_DELTA_VALUE	FIELD16(0x003f)
-#define EEPROM_TXPOWER_DELTA_TYPE	FIELD16(0x0040)
-#define EEPROM_TXPOWER_DELTA_TXPOWER	FIELD16(0x0080)
-
-/*
- * EEPROM TXPOWER 802.11BG
- */
-#define	EEPROM_TXPOWER_BG1		0x0029
-#define	EEPROM_TXPOWER_BG2		0x0030
-#define EEPROM_TXPOWER_BG_SIZE		7
-#define EEPROM_TXPOWER_BG_1		FIELD16(0x00ff)
-#define EEPROM_TXPOWER_BG_2		FIELD16(0xff00)
-
-/*
- * EEPROM TXPOWER 802.11A
- */
-#define EEPROM_TXPOWER_A1		0x003c
-#define EEPROM_TXPOWER_A2		0x0053
-#define EEPROM_TXPOWER_A_SIZE		6
-#define EEPROM_TXPOWER_A_1		FIELD16(0x00ff)
-#define EEPROM_TXPOWER_A_2		FIELD16(0xff00)
-
-/*
- * EEPROM TXpower byrate: 20MHZ power
- */
-#define EEPROM_TXPOWER_BYRATE		0x006f
-
-/*
- * EEPROM BBP.
- */
-#define	EEPROM_BBP_START		0x0078
-#define EEPROM_BBP_SIZE			16
-#define EEPROM_BBP_VALUE		FIELD16(0x00ff)
-#define EEPROM_BBP_REG_ID		FIELD16(0xff00)
-
-/*
- * MCU mailbox commands.
- */
-#define MCU_SLEEP			0x30
-#define MCU_WAKEUP			0x31
-#define MCU_RADIO_OFF			0x35
-#define MCU_CURRENT			0x36
-#define MCU_LED				0x50
-#define MCU_LED_STRENGTH		0x51
-#define MCU_LED_1			0x52
-#define MCU_LED_2			0x53
-#define MCU_LED_3			0x54
-#define MCU_RADAR			0x60
-#define MCU_BOOT_SIGNAL			0x72
-#define MCU_BBP_SIGNAL			0x80
-#define MCU_POWER_SAVE			0x83
-
-/*
- * MCU mailbox tokens
- */
-#define TOKEN_WAKUP			3
-
-/*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE			( 4 * sizeof(__le32) )
 #define TXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
-#define TXWI_DESC_SIZE			( 4 * sizeof(__le32) )
-#define RXD_DESC_SIZE			( 1 * sizeof(__le32) )
-#define RXWI_DESC_SIZE			( 4 * sizeof(__le32) )
-
-/*
- * TX descriptor format for TX, PRIO and Beacon Ring.
- */
-
-/*
- * Word0
- */
-#define TXD_W0_SD_PTR0			FIELD32(0xffffffff)
-
-/*
- * Word1
- */
-#define TXD_W1_SD_LEN1			FIELD32(0x00003fff)
-#define TXD_W1_LAST_SEC1		FIELD32(0x00004000)
-#define TXD_W1_BURST			FIELD32(0x00008000)
-#define TXD_W1_SD_LEN0			FIELD32(0x3fff0000)
-#define TXD_W1_LAST_SEC0		FIELD32(0x40000000)
-#define TXD_W1_DMA_DONE			FIELD32(0x80000000)
-
-/*
- * Word2
- */
-#define TXD_W2_SD_PTR1			FIELD32(0xffffffff)
-
-/*
- * Word3
- * WIV: Wireless Info Valid. 1: Driver filled WI,  0: DMA needs to copy WI
- * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
- *       0:MGMT, 1:HCCA 2:EDCA
- */
-#define TXD_W3_WIV			FIELD32(0x01000000)
-#define TXD_W3_QSEL			FIELD32(0x06000000)
-#define TXD_W3_TCO			FIELD32(0x20000000)
-#define TXD_W3_UCO			FIELD32(0x40000000)
-#define TXD_W3_ICO			FIELD32(0x80000000)
+#define RXINFO_DESC_SIZE		( 1 * sizeof(__le32) )
 
 /*
  * TX Info structure
@@ -1807,52 +101,6 @@ struct mac_iveiv_entry {
 #define TXINFO_W0_USB_DMA_TX_BURST	FIELD32(0x80000000)
 
 /*
- * TX WI structure
- */
-
-/*
- * Word0
- * FRAG: 1 To inform TKIP engine this is a fragment.
- * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
- * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
- * BW: Channel bandwidth 20MHz or 40 MHz
- * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
- */
-#define TXWI_W0_FRAG			FIELD32(0x00000001)
-#define TXWI_W0_MIMO_PS			FIELD32(0x00000002)
-#define TXWI_W0_CF_ACK			FIELD32(0x00000004)
-#define TXWI_W0_TS			FIELD32(0x00000008)
-#define TXWI_W0_AMPDU			FIELD32(0x00000010)
-#define TXWI_W0_MPDU_DENSITY		FIELD32(0x000000e0)
-#define TXWI_W0_TX_OP			FIELD32(0x00000300)
-#define TXWI_W0_MCS			FIELD32(0x007f0000)
-#define TXWI_W0_BW			FIELD32(0x00800000)
-#define TXWI_W0_SHORT_GI		FIELD32(0x01000000)
-#define TXWI_W0_STBC			FIELD32(0x06000000)
-#define TXWI_W0_IFS			FIELD32(0x08000000)
-#define TXWI_W0_PHYMODE			FIELD32(0xc0000000)
-
-/*
- * Word1
- */
-#define TXWI_W1_ACK			FIELD32(0x00000001)
-#define TXWI_W1_NSEQ			FIELD32(0x00000002)
-#define TXWI_W1_BW_WIN_SIZE		FIELD32(0x000000fc)
-#define TXWI_W1_WIRELESS_CLI_ID		FIELD32(0x0000ff00)
-#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
-#define TXWI_W1_PACKETID		FIELD32(0xf0000000)
-
-/*
- * Word2
- */
-#define TXWI_W2_IV			FIELD32(0xffffffff)
-
-/*
- * Word3
- */
-#define TXWI_W3_EIV			FIELD32(0xffffffff)
-
-/*
  * RX descriptor format for RX Ring.
  */
 
@@ -1867,85 +115,25 @@ struct mac_iveiv_entry {
  * AMSDU: rx with 802.3 header, not 802.11 header.
  */
 
-#define RXD_W0_BA			FIELD32(0x00000001)
-#define RXD_W0_DATA			FIELD32(0x00000002)
-#define RXD_W0_NULLDATA			FIELD32(0x00000004)
-#define RXD_W0_FRAG			FIELD32(0x00000008)
-#define RXD_W0_UNICAST_TO_ME		FIELD32(0x00000010)
-#define RXD_W0_MULTICAST		FIELD32(0x00000020)
-#define RXD_W0_BROADCAST		FIELD32(0x00000040)
-#define RXD_W0_MY_BSS			FIELD32(0x00000080)
-#define RXD_W0_CRC_ERROR		FIELD32(0x00000100)
-#define RXD_W0_CIPHER_ERROR		FIELD32(0x00000600)
-#define RXD_W0_AMSDU			FIELD32(0x00000800)
-#define RXD_W0_HTC			FIELD32(0x00001000)
-#define RXD_W0_RSSI			FIELD32(0x00002000)
-#define RXD_W0_L2PAD			FIELD32(0x00004000)
-#define RXD_W0_AMPDU			FIELD32(0x00008000)
-#define RXD_W0_DECRYPTED		FIELD32(0x00010000)
-#define RXD_W0_PLCP_RSSI		FIELD32(0x00020000)
-#define RXD_W0_CIPHER_ALG		FIELD32(0x00040000)
-#define RXD_W0_LAST_AMSDU		FIELD32(0x00080000)
-#define RXD_W0_PLCP_SIGNAL		FIELD32(0xfff00000)
-
-/*
- * RX WI structure
- */
-
-/*
- * Word0
- */
-#define RXWI_W0_WIRELESS_CLI_ID		FIELD32(0x000000ff)
-#define RXWI_W0_KEY_INDEX		FIELD32(0x00000300)
-#define RXWI_W0_BSSID			FIELD32(0x00001c00)
-#define RXWI_W0_UDF			FIELD32(0x0000e000)
-#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT	FIELD32(0x0fff0000)
-#define RXWI_W0_TID			FIELD32(0xf0000000)
-
-/*
- * Word1
- */
-#define RXWI_W1_FRAG			FIELD32(0x0000000f)
-#define RXWI_W1_SEQUENCE		FIELD32(0x0000fff0)
-#define RXWI_W1_MCS			FIELD32(0x007f0000)
-#define RXWI_W1_BW			FIELD32(0x00800000)
-#define RXWI_W1_SHORT_GI		FIELD32(0x01000000)
-#define RXWI_W1_STBC			FIELD32(0x06000000)
-#define RXWI_W1_PHYMODE			FIELD32(0xc0000000)
-
-/*
- * Word2
- */
-#define RXWI_W2_RSSI0			FIELD32(0x000000ff)
-#define RXWI_W2_RSSI1			FIELD32(0x0000ff00)
-#define RXWI_W2_RSSI2			FIELD32(0x00ff0000)
-
-/*
- * Word3
- */
-#define RXWI_W3_SNR0			FIELD32(0x000000ff)
-#define RXWI_W3_SNR1			FIELD32(0x0000ff00)
-
-/*
- * Macros for converting txpower from EEPROM to mac80211 value
- * and from mac80211 value to register value.
- */
-#define MIN_G_TXPOWER	0
-#define MIN_A_TXPOWER	-7
-#define MAX_G_TXPOWER	31
-#define MAX_A_TXPOWER	15
-#define DEFAULT_TXPOWER	5
-
-#define TXPOWER_G_FROM_DEV(__txpower) \
-	((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
-
-#define TXPOWER_G_TO_DEV(__txpower) \
-	clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
-
-#define TXPOWER_A_FROM_DEV(__txpower) \
-	((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
-
-#define TXPOWER_A_TO_DEV(__txpower) \
-	clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+#define RXINFO_W0_BA			FIELD32(0x00000001)
+#define RXINFO_W0_DATA			FIELD32(0x00000002)
+#define RXINFO_W0_NULLDATA		FIELD32(0x00000004)
+#define RXINFO_W0_FRAG			FIELD32(0x00000008)
+#define RXINFO_W0_UNICAST_TO_ME		FIELD32(0x00000010)
+#define RXINFO_W0_MULTICAST		FIELD32(0x00000020)
+#define RXINFO_W0_BROADCAST		FIELD32(0x00000040)
+#define RXINFO_W0_MY_BSS		FIELD32(0x00000080)
+#define RXINFO_W0_CRC_ERROR		FIELD32(0x00000100)
+#define RXINFO_W0_CIPHER_ERROR		FIELD32(0x00000600)
+#define RXINFO_W0_AMSDU			FIELD32(0x00000800)
+#define RXINFO_W0_HTC			FIELD32(0x00001000)
+#define RXINFO_W0_RSSI			FIELD32(0x00002000)
+#define RXINFO_W0_L2PAD			FIELD32(0x00004000)
+#define RXINFO_W0_AMPDU			FIELD32(0x00008000)
+#define RXINFO_W0_DECRYPTED		FIELD32(0x00010000)
+#define RXINFO_W0_PLCP_RSSI		FIELD32(0x00020000)
+#define RXINFO_W0_CIPHER_ALG		FIELD32(0x00040000)
+#define RXINFO_W0_LAST_AMSDU		FIELD32(0x00080000)
+#define RXINFO_W0_PLCP_SIGNAL		FIELD32(0xfff00000)
 
 #endif /* RT2800USB_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -205,6 +205,7 @@ void rt2x00lib_txdone(struct queue_entry
 	enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
 	unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
 	u8 rate_idx, rate_flags, retry_rates;
+	u8 skbdesc_flags = skbdesc->flags;
 	unsigned int i;
 	bool success;
 
@@ -287,12 +288,12 @@ void rt2x00lib_txdone(struct queue_entry
 	}
 
 	/*
-	 * Only send the status report to mac80211 when TX status was
-	 * requested by it. If this was a extra frame coming through
-	 * a mac80211 library call (RTS/CTS) then we should not send the
-	 * status report back.
+	 * Only send the status report to mac80211 when it's a frame
+	 * that originated in mac80211. If this was a extra frame coming
+	 * through a mac80211 library call (RTS/CTS) then we should not
+	 * send the status report back.
 	 */
-	if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
+	if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
 		ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
 	else
 		dev_kfree_skb_irq(entry->skb);
@@ -430,7 +431,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev
 
 	rx_status->mactime = rxdesc.timestamp;
 	rx_status->rate_idx = rate_idx;
-	rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
 	rx_status->signal = rxdesc.rssi;
 	rx_status->noise = rxdesc.noise;
 	rx_status->flag = rxdesc.flags;
@@ -684,6 +684,21 @@ static int rt2x00lib_probe_hw(struct rt2
 	rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;
 
 	/*
+	 * Initialize extra TX headroom required.
+	 */
+	rt2x00dev->hw->extra_tx_headroom =
+		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
+		      rt2x00dev->ops->extra_tx_headroom);
+
+	/*
+	 * Take TX headroom required for alignment into account.
+	 */
+	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
+	else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
+
+	/*
 	 * Register HW.
 	 */
 	status = ieee80211_register_hw(rt2x00dev->hw);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c	2013-05-03 14:03:24.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c	2013-05-03 12:11:00.000000000 -0400
@@ -1,5 +1,6 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -112,6 +113,12 @@
 	(  ((unsigned long)((__skb)->data + (__header))) & 3 )
 
 /*
+ * Constants for extra TX headroom for alignment purposes.
+ */
+#define RT2X00_ALIGN_SIZE	4 /* Only whole frame needs alignment */
+#define RT2X00_L2PAD_SIZE	8 /* Both header & payload need alignment */
+
+/*
  * Standard timing and size defines.
  * These values should follow the ieee80211 specifications.
  */
@@ -144,6 +151,11 @@ struct avg_val {
 	int avg_weight;
 };
 
+enum rt2x00_chip_intf {
+	RT2X00_CHIP_INTF_PCI,
+	RT2X00_CHIP_INTF_USB,
+};
+
 /*
  * Chipset identification
  * The chipset on the device is composed of a RT and RF chip.
@@ -158,10 +170,20 @@ struct rt2x00_chip {
 #define RT2561		0x0302
 #define RT2661		0x0401
 #define RT2571		0x1300
+#define RT2860		0x0601	/* 2.4GHz PCI/CB */
+#define RT2860D		0x0681	/* 2.4GHz, 5GHz PCI/CB */
+#define RT2890		0x0701	/* 2.4GHz PCIe */
+#define RT2890D		0x0781	/* 2.4GHz, 5GHz PCIe */
+#define RT2880		0x2880	/* WSOC */
+#define RT3052		0x3052	/* WSOC */
+#define RT3090		0x3090	/* 2.4GHz PCIe */
 #define RT2870		0x1600
+#define RT3070		0x1800
 
 	u16 rf;
 	u32 rev;
+
+	enum rt2x00_chip_intf intf;
 };
 
 /*
@@ -299,13 +321,6 @@ struct link {
 	struct avg_val avg_rssi;
 
 	/*
-	 * Currently precalculated percentages of successful
-	 * TX and RX frames.
-	 */
-	int rx_percentage;
-	int tx_percentage;
-
-	/*
 	 * Work structure for scheduling periodic link tuning.
 	 */
 	struct delayed_work work;
@@ -579,6 +594,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;
@@ -835,9 +851,23 @@ struct rt2x00_dev {
 	 * Firmware image.
 	 */
 	const struct firmware *fw;
+
+	/*
+	 * Driver specific data.
+	 */
+	void *priv;
 };
 
 /*
+ * Register defines.
+ * Some registers require multiple attempts before success,
+ * in those cases REGISTER_BUSY_COUNT attempts should be
+ * taken with a REGISTER_BUSY_DELAY interval.
+ */
+#define REGISTER_BUSY_COUNT	5
+#define REGISTER_BUSY_DELAY	100
+
+/*
  * Generic RF access.
  * The RF is being accessed by word index.
  */
@@ -883,10 +913,6 @@ static inline void rt2x00_eeprom_write(s
 static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
 				   const u16 rt, const u16 rf, const u32 rev)
 {
-	INFO(rt2x00dev,
-	     "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n",
-	     rt, rf, rev);
-
 	rt2x00dev->chip.rt = rt;
 	rt2x00dev->chip.rf = rf;
 	rt2x00dev->chip.rev = rev;
@@ -904,6 +930,13 @@ static inline void rt2x00_set_chip_rf(st
 	rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
 }
 
+static inline void rt2x00_print_chip(struct rt2x00_dev *rt2x00dev)
+{
+	INFO(rt2x00dev,
+	     "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n",
+	     rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
+}
+
 static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
 {
 	return (chipset->rt == chip);
@@ -925,6 +958,28 @@ static inline bool rt2x00_check_rev(cons
 	return ((chipset->rev & mask) == rev);
 }
 
+static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
+					enum rt2x00_chip_intf intf)
+{
+	rt2x00dev->chip.intf = intf;
+}
+
+static inline bool rt2x00_intf(const struct rt2x00_chip *chipset,
+			       enum rt2x00_chip_intf intf)
+{
+	return (chipset->intf == intf);
+}
+
+static inline bool rt2x00_intf_is_pci(struct rt2x00_dev *rt2x00dev)
+{
+	return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_PCI);
+}
+
+static inline bool rt2x00_intf_is_usb(struct rt2x00_dev *rt2x00dev)
+{
+	return rt2x00_intf(&rt2x00dev->chip, RT2X00_CHIP_INTF_USB);
+}
+
 /**
  * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00ht.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00ht.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00ht.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00ht.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -33,8 +33,6 @@ enum led_type {
 	LED_TYPE_QUALITY,
 };
 
-#ifdef CONFIG_RT2X00_LIB_LEDS
-
 struct rt2x00_led {
 	struct rt2x00_dev *rt2x00dev;
 	struct led_classdev led_dev;
@@ -45,6 +43,4 @@ struct rt2x00_led {
 #define LED_REGISTERED		( 1 << 1 )
 };
 
-#endif /* CONFIG_RT2X00_LIB_LEDS */
-
 #endif /* RT2X00LEDS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -161,8 +162,10 @@ void rt2x00queue_remove_l2pad(struct sk_
  * rt2x00queue_write_tx_frame - Write TX frame to hardware
  * @queue: Queue over which the frame should be send
  * @skb: The skb to send
+ * @local: frame is not from mac80211
  */
-int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
+			       bool local);
 
 /**
  * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
@@ -223,19 +226,6 @@ void rt2x00link_update_stats(struct rt2x
 			     struct rxdone_entry_desc *rxdesc);
 
 /**
- * rt2x00link_calculate_signal - Calculate signal quality
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @rssi: RX Frame RSSI
- *
- * Calculate the signal quality of a frame based on the rssi
- * measured during the receiving of the frame and the global
- * link quality statistics measured since the start of the
- * link tuning. The result is a value between 0 and 100 which
- * is an indication of the signal quality.
- */
-int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi);
-
-/**
  * rt2x00link_start_tuner - Start periodic link tuner work
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  *
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -36,24 +36,6 @@
 #define DEFAULT_RSSI		-128
 
 /*
- * When no TX/RX percentage could be calculated due to lack of
- * frames on the air, we fallback to a percentage of 50%.
- * This will assure we will get at least get some decent value
- * when the link tuner starts.
- * The value will be dropped and overwritten with the correct (measured)
- * value anyway during the first run of the link tuner.
- */
-#define DEFAULT_PERCENTAGE	50
-
-/*
- * Small helper macro for percentage calculation
- * This is a very simple macro with the only catch that it will
- * produce a default value in case no total value was provided.
- */
-#define PERCENTAGE(__value, __total) \
-	( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) )
-
-/*
  * Helper struct and macro to work with moving/walking averages.
  * When adding a value to the average value the following calculation
  * is needed:
@@ -91,27 +73,6 @@
 	__new; \
 })
 
-/*
- * For calculating the Signal quality we have determined
- * the total number of success and failed RX and TX frames.
- * With the addition of the average RSSI value we can determine
- * the link quality using the following algorithm:
- *
- *         rssi_percentage = (avg_rssi * 100) / rssi_offset
- *         rx_percentage = (rx_success * 100) / rx_total
- *         tx_percentage = (tx_success * 100) / tx_total
- *         avg_signal = ((WEIGHT_RSSI * avg_rssi) +
- *                       (WEIGHT_TX * tx_percentage) +
- *                       (WEIGHT_RX * rx_percentage)) / 100
- *
- * This value should then be checked to not be greater then 100.
- * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must
- * sum up to 100 as well.
- */
-#define WEIGHT_RSSI	20
-#define WEIGHT_RX	40
-#define WEIGHT_TX	40
-
 static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
@@ -304,46 +265,6 @@ void rt2x00link_update_stats(struct rt2x
 	ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi);
 }
 
-static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev)
-{
-	struct link *link = &rt2x00dev->link;
-	struct link_qual *qual = &rt2x00dev->link.qual;
-
-	link->rx_percentage =
-	    PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success);
-	link->tx_percentage =
-	    PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success);
-}
-
-int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi)
-{
-	struct link *link = &rt2x00dev->link;
-	int rssi_percentage = 0;
-	int signal;
-
-	/*
-	 * We need a positive value for the RSSI.
-	 */
-	if (rssi < 0)
-		rssi += rt2x00dev->rssi_offset;
-
-	/*
-	 * Calculate the different percentages,
-	 * which will be used for the signal.
-	 */
-	rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset);
-
-	/*
-	 * Add the individual percentages and use the WEIGHT
-	 * defines to calculate the current link signal.
-	 */
-	signal = ((WEIGHT_RSSI * rssi_percentage) +
-		  (WEIGHT_TX * link->tx_percentage) +
-		  (WEIGHT_RX * link->rx_percentage)) / 100;
-
-	return max_t(int, signal, 100);
-}
-
 void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
 {
 	struct link *link = &rt2x00dev->link;
@@ -357,9 +278,6 @@ void rt2x00link_start_tuner(struct rt2x0
 	if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)
 		return;
 
-	link->rx_percentage = DEFAULT_PERCENTAGE;
-	link->tx_percentage = DEFAULT_PERCENTAGE;
-
 	rt2x00link_reset_tuner(rt2x00dev, false);
 
 	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
@@ -448,12 +366,6 @@ static void rt2x00link_tuner(struct work
 		rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
 
 	/*
-	 * Precalculate a portion of the link signal which is
-	 * in based on the tx/rx success/failure counters.
-	 */
-	rt2x00link_precalculate_signal(rt2x00dev);
-
-	/*
 	 * Send a signal to the led to update the led signal strength.
 	 */
 	rt2x00leds_led_quality(rt2x00dev, qual->rssi);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -66,7 +66,6 @@ static int rt2x00mac_tx_rts_cts(struct r
 	rts_info = IEEE80211_SKB_CB(skb);
 	rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
 	rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT;
-	rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
 
 	if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
 		rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
@@ -91,7 +90,7 @@ static int rt2x00mac_tx_rts_cts(struct r
 				  frag_skb->data, data_length, tx_info,
 				  (struct ieee80211_rts *)(skb->data));
 
-	retval = rt2x00queue_write_tx_frame(queue, skb);
+	retval = rt2x00queue_write_tx_frame(queue, skb, true);
 	if (retval) {
 		dev_kfree_skb_any(skb);
 		WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
@@ -104,10 +103,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
 	enum data_queue_qid qid = skb_get_queue_mapping(skb);
 	struct data_queue *queue;
-	u16 frame_control;
 
 	/*
 	 * Mac80211 might be calling this function while we are trying
@@ -142,7 +139,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw
 	 * either RTS or CTS-to-self frame and handles everything
 	 * inside the hardware.
 	 */
-	frame_control = le16_to_cpu(ieee80211hdr->frame_control);
 	if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
 						IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
 	    !rt2x00dev->ops->hw->set_rts_threshold) {
@@ -153,7 +149,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw
 			goto exit_fail;
 	}
 
-	if (rt2x00queue_write_tx_frame(queue, skb))
+	if (rt2x00queue_write_tx_frame(queue, skb, false))
 		goto exit_fail;
 
 	if (rt2x00queue_threshold(queue))
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -310,6 +310,8 @@ int rt2x00pci_probe(struct pci_dev *pci_
 	rt2x00dev->irq = pci_dev->irq;
 	rt2x00dev->name = pci_name(pci_dev);
 
+	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
+
 	/*
 	 * Determine RT chipset by reading PCI header.
 	 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -35,15 +35,6 @@
 #define PCI_DEVICE_DATA(__ops)	.driver_data = (kernel_ulong_t)(__ops)
 
 /*
- * Register defines.
- * Some registers require multiple attempts before success,
- * in those cases REGISTER_BUSY_COUNT attempts should be
- * taken with a REGISTER_BUSY_DELAY interval.
- */
-#define REGISTER_BUSY_COUNT	5
-#define REGISTER_BUSY_DELAY	100
-
-/*
  * Register access.
  */
 static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
@@ -53,10 +44,9 @@ static inline void rt2x00pci_register_re
 	*value = readl(rt2x00dev->csr.base + offset);
 }
 
-static inline void
-rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
-			     const unsigned int offset,
-			     void *value, const u16 length)
+static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
+						const unsigned int offset,
+						void *value, const u32 length)
 {
 	memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
 }
@@ -68,10 +58,10 @@ static inline void rt2x00pci_register_wr
 	writel(value, rt2x00dev->csr.base + offset);
 }
 
-static inline void
-rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
-			      const unsigned int offset,
-			      const void *value, const u16 length)
+static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+						 const unsigned int offset,
+						 const void *value,
+						 const u32 length)
 {
 	memcpy_toio(rt2x00dev->csr.base + offset, value, length);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,6 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -103,7 +104,7 @@ void rt2x00queue_map_txskb(struct rt2x00
 	 * is also mapped to the DMA so it can be used for transfering
 	 * additional descriptor information to the hardware.
 	 */
-	skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
+	skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
 
 	skbdesc->skb_dma =
 	    dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
@@ -111,7 +112,7 @@ void rt2x00queue_map_txskb(struct rt2x00
 	/*
 	 * Restore data pointer to original location again.
 	 */
-	skb_pull(skb, rt2x00dev->hw->extra_tx_headroom);
+	skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
 
 	skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
 }
@@ -133,7 +134,7 @@ void rt2x00queue_unmap_skb(struct rt2x00
 		 * by the driver, but it was actually mapped to DMA.
 		 */
 		dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
-				 skb->len + rt2x00dev->hw->extra_tx_headroom,
+				 skb->len + rt2x00dev->ops->extra_tx_headroom,
 				 DMA_TO_DEVICE);
 		skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
 	}
@@ -161,10 +162,10 @@ void rt2x00queue_align_frame(struct sk_b
 	skb_trim(skb, frame_length);
 }
 
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_lengt)
+void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
 {
 	unsigned int frame_length = skb->len;
-	unsigned int align = ALIGN_SIZE(skb, header_lengt);
+	unsigned int align = ALIGN_SIZE(skb, header_length);
 
 	if (!align)
 		return;
@@ -213,7 +214,7 @@ void rt2x00queue_insert_l2pad(struct sk_
 		skb_push(skb, header_align);
 		memmove(skb->data, skb->data + header_align, header_length);
 		memmove(skb->data + header_length + l2pad,
-			skb->data + header_length + l2pad + header_align,
+			skb->data + header_length + l2pad + payload_align,
 			frame_length - header_length);
 		skbdesc->flags |= SKBDESC_L2_PADDED;
 	}
@@ -453,7 +454,8 @@ static void rt2x00queue_write_tx_descrip
 		rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
 }
 
-int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
+			       bool local)
 {
 	struct ieee80211_tx_info *tx_info;
 	struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
@@ -494,6 +496,9 @@ int rt2x00queue_write_tx_frame(struct da
 	skbdesc->tx_rate_idx = rate_idx;
 	skbdesc->tx_rate_flags = rate_flags;
 
+	if (local)
+		skbdesc->flags |= SKBDESC_NOT_MAC80211;
+
 	/*
 	 * When hardware encryption is supported, and this frame
 	 * is to be encrypted, we should strip the IV/EIV data from
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -94,12 +94,15 @@ enum data_queue_qid {
  *	mac80211 but was stripped for processing by the driver.
  * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
  *	the padded bytes are located between header and payload.
+ * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
+ *	don't try to pass it back.
  */
 enum skb_frame_desc_flags {
 	SKBDESC_DMA_MAPPED_RX = 1 << 0,
 	SKBDESC_DMA_MAPPED_TX = 1 << 1,
 	SKBDESC_IV_STRIPPED = 1 << 2,
-	SKBDESC_L2_PADDED = 1 << 3
+	SKBDESC_L2_PADDED = 1 << 3,
+	SKBDESC_NOT_MAC80211 = 1 << 4,
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,165 @@
+/*
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	Copyright (C) 2004 - 2009 Felix Fietkau <nbd@openwrt.org>
+	<http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2x00soc
+	Abstract: rt2x00 generic soc device routines.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "rt2x00.h"
+#include "rt2x00soc.h"
+
+static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)
+{
+	kfree(rt2x00dev->rf);
+	rt2x00dev->rf = NULL;
+
+	kfree(rt2x00dev->eeprom);
+	rt2x00dev->eeprom = NULL;
+}
+
+static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
+{
+	struct platform_device *pdev = to_platform_device(rt2x00dev->dev);
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	rt2x00dev->csr.base = (void __iomem *)KSEG1ADDR(res->start);
+	if (!rt2x00dev->csr.base)
+		goto exit;
+
+	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
+	if (!rt2x00dev->eeprom)
+		goto exit;
+
+	rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
+	if (!rt2x00dev->rf)
+		goto exit;
+
+	return 0;
+
+exit:
+	ERROR_PROBE("Failed to allocate registers.\n");
+	rt2x00soc_free_reg(rt2x00dev);
+
+	return -ENOMEM;
+}
+
+int rt2x00soc_probe(struct platform_device *pdev,
+		    const unsigned short chipset,
+		    const struct rt2x00_ops *ops)
+{
+	struct ieee80211_hw *hw;
+	struct rt2x00_dev *rt2x00dev;
+	int retval;
+
+	hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
+	if (!hw) {
+		ERROR_PROBE("Failed to allocate hardware.\n");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, hw);
+
+	rt2x00dev = hw->priv;
+	rt2x00dev->dev = &pdev->dev;
+	rt2x00dev->ops = ops;
+	rt2x00dev->hw = hw;
+	rt2x00dev->irq = platform_get_irq(pdev, 0);
+	rt2x00dev->name = pdev->dev.driver->name;
+
+	/*
+	 * SoC devices mimic PCI behavior.
+	 */
+	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
+
+	rt2x00_set_chip_rt(rt2x00dev, chipset);
+
+	retval = rt2x00soc_alloc_reg(rt2x00dev);
+	if (retval)
+		goto exit_free_device;
+
+	retval = rt2x00lib_probe_dev(rt2x00dev);
+	if (retval)
+		goto exit_free_reg;
+
+	return 0;
+
+exit_free_reg:
+	rt2x00soc_free_reg(rt2x00dev);
+
+exit_free_device:
+	ieee80211_free_hw(hw);
+
+	return retval;
+}
+
+int rt2x00soc_remove(struct platform_device *pdev)
+{
+	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	/*
+	 * Free all allocated data.
+	 */
+	rt2x00lib_remove_dev(rt2x00dev);
+	rt2x00soc_free_reg(rt2x00dev);
+	ieee80211_free_hw(hw);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00soc_remove);
+
+#ifdef CONFIG_PM
+int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	return rt2x00lib_suspend(rt2x00dev, state);
+}
+EXPORT_SYMBOL_GPL(rt2x00soc_suspend);
+
+int rt2x00soc_resume(struct platform_device *pdev)
+{
+	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	return rt2x00lib_resume(rt2x00dev);
+}
+EXPORT_SYMBOL_GPL(rt2x00soc_resume);
+#endif /* CONFIG_PM */
+
+/*
+ * rt2x00soc module information.
+ */
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("rt2x00 soc library");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00soc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+	<http://rt2x00.serialmonkey.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.
+ */
+
+/*
+	Module: rt2x00soc
+	Abstract: Data structures for the rt2x00soc module.
+ */
+
+#ifndef RT2X00SOC_H
+#define RT2X00SOC_H
+
+#define KSEG1ADDR(__ptr) __ptr
+
+#define __rt2x00soc_probe(__chipset, __ops) \
+static int __rt2x00soc_probe(struct platform_device *pdev) \
+{ \
+	return rt2x00soc_probe(pdev, (__chipset), (__ops)); \
+}
+
+/*
+ * SoC driver handlers.
+ */
+int rt2x00soc_probe(struct platform_device *pdev,
+		    const unsigned short chipset,
+		    const struct rt2x00_ops *ops);
+int rt2x00soc_remove(struct platform_device *pdev);
+#ifdef CONFIG_PM
+int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state);
+int rt2x00soc_resume(struct platform_device *pdev);
+#else
+#define rt2x00soc_suspend	NULL
+#define rt2x00soc_resume	NULL
+#endif /* CONFIG_PM */
+
+#endif /* RT2X00SOC_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -160,7 +160,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_reque
 
 int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
 			   const unsigned int offset,
-			   struct rt2x00_field32 field,
+			   const struct rt2x00_field32 field,
 			   u32 *reg)
 {
 	unsigned int i;
@@ -653,6 +653,8 @@ int rt2x00usb_probe(struct usb_interface
 	rt2x00dev->ops = ops;
 	rt2x00dev->hw = hw;
 
+	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
+
 	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
 		goto exit_free_device;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,8 @@
 #ifndef RT2X00USB_H
 #define RT2X00USB_H
 
+#include <linux/usb.h>
+
 #define to_usb_device_intf(d) \
 ({ \
 	struct usb_interface *intf = to_usb_interface(d); \
@@ -39,17 +41,11 @@
 #define USB_DEVICE_DATA(__ops)	.driver_info = (kernel_ulong_t)(__ops)
 
 /*
- * Register defines.
- * Some registers require multiple attempts before success,
- * in those cases REGISTER_BUSY_COUNT attempts should be
- * taken with a REGISTER_BUSY_DELAY interval.
  * For USB vendor requests we need to pass a timeout
  * time in ms, for this we use the REGISTER_TIMEOUT,
  * however when loading firmware a higher value is
  * required. In that case we use the REGISTER_TIMEOUT_FIRMWARE.
  */
-#define REGISTER_BUSY_COUNT		5
-#define REGISTER_BUSY_DELAY		100
 #define REGISTER_TIMEOUT		500
 #define REGISTER_TIMEOUT_FIRMWARE	1000
 
@@ -232,7 +228,7 @@ static inline int rt2x00usb_eeprom_read(
 }
 
 /**
- * rt2x00usb_regbusy_read - Read 32bit register word
+ * rt2x00usb_register_read - Read 32bit register word
  * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
  * @offset: Register offset
  * @value: Pointer to where register contents should be stored
@@ -340,12 +336,13 @@ static inline void rt2x00usb_register_wr
  * through rt2x00usb_vendor_request_buff().
  */
 static inline void rt2x00usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
-					       const unsigned int offset,
-					       void *value, const u32 length)
+						 const unsigned int offset,
+						 const void *value,
+						 const u32 length)
 {
 	rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
 				      USB_VENDOR_REQUEST_OUT, offset,
-				      value, length,
+				      (void *)value, length,
 				      REGISTER_TIMEOUT32(length));
 }
 
@@ -364,7 +361,7 @@ static inline void rt2x00usb_register_mu
  */
 int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
 			   const unsigned int offset,
-			   struct rt2x00_field32 field,
+			   const struct rt2x00_field32 field,
 			   u32 *reg);
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt61pci.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 14:03:30.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 12:11:05.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable har
  * These indirect registers work with busy bits,
  * and we will try maximal REGISTER_BUSY_COUNT times to access
  * the register while taking a REGISTER_BUSY_DELAY us delay
- * between each attampt. When the busy bit is still set at that time,
+ * between each attempt. When the busy bit is still set at that time,
  * the access attempt is considered to have failed,
  * and we will print an error.
  */
@@ -386,7 +386,7 @@ static int rt61pci_config_shared_key(str
 		 * The driver does not support the IV/EIV generation
 		 * in hardware. However it doesn't support the IV/EIV
 		 * inside the ieee80211 frame either, but requires it
-		 * to be provided seperately for the descriptor.
+		 * to be provided separately for the descriptor.
 		 * rt2x00lib will cut the IV/EIV data out of all frames
 		 * given to us by mac80211, but we must tell mac80211
 		 * to generate the IV/EIV data.
@@ -397,7 +397,7 @@ static int rt61pci_config_shared_key(str
 	/*
 	 * SEC_CSR0 contains only single-bit fields to indicate
 	 * a particular key is valid. Because using the FIELD32()
-	 * defines directly will cause a lot of overhead we use
+	 * defines directly will cause a lot of overhead, we use
 	 * a calculation to determine the correct bit directly.
 	 */
 	mask = 1 << key->hw_key_idx;
@@ -425,11 +425,11 @@ static int rt61pci_config_pairwise_key(s
 		/*
 		 * rt2x00lib can't determine the correct free
 		 * key_idx for pairwise keys. We have 2 registers
-		 * with key valid bits. The goal is simple, read
-		 * the first register, if that is full move to
+		 * with key valid bits. The goal is simple: read
+		 * the first register. If that is full, move to
 		 * the next register.
-		 * When both registers are full, we drop the key,
-		 * otherwise we use the first invalid entry.
+		 * When both registers are full, we drop the key.
+		 * Otherwise, we use the first invalid entry.
 		 */
 		rt2x00pci_register_read(rt2x00dev, SEC_CSR2, &reg);
 		if (reg && reg == ~0) {
@@ -464,8 +464,8 @@ static int rt61pci_config_pairwise_key(s
 					      &addr_entry, sizeof(addr_entry));
 
 		/*
-		 * Enable pairwise lookup table for given BSS idx,
-		 * without this received frames will not be decrypted
+		 * Enable pairwise lookup table for given BSS idx.
+		 * Without this, received frames will not be decrypted
 		 * by the hardware.
 		 */
 		rt2x00pci_register_read(rt2x00dev, SEC_CSR4, &reg);
@@ -487,7 +487,7 @@ static int rt61pci_config_pairwise_key(s
 	/*
 	 * SEC_CSR2 and SEC_CSR3 contain only single-bit fields to indicate
 	 * a particular key is valid. Because using the FIELD32()
-	 * defines directly will cause a lot of overhead we use
+	 * defines directly will cause a lot of overhead, we use
 	 * a calculation to determine the correct bit directly.
 	 */
 	if (key->hw_key_idx < 32) {
@@ -556,7 +556,7 @@ static void rt61pci_config_intf(struct r
 	if (flags & CONFIG_UPDATE_TYPE) {
 		/*
 		 * Clear current synchronisation setup.
-		 * For the Beacon base registers we only need to clear
+		 * For the Beacon base registers, we only need to clear
 		 * the first byte since that byte contains the VALID and OWNER
 		 * bits which (when set to 0) will invalidate the entire beacon.
 		 */
@@ -1168,8 +1168,8 @@ static int rt61pci_check_firmware(struct
 		return FW_BAD_LENGTH;
 
 	/*
-	 * The last 2 bytes in the firmware array are the crc checksum itself,
-	 * this means that we should never pass those 2 bytes to the crc
+	 * The last 2 bytes in the firmware array are the crc checksum itself.
+	 * This means that we should never pass those 2 bytes to the crc
 	 * algorithm.
 	 */
 	fw_crc = (data[len - 2] << 8 | data[len - 1]);
@@ -1986,7 +1986,7 @@ static void rt61pci_fill_rxdone(struct q
 
 		/*
 		 * Hardware has stripped IV/EIV data from 802.11 frame during
-		 * decryption. It has provided the data seperately but rt2x00lib
+		 * decryption. It has provided the data separately but rt2x00lib
 		 * should decide if it should be reinserted.
 		 */
 		rxdesc->flags |= RX_FLAG_IV_STRIPPED;
@@ -2042,7 +2042,7 @@ static void rt61pci_txdone(struct rt2x00
 	 * During each loop we will compare the freshly read
 	 * STA_CSR4 register value with the value read from
 	 * the previous loop. If the 2 values are equal then
-	 * we should stop processing because the chance it
+	 * we should stop processing because the chance is
 	 * quite big that the device has been unplugged and
 	 * we risk going into an endless loop.
 	 */
@@ -2300,6 +2300,7 @@ static int rt61pci_init_eeprom(struct rt
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip_rf(rt2x00dev, value, reg);
+	rt2x00_print_chip(rt2x00dev);
 
 	if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
 	    !rt2x00_rf(&rt2x00dev->chip, RF5325) &&
@@ -2330,7 +2331,7 @@ static int rt61pci_init_eeprom(struct rt
 		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 
 	/*
-	 * Detect if this device has an hardware controlled radio.
+	 * Detect if this device has a hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
@@ -2355,7 +2356,7 @@ static int rt61pci_init_eeprom(struct rt
 		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
 
 	/*
-	 * When working with a RF2529 chip without double antenna
+	 * When working with a RF2529 chip without double antenna,
 	 * the antenna settings should be gathered from the NIC
 	 * eeprom word.
 	 */
@@ -2538,6 +2539,11 @@ static int rt61pci_probe_hw_mode(struct
 	unsigned int i;
 
 	/*
+	 * Disable powersaving as default.
+	 */
+	rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	/*
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags =
@@ -2545,7 +2551,6 @@ static int rt61pci_probe_hw_mode(struct
 	    IEEE80211_HW_SIGNAL_DBM |
 	    IEEE80211_HW_SUPPORTS_PS |
 	    IEEE80211_HW_PS_NULLFUNC_STACK;
-	rt2x00dev->hw->extra_tx_headroom = 0;
 
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2668,7 +2673,7 @@ static int rt61pci_conf_tx(struct ieee80
 
 	/*
 	 * We only need to perform additional register initialization
-	 * for WMM queues/
+	 * for WMM queues.
 	 */
 	if (queue_idx >= 4)
 		return 0;
@@ -2787,19 +2792,20 @@ static const struct data_queue_desc rt61
 };
 
 static const struct rt2x00_ops rt61pci_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 4,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt61pci_queue_rx,
-	.tx		= &rt61pci_queue_tx,
-	.bcn		= &rt61pci_queue_bcn,
-	.lib		= &rt61pci_rt2x00_ops,
-	.hw		= &rt61pci_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 4,
+	.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,
+	.lib			= &rt61pci_rt2x00_ops,
+	.hw			= &rt61pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt61pci_rt2x00debug,
+	.debugfs		= &rt61pci_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt61pci.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 14:03:27.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 12:11:03.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt73usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 14:03:35.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 12:11:10.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -1825,6 +1825,7 @@ static int rt73usb_init_eeprom(struct rt
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
 	rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
+	rt2x00_print_chip(rt2x00dev);
 
 	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
 	    rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
@@ -2068,7 +2069,6 @@ static int rt73usb_probe_hw_mode(struct
 	    IEEE80211_HW_SIGNAL_DBM |
 	    IEEE80211_HW_SUPPORTS_PS |
 	    IEEE80211_HW_PS_NULLFUNC_STACK;
-	rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
 
 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2305,19 +2305,20 @@ static const struct data_queue_desc rt73
 };
 
 static const struct rt2x00_ops rt73usb_ops = {
-	.name		= KBUILD_MODNAME,
-	.max_sta_intf	= 1,
-	.max_ap_intf	= 4,
-	.eeprom_size	= EEPROM_SIZE,
-	.rf_size	= RF_SIZE,
-	.tx_queues	= NUM_TX_QUEUES,
-	.rx		= &rt73usb_queue_rx,
-	.tx		= &rt73usb_queue_tx,
-	.bcn		= &rt73usb_queue_bcn,
-	.lib		= &rt73usb_rt2x00_ops,
-	.hw		= &rt73usb_mac80211_ops,
+	.name			= KBUILD_MODNAME,
+	.max_sta_intf		= 1,
+	.max_ap_intf		= 4,
+	.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,
+	.lib			= &rt73usb_rt2x00_ops,
+	.hw			= &rt73usb_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs	= &rt73usb_rt2x00debug,
+	.debugfs		= &rt73usb_rt2x00debug,
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt73usb.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 14:03:32.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 12:11:08.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
 
 /*
  * Signal information.
- * Defaul offset is required for RSSI <-> dBm conversion.
+ * Default offset is required for RSSI <-> dBm conversion.
  */
 #define DEFAULT_RSSI_OFFSET		120
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8180_dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -132,7 +132,6 @@ static void rtl8180_handle_rx(struct iee
 
 			rx_status.antenna = (flags2 >> 15) & 1;
 			/* TODO: improve signal/rssi reporting */
-			rx_status.qual = flags2 & 0xFF;
 			rx_status.signal = (flags2 >> 8) & 0x7F;
 			/* XXX: is this correct? */
 			rx_status.rate_idx = (flags >> 20) & 0xF;
@@ -548,7 +547,7 @@ static int rtl8180_start(struct ieee8021
 	rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
 	rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
 
-	ret = request_irq(priv->pdev->irq, &rtl8180_interrupt,
+	ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
 			  IRQF_SHARED, KBUILD_MODNAME, dev);
 	if (ret) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,6 +65,7 @@ static struct usb_device_id rtl8187_tabl
 	/* Sitecom */
 	{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
+	{USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B},
 	/* Sphairon Access Systems GmbH */
 	{USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
 	/* Dick Smith Electronics */
@@ -320,7 +321,6 @@ static void rtl8187_rx_cb(struct urb *ur
 	struct ieee80211_rx_status rx_status = { 0 };
 	int rate, signal;
 	u32 flags;
-	u32 quality;
 	unsigned long f;
 
 	spin_lock_irqsave(&priv->rx_queue.lock, f);
@@ -338,10 +338,9 @@ static void rtl8187_rx_cb(struct urb *ur
 			(typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
 		flags = le32_to_cpu(hdr->flags);
 		/* As with the RTL8187B below, the AGC is used to calculate
-		 * signal strength and quality. In this case, the scaling
+		 * signal strength. In this case, the scaling
 		 * constants are derived from the output of p54usb.
 		 */
-		quality = 130 - ((41 * hdr->agc) >> 6);
 		signal = -4 - ((27 * hdr->agc) >> 6);
 		rx_status.antenna = (hdr->signal >> 7) & 1;
 		rx_status.mactime = le64_to_cpu(hdr->mac_time);
@@ -354,23 +353,18 @@ static void rtl8187_rx_cb(struct urb *ur
 		 * In testing, none of these quantities show qualitative
 		 * agreement with AP signal strength, except for the AGC,
 		 * which is inversely proportional to the strength of the
-		 * signal. In the following, the quality and signal strength
-		 * are derived from the AGC. The arbitrary scaling constants
+		 * signal. In the following, the signal strength
+		 * is derived from the AGC. The arbitrary scaling constants
 		 * are chosen to make the results close to the values obtained
 		 * for a BCM4312 using b43 as the driver. The noise is ignored
 		 * for now.
 		 */
 		flags = le32_to_cpu(hdr->flags);
-		quality = 170 - hdr->agc;
 		signal = 14 - hdr->agc / 2;
 		rx_status.antenna = (hdr->rssi >> 7) & 1;
 		rx_status.mactime = le64_to_cpu(hdr->mac_time);
 	}
 
-	if (quality > 100)
-		quality = 100;
-	rx_status.qual = quality;
-	priv->quality = quality;
 	rx_status.signal = signal;
 	priv->signal = signal;
 	rate = (flags >> 20) & 0xF;
@@ -1329,6 +1323,7 @@ static int __devinit rtl8187_probe(struc
 	struct ieee80211_channel *channel;
 	const char *chip_name;
 	u16 txpwr, reg;
+	u16 product_id = le16_to_cpu(udev->descriptor.idProduct);
 	int err, i;
 
 	dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
@@ -1488,6 +1483,13 @@ static int __devinit rtl8187_probe(struc
 		(*channel++).hw_value = txpwr & 0xFF;
 		(*channel++).hw_value = txpwr >> 8;
 	}
+	/* Handle the differing rfkill GPIO bit in different models */
+	priv->rfkill_mask = RFKILL_MASK_8187_89_97;
+	if (product_id == 0x8197 || product_id == 0x8198) {
+		eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, &reg);
+		if (reg & 0xFF00)
+			priv->rfkill_mask = RFKILL_MASK_8198;
+	}
 
 	/*
 	 * XXX: Once this driver supports anything that requires
@@ -1516,9 +1518,9 @@ static int __devinit rtl8187_probe(struc
 	mutex_init(&priv->conf_mutex);
 	skb_queue_head_init(&priv->b_tx_status.queue);
 
-	printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n",
+	printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
 	       wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
-	       chip_name, priv->asic_rev, priv->rf->name);
+	       chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
 
 #ifdef CONFIG_RTL8187_LEDS
 	eeprom_93cx6_read(&eeprom, 0x3F, &reg);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #define RTL8187_EEPROM_TXPWR_CHAN_1	0x16	/* 3 channels */
 #define RTL8187_EEPROM_TXPWR_CHAN_6	0x1B	/* 2 channels */
 #define RTL8187_EEPROM_TXPWR_CHAN_4	0x3D	/* 2 channels */
+#define RTL8187_EEPROM_SELECT_GPIO	0x3B
 
 #define RTL8187_REQT_READ	0xC0
 #define RTL8187_REQT_WRITE	0x40
@@ -31,6 +32,9 @@
 
 #define RTL8187_MAX_RX		0x9C4
 
+#define RFKILL_MASK_8187_89_97	0x2
+#define RFKILL_MASK_8198	0x4
+
 struct rtl8187_rx_info {
 	struct urb *urb;
 	struct ieee80211_hw *dev;
@@ -104,6 +108,7 @@ struct rtl8187_priv {
 	struct delayed_work work;
 	struct ieee80211_hw *dev;
 #ifdef CONFIG_RTL8187_LEDS
+	struct rtl8187_led led_radio;
 	struct rtl8187_led led_tx;
 	struct rtl8187_led led_rx;
 	struct delayed_work led_on;
@@ -119,10 +124,10 @@ struct rtl8187_priv {
 	} hw_rev;
 	struct sk_buff_head rx_queue;
 	u8 signal;
-	u8 quality;
 	u8 noise;
 	u8 slot_time;
 	u8 aifsn[4];
+	u8 rfkill_mask;
 	struct {
 		__le64 buf;
 		struct sk_buff_head queue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,19 +105,36 @@ static void rtl8187_led_brightness_set(s
 	struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
 					       led_dev);
 	struct ieee80211_hw *hw = led->dev;
-	struct rtl8187_priv *priv = hw->priv;
+	struct rtl8187_priv *priv;
+	static bool radio_on;
 
-	if (brightness == LED_OFF) {
-		ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
-		/* The LED is off for 1/20 sec so that it just blinks. */
-		ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20);
-	} else
-		ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
+	if (!hw)
+		return;
+	priv = hw->priv;
+	if (led->is_radio) {
+		if (brightness == LED_FULL) {
+			ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
+			radio_on = true;
+		} else if (radio_on) {
+			radio_on = false;
+			cancel_delayed_work_sync(&priv->led_on);
+			ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
+		}
+	} else if (radio_on) {
+		if (brightness == LED_OFF) {
+			ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
+			/* The LED is off for 1/20 sec - it just blinks. */
+			ieee80211_queue_delayed_work(hw, &priv->led_on,
+						     HZ / 20);
+		} else
+			ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
+	}
 }
 
 static int rtl8187_register_led(struct ieee80211_hw *dev,
 				struct rtl8187_led *led, const char *name,
-				const char *default_trigger, u8 ledpin)
+				const char *default_trigger, u8 ledpin,
+				bool is_radio)
 {
 	int err;
 	struct rtl8187_priv *priv = dev->priv;
@@ -128,6 +145,7 @@ static int rtl8187_register_led(struct i
 		return -EINVAL;
 	led->dev = dev;
 	led->ledpin = ledpin;
+	led->is_radio = is_radio;
 	strncpy(led->name, name, sizeof(led->name));
 
 	led->led_dev.name = led->name;
@@ -145,7 +163,11 @@ static int rtl8187_register_led(struct i
 
 static void rtl8187_unregister_led(struct rtl8187_led *led)
 {
+	struct ieee80211_hw *hw = led->dev;
+	struct rtl8187_priv *priv = hw->priv;
+
 	led_classdev_unregister(&led->led_dev);
+	flush_delayed_work(&priv->led_off);
 	led->dev = NULL;
 }
 
@@ -183,33 +205,37 @@ void rtl8187_leds_init(struct ieee80211_
 	INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
 
 	snprintf(name, sizeof(name),
+		 "rtl8187-%s::radio", wiphy_name(dev->wiphy));
+	err = rtl8187_register_led(dev, &priv->led_radio, name,
+			 ieee80211_get_radio_led_name(dev), ledpin, true);
+	if (err)
+		return;
+
+	snprintf(name, sizeof(name),
 		 "rtl8187-%s::tx", wiphy_name(dev->wiphy));
 	err = rtl8187_register_led(dev, &priv->led_tx, name,
-			 ieee80211_get_tx_led_name(dev), ledpin);
+			 ieee80211_get_tx_led_name(dev), ledpin, false);
 	if (err)
-		goto error;
+		goto err_tx;
+
 	snprintf(name, sizeof(name),
 		 "rtl8187-%s::rx", wiphy_name(dev->wiphy));
 	err = rtl8187_register_led(dev, &priv->led_rx, name,
-			 ieee80211_get_rx_led_name(dev), ledpin);
-	if (!err) {
-		ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
+			 ieee80211_get_rx_led_name(dev), ledpin, false);
+	if (!err)
 		return;
-	}
-	/* registration of RX LED failed - unregister TX */
+
+	/* registration of RX LED failed - unregister */
 	rtl8187_unregister_led(&priv->led_tx);
-error:
-	/* If registration of either failed, cancel delayed work */
-	cancel_delayed_work_sync(&priv->led_off);
-	cancel_delayed_work_sync(&priv->led_on);
+err_tx:
+	rtl8187_unregister_led(&priv->led_radio);
 }
 
 void rtl8187_leds_exit(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
 
-	/* turn the LED off before exiting */
-	ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
+	rtl8187_unregister_led(&priv->led_radio);
 	rtl8187_unregister_led(&priv->led_rx);
 	rtl8187_unregister_led(&priv->led_tx);
 	cancel_delayed_work_sync(&priv->led_off);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_leds.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,8 @@ struct rtl8187_led {
 	u8 ledpin;
 	/* The unique name string for this LED device. */
 	char name[RTL8187_LED_MAX_NAME_LEN + 1];
+	/* If the LED is radio or tx/rx */
+	bool is_radio;
 };
 
 void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_rfkill.c linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/rtl818x/rtl8187_rfkill.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/rtl818x/rtl8187_rfkill.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,10 +25,10 @@ static bool rtl8187_is_radio_enabled(str
 	u8 gpio;
 
 	gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
-	rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask);
 	gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
 
-	return gpio & 0x02;
+	return gpio & priv->rfkill_mask;
 }
 
 void rtl8187_rfkill_init(struct ieee80211_hw *hw)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/strip.c linux-libre-2.6.33-gnu1/drivers/net/wireless/strip.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/strip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/strip.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2805 +0,0 @@
-/*
- * Copyright 1996 The Board of Trustees of The Leland Stanford
- * Junior University. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies.  Stanford University
- * makes no representations about the suitability of this
- * software for any purpose.  It is provided "as is" without
- * express or implied warranty.
- *
- * strip.c	This module implements Starmode Radio IP (STRIP)
- *		for kernel-based devices like TTY.  It interfaces between a
- *		raw TTY, and the kernel's INET protocol layers (via DDI).
- *
- * Version:	@(#)strip.c	1.3	July 1997
- *
- * Author:	Stuart Cheshire <cheshire@cs.stanford.edu>
- *
- * Fixes:	v0.9 12th Feb 1996 (SC)
- *		New byte stuffing (2+6 run-length encoding)
- *		New watchdog timer task
- *		New Protocol key (SIP0)
- *		
- *		v0.9.1 3rd March 1996 (SC)
- *		Changed to dynamic device allocation -- no more compile
- *		time (or boot time) limit on the number of STRIP devices.
- *		
- *		v0.9.2 13th March 1996 (SC)
- *		Uses arp cache lookups (but doesn't send arp packets yet)
- *		
- *		v0.9.3 17th April 1996 (SC)
- *		Fixed bug where STR_ERROR flag was getting set unneccessarily
- *		(causing otherwise good packets to be unneccessarily dropped)
- *		
- *		v0.9.4 27th April 1996 (SC)
- *		First attempt at using "&COMMAND" Starmode AT commands
- *		
- *		v0.9.5 29th May 1996 (SC)
- *		First attempt at sending (unicast) ARP packets
- *		
- *		v0.9.6 5th June 1996 (Elliot)
- *		Put "message level" tags in every "printk" statement
- *		
- *		v0.9.7 13th June 1996 (laik)
- *		Added support for the /proc fs
- *
- *              v0.9.8 July 1996 (Mema)
- *              Added packet logging
- *
- *              v1.0 November 1996 (SC)
- *              Fixed (severe) memory leaks in the /proc fs code
- *              Fixed race conditions in the logging code
- *
- *              v1.1 January 1997 (SC)
- *              Deleted packet logging (use tcpdump instead)
- *              Added support for Metricom Firmware v204 features
- *              (like message checksums)
- *
- *              v1.2 January 1997 (SC)
- *              Put portables list back in
- *
- *              v1.3 July 1997 (SC)
- *              Made STRIP driver set the radio's baud rate automatically.
- *              It is no longer necessarily to manually set the radio's
- *              rate permanently to 115200 -- the driver handles setting
- *              the rate automatically.
- */
-
-#ifdef MODULE
-static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR";
-#else
-static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
-#endif
-
-#define TICKLE_TIMERS 0
-#define EXT_COUNTERS 1
-
-
-/************************************************************************/
-/* Header files								*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-# include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/if_strip.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/rcupdate.h>
-#include <net/arp.h>
-#include <net/net_namespace.h>
-
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/time.h>
-#include <linux/jiffies.h>
-
-/************************************************************************/
-/* Useful structures and definitions					*/
-
-/*
- * A MetricomKey identifies the protocol being carried inside a Metricom
- * Starmode packet.
- */
-
-typedef union {
-	__u8 c[4];
-	__u32 l;
-} MetricomKey;
-
-/*
- * An IP address can be viewed as four bytes in memory (which is what it is) or as
- * a single 32-bit long (which is convenient for assignment, equality testing etc.)
- */
-
-typedef union {
-	__u8 b[4];
-	__u32 l;
-} IPaddr;
-
-/*
- * A MetricomAddressString is used to hold a printable representation of
- * a Metricom address.
- */
-
-typedef struct {
-	__u8 c[24];
-} MetricomAddressString;
-
-/* Encapsulation can expand packet of size x to 65/64x + 1
- * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>"
- *                           1 1   1-18  1  4         ?         1
- * eg.                     <CR>*0000-1234*SIP0<encaps payload><CR>
- * We allow 31 bytes for the stars, the key, the address and the <CR>s
- */
-#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)
-
-/*
- * A STRIP_Header is never really sent over the radio, but making a dummy
- * header for internal use within the kernel that looks like an Ethernet
- * header makes certain other software happier. For example, tcpdump
- * already understands Ethernet headers.
- */
-
-typedef struct {
-	MetricomAddress dst_addr;	/* Destination address, e.g. "0000-1234"   */
-	MetricomAddress src_addr;	/* Source address, e.g. "0000-5678"        */
-	unsigned short protocol;	/* The protocol type, using Ethernet codes */
-} STRIP_Header;
-
-typedef struct {
-	char c[60];
-} MetricomNode;
-
-#define NODE_TABLE_SIZE 32
-typedef struct {
-	struct timeval timestamp;
-	int num_nodes;
-	MetricomNode node[NODE_TABLE_SIZE];
-} MetricomNodeTable;
-
-enum { FALSE = 0, TRUE = 1 };
-
-/*
- * Holds the radio's firmware version.
- */
-typedef struct {
-	char c[50];
-} FirmwareVersion;
-
-/*
- * Holds the radio's serial number.
- */
-typedef struct {
-	char c[18];
-} SerialNumber;
-
-/*
- * Holds the radio's battery voltage.
- */
-typedef struct {
-	char c[11];
-} BatteryVoltage;
-
-typedef struct {
-	char c[8];
-} char8;
-
-enum {
-	NoStructure = 0,	/* Really old firmware */
-	StructuredMessages = 1,	/* Parsable AT response msgs */
-	ChecksummedMessages = 2	/* Parsable AT response msgs with checksums */
-};
-
-struct strip {
-	int magic;
-	/*
-	 * These are pointers to the malloc()ed frame buffers.
-	 */
-
-	unsigned char *rx_buff;	/* buffer for received IP packet */
-	unsigned char *sx_buff;	/* buffer for received serial data */
-	int sx_count;		/* received serial data counter */
-	int sx_size;		/* Serial buffer size           */
-	unsigned char *tx_buff;	/* transmitter buffer           */
-	unsigned char *tx_head;	/* pointer to next byte to XMIT */
-	int tx_left;		/* bytes left in XMIT queue     */
-	int tx_size;		/* Serial buffer size           */
-
-	/*
-	 * STRIP interface statistics.
-	 */
-
-	unsigned long rx_packets;	/* inbound frames counter       */
-	unsigned long tx_packets;	/* outbound frames counter      */
-	unsigned long rx_errors;	/* Parity, etc. errors          */
-	unsigned long tx_errors;	/* Planned stuff                */
-	unsigned long rx_dropped;	/* No memory for skb            */
-	unsigned long tx_dropped;	/* When MTU change              */
-	unsigned long rx_over_errors;	/* Frame bigger than STRIP buf. */
-
-	unsigned long pps_timer;	/* Timer to determine pps       */
-	unsigned long rx_pps_count;	/* Counter to determine pps     */
-	unsigned long tx_pps_count;	/* Counter to determine pps     */
-	unsigned long sx_pps_count;	/* Counter to determine pps     */
-	unsigned long rx_average_pps;	/* rx packets per second * 8    */
-	unsigned long tx_average_pps;	/* tx packets per second * 8    */
-	unsigned long sx_average_pps;	/* sent packets per second * 8  */
-
-#ifdef EXT_COUNTERS
-	unsigned long rx_bytes;		/* total received bytes */
-	unsigned long tx_bytes;		/* total received bytes */
-	unsigned long rx_rbytes;	/* bytes thru radio i/f */
-	unsigned long tx_rbytes;	/* bytes thru radio i/f */
-	unsigned long rx_sbytes;	/* tot bytes thru serial i/f */
-	unsigned long tx_sbytes;	/* tot bytes thru serial i/f */
-	unsigned long rx_ebytes;	/* tot stat/err bytes */
-	unsigned long tx_ebytes;	/* tot stat/err bytes */
-#endif
-
-	/*
-	 * Internal variables.
-	 */
-
-	struct list_head  list;		/* Linked list of devices */
-
-	int discard;			/* Set if serial error          */
-	int working;			/* Is radio working correctly?  */
-	int firmware_level;		/* Message structuring level    */
-	int next_command;		/* Next periodic command        */
-	unsigned int user_baud;		/* The user-selected baud rate  */
-	int mtu;			/* Our mtu (to spot changes!)   */
-	long watchdog_doprobe;		/* Next time to test the radio  */
-	long watchdog_doreset;		/* Time to do next reset        */
-	long gratuitous_arp;		/* Time to send next ARP refresh */
-	long arp_interval;		/* Next ARP interval            */
-	struct timer_list idle_timer;	/* For periodic wakeup calls    */
-	MetricomAddress true_dev_addr;	/* True address of radio        */
-	int manual_dev_addr;		/* Hack: See note below         */
-
-	FirmwareVersion firmware_version;	/* The radio's firmware version */
-	SerialNumber serial_number;	/* The radio's serial number    */
-	BatteryVoltage battery_voltage;	/* The radio's battery voltage  */
-
-	/*
-	 * Other useful structures.
-	 */
-
-	struct tty_struct *tty;		/* ptr to TTY structure         */
-	struct net_device *dev;		/* Our device structure         */
-
-	/*
-	 * Neighbour radio records
-	 */
-
-	MetricomNodeTable portables;
-	MetricomNodeTable poletops;
-};
-
-/*
- * Note: manual_dev_addr hack
- * 
- * It is not possible to change the hardware address of a Metricom radio,
- * or to send packets with a user-specified hardware source address, thus
- * trying to manually set a hardware source address is a questionable
- * thing to do.  However, if the user *does* manually set the hardware
- * source address of a STRIP interface, then the kernel will believe it,
- * and use it in certain places. For example, the hardware address listed
- * by ifconfig will be the manual address, not the true one.
- * (Both addresses are listed in /proc/net/strip.)
- * Also, ARP packets will be sent out giving the user-specified address as
- * the source address, not the real address. This is dangerous, because
- * it means you won't receive any replies -- the ARP replies will go to
- * the specified address, which will be some other radio. The case where
- * this is useful is when that other radio is also connected to the same
- * machine. This allows you to connect a pair of radios to one machine,
- * and to use one exclusively for inbound traffic, and the other
- * exclusively for outbound traffic. Pretty neat, huh?
- * 
- * Here's the full procedure to set this up:
- * 
- * 1. "slattach" two interfaces, e.g. st0 for outgoing packets,
- *    and st1 for incoming packets
- * 
- * 2. "ifconfig" st0 (outbound radio) to have the hardware address
- *    which is the real hardware address of st1 (inbound radio).
- *    Now when it sends out packets, it will masquerade as st1, and
- *    replies will be sent to that radio, which is exactly what we want.
- * 
- * 3. Set the route table entry ("route add default ..." or
- *    "route add -net ...", as appropriate) to send packets via the st0
- *    interface (outbound radio). Do not add any route which sends packets
- *    out via the st1 interface -- that radio is for inbound traffic only.
- * 
- * 4. "ifconfig" st1 (inbound radio) to have hardware address zero.
- *    This tells the STRIP driver to "shut down" that interface and not
- *    send any packets through it. In particular, it stops sending the
- *    periodic gratuitous ARP packets that a STRIP interface normally sends.
- *    Also, when packets arrive on that interface, it will search the
- *    interface list to see if there is another interface who's manual
- *    hardware address matches its own real address (i.e. st0 in this
- *    example) and if so it will transfer ownership of the skbuff to
- *    that interface, so that it looks to the kernel as if the packet
- *    arrived on that interface. This is necessary because when the
- *    kernel sends an ARP packet on st0, it expects to get a reply on
- *    st0, and if it sees the reply come from st1 then it will ignore
- *    it (to be accurate, it puts the entry in the ARP table, but
- *    labelled in such a way that st0 can't use it).
- * 
- * Thanks to Petros Maniatis for coming up with the idea of splitting
- * inbound and outbound traffic between two interfaces, which turned
- * out to be really easy to implement, even if it is a bit of a hack.
- * 
- * Having set a manual address on an interface, you can restore it
- * to automatic operation (where the address is automatically kept
- * consistent with the real address of the radio) by setting a manual
- * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF"
- * This 'turns off' manual override mode for the device address.
- * 
- * Note: The IEEE 802 headers reported in tcpdump will show the *real*
- * radio addresses the packets were sent and received from, so that you
- * can see what is really going on with packets, and which interfaces
- * they are really going through.
- */
-
-
-/************************************************************************/
-/* Constants								*/
-
-/*
- * CommandString1 works on all radios
- * Other CommandStrings are only used with firmware that provides structured responses.
- * 
- * ats319=1 Enables Info message for node additions and deletions
- * ats319=2 Enables Info message for a new best node
- * ats319=4 Enables checksums
- * ats319=8 Enables ACK messages
- */
-
-static const int MaxCommandStringLength = 32;
-static const int CompatibilityCommand = 1;
-
-static const char CommandString0[] = "*&COMMAND*ATS319=7";	/* Turn on checksums & info messages */
-static const char CommandString1[] = "*&COMMAND*ATS305?";	/* Query radio name */
-static const char CommandString2[] = "*&COMMAND*ATS325?";	/* Query battery voltage */
-static const char CommandString3[] = "*&COMMAND*ATS300?";	/* Query version information */
-static const char CommandString4[] = "*&COMMAND*ATS311?";	/* Query poletop list */
-static const char CommandString5[] = "*&COMMAND*AT~LA";		/* Query portables list */
-typedef struct {
-	const char *string;
-	long length;
-} StringDescriptor;
-
-static const StringDescriptor CommandString[] = {
-	{CommandString0, sizeof(CommandString0) - 1},
-	{CommandString1, sizeof(CommandString1) - 1},
-	{CommandString2, sizeof(CommandString2) - 1},
-	{CommandString3, sizeof(CommandString3) - 1},
-	{CommandString4, sizeof(CommandString4) - 1},
-	{CommandString5, sizeof(CommandString5) - 1}
-};
-
-#define GOT_ALL_RADIO_INFO(S)      \
-    ((S)->firmware_version.c[0] && \
-     (S)->battery_voltage.c[0]  && \
-     memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address)))
-
-static const char hextable[16] = "0123456789ABCDEF";
-
-static const MetricomAddress zero_address;
-static const MetricomAddress broadcast_address =
-    { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
-
-static const MetricomKey SIP0Key = { "SIP0" };
-static const MetricomKey ARP0Key = { "ARP0" };
-static const MetricomKey ATR_Key = { "ATR " };
-static const MetricomKey ACK_Key = { "ACK_" };
-static const MetricomKey INF_Key = { "INF_" };
-static const MetricomKey ERR_Key = { "ERR_" };
-
-static const long MaxARPInterval = 60 * HZ;	/* One minute */
-
-/*
- * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for
- * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion
- * for STRIP encoding, that translates to a maximum payload MTU of 1155.
- * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes
- * long, including IP header, UDP header, and NFS header. Setting the STRIP
- * MTU to 1152 allows us to send default sized NFS packets without fragmentation.
- */
-static const unsigned short MAX_SEND_MTU = 1152;
-static const unsigned short MAX_RECV_MTU = 1500;	/* Hoping for Ethernet sized packets in the future! */
-static const unsigned short DEFAULT_STRIP_MTU = 1152;
-static const int STRIP_MAGIC = 0x5303;
-static const long LongTime = 0x7FFFFFFF;
-
-/************************************************************************/
-/* Global variables							*/
-
-static LIST_HEAD(strip_list);
-static DEFINE_SPINLOCK(strip_lock);
-
-/************************************************************************/
-/* Macros								*/
-
-/* Returns TRUE if text T begins with prefix P */
-#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))
-
-/* Returns TRUE if text T of length L is equal to string S */
-#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))
-
-#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' :      \
-                    (X)>='a' && (X)<='f' ? (X)-'a'+10 :   \
-                    (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 )
-
-#define READHEX16(X) ((__u16)(READHEX(X)))
-
-#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0)
-
-#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
-
-#define JIFFIE_TO_SEC(X) ((X) / HZ)
-
-
-/************************************************************************/
-/* Utility routines							*/
-
-static int arp_query(unsigned char *haddr, u32 paddr,
-		     struct net_device *dev)
-{
-	struct neighbour *neighbor_entry;
-	int ret = 0;
-
-	neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
-
-	if (neighbor_entry != NULL) {
-		neighbor_entry->used = jiffies;
-		if (neighbor_entry->nud_state & NUD_VALID) {
-			memcpy(haddr, neighbor_entry->ha, dev->addr_len);
-			ret = 1;
-		}
-		neigh_release(neighbor_entry);
-	}
-	return ret;
-}
-
-static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,
-		     __u8 * end)
-{
-	static const int MAX_DumpData = 80;
-	__u8 pkt_text[MAX_DumpData], *p = pkt_text;
-
-	*p++ = '\"';
-
-	while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) {
-		if (*ptr == '\\') {
-			*p++ = '\\';
-			*p++ = '\\';
-		} else {
-			if (*ptr >= 32 && *ptr <= 126) {
-				*p++ = *ptr;
-			} else {
-				sprintf(p, "\\%02X", *ptr);
-				p += 3;
-			}
-		}
-		ptr++;
-	}
-
-	if (ptr == end)
-		*p++ = '\"';
-	*p++ = 0;
-
-	printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text);
-}
-
-
-/************************************************************************/
-/* Byte stuffing/unstuffing routines					*/
-
-/* Stuffing scheme:
- * 00    Unused (reserved character)
- * 01-3F Run of 2-64 different characters
- * 40-7F Run of 1-64 different characters plus a single zero at the end
- * 80-BF Run of 1-64 of the same character
- * C0-FF Run of 1-64 zeroes (ASCII 0)
- */
-
-typedef enum {
-	Stuff_Diff = 0x00,
-	Stuff_DiffZero = 0x40,
-	Stuff_Same = 0x80,
-	Stuff_Zero = 0xC0,
-	Stuff_NoCode = 0xFF,	/* Special code, meaning no code selected */
-
-	Stuff_CodeMask = 0xC0,
-	Stuff_CountMask = 0x3F,
-	Stuff_MaxCount = 0x3F,
-	Stuff_Magic = 0x0D	/* The value we are eliminating */
-} StuffingCode;
-
-/* StuffData encodes the data starting at "src" for "length" bytes.
- * It writes it to the buffer pointed to by "dst" (which must be at least
- * as long as 1 + 65/64 of the input length). The output may be up to 1.6%
- * larger than the input for pathological input, but will usually be smaller.
- * StuffData returns the new value of the dst pointer as its result.
- * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state
- * between calls, allowing an encoded packet to be incrementally built up
- * from small parts. On the first call, the "__u8 *" pointed to should be
- * initialized to NULL; between subsequent calls the calling routine should
- * leave the value alone and simply pass it back unchanged so that the
- * encoder can recover its current state.
- */
-
-#define StuffData_FinishBlock(X) \
-(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)
-
-static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst,
-		       __u8 ** code_ptr_ptr)
-{
-	__u8 *end = src + length;
-	__u8 *code_ptr = *code_ptr_ptr;
-	__u8 code = Stuff_NoCode, count = 0;
-
-	if (!length)
-		return (dst);
-
-	if (code_ptr) {
-		/*
-		 * Recover state from last call, if applicable
-		 */
-		code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
-		count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
-	}
-
-	while (src < end) {
-		switch (code) {
-			/* Stuff_NoCode: If no current code, select one */
-		case Stuff_NoCode:
-			/* Record where we're going to put this code */
-			code_ptr = dst++;
-			count = 0;	/* Reset the count (zero means one instance) */
-			/* Tentatively start a new block */
-			if (*src == 0) {
-				code = Stuff_Zero;
-				src++;
-			} else {
-				code = Stuff_Same;
-				*dst++ = *src++ ^ Stuff_Magic;
-			}
-			/* Note: We optimistically assume run of same -- */
-			/* which will be fixed later in Stuff_Same */
-			/* if it turns out not to be true. */
-			break;
-
-			/* Stuff_Zero: We already have at least one zero encoded */
-		case Stuff_Zero:
-			/* If another zero, count it, else finish this code block */
-			if (*src == 0) {
-				count++;
-				src++;
-			} else {
-				StuffData_FinishBlock(Stuff_Zero + count);
-			}
-			break;
-
-			/* Stuff_Same: We already have at least one byte encoded */
-		case Stuff_Same:
-			/* If another one the same, count it */
-			if ((*src ^ Stuff_Magic) == code_ptr[1]) {
-				count++;
-				src++;
-				break;
-			}
-			/* else, this byte does not match this block. */
-			/* If we already have two or more bytes encoded, finish this code block */
-			if (count) {
-				StuffData_FinishBlock(Stuff_Same + count);
-				break;
-			}
-			/* else, we only have one so far, so switch to Stuff_Diff code */
-			code = Stuff_Diff;
-			/* and fall through to Stuff_Diff case below
-			 * Note cunning cleverness here: case Stuff_Diff compares 
-			 * the current character with the previous two to see if it
-			 * has a run of three the same. Won't this be an error if
-			 * there aren't two previous characters stored to compare with?
-			 * No. Because we know the current character is *not* the same
-			 * as the previous one, the first test below will necessarily
-			 * fail and the send half of the "if" won't be executed.
-			 */
-
-			/* Stuff_Diff: We have at least two *different* bytes encoded */
-		case Stuff_Diff:
-			/* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */
-			if (*src == 0) {
-				StuffData_FinishBlock(Stuff_DiffZero +
-						      count);
-			}
-			/* else, if we have three in a row, it is worth starting a Stuff_Same block */
-			else if ((*src ^ Stuff_Magic) == dst[-1]
-				 && dst[-1] == dst[-2]) {
-				/* Back off the last two characters we encoded */
-				code += count - 2;
-				/* Note: "Stuff_Diff + 0" is an illegal code */
-				if (code == Stuff_Diff + 0) {
-					code = Stuff_Same + 0;
-				}
-				StuffData_FinishBlock(code);
-				code_ptr = dst - 2;
-				/* dst[-1] already holds the correct value */
-				count = 2;	/* 2 means three bytes encoded */
-				code = Stuff_Same;
-			}
-			/* else, another different byte, so add it to the block */
-			else {
-				*dst++ = *src ^ Stuff_Magic;
-				count++;
-			}
-			src++;	/* Consume the byte */
-			break;
-		}
-		if (count == Stuff_MaxCount) {
-			StuffData_FinishBlock(code + count);
-		}
-	}
-	if (code == Stuff_NoCode) {
-		*code_ptr_ptr = NULL;
-	} else {
-		*code_ptr_ptr = code_ptr;
-		StuffData_FinishBlock(code + count);
-	}
-	return (dst);
-}
-
-/*
- * UnStuffData decodes the data at "src", up to (but not including) "end".
- * It writes the decoded data into the buffer pointed to by "dst", up to a
- * maximum of "dst_length", and returns the new value of "src" so that a
- * follow-on call can read more data, continuing from where the first left off.
- * 
- * There are three types of results:
- * 1. The source data runs out before extracting "dst_length" bytes:
- *    UnStuffData returns NULL to indicate failure.
- * 2. The source data produces exactly "dst_length" bytes:
- *    UnStuffData returns new_src = end to indicate that all bytes were consumed.
- * 3. "dst_length" bytes are extracted, with more remaining.
- *    UnStuffData returns new_src < end to indicate that there are more bytes
- *    to be read.
- * 
- * Note: The decoding may be destructive, in that it may alter the source
- * data in the process of decoding it (this is necessary to allow a follow-on
- * call to resume correctly).
- */
-
-static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
-			 __u32 dst_length)
-{
-	__u8 *dst_end = dst + dst_length;
-	/* Sanity check */
-	if (!src || !end || !dst || !dst_length)
-		return (NULL);
-	while (src < end && dst < dst_end) {
-		int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
-		switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) {
-		case Stuff_Diff:
-			if (src + 1 + count >= end)
-				return (NULL);
-			do {
-				*dst++ = *++src ^ Stuff_Magic;
-			}
-			while (--count >= 0 && dst < dst_end);
-			if (count < 0)
-				src += 1;
-			else {
-				if (count == 0)
-					*src = Stuff_Same ^ Stuff_Magic;
-				else
-					*src =
-					    (Stuff_Diff +
-					     count) ^ Stuff_Magic;
-			}
-			break;
-		case Stuff_DiffZero:
-			if (src + 1 + count >= end)
-				return (NULL);
-			do {
-				*dst++ = *++src ^ Stuff_Magic;
-			}
-			while (--count >= 0 && dst < dst_end);
-			if (count < 0)
-				*src = Stuff_Zero ^ Stuff_Magic;
-			else
-				*src =
-				    (Stuff_DiffZero + count) ^ Stuff_Magic;
-			break;
-		case Stuff_Same:
-			if (src + 1 >= end)
-				return (NULL);
-			do {
-				*dst++ = src[1] ^ Stuff_Magic;
-			}
-			while (--count >= 0 && dst < dst_end);
-			if (count < 0)
-				src += 2;
-			else
-				*src = (Stuff_Same + count) ^ Stuff_Magic;
-			break;
-		case Stuff_Zero:
-			do {
-				*dst++ = 0;
-			}
-			while (--count >= 0 && dst < dst_end);
-			if (count < 0)
-				src += 1;
-			else
-				*src = (Stuff_Zero + count) ^ Stuff_Magic;
-			break;
-		}
-	}
-	if (dst < dst_end)
-		return (NULL);
-	else
-		return (src);
-}
-
-
-/************************************************************************/
-/* General routines for STRIP						*/
-
-/*
- * set_baud sets the baud rate to the rate defined by baudcode
- */
-static void set_baud(struct tty_struct *tty, speed_t baudrate)
-{
-	struct ktermios old_termios;
-
-	mutex_lock(&tty->termios_mutex);
-	old_termios =*(tty->termios);
-	tty_encode_baud_rate(tty, baudrate, baudrate);
-	tty->ops->set_termios(tty, &old_termios);
-	mutex_unlock(&tty->termios_mutex);
-}
-
-/*
- * Convert a string to a Metricom Address.
- */
-
-#define IS_RADIO_ADDRESS(p) (                                                 \
-  isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \
-  (p)[4] == '-' &&                                                            \
-  isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8])    )
-
-static int string_to_radio_address(MetricomAddress * addr, __u8 * p)
-{
-	if (!IS_RADIO_ADDRESS(p))
-		return (1);
-	addr->c[0] = 0;
-	addr->c[1] = 0;
-	addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]);
-	addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]);
-	addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]);
-	addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]);
-	return (0);
-}
-
-/*
- * Convert a Metricom Address to a string.
- */
-
-static __u8 *radio_address_to_string(const MetricomAddress * addr,
-				     MetricomAddressString * p)
-{
-	sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3],
-		addr->c[4], addr->c[5]);
-	return (p->c);
-}
-
-/*
- * Note: Must make sure sx_size is big enough to receive a stuffed
- * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's
- * big enough to receive a large radio neighbour list (currently 4K).
- */
-
-static int allocate_buffers(struct strip *strip_info, int mtu)
-{
-	struct net_device *dev = strip_info->dev;
-	int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096);
-	int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength;
-	__u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC);
-	__u8 *s = kmalloc(sx_size, GFP_ATOMIC);
-	__u8 *t = kmalloc(tx_size, GFP_ATOMIC);
-	if (r && s && t) {
-		strip_info->rx_buff = r;
-		strip_info->sx_buff = s;
-		strip_info->tx_buff = t;
-		strip_info->sx_size = sx_size;
-		strip_info->tx_size = tx_size;
-		strip_info->mtu = dev->mtu = mtu;
-		return (1);
-	}
-	kfree(r);
-	kfree(s);
-	kfree(t);
-	return (0);
-}
-
-/*
- * MTU has been changed by the IP layer. 
- * We could be in
- * an upcall from the tty driver, or in an ip packet queue.
- */
-static int strip_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct strip *strip_info = netdev_priv(dev);
-	int old_mtu = strip_info->mtu;
-	unsigned char *orbuff = strip_info->rx_buff;
-	unsigned char *osbuff = strip_info->sx_buff;
-	unsigned char *otbuff = strip_info->tx_buff;
-
-	if (new_mtu > MAX_SEND_MTU) {
-		printk(KERN_ERR
-		       "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n",
-		       strip_info->dev->name, MAX_SEND_MTU);
-		return -EINVAL;
-	}
-
-	spin_lock_bh(&strip_lock);
-	if (!allocate_buffers(strip_info, new_mtu)) {
-		printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
-		       strip_info->dev->name);
-		spin_unlock_bh(&strip_lock);
-		return -ENOMEM;
-	}
-
-	if (strip_info->sx_count) {
-		if (strip_info->sx_count <= strip_info->sx_size)
-			memcpy(strip_info->sx_buff, osbuff,
-			       strip_info->sx_count);
-		else {
-			strip_info->discard = strip_info->sx_count;
-			strip_info->rx_over_errors++;
-		}
-	}
-
-	if (strip_info->tx_left) {
-		if (strip_info->tx_left <= strip_info->tx_size)
-			memcpy(strip_info->tx_buff, strip_info->tx_head,
-			       strip_info->tx_left);
-		else {
-			strip_info->tx_left = 0;
-			strip_info->tx_dropped++;
-		}
-	}
-	strip_info->tx_head = strip_info->tx_buff;
-	spin_unlock_bh(&strip_lock);
-
-	printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
-	       strip_info->dev->name, old_mtu, strip_info->mtu);
-
-	kfree(orbuff);
-	kfree(osbuff);
-	kfree(otbuff);
-	return 0;
-}
-
-static void strip_unlock(struct strip *strip_info)
-{
-	/*
-	 * Set the timer to go off in one second.
-	 */
-	strip_info->idle_timer.expires = jiffies + 1 * HZ;
-	add_timer(&strip_info->idle_timer);
-	netif_wake_queue(strip_info->dev);
-}
-
-
-
-/*
- * If the time is in the near future, time_delta prints the number of
- * seconds to go into the buffer and returns the address of the buffer.
- * If the time is not in the near future, it returns the address of the
- * string "Not scheduled" The buffer must be long enough to contain the
- * ascii representation of the number plus 9 charactes for the " seconds"
- * and the null character.
- */
-#ifdef CONFIG_PROC_FS
-static char *time_delta(char buffer[], long time)
-{
-	time -= jiffies;
-	if (time > LongTime / 2)
-		return ("Not scheduled");
-	if (time < 0)
-		time = 0;	/* Don't print negative times */
-	sprintf(buffer, "%ld seconds", time / HZ);
-	return (buffer);
-}
-
-/* get Nth element of the linked list */
-static struct strip *strip_get_idx(loff_t pos) 
-{
-	struct strip *str;
-	int i = 0;
-
-	list_for_each_entry_rcu(str, &strip_list, list) {
-		if (pos == i)
-			return str;
-		++i;
-	}
-	return NULL;
-}
-
-static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(RCU)
-{
-	rcu_read_lock();
-	return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
-}
-
-static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	struct list_head *l;
-	struct strip *s;
-
-	++*pos;
-	if (v == SEQ_START_TOKEN)
-		return strip_get_idx(1);
-
-	s = v;
-	l = &s->list;
-	list_for_each_continue_rcu(l, &strip_list) {
-		return list_entry(l, struct strip, list);
-	}
-	return NULL;
-}
-
-static void strip_seq_stop(struct seq_file *seq, void *v)
-	__releases(RCU)
-{
-	rcu_read_unlock();
-}
-
-static void strip_seq_neighbours(struct seq_file *seq,
-			   const MetricomNodeTable * table,
-			   const char *title)
-{
-	/* We wrap this in a do/while loop, so if the table changes */
-	/* while we're reading it, we just go around and try again. */
-	struct timeval t;
-
-	do {
-		int i;
-		t = table->timestamp;
-		if (table->num_nodes)
-			seq_printf(seq, "\n %s\n", title);
-		for (i = 0; i < table->num_nodes; i++) {
-			MetricomNode node;
-
-			spin_lock_bh(&strip_lock);
-			node = table->node[i];
-			spin_unlock_bh(&strip_lock);
-			seq_printf(seq, "  %s\n", node.c);
-		}
-	} while (table->timestamp.tv_sec != t.tv_sec
-		 || table->timestamp.tv_usec != t.tv_usec);
-}
-
-/*
- * This function prints radio status information via the seq_file
- * interface.  The interface takes care of buffer size and over
- * run issues. 
- *
- * The buffer in seq_file is PAGESIZE (4K) 
- * so this routine should never print more or it will get truncated.
- * With the maximum of 32 portables and 32 poletops
- * reported, the routine outputs 3107 bytes into the buffer.
- */
-static void strip_seq_status_info(struct seq_file *seq, 
-				  const struct strip *strip_info)
-{
-	char temp[32];
-	MetricomAddressString addr_string;
-
-	/* First, we must copy all of our data to a safe place, */
-	/* in case a serial interrupt comes in and changes it.  */
-	int tx_left = strip_info->tx_left;
-	unsigned long rx_average_pps = strip_info->rx_average_pps;
-	unsigned long tx_average_pps = strip_info->tx_average_pps;
-	unsigned long sx_average_pps = strip_info->sx_average_pps;
-	int working = strip_info->working;
-	int firmware_level = strip_info->firmware_level;
-	long watchdog_doprobe = strip_info->watchdog_doprobe;
-	long watchdog_doreset = strip_info->watchdog_doreset;
-	long gratuitous_arp = strip_info->gratuitous_arp;
-	long arp_interval = strip_info->arp_interval;
-	FirmwareVersion firmware_version = strip_info->firmware_version;
-	SerialNumber serial_number = strip_info->serial_number;
-	BatteryVoltage battery_voltage = strip_info->battery_voltage;
-	char *if_name = strip_info->dev->name;
-	MetricomAddress true_dev_addr = strip_info->true_dev_addr;
-	MetricomAddress dev_dev_addr =
-	    *(MetricomAddress *) strip_info->dev->dev_addr;
-	int manual_dev_addr = strip_info->manual_dev_addr;
-#ifdef EXT_COUNTERS
-	unsigned long rx_bytes = strip_info->rx_bytes;
-	unsigned long tx_bytes = strip_info->tx_bytes;
-	unsigned long rx_rbytes = strip_info->rx_rbytes;
-	unsigned long tx_rbytes = strip_info->tx_rbytes;
-	unsigned long rx_sbytes = strip_info->rx_sbytes;
-	unsigned long tx_sbytes = strip_info->tx_sbytes;
-	unsigned long rx_ebytes = strip_info->rx_ebytes;
-	unsigned long tx_ebytes = strip_info->tx_ebytes;
-#endif
-
-	seq_printf(seq, "\nInterface name\t\t%s\n", if_name);
-	seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No");
-	radio_address_to_string(&true_dev_addr, &addr_string);
-	seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c);
-	if (manual_dev_addr) {
-		radio_address_to_string(&dev_dev_addr, &addr_string);
-		seq_printf(seq, " Device address:\t%s\n", addr_string.c);
-	}
-	seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" :
-		     !firmware_level ? "Should be upgraded" :
-		     firmware_version.c);
-	if (firmware_level >= ChecksummedMessages)
-		seq_printf(seq, " (Checksums Enabled)");
-	seq_printf(seq, "\n");
-	seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c);
-	seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c);
-	seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left);
-	seq_printf(seq, " Receive packet rate:   %ld packets per second\n",
-		     rx_average_pps / 8);
-	seq_printf(seq, " Transmit packet rate:  %ld packets per second\n",
-		     tx_average_pps / 8);
-	seq_printf(seq, " Sent packet rate:      %ld packets per second\n",
-		     sx_average_pps / 8);
-	seq_printf(seq, " Next watchdog probe:\t%s\n",
-		     time_delta(temp, watchdog_doprobe));
-	seq_printf(seq, " Next watchdog reset:\t%s\n",
-		     time_delta(temp, watchdog_doreset));
-	seq_printf(seq, " Next gratuitous ARP:\t");
-
-	if (!memcmp
-	    (strip_info->dev->dev_addr, zero_address.c,
-	     sizeof(zero_address)))
-		seq_printf(seq, "Disabled\n");
-	else {
-		seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp));
-		seq_printf(seq, " Next ARP interval:\t%ld seconds\n",
-			     JIFFIE_TO_SEC(arp_interval));
-	}
-
-	if (working) {
-#ifdef EXT_COUNTERS
-		seq_printf(seq, "\n");
-		seq_printf(seq,
-			     " Total bytes:         \trx:\t%lu\ttx:\t%lu\n",
-			     rx_bytes, tx_bytes);
-		seq_printf(seq,
-			     "  thru radio:         \trx:\t%lu\ttx:\t%lu\n",
-			     rx_rbytes, tx_rbytes);
-		seq_printf(seq,
-			     "  thru serial port:   \trx:\t%lu\ttx:\t%lu\n",
-			     rx_sbytes, tx_sbytes);
-		seq_printf(seq,
-			     " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n",
-			     rx_ebytes, tx_ebytes);
-#endif
-		strip_seq_neighbours(seq, &strip_info->poletops,
-					"Poletops:");
-		strip_seq_neighbours(seq, &strip_info->portables,
-					"Portables:");
-	}
-}
-
-/*
- * This function is exports status information from the STRIP driver through
- * the /proc file system.
- */
-static int strip_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN)
-		seq_printf(seq, "strip_version: %s\n", StripVersion);
-	else
-		strip_seq_status_info(seq, (const struct strip *)v);
-	return 0;
-}
-
-
-static const struct seq_operations strip_seq_ops = {
-	.start = strip_seq_start,
-	.next  = strip_seq_next,
-	.stop  = strip_seq_stop,
-	.show  = strip_seq_show,
-};
-
-static int strip_seq_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &strip_seq_ops);
-}
-
-static const struct file_operations strip_seq_fops = {
-	.owner	 = THIS_MODULE,
-	.open    = strip_seq_open,
-	.read    = seq_read,
-	.llseek  = seq_lseek,
-	.release = seq_release,
-};
-#endif
-
-
-
-/************************************************************************/
-/* Sending routines							*/
-
-static void ResetRadio(struct strip *strip_info)
-{
-	struct tty_struct *tty = strip_info->tty;
-	static const char init[] = "ate0q1dt**starmode\r**";
-	StringDescriptor s = { init, sizeof(init) - 1 };
-
-	/* 
-	 * If the radio isn't working anymore,
-	 * we should clear the old status information.
-	 */
-	if (strip_info->working) {
-		printk(KERN_INFO "%s: No response: Resetting radio.\n",
-		       strip_info->dev->name);
-		strip_info->firmware_version.c[0] = '\0';
-		strip_info->serial_number.c[0] = '\0';
-		strip_info->battery_voltage.c[0] = '\0';
-		strip_info->portables.num_nodes = 0;
-		do_gettimeofday(&strip_info->portables.timestamp);
-		strip_info->poletops.num_nodes = 0;
-		do_gettimeofday(&strip_info->poletops.timestamp);
-	}
-
-	strip_info->pps_timer = jiffies;
-	strip_info->rx_pps_count = 0;
-	strip_info->tx_pps_count = 0;
-	strip_info->sx_pps_count = 0;
-	strip_info->rx_average_pps = 0;
-	strip_info->tx_average_pps = 0;
-	strip_info->sx_average_pps = 0;
-
-	/* Mark radio address as unknown */
-	*(MetricomAddress *) & strip_info->true_dev_addr = zero_address;
-	if (!strip_info->manual_dev_addr)
-		*(MetricomAddress *) strip_info->dev->dev_addr =
-		    zero_address;
-	strip_info->working = FALSE;
-	strip_info->firmware_level = NoStructure;
-	strip_info->next_command = CompatibilityCommand;
-	strip_info->watchdog_doprobe = jiffies + 10 * HZ;
-	strip_info->watchdog_doreset = jiffies + 1 * HZ;
-
-	/* If the user has selected a baud rate above 38.4 see what magic we have to do */
-	if (strip_info->user_baud > 38400) {
-		/*
-		 * Subtle stuff: Pay attention :-)
-		 * If the serial port is currently at the user's selected (>38.4) rate,
-		 * then we temporarily switch to 19.2 and issue the ATS304 command
-		 * to tell the radio to switch to the user's selected rate.
-		 * If the serial port is not currently at that rate, that means we just
-		 * issued the ATS304 command last time through, so this time we restore
-		 * the user's selected rate and issue the normal starmode reset string.
-		 */
-		if (strip_info->user_baud == tty_get_baud_rate(tty)) {
-			static const char b0[] = "ate0q1s304=57600\r";
-			static const char b1[] = "ate0q1s304=115200\r";
-			static const StringDescriptor baudstring[2] =
-			    { {b0, sizeof(b0) - 1}
-			, {b1, sizeof(b1) - 1}
-			};
-			set_baud(tty, 19200);
-			if (strip_info->user_baud == 57600)
-				s = baudstring[0];
-			else if (strip_info->user_baud == 115200)
-				s = baudstring[1];
-			else
-				s = baudstring[1];	/* For now */
-		} else
-			set_baud(tty, strip_info->user_baud);
-	}
-
-	tty->ops->write(tty, s.string, s.length);
-#ifdef EXT_COUNTERS
-	strip_info->tx_ebytes += s.length;
-#endif
-}
-
-/*
- * Called by the driver when there's room for more data.  If we have
- * more packets to send, we send them here.
- */
-
-static void strip_write_some_more(struct tty_struct *tty)
-{
-	struct strip *strip_info = tty->disc_data;
-
-	/* First make sure we're connected. */
-	if (!strip_info || strip_info->magic != STRIP_MAGIC ||
-	    !netif_running(strip_info->dev))
-		return;
-
-	if (strip_info->tx_left > 0) {
-		int num_written =
-		    tty->ops->write(tty, strip_info->tx_head,
-				      strip_info->tx_left);
-		strip_info->tx_left -= num_written;
-		strip_info->tx_head += num_written;
-#ifdef EXT_COUNTERS
-		strip_info->tx_sbytes += num_written;
-#endif
-	} else {		/* Else start transmission of another packet */
-
-		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-		strip_unlock(strip_info);
-	}
-}
-
-static __u8 *add_checksum(__u8 * buffer, __u8 * end)
-{
-	__u16 sum = 0;
-	__u8 *p = buffer;
-	while (p < end)
-		sum += *p++;
-	end[3] = hextable[sum & 0xF];
-	sum >>= 4;
-	end[2] = hextable[sum & 0xF];
-	sum >>= 4;
-	end[1] = hextable[sum & 0xF];
-	sum >>= 4;
-	end[0] = hextable[sum & 0xF];
-	return (end + 4);
-}
-
-static unsigned char *strip_make_packet(unsigned char *buffer,
-					struct strip *strip_info,
-					struct sk_buff *skb)
-{
-	__u8 *ptr = buffer;
-	__u8 *stuffstate = NULL;
-	STRIP_Header *header = (STRIP_Header *) skb->data;
-	MetricomAddress haddr = header->dst_addr;
-	int len = skb->len - sizeof(STRIP_Header);
-	MetricomKey key;
-
-	/*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */
-
-	if (header->protocol == htons(ETH_P_IP))
-		key = SIP0Key;
-	else if (header->protocol == htons(ETH_P_ARP))
-		key = ARP0Key;
-	else {
-		printk(KERN_ERR
-		       "%s: strip_make_packet: Unknown packet type 0x%04X\n",
-		       strip_info->dev->name, ntohs(header->protocol));
-		return (NULL);
-	}
-
-	if (len > strip_info->mtu) {
-		printk(KERN_ERR
-		       "%s: Dropping oversized transmit packet: %d bytes\n",
-		       strip_info->dev->name, len);
-		return (NULL);
-	}
-
-	/*
-	 * If we're sending to ourselves, discard the packet.
-	 * (Metricom radios choke if they try to send a packet to their own address.)
-	 */
-	if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) {
-		printk(KERN_ERR "%s: Dropping packet addressed to self\n",
-		       strip_info->dev->name);
-		return (NULL);
-	}
-
-	/*
-	 * If this is a broadcast packet, send it to our designated Metricom
-	 * 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
-	 */
-	if (haddr.c[0] == 0xFF) {
-		__be32 brd = 0;
-		struct in_device *in_dev;
-
-		rcu_read_lock();
-		in_dev = __in_dev_get_rcu(strip_info->dev);
-		if (in_dev == NULL) {
-			rcu_read_unlock();
-			return NULL;
-		}
-		if (in_dev->ifa_list)
-			brd = in_dev->ifa_list->ifa_broadcast;
-		rcu_read_unlock();
-
-		/* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
-		if (!arp_query(haddr.c, brd, strip_info->dev)) {
-			printk(KERN_ERR
-			       "%s: Unable to send packet (no broadcast hub configured)\n",
-			       strip_info->dev->name);
-			return (NULL);
-		}
-		/*
-		 * If we are the broadcast hub, don't bother sending to ourselves.
-		 * (Metricom radios choke if they try to send a packet to their own address.)
-		 */
-		if (!memcmp
-		    (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
-			return (NULL);
-	}
-
-	*ptr++ = 0x0D;
-	*ptr++ = '*';
-	*ptr++ = hextable[haddr.c[2] >> 4];
-	*ptr++ = hextable[haddr.c[2] & 0xF];
-	*ptr++ = hextable[haddr.c[3] >> 4];
-	*ptr++ = hextable[haddr.c[3] & 0xF];
-	*ptr++ = '-';
-	*ptr++ = hextable[haddr.c[4] >> 4];
-	*ptr++ = hextable[haddr.c[4] & 0xF];
-	*ptr++ = hextable[haddr.c[5] >> 4];
-	*ptr++ = hextable[haddr.c[5] & 0xF];
-	*ptr++ = '*';
-	*ptr++ = key.c[0];
-	*ptr++ = key.c[1];
-	*ptr++ = key.c[2];
-	*ptr++ = key.c[3];
-
-	ptr =
-	    StuffData(skb->data + sizeof(STRIP_Header), len, ptr,
-		      &stuffstate);
-
-	if (strip_info->firmware_level >= ChecksummedMessages)
-		ptr = add_checksum(buffer + 1, ptr);
-
-	*ptr++ = 0x0D;
-	return (ptr);
-}
-
-static void strip_send(struct strip *strip_info, struct sk_buff *skb)
-{
-	MetricomAddress haddr;
-	unsigned char *ptr = strip_info->tx_buff;
-	int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
-	int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
-	    && !doreset;
-	__be32 addr, brd;
-
-	/*
-	 * 1. If we have a packet, encapsulate it and put it in the buffer
-	 */
-	if (skb) {
-		char *newptr = strip_make_packet(ptr, strip_info, skb);
-		strip_info->tx_pps_count++;
-		if (!newptr)
-			strip_info->tx_dropped++;
-		else {
-			ptr = newptr;
-			strip_info->sx_pps_count++;
-			strip_info->tx_packets++;	/* Count another successful packet */
-#ifdef EXT_COUNTERS
-			strip_info->tx_bytes += skb->len;
-			strip_info->tx_rbytes += ptr - strip_info->tx_buff;
-#endif
-			/*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */
-			/*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */
-		}
-	}
-
-	/*
-	 * 2. If it is time for another tickle, tack it on, after the packet
-	 */
-	if (doprobe) {
-		StringDescriptor ts = CommandString[strip_info->next_command];
-#if TICKLE_TIMERS
-		{
-			struct timeval tv;
-			do_gettimeofday(&tv);
-			printk(KERN_INFO "**** Sending tickle string %d      at %02d.%06d\n",
-			       strip_info->next_command, tv.tv_sec % 100,
-			       tv.tv_usec);
-		}
-#endif
-		if (ptr == strip_info->tx_buff)
-			*ptr++ = 0x0D;
-
-		*ptr++ = '*';	/* First send "**" to provoke an error message */
-		*ptr++ = '*';
-
-		/* Then add the command */
-		memcpy(ptr, ts.string, ts.length);
-
-		/* Add a checksum ? */
-		if (strip_info->firmware_level < ChecksummedMessages)
-			ptr += ts.length;
-		else
-			ptr = add_checksum(ptr, ptr + ts.length);
-
-		*ptr++ = 0x0D;	/* Terminate the command with a <CR> */
-
-		/* Cycle to next periodic command? */
-		if (strip_info->firmware_level >= StructuredMessages)
-			if (++strip_info->next_command >=
-			    ARRAY_SIZE(CommandString))
-				strip_info->next_command = 0;
-#ifdef EXT_COUNTERS
-		strip_info->tx_ebytes += ts.length;
-#endif
-		strip_info->watchdog_doprobe = jiffies + 10 * HZ;
-		strip_info->watchdog_doreset = jiffies + 1 * HZ;
-		/*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */
-	}
-
-	/*
-	 * 3. Set up the strip_info ready to send the data (if any).
-	 */
-	strip_info->tx_head = strip_info->tx_buff;
-	strip_info->tx_left = ptr - strip_info->tx_buff;
-	set_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags);
-	/*
-	 * 4. Debugging check to make sure we're not overflowing the buffer.
-	 */
-	if (strip_info->tx_size - strip_info->tx_left < 20)
-		printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n",
-		       strip_info->dev->name, strip_info->tx_left,
-		       strip_info->tx_size - strip_info->tx_left);
-
-	/*
-	 * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in
-	 * the buffer, strip_write_some_more will send it after the reset has finished
-	 */
-	if (doreset) {
-		ResetRadio(strip_info);
-		return;
-	}
-
-	if (1) {
-		struct in_device *in_dev;
-
-		brd = addr = 0;
-		rcu_read_lock();
-		in_dev = __in_dev_get_rcu(strip_info->dev);
-		if (in_dev) {
-			if (in_dev->ifa_list) {
-				brd = in_dev->ifa_list->ifa_broadcast;
-				addr = in_dev->ifa_list->ifa_local;
-			}
-		}
-		rcu_read_unlock();
-	}
-
-
-	/*
-	 * 6. If it is time for a periodic ARP, queue one up to be sent.
-	 * We only do this if:
-	 *  1. The radio is working
-	 *  2. It's time to send another periodic ARP
-	 *  3. We really know what our address is (and it is not manually set to zero)
-	 *  4. We have a designated broadcast address configured
-	 * If we queue up an ARP packet when we don't have a designated broadcast
-	 * address configured, then the packet will just have to be discarded in
-	 * strip_make_packet. This is not fatal, but it causes misleading information
-	 * to be displayed in tcpdump. tcpdump will report that periodic APRs are
-	 * being sent, when in fact they are not, because they are all being dropped
-	 * in the strip_make_packet routine.
-	 */
-	if (strip_info->working
-	    && (long) jiffies - strip_info->gratuitous_arp >= 0
-	    && memcmp(strip_info->dev->dev_addr, zero_address.c,
-		      sizeof(zero_address))
-	    && arp_query(haddr.c, brd, strip_info->dev)) {
-		/*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n",
-		   strip_info->dev->name, strip_info->arp_interval / HZ); */
-		strip_info->gratuitous_arp =
-		    jiffies + strip_info->arp_interval;
-		strip_info->arp_interval *= 2;
-		if (strip_info->arp_interval > MaxARPInterval)
-			strip_info->arp_interval = MaxARPInterval;
-		if (addr)
-			arp_send(ARPOP_REPLY, ETH_P_ARP, addr,	/* Target address of ARP packet is our address */
-				 strip_info->dev,	/* Device to send packet on */
-				 addr,	/* Source IP address this ARP packet comes from */
-				 NULL,	/* Destination HW address is NULL (broadcast it) */
-				 strip_info->dev->dev_addr,	/* Source HW address is our HW address */
-				 strip_info->dev->dev_addr);	/* Target HW address is our HW address (redundant) */
-	}
-
-	/*
-	 * 7. All ready. Start the transmission
-	 */
-	strip_write_some_more(strip_info->tty);
-}
-
-/* Encapsulate a datagram and kick it into a TTY queue. */
-static netdev_tx_t strip_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct strip *strip_info = netdev_priv(dev);
-
-	if (!netif_running(dev)) {
-		printk(KERN_ERR "%s: xmit call when iface is down\n",
-		       dev->name);
-		return NETDEV_TX_BUSY;
-	}
-
-	netif_stop_queue(dev);
-
-	del_timer(&strip_info->idle_timer);
-
-
-	if (time_after(jiffies, strip_info->pps_timer + HZ)) {
-		unsigned long t = jiffies - strip_info->pps_timer;
-		unsigned long rx_pps_count =
-			DIV_ROUND_CLOSEST(strip_info->rx_pps_count*HZ*8, t);
-		unsigned long tx_pps_count =
-			DIV_ROUND_CLOSEST(strip_info->tx_pps_count*HZ*8, t);
-		unsigned long sx_pps_count =
-			DIV_ROUND_CLOSEST(strip_info->sx_pps_count*HZ*8, t);
-
-		strip_info->pps_timer = jiffies;
-		strip_info->rx_pps_count = 0;
-		strip_info->tx_pps_count = 0;
-		strip_info->sx_pps_count = 0;
-
-		strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2;
-		strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2;
-		strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2;
-
-		if (rx_pps_count / 8 >= 10)
-			printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n",
-			       strip_info->dev->name, rx_pps_count / 8);
-		if (tx_pps_count / 8 >= 10)
-			printk(KERN_INFO "%s: WARNING: Tx        %ld packets per second.\n",
-			       strip_info->dev->name, tx_pps_count / 8);
-		if (sx_pps_count / 8 >= 10)
-			printk(KERN_INFO "%s: WARNING: Sending   %ld packets per second.\n",
-			       strip_info->dev->name, sx_pps_count / 8);
-	}
-
-	spin_lock_bh(&strip_lock);
-
-	strip_send(strip_info, skb);
-
-	spin_unlock_bh(&strip_lock);
-
-	if (skb)
-		dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
-}
-
-/*
- * IdleTask periodically calls strip_xmit, so even when we have no IP packets
- * to send for an extended period of time, the watchdog processing still gets
- * done to ensure that the radio stays in Starmode
- */
-
-static void strip_IdleTask(unsigned long parameter)
-{
-	strip_xmit(NULL, (struct net_device *) parameter);
-}
-
-/*
- * Create the MAC header for an arbitrary protocol layer
- *
- * saddr!=NULL        means use this specific address (n/a for Metricom)
- * saddr==NULL        means use default device source address
- * daddr!=NULL        means use this destination address
- * daddr==NULL        means leave destination address alone
- *                 (e.g. unresolved arp -- kernel will call
- *                 rebuild_header later to fill in the address)
- */
-
-static int strip_header(struct sk_buff *skb, struct net_device *dev,
-			unsigned short type, const void *daddr,
-			const void *saddr, unsigned len)
-{
-	struct strip *strip_info = netdev_priv(dev);
-	STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
-
-	/*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
-	   type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */
-
-	header->src_addr = strip_info->true_dev_addr;
-	header->protocol = htons(type);
-
-	/*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
-
-	if (!daddr)
-		return (-dev->hard_header_len);
-
-	header->dst_addr = *(MetricomAddress *) daddr;
-	return (dev->hard_header_len);
-}
-
-/*
- * Rebuild the MAC header. This is called after an ARP
- * (or in future other address resolution) has completed on this
- * sk_buff. We now let ARP fill in the other fields.
- * I think this should return zero if packet is ready to send,
- * or non-zero if it needs more time to do an address lookup
- */
-
-static int strip_rebuild_header(struct sk_buff *skb)
-{
-#ifdef CONFIG_INET
-	STRIP_Header *header = (STRIP_Header *) skb->data;
-
-	/* Arp find returns zero if if knows the address, */
-	/* or if it doesn't know the address it sends an ARP packet and returns non-zero */
-	return arp_find(header->dst_addr.c, skb) ? 1 : 0;
-#else
-	return 0;
-#endif
-}
-
-
-/************************************************************************/
-/* Receiving routines							*/
-
-/*
- * This function parses the response to the ATS300? command,
- * extracting the radio version and serial number.
- */
-static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end)
-{
-	__u8 *p, *value_begin, *value_end;
-	int len;
-
-	/* Determine the beginning of the second line of the payload */
-	p = ptr;
-	while (p < end && *p != 10)
-		p++;
-	if (p >= end)
-		return;
-	p++;
-	value_begin = p;
-
-	/* Determine the end of line */
-	while (p < end && *p != 10)
-		p++;
-	if (p >= end)
-		return;
-	value_end = p;
-	p++;
-
-	len = value_end - value_begin;
-	len = min_t(int, len, sizeof(FirmwareVersion) - 1);
-	if (strip_info->firmware_version.c[0] == 0)
-		printk(KERN_INFO "%s: Radio Firmware: %.*s\n",
-		       strip_info->dev->name, len, value_begin);
-	sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin);
-
-	/* Look for the first colon */
-	while (p < end && *p != ':')
-		p++;
-	if (p >= end)
-		return;
-	/* Skip over the space */
-	p += 2;
-	len = sizeof(SerialNumber) - 1;
-	if (p + len <= end) {
-		sprintf(strip_info->serial_number.c, "%.*s", len, p);
-	} else {
-		printk(KERN_DEBUG
-		       "STRIP: radio serial number shorter (%zd) than expected (%d)\n",
-		       end - p, len);
-	}
-}
-
-/*
- * This function parses the response to the ATS325? command,
- * extracting the radio battery voltage.
- */
-static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end)
-{
-	int len;
-
-	len = sizeof(BatteryVoltage) - 1;
-	if (ptr + len <= end) {
-		sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr);
-	} else {
-		printk(KERN_DEBUG
-		       "STRIP: radio voltage string shorter (%zd) than expected (%d)\n",
-		       end - ptr, len);
-	}
-}
-
-/*
- * This function parses the responses to the AT~LA and ATS311 commands,
- * which list the radio's neighbours.
- */
-static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end)
-{
-	table->num_nodes = 0;
-	while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) {
-		MetricomNode *node = &table->node[table->num_nodes++];
-		char *dst = node->c, *limit = dst + sizeof(*node) - 1;
-		while (ptr < end && *ptr <= 32)
-			ptr++;
-		while (ptr < end && dst < limit && *ptr != 10)
-			*dst++ = *ptr++;
-		*dst++ = 0;
-		while (ptr < end && ptr[-1] != 10)
-			ptr++;
-	}
-	do_gettimeofday(&table->timestamp);
-}
-
-static int get_radio_address(struct strip *strip_info, __u8 * p)
-{
-	MetricomAddress addr;
-
-	if (string_to_radio_address(&addr, p))
-		return (1);
-
-	/* See if our radio address has changed */
-	if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) {
-		MetricomAddressString addr_string;
-		radio_address_to_string(&addr, &addr_string);
-		printk(KERN_INFO "%s: Radio address = %s\n",
-		       strip_info->dev->name, addr_string.c);
-		strip_info->true_dev_addr = addr;
-		if (!strip_info->manual_dev_addr)
-			*(MetricomAddress *) strip_info->dev->dev_addr =
-			    addr;
-		/* Give the radio a few seconds to get its head straight, then send an arp */
-		strip_info->gratuitous_arp = jiffies + 15 * HZ;
-		strip_info->arp_interval = 1 * HZ;
-	}
-	return (0);
-}
-
-static int verify_checksum(struct strip *strip_info)
-{
-	__u8 *p = strip_info->sx_buff;
-	__u8 *end = strip_info->sx_buff + strip_info->sx_count - 4;
-	u_short sum =
-	    (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) |
-	    (READHEX16(end[2]) << 4) | (READHEX16(end[3]));
-	while (p < end)
-		sum -= *p++;
-	if (sum == 0 && strip_info->firmware_level == StructuredMessages) {
-		strip_info->firmware_level = ChecksummedMessages;
-		printk(KERN_INFO "%s: Radio provides message checksums\n",
-		       strip_info->dev->name);
-	}
-	return (sum == 0);
-}
-
-static void RecvErr(char *msg, struct strip *strip_info)
-{
-	__u8 *ptr = strip_info->sx_buff;
-	__u8 *end = strip_info->sx_buff + strip_info->sx_count;
-	DumpData(msg, strip_info, ptr, end);
-	strip_info->rx_errors++;
-}
-
-static void RecvErr_Message(struct strip *strip_info, __u8 * sendername,
-			    const __u8 * msg, u_long len)
-{
-	if (has_prefix(msg, len, "001")) {	/* Not in StarMode! */
-		RecvErr("Error Msg:", strip_info);
-		printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
-		       strip_info->dev->name, sendername);
-	}
-
-	else if (has_prefix(msg, len, "002")) {	/* Remap handle */
-		/* We ignore "Remap handle" messages for now */
-	}
-
-	else if (has_prefix(msg, len, "003")) {	/* Can't resolve name */
-		RecvErr("Error Msg:", strip_info);
-		printk(KERN_INFO "%s: Destination radio name is unknown\n",
-		       strip_info->dev->name);
-	}
-
-	else if (has_prefix(msg, len, "004")) {	/* Name too small or missing */
-		strip_info->watchdog_doreset = jiffies + LongTime;
-#if TICKLE_TIMERS
-		{
-			struct timeval tv;
-			do_gettimeofday(&tv);
-			printk(KERN_INFO
-			       "**** Got ERR_004 response         at %02d.%06d\n",
-			       tv.tv_sec % 100, tv.tv_usec);
-		}
-#endif
-		if (!strip_info->working) {
-			strip_info->working = TRUE;
-			printk(KERN_INFO "%s: Radio now in starmode\n",
-			       strip_info->dev->name);
-			/*
-			 * If the radio has just entered a working state, we should do our first
-			 * probe ASAP, so that we find out our radio address etc. without delay.
-			 */
-			strip_info->watchdog_doprobe = jiffies;
-		}
-		if (strip_info->firmware_level == NoStructure && sendername) {
-			strip_info->firmware_level = StructuredMessages;
-			strip_info->next_command = 0;	/* Try to enable checksums ASAP */
-			printk(KERN_INFO
-			       "%s: Radio provides structured messages\n",
-			       strip_info->dev->name);
-		}
-		if (strip_info->firmware_level >= StructuredMessages) {
-			/*
-			 * If this message has a valid checksum on the end, then the call to verify_checksum
-			 * will elevate the firmware_level to ChecksummedMessages for us. (The actual return
-			 * code from verify_checksum is ignored here.)
-			 */
-			verify_checksum(strip_info);
-			/*
-			 * If the radio has structured messages but we don't yet have all our information about it,
-			 * we should do probes without delay, until we have gathered all the information
-			 */
-			if (!GOT_ALL_RADIO_INFO(strip_info))
-				strip_info->watchdog_doprobe = jiffies;
-		}
-	}
-
-	else if (has_prefix(msg, len, "005"))	/* Bad count specification */
-		RecvErr("Error Msg:", strip_info);
-
-	else if (has_prefix(msg, len, "006"))	/* Header too big */
-		RecvErr("Error Msg:", strip_info);
-
-	else if (has_prefix(msg, len, "007")) {	/* Body too big */
-		RecvErr("Error Msg:", strip_info);
-		printk(KERN_ERR
-		       "%s: Error! Packet size too big for radio.\n",
-		       strip_info->dev->name);
-	}
-
-	else if (has_prefix(msg, len, "008")) {	/* Bad character in name */
-		RecvErr("Error Msg:", strip_info);
-		printk(KERN_ERR
-		       "%s: Radio name contains illegal character\n",
-		       strip_info->dev->name);
-	}
-
-	else if (has_prefix(msg, len, "009"))	/* No count or line terminator */
-		RecvErr("Error Msg:", strip_info);
-
-	else if (has_prefix(msg, len, "010"))	/* Invalid checksum */
-		RecvErr("Error Msg:", strip_info);
-
-	else if (has_prefix(msg, len, "011"))	/* Checksum didn't match */
-		RecvErr("Error Msg:", strip_info);
-
-	else if (has_prefix(msg, len, "012"))	/* Failed to transmit packet */
-		RecvErr("Error Msg:", strip_info);
-
-	else
-		RecvErr("Error Msg:", strip_info);
-}
-
-static void process_AT_response(struct strip *strip_info, __u8 * ptr,
-				__u8 * end)
-{
-	u_long len;
-	__u8 *p = ptr;
-	while (p < end && p[-1] != 10)
-		p++;		/* Skip past first newline character */
-	/* Now ptr points to the AT command, and p points to the text of the response. */
-	len = p - ptr;
-
-#if TICKLE_TIMERS
-	{
-		struct timeval tv;
-		do_gettimeofday(&tv);
-		printk(KERN_INFO "**** Got AT response %.7s      at %02d.%06d\n",
-		       ptr, tv.tv_sec % 100, tv.tv_usec);
-	}
-#endif
-
-	if (has_prefix(ptr, len, "ATS300?"))
-		get_radio_version(strip_info, p, end);
-	else if (has_prefix(ptr, len, "ATS305?"))
-		get_radio_address(strip_info, p);
-	else if (has_prefix(ptr, len, "ATS311?"))
-		get_radio_neighbours(&strip_info->poletops, p, end);
-	else if (has_prefix(ptr, len, "ATS319=7"))
-		verify_checksum(strip_info);
-	else if (has_prefix(ptr, len, "ATS325?"))
-		get_radio_voltage(strip_info, p, end);
-	else if (has_prefix(ptr, len, "AT~LA"))
-		get_radio_neighbours(&strip_info->portables, p, end);
-	else
-		RecvErr("Unknown AT Response:", strip_info);
-}
-
-static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end)
-{
-	/* Currently we don't do anything with ACKs from the radio */
-}
-
-static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end)
-{
-	if (ptr + 16 > end)
-		RecvErr("Bad Info Msg:", strip_info);
-}
-
-static struct net_device *get_strip_dev(struct strip *strip_info)
-{
-	/* If our hardware address is *manually set* to zero, and we know our */
-	/* real radio hardware address, try to find another strip device that has been */
-	/* manually set to that address that we can 'transfer ownership' of this packet to  */
-	if (strip_info->manual_dev_addr &&
-	    !memcmp(strip_info->dev->dev_addr, zero_address.c,
-		    sizeof(zero_address))
-	    && memcmp(&strip_info->true_dev_addr, zero_address.c,
-		      sizeof(zero_address))) {
-		struct net_device *dev;
-		read_lock_bh(&dev_base_lock);
-		for_each_netdev(&init_net, dev) {
-			if (dev->type == strip_info->dev->type &&
-			    !memcmp(dev->dev_addr,
-				    &strip_info->true_dev_addr,
-				    sizeof(MetricomAddress))) {
-				printk(KERN_INFO
-				       "%s: Transferred packet ownership to %s.\n",
-				       strip_info->dev->name, dev->name);
-				read_unlock_bh(&dev_base_lock);
-				return (dev);
-			}
-		}
-		read_unlock_bh(&dev_base_lock);
-	}
-	return (strip_info->dev);
-}
-
-/*
- * Send one completely decapsulated datagram to the next layer.
- */
-
-static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
-			   __u16 packetlen)
-{
-	struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen);
-	if (!skb) {
-		printk(KERN_ERR "%s: memory squeeze, dropping packet.\n",
-		       strip_info->dev->name);
-		strip_info->rx_dropped++;
-	} else {
-		memcpy(skb_put(skb, sizeof(STRIP_Header)), header,
-		       sizeof(STRIP_Header));
-		memcpy(skb_put(skb, packetlen), strip_info->rx_buff,
-		       packetlen);
-		skb->dev = get_strip_dev(strip_info);
-		skb->protocol = header->protocol;
-		skb_reset_mac_header(skb);
-
-		/* Having put a fake header on the front of the sk_buff for the */
-		/* benefit of tools like tcpdump, skb_pull now 'consumes' that  */
-		/* fake header before we hand the packet up to the next layer.  */
-		skb_pull(skb, sizeof(STRIP_Header));
-
-		/* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */
-		strip_info->rx_packets++;
-		strip_info->rx_pps_count++;
-#ifdef EXT_COUNTERS
-		strip_info->rx_bytes += packetlen;
-#endif
-		netif_rx(skb);
-	}
-}
-
-static void process_IP_packet(struct strip *strip_info,
-			      STRIP_Header * header, __u8 * ptr,
-			      __u8 * end)
-{
-	__u16 packetlen;
-
-	/* Decode start of the IP packet header */
-	ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
-	if (!ptr) {
-		RecvErr("IP Packet too short", strip_info);
-		return;
-	}
-
-	packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];
-
-	if (packetlen > MAX_RECV_MTU) {
-		printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n",
-		       strip_info->dev->name, packetlen);
-		strip_info->rx_dropped++;
-		return;
-	}
-
-	/*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */
-
-	/* Decode remainder of the IP packet */
-	ptr =
-	    UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4);
-	if (!ptr) {
-		RecvErr("IP Packet too short", strip_info);
-		return;
-	}
-
-	if (ptr < end) {
-		RecvErr("IP Packet too long", strip_info);
-		return;
-	}
-
-	header->protocol = htons(ETH_P_IP);
-
-	deliver_packet(strip_info, header, packetlen);
-}
-
-static void process_ARP_packet(struct strip *strip_info,
-			       STRIP_Header * header, __u8 * ptr,
-			       __u8 * end)
-{
-	__u16 packetlen;
-	struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff;
-
-	/* Decode start of the ARP packet */
-	ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8);
-	if (!ptr) {
-		RecvErr("ARP Packet too short", strip_info);
-		return;
-	}
-
-	packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2;
-
-	if (packetlen > MAX_RECV_MTU) {
-		printk(KERN_INFO
-		       "%s: Dropping oversized received ARP packet: %d bytes\n",
-		       strip_info->dev->name, packetlen);
-		strip_info->rx_dropped++;
-		return;
-	}
-
-	/*printk(KERN_INFO "%s: Got %d byte ARP %s\n",
-	   strip_info->dev->name, packetlen,
-	   ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */
-
-	/* Decode remainder of the ARP packet */
-	ptr =
-	    UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8);
-	if (!ptr) {
-		RecvErr("ARP Packet too short", strip_info);
-		return;
-	}
-
-	if (ptr < end) {
-		RecvErr("ARP Packet too long", strip_info);
-		return;
-	}
-
-	header->protocol = htons(ETH_P_ARP);
-
-	deliver_packet(strip_info, header, packetlen);
-}
-
-/*
- * process_text_message processes a <CR>-terminated block of data received
- * from the radio that doesn't begin with a '*' character. All normal
- * Starmode communication messages with the radio begin with a '*',
- * so any text that does not indicates a serial port error, a radio that
- * is in Hayes command mode instead of Starmode, or a radio with really
- * old firmware that doesn't frame its Starmode responses properly.
- */
-static void process_text_message(struct strip *strip_info)
-{
-	__u8 *msg = strip_info->sx_buff;
-	int len = strip_info->sx_count;
-
-	/* Check for anything that looks like it might be our radio name */
-	/* (This is here for backwards compatibility with old firmware)  */
-	if (len == 9 && get_radio_address(strip_info, msg) == 0)
-		return;
-
-	if (text_equal(msg, len, "OK"))
-		return;		/* Ignore 'OK' responses from prior commands */
-	if (text_equal(msg, len, "ERROR"))
-		return;		/* Ignore 'ERROR' messages */
-	if (has_prefix(msg, len, "ate0q1"))
-		return;		/* Ignore character echo back from the radio */
-
-	/* Catch other error messages */
-	/* (This is here for backwards compatibility with old firmware) */
-	if (has_prefix(msg, len, "ERR_")) {
-		RecvErr_Message(strip_info, NULL, &msg[4], len - 4);
-		return;
-	}
-
-	RecvErr("No initial *", strip_info);
-}
-
-/*
- * process_message processes a <CR>-terminated block of data received
- * from the radio. If the radio is not in Starmode or has old firmware,
- * it may be a line of text in response to an AT command. Ideally, with
- * a current radio that's properly in Starmode, all data received should
- * be properly framed and checksummed radio message blocks, containing
- * either a starmode packet, or a other communication from the radio
- * firmware, like "INF_" Info messages and &COMMAND responses.
- */
-static void process_message(struct strip *strip_info)
-{
-	STRIP_Header header = { zero_address, zero_address, 0 };
-	__u8 *ptr = strip_info->sx_buff;
-	__u8 *end = strip_info->sx_buff + strip_info->sx_count;
-	__u8 sendername[32], *sptr = sendername;
-	MetricomKey key;
-
-	/*HexDump("Receiving", strip_info, ptr, end); */
-
-	/* Check for start of address marker, and then skip over it */
-	if (*ptr == '*')
-		ptr++;
-	else {
-		process_text_message(strip_info);
-		return;
-	}
-
-	/* Copy out the return address */
-	while (ptr < end && *ptr != '*'
-	       && sptr < ARRAY_END(sendername) - 1)
-		*sptr++ = *ptr++;
-	*sptr = 0;		/* Null terminate the sender name */
-
-	/* Check for end of address marker, and skip over it */
-	if (ptr >= end || *ptr != '*') {
-		RecvErr("No second *", strip_info);
-		return;
-	}
-	ptr++;			/* Skip the second '*' */
-
-	/* If the sender name is "&COMMAND", ignore this 'packet'       */
-	/* (This is here for backwards compatibility with old firmware) */
-	if (!strcmp(sendername, "&COMMAND")) {
-		strip_info->firmware_level = NoStructure;
-		strip_info->next_command = CompatibilityCommand;
-		return;
-	}
-
-	if (ptr + 4 > end) {
-		RecvErr("No proto key", strip_info);
-		return;
-	}
-
-	/* Get the protocol key out of the buffer */
-	key.c[0] = *ptr++;
-	key.c[1] = *ptr++;
-	key.c[2] = *ptr++;
-	key.c[3] = *ptr++;
-
-	/* If we're using checksums, verify the checksum at the end of the packet */
-	if (strip_info->firmware_level >= ChecksummedMessages) {
-		end -= 4;	/* Chop the last four bytes off the packet (they're the checksum) */
-		if (ptr > end) {
-			RecvErr("Missing Checksum", strip_info);
-			return;
-		}
-		if (!verify_checksum(strip_info)) {
-			RecvErr("Bad Checksum", strip_info);
-			return;
-		}
-	}
-
-	/*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */
-
-	/*
-	 * Fill in (pseudo) source and destination addresses in the packet.
-	 * We assume that the destination address was our address (the radio does not
-	 * tell us this). If the radio supplies a source address, then we use it.
-	 */
-	header.dst_addr = strip_info->true_dev_addr;
-	string_to_radio_address(&header.src_addr, sendername);
-
-#ifdef EXT_COUNTERS
-	if (key.l == SIP0Key.l) {
-		strip_info->rx_rbytes += (end - ptr);
-		process_IP_packet(strip_info, &header, ptr, end);
-	} else if (key.l == ARP0Key.l) {
-		strip_info->rx_rbytes += (end - ptr);
-		process_ARP_packet(strip_info, &header, ptr, end);
-	} else if (key.l == ATR_Key.l) {
-		strip_info->rx_ebytes += (end - ptr);
-		process_AT_response(strip_info, ptr, end);
-	} else if (key.l == ACK_Key.l) {
-		strip_info->rx_ebytes += (end - ptr);
-		process_ACK(strip_info, ptr, end);
-	} else if (key.l == INF_Key.l) {
-		strip_info->rx_ebytes += (end - ptr);
-		process_Info(strip_info, ptr, end);
-	} else if (key.l == ERR_Key.l) {
-		strip_info->rx_ebytes += (end - ptr);
-		RecvErr_Message(strip_info, sendername, ptr, end - ptr);
-	} else
-		RecvErr("Unrecognized protocol key", strip_info);
-#else
-	if (key.l == SIP0Key.l)
-		process_IP_packet(strip_info, &header, ptr, end);
-	else if (key.l == ARP0Key.l)
-		process_ARP_packet(strip_info, &header, ptr, end);
-	else if (key.l == ATR_Key.l)
-		process_AT_response(strip_info, ptr, end);
-	else if (key.l == ACK_Key.l)
-		process_ACK(strip_info, ptr, end);
-	else if (key.l == INF_Key.l)
-		process_Info(strip_info, ptr, end);
-	else if (key.l == ERR_Key.l)
-		RecvErr_Message(strip_info, sendername, ptr, end - ptr);
-	else
-		RecvErr("Unrecognized protocol key", strip_info);
-#endif
-}
-
-#define TTYERROR(X) ((X) == TTY_BREAK   ? "Break"            : \
-                     (X) == TTY_FRAME   ? "Framing Error"    : \
-                     (X) == TTY_PARITY  ? "Parity Error"     : \
-                     (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error")
-
-/*
- * Handle the 'receiver data ready' interrupt.
- * This function is called by the 'tty_io' module in the kernel when
- * a block of STRIP data has been received, which can now be decapsulated
- * and sent on to some IP layer for further processing.
- */
-
-static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
-		  char *fp, int count)
-{
-	struct strip *strip_info = tty->disc_data;
-	const unsigned char *end = cp + count;
-
-	if (!strip_info || strip_info->magic != STRIP_MAGIC
-	    || !netif_running(strip_info->dev))
-		return;
-
-	spin_lock_bh(&strip_lock);
-#if 0
-	{
-		struct timeval tv;
-		do_gettimeofday(&tv);
-		printk(KERN_INFO
-		       "**** strip_receive_buf: %3d bytes at %02d.%06d\n",
-		       count, tv.tv_sec % 100, tv.tv_usec);
-	}
-#endif
-
-#ifdef EXT_COUNTERS
-	strip_info->rx_sbytes += count;
-#endif
-
-	/* Read the characters out of the buffer */
-	while (cp < end) {
-		if (fp && *fp)
-			printk(KERN_INFO "%s: %s on serial port\n",
-			       strip_info->dev->name, TTYERROR(*fp));
-		if (fp && *fp++ && !strip_info->discard) {	/* If there's a serial error, record it */
-			/* If we have some characters in the buffer, discard them */
-			strip_info->discard = strip_info->sx_count;
-			strip_info->rx_errors++;
-		}
-
-		/* Leading control characters (CR, NL, Tab, etc.) are ignored */
-		if (strip_info->sx_count > 0 || *cp >= ' ') {
-			if (*cp == 0x0D) {	/* If end of packet, decide what to do with it */
-				if (strip_info->sx_count > 3000)
-					printk(KERN_INFO
-					       "%s: Cut a %d byte packet (%zd bytes remaining)%s\n",
-					       strip_info->dev->name,
-					       strip_info->sx_count,
-					       end - cp - 1,
-					       strip_info->
-					       discard ? " (discarded)" :
-					       "");
-				if (strip_info->sx_count >
-				    strip_info->sx_size) {
-					strip_info->rx_over_errors++;
-					printk(KERN_INFO
-					       "%s: sx_buff overflow (%d bytes total)\n",
-					       strip_info->dev->name,
-					       strip_info->sx_count);
-				} else if (strip_info->discard)
-					printk(KERN_INFO
-					       "%s: Discarding bad packet (%d/%d)\n",
-					       strip_info->dev->name,
-					       strip_info->discard,
-					       strip_info->sx_count);
-				else
-					process_message(strip_info);
-				strip_info->discard = 0;
-				strip_info->sx_count = 0;
-			} else {
-				/* Make sure we have space in the buffer */
-				if (strip_info->sx_count <
-				    strip_info->sx_size)
-					strip_info->sx_buff[strip_info->
-							    sx_count] =
-					    *cp;
-				strip_info->sx_count++;
-			}
-		}
-		cp++;
-	}
-	spin_unlock_bh(&strip_lock);
-}
-
-
-/************************************************************************/
-/* General control routines						*/
-
-static int set_mac_address(struct strip *strip_info,
-			   MetricomAddress * addr)
-{
-	/*
-	 * We're using a manually specified address if the address is set
-	 * to anything other than all ones. Setting the address to all ones
-	 * disables manual mode and goes back to automatic address determination
-	 * (tracking the true address that the radio has).
-	 */
-	strip_info->manual_dev_addr =
-	    memcmp(addr->c, broadcast_address.c,
-		   sizeof(broadcast_address));
-	if (strip_info->manual_dev_addr)
-		*(MetricomAddress *) strip_info->dev->dev_addr = *addr;
-	else
-		*(MetricomAddress *) strip_info->dev->dev_addr =
-		    strip_info->true_dev_addr;
-	return 0;
-}
-
-static int strip_set_mac_address(struct net_device *dev, void *addr)
-{
-	struct strip *strip_info = netdev_priv(dev);
-	struct sockaddr *sa = addr;
-	printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
-	set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
-	return 0;
-}
-
-static struct net_device_stats *strip_get_stats(struct net_device *dev)
-{
-	struct strip *strip_info = netdev_priv(dev);
-	static struct net_device_stats stats;
-
-	memset(&stats, 0, sizeof(struct net_device_stats));
-
-	stats.rx_packets = strip_info->rx_packets;
-	stats.tx_packets = strip_info->tx_packets;
-	stats.rx_dropped = strip_info->rx_dropped;
-	stats.tx_dropped = strip_info->tx_dropped;
-	stats.tx_errors = strip_info->tx_errors;
-	stats.rx_errors = strip_info->rx_errors;
-	stats.rx_over_errors = strip_info->rx_over_errors;
-	return (&stats);
-}
-
-
-/************************************************************************/
-/* Opening and closing							*/
-
-/*
- * Here's the order things happen:
- * When the user runs "slattach -p strip ..."
- *  1. The TTY module calls strip_open;;
- *  2. strip_open calls strip_alloc
- *  3.                  strip_alloc calls register_netdev
- *  4.                  register_netdev calls strip_dev_init
- *  5. then strip_open finishes setting up the strip_info
- *
- * When the user runs "ifconfig st<x> up address netmask ..."
- *  6. strip_open_low gets called
- *
- * When the user runs "ifconfig st<x> down"
- *  7. strip_close_low gets called
- *
- * When the user kills the slattach process
- *  8. strip_close gets called
- *  9. strip_close calls dev_close
- * 10. if the device is still up, then dev_close calls strip_close_low
- * 11. strip_close calls strip_free
- */
-
-/* Open the low-level part of the STRIP channel. Easy! */
-
-static int strip_open_low(struct net_device *dev)
-{
-	struct strip *strip_info = netdev_priv(dev);
-
-	if (strip_info->tty == NULL)
-		return (-ENODEV);
-
-	if (!allocate_buffers(strip_info, dev->mtu))
-		return (-ENOMEM);
-
-	strip_info->sx_count = 0;
-	strip_info->tx_left = 0;
-
-	strip_info->discard = 0;
-	strip_info->working = FALSE;
-	strip_info->firmware_level = NoStructure;
-	strip_info->next_command = CompatibilityCommand;
-	strip_info->user_baud = tty_get_baud_rate(strip_info->tty);
-
-	printk(KERN_INFO "%s: Initializing Radio.\n",
-	       strip_info->dev->name);
-	ResetRadio(strip_info);
-	strip_info->idle_timer.expires = jiffies + 1 * HZ;
-	add_timer(&strip_info->idle_timer);
-	netif_wake_queue(dev);
-	return (0);
-}
-
-
-/*
- * Close the low-level part of the STRIP channel. Easy!
- */
-
-static int strip_close_low(struct net_device *dev)
-{
-	struct strip *strip_info = netdev_priv(dev);
-
-	if (strip_info->tty == NULL)
-		return -EBUSY;
-	clear_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags);
-	netif_stop_queue(dev);
-
-	/*
-	 * Free all STRIP frame buffers.
-	 */
-	kfree(strip_info->rx_buff);
-	strip_info->rx_buff = NULL;
-	kfree(strip_info->sx_buff);
-	strip_info->sx_buff = NULL;
-	kfree(strip_info->tx_buff);
-	strip_info->tx_buff = NULL;
-
-	del_timer(&strip_info->idle_timer);
-	return 0;
-}
-
-static const struct header_ops strip_header_ops = {
-	.create = strip_header,
-	.rebuild = strip_rebuild_header,
-};
-
-
-static const struct net_device_ops strip_netdev_ops = {
-	.ndo_open 	= strip_open_low,
-	.ndo_stop 	= strip_close_low,
-	.ndo_start_xmit = strip_xmit,
-	.ndo_set_mac_address = strip_set_mac_address,
-	.ndo_get_stats	= strip_get_stats,
-	.ndo_change_mtu = strip_change_mtu,
-};
-
-/*
- * This routine is called by DDI when the
- * (dynamically assigned) device is registered
- */
-
-static void strip_dev_setup(struct net_device *dev)
-{
-	/*
-	 * Finish setting up the DEVICE info.
-	 */
-
-	dev->trans_start = 0;
-	dev->tx_queue_len = 30;	/* Drop after 30 frames queued */
-
-	dev->flags = 0;
-	dev->mtu = DEFAULT_STRIP_MTU;
-	dev->type = ARPHRD_METRICOM;	/* dtang */
-	dev->hard_header_len = sizeof(STRIP_Header);
-	/*
-	 *  netdev_priv(dev) Already holds a pointer to our struct strip
-	 */
-
-	*(MetricomAddress *)dev->broadcast = broadcast_address;
-	dev->dev_addr[0] = 0;
-	dev->addr_len = sizeof(MetricomAddress);
-
-	dev->header_ops = &strip_header_ops,
-	dev->netdev_ops = &strip_netdev_ops;
-}
-
-/*
- * Free a STRIP channel.
- */
-
-static void strip_free(struct strip *strip_info)
-{
-	spin_lock_bh(&strip_lock);
-	list_del_rcu(&strip_info->list);
-	spin_unlock_bh(&strip_lock);
-
-	strip_info->magic = 0;
-
-	free_netdev(strip_info->dev);
-}
-
-
-/*
- * Allocate a new free STRIP channel
- */
-static struct strip *strip_alloc(void)
-{
-	struct list_head *n;
-	struct net_device *dev;
-	struct strip *strip_info;
-
-	dev = alloc_netdev(sizeof(struct strip), "st%d",
-			   strip_dev_setup);
-
-	if (!dev)
-		return NULL;	/* If no more memory, return */
-
-
-	strip_info = netdev_priv(dev);
-	strip_info->dev = dev;
-
-	strip_info->magic = STRIP_MAGIC;
-	strip_info->tty = NULL;
-
-	strip_info->gratuitous_arp = jiffies + LongTime;
-	strip_info->arp_interval = 0;
-	init_timer(&strip_info->idle_timer);
-	strip_info->idle_timer.data = (long) dev;
-	strip_info->idle_timer.function = strip_IdleTask;
-
-
-	spin_lock_bh(&strip_lock);
- rescan:
-	/*
-	 * Search the list to find where to put our new entry
-	 * (and in the process decide what channel number it is
-	 * going to be)
-	 */
-	list_for_each(n, &strip_list) {
-		struct strip *s = hlist_entry(n, struct strip, list);
-
-		if (s->dev->base_addr == dev->base_addr) {
-			++dev->base_addr;
-			goto rescan;
-		}
-	}
-
-	sprintf(dev->name, "st%ld", dev->base_addr);
-
-	list_add_tail_rcu(&strip_info->list, &strip_list);
-	spin_unlock_bh(&strip_lock);
-
-	return strip_info;
-}
-
-/*
- * Open the high-level part of the STRIP channel.
- * This function is called by the TTY module when the
- * STRIP line discipline is called for.  Because we are
- * sure the tty line exists, we only have to link it to
- * a free STRIP channel...
- */
-
-static int strip_open(struct tty_struct *tty)
-{
-	struct strip *strip_info = tty->disc_data;
-
-	/*
-	 * First make sure we're not already connected.
-	 */
-
-	if (strip_info && strip_info->magic == STRIP_MAGIC)
-		return -EEXIST;
-
-	/*
-	 * We need a write method.
-	 */
-
-	if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
-		return -EOPNOTSUPP;
-
-	/*
-	 * OK.  Find a free STRIP channel to use.
-	 */
-	if ((strip_info = strip_alloc()) == NULL)
-		return -ENFILE;
-
-	/*
-	 * Register our newly created device so it can be ifconfig'd
-	 * strip_dev_init() will be called as a side-effect
-	 */
-
-	if (register_netdev(strip_info->dev) != 0) {
-		printk(KERN_ERR "strip: register_netdev() failed.\n");
-		strip_free(strip_info);
-		return -ENFILE;
-	}
-
-	strip_info->tty = tty;
-	tty->disc_data = strip_info;
-	tty->receive_room = 65536;
-
-	tty_driver_flush_buffer(tty);
-
-	/*
-	 * Restore default settings
-	 */
-
-	strip_info->dev->type = ARPHRD_METRICOM;	/* dtang */
-
-	/*
-	 * Set tty options
-	 */
-
-	tty->termios->c_iflag |= IGNBRK | IGNPAR;	/* Ignore breaks and parity errors. */
-	tty->termios->c_cflag |= CLOCAL;	/* Ignore modem control signals. */
-	tty->termios->c_cflag &= ~HUPCL;	/* Don't close on hup */
-
-	printk(KERN_INFO "STRIP: device \"%s\" activated\n",
-	       strip_info->dev->name);
-
-	/*
-	 * Done.  We have linked the TTY line to a channel.
-	 */
-	return (strip_info->dev->base_addr);
-}
-
-/*
- * Close down a STRIP channel.
- * This means flushing out any pending queues, and then restoring the
- * TTY line discipline to what it was before it got hooked to STRIP
- * (which usually is TTY again).
- */
-
-static void strip_close(struct tty_struct *tty)
-{
-	struct strip *strip_info = tty->disc_data;
-
-	/*
-	 * First make sure we're connected.
-	 */
-
-	if (!strip_info || strip_info->magic != STRIP_MAGIC)
-		return;
-
-	unregister_netdev(strip_info->dev);
-
-	tty->disc_data = NULL;
-	strip_info->tty = NULL;
-	printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
-	       strip_info->dev->name);
-	strip_free(strip_info);
-	tty->disc_data = NULL;
-}
-
-
-/************************************************************************/
-/* Perform I/O control calls on an active STRIP channel.		*/
-
-static int strip_ioctl(struct tty_struct *tty, struct file *file,
-		       unsigned int cmd, unsigned long arg)
-{
-	struct strip *strip_info = tty->disc_data;
-
-	/*
-	 * First make sure we're connected.
-	 */
-
-	if (!strip_info || strip_info->magic != STRIP_MAGIC)
-		return -EINVAL;
-
-	switch (cmd) {
-	case SIOCGIFNAME:
-		if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
-			return -EFAULT;
-		break;
-	case SIOCSIFHWADDR:
-	{
-		MetricomAddress addr;
-		//printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name);
-		if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
-			return -EFAULT;
-		return set_mac_address(strip_info, &addr);
-	}
-	default:
-		return tty_mode_ioctl(tty, file, cmd, arg);
-		break;
-	}
-	return 0;
-}
-
-
-/************************************************************************/
-/* Initialization							*/
-
-static struct tty_ldisc_ops strip_ldisc = {
-	.magic = TTY_LDISC_MAGIC,
-	.name = "strip",
-	.owner = THIS_MODULE,
-	.open = strip_open,
-	.close = strip_close,
-	.ioctl = strip_ioctl,
-	.receive_buf = strip_receive_buf,
-	.write_wakeup = strip_write_some_more,
-};
-
-/*
- * Initialize the STRIP driver.
- * This routine is called at boot time, to bootstrap the multi-channel
- * STRIP driver
- */
-
-static char signon[] __initdata =
-    KERN_INFO "STRIP: Version %s (unlimited channels)\n";
-
-static int __init strip_init_driver(void)
-{
-	int status;
-
-	printk(signon, StripVersion);
-
-	
-	/*
-	 * Fill in our line protocol discipline, and register it
-	 */
-	if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
-		printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n",
-		       status);
-
-	/*
-	 * Register the status file with /proc
-	 */
-	proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops);
-
-	return status;
-}
-
-module_init(strip_init_driver);
-
-static const char signoff[] __exitdata =
-    KERN_INFO "STRIP: Module Unloaded\n";
-
-static void __exit strip_exit_driver(void)
-{
-	int i;
-	struct list_head *p,*n;
-
-	/* module ref count rules assure that all entries are unregistered */
-	list_for_each_safe(p, n, &strip_list) {
-		struct strip *s = list_entry(p, struct strip, list);
-		strip_free(s);
-	}
-
-	/* Unregister with the /proc/net file here. */
-	proc_net_remove(&init_net, "strip");
-
-	if ((i = tty_unregister_ldisc(N_STRIP)))
-		printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
-
-	printk(signoff);
-}
-
-module_exit(strip_exit_driver);
-
-MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
-MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
-MODULE_LICENSE("Dual BSD/GPL");
-
-MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4383 +0,0 @@
-/*
- *	WaveLAN ISA driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follows (also see the end of this file).
- * See wavelan.p.h for details.
- *
- *
- *
- * AT&T GIS (nee NCR) WaveLAN card:
- *	An Ethernet-like radio transceiver
- *	controlled by an Intel 82586 coprocessor.
- */
-
-#include "wavelan.p.h"		/* Private header */
-
-/************************* MISC SUBROUTINES **************************/
-/*
- * Subroutines which won't fit in one of the following category
- * (WaveLAN modem or i82586)
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Translate irq number to PSA irq parameter
- */
-static u8 wv_irq_to_psa(int irq)
-{
-	if (irq < 0 || irq >= ARRAY_SIZE(irqvals))
-		return 0;
-
-	return irqvals[irq];
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Translate PSA irq parameter to irq number 
- */
-static int __init wv_psa_to_irq(u8 irqval)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(irqvals); i++)
-		if (irqvals[i] == irqval)
-			return i;
-
-	return -1;
-}
-
-/********************* HOST ADAPTER SUBROUTINES *********************/
-/*
- * Useful subroutines to manage the WaveLAN ISA interface
- *
- * One major difference with the PCMCIA hardware (except the port mapping)
- * is that we have to keep the state of the Host Control Register
- * because of the interrupt enable & bus size flags.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read from card's Host Adaptor Status Register.
- */
-static inline u16 hasr_read(unsigned long ioaddr)
-{
-	return (inw(HASR(ioaddr)));
-}				/* hasr_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register.
- */
-static inline void hacr_write(unsigned long ioaddr, u16 hacr)
-{
-	outw(hacr, HACR(ioaddr));
-}				/* hacr_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register. Include a delay for
- * those times when it is needed.
- */
-static void hacr_write_slow(unsigned long ioaddr, u16 hacr)
-{
-	hacr_write(ioaddr, hacr);
-	/* delay might only be needed sometimes */
-	mdelay(1);
-}				/* hacr_write_slow */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the channel attention bit.
- */
-static inline void set_chan_attn(unsigned long ioaddr, u16 hacr)
-{
-	hacr_write(ioaddr, hacr | HACR_CA);
-}				/* set_chan_attn */
-
-/*------------------------------------------------------------------*/
-/*
- * Reset, and then set host adaptor into default mode.
- */
-static inline void wv_hacr_reset(unsigned long ioaddr)
-{
-	hacr_write_slow(ioaddr, HACR_RESET);
-	hacr_write(ioaddr, HACR_DEFAULT);
-}				/* wv_hacr_reset */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_off(unsigned long ioaddr, u16 hacr)
-{
-	hacr &= ~HACR_16BITS;
-	hacr_write(ioaddr, hacr);
-}				/* wv_16_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
-{
-	hacr |= HACR_16BITS;
-	hacr_write(ioaddr, hacr);
-}				/* wv_16_on */
-
-/*------------------------------------------------------------------*/
-/*
- * Disable interrupts on the WaveLAN hardware.
- * (called by wv_82586_stop())
- */
-static inline void wv_ints_off(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	
-	lp->hacr &= ~HACR_INTRON;
-	hacr_write(ioaddr, lp->hacr);
-}				/* wv_ints_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Enable interrupts on the WaveLAN hardware.
- * (called by wv_hw_reset())
- */
-static inline void wv_ints_on(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-
-	lp->hacr |= HACR_INTRON;
-	hacr_write(ioaddr, lp->hacr);
-}				/* wv_ints_on */
-
-/******************* MODEM MANAGEMENT SUBROUTINES *******************/
-/*
- * Useful subroutines to manage the modem of the WaveLAN
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Parameter Storage Area from the WaveLAN card's memory
- */
-/*
- * Read bytes from the PSA.
- */
-static void psa_read(unsigned long ioaddr, u16 hacr, int o,	/* offset in PSA */
-		     u8 * b,	/* buffer to fill */
-		     int n)
-{				/* size to read */
-	wv_16_off(ioaddr, hacr);
-
-	while (n-- > 0) {
-		outw(o, PIOR2(ioaddr));
-		o++;
-		*b++ = inb(PIOP2(ioaddr));
-	}
-
-	wv_16_on(ioaddr, hacr);
-}				/* psa_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write the Parameter Storage Area to the WaveLAN card's memory.
- */
-static void psa_write(unsigned long ioaddr, u16 hacr, int o,	/* Offset in PSA */
-		      u8 * b,	/* Buffer in memory */
-		      int n)
-{				/* Length of buffer */
-	int count = 0;
-
-	wv_16_off(ioaddr, hacr);
-
-	while (n-- > 0) {
-		outw(o, PIOR2(ioaddr));
-		o++;
-
-		outb(*b, PIOP2(ioaddr));
-		b++;
-
-		/* Wait for the memory to finish its write cycle */
-		count = 0;
-		while ((count++ < 100) &&
-		       (hasr_read(ioaddr) & HASR_PSA_BUSY)) mdelay(1);
-	}
-
-	wv_16_on(ioaddr, hacr);
-}				/* psa_write */
-
-#ifdef SET_PSA_CRC
-/*------------------------------------------------------------------*/
-/*
- * Calculate the PSA CRC
- * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
- * NOTE: By specifying a length including the CRC position the
- * returned value should be zero. (i.e. a correct checksum in the PSA)
- *
- * The Windows drivers don't use the CRC, but the AP and the PtP tool
- * depend on it.
- */
-static u16 psa_crc(u8 * psa,	/* The PSA */
-			      int size)
-{				/* Number of short for CRC */
-	int byte_cnt;		/* Loop on the PSA */
-	u16 crc_bytes = 0;	/* Data in the PSA */
-	int bit_cnt;		/* Loop on the bits of the short */
-
-	for (byte_cnt = 0; byte_cnt < size; byte_cnt++) {
-		crc_bytes ^= psa[byte_cnt];	/* Its an xor */
-
-		for (bit_cnt = 1; bit_cnt < 9; bit_cnt++) {
-			if (crc_bytes & 0x0001)
-				crc_bytes = (crc_bytes >> 1) ^ 0xA001;
-			else
-				crc_bytes >>= 1;
-		}
-	}
-
-	return crc_bytes;
-}				/* psa_crc */
-#endif				/* SET_PSA_CRC */
-
-/*------------------------------------------------------------------*/
-/*
- * update the checksum field in the Wavelan's PSA
- */
-static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr)
-{
-#ifdef SET_PSA_CRC
-	psa_t psa;
-	u16 crc;
-
-	/* read the parameter storage area */
-	psa_read(ioaddr, hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-	/* update the checksum */
-	crc = psa_crc((unsigned char *) &psa,
-		      sizeof(psa) - sizeof(psa.psa_crc[0]) -
-		      sizeof(psa.psa_crc[1])
-		      - sizeof(psa.psa_crc_status));
-
-	psa.psa_crc[0] = crc & 0xFF;
-	psa.psa_crc[1] = (crc & 0xFF00) >> 8;
-
-	/* Write it ! */
-	psa_write(ioaddr, hacr, (char *) &psa.psa_crc - (char *) &psa,
-		  (unsigned char *) &psa.psa_crc, 2);
-
-#ifdef DEBUG_IOCTL_INFO
-	printk(KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
-	       dev->name, psa.psa_crc[0], psa.psa_crc[1]);
-
-	/* Check again (luxury !) */
-	crc = psa_crc((unsigned char *) &psa,
-		      sizeof(psa) - sizeof(psa.psa_crc_status));
-
-	if (crc != 0)
-		printk(KERN_WARNING
-		       "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n",
-		       dev->name);
-#endif				/* DEBUG_IOCTL_INFO */
-#endif				/* SET_PSA_CRC */
-}				/* update_psa_checksum */
-
-/*------------------------------------------------------------------*/
-/*
- * Write 1 byte to the MMC.
- */
-static void mmc_out(unsigned long ioaddr, u16 o, u8 d)
-{
-	int count = 0;
-
-	/* Wait for MMC to go idle */
-	while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-		udelay(10);
-
-	outw((u16) (((u16) d << 8) | (o << 1) | 1), MMCR(ioaddr));
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to write bytes to the Modem Management Controller.
- * We start at the end because it is the way it should be!
- */
-static void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n)
-{
-	o += n;
-	b += n;
-
-	while (n-- > 0)
-		mmc_out(ioaddr, --o, *(--b));
-}				/* mmc_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Read a byte from the MMC.
- * Optimised version for 1 byte, avoid using memory.
- */
-static u8 mmc_in(unsigned long ioaddr, u16 o)
-{
-	int count = 0;
-
-	while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-		udelay(10);
-	outw(o << 1, MMCR(ioaddr));
-
-	while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-		udelay(10);
-	return (u8) (inw(MMCR(ioaddr)) >> 8);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read bytes from the Modem Management Controller.
- * The implementation is complicated by a lack of address lines,
- * which prevents decoding of the low-order bit.
- * (code has just been moved in the above function)
- * We start at the end because it is the way it should be!
- */
-static inline void mmc_read(unsigned long ioaddr, u8 o, u8 * b, int n)
-{
-	o += n;
-	b += n;
-
-	while (n-- > 0)
-		*(--b) = mmc_in(ioaddr, --o);
-}				/* mmc_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Get the type of encryption available.
- */
-static inline int mmc_encr(unsigned long ioaddr)
-{				/* I/O port of the card */
-	int temp;
-
-	temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail));
-	if ((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
-		return 0;
-	else
-		return temp;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wait for the frequency EEPROM to complete a command.
- * I hope this one will be optimally inlined.
- */
-static inline void fee_wait(unsigned long ioaddr,	/* I/O port of the card */
-			    int delay,	/* Base delay to wait for */
-			    int number)
-{				/* Number of time to wait */
-	int count = 0;		/* Wait only a limited time */
-
-	while ((count++ < number) &&
-	       (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-		MMR_FEE_STATUS_BUSY)) udelay(delay);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the Frequency EEPROM (frequency select cards).
- */
-static void fee_read(unsigned long ioaddr,	/* I/O port of the card */
-		     u16 o,	/* destination offset */
-		     u16 * b,	/* data buffer */
-		     int n)
-{				/* number of registers */
-	b += n;			/* Position at the end of the area */
-
-	/* Write the address */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-	/* Loop on all buffer */
-	while (n-- > 0) {
-		/* Write the read command */
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-			MMW_FEE_CTRL_READ);
-
-		/* Wait until EEPROM is ready (should be quick). */
-		fee_wait(ioaddr, 10, 100);
-
-		/* Read the value. */
-		*--b = ((mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)) << 8) |
-			mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
-	}
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes from the Frequency EEPROM (frequency select cards).
- * This is a bit complicated, because the frequency EEPROM has to
- * be unprotected and the write enabled.
- * Jean II
- */
-static void fee_write(unsigned long ioaddr,	/* I/O port of the card */
-		      u16 o,	/* destination offset */
-		      u16 * b,	/* data buffer */
-		      int n)
-{				/* number of registers */
-	b += n;			/* Position at the end of the area. */
-
-#ifdef EEPROM_IS_PROTECTED	/* disabled */
-#ifdef DOESNT_SEEM_TO_WORK	/* disabled */
-	/* Ask to read the protected register */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
-
-	fee_wait(ioaddr, 10, 100);
-
-	/* Read the protected register. */
-	printk("Protected 2:  %02X-%02X\n",
-	       mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)),
-	       mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
-#endif				/* DOESNT_SEEM_TO_WORK */
-
-	/* Enable protected register. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
-
-	fee_wait(ioaddr, 10, 100);
-
-	/* Unprotect area. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n);
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-#ifdef DOESNT_SEEM_TO_WORK	/* disabled */
-	/* or use: */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
-#endif				/* DOESNT_SEEM_TO_WORK */
-
-	fee_wait(ioaddr, 10, 100);
-#endif				/* EEPROM_IS_PROTECTED */
-
-	/* Write enable. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
-
-	fee_wait(ioaddr, 10, 100);
-
-	/* Write the EEPROM address. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-	/* Loop on all buffer */
-	while (n-- > 0) {
-		/* Write the value. */
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
-
-		/* Write the write command. */
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-			MMW_FEE_CTRL_WRITE);
-
-		/* WaveLAN documentation says to wait at least 10 ms for EEBUSY = 0 */
-		mdelay(10);
-		fee_wait(ioaddr, 10, 100);
-	}
-
-	/* Write disable. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
-
-	fee_wait(ioaddr, 10, 100);
-
-#ifdef EEPROM_IS_PROTECTED	/* disabled */
-	/* Reprotect EEPROM. */
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);
-	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-
-	fee_wait(ioaddr, 10, 100);
-#endif				/* EEPROM_IS_PROTECTED */
-}
-
-/************************ I82586 SUBROUTINES *************************/
-/*
- * Useful subroutines to manage the Ethernet controller
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the on-board RAM.
- * Why does inlining this function make it fail?
- */
-static /*inline */ void obram_read(unsigned long ioaddr,
-				   u16 o, u8 * b, int n)
-{
-	outw(o, PIOR1(ioaddr));
-	insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes to the on-board RAM.
- */
-static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n)
-{
-	outw(o, PIOR1(ioaddr));
-	outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Acknowledge the reading of the status issued by the i82586.
- */
-static void wv_ack(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	u16 scb_cs;
-	int i;
-
-	obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-		   (unsigned char *) &scb_cs, sizeof(scb_cs));
-	scb_cs &= SCB_ST_INT;
-
-	if (scb_cs == 0)
-		return;
-
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-	set_chan_attn(ioaddr, lp->hacr);
-
-	for (i = 1000; i > 0; i--) {
-		obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-			   (unsigned char *) &scb_cs, sizeof(scb_cs));
-		if (scb_cs == 0)
-			break;
-
-		udelay(10);
-	}
-	udelay(100);
-
-#ifdef DEBUG_CONFIG_ERROR
-	if (i <= 0)
-		printk(KERN_INFO
-		       "%s: wv_ack(): board not accepting command.\n",
-		       dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Set channel attention bit and busy wait until command has
- * completed, then acknowledge completion of the command.
- */
-static int wv_synchronous_cmd(struct net_device * dev, const char *str)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	u16 scb_cmd;
-	ach_t cb;
-	int i;
-
-	scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &scb_cmd, sizeof(scb_cmd));
-
-	set_chan_attn(ioaddr, lp->hacr);
-
-	for (i = 1000; i > 0; i--) {
-		obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb,
-			   sizeof(cb));
-		if (cb.ac_status & AC_SFLD_C)
-			break;
-
-		udelay(10);
-	}
-	udelay(100);
-
-	if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO "%s: %s failed; status = 0x%x\n",
-		       dev->name, str, cb.ac_status);
-#endif
-#ifdef DEBUG_I82586_SHOW
-		wv_scb_show(ioaddr);
-#endif
-		return -1;
-	}
-
-	/* Ack the status */
-	wv_ack(dev);
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Configuration commands completion interrupt.
- * Check if done, and if OK.
- */
-static int
-wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
-{
-	unsigned short mcs_addr;
-	unsigned short status;
-	int ret;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name);
-#endif
-
-	mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t)
-	    + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t);
-
-	/* Read the status of the last command (set mc list). */
-	obram_read(ioaddr, acoff(mcs_addr, ac_status),
-		   (unsigned char *) &status, sizeof(status));
-
-	/* If not completed -> exit */
-	if ((status & AC_SFLD_C) == 0)
-		ret = 0;	/* Not ready to be scrapped */
-	else {
-#ifdef DEBUG_CONFIG_ERROR
-		unsigned short cfg_addr;
-		unsigned short ias_addr;
-
-		/* Check mc_config command */
-		if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-			printk(KERN_INFO
-			       "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n",
-			       dev->name, status);
-
-		/* check ia-config command */
-		ias_addr = mcs_addr - sizeof(ac_ias_t);
-		obram_read(ioaddr, acoff(ias_addr, ac_status),
-			   (unsigned char *) &status, sizeof(status));
-		if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-			printk(KERN_INFO
-			       "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n",
-			       dev->name, status);
-
-		/* Check config command. */
-		cfg_addr = ias_addr - sizeof(ac_cfg_t);
-		obram_read(ioaddr, acoff(cfg_addr, ac_status),
-			   (unsigned char *) &status, sizeof(status));
-		if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-			printk(KERN_INFO
-			       "%s: wv_config_complete(): configure failed; status = 0x%x\n",
-			       dev->name, status);
-#endif	/* DEBUG_CONFIG_ERROR */
-
-		ret = 1;	/* Ready to be scrapped */
-	}
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name,
-	       ret);
-#endif
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Command completion interrupt.
- * Reclaim as many freed tx buffers as we can.
- * (called in wavelan_interrupt()).
- * Note : the spinlock is already grabbed for us.
- */
-static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
-{
-	int nreaped = 0;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name);
-#endif
-
-	/* Loop on all the transmit buffers */
-	while (lp->tx_first_in_use != I82586NULL) {
-		unsigned short tx_status;
-
-		/* Read the first transmit buffer */
-		obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status),
-			   (unsigned char *) &tx_status,
-			   sizeof(tx_status));
-
-		/* If not completed -> exit */
-		if ((tx_status & AC_SFLD_C) == 0)
-			break;
-
-		/* Hack for reconfiguration */
-		if (tx_status == 0xFFFF)
-			if (!wv_config_complete(dev, ioaddr, lp))
-				break;	/* Not completed */
-
-		/* We now remove this buffer */
-		nreaped++;
-		--lp->tx_n_in_use;
-
-/*
-if (lp->tx_n_in_use > 0)
-	printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
-*/
-
-		/* Was it the last one? */
-		if (lp->tx_n_in_use <= 0)
-			lp->tx_first_in_use = I82586NULL;
-		else {
-			/* Next one in the chain */
-			lp->tx_first_in_use += TXBLOCKZ;
-			if (lp->tx_first_in_use >=
-			    OFFSET_CU +
-			    NTXBLOCKS * TXBLOCKZ) lp->tx_first_in_use -=
-				    NTXBLOCKS * TXBLOCKZ;
-		}
-
-		/* Hack for reconfiguration */
-		if (tx_status == 0xFFFF)
-			continue;
-
-		/* Now, check status of the finished command */
-		if (tx_status & AC_SFLD_OK) {
-			int ncollisions;
-
-			dev->stats.tx_packets++;
-			ncollisions = tx_status & AC_SFLD_MAXCOL;
-			dev->stats.collisions += ncollisions;
-#ifdef DEBUG_TX_INFO
-			if (ncollisions > 0)
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx completed after %d collisions.\n",
-				       dev->name, ncollisions);
-#endif
-		} else {
-			dev->stats.tx_errors++;
-			if (tx_status & AC_SFLD_S10) {
-				dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx error: no CS.\n",
-				       dev->name);
-#endif
-			}
-			if (tx_status & AC_SFLD_S9) {
-				dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx error: lost CTS.\n",
-				       dev->name);
-#endif
-			}
-			if (tx_status & AC_SFLD_S8) {
-				dev->stats.tx_fifo_errors++;
-#ifdef DEBUG_TX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx error: slow DMA.\n",
-				       dev->name);
-#endif
-			}
-			if (tx_status & AC_SFLD_S6) {
-				dev->stats.tx_heartbeat_errors++;
-#ifdef DEBUG_TX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx error: heart beat.\n",
-				       dev->name);
-#endif
-			}
-			if (tx_status & AC_SFLD_S5) {
-				dev->stats.tx_aborted_errors++;
-#ifdef DEBUG_TX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_complete(): tx error: too many collisions.\n",
-				       dev->name);
-#endif
-			}
-		}
-
-#ifdef DEBUG_TX_INFO
-		printk(KERN_DEBUG
-		       "%s: wv_complete(): tx completed, tx_status 0x%04x\n",
-		       dev->name, tx_status);
-#endif
-	}
-
-#ifdef DEBUG_INTERRUPT_INFO
-	if (nreaped > 1)
-		printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n",
-		       dev->name, nreaped);
-#endif
-
-	/*
-	 * Inform upper layers.
-	 */
-	if (lp->tx_n_in_use < NTXBLOCKS - 1) {
-		netif_wake_queue(dev);
-	}
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name);
-#endif
-	return nreaped;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Reconfigure the i82586, or at least ask for it.
- * Because wv_82586_config uses a transmission buffer, we must do it
- * when we are sure that there is one left, so we do it now
- * or in wavelan_packet_xmit() (I can't find any better place,
- * wavelan_interrupt is not an option), so you may experience
- * delays sometimes.
- */
-static void wv_82586_reconfig(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-
-	/* Arm the flag, will be cleard in wv_82586_config() */
-	lp->reconfig_82586 = 1;
-
-	/* Check if we can do it now ! */
-	if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
-		spin_lock_irqsave(&lp->spinlock, flags);
-		/* May fail */
-		wv_82586_config(dev);
-		spin_unlock_irqrestore(&lp->spinlock, flags);
-	}
-	else {
-#ifdef DEBUG_CONFIG_INFO
-		printk(KERN_DEBUG
-		       "%s: wv_82586_reconfig(): delayed (state = %lX)\n",
-			       dev->name, dev->state);
-#endif
-	}
-}
-
-/********************* DEBUG & INFO SUBROUTINES *********************/
-/*
- * This routine is used in the code to show information for debugging.
- * Most of the time, it dumps the contents of hardware structures.
- */
-
-#ifdef DEBUG_PSA_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted contents of the Parameter Storage Area.
- */
-static void wv_psa_show(psa_t * p)
-{
-	printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");
-	printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
-	       p->psa_io_base_addr_1,
-	       p->psa_io_base_addr_2,
-	       p->psa_io_base_addr_3, p->psa_io_base_addr_4);
-	printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
-	       p->psa_rem_boot_addr_1,
-	       p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3);
-	printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
-	printk("psa_int_req_no: %d\n", p->psa_int_req_no);
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
-#endif				/* DEBUG_SHOW_UNUSED */
-	printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
-	printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
-	printk(KERN_DEBUG "psa_univ_local_sel: %d, ",
-	       p->psa_univ_local_sel);
-	printk("psa_comp_number: %d, ", p->psa_comp_number);
-	printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
-	printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
-	       p->psa_feature_select);
-	printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
-	printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
-	printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
-	printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0],
-	       p->psa_nwid[1]);
-	printk("psa_nwid_select: %d\n", p->psa_nwid_select);
-	printk(KERN_DEBUG "psa_encryption_select: %d, ",
-	       p->psa_encryption_select);
-	printk
-	    ("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-	     p->psa_encryption_key[0], p->psa_encryption_key[1],
-	     p->psa_encryption_key[2], p->psa_encryption_key[3],
-	     p->psa_encryption_key[4], p->psa_encryption_key[5],
-	     p->psa_encryption_key[6], p->psa_encryption_key[7]);
-	printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
-	printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
-	       p->psa_call_code[0]);
-	printk
-	    ("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-	     p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2],
-	     p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
-	     p->psa_call_code[6], p->psa_call_code[7]);
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
-	       p->psa_reserved[0],
-	       p->psa_reserved[1]);
-#endif				/* DEBUG_SHOW_UNUSED */
-	printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
-	printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
-	printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
-}				/* wv_psa_show */
-#endif				/* DEBUG_PSA_SHOW */
-
-#ifdef DEBUG_MMC_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the Modem Management Controller.
- * This function needs to be completed.
- */
-static void wv_mmc_show(struct net_device * dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	mmr_t m;
-
-	/* Basic check */
-	if (hasr_read(ioaddr) & HASR_NO_CLK) {
-		printk(KERN_WARNING
-		       "%s: wv_mmc_show: modem not connected\n",
-		       dev->name);
-		return;
-	}
-
-	/* Read the mmc */
-	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-	mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
-	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-	/* Don't forget to update statistics */
-	lp->wstats.discard.nwid +=
-	    (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
-	printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG
-	       "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-	       m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2],
-	       m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5],
-	       m.mmr_unused0[6], m.mmr_unused0[7]);
-#endif				/* DEBUG_SHOW_UNUSED */
-	printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
-	       m.mmr_des_avail, m.mmr_des_status);
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
-	       m.mmr_unused1[0],
-	       m.mmr_unused1[1],
-	       m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]);
-#endif				/* DEBUG_SHOW_UNUSED */
-	printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
-	       m.mmr_dce_status,
-	       (m.
-		mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ?
-	       "energy detected," : "",
-	       (m.
-		mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
-	       "loop test indicated," : "",
-	       (m.
-		mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ?
-	       "transmitter on," : "",
-	       (m.
-		mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
-	       "jabber timer expired," : "");
-	printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id);
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
-	       m.mmr_unused2[0], m.mmr_unused2[1]);
-#endif				/* DEBUG_SHOW_UNUSED */
-	printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
-	       (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
-	       (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
-	printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
-	       m.mmr_thr_pre_set & MMR_THR_PRE_SET,
-	       (m.
-		mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" :
-	       "below");
-	printk(KERN_DEBUG "signal_lvl: %d [%s], ",
-	       m.mmr_signal_lvl & MMR_SIGNAL_LVL,
-	       (m.
-		mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" :
-	       "no new msg");
-	printk("silence_lvl: %d [%s], ",
-	       m.mmr_silence_lvl & MMR_SILENCE_LVL,
-	       (m.
-		mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" :
-	       "no new update");
-	printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
-	       (m.
-		mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" :
-	       "Antenna 0");
-#ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
-#endif				/* DEBUG_SHOW_UNUSED */
-}				/* wv_mmc_show */
-#endif				/* DEBUG_MMC_SHOW */
-
-#ifdef DEBUG_I82586_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the last block of the i82586 memory.
- */
-static void wv_scb_show(unsigned long ioaddr)
-{
-	scb_t scb;
-
-	obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-		   sizeof(scb));
-
-	printk(KERN_DEBUG "##### WaveLAN system control block: #####\n");
-
-	printk(KERN_DEBUG "status: ");
-	printk("stat 0x%x[%s%s%s%s] ",
-	       (scb.
-		scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA |
-			      SCB_ST_RNR)) >> 12,
-	       (scb.
-		scb_status & SCB_ST_CX) ? "command completion interrupt," :
-	       "", (scb.scb_status & SCB_ST_FR) ? "frame received," : "",
-	       (scb.
-		scb_status & SCB_ST_CNA) ? "command unit not active," : "",
-	       (scb.
-		scb_status & SCB_ST_RNR) ? "receiving unit not ready," :
-	       "");
-	printk("cus 0x%x[%s%s%s] ", (scb.scb_status & SCB_ST_CUS) >> 8,
-	       ((scb.scb_status & SCB_ST_CUS) ==
-		SCB_ST_CUS_IDLE) ? "idle" : "",
-	       ((scb.scb_status & SCB_ST_CUS) ==
-		SCB_ST_CUS_SUSP) ? "suspended" : "",
-	       ((scb.scb_status & SCB_ST_CUS) ==
-		SCB_ST_CUS_ACTV) ? "active" : "");
-	printk("rus 0x%x[%s%s%s%s]\n", (scb.scb_status & SCB_ST_RUS) >> 4,
-	       ((scb.scb_status & SCB_ST_RUS) ==
-		SCB_ST_RUS_IDLE) ? "idle" : "",
-	       ((scb.scb_status & SCB_ST_RUS) ==
-		SCB_ST_RUS_SUSP) ? "suspended" : "",
-	       ((scb.scb_status & SCB_ST_RUS) ==
-		SCB_ST_RUS_NRES) ? "no resources" : "",
-	       ((scb.scb_status & SCB_ST_RUS) ==
-		SCB_ST_RUS_RDY) ? "ready" : "");
-
-	printk(KERN_DEBUG "command: ");
-	printk("ack 0x%x[%s%s%s%s] ",
-	       (scb.
-		scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR |
-			       SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12,
-	       (scb.
-		scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "",
-	       (scb.
-		scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "",
-	       (scb.
-		scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "",
-	       (scb.
-		scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : "");
-	printk("cuc 0x%x[%s%s%s%s%s] ",
-	       (scb.scb_command & SCB_CMD_CUC) >> 8,
-	       ((scb.scb_command & SCB_CMD_CUC) ==
-		SCB_CMD_CUC_NOP) ? "nop" : "",
-	       ((scb.scb_command & SCB_CMD_CUC) ==
-		SCB_CMD_CUC_GO) ? "start cbl_offset" : "",
-	       ((scb.scb_command & SCB_CMD_CUC) ==
-		SCB_CMD_CUC_RES) ? "resume execution" : "",
-	       ((scb.scb_command & SCB_CMD_CUC) ==
-		SCB_CMD_CUC_SUS) ? "suspend execution" : "",
-	       ((scb.scb_command & SCB_CMD_CUC) ==
-		SCB_CMD_CUC_ABT) ? "abort execution" : "");
-	printk("ruc 0x%x[%s%s%s%s%s]\n",
-	       (scb.scb_command & SCB_CMD_RUC) >> 4,
-	       ((scb.scb_command & SCB_CMD_RUC) ==
-		SCB_CMD_RUC_NOP) ? "nop" : "",
-	       ((scb.scb_command & SCB_CMD_RUC) ==
-		SCB_CMD_RUC_GO) ? "start rfa_offset" : "",
-	       ((scb.scb_command & SCB_CMD_RUC) ==
-		SCB_CMD_RUC_RES) ? "resume reception" : "",
-	       ((scb.scb_command & SCB_CMD_RUC) ==
-		SCB_CMD_RUC_SUS) ? "suspend reception" : "",
-	       ((scb.scb_command & SCB_CMD_RUC) ==
-		SCB_CMD_RUC_ABT) ? "abort reception" : "");
-
-	printk(KERN_DEBUG "cbl_offset 0x%x ", scb.scb_cbl_offset);
-	printk("rfa_offset 0x%x\n", scb.scb_rfa_offset);
-
-	printk(KERN_DEBUG "crcerrs %d ", scb.scb_crcerrs);
-	printk("alnerrs %d ", scb.scb_alnerrs);
-	printk("rscerrs %d ", scb.scb_rscerrs);
-	printk("ovrnerrs %d\n", scb.scb_ovrnerrs);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the i82586's receive unit.
- */
-static void wv_ru_show(struct net_device * dev)
-{
-	printk(KERN_DEBUG
-	       "##### WaveLAN i82586 receiver unit status: #####\n");
-	printk(KERN_DEBUG "ru:");
-	/*
-	 * Not implemented yet
-	 */
-	printk("\n");
-}				/* wv_ru_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Display info about one control block of the i82586 memory.
- */
-static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p)
-{
-	unsigned long ioaddr;
-	ac_tx_t actx;
-
-	ioaddr = dev->base_addr;
-
-	printk("%d: 0x%x:", i, p);
-
-	obram_read(ioaddr, p, (unsigned char *) &actx, sizeof(actx));
-	printk(" status=0x%x,", actx.tx_h.ac_status);
-	printk(" command=0x%x,", actx.tx_h.ac_command);
-
-	/*
-	   {
-	   tbd_t      tbd;
-
-	   obram_read(ioaddr, actx.tx_tbd_offset, (unsigned char *)&tbd, sizeof(tbd));
-	   printk(" tbd_status=0x%x,", tbd.tbd_status);
-	   }
-	 */
-
-	printk("|");
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Print status of the command unit of the i82586.
- */
-static void wv_cu_show(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned int i;
-	u16 p;
-
-	printk(KERN_DEBUG
-	       "##### WaveLAN i82586 command unit status: #####\n");
-
-	printk(KERN_DEBUG);
-	for (i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++) {
-		wv_cu_show_one(dev, lp, i, p);
-
-		p += TXBLOCKZ;
-		if (p >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-			p -= NTXBLOCKS * TXBLOCKZ;
-	}
-	printk("\n");
-}
-#endif				/* DEBUG_I82586_SHOW */
-
-#ifdef DEBUG_DEVICE_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver.
- */
-static void wv_dev_show(struct net_device * dev)
-{
-	printk(KERN_DEBUG "dev:");
-	printk(" state=%lX,", dev->state);
-	printk(" trans_start=%ld,", dev->trans_start);
-	printk(" flags=0x%x,", dev->flags);
-	printk("\n");
-}				/* wv_dev_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver's
- * private information.
- */
-static void wv_local_show(struct net_device * dev)
-{
-	net_local *lp;
-
-	lp = netdev_priv(dev);
-
-	printk(KERN_DEBUG "local:");
-	printk(" tx_n_in_use=%d,", lp->tx_n_in_use);
-	printk(" hacr=0x%x,", lp->hacr);
-	printk(" rx_head=0x%x,", lp->rx_head);
-	printk(" rx_last=0x%x,", lp->rx_last);
-	printk(" tx_first_free=0x%x,", lp->tx_first_free);
-	printk(" tx_first_in_use=0x%x,", lp->tx_first_in_use);
-	printk("\n");
-}				/* wv_local_show */
-#endif				/* DEBUG_DEVICE_SHOW */
-
-#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
-/*------------------------------------------------------------------*/
-/*
- * Dump packet header (and content if necessary) on the screen
- */
-static inline void wv_packet_info(u8 * p,	/* Packet to dump */
-				  int length,	/* Length of the packet */
-				  char *msg1,	/* Name of the device */
-				  char *msg2)
-{				/* Name of the function */
-	int i;
-	int maxi;
-
-	printk(KERN_DEBUG
-	       "%s: %s(): dest %pM, length %d\n",
-	       msg1, msg2, p, length);
-	printk(KERN_DEBUG
-	       "%s: %s(): src %pM, type 0x%02X%02X\n",
-	       msg1, msg2, &p[6], p[12], p[13]);
-
-#ifdef DEBUG_PACKET_DUMP
-
-	printk(KERN_DEBUG "data=\"");
-
-	if ((maxi = length) > DEBUG_PACKET_DUMP)
-		maxi = DEBUG_PACKET_DUMP;
-	for (i = 14; i < maxi; i++)
-		if (p[i] >= ' ' && p[i] <= '~')
-			printk(" %c", p[i]);
-		else
-			printk("%02X", p[i]);
-	if (maxi < length)
-		printk("..");
-	printk("\"\n");
-	printk(KERN_DEBUG "\n");
-#endif				/* DEBUG_PACKET_DUMP */
-}
-#endif				/* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
-
-/*------------------------------------------------------------------*/
-/*
- * This is the information which is displayed by the driver at startup.
- * There are lots of flags for configuring it to your liking.
- */
-static void wv_init_info(struct net_device * dev)
-{
-	short ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-
-	/* Read the parameter storage area */
-	psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef DEBUG_PSA_SHOW
-	wv_psa_show(&psa);
-#endif
-#ifdef DEBUG_MMC_SHOW
-	wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82586_SHOW
-	wv_cu_show(dev);
-#endif
-
-#ifdef DEBUG_BASIC_SHOW
-	/* Now, let's go for the basic stuff. */
-	printk(KERN_NOTICE "%s: WaveLAN at %#x, %pM, IRQ %d",
-	       dev->name, ioaddr, dev->dev_addr, dev->irq);
-
-	/* Print current network ID. */
-	if (psa.psa_nwid_select)
-		printk(", nwid 0x%02X-%02X", psa.psa_nwid[0],
-		       psa.psa_nwid[1]);
-	else
-		printk(", nwid off");
-
-	/* If 2.00 card */
-	if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		unsigned short freq;
-
-		/* Ask the EEPROM to read the frequency from the first area. */
-		fee_read(ioaddr, 0x00, &freq, 1);
-
-		/* Print frequency */
-		printk(", 2.00, %ld", (freq >> 6) + 2400L);
-
-		/* Hack! */
-		if (freq & 0x20)
-			printk(".5");
-	} else {
-		printk(", PC");
-		switch (psa.psa_comp_number) {
-		case PSA_COMP_PC_AT_915:
-		case PSA_COMP_PC_AT_2400:
-			printk("-AT");
-			break;
-		case PSA_COMP_PC_MC_915:
-		case PSA_COMP_PC_MC_2400:
-			printk("-MC");
-			break;
-		case PSA_COMP_PCMCIA_915:
-			printk("MCIA");
-			break;
-		default:
-			printk("?");
-		}
-		printk(", ");
-		switch (psa.psa_subband) {
-		case PSA_SUBBAND_915:
-			printk("915");
-			break;
-		case PSA_SUBBAND_2425:
-			printk("2425");
-			break;
-		case PSA_SUBBAND_2460:
-			printk("2460");
-			break;
-		case PSA_SUBBAND_2484:
-			printk("2484");
-			break;
-		case PSA_SUBBAND_2430_5:
-			printk("2430.5");
-			break;
-		default:
-			printk("?");
-		}
-	}
-
-	printk(" MHz\n");
-#endif				/* DEBUG_BASIC_SHOW */
-
-#ifdef DEBUG_VERSION_SHOW
-	/* Print version information */
-	printk(KERN_NOTICE "%s", version);
-#endif
-}				/* wv_init_info */
-
-/********************* IOCTL, STATS & RECONFIG *********************/
-/*
- * We found here routines that are called by Linux on different
- * occasions after the configuration and not for transmitting data
- * These may be called when the user use ifconfig, /proc/net/dev
- * or wireless extensions
- */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1	Promiscuous mode, receive all packets
- * num_addrs == 0	Normal mode, clear multicast list
- * num_addrs > 0	Multicast mode, receive normal and MC packets,
- *			and do best-effort filtering.
- */
-static void wavelan_set_multicast_list(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-
-#ifdef DEBUG_IOCTL_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n",
-	       dev->name);
-#endif
-
-#ifdef DEBUG_IOCTL_INFO
-	printk(KERN_DEBUG
-	       "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-	       dev->name, dev->flags, dev->mc_count);
-#endif
-
-	/* Are we asking for promiscuous mode,
-	 * or all multicast addresses (we don't have that!)
-	 * or too many multicast addresses for the hardware filter? */
-	if ((dev->flags & IFF_PROMISC) ||
-	    (dev->flags & IFF_ALLMULTI) ||
-	    (dev->mc_count > I82586_MAX_MULTICAST_ADDRESSES)) {
-		/*
-		 * Enable promiscuous mode: receive all packets.
-		 */
-		if (!lp->promiscuous) {
-			lp->promiscuous = 1;
-			lp->mc_count = 0;
-
-			wv_82586_reconfig(dev);
-		}
-	} else
-		/* Are there multicast addresses to send? */
-	if (dev->mc_list != (struct dev_mc_list *) NULL) {
-		/*
-		 * Disable promiscuous mode, but receive all packets
-		 * in multicast list
-		 */
-#ifdef MULTICAST_AVOID
-		if (lp->promiscuous || (dev->mc_count != lp->mc_count))
-#endif
-		{
-			lp->promiscuous = 0;
-			lp->mc_count = dev->mc_count;
-
-			wv_82586_reconfig(dev);
-		}
-	} else {
-		/*
-		 * Switch to normal mode: disable promiscuous mode and 
-		 * clear the multicast list.
-		 */
-		if (lp->promiscuous || lp->mc_count == 0) {
-			lp->promiscuous = 0;
-			lp->mc_count = 0;
-
-			wv_82586_reconfig(dev);
-		}
-	}
-#ifdef DEBUG_IOCTL_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n",
-	       dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This function doesn't exist.
- * (Note : it was a nice way to test the reconfigure stuff...)
- */
-#ifdef SET_MAC_ADDRESS
-static int wavelan_set_mac_address(struct net_device * dev, void *addr)
-{
-	struct sockaddr *mac = addr;
-
-	/* Copy the address. */
-	memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
-
-	/* Reconfigure the beast. */
-	wv_82586_reconfig(dev);
-
-	return 0;
-}
-#endif				/* SET_MAC_ADDRESS */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Frequency setting (for hardware capable of it)
- * It's a bit complicated and you don't really want to look into it.
- * (called in wavelan_ioctl)
- */
-static int wv_set_frequency(unsigned long ioaddr,	/* I/O port of the card */
-				   iw_freq * frequency)
-{
-	const int BAND_NUM = 10;	/* Number of bands */
-	long freq = 0L;		/* offset to 2.4 GHz in .5 MHz */
-#ifdef DEBUG_IOCTL_INFO
-	int i;
-#endif
-
-	/* Setting by frequency */
-	/* Theoretically, you may set any frequency between
-	 * the two limits with a 0.5 MHz precision. In practice,
-	 * I don't want you to have trouble with local regulations.
-	 */
-	if ((frequency->e == 1) &&
-	    (frequency->m >= (int) 2.412e8)
-	    && (frequency->m <= (int) 2.487e8)) {
-		freq = ((frequency->m / 10000) - 24000L) / 5;
-	}
-
-	/* Setting by channel (same as wfreqsel) */
-	/* Warning: each channel is 22 MHz wide, so some of the channels
-	 * will interfere. */
-	if ((frequency->e == 0) && (frequency->m < BAND_NUM)) {
-		/* Get frequency offset. */
-		freq = channel_bands[frequency->m] >> 1;
-	}
-
-	/* Verify that the frequency is allowed. */
-	if (freq != 0L) {
-		u16 table[10];	/* Authorized frequency table */
-
-		/* Read the frequency table. */
-		fee_read(ioaddr, 0x71, table, 10);
-
-#ifdef DEBUG_IOCTL_INFO
-		printk(KERN_DEBUG "Frequency table: ");
-		for (i = 0; i < 10; i++) {
-			printk(" %04X", table[i]);
-		}
-		printk("\n");
-#endif
-
-		/* Look in the table to see whether the frequency is allowed. */
-		if (!(table[9 - ((freq - 24) / 16)] &
-		      (1 << ((freq - 24) % 16)))) return -EINVAL;	/* not allowed */
-	} else
-		return -EINVAL;
-
-	/* if we get a usable frequency */
-	if (freq != 0L) {
-		unsigned short area[16];
-		unsigned short dac[2];
-		unsigned short area_verify[16];
-		unsigned short dac_verify[2];
-		/* Corresponding gain (in the power adjust value table)
-		 * See AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8
-		 * and WCIN062D.DOC, page 6.2.9. */
-		unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
-		int power_band = 0;	/* Selected band */
-		unsigned short power_adjust;	/* Correct value */
-
-		/* Search for the gain. */
-		power_band = 0;
-		while ((freq > power_limit[power_band]) &&
-		       (power_limit[++power_band] != 0));
-
-		/* Read the first area. */
-		fee_read(ioaddr, 0x00, area, 16);
-
-		/* Read the DAC. */
-		fee_read(ioaddr, 0x60, dac, 2);
-
-		/* Read the new power adjust value. */
-		fee_read(ioaddr, 0x6B - (power_band >> 1), &power_adjust,
-			 1);
-		if (power_band & 0x1)
-			power_adjust >>= 8;
-		else
-			power_adjust &= 0xFF;
-
-#ifdef DEBUG_IOCTL_INFO
-		printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
-		for (i = 0; i < 16; i++) {
-			printk(" %04X", area[i]);
-		}
-		printk("\n");
-
-		printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
-		       dac[0], dac[1]);
-#endif
-
-		/* Frequency offset (for info only) */
-		area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
-
-		/* Receiver Principle main divider coefficient */
-		area[3] = (freq >> 1) + 2400L - 352L;
-		area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-		/* Transmitter Main divider coefficient */
-		area[13] = (freq >> 1) + 2400L;
-		area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-		/* Other parts of the area are flags, bit streams or unused. */
-
-		/* Set the value in the DAC. */
-		dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
-		dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
-
-		/* Write the first area. */
-		fee_write(ioaddr, 0x00, area, 16);
-
-		/* Write the DAC. */
-		fee_write(ioaddr, 0x60, dac, 2);
-
-		/* We now should verify here that the writing of the EEPROM went OK. */
-
-		/* Reread the first area. */
-		fee_read(ioaddr, 0x00, area_verify, 16);
-
-		/* Reread the DAC. */
-		fee_read(ioaddr, 0x60, dac_verify, 2);
-
-		/* Compare. */
-		if (memcmp(area, area_verify, 16 * 2) ||
-		    memcmp(dac, dac_verify, 2 * 2)) {
-#ifdef DEBUG_IOCTL_ERROR
-			printk(KERN_INFO
-			       "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n");
-#endif
-			return -EOPNOTSUPP;
-		}
-
-		/* We must download the frequency parameters to the
-		 * synthesizers (from the EEPROM - area 1)
-		 * Note: as the EEPROM is automatically decremented, we set the end
-		 * if the area... */
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F);
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-			MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-		/* Wait until the download is finished. */
-		fee_wait(ioaddr, 100, 100);
-
-		/* We must now download the power adjust value (gain) to
-		 * the synthesizers (from the EEPROM - area 7 - DAC). */
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61);
-		mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-			MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-		/* Wait for the download to finish. */
-		fee_wait(ioaddr, 100, 100);
-
-#ifdef DEBUG_IOCTL_INFO
-		/* Verification of what we have done */
-
-		printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
-		for (i = 0; i < 16; i++) {
-			printk(" %04X", area_verify[i]);
-		}
-		printk("\n");
-
-		printk(KERN_DEBUG "WaveLAN EEPROM DAC:  %04X %04X\n",
-		       dac_verify[0], dac_verify[1]);
-#endif
-
-		return 0;
-	} else
-		return -EINVAL;	/* Bah, never get there... */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Give the list of available frequencies.
- */
-static int wv_frequency_list(unsigned long ioaddr,	/* I/O port of the card */
-				    iw_freq * list,	/* List of frequencies to fill */
-				    int max)
-{				/* Maximum number of frequencies */
-	u16 table[10];	/* Authorized frequency table */
-	long freq = 0L;		/* offset to 2.4 GHz in .5 MHz + 12 MHz */
-	int i;			/* index in the table */
-	int c = 0;		/* Channel number */
-
-	/* Read the frequency table. */
-	fee_read(ioaddr, 0x71 /* frequency table */ , table, 10);
-
-	/* Check all frequencies. */
-	i = 0;
-	for (freq = 0; freq < 150; freq++)
-		/* Look in the table if the frequency is allowed */
-		if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
-			/* Compute approximate channel number */
-			while ((c < ARRAY_SIZE(channel_bands)) &&
-				(((channel_bands[c] >> 1) - 24) < freq)) 
-				c++;
-			list[i].i = c;	/* Set the list index */
-
-			/* put in the list */
-			list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
-			list[i++].e = 1;
-
-			/* Check number. */
-			if (i >= max)
-				return (i);
-		}
-
-	return (i);
-}
-
-#ifdef IW_WIRELESS_SPY
-/*------------------------------------------------------------------*/
-/*
- * Gather wireless spy statistics:  for each packet, compare the source
- * address with our list, and if they match, get the statistics.
- * Sorry, but this function really needs the wireless extensions.
- */
-static inline void wl_spy_gather(struct net_device * dev,
-				 u8 *	mac,	/* MAC address */
-				 u8 *	stats)	/* Statistics to gather */
-{
-	struct iw_quality wstats;
-
-	wstats.qual = stats[2] & MMR_SGNL_QUAL;
-	wstats.level = stats[0] & MMR_SIGNAL_LVL;
-	wstats.noise = stats[1] & MMR_SILENCE_LVL;
-	wstats.updated = 0x7;
-
-	/* Update spy records */
-	wireless_spy_update(dev, mac, &wstats);
-}
-#endif /* IW_WIRELESS_SPY */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * This function calculates a histogram of the signal level.
- * As the noise is quite constant, it's like doing it on the SNR.
- * We have defined a set of interval (lp->his_range), and each time
- * the level goes in that interval, we increment the count (lp->his_sum).
- * With this histogram you may detect if one WaveLAN is really weak,
- * or you may also calculate the mean and standard deviation of the level.
- */
-static inline void wl_his_gather(struct net_device * dev, u8 * stats)
-{				/* Statistics to gather */
-	net_local *lp = netdev_priv(dev);
-	u8 level = stats[0] & MMR_SIGNAL_LVL;
-	int i;
-
-	/* Find the correct interval. */
-	i = 0;
-	while ((i < (lp->his_number - 1))
-	       && (level >= lp->his_range[i++]));
-
-	/* Increment interval counter. */
-	(lp->his_sum[i])++;
-}
-#endif /* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get protocol name
- */
-static int wavelan_get_name(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	strcpy(wrqu->name, "WaveLAN");
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set NWID
- */
-static int wavelan_set_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	mm_t m;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Set NWID in WaveLAN. */
-	if (!wrqu->nwid.disabled) {
-		/* Set NWID in psa */
-		psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
-		psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
-		psa.psa_nwid_select = 0x01;
-		psa_write(ioaddr, lp->hacr,
-			  (char *) psa.psa_nwid - (char *) &psa,
-			  (unsigned char *) psa.psa_nwid, 3);
-
-		/* Set NWID in mmc. */
-		m.w.mmw_netw_id_l = psa.psa_nwid[1];
-		m.w.mmw_netw_id_h = psa.psa_nwid[0];
-		mmc_write(ioaddr,
-			  (char *) &m.w.mmw_netw_id_l -
-			  (char *) &m,
-			  (unsigned char *) &m.w.mmw_netw_id_l, 2);
-		mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
-	} else {
-		/* Disable NWID in the psa. */
-		psa.psa_nwid_select = 0x00;
-		psa_write(ioaddr, lp->hacr,
-			  (char *) &psa.psa_nwid_select -
-			  (char *) &psa,
-			  (unsigned char *) &psa.psa_nwid_select,
-			  1);
-
-		/* Disable NWID in the mmc (no filtering). */
-		mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel),
-			MMW_LOOPT_SEL_DIS_NWID);
-	}
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev, ioaddr, lp->hacr);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get NWID 
- */
-static int wavelan_get_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Read the NWID. */
-	psa_read(ioaddr, lp->hacr,
-		 (char *) psa.psa_nwid - (char *) &psa,
-		 (unsigned char *) psa.psa_nwid, 3);
-	wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
-	wrqu->nwid.disabled = !(psa.psa_nwid_select);
-	wrqu->nwid.fixed = 1;	/* Superfluous */
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set frequency
- */
-static int wavelan_set_freq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	unsigned long flags;
-	int ret;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-	if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-		ret = wv_set_frequency(ioaddr, &(wrqu->freq));
-	else
-		ret = -EOPNOTSUPP;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get frequency
- */
-static int wavelan_get_freq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
-	 * Does it work for everybody, especially old cards? */
-	if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		unsigned short freq;
-
-		/* Ask the EEPROM to read the frequency from the first area. */
-		fee_read(ioaddr, 0x00, &freq, 1);
-		wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
-		wrqu->freq.e = 1;
-	} else {
-		psa_read(ioaddr, lp->hacr,
-			 (char *) &psa.psa_subband - (char *) &psa,
-			 (unsigned char *) &psa.psa_subband, 1);
-
-		if (psa.psa_subband <= 4) {
-			wrqu->freq.m = fixed_bands[psa.psa_subband];
-			wrqu->freq.e = (psa.psa_subband != 0);
-		} else
-			ret = -EOPNOTSUPP;
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set level threshold
- */
-static int wavelan_set_sens(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Set the level threshold. */
-	/* We should complain loudly if wrqu->sens.fixed = 0, because we
-	 * can't set auto mode... */
-	psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
-	psa_write(ioaddr, lp->hacr,
-		  (char *) &psa.psa_thr_pre_set - (char *) &psa,
-		  (unsigned char *) &psa.psa_thr_pre_set, 1);
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev, ioaddr, lp->hacr);
-	mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set),
-		psa.psa_thr_pre_set);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get level threshold
- */
-static int wavelan_get_sens(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Read the level threshold. */
-	psa_read(ioaddr, lp->hacr,
-		 (char *) &psa.psa_thr_pre_set - (char *) &psa,
-		 (unsigned char *) &psa.psa_thr_pre_set, 1);
-	wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
-	wrqu->sens.fixed = 1;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set encryption key
- */
-static int wavelan_set_encode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu,
-			      char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	unsigned long flags;
-	psa_t psa;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-
-	/* Check if capable of encryption */
-	if (!mmc_encr(ioaddr)) {
-		ret = -EOPNOTSUPP;
-	}
-
-	/* Check the size of the key */
-	if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
-		ret = -EINVAL;
-	}
-
-	if(!ret) {
-		/* Basic checking... */
-		if (wrqu->encoding.length == 8) {
-			/* Copy the key in the driver */
-			memcpy(psa.psa_encryption_key, extra,
-			       wrqu->encoding.length);
-			psa.psa_encryption_select = 1;
-
-			psa_write(ioaddr, lp->hacr,
-				  (char *) &psa.psa_encryption_select -
-				  (char *) &psa,
-				  (unsigned char *) &psa.
-				  psa_encryption_select, 8 + 1);
-
-			mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
-				MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
-			mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
-				  (unsigned char *) &psa.
-				  psa_encryption_key, 8);
-		}
-
-		/* disable encryption */
-		if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
-			psa.psa_encryption_select = 0;
-			psa_write(ioaddr, lp->hacr,
-				  (char *) &psa.psa_encryption_select -
-				  (char *) &psa,
-				  (unsigned char *) &psa.
-				  psa_encryption_select, 1);
-
-			mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
-		}
-		/* update the Wavelan checksum */
-		update_psa_checksum(dev, ioaddr, lp->hacr);
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get encryption key
- */
-static int wavelan_get_encode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu,
-			      char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Check if encryption is available */
-	if (!mmc_encr(ioaddr)) {
-		ret = -EOPNOTSUPP;
-	} else {
-		/* Read the encryption key */
-		psa_read(ioaddr, lp->hacr,
-			 (char *) &psa.psa_encryption_select -
-			 (char *) &psa,
-			 (unsigned char *) &psa.
-			 psa_encryption_select, 1 + 8);
-
-		/* encryption is enabled ? */
-		if (psa.psa_encryption_select)
-			wrqu->encoding.flags = IW_ENCODE_ENABLED;
-		else
-			wrqu->encoding.flags = IW_ENCODE_DISABLED;
-		wrqu->encoding.flags |= mmc_encr(ioaddr);
-
-		/* Copy the key to the user buffer */
-		wrqu->encoding.length = 8;
-		memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get range info
- */
-static int wavelan_get_range(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	struct iw_range *range = (struct iw_range *) extra;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Set the length (very important for backward compatibility) */
-	wrqu->data.length = sizeof(struct iw_range);
-
-	/* Set all the info we don't care or don't know about to zero */
-	memset(range, 0, sizeof(struct iw_range));
-
-	/* Set the Wireless Extension versions */
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 9;
-
-	/* Set information in the range struct.  */
-	range->throughput = 1.6 * 1000 * 1000;	/* don't argue on this ! */
-	range->min_nwid = 0x0000;
-	range->max_nwid = 0xFFFF;
-
-	range->sensitivity = 0x3F;
-	range->max_qual.qual = MMR_SGNL_QUAL;
-	range->max_qual.level = MMR_SIGNAL_LVL;
-	range->max_qual.noise = MMR_SILENCE_LVL;
-	range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
-	/* Need to get better values for those two */
-	range->avg_qual.level = 30;
-	range->avg_qual.noise = 8;
-
-	range->num_bitrates = 1;
-	range->bitrate[0] = 2000000;	/* 2 Mb/s */
-
-	/* Event capability (kernel + driver) */
-	range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
-				IW_EVENT_CAPA_MASK(0x8B04));
-	range->event_capa[1] = IW_EVENT_CAPA_K_1;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-	if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		range->num_channels = 10;
-		range->num_frequency = wv_frequency_list(ioaddr, range->freq,
-							IW_MAX_FREQUENCIES);
-	} else
-		range->num_channels = range->num_frequency = 0;
-
-	/* Encryption supported ? */
-	if (mmc_encr(ioaddr)) {
-		range->encoding_size[0] = 8;	/* DES = 64 bits key */
-		range->num_encoding_sizes = 1;
-		range->max_encoding_tokens = 1;	/* Only one key possible */
-	} else {
-		range->num_encoding_sizes = 0;
-		range->max_encoding_tokens = 0;
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set quality threshold
- */
-static int wavelan_set_qthr(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	psa.psa_quality_thr = *(extra) & 0x0F;
-	psa_write(ioaddr, lp->hacr,
-		  (char *) &psa.psa_quality_thr - (char *) &psa,
-		  (unsigned char *) &psa.psa_quality_thr, 1);
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev, ioaddr, lp->hacr);
-	mmc_out(ioaddr, mmwoff(0, mmw_quality_thr),
-		psa.psa_quality_thr);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_qthr(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-	psa_t psa;
-	unsigned long flags;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	psa_read(ioaddr, lp->hacr,
-		 (char *) &psa.psa_quality_thr - (char *) &psa,
-		 (unsigned char *) &psa.psa_quality_thr, 1);
-	*(extra) = psa.psa_quality_thr & 0x0F;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return 0;
-}
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set histogram
- */
-static int wavelan_set_histo(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-
-	/* Check the number of intervals. */
-	if (wrqu->data.length > 16) {
-		return(-E2BIG);
-	}
-
-	/* Disable histo while we copy the addresses.
-	 * As we don't disable interrupts, we need to do this */
-	lp->his_number = 0;
-
-	/* Are there ranges to copy? */
-	if (wrqu->data.length > 0) {
-		/* Copy interval ranges to the driver */
-		memcpy(lp->his_range, extra, wrqu->data.length);
-
-		{
-		  int i;
-		  printk(KERN_DEBUG "Histo :");
-		  for(i = 0; i < wrqu->data.length; i++)
-		    printk(" %d", lp->his_range[i]);
-		  printk("\n");
-		}
-
-		/* Reset result structure. */
-		memset(lp->his_sum, 0x00, sizeof(long) * 16);
-	}
-
-	/* Now we can set the number of ranges */
-	lp->his_number = wrqu->data.length;
-
-	return(0);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get histogram
- */
-static int wavelan_get_histo(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);	/* lp is not unused */
-
-	/* Set the number of intervals. */
-	wrqu->data.length = lp->his_number;
-
-	/* Give back the distribution statistics */
-	if(lp->his_number > 0)
-		memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
-
-	return(0);
-}
-#endif			/* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Structures to export the Wireless Handlers
- */
-
-static const iw_handler		wavelan_handler[] =
-{
-	NULL,				/* SIOCSIWNAME */
-	wavelan_get_name,		/* SIOCGIWNAME */
-	wavelan_set_nwid,		/* SIOCSIWNWID */
-	wavelan_get_nwid,		/* SIOCGIWNWID */
-	wavelan_set_freq,		/* SIOCSIWFREQ */
-	wavelan_get_freq,		/* SIOCGIWFREQ */
-	NULL,				/* SIOCSIWMODE */
-	NULL,				/* SIOCGIWMODE */
-	wavelan_set_sens,		/* SIOCSIWSENS */
-	wavelan_get_sens,		/* SIOCGIWSENS */
-	NULL,				/* SIOCSIWRANGE */
-	wavelan_get_range,		/* SIOCGIWRANGE */
-	NULL,				/* SIOCSIWPRIV */
-	NULL,				/* SIOCGIWPRIV */
-	NULL,				/* SIOCSIWSTATS */
-	NULL,				/* SIOCGIWSTATS */
-	iw_handler_set_spy,		/* SIOCSIWSPY */
-	iw_handler_get_spy,		/* SIOCGIWSPY */
-	iw_handler_set_thrspy,		/* SIOCSIWTHRSPY */
-	iw_handler_get_thrspy,		/* SIOCGIWTHRSPY */
-	NULL,				/* SIOCSIWAP */
-	NULL,				/* SIOCGIWAP */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCGIWAPLIST */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWESSID */
-	NULL,				/* SIOCGIWESSID */
-	NULL,				/* SIOCSIWNICKN */
-	NULL,				/* SIOCGIWNICKN */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWRATE */
-	NULL,				/* SIOCGIWRATE */
-	NULL,				/* SIOCSIWRTS */
-	NULL,				/* SIOCGIWRTS */
-	NULL,				/* SIOCSIWFRAG */
-	NULL,				/* SIOCGIWFRAG */
-	NULL,				/* SIOCSIWTXPOW */
-	NULL,				/* SIOCGIWTXPOW */
-	NULL,				/* SIOCSIWRETRY */
-	NULL,				/* SIOCGIWRETRY */
-	/* Bummer ! Why those are only at the end ??? */
-	wavelan_set_encode,		/* SIOCSIWENCODE */
-	wavelan_get_encode,		/* SIOCGIWENCODE */
-};
-
-static const iw_handler		wavelan_private_handler[] =
-{
-	wavelan_set_qthr,		/* SIOCIWFIRSTPRIV */
-	wavelan_get_qthr,		/* SIOCIWFIRSTPRIV + 1 */
-#ifdef HISTOGRAM
-	wavelan_set_histo,		/* SIOCIWFIRSTPRIV + 2 */
-	wavelan_get_histo,		/* SIOCIWFIRSTPRIV + 3 */
-#endif	/* HISTOGRAM */
-};
-
-static const struct iw_priv_args wavelan_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
-  { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
-  { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16,                    0, "sethisto" },
-  { SIOCGIPHISTO, 0,                     IW_PRIV_TYPE_INT | 16, "gethisto" },
-};
-
-static const struct iw_handler_def	wavelan_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(wavelan_handler),
-	.num_private	= ARRAY_SIZE(wavelan_private_handler),
-	.num_private_args = ARRAY_SIZE(wavelan_private_args),
-	.standard	= wavelan_handler,
-	.private	= wavelan_private_handler,
-	.private_args	= wavelan_private_args,
-	.get_wireless_stats = wavelan_get_wireless_stats,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Get wireless statistics.
- * Called by /proc/net/wireless
- */
-static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	mmr_t m;
-	iw_stats *wstats;
-	unsigned long flags;
-
-#ifdef DEBUG_IOCTL_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n",
-	       dev->name);
-#endif
-
-	/* Check */
-	if (lp == (net_local *) NULL)
-		return (iw_stats *) NULL;
-	
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	wstats = &lp->wstats;
-
-	/* Get data from the mmc. */
-	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-
-	mmc_read(ioaddr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
-	mmc_read(ioaddr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l,
-		 2);
-	mmc_read(ioaddr, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set,
-		 4);
-
-	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-	/* Copy data to wireless stuff. */
-	wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
-	wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
-	wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
-	wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
-	wstats->qual.updated = (((m. mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) 
-			| ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) 
-			| ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
-	wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-	wstats->discard.code = 0L;
-	wstats->discard.misc = 0L;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_IOCTL_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n",
-	       dev->name);
-#endif
-	return &lp->wstats;
-}
-
-/************************* PACKET RECEPTION *************************/
-/*
- * This part deals with receiving the packets.
- * The interrupt handler gets an interrupt when a packet has been
- * successfully received and calls this part.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does the actual copying of data (including the Ethernet
- * header structure) from the WaveLAN card to an sk_buff chain that
- * will be passed up to the network interface layer. NOTE: we
- * currently don't handle trailer protocols (neither does the rest of
- * the network interface), so if that is needed, it will (at least in
- * part) be added here.  The contents of the receive ring buffer are
- * copied to a message chain that is then passed to the kernel.
- *
- * Note: if any errors occur, the packet is "dropped on the floor".
- * (called by wv_packet_rcv())
- */
-static void
-wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	struct sk_buff *skb;
-
-#ifdef DEBUG_RX_TRACE
-	printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
-	       dev->name, buf_off, sksize);
-#endif
-
-	/* Allocate buffer for the data */
-	if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *) NULL) {
-#ifdef DEBUG_RX_ERROR
-		printk(KERN_INFO
-		       "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n",
-		       dev->name, sksize);
-#endif
-		dev->stats.rx_dropped++;
-		return;
-	}
-
-	/* Copy the packet to the buffer. */
-	obram_read(ioaddr, buf_off, skb_put(skb, sksize), sksize);
-	skb->protocol = eth_type_trans(skb, dev);
-
-#ifdef DEBUG_RX_INFO
-	wv_packet_info(skb_mac_header(skb), sksize, dev->name,
-		       "wv_packet_read");
-#endif				/* DEBUG_RX_INFO */
-
-	/* Statistics-gathering and associated stuff.
-	 * It seem a bit messy with all the define, but it's really
-	 * simple... */
-	if (
-#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
-		   (lp->spy_data.spy_number > 0) ||
-#endif /* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-		   (lp->his_number > 0) ||
-#endif /* HISTOGRAM */
-		   0) {
-		u8 stats[3];	/* signal level, noise level, signal quality */
-
-		/* Read signal level, silence level and signal quality bytes */
-		/* Note: in the PCMCIA hardware, these are part of the frame.
-		 * It seems that for the ISA hardware, it's nowhere to be
-		 * found in the frame, so I'm obliged to do this (it has a
-		 * side effect on /proc/net/wireless).
-		 * Any ideas?
-		 */
-		mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-		mmc_read(ioaddr, mmroff(0, mmr_signal_lvl), stats, 3);
-		mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-#ifdef DEBUG_RX_INFO
-		printk(KERN_DEBUG
-		       "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
-		       dev->name, stats[0] & 0x3F, stats[1] & 0x3F,
-		       stats[2] & 0x0F);
-#endif
-
-		/* Spying stuff */
-#ifdef IW_WIRELESS_SPY
-		wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE,
-			      stats);
-#endif /* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-		wl_his_gather(dev, stats);
-#endif /* HISTOGRAM */
-	}
-
-	/*
-	 * Hand the packet to the network module.
-	 */
-	netif_rx(skb);
-
-	/* Keep statistics up to date */
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += sksize;
-
-#ifdef DEBUG_RX_TRACE
-	printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Transfer as many packets as we can
- * from the device RAM.
- * (called in wavelan_interrupt()).
- * Note : the spinlock is already grabbed for us.
- */
-static void wv_receive(struct net_device * dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	fd_t fd;
-	rbd_t rbd;
-	int nreaped = 0;
-
-#ifdef DEBUG_RX_TRACE
-	printk(KERN_DEBUG "%s: ->wv_receive()\n", dev->name);
-#endif
-
-	/* Loop on each received packet. */
-	for (;;) {
-		obram_read(ioaddr, lp->rx_head, (unsigned char *) &fd,
-			   sizeof(fd));
-
-		/* Note about the status :
-		 * It start up to be 0 (the value we set). Then, when the RU
-		 * grab the buffer to prepare for reception, it sets the
-		 * FD_STATUS_B flag. When the RU has finished receiving the
-		 * frame, it clears FD_STATUS_B, set FD_STATUS_C to indicate
-		 * completion and set the other flags to indicate the eventual
-		 * errors. FD_STATUS_OK indicates that the reception was OK.
-		 */
-
-		/* If the current frame is not complete, we have reached the end. */
-		if ((fd.fd_status & FD_STATUS_C) != FD_STATUS_C)
-			break;	/* This is how we exit the loop. */
-
-		nreaped++;
-
-		/* Check whether frame was correctly received. */
-		if ((fd.fd_status & FD_STATUS_OK) == FD_STATUS_OK) {
-			/* Does the frame contain a pointer to the data?  Let's check. */
-			if (fd.fd_rbd_offset != I82586NULL) {
-				/* Read the receive buffer descriptor */
-				obram_read(ioaddr, fd.fd_rbd_offset,
-					   (unsigned char *) &rbd,
-					   sizeof(rbd));
-
-#ifdef DEBUG_RX_ERROR
-				if ((rbd.rbd_status & RBD_STATUS_EOF) !=
-				    RBD_STATUS_EOF) printk(KERN_INFO
-							   "%s: wv_receive(): missing EOF flag.\n",
-							   dev->name);
-
-				if ((rbd.rbd_status & RBD_STATUS_F) !=
-				    RBD_STATUS_F) printk(KERN_INFO
-							 "%s: wv_receive(): missing F flag.\n",
-							 dev->name);
-#endif				/* DEBUG_RX_ERROR */
-
-				/* Read the packet and transmit to Linux */
-				wv_packet_read(dev, rbd.rbd_bufl,
-					       rbd.
-					       rbd_status &
-					       RBD_STATUS_ACNT);
-			}
-#ifdef DEBUG_RX_ERROR
-			else	/* if frame has no data */
-				printk(KERN_INFO
-				       "%s: wv_receive(): frame has no data.\n",
-				       dev->name);
-#endif
-		} else {	/* If reception was no successful */
-
-			dev->stats.rx_errors++;
-
-#ifdef DEBUG_RX_INFO
-			printk(KERN_DEBUG
-			       "%s: wv_receive(): frame not received successfully (%X).\n",
-			       dev->name, fd.fd_status);
-#endif
-
-#ifdef DEBUG_RX_ERROR
-			if ((fd.fd_status & FD_STATUS_S6) != 0)
-				printk(KERN_INFO
-				       "%s: wv_receive(): no EOF flag.\n",
-				       dev->name);
-#endif
-
-			if ((fd.fd_status & FD_STATUS_S7) != 0) {
-				dev->stats.rx_length_errors++;
-#ifdef DEBUG_RX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_receive(): frame too short.\n",
-				       dev->name);
-#endif
-			}
-
-			if ((fd.fd_status & FD_STATUS_S8) != 0) {
-				dev->stats.rx_over_errors++;
-#ifdef DEBUG_RX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_receive(): rx DMA overrun.\n",
-				       dev->name);
-#endif
-			}
-
-			if ((fd.fd_status & FD_STATUS_S9) != 0) {
-				dev->stats.rx_fifo_errors++;
-#ifdef DEBUG_RX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_receive(): ran out of resources.\n",
-				       dev->name);
-#endif
-			}
-
-			if ((fd.fd_status & FD_STATUS_S10) != 0) {
-				dev->stats.rx_frame_errors++;
-#ifdef DEBUG_RX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_receive(): alignment error.\n",
-				       dev->name);
-#endif
-			}
-
-			if ((fd.fd_status & FD_STATUS_S11) != 0) {
-				dev->stats.rx_crc_errors++;
-#ifdef DEBUG_RX_FAIL
-				printk(KERN_DEBUG
-				       "%s: wv_receive(): CRC error.\n",
-				       dev->name);
-#endif
-			}
-		}
-
-		fd.fd_status = 0;
-		obram_write(ioaddr, fdoff(lp->rx_head, fd_status),
-			    (unsigned char *) &fd.fd_status,
-			    sizeof(fd.fd_status));
-
-		fd.fd_command = FD_COMMAND_EL;
-		obram_write(ioaddr, fdoff(lp->rx_head, fd_command),
-			    (unsigned char *) &fd.fd_command,
-			    sizeof(fd.fd_command));
-
-		fd.fd_command = 0;
-		obram_write(ioaddr, fdoff(lp->rx_last, fd_command),
-			    (unsigned char *) &fd.fd_command,
-			    sizeof(fd.fd_command));
-
-		lp->rx_last = lp->rx_head;
-		lp->rx_head = fd.fd_link_offset;
-	}			/* for(;;) -> loop on all frames */
-
-#ifdef DEBUG_RX_INFO
-	if (nreaped > 1)
-		printk(KERN_DEBUG "%s: wv_receive(): reaped %d\n",
-		       dev->name, nreaped);
-#endif
-#ifdef DEBUG_RX_TRACE
-	printk(KERN_DEBUG "%s: <-wv_receive()\n", dev->name);
-#endif
-}
-
-/*********************** PACKET TRANSMISSION ***********************/
-/*
- * This part deals with sending packets through the WaveLAN.
- *
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine fills in the appropriate registers and memory
- * locations on the WaveLAN card and starts the card off on
- * the transmit.
- *
- * The principle:
- * Each block contains a transmit command, a NOP command,
- * a transmit block descriptor and a buffer.
- * The CU read the transmit block which point to the tbd,
- * read the tbd and the content of the buffer.
- * When it has finish with it, it goes to the next command
- * which in our case is the NOP. The NOP points on itself,
- * so the CU stop here.
- * When we add the next block, we modify the previous nop
- * to make it point on the new tx command.
- * Simple, isn't it ?
- *
- * (called in wavelan_packet_xmit())
- */
-static int wv_packet_write(struct net_device * dev, void *buf, short length)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	unsigned short txblock;
-	unsigned short txpred;
-	unsigned short tx_addr;
-	unsigned short nop_addr;
-	unsigned short tbd_addr;
-	unsigned short buf_addr;
-	ac_tx_t tx;
-	ac_nop_t nop;
-	tbd_t tbd;
-	int clen = length;
-	unsigned long flags;
-
-#ifdef DEBUG_TX_TRACE
-	printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name,
-	       length);
-#endif
-
-	spin_lock_irqsave(&lp->spinlock, flags);
-
-	/* Check nothing bad has happened */
-	if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
-#ifdef DEBUG_TX_ERROR
-		printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n",
-		       dev->name);
-#endif
-		spin_unlock_irqrestore(&lp->spinlock, flags);
-		return 1;
-	}
-
-	/* Calculate addresses of next block and previous block. */
-	txblock = lp->tx_first_free;
-	txpred = txblock - TXBLOCKZ;
-	if (txpred < OFFSET_CU)
-		txpred += NTXBLOCKS * TXBLOCKZ;
-	lp->tx_first_free += TXBLOCKZ;
-	if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-		lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
-
-	lp->tx_n_in_use++;
-
-	/* Calculate addresses of the different parts of the block. */
-	tx_addr = txblock;
-	nop_addr = tx_addr + sizeof(tx);
-	tbd_addr = nop_addr + sizeof(nop);
-	buf_addr = tbd_addr + sizeof(tbd);
-
-	/*
-	 * Transmit command
-	 */
-	tx.tx_h.ac_status = 0;
-	obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
-		    (unsigned char *) &tx.tx_h.ac_status,
-		    sizeof(tx.tx_h.ac_status));
-
-	/*
-	 * NOP command
-	 */
-	nop.nop_h.ac_status = 0;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-		    (unsigned char *) &nop.nop_h.ac_status,
-		    sizeof(nop.nop_h.ac_status));
-	nop.nop_h.ac_link = nop_addr;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-		    (unsigned char *) &nop.nop_h.ac_link,
-		    sizeof(nop.nop_h.ac_link));
-
-	/*
-	 * Transmit buffer descriptor
-	 */
-	tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & clen);
-	tbd.tbd_next_bd_offset = I82586NULL;
-	tbd.tbd_bufl = buf_addr;
-	tbd.tbd_bufh = 0;
-	obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd, sizeof(tbd));
-
-	/*
-	 * Data
-	 */
-	obram_write(ioaddr, buf_addr, buf, length);
-
-	/*
-	 * Overwrite the predecessor NOP link
-	 * so that it points to this txblock.
-	 */
-	nop_addr = txpred + sizeof(tx);
-	nop.nop_h.ac_status = 0;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-		    (unsigned char *) &nop.nop_h.ac_status,
-		    sizeof(nop.nop_h.ac_status));
-	nop.nop_h.ac_link = txblock;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-		    (unsigned char *) &nop.nop_h.ac_link,
-		    sizeof(nop.nop_h.ac_link));
-
-	/* Make sure the watchdog will keep quiet for a while */
-	dev->trans_start = jiffies;
-
-	/* Keep stats up to date. */
-	dev->stats.tx_bytes += length;
-
-	if (lp->tx_first_in_use == I82586NULL)
-		lp->tx_first_in_use = txblock;
-
-	if (lp->tx_n_in_use < NTXBLOCKS - 1)
-		netif_wake_queue(dev);
-
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-	
-#ifdef DEBUG_TX_INFO
-	wv_packet_info((u8 *) buf, length, dev->name,
-		       "wv_packet_write");
-#endif				/* DEBUG_TX_INFO */
-
-#ifdef DEBUG_TX_TRACE
-	printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
-#endif
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the harware is ready to accept
- * the packet.  We also prevent reentrance.  Then we call the function
- * to send the packet.
- */
-static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb,
-					     struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-	char data[ETH_ZLEN];
-
-#ifdef DEBUG_TX_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
-	       (unsigned) skb);
-#endif
-
-	/*
-	 * Block a timer-based transmit from overlapping.
-	 * In other words, prevent reentering this routine.
-	 */
-	netif_stop_queue(dev);
-
-	/* If somebody has asked to reconfigure the controller, 
-	 * we can do it now.
-	 */
-	if (lp->reconfig_82586) {
-		spin_lock_irqsave(&lp->spinlock, flags);
-		wv_82586_config(dev);
-		spin_unlock_irqrestore(&lp->spinlock, flags);
-		/* Check that we can continue */
-		if (lp->tx_n_in_use == (NTXBLOCKS - 1))
-			return NETDEV_TX_BUSY;
-	}
-
-	/* Do we need some padding? */
-	/* Note : on wireless the propagation time is in the order of 1us,
-	 * and we don't have the Ethernet specific requirement of beeing
-	 * able to detect collisions, therefore in theory we don't really
-	 * need to pad. Jean II */
-	if (skb->len < ETH_ZLEN) {
-		memset(data, 0, ETH_ZLEN);
-		skb_copy_from_linear_data(skb, data, skb->len);
-		/* Write packet on the card */
-		if(wv_packet_write(dev, data, ETH_ZLEN))
-			return NETDEV_TX_BUSY;	/* We failed */
-	}
-	else if(wv_packet_write(dev, skb->data, skb->len))
-		return NETDEV_TX_BUSY;	/* We failed */
-
-
-	dev_kfree_skb(skb);
-
-#ifdef DEBUG_TX_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
-#endif
-	return NETDEV_TX_OK;
-}
-
-/*********************** HARDWARE CONFIGURATION ***********************/
-/*
- * This part does the real job of starting and configuring the hardware.
- */
-
-/*--------------------------------------------------------------------*/
-/*
- * Routine to initialize the Modem Management Controller.
- * (called by wv_hw_reset())
- */
-static int wv_mmc_init(struct net_device * dev)
-{
-	unsigned long ioaddr = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	mmw_t m;
-	int configured;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
-#endif
-
-	/* Read the parameter storage area. */
-	psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef USE_PSA_CONFIG
-	configured = psa.psa_conf_status & 1;
-#else
-	configured = 0;
-#endif
-
-	/* Is the PSA is not configured */
-	if (!configured) {
-		/* User will be able to configure NWID later (with iwconfig). */
-		psa.psa_nwid[0] = 0;
-		psa.psa_nwid[1] = 0;
-
-		/* no NWID checking since NWID is not set */
-		psa.psa_nwid_select = 0;
-
-		/* Disable encryption */
-		psa.psa_encryption_select = 0;
-
-		/* Set to standard values:
-		 * 0x04 for AT,
-		 * 0x01 for MCA,
-		 * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
-		 */
-		if (psa.psa_comp_number & 1)
-			psa.psa_thr_pre_set = 0x01;
-		else
-			psa.psa_thr_pre_set = 0x04;
-		psa.psa_quality_thr = 0x03;
-
-		/* It is configured */
-		psa.psa_conf_status |= 1;
-
-#ifdef USE_PSA_CONFIG
-		/* Write the psa. */
-		psa_write(ioaddr, lp->hacr,
-			  (char *) psa.psa_nwid - (char *) &psa,
-			  (unsigned char *) psa.psa_nwid, 4);
-		psa_write(ioaddr, lp->hacr,
-			  (char *) &psa.psa_thr_pre_set - (char *) &psa,
-			  (unsigned char *) &psa.psa_thr_pre_set, 1);
-		psa_write(ioaddr, lp->hacr,
-			  (char *) &psa.psa_quality_thr - (char *) &psa,
-			  (unsigned char *) &psa.psa_quality_thr, 1);
-		psa_write(ioaddr, lp->hacr,
-			  (char *) &psa.psa_conf_status - (char *) &psa,
-			  (unsigned char *) &psa.psa_conf_status, 1);
-		/* update the Wavelan checksum */
-		update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
-	}
-
-	/* Zero the mmc structure. */
-	memset(&m, 0x00, sizeof(m));
-
-	/* Copy PSA info to the mmc. */
-	m.mmw_netw_id_l = psa.psa_nwid[1];
-	m.mmw_netw_id_h = psa.psa_nwid[0];
-
-	if (psa.psa_nwid_select & 1)
-		m.mmw_loopt_sel = 0x00;
-	else
-		m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
-
-	memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
-	       sizeof(m.mmw_encr_key));
-
-	if (psa.psa_encryption_select)
-		m.mmw_encr_enable =
-		    MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
-	else
-		m.mmw_encr_enable = 0;
-
-	m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
-	m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
-
-	/*
-	 * Set default modem control parameters.
-	 * See NCR document 407-0024326 Rev. A.
-	 */
-	m.mmw_jabber_enable = 0x01;
-	m.mmw_freeze = 0;
-	m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
-	m.mmw_ifs = 0x20;
-	m.mmw_mod_delay = 0x04;
-	m.mmw_jam_time = 0x38;
-
-	m.mmw_des_io_invert = 0;
-	m.mmw_decay_prm = 0;
-	m.mmw_decay_updat_prm = 0;
-
-	/* Write all info to MMC. */
-	mmc_write(ioaddr, 0, (u8 *) & m, sizeof(m));
-
-	/* The following code starts the modem of the 2.00 frequency
-	 * selectable cards at power on.  It's not strictly needed for the
-	 * following boots.
-	 * The original patch was by Joe Finney for the PCMCIA driver, but
-	 * I've cleaned it up a bit and added documentation.
-	 * Thanks to Loeke Brederveld from Lucent for the info.
-	 */
-
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-	 * Does it work for everybody, especially old cards? */
-	/* Note: WFREQSEL verifies that it is able to read a sensible
-	 * frequency from EEPROM (address 0x00) and that MMR_FEE_STATUS_ID
-	 * is 0xA (Xilinx version) or 0xB (Ariadne version).
-	 * My test is more crude but does work. */
-	if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		/* We must download the frequency parameters to the
-		 * synthesizers (from the EEPROM - area 1)
-		 * Note: as the EEPROM is automatically decremented, we set the end
-		 * if the area... */
-		m.mmw_fee_addr = 0x0F;
-		m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-		mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
-			  (unsigned char *) &m.mmw_fee_ctrl, 2);
-
-		/* Wait until the download is finished. */
-		fee_wait(ioaddr, 100, 100);
-
-#ifdef DEBUG_CONFIG_INFO
-		/* The frequency was in the last word downloaded. */
-		mmc_read(ioaddr, (char *) &m.mmw_fee_data_l - (char *) &m,
-			 (unsigned char *) &m.mmw_fee_data_l, 2);
-
-		/* Print some info for the user. */
-		printk(KERN_DEBUG
-		       "%s: WaveLAN 2.00 recognised (frequency select).  Current frequency = %ld\n",
-		       dev->name,
-		       ((m.
-			 mmw_fee_data_h << 4) | (m.mmw_fee_data_l >> 4)) *
-		       5 / 2 + 24000L);
-#endif
-
-		/* We must now download the power adjust value (gain) to
-		 * the synthesizers (from the EEPROM - area 7 - DAC). */
-		m.mmw_fee_addr = 0x61;
-		m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-		mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
-			  (unsigned char *) &m.mmw_fee_ctrl, 2);
-
-		/* Wait until the download is finished. */
-	}
-	/* if 2.00 card */
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Construct the fd and rbd structures.
- * Start the receive unit.
- * (called by wv_hw_reset())
- */
-static int wv_ru_start(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	u16 scb_cs;
-	fd_t fd;
-	rbd_t rbd;
-	u16 rx;
-	u16 rx_next;
-	int i;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
-#endif
-
-	obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-		   (unsigned char *) &scb_cs, sizeof(scb_cs));
-	if ((scb_cs & SCB_ST_RUS) == SCB_ST_RUS_RDY)
-		return 0;
-
-	lp->rx_head = OFFSET_RU;
-
-	for (i = 0, rx = lp->rx_head; i < NRXBLOCKS; i++, rx = rx_next) {
-		rx_next =
-		    (i == NRXBLOCKS - 1) ? lp->rx_head : rx + RXBLOCKZ;
-
-		fd.fd_status = 0;
-		fd.fd_command = (i == NRXBLOCKS - 1) ? FD_COMMAND_EL : 0;
-		fd.fd_link_offset = rx_next;
-		fd.fd_rbd_offset = rx + sizeof(fd);
-		obram_write(ioaddr, rx, (unsigned char *) &fd, sizeof(fd));
-
-		rbd.rbd_status = 0;
-		rbd.rbd_next_rbd_offset = I82586NULL;
-		rbd.rbd_bufl = rx + sizeof(fd) + sizeof(rbd);
-		rbd.rbd_bufh = 0;
-		rbd.rbd_el_size = RBD_EL | (RBD_SIZE & MAXDATAZ);
-		obram_write(ioaddr, rx + sizeof(fd),
-			    (unsigned char *) &rbd, sizeof(rbd));
-
-		lp->rx_last = rx;
-	}
-
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_rfa_offset),
-		    (unsigned char *) &lp->rx_head, sizeof(lp->rx_head));
-
-	scb_cs = SCB_CMD_RUC_GO;
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-	set_chan_attn(ioaddr, lp->hacr);
-
-	for (i = 1000; i > 0; i--) {
-		obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-			   (unsigned char *) &scb_cs, sizeof(scb_cs));
-		if (scb_cs == 0)
-			break;
-
-		udelay(10);
-	}
-
-	if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_ru_start(): board not accepting command.\n",
-		       dev->name);
-#endif
-		return -1;
-	}
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Initialise the transmit blocks.
- * Start the command unit executing the NOP
- * self-loop of the first transmit block.
- *
- * Here we create the list of send buffers used to transmit packets
- * between the PC and the command unit. For each buffer, we create a
- * buffer descriptor (pointing on the buffer), a transmit command
- * (pointing to the buffer descriptor) and a NOP command.
- * The transmit command is linked to the NOP, and the NOP to itself.
- * When we will have finished executing the transmit command, we will
- * then loop on the NOP. By releasing the NOP link to a new command,
- * we may send another buffer.
- *
- * (called by wv_hw_reset())
- */
-static int wv_cu_start(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	int i;
-	u16 txblock;
-	u16 first_nop;
-	u16 scb_cs;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_cu_start()\n", dev->name);
-#endif
-
-	lp->tx_first_free = OFFSET_CU;
-	lp->tx_first_in_use = I82586NULL;
-
-	for (i = 0, txblock = OFFSET_CU;
-	     i < NTXBLOCKS; i++, txblock += TXBLOCKZ) {
-		ac_tx_t tx;
-		ac_nop_t nop;
-		tbd_t tbd;
-		unsigned short tx_addr;
-		unsigned short nop_addr;
-		unsigned short tbd_addr;
-		unsigned short buf_addr;
-
-		tx_addr = txblock;
-		nop_addr = tx_addr + sizeof(tx);
-		tbd_addr = nop_addr + sizeof(nop);
-		buf_addr = tbd_addr + sizeof(tbd);
-
-		tx.tx_h.ac_status = 0;
-		tx.tx_h.ac_command = acmd_transmit | AC_CFLD_I;
-		tx.tx_h.ac_link = nop_addr;
-		tx.tx_tbd_offset = tbd_addr;
-		obram_write(ioaddr, tx_addr, (unsigned char *) &tx,
-			    sizeof(tx));
-
-		nop.nop_h.ac_status = 0;
-		nop.nop_h.ac_command = acmd_nop;
-		nop.nop_h.ac_link = nop_addr;
-		obram_write(ioaddr, nop_addr, (unsigned char *) &nop,
-			    sizeof(nop));
-
-		tbd.tbd_status = TBD_STATUS_EOF;
-		tbd.tbd_next_bd_offset = I82586NULL;
-		tbd.tbd_bufl = buf_addr;
-		tbd.tbd_bufh = 0;
-		obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd,
-			    sizeof(tbd));
-	}
-
-	first_nop =
-	    OFFSET_CU + (NTXBLOCKS - 1) * TXBLOCKZ + sizeof(ac_tx_t);
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_cbl_offset),
-		    (unsigned char *) &first_nop, sizeof(first_nop));
-
-	scb_cs = SCB_CMD_CUC_GO;
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-	set_chan_attn(ioaddr, lp->hacr);
-
-	for (i = 1000; i > 0; i--) {
-		obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-			   (unsigned char *) &scb_cs, sizeof(scb_cs));
-		if (scb_cs == 0)
-			break;
-
-		udelay(10);
-	}
-
-	if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_cu_start(): board not accepting command.\n",
-		       dev->name);
-#endif
-		return -1;
-	}
-
-	lp->tx_n_in_use = 0;
-	netif_start_queue(dev);
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_cu_start()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard configuration of the WaveLAN 
- * controller (i82586).
- *
- * It initialises the scp, iscp and scb structure
- * The first two are just pointers to the next.
- * The last one is used for basic configuration and for basic
- * communication (interrupt status).
- *
- * (called by wv_hw_reset())
- */
-static int wv_82586_start(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	scp_t scp;		/* system configuration pointer */
-	iscp_t iscp;		/* intermediate scp */
-	scb_t scb;		/* system control block */
-	ach_t cb;		/* Action command header */
-	u8 zeroes[512];
-	int i;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_82586_start()\n", dev->name);
-#endif
-
-	/*
-	 * Clear the onboard RAM.
-	 */
-	memset(&zeroes[0], 0x00, sizeof(zeroes));
-	for (i = 0; i < I82586_MEMZ; i += sizeof(zeroes))
-		obram_write(ioaddr, i, &zeroes[0], sizeof(zeroes));
-
-	/*
-	 * Construct the command unit structures:
-	 * scp, iscp, scb, cb.
-	 */
-	memset(&scp, 0x00, sizeof(scp));
-	scp.scp_sysbus = SCP_SY_16BBUS;
-	scp.scp_iscpl = OFFSET_ISCP;
-	obram_write(ioaddr, OFFSET_SCP, (unsigned char *) &scp,
-		    sizeof(scp));
-
-	memset(&iscp, 0x00, sizeof(iscp));
-	iscp.iscp_busy = 1;
-	iscp.iscp_offset = OFFSET_SCB;
-	obram_write(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
-		    sizeof(iscp));
-
-	/* Our first command is to reset the i82586. */
-	memset(&scb, 0x00, sizeof(scb));
-	scb.scb_command = SCB_CMD_RESET;
-	scb.scb_cbl_offset = OFFSET_CU;
-	scb.scb_rfa_offset = OFFSET_RU;
-	obram_write(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-		    sizeof(scb));
-
-	set_chan_attn(ioaddr, lp->hacr);
-
-	/* Wait for command to finish. */
-	for (i = 1000; i > 0; i--) {
-		obram_read(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
-			   sizeof(iscp));
-
-		if (iscp.iscp_busy == (unsigned short) 0)
-			break;
-
-		udelay(10);
-	}
-
-	if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wv_82586_start(): iscp_busy timeout.\n",
-		       dev->name);
-#endif
-		return -1;
-	}
-
-	/* Check command completion. */
-	for (i = 15; i > 0; i--) {
-		obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-			   sizeof(scb));
-
-		if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA))
-			break;
-
-		udelay(10);
-	}
-
-	if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wv_82586_start(): status: expected 0x%02x, got 0x%02x.\n",
-		       dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status);
-#endif
-		return -1;
-	}
-
-	wv_ack(dev);
-
-	/* Set the action command header. */
-	memset(&cb, 0x00, sizeof(cb));
-	cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose);
-	cb.ac_link = OFFSET_CU;
-	obram_write(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
-
-	if (wv_synchronous_cmd(dev, "diag()") == -1)
-		return -1;
-
-	obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
-	if (cb.ac_status & AC_SFLD_FAIL) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wv_82586_start(): i82586 Self Test failed.\n",
-		       dev->name);
-#endif
-		return -1;
-	}
-#ifdef DEBUG_I82586_SHOW
-	wv_scb_show(ioaddr);
-#endif
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_82586_start()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard configuration of the WaveLAN
- * controller (i82586).
- *
- * This routine is a violent hack. We use the first free transmit block
- * to make our configuration. In the buffer area, we create the three
- * configuration commands (linked). We make the previous NOP point to
- * the beginning of the buffer instead of the tx command. After, we go
- * as usual to the NOP command.
- * Note that only the last command (mc_set) will generate an interrupt.
- *
- * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
- */
-static void wv_82586_config(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	unsigned short txblock;
-	unsigned short txpred;
-	unsigned short tx_addr;
-	unsigned short nop_addr;
-	unsigned short tbd_addr;
-	unsigned short cfg_addr;
-	unsigned short ias_addr;
-	unsigned short mcs_addr;
-	ac_tx_t tx;
-	ac_nop_t nop;
-	ac_cfg_t cfg;		/* Configure action */
-	ac_ias_t ias;		/* IA-setup action */
-	ac_mcs_t mcs;		/* Multicast setup */
-	struct dev_mc_list *dmi;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
-#endif
-
-	/* Check nothing bad has happened */
-	if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
-		       dev->name);
-#endif
-		return;
-	}
-
-	/* Calculate addresses of next block and previous block. */
-	txblock = lp->tx_first_free;
-	txpred = txblock - TXBLOCKZ;
-	if (txpred < OFFSET_CU)
-		txpred += NTXBLOCKS * TXBLOCKZ;
-	lp->tx_first_free += TXBLOCKZ;
-	if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-		lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
-
-	lp->tx_n_in_use++;
-
-	/* Calculate addresses of the different parts of the block. */
-	tx_addr = txblock;
-	nop_addr = tx_addr + sizeof(tx);
-	tbd_addr = nop_addr + sizeof(nop);
-	cfg_addr = tbd_addr + sizeof(tbd_t);	/* beginning of the buffer */
-	ias_addr = cfg_addr + sizeof(cfg);
-	mcs_addr = ias_addr + sizeof(ias);
-
-	/*
-	 * Transmit command
-	 */
-	tx.tx_h.ac_status = 0xFFFF;	/* Fake completion value */
-	obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
-		    (unsigned char *) &tx.tx_h.ac_status,
-		    sizeof(tx.tx_h.ac_status));
-
-	/*
-	 * NOP command
-	 */
-	nop.nop_h.ac_status = 0;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-		    (unsigned char *) &nop.nop_h.ac_status,
-		    sizeof(nop.nop_h.ac_status));
-	nop.nop_h.ac_link = nop_addr;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-		    (unsigned char *) &nop.nop_h.ac_link,
-		    sizeof(nop.nop_h.ac_link));
-
-	/* Create a configure action. */
-	memset(&cfg, 0x00, sizeof(cfg));
-
-	/*
-	 * For Linux we invert AC_CFG_ALOC() so as to conform
-	 * to the way that net packets reach us from above.
-	 * (See also ac_tx_t.)
-	 *
-	 * Updated from Wavelan Manual WCIN085B
-	 */
-	cfg.cfg_byte_cnt =
-	    AC_CFG_BYTE_CNT(sizeof(ac_cfg_t) - sizeof(ach_t));
-	cfg.cfg_fifolim = AC_CFG_FIFOLIM(4);
-	cfg.cfg_byte8 = AC_CFG_SAV_BF(1) | AC_CFG_SRDY(0);
-	cfg.cfg_byte9 = AC_CFG_ELPBCK(0) |
-	    AC_CFG_ILPBCK(0) |
-	    AC_CFG_PRELEN(AC_CFG_PLEN_2) |
-	    AC_CFG_ALOC(1) | AC_CFG_ADDRLEN(WAVELAN_ADDR_SIZE);
-	cfg.cfg_byte10 = AC_CFG_BOFMET(1) |
-	    AC_CFG_ACR(6) | AC_CFG_LINPRIO(0);
-	cfg.cfg_ifs = 0x20;
-	cfg.cfg_slotl = 0x0C;
-	cfg.cfg_byte13 = AC_CFG_RETRYNUM(15) | AC_CFG_SLTTMHI(0);
-	cfg.cfg_byte14 = AC_CFG_FLGPAD(0) |
-	    AC_CFG_BTSTF(0) |
-	    AC_CFG_CRC16(0) |
-	    AC_CFG_NCRC(0) |
-	    AC_CFG_TNCRS(1) |
-	    AC_CFG_MANCH(0) |
-	    AC_CFG_BCDIS(0) | AC_CFG_PRM(lp->promiscuous);
-	cfg.cfg_byte15 = AC_CFG_ICDS(0) |
-	    AC_CFG_CDTF(0) | AC_CFG_ICSS(0) | AC_CFG_CSTF(0);
-/*
-  cfg.cfg_min_frm_len = AC_CFG_MNFRM(64);
-*/
-	cfg.cfg_min_frm_len = AC_CFG_MNFRM(8);
-
-	cfg.cfg_h.ac_command = (AC_CFLD_CMD & acmd_configure);
-	cfg.cfg_h.ac_link = ias_addr;
-	obram_write(ioaddr, cfg_addr, (unsigned char *) &cfg, sizeof(cfg));
-
-	/* Set up the MAC address */
-	memset(&ias, 0x00, sizeof(ias));
-	ias.ias_h.ac_command = (AC_CFLD_CMD & acmd_ia_setup);
-	ias.ias_h.ac_link = mcs_addr;
-	memcpy(&ias.ias_addr[0], (unsigned char *) &dev->dev_addr[0],
-	       sizeof(ias.ias_addr));
-	obram_write(ioaddr, ias_addr, (unsigned char *) &ias, sizeof(ias));
-
-	/* Initialize adapter's Ethernet multicast addresses */
-	memset(&mcs, 0x00, sizeof(mcs));
-	mcs.mcs_h.ac_command = AC_CFLD_I | (AC_CFLD_CMD & acmd_mc_setup);
-	mcs.mcs_h.ac_link = nop_addr;
-	mcs.mcs_cnt = WAVELAN_ADDR_SIZE * lp->mc_count;
-	obram_write(ioaddr, mcs_addr, (unsigned char *) &mcs, sizeof(mcs));
-
-	/* Any address to set? */
-	if (lp->mc_count) {
-		for (dmi = dev->mc_list; dmi; dmi = dmi->next)
-			outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr,
-			      WAVELAN_ADDR_SIZE >> 1);
-
-#ifdef DEBUG_CONFIG_INFO
-		printk(KERN_DEBUG
-		       "%s: wv_82586_config(): set %d multicast addresses:\n",
-		       dev->name, lp->mc_count);
-		for (dmi = dev->mc_list; dmi; dmi = dmi->next)
-			printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
-#endif
-	}
-
-	/*
-	 * Overwrite the predecessor NOP link
-	 * so that it points to the configure action.
-	 */
-	nop_addr = txpred + sizeof(tx);
-	nop.nop_h.ac_status = 0;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-		    (unsigned char *) &nop.nop_h.ac_status,
-		    sizeof(nop.nop_h.ac_status));
-	nop.nop_h.ac_link = cfg_addr;
-	obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-		    (unsigned char *) &nop.nop_h.ac_link,
-		    sizeof(nop.nop_h.ac_link));
-
-	/* Job done, clear the flag */
-	lp->reconfig_82586 = 0;
-
-	if (lp->tx_first_in_use == I82586NULL)
-		lp->tx_first_in_use = txblock;
-
-	if (lp->tx_n_in_use == (NTXBLOCKS - 1))
-		netif_stop_queue(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine, called by wavelan_close(), gracefully stops the 
- * WaveLAN controller (i82586).
- * (called by wavelan_close())
- */
-static void wv_82586_stop(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-	u16 scb_cmd;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_82586_stop()\n", dev->name);
-#endif
-
-	/* Suspend both command unit and receive unit. */
-	scb_cmd =
-	    (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC &
-					       SCB_CMD_RUC_SUS);
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &scb_cmd, sizeof(scb_cmd));
-	set_chan_attn(ioaddr, lp->hacr);
-
-	/* No more interrupts */
-	wv_ints_off(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_82586_stop()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Totally reset the WaveLAN and restart it.
- * Performs the following actions:
- *	1. A power reset (reset DMA)
- *	2. Initialize the radio modem (using wv_mmc_init)
- *	3. Reset & Configure LAN controller (using wv_82586_start)
- *	4. Start the LAN controller's command unit
- *	5. Start the LAN controller's receive unit
- * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
- */
-static int wv_hw_reset(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name,
-	       (unsigned int) dev);
-#endif
-
-	/* Increase the number of resets done. */
-	lp->nresets++;
-
-	wv_hacr_reset(ioaddr);
-	lp->hacr = HACR_DEFAULT;
-
-	if ((wv_mmc_init(dev) < 0) || (wv_82586_start(dev) < 0))
-		return -1;
-
-	/* Enable the card to send interrupts. */
-	wv_ints_on(dev);
-
-	/* Start card functions */
-	if (wv_cu_start(dev) < 0)
-		return -1;
-
-	/* Setup the controller and parameters */
-	wv_82586_config(dev);
-
-	/* Finish configuration with the receive unit */
-	if (wv_ru_start(dev) < 0)
-		return -1;
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Check if there is a WaveLAN at the specific base address.
- * As a side effect, this reads the MAC address.
- * (called in wavelan_probe() and init_module())
- */
-static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
-{
-	int i;			/* Loop counter */
-
-	/* Check if the base address if available. */
-	if (!request_region(ioaddr, sizeof(ha_t), "wavelan probe"))
-		return -EBUSY;		/* ioaddr already used */
-
-	/* Reset host interface */
-	wv_hacr_reset(ioaddr);
-
-	/* Read the MAC address from the parameter storage area. */
-	psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_univ_mac_addr),
-		 mac, 6);
-
-	release_region(ioaddr, sizeof(ha_t));
-
-	/*
-	 * Check the first three octets of the address for the manufacturer's code.
-	 * Note: if this can't find your WaveLAN card, you've got a
-	 * non-NCR/AT&T/Lucent ISA card.  See wavelan.p.h for detail on
-	 * how to configure your card.
-	 */
-	for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
-		if ((mac[0] == MAC_ADDRESSES[i][0]) &&
-		    (mac[1] == MAC_ADDRESSES[i][1]) &&
-		    (mac[2] == MAC_ADDRESSES[i][2]))
-			return 0;
-
-#ifdef DEBUG_CONFIG_INFO
-	printk(KERN_WARNING
-	       "WaveLAN (0x%3X): your MAC address might be %02X:%02X:%02X.\n",
-	       ioaddr, mac[0], mac[1], mac[2]);
-#endif
-	return -ENODEV;
-}
-
-/************************ INTERRUPT HANDLING ************************/
-
-/*
- * This function is the interrupt handler for the WaveLAN card. This
- * routine will be called whenever: 
- */
-static irqreturn_t wavelan_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev;
-	unsigned long ioaddr;
-	net_local *lp;
-	u16 hasr;
-	u16 status;
-	u16 ack_cmd;
-
-	dev = dev_id;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
-#endif
-
-	lp = netdev_priv(dev);
-	ioaddr = dev->base_addr;
-
-#ifdef DEBUG_INTERRUPT_INFO
-	/* Check state of our spinlock */
-	if(spin_is_locked(&lp->spinlock))
-		printk(KERN_DEBUG
-		       "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
-		       dev->name);
-#endif
-
-	/* Prevent reentrancy. We need to do that because we may have
-	 * multiple interrupt handler running concurrently.
-	 * It is safe because interrupts are disabled before acquiring
-	 * the spinlock. */
-	spin_lock(&lp->spinlock);
-
-	/* We always had spurious interrupts at startup, but lately I
-	 * saw them comming *between* the request_irq() and the
-	 * spin_lock_irqsave() in wavelan_open(), so the spinlock
-	 * protection is no enough.
-	 * So, we also check lp->hacr that will tell us is we enabled
-	 * irqs or not (see wv_ints_on()).
-	 * We can't use netif_running(dev) because we depend on the
-	 * proper processing of the irq generated during the config. */
-
-	/* Which interrupt it is ? */
-	hasr = hasr_read(ioaddr);
-
-#ifdef DEBUG_INTERRUPT_INFO
-	printk(KERN_INFO
-	       "%s: wavelan_interrupt(): hasr 0x%04x; hacr 0x%04x.\n",
-	       dev->name, hasr, lp->hacr);
-#endif
-
-	/* Check modem interrupt */
-	if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) {
-		u8 dce_status;
-
-		/*
-		 * Interrupt from the modem management controller.
-		 * This will clear it -- ignored for now.
-		 */
-		mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status,
-			 sizeof(dce_status));
-
-#ifdef DEBUG_INTERRUPT_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n",
-		       dev->name, dce_status);
-#endif
-	}
-
-	/* Check if not controller interrupt */
-	if (((hasr & HASR_82586_INTR) == 0) ||
-	    ((lp->hacr & HACR_82586_INT_ENABLE) == 0)) {
-#ifdef DEBUG_INTERRUPT_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_interrupt(): interrupt not coming from i82586 - hasr 0x%04x.\n",
-		       dev->name, hasr);
-#endif
-		spin_unlock (&lp->spinlock);
-		return IRQ_NONE;
-	}
-
-	/* Read interrupt data. */
-	obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-		   (unsigned char *) &status, sizeof(status));
-
-	/*
-	 * Acknowledge the interrupt(s).
-	 */
-	ack_cmd = status & SCB_ST_INT;
-	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-		    (unsigned char *) &ack_cmd, sizeof(ack_cmd));
-	set_chan_attn(ioaddr, lp->hacr);
-
-#ifdef DEBUG_INTERRUPT_INFO
-	printk(KERN_DEBUG "%s: wavelan_interrupt(): status 0x%04x.\n",
-	       dev->name, status);
-#endif
-
-	/* Command completed. */
-	if ((status & SCB_ST_CX) == SCB_ST_CX) {
-#ifdef DEBUG_INTERRUPT_INFO
-		printk(KERN_DEBUG
-		       "%s: wavelan_interrupt(): command completed.\n",
-		       dev->name);
-#endif
-		wv_complete(dev, ioaddr, lp);
-	}
-
-	/* Frame received. */
-	if ((status & SCB_ST_FR) == SCB_ST_FR) {
-#ifdef DEBUG_INTERRUPT_INFO
-		printk(KERN_DEBUG
-		       "%s: wavelan_interrupt(): received packet.\n",
-		       dev->name);
-#endif
-		wv_receive(dev);
-	}
-
-	/* Check the state of the command unit. */
-	if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
-	    (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
-	     (netif_running(dev)))) {
-#ifdef DEBUG_INTERRUPT_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_interrupt(): CU inactive -- restarting\n",
-		       dev->name);
-#endif
-		wv_hw_reset(dev);
-	}
-
-	/* Check the state of the command unit. */
-	if (((status & SCB_ST_RNR) == SCB_ST_RNR) ||
-	    (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) &&
-	     (netif_running(dev)))) {
-#ifdef DEBUG_INTERRUPT_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_interrupt(): RU not ready -- restarting\n",
-		       dev->name);
-#endif
-		wv_hw_reset(dev);
-	}
-
-	/* Release spinlock */
-	spin_unlock (&lp->spinlock);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
-#endif
-	return IRQ_HANDLED;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Watchdog: when we start a transmission, a timer is set for us in the
- * kernel.  If the transmission completes, this timer is disabled. If
- * the timer expires, we are called and we try to unlock the hardware.
- */
-static void wavelan_watchdog(struct net_device *	dev)
-{
-	net_local *lp = netdev_priv(dev);
-	u_long		ioaddr = dev->base_addr;
-	unsigned long	flags;
-	unsigned int	nreaped;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
-#endif
-
-#ifdef DEBUG_INTERRUPT_ERROR
-	printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
-	       dev->name);
-#endif
-
-	/* Check that we came here for something */
-	if (lp->tx_n_in_use <= 0) {
-		return;
-	}
-
-	spin_lock_irqsave(&lp->spinlock, flags);
-
-	/* Try to see if some buffers are not free (in case we missed
-	 * an interrupt */
-	nreaped = wv_complete(dev, ioaddr, lp);
-
-#ifdef DEBUG_INTERRUPT_INFO
-	printk(KERN_DEBUG
-	       "%s: wavelan_watchdog(): %d reaped, %d remain.\n",
-	       dev->name, nreaped, lp->tx_n_in_use);
-#endif
-
-#ifdef DEBUG_PSA_SHOW
-	{
-		psa_t psa;
-		psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-		wv_psa_show(&psa);
-	}
-#endif
-#ifdef DEBUG_MMC_SHOW
-	wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82586_SHOW
-	wv_cu_show(dev);
-#endif
-
-	/* If no buffer has been freed */
-	if (nreaped == 0) {
-#ifdef DEBUG_INTERRUPT_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_watchdog(): cleanup failed, trying reset\n",
-		       dev->name);
-#endif
-		wv_hw_reset(dev);
-	}
-
-	/* At this point, we should have some free Tx buffer ;-) */
-	if (lp->tx_n_in_use < NTXBLOCKS - 1)
-		netif_wake_queue(dev);
-
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-	
-#ifdef DEBUG_INTERRUPT_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
-#endif
-}
-
-/********************* CONFIGURATION CALLBACKS *********************/
-/*
- * Here are the functions called by the Linux networking code (NET3)
- * for initialization, configuration and deinstallations of the 
- * WaveLAN ISA hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Configure and start up the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "opens" the device.
- */
-static int wavelan_open(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long	flags;
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
-	       (unsigned int) dev);
-#endif
-
-	/* Check irq */
-	if (dev->irq == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n",
-		       dev->name);
-#endif
-		return -ENXIO;
-	}
-
-	if (request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", dev) != 0) 
-	{
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n",
-		       dev->name);
-#endif
-		return -EAGAIN;
-	}
-
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	if (wv_hw_reset(dev) != -1) {
-		netif_start_queue(dev);
-	} else {
-		free_irq(dev->irq, dev);
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_open(): impossible to start the card\n",
-		       dev->name);
-#endif
-		spin_unlock_irqrestore(&lp->spinlock, flags);
-		return -EAGAIN;
-	}
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-	
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
-#endif
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Shut down the WaveLAN ISA card.
- * Called by NET3 when it "closes" the device.
- */
-static int wavelan_close(struct net_device * dev)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
-	       (unsigned int) dev);
-#endif
-
-	netif_stop_queue(dev);
-
-	/*
-	 * Flush the Tx and disable Rx.
-	 */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	wv_82586_stop(dev);
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	free_irq(dev->irq, dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
-#endif
-	return 0;
-}
-
-static const struct net_device_ops wavelan_netdev_ops = {
-	.ndo_open 		= wavelan_open,
-	.ndo_stop 		= wavelan_close,
-	.ndo_start_xmit		= wavelan_packet_xmit,
-	.ndo_set_multicast_list = wavelan_set_multicast_list,
-        .ndo_tx_timeout		= wavelan_watchdog,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_validate_addr	= eth_validate_addr,
-#ifdef SET_MAC_ADDRESS
-	.ndo_set_mac_address	= wavelan_set_mac_address
-#else
-	.ndo_set_mac_address 	= eth_mac_addr,
-#endif
-};
-
-
-/*------------------------------------------------------------------*/
-/*
- * Probe an I/O address, and if the WaveLAN is there configure the
- * device structure
- * (called by wavelan_probe() and via init_module()).
- */
-static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
-{
-	u8 irq_mask;
-	int irq;
-	net_local *lp;
-	mac_addr mac;
-	int err;
-
-	if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
-		return -EADDRINUSE;
-
-	err = wv_check_ioaddr(ioaddr, mac);
-	if (err)
-		goto out;
-
-	memcpy(dev->dev_addr, mac, 6);
-
-	dev->base_addr = ioaddr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
-	       dev->name, (unsigned int) dev, ioaddr);
-#endif
-
-	/* Check IRQ argument on command line. */
-	if (dev->irq != 0) {
-		irq_mask = wv_irq_to_psa(dev->irq);
-
-		if (irq_mask == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-			printk(KERN_WARNING
-			       "%s: wavelan_config(): invalid IRQ %d ignored.\n",
-			       dev->name, dev->irq);
-#endif
-			dev->irq = 0;
-		} else {
-#ifdef DEBUG_CONFIG_INFO
-			printk(KERN_DEBUG
-			       "%s: wavelan_config(): changing IRQ to %d\n",
-			       dev->name, dev->irq);
-#endif
-			psa_write(ioaddr, HACR_DEFAULT,
-				  psaoff(0, psa_int_req_no), &irq_mask, 1);
-			/* update the Wavelan checksum */
-			update_psa_checksum(dev, ioaddr, HACR_DEFAULT);
-			wv_hacr_reset(ioaddr);
-		}
-	}
-
-	psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_int_req_no),
-		 &irq_mask, 1);
-	if ((irq = wv_psa_to_irq(irq_mask)) == -1) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_INFO
-		       "%s: wavelan_config(): could not wavelan_map_irq(%d).\n",
-		       dev->name, irq_mask);
-#endif
-		err = -EAGAIN;
-		goto out;
-	}
-
-	dev->irq = irq;
-
-	dev->mem_start = 0x0000;
-	dev->mem_end = 0x0000;
-	dev->if_port = 0;
-
-	/* Initialize device structures */
-	memset(netdev_priv(dev), 0, sizeof(net_local));
-	lp = netdev_priv(dev);
-
-	/* Back link to the device structure. */
-	lp->dev = dev;
-	/* Add the device at the beginning of the linked list. */
-	lp->next = wavelan_list;
-	wavelan_list = lp;
-
-	lp->hacr = HACR_DEFAULT;
-
-	/* Multicast stuff */
-	lp->promiscuous = 0;
-	lp->mc_count = 0;
-
-	/* Init spinlock */
-	spin_lock_init(&lp->spinlock);
-
-	dev->netdev_ops = &wavelan_netdev_ops;
-	dev->watchdog_timeo = WATCHDOG_JIFFIES;
-	dev->wireless_handlers = &wavelan_handler_def;
-	lp->wireless_data.spy_data = &lp->spy_data;
-	dev->wireless_data = &lp->wireless_data;
-
-	dev->mtu = WAVELAN_MTU;
-
-	/* Display nice information. */
-	wv_init_info(dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name);
-#endif
-	return 0;
-out:
-	release_region(ioaddr, sizeof(ha_t));
-	return err;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Check for a network adaptor of this type.  Return '0' iff one 
- * exists.  There seem to be different interpretations of
- * the initial value of dev->base_addr.
- * We follow the example in drivers/net/ne.c.
- * (called in "Space.c")
- */
-struct net_device * __init wavelan_probe(int unit)
-{
-	struct net_device *dev;
-	short base_addr;
-	int def_irq;
-	int i;
-	int r = 0;
-
-	/* compile-time check the sizes of structures */
-	BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
-	BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
-	BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
-	BUILD_BUG_ON(sizeof(ha_t) != HA_SIZE);
-
-	dev = alloc_etherdev(sizeof(net_local));
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-	base_addr = dev->base_addr;
-	def_irq = dev->irq;
-
-#ifdef DEBUG_CALLBACK_TRACE
-	printk(KERN_DEBUG
-	       "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n",
-	       dev->name, dev, (unsigned int) dev->base_addr);
-#endif
-
-	/* Don't probe at all. */
-	if (base_addr < 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_WARNING
-		       "%s: wavelan_probe(): invalid base address\n",
-		       dev->name);
-#endif
-		r = -ENXIO;
-	} else if (base_addr > 0x100) { /* Check a single specified location. */
-		r = wavelan_config(dev, base_addr);
-#ifdef DEBUG_CONFIG_INFO
-		if (r != 0)
-			printk(KERN_DEBUG
-			       "%s: wavelan_probe(): no device at specified base address (0x%X) or address already in use\n",
-			       dev->name, base_addr);
-#endif
-
-#ifdef DEBUG_CALLBACK_TRACE
-		printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
-#endif
-	} else { /* Scan all possible addresses of the WaveLAN hardware. */
-		for (i = 0; i < ARRAY_SIZE(iobase); i++) {
-			dev->irq = def_irq;
-			if (wavelan_config(dev, iobase[i]) == 0) {
-#ifdef DEBUG_CALLBACK_TRACE
-				printk(KERN_DEBUG
-				       "%s: <-wavelan_probe()\n",
-				       dev->name);
-#endif
-				break;
-			}
-		}
-		if (i == ARRAY_SIZE(iobase))
-			r = -ENODEV;
-	}
-	if (r) 
-		goto out;
-	r = register_netdev(dev);
-	if (r)
-		goto out1;
-	return dev;
-out1:
-	release_region(dev->base_addr, sizeof(ha_t));
-	wavelan_list = wavelan_list->next;
-out:
-	free_netdev(dev);
-	return ERR_PTR(r);
-}
-
-/****************************** MODULE ******************************/
-/*
- * Module entry point: insertion and removal
- */
-
-#ifdef	MODULE
-/*------------------------------------------------------------------*/
-/*
- * Insertion of the module
- * I'm now quite proud of the multi-device support.
- */
-int __init init_module(void)
-{
-	int ret = -EIO;		/* Return error if no cards found */
-	int i;
-
-#ifdef DEBUG_MODULE_TRACE
-	printk(KERN_DEBUG "-> init_module()\n");
-#endif
-
-	/* If probing is asked */
-	if (io[0] == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-		printk(KERN_WARNING
-		       "WaveLAN init_module(): doing device probing (bad !)\n");
-		printk(KERN_WARNING
-		       "Specify base addresses while loading module to correct the problem\n");
-#endif
-
-		/* Copy the basic set of address to be probed. */
-		for (i = 0; i < ARRAY_SIZE(iobase); i++)
-			io[i] = iobase[i];
-	}
-
-
-	/* Loop on all possible base addresses. */
-	for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) {
-		struct net_device *dev = alloc_etherdev(sizeof(net_local));
-		if (!dev)
-			break;
-		if (name[i])
-			strcpy(dev->name, name[i]);	/* Copy name */
-		dev->base_addr = io[i];
-		dev->irq = irq[i];
-
-		/* Check if there is something at this base address. */
-		if (wavelan_config(dev, io[i]) == 0) {
-			if (register_netdev(dev) != 0) {
-				release_region(dev->base_addr, sizeof(ha_t));
-				wavelan_list = wavelan_list->next;
-			} else {
-				ret = 0;
-				continue;
-			}
-		}
-		free_netdev(dev);
-	}
-
-#ifdef DEBUG_CONFIG_ERROR
-	if (!wavelan_list)
-		printk(KERN_WARNING
-		       "WaveLAN init_module(): no device found\n");
-#endif
-
-#ifdef DEBUG_MODULE_TRACE
-	printk(KERN_DEBUG "<- init_module()\n");
-#endif
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Removal of the module
- */
-void cleanup_module(void)
-{
-#ifdef DEBUG_MODULE_TRACE
-	printk(KERN_DEBUG "-> cleanup_module()\n");
-#endif
-
-	/* Loop on all devices and release them. */
-	while (wavelan_list) {
-		struct net_device *dev = wavelan_list->dev;
-
-#ifdef DEBUG_CONFIG_INFO
-		printk(KERN_DEBUG
-		       "%s: cleanup_module(): removing device at 0x%x\n",
-		       dev->name, (unsigned int) dev);
-#endif
-		unregister_netdev(dev);
-
-		release_region(dev->base_addr, sizeof(ha_t));
-		wavelan_list = wavelan_list->next;
-
-		free_netdev(dev);
-	}
-
-#ifdef DEBUG_MODULE_TRACE
-	printk(KERN_DEBUG "<- cleanup_module()\n");
-#endif
-}
-#endif				/* MODULE */
-MODULE_LICENSE("GPL");
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * This software was developed as a component of the
- * Linux operating system.
- * It is based on other device drivers and information
- * either written or supplied by:
- *	Ajay Bakre (bakre@paul.rutgers.edu),
- *	Donald Becker (becker@scyld.com),
- *	Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com),
- *	Anders Klemets (klemets@it.kth.se),
- *	Vladimir V. Kolpakov (w@stier.koenig.ru),
- *	Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
- *	Pauline Middelink (middelin@polyware.iaf.nl),
- *	Robert Morris (rtm@das.harvard.edu),
- *	Jean Tourrilhes (jt@hplb.hpl.hp.com),
- *	Girish Welling (welling@paul.rutgers.edu),
- *
- * Thanks go also to:
- *	James Ashton (jaa101@syseng.anu.edu.au),
- *	Alan Cox (alan@lxorguk.ukuu.org.uk),
- *	Allan Creighton (allanc@cs.usyd.edu.au),
- *	Matthew Geier (matthew@cs.usyd.edu.au),
- *	Remo di Giovanni (remo@cs.usyd.edu.au),
- *	Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
- *	Vipul Gupta (vgupta@cs.binghamton.edu),
- *	Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- *	Tim Nicholson (tim@cs.usyd.edu.au),
- *	Ian Parkin (ian@cs.usyd.edu.au),
- *	John Rosenberg (johnr@cs.usyd.edu.au),
- *	George Rossi (george@phm.gov.au),
- *	Arthur Scott (arthur@cs.usyd.edu.au),
- *	Peter Storey,
- * for their assistance and advice.
- *
- * Please send bug reports, updates, comments to:
- *
- * Bruce Janson                                    Email:  bruce@cs.usyd.edu.au
- * Basser Department of Computer Science           Phone:  +61-2-9351-3423
- * University of Sydney, N.S.W., 2006, AUSTRALIA   Fax:    +61-2-9351-3838
- */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4635 +0,0 @@
-/*
- *	Wavelan Pcmcia driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follow. See wavelan_cs.p.h for details.
- *
- * This code is derived from Anthony D. Joseph's code and all the changes here
- * are also under the original copyright below.
- *
- * This code supports version 2.00 of WaveLAN/PCMCIA cards (2.4GHz), and
- * can work on Linux 2.0.36 with support of David Hinds' PCMCIA Card Services
- *
- * Joe Finney (joe@comp.lancs.ac.uk) at Lancaster University in UK added
- * critical code in the routine to initialize the Modem Management Controller.
- *
- * Thanks to Alan Cox and Bruce Janson for their advice.
- *
- *	-- Yunzhou Li (scip4166@nus.sg)
- *
-#ifdef WAVELAN_ROAMING	
- * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu)
- * based on patch by Joe Finney from Lancaster University.
-#endif
- *
- * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An
- * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor.
- *
- *   A non-shared memory PCMCIA ethernet driver for linux
- *
- * ISA version modified to support PCMCIA by Anthony Joseph (adj@lcs.mit.edu)
- *
- *
- * Joseph O'Sullivan & John Langford (josullvn@cs.cmu.edu & jcl@cs.cmu.edu)
- *
- * Apr 2 '98  made changes to bring the i82593 control/int handling in line
- *             with offical specs...
- *
- ****************************************************************************
- *   Copyright 1995
- *   Anthony D. Joseph
- *   Massachusetts Institute of Technology
- *
- *   Permission to use, copy, modify, and distribute this program
- *   for any purpose and without fee is hereby granted, provided
- *   that this copyright and permission notice appear on all copies
- *   and supporting documentation, the name of M.I.T. not be used
- *   in advertising or publicity pertaining to distribution of the
- *   program without specific prior permission, and notice be given
- *   in supporting documentation that copying and distribution is
- *   by permission of M.I.T.  M.I.T. makes no representations about
- *   the suitability of this software for any purpose.  It is pro-
- *   vided "as is" without express or implied warranty.         
- ****************************************************************************
- *
- */
-
-/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
-#include "wavelan_cs.p.h"		/* Private header */
-
-#ifdef WAVELAN_ROAMING
-static void wl_cell_expiry(unsigned long data);
-static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
-static void wv_nwid_filter(unsigned char mode, net_local *lp);
-#endif  /*  WAVELAN_ROAMING  */
-
-/************************* MISC SUBROUTINES **************************/
-/*
- * Subroutines which won't fit in one of the following category
- * (wavelan modem or i82593)
- */
-
-/******************* MODEM MANAGEMENT SUBROUTINES *******************/
-/*
- * Useful subroutines to manage the modem of the wavelan
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read from card's Host Adaptor Status Register.
- */
-static inline u_char
-hasr_read(u_long	base)
-{
-  return(inb(HASR(base)));
-} /* hasr_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register.
- */
-static inline void
-hacr_write(u_long	base,
-	   u_char	hacr)
-{
-  outb(hacr, HACR(base));
-} /* hacr_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register. Include a delay for
- * those times when it is needed.
- */
-static void
-hacr_write_slow(u_long	base,
-		u_char	hacr)
-{
-  hacr_write(base, hacr);
-  /* delay might only be needed sometimes */
-  mdelay(1);
-} /* hacr_write_slow */
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Parameter Storage Area from the WaveLAN card's memory
- */
-static void
-psa_read(struct net_device *	dev,
-	 int		o,	/* offset in PSA */
-	 u_char *	b,	/* buffer to fill */
-	 int		n)	/* size to read */
-{
-  net_local *lp = netdev_priv(dev);
-  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
-
-  while(n-- > 0)
-    {
-      *b++ = readb(ptr);
-      /* Due to a lack of address decode pins, the WaveLAN PCMCIA card
-       * only supports reading even memory addresses. That means the
-       * increment here MUST be two.
-       * Because of that, we can't use memcpy_fromio()...
-       */
-      ptr += 2;
-    }
-} /* psa_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write the Parameter Storage Area to the WaveLAN card's memory
- */
-static void
-psa_write(struct net_device *	dev,
-	  int		o,	/* Offset in psa */
-	  u_char *	b,	/* Buffer in memory */
-	  int		n)	/* Length of buffer */
-{
-  net_local *lp = netdev_priv(dev);
-  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
-  int		count = 0;
-  unsigned int	base = dev->base_addr;
-  /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
-   * oblige to verify this address to know when the PSA is ready... */
-  volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
-    (psaoff(0, psa_comp_number) << 1);
-
-  /* Authorize writing to PSA */
-  hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
-
-  while(n-- > 0)
-    {
-      /* write to PSA */
-      writeb(*b++, ptr);
-      ptr += 2;
-
-      /* I don't have the spec, so I don't know what the correct
-       * sequence to write is. This hack seem to work for me... */
-      count = 0;
-      while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100))
-	mdelay(1);
-    }
-
-  /* Put the host interface back in standard state */
-  hacr_write(base, HACR_DEFAULT);
-} /* psa_write */
-
-#ifdef SET_PSA_CRC
-/*------------------------------------------------------------------*/
-/*
- * Calculate the PSA CRC
- * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
- * NOTE: By specifying a length including the CRC position the
- * returned value should be zero. (i.e. a correct checksum in the PSA)
- *
- * The Windows drivers don't use the CRC, but the AP and the PtP tool
- * depend on it.
- */
-static u_short
-psa_crc(unsigned char *	psa,	/* The PSA */
-	int		size)	/* Number of short for CRC */
-{
-  int		byte_cnt;	/* Loop on the PSA */
-  u_short	crc_bytes = 0;	/* Data in the PSA */
-  int		bit_cnt;	/* Loop on the bits of the short */
-
-  for(byte_cnt = 0; byte_cnt < size; byte_cnt++ )
-    {
-      crc_bytes ^= psa[byte_cnt];	/* Its an xor */
-
-      for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ )
-	{
-	  if(crc_bytes & 0x0001)
-	    crc_bytes = (crc_bytes >> 1) ^ 0xA001;
-	  else
-	    crc_bytes >>= 1 ;
-        }
-    }
-
-  return crc_bytes;
-} /* psa_crc */
-#endif	/* SET_PSA_CRC */
-
-/*------------------------------------------------------------------*/
-/*
- * update the checksum field in the Wavelan's PSA
- */
-static void
-update_psa_checksum(struct net_device *	dev)
-{
-#ifdef SET_PSA_CRC
-  psa_t		psa;
-  u_short	crc;
-
-  /* read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-  /* update the checksum */
-  crc = psa_crc((unsigned char *) &psa,
-		sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1])
-		- sizeof(psa.psa_crc_status));
-
-  psa.psa_crc[0] = crc & 0xFF;
-  psa.psa_crc[1] = (crc & 0xFF00) >> 8;
-
-  /* Write it ! */
-  psa_write(dev, (char *)&psa.psa_crc - (char *)&psa,
-	    (unsigned char *)&psa.psa_crc, 2);
-
-#ifdef DEBUG_IOCTL_INFO
-  printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
-          dev->name, psa.psa_crc[0], psa.psa_crc[1]);
-
-  /* Check again (luxury !) */
-  crc = psa_crc((unsigned char *) &psa,
-		 sizeof(psa) - sizeof(psa.psa_crc_status));
-
-  if(crc != 0)
-    printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name);
-#endif /* DEBUG_IOCTL_INFO */
-#endif	/* SET_PSA_CRC */
-} /* update_psa_checksum */
-
-/*------------------------------------------------------------------*/
-/*
- * Write 1 byte to the MMC.
- */
-static void
-mmc_out(u_long		base,
-	u_short		o,
-	u_char		d)
-{
-  int count = 0;
-
-  /* Wait for MMC to go idle */
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-
-  outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base));
-  outb(d, MMD(base));
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to write bytes to the Modem Management Controller.
- * We start by the end because it is the way it should be !
- */
-static void
-mmc_write(u_long	base,
-	  u_char	o,
-	  u_char *	b,
-	  int		n)
-{
-  o += n;
-  b += n;
-
-  while(n-- > 0 )
-    mmc_out(base, --o, *(--b));
-} /* mmc_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Read 1 byte from the MMC.
- * Optimised version for 1 byte, avoid using memory...
- */
-static u_char
-mmc_in(u_long	base,
-       u_short	o)
-{
-  int count = 0;
-
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-  outb(o << 1, MMR(base));		/* Set the read address */
-
-  outb(0, MMD(base));			/* Required dummy write */
-
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-  return (u_char) (inb(MMD(base)));	/* Now do the actual read */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read bytes from the Modem Management Controller.
- * The implementation is complicated by a lack of address lines,
- * which prevents decoding of the low-order bit.
- * (code has just been moved in the above function)
- * We start by the end because it is the way it should be !
- */
-static void
-mmc_read(u_long		base,
-	 u_char		o,
-	 u_char *	b,
-	 int		n)
-{
-  o += n;
-  b += n;
-
-  while(n-- > 0)
-    *(--b) = mmc_in(base, --o);
-} /* mmc_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Get the type of encryption available...
- */
-static inline int
-mmc_encr(u_long		base)	/* i/o port of the card */
-{
-  int	temp;
-
-  temp = mmc_in(base, mmroff(0, mmr_des_avail));
-  if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
-    return 0;
-  else
-    return temp;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wait for the frequency EEprom to complete a command...
- */
-static void
-fee_wait(u_long		base,	/* i/o port of the card */
-	 int		delay,	/* Base delay to wait for */
-	 int		number)	/* Number of time to wait */
-{
-  int		count = 0;	/* Wait only a limited time */
-
-  while((count++ < number) &&
-	(mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY))
-    udelay(delay);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the Frequency EEprom (frequency select cards).
- */
-static void
-fee_read(u_long		base,	/* i/o port of the card */
-	 u_short	o,	/* destination offset */
-	 u_short *	b,	/* data buffer */
-	 int		n)	/* number of registers */
-{
-  b += n;		/* Position at the end of the area */
-
-  /* Write the address */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-  /* Loop on all buffer */
-  while(n-- > 0)
-    {
-      /* Write the read command */
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
-
-      /* Wait until EEprom is ready (should be quick !) */
-      fee_wait(base, 10, 100);
-
-      /* Read the value */
-      *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) |
-	      mmc_in(base, mmroff(0, mmr_fee_data_l)));
-    }
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes from the Frequency EEprom (frequency select cards).
- * This is a bit complicated, because the frequency eeprom has to
- * be unprotected and the write enabled.
- * Jean II
- */
-static void
-fee_write(u_long	base,	/* i/o port of the card */
-	  u_short	o,	/* destination offset */
-	  u_short *	b,	/* data buffer */
-	  int		n)	/* number of registers */
-{
-  b += n;		/* Position at the end of the area */
-
-#ifdef EEPROM_IS_PROTECTED	/* disabled */
-#ifdef DOESNT_SEEM_TO_WORK	/* disabled */
-  /* Ask to read the protected register */
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
-
-  fee_wait(base, 10, 100);
-
-  /* Read the protected register */
-  printk("Protected 2 : %02X-%02X\n",
-	 mmc_in(base, mmroff(0, mmr_fee_data_h)),
-	 mmc_in(base, mmroff(0, mmr_fee_data_l)));
-#endif	/* DOESNT_SEEM_TO_WORK */
-
-  /* Enable protected register */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
-
-  fee_wait(base, 10, 100);
-
-  /* Unprotect area */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-#ifdef DOESNT_SEEM_TO_WORK	/* disabled */
-  /* Or use : */
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
-#endif	/* DOESNT_SEEM_TO_WORK */
-
-  fee_wait(base, 10, 100);
-#endif	/* EEPROM_IS_PROTECTED */
-
-  /* Write enable */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
-
-  fee_wait(base, 10, 100);
-
-  /* Write the EEprom address */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-  /* Loop on all buffer */
-  while(n-- > 0)
-    {
-      /* Write the value */
-      mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
-      mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
-
-      /* Write the write command */
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
-
-      /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */
-      mdelay(10);
-      fee_wait(base, 10, 100);
-    }
-
-  /* Write disable */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
-
-  fee_wait(base, 10, 100);
-
-#ifdef EEPROM_IS_PROTECTED	/* disabled */
-  /* Reprotect EEprom */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-
-  fee_wait(base, 10, 100);
-#endif	/* EEPROM_IS_PROTECTED */
-}
-
-/******************* WaveLAN Roaming routines... ********************/
-
-#ifdef WAVELAN_ROAMING	/* Conditional compile, see wavelan_cs.h */
-
-static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
-  
-static void wv_roam_init(struct net_device *dev)
-{
-  net_local  *lp= netdev_priv(dev);
-
-  /* Do not remove this unless you have a good reason */
-  printk(KERN_NOTICE "%s: Warning, you have enabled roaming on"
-	 " device %s !\n", dev->name, dev->name);
-  printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature"
-	 " of the Wavelan driver.\n");
-  printk(KERN_NOTICE "It may work, but may also make the driver behave in"
-	 " erratic ways or crash.\n");
-
-  lp->wavepoint_table.head=NULL;           /* Initialise WavePoint table */
-  lp->wavepoint_table.num_wavepoints=0;
-  lp->wavepoint_table.locked=0;
-  lp->curr_point=NULL;                        /* No default WavePoint */
-  lp->cell_search=0;
-  
-  lp->cell_timer.data=(long)lp;               /* Start cell expiry timer */
-  lp->cell_timer.function=wl_cell_expiry;
-  lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
-  add_timer(&lp->cell_timer);
-  
-  wv_nwid_filter(NWID_PROMISC,lp) ;    /* Enter NWID promiscuous mode */
-  /* to build up a good WavePoint */
-                                           /* table... */
-  printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
-}
- 
-static void wv_roam_cleanup(struct net_device *dev)
-{
-  wavepoint_history *ptr,*old_ptr;
-  net_local *lp= netdev_priv(dev);
-  
-  printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %s\n",dev->name);
-  
-  /* Fixme : maybe we should check that the timer exist before deleting it */
-  del_timer(&lp->cell_timer);          /* Remove cell expiry timer       */
-  ptr=lp->wavepoint_table.head;        /* Clear device's WavePoint table */
-  while(ptr!=NULL)
-    {
-      old_ptr=ptr;
-      ptr=ptr->next;	
-      wl_del_wavepoint(old_ptr,lp);	
-    }
-}
-
-/* Enable/Disable NWID promiscuous mode on a given device */
-static void wv_nwid_filter(unsigned char mode, net_local *lp)
-{
-  mm_t                  m;
-  unsigned long         flags;
-  
-#ifdef WAVELAN_ROAMING_DEBUG
-  printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %s\n",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name);
-#endif
-  
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-  
-  m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
-  mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
-  
-  if(mode==NWID_PROMISC)
-    lp->cell_search=1;
-  else
-    lp->cell_search=0;
-
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-}
-
-/* Find a record in the WavePoint table matching a given NWID */
-static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
-{
-  wavepoint_history	*ptr=lp->wavepoint_table.head;
-  
-  while(ptr!=NULL){
-    if(ptr->nwid==nwid)
-      return ptr;	
-    ptr=ptr->next;
-  }
-  return NULL;
-}
-
-/* Create a new wavepoint table entry */
-static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
-{
-  wavepoint_history *new_wavepoint;
-
-#ifdef WAVELAN_ROAMING_DEBUG	
-  printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4X\n",nwid);
-#endif
-  
-  if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
-    return NULL;
-  
-  new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
-  if(new_wavepoint==NULL)
-    return NULL;
-  
-  new_wavepoint->nwid=nwid;                       /* New WavePoints NWID */
-  new_wavepoint->average_fast=0;                    /* Running Averages..*/
-  new_wavepoint->average_slow=0;
-  new_wavepoint->qualptr=0;                       /* Start of ringbuffer */
-  new_wavepoint->last_seq=seq-1;                /* Last sequence no.seen */
-  memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);/* Empty ringbuffer */
-  
-  new_wavepoint->next=lp->wavepoint_table.head;/* Add to wavepoint table */
-  new_wavepoint->prev=NULL;
-  
-  if(lp->wavepoint_table.head!=NULL)
-    lp->wavepoint_table.head->prev=new_wavepoint;
-  
-  lp->wavepoint_table.head=new_wavepoint;
-  
-  lp->wavepoint_table.num_wavepoints++;     /* no. of visible wavepoints */
-  
-  return new_wavepoint;
-}
-
-/* Remove a wavepoint entry from WavePoint table */
-static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
-{
-  if(wavepoint==NULL)
-    return;
-  
-  if(lp->curr_point==wavepoint)
-    lp->curr_point=NULL;
-  
-  if(wavepoint->prev!=NULL)
-    wavepoint->prev->next=wavepoint->next;
-  
-  if(wavepoint->next!=NULL)
-    wavepoint->next->prev=wavepoint->prev;
-  
-  if(lp->wavepoint_table.head==wavepoint)
-    lp->wavepoint_table.head=wavepoint->next;
-  
-  lp->wavepoint_table.num_wavepoints--;
-  kfree(wavepoint);
-}
-
-/* Timer callback function - checks WavePoint table for stale entries */ 
-static void wl_cell_expiry(unsigned long data)
-{
-  net_local *lp=(net_local *)data;
-  wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
-  
-#if WAVELAN_ROAMING_DEBUG > 1
-  printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %s\n",lp->dev->name);
-#endif
-  
-  if(lp->wavepoint_table.locked)
-    {
-#if WAVELAN_ROAMING_DEBUG > 1
-      printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...\n");
-#endif
-      
-      lp->cell_timer.expires=jiffies+1; /* If table in use, come back later */
-      add_timer(&lp->cell_timer);
-      return;
-    }
-  
-  while(wavepoint!=NULL)
-    {
-      if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT))
-	{
-#ifdef WAVELAN_ROAMING_DEBUG
-	  printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid);
-#endif
-	  
-	  old_point=wavepoint;
-	  wavepoint=wavepoint->next;
-	  wl_del_wavepoint(old_point,lp);
-	}
-      else
-	wavepoint=wavepoint->next;
-    }
-  lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
-  add_timer(&lp->cell_timer);
-}
-
-/* Update SNR history of a wavepoint */
-static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)	
-{
-  int i=0,num_missed=0,ptr=0;
-  int average_fast=0,average_slow=0;
-  
-  num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;/* Have we missed
-							    any beacons? */
-  if(num_missed)
-    for(i=0;i<num_missed;i++)
-      {
-	wavepoint->sigqual[wavepoint->qualptr++]=0; /* If so, enter them as 0's */
-	wavepoint->qualptr %=WAVEPOINT_HISTORY;    /* in the ringbuffer. */
-      }
-  wavepoint->last_seen=jiffies;                 /* Add beacon to history */
-  wavepoint->last_seq=seq;	
-  wavepoint->sigqual[wavepoint->qualptr++]=sigqual;          
-  wavepoint->qualptr %=WAVEPOINT_HISTORY;
-  ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY;
-  
-  for(i=0;i<WAVEPOINT_FAST_HISTORY;i++)       /* Update running averages */
-    {
-      average_fast+=wavepoint->sigqual[ptr++];
-      ptr %=WAVEPOINT_HISTORY;
-    }
-  
-  average_slow=average_fast;
-  for(i=WAVEPOINT_FAST_HISTORY;i<WAVEPOINT_HISTORY;i++)
-    {
-      average_slow+=wavepoint->sigqual[ptr++];
-      ptr %=WAVEPOINT_HISTORY;
-    }
-  
-  wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY;
-  wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY;	
-}
-
-/* Perform a handover to a new WavePoint */
-static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
-{
-  unsigned int		base = lp->dev->base_addr;
-  mm_t                  m;
-  unsigned long         flags;
-
-  if(wavepoint==lp->curr_point)          /* Sanity check... */
-    {
-      wv_nwid_filter(!NWID_PROMISC,lp);
-      return;
-    }
-  
-#ifdef WAVELAN_ROAMING_DEBUG
-  printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %s\n",wavepoint->nwid,lp->dev->name);
-#endif
- 	
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
-  m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
-  
-  mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
-  
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  wv_nwid_filter(!NWID_PROMISC,lp);
-  lp->curr_point=wavepoint;
-}
-
-/* Called when a WavePoint beacon is received */
-static void wl_roam_gather(struct net_device *  dev,
-			   u_char *  hdr,   /* Beacon header */
-			   u_char *  stats) /* SNR, Signal quality
-						      of packet */
-{
-  wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */
-  unsigned short nwid=ntohs(beacon->nwid);  
-  unsigned short sigqual=stats[2] & MMR_SGNL_QUAL;   /* SNR of beacon */
-  wavepoint_history *wavepoint=NULL;                /* WavePoint table entry */
-  net_local *lp = netdev_priv(dev);              /* Device info */
-
-#ifdef I_NEED_THIS_FEATURE
-  /* Some people don't need this, some other may need it */
-  nwid=nwid^ntohs(beacon->domain_id);
-#endif
-
-#if WAVELAN_ROAMING_DEBUG > 1
-  printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name);
-  printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual);
-#endif
-  
-  lp->wavepoint_table.locked=1;                            /* <Mutex> */
-  
-  wavepoint=wl_roam_check(nwid,lp);            /* Find WavePoint table entry */
-  if(wavepoint==NULL)                    /* If no entry, Create a new one... */
-    {
-      wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp);
-      if(wavepoint==NULL)
-	goto out;
-    }
-  if(lp->curr_point==NULL)             /* If this is the only WavePoint, */
-    wv_roam_handover(wavepoint, lp);	         /* Jump on it! */
-  
-  wl_update_history(wavepoint, sigqual, beacon->seq); /* Update SNR history
-							 stats. */
-  
-  if(lp->curr_point->average_slow < SEARCH_THRESH_LOW) /* If our current */
-    if(!lp->cell_search)                  /* WavePoint is getting faint, */
-      wv_nwid_filter(NWID_PROMISC,lp);    /* start looking for a new one */
-  
-  if(wavepoint->average_slow > 
-     lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA)
-    wv_roam_handover(wavepoint, lp);   /* Handover to a better WavePoint */
-  
-  if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH) /* If our SNR is */
-    if(lp->cell_search)  /* getting better, drop out of cell search mode */
-      wv_nwid_filter(!NWID_PROMISC,lp);
-  
-out:
-  lp->wavepoint_table.locked=0;                        /* </MUTEX>   :-) */
-}
-
-/* Test this MAC frame a WavePoint beacon */
-static inline int WAVELAN_BEACON(unsigned char *data)
-{
-  wavepoint_beacon *beacon= (wavepoint_beacon *)data;
-  static const wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00};
-  
-  if(memcmp(beacon,&beacon_template,9)==0)
-    return 1;
-  else
-    return 0;
-}
-#endif	/* WAVELAN_ROAMING */
-
-/************************ I82593 SUBROUTINES *************************/
-/*
- * Useful subroutines to manage the Ethernet controller
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to synchronously send a command to the i82593 chip. 
- * Should be called with interrupts disabled.
- * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(),
- *  wv_82593_config() & wv_diag())
- */
-static int
-wv_82593_cmd(struct net_device *	dev,
-	     char *	str,
-	     int	cmd,
-	     int	result)
-{
-  unsigned int	base = dev->base_addr;
-  int		status;
-  int		wait_completed;
-  long		spin;
-
-  /* Spin until the chip finishes executing its current command (if any) */
-  spin = 1000;
-  do
-    {
-      /* Time calibration of the loop */
-      udelay(10);
-
-      /* Read the interrupt register */
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
-
-  /* If the interrupt hasn't been posted */
-  if (spin < 0) {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
-	     str, status);
-#endif
-      return(FALSE);
-    }
-
-  /* Issue the command to the controller */
-  outb(cmd, LCCR(base));
-
-  /* If we don't have to check the result of the command
-   * Note : this mean that the irq handler will deal with that */
-  if(result == SR0_NO_RESULT)
-    return(TRUE);
-
-  /* We are waiting for command completion */
-  wait_completed = TRUE;
-
-  /* Busy wait while the LAN controller executes the command. */
-  spin = 1000;
-  do
-    {
-      /* Time calibration of the loop */
-      udelay(10);
-
-      /* Read the interrupt register */
-      outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
-      status = inb(LCSR(base));
-
-      /* Check if there was an interrupt posted */
-      if((status & SR0_INTERRUPT))
-	{
-	  /* Acknowledge the interrupt */
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-
-	  /* Check if interrupt is a command completion */
-	  if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) &&
-	     ((status & SR0_BOTH_RX_TX) != 0x0) &&
-	     !(status & SR0_RECEPTION))
-	    {
-	      /* Signal command completion */
-	      wait_completed = FALSE;
-	    }
-	  else
-	    {
-	      /* Note : Rx interrupts will be handled later, because we can
-	       * handle multiple Rx packets at once */
-#ifdef DEBUG_INTERRUPT_INFO
-	      printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");
-#endif
-	    }
-	}
-    }
-  while(wait_completed && (spin-- > 0));
-
-  /* If the interrupt hasn't be posted */
-  if(wait_completed)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n",
-	     str, status);
-#endif
-      return(FALSE);
-    }
-
-  /* Check the return code returned by the card (see above) against
-   * the expected return code provided by the caller */
-  if((status & SR0_EVENT_MASK) != result)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n",
-	     str, status);
-#endif
-      return(FALSE);
-    }
-
-  return(TRUE);
-} /* wv_82593_cmd */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a 593 op-code number 7, and obtains the diagnose
- * status for the WaveLAN.
- */
-static inline int
-wv_diag(struct net_device *	dev)
-{
-  return(wv_82593_cmd(dev, "wv_diag(): diagnose",
-		      OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED));
-} /* wv_diag */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read len bytes from the i82593's ring buffer, starting at
- * chip address addr. The results read from the chip are stored in buf.
- * The return value is the address to use for next the call.
- */
-static int
-read_ringbuf(struct net_device *	dev,
-	     int	addr,
-	     char *	buf,
-	     int	len)
-{
-  unsigned int	base = dev->base_addr;
-  int		ring_ptr = addr;
-  int		chunk_len;
-  char *	buf_ptr = buf;
-
-  /* Get all the buffer */
-  while(len > 0)
-    {
-      /* Position the Program I/O Register at the ring buffer pointer */
-      outb(ring_ptr & 0xff, PIORL(base));
-      outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base));
-
-      /* First, determine how much we can read without wrapping around the
-	 ring buffer */
-      if((addr + len) < (RX_BASE + RX_SIZE))
-	chunk_len = len;
-      else
-	chunk_len = RX_BASE + RX_SIZE - addr;
-      insb(PIOP(base), buf_ptr, chunk_len);
-      buf_ptr += chunk_len;
-      len -= chunk_len;
-      ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE;
-    }
-  return(ring_ptr);
-} /* read_ringbuf */
-
-/*------------------------------------------------------------------*/
-/*
- * Reconfigure the i82593, or at least ask for it...
- * Because wv_82593_config use the transmission buffer, we must do it
- * when we are sure that there is no transmission, so we do it now
- * or in wavelan_packet_xmit() (I can't find any better place,
- * wavelan_interrupt is not an option...), so you may experience
- * some delay sometime...
- */
-static void
-wv_82593_reconfig(struct net_device *	dev)
-{
-  net_local *		lp = netdev_priv(dev);
-  struct pcmcia_device *		link = lp->link;
-  unsigned long		flags;
-
-  /* Arm the flag, will be cleard in wv_82593_config() */
-  lp->reconfig_82593 = TRUE;
-
-  /* Check if we can do it now ! */
-  if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
-    {
-      spin_lock_irqsave(&lp->spinlock, flags);	/* Disable interrupts */
-      wv_82593_config(dev);
-      spin_unlock_irqrestore(&lp->spinlock, flags);	/* Re-enable interrupts */
-    }
-  else
-    {
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG
-	     "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n",
-	     dev->name, dev->state, link->open);
-#endif
-    }
-}
-
-/********************* DEBUG & INFO SUBROUTINES *********************/
-/*
- * This routines are used in the code to show debug informations.
- * Most of the time, it dump the content of hardware structures...
- */
-
-#ifdef DEBUG_PSA_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted contents of the Parameter Storage Area.
- */
-static void
-wv_psa_show(psa_t *	p)
-{
-  printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
-  printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
-	 p->psa_io_base_addr_1,
-	 p->psa_io_base_addr_2,
-	 p->psa_io_base_addr_3,
-	 p->psa_io_base_addr_4);
-  printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
-	 p->psa_rem_boot_addr_1,
-	 p->psa_rem_boot_addr_2,
-	 p->psa_rem_boot_addr_3);
-  printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
-  printk("psa_int_req_no: %d\n", p->psa_int_req_no);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
-#endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
-  printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
-  printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
-  printk("psa_comp_number: %d, ", p->psa_comp_number);
-  printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
-  printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
-	 p->psa_feature_select);
-  printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
-  printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
-  printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
-  printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]);
-  printk("psa_nwid_select: %d\n", p->psa_nwid_select);
-  printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select);
-  printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-	 p->psa_encryption_key[0],
-	 p->psa_encryption_key[1],
-	 p->psa_encryption_key[2],
-	 p->psa_encryption_key[3],
-	 p->psa_encryption_key[4],
-	 p->psa_encryption_key[5],
-	 p->psa_encryption_key[6],
-	 p->psa_encryption_key[7]);
-  printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
-  printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
-	 p->psa_call_code[0]);
-  printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-	 p->psa_call_code[0],
-	 p->psa_call_code[1],
-	 p->psa_call_code[2],
-	 p->psa_call_code[3],
-	 p->psa_call_code[4],
-	 p->psa_call_code[5],
-	 p->psa_call_code[6],
-	 p->psa_call_code[7]);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
-	 p->psa_reserved[0],
-	 p->psa_reserved[1]);
-#endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
-  printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
-  printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
-} /* wv_psa_show */
-#endif	/* DEBUG_PSA_SHOW */
-
-#ifdef DEBUG_MMC_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the Modem Management Controller.
- * This function need to be completed...
- */
-static void
-wv_mmc_show(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  net_local *	lp = netdev_priv(dev);
-  mmr_t		m;
-
-  /* Basic check */
-  if(hasr_read(base) & HASR_NO_CLK)
-    {
-      printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n",
-	     dev->name);
-      return;
-    }
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Read the mmc */
-  mmc_out(base, mmwoff(0, mmw_freeze), 1);
-  mmc_read(base, 0, (u_char *)&m, sizeof(m));
-  mmc_out(base, mmwoff(0, mmw_freeze), 0);
-
-  /* Don't forget to update statistics */
-  lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-	 m.mmr_unused0[0],
-	 m.mmr_unused0[1],
-	 m.mmr_unused0[2],
-	 m.mmr_unused0[3],
-	 m.mmr_unused0[4],
-	 m.mmr_unused0[5],
-	 m.mmr_unused0[6],
-	 m.mmr_unused0[7]);
-#endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
-	 m.mmr_des_avail, m.mmr_des_status);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
-	 m.mmr_unused1[0],
-	 m.mmr_unused1[1],
-	 m.mmr_unused1[2],
-	 m.mmr_unused1[3],
-	 m.mmr_unused1[4]);
-#endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
-	 m.mmr_dce_status,
-	 (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"",
-	 (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
-	 "loop test indicated," : "",
-	 (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "",
-	 (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
-	 "jabber timer expired," : "");
-  printk(KERN_DEBUG "Dsp ID: %02X\n",
-	 m.mmr_dsp_id);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
-	 m.mmr_unused2[0],
-	 m.mmr_unused2[1]);
-#endif	/* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
-	 (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
-	 (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
-  printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
-	 m.mmr_thr_pre_set & MMR_THR_PRE_SET,
-	 (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below");
-  printk(KERN_DEBUG "signal_lvl: %d [%s], ",
-	 m.mmr_signal_lvl & MMR_SIGNAL_LVL,
-	 (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg");
-  printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL,
-	 (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update");
-  printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
-	 (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
-#endif	/* DEBUG_SHOW_UNUSED */
-} /* wv_mmc_show */
-#endif	/* DEBUG_MMC_SHOW */
-
-#ifdef DEBUG_I82593_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the i82593's receive unit.
- */
-static void
-wv_ru_show(struct net_device *	dev)
-{
-  net_local *lp = netdev_priv(dev);
-
-  printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n");
-  printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop);
-  /*
-   * Not implemented yet...
-   */
-  printk("\n");
-} /* wv_ru_show */
-#endif	/* DEBUG_I82593_SHOW */
-
-#ifdef DEBUG_DEVICE_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver.
- */
-static void
-wv_dev_show(struct net_device *	dev)
-{
-  printk(KERN_DEBUG "dev:");
-  printk(" state=%lX,", dev->state);
-  printk(" trans_start=%ld,", dev->trans_start);
-  printk(" flags=0x%x,", dev->flags);
-  printk("\n");
-} /* wv_dev_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver's
- * private information.
- */
-static void
-wv_local_show(struct net_device *	dev)
-{
-  net_local *lp = netdev_priv(dev);
-
-  printk(KERN_DEBUG "local:");
-  /*
-   * Not implemented yet...
-   */
-  printk("\n");
-} /* wv_local_show */
-#endif	/* DEBUG_DEVICE_SHOW */
-
-#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
-/*------------------------------------------------------------------*/
-/*
- * Dump packet header (and content if necessary) on the screen
- */
-static void
-wv_packet_info(u_char *		p,		/* Packet to dump */
-	       int		length,		/* Length of the packet */
-	       char *		msg1,		/* Name of the device */
-	       char *		msg2)		/* Name of the function */
-{
-  int		i;
-  int		maxi;
-
-  printk(KERN_DEBUG "%s: %s(): dest %pM, length %d\n",
-	 msg1, msg2, p, length);
-  printk(KERN_DEBUG "%s: %s(): src %pM, type 0x%02X%02X\n",
-	 msg1, msg2, &p[6], p[12], p[13]);
-
-#ifdef DEBUG_PACKET_DUMP
-
-  printk(KERN_DEBUG "data=\"");
-
-  if((maxi = length) > DEBUG_PACKET_DUMP)
-    maxi = DEBUG_PACKET_DUMP;
-  for(i = 14; i < maxi; i++)
-    if(p[i] >= ' ' && p[i] <= '~')
-      printk(" %c", p[i]);
-    else
-      printk("%02X", p[i]);
-  if(maxi < length)
-    printk("..");
-  printk("\"\n");
-  printk(KERN_DEBUG "\n");
-#endif	/* DEBUG_PACKET_DUMP */
-}
-#endif	/* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
-
-/*------------------------------------------------------------------*/
-/*
- * This is the information which is displayed by the driver at startup
- * There  is a lot of flag to configure it at your will...
- */
-static void
-wv_init_info(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  psa_t		psa;
-
-  /* Read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef DEBUG_PSA_SHOW
-  wv_psa_show(&psa);
-#endif
-#ifdef DEBUG_MMC_SHOW
-  wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82593_SHOW
-  wv_ru_show(dev);
-#endif
-
-#ifdef DEBUG_BASIC_SHOW
-  /* Now, let's go for the basic stuff */
-  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr %pM",
-	 dev->name, base, dev->irq, dev->dev_addr);
-
-  /* Print current network id */
-  if(psa.psa_nwid_select)
-    printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);
-  else
-    printk(", nwid off");
-
-  /* If 2.00 card */
-  if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-    {
-      unsigned short	freq;
-
-      /* Ask the EEprom to read the frequency from the first area */
-      fee_read(base, 0x00 /* 1st area - frequency... */,
-	       &freq, 1);
-
-      /* Print frequency */
-      printk(", 2.00, %ld", (freq >> 6) + 2400L);
-
-      /* Hack !!! */
-      if(freq & 0x20)
-	printk(".5");
-    }
-  else
-    {
-      printk(", PCMCIA, ");
-      switch (psa.psa_subband)
-	{
-	case PSA_SUBBAND_915:
-	  printk("915");
-	  break;
-	case PSA_SUBBAND_2425:
-	  printk("2425");
-	  break;
-	case PSA_SUBBAND_2460:
-	  printk("2460");
-	  break;
-	case PSA_SUBBAND_2484:
-	  printk("2484");
-	  break;
-	case PSA_SUBBAND_2430_5:
-	  printk("2430.5");
-	  break;
-	default:
-	  printk("unknown");
-	}
-    }
-
-  printk(" MHz\n");
-#endif	/* DEBUG_BASIC_SHOW */
-
-#ifdef DEBUG_VERSION_SHOW
-  /* Print version information */
-  printk(KERN_NOTICE "%s", version);
-#endif
-} /* wv_init_info */
-
-/********************* IOCTL, STATS & RECONFIG *********************/
-/*
- * We found here routines that are called by Linux on differents
- * occasions after the configuration and not for transmitting data
- * These may be called when the user use ifconfig, /proc/net/dev
- * or wireless extensions
- */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1	Promiscuous mode, receive all packets
- * num_addrs == 0	Normal mode, clear multicast list
- * num_addrs > 0	Multicast mode, receive normal and MC packets,
- *			and do best-effort filtering.
- */
-
-static void
-wavelan_set_multicast_list(struct net_device *	dev)
-{
-  net_local *	lp = netdev_priv(dev);
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name);
-#endif
-
-#ifdef DEBUG_IOCTL_INFO
-  printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-	 dev->name, dev->flags, dev->mc_count);
-#endif
-
-  if(dev->flags & IFF_PROMISC)
-    {
-      /*
-       * Enable promiscuous mode: receive all packets.
-       */
-      if(!lp->promiscuous)
-	{
-	  lp->promiscuous = 1;
-	  lp->allmulticast = 0;
-	  lp->mc_count = 0;
-
-	  wv_82593_reconfig(dev);
-	}
-    }
-  else
-    /* If all multicast addresses
-     * or too much multicast addresses for the hardware filter */
-    if((dev->flags & IFF_ALLMULTI) ||
-       (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))
-      {
-	/*
-	 * Disable promiscuous mode, but active the all multicast mode
-	 */
-	if(!lp->allmulticast)
-	  {
-	    lp->promiscuous = 0;
-	    lp->allmulticast = 1;
-	    lp->mc_count = 0;
-
-	    wv_82593_reconfig(dev);
-	  }
-      }
-    else
-      /* If there is some multicast addresses to send */
-      if(dev->mc_list != (struct dev_mc_list *) NULL)
-	{
-	  /*
-	   * Disable promiscuous mode, but receive all packets
-	   * in multicast list
-	   */
-#ifdef MULTICAST_AVOID
-	  if(lp->promiscuous || lp->allmulticast ||
-	     (dev->mc_count != lp->mc_count))
-#endif
-	    {
-	      lp->promiscuous = 0;
-	      lp->allmulticast = 0;
-	      lp->mc_count = dev->mc_count;
-
-	      wv_82593_reconfig(dev);
-	    }
-	}
-      else
-	{
-	  /*
-	   * Switch to normal mode: disable promiscuous mode and 
-	   * clear the multicast list.
-	   */
-	  if(lp->promiscuous || lp->mc_count == 0)
-	    {
-	      lp->promiscuous = 0;
-	      lp->allmulticast = 0;
-	      lp->mc_count = 0;
-
-	      wv_82593_reconfig(dev);
-	    }
-	}
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This function doesn't exist...
- * (Note : it was a nice way to test the reconfigure stuff...)
- */
-#ifdef SET_MAC_ADDRESS
-static int
-wavelan_set_mac_address(struct net_device *	dev,
-			void *		addr)
-{
-  struct sockaddr *	mac = addr;
-
-  /* Copy the address */
-  memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
-
-  /* Reconfig the beast */
-  wv_82593_reconfig(dev);
-
-  return 0;
-}
-#endif	/* SET_MAC_ADDRESS */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Frequency setting (for hardware able of it)
- * It's a bit complicated and you don't really want to look into it...
- */
-static int
-wv_set_frequency(u_long		base,	/* i/o port of the card */
-		 iw_freq *	frequency)
-{
-  const int	BAND_NUM = 10;	/* Number of bands */
-  long		freq = 0L;	/* offset to 2.4 GHz in .5 MHz */
-#ifdef DEBUG_IOCTL_INFO
-  int		i;
-#endif
-
-  /* Setting by frequency */
-  /* Theoritically, you may set any frequency between
-   * the two limits with a 0.5 MHz precision. In practice,
-   * I don't want you to have trouble with local
-   * regulations... */
-  if((frequency->e == 1) &&
-     (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))
-    {
-      freq = ((frequency->m / 10000) - 24000L) / 5;
-    }
-
-  /* Setting by channel (same as wfreqsel) */
-  /* Warning : each channel is 22MHz wide, so some of the channels
-   * will interfere... */
-  if((frequency->e == 0) &&
-     (frequency->m >= 0) && (frequency->m < BAND_NUM))
-    {
-      /* Get frequency offset. */
-      freq = channel_bands[frequency->m] >> 1;
-    }
-
-  /* Verify if the frequency is allowed */
-  if(freq != 0L)
-    {
-      u_short	table[10];	/* Authorized frequency table */
-
-      /* Read the frequency table */
-      fee_read(base, 0x71 /* frequency table */,
-	       table, 10);
-
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG "Frequency table :");
-      for(i = 0; i < 10; i++)
-	{
-	  printk(" %04X",
-		 table[i]);
-	}
-      printk("\n");
-#endif
-
-      /* Look in the table if the frequency is allowed */
-      if(!(table[9 - ((freq - 24) / 16)] &
-	   (1 << ((freq - 24) % 16))))
-	return -EINVAL;		/* not allowed */
-    }
-  else
-    return -EINVAL;
-
-  /* If we get a usable frequency */
-  if(freq != 0L)
-    {
-      unsigned short	area[16];
-      unsigned short	dac[2];
-      unsigned short	area_verify[16];
-      unsigned short	dac_verify[2];
-      /* Corresponding gain (in the power adjust value table)
-       * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8
-       * & WCIN062D.DOC, page 6.2.9 */
-      unsigned short	power_limit[] = { 40, 80, 120, 160, 0 };
-      int		power_band = 0;		/* Selected band */
-      unsigned short	power_adjust;		/* Correct value */
-
-      /* Search for the gain */
-      power_band = 0;
-      while((freq > power_limit[power_band]) &&
-	    (power_limit[++power_band] != 0))
-	;
-
-      /* Read the first area */
-      fee_read(base, 0x00,
-	       area, 16);
-
-      /* Read the DAC */
-      fee_read(base, 0x60,
-	       dac, 2);
-
-      /* Read the new power adjust value */
-      fee_read(base, 0x6B - (power_band >> 1),
-	       &power_adjust, 1);
-      if(power_band & 0x1)
-	power_adjust >>= 8;
-      else
-	power_adjust &= 0xFF;
-
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
-      for(i = 0; i < 16; i++)
-	{
-	  printk(" %04X",
-		 area[i]);
-	}
-      printk("\n");
-
-      printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
-	     dac[0], dac[1]);
-#endif
-
-      /* Frequency offset (for info only...) */
-      area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
-
-      /* Receiver Principle main divider coefficient */
-      area[3] = (freq >> 1) + 2400L - 352L;
-      area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-      /* Transmitter Main divider coefficient */
-      area[13] = (freq >> 1) + 2400L;
-      area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-      /* Others part of the area are flags, bit streams or unused... */
-
-      /* Set the value in the DAC */
-      dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
-      dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
-
-      /* Write the first area */
-      fee_write(base, 0x00,
-		area, 16);
-
-      /* Write the DAC */
-      fee_write(base, 0x60,
-		dac, 2);
-
-      /* We now should verify here that the EEprom writing was ok */
-
-      /* ReRead the first area */
-      fee_read(base, 0x00,
-	       area_verify, 16);
-
-      /* ReRead the DAC */
-      fee_read(base, 0x60,
-	       dac_verify, 2);
-
-      /* Compare */
-      if(memcmp(area, area_verify, 16 * 2) ||
-	 memcmp(dac, dac_verify, 2 * 2))
-	{
-#ifdef DEBUG_IOCTL_ERROR
-	  printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)\n");
-#endif
-	  return -EOPNOTSUPP;
-	}
-
-      /* We must download the frequency parameters to the
-       * synthetisers (from the EEprom - area 1)
-       * Note : as the EEprom is auto decremented, we set the end
-       * if the area... */
-      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl),
-	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-      /* We must now download the power adjust value (gain) to
-       * the synthetisers (from the EEprom - area 7 - DAC) */
-      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl),
-	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-#ifdef DEBUG_IOCTL_INFO
-      /* Verification of what we have done... */
-
-      printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
-      for(i = 0; i < 16; i++)
-	{
-	  printk(" %04X",
-		 area_verify[i]);
-	}
-      printk("\n");
-
-      printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
-	     dac_verify[0], dac_verify[1]);
-#endif
-
-      return 0;
-    }
-  else
-    return -EINVAL;		/* Bah, never get there... */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Give the list of available frequencies
- */
-static int
-wv_frequency_list(u_long	base,	/* i/o port of the card */
-		  iw_freq *	list,	/* List of frequency to fill */
-		  int		max)	/* Maximum number of frequencies */
-{
-  u_short	table[10];	/* Authorized frequency table */
-  long		freq = 0L;	/* offset to 2.4 GHz in .5 MHz + 12 MHz */
-  int		i;		/* index in the table */
-  const int	BAND_NUM = 10;	/* Number of bands */
-  int		c = 0;		/* Channel number */
-
-  /* Read the frequency table */
-  fee_read(base, 0x71 /* frequency table */,
-	   table, 10);
-
-  /* Look all frequencies */
-  i = 0;
-  for(freq = 0; freq < 150; freq++)
-    /* Look in the table if the frequency is allowed */
-    if(table[9 - (freq / 16)] & (1 << (freq % 16)))
-      {
-	/* Compute approximate channel number */
-	while((((channel_bands[c] >> 1) - 24) < freq) &&
-	      (c < BAND_NUM))
-	  c++;
-	list[i].i = c;	/* Set the list index */
-
-	/* put in the list */
-	list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
-	list[i++].e = 1;
-
-	/* Check number */
-	if(i >= max)
-	  return(i);
-      }
-
-  return(i);
-}
-
-#ifdef IW_WIRELESS_SPY
-/*------------------------------------------------------------------*/
-/*
- * Gather wireless spy statistics : for each packet, compare the source
- * address with out list, and if match, get the stats...
- * Sorry, but this function really need wireless extensions...
- */
-static inline void
-wl_spy_gather(struct net_device *	dev,
-	      u_char *	mac,		/* MAC address */
-	      u_char *	stats)		/* Statistics to gather */
-{
-  struct iw_quality wstats;
-
-  wstats.qual = stats[2] & MMR_SGNL_QUAL;
-  wstats.level = stats[0] & MMR_SIGNAL_LVL;
-  wstats.noise = stats[1] & MMR_SILENCE_LVL;
-  wstats.updated = 0x7;
-
-  /* Update spy records */
-  wireless_spy_update(dev, mac, &wstats);
-}
-#endif	/* IW_WIRELESS_SPY */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * This function calculate an histogram on the signal level.
- * As the noise is quite constant, it's like doing it on the SNR.
- * We have defined a set of interval (lp->his_range), and each time
- * the level goes in that interval, we increment the count (lp->his_sum).
- * With this histogram you may detect if one wavelan is really weak,
- * or you may also calculate the mean and standard deviation of the level...
- */
-static inline void
-wl_his_gather(struct net_device *	dev,
-	      u_char *	stats)		/* Statistics to gather */
-{
-  net_local *	lp = netdev_priv(dev);
-  u_char	level = stats[0] & MMR_SIGNAL_LVL;
-  int		i;
-
-  /* Find the correct interval */
-  i = 0;
-  while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))
-    ;
-
-  /* Increment interval counter */
-  (lp->his_sum[i])++;
-}
-#endif	/* HISTOGRAM */
-
-static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-	strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
-}
-
-static const struct ethtool_ops ops = {
-	.get_drvinfo = wl_get_drvinfo
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get protocol name
- */
-static int wavelan_get_name(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	strcpy(wrqu->name, "WaveLAN");
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set NWID
- */
-static int wavelan_set_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	mm_t m;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Set NWID in WaveLAN. */
-	if (!wrqu->nwid.disabled) {
-		/* Set NWID in psa */
-		psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
-		psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
-		psa.psa_nwid_select = 0x01;
-		psa_write(dev,
-			  (char *) psa.psa_nwid - (char *) &psa,
-			  (unsigned char *) psa.psa_nwid, 3);
-
-		/* Set NWID in mmc. */
-		m.w.mmw_netw_id_l = psa.psa_nwid[1];
-		m.w.mmw_netw_id_h = psa.psa_nwid[0];
-		mmc_write(base,
-			  (char *) &m.w.mmw_netw_id_l -
-			  (char *) &m,
-			  (unsigned char *) &m.w.mmw_netw_id_l, 2);
-		mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
-	} else {
-		/* Disable NWID in the psa. */
-		psa.psa_nwid_select = 0x00;
-		psa_write(dev,
-			  (char *) &psa.psa_nwid_select -
-			  (char *) &psa,
-			  (unsigned char *) &psa.psa_nwid_select,
-			  1);
-
-		/* Disable NWID in the mmc (no filtering). */
-		mmc_out(base, mmwoff(0, mmw_loopt_sel),
-			MMW_LOOPT_SEL_DIS_NWID);
-	}
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get NWID 
- */
-static int wavelan_get_nwid(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Read the NWID. */
-	psa_read(dev,
-		 (char *) psa.psa_nwid - (char *) &psa,
-		 (unsigned char *) psa.psa_nwid, 3);
-	wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
-	wrqu->nwid.disabled = !(psa.psa_nwid_select);
-	wrqu->nwid.fixed = 1;	/* Superfluous */
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set frequency
- */
-static int wavelan_set_freq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-	int ret;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-	if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-		ret = wv_set_frequency(base, &(wrqu->freq));
-	else
-		ret = -EOPNOTSUPP;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get frequency
- */
-static int wavelan_get_freq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
-	 * Does it work for everybody, especially old cards? */
-	if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		unsigned short freq;
-
-		/* Ask the EEPROM to read the frequency from the first area. */
-		fee_read(base, 0x00, &freq, 1);
-		wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
-		wrqu->freq.e = 1;
-	} else {
-		psa_read(dev,
-			 (char *) &psa.psa_subband - (char *) &psa,
-			 (unsigned char *) &psa.psa_subband, 1);
-
-		if (psa.psa_subband <= 4) {
-			wrqu->freq.m = fixed_bands[psa.psa_subband];
-			wrqu->freq.e = (psa.psa_subband != 0);
-		} else
-			ret = -EOPNOTSUPP;
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set level threshold
- */
-static int wavelan_set_sens(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Set the level threshold. */
-	/* We should complain loudly if wrqu->sens.fixed = 0, because we
-	 * can't set auto mode... */
-	psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
-	psa_write(dev,
-		  (char *) &psa.psa_thr_pre_set - (char *) &psa,
-		  (unsigned char *) &psa.psa_thr_pre_set, 1);
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev);
-	mmc_out(base, mmwoff(0, mmw_thr_pre_set),
-		psa.psa_thr_pre_set);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get level threshold
- */
-static int wavelan_get_sens(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Read the level threshold. */
-	psa_read(dev,
-		 (char *) &psa.psa_thr_pre_set - (char *) &psa,
-		 (unsigned char *) &psa.psa_thr_pre_set, 1);
-	wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
-	wrqu->sens.fixed = 1;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set encryption key
- */
-static int wavelan_set_encode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu,
-			      char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-	psa_t psa;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-
-	/* Check if capable of encryption */
-	if (!mmc_encr(base)) {
-		ret = -EOPNOTSUPP;
-	}
-
-	/* Check the size of the key */
-	if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
-		ret = -EINVAL;
-	}
-
-	if(!ret) {
-		/* Basic checking... */
-		if (wrqu->encoding.length == 8) {
-			/* Copy the key in the driver */
-			memcpy(psa.psa_encryption_key, extra,
-			       wrqu->encoding.length);
-			psa.psa_encryption_select = 1;
-
-			psa_write(dev,
-				  (char *) &psa.psa_encryption_select -
-				  (char *) &psa,
-				  (unsigned char *) &psa.
-				  psa_encryption_select, 8 + 1);
-
-			mmc_out(base, mmwoff(0, mmw_encr_enable),
-				MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
-			mmc_write(base, mmwoff(0, mmw_encr_key),
-				  (unsigned char *) &psa.
-				  psa_encryption_key, 8);
-		}
-
-		/* disable encryption */
-		if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
-			psa.psa_encryption_select = 0;
-			psa_write(dev,
-				  (char *) &psa.psa_encryption_select -
-				  (char *) &psa,
-				  (unsigned char *) &psa.
-				  psa_encryption_select, 1);
-
-			mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
-		}
-		/* update the Wavelan checksum */
-		update_psa_checksum(dev);
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get encryption key
- */
-static int wavelan_get_encode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu,
-			      char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Check if encryption is available */
-	if (!mmc_encr(base)) {
-		ret = -EOPNOTSUPP;
-	} else {
-		/* Read the encryption key */
-		psa_read(dev,
-			 (char *) &psa.psa_encryption_select -
-			 (char *) &psa,
-			 (unsigned char *) &psa.
-			 psa_encryption_select, 1 + 8);
-
-		/* encryption is enabled ? */
-		if (psa.psa_encryption_select)
-			wrqu->encoding.flags = IW_ENCODE_ENABLED;
-		else
-			wrqu->encoding.flags = IW_ENCODE_DISABLED;
-		wrqu->encoding.flags |= mmc_encr(base);
-
-		/* Copy the key to the user buffer */
-		wrqu->encoding.length = 8;
-		memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-#ifdef WAVELAN_ROAMING_EXT
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set ESSID (domain)
- */
-static int wavelan_set_essid(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Check if disable */
-	if(wrqu->data.flags == 0)
-		lp->filter_domains = 0;
-	else {
-		char	essid[IW_ESSID_MAX_SIZE + 1];
-		char *	endp;
-
-		/* Terminate the string */
-		memcpy(essid, extra, wrqu->data.length);
-		essid[IW_ESSID_MAX_SIZE] = '\0';
-
-#ifdef DEBUG_IOCTL_INFO
-		printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
-#endif	/* DEBUG_IOCTL_INFO */
-
-		/* Convert to a number (note : Wavelan specific) */
-		lp->domain_id = simple_strtoul(essid, &endp, 16);
-		/* Has it worked  ? */
-		if(endp > essid)
-			lp->filter_domains = 1;
-		else {
-			lp->filter_domains = 0;
-			ret = -EINVAL;
-		}
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get ESSID (domain)
- */
-static int wavelan_get_essid(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-
-	/* Is the domain ID active ? */
-	wrqu->data.flags = lp->filter_domains;
-
-	/* Copy Domain ID into a string (Wavelan specific) */
-	/* Sound crazy, be we can't have a snprintf in the kernel !!! */
-	sprintf(extra, "%lX", lp->domain_id);
-	extra[IW_ESSID_MAX_SIZE] = '\0';
-
-	/* Set the length */
-	wrqu->data.length = strlen(extra);
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set AP address
- */
-static int wavelan_set_wap(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-{
-#ifdef DEBUG_IOCTL_INFO
-	printk(KERN_DEBUG "Set AP to : %pM\n", wrqu->ap_addr.sa_data);
-#endif	/* DEBUG_IOCTL_INFO */
-
-	return -EOPNOTSUPP;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get AP address
- */
-static int wavelan_get_wap(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
-{
-	/* Should get the real McCoy instead of own Ethernet address */
-	memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
-	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
-	return -EOPNOTSUPP;
-}
-#endif	/* WAVELAN_ROAMING_EXT */
-
-#ifdef WAVELAN_ROAMING
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set mode
- */
-static int wavelan_set_mode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-	int ret = 0;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-
-	/* Check mode */
-	switch(wrqu->mode) {
-	case IW_MODE_ADHOC:
-		if(do_roaming) {
-			wv_roam_cleanup(dev);
-			do_roaming = 0;
-		}
-		break;
-	case IW_MODE_INFRA:
-		if(!do_roaming) {
-			wv_roam_init(dev);
-			do_roaming = 1;
-		}
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get mode
- */
-static int wavelan_get_mode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	if(do_roaming)
-		wrqu->mode = IW_MODE_INFRA;
-	else
-		wrqu->mode = IW_MODE_ADHOC;
-
-	return 0;
-}
-#endif	/* WAVELAN_ROAMING */
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get range info
- */
-static int wavelan_get_range(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	struct iw_range *range = (struct iw_range *) extra;
-	unsigned long flags;
-	int ret = 0;
-
-	/* Set the length (very important for backward compatibility) */
-	wrqu->data.length = sizeof(struct iw_range);
-
-	/* Set all the info we don't care or don't know about to zero */
-	memset(range, 0, sizeof(struct iw_range));
-
-	/* Set the Wireless Extension versions */
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 9;
-
-	/* Set information in the range struct.  */
-	range->throughput = 1.4 * 1000 * 1000;	/* don't argue on this ! */
-	range->min_nwid = 0x0000;
-	range->max_nwid = 0xFFFF;
-
-	range->sensitivity = 0x3F;
-	range->max_qual.qual = MMR_SGNL_QUAL;
-	range->max_qual.level = MMR_SIGNAL_LVL;
-	range->max_qual.noise = MMR_SILENCE_LVL;
-	range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
-	/* Need to get better values for those two */
-	range->avg_qual.level = 30;
-	range->avg_qual.noise = 8;
-
-	range->num_bitrates = 1;
-	range->bitrate[0] = 2000000;	/* 2 Mb/s */
-
-	/* Event capability (kernel + driver) */
-	range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
-				IW_EVENT_CAPA_MASK(0x8B04) |
-				IW_EVENT_CAPA_MASK(0x8B06));
-	range->event_capa[1] = IW_EVENT_CAPA_K_1;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-	if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-	      (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-		range->num_channels = 10;
-		range->num_frequency = wv_frequency_list(base, range->freq,
-							IW_MAX_FREQUENCIES);
-	} else
-		range->num_channels = range->num_frequency = 0;
-
-	/* Encryption supported ? */
-	if (mmc_encr(base)) {
-		range->encoding_size[0] = 8;	/* DES = 64 bits key */
-		range->num_encoding_sizes = 1;
-		range->max_encoding_tokens = 1;	/* Only one key possible */
-	} else {
-		range->num_encoding_sizes = 0;
-		range->max_encoding_tokens = 0;
-	}
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set quality threshold
- */
-static int wavelan_set_qthr(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	unsigned int base = dev->base_addr;
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	psa.psa_quality_thr = *(extra) & 0x0F;
-	psa_write(dev,
-		  (char *) &psa.psa_quality_thr - (char *) &psa,
-		  (unsigned char *) &psa.psa_quality_thr, 1);
-	/* update the Wavelan checksum */
-	update_psa_checksum(dev);
-	mmc_out(base, mmwoff(0, mmw_quality_thr),
-		psa.psa_quality_thr);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_qthr(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	psa_t psa;
-	unsigned long flags;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	psa_read(dev,
-		 (char *) &psa.psa_quality_thr - (char *) &psa,
-		 (unsigned char *) &psa.psa_quality_thr, 1);
-	*(extra) = psa.psa_quality_thr & 0x0F;
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return 0;
-}
-
-#ifdef WAVELAN_ROAMING
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set roaming
- */
-static int wavelan_set_roam(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-
-	/* Disable interrupts and save flags. */
-	spin_lock_irqsave(&lp->spinlock, flags);
-	
-	/* Note : should check if user == root */
-	if(do_roaming && (*extra)==0)
-		wv_roam_cleanup(dev);
-	else if(do_roaming==0 && (*extra)!=0)
-		wv_roam_init(dev);
-
-	do_roaming = (*extra);
-
-	/* Enable interrupts and restore flags. */
-	spin_unlock_irqrestore(&lp->spinlock, flags);
-
-	return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_roam(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu,
-			    char *extra)
-{
-	*(extra) = do_roaming;
-
-	return 0;
-}
-#endif	/* WAVELAN_ROAMING */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set histogram
- */
-static int wavelan_set_histo(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-
-	/* Check the number of intervals. */
-	if (wrqu->data.length > 16) {
-		return(-E2BIG);
-	}
-
-	/* Disable histo while we copy the addresses.
-	 * As we don't disable interrupts, we need to do this */
-	lp->his_number = 0;
-
-	/* Are there ranges to copy? */
-	if (wrqu->data.length > 0) {
-		/* Copy interval ranges to the driver */
-		memcpy(lp->his_range, extra, wrqu->data.length);
-
-		{
-		  int i;
-		  printk(KERN_DEBUG "Histo :");
-		  for(i = 0; i < wrqu->data.length; i++)
-		    printk(" %d", lp->his_range[i]);
-		  printk("\n");
-		}
-
-		/* Reset result structure. */
-		memset(lp->his_sum, 0x00, sizeof(long) * 16);
-	}
-
-	/* Now we can set the number of ranges */
-	lp->his_number = wrqu->data.length;
-
-	return(0);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get histogram
- */
-static int wavelan_get_histo(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu,
-			     char *extra)
-{
-	net_local *lp = netdev_priv(dev);
-
-	/* Set the number of intervals. */
-	wrqu->data.length = lp->his_number;
-
-	/* Give back the distribution statistics */
-	if(lp->his_number > 0)
-		memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
-
-	return(0);
-}
-#endif			/* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Structures to export the Wireless Handlers
- */
-
-static const struct iw_priv_args wavelan_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
-  { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
-  { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" },
-  { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
-  { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16,                    0, "sethisto" },
-  { SIOCGIPHISTO, 0,                     IW_PRIV_TYPE_INT | 16, "gethisto" },
-};
-
-static const iw_handler		wavelan_handler[] =
-{
-	NULL,				/* SIOCSIWNAME */
-	wavelan_get_name,		/* SIOCGIWNAME */
-	wavelan_set_nwid,		/* SIOCSIWNWID */
-	wavelan_get_nwid,		/* SIOCGIWNWID */
-	wavelan_set_freq,		/* SIOCSIWFREQ */
-	wavelan_get_freq,		/* SIOCGIWFREQ */
-#ifdef WAVELAN_ROAMING
-	wavelan_set_mode,		/* SIOCSIWMODE */
-	wavelan_get_mode,		/* SIOCGIWMODE */
-#else	/* WAVELAN_ROAMING */
-	NULL,				/* SIOCSIWMODE */
-	NULL,				/* SIOCGIWMODE */
-#endif	/* WAVELAN_ROAMING */
-	wavelan_set_sens,		/* SIOCSIWSENS */
-	wavelan_get_sens,		/* SIOCGIWSENS */
-	NULL,				/* SIOCSIWRANGE */
-	wavelan_get_range,		/* SIOCGIWRANGE */
-	NULL,				/* SIOCSIWPRIV */
-	NULL,				/* SIOCGIWPRIV */
-	NULL,				/* SIOCSIWSTATS */
-	NULL,				/* SIOCGIWSTATS */
-	iw_handler_set_spy,		/* SIOCSIWSPY */
-	iw_handler_get_spy,		/* SIOCGIWSPY */
-	iw_handler_set_thrspy,		/* SIOCSIWTHRSPY */
-	iw_handler_get_thrspy,		/* SIOCGIWTHRSPY */
-#ifdef WAVELAN_ROAMING_EXT
-	wavelan_set_wap,		/* SIOCSIWAP */
-	wavelan_get_wap,		/* SIOCGIWAP */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCGIWAPLIST */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	wavelan_set_essid,		/* SIOCSIWESSID */
-	wavelan_get_essid,		/* SIOCGIWESSID */
-#else	/* WAVELAN_ROAMING_EXT */
-	NULL,				/* SIOCSIWAP */
-	NULL,				/* SIOCGIWAP */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCGIWAPLIST */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWESSID */
-	NULL,				/* SIOCGIWESSID */
-#endif	/* WAVELAN_ROAMING_EXT */
-	NULL,				/* SIOCSIWNICKN */
-	NULL,				/* SIOCGIWNICKN */
-	NULL,				/* -- hole -- */
-	NULL,				/* -- hole -- */
-	NULL,				/* SIOCSIWRATE */
-	NULL,				/* SIOCGIWRATE */
-	NULL,				/* SIOCSIWRTS */
-	NULL,				/* SIOCGIWRTS */
-	NULL,				/* SIOCSIWFRAG */
-	NULL,				/* SIOCGIWFRAG */
-	NULL,				/* SIOCSIWTXPOW */
-	NULL,				/* SIOCGIWTXPOW */
-	NULL,				/* SIOCSIWRETRY */
-	NULL,				/* SIOCGIWRETRY */
-	wavelan_set_encode,		/* SIOCSIWENCODE */
-	wavelan_get_encode,		/* SIOCGIWENCODE */
-};
-
-static const iw_handler		wavelan_private_handler[] =
-{
-	wavelan_set_qthr,		/* SIOCIWFIRSTPRIV */
-	wavelan_get_qthr,		/* SIOCIWFIRSTPRIV + 1 */
-#ifdef WAVELAN_ROAMING
-	wavelan_set_roam,		/* SIOCIWFIRSTPRIV + 2 */
-	wavelan_get_roam,		/* SIOCIWFIRSTPRIV + 3 */
-#else	/* WAVELAN_ROAMING */
-	NULL,				/* SIOCIWFIRSTPRIV + 2 */
-	NULL,				/* SIOCIWFIRSTPRIV + 3 */
-#endif	/* WAVELAN_ROAMING */
-#ifdef HISTOGRAM
-	wavelan_set_histo,		/* SIOCIWFIRSTPRIV + 4 */
-	wavelan_get_histo,		/* SIOCIWFIRSTPRIV + 5 */
-#endif	/* HISTOGRAM */
-};
-
-static const struct iw_handler_def	wavelan_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(wavelan_handler),
-	.num_private	= ARRAY_SIZE(wavelan_private_handler),
-	.num_private_args = ARRAY_SIZE(wavelan_private_args),
-	.standard	= wavelan_handler,
-	.private	= wavelan_private_handler,
-	.private_args	= wavelan_private_args,
-	.get_wireless_stats = wavelan_get_wireless_stats,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Get wireless statistics
- * Called by /proc/net/wireless...
- */
-static iw_stats *
-wavelan_get_wireless_stats(struct net_device *	dev)
-{
-  unsigned int		base = dev->base_addr;
-  net_local *		lp = netdev_priv(dev);
-  mmr_t			m;
-  iw_stats *		wstats;
-  unsigned long		flags;
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);
-#endif
-
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  wstats = &lp->wstats;
-
-  /* Get data from the mmc */
-  mmc_out(base, mmwoff(0, mmw_freeze), 1);
-
-  mmc_read(base, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
-  mmc_read(base, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2);
-  mmc_read(base, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4);
-
-  mmc_out(base, mmwoff(0, mmw_freeze), 0);
-
-  /* Copy data to wireless stuff */
-  wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
-  wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
-  wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
-  wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
-  wstats->qual.updated = (((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) |
-			  ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) |
-			  ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
-  wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-  wstats->discard.code = 0L;
-  wstats->discard.misc = 0L;
-
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
-#endif
-  return &lp->wstats;
-}
-
-/************************* PACKET RECEPTION *************************/
-/*
- * This part deal with receiving the packets.
- * The interrupt handler get an interrupt when a packet has been
- * successfully received and called this part...
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Calculate the starting address of the frame pointed to by the receive
- * frame pointer and verify that the frame seem correct
- * (called by wv_packet_rcv())
- */
-static int
-wv_start_of_frame(struct net_device *	dev,
-		  int		rfp,	/* end of frame */
-		  int		wrap)	/* start of buffer */
-{
-  unsigned int	base = dev->base_addr;
-  int		rp;
-  int		len;
-
-  rp = (rfp - 5 + RX_SIZE) % RX_SIZE;
-  outb(rp & 0xff, PIORL(base));
-  outb(((rp >> 8) & PIORH_MASK), PIORH(base));
-  len = inb(PIOP(base));
-  len |= inb(PIOP(base)) << 8;
-
-  /* Sanity checks on size */
-  /* Frame too big */
-  if(len > MAXDATAZ + 100)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: Received frame too large, rfp %d len 0x%x\n",
-	     dev->name, rfp, len);
-#endif
-      return(-1);
-    }
-  
-  /* Frame too short */
-  if(len < 7)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: Received null frame, rfp %d len 0x%x\n",
-	     dev->name, rfp, len);
-#endif
-      return(-1);
-    }
-  
-  /* Wrap around buffer */
-  if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE))	/* magic formula ! */
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n",
-	     dev->name, wrap, rfp, len);
-#endif
-      return(-1);
-    }
-
-  return((rp - len + RX_SIZE) % RX_SIZE);
-} /* wv_start_of_frame */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does the actual copy of data (including the ethernet
- * header structure) from the WaveLAN card to an sk_buff chain that
- * will be passed up to the network interface layer. NOTE: We
- * currently don't handle trailer protocols (neither does the rest of
- * the network interface), so if that is needed, it will (at least in
- * part) be added here.  The contents of the receive ring buffer are
- * copied to a message chain that is then passed to the kernel.
- *
- * Note: if any errors occur, the packet is "dropped on the floor"
- * (called by wv_packet_rcv())
- */
-static void
-wv_packet_read(struct net_device *		dev,
-	       int		fd_p,
-	       int		sksize)
-{
-  net_local *		lp = netdev_priv(dev);
-  struct sk_buff *	skb;
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
-	 dev->name, fd_p, sksize);
-#endif
-
-  /* Allocate some buffer for the new packet */
-  if((skb = dev_alloc_skb(sksize+2)) == (struct sk_buff *) NULL)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
-	     dev->name, sksize);
-#endif
-      dev->stats.rx_dropped++;
-      /*
-       * Not only do we want to return here, but we also need to drop the
-       * packet on the floor to clear the interrupt.
-       */
-      return;
-    }
-
-  skb_reserve(skb, 2);
-  fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize);
-  skb->protocol = eth_type_trans(skb, dev);
-
-#ifdef DEBUG_RX_INFO
-  wv_packet_info(skb_mac_header(skb), sksize, dev->name, "wv_packet_read");
-#endif	/* DEBUG_RX_INFO */
-     
-  /* Statistics gathering & stuff associated.
-   * It seem a bit messy with all the define, but it's really simple... */
-  if(
-#ifdef IW_WIRELESS_SPY
-     (lp->spy_data.spy_number > 0) ||
-#endif	/* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-     (lp->his_number > 0) ||
-#endif	/* HISTOGRAM */
-#ifdef WAVELAN_ROAMING
-     (do_roaming) ||
-#endif	/* WAVELAN_ROAMING */
-     0)
-    {
-      u_char	stats[3];	/* Signal level, Noise level, Signal quality */
-
-      /* read signal level, silence level and signal quality bytes */
-      fd_p = read_ringbuf(dev, (fd_p + 4) % RX_SIZE + RX_BASE,
-			  stats, 3);
-#ifdef DEBUG_RX_INFO
-      printk(KERN_DEBUG "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
-	     dev->name, stats[0] & 0x3F, stats[1] & 0x3F, stats[2] & 0x0F);
-#endif
-
-#ifdef WAVELAN_ROAMING
-      if(do_roaming)
-	if(WAVELAN_BEACON(skb->data))
-	  wl_roam_gather(dev, skb->data, stats);
-#endif	/* WAVELAN_ROAMING */
-	  
-#ifdef WIRELESS_SPY
-      wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, stats);
-#endif	/* WIRELESS_SPY */
-#ifdef HISTOGRAM
-      wl_his_gather(dev, stats);
-#endif	/* HISTOGRAM */
-    }
-
-  /*
-   * Hand the packet to the Network Module
-   */
-  netif_rx(skb);
-
-  /* Keep stats up to date */
-  dev->stats.rx_packets++;
-  dev->stats.rx_bytes += sksize;
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
-#endif
-  return;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called by the interrupt handler to initiate a
- * packet transfer from the card to the network interface layer above
- * this driver.  This routine checks if a buffer has been successfully
- * received by the WaveLAN card.  If so, the routine wv_packet_read is
- * called to do the actual transfer of the card's data including the
- * ethernet header into a packet consisting of an sk_buff chain.
- * (called by wavelan_interrupt())
- * Note : the spinlock is already grabbed for us and irq are disabled.
- */
-static void
-wv_packet_rcv(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  net_local *	lp = netdev_priv(dev);
-  int		newrfp;
-  int		rp;
-  int		len;
-  int		f_start;
-  int		status;
-  int		i593_rfp;
-  int		stat_ptr;
-  u_char	c[4];
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_rcv()\n", dev->name);
-#endif
-
-  /* Get the new receive frame pointer from the i82593 chip */
-  outb(CR0_STATUS_2 | OP0_NOP, LCCR(base));
-  i593_rfp = inb(LCSR(base));
-  i593_rfp |= inb(LCSR(base)) << 8;
-  i593_rfp %= RX_SIZE;
-
-  /* Get the new receive frame pointer from the WaveLAN card.
-   * It is 3 bytes more than the increment of the i82593 receive
-   * frame pointer, for each packet. This is because it includes the
-   * 3 roaming bytes added by the mmc.
-   */
-  newrfp = inb(RPLL(base));
-  newrfp |= inb(RPLH(base)) << 8;
-  newrfp %= RX_SIZE;
-
-#ifdef DEBUG_RX_INFO
-  printk(KERN_DEBUG "%s: wv_packet_rcv(): i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-	 dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-
-#ifdef DEBUG_RX_ERROR
-  /* If no new frame pointer... */
-  if(lp->overrunning || newrfp == lp->rfp)
-    printk(KERN_INFO "%s: wv_packet_rcv(): no new frame: i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-	   dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-
-  /* Read all frames (packets) received */
-  while(newrfp != lp->rfp)
-    {
-      /* A frame is composed of the packet, followed by a status word,
-       * the length of the frame (word) and the mmc info (SNR & qual).
-       * It's because the length is at the end that we can only scan
-       * frames backward. */
-
-      /* Find the first frame by skipping backwards over the frames */
-      rp = newrfp;	/* End of last frame */
-      while(((f_start = wv_start_of_frame(dev, rp, newrfp)) != lp->rfp) &&
-	    (f_start != -1))
-	  rp = f_start;
-
-      /* If we had a problem */
-      if(f_start == -1)
-	{
-#ifdef DEBUG_RX_ERROR
-	  printk(KERN_INFO "wavelan_cs: cannot find start of frame ");
-	  printk(" i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-		 i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-	  lp->rfp = rp;		/* Get to the last usable frame */
-	  continue;
-	}
-
-      /* f_start point to the beggining of the first frame received
-       * and rp to the beggining of the next one */
-
-      /* Read status & length of the frame */
-      stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE;
-      stat_ptr = read_ringbuf(dev, stat_ptr, c, 4);
-      status = c[0] | (c[1] << 8);
-      len = c[2] | (c[3] << 8);
-
-      /* Check status */
-      if((status & RX_RCV_OK) != RX_RCV_OK)
-	{
-	  dev->stats.rx_errors++;
-	  if(status & RX_NO_SFD)
-	    dev->stats.rx_frame_errors++;
-	  if(status & RX_CRC_ERR)
-	    dev->stats.rx_crc_errors++;
-	  if(status & RX_OVRRUN)
-	    dev->stats.rx_over_errors++;
-
-#ifdef DEBUG_RX_FAIL
-	  printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
-		 dev->name, status);
-#endif
-	}
-      else
-	/* Read the packet and transmit to Linux */
-	wv_packet_read(dev, f_start, len - 2);
-
-      /* One frame has been processed, skip it */
-      lp->rfp = rp;
-    }
-
-  /*
-   * Update the frame stop register, but set it to less than
-   * the full 8K to allow space for 3 bytes of signal strength
-   * per packet.
-   */
-  lp->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
-  outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
-  outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
-  outb(OP1_SWIT_TO_PORT_0, LCCR(base));
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_rcv()\n", dev->name);
-#endif
-}
-
-/*********************** PACKET TRANSMISSION ***********************/
-/*
- * This part deal with sending packet through the wavelan
- * We copy the packet to the send buffer and then issue the send
- * command to the i82593. The result of this operation will be
- * checked in wavelan_interrupt()
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine fills in the appropriate registers and memory
- * locations on the WaveLAN card and starts the card off on
- * the transmit.
- * (called in wavelan_packet_xmit())
- */
-static void
-wv_packet_write(struct net_device *	dev,
-		void *		buf,
-		short		length)
-{
-  net_local *		lp = netdev_priv(dev);
-  unsigned int		base = dev->base_addr;
-  unsigned long		flags;
-  int			clen = length;
-  register u_short	xmtdata_base = TX_BASE;
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Write the length of data buffer followed by the buffer */
-  outb(xmtdata_base & 0xff, PIORL(base));
-  outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(clen & 0xff, PIOP(base));	/* lsb */
-  outb(clen >> 8, PIOP(base));  	/* msb */
-
-  /* Send the data */
-  outsb(PIOP(base), buf, clen);
-
-  /* Indicate end of transmit chain */
-  outb(OP0_NOP, PIOP(base));
-  /* josullvn@cs.cmu.edu: need to send a second NOP for alignment... */
-  outb(OP0_NOP, PIOP(base));
-
-  /* Reset the transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  /* Send the transmit command */
-  wv_82593_cmd(dev, "wv_packet_write(): transmit",
-	       OP0_TRANSMIT, SR0_NO_RESULT);
-
-  /* Make sure the watchdog will keep quiet for a while */
-  dev->trans_start = jiffies;
-
-  /* Keep stats up to date */
-  dev->stats.tx_bytes += length;
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_TX_INFO
-  wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
-#endif	/* DEBUG_TX_INFO */
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the harware is ready to accept
- * the packet. We also prevent reentrance. Then, we call the function
- * to send the packet...
- */
-static netdev_tx_t
-wavelan_packet_xmit(struct sk_buff *	skb,
-		    struct net_device *		dev)
-{
-  net_local *		lp = netdev_priv(dev);
-  unsigned long		flags;
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
-	 (unsigned) skb);
-#endif
-
-  /*
-   * Block a timer-based transmit from overlapping a previous transmit.
-   * In other words, prevent reentering this routine.
-   */
-  netif_stop_queue(dev);
-
-  /* If somebody has asked to reconfigure the controller,
-   * we can do it now */
-  if(lp->reconfig_82593)
-    {
-      spin_lock_irqsave(&lp->spinlock, flags);	/* Disable interrupts */
-      wv_82593_config(dev);
-      spin_unlock_irqrestore(&lp->spinlock, flags);	/* Re-enable interrupts */
-      /* Note : the configure procedure was totally synchronous,
-       * so the Tx buffer is now free */
-    }
-
-	/* Check if we need some padding */
-	/* Note : on wireless the propagation time is in the order of 1us,
-	 * and we don't have the Ethernet specific requirement of beeing
-	 * able to detect collisions, therefore in theory we don't really
-	 * need to pad. Jean II */
-	if (skb_padto(skb, ETH_ZLEN))
-		return NETDEV_TX_OK;
-
-  wv_packet_write(dev, skb->data, skb->len);
-
-  dev_kfree_skb(skb);
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
-#endif
-  return NETDEV_TX_OK;
-}
-
-/********************** HARDWARE CONFIGURATION **********************/
-/*
- * This part do the real job of starting and configuring the hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to initialize the Modem Management Controller.
- * (called by wv_hw_config())
- */
-static int
-wv_mmc_init(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  psa_t		psa;
-  mmw_t		m;
-  int		configured;
-  int		i;		/* Loop counter */
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
-#endif
-
-  /* Read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-  /*
-   * Check the first three octets of the MAC addr for the manufacturer's code.
-   * Note: If you get the error message below, you've got a
-   * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
-   * how to configure your card...
-   */
-  for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
-    if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
-        (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
-        (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
-      break;
-
-  /* If we have not found it... */
-  if (i == ARRAY_SIZE(MAC_ADDRESSES))
-    {
-#ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
-	     dev->name, psa.psa_univ_mac_addr[0],
-	     psa.psa_univ_mac_addr[1], psa.psa_univ_mac_addr[2]);
-#endif
-      return FALSE;
-    }
-
-  /* Get the MAC address */
-  memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE);
-
-#ifdef USE_PSA_CONFIG
-  configured = psa.psa_conf_status & 1;
-#else
-  configured = 0;
-#endif
-
-  /* Is the PSA is not configured */
-  if(!configured)
-    {
-      /* User will be able to configure NWID after (with iwconfig) */
-      psa.psa_nwid[0] = 0;
-      psa.psa_nwid[1] = 0;
-
-      /* As NWID is not set : no NWID checking */
-      psa.psa_nwid_select = 0;
-
-      /* Disable encryption */
-      psa.psa_encryption_select = 0;
-
-      /* Set to standard values
-       * 0x04 for AT,
-       * 0x01 for MCA,
-       * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
-       */
-      if (psa.psa_comp_number & 1)
-	psa.psa_thr_pre_set = 0x01;
-      else
-	psa.psa_thr_pre_set = 0x04;
-      psa.psa_quality_thr = 0x03;
-
-      /* It is configured */
-      psa.psa_conf_status |= 1;
-
-#ifdef USE_PSA_CONFIG
-      /* Write the psa */
-      psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
-		(unsigned char *)psa.psa_nwid, 4);
-      psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
-		(unsigned char *)&psa.psa_thr_pre_set, 1);
-      psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
-		(unsigned char *)&psa.psa_quality_thr, 1);
-      psa_write(dev, (char *)&psa.psa_conf_status - (char *)&psa,
-		(unsigned char *)&psa.psa_conf_status, 1);
-      /* update the Wavelan checksum */
-      update_psa_checksum(dev);
-#endif	/* USE_PSA_CONFIG */
-    }
-
-  /* Zero the mmc structure */
-  memset(&m, 0x00, sizeof(m));
-
-  /* Copy PSA info to the mmc */
-  m.mmw_netw_id_l = psa.psa_nwid[1];
-  m.mmw_netw_id_h = psa.psa_nwid[0];
-  
-  if(psa.psa_nwid_select & 1)
-    m.mmw_loopt_sel = 0x00;
-  else
-    m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
-
-  memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, 
-	 sizeof(m.mmw_encr_key));
-
-  if(psa.psa_encryption_select)
-    m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
-  else
-    m.mmw_encr_enable = 0;
-
-  m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
-  m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
-
-  /*
-   * Set default modem control parameters.
-   * See NCR document 407-0024326 Rev. A.
-   */
-  m.mmw_jabber_enable = 0x01;
-  m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
-  m.mmw_ifs = 0x20;
-  m.mmw_mod_delay = 0x04;
-  m.mmw_jam_time = 0x38;
-
-  m.mmw_des_io_invert = 0;
-  m.mmw_freeze = 0;
-  m.mmw_decay_prm = 0;
-  m.mmw_decay_updat_prm = 0;
-
-  /* Write all info to mmc */
-  mmc_write(base, 0, (u_char *)&m, sizeof(m));
-
-  /* The following code start the modem of the 2.00 frequency
-   * selectable cards at power on. It's not strictly needed for the
-   * following boots...
-   * The original patch was by Joe Finney for the PCMCIA driver, but
-   * I've cleaned it a bit and add documentation.
-   * Thanks to Loeke Brederveld from Lucent for the info.
-   */
-
-  /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-   * (does it work for everybody ? - especially old cards...) */
-  /* Note : WFREQSEL verify that it is able to read from EEprom
-   * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID
-   * is 0xA (Xilinx version) or 0xB (Ariadne version).
-   * My test is more crude but do work... */
-  if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-    {
-      /* We must download the frequency parameters to the
-       * synthetisers (from the EEprom - area 1)
-       * Note : as the EEprom is auto decremented, we set the end
-       * if the area... */
-      m.mmw_fee_addr = 0x0F;
-      m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-      mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
-		(unsigned char *)&m.mmw_fee_ctrl, 2);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-#ifdef DEBUG_CONFIG_INFO
-      /* The frequency was in the last word downloaded... */
-      mmc_read(base, (char *)&m.mmw_fee_data_l - (char *)&m,
-	       (unsigned char *)&m.mmw_fee_data_l, 2);
-
-      /* Print some info for the user */
-      printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n",
-	     dev->name,
-	     ((m.mmw_fee_data_h << 4) |
-	      (m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L);
-#endif
-
-      /* We must now download the power adjust value (gain) to
-       * the synthetisers (from the EEprom - area 7 - DAC) */
-      m.mmw_fee_addr = 0x61;
-      m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-      mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
-		(unsigned char *)&m.mmw_fee_ctrl, 2);
-
-      /* Wait until the download is finished */
-    }	/* if 2.00 card */
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to gracefully turn off reception, and wait for any commands
- * to complete.
- * (called in wv_ru_start() and wavelan_close() and wavelan_event())
- */
-static int
-wv_ru_stop(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  net_local *	lp = netdev_priv(dev);
-  unsigned long	flags;
-  int		status;
-  int		spin;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* First, send the LAN controller a stop receive command */
-  wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
-	       OP0_STOP_RCV, SR0_NO_RESULT);
-
-  /* Then, spin until the receive unit goes idle */
-  spin = 300;
-  do
-    {
-      udelay(10);
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0));
-
-  /* Now, spin until the chip finishes executing its current command */
-  do
-    {
-      udelay(10);
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  /* If there was a problem */
-  if(spin <= 0)
-    {
-#ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
-	     dev->name);
-#endif
-      return FALSE;
-    }
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_ru_stop()\n", dev->name);
-#endif
-  return TRUE;
-} /* wv_ru_stop */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine starts the receive unit running.  First, it checks if
- * the card is actually ready. Then the card is instructed to receive
- * packets again.
- * (called in wv_hw_reset() & wavelan_open())
- */
-static int
-wv_ru_start(struct net_device *	dev)
-{
-  unsigned int	base = dev->base_addr;
-  net_local *	lp = netdev_priv(dev);
-  unsigned long	flags;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
-#endif
-
-  /*
-   * We need to start from a quiescent state. To do so, we could check
-   * if the card is already running, but instead we just try to shut
-   * it down. First, we disable reception (in case it was already enabled).
-   */
-  if(!wv_ru_stop(dev))
-    return FALSE;
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Now we know that no command is being executed. */
-
-  /* Set the receive frame pointer and stop pointer */
-  lp->rfp = 0;
-  outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
-
-  /* Reset ring management.  This sets the receive frame pointer to 1 */
-  outb(OP1_RESET_RING_MNGMT, LCCR(base));
-
-#if 0
-  /* XXX the i82593 manual page 6-4 seems to indicate that the stop register
-     should be set as below */
-  /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/
-#elif 0
-  /* but I set it 0 instead */
-  lp->stop = 0;
-#else
-  /* but I set it to 3 bytes per packet less than 8K */
-  lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
-#endif
-  outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
-  outb(OP1_INT_ENABLE, LCCR(base));
-  outb(OP1_SWIT_TO_PORT_0, LCCR(base));
-
-  /* Reset receive DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write_slow(base, HACR_DEFAULT);
-
-  /* Receive DMA on channel 1 */
-  wv_82593_cmd(dev, "wv_ru_start(): rcv-enable",
-	       CR0_CHNL | OP0_RCV_ENABLE, SR0_NO_RESULT);
-
-#ifdef DEBUG_I82593_SHOW
-  {
-    int	status;
-    int	opri;
-    int	spin = 10000;
-
-    /* spin until the chip starts receiving */
-    do
-      {
-	outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-	status = inb(LCSR(base));
-	if(spin-- <= 0)
-	  break;
-      }
-    while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) &&
-	  ((status & SR3_RCV_STATE_MASK) != SR3_RCV_READY));
-    printk(KERN_DEBUG "rcv status is 0x%x [i:%d]\n",
-	   (status & SR3_RCV_STATE_MASK), i);
-  }
-#endif
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard config of the WaveLAN controller (i82593).
- * In the ISA driver, this is integrated in wavelan_hardware_reset()
- * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit())
- */
-static int
-wv_82593_config(struct net_device *	dev)
-{
-  unsigned int			base = dev->base_addr;
-  net_local *			lp = netdev_priv(dev);
-  struct i82593_conf_block	cfblk;
-  int				ret = TRUE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name);
-#endif
-
-  /* Create & fill i82593 config block
-   *
-   * Now conform to Wavelan document WCIN085B
-   */
-  memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
-  cfblk.d6mod = FALSE;  	/* Run in i82593 advanced mode */
-  cfblk.fifo_limit = 5;         /* = 56 B rx and 40 B tx fifo thresholds */
-  cfblk.forgnesi = FALSE;       /* 0=82C501, 1=AMD7992B compatibility */
-  cfblk.fifo_32 = 1;
-  cfblk.throttle_enb = FALSE;
-  cfblk.contin = TRUE;          /* enable continuous mode */
-  cfblk.cntrxint = FALSE;       /* enable continuous mode receive interrupts */
-  cfblk.addr_len = WAVELAN_ADDR_SIZE;
-  cfblk.acloc = TRUE;           /* Disable source addr insertion by i82593 */
-  cfblk.preamb_len = 0;         /* 2 bytes preamble (SFD) */
-  cfblk.loopback = FALSE;
-  cfblk.lin_prio = 0;   	/* conform to 802.3 backoff algorithm */
-  cfblk.exp_prio = 5;	        /* conform to 802.3 backoff algorithm */
-  cfblk.bof_met = 1;	        /* conform to 802.3 backoff algorithm */
-  cfblk.ifrm_spc = 0x20 >> 4;	/* 32 bit times interframe spacing */
-  cfblk.slottim_low = 0x20 >> 5;	/* 32 bit times slot time */
-  cfblk.slottim_hi = 0x0;
-  cfblk.max_retr = 15;
-  cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE);	/* Promiscuous mode */
-  cfblk.bc_dis = FALSE;         /* Enable broadcast reception */
-  cfblk.crs_1 = TRUE;		/* Transmit without carrier sense */
-  cfblk.nocrc_ins = FALSE;	/* i82593 generates CRC */	
-  cfblk.crc_1632 = FALSE;	/* 32-bit Autodin-II CRC */
-  cfblk.crs_cdt = FALSE;	/* CD not to be interpreted as CS */
-  cfblk.cs_filter = 0;  	/* CS is recognized immediately */
-  cfblk.crs_src = FALSE;	/* External carrier sense */
-  cfblk.cd_filter = 0;  	/* CD is recognized immediately */
-  cfblk.min_fr_len = ETH_ZLEN >> 2;     /* Minimum frame length 64 bytes */
-  cfblk.lng_typ = FALSE;	/* Length field > 1500 = type field */
-  cfblk.lng_fld = TRUE; 	/* Disable 802.3 length field check */
-  cfblk.rxcrc_xf = TRUE;	/* Don't transfer CRC to memory */
-  cfblk.artx = TRUE;		/* Disable automatic retransmission */
-  cfblk.sarec = TRUE;		/* Disable source addr trig of CD */
-  cfblk.tx_jabber = TRUE;	/* Disable jabber jam sequence */
-  cfblk.hash_1 = FALSE; 	/* Use bits 0-5 in mc address hash */
-  cfblk.lbpkpol = TRUE; 	/* Loopback pin active high */
-  cfblk.fdx = FALSE;		/* Disable full duplex operation */
-  cfblk.dummy_6 = 0x3f; 	/* all ones */
-  cfblk.mult_ia = FALSE;	/* No multiple individual addresses */
-  cfblk.dis_bof = FALSE;	/* Disable the backoff algorithm ?! */
-  cfblk.dummy_1 = TRUE; 	/* set to 1 */
-  cfblk.tx_ifs_retrig = 3;	/* Hmm... Disabled */
-#ifdef MULTICAST_ALL
-  cfblk.mc_all = (lp->allmulticast ? TRUE: FALSE);	/* Allow all multicasts */
-#else
-  cfblk.mc_all = FALSE;		/* No multicast all mode */
-#endif
-  cfblk.rcv_mon = 0;		/* Monitor mode disabled */
-  cfblk.frag_acpt = TRUE;	/* Do not accept fragments */
-  cfblk.tstrttrs = FALSE;	/* No start transmission threshold */
-  cfblk.fretx = TRUE;		/* FIFO automatic retransmission */
-  cfblk.syncrqs = FALSE; 	/* Synchronous DRQ deassertion... */
-  cfblk.sttlen = TRUE;  	/* 6 byte status registers */
-  cfblk.rx_eop = TRUE;  	/* Signal EOP on packet reception */
-  cfblk.tx_eop = TRUE;  	/* Signal EOP on packet transmission */
-  cfblk.rbuf_size = RX_SIZE>>11;	/* Set receive buffer size */
-  cfblk.rcvstop = TRUE; 	/* Enable Receive Stop Register */
-
-#ifdef DEBUG_I82593_SHOW
-  print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE,
-		 16, 1, &cfblk, sizeof(struct i82593_conf_block), false);
-#endif
-
-  /* Copy the config block to the i82593 */
-  outb(TX_BASE & 0xff, PIORL(base));
-  outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(sizeof(struct i82593_conf_block) & 0xff, PIOP(base));    /* lsb */
-  outb(sizeof(struct i82593_conf_block) >> 8, PIOP(base));	/* msb */
-  outsb(PIOP(base), (char *) &cfblk, sizeof(struct i82593_conf_block));
-
-  /* reset transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  if(!wv_82593_cmd(dev, "wv_82593_config(): configure",
-		   OP0_CONFIGURE, SR0_CONFIGURE_DONE))
-    ret = FALSE;
-
-  /* Initialize adapter's ethernet MAC address */
-  outb(TX_BASE & 0xff, PIORL(base));
-  outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(WAVELAN_ADDR_SIZE, PIOP(base));	/* byte count lsb */
-  outb(0, PIOP(base));			/* byte count msb */
-  outsb(PIOP(base), &dev->dev_addr[0], WAVELAN_ADDR_SIZE);
-
-  /* reset transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup",
-		   OP0_IA_SETUP, SR0_IA_SETUP_DONE))
-    ret = FALSE;
-
-#ifdef WAVELAN_ROAMING
-    /* If roaming is enabled, join the "Beacon Request" multicast group... */
-    /* But only if it's not in there already! */
-  if(do_roaming)
-    dev_mc_add(dev,WAVELAN_BEACON_ADDRESS, WAVELAN_ADDR_SIZE, 1);
-#endif	/* WAVELAN_ROAMING */
-
-  /* If any multicast address to set */
-  if(lp->mc_count)
-    {
-      struct dev_mc_list *	dmi;
-      int			addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
-
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
-	     dev->name, lp->mc_count);
-      for(dmi=dev->mc_list; dmi; dmi=dmi->next)
-	printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
-#endif
-
-      /* Initialize adapter's ethernet multicast addresses */
-      outb(TX_BASE & 0xff, PIORL(base));
-      outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-      outb(addrs_len & 0xff, PIOP(base));	/* byte count lsb */
-      outb((addrs_len >> 8), PIOP(base));	/* byte count msb */
-      for(dmi=dev->mc_list; dmi; dmi=dmi->next)
-	outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen);
-
-      /* reset transmit DMA pointer */
-      hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-      hacr_write(base, HACR_DEFAULT);
-      if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
-		       OP0_MC_SETUP, SR0_MC_SETUP_DONE))
-	ret = FALSE;
-      lp->mc_count = dev->mc_count;	/* remember to avoid repeated reset */
-    }
-
-  /* Job done, clear the flag */
-  lp->reconfig_82593 = FALSE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name);
-#endif
-  return(ret);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Access Configuration Register, perform a software reset,
- * and then re-enable the card's software.
- *
- * If I understand correctly : reset the pcmcia interface of the
- * wavelan.
- * (called by wv_config())
- */
-static int
-wv_pcmcia_reset(struct net_device *	dev)
-{
-  int		i;
-  conf_reg_t	reg = { 0, CS_READ, CISREG_COR, 0 };
-  struct pcmcia_device *	link = ((net_local *)netdev_priv(dev))->link;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
-#endif
-
-  i = pcmcia_access_configuration_register(link, &reg);
-  if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
-      return FALSE;
-    }
-      
-#ifdef DEBUG_CONFIG_INFO
-  printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
-	 dev->name, (u_int) reg.Value);
-#endif
-
-  reg.Action = CS_WRITE;
-  reg.Value = reg.Value | COR_SW_RESET;
-  i = pcmcia_access_configuration_register(link, &reg);
-  if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
-      return FALSE;
-    }
-      
-  reg.Action = CS_WRITE;
-  reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
-  i = pcmcia_access_configuration_register(link, &reg);
-  if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
-      return FALSE;
-    }
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * wavelan_hw_config() is called after a CARD_INSERTION event is
- * received, to configure the wavelan hardware.
- * Note that the reception will be enabled in wavelan->open(), so the
- * device is configured but idle...
- * Performs the following actions:
- * 	1. A pcmcia software reset (using wv_pcmcia_reset())
- *	2. A power reset (reset DMA)
- *	3. Reset the LAN controller
- *	4. Initialize the radio modem (using wv_mmc_init)
- *	5. Configure LAN controller (using wv_82593_config)
- *	6. Perform a diagnostic on the LAN controller
- * (called by wavelan_event() & wv_hw_reset())
- */
-static int
-wv_hw_config(struct net_device *	dev)
-{
-  net_local *		lp = netdev_priv(dev);
-  unsigned int		base = dev->base_addr;
-  unsigned long		flags;
-  int			ret = FALSE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
-#endif
-
-  /* compile-time check the sizes of structures */
-  BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
-  BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
-  BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
-
-  /* Reset the pcmcia interface */
-  if(wv_pcmcia_reset(dev) == FALSE)
-    return FALSE;
-
-  /* Disable interrupts */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Disguised goto ;-) */
-  do
-    {
-      /* Power UP the module + reset the modem + reset host adapter
-       * (in fact, reset DMA channels) */
-      hacr_write_slow(base, HACR_RESET);
-      hacr_write(base, HACR_DEFAULT);
-
-      /* Check if the module has been powered up... */
-      if(hasr_read(base) & HASR_NO_CLK)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
-		 dev->name);
-#endif
-	  break;
-	}
-
-      /* initialize the modem */
-      if(wv_mmc_init(dev) == FALSE)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n",
-		 dev->name);
-#endif
-	  break;
-	}
-
-      /* reset the LAN controller (i82593) */
-      outb(OP0_RESET, LCCR(base));
-      mdelay(1);	/* A bit crude ! */
-
-      /* Initialize the LAN controller */
-      if(wv_82593_config(dev) == FALSE)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n",
-		 dev->name);
-#endif
-	  break;
-	}
-
-      /* Diagnostic */
-      if(wv_diag(dev) == FALSE)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n",
-		 dev->name);
-#endif
-	  break;
-	}
-
-      /* 
-       * insert code for loopback test here
-       */
-
-      /* The device is now configured */
-      lp->configured = 1;
-      ret = TRUE;
-    }
-  while(0);
-
-  /* Re-enable interrupts */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
-#endif
-  return(ret);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Totally reset the wavelan and restart it.
- * Performs the following actions:
- * 	1. Call wv_hw_config()
- *	2. Start the LAN controller's receive unit
- * (called by wavelan_event(), wavelan_watchdog() and wavelan_open())
- */
-static void
-wv_hw_reset(struct net_device *	dev)
-{
-  net_local *	lp = netdev_priv(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name);
-#endif
-
-  lp->nresets++;
-  lp->configured = 0;
-  
-  /* Call wv_hw_config() for most of the reset & init stuff */
-  if(wv_hw_config(dev) == FALSE)
-    return;
-
-  /* start receive unit */
-  wv_ru_start(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * wv_pcmcia_config() is called after a CARD_INSERTION event is
- * received, to configure the PCMCIA socket, and to make the ethernet
- * device available to the system.
- * (called by wavelan_event())
- */
-static int
-wv_pcmcia_config(struct pcmcia_device *	link)
-{
-  struct net_device *	dev = (struct net_device *) link->priv;
-  int			i;
-  win_req_t		req;
-  memreq_t		mem;
-  net_local *		lp = netdev_priv(dev);
-
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
-#endif
-
-  do
-    {
-      i = pcmcia_request_io(link, &link->io);
-      if (i != 0)
-	{
-	  cs_error(link, RequestIO, i);
-	  break;
-	}
-
-      /*
-       * Now allocate an interrupt line.  Note that this does not
-       * actually assign a handler to the interrupt.
-       */
-      i = pcmcia_request_irq(link, &link->irq);
-      if (i != 0)
-	{
-	  cs_error(link, RequestIRQ, i);
-	  break;
-	}
-
-      /*
-       * This actually configures the PCMCIA socket -- setting up
-       * the I/O windows and the interrupt mapping.
-       */
-      link->conf.ConfigIndex = 1;
-      i = pcmcia_request_configuration(link, &link->conf);
-      if (i != 0)
-	{
-	  cs_error(link, RequestConfiguration, i);
-	  break;
-	}
-
-      /*
-       * Allocate a small memory window.  Note that the struct pcmcia_device
-       * structure provides space for one window handle -- if your
-       * device needs several windows, you'll need to keep track of
-       * the handles in your private data structure, link->priv.
-       */
-      req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
-      req.Base = req.Size = 0;
-      req.AccessSpeed = mem_speed;
-      i = pcmcia_request_window(&link, &req, &link->win);
-      if (i != 0)
-	{
-	  cs_error(link, RequestWindow, i);
-	  break;
-	}
-
-      lp->mem = ioremap(req.Base, req.Size);
-      dev->mem_start = (u_long)lp->mem;
-      dev->mem_end = dev->mem_start + req.Size;
-
-      mem.CardOffset = 0; mem.Page = 0;
-      i = pcmcia_map_mem_page(link->win, &mem);
-      if (i != 0)
-	{
-	  cs_error(link, MapMemPage, i);
-	  break;
-	}
-
-      /* Feed device with this info... */
-      dev->irq = link->irq.AssignedIRQ;
-      dev->base_addr = link->io.BasePort1;
-      netif_start_queue(dev);
-
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
-	     lp->mem, dev->irq, (u_int) dev->base_addr);
-#endif
-
-      SET_NETDEV_DEV(dev, &handle_to_dev(link));
-      i = register_netdev(dev);
-      if(i != 0)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_INFO "wv_pcmcia_config(): register_netdev() failed\n");
-#endif
-	  break;
-	}
-    }
-  while(0);		/* Humm... Disguised goto !!! */
-
-  /* If any step failed, release any partially configured state */
-  if(i != 0)
-    {
-      wv_pcmcia_release(link);
-      return FALSE;
-    }
-
-  strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
-  link->dev_node = &((net_local *) netdev_priv(dev))->node;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * After a card is removed, wv_pcmcia_release() will unregister the net
- * device, and release the PCMCIA configuration.  If the device is
- * still open, this will be postponed until it is closed.
- */
-static void
-wv_pcmcia_release(struct pcmcia_device *link)
-{
-	struct net_device *	dev = (struct net_device *) link->priv;
-	net_local *		lp = netdev_priv(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
-#endif
-
-	iounmap(lp->mem);
-	pcmcia_disable_device(link);
-
-#ifdef DEBUG_CONFIG_TRACE
-	printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
-#endif
-}
-
-/************************ INTERRUPT HANDLING ************************/
-
-/*
- * This function is the interrupt handler for the WaveLAN card. This
- * routine will be called whenever: 
- *	1. A packet is received.
- *	2. A packet has successfully been transferred and the unit is
- *	   ready to transmit another packet.
- *	3. A command has completed execution.
- */
-static irqreturn_t
-wavelan_interrupt(int		irq,
-		  void *	dev_id)
-{
-  struct net_device *	dev = dev_id;
-  net_local *	lp;
-  unsigned int	base;
-  int		status0;
-  u_int		tx_status;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
-#endif
-
-  lp = netdev_priv(dev);
-  base = dev->base_addr;
-
-#ifdef DEBUG_INTERRUPT_INFO
-  /* Check state of our spinlock (it should be cleared) */
-  if(spin_is_locked(&lp->spinlock))
-    printk(KERN_DEBUG
-	   "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
-	   dev->name);
-#endif
-
-  /* Prevent reentrancy. We need to do that because we may have
-   * multiple interrupt handler running concurently.
-   * It is safe because interrupts are disabled before aquiring
-   * the spinlock. */
-  spin_lock(&lp->spinlock);
-
-  /* Treat all pending interrupts */
-  while(1)
-    {
-      /* ---------------- INTERRUPT CHECKING ---------------- */
-      /*
-       * Look for the interrupt and verify the validity
-       */
-      outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
-      status0 = inb(LCSR(base));
-
-#ifdef DEBUG_INTERRUPT_INFO
-      printk(KERN_DEBUG "status0 0x%x [%s => 0x%x]", status0, 
-	     (status0&SR0_INTERRUPT)?"int":"no int",status0&~SR0_INTERRUPT);
-      if(status0&SR0_INTERRUPT)
-	{
-	  printk(" [%s => %d]\n", (status0 & SR0_CHNL) ? "chnl" :
-		 ((status0 & SR0_EXECUTION) ? "cmd" :
-		  ((status0 & SR0_RECEPTION) ? "recv" : "unknown")),
-		 (status0 & SR0_EVENT_MASK));
-	}
-      else
-	printk("\n");
-#endif
-
-      /* Return if no actual interrupt from i82593 (normal exit) */
-      if(!(status0 & SR0_INTERRUPT))
-	break;
-
-      /* If interrupt is both Rx and Tx or none...
-       * This code in fact is there to catch the spurious interrupt
-       * when you remove the wavelan pcmcia card from the socket */
-      if(((status0 & SR0_BOTH_RX_TX) == SR0_BOTH_RX_TX) ||
-	 ((status0 & SR0_BOTH_RX_TX) == 0x0))
-	{
-#ifdef DEBUG_INTERRUPT_INFO
-	  printk(KERN_INFO "%s: wv_interrupt(): bogus interrupt (or from dead card) : %X\n",
-		 dev->name, status0);
-#endif
-	  /* Acknowledge the interrupt */
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-	  break;
-	}
-
-      /* ----------------- RECEIVING PACKET ----------------- */
-      /*
-       * When the wavelan signal the reception of a new packet,
-       * we call wv_packet_rcv() to copy if from the buffer and
-       * send it to NET3
-       */
-      if(status0 & SR0_RECEPTION)
-	{
-#ifdef DEBUG_INTERRUPT_INFO
-	  printk(KERN_DEBUG "%s: wv_interrupt(): receive\n", dev->name);
-#endif
-
-	  if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT)
-	    {
-#ifdef DEBUG_INTERRUPT_ERROR
-	      printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
-		     dev->name);
-#endif
-	      dev->stats.rx_over_errors++;
-	      lp->overrunning = 1;
-      	    }
-
-	  /* Get the packet */
-	  wv_packet_rcv(dev);
-	  lp->overrunning = 0;
-
-	  /* Acknowledge the interrupt */
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-	  continue;
-    	}
-
-      /* ---------------- COMMAND COMPLETION ---------------- */
-      /*
-       * Interrupts issued when the i82593 has completed a command.
-       * Most likely : transmission done
-       */
-
-      /* If a transmission has been done */
-      if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
-	 (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
-	 (status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
-	{
-#ifdef DEBUG_TX_ERROR
-	  if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
-	    printk(KERN_INFO "%s: wv_interrupt(): packet transmitted without CRC.\n",
-		   dev->name);
-#endif
-
-	  /* Get transmission status */
-	  tx_status = inb(LCSR(base));
-	  tx_status |= (inb(LCSR(base)) << 8);
-#ifdef DEBUG_INTERRUPT_INFO
-	  printk(KERN_DEBUG "%s: wv_interrupt(): transmission done\n",
-		 dev->name);
-	  {
-	    u_int	rcv_bytes;
-	    u_char	status3;
-	    rcv_bytes = inb(LCSR(base));
-	    rcv_bytes |= (inb(LCSR(base)) << 8);
-	    status3 = inb(LCSR(base));
-	    printk(KERN_DEBUG "tx_status 0x%02x rcv_bytes 0x%02x status3 0x%x\n",
-		   tx_status, rcv_bytes, (u_int) status3);
-	  }
-#endif
-	  /* Check for possible errors */
-	  if((tx_status & TX_OK) != TX_OK)
-	    {
-	      dev->stats.tx_errors++;
-
-	      if(tx_status & TX_FRTL)
-		{
-#ifdef DEBUG_TX_ERROR
-		  printk(KERN_INFO "%s: wv_interrupt(): frame too long\n",
-			 dev->name);
-#endif
-		}
-	      if(tx_status & TX_UND_RUN)
-		{
-#ifdef DEBUG_TX_FAIL
-		  printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
-			 dev->name);
-#endif
-		  dev->stats.tx_aborted_errors++;
-		}
-	      if(tx_status & TX_LOST_CTS)
-		{
-#ifdef DEBUG_TX_FAIL
-		  printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
-#endif
-		  dev->stats.tx_carrier_errors++;
-		}
-	      if(tx_status & TX_LOST_CRS)
-		{
-#ifdef DEBUG_TX_FAIL
-		  printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
-			 dev->name);
-#endif
-		  dev->stats.tx_carrier_errors++;
-		}
-	      if(tx_status & TX_HRT_BEAT)
-		{
-#ifdef DEBUG_TX_FAIL
-		  printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
-#endif
-		  dev->stats.tx_heartbeat_errors++;
-		}
-	      if(tx_status & TX_DEFER)
-		{
-#ifdef DEBUG_TX_FAIL
-		  printk(KERN_DEBUG "%s: wv_interrupt(): channel jammed\n",
-			 dev->name);
-#endif
-		}
-	      /* Ignore late collisions since they're more likely to happen
-	       * here (the WaveLAN design prevents the LAN controller from
-	       * receiving while it is transmitting). We take action only when
-	       * the maximum retransmit attempts is exceeded.
-	       */
-	      if(tx_status & TX_COLL)
-		{
-		  if(tx_status & TX_MAX_COL)
-		    {
-#ifdef DEBUG_TX_FAIL
-		      printk(KERN_DEBUG "%s: wv_interrupt(): channel congestion\n",
-			     dev->name);
-#endif
-		      if(!(tx_status & TX_NCOL_MASK))
-			{
-			  dev->stats.collisions += 0x10;
-			}
-		    }
-		}
-	    }	/* if(!(tx_status & TX_OK)) */
-
-	  dev->stats.collisions += (tx_status & TX_NCOL_MASK);
-	  dev->stats.tx_packets++;
-
-	  netif_wake_queue(dev);
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));	/* Acknowledge the interrupt */
-    	} 
-      else	/* if interrupt = transmit done or retransmit done */
-	{
-#ifdef DEBUG_INTERRUPT_ERROR
-	  printk(KERN_INFO "wavelan_cs: unknown interrupt, status0 = %02x\n",
-		 status0);
-#endif
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));	/* Acknowledge the interrupt */
-    	}
-    }	/* while(1) */
-
-  spin_unlock(&lp->spinlock);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
-#endif
-
-  /* We always return IRQ_HANDLED, because we will receive empty
-   * interrupts under normal operations. Anyway, it doesn't matter
-   * as we are dealing with an ISA interrupt that can't be shared.
-   *
-   * Explanation : under heavy receive, the following happens :
-   * ->wavelan_interrupt()
-   *    (status0 & SR0_INTERRUPT) != 0
-   *       ->wv_packet_rcv()
-   *    (status0 & SR0_INTERRUPT) != 0
-   *       ->wv_packet_rcv()
-   *    (status0 & SR0_INTERRUPT) == 0	// i.e. no more event
-   * <-wavelan_interrupt()
-   * ->wavelan_interrupt()
-   *    (status0 & SR0_INTERRUPT) == 0	// i.e. empty interrupt
-   * <-wavelan_interrupt()
-   * Jean II */
-  return IRQ_HANDLED;
-} /* wv_interrupt */
-
-/*------------------------------------------------------------------*/
-/*
- * Watchdog: when we start a transmission, a timer is set for us in the
- * kernel.  If the transmission completes, this timer is disabled. If
- * the timer expires, we are called and we try to unlock the hardware.
- *
- * Note : This watchdog is move clever than the one in the ISA driver,
- * because it try to abort the current command before reseting
- * everything...
- * On the other hand, it's a bit simpler, because we don't have to
- * deal with the multiple Tx buffers...
- */
-static void
-wavelan_watchdog(struct net_device *	dev)
-{
-  net_local *		lp = netdev_priv(dev);
-  unsigned int		base = dev->base_addr;
-  unsigned long		flags;
-  int			aborted = FALSE;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
-#endif
-
-#ifdef DEBUG_INTERRUPT_ERROR
-  printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
-	 dev->name);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Ask to abort the current command */
-  outb(OP0_ABORT, LCCR(base));
-
-  /* Wait for the end of the command (a bit hackish) */
-  if(wv_82593_cmd(dev, "wavelan_watchdog(): abort",
-		  OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED))
-    aborted = TRUE;
-
-  /* Release spinlock here so that wv_hw_reset() can grab it */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  /* Check if we were successful in aborting it */
-  if(!aborted)
-    {
-      /* It seem that it wasn't enough */
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "%s: wavelan_watchdog: abort failed, trying reset\n",
-	     dev->name);
-#endif
-      wv_hw_reset(dev);
-    }
-
-#ifdef DEBUG_PSA_SHOW
-  {
-    psa_t		psa;
-    psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-    wv_psa_show(&psa);
-  }
-#endif
-#ifdef DEBUG_MMC_SHOW
-  wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82593_SHOW
-  wv_ru_show(dev);
-#endif
-
-  /* We are no more waiting for something... */
-  netif_wake_queue(dev);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
-#endif
-}
-
-/********************* CONFIGURATION CALLBACKS *********************/
-/*
- * Here are the functions called by the pcmcia package (cardmgr) and
- * linux networking (NET3) for initialization, configuration and
- * deinstallations of the Wavelan Pcmcia Hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Configure and start up the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "open" the device.
- */
-static int
-wavelan_open(struct net_device *	dev)
-{
-  net_local *	lp = netdev_priv(dev);
-  struct pcmcia_device *	link = lp->link;
-  unsigned int	base = dev->base_addr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
-	 (unsigned int) dev);
-#endif
-
-  /* Check if the modem is powered up (wavelan_close() power it down */
-  if(hasr_read(base) & HASR_NO_CLK)
-    {
-      /* Power up (power up time is 250us) */
-      hacr_write(base, HACR_DEFAULT);
-
-      /* Check if the module has been powered up... */
-      if(hasr_read(base) & HASR_NO_CLK)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_WARNING "%s: wavelan_open(): modem not connected\n",
-		 dev->name);
-#endif
-	  return FALSE;
-	}
-    }
-
-  /* Start reception and declare the driver ready */
-  if(!lp->configured)
-    return FALSE;
-  if(!wv_ru_start(dev))
-    wv_hw_reset(dev);		/* If problem : reset */
-  netif_start_queue(dev);
-
-  /* Mark the device as used */
-  link->open++;
-
-#ifdef WAVELAN_ROAMING
-  if(do_roaming)
-    wv_roam_init(dev);
-#endif	/* WAVELAN_ROAMING */
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
-#endif
-  return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Shutdown the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "close" the device.
- */
-static int
-wavelan_close(struct net_device *	dev)
-{
-  struct pcmcia_device *	link = ((net_local *)netdev_priv(dev))->link;
-  unsigned int	base = dev->base_addr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
-	 (unsigned int) dev);
-#endif
-
-  /* If the device isn't open, then nothing to do */
-  if(!link->open)
-    {
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "%s: wavelan_close(): device not open\n", dev->name);
-#endif
-      return 0;
-    }
-
-#ifdef WAVELAN_ROAMING
-  /* Cleanup of roaming stuff... */
-  if(do_roaming)
-    wv_roam_cleanup(dev);
-#endif	/* WAVELAN_ROAMING */
-
-  link->open--;
-
-  /* If the card is still present */
-  if(netif_running(dev))
-    {
-      netif_stop_queue(dev);
-
-      /* Stop receiving new messages and wait end of transmission */
-      wv_ru_stop(dev);
-
-      /* Power down the module */
-      hacr_write(base, HACR_DEFAULT & (~HACR_PWR_STAT));
-    }
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
-#endif
-  return 0;
-}
-
-static const struct net_device_ops wavelan_netdev_ops = {
-	.ndo_open 		= wavelan_open,
-	.ndo_stop		= wavelan_close,
-	.ndo_start_xmit		= wavelan_packet_xmit,
-	.ndo_set_multicast_list = wavelan_set_multicast_list,
-#ifdef SET_MAC_ADDRESS
-	.ndo_set_mac_address	= wavelan_set_mac_address,
-#endif
-	.ndo_tx_timeout		= wavelan_watchdog,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * wavelan_attach() creates an "instance" of the driver, allocating
- * local data structures for one device (one interface).  The device
- * is registered with Card Services.
- *
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a
- * card insertion event.
- */
-static int
-wavelan_probe(struct pcmcia_device *p_dev)
-{
-  struct net_device *	dev;		/* Interface generic data */
-  net_local *	lp;		/* Interface specific data */
-  int ret;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "-> wavelan_attach()\n");
-#endif
-
-  /* The io structure describes IO port mapping */
-  p_dev->io.NumPorts1 = 8;
-  p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-  p_dev->io.IOAddrLines = 3;
-
-  /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-  p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
-  p_dev->irq.Handler = wavelan_interrupt;
-
-  /* General socket configuration */
-  p_dev->conf.Attributes = CONF_ENABLE_IRQ;
-  p_dev->conf.IntType = INT_MEMORY_AND_IO;
-
-  /* Allocate the generic data structure */
-  dev = alloc_etherdev(sizeof(net_local));
-  if (!dev)
-      return -ENOMEM;
-
-  p_dev->priv = p_dev->irq.Instance = dev;
-
-  lp = netdev_priv(dev);
-
-  /* Init specific data */
-  lp->configured = 0;
-  lp->reconfig_82593 = FALSE;
-  lp->nresets = 0;
-  /* Multicast stuff */
-  lp->promiscuous = 0;
-  lp->allmulticast = 0;
-  lp->mc_count = 0;
-
-  /* Init spinlock */
-  spin_lock_init(&lp->spinlock);
-
-  /* back links */
-  lp->dev = dev;
-
-  /* wavelan NET3 callbacks */
-  dev->netdev_ops = &wavelan_netdev_ops;
-  dev->watchdog_timeo	= WATCHDOG_JIFFIES;
-  SET_ETHTOOL_OPS(dev, &ops);
-
-  dev->wireless_handlers = &wavelan_handler_def;
-  lp->wireless_data.spy_data = &lp->spy_data;
-  dev->wireless_data = &lp->wireless_data;
-
-  /* Other specific data */
-  dev->mtu = WAVELAN_MTU;
-
-  ret = wv_pcmcia_config(p_dev);
-  if (ret)
-	  return ret;
-
-  ret = wv_hw_config(dev);
-  if (ret) {
-	  dev->irq = 0;
-	  pcmcia_disable_device(p_dev);
-	  return ret;
-  }
-
-  wv_init_info(dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<- wavelan_attach()\n");
-#endif
-
-  return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This deletes a driver "instance".  The device is de-registered with
- * Card Services.  If it has been released, all local data structures
- * are freed.  Otherwise, the structures will be freed when the device
- * is released.
- */
-static void
-wavelan_detach(struct pcmcia_device *link)
-{
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
-#endif
-
-  /* Some others haven't done their job : give them another chance */
-  wv_pcmcia_release(link);
-
-  /* Free pieces */
-  if(link->priv)
-    {
-      struct net_device *	dev = (struct net_device *) link->priv;
-
-      /* Remove ourselves from the kernel list of ethernet devices */
-      /* Warning : can't be called from interrupt, timer or wavelan_close() */
-      if (link->dev_node)
-	unregister_netdev(dev);
-      link->dev_node = NULL;
-      ((net_local *)netdev_priv(dev))->link = NULL;
-      ((net_local *)netdev_priv(dev))->dev = NULL;
-      free_netdev(dev);
-    }
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<- wavelan_detach()\n");
-#endif
-}
-
-static int wavelan_suspend(struct pcmcia_device *link)
-{
-	struct net_device *	dev = (struct net_device *) link->priv;
-
-	/* NB: wavelan_close will be called, but too late, so we are
-	 * obliged to close nicely the wavelan here. David, could you
-	 * close the device before suspending them ? And, by the way,
-	 * could you, on resume, add a "route add -net ..." after the
-	 * ifconfig up ? Thanks... */
-
-	/* Stop receiving new messages and wait end of transmission */
-	wv_ru_stop(dev);
-
-	if (link->open)
-		netif_device_detach(dev);
-
-	/* Power down the module */
-	hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
-
-	return 0;
-}
-
-static int wavelan_resume(struct pcmcia_device *link)
-{
-	struct net_device *	dev = (struct net_device *) link->priv;
-
-	if (link->open) {
-		wv_hw_reset(dev);
-		netif_device_attach(dev);
-	}
-
-	return 0;
-}
-
-
-static struct pcmcia_device_id wavelan_ids[] = {
-	PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
-	PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
-	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975),
-	PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975),
-	PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, wavelan_ids);
-
-static struct pcmcia_driver wavelan_driver = {
-	.owner		= THIS_MODULE,
-	.drv		= {
-		.name	= "wavelan_cs",
-	},
-	.probe		= wavelan_probe,
-	.remove		= wavelan_detach,
-	.id_table       = wavelan_ids,
-	.suspend	= wavelan_suspend,
-	.resume		= wavelan_resume,
-};
-
-static int __init
-init_wavelan_cs(void)
-{
-	return pcmcia_register_driver(&wavelan_driver);
-}
-
-static void __exit
-exit_wavelan_cs(void)
-{
-	pcmcia_unregister_driver(&wavelan_driver);
-}
-
-module_init(init_wavelan_cs);
-module_exit(exit_wavelan_cs);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,386 +0,0 @@
-/*
- *	Wavelan Pcmcia driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganization and extension of the driver.
- * Original copyright follow. See wavelan_cs.h for details.
- *
- * This file contain the declarations of the Wavelan hardware. Note that
- * the Pcmcia Wavelan include a i82593 controller (see definitions in
- * file i82593.h).
- *
- * The main difference between the pcmcia hardware and the ISA one is
- * the Ethernet Controller (i82593 instead of i82586). The i82593 allow
- * only one send buffer. The PSA (Parameter Storage Area : EEprom for
- * permanent storage of various info) is memory mapped, but not the
- * MMI (Modem Management Interface).
- */
-
-/*
- * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card: 
- *   An Ethernet-like radio transceiver controlled by an Intel 82593
- *   coprocessor.
- *
- *
- ****************************************************************************
- *   Copyright 1995
- *   Anthony D. Joseph
- *   Massachusetts Institute of Technology
- *
- *   Permission to use, copy, modify, and distribute this program
- *   for any purpose and without fee is hereby granted, provided
- *   that this copyright and permission notice appear on all copies
- *   and supporting documentation, the name of M.I.T. not be used
- *   in advertising or publicity pertaining to distribution of the
- *   program without specific prior permission, and notice be given
- *   in supporting documentation that copying and distribution is
- *   by permission of M.I.T.  M.I.T. makes no representations about
- *   the suitability of this software for any purpose.  It is pro-
- *   vided "as is" without express or implied warranty.         
- ****************************************************************************
- *
- *
- * Credits:
- *     Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht for
- *       providing extremely useful information about WaveLAN PCMCIA hardware
- *
- *     This driver is based upon several other drivers, in particular:
- *       David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
- *       Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
- *	 Anders Klemets' PCMCIA WaveLAN adapter driver
- *       Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
- */
-
-#ifndef _WAVELAN_CS_H
-#define	_WAVELAN_CS_H
-
-/************************** MAGIC NUMBERS ***************************/
-
-/* The detection of the wavelan card is made by reading the MAC address
- * from the card and checking it. If you have a non AT&T product (OEM,
- * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
- * part to accommodate your hardware...
- */
-static const unsigned char	MAC_ADDRESSES[][3] =
-{
-  { 0x08, 0x00, 0x0E },		/* AT&T Wavelan (standard) & DEC RoamAbout */
-  { 0x08, 0x00, 0x6A },		/* AT&T Wavelan (alternate) */
-  { 0x00, 0x00, 0xE1 },		/* Hitachi Wavelan */
-  { 0x00, 0x60, 0x1D }		/* Lucent Wavelan (another one) */
-  /* Add your card here and send me the patch ! */
-};
-
-/*
- * Constants used to convert channels to frequencies
- */
-
-/* Frequency available in the 2.0 modem, in units of 250 kHz
- * (as read in the offset register of the dac area).
- * Used to map channel numbers used by `wfreqsel' to frequencies
- */
-static const short	channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
-				    0xD0, 0xF0, 0xF8, 0x150 };
-
-/* Frequencies of the 1.0 modem (fixed frequencies).
- * Use to map the PSA `subband' to a frequency
- * Note : all frequencies apart from the first one need to be multiplied by 10
- */
-static const int	fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
-
-
-/*************************** PC INTERFACE ****************************/
-
-/* WaveLAN host interface definitions */
-
-#define	LCCR(base)	(base)		/* LAN Controller Command Register */
-#define	LCSR(base)	(base)		/* LAN Controller Status Register */
-#define	HACR(base)	(base+0x1)	/* Host Adapter Command Register */
-#define	HASR(base)	(base+0x1)	/* Host Adapter Status Register */
-#define PIORL(base)	(base+0x2)	/* Program I/O Register Low */
-#define RPLL(base)	(base+0x2)	/* Receive Pointer Latched Low */
-#define PIORH(base)	(base+0x3)	/* Program I/O Register High */
-#define RPLH(base)	(base+0x3)	/* Receive Pointer Latched High */
-#define PIOP(base)	(base+0x4)	/* Program I/O Port */
-#define MMR(base)	(base+0x6)	/* MMI Address Register */
-#define MMD(base)	(base+0x7)	/* MMI Data Register */
-
-/* Host Adaptor Command Register bit definitions */
-
-#define HACR_LOF	  (1 << 3)	/* Lock Out Flag, toggle every 250ms */
-#define HACR_PWR_STAT	  (1 << 4)	/* Power State, 1=active, 0=sleep */
-#define HACR_TX_DMA_RESET (1 << 5)	/* Reset transmit DMA ptr on high */
-#define HACR_RX_DMA_RESET (1 << 6)	/* Reset receive DMA ptr on high */
-#define HACR_ROM_WEN	  (1 << 7)	/* EEPROM write enabled when true */
-
-#define HACR_RESET              (HACR_TX_DMA_RESET | HACR_RX_DMA_RESET)
-#define	HACR_DEFAULT		(HACR_PWR_STAT)
-
-/* Host Adapter Status Register bit definitions */
-
-#define HASR_MMI_BUSY	(1 << 2)	/* MMI is busy when true */
-#define HASR_LOF	(1 << 3)	/* Lock out flag status */
-#define HASR_NO_CLK	(1 << 4)	/* active when modem not connected */
-
-/* Miscellaneous bit definitions */
-
-#define PIORH_SEL_TX	(1 << 5)	/* PIOR points to 0=rx/1=tx buffer */
-#define MMR_MMI_WR	(1 << 0)	/* Next MMI cycle is 0=read, 1=write */
-#define PIORH_MASK	0x1f		/* only low 5 bits are significant */
-#define RPLH_MASK	0x1f		/* only low 5 bits are significant */
-#define MMI_ADDR_MASK	0x7e		/* Bits 1-6 of MMR are significant */
-
-/* Attribute Memory map */
-
-#define CIS_ADDR	0x0000		/* Card Information Status Register */
-#define PSA_ADDR	0x0e00		/* Parameter Storage Area address */
-#define EEPROM_ADDR	0x1000		/* EEPROM address (unused ?) */
-#define COR_ADDR	0x4000		/* Configuration Option Register */
-
-/* Configuration Option Register bit definitions */
-
-#define COR_CONFIG	(1 << 0)	/* Config Index, 0 when unconfigured */
-#define COR_SW_RESET	(1 << 7)	/* Software Reset on true */
-#define COR_LEVEL_IRQ	(1 << 6)	/* Level IRQ */
-
-/* Local Memory map */
-
-#define RX_BASE		0x0000		/* Receive memory, 8 kB */
-#define TX_BASE		0x2000		/* Transmit memory, 2 kB */
-#define UNUSED_BASE	0x2800		/* Unused, 22 kB */
-#define RX_SIZE		(TX_BASE-RX_BASE)	/* Size of receive area */
-#define RX_SIZE_SHIFT	6		/* Bits to shift in stop register */
-
-#define TRUE  1
-#define FALSE 0
-
-#define MOD_ENAL 1
-#define MOD_PROM 2
-
-/* Size of a MAC address */
-#define WAVELAN_ADDR_SIZE	6
-
-/* Maximum size of Wavelan packet */
-#define WAVELAN_MTU	1500
-
-#define	MAXDATAZ		(6 + 6 + 2 + WAVELAN_MTU)
-
-/********************** PARAMETER STORAGE AREA **********************/
-
-/*
- * Parameter Storage Area (PSA).
- */
-typedef struct psa_t	psa_t;
-struct psa_t
-{
-  /* For the PCMCIA Adapter, locations 0x00-0x0F are unused and fixed at 00 */
-  unsigned char	psa_io_base_addr_1;	/* [0x00] Base address 1 ??? */
-  unsigned char	psa_io_base_addr_2;	/* [0x01] Base address 2 */
-  unsigned char	psa_io_base_addr_3;	/* [0x02] Base address 3 */
-  unsigned char	psa_io_base_addr_4;	/* [0x03] Base address 4 */
-  unsigned char	psa_rem_boot_addr_1;	/* [0x04] Remote Boot Address 1 */
-  unsigned char	psa_rem_boot_addr_2;	/* [0x05] Remote Boot Address 2 */
-  unsigned char	psa_rem_boot_addr_3;	/* [0x06] Remote Boot Address 3 */
-  unsigned char	psa_holi_params;	/* [0x07] HOst Lan Interface (HOLI) Parameters */
-  unsigned char	psa_int_req_no;		/* [0x08] Interrupt Request Line */
-  unsigned char	psa_unused0[7];		/* [0x09-0x0F] unused */
-
-  unsigned char	psa_univ_mac_addr[WAVELAN_ADDR_SIZE];	/* [0x10-0x15] Universal (factory) MAC Address */
-  unsigned char	psa_local_mac_addr[WAVELAN_ADDR_SIZE];	/* [0x16-1B] Local MAC Address */
-  unsigned char	psa_univ_local_sel;	/* [0x1C] Universal Local Selection */
-#define		PSA_UNIVERSAL	0		/* Universal (factory) */
-#define		PSA_LOCAL	1		/* Local */
-  unsigned char	psa_comp_number;	/* [0x1D] Compatability Number: */
-#define		PSA_COMP_PC_AT_915	0 	/* PC-AT 915 MHz	*/
-#define		PSA_COMP_PC_MC_915	1 	/* PC-MC 915 MHz	*/
-#define		PSA_COMP_PC_AT_2400	2 	/* PC-AT 2.4 GHz	*/
-#define		PSA_COMP_PC_MC_2400	3 	/* PC-MC 2.4 GHz	*/
-#define		PSA_COMP_PCMCIA_915	4 	/* PCMCIA 915 MHz or 2.0 */
-  unsigned char	psa_thr_pre_set;	/* [0x1E] Modem Threshold Preset */
-  unsigned char	psa_feature_select;	/* [0x1F] Call code required (1=on) */
-#define		PSA_FEATURE_CALL_CODE	0x01 	/* Call code required (Japan) */
-  unsigned char	psa_subband;		/* [0x20] Subband	*/
-#define		PSA_SUBBAND_915		0	/* 915 MHz or 2.0 */
-#define		PSA_SUBBAND_2425	1	/* 2425 MHz	*/
-#define		PSA_SUBBAND_2460	2	/* 2460 MHz	*/
-#define		PSA_SUBBAND_2484	3	/* 2484 MHz	*/
-#define		PSA_SUBBAND_2430_5	4	/* 2430.5 MHz	*/
-  unsigned char	psa_quality_thr;	/* [0x21] Modem Quality Threshold */
-  unsigned char	psa_mod_delay;		/* [0x22] Modem Delay ??? (reserved) */
-  unsigned char	psa_nwid[2];		/* [0x23-0x24] Network ID */
-  unsigned char	psa_nwid_select;	/* [0x25] Network ID Select On Off */
-  unsigned char	psa_encryption_select;	/* [0x26] Encryption On Off */
-  unsigned char	psa_encryption_key[8];	/* [0x27-0x2E] Encryption Key */
-  unsigned char	psa_databus_width;	/* [0x2F] AT bus width select 8/16 */
-  unsigned char	psa_call_code[8];	/* [0x30-0x37] (Japan) Call Code */
-  unsigned char	psa_nwid_prefix[2];	/* [0x38-0x39] Roaming domain */
-  unsigned char	psa_reserved[2];	/* [0x3A-0x3B] Reserved - fixed 00 */
-  unsigned char	psa_conf_status;	/* [0x3C] Conf Status, bit 0=1:config*/
-  unsigned char	psa_crc[2];		/* [0x3D] CRC-16 over PSA */
-  unsigned char	psa_crc_status;		/* [0x3F] CRC Valid Flag */
-};
-
-/* Size for structure checking (if padding is correct) */
-#define	PSA_SIZE	64
-
-/* Calculate offset of a field in the above structure
- * Warning : only even addresses are used */
-#define	psaoff(p,f) 	((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
-
-/******************** MODEM MANAGEMENT INTERFACE ********************/
-
-/*
- * Modem Management Controller (MMC) write structure.
- */
-typedef struct mmw_t	mmw_t;
-struct mmw_t
-{
-  unsigned char	mmw_encr_key[8];	/* encryption key */
-  unsigned char	mmw_encr_enable;	/* enable/disable encryption */
-#define	MMW_ENCR_ENABLE_MODE	0x02	/* Mode of security option */
-#define	MMW_ENCR_ENABLE_EN	0x01	/* Enable security option */
-  unsigned char	mmw_unused0[1];		/* unused */
-  unsigned char	mmw_des_io_invert;	/* Encryption option */
-#define	MMW_DES_IO_INVERT_RES	0x0F	/* Reserved */
-#define	MMW_DES_IO_INVERT_CTRL	0xF0	/* Control ??? (set to 0) */
-  unsigned char	mmw_unused1[5];		/* unused */
-  unsigned char	mmw_loopt_sel;		/* looptest selection */
-#define	MMW_LOOPT_SEL_DIS_NWID	0x40	/* disable NWID filtering */
-#define	MMW_LOOPT_SEL_INT	0x20	/* activate Attention Request */
-#define	MMW_LOOPT_SEL_LS	0x10	/* looptest w/o collision avoidance */
-#define MMW_LOOPT_SEL_LT3A	0x08	/* looptest 3a */
-#define	MMW_LOOPT_SEL_LT3B	0x04	/* looptest 3b */
-#define	MMW_LOOPT_SEL_LT3C	0x02	/* looptest 3c */
-#define	MMW_LOOPT_SEL_LT3D	0x01	/* looptest 3d */
-  unsigned char	mmw_jabber_enable;	/* jabber timer enable */
-  /* Abort transmissions > 200 ms */
-  unsigned char	mmw_freeze;		/* freeze / unfreeeze signal level */
-  /* 0 : signal level & qual updated for every new message, 1 : frozen */
-  unsigned char	mmw_anten_sel;		/* antenna selection */
-#define MMW_ANTEN_SEL_SEL	0x01	/* direct antenna selection */
-#define	MMW_ANTEN_SEL_ALG_EN	0x02	/* antenna selection algo. enable */
-  unsigned char	mmw_ifs;		/* inter frame spacing */
-  /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
-  unsigned char	mmw_mod_delay;	 	/* modem delay (synchro) */
-  unsigned char	mmw_jam_time;		/* jamming time (after collision) */
-  unsigned char	mmw_unused2[1];		/* unused */
-  unsigned char	mmw_thr_pre_set;	/* level threshold preset */
-  /* Discard all packet with signal < this value (4) */
-  unsigned char	mmw_decay_prm;		/* decay parameters */
-  unsigned char	mmw_decay_updat_prm;	/* decay update parameterz */
-  unsigned char	mmw_quality_thr;	/* quality (z-quotient) threshold */
-  /* Discard all packet with quality < this value (3) */
-  unsigned char	mmw_netw_id_l;		/* NWID low order byte */
-  unsigned char	mmw_netw_id_h;		/* NWID high order byte */
-  /* Network ID or Domain : create virtual net on the air */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char	mmw_mode_select;	/* for analog tests (set to 0) */
-  unsigned char	mmw_unused3[1];		/* unused */
-  unsigned char	mmw_fee_ctrl;		/* frequency eeprom control */
-#define	MMW_FEE_CTRL_PRE	0x10	/* Enable protected instructions */
-#define	MMW_FEE_CTRL_DWLD	0x08	/* Download eeprom to mmc */
-#define	MMW_FEE_CTRL_CMD	0x07	/* EEprom commands : */
-#define	MMW_FEE_CTRL_READ	0x06	/* Read */
-#define	MMW_FEE_CTRL_WREN	0x04	/* Write enable */
-#define	MMW_FEE_CTRL_WRITE	0x05	/* Write data to address */
-#define	MMW_FEE_CTRL_WRALL	0x04	/* Write data to all addresses */
-#define	MMW_FEE_CTRL_WDS	0x04	/* Write disable */
-#define	MMW_FEE_CTRL_PRREAD	0x16	/* Read addr from protect register */
-#define	MMW_FEE_CTRL_PREN	0x14	/* Protect register enable */
-#define	MMW_FEE_CTRL_PRCLEAR	0x17	/* Unprotect all registers */
-#define	MMW_FEE_CTRL_PRWRITE	0x15	/* Write addr in protect register */
-#define	MMW_FEE_CTRL_PRDS	0x14	/* Protect register disable */
-  /* Never issue this command (PRDS) : it's irreversible !!! */
-
-  unsigned char	mmw_fee_addr;		/* EEprom address */
-#define	MMW_FEE_ADDR_CHANNEL	0xF0	/* Select the channel */
-#define	MMW_FEE_ADDR_OFFSET	0x0F	/* Offset in channel data */
-#define	MMW_FEE_ADDR_EN		0xC0	/* FEE_CTRL enable operations */
-#define	MMW_FEE_ADDR_DS		0x00	/* FEE_CTRL disable operations */
-#define	MMW_FEE_ADDR_ALL	0x40	/* FEE_CTRL all operations */
-#define	MMW_FEE_ADDR_CLEAR	0xFF	/* FEE_CTRL clear operations */
-
-  unsigned char	mmw_fee_data_l;		/* Write data to EEprom */
-  unsigned char	mmw_fee_data_h;		/* high octet */
-  unsigned char	mmw_ext_ant;		/* Setting for external antenna */
-#define	MMW_EXT_ANT_EXTANT	0x01	/* Select external antenna */
-#define	MMW_EXT_ANT_POL		0x02	/* Polarity of the antenna */
-#define	MMW_EXT_ANT_INTERNAL	0x00	/* Internal antenna */
-#define	MMW_EXT_ANT_EXTERNAL	0x03	/* External antenna */
-#define	MMW_EXT_ANT_IQ_TEST	0x1C	/* IQ test pattern (set to 0) */
-} __attribute__((packed));
-
-/* Size for structure checking (if padding is correct) */
-#define	MMW_SIZE	37
-
-/* Calculate offset of a field in the above structure */
-#define	mmwoff(p,f) 	(unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
-
-
-/*
- * Modem Management Controller (MMC) read structure.
- */
-typedef struct mmr_t	mmr_t;
-struct mmr_t
-{
-  unsigned char	mmr_unused0[8];		/* unused */
-  unsigned char	mmr_des_status;		/* encryption status */
-  unsigned char	mmr_des_avail;		/* encryption available (0x55 read) */
-#define	MMR_DES_AVAIL_DES	0x55		/* DES available */
-#define	MMR_DES_AVAIL_AES	0x33		/* AES (AT&T) available */
-  unsigned char	mmr_des_io_invert;	/* des I/O invert register */
-  unsigned char	mmr_unused1[5];		/* unused */
-  unsigned char	mmr_dce_status;		/* DCE status */
-#define	MMR_DCE_STATUS_RX_BUSY		0x01	/* receiver busy */
-#define	MMR_DCE_STATUS_LOOPT_IND	0x02	/* loop test indicated */
-#define	MMR_DCE_STATUS_TX_BUSY		0x04	/* transmitter on */
-#define	MMR_DCE_STATUS_JBR_EXPIRED	0x08	/* jabber timer expired */
-#define MMR_DCE_STATUS			0x0F	/* mask to get the bits */
-  unsigned char	mmr_dsp_id;		/* DSP id (AA = Daedalus rev A) */
-  unsigned char	mmr_unused2[2];		/* unused */
-  unsigned char	mmr_correct_nwid_l;	/* # of correct NWID's rxd (low) */
-  unsigned char	mmr_correct_nwid_h;	/* # of correct NWID's rxd (high) */
-  /* Warning : Read high order octet first !!! */
-  unsigned char	mmr_wrong_nwid_l;	/* # of wrong NWID's rxd (low) */
-  unsigned char	mmr_wrong_nwid_h;	/* # of wrong NWID's rxd (high) */
-  unsigned char	mmr_thr_pre_set;	/* level threshold preset */
-#define	MMR_THR_PRE_SET		0x3F		/* level threshold preset */
-#define	MMR_THR_PRE_SET_CUR	0x80		/* Current signal above it */
-  unsigned char	mmr_signal_lvl;		/* signal level */
-#define	MMR_SIGNAL_LVL		0x3F		/* signal level */
-#define	MMR_SIGNAL_LVL_VALID	0x80		/* Updated since last read */
-  unsigned char	mmr_silence_lvl;	/* silence level (noise) */
-#define	MMR_SILENCE_LVL		0x3F		/* silence level */
-#define	MMR_SILENCE_LVL_VALID	0x80		/* Updated since last read */
-  unsigned char	mmr_sgnl_qual;		/* signal quality */
-#define	MMR_SGNL_QUAL		0x0F		/* signal quality */
-#define	MMR_SGNL_QUAL_ANT	0x80		/* current antenna used */
-  unsigned char	mmr_netw_id_l;		/* NWID low order byte ??? */
-  unsigned char	mmr_unused3[3];		/* unused */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char	mmr_fee_status;		/* Status of frequency eeprom */
-#define	MMR_FEE_STATUS_ID	0xF0		/* Modem revision id */
-#define	MMR_FEE_STATUS_DWLD	0x08		/* Download in progress */
-#define	MMR_FEE_STATUS_BUSY	0x04		/* EEprom busy */
-  unsigned char	mmr_unused4[1];		/* unused */
-  unsigned char	mmr_fee_data_l;		/* Read data from eeprom (low) */
-  unsigned char	mmr_fee_data_h;		/* Read data from eeprom (high) */
-};
-
-/* Size for structure checking (if padding is correct) */
-#define	MMR_SIZE	36
-
-/* Calculate offset of a field in the above structure */
-#define	mmroff(p,f) 	(unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
-
-
-/* Make the two above structures one */
-typedef union mm_t
-{
-  struct mmw_t	w;	/* Write to the mmc */
-  struct mmr_t	r;	/* Read from the mmc */
-} mm_t;
-
-#endif /* _WAVELAN_CS_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.p.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.p.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan_cs.p.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan_cs.p.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,766 +0,0 @@
-/*
- *	Wavelan Pcmcia driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- *
- * This file contain all definition and declarations necessary for the
- * wavelan pcmcia driver. This file is a private header, so it should
- * be included only on wavelan_cs.c !!!
- */
-
-#ifndef WAVELAN_CS_P_H
-#define WAVELAN_CS_P_H
-
-/************************** DOCUMENTATION **************************/
-/*
- * This driver provide a Linux interface to the Wavelan Pcmcia hardware
- * The Wavelan is a product of Lucent (http://www.wavelan.com/).
- * This division was formerly part of NCR and then AT&T.
- * Wavelan are also distributed by DEC (RoamAbout DS)...
- *
- * To know how to use this driver, read the PCMCIA HOWTO.
- * If you want to exploit the many other fonctionalities, look comments
- * in the code...
- *
- * This driver is the result of the effort of many peoples (see below).
- */
-
-/* ------------------------ SPECIFIC NOTES ------------------------ */
-/*
- * Web page
- * --------
- *	I try to maintain a web page with the Wireless LAN Howto at :
- *	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
- *
- * SMP
- * ---
- *	We now are SMP compliant (I eventually fixed the remaining bugs).
- *	The driver has been tested on a dual P6-150 and survived my usual
- *	set of torture tests.
- *	Anyway, I spent enough time chasing interrupt re-entrancy during
- *	errors or reconfigure, and I designed the locked/unlocked sections
- *	of the driver with great care, and with the recent addition of
- *	the spinlock (thanks to the new API), we should be quite close to
- *	the truth.
- *	The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
- *	but better safe than sorry (especially at 2 Mb/s ;-).
- *
- *	I have also looked into disabling only our interrupt on the card
- *	(via HACR) instead of all interrupts in the processor (via cli),
- *	so that other driver are not impacted, and it look like it's
- *	possible, but it's very tricky to do right (full of races). As
- *	the gain would be mostly for SMP systems, it can wait...
- *
- * Debugging and options
- * ---------------------
- *	You will find below a set of '#define" allowing a very fine control
- *	on the driver behaviour and the debug messages printed.
- *	The main options are :
- *	o WAVELAN_ROAMING, for the experimental roaming support.
- *	o SET_PSA_CRC, to have your card correctly recognised by
- *	  an access point and the Point-to-Point diagnostic tool.
- *	o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
- *	  (otherwise we always start afresh with some defaults)
- *
- * wavelan_cs.o is darn too big
- * -------------------------
- *	That's true ! There is a very simple way to reduce the driver
- *	object by 33% (yes !). Comment out the following line :
- *		#include <linux/wireless.h>
- *	Other compile options can also reduce the size of it...
- *
- * MAC address and hardware detection :
- * ----------------------------------
- *	The detection code of the wavelan chech that the first 3
- *	octets of the MAC address fit the company code. This type of
- *	detection work well for AT&T cards (because the AT&T code is
- *	hardcoded in wavelan_cs.h), but of course will fail for other
- *	manufacturer.
- *
- *	If you are sure that your card is derived from the wavelan,
- *	here is the way to configure it :
- *	1) Get your MAC address
- *		a) With your card utilities (wfreqsel, instconf, ...)
- *		b) With the driver :
- *			o compile the kernel with DEBUG_CONFIG_INFO enabled
- *			o Boot and look the card messages
- *	2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan_cs.h)
- *	3) Compile & verify
- *	4) Send me the MAC code - I will include it in the next version...
- *
- */
-
-/* --------------------- WIRELESS EXTENSIONS --------------------- */
-/*
- * This driver is the first one to support "wireless extensions".
- * This set of extensions provide you some way to control the wireless
- * caracteristics of the hardware in a standard way and support for
- * applications for taking advantage of it (like Mobile IP).
- *
- * It might be a good idea as well to fetch the wireless tools to
- * configure the device and play a bit.
- */
-
-/* ---------------------------- FILES ---------------------------- */
-/*
- * wavelan_cs.c :	The actual code for the driver - C functions
- *
- * wavelan_cs.p.h :	Private header : local types / vars for the driver
- *
- * wavelan_cs.h :	Description of the hardware interface & structs
- *
- * i82593.h :		Description if the Ethernet controller
- */
-
-/* --------------------------- HISTORY --------------------------- */
-/*
- * The history of the Wavelan drivers is as complicated as history of
- * the Wavelan itself (NCR -> AT&T -> Lucent).
- *
- * All started with Anders Klemets <klemets@paul.rutgers.edu>,
- * writing a Wavelan ISA driver for the MACH microkernel. Girish
- * Welling <welling@paul.rutgers.edu> had also worked on it.
- * Keith Moore modify this for the Pcmcia hardware.
- * 
- * Robert Morris <rtm@das.harvard.edu> port these two drivers to BSDI
- * and add specific Pcmcia support (there is currently no equivalent
- * of the PCMCIA package under BSD...).
- *
- * Jim Binkley <jrb@cs.pdx.edu> port both BSDI drivers to FreeBSD.
- *
- * Bruce Janson <bruce@cs.usyd.edu.au> port the BSDI ISA driver to Linux.
- *
- * Anthony D. Joseph <adj@lcs.mit.edu> started modify Bruce driver
- * (with help of the BSDI PCMCIA driver) for PCMCIA.
- * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished is work.
- * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
- * correctly 2.00 cards (2.4 GHz with frequency selection).
- * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
- * Pcmcia package (+ bug corrections).
- *
- * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
- * patchs to the Pcmcia driver. After, I added code in the ISA driver
- * for Wireless Extensions and full support of frequency selection
- * cards. Now, I'm doing the same to the Pcmcia driver + some
- * reorganisation.
- * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
- * much needed informations on the Wavelan hardware.
- */
-
-/* By the way : for the copyright & legal stuff :
- * Almost everybody wrote code under GNU or BSD license (or alike),
- * and want that their original copyright remain somewhere in the
- * code (for myself, I go with the GPL).
- * Nobody want to take responsibility for anything, except the fame...
- */
-
-/* --------------------------- CREDITS --------------------------- */
-/*
- * Credits:
- *    Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht and
- *	Loeke Brederveld of Lucent for providing extremely useful
- *	information about WaveLAN PCMCIA hardware
- *
- *    This driver is based upon several other drivers, in particular:
- *	David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
- *	Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
- *	Anders Klemets' PCMCIA WaveLAN adapter driver
- *	Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
- *
- * Additional Credits:
- *
- *    This software was originally developed under Linux 1.2.3
- *	(Slackware 2.0 distribution).
- *    And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+)
- *	with an HP OmniBook 4000 and then a 5500.
- *
- *    It is based on other device drivers and information either written
- *    or supplied by:
- *	James Ashton (jaa101@syseng.anu.edu.au),
- *	Ajay Bakre (bakre@paul.rutgers.edu),
- *	Donald Becker (becker@super.org),
- *	Jim Binkley <jrb@cs.pdx.edu>,
- *	Loeke Brederveld <lbrederv@wavelan.com>,
- *	Allan Creighton (allanc@cs.su.oz.au),
- *	Brent Elphick <belphick@uwaterloo.ca>,
- *	Joe Finney <joe@comp.lancs.ac.uk>,
- *	Matthew Geier (matthew@cs.su.oz.au),
- *	Remo di Giovanni (remo@cs.su.oz.au),
- *	Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- *	David Hinds <dahinds@users.sourceforge.net>,
- *	Jan Hoogendoorn (c/o marteijn@lucent.com),
- *      Bruce Janson <bruce@cs.usyd.edu.au>,
- *	Anthony D. Joseph <adj@lcs.mit.edu>,
- *	Anders Klemets (klemets@paul.rutgers.edu),
- *	Yunzhou Li <yunzhou@strat.iol.unh.edu>,
- *	Marc Meertens (mmeertens@lucent.com),
- *	Keith Moore,
- *	Robert Morris (rtm@das.harvard.edu),
- *	Ian Parkin (ian@cs.su.oz.au),
- *	John Rosenberg (johnr@cs.su.oz.au),
- *	George Rossi (george@phm.gov.au),
- *	Arthur Scott (arthur@cs.su.oz.au),
- *	Stanislav Sinyagin <stas@isf.ru>
- *	Peter Storey,
- *	Jean Tourrilhes <jt@hpl.hp.com>,
- *	Girish Welling (welling@paul.rutgers.edu)
- *	Clark Woodworth <clark@hiway1.exit109.com>
- *	Yongguang Zhang <ygz@isl.hrl.hac.com>...
- */
-
-/* ------------------------- IMPROVEMENTS ------------------------- */
-/*
- * I proudly present :
- *
- * Changes made in 2.8.22 :
- * ----------------------
- *	- improved wv_set_multicast_list
- *	- catch spurious interrupt
- *	- correct release of the device
- *
- * Changes mades in release :
- * ------------------------
- *	- Reorganisation of the code, function name change
- *	- Creation of private header (wavelan_cs.h)
- *	- Reorganised debug messages
- *	- More comments, history, ...
- *	- Configure earlier (in "insert" instead of "open")
- *        and do things only once
- *	- mmc_init : configure the PSA if not done
- *	- mmc_init : 2.00 detection better code for 2.00 init
- *	- better info at startup
- *	- Correct a HUGE bug (volatile & uncalibrated busy loop)
- *	  in wv_82593_cmd => config speedup
- *	- Stop receiving & power down on close (and power up on open)
- *	  use "ifconfig down" & "ifconfig up ; route add -net ..."
- *	- Send packets : add watchdog instead of pooling
- *	- Receive : check frame wrap around & try to recover some frames
- *	- wavelan_set_multicast_list : avoid reset
- *	- add wireless extensions (ioctl & get_wireless_stats)
- *	  get/set nwid/frequency on fly, info for /proc/net/wireless
- *	- Suppress useless stuff from lp (net_local), but add link
- *	- More inlines
- *	- Lot of others minor details & cleanups
- *
- * Changes made in second release :
- * ------------------------------
- *	- Optimise wv_85893_reconfig stuff, fix potential problems
- *	- Change error values for ioctl
- *	- Non blocking wv_ru_stop() + call wv_reset() in case of problems
- *	- Remove development printk from wavelan_watchdog()
- *	- Remove of the watchdog to wavelan_close instead of wavelan_release
- *	  fix potential problems...
- *	- Start debugging suspend stuff (but it's still a bit weird)
- *	- Debug & optimize dump header/packet in Rx & Tx (debug)
- *	- Use "readb" and "writeb" to be kernel 2.1 compliant
- *	- Better handling of bogus interrupts
- *	- Wireless extension : SETSPY and GETSPY
- *	- Remove old stuff (stats - for those needing it, just ask me...)
- *	- Make wireless extensions optional
- *
- * Changes made in third release :
- * -----------------------------
- *	- cleanups & typos
- *	- modif wireless ext (spy -> only one pointer)
- *	- new private ioctl to set/get quality & level threshold
- *	- Init : correct default value of level threshold for pcmcia
- *	- kill watchdog in hw_reset
- *	- more 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
- *	- Add message level (debug stuff in /var/adm/debug & errors not
- *	  displayed at console and still in /var/adm/messages)
- *
- * Changes made in fourth release :
- * ------------------------------
- *	- multicast support (yes !) thanks to Yongguang Zhang.
- *
- * Changes made in fifth release (2.9.0) :
- * -------------------------------------
- *	- Revisited multicast code (it was mostly wrong).
- *	- protect code in wv_82593_reconfig with dev->tbusy (oups !)
- *
- * Changes made in sixth release (2.9.1a) :
- * --------------------------------------
- *	- Change the detection code for multi manufacturer code support
- *	- Correct bug (hang kernel) in init when we were "rejecting" a card 
- *
- * Changes made in seventh release (2.9.1b) :
- * ----------------------------------------
- *	- Update to wireless extensions changes
- *	- Silly bug in card initial configuration (psa_conf_status)
- *
- * Changes made in eigth release :
- * -----------------------------
- *	- Small bug in debug code (probably not the last one...)
- *	- 1.2.13 support (thanks to Clark Woodworth)
- *
- * Changes made for release in 2.9.2b :
- * ----------------------------------
- *	- Level threshold is now a standard wireless extension (version 4 !)
- *	- modules parameters types for kernel > 2.1.17
- *	- updated man page
- *	- Others cleanup from David Hinds
- *
- * Changes made for release in 2.9.5 :
- * ---------------------------------
- *	- byte count stats (courtesy of David Hinds)
- *	- Remove dev_tint stuff (courtesy of David Hinds)
- *	- Others cleanup from David Hinds
- *	- Encryption setting from Brent Elphick (thanks a lot !)
- *	- 'base' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
- *
- * Changes made for release in 2.9.6 :
- * ---------------------------------
- *	- fix bug : no longuer disable watchdog in case of bogus interrupt
- *	- increase timeout in config code for picky hardware
- *	- mask unused bits in status (Wireless Extensions)
- *
- * Changes integrated by Justin Seger <jseger@MIT.EDU> & David Hinds :
- * -----------------------------------------------------------------
- *	- Roaming "hack" from Joe Finney <joe@comp.lancs.ac.uk>
- *	- PSA CRC code from Bob Gray <rgray@bald.cs.dartmouth.edu>
- *	- Better initialisation of the i82593 controller
- *	  from Joseph K. O'Sullivan <josullvn+@cs.cmu.edu>
- *
- * Changes made for release in 3.0.10 :
- * ----------------------------------
- *	- Fix eject "hang" of the driver under 2.2.X :
- *		o create wv_flush_stale_links()
- *		o Rename wavelan_release to wv_pcmcia_release & move up
- *		o move unregister_netdev to wavelan_detach()
- *		o wavelan_release() no longer call wavelan_detach()
- *		o Suppress "release" timer
- *		o Other cleanups & fixes
- *	- New MAC address in the probe
- *	- Reorg PSA_CRC code (endian neutral & cleaner)
- *	- Correct initialisation of the i82593 from Lucent manual
- *	- Put back the watchdog, with larger timeout
- *	- TRANSMIT_NO_CRC is a "normal" error, so recover from it
- *	  from Derrick J Brashear <shadow@dementia.org>
- *	- Better handling of TX and RX normal failure conditions
- *	- #ifdef out all the roaming code
- *	- Add ESSID & "AP current address" ioctl stubs
- *	- General cleanup of the code
- *
- * Changes made for release in 3.0.13 :
- * ----------------------------------
- *	- Re-enable compilation of roaming code by default, but with
- *	  do_roaming = 0
- *	- Nuke `nwid=nwid^ntohs(beacon->domain_id)' in wl_roam_gather
- *	  at the demand of John Carol Langford <jcl@gs176.sp.cs.cmu.edu>
- *	- Introduced WAVELAN_ROAMING_EXT for incomplete ESSID stuff.
- *
- * Changes made for release in 3.0.15 :
- * ----------------------------------
- *	- Change e-mail and web page addresses
- *	- Watchdog timer is now correctly expressed in HZ, not in jiffies
- *	- Add channel number to the list of frequencies in range
- *	- Add the (short) list of bit-rates in range
- *	- Developp a new sensitivity... (sens.value & sens.fixed)
- *
- * Changes made for release in 3.1.2 :
- * ---------------------------------
- *	- Fix check for root permission (break instead of exit)
- *	- New nwid & encoding setting (Wireless Extension 9)
- *
- * Changes made for release in 3.1.12 :
- * ----------------------------------
- *	- reworked wv_82593_cmd to avoid using the IRQ handler and doing
- *	  ugly things with interrupts.
- *	- Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog
- *	- Update to new network API (softnet - 2.3.43) :
- *		o replace dev->tbusy (David + me)
- *		o replace dev->tstart (David + me)
- *		o remove dev->interrupt (David)
- *		o add SMP locking via spinlock in splxx (me)
- *		o add spinlock in interrupt handler (me)
- *		o use kernel watchdog instead of ours (me)
- *		o verify that all the changes make sense and work (me)
- *	- Re-sync kernel/pcmcia versions (not much actually)
- *	- A few other cleanups (David & me)...
- *
- * Changes made for release in 3.1.22 :
- * ----------------------------------
- *	- Check that SMP works, remove annoying log message
- *
- * Changes made for release in 3.1.24 :
- * ----------------------------------
- *	- Fix unfrequent card lockup when watchdog was reseting the hardware :
- *		o control first busy loop in wv_82593_cmd()
- *		o Extend spinlock protection in wv_hw_config()
- *
- * Changes made for release in 3.1.33 :
- * ----------------------------------
- *	- Optional use new driver API for Wireless Extensions :
- *		o got rid of wavelan_ioctl()
- *		o use a bunch of iw_handler instead
- *
- * Changes made for release in 3.2.1 :
- * ---------------------------------
- *	- Set dev->trans_start to avoid filling the logs
- *		(and generating useless abort commands)
- *	- Avoid deadlocks in mmc_out()/mmc_in()
- *
- * Wishes & dreams:
- * ----------------
- *	- Cleanup and integrate the roaming code
- *	  (std debug, set DomainID, decay avg and co...)
- */
-
-/***************************** INCLUDES *****************************/
-
-/* Linux headers that we need */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/ethtool.h>
-#include <linux/wireless.h>		/* Wireless extensions */
-#include <net/iw_handler.h>		/* New driver API */
-
-/* Pcmcia headers that we need */
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-/* Wavelan declarations */
-#include "i82593.h"	/* Definitions for the Intel chip */
-
-#include "wavelan_cs.h"	/* Others bits of the hardware */
-
-/************************** DRIVER OPTIONS **************************/
-/*
- * `#define' or `#undef' the following constant to change the behaviour
- * of the driver...
- */
-#define WAVELAN_ROAMING		/* Include experimental roaming code */
-#undef WAVELAN_ROAMING_EXT	/* Enable roaming wireless extensions */
-#undef SET_PSA_CRC		/* Set the CRC in PSA (slower) */
-#define USE_PSA_CONFIG		/* Use info from the PSA */
-#undef EEPROM_IS_PROTECTED	/* Doesn't seem to be necessary */
-#define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical) */
-#undef SET_MAC_ADDRESS		/* Experimental */
-
-/* Warning : these stuff will slow down the driver... */
-#define WIRELESS_SPY		/* Enable spying addresses */
-#undef HISTOGRAM		/* Enable histogram of sig level... */
-
-/****************************** DEBUG ******************************/
-
-#undef DEBUG_MODULE_TRACE	/* Module insertion/removal */
-#undef DEBUG_CALLBACK_TRACE	/* Calls made by Linux */
-#undef DEBUG_INTERRUPT_TRACE	/* Calls to handler */
-#undef DEBUG_INTERRUPT_INFO	/* type of interrupt & so on */
-#define DEBUG_INTERRUPT_ERROR	/* problems */
-#undef DEBUG_CONFIG_TRACE	/* Trace the config functions */
-#undef DEBUG_CONFIG_INFO	/* What's going on... */
-#define DEBUG_CONFIG_ERRORS	/* Errors on configuration */
-#undef DEBUG_TX_TRACE		/* Transmission calls */
-#undef DEBUG_TX_INFO		/* Header of the transmitted packet */
-#undef DEBUG_TX_FAIL		/* Normal failure conditions */
-#define DEBUG_TX_ERROR		/* Unexpected conditions */
-#undef DEBUG_RX_TRACE		/* Transmission calls */
-#undef DEBUG_RX_INFO		/* Header of the transmitted packet */
-#undef DEBUG_RX_FAIL		/* Normal failure conditions */
-#define DEBUG_RX_ERROR		/* Unexpected conditions */
-#undef DEBUG_PACKET_DUMP	/* Dump packet on the screen */
-#undef DEBUG_IOCTL_TRACE	/* Misc call by Linux */
-#undef DEBUG_IOCTL_INFO		/* Various debug info */
-#define DEBUG_IOCTL_ERROR	/* What's going wrong */
-#define DEBUG_BASIC_SHOW	/* Show basic startup info */
-#undef DEBUG_VERSION_SHOW	/* Print version info */
-#undef DEBUG_PSA_SHOW		/* Dump psa to screen */
-#undef DEBUG_MMC_SHOW		/* Dump mmc to screen */
-#undef DEBUG_SHOW_UNUSED	/* Show also unused fields */
-#undef DEBUG_I82593_SHOW	/* Show i82593 status */
-#undef DEBUG_DEVICE_SHOW	/* Show device parameters */
-
-/************************ CONSTANTS & MACROS ************************/
-
-#ifdef DEBUG_VERSION_SHOW
-static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/1/02\n";
-#endif
-
-/* Watchdog temporisation */
-#define	WATCHDOG_JIFFIES	(256*HZ/100)
-
-/* Fix a bug in some old wireless extension definitions */
-#ifndef IW_ESSID_MAX_SIZE
-#define IW_ESSID_MAX_SIZE	32
-#endif
-
-/* ------------------------ PRIVATE IOCTL ------------------------ */
-
-#define SIOCSIPQTHR	SIOCIWFIRSTPRIV		/* Set quality threshold */
-#define SIOCGIPQTHR	SIOCIWFIRSTPRIV + 1	/* Get quality threshold */
-#define SIOCSIPROAM     SIOCIWFIRSTPRIV + 2	/* Set roaming state */
-#define SIOCGIPROAM     SIOCIWFIRSTPRIV + 3	/* Get roaming state */
-
-#define SIOCSIPHISTO	SIOCIWFIRSTPRIV + 4	/* Set histogram ranges */
-#define SIOCGIPHISTO	SIOCIWFIRSTPRIV + 5	/* Get histogram values */
-
-/*************************** WaveLAN Roaming  **************************/
-#ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
-
-#define WAVELAN_ROAMING_DEBUG	 0	/* 1 = Trace of handover decisions */
-					/* 2 = Info on each beacon rcvd... */
-#define MAX_WAVEPOINTS		7	/* Max visible at one time */
-#define WAVEPOINT_HISTORY	5	/* SNR sample history slow search */
-#define WAVEPOINT_FAST_HISTORY	2	/* SNR sample history fast search */
-#define SEARCH_THRESH_LOW	10	/* SNR to enter cell search */
-#define SEARCH_THRESH_HIGH	13	/* SNR to leave cell search */
-#define WAVELAN_ROAMING_DELTA	1	/* Hysteresis value (+/- SNR) */
-#define CELL_TIMEOUT		2*HZ	/* in jiffies */
-
-#define FAST_CELL_SEARCH	1	/* Boolean values... */
-#define NWID_PROMISC		1	/* for code clarity. */
-
-typedef struct wavepoint_beacon
-{
-  unsigned char		dsap,		/* Unused */
-			ssap,		/* Unused */
-			ctrl,		/* Unused */
-			O,U,I,		/* Unused */
-			spec_id1,	/* Unused */
-			spec_id2,	/* Unused */
-			pdu_type,	/* Unused */
-			seq;		/* WavePoint beacon sequence number */
-  __be16		domain_id,	/* WavePoint Domain ID */
-			nwid;		/* WavePoint NWID */
-} wavepoint_beacon;
-
-typedef struct wavepoint_history
-{
-  unsigned short	nwid;		/* WavePoint's NWID */
-  int			average_slow;	/* SNR running average */
-  int			average_fast;	/* SNR running average */
-  unsigned char	  sigqual[WAVEPOINT_HISTORY]; /* Ringbuffer of recent SNR's */
-  unsigned char		qualptr;	/* Index into ringbuffer */
-  unsigned char		last_seq;	/* Last seq. no seen for WavePoint */
-  struct wavepoint_history *next;	/* Next WavePoint in table */
-  struct wavepoint_history *prev;	/* Previous WavePoint in table */
-  unsigned long		last_seen;	/* Time of last beacon recvd, jiffies */
-} wavepoint_history;
-
-struct wavepoint_table
-{
-  wavepoint_history	*head;		/* Start of ringbuffer */
-  int			num_wavepoints;	/* No. of WavePoints visible */
-  unsigned char		locked;		/* Table lock */
-};
-
-#endif	/* WAVELAN_ROAMING */
-
-/****************************** TYPES ******************************/
-
-/* Shortcuts */
-typedef struct iw_statistics	iw_stats;
-typedef struct iw_quality	iw_qual;
-typedef struct iw_freq		iw_freq;
-typedef struct net_local	net_local;
-typedef struct timer_list	timer_list;
-
-/* Basic types */
-typedef u_char		mac_addr[WAVELAN_ADDR_SIZE];	/* Hardware address */
-
-/*
- * Static specific data for the interface.
- *
- * For each network interface, Linux keep data in two structure. "device"
- * keep the generic data (same format for everybody) and "net_local" keep
- * the additional specific data.
- */
-struct net_local
-{
-  dev_node_t 	node;		/* ???? What is this stuff ???? */
-  struct net_device *	dev;		/* Reverse link... */
-  spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
-  struct pcmcia_device *	link;		/* pcmcia structure */
-  int		nresets;	/* Number of hw resets */
-  u_char	configured;	/* If it is configured */
-  u_char	reconfig_82593;	/* Need to reconfigure the controller */
-  u_char	promiscuous;	/* Promiscuous mode */
-  u_char	allmulticast;	/* All Multicast mode */
-  int		mc_count;	/* Number of multicast addresses */
-
-  int   	stop;		/* Current i82593 Stop Hit Register */
-  int   	rfp;		/* Last DMA machine receive pointer */
-  int		overrunning;	/* Receiver overrun flag */
-
-  iw_stats	wstats;		/* Wireless specific stats */
-
-  struct iw_spy_data	spy_data;
-  struct iw_public_data	wireless_data;
-
-#ifdef HISTOGRAM
-  int		his_number;		/* Number of intervals */
-  u_char	his_range[16];		/* Boundaries of interval ]n-1; n] */
-  u_long	his_sum[16];		/* Sum in interval */
-#endif	/* HISTOGRAM */
-#ifdef WAVELAN_ROAMING
-  u_long	domain_id;	/* Domain ID we lock on for roaming */
-  int		filter_domains;	/* Check Domain ID of beacon found */
- struct wavepoint_table	wavepoint_table;	/* Table of visible WavePoints*/
-  wavepoint_history *	curr_point;		/* Current wavepoint */
-  int			cell_search;		/* Searching for new cell? */
-  struct timer_list	cell_timer;		/* Garbage collection */
-#endif	/* WAVELAN_ROAMING */
-  void __iomem *mem;
-};
-
-/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
-static inline u_char		/* data */
-	hasr_read(u_long);	/* Read the host interface : base address */
-static void
-	hacr_write(u_long,	/* Write to host interface : base address */
-		   u_char),	/* data */
-	hacr_write_slow(u_long,
-		   u_char);
-static void
-	psa_read(struct net_device *,	/* Read the Parameter Storage Area */
-		 int,		/* offset in PSA */
-		 u_char *,	/* buffer to fill */
-		 int),		/* size to read */
-	psa_write(struct net_device *,	/* Write to the PSA */
-		  int,		/* Offset in psa */
-		  u_char *,	/* Buffer in memory */
-		  int);		/* Length of buffer */
-static void
-	mmc_out(u_long,		/* Write 1 byte to the Modem Manag Control */
-		u_short,
-		u_char),
-	mmc_write(u_long,	/* Write n bytes to the MMC */
-		  u_char,
-		  u_char *,
-		  int);
-static u_char			/* Read 1 byte from the MMC */
-	mmc_in(u_long,
-	       u_short);
-static void
-	mmc_read(u_long,	/* Read n bytes from the MMC */
-		 u_char,
-		 u_char *,
-		 int),
-	fee_wait(u_long,	/* Wait for frequency EEprom : base address */
-		 int,		/* Base delay to wait for */
-		 int);		/* Number of time to wait */
-static void
-	fee_read(u_long,	/* Read the frequency EEprom : base address */
-		 u_short,	/* destination offset */
-		 u_short *,	/* data buffer */
-		 int);		/* number of registers */
-/* ---------------------- I82593 SUBROUTINES ----------------------- */
-static int
-	wv_82593_cmd(struct net_device *,	/* synchronously send a command to i82593 */ 
-		     char *,
-		     int,
-		     int);
-static inline int
-	wv_diag(struct net_device *);	/* Diagnostique the i82593 */
-static int
-	read_ringbuf(struct net_device *,	/* Read a receive buffer */
-		     int,
-		     char *,
-		     int);
-static void
-	wv_82593_reconfig(struct net_device *);	/* Reconfigure the controller */
-/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
-static void
-	wv_init_info(struct net_device *);	/* display startup info */
-/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static iw_stats *
-	wavelan_get_wireless_stats(struct net_device *);
-/* ----------------------- PACKET RECEPTION ----------------------- */
-static int
-	wv_start_of_frame(struct net_device *,	/* Seek beggining of current frame */
-			  int,	/* end of frame */
-			  int);	/* start of buffer */
-static void
-	wv_packet_read(struct net_device *,	/* Read a packet from a frame */
-		       int,
-		       int),
-	wv_packet_rcv(struct net_device *);	/* Read all packets waiting */
-/* --------------------- PACKET TRANSMISSION --------------------- */
-static void
-	wv_packet_write(struct net_device *,	/* Write a packet to the Tx buffer */
-			void *,
-			short);
-static netdev_tx_t
-	wavelan_packet_xmit(struct sk_buff *,	/* Send a packet */
-			    struct net_device *);
-/* -------------------- HARDWARE CONFIGURATION -------------------- */
-static int
-	wv_mmc_init(struct net_device *);	/* Initialize the modem */
-static int
-	wv_ru_stop(struct net_device *),	/* Stop the i82593 receiver unit */
-	wv_ru_start(struct net_device *);	/* Start the i82593 receiver unit */
-static int
-	wv_82593_config(struct net_device *);	/* Configure the i82593 */
-static int
-	wv_pcmcia_reset(struct net_device *);	/* Reset the pcmcia interface */
-static int
-	wv_hw_config(struct net_device *);	/* Reset & configure the whole hardware */
-static void
-	wv_hw_reset(struct net_device *);	/* Same, + start receiver unit */
-static int
-	wv_pcmcia_config(struct pcmcia_device *);	/* Configure the pcmcia interface */
-static void
-	wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */
-/* ---------------------- INTERRUPT HANDLING ---------------------- */
-static irqreturn_t
-	wavelan_interrupt(int,	/* Interrupt handler */
-			  void *);
-static void
-	wavelan_watchdog(struct net_device *);	/* Transmission watchdog */
-/* ------------------- CONFIGURATION CALLBACKS ------------------- */
-static int
-	wavelan_open(struct net_device *),		/* Open the device */
-	wavelan_close(struct net_device *);	/* Close the device */
-static void
-	wavelan_detach(struct pcmcia_device *p_dev);	/* Destroy a removed device */
-
-/**************************** VARIABLES ****************************/
-
-/*
- * Parameters that can be set with 'insmod'
- * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
- */
-
-/* Shared memory speed, in ns */
-static int	mem_speed = 0;
-
-/* New module interface */
-module_param(mem_speed, int, 0);
-
-#ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
-/* Enable roaming mode ? No ! Please keep this to 0 */
-static int	do_roaming = 0;
-module_param(do_roaming, bool, 0);
-#endif	/* WAVELAN_ROAMING */
-
-MODULE_LICENSE("GPL");
-
-#endif	/* WAVELAN_CS_P_H */
-
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,370 +0,0 @@
-/*
- *	WaveLAN ISA driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follows. See wavelan.p.h for details.
- *
- * This file contains the declarations for the WaveLAN hardware. Note that
- * the WaveLAN ISA includes a i82586 controller (see definitions in
- * file i82586.h).
- *
- * The main difference between the ISA hardware and the PCMCIA one is
- * the Ethernet controller (i82586 instead of i82593).
- * The i82586 allows multiple transmit buffers.  The PSA needs to be accessed
- * through the host interface.
- */
-
-#ifndef _WAVELAN_H
-#define	_WAVELAN_H
-
-/************************** MAGIC NUMBERS ***************************/
-
-/* Detection of the WaveLAN card is done by reading the MAC
- * address from the card and checking it.  If you have a non-AT&T
- * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson),
- * you might need to modify this part to accommodate your hardware.
- */
-static const char	MAC_ADDRESSES[][3] =
-{
-  { 0x08, 0x00, 0x0E },		/* AT&T WaveLAN (standard) & DEC RoamAbout */
-  { 0x08, 0x00, 0x6A },		/* AT&T WaveLAN (alternate) */
-  { 0x00, 0x00, 0xE1 },		/* Hitachi Wavelan */
-  { 0x00, 0x60, 0x1D }		/* Lucent Wavelan (another one) */
-  /* Add your card here and send me the patch! */
-};
-
-#define WAVELAN_ADDR_SIZE	6	/* Size of a MAC address */
-
-#define WAVELAN_MTU		1500	/* Maximum size of WaveLAN packet */
-
-#define	MAXDATAZ		(WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU)
-
-/*
- * Constants used to convert channels to frequencies
- */
-
-/* Frequency available in the 2.0 modem, in units of 250 kHz
- * (as read in the offset register of the dac area).
- * Used to map channel numbers used by `wfreqsel' to frequencies
- */
-static const short	channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
-				    0xD0, 0xF0, 0xF8, 0x150 };
-
-/* Frequencies of the 1.0 modem (fixed frequencies).
- * Use to map the PSA `subband' to a frequency
- * Note : all frequencies apart from the first one need to be multiplied by 10
- */
-static const int	fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
-
-
-
-/*************************** PC INTERFACE ****************************/
-
-/*
- * Host Adaptor structure.
- * (base is board port address).
- */
-typedef union hacs_u	hacs_u;
-union hacs_u
-{
-	unsigned short	hu_command;		/* Command register */
-#define		HACR_RESET		0x0001	/* Reset board */
-#define		HACR_CA			0x0002	/* Set Channel Attention for 82586 */
-#define		HACR_16BITS		0x0004	/* 16-bit operation (0 => 8bits) */
-#define		HACR_OUT0		0x0008	/* General purpose output pin 0 */
-						/* not used - must be 1 */
-#define		HACR_OUT1		0x0010	/* General purpose output pin 1 */
-						/* not used - must be 1 */
-#define		HACR_82586_INT_ENABLE	0x0020	/* Enable 82586 interrupts */
-#define		HACR_MMC_INT_ENABLE	0x0040	/* Enable MMC interrupts */
-#define		HACR_INTR_CLR_ENABLE	0x0080	/* Enable interrupt status read/clear */
-	unsigned short	hu_status;		/* Status Register */
-#define		HASR_82586_INTR		0x0001	/* Interrupt request from 82586 */
-#define		HASR_MMC_INTR		0x0002	/* Interrupt request from MMC */
-#define		HASR_MMC_BUSY		0x0004	/* MMC busy indication */
-#define		HASR_PSA_BUSY		0x0008	/* LAN parameter storage area busy */
-} __attribute__ ((packed));
-
-typedef struct ha_t	ha_t;
-struct ha_t
-{
-	hacs_u		ha_cs;		/* Command and status registers */
-#define 		ha_command	ha_cs.hu_command
-#define 		ha_status	ha_cs.hu_status
-	unsigned short	ha_mmcr;	/* Modem Management Ctrl Register */
-	unsigned short	ha_pior0;	/* Program I/O Address Register Port 0 */
-	unsigned short	ha_piop0;	/* Program I/O Port 0 */
-	unsigned short	ha_pior1;	/* Program I/O Address Register Port 1 */
-	unsigned short	ha_piop1;	/* Program I/O Port 1 */
-	unsigned short	ha_pior2;	/* Program I/O Address Register Port 2 */
-	unsigned short	ha_piop2;	/* Program I/O Port 2 */
-};
-
-#define HA_SIZE		16
-
-#define	hoff(p,f) 	(unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0)
-#define	HACR(p)		hoff(p, ha_command)
-#define	HASR(p)		hoff(p, ha_status)
-#define	MMCR(p)		hoff(p, ha_mmcr)
-#define	PIOR0(p)	hoff(p, ha_pior0)
-#define	PIOP0(p)	hoff(p, ha_piop0)
-#define	PIOR1(p)	hoff(p, ha_pior1)
-#define	PIOP1(p)	hoff(p, ha_piop1)
-#define	PIOR2(p)	hoff(p, ha_pior2)
-#define	PIOP2(p)	hoff(p, ha_piop2)
-
-/*
- * Program I/O Mode Register values.
- */
-#define STATIC_PIO		0	/* Mode 1: static mode */
-					/* RAM access ??? */
-#define AUTOINCR_PIO		1	/* Mode 2: auto increment mode */
-					/* RAM access ??? */
-#define AUTODECR_PIO		2	/* Mode 3: auto decrement mode */
-					/* RAM access ??? */
-#define PARAM_ACCESS_PIO	3	/* Mode 4: LAN parameter access mode */
-					/* Parameter access. */
-#define PIO_MASK		3	/* register mask */
-#define PIOM(cmd,piono)		((u_short)cmd << 10 << (piono * 2))
-
-#define	HACR_DEFAULT		(HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2))
-#define	HACR_INTRON		(HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE)
-
-/************************** MEMORY LAYOUT **************************/
-
-/*
- * Onboard 64 k RAM layout.
- * (Offsets from 0x0000.)
- */
-#define OFFSET_RU		0x0000		/* 75% memory */
-#define OFFSET_CU		0xC000		/* 25% memory */
-#define OFFSET_SCB		(OFFSET_ISCP - sizeof(scb_t))
-#define OFFSET_ISCP		(OFFSET_SCP - sizeof(iscp_t))
-#define OFFSET_SCP		I82586_SCP_ADDR
-
-#define	RXBLOCKZ		(sizeof(fd_t) + sizeof(rbd_t) + MAXDATAZ)
-#define	TXBLOCKZ		(sizeof(ac_tx_t) + sizeof(ac_nop_t) + sizeof(tbd_t) + MAXDATAZ)
-
-#define	NRXBLOCKS		((OFFSET_CU - OFFSET_RU) / RXBLOCKZ)
-#define	NTXBLOCKS		((OFFSET_SCB - OFFSET_CU) / TXBLOCKZ)
-
-/********************** PARAMETER STORAGE AREA **********************/
-
-/*
- * Parameter Storage Area (PSA).
- */
-typedef struct psa_t	psa_t;
-struct psa_t
-{
-  unsigned char	psa_io_base_addr_1;	/* [0x00] Base address 1 ??? */
-  unsigned char	psa_io_base_addr_2;	/* [0x01] Base address 2 */
-  unsigned char	psa_io_base_addr_3;	/* [0x02] Base address 3 */
-  unsigned char	psa_io_base_addr_4;	/* [0x03] Base address 4 */
-  unsigned char	psa_rem_boot_addr_1;	/* [0x04] Remote Boot Address 1 */
-  unsigned char	psa_rem_boot_addr_2;	/* [0x05] Remote Boot Address 2 */
-  unsigned char	psa_rem_boot_addr_3;	/* [0x06] Remote Boot Address 3 */
-  unsigned char	psa_holi_params;	/* [0x07] HOst Lan Interface (HOLI) Parameters */
-  unsigned char	psa_int_req_no;		/* [0x08] Interrupt Request Line */
-  unsigned char	psa_unused0[7];		/* [0x09-0x0F] unused */
-
-  unsigned char	psa_univ_mac_addr[WAVELAN_ADDR_SIZE];	/* [0x10-0x15] Universal (factory) MAC Address */
-  unsigned char	psa_local_mac_addr[WAVELAN_ADDR_SIZE];	/* [0x16-1B] Local MAC Address */
-  unsigned char	psa_univ_local_sel;	/* [0x1C] Universal Local Selection */
-#define		PSA_UNIVERSAL	0		/* Universal (factory) */
-#define		PSA_LOCAL	1		/* Local */
-  unsigned char	psa_comp_number;	/* [0x1D] Compatibility Number:	 */
-#define		PSA_COMP_PC_AT_915	0 	/* PC-AT 915 MHz 	 */
-#define		PSA_COMP_PC_MC_915	1 	/* PC-MC 915 MHz	 */
-#define		PSA_COMP_PC_AT_2400	2 	/* PC-AT 2.4 GHz	 */
-#define		PSA_COMP_PC_MC_2400	3 	/* PC-MC 2.4 GHz 	 */
-#define		PSA_COMP_PCMCIA_915	4 	/* PCMCIA 915 MHz or 2.0 */
-  unsigned char	psa_thr_pre_set;	/* [0x1E] Modem Threshold Preset */
-  unsigned char	psa_feature_select;	/* [0x1F] Call code required (1=on) */
-#define		PSA_FEATURE_CALL_CODE	0x01 	/* Call code required (Japan) */
-  unsigned char	psa_subband;		/* [0x20] Subband	  */
-#define		PSA_SUBBAND_915		0	/* 915 MHz or 2.0 */
-#define		PSA_SUBBAND_2425	1	/* 2425 MHz	  */
-#define		PSA_SUBBAND_2460	2	/* 2460 MHz	  */
-#define		PSA_SUBBAND_2484	3	/* 2484 MHz	  */
-#define		PSA_SUBBAND_2430_5	4	/* 2430.5 MHz	  */
-  unsigned char	psa_quality_thr;	/* [0x21] Modem Quality Threshold */
-  unsigned char	psa_mod_delay;		/* [0x22] Modem Delay (?) (reserved) */
-  unsigned char	psa_nwid[2];		/* [0x23-0x24] Network ID */
-  unsigned char	psa_nwid_select;	/* [0x25] Network ID Select On/Off */
-  unsigned char	psa_encryption_select;	/* [0x26] Encryption On/Off */
-  unsigned char	psa_encryption_key[8];	/* [0x27-0x2E] Encryption Key */
-  unsigned char	psa_databus_width;	/* [0x2F] AT bus width select 8/16 */
-  unsigned char	psa_call_code[8];	/* [0x30-0x37] (Japan) Call Code */
-  unsigned char	psa_nwid_prefix[2];	/* [0x38-0x39] Roaming domain */
-  unsigned char	psa_reserved[2];	/* [0x3A-0x3B] Reserved - fixed 00 */
-  unsigned char	psa_conf_status;	/* [0x3C] Conf Status, bit 0=1:config*/
-  unsigned char	psa_crc[2];		/* [0x3D] CRC-16 over PSA */
-  unsigned char	psa_crc_status;		/* [0x3F] CRC Valid Flag */
-};
-
-#define	PSA_SIZE	64
-
-/* Calculate offset of a field in the above structure.
- * Warning:  only even addresses are used. */
-#define	psaoff(p,f) 	((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
-
-/******************** MODEM MANAGEMENT INTERFACE ********************/
-
-/*
- * Modem Management Controller (MMC) write structure.
- */
-typedef struct mmw_t	mmw_t;
-struct mmw_t
-{
-  unsigned char	mmw_encr_key[8];	/* encryption key */
-  unsigned char	mmw_encr_enable;	/* Enable or disable encryption. */
-#define	MMW_ENCR_ENABLE_MODE	0x02	/* mode of security option */
-#define	MMW_ENCR_ENABLE_EN	0x01	/* Enable security option. */
-  unsigned char	mmw_unused0[1];		/* unused */
-  unsigned char	mmw_des_io_invert;	/* encryption option */
-#define	MMW_DES_IO_INVERT_RES	0x0F	/* reserved */
-#define	MMW_DES_IO_INVERT_CTRL	0xF0	/* control (?) (set to 0) */
-  unsigned char	mmw_unused1[5];		/* unused */
-  unsigned char	mmw_loopt_sel;		/* looptest selection */
-#define	MMW_LOOPT_SEL_DIS_NWID	0x40	/* Disable NWID filtering. */
-#define	MMW_LOOPT_SEL_INT	0x20	/* Activate Attention Request. */
-#define	MMW_LOOPT_SEL_LS	0x10	/* looptest, no collision avoidance */
-#define MMW_LOOPT_SEL_LT3A	0x08	/* looptest 3a */
-#define	MMW_LOOPT_SEL_LT3B	0x04	/* looptest 3b */
-#define	MMW_LOOPT_SEL_LT3C	0x02	/* looptest 3c */
-#define	MMW_LOOPT_SEL_LT3D	0x01	/* looptest 3d */
-  unsigned char	mmw_jabber_enable;	/* jabber timer enable */
-  /* Abort transmissions > 200 ms */
-  unsigned char	mmw_freeze;		/* freeze or unfreeze signal level */
-  /* 0 : signal level & qual updated for every new message, 1 : frozen */
-  unsigned char	mmw_anten_sel;		/* antenna selection */
-#define MMW_ANTEN_SEL_SEL	0x01	/* direct antenna selection */
-#define	MMW_ANTEN_SEL_ALG_EN	0x02	/* antenna selection algo. enable */
-  unsigned char	mmw_ifs;		/* inter frame spacing */
-  /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
-  unsigned char	mmw_mod_delay;	 	/* modem delay (synchro) */
-  unsigned char	mmw_jam_time;		/* jamming time (after collision) */
-  unsigned char	mmw_unused2[1];		/* unused */
-  unsigned char	mmw_thr_pre_set;	/* level threshold preset */
-  /* Discard all packet with signal < this value (4) */
-  unsigned char	mmw_decay_prm;		/* decay parameters */
-  unsigned char	mmw_decay_updat_prm;	/* decay update parameters */
-  unsigned char	mmw_quality_thr;	/* quality (z-quotient) threshold */
-  /* Discard all packet with quality < this value (3) */
-  unsigned char	mmw_netw_id_l;		/* NWID low order byte */
-  unsigned char	mmw_netw_id_h;		/* NWID high order byte */
-  /* Network ID or Domain : create virtual net on the air */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char	mmw_mode_select;	/* for analog tests (set to 0) */
-  unsigned char	mmw_unused3[1];		/* unused */
-  unsigned char	mmw_fee_ctrl;		/* frequency EEPROM control */
-#define	MMW_FEE_CTRL_PRE	0x10	/* Enable protected instructions. */
-#define	MMW_FEE_CTRL_DWLD	0x08	/* Download EEPROM to mmc. */
-#define	MMW_FEE_CTRL_CMD	0x07	/* EEPROM commands:  */
-#define	MMW_FEE_CTRL_READ	0x06	/* Read */
-#define	MMW_FEE_CTRL_WREN	0x04	/* Write enable */
-#define	MMW_FEE_CTRL_WRITE	0x05	/* Write data to address. */
-#define	MMW_FEE_CTRL_WRALL	0x04	/* Write data to all addresses. */
-#define	MMW_FEE_CTRL_WDS	0x04	/* Write disable */
-#define	MMW_FEE_CTRL_PRREAD	0x16	/* Read addr from protect register */
-#define	MMW_FEE_CTRL_PREN	0x14	/* Protect register enable */
-#define	MMW_FEE_CTRL_PRCLEAR	0x17	/* Unprotect all registers. */
-#define	MMW_FEE_CTRL_PRWRITE	0x15	/* Write address in protect register */
-#define	MMW_FEE_CTRL_PRDS	0x14	/* Protect register disable */
-  /* Never issue the PRDS command:  it's irreversible! */
-
-  unsigned char	mmw_fee_addr;		/* EEPROM address */
-#define	MMW_FEE_ADDR_CHANNEL	0xF0	/* Select the channel. */
-#define	MMW_FEE_ADDR_OFFSET	0x0F	/* Offset in channel data */
-#define	MMW_FEE_ADDR_EN		0xC0	/* FEE_CTRL enable operations */
-#define	MMW_FEE_ADDR_DS		0x00	/* FEE_CTRL disable operations */
-#define	MMW_FEE_ADDR_ALL	0x40	/* FEE_CTRL all operations */
-#define	MMW_FEE_ADDR_CLEAR	0xFF	/* FEE_CTRL clear operations */
-
-  unsigned char	mmw_fee_data_l;		/* Write data to EEPROM. */
-  unsigned char	mmw_fee_data_h;		/* high octet */
-  unsigned char	mmw_ext_ant;		/* Setting for external antenna */
-#define	MMW_EXT_ANT_EXTANT	0x01	/* Select external antenna */
-#define	MMW_EXT_ANT_POL		0x02	/* Polarity of the antenna */
-#define	MMW_EXT_ANT_INTERNAL	0x00	/* Internal antenna */
-#define	MMW_EXT_ANT_EXTERNAL	0x03	/* External antenna */
-#define	MMW_EXT_ANT_IQ_TEST	0x1C	/* IQ test pattern (set to 0) */
-} __attribute__ ((packed));
-
-#define	MMW_SIZE	37
-
-#define	mmwoff(p,f) 	(unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * Modem Management Controller (MMC) read structure.
- */
-typedef struct mmr_t	mmr_t;
-struct mmr_t
-{
-  unsigned char	mmr_unused0[8];		/* unused */
-  unsigned char	mmr_des_status;		/* encryption status */
-  unsigned char	mmr_des_avail;		/* encryption available (0x55 read) */
-#define	MMR_DES_AVAIL_DES	0x55		/* DES available */
-#define	MMR_DES_AVAIL_AES	0x33		/* AES (AT&T) available */
-  unsigned char	mmr_des_io_invert;	/* des I/O invert register */
-  unsigned char	mmr_unused1[5];		/* unused */
-  unsigned char	mmr_dce_status;		/* DCE status */
-#define	MMR_DCE_STATUS_RX_BUSY		0x01	/* receiver busy */
-#define	MMR_DCE_STATUS_LOOPT_IND	0x02	/* loop test indicated */
-#define	MMR_DCE_STATUS_TX_BUSY		0x04	/* transmitter on */
-#define	MMR_DCE_STATUS_JBR_EXPIRED	0x08	/* jabber timer expired */
-#define MMR_DCE_STATUS			0x0F	/* mask to get the bits */
-  unsigned char	mmr_dsp_id;		/* DSP ID (AA = Daedalus rev A) */
-  unsigned char	mmr_unused2[2];		/* unused */
-  unsigned char	mmr_correct_nwid_l;	/* # of correct NWIDs rxd (low) */
-  unsigned char	mmr_correct_nwid_h;	/* # of correct NWIDs rxd (high) */
-  /* Warning:  read high-order octet first! */
-  unsigned char	mmr_wrong_nwid_l;	/* # of wrong NWIDs rxd (low) */
-  unsigned char	mmr_wrong_nwid_h;	/* # of wrong NWIDs rxd (high) */
-  unsigned char	mmr_thr_pre_set;	/* level threshold preset */
-#define	MMR_THR_PRE_SET		0x3F		/* level threshold preset */
-#define	MMR_THR_PRE_SET_CUR	0x80		/* Current signal above it */
-  unsigned char	mmr_signal_lvl;		/* signal level */
-#define	MMR_SIGNAL_LVL		0x3F		/* signal level */
-#define	MMR_SIGNAL_LVL_VALID	0x80		/* Updated since last read */
-  unsigned char	mmr_silence_lvl;	/* silence level (noise) */
-#define	MMR_SILENCE_LVL		0x3F		/* silence level */
-#define	MMR_SILENCE_LVL_VALID	0x80		/* Updated since last read */
-  unsigned char	mmr_sgnl_qual;		/* signal quality */
-#define	MMR_SGNL_QUAL		0x0F		/* signal quality */
-#define	MMR_SGNL_QUAL_ANT	0x80		/* current antenna used */
-  unsigned char	mmr_netw_id_l;		/* NWID low order byte (?) */
-  unsigned char	mmr_unused3[3];		/* unused */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char	mmr_fee_status;		/* Status of frequency EEPROM */
-#define	MMR_FEE_STATUS_ID	0xF0		/* Modem revision ID */
-#define	MMR_FEE_STATUS_DWLD	0x08		/* Download in progress */
-#define	MMR_FEE_STATUS_BUSY	0x04		/* EEPROM busy */
-  unsigned char	mmr_unused4[1];		/* unused */
-  unsigned char	mmr_fee_data_l;		/* Read data from EEPROM (low) */
-  unsigned char	mmr_fee_data_h;		/* Read data from EEPROM (high) */
-} __attribute__ ((packed));
-
-#define	MMR_SIZE	36
-
-#define	mmroff(p,f) 	(unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/* Make the two above structures one */
-typedef union mm_t
-{
-  struct mmw_t	w;	/* Write to the mmc */
-  struct mmr_t	r;	/* Read from the mmc */
-} mm_t;
-
-#endif /* _WAVELAN_H */
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * For more details, see wavelan.c.
- */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.p.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.p.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wavelan.p.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wavelan.p.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,696 +0,0 @@
-/*
- *	WaveLAN ISA driver
- *
- *		Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- *
- * This file contains all definitions and declarations necessary for the
- * WaveLAN ISA driver.  This file is a private header, so it should
- * be included only in wavelan.c!
- */
-
-#ifndef WAVELAN_P_H
-#define WAVELAN_P_H
-
-/************************** DOCUMENTATION ***************************/
-/*
- * This driver provides a Linux interface to the WaveLAN ISA hardware.
- * The WaveLAN is a product of Lucent (http://www.wavelan.com/).
- * This division was formerly part of NCR and then AT&T.
- * WaveLANs are also distributed by DEC (RoamAbout DS) and Digital Ocean.
- *
- * To learn how to use this driver, read the NET3 HOWTO.
- * If you want to exploit the many other functionalities, read the comments
- * in the code.
- *
- * This driver is the result of the effort of many people (see below).
- */
-
-/* ------------------------ SPECIFIC NOTES ------------------------ */
-/*
- * Web page
- * --------
- *	I try to maintain a web page with the Wireless LAN Howto at :
- *	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
- *
- * SMP
- * ---
- *	We now are SMP compliant (I eventually fixed the remaining bugs).
- *	The driver has been tested on a dual P6-150 and survived my usual
- *	set of torture tests.
- *	Anyway, I spent enough time chasing interrupt re-entrancy during
- *	errors or reconfigure, and I designed the locked/unlocked sections
- *	of the driver with great care, and with the recent addition of
- *	the spinlock (thanks to the new API), we should be quite close to
- *	the truth.
- *	The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
- *	but better safe than sorry (especially at 2 Mb/s ;-).
- *
- *	I have also looked into disabling only our interrupt on the card
- *	(via HACR) instead of all interrupts in the processor (via cli),
- *	so that other driver are not impacted, and it look like it's
- *	possible, but it's very tricky to do right (full of races). As
- *	the gain would be mostly for SMP systems, it can wait...
- *
- * Debugging and options
- * ---------------------
- *	You will find below a set of '#define" allowing a very fine control
- *	on the driver behaviour and the debug messages printed.
- *	The main options are :
- *	o SET_PSA_CRC, to have your card correctly recognised by
- *	  an access point and the Point-to-Point diagnostic tool.
- *	o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
- *	  (otherwise we always start afresh with some defaults)
- *
- * wavelan.o is too darned big
- * ---------------------------
- *	That's true!  There is a very simple way to reduce the driver
- *	object by 33%!  Comment out the following line:
- *		#include <linux/wireless.h>
- *	Other compile options can also reduce the size of it...
- *
- * MAC address and hardware detection:
- * -----------------------------------
- *	The detection code for the WaveLAN checks that the first three
- *	octets of the MAC address fit the company code.  This type of
- *	detection works well for AT&T cards (because the AT&T code is
- *	hardcoded in wavelan.h), but of course will fail for other
- *	manufacturers.
- *
- *	If you are sure that your card is derived from the WaveLAN,
- *	here is the way to configure it:
- *	1) Get your MAC address
- *		a) With your card utilities (wfreqsel, instconf, etc.)
- *		b) With the driver:
- *			o compile the kernel with DEBUG_CONFIG_INFO enabled
- *			o Boot and look the card messages
- *	2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan.h)
- *	3) Compile and verify
- *	4) Send me the MAC code.  I will include it in the next version.
- *
- */
-
-/* --------------------- WIRELESS EXTENSIONS --------------------- */
-/*
- * This driver is the first to support "wireless extensions".
- * This set of extensions provides a standard way to control the wireless
- * characteristics of the hardware.  Applications such as mobile IP may
- * take advantage of it.
- *
- * It might be a good idea as well to fetch the wireless tools to
- * configure the device and play a bit.
- */
-
-/* ---------------------------- FILES ---------------------------- */
-/*
- * wavelan.c:		actual code for the driver:  C functions
- *
- * wavelan.p.h:		private header:  local types and variables for driver
- *
- * wavelan.h:		description of the hardware interface and structs
- *
- * i82586.h:		description of the Ethernet controller
- */
-
-/* --------------------------- HISTORY --------------------------- */
-/*
- * This is based on information in the drivers' headers. It may not be
- * accurate, and I guarantee only my best effort.
- *
- * The history of the WaveLAN drivers is as complicated as the history of
- * the WaveLAN itself (NCR -> AT&T -> Lucent).
- *
- * It all started with Anders Klemets <klemets@paul.rutgers.edu>
- * writing a WaveLAN ISA driver for the Mach microkernel.  Girish
- * Welling <welling@paul.rutgers.edu> had also worked on it.
- * Keith Moore modified this for the PCMCIA hardware.
- * 
- * Robert Morris <rtm@das.harvard.edu> ported these two drivers to BSDI
- * and added specific PCMCIA support (there is currently no equivalent
- * of the PCMCIA package under BSD).
- *
- * Jim Binkley <jrb@cs.pdx.edu> ported both BSDI drivers to FreeBSD.
- *
- * Bruce Janson <bruce@cs.usyd.edu.au> ported the BSDI ISA driver to Linux.
- *
- * Anthony D. Joseph <adj@lcs.mit.edu> started to modify Bruce's driver
- * (with help of the BSDI PCMCIA driver) for PCMCIA.
- * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished this work.
- * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
- * 2.00 cards correctly (2.4 GHz with frequency selection).
- * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
- * PCMCIA package (and bug corrections).
- *
- * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
- * patches to the PCMCIA driver.  Later, I added code in the ISA driver
- * for Wireless Extensions and full support of frequency selection
- * cards.  Then, I did the same to the PCMCIA driver, and did some
- * reorganisation.  Finally, I came back to the ISA driver to
- * upgrade it at the same level as the PCMCIA one and reorganise
- * the code.
- * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
- * much needed information on the WaveLAN hardware.
- */
-
-/* The original copyrights and literature mention others' names and
- * credits.  I don't know what their part in this development was.
- */
-
-/* By the way, for the copyright and legal stuff:
- * almost everybody wrote code under the GNU or BSD license (or similar),
- * and want their original copyright to remain somewhere in the
- * code (for myself, I go with the GPL).
- * Nobody wants to take responsibility for anything, except the fame.
- */
-
-/* --------------------------- CREDITS --------------------------- */
-/*
- * This software was developed as a component of the
- * Linux operating system.
- * It is based on other device drivers and information
- * either written or supplied by:
- *	Ajay Bakre <bakre@paul.rutgers.edu>,
- *	Donald Becker <becker@cesdis.gsfc.nasa.gov>,
- *	Loeke Brederveld <Loeke.Brederveld@Utrecht.NCR.com>,
- *	Brent Elphick <belphick@uwaterloo.ca>,
- *	Anders Klemets <klemets@it.kth.se>,
- *	Vladimir V. Kolpakov <w@stier.koenig.ru>,
- *	Marc Meertens <Marc.Meertens@Utrecht.NCR.com>,
- *	Pauline Middelink <middelin@polyware.iaf.nl>,
- *	Robert Morris <rtm@das.harvard.edu>,
- *	Jean Tourrilhes <jt@hpl.hp.com>,
- *	Girish Welling <welling@paul.rutgers.edu>,
- *	Clark Woodworth <clark@hiway1.exit109.com>
- *	Yongguang Zhang <ygz@isl.hrl.hac.com>
- *
- * Thanks go also to:
- *	James Ashton <jaa101@syseng.anu.edu.au>,
- *	Alan Cox <alan@lxorguk.ukuu.org.uk>,
- *	Allan Creighton <allanc@cs.usyd.edu.au>,
- *	Matthew Geier <matthew@cs.usyd.edu.au>,
- *	Remo di Giovanni <remo@cs.usyd.edu.au>,
- *	Eckhard Grah <grah@wrcs1.urz.uni-wuppertal.de>,
- *	Vipul Gupta <vgupta@cs.binghamton.edu>,
- *	Mark Hagan <mhagan@wtcpost.daytonoh.NCR.COM>,
- *	Tim Nicholson <tim@cs.usyd.edu.au>,
- *	Ian Parkin <ian@cs.usyd.edu.au>,
- *	John Rosenberg <johnr@cs.usyd.edu.au>,
- *	George Rossi <george@phm.gov.au>,
- *	Arthur Scott <arthur@cs.usyd.edu.au>,
- *	Stanislav Sinyagin <stas@isf.ru>
- *	and Peter Storey for their assistance and advice.
- *
- * Additional Credits:
- *
- *	My development has been done initially under Debian 1.1 (Linux 2.0.x)
- *	and now	under Debian 2.2, initially with an HP Vectra XP/60, and now
- *	an HP Vectra XP/90.
- *
- */
-
-/* ------------------------- IMPROVEMENTS ------------------------- */
-/*
- * I proudly present:
- *
- * Changes made in first pre-release:
- * ----------------------------------
- *	- reorganisation of the code, function name change
- *	- creation of private header (wavelan.p.h)
- *	- reorganised debug messages
- *	- more comments, history, etc.
- *	- mmc_init:  configure the PSA if not done
- *	- mmc_init:  correct default value of level threshold for PCMCIA
- *	- mmc_init:  2.00 detection better code for 2.00 initialization
- *	- better info at startup
- *	- IRQ setting (note:  this setting is permanent)
- *	- watchdog:  change strategy (and solve module removal problems)
- *	- add wireless extensions (ioctl and get_wireless_stats)
- *	  get/set nwid/frequency on fly, info for /proc/net/wireless
- *	- more wireless extensions:  SETSPY and GETSPY
- *	- make wireless extensions optional
- *	- private ioctl to set/get quality and level threshold, histogram
- *	- remove /proc/net/wavelan
- *	- suppress useless stuff from lp (net_local)
- *	- kernel 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
- *	- add message level (debug stuff in /var/adm/debug and errors not
- *	  displayed at console and still in /var/adm/messages)
- *	- multi device support
- *	- start fixing the probe (init code)
- *	- more inlines
- *	- man page
- *	- many other minor details and cleanups
- *
- * Changes made in second pre-release:
- * -----------------------------------
- *	- clean up init code (probe and module init)
- *	- better multiple device support (module)
- *	- name assignment (module)
- *
- * Changes made in third pre-release:
- * ----------------------------------
- *	- be more conservative on timers
- *	- preliminary support for multicast (I still lack some details)
- *
- * Changes made in fourth pre-release:
- * -----------------------------------
- *	- multicast (revisited and finished)
- *	- avoid reset in set_multicast_list (a really big hack)
- *	  if somebody could apply this code for other i82586 based drivers
- *	- share onboard memory 75% RU and 25% CU (instead of 50/50)
- *
- * Changes made for release in 2.1.15:
- * -----------------------------------
- *	- change the detection code for multi manufacturer code support
- *
- * Changes made for release in 2.1.17:
- * -----------------------------------
- *	- update to wireless extensions changes
- *	- silly bug in card initial configuration (psa_conf_status)
- *
- * Changes made for release in 2.1.27 & 2.0.30:
- * --------------------------------------------
- *	- small bug in debug code (probably not the last one...)
- *	- remove extern keyword for wavelan_probe()
- *	- level threshold is now a standard wireless extension (version 4 !)
- *	- modules parameters types (new module interface)
- *
- * Changes made for release in 2.1.36:
- * -----------------------------------
- *	- byte count stats (courtesy of David Hinds)
- *	- remove dev_tint stuff (courtesy of David Hinds)
- *	- encryption setting from Brent Elphick (thanks a lot!)
- *	- 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
- *
- * Other changes (not by me) :
- * -------------------------
- *	- Spelling and gramar "rectification".
- *
- * Changes made for release in 2.0.37 & 2.2.2 :
- * ------------------------------------------
- *	- Correct status in /proc/net/wireless
- *	- Set PSA CRC to make PtP diagnostic tool happy (Bob Gray)
- *	- Module init code don't fail if we found at least one card in
- *	  the address list (Karlis Peisenieks)
- *	- Missing parenthesis (Christopher Peterson)
- *	- Correct i82586 configuration parameters
- *	- Encryption initialisation bug (Robert McCormack)
- *	- New mac addresses detected in the probe
- *	- Increase watchdog for busy environments
- *
- * Changes made for release in 2.0.38 & 2.2.7 :
- * ------------------------------------------
- *	- Correct the reception logic to better report errors and avoid
- *	  sending bogus packet up the stack
- *	- Delay RU config to avoid corrupting first received packet
- *	- Change config completion code (to actually check something)
- *	- Avoid reading out of bound in skbuf to transmit
- *	- Rectify a lot of (useless) debugging code
- *	- Change the way to `#ifdef SET_PSA_CRC'
- *
- * Changes made for release in 2.2.11 & 2.3.13 :
- * -------------------------------------------
- *	- Change e-mail and web page addresses
- *	- Watchdog timer is now correctly expressed in HZ, not in jiffies
- *	- Add channel number to the list of frequencies in range
- *	- Add the (short) list of bit-rates in range
- *	- Developp a new sensitivity... (sens.value & sens.fixed)
- *
- * Changes made for release in 2.2.14 & 2.3.23 :
- * -------------------------------------------
- *	- Fix check for root permission (break instead of exit)
- *	- New nwid & encoding setting (Wireless Extension 9)
- *
- * Changes made for release in 2.3.49 :
- * ----------------------------------
- *	- Indentation reformating (Alan)
- *	- Update to new network API (softnet - 2.3.43) :
- *		o replace dev->tbusy (Alan)
- *		o replace dev->tstart (Alan)
- *		o remove dev->interrupt (Alan)
- *		o add SMP locking via spinlock in splxx (me)
- *		o add spinlock in interrupt handler (me)
- *		o use kernel watchdog instead of ours (me)
- *		o increase watchdog timeout (kernel is more sensitive) (me)
- *		o verify that all the changes make sense and work (me)
- *	- Fixup a potential gotcha when reconfiguring and thighten a bit
- *		the interactions with Tx queue.
- *
- * Changes made for release in 2.4.0 :
- * ---------------------------------
- *	- Fix spinlock stupid bugs that I left in. The driver is now SMP
- *		compliant and doesn't lockup at startup.
- *
- * Changes made for release in 2.5.2 :
- * ---------------------------------
- *	- Use new driver API for Wireless Extensions :
- *		o got rid of wavelan_ioctl()
- *		o use a bunch of iw_handler instead
- *
- * Changes made for release in 2.5.35 :
- * ----------------------------------
- *	- Set dev->trans_start to avoid filling the logs
- *	- Handle better spurious/bogus interrupt
- *	- Avoid deadlocks in mmc_out()/mmc_in()
- *
- * Wishes & dreams:
- * ----------------
- *	- roaming (see Pcmcia driver)
- */
-
-/***************************** INCLUDES *****************************/
-
-#include	<linux/module.h>
-
-#include	<linux/kernel.h>
-#include	<linux/sched.h>
-#include	<linux/types.h>
-#include	<linux/fcntl.h>
-#include	<linux/interrupt.h>
-#include	<linux/stat.h>
-#include	<linux/ptrace.h>
-#include	<linux/ioport.h>
-#include	<linux/in.h>
-#include	<linux/string.h>
-#include	<linux/delay.h>
-#include	<linux/bitops.h>
-#include	<asm/system.h>
-#include	<asm/io.h>
-#include	<asm/dma.h>
-#include	<asm/uaccess.h>
-#include	<linux/errno.h>
-#include	<linux/netdevice.h>
-#include	<linux/etherdevice.h>
-#include	<linux/skbuff.h>
-#include	<linux/slab.h>
-#include	<linux/timer.h>
-#include	<linux/init.h>
-
-#include <linux/wireless.h>		/* Wireless extensions */
-#include <net/iw_handler.h>		/* Wireless handlers */
-
-/* WaveLAN declarations */
-#include	"i82586.h"
-#include	"wavelan.h"
-
-/************************** DRIVER OPTIONS **************************/
-/*
- * `#define' or `#undef' the following constant to change the behaviour
- * of the driver...
- */
-#undef SET_PSA_CRC		/* Calculate and set the CRC on PSA (slower) */
-#define USE_PSA_CONFIG		/* Use info from the PSA. */
-#undef EEPROM_IS_PROTECTED	/* doesn't seem to be necessary */
-#define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical). */
-#undef SET_MAC_ADDRESS		/* Experimental */
-
-/* Warning:  this stuff will slow down the driver. */
-#define WIRELESS_SPY		/* Enable spying addresses. */
-#undef HISTOGRAM		/* Enable histogram of signal level. */
-
-/****************************** DEBUG ******************************/
-
-#undef DEBUG_MODULE_TRACE	/* module insertion/removal */
-#undef DEBUG_CALLBACK_TRACE	/* calls made by Linux */
-#undef DEBUG_INTERRUPT_TRACE	/* calls to handler */
-#undef DEBUG_INTERRUPT_INFO	/* type of interrupt and so on */
-#define DEBUG_INTERRUPT_ERROR	/* problems */
-#undef DEBUG_CONFIG_TRACE	/* Trace the config functions. */
-#undef DEBUG_CONFIG_INFO	/* what's going on */
-#define DEBUG_CONFIG_ERROR	/* errors on configuration */
-#undef DEBUG_TX_TRACE		/* transmission calls */
-#undef DEBUG_TX_INFO		/* header of the transmitted packet */
-#undef DEBUG_TX_FAIL		/* Normal failure conditions */
-#define DEBUG_TX_ERROR		/* Unexpected conditions */
-#undef DEBUG_RX_TRACE		/* transmission calls */
-#undef DEBUG_RX_INFO		/* header of the received packet */
-#undef DEBUG_RX_FAIL		/* Normal failure conditions */
-#define DEBUG_RX_ERROR		/* Unexpected conditions */
-
-#undef DEBUG_PACKET_DUMP	/* Dump packet on the screen if defined to 32. */
-#undef DEBUG_IOCTL_TRACE	/* misc. call by Linux */
-#undef DEBUG_IOCTL_INFO		/* various debugging info */
-#define DEBUG_IOCTL_ERROR	/* what's going wrong */
-#define DEBUG_BASIC_SHOW	/* Show basic startup info. */
-#undef DEBUG_VERSION_SHOW	/* Print version info. */
-#undef DEBUG_PSA_SHOW		/* Dump PSA to screen. */
-#undef DEBUG_MMC_SHOW		/* Dump mmc to screen. */
-#undef DEBUG_SHOW_UNUSED	/* Show unused fields too. */
-#undef DEBUG_I82586_SHOW	/* Show i82586 status. */
-#undef DEBUG_DEVICE_SHOW	/* Show device parameters. */
-
-/************************ CONSTANTS & MACROS ************************/
-
-#ifdef DEBUG_VERSION_SHOW
-static const char	*version	= "wavelan.c : v24 (SMP + wireless extensions) 11/12/01\n";
-#endif
-
-/* Watchdog temporisation */
-#define	WATCHDOG_JIFFIES	(512*HZ/100)
-
-/* ------------------------ PRIVATE IOCTL ------------------------ */
-
-#define SIOCSIPQTHR	SIOCIWFIRSTPRIV		/* Set quality threshold */
-#define SIOCGIPQTHR	SIOCIWFIRSTPRIV + 1	/* Get quality threshold */
-
-#define SIOCSIPHISTO	SIOCIWFIRSTPRIV + 2	/* Set histogram ranges */
-#define SIOCGIPHISTO	SIOCIWFIRSTPRIV + 3	/* Get histogram values */
-
-/****************************** TYPES ******************************/
-
-/* Shortcuts */
-typedef struct iw_statistics	iw_stats;
-typedef struct iw_quality	iw_qual;
-typedef struct iw_freq		iw_freq;typedef struct net_local	net_local;
-typedef struct timer_list	timer_list;
-
-/* Basic types */
-typedef u_char		mac_addr[WAVELAN_ADDR_SIZE];	/* Hardware address */
-
-/*
- * Static specific data for the interface.
- *
- * For each network interface, Linux keeps data in two structures:  "device"
- * keeps the generic data (same format for everybody) and "net_local" keeps
- * additional specific data.
- */
-struct net_local
-{
-  net_local *	next;		/* linked list of the devices */
-  struct net_device *	dev;		/* reverse link */
-  spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
-  int		nresets;	/* number of hardware resets */
-  u_char	reconfig_82586;	/* We need to reconfigure the controller. */
-  u_char	promiscuous;	/* promiscuous mode */
-  int		mc_count;	/* number of multicast addresses */
-  u_short	hacr;		/* current host interface state */
-
-  int		tx_n_in_use;
-  u_short	rx_head;
-  u_short	rx_last;
-  u_short	tx_first_free;
-  u_short	tx_first_in_use;
-
-  iw_stats	wstats;		/* Wireless-specific statistics */
-
-  struct iw_spy_data	spy_data;
-  struct iw_public_data	wireless_data;
-
-#ifdef HISTOGRAM
-  int		his_number;		/* number of intervals */
-  u_char	his_range[16];		/* boundaries of interval ]n-1; n] */
-  u_long	his_sum[16];		/* sum in interval */
-#endif	/* HISTOGRAM */
-};
-
-/**************************** PROTOTYPES ****************************/
-
-/* ----------------------- MISC. SUBROUTINES ------------------------ */
-static u_char
-	wv_irq_to_psa(int);
-static int
-	wv_psa_to_irq(u_char);
-/* ------------------- HOST ADAPTER SUBROUTINES ------------------- */
-static inline u_short		/* data */
-	hasr_read(u_long);	/* Read the host interface:  base address */
-static inline void
-	hacr_write(u_long,	/* Write to host interface:  base address */
-		   u_short),	/* data */
-	hacr_write_slow(u_long,
-		   u_short),
-	set_chan_attn(u_long,	/* ioaddr */
-		      u_short),	/* hacr   */
-	wv_hacr_reset(u_long),	/* ioaddr */
-	wv_16_off(u_long,	/* ioaddr */
-		  u_short),	/* hacr   */
-	wv_16_on(u_long,	/* ioaddr */
-		 u_short),	/* hacr   */
-	wv_ints_off(struct net_device *),
-	wv_ints_on(struct net_device *);
-/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
-static void
-	psa_read(u_long,	/* Read the Parameter Storage Area. */
-		 u_short,	/* hacr */
-		 int,		/* offset in PSA */
-		 u_char *,	/* buffer to fill */
-		 int),		/* size to read */
-	psa_write(u_long, 	/* Write to the PSA. */
-		  u_short,	/* hacr */
-		  int,		/* offset in PSA */
-		  u_char *,	/* buffer in memory */
-		  int);		/* length of buffer */
-static inline void
-	mmc_out(u_long,		/* Write 1 byte to the Modem Manag Control. */
-		u_short,
-		u_char),
-	mmc_write(u_long,	/* Write n bytes to the MMC. */
-		  u_char,
-		  u_char *,
-		  int);
-static inline u_char		/* Read 1 byte from the MMC. */
-	mmc_in(u_long,
-	       u_short);
-static inline void
-	mmc_read(u_long,	/* Read n bytes from the MMC. */
-		 u_char,
-		 u_char *,
-		 int),
-	fee_wait(u_long,	/* Wait for frequency EEPROM:  base address */
-		 int,		/* base delay to wait for */
-		 int);		/* time to wait */
-static void
-	fee_read(u_long,	/* Read the frequency EEPROM:  base address */
-		 u_short,	/* destination offset */
-		 u_short *,	/* data buffer */
-		 int);		/* number of registers */
-/* ---------------------- I82586 SUBROUTINES ----------------------- */
-static /*inline*/ void
-	obram_read(u_long,	/* ioaddr */
-		   u_short,	/* o */
-		   u_char *,	/* b */
-		   int);	/* n */
-static inline void
-	obram_write(u_long,	/* ioaddr */
-		    u_short,	/* o */
-		    u_char *,	/* b */
-		    int);	/* n */
-static void
-	wv_ack(struct net_device *);
-static inline int
-	wv_synchronous_cmd(struct net_device *,
-			   const char *),
-	wv_config_complete(struct net_device *,
-			   u_long,
-			   net_local *);
-static int
-	wv_complete(struct net_device *,
-		    u_long,
-		    net_local *);
-static inline void
-	wv_82586_reconfig(struct net_device *);
-/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
-#ifdef DEBUG_I82586_SHOW
-static void
-	wv_scb_show(unsigned short);
-#endif
-static inline void
-	wv_init_info(struct net_device *);	/* display startup info */
-/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static iw_stats *
-	wavelan_get_wireless_stats(struct net_device *);
-static void
-	wavelan_set_multicast_list(struct net_device *);
-/* ----------------------- PACKET RECEPTION ----------------------- */
-static inline void
-	wv_packet_read(struct net_device *,	/* Read a packet from a frame. */
-		       u_short,
-		       int),
-	wv_receive(struct net_device *);	/* Read all packets waiting. */
-/* --------------------- PACKET TRANSMISSION --------------------- */
-static inline int
-	wv_packet_write(struct net_device *,	/* Write a packet to the Tx buffer. */
-			void *,
-			short);
-static netdev_tx_t
-	wavelan_packet_xmit(struct sk_buff *,	/* Send a packet. */
-			    struct net_device *);
-/* -------------------- HARDWARE CONFIGURATION -------------------- */
-static inline int
-	wv_mmc_init(struct net_device *),	/* Initialize the modem. */
-	wv_ru_start(struct net_device *),	/* Start the i82586 receiver unit. */
-	wv_cu_start(struct net_device *),	/* Start the i82586 command unit. */
-	wv_82586_start(struct net_device *);	/* Start the i82586. */
-static void
-	wv_82586_config(struct net_device *);	/* Configure the i82586. */
-static inline void
-	wv_82586_stop(struct net_device *);
-static int
-	wv_hw_reset(struct net_device *),	/* Reset the WaveLAN hardware. */
-	wv_check_ioaddr(u_long,		/* ioaddr */
-			u_char *);	/* mac address (read) */
-/* ---------------------- INTERRUPT HANDLING ---------------------- */
-static irqreturn_t
-	wavelan_interrupt(int,		/* interrupt handler */
-			  void *);
-static void
-	wavelan_watchdog(struct net_device *);	/* transmission watchdog */
-/* ------------------- CONFIGURATION CALLBACKS ------------------- */
-static int
-	wavelan_open(struct net_device *),	/* Open the device. */
-	wavelan_close(struct net_device *),	/* Close the device. */
-	wavelan_config(struct net_device *, unsigned short);/* Configure one device. */
-extern struct net_device *wavelan_probe(int unit);	/* See Space.c. */
-
-/**************************** VARIABLES ****************************/
-
-/*
- * This is the root of the linked list of WaveLAN drivers
- * It is use to verify that we don't reuse the same base address
- * for two different drivers and to clean up when removing the module.
- */
-static net_local *	wavelan_list	= (net_local *) NULL;
-
-/*
- * This table is used to translate the PSA value to IRQ number
- * and vice versa.
- */
-static u_char	irqvals[]	=
-{
-	   0,    0,    0, 0x01,
-	0x02, 0x04,    0, 0x08,
-	   0,    0, 0x10, 0x20,
-	0x40,    0,    0, 0x80,
-};
-
-/*
- * Table of the available I/O addresses (base addresses) for WaveLAN
- */
-static unsigned short	iobase[]	=
-{
-#if	0
-  /* Leave out 0x3C0 for now -- seems to clash with some video
-   * controllers.
-   * Leave out the others too -- we will always use 0x390 and leave
-   * 0x300 for the Ethernet device.
-   * Jean II:  0x3E0 is fine as well.
-   */
-  0x300, 0x390, 0x3E0, 0x3C0
-#endif	/* 0 */
-  0x390, 0x3E0
-};
-
-#ifdef	MODULE
-/* Parameters set by insmod */
-static int	io[4];
-static int	irq[4];
-static char	*name[4];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(name, charp, NULL, 0);
-
-MODULE_PARM_DESC(io, "WaveLAN I/O base address(es),required");
-MODULE_PARM_DESC(irq, "WaveLAN IRQ number(s)");
-MODULE_PARM_DESC(name, "WaveLAN interface neme(s)");
-#endif	/* MODULE */
-
-#endif	/* WAVELAN_P_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 menuconfig WL12XX
 	tristate "TI wl12xx driver support"
-	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && EXPERIMENTAL
 	---help---
 	  This will enable TI wl12xx driver support. The drivers make
 	  use of the mac80211 stack.
@@ -42,6 +42,7 @@ config WL1251_SDIO
 config WL1271
 	tristate "TI wl1271 support"
 	depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS
+	depends on INET
 	select FW_LOADER
 	select CRC7
 	---help---
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.c	2010-02-24 13:52:17.000000000 -0500
@@ -494,7 +494,7 @@ out:
 	return ret;
 }
 
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl)
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
 {
 	struct acx_beacon_filter_option *beacon_filter;
 	int ret;
@@ -507,7 +507,7 @@ int wl1251_acx_beacon_filter_opt(struct
 		goto out;
 	}
 
-	beacon_filter->enable = 0;
+	beacon_filter->enable = enable_filter;
 	beacon_filter->max_num_beacons = 0;
 
 	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
@@ -525,6 +525,7 @@ out:
 int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
 {
 	struct acx_beacon_filter_ie_table *ie_table;
+	int idx = 0;
 	int ret;
 
 	wl1251_debug(DEBUG_ACX, "acx beacon filter table");
@@ -535,8 +536,10 @@ int wl1251_acx_beacon_filter_table(struc
 		goto out;
 	}
 
-	ie_table->num_ie = 0;
-	memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+	/* configure default beacon pass-through rules */
+	ie_table->num_ie = 1;
+	ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
+	ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
 
 	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 				   ie_table, sizeof(*ie_table));
@@ -550,6 +553,35 @@ out:
 	return ret;
 }
 
+int wl1251_acx_conn_monit_params(struct wl1251 *wl)
+{
+	struct acx_conn_monit_params *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
+	acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
+
+	ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("failed to set connection monitor "
+			       "parameters: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
 int wl1251_acx_sg_enable(struct wl1251 *wl)
 {
 	struct acx_bt_wlan_coex *pta;
@@ -916,3 +948,31 @@ out:
 	kfree(mem_conf);
 	return ret;
 }
+
+int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
+{
+	struct wl1251_acx_wr_tbtt_and_dtim *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->tbtt = tbtt;
+	acx->dtim = dtim;
+
+	ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("failed to set tbtt and dtim: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_acx.h	2010-02-24 13:52:17.000000000 -0500
@@ -450,6 +450,11 @@ struct acx_beacon_filter_option {
 			   (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
 			    BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
 
+#define BEACON_RULE_PASS_ON_CHANGE                     BIT(0)
+#define BEACON_RULE_PASS_ON_APPEARANCE                 BIT(1)
+
+#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN         (37)
+
 struct acx_beacon_filter_ie_table {
 	struct acx_header header;
 
@@ -458,6 +463,16 @@ struct acx_beacon_filter_ie_table {
 	u8 pad[3];
 } __attribute__ ((packed));
 
+#define SYNCH_FAIL_DEFAULT_THRESHOLD    10     /* number of beacons */
+#define NO_BEACON_DEFAULT_TIMEOUT       (500) /* in microseconds */
+
+struct acx_conn_monit_params {
+	struct acx_header header;
+
+	u32 synch_fail_thold; /* number of beacons missed */
+	u32 bss_lose_timeout; /* number of TU's from synch fail */
+};
+
 enum {
 	SG_ENABLE = 0,
 	SG_DISABLE,
@@ -1134,6 +1149,23 @@ struct wl1251_acx_mem_map {
 	u32 num_rx_mem_blocks;
 } __attribute__ ((packed));
 
+
+struct wl1251_acx_wr_tbtt_and_dtim {
+
+	struct acx_header header;
+
+	/* Time in TUs between two consecutive beacons */
+	u16 tbtt;
+
+	/*
+	 * DTIM period
+	 * For BSS: Number of TBTTs in a DTIM period (range: 1-10)
+	 * For IBSS: value shall be set to 1
+	*/
+	u8  dtim;
+	u8  padding;
+} __attribute__ ((packed));
+
 /*************************************************************************
 
     Host Interrupt Register (WiLink -> Host)
@@ -1273,8 +1305,9 @@ int wl1251_acx_slot(struct wl1251 *wl, e
 int wl1251_acx_group_address_tbl(struct wl1251 *wl);
 int wl1251_acx_service_period_timeout(struct wl1251 *wl);
 int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl);
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
 int wl1251_acx_beacon_filter_table(struct wl1251 *wl);
+int wl1251_acx_conn_monit_params(struct wl1251 *wl);
 int wl1251_acx_sg_enable(struct wl1251 *wl);
 int wl1251_acx_sg_cfg(struct wl1251 *wl);
 int wl1251_acx_cca_threshold(struct wl1251 *wl);
@@ -1288,5 +1321,6 @@ int wl1251_acx_statistics(struct wl1251
 int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
 int wl1251_acx_rate_policies(struct wl1251 *wl);
 int wl1251_acx_mem_cfg(struct wl1251 *wl);
+int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
 
 #endif /* __WL1251_ACX_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_boot.c	2010-02-24 13:52:17.000000000 -0500
@@ -256,7 +256,7 @@ int wl1251_boot_run_firmware(struct wl12
 		}
 	}
 
-	if (loop >= INIT_LOOP) {
+	if (loop > INIT_LOOP) {
 		wl1251_error("timeout waiting for the hardware to "
 			     "complete initialization");
 		return -EIO;
@@ -296,8 +296,12 @@ int wl1251_boot_run_firmware(struct wl12
 		WL1251_ACX_INTR_INIT_COMPLETE;
 	wl1251_boot_target_enable_interrupts(wl);
 
-	/* unmask all mbox events  */
-	wl->event_mask = 0xffffffff;
+	wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
+		SYNCHRONIZATION_TIMEOUT_EVENT_ID |
+		ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
+		ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
+		REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
+		BT_PTA_PREDICTION_EVENT_ID;
 
 	ret = wl1251_event_unmask(wl);
 	if (ret < 0) {
@@ -314,8 +318,8 @@ int wl1251_boot_run_firmware(struct wl12
 static int wl1251_boot_upload_firmware(struct wl1251 *wl)
 {
 	int addr, chunk_num, partition_limit;
-	size_t fw_data_len;
-	u8 *p;
+	size_t fw_data_len, len;
+	u8 *p, *buf;
 
 	/* whal_FwCtrl_LoadFwImageSm() */
 
@@ -334,6 +338,12 @@ static int wl1251_boot_upload_firmware(s
 		return -EIO;
 	}
 
+	buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+	if (!buf) {
+		wl1251_error("allocation for firmware upload chunk failed");
+		return -ENOMEM;
+	}
+
 	wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
 			     WL1251_PART_DOWN_MEM_SIZE,
 			     WL1251_PART_DOWN_REG_START,
@@ -364,7 +374,11 @@ static int wl1251_boot_upload_firmware(s
 		p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
 		wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
 			     p, addr);
-		wl1251_mem_write(wl, addr, p, CHUNK_SIZE);
+
+		/* need to copy the chunk for dma */
+		len = CHUNK_SIZE;
+		memcpy(buf, p, len);
+		wl1251_mem_write(wl, addr, buf, len);
 
 		chunk_num++;
 	}
@@ -372,9 +386,16 @@ static int wl1251_boot_upload_firmware(s
 	/* 10.4 upload the last chunk */
 	addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
 	p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+
+	/* need to copy the chunk for dma */
+	len = fw_data_len % CHUNK_SIZE;
+	memcpy(buf, p, len);
+
 	wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
-		     fw_data_len % CHUNK_SIZE, p, addr);
-	wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+		     len, p, addr);
+	wl1251_mem_write(wl, addr, buf, len);
+
+	kfree(buf);
 
 	return 0;
 }
@@ -473,13 +494,19 @@ int wl1251_boot(struct wl1251 *wl)
 		goto out;
 
 	/* 2. start processing NVS file */
-	ret = wl1251_boot_upload_nvs(wl);
-	if (ret < 0)
-		goto out;
+	if (wl->use_eeprom) {
+		wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
+		msleep(4000);
+		wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
+	} else {
+		ret = wl1251_boot_upload_nvs(wl);
+		if (ret < 0)
+			goto out;
 
-	/* write firmware's last address (ie. it's length) to
-	 * ACX_EEPROMLESS_IND_REG */
-	wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+		/* write firmware's last address (ie. it's length) to
+		 * ACX_EEPROMLESS_IND_REG */
+		wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+	}
 
 	/* 6. read the EEPROM parameters */
 	tmp = wl1251_reg_read32(wl, SCR_PAD2);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_event.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_event.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_event.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,6 +79,21 @@ static int wl1251_event_process(struct w
 		}
 	}
 
+	if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
+		wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
+
+		/* indicate to the stack, that beacons have been lost */
+		ieee80211_beacon_loss(wl->vif);
+	}
+
+	if (vector & REGAINED_BSS_EVENT_ID) {
+		if (wl->psm_requested) {
+			ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251.h	2013-05-03 14:04:10.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251.h	2013-05-03 12:11:41.000000000 -0400
@@ -269,6 +269,7 @@ struct wl1251 {
 
 	void (*set_power)(bool enable);
 	int irq;
+	bool use_eeprom;
 
 	enum wl1251_state state;
 	struct mutex mutex;
@@ -354,6 +355,8 @@ struct wl1251 {
 	/* is firmware in elp mode */
 	bool elp;
 
+	struct delayed_work elp_work;
+
 	/* we can be in psm, but not in elp, we have to differentiate */
 	bool psm;
 
@@ -374,6 +377,8 @@ struct wl1251 {
 	u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
 	struct wl1251_rx_descriptor *rx_descriptor;
 
+	struct ieee80211_vif *vif;
+
 	u32 chip_id;
 	char fw_ver[21];
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -147,7 +147,8 @@ int wl1251_hw_init_beacon_filter(struct
 {
 	int ret;
 
-	ret = wl1251_acx_beacon_filter_opt(wl);
+	/* disable beacon filtering at this stage */
+	ret = wl1251_acx_beacon_filter_opt(wl, false);
 	if (ret < 0)
 		return ret;
 
@@ -364,6 +365,11 @@ int wl1251_hw_init(struct wl1251 *wl)
 	if (ret < 0)
 		goto out_free_data_path;
 
+	/* Initialize connection monitoring thresholds */
+	ret = wl1251_acx_conn_monit_params(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
 	/* Beacon filtering */
 	ret = wl1251_hw_init_beacon_filter(wl);
 	if (ret < 0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c	2013-05-03 14:04:08.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_main.c	2013-05-03 12:11:39.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/irq.h>
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
@@ -83,7 +84,7 @@ static int wl1251_fetch_firmware(struct
 	}
 
 	wl->fw_len = fw->size;
-	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+	wl->fw = vmalloc(wl->fw_len);
 
 	if (!wl->fw) {
 		wl1251_error("could not allocate memory for the firmware");
@@ -183,8 +184,11 @@ static int wl1251_chip_wakeup(struct wl1
 		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
 			     wl->chip_id);
 		break;
-	case CHIP_ID_1251_PG10:
 	case CHIP_ID_1251_PG11:
+		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
+			     wl->chip_id);
+		break;
+	case CHIP_ID_1251_PG10:
 	default:
 		wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
 		ret = -ENODEV;
@@ -208,9 +212,10 @@ out:
 	return ret;
 }
 
+#define WL1251_IRQ_LOOP_COUNT 10
 static void wl1251_irq_work(struct work_struct *work)
 {
-	u32 intr;
+	u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
 	struct wl1251 *wl =
 		container_of(work, struct wl1251, irq_work);
 	int ret;
@@ -231,78 +236,86 @@ static void wl1251_irq_work(struct work_
 	intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
 	wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
 
-	if (wl->data_path) {
-		wl->rx_counter =
-			wl1251_mem_read32(wl, wl->data_path->rx_control_addr);
-
-		/* We handle a frmware bug here */
-		switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
-		case 0:
-			wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync");
-			intr &= ~WL1251_ACX_INTR_RX0_DATA;
-			intr &= ~WL1251_ACX_INTR_RX1_DATA;
-			break;
-		case 1:
-			wl1251_debug(DEBUG_IRQ, "RX: FW +1");
-			intr |= WL1251_ACX_INTR_RX0_DATA;
-			intr &= ~WL1251_ACX_INTR_RX1_DATA;
-			break;
-		case 2:
-			wl1251_debug(DEBUG_IRQ, "RX: FW +2");
-			intr |= WL1251_ACX_INTR_RX0_DATA;
-			intr |= WL1251_ACX_INTR_RX1_DATA;
-			break;
-		default:
-			wl1251_warning("RX: FW and host out of sync: %d",
-				       wl->rx_counter - wl->rx_handled);
-			break;
-		}
+	do {
+		if (wl->data_path) {
+			wl->rx_counter = wl1251_mem_read32(
+				wl, wl->data_path->rx_control_addr);
 
-		wl->rx_handled = wl->rx_counter;
+			/* We handle a frmware bug here */
+			switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+			case 0:
+				wl1251_debug(DEBUG_IRQ,
+					     "RX: FW and host in sync");
+				intr &= ~WL1251_ACX_INTR_RX0_DATA;
+				intr &= ~WL1251_ACX_INTR_RX1_DATA;
+				break;
+			case 1:
+				wl1251_debug(DEBUG_IRQ, "RX: FW +1");
+				intr |= WL1251_ACX_INTR_RX0_DATA;
+				intr &= ~WL1251_ACX_INTR_RX1_DATA;
+				break;
+			case 2:
+				wl1251_debug(DEBUG_IRQ, "RX: FW +2");
+				intr |= WL1251_ACX_INTR_RX0_DATA;
+				intr |= WL1251_ACX_INTR_RX1_DATA;
+				break;
+			default:
+				wl1251_warning(
+					"RX: FW and host out of sync: %d",
+					wl->rx_counter - wl->rx_handled);
+				break;
+			}
 
+			wl->rx_handled = wl->rx_counter;
 
-		wl1251_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
-	}
+			wl1251_debug(DEBUG_IRQ, "RX counter: %d",
+				     wl->rx_counter);
+		}
 
-	intr &= wl->intr_mask;
+		intr &= wl->intr_mask;
 
-	if (intr == 0) {
-		wl1251_debug(DEBUG_IRQ, "INTR is 0");
-		wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
-				   ~(wl->intr_mask));
+		if (intr == 0) {
+			wl1251_debug(DEBUG_IRQ, "INTR is 0");
+			goto out_sleep;
+		}
 
-		goto out_sleep;
-	}
+		if (intr & WL1251_ACX_INTR_RX0_DATA) {
+			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+			wl1251_rx(wl);
+		}
 
-	if (intr & WL1251_ACX_INTR_RX0_DATA) {
-		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
-		wl1251_rx(wl);
-	}
+		if (intr & WL1251_ACX_INTR_RX1_DATA) {
+			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+			wl1251_rx(wl);
+		}
 
-	if (intr & WL1251_ACX_INTR_RX1_DATA) {
-		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
-		wl1251_rx(wl);
-	}
+		if (intr & WL1251_ACX_INTR_TX_RESULT) {
+			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+			wl1251_tx_complete(wl);
+		}
 
-	if (intr & WL1251_ACX_INTR_TX_RESULT) {
-		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
-		wl1251_tx_complete(wl);
-	}
+		if (intr & (WL1251_ACX_INTR_EVENT_A |
+			    WL1251_ACX_INTR_EVENT_B)) {
+			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)",
+				     intr);
+			if (intr & WL1251_ACX_INTR_EVENT_A)
+				wl1251_event_handle(wl, 0);
+			else
+				wl1251_event_handle(wl, 1);
+		}
 
-	if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
-		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
-		if (intr & WL1251_ACX_INTR_EVENT_A)
-			wl1251_event_handle(wl, 0);
-		else
-			wl1251_event_handle(wl, 1);
-	}
+		if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+			wl1251_debug(DEBUG_IRQ,
+				     "WL1251_ACX_INTR_INIT_COMPLETE");
 
-	if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
-		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
+		if (--ctr == 0)
+			break;
 
-	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+		intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+	} while (intr);
 
 out_sleep:
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
 	wl1251_ps_elp_sleep(wl);
 
 out:
@@ -506,6 +519,12 @@ static int wl1251_op_add_interface(struc
 		     conf->type, conf->mac_addr);
 
 	mutex_lock(&wl->mutex);
+	if (wl->vif) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl->vif = conf->vif;
 
 	switch (conf->type) {
 	case NL80211_IFTYPE_STATION:
@@ -535,7 +554,12 @@ out:
 static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
 					 struct ieee80211_if_init_conf *conf)
 {
+	struct wl1251 *wl = hw->priv;
+
+	mutex_lock(&wl->mutex);
 	wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
+	wl->vif = NULL;
+	mutex_unlock(&wl->mutex);
 }
 
 static int wl1251_build_null_data(struct wl1251 *wl)
@@ -552,7 +576,8 @@ static int wl1251_build_null_data(struct
 
 	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
 	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
-						IEEE80211_STYPE_NULLFUNC);
+						IEEE80211_STYPE_NULLFUNC |
+						IEEE80211_FCTL_TODS);
 
 	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
 				       sizeof(template));
@@ -565,7 +590,10 @@ static int wl1251_build_ps_poll(struct w
 
 	memcpy(template.bssid, wl->bssid, ETH_ALEN);
 	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
-	template.aid = aid;
+
+	/* aid in PS-Poll has its two MSBs each set to 1 */
+	template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
+
 	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
 
 	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
@@ -601,10 +629,6 @@ static int wl1251_op_config(struct ieee8
 			goto out_sleep;
 	}
 
-	ret = wl1251_build_null_data(wl);
-	if (ret < 0)
-		goto out_sleep;
-
 	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
 		wl1251_debug(DEBUG_PSM, "psm enabled");
 
@@ -1082,13 +1106,28 @@ static void wl1251_op_bss_info_changed(s
 	if (ret < 0)
 		goto out;
 
+	if (changed & BSS_CHANGED_BSSID) {
+		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+		ret = wl1251_build_null_data(wl);
+		if (ret < 0)
+			goto out;
+
+		if (wl->bss_type != BSS_TYPE_IBSS) {
+			ret = wl1251_join(wl, wl->bss_type, wl->channel,
+					  wl->beacon_int, wl->dtim_period);
+			if (ret < 0)
+				goto out_sleep;
+		}
+	}
+
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (bss_conf->assoc) {
 			wl->beacon_int = bss_conf->beacon_int;
 			wl->dtim_period = bss_conf->dtim_period;
 
-			/* FIXME: call join */
-
+			ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
+							  wl->dtim_period);
 			wl->aid = bss_conf->aid;
 
 			ret = wl1251_build_ps_poll(wl, wl->aid);
@@ -1141,23 +1180,6 @@ static void wl1251_op_bss_info_changed(s
 		}
 	}
 
-	if (changed & BSS_CHANGED_BSSID) {
-		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
-
-		ret = wl1251_build_null_data(wl);
-		if (ret < 0)
-			goto out;
-
-		if (wl->bss_type != BSS_TYPE_IBSS) {
-			ret = wl1251_join(wl, wl->bss_type, wl->channel,
-					  wl->beacon_int, wl->dtim_period);
-			if (ret < 0)
-				goto out_sleep;
-			wl1251_warning("Set ctsprotect failed %d", ret);
-			goto out_sleep;
-		}
-	}
-
 	if (changed & BSS_CHANGED_BEACON) {
 		beacon = ieee80211_beacon_get(hw, vif);
 		ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
@@ -1308,7 +1330,9 @@ int wl1251_init_ieee80211(struct wl1251
 	wl->hw->channel_change_time = 10000;
 
 	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		IEEE80211_HW_NOISE_DBM;
+		IEEE80211_HW_NOISE_DBM |
+		IEEE80211_HW_SUPPORTS_PS |
+		IEEE80211_HW_BEACON_FILTER;
 
 	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 	wl->hw->wiphy->max_scan_ssids = 1;
@@ -1351,6 +1375,7 @@ struct ieee80211_hw *wl1251_alloc_hw(voi
 	skb_queue_head_init(&wl->tx_queue);
 
 	INIT_WORK(&wl->filter_work, wl1251_filter_work);
+	INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
 	wl->channel = WL1251_DEFAULT_CHANNEL;
 	wl->scanning = false;
 	wl->default_key = 0;
@@ -1368,6 +1393,7 @@ struct ieee80211_hw *wl1251_alloc_hw(voi
 	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
 	wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
 	wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
+	wl->vif = NULL;
 
 	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
 		wl->tx_frames[i] = NULL;
@@ -1409,7 +1435,7 @@ int wl1251_free_hw(struct wl1251 *wl)
 
 	kfree(wl->target_mem_map);
 	kfree(wl->data_path);
-	kfree(wl->fw);
+	vfree(wl->fw);
 	wl->fw = NULL;
 	kfree(wl->nvs);
 	wl->nvs = NULL;
@@ -1426,4 +1452,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw);
 MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
-MODULE_ALIAS("spi:wl12xx");
+MODULE_ALIAS("spi:wl1251");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_netlink.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_netlink.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_netlink.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_netlink.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@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
- *
- */
-
-#ifndef __WL1251_NETLINK_H__
-#define __WL1251_NETLINK_H__
-
-int wl1251_nl_register(void);
-void wl1251_nl_unregister(void);
-
-#endif /* __WL1251_NETLINK_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,17 +28,41 @@
 
 #define WL1251_WAKEUP_TIMEOUT 2000
 
-/* Routines to toggle sleep mode while in ELP */
-void wl1251_ps_elp_sleep(struct wl1251 *wl)
+void wl1251_elp_work(struct work_struct *work)
 {
+	struct delayed_work *dwork;
+	struct wl1251 *wl;
+
+	dwork = container_of(work, struct delayed_work, work);
+	wl = container_of(dwork, struct wl1251, elp_work);
+
+	wl1251_debug(DEBUG_PSM, "elp work");
+
+	mutex_lock(&wl->mutex);
+
 	if (wl->elp || !wl->psm)
-		return;
+		goto out;
 
 	wl1251_debug(DEBUG_PSM, "chip to elp");
-
 	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
-
 	wl->elp = true;
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+#define ELP_ENTRY_DELAY  5
+
+/* Routines to toggle sleep mode while in ELP */
+void wl1251_ps_elp_sleep(struct wl1251 *wl)
+{
+	unsigned long delay;
+
+	if (wl->psm) {
+		cancel_delayed_work(&wl->elp_work);
+		delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
+		ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
+	}
 }
 
 int wl1251_ps_elp_wakeup(struct wl1251 *wl)
@@ -119,6 +143,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl
 	case STATION_POWER_SAVE_MODE:
 		wl1251_debug(DEBUG_PSM, "entering psm");
 
+		/* enable beacon filtering */
+		ret = wl1251_acx_beacon_filter_opt(wl, true);
+		if (ret < 0)
+			return ret;
+
 		ret = wl1251_acx_wake_up_conditions(wl,
 						    WAKE_UP_EVENT_DTIM_BITMAP,
 						    wl->listen_int);
@@ -142,6 +171,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl
 		if (ret < 0)
 			return ret;
 
+		/* disable beacon filtering */
+		ret = wl1251_acx_beacon_filter_opt(wl, false);
+		if (ret < 0)
+			return ret;
+
 		ret = wl1251_acx_wake_up_conditions(wl,
 						    WAKE_UP_EVENT_DTIM_BITMAP,
 						    wl->listen_int);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_ps.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
 void wl1251_ps_elp_sleep(struct wl1251 *wl);
 int wl1251_ps_elp_wakeup(struct wl1251 *wl);
+void wl1251_elp_work(struct work_struct *work);
 
 
 #endif /* __WL1251_PS_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -370,6 +370,7 @@ enum wl12xx_acx_int_reg {
  EEPROM location specified in the EE_ADDR register.
  The Wlan hardware hardware clears this bit automatically.
 *===============================================*/
+#define EE_CTL                              (REGISTERS_BASE + 0x2000)
 #define ACX_EE_CTL_REG                      EE_CTL
 #define EE_WRITE                            0x00000001ul
 #define EE_READ                             0x00000002ul
@@ -380,6 +381,7 @@ enum wl12xx_acx_int_reg {
   This register specifies the address
   within the EEPROM from/to which to read/write data.
   ===============================================*/
+#define EE_ADDR                             (REGISTERS_BASE + 0x2008)
 #define ACX_EE_ADDR_REG                     EE_ADDR
 
 /*===============================================
@@ -389,8 +391,12 @@ enum wl12xx_acx_int_reg {
   data from the EEPROM or the write data
   to be written to the EEPROM.
   ===============================================*/
+#define EE_DATA                             (REGISTERS_BASE + 0x2004)
 #define ACX_EE_DATA_REG                     EE_DATA
 
+#define EEPROM_ACCESS_TO                    10000   /* timeout counter */
+#define START_EEPROM_MGR                    0x00000001
+
 /*===============================================
   EEPROM Base Address  - 32bit RW
   ------------------------------------------
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,10 +72,6 @@ static void wl1251_rx_status(struct wl12
 	}
 
 	status->signal = desc->rssi;
-	status->qual = (desc->rssi - WL1251_RX_MIN_RSSI) * 100 /
-		(WL1251_RX_MAX_RSSI - WL1251_RX_MIN_RSSI);
-	status->qual = min(status->qual, 100);
-	status->qual = max(status->qual, 0);
 
 	/*
 	 * FIXME: guessing that snr needs to be divided by two, otherwise
@@ -153,7 +149,7 @@ static void wl1251_rx_body(struct wl1251
 		     beacon ? "beacon" : "");
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-	ieee80211_rx(wl->hw, skb);
+	ieee80211_rx_ni(wl->hw, skb);
 }
 
 static void wl1251_rx_ack(struct wl1251 *wl)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1251_spi.c	2010-02-24 13:52:17.000000000 -0500
@@ -270,6 +270,8 @@ static int __devinit wl1251_spi_probe(st
 		return -ENODEV;
 	}
 
+	wl->use_eeprom = pdata->use_eeprom;
+
 	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1251_error("request_irq() failed: %d", ret);
@@ -307,7 +309,7 @@ static int __devexit wl1251_spi_remove(s
 
 static struct spi_driver wl1251_spi_driver = {
 	.driver = {
-		.name		= "wl12xx",
+		.name		= "wl1251",
 		.bus		= &spi_bus_type,
 		.owner		= THIS_MODULE,
 	},
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.c	2010-02-24 13:52:17.000000000 -0500
@@ -34,8 +34,7 @@
 #include "wl1271_spi.h"
 #include "wl1271_ps.h"
 
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
-				  u8 listen_interval)
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
 {
 	struct acx_wake_up_condition *wake_up;
 	int ret;
@@ -48,8 +47,8 @@ int wl1271_acx_wake_up_conditions(struct
 		goto out;
 	}
 
-	wake_up->wake_up_event = wake_up_event;
-	wake_up->listen_interval = listen_interval;
+	wake_up->wake_up_event = wl->conf.conn.wake_up_event;
+	wake_up->listen_interval = wl->conf.conn.listen_interval;
 
 	ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
 				   wake_up, sizeof(*wake_up));
@@ -137,7 +136,12 @@ int wl1271_acx_tx_power(struct wl1271 *w
 		goto out;
 	}
 
-	acx->current_tx_power = power * 10;
+	/*
+	 * FIXME: This is a workaround needed while we don't the correct
+	 * calibration, to avoid distortions
+	 */
+	/* acx->current_tx_power = power * 10; */
+	acx->current_tx_power = 120;
 
 	ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
 	if (ret < 0) {
@@ -193,7 +197,7 @@ int wl1271_acx_mem_map(struct wl1271 *wl
 	return 0;
 }
 
-int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
+int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
 {
 	struct acx_rx_msdu_lifetime *acx;
 	int ret;
@@ -206,7 +210,7 @@ int wl1271_acx_rx_msdu_life_time(struct
 		goto out;
 	}
 
-	acx->lifetime = life_time;
+	acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
 	ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
 				   acx, sizeof(*acx));
 	if (ret < 0) {
@@ -232,8 +236,8 @@ int wl1271_acx_rx_config(struct wl1271 *
 		goto out;
 	}
 
-	rx_config->config_options = config;
-	rx_config->filter_options = filter;
+	rx_config->config_options = cpu_to_le32(config);
+	rx_config->filter_options = cpu_to_le32(filter);
 
 	ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
 				   rx_config, sizeof(*rx_config));
@@ -260,7 +264,7 @@ int wl1271_acx_pd_threshold(struct wl127
 		goto out;
 	}
 
-	/* FIXME: threshold value not set */
+	pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold);
 
 	ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
 	if (ret < 0) {
@@ -300,7 +304,8 @@ out:
 	return ret;
 }
 
-int wl1271_acx_group_address_tbl(struct wl1271 *wl)
+int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
+				 void *mc_list, u32 mc_list_len)
 {
 	struct acx_dot11_grp_addr_tbl *acx;
 	int ret;
@@ -314,9 +319,9 @@ int wl1271_acx_group_address_tbl(struct
 	}
 
 	/* MAC filtering */
-	acx->enabled = 0;
-	acx->num_groups = 0;
-	memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+	acx->enabled = enable;
+	acx->num_groups = mc_list_len;
+	memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
 
 	ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
 				   acx, sizeof(*acx));
@@ -343,8 +348,8 @@ int wl1271_acx_service_period_timeout(st
 
 	wl1271_debug(DEBUG_ACX, "acx service period timeout");
 
-	rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
-	rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+	rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
+	rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
 
 	ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
 				   rx_timeout, sizeof(*rx_timeout));
@@ -372,7 +377,7 @@ int wl1271_acx_rts_threshold(struct wl12
 		goto out;
 	}
 
-	rts->threshold = rts_threshold;
+	rts->threshold = cpu_to_le16(rts_threshold);
 
 	ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 	if (ret < 0) {
@@ -385,20 +390,29 @@ out:
 	return ret;
 }
 
-int wl1271_acx_beacon_filter_opt(struct wl1271 *wl)
+int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
 {
-	struct acx_beacon_filter_option *beacon_filter;
-	int ret;
+	struct acx_beacon_filter_option *beacon_filter = NULL;
+	int ret = 0;
 
 	wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
 
+	if (enable_filter &&
+	    wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
+		goto out;
+
 	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
 	if (!beacon_filter) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	beacon_filter->enable = 0;
+	beacon_filter->enable = enable_filter;
+
+	/*
+	 * When set to zero, and the filter is enabled, beacons
+	 * without the unicast TIM bit set are dropped.
+	 */
 	beacon_filter->max_num_beacons = 0;
 
 	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
@@ -416,7 +430,9 @@ out:
 int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
 {
 	struct acx_beacon_filter_ie_table *ie_table;
+	int i, idx = 0;
 	int ret;
+	bool vendor_spec = false;
 
 	wl1271_debug(DEBUG_ACX, "acx beacon filter table");
 
@@ -426,8 +442,32 @@ int wl1271_acx_beacon_filter_table(struc
 		goto out;
 	}
 
+	/* configure default beacon pass-through rules */
 	ie_table->num_ie = 0;
-	memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+	for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
+		struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
+		ie_table->table[idx++] = r->ie;
+		ie_table->table[idx++] = r->rule;
+
+		if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
+			/* only one vendor specific ie allowed */
+			if (vendor_spec)
+				continue;
+
+			/* for vendor specific rules configure the
+			   additional fields */
+			memcpy(&(ie_table->table[idx]), r->oui,
+			       CONF_BCN_IE_OUI_LEN);
+			idx += CONF_BCN_IE_OUI_LEN;
+			ie_table->table[idx++] = r->type;
+			memcpy(&(ie_table->table[idx]), r->version,
+			       CONF_BCN_IE_VER_LEN);
+			idx += CONF_BCN_IE_VER_LEN;
+			vendor_spec = true;
+		}
+
+		ie_table->num_ie++;
+	}
 
 	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
 				   ie_table, sizeof(*ie_table));
@@ -441,6 +481,36 @@ out:
 	return ret;
 }
 
+int wl1271_acx_conn_monit_params(struct wl1271 *wl)
+{
+	struct acx_conn_monit_params *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx connection monitor parameters");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold);
+	acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout);
+
+	ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("failed to set connection monitor "
+			       "parameters: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+
 int wl1271_acx_sg_enable(struct wl1271 *wl)
 {
 	struct acx_bt_wlan_coex *pta;
@@ -470,6 +540,7 @@ out:
 int wl1271_acx_sg_cfg(struct wl1271 *wl)
 {
 	struct acx_bt_wlan_coex_param *param;
+	struct conf_sg_settings *c = &wl->conf.sg;
 	int ret;
 
 	wl1271_debug(DEBUG_ACX, "acx sg cfg");
@@ -481,34 +552,19 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
 	}
 
 	/* BT-WLAN coext parameters */
-	param->min_rate = RATE_INDEX_24MBPS;
-	param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
-	param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
-	param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
-	param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
-	param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
-	param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
-	param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
-	param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
-	param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
-	param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
-	param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
-	param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
-	param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
-	param->antenna_type = PTA_ANTENNA_TYPE_DEF;
-	param->signal_type = PTA_SIGNALING_TYPE_DEF;
-	param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
-	param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
-	param->max_cts = PTA_MAX_NUM_CTS_DEF;
-	param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
-	param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
-	param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
-	param->wlan_elp_hp = PTA_ELP_HP_DEF;
-	param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
-	param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
-	param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
-	param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
-	param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+	param->per_threshold = cpu_to_le32(c->per_threshold);
+	param->max_scan_compensation_time =
+		cpu_to_le32(c->max_scan_compensation_time);
+	param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval);
+	param->load_ratio = c->load_ratio;
+	param->auto_ps_mode = c->auto_ps_mode;
+	param->probe_req_compensation = c->probe_req_compensation;
+	param->scan_window_compensation = c->scan_window_compensation;
+	param->antenna_config = c->antenna_config;
+	param->beacon_miss_threshold = c->beacon_miss_threshold;
+	param->rate_adaptation_threshold =
+		cpu_to_le32(c->rate_adaptation_threshold);
+	param->rate_adaptation_snr = c->rate_adaptation_snr;
 
 	ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
 	if (ret < 0) {
@@ -534,8 +590,8 @@ int wl1271_acx_cca_threshold(struct wl12
 		goto out;
 	}
 
-	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
-	detection->tx_energy_detection = 0;
+	detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
+	detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
 
 	ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
 				   detection, sizeof(*detection));
@@ -562,10 +618,10 @@ int wl1271_acx_bcn_dtim_options(struct w
 		goto out;
 	}
 
-	bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
-	bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
-	bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
-	bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+	bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
+	bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
+	bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
+	bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
 
 	ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
 	if (ret < 0) {
@@ -591,7 +647,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u1
 		goto out;
 	}
 
-	acx_aid->aid = aid;
+	acx_aid->aid = cpu_to_le16(aid);
 
 	ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
 	if (ret < 0) {
@@ -618,9 +674,8 @@ int wl1271_acx_event_mbox_mask(struct wl
 	}
 
 	/* high event mask is unused */
-	mask->high_event_mask = 0xffffffff;
-
-	mask->event_mask = event_mask;
+	mask->high_event_mask = cpu_to_le32(0xffffffff);
+	mask->event_mask = cpu_to_le32(event_mask);
 
 	ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
 				   mask, sizeof(*mask));
@@ -703,9 +758,10 @@ int wl1271_acx_statistics(struct wl1271
 	return 0;
 }
 
-int wl1271_acx_rate_policies(struct wl1271 *wl)
+int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
 {
 	struct acx_rate_policy *acx;
+	struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
 	int ret = 0;
 
 	wl1271_debug(DEBUG_ACX, "acx rate policies");
@@ -718,11 +774,11 @@ int wl1271_acx_rate_policies(struct wl12
 	}
 
 	/* configure one default (one-size-fits-all) rate class */
-	acx->rate_class_cnt = 1;
-	acx->rate_class[0].enabled_rates = ACX_RATE_MASK_ALL;
-	acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
-	acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
-	acx->rate_class[0].aflags = 0;
+	acx->rate_class_cnt = cpu_to_le32(1);
+	acx->rate_class[0].enabled_rates = cpu_to_le32(enabled_rates);
+	acx->rate_class[0].short_retry_limit = c->short_retry_limit;
+	acx->rate_class[0].long_retry_limit = c->long_retry_limit;
+	acx->rate_class[0].aflags = c->aflags;
 
 	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
 	if (ret < 0) {
@@ -749,22 +805,14 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl)
 		goto out;
 	}
 
-	/*
-	 * FIXME: Configure each AC with appropriate values (most suitable
-	 * values will probably be different for each AC.
-	 */
-	for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
-		acx->ac = i;
-
-		/*
-		 * FIXME: The following default values originate from
-		 * the TI reference driver. What do they mean?
-		 */
-		acx->cw_min = 15;
-		acx->cw_max = 63;
-		acx->aifsn = 3;
+	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+		struct conf_tx_ac_category *c = &(wl->conf.tx.ac_conf[i]);
+		acx->ac = c->ac;
+		acx->cw_min = c->cw_min;
+		acx->cw_max = cpu_to_le16(c->cw_max);
+		acx->aifsn = c->aifsn;
 		acx->reserved = 0;
-		acx->tx_op_limit = 0;
+		acx->tx_op_limit = cpu_to_le16(c->tx_op_limit);
 
 		ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
 		if (ret < 0) {
@@ -793,12 +841,15 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl
 		goto out;
 	}
 
-	/* FIXME: configure each TID with a different AC reference */
-	for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
-		acx->queue_id = i;
-		acx->tsid = WL1271_ACX_AC_BE;
-		acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
-		acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
+	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+		struct conf_tx_tid *c = &(wl->conf.tx.tid_conf[i]);
+		acx->queue_id = c->queue_id;
+		acx->channel_type = c->channel_type;
+		acx->tsid = c->tsid;
+		acx->ps_scheme = c->ps_scheme;
+		acx->ack_policy = c->ack_policy;
+		acx->apsd_conf[0] = cpu_to_le32(c->apsd_conf[0]);
+		acx->apsd_conf[1] = cpu_to_le32(c->apsd_conf[1]);
 
 		ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
 		if (ret < 0) {
@@ -826,7 +877,7 @@ int wl1271_acx_frag_threshold(struct wl1
 		goto out;
 	}
 
-	acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+	acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold);
 	ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
 	if (ret < 0) {
 		wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -852,8 +903,8 @@ int wl1271_acx_tx_config_options(struct
 		goto out;
 	}
 
-	acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
-	acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
+	acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
+	acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
 	ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
 	if (ret < 0) {
 		wl1271_warning("Setting of tx options failed: %d", ret);
@@ -879,11 +930,11 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl
 	}
 
 	/* memory config */
-	mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+	mem_conf->num_stations = DEFAULT_NUM_STATIONS;
 	mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
 	mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
 	mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
-	mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
+	mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
 
 	ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 				   sizeof(*mem_conf));
@@ -906,7 +957,7 @@ int wl1271_acx_init_mem_config(struct wl
 		return ret;
 
 	wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
-					  GFP_KERNEL);
+				     GFP_KERNEL);
 	if (!wl->target_mem_map) {
 		wl1271_error("couldn't allocate target memory map");
 		return -ENOMEM;
@@ -923,7 +974,8 @@ int wl1271_acx_init_mem_config(struct wl
 	}
 
 	/* initialize TX block book keeping */
-	wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
+	wl->tx_blocks_available =
+		le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
 	wl1271_debug(DEBUG_TX, "available tx blocks: %d",
 		     wl->tx_blocks_available);
 
@@ -943,10 +995,10 @@ int wl1271_acx_init_rx_interrupt(struct
 		goto out;
 	}
 
-	rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
-	rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
-	rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
-	rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
+	rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
+	rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
+	rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
+	rx_conf->queue_type = wl->conf.rx.queue_type;
 
 	ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
 				   sizeof(*rx_conf));
@@ -959,3 +1011,124 @@ out:
 	kfree(rx_conf);
 	return ret;
 }
+
+int wl1271_acx_smart_reflex(struct wl1271 *wl)
+{
+	struct acx_smart_reflex_state *sr_state = NULL;
+	struct acx_smart_reflex_config_params *sr_param = NULL;
+	int i, ret;
+
+	wl1271_debug(DEBUG_ACX, "acx smart reflex");
+
+	sr_param = kzalloc(sizeof(*sr_param), GFP_KERNEL);
+	if (!sr_param) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < CONF_SR_ERR_TBL_COUNT; i++) {
+		struct conf_mart_reflex_err_table *e =
+			&(wl->conf.init.sr_err_tbl[i]);
+
+		sr_param->error_table[i].len = e->len;
+		sr_param->error_table[i].upper_limit = e->upper_limit;
+		memcpy(sr_param->error_table[i].values, e->values, e->len);
+	}
+
+	ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_PARAMS,
+				   sr_param, sizeof(*sr_param));
+	if (ret < 0) {
+		wl1271_warning("failed to set smart reflex params: %d", ret);
+		goto out;
+	}
+
+	sr_state = kzalloc(sizeof(*sr_state), GFP_KERNEL);
+	if (!sr_state) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* enable smart reflex */
+	sr_state->enable = wl->conf.init.sr_enable;
+
+	ret = wl1271_cmd_configure(wl, ACX_SET_SMART_REFLEX_STATE,
+				   sr_state, sizeof(*sr_state));
+	if (ret < 0) {
+		wl1271_warning("failed to set smart reflex params: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(sr_state);
+	kfree(sr_param);
+	return ret;
+
+}
+
+int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
+{
+	struct wl1271_acx_bet_enable *acx = NULL;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx bet enable");
+
+	if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
+		goto out;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
+	acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
+
+	ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx bet enable failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
+			     u8 version)
+{
+	struct wl1271_acx_arp_filter *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->version = version;
+	acx->enable = enable;
+
+	if (enable == true) {
+		if (version == ACX_IPV4_VERSION)
+			memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE);
+		else if (version == ACX_IPV6_VERSION)
+			memcpy(acx->address, address, sizeof(acx->address));
+		else
+			wl1271_error("Invalid IP version");
+	}
+
+	ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("failed to set arp ip filter: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_acx.h	2010-02-24 13:52:17.000000000 -0500
@@ -61,8 +61,9 @@
 					    WL1271_ACX_INTR_HW_AVAILABLE  | \
 					    WL1271_ACX_INTR_DATA)
 
-#define WL1271_INTR_MASK                   (WL1271_ACX_INTR_EVENT_A |	\
-					    WL1271_ACX_INTR_EVENT_B | \
+#define WL1271_INTR_MASK                   (WL1271_ACX_INTR_EVENT_A      | \
+					    WL1271_ACX_INTR_EVENT_B      | \
+					    WL1271_ACX_INTR_HW_AVAILABLE | \
 					    WL1271_ACX_INTR_DATA)
 
 /* Target's information element */
@@ -70,11 +71,11 @@ struct acx_header {
 	struct wl1271_cmd_header cmd;
 
 	/* acx (or information element) header */
-	u16 id;
+	__le16 id;
 
 	/* payload length (not including headers */
-	u16 len;
-};
+	__le16 len;
+} __attribute__ ((packed));
 
 struct acx_error_counter {
 	struct acx_header header;
@@ -82,21 +83,21 @@ struct acx_error_counter {
 	/* The number of PLCP errors since the last time this */
 	/* information element was interrogated. This field is */
 	/* automatically cleared when it is interrogated.*/
-	u32 PLCP_error;
+	__le32 PLCP_error;
 
 	/* The number of FCS errors since the last time this */
 	/* information element was interrogated. This field is */
 	/* automatically cleared when it is interrogated.*/
-	u32 FCS_error;
+	__le32 FCS_error;
 
 	/* The number of MPDUs without PLCP header errors received*/
 	/* since the last time this information element was interrogated. */
 	/* This field is automatically cleared when it is interrogated.*/
-	u32 valid_frame;
+	__le32 valid_frame;
 
 	/* the number of missed sequence numbers in the squentially */
 	/* values of frames seq numbers */
-	u32 seq_num_miss;
+	__le32 seq_num_miss;
 } __attribute__ ((packed));
 
 struct acx_revision {
@@ -125,7 +126,7 @@ struct acx_revision {
 	 *              (1 = first spin, 2 = second spin, and so on).
 	 * bits 24 - 31: Chip ID - The WiLink chip ID.
 	 */
-	u32 hw_version;
+	__le32 hw_version;
 } __attribute__ ((packed));
 
 enum wl1271_psm_mode {
@@ -170,7 +171,6 @@ enum {
 #define  DP_RX_PACKET_RING_CHUNK_NUM 2
 #define  DP_TX_PACKET_RING_CHUNK_NUM 2
 #define  DP_TX_COMPLETE_TIME_OUT 20
-#define  FW_TX_CMPLT_BLOCK_SIZE 16
 
 #define TX_MSDU_LIFETIME_MIN       0
 #define TX_MSDU_LIFETIME_MAX       3000
@@ -186,7 +186,7 @@ struct acx_rx_msdu_lifetime {
 	 * The maximum amount of time, in TU, before the
 	 * firmware discards the MSDU.
 	 */
-	u32 lifetime;
+	__le32 lifetime;
 } __attribute__ ((packed));
 
 /*
@@ -273,14 +273,14 @@ struct acx_rx_msdu_lifetime {
 struct acx_rx_config {
 	struct acx_header header;
 
-	u32 config_options;
-	u32 filter_options;
+	__le32 config_options;
+	__le32 filter_options;
 } __attribute__ ((packed));
 
 struct acx_packet_detection {
 	struct acx_header header;
 
-	u32 threshold;
+	__le32 threshold;
 } __attribute__ ((packed));
 
 
@@ -302,8 +302,8 @@ struct acx_slot {
 } __attribute__ ((packed));
 
 
-#define ADDRESS_GROUP_MAX	(8)
-#define ADDRESS_GROUP_MAX_LEN	(ETH_ALEN * ADDRESS_GROUP_MAX)
+#define ACX_MC_ADDRESS_GROUP_MAX	(8)
+#define ADDRESS_GROUP_MAX_LEN	        (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX)
 
 struct acx_dot11_grp_addr_tbl {
 	struct acx_header header;
@@ -314,40 +314,17 @@ struct acx_dot11_grp_addr_tbl {
 	u8 mac_table[ADDRESS_GROUP_MAX_LEN];
 } __attribute__ ((packed));
 
-
-#define  RX_TIMEOUT_PS_POLL_MIN    0
-#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
-#define  RX_TIMEOUT_PS_POLL_DEF    (15)
-#define  RX_TIMEOUT_UPSD_MIN       0
-#define  RX_TIMEOUT_UPSD_MAX       (200000)
-#define  RX_TIMEOUT_UPSD_DEF       (15)
-
 struct acx_rx_timeout {
 	struct acx_header header;
 
-	/*
-	 * The longest time the STA will wait to receive
-	 * traffic from the AP after a PS-poll has been
-	 * transmitted.
-	 */
-	u16 ps_poll_timeout;
-
-	/*
-	 * The longest time the STA will wait to receive
-	 * traffic from the AP after a frame has been sent
-	 * from an UPSD enabled queue.
-	 */
-	u16 upsd_timeout;
+	__le16 ps_poll_timeout;
+	__le16 upsd_timeout;
 } __attribute__ ((packed));
 
-#define RTS_THRESHOLD_MIN              0
-#define RTS_THRESHOLD_MAX              4096
-#define RTS_THRESHOLD_DEF              2347
-
 struct acx_rts_threshold {
 	struct acx_header header;
 
-	u16 threshold;
+	__le16 threshold;
 	u8 pad[2];
 } __attribute__ ((packed));
 
@@ -408,6 +385,13 @@ struct acx_beacon_filter_ie_table {
 	u8 pad[3];
 } __attribute__ ((packed));
 
+struct acx_conn_monit_params {
+       struct acx_header header;
+
+       __le32 synch_fail_thold; /* number of beacons missed */
+       __le32 bss_lose_timeout; /* number of TU's from synch fail */
+} __attribute__ ((packed));
+
 enum {
 	SG_ENABLE = 0,
 	SG_DISABLE,
@@ -431,6 +415,25 @@ struct acx_bt_wlan_coex {
 	u8 pad[3];
 } __attribute__ ((packed));
 
+struct acx_smart_reflex_state {
+	struct acx_header header;
+
+	u8 enable;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+struct smart_reflex_err_table {
+	u8 len;
+	s8 upper_limit;
+	s8 values[14];
+} __attribute__ ((packed));
+
+struct acx_smart_reflex_config_params {
+	struct acx_header header;
+
+	struct smart_reflex_err_table error_table[3];
+} __attribute__ ((packed));
+
 #define PTA_ANTENNA_TYPE_DEF		  (0)
 #define PTA_BT_HP_MAXTIME_DEF		  (2000)
 #define PTA_WLAN_HP_MAX_TIME_DEF	  (5000)
@@ -463,150 +466,34 @@ struct acx_bt_wlan_coex {
 struct acx_bt_wlan_coex_param {
 	struct acx_header header;
 
-	/*
-	 * The minimum rate of a received WLAN packet in the STA,
-	 * during protective mode, of which a new BT-HP request
-	 * during this Rx will always be respected and gain the antenna.
-	 */
-	u32 min_rate;
-
-	/* Max time the BT HP will be respected. */
-	u16 bt_hp_max_time;
-
-	/* Max time the WLAN HP will be respected. */
-	u16 wlan_hp_max_time;
-
-	/*
-	 * The time between the last BT activity
-	 * and the moment when the sense mode returns
-	 * to SENSE_INACTIVE.
-	 */
-	u16 sense_disable_timer;
-
-	/* Time before the next BT HP instance */
-	u16 rx_time_bt_hp;
-	u16 tx_time_bt_hp;
-
-	/* range: 10-20000    default: 1500 */
-	u16 rx_time_bt_hp_fast;
-	u16 tx_time_bt_hp_fast;
-
-	/* range: 2000-65535  default: 8700 */
-	u16 wlan_cycle_fast;
-
-	/* range: 0 - 15000 (Msec) default: 1000 */
-	u16 bt_anti_starvation_period;
-
-	/* range 400-10000(Usec) default: 3000 */
-	u16 next_bt_lp_packet;
-
-	/* Deafult: worst case for BT DH5 traffic */
-	u16 wake_up_beacon;
-
-	/* range: 0-50000(Usec) default: 1050 */
-	u16 hp_dm_max_guard_time;
-
-	/*
-	 * This is to prevent both BT & WLAN antenna
-	 * starvation.
-	 * Range: 100-50000(Usec) default:2550
-	 */
-	u16 next_wlan_packet;
-
-	/* 0 -> shared antenna */
-	u8 antenna_type;
-
-	/*
-	 * 0 -> TI legacy
-	 * 1 -> Palau
-	 */
-	u8 signal_type;
-
-	/*
-	 * BT AFH status
-	 * 0 -> no AFH
-	 * 1 -> from dedicated GPIO
-	 * 2 -> AFH on (from host)
-	 */
-	u8 afh_leverage_on;
-
-	/*
-	 * The number of cycles during which no
-	 * TX will be sent after 1 cycle of RX
-	 * transaction in protective mode
-	 */
-	u8 quiet_cycle_num;
-
-	/*
-	 * The maximum number of CTSs that will
-	 * be sent for receiving RX packet in
-	 * protective mode
-	 */
-	u8 max_cts;
-
-	/*
-	 * The number of WLAN packets
-	 * transferred in common mode before
-	 * switching to BT.
-	 */
-	u8 wlan_packets_num;
-
-	/*
-	 * The number of BT packets
-	 * transferred in common mode before
-	 * switching to WLAN.
-	 */
-	u8 bt_packets_num;
-
-	/* range: 1-255  default: 5 */
-	u8 missed_rx_avalanche;
-
-	/* range: 0-1    default: 1 */
-	u8 wlan_elp_hp;
-
-	/* range: 0 - 15  default: 4 */
-	u8 bt_anti_starvation_cycles;
-
-	u8 ack_mode_dual_ant;
-
-	/*
-	 * Allow PA_SD assertion/de-assertion
-	 * during enabled BT activity.
-	 */
-	u8 pa_sd_enable;
-
-	/*
-	 * Enable/Disable PTA in auto mode:
-	 * Support Both Active & P.S modes
-	 */
-	u8 pta_auto_mode_enable;
-
-	/* range: 0 - 20  default: 1 */
-	u8 bt_hp_respected_num;
+	__le32 per_threshold;
+	__le32 max_scan_compensation_time;
+	__le16 nfs_sample_interval;
+	u8 load_ratio;
+	u8 auto_ps_mode;
+	u8 probe_req_compensation;
+	u8 scan_window_compensation;
+	u8 antenna_config;
+	u8 beacon_miss_threshold;
+	__le32 rate_adaptation_threshold;
+	s8 rate_adaptation_snr;
+	u8 padding[3];
 } __attribute__ ((packed));
 
-#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
-#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
-
 struct acx_energy_detection {
 	struct acx_header header;
 
 	/* The RX Clear Channel Assessment threshold in the PHY */
-	u16 rx_cca_threshold;
+	__le16 rx_cca_threshold;
 	u8 tx_energy_detection;
 	u8 pad;
 } __attribute__ ((packed));
 
-#define BCN_RX_TIMEOUT_DEF_VALUE        10000
-#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
-#define RX_BROADCAST_IN_PS_DEF_VALUE    1
-#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
-
 struct acx_beacon_broadcast {
 	struct acx_header header;
 
-	u16 beacon_rx_timeout;
-	u16 broadcast_timeout;
+	__le16 beacon_rx_timeout;
+	__le16 broadcast_timeout;
 
 	/* Enables receiving of broadcast packets in PS mode */
 	u8 rx_broadcast_in_ps;
@@ -619,8 +506,8 @@ struct acx_beacon_broadcast {
 struct acx_event_mask {
 	struct acx_header header;
 
-	u32 event_mask;
-	u32 high_event_mask; /* Unused */
+	__le32 event_mask;
+	__le32 high_event_mask; /* Unused */
 } __attribute__ ((packed));
 
 #define CFG_RX_FCS		BIT(2)
@@ -657,11 +544,15 @@ struct acx_event_mask {
 #define SCAN_TRIGGERED		BIT(2)
 #define SCAN_PRIORITY_HIGH	BIT(3)
 
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE      0x01
+#define DF_SNIFF_MODE_ENABLE       0x80
+
 struct acx_feature_config {
 	struct acx_header header;
 
-	u32 options;
-	u32 data_flow_options;
+	__le32 options;
+	__le32 data_flow_options;
 } __attribute__ ((packed));
 
 struct acx_current_tx_power {
@@ -671,14 +562,6 @@ struct acx_current_tx_power {
 	u8  padding[3];
 } __attribute__ ((packed));
 
-enum acx_wake_up_event {
-	WAKE_UP_EVENT_BEACON_BITMAP	= 0x01, /* Wake on every Beacon*/
-	WAKE_UP_EVENT_DTIM_BITMAP	= 0x02,	/* Wake on every DTIM*/
-	WAKE_UP_EVENT_N_DTIM_BITMAP	= 0x04, /* Wake on every Nth DTIM */
-	WAKE_UP_EVENT_N_BEACONS_BITMAP	= 0x08, /* Wake on every Nth Beacon */
-	WAKE_UP_EVENT_BITS_MASK		= 0x0F
-};
-
 struct acx_wake_up_condition {
 	struct acx_header header;
 
@@ -693,7 +576,7 @@ struct acx_aid {
 	/*
 	 * To be set when associated with an AP.
 	 */
-	u16 aid;
+	__le16 aid;
 	u8 pad[2];
 } __attribute__ ((packed));
 
@@ -725,152 +608,152 @@ struct acx_ctsprotect {
 } __attribute__ ((packed));
 
 struct acx_tx_statistics {
-	u32 internal_desc_overflow;
+	__le32 internal_desc_overflow;
 }  __attribute__ ((packed));
 
 struct acx_rx_statistics {
-	u32 out_of_mem;
-	u32 hdr_overflow;
-	u32 hw_stuck;
-	u32 dropped;
-	u32 fcs_err;
-	u32 xfr_hint_trig;
-	u32 path_reset;
-	u32 reset_counter;
+	__le32 out_of_mem;
+	__le32 hdr_overflow;
+	__le32 hw_stuck;
+	__le32 dropped;
+	__le32 fcs_err;
+	__le32 xfr_hint_trig;
+	__le32 path_reset;
+	__le32 reset_counter;
 } __attribute__ ((packed));
 
 struct acx_dma_statistics {
-	u32 rx_requested;
-	u32 rx_errors;
-	u32 tx_requested;
-	u32 tx_errors;
+	__le32 rx_requested;
+	__le32 rx_errors;
+	__le32 tx_requested;
+	__le32 tx_errors;
 }  __attribute__ ((packed));
 
 struct acx_isr_statistics {
 	/* host command complete */
-	u32 cmd_cmplt;
+	__le32 cmd_cmplt;
 
 	/* fiqisr() */
-	u32 fiqs;
+	__le32 fiqs;
 
 	/* (INT_STS_ND & INT_TRIG_RX_HEADER) */
-	u32 rx_headers;
+	__le32 rx_headers;
 
 	/* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
-	u32 rx_completes;
+	__le32 rx_completes;
 
 	/* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
-	u32 rx_mem_overflow;
+	__le32 rx_mem_overflow;
 
 	/* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
-	u32 rx_rdys;
+	__le32 rx_rdys;
 
 	/* irqisr() */
-	u32 irqs;
+	__le32 irqs;
 
 	/* (INT_STS_ND & INT_TRIG_TX_PROC) */
-	u32 tx_procs;
+	__le32 tx_procs;
 
 	/* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
-	u32 decrypt_done;
+	__le32 decrypt_done;
 
 	/* (INT_STS_ND & INT_TRIG_DMA0) */
-	u32 dma0_done;
+	__le32 dma0_done;
 
 	/* (INT_STS_ND & INT_TRIG_DMA1) */
-	u32 dma1_done;
+	__le32 dma1_done;
 
 	/* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
-	u32 tx_exch_complete;
+	__le32 tx_exch_complete;
 
 	/* (INT_STS_ND & INT_TRIG_COMMAND) */
-	u32 commands;
+	__le32 commands;
 
 	/* (INT_STS_ND & INT_TRIG_RX_PROC) */
-	u32 rx_procs;
+	__le32 rx_procs;
 
 	/* (INT_STS_ND & INT_TRIG_PM_802) */
-	u32 hw_pm_mode_changes;
+	__le32 hw_pm_mode_changes;
 
 	/* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
-	u32 host_acknowledges;
+	__le32 host_acknowledges;
 
 	/* (INT_STS_ND & INT_TRIG_PM_PCI) */
-	u32 pci_pm;
+	__le32 pci_pm;
 
 	/* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
-	u32 wakeups;
+	__le32 wakeups;
 
 	/* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
-	u32 low_rssi;
+	__le32 low_rssi;
 } __attribute__ ((packed));
 
 struct acx_wep_statistics {
 	/* WEP address keys configured */
-	u32 addr_key_count;
+	__le32 addr_key_count;
 
 	/* default keys configured */
-	u32 default_key_count;
+	__le32 default_key_count;
 
-	u32 reserved;
+	__le32 reserved;
 
 	/* number of times that WEP key not found on lookup */
-	u32 key_not_found;
+	__le32 key_not_found;
 
 	/* number of times that WEP key decryption failed */
-	u32 decrypt_fail;
+	__le32 decrypt_fail;
 
 	/* WEP packets decrypted */
-	u32 packets;
+	__le32 packets;
 
 	/* WEP decrypt interrupts */
-	u32 interrupt;
+	__le32 interrupt;
 } __attribute__ ((packed));
 
 #define ACX_MISSED_BEACONS_SPREAD 10
 
 struct acx_pwr_statistics {
 	/* the amount of enters into power save mode (both PD & ELP) */
-	u32 ps_enter;
+	__le32 ps_enter;
 
 	/* the amount of enters into ELP mode */
-	u32 elp_enter;
+	__le32 elp_enter;
 
 	/* the amount of missing beacon interrupts to the host */
-	u32 missing_bcns;
+	__le32 missing_bcns;
 
 	/* the amount of wake on host-access times */
-	u32 wake_on_host;
+	__le32 wake_on_host;
 
 	/* the amount of wake on timer-expire */
-	u32 wake_on_timer_exp;
+	__le32 wake_on_timer_exp;
 
 	/* the number of packets that were transmitted with PS bit set */
-	u32 tx_with_ps;
+	__le32 tx_with_ps;
 
 	/* the number of packets that were transmitted with PS bit clear */
-	u32 tx_without_ps;
+	__le32 tx_without_ps;
 
 	/* the number of received beacons */
-	u32 rcvd_beacons;
+	__le32 rcvd_beacons;
 
 	/* the number of entering into PowerOn (power save off) */
-	u32 power_save_off;
+	__le32 power_save_off;
 
 	/* the number of entries into power save mode */
-	u16 enable_ps;
+	__le16 enable_ps;
 
 	/*
 	 * the number of exits from power save, not including failed PS
 	 * transitions
 	 */
-	u16 disable_ps;
+	__le16 disable_ps;
 
 	/*
 	 * the number of times the TSF counter was adjusted because
 	 * of drift
 	 */
-	u32 fix_tsf_ps;
+	__le32 fix_tsf_ps;
 
 	/* Gives statistics about the spread continuous missed beacons.
 	 * The 16 LSB are dedicated for the PS mode.
@@ -881,53 +764,53 @@ struct acx_pwr_statistics {
 	 * ...
 	 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
 	*/
-	u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+	__le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
 
 	/* the number of beacons in awake mode */
-	u32 rcvd_awake_beacons;
+	__le32 rcvd_awake_beacons;
 } __attribute__ ((packed));
 
 struct acx_mic_statistics {
-	u32 rx_pkts;
-	u32 calc_failure;
+	__le32 rx_pkts;
+	__le32 calc_failure;
 } __attribute__ ((packed));
 
 struct acx_aes_statistics {
-	u32 encrypt_fail;
-	u32 decrypt_fail;
-	u32 encrypt_packets;
-	u32 decrypt_packets;
-	u32 encrypt_interrupt;
-	u32 decrypt_interrupt;
+	__le32 encrypt_fail;
+	__le32 decrypt_fail;
+	__le32 encrypt_packets;
+	__le32 decrypt_packets;
+	__le32 encrypt_interrupt;
+	__le32 decrypt_interrupt;
 } __attribute__ ((packed));
 
 struct acx_event_statistics {
-	u32 heart_beat;
-	u32 calibration;
-	u32 rx_mismatch;
-	u32 rx_mem_empty;
-	u32 rx_pool;
-	u32 oom_late;
-	u32 phy_transmit_error;
-	u32 tx_stuck;
+	__le32 heart_beat;
+	__le32 calibration;
+	__le32 rx_mismatch;
+	__le32 rx_mem_empty;
+	__le32 rx_pool;
+	__le32 oom_late;
+	__le32 phy_transmit_error;
+	__le32 tx_stuck;
 } __attribute__ ((packed));
 
 struct acx_ps_statistics {
-	u32 pspoll_timeouts;
-	u32 upsd_timeouts;
-	u32 upsd_max_sptime;
-	u32 upsd_max_apturn;
-	u32 pspoll_max_apturn;
-	u32 pspoll_utilization;
-	u32 upsd_utilization;
+	__le32 pspoll_timeouts;
+	__le32 upsd_timeouts;
+	__le32 upsd_max_sptime;
+	__le32 upsd_max_apturn;
+	__le32 pspoll_max_apturn;
+	__le32 pspoll_utilization;
+	__le32 upsd_utilization;
 } __attribute__ ((packed));
 
 struct acx_rxpipe_statistics {
-	u32 rx_prep_beacon_drop;
-	u32 descr_host_int_trig_rx_data;
-	u32 beacon_buffer_thres_host_int_trig_rx_data;
-	u32 missed_beacon_host_int_trig_rx_data;
-	u32 tx_xfr_host_int_trig_rx_data;
+	__le32 rx_prep_beacon_drop;
+	__le32 descr_host_int_trig_rx_data;
+	__le32 beacon_buffer_thres_host_int_trig_rx_data;
+	__le32 missed_beacon_host_int_trig_rx_data;
+	__le32 tx_xfr_host_int_trig_rx_data;
 } __attribute__ ((packed));
 
 struct acx_statistics {
@@ -946,13 +829,8 @@ struct acx_statistics {
 	struct acx_rxpipe_statistics rxpipe;
 } __attribute__ ((packed));
 
-#define ACX_MAX_RATE_CLASSES       8
-#define ACX_RATE_MASK_UNSPECIFIED  0
-#define ACX_RATE_MASK_ALL          0x1eff
-#define ACX_RATE_RETRY_LIMIT       10
-
 struct acx_rate_class {
-	u32 enabled_rates;
+	__le32 enabled_rates;
 	u8 short_retry_limit;
 	u8 long_retry_limit;
 	u8 aflags;
@@ -962,47 +840,20 @@ struct acx_rate_class {
 struct acx_rate_policy {
 	struct acx_header header;
 
-	u32 rate_class_cnt;
-	struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
+	__le32 rate_class_cnt;
+	struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES];
 } __attribute__ ((packed));
 
-#define WL1271_ACX_AC_COUNT 4
-
 struct acx_ac_cfg {
 	struct acx_header header;
 	u8 ac;
 	u8 cw_min;
-	u16 cw_max;
+	__le16 cw_max;
 	u8 aifsn;
 	u8 reserved;
-	u16 tx_op_limit;
+	__le16 tx_op_limit;
 } __attribute__ ((packed));
 
-enum wl1271_acx_ac {
-	WL1271_ACX_AC_BE = 0,
-	WL1271_ACX_AC_BK = 1,
-	WL1271_ACX_AC_VI = 2,
-	WL1271_ACX_AC_VO = 3,
-	WL1271_ACX_AC_CTS2SELF = 4,
-	WL1271_ACX_AC_ANY_TID = 0x1F,
-	WL1271_ACX_AC_INVALID = 0xFF,
-};
-
-enum wl1271_acx_ps_scheme {
-	WL1271_ACX_PS_SCHEME_LEGACY = 0,
-	WL1271_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
-	WL1271_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
-	WL1271_ACX_PS_SCHEME_SAPSD = 3,
-};
-
-enum wl1271_acx_ack_policy {
-	WL1271_ACX_ACK_POLICY_LEGACY = 0,
-	WL1271_ACX_ACK_POLICY_NO_ACK = 1,
-	WL1271_ACX_ACK_POLICY_BLOCK = 2,
-};
-
-#define WL1271_ACX_TID_COUNT 7
-
 struct acx_tid_config {
 	struct acx_header header;
 	u8 queue_id;
@@ -1011,22 +862,19 @@ struct acx_tid_config {
 	u8 ps_scheme;
 	u8 ack_policy;
 	u8 padding[3];
-	u32 apsd_conf[2];
+	__le32 apsd_conf[2];
 } __attribute__ ((packed));
 
 struct acx_frag_threshold {
 	struct acx_header header;
-	u16 frag_threshold;
+	__le16 frag_threshold;
 	u8 padding[2];
 } __attribute__ ((packed));
 
-#define WL1271_ACX_TX_COMPL_TIMEOUT   5
-#define WL1271_ACX_TX_COMPL_THRESHOLD 5
-
 struct acx_tx_config_options {
 	struct acx_header header;
-	u16 tx_compl_timeout;     /* msec */
-	u16 tx_compl_threshold;   /* number of packets */
+	__le16 tx_compl_timeout;     /* msec */
+	__le16 tx_compl_threshold;   /* number of packets */
 } __attribute__ ((packed));
 
 #define ACX_RX_MEM_BLOCKS     64
@@ -1041,79 +889,87 @@ struct wl1271_acx_config_memory {
 	u8 tx_min_mem_block_num;
 	u8 num_stations;
 	u8 num_ssid_profiles;
-	u32 total_tx_descriptors;
+	__le32 total_tx_descriptors;
 } __attribute__ ((packed));
 
 struct wl1271_acx_mem_map {
 	struct acx_header header;
 
-	void *code_start;
-	void *code_end;
+	__le32 code_start;
+	__le32 code_end;
 
-	void *wep_defkey_start;
-	void *wep_defkey_end;
+	__le32 wep_defkey_start;
+	__le32 wep_defkey_end;
 
-	void *sta_table_start;
-	void *sta_table_end;
+	__le32 sta_table_start;
+	__le32 sta_table_end;
 
-	void *packet_template_start;
-	void *packet_template_end;
+	__le32 packet_template_start;
+	__le32 packet_template_end;
 
 	/* Address of the TX result interface (control block) */
-	u32 tx_result;
-	u32 tx_result_queue_start;
+	__le32 tx_result;
+	__le32 tx_result_queue_start;
 
-	void *queue_memory_start;
-	void *queue_memory_end;
+	__le32 queue_memory_start;
+	__le32 queue_memory_end;
 
-	u32 packet_memory_pool_start;
-	u32 packet_memory_pool_end;
+	__le32 packet_memory_pool_start;
+	__le32 packet_memory_pool_end;
 
-	void *debug_buffer1_start;
-	void *debug_buffer1_end;
+	__le32 debug_buffer1_start;
+	__le32 debug_buffer1_end;
 
-	void *debug_buffer2_start;
-	void *debug_buffer2_end;
+	__le32 debug_buffer2_start;
+	__le32 debug_buffer2_end;
 
 	/* Number of blocks FW allocated for TX packets */
-	u32 num_tx_mem_blocks;
+	__le32 num_tx_mem_blocks;
 
 	/* Number of blocks FW allocated for RX packets */
-	u32 num_rx_mem_blocks;
+	__le32 num_rx_mem_blocks;
 
 	/* the following 4 fields are valid in SLAVE mode only */
 	u8 *tx_cbuf;
 	u8 *rx_cbuf;
-	void *rx_ctrl;
-	void *tx_ctrl;
+	__le32 rx_ctrl;
+	__le32 tx_ctrl;
 } __attribute__ ((packed));
 
-enum wl1271_acx_rx_queue_type {
-	RX_QUEUE_TYPE_RX_LOW_PRIORITY,    /* All except the high priority */
-	RX_QUEUE_TYPE_RX_HIGH_PRIORITY,   /* Management and voice packets */
-	RX_QUEUE_TYPE_NUM,
-	RX_QUEUE_TYPE_MAX = USHORT_MAX
-};
-
-#define WL1271_RX_INTR_THRESHOLD_DEF  0       /* no pacing, send interrupt on
-					       * every event */
-#define WL1271_RX_INTR_THRESHOLD_MIN  0
-#define WL1271_RX_INTR_THRESHOLD_MAX  15
-
-#define WL1271_RX_INTR_TIMEOUT_DEF    5
-#define WL1271_RX_INTR_TIMEOUT_MIN    1
-#define WL1271_RX_INTR_TIMEOUT_MAX    100
-
 struct wl1271_acx_rx_config_opt {
 	struct acx_header header;
 
-	u16 mblk_threshold;
-	u16 threshold;
-	u16 timeout;
+	__le16 mblk_threshold;
+	__le16 threshold;
+	__le16 timeout;
 	u8 queue_type;
 	u8 reserved;
 } __attribute__ ((packed));
 
+
+struct wl1271_acx_bet_enable {
+	struct acx_header header;
+
+	u8 enable;
+	u8 max_consecutive;
+	u8 padding[2];
+} __attribute__ ((packed));
+
+#define ACX_IPV4_VERSION 4
+#define ACX_IPV6_VERSION 6
+#define ACX_IPV4_ADDR_SIZE 4
+struct wl1271_acx_arp_filter {
+	struct acx_header header;
+	u8 version;         /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
+	u8 enable;          /* 1 to enable ARP filtering, 0 to disable */
+	u8 padding[2];
+	u8 address[16];     /* The configured device IP address - all ARP
+			       requests directed to this IP address will pass
+			       through. For IPv4, the first four bytes are
+			       used. */
+} __attribute__((packed));
+
+
 enum {
 	ACX_WAKE_UP_CONDITIONS      = 0x0002,
 	ACX_MEM_CFG                 = 0x0003,
@@ -1170,6 +1026,9 @@ enum {
 	ACX_PEER_HT_CAP             = 0x0057,
 	ACX_HT_BSS_OPERATION        = 0x0058,
 	ACX_COEX_ACTIVITY           = 0x0059,
+	ACX_SET_SMART_REFLEX_DEBUG  = 0x005A,
+	ACX_SET_SMART_REFLEX_STATE  = 0x005B,
+	ACX_SET_SMART_REFLEX_PARAMS = 0x005F,
 	DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
 	DOT11_CUR_TX_PWR            = 0x100D,
 	DOT11_RX_DOT11_MODE         = 0x1012,
@@ -1182,23 +1041,24 @@ enum {
 };
 
 
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
-				  u8 listen_interval);
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl);
 int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
 int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
 int wl1271_acx_tx_power(struct wl1271 *wl, int power);
 int wl1271_acx_feature_cfg(struct wl1271 *wl);
 int wl1271_acx_mem_map(struct wl1271 *wl,
 		       struct acx_header *mem_map, size_t len);
-int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time);
+int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl);
 int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter);
 int wl1271_acx_pd_threshold(struct wl1271 *wl);
 int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
-int wl1271_acx_group_address_tbl(struct wl1271 *wl);
+int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
+				 void *mc_list, u32 mc_list_len);
 int wl1271_acx_service_period_timeout(struct wl1271 *wl);
 int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
-int wl1271_acx_beacon_filter_opt(struct wl1271 *wl);
+int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
 int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
+int wl1271_acx_conn_monit_params(struct wl1271 *wl);
 int wl1271_acx_sg_enable(struct wl1271 *wl);
 int wl1271_acx_sg_cfg(struct wl1271 *wl);
 int wl1271_acx_cca_threshold(struct wl1271 *wl);
@@ -1207,9 +1067,9 @@ int wl1271_acx_aid(struct wl1271 *wl, u1
 int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
 int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
 int wl1271_acx_cts_protect(struct wl1271 *wl,
-			    enum acx_ctsprotect_type ctsprotect);
+			   enum acx_ctsprotect_type ctsprotect);
 int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
-int wl1271_acx_rate_policies(struct wl1271 *wl);
+int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates);
 int wl1271_acx_ac_cfg(struct wl1271 *wl);
 int wl1271_acx_tid_cfg(struct wl1271 *wl);
 int wl1271_acx_frag_threshold(struct wl1271 *wl);
@@ -1217,5 +1077,9 @@ int wl1271_acx_tx_config_options(struct
 int wl1271_acx_mem_cfg(struct wl1271 *wl);
 int wl1271_acx_init_mem_config(struct wl1271 *wl);
 int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
+int wl1271_acx_smart_reflex(struct wl1271 *wl);
+int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
+int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
+			     u8 version);
 
 #endif /* __WL1271_ACX_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,14 @@ static struct wl1271_partition_set part_
 			.start = REGISTERS_BASE,
 			.size  = 0x00008800
 		},
+		.mem2 = {
+			.start = 0x00000000,
+			.size  = 0x00000000
+		},
+		.mem3 = {
+			.start = 0x00000000,
+			.size  = 0x00000000
+		},
 	},
 
 	[PART_WORK] = {
@@ -48,7 +56,15 @@ static struct wl1271_partition_set part_
 		},
 		.reg = {
 			.start = REGISTERS_BASE,
-			.size  = 0x0000b000
+			.size  = 0x0000a000
+		},
+		.mem2 = {
+			.start = 0x003004f8,
+			.size  = 0x00000004
+		},
+		.mem3 = {
+			.start = 0x00040404,
+			.size  = 0x00000000
 		},
 	},
 
@@ -60,6 +76,14 @@ static struct wl1271_partition_set part_
 		.reg = {
 			.start = DRPW_BASE,
 			.size  = 0x00006000
+		},
+		.mem2 = {
+			.start = 0x00000000,
+			.size  = 0x00000000
+		},
+		.mem3 = {
+			.start = 0x00000000,
+			.size  = 0x00000000
 		}
 	}
 };
@@ -69,19 +93,19 @@ static void wl1271_boot_set_ecpu_ctrl(st
 	u32 cpu_ctrl;
 
 	/* 10.5.0 run the firmware (I) */
-	cpu_ctrl = wl1271_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+	cpu_ctrl = wl1271_spi_read32(wl, ACX_REG_ECPU_CONTROL);
 
 	/* 10.5.1 run the firmware (II) */
 	cpu_ctrl |= flag;
-	wl1271_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+	wl1271_spi_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
 }
 
 static void wl1271_boot_fw_version(struct wl1271 *wl)
 {
 	struct wl1271_static_data static_data;
 
-	wl1271_spi_mem_read(wl, wl->cmd_box_addr,
-			    &static_data, sizeof(static_data));
+	wl1271_spi_read(wl, wl->cmd_box_addr,
+			&static_data, sizeof(static_data), false);
 
 	strncpy(wl->chip.fw_ver, static_data.fw_version,
 		sizeof(wl->chip.fw_ver));
@@ -93,8 +117,9 @@ static void wl1271_boot_fw_version(struc
 static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
 					     size_t fw_data_len, u32 dest)
 {
+	struct wl1271_partition_set partition;
 	int addr, chunk_num, partition_limit;
-	u8 *p;
+	u8 *p, *chunk;
 
 	/* whal_FwCtrl_LoadFwImageSm() */
 
@@ -103,16 +128,20 @@ static int wl1271_boot_upload_firmware_c
 	wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
 		     fw_data_len, CHUNK_SIZE);
 
-
 	if ((fw_data_len % 4) != 0) {
 		wl1271_error("firmware length not multiple of four");
 		return -EIO;
 	}
 
-	wl1271_set_partition(wl, dest,
-			     part_table[PART_DOWN].mem.size,
-			     part_table[PART_DOWN].reg.start,
-			     part_table[PART_DOWN].reg.size);
+	chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+	if (!chunk) {
+		wl1271_error("allocation for firmware upload chunk failed");
+		return -ENOMEM;
+	}
+
+	memcpy(&partition, &part_table[PART_DOWN], sizeof(partition));
+	partition.mem.start = dest;
+	wl1271_set_partition(wl, &partition);
 
 	/* 10.1 set partition limit and chunk num */
 	chunk_num = 0;
@@ -125,21 +154,17 @@ static int wl1271_boot_upload_firmware_c
 			addr = dest + chunk_num * CHUNK_SIZE;
 			partition_limit = chunk_num * CHUNK_SIZE +
 				part_table[PART_DOWN].mem.size;
-
-			/* FIXME: Over 80 chars! */
-			wl1271_set_partition(wl,
-					     addr,
-					     part_table[PART_DOWN].mem.size,
-					     part_table[PART_DOWN].reg.start,
-					     part_table[PART_DOWN].reg.size);
+			partition.mem.start = addr;
+			wl1271_set_partition(wl, &partition);
 		}
 
 		/* 10.3 upload the chunk */
 		addr = dest + chunk_num * CHUNK_SIZE;
 		p = buf + chunk_num * CHUNK_SIZE;
+		memcpy(chunk, p, CHUNK_SIZE);
 		wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
 			     p, addr);
-		wl1271_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+		wl1271_spi_write(wl, addr, chunk, CHUNK_SIZE, false);
 
 		chunk_num++;
 	}
@@ -147,28 +172,31 @@ static int wl1271_boot_upload_firmware_c
 	/* 10.4 upload the last chunk */
 	addr = dest + chunk_num * CHUNK_SIZE;
 	p = buf + chunk_num * CHUNK_SIZE;
+	memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
 	wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
 		     fw_data_len % CHUNK_SIZE, p, addr);
-	wl1271_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+	wl1271_spi_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
 
+	kfree(chunk);
 	return 0;
 }
 
 static int wl1271_boot_upload_firmware(struct wl1271 *wl)
 {
 	u32 chunks, addr, len;
+	int ret = 0;
 	u8 *fw;
 
 	fw = wl->fw;
-	chunks = be32_to_cpup((u32 *) fw);
+	chunks = be32_to_cpup((__be32 *) fw);
 	fw += sizeof(u32);
 
 	wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
 
 	while (chunks--) {
-		addr = be32_to_cpup((u32 *) fw);
+		addr = be32_to_cpup((__be32 *) fw);
 		fw += sizeof(u32);
-		len = be32_to_cpup((u32 *) fw);
+		len = be32_to_cpup((__be32 *) fw);
 		fw += sizeof(u32);
 
 		if (len > 300000) {
@@ -177,11 +205,13 @@ static int wl1271_boot_upload_firmware(s
 		}
 		wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
 			     chunks, addr, len);
-		wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
+		ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
+		if (ret != 0)
+			break;
 		fw += len;
 	}
 
-	return 0;
+	return ret;
 }
 
 static int wl1271_boot_upload_nvs(struct wl1271 *wl)
@@ -235,7 +265,7 @@ static int wl1271_boot_upload_nvs(struct
 			wl1271_debug(DEBUG_BOOT,
 				     "nvs burst write 0x%x: 0x%x",
 				     dest_addr, val);
-			wl1271_reg_write32(wl, dest_addr, val);
+			wl1271_spi_write32(wl, dest_addr, val);
 
 			nvs_ptr += 4;
 			dest_addr += 4;
@@ -253,20 +283,18 @@ static int wl1271_boot_upload_nvs(struct
 	/* FIXME: The driver sets the partition here, but this is not needed,
 	   since it sets to the same one as currently in use */
 	/* Now we must set the partition correctly */
-	wl1271_set_partition(wl,
-			     part_table[PART_WORK].mem.start,
-			     part_table[PART_WORK].mem.size,
-			     part_table[PART_WORK].reg.start,
-			     part_table[PART_WORK].reg.size);
+	wl1271_set_partition(wl, &part_table[PART_WORK]);
 
 	/* Copy the NVS tables to a new block to ensure alignment */
 	nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
+	if (!nvs_aligned)
+		return -ENOMEM;
 
 	/* And finally we upload the NVS tables */
 	/* FIXME: In wl1271, we upload everything at once.
 	   No endianness handling needed here?! The ref driver doesn't do
 	   anything about it at this point */
-	wl1271_spi_mem_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len);
+	wl1271_spi_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
 
 	kfree(nvs_aligned);
 	return 0;
@@ -275,9 +303,9 @@ static int wl1271_boot_upload_nvs(struct
 static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
 {
 	enable_irq(wl->irq);
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
 			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
-	wl1271_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+	wl1271_spi_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
 }
 
 static int wl1271_boot_soft_reset(struct wl1271 *wl)
@@ -286,12 +314,13 @@ static int wl1271_boot_soft_reset(struct
 	u32 boot_data;
 
 	/* perform soft reset */
-	wl1271_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+	wl1271_spi_write32(wl, ACX_REG_SLV_SOFT_RESET,
+			   ACX_SLV_SOFT_RESET_BIT);
 
 	/* SOFT_RESET is self clearing */
 	timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
 	while (1) {
-		boot_data = wl1271_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+		boot_data = wl1271_spi_read32(wl, ACX_REG_SLV_SOFT_RESET);
 		wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
 		if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
 			break;
@@ -307,10 +336,10 @@ static int wl1271_boot_soft_reset(struct
 	}
 
 	/* disable Rx/Tx */
-	wl1271_reg_write32(wl, ENABLE, 0x0);
+	wl1271_spi_write32(wl, ENABLE, 0x0);
 
 	/* disable auto calibration on start*/
-	wl1271_reg_write32(wl, SPARE_A2, 0xffff);
+	wl1271_spi_write32(wl, SPARE_A2, 0xffff);
 
 	return 0;
 }
@@ -322,7 +351,7 @@ static int wl1271_boot_run_firmware(stru
 
 	wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 
-	chip_id = wl1271_reg_read32(wl, CHIP_ID_B);
+	chip_id = wl1271_spi_read32(wl, CHIP_ID_B);
 
 	wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
 
@@ -335,7 +364,8 @@ static int wl1271_boot_run_firmware(stru
 	loop = 0;
 	while (loop++ < INIT_LOOP) {
 		udelay(INIT_LOOP_DELAY);
-		interrupt = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+		interrupt = wl1271_spi_read32(wl,
+					      ACX_REG_INTERRUPT_NO_CLEAR);
 
 		if (interrupt == 0xffffffff) {
 			wl1271_error("error reading hardware complete "
@@ -344,30 +374,26 @@ static int wl1271_boot_run_firmware(stru
 		}
 		/* check that ACX_INTR_INIT_COMPLETE is enabled */
 		else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
-			wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+			wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK,
 					   WL1271_ACX_INTR_INIT_COMPLETE);
 			break;
 		}
 	}
 
-	if (loop >= INIT_LOOP) {
+	if (loop > INIT_LOOP) {
 		wl1271_error("timeout waiting for the hardware to "
 			     "complete initialization");
 		return -EIO;
 	}
 
 	/* get hardware config command mail box */
-	wl->cmd_box_addr = wl1271_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+	wl->cmd_box_addr = wl1271_spi_read32(wl, REG_COMMAND_MAILBOX_PTR);
 
 	/* get hardware config event mail box */
-	wl->event_box_addr = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->event_box_addr = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);
 
 	/* set the working partition to its "running" mode offset */
-	wl1271_set_partition(wl,
-			     part_table[PART_WORK].mem.start,
-			     part_table[PART_WORK].mem.size,
-			     part_table[PART_WORK].reg.start,
-			     part_table[PART_WORK].reg.size);
+	wl1271_set_partition(wl, &part_table[PART_WORK]);
 
 	wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
 		     wl->cmd_box_addr, wl->event_box_addr);
@@ -379,11 +405,10 @@ static int wl1271_boot_run_firmware(stru
 	 * ready to receive event from the command mailbox
 	 */
 
-	/* enable gpio interrupts */
-	wl1271_boot_enable_interrupts(wl);
-
-	/* unmask all mbox events  */
-	wl->event_mask = 0xffffffff;
+	/* unmask required mbox events  */
+	wl->event_mask = BSS_LOSE_EVENT_ID |
+		SCAN_COMPLETE_EVENT_ID |
+		PS_REPORT_EVENT_ID;
 
 	ret = wl1271_event_unmask(wl);
 	if (ret < 0) {
@@ -399,34 +424,13 @@ static int wl1271_boot_run_firmware(stru
 
 static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
 {
-	u32 polarity, status, i;
-
-	wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
-	wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
-
-	/* Wait until the command is complete (ie. bit 18 is set) */
-	for (i = 0; i < OCP_CMD_LOOP; i++) {
-		polarity = wl1271_reg_read32(wl, OCP_DATA_READ);
-		if (polarity & OCP_READY_MASK)
-			break;
-	}
-	if (i == OCP_CMD_LOOP) {
-		wl1271_error("OCP command timeout!");
-		return -EIO;
-	}
+	u32 polarity;
 
-	status = polarity & OCP_STATUS_MASK;
-	if (status != OCP_STATUS_OK) {
-		wl1271_error("OCP command failed (%d)", status);
-		return -EIO;
-	}
+	polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
 
 	/* We use HIGH polarity, so unset the LOW bit */
 	polarity &= ~POLARITY_LOW;
-
-	wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
-	wl1271_reg_write32(wl, OCP_DATA_WRITE, polarity);
-	wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
+	wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
 
 	return 0;
 }
@@ -436,16 +440,32 @@ int wl1271_boot(struct wl1271 *wl)
 	int ret = 0;
 	u32 tmp, clk, pause;
 
-	if (REF_CLOCK == 0 || REF_CLOCK == 2)
-		/* ref clk: 19.2/38.4 */
+	if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
+		/* ref clk: 19.2/38.4/38.4-XTAL */
 		clk = 0x3;
 	else if (REF_CLOCK == 1 || REF_CLOCK == 3)
 		/* ref clk: 26/52 */
 		clk = 0x5;
 
-	wl1271_reg_write32(wl, PLL_PARAMETERS, clk);
+	if (REF_CLOCK != 0) {
+		u16 val;
+		/* Set clock type */
+		val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
+		val &= FREF_CLK_TYPE_BITS;
+		val |= CLK_REQ_PRCM;
+		wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
+	} else {
+		u16 val;
+		/* Set clock polarity */
+		val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
+		val &= FREF_CLK_POLARITY_BITS;
+		val |= CLK_REQ_OUTN_SEL;
+		wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
+	}
 
-	pause = wl1271_reg_read32(wl, PLL_PARAMETERS);
+	wl1271_spi_write32(wl, PLL_PARAMETERS, clk);
+
+	pause = wl1271_spi_read32(wl, PLL_PARAMETERS);
 
 	wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
 
@@ -454,39 +474,31 @@ int wl1271_boot(struct wl1271 *wl)
 					   * 0x3ff (magic number ).  How does
 					   * this work?! */
 	pause |= WU_COUNTER_PAUSE_VAL;
-	wl1271_reg_write32(wl, WU_COUNTER_PAUSE, pause);
+	wl1271_spi_write32(wl, WU_COUNTER_PAUSE, pause);
 
 	/* Continue the ELP wake up sequence */
-	wl1271_reg_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
+	wl1271_spi_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
 	udelay(500);
 
-	wl1271_set_partition(wl,
-			     part_table[PART_DRPW].mem.start,
-			     part_table[PART_DRPW].mem.size,
-			     part_table[PART_DRPW].reg.start,
-			     part_table[PART_DRPW].reg.size);
+	wl1271_set_partition(wl, &part_table[PART_DRPW]);
 
 	/* Read-modify-write DRPW_SCRATCH_START register (see next state)
 	   to be used by DRPw FW. The RTRIM value will be added by the FW
 	   before taking DRPw out of reset */
 
 	wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
-	clk = wl1271_reg_read32(wl, DRPW_SCRATCH_START);
+	clk = wl1271_spi_read32(wl, DRPW_SCRATCH_START);
 
 	wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
 
 	/* 2 */
 	clk |= (REF_CLOCK << 1) << 4;
-	wl1271_reg_write32(wl, DRPW_SCRATCH_START, clk);
+	wl1271_spi_write32(wl, DRPW_SCRATCH_START, clk);
 
-	wl1271_set_partition(wl,
-			     part_table[PART_WORK].mem.start,
-			     part_table[PART_WORK].mem.size,
-			     part_table[PART_WORK].reg.start,
-			     part_table[PART_WORK].reg.size);
+	wl1271_set_partition(wl, &part_table[PART_WORK]);
 
 	/* Disable interrupts */
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
 
 	ret = wl1271_boot_soft_reset(wl);
 	if (ret < 0)
@@ -501,21 +513,22 @@ int wl1271_boot(struct wl1271 *wl)
 	 * ACX_EEPROMLESS_IND_REG */
 	wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
 
-	wl1271_reg_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
+	wl1271_spi_write32(wl, ACX_EEPROMLESS_IND_REG,
+			   ACX_EEPROMLESS_IND_REG);
 
-	tmp = wl1271_reg_read32(wl, CHIP_ID_B);
+	tmp = wl1271_spi_read32(wl, CHIP_ID_B);
 
 	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
 
 	/* 6. read the EEPROM parameters */
-	tmp = wl1271_reg_read32(wl, SCR_PAD2);
+	tmp = wl1271_spi_read32(wl, SCR_PAD2);
 
 	ret = wl1271_boot_write_irq_polarity(wl);
 	if (ret < 0)
 		goto out;
 
 	/* FIXME: Need to check whether this is really what we want */
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
 			   WL1271_ACX_ALL_EVENTS_VECTOR);
 
 	/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
@@ -530,6 +543,9 @@ int wl1271_boot(struct wl1271 *wl)
 	if (ret < 0)
 		goto out;
 
+	/* Enable firmware interrupts now */
+	wl1271_boot_enable_interrupts(wl);
+
 	/* set the wl1271 default filters */
 	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
 	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_boot.h	2010-02-24 13:52:17.000000000 -0500
@@ -50,23 +50,17 @@ struct wl1271_static_data {
 #define WU_COUNTER_PAUSE_VAL 0x3FF
 #define WELP_ARM_COMMAND_VAL 0x4
 
-#define OCP_CMD_LOOP  32
-
-#define OCP_CMD_WRITE 0x1
-#define OCP_CMD_READ  0x2
-
-#define OCP_READY_MASK  BIT(18)
-#define OCP_STATUS_MASK (BIT(16) | BIT(17))
-
-#define OCP_STATUS_NO_RESP    0x00000
-#define OCP_STATUS_OK         0x10000
-#define OCP_STATUS_REQ_FAILED 0x20000
-#define OCP_STATUS_RESP_ERROR 0x30000
-
-#define OCP_REG_POLARITY 0x30032
+#define OCP_REG_POLARITY     0x0064
+#define OCP_REG_CLK_TYPE     0x0448
+#define OCP_REG_CLK_POLARITY 0x0cb2
 
 #define CMD_MBOX_ADDRESS 0x407B4
 
 #define POLARITY_LOW BIT(1)
 
+#define FREF_CLK_TYPE_BITS     0xfffffe7f
+#define CLK_REQ_PRCM           0x100
+#define FREF_CLK_POLARITY_BITS 0xfffff8ff
+#define CLK_REQ_OUTN_SEL       0x700
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,26 +42,28 @@
  * @buf: buffer containing the command, must work with dma
  * @len: length of the buffer
  */
-int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
+int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
+		    size_t res_len)
 {
 	struct wl1271_cmd_header *cmd;
 	unsigned long timeout;
 	u32 intr;
 	int ret = 0;
+	u16 status;
 
 	cmd = buf;
-	cmd->id = id;
+	cmd->id = cpu_to_le16(id);
 	cmd->status = 0;
 
 	WARN_ON(len % 4 != 0);
 
-	wl1271_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
+	wl1271_spi_write(wl, wl->cmd_box_addr, buf, len, false);
 
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
 
 	timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
 
-	intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 	while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
 		if (time_after(jiffies, timeout)) {
 			wl1271_error("command complete timeout");
@@ -71,17 +73,28 @@ int wl1271_cmd_send(struct wl1271 *wl, u
 
 		msleep(1);
 
-		intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+		intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 	}
 
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+	/* read back the status code of the command */
+	if (res_len == 0)
+		res_len = sizeof(struct wl1271_cmd_header);
+	wl1271_spi_read(wl, wl->cmd_box_addr, cmd, res_len, false);
+
+	status = le16_to_cpu(cmd->status);
+	if (status != CMD_STATUS_SUCCESS) {
+		wl1271_error("command execute failure %d", status);
+		ret = -EIO;
+	}
+
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK,
 			   WL1271_ACX_INTR_CMD_COMPLETE);
 
 out:
 	return ret;
 }
 
-int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
+static int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
 {
 	struct wl1271_cmd_cal_channel_tune *cmd;
 	int ret = 0;
@@ -104,7 +117,7 @@ int wl1271_cmd_cal_channel_tune(struct w
 	return ret;
 }
 
-int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
+static int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
 {
 	struct wl1271_cmd_cal_update_ref_point *cmd;
 	int ret = 0;
@@ -129,7 +142,7 @@ int wl1271_cmd_cal_update_ref_point(stru
 	return ret;
 }
 
-int wl1271_cmd_cal_p2g(struct wl1271 *wl)
+static int wl1271_cmd_cal_p2g(struct wl1271 *wl)
 {
 	struct wl1271_cmd_cal_p2g *cmd;
 	int ret = 0;
@@ -150,7 +163,7 @@ int wl1271_cmd_cal_p2g(struct wl1271 *wl
 	return ret;
 }
 
-int wl1271_cmd_cal(struct wl1271 *wl)
+static int wl1271_cmd_cal(struct wl1271 *wl)
 {
 	/*
 	 * FIXME: we must make sure that we're not sleeping when calibration
@@ -175,11 +188,116 @@ int wl1271_cmd_cal(struct wl1271 *wl)
 	return ret;
 }
 
-int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
-		    u16 beacon_interval, u8 wait)
+int wl1271_cmd_general_parms(struct wl1271 *wl)
+{
+	struct wl1271_general_parms_cmd *gen_parms;
+	struct conf_general_parms *g = &wl->conf.init.genparam;
+	int ret;
+
+	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
+	if (!gen_parms)
+		return -ENOMEM;
+
+	gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
+
+	gen_parms->ref_clk = g->ref_clk;
+	gen_parms->settling_time = g->settling_time;
+	gen_parms->clk_valid_on_wakeup = g->clk_valid_on_wakeup;
+	gen_parms->dc2dcmode = g->dc2dcmode;
+	gen_parms->single_dual_band = g->single_dual_band;
+	gen_parms->tx_bip_fem_autodetect = g->tx_bip_fem_autodetect;
+	gen_parms->tx_bip_fem_manufacturer = g->tx_bip_fem_manufacturer;
+	gen_parms->settings = g->settings;
+
+	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
+	if (ret < 0)
+		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
+
+	kfree(gen_parms);
+	return ret;
+}
+
+int wl1271_cmd_radio_parms(struct wl1271 *wl)
+{
+	struct wl1271_radio_parms_cmd *radio_parms;
+	struct conf_radio_parms *r = &wl->conf.init.radioparam;
+	int i, ret;
+
+	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
+	if (!radio_parms)
+		return -ENOMEM;
+
+	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
+
+	/* Static radio parameters */
+	radio_parms->rx_trace_loss = r->rx_trace_loss;
+	radio_parms->tx_trace_loss = r->tx_trace_loss;
+	memcpy(radio_parms->rx_rssi_and_proc_compens,
+	       r->rx_rssi_and_proc_compens,
+	       CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE);
+
+	memcpy(radio_parms->rx_trace_loss_5, r->rx_trace_loss_5,
+	       CONF_NUMBER_OF_SUB_BANDS_5);
+	memcpy(radio_parms->tx_trace_loss_5, r->tx_trace_loss_5,
+	       CONF_NUMBER_OF_SUB_BANDS_5);
+	memcpy(radio_parms->rx_rssi_and_proc_compens_5,
+	       r->rx_rssi_and_proc_compens_5,
+	       CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE);
+
+	/* Dynamic radio parameters */
+	radio_parms->tx_ref_pd_voltage = cpu_to_le16(r->tx_ref_pd_voltage);
+	radio_parms->tx_ref_power = r->tx_ref_power;
+	radio_parms->tx_offset_db = r->tx_offset_db;
+
+	memcpy(radio_parms->tx_rate_limits_normal, r->tx_rate_limits_normal,
+	       CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->tx_rate_limits_degraded, r->tx_rate_limits_degraded,
+	       CONF_NUMBER_OF_RATE_GROUPS);
+
+	memcpy(radio_parms->tx_channel_limits_11b, r->tx_channel_limits_11b,
+	       CONF_NUMBER_OF_CHANNELS_2_4);
+	memcpy(radio_parms->tx_channel_limits_ofdm, r->tx_channel_limits_ofdm,
+	       CONF_NUMBER_OF_CHANNELS_2_4);
+	memcpy(radio_parms->tx_pdv_rate_offsets, r->tx_pdv_rate_offsets,
+	       CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->tx_ibias, r->tx_ibias, CONF_NUMBER_OF_RATE_GROUPS);
+
+	radio_parms->rx_fem_insertion_loss = r->rx_fem_insertion_loss;
+
+	for (i = 0; i < CONF_NUMBER_OF_SUB_BANDS_5; i++)
+		radio_parms->tx_ref_pd_voltage_5[i] =
+			cpu_to_le16(r->tx_ref_pd_voltage_5[i]);
+	memcpy(radio_parms->tx_ref_power_5, r->tx_ref_power_5,
+	       CONF_NUMBER_OF_SUB_BANDS_5);
+	memcpy(radio_parms->tx_offset_db_5, r->tx_offset_db_5,
+	       CONF_NUMBER_OF_SUB_BANDS_5);
+	memcpy(radio_parms->tx_rate_limits_normal_5,
+	       r->tx_rate_limits_normal_5, CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->tx_rate_limits_degraded_5,
+	       r->tx_rate_limits_degraded_5, CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->tx_channel_limits_ofdm_5,
+	       r->tx_channel_limits_ofdm_5, CONF_NUMBER_OF_CHANNELS_5);
+	memcpy(radio_parms->tx_pdv_rate_offsets_5, r->tx_pdv_rate_offsets_5,
+	       CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->tx_ibias_5, r->tx_ibias_5,
+	       CONF_NUMBER_OF_RATE_GROUPS);
+	memcpy(radio_parms->rx_fem_insertion_loss_5,
+	       r->rx_fem_insertion_loss_5, CONF_NUMBER_OF_SUB_BANDS_5);
+
+	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
+		    radio_parms, sizeof(*radio_parms));
+
+	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
+	if (ret < 0)
+		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
+
+	kfree(radio_parms);
+	return ret;
+}
+
+int wl1271_cmd_join(struct wl1271 *wl)
 {
 	static bool do_cal = true;
-	unsigned long timeout;
 	struct wl1271_cmd_join *join;
 	int ret, i;
 	u8 *bssid;
@@ -193,6 +311,18 @@ int wl1271_cmd_join(struct wl1271 *wl, u
 			do_cal = false;
 	}
 
+	/* FIXME: This is a workaround, because with the current stack, we
+	 * cannot know when we have disassociated.  So, if we have already
+	 * joined, we disconnect before joining again. */
+	if (wl->joined) {
+		ret = wl1271_cmd_disconnect(wl);
+		if (ret < 0) {
+			wl1271_error("failed to disconnect before rejoining");
+			goto out;
+		}
+
+		wl->joined = false;
+	}
 
 	join = kzalloc(sizeof(*join), GFP_KERNEL);
 	if (!join) {
@@ -207,15 +337,34 @@ int wl1271_cmd_join(struct wl1271 *wl, u
 	for (i = 0; i < ETH_ALEN; i++)
 		bssid[i] = wl->bssid[ETH_ALEN - i - 1];
 
-	join->rx_config_options = wl->rx_config;
-	join->rx_filter_options = wl->rx_filter;
+	join->rx_config_options = cpu_to_le32(wl->rx_config);
+	join->rx_filter_options = cpu_to_le32(wl->rx_filter);
+	join->bss_type = wl->bss_type;
 
-	join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
-		RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+	/*
+	 * FIXME: disable temporarily all filters because after commit
+	 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
+	 * association. The filter logic needs to be implemented properly
+	 * and once that is done, this hack can be removed.
+	 */
+	join->rx_config_options = cpu_to_le32(0);
+	join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
+
+	if (wl->band == IEEE80211_BAND_2GHZ)
+		join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS   |
+						   CONF_HW_BIT_RATE_2MBPS   |
+						   CONF_HW_BIT_RATE_5_5MBPS |
+						   CONF_HW_BIT_RATE_11MBPS);
+	else {
+		join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
+		join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS  |
+						   CONF_HW_BIT_RATE_12MBPS |
+						   CONF_HW_BIT_RATE_24MBPS);
+	}
+
+	join->beacon_interval = cpu_to_le16(WL1271_DEFAULT_BEACON_INT);
+	join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
 
-	join->beacon_interval = beacon_interval;
-	join->dtim_interval = dtim_interval;
-	join->bss_type = bss_type;
 	join->channel = wl->channel;
 	join->ssid_len = wl->ssid_len;
 	memcpy(join->ssid, wl->ssid, wl->ssid_len);
@@ -228,21 +377,24 @@ int wl1271_cmd_join(struct wl1271 *wl, u
 
 	join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
 
+	/* reset TX security counters */
+	wl->tx_security_last_seq = 0;
+	wl->tx_security_seq_16 = 0;
+	wl->tx_security_seq_32 = 0;
 
-	ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
+	ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
 	if (ret < 0) {
 		wl1271_error("failed to initiate cmd join");
 		goto out_free;
 	}
 
-	timeout = msecs_to_jiffies(JOIN_TIMEOUT);
+	wl->joined = true;
 
 	/*
 	 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
 	 * simplify locking we just sleep instead, for now
 	 */
-	if (wait)
-		msleep(10);
+	msleep(10);
 
 out_free:
 	kfree(join);
@@ -262,34 +414,21 @@ out:
 int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
 {
 	int ret;
+	size_t res_len = 0;
 
 	wl1271_debug(DEBUG_CMD, "cmd test");
 
-	ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len);
+	if (answer)
+		res_len = buf_len;
+
+	ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len);
 
 	if (ret < 0) {
 		wl1271_warning("TEST command failed");
 		return ret;
 	}
 
-	if (answer) {
-		struct wl1271_command *cmd_answer;
-
-		/*
-		 * The test command got in, we can read the answer.
-		 * The answer would be a wl1271_command, where the
-		 * parameter array contains the actual answer.
-		 */
-		wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
-
-		cmd_answer = buf;
-
-		if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
-			wl1271_error("TEST command answer error: %d",
-				     cmd_answer->header.status);
-	}
-
-	return 0;
+	return ret;
 }
 
 /**
@@ -307,26 +446,15 @@ int wl1271_cmd_interrogate(struct wl1271
 
 	wl1271_debug(DEBUG_CMD, "cmd interrogate");
 
-	acx->id = id;
+	acx->id = cpu_to_le16(id);
 
 	/* payload length, does not include any headers */
-	acx->len = len - sizeof(*acx);
+	acx->len = cpu_to_le16(len - sizeof(*acx));
 
-	ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
-	if (ret < 0) {
+	ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len);
+	if (ret < 0)
 		wl1271_error("INTERROGATE command failed");
-		goto out;
-	}
 
-	/* the interrogate command got in, we can read the answer */
-	wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
-
-	acx = buf;
-	if (acx->cmd.status != CMD_STATUS_SUCCESS)
-		wl1271_error("INTERROGATE command error: %d",
-			     acx->cmd.status);
-
-out:
 	return ret;
 }
 
@@ -345,12 +473,12 @@ int wl1271_cmd_configure(struct wl1271 *
 
 	wl1271_debug(DEBUG_CMD, "cmd configure");
 
-	acx->id = id;
+	acx->id = cpu_to_le16(id);
 
 	/* payload length, does not include any headers */
-	acx->len = len - sizeof(*acx);
+	acx->len = cpu_to_le16(len - sizeof(*acx));
 
-	ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len);
+	ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0);
 	if (ret < 0) {
 		wl1271_warning("CONFIGURE command NOK");
 		return ret;
@@ -383,7 +511,7 @@ int wl1271_cmd_data_path(struct wl1271 *
 		cmd_tx = CMD_DISABLE_TX;
 	}
 
-	ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_error("rx %s cmd for channel %d failed",
 			     enable ? "start" : "stop", channel);
@@ -393,7 +521,7 @@ int wl1271_cmd_data_path(struct wl1271 *
 	wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
 		     enable ? "start" : "stop", channel);
 
-	ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_error("tx %s cmd for channel %d failed",
 			     enable ? "start" : "stop", channel);
@@ -414,8 +542,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl
 	int ret = 0;
 
 	/* FIXME: this should be in ps.c */
-	ret = wl1271_acx_wake_up_conditions(wl, WAKE_UP_EVENT_DTIM_BITMAP,
-					    wl->listen_int);
+	ret = wl1271_acx_wake_up_conditions(wl);
 	if (ret < 0) {
 		wl1271_error("couldn't set wake up conditions");
 		goto out;
@@ -433,10 +560,10 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl
 	ps_params->send_null_data = 1;
 	ps_params->retries = 5;
 	ps_params->hang_over_period = 128;
-	ps_params->null_data_rate = 1; /* 1 Mbps */
+	ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
 
 	ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
-			      sizeof(*ps_params));
+			      sizeof(*ps_params), 0);
 	if (ret < 0) {
 		wl1271_error("cmd set_ps_mode failed");
 		goto out;
@@ -464,22 +591,17 @@ int wl1271_cmd_read_memory(struct wl1271
 	WARN_ON(len > MAX_READ_SIZE);
 	len = min_t(size_t, len, MAX_READ_SIZE);
 
-	cmd->addr = addr;
-	cmd->size = len;
+	cmd->addr = cpu_to_le32(addr);
+	cmd->size = cpu_to_le32(len);
 
-	ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
+			      sizeof(*cmd));
 	if (ret < 0) {
 		wl1271_error("read memory command failed: %d", ret);
 		goto out;
 	}
 
-	/* the read command got in, we can now read the answer */
-	wl1271_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
-	if (cmd->header.status != CMD_STATUS_SUCCESS)
-		wl1271_error("error in read command result: %d",
-			     cmd->header.status);
-
+	/* the read command got in */
 	memcpy(answer, cmd->value, len);
 
 out:
@@ -488,14 +610,31 @@ out:
 }
 
 int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
-		    u8 active_scan, u8 high_prio, u8 num_channels,
+		    u8 active_scan, u8 high_prio, u8 band,
 		    u8 probe_requests)
 {
 
 	struct wl1271_cmd_trigger_scan_to *trigger = NULL;
 	struct wl1271_cmd_scan *params = NULL;
-	int i, ret;
+	struct ieee80211_channel *channels;
+	int i, j, n_ch, ret;
 	u16 scan_options = 0;
+	u8 ieee_band;
+
+	if (band == WL1271_SCAN_BAND_2_4_GHZ)
+		ieee_band = IEEE80211_BAND_2GHZ;
+	else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled())
+		ieee_band = IEEE80211_BAND_2GHZ;
+	else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled())
+		ieee_band = IEEE80211_BAND_5GHZ;
+	else
+		return -EINVAL;
+
+	if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
+		return -EINVAL;
+
+	channels = wl->hw->wiphy->bands[ieee_band]->channels;
+	n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels;
 
 	if (wl->scanning)
 		return -EINVAL;
@@ -512,32 +651,43 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 		scan_options |= WL1271_SCAN_OPT_PASSIVE;
 	if (high_prio)
 		scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH;
-	params->params.scan_options = scan_options;
+	params->params.scan_options = cpu_to_le16(scan_options);
 
-	params->params.num_channels = num_channels;
 	params->params.num_probe_requests = probe_requests;
-	params->params.tx_rate = cpu_to_le32(RATE_MASK_2MBPS);
+	/* Let the fw autodetect suitable tx_rate for probes */
+	params->params.tx_rate = 0;
 	params->params.tid_trigger = 0;
 	params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
 
-	for (i = 0; i < num_channels; i++) {
-		params->channels[i].min_duration =
-			cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
-		params->channels[i].max_duration =
-			cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
-		memset(&params->channels[i].bssid_lsb, 0xff, 4);
-		memset(&params->channels[i].bssid_msb, 0xff, 2);
-		params->channels[i].early_termination = 0;
-		params->channels[i].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR;
-		params->channels[i].channel = i + 1;
+	if (band == WL1271_SCAN_BAND_DUAL)
+		params->params.band = WL1271_SCAN_BAND_2_4_GHZ;
+	else
+		params->params.band = band;
+
+	for (i = 0, j = 0; i < n_ch && i < WL1271_SCAN_MAX_CHANNELS; i++) {
+		if (!(channels[i].flags & IEEE80211_CHAN_DISABLED)) {
+			params->channels[j].min_duration =
+				cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
+			params->channels[j].max_duration =
+				cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
+			memset(&params->channels[j].bssid_lsb, 0xff, 4);
+			memset(&params->channels[j].bssid_msb, 0xff, 2);
+			params->channels[j].early_termination = 0;
+			params->channels[j].tx_power_att =
+				WL1271_SCAN_CURRENT_TX_PWR;
+			params->channels[j].channel = channels[i].hw_value;
+			j++;
+		}
 	}
 
+	params->params.num_channels = j;
+
 	if (len && ssid) {
 		params->params.ssid_len = len;
 		memcpy(params->params.ssid, ssid, len);
 	}
 
-	ret = wl1271_cmd_build_probe_req(wl, ssid, len);
+	ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band);
 	if (ret < 0) {
 		wl1271_error("PROBE request template failed");
 		goto out;
@@ -553,7 +703,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 	trigger->timeout = 0;
 
 	ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
-			      sizeof(*trigger));
+			      sizeof(*trigger), 0);
 	if (ret < 0) {
 		wl1271_error("trigger scan to failed for hw scan");
 		goto out;
@@ -562,20 +712,24 @@ int wl1271_cmd_scan(struct wl1271 *wl, u
 	wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
 
 	wl->scanning = true;
+	if (wl1271_11a_enabled()) {
+		wl->scan.state = band;
+		if (band == WL1271_SCAN_BAND_DUAL) {
+			wl->scan.active = active_scan;
+			wl->scan.high_prio = high_prio;
+			wl->scan.probe_requests = probe_requests;
+			if (len && ssid) {
+				wl->scan.ssid_len = len;
+				memcpy(wl->scan.ssid, ssid, len);
+			} else
+				wl->scan.ssid_len = 0;
+		}
+	}
 
-	ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+	ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
 	if (ret < 0) {
 		wl1271_error("SCAN failed");
-		goto out;
-	}
-
-	wl1271_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
-
-	if (params->header.status != CMD_STATUS_SUCCESS) {
-		wl1271_error("Scan command error: %d",
-			     params->header.status);
 		wl->scanning = false;
-		ret = -EIO;
 		goto out;
 	}
 
@@ -603,14 +757,14 @@ int wl1271_cmd_template_set(struct wl127
 
 	cmd->len = cpu_to_le16(buf_len);
 	cmd->template_type = template_id;
-	cmd->enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
-	cmd->short_retry_limit = ACX_RATE_RETRY_LIMIT;
-	cmd->long_retry_limit = ACX_RATE_RETRY_LIMIT;
+	cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates);
+	cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
+	cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
 
 	if (buf)
 		memcpy(cmd->template_data, buf, buf_len);
 
-	ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_warning("cmd set_template failed: %d", ret);
 		goto out_free;
@@ -623,30 +777,62 @@ out:
 	return ret;
 }
 
-static int wl1271_build_basic_rates(char *rates)
+static int wl1271_build_basic_rates(u8 *rates, u8 band)
 {
 	u8 index = 0;
 
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+	if (band == IEEE80211_BAND_2GHZ) {
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+	} else if (band == IEEE80211_BAND_5GHZ) {
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
+	} else {
+		wl1271_error("build_basic_rates invalid band: %d", band);
+	}
 
 	return index;
 }
 
-static int wl1271_build_extended_rates(char *rates)
+static int wl1271_build_extended_rates(u8 *rates, u8 band)
 {
 	u8 index = 0;
 
-	rates[index++] = IEEE80211_OFDM_RATE_6MB;
-	rates[index++] = IEEE80211_OFDM_RATE_9MB;
-	rates[index++] = IEEE80211_OFDM_RATE_12MB;
-	rates[index++] = IEEE80211_OFDM_RATE_18MB;
-	rates[index++] = IEEE80211_OFDM_RATE_24MB;
-	rates[index++] = IEEE80211_OFDM_RATE_36MB;
-	rates[index++] = IEEE80211_OFDM_RATE_48MB;
-	rates[index++] = IEEE80211_OFDM_RATE_54MB;
+	if (band == IEEE80211_BAND_2GHZ) {
+		rates[index++] = IEEE80211_OFDM_RATE_6MB;
+		rates[index++] = IEEE80211_OFDM_RATE_9MB;
+		rates[index++] = IEEE80211_OFDM_RATE_12MB;
+		rates[index++] = IEEE80211_OFDM_RATE_18MB;
+		rates[index++] = IEEE80211_OFDM_RATE_24MB;
+		rates[index++] = IEEE80211_OFDM_RATE_36MB;
+		rates[index++] = IEEE80211_OFDM_RATE_48MB;
+		rates[index++] = IEEE80211_OFDM_RATE_54MB;
+	} else if (band == IEEE80211_BAND_5GHZ) {
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
+		rates[index++] =
+			IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
+	} else {
+		wl1271_error("build_basic_rates invalid band: %d", band);
+	}
 
 	return index;
 }
@@ -665,7 +851,8 @@ int wl1271_cmd_build_null_data(struct wl
 
 	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
 	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
-						IEEE80211_STYPE_NULLFUNC);
+						IEEE80211_STYPE_NULLFUNC |
+						IEEE80211_FCTL_TODS);
 
 	return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template,
 				       sizeof(template));
@@ -678,7 +865,10 @@ int wl1271_cmd_build_ps_poll(struct wl12
 
 	memcpy(template.bssid, wl->bssid, ETH_ALEN);
 	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
-	template.aid = aid;
+
+	/* aid in PS-Poll has its two MSBs each set to 1 */
+	template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
+
 	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
 
 	return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template,
@@ -686,12 +876,14 @@ int wl1271_cmd_build_ps_poll(struct wl12
 
 }
 
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len)
+int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len,
+			       u8 band)
 {
 	struct wl12xx_probe_req_template template;
 	struct wl12xx_ie_rates *rates;
 	char *ptr;
 	u16 size;
+	int ret;
 
 	ptr = (char *)&template;
 	size = sizeof(struct ieee80211_header);
@@ -713,20 +905,25 @@ int wl1271_cmd_build_probe_req(struct wl
 	/* Basic Rates */
 	rates = (struct wl12xx_ie_rates *)ptr;
 	rates->header.id = WLAN_EID_SUPP_RATES;
-	rates->header.len = wl1271_build_basic_rates(rates->rates);
+	rates->header.len = wl1271_build_basic_rates(rates->rates, band);
 	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
 	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
 
 	/* Extended rates */
 	rates = (struct wl12xx_ie_rates *)ptr;
 	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
-	rates->header.len = wl1271_build_extended_rates(rates->rates);
+	rates->header.len = wl1271_build_extended_rates(rates->rates, band);
 	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
 
 	wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
 
-	return wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
-				       &template, size);
+	if (band == IEEE80211_BAND_2GHZ)
+		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+					      &template, size);
+	else
+		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+					      &template, size);
+	return ret;
 }
 
 int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -743,10 +940,10 @@ int wl1271_cmd_set_default_wep_key(struc
 	}
 
 	cmd->id = id;
-	cmd->key_action = KEY_SET_ID;
+	cmd->key_action = cpu_to_le16(KEY_SET_ID);
 	cmd->key_type = KEY_WEP;
 
-	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_warning("cmd set_default_wep_key failed: %d", ret);
 		goto out;
@@ -759,7 +956,8 @@ out:
 }
 
 int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
-		       u8 key_size, const u8 *key, const u8 *addr)
+		       u8 key_size, const u8 *key, const u8 *addr,
+		       u32 tx_seq_32, u16 tx_seq_16)
 {
 	struct wl1271_cmd_set_keys *cmd;
 	int ret = 0;
@@ -773,16 +971,18 @@ int wl1271_cmd_set_key(struct wl1271 *wl
 	if (key_type != KEY_WEP)
 		memcpy(cmd->addr, addr, ETH_ALEN);
 
-	cmd->key_action = action;
+	cmd->key_action = cpu_to_le16(action);
 	cmd->key_size = key_size;
 	cmd->key_type = key_type;
 
+	cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
+	cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
+
 	/* we have only one SSID profile */
 	cmd->ssid_profile = 0;
 
 	cmd->id = id;
 
-	/* FIXME: this is from wl1251, needs to be checked */
 	if (key_type == KEY_TKIP) {
 		/*
 		 * We get the key in the following form:
@@ -800,7 +1000,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl
 
 	wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
 
-	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
 	if (ret < 0) {
 		wl1271_warning("could not set keys");
 		goto out;
@@ -811,3 +1011,34 @@ out:
 
 	return ret;
 }
+
+int wl1271_cmd_disconnect(struct wl1271 *wl)
+{
+	struct wl1271_cmd_disconnect *cmd;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd disconnect");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->rx_config_options = cpu_to_le32(wl->rx_config);
+	cmd->rx_filter_options = cpu_to_le32(wl->rx_filter);
+	/* disconnect reason is not used in immediate disconnections */
+	cmd->type = DISCONNECT_IMMEDIATE;
+
+	ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0);
+	if (ret < 0) {
+		wl1271_error("failed to send disconnect command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_cmd.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,9 +29,11 @@
 
 struct acx_header;
 
-int wl1271_cmd_send(struct wl1271 *wl, u16 type, void *buf, size_t buf_len);
-int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
-		    u16 beacon_interval, u8 wait);
+int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
+		    size_t res_len);
+int wl1271_cmd_general_parms(struct wl1271 *wl);
+int wl1271_cmd_radio_parms(struct wl1271 *wl);
+int wl1271_cmd_join(struct wl1271 *wl);
 int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
 int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
 int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
@@ -40,16 +42,19 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl
 int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
 			   size_t len);
 int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
-		    u8 active_scan, u8 high_prio, u8 num_channels,
+		    u8 active_scan, u8 high_prio, u8 band,
 		    u8 probe_requests);
 int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
 			    void *buf, size_t buf_len);
 int wl1271_cmd_build_null_data(struct wl1271 *wl);
 int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len);
+int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len,
+			       u8 band);
 int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
 int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
-		       u8 key_size, const u8 *key, const u8 *addr);
+		       u8 key_size, const u8 *key, const u8 *addr,
+		       u32 tx_seq_32, u16 tx_seq_16);
+int wl1271_cmd_disconnect(struct wl1271 *wl);
 
 enum wl1271_commands {
 	CMD_INTERROGATE     = 1,    /*use this to read information elements*/
@@ -118,8 +123,8 @@ enum cmd_templ {
 #define WL1271_CMD_TEMPL_MAX_SIZE  252
 
 struct wl1271_cmd_header {
-	u16 id;
-	u16 status;
+	__le16 id;
+	__le16 status;
 	/* payload */
 	u8 data[0];
 } __attribute__ ((packed));
@@ -172,17 +177,17 @@ struct cmd_read_write_memory {
 	struct wl1271_cmd_header header;
 
 	/* The address of the memory to read from or write to.*/
-	u32 addr;
+	__le32 addr;
 
 	/* The amount of data in bytes to read from or write to the WiLink
 	 * device.*/
-	u32 size;
+	__le32 size;
 
 	/* The actual value read from or written to the Wilink. The source
 	   of this field is the Host in WRITE command or the Wilink in READ
 	   command. */
 	u8 value[MAX_READ_SIZE];
-};
+} __attribute__ ((packed));
 
 #define CMDMBOX_HEADER_LEN 4
 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4
@@ -196,22 +201,23 @@ enum {
 
 #define WL1271_JOIN_CMD_CTRL_TX_FLUSH     0x80 /* Firmware flushes all Tx */
 #define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
+#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10
 
 struct wl1271_cmd_join {
 	struct wl1271_cmd_header header;
 
-	u32 bssid_lsb;
-	u16 bssid_msb;
-	u16 beacon_interval; /* in TBTTs */
-	u32 rx_config_options;
-	u32 rx_filter_options;
+	__le32 bssid_lsb;
+	__le16 bssid_msb;
+	__le16 beacon_interval; /* in TBTTs */
+	__le32 rx_config_options;
+	__le32 rx_filter_options;
 
 	/*
 	 * The target uses this field to determine the rate at
 	 * which to transmit control frame responses (such as
 	 * ACK or CTS frames).
 	 */
-	u32 basic_rate_set;
+	__le32 basic_rate_set;
 	u8 dtim_interval;
 	/*
 	 * bits 0-2: This bitwise field specifies the type
@@ -240,10 +246,10 @@ struct cmd_enabledisable_path {
 struct wl1271_cmd_template_set {
 	struct wl1271_cmd_header header;
 
-	u16 len;
+	__le16 len;
 	u8 template_type;
 	u8 index;  /* relevant only for KLV_TEMPLATE type */
-	u32 enabled_rates;
+	__le32 enabled_rates;
 	u8 short_retry_limit;
 	u8 long_retry_limit;
 	u8 aflags;
@@ -280,18 +286,13 @@ struct wl1271_cmd_ps_params {
 	  * to power save mode.
 	  */
 	u8 hang_over_period;
-	u32 null_data_rate;
+	__le32 null_data_rate;
 } __attribute__ ((packed));
 
 /* HW encryption keys */
 #define NUM_ACCESS_CATEGORIES_COPY 4
 #define MAX_KEY_SIZE 32
 
-/* When set, disable HW encryption */
-#define DF_ENCRYPTION_DISABLE      0x01
-/* When set, disable HW decryption */
-#define DF_SNIFF_MODE_ENABLE       0x80
-
 enum wl1271_cmd_key_action {
 	KEY_ADD_OR_REPLACE = 1,
 	KEY_REMOVE         = 2,
@@ -316,9 +317,9 @@ struct wl1271_cmd_set_keys {
 	u8 addr[ETH_ALEN];
 
 	/* key_action_e */
-	u16 key_action;
+	__le16 key_action;
 
-	u16 reserved_1;
+	__le16 reserved_1;
 
 	/* key size in bytes */
 	u8 key_size;
@@ -334,8 +335,8 @@ struct wl1271_cmd_set_keys {
 	u8 id;
 	u8 reserved_2[6];
 	u8 key[MAX_KEY_SIZE];
-	u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
-	u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+	__le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+	__le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
 } __attribute__ ((packed));
 
 
@@ -347,19 +348,22 @@ struct wl1271_cmd_set_keys {
 #define WL1271_SCAN_OPT_PRIORITY_HIGH  4
 #define WL1271_SCAN_CHAN_MIN_DURATION  30000  /* TU */
 #define WL1271_SCAN_CHAN_MAX_DURATION  60000  /* TU */
+#define WL1271_SCAN_BAND_2_4_GHZ 0
+#define WL1271_SCAN_BAND_5_GHZ 1
+#define WL1271_SCAN_BAND_DUAL 2
 
 struct basic_scan_params {
-	u32 rx_config_options;
-	u32 rx_filter_options;
+	__le32 rx_config_options;
+	__le32 rx_filter_options;
 	/* Scan option flags (WL1271_SCAN_OPT_*) */
-	u16 scan_options;
+	__le16 scan_options;
 	/* Number of scan channels in the list (maximum 30) */
 	u8 num_channels;
 	/* This field indicates the number of probe requests to send
 	   per channel for an active scan */
 	u8 num_probe_requests;
 	/* Rate bit field for sending the probes */
-	u32 tx_rate;
+	__le32 tx_rate;
 	u8 tid_trigger;
 	u8 ssid_len;
 	/* in order to align */
@@ -374,10 +378,10 @@ struct basic_scan_params {
 
 struct basic_scan_channel_params {
 	/* Duration in TU to wait for frames on a channel for active scan */
-	u32 min_duration;
-	u32 max_duration;
-	u32 bssid_lsb;
-	u16 bssid_msb;
+	__le32 min_duration;
+	__le32 max_duration;
+	__le32 bssid_lsb;
+	__le16 bssid_msb;
 	u8 early_termination;
 	u8 tx_power_att;
 	u8 channel;
@@ -397,13 +401,13 @@ struct wl1271_cmd_scan {
 struct wl1271_cmd_trigger_scan_to {
 	struct wl1271_cmd_header header;
 
-	u32 timeout;
-};
+	__le32 timeout;
+} __attribute__ ((packed));
 
 struct wl1271_cmd_test_header {
 	u8 id;
 	u8 padding[3];
-};
+} __attribute__ ((packed));
 
 enum wl1271_channel_tune_bands {
 	WL1271_CHANNEL_TUNE_BAND_2_4,
@@ -416,6 +420,76 @@ enum wl1271_channel_tune_bands {
 #define TEST_CMD_P2G_CAL                   0x02
 #define TEST_CMD_CHANNEL_TUNE              0x0d
 #define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
+#define TEST_CMD_INI_FILE_RADIO_PARAM      0x19
+#define TEST_CMD_INI_FILE_GENERAL_PARAM    0x1E
+
+struct wl1271_general_parms_cmd {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	u8 ref_clk;
+	u8 settling_time;
+	u8 clk_valid_on_wakeup;
+	u8 dc2dcmode;
+	u8 single_dual_band;
+
+	u8 tx_bip_fem_autodetect;
+	u8 tx_bip_fem_manufacturer;
+	u8 settings;
+} __attribute__ ((packed));
+
+struct wl1271_radio_parms_cmd {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	/* Static radio parameters */
+	/* 2.4GHz */
+	u8 rx_trace_loss;
+	u8 tx_trace_loss;
+	s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/* 5GHz */
+	u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/* Dynamic radio parameters */
+	/* 2.4GHz */
+	__le16 tx_ref_pd_voltage;
+	s8  tx_ref_power;
+	s8  tx_offset_db;
+
+	s8  tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
+	s8  tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
+	s8  tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
+
+	u8  tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
+	u8  rx_fem_insertion_loss;
+
+	u8 padding2;
+
+	/* 5GHz */
+	__le16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8  tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8  tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
+
+	s8  tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
+	s8  tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
+
+	/* FIXME: this is inconsistent with the types for 2.4GHz */
+	s8  tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+
+	u8 padding3[2];
+} __attribute__ ((packed));
 
 struct wl1271_cmd_cal_channel_tune {
 	struct wl1271_cmd_header header;
@@ -425,7 +499,7 @@ struct wl1271_cmd_cal_channel_tune {
 	u8 band;
 	u8 channel;
 
-	u16 radio_status;
+	__le16 radio_status;
 } __attribute__ ((packed));
 
 struct wl1271_cmd_cal_update_ref_point {
@@ -433,8 +507,8 @@ struct wl1271_cmd_cal_update_ref_point {
 
 	struct wl1271_cmd_test_header test;
 
-	s32 ref_power;
-	s32 ref_detector;
+	__le32 ref_power;
+	__le32 ref_detector;
 	u8  sub_band;
 	u8  padding[3];
 } __attribute__ ((packed));
@@ -449,16 +523,42 @@ struct wl1271_cmd_cal_p2g {
 
 	struct wl1271_cmd_test_header test;
 
-	u16 len;
+	__le16 len;
 	u8  buf[MAX_TLV_LENGTH];
 	u8  type;
 	u8  padding;
 
-	s16 radio_status;
+	__le16 radio_status;
 	u8  nvs_version[MAX_NVS_VERSION_LENGTH];
 
 	u8  sub_band_mask;
 	u8  padding2;
 } __attribute__ ((packed));
 
+
+/*
+ * There are three types of disconnections:
+ *
+ * DISCONNECT_IMMEDIATE: the fw doesn't send any frames
+ * DISCONNECT_DEAUTH:    the fw generates a DEAUTH request with the reason
+ *                       we have passed
+ * DISCONNECT_DISASSOC:  the fw generates a DESASSOC request with the reason
+ *                       we have passed
+ */
+enum wl1271_disconnect_type {
+	DISCONNECT_IMMEDIATE,
+	DISCONNECT_DEAUTH,
+	DISCONNECT_DISASSOC
+};
+
+struct wl1271_cmd_disconnect {
+	__le32 rx_config_options;
+	__le32 rx_filter_options;
+
+	__le16 reason;
+	u8  type;
+
+	u8  padding;
+} __attribute__ ((packed));
+
 #endif /* __WL1271_CMD_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_conf.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,919 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_CONF_H__
+#define __WL1271_CONF_H__
+
+enum {
+	CONF_HW_BIT_RATE_1MBPS   = BIT(0),
+	CONF_HW_BIT_RATE_2MBPS   = BIT(1),
+	CONF_HW_BIT_RATE_5_5MBPS = BIT(2),
+	CONF_HW_BIT_RATE_6MBPS   = BIT(3),
+	CONF_HW_BIT_RATE_9MBPS   = BIT(4),
+	CONF_HW_BIT_RATE_11MBPS  = BIT(5),
+	CONF_HW_BIT_RATE_12MBPS  = BIT(6),
+	CONF_HW_BIT_RATE_18MBPS  = BIT(7),
+	CONF_HW_BIT_RATE_22MBPS  = BIT(8),
+	CONF_HW_BIT_RATE_24MBPS  = BIT(9),
+	CONF_HW_BIT_RATE_36MBPS  = BIT(10),
+	CONF_HW_BIT_RATE_48MBPS  = BIT(11),
+	CONF_HW_BIT_RATE_54MBPS  = BIT(12),
+	CONF_HW_BIT_RATE_MCS_0   = BIT(13),
+	CONF_HW_BIT_RATE_MCS_1   = BIT(14),
+	CONF_HW_BIT_RATE_MCS_2   = BIT(15),
+	CONF_HW_BIT_RATE_MCS_3   = BIT(16),
+	CONF_HW_BIT_RATE_MCS_4   = BIT(17),
+	CONF_HW_BIT_RATE_MCS_5   = BIT(18),
+	CONF_HW_BIT_RATE_MCS_6   = BIT(19),
+	CONF_HW_BIT_RATE_MCS_7   = BIT(20)
+};
+
+enum {
+	CONF_HW_RATE_INDEX_1MBPS   = 0,
+	CONF_HW_RATE_INDEX_2MBPS   = 1,
+	CONF_HW_RATE_INDEX_5_5MBPS = 2,
+	CONF_HW_RATE_INDEX_6MBPS   = 3,
+	CONF_HW_RATE_INDEX_9MBPS   = 4,
+	CONF_HW_RATE_INDEX_11MBPS  = 5,
+	CONF_HW_RATE_INDEX_12MBPS  = 6,
+	CONF_HW_RATE_INDEX_18MBPS  = 7,
+	CONF_HW_RATE_INDEX_22MBPS  = 8,
+	CONF_HW_RATE_INDEX_24MBPS  = 9,
+	CONF_HW_RATE_INDEX_36MBPS  = 10,
+	CONF_HW_RATE_INDEX_48MBPS  = 11,
+	CONF_HW_RATE_INDEX_54MBPS  = 12,
+	CONF_HW_RATE_INDEX_MAX     = CONF_HW_RATE_INDEX_54MBPS,
+};
+
+struct conf_sg_settings {
+	/*
+	 * Defines the PER threshold in PPM of the BT voice of which reaching
+	 * this value will trigger raising the priority of the BT voice by
+	 * the BT IP until next NFS sample interval time as defined in
+	 * nfs_sample_interval.
+	 *
+	 * Unit: PER value in PPM (parts per million)
+	 * #Error_packets / #Total_packets
+
+	 * Range: u32
+	 */
+	u32 per_threshold;
+
+	/*
+	 * This value is an absolute time in micro-seconds to limit the
+	 * maximum scan duration compensation while in SG
+	 */
+	u32 max_scan_compensation_time;
+
+	/* Defines the PER threshold of the BT voice of which reaching this
+	 * value will trigger raising the priority of the BT voice until next
+	 * NFS sample interval time as defined in sample_interval.
+	 *
+	 * Unit: msec
+	 * Range: 1-65000
+	 */
+	u16 nfs_sample_interval;
+
+	/*
+	 * Defines the load ratio for the BT.
+	 * The WLAN ratio is: 100 - load_ratio
+	 *
+	 * Unit: Percent
+	 * Range: 0-100
+	 */
+	u8 load_ratio;
+
+	/*
+	 * true - Co-ex is allowed to enter/exit P.S automatically and
+	 *        transparently to the host
+	 *
+	 * false - Co-ex is disallowed to enter/exit P.S and will trigger an
+	 *         event to the host to notify for the need to enter/exit P.S
+	 *         due to BT change state
+	 *
+	 */
+	u8 auto_ps_mode;
+
+	/*
+	 * This parameter defines the compensation percentage of num of probe
+	 * requests in case scan is initiated during BT voice/BT ACL
+	 * guaranteed link.
+	 *
+	 * Unit: Percent
+	 * Range: 0-255 (0 - No compensation)
+	 */
+	u8 probe_req_compensation;
+
+	/*
+	 * This parameter defines the compensation percentage of scan window
+	 * size in case scan is initiated during BT voice/BT ACL Guaranteed
+	 * link.
+	 *
+	 * Unit: Percent
+	 * Range: 0-255 (0 - No compensation)
+	 */
+	u8 scan_window_compensation;
+
+	/*
+	 * Defines the antenna configuration.
+	 *
+	 * Range: 0 - Single Antenna; 1 - Dual Antenna
+	 */
+	u8 antenna_config;
+
+	/*
+	 * The percent out of the Max consecutive beacon miss roaming trigger
+	 * which is the threshold for raising the priority of beacon
+	 * reception.
+	 *
+	 * Range: 1-100
+	 * N = MaxConsecutiveBeaconMiss
+	 * P = coexMaxConsecutiveBeaconMissPrecent
+	 * Threshold = MIN( N-1, round(N * P / 100))
+	 */
+	u8 beacon_miss_threshold;
+
+	/*
+	 * The RX rate threshold below which rate adaptation is assumed to be
+	 * occurring at the AP which will raise priority for ACTIVE_RX and RX
+	 * SP.
+	 *
+	 * Range: HW_BIT_RATE_*
+	 */
+	u32 rate_adaptation_threshold;
+
+	/*
+	 * The SNR above which the RX rate threshold indicating AP rate
+	 * adaptation is valid
+	 *
+	 * Range: -128 - 127
+	 */
+	s8 rate_adaptation_snr;
+};
+
+enum conf_rx_queue_type {
+	CONF_RX_QUEUE_TYPE_LOW_PRIORITY,  /* All except the high priority */
+	CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */
+};
+
+struct conf_rx_settings {
+	/*
+	 * The maximum amount of time, in TU, before the
+	 * firmware discards the MSDU.
+	 *
+	 * Range: 0 - 0xFFFFFFFF
+	 */
+	u32 rx_msdu_life_time;
+
+	/*
+	 * Packet detection threshold in the PHY.
+	 *
+	 * FIXME: details unknown.
+	 */
+	u32 packet_detection_threshold;
+
+	/*
+	 * The longest time the STA will wait to receive traffic from the AP
+	 * after a PS-poll has been transmitted.
+	 *
+	 * Range: 0 - 200000
+	 */
+	u16 ps_poll_timeout;
+	/*
+	 * The longest time the STA will wait to receive traffic from the AP
+	 * after a frame has been sent from an UPSD enabled queue.
+	 *
+	 * Range: 0 - 200000
+	 */
+	u16 upsd_timeout;
+
+	/*
+	 * The number of octets in an MPDU, below which an RTS/CTS
+	 * handshake is not performed.
+	 *
+	 * Range: 0 - 4096
+	 */
+	u16 rts_threshold;
+
+	/*
+	 * The RX Clear Channel Assessment threshold in the PHY
+	 * (the energy threshold).
+	 *
+	 * Range: ENABLE_ENERGY_D  == 0x140A
+	 *        DISABLE_ENERGY_D == 0xFFEF
+	 */
+	u16 rx_cca_threshold;
+
+	/*
+	 * Occupied Rx mem-blocks number which requires interrupting the host
+	 * (0 = no buffering, 0xffff = disabled).
+	 *
+	 * Range: u16
+	 */
+	u16 irq_blk_threshold;
+
+	/*
+	 * Rx packets number which requires interrupting the host
+	 * (0 = no buffering).
+	 *
+	 * Range: u16
+	 */
+	u16 irq_pkt_threshold;
+
+	/*
+	 * Max time in msec the FW may delay RX-Complete interrupt.
+	 *
+	 * Range: 1 - 100
+	 */
+	u16 irq_timeout;
+
+	/*
+	 * The RX queue type.
+	 *
+	 * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY,
+	 */
+	u8 queue_type;
+};
+
+#define CONF_TX_MAX_RATE_CLASSES       8
+
+#define CONF_TX_RATE_MASK_UNSPECIFIED  0
+#define CONF_TX_RATE_MASK_ALL          0x1eff
+#define CONF_TX_RATE_RETRY_LIMIT       10
+
+struct conf_tx_rate_class {
+
+	/*
+	 * The rates enabled for this rate class.
+	 *
+	 * Range: CONF_HW_BIT_RATE_* bit mask
+	 */
+	u32 enabled_rates;
+
+	/*
+	 * The dot11 short retry limit used for TX retries.
+	 *
+	 * Range: u8
+	 */
+	u8 short_retry_limit;
+
+	/*
+	 * The dot11 long retry limit used for TX retries.
+	 *
+	 * Range: u8
+	 */
+	u8 long_retry_limit;
+
+	/*
+	 * Flags controlling the attributes of TX transmission.
+	 *
+	 * Range: bit 0: Truncate - when set, FW attempts to send a frame stop
+	 *               when the total valid per-rate attempts have
+	 *               been exhausted; otherwise transmissions
+	 *               will continue at the lowest available rate
+	 *               until the appropriate one of the
+	 *               short_retry_limit, long_retry_limit,
+	 *               dot11_max_transmit_msdu_life_time, or
+	 *               max_tx_life_time, is exhausted.
+	 *            1: Preamble Override - indicates if the preamble type
+	 *               should be used in TX.
+	 *            2: Preamble Type - the type of the preamble to be used by
+	 *               the policy (0 - long preamble, 1 - short preamble.
+	 */
+	u8 aflags;
+};
+
+#define CONF_TX_MAX_AC_COUNT 4
+
+/* Slot number setting to start transmission at PIFS interval */
+#define CONF_TX_AIFS_PIFS 1
+/* Slot number setting to start transmission at DIFS interval normal
+ * DCF access */
+#define CONF_TX_AIFS_DIFS 2
+
+
+enum conf_tx_ac {
+	CONF_TX_AC_BE = 0,         /* best effort / legacy */
+	CONF_TX_AC_BK = 1,         /* background */
+	CONF_TX_AC_VI = 2,         /* video */
+	CONF_TX_AC_VO = 3,         /* voice */
+	CONF_TX_AC_CTS2SELF = 4,   /* fictious AC, follows AC_VO */
+	CONF_TX_AC_ANY_TID = 0x1f
+};
+
+struct conf_tx_ac_category {
+	/*
+	 * The AC class identifier.
+	 *
+	 * Range: enum conf_tx_ac
+	 */
+	u8 ac;
+
+	/*
+	 * The contention window minimum size (in slots) for the access
+	 * class.
+	 *
+	 * Range: u8
+	 */
+	u8 cw_min;
+
+	/*
+	 * The contention window maximum size (in slots) for the access
+	 * class.
+	 *
+	 * Range: u8
+	 */
+	u16 cw_max;
+
+	/*
+	 * The AIF value (in slots) for the access class.
+	 *
+	 * Range: u8
+	 */
+	u8 aifsn;
+
+	/*
+	 * The TX Op Limit (in microseconds) for the access class.
+	 *
+	 * Range: u16
+	 */
+	u16 tx_op_limit;
+};
+
+#define CONF_TX_MAX_TID_COUNT 7
+
+enum {
+	CONF_CHANNEL_TYPE_DCF = 0,   /* DC/LEGACY*/
+	CONF_CHANNEL_TYPE_EDCF = 1,  /* EDCA*/
+	CONF_CHANNEL_TYPE_HCCA = 2,  /* HCCA*/
+};
+
+enum {
+	CONF_PS_SCHEME_LEGACY = 0,
+	CONF_PS_SCHEME_UPSD_TRIGGER = 1,
+	CONF_PS_SCHEME_LEGACY_PSPOLL = 2,
+	CONF_PS_SCHEME_SAPSD = 3,
+};
+
+enum {
+	CONF_ACK_POLICY_LEGACY = 0,
+	CONF_ACK_POLICY_NO_ACK = 1,
+	CONF_ACK_POLICY_BLOCK = 2,
+};
+
+
+struct conf_tx_tid {
+	u8 queue_id;
+	u8 channel_type;
+	u8 tsid;
+	u8 ps_scheme;
+	u8 ack_policy;
+	u32 apsd_conf[2];
+};
+
+struct conf_tx_settings {
+	/*
+	 * The TX ED value for TELEC Enable/Disable.
+	 *
+	 * Range: 0, 1
+	 */
+	u8 tx_energy_detection;
+
+	/*
+	 * Configuration for rate classes for TX (currently only one
+	 * rate class supported.)
+	 */
+	struct conf_tx_rate_class rc_conf;
+
+	/*
+	 * Configuration for access categories for TX rate control.
+	 */
+	u8 ac_conf_count;
+	struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];
+
+	/*
+	 * Configuration for TID parameters.
+	 */
+	u8 tid_conf_count;
+	struct conf_tx_tid tid_conf[CONF_TX_MAX_TID_COUNT];
+
+	/*
+	 * The TX fragmentation threshold.
+	 *
+	 * Range: u16
+	 */
+	u16 frag_threshold;
+
+	/*
+	 * Max time in msec the FW may delay frame TX-Complete interrupt.
+	 *
+	 * Range: u16
+	 */
+	u16 tx_compl_timeout;
+
+	/*
+	 * Completed TX packet count which requires to issue the TX-Complete
+	 * interrupt.
+	 *
+	 * Range: u16
+	 */
+	u16 tx_compl_threshold;
+
+};
+
+enum {
+	CONF_WAKE_UP_EVENT_BEACON    = 0x01, /* Wake on every Beacon*/
+	CONF_WAKE_UP_EVENT_DTIM      = 0x02, /* Wake on every DTIM*/
+	CONF_WAKE_UP_EVENT_N_DTIM    = 0x04, /* Wake every Nth DTIM */
+	CONF_WAKE_UP_EVENT_N_BEACONS = 0x08, /* Wake every Nth beacon */
+	CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F
+};
+
+#define CONF_MAX_BCN_FILT_IE_COUNT 32
+
+#define CONF_BCN_RULE_PASS_ON_CHANGE         BIT(0)
+#define CONF_BCN_RULE_PASS_ON_APPEARANCE     BIT(1)
+
+#define CONF_BCN_IE_OUI_LEN    3
+#define CONF_BCN_IE_VER_LEN    2
+
+struct conf_bcn_filt_rule {
+	/*
+	 * IE number to which to associate a rule.
+	 *
+	 * Range: u8
+	 */
+	u8 ie;
+
+	/*
+	 * Rule to associate with the specific ie.
+	 *
+	 * Range: CONF_BCN_RULE_PASS_ON_*
+	 */
+	u8 rule;
+
+	/*
+	 * OUI for the vendor specifie IE (221)
+	 */
+	u8 oui[CONF_BCN_IE_OUI_LEN];
+
+	/*
+	 * Type for the vendor specifie IE (221)
+	 */
+	u8 type;
+
+	/*
+	 * Version for the vendor specifie IE (221)
+	 */
+	u8 version[CONF_BCN_IE_VER_LEN];
+};
+
+#define CONF_MAX_RSSI_SNR_TRIGGERS 8
+
+enum {
+	CONF_TRIG_METRIC_RSSI_BEACON = 0,
+	CONF_TRIG_METRIC_RSSI_DATA,
+	CONF_TRIG_METRIC_SNR_BEACON,
+	CONF_TRIG_METRIC_SNR_DATA
+};
+
+enum {
+	CONF_TRIG_EVENT_TYPE_LEVEL = 0,
+	CONF_TRIG_EVENT_TYPE_EDGE
+};
+
+enum {
+	CONF_TRIG_EVENT_DIR_LOW = 0,
+	CONF_TRIG_EVENT_DIR_HIGH,
+	CONF_TRIG_EVENT_DIR_BIDIR
+};
+
+
+struct conf_sig_trigger {
+	/*
+	 * The RSSI / SNR threshold value.
+	 *
+	 * FIXME: what is the range?
+	 */
+	s16 threshold;
+
+	/*
+	 * Minimum delay between two trigger events for this trigger in ms.
+	 *
+	 * Range: 0 - 60000
+	 */
+	u16 pacing;
+
+	/*
+	 * The measurement data source for this trigger.
+	 *
+	 * Range: CONF_TRIG_METRIC_*
+	 */
+	u8 metric;
+
+	/*
+	 * The trigger type of this trigger.
+	 *
+	 * Range: CONF_TRIG_EVENT_TYPE_*
+	 */
+	u8 type;
+
+	/*
+	 * The direction of the trigger.
+	 *
+	 * Range: CONF_TRIG_EVENT_DIR_*
+	 */
+	u8 direction;
+
+	/*
+	 * Hysteresis range of the trigger around the threshold (in dB)
+	 *
+	 * Range: u8
+	 */
+	u8 hysteresis;
+
+	/*
+	 * Index of the trigger rule.
+	 *
+	 * Range: 0 - CONF_MAX_RSSI_SNR_TRIGGERS-1
+	 */
+	u8 index;
+
+	/*
+	 * Enable / disable this rule (to use for clearing rules.)
+	 *
+	 * Range: 1 - Enabled, 2 - Not enabled
+	 */
+	u8 enable;
+};
+
+struct conf_sig_weights {
+
+	/*
+	 * RSSI from beacons average weight.
+	 *
+	 * Range: u8
+	 */
+	u8 rssi_bcn_avg_weight;
+
+	/*
+	 * RSSI from data average weight.
+	 *
+	 * Range: u8
+	 */
+	u8 rssi_pkt_avg_weight;
+
+	/*
+	 * SNR from beacons average weight.
+	 *
+	 * Range: u8
+	 */
+	u8 snr_bcn_avg_weight;
+
+	/*
+	 * SNR from data average weight.
+	 *
+	 * Range: u8
+	 */
+	u8 snr_pkt_avg_weight;
+};
+
+enum conf_bcn_filt_mode {
+	CONF_BCN_FILT_MODE_DISABLED = 0,
+	CONF_BCN_FILT_MODE_ENABLED = 1
+};
+
+enum conf_bet_mode {
+	CONF_BET_MODE_DISABLE = 0,
+	CONF_BET_MODE_ENABLE = 1,
+};
+
+struct conf_conn_settings {
+	/*
+	 * Firmware wakeup conditions configuration. The host may set only
+	 * one bit.
+	 *
+	 * Range: CONF_WAKE_UP_EVENT_*
+	 */
+	u8 wake_up_event;
+
+	/*
+	 * Listen interval for beacons or Dtims.
+	 *
+	 * Range: 0 for beacon and Dtim wakeup
+	 *        1-10 for x Dtims
+	 *        1-255 for x beacons
+	 */
+	u8 listen_interval;
+
+	/*
+	 * Enable or disable the beacon filtering.
+	 *
+	 * Range: CONF_BCN_FILT_MODE_*
+	 */
+	enum conf_bcn_filt_mode bcn_filt_mode;
+
+	/*
+	 * Configure Beacon filter pass-thru rules.
+	 */
+	u8 bcn_filt_ie_count;
+	struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT];
+
+	/*
+	 * The number of consequtive beacons to lose, before the firmware
+	 * becomes out of synch.
+	 *
+	 * Range: u32
+	 */
+	u32 synch_fail_thold;
+
+	/*
+	 * After out-of-synch, the number of TU's to wait without a further
+	 * received beacon (or probe response) before issuing the BSS_EVENT_LOSE
+	 * event.
+	 *
+	 * Range: u32
+	 */
+	u32 bss_lose_timeout;
+
+	/*
+	 * Beacon receive timeout.
+	 *
+	 * Range: u32
+	 */
+	u32 beacon_rx_timeout;
+
+	/*
+	 * Broadcast receive timeout.
+	 *
+	 * Range: u32
+	 */
+	u32 broadcast_timeout;
+
+	/*
+	 * Enable/disable reception of broadcast packets in power save mode
+	 *
+	 * Range: 1 - enable, 0 - disable
+	 */
+	u8 rx_broadcast_in_ps;
+
+	/*
+	 * Consequtive PS Poll failures before sending event to driver
+	 *
+	 * Range: u8
+	 */
+	u8 ps_poll_threshold;
+
+	/*
+	 * Configuration of signal (rssi/snr) triggers.
+	 */
+	u8 sig_trigger_count;
+	struct conf_sig_trigger sig_trigger[CONF_MAX_RSSI_SNR_TRIGGERS];
+
+	/*
+	 * Configuration of signal average weights.
+	 */
+	struct conf_sig_weights sig_weights;
+
+	/*
+	 * Specifies if beacon early termination procedure is enabled or
+	 * disabled.
+	 *
+	 * Range: CONF_BET_MODE_*
+	 */
+	u8 bet_enable;
+
+	/*
+	 * Specifies the maximum number of consecutive beacons that may be
+	 * early terminated. After this number is reached at least one full
+	 * beacon must be correctly received in FW before beacon ET
+	 * resumes.
+	 *
+	 * Range 0 - 255
+	 */
+	u8 bet_max_consecutive;
+
+	/*
+	 * Specifies the maximum number of times to try PSM entry if it fails
+	 * (if sending the appropriate null-func message fails.)
+	 *
+	 * Range 0 - 255
+	 */
+	u8 psm_entry_retries;
+};
+
+#define CONF_SR_ERR_TBL_MAX_VALUES   14
+
+struct conf_mart_reflex_err_table {
+	/*
+	 * Length of the error table values table.
+	 *
+	 * Range: 0 - CONF_SR_ERR_TBL_MAX_VALUES
+	 */
+	u8 len;
+
+	/*
+	 * Smart Reflex error table upper limit.
+	 *
+	 * Range: s8
+	 */
+	s8 upper_limit;
+
+	/*
+	 * Smart Reflex error table values.
+	 *
+	 * Range: s8
+	 */
+	s8 values[CONF_SR_ERR_TBL_MAX_VALUES];
+};
+
+enum {
+	CONF_REF_CLK_19_2_E,
+	CONF_REF_CLK_26_E,
+	CONF_REF_CLK_38_4_E,
+	CONF_REF_CLK_52_E
+};
+
+enum single_dual_band_enum {
+	CONF_SINGLE_BAND,
+	CONF_DUAL_BAND
+};
+
+struct conf_general_parms {
+	/*
+	 * RF Reference Clock type / speed
+	 *
+	 * Range: CONF_REF_CLK_*
+	 */
+	u8 ref_clk;
+
+	/*
+	 * Settling time of the reference clock after boot.
+	 *
+	 * Range: u8
+	 */
+	u8 settling_time;
+
+	/*
+	 * Flag defining whether clock is valid on wakeup.
+	 *
+	 * Range: 0 - not valid on wakeup, 1 - valid on wakeup
+	 */
+	u8 clk_valid_on_wakeup;
+
+	/*
+	 * DC-to-DC mode.
+	 *
+	 * Range: Unknown
+	 */
+	u8 dc2dcmode;
+
+	/*
+	 * Flag defining whether used as single or dual-band.
+	 *
+	 * Range: CONF_SINGLE_BAND, CONF_DUAL_BAND
+	 */
+	u8 single_dual_band;
+
+	/*
+	 * TX bip fem autodetect flag.
+	 *
+	 * Range: Unknown
+	 */
+	u8 tx_bip_fem_autodetect;
+
+	/*
+	 * TX bip gem manufacturer.
+	 *
+	 * Range: Unknown
+	 */
+	u8 tx_bip_fem_manufacturer;
+
+	/*
+	 * Settings flags.
+	 *
+	 * Range: Unknown
+	 */
+	u8 settings;
+};
+
+#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15
+#define CONF_NUMBER_OF_SUB_BANDS_5  7
+#define CONF_NUMBER_OF_RATE_GROUPS  6
+#define CONF_NUMBER_OF_CHANNELS_2_4 14
+#define CONF_NUMBER_OF_CHANNELS_5   35
+
+struct conf_radio_parms {
+	/*
+	 * Static radio parameters for 2.4GHz
+	 *
+	 * Range: unknown
+	 */
+	u8 rx_trace_loss;
+	u8 tx_trace_loss;
+	s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/*
+	 * Static radio parameters for 5GHz
+	 *
+	 * Range: unknown
+	 */
+	u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/*
+	 * Dynamic radio parameters for 2.4GHz
+	 *
+	 * Range: unknown
+	 */
+	s16 tx_ref_pd_voltage;
+	s8  tx_ref_power;
+	s8  tx_offset_db;
+
+	s8  tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];
+	s8  tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];
+	s8  tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];
+
+	u8  tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];
+	u8  rx_fem_insertion_loss;
+
+	/*
+	 * Dynamic radio parameters for 5GHz
+	 *
+	 * Range: unknown
+	 */
+	s16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8  tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];
+	s8  tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];
+
+	s8  tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];
+	s8  tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];
+
+	/* FIXME: this is inconsistent with the types for 2.4GHz */
+	s8  tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];
+	s8  rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];
+};
+
+#define CONF_SR_ERR_TBL_COUNT        3
+
+struct conf_init_settings {
+	/*
+	 * Configure Smart Reflex error table values.
+	 */
+	struct conf_mart_reflex_err_table sr_err_tbl[CONF_SR_ERR_TBL_COUNT];
+
+	/*
+	 * Smart Reflex enable flag.
+	 *
+	 * Range: 1 - Smart Reflex enabled, 0 - Smart Reflex disabled
+	 */
+	u8 sr_enable;
+
+	/*
+	 * Configure general parameters.
+	 */
+	struct conf_general_parms genparam;
+
+	/*
+	 * Configure radio parameters.
+	 */
+	struct conf_radio_parms radioparam;
+
+};
+
+struct conf_drv_settings {
+	struct conf_sg_settings sg;
+	struct conf_rx_settings rx;
+	struct conf_tx_settings tx;
+	struct conf_conn_settings conn;
+	struct conf_init_settings init;
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,23 +26,86 @@
 #include "wl1271_spi.h"
 #include "wl1271_event.h"
 #include "wl1271_ps.h"
+#include "wl12xx_80211.h"
 
 static int wl1271_event_scan_complete(struct wl1271 *wl,
 				      struct event_mailbox *mbox)
 {
+	int size = sizeof(struct wl12xx_probe_req_template);
 	wl1271_debug(DEBUG_EVENT, "status: 0x%x",
 		     mbox->scheduled_scan_status);
 
 	if (wl->scanning) {
-		mutex_unlock(&wl->mutex);
-		ieee80211_scan_completed(wl->hw, false);
-		mutex_lock(&wl->mutex);
-		wl->scanning = false;
-	}
+		if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
+			wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+						NULL, size);
+			/* 2.4 GHz band scanned, scan 5 GHz band, pretend
+			 * to the wl1271_cmd_scan function that we are not
+			 * scanning as it checks that.
+			 */
+			wl->scanning = false;
+			wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
+						wl->scan.active,
+						wl->scan.high_prio,
+						WL1271_SCAN_BAND_5_GHZ,
+						wl->scan.probe_requests);
+		} else {
+			if (wl->scan.state == WL1271_SCAN_BAND_2_4_GHZ)
+				wl1271_cmd_template_set(wl,
+						CMD_TEMPL_CFG_PROBE_REQ_2_4,
+						NULL, size);
+			else
+				wl1271_cmd_template_set(wl,
+						CMD_TEMPL_CFG_PROBE_REQ_5,
+						NULL, size);
 
+			mutex_unlock(&wl->mutex);
+			ieee80211_scan_completed(wl->hw, false);
+			mutex_lock(&wl->mutex);
+			wl->scanning = false;
+		}
+	}
 	return 0;
 }
 
+static int wl1271_event_ps_report(struct wl1271 *wl,
+				  struct event_mailbox *mbox,
+				  bool *beacon_loss)
+{
+	int ret = 0;
+
+	wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
+
+	switch (mbox->ps_status) {
+	case EVENT_ENTER_POWER_SAVE_FAIL:
+		if (!wl->psm) {
+			wl->psm_entry_retry = 0;
+			break;
+		}
+
+		if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
+			wl->psm_entry_retry++;
+			ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+		} else {
+			wl1271_error("PSM entry failed, giving up.\n");
+			wl->psm_entry_retry = 0;
+			*beacon_loss = true;
+		}
+		break;
+	case EVENT_ENTER_POWER_SAVE_SUCCESS:
+		wl->psm_entry_retry = 0;
+		break;
+	case EVENT_EXIT_POWER_SAVE_FAIL:
+		wl1271_info("PSM exit failed");
+		break;
+	case EVENT_EXIT_POWER_SAVE_SUCCESS:
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
 {
 	wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -54,10 +117,12 @@ static int wl1271_event_process(struct w
 {
 	int ret;
 	u32 vector;
+	bool beacon_loss = false;
 
 	wl1271_event_mbox_dump(mbox);
 
-	vector = mbox->events_vector & ~(mbox->events_mask);
+	vector = le32_to_cpu(mbox->events_vector);
+	vector &= ~(le32_to_cpu(mbox->events_mask));
 	wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);
 
 	if (vector & SCAN_COMPLETE_EVENT_ID) {
@@ -66,14 +131,34 @@ static int wl1271_event_process(struct w
 			return ret;
 	}
 
-	if (vector & BSS_LOSE_EVENT_ID) {
+	/*
+	 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
+	 * filtering) is enabled. Without PSM, the stack will receive all
+	 * beacons and can detect beacon loss by itself.
+	 */
+	if (vector & BSS_LOSE_EVENT_ID && wl->psm) {
 		wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
-		if (wl->psm_requested && wl->psm) {
-			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
-			if (ret < 0)
-				return ret;
-		}
+		/* indicate to the stack, that beacons have been lost */
+		beacon_loss = true;
+	}
+
+	if (vector & PS_REPORT_EVENT_ID) {
+		wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
+		ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (beacon_loss) {
+		/* Obviously, it's dangerous to release the mutex while
+		   we are holding many of the variables in the wl struct.
+		   That's why it's done last in the function, and care must
+		   be taken that nothing more is done after this function
+		   returns. */
+		mutex_unlock(&wl->mutex);
+		ieee80211_beacon_loss(wl->vif);
+		mutex_lock(&wl->mutex);
 	}
 
 	return 0;
@@ -92,14 +177,14 @@ int wl1271_event_unmask(struct wl1271 *w
 
 void wl1271_event_mbox_config(struct wl1271 *wl)
 {
-	wl->mbox_ptr[0] = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->mbox_ptr[0] = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);
 	wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
 
 	wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
 		     wl->mbox_ptr[0], wl->mbox_ptr[1]);
 }
 
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num, bool do_ack)
 {
 	struct event_mailbox mbox;
 	int ret;
@@ -110,8 +195,8 @@ int wl1271_event_handle(struct wl1271 *w
 		return -EINVAL;
 
 	/* first we read the mbox descriptor */
-	wl1271_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
-			    sizeof(struct event_mailbox));
+	wl1271_spi_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+			sizeof(struct event_mailbox), false);
 
 	/* process the descriptor */
 	ret = wl1271_event_process(wl, &mbox);
@@ -119,7 +204,9 @@ int wl1271_event_handle(struct wl1271 *w
 		return ret;
 
 	/* then we let the firmware know it can go on...*/
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+	if (do_ack)
+		wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG,
+				   INTR_TRIG_EVENT_ACK);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_event.h	2010-02-24 13:52:17.000000000 -0500
@@ -63,36 +63,43 @@ enum {
 	EVENT_MBOX_ALL_EVENT_ID			 = 0x7fffffff,
 };
 
+enum {
+	EVENT_ENTER_POWER_SAVE_FAIL = 0,
+	EVENT_ENTER_POWER_SAVE_SUCCESS,
+	EVENT_EXIT_POWER_SAVE_FAIL,
+	EVENT_EXIT_POWER_SAVE_SUCCESS,
+};
+
 struct event_debug_report {
 	u8 debug_event_id;
 	u8 num_params;
-	u16 pad;
-	u32 report_1;
-	u32 report_2;
-	u32 report_3;
+	__le16 pad;
+	__le32 report_1;
+	__le32 report_2;
+	__le32 report_3;
 } __attribute__ ((packed));
 
 #define NUM_OF_RSSI_SNR_TRIGGERS 8
 
 struct event_mailbox {
-	u32 events_vector;
-	u32 events_mask;
-	u32 reserved_1;
-	u32 reserved_2;
+	__le32 events_vector;
+	__le32 events_mask;
+	__le32 reserved_1;
+	__le32 reserved_2;
 
 	u8 dbg_event_id;
 	u8 num_relevant_params;
-	u16 reserved_3;
-	u32 event_report_p1;
-	u32 event_report_p2;
-	u32 event_report_p3;
+	__le16 reserved_3;
+	__le32 event_report_p1;
+	__le32 event_report_p2;
+	__le32 event_report_p3;
 
 	u8 number_of_scan_results;
 	u8 scan_tag;
 	u8 reserved_4[2];
-	u32 compl_scheduled_scan_status;
+	__le32 compl_scheduled_scan_status;
 
-	u16 scheduled_scan_attended_channels;
+	__le16 scheduled_scan_attended_channels;
 	u8 soft_gemini_sense_info;
 	u8 soft_gemini_protective_info;
 	s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
@@ -105,6 +112,6 @@ struct event_mailbox {
 
 int wl1271_event_unmask(struct wl1271 *wl);
 void wl1271_event_mbox_config(struct wl1271 *wl);
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox, bool do_ack);
 
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271.h	2013-05-03 14:04:12.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271.h	2013-05-03 12:11:45.000000000 -0400
@@ -32,6 +32,8 @@
 #include <linux/bitops.h>
 #include <net/mac80211.h>
 
+#include "wl1271_conf.h"
+
 #define DRIVER_NAME "wl1271"
 #define DRIVER_PREFIX DRIVER_NAME ": "
 
@@ -97,21 +99,42 @@ enum {
 	} while (0)
 
 #define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |	\
-				  CFG_BSSID_FILTER_EN)
+				  CFG_BSSID_FILTER_EN | \
+				  CFG_MC_FILTER_EN)
 
 #define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN |  \
 				  CFG_RX_MGMT_EN | CFG_RX_DATA_EN |   \
 				  CFG_RX_CTL_EN | CFG_RX_BCN_EN |     \
 				  CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
 
+#define WL1271_DEFAULT_BASIC_RATE_SET (CONF_TX_RATE_MASK_ALL)
+
 #define WL1271_FW_NAME "/*(DEBLOBBED)*/"
 #define WL1271_NVS_NAME "/*(DEBLOBBED)*/"
 
-#define WL1271_BUSY_WORD_LEN 8
+/*
+ * Enable/disable 802.11a support for WL1273
+ */
+#undef WL1271_80211A_ENABLED
+
+/*
+ * FIXME: for the wl1271, a busy word count of 1 here will result in a more
+ * optimal SPI interface. There is some SPI bug however, causing RXS time outs
+ * with this mode occasionally on boot, so lets have three for now. A value of
+ * three should make sure, that the chipset will always be ready, though this
+ * will impact throughput and latencies slightly.
+ */
+#define WL1271_BUSY_WORD_CNT 3
+#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
 
 #define WL1271_ELP_HW_STATE_ASLEEP 0
 #define WL1271_ELP_HW_STATE_IRQ    1
 
+#define WL1271_DEFAULT_BEACON_INT  100
+#define WL1271_DEFAULT_DTIM_PERIOD 1
+
+#define ACX_TX_DESCRIPTORS         32
+
 enum wl1271_state {
 	WL1271_STATE_OFF,
 	WL1271_STATE_ON,
@@ -134,6 +157,8 @@ struct wl1271_partition {
 struct wl1271_partition_set {
 	struct wl1271_partition mem;
 	struct wl1271_partition reg;
+	struct wl1271_partition mem2;
+	struct wl1271_partition mem3;
 };
 
 struct wl1271;
@@ -258,15 +283,15 @@ struct wl1271_debugfs {
 
 /* FW status registers */
 struct wl1271_fw_status {
-	u32 intr;
+	__le32 intr;
 	u8  fw_rx_counter;
 	u8  drv_rx_counter;
 	u8  reserved;
 	u8  tx_results_counter;
-	u32 rx_pkt_descs[NUM_RX_PKT_DESC];
-	u32 tx_released_blks[NUM_TX_QUEUES];
-	u32 fw_localtime;
-	u32 padding[2];
+	__le32 rx_pkt_descs[NUM_RX_PKT_DESC];
+	__le32 tx_released_blks[NUM_TX_QUEUES];
+	__le32 fw_localtime;
+	__le32 padding[2];
 } __attribute__ ((packed));
 
 struct wl1271_rx_mem_pool_addr {
@@ -274,6 +299,15 @@ struct wl1271_rx_mem_pool_addr {
 	u32 addr_extra;
 };
 
+struct wl1271_scan {
+	u8 state;
+	u8 ssid[IW_ESSID_MAX_SIZE+1];
+	size_t ssid_len;
+	u8 active;
+	u8 high_prio;
+	u8 probe_requests;
+};
+
 struct wl1271 {
 	struct ieee80211_hw *hw;
 	bool mac80211_registered;
@@ -288,10 +322,7 @@ struct wl1271 {
 	enum wl1271_state state;
 	struct mutex mutex;
 
-	int physical_mem_addr;
-	int physical_reg_addr;
-	int virtual_mem_addr;
-	int virtual_reg_addr;
+	struct wl1271_partition_set part;
 
 	struct wl1271_chip chip;
 
@@ -308,7 +339,6 @@ struct wl1271 {
 	u8 bss_type;
 	u8 ssid[IW_ESSID_MAX_SIZE + 1];
 	u8 ssid_len;
-	u8 listen_int;
 	int channel;
 
 	struct wl1271_acx_mem_map *target_mem_map;
@@ -332,10 +362,14 @@ struct wl1271 {
 	bool tx_queue_stopped;
 
 	struct work_struct tx_work;
-	struct work_struct filter_work;
 
 	/* Pending TX frames */
-	struct sk_buff *tx_frames[16];
+	struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
+
+	/* Security sequence number counters */
+	u8 tx_security_last_seq;
+	u16 tx_security_seq_16;
+	u32 tx_security_seq_32;
 
 	/* FW Rx counter */
 	u32 rx_counter;
@@ -354,10 +388,17 @@ struct wl1271 {
 
 	/* Are we currently scanning */
 	bool scanning;
+	struct wl1271_scan scan;
 
 	/* Our association ID */
 	u16 aid;
 
+	/* currently configured rate set */
+	u32 basic_rate_set;
+
+	/* The current band */
+	enum ieee80211_band band;
+
 	/* Default key (for WEP) */
 	u32 default_key;
 
@@ -368,6 +409,7 @@ struct wl1271 {
 	bool elp;
 
 	struct completion *elp_compl;
+	struct delayed_work elp_work;
 
 	/* we can be in psm, but not in elp, we have to differentiate */
 	bool psm;
@@ -375,6 +417,9 @@ struct wl1271 {
 	/* PSM mode requested */
 	bool psm_requested;
 
+	/* retry counter for PSM entries */
+	u8 psm_entry_retry;
+
 	/* in dBm */
 	int power_level;
 
@@ -383,11 +428,20 @@ struct wl1271 {
 
 	u32 buffer_32;
 	u32 buffer_cmd;
-	u8 buffer_busyword[WL1271_BUSY_WORD_LEN];
-	struct wl1271_rx_descriptor *rx_descriptor;
+	u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
 
 	struct wl1271_fw_status *fw_status;
 	struct wl1271_tx_hw_res_if *tx_res_if;
+
+	struct ieee80211_vif *vif;
+
+	/* Used for a workaround to send disconnect before rejoining */
+	bool joined;
+
+	/* Current chipset configuration */
+	struct conf_drv_settings conf;
+
+	struct list_head list;
 };
 
 int wl1271_plt_start(struct wl1271 *wl);
@@ -404,4 +458,13 @@ int wl1271_plt_stop(struct wl1271 *wl);
 /* WL1271 needs a 200ms sleep after power on */
 #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
 
+static inline bool wl1271_11a_enabled(void)
+{
+#ifdef WL1271_80211A_ENABLED
+	return true;
+#else
+	return false;
+#endif
+}
+
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,6 +59,14 @@ static int wl1271_init_templates_config(
 	if (ret < 0)
 		return ret;
 
+	if (wl1271_11a_enabled()) {
+		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+				NULL,
+				sizeof(struct wl12xx_probe_req_template));
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
 				      sizeof(struct wl12xx_null_data_template));
 	if (ret < 0)
@@ -94,7 +102,7 @@ static int wl1271_init_rx_config(struct
 {
 	int ret;
 
-	ret = wl1271_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+	ret = wl1271_acx_rx_msdu_life_time(wl);
 	if (ret < 0)
 		return ret;
 
@@ -117,7 +125,7 @@ static int wl1271_init_phy_config(struct
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_acx_group_address_tbl(wl);
+	ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
 	if (ret < 0)
 		return ret;
 
@@ -125,7 +133,7 @@ static int wl1271_init_phy_config(struct
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+	ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold);
 	if (ret < 0)
 		return ret;
 
@@ -136,7 +144,8 @@ static int wl1271_init_beacon_filter(str
 {
 	int ret;
 
-	ret = wl1271_acx_beacon_filter_opt(wl);
+	/* disable beacon filtering at this stage */
+	ret = wl1271_acx_beacon_filter_opt(wl, false);
 	if (ret < 0)
 		return ret;
 
@@ -184,118 +193,15 @@ static int wl1271_init_beacon_broadcast(
 	return 0;
 }
 
-static int wl1271_init_general_parms(struct wl1271 *wl)
-{
-	struct wl1271_general_parms *gen_parms;
-	int ret;
-
-	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
-	if (!gen_parms)
-		return -ENOMEM;
-
-	gen_parms->id = TEST_CMD_INI_FILE_GENERAL_PARAM;
-
-	gen_parms->ref_clk = REF_CLK_38_4_E;
-	/* FIXME: magic numbers */
-	gen_parms->settling_time = 5;
-	gen_parms->clk_valid_on_wakeup = 0;
-	gen_parms->dc2dcmode = 0;
-	gen_parms->single_dual_band = 0;
-	gen_parms->tx_bip_fem_autodetect = 1;
-	gen_parms->tx_bip_fem_manufacturer = 1;
-	gen_parms->settings = 1;
-
-	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
-	if (ret < 0) {
-		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
-		return ret;
-	}
-
-	kfree(gen_parms);
-	return 0;
-}
-
-static int wl1271_init_radio_parms(struct wl1271 *wl)
-{
-	/*
-	 * FIXME: All these magic numbers should be moved to some place where
-	 * they can be configured (separate file?)
-	 */
-
-	struct wl1271_radio_parms *radio_parms;
-	int ret;
-	u8 compensation[] = { 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8, 0xfc, 0x00,
-			      0x08, 0x10, 0xf0, 0xf8, 0x00, 0x0a, 0x14 };
-
-	u8 tx_rate_limits_normal[]   = { 0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 };
-	u8 tx_rate_limits_degraded[] = { 0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 };
-
-	u8 tx_channel_limits_11b[] = { 0x22, 0x50, 0x50, 0x50,
-				       0x50, 0x50, 0x50, 0x50,
-				       0x50, 0x50, 0x22, 0x50,
-				       0x22, 0x50 };
-
-	u8 tx_channel_limits_ofdm[] = { 0x20, 0x50, 0x50, 0x50,
-					0x50, 0x50, 0x50, 0x50,
-					0x50, 0x50, 0x20, 0x50,
-					0x20, 0x50 };
-
-	u8 tx_pdv_rate_offsets[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-	u8 tx_ibias[] = { 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 };
-
-	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
-	if (!radio_parms)
-		return -ENOMEM;
-
-	radio_parms->id = TEST_CMD_INI_FILE_RADIO_PARAM;
-
-	/* Static radio parameters */
-	radio_parms->rx_trace_loss = 10;
-	radio_parms->tx_trace_loss = 10;
-	memcpy(radio_parms->rx_rssi_and_proc_compens, compensation,
-	       sizeof(compensation));
-
-	/* We don't set the 5GHz -- N/A */
-
-	/* Dynamic radio parameters */
-	radio_parms->tx_ref_pd_voltage = cpu_to_le16(0x24e);
-	radio_parms->tx_ref_power = 0x78;
-	radio_parms->tx_offset_db = 0x0;
-
-	memcpy(radio_parms->tx_rate_limits_normal, tx_rate_limits_normal,
-	       sizeof(tx_rate_limits_normal));
-	memcpy(radio_parms->tx_rate_limits_degraded, tx_rate_limits_degraded,
-	       sizeof(tx_rate_limits_degraded));
-
-	memcpy(radio_parms->tx_channel_limits_11b, tx_channel_limits_11b,
-	       sizeof(tx_channel_limits_11b));
-	memcpy(radio_parms->tx_channel_limits_ofdm, tx_channel_limits_ofdm,
-	       sizeof(tx_channel_limits_ofdm));
-	memcpy(radio_parms->tx_pdv_rate_offsets, tx_pdv_rate_offsets,
-	       sizeof(tx_pdv_rate_offsets));
-	memcpy(radio_parms->tx_ibias, tx_ibias,
-	       sizeof(tx_ibias));
-
-	radio_parms->rx_fem_insertion_loss = 0x14;
-
-	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
-	if (ret < 0)
-		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
-
-	kfree(radio_parms);
-	return ret;
-}
-
 int wl1271_hw_init(struct wl1271 *wl)
 {
 	int ret;
 
-	ret = wl1271_init_general_parms(wl);
+	ret = wl1271_cmd_general_parms(wl);
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_init_radio_parms(wl);
+	ret = wl1271_cmd_radio_parms(wl);
 	if (ret < 0)
 		return ret;
 
@@ -311,8 +217,8 @@ int wl1271_hw_init(struct wl1271 *wl)
 
 	/* RX config */
 	ret = wl1271_init_rx_config(wl,
-				       RX_CFG_PROMISCUOUS | RX_CFG_TSF,
-				       RX_FILTER_OPTION_DEF);
+				    RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+				    RX_FILTER_OPTION_DEF);
 	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
 	   RX_FILTER_OPTION_FILTER_ALL); */
 	if (ret < 0)
@@ -323,6 +229,11 @@ int wl1271_hw_init(struct wl1271 *wl)
 	if (ret < 0)
 		goto out_free_memmap;
 
+	/* Initialize connection monitoring thresholds */
+	ret = wl1271_acx_conn_monit_params(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	/* Beacon filtering */
 	ret = wl1271_init_beacon_filter(wl);
 	if (ret < 0)
@@ -369,7 +280,7 @@ int wl1271_hw_init(struct wl1271 *wl)
 		goto out_free_memmap;
 
 	/* Configure TX rate classes */
-	ret = wl1271_acx_rate_policies(wl);
+	ret = wl1271_acx_rate_policies(wl, CONF_TX_RATE_MASK_ALL);
 	if (ret < 0)
 		goto out_free_memmap;
 
@@ -388,10 +299,16 @@ int wl1271_hw_init(struct wl1271 *wl)
 	if (ret < 0)
 		goto out_free_memmap;
 
+	/* Configure smart reflex */
+	ret = wl1271_acx_smart_reflex(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	return 0;
 
  out_free_memmap:
 	kfree(wl->target_mem_map);
+	wl->target_mem_map = NULL;
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_init.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,87 +29,4 @@
 int wl1271_hw_init_power_auth(struct wl1271 *wl);
 int wl1271_hw_init(struct wl1271 *wl);
 
-/* These are not really a TEST_CMD, but the ref driver uses them as such */
-#define TEST_CMD_INI_FILE_RADIO_PARAM   0x19
-#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
-
-struct wl1271_general_parms {
-	u8 id;
-	u8 padding[3];
-
-	u8 ref_clk;
-	u8 settling_time;
-	u8 clk_valid_on_wakeup;
-	u8 dc2dcmode;
-	u8 single_dual_band;
-
-	u8 tx_bip_fem_autodetect;
-	u8 tx_bip_fem_manufacturer;
-	u8 settings;
-} __attribute__ ((packed));
-
-enum ref_clk_enum {
-	REF_CLK_19_2_E,
-	REF_CLK_26_E,
-	REF_CLK_38_4_E,
-	REF_CLK_52_E
-};
-
-#define RSSI_AND_PROCESS_COMPENSATION_SIZE 15
-#define NUMBER_OF_SUB_BANDS_5  7
-#define NUMBER_OF_RATE_GROUPS  6
-#define NUMBER_OF_CHANNELS_2_4 14
-#define NUMBER_OF_CHANNELS_5   35
-
-struct wl1271_radio_parms {
-	u8 id;
-	u8 padding[3];
-
-	/* Static radio parameters */
-	/* 2.4GHz */
-	u8 rx_trace_loss;
-	u8 tx_trace_loss;
-	s8 rx_rssi_and_proc_compens[RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/* 5GHz */
-	u8 rx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
-	u8 tx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
-	s8 rx_rssi_and_proc_compens_5[RSSI_AND_PROCESS_COMPENSATION_SIZE];
-
-	/* Dynamic radio parameters */
-	/* 2.4GHz */
-	s16 tx_ref_pd_voltage;
-	s8  tx_ref_power;
-	s8  tx_offset_db;
-
-	s8  tx_rate_limits_normal[NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded[NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_11b[NUMBER_OF_CHANNELS_2_4];
-	s8  tx_channel_limits_ofdm[NUMBER_OF_CHANNELS_2_4];
-	s8  tx_pdv_rate_offsets[NUMBER_OF_RATE_GROUPS];
-
-	u8  tx_ibias[NUMBER_OF_RATE_GROUPS];
-	u8  rx_fem_insertion_loss;
-
-	u8 padding2;
-
-	/* 5GHz */
-	s16 tx_ref_pd_voltage_5[NUMBER_OF_SUB_BANDS_5];
-	s8  tx_ref_power_5[NUMBER_OF_SUB_BANDS_5];
-	s8  tx_offset_db_5[NUMBER_OF_SUB_BANDS_5];
-
-	s8  tx_rate_limits_normal_5[NUMBER_OF_RATE_GROUPS];
-	s8  tx_rate_limits_degraded_5[NUMBER_OF_RATE_GROUPS];
-
-	s8  tx_channel_limits_ofdm_5[NUMBER_OF_CHANNELS_5];
-	s8  tx_pdv_rate_offsets_5[NUMBER_OF_RATE_GROUPS];
-
-	/* FIXME: this is inconsistent with the types for 2.4GHz */
-	s8  tx_ibias_5[NUMBER_OF_RATE_GROUPS];
-	s8  rx_fem_insertion_loss_5[NUMBER_OF_SUB_BANDS_5];
-
-	u8 padding3[2];
-} __attribute__ ((packed));
-
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c	2013-05-03 14:04:10.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_main.c	2013-05-03 12:11:43.000000000 -0400
@@ -30,7 +30,9 @@
 #include <linux/spi/spi.h>
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
 #include <linux/spi/wl12xx.h>
+#include <linux/inetdevice.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
@@ -45,10 +47,314 @@
 #include "wl1271_cmd.h"
 #include "wl1271_boot.h"
 
+static struct conf_drv_settings default_conf = {
+	.sg = {
+		.per_threshold               = 7500,
+		.max_scan_compensation_time  = 120000,
+		.nfs_sample_interval         = 400,
+		.load_ratio                  = 50,
+		.auto_ps_mode                = 0,
+		.probe_req_compensation      = 170,
+		.scan_window_compensation    = 50,
+		.antenna_config              = 0,
+		.beacon_miss_threshold       = 60,
+		.rate_adaptation_threshold   = CONF_HW_BIT_RATE_12MBPS,
+		.rate_adaptation_snr         = 0
+	},
+	.rx = {
+		.rx_msdu_life_time           = 512000,
+		.packet_detection_threshold  = 0,
+		.ps_poll_timeout             = 15,
+		.upsd_timeout                = 15,
+		.rts_threshold               = 2347,
+		.rx_cca_threshold            = 0xFFEF,
+		.irq_blk_threshold           = 0,
+		.irq_pkt_threshold           = USHORT_MAX,
+		.irq_timeout                 = 5,
+		.queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
+	},
+	.tx = {
+		.tx_energy_detection         = 0,
+		.rc_conf                     = {
+			.enabled_rates       = CONF_TX_RATE_MASK_UNSPECIFIED,
+			.short_retry_limit   = 10,
+			.long_retry_limit    = 10,
+			.aflags              = 0
+		},
+		.ac_conf_count               = 4,
+		.ac_conf                     = {
+			[0] = {
+				.ac          = CONF_TX_AC_BE,
+				.cw_min      = 15,
+				.cw_max      = 63,
+				.aifsn       = 3,
+				.tx_op_limit = 0,
+			},
+			[1] = {
+				.ac          = CONF_TX_AC_BK,
+				.cw_min      = 15,
+				.cw_max      = 63,
+				.aifsn       = 7,
+				.tx_op_limit = 0,
+			},
+			[2] = {
+				.ac          = CONF_TX_AC_VI,
+				.cw_min      = 15,
+				.cw_max      = 63,
+				.aifsn       = CONF_TX_AIFS_PIFS,
+				.tx_op_limit = 3008,
+			},
+			[3] = {
+				.ac          = CONF_TX_AC_VO,
+				.cw_min      = 15,
+				.cw_max      = 63,
+				.aifsn       = CONF_TX_AIFS_PIFS,
+				.tx_op_limit = 1504,
+			},
+		},
+		.tid_conf_count = 7,
+		.tid_conf = {
+			[0] = {
+				.queue_id    = 0,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[1] = {
+				.queue_id    = 1,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[2] = {
+				.queue_id    = 2,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[3] = {
+				.queue_id    = 3,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[4] = {
+				.queue_id    = 4,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[5] = {
+				.queue_id    = 5,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			},
+			[6] = {
+				.queue_id    = 6,
+				.channel_type = CONF_CHANNEL_TYPE_DCF,
+				.tsid        = CONF_TX_AC_BE,
+				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
+				.ack_policy  = CONF_ACK_POLICY_LEGACY,
+				.apsd_conf   = {0, 0},
+			}
+		},
+		.frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
+		.tx_compl_timeout            = 5,
+		.tx_compl_threshold          = 5
+	},
+	.conn = {
+		.wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
+		.listen_interval             = 0,
+		.bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
+		.bcn_filt_ie_count           = 1,
+		.bcn_filt_ie = {
+			[0] = {
+				.ie          = WLAN_EID_CHANNEL_SWITCH,
+				.rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
+			}
+		},
+		.synch_fail_thold            = 5,
+		.bss_lose_timeout            = 100,
+		.beacon_rx_timeout           = 10000,
+		.broadcast_timeout           = 20000,
+		.rx_broadcast_in_ps          = 1,
+		.ps_poll_threshold           = 4,
+		.sig_trigger_count           = 2,
+		.sig_trigger = {
+			[0] = {
+				.threshold   = -75,
+				.pacing      = 500,
+				.metric      = CONF_TRIG_METRIC_RSSI_BEACON,
+				.type        = CONF_TRIG_EVENT_TYPE_EDGE,
+				.direction   = CONF_TRIG_EVENT_DIR_LOW,
+				.hysteresis  = 2,
+				.index       = 0,
+				.enable      = 1
+			},
+			[1] = {
+				.threshold   = -75,
+				.pacing      = 500,
+				.metric      = CONF_TRIG_METRIC_RSSI_BEACON,
+				.type        = CONF_TRIG_EVENT_TYPE_EDGE,
+				.direction   = CONF_TRIG_EVENT_DIR_HIGH,
+				.hysteresis  = 2,
+				.index       = 1,
+				.enable      = 1
+			}
+		},
+		.sig_weights = {
+			.rssi_bcn_avg_weight = 10,
+			.rssi_pkt_avg_weight = 10,
+			.snr_bcn_avg_weight  = 10,
+			.snr_pkt_avg_weight  = 10
+		},
+		.bet_enable                  = CONF_BET_MODE_ENABLE,
+		.bet_max_consecutive         = 10,
+		.psm_entry_retries           = 3
+	},
+	.init = {
+		.sr_err_tbl = {
+			[0] = {
+				.len         = 7,
+				.upper_limit = 0x03,
+				.values      = {
+					0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
+					0x00 }
+			},
+			[1] = {
+				.len         = 7,
+				.upper_limit = 0x03,
+				.values      = {
+					0x18, 0x10, 0x05, 0xf6, 0xf0, 0xe8,
+					0x00 }
+			},
+			[2] = {
+				.len         = 7,
+				.upper_limit = 0x03,
+				.values      = {
+					0x18, 0x10, 0x05, 0xfb, 0xf0, 0xe8,
+					0x00 }
+			}
+		},
+		.sr_enable                   = 1,
+		.genparam                    = {
+			.ref_clk             = CONF_REF_CLK_38_4_E,
+			.settling_time       = 5,
+			.clk_valid_on_wakeup = 0,
+			.dc2dcmode           = 0,
+			.single_dual_band    = CONF_SINGLE_BAND,
+			.tx_bip_fem_autodetect = 0,
+			.tx_bip_fem_manufacturer = 1,
+			.settings = 1,
+		},
+		.radioparam = {
+			.rx_trace_loss       = 10,
+			.tx_trace_loss       = 10,
+			.rx_rssi_and_proc_compens = {
+				0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8,
+				0xfc, 0x00, 0x08, 0x10, 0xf0, 0xf8,
+				0x00, 0x0a, 0x14 },
+			.rx_trace_loss_5     = { 0, 0, 0, 0, 0, 0, 0 },
+			.tx_trace_loss_5     = { 0, 0, 0, 0, 0, 0, 0 },
+			.rx_rssi_and_proc_compens_5 = {
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00 },
+			.tx_ref_pd_voltage   = 0x24e,
+			.tx_ref_power        = 0x78,
+			.tx_offset_db        = 0x0,
+			.tx_rate_limits_normal = {
+				0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 },
+			.tx_rate_limits_degraded = {
+				0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 },
+			.tx_channel_limits_11b = {
+				0x22, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50, 0x50, 0x22, 0x50,
+				0x22, 0x50 },
+			.tx_channel_limits_ofdm = {
+				0x20, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50, 0x50, 0x20, 0x50,
+				0x20, 0x50 },
+			.tx_pdv_rate_offsets = {
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+			.tx_ibias            = {
+				0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 },
+			.rx_fem_insertion_loss = 0x14,
+			.tx_ref_pd_voltage_5 = {
+				0x0190, 0x01a4, 0x01c3, 0x01d8,
+				0x020a, 0x021c },
+			.tx_ref_power_5      = {
+				0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
+			.tx_offset_db_5      = {
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+			.tx_rate_limits_normal_5 = {
+				0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
+			.tx_rate_limits_degraded_5 = {
+				0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },
+			.tx_channel_limits_ofdm_5 = {
+				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
+				0x50, 0x50, 0x50 },
+			.tx_pdv_rate_offsets_5 = {
+				0x01, 0x02, 0x02, 0x02, 0x02, 0x00 },
+			.tx_ibias_5          = {
+				0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
+			.rx_fem_insertion_loss_5 = {
+				0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }
+		}
+	}
+};
+
+static LIST_HEAD(wl_list);
+
+static void wl1271_conf_init(struct wl1271 *wl)
+{
+
+	/*
+	 * This function applies the default configuration to the driver. This
+	 * function is invoked upon driver load (spi probe.)
+	 *
+	 * The configuration is stored in a run-time structure in order to
+	 * facilitate for run-time adjustment of any of the parameters. Making
+	 * changes to the configuration structure will apply the new values on
+	 * the next interface up (wl1271_op_start.)
+	 */
+
+	/* apply driver default configuration */
+	memcpy(&wl->conf, &default_conf, sizeof(default_conf));
+
+	if (wl1271_11a_enabled())
+		wl->conf.init.genparam.single_dual_band = CONF_DUAL_BAND;
+}
+
+
 static int wl1271_plt_init(struct wl1271 *wl)
 {
 	int ret;
 
+	ret = wl1271_cmd_general_parms(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_radio_parms(wl);
+	if (ret < 0)
+		return ret;
+
 	ret = wl1271_acx_init_mem_config(wl);
 	if (ret < 0)
 		return ret;
@@ -75,20 +381,14 @@ static void wl1271_power_on(struct wl127
 	wl->set_power(true);
 }
 
-static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status)
+static void wl1271_fw_status(struct wl1271 *wl,
+			     struct wl1271_fw_status *status)
 {
 	u32 total = 0;
 	int i;
 
-	/*
-	 * FIXME: Reading the FW status directly from the registers seems to
-	 * be the right thing to do, but it doesn't work.  And in the
-	 * reference driver, there is a workaround called
-	 * USE_SDIO_24M_WORKAROUND, which reads the status from memory
-	 * instead, so we do the same here.
-	 */
-
-	wl1271_spi_mem_read(wl, STATUS_MEM_ADDRESS, status, sizeof(*status));
+	wl1271_spi_read(wl, FW_STATUS_ADDR, status,
+			sizeof(*status), false);
 
 	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
 		     "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -99,25 +399,28 @@ static void wl1271_fw_status(struct wl12
 
 	/* update number of available TX blocks */
 	for (i = 0; i < NUM_TX_QUEUES; i++) {
-		u32 cnt = status->tx_released_blks[i] - wl->tx_blocks_freed[i];
-		wl->tx_blocks_freed[i] = status->tx_released_blks[i];
+		u32 cnt = le32_to_cpu(status->tx_released_blks[i]) -
+			wl->tx_blocks_freed[i];
+
+		wl->tx_blocks_freed[i] =
+			le32_to_cpu(status->tx_released_blks[i]);
 		wl->tx_blocks_available += cnt;
 		total += cnt;
 	}
 
 	/* if more blocks are available now, schedule some tx work */
 	if (total && !skb_queue_empty(&wl->tx_queue))
-		schedule_work(&wl->tx_work);
+		ieee80211_queue_work(wl->hw, &wl->tx_work);
 
 	/* update the host-chipset time offset */
-	wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime;
+	wl->time_offset = jiffies_to_usecs(jiffies) -
+		le32_to_cpu(status->fw_localtime);
 }
 
-#define WL1271_IRQ_MAX_LOOPS 10
 static void wl1271_irq_work(struct work_struct *work)
 {
-	u32 intr, ctr = WL1271_IRQ_MAX_LOOPS;
 	int ret;
+	u32 intr;
 	struct wl1271 *wl =
 		container_of(work, struct wl1271, irq_work);
 
@@ -132,9 +435,10 @@ static void wl1271_irq_work(struct work_
 	if (ret < 0)
 		goto out;
 
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
 
-	intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+	wl1271_fw_status(wl, wl->fw_status);
+	intr = le32_to_cpu(wl->fw_status->intr);
 	if (!intr) {
 		wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
 		goto out_sleep;
@@ -142,46 +446,39 @@ static void wl1271_irq_work(struct work_
 
 	intr &= WL1271_INTR_MASK;
 
-	do {
-		wl1271_fw_status(wl, wl->fw_status);
-
-
-		if (intr & (WL1271_ACX_INTR_EVENT_A |
-			    WL1271_ACX_INTR_EVENT_B)) {
-			wl1271_debug(DEBUG_IRQ,
-				     "WL1271_ACX_INTR_EVENT (0x%x)", intr);
-			if (intr & WL1271_ACX_INTR_EVENT_A)
-				wl1271_event_handle(wl, 0);
-			else
-				wl1271_event_handle(wl, 1);
-		}
+	if (intr & WL1271_ACX_INTR_EVENT_A) {
+		bool do_ack = (intr & WL1271_ACX_INTR_EVENT_B) ? false : true;
+		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
+		wl1271_event_handle(wl, 0, do_ack);
+	}
 
-		if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
-			wl1271_debug(DEBUG_IRQ,
-				     "WL1271_ACX_INTR_INIT_COMPLETE");
+	if (intr & WL1271_ACX_INTR_EVENT_B) {
+		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
+		wl1271_event_handle(wl, 1, true);
+	}
 
-		if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
-			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
+	if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
+		wl1271_debug(DEBUG_IRQ,
+			     "WL1271_ACX_INTR_INIT_COMPLETE");
 
-		if (intr & WL1271_ACX_INTR_DATA) {
-			u8 tx_res_cnt = wl->fw_status->tx_results_counter -
-				wl->tx_results_count;
+	if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
+		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
 
-			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
+	if (intr & WL1271_ACX_INTR_DATA) {
+		u8 tx_res_cnt = wl->fw_status->tx_results_counter -
+			wl->tx_results_count;
 
-			/* check for tx results */
-			if (tx_res_cnt)
-				wl1271_tx_complete(wl, tx_res_cnt);
+		wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
 
-			wl1271_rx(wl, wl->fw_status);
-		}
+		/* check for tx results */
+		if (tx_res_cnt)
+			wl1271_tx_complete(wl, tx_res_cnt);
 
-		intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
-		intr &= WL1271_INTR_MASK;
-	} while (intr && --ctr);
+		wl1271_rx(wl, wl->fw_status);
+	}
 
 out_sleep:
-	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+	wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,
 			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
 	wl1271_ps_elp_sleep(wl);
 
@@ -205,7 +502,7 @@ static irqreturn_t wl1271_irq(int irq, v
 		wl->elp_compl = NULL;
 	}
 
-	schedule_work(&wl->irq_work);
+	ieee80211_queue_work(wl->hw, &wl->irq_work);
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
 	return IRQ_HANDLED;
@@ -231,7 +528,7 @@ static int wl1271_fetch_firmware(struct
 	}
 
 	wl->fw_len = fw->size;
-	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+	wl->fw = vmalloc(wl->fw_len);
 
 	if (!wl->fw) {
 		wl1271_error("could not allocate memory for the firmware");
@@ -292,7 +589,7 @@ static void wl1271_fw_wakeup(struct wl12
 	u32 elp_reg;
 
 	elp_reg = ELPCTRL_WAKE_UP;
-	wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
 }
 
 static int wl1271_setup(struct wl1271 *wl)
@@ -314,6 +611,7 @@ static int wl1271_setup(struct wl1271 *w
 
 static int wl1271_chip_wakeup(struct wl1271 *wl)
 {
+	struct wl1271_partition_set partition;
 	int ret = 0;
 
 	wl1271_power_on(wl);
@@ -323,11 +621,10 @@ static int wl1271_chip_wakeup(struct wl1
 
 	/* We don't need a real memory partition here, because we only want
 	 * to use the registers at this point. */
-	wl1271_set_partition(wl,
-			     0x00000000,
-			     0x00000000,
-			     REGISTERS_BASE,
-			     REGISTERS_DOWN_SIZE);
+	memset(&partition, 0, sizeof(partition));
+	partition.reg.start = REGISTERS_BASE;
+	partition.reg.size = REGISTERS_DOWN_SIZE;
+	wl1271_set_partition(wl, &partition);
 
 	/* ELP module wake up */
 	wl1271_fw_wakeup(wl);
@@ -335,7 +632,7 @@ static int wl1271_chip_wakeup(struct wl1
 	/* whal_FwCtrl_BootSm() */
 
 	/* 0. read chip id from CHIP_ID */
-	wl->chip.id = wl1271_reg_read32(wl, CHIP_ID_B);
+	wl->chip.id = wl1271_spi_read32(wl, CHIP_ID_B);
 
 	/* 1. check if chip id is valid */
 
@@ -346,7 +643,7 @@ static int wl1271_chip_wakeup(struct wl1
 
 		ret = wl1271_setup(wl);
 		if (ret < 0)
-			goto out;
+			goto out_power_off;
 		break;
 	case CHIP_ID_1271_PG20:
 		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
@@ -354,56 +651,34 @@ static int wl1271_chip_wakeup(struct wl1
 
 		ret = wl1271_setup(wl);
 		if (ret < 0)
-			goto out;
+			goto out_power_off;
 		break;
 	default:
 		wl1271_error("unsupported chip id: 0x%x", wl->chip.id);
 		ret = -ENODEV;
-		goto out;
+		goto out_power_off;
 	}
 
 	if (wl->fw == NULL) {
 		ret = wl1271_fetch_firmware(wl);
 		if (ret < 0)
-			goto out;
+			goto out_power_off;
 	}
 
 	/* No NVS from netlink, try to get it from the filesystem */
 	if (wl->nvs == NULL) {
 		ret = wl1271_fetch_nvs(wl);
 		if (ret < 0)
-			goto out;
+			goto out_power_off;
 	}
 
-out:
-	return ret;
-}
-
-static void wl1271_filter_work(struct work_struct *work)
-{
-	struct wl1271 *wl =
-		container_of(work, struct wl1271, filter_work);
-	int ret;
-
-	mutex_lock(&wl->mutex);
-
-	if (wl->state == WL1271_STATE_OFF)
-		goto out;
-
-	ret = wl1271_ps_elp_wakeup(wl, false);
-	if (ret < 0)
-		goto out;
-
-	/* FIXME: replace the magic numbers with proper definitions */
-	ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
-	if (ret < 0)
-		goto out_sleep;
+	goto out;
 
-out_sleep:
-	wl1271_ps_elp_sleep(wl);
+out_power_off:
+	wl1271_power_off(wl);
 
 out:
-	mutex_unlock(&wl->mutex);
+	return ret;
 }
 
 int wl1271_plt_start(struct wl1271 *wl)
@@ -429,13 +704,26 @@ int wl1271_plt_start(struct wl1271 *wl)
 
 	ret = wl1271_boot(wl);
 	if (ret < 0)
-		goto out;
+		goto out_power_off;
 
 	wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
 
 	ret = wl1271_plt_init(wl);
 	if (ret < 0)
-		goto out;
+		goto out_irq_disable;
+
+	/* Make sure power saving is disabled */
+	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
+	if (ret < 0)
+		goto out_irq_disable;
+
+	goto out;
+
+out_irq_disable:
+	wl1271_disable_interrupts(wl);
+
+out_power_off:
+	wl1271_power_off(wl);
 
 out:
 	mutex_unlock(&wl->mutex);
@@ -462,6 +750,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
 	wl1271_power_off(wl);
 
 	wl->state = WL1271_STATE_OFF;
+	wl->rx_counter = 0;
 
 out:
 	mutex_unlock(&wl->mutex);
@@ -481,7 +770,7 @@ static int wl1271_op_tx(struct ieee80211
 	 * before that, the tx_work will not be initialized!
 	 */
 
-	schedule_work(&wl->tx_work);
+	ieee80211_queue_work(wl->hw, &wl->tx_work);
 
 	/*
 	 * The workqueue is slow to process the tx_queue and we need stop
@@ -501,6 +790,93 @@ static int wl1271_op_tx(struct ieee80211
 	return NETDEV_TX_OK;
 }
 
+static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
+			     void *arg)
+{
+	struct net_device *dev;
+	struct wireless_dev *wdev;
+	struct wiphy *wiphy;
+	struct ieee80211_hw *hw;
+	struct wl1271 *wl;
+	struct wl1271 *wl_temp;
+	struct in_device *idev;
+	struct in_ifaddr *ifa = arg;
+	int ret = 0;
+
+	/* FIXME: this ugly function should probably be implemented in the
+	 * mac80211, and here should only be a simple callback handling actual
+	 * setting of the filters. Now we need to dig up references to
+	 * various structures to gain access to what we need.
+	 * Also, because of this, there is no "initial" setting of the filter
+	 * in "op_start", because we don't want to dig up struct net_device
+	 * there - the filter will be set upon first change of the interface
+	 * IP address. */
+
+	dev = ifa->ifa_dev->dev;
+
+	wdev = dev->ieee80211_ptr;
+	if (wdev == NULL)
+		return NOTIFY_DONE;
+
+	wiphy = wdev->wiphy;
+	if (wiphy == NULL)
+		return NOTIFY_DONE;
+
+	hw = wiphy_priv(wiphy);
+	if (hw == NULL)
+		return NOTIFY_DONE;
+
+	/* Check that the interface is one supported by this driver. */
+	wl_temp = hw->priv;
+	list_for_each_entry(wl, &wl_list, list) {
+		if (wl == wl_temp)
+			break;
+	}
+	if (wl == NULL)
+		return NOTIFY_DONE;
+
+	/* Get the interface IP address for the device. "ifa" will become
+	   NULL if:
+	     - there is no IPV4 protocol address configured
+	     - there are multiple (virtual) IPV4 addresses configured
+	   When "ifa" is NULL, filtering will be disabled.
+	*/
+	ifa = NULL;
+	idev = dev->ip_ptr;
+	if (idev)
+		ifa = idev->ifa_list;
+
+	if (ifa && ifa->ifa_next)
+		ifa = NULL;
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->state == WL1271_STATE_OFF)
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+	if (ifa)
+		ret = wl1271_acx_arp_ip_filter(wl, true,
+					       (u8 *)&ifa->ifa_address,
+					       ACX_IPV4_VERSION);
+	else
+		ret = wl1271_acx_arp_ip_filter(wl, false, NULL,
+					       ACX_IPV4_VERSION);
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block wl1271_dev_notifier = {
+	.notifier_call = wl1271_dev_notify,
+};
+
+
 static int wl1271_op_start(struct ieee80211_hw *hw)
 {
 	struct wl1271 *wl = hw->priv;
@@ -523,22 +899,32 @@ static int wl1271_op_start(struct ieee80
 
 	ret = wl1271_boot(wl);
 	if (ret < 0)
-		goto out;
+		goto out_power_off;
 
 	ret = wl1271_hw_init(wl);
 	if (ret < 0)
-		goto out;
+		goto out_irq_disable;
 
 	wl->state = WL1271_STATE_ON;
 
 	wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
 
-out:
-	if (ret < 0)
-		wl1271_power_off(wl);
+	goto out;
 
+out_irq_disable:
+	wl1271_disable_interrupts(wl);
+
+out_power_off:
+	wl1271_power_off(wl);
+
+out:
 	mutex_unlock(&wl->mutex);
 
+	if (!ret) {
+		list_add(&wl->list, &wl_list);
+		register_inetaddr_notifier(&wl1271_dev_notifier);
+	}
+
 	return ret;
 }
 
@@ -551,6 +937,9 @@ static void wl1271_op_stop(struct ieee80
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
 
+	unregister_inetaddr_notifier(&wl1271_dev_notifier);
+	list_del(&wl->list);
+
 	mutex_lock(&wl->mutex);
 
 	WARN_ON(wl->state != WL1271_STATE_ON);
@@ -570,7 +959,6 @@ static void wl1271_op_stop(struct ieee80
 
 	cancel_work_sync(&wl->irq_work);
 	cancel_work_sync(&wl->tx_work);
-	cancel_work_sync(&wl->filter_work);
 
 	mutex_lock(&wl->mutex);
 
@@ -581,19 +969,25 @@ static void wl1271_op_stop(struct ieee80
 	memset(wl->bssid, 0, ETH_ALEN);
 	memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
 	wl->ssid_len = 0;
-	wl->listen_int = 1;
 	wl->bss_type = MAX_BSS_TYPE;
+	wl->band = IEEE80211_BAND_2GHZ;
 
 	wl->rx_counter = 0;
 	wl->elp = false;
 	wl->psm = 0;
+	wl->psm_entry_retry = 0;
 	wl->tx_queue_stopped = false;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
 	wl->tx_blocks_available = 0;
 	wl->tx_results_count = 0;
 	wl->tx_packets_count = 0;
+	wl->tx_security_last_seq = 0;
+	wl->tx_security_seq_16 = 0;
+	wl->tx_security_seq_32 = 0;
 	wl->time_offset = 0;
 	wl->session_counter = 0;
+	wl->joined = false;
+
 	for (i = 0; i < NUM_TX_QUEUES; i++)
 		wl->tx_blocks_freed[i] = 0;
 
@@ -611,6 +1005,12 @@ static int wl1271_op_add_interface(struc
 		     conf->type, conf->mac_addr);
 
 	mutex_lock(&wl->mutex);
+	if (wl->vif) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl->vif = conf->vif;
 
 	switch (conf->type) {
 	case NL80211_IFTYPE_STATION:
@@ -634,7 +1034,12 @@ out:
 static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
 					 struct ieee80211_if_init_conf *conf)
 {
+	struct wl1271 *wl = hw->priv;
+
+	mutex_lock(&wl->mutex);
 	wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
+	wl->vif = NULL;
+	mutex_unlock(&wl->mutex);
 }
 
 #if 0
@@ -657,23 +1062,24 @@ static int wl1271_op_config_interface(st
 	if (ret < 0)
 		goto out;
 
-	memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+	if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) {
+		wl1271_debug(DEBUG_MAC80211, "bssid changed");
 
-	ret = wl1271_cmd_build_null_data(wl);
-	if (ret < 0)
-		goto out_sleep;
+		memcpy(wl->bssid, conf->bssid, ETH_ALEN);
 
-	wl->ssid_len = conf->ssid_len;
-	if (wl->ssid_len)
-		memcpy(wl->ssid, conf->ssid, wl->ssid_len);
+		ret = wl1271_cmd_join(wl);
+		if (ret < 0)
+			goto out_sleep;
 
-	if (wl->bss_type != BSS_TYPE_IBSS) {
-		/* FIXME: replace the magic numbers with proper definitions */
-		ret = wl1271_cmd_join(wl, wl->bss_type, 5, 100, 1);
+		ret = wl1271_cmd_build_null_data(wl);
 		if (ret < 0)
 			goto out_sleep;
 	}
 
+	wl->ssid_len = conf->ssid_len;
+	if (wl->ssid_len)
+		memcpy(wl->ssid, conf->ssid, wl->ssid_len);
+
 	if (conf->changed & IEEE80211_IFCC_BEACON) {
 		beacon = ieee80211_beacon_get(hw, vif);
 		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
@@ -691,12 +1097,6 @@ static int wl1271_op_config_interface(st
 
 		if (ret < 0)
 			goto out_sleep;
-
-		/* FIXME: replace the magic numbers with proper definitions */
-		ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
-
-		if (ret < 0)
-			goto out_sleep;
 	}
 
 out_sleep:
@@ -724,26 +1124,22 @@ static int wl1271_op_config(struct ieee8
 
 	mutex_lock(&wl->mutex);
 
+	wl->band = conf->channel->band;
+
 	ret = wl1271_ps_elp_wakeup(wl, false);
 	if (ret < 0)
 		goto out;
 
 	if (channel != wl->channel) {
-		u8 old_channel = wl->channel;
+		/*
+		 * We assume that the stack will configure the right channel
+		 * before associating, so we don't need to send a join
+		 * command here.  We will join the right channel when the
+		 * BSSID changes
+		 */
 		wl->channel = channel;
-
-		/* FIXME: use beacon interval provided by mac80211 */
-		ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
-		if (ret < 0) {
-			wl->channel = old_channel;
-			goto out_sleep;
-		}
 	}
 
-	ret = wl1271_cmd_build_null_data(wl);
-	if (ret < 0)
-		goto out_sleep;
-
 	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
 		wl1271_info("psm enabled");
 
@@ -768,7 +1164,7 @@ static int wl1271_op_config(struct ieee8
 	if (conf->power_level != wl->power_level) {
 		ret = wl1271_acx_tx_power(wl, conf->power_level);
 		if (ret < 0)
-			goto out;
+			goto out_sleep;
 
 		wl->power_level = conf->power_level;
 	}
@@ -782,6 +1178,45 @@ out:
 	return ret;
 }
 
+struct wl1271_filter_params {
+	bool enabled;
+	int mc_list_length;
+	u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
+};
+
+static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
+				       struct dev_addr_list *mc_list)
+{
+	struct wl1271_filter_params *fp;
+	int i;
+
+	fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
+	if (!fp) {
+		wl1271_error("Out of memory setting filters.");
+		return 0;
+	}
+
+	/* update multicast filtering parameters */
+	fp->enabled = true;
+	if (mc_count > ACX_MC_ADDRESS_GROUP_MAX) {
+		mc_count = 0;
+		fp->enabled = false;
+	}
+
+	fp->mc_list_length = 0;
+	for (i = 0; i < mc_count; i++) {
+		if (mc_list->da_addrlen == ETH_ALEN) {
+			memcpy(fp->mc_list[fp->mc_list_length],
+			       mc_list->da_addr, ETH_ALEN);
+			fp->mc_list_length++;
+		} else
+			wl1271_warning("Unknown mc address length.");
+		mc_list = mc_list->next;
+	}
+
+	return (u64)(unsigned long)fp;
+}
+
 #define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
 				  FIF_ALLMULTI | \
 				  FIF_FCSFAIL | \
@@ -791,28 +1226,53 @@ out:
 
 static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
 				       unsigned int changed,
-				       unsigned int *total,u64 multicast)
+				       unsigned int *total, u64 multicast)
 {
+	struct wl1271_filter_params *fp = (void *)(unsigned long)multicast;
 	struct wl1271 *wl = hw->priv;
+	int ret;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter");
 
+	mutex_lock(&wl->mutex);
+
+	if (wl->state == WL1271_STATE_OFF)
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
 	*total &= WL1271_SUPPORTED_FILTERS;
 	changed &= WL1271_SUPPORTED_FILTERS;
 
+	if (*total & FIF_ALLMULTI)
+		ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0);
+	else if (fp)
+		ret = wl1271_acx_group_address_tbl(wl, fp->enabled,
+						   fp->mc_list,
+						   fp->mc_list_length);
+	if (ret < 0)
+		goto out_sleep;
+
+	kfree(fp);
+
+	/* FIXME: We still need to set our filters properly */
+
+	/* determine, whether supported filter values have changed */
 	if (changed == 0)
-		return;
+		goto out_sleep;
 
-	/* FIXME: wl->rx_config and wl->rx_filter are not protected */
-	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
-	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
+	/* apply configured filters */
+	ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
+	if (ret < 0)
+		goto out_sleep;
 
-	/*
-	 * FIXME: workqueues need to be properly cancelled on stop(), for
-	 * now let's just disable changing the filter settings. They will
-	 * be updated any on config().
-	 */
-	/* schedule_work(&wl->filter_work); */
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
 }
 
 static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -823,6 +1283,8 @@ static int wl1271_op_set_key(struct ieee
 	struct wl1271 *wl = hw->priv;
 	const u8 *addr;
 	int ret;
+	u32 tx_seq_32 = 0;
+	u16 tx_seq_16 = 0;
 	u8 key_type;
 
 	static const u8 bcast_addr[ETH_ALEN] =
@@ -861,11 +1323,15 @@ static int wl1271_op_set_key(struct ieee
 		key_type = KEY_TKIP;
 
 		key_conf->hw_key_idx = key_conf->keyidx;
+		tx_seq_32 = wl->tx_security_seq_32;
+		tx_seq_16 = wl->tx_security_seq_16;
 		break;
 	case ALG_CCMP:
 		key_type = KEY_AES;
 
 		key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+		tx_seq_32 = wl->tx_security_seq_32;
+		tx_seq_16 = wl->tx_security_seq_16;
 		break;
 	default:
 		wl1271_error("Unknown key algo 0x%x", key_conf->alg);
@@ -879,7 +1345,7 @@ static int wl1271_op_set_key(struct ieee
 		ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE,
 					 key_conf->keyidx, key_type,
 					 key_conf->keylen, key_conf->key,
-					 addr);
+					 addr, tx_seq_32, tx_seq_16);
 		if (ret < 0) {
 			wl1271_error("Could not add or replace key");
 			goto out_sleep;
@@ -890,7 +1356,7 @@ static int wl1271_op_set_key(struct ieee
 		ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
 					 key_conf->keyidx, key_type,
 					 key_conf->keylen, key_conf->key,
-					 addr);
+					 addr, 0, 0);
 		if (ret < 0) {
 			wl1271_error("Could not remove key");
 			goto out_sleep;
@@ -921,13 +1387,13 @@ static int wl1271_op_hw_scan(struct ieee
 	struct wl1271 *wl = hw->priv;
 	int ret;
 	u8 *ssid = NULL;
-	size_t ssid_len = 0;
+	size_t len = 0;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");
 
 	if (req->n_ssids) {
 		ssid = req->ssids[0].ssid;
-		ssid_len = req->ssids[0].ssid_len;
+		len = req->ssids[0].ssid_len;
 	}
 
 	mutex_lock(&wl->mutex);
@@ -936,7 +1402,12 @@ static int wl1271_op_hw_scan(struct ieee
 	if (ret < 0)
 		goto out;
 
-	ret = wl1271_cmd_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+	if (wl1271_11a_enabled())
+		ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0,
+				      WL1271_SCAN_BAND_DUAL, 3);
+	else
+		ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0,
+				      WL1271_SCAN_BAND_2_4_GHZ, 3);
 
 	wl1271_ps_elp_sleep(wl);
 
@@ -969,6 +1440,22 @@ out:
 	return ret;
 }
 
+static u32 wl1271_enabled_rates_get(struct wl1271 *wl, u64 basic_rate_set)
+{
+	struct ieee80211_supported_band *band;
+	u32 enabled_rates = 0;
+	int bit;
+
+	band = wl->hw->wiphy->bands[wl->band];
+	for (bit = 0; bit < band->n_bitrates; bit++) {
+		if (basic_rate_set & 0x1)
+			enabled_rates |= band->bitrates[bit].hw_value;
+		basic_rate_set >>= 1;
+	}
+
+	return enabled_rates;
+}
+
 static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
@@ -990,6 +1477,12 @@ static void wl1271_op_bss_info_changed(s
 		if (bss_conf->assoc) {
 			wl->aid = bss_conf->aid;
 
+			/*
+			 * with wl1271, we don't need to update the
+			 * beacon_int and dtim_period, because the firmware
+			 * updates it by itself when the first beacon is
+			 * received after a join.
+			 */
 			ret = wl1271_cmd_build_ps_poll(wl, wl->aid);
 			if (ret < 0)
 				goto out_sleep;
@@ -1005,8 +1498,14 @@ static void wl1271_op_bss_info_changed(s
 				if (ret < 0)
 					goto out_sleep;
 			}
+		} else {
+			/* use defaults when not associated */
+			wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
+			wl->aid = 0;
 		}
+
 	}
+
 	if (changed & BSS_CHANGED_ERP_SLOT) {
 		if (bss_conf->use_short_slot)
 			ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT);
@@ -1036,6 +1535,17 @@ static void wl1271_op_bss_info_changed(s
 		}
 	}
 
+	if (changed & BSS_CHANGED_BASIC_RATES) {
+		wl->basic_rate_set = wl1271_enabled_rates_get(
+			wl, bss_conf->basic_rates);
+
+		ret = wl1271_acx_rate_policies(wl, wl->basic_rate_set);
+		if (ret < 0) {
+			wl1271_warning("Set rate policies failed %d", ret);
+			goto out_sleep;
+		}
+	}
+
 out_sleep:
 	wl1271_ps_elp_sleep(wl);
 
@@ -1047,44 +1557,44 @@ out:
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_rate wl1271_rates[] = {
 	{ .bitrate = 10,
-	  .hw_value = 0x1,
-	  .hw_value_short = 0x1, },
+	  .hw_value = CONF_HW_BIT_RATE_1MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
 	{ .bitrate = 20,
-	  .hw_value = 0x2,
-	  .hw_value_short = 0x2,
+	  .hw_value = CONF_HW_BIT_RATE_2MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
 	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 	{ .bitrate = 55,
-	  .hw_value = 0x4,
-	  .hw_value_short = 0x4,
+	  .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
 	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 	{ .bitrate = 110,
-	  .hw_value = 0x20,
-	  .hw_value_short = 0x20,
+	  .hw_value = CONF_HW_BIT_RATE_11MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
 	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 	{ .bitrate = 60,
-	  .hw_value = 0x8,
-	  .hw_value_short = 0x8, },
+	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
 	{ .bitrate = 90,
-	  .hw_value = 0x10,
-	  .hw_value_short = 0x10, },
+	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
 	{ .bitrate = 120,
-	  .hw_value = 0x40,
-	  .hw_value_short = 0x40, },
+	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
 	{ .bitrate = 180,
-	  .hw_value = 0x80,
-	  .hw_value_short = 0x80, },
+	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
 	{ .bitrate = 240,
-	  .hw_value = 0x200,
-	  .hw_value_short = 0x200, },
+	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
 	{ .bitrate = 360,
-	 .hw_value = 0x400,
-	 .hw_value_short = 0x400, },
+	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
+	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
 	{ .bitrate = 480,
-	  .hw_value = 0x800,
-	  .hw_value_short = 0x800, },
+	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
 	{ .bitrate = 540,
-	  .hw_value = 0x1000,
-	  .hw_value_short = 0x1000, },
+	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
 };
 
 /* can't be const, mac80211 writes to this */
@@ -1112,6 +1622,88 @@ static struct ieee80211_supported_band w
 	.n_bitrates = ARRAY_SIZE(wl1271_rates),
 };
 
+/* 5 GHz data rates for WL1273 */
+static struct ieee80211_rate wl1271_rates_5ghz[] = {
+	{ .bitrate = 60,
+	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
+	{ .bitrate = 90,
+	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
+	{ .bitrate = 120,
+	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
+	{ .bitrate = 180,
+	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
+	{ .bitrate = 240,
+	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
+	{ .bitrate = 360,
+	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
+	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
+	{ .bitrate = 480,
+	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
+	{ .bitrate = 540,
+	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
+	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
+};
+
+/* 5 GHz band channels for WL1273 */
+static struct ieee80211_channel wl1271_channels_5ghz[] = {
+	{ .hw_value = 183, .center_freq = 4915},
+	{ .hw_value = 184, .center_freq = 4920},
+	{ .hw_value = 185, .center_freq = 4925},
+	{ .hw_value = 187, .center_freq = 4935},
+	{ .hw_value = 188, .center_freq = 4940},
+	{ .hw_value = 189, .center_freq = 4945},
+	{ .hw_value = 192, .center_freq = 4960},
+	{ .hw_value = 196, .center_freq = 4980},
+	{ .hw_value = 7, .center_freq = 5035},
+	{ .hw_value = 8, .center_freq = 5040},
+	{ .hw_value = 9, .center_freq = 5045},
+	{ .hw_value = 11, .center_freq = 5055},
+	{ .hw_value = 12, .center_freq = 5060},
+	{ .hw_value = 16, .center_freq = 5080},
+	{ .hw_value = 34, .center_freq = 5170},
+	{ .hw_value = 36, .center_freq = 5180},
+	{ .hw_value = 38, .center_freq = 5190},
+	{ .hw_value = 40, .center_freq = 5200},
+	{ .hw_value = 42, .center_freq = 5210},
+	{ .hw_value = 44, .center_freq = 5220},
+	{ .hw_value = 46, .center_freq = 5230},
+	{ .hw_value = 48, .center_freq = 5240},
+	{ .hw_value = 52, .center_freq = 5260},
+	{ .hw_value = 56, .center_freq = 5280},
+	{ .hw_value = 60, .center_freq = 5300},
+	{ .hw_value = 64, .center_freq = 5320},
+	{ .hw_value = 100, .center_freq = 5500},
+	{ .hw_value = 104, .center_freq = 5520},
+	{ .hw_value = 108, .center_freq = 5540},
+	{ .hw_value = 112, .center_freq = 5560},
+	{ .hw_value = 116, .center_freq = 5580},
+	{ .hw_value = 120, .center_freq = 5600},
+	{ .hw_value = 124, .center_freq = 5620},
+	{ .hw_value = 128, .center_freq = 5640},
+	{ .hw_value = 132, .center_freq = 5660},
+	{ .hw_value = 136, .center_freq = 5680},
+	{ .hw_value = 140, .center_freq = 5700},
+	{ .hw_value = 149, .center_freq = 5745},
+	{ .hw_value = 153, .center_freq = 5765},
+	{ .hw_value = 157, .center_freq = 5785},
+	{ .hw_value = 161, .center_freq = 5805},
+	{ .hw_value = 165, .center_freq = 5825},
+};
+
+
+static struct ieee80211_supported_band wl1271_band_5ghz = {
+	.channels = wl1271_channels_5ghz,
+	.n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
+	.bitrates = wl1271_rates_5ghz,
+	.n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
+};
+
 static const struct ieee80211_ops wl1271_ops = {
 	.start = wl1271_op_start,
 	.stop = wl1271_op_stop,
@@ -1119,6 +1711,7 @@ static const struct ieee80211_ops wl1271
 	.remove_interface = wl1271_op_remove_interface,
 	.config = wl1271_op_config,
 /* 	.config_interface = wl1271_op_config_interface, */
+	.prepare_multicast = wl1271_op_prepare_multicast,
 	.configure_filter = wl1271_op_configure_filter,
 	.tx = wl1271_op_tx,
 	.set_key = wl1271_op_set_key,
@@ -1151,24 +1744,26 @@ static int wl1271_register_hw(struct wl1
 
 static int wl1271_init_ieee80211(struct wl1271 *wl)
 {
-	/*
-	 * The tx descriptor buffer and the TKIP space.
-	 *
-	 * FIXME: add correct 1271 descriptor size
-	 */
-	wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE;
+	/* The tx descriptor buffer and the TKIP space. */
+	wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
+		sizeof(struct wl1271_tx_hw_descr);
 
 	/* unit us */
 	/* FIXME: find a proper value */
 	wl->hw->channel_change_time = 10000;
 
 	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		IEEE80211_HW_NOISE_DBM;
+		IEEE80211_HW_NOISE_DBM |
+		IEEE80211_HW_BEACON_FILTER |
+		IEEE80211_HW_SUPPORTS_PS;
 
 	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
 
+	if (wl1271_11a_enabled())
+		wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
+
 	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
 
 	return 0;
@@ -1213,29 +1808,33 @@ static int __devinit wl1271_probe(struct
 	wl = hw->priv;
 	memset(wl, 0, sizeof(*wl));
 
+	INIT_LIST_HEAD(&wl->list);
+
 	wl->hw = hw;
 	dev_set_drvdata(&spi->dev, wl);
 	wl->spi = spi;
 
 	skb_queue_head_init(&wl->tx_queue);
 
-	INIT_WORK(&wl->filter_work, wl1271_filter_work);
+	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
 	wl->channel = WL1271_DEFAULT_CHANNEL;
 	wl->scanning = false;
 	wl->default_key = 0;
-	wl->listen_int = 1;
 	wl->rx_counter = 0;
 	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
 	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
 	wl->elp = false;
 	wl->psm = 0;
 	wl->psm_requested = false;
+	wl->psm_entry_retry = 0;
 	wl->tx_queue_stopped = false;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
+	wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
+	wl->band = IEEE80211_BAND_2GHZ;
+	wl->vif = NULL;
+	wl->joined = false;
 
-	/* We use the default power on sleep time until we know which chip
-	 * we're using */
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
 		wl->tx_frames[i] = NULL;
 
 	spin_lock_init(&wl->wl_lock);
@@ -1250,13 +1849,6 @@ static int __devinit wl1271_probe(struct
 	wl->state = WL1271_STATE_OFF;
 	mutex_init(&wl->mutex);
 
-	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
-	if (!wl->rx_descriptor) {
-		wl1271_error("could not allocate memory for rx descriptor");
-		ret = -ENOMEM;
-		goto out_free;
-	}
-
 	/* This is the only SPI value that we need to set here, the rest
 	 * comes from the board-peripherals file */
 	spi->bits_per_word = 32;
@@ -1298,6 +1890,9 @@ static int __devinit wl1271_probe(struct
 	}
 	dev_set_drvdata(&wl1271_device.dev, wl);
 
+	/* Apply default driver configuration. */
+	wl1271_conf_init(wl);
+
 	ret = wl1271_init_ieee80211(wl);
 	if (ret)
 		goto out_platform;
@@ -1319,9 +1914,6 @@ static int __devinit wl1271_probe(struct
 	free_irq(wl->irq, wl);
 
  out_free:
-	kfree(wl->rx_descriptor);
-	wl->rx_descriptor = NULL;
-
 	ieee80211_free_hw(hw);
 
 	return ret;
@@ -1337,14 +1929,11 @@ static int __devexit wl1271_remove(struc
 	platform_device_unregister(&wl1271_device);
 	free_irq(wl->irq, wl);
 	kfree(wl->target_mem_map);
-	kfree(wl->fw);
+	vfree(wl->fw);
 	wl->fw = NULL;
 	kfree(wl->nvs);
 	wl->nvs = NULL;
 
-	kfree(wl->rx_descriptor);
-	wl->rx_descriptor = NULL;
-
 	kfree(wl->fw_status);
 	kfree(wl->tx_res_if);
 
@@ -1391,3 +1980,5 @@ module_exit(wl1271_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
+MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,25 +27,38 @@
 
 #define WL1271_WAKEUP_TIMEOUT 500
 
+void wl1271_elp_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct wl1271 *wl;
+
+	dwork = container_of(work, struct delayed_work, work);
+	wl = container_of(dwork, struct wl1271, elp_work);
+
+	wl1271_debug(DEBUG_PSM, "elp work");
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->elp || !wl->psm)
+		goto out;
+
+	wl1271_debug(DEBUG_PSM, "chip to elp");
+	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+	wl->elp = true;
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+#define ELP_ENTRY_DELAY  5
+
 /* Routines to toggle sleep mode while in ELP */
 void wl1271_ps_elp_sleep(struct wl1271 *wl)
 {
-	/*
-	 * FIXME: due to a problem in the firmware (causing a firmware
-	 * crash), ELP entry is prevented below. Remove the "true" to
-	 * re-enable ELP entry.
-	 */
-	if (true || wl->elp || !wl->psm)
-		return;
-
-	/*
-	 * Go to ELP unless there is work already pending - pending work
-	 * will immediately wakeup the chipset anyway.
-	 */
-	if (!work_pending(&wl->irq_work) && !work_pending(&wl->tx_work)) {
-		wl1271_debug(DEBUG_PSM, "chip to elp");
-		wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
-		wl->elp = true;
+	if (wl->psm) {
+		cancel_delayed_work(&wl->elp_work);
+		ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
+					msecs_to_jiffies(ELP_ENTRY_DELAY));
 	}
 }
 
@@ -73,7 +86,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *
 		wl->elp_compl = &compl;
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
-	wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
 
 	if (!pending) {
 		ret = wait_for_completion_timeout(
@@ -111,6 +124,17 @@ int wl1271_ps_set_mode(struct wl1271 *wl
 	switch (mode) {
 	case STATION_POWER_SAVE_MODE:
 		wl1271_debug(DEBUG_PSM, "entering psm");
+
+		/* enable beacon filtering */
+		ret = wl1271_acx_beacon_filter_opt(wl, true);
+		if (ret < 0)
+			return ret;
+
+		/* enable beacon early termination */
+		ret = wl1271_acx_bet_enable(wl, true);
+		if (ret < 0)
+			return ret;
+
 		ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
 		if (ret < 0)
 			return ret;
@@ -128,6 +152,16 @@ int wl1271_ps_set_mode(struct wl1271 *wl
 		if (ret < 0)
 			return ret;
 
+		/* disable beacon early termination */
+		ret = wl1271_acx_bet_enable(wl, false);
+		if (ret < 0)
+			return ret;
+
+		/* disable beacon filtering */
+		ret = wl1271_acx_beacon_filter_opt(wl, false);
+		if (ret < 0)
+			return ret;
+
 		ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
 		if (ret < 0)
 			return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_ps.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,6 @@
 int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode);
 void wl1271_ps_elp_sleep(struct wl1271 *wl);
 int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
-
+void wl1271_elp_work(struct work_struct *work);
 
 #endif /* __WL1271_PS_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_reg.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,7 +34,7 @@
 #define REGISTERS_WORK_SIZE 0x0000b000
 
 #define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
-#define STATUS_MEM_ADDRESS                  0x40400
+#define FW_STATUS_ADDR                      (0x14FC0 + 0xA000)
 
 /* ELP register commands */
 #define ELPCTRL_WAKE_UP             0x1
@@ -213,7 +213,6 @@
 ==============================================*/
 #define ACX_REG_INTERRUPT_ACK          (REGISTERS_BASE + 0x04F0)
 
-#define RX_DRIVER_DUMMY_WRITE_ADDRESS  (REGISTERS_BASE + 0x0534)
 #define RX_DRIVER_COUNTER_ADDRESS      (REGISTERS_BASE + 0x0538)
 
 /* Device Configuration registers*/
@@ -614,50 +613,6 @@ enum {
 	MAX_RADIO_BANDS = 0xFF
 };
 
-enum {
-	NO_RATE      = 0,
-	RATE_1MBPS   = 0x0A,
-	RATE_2MBPS   = 0x14,
-	RATE_5_5MBPS = 0x37,
-	RATE_6MBPS   = 0x0B,
-	RATE_9MBPS   = 0x0F,
-	RATE_11MBPS  = 0x6E,
-	RATE_12MBPS  = 0x0A,
-	RATE_18MBPS  = 0x0E,
-	RATE_22MBPS  = 0xDC,
-	RATE_24MBPS  = 0x09,
-	RATE_36MBPS  = 0x0D,
-	RATE_48MBPS  = 0x08,
-	RATE_54MBPS  = 0x0C
-};
-
-enum {
-	RATE_INDEX_1MBPS   =  0,
-	RATE_INDEX_2MBPS   =  1,
-	RATE_INDEX_5_5MBPS =  2,
-	RATE_INDEX_6MBPS   =  3,
-	RATE_INDEX_9MBPS   =  4,
-	RATE_INDEX_11MBPS  =  5,
-	RATE_INDEX_12MBPS  =  6,
-	RATE_INDEX_18MBPS  =  7,
-	RATE_INDEX_22MBPS  =  8,
-	RATE_INDEX_24MBPS  =  9,
-	RATE_INDEX_36MBPS  =  10,
-	RATE_INDEX_48MBPS  =  11,
-	RATE_INDEX_54MBPS  =  12,
-	RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
-	MAX_RATE_INDEX,
-	INVALID_RATE_INDEX = MAX_RATE_INDEX,
-	RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
-};
-
-enum {
-	RATE_MASK_1MBPS = 0x1,
-	RATE_MASK_2MBPS = 0x2,
-	RATE_MASK_5_5MBPS = 0x4,
-	RATE_MASK_11MBPS = 0x20,
-};
-
 #define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
 #define OFDM_RATE_BIT        BIT(6)
 #define PBCC_RATE_BIT        BIT(7)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,14 +30,15 @@
 static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
 				  u32 drv_rx_counter)
 {
-	return status->rx_pkt_descs[drv_rx_counter] & RX_MEM_BLOCK_MASK;
+	return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
+		RX_MEM_BLOCK_MASK;
 }
 
 static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
 				 u32 drv_rx_counter)
 {
-	return (status->rx_pkt_descs[drv_rx_counter] & RX_BUF_SIZE_MASK) >>
-		RX_BUF_SIZE_SHIFT_DIV;
+	return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
+		RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
 }
 
 /* The values of this table must match the wl1271_rates[] array */
@@ -70,6 +71,36 @@ static u8 wl1271_rx_rate_to_idx[] = {
 	0                           /* WL1271_RATE_1    */
 };
 
+/* The values of this table must match the wl1271_rates[] array */
+static u8 wl1271_5_ghz_rx_rate_to_idx[] = {
+	/* MCS rates are used only with 11n */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
+
+	7,                          /* WL1271_RATE_54   */
+	6,                          /* WL1271_RATE_48   */
+	5,                          /* WL1271_RATE_36   */
+	4,                          /* WL1271_RATE_24   */
+
+	/* TI-specific rate */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22   */
+
+	3,                          /* WL1271_RATE_18   */
+	2,                          /* WL1271_RATE_12   */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_11   */
+	1,                          /* WL1271_RATE_9    */
+	0,                          /* WL1271_RATE_6    */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_5_5  */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_2    */
+	WL1271_RX_RATE_UNSUPPORTED  /* WL1271_RATE_1    */
+};
+
 static void wl1271_rx_status(struct wl1271 *wl,
 			     struct wl1271_rx_descriptor *desc,
 			     struct ieee80211_rx_status *status,
@@ -77,12 +108,21 @@ static void wl1271_rx_status(struct wl12
 {
 	memset(status, 0, sizeof(struct ieee80211_rx_status));
 
-	if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
+	if ((desc->flags & WL1271_RX_DESC_BAND_MASK) ==
+	    WL1271_RX_DESC_BAND_BG) {
 		status->band = IEEE80211_BAND_2GHZ;
-	else
+		status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
+	} else if ((desc->flags & WL1271_RX_DESC_BAND_MASK) ==
+		 WL1271_RX_DESC_BAND_A) {
+		status->band = IEEE80211_BAND_5GHZ;
+		status->rate_idx = wl1271_5_ghz_rx_rate_to_idx[desc->rate];
+	} else
 		wl1271_warning("unsupported band 0x%x",
 			       desc->flags & WL1271_RX_DESC_BAND_MASK);
 
+	if (unlikely(status->rate_idx == WL1271_RX_RATE_UNSUPPORTED))
+		wl1271_warning("unsupported rate");
+
 	/*
 	 * FIXME: Add mactime handling.  For IBSS (ad-hoc) we need to get the
 	 * timestamp from the beacon (acx_tsf_info).  In BSS mode (infra) we
@@ -91,12 +131,6 @@ static void wl1271_rx_status(struct wl12
 	 */
 	status->signal = desc->rssi;
 
-	/* FIXME: Should this be optimized? */
-	status->qual = (desc->rssi - WL1271_RX_MIN_RSSI) * 100 /
-		(WL1271_RX_MAX_RSSI - WL1271_RX_MIN_RSSI);
-	status->qual = min(status->qual, 100);
-	status->qual = max(status->qual, 0);
-
 	/*
 	 * FIXME: In wl1251, the SNR should be divided by two.  In wl1271 we
 	 * need to divide by two for now, but TI has been discussing about
@@ -109,17 +143,11 @@ static void wl1271_rx_status(struct wl12
 	if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
 		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
 
-		if (likely(!(desc->flags & WL1271_RX_DESC_DECRYPT_FAIL)))
+		if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL)))
 			status->flag |= RX_FLAG_DECRYPTED;
-
-		if (unlikely(desc->flags & WL1271_RX_DESC_MIC_FAIL))
+		if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL))
 			status->flag |= RX_FLAG_MMIC_ERROR;
 	}
-
-	status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
-
-	if (status->rate_idx == WL1271_RX_RATE_UNSUPPORTED)
-		wl1271_warning("unsupported rate");
 }
 
 static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
@@ -131,14 +159,14 @@ static void wl1271_rx_handle_data(struct
 	u8 *buf;
 	u8 beacon = 0;
 
-	skb = dev_alloc_skb(length);
+	skb = __dev_alloc_skb(length, GFP_KERNEL);
 	if (!skb) {
 		wl1271_error("Couldn't allocate RX frame");
 		return;
 	}
 
 	buf = skb_put(skb, length);
-	wl1271_spi_reg_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
+	wl1271_spi_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
 
 	/* the data read starts with the descriptor */
 	desc = (struct wl1271_rx_descriptor *) buf;
@@ -156,7 +184,7 @@ static void wl1271_rx_handle_data(struct
 		     beacon ? "beacon" : "");
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
-	ieee80211_rx(wl->hw, skb);
+	ieee80211_rx_ni(wl->hw, skb);
 }
 
 void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
@@ -176,15 +204,15 @@ void wl1271_rx(struct wl1271 *wl, struct
 			break;
 		}
 
-		wl->rx_mem_pool_addr.addr =
-			(mem_block << 8) + wl_mem_map->packet_memory_pool_start;
+		wl->rx_mem_pool_addr.addr = (mem_block << 8) +
+			le32_to_cpu(wl_mem_map->packet_memory_pool_start);
 		wl->rx_mem_pool_addr.addr_extra =
 			wl->rx_mem_pool_addr.addr + 4;
 
 		/* Choose the block we want to read */
-		wl1271_spi_reg_write(wl, WL1271_SLV_REG_DATA,
-				     &wl->rx_mem_pool_addr,
-				     sizeof(wl->rx_mem_pool_addr), false);
+		wl1271_spi_write(wl, WL1271_SLV_REG_DATA,
+				 &wl->rx_mem_pool_addr,
+				 sizeof(wl->rx_mem_pool_addr), false);
 
 		wl1271_rx_handle_data(wl, buf_size);
 
@@ -192,9 +220,5 @@ void wl1271_rx(struct wl1271 *wl, struct
 		drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
 	}
 
-	wl1271_reg_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
-
-	/* This is a workaround for some problems in the chip */
-	wl1271_reg_write32(wl, RX_DRIVER_DUMMY_WRITE_ADDRESS, 0x1);
-
+	wl1271_spi_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_rx.h	2010-02-24 13:52:17.000000000 -0500
@@ -102,14 +102,14 @@
 #define RX_BUF_SIZE_SHIFT_DIV 6
 
 struct wl1271_rx_descriptor {
-	u16 length;
+	__le16 length;
 	u8  status;
 	u8  flags;
 	u8  rate;
 	u8  channel;
 	s8  rssi;
 	u8  snr;
-	u32 timestamp;
+	__le32 timestamp;
 	u8  packet_class;
 	u8  process_id;
 	u8  pad_len;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,17 +30,29 @@
 #include "wl12xx_80211.h"
 #include "wl1271_spi.h"
 
-static int wl1271_translate_reg_addr(struct wl1271 *wl, int addr)
-{
-	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl1271_translate_mem_addr(struct wl1271 *wl, int addr)
+static int wl1271_translate_addr(struct wl1271 *wl, int addr)
 {
-	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+	/*
+	 * To translate, first check to which window of addresses the
+	 * particular address belongs. Then subtract the starting address
+	 * of that window from the address. Then, add offset of the
+	 * translated region.
+	 *
+	 * The translated regions occur next to each other in physical device
+	 * memory, so just add the sizes of the preceeding address regions to
+	 * get the offset to the new region.
+	 *
+	 * Currently, only the two first regions are addressed, and the
+	 * assumption is that all addresses will fall into either of those
+	 * two.
+	 */
+	if ((addr >= wl->part.reg.start) &&
+	    (addr < wl->part.reg.start + wl->part.reg.size))
+		return addr - wl->part.reg.start + wl->part.mem.size;
+	else
+		return addr - wl->part.mem.start;
 }
 
-
 void wl1271_spi_reset(struct wl1271 *wl)
 {
 	u8 *cmd;
@@ -123,133 +135,137 @@ void wl1271_spi_init(struct wl1271 *wl)
 
 /* Set the SPI partitions to access the chip addresses
  *
- * There are two VIRTUAL (SPI) partitions (the memory partition and the
- * registers partition), which are mapped to two different areas of the
- * PHYSICAL (hardware) memory.  This function also makes other checks to
- * ensure that the partitions are not overlapping.  In the diagram below, the
- * memory partition comes before the register partition, but the opposite is
- * also supported.
+ * To simplify driver code, a fixed (virtual) memory map is defined for
+ * register and memory addresses. Because in the chipset, in different stages
+ * of operation, those addresses will move around, an address translation
+ * mechanism is required.
  *
- *                               PHYSICAL address
+ * There are four partitions (three memory and one register partition),
+ * which are mapped to two different areas of the hardware memory.
+ *
+ *                                Virtual address
  *                                     space
  *
  *                                    |    |
- *                                 ...+----+--> mem_start
- *          VIRTUAL address     ...   |    |
+ *                                 ...+----+--> mem.start
+ *          Physical address    ...   |    |
  *               space       ...      |    | [PART_0]
  *                        ...         |    |
- * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *  00000000  <--+----+...         ...+----+--> mem.start + mem.size
  *               |    |         ...   |    |
  *               |MEM |      ...      |    |
  *               |    |   ...         |    |
- *  part_size <--+----+...            |    | {unused area)
+ *  mem.size  <--+----+...            |    | {unused area)
  *               |    |   ...         |    |
  *               |REG |      ...      |    |
- *  part_size    |    |         ...   |    |
- *      +     <--+----+...         ...+----+--> reg_start
- *  reg_size              ...         |    |
- *                           ...      |    | [PART_1]
- *                              ...   |    |
- *                                 ...+----+--> reg_start + reg_size
+ *  mem.size     |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg.start
+ *  reg.size     |    |   ...         |    |
+ *               |MEM2|      ...      |    | [PART_1]
+ *               |    |         ...   |    |
+ *                                 ...+----+--> reg.start + reg.size
  *                                    |    |
  *
  */
 int wl1271_set_partition(struct wl1271 *wl,
-			  u32 mem_start, u32 mem_size,
-			  u32 reg_start, u32 reg_size)
+			 struct wl1271_partition_set *p)
 {
-	struct wl1271_partition *partition;
-	struct spi_transfer t;
-	struct spi_message m;
-	size_t len, cmd_len;
-	u32 *cmd;
-	int addr;
-
-	cmd_len = sizeof(u32) + 2 * sizeof(struct wl1271_partition);
-	cmd = kzalloc(cmd_len, GFP_KERNEL);
-	if (!cmd)
-		return -ENOMEM;
-
-	spi_message_init(&m);
-	memset(&t, 0, sizeof(t));
-
-	partition = (struct wl1271_partition *) (cmd + 1);
-	addr = HW_ACCESS_PART0_SIZE_ADDR;
-	len = 2 * sizeof(struct wl1271_partition);
-
-	*cmd |= WSPI_CMD_WRITE;
-	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+	/* copy partition info */
+	memcpy(&wl->part, p, sizeof(*p));
 
 	wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-		     mem_start, mem_size);
+		     p->mem.start, p->mem.size);
 	wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-		     reg_start, reg_size);
+		     p->reg.start, p->reg.size);
+	wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
+		     p->mem2.start, p->mem2.size);
+	wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
+		     p->mem3.start, p->mem3.size);
 
-	/* Make sure that the two partitions together don't exceed the
-	 * address range */
-	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
-		wl1271_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
-			     " address range.  Truncating partition[0].");
-		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
-		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
+	/* write partition info to the chipset */
+	wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
+	wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
+	wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
+	wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
+	wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
+	wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
+	wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
 
-	if ((mem_start < reg_start) &&
-	    ((mem_start + mem_size) > reg_start)) {
-		/* Guarantee that the memory partition doesn't overlap the
-		 * registers partition */
-		wl1271_debug(DEBUG_SPI, "End of partition[0] is "
-			     "overlapping partition[1].  Adjusted.");
-		mem_size = reg_start - mem_start;
-		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	} else if ((reg_start < mem_start) &&
-		   ((reg_start + reg_size) > mem_start)) {
-		/* Guarantee that the register partition doesn't overlap the
-		 * memory partition */
-		wl1271_debug(DEBUG_SPI, "End of partition[1] is"
-			     " overlapping partition[0].  Adjusted.");
-		reg_size = mem_start - reg_start;
-		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
+	return 0;
+}
 
-	partition[0].start = mem_start;
-	partition[0].size  = mem_size;
-	partition[1].start = reg_start;
-	partition[1].size  = reg_size;
+#define WL1271_BUSY_WORD_TIMEOUT 1000
 
-	wl->physical_mem_addr = mem_start;
-	wl->physical_reg_addr = reg_start;
+/* FIXME: Check busy words, removed due to SPI bug */
+#if 0
+static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
+{
+	struct spi_transfer t[1];
+	struct spi_message m;
+	u32 *busy_buf;
+	int num_busy_bytes = 0;
 
-	wl->virtual_mem_addr = 0;
-	wl->virtual_reg_addr = mem_size;
+	wl1271_info("spi read BUSY!");
 
-	t.tx_buf = cmd;
-	t.len = cmd_len;
-	spi_message_add_tail(&t, &m);
+	/*
+	 * Look for the non-busy word in the read buffer, and if found,
+	 * read in the remaining data into the buffer.
+	 */
+	busy_buf = (u32 *)buf;
+	for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
+		num_busy_bytes += sizeof(u32);
+		if (*busy_buf & 0x1) {
+			spi_message_init(&m);
+			memset(t, 0, sizeof(t));
+			memmove(buf, busy_buf, len - num_busy_bytes);
+			t[0].rx_buf = buf + (len - num_busy_bytes);
+			t[0].len = num_busy_bytes;
+			spi_message_add_tail(&t[0], &m);
+			spi_sync(wl->spi, &m);
+			return;
+		}
+	}
 
-	spi_sync(wl->spi, &m);
+	/*
+	 * Read further busy words from SPI until a non-busy word is
+	 * encountered, then read the data itself into the buffer.
+	 */
+	wl1271_info("spi read BUSY-polling needed!");
 
-	kfree(cmd);
+	num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
+	busy_buf = wl->buffer_busyword;
+	while (num_busy_bytes) {
+		num_busy_bytes--;
+		spi_message_init(&m);
+		memset(t, 0, sizeof(t));
+		t[0].rx_buf = busy_buf;
+		t[0].len = sizeof(u32);
+		spi_message_add_tail(&t[0], &m);
+		spi_sync(wl->spi, &m);
 
-	return 0;
+		if (*busy_buf & 0x1) {
+			spi_message_init(&m);
+			memset(t, 0, sizeof(t));
+			t[0].rx_buf = buf;
+			t[0].len = len;
+			spi_message_add_tail(&t[0], &m);
+			spi_sync(wl->spi, &m);
+			return;
+		}
+	}
+
+	/* The SPI bus is unresponsive, the read failed. */
+	memset(buf, 0, len);
+	wl1271_error("SPI read busy-word timeout!\n");
 }
+#endif
 
-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
-		     size_t len, bool fixed)
+void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
+			 size_t len, bool fixed)
 {
 	struct spi_transfer t[3];
 	struct spi_message m;
-	u8 *busy_buf;
+	u32 *busy_buf;
 	u32 *cmd;
 
 	cmd = &wl->buffer_cmd;
@@ -281,14 +297,16 @@ void wl1271_spi_read(struct wl1271 *wl,
 
 	spi_sync(wl->spi, &m);
 
-	/* FIXME: check busy words */
+	/* FIXME: Check busy words, removed due to SPI bug */
+	/* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1))
+	   wl1271_spi_read_busy(wl, buf, len); */
 
 	wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
 	wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
 }
 
-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
-		      size_t len, bool fixed)
+void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
+			  size_t len, bool fixed)
 {
 	struct spi_transfer t[2];
 	struct spi_message m;
@@ -321,62 +339,77 @@ void wl1271_spi_write(struct wl1271 *wl,
 	wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
 }
 
-void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf,
-			 size_t len)
+void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+		     bool fixed)
 {
 	int physical;
 
-	physical = wl1271_translate_mem_addr(wl, addr);
+	physical = wl1271_translate_addr(wl, addr);
 
-	wl1271_spi_read(wl, physical, buf, len, false);
+	wl1271_spi_raw_read(wl, physical, buf, len, fixed);
 }
 
-void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf,
-			  size_t len)
+void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+		      bool fixed)
 {
 	int physical;
 
-	physical = wl1271_translate_mem_addr(wl, addr);
+	physical = wl1271_translate_addr(wl, addr);
 
-	wl1271_spi_write(wl, physical, buf, len, false);
+	wl1271_spi_raw_write(wl, physical, buf, len, fixed);
 }
 
-void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
-			 bool fixed)
+u32 wl1271_spi_read32(struct wl1271 *wl, int addr)
 {
-	int physical;
-
-	physical = wl1271_translate_reg_addr(wl, addr);
+	return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
+}
 
-	wl1271_spi_read(wl, physical, buf, len, fixed);
+void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
 }
 
-void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
-			  bool fixed)
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
 {
-	int physical;
+	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
+	addr = (addr >> 1) + 0x30000;
+	wl1271_spi_write32(wl, OCP_POR_CTR, addr);
 
-	physical = wl1271_translate_reg_addr(wl, addr);
+	/* write value to OCP_POR_WDATA */
+	wl1271_spi_write32(wl, OCP_DATA_WRITE, val);
 
-	wl1271_spi_write(wl, physical, buf, len, fixed);
+	/* write 1 to OCP_CMD */
+	wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_WRITE);
 }
 
-u32 wl1271_mem_read32(struct wl1271 *wl, int addr)
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
 {
-	return wl1271_read32(wl, wl1271_translate_mem_addr(wl, addr));
-}
+	u32 val;
+	int timeout = OCP_CMD_LOOP;
 
-void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val)
-{
-	wl1271_write32(wl, wl1271_translate_mem_addr(wl, addr), val);
-}
+	/* write address >> 1 + 0x30000 to OCP_POR_CTR */
+	addr = (addr >> 1) + 0x30000;
+	wl1271_spi_write32(wl, OCP_POR_CTR, addr);
 
-u32 wl1271_reg_read32(struct wl1271 *wl, int addr)
-{
-	return wl1271_read32(wl, wl1271_translate_reg_addr(wl, addr));
-}
+	/* write 2 to OCP_CMD */
+	wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_READ);
 
-void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
-{
-	wl1271_write32(wl, wl1271_translate_reg_addr(wl, addr), val);
+	/* poll for data ready */
+	do {
+		val = wl1271_spi_read32(wl, OCP_DATA_READ);
+		timeout--;
+	} while (!(val & OCP_READY_MASK) && timeout);
+
+	if (!timeout) {
+		wl1271_warning("Top register access timed out.");
+		return 0xffff;
+	}
+
+	/* check data status and return if OK */
+	if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
+		return val & 0xffff;
+	else {
+		wl1271_warning("Top register access returned error.");
+		return 0xffff;
+	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_spi.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,10 +29,14 @@
 
 #define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
 
-#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
-#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
-#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
-#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+#define HW_PARTITION_REGISTERS_ADDR         0x1ffc0
+#define HW_PART0_SIZE_ADDR                  (HW_PARTITION_REGISTERS_ADDR)
+#define HW_PART0_START_ADDR                 (HW_PARTITION_REGISTERS_ADDR + 4)
+#define HW_PART1_SIZE_ADDR                  (HW_PARTITION_REGISTERS_ADDR + 8)
+#define HW_PART1_START_ADDR                 (HW_PARTITION_REGISTERS_ADDR + 12)
+#define HW_PART2_SIZE_ADDR                  (HW_PARTITION_REGISTERS_ADDR + 16)
+#define HW_PART2_START_ADDR                 (HW_PARTITION_REGISTERS_ADDR + 20)
+#define HW_PART3_START_ADDR                 (HW_PARTITION_REGISTERS_ADDR + 24)
 
 #define HW_ACCESS_REGISTER_SIZE             4
 
@@ -67,47 +71,56 @@
 		((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
 #define HW_ACCESS_WSPI_INIT_CMD_MASK  0
 
+#define OCP_CMD_LOOP  32
+
+#define OCP_CMD_WRITE 0x1
+#define OCP_CMD_READ  0x2
+
+#define OCP_READY_MASK  BIT(18)
+#define OCP_STATUS_MASK (BIT(16) | BIT(17))
+
+#define OCP_STATUS_NO_RESP    0x00000
+#define OCP_STATUS_OK         0x10000
+#define OCP_STATUS_REQ_FAILED 0x20000
+#define OCP_STATUS_RESP_ERROR 0x30000
 
 /* Raw target IO, address is not translated */
-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
+void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
 		      size_t len, bool fixed);
-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
+void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
 		     size_t len, bool fixed);
 
-/* Memory target IO, address is tranlated to partition 0 */
-void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf, size_t len);
-void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf, size_t len);
-u32 wl1271_mem_read32(struct wl1271 *wl, int addr);
-void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val);
+/* Translated target IO */
+void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+		     bool fixed);
+void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+		      bool fixed);
+u32 wl1271_spi_read32(struct wl1271 *wl, int addr);
+void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val);
 
-/* Registers IO */
-void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
-			 bool fixed);
-void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
-			  bool fixed);
-u32 wl1271_reg_read32(struct wl1271 *wl, int addr);
-void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
+/* Top Register IO */
+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
 
 /* INIT and RESET words */
 void wl1271_spi_reset(struct wl1271 *wl);
 void wl1271_spi_init(struct wl1271 *wl);
 int wl1271_set_partition(struct wl1271 *wl,
-			 u32 part_start, u32 part_size,
-			 u32 reg_start,  u32 reg_size);
+			 struct wl1271_partition_set *p);
 
-static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
+static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
 {
-	wl1271_spi_read(wl, addr, &wl->buffer_32,
-			sizeof(wl->buffer_32), false);
+	wl1271_spi_raw_read(wl, addr, &wl->buffer_32,
+			    sizeof(wl->buffer_32), false);
 
 	return wl->buffer_32;
 }
 
-static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
+static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
 {
 	wl->buffer_32 = val;
-	wl1271_spi_write(wl, addr, &wl->buffer_32,
-			 sizeof(wl->buffer_32), false);
+	wl1271_spi_raw_write(wl, addr, &wl->buffer_32,
+			     sizeof(wl->buffer_32), false);
 }
 
 #endif /* __WL1271_SPI_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.c	2010-02-24 13:52:17.000000000 -0500
@@ -33,8 +33,7 @@
 static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
 {
 	int i;
-
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
 		if (wl->tx_frames[i] == NULL) {
 			wl->tx_frames[i] = skb;
 			return i;
@@ -58,8 +57,8 @@ static int wl1271_tx_allocate(struct wl1
 	/* approximate the number of blocks required for this packet
 	   in the firmware */
 	/* FIXME: try to figure out what is done here and make it cleaner */
-	total_blocks = (skb->len) >> TX_HW_BLOCK_SHIFT_DIV;
-	excluded = (total_blocks << 2) + (skb->len & 0xff) + 34;
+	total_blocks = (total_len + 20) >> TX_HW_BLOCK_SHIFT_DIV;
+	excluded = (total_blocks << 2) + ((total_len + 20) & 0xff) + 34;
 	total_blocks += (excluded > 252) ? 2 : 1;
 	total_blocks += TX_HW_BLOCK_SPARE;
 
@@ -89,15 +88,25 @@ static int wl1271_tx_fill_hdr(struct wl1
 {
 	struct wl1271_tx_hw_descr *desc;
 	int pad;
+	u16 tx_attr;
 
 	desc = (struct wl1271_tx_hw_descr *) skb->data;
 
+	/* relocate space for security header */
+	if (extra) {
+		void *framestart = skb->data + sizeof(*desc);
+		u16 fc = *(u16 *)(framestart + extra);
+		int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc));
+		memmove(framestart, framestart + extra, hdrlen);
+	}
+
 	/* configure packet life time */
-	desc->start_time = jiffies_to_usecs(jiffies) - wl->time_offset;
-	desc->life_time = TX_HW_MGMT_PKT_LIFETIME_TU;
+	desc->start_time = cpu_to_le32(jiffies_to_usecs(jiffies) -
+				       wl->time_offset);
+	desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
 
 	/* configure the tx attributes */
-	desc->tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
+	tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
 	/* FIXME: do we know the packet priority? can we identify mgmt
 	   packets, and use max prio for them at least? */
 	desc->tid = 0;
@@ -106,11 +115,13 @@ static int wl1271_tx_fill_hdr(struct wl1
 
 	/* align the length (and store in terms of words) */
 	pad = WL1271_TX_ALIGN(skb->len);
-	desc->length = pad >> 2;
+	desc->length = cpu_to_le16(pad >> 2);
 
 	/* calculate number of padding bytes */
 	pad = pad - skb->len;
-	desc->tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+	tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+
+	desc->tx_attr = cpu_to_le16(tx_attr);
 
 	wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
 	return 0;
@@ -147,11 +158,11 @@ static int wl1271_tx_send_packet(struct
 	len = WL1271_TX_ALIGN(skb->len);
 
 	/* perform a fixed address block write with the packet */
-	wl1271_spi_reg_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
+	wl1271_spi_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
 
 	/* write packet new counter into the write access register */
 	wl->tx_packets_count++;
-	wl1271_reg_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+	wl1271_spi_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
 
 	desc = (struct wl1271_tx_hw_descr *) skb->data;
 	wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
@@ -254,14 +265,13 @@ out:
 static void wl1271_tx_complete_packet(struct wl1271 *wl,
 				      struct wl1271_tx_hw_res_descr *result)
 {
-
 	struct ieee80211_tx_info *info;
 	struct sk_buff *skb;
-	u32 header_len;
+	u16 seq;
 	int id = result->id;
 
 	/* check for id legality */
-	if (id >= TX_HW_RESULT_QUEUE_LEN || wl->tx_frames[id] == NULL) {
+	if (id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL) {
 		wl1271_warning("TX result illegal id: %d", id);
 		return;
 	}
@@ -284,22 +294,32 @@ static void wl1271_tx_complete_packet(st
 	/* info->status.retry_count = result->ack_failures; */
 	wl->stats.retry_count += result->ack_failures;
 
-	/* get header len */
+	/* update security sequence number */
+	seq = wl->tx_security_seq_16 +
+		(result->lsb_security_sequence_number -
+		 wl->tx_security_last_seq);
+	wl->tx_security_last_seq = result->lsb_security_sequence_number;
+
+	if (seq < wl->tx_security_seq_16)
+		wl->tx_security_seq_32++;
+	wl->tx_security_seq_16 = seq;
+
+	/* remove private header from packet */
+	skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+
+	/* remove TKIP header space if present */
 	if (info->control.hw_key &&
-	    info->control.hw_key->alg == ALG_TKIP)
-		header_len = WL1271_TKIP_IV_SPACE +
-			sizeof(struct wl1271_tx_hw_descr);
-	else
-		header_len = sizeof(struct wl1271_tx_hw_descr);
+	    info->control.hw_key->alg == ALG_TKIP) {
+		int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+		memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen);
+		skb_pull(skb, WL1271_TKIP_IV_SPACE);
+	}
 
 	wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
 		     " status 0x%x",
 		     result->id, skb, result->ack_failures,
 		     result->rate_class_index, result->status);
 
-	/* remove private header from packet */
-	skb_pull(skb, header_len);
-
 	/* return the packet to the stack */
 	ieee80211_tx_status(wl->hw, skb);
 	wl->tx_frames[result->id] = NULL;
@@ -315,8 +335,8 @@ void wl1271_tx_complete(struct wl1271 *w
 	wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
 
 	/* read the tx results from the chipset */
-	wl1271_spi_mem_read(wl, memmap->tx_result,
-			    wl->tx_res_if, sizeof(*wl->tx_res_if));
+	wl1271_spi_read(wl, le32_to_cpu(memmap->tx_result),
+			wl->tx_res_if, sizeof(*wl->tx_res_if), false);
 
 	/* verify that the result buffer is not getting overrun */
 	if (count > TX_HW_RESULT_QUEUE_LEN) {
@@ -337,10 +357,10 @@ void wl1271_tx_complete(struct wl1271 *w
 	}
 
 	/* write host counter to chipset (to ack) */
-	wl1271_mem_write32(wl, memmap->tx_result +
+	wl1271_spi_write32(wl, le32_to_cpu(memmap->tx_result) +
 			   offsetof(struct wl1271_tx_hw_res_if,
 				    tx_result_host_counter),
-			   wl->tx_res_if->tx_result_fw_counter);
+			   le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));
 }
 
 /* caller must hold wl->mutex */
@@ -364,7 +384,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
 		ieee80211_tx_status(wl->hw, skb);
 	}
 
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
 		if (wl->tx_frames[i] != NULL) {
 			skb = wl->tx_frames[i];
 			info = IEEE80211_SKB_CB(skb);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl1271_tx.h	2010-02-24 13:52:17.000000000 -0500
@@ -58,7 +58,7 @@
 
 struct wl1271_tx_hw_descr {
 	/* Length of packet in words, including descriptor+header+data */
-	u16 length;
+	__le16 length;
 	/* Number of extra memory blocks to allocate for this packet in
 	   addition to the number of blocks derived from the packet length */
 	u8 extra_mem_blocks;
@@ -67,12 +67,12 @@ struct wl1271_tx_hw_descr {
 	   HW!! */
 	u8 total_mem_blocks;
 	/* Device time (in us) when the packet arrived to the driver */
-	u32 start_time;
+	__le32 start_time;
 	/* Max delay in TUs until transmission. The last device time the
 	   packet can be transmitted is: startTime+(1024*LifeTime) */
-	u16 life_time;
+	__le16 life_time;
 	/* Bitwise fields - see TX_ATTR... definitions above. */
-	u16 tx_attr;
+	__le16 tx_attr;
 	/* Packet identifier used also in the Tx-Result. */
 	u8 id;
 	/* The packet TID value (as User-Priority) */
@@ -100,12 +100,12 @@ struct wl1271_tx_hw_res_descr {
 	   several possible reasons for failure. */
 	u8 status;
 	/* Total air access duration including all retrys and overheads.*/
-	u16 medium_usage;
+	__le16 medium_usage;
 	/* The time passed from host xfer to Tx-complete.*/
-	u32 fw_handling_time;
+	__le32 fw_handling_time;
 	/* Total media delay
 	   (from 1st EDCA AIFS counter until TX Complete). */
-	u32 medium_delay;
+	__le32 medium_delay;
 	/* LS-byte of last TKIP seq-num (saved per AC for recovery). */
 	u8 lsb_security_sequence_number;
 	/* Retry count - number of transmissions without successful ACK.*/
@@ -118,8 +118,8 @@ struct wl1271_tx_hw_res_descr {
 } __attribute__ ((packed));
 
 struct wl1271_tx_hw_res_if {
-	u32 tx_result_fw_counter;
-	u32 tx_result_host_counter;
+	__le32 tx_result_fw_counter;
+	__le32 tx_result_host_counter;
 	struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
 } __attribute__ ((packed));
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl12xx_80211.h linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl12xx_80211.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl12xx/wl12xx_80211.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl12xx/wl12xx_80211.h	2010-02-24 13:52:17.000000000 -0500
@@ -122,8 +122,8 @@ struct wl12xx_null_data_template {
 } __attribute__ ((packed));
 
 struct wl12xx_ps_poll_template {
-	u16 fc;
-	u16 aid;
+	__le16 fc;
+	__le16 aid;
 	u8 bssid[ETH_ALEN];
 	u8 ta[ETH_ALEN];
 } __attribute__ ((packed));
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/wl3501_cs.c linux-libre-2.6.33-gnu1/drivers/net/wireless/wl3501_cs.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/wl3501_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/wl3501_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,23 +67,7 @@
 /* For rough constant delay */
 #define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
 
-/*
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If you do not
- * define PCMCIA_DEBUG at all, all the debug code will be left out.  If you
- * compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
- * but it can then be enabled for specific modules at load time with a
- * 'pc_debug=#' option to insmod.
- */
-#define PCMCIA_DEBUG 0
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define dprintk(n, format, args...) \
-	{ if (pc_debug > (n)) \
-		printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
-#else
-#define dprintk(n, format, args...)
-#endif
+
 
 #define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
 #define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
@@ -381,7 +365,7 @@ static void wl3501_free_tx_buffer(struct
 
 static int wl3501_esbq_req_test(struct wl3501_card *this)
 {
-	u8 tmp;
+	u8 tmp = 0;
 
 	wl3501_get_from_wla(this, this->esbq_req_head + 3, &tmp, sizeof(tmp));
 	return tmp & 0x80;
@@ -684,10 +668,10 @@ static void wl3501_mgmt_scan_confirm(str
 	int matchflag = 0;
 	struct wl3501_scan_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 	if (sig.status == WL3501_STATUS_SUCCESS) {
-		dprintk(3, "success");
+		pr_debug("success");
 		if ((this->net_type == IW_MODE_INFRA &&
 		     (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
 		    (this->net_type == IW_MODE_ADHOC &&
@@ -722,7 +706,7 @@ static void wl3501_mgmt_scan_confirm(str
 			}
 		}
 	} else if (sig.status == WL3501_STATUS_TIMEOUT) {
-		dprintk(3, "timeout");
+		pr_debug("timeout");
 		this->join_sta_bss = 0;
 		for (i = this->join_sta_bss; i < this->bss_cnt; i++)
 			if (!wl3501_mgmt_join(this, i))
@@ -879,7 +863,7 @@ static int wl3501_mgmt_auth(struct wl350
 		.timeout = 1000,
 	};
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
 	return wl3501_esbq_exec(this, &sig, sizeof(sig));
 }
@@ -893,7 +877,7 @@ static int wl3501_mgmt_association(struc
 		.cap_info	 = this->cap_info,
 	};
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
 	return wl3501_esbq_exec(this, &sig, sizeof(sig));
 }
@@ -903,7 +887,7 @@ static void wl3501_mgmt_join_confirm(str
 	struct wl3501_card *this = netdev_priv(dev);
 	struct wl3501_join_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 	if (sig.status == WL3501_STATUS_SUCCESS) {
 		if (this->net_type == IW_MODE_INFRA) {
@@ -962,7 +946,7 @@ static inline void wl3501_md_confirm_int
 {
 	struct wl3501_md_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 	wl3501_free_tx_buffer(this, sig.data);
 	if (netif_queue_stopped(dev))
@@ -1017,7 +1001,7 @@ static inline void wl3501_md_ind_interru
 static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
 						u16 addr, void *sig, int size)
 {
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
 			    sizeof(this->sig_get_confirm));
 	wake_up(&this->wait);
@@ -1029,7 +1013,7 @@ static inline void wl3501_start_confirm_
 {
 	struct wl3501_start_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 	if (sig.status == WL3501_STATUS_SUCCESS)
 		netif_wake_queue(dev);
@@ -1041,7 +1025,7 @@ static inline void wl3501_assoc_confirm_
 	struct wl3501_card *this = netdev_priv(dev);
 	struct wl3501_assoc_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 
 	if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1053,7 +1037,7 @@ static inline void wl3501_auth_confirm_i
 {
 	struct wl3501_auth_confirm sig;
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 	wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 
 	if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1069,7 +1053,7 @@ static inline void wl3501_rx_interrupt(s
 	u8 sig_id;
 	struct wl3501_card *this = netdev_priv(dev);
 
-	dprintk(3, "entry");
+	pr_debug("entry");
 loop:
 	morepkts = 0;
 	if (!wl3501_esbq_confirm(this))
@@ -1302,7 +1286,7 @@ static int wl3501_reset(struct net_devic
 	wl3501_ack_interrupt(this);
 	wl3501_unblock_interrupt(this);
 	wl3501_mgmt_scan(this, 100);
-	dprintk(1, "%s: device reset", dev->name);
+	pr_debug("%s: device reset", dev->name);
 	rc = 0;
 out:
 	return rc;
@@ -1376,7 +1360,7 @@ static int wl3501_open(struct net_device
 	link->open++;
 
 	/* Initial WL3501 firmware */
-	dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
+	pr_debug("%s: Initialize WL3501 firmware...", dev->name);
 	if (wl3501_init_firmware(this))
 		goto fail;
 	/* Initial device variables */
@@ -1388,7 +1372,7 @@ static int wl3501_open(struct net_device
 	wl3501_unblock_interrupt(this);
 	wl3501_mgmt_scan(this, 100);
 	rc = 0;
-	dprintk(1, "%s: WL3501 opened", dev->name);
+	pr_debug("%s: WL3501 opened", dev->name);
 	printk(KERN_INFO "%s: Card Name: %s\n"
 			 "%s: Firmware Date: %s\n",
 			 dev->name, this->card_name,
@@ -1914,8 +1898,7 @@ static int wl3501_probe(struct pcmcia_de
 	p_dev->io.IOAddrLines	= 5;
 
 	/* Interrupt setup */
-	p_dev->irq.Attributes	= IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-	p_dev->irq.IRQInfo1	= IRQ_LEVEL_ID;
+	p_dev->irq.Attributes	= IRQ_TYPE_DYNAMIC_SHARING;
 	p_dev->irq.Handler = wl3501_interrupt;
 
 	/* General socket configuration */
@@ -1938,16 +1921,13 @@ static int wl3501_probe(struct pcmcia_de
 	dev->wireless_handlers	= &wl3501_handler_def;
 	SET_ETHTOOL_OPS(dev, &ops);
 	netif_stop_queue(dev);
-	p_dev->priv = p_dev->irq.Instance = dev;
+	p_dev->priv = dev;
 
 	return wl3501_config(p_dev);
 out_link:
 	return -ENOMEM;
 }
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /**
  * wl3501_config - configure the PCMCIA socket and make eth device available
  * @link - FILL_IN
@@ -1959,7 +1939,7 @@ do { last_fn = (fn); if ((last_ret = (re
 static int wl3501_config(struct pcmcia_device *link)
 {
 	struct net_device *dev = link->priv;
-	int i = 0, j, last_fn, last_ret;
+	int i = 0, j, ret;
 	struct wl3501_card *this;
 
 	/* Try allocating IO ports.  This tries a few fixed addresses.  If you
@@ -1975,24 +1955,26 @@ static int wl3501_config(struct pcmcia_d
 		if (i == 0)
 			break;
 	}
-	if (i != 0) {
-		cs_error(link, RequestIO, i);
+	if (i != 0)
 		goto failed;
-	}
 
 	/* Now allocate an interrupt line. Note that this does not actually
 	 * assign a handler to the interrupt. */
 
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
 
 	/* This actually configures the PCMCIA socket -- setting up the I/O
 	 * windows and the interrupt mapping.  */
 
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	dev->irq = link->irq.AssignedIRQ;
 	dev->base_addr = link->io.BasePort1;
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
+	SET_NETDEV_DEV(dev, &link->dev);
 	if (register_netdev(dev)) {
 		printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
 		goto failed;
@@ -2041,8 +2023,6 @@ static int wl3501_config(struct pcmcia_d
 	netif_start_queue(dev);
 	return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
 failed:
 	wl3501_release(link);
 	return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1201.c linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1201.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 14:04:14.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 12:11:47.000000000 -0400
@@ -112,6 +112,8 @@ exit:
 	return err;
 }
 
+/*(DEBLOBBED)*/
+
 static void zd1201_usbfree(struct urb *urb)
 {
 	struct zd1201 *zd = urb->context;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/Kconfig linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 config ZD1211RW
 	tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
-	depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+	depends on USB && MAC80211 && EXPERIMENTAL
 	select FW_LOADER
 	---help---
 	  This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2010-02-24 13:52:17.000000000 -0500
@@ -755,7 +755,7 @@ static int hw_reset_phy(struct zd_chip *
 static int zd1211_hw_init_hmac(struct zd_chip *chip)
 {
 	static const struct zd_ioreq32 ioreqs[] = {
-		{ CR_ZD1211_RETRY_MAX,		0x2 },
+		{ CR_ZD1211_RETRY_MAX,		ZD1211_RETRY_COUNT },
 		{ CR_RX_THRESHOLD,		0x000c0640 },
 	};
 
@@ -767,7 +767,7 @@ static int zd1211_hw_init_hmac(struct zd
 static int zd1211b_hw_init_hmac(struct zd_chip *chip)
 {
 	static const struct zd_ioreq32 ioreqs[] = {
-		{ CR_ZD1211B_RETRY_MAX,		0x02020202 },
+		{ CR_ZD1211B_RETRY_MAX,		ZD1211B_RETRY_COUNT },
 		{ CR_ZD1211B_CWIN_MAX_MIN_AC0,	0x007f003f },
 		{ CR_ZD1211B_CWIN_MAX_MIN_AC1,	0x007f003f },
 		{ CR_ZD1211B_CWIN_MAX_MIN_AC2,  0x003f001f },
@@ -1325,151 +1325,11 @@ int zd_chip_set_basic_rates(struct zd_ch
 	return r;
 }
 
-static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size)
-{
-	static const u16 constants[] = {
-		715, 655, 585, 540, 470, 410, 360, 315,
-		270, 235, 205, 175, 150, 125, 105,  85,
-		 65,  50,  40,  25,  15
-	};
-
-	int i;
-	u32 x;
-
-	/* It seems that their quality parameter is somehow per signal
-	 * and is now transferred per bit.
-	 */
-	switch (zd_rate) {
-	case ZD_OFDM_RATE_6M:
-	case ZD_OFDM_RATE_12M:
-	case ZD_OFDM_RATE_24M:
-		size *= 2;
-		break;
-	case ZD_OFDM_RATE_9M:
-	case ZD_OFDM_RATE_18M:
-	case ZD_OFDM_RATE_36M:
-	case ZD_OFDM_RATE_54M:
-		size *= 4;
-		size /= 3;
-		break;
-	case ZD_OFDM_RATE_48M:
-		size *= 3;
-		size /= 2;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	x = (10000 * status_quality)/size;
-	for (i = 0; i < ARRAY_SIZE(constants); i++) {
-		if (x > constants[i])
-			break;
-	}
-
-	switch (zd_rate) {
-	case ZD_OFDM_RATE_6M:
-	case ZD_OFDM_RATE_9M:
-		i += 3;
-		break;
-	case ZD_OFDM_RATE_12M:
-	case ZD_OFDM_RATE_18M:
-		i += 5;
-		break;
-	case ZD_OFDM_RATE_24M:
-	case ZD_OFDM_RATE_36M:
-		i += 9;
-		break;
-	case ZD_OFDM_RATE_48M:
-	case ZD_OFDM_RATE_54M:
-		i += 15;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return i;
-}
-
-static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size)
-{
-	int r;
-
-	r = ofdm_qual_db(status_quality, zd_rate, size);
-	ZD_ASSERT(r >= 0);
-	if (r < 0)
-		r = 0;
-
-	r = (r * 100)/29;
-	return r <= 100 ? r : 100;
-}
-
-static unsigned int log10times100(unsigned int x)
-{
-	static const u8 log10[] = {
-		  0,
-		  0,   30,   47,   60,   69,   77,   84,   90,   95,  100,
-		104,  107,  111,  114,  117,  120,  123,  125,  127,  130,
-		132,  134,  136,  138,  139,  141,  143,  144,  146,  147,
-		149,  150,  151,  153,  154,  155,  156,  157,  159,  160,
-		161,  162,  163,  164,  165,  166,  167,  168,  169,  169,
-		170,  171,  172,  173,  174,  174,  175,  176,  177,  177,
-		178,  179,  179,  180,  181,  181,  182,  183,  183,  184,
-		185,  185,  186,  186,  187,  188,  188,  189,  189,  190,
-		190,  191,  191,  192,  192,  193,  193,  194,  194,  195,
-		195,  196,  196,  197,  197,  198,  198,  199,  199,  200,
-		200,  200,  201,  201,  202,  202,  202,  203,  203,  204,
-		204,  204,  205,  205,  206,  206,  206,  207,  207,  207,
-		208,  208,  208,  209,  209,  210,  210,  210,  211,  211,
-		211,  212,  212,  212,  213,  213,  213,  213,  214,  214,
-		214,  215,  215,  215,  216,  216,  216,  217,  217,  217,
-		217,  218,  218,  218,  219,  219,  219,  219,  220,  220,
-		220,  220,  221,  221,  221,  222,  222,  222,  222,  223,
-		223,  223,  223,  224,  224,  224,  224,
-	};
-
-	return x < ARRAY_SIZE(log10) ? log10[x] : 225;
-}
-
-enum {
-	MAX_CCK_EVM_DB = 45,
-};
-
-static int cck_evm_db(u8 status_quality)
-{
-	return (20 * log10times100(status_quality)) / 100;
-}
-
-static int cck_snr_db(u8 status_quality)
-{
-	int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);
-	ZD_ASSERT(r >= 0);
-	return r;
-}
-
-static int cck_qual_percent(u8 status_quality)
-{
-	int r;
-
-	r = cck_snr_db(status_quality);
-	r = (100*r)/17;
-	return r <= 100 ? r : 100;
-}
-
 static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame)
 {
 	return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame);
 }
 
-u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
-	              const struct rx_status *status)
-{
-	return (status->frame_status&ZD_RX_OFDM) ?
-		ofdm_qual_percent(status->signal_quality_ofdm,
-				  zd_rate_from_ofdm_plcp_header(rx_frame),
-			          size) :
-		cck_qual_percent(status->signal_quality_cck);
-}
-
 /**
  * zd_rx_rate - report zd-rate
  * @rx_frame - received frame
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h	2010-02-24 13:52:17.000000000 -0500
@@ -642,13 +642,29 @@ enum {
 #define CR_ZD1211B_TXOP			CTL_REG(0x0b20)
 #define CR_ZD1211B_RETRY_MAX		CTL_REG(0x0b28)
 
+/* Value for CR_ZD1211_RETRY_MAX & CR_ZD1211B_RETRY_MAX. Vendor driver uses 2,
+ * we use 0. The first rate is tried (count+2), then all next rates are tried
+ * twice, until 1 Mbits is tried. */
+#define	ZD1211_RETRY_COUNT		0
+#define	ZD1211B_RETRY_COUNT	\
+	(ZD1211_RETRY_COUNT <<  0)|	\
+	(ZD1211_RETRY_COUNT <<  8)|	\
+	(ZD1211_RETRY_COUNT << 16)|	\
+	(ZD1211_RETRY_COUNT << 24)
+
 /* Used to detect PLL lock */
 #define UW2453_INTR_REG			((zd_addr_t)0x85c1)
 
 #define CWIN_SIZE			0x007f043f
 
 
-#define HWINT_ENABLED			0x004f0000
+#define HWINT_ENABLED			\
+	(INT_TX_COMPLETE_EN|		\
+	 INT_RX_COMPLETE_EN|		\
+	 INT_RETRY_FAIL_EN|		\
+	 INT_WAKEUP_EN|			\
+	 INT_CFG_NEXT_BCN_EN)
+
 #define HWINT_DISABLED			0
 
 #define E2P_PWR_INT_GUARD		8
@@ -913,9 +929,6 @@ static inline int zd_get_beacon_interval
 
 struct rx_status;
 
-u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
-	               const struct rx_status *status);
-
 u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
 
 struct zd_mc_hash {
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2010-02-24 13:52:17.000000000 -0500
@@ -88,6 +88,34 @@ static const struct ieee80211_rate zd_ra
 	  .flags = 0 },
 };
 
+/*
+ * Zydas retry rates table. Each line is listed in the same order as
+ * in zd_rates[] and contains all the rate used when a packet is sent
+ * starting with a given rates. Let's consider an example :
+ *
+ * "11 Mbits : 4, 3, 2, 1, 0" means :
+ * - packet is sent using 4 different rates
+ * - 1st rate is index 3 (ie 11 Mbits)
+ * - 2nd rate is index 2 (ie 5.5 Mbits)
+ * - 3rd rate is index 1 (ie 2 Mbits)
+ * - 4th rate is index 0 (ie 1 Mbits)
+ */
+
+static const struct tx_retry_rate zd_retry_rates[] = {
+	{ /*  1 Mbits */	1, { 0 }},
+	{ /*  2 Mbits */	2, { 1,  0 }},
+	{ /*  5.5 Mbits */	3, { 2,  1, 0 }},
+	{ /* 11 Mbits */	4, { 3,  2, 1, 0 }},
+	{ /*  6 Mbits */	5, { 4,  3, 2, 1, 0 }},
+	{ /*  9 Mbits */	6, { 5,  4, 3, 2, 1, 0}},
+	{ /* 12 Mbits */	5, { 6,  3, 2, 1, 0 }},
+	{ /* 18 Mbits */	6, { 7,  6, 3, 2, 1, 0 }},
+	{ /* 24 Mbits */	6, { 8,  6, 3, 2, 1, 0 }},
+	{ /* 36 Mbits */	7, { 9,  8, 6, 3, 2, 1, 0 }},
+	{ /* 48 Mbits */	8, {10,  9, 8, 6, 3, 2, 1, 0 }},
+	{ /* 54 Mbits */	9, {11, 10, 9, 8, 6, 3, 2, 1, 0 }}
+};
+
 static const struct ieee80211_channel zd_channels[] = {
 	{ .center_freq = 2412, .hw_value = 1 },
 	{ .center_freq = 2417, .hw_value = 2 },
@@ -282,7 +310,7 @@ static void zd_op_stop(struct ieee80211_
 }
 
 /**
- * tx_status - reports tx status of a packet if required
+ * zd_mac_tx_status - reports tx status of a packet if required
  * @hw - a &struct ieee80211_hw pointer
  * @skb - a sk-buffer
  * @flags: extra flags to set in the TX status info
@@ -295,15 +323,49 @@ static void zd_op_stop(struct ieee80211_
  *
  * If no status information has been requested, the skb is freed.
  */
-static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
-		      int ackssi, bool success)
+static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
+		      int ackssi, struct tx_status *tx_status)
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	int i;
+	int success = 1, retry = 1;
+	int first_idx;
+	const struct tx_retry_rate *retries;
 
 	ieee80211_tx_info_clear_status(info);
 
-	if (success)
+	if (tx_status) {
+		success = !tx_status->failure;
+		retry = tx_status->retry + success;
+	}
+
+	if (success) {
+		/* success */
 		info->flags |= IEEE80211_TX_STAT_ACK;
+	} else {
+		/* failure */
+		info->flags &= ~IEEE80211_TX_STAT_ACK;
+	}
+
+	first_idx = info->status.rates[0].idx;
+	ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
+	retries = &zd_retry_rates[first_idx];
+	ZD_ASSERT(0<=retry && retry<=retries->count);
+
+	info->status.rates[0].idx = retries->rate[0];
+	info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
+
+	for (i=1; i<IEEE80211_TX_MAX_RATES-1 && i<retry; i++) {
+		info->status.rates[i].idx = retries->rate[i];
+		info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
+	}
+	for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
+		info->status.rates[i].idx = retries->rate[retry-1];
+		info->status.rates[i].count = 1; // (success ? 1:2);
+	}
+	if (i<IEEE80211_TX_MAX_RATES)
+		info->status.rates[i].idx = -1; /* terminate */
+
 	info->status.ack_signal = ackssi;
 	ieee80211_tx_status_irqsafe(hw, skb);
 }
@@ -312,20 +374,83 @@ static void tx_status(struct ieee80211_h
  * zd_mac_tx_failed - callback for failed frames
  * @dev: the mac80211 wireless device
  *
- * This function is called if a frame couldn't be succesfully be
+ * This function is called if a frame couldn't be successfully be
  * transferred. The first frame from the tx queue, will be selected and
  * reported as error to the upper layers.
  */
-void zd_mac_tx_failed(struct ieee80211_hw *hw)
+void zd_mac_tx_failed(struct urb *urb)
 {
-	struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
+	struct ieee80211_hw * hw = zd_usb_to_hw(urb->context);
+	struct zd_mac *mac = zd_hw_mac(hw);
+	struct sk_buff_head *q = &mac->ack_wait_queue;
 	struct sk_buff *skb;
+	struct tx_status *tx_status = (struct tx_status *)urb->transfer_buffer;
+	unsigned long flags;
+	int success = !tx_status->failure;
+	int retry = tx_status->retry + success;
+	int found = 0;
+	int i, position = 0;
 
-	skb = skb_dequeue(q);
-	if (skb == NULL)
-		return;
+	q = &mac->ack_wait_queue;
+	spin_lock_irqsave(&q->lock, flags);
 
-	tx_status(hw, skb, 0, 0);
+	skb_queue_walk(q, skb) {
+		struct ieee80211_hdr *tx_hdr;
+		struct ieee80211_tx_info *info;
+		int first_idx, final_idx;
+		const struct tx_retry_rate *retries;
+		u8 final_rate;
+
+		position ++;
+
+		/* if the hardware reports a failure and we had a 802.11 ACK
+		 * pending, then we skip the first skb when searching for a
+		 * matching frame */
+		if (tx_status->failure && mac->ack_pending &&
+		    skb_queue_is_first(q, skb)) {
+			continue;
+		}
+
+		tx_hdr = (struct ieee80211_hdr *)skb->data;
+
+		/* we skip all frames not matching the reported destination */
+		if (unlikely(memcmp(tx_hdr->addr1, tx_status->mac, ETH_ALEN))) {
+			continue;
+		}
+
+		/* we skip all frames not matching the reported final rate */
+
+		info = IEEE80211_SKB_CB(skb);
+		first_idx = info->status.rates[0].idx;
+		ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
+		retries = &zd_retry_rates[first_idx];
+		if (retry < 0 || retry > retries->count) {
+			continue;
+		}
+
+		ZD_ASSERT(0<=retry && retry<=retries->count);
+		final_idx = retries->rate[retry-1];
+		final_rate = zd_rates[final_idx].hw_value;
+
+		if (final_rate != tx_status->rate) {
+			continue;
+		}
+
+		found = 1;
+		break;
+	}
+
+	if (found) {
+		for (i=1; i<=position; i++) {
+			skb = __skb_dequeue(q);
+			zd_mac_tx_status(hw, skb,
+					 mac->ack_pending ? mac->ack_signal : 0,
+					 i == position ? tx_status : NULL);
+			mac->ack_pending = 0;
+		}
+	}
+
+	spin_unlock_irqrestore(&q->lock, flags);
 }
 
 /**
@@ -342,18 +467,27 @@ void zd_mac_tx_to_dev(struct sk_buff *sk
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hw *hw = info->rate_driver_data[0];
+	struct zd_mac *mac = zd_hw_mac(hw);
+
+	ieee80211_tx_info_clear_status(info);
 
 	skb_pull(skb, sizeof(struct zd_ctrlset));
 	if (unlikely(error ||
 	    (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
-		tx_status(hw, skb, 0, !error);
+		/*
+		 * FIXME : do we need to fill in anything ?
+		 */
+		ieee80211_tx_status_irqsafe(hw, skb);
 	} else {
-		struct sk_buff_head *q =
-			&zd_hw_mac(hw)->ack_wait_queue;
+		struct sk_buff_head *q = &mac->ack_wait_queue;
 
 		skb_queue_tail(q, skb);
-		while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
-			zd_mac_tx_failed(hw);
+		while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) {
+			zd_mac_tx_status(hw, skb_dequeue(q),
+					 mac->ack_pending ? mac->ack_signal : 0,
+					 NULL);
+			mac->ack_pending = 0;
+		}
 	}
 }
 
@@ -606,27 +740,47 @@ fail:
 static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
 		      struct ieee80211_rx_status *stats)
 {
+	struct zd_mac *mac = zd_hw_mac(hw);
 	struct sk_buff *skb;
 	struct sk_buff_head *q;
 	unsigned long flags;
+	int found = 0;
+	int i, position = 0;
 
 	if (!ieee80211_is_ack(rx_hdr->frame_control))
 		return 0;
 
-	q = &zd_hw_mac(hw)->ack_wait_queue;
+	q = &mac->ack_wait_queue;
 	spin_lock_irqsave(&q->lock, flags);
 	skb_queue_walk(q, skb) {
 		struct ieee80211_hdr *tx_hdr;
 
+		position ++;
+
+		if (mac->ack_pending && skb_queue_is_first(q, skb))
+		    continue;
+
 		tx_hdr = (struct ieee80211_hdr *)skb->data;
 		if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN)))
 		{
-			__skb_unlink(skb, q);
-			tx_status(hw, skb, stats->signal, 1);
-			goto out;
+			found = 1;
+			break;
 		}
 	}
-out:
+
+	if (found) {
+		for (i=1; i<position; i++) {
+			skb = __skb_dequeue(q);
+			zd_mac_tx_status(hw, skb,
+					 mac->ack_pending ? mac->ack_signal : 0,
+					 NULL);
+			mac->ack_pending = 0;
+		}
+
+		mac->ack_pending = 1;
+		mac->ack_signal = stats->signal;
+	}
+
 	spin_unlock_irqrestore(&q->lock, flags);
 	return 1;
 }
@@ -674,9 +828,6 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
 	stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
 	stats.band = IEEE80211_BAND_2GHZ;
 	stats.signal = status->signal_strength;
-	stats.qual = zd_rx_qual_percent(buffer,
-		                          length - sizeof(struct rx_status),
-		                          status);
 
 	rate = zd_rx_rate(buffer, status);
 
@@ -709,6 +860,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
 		skb_reserve(skb, 2);
 	}
 
+	/* FIXME : could we avoid this big memcpy ? */
 	memcpy(skb_put(skb, length), buffer, length);
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
@@ -835,12 +987,13 @@ static void zd_op_configure_filter(struc
 	changed_flags &= SUPPORTED_FIF_FLAGS;
 	*new_flags &= SUPPORTED_FIF_FLAGS;
 
-	/* changed_flags is always populated but this driver
-	 * doesn't support all FIF flags so its possible we don't
-	 * need to do anything */
-	if (!changed_flags)
-		return;
-
+	/*
+	 * If multicast parameter (as returned by zd_op_prepare_multicast)
+	 * has changed, no bit in changed_flags is set. To handle this
+	 * situation, we do not return if changed_flags is 0. If we do so,
+	 * we will have some issue with IPv6 which uses multicast for link
+	 * layer address resolution.
+	 */
 	if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI))
 		zd_mc_add_all(&hash);
 
@@ -999,7 +1152,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(str
 	hw->queues = 1;
 	hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
 
+	/*
+	 * Tell mac80211 that we support multi rate retries
+	 */
+	hw->max_rates = IEEE80211_TX_MAX_RATES;
+	hw->max_rate_tries = 18;	/* 9 rates * 2 retries/rate */
+
 	skb_queue_head_init(&mac->ack_wait_queue);
+	mac->ack_pending = 0;
 
 	zd_chip_init(&mac->chip, hw, intf);
 	housekeeping_init(mac);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_mac.h linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.h
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_mac.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_mac.h	2010-02-24 13:52:17.000000000 -0500
@@ -140,6 +140,21 @@ struct rx_status {
 #define ZD_RX_CRC16_ERROR		0x40
 #define ZD_RX_ERROR			0x80
 
+struct tx_retry_rate {
+	int count;	/* number of valid element in rate[] array */
+	int rate[10];	/* retry rates, described by an index in zd_rates[] */
+};
+
+struct tx_status {
+	u8 type;	/* must always be 0x01 : USB_INT_TYPE */
+	u8 id;		/* must always be 0xa0 : USB_INT_ID_RETRY_FAILED */
+	u8 rate;
+	u8 pad;
+	u8 mac[ETH_ALEN];
+	u8 retry;
+	u8 failure;
+} __attribute__((packed));
+
 enum mac_flags {
 	MAC_FIXED_CHANNEL = 0x01,
 };
@@ -150,7 +165,7 @@ struct housekeeping {
 
 #define ZD_MAC_STATS_BUFFER_SIZE 16
 
-#define ZD_MAC_MAX_ACK_WAITERS 10
+#define ZD_MAC_MAX_ACK_WAITERS 50
 
 struct zd_mac {
 	struct zd_chip chip;
@@ -184,6 +199,12 @@ struct zd_mac {
 
 	/* whether to pass control frames to stack */
 	unsigned int pass_ctrl:1;
+
+	/* whether we have received a 802.11 ACK that is pending */
+	unsigned int ack_pending:1;
+
+	/* signal strength of the last 802.11 ACK received */
+	int ack_signal;
 };
 
 #define ZD_REGDOMAIN_FCC	0x10
@@ -279,7 +300,7 @@ int zd_mac_preinit_hw(struct ieee80211_h
 int zd_mac_init_hw(struct ieee80211_hw *hw);
 
 int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length);
-void zd_mac_tx_failed(struct ieee80211_hw *hw);
+void zd_mac_tx_failed(struct urb *urb);
 void zd_mac_tx_to_dev(struct sk_buff *skb, int error);
 
 #ifdef DEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c
--- linux-libre-2.6.32-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2013-05-03 14:04:17.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2013-05-03 12:11:50.000000000 -0400
@@ -62,6 +62,7 @@ static struct usb_device_id usb_ids[] =
 	{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
 	/* ZD1211B */
 	{ USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0409, 0x0248), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
@@ -318,6 +319,8 @@ error:
 	return r;
 }
 
+/*(DEBLOBBED)*/
+
 /* Read data from device address space using "firmware interface" which does
  * not require firmware to be loaded. */
 int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
@@ -419,7 +422,7 @@ static void int_urb_complete(struct urb
 		handle_regs_int(urb);
 		break;
 	case USB_INT_ID_RETRY_FAILED:
-		zd_mac_tx_failed(zd_usb_to_hw(urb->context));
+		zd_mac_tx_failed(urb);
 		break;
 	default:
 		dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb,
@@ -553,6 +556,8 @@ static void handle_rx_packet(struct zd_u
 
 	if (length < sizeof(struct rx_length_info)) {
 		/* It's not a complete packet anyhow. */
+		printk("%s: invalid, small RX packet : %d\n",
+		       __func__, length);
 		return;
 	}
 	length_info = (struct rx_length_info *)
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/xen-netfront.c linux-libre-2.6.33-gnu1/drivers/net/xen-netfront.c
--- linux-libre-2.6.32-gnu1/drivers/net/xen-netfront.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/xen-netfront.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@
 #include <linux/mm.h>
 #include <net/ip.h>
 
+#include <xen/xen.h>
 #include <xen/xenbus.h>
 #include <xen/events.h>
 #include <xen/page.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/xilinx_emaclite.c linux-libre-2.6.33-gnu1/drivers/net/xilinx_emaclite.c
--- linux-libre-2.6.32-gnu1/drivers/net/xilinx_emaclite.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/xilinx_emaclite.c	2010-02-24 13:52:17.000000000 -0500
@@ -660,7 +660,7 @@ static int xemaclite_open(struct net_dev
 	xemaclite_set_mac_address(lp, dev->dev_addr);
 
 	/* Grab the IRQ */
-	retval = request_irq(dev->irq, &xemaclite_interrupt, 0, dev->name, dev);
+	retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev);
 	if (retval) {
 		dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n",
 			dev->irq);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/xtsonic.c linux-libre-2.6.33-gnu1/drivers/net/xtsonic.c
--- linux-libre-2.6.32-gnu1/drivers/net/xtsonic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/xtsonic.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,7 +92,7 @@ static unsigned short known_revisions[]
 
 static int xtsonic_open(struct net_device *dev)
 {
-	if (request_irq(dev->irq,&sonic_interrupt,IRQF_DISABLED,"sonic",dev)) {
+	if (request_irq(dev->irq,sonic_interrupt,IRQF_DISABLED,"sonic",dev)) {
 		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
 		       dev->name, dev->irq);
 		return -EAGAIN;
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/yellowfin.c linux-libre-2.6.33-gnu1/drivers/net/yellowfin.c
--- linux-libre-2.6.32-gnu1/drivers/net/yellowfin.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/yellowfin.c	2010-02-24 13:52:17.000000000 -0500
@@ -579,7 +579,7 @@ static int yellowfin_open(struct net_dev
 	/* Reset the chip. */
 	iowrite32(0x80000000, ioaddr + DMACtrl);
 
-	ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+	ret = request_irq(dev->irq, yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
 	if (ret)
 		return ret;
 
@@ -944,8 +944,8 @@ static irqreturn_t yellowfin_interrupt(i
 			dev_kfree_skb_irq(skb);
 			yp->tx_skbuff[entry] = NULL;
 		}
-		if (yp->tx_full
-			&& yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE - 4) {
+		if (yp->tx_full &&
+		    yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE - 4) {
 			/* The ring is no longer full, clear tbusy. */
 			yp->tx_full = 0;
 			netif_wake_queue(dev);
@@ -1014,8 +1014,8 @@ static irqreturn_t yellowfin_interrupt(i
 			}
 #endif
 
-			if (yp->tx_full
-				&& yp->cur_tx - dirty_tx < TX_QUEUE_SIZE - 2) {
+			if (yp->tx_full &&
+			    yp->cur_tx - dirty_tx < TX_QUEUE_SIZE - 2) {
 				/* The ring is no longer full, clear tbusy. */
 				yp->tx_full = 0;
 				netif_wake_queue(dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/net/znet.c linux-libre-2.6.33-gnu1/drivers/net/znet.c
--- linux-libre-2.6.32-gnu1/drivers/net/znet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/net/znet.c	2010-02-24 13:52:17.000000000 -0500
@@ -103,8 +103,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-/* This include could be elsewhere, since it is not wireless specific */
-#include "wireless/i82593.h"
+#include <linux/i82593.h>
 
 static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n";
 
@@ -170,7 +169,7 @@ static int znet_request_resources (struc
 {
 	struct znet_private *znet = netdev_priv(dev);
 
-	if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
+	if (request_irq (dev->irq, znet_interrupt, 0, "ZNet", dev))
 		goto failed;
 	if (request_dma (znet->rx_dma, "ZNet rx"))
 		goto free_irq;
@@ -698,8 +697,8 @@ static void znet_rx(struct net_device *d
 	   the same area of the backwards links we now have.  This allows us to
 	   pass packets to the upper layers in the order they were received --
 	   important for fast-path sequential operations. */
-	 while (znet->rx_start + cur_frame_end_offset != znet->rx_cur
-			&& ++boguscount < 5) {
+	while (znet->rx_start + cur_frame_end_offset != znet->rx_cur &&
+	       ++boguscount < 5) {
 		unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
 		int count, status;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/of/base.c linux-libre-2.6.33-gnu1/drivers/of/base.c
--- linux-libre-2.6.32-gnu1/drivers/of/base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/of/base.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,7 +9,8 @@
  *
  *  Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
  *
- *  Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell.
+ *  Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
+ *  Grant Likely.
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -82,6 +83,29 @@ struct property *of_find_property(const
 }
 EXPORT_SYMBOL(of_find_property);
 
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev:	Previous node or NULL to start iteration
+ *		of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+	struct device_node *np;
+
+	read_lock(&devtree_lock);
+	np = prev ? prev->allnext : allnodes;
+	for (; np != NULL; np = np->allnext)
+		if (of_node_get(np))
+			break;
+	of_node_put(prev);
+	read_unlock(&devtree_lock);
+	return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
 /*
  * Find a property with a given name for a given node
  * and return the value.
diff -druNp linux-libre-2.6.32-gnu1/drivers/of/platform.c linux-libre-2.6.33-gnu1/drivers/of/platform.c
--- linux-libre-2.6.32-gnu1/drivers/of/platform.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/of/platform.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,47 +65,322 @@ static int of_platform_device_remove(str
 	return 0;
 }
 
-static int of_platform_device_suspend(struct device *dev, pm_message_t state)
+static void of_platform_device_shutdown(struct device *dev)
 {
 	struct of_device *of_dev = to_of_device(dev);
 	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
-	int error = 0;
 
-	if (dev->driver && drv->suspend)
-		error = drv->suspend(of_dev, state);
-	return error;
+	if (dev->driver && drv->shutdown)
+		drv->shutdown(of_dev);
 }
 
-static int of_platform_device_resume(struct device * dev)
+#ifdef CONFIG_PM_SLEEP
+
+static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct of_device *of_dev = to_of_device(dev);
 	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
-	int error = 0;
+	int ret = 0;
 
-	if (dev->driver && drv->resume)
-		error = drv->resume(of_dev);
-	return error;
+	if (dev->driver && drv->suspend)
+		ret = drv->suspend(of_dev, mesg);
+	return ret;
 }
 
-static void of_platform_device_shutdown(struct device *dev)
+static int of_platform_legacy_resume(struct device *dev)
 {
 	struct of_device *of_dev = to_of_device(dev);
 	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	int ret = 0;
 
-	if (dev->driver && drv->shutdown)
-		drv->shutdown(of_dev);
+	if (dev->driver && drv->resume)
+		ret = drv->resume(of_dev);
+	return ret;
+}
+
+static int of_platform_pm_prepare(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (drv && drv->pm && drv->pm->prepare)
+		ret = drv->pm->prepare(dev);
+
+	return ret;
 }
 
+static void of_platform_pm_complete(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv && drv->pm && drv->pm->complete)
+		drv->pm->complete(dev);
+}
+
+#ifdef CONFIG_SUSPEND
+
+static int of_platform_pm_suspend(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend)
+			ret = drv->pm->suspend(dev);
+	} else {
+		ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_suspend_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend_noirq)
+			ret = drv->pm->suspend_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_resume(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume)
+			ret = drv->pm->resume(dev);
+	} else {
+		ret = of_platform_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_resume_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume_noirq)
+			ret = drv->pm->resume_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define of_platform_pm_suspend		NULL
+#define of_platform_pm_resume		NULL
+#define of_platform_pm_suspend_noirq	NULL
+#define of_platform_pm_resume_noirq	NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int of_platform_pm_freeze(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze)
+			ret = drv->pm->freeze(dev);
+	} else {
+		ret = of_platform_legacy_suspend(dev, PMSG_FREEZE);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_freeze_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze_noirq)
+			ret = drv->pm->freeze_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_thaw(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw)
+			ret = drv->pm->thaw(dev);
+	} else {
+		ret = of_platform_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_thaw_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw_noirq)
+			ret = drv->pm->thaw_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_poweroff(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff)
+			ret = drv->pm->poweroff(dev);
+	} else {
+		ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_poweroff_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff_noirq)
+			ret = drv->pm->poweroff_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_restore(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore)
+			ret = drv->pm->restore(dev);
+	} else {
+		ret = of_platform_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int of_platform_pm_restore_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore_noirq)
+			ret = drv->pm->restore_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define of_platform_pm_freeze		NULL
+#define of_platform_pm_thaw		NULL
+#define of_platform_pm_poweroff		NULL
+#define of_platform_pm_restore		NULL
+#define of_platform_pm_freeze_noirq	NULL
+#define of_platform_pm_thaw_noirq		NULL
+#define of_platform_pm_poweroff_noirq	NULL
+#define of_platform_pm_restore_noirq	NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+static struct dev_pm_ops of_platform_dev_pm_ops = {
+	.prepare = of_platform_pm_prepare,
+	.complete = of_platform_pm_complete,
+	.suspend = of_platform_pm_suspend,
+	.resume = of_platform_pm_resume,
+	.freeze = of_platform_pm_freeze,
+	.thaw = of_platform_pm_thaw,
+	.poweroff = of_platform_pm_poweroff,
+	.restore = of_platform_pm_restore,
+	.suspend_noirq = of_platform_pm_suspend_noirq,
+	.resume_noirq = of_platform_pm_resume_noirq,
+	.freeze_noirq = of_platform_pm_freeze_noirq,
+	.thaw_noirq = of_platform_pm_thaw_noirq,
+	.poweroff_noirq = of_platform_pm_poweroff_noirq,
+	.restore_noirq = of_platform_pm_restore_noirq,
+};
+
+#define OF_PLATFORM_PM_OPS_PTR	(&of_platform_dev_pm_ops)
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define OF_PLATFORM_PM_OPS_PTR	NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
 int of_bus_type_init(struct bus_type *bus, const char *name)
 {
 	bus->name = name;
 	bus->match = of_platform_bus_match;
 	bus->probe = of_platform_device_probe;
 	bus->remove = of_platform_device_remove;
-	bus->suspend = of_platform_device_suspend;
-	bus->resume = of_platform_device_resume;
 	bus->shutdown = of_platform_device_shutdown;
 	bus->dev_attrs = of_platform_device_attrs;
+	bus->pm = OF_PLATFORM_PM_OPS_PTR;
 	return bus_register(bus);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/oprofile/cpu_buffer.c linux-libre-2.6.33-gnu1/drivers/oprofile/cpu_buffer.c
--- linux-libre-2.6.32-gnu1/drivers/oprofile/cpu_buffer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/oprofile/cpu_buffer.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,7 @@
  */
 static struct ring_buffer *op_ring_buffer_read;
 static struct ring_buffer *op_ring_buffer_write;
-DEFINE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
+DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer);
 
 static void wq_sync_buffer(struct work_struct *work);
 
@@ -61,8 +61,7 @@ unsigned long oprofile_get_cpu_buffer_si
 
 void oprofile_cpu_buffer_inc_smpl_lost(void)
 {
-	struct oprofile_cpu_buffer *cpu_buf
-		= &__get_cpu_var(cpu_buffer);
+	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(op_cpu_buffer);
 
 	cpu_buf->sample_lost_overflow++;
 }
@@ -95,7 +94,7 @@ int alloc_cpu_buffers(void)
 		goto fail;
 
 	for_each_possible_cpu(i) {
-		struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
+		struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i);
 
 		b->last_task = NULL;
 		b->last_is_kernel = -1;
@@ -122,7 +121,7 @@ void start_cpu_work(void)
 	work_enabled = 1;
 
 	for_each_online_cpu(i) {
-		struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
+		struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i);
 
 		/*
 		 * Spread the work by 1 jiffy per cpu so they dont all
@@ -139,7 +138,7 @@ void end_cpu_work(void)
 	work_enabled = 0;
 
 	for_each_online_cpu(i) {
-		struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
+		struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i);
 
 		cancel_delayed_work(&b->work);
 	}
@@ -330,7 +329,7 @@ static inline void
 __oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
 			  unsigned long event, int is_kernel)
 {
-	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
+	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(op_cpu_buffer);
 	unsigned long backtrace = oprofile_backtrace_depth;
 
 	/*
@@ -375,7 +374,7 @@ oprofile_write_reserve(struct op_entry *
 {
 	struct op_sample *sample;
 	int is_kernel = !user_mode(regs);
-	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
+	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(op_cpu_buffer);
 
 	cpu_buf->sample_received++;
 
@@ -430,13 +429,13 @@ int oprofile_write_commit(struct op_entr
 
 void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
 {
-	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
+	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(op_cpu_buffer);
 	log_sample(cpu_buf, pc, 0, is_kernel, event);
 }
 
 void oprofile_add_trace(unsigned long pc)
 {
-	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
+	struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(op_cpu_buffer);
 
 	if (!cpu_buf->tracing)
 		return;
diff -druNp linux-libre-2.6.32-gnu1/drivers/oprofile/cpu_buffer.h linux-libre-2.6.33-gnu1/drivers/oprofile/cpu_buffer.h
--- linux-libre-2.6.32-gnu1/drivers/oprofile/cpu_buffer.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/oprofile/cpu_buffer.h	2010-02-24 13:52:17.000000000 -0500
@@ -50,7 +50,7 @@ struct oprofile_cpu_buffer {
 	struct delayed_work work;
 };
 
-DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
+DECLARE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer);
 
 /*
  * Resets the cpu buffer to a sane state.
@@ -60,7 +60,7 @@ DECLARE_PER_CPU(struct oprofile_cpu_buff
  */
 static inline void op_cpu_buffer_reset(int cpu)
 {
-	struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu);
+	struct oprofile_cpu_buffer *cpu_buf = &per_cpu(op_cpu_buffer, cpu);
 
 	cpu_buf->last_is_kernel = -1;
 	cpu_buf->last_task = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/oprofile/oprofile_stats.c linux-libre-2.6.33-gnu1/drivers/oprofile/oprofile_stats.c
--- linux-libre-2.6.32-gnu1/drivers/oprofile/oprofile_stats.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/oprofile/oprofile_stats.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@ void oprofile_reset_stats(void)
 	int i;
 
 	for_each_possible_cpu(i) {
-		cpu_buf = &per_cpu(cpu_buffer, i);
+		cpu_buf = &per_cpu(op_cpu_buffer, i);
 		cpu_buf->sample_received = 0;
 		cpu_buf->sample_lost_overflow = 0;
 		cpu_buf->backtrace_aborted = 0;
@@ -51,7 +51,7 @@ void oprofile_create_stats_files(struct
 		return;
 
 	for_each_possible_cpu(i) {
-		cpu_buf = &per_cpu(cpu_buffer, i);
+		cpu_buf = &per_cpu(op_cpu_buffer, i);
 		snprintf(buf, 10, "cpu%d", i);
 		cpudir = oprofilefs_mkdir(sb, dir, buf);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/ccio-dma.c linux-libre-2.6.33-gnu1/drivers/parisc/ccio-dma.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/ccio-dma.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/ccio-dma.c	2010-02-24 13:52:17.000000000 -0500
@@ -650,7 +650,7 @@ ccio_clear_io_tlb(struct ioc *ioc, dma_a
  * Mark the I/O Pdir entries invalid and blow away the corresponding I/O
  * TLB entries.
  *
- * FIXME: at some threshhold it might be "cheaper" to just blow
+ * FIXME: at some threshold it might be "cheaper" to just blow
  *        away the entire I/O TLB instead of individual entries.
  *
  * FIXME: Uturn has 256 TLB entries. We don't need to purge every
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/dino.c linux-libre-2.6.33-gnu1/drivers/parisc/dino.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/dino.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/dino.c	2010-02-24 13:52:17.000000000 -0500
@@ -354,7 +354,7 @@ static unsigned int dino_startup_irq(uns
 }
 
 static struct irq_chip dino_interrupt_type = {
-	.typename	= "GSC-PCI",
+	.name		= "GSC-PCI",
 	.startup	= dino_startup_irq,
 	.shutdown	= dino_disable_irq,
 	.enable		= dino_enable_irq, 
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/eisa.c linux-libre-2.6.33-gnu1/drivers/parisc/eisa.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/eisa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/eisa.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,7 @@ static unsigned int eisa_startup_irq(uns
 }
 
 static struct irq_chip eisa_interrupt_type = {
-	.typename =	"EISA",
+	.name	 =	"EISA",
 	.startup =	eisa_startup_irq,
 	.shutdown =	eisa_disable_irq,
 	.enable =	eisa_enable_irq,
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/eisa_eeprom.c linux-libre-2.6.33-gnu1/drivers/parisc/eisa_eeprom.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/eisa_eeprom.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/eisa_eeprom.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,17 +75,8 @@ static ssize_t eisa_eeprom_read(struct f
 	return ret;
 }
 
-static int eisa_eeprom_ioctl(struct inode *inode, struct file *file, 
-			   unsigned int cmd,
-			   unsigned long arg)
-{
-	return -ENOTTY;
-}
-
 static int eisa_eeprom_open(struct inode *inode, struct file *file)
 {
-	cycle_kernel_lock();
-
 	if (file->f_mode & FMODE_WRITE)
 		return -EINVAL;
    
@@ -104,7 +95,6 @@ static const struct file_operations eisa
 	.owner =	THIS_MODULE,
 	.llseek =	eisa_eeprom_llseek,
 	.read =		eisa_eeprom_read,
-	.ioctl =	eisa_eeprom_ioctl,
 	.open =		eisa_eeprom_open,
 	.release =	eisa_eeprom_release,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/gsc.c linux-libre-2.6.33-gnu1/drivers/parisc/gsc.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/gsc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/gsc.c	2010-02-24 13:52:17.000000000 -0500
@@ -149,7 +149,7 @@ static unsigned int gsc_asic_startup_irq
 }
 
 static struct irq_chip gsc_asic_interrupt_type = {
-	.typename =	"GSC-ASIC",
+	.name	 =	"GSC-ASIC",
 	.startup =	gsc_asic_startup_irq,
 	.shutdown =	gsc_asic_disable_irq,
 	.enable =	gsc_asic_enable_irq,
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/iosapic.c linux-libre-2.6.33-gnu1/drivers/parisc/iosapic.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/iosapic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/iosapic.c	2010-02-24 13:52:17.000000000 -0500
@@ -730,7 +730,7 @@ static int iosapic_set_affinity_irq(unsi
 #endif
 
 static struct irq_chip iosapic_interrupt_type = {
-	.typename =	"IO-SAPIC-level",
+	.name	 =	"IO-SAPIC-level",
 	.startup =	iosapic_startup_irq,
 	.shutdown =	iosapic_disable_irq,
 	.enable =	iosapic_enable_irq,
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/led.c linux-libre-2.6.33-gnu1/drivers/parisc/led.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/led.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/led.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,6 +38,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/reboot.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/ctype.h>
 #include <linux/blkdev.h>
 #include <linux/workqueue.h>
@@ -147,41 +148,34 @@ device_initcall(start_task);
 static void (*led_func_ptr) (unsigned char) __read_mostly;
 
 #ifdef CONFIG_PROC_FS
-static int led_proc_read(char *page, char **start, off_t off, int count, 
-	int *eof, void *data)
+static int led_proc_show(struct seq_file *m, void *v)
 {
-	char *out = page;
-	int len;
-
-	switch ((long)data)
+	switch ((long)m->private)
 	{
 	case LED_NOLCD:
-		out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
-		out += sprintf(out, "Disk IO: %d\n", led_diskio);
-		out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
+		seq_printf(m, "Heartbeat: %d\n", led_heartbeat);
+		seq_printf(m, "Disk IO: %d\n", led_diskio);
+		seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx);
 		break;
 	case LED_HASLCD:
-		out += sprintf(out, "%s\n", lcd_text);
+		seq_printf(m, "%s\n", lcd_text);
 		break;
 	default:
-		*eof = 1;
 		return 0;
 	}
+	return 0;
+}
 
-	len = out - page - off;
-	if (len < count) {
-		*eof = 1;
-		if (len <= 0) return 0;
-	} else {
-		len = count;
-	}
-	*start = page + off;
-	return len;
+static int led_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, led_proc_show, PDE(inode)->data);
 }
 
-static int led_proc_write(struct file *file, const char *buf, 
-	unsigned long count, void *data)
+
+static ssize_t led_proc_write(struct file *file, const char *buf,
+	size_t count, loff_t *pos)
 {
+	void *data = PDE(file->f_path.dentry->d_inode)->data;
 	char *cur, lbuf[count + 1];
 	int d;
 
@@ -234,6 +228,15 @@ parse_error:
 	return -EINVAL;
 }
 
+static const struct file_operations led_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= led_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= led_proc_write,
+};
+
 static int __init led_create_procfs(void)
 {
 	struct proc_dir_entry *proc_pdc_root = NULL;
@@ -243,19 +246,15 @@ static int __init led_create_procfs(void
 
 	proc_pdc_root = proc_mkdir("pdc", 0);
 	if (!proc_pdc_root) return -1;
-	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+	ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+				&led_proc_fops, (void *)LED_NOLCD); /* LED */
 	if (!ent) return -1;
-	ent->data = (void *)LED_NOLCD; /* LED */
-	ent->read_proc = led_proc_read;
-	ent->write_proc = led_proc_write;
 
 	if (led_type == LED_HASLCD)
 	{
-		ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+		ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
+					&led_proc_fops, (void *)LED_HASLCD); /* LCD */
 		if (!ent) return -1;
-		ent->data = (void *)LED_HASLCD; /* LCD */
-		ent->read_proc = led_proc_read;
-		ent->write_proc = led_proc_write;
 	}
 
 	return 0;
@@ -352,11 +351,9 @@ static __inline__ int led_get_net_activi
 
 	rx_total = tx_total = 0;
 	
-	/* we are running as a workqueue task, so locking dev_base 
-	 * for reading should be OK */
-	read_lock(&dev_base_lock);
+	/* we are running as a workqueue task, so we can use an RCU lookup */
 	rcu_read_lock();
-	for_each_netdev(&init_net, dev) {
+	for_each_netdev_rcu(&init_net, dev) {
 	    const struct net_device_stats *stats;
 	    struct in_device *in_dev = __in_dev_get_rcu(dev);
 	    if (!in_dev || !in_dev->ifa_list)
@@ -368,7 +365,6 @@ static __inline__ int led_get_net_activi
 	    tx_total += stats->tx_packets;
 	}
 	rcu_read_unlock();
-	read_unlock(&dev_base_lock);
 
 	retval = 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/pdc_stable.c linux-libre-2.6.33-gnu1/drivers/parisc/pdc_stable.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/pdc_stable.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/pdc_stable.c	2010-02-24 13:52:17.000000000 -0500
@@ -779,12 +779,9 @@ static ssize_t pdcs_auto_write(struct ko
 	read_unlock(&pathentry->rw_lock);
 	
 	DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
-			
-	temp = in;
-	
-	while (*temp && isspace(*temp))
-		temp++;
-	
+
+	temp = skip_spaces(in);
+
 	c = *temp++ - '0';
 	if ((c != 0) && (c != 1))
 		goto parse_error;
diff -druNp linux-libre-2.6.32-gnu1/drivers/parisc/superio.c linux-libre-2.6.33-gnu1/drivers/parisc/superio.c
--- linux-libre-2.6.32-gnu1/drivers/parisc/superio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parisc/superio.c	2010-02-24 13:52:17.000000000 -0500
@@ -326,7 +326,7 @@ static unsigned int superio_startup_irq(
 }
 
 static struct irq_chip superio_interrupt_type = {
-	.typename =	SUPERIO,
+	.name	 =	SUPERIO,
 	.startup =	superio_startup_irq,
 	.shutdown =	superio_disable_irq,
 	.enable =	superio_enable_irq,
diff -druNp linux-libre-2.6.32-gnu1/drivers/parport/parport_cs.c linux-libre-2.6.33-gnu1/drivers/parport/parport_cs.c
--- linux-libre-2.6.32-gnu1/drivers/parport/parport_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parport/parport_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,14 +67,6 @@ MODULE_LICENSE("Dual MPL/GPL");
 
 INT_MODULE_PARM(epp_mode, 1);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"parport_cs.c 1.29 2002/10/11 06:57:41 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -103,7 +95,7 @@ static int parport_probe(struct pcmcia_d
 {
     parport_info_t *info;
 
-    DEBUG(0, "parport_attach()\n");
+    dev_dbg(&link->dev, "parport_attach()\n");
 
     /* Create new parport device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -114,7 +106,6 @@ static int parport_probe(struct pcmcia_d
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -132,7 +123,7 @@ static int parport_probe(struct pcmcia_d
 
 static void parport_detach(struct pcmcia_device *link)
 {
-    DEBUG(0, "parport_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "parport_detach\n");
 
     parport_cs_release(link);
 
@@ -147,9 +138,6 @@ static void parport_detach(struct pcmcia
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int parport_config_check(struct pcmcia_device *p_dev,
 				cistpl_cftable_entry_t *cfg,
 				cistpl_cftable_entry_t *dflt,
@@ -178,18 +166,20 @@ static int parport_config(struct pcmcia_
 {
     parport_info_t *info = link->priv;
     struct parport *p;
-    int last_ret, last_fn;
+    int ret;
 
-    DEBUG(0, "parport_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "parport_config\n");
 
-    last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
-    if (last_ret) {
-	    cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, parport_config_check, NULL);
+    if (ret)
 	    goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
 			      link->irq.AssignedIRQ, PARPORT_DMA_NONE,
@@ -213,8 +203,6 @@ static int parport_config(struct pcmcia_
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     parport_cs_release(link);
     return -ENODEV;
@@ -232,7 +220,7 @@ static void parport_cs_release(struct pc
 {
 	parport_info_t *info = link->priv;
 
-	DEBUG(0, "parport_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "parport_release\n");
 
 	if (info->ndev) {
 		struct parport *p = info->port;
diff -druNp linux-libre-2.6.32-gnu1/drivers/parport/parport_mfc3.c linux-libre-2.6.33-gnu1/drivers/parport/parport_mfc3.c
--- linux-libre-2.6.32-gnu1/drivers/parport/parport_mfc3.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parport/parport_mfc3.c	2010-02-24 13:52:17.000000000 -0500
@@ -386,7 +386,7 @@ static void __exit parport_mfc3_exit(voi
 		if (!this_port[i])
 			continue;
 		parport_remove_port(this_port[i]);
-		if (!this_port[i]->irq != PARPORT_IRQ_NONE) {
+		if (this_port[i]->irq != PARPORT_IRQ_NONE) {
 			if (--use_cnt == 0) 
 				free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/parport/parport_pc.c linux-libre-2.6.33-gnu1/drivers/parport/parport_pc.c
--- linux-libre-2.6.32-gnu1/drivers/parport/parport_pc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parport/parport_pc.c	2010-02-24 13:52:17.000000000 -0500
@@ -3403,7 +3403,7 @@ static int __init parport_parse_param(co
 		*val = automatic;
 	else if (!strncmp(s, "none", 4))
 		*val = none;
-	else if (nofifo && !strncmp(s, "nofifo", 4))
+	else if (nofifo && !strncmp(s, "nofifo", 6))
 		*val = nofifo;
 	else {
 		char *ep;
diff -druNp linux-libre-2.6.32-gnu1/drivers/parport/procfs.c linux-libre-2.6.33-gnu1/drivers/parport/procfs.c
--- linux-libre-2.6.32-gnu1/drivers/parport/procfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/parport/procfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -233,10 +233,10 @@ static int do_hardware_modes (ctl_table
 	return copy_to_user(result, buffer, len) ? -EFAULT : 0;
 }
 
-#define PARPORT_PORT_DIR(CHILD) { .ctl_name = 0, .procname = NULL, .mode = 0555, .child = CHILD }
-#define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \
+#define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD }
+#define PARPORT_PARPORT_DIR(CHILD) { .procname = "parport", \
                                      .mode = 0555, .child = CHILD }
-#define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD }
+#define PARPORT_DEV_DIR(CHILD) { .procname = "dev", .mode = 0555, .child = CHILD }
 #define PARPORT_DEVICES_ROOT_DIR  {  .procname = "devices", \
                                     .mode = 0555, .child = NULL }
 
@@ -270,7 +270,7 @@ static const struct parport_sysctl_table
 			.data		= NULL,
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
-			.proc_handler	= &proc_dointvec_minmax,
+			.proc_handler	= proc_dointvec_minmax,
 			.extra1		= (void*) &parport_min_spintime_value,
 			.extra2		= (void*) &parport_max_spintime_value
 		},
@@ -279,28 +279,28 @@ static const struct parport_sysctl_table
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_hardware_base_addr
+			.proc_handler	= do_hardware_base_addr
 		},
 		{
 			.procname	= "irq",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_hardware_irq
+			.proc_handler	= do_hardware_irq
 		},
 		{
 			.procname	= "dma",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_hardware_dma
+			.proc_handler	= do_hardware_dma
 		},
 		{
 			.procname	= "modes",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_hardware_modes
+			.proc_handler	= do_hardware_modes
 		},
 		PARPORT_DEVICES_ROOT_DIR,
 #ifdef CONFIG_PARPORT_1284
@@ -309,35 +309,35 @@ static const struct parport_sysctl_table
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_autoprobe
+			.proc_handler	= do_autoprobe
 		},
 		{
 			.procname	= "autoprobe0",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	=  &do_autoprobe
+			.proc_handler	= do_autoprobe
 		},
 		{
 			.procname	= "autoprobe1",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_autoprobe
+			.proc_handler	= do_autoprobe
 		},
 		{
 			.procname	= "autoprobe2",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_autoprobe
+			.proc_handler	= do_autoprobe
 		},
 		{
 			.procname	= "autoprobe3",
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_autoprobe
+			.proc_handler	= do_autoprobe
 		},
 #endif /* IEEE 1284 support */
 		{}
@@ -348,7 +348,7 @@ static const struct parport_sysctl_table
 			.data		= NULL,
 			.maxlen		= 0,
 			.mode		= 0444,
-			.proc_handler	= &do_active_device
+			.proc_handler	= do_active_device
 		},
 		{}
 	},
@@ -386,14 +386,13 @@ parport_device_sysctl_template = {
 			.data		= NULL,
 			.maxlen		= sizeof(unsigned long),
 			.mode		= 0644,
-			.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+			.proc_handler	= proc_doulongvec_ms_jiffies_minmax,
 			.extra1		= (void*) &parport_min_timeslice_value,
 			.extra2		= (void*) &parport_max_timeslice_value
 		},
 	},
 	{
 		{
-			.ctl_name	= 0,
 			.procname	= NULL,
 			.data		= NULL,
 			.maxlen		= 0,
@@ -438,7 +437,7 @@ parport_default_sysctl_table = {
 			.data		= &parport_default_timeslice,
 			.maxlen		= sizeof(parport_default_timeslice),
 			.mode		= 0644,
-			.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+			.proc_handler	= proc_doulongvec_ms_jiffies_minmax,
 			.extra1		= (void*) &parport_min_timeslice_value,
 			.extra2		= (void*) &parport_max_timeslice_value
 		},
@@ -447,7 +446,7 @@ parport_default_sysctl_table = {
 			.data		= &parport_default_spintime,
 			.maxlen		= sizeof(parport_default_spintime),
 			.mode		= 0644,
-			.proc_handler	= &proc_dointvec_minmax,
+			.proc_handler	= proc_dointvec_minmax,
 			.extra1		= (void*) &parport_min_spintime_value,
 			.extra2		= (void*) &parport_max_spintime_value
 		},
@@ -455,7 +454,6 @@ parport_default_sysctl_table = {
 	},
 	{
 		{
-			.ctl_name	= DEV_PARPORT_DEFAULT,
 			.procname	= "default",
 			.mode		= 0555,
 			.child		= parport_default_sysctl_table.vars
@@ -495,7 +493,6 @@ int parport_proc_register(struct parport
 		t->vars[6 + i].extra2 = &port->probe_info[i];
 
 	t->port_dir[0].procname = port->name;
-	t->port_dir[0].ctl_name = 0;
 
 	t->port_dir[0].child = t->vars;
 	t->parport_dir[0].child = t->port_dir;
@@ -534,11 +531,9 @@ int parport_device_proc_register(struct
 	t->dev_dir[0].child = t->parport_dir;
 	t->parport_dir[0].child = t->port_dir;
 	t->port_dir[0].procname = port->name;
-	t->port_dir[0].ctl_name = 0;
 	t->port_dir[0].child = t->devices_root_dir;
 	t->devices_root_dir[0].child = t->device_dir;
 
-	t->device_dir[0].ctl_name = 0;
 	t->device_dir[0].procname = device->name;
 	t->device_dir[0].child = t->vars;
 	t->vars[0].data = &device->timeslice;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/dmar.c linux-libre-2.6.33-gnu1/drivers/pci/dmar.c
--- linux-libre-2.6.32-gnu1/drivers/pci/dmar.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/dmar.c	2010-02-24 13:52:17.000000000 -0500
@@ -320,7 +320,7 @@ found:
 	for (bus = dev->bus; bus; bus = bus->parent) {
 		struct pci_dev *bridge = bus->self;
 
-		if (!bridge || !bridge->is_pcie ||
+		if (!bridge || !pci_is_pcie(bridge) ||
 		    bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
 			return 0;
 
@@ -339,6 +339,35 @@ found:
 }
 #endif
 
+#ifdef CONFIG_ACPI_NUMA
+static int __init
+dmar_parse_one_rhsa(struct acpi_dmar_header *header)
+{
+	struct acpi_dmar_rhsa *rhsa;
+	struct dmar_drhd_unit *drhd;
+
+	rhsa = (struct acpi_dmar_rhsa *)header;
+	for_each_drhd_unit(drhd) {
+		if (drhd->reg_base_addr == rhsa->base_address) {
+			int node = acpi_map_pxm_to_node(rhsa->proximity_domain);
+
+			if (!node_online(node))
+				node = -1;
+			drhd->iommu->node = node;
+			return 0;
+		}
+	}
+	WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
+	     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+	     drhd->reg_base_addr,
+	     dmi_get_system_info(DMI_BIOS_VENDOR),
+	     dmi_get_system_info(DMI_BIOS_VERSION),
+	     dmi_get_system_info(DMI_PRODUCT_VERSION));
+
+	return 0;
+}
+#endif
+
 static void __init
 dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
 {
@@ -458,7 +487,9 @@ parse_dmar_table(void)
 #endif
 			break;
 		case ACPI_DMAR_HARDWARE_AFFINITY:
-			/* We don't do anything with RHSA (yet?) */
+#ifdef CONFIG_ACPI_NUMA
+			ret = dmar_parse_one_rhsa(entry_header);
+#endif
 			break;
 		default:
 			printk(KERN_WARNING PREFIX
@@ -582,6 +613,8 @@ int __init dmar_table_init(void)
 	return 0;
 }
 
+static int bios_warned;
+
 int __init check_zero_address(void)
 {
 	struct acpi_table_dmar *dmar;
@@ -601,6 +634,9 @@ int __init check_zero_address(void)
 		}
 
 		if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
+			void __iomem *addr;
+			u64 cap, ecap;
+
 			drhd = (void *)entry_header;
 			if (!drhd->address) {
 				/* Promote an attitude of violence to a BIOS engineer today */
@@ -609,17 +645,40 @@ int __init check_zero_address(void)
 				     dmi_get_system_info(DMI_BIOS_VENDOR),
 				     dmi_get_system_info(DMI_BIOS_VERSION),
 				     dmi_get_system_info(DMI_PRODUCT_VERSION));
-#ifdef CONFIG_DMAR
-				dmar_disabled = 1;
-#endif
-				return 0;
+				bios_warned = 1;
+				goto failed;
+			}
+
+			addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
+			if (!addr ) {
+				printk("IOMMU: can't validate: %llx\n", drhd->address);
+				goto failed;
+			}
+			cap = dmar_readq(addr + DMAR_CAP_REG);
+			ecap = dmar_readq(addr + DMAR_ECAP_REG);
+			early_iounmap(addr, VTD_PAGE_SIZE);
+			if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
+				/* Promote an attitude of violence to a BIOS engineer today */
+				WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
+				     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+				      drhd->address,
+				      dmi_get_system_info(DMI_BIOS_VENDOR),
+				      dmi_get_system_info(DMI_BIOS_VERSION),
+				      dmi_get_system_info(DMI_PRODUCT_VERSION));
+				bios_warned = 1;
+				goto failed;
 			}
-			break;
 		}
 
 		entry_header = ((void *)entry_header + entry_header->length);
 	}
 	return 1;
+
+failed:
+#ifdef CONFIG_DMAR
+	dmar_disabled = 1;
+#endif
+	return 0;
 }
 
 void __init detect_intel_iommu(void)
@@ -645,9 +704,15 @@ void __init detect_intel_iommu(void)
 			       "x2apic and Intr-remapping.\n");
 #endif
 #ifdef CONFIG_DMAR
-		if (ret && !no_iommu && !iommu_detected && !swiotlb &&
-		    !dmar_disabled)
+		if (ret && !no_iommu && !iommu_detected && !dmar_disabled) {
 			iommu_detected = 1;
+			/* Make sure ACS will be enabled */
+			pci_request_acs();
+		}
+#endif
+#ifdef CONFIG_X86
+		if (ret)
+			x86_init.iommu.iommu_init = intel_iommu_init;
 #endif
 	}
 	early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
@@ -664,6 +729,18 @@ int alloc_iommu(struct dmar_drhd_unit *d
 	int agaw = 0;
 	int msagaw = 0;
 
+	if (!drhd->reg_base_addr) {
+		if (!bios_warned) {
+			WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
+			     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+			     dmi_get_system_info(DMI_BIOS_VENDOR),
+			     dmi_get_system_info(DMI_BIOS_VERSION),
+			     dmi_get_system_info(DMI_PRODUCT_VERSION));
+			bios_warned = 1;
+		}
+		return -EINVAL;
+	}
+
 	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
 	if (!iommu)
 		return -ENOMEM;
@@ -680,13 +757,16 @@ int alloc_iommu(struct dmar_drhd_unit *d
 	iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
 
 	if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
-		/* Promote an attitude of violence to a BIOS engineer today */
-		WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
-		     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
-		     drhd->reg_base_addr,
-		     dmi_get_system_info(DMI_BIOS_VENDOR),
-		     dmi_get_system_info(DMI_BIOS_VERSION),
-		     dmi_get_system_info(DMI_PRODUCT_VERSION));
+		if (!bios_warned) {
+			/* Promote an attitude of violence to a BIOS engineer today */
+			WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
+			     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+			     drhd->reg_base_addr,
+			     dmi_get_system_info(DMI_BIOS_VENDOR),
+			     dmi_get_system_info(DMI_BIOS_VERSION),
+			     dmi_get_system_info(DMI_PRODUCT_VERSION));
+			bios_warned = 1;
+		}
 		goto err_unmap;
 	}
 
@@ -709,6 +789,8 @@ int alloc_iommu(struct dmar_drhd_unit *d
 	iommu->agaw = agaw;
 	iommu->msagaw = msagaw;
 
+	iommu->node = -1;
+
 	/* the registers might be more than one page */
 	map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
 		cap_max_fault_reg_offset(iommu->cap));
@@ -1050,6 +1132,7 @@ static void __dmar_enable_qi(struct inte
 int dmar_enable_qi(struct intel_iommu *iommu)
 {
 	struct q_inval *qi;
+	struct page *desc_page;
 
 	if (!ecap_qis(iommu->ecap))
 		return -ENOENT;
@@ -1066,13 +1149,16 @@ int dmar_enable_qi(struct intel_iommu *i
 
 	qi = iommu->qi;
 
-	qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC));
-	if (!qi->desc) {
+
+	desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0);
+	if (!desc_page) {
 		kfree(qi);
 		iommu->qi = 0;
 		return -ENOMEM;
 	}
 
+	qi->desc = page_address(desc_page);
+
 	qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
 	if (!qi->desc_status) {
 		free_page((unsigned long) qi->desc);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpi_pcihp.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpi_pcihp.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2010-02-24 13:52:17.000000000 -0500
@@ -362,6 +362,8 @@ int acpi_get_hp_hw_control_from_firmware
 		status = acpi_pci_osc_control_set(handle, flags);
 		if (ACPI_SUCCESS(status))
 			goto got_one;
+		if (status == AE_SUPPORT)
+			goto no_control;
 		kfree(string.pointer);
 		string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
 	}
@@ -394,10 +396,9 @@ int acpi_get_hp_hw_control_from_firmware
 		if (ACPI_FAILURE(status))
 			break;
 	}
-
+no_control:
 	dbg("Cannot get control of hotplug hardware for pci %s\n",
 	    pci_name(pdev));
-
 	kfree(string.pointer);
 	return -ENODEV;
 got_one:
@@ -471,7 +472,7 @@ int acpi_pci_detect_ejectable(acpi_handl
 		return found;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
-			    check_hotplug, (void *)&found, NULL);
+			    check_hotplug, NULL, (void *)&found, NULL);
 	return found;
 }
 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp_glue.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,8 +52,6 @@
 #include "acpiphp.h"
 
 static LIST_HEAD(bridge_list);
-static LIST_HEAD(ioapic_list);
-static DEFINE_SPINLOCK(ioapic_list_lock);
 
 #define MY_NAME "acpiphp_glue"
 
@@ -266,7 +264,7 @@ static int detect_ejectable_slots(acpi_h
 	int found = acpi_pci_detect_ejectable(handle);
 	if (!found) {
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				    is_pci_dock_device, (void *)&found, NULL);
+				    is_pci_dock_device, NULL, (void *)&found, NULL);
 	}
 	return found;
 }
@@ -281,7 +279,7 @@ static void init_bridge_misc(struct acpi
 
 	/* register all slot objects under this bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
-				     register_slot, bridge, NULL);
+				     register_slot, NULL, bridge, NULL);
 	if (ACPI_FAILURE(status)) {
 		list_del(&bridge->list);
 		return;
@@ -311,17 +309,13 @@ static void init_bridge_misc(struct acpi
 /* find acpiphp_func from acpiphp_bridge */
 static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
 {
-	struct list_head *node, *l;
 	struct acpiphp_bridge *bridge;
 	struct acpiphp_slot *slot;
 	struct acpiphp_func *func;
 
-	list_for_each(node, &bridge_list) {
-		bridge = list_entry(node, struct acpiphp_bridge, list);
+	list_for_each_entry(bridge, &bridge_list, list) {
 		for (slot = bridge->slots; slot; slot = slot->next) {
-			list_for_each(l, &slot->funcs) {
-				func = list_entry(l, struct acpiphp_func,
-							sibling);
+			list_for_each_entry(func, &slot->funcs, sibling) {
 				if (func->handle == handle)
 					return func;
 			}
@@ -447,7 +441,7 @@ find_p2p_bridge(acpi_handle handle, u32
 
 	/* search P2P bridges under this p2p bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL);
+				     find_p2p_bridge, NULL, NULL, NULL);
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
 
@@ -485,7 +479,7 @@ static int add_bridge(acpi_handle handle
 
 	/* search P2P bridges under this host bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, NULL, NULL);
+				     find_p2p_bridge, NULL, NULL, NULL);
 
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
@@ -495,21 +489,19 @@ static int add_bridge(acpi_handle handle
 
 static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
 {
-	struct list_head *head;
-	list_for_each(head, &bridge_list) {
-		struct acpiphp_bridge *bridge = list_entry(head,
-						struct acpiphp_bridge, list);
+	struct acpiphp_bridge *bridge;
+
+	list_for_each_entry(bridge, &bridge_list, list)
 		if (bridge->handle == handle)
 			return bridge;
-	}
 
 	return NULL;
 }
 
 static void cleanup_bridge(struct acpiphp_bridge *bridge)
 {
-	struct list_head *list, *tmp;
-	struct acpiphp_slot *slot;
+	struct acpiphp_slot *slot, *next;
+	struct acpiphp_func *func, *tmp;
 	acpi_status status;
 	acpi_handle handle = bridge->handle;
 
@@ -530,10 +522,8 @@ static void cleanup_bridge(struct acpiph
 
 	slot = bridge->slots;
 	while (slot) {
-		struct acpiphp_slot *next = slot->next;
-		list_for_each_safe (list, tmp, &slot->funcs) {
-			struct acpiphp_func *func;
-			func = list_entry(list, struct acpiphp_func, sibling);
+		next = slot->next;
+		list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
 			if (is_dock_device(func->handle)) {
 				unregister_hotplug_dock_device(func->handle);
 				unregister_dock_notifier(&func->nb);
@@ -545,7 +535,7 @@ static void cleanup_bridge(struct acpiph
 				if (ACPI_FAILURE(status))
 					err("failed to remove notify handler\n");
 			}
-			list_del(list);
+			list_del(&func->sibling);
 			kfree(func);
 		}
 		acpiphp_unregister_hotplug_slot(slot);
@@ -573,7 +563,7 @@ cleanup_p2p_bridge(acpi_handle handle, u
 	/* cleanup p2p bridges under this P2P bridge
 	   in a depth-first manner */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				cleanup_p2p_bridge, NULL, NULL);
+				cleanup_p2p_bridge, NULL, NULL, NULL);
 
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (bridge)
@@ -589,7 +579,7 @@ static void remove_bridge(acpi_handle ha
 	/* cleanup p2p bridges under this host bridge
 	   in a depth-first manner */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-				(u32)1, cleanup_p2p_bridge, NULL, NULL);
+				(u32)1, cleanup_p2p_bridge, NULL, NULL, NULL);
 
 	/*
 	 * On root bridges with hotplug slots directly underneath (ie,
@@ -606,204 +596,17 @@ static void remove_bridge(acpi_handle ha
 					   handle_hotplug_event_bridge);
 }
 
-static struct pci_dev * get_apic_pci_info(acpi_handle handle)
-{
-	struct pci_dev *dev;
-
-	dev = acpi_get_pci_dev(handle);
-	if (!dev)
-		return NULL;
-
-	if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
-	    (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
-	{
-		pci_dev_put(dev);
-		return NULL;
-	}
-
-	return dev;
-}
-
-static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
-{
-	acpi_status status;
-	int result = -1;
-	unsigned long long gsb;
-	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	union acpi_object *obj;
-	void *table;
-
-	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
-	if (ACPI_SUCCESS(status)) {
-		*gsi_base = (u32)gsb;
-		return 0;
-	}
-
-	status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
-	if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
-		return -1;
-
-	obj = buffer.pointer;
-	if (obj->type != ACPI_TYPE_BUFFER)
-		goto out;
-
-	table = obj->buffer.pointer;
-	switch (((struct acpi_subtable_header *)table)->type) {
-	case ACPI_MADT_TYPE_IO_SAPIC:
-		*gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base;
-		result = 0;
-		break;
-	case ACPI_MADT_TYPE_IO_APIC:
-		*gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base;
-		result = 0;
-		break;
-	default:
-		break;
-	}
- out:
-	kfree(buffer.pointer);
-	return result;
-}
-
-static acpi_status
-ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	unsigned long long sta;
-	acpi_handle tmp;
-	struct pci_dev *pdev;
-	u32 gsi_base;
-	u64 phys_addr;
-	struct acpiphp_ioapic *ioapic;
-
-	/* Evaluate _STA if present */
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
-		return AE_CTRL_DEPTH;
-
-	/* Scan only PCI bus scope */
-	status = acpi_get_handle(handle, "_HID", &tmp);
-	if (ACPI_SUCCESS(status))
-		return AE_CTRL_DEPTH;
-
-	if (get_gsi_base(handle, &gsi_base))
-		return AE_OK;
-
-	ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL);
-	if (!ioapic)
-		return AE_NO_MEMORY;
-
-	pdev = get_apic_pci_info(handle);
-	if (!pdev)
-		goto exit_kfree;
-
-	if (pci_enable_device(pdev))
-		goto exit_pci_dev_put;
-
-	pci_set_master(pdev);
-
-	if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)"))
-		goto exit_pci_disable_device;
-
-	phys_addr = pci_resource_start(pdev, 0);
-	if (acpi_register_ioapic(handle, phys_addr, gsi_base))
-		goto exit_pci_release_region;
-
-	ioapic->gsi_base = gsi_base;
-	ioapic->dev = pdev;
-	spin_lock(&ioapic_list_lock);
-	list_add_tail(&ioapic->list, &ioapic_list);
-	spin_unlock(&ioapic_list_lock);
-
-	return AE_OK;
-
- exit_pci_release_region:
-	pci_release_region(pdev, 0);
- exit_pci_disable_device:
-	pci_disable_device(pdev);
- exit_pci_dev_put:
-	pci_dev_put(pdev);
- exit_kfree:
-	kfree(ioapic);
-
-	return AE_OK;
-}
-
-static acpi_status
-ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	unsigned long long sta;
-	acpi_handle tmp;
-	u32 gsi_base;
-	struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
-
-	/* Evaluate _STA if present */
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
-		return AE_CTRL_DEPTH;
-
-	/* Scan only PCI bus scope */
-	status = acpi_get_handle(handle, "_HID", &tmp);
-	if (ACPI_SUCCESS(status))
-		return AE_CTRL_DEPTH;
-
-	if (get_gsi_base(handle, &gsi_base))
-		return AE_OK;
-
-	acpi_unregister_ioapic(handle, gsi_base);
-
-	spin_lock(&ioapic_list_lock);
-	list_for_each_entry_safe(pos, n, &ioapic_list, list) {
-		if (pos->gsi_base != gsi_base)
-			continue;
-		ioapic = pos;
-		list_del(&ioapic->list);
-		break;
-	}
-	spin_unlock(&ioapic_list_lock);
-
-	if (!ioapic)
-		return AE_OK;
-
-	pci_release_region(ioapic->dev, 0);
-	pci_disable_device(ioapic->dev);
-	pci_dev_put(ioapic->dev);
-	kfree(ioapic);
-
-	return AE_OK;
-}
-
-static int acpiphp_configure_ioapics(acpi_handle handle)
-{
-	ioapic_add(handle, 0, NULL, NULL);
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-			    ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
-	return 0;
-}
-
-static int acpiphp_unconfigure_ioapics(acpi_handle handle)
-{
-	ioapic_remove(handle, 0, NULL, NULL);
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-			    ACPI_UINT32_MAX, ioapic_remove, NULL, NULL);
-	return 0;
-}
-
 static int power_on_slot(struct acpiphp_slot *slot)
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 	int retval = 0;
 
 	/* if already enabled, just skip */
 	if (slot->flags & SLOT_POWEREDON)
 		goto err_exit;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_PS0) {
 			dbg("%s: executing _PS0\n", __func__);
 			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
@@ -829,7 +632,6 @@ static int power_off_slot(struct acpiphp
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 
 	int retval = 0;
 
@@ -837,9 +639,7 @@ static int power_off_slot(struct acpiphp
 	if ((slot->flags & SLOT_POWEREDON) == 0)
 		goto err_exit;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_PS3) {
 			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
 			if (ACPI_FAILURE(status)) {
@@ -920,12 +720,6 @@ static int acpiphp_bus_add(struct acpiph
 			-ret_val);
 		goto acpiphp_bus_add_out;
 	}
-	/*
-	 * try to start anyway.  We could have failed to add
-	 * simply because this bus had previously been added
-	 * on another add.  Don't bother with the return value
-	 * we just keep going.
-	 */
 	ret_val = acpi_bus_start(device);
 
 acpiphp_bus_add_out:
@@ -966,7 +760,6 @@ static int __ref enable_device(struct ac
 {
 	struct pci_dev *dev;
 	struct pci_bus *bus = slot->bridge->pci_bus;
-	struct list_head *l;
 	struct acpiphp_func *func;
 	int retval = 0;
 	int num, max, pass;
@@ -1006,21 +799,16 @@ static int __ref enable_device(struct ac
 		}
 	}
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
+	list_for_each_entry(func, &slot->funcs, sibling)
 		acpiphp_bus_add(func);
-	}
 
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
 	acpiphp_set_hpp_values(bus);
-	list_for_each_entry(func, &slot->funcs, sibling)
-		acpiphp_configure_ioapics(func->handle);
 	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
 						  func->function));
 		if (!dev)
@@ -1091,7 +879,6 @@ static int disable_device(struct acpiphp
 	}
 
 	list_for_each_entry(func, &slot->funcs, sibling) {
-		acpiphp_unconfigure_ioapics(func->handle);
 		acpiphp_bus_trim(func->handle);
 	}
 
@@ -1119,12 +906,9 @@ static unsigned int get_slot_status(stru
 	acpi_status status;
 	unsigned long long sta = 0;
 	u32 dvid;
-	struct list_head *l;
 	struct acpiphp_func *func;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		if (func->flags & FUNC_HAS_STA) {
 			status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
 			if (ACPI_SUCCESS(status) && sta)
@@ -1152,13 +936,10 @@ int acpiphp_eject_slot(struct acpiphp_sl
 {
 	acpi_status status;
 	struct acpiphp_func *func;
-	struct list_head *l;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		/* We don't want to call _EJ0 on non-existing functions. */
 		if ((func->flags & FUNC_HAS_EJ0)) {
 			/* _EJ0 method take one argument */
@@ -1275,7 +1056,6 @@ static int acpiphp_configure_bridge (acp
 	acpiphp_sanitize_bus(bus);
 	acpiphp_set_hpp_values(bus);
 	pci_enable_bridges(bus);
-	acpiphp_configure_ioapics(handle);
 	return 0;
 }
 
@@ -1367,7 +1147,7 @@ static void handle_hotplug_event_bridge(
 	bridge = acpiphp_handle_to_bridge(handle);
 	if (type == ACPI_NOTIFY_BUS_CHECK) {
 		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
-			count_sub_bridges, &num_sub_bridges, NULL);
+			count_sub_bridges, NULL, &num_sub_bridges, NULL);
 	}
 
 	if (!bridge && !num_sub_bridges) {
@@ -1388,7 +1168,7 @@ static void handle_hotplug_event_bridge(
 		}
 		if (num_sub_bridges)
 			acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-				ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL);
+				ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL);
 		break;
 
 	case ACPI_NOTIFY_DEVICE_CHECK:
@@ -1512,7 +1292,7 @@ int __init acpiphp_glue_init(void)
 	int num = 0;
 
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
+			ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
 
 	if (num <= 0)
 		return -1;
@@ -1542,7 +1322,7 @@ int __init acpiphp_get_num_slots(void)
 	struct acpiphp_bridge *bridge;
 	int num_slots = 0;
 
-	list_for_each_entry (bridge, &bridge_list, list) {
+	list_for_each_entry(bridge, &bridge_list, list) {
 		dbg("Bus %04x:%02x has %d slot%s\n",
 				pci_domain_nr(bridge->pci_bus),
 				bridge->pci_bus->number, bridge->nr_slots,
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp.h linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp.h
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp.h	2010-02-24 13:52:17.000000000 -0500
@@ -146,12 +146,6 @@ struct acpiphp_attention_info
 	struct module *owner;
 };
 
-struct acpiphp_ioapic {
-	struct pci_dev *dev;
-	u32 gsi_base;
-	struct list_head list;
-};
-
 /* PCI bus bridge HID */
 #define ACPI_PCI_HOST_HID		"PNP0A03"
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp_ibm.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_ibm.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/acpiphp_ibm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/acpiphp_ibm.c	2010-02-24 13:52:17.000000000 -0500
@@ -434,7 +434,7 @@ static int __init ibm_acpiphp_init(void)
 	dbg("%s\n", __func__);
 
 	if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			ACPI_UINT32_MAX, ibm_find_acpi_device,
+			ACPI_UINT32_MAX, ibm_find_acpi_device, NULL,
 			&ibm_acpi_handle, NULL) != FOUND_APCI) {
 		err("%s: acpi_walk_namespace failed\n", __func__);
 		retval = -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/ibmphp_hpc.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_hpc.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/ibmphp_hpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/ibmphp_hpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -890,7 +890,7 @@ static int poll_hpc(void *data)
 			msleep(POLL_INTERVAL_SEC * 1000);
 
 			if (kthread_should_stop())
-				break;
+				goto out_sleep;
 			
 			down (&semOperations);
 			
@@ -904,6 +904,7 @@ static int poll_hpc(void *data)
 		/* give up the hardware semaphore */
 		up (&semOperations);
 		/* sleep for a short time just for good measure */
+out_sleep:
 		msleep(100);
 	}
 	up (&sem_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/Makefile linux-libre-2.6.33-gnu1/drivers/pci/hotplug/Makefile
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -6,18 +6,22 @@ obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplu
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
 
-# pciehp should be linked before acpiphp in order to allow the native driver
-# to attempt to bind first. We can then fall back to generic support.
+# native drivers should be linked before acpiphp in order to allow the
+# native driver to attempt to bind first. We can then fall back to
+# generic support.
 
 obj-$(CONFIG_HOTPLUG_PCI_PCIE)		+= pciehp.o
-obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
-obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM)	+= acpiphp_ibm.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
 obj-$(CONFIG_HOTPLUG_PCI_SHPC)		+= shpchp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)		+= rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
 obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
+obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
+
+# acpiphp_ibm extends acpiphp, so should be linked afterwards.
+
+obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM)	+= acpiphp_ibm.o
 
 # Link this last so it doesn't claim devices that have a real hotplug driver
 obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakephp.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_acpi.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,7 +87,8 @@ static int __init dummy_probe(struct pci
 	/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
 	if (pciehp_get_hp_hw_control_from_firmware(pdev))
 		return -ENODEV;
-	if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
+	pos = pci_pcie_cap(pdev);
+	if (!pos)
 		return -ENODEV;
 	pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
 	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_core.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_core.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,18 +72,6 @@ static int get_adapter_status	(struct ho
 static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
-static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
-	.set_attention_status =	set_attention_status,
-	.enable_slot =		enable_slot,
-	.disable_slot =		disable_slot,
-	.get_power_status =	get_power_status,
-	.get_attention_status =	get_attention_status,
-	.get_latch_status =	get_latch_status,
-	.get_adapter_status =	get_adapter_status,
-  	.get_max_bus_speed =	get_max_bus_speed,
-  	.get_cur_bus_speed =	get_cur_bus_speed,
-};
-
 /**
  * release_slot - free up the memory used by a slot
  * @hotplug_slot: slot to free
@@ -95,6 +83,7 @@ static void release_slot(struct hotplug_
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, hotplug_slot_name(hotplug_slot));
 
+	kfree(hotplug_slot->ops);
 	kfree(hotplug_slot->info);
 	kfree(hotplug_slot);
 }
@@ -104,6 +93,7 @@ static int init_slot(struct controller *
 	struct slot *slot = ctrl->slot;
 	struct hotplug_slot *hotplug = NULL;
 	struct hotplug_slot_info *info = NULL;
+	struct hotplug_slot_ops *ops = NULL;
 	char name[SLOT_NAME_SIZE];
 	int retval = -ENOMEM;
 
@@ -115,11 +105,28 @@ static int init_slot(struct controller *
 	if (!info)
 		goto out;
 
+	/* Setup hotplug slot ops */
+	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
+	if (!ops)
+		goto out;
+	ops->enable_slot = enable_slot;
+	ops->disable_slot = disable_slot;
+	ops->get_power_status = get_power_status;
+	ops->get_adapter_status = get_adapter_status;
+	ops->get_max_bus_speed = get_max_bus_speed;
+	ops->get_cur_bus_speed = get_cur_bus_speed;
+	if (MRL_SENS(ctrl))
+		ops->get_latch_status = get_latch_status;
+	if (ATTN_LED(ctrl)) {
+		ops->get_attention_status = get_attention_status;
+		ops->set_attention_status = set_attention_status;
+	}
+
 	/* register this slot with the hotplug pci core */
 	hotplug->info = info;
 	hotplug->private = slot;
 	hotplug->release = &release_slot;
-	hotplug->ops = &pciehp_hotplug_slot_ops;
+	hotplug->ops = ops;
 	slot->hotplug_slot = hotplug;
 	snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl));
 
@@ -128,17 +135,12 @@ static int init_slot(struct controller *
 		 ctrl->pcie->port->subordinate->number, PSN(ctrl));
 	retval = pci_hp_register(hotplug,
 				 ctrl->pcie->port->subordinate, 0, name);
-	if (retval) {
+	if (retval)
 		ctrl_err(ctrl,
 			 "pci_hp_register failed with error %d\n", retval);
-		goto out;
-	}
-	get_power_status(hotplug, &info->power_status);
-	get_attention_status(hotplug, &info->attention_status);
-	get_latch_status(hotplug, &info->latch_status);
-	get_adapter_status(hotplug, &info->adapter_status);
 out:
 	if (retval) {
+		kfree(ops);
 		kfree(info);
 		kfree(hotplug);
 	}
@@ -160,12 +162,7 @@ static int set_attention_status(struct h
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	hotplug_slot->info->attention_status = status;
-
-	if (ATTN_LED(slot->ctrl))
-		pciehp_set_attention_status(slot, status);
-
-	return 0;
+	return pciehp_set_attention_status(slot, status);
 }
 
 
@@ -193,92 +190,62 @@ static int disable_slot(struct hotplug_s
 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	retval = pciehp_get_power_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->power_status;
-
-	return 0;
+	return pciehp_get_power_status(slot, value);
 }
 
 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		  __func__, slot_name(slot));
 
-	retval = pciehp_get_attention_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->attention_status;
-
-	return 0;
+	return pciehp_get_attention_status(slot, value);
 }
 
 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_latch_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->latch_status;
-
-	return 0;
+	return pciehp_get_latch_status(slot, value);
 }
 
 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_adapter_status(slot, value);
-	if (retval < 0)
-		*value = hotplug_slot->info->adapter_status;
-
-	return 0;
+	return pciehp_get_adapter_status(slot, value);
 }
 
 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
 				enum pci_bus_speed *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_max_link_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
+	return pciehp_get_max_link_speed(slot, value);
 }
 
 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	struct slot *slot = hotplug_slot->private;
-	int retval;
 
 	ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n",
 		 __func__, slot_name(slot));
 
-	retval = pciehp_get_cur_link_speed(slot, value);
-	if (retval < 0)
-		*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
+	return pciehp_get_cur_link_speed(slot, value);
 }
 
 static int pciehp_probe(struct pcie_device *dev)
@@ -286,14 +253,13 @@ static int pciehp_probe(struct pcie_devi
 	int rc;
 	struct controller *ctrl;
 	struct slot *slot;
-	u8 value;
-	struct pci_dev *pdev = dev->port;
+	u8 occupied, poweron;
 
 	if (pciehp_force)
 		dev_info(&dev->device,
 			 "Bypassing BIOS check for pciehp use on %s\n",
-			 pci_name(pdev));
-	else if (pciehp_get_hp_hw_control_from_firmware(pdev))
+			 pci_name(dev->port));
+	else if (pciehp_get_hp_hw_control_from_firmware(dev->port))
 		goto err_out_none;
 
 	ctrl = pcie_init(dev);
@@ -318,23 +284,18 @@ static int pciehp_probe(struct pcie_devi
 	rc = pcie_init_notification(ctrl);
 	if (rc) {
 		ctrl_err(ctrl, "Notification initialization failed\n");
-		goto err_out_release_ctlr;
+		goto err_out_free_ctrl_slot;
 	}
 
 	/* Check if slot is occupied */
 	slot = ctrl->slot;
-	pciehp_get_adapter_status(slot, &value);
-	if (value) {
-		if (pciehp_force)
-			pciehp_enable_slot(slot);
-	} else {
-		/* Power off slot if not occupied */
-		if (POWER_CTRL(ctrl)) {
-			rc = pciehp_power_off_slot(slot);
-			if (rc)
-				goto err_out_free_ctrl_slot;
-		}
-	}
+	pciehp_get_adapter_status(slot, &occupied);
+	pciehp_get_power_status(slot, &poweron);
+	if (occupied && pciehp_force)
+		pciehp_enable_slot(slot);
+	/* If empty slot's power status is on, turn power off */
+	if (!occupied && poweron && POWER_CTRL(ctrl))
+		pciehp_power_off_slot(slot);
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_ctrl.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_ctrl.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_ctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_ctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,23 +142,9 @@ u8 pciehp_handle_power_fault(struct slot
 
 	/* power fault */
 	ctrl_dbg(ctrl, "Power fault interrupt received\n");
-
-	if (!pciehp_query_power_fault(p_slot)) {
-		/*
-		 * power fault Cleared
-		 */
-		ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
-			  slot_name(p_slot));
-		event_type = INT_POWER_FAULT_CLEAR;
-	} else {
-		/*
-		 *   power fault
-		 */
-		ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot));
-		event_type = INT_POWER_FAULT;
-		ctrl_info(ctrl, "Power fault bit %x set\n", 0);
-	}
-
+	ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
+	event_type = INT_POWER_FAULT;
+	ctrl_info(ctrl, "Power fault bit %x set\n", 0);
 	queue_interrupt_event(p_slot, event_type);
 
 	return 1;
@@ -224,13 +210,12 @@ static int board_added(struct slot *p_sl
 	retval = pciehp_check_link_status(ctrl);
 	if (retval) {
 		ctrl_err(ctrl, "Failed to check link status\n");
-		set_slot_off(ctrl, p_slot);
-		return retval;
+		goto err_exit;
 	}
 
 	/* Check for a power fault */
-	if (pciehp_query_power_fault(p_slot)) {
-		ctrl_dbg(ctrl, "Power fault detected\n");
+	if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
+		ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
 		retval = -EIO;
 		goto err_exit;
 	}
@@ -363,25 +348,6 @@ void pciehp_queue_pushbutton_work(struct
 	mutex_unlock(&p_slot->lock);
 }
 
-static int update_slot_info(struct slot *slot)
-{
-	struct hotplug_slot_info *info;
-	int result;
-
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	pciehp_get_power_status(slot, &info->power_status);
-	pciehp_get_attention_status(slot, &info->attention_status);
-	pciehp_get_latch_status(slot, &info->latch_status);
-	pciehp_get_adapter_status(slot, &info->adapter_status);
-
-	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
-	kfree (info);
-	return result;
-}
-
 /*
  * Note: This function must be called with slot->lock held
  */
@@ -442,7 +408,6 @@ static void handle_button_press_event(st
 		 * to hot-add or hot-remove is undergoing
 		 */
 		ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
-		update_slot_info(p_slot);
 		break;
 	default:
 		ctrl_warn(ctrl, "Not a valid state\n");
@@ -500,11 +465,9 @@ static void interrupt_event_handler(stru
 		if (!HP_SUPR_RM(ctrl))
 			break;
 		ctrl_dbg(ctrl, "Surprise Removal\n");
-		update_slot_info(p_slot);
 		handle_surprise_event(p_slot);
 		break;
 	default:
-		update_slot_info(p_slot);
 		break;
 	}
 	mutex_unlock(&p_slot->lock);
@@ -547,9 +510,6 @@ int pciehp_enable_slot(struct slot *p_sl
 	if (rc) {
 		pciehp_get_latch_status(p_slot, &getstatus);
 	}
-
-	update_slot_info(p_slot);
-
 	return rc;
 }
 
@@ -590,10 +550,7 @@ int pciehp_disable_slot(struct slot *p_s
 		}
 	}
 
-	ret = remove_board(p_slot);
-	update_slot_info(p_slot);
-
-	return ret;
+	return remove_board(p_slot);
 }
 
 int pciehp_sysfs_enable_slot(struct slot *p_slot)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp.h linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp.h
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp.h	2010-02-24 13:52:17.000000000 -0500
@@ -91,7 +91,6 @@ struct controller {
 	struct slot *slot;
 	wait_queue_head_t queue;	/* sleep & wake process */
 	u32 slot_cap;
-	u8 cap_base;
 	struct timer_list poll_timer;
 	unsigned int cmd_busy:1;
 	unsigned int no_cmd_complete:1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_hpc.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_hpc.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,25 +45,25 @@ static atomic_t pciehp_num_controllers =
 static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_read_config_word(dev, ctrl->cap_base + reg, value);
+	return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_read_config_dword(dev, ctrl->cap_base + reg, value);
+	return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_write_config_word(dev, ctrl->cap_base + reg, value);
+	return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
 {
 	struct pci_dev *dev = ctrl->pcie->port;
-	return pci_write_config_dword(dev, ctrl->cap_base + reg, value);
+	return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 /* Power Control Command */
@@ -318,8 +318,8 @@ int pciehp_get_attention_status(struct s
 		return retval;
 	}
 
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
 	atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6;
 
@@ -356,8 +356,8 @@ int pciehp_get_power_status(struct slot
 		ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
 		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
 	pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10;
 
@@ -427,27 +427,24 @@ int pciehp_set_attention_status(struct s
 	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 cmd_mask;
-	int rc;
 
 	cmd_mask = PCI_EXP_SLTCTL_AIC;
 	switch (value) {
-		case 0 :	/* turn off */
-			slot_cmd = 0x00C0;
-			break;
-		case 1:		/* turn on */
-			slot_cmd = 0x0040;
-			break;
-		case 2:		/* turn blink */
-			slot_cmd = 0x0080;
-			break;
-		default:
-			return -1;
+	case 0 :	/* turn off */
+		slot_cmd = 0x00C0;
+		break;
+	case 1:		/* turn on */
+		slot_cmd = 0x0040;
+		break;
+	case 2:		/* turn blink */
+		slot_cmd = 0x0080;
+		break;
+	default:
+		return -EINVAL;
 	}
-	rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
-
-	return rc;
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
+	return pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 }
 
 void pciehp_green_led_on(struct slot *slot)
@@ -459,8 +456,8 @@ void pciehp_green_led_on(struct slot *sl
 	slot_cmd = 0x0100;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_off(struct slot *slot)
@@ -472,8 +469,8 @@ void pciehp_green_led_off(struct slot *s
 	slot_cmd = 0x0300;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_blink(struct slot *slot)
@@ -485,8 +482,8 @@ void pciehp_green_led_blink(struct slot
 	slot_cmd = 0x0200;
 	cmd_mask = PCI_EXP_SLTCTL_PIC;
 	pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 int pciehp_power_on_slot(struct slot * slot)
@@ -514,97 +511,38 @@ int pciehp_power_on_slot(struct slot * s
 			return retval;
 		}
 	}
+	ctrl->power_fault_detected = 0;
 
 	slot_cmd = POWER_ON;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	if (!pciehp_poll_mode) {
-		/* Enable power fault detection turned off at power off time */
-		slot_cmd |= PCI_EXP_SLTCTL_PFDE;
-		cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-	}
-
 	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 	if (retval) {
 		ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
 		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
-	ctrl->power_fault_detected = 0;
 	return retval;
 }
 
-static inline int pcie_mask_bad_dllp(struct controller *ctrl)
-{
-	struct pci_dev *dev = ctrl->pcie->port;
-	int pos;
-	u32 reg;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return 0;
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
-	if (reg & PCI_ERR_COR_BAD_DLLP)
-		return 0;
-	reg |= PCI_ERR_COR_BAD_DLLP;
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
-	return 1;
-}
-
-static inline void pcie_unmask_bad_dllp(struct controller *ctrl)
-{
-	struct pci_dev *dev = ctrl->pcie->port;
-	u32 reg;
-	int pos;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return;
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
-	if (!(reg & PCI_ERR_COR_BAD_DLLP))
-		return;
-	reg &= ~PCI_ERR_COR_BAD_DLLP;
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
-}
-
 int pciehp_power_off_slot(struct slot * slot)
 {
 	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 cmd_mask;
-	int retval = 0;
-	int changed;
-
-	/*
-	 * Set Bad DLLP Mask bit in Correctable Error Mask
-	 * Register. This is the workaround against Bad DLLP error
-	 * that sometimes happens during turning power off the slot
-	 * which conforms to PCI Express 1.0a spec.
-	 */
-	changed = pcie_mask_bad_dllp(ctrl);
+	int retval;
 
 	slot_cmd = POWER_OFF;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	if (!pciehp_poll_mode) {
-		/* Disable power fault detection */
-		slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
-		cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-	}
-
 	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 	if (retval) {
 		ctrl_err(ctrl, "Write command failed!\n");
-		retval = -1;
-		goto out;
+		return retval;
 	}
-	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
- out:
-	if (changed)
-		pcie_unmask_bad_dllp(ctrl);
-
-	return retval;
+	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
+	return 0;
 }
 
 static irqreturn_t pcie_isr(int irq, void *dev_id)
@@ -840,11 +778,19 @@ int pcie_enable_notification(struct cont
 {
 	u16 cmd, mask;
 
+	/*
+	 * TBD: Power fault detected software notification support.
+	 *
+	 * Power fault detected software notification is not enabled
+	 * now, because it caused power fault detected interrupt storm
+	 * on some machines. On those machines, power fault detected
+	 * bit in the slot status register was set again immediately
+	 * when it is cleared in the interrupt service routine, and
+	 * next power fault detected interrupt was notified again.
+	 */
 	cmd = PCI_EXP_SLTCTL_PDCE;
 	if (ATTN_BUTTN(ctrl))
 		cmd |= PCI_EXP_SLTCTL_ABPE;
-	if (POWER_CTRL(ctrl))
-		cmd |= PCI_EXP_SLTCTL_PFDE;
 	if (MRL_SENS(ctrl))
 		cmd |= PCI_EXP_SLTCTL_MRLSCE;
 	if (!pciehp_poll_mode)
@@ -866,7 +812,8 @@ static void pcie_disable_notification(st
 	u16 mask;
 	mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
 		PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
-		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE);
+		PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
+		PCI_EXP_SLTCTL_DLLSCE);
 	if (pcie_write_cmd(ctrl, 0, mask))
 		ctrl_warn(ctrl, "Cannot disable software notification\n");
 }
@@ -934,7 +881,8 @@ static inline void dbg_ctrl(struct contr
 		  pdev->subsystem_device);
 	ctrl_info(ctrl, "  Subsystem Vendor ID  : 0x%04x\n",
 		  pdev->subsystem_vendor);
-	ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n", ctrl->cap_base);
+	ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n",
+		  pci_pcie_cap(pdev));
 	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 		if (!pci_resource_len(pdev, i))
 			continue;
@@ -978,8 +926,7 @@ struct controller *pcie_init(struct pcie
 		goto abort;
 	}
 	ctrl->pcie = dev;
-	ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	if (!ctrl->cap_base) {
+	if (!pci_pcie_cap(pdev)) {
 		ctrl_err(ctrl, "Cannot find PCI Express capability\n");
 		goto abort_ctrl;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pci_hotplug_core.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pci_hotplug_core.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pci_hotplug_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pci_hotplug_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -68,26 +68,26 @@ static DEFINE_MUTEX(pci_hp_mutex);
 static char *pci_bus_speed_strings[] = {
 	"33 MHz PCI",		/* 0x00 */
 	"66 MHz PCI",		/* 0x01 */
-	"66 MHz PCIX", 		/* 0x02 */
-	"100 MHz PCIX",		/* 0x03 */
-	"133 MHz PCIX",		/* 0x04 */
+	"66 MHz PCI-X",		/* 0x02 */
+	"100 MHz PCI-X",	/* 0x03 */
+	"133 MHz PCI-X",	/* 0x04 */
 	NULL,			/* 0x05 */
 	NULL,			/* 0x06 */
 	NULL,			/* 0x07 */
 	NULL,			/* 0x08 */
-	"66 MHz PCIX 266",	/* 0x09 */
-	"100 MHz PCIX 266",	/* 0x0a */
-	"133 MHz PCIX 266",	/* 0x0b */
+	"66 MHz PCI-X 266",	/* 0x09 */
+	"100 MHz PCI-X 266",	/* 0x0a */
+	"133 MHz PCI-X 266",	/* 0x0b */
 	NULL,			/* 0x0c */
 	NULL,			/* 0x0d */
 	NULL,			/* 0x0e */
 	NULL,			/* 0x0f */
 	NULL,			/* 0x10 */
-	"66 MHz PCIX 533",	/* 0x11 */
-	"100 MHz PCIX 533",	/* 0x12 */
-	"133 MHz PCIX 533",	/* 0x13 */
-	"2.5 GT/s PCI-E",	/* 0x14 */
-	"5.0 GT/s PCI-E",	/* 0x15 */
+	"66 MHz PCI-X 533",	/* 0x11 */
+	"100 MHz PCI-X 533",	/* 0x12 */
+	"133 MHz PCI-X 533",	/* 0x13 */
+	"2.5 GT/s PCIe",	/* 0x14 */
+	"5.0 GT/s PCIe",	/* 0x15 */
 };
 
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pcihp_slot.c linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pcihp_slot.c
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/pcihp_slot.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/pcihp_slot.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,7 +43,7 @@ static void program_hpp_type0(struct pci
 		 * Perhaps we *should* use default settings for PCIe, but
 		 * pciehp didn't, so we won't either.
 		 */
-		if (dev->is_pcie)
+		if (pci_is_pcie(dev))
 			return;
 		dev_info(&dev->dev, "using default PCI settings\n");
 		hpp = &pci_default_type0;
@@ -102,7 +102,7 @@ static void program_hpp_type2(struct pci
 		return;
 
 	/* Find PCI Express capability */
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/hotplug/shpchp.h linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp.h
--- linux-libre-2.6.32-gnu1/drivers/pci/hotplug/shpchp.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/hotplug/shpchp.h	2010-02-24 13:52:17.000000000 -0500
@@ -121,7 +121,7 @@ struct controller {
 #define PCI_DEVICE_ID_AMD_GOLAM_7450	0x7450
 #define PCI_DEVICE_ID_AMD_POGO_7458	0x7458
 
-/* AMD PCIX bridge registers */
+/* AMD PCI-X bridge registers */
 #define PCIX_MEM_BASE_LIMIT_OFFSET	0x1C
 #define PCIX_MISCII_OFFSET		0x48
 #define PCIX_MISC_BRIDGE_ERRORS_OFFSET	0x80
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/intel-iommu.c linux-libre-2.6.33-gnu1/drivers/pci/intel-iommu.c
--- linux-libre-2.6.32-gnu1/drivers/pci/intel-iommu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/intel-iommu.c	2010-02-24 13:52:17.000000000 -0500
@@ -277,6 +277,7 @@ static int hw_pass_through = 1;
 
 struct dmar_domain {
 	int	id;			/* domain id */
+	int	nid;			/* node id */
 	unsigned long iommu_bmp;	/* bitmap of iommus this domain uses*/
 
 	struct list_head devices; 	/* all devices' list */
@@ -304,7 +305,7 @@ struct device_domain_info {
 	int segment;		/* PCI domain */
 	u8 bus;			/* PCI bus number */
 	u8 devfn;		/* PCI devfn number */
-	struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
+	struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */
 	struct intel_iommu *iommu; /* IOMMU used by this device */
 	struct dmar_domain *domain; /* pointer to domain */
 };
@@ -386,30 +387,14 @@ static struct kmem_cache *iommu_domain_c
 static struct kmem_cache *iommu_devinfo_cache;
 static struct kmem_cache *iommu_iova_cache;
 
-static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
-{
-	unsigned int flags;
-	void *vaddr;
-
-	/* trying to avoid low memory issues */
-	flags = current->flags & PF_MEMALLOC;
-	current->flags |= PF_MEMALLOC;
-	vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
-	current->flags &= (~PF_MEMALLOC | flags);
-	return vaddr;
-}
-
-
-static inline void *alloc_pgtable_page(void)
+static inline void *alloc_pgtable_page(int node)
 {
-	unsigned int flags;
-	void *vaddr;
+	struct page *page;
+	void *vaddr = NULL;
 
-	/* trying to avoid low memory issues */
-	flags = current->flags & PF_MEMALLOC;
-	current->flags |= PF_MEMALLOC;
-	vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
-	current->flags &= (~PF_MEMALLOC | flags);
+	page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
+	if (page)
+		vaddr = page_address(page);
 	return vaddr;
 }
 
@@ -420,7 +405,7 @@ static inline void free_pgtable_page(voi
 
 static inline void *alloc_domain_mem(void)
 {
-	return iommu_kmem_cache_alloc(iommu_domain_cache);
+	return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
 }
 
 static void free_domain_mem(void *vaddr)
@@ -430,7 +415,7 @@ static void free_domain_mem(void *vaddr)
 
 static inline void * alloc_devinfo_mem(void)
 {
-	return iommu_kmem_cache_alloc(iommu_devinfo_cache);
+	return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
 }
 
 static inline void free_devinfo_mem(void *vaddr)
@@ -440,7 +425,7 @@ static inline void free_devinfo_mem(void
 
 struct iova *alloc_iova_mem(void)
 {
-	return iommu_kmem_cache_alloc(iommu_iova_cache);
+	return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC);
 }
 
 void free_iova_mem(struct iova *iova)
@@ -589,7 +574,8 @@ static struct context_entry * device_to_
 	root = &iommu->root_entry[bus];
 	context = get_context_addr_from_root(root);
 	if (!context) {
-		context = (struct context_entry *)alloc_pgtable_page();
+		context = (struct context_entry *)
+				alloc_pgtable_page(iommu->node);
 		if (!context) {
 			spin_unlock_irqrestore(&iommu->lock, flags);
 			return NULL;
@@ -732,7 +718,7 @@ static struct dma_pte *pfn_to_dma_pte(st
 		if (!dma_pte_present(pte)) {
 			uint64_t pteval;
 
-			tmp_page = alloc_pgtable_page();
+			tmp_page = alloc_pgtable_page(domain->nid);
 
 			if (!tmp_page)
 				return NULL;
@@ -868,7 +854,7 @@ static int iommu_alloc_root_entry(struct
 	struct root_entry *root;
 	unsigned long flags;
 
-	root = (struct root_entry *)alloc_pgtable_page();
+	root = (struct root_entry *)alloc_pgtable_page(iommu->node);
 	if (!root)
 		return -ENOMEM;
 
@@ -1263,6 +1249,7 @@ static struct dmar_domain *alloc_domain(
 	if (!domain)
 		return NULL;
 
+	domain->nid = -1;
 	memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
 	domain->flags = 0;
 
@@ -1420,9 +1407,10 @@ static int domain_init(struct dmar_domai
 		domain->iommu_snooping = 0;
 
 	domain->iommu_count = 1;
+	domain->nid = iommu->node;
 
 	/* always allocate the top pgd */
-	domain->pgd = (struct dma_pte *)alloc_pgtable_page();
+	domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
 	if (!domain->pgd)
 		return -ENOMEM;
 	__iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
@@ -1523,12 +1511,15 @@ static int domain_context_mapping_one(st
 
 		/* Skip top levels of page tables for
 		 * iommu which has less agaw than default.
+		 * Unnecessary for PT mode.
 		 */
-		for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
-			pgd = phys_to_virt(dma_pte_addr(pgd));
-			if (!dma_pte_present(pgd)) {
-				spin_unlock_irqrestore(&iommu->lock, flags);
-				return -ENOMEM;
+		if (translation != CONTEXT_TT_PASS_THROUGH) {
+			for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
+				pgd = phys_to_virt(dma_pte_addr(pgd));
+				if (!dma_pte_present(pgd)) {
+					spin_unlock_irqrestore(&iommu->lock, flags);
+					return -ENOMEM;
+				}
 			}
 		}
 	}
@@ -1577,6 +1568,8 @@ static int domain_context_mapping_one(st
 	spin_lock_irqsave(&domain->iommu_lock, flags);
 	if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
 		domain->iommu_count++;
+		if (domain->iommu_count == 1)
+			domain->nid = iommu->node;
 		domain_update_iommu_cap(domain);
 	}
 	spin_unlock_irqrestore(&domain->iommu_lock, flags);
@@ -1611,7 +1604,7 @@ domain_context_mapping(struct dmar_domai
 			return ret;
 		parent = parent->bus->self;
 	}
-	if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+	if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
 		return domain_context_mapping_one(domain,
 					pci_domain_nr(tmp->subordinate),
 					tmp->subordinate->number, 0,
@@ -1651,7 +1644,7 @@ static int domain_context_mapped(struct
 			return ret;
 		parent = parent->bus->self;
 	}
-	if (tmp->is_pcie)
+	if (pci_is_pcie(tmp))
 		return device_context_mapped(iommu, tmp->subordinate->number,
 					     0);
 	else
@@ -1821,7 +1814,7 @@ static struct dmar_domain *get_domain_fo
 
 	dev_tmp = pci_find_upstream_pcie_bridge(pdev);
 	if (dev_tmp) {
-		if (dev_tmp->is_pcie) {
+		if (pci_is_pcie(dev_tmp)) {
 			bus = dev_tmp->subordinate->number;
 			devfn = 0;
 		} else {
@@ -1991,6 +1984,16 @@ static int iommu_prepare_identity_map(st
 	       "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
 	       pci_name(pdev), start, end);
 	
+	if (end < start) {
+		WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
+			"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+			dmi_get_system_info(DMI_BIOS_VENDOR),
+			dmi_get_system_info(DMI_BIOS_VERSION),
+		     dmi_get_system_info(DMI_PRODUCT_VERSION));
+		ret = -EIO;
+		goto error;
+	}
+
 	if (end >> agaw_to_width(domain->agaw)) {
 		WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
 		     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
@@ -2182,7 +2185,7 @@ static int iommu_should_identity_map(str
 	 * the 1:1 domain, just in _case_ one of their siblings turns out
 	 * not to be able to map all of memory.
 	 */
-	if (!pdev->is_pcie) {
+	if (!pci_is_pcie(pdev)) {
 		if (!pci_is_root_bus(pdev->bus))
 			return 0;
 		if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
@@ -3228,6 +3231,9 @@ static int device_notifier(struct notifi
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct dmar_domain *domain;
 
+	if (iommu_no_mapping(dev))
+		return 0;
+
 	domain = find_domain(pdev);
 	if (!domain)
 		return 0;
@@ -3266,7 +3272,7 @@ int __init intel_iommu_init(void)
 	 * Check the need for DMA-remapping initialization now.
 	 * Above initialization will also be used by Interrupt-remapping.
 	 */
-	if (no_iommu || swiotlb || dmar_disabled)
+	if (no_iommu || dmar_disabled)
 		return -ENODEV;
 
 	iommu_init_mempool();
@@ -3287,7 +3293,9 @@ int __init intel_iommu_init(void)
 	"PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
 
 	init_timer(&unmap_timer);
-	force_iommu = 1;
+#ifdef CONFIG_SWIOTLB
+	swiotlb = 0;
+#endif
 	dma_ops = &intel_dma_ops;
 
 	init_iommu_sysfs();
@@ -3317,7 +3325,7 @@ static void iommu_detach_dependent_devic
 					 parent->devfn);
 			parent = parent->bus->self;
 		}
-		if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+		if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
 			iommu_detach_dev(iommu,
 				tmp->subordinate->number, 0);
 		else /* this is a legacy PCI bridge */
@@ -3453,6 +3461,7 @@ static struct dmar_domain *iommu_alloc_v
 		return NULL;
 
 	domain->id = vm_domid++;
+	domain->nid = -1;
 	memset(&domain->iommu_bmp, 0, sizeof(unsigned long));
 	domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
 
@@ -3479,9 +3488,10 @@ static int md_domain_init(struct dmar_do
 	domain->iommu_coherency = 0;
 	domain->iommu_snooping = 0;
 	domain->max_addr = 0;
+	domain->nid = -1;
 
 	/* always allocate the top pgd */
-	domain->pgd = (struct dma_pte *)alloc_pgtable_page();
+	domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
 	if (!domain->pgd)
 		return -ENOMEM;
 	domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/intr_remapping.c linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.c
--- linux-libre-2.6.32-gnu1/drivers/pci/intr_remapping.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,6 +2,7 @@
 #include <linux/dmar.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
+#include <linux/hpet.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
 #include <asm/io_apic.h>
@@ -14,7 +15,8 @@
 #include "pci.h"
 
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
-static int ir_ioapic_num;
+static struct hpet_scope ir_hpet[MAX_HPET_TBS];
+static int ir_ioapic_num, ir_hpet_num;
 int intr_remapping_enabled;
 
 static int disable_intremap;
@@ -343,6 +345,16 @@ int flush_irte(int irq)
 	return rc;
 }
 
+struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
+{
+	int i;
+
+	for (i = 0; i < MAX_HPET_TBS; i++)
+		if (ir_hpet[i].id == hpet_id)
+			return ir_hpet[i].iommu;
+	return NULL;
+}
+
 struct intel_iommu *map_ioapic_to_ir(int apic)
 {
 	int i;
@@ -470,6 +482,36 @@ int set_ioapic_sid(struct irte *irte, in
 	return 0;
 }
 
+int set_hpet_sid(struct irte *irte, u8 id)
+{
+	int i;
+	u16 sid = 0;
+
+	if (!irte)
+		return -1;
+
+	for (i = 0; i < MAX_HPET_TBS; i++) {
+		if (ir_hpet[i].id == id) {
+			sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn;
+			break;
+		}
+	}
+
+	if (sid == 0) {
+		pr_warning("Failed to set source-id of HPET block (%d)\n", id);
+		return -1;
+	}
+
+	/*
+	 * Should really use SQ_ALL_16. Some platforms are broken.
+	 * While we figure out the right quirks for these broken platforms, use
+	 * SQ_13_IGNORE_3 for now.
+	 */
+	set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_13_IGNORE_3, sid);
+
+	return 0;
+}
+
 int set_msi_sid(struct irte *irte, struct pci_dev *dev)
 {
 	struct pci_dev *bridge;
@@ -478,7 +520,7 @@ int set_msi_sid(struct irte *irte, struc
 		return -1;
 
 	/* PCIe device or Root Complex integrated PCI device */
-	if (dev->is_pcie || !dev->bus->parent) {
+	if (pci_is_pcie(dev) || !dev->bus->parent) {
 		set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
 			     (dev->bus->number << 8) | dev->devfn);
 		return 0;
@@ -486,7 +528,7 @@ int set_msi_sid(struct irte *irte, struc
 
 	bridge = pci_find_upstream_pcie_bridge(dev);
 	if (bridge) {
-		if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */
+		if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */
 			set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
 				(bridge->bus->number << 8) | dev->bus->number);
 		else /* this is a legacy PCI bridge */
@@ -548,7 +590,8 @@ static int setup_intr_remapping(struct i
 	if (!iommu->ir_table)
 		return -ENOMEM;
 
-	pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
+	pages = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO,
+				 INTR_REMAP_PAGE_ORDER);
 
 	if (!pages) {
 		printk(KERN_ERR "failed to allocate pages of order %d\n",
@@ -711,6 +754,34 @@ error:
 	return -1;
 }
 
+static void ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope,
+				      struct intel_iommu *iommu)
+{
+	struct acpi_dmar_pci_path *path;
+	u8 bus;
+	int count;
+
+	bus = scope->bus;
+	path = (struct acpi_dmar_pci_path *)(scope + 1);
+	count = (scope->length - sizeof(struct acpi_dmar_device_scope))
+		/ sizeof(struct acpi_dmar_pci_path);
+
+	while (--count > 0) {
+		/*
+		 * Access PCI directly due to the PCI
+		 * subsystem isn't initialized yet.
+		 */
+		bus = read_pci_config_byte(bus, path->dev, path->fn,
+					   PCI_SECONDARY_BUS);
+		path++;
+	}
+	ir_hpet[ir_hpet_num].bus   = bus;
+	ir_hpet[ir_hpet_num].devfn = PCI_DEVFN(path->dev, path->fn);
+	ir_hpet[ir_hpet_num].iommu = iommu;
+	ir_hpet[ir_hpet_num].id    = scope->enumeration_id;
+	ir_hpet_num++;
+}
+
 static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope,
 				      struct intel_iommu *iommu)
 {
@@ -740,8 +811,8 @@ static void ir_parse_one_ioapic_scope(st
 	ir_ioapic_num++;
 }
 
-static int ir_parse_ioapic_scope(struct acpi_dmar_header *header,
-				 struct intel_iommu *iommu)
+static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header,
+				      struct intel_iommu *iommu)
 {
 	struct acpi_dmar_hardware_unit *drhd;
 	struct acpi_dmar_device_scope *scope;
@@ -765,6 +836,17 @@ static int ir_parse_ioapic_scope(struct
 			       drhd->address);
 
 			ir_parse_one_ioapic_scope(scope, iommu);
+		} else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) {
+			if (ir_hpet_num == MAX_HPET_TBS) {
+				printk(KERN_WARNING "Exceeded Max HPET blocks\n");
+				return -1;
+			}
+
+			printk(KERN_INFO "HPET id %d under DRHD base"
+			       " 0x%Lx\n", scope->enumeration_id,
+			       drhd->address);
+
+			ir_parse_one_hpet_scope(scope, iommu);
 		}
 		start += scope->length;
 	}
@@ -785,7 +867,7 @@ int __init parse_ioapics_under_ir(void)
 		struct intel_iommu *iommu = drhd->iommu;
 
 		if (ecap_ir_support(iommu->ecap)) {
-			if (ir_parse_ioapic_scope(drhd->hdr, iommu))
+			if (ir_parse_ioapic_hpet_scope(drhd->hdr, iommu))
 				return -1;
 
 			ir_supported = 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/intr_remapping.h linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.h
--- linux-libre-2.6.32-gnu1/drivers/pci/intr_remapping.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/intr_remapping.h	2010-02-24 13:52:17.000000000 -0500
@@ -7,4 +7,11 @@ struct ioapic_scope {
 	unsigned int devfn;	/* PCI devfn number */
 };
 
+struct hpet_scope {
+	struct intel_iommu *iommu;
+	u8 id;
+	unsigned int bus;
+	unsigned int devfn;
+};
+
 #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/ioapic.c linux-libre-2.6.33-gnu1/drivers/pci/ioapic.c
--- linux-libre-2.6.32-gnu1/drivers/pci/ioapic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/ioapic.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,127 @@
+/*
+ * IOAPIC/IOxAPIC/IOSAPIC driver
+ *
+ * Copyright (C) 2009 Fujitsu Limited.
+ * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This 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 manages PCI I/O APICs added by hotplug after boot.  We try to
+ * claim all I/O APIC PCI devices, but those present at boot were registered
+ * when we parsed the ACPI MADT, so we'll fail when we try to re-register
+ * them.
+ */
+
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+struct ioapic {
+	acpi_handle	handle;
+	u32		gsi_base;
+};
+
+static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	acpi_handle handle;
+	acpi_status status;
+	unsigned long long gsb;
+	struct ioapic *ioapic;
+	u64 addr;
+	int ret;
+	char *type;
+
+	handle = DEVICE_ACPI_HANDLE(&dev->dev);
+	if (!handle)
+		return -EINVAL;
+
+	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	/*
+	 * The previous code in acpiphp evaluated _MAT if _GSB failed, but
+	 * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs.
+	 */
+
+	ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL);
+	if (!ioapic)
+		return -ENOMEM;
+
+	ioapic->handle = handle;
+	ioapic->gsi_base = (u32) gsb;
+
+	if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC)
+		type = "IOAPIC";
+	else
+		type = "IOxAPIC";
+
+	ret = pci_enable_device(dev);
+	if (ret < 0)
+		goto exit_free;
+
+	pci_set_master(dev);
+
+	if (pci_request_region(dev, 0, type))
+		goto exit_disable;
+
+	addr = pci_resource_start(dev, 0);
+	if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base))
+		goto exit_release;
+
+	pci_set_drvdata(dev, ioapic);
+	dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr,
+		 ioapic->gsi_base);
+	return 0;
+
+exit_release:
+	pci_release_region(dev, 0);
+exit_disable:
+	pci_disable_device(dev);
+exit_free:
+	kfree(ioapic);
+	return -ENODEV;
+}
+
+static void ioapic_remove(struct pci_dev *dev)
+{
+	struct ioapic *ioapic = pci_get_drvdata(dev);
+
+	acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base);
+	pci_release_region(dev, 0);
+	pci_disable_device(dev);
+	kfree(ioapic);
+}
+
+
+static struct pci_device_id ioapic_devices[] = {
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, },
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, },
+	{ }
+};
+
+static struct pci_driver ioapic_driver = {
+	.name		= "ioapic",
+	.id_table	= ioapic_devices,
+	.probe		= ioapic_probe,
+	.remove		= __devexit_p(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);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/iov.c linux-libre-2.6.33-gnu1/drivers/pci/iov.c
--- linux-libre-2.6.32-gnu1/drivers/pci/iov.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/iov.c	2010-02-24 13:52:17.000000000 -0500
@@ -555,7 +555,7 @@ int pci_iov_init(struct pci_dev *dev)
 {
 	int pos;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/Kconfig linux-libre-2.6.33-gnu1/drivers/pci/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/pci/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -27,10 +27,10 @@ config PCI_LEGACY
 	default y
 	help
 	  Say Y here if you want to include support for the deprecated
-	  pci_find_slot() and pci_find_device() APIs.  Most drivers have
-	  been converted over to using the proper hotplug APIs, so this
-	  option serves to include/exclude only a few drivers that are
-	  still using this API.
+	  pci_find_device() API.  Most drivers have been converted over
+	  to using the proper hotplug APIs, so this option serves to
+	  include/exclude only a few drivers that are still using this
+	  API.
 
 config PCI_DEBUG
 	bool "PCI Debugging"
@@ -69,3 +69,10 @@ config PCI_IOV
 	  physical resources.
 
 	  If unsure, say N.
+
+config PCI_IOAPIC
+	bool
+	depends on PCI
+	depends on ACPI
+	depends on HOTPLUG
+	default y
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/Makefile linux-libre-2.6.33-gnu1/drivers/pci/Makefile
--- linux-libre-2.6.32-gnu1/drivers/pci/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,8 @@ CFLAGS_legacy.o += -Wno-deprecated-decla
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
+obj-$(CONFIG_PCI_IOAPIC) += ioapic.o
+
 obj-$(CONFIG_HOTPLUG) += hotplug.o
 
 # Build the PCI Hotplug drivers if we were asked to
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pci-acpi.c linux-libre-2.6.33-gnu1/drivers/pci/pci-acpi.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pci-acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pci-acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -112,11 +112,7 @@ static bool acpi_pci_can_wakeup(struct p
 static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
-		struct pci_dev *bridge = bus->self;
-		int ret;
-
-		ret = acpi_pm_device_sleep_wake(&bridge->dev, enable);
-		if (!ret || bridge->is_pcie)
+		if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable))
 			return;
 		bus = bus->parent;
 	}
@@ -131,9 +127,7 @@ static int acpi_pci_sleep_wake(struct pc
 	if (acpi_pci_can_wakeup(dev))
 		return acpi_pm_device_sleep_wake(&dev->dev, enable);
 
-	if (!dev->is_pcie)
-		acpi_pci_propagate_wakeup_enable(dev->bus, enable);
-
+	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pci.c linux-libre-2.6.33-gnu1/drivers/pci/pci.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,7 +29,17 @@ const char *pci_power_names[] = {
 };
 EXPORT_SYMBOL_GPL(pci_power_names);
 
-unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
+unsigned int pci_pm_d3_delay;
+
+static void pci_dev_d3_sleep(struct pci_dev *dev)
+{
+	unsigned int delay = dev->d3_delay;
+
+	if (delay < pci_pm_d3_delay)
+		delay = pci_pm_d3_delay;
+
+	msleep(delay);
+}
 
 #ifdef CONFIG_PCI_DOMAINS
 int pci_domains_supported = 1;
@@ -47,6 +57,15 @@ unsigned long pci_cardbus_mem_size = DEF
 unsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;
 unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
 
+/*
+ * The default CLS is used if arch didn't set CLS explicitly and not
+ * all pci devices agree on the same value.  Arch can override either
+ * the dfl or actual value as it sees fit.  Don't forget this is
+ * measured in 32-bit words, not bytes.
+ */
+u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2;
+u8 pci_cache_line_size;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -373,8 +392,12 @@ pci_find_parent_resource(const struct pc
 			continue;	/* Wrong type */
 		if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
 			return r;	/* Exact match */
-		if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
-			best = r;	/* Approximating prefetchable by non-prefetchable */
+		/* We can't insert a non-prefetch resource inside a prefetchable parent .. */
+		if (r->flags & IORESOURCE_PREFETCH)
+			continue;
+		/* .. but we can put a prefetchable resource inside a non-prefetchable one */
+		if (!best)
+			best = r;
 	}
 	return best;
 }
@@ -509,7 +532,7 @@ static int pci_raw_set_power_state(struc
 	/* Mandatory power management transition delays */
 	/* see PCI PM 1.1 5.6.1 table 18 */
 	if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
-		msleep(pci_pm_d3_delay);
+		pci_dev_d3_sleep(dev);
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(PCI_PM_D2_DELAY);
 
@@ -728,8 +751,8 @@ static int pci_save_pcie_state(struct pc
 	u16 *cap;
 	u16 flags;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	if (pos <= 0)
+	pos = pci_pcie_cap(dev);
+	if (!pos)
 		return 0;
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
@@ -837,7 +860,7 @@ pci_save_state(struct pci_dev *dev)
 	int i;
 	/* XXX: 100% dword access ok here? */
 	for (i = 0; i < 16; i++)
-		pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
+		pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]);
 	dev->state_saved = true;
 	if ((i = pci_save_pcie_state(dev)) != 0)
 		return i;
@@ -1140,11 +1163,11 @@ pci_disable_device(struct pci_dev *dev)
 
 /**
  * pcibios_set_pcie_reset_state - set reset state for device dev
- * @dev: the PCI-E device reset
+ * @dev: the PCIe device reset
  * @state: Reset state to enter into
  *
  *
- * Sets the PCI-E reset state for the device. This is the default
+ * Sets the PCIe reset state for the device. This is the default
  * implementation. Architecture implementations can override this.
  */
 int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev,
@@ -1155,7 +1178,7 @@ int __attribute__ ((weak)) pcibios_set_p
 
 /**
  * pci_set_pcie_reset_state - set reset state for device dev
- * @dev: the PCI-E device reset
+ * @dev: the PCIe device reset
  * @state: Reset state to enter into
  *
  *
@@ -1202,7 +1225,7 @@ void pci_pme_active(struct pci_dev *dev,
 
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
 
-	dev_printk(KERN_INFO, &dev->dev, "PME# %s\n",
+	dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n",
 			enable ? "enabled" : "disabled");
 }
 
@@ -1396,6 +1419,7 @@ void pci_pm_init(struct pci_dev *dev)
 	}
 
 	dev->pm_cap = pm;
+	dev->d3_delay = PCI_PM_D3_WAIT;
 
 	dev->d1_support = false;
 	dev->d2_support = false;
@@ -1413,7 +1437,8 @@ void pci_pm_init(struct pci_dev *dev)
 
 	pmc &= PCI_PM_CAP_PME_MASK;
 	if (pmc) {
-		dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
+		dev_printk(KERN_DEBUG, &dev->dev,
+			 "PME# supported from%s%s%s%s%s\n",
 			 (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
 			 (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
 			 (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
@@ -1510,7 +1535,7 @@ void pci_enable_ari(struct pci_dev *dev)
 	u16 ctrl;
 	struct pci_dev *bridge;
 
-	if (!dev->is_pcie || dev->devfn)
+	if (!pci_is_pcie(dev) || dev->devfn)
 		return;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
@@ -1518,10 +1543,10 @@ void pci_enable_ari(struct pci_dev *dev)
 		return;
 
 	bridge = dev->bus->self;
-	if (!bridge || !bridge->is_pcie)
+	if (!bridge || !pci_is_pcie(bridge))
 		return;
 
-	pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(bridge);
 	if (!pos)
 		return;
 
@@ -1536,6 +1561,54 @@ void pci_enable_ari(struct pci_dev *dev)
 	bridge->ari_enabled = 1;
 }
 
+static int pci_acs_enable;
+
+/**
+ * pci_request_acs - ask for ACS to be enabled if supported
+ */
+void pci_request_acs(void)
+{
+	pci_acs_enable = 1;
+}
+
+/**
+ * pci_enable_acs - enable ACS if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_acs(struct pci_dev *dev)
+{
+	int pos;
+	u16 cap;
+	u16 ctrl;
+
+	if (!pci_acs_enable)
+		return;
+
+	if (!pci_is_pcie(dev))
+		return;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
+	if (!pos)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
+	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
+
+	/* Source Validation */
+	ctrl |= (cap & PCI_ACS_SV);
+
+	/* P2P Request Redirect */
+	ctrl |= (cap & PCI_ACS_RR);
+
+	/* P2P Completion Redirect */
+	ctrl |= (cap & PCI_ACS_CR);
+
+	/* Upstream Forwarding */
+	ctrl |= (cap & PCI_ACS_UF);
+
+	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
+}
+
 /**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
@@ -1669,9 +1742,7 @@ static int __pci_request_region(struct p
 	return 0;
 
 err_out:
-	dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n",
-		 bar,
-		 pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
+	dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar,
 		 &pdev->resource[bar]);
 	return -EBUSY;
 }
@@ -1866,31 +1937,6 @@ void pci_clear_master(struct pci_dev *de
 	__pci_set_master(dev, false);
 }
 
-#ifdef PCI_DISABLE_MWI
-int pci_set_mwi(struct pci_dev *dev)
-{
-	return 0;
-}
-
-int pci_try_set_mwi(struct pci_dev *dev)
-{
-	return 0;
-}
-
-void pci_clear_mwi(struct pci_dev *dev)
-{
-}
-
-#else
-
-#ifndef PCI_CACHE_LINE_BYTES
-#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
-#endif
-
-/* This can be overridden by arch code. */
-/* Don't forget this is measured in 32-bit words, not bytes */
-u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4;
-
 /**
  * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
  * @dev: the PCI device for which MWI is to be enabled
@@ -1901,13 +1947,12 @@ u8 pci_cache_line_size = PCI_CACHE_LINE_
  *
  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
  */
-static int
-pci_set_cacheline_size(struct pci_dev *dev)
+int pci_set_cacheline_size(struct pci_dev *dev)
 {
 	u8 cacheline_size;
 
 	if (!pci_cache_line_size)
-		return -EINVAL;		/* The system doesn't support MWI. */
+		return -EINVAL;
 
 	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
 	   equal to or multiple of the right value. */
@@ -1928,6 +1973,24 @@ pci_set_cacheline_size(struct pci_dev *d
 
 	return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(pci_set_cacheline_size);
+
+#ifdef PCI_DISABLE_MWI
+int pci_set_mwi(struct pci_dev *dev)
+{
+	return 0;
+}
+
+int pci_try_set_mwi(struct pci_dev *dev)
+{
+	return 0;
+}
+
+void pci_clear_mwi(struct pci_dev *dev)
+{
+}
+
+#else
 
 /**
  * pci_set_mwi - enables memory-write-invalidate PCI transaction
@@ -2062,6 +2125,7 @@ pci_set_dma_mask(struct pci_dev *dev, u6
 		return -EIO;
 
 	dev->dma_mask = mask;
+	dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
 
 	return 0;
 }
@@ -2073,6 +2137,7 @@ pci_set_consistent_dma_mask(struct pci_d
 		return -EIO;
 
 	dev->dev.coherent_dma_mask = mask;
+	dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
 
 	return 0;
 }
@@ -2099,9 +2164,9 @@ static int pcie_flr(struct pci_dev *dev,
 	int i;
 	int pos;
 	u32 cap;
-	u16 status;
+	u16 status, control;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -ENOTTY;
 
@@ -2126,8 +2191,10 @@ static int pcie_flr(struct pci_dev *dev,
 			"proceeding with reset anyway\n");
 
 clear:
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
-				PCI_EXP_DEVCTL_BCR_FLR);
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
+	control |= PCI_EXP_DEVCTL_BCR_FLR;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
+
 	msleep(100);
 
 	return 0;
@@ -2191,12 +2258,12 @@ static int pci_pm_reset(struct pci_dev *
 	csr &= ~PCI_PM_CTRL_STATE_MASK;
 	csr |= PCI_D3hot;
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
-	msleep(pci_pm_d3_delay);
+	pci_dev_d3_sleep(dev);
 
 	csr &= ~PCI_PM_CTRL_STATE_MASK;
 	csr |= PCI_D0;
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
-	msleep(pci_pm_d3_delay);
+	pci_dev_d3_sleep(dev);
 
 	return 0;
 }
@@ -2240,6 +2307,10 @@ static int pci_dev_reset(struct pci_dev
 		down(&dev->dev.sem);
 	}
 
+	rc = pci_dev_specific_reset(dev, probe);
+	if (rc != -ENOTTY)
+		goto done;
+
 	rc = pcie_flr(dev, probe);
 	if (rc != -ENOTTY)
 		goto done;
@@ -2450,7 +2521,7 @@ int pcie_get_readrq(struct pci_dev *dev)
 	int ret, cap;
 	u16 ctl;
 
-	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	cap = pci_pcie_cap(dev);
 	if (!cap)
 		return -EINVAL;
 
@@ -2480,7 +2551,7 @@ int pcie_set_readrq(struct pci_dev *dev,
 
 	v = (ffs(rq) - 8) << 12;
 
-	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	cap = pci_pcie_cap(dev);
 	if (!cap)
 		goto out;
 
@@ -2540,7 +2611,7 @@ int pci_resource_bar(struct pci_dev *dev
 			return reg;
 	}
 
-	dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
+	dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
 	return 0;
 }
 
@@ -2590,7 +2661,7 @@ int pci_set_vga_state(struct pci_dev *de
 
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
 static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
-spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(resource_alignment_lock);
 
 /**
  * pci_specified_resource_alignment - get resource alignment specified by user.
@@ -2723,6 +2794,11 @@ int __attribute__ ((weak)) pci_ext_cfg_a
 	return 1;
 }
 
+void __weak pci_fixup_cardbus(struct pci_bus *bus)
+{
+}
+EXPORT_SYMBOL(pci_fixup_cardbus);
+
 static int __init pci_setup(char *str)
 {
 	while (str) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
  *
  * @return: Zero on success. Nonzero otherwise.
  *
- * Invoked when PCIE bus loads AER service driver. To avoid conflict with
+ * Invoked when PCIe bus loads AER service driver. To avoid conflict with
  * BIOS AER support requires BIOS to yield AER control to OS native driver.
  **/
 int aer_osc_setup(struct pcie_device *pciedev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,7 @@ static struct pci_error_handlers aer_err
 
 static struct pcie_port_service_driver aerdriver = {
 	.name		= "aer",
-	.port_type	= PCIE_RC_PORT,
+	.port_type	= PCI_EXP_TYPE_ROOT_PORT,
 	.service	= PCIE_PORT_SERVICE_AER,
 
 	.probe		= aer_probe,
@@ -155,7 +155,7 @@ static struct aer_rpc *aer_alloc_rpc(str
 	mutex_init(&rpc->rpc_mutex);
 	init_waitqueue_head(&rpc->wait_release);
 
-	/* Use PCIE bus function to store rpc into PCIE device */
+	/* Use PCIe bus function to store rpc into PCIe device */
 	set_service_data(dev, rpc);
 
 	return rpc;
@@ -295,7 +295,7 @@ static void aer_error_resume(struct pci_
 	u16 reg16;
 
 	/* Clean up Root device status */
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
 	pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_core.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_core.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,11 +35,14 @@ int pci_enable_pcie_error_reporting(stru
 	u16 reg16 = 0;
 	int pos;
 
+	if (dev->aer_firmware_first)
+		return -EIO;
+
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos)
 		return -EIO;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -EIO;
 
@@ -60,7 +63,10 @@ int pci_disable_pcie_error_reporting(str
 	u16 reg16 = 0;
 	int pos;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (dev->aer_firmware_first)
+		return -EIO;
+
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return -EIO;
 
@@ -78,48 +84,27 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error
 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 {
 	int pos;
-	u32 status, mask;
+	u32 status;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos)
 		return -EIO;
 
 	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
-	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
-	if (dev->error_state == pci_channel_io_normal)
-		status &= ~mask; /* Clear corresponding nonfatal bits */
-	else
-		status &= mask; /* Clear corresponding fatal bits */
-	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+	if (status)
+		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
 
-#if 0
-int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
-{
-	int pos;
-	u32 status;
-
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return -EIO;
-
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
-
-	return 0;
-}
-#endif  /*  0  */
-
 static int set_device_error_reporting(struct pci_dev *dev, void *data)
 {
 	bool enable = *((bool *)data);
 
-	if (dev->pcie_type == PCIE_RC_PORT ||
-	    dev->pcie_type == PCIE_SW_UPSTREAM_PORT ||
-	    dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) {
+	if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
+	    (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
+	    (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
 		if (enable)
 			pci_enable_pcie_error_reporting(dev);
 		else
@@ -218,7 +203,7 @@ static int find_device_iter(struct pci_d
 	 */
 	if (atomic_read(&dev->enable_cnt) == 0)
 		return 0;
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos)
 		return 0;
 	/* Check if AER is enabled */
@@ -431,10 +416,9 @@ static int find_aer_service_iter(struct
 	result = (struct find_aer_service_data *) data;
 
 	if (device->bus == &pcie_port_bus_type) {
-		struct pcie_port_data *port_data;
+		struct pcie_device *pcie = to_pcie_device(device);
 
-		port_data = pci_get_drvdata(to_pcie_device(device)->port);
-		if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
+		if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
 			result->is_downstream = 1;
 
 		driver = device->driver;
@@ -603,7 +587,7 @@ static void handle_error_source(struct p
  * aer_enable_rootport - enable Root Port's interrupts when receiving messages
  * @rpc: pointer to a Root Port data structure
  *
- * Invoked when PCIE bus loads AER service driver.
+ * Invoked when PCIe bus loads AER service driver.
  */
 void aer_enable_rootport(struct aer_rpc *rpc)
 {
@@ -612,8 +596,8 @@ void aer_enable_rootport(struct aer_rpc
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	/* Clear PCIE Capability's Device Status */
+	pos = pci_pcie_cap(pdev);
+	/* Clear PCIe Capability's Device Status */
 	pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
 	pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
 
@@ -647,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc
  * disable_root_aer - disable Root Port's interrupts when receiving messages
  * @rpc: pointer to a Root Port data structure
  *
- * Invoked when PCIE bus unloads AER service driver.
+ * Invoked when PCIe bus unloads AER service driver.
  */
 static void disable_root_aer(struct aer_rpc *rpc)
 {
@@ -874,8 +858,22 @@ void aer_delete_rootport(struct aer_rpc
  */
 int aer_init(struct pcie_device *dev)
 {
-	if (aer_osc_setup(dev) && !forceload)
-		return -ENXIO;
+	if (dev->port->aer_firmware_first) {
+		dev_printk(KERN_DEBUG, &dev->device,
+			   "PCIe errors handled by platform firmware.\n");
+		goto out;
+	}
+
+	if (aer_osc_setup(dev))
+		goto out;
 
 	return 0;
+out:
+	if (forceload) {
+		dev_printk(KERN_DEBUG, &dev->device,
+			   "aerdrv forceload requested.\n");
+		dev->port->aer_firmware_first = 0;
+		return 0;
+	}
+	return -ENXIO;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_errprint.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_errprint.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aerdrv_errprint.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aerdrv_errprint.c	2010-02-24 13:52:17.000000000 -0500
@@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev
 
 	if (info->status == 0) {
 		AER_PR(info, dev,
-			"PCIE Bus Error: severity=%s, type=Unaccessible, "
+			"PCIe Bus Error: severity=%s, type=Unaccessible, "
 			"id=%04x(Unregistered Agent ID)\n",
 			aer_error_severity_string[info->severity], id);
 	} else {
@@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev
 		agent = AER_GET_AGENT(info->severity, info->status);
 
 		AER_PR(info, dev,
-			"PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
+			"PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
 			aer_error_severity_string[info->severity],
 			aer_error_layer[layer], id, aer_agent_string[agent]);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aer_inject.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aer_inject.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/aer_inject.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/aer_inject.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,7 @@
 /*
- * PCIE AER software error injection support.
+ * PCIe AER software error injection support.
  *
- * Debuging PCIE AER code is quite difficult because it is hard to
+ * Debuging PCIe AER code is quite difficult because it is hard to
  * trigger various real hardware errors. Software based error
  * injection can fake almost all kinds of errors with the help of a
  * user space helper tool aer-inject, which can be gotten from:
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
+#include <linux/stddef.h>
 #include "aerdrv.h"
 
 struct aer_error_inj {
@@ -35,10 +36,12 @@ struct aer_error_inj {
 	u32 header_log1;
 	u32 header_log2;
 	u32 header_log3;
+	u16 domain;
 };
 
 struct aer_error {
 	struct list_head list;
+	u16 domain;
 	unsigned int bus;
 	unsigned int devfn;
 	int pos_cap_err;
@@ -66,22 +69,27 @@ static LIST_HEAD(pci_bus_ops_list);
 /* Protect einjected and pci_bus_ops_list */
 static DEFINE_SPINLOCK(inject_lock);
 
-static void aer_error_init(struct aer_error *err, unsigned int bus,
-			   unsigned int devfn, int pos_cap_err)
+static void aer_error_init(struct aer_error *err, u16 domain,
+			   unsigned int bus, unsigned int devfn,
+			   int pos_cap_err)
 {
 	INIT_LIST_HEAD(&err->list);
+	err->domain = domain;
 	err->bus = bus;
 	err->devfn = devfn;
 	err->pos_cap_err = pos_cap_err;
 }
 
 /* inject_lock must be held before calling */
-static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn)
+static struct aer_error *__find_aer_error(u16 domain, unsigned int bus,
+					  unsigned int devfn)
 {
 	struct aer_error *err;
 
 	list_for_each_entry(err, &einjected, list) {
-		if (bus == err->bus && devfn == err->devfn)
+		if (domain == err->domain &&
+		    bus == err->bus &&
+		    devfn == err->devfn)
 			return err;
 	}
 	return NULL;
@@ -90,7 +98,10 @@ static struct aer_error *__find_aer_erro
 /* inject_lock must be held before calling */
 static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
 {
-	return __find_aer_error(dev->bus->number, dev->devfn);
+	int domain = pci_domain_nr(dev->bus);
+	if (domain < 0)
+		return NULL;
+	return __find_aer_error((u16)domain, dev->bus->number, dev->devfn);
 }
 
 /* inject_lock must be held before calling */
@@ -172,11 +183,15 @@ static int pci_read_aer(struct pci_bus *
 	struct aer_error *err;
 	unsigned long flags;
 	struct pci_ops *ops;
+	int domain;
 
 	spin_lock_irqsave(&inject_lock, flags);
 	if (size != sizeof(u32))
 		goto out;
-	err = __find_aer_error(bus->number, devfn);
+	domain = pci_domain_nr(bus);
+	if (domain < 0)
+		goto out;
+	err = __find_aer_error((u16)domain, bus->number, devfn);
 	if (!err)
 		goto out;
 
@@ -200,11 +215,15 @@ int pci_write_aer(struct pci_bus *bus, u
 	unsigned long flags;
 	int rw1cs;
 	struct pci_ops *ops;
+	int domain;
 
 	spin_lock_irqsave(&inject_lock, flags);
 	if (size != sizeof(u32))
 		goto out;
-	err = __find_aer_error(bus->number, devfn);
+	domain = pci_domain_nr(bus);
+	if (domain < 0)
+		goto out;
+	err = __find_aer_error((u16)domain, bus->number, devfn);
 	if (!err)
 		goto out;
 
@@ -262,7 +281,7 @@ out:
 static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
 {
 	while (1) {
-		if (!dev->is_pcie)
+		if (!pci_is_pcie(dev))
 			break;
 		if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
 			return dev;
@@ -302,28 +321,31 @@ static int aer_inject(struct aer_error_i
 	unsigned long flags;
 	unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
 	int pos_cap_err, rp_pos_cap_err;
-	u32 sever;
+	u32 sever, cor_mask, uncor_mask;
 	int ret = 0;
 
-	dev = pci_get_bus_and_slot(einj->bus, devfn);
+	dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
 	if (!dev)
-		return -EINVAL;
+		return -ENODEV;
 	rpdev = pcie_find_root_port(dev);
 	if (!rpdev) {
-		ret = -EINVAL;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 
 	pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos_cap_err) {
-		ret = -EIO;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
+	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask);
+	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
+			      &uncor_mask);
 
 	rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
 	if (!rp_pos_cap_err) {
-		ret = -EIO;
+		ret = -ENOTTY;
 		goto out_put;
 	}
 
@@ -344,7 +366,8 @@ static int aer_inject(struct aer_error_i
 	if (!err) {
 		err = err_alloc;
 		err_alloc = NULL;
-		aer_error_init(err, einj->bus, devfn, pos_cap_err);
+		aer_error_init(err, einj->domain, einj->bus, devfn,
+			       pos_cap_err);
 		list_add(&err->list, &einjected);
 	}
 	err->uncor_status |= einj->uncor_status;
@@ -354,11 +377,27 @@ static int aer_inject(struct aer_error_i
 	err->header_log2 = einj->header_log2;
 	err->header_log3 = einj->header_log3;
 
+	if (einj->cor_status && !(einj->cor_status & ~cor_mask)) {
+		ret = -EINVAL;
+		printk(KERN_WARNING "The correctable error(s) is masked "
+				"by device\n");
+		spin_unlock_irqrestore(&inject_lock, flags);
+		goto out_put;
+	}
+	if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) {
+		ret = -EINVAL;
+		printk(KERN_WARNING "The uncorrectable error(s) is masked "
+				"by device\n");
+		spin_unlock_irqrestore(&inject_lock, flags);
+		goto out_put;
+	}
+
 	rperr = __find_aer_error_by_dev(rpdev);
 	if (!rperr) {
 		rperr = rperr_alloc;
 		rperr_alloc = NULL;
-		aer_error_init(rperr, rpdev->bus->number, rpdev->devfn,
+		aer_error_init(rperr, pci_domain_nr(rpdev->bus),
+			       rpdev->bus->number, rpdev->devfn,
 			       rp_pos_cap_err);
 		list_add(&rperr->list, &einjected);
 	}
@@ -392,8 +431,14 @@ static int aer_inject(struct aer_error_i
 	if (ret)
 		goto out_put;
 
-	if (find_aer_device(rpdev, &edev))
+	if (find_aer_device(rpdev, &edev)) {
+		if (!get_service_data(edev)) {
+			printk(KERN_WARNING "AER service is not initialized\n");
+			ret = -EINVAL;
+			goto out_put;
+		}
 		aer_irq(-1, edev);
+	}
 	else
 		ret = -EINVAL;
 out_put:
@@ -411,10 +456,11 @@ static ssize_t aer_inject_write(struct f
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-
-	if (usize != sizeof(struct aer_error_inj))
+	if (usize < offsetof(struct aer_error_inj, domain) ||
+	    usize > sizeof(einj))
 		return -EINVAL;
 
+	memset(&einj, 0, sizeof(einj));
 	if (copy_from_user(&einj, ubuf, usize))
 		return -EFAULT;
 
@@ -452,7 +498,7 @@ static void __exit aer_inject_exit(void)
 	}
 
 	spin_lock_irqsave(&inject_lock, flags);
-	list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) {
+	list_for_each_entry_safe(err, err_next, &einjected, list) {
 		list_del(&err->list);
 		kfree(err);
 	}
@@ -462,5 +508,5 @@ static void __exit aer_inject_exit(void)
 module_init(aer_inject_init);
 module_exit(aer_inject_exit);
 
-MODULE_DESCRIPTION("PCIE AER software error injector");
+MODULE_DESCRIPTION("PCIe AER software error injector");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/ecrc.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/ecrc.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/ecrc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/ecrc.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ static int enable_ecrc_checking(struct p
 	int pos;
 	u32 reg32;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
@@ -79,7 +79,7 @@ static int disable_ecrc_checking(struct
 	int pos;
 	u32 reg32;
 
-	if (!dev->is_pcie)
+	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/Kconfig.debug linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/Kconfig.debug
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aer/Kconfig.debug	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aer/Kconfig.debug	2010-02-24 13:52:17.000000000 -0500
@@ -3,14 +3,14 @@
 #
 
 config PCIEAER_INJECT
-	tristate "PCIE AER error injector support"
+	tristate "PCIe AER error injector support"
 	depends on PCIEAER
 	default n
 	help
 	  This enables PCI Express Root Port Advanced Error Reporting
 	  (AER) software error injector.
 
-	  Debuging PCIE AER code is quite difficult because it is hard
+	  Debugging PCIe AER code is quite difficult because it is hard
 	  to trigger various real hardware errors. Software based
 	  error injection can fake almost all kinds of errors with the
 	  help of a user space helper tool aer-inject, which can be
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/aspm.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/aspm.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/aspm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/aspm.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,6 +1,6 @@
 /*
  * File:	drivers/pci/pcie/aspm.c
- * Enabling PCIE link L0s/L1 state and Clock Power Management
+ * Enabling PCIe link L0s/L1 state and Clock Power Management
  *
  * Copyright (C) 2007 Intel
  * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com)
@@ -122,7 +122,7 @@ static void pcie_set_clkpm_nocheck(struc
 	struct pci_bus *linkbus = link->pdev->subordinate;
 
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return;
 		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
@@ -156,7 +156,7 @@ static void pcie_clkpm_cap_init(struct p
 
 	/* All functions should have the same cap and state, take the worst */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return;
 		pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
@@ -191,23 +191,23 @@ static void pcie_aspm_configure_common_c
 	 * Configuration, so just check one function
 	 */
 	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
-	BUG_ON(!child->is_pcie);
+	BUG_ON(!pci_is_pcie(child));
 
 	/* Check downstream component if bit Slot Clock Configuration is 1 */
-	cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+	cpos = pci_pcie_cap(child);
 	pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 
 	/* Check upstream component if bit Slot Clock Configuration is 1 */
-	ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
+	ppos = pci_pcie_cap(parent);
 	pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 
 	/* Configure downstream component, all functions */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		cpos = pci_pcie_cap(child);
 		pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
 		child_reg[PCI_FUNC(child->devfn)] = reg16;
 		if (same_clock)
@@ -247,7 +247,7 @@ static void pcie_aspm_configure_common_c
 	dev_printk(KERN_ERR, &parent->dev,
 		   "ASPM: Could not configure common clock\n");
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		cpos = pci_pcie_cap(child);
 		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
 				      child_reg[PCI_FUNC(child->devfn)]);
 	}
@@ -300,7 +300,7 @@ static void pcie_get_aspm_reg(struct pci
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(pdev);
 	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
 	info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
 	info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
@@ -420,7 +420,7 @@ static void pcie_aspm_cap_init(struct pc
 		    child->pcie_type != PCI_EXP_TYPE_LEG_END)
 			continue;
 
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
 		/* Calculate endpoint L0s acceptable latency */
 		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
@@ -436,7 +436,7 @@ static void pcie_aspm_cap_init(struct pc
 static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
 	u16 reg16;
-	int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	int pos = pci_pcie_cap(pdev);
 
 	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
 	reg16 &= ~0x3;
@@ -499,11 +499,11 @@ static int pcie_aspm_sanity_check(struct
 	int pos;
 	u32 reg32;
 	/*
-	 * Some functions in a slot might not all be PCIE functions,
+	 * Some functions in a slot might not all be PCIe functions,
 	 * very strange. Disable ASPM for the whole slot
 	 */
 	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
-		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pos = pci_pcie_cap(child);
 		if (!pos)
 			return -EINVAL;
 		/*
@@ -563,7 +563,7 @@ void pcie_aspm_init_link_state(struct pc
 	struct pcie_link_state *link;
 	int blacklist = !!pcie_aspm_sanity_check(pdev);
 
-	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
+	if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
 		return;
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
 	    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
@@ -629,7 +629,8 @@ void pcie_aspm_exit_link_state(struct pc
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link, *root, *parent_link;
 
-	if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state)
+	if (aspm_disabled || !pci_is_pcie(pdev) ||
+	    !parent || !parent->link_state)
 		return;
 	if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
 	    (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
@@ -670,7 +671,7 @@ void pcie_aspm_pm_state_change(struct pc
 {
 	struct pcie_link_state *link = pdev->link_state;
 
-	if (aspm_disabled || !pdev->is_pcie || !link)
+	if (aspm_disabled || !pci_is_pcie(pdev) || !link)
 		return;
 	if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
 	    (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
@@ -696,7 +697,7 @@ void pci_disable_link_state(struct pci_d
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link;
 
-	if (aspm_disabled || !pdev->is_pcie)
+	if (aspm_disabled || !pci_is_pcie(pdev))
 		return;
 	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
 	    pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
@@ -841,8 +842,9 @@ void pcie_aspm_create_sysfs_dev_files(st
 {
 	struct pcie_link_state *link_state = pdev->link_state;
 
-	if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+	if (!pci_is_pcie(pdev) ||
+	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 
 	if (link_state->aspm_support)
@@ -857,8 +859,9 @@ void pcie_aspm_remove_sysfs_dev_files(st
 {
 	struct pcie_link_state *link_state = pdev->link_state;
 
-	if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
+	if (!pci_is_pcie(pdev) ||
+	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 
 	if (link_state->aspm_support)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_bus.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_bus.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,7 +26,6 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type);
 static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct pcie_device *pciedev;
-	struct pcie_port_data *port_data;
 	struct pcie_port_service_driver *driver;
 
 	if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
@@ -38,10 +37,8 @@ static int pcie_port_bus_match(struct de
 	if (driver->service != pciedev->service)
 		return 0;
 
-	port_data = pci_get_drvdata(pciedev->port);
-
-	if (driver->port_type != PCIE_ANY_PORT
-	     && driver->port_type != port_data->port_type)
+	if ((driver->port_type != PCIE_ANY_PORT) &&
+	    (driver->port_type != pciedev->port->pcie_type))
 		return 0;
 
 	return 1;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_core.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_core.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@
  */
 static void release_pcie_device(struct device *dev)
 {
-	kfree(to_pcie_device(dev));			
+	kfree(to_pcie_device(dev));
 }
 
 /**
@@ -108,9 +108,9 @@ static int pcie_port_enable_msix(struct
 		 * the value in this field indicates which MSI-X Table entry is
 		 * used to generate the interrupt message."
 		 */
-		pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-		pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
-		entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK;
+		pos = pci_pcie_cap(dev);
+		pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
+		entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9;
 		if (entry >= nr_entries)
 			goto Error;
 
@@ -177,37 +177,40 @@ static int pcie_port_enable_msix(struct
 }
 
 /**
- * assign_interrupt_mode - choose interrupt mode for PCI Express port services
- *                         (INTx, MSI-X, MSI) and set up vectors
+ * init_service_irqs - initialize irqs for PCI Express port services
  * @dev: PCI Express port to handle
- * @vectors: Array of interrupt vectors to populate
+ * @irqs: Array of irqs to populate
  * @mask: Bitmask of port capabilities returned by get_port_device_capability()
  *
  * Return value: Interrupt mode associated with the port
  */
-static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
+static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 {
-	int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
-	int i;
+	int i, irq;
 
 	/* Try to use MSI-X if supported */
-	if (!pcie_port_enable_msix(dev, vectors, mask))
-		return PCIE_PORT_MSIX_MODE;
-
+	if (!pcie_port_enable_msix(dev, irqs, mask))
+		return 0;
 	/* We're not going to use MSI-X, so try MSI and fall back to INTx */
-	if (!pci_enable_msi(dev))
-		interrupt_mode = PCIE_PORT_MSI_MODE;
-
-	if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
-		interrupt_mode = PCIE_PORT_INTx_MODE;
+	irq = -1;
+	if (!pci_enable_msi(dev) || dev->pin)
+		irq = dev->irq;
 
-	irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
-		vectors[i] = irq;
+		irqs[i] = irq;
+	irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
 
-	vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
+	if (irq < 0)
+		return -ENODEV;
+	return 0;
+}
 
-	return interrupt_mode;
+static void cleanup_service_irqs(struct pci_dev *dev)
+{
+	if (dev->msix_enabled)
+		pci_disable_msix(dev);
+	else if (dev->msi_enabled)
+		pci_disable_msi(dev);
 }
 
 /**
@@ -226,13 +229,12 @@ static int get_port_device_capability(st
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+	pos = pci_pcie_cap(dev);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
 	/* Hot-Plug Capable */
-	if (reg16 & PORT_TO_SLOT_MASK) {
-		pci_read_config_dword(dev, 
-			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
-		if (reg32 & SLOT_HP_CAPABLE_MASK)
+	if (reg16 & PCI_EXP_FLAGS_SLOT) {
+		pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
+		if (reg32 & PCI_EXP_SLTCAP_HPC)
 			services |= PCIE_PORT_SERVICE_HP;
 	}
 	/* AER capable */
@@ -241,80 +243,47 @@ static int get_port_device_capability(st
 	/* VC support */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
 		services |= PCIE_PORT_SERVICE_VC;
+	/* Root ports are capable of generating PME too */
+	if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+		services |= PCIE_PORT_SERVICE_PME;
 
 	return services;
 }
 
 /**
- * pcie_device_init - initialize PCI Express port service device
- * @dev: Port service device to initialize
- * @parent: PCI Express port to associate the service device with
- * @port_type: Type of the port
- * @service_type: Type of service to associate with the service device
+ * pcie_device_init - allocate and initialize PCI Express port service device
+ * @pdev: PCI Express port to associate the service device with
+ * @service: Type of service to associate with the service device
  * @irq: Interrupt vector to associate with the service device
  */
-static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 
-	int service_type, int irq)
+static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
 {
-	struct pcie_port_data *port_data = pci_get_drvdata(parent);
+	int retval;
+	struct pcie_device *pcie;
 	struct device *device;
-	int port_type = port_data->port_type;
 
-	dev->port = parent;
-	dev->irq = irq;
-	dev->service = service_type;
+	pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+	pcie->port = pdev;
+	pcie->irq = irq;
+	pcie->service = service;
 
 	/* Initialize generic device interface */
-	device = &dev->device;
-	memset(device, 0, sizeof(struct device));
+	device = &pcie->device;
 	device->bus = &pcie_port_bus_type;
-	device->driver = NULL;
-	dev_set_drvdata(device, NULL);
 	device->release = release_pcie_device;	/* callback to free pcie dev */
 	dev_set_name(device, "%s:pcie%02x",
-		 pci_name(parent), get_descriptor_id(port_type, service_type));
-	device->parent = &parent->dev;
-}
-
-/**
- * alloc_pcie_device - allocate PCI Express port service device structure
- * @parent: PCI Express port to associate the service device with
- * @port_type: Type of the port
- * @service_type: Type of service to associate with the service device
- * @irq: Interrupt vector to associate with the service device
- */
-static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
-	int service_type, int irq)
-{
-	struct pcie_device *device;
-
-	device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL);
-	if (!device)
-		return NULL;
-
-	pcie_device_init(parent, device, service_type, irq);
-	return device;
-}
-
-/**
- * pcie_port_device_probe - check if device is a PCI Express port
- * @dev: Device to check
- */
-int pcie_port_device_probe(struct pci_dev *dev)
-{
-	int pos, type;
-	u16 reg;
-
-	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
-		return -ENODEV;
-
-	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
-	type = (reg >> 4) & PORT_TYPE_MASK;
-	if (	type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
-		type == PCIE_SW_DOWNSTREAM_PORT )
-		return 0;
+		     pci_name(pdev),
+		     get_descriptor_id(pdev->pcie_type, service));
+	device->parent = &pdev->dev;
 
-	return -ENODEV;
+	retval = device_register(device);
+	if (retval)
+		kfree(pcie);
+	else
+		get_device(device);
+	return retval;
 }
 
 /**
@@ -326,77 +295,49 @@ int pcie_port_device_probe(struct pci_de
  */
 int pcie_port_device_register(struct pci_dev *dev)
 {
-	struct pcie_port_data *port_data;
-	int status, capabilities, irq_mode, i, nr_serv;
-	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
-	u16 reg16;
-
-	port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
-	if (!port_data)
-		return -ENOMEM;
-	pci_set_drvdata(dev, port_data);
-
-	/* Get port type */
-	pci_read_config_word(dev,
-		pci_find_capability(dev, PCI_CAP_ID_EXP) +
-		PCIE_CAPABILITIES_REG, &reg16);
-	port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
+	int status, capabilities, i, nr_service;
+	int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
 
+	/* Get and check PCI Express port services */
 	capabilities = get_port_device_capability(dev);
-	/* Root ports are capable of generating PME too */
-	if (port_data->port_type == PCIE_RC_PORT)
-		capabilities |= PCIE_PORT_SERVICE_PME;
-
-	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
-	if (irq_mode == PCIE_PORT_NO_IRQ) {
-		/*
-		 * Don't use service devices that require interrupts if there is
-		 * no way to generate them.
-		 */
-		if (!(capabilities & PCIE_PORT_SERVICE_VC)) {
-			status = -ENODEV;
-			goto Error;
-		}
-		capabilities = PCIE_PORT_SERVICE_VC;
-	}
-	port_data->port_irq_mode = irq_mode;
+	if (!capabilities)
+		return -ENODEV;
 
+	/* Enable PCI Express port device */
 	status = pci_enable_device(dev);
 	if (status)
-		goto Error;
+		return status;
 	pci_set_master(dev);
+	/*
+	 * Initialize service irqs. Don't use service devices that
+	 * require interrupts if there is no way to generate them.
+	 */
+	status = init_service_irqs(dev, irqs, capabilities);
+	if (status) {
+		capabilities &= PCIE_PORT_SERVICE_VC;
+		if (!capabilities)
+			goto error_disable;
+	}
 
 	/* Allocate child services if any */
-	for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
-		struct pcie_device *child;
+	status = -ENODEV;
+	nr_service = 0;
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 		int service = 1 << i;
-
 		if (!(capabilities & service))
 			continue;
-
-		child = alloc_pcie_device(dev, service, vectors[i]);
-		if (!child)
-			continue;
-
-		status = device_register(&child->device);
-		if (status) {
-			kfree(child);
-			continue;
-		}
-
-		get_device(&child->device);
-		nr_serv++;
-	}
-	if (!nr_serv) {
-		pci_disable_device(dev);
-		status = -ENODEV;
-		goto Error;
+		if (!pcie_device_init(dev, service, irqs[i]))
+			nr_service++;
 	}
+	if (!nr_service)
+		goto error_cleanup_irqs;
 
 	return 0;
 
- Error:
-	kfree(port_data);
+error_cleanup_irqs:
+	cleanup_service_irqs(dev);
+error_disable:
+	pci_disable_device(dev);
 	return status;
 }
 
@@ -405,12 +346,11 @@ static int suspend_iter(struct device *d
 {
 	struct pcie_port_service_driver *service_driver;
 
- 	if ((dev->bus == &pcie_port_bus_type) &&
- 	    (dev->driver)) {
- 		service_driver = to_service_driver(dev->driver);
- 		if (service_driver->suspend)
- 			service_driver->suspend(to_pcie_device(dev));
-  	}
+	if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
+		service_driver = to_service_driver(dev->driver);
+		if (service_driver->suspend)
+			service_driver->suspend(to_pcie_device(dev));
+	}
 	return 0;
 }
 
@@ -464,21 +404,9 @@ static int remove_iter(struct device *de
  */
 void pcie_port_device_remove(struct pci_dev *dev)
 {
-	struct pcie_port_data *port_data = pci_get_drvdata(dev);
-
 	device_for_each_child(&dev->dev, NULL, remove_iter);
+	cleanup_service_irqs(dev);
 	pci_disable_device(dev);
-
-	switch (port_data->port_irq_mode) {
-	case PCIE_PORT_MSIX_MODE:
-		pci_disable_msix(dev);
-		break;
-	case PCIE_PORT_MSI_MODE:
-		pci_disable_msi(dev);
-		break;
-	}
-
-	kfree(port_data);
 }
 
 /**
@@ -565,6 +493,7 @@ int pcie_port_service_register(struct pc
 
 	return driver_register(&new->driver);
 }
+EXPORT_SYMBOL(pcie_port_service_register);
 
 /**
  * pcie_port_service_unregister - unregister PCI Express port service driver
@@ -574,6 +503,4 @@ void pcie_port_service_unregister(struct
 {
 	driver_unregister(&drv->driver);
 }
-
-EXPORT_SYMBOL(pcie_port_service_register);
 EXPORT_SYMBOL(pcie_port_service_unregister);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv.h linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv.h
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,31 +11,16 @@
 
 #include <linux/compiler.h>
 
-#if !defined(PCI_CAP_ID_PME)
-#define PCI_CAP_ID_PME			1
-#endif
-
-#if !defined(PCI_CAP_ID_EXP)
-#define PCI_CAP_ID_EXP			0x10
-#endif
-
-#define PORT_TYPE_MASK			0xf
-#define PORT_TO_SLOT_MASK		0x100
-#define SLOT_HP_CAPABLE_MASK		0x40
-#define PCIE_CAPABILITIES_REG		0x2
-#define PCIE_SLOT_CAPABILITIES_REG	0x14
-#define PCIE_PORT_DEVICE_MAXSERVICES	4
-#define PCIE_PORT_MSI_VECTOR_MASK	0x1f
+#define PCIE_PORT_DEVICE_MAXSERVICES   4
 /*
- * According to the PCI Express Base Specification 2.0, the indices of the MSI-X
- * table entires used by port services must not exceed 31
+ * According to the PCI Express Base Specification 2.0, the indices of
+ * the MSI-X table entires used by port services must not exceed 31
  */
 #define PCIE_PORT_MAX_MSIX_ENTRIES	32
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
 extern struct bus_type pcie_port_bus_type;
-extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
 extern int pcie_port_device_suspend(struct device *dev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_pci.c linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_pci.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pcie/portdrv_pci.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pcie/portdrv_pci.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
  */
 #define DRIVER_VERSION "v1.0"
 #define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
-#define DRIVER_DESC "PCIE Port Bus Driver"
+#define DRIVER_DESC "PCIe Port Bus Driver"
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
@@ -43,7 +43,7 @@ static int pcie_portdrv_restore_config(s
 }
 
 #ifdef CONFIG_PM
-static struct dev_pm_ops pcie_portdrv_pm_ops = {
+static const struct dev_pm_ops pcie_portdrv_pm_ops = {
 	.suspend	= pcie_port_device_suspend,
 	.resume		= pcie_port_device_resume,
 	.freeze		= pcie_port_device_suspend,
@@ -63,20 +63,22 @@ static struct dev_pm_ops pcie_portdrv_pm
  * pcie_portdrv_probe - Probe PCI-Express port devices
  * @dev: PCI-Express port device being probed
  *
- * If detected invokes the pcie_port_device_register() method for 
+ * If detected invokes the pcie_port_device_register() method for
  * this port device.
  *
  */
-static int __devinit pcie_portdrv_probe (struct pci_dev *dev, 
-				const struct pci_device_id *id )
+static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
+					const struct pci_device_id *id)
 {
-	int			status;
+	int status;
 
-	status = pcie_port_device_probe(dev);
-	if (status)
-		return status;
+	if (!pci_is_pcie(dev) ||
+	    ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
+	     (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) &&
+	     (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
+		return -ENODEV;
 
-        if (!dev->irq && dev->pin) {
+	if (!dev->irq && dev->pin) {
 		dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
 			 "check vendor BIOS\n", dev->vendor, dev->device);
 	}
@@ -89,7 +91,7 @@ static int __devinit pcie_portdrv_probe
 	return 0;
 }
 
-static void pcie_portdrv_remove (struct pci_dev *dev)
+static void pcie_portdrv_remove(struct pci_dev *dev)
 {
 	pcie_port_device_remove(dev);
 	pci_disable_device(dev);
@@ -127,14 +129,13 @@ static int error_detected_iter(struct de
 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
 					enum pci_channel_state error)
 {
-	struct aer_broadcast_data result_data =
-			{error, PCI_ERS_RESULT_CAN_RECOVER};
-	int retval;
+	struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER};
+	int ret;
 
 	/* can not fail */
-	retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter);
+	ret = device_for_each_child(&dev->dev, &data, error_detected_iter);
 
-	return result_data.result;
+	return data.result;
 }
 
 static int mmio_enabled_iter(struct device *device, void *data)
@@ -288,7 +289,7 @@ static int __init pcie_portdrv_init(void
 	return retval;
 }
 
-static void __exit pcie_portdrv_exit(void) 
+static void __exit pcie_portdrv_exit(void)
 {
 	pci_unregister_driver(&pcie_portdriver);
 	pcie_port_bus_unregister();
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pci.h linux-libre-2.6.33-gnu1/drivers/pci/pci.h
--- linux-libre-2.6.32-gnu1/drivers/pci/pci.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pci.h	2010-02-24 13:52:17.000000000 -0500
@@ -311,4 +311,14 @@ static inline int pci_resource_alignment
 	return resource_alignment(res);
 }
 
+extern void pci_enable_acs(struct pci_dev *dev);
+
+struct pci_dev_reset_methods {
+	u16 vendor;
+	u16 device;
+	int (*reset)(struct pci_dev *dev, int probe);
+};
+
+extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+
 #endif /* DRIVERS_PCI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/pci-sysfs.c linux-libre-2.6.33-gnu1/drivers/pci/pci-sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/pci/pci-sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/pci-sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -74,7 +74,12 @@ static ssize_t local_cpus_show(struct de
 	const struct cpumask *mask;
 	int len;
 
+#ifdef CONFIG_NUMA
+	mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
+					  cpumask_of_node(dev_to_node(dev));
+#else
 	mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
+#endif
 	len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
 	buf[len++] = '\n';
 	buf[len] = '\0';
@@ -88,7 +93,12 @@ static ssize_t local_cpulist_show(struct
 	const struct cpumask *mask;
 	int len;
 
+#ifdef CONFIG_NUMA
+	mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
+					  cpumask_of_node(dev_to_node(dev));
+#else
 	mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
+#endif
 	len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask);
 	buf[len++] = '\n';
 	buf[len] = '\0';
@@ -176,6 +186,21 @@ numa_node_show(struct device *dev, struc
 #endif
 
 static ssize_t
+dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return sprintf (buf, "%d\n", fls64(pdev->dma_mask));
+}
+
+static ssize_t
+consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr,
+				 char *buf)
+{
+	return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask));
+}
+
+static ssize_t
 msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -306,6 +331,8 @@ struct device_attribute pci_dev_attrs[]
 #ifdef CONFIG_NUMA
 	__ATTR_RO(numa_node),
 #endif
+	__ATTR_RO(dma_mask_bits),
+	__ATTR_RO(consistent_dma_mask_bits),
 	__ATTR(enable, 0600, is_enabled_show, is_enabled_store),
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/probe.c linux-libre-2.6.33-gnu1/drivers/pci/probe.c
--- linux-libre-2.6.32-gnu1/drivers/pci/probe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/probe.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <acpi/acpi_hest.h>
 #include "pci.h"
 
 #define CARDBUS_LATENCY_TIMER	176	/* secondary latency timer */
@@ -163,12 +164,12 @@ int __pci_read_base(struct pci_dev *dev,
 {
 	u32 l, sz, mask;
 
-	mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0;
+	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
 	res->name = pci_name(dev);
 
 	pci_read_config_dword(dev, pos, &l);
-	pci_write_config_dword(dev, pos, mask);
+	pci_write_config_dword(dev, pos, l | mask);
 	pci_read_config_dword(dev, pos, &sz);
 	pci_write_config_dword(dev, pos, l);
 
@@ -223,9 +224,13 @@ int __pci_read_base(struct pci_dev *dev,
 			goto fail;
 
 		if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) {
-			dev_err(&dev->dev, "can't handle 64-bit BAR\n");
+			dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n",
+				pos);
 			goto fail;
-		} else if ((sizeof(resource_size_t) < 8) && l) {
+		}
+
+		res->flags |= IORESOURCE_MEM_64;
+		if ((sizeof(resource_size_t) < 8) && l) {
 			/* Address above 32-bit boundary; disable the BAR */
 			pci_write_config_dword(dev, pos, 0);
 			pci_write_config_dword(dev, pos + 4, 0);
@@ -234,14 +239,9 @@ int __pci_read_base(struct pci_dev *dev,
 		} else {
 			res->start = l64;
 			res->end = l64 + sz64;
-			dev_printk(KERN_DEBUG, &dev->dev,
-				"reg %x %s: %pR\n", pos,
-				 (res->flags & IORESOURCE_PREFETCH) ?
-					"64bit mmio pref" : "64bit mmio",
-				 res);
+			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n",
+				   pos, res);
 		}
-
-		res->flags |= IORESOURCE_MEM_64;
 	} else {
 		sz = pci_size(l, sz, mask);
 
@@ -251,11 +251,7 @@ int __pci_read_base(struct pci_dev *dev,
 		res->start = l;
 		res->end = l + sz;
 
-		dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
-			(res->flags & IORESOURCE_IO) ? "io port" :
-			 ((res->flags & IORESOURCE_PREFETCH) ?
-				 "32bit mmio pref" : "32bit mmio"),
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
 	}
 
  out:
@@ -297,8 +293,11 @@ void __devinit pci_read_bridge_bases(str
 	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
 		return;
 
+	dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
+		 child->secondary, child->subordinate,
+		 dev->transparent ? " (subtractive decode)": "");
+
 	if (dev->transparent) {
-		dev_info(&dev->dev, "transparent bridge\n");
 		for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
 			child->resource[i] = child->parent->resource[i - 3];
 	}
@@ -323,7 +322,7 @@ void __devinit pci_read_bridge_bases(str
 			res->start = base;
 		if (!res->end)
 			res->end = limit + 0xfff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 
 	res = child->resource[1];
@@ -335,8 +334,7 @@ void __devinit pci_read_bridge_bases(str
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 
 	res = child->resource[2];
@@ -375,9 +373,7 @@ void __devinit pci_read_bridge_bases(str
 			res->flags |= IORESOURCE_MEM_64;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
-			(res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
-			res);
+		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
 
@@ -651,13 +647,14 @@ int __devinit pci_scan_bridge(struct pci
 		    (child->number > bus->subordinate) ||
 		    (child->number < bus->number) ||
 		    (child->subordinate < bus->number)) {
-			pr_debug("PCI: Bus #%02x (-#%02x) is %s "
-				"hidden behind%s bridge #%02x (-#%02x)\n",
+			dev_info(&child->dev, "[bus %02x-%02x] %s "
+				"hidden behind%s bridge %s [bus %02x-%02x]\n",
 				child->number, child->subordinate,
 				(bus->number > child->subordinate &&
 				 bus->subordinate < child->number) ?
 					"wholly" : "partially",
 				bus->self->transparent ? " transparent" : "",
+				dev_name(&bus->dev),
 				bus->number, bus->subordinate);
 		}
 		bus = bus->parent;
@@ -684,7 +681,7 @@ static void pci_read_irq(struct pci_dev
 	dev->irq = irq;
 }
 
-static void set_pcie_port_type(struct pci_dev *pdev)
+void set_pcie_port_type(struct pci_dev *pdev)
 {
 	int pos;
 	u16 reg16;
@@ -693,17 +690,18 @@ static void set_pcie_port_type(struct pc
 	if (!pos)
 		return;
 	pdev->is_pcie = 1;
+	pdev->pcie_cap = pos;
 	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
 	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
-static void set_pcie_hotplug_bridge(struct pci_dev *pdev)
+void set_pcie_hotplug_bridge(struct pci_dev *pdev)
 {
 	int pos;
 	u16 reg16;
 	u32 reg32;
 
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(pdev);
 	if (!pos)
 		return;
 	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
@@ -714,6 +712,12 @@ static void set_pcie_hotplug_bridge(stru
 		pdev->is_hotplug_bridge = 1;
 }
 
+static void set_pci_aer_firmware_first(struct pci_dev *pdev)
+{
+	if (acpi_hest_firmware_first_pci(pdev))
+		pdev->aer_firmware_first = 1;
+}
+
 #define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
 /**
@@ -731,6 +735,7 @@ int pci_setup_device(struct pci_dev *dev
 	u32 class;
 	u8 hdr_type;
 	struct pci_slot *slot;
+	int pos = 0;
 
 	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
 		return -EIO;
@@ -742,6 +747,7 @@ int pci_setup_device(struct pci_dev *dev
 	dev->multifunction = !!(hdr_type & 0x80);
 	dev->error_state = pci_channel_io_normal;
 	set_pcie_port_type(dev);
+	set_pci_aer_firmware_first(dev);
 
 	list_for_each_entry(slot, &dev->bus->slots, list)
 		if (PCI_SLOT(dev->devfn) == slot->number)
@@ -822,6 +828,11 @@ int pci_setup_device(struct pci_dev *dev
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
 		set_pcie_hotplug_bridge(dev);
+		pos = pci_find_capability(dev, PCI_CAP_ID_SSVID);
+		if (pos) {
+			pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor);
+			pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device);
+		}
 		break;
 
 	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
@@ -907,7 +918,7 @@ int pci_cfg_space_size(struct pci_dev *d
 	if (class == PCI_CLASS_BRIDGE_HOST)
 		return pci_cfg_space_size_ext(dev);
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pos = pci_pcie_cap(dev);
 	if (!pos) {
 		pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 		if (!pos)
@@ -1014,6 +1025,9 @@ static void pci_init_capabilities(struct
 
 	/* Single Root I/O Virtualization */
 	pci_iov_init(dev);
+
+	/* Enable ACS P2P upstream forwarding */
+	pci_enable_acs(dev);
 }
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1110,7 +1124,7 @@ unsigned int __devinit pci_scan_child_bu
 	unsigned int devfn, pass, max = bus->secondary;
 	struct pci_dev *dev;
 
-	pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
+	dev_dbg(&bus->dev, "scanning bus\n");
 
 	/* Go find them, Rover! */
 	for (devfn = 0; devfn < 0x100; devfn += 8)
@@ -1124,8 +1138,7 @@ unsigned int __devinit pci_scan_child_bu
 	 * all PCI-to-PCI bridges on this bus.
 	 */
 	if (!bus->is_added) {
-		pr_debug("PCI: Fixups for bus %04x:%02x\n",
-			 pci_domain_nr(bus), bus->number);
+		dev_dbg(&bus->dev, "fixups for bus\n");
 		pcibios_fixup_bus(bus);
 		if (pci_is_root_bus(bus))
 			bus->is_added = 1;
@@ -1145,8 +1158,7 @@ unsigned int __devinit pci_scan_child_bu
 	 *
 	 * Return how far we've got finding sub-buses.
 	 */
-	pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n",
-		pci_domain_nr(bus), bus->number, max);
+	dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max);
 	return max;
 }
 
@@ -1154,7 +1166,7 @@ struct pci_bus * pci_create_bus(struct d
 		int bus, struct pci_ops *ops, void *sysdata)
 {
 	int error;
-	struct pci_bus *b;
+	struct pci_bus *b, *b2;
 	struct device *dev;
 
 	b = pci_alloc_bus();
@@ -1170,9 +1182,10 @@ struct pci_bus * pci_create_bus(struct d
 	b->sysdata = sysdata;
 	b->ops = ops;
 
-	if (pci_find_bus(pci_domain_nr(b), bus)) {
+	b2 = pci_find_bus(pci_domain_nr(b), bus);
+	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
-		pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
+		dev_dbg(&b2->dev, "bus already known\n");
 		goto err_out;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/quirks.c linux-libre-2.6.33-gnu1/drivers/pci/quirks.c
--- linux-libre-2.6.32-gnu1/drivers/pci/quirks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/quirks.c	2010-02-24 13:52:17.000000000 -0500
@@ -338,6 +338,23 @@ static void __devinit quirk_s3_64M(struc
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3,	PCI_DEVICE_ID_S3_868,		quirk_s3_64M);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3,	PCI_DEVICE_ID_S3_968,		quirk_s3_64M);
 
+/*
+ * Some CS5536 BIOSes (for example, the Soekris NET5501 board w/ comBIOS
+ * ver. 1.33  20070103) don't set the correct ISA PCI region header info.
+ * BAR0 should be 8 bytes; instead, it may be set to something like 8k
+ * (which conflicts w/ BAR1's memory range).
+ */
+static void __devinit quirk_cs5536_vsa(struct pci_dev *dev)
+{
+	if (pci_resource_len(dev, 0) != 8) {
+		struct resource *res = &dev->resource[0];
+		res->end = res->start + 8 - 1;
+		dev_info(&dev->dev, "CS5536 ISA bridge bug detected "
+				"(incorrect header); workaround applied.\n");
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa);
+
 static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
 	unsigned size, int nr, const char *name)
 {
@@ -357,7 +374,7 @@ static void __devinit quirk_io_region(st
 		pcibios_bus_to_resource(dev, res, &bus_region);
 
 		pci_claim_resource(dev, nr);
-		dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name);
+		dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
 	}
 }	
 
@@ -1680,6 +1697,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_S
  */
 #define AMD_813X_MISC			0x40
 #define AMD_813X_NOIOAMODE		(1<<0)
+#define AMD_813X_REV_B1			0x12
 #define AMD_813X_REV_B2			0x13
 
 static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
@@ -1688,7 +1706,8 @@ static void quirk_disable_amd_813x_boot_
 
 	if (noioapicquirk)
 		return;
-	if (dev->revision == AMD_813X_REV_B2)
+	if ((dev->revision == AMD_813X_REV_B1) ||
+	    (dev->revision == AMD_813X_REV_B2))
 		return;
 
 	pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword);
@@ -1698,8 +1717,10 @@ static void quirk_disable_amd_813x_boot_
 	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8131_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8132_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8131_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8131_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8132_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8132_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
 
 #define AMD_8111_PCI_IRQ_ROUTING	0x56
 
@@ -2595,16 +2616,116 @@ void pci_fixup_device(enum pci_fixup_pas
 static int __init pci_apply_final_quirks(void)
 {
 	struct pci_dev *dev = NULL;
+	u8 cls = 0;
+	u8 tmp;
+
+	if (pci_cache_line_size)
+		printk(KERN_DEBUG "PCI: CLS %u bytes\n",
+		       pci_cache_line_size << 2);
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_fixup_device(pci_fixup_final, dev);
+		/*
+		 * If arch hasn't set it explicitly yet, use the CLS
+		 * value shared by all PCI devices.  If there's a
+		 * mismatch, fall back to the default value.
+		 */
+		if (!pci_cache_line_size) {
+			pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp);
+			if (!cls)
+				cls = tmp;
+			if (!tmp || cls == tmp)
+				continue;
+
+			printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), "
+			       "using %u bytes\n", cls << 2, tmp << 2,
+			       pci_dfl_cache_line_size << 2);
+			pci_cache_line_size = pci_dfl_cache_line_size;
+		}
+	}
+	if (!pci_cache_line_size) {
+		printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
+		       cls << 2, pci_dfl_cache_line_size << 2);
+		pci_cache_line_size = cls ? cls : pci_dfl_cache_line_size;
 	}
 
 	return 0;
 }
 
 fs_initcall_sync(pci_apply_final_quirks);
+
+/*
+ * Followings are device-specific reset methods which can be used to
+ * reset a single function if other methods (e.g. FLR, PM D0->D3) are
+ * not available.
+ */
+static int reset_intel_generic_dev(struct pci_dev *dev, int probe)
+{
+	int pos;
+
+	/* only implement PCI_CLASS_SERIAL_USB at present */
+	if (dev->class == PCI_CLASS_SERIAL_USB) {
+		pos = pci_find_capability(dev, PCI_CAP_ID_VNDR);
+		if (!pos)
+			return -ENOTTY;
+
+		if (probe)
+			return 0;
+
+		pci_write_config_byte(dev, pos + 0x4, 1);
+		msleep(100);
+
+		return 0;
+	} else {
+		return -ENOTTY;
+	}
+}
+
+static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
+{
+	int pos;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return -ENOTTY;
+
+	if (probe)
+		return 0;
+
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
+				PCI_EXP_DEVCTL_BCR_FLR);
+	msleep(100);
+
+	return 0;
+}
+
+#define PCI_DEVICE_ID_INTEL_82599_SFP_VF   0x10ed
+
+static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
+		 reset_intel_82599_sfp_virtfn },
+	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+		reset_intel_generic_dev },
+	{ 0 }
+};
+
+int pci_dev_specific_reset(struct pci_dev *dev, int probe)
+{
+	const struct pci_dev_reset_methods *i;
+
+	for (i = pci_dev_reset_methods; i->reset; i++) {
+		if ((i->vendor == dev->vendor ||
+		     i->vendor == (u16)PCI_ANY_ID) &&
+		    (i->device == dev->device ||
+		     i->device == (u16)PCI_ANY_ID))
+			return i->reset(dev, probe);
+	}
+
+	return -ENOTTY;
+}
+
 #else
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
+int pci_dev_specific_reset(struct pci_dev *dev, int probe) { return -ENOTTY; }
 #endif
 EXPORT_SYMBOL(pci_fixup_device);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/search.c linux-libre-2.6.33-gnu1/drivers/pci/search.c
--- linux-libre-2.6.32-gnu1/drivers/pci/search.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/search.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,9 +15,9 @@
 
 DECLARE_RWSEM(pci_bus_sem);
 /*
- * find the upstream PCIE-to-PCI bridge of a PCI device
+ * find the upstream PCIe-to-PCI bridge of a PCI device
  * if the device is PCIE, return NULL
- * if the device isn't connected to a PCIE bridge (that is its parent is a
+ * if the device isn't connected to a PCIe bridge (that is its parent is a
  * legacy PCI bridge and the bridge is directly connected to bus 0), return its
  * parent
  */
@@ -26,18 +26,18 @@ pci_find_upstream_pcie_bridge(struct pci
 {
 	struct pci_dev *tmp = NULL;
 
-	if (pdev->is_pcie)
+	if (pci_is_pcie(pdev))
 		return NULL;
 	while (1) {
 		if (pci_is_root_bus(pdev->bus))
 			break;
 		pdev = pdev->bus->self;
 		/* a p2p bridge */
-		if (!pdev->is_pcie) {
+		if (!pci_is_pcie(pdev)) {
 			tmp = pdev;
 			continue;
 		}
-		/* PCI device should connect to a PCIE bridge */
+		/* PCI device should connect to a PCIe bridge */
 		if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
 			/* Busted hardware? */
 			WARN_ON_ONCE(1);
@@ -149,32 +149,33 @@ struct pci_dev * pci_get_slot(struct pci
 }
 
 /**
- * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot
- * @bus: number of PCI bus on which desired PCI device resides
- * @devfn: encodes number of PCI slot in which the desired PCI
- * device resides and the logical device number within that slot
- * in case of multi-function devices.
- *
- * Note: the bus/slot search is limited to PCI domain (segment) 0.
+ * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot
+ * @domain: PCI domain/segment on which the PCI device resides.
+ * @bus: PCI bus on which desired PCI device resides
+ * @devfn: encodes number of PCI slot in which the desired PCI device
+ * resides and the logical device number within that slot in case of
+ * multi-function devices.
  *
- * Given a PCI bus and slot/function number, the desired PCI device
- * is located in system global list of PCI devices.  If the device
- * is found, a pointer to its data structure is returned.  If no
- * device is found, %NULL is returned. The returned device has its
- * reference count bumped by one.
+ * Given a PCI domain, bus, and slot/function number, the desired PCI
+ * device is located in the list of PCI devices. If the device is
+ * found, its reference count is increased and this function returns a
+ * pointer to its data structure.  The caller must decrement the
+ * reference count by calling pci_dev_put().  If no device is found,
+ * %NULL is returned.
  */
-
-struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
+struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
+					    unsigned int devfn)
 {
 	struct pci_dev *dev = NULL;
 
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (pci_domain_nr(dev->bus) == 0 &&
-		   (dev->bus->number == bus && dev->devfn == devfn))
+		if (pci_domain_nr(dev->bus) == domain &&
+		    (dev->bus->number == bus && dev->devfn == devfn))
 			return dev;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(pci_get_domain_bus_and_slot);
 
 static int match_pci_dev_by_id(struct device *dev, void *data)
 {
@@ -354,5 +355,4 @@ EXPORT_SYMBOL(pci_find_next_bus);
 EXPORT_SYMBOL(pci_get_device);
 EXPORT_SYMBOL(pci_get_subsys);
 EXPORT_SYMBOL(pci_get_slot);
-EXPORT_SYMBOL(pci_get_bus_and_slot);
 EXPORT_SYMBOL(pci_get_class);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/setup-bus.c linux-libre-2.6.33-gnu1/drivers/pci/setup-bus.c
--- linux-libre-2.6.32-gnu1/drivers/pci/setup-bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/setup-bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,53 +71,50 @@ static void pbus_assign_resources_sorted
 void pci_setup_cardbus(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
+	struct resource *res;
 	struct pci_bus_region region;
 
-	dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n",
-		 pci_domain_nr(bus), bus->number);
+	dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
+		 bus->secondary, bus->subordinate);
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
-	if (bus->resource[0]->flags & IORESOURCE_IO) {
+	res = bus->resource[0];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
 		/*
 		 * The IO resource is allocated a range twice as large as it
 		 * would normally need.  This allows us to set both IO regs.
 		 */
-		dev_info(&bridge->dev, "  IO window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
-	if (bus->resource[1]->flags & IORESOURCE_IO) {
-		dev_info(&bridge->dev, "  IO window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[1];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
-	if (bus->resource[2]->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  PREFETCH window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[2];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
 					region.end);
 	}
 
-	pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
-	if (bus->resource[3]->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  MEM window: %#08lx-%#08lx\n",
-		       (unsigned long)region.start,
-		       (unsigned long)region.end);
+	res = bus->resource[3];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -140,34 +137,33 @@ EXPORT_SYMBOL(pci_setup_cardbus);
 static void pci_setup_bridge(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
+	struct resource *res;
 	struct pci_bus_region region;
 	u32 l, bu, lu, io_upper16;
-	int pref_mem64;
 
 	if (pci_is_enabled(bridge))
 		return;
 
-	dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
-		 pci_domain_nr(bus), bus->number);
+	dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
+		 bus->secondary, bus->subordinate);
 
 	/* Set up the top and bottom of the PCI I/O segment for this bus. */
-	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
-	if (bus->resource[0]->flags & IORESOURCE_IO) {
+	res = bus->resource[0];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_IO) {
 		pci_read_config_dword(bridge, PCI_IO_BASE, &l);
 		l &= 0xffff0000;
 		l |= (region.start >> 8) & 0x00f0;
 		l |= region.end & 0xf000;
 		/* Set up upper 16 bits of I/O base/limit. */
 		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
-		dev_info(&bridge->dev, "  IO window: %#04lx-%#04lx\n",
-		    (unsigned long)region.start,
-		    (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		/* Clear upper 16 bits of I/O base/limit. */
 		io_upper16 = 0;
 		l = 0x00f0;
-		dev_info(&bridge->dev, "  IO window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [io  disabled]\n");
 	}
 	/* Temporarily disable the I/O range before updating PCI_IO_BASE. */
 	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
@@ -178,17 +174,16 @@ static void pci_setup_bridge(struct pci_
 
 	/* Set up the top and bottom of the PCI Memory segment
 	   for this bus. */
-	pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
-	if (bus->resource[1]->flags & IORESOURCE_MEM) {
+	res = bus->resource[1];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_MEM) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		dev_info(&bridge->dev, "  MEM window: %#08lx-%#08lx\n",
-		    (unsigned long)region.start,
-		    (unsigned long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		l = 0x0000fff0;
-		dev_info(&bridge->dev, "  MEM window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [mem disabled]\n");
 	}
 	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
 
@@ -198,34 +193,27 @@ static void pci_setup_bridge(struct pci_
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 	/* Set up PREF base/limit. */
-	pref_mem64 = 0;
 	bu = lu = 0;
-	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
-	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
-		int width = 8;
+	res = bus->resource[2];
+	pcibios_resource_to_bus(bridge, &region, res);
+	if (res->flags & IORESOURCE_PREFETCH) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
-			pref_mem64 = 1;
+		if (res->flags & IORESOURCE_MEM_64) {
 			bu = upper_32_bits(region.start);
 			lu = upper_32_bits(region.end);
-			width = 16;
 		}
-		dev_info(&bridge->dev, "  PREFETCH window: %#0*llx-%#0*llx\n",
-				width, (unsigned long long)region.start,
-				width, (unsigned long long)region.end);
+		dev_info(&bridge->dev, "  bridge window %pR\n", res);
 	}
 	else {
 		l = 0x0000fff0;
-		dev_info(&bridge->dev, "  PREFETCH window: disabled\n");
+		dev_info(&bridge->dev, "  bridge window [mem pref disabled]\n");
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 
-	if (pref_mem64) {
-		/* Set the upper 32 bits of PREF base & limit. */
-		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
-		pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
-	}
+	/* Set the upper 32 bits of PREF base & limit. */
+	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
 
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 }
@@ -345,6 +333,10 @@ static void pbus_size_io(struct pci_bus
 #endif
 	size = ALIGN(size + size1, 4096);
 	if (!size) {
+		if (b_res->start || b_res->end)
+			dev_info(&bus->self->dev, "disabling bridge window "
+				 "%pR to [bus %02x-%02x] (unused)\n", b_res,
+				 bus->secondary, bus->subordinate);
 		b_res->flags = 0;
 		return;
 	}
@@ -390,8 +382,9 @@ static int pbus_size_mem(struct pci_bus
 			align = pci_resource_alignment(dev, r);
 			order = __ffs(align) - 20;
 			if (order > 11) {
-				dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
-					 "%pR\n", i, (unsigned long long)align, r);
+				dev_warn(&dev->dev, "disabling BAR %d: %pR "
+					 "(bad alignment %#llx)\n", i, r,
+					 (unsigned long long) align);
 				r->flags = 0;
 				continue;
 			}
@@ -425,6 +418,10 @@ static int pbus_size_mem(struct pci_bus
 	}
 	size = ALIGN(size, min_align);
 	if (!size) {
+		if (b_res->start || b_res->end)
+			dev_info(&bus->self->dev, "disabling bridge window "
+				 "%pR to [bus %02x-%02x] (unused)\n", b_res,
+				 bus->secondary, bus->subordinate);
 		b_res->flags = 0;
 		return 1;
 	}
@@ -582,10 +579,7 @@ static void pci_bus_dump_res(struct pci_
                 if (!res || !res->end)
                         continue;
 
-		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i,
-			   (res->flags & IORESOURCE_IO) ? "io: " :
-			    ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"),
-			   res);
+		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res);
         }
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pci/setup-res.c linux-libre-2.6.33-gnu1/drivers/pci/setup-res.c
--- linux-libre-2.6.32-gnu1/drivers/pci/setup-res.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pci/setup-res.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev
 
 	pcibios_resource_to_bus(dev, &region, res);
 
-	dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] "
-		"flags %#lx\n", resno, res,
-		 (unsigned long long)region.start,
-		 (unsigned long long)region.end,
-		 (unsigned long)res->flags);
-
 	new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
 	if (res->flags & IORESOURCE_IO)
 		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev
 		}
 	}
 	res->flags &= ~IORESOURCE_UNSET;
-	dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n",
-		resno, (unsigned long long)region.start,
-		(unsigned long long)region.end, res->flags);
+	dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n",
+		 resno, res, (unsigned long long)region.start,
+		 (unsigned long long)region.end);
 }
 
 int pci_claim_resource(struct pci_dev *dev, int resource)
@@ -103,20 +97,17 @@ int pci_claim_resource(struct pci_dev *d
 	int err;
 
 	root = pci_find_parent_resource(dev, res);
-
-	err = -EINVAL;
-	if (root != NULL)
-		err = request_resource(root, res);
-
-	if (err) {
-		const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
-		dev_err(&dev->dev, "BAR %d: %s of %s %pR\n",
-			resource,
-			root ? "address space collision on" :
-				"no parent found for",
-			dtype, res);
+	if (!root) {
+		dev_err(&dev->dev, "no compatible bridge window for %pR\n",
+			res);
+		return -EINVAL;
 	}
 
+	err = request_resource(root, res);
+	if (err)
+		dev_err(&dev->dev,
+			"address space collision: %pR already in use\n", res);
+
 	return err;
 }
 EXPORT_SYMBOL(pci_claim_resource);
@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource);
 #ifdef CONFIG_PCI_QUIRKS
 void pci_disable_bridge_window(struct pci_dev *dev)
 {
-	dev_dbg(&dev->dev, "Disabling bridge window.\n");
+	dev_info(&dev->dev, "disabling bridge mem windows\n");
 
 	/* MMIO Base/Limit */
 	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
@@ -165,6 +156,7 @@ static int __pci_assign_resource(struct
 
 	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
+		dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
 		if (resno < PCI_BRIDGE_RESOURCES)
 			pci_update_resource(dev, resno);
 	}
@@ -178,12 +170,12 @@ int pci_assign_resource(struct pci_dev *
 	resource_size_t align;
 	struct pci_bus *bus;
 	int ret;
+	char *type;
 
 	align = pci_resource_alignment(dev, res);
 	if (!align) {
-		dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
-			"alignment) %pR flags %#lx\n",
-			resno, res, res->flags);
+		dev_info(&dev->dev, "BAR %d: can't assign %pR "
+			 "(bogus alignment)\n", resno, res);
 		return -EINVAL;
 	}
 
@@ -198,9 +190,20 @@ int pci_assign_resource(struct pci_dev *
 		break;
 	}
 
-	if (ret)
-		dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
-			resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
+	if (ret) {
+		if (res->flags & IORESOURCE_MEM)
+			if (res->flags & IORESOURCE_PREFETCH)
+				type = "mem pref";
+			else
+				type = "mem";
+		else if (res->flags & IORESOURCE_IO)
+			type = "io";
+		else
+			type = "unknown";
+		dev_info(&dev->dev,
+			 "BAR %d: can't assign %s (size %#llx)\n",
+			 resno, type, (unsigned long long) resource_size(res));
+	}
 
 	return ret;
 }
@@ -225,9 +228,8 @@ void pdev_sort_resources(struct pci_dev
 
 		r_align = pci_resource_alignment(dev, r);
 		if (!r_align) {
-			dev_warn(&dev->dev, "BAR %d: bogus alignment "
-				"%pR flags %#lx\n",
-				i, r, r->flags);
+			dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
+				 i, r);
 			continue;
 		}
 		for (list = head; ; list = list->next) {
@@ -274,8 +276,8 @@ int pci_enable_resources(struct pci_dev
 			continue;
 
 		if (!r->parent) {
-			dev_err(&dev->dev, "device not available because of "
-				"BAR %d %pR collisions\n", i, r);
+			dev_err(&dev->dev, "device not available "
+				"(can't reserve %pR)\n", r);
 			return -EINVAL;
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/cardbus.c linux-libre-2.6.33-gnu1/drivers/pcmcia/cardbus.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/cardbus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/cardbus.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,8 +27,8 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -58,7 +58,7 @@
     image number and an offset within that image.  xlate_rom_addr()
     converts an image/offset address to an absolute offset from the
     ROM's base address.
-    
+
 =====================================================================*/
 
 static u_int xlate_rom_addr(void __iomem *b, u_int addr)
@@ -85,20 +85,20 @@ static u_int xlate_rom_addr(void __iomem
     These are similar to setup_cis_mem and release_cis_mem for 16-bit
     cards.  The "result" that is used externally is the cb_cis_virt
     pointer in the struct pcmcia_socket structure.
-    
+
 =====================================================================*/
 
-static void cb_release_cis_mem(struct pcmcia_socket * s)
+static void cb_release_cis_mem(struct pcmcia_socket *s)
 {
 	if (s->cb_cis_virt) {
-		cs_dbg(s, 1, "cb_release_cis_mem()\n");
+		dev_dbg(&s->dev, "cb_release_cis_mem()\n");
 		iounmap(s->cb_cis_virt);
 		s->cb_cis_virt = NULL;
 		s->cb_cis_res = NULL;
 	}
 }
 
-static int cb_setup_cis_mem(struct pcmcia_socket * s, struct resource *res)
+static int cb_setup_cis_mem(struct pcmcia_socket *s, struct resource *res)
 {
 	unsigned int start, size;
 
@@ -124,15 +124,16 @@ static int cb_setup_cis_mem(struct pcmci
 
     This is used by the CIS processing code to read CIS information
     from a CardBus device.
-    
+
 =====================================================================*/
 
-int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void *ptr)
+int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
+		void *ptr)
 {
 	struct pci_dev *dev;
 	struct resource *res;
 
-	cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
+	dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
 
 	dev = pci_get_slot(s->cb_dev->subordinate, 0);
 	if (!dev)
@@ -181,40 +182,47 @@ fail:
     cb_alloc() and cb_free() allocate and free the kernel data
     structures for a Cardbus device, and handle the lowest level PCI
     device setup issues.
-    
+
 =====================================================================*/
 
-/*
- * Since there is only one interrupt available to CardBus
- * devices, all devices downstream of this device must
- * be using this IRQ.
- */
-static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
+static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
 {
 	struct pci_dev *dev;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u8 irq_pin;
 
+		/*
+		 * Since there is only one interrupt available to
+		 * CardBus devices, all devices downstream of this
+		 * device must be using this IRQ.
+		 */
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
 		if (irq_pin) {
 			dev->irq = irq;
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 		}
 
+		/*
+		 * Some controllers transfer very slowly with 0 CLS.
+		 * Configure it.  This may fail as CLS configuration
+		 * is mandatory only for MWI.
+		 */
+		pci_set_cacheline_size(dev);
+
 		if (dev->subordinate)
-			cardbus_assign_irqs(dev->subordinate, irq);
+			cardbus_config_irq_and_cls(dev->subordinate, irq);
 	}
 }
 
-int __ref cb_alloc(struct pcmcia_socket * s)
+int __ref cb_alloc(struct pcmcia_socket *s)
 {
 	struct pci_bus *bus = s->cb_dev->subordinate;
 	struct pci_dev *dev;
 	unsigned int max, pass;
 
 	s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
-//	pcibios_fixup_bus(bus);
+	pci_fixup_cardbus(bus); 
 
 	max = bus->secondary;
 	for (pass = 0; pass < 2; pass++)
@@ -228,7 +236,7 @@ int __ref cb_alloc(struct pcmcia_socket
 	 */
 	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
-	cardbus_assign_irqs(bus, s->pci_irq);
+	cardbus_config_irq_and_cls(bus, s->pci_irq);
 
 	/* socket specific tune function */
 	if (s->tune_bridge)
@@ -241,7 +249,7 @@ int __ref cb_alloc(struct pcmcia_socket
 	return 0;
 }
 
-void cb_free(struct pcmcia_socket * s)
+void cb_free(struct pcmcia_socket *s)
 {
 	struct pci_dev *bridge = s->cb_dev;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/cirrus.h linux-libre-2.6.33-gnu1/drivers/pcmcia/cirrus.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/cirrus.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/cirrus.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,16 +30,6 @@
 #ifndef _LINUX_CIRRUS_H
 #define _LINUX_CIRRUS_H
 
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS		0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6729
-#define PCI_DEVICE_ID_CIRRUS_6729	0x1100
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6832
-#define PCI_DEVICE_ID_CIRRUS_6832	0x1110
-#endif
-
 #define PD67_MISC_CTL_1		0x16	/* Misc control 1 */
 #define PD67_FIFO_CTL		0x17	/* FIFO control */
 #define PD67_MISC_CTL_2		0x1E	/* Misc control 2 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/cistpl.c linux-libre-2.6.33-gnu1/drivers/pcmcia/cistpl.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/cistpl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/cistpl.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
@@ -125,7 +125,7 @@ set_cis_map(struct pcmcia_socket *s, uns
 
     Low-level functions to read and write CIS memory.  I think the
     write routine is only useful for writing one-byte registers.
-    
+
 ======================================================================*/
 
 /* Bits in attr field */
@@ -137,8 +137,8 @@ int pcmcia_read_cis_mem(struct pcmcia_so
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
-    
-    cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+
+    dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
@@ -190,7 +190,7 @@ int pcmcia_read_cis_mem(struct pcmcia_so
 	    addr = 0;
 	}
     }
-    cs_dbg(s, 3, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
+    dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
 	  *(u_char *)(ptr+0), *(u_char *)(ptr+1),
 	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
     return 0;
@@ -203,8 +203,8 @@ void pcmcia_write_cis_mem(struct pcmcia_
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
-    
-    cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+
+    dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
@@ -262,7 +262,7 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
     This is a wrapper around read_cis_mem, with the same interface,
     but which caches information, for cards whose CIS may not be
     readable all the time.
-    
+
 ======================================================================*/
 
 static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
@@ -342,7 +342,7 @@ EXPORT_SYMBOL(destroy_cis_cache);
 
     This verifies if the CIS of a card matches what is in the CIS
     cache.
-    
+
 ======================================================================*/
 
 int verify_cis_cache(struct pcmcia_socket *s)
@@ -381,7 +381,7 @@ int verify_cis_cache(struct pcmcia_socke
 
     For really bad cards, we provide a facility for uploading a
     replacement CIS.
-    
+
 ======================================================================*/
 
 int pcmcia_replace_cis(struct pcmcia_socket *s,
@@ -406,7 +406,7 @@ EXPORT_SYMBOL(pcmcia_replace_cis);
 /*======================================================================
 
     The high-level CIS tuple services
-    
+
 ======================================================================*/
 
 typedef struct tuple_flags {
@@ -421,8 +421,6 @@ typedef struct tuple_flags {
 #define MFC_FN(f)	(((tuple_flags *)(&(f)))->mfc_fn)
 #define SPACE(f)	(((tuple_flags *)(&(f)))->space)
 
-int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
-
 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
 {
     if (!s)
@@ -523,10 +521,11 @@ int pccard_get_next_tuple(struct pcmcia_
 		ofs++; continue;
 	    }
 	}
-	
+
 	/* End of chain?  Follow long link if possible */
 	if (link[0] == CISTPL_END) {
-	    if ((ofs = follow_link(s, tuple)) < 0)
+	    ofs = follow_link(s, tuple);
+	    if (ofs < 0)
 		return -ENOSPC;
 	    attr = SPACE(tuple->Flags);
 	    read_cis_cache(s, attr, ofs, 2, link);
@@ -578,16 +577,16 @@ int pccard_get_next_tuple(struct pcmcia_
 	} else
 	    if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
 		break;
-	
+
 	if (link[0] == tuple->DesiredTuple)
 	    break;
 	ofs += link[1] + 2;
     }
     if (i == MAX_TUPLES) {
-	cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
+	dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
 	return -ENOSPC;
     }
-    
+
     tuple->TupleCode = link[0];
     tuple->TupleLink = link[1];
     tuple->CISOffset = ofs + 2;
@@ -623,7 +622,7 @@ EXPORT_SYMBOL(pccard_get_tuple_data);
 /*======================================================================
 
     Parsing routines for individual tuples
-    
+
 ======================================================================*/
 
 static int parse_device(tuple_t *tuple, cistpl_device_t *device)
@@ -637,26 +636,37 @@ static int parse_device(tuple_t *tuple,
 
     device->ndev = 0;
     for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
-	
-	if (*p == 0xff) break;
+
+	if (*p == 0xff)
+		break;
 	device->dev[i].type = (*p >> 4);
 	device->dev[i].wp = (*p & 0x08) ? 1 : 0;
 	switch (*p & 0x07) {
-	case 0: device->dev[i].speed = 0;   break;
-	case 1: device->dev[i].speed = 250; break;
-	case 2: device->dev[i].speed = 200; break;
-	case 3: device->dev[i].speed = 150; break;
-	case 4: device->dev[i].speed = 100; break;
+	case 0:
+		device->dev[i].speed = 0;
+		break;
+	case 1:
+		device->dev[i].speed = 250;
+		break;
+	case 2:
+		device->dev[i].speed = 200;
+		break;
+	case 3:
+		device->dev[i].speed = 150;
+		break;
+	case 4:
+		device->dev[i].speed = 100;
+		break;
 	case 7:
-	    if (++p == q)
-		    return -EINVAL;
-	    device->dev[i].speed = SPEED_CVT(*p);
-	    while (*p & 0x80)
 		if (++p == q)
 			return -EINVAL;
-	    break;
+		device->dev[i].speed = SPEED_CVT(*p);
+		while (*p & 0x80)
+			if (++p == q)
+				return -EINVAL;
+		break;
 	default:
-	    return -EINVAL;
+		return -EINVAL;
 	}
 
 	if (++p == q)
@@ -671,7 +681,7 @@ static int parse_device(tuple_t *tuple,
 	if (++p == q)
 		break;
     }
-    
+
     return 0;
 }
 
@@ -706,9 +716,9 @@ static int parse_longlink_mfc(tuple_t *t
 {
     u_char *p;
     int i;
-    
+
     p = (u_char *)tuple->TupleData;
-    
+
     link->nfn = *p; p++;
     if (tuple->TupleDataLen <= link->nfn*5)
 	return -EINVAL;
@@ -737,11 +747,13 @@ static int parse_strings(u_char *p, u_ch
 	ns++;
 	for (;;) {
 	    s[j++] = (*p == 0xff) ? '\0' : *p;
-	    if ((*p == '\0') || (*p == 0xff)) break;
+	    if ((*p == '\0') || (*p == 0xff))
+		    break;
 	    if (++p == q)
 		    return -EINVAL;
 	}
-	if ((*p == 0xff) || (++p == q)) break;
+	if ((*p == 0xff) || (++p == q))
+		break;
     }
     if (found) {
 	*found = ns;
@@ -756,10 +768,10 @@ static int parse_strings(u_char *p, u_ch
 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
 {
     u_char *p, *q;
-    
+
     p = (u_char *)tuple->TupleData;
     q = p + tuple->TupleDataLen;
-    
+
     vers_1->major = *p; p++;
     vers_1->minor = *p; p++;
     if (p >= q)
@@ -774,10 +786,10 @@ static int parse_vers_1(tuple_t *tuple,
 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
 {
     u_char *p, *q;
-    
+
     p = (u_char *)tuple->TupleData;
     q = p + tuple->TupleDataLen;
-    
+
     return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
 			 altstr->str, altstr->ofs, &altstr->ns);
 }
@@ -793,7 +805,8 @@ static int parse_jedec(tuple_t *tuple, c
     q = p + tuple->TupleDataLen;
 
     for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
-	if (p > q-2) break;
+	if (p > q-2)
+		break;
 	jedec->id[nid].mfr = p[0];
 	jedec->id[nid].info = p[1];
 	p += 2;
@@ -871,7 +884,7 @@ static int parse_config(tuple_t *tuple,
 
     The following routines are all used to parse the nightmarish
     config table entries.
-    
+
 ======================================================================*/
 
 static u_char *parse_power(u_char *p, u_char *q,
@@ -880,17 +893,20 @@ static u_char *parse_power(u_char *p, u_
     int i;
     u_int scale;
 
-    if (p == q) return NULL;
+    if (p == q)
+	    return NULL;
     pwr->present = *p;
     pwr->flags = 0;
     p++;
     for (i = 0; i < 7; i++)
 	if (pwr->present & (1<<i)) {
-	    if (p == q) return NULL;
+	    if (p == q)
+		    return NULL;
 	    pwr->param[i] = POWER_CVT(*p);
 	    scale = POWER_SCALE(*p);
 	    while (*p & 0x80) {
-		if (++p == q) return NULL;
+		if (++p == q)
+			return NULL;
 		if ((*p & 0x7f) < 100)
 		    pwr->param[i] += (*p & 0x7f) * scale / 100;
 		else if (*p == 0x7d)
@@ -914,24 +930,28 @@ static u_char *parse_timing(u_char *p, u
 {
     u_char scale;
 
-    if (p == q) return NULL;
+    if (p == q)
+	    return NULL;
     scale = *p;
     if ((scale & 3) != 3) {
-	if (++p == q) return NULL;
+	if (++p == q)
+		return NULL;
 	timing->wait = SPEED_CVT(*p);
 	timing->waitscale = exponent[scale & 3];
     } else
 	timing->wait = 0;
     scale >>= 2;
     if ((scale & 7) != 7) {
-	if (++p == q) return NULL;
+	if (++p == q)
+		return NULL;
 	timing->ready = SPEED_CVT(*p);
 	timing->rdyscale = exponent[scale & 7];
     } else
 	timing->ready = 0;
     scale >>= 3;
     if (scale != 7) {
-	if (++p == q) return NULL;
+	if (++p == q)
+		return NULL;
 	timing->reserved = SPEED_CVT(*p);
 	timing->rsvscale = exponent[scale];
     } else
@@ -946,7 +966,8 @@ static u_char *parse_io(u_char *p, u_cha
 {
     int i, j, bsz, lsz;
 
-    if (p == q) return NULL;
+    if (p == q)
+	    return NULL;
     io->flags = *p;
 
     if (!(*p & 0x80)) {
@@ -955,24 +976,29 @@ static u_char *parse_io(u_char *p, u_cha
 	io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
 	return p+1;
     }
-    
-    if (++p == q) return NULL;
+
+    if (++p == q)
+	    return NULL;
     io->nwin = (*p & 0x0f) + 1;
     bsz = (*p & 0x30) >> 4;
-    if (bsz == 3) bsz++;
+    if (bsz == 3)
+	    bsz++;
     lsz = (*p & 0xc0) >> 6;
-    if (lsz == 3) lsz++;
+    if (lsz == 3)
+	    lsz++;
     p++;
-    
+
     for (i = 0; i < io->nwin; i++) {
 	io->win[i].base = 0;
 	io->win[i].len = 1;
 	for (j = 0; j < bsz; j++, p++) {
-	    if (p == q) return NULL;
+	    if (p == q)
+		    return NULL;
 	    io->win[i].base += *p << (j*8);
 	}
 	for (j = 0; j < lsz; j++, p++) {
-	    if (p == q) return NULL;
+	    if (p == q)
+		    return NULL;
 	    io->win[i].len += *p << (j*8);
 	}
     }
@@ -986,27 +1012,32 @@ static u_char *parse_mem(u_char *p, u_ch
     int i, j, asz, lsz, has_ha;
     u_int len, ca, ha;
 
-    if (p == q) return NULL;
+    if (p == q)
+	    return NULL;
 
     mem->nwin = (*p & 0x07) + 1;
     lsz = (*p & 0x18) >> 3;
     asz = (*p & 0x60) >> 5;
     has_ha = (*p & 0x80);
-    if (++p == q) return NULL;
-    
+    if (++p == q)
+	    return NULL;
+
     for (i = 0; i < mem->nwin; i++) {
 	len = ca = ha = 0;
 	for (j = 0; j < lsz; j++, p++) {
-	    if (p == q) return NULL;
+	    if (p == q)
+		    return NULL;
 	    len += *p << (j*8);
 	}
 	for (j = 0; j < asz; j++, p++) {
-	    if (p == q) return NULL;
+	    if (p == q)
+		    return NULL;
 	    ca += *p << (j*8);
 	}
 	if (has_ha)
 	    for (j = 0; j < asz; j++, p++) {
-		if (p == q) return NULL;
+		if (p == q)
+			return NULL;
 		ha += *p << (j*8);
 	    }
 	mem->win[i].len = len << 8;
@@ -1095,7 +1126,7 @@ static int parse_cftable_entry(tuple_t *
 	entry->timing.ready = 0;
 	entry->timing.reserved = 0;
     }
-    
+
     /* I/O window options */
     if (features & 0x08) {
 	p = parse_io(p, q, &entry->io);
@@ -1103,7 +1134,7 @@ static int parse_cftable_entry(tuple_t *
 		return -EINVAL;
     } else
 	entry->io.nwin = 0;
-    
+
     /* Interrupt options */
     if (features & 0x10) {
 	p = parse_irq(p, q, &entry->irq);
@@ -1153,7 +1184,7 @@ static int parse_cftable_entry(tuple_t *
     }
 
     entry->subtuples = q-p;
-    
+
     return 0;
 }
 
@@ -1176,7 +1207,7 @@ static int parse_bar(tuple_t *tuple, cis
 static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
 {
     u_char *p;
-    
+
     p = (u_char *)tuple->TupleData;
     if ((*p != 3) || (tuple->TupleDataLen < 6))
 	return -EINVAL;
@@ -1231,7 +1262,7 @@ static int parse_cftable_entry_cb(tuple_
 	entry->io = *p; p++;
     } else
 	entry->io = 0;
-    
+
     /* Interrupt options */
     if (features & 0x10) {
 	p = parse_irq(p, q, &entry->irq);
@@ -1264,7 +1295,7 @@ static int parse_cftable_entry_cb(tuple_
     }
 
     entry->subtuples = q-p;
-    
+
     return 0;
 }
 
@@ -1281,7 +1312,8 @@ static int parse_device_geo(tuple_t *tup
     q = p + tuple->TupleDataLen;
 
     for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
-	if (p > q-6) break;
+	if (p > q-6)
+		break;
 	geo->geo[n].buswidth = p[0];
 	geo->geo[n].erase_block = 1 << (p[1]-1);
 	geo->geo[n].read_block  = 1 << (p[2]-1);
@@ -1302,13 +1334,13 @@ static int parse_vers_2(tuple_t *tuple,
 
     if (tuple->TupleDataLen < 10)
 	return -EINVAL;
-    
+
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
 
     v2->vers = p[0];
     v2->comply = p[1];
-    v2->dindex = get_unaligned_le16(p +2 );
+    v2->dindex = get_unaligned_le16(p + 2);
     v2->vspec8 = p[6];
     v2->vspec9 = p[7];
     v2->nhdr = p[8];
@@ -1322,7 +1354,7 @@ static int parse_org(tuple_t *tuple, cis
 {
     u_char *p, *q;
     int i;
-    
+
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
     if (p == q)
@@ -1332,7 +1364,8 @@ static int parse_org(tuple_t *tuple, cis
 	    return -EINVAL;
     for (i = 0; i < 30; i++) {
 	org->desc[i] = *p;
-	if (*p == '\0') break;
+	if (*p == '\0')
+		break;
 	if (++p == q)
 		return -EINVAL;
     }
@@ -1363,7 +1396,7 @@ static int parse_format(tuple_t *tuple,
 int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
 {
     int ret = 0;
-    
+
     if (tuple->TupleDataLen > tuple->TupleDataMax)
 	return -EINVAL;
     switch (tuple->TupleCode) {
@@ -1440,7 +1473,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, c
 	break;
     }
     if (ret)
-	    __cs_dbg(0, "parse_tuple failed %d\n", ret);
+	    pr_debug("parse_tuple failed %d\n", ret);
     return ret;
 }
 EXPORT_SYMBOL(pcmcia_parse_tuple);
@@ -1448,7 +1481,7 @@ EXPORT_SYMBOL(pcmcia_parse_tuple);
 /*======================================================================
 
     This is used internally by Card Services to look up CIS stuff.
-    
+
 ======================================================================*/
 
 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse)
@@ -1482,6 +1515,67 @@ done:
 }
 EXPORT_SYMBOL(pccard_read_tuple);
 
+
+/**
+ * pccard_loop_tuple() - loop over tuples in the CIS
+ * @s:		the struct pcmcia_socket where the card is inserted
+ * @function:	the device function we loop for
+ * @code:	which CIS code shall we look for?
+ * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
+ * @priv_data:	private data to be passed to the loop_tuple function.
+ * @loop_tuple:	function to call for each CIS entry of type @function. IT
+ *		gets passed the raw tuple, the paresed tuple (if @parse is
+ *		set) and @priv_data.
+ *
+ * pccard_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+		      cisdata_t code, cisparse_t *parse, void *priv_data,
+		      int (*loop_tuple) (tuple_t *tuple,
+					 cisparse_t *parse,
+					 void *priv_data))
+{
+	tuple_t tuple;
+	cisdata_t *buf;
+	int ret;
+
+	buf = kzalloc(256, GFP_KERNEL);
+	if (buf == NULL) {
+		dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+		return -ENOMEM;
+	}
+
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = 255;
+	tuple.TupleOffset = 0;
+	tuple.DesiredTuple = code;
+	tuple.Attributes = 0;
+
+	ret = pccard_get_first_tuple(s, function, &tuple);
+	while (!ret) {
+		if (pccard_get_tuple_data(s, &tuple))
+			goto next_entry;
+
+		if (parse)
+			if (pcmcia_parse_tuple(&tuple, parse))
+				goto next_entry;
+
+		ret = loop_tuple(&tuple, parse, priv_data);
+		if (!ret)
+			break;
+
+next_entry:
+		ret = pccard_get_next_tuple(s, function, &tuple);
+	}
+
+	kfree(buf);
+	return ret;
+}
+EXPORT_SYMBOL(pccard_loop_tuple);
+
+
 /*======================================================================
 
     This tries to determine if a card has a sensible CIS.  It returns
@@ -1489,7 +1583,7 @@ EXPORT_SYMBOL(pccard_read_tuple);
     checks include making sure several critical tuples are present and
     valid; seeing if the total number of tuples is reasonable; and
     looking for tuples that use reserved codes.
-    
+
 ======================================================================*/
 
 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/cs.c linux-libre-2.6.33-gnu1/drivers/pcmcia/cs.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -61,17 +61,6 @@ INT_MODULE_PARM(unreset_limit,	30);		/*
 /* Access speed for attribute memory windows */
 INT_MODULE_PARM(cis_speed,	300);		/* ns */
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-int cs_debug_level(int level)
-{
-	return pc_debug > level;
-}
-#endif
-
 
 socket_state_t dead_socket = {
 	.csc_mask	= SS_DETECT,
@@ -146,7 +135,7 @@ int pcmcia_socket_dev_resume(struct devi
 EXPORT_SYMBOL(pcmcia_socket_dev_resume);
 
 
-struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
+struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)
 {
 	struct device *dev = get_device(&skt->dev);
 	if (!dev)
@@ -156,7 +145,7 @@ struct pcmcia_socket * pcmcia_get_socket
 		put_device(&skt->dev);
 		return NULL;
 	}
-	return (skt);
+	return skt;
 }
 EXPORT_SYMBOL(pcmcia_get_socket);
 
@@ -190,7 +179,7 @@ int pcmcia_register_socket(struct pcmcia
 	if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
 		return -EINVAL;
 
-	cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
+	dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
 
 	spin_lock_init(&socket->lock);
 
@@ -262,6 +251,13 @@ int pcmcia_register_socket(struct pcmcia
 
 	pcmcia_parse_events(socket, SS_DETECT);
 
+	/*
+	 * Let's try to get the PCMCIA module for 16-bit PCMCIA support.
+	 * If it fails, it doesn't matter -- we still have 32-bit CardBus
+	 * support to offer, so this is not a failure mode.
+	 */
+	request_module_nowait("pcmcia");
+
 	return 0;
 
  err:
@@ -282,7 +278,7 @@ void pcmcia_unregister_socket(struct pcm
 	if (!socket)
 		return;
 
-	cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
+	dev_dbg(&socket->dev, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
 
 	if (socket->thread)
 		kthread_stop(socket->thread);
@@ -301,7 +297,7 @@ void pcmcia_unregister_socket(struct pcm
 EXPORT_SYMBOL(pcmcia_unregister_socket);
 
 
-struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
+struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr)
 {
 	struct pcmcia_socket *s;
 
@@ -335,7 +331,7 @@ static int send_event(struct pcmcia_sock
 	if (s->state & SOCKET_CARDBUS)
 		return 0;
 
-	cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
+	dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
 	   event, priority, s->callback);
 
 	if (!s->callback)
@@ -352,7 +348,7 @@ static int send_event(struct pcmcia_sock
 
 static void socket_remove_drivers(struct pcmcia_socket *skt)
 {
-	cs_dbg(skt, 4, "remove_drivers\n");
+	dev_dbg(&skt->dev, "remove_drivers\n");
 
 	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 }
@@ -361,7 +357,7 @@ static int socket_reset(struct pcmcia_so
 {
 	int status, i;
 
-	cs_dbg(skt, 4, "reset\n");
+	dev_dbg(&skt->dev, "reset\n");
 
 	skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
 	skt->ops->set_socket(skt, &skt->socket);
@@ -383,7 +379,7 @@ static int socket_reset(struct pcmcia_so
 		msleep(unreset_check * 10);
 	}
 
-	cs_err(skt, "time out after reset.\n");
+	dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n");
 	return -ETIMEDOUT;
 }
 
@@ -397,7 +393,7 @@ static void socket_shutdown(struct pcmci
 {
 	int status;
 
-	cs_dbg(s, 4, "shutdown\n");
+	dev_dbg(&s->dev, "shutdown\n");
 
 	socket_remove_drivers(s);
 	s->state &= SOCKET_INUSE | SOCKET_PRESENT;
@@ -432,7 +428,7 @@ static int socket_setup(struct pcmcia_so
 {
 	int status, i;
 
-	cs_dbg(skt, 4, "setup\n");
+	dev_dbg(&skt->dev, "setup\n");
 
 	skt->ops->get_status(skt, &status);
 	if (!(status & SS_DETECT))
@@ -452,13 +448,15 @@ static int socket_setup(struct pcmcia_so
 	}
 
 	if (status & SS_PENDING) {
-		cs_err(skt, "voltage interrogation timed out.\n");
+		dev_printk(KERN_ERR, &skt->dev,
+			   "voltage interrogation timed out.\n");
 		return -ETIMEDOUT;
 	}
 
 	if (status & SS_CARDBUS) {
 		if (!(skt->features & SS_CAP_CARDBUS)) {
-			cs_err(skt, "cardbus cards are not supported.\n");
+			dev_printk(KERN_ERR, &skt->dev,
+				"cardbus cards are not supported.\n");
 			return -EINVAL;
 		}
 		skt->state |= SOCKET_CARDBUS;
@@ -472,7 +470,7 @@ static int socket_setup(struct pcmcia_so
 	else if (!(status & SS_XVCARD))
 		skt->socket.Vcc = skt->socket.Vpp = 50;
 	else {
-		cs_err(skt, "unsupported voltage key.\n");
+		dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n");
 		return -EIO;
 	}
 
@@ -489,7 +487,7 @@ static int socket_setup(struct pcmcia_so
 
 	skt->ops->get_status(skt, &status);
 	if (!(status & SS_POWERON)) {
-		cs_err(skt, "unable to apply power.\n");
+		dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n");
 		return -EIO;
 	}
 
@@ -509,7 +507,7 @@ static int socket_insert(struct pcmcia_s
 {
 	int ret;
 
-	cs_dbg(skt, 4, "insert\n");
+	dev_dbg(&skt->dev, "insert\n");
 
 	if (!cs_socket_get(skt))
 		return -ENODEV;
@@ -529,7 +527,7 @@ static int socket_insert(struct pcmcia_s
 			skt->state |= SOCKET_CARDBUS_CONFIG;
 		}
 #endif
-		cs_dbg(skt, 4, "insert done\n");
+		dev_dbg(&skt->dev, "insert done\n");
 
 		send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	} else {
@@ -576,7 +574,7 @@ static int socket_late_resume(struct pcm
 		 * FIXME: need a better check here for cardbus cards.
 		 */
 		if (verify_cis_cache(skt) != 0) {
-			cs_dbg(skt, 4, "cis mismatch - different card\n");
+			dev_dbg(&skt->dev, "cis mismatch - different card\n");
 			socket_remove_drivers(skt);
 			destroy_cis_cache(skt);
 			/*
@@ -587,7 +585,7 @@ static int socket_late_resume(struct pcm
 			msleep(200);
 			send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 		} else {
-			cs_dbg(skt, 4, "cis matches cache\n");
+			dev_dbg(&skt->dev, "cis matches cache\n");
 			send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
 		}
 	} else {
@@ -723,7 +721,7 @@ static int pccardd(void *__skt)
 void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
 {
 	unsigned long flags;
-	cs_dbg(s, 4, "parse_events: events %08x\n", events);
+	dev_dbg(&s->dev, "parse_events: events %08x\n", events);
 	if (s->thread) {
 		spin_lock_irqsave(&s->thread_lock, flags);
 		s->thread_events |= events;
@@ -738,7 +736,7 @@ EXPORT_SYMBOL(pcmcia_parse_events);
 /* register pcmcia_callback */
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
 {
-        int ret = 0;
+	int ret = 0;
 
 	/* s->skt_mutex also protects s->callback */
 	mutex_lock(&s->skt_mutex);
@@ -773,19 +771,22 @@ int pcmcia_reset_card(struct pcmcia_sock
 {
 	int ret;
 
-	cs_dbg(skt, 1, "resetting socket\n");
+	dev_dbg(&skt->dev, "resetting socket\n");
 
 	mutex_lock(&skt->skt_mutex);
 	do {
 		if (!(skt->state & SOCKET_PRESENT)) {
+			dev_dbg(&skt->dev, "can't reset, not present\n");
 			ret = -ENODEV;
 			break;
 		}
 		if (skt->state & SOCKET_SUSPEND) {
+			dev_dbg(&skt->dev, "can't reset, suspended\n");
 			ret = -EBUSY;
 			break;
 		}
 		if (skt->state & SOCKET_CARDBUS) {
+			dev_dbg(&skt->dev, "can't reset, is cardbus\n");
 			ret = -EPERM;
 			break;
 		}
@@ -818,7 +819,7 @@ int pcmcia_suspend_card(struct pcmcia_so
 {
 	int ret;
 
-	cs_dbg(skt, 1, "suspending socket\n");
+	dev_dbg(&skt->dev, "suspending socket\n");
 
 	mutex_lock(&skt->skt_mutex);
 	do {
@@ -847,8 +848,8 @@ EXPORT_SYMBOL(pcmcia_suspend_card);
 int pcmcia_resume_card(struct pcmcia_socket *skt)
 {
 	int ret;
-    
-	cs_dbg(skt, 1, "waking up socket\n");
+
+	dev_dbg(&skt->dev, "waking up socket\n");
 
 	mutex_lock(&skt->skt_mutex);
 	do {
@@ -875,8 +876,8 @@ EXPORT_SYMBOL(pcmcia_resume_card);
 int pcmcia_eject_card(struct pcmcia_socket *skt)
 {
 	int ret;
-    
-	cs_dbg(skt, 1, "user eject request\n");
+
+	dev_dbg(&skt->dev, "user eject request\n");
 
 	mutex_lock(&skt->skt_mutex);
 	do {
@@ -905,7 +906,7 @@ int pcmcia_insert_card(struct pcmcia_soc
 {
 	int ret;
 
-	cs_dbg(skt, 1, "user insert request\n");
+	dev_dbg(&skt->dev, "user insert request\n");
 
 	mutex_lock(&skt->skt_mutex);
 	do {
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/cs_internal.h linux-libre-2.6.33-gnu1/drivers/pcmcia/cs_internal.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/cs_internal.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/cs_internal.h	2010-02-24 13:52:17.000000000 -0500
@@ -107,28 +107,6 @@ static inline void cs_socket_put(struct
 	}
 }
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int cs_debug_level(int);
-
-#define cs_dbg(skt, lvl, fmt, arg...) do {		\
-	if (cs_debug_level(lvl))			\
-		dev_printk(KERN_DEBUG, &skt->dev,	\
-		 "cs: " fmt, ## arg);			\
-} while (0)
-#define __cs_dbg(lvl, fmt, arg...) do {			\
-	if (cs_debug_level(lvl))			\
-		printk(KERN_DEBUG 			\
-		 "cs: " fmt, ## arg);			\
-} while (0)
-
-#else
-#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
-#define cs_err(skt, fmt, arg...) \
-	dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
-
 
 /*
  * Stuff internal to module "pcmcia_core":
@@ -170,10 +148,6 @@ extern struct rw_semaphore pcmcia_socket
 extern struct list_head pcmcia_socket_list;
 extern struct class pcmcia_socket_class;
 
-int pcmcia_get_window(struct pcmcia_socket *s,
-		      window_handle_t *handle,
-		      int idx,
-		      win_req_t *req);
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
 struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
 
@@ -199,6 +173,22 @@ int pcmcia_replace_cis(struct pcmcia_soc
 		       const u8 *data, const size_t len);
 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
 
+/* loop over CIS entries */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+		      cisdata_t code, cisparse_t *parse, void *priv_data,
+		      int (*loop_tuple) (tuple_t *tuple,
+					 cisparse_t *parse,
+					 void *priv_data));
+
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
+			tuple_t *tuple);
+
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
+			tuple_t *tuple);
+
+int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
+
+
 /* rsrc_mgr.c */
 int pcmcia_validate_mem(struct pcmcia_socket *s);
 struct resource *pcmcia_find_io_region(unsigned long base,
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/ds.c linux-libre-2.6.33-gnu1/drivers/pcmcia/ds.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/ds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/ds.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,129 +41,11 @@ MODULE_AUTHOR("David Hinds <dahinds@user
 MODULE_DESCRIPTION("PCMCIA Driver Services");
 MODULE_LICENSE("GPL");
 
-#ifdef CONFIG_PCMCIA_DEBUG
-int ds_pc_debug;
-
-module_param_named(pc_debug, ds_pc_debug, int, 0644);
-
-#define ds_dbg(lvl, fmt, arg...) do {				\
-	if (ds_pc_debug > (lvl))				\
-		printk(KERN_DEBUG "ds: " fmt , ## arg);		\
-} while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do {				\
-	if (ds_pc_debug > (lvl))					\
-		dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg);	\
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
-#endif
 
 spinlock_t pcmcia_dev_list_lock;
 
 /*====================================================================*/
 
-/* code which was in cs.c before */
-
-/* String tables for error messages */
-
-typedef struct lookup_t {
-    const int key;
-    const char *msg;
-} lookup_t;
-
-static const lookup_t error_table[] = {
-    { 0,			"Operation succeeded" },
-    { -EIO,			"Input/Output error" },
-    { -ENODEV,			"No card present" },
-    { -EINVAL,			"Bad parameter" },
-    { -EACCES,			"Configuration locked" },
-    { -EBUSY,			"Resource in use" },
-    { -ENOSPC,			"No more items" },
-    { -ENOMEM,			"Out of resource" },
-};
-
-
-static const lookup_t service_table[] = {
-    { AccessConfigurationRegister,	"AccessConfigurationRegister" },
-    { AddSocketServices,		"AddSocketServices" },
-    { AdjustResourceInfo,		"AdjustResourceInfo" },
-    { CheckEraseQueue,			"CheckEraseQueue" },
-    { CloseMemory,			"CloseMemory" },
-    { DeregisterClient,			"DeregisterClient" },
-    { DeregisterEraseQueue,		"DeregisterEraseQueue" },
-    { GetCardServicesInfo,		"GetCardServicesInfo" },
-    { GetClientInfo,			"GetClientInfo" },
-    { GetConfigurationInfo,		"GetConfigurationInfo" },
-    { GetEventMask,			"GetEventMask" },
-    { GetFirstClient,			"GetFirstClient" },
-    { GetFirstRegion,			"GetFirstRegion" },
-    { GetFirstTuple,			"GetFirstTuple" },
-    { GetNextClient,			"GetNextClient" },
-    { GetNextRegion,			"GetNextRegion" },
-    { GetNextTuple,			"GetNextTuple" },
-    { GetStatus,			"GetStatus" },
-    { GetTupleData,			"GetTupleData" },
-    { MapMemPage,			"MapMemPage" },
-    { ModifyConfiguration,		"ModifyConfiguration" },
-    { ModifyWindow,			"ModifyWindow" },
-    { OpenMemory,			"OpenMemory" },
-    { ParseTuple,			"ParseTuple" },
-    { ReadMemory,			"ReadMemory" },
-    { RegisterClient,			"RegisterClient" },
-    { RegisterEraseQueue,		"RegisterEraseQueue" },
-    { RegisterMTD,			"RegisterMTD" },
-    { ReleaseConfiguration,		"ReleaseConfiguration" },
-    { ReleaseIO,			"ReleaseIO" },
-    { ReleaseIRQ,			"ReleaseIRQ" },
-    { ReleaseWindow,			"ReleaseWindow" },
-    { RequestConfiguration,		"RequestConfiguration" },
-    { RequestIO,			"RequestIO" },
-    { RequestIRQ,			"RequestIRQ" },
-    { RequestSocketMask,		"RequestSocketMask" },
-    { RequestWindow,			"RequestWindow" },
-    { ResetCard,			"ResetCard" },
-    { SetEventMask,			"SetEventMask" },
-    { ValidateCIS,			"ValidateCIS" },
-    { WriteMemory,			"WriteMemory" },
-    { BindDevice,			"BindDevice" },
-    { BindMTD,				"BindMTD" },
-    { ReportError,			"ReportError" },
-    { SuspendCard,			"SuspendCard" },
-    { ResumeCard,			"ResumeCard" },
-    { EjectCard,			"EjectCard" },
-    { InsertCard,			"InsertCard" },
-    { ReplaceCIS,			"ReplaceCIS" }
-};
-
-const char *pcmcia_error_func(int func)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(service_table); i++)
-		if (service_table[i].key == func)
-			return service_table[i].msg;
-
-	return "Unknown service number";
-}
-EXPORT_SYMBOL(pcmcia_error_func);
-
-const char *pcmcia_error_ret(int ret)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(error_table); i++)
-		if (error_table[i].key == ret)
-			return error_table[i].msg;
-
-	return "unknown";
-}
-EXPORT_SYMBOL(pcmcia_error_ret);
-
-/*======================================================================*/
-
-
-
 static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
 {
 	struct pcmcia_device_id *did = p_drv->id_table;
@@ -175,7 +57,7 @@ static void pcmcia_check_driver(struct p
 		       "function\n", p_drv->drv.name);
 
 	while (did && did->match_flags) {
-		for (i=0; i<4; i++) {
+		for (i = 0; i < 4; i++) {
 			if (!did->prod_id[i])
 				continue;
 
@@ -223,7 +105,7 @@ pcmcia_store_new_id(struct device_driver
 	__u16 match_flags, manf_id, card_id;
 	__u8 func_id, function, device_no;
 	__u32 prod_id_hash[4] = {0, 0, 0, 0};
-	int fields=0;
+	int fields = 0;
 	int retval = 0;
 
 	fields = sscanf(buf, "%hx %hx %hx %hhx %hhx %hhx %x %x %x %x",
@@ -303,7 +185,7 @@ int pcmcia_register_driver(struct pcmcia
 	spin_lock_init(&driver->dynids.lock);
 	INIT_LIST_HEAD(&driver->dynids.list);
 
-	ds_dbg(3, "registering driver %s\n", driver->drv.name);
+	pr_debug("registering driver %s\n", driver->drv.name);
 
 	error = driver_register(&driver->drv);
 	if (error < 0)
@@ -323,7 +205,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
  */
 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
 {
-	ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
+	pr_debug("unregistering driver %s\n", driver->drv.name);
 	driver_unregister(&driver->drv);
 	pcmcia_free_dynids(driver);
 }
@@ -332,7 +214,7 @@ EXPORT_SYMBOL(pcmcia_unregister_driver);
 
 /* pcmcia_device handling */
 
-struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)
+struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
 {
 	struct device *tmp_dev;
 	tmp_dev = get_device(&p_dev->dev);
@@ -350,14 +232,14 @@ void pcmcia_put_dev(struct pcmcia_device
 static void pcmcia_release_function(struct kref *ref)
 {
 	struct config_t *c = container_of(ref, struct config_t, ref);
-	ds_dbg(1, "releasing config_t\n");
+	pr_debug("releasing config_t\n");
 	kfree(c);
 }
 
 static void pcmcia_release_dev(struct device *dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-	ds_dev_dbg(1, dev, "releasing device\n");
+	dev_dbg(dev, "releasing device\n");
 	pcmcia_put_socket(p_dev->socket);
 	kfree(p_dev->devname);
 	kref_put(&p_dev->function_config->ref, pcmcia_release_function);
@@ -367,7 +249,7 @@ static void pcmcia_release_dev(struct de
 static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
 {
 	if (!s->pcmcia_state.device_add_pending) {
-		ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
+		dev_dbg(&s->dev, "scheduling to add %s secondary"
 		       " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
 		s->pcmcia_state.device_add_pending = 1;
 		s->pcmcia_state.mfc_pfc = mfc;
@@ -376,7 +258,7 @@ static void pcmcia_add_device_later(stru
 	return;
 }
 
-static int pcmcia_device_probe(struct device * dev)
+static int pcmcia_device_probe(struct device *dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
@@ -405,7 +287,7 @@ static int pcmcia_device_probe(struct de
 	 */
 	did = dev_get_drvdata(&p_dev->dev);
 
-	ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
+	dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
 
 	if ((!p_drv->probe) || (!p_dev->function_config) ||
 	    (!try_module_get(p_drv->owner))) {
@@ -428,7 +310,7 @@ static int pcmcia_device_probe(struct de
 
 	ret = p_drv->probe(p_dev);
 	if (ret) {
-		ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
+		dev_dbg(dev, "binding to %s failed with %d\n",
 			   p_drv->drv.name, ret);
 		goto put_module;
 	}
@@ -443,7 +325,7 @@ put_module:
 put_dev:
 	if (ret)
 		put_device(dev);
-	return (ret);
+	return ret;
 }
 
 
@@ -456,7 +338,7 @@ static void pcmcia_card_remove(struct pc
 	struct pcmcia_device	*tmp;
 	unsigned long		flags;
 
-	ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
+	dev_dbg(leftover ? &leftover->dev : &s->dev,
 		   "pcmcia_card_remove(%d) %s\n", s->sock,
 		   leftover ? leftover->devname : "");
 
@@ -472,17 +354,17 @@ static void pcmcia_card_remove(struct pc
 
 		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 		list_del(&p_dev->socket_device_list);
-		p_dev->_removed=1;
+		p_dev->_removed = 1;
 		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-		ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
+		dev_dbg(&p_dev->dev, "unregistering device\n");
 		device_unregister(&p_dev->dev);
 	}
 
 	return;
 }
 
-static int pcmcia_device_remove(struct device * dev)
+static int pcmcia_device_remove(struct device *dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
@@ -492,7 +374,7 @@ static int pcmcia_device_remove(struct d
 	p_dev = to_pcmcia_dev(dev);
 	p_drv = to_pcmcia_drv(dev->driver);
 
-	ds_dev_dbg(1, dev, "removing device\n");
+	dev_dbg(dev, "removing device\n");
 
 	/* If we're removing the primary module driving a
 	 * pseudo multi-function card, we need to unbind
@@ -509,7 +391,7 @@ static int pcmcia_device_remove(struct d
 		return 0;
 
 	if (p_drv->remove)
-	       	p_drv->remove(p_dev);
+		p_drv->remove(p_dev);
 
 	p_dev->dev_node = NULL;
 
@@ -572,7 +454,7 @@ static int pcmcia_device_query(struct pc
 		}
 		if (!pccard_read_tuple(p_dev->socket, p_dev->func,
 				      CISTPL_DEVICE_GEO, devgeo)) {
-			ds_dev_dbg(0, &p_dev->dev,
+			dev_dbg(&p_dev->dev,
 				   "mem device geometry probably means "
 				   "FUNCID_MEMORY\n");
 			p_dev->func_id = CISTPL_FUNCID_MEMORY;
@@ -617,7 +499,7 @@ static int pcmcia_device_query(struct pc
  */
 static DEFINE_MUTEX(device_add_lock);
 
-struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
+struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
 {
 	struct pcmcia_device *p_dev, *tmp_dev;
 	unsigned long flags;
@@ -628,7 +510,7 @@ struct pcmcia_device * pcmcia_device_add
 
 	mutex_lock(&device_add_lock);
 
-	ds_dbg(3, "adding device to %d, function %d\n", s->sock, function);
+	pr_debug("adding device to %d, function %d\n", s->sock, function);
 
 	/* max of 4 devices per card */
 	if (s->device_count == 4)
@@ -654,7 +536,7 @@ struct pcmcia_device * pcmcia_device_add
 	p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
 	if (!p_dev->devname)
 		goto err_free;
-	ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
+	dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
 
 	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 
@@ -663,8 +545,8 @@ struct pcmcia_device * pcmcia_device_add
 	 * Note that this is serialized by the device_add_lock, so that
 	 * only one such struct will be created.
 	 */
-        list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
-                if (p_dev->func == tmp_dev->func) {
+	list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
+		if (p_dev->func == tmp_dev->func) {
 			p_dev->function_config = tmp_dev->function_config;
 			p_dev->io = tmp_dev->io;
 			p_dev->irq = tmp_dev->irq;
@@ -677,7 +559,7 @@ struct pcmcia_device * pcmcia_device_add
 	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
 	if (!p_dev->function_config) {
-		ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
+		dev_dbg(&p_dev->dev, "creating config_t\n");
 		p_dev->function_config = kzalloc(sizeof(struct config_t),
 						 GFP_KERNEL);
 		if (!p_dev->function_config)
@@ -722,20 +604,20 @@ static int pcmcia_card_add(struct pcmcia
 	int ret = 0;
 
 	if (!(s->resource_setup_done)) {
-		ds_dev_dbg(3, &s->dev,
+		dev_dbg(&s->dev,
 			   "no resources available, delaying card_add\n");
 		return -EAGAIN; /* try again, but later... */
 	}
 
 	if (pcmcia_validate_mem(s)) {
-		ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
+		dev_dbg(&s->dev, "validating mem resources failed, "
 		       "delaying card_add\n");
 		return -EAGAIN; /* try again, but later... */
 	}
 
 	ret = pccard_validate_cis(s, &no_chains);
 	if (ret || !no_chains) {
-		ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
+		dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
 		return -ENODEV;
 	}
 
@@ -745,10 +627,10 @@ static int pcmcia_card_add(struct pcmcia
 		no_funcs = 1;
 	s->functions = no_funcs;
 
-	for (i=0; i < no_funcs; i++)
+	for (i = 0; i < no_funcs; i++)
 		pcmcia_device_add(s, i);
 
-	return (ret);
+	return ret;
 }
 
 
@@ -756,7 +638,7 @@ static void pcmcia_delayed_add_device(st
 {
 	struct pcmcia_socket *s =
 		container_of(work, struct pcmcia_socket, device_add);
-	ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
+	dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
 	pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
 	s->pcmcia_state.device_add_pending = 0;
 	s->pcmcia_state.mfc_pfc = 0;
@@ -766,7 +648,7 @@ static int pcmcia_requery(struct device
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	if (!p_dev->dev.driver) {
-		ds_dev_dbg(1, dev, "update device information\n");
+		dev_dbg(dev, "update device information\n");
 		pcmcia_device_query(p_dev);
 	}
 
@@ -780,7 +662,7 @@ static void pcmcia_bus_rescan(struct pcm
 	unsigned long flags;
 
 	/* must be called with skt_mutex held */
-	ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
+	dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
 
 	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 	if (list_empty(&skt->devices_list))
@@ -835,7 +717,7 @@ static int pcmcia_load_firmware(struct p
 	if (!filename)
 		return -EINVAL;
 
-	ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
+	dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename);
 
 	if (request_firmware(&fw, filename, &dev->dev) == 0) {
 		if (fw->size >= CISTPL_MAX_CIS_SIZE) {
@@ -874,7 +756,7 @@ static int pcmcia_load_firmware(struct p
  release:
 	release_firmware(fw);
 
-	return (ret);
+	return ret;
 }
 
 #else /* !CONFIG_PCMCIA_LOAD_CIS */
@@ -953,14 +835,14 @@ static inline int pcmcia_devmatch(struct
 		 * after it has re-checked that there is no possible module
 		 * with a prod_id/manf_id/card_id match.
 		 */
-		ds_dev_dbg(0, &dev->dev,
+		dev_dbg(&dev->dev,
 			"skipping FUNC_ID match until userspace interaction\n");
 		if (!dev->allow_func_id_match)
 			return 0;
 	}
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
-		ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
+		dev_dbg(&dev->dev, "device needs a fake CIS\n");
 		if (!dev->socket->fake_cis)
 			pcmcia_load_firmware(dev, did->cisfile);
 
@@ -970,7 +852,7 @@ static inline int pcmcia_devmatch(struct
 
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
 		int i;
-		for (i=0; i<4; i++)
+		for (i = 0; i < 4; i++)
 			if (dev->prod_id[i])
 				return 0;
 		if (dev->has_manf_id || dev->has_card_id || dev->has_func_id)
@@ -983,18 +865,19 @@ static inline int pcmcia_devmatch(struct
 }
 
 
-static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
-	struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
-	struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
+static int pcmcia_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct pcmcia_driver *p_drv = to_pcmcia_drv(drv);
 	struct pcmcia_device_id *did = p_drv->id_table;
 	struct pcmcia_dynid *dynid;
 
 	/* match dynamic devices first */
 	spin_lock(&p_drv->dynids.lock);
 	list_for_each_entry(dynid, &p_drv->dynids.list, node) {
-		ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+		dev_dbg(dev, "trying to match to %s\n", drv->name);
 		if (pcmcia_devmatch(p_dev, &dynid->id)) {
-			ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+			dev_dbg(dev, "matched to %s\n", drv->name);
 			spin_unlock(&p_drv->dynids.lock);
 			return 1;
 		}
@@ -1004,15 +887,15 @@ static int pcmcia_bus_match(struct devic
 #ifdef CONFIG_PCMCIA_IOCTL
 	/* matching by cardmgr */
 	if (p_dev->cardmgr == p_drv) {
-		ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
+		dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
 		return 1;
 	}
 #endif
 
 	while (did && did->match_flags) {
-		ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+		dev_dbg(dev, "trying to match to %s\n", drv->name);
 		if (pcmcia_devmatch(p_dev, did)) {
-			ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+			dev_dbg(dev, "matched to %s\n", drv->name);
 			return 1;
 		}
 		did++;
@@ -1035,7 +918,7 @@ static int pcmcia_bus_uevent(struct devi
 	p_dev = to_pcmcia_dev(dev);
 
 	/* calculate hashes */
-	for (i=0; i<4; i++) {
+	for (i = 0; i < 4; i++) {
 		if (!p_dev->prod_id[i])
 			continue;
 		hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
@@ -1102,14 +985,14 @@ static void runtime_resume(struct device
 static ssize_t field##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
-	return p_dev->test ? sprintf (buf, format, p_dev->field) : -ENODEV; \
+	return p_dev->test ? sprintf(buf, format, p_dev->field) : -ENODEV; \
 }
 
 #define pcmcia_device_stringattr(name, field)					\
 static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
-	return p_dev->field ? sprintf (buf, "%s\n", p_dev->field) : -ENODEV; \
+	return p_dev->field ? sprintf(buf, "%s\n", p_dev->field) : -ENODEV; \
 }
 
 pcmcia_device_attr(func, socket, "0x%02x\n");
@@ -1138,8 +1021,8 @@ static ssize_t pcmcia_store_pm_state(str
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	int ret = 0;
 
-        if (!count)
-                return -EINVAL;
+	if (!count)
+		return -EINVAL;
 
 	if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
 		ret = runtime_suspend(dev);
@@ -1157,10 +1040,11 @@ static ssize_t modalias_show(struct devi
 	u32 hash[4] = { 0, 0, 0, 0};
 
 	/* calculate hashes */
-	for (i=0; i<4; i++) {
+	for (i = 0; i < 4; i++) {
 		if (!p_dev->prod_id[i])
 			continue;
-		hash[i] = crc32(0,p_dev->prod_id[i],strlen(p_dev->prod_id[i]));
+		hash[i] = crc32(0, p_dev->prod_id[i],
+				strlen(p_dev->prod_id[i]));
 	}
 	return sprintf(buf, "pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
 				"pa%08Xpb%08Xpc%08Xpd%08X\n",
@@ -1209,7 +1093,7 @@ static struct device_attribute pcmcia_de
 
 /* PM support, also needed for reset */
 
-static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
+static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	struct pcmcia_driver *p_drv = NULL;
@@ -1218,7 +1102,7 @@ static int pcmcia_dev_suspend(struct dev
 	if (p_dev->suspended)
 		return 0;
 
-	ds_dev_dbg(2, dev, "suspending\n");
+	dev_dbg(dev, "suspending\n");
 
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
@@ -1238,7 +1122,7 @@ static int pcmcia_dev_suspend(struct dev
 	}
 
 	if (p_dev->device_no == p_dev->func) {
-		ds_dev_dbg(2, dev, "releasing configuration\n");
+		dev_dbg(dev, "releasing configuration\n");
 		pcmcia_release_configuration(p_dev);
 	}
 
@@ -1249,16 +1133,16 @@ static int pcmcia_dev_suspend(struct dev
 }
 
 
-static int pcmcia_dev_resume(struct device * dev)
+static int pcmcia_dev_resume(struct device *dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-        struct pcmcia_driver *p_drv = NULL;
+	struct pcmcia_driver *p_drv = NULL;
 	int ret = 0;
 
 	if (!p_dev->suspended)
 		return 0;
 
-	ds_dev_dbg(2, dev, "resuming\n");
+	dev_dbg(dev, "resuming\n");
 
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
@@ -1267,7 +1151,7 @@ static int pcmcia_dev_resume(struct devi
 		goto out;
 
 	if (p_dev->device_no == p_dev->func) {
-		ds_dev_dbg(2, dev, "requesting configuration\n");
+		dev_dbg(dev, "requesting configuration\n");
 		ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
 		if (ret)
 			goto out;
@@ -1309,14 +1193,14 @@ static int pcmcia_bus_resume_callback(st
 
 static int pcmcia_bus_resume(struct pcmcia_socket *skt)
 {
-	ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
+	dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock);
 	bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
 	return 0;
 }
 
 static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
 {
-	ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
+	dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock);
 	if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
 			     pcmcia_bus_suspend_callback)) {
 		pcmcia_bus_resume(skt);
@@ -1329,7 +1213,7 @@ static int pcmcia_bus_suspend(struct pcm
 /*======================================================================
 
     The card status event handler.
-    
+
 ======================================================================*/
 
 /* Normally, the event is passed to individual drivers after
@@ -1348,7 +1232,7 @@ static int ds_event(struct pcmcia_socket
 		return -ENODEV;
 	}
 
-	ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
+	dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
 		   event, priority, skt);
 
 	switch (event) {
@@ -1382,7 +1266,7 @@ static int ds_event(struct pcmcia_socket
 } /* ds_event */
 
 
-struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *_p_dev)
+struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_device *ret = NULL;
@@ -1447,7 +1331,7 @@ static int __devinit pcmcia_bus_add_sock
 	if (ret) {
 		dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
 		pcmcia_put_socket(socket);
-		return (ret);
+		return ret;
 	}
 
 	return 0;
@@ -1518,7 +1402,7 @@ static int __init init_pcmcia_bus(void)
 
 	return 0;
 }
-fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that 
+fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
 			       * pcmcia_socket_class is already registered */
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/i82365.c linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/i82365.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/i82365.c	2010-02-24 13:52:17.000000000 -0500
@@ -63,21 +63,6 @@
 #include "vg468.h"
 #include "ricoh.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static const char version[] =
-"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
-
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-#define debug(lvl, fmt, arg...) do {				\
-	if (pc_debug > (lvl))					\
-		printk(KERN_DEBUG "i82365: " fmt , ## arg);	\
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
 
 static irqreturn_t i365_count_irq(int, void *);
 static inline int _check_irq(int irq, int flags)
@@ -501,13 +486,13 @@ static irqreturn_t i365_count_irq(int ir
 {
     i365_get(irq_sock, I365_CSC);
     irq_hits++;
-    debug(2, "-> hit on irq %d\n", irq);
+    pr_debug("i82365: -> hit on irq %d\n", irq);
     return IRQ_HANDLED;
 }
 
 static u_int __init test_irq(u_short sock, int irq)
 {
-    debug(2, "  testing ISA irq %d\n", irq);
+    pr_debug("i82365:  testing ISA irq %d\n", irq);
     if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
 			i365_count_irq) != 0)
 	return 1;
@@ -515,7 +500,7 @@ static u_int __init test_irq(u_short soc
     msleep(10);
     if (irq_hits) {
 	free_irq(irq, i365_count_irq);
-	debug(2, "    spurious hit!\n");
+	pr_debug("i82365:    spurious hit!\n");
 	return 1;
     }
 
@@ -528,7 +513,7 @@ static u_int __init test_irq(u_short soc
 
     /* mask all interrupts */
     i365_set(sock, I365_CSCINT, 0);
-    debug(2, "    hits = %d\n", irq_hits);
+    pr_debug("i82365:    hits = %d\n", irq_hits);
     
     return (irq_hits != 1);
 }
@@ -854,7 +839,7 @@ static irqreturn_t pcic_interrupt(int ir
     u_long flags = 0;
     int handled = 0;
 
-    debug(4, "pcic_interrupt(%d)\n", irq);
+    pr_debug("pcic_interrupt(%d)\n", irq);
 
     for (j = 0; j < 20; j++) {
 	active = 0;
@@ -878,7 +863,7 @@ static irqreturn_t pcic_interrupt(int ir
 		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
 	    }
 	    ISA_UNLOCK(i, flags);
-	    debug(2, "socket %d event 0x%02x\n", i, events);
+	    pr_debug("socket %d event 0x%02x\n", i, events);
 
 	    if (events)
 		pcmcia_parse_events(&socket[i].socket, events);
@@ -890,7 +875,7 @@ static irqreturn_t pcic_interrupt(int ir
     if (j == 20)
 	printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
 
-    debug(4, "interrupt done\n");
+    pr_debug("pcic_interrupt done\n");
     return IRQ_RETVAL(handled);
 } /* pcic_interrupt */
 
@@ -932,7 +917,7 @@ static int i365_get_status(u_short sock,
 	}
     }
     
-    debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value);
+    pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
     return 0;
 } /* i365_get_status */
 
@@ -943,7 +928,7 @@ static int i365_set_socket(u_short sock,
     struct i82365_socket *t = &socket[sock];
     u_char reg;
     
-    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+    pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 	  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
 	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
     
@@ -1052,7 +1037,7 @@ static int i365_set_io_map(u_short sock,
 {
     u_char map, ioctl;
     
-    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+    pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
 	  "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
 	  (unsigned long long)io->start, (unsigned long long)io->stop);
     map = io->map;
@@ -1082,7 +1067,7 @@ static int i365_set_mem_map(u_short sock
     u_short base, i;
     u_char map;
     
-    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
+    pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
 	  "%#x)\n", sock, mem->map, mem->flags, mem->speed,
 	  (unsigned long long)mem->res->start,
 	  (unsigned long long)mem->res->end, mem->card_start);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/Kconfig linux-libre-2.6.33-gnu1/drivers/pcmcia/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -17,24 +17,6 @@ menuconfig PCCARD
 
 if PCCARD
 
-config PCMCIA_DEBUG
-	bool "Enable PCCARD debugging"
-	help
-	  Say Y here to enable PCMCIA subsystem debugging.  You
-	  will need to choose the debugging level either via the
-	  kernel command line, or module options depending whether
-	  you build the PCMCIA as modules.
-
-	  The kernel command line options are:
-	    pcmcia_core.pc_debug=N
-	    pcmcia.pc_debug=N
-	    sa11xx_core.pc_debug=N
-
-	  The module option is called pc_debug=N
-
-	  In all the above examples, N is the debugging verbosity
-	  level.
-
 config PCMCIA
 	tristate "16-bit PCMCIA support"
 	select CRC32
@@ -82,7 +64,7 @@ config PCMCIA_IOCTL
 	  If unsure, say Y.
 
 config CARDBUS
-	bool "32-bit CardBus support"	
+	bool "32-bit CardBus support"
 	depends on PCI
 	default y
 	---help---
@@ -105,8 +87,8 @@ config YENTA
 	select PCCARD_NONSTATIC
 	---help---
 	  This option enables support for CardBus host bridges.  Virtually
-	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is 
-	  the hardware inside your computer that PCMCIA cards are plugged 
+	  all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
+	  the hardware inside your computer that PCMCIA cards are plugged
 	  into.
 
 	  To compile this driver as modules, choose M here: the
@@ -196,9 +178,13 @@ config PCMCIA_BCM63XX
 	tristate "bcm63xx pcmcia support"
 	depends on BCM63XX && PCMCIA
 
+config PCMCIA_SOC_COMMON
+	tristate
+
 config PCMCIA_SA1100
 	tristate "SA1100 support"
 	depends on ARM && ARCH_SA1100 && PCMCIA
+	select PCMCIA_SOC_COMMON
 	help
 	  Say Y here to include support for SA11x0-based PCMCIA or CF
 	  sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -209,6 +195,7 @@ config PCMCIA_SA1100
 config PCMCIA_SA1111
 	tristate "SA1111 support"
 	depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
+	select PCMCIA_SOC_COMMON
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
@@ -221,10 +208,29 @@ config PCMCIA_PXA2XX
 	depends on ARM && ARCH_PXA && PCMCIA
 	depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
 		    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
-		    || ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
+		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2)
+	select PCMCIA_SOC_COMMON
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
 
+config PCMCIA_DEBUG
+	bool "Enable debugging"
+	depends on (PCMCIA_SA1111 || PCMCIA_SA1100 || PCMCIA_PXA2XX)
+	help
+	  Say Y here to enable debugging for the SoC PCMCIA layer.
+	  You will need to choose the debugging level either via the
+	  kernel command line, or module options depending whether
+	  you build the drivers as modules.
+
+	  The kernel command line options are:
+	    sa11xx_core.pc_debug=N
+	    pxa2xx_core.pc_debug=N
+
+	  The module option is called pc_debug=N
+
+	  In all the above examples, N is the debugging verbosity
+	  level.
+
 config PCMCIA_PROBE
 	bool
 	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/m32r_cfc.c linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_cfc.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/m32r_cfc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_cfc.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,17 +38,6 @@
 
 #include "m32r_cfc.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_cfc_debug;
-module_param(m32r_cfc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do {				\
-	if (m32r_cfc_debug > (lvl))				\
-		printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg);	\
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
-
 /* Poll status interval -- 0 means default to interrupt */
 static int poll_interval = 0;
 
@@ -123,7 +112,7 @@ void pcc_ioread_byte(int sock, unsigned
 	unsigned char *bp = (unsigned char *)buf;
 	unsigned long flags;
 
-	debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
+	pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
 		 "size=%u, nmemb=%d, flag=%d\n",
 		  sock, port, buf, size, nmemb, flag);
 
@@ -132,7 +121,7 @@ void pcc_ioread_byte(int sock, unsigned
 		printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
 		return;
 	}
-	debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
+	pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
 
 	spin_lock_irqsave(&pcc_lock, flags);
 	/* read Byte */
@@ -148,7 +137,7 @@ void pcc_ioread_word(int sock, unsigned
 	unsigned short *bp = (unsigned short *)buf;
 	unsigned long flags;
 
-	debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
+	pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 		 sock, port, buf, size, nmemb, flag);
 
@@ -163,7 +152,7 @@ void pcc_ioread_word(int sock, unsigned
 		printk("m32r_cfc:ioread_word null port :%#lx\n",port);
 		return;
 	}
-	debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
+	pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
 
 	spin_lock_irqsave(&pcc_lock, flags);
 	/* read Word */
@@ -179,7 +168,7 @@ void pcc_iowrite_byte(int sock, unsigned
 	unsigned char *bp = (unsigned char *)buf;
 	unsigned long flags;
 
-	debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
+	pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 		 sock, port, buf, size, nmemb, flag);
 
@@ -189,7 +178,7 @@ void pcc_iowrite_byte(int sock, unsigned
 		printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
 		return;
 	}
-	debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
+	pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
 
 	spin_lock_irqsave(&pcc_lock, flags);
 	while (nmemb--)
@@ -204,7 +193,7 @@ void pcc_iowrite_word(int sock, unsigned
 	unsigned short *bp = (unsigned short *)buf;
 	unsigned long flags;
 
-	debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
+	pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 		 sock, port, buf, size, nmemb, flag);
 
@@ -226,7 +215,7 @@ void pcc_iowrite_word(int sock, unsigned
 		return;
 	}
 #endif
-	debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
+	pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
 
 	spin_lock_irqsave(&pcc_lock, flags);
 	while (nmemb--)
@@ -262,7 +251,7 @@ static struct timer_list poll_timer;
 static unsigned int pcc_get(u_short sock, unsigned int reg)
 {
 	unsigned int val = inw(reg);
-	debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
+	pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
 	return val;
 }
 
@@ -270,7 +259,7 @@ static unsigned int pcc_get(u_short sock
 static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
 {
 	outw(data, reg);
-	debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
+	pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
 }
 
 /*======================================================================
@@ -286,14 +275,14 @@ static int __init is_alive(u_short sock)
 {
 	unsigned int stat;
 
-	debug(3, "m32r_cfc: is_alive:\n");
+	pr_debug("m32r_cfc: is_alive:\n");
 
 	printk("CF: ");
 	stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
 	if (!stat)
 		printk("No ");
 	printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
-	debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
+	pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
 
 	return 0;
 }
@@ -303,7 +292,7 @@ static void add_pcc_socket(ulong base, i
 {
 	pcc_socket_t *t = &socket[pcc_sockets];
 
-	debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
+	pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
 		 "mapaddr=%#lx, ioaddr=%08x\n",
 		 base, irq, mapaddr, ioaddr);
 
@@ -358,7 +347,7 @@ static void add_pcc_socket(ulong base, i
 	/* eject interrupt */
 	request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
 #endif
-	debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
+	pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
 	pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
 #endif	/* CONFIG_PLAT_USRV */
 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
@@ -378,26 +367,26 @@ static irqreturn_t pcc_interrupt(int irq
 	u_int events = 0;
 	int handled = 0;
 
-	debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
+	pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
 	for (i = 0; i < pcc_sockets; i++) {
 		if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
 			continue;
 
 		handled = 1;
-		debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
+		pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
 			i, irq);
 		events |= SS_DETECT;	/* insert or eject */
 		if (events)
 			pcmcia_parse_events(&socket[i].socket, events);
 	}
-	debug(3, "m32r_cfc: pcc_interrupt: done\n");
+	pr_debug("m32r_cfc: pcc_interrupt: done\n");
 
 	return IRQ_RETVAL(handled);
 } /* pcc_interrupt */
 
 static void pcc_interrupt_wrapper(u_long data)
 {
-	debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
+	pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
 	pcc_interrupt(0, NULL);
 	init_timer(&poll_timer);
 	poll_timer.expires = jiffies + poll_interval;
@@ -410,17 +399,17 @@ static int _pcc_get_status(u_short sock,
 {
 	u_int status;
 
-	debug(3, "m32r_cfc: _pcc_get_status:\n");
+	pr_debug("m32r_cfc: _pcc_get_status:\n");
 	status = pcc_get(sock, (unsigned int)PLD_CFSTS);
 	*value = (status) ? SS_DETECT : 0;
- 	debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
+	pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
 
 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
 	if ( status ) {
 		/* enable CF power */
 		status = inw((unsigned int)PLD_CPCR);
 		if (!(status & PLD_CPCR_CF)) {
-			debug(3, "m32r_cfc: _pcc_get_status: "
+			pr_debug("m32r_cfc: _pcc_get_status: "
 				 "power on (CPCR=0x%08x)\n", status);
 			status |= PLD_CPCR_CF;
 			outw(status, (unsigned int)PLD_CPCR);
@@ -439,7 +428,7 @@ static int _pcc_get_status(u_short sock,
 		status &= ~PLD_CPCR_CF;
 		outw(status, (unsigned int)PLD_CPCR);
 		udelay(100);
-		debug(3, "m32r_cfc: _pcc_get_status: "
+		pr_debug("m32r_cfc: _pcc_get_status: "
 			 "power off (CPCR=0x%08x)\n", status);
 	}
 #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
@@ -465,13 +454,13 @@ static int _pcc_get_status(u_short sock,
 		/* disable CF power */
 	        pcc_set(sock, (unsigned int)PLD_CPCR, 0);
 		udelay(100);
-		debug(3, "m32r_cfc: _pcc_get_status: "
+		pr_debug("m32r_cfc: _pcc_get_status: "
 			 "power off (CPCR=0x%08x)\n", status);
 	}
 #else
 #error no platform configuration
 #endif
-	debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
+	pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
 		 sock, *value);
 	return 0;
 } /* _get_status */
@@ -480,7 +469,7 @@ static int _pcc_get_status(u_short sock,
 
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
-	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+	pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 		  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
 		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -492,41 +481,39 @@ static int _pcc_set_socket(u_short sock,
 	}
 #endif
 	if (state->flags & SS_RESET) {
-		debug(3, ":RESET\n");
+		pr_debug(":RESET\n");
 		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
 	}else{
 		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
 	}
 	if (state->flags & SS_OUTPUT_ENA){
-		debug(3, ":OUTPUT_ENA\n");
+		pr_debug(":OUTPUT_ENA\n");
 		/* bit clear */
 		pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
 	} else {
 		pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
 	}
 
-#ifdef CONFIG_PCMCIA_DEBUG
 	if(state->flags & SS_IOCARD){
-		debug(3, ":IOCARD");
+		pr_debug(":IOCARD");
 	}
 	if (state->flags & SS_PWR_AUTO) {
-		debug(3, ":PWR_AUTO");
+		pr_debug(":PWR_AUTO");
 	}
 	if (state->csc_mask & SS_DETECT)
-		debug(3, ":csc-SS_DETECT");
+		pr_debug(":csc-SS_DETECT");
 	if (state->flags & SS_IOCARD) {
 		if (state->csc_mask & SS_STSCHG)
-			debug(3, ":STSCHG");
+			pr_debug(":STSCHG");
 	} else {
 		if (state->csc_mask & SS_BATDEAD)
-			debug(3, ":BATDEAD");
+			pr_debug(":BATDEAD");
 		if (state->csc_mask & SS_BATWARN)
-			debug(3, ":BATWARN");
+			pr_debug(":BATWARN");
 		if (state->csc_mask & SS_READY)
-			debug(3, ":READY");
+			pr_debug(":READY");
 	}
-	debug(3, "\n");
-#endif
+	pr_debug("\n");
 	return 0;
 } /* _set_socket */
 
@@ -536,7 +523,7 @@ static int _pcc_set_io_map(u_short sock,
 {
 	u_char map;
 
-	debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
 		  "%#llx-%#llx)\n", sock, io->map, io->flags,
 		  io->speed, (unsigned long long)io->start,
 		  (unsigned long long)io->stop);
@@ -554,7 +541,7 @@ static int _pcc_set_mem_map(u_short sock
 	u_long addr;
 	pcc_socket_t *t = &socket[sock];
 
-	debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
 		 "%#llx, %#x)\n", sock, map, mem->flags,
 		 mem->speed, (unsigned long long)mem->static_start,
 		 mem->card_start);
@@ -640,11 +627,11 @@ static int pcc_get_status(struct pcmcia_
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
 	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
+		dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
 		*value = 0;
 		return -EINVAL;
 	}
-	debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
+	dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
 	LOCKED(_pcc_get_status(sock, value));
 }
 
@@ -653,10 +640,10 @@ static int pcc_set_socket(struct pcmcia_
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
 	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
+		dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
 		return -EINVAL;
 	}
-	debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
+	dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
 	LOCKED(_pcc_set_socket(sock, state));
 }
 
@@ -665,10 +652,10 @@ static int pcc_set_io_map(struct pcmcia_
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
 	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
+		dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
 		return -EINVAL;
 	}
-	debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
+	dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
 	LOCKED(_pcc_set_io_map(sock, io));
 }
 
@@ -677,16 +664,16 @@ static int pcc_set_mem_map(struct pcmcia
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
 	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
+		dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
 		return -EINVAL;
 	}
-	debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
+	dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
 	LOCKED(_pcc_set_mem_map(sock, mem));
 }
 
 static int pcc_init(struct pcmcia_socket *s)
 {
-	debug(3, "m32r_cfc: pcc_init()\n");
+	dev_dbg(&s->dev, "pcc_init()\n");
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/m32r_pcc.c linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_pcc.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/m32r_pcc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/m32r_pcc.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,16 +45,6 @@
 
 #define PCC_DEBUG_DBEX
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_pcc_debug;
-module_param(m32r_pcc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do {				\
-	if (m32r_pcc_debug > (lvl))				\
-		printk(KERN_DEBUG "m32r_pcc: " fmt , ## arg);	\
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
 
 /* Poll status interval -- 0 means default to interrupt */
 static int poll_interval = 0;
@@ -358,7 +348,7 @@ static irqreturn_t pcc_interrupt(int irq
 	u_int events, active;
 	int handled = 0;
 
-	debug(4, "m32r: pcc_interrupt(%d)\n", irq);
+	pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
 
 	for (j = 0; j < 20; j++) {
 		active = 0;
@@ -369,13 +359,14 @@ static irqreturn_t pcc_interrupt(int irq
 			handled = 1;
 			irc = pcc_get(i, PCIRC);
 			irc >>=16;
-			debug(2, "m32r-pcc:interrupt: socket %d pcirc 0x%02x ", i, irc);
+			pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
+				i, irc);
 			if (!irc)
 				continue;
 
 			events = (irc) ? SS_DETECT : 0;
 			events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
-			debug(2, " event 0x%02x\n", events);
+			pr_debug("m32r_pcc: event 0x%02x\n", events);
 
 			if (events)
 				pcmcia_parse_events(&socket[i].socket, events);
@@ -388,7 +379,7 @@ static irqreturn_t pcc_interrupt(int irq
 	if (j == 20)
 		printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
 
-	debug(4, "m32r-pcc: interrupt done\n");
+	pr_debug("m32r_pcc: interrupt done\n");
 
 	return IRQ_RETVAL(handled);
 } /* pcc_interrupt */
@@ -422,7 +413,7 @@ static int _pcc_get_status(u_short sock,
 	status = pcc_get(sock,PCCSIGCR);
 	*value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
 
-	debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
+	pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
 	return 0;
 } /* _get_status */
 
@@ -432,7 +423,7 @@ static int _pcc_set_socket(u_short sock,
 {
 	u_long reg = 0;
 
-	debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+	pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 		  "io_irq %d, csc_mask %#2.2x)", sock, state->flags,
 		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -448,11 +439,11 @@ static int _pcc_set_socket(u_short sock,
 	}
 
 	if (state->flags & SS_RESET) {
-		debug(3, ":RESET\n");
+		pr_debug("m32r_pcc: :RESET\n");
 		reg |= PCCSIGCR_CRST;
 	}
 	if (state->flags & SS_OUTPUT_ENA){
-		debug(3, ":OUTPUT_ENA\n");
+		pr_debug("m32r_pcc: :OUTPUT_ENA\n");
 		/* bit clear */
 	} else {
 		reg |= PCCSIGCR_SEN;
@@ -460,28 +451,26 @@ static int _pcc_set_socket(u_short sock,
 
 	pcc_set(sock,PCCSIGCR,reg);
 
-#ifdef CONFIG_PCMCIA_DEBUG
 	if(state->flags & SS_IOCARD){
-		debug(3, ":IOCARD");
+		pr_debug("m32r_pcc: :IOCARD");
 	}
 	if (state->flags & SS_PWR_AUTO) {
-		debug(3, ":PWR_AUTO");
+		pr_debug("m32r_pcc: :PWR_AUTO");
 	}
 	if (state->csc_mask & SS_DETECT)
-		debug(3, ":csc-SS_DETECT");
+		pr_debug("m32r_pcc: :csc-SS_DETECT");
 	if (state->flags & SS_IOCARD) {
 		if (state->csc_mask & SS_STSCHG)
-			debug(3, ":STSCHG");
+			pr_debug("m32r_pcc: :STSCHG");
 	} else {
 		if (state->csc_mask & SS_BATDEAD)
-			debug(3, ":BATDEAD");
+			pr_debug("m32r_pcc: :BATDEAD");
 		if (state->csc_mask & SS_BATWARN)
-			debug(3, ":BATWARN");
+			pr_debug("m32r_pcc: :BATWARN");
 		if (state->csc_mask & SS_READY)
-			debug(3, ":READY");
+			pr_debug("m32r_pcc: :READY");
 	}
-	debug(3, "\n");
-#endif
+	pr_debug("m32r_pcc: \n");
 	return 0;
 } /* _set_socket */
 
@@ -491,7 +480,7 @@ static int _pcc_set_io_map(u_short sock,
 {
 	u_char map;
 
-	debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
 		  "%#llx-%#llx)\n", sock, io->map, io->flags,
 		  io->speed, (unsigned long long)io->start,
 		  (unsigned long long)io->stop);
@@ -515,7 +504,7 @@ static int _pcc_set_mem_map(u_short sock
 #endif
 #endif
 
-	debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
 		 "%#llx,  %#x)\n", sock, map, mem->flags,
 		 mem->speed, (unsigned long long)mem->static_start,
 		 mem->card_start);
@@ -662,7 +651,7 @@ static int pcc_set_mem_map(struct pcmcia
 
 static int pcc_init(struct pcmcia_socket *s)
 {
-	debug(4, "m32r-pcc: init call\n");
+	pr_debug("m32r_pcc: init call\n");
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/m8xx_pcmcia.c linux-libre-2.6.33-gnu1/drivers/pcmcia/m8xx_pcmcia.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2010-02-24 13:52:17.000000000 -0500
@@ -64,14 +64,6 @@
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-module_param(pc_debug, int, 0);
-#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
-#else
-#define dprintk(args...)
-#endif
-
 #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
 #define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
 
@@ -565,7 +557,7 @@ static irqreturn_t m8xx_interrupt(int ir
 	unsigned int i, events, pscr, pipr, per;
 	pcmconf8xx_t *pcmcia = socket[0].pcmcia;
 
-	dprintk("Interrupt!\n");
+	pr_debug("m8xx_pcmcia: Interrupt!\n");
 	/* get interrupt sources */
 
 	pscr = in_be32(&pcmcia->pcmc_pscr);
@@ -614,7 +606,7 @@ static irqreturn_t m8xx_interrupt(int ir
 
 		/* call the handler */
 
-		dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
+		pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
 			"pipr = 0x%08x\n", i, events, pscr, pipr);
 
 		if (events) {
@@ -641,7 +633,7 @@ static irqreturn_t m8xx_interrupt(int ir
 	/* clear the interrupt sources */
 	out_be32(&pcmcia->pcmc_pscr, pscr);
 
-	dprintk("Interrupt done.\n");
+	pr_debug("m8xx_pcmcia: Interrupt done.\n");
 
 	return IRQ_HANDLED;
 }
@@ -815,7 +807,7 @@ static int m8xx_get_status(struct pcmcia
 		};
 	}
 
-	dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
+	pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
 	return 0;
 }
 
@@ -828,7 +820,7 @@ static int m8xx_set_socket(struct pcmcia
 	unsigned long flags;
 	pcmconf8xx_t *pcmcia = socket[0].pcmcia;
 
-	dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+	pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 		"io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
 		state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -974,7 +966,7 @@ static int m8xx_set_io_map(struct pcmcia
 #define M8XX_SIZE (io->stop - io->start + 1)
 #define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
 
-	dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
 		"%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
 		io->speed, (unsigned long long)io->start,
 		(unsigned long long)io->stop);
@@ -988,7 +980,7 @@ static int m8xx_set_io_map(struct pcmcia
 
 	if (io->flags & MAP_ACTIVE) {
 
-		dprintk("io->flags & MAP_ACTIVE\n");
+		pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
 
 		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
 		    + (lsock * PCMCIA_IO_WIN_NO) + io->map;
@@ -1018,8 +1010,8 @@ static int m8xx_set_io_map(struct pcmcia
 
 		out_be32(&w->or, reg);
 
-		dprintk("Socket %u: Mapped io window %u at %#8.8x, "
-			"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+		pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
+			"%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
 	} else {
 		/* shutdown IO window */
 		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
@@ -1033,14 +1025,14 @@ static int m8xx_set_io_map(struct pcmcia
 		out_be32(&w->or, 0);	/* turn off window */
 		out_be32(&w->br, 0);	/* turn off base address */
 
-		dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
-			"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+		pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
+			"%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
 	}
 
 	/* copy the struct and modify the copy */
 	s->io_win[io->map] = *io;
 	s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
-	dprintk("SetIOMap exit\n");
+	pr_debug("m8xx_pcmcia: SetIOMap exit\n");
 
 	return 0;
 }
@@ -1055,7 +1047,7 @@ static int m8xx_set_mem_map(struct pcmci
 	unsigned int reg, winnr;
 	pcmconf8xx_t *pcmcia = s->pcmcia;
 
-	dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
 		"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
 		mem->speed, (unsigned long long)mem->static_start,
 		mem->card_start);
@@ -1098,7 +1090,7 @@ static int m8xx_set_mem_map(struct pcmci
 
 	out_be32(&w->or, reg);
 
-	dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
+	pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
 		"OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
 
 	if (mem->flags & MAP_ACTIVE) {
@@ -1108,7 +1100,7 @@ static int m8xx_set_mem_map(struct pcmci
 		    + mem->card_start;
 	}
 
-	dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+	pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
 		"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
 		mem->speed, (unsigned long long)mem->static_start,
 		mem->card_start);
@@ -1129,7 +1121,7 @@ static int m8xx_sock_init(struct pcmcia_
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
 	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
 
-	dprintk("sock_init(%d)\n", s);
+	pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
 
 	m8xx_set_socket(sock, &dead_socket);
 	for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/Makefile linux-libre-2.6.33-gnu1/drivers/pcmcia/Makefile
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -22,8 +22,9 @@ obj-$(CONFIG_I82365)				+= i82365.o
 obj-$(CONFIG_I82092)				+= i82092.o
 obj-$(CONFIG_TCIC)				+= tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)			+= m8xx_pcmcia.o
-obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_core.o sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_core.o sa1111_cs.o
+obj-$(CONFIG_PCMCIA_SOC_COMMON)			+= soc_common.o
+obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_base.o sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_base.o sa1111_cs.o
 obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
 obj-$(CONFIG_PCMCIA_AU1X00)			+= au1x00_ss.o
@@ -35,9 +36,6 @@ obj-$(CONFIG_BFIN_CFPCMCIA)			+= bfin_cf
 obj-$(CONFIG_AT91_CF)				+= at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
 
-sa11xx_core-y					+= soc_common.o sa11xx_base.o
-pxa2xx_core-y					+= soc_common.o pxa2xx_base.o
-
 au1x00_ss-y					+= au1000_generic.o
 au1x00_ss-$(CONFIG_MIPS_PB1000)			+= au1000_pb1x00.o
 au1x00_ss-$(CONFIG_MIPS_PB1100)			+= au1000_pb1x00.o
@@ -69,7 +67,7 @@ pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)		+= px
 pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)		+= pxa2xx_sharpsl.o
 pxa2xx-obj-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x2xx_cs.o
-pxa2xx-obj-$(CONFIG_ARCH_VIPER)			+= pxa2xx_viper.o
+pxa2xx-obj-$(CONFIG_ARCOM_PCMCIA)		+= pxa2xx_viper.o
 pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)		+= pxa2xx_trizeps4.o
 pxa2xx-obj-$(CONFIG_MACH_PALMTX)		+= pxa2xx_palmtx.o
 pxa2xx-obj-$(CONFIG_MACH_PALMTC)		+= pxa2xx_palmtc.o
@@ -77,4 +75,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD)		+= pxa
 pxa2xx-obj-$(CONFIG_MACH_E740)			+= pxa2xx_e740.o
 pxa2xx-obj-$(CONFIG_MACH_STARGATE2)		+= pxa2xx_stargate2.o
 
-obj-$(CONFIG_PCMCIA_PXA2XX)			+= pxa2xx_core.o $(pxa2xx-obj-y)
+obj-$(CONFIG_PCMCIA_PXA2XX)			+= pxa2xx_base.o $(pxa2xx-obj-y)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/o2micro.h linux-libre-2.6.33-gnu1/drivers/pcmcia/o2micro.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/o2micro.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/o2micro.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,28 +30,6 @@
 #ifndef _LINUX_O2MICRO_H
 #define _LINUX_O2MICRO_H
 
-#ifndef PCI_VENDOR_ID_O2
-#define PCI_VENDOR_ID_O2		0x1217
-#endif
-#ifndef PCI_DEVICE_ID_O2_6729
-#define PCI_DEVICE_ID_O2_6729		0x6729
-#endif
-#ifndef PCI_DEVICE_ID_O2_6730
-#define PCI_DEVICE_ID_O2_6730		0x673a
-#endif
-#ifndef PCI_DEVICE_ID_O2_6832
-#define PCI_DEVICE_ID_O2_6832		0x6832
-#endif
-#ifndef PCI_DEVICE_ID_O2_6836
-#define PCI_DEVICE_ID_O2_6836		0x6836
-#endif
-#ifndef PCI_DEVICE_ID_O2_6812
-#define PCI_DEVICE_ID_O2_6812		0x6872
-#endif
-#ifndef PCI_DEVICE_ID_O2_6933
-#define PCI_DEVICE_ID_O2_6933           0x6933
-#endif
-
 /* Additional PCI configuration registers */
 
 #define O2_MUX_CONTROL		0x90	/* 32 bit */
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/omap_cf.c linux-libre-2.6.33-gnu1/drivers/pcmcia/omap_cf.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/omap_cf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/omap_cf.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,8 +23,8 @@
 #include <asm/io.h>
 #include <asm/sizes.h>
 
-#include <mach/mux.h>
-#include <mach/tc.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
 
 
 /* NOTE:  don't expect this to support many I/O cards.  The 16xx chips have
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pcmcia_ioctl.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pcmcia_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,17 +58,6 @@ typedef struct user_info_t {
 } user_info_t;
 
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(lvl, fmt, arg...) do {		\
-	if (ds_pc_debug >= lvl)				\
-		printk(KERN_DEBUG "ds: " fmt , ## arg);		\
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
 						unsigned int function)
 {
@@ -99,12 +88,12 @@ static struct pcmcia_driver *get_pcmcia_
 
 	p_drv = container_of(drv, struct pcmcia_driver, drv);
 
-	return (p_drv);
+	return p_drv;
 }
 
 
 #ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_pccard = NULL;
+static struct proc_dir_entry *proc_pccard;
 
 static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
 {
@@ -169,7 +158,8 @@ static int adjust_irq(struct pcmcia_sock
 
 #else
 
-static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
+static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
+{
 	return 0;
 }
 
@@ -206,7 +196,7 @@ static int pcmcia_adjust_resource_info(a
 				begin = adj->resource.memory.Base;
 				end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
 				if (s->resource_ops->add_mem)
-					ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
+					ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
 			case RES_IO_RANGE:
 				begin = adj->resource.io.BasePort;
 				end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
@@ -226,9 +216,64 @@ static int pcmcia_adjust_resource_info(a
 	}
 	up_read(&pcmcia_socket_list_rwsem);
 
-	return (ret);
+	return ret;
 }
 
+
+/** pcmcia_get_window
+ */
+static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
+			window_handle_t wh, win_req_t *req)
+{
+	pccard_mem_map *win;
+	window_handle_t w;
+
+	wh--;
+	if (!s || !(s->state & SOCKET_PRESENT))
+		return -ENODEV;
+	if (wh >= MAX_WIN)
+		return -EINVAL;
+	for (w = wh; w < MAX_WIN; w++)
+		if (s->state & SOCKET_WIN_REQ(w))
+			break;
+	if (w == MAX_WIN)
+		return -EINVAL;
+	win = &s->win[w];
+	req->Base = win->res->start;
+	req->Size = win->res->end - win->res->start + 1;
+	req->AccessSpeed = win->speed;
+	req->Attributes = 0;
+	if (win->flags & MAP_ATTRIB)
+		req->Attributes |= WIN_MEMORY_TYPE_AM;
+	if (win->flags & MAP_ACTIVE)
+		req->Attributes |= WIN_ENABLE;
+	if (win->flags & MAP_16BIT)
+		req->Attributes |= WIN_DATA_WIDTH_16;
+	if (win->flags & MAP_USE_WAIT)
+		req->Attributes |= WIN_USE_WAIT;
+
+	*wh_out = w + 1;
+	return 0;
+} /* pcmcia_get_window */
+
+
+/** pcmcia_get_mem_page
+ *
+ * Change the card address of an already open memory window.
+ */
+static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
+			memreq_t *req)
+{
+	wh--;
+	if (wh >= MAX_WIN)
+		return -EINVAL;
+
+	req->Page = 0;
+	req->CardOffset = skt->win[wh].card_start;
+	return 0;
+} /* pcmcia_get_mem_page */
+
+
 /** pccard_get_status
  *
  * Get the current socket state bits.  We don't support the latched
@@ -431,7 +476,7 @@ static int bind_request(struct pcmcia_so
 	if (!s)
 		return -EINVAL;
 
-	ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
+	pr_debug("bind_request(%d, '%s')\n", s->sock,
 	       (char *)bind_info->dev_info);
 
 	p_drv = get_pcmcia_driver(&bind_info->dev_info);
@@ -446,7 +491,7 @@ static int bind_request(struct pcmcia_so
 	}
 
 	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-        list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
+	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
 		if (p_dev->func == bind_info->function) {
 			if ((p_dev->dev.driver == &p_drv->drv)) {
 				if (p_dev->cardmgr) {
@@ -514,7 +559,7 @@ rescan:
  err_put:
 	pcmcia_put_socket(s);
 
-	return (ret);
+	return ret;
 } /* bind_request */
 
 #ifdef CONFIG_CARDBUS
@@ -611,7 +656,7 @@ static int get_device_info(struct pcmcia
 
  err_put:
 	pcmcia_put_dev(p_dev);
-	return (ret);
+	return ret;
 } /* get_device_info */
 
 
@@ -620,10 +665,10 @@ static int ds_open(struct inode *inode,
     socket_t i = iminor(inode);
     struct pcmcia_socket *s;
     user_info_t *user;
-    static int warning_printed = 0;
+    static int warning_printed;
     int ret = 0;
 
-    ds_dbg(0, "ds_open(socket %d)\n", i);
+    pr_debug("ds_open(socket %d)\n", i);
 
     lock_kernel();
     s = pcmcia_get_socket_by_nr(i);
@@ -685,7 +730,7 @@ static int ds_release(struct inode *inod
     struct pcmcia_socket *s;
     user_info_t *user, **link;
 
-    ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
+    pr_debug("ds_release(socket %d)\n", iminor(inode));
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -694,12 +739,13 @@ static int ds_release(struct inode *inod
     s = user->socket;
 
     /* Unlink user data structure */
-    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+    if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 	s->pcmcia_state.busy = 0;
-    }
+
     file->private_data = NULL;
     for (link = &s->user; *link; link = &(*link)->next)
-	if (*link == user) break;
+	if (*link == user)
+		break;
     if (link == NULL)
 	goto out;
     *link = user->next;
@@ -719,7 +765,7 @@ static ssize_t ds_read(struct file *file
     user_info_t *user;
     int ret;
 
-    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count < 4)
 	return -EINVAL;
@@ -730,7 +776,7 @@ static ssize_t ds_read(struct file *file
 
     s = user->socket;
     if (s->pcmcia_state.dead)
-        return -EIO;
+	return -EIO;
 
     ret = wait_event_interruptible(s->queue, !queue_empty(user));
     if (ret == 0)
@@ -744,7 +790,7 @@ static ssize_t ds_read(struct file *file
 static ssize_t ds_write(struct file *file, const char __user *buf,
 			size_t count, loff_t *ppos)
 {
-    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count != 4)
 	return -EINVAL;
@@ -762,7 +808,7 @@ static u_int ds_poll(struct file *file,
     struct pcmcia_socket *s;
     user_info_t *user;
 
-    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -780,7 +826,7 @@ static u_int ds_poll(struct file *file,
 
 /*====================================================================*/
 
-static int ds_ioctl(struct inode * inode, struct file * file,
+static int ds_ioctl(struct inode *inode, struct file *file,
 		    u_int cmd, u_long arg)
 {
     struct pcmcia_socket *s;
@@ -790,7 +836,7 @@ static int ds_ioctl(struct inode * inode
     ds_ioctl_arg_t *buf;
     user_info_t *user;
 
-    ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
+    pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -798,10 +844,11 @@ static int ds_ioctl(struct inode * inode
 
     s = user->socket;
     if (s->pcmcia_state.dead)
-        return -EIO;
+	return -EIO;
 
     size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
-    if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
+    if (size > sizeof(ds_ioctl_arg_t))
+	return -EINVAL;
 
     /* Permission check */
     if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
@@ -809,13 +856,13 @@ static int ds_ioctl(struct inode * inode
 
     if (cmd & IOC_IN) {
 	if (!access_ok(VERIFY_READ, uarg, size)) {
-	    ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
+	    pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
 	    return -EFAULT;
 	}
     }
     if (cmd & IOC_OUT) {
 	if (!access_ok(VERIFY_WRITE, uarg, size)) {
-	    ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
+	    pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
 	    return -EFAULT;
 	}
     }
@@ -927,15 +974,15 @@ static int ds_ioctl(struct inode * inode
 	goto free_out;
 	break;
     case DS_GET_FIRST_WINDOW:
-	ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
+	ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
 			&buf->win_info.window);
 	break;
     case DS_GET_NEXT_WINDOW:
 	ret = pcmcia_get_window(s, &buf->win_info.handle,
-			buf->win_info.handle->index + 1, &buf->win_info.window);
+			buf->win_info.handle + 1, &buf->win_info.window);
 	break;
     case DS_GET_MEM_PAGE:
-	ret = pcmcia_get_mem_page(buf->win_info.handle,
+	ret = pcmcia_get_mem_page(s, buf->win_info.handle,
 			   &buf->win_info.map);
 	break;
     case DS_REPLACE_CIS:
@@ -962,7 +1009,7 @@ static int ds_ioctl(struct inode * inode
     }
 
     if ((err == 0) && (ret != 0)) {
-	ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
+	pr_debug("ds_ioctl: ret = %d\n", ret);
 	switch (ret) {
 	case -ENODEV:
 	case -EINVAL:
@@ -980,8 +1027,8 @@ static int ds_ioctl(struct inode * inode
     }
 
     if (cmd & IOC_OUT) {
-        if (__copy_to_user(uarg, (char *)buf, size))
-            err = -EFAULT;
+	if (__copy_to_user(uarg, (char *)buf, size))
+		err = -EFAULT;
     }
 
 free_out:
@@ -1001,7 +1048,8 @@ static const struct file_operations ds_f
 	.poll		= ds_poll,
 };
 
-void __init pcmcia_setup_ioctl(void) {
+void __init pcmcia_setup_ioctl(void)
+{
 	int i;
 
 	/* Set up character device for user mode clients */
@@ -1020,7 +1068,8 @@ void __init pcmcia_setup_ioctl(void) {
 }
 
 
-void __exit pcmcia_cleanup_ioctl(void) {
+void __exit pcmcia_cleanup_ioctl(void)
+{
 #ifdef CONFIG_PROC_FS
 	if (proc_pccard) {
 		remove_proc_entry("drivers", proc_pccard);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pcmcia_resource.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_resource.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pcmcia_resource.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pcmcia_resource.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/device.h>
+#include <linux/netdevice.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -32,7 +33,7 @@
 
 
 /* Access speed for IO windows */
-static int io_speed = 0;
+static int io_speed;
 module_param(io_speed, int, 0444);
 
 
@@ -43,21 +44,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
 #endif
 
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(skt, lvl, fmt, arg...) do {			\
-	if (ds_pc_debug >= lvl)					\
-		dev_printk(KERN_DEBUG, &skt->dev,		\
-			   "pcmcia_resource: " fmt,		\
-			   ## arg);				\
-} while (0)
-#else
-#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#endif
-
-
-
 /** alloc_io_space
  *
  * Special stuff for managing IO windows, because they are scarce
@@ -72,14 +58,15 @@ static int alloc_io_space(struct pcmcia_
 	align = (*base) ? (lines ? 1<<lines : 0) : 1;
 	if (align && (align < num)) {
 		if (*base) {
-			ds_dbg(s, 0, "odd IO request: num %#x align %#x\n",
+			dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n",
 			       num, align);
 			align = 0;
 		} else
-			while (align && (align < num)) align <<= 1;
+			while (align && (align < num))
+				align <<= 1;
 	}
 	if (*base & ~(align-1)) {
-		ds_dbg(s, 0, "odd IO request: base %#x align %#x\n",
+		dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n",
 		       *base, align);
 		align = 0;
 	}
@@ -173,8 +160,10 @@ int pcmcia_access_configuration_register
 	s = p_dev->socket;
 	c = p_dev->function_config;
 
-	if (!(c->state & CONFIG_LOCKED))
+	if (!(c->state & CONFIG_LOCKED)) {
+		dev_dbg(&s->dev, "Configuration isnt't locked\n");
 		return -EACCES;
+	}
 
 	addr = (c->ConfigBase + reg->Offset) >> 1;
 
@@ -188,6 +177,7 @@ int pcmcia_access_configuration_register
 		pcmcia_write_cis_mem(s, 1, addr, 1, &val);
 		break;
 	default:
+		dev_dbg(&s->dev, "Invalid conf register request\n");
 		return -EINVAL;
 		break;
 	}
@@ -196,68 +186,21 @@ int pcmcia_access_configuration_register
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
 
-/** pcmcia_get_window
- */
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
-		      int idx, win_req_t *req)
-{
-	window_t *win;
-	int w;
-
-	if (!s || !(s->state & SOCKET_PRESENT))
-		return -ENODEV;
-	for (w = idx; w < MAX_WIN; w++)
-		if (s->state & SOCKET_WIN_REQ(w))
-			break;
-	if (w == MAX_WIN)
-		return -EINVAL;
-	win = &s->win[w];
-	req->Base = win->ctl.res->start;
-	req->Size = win->ctl.res->end - win->ctl.res->start + 1;
-	req->AccessSpeed = win->ctl.speed;
-	req->Attributes = 0;
-	if (win->ctl.flags & MAP_ATTRIB)
-		req->Attributes |= WIN_MEMORY_TYPE_AM;
-	if (win->ctl.flags & MAP_ACTIVE)
-		req->Attributes |= WIN_ENABLE;
-	if (win->ctl.flags & MAP_16BIT)
-		req->Attributes |= WIN_DATA_WIDTH_16;
-	if (win->ctl.flags & MAP_USE_WAIT)
-		req->Attributes |= WIN_USE_WAIT;
-	*handle = win;
-	return 0;
-} /* pcmcia_get_window */
-EXPORT_SYMBOL(pcmcia_get_window);
-
-
-/** pcmcia_get_mem_page
- *
- * Change the card address of an already open memory window.
- */
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
+int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
+			memreq_t *req)
 {
-	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-		return -EINVAL;
-	req->Page = 0;
-	req->CardOffset = win->ctl.card_start;
-	return 0;
-} /* pcmcia_get_mem_page */
-EXPORT_SYMBOL(pcmcia_get_mem_page);
-
+	struct pcmcia_socket *s = p_dev->socket;
 
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
-{
-	struct pcmcia_socket *s;
-	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+	wh--;
+	if (wh >= MAX_WIN)
 		return -EINVAL;
-	s = win->sock;
 	if (req->Page != 0) {
-		ds_dbg(s, 0, "failure: requested page is zero\n");
+		dev_dbg(&s->dev, "failure: requested page is zero\n");
 		return -EINVAL;
 	}
-	win->ctl.card_start = req->CardOffset;
-	if (s->ops->set_mem_map(s, &win->ctl) != 0) {
-		ds_dbg(s, 0, "failed to set_mem_map\n");
+	s->win[wh].card_start = req->CardOffset;
+	if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
+		dev_dbg(&s->dev, "failed to set_mem_map\n");
 		return -EIO;
 	}
 	return 0;
@@ -278,10 +221,14 @@ int pcmcia_modify_configuration(struct p
 	s = p_dev->socket;
 	c = p_dev->function_config;
 
-	if (!(s->state & SOCKET_PRESENT))
+	if (!(s->state & SOCKET_PRESENT)) {
+		dev_dbg(&s->dev, "No card present\n");
 		return -ENODEV;
-	if (!(c->state & CONFIG_LOCKED))
+	}
+	if (!(c->state & CONFIG_LOCKED)) {
+		dev_dbg(&s->dev, "Configuration isnt't locked\n");
 		return -EACCES;
+	}
 
 	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
 		if (mod->Attributes & CONF_ENABLE_IRQ) {
@@ -295,7 +242,7 @@ int pcmcia_modify_configuration(struct p
 	}
 
 	if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
-		ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
 		return -EINVAL;
 	}
 
@@ -303,7 +250,7 @@ int pcmcia_modify_configuration(struct p
 	if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
 	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
 		if (mod->Vpp1 != mod->Vpp2) {
-			ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
+			dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
 			return -EINVAL;
 		}
 		s->socket.Vpp = mod->Vpp1;
@@ -314,7 +261,7 @@ int pcmcia_modify_configuration(struct p
 		}
 	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
 		   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
-		ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+		dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
 		return -EINVAL;
 	}
 
@@ -392,7 +339,7 @@ static int pcmcia_release_io(struct pcmc
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c = p_dev->function_config;
 
-	if (!p_dev->_io )
+	if (!p_dev->_io)
 		return -EINVAL;
 
 	p_dev->_io = 0;
@@ -416,7 +363,7 @@ static int pcmcia_release_io(struct pcmc
 static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
-	config_t *c= p_dev->function_config;
+	config_t *c = p_dev->function_config;
 
 	if (!p_dev->_irq)
 		return -EINVAL;
@@ -425,11 +372,11 @@ static int pcmcia_release_irq(struct pcm
 	if (c->state & CONFIG_LOCKED)
 		return -EACCES;
 	if (c->irq.Attributes != req->Attributes) {
-		ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
+		dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
 		return -EINVAL;
 	}
 	if (s->irq.AssignedIRQ != req->AssignedIRQ) {
-		ds_dbg(s, 0, "IRQ must match assigned one\n");
+		dev_dbg(&s->dev, "IRQ must match assigned one\n");
 		return -EINVAL;
 	}
 	if (--s->irq.Config == 0) {
@@ -437,9 +384,8 @@ static int pcmcia_release_irq(struct pcm
 		s->irq.AssignedIRQ = 0;
 	}
 
-	if (req->Attributes & IRQ_HANDLE_PRESENT) {
-		free_irq(req->AssignedIRQ, req->Instance);
-	}
+	if (req->Handler)
+		free_irq(req->AssignedIRQ, p_dev->priv);
 
 #ifdef CONFIG_PCMCIA_PROBE
 	pcmcia_used_irq[req->AssignedIRQ]--;
@@ -449,30 +395,34 @@ static int pcmcia_release_irq(struct pcm
 } /* pcmcia_release_irq */
 
 
-int pcmcia_release_window(window_handle_t win)
+int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
 {
-	struct pcmcia_socket *s;
+	struct pcmcia_socket *s = p_dev->socket;
+	pccard_mem_map *win;
 
-	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+	wh--;
+	if (wh >= MAX_WIN)
 		return -EINVAL;
-	s = win->sock;
-	if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
+
+	win = &s->win[wh];
+
+	if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
+		dev_dbg(&s->dev, "not releasing unknown window\n");
 		return -EINVAL;
+	}
 
 	/* Shut down memory window */
-	win->ctl.flags &= ~MAP_ACTIVE;
-	s->ops->set_mem_map(s, &win->ctl);
-	s->state &= ~SOCKET_WIN_REQ(win->index);
+	win->flags &= ~MAP_ACTIVE;
+	s->ops->set_mem_map(s, win);
+	s->state &= ~SOCKET_WIN_REQ(wh);
 
 	/* Release system memory */
-	if (win->ctl.res) {
-		release_resource(win->ctl.res);
-		kfree(win->ctl.res);
-		win->ctl.res = NULL;
+	if (win->res) {
+		release_resource(win->res);
+		kfree(win->res);
+		win->res = NULL;
 	}
-	win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
-
-	win->magic = 0;
+	p_dev->_win &= ~CLIENT_WIN_REQ(wh);
 
 	return 0;
 } /* pcmcia_release_window */
@@ -492,12 +442,14 @@ int pcmcia_request_configuration(struct
 		return -ENODEV;
 
 	if (req->IntType & INT_CARDBUS) {
-		ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
+		dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
 		return -EINVAL;
 	}
 	c = p_dev->function_config;
-	if (c->state & CONFIG_LOCKED)
+	if (c->state & CONFIG_LOCKED) {
+		dev_dbg(&s->dev, "Configuration is locked\n");
 		return -EACCES;
+	}
 
 	/* Do power control.  We don't allow changes in Vcc. */
 	s->socket.Vpp = req->Vpp;
@@ -609,40 +561,44 @@ int pcmcia_request_io(struct pcmcia_devi
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c;
 
-	if (!(s->state & SOCKET_PRESENT))
+	if (!(s->state & SOCKET_PRESENT)) {
+		dev_dbg(&s->dev, "No card present\n");
 		return -ENODEV;
+	}
 
 	if (!req)
 		return -EINVAL;
 	c = p_dev->function_config;
-	if (c->state & CONFIG_LOCKED)
+	if (c->state & CONFIG_LOCKED) {
+		dev_dbg(&s->dev, "Configuration is locked\n");
 		return -EACCES;
+	}
 	if (c->state & CONFIG_IO_REQ) {
-		ds_dbg(s, 0, "IO already configured\n");
+		dev_dbg(&s->dev, "IO already configured\n");
 		return -EBUSY;
 	}
 	if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
-		ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
+		dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
 		return -EINVAL;
 	}
 	if ((req->NumPorts2 > 0) &&
 	    (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
-		ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
+		dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
 		return -EINVAL;
 	}
 
-	ds_dbg(s, 1, "trying to allocate resource 1\n");
+	dev_dbg(&s->dev, "trying to allocate resource 1\n");
 	if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
 			   req->NumPorts1, req->IOAddrLines)) {
-		ds_dbg(s, 0, "allocation of resource 1 failed\n");
+		dev_dbg(&s->dev, "allocation of resource 1 failed\n");
 		return -EBUSY;
 	}
 
 	if (req->NumPorts2) {
-		ds_dbg(s, 1, "trying to allocate resource 2\n");
+		dev_dbg(&s->dev, "trying to allocate resource 2\n");
 		if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
 				   req->NumPorts2, req->IOAddrLines)) {
-			ds_dbg(s, 0, "allocation of resource 2 failed\n");
+			dev_dbg(&s->dev, "allocation of resource 2 failed\n");
 			release_io_space(s, req->BasePort1, req->NumPorts1);
 			return -EBUSY;
 		}
@@ -680,13 +636,17 @@ int pcmcia_request_irq(struct pcmcia_dev
 	int ret = -EINVAL, irq = 0;
 	int type;
 
-	if (!(s->state & SOCKET_PRESENT))
+	if (!(s->state & SOCKET_PRESENT)) {
+		dev_dbg(&s->dev, "No card present\n");
 		return -ENODEV;
+	}
 	c = p_dev->function_config;
-	if (c->state & CONFIG_LOCKED)
+	if (c->state & CONFIG_LOCKED) {
+		dev_dbg(&s->dev, "Configuration is locked\n");
 		return -EACCES;
+	}
 	if (c->state & CONFIG_IRQ_REQ) {
-		ds_dbg(s, 0, "IRQ already configured\n");
+		dev_dbg(&s->dev, "IRQ already configured\n");
 		return -EBUSY;
 	}
 
@@ -696,7 +656,8 @@ int pcmcia_request_irq(struct pcmcia_dev
 		type = IRQF_SHARED;
 	else if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)
 		type = IRQF_SHARED;
-	else printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
+	else
+		printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
 
 #ifdef CONFIG_PCMCIA_PROBE
 
@@ -704,7 +665,7 @@ int pcmcia_request_irq(struct pcmcia_dev
 	/* if the underlying IRQ infrastructure allows for it, only allocate
 	 * the IRQ, but do not enable it
 	 */
-	if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+	if (!(req->Handler))
 		type |= IRQ_NOAUTOEN;
 #endif /* IRQ_NOAUTOEN */
 
@@ -714,7 +675,7 @@ int pcmcia_request_irq(struct pcmcia_dev
 	} else {
 		int try;
 		u32 mask = s->irq_mask;
-		void *data = &p_dev->dev.driver; /* something unique to this device */
+		void *data = p_dev; /* something unique to this device */
 
 		for (try = 0; try < 64; try++) {
 			irq = try % 32;
@@ -731,12 +692,12 @@ int pcmcia_request_irq(struct pcmcia_dev
 			 * registering a dummy handle works, i.e. if the IRQ isn't
 			 * marked as used by the kernel resource management core */
 			ret = request_irq(irq,
-					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
+					  (req->Handler) ? req->Handler : test_action,
 					  type,
 					  p_dev->devname,
-					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
+					  (req->Handler) ? p_dev->priv : data);
 			if (!ret) {
-				if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+				if (!req->Handler)
 					free_irq(irq, data);
 				break;
 			}
@@ -745,17 +706,22 @@ int pcmcia_request_irq(struct pcmcia_dev
 #endif
 	/* only assign PCI irq if no IRQ already assigned */
 	if (ret && !s->irq.AssignedIRQ) {
-		if (!s->pci_irq)
+		if (!s->pci_irq) {
+			dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
 			return ret;
+		}
 		type = IRQF_SHARED;
 		irq = s->pci_irq;
 	}
 
-	if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
+	if (ret && req->Handler) {
 		ret = request_irq(irq, req->Handler, type,
-				  p_dev->devname, req->Instance);
-		if (ret)
+				  p_dev->devname, p_dev->priv);
+		if (ret) {
+			dev_printk(KERN_INFO, &s->dev,
+				"request_irq() failed\n");
 			return ret;
+		}
 	}
 
 	/* Make sure the fact the request type was overridden is passed back */
@@ -787,17 +753,19 @@ EXPORT_SYMBOL(pcmcia_request_irq);
  * Request_window() establishes a mapping between card memory space
  * and system memory space.
  */
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
+int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh)
 {
-	struct pcmcia_socket *s = (*p_dev)->socket;
-	window_t *win;
+	struct pcmcia_socket *s = p_dev->socket;
+	pccard_mem_map *win;
 	u_long align;
 	int w;
 
-	if (!(s->state & SOCKET_PRESENT))
+	if (!(s->state & SOCKET_PRESENT)) {
+		dev_dbg(&s->dev, "No card present\n");
 		return -ENODEV;
+	}
 	if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
-		ds_dbg(s, 0, "bad attribute setting for iomem region\n");
+		dev_dbg(&s->dev, "bad attribute setting for iomem region\n");
 		return -EINVAL;
 	}
 
@@ -808,12 +776,12 @@ int pcmcia_request_window(struct pcmcia_
 		  (req->Attributes & WIN_STRICT_ALIGN)) ?
 		 req->Size : s->map_size);
 	if (req->Size & (s->map_size-1)) {
-		ds_dbg(s, 0, "invalid map size\n");
+		dev_dbg(&s->dev, "invalid map size\n");
 		return -EINVAL;
 	}
 	if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
 	    (req->Base & (align-1))) {
-		ds_dbg(s, 0, "invalid base address\n");
+		dev_dbg(&s->dev, "invalid base address\n");
 		return -EINVAL;
 	}
 	if (req->Base)
@@ -821,77 +789,102 @@ int pcmcia_request_window(struct pcmcia_
 
 	/* Allocate system memory window */
 	for (w = 0; w < MAX_WIN; w++)
-		if (!(s->state & SOCKET_WIN_REQ(w))) break;
+		if (!(s->state & SOCKET_WIN_REQ(w)))
+			break;
 	if (w == MAX_WIN) {
-		ds_dbg(s, 0, "all windows are used already\n");
+		dev_dbg(&s->dev, "all windows are used already\n");
 		return -EINVAL;
 	}
 
 	win = &s->win[w];
-	win->magic = WINDOW_MAGIC;
-	win->index = w;
-	win->handle = *p_dev;
-	win->sock = s;
 
 	if (!(s->features & SS_CAP_STATIC_MAP)) {
-		win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
+		win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
 						      (req->Attributes & WIN_MAP_BELOW_1MB), s);
-		if (!win->ctl.res) {
-			ds_dbg(s, 0, "allocating mem region failed\n");
+		if (!win->res) {
+			dev_dbg(&s->dev, "allocating mem region failed\n");
 			return -EINVAL;
 		}
 	}
-	(*p_dev)->_win |= CLIENT_WIN_REQ(w);
+	p_dev->_win |= CLIENT_WIN_REQ(w);
 
 	/* Configure the socket controller */
-	win->ctl.map = w+1;
-	win->ctl.flags = 0;
-	win->ctl.speed = req->AccessSpeed;
+	win->map = w+1;
+	win->flags = 0;
+	win->speed = req->AccessSpeed;
 	if (req->Attributes & WIN_MEMORY_TYPE)
-		win->ctl.flags |= MAP_ATTRIB;
+		win->flags |= MAP_ATTRIB;
 	if (req->Attributes & WIN_ENABLE)
-		win->ctl.flags |= MAP_ACTIVE;
+		win->flags |= MAP_ACTIVE;
 	if (req->Attributes & WIN_DATA_WIDTH_16)
-		win->ctl.flags |= MAP_16BIT;
+		win->flags |= MAP_16BIT;
 	if (req->Attributes & WIN_USE_WAIT)
-		win->ctl.flags |= MAP_USE_WAIT;
-	win->ctl.card_start = 0;
-	if (s->ops->set_mem_map(s, &win->ctl) != 0) {
-		ds_dbg(s, 0, "failed to set memory mapping\n");
+		win->flags |= MAP_USE_WAIT;
+	win->card_start = 0;
+	if (s->ops->set_mem_map(s, win) != 0) {
+		dev_dbg(&s->dev, "failed to set memory mapping\n");
 		return -EIO;
 	}
 	s->state |= SOCKET_WIN_REQ(w);
 
 	/* Return window handle */
-	if (s->features & SS_CAP_STATIC_MAP) {
-		req->Base = win->ctl.static_start;
-	} else {
-		req->Base = win->ctl.res->start;
-	}
-	*wh = win;
+	if (s->features & SS_CAP_STATIC_MAP)
+		req->Base = win->static_start;
+	else
+		req->Base = win->res->start;
+
+	*wh = w + 1;
 
 	return 0;
 } /* pcmcia_request_window */
 EXPORT_SYMBOL(pcmcia_request_window);
 
-void pcmcia_disable_device(struct pcmcia_device *p_dev) {
+void pcmcia_disable_device(struct pcmcia_device *p_dev)
+{
 	pcmcia_release_configuration(p_dev);
 	pcmcia_release_io(p_dev, &p_dev->io);
 	pcmcia_release_irq(p_dev, &p_dev->irq);
 	if (p_dev->win)
-		pcmcia_release_window(p_dev->win);
+		pcmcia_release_window(p_dev, p_dev->win);
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
 
 
 struct pcmcia_cfg_mem {
-	tuple_t tuple;
+	struct pcmcia_device *p_dev;
+	void *priv_data;
+	int (*conf_check) (struct pcmcia_device *p_dev,
+			   cistpl_cftable_entry_t *cfg,
+			   cistpl_cftable_entry_t *dflt,
+			   unsigned int vcc,
+			   void *priv_data);
 	cisparse_t parse;
-	u8 buf[256];
 	cistpl_cftable_entry_t dflt;
 };
 
 /**
+ * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_config() is the internal callback for the call from
+ * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+	cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
+	struct pcmcia_cfg_mem *cfg_mem = priv;
+
+	/* default values */
+	cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
+	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+		cfg_mem->dflt = *cfg;
+
+	return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
+				   cfg_mem->p_dev->socket->socket.Vcc,
+				   cfg_mem->priv_data);
+}
+
+/**
  * pcmcia_loop_config() - loop over configuration options
  * @p_dev:	the struct pcmcia_device which we need to loop for.
  * @conf_check:	function to call for each configuration option.
@@ -913,48 +906,174 @@ int pcmcia_loop_config(struct pcmcia_dev
 		       void *priv_data)
 {
 	struct pcmcia_cfg_mem *cfg_mem;
-
-	tuple_t *tuple;
 	int ret;
-	unsigned int vcc;
 
 	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
 	if (cfg_mem == NULL)
 		return -ENOMEM;
 
-	/* get the current Vcc setting */
-	vcc = p_dev->socket->socket.Vcc;
+	cfg_mem->p_dev = p_dev;
+	cfg_mem->conf_check = conf_check;
+	cfg_mem->priv_data = priv_data;
 
-	tuple = &cfg_mem->tuple;
-	tuple->TupleData = cfg_mem->buf;
-	tuple->TupleDataMax = 255;
-	tuple->TupleOffset = 0;
-	tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	tuple->Attributes = 0;
+	ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
+				CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
+				cfg_mem, pcmcia_do_loop_config);
 
-	ret = pcmcia_get_first_tuple(p_dev, tuple);
-	while (!ret) {
-		cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
+	kfree(cfg_mem);
+	return ret;
+}
+EXPORT_SYMBOL(pcmcia_loop_config);
 
-		if (pcmcia_get_tuple_data(p_dev, tuple))
-			goto next_entry;
 
-		if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
-			goto next_entry;
+struct pcmcia_loop_mem {
+	struct pcmcia_device *p_dev;
+	void *priv_data;
+	int (*loop_tuple) (struct pcmcia_device *p_dev,
+			   tuple_t *tuple,
+			   void *priv_data);
+};
 
-		/* default values */
-		p_dev->conf.ConfigIndex = cfg->index;
-		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-			cfg_mem->dflt = *cfg;
+/**
+ * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_tuple() is the internal callback for the call from
+ * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+	struct pcmcia_loop_mem *loop = priv;
 
-		ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
-		if (!ret)
-			break;
+	return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
+};
 
-next_entry:
-		ret = pcmcia_get_next_tuple(p_dev, tuple);
+/**
+ * pcmcia_loop_tuple() - loop over tuples in the CIS
+ * @p_dev:	the struct pcmcia_device which we need to loop for.
+ * @code:	which CIS code shall we look for?
+ * @priv_data:	private data to be passed to the loop_tuple function.
+ * @loop_tuple:	function to call for each CIS entry of type @function. IT
+ *		gets passed the raw tuple and @priv_data.
+ *
+ * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+		      int (*loop_tuple) (struct pcmcia_device *p_dev,
+					 tuple_t *tuple,
+					 void *priv_data),
+		      void *priv_data)
+{
+	struct pcmcia_loop_mem loop = {
+		.p_dev = p_dev,
+		.loop_tuple = loop_tuple,
+		.priv_data = priv_data};
+
+	return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
+				 &loop, pcmcia_do_loop_tuple);
+}
+EXPORT_SYMBOL(pcmcia_loop_tuple);
+
+
+struct pcmcia_loop_get {
+	size_t len;
+	cisdata_t **buf;
+};
+
+/**
+ * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
+ *
+ * pcmcia_do_get_tuple() is the internal callback for the call from
+ * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
+ * the first tuple, return 0 unconditionally. Create a memory buffer large
+ * enough to hold the content of the tuple, and fill it with the tuple data.
+ * The caller is responsible to free the buffer.
+ */
+static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
+			       void *priv)
+{
+	struct pcmcia_loop_get *get = priv;
+
+	*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
+	if (*get->buf) {
+		get->len = tuple->TupleDataLen;
+		memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
+	} else
+		dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
+	return 0;
+}
+
+/**
+ * pcmcia_get_tuple() - get first tuple from CIS
+ * @p_dev:	the struct pcmcia_device which we need to loop for.
+ * @code:	which CIS code shall we look for?
+ * @buf:        pointer to store the buffer to.
+ *
+ * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
+ * It returns the buffer length (or zero). The caller is responsible to free
+ * the buffer passed in @buf.
+ */
+size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+			unsigned char **buf)
+{
+	struct pcmcia_loop_get get = {
+		.len = 0,
+		.buf = buf,
+	};
+
+	*get.buf = NULL;
+	pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
+
+	return get.len;
+}
+EXPORT_SYMBOL(pcmcia_get_tuple);
+
+
+/**
+ * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
+ *
+ * pcmcia_do_get_mac() is the internal callback for the call from
+ * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
+ * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
+ * to struct net_device->dev_addr[i].
+ */
+static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
+			     void *priv)
+{
+	struct net_device *dev = priv;
+	int i;
+
+	if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+		return -EINVAL;
+	if (tuple->TupleDataLen < ETH_ALEN + 2) {
+		dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
+			"LAN_NODE_ID\n");
+		return -EINVAL;
 	}
 
-	return ret;
+	if (tuple->TupleData[1] != ETH_ALEN) {
+		dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = tuple->TupleData[i+2];
+	return 0;
 }
-EXPORT_SYMBOL(pcmcia_loop_config);
+
+/**
+ * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
+ * @p_dev:	the struct pcmcia_device for which we want the address.
+ * @dev:	a properly prepared struct net_device to store the info to.
+ *
+ * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
+ * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
+ * must be set up properly by the driver (see examples!).
+ */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
+{
+	return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
+}
+EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pd6729.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pd6729.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.c	2010-02-24 13:52:17.000000000 -0500
@@ -213,7 +213,8 @@ static irqreturn_t pd6729_interrupt(int
 
 			if (csc & I365_CSC_DETECT) {
 				events |= SS_DETECT;
-				dprintk("Card detected in socket %i!\n", i);
+				dev_vdbg(&socket[i].socket.dev,
+					"Card detected in socket %i!\n", i);
 			}
 
 			if (indirect_read(&socket[i], I365_INTCTL)
@@ -331,11 +332,11 @@ static int pd6729_set_socket(struct pcmc
 	reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
 
 	if (state->flags & SS_PWR_AUTO) {
-		dprintk("Auto power\n");
+		dev_dbg(&sock->dev, "Auto power\n");
 		reg |= I365_PWR_AUTO;	/* automatic power mngmnt */
 	}
 	if (state->flags & SS_OUTPUT_ENA) {
-		dprintk("Power Enabled\n");
+		dev_dbg(&sock->dev, "Power Enabled\n");
 		reg |= I365_PWR_OUT;	/* enable power */
 	}
 
@@ -343,40 +344,44 @@ static int pd6729_set_socket(struct pcmc
 	case 0:
 		break;
 	case 33:
-		dprintk("setting voltage to Vcc to 3.3V on socket %i\n",
+		dev_dbg(&sock->dev,
+			"setting voltage to Vcc to 3.3V on socket %i\n",
 			socket->number);
 		reg |= I365_VCC_5V;
 		indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 		break;
 	case 50:
-		dprintk("setting voltage to Vcc to 5V on socket %i\n",
+		dev_dbg(&sock->dev,
+			"setting voltage to Vcc to 5V on socket %i\n",
 			socket->number);
 		reg |= I365_VCC_5V;
 		indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
 		break;
 	default:
-		dprintk("pd6729: pd6729_set_socket called with "
-				"invalid VCC power value: %i\n",
-			state->Vcc);
+		dev_dbg(&sock->dev,
+			"pd6729_set_socket called with invalid VCC power "
+			"value: %i\n", state->Vcc);
 		return -EINVAL;
 	}
 
 	switch (state->Vpp) {
 	case 0:
-		dprintk("not setting Vpp on socket %i\n", socket->number);
+		dev_dbg(&sock->dev, "not setting Vpp on socket %i\n",
+			socket->number);
 		break;
 	case 33:
 	case 50:
-		dprintk("setting Vpp to Vcc for socket %i\n", socket->number);
+		dev_dbg(&sock->dev, "setting Vpp to Vcc for socket %i\n",
+			socket->number);
 		reg |= I365_VPP1_5V;
 		break;
 	case 120:
-		dprintk("setting Vpp to 12.0\n");
+		dev_dbg(&sock->dev, "setting Vpp to 12.0\n");
 		reg |= I365_VPP1_12V;
 		break;
 	default:
-		dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n",
-			state->Vpp);
+		dev_dbg(&sock->dev, "pd6729: pd6729_set_socket called with "
+			"invalid VPP power value: %i\n", state->Vpp);
 		return -EINVAL;
 	}
 
@@ -438,7 +443,7 @@ static int pd6729_set_io_map(struct pcmc
 
 	/* Check error conditions */
 	if (map > 1) {
-		dprintk("pd6729_set_io_map with invalid map");
+		dev_dbg(&sock->dev, "pd6729_set_io_map with invalid map\n");
 		return -EINVAL;
 	}
 
@@ -446,7 +451,7 @@ static int pd6729_set_io_map(struct pcmc
 	if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
 		indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
 
-	/* dprintk("set_io_map: Setting range to %x - %x\n",
+	/* dev_dbg(&sock->dev, "set_io_map: Setting range to %x - %x\n",
 	   io->start, io->stop);*/
 
 	/* write the new values */
@@ -478,12 +483,12 @@ static int pd6729_set_mem_map(struct pcm
 
 	map = mem->map;
 	if (map > 4) {
-		printk("pd6729_set_mem_map: invalid map");
+		dev_warn(&sock->dev, "invalid map requested\n");
 		return -EINVAL;
 	}
 
 	if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
-		printk("pd6729_set_mem_map: invalid address / speed");
+		dev_warn(&sock->dev, "invalid invalid address / speed\n");
 		return -EINVAL;
 	}
 
@@ -529,12 +534,12 @@ static int pd6729_set_mem_map(struct pcm
 	if (mem->flags & MAP_WRPROT)
 		i |= I365_MEM_WRPROT;
 	if (mem->flags & MAP_ATTRIB) {
-		/* dprintk("requesting attribute memory for socket %i\n",
-			socket->number);*/
+		/* dev_dbg(&sock->dev, "requesting attribute memory for "
+		   "socket %i\n", socket->number);*/
 		i |= I365_MEM_REG;
 	} else {
-		/* dprintk("requesting normal memory for socket %i\n",
-			socket->number);*/
+		/* dev_dbg(&sock->dev, "requesting normal memory for "
+		   "socket %i\n", socket->number);*/
 	}
 	indirect_write16(socket, base + I365_W_OFF, i);
 
@@ -577,7 +582,7 @@ static struct pccard_operations pd6729_o
 
 static irqreturn_t pd6729_test(int irq, void *dev)
 {
-	dprintk("-> hit on irq %d\n", irq);
+	pr_devel("-> hit on irq %d\n", irq);
 	return IRQ_HANDLED;
 }
 
@@ -642,13 +647,13 @@ static int __devinit pd6729_pci_probe(st
 		goto err_out_free_mem;
 
 	if (!pci_resource_start(dev, 0)) {
-		printk(KERN_INFO "pd6729: refusing to load the driver "
-				 "as the io_base is 0.\n");
+		dev_warn(&dev->dev, "refusing to load the driver as the "
+			"io_base is NULL.\n");
 		goto err_out_free_mem;
 	}
 
-	printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
-		"at 0x%llx on irq %d\n",
+	dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
+		"on irq %d\n",
 		(unsigned long long)pci_resource_start(dev, 0), dev->irq);
  	/*
 	 * Since we have no memory BARs some firmware may not
@@ -656,14 +661,14 @@ static int __devinit pd6729_pci_probe(st
 	 */
 	pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
 	if (!(configbyte & PCI_COMMAND_MEMORY)) {
-		printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
+		dev_dbg(&dev->dev, "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
 		configbyte |= PCI_COMMAND_MEMORY;
 		pci_write_config_byte(dev, PCI_COMMAND, configbyte);
 	}
 
 	ret = pci_request_regions(dev, "pd6729");
 	if (ret) {
-		printk(KERN_INFO "pd6729: pci request region failed.\n");
+		dev_warn(&dev->dev, "pci request region failed.\n");
 		goto err_out_disable;
 	}
 
@@ -672,7 +677,7 @@ static int __devinit pd6729_pci_probe(st
 
 	mask = pd6729_isa_scan();
 	if (irq_mode == 0 && mask == 0) {
-		printk(KERN_INFO "pd6729: no ISA interrupt is available.\n");
+		dev_warn(&dev->dev, "no ISA interrupt is available.\n");
 		goto err_out_free_res;
 	}
 
@@ -697,8 +702,8 @@ static int __devinit pd6729_pci_probe(st
 		/* Register the interrupt handler */
 		if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
 							"pd6729", socket))) {
-			printk(KERN_ERR "pd6729: Failed to register irq %d, "
-							"aborting\n", dev->irq);
+			dev_err(&dev->dev, "Failed to register irq %d\n",
+				dev->irq);
 			goto err_out_free_res;
 		}
 	} else {
@@ -713,8 +718,7 @@ static int __devinit pd6729_pci_probe(st
 	for (i = 0; i < MAX_SOCKETS; i++) {
 		ret = pcmcia_register_socket(&socket[i].socket);
 		if (ret) {
-			printk(KERN_INFO "pd6729: pcmcia_register_socket "
-					       "failed.\n");
+			dev_warn(&dev->dev, "pcmcia_register_socket failed.\n");
 			for (j = 0; j < i ; j++)
 				pcmcia_unregister_socket(&socket[j].socket);
 			goto err_out_free_res2;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pd6729.h linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pd6729.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pd6729.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,13 +1,6 @@
 #ifndef _INCLUDE_GUARD_PD6729_H_
 #define _INCLUDE_GUARD_PD6729_H_
 
-/* Debuging defines */
-#ifdef NOTRACE
-#define dprintk(fmt, args...) printk(fmt , ## args)
-#else
-#define dprintk(fmt, args...) do {} while (0)
-#endif
-
 /* Flags for I365_GENCTL */
 #define I365_DF_VS1		0x40	/* DF-step Voltage Sense */
 #define I365_DF_VS2		0x80
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_base.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -214,7 +214,8 @@ static void pxa2xx_configure_sockets(str
 	MECR |= MECR_CIT;
 
 	/* Set MECR:NOS (Number Of Sockets) */
-	if ((ops->first + ops->nr) > 1 || machine_is_viper())
+	if ((ops->first + ops->nr) > 1 ||
+	    machine_is_viper() || machine_is_arcom_zeus())
 		MECR |= MECR_NOS;
 	else
 		MECR &= ~MECR_NOS;
@@ -228,17 +229,54 @@ static const char *skt_names[] = {
 #define SKT_DEV_INFO_SIZE(n) \
 	(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 
-int __pxa2xx_drv_pcmcia_probe(struct device *dev)
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 {
-	int i, ret;
+	skt->res_skt.start = _PCMCIA(skt->nr);
+	skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+	skt->res_skt.name = skt_names[skt->nr];
+	skt->res_skt.flags = IORESOURCE_MEM;
+
+	skt->res_io.start = _PCMCIAIO(skt->nr);
+	skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+	skt->res_io.name = "io";
+	skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+	skt->res_mem.start = _PCMCIAMem(skt->nr);
+	skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+	skt->res_mem.name = "memory";
+	skt->res_mem.flags = IORESOURCE_MEM;
+
+	skt->res_attr.start = _PCMCIAAttr(skt->nr);
+	skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+	skt->res_attr.name = "attribute";
+	skt->res_attr.flags = IORESOURCE_MEM;
+
+	return soc_pcmcia_add_one(skt);
+}
+EXPORT_SYMBOL(pxa2xx_drv_pcmcia_add_one);
+
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
+	/* Provide our PXA2xx specific timing routines. */
+	ops->set_timing  = pxa2xx_pcmcia_set_timing;
+#ifdef CONFIG_CPU_FREQ
+	ops->frequency_change = pxa2xx_pcmcia_frequency_change;
+#endif
+}
+EXPORT_SYMBOL(pxa2xx_drv_pcmcia_ops);
+
+static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
+{
+	int i, ret = 0;
 	struct pcmcia_low_level *ops;
 	struct skt_dev_info *sinfo;
 	struct soc_pcmcia_socket *skt;
 
-	if (!dev || !dev->platform_data)
+	ops = (struct pcmcia_low_level *)dev->dev.platform_data;
+	if (!ops)
 		return -ENODEV;
 
-	ops = (struct pcmcia_low_level *)dev->platform_data;
+	pxa2xx_drv_pcmcia_ops(ops);
 
 	sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
 	if (!sinfo)
@@ -250,54 +288,41 @@ int __pxa2xx_drv_pcmcia_probe(struct dev
 	for (i = 0; i < ops->nr; i++) {
 		skt = &sinfo->skt[i];
 
-		skt->nr		= ops->first + i;
-		skt->irq	= NO_IRQ;
-
-		skt->res_skt.start	= _PCMCIA(skt->nr);
-		skt->res_skt.end	= _PCMCIA(skt->nr) + PCMCIASp - 1;
-		skt->res_skt.name	= skt_names[skt->nr];
-		skt->res_skt.flags	= IORESOURCE_MEM;
-
-		skt->res_io.start	= _PCMCIAIO(skt->nr);
-		skt->res_io.end		= _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
-		skt->res_io.name	= "io";
-		skt->res_io.flags	= IORESOURCE_MEM | IORESOURCE_BUSY;
-
-		skt->res_mem.start	= _PCMCIAMem(skt->nr);
-		skt->res_mem.end	= _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
-		skt->res_mem.name	= "memory";
-		skt->res_mem.flags	= IORESOURCE_MEM;
+		skt->nr = ops->first + i;
+		skt->ops = ops;
+		skt->socket.owner = ops->owner;
+		skt->socket.dev.parent = &dev->dev;
+		skt->socket.pci_irq = NO_IRQ;
 
-		skt->res_attr.start	= _PCMCIAAttr(skt->nr);
-		skt->res_attr.end	= _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
-		skt->res_attr.name	= "attribute";
-		skt->res_attr.flags	= IORESOURCE_MEM;
+		ret = pxa2xx_drv_pcmcia_add_one(skt);
+		if (ret)
+			break;
 	}
 
-	/* Provide our PXA2xx specific timing routines. */
-	ops->set_timing  = pxa2xx_pcmcia_set_timing;
-#ifdef CONFIG_CPU_FREQ
-	ops->frequency_change = pxa2xx_pcmcia_frequency_change;
-#endif
-
-	ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
-
-	if (!ret)
-		pxa2xx_configure_sockets(dev);
+	if (ret) {
+		while (--i >= 0)
+			soc_pcmcia_remove_one(&sinfo->skt[i]);
+		kfree(sinfo);
+	} else {
+		pxa2xx_configure_sockets(&dev->dev);
+		dev_set_drvdata(&dev->dev, sinfo);
+	}
 
 	return ret;
 }
-EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe);
-
-
-static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
-{
-	return __pxa2xx_drv_pcmcia_probe(&dev->dev);
-}
 
 static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
 {
-	return soc_common_drv_pcmcia_remove(&dev->dev);
+	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+	int i;
+
+	platform_set_drvdata(dev, NULL);
+
+	for (i = 0; i < sinfo->nskt; i++)
+		soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+	kfree(sinfo);
+	return 0;
 }
 
 static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
@@ -311,7 +336,7 @@ static int pxa2xx_drv_pcmcia_resume(stru
 	return pcmcia_socket_dev_resume(dev);
 }
 
-static struct dev_pm_ops  pxa2xx_drv_pcmcia_pm_ops = {
+static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
 	.suspend	= pxa2xx_drv_pcmcia_suspend,
 	.resume		= pxa2xx_drv_pcmcia_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_base.h linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,3 +1,3 @@
-/* temporary measure */
-extern int __pxa2xx_drv_pcmcia_probe(struct device *);
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@ static int cmx255_pcmcia_hw_init(struct
 		return ret;
 	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-	skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+	skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
 	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	if (!ret)
 		gpio_free(GPIO_PCMCIA_RESET);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,7 @@ static int cmx270_pcmcia_hw_init(struct
 		return ret;
 	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-	skt->irq = PCMCIA_S0_RDYINT;
+	skt->socket.pci_irq = PCMCIA_S0_RDYINT;
 	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	if (!ret)
 		gpio_free(GPIO_PCMCIA_RESET);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_e740.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_e740.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_e740.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_e740.c	2010-02-24 13:52:17.000000000 -0500
@@ -38,7 +38,7 @@ static struct pcmcia_irqs cd_irqs[] = {
 
 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
+	skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
 				IRQ_GPIO(GPIO_E740_PCMCIA_RDY1);
 
 	return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_lubbock.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_lubbock.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_lubbock.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_lubbock.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,6 +32,7 @@ static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 				const socket_state_t *state)
 {
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
 	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
 	int ret = 0;
 
@@ -149,7 +150,7 @@ lubbock_pcmcia_configure_socket(struct s
 
 	if (ret == 0) {
 		lubbock_set_misc_wr(misc_mask, misc_set);
-		sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
 	}
 
 #if 1
@@ -175,7 +176,7 @@ lubbock_pcmcia_configure_socket(struct s
 			 * Switch to 5V,  Configure socket with 5V voltage
 			 */
 			lubbock_set_misc_wr(misc_mask, 0);
-			sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0);
+			sa1111_set_io(s->dev, pa_dwr_mask, 0);
 
 			/*
 			 * It takes about 100ms to turn off Vcc.
@@ -200,12 +201,8 @@ lubbock_pcmcia_configure_socket(struct s
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
 	.owner			= THIS_MODULE,
-	.hw_init		= sa1111_pcmcia_hw_init,
-	.hw_shutdown		= sa1111_pcmcia_hw_shutdown,
-	.socket_state		= sa1111_pcmcia_socket_state,
 	.configure_socket	= lubbock_pcmcia_configure_socket,
 	.socket_init		= sa1111_pcmcia_socket_init,
-	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 	.first			= 0,
 	.nr			= 2,
 };
@@ -228,8 +225,9 @@ int pcmcia_lubbock_init(struct sa1111_de
 		/* Set CF Socket 1 power to standby mode. */
 		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
 
-		sadev->dev.platform_data = &lubbock_pcmcia_ops;
-		ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
+		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
+		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
+				pxa2xx_drv_pcmcia_add_one);
 	}
 
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_mainstone.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_mainstone.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_mainstone.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_mainstone.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,7 @@ static int mst_pcmcia_hw_init(struct soc
 	 * before we enable them as outputs.
 	 */
 
-	skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
+	skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmld.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmld.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmld.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmld.c	2010-02-24 13:52:17.000000000 -0500
@@ -45,7 +45,7 @@ static int palmld_pcmcia_hw_init(struct
 	if (ret)
 		goto err4;
 
-	skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
+	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
 	return 0;
 
 err4:
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmtc.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmtc.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmtc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmtc.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,7 +67,7 @@ static int palmtc_pcmcia_hw_init(struct
 	if (ret)
 		goto err7;
 
-	skt->irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
+	skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
 	return 0;
 
 err7:
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmtx.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmtx.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_palmtx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_palmtx.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,7 @@ static int palmtx_pcmcia_hw_init(struct
 	if (ret)
 		goto err5;
 
-	skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
+	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
 	return 0;
 
 err5:
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,7 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct
 		}
 	}
 
-	skt->irq = SCOOP_DEV[skt->nr].irq;
+	skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_stargate2.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_stargate2.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_stargate2.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_stargate2.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,7 +40,7 @@ static struct pcmcia_irqs irqs[] = {
 
 static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->irq = IRQ_GPIO(SG2_S0_GPIO_READY);
+	skt->socket.pci_irq = IRQ_GPIO(SG2_S0_GPIO_READY);
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,7 @@ static int trizeps_pcmcia_hw_init(struct
 			gpio_free(GPIO_PRDY);
 			return -EINVAL;
 		}
-		skt->irq = IRQ_GPIO(GPIO_PRDY);
+		skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY);
 		break;
 
 #ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -63,7 +63,7 @@ static int trizeps_pcmcia_hw_init(struct
 		break;
 	}
 	/* release the reset of this card */
-	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
+	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
 
 	/* supplementory irqs for the socket */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_viper.c linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_viper.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/pxa2xx_viper.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/pxa2xx_viper.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,8 @@
 /*
- * VIPER PCMCIA support
+ * Viper/Zeus PCMCIA support
  *   Copyright 2004 Arcom Control Systems
  *
  * Maintained by Marc Zyngier <maz@misterjones.org>
- * 			      <marc.zyngier@altran.com>
  *
  * Based on:
  *   iPAQ h2200 PCMCIA support
@@ -26,37 +25,47 @@
 
 #include <asm/irq.h>
 
-#include <mach/viper.h>
-#include <asm/mach-types.h>
+#include <mach/arcom-pcmcia.h>
 
 #include "soc_common.h"
 #include "pxa2xx_base.h"
 
+static struct platform_device *arcom_pcmcia_dev;
+
 static struct pcmcia_irqs irqs[] = {
-	{ 0, gpio_to_irq(VIPER_CF_CD_GPIO),  "PCMCIA_CD" }
+	{
+		.sock	= 0,
+		.str	= "PCMCIA_CD",
+	},
 };
 
+static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
+{
+	return arcom_pcmcia_dev->dev.platform_data;
+}
+
 static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
+	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
 	unsigned long flags;
 
-	skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
+	skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio);
+	irqs[0].irq = gpio_to_irq(pdata->cd_gpio);
 
-	if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
+	if (gpio_request(pdata->cd_gpio, "CF detect"))
 		goto err_request_cd;
 
-	if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
+	if (gpio_request(pdata->rdy_gpio, "CF ready"))
 		goto err_request_rdy;
 
-	if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
+	if (gpio_request(pdata->pwr_gpio, "CF power"))
 		goto err_request_pwr;
 
 	local_irq_save(flags);
 
-	/* GPIO 82 is the CF power enable line. initially off */
-	if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
-	    gpio_direction_input(VIPER_CF_CD_GPIO) ||
-	    gpio_direction_input(VIPER_CF_RDY_GPIO)) {
+	if (gpio_direction_output(pdata->pwr_gpio, 0) ||
+	    gpio_direction_input(pdata->cd_gpio) ||
+	    gpio_direction_input(pdata->rdy_gpio)) {
 		local_irq_restore(flags);
 		goto err_dir;
 	}
@@ -66,13 +75,13 @@ static int viper_pcmcia_hw_init(struct s
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 
 err_dir:
-	gpio_free(VIPER_CF_POWER_GPIO);
+	gpio_free(pdata->pwr_gpio);
 err_request_pwr:
-	gpio_free(VIPER_CF_RDY_GPIO);
+	gpio_free(pdata->rdy_gpio);
 err_request_rdy:
-	gpio_free(VIPER_CF_CD_GPIO);
+	gpio_free(pdata->cd_gpio);
 err_request_cd:
-	printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
+	dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
 	return -1;
 }
 
@@ -81,17 +90,21 @@ err_request_cd:
  */
 static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
+	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
+
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-	gpio_free(VIPER_CF_POWER_GPIO);
-	gpio_free(VIPER_CF_RDY_GPIO);
-	gpio_free(VIPER_CF_CD_GPIO);
+	gpio_free(pdata->pwr_gpio);
+	gpio_free(pdata->rdy_gpio);
+	gpio_free(pdata->cd_gpio);
 }
 
 static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				      struct pcmcia_state *state)
 {
-	state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
-	state->ready  = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
+	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
+
+	state->detect = !gpio_get_value(pdata->cd_gpio);
+	state->ready  = !!gpio_get_value(pdata->rdy_gpio);
 	state->bvd1   = 1;
 	state->bvd2   = 1;
 	state->wrprot = 0;
@@ -102,20 +115,21 @@ static void viper_pcmcia_socket_state(st
 static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 					 const socket_state_t *state)
 {
+	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
+
 	/* Silently ignore Vpp, output enable, speaker enable. */
-	viper_cf_rst(state->flags & SS_RESET);
+	pdata->reset(state->flags & SS_RESET);
 
 	/* Apply socket voltage */
 	switch (state->Vcc) {
 	case 0:
-		gpio_set_value(VIPER_CF_POWER_GPIO, 0);
+		gpio_set_value(pdata->pwr_gpio, 0);
 		break;
 	case 33:
-		gpio_set_value(VIPER_CF_POWER_GPIO, 1);
+		gpio_set_value(pdata->pwr_gpio, 1);
 		break;
 	default:
-		printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
-		       __func__, state->Vcc);
+		dev_err(&arcom_pcmcia_dev->dev, "Unsupported Vcc:%d\n", state->Vcc);
 		return -1;
 	}
 
@@ -130,7 +144,7 @@ static void viper_pcmcia_socket_suspend(
 {
 }
 
-static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
+static struct pcmcia_low_level viper_pcmcia_ops = {
 	.owner          	= THIS_MODULE,
 	.hw_init        	= viper_pcmcia_hw_init,
 	.hw_shutdown		= viper_pcmcia_hw_shutdown,
@@ -143,17 +157,25 @@ static struct pcmcia_low_level viper_pcm
 
 static struct platform_device *viper_pcmcia_device;
 
-static int __init viper_pcmcia_init(void)
+static int viper_pcmcia_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	if (!machine_is_viper())
-		return -ENODEV;
+	/* I can't imagine more than one device, but you never know... */
+	if (arcom_pcmcia_dev)
+		return -EEXIST;
+
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
 
 	viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 	if (!viper_pcmcia_device)
 		return -ENOMEM;
 
+	arcom_pcmcia_dev = pdev;
+
+	viper_pcmcia_device->dev.parent = &pdev->dev;
+
 	ret = platform_device_add_data(viper_pcmcia_device,
 				       &viper_pcmcia_ops,
 				       sizeof(viper_pcmcia_ops));
@@ -161,18 +183,49 @@ static int __init viper_pcmcia_init(void
 	if (!ret)
 		ret = platform_device_add(viper_pcmcia_device);
 
-	if (ret)
+	if (ret) {
 		platform_device_put(viper_pcmcia_device);
+		arcom_pcmcia_dev = NULL;
+	}
 
 	return ret;
 }
 
-static void __exit viper_pcmcia_exit(void)
+static int viper_pcmcia_remove(struct platform_device *pdev)
 {
 	platform_device_unregister(viper_pcmcia_device);
+	arcom_pcmcia_dev = NULL;
+	return 0;
+}
+
+static struct platform_device_id viper_pcmcia_id_table[] = {
+	{ .name = "viper-pcmcia", },
+	{ .name = "zeus-pcmcia",  },
+	{ },
+};
+
+static struct platform_driver viper_pcmcia_driver = {
+	.probe		= viper_pcmcia_probe,
+	.remove		= viper_pcmcia_remove,
+	.driver		= {
+		.name	= "arcom-pcmcia",
+		.owner	= THIS_MODULE,
+	},
+	.id_table	= viper_pcmcia_id_table,
+};
+
+static int __init viper_pcmcia_init(void)
+{
+	return platform_driver_register(&viper_pcmcia_driver);
+}
+
+static void __exit viper_pcmcia_exit(void)
+{
+	return platform_driver_unregister(&viper_pcmcia_driver);
 }
 
 module_init(viper_pcmcia_init);
 module_exit(viper_pcmcia_exit);
 
+MODULE_DEVICE_TABLE(platform, viper_pcmcia_id_table);
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/rsrc_mgr.c linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_mgr.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/rsrc_mgr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_mgr.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,6 +18,7 @@
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 
 
@@ -125,16 +126,16 @@ static void pcmcia_align(void *align_dat
 	res->start = start;
 
 #ifdef CONFIG_X86
-        if (res->flags & IORESOURCE_IO) {
-                if (start & 0x300) {
-                        start = (start + 0x3ff) & ~0x3ff;
-                        res->start = start;
-                }
-        }
+	if (res->flags & IORESOURCE_IO) {
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
 #endif
 
 #ifdef CONFIG_M68K
-        if (res->flags & IORESOURCE_IO) {
+	if (res->flags & IORESOURCE_IO) {
 		if ((res->start + size - 1) >= 1024)
 			res->start = res->end;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/rsrc_nonstatic.c linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_nonstatic.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/rsrc_nonstatic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/rsrc_nonstatic.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,9 +24,9 @@
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -144,43 +144,44 @@ static int add_interval(struct resource_
 
 static int sub_interval(struct resource_map *map, u_long base, u_long num)
 {
-    struct resource_map *p, *q;
+	struct resource_map *p, *q;
 
-    for (p = map; ; p = q) {
-	q = p->next;
-	if (q == map)
-	    break;
-	if ((q->base+q->num > base) && (base+num > q->base)) {
-	    if (q->base >= base) {
-		if (q->base+q->num <= base+num) {
-		    /* Delete whole block */
-		    p->next = q->next;
-		    kfree(q);
-		    /* don't advance the pointer yet */
-		    q = p;
-		} else {
-		    /* Cut off bit from the front */
-		    q->num = q->base + q->num - base - num;
-		    q->base = base + num;
-		}
-	    } else if (q->base+q->num <= base+num) {
-		/* Cut off bit from the end */
-		q->num = base - q->base;
-	    } else {
-		/* Split the block into two pieces */
-		p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
-		if (!p) {
-		    printk(KERN_WARNING "out of memory to update resources\n");
-		    return -ENOMEM;
+	for (p = map; ; p = q) {
+		q = p->next;
+		if (q == map)
+			break;
+		if ((q->base+q->num > base) && (base+num > q->base)) {
+			if (q->base >= base) {
+				if (q->base+q->num <= base+num) {
+					/* Delete whole block */
+					p->next = q->next;
+					kfree(q);
+					/* don't advance the pointer yet */
+					q = p;
+				} else {
+					/* Cut off bit from the front */
+					q->num = q->base + q->num - base - num;
+					q->base = base + num;
+				}
+			} else if (q->base+q->num <= base+num) {
+				/* Cut off bit from the end */
+				q->num = base - q->base;
+			} else {
+				/* Split the block into two pieces */
+				p = kmalloc(sizeof(struct resource_map),
+					GFP_KERNEL);
+				if (!p) {
+					printk(KERN_WARNING "out of memory to update resources\n");
+					return -ENOMEM;
+				}
+				p->base = base+num;
+				p->num = q->base+q->num - p->base;
+				q->num = base - q->base;
+				p->next = q->next ; q->next = p;
+			}
 		}
-		p->base = base+num;
-		p->num = q->base+q->num - p->base;
-		q->num = base - q->base;
-		p->next = q->next ; q->next = p;
-	    }
 	}
-    }
-    return 0;
+	return 0;
 }
 
 /*======================================================================
@@ -194,69 +195,72 @@ static int sub_interval(struct resource_
 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
 			unsigned int num)
 {
-    struct resource *res;
-    struct socket_data *s_data = s->resource_data;
-    unsigned int i, j, bad;
-    int any;
-    u_char *b, hole, most;
+	struct resource *res;
+	struct socket_data *s_data = s->resource_data;
+	unsigned int i, j, bad;
+	int any;
+	u_char *b, hole, most;
 
-    dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
-	       base, base+num-1);
+	dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
+		base, base+num-1);
 
-    /* First, what does a floating port look like? */
-    b = kzalloc(256, GFP_KERNEL);
-    if (!b) {
-	    printk("\n");
-	    dev_printk(KERN_ERR, &s->dev,
-		   "do_io_probe: unable to kmalloc 256 bytes");
-            return;
-    }
-    for (i = base, most = 0; i < base+num; i += 8) {
-	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
-	if (!res)
-	    continue;
-	hole = inb(i);
-	for (j = 1; j < 8; j++)
-	    if (inb(i+j) != hole) break;
-	free_region(res);
-	if ((j == 8) && (++b[hole] > b[most]))
-	    most = hole;
-	if (b[most] == 127) break;
-    }
-    kfree(b);
+	/* First, what does a floating port look like? */
+	b = kzalloc(256, GFP_KERNEL);
+	if (!b) {
+		printk("\n");
+		dev_printk(KERN_ERR, &s->dev,
+			"do_io_probe: unable to kmalloc 256 bytes");
+		return;
+	}
+	for (i = base, most = 0; i < base+num; i += 8) {
+		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+		if (!res)
+			continue;
+		hole = inb(i);
+		for (j = 1; j < 8; j++)
+			if (inb(i+j) != hole)
+				break;
+		free_region(res);
+		if ((j == 8) && (++b[hole] > b[most]))
+			most = hole;
+		if (b[most] == 127)
+			break;
+	}
+	kfree(b);
 
-    bad = any = 0;
-    for (i = base; i < base+num; i += 8) {
-	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
-	if (!res)
-	    continue;
-	for (j = 0; j < 8; j++)
-	    if (inb(i+j) != most) break;
-	free_region(res);
-	if (j < 8) {
-	    if (!any)
-		printk(" excluding");
-	    if (!bad)
-		bad = any = i;
-	} else {
-	    if (bad) {
-		sub_interval(&s_data->io_db, bad, i-bad);
-		printk(" %#x-%#x", bad, i-1);
-		bad = 0;
-	    }
+	bad = any = 0;
+	for (i = base; i < base+num; i += 8) {
+		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+		if (!res)
+			continue;
+		for (j = 0; j < 8; j++)
+			if (inb(i+j) != most)
+				break;
+		free_region(res);
+		if (j < 8) {
+			if (!any)
+				printk(" excluding");
+			if (!bad)
+				bad = any = i;
+		} else {
+			if (bad) {
+				sub_interval(&s_data->io_db, bad, i-bad);
+				printk(" %#x-%#x", bad, i-1);
+				bad = 0;
+			}
+		}
 	}
-    }
-    if (bad) {
-	if ((num > 16) && (bad == base) && (i == base+num)) {
-	    printk(" nothing: probe failed.\n");
-	    return;
-	} else {
-	    sub_interval(&s_data->io_db, bad, i-bad);
-	    printk(" %#x-%#x", bad, i-1);
+	if (bad) {
+		if ((num > 16) && (bad == base) && (i == base+num)) {
+			printk(" nothing: probe failed.\n");
+			return;
+		} else {
+			sub_interval(&s_data->io_db, bad, i-bad);
+			printk(" %#x-%#x", bad, i-1);
+		}
 	}
-    }
 
-    printk(any ? "\n" : " clean.\n");
+	printk(any ? "\n" : " clean.\n");
 }
 #endif
 
@@ -327,8 +331,9 @@ cis_readable(struct pcmcia_socket *s, un
 	unsigned int info1, info2;
 	int ret = 0;
 
-	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
-	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
+	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
+	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
+			"PCMCIA memprobe");
 
 	if (res1 && res2) {
 		ret = readable(s, res1, &info1);
@@ -347,8 +352,9 @@ checksum_match(struct pcmcia_socket *s,
 	struct resource *res1, *res2;
 	int a = -1, b = -1;
 
-	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
-	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
+	res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
+	res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
+			"PCMCIA memprobe");
 
 	if (res1 && res2) {
 		a = checksum(s, res1);
@@ -371,42 +377,43 @@ checksum_match(struct pcmcia_socket *s,
 
 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
 {
-    struct socket_data *s_data = s->resource_data;
-    u_long i, j, bad, fail, step;
+	struct socket_data *s_data = s->resource_data;
+	u_long i, j, bad, fail, step;
 
-    dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
-	       base, base+num-1);
-    bad = fail = 0;
-    step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
-    /* don't allow too large steps */
-    if (step > 0x800000)
-	step = 0x800000;
-    /* cis_readable wants to map 2x map_size */
-    if (step < 2 * s->map_size)
-	step = 2 * s->map_size;
-    for (i = j = base; i < base+num; i = j + step) {
-	if (!fail) {
-	    for (j = i; j < base+num; j += step) {
-		if (cis_readable(s, j, step))
-		    break;
-	    }
-	    fail = ((i == base) && (j == base+num));
-	}
-	if (fail) {
-	    for (j = i; j < base+num; j += 2*step)
-		if (checksum_match(s, j, step) &&
-		    checksum_match(s, j + step, step))
-		    break;
-	}
-	if (i != j) {
-	    if (!bad) printk(" excluding");
-	    printk(" %#05lx-%#05lx", i, j-1);
-	    sub_interval(&s_data->mem_db, i, j-i);
-	    bad += j-i;
+	dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
+		base, base+num-1);
+	bad = fail = 0;
+	step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
+	/* don't allow too large steps */
+	if (step > 0x800000)
+		step = 0x800000;
+	/* cis_readable wants to map 2x map_size */
+	if (step < 2 * s->map_size)
+		step = 2 * s->map_size;
+	for (i = j = base; i < base+num; i = j + step) {
+		if (!fail) {
+			for (j = i; j < base+num; j += step) {
+				if (cis_readable(s, j, step))
+					break;
+			}
+			fail = ((i == base) && (j == base+num));
+		}
+		if (fail) {
+			for (j = i; j < base+num; j += 2*step)
+				if (checksum_match(s, j, step) &&
+					checksum_match(s, j + step, step))
+					break;
+		}
+		if (i != j) {
+			if (!bad)
+				printk(" excluding");
+			printk(" %#05lx-%#05lx", i, j-1);
+			sub_interval(&s_data->mem_db, i, j-i);
+			bad += j-i;
+		}
 	}
-    }
-    printk(bad ? "\n" : " clean.\n");
-    return (num - bad);
+	printk(bad ? "\n" : " clean.\n");
+	return num - bad;
 }
 
 #ifdef CONFIG_PCMCIA_PROBE
@@ -656,7 +663,7 @@ static struct resource *nonstatic_find_i
 	return res;
 }
 
-static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
+static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 		u_long align, int low, struct pcmcia_socket *s)
 {
 	struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
@@ -794,7 +801,7 @@ static int nonstatic_autoadd_resources(s
 		return -EINVAL;
 #endif
 
-	for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
+	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		res = s->cb_dev->bus->resource[i];
 		if (!res)
 			continue;
@@ -908,14 +915,14 @@ static ssize_t show_io_db(struct device
 	for (p = data->io_db.next; p != &data->io_db; p = p->next) {
 		if (ret > (PAGE_SIZE - 10))
 			continue;
-		ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
-				 "0x%08lx - 0x%08lx\n",
-				 ((unsigned long) p->base),
-				 ((unsigned long) p->base + p->num - 1));
+		ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
+				"0x%08lx - 0x%08lx\n",
+				((unsigned long) p->base),
+				((unsigned long) p->base + p->num - 1));
 	}
 
 	mutex_unlock(&rsrc_mutex);
-	return (ret);
+	return ret;
 }
 
 static ssize_t store_io_db(struct device *dev,
@@ -927,12 +934,13 @@ static ssize_t store_io_db(struct device
 	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
 
-	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
+	ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
 	if (ret != 2) {
-		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
+		ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
 		add = REMOVE_MANAGED_RESOURCE;
 		if (ret != 2) {
-			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
+			ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
+				&end_addr);
 			add = ADD_MANAGED_RESOURCE;
 			if (ret != 2)
 				return -EINVAL;
@@ -963,14 +971,14 @@ static ssize_t show_mem_db(struct device
 	for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
 		if (ret > (PAGE_SIZE - 10))
 			continue;
-		ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
-				 "0x%08lx - 0x%08lx\n",
-				 ((unsigned long) p->base),
-				 ((unsigned long) p->base + p->num - 1));
+		ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
+				"0x%08lx - 0x%08lx\n",
+				((unsigned long) p->base),
+				((unsigned long) p->base + p->num - 1));
 	}
 
 	mutex_unlock(&rsrc_mutex);
-	return (ret);
+	return ret;
 }
 
 static ssize_t store_mem_db(struct device *dev,
@@ -982,12 +990,13 @@ static ssize_t store_mem_db(struct devic
 	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
 
-	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
+	ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
 	if (ret != 2) {
-		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
+		ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
 		add = REMOVE_MANAGED_RESOURCE;
 		if (ret != 2) {
-			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
+			ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
+				&end_addr);
 			add = ADD_MANAGED_RESOURCE;
 			if (ret != 2)
 				return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_assabet.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_assabet.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_assabet.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_assabet.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
 
 static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->irq = ASSABET_IRQ_GPIO_CF_IRQ;
+	skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
 
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_badge4.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_badge4.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_badge4.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_badge4.c	2010-02-24 13:52:17.000000000 -0500
@@ -127,13 +127,10 @@ badge4_pcmcia_configure_socket(struct so
 
 static struct pcmcia_low_level badge4_pcmcia_ops = {
 	.owner			= THIS_MODULE,
-	.hw_init		= sa1111_pcmcia_hw_init,
-	.hw_shutdown		= sa1111_pcmcia_hw_shutdown,
-	.socket_state		= sa1111_pcmcia_socket_state,
 	.configure_socket	= badge4_pcmcia_configure_socket,
-
 	.socket_init		= sa1111_pcmcia_socket_init,
-	.socket_suspend		= sa1111_pcmcia_socket_suspend,
+	.first			= 0,
+	.nr			= 2,
 };
 
 int pcmcia_badge4_init(struct device *dev)
@@ -146,7 +143,9 @@ int pcmcia_badge4_init(struct device *de
 		       __func__,
 		       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
 
-		ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2);
+		sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
+		ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
 	}
 
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_cerf.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_cerf.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_cerf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_cerf.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
 
 static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->irq = CERF_IRQ_GPIO_CF_IRQ;
+	skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
 
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_generic.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_generic.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ static int (*sa11x0_pcmcia_hw_init[])(st
 #ifdef CONFIG_SA1100_CERF
 	pcmcia_cerf_init,
 #endif
-#ifdef CONFIG_SA1100_H3600
+#if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
 	pcmcia_h3600_init,
 #endif
 #ifdef CONFIG_SA1100_SHANNON
@@ -83,7 +83,16 @@ static int sa11x0_drv_pcmcia_probe(struc
 
 static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
 {
-	return soc_common_drv_pcmcia_remove(&dev->dev);
+	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+	int i;
+
+	platform_set_drvdata(dev, NULL);
+
+	for (i = 0; i < sinfo->nskt; i++)
+		soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+	kfree(sinfo);
+	return 0;
 }
 
 static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_h3600.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_h3600.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_h3600.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_h3600.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,47 +10,139 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <mach/h3600.h>
+#include <mach/h3xxx.h>
 
 #include "sa1100_generic.h"
 
 static struct pcmcia_irqs irqs[] = {
-	{ 0, IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" },
-	{ 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
+	{ .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
+	{ .sock = 1, .str = "PCMCIA CD1" }
 };
 
 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
-			   : IRQ_GPIO_H3600_PCMCIA_IRQ0;
+	int err;
 
+	switch (skt->nr) {
+	case 0:
+		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0");
+		if (err)
+			goto err00;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0);
+		if (err)
+			goto err01;
+		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
 
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+		err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
+		if (err)
+			goto err01;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
+		if (err)
+			goto err02;
+		irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
+
+		err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
+		if (err)
+			goto err02;
+		err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
+		if (err)
+			goto err03;
+		err = gpio_request(H3XXX_EGPIO_OPT_ON, "OPT ON");
+		if (err)
+			goto err03;
+		err = gpio_direction_output(H3XXX_EGPIO_OPT_ON, 0);
+		if (err)
+			goto err04;
+		err = gpio_request(H3XXX_EGPIO_OPT_RESET, "OPT RESET");
+		if (err)
+			goto err04;
+		err = gpio_direction_output(H3XXX_EGPIO_OPT_RESET, 0);
+		if (err)
+			goto err05;
+		err = gpio_request(H3XXX_EGPIO_CARD_RESET, "PCMCIA CARD RESET");
+		if (err)
+			goto err05;
+		err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
+		if (err)
+			goto err06;
+		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+		if (err)
+			goto err06;
+		break;
+	case 1:
+		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
+		if (err)
+			goto err10;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
+		if (err)
+			goto err11;
+		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
+
+		err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
+		if (err)
+			goto err11;
+		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
+		if (err)
+			goto err12;
+		irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
+
+		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+		if (err)
+			goto err12;
+		break;
+	}
+	return 0;
+
+err06:	gpio_free(H3XXX_EGPIO_CARD_RESET);
+err05:	gpio_free(H3XXX_EGPIO_OPT_RESET);
+err04:	gpio_free(H3XXX_EGPIO_OPT_ON);
+err03:	gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
+err02:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err01:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err00:	return err;
+
+err12:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err11:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err10:	return err;
 }
 
 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
   
-	/* Disable CF bus: */
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
+	switch (skt->nr) {
+	case 0:
+		/* Disable CF bus: */
+		gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
+		gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
+		gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
+
+		gpio_free(H3XXX_EGPIO_CARD_RESET);
+		gpio_free(H3XXX_EGPIO_OPT_RESET);
+		gpio_free(H3XXX_EGPIO_OPT_ON);
+		gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
+		gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+		gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+		break;
+	case 1:
+		gpio_free(H3XXX_GPIO_PCMCIA_CD1);
+		gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
+		break;
+	}
 }
 
 static void
 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
-
 	switch (skt->nr) {
 	case 0:
-		state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
-		state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
+		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
 		state->bvd1 = 0;
 		state->bvd2 = 0;
 		state->wrprot = 0; /* Not available on H3600. */
@@ -59,8 +151,8 @@ h3600_pcmcia_socket_state(struct soc_pcm
 		break;
 
 	case 1:
-		state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
-		state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
+		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
 		state->bvd1 = 0;
 		state->bvd2 = 0;
 		state->wrprot = 0; /* Not available on H3600. */
@@ -79,7 +171,7 @@ h3600_pcmcia_configure_socket(struct soc
 		return -1;
 	}
 
-	assign_h3600_egpio(IPAQ_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
+	gpio_set_value(H3XXX_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
 
 	/* Silently ignore Vpp, output enable, speaker enable. */
 
@@ -89,9 +181,9 @@ h3600_pcmcia_configure_socket(struct soc
 static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 {
 	/* Enable CF bus: */
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 1);
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 1);
-	assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 0);
+	gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 1);
+	gpio_set_value(H3XXX_EGPIO_OPT_ON, 1);
+	gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
 
 	msleep(10);
 
@@ -109,10 +201,10 @@ static void h3600_pcmcia_socket_suspend(
 	 * socket 0 then socket 1.
 	 */
 	if (skt->nr == 1) {
-		assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
-		assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
+		gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
+		gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
 		/* hmm, does this suck power? */
-		assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
+		gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
 	}
 }
 
@@ -131,7 +223,7 @@ int __init pcmcia_h3600_init(struct devi
 {
 	int ret = -ENODEV;
 
-	if (machine_is_h3600())
+	if (machine_is_h3600() || machine_is_h3100())
 		ret = sa11xx_drv_pcmcia_probe(dev, &h3600_pcmcia_ops, 0, 2);
 
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_jornada720.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_jornada720.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_jornada720.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_jornada720.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,25 +22,10 @@
 #define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
 #define SOCKET1_3V	GPIO_GPIO3
 
-static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-	/*
-	* What is all this crap for?
-	*/
-	GRER |= 0x00000002;
-	/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-	sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0);
-	sa1111_set_io(SA1111_DEV(skt->dev), pin, 0);
-	sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0);
-
-	return sa1111_pcmcia_hw_init(skt);
-}
-
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
 	unsigned int pa_dwr_mask, pa_dwr_set;
 	int ret;
 
@@ -97,7 +82,7 @@ jornada720_pcmcia_configure_socket(struc
 		unsigned long flags;
 
 		local_irq_save(flags);
-		sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
 		local_irq_restore(flags);
 	}
 
@@ -106,21 +91,30 @@ jornada720_pcmcia_configure_socket(struc
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
 	.owner			= THIS_MODULE,
-	.hw_init		= jornada720_pcmcia_hw_init,
-	.hw_shutdown		= sa1111_pcmcia_hw_shutdown,
-	.socket_state		= sa1111_pcmcia_socket_state,
 	.configure_socket	= jornada720_pcmcia_configure_socket,
-
 	.socket_init		= sa1111_pcmcia_socket_init,
-	.socket_suspend		= sa1111_pcmcia_socket_suspend,
+	.first			= 0,
+	.nr			= 2,
 };
 
 int __devinit pcmcia_jornada720_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
-	if (machine_is_jornada720())
-		ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2);
+	if (machine_is_jornada720()) {
+		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+		GRER |= 0x00000002;
+
+		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+		sa1111_set_io_dir(dev, pin, 0, 0);
+		sa1111_set_io(dev, pin, 0);
+		sa1111_set_sleep_io(dev, pin, 0);
+
+		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
+		ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
+	}
 
 	return ret;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_neponset.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_neponset.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_neponset.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_neponset.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,6 +43,7 @@
 static int
 neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
 	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
 	int ret;
 
@@ -99,7 +100,7 @@ neponset_pcmcia_configure_socket(struct
 		NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
 
 		local_irq_restore(flags);
-		sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
 	}
 
 	return 0;
@@ -115,12 +116,10 @@ static void neponset_pcmcia_socket_init(
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
 	.owner			= THIS_MODULE,
-	.hw_init		= sa1111_pcmcia_hw_init,
-	.hw_shutdown		= sa1111_pcmcia_hw_shutdown,
-	.socket_state		= sa1111_pcmcia_socket_state,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 	.socket_init		= neponset_pcmcia_socket_init,
-	.socket_suspend 	= sa1111_pcmcia_socket_suspend,
+	.first			= 0,
+	.nr			= 2,
 };
 
 int pcmcia_neponset_init(struct sa1111_dev *sadev)
@@ -135,7 +134,9 @@ int pcmcia_neponset_init(struct sa1111_d
 		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
 		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
 		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2);
+		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
+		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
 	}
 
 	return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_shannon.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_shannon.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_shannon.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_shannon.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ static int shannon_pcmcia_hw_init(struct
 	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
 		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
 
-	skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
+	skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
 
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_simpad.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_simpad.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1100_simpad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1100_simpad.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@ static int simpad_pcmcia_hw_init(struct
 
 	clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-	skt->irq = IRQ_GPIO_CF_IRQ;
+	skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
 
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1111_generic.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1111_generic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,23 +28,20 @@ static struct pcmcia_irqs irqs[] = {
 	{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1"            },
 };
 
-int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	if (skt->irq == NO_IRQ)
-		skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
-
 	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
-void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
-	unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR);
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
 
 	switch (skt->nr) {
 	case 0:
@@ -71,7 +68,7 @@ void sa1111_pcmcia_socket_state(struct s
 
 int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-	struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
 	unsigned int pccr_skt_mask, pccr_set_mask, val;
 	unsigned long flags;
 
@@ -100,10 +97,10 @@ int sa1111_pcmcia_configure_socket(struc
 		pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
 
 	local_irq_save(flags);
-	val = sa1111_readl(sadev->mapbase + SA1111_PCCR);
+	val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
 	val &= ~pccr_skt_mask;
 	val |= pccr_set_mask & pccr_skt_mask;
-	sa1111_writel(val, sadev->mapbase + SA1111_PCCR);
+	sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
 	local_irq_restore(flags);
 
 	return 0;
@@ -114,15 +111,51 @@ void sa1111_pcmcia_socket_init(struct so
 	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
-void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
 	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+	int (*add)(struct soc_pcmcia_socket *))
+{
+	struct sa1111_pcmcia_socket *s;
+	int i, ret = 0;
+
+	ops->hw_init = sa1111_pcmcia_hw_init;
+	ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
+	ops->socket_state = sa1111_pcmcia_socket_state;
+	ops->socket_suspend = sa1111_pcmcia_socket_suspend;
+
+	for (i = 0; i < ops->nr; i++) {
+		s = kzalloc(sizeof(*s), GFP_KERNEL);
+		if (!s)
+			return -ENOMEM;
+
+		s->soc.nr = ops->first + i;
+		s->soc.ops = ops;
+		s->soc.socket.owner = ops->owner;
+		s->soc.socket.dev.parent = &dev->dev;
+		s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
+		s->dev = dev;
+
+		ret = add(&s->soc);
+		if (ret == 0) {
+			s->next = dev_get_drvdata(&dev->dev);
+			dev_set_drvdata(&dev->dev, s);
+		} else
+			kfree(s);
+	}
+
+	return ret;
+}
+
 static int pcmcia_probe(struct sa1111_dev *dev)
 {
 	void __iomem *base;
 
+	dev_set_drvdata(&dev->dev, NULL);
+
 	if (!request_mem_region(dev->res.start, 512,
 				SA1111_DRIVER_NAME(dev)))
 		return -EBUSY;
@@ -152,7 +185,15 @@ static int pcmcia_probe(struct sa1111_de
 
 static int __devexit pcmcia_remove(struct sa1111_dev *dev)
 {
-	soc_common_drv_pcmcia_remove(&dev->dev);
+	struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
+
+	dev_set_drvdata(&dev->dev, NULL);
+
+	for (; next = s->next, s; s = next) {
+		soc_pcmcia_remove_one(&s->soc);
+		kfree(s);
+	}
+
 	release_mem_region(dev->res.start, 512);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1111_generic.h linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa1111_generic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa1111_generic.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,12 +1,23 @@
 #include "soc_common.h"
 #include "sa11xx_base.h"
 
-extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *);
+struct sa1111_pcmcia_socket {
+	struct soc_pcmcia_socket soc;
+	struct sa1111_dev *dev;
+	struct sa1111_pcmcia_socket *next;
+};
+
+static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
+{
+	return container_of(s, struct sa1111_pcmcia_socket, soc);
+}
+
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+	int (*add)(struct soc_pcmcia_socket *));
+
 extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
 extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
 extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *);
 
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_jornada720_init(struct device *);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa11xx_base.c linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa11xx_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -171,47 +171,34 @@ static const char *skt_names[] = {
 #define SKT_DEV_INFO_SIZE(n) \
 	(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 
-int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
-			    int first, int nr)
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 {
-	struct skt_dev_info *sinfo;
-	struct soc_pcmcia_socket *skt;
-	int i;
-
-	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
-	if (!sinfo)
-		return -ENOMEM;
-
-	sinfo->nskt = nr;
-
-	/* Initiliaze processor specific parameters */
-	for (i = 0; i < nr; i++) {
-		skt = &sinfo->skt[i];
-
-		skt->nr		= first + i;
-		skt->irq	= NO_IRQ;
+	skt->res_skt.start = _PCMCIA(skt->nr);
+	skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+	skt->res_skt.name = skt_names[skt->nr];
+	skt->res_skt.flags = IORESOURCE_MEM;
 
-		skt->res_skt.start	= _PCMCIA(skt->nr);
-		skt->res_skt.end	= _PCMCIA(skt->nr) + PCMCIASp - 1;
-		skt->res_skt.name	= skt_names[skt->nr];
-		skt->res_skt.flags	= IORESOURCE_MEM;
+	skt->res_io.start = _PCMCIAIO(skt->nr);
+	skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+	skt->res_io.name = "io";
+	skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 
-		skt->res_io.start	= _PCMCIAIO(skt->nr);
-		skt->res_io.end		= _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
-		skt->res_io.name	= "io";
-		skt->res_io.flags	= IORESOURCE_MEM | IORESOURCE_BUSY;
+	skt->res_mem.start = _PCMCIAMem(skt->nr);
+	skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+	skt->res_mem.name = "memory";
+	skt->res_mem.flags = IORESOURCE_MEM;
 
-		skt->res_mem.start	= _PCMCIAMem(skt->nr);
-		skt->res_mem.end	= _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
-		skt->res_mem.name	= "memory";
-		skt->res_mem.flags	= IORESOURCE_MEM;
+	skt->res_attr.start = _PCMCIAAttr(skt->nr);
+	skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+	skt->res_attr.name = "attribute";
+	skt->res_attr.flags = IORESOURCE_MEM;
 
-		skt->res_attr.start	= _PCMCIAAttr(skt->nr);
-		skt->res_attr.end	= _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
-		skt->res_attr.name	= "attribute";
-		skt->res_attr.flags	= IORESOURCE_MEM;
-	}
+	return soc_pcmcia_add_one(skt);
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
 
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
 	/*
 	 * set default MECR calculation if the board specific
 	 * code did not specify one...
@@ -225,8 +212,48 @@ int sa11xx_drv_pcmcia_probe(struct devic
 #ifdef CONFIG_CPU_FREQ
 	ops->frequency_change = sa1100_pcmcia_frequency_change;
 #endif
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
 
-	return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
+int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
+			    int first, int nr)
+{
+	struct skt_dev_info *sinfo;
+	struct soc_pcmcia_socket *skt;
+	int i, ret = 0;
+
+	sa11xx_drv_pcmcia_ops(ops);
+
+	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+	if (!sinfo)
+		return -ENOMEM;
+
+	sinfo->nskt = nr;
+
+	/* Initiliaze processor specific parameters */
+	for (i = 0; i < nr; i++) {
+		skt = &sinfo->skt[i];
+
+		skt->nr = first + i;
+		skt->ops = ops;
+		skt->socket.owner = ops->owner;
+		skt->socket.dev.parent = dev;
+		skt->socket.pci_irq = NO_IRQ;
+
+		ret = sa11xx_drv_pcmcia_add_one(skt);
+		if (ret)
+			break;
+	}
+
+	if (ret) {
+		while (--i >= 0)
+			soc_pcmcia_remove_one(&sinfo->skt[i]);
+		kfree(sinfo);
+	} else {
+		dev_set_drvdata(dev, sinfo);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/sa11xx_base.h linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/sa11xx_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/sa11xx_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -118,6 +118,8 @@ static inline unsigned int sa1100_pcmcia
 }
 
 
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
 extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
 
 #endif  /* !defined(_PCMCIA_SA1100_H) */
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/soc_common.c linux-libre-2.6.33-gnu1/drivers/pcmcia/soc_common.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/soc_common.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/soc_common.c	2010-02-24 13:52:17.000000000 -0500
@@ -144,10 +144,10 @@ soc_common_pcmcia_config_skt(struct soc_
 		 */
 		if (skt->irq_state != 1 && state->io_irq) {
 			skt->irq_state = 1;
-			set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING);
+			set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
 		} else if (skt->irq_state == 1 && state->io_irq == 0) {
 			skt->irq_state = 0;
-			set_irq_type(skt->irq, IRQ_TYPE_NONE);
+			set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
 		}
 
 		skt->cs_state = *state;
@@ -492,7 +492,8 @@ static ssize_t show_status(struct device
 
 	p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
 	p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
-	p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq, skt->irq);
+	p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
+		skt->socket.pci_irq);
 	if (skt->ops->show_timing)
 		p+=skt->ops->show_timing(skt, p);
 
@@ -574,7 +575,7 @@ void soc_pcmcia_enable_irqs(struct soc_p
 EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
 
 
-LIST_HEAD(soc_pcmcia_sockets);
+static LIST_HEAD(soc_pcmcia_sockets);
 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
 #ifdef CONFIG_CPU_FREQ
@@ -609,177 +610,137 @@ static int soc_pcmcia_cpufreq_register(v
 				"notifier for PCMCIA (%d)\n", ret);
 	return ret;
 }
+fs_initcall(soc_pcmcia_cpufreq_register);
 
 static void soc_pcmcia_cpufreq_unregister(void)
 {
 	cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 }
+module_exit(soc_pcmcia_cpufreq_unregister);
 
-#else
-static int soc_pcmcia_cpufreq_register(void) { return 0; }
-static void soc_pcmcia_cpufreq_unregister(void) {}
 #endif
 
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
-				struct skt_dev_info *sinfo)
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
-	struct soc_pcmcia_socket *skt;
-	int ret, i;
-
 	mutex_lock(&soc_pcmcia_sockets_lock);
+	del_timer_sync(&skt->poll_timer);
 
-	/*
-	 * Initialise the per-socket structure.
-	 */
-	for (i = 0; i < sinfo->nskt; i++) {
-		skt = &sinfo->skt[i];
+	pcmcia_unregister_socket(&skt->socket);
 
-		skt->socket.ops = &soc_common_pcmcia_operations;
-		skt->socket.owner = ops->owner;
-		skt->socket.dev.parent = dev;
+	flush_scheduled_work();
 
-		init_timer(&skt->poll_timer);
-		skt->poll_timer.function = soc_common_pcmcia_poll_event;
-		skt->poll_timer.data = (unsigned long)skt;
-		skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
+	skt->ops->hw_shutdown(skt);
 
-		skt->dev	= dev;
-		skt->ops	= ops;
+	soc_common_pcmcia_config_skt(skt, &dead_socket);
 
-		ret = request_resource(&iomem_resource, &skt->res_skt);
-		if (ret)
-			goto out_err_1;
+	list_del(&skt->node);
+	mutex_unlock(&soc_pcmcia_sockets_lock);
 
-		ret = request_resource(&skt->res_skt, &skt->res_io);
-		if (ret)
-			goto out_err_2;
+	iounmap(skt->virt_io);
+	skt->virt_io = NULL;
+	release_resource(&skt->res_attr);
+	release_resource(&skt->res_mem);
+	release_resource(&skt->res_io);
+	release_resource(&skt->res_skt);
+}
+EXPORT_SYMBOL(soc_pcmcia_remove_one);
 
-		ret = request_resource(&skt->res_skt, &skt->res_mem);
-		if (ret)
-			goto out_err_3;
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+	int ret;
 
-		ret = request_resource(&skt->res_skt, &skt->res_attr);
-		if (ret)
-			goto out_err_4;
+	init_timer(&skt->poll_timer);
+	skt->poll_timer.function = soc_common_pcmcia_poll_event;
+	skt->poll_timer.data = (unsigned long)skt;
+	skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
 
-		skt->virt_io = ioremap(skt->res_io.start, 0x10000);
-		if (skt->virt_io == NULL) {
-			ret = -ENOMEM;
-			goto out_err_5;
-		}
+	ret = request_resource(&iomem_resource, &skt->res_skt);
+	if (ret)
+		goto out_err_1;
 
-		if (list_empty(&soc_pcmcia_sockets))
-			soc_pcmcia_cpufreq_register();
+	ret = request_resource(&skt->res_skt, &skt->res_io);
+	if (ret)
+		goto out_err_2;
 
-		list_add(&skt->node, &soc_pcmcia_sockets);
+	ret = request_resource(&skt->res_skt, &skt->res_mem);
+	if (ret)
+		goto out_err_3;
 
-		/*
-		 * We initialize default socket timing here, because
-		 * we are not guaranteed to see a SetIOMap operation at
-		 * runtime.
-		 */
-		ops->set_timing(skt);
+	ret = request_resource(&skt->res_skt, &skt->res_attr);
+	if (ret)
+		goto out_err_4;
 
-		ret = ops->hw_init(skt);
-		if (ret)
-			goto out_err_6;
+	skt->virt_io = ioremap(skt->res_io.start, 0x10000);
+	if (skt->virt_io == NULL) {
+		ret = -ENOMEM;
+		goto out_err_5;
+	}
 
-		skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
-		skt->socket.resource_ops = &pccard_static_ops;
-		skt->socket.irq_mask = 0;
-		skt->socket.map_size = PAGE_SIZE;
-		skt->socket.pci_irq = skt->irq;
-		skt->socket.io_offset = (unsigned long)skt->virt_io;
+	mutex_lock(&soc_pcmcia_sockets_lock);
 
-		skt->status = soc_common_pcmcia_skt_state(skt);
+	list_add(&skt->node, &soc_pcmcia_sockets);
 
-		ret = pcmcia_register_socket(&skt->socket);
-		if (ret)
-			goto out_err_7;
+	/*
+	 * We initialize default socket timing here, because
+	 * we are not guaranteed to see a SetIOMap operation at
+	 * runtime.
+	 */
+	skt->ops->set_timing(skt);
 
-		WARN_ON(skt->socket.sock != i);
+	ret = skt->ops->hw_init(skt);
+	if (ret)
+		goto out_err_6;
 
-		add_timer(&skt->poll_timer);
+	skt->socket.ops = &soc_common_pcmcia_operations;
+	skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
+	skt->socket.resource_ops = &pccard_static_ops;
+	skt->socket.irq_mask = 0;
+	skt->socket.map_size = PAGE_SIZE;
+	skt->socket.io_offset = (unsigned long)skt->virt_io;
 
-		ret = device_create_file(&skt->socket.dev, &dev_attr_status);
-		if (ret)
-			goto out_err_8;
-	}
+	skt->status = soc_common_pcmcia_skt_state(skt);
 
-	dev_set_drvdata(dev, sinfo);
-	ret = 0;
-	goto out;
+	ret = pcmcia_register_socket(&skt->socket);
+	if (ret)
+		goto out_err_7;
 
-	do {
-		skt = &sinfo->skt[i];
+	add_timer(&skt->poll_timer);
+
+	mutex_unlock(&soc_pcmcia_sockets_lock);
+
+	ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+	if (ret)
+		goto out_err_8;
+
+	return ret;
 
-		device_remove_file(&skt->socket.dev, &dev_attr_status);
  out_err_8:
-		del_timer_sync(&skt->poll_timer);
-		pcmcia_unregister_socket(&skt->socket);
+	mutex_lock(&soc_pcmcia_sockets_lock);
+	del_timer_sync(&skt->poll_timer);
+	pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
-		flush_scheduled_work();
+	flush_scheduled_work();
 
-		ops->hw_shutdown(skt);
+	skt->ops->hw_shutdown(skt);
  out_err_6:
- 		list_del(&skt->node);
-		iounmap(skt->virt_io);
+	list_del(&skt->node);
+	mutex_unlock(&soc_pcmcia_sockets_lock);
+	iounmap(skt->virt_io);
  out_err_5:
-		release_resource(&skt->res_attr);
+	release_resource(&skt->res_attr);
  out_err_4:
-		release_resource(&skt->res_mem);
+	release_resource(&skt->res_mem);
  out_err_3:
-		release_resource(&skt->res_io);
+	release_resource(&skt->res_io);
  out_err_2:
-		release_resource(&skt->res_skt);
+	release_resource(&skt->res_skt);
  out_err_1:
-		i--;
-	} while (i > 0);
-
-	kfree(sinfo);
 
- out:
-	mutex_unlock(&soc_pcmcia_sockets_lock);
 	return ret;
 }
+EXPORT_SYMBOL(soc_pcmcia_add_one);
 
-int soc_common_drv_pcmcia_remove(struct device *dev)
-{
-	struct skt_dev_info *sinfo = dev_get_drvdata(dev);
-	int i;
-
-	dev_set_drvdata(dev, NULL);
-
-	mutex_lock(&soc_pcmcia_sockets_lock);
-	for (i = 0; i < sinfo->nskt; i++) {
-		struct soc_pcmcia_socket *skt = &sinfo->skt[i];
-
-		del_timer_sync(&skt->poll_timer);
-
-		pcmcia_unregister_socket(&skt->socket);
-
-		flush_scheduled_work();
-
-		skt->ops->hw_shutdown(skt);
-
-		soc_common_pcmcia_config_skt(skt, &dead_socket);
-
-		list_del(&skt->node);
-		iounmap(skt->virt_io);
-		skt->virt_io = NULL;
-		release_resource(&skt->res_attr);
-		release_resource(&skt->res_mem);
-		release_resource(&skt->res_io);
-		release_resource(&skt->res_skt);
-	}
-	if (list_empty(&soc_pcmcia_sockets))
-		soc_pcmcia_cpufreq_unregister();
-
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
-	kfree(sinfo);
-
-	return 0;
-}
-EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
+MODULE_LICENSE("Dual MPL/GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/soc_common.h linux-libre-2.6.33-gnu1/drivers/pcmcia/soc_common.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/soc_common.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/soc_common.h	2010-02-24 13:52:17.000000000 -0500
@@ -30,14 +30,12 @@ struct soc_pcmcia_socket {
 	/*
 	 * Info from low level handler
 	 */
-	struct device		*dev;
 	unsigned int		nr;
-	unsigned int		irq;
 
 	/*
 	 * Core PCMCIA state
 	 */
-	struct pcmcia_low_level *ops;
+	const struct pcmcia_low_level *ops;
 
 	unsigned int		status;
 	socket_state_t		cs_state;
@@ -135,10 +133,8 @@ extern void soc_pcmcia_enable_irqs(struc
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
 
-extern struct list_head soc_pcmcia_sockets;
-
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
-extern int soc_common_drv_pcmcia_remove(struct device *dev);
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 
 
 #ifdef CONFIG_PCMCIA_DEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/socket_sysfs.c linux-libre-2.6.33-gnu1/drivers/pcmcia/socket_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/socket_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/socket_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ static ssize_t pccard_store_irq_mask(str
 	if (!count)
 		return -EINVAL;
 
-	ret = sscanf (buf, "0x%x\n", &mask);
+	ret = sscanf(buf, "0x%x\n", &mask);
 
 	if (ret == 1) {
 		s->irq_mask &= mask;
@@ -278,7 +278,7 @@ static ssize_t pccard_extract_cis(struct
  free_tuple:
 	kfree(tuplebuffer);
 
-	return (ret);
+	return ret;
 }
 
 static ssize_t pccard_show_cis(struct kobject *kobj,
@@ -308,7 +308,7 @@ static ssize_t pccard_show_cis(struct ko
 		count = pccard_extract_cis(s, buf, off, count);
 	}
 
-	return (count);
+	return count;
 }
 
 static ssize_t pccard_store_cis(struct kobject *kobj,
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/tcic.c linux-libre-2.6.33-gnu1/drivers/pcmcia/tcic.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/tcic.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/tcic.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,21 +55,6 @@
 #include <pcmcia/ss.h>
 #include "tcic.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-static const char version[] =
-"tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
-
-#define debug(lvl, fmt, arg...) do {				\
-	if (pc_debug > (lvl))					\
-		printk(KERN_DEBUG "tcic: " fmt , ## arg);	\
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
-
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
 MODULE_LICENSE("Dual MPL/GPL");
@@ -574,7 +559,7 @@ static irqreturn_t tcic_interrupt(int ir
     } else
 	active = 1;
 
-    debug(2, "tcic_interrupt()\n");
+    pr_debug("tcic_interrupt()\n");
     
     for (i = 0; i < sockets; i++) {
 	psock = socket_table[i].psock;
@@ -611,13 +596,13 @@ static irqreturn_t tcic_interrupt(int ir
     }
     active = 0;
     
-    debug(2, "interrupt done\n");
+    pr_debug("interrupt done\n");
     return IRQ_HANDLED;
 } /* tcic_interrupt */
 
 static void tcic_timer(u_long data)
 {
-    debug(2, "tcic_timer()\n");
+    pr_debug("tcic_timer()\n");
     tcic_timer_pending = 0;
     tcic_interrupt(0, NULL);
 } /* tcic_timer */
@@ -644,7 +629,7 @@ static int tcic_get_status(struct pcmcia
     reg = tcic_getb(TCIC_PWR);
     if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
 	*value |= SS_POWERON;
-    debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
+    dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
     return 0;
 } /* tcic_get_status */
 
@@ -656,7 +641,7 @@ static int tcic_set_socket(struct pcmcia
     u_char reg;
     u_short scf1, scf2;
 
-    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+    dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 	  "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
 	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
     tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
@@ -731,7 +716,7 @@ static int tcic_set_io_map(struct pcmcia
     u_int addr;
     u_short base, len, ioctl;
     
-    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+    dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
 	  "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
 	  (unsigned long long)io->start, (unsigned long long)io->stop);
     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
@@ -768,7 +753,7 @@ static int tcic_set_mem_map(struct pcmci
     u_short addr, ctl;
     u_long base, len, mmap;
 
-    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+    dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
 	  "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
 	  mem->speed, (unsigned long long)mem->res->start,
 	  (unsigned long long)mem->res->end, mem->card_start);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/topic.h linux-libre-2.6.33-gnu1/drivers/pcmcia/topic.h
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/topic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/topic.h	2010-02-24 13:52:17.000000000 -0500
@@ -114,22 +114,17 @@ static void topic97_zoom_video(struct pc
 		reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
 		config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
 
-		reg = config_readb(socket, TOPIC97_MISC2);
-		reg |= TOPIC97_MISC2_ZV_ENABLE;
-		config_writeb(socket, TOPIC97_MISC2, reg);
-
-		/* not sure this is needed, doc is unclear */
-#if 0
 		reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
 		reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
 		config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
-#endif
-	}
-	else {
+	} else {
 		reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
 		config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
-	}
 
+		reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
+		reg &= ~(TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL);
+		config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
+	}
 }
 
 static int topic97_override(struct yenta_socket *socket)
diff -druNp linux-libre-2.6.32-gnu1/drivers/pcmcia/yenta_socket.c linux-libre-2.6.33-gnu1/drivers/pcmcia/yenta_socket.c
--- linux-libre-2.6.32-gnu1/drivers/pcmcia/yenta_socket.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pcmcia/yenta_socket.c	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  * Changelog:
  * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
  * 	Dynamically adjust the size of the bridge resource
- * 	
+ *
  * May 2003: Dominik Brodowski <linux@brodo.de>
  * 	Merge pci_socket.c and yenta.c into one file
  */
@@ -16,13 +16,12 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
-#include <asm/io.h>
-
 #include "yenta_socket.h"
 #include "i82365.h"
 
@@ -55,7 +54,7 @@ static int yenta_probe_cb_irq(struct yen
 
 static unsigned int override_bios;
 module_param(override_bios, uint, 0000);
-MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
+MODULE_PARM_DESC(override_bios, "yenta ignore bios resource allocation");
 
 /*
  * Generate easy-to-use ways of reading a cardbus sockets
@@ -237,24 +236,42 @@ static void yenta_set_power(struct yenta
 		/* i82365SL-DF style */
 		if (socket->flags & YENTA_16BIT_POWER_DF) {
 			switch (state->Vcc) {
-			case 33: reg |= I365_VCC_3V; break;
-			case 50: reg |= I365_VCC_5V; break;
-			default: reg = 0; break;
+			case 33:
+				reg |= I365_VCC_3V;
+				break;
+			case 50:
+				reg |= I365_VCC_5V;
+				break;
+			default:
+				reg = 0;
+				break;
 			}
 			switch (state->Vpp) {
 			case 33:
-			case 50: reg |= I365_VPP1_5V; break;
-			case 120: reg |= I365_VPP1_12V; break;
+			case 50:
+				reg |= I365_VPP1_5V;
+				break;
+			case 120:
+				reg |= I365_VPP1_12V;
+				break;
 			}
 		} else {
 			/* i82365SL-B style */
 			switch (state->Vcc) {
-			case 50: reg |= I365_VCC_5V; break;
-			default: reg = 0; break;
+			case 50:
+				reg |= I365_VCC_5V;
+				break;
+			default:
+				reg = 0;
+				break;
 			}
 			switch (state->Vpp) {
-			case 50: reg |= I365_VPP1_5V | I365_VPP2_5V; break;
-			case 120: reg |= I365_VPP1_12V | I365_VPP2_12V; break;
+			case 50:
+				reg |= I365_VPP1_5V | I365_VPP2_5V;
+				break;
+			case 120:
+				reg |= I365_VPP1_12V | I365_VPP2_12V;
+				break;
 			}
 		}
 
@@ -263,14 +280,26 @@ static void yenta_set_power(struct yenta
 	} else {
 		u32 reg = 0;	/* CB_SC_STPCLK? */
 		switch (state->Vcc) {
-		case 33: reg = CB_SC_VCC_3V; break;
-		case 50: reg = CB_SC_VCC_5V; break;
-		default: reg = 0; break;
+		case 33:
+			reg = CB_SC_VCC_3V;
+			break;
+		case 50:
+			reg = CB_SC_VCC_5V;
+			break;
+		default:
+			reg = 0;
+			break;
 		}
 		switch (state->Vpp) {
-		case 33:  reg |= CB_SC_VPP_3V; break;
-		case 50:  reg |= CB_SC_VPP_5V; break;
-		case 120: reg |= CB_SC_VPP_12V; break;
+		case 33:
+			reg |= CB_SC_VPP_3V;
+			break;
+		case 50:
+			reg |= CB_SC_VPP_5V;
+			break;
+		case 120:
+			reg |= CB_SC_VPP_12V;
+			break;
 		}
 		if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
 			cb_writel(socket, CB_SOCKET_CONTROL, reg);
@@ -314,23 +343,29 @@ static int yenta_set_socket(struct pcmci
 
 		reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
 		reg |= I365_PWR_NORESET;
-		if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
-		if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
+		if (state->flags & SS_PWR_AUTO)
+			reg |= I365_PWR_AUTO;
+		if (state->flags & SS_OUTPUT_ENA)
+			reg |= I365_PWR_OUT;
 		if (exca_readb(socket, I365_POWER) != reg)
 			exca_writeb(socket, I365_POWER, reg);
 
 		/* CSC interrupt: no ISA irq for CSC */
 		reg = I365_CSC_DETECT;
 		if (state->flags & SS_IOCARD) {
-			if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
+			if (state->csc_mask & SS_STSCHG)
+				reg |= I365_CSC_STSCHG;
 		} else {
-			if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
-			if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
-			if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
+			if (state->csc_mask & SS_BATDEAD)
+				reg |= I365_CSC_BVD1;
+			if (state->csc_mask & SS_BATWARN)
+				reg |= I365_CSC_BVD2;
+			if (state->csc_mask & SS_READY)
+				reg |= I365_CSC_READY;
 		}
 		exca_writeb(socket, I365_CSCINT, reg);
 		exca_readb(socket, I365_CSC);
-		if(sock->zoom_video)
+		if (sock->zoom_video)
 			sock->zoom_video(sock, state->flags & SS_ZVCARD);
 	}
 	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
@@ -368,9 +403,12 @@ static int yenta_set_io_map(struct pcmci
 	exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop);
 
 	ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
-	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+	if (io->flags & MAP_0WS)
+		ioctl |= I365_IOCTL_0WS(map);
+	if (io->flags & MAP_16BIT)
+		ioctl |= I365_IOCTL_16BIT(map);
+	if (io->flags & MAP_AUTOSZ)
+		ioctl |= I365_IOCTL_IOCS16(map);
 	exca_writeb(socket, I365_IOCTL, ioctl);
 
 	if (io->flags & MAP_ACTIVE)
@@ -416,10 +454,17 @@ static int yenta_set_mem_map(struct pcmc
 
 	word = (stop >> 12) & 0x0fff;
 	switch (to_cycles(mem->speed)) {
-		case 0: break;
-		case 1:  word |= I365_MEM_WS0; break;
-		case 2:  word |= I365_MEM_WS1; break;
-		default: word |= I365_MEM_WS1 | I365_MEM_WS0; break;
+	case 0:
+		break;
+	case 1:
+		word |= I365_MEM_WS0;
+		break;
+	case 2:
+		word |= I365_MEM_WS1;
+		break;
+	default:
+		word |= I365_MEM_WS1 | I365_MEM_WS0;
+		break;
 	}
 	exca_writew(socket, I365_MEM(map) + I365_W_STOP, word);
 
@@ -547,9 +592,9 @@ static int yenta_sock_suspend(struct pcm
  * max 4 MB, min 16 kB. We try very hard to not get below
  * the "ACC" values, though.
  */
-#define BRIDGE_MEM_MAX 4*1024*1024
-#define BRIDGE_MEM_ACC 128*1024
-#define BRIDGE_MEM_MIN 16*1024
+#define BRIDGE_MEM_MAX (4*1024*1024)
+#define BRIDGE_MEM_ACC (128*1024)
+#define BRIDGE_MEM_MIN (16*1024)
 
 #define BRIDGE_IO_MAX 512
 #define BRIDGE_IO_ACC 256
@@ -574,7 +619,7 @@ static int yenta_search_one_res(struct r
 		int i;
 		size = BRIDGE_MEM_MAX;
 		if (size > avail/8) {
-			size=(avail+1)/8;
+			size = (avail+1)/8;
 			/* round size down to next power of 2 */
 			i = 0;
 			while ((size /= 2) != 0)
@@ -590,7 +635,7 @@ static int yenta_search_one_res(struct r
 
 	do {
 		if (allocate_resource(root, res, size, start, end, align,
-				      NULL, NULL)==0) {
+				      NULL, NULL) == 0) {
 			return 1;
 		}
 		size = size/2;
@@ -605,8 +650,8 @@ static int yenta_search_res(struct yenta
 			    u32 min)
 {
 	int i;
-	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
-		struct resource * root = socket->dev->bus->resource[i];
+	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
+		struct resource *root = socket->dev->bus->resource[i];
 		if (!root)
 			continue;
 
@@ -704,7 +749,7 @@ static void yenta_allocate_resources(str
 static void yenta_free_resources(struct yenta_socket *socket)
 {
 	int i;
-	for (i=0;i<4;i++) {
+	for (i = 0; i < 4; i++) {
 		struct resource *res;
 		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
 		if (res->start != 0 && res->end != 0)
@@ -726,7 +771,7 @@ static void __devexit yenta_close(struct
 
 	/* we don't want a dying socket registered */
 	pcmcia_unregister_socket(&sock->socket);
-	
+
 	/* Disable all events so we don't die in an IRQ storm */
 	cb_writel(sock, CB_SOCKET_MASK, 0x0);
 	exca_writeb(sock, I365_CSCINT, 0);
@@ -898,7 +943,7 @@ static irqreturn_t yenta_probe_handler(i
 {
 	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
 	u8 csc;
-        u32 cb_event;
+	u32 cb_event;
 
 	/* Clear interrupt status for the event */
 	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
@@ -1019,7 +1064,7 @@ static void yenta_fixup_parent_bridge(st
 {
 	struct list_head *tmp;
 	unsigned char upper_limit;
- 	/*
+	/*
 	 * We only check and fix the parent bridge: All systems which need
 	 * this fixup that have been reviewed are laptops and the only bridge
 	 * which needed fixing was the parent bridge of the CardBus bridge:
@@ -1038,7 +1083,7 @@ static void yenta_fixup_parent_bridge(st
 
 	/* check the bus ranges of all silbling bridges to prevent overlap */
 	list_for_each(tmp, &bridge_to_fix->parent->children) {
-		struct pci_bus * silbling = pci_bus_b(tmp);
+		struct pci_bus *silbling = pci_bus_b(tmp);
 		/*
 		 * If the silbling has a higher secondary bus number
 		 * and it's secondary is equal or smaller than our
@@ -1083,7 +1128,7 @@ static void yenta_fixup_parent_bridge(st
  * interrupt, and that we can map the cardbus area. Fill in the
  * socket information structure..
  */
-static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct yenta_socket *socket;
 	int ret;
@@ -1285,7 +1330,7 @@ static int yenta_dev_resume(struct devic
 	return 0;
 }
 
-static struct dev_pm_ops yenta_pm_ops = {
+static const struct dev_pm_ops yenta_pm_ops = {
 	.suspend_noirq = yenta_dev_suspend_noirq,
 	.resume_noirq = yenta_dev_resume_noirq,
 	.resume = yenta_dev_resume,
@@ -1302,7 +1347,7 @@ static struct dev_pm_ops yenta_pm_ops =
 #define YENTA_PM_OPS	NULL
 #endif
 
-#define CB_ID(vend,dev,type)				\
+#define CB_ID(vend, dev, type)				\
 	{						\
 		.vendor		= vend,			\
 		.device		= dev,			\
@@ -1313,7 +1358,7 @@ static struct dev_pm_ops yenta_pm_ops =
 		.driver_data	= CARDBUS_TYPE_##type,	\
 	}
 
-static struct pci_device_id yenta_table [] = {
+static struct pci_device_id yenta_table[] = {
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI),
 
 	/*
@@ -1403,13 +1448,13 @@ static struct pci_driver yenta_cardbus_d
 
 static int __init yenta_socket_init(void)
 {
-	return pci_register_driver (&yenta_cardbus_driver);
+	return pci_register_driver(&yenta_cardbus_driver);
 }
 
 
-static void __exit yenta_socket_exit (void)
+static void __exit yenta_socket_exit(void)
 {
-	pci_unregister_driver (&yenta_cardbus_driver);
+	pci_unregister_driver(&yenta_cardbus_driver);
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/Kconfig linux-libre-2.6.33-gnu1/drivers/platform/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/platform/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,3 @@
-# drivers/platform/Kconfig
-
 if X86
 source "drivers/platform/x86/Kconfig"
 endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/acerhdf.c linux-libre-2.6.33-gnu1/drivers/platform/x86/acerhdf.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/acerhdf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/acerhdf.c	2010-02-24 13:52:17.000000000 -0500
@@ -52,7 +52,7 @@
  */
 #undef START_IN_KERNEL_MODE
 
-#define DRV_VER "0.5.18"
+#define DRV_VER "0.5.22"
 
 /*
  * According to the Atom N270 datasheet,
@@ -112,12 +112,14 @@ module_param_string(force_product, force
 MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
 
 /*
- * cmd_off: to switch the fan completely off / to check if the fan is off
+ * cmd_off: to switch the fan completely off
+ * chk_off: to check if the fan is off
  *	cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then
  *		the fan speed depending on the temperature
  */
 struct fancmd {
 	u8 cmd_off;
+	u8 chk_off;
 	u8 cmd_auto;
 };
 
@@ -134,32 +136,47 @@ struct bios_settings_t {
 /* Register addresses and values for different BIOS versions */
 static const struct bios_settings_t bios_tbl[] = {
 	/* AOA110 */
-	{"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
-	{"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
-	{"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
-	{"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
-	{"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
-	{"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} },
-	{"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
-	{"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
-	{"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
+	{"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+	{"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+	{"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+	{"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+	{"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+	{"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+	{"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x21, 0x00} },
+	{"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x21, 0x00} },
+	{"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x21, 0x00} },
 	/* AOA150 */
-	{"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
-	{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
-	/* special BIOS / other */
-	{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
-	{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
-	{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
-	{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
-	{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	/* Acer 1410 */
+	{"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	/* Acer 1810xx */
+	{"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	{"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	{"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	{"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	/* Gateway */
+	{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} },
+	{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+	{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+	{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+	/* Packard Bell */
+	{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} },
+	{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} },
+	{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
+	{"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+	{"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
 	/* pewpew-terminator */
-	{"", "", "", 0, 0, {0, 0} }
+	{"", "", "", 0, 0, {0, 0, 0} }
 };
 
 static const struct bios_settings_t *bios_cfg __read_mostly;
@@ -183,7 +200,7 @@ static int acerhdf_get_fanstate(int *sta
 	if (ec_read(bios_cfg->fanreg, &fan))
 		return -EINVAL;
 
-	if (fan != bios_cfg->cmd.cmd_off)
+	if (fan != bios_cfg->cmd.chk_off)
 		*state = ACERHDF_FAN_AUTO;
 	else
 		*state = ACERHDF_FAN_OFF;
@@ -460,7 +477,7 @@ static int acerhdf_remove(struct platfor
 	return 0;
 }
 
-static struct dev_pm_ops acerhdf_pm_ops = {
+static const struct dev_pm_ops acerhdf_pm_ops = {
 	.suspend = acerhdf_suspend,
 	.freeze  = acerhdf_suspend,
 };
@@ -475,13 +492,26 @@ static struct platform_driver acerhdf_dr
 	.remove = acerhdf_remove,
 };
 
+/* checks if str begins with start */
+static int str_starts_with(const char *str, const char *start)
+{
+	unsigned long str_len = 0, start_len = 0;
+
+	str_len = strlen(str);
+	start_len = strlen(start);
+
+	if (str_len >= start_len &&
+			!strncmp(str, start, start_len))
+		return 1;
+
+	return 0;
+}
 
 /* check hardware */
 static int acerhdf_check_hardware(void)
 {
 	char const *vendor, *version, *product;
-	int i;
-	unsigned long prod_len = 0;
+	const struct bios_settings_t *bt = NULL;
 
 	/* get BIOS data */
 	vendor  = dmi_get_system_info(DMI_SYS_VENDOR);
@@ -503,20 +533,20 @@ static int acerhdf_check_hardware(void)
 		kernelmode = 0;
 	}
 
-	prod_len = strlen(product);
-
 	if (verbose)
 		pr_info("BIOS info: %s %s, product: %s\n",
 			vendor, version, product);
 
 	/* search BIOS version and vendor in BIOS settings table */
-	for (i = 0; bios_tbl[i].version[0]; i++) {
-		if (strlen(bios_tbl[i].product) >= prod_len &&
-		    !strncmp(bios_tbl[i].product, product,
-			   strlen(bios_tbl[i].product)) &&
-		    !strcmp(bios_tbl[i].vendor, vendor) &&
-		    !strcmp(bios_tbl[i].version, version)) {
-			bios_cfg = &bios_tbl[i];
+	for (bt = bios_tbl; bt->vendor[0]; bt++) {
+		/*
+		 * check if actual hardware BIOS vendor, product and version
+		 * IDs start with the strings of BIOS table entry
+		 */
+		if (str_starts_with(vendor, bt->vendor) &&
+				str_starts_with(product, bt->product) &&
+				str_starts_with(version, bt->version)) {
+			bios_cfg = bt;
 			break;
 		}
 	}
@@ -629,9 +659,14 @@ static void __exit acerhdf_exit(void)
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Peter Feuerer");
 MODULE_DESCRIPTION("Aspire One temperature and fan driver");
-MODULE_ALIAS("dmi:*:*Acer*:*:");
-MODULE_ALIAS("dmi:*:*Gateway*:*:");
-MODULE_ALIAS("dmi:*:*Packard Bell*:*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:");
+MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:");
 
 module_init(acerhdf_init);
 module_exit(acerhdf_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/acer-wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/acer-wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/acer-wmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/acer-wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -96,9 +96,6 @@ struct acer_quirks {
 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
 MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
 
-/* Temporary workaround until the WMI sysfs interface goes in */
-MODULE_ALIAS("dmi:*:*Acer*:*:");
-
 /*
  * Interface capability flags
  */
@@ -937,7 +934,7 @@ static int __devinit acer_backlight_init
 	acer_backlight_device = bd;
 
 	bd->props.power = FB_BLANK_UNBLANK;
-	bd->props.brightness = max_brightness;
+	bd->props.brightness = read_brightness(bd);
 	bd->props.max_brightness = max_brightness;
 	backlight_update_status(bd);
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/asus_acpi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/asus_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/asus_acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/asus_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/backlight.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
@@ -466,6 +467,7 @@ MODULE_DEVICE_TABLE(acpi, asus_device_id
 static struct acpi_driver asus_hotk_driver = {
 	.name = "asus_acpi",
 	.class = ACPI_HOTK_CLASS,
+	.owner = THIS_MODULE,
 	.ids = asus_device_ids,
 	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
 	.ops = {
@@ -512,26 +514,12 @@ static int read_acpi_int(acpi_handle han
 	return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
 }
 
-/*
- * We write our info in page, we begin at offset off and cannot write more
- * than count bytes. We set eof to 1 if we handle those 2 values. We return the
- * number of bytes written in page
- */
-static int
-proc_read_info(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int asus_info_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	int temp;
-	char buf[16];		/* enough for all info */
-	/*
-	 * We use the easy way, we don't care of off and count,
-	 * so we don't set eof to 1
-	 */
 
-	len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
-	len += sprintf(page + len, "Model reference    : %s\n",
-		       hotk->methods->name);
+	seq_printf(m, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
+	seq_printf(m, "Model reference    : %s\n", hotk->methods->name);
 	/*
 	 * The SFUN method probably allows the original driver to get the list
 	 * of features supported by a given model. For now, 0x0100 or 0x0800
@@ -539,8 +527,7 @@ proc_read_info(char *page, char **start,
 	 * The significance of others is yet to be found.
 	 */
 	if (read_acpi_int(hotk->handle, "SFUN", &temp))
-		len +=
-		    sprintf(page + len, "SFUN value         : 0x%04x\n", temp);
+		seq_printf(m, "SFUN value         : 0x%04x\n", temp);
 	/*
 	 * Another value for userspace: the ASYM method returns 0x02 for
 	 * battery low and 0x04 for battery critical, its readings tend to be
@@ -549,30 +536,34 @@ proc_read_info(char *page, char **start,
 	 * silently ignored.
 	 */
 	if (read_acpi_int(hotk->handle, "ASYM", &temp))
-		len +=
-		    sprintf(page + len, "ASYM value         : 0x%04x\n", temp);
+		seq_printf(m, "ASYM value         : 0x%04x\n", temp);
 	if (asus_info) {
-		snprintf(buf, 16, "%d", asus_info->length);
-		len += sprintf(page + len, "DSDT length        : %s\n", buf);
-		snprintf(buf, 16, "%d", asus_info->checksum);
-		len += sprintf(page + len, "DSDT checksum      : %s\n", buf);
-		snprintf(buf, 16, "%d", asus_info->revision);
-		len += sprintf(page + len, "DSDT revision      : %s\n", buf);
-		snprintf(buf, 7, "%s", asus_info->oem_id);
-		len += sprintf(page + len, "OEM id             : %s\n", buf);
-		snprintf(buf, 9, "%s", asus_info->oem_table_id);
-		len += sprintf(page + len, "OEM table id       : %s\n", buf);
-		snprintf(buf, 16, "%x", asus_info->oem_revision);
-		len += sprintf(page + len, "OEM revision       : 0x%s\n", buf);
-		snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
-		len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
-		snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
-		len += sprintf(page + len, "ASL comp revision  : 0x%s\n", buf);
+		seq_printf(m, "DSDT length        : %d\n", asus_info->length);
+		seq_printf(m, "DSDT checksum      : %d\n", asus_info->checksum);
+		seq_printf(m, "DSDT revision      : %d\n", asus_info->revision);
+		seq_printf(m, "OEM id             : %.*s\n", ACPI_OEM_ID_SIZE, asus_info->oem_id);
+		seq_printf(m, "OEM table id       : %.*s\n", ACPI_OEM_TABLE_ID_SIZE, asus_info->oem_table_id);
+		seq_printf(m, "OEM revision       : 0x%x\n", asus_info->oem_revision);
+		seq_printf(m, "ASL comp vendor id : %.*s\n", ACPI_NAME_SIZE, asus_info->asl_compiler_id);
+		seq_printf(m, "ASL comp revision  : 0x%x\n", asus_info->asl_compiler_revision);
 	}
 
-	return len;
+	return 0;
 }
 
+static int asus_info_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, asus_info_proc_show, NULL);
+}
+
+static const struct file_operations asus_info_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= asus_info_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * /proc handlers
  * We write our info in page, we begin at offset off and cannot write more
@@ -638,34 +629,48 @@ write_led(const char __user *buffer, uns
 /*
  * Proc handlers for MLED
  */
-static int
-proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int mled_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n",
-		       read_led(hotk->methods->mled_status, MLED_ON));
+	seq_printf(m, "%d\n", read_led(hotk->methods->mled_status, MLED_ON));
+	return 0;
 }
 
-static int
-proc_write_mled(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static int mled_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mled_proc_show, NULL);
+}
+
+static ssize_t mled_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *pos)
 {
 	return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
 }
 
+static const struct file_operations mled_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mled_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= mled_proc_write,
+};
+
 /*
  * Proc handlers for LED display
  */
-static int
-proc_read_ledd(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int ledd_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "0x%08x\n", hotk->ledd_status);
+	seq_printf(m, "0x%08x\n", hotk->ledd_status);
+	return 0;
 }
 
-static int
-proc_write_ledd(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static int ledd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ledd_proc_show, NULL);
+}
+
+static ssize_t ledd_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *pos)
 {
 	int rv, value;
 
@@ -681,61 +686,104 @@ proc_write_ledd(struct file *file, const
 	return rv;
 }
 
+static const struct file_operations ledd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ledd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= ledd_proc_write,
+};
+
 /*
  * Proc handlers for WLED
  */
-static int
-proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int wled_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n",
-		       read_led(hotk->methods->wled_status, WLED_ON));
+	seq_printf(m, "%d\n", read_led(hotk->methods->wled_status, WLED_ON));
+	return 0;
 }
 
-static int
-proc_write_wled(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static int wled_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, wled_proc_show, NULL);
+}
+
+static ssize_t wled_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *pos)
 {
 	return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
 }
 
+static const struct file_operations wled_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= wled_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= wled_proc_write,
+};
+
 /*
  * Proc handlers for Bluetooth
  */
-static int
-proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof,
-		    void *data)
+static int bluetooth_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON));
+	seq_printf(m, "%d\n", read_led(hotk->methods->bt_status, BT_ON));
+	return 0;
 }
 
-static int
-proc_write_bluetooth(struct file *file, const char __user *buffer,
-		     unsigned long count, void *data)
+static int bluetooth_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bluetooth_proc_show, NULL);
+}
+
+static ssize_t bluetooth_proc_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *pos)
 {
 	/* Note: mt_bt_switch controls both internal Bluetooth adapter's
 	   presence and its LED */
 	return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
 }
 
+static const struct file_operations bluetooth_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= bluetooth_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= bluetooth_proc_write,
+};
+
 /*
  * Proc handlers for TLED
  */
-static int
-proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int tled_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n",
-		       read_led(hotk->methods->tled_status, TLED_ON));
+	seq_printf(m, "%d\n", read_led(hotk->methods->tled_status, TLED_ON));
+	return 0;
 }
 
-static int
-proc_write_tled(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static int tled_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, tled_proc_show, NULL);
+}
+
+static ssize_t tled_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *pos)
 {
 	return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
 }
 
+static const struct file_operations tled_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tled_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= tled_proc_write,
+};
+
 static int get_lcd_state(void)
 {
 	int lcd = 0;
@@ -828,16 +876,19 @@ static int set_lcd_state(int value)
 
 }
 
-static int
-proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
-	      void *data)
+static int lcd_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n", get_lcd_state());
+	seq_printf(m, "%d\n", get_lcd_state());
+	return 0;
 }
 
-static int
-proc_write_lcd(struct file *file, const char __user *buffer,
-	       unsigned long count, void *data)
+static int lcd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, lcd_proc_show, NULL);
+}
+
+static ssize_t lcd_proc_write(struct file *file, const char __user *buffer,
+	       size_t count, loff_t *pos)
 {
 	int rv, value;
 
@@ -847,6 +898,15 @@ proc_write_lcd(struct file *file, const
 	return rv;
 }
 
+static const struct file_operations lcd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= lcd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= lcd_proc_write,
+};
+
 static int read_brightness(struct backlight_device *bd)
 {
 	int value;
@@ -906,16 +966,19 @@ static int set_brightness_status(struct
 	return set_brightness(bd->props.brightness);
 }
 
-static int
-proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
-	      void *data)
+static int brn_proc_show(struct seq_file *m, void *v)
 {
-	return sprintf(page, "%d\n", read_brightness(NULL));
+	seq_printf(m, "%d\n", read_brightness(NULL));
+	return 0;
 }
 
-static int
-proc_write_brn(struct file *file, const char __user *buffer,
-	       unsigned long count, void *data)
+static int brn_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, brn_proc_show, NULL);
+}
+
+static ssize_t brn_proc_write(struct file *file, const char __user *buffer,
+	       size_t count, loff_t *pos)
 {
 	int rv, value;
 
@@ -928,6 +991,15 @@ proc_write_brn(struct file *file, const
 	return rv;
 }
 
+static const struct file_operations brn_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= brn_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= brn_proc_write,
+};
+
 static void set_display(int value)
 {
 	/* no sanity check needed for now */
@@ -941,9 +1013,7 @@ static void set_display(int value)
  * Now, *this* one could be more user-friendly, but so far, no-one has
  * complained. The significance of bits is the same as in proc_write_disp()
  */
-static int
-proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
-	       void *data)
+static int disp_proc_show(struct seq_file *m, void *v)
 {
 	int value = 0;
 
@@ -951,7 +1021,13 @@ proc_read_disp(char *page, char **start,
 		printk(KERN_WARNING
 		       "Asus ACPI: Error reading display status\n");
 	value &= 0x07;	/* needed for some models, shouldn't hurt others */
-	return sprintf(page, "%d\n", value);
+	seq_printf(m, "%d\n", value);
+	return 0;
+}
+
+static int disp_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, disp_proc_show, NULL);
 }
 
 /*
@@ -960,9 +1036,8 @@ proc_read_disp(char *page, char **start,
  * (bitwise) of these will suffice. I never actually tested 3 displays hooked
  * up simultaneously, so be warned. See the acpi4asus README for more info.
  */
-static int
-proc_write_disp(struct file *file, const char __user *buffer,
-		unsigned long count, void *data)
+static ssize_t disp_proc_write(struct file *file, const char __user *buffer,
+		size_t count, loff_t *pos)
 {
 	int rv, value;
 
@@ -972,25 +1047,27 @@ proc_write_disp(struct file *file, const
 	return rv;
 }
 
-typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
-			     int *eof, void *data);
-typedef int (proc_writefunc) (struct file *file, const char __user *buffer,
-			      unsigned long count, void *data);
+static const struct file_operations disp_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= disp_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= disp_proc_write,
+};
 
 static int
-asus_proc_add(char *name, proc_writefunc *writefunc,
-		     proc_readfunc *readfunc, mode_t mode,
+asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode,
 		     struct acpi_device *device)
 {
-	struct proc_dir_entry *proc =
-	    create_proc_entry(name, mode, acpi_device_dir(device));
+	struct proc_dir_entry *proc;
+
+	proc = proc_create_data(name, mode, acpi_device_dir(device),
+				proc_fops, acpi_driver_data(device));
 	if (!proc) {
 		printk(KERN_WARNING "  Unable to create %s fs entry\n", name);
 		return -1;
 	}
-	proc->write_proc = writefunc;
-	proc->read_proc = readfunc;
-	proc->data = acpi_driver_data(device);
 	proc->uid = asus_uid;
 	proc->gid = asus_gid;
 	return 0;
@@ -1019,10 +1096,9 @@ static int asus_hotk_add_fs(struct acpi_
 	if (!acpi_device_dir(device))
 		return -ENODEV;
 
-	proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device));
+	proc = proc_create(PROC_INFO, mode, acpi_device_dir(device),
+			   &asus_info_proc_fops);
 	if (proc) {
-		proc->read_proc = proc_read_info;
-		proc->data = acpi_driver_data(device);
 		proc->uid = asus_uid;
 		proc->gid = asus_gid;
 	} else {
@@ -1031,28 +1107,23 @@ static int asus_hotk_add_fs(struct acpi_
 	}
 
 	if (hotk->methods->mt_wled) {
-		asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled,
-			      mode, device);
+		asus_proc_add(PROC_WLED, &wled_proc_fops, mode, device);
 	}
 
 	if (hotk->methods->mt_ledd) {
-		asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd,
-			      mode, device);
+		asus_proc_add(PROC_LEDD, &ledd_proc_fops, mode, device);
 	}
 
 	if (hotk->methods->mt_mled) {
-		asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled,
-			      mode, device);
+		asus_proc_add(PROC_MLED, &mled_proc_fops, mode, device);
 	}
 
 	if (hotk->methods->mt_tled) {
-		asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled,
-			      mode, device);
+		asus_proc_add(PROC_TLED, &tled_proc_fops, mode, device);
 	}
 
 	if (hotk->methods->mt_bt_switch) {
-		asus_proc_add(PROC_BT, &proc_write_bluetooth,
-			      &proc_read_bluetooth, mode, device);
+		asus_proc_add(PROC_BT, &bluetooth_proc_fops, mode, device);
 	}
 
 	/*
@@ -1060,19 +1131,16 @@ static int asus_hotk_add_fs(struct acpi_
 	 * accessible from the keyboard
 	 */
 	if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
-		asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
-			      device);
+		asus_proc_add(PROC_LCD, &lcd_proc_fops, mode, device);
 	}
 
 	if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
 	    (hotk->methods->brightness_get && hotk->methods->brightness_set)) {
-		asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode,
-			      device);
+		asus_proc_add(PROC_BRN, &brn_proc_fops, mode, device);
 	}
 
 	if (hotk->methods->display_set) {
-		asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp,
-			      mode, device);
+		asus_proc_add(PROC_DISP, &disp_proc_fops, mode, device);
 	}
 
 	return 0;
@@ -1334,9 +1402,6 @@ static int asus_hotk_add(struct acpi_dev
 	acpi_status status = AE_OK;
 	int result;
 
-	if (!device)
-		return -EINVAL;
-
 	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
 	       ASUS_ACPI_VERSION);
 
@@ -1392,9 +1457,6 @@ end:
 
 static int asus_hotk_remove(struct acpi_device *device, int type)
 {
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
 	asus_hotk_remove_fs(device);
 
 	kfree(hotk);
@@ -1422,21 +1484,17 @@ static int __init asus_acpi_init(void)
 {
 	int result;
 
-	if (acpi_disabled)
-		return -ENODEV;
+	result = acpi_bus_register_driver(&asus_hotk_driver);
+	if (result < 0)
+		return result;
 
 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
 	if (!asus_proc_dir) {
 		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
+		acpi_bus_unregister_driver(&asus_hotk_driver);
 		return -ENODEV;
 	}
 
-	result = acpi_bus_register_driver(&asus_hotk_driver);
-	if (result < 0) {
-		remove_proc_entry(PROC_ASUS, acpi_root_dir);
-		return result;
-	}
-
 	/*
 	 * This is a bit of a kludge.  We only want this module loaded
 	 * for ASUS systems, but there's currently no way to probe the
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/asus-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/asus-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/asus-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/asus-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -221,6 +221,7 @@ static struct asus_hotk *hotk;
  */
 static const struct acpi_device_id asus_device_ids[] = {
 	{"ATK0100", 0},
+	{"ATK0101", 0},
 	{"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, asus_device_ids);
@@ -232,6 +233,7 @@ static void asus_hotk_notify(struct acpi
 static struct acpi_driver asus_hotk_driver = {
 	.name = ASUS_HOTK_NAME,
 	.class = ASUS_HOTK_CLASS,
+	.owner = THIS_MODULE,
 	.ids = asus_device_ids,
 	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
 	.ops = {
@@ -293,6 +295,11 @@ struct key_entry {
 enum { KE_KEY, KE_END };
 
 static struct key_entry asus_keymap[] = {
+	{KE_KEY, 0x02, KEY_SCREENLOCK},
+	{KE_KEY, 0x05, KEY_WLAN},
+	{KE_KEY, 0x08, KEY_F13},
+	{KE_KEY, 0x17, KEY_ZOOM},
+	{KE_KEY, 0x1f, KEY_BATTERY},
 	{KE_KEY, 0x30, KEY_VOLUMEUP},
 	{KE_KEY, 0x31, KEY_VOLUMEDOWN},
 	{KE_KEY, 0x32, KEY_MUTE},
@@ -312,8 +319,11 @@ static struct key_entry asus_keymap[] =
 	{KE_KEY, 0x5F, KEY_WLAN},
 	{KE_KEY, 0x60, KEY_SWITCHVIDEOMODE},
 	{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
-	{KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
+	{KE_KEY, 0x62, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x63, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */
 	{KE_KEY, 0x82, KEY_CAMERA},
+	{KE_KEY, 0x88, KEY_WLAN },
 	{KE_KEY, 0x8A, KEY_PROG1},
 	{KE_KEY, 0x95, KEY_MEDIA},
 	{KE_KEY, 0x99, KEY_PHONE},
@@ -1240,9 +1250,6 @@ static int asus_hotk_add(struct acpi_dev
 {
 	int result;
 
-	if (!device)
-		return -EINVAL;
-
 	pr_notice("Asus Laptop Support version %s\n",
 	       ASUS_LAPTOP_VERSION);
 
@@ -1283,8 +1290,8 @@ static int asus_hotk_add(struct acpi_dev
 	hotk->ledd_status = 0xFFF;
 
 	/* Set initial values of light sensor and level */
-	hotk->light_switch = 1;	/* Default to light sensor disabled */
-	hotk->light_level = 0;	/* level 5 for sensor sensitivity */
+	hotk->light_switch = 0;	/* Default to light sensor disabled */
+	hotk->light_level = 5;	/* level 5 for sensor sensitivity */
 
 	if (ls_switch_handle)
 		set_light_sens_switch(hotk->light_switch);
@@ -1306,9 +1313,6 @@ end:
 
 static int asus_hotk_remove(struct acpi_device *device, int type)
 {
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
 	kfree(hotk->name);
 	kfree(hotk);
 
@@ -1444,9 +1448,6 @@ static int __init asus_laptop_init(void)
 {
 	int result;
 
-	if (acpi_disabled)
-		return -ENODEV;
-
 	result = acpi_bus_register_driver(&asus_hotk_driver);
 	if (result < 0)
 		return result;
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/classmate-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/classmate-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/classmate-laptop.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/classmate-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,609 @@
+/*
+ *  Copyright (C) 2009  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.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.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/backlight.h>
+#include <linux/input.h>
+
+MODULE_LICENSE("GPL");
+
+
+struct cmpc_accel {
+	int sensitivity;
+};
+
+#define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
+
+
+/*
+ * Generic input device code.
+ */
+
+typedef void (*input_device_init)(struct input_dev *dev);
+
+static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
+				       input_device_init idev_init)
+{
+	struct input_dev *inputdev;
+	int error;
+
+	inputdev = input_allocate_device();
+	if (!inputdev)
+		return -ENOMEM;
+	inputdev->name = name;
+	inputdev->dev.parent = &acpi->dev;
+	idev_init(inputdev);
+	error = input_register_device(inputdev);
+	if (error) {
+		input_free_device(inputdev);
+		return error;
+	}
+	dev_set_drvdata(&acpi->dev, inputdev);
+	return 0;
+}
+
+static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
+{
+	struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
+	input_unregister_device(inputdev);
+	return 0;
+}
+
+/*
+ * Accelerometer code.
+ */
+static acpi_status cmpc_start_accel(acpi_handle handle)
+{
+	union acpi_object param[2];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x3;
+	param[1].type = ACPI_TYPE_INTEGER;
+	input.count = 2;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_stop_accel(acpi_handle handle)
+{
+	union acpi_object param[2];
+	struct acpi_object_list input;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x4;
+	param[1].type = ACPI_TYPE_INTEGER;
+	input.count = 2;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
+	return status;
+}
+
+static acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val)
+{
+	union acpi_object param[2];
+	struct acpi_object_list input;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x02;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = val;
+	input.count = 2;
+	input.pointer = param;
+	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
+}
+
+static acpi_status cmpc_get_accel(acpi_handle handle,
+				  unsigned char *x,
+				  unsigned char *y,
+				  unsigned char *z)
+{
+	union acpi_object param[2];
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 };
+	unsigned char *locs;
+	acpi_status status;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0x01;
+	param[1].type = ACPI_TYPE_INTEGER;
+	input.count = 2;
+	input.pointer = param;
+	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
+	if (ACPI_SUCCESS(status)) {
+		union acpi_object *obj;
+		obj = output.pointer;
+		locs = obj->buffer.pointer;
+		*x = locs[0];
+		*y = locs[1];
+		*z = locs[2];
+		kfree(output.pointer);
+	}
+	return status;
+}
+
+static void cmpc_accel_handler(struct acpi_device *dev, u32 event)
+{
+	if (event == 0x81) {
+		unsigned char x, y, z;
+		acpi_status status;
+
+		status = cmpc_get_accel(dev->handle, &x, &y, &z);
+		if (ACPI_SUCCESS(status)) {
+			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+
+			input_report_abs(inputdev, ABS_X, x);
+			input_report_abs(inputdev, ABS_Y, y);
+			input_report_abs(inputdev, ABS_Z, z);
+			input_sync(inputdev);
+		}
+	}
+}
+
+static ssize_t cmpc_accel_sensitivity_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	return sprintf(buf, "%d\n", accel->sensitivity);
+}
+
+static ssize_t cmpc_accel_sensitivity_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+	unsigned long sensitivity;
+	int r;
+
+	acpi = to_acpi_device(dev);
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	r = strict_strtoul(buf, 0, &sensitivity);
+	if (r)
+		return r;
+
+	accel->sensitivity = sensitivity;
+	cmpc_accel_set_sensitivity(acpi->handle, sensitivity);
+
+	return strnlen(buf, count);
+}
+
+struct device_attribute cmpc_accel_sensitivity_attr = {
+	.attr = { .name = "sensitivity", .mode = 0660 },
+	.show = cmpc_accel_sensitivity_show,
+	.store = cmpc_accel_sensitivity_store
+};
+
+static int cmpc_accel_open(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+
+	acpi = to_acpi_device(input->dev.parent);
+	if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle)))
+		return 0;
+	return -EIO;
+}
+
+static void cmpc_accel_close(struct input_dev *input)
+{
+	struct acpi_device *acpi;
+
+	acpi = to_acpi_device(input->dev.parent);
+	cmpc_stop_accel(acpi->handle);
+}
+
+static void cmpc_accel_idev_init(struct input_dev *inputdev)
+{
+	set_bit(EV_ABS, inputdev->evbit);
+	input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0);
+	input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0);
+	input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0);
+	inputdev->open = cmpc_accel_open;
+	inputdev->close = cmpc_accel_close;
+}
+
+static int cmpc_accel_add(struct acpi_device *acpi)
+{
+	int error;
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
+	if (!accel)
+		return -ENOMEM;
+
+	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
+	cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity);
+
+	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
+	if (error)
+		goto failed_file;
+
+	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel",
+					    cmpc_accel_idev_init);
+	if (error)
+		goto failed_input;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	dev_set_drvdata(&inputdev->dev, accel);
+
+	return 0;
+
+failed_input:
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
+failed_file:
+	kfree(accel);
+	return error;
+}
+
+static int cmpc_accel_remove(struct acpi_device *acpi, int type)
+{
+	struct input_dev *inputdev;
+	struct cmpc_accel *accel;
+
+	inputdev = dev_get_drvdata(&acpi->dev);
+	accel = dev_get_drvdata(&inputdev->dev);
+
+	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
+	return cmpc_remove_acpi_notify_device(acpi);
+}
+
+static const struct acpi_device_id cmpc_accel_device_ids[] = {
+	{"ACCE0000", 0},
+	{"", 0}
+};
+MODULE_DEVICE_TABLE(acpi, cmpc_accel_device_ids);
+
+static struct acpi_driver cmpc_accel_acpi_driver = {
+	.owner = THIS_MODULE,
+	.name = "cmpc_accel",
+	.class = "cmpc_accel",
+	.ids = cmpc_accel_device_ids,
+	.ops = {
+		.add = cmpc_accel_add,
+		.remove = cmpc_accel_remove,
+		.notify = cmpc_accel_handler,
+	}
+};
+
+
+/*
+ * Tablet mode code.
+ */
+static acpi_status cmpc_get_tablet(acpi_handle handle,
+				   unsigned long long *value)
+{
+	union acpi_object param;
+	struct acpi_object_list input;
+	unsigned long long output;
+	acpi_status status;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = 0x01;
+	input.count = 1;
+	input.pointer = &param;
+	status = acpi_evaluate_integer(handle, "TCMD", &input, &output);
+	if (ACPI_SUCCESS(status))
+		*value = output;
+	return status;
+}
+
+static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
+{
+	unsigned long long val = 0;
+	struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+
+	if (event == 0x81) {
+		if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val)))
+			input_report_switch(inputdev, SW_TABLET_MODE, !val);
+	}
+}
+
+static void cmpc_tablet_idev_init(struct input_dev *inputdev)
+{
+	unsigned long long val = 0;
+	struct acpi_device *acpi;
+
+	set_bit(EV_SW, inputdev->evbit);
+	set_bit(SW_TABLET_MODE, inputdev->swbit);
+
+	acpi = to_acpi_device(inputdev->dev.parent);
+	if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val)))
+		input_report_switch(inputdev, SW_TABLET_MODE, !val);
+}
+
+static int cmpc_tablet_add(struct acpi_device *acpi)
+{
+	return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet",
+					   cmpc_tablet_idev_init);
+}
+
+static int cmpc_tablet_remove(struct acpi_device *acpi, int type)
+{
+	return cmpc_remove_acpi_notify_device(acpi);
+}
+
+static int cmpc_tablet_resume(struct acpi_device *acpi)
+{
+	struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
+	unsigned long long val = 0;
+	if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val)))
+		input_report_switch(inputdev, SW_TABLET_MODE, !val);
+	return 0;
+}
+
+static const struct acpi_device_id cmpc_tablet_device_ids[] = {
+	{"TBLT0000", 0},
+	{"", 0}
+};
+MODULE_DEVICE_TABLE(acpi, cmpc_tablet_device_ids);
+
+static struct acpi_driver cmpc_tablet_acpi_driver = {
+	.owner = THIS_MODULE,
+	.name = "cmpc_tablet",
+	.class = "cmpc_tablet",
+	.ids = cmpc_tablet_device_ids,
+	.ops = {
+		.add = cmpc_tablet_add,
+		.remove = cmpc_tablet_remove,
+		.resume = cmpc_tablet_resume,
+		.notify = cmpc_tablet_handler,
+	}
+};
+
+
+/*
+ * Backlight code.
+ */
+
+static acpi_status cmpc_get_brightness(acpi_handle handle,
+				       unsigned long long *value)
+{
+	union acpi_object param;
+	struct acpi_object_list input;
+	unsigned long long output;
+	acpi_status status;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = 0xC0;
+	input.count = 1;
+	input.pointer = &param;
+	status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
+	if (ACPI_SUCCESS(status))
+		*value = output;
+	return status;
+}
+
+static acpi_status cmpc_set_brightness(acpi_handle handle,
+				       unsigned long long value)
+{
+	union acpi_object param[2];
+	struct acpi_object_list input;
+	acpi_status status;
+	unsigned long long output;
+
+	param[0].type = ACPI_TYPE_INTEGER;
+	param[0].integer.value = 0xC0;
+	param[1].type = ACPI_TYPE_INTEGER;
+	param[1].integer.value = value;
+	input.count = 2;
+	input.pointer = param;
+	status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
+	return status;
+}
+
+static int cmpc_bl_get_brightness(struct backlight_device *bd)
+{
+	acpi_status status;
+	acpi_handle handle;
+	unsigned long long brightness;
+
+	handle = bl_get_data(bd);
+	status = cmpc_get_brightness(handle, &brightness);
+	if (ACPI_SUCCESS(status))
+		return brightness;
+	else
+		return -1;
+}
+
+static int cmpc_bl_update_status(struct backlight_device *bd)
+{
+	acpi_status status;
+	acpi_handle handle;
+
+	handle = bl_get_data(bd);
+	status = cmpc_set_brightness(handle, bd->props.brightness);
+	if (ACPI_SUCCESS(status))
+		return 0;
+	else
+		return -1;
+}
+
+static struct backlight_ops cmpc_bl_ops = {
+	.get_brightness = cmpc_bl_get_brightness,
+	.update_status = cmpc_bl_update_status
+};
+
+static int cmpc_bl_add(struct acpi_device *acpi)
+{
+	struct backlight_device *bd;
+
+	bd = backlight_device_register("cmpc_bl", &acpi->dev,
+				       acpi->handle, &cmpc_bl_ops);
+	bd->props.max_brightness = 7;
+	dev_set_drvdata(&acpi->dev, bd);
+	return 0;
+}
+
+static int cmpc_bl_remove(struct acpi_device *acpi, int type)
+{
+	struct backlight_device *bd;
+
+	bd = dev_get_drvdata(&acpi->dev);
+	backlight_device_unregister(bd);
+	return 0;
+}
+
+static const struct acpi_device_id cmpc_device_ids[] = {
+	{"IPML200", 0},
+	{"", 0}
+};
+MODULE_DEVICE_TABLE(acpi, cmpc_device_ids);
+
+static struct acpi_driver cmpc_bl_acpi_driver = {
+	.owner = THIS_MODULE,
+	.name = "cmpc",
+	.class = "cmpc",
+	.ids = cmpc_device_ids,
+	.ops = {
+		.add = cmpc_bl_add,
+		.remove = cmpc_bl_remove
+	}
+};
+
+
+/*
+ * Extra keys code.
+ */
+static int cmpc_keys_codes[] = {
+	KEY_UNKNOWN,
+	KEY_WLAN,
+	KEY_SWITCHVIDEOMODE,
+	KEY_BRIGHTNESSDOWN,
+	KEY_BRIGHTNESSUP,
+	KEY_VENDOR,
+	KEY_MAX
+};
+
+static void cmpc_keys_handler(struct acpi_device *dev, u32 event)
+{
+	struct input_dev *inputdev;
+	int code = KEY_MAX;
+
+	if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes))
+		code = cmpc_keys_codes[event & 0x0F];
+	inputdev = dev_get_drvdata(&dev->dev);;
+	input_report_key(inputdev, code, !(event & 0x10));
+}
+
+static void cmpc_keys_idev_init(struct input_dev *inputdev)
+{
+	int i;
+
+	set_bit(EV_KEY, inputdev->evbit);
+	for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++)
+		set_bit(cmpc_keys_codes[i], inputdev->keybit);
+}
+
+static int cmpc_keys_add(struct acpi_device *acpi)
+{
+	return cmpc_add_acpi_notify_device(acpi, "cmpc_keys",
+					   cmpc_keys_idev_init);
+}
+
+static int cmpc_keys_remove(struct acpi_device *acpi, int type)
+{
+	return cmpc_remove_acpi_notify_device(acpi);
+}
+
+static const struct acpi_device_id cmpc_keys_device_ids[] = {
+	{"FnBT0000", 0},
+	{"", 0}
+};
+MODULE_DEVICE_TABLE(acpi, cmpc_keys_device_ids);
+
+static struct acpi_driver cmpc_keys_acpi_driver = {
+	.owner = THIS_MODULE,
+	.name = "cmpc_keys",
+	.class = "cmpc_keys",
+	.ids = cmpc_keys_device_ids,
+	.ops = {
+		.add = cmpc_keys_add,
+		.remove = cmpc_keys_remove,
+		.notify = cmpc_keys_handler,
+	}
+};
+
+
+/*
+ * General init/exit code.
+ */
+
+static int cmpc_init(void)
+{
+	int r;
+
+	r = acpi_bus_register_driver(&cmpc_keys_acpi_driver);
+	if (r)
+		goto failed_keys;
+
+	r = acpi_bus_register_driver(&cmpc_bl_acpi_driver);
+	if (r)
+		goto failed_bl;
+
+	r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver);
+	if (r)
+		goto failed_tablet;
+
+	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver);
+	if (r)
+		goto failed_accel;
+
+	return r;
+
+failed_accel:
+	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
+
+failed_tablet:
+	acpi_bus_unregister_driver(&cmpc_bl_acpi_driver);
+
+failed_bl:
+	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
+
+failed_keys:
+	return r;
+}
+
+static void cmpc_exit(void)
+{
+	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
+	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
+	acpi_bus_unregister_driver(&cmpc_bl_acpi_driver);
+	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
+}
+
+module_init(cmpc_init);
+module_exit(cmpc_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/compal-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/compal-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/compal-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/compal-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,6 @@
 #include <linux/dmi.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
-#include <linux/autoconf.h>
 
 #define COMPAL_DRIVER_VERSION "0.2.6"
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/dell-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/dell-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,6 +58,14 @@ static int da_command_code;
 static int da_num_tokens;
 static struct calling_interface_token *da_tokens;
 
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = "dell-laptop",
+		.owner = THIS_MODULE,
+	}
+};
+
+static struct platform_device *platform_device;
 static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
@@ -74,7 +82,7 @@ static const struct dmi_system_id __init
 	{ }
 };
 
-static void parse_da_table(const struct dmi_header *dm)
+static void __init parse_da_table(const struct dmi_header *dm)
 {
 	/* Final token is a terminator, so we don't want to copy it */
 	int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
@@ -103,7 +111,7 @@ static void parse_da_table(const struct
 	da_num_tokens += tokens;
 }
 
-static void find_tokens(const struct dmi_header *dm, void *dummy)
+static void __init find_tokens(const struct dmi_header *dm, void *dummy)
 {
 	switch (dm->type) {
 	case 0xd4: /* Indexed IO */
@@ -197,8 +205,8 @@ static void dell_rfkill_query(struct rfk
 	dell_send_request(&buffer, 17, 11);
 	status = buffer.output[1];
 
-	if (status & BIT(bit))
-		rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
+	rfkill_set_sw_state(rfkill, !!(status & BIT(bit)));
+	rfkill_set_hw_state(rfkill, !(status & BIT(16)));
 }
 
 static const struct rfkill_ops dell_rfkill_ops = {
@@ -206,7 +214,7 @@ static const struct rfkill_ops dell_rfki
 	.query = dell_rfkill_query,
 };
 
-static int dell_setup_rfkill(void)
+static int __init dell_setup_rfkill(void)
 {
 	struct calling_interface_buffer buffer;
 	int status;
@@ -217,7 +225,8 @@ static int dell_setup_rfkill(void)
 	status = buffer.output[1];
 
 	if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
-		wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,
+		wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
+					   RFKILL_TYPE_WLAN,
 					   &dell_rfkill_ops, (void *) 1);
 		if (!wifi_rfkill) {
 			ret = -ENOMEM;
@@ -229,7 +238,8 @@ static int dell_setup_rfkill(void)
 	}
 
 	if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
-		bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,
+		bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
+						&platform_device->dev,
 						RFKILL_TYPE_BLUETOOTH,
 						&dell_rfkill_ops, (void *) 2);
 		if (!bluetooth_rfkill) {
@@ -242,7 +252,9 @@ static int dell_setup_rfkill(void)
 	}
 
 	if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
-		wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,
+		wwan_rfkill = rfkill_alloc("dell-wwan",
+					   &platform_device->dev,
+					   RFKILL_TYPE_WWAN,
 					   &dell_rfkill_ops, (void *) 3);
 		if (!wwan_rfkill) {
 			ret = -ENOMEM;
@@ -268,6 +280,22 @@ err_wifi:
 	return ret;
 }
 
+static void dell_cleanup_rfkill(void)
+{
+	if (wifi_rfkill) {
+		rfkill_unregister(wifi_rfkill);
+		rfkill_destroy(wifi_rfkill);
+	}
+	if (bluetooth_rfkill) {
+		rfkill_unregister(bluetooth_rfkill);
+		rfkill_destroy(bluetooth_rfkill);
+	}
+	if (wwan_rfkill) {
+		rfkill_unregister(wwan_rfkill);
+		rfkill_destroy(wwan_rfkill);
+	}
+}
+
 static int dell_send_intensity(struct backlight_device *bd)
 {
 	struct calling_interface_buffer buffer;
@@ -326,11 +354,23 @@ static int __init dell_init(void)
 		return -ENODEV;
 	}
 
+	ret = platform_driver_register(&platform_driver);
+	if (ret)
+		goto fail_platform_driver;
+	platform_device = platform_device_alloc("dell-laptop", -1);
+	if (!platform_device) {
+		ret = -ENOMEM;
+		goto fail_platform_device1;
+	}
+	ret = platform_device_add(platform_device);
+	if (ret)
+		goto fail_platform_device2;
+
 	ret = dell_setup_rfkill();
 
 	if (ret) {
 		printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n");
-		goto out;
+		goto fail_rfkill;
 	}
 
 #ifdef CONFIG_ACPI
@@ -352,13 +392,13 @@ static int __init dell_init(void)
 	if (max_intensity) {
 		dell_backlight_device = backlight_device_register(
 			"dell_backlight",
-			NULL, NULL,
+			&platform_device->dev, NULL,
 			&dell_ops);
 
 		if (IS_ERR(dell_backlight_device)) {
 			ret = PTR_ERR(dell_backlight_device);
 			dell_backlight_device = NULL;
-			goto out;
+			goto fail_backlight;
 		}
 
 		dell_backlight_device->props.max_brightness = max_intensity;
@@ -368,13 +408,16 @@ static int __init dell_init(void)
 	}
 
 	return 0;
-out:
-	if (wifi_rfkill)
-		rfkill_unregister(wifi_rfkill);
-	if (bluetooth_rfkill)
-		rfkill_unregister(bluetooth_rfkill);
-	if (wwan_rfkill)
-		rfkill_unregister(wwan_rfkill);
+
+fail_backlight:
+	dell_cleanup_rfkill();
+fail_rfkill:
+	platform_device_del(platform_device);
+fail_platform_device2:
+	platform_device_put(platform_device);
+fail_platform_device1:
+	platform_driver_unregister(&platform_driver);
+fail_platform_driver:
 	kfree(da_tokens);
 	return ret;
 }
@@ -382,12 +425,7 @@ out:
 static void __exit dell_exit(void)
 {
 	backlight_device_unregister(dell_backlight_device);
-	if (wifi_rfkill)
-		rfkill_unregister(wifi_rfkill);
-	if (bluetooth_rfkill)
-		rfkill_unregister(bluetooth_rfkill);
-	if (wwan_rfkill)
-		rfkill_unregister(wwan_rfkill);
+	dell_cleanup_rfkill();
 }
 
 module_init(dell_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/dell-wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/dell-wmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/dell-wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/acpi.h>
 #include <linux/string.h>
+#include <linux/dmi.h>
 
 MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
 MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
@@ -38,6 +39,8 @@ MODULE_LICENSE("GPL");
 
 #define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
 
+static int acpi_video;
+
 MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
 
 struct key_entry {
@@ -54,7 +57,7 @@ enum { KE_KEY, KE_SW, KE_IGNORE, KE_END
  * via the keyboard controller so should not be sent again.
  */
 
-static struct key_entry dell_wmi_keymap[] = {
+static struct key_entry dell_legacy_wmi_keymap[] = {
 	{KE_KEY, 0xe045, KEY_PROG1},
 	{KE_KEY, 0xe009, KEY_EJECTCD},
 
@@ -72,7 +75,7 @@ static struct key_entry dell_wmi_keymap[
 
 	/* The next device is at offset 6, the active devices are at
 	   offset 8 and the attached devices at offset 10 */
-	{KE_KEY, 0xe00b, KEY_DISPLAYTOGGLE},
+	{KE_KEY, 0xe00b, KEY_SWITCHVIDEOMODE},
 
 	{KE_IGNORE, 0xe00c, KEY_KBDILLUMTOGGLE},
 
@@ -96,6 +99,47 @@ static struct key_entry dell_wmi_keymap[
 	{KE_END, 0}
 };
 
+static bool dell_new_hk_type;
+
+struct dell_new_keymap_entry {
+	u16 scancode;
+	u16 keycode;
+};
+
+struct dell_hotkey_table {
+	struct dmi_header header;
+	struct dell_new_keymap_entry keymap[];
+
+};
+
+static struct key_entry *dell_new_wmi_keymap;
+
+static u16 bios_to_linux_keycode[256] = {
+
+	KEY_MEDIA,	KEY_NEXTSONG,	KEY_PLAYPAUSE, KEY_PREVIOUSSONG,
+	KEY_STOPCD,	KEY_UNKNOWN,	KEY_UNKNOWN,	KEY_UNKNOWN,
+	KEY_WWW,	KEY_UNKNOWN,	KEY_VOLUMEDOWN, KEY_MUTE,
+	KEY_VOLUMEUP,	KEY_UNKNOWN,	KEY_BATTERY,	KEY_EJECTCD,
+	KEY_UNKNOWN,	KEY_SLEEP,	KEY_PROG1, KEY_BRIGHTNESSDOWN,
+	KEY_BRIGHTNESSUP,	KEY_UNKNOWN,	KEY_KBDILLUMTOGGLE,
+	KEY_UNKNOWN,	KEY_SWITCHVIDEOMODE,	KEY_UNKNOWN, KEY_UNKNOWN,
+	KEY_SWITCHVIDEOMODE,	KEY_UNKNOWN,	KEY_UNKNOWN, KEY_PROG2,
+	KEY_UNKNOWN, 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, 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, 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, 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,
+	KEY_PROG3
+};
+
+
+static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap;
+
 static struct input_dev *dell_wmi_input_dev;
 
 static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
@@ -158,30 +202,90 @@ static void dell_wmi_notify(u32 value, v
 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
 	static struct key_entry *key;
 	union acpi_object *obj;
+	acpi_status status;
 
-	wmi_get_event_data(value, &response);
+	status = wmi_get_event_data(value, &response);
+	if (status != AE_OK) {
+		printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status);
+		return;
+	}
 
 	obj = (union acpi_object *)response.pointer;
 
 	if (obj && obj->type == ACPI_TYPE_BUFFER) {
-		int *buffer = (int *)obj->buffer.pointer;
-		/*
-		 *  The upper bytes of the event may contain
-		 *  additional information, so mask them off for the
-		 *  scancode lookup
-		 */
-		key = dell_wmi_get_entry_by_scancode(buffer[1] & 0xFFFF);
-		if (key) {
+		int reported_key;
+		u16 *buffer_entry = (u16 *)obj->buffer.pointer;
+		if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
+			printk(KERN_INFO "dell-wmi: Received unknown WMI event"
+					 " (0x%x)\n", buffer_entry[1]);
+			return;
+		}
+
+		if (dell_new_hk_type)
+			reported_key = (int)buffer_entry[2];
+		else
+			reported_key = (int)buffer_entry[1] & 0xffff;
+
+		key = dell_wmi_get_entry_by_scancode(reported_key);
+
+		if (!key) {
+			printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+				reported_key);
+		} else if ((key->keycode == KEY_BRIGHTNESSUP ||
+			    key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
+			/* Don't report brightness notifications that will also
+			 * come via ACPI */
+			return;
+		} else {
 			input_report_key(dell_wmi_input_dev, key->keycode, 1);
 			input_sync(dell_wmi_input_dev);
 			input_report_key(dell_wmi_input_dev, key->keycode, 0);
 			input_sync(dell_wmi_input_dev);
-		} else if (buffer[1] & 0xFFFF)
-			printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
-			       buffer[1] & 0xFFFF);
+		}
 	}
+	kfree(obj);
 }
 
+
+static void setup_new_hk_map(const struct dmi_header *dm)
+{
+
+	int i;
+	int hotkey_num = (dm->length-4)/sizeof(struct dell_new_keymap_entry);
+	struct dell_hotkey_table *table =
+		container_of(dm, struct dell_hotkey_table, header);
+
+	dell_new_wmi_keymap = kzalloc((hotkey_num+1) *
+				      sizeof(struct key_entry), GFP_KERNEL);
+
+	for (i = 0; i < hotkey_num; i++) {
+		dell_new_wmi_keymap[i].type = KE_KEY;
+		dell_new_wmi_keymap[i].code = table->keymap[i].scancode;
+		dell_new_wmi_keymap[i].keycode =
+			(table->keymap[i].keycode > 255) ? 0 :
+			bios_to_linux_keycode[table->keymap[i].keycode];
+	}
+
+	dell_new_wmi_keymap[i].type = KE_END;
+	dell_new_wmi_keymap[i].code = 0;
+	dell_new_wmi_keymap[i].keycode = 0;
+
+	dell_wmi_keymap = dell_new_wmi_keymap;
+
+}
+
+
+static void find_hk_type(const struct dmi_header *dm, void *dummy)
+{
+
+	if ((dm->type == 0xb2) && (dm->length > 6)) {
+		dell_new_hk_type = true;
+		setup_new_hk_map(dm);
+	}
+
+}
+
+
 static int __init dell_wmi_input_setup(void)
 {
 	struct key_entry *key;
@@ -224,34 +328,37 @@ static int __init dell_wmi_input_setup(v
 static int __init dell_wmi_init(void)
 {
 	int err;
+	acpi_status status;
 
-	if (wmi_has_guid(DELL_EVENT_GUID)) {
-		err = dell_wmi_input_setup();
+	if (!wmi_has_guid(DELL_EVENT_GUID)) {
+		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+		return -ENODEV;
+	}
 
-		if (err)
-			return err;
+	dmi_walk(find_hk_type, NULL);
+	acpi_video = acpi_video_backlight_support();
 
-		err = wmi_install_notify_handler(DELL_EVENT_GUID,
-						 dell_wmi_notify, NULL);
-		if (err) {
-			input_unregister_device(dell_wmi_input_dev);
-			printk(KERN_ERR "dell-wmi: Unable to register"
-			       " notify handler - %d\n", err);
-			return err;
-		}
+	err = dell_wmi_input_setup();
+	if (err)
+		return err;
 
-	} else
-		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+	status = wmi_install_notify_handler(DELL_EVENT_GUID,
+					 dell_wmi_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		input_unregister_device(dell_wmi_input_dev);
+		printk(KERN_ERR
+			"dell-wmi: Unable to register notify handler - %d\n",
+			status);
+		return -ENODEV;
+	}
 
 	return 0;
 }
 
 static void __exit dell_wmi_exit(void)
 {
-	if (wmi_has_guid(DELL_EVENT_GUID)) {
-		wmi_remove_notify_handler(DELL_EVENT_GUID);
-		input_unregister_device(dell_wmi_input_dev);
-	}
+	wmi_remove_notify_handler(DELL_EVENT_GUID);
+	input_unregister_device(dell_wmi_input_dev);
 }
 
 module_init(dell_wmi_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/eeepc-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/eeepc-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/eeepc-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- *  eepc-laptop.c - Asus Eee PC extras
+ *  eeepc-laptop.c - Asus Eee PC extras
  *
  *  Based on asus_acpi.c as patched for the Eee PC by Asus:
  *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
@@ -31,23 +31,36 @@
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
 #include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/rfkill.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/leds.h>
+#include <linux/dmi.h>
 
 #define EEEPC_LAPTOP_VERSION	"0.1"
+#define EEEPC_LAPTOP_NAME	"Eee PC Hotkey Driver"
+#define EEEPC_LAPTOP_FILE	"eeepc"
 
-#define EEEPC_HOTK_NAME		"Eee PC Hotkey Driver"
-#define EEEPC_HOTK_FILE		"eeepc"
-#define EEEPC_HOTK_CLASS	"hotkey"
-#define EEEPC_HOTK_DEVICE_NAME	"Hotkey"
-#define EEEPC_HOTK_HID		"ASUS010"
+#define EEEPC_ACPI_CLASS	"hotkey"
+#define EEEPC_ACPI_DEVICE_NAME	"Hotkey"
+#define EEEPC_ACPI_HID		"ASUS010"
+
+MODULE_AUTHOR("Corentin Chary, Eric Cooper");
+MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
+MODULE_LICENSE("GPL");
 
+static bool hotplug_disabled;
+
+module_param(hotplug_disabled, bool, 0644);
+MODULE_PARM_DESC(hotplug_disabled,
+		 "Disable hotplug for wireless device. "
+		 "If your laptop need that, please report to "
+		 "acpi4asus-user@lists.sourceforge.net.");
 
 /*
  * Definitions for Asus EeePC
  */
-#define	NOTIFY_WLAN_ON	0x10
 #define NOTIFY_BRN_MIN	0x20
 #define NOTIFY_BRN_MAX	0x2f
 
@@ -117,145 +130,64 @@ static const char *cm_setv[] = {
 	NULL, NULL, "PBPS", "TPDS"
 };
 
-#define EEEPC_EC	"\\_SB.PCI0.SBRG.EC0."
-
-#define EEEPC_EC_FAN_PWM	EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
-#define EEEPC_EC_SC02		0x63
-#define EEEPC_EC_FAN_HRPM	EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
-#define EEEPC_EC_FAN_LRPM	EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
-#define EEEPC_EC_FAN_CTRL	EEEPC_EC "SFB3" /* Byte containing SF25  */
-#define EEEPC_EC_SFB3		0xD3
+static const struct key_entry eeepc_keymap[] = {
+	{ KE_KEY, 0x10, { KEY_WLAN } },
+	{ KE_KEY, 0x11, { KEY_WLAN } },
+	{ KE_KEY, 0x12, { KEY_PROG1 } },
+	{ KE_KEY, 0x13, { KEY_MUTE } },
+	{ KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
+	{ KE_KEY, 0x15, { KEY_VOLUMEUP } },
+	{ KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
+	{ KE_KEY, 0x1a, { KEY_COFFEE } },
+	{ KE_KEY, 0x1b, { KEY_ZOOM } },
+	{ KE_KEY, 0x1c, { KEY_PROG2 } },
+	{ KE_KEY, 0x1d, { KEY_PROG3 } },
+	{ KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
+	{ KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
+	{ KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
+	{ KE_KEY, 0x38, { KEY_F14 } },
+	{ KE_END, 0 },
+};
 
 /*
  * This is the main structure, we can use it to store useful information
- * about the hotk device
  */
-struct eeepc_hotk {
-	struct acpi_device *device;	/* the device we are in */
-	acpi_handle handle;		/* the handle of the hotk device */
+struct eeepc_laptop {
+	acpi_handle handle;		/* the handle of the acpi device */
 	u32 cm_supported;		/* the control methods supported
 					   by this BIOS */
-	uint init_flag;			/* Init flags */
+	bool cpufv_disabled;
+	bool hotplug_disabled;
 	u16 event_count[128];		/* count for each event */
+
+	struct platform_device *platform_device;
+	struct device *hwmon_device;
+	struct backlight_device *backlight_device;
+
 	struct input_dev *inputdev;
-	u16 *keycode_map;
+	struct key_entry *keymap;
+
 	struct rfkill *wlan_rfkill;
 	struct rfkill *bluetooth_rfkill;
 	struct rfkill *wwan3g_rfkill;
 	struct rfkill *wimax_rfkill;
+
 	struct hotplug_slot *hotplug_slot;
 	struct mutex hotplug_lock;
-};
-
-/* The actual device the driver binds to */
-static struct eeepc_hotk *ehotk;
-
-/* Platform device/driver */
-static int eeepc_hotk_thaw(struct device *device);
-static int eeepc_hotk_restore(struct device *device);
-
-static struct dev_pm_ops eeepc_pm_ops = {
-	.thaw = eeepc_hotk_thaw,
-	.restore = eeepc_hotk_restore,
-};
-
-static struct platform_driver platform_driver = {
-	.driver = {
-		.name = EEEPC_HOTK_FILE,
-		.owner = THIS_MODULE,
-		.pm = &eeepc_pm_ops,
-	}
-};
-
-static struct platform_device *platform_device;
-
-struct key_entry {
-	char type;
-	u8 code;
-	u16 keycode;
-};
-
-enum { KE_KEY, KE_END };
 
-static struct key_entry eeepc_keymap[] = {
-	/* Sleep already handled via generic ACPI code */
-	{KE_KEY, 0x10, KEY_WLAN },
-	{KE_KEY, 0x11, KEY_WLAN },
-	{KE_KEY, 0x12, KEY_PROG1 },
-	{KE_KEY, 0x13, KEY_MUTE },
-	{KE_KEY, 0x14, KEY_VOLUMEDOWN },
-	{KE_KEY, 0x15, KEY_VOLUMEUP },
-	{KE_KEY, 0x1a, KEY_COFFEE },
-	{KE_KEY, 0x1b, KEY_ZOOM },
-	{KE_KEY, 0x1c, KEY_PROG2 },
-	{KE_KEY, 0x1d, KEY_PROG3 },
-	{KE_KEY, NOTIFY_BRN_MIN,     KEY_BRIGHTNESSDOWN },
-	{KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
-	{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
-	{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
-	{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
-	{KE_END, 0},
-};
-
-/*
- * The hotkey driver declaration
- */
-static int eeepc_hotk_add(struct acpi_device *device);
-static int eeepc_hotk_remove(struct acpi_device *device, int type);
-static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
-
-static const struct acpi_device_id eeepc_device_ids[] = {
-	{EEEPC_HOTK_HID, 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
-
-static struct acpi_driver eeepc_hotk_driver = {
-	.name = EEEPC_HOTK_NAME,
-	.class = EEEPC_HOTK_CLASS,
-	.ids = eeepc_device_ids,
-	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
-	.ops = {
-		.add = eeepc_hotk_add,
-		.remove = eeepc_hotk_remove,
-		.notify = eeepc_hotk_notify,
-	},
-};
-
-/* PCI hotplug ops */
-static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
-
-static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
-	.owner = THIS_MODULE,
-	.get_adapter_status = eeepc_get_adapter_status,
-	.get_power_status = eeepc_get_adapter_status,
-};
-
-/* The backlight device /sys/class/backlight */
-static struct backlight_device *eeepc_backlight_device;
-
-/* The hwmon device */
-static struct device *eeepc_hwmon_device;
-
-/*
- * The backlight class declaration
- */
-static int read_brightness(struct backlight_device *bd);
-static int update_bl_status(struct backlight_device *bd);
-static struct backlight_ops eeepcbl_ops = {
-	.get_brightness = read_brightness,
-	.update_status = update_bl_status,
+	struct led_classdev tpd_led;
+	int tpd_led_wk;
+	struct workqueue_struct *led_workqueue;
+	struct work_struct tpd_led_work;
 };
 
-MODULE_AUTHOR("Corentin Chary, Eric Cooper");
-MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
-MODULE_LICENSE("GPL");
-
 /*
  * ACPI Helpers
  */
-static int write_acpi_int(acpi_handle handle, const char *method, int val,
-			  struct acpi_buffer *output)
+static int write_acpi_int(acpi_handle handle, const char *method, int val)
 {
 	struct acpi_object_list params;
 	union acpi_object in_obj;
@@ -266,7 +198,7 @@ static int write_acpi_int(acpi_handle ha
 	in_obj.type = ACPI_TYPE_INTEGER;
 	in_obj.integer.value = val;
 
-	status = acpi_evaluate_object(handle, (char *)method, &params, output);
+	status = acpi_evaluate_object(handle, (char *)method, &params, NULL);
 	return (status == AE_OK ? 0 : -1);
 }
 
@@ -285,81 +217,56 @@ static int read_acpi_int(acpi_handle han
 	}
 }
 
-static int set_acpi(int cm, int value)
-{
-	if (ehotk->cm_supported & (0x1 << cm)) {
-		const char *method = cm_setv[cm];
-		if (method == NULL)
-			return -ENODEV;
-		if (write_acpi_int(ehotk->handle, method, value, NULL))
-			pr_warning("Error writing %s\n", method);
-	}
-	return 0;
-}
-
-static int get_acpi(int cm)
+static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
 {
-	int value = -ENODEV;
-	if ((ehotk->cm_supported & (0x1 << cm))) {
-		const char *method = cm_getv[cm];
-		if (method == NULL)
-			return -ENODEV;
-		if (read_acpi_int(ehotk->handle, method, &value))
-			pr_warning("Error reading %s\n", method);
-	}
-	return value;
-}
+	const char *method = cm_setv[cm];
 
-/*
- * Backlight
- */
-static int read_brightness(struct backlight_device *bd)
-{
-	return get_acpi(CM_ASL_PANELBRIGHT);
-}
+	if (method == NULL)
+		return -ENODEV;
+	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
+		return -ENODEV;
 
-static int set_brightness(struct backlight_device *bd, int value)
-{
-	value = max(0, min(15, value));
-	return set_acpi(CM_ASL_PANELBRIGHT, value);
+	if (write_acpi_int(eeepc->handle, method, value))
+		pr_warning("Error writing %s\n", method);
+	return 0;
 }
 
-static int update_bl_status(struct backlight_device *bd)
+static int get_acpi(struct eeepc_laptop *eeepc, int cm)
 {
-	return set_brightness(bd, bd->props.brightness);
-}
+	const char *method = cm_getv[cm];
+	int value;
 
-/*
- * Rfkill helpers
- */
+	if (method == NULL)
+		return -ENODEV;
+	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
+		return -ENODEV;
 
-static bool eeepc_wlan_rfkill_blocked(void)
-{
-	if (get_acpi(CM_ASL_WLAN) == 1)
-		return false;
-	return true;
+	if (read_acpi_int(eeepc->handle, method, &value))
+		pr_warning("Error reading %s\n", method);
+	return value;
 }
 
-static int eeepc_rfkill_set(void *data, bool blocked)
+static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
+			      acpi_handle *handle)
 {
-	unsigned long asl = (unsigned long)data;
-	return set_acpi(asl, !blocked);
-}
+	const char *method = cm_setv[cm];
+	acpi_status status;
 
-static const struct rfkill_ops eeepc_rfkill_ops = {
-	.set_block = eeepc_rfkill_set,
-};
+	if (method == NULL)
+		return -ENODEV;
+	if ((eeepc->cm_supported & (0x1 << cm)) == 0)
+		return -ENODEV;
 
-static void __devinit eeepc_enable_camera(void)
-{
-	/*
-	 * If the following call to set_acpi() fails, it's because there's no
-	 * camera so we can ignore the error.
-	 */
-	if (get_acpi(CM_ASL_CAMERA) == 0)
-		set_acpi(CM_ASL_CAMERA, 1);
+	status = acpi_get_handle(eeepc->handle, (char *)method,
+				 handle);
+	if (status != AE_OK) {
+		pr_warning("Error finding %s\n", method);
+		return -ENODEV;
+	}
+	return 0;
 }
 
+
 /*
  * Sys helpers
  */
@@ -372,60 +279,63 @@ static int parse_arg(const char *buf, un
 	return count;
 }
 
-static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
+static ssize_t store_sys_acpi(struct device *dev, int cm,
+			      const char *buf, size_t count)
 {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 	int rv, value;
 
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0)
-		value = set_acpi(cm, value);
+		value = set_acpi(eeepc, cm, value);
 	if (value < 0)
-		return value;
+		return -EIO;
 	return rv;
 }
 
-static ssize_t show_sys_acpi(int cm, char *buf)
+static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
 {
-	int value = get_acpi(cm);
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+	int value = get_acpi(eeepc, cm);
 
 	if (value < 0)
-		return value;
+		return -EIO;
 	return sprintf(buf, "%d\n", value);
 }
 
-#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm)				\
+#define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm)			\
 	static ssize_t show_##_name(struct device *dev,			\
 				    struct device_attribute *attr,	\
 				    char *buf)				\
 	{								\
-		return show_sys_acpi(_cm, buf);				\
+		return show_sys_acpi(dev, _cm, buf);			\
 	}								\
 	static ssize_t store_##_name(struct device *dev,		\
 				     struct device_attribute *attr,	\
 				     const char *buf, size_t count)	\
 	{								\
-		return store_sys_acpi(_cm, buf, count);			\
+		return store_sys_acpi(dev, _cm, buf, count);		\
 	}								\
 	static struct device_attribute dev_attr_##_name = {		\
 		.attr = {						\
 			.name = __stringify(_name),			\
-			.mode = 0644 },					\
+			.mode = _mode },				\
 		.show   = show_##_name,					\
 		.store  = store_##_name,				\
 	}
 
-EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
-EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
-EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
+EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
+EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
+EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
 
 struct eeepc_cpufv {
 	int num;
 	int cur;
 };
 
-static int get_cpufv(struct eeepc_cpufv *c)
+static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
 {
-	c->cur = get_acpi(CM_ASL_CPUFV);
+	c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
 	c->num = (c->cur >> 8) & 0xff;
 	c->cur &= 0xff;
 	if (c->cur < 0 || c->num <= 0 || c->num > 12)
@@ -437,11 +347,12 @@ static ssize_t show_available_cpufv(stru
 				    struct device_attribute *attr,
 				    char *buf)
 {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 	struct eeepc_cpufv c;
 	int i;
 	ssize_t len = 0;
 
-	if (get_cpufv(&c))
+	if (get_cpufv(eeepc, &c))
 		return -ENODEV;
 	for (i = 0; i < c.num; i++)
 		len += sprintf(buf + len, "%d ", i);
@@ -453,9 +364,10 @@ static ssize_t show_cpufv(struct device
 			  struct device_attribute *attr,
 			  char *buf)
 {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 	struct eeepc_cpufv c;
 
-	if (get_cpufv(&c))
+	if (get_cpufv(eeepc, &c))
 		return -ENODEV;
 	return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
 }
@@ -464,20 +376,58 @@ static ssize_t store_cpufv(struct device
 			   struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 	struct eeepc_cpufv c;
 	int rv, value;
 
-	if (get_cpufv(&c))
+	if (eeepc->cpufv_disabled)
+		return -EPERM;
+	if (get_cpufv(eeepc, &c))
 		return -ENODEV;
 	rv = parse_arg(buf, count, &value);
 	if (rv < 0)
 		return rv;
 	if (!rv || value < 0 || value >= c.num)
 		return -EINVAL;
-	set_acpi(CM_ASL_CPUFV, value);
+	set_acpi(eeepc, CM_ASL_CPUFV, value);
 	return rv;
 }
 
+static ssize_t show_cpufv_disabled(struct device *dev,
+			  struct device_attribute *attr,
+			  char *buf)
+{
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
+}
+
+static ssize_t store_cpufv_disabled(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+	int rv, value;
+
+	rv = parse_arg(buf, count, &value);
+	if (rv < 0)
+		return rv;
+
+	switch (value) {
+	case 0:
+		if (eeepc->cpufv_disabled)
+			pr_warning("cpufv enabled (not officially supported "
+				"on this model)\n");
+		eeepc->cpufv_disabled = false;
+		return rv;
+	case 1:
+		return -EPERM;
+	default:
+		return -EINVAL;
+	}
+}
+
+
 static struct device_attribute dev_attr_cpufv = {
 	.attr = {
 		.name = "cpufv",
@@ -493,12 +443,22 @@ static struct device_attribute dev_attr_
 	.show   = show_available_cpufv
 };
 
+static struct device_attribute dev_attr_cpufv_disabled = {
+	.attr = {
+		.name = "cpufv_disabled",
+		.mode = 0644 },
+	.show   = show_cpufv_disabled,
+	.store  = store_cpufv_disabled
+};
+
+
 static struct attribute *platform_attributes[] = {
 	&dev_attr_camera.attr,
 	&dev_attr_cardr.attr,
 	&dev_attr_disp.attr,
 	&dev_attr_cpufv.attr,
 	&dev_attr_available_cpufv.attr,
+	&dev_attr_cpufv_disabled.attr,
 	NULL
 };
 
@@ -506,156 +466,125 @@ static struct attribute_group platform_a
 	.attrs = platform_attributes
 };
 
-/*
- * Hotkey functions
- */
-static struct key_entry *eepc_get_entry_by_scancode(int code)
+static int eeepc_platform_init(struct eeepc_laptop *eeepc)
 {
-	struct key_entry *key;
-
-	for (key = eeepc_keymap; key->type != KE_END; key++)
-		if (code == key->code)
-			return key;
+	int result;
 
-	return NULL;
-}
+	eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
+	if (!eeepc->platform_device)
+		return -ENOMEM;
+	platform_set_drvdata(eeepc->platform_device, eeepc);
 
-static struct key_entry *eepc_get_entry_by_keycode(int code)
-{
-	struct key_entry *key;
+	result = platform_device_add(eeepc->platform_device);
+	if (result)
+		goto fail_platform_device;
 
-	for (key = eeepc_keymap; key->type != KE_END; key++)
-		if (code == key->keycode && key->type == KE_KEY)
-			return key;
+	result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
+				    &platform_attribute_group);
+	if (result)
+		goto fail_sysfs;
+	return 0;
 
-	return NULL;
+fail_sysfs:
+	platform_device_del(eeepc->platform_device);
+fail_platform_device:
+	platform_device_put(eeepc->platform_device);
+	return result;
 }
 
-static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
 {
-	struct key_entry *key = eepc_get_entry_by_scancode(scancode);
+	sysfs_remove_group(&eeepc->platform_device->dev.kobj,
+			   &platform_attribute_group);
+	platform_device_unregister(eeepc->platform_device);
+}
 
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
-		return 0;
-	}
+/*
+ * LEDs
+ */
+/*
+ * These functions actually update the LED's, and are called from a
+ * workqueue. By doing this as separate work rather than when the LED
+ * subsystem asks, we avoid messing with the Asus ACPI stuff during a
+ * potentially bad time, such as a timer interrupt.
+ */
+static void tpd_led_update(struct work_struct *work)
+ {
+	struct eeepc_laptop *eeepc;
 
-	return -EINVAL;
+	eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
+
+	set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
 }
 
-static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static void tpd_led_set(struct led_classdev *led_cdev,
+			enum led_brightness value)
 {
-	struct key_entry *key;
-	int old_keycode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
+	struct eeepc_laptop *eeepc;
 
-	key = eepc_get_entry_by_scancode(scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!eepc_get_entry_by_keycode(old_keycode))
-			clear_bit(old_keycode, dev->keybit);
-		return 0;
-	}
+	eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
 
-	return -EINVAL;
+	eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
+	queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
 }
 
-static void cmsg_quirk(int cm, const char *name)
+static int eeepc_led_init(struct eeepc_laptop *eeepc)
 {
-	int dummy;
+	int rv;
 
-	/* Some BIOSes do not report cm although it is avaliable.
-	   Check if cm_getv[cm] works and, if yes, assume cm should be set. */
-	if (!(ehotk->cm_supported & (1 << cm))
-	    && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
-		pr_info("%s (%x) not reported by BIOS,"
-			" enabling anyway\n", name, 1 << cm);
-		ehotk->cm_supported |= 1 << cm;
-	}
-}
+	if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
+		return 0;
 
-static void cmsg_quirks(void)
-{
-	cmsg_quirk(CM_ASL_LID, "LID");
-	cmsg_quirk(CM_ASL_TYPE, "TYPE");
-	cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
-	cmsg_quirk(CM_ASL_TPD, "TPD");
-}
+	eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
+	if (!eeepc->led_workqueue)
+		return -ENOMEM;
+	INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
 
-static int eeepc_hotk_check(void)
-{
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	int result;
+	eeepc->tpd_led.name = "eeepc::touchpad";
+	eeepc->tpd_led.brightness_set = tpd_led_set;
+	eeepc->tpd_led.max_brightness = 1;
 
-	result = acpi_bus_get_status(ehotk->device);
-	if (result)
-		return result;
-	if (ehotk->device->status.present) {
-		if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
-				    &buffer)) {
-			pr_err("Hotkey initialization failed\n");
-			return -ENODEV;
-		} else {
-			pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
-		}
-		/* get control methods supported */
-		if (read_acpi_int(ehotk->handle, "CMSG"
-				   , &ehotk->cm_supported)) {
-			pr_err("Get control methods supported failed\n");
-			return -ENODEV;
-		} else {
-			cmsg_quirks();
-			pr_info("Get control methods supported: 0x%x\n",
-				ehotk->cm_supported);
-		}
-	} else {
-		pr_err("Hotkey device not present, aborting\n");
-		return -EINVAL;
+	rv = led_classdev_register(&eeepc->platform_device->dev,
+				   &eeepc->tpd_led);
+	if (rv) {
+		destroy_workqueue(eeepc->led_workqueue);
+		return rv;
 	}
+
 	return 0;
 }
 
-static int notify_brn(void)
+static void eeepc_led_exit(struct eeepc_laptop *eeepc)
 {
-	/* returns the *previous* brightness, or -1 */
-	struct backlight_device *bd = eeepc_backlight_device;
-	if (bd) {
-		int old = bd->props.brightness;
-		backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
-		return old;
-	}
-	return -1;
+	if (eeepc->tpd_led.dev)
+		led_classdev_unregister(&eeepc->tpd_led);
+	if (eeepc->led_workqueue)
+		destroy_workqueue(eeepc->led_workqueue);
 }
 
-static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
-				    u8 *value)
-{
-	int val = get_acpi(CM_ASL_WLAN);
-
-	if (val == 1 || val == 0)
-		*value = val;
-	else
-		return -EINVAL;
 
-	return 0;
+/*
+ * PCI hotplug (for wlan rfkill)
+ */
+static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
+{
+	if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
+		return false;
+	return true;
 }
 
-static void eeepc_rfkill_hotplug(void)
+static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
 {
 	struct pci_dev *dev;
 	struct pci_bus *bus;
-	bool blocked = eeepc_wlan_rfkill_blocked();
+	bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
 
-	if (ehotk->wlan_rfkill)
-		rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
+	if (eeepc->wlan_rfkill)
+		rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
 
-	mutex_lock(&ehotk->hotplug_lock);
+	mutex_lock(&eeepc->hotplug_lock);
 
-	if (ehotk->hotplug_slot) {
+	if (eeepc->hotplug_slot) {
 		bus = pci_find_bus(0, 1);
 		if (!bus) {
 			pr_warning("Unable to find PCI bus 1?\n");
@@ -685,69 +614,23 @@ static void eeepc_rfkill_hotplug(void)
 	}
 
 out_unlock:
-	mutex_unlock(&ehotk->hotplug_lock);
+	mutex_unlock(&eeepc->hotplug_lock);
 }
 
 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 {
+	struct eeepc_laptop *eeepc = data;
+
 	if (event != ACPI_NOTIFY_BUS_CHECK)
 		return;
 
-	eeepc_rfkill_hotplug();
-}
-
-static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
-{
-	static struct key_entry *key;
-	u16 count;
-	int brn = -ENODEV;
-
-	if (!ehotk)
-		return;
-	if (event > ACPI_MAX_SYS_NOTIFY)
-		return;
-	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
-		brn = notify_brn();
-	count = ehotk->event_count[event % 128]++;
-	acpi_bus_generate_proc_event(ehotk->device, event, count);
-	acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
-					dev_name(&ehotk->device->dev), event,
-					count);
-	if (ehotk->inputdev) {
-		if (brn != -ENODEV) {
-			/* brightness-change events need special
-			 * handling for conversion to key events
-			 */
-			if (brn < 0)
-				brn = event;
-			else
-				brn += NOTIFY_BRN_MIN;
-			if (event < brn)
-				event = NOTIFY_BRN_MIN; /* brightness down */
-			else if (event > brn)
-				event = NOTIFY_BRN_MIN + 2; /* ... up */
-			else
-				event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
-		}
-		key = eepc_get_entry_by_scancode(event);
-		if (key) {
-			switch (key->type) {
-			case KE_KEY:
-				input_report_key(ehotk->inputdev, key->keycode,
-						 1);
-				input_sync(ehotk->inputdev);
-				input_report_key(ehotk->inputdev, key->keycode,
-						 0);
-				input_sync(ehotk->inputdev);
-				break;
-			}
-		}
-	}
+	eeepc_rfkill_hotplug(eeepc);
 }
 
-static int eeepc_register_rfkill_notifier(char *node)
+static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
+					  char *node)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 	acpi_handle handle;
 
 	status = acpi_get_handle(NULL, node, &handle);
@@ -756,7 +639,7 @@ static int eeepc_register_rfkill_notifie
 		status = acpi_install_notify_handler(handle,
 						     ACPI_SYSTEM_NOTIFY,
 						     eeepc_rfkill_notify,
-						     NULL);
+						     eeepc);
 		if (ACPI_FAILURE(status))
 			pr_warning("Failed to register notify on %s\n", node);
 	} else
@@ -765,7 +648,8 @@ static int eeepc_register_rfkill_notifie
 	return 0;
 }
 
-static void eeepc_unregister_rfkill_notifier(char *node)
+static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
+					     char *node)
 {
 	acpi_status status = AE_OK;
 	acpi_handle handle;
@@ -782,13 +666,33 @@ static void eeepc_unregister_rfkill_noti
 	}
 }
 
+static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
+				    u8 *value)
+{
+	struct eeepc_laptop *eeepc = hotplug_slot->private;
+	int val = get_acpi(eeepc, CM_ASL_WLAN);
+
+	if (val == 1 || val == 0)
+		*value = val;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
 {
 	kfree(hotplug_slot->info);
 	kfree(hotplug_slot);
 }
 
-static int eeepc_setup_pci_hotplug(void)
+static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
+	.owner = THIS_MODULE,
+	.get_adapter_status = eeepc_get_adapter_status,
+	.get_power_status = eeepc_get_adapter_status,
+};
+
+static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
 {
 	int ret = -ENOMEM;
 	struct pci_bus *bus = pci_find_bus(0, 1);
@@ -798,22 +702,22 @@ static int eeepc_setup_pci_hotplug(void)
 		return -ENODEV;
 	}
 
-	ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
-	if (!ehotk->hotplug_slot)
+	eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
+	if (!eeepc->hotplug_slot)
 		goto error_slot;
 
-	ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
+	eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
 					    GFP_KERNEL);
-	if (!ehotk->hotplug_slot->info)
+	if (!eeepc->hotplug_slot->info)
 		goto error_info;
 
-	ehotk->hotplug_slot->private = ehotk;
-	ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
-	ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
-	eeepc_get_adapter_status(ehotk->hotplug_slot,
-				 &ehotk->hotplug_slot->info->adapter_status);
+	eeepc->hotplug_slot->private = eeepc;
+	eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
+	eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
+	eeepc_get_adapter_status(eeepc->hotplug_slot,
+				 &eeepc->hotplug_slot->info->adapter_status);
 
-	ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
+	ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
 	if (ret) {
 		pr_err("Unable to register hotplug slot - %d\n", ret);
 		goto error_register;
@@ -822,17 +726,159 @@ static int eeepc_setup_pci_hotplug(void)
 	return 0;
 
 error_register:
-	kfree(ehotk->hotplug_slot->info);
+	kfree(eeepc->hotplug_slot->info);
 error_info:
-	kfree(ehotk->hotplug_slot);
-	ehotk->hotplug_slot = NULL;
+	kfree(eeepc->hotplug_slot);
+	eeepc->hotplug_slot = NULL;
 error_slot:
 	return ret;
 }
 
+/*
+ * Rfkill devices
+ */
+static int eeepc_rfkill_set(void *data, bool blocked)
+{
+	acpi_handle handle = data;
+
+	return write_acpi_int(handle, NULL, !blocked);
+}
+
+static const struct rfkill_ops eeepc_rfkill_ops = {
+	.set_block = eeepc_rfkill_set,
+};
+
+static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
+			    struct rfkill **rfkill,
+			    const char *name,
+			    enum rfkill_type type, int cm)
+{
+	acpi_handle handle;
+	int result;
+
+	result = acpi_setter_handle(eeepc, cm, &handle);
+	if (result < 0)
+		return result;
+
+	*rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
+			       &eeepc_rfkill_ops, handle);
+
+	if (!*rfkill)
+		return -EINVAL;
+
+	rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
+	result = rfkill_register(*rfkill);
+	if (result) {
+		rfkill_destroy(*rfkill);
+		*rfkill = NULL;
+		return result;
+	}
+	return 0;
+}
+
+static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
+{
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
+	eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
+	if (eeepc->wlan_rfkill) {
+		rfkill_unregister(eeepc->wlan_rfkill);
+		rfkill_destroy(eeepc->wlan_rfkill);
+		eeepc->wlan_rfkill = NULL;
+	}
+	/*
+	 * Refresh pci hotplug in case the rfkill state was changed after
+	 * eeepc_unregister_rfkill_notifier()
+	 */
+	eeepc_rfkill_hotplug(eeepc);
+	if (eeepc->hotplug_slot)
+		pci_hp_deregister(eeepc->hotplug_slot);
+
+	if (eeepc->bluetooth_rfkill) {
+		rfkill_unregister(eeepc->bluetooth_rfkill);
+		rfkill_destroy(eeepc->bluetooth_rfkill);
+		eeepc->bluetooth_rfkill = NULL;
+	}
+	if (eeepc->wwan3g_rfkill) {
+		rfkill_unregister(eeepc->wwan3g_rfkill);
+		rfkill_destroy(eeepc->wwan3g_rfkill);
+		eeepc->wwan3g_rfkill = NULL;
+	}
+	if (eeepc->wimax_rfkill) {
+		rfkill_unregister(eeepc->wimax_rfkill);
+		rfkill_destroy(eeepc->wimax_rfkill);
+		eeepc->wimax_rfkill = NULL;
+	}
+}
+
+static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
+{
+	int result = 0;
+
+	mutex_init(&eeepc->hotplug_lock);
+
+	result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
+				  "eeepc-wlan", RFKILL_TYPE_WLAN,
+				  CM_ASL_WLAN);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
+	result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
+				  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
+				  CM_ASL_BLUETOOTH);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
+	result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
+				  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
+				  CM_ASL_3G);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
+	result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
+				  "eeepc-wimax", RFKILL_TYPE_WIMAX,
+				  CM_ASL_WIMAX);
+
+	if (result && result != -ENODEV)
+		goto exit;
+
+	if (eeepc->hotplug_disabled)
+		return 0;
+
+	result = eeepc_setup_pci_hotplug(eeepc);
+	/*
+	 * If we get -EBUSY then something else is handling the PCI hotplug -
+	 * don't fail in this case
+	 */
+	if (result == -EBUSY)
+		result = 0;
+
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
+	eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
+	/*
+	 * Refresh pci hotplug in case the rfkill state was changed during
+	 * setup.
+	 */
+	eeepc_rfkill_hotplug(eeepc);
+
+exit:
+	if (result && result != -ENODEV)
+		eeepc_rfkill_exit(eeepc);
+	return result;
+}
+
+/*
+ * Platform driver - hibernate/resume callbacks
+ */
 static int eeepc_hotk_thaw(struct device *device)
 {
-	if (ehotk->wlan_rfkill) {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
+
+	if (eeepc->wlan_rfkill) {
 		bool wlan;
 
 		/*
@@ -840,8 +886,8 @@ static int eeepc_hotk_thaw(struct device
 		 * during suspend.  Normally it restores it on resume, but
 		 * we should kick it ourselves in case hibernation is aborted.
 		 */
-		wlan = get_acpi(CM_ASL_WLAN);
-		set_acpi(CM_ASL_WLAN, wlan);
+		wlan = get_acpi(eeepc, CM_ASL_WLAN);
+		set_acpi(eeepc, CM_ASL_WLAN, wlan);
 	}
 
 	return 0;
@@ -849,70 +895,96 @@ static int eeepc_hotk_thaw(struct device
 
 static int eeepc_hotk_restore(struct device *device)
 {
+	struct eeepc_laptop *eeepc = dev_get_drvdata(device);
+
 	/* Refresh both wlan rfkill state and pci hotplug */
-	if (ehotk->wlan_rfkill)
-		eeepc_rfkill_hotplug();
+	if (eeepc->wlan_rfkill)
+		eeepc_rfkill_hotplug(eeepc);
 
-	if (ehotk->bluetooth_rfkill)
-		rfkill_set_sw_state(ehotk->bluetooth_rfkill,
-				    get_acpi(CM_ASL_BLUETOOTH) != 1);
-	if (ehotk->wwan3g_rfkill)
-		rfkill_set_sw_state(ehotk->wwan3g_rfkill,
-				    get_acpi(CM_ASL_3G) != 1);
-	if (ehotk->wimax_rfkill)
-		rfkill_set_sw_state(ehotk->wimax_rfkill,
-				    get_acpi(CM_ASL_WIMAX) != 1);
+	if (eeepc->bluetooth_rfkill)
+		rfkill_set_sw_state(eeepc->bluetooth_rfkill,
+				    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
+	if (eeepc->wwan3g_rfkill)
+		rfkill_set_sw_state(eeepc->wwan3g_rfkill,
+				    get_acpi(eeepc, CM_ASL_3G) != 1);
+	if (eeepc->wimax_rfkill)
+		rfkill_set_sw_state(eeepc->wimax_rfkill,
+				    get_acpi(eeepc, CM_ASL_WIMAX) != 1);
 
 	return 0;
 }
 
+static const struct dev_pm_ops eeepc_pm_ops = {
+	.thaw = eeepc_hotk_thaw,
+	.restore = eeepc_hotk_restore,
+};
+
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = EEEPC_LAPTOP_FILE,
+		.owner = THIS_MODULE,
+		.pm = &eeepc_pm_ops,
+	}
+};
+
 /*
- * Hwmon
+ * Hwmon device
  */
+
+#define EEEPC_EC_SC00      0x61
+#define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
+#define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
+#define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
+
+#define EEEPC_EC_SFB0      0xD0
+#define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
+
 static int eeepc_get_fan_pwm(void)
 {
-	int value = 0;
+	u8 value = 0;
 
-	read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
-	value = value * 255 / 100;
-	return (value);
+	ec_read(EEEPC_EC_FAN_PWM, &value);
+	return value * 255 / 100;
 }
 
 static void eeepc_set_fan_pwm(int value)
 {
 	value = SENSORS_LIMIT(value, 0, 255);
 	value = value * 100 / 255;
-	ec_write(EEEPC_EC_SC02, value);
+	ec_write(EEEPC_EC_FAN_PWM, value);
 }
 
 static int eeepc_get_fan_rpm(void)
 {
-	int high = 0;
-	int low = 0;
+	u8 high = 0;
+	u8 low = 0;
 
-	read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
-	read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
-	return (high << 8 | low);
+	ec_read(EEEPC_EC_FAN_HRPM, &high);
+	ec_read(EEEPC_EC_FAN_LRPM, &low);
+	return high << 8 | low;
 }
 
 static int eeepc_get_fan_ctrl(void)
 {
-	int value = 0;
+	u8 value = 0;
 
-	read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
-	return ((value & 0x02 ? 1 : 0));
+	ec_read(EEEPC_EC_FAN_CTRL, &value);
+	if (value & 0x02)
+		return 1; /* manual */
+	else
+		return 2; /* automatic */
 }
 
 static void eeepc_set_fan_ctrl(int manual)
 {
-	int value = 0;
+	u8 value = 0;
 
-	read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
-	if (manual)
+	ec_read(EEEPC_EC_FAN_CTRL, &value);
+	if (manual == 1)
 		value |= 0x02;
 	else
 		value &= ~0x02;
-	ec_write(EEEPC_EC_SFB3, value);
+	ec_write(EEEPC_EC_FAN_CTRL, value);
 }
 
 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
@@ -970,348 +1042,461 @@ static struct attribute_group hwmon_attr
 	.attrs = hwmon_attributes
 };
 
-/*
- * exit/init
- */
-static void eeepc_backlight_exit(void)
+static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
 {
-	if (eeepc_backlight_device)
-		backlight_device_unregister(eeepc_backlight_device);
-	eeepc_backlight_device = NULL;
+	struct device *hwmon;
+
+	hwmon = eeepc->hwmon_device;
+	if (!hwmon)
+		return;
+	sysfs_remove_group(&hwmon->kobj,
+			   &hwmon_attribute_group);
+	hwmon_device_unregister(hwmon);
+	eeepc->hwmon_device = NULL;
 }
 
-static void eeepc_rfkill_exit(void)
+static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
 {
-	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5");
-	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
-	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
-	if (ehotk->wlan_rfkill) {
-		rfkill_unregister(ehotk->wlan_rfkill);
-		rfkill_destroy(ehotk->wlan_rfkill);
-		ehotk->wlan_rfkill = NULL;
-	}
-	/*
-	 * Refresh pci hotplug in case the rfkill state was changed after
-	 * eeepc_unregister_rfkill_notifier()
-	 */
-	eeepc_rfkill_hotplug();
-	if (ehotk->hotplug_slot)
-		pci_hp_deregister(ehotk->hotplug_slot);
+	struct device *hwmon;
+	int result;
 
-	if (ehotk->bluetooth_rfkill) {
-		rfkill_unregister(ehotk->bluetooth_rfkill);
-		rfkill_destroy(ehotk->bluetooth_rfkill);
-		ehotk->bluetooth_rfkill = NULL;
-	}
-	if (ehotk->wwan3g_rfkill) {
-		rfkill_unregister(ehotk->wwan3g_rfkill);
-		rfkill_destroy(ehotk->wwan3g_rfkill);
-		ehotk->wwan3g_rfkill = NULL;
-	}
-	if (ehotk->wimax_rfkill) {
-		rfkill_unregister(ehotk->wimax_rfkill);
-		rfkill_destroy(ehotk->wimax_rfkill);
-		ehotk->wimax_rfkill = NULL;
+	hwmon = hwmon_device_register(&eeepc->platform_device->dev);
+	if (IS_ERR(hwmon)) {
+		pr_err("Could not register eeepc hwmon device\n");
+		eeepc->hwmon_device = NULL;
+		return PTR_ERR(hwmon);
 	}
+	eeepc->hwmon_device = hwmon;
+	result = sysfs_create_group(&hwmon->kobj,
+				    &hwmon_attribute_group);
+	if (result)
+		eeepc_hwmon_exit(eeepc);
+	return result;
 }
 
-static void eeepc_input_exit(void)
+/*
+ * Backlight device
+ */
+static int read_brightness(struct backlight_device *bd)
 {
-	if (ehotk->inputdev)
-		input_unregister_device(ehotk->inputdev);
+	struct eeepc_laptop *eeepc = bl_get_data(bd);
+
+	return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
 }
 
-static void eeepc_hwmon_exit(void)
+static int set_brightness(struct backlight_device *bd, int value)
 {
-	struct device *hwmon;
+	struct eeepc_laptop *eeepc = bl_get_data(bd);
 
-	hwmon = eeepc_hwmon_device;
-	if (!hwmon)
-		return ;
-	sysfs_remove_group(&hwmon->kobj,
-			   &hwmon_attribute_group);
-	hwmon_device_unregister(hwmon);
-	eeepc_hwmon_device = NULL;
+	return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
 }
 
-static int eeepc_new_rfkill(struct rfkill **rfkill,
-			    const char *name, struct device *dev,
-			    enum rfkill_type type, int cm)
+static int update_bl_status(struct backlight_device *bd)
 {
-	int result;
+	return set_brightness(bd, bd->props.brightness);
+}
 
-	result = get_acpi(cm);
-	if (result < 0)
-		return result;
+static struct backlight_ops eeepcbl_ops = {
+	.get_brightness = read_brightness,
+	.update_status = update_bl_status,
+};
 
-	*rfkill = rfkill_alloc(name, dev, type,
-			       &eeepc_rfkill_ops, (void *)(unsigned long)cm);
+static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
+{
+	struct backlight_device *bd = eeepc->backlight_device;
+	int old = bd->props.brightness;
 
-	if (!*rfkill)
-		return -EINVAL;
+	backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
 
-	rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
-	result = rfkill_register(*rfkill);
-	if (result) {
-		rfkill_destroy(*rfkill);
-		*rfkill = NULL;
-		return result;
+	return old;
+}
+
+static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
+{
+	struct backlight_device *bd;
+
+	bd = backlight_device_register(EEEPC_LAPTOP_FILE,
+				       &eeepc->platform_device->dev,
+				       eeepc, &eeepcbl_ops);
+	if (IS_ERR(bd)) {
+		pr_err("Could not register eeepc backlight device\n");
+		eeepc->backlight_device = NULL;
+		return PTR_ERR(bd);
 	}
+	eeepc->backlight_device = bd;
+	bd->props.max_brightness = 15;
+	bd->props.brightness = read_brightness(bd);
+	bd->props.power = FB_BLANK_UNBLANK;
+	backlight_update_status(bd);
 	return 0;
 }
 
+static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
+{
+	if (eeepc->backlight_device)
+		backlight_device_unregister(eeepc->backlight_device);
+	eeepc->backlight_device = NULL;
+}
+
 
-static int eeepc_rfkill_init(struct device *dev)
+/*
+ * Input device (i.e. hotkeys)
+ */
+static int eeepc_input_init(struct eeepc_laptop *eeepc)
 {
-	int result = 0;
+	struct input_dev *input;
+	int error;
 
-	mutex_init(&ehotk->hotplug_lock);
+	input = input_allocate_device();
+	if (!input) {
+		pr_info("Unable to allocate input device\n");
+		return -ENOMEM;
+	}
 
-	result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
-				  "eeepc-wlan", dev,
-				  RFKILL_TYPE_WLAN, CM_ASL_WLAN);
+	input->name = "Asus EeePC extra buttons";
+	input->phys = EEEPC_LAPTOP_FILE "/input0";
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &eeepc->platform_device->dev;
 
-	if (result && result != -ENODEV)
-		goto exit;
+	error = sparse_keymap_setup(input, eeepc_keymap, NULL);
+	if (error) {
+		pr_err("Unable to setup input device keymap\n");
+		goto err_free_dev;
+	}
 
-	result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
-				  "eeepc-bluetooth", dev,
-				  RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
+	error = input_register_device(input);
+	if (error) {
+		pr_err("Unable to register input device\n");
+		goto err_free_keymap;
+	}
 
-	if (result && result != -ENODEV)
-		goto exit;
+	eeepc->inputdev = input;
+	return 0;
 
-	result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
-				  "eeepc-wwan3g", dev,
-				  RFKILL_TYPE_WWAN, CM_ASL_3G);
+ err_free_keymap:
+	sparse_keymap_free(input);
+ err_free_dev:
+	input_free_device(input);
+	return error;
+}
 
-	if (result && result != -ENODEV)
-		goto exit;
+static void eeepc_input_exit(struct eeepc_laptop *eeepc)
+{
+	if (eeepc->inputdev) {
+		input_unregister_device(eeepc->inputdev);
+		kfree(eeepc->keymap);
+	}
+}
 
-	result = eeepc_new_rfkill(&ehotk->wimax_rfkill,
-				  "eeepc-wimax", dev,
-				  RFKILL_TYPE_WIMAX, CM_ASL_WIMAX);
+/*
+ * ACPI driver
+ */
+static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
+{
+	struct eeepc_laptop *eeepc = acpi_driver_data(device);
+	u16 count;
 
-	if (result && result != -ENODEV)
-		goto exit;
+	if (event > ACPI_MAX_SYS_NOTIFY)
+		return;
+	count = eeepc->event_count[event % 128]++;
+	acpi_bus_generate_proc_event(device, event, count);
+	acpi_bus_generate_netlink_event(device->pnp.device_class,
+					dev_name(&device->dev), event,
+					count);
+
+	/* Brightness events are special */
+	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
+
+		/* Ignore them completely if the acpi video driver is used */
+		if (eeepc->backlight_device != NULL) {
+			int old_brightness, new_brightness;
+
+			/* Update the backlight device. */
+			old_brightness = eeepc_backlight_notify(eeepc);
+
+			/* Convert event to keypress (obsolescent hack) */
+			new_brightness = event - NOTIFY_BRN_MIN;
+
+			if (new_brightness < old_brightness) {
+				event = NOTIFY_BRN_MIN; /* brightness down */
+			} else if (new_brightness > old_brightness) {
+				event = NOTIFY_BRN_MAX; /* brightness up */
+			} else {
+				/*
+				* no change in brightness - already at min/max,
+				* event will be desired value (or else ignored)
+				*/
+			}
+			sparse_keymap_report_event(eeepc->inputdev, event,
+						   1, true);
+		}
+	} else {
+		/* Everything else is a bona-fide keypress event */
+		sparse_keymap_report_event(eeepc->inputdev, event, 1, true);
+	}
+}
+
+static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
+{
+	const char *model;
+
+	model = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!model)
+		return;
 
-	result = eeepc_setup_pci_hotplug();
 	/*
-	 * If we get -EBUSY then something else is handling the PCI hotplug -
-	 * don't fail in this case
+	 * Blacklist for setting cpufv (cpu speed).
+	 *
+	 * EeePC 4G ("701") implements CFVS, but it is not supported
+	 * by the pre-installed OS, and the original option to change it
+	 * in the BIOS setup screen was removed in later versions.
+	 *
+	 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
+	 * this applies to all "701" models (4G/4G Surf/2G Surf).
+	 *
+	 * So Asus made a deliberate decision not to support it on this model.
+	 * We have several reports that using it can cause the system to hang
+	 *
+	 * The hang has also been reported on a "702" (Model name "8G"?).
+	 *
+	 * We avoid dmi_check_system() / dmi_match(), because they use
+	 * substring matching.  We don't want to affect the "701SD"
+	 * and "701SDX" models, because they do support S.H.E.
 	 */
-	if (result == -EBUSY)
-		result = 0;
+	if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
+		eeepc->cpufv_disabled = true;
+		pr_info("model %s does not officially support setting cpu "
+			"speed\n", model);
+		pr_info("cpufv disabled to avoid instability\n");
+	}
 
-	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5");
-	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
-	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
 	/*
-	 * Refresh pci hotplug in case the rfkill state was changed during
-	 * setup.
+	 * Blacklist for wlan hotplug
+	 *
+	 * Eeepc 1005HA doesn't work like others models and don't need the
+	 * hotplug code. In fact, current hotplug code seems to unplug another
+	 * device...
 	 */
-	eeepc_rfkill_hotplug();
-
-exit:
-	if (result && result != -ENODEV)
-		eeepc_rfkill_exit();
-	return result;
+	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) {
+		eeepc->hotplug_disabled = true;
+		pr_info("wlan hotplug disabled\n");
+	}
 }
 
-static int eeepc_backlight_init(struct device *dev)
+static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
 {
-	struct backlight_device *bd;
+	int dummy;
 
-	bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
-				       NULL, &eeepcbl_ops);
-	if (IS_ERR(bd)) {
-		pr_err("Could not register eeepc backlight device\n");
-		eeepc_backlight_device = NULL;
-		return PTR_ERR(bd);
+	/* Some BIOSes do not report cm although it is avaliable.
+	   Check if cm_getv[cm] works and, if yes, assume cm should be set. */
+	if (!(eeepc->cm_supported & (1 << cm))
+	    && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
+		pr_info("%s (%x) not reported by BIOS,"
+			" enabling anyway\n", name, 1 << cm);
+		eeepc->cm_supported |= 1 << cm;
 	}
-	eeepc_backlight_device = bd;
-	bd->props.max_brightness = 15;
-	bd->props.brightness = read_brightness(NULL);
-	bd->props.power = FB_BLANK_UNBLANK;
-	backlight_update_status(bd);
-	return 0;
 }
 
-static int eeepc_hwmon_init(struct device *dev)
+static void cmsg_quirks(struct eeepc_laptop *eeepc)
 {
-	struct device *hwmon;
-	int result;
-
-	hwmon = hwmon_device_register(dev);
-	if (IS_ERR(hwmon)) {
-		pr_err("Could not register eeepc hwmon device\n");
-		eeepc_hwmon_device = NULL;
-		return PTR_ERR(hwmon);
-	}
-	eeepc_hwmon_device = hwmon;
-	result = sysfs_create_group(&hwmon->kobj,
-				    &hwmon_attribute_group);
-	if (result)
-		eeepc_hwmon_exit();
-	return result;
+	cmsg_quirk(eeepc, CM_ASL_LID, "LID");
+	cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
+	cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
+	cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
 }
 
-static int eeepc_input_init(struct device *dev)
+static int eeepc_acpi_init(struct eeepc_laptop *eeepc,
+			   struct acpi_device *device)
 {
-	const struct key_entry *key;
+	unsigned int init_flags;
 	int result;
 
-	ehotk->inputdev = input_allocate_device();
-	if (!ehotk->inputdev) {
-		pr_info("Unable to allocate input device\n");
-		return -ENOMEM;
+	result = acpi_bus_get_status(device);
+	if (result)
+		return result;
+	if (!device->status.present) {
+		pr_err("Hotkey device not present, aborting\n");
+		return -ENODEV;
 	}
-	ehotk->inputdev->name = "Asus EeePC extra buttons";
-	ehotk->inputdev->dev.parent = dev;
-	ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
-	ehotk->inputdev->id.bustype = BUS_HOST;
-	ehotk->inputdev->getkeycode = eeepc_getkeycode;
-	ehotk->inputdev->setkeycode = eeepc_setkeycode;
 
-	for (key = eeepc_keymap; key->type != KE_END; key++) {
-		switch (key->type) {
-		case KE_KEY:
-			set_bit(EV_KEY, ehotk->inputdev->evbit);
-			set_bit(key->keycode, ehotk->inputdev->keybit);
-			break;
-		}
+	init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
+	pr_notice("Hotkey init flags 0x%x\n", init_flags);
+
+	if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
+		pr_err("Hotkey initialization failed\n");
+		return -ENODEV;
 	}
-	result = input_register_device(ehotk->inputdev);
-	if (result) {
-		pr_info("Unable to register input device\n");
-		input_free_device(ehotk->inputdev);
-		return result;
+
+	/* get control methods supported */
+	if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
+		pr_err("Get control methods supported failed\n");
+		return -ENODEV;
 	}
+	cmsg_quirks(eeepc);
+	pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
+
 	return 0;
 }
 
-static int __devinit eeepc_hotk_add(struct acpi_device *device)
+static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
 {
-	struct device *dev;
+	/*
+	 * If the following call to set_acpi() fails, it's because there's no
+	 * camera so we can ignore the error.
+	 */
+	if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
+		set_acpi(eeepc, CM_ASL_CAMERA, 1);
+}
+
+static bool eeepc_device_present;
+
+static int __devinit eeepc_acpi_add(struct acpi_device *device)
+{
+	struct eeepc_laptop *eeepc;
 	int result;
 
-	if (!device)
-		return -EINVAL;
-	pr_notice(EEEPC_HOTK_NAME "\n");
-	ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
-	if (!ehotk)
+	pr_notice(EEEPC_LAPTOP_NAME "\n");
+	eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
+	if (!eeepc)
 		return -ENOMEM;
-	ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
-	ehotk->handle = device->handle;
-	strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
-	strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
-	device->driver_data = ehotk;
-	ehotk->device = device;
+	eeepc->handle = device->handle;
+	strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
+	strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
+	device->driver_data = eeepc;
 
-	result = eeepc_hotk_check();
-	if (result)
-		goto fail_platform_driver;
-	eeepc_enable_camera();
+	eeepc->hotplug_disabled = hotplug_disabled;
 
-	/* Register platform stuff */
-	result = platform_driver_register(&platform_driver);
-	if (result)
-		goto fail_platform_driver;
-	platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
-	if (!platform_device) {
-		result = -ENOMEM;
-		goto fail_platform_device1;
-	}
-	result = platform_device_add(platform_device);
-	if (result)
-		goto fail_platform_device2;
-	result = sysfs_create_group(&platform_device->dev.kobj,
-				    &platform_attribute_group);
+	eeepc_dmi_check(eeepc);
+
+	result = eeepc_acpi_init(eeepc, device);
 	if (result)
-		goto fail_sysfs;
+		goto fail_platform;
+	eeepc_enable_camera(eeepc);
 
-	dev = &platform_device->dev;
+	/*
+	 * Register the platform device first.  It is used as a parent for the
+	 * sub-devices below.
+	 *
+	 * Note that if there are multiple instances of this ACPI device it
+	 * will bail out, because the platform device is registered with a
+	 * fixed name.  Of course it doesn't make sense to have more than one,
+	 * and machine-specific scripts find the fixed name convenient.  But
+	 * It's also good for us to exclude multiple instances because both
+	 * our hwmon and our wlan rfkill subdevice use global ACPI objects
+	 * (the EC and the wlan PCI slot respectively).
+	 */
+	result = eeepc_platform_init(eeepc);
+	if (result)
+		goto fail_platform;
 
 	if (!acpi_video_backlight_support()) {
-		result = eeepc_backlight_init(dev);
+		result = eeepc_backlight_init(eeepc);
 		if (result)
 			goto fail_backlight;
 	} else
-		pr_info("Backlight controlled by ACPI video "
-			"driver\n");
+		pr_info("Backlight controlled by ACPI video driver\n");
 
-	result = eeepc_input_init(dev);
+	result = eeepc_input_init(eeepc);
 	if (result)
 		goto fail_input;
 
-	result = eeepc_hwmon_init(dev);
+	result = eeepc_hwmon_init(eeepc);
 	if (result)
 		goto fail_hwmon;
 
-	result = eeepc_rfkill_init(dev);
+	result = eeepc_led_init(eeepc);
+	if (result)
+		goto fail_led;
+
+	result = eeepc_rfkill_init(eeepc);
 	if (result)
 		goto fail_rfkill;
 
+	eeepc_device_present = true;
 	return 0;
 
 fail_rfkill:
-	eeepc_hwmon_exit();
+	eeepc_led_exit(eeepc);
+fail_led:
+	eeepc_hwmon_exit(eeepc);
 fail_hwmon:
-	eeepc_input_exit();
+	eeepc_input_exit(eeepc);
 fail_input:
-	eeepc_backlight_exit();
+	eeepc_backlight_exit(eeepc);
 fail_backlight:
-	sysfs_remove_group(&platform_device->dev.kobj,
-			   &platform_attribute_group);
-fail_sysfs:
-	platform_device_del(platform_device);
-fail_platform_device2:
-	platform_device_put(platform_device);
-fail_platform_device1:
-	platform_driver_unregister(&platform_driver);
-fail_platform_driver:
-	kfree(ehotk);
+	eeepc_platform_exit(eeepc);
+fail_platform:
+	kfree(eeepc);
 
 	return result;
 }
 
-static int eeepc_hotk_remove(struct acpi_device *device, int type)
+static int eeepc_acpi_remove(struct acpi_device *device, int type)
 {
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	struct eeepc_laptop *eeepc = acpi_driver_data(device);
 
-	eeepc_backlight_exit();
-	eeepc_rfkill_exit();
-	eeepc_input_exit();
-	eeepc_hwmon_exit();
-	sysfs_remove_group(&platform_device->dev.kobj,
-			   &platform_attribute_group);
-	platform_device_unregister(platform_device);
-	platform_driver_unregister(&platform_driver);
+	eeepc_backlight_exit(eeepc);
+	eeepc_rfkill_exit(eeepc);
+	eeepc_input_exit(eeepc);
+	eeepc_hwmon_exit(eeepc);
+	eeepc_led_exit(eeepc);
+	eeepc_platform_exit(eeepc);
 
-	kfree(ehotk);
+	kfree(eeepc);
 	return 0;
 }
 
+
+static const struct acpi_device_id eeepc_device_ids[] = {
+	{EEEPC_ACPI_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
+
+static struct acpi_driver eeepc_acpi_driver = {
+	.name = EEEPC_LAPTOP_NAME,
+	.class = EEEPC_ACPI_CLASS,
+	.owner = THIS_MODULE,
+	.ids = eeepc_device_ids,
+	.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
+	.ops = {
+		.add = eeepc_acpi_add,
+		.remove = eeepc_acpi_remove,
+		.notify = eeepc_acpi_notify,
+	},
+};
+
+
 static int __init eeepc_laptop_init(void)
 {
 	int result;
 
-	if (acpi_disabled)
-		return -ENODEV;
-	result = acpi_bus_register_driver(&eeepc_hotk_driver);
+	result = platform_driver_register(&platform_driver);
 	if (result < 0)
 		return result;
-	if (!ehotk) {
-		acpi_bus_unregister_driver(&eeepc_hotk_driver);
-		return -ENODEV;
+
+	result = acpi_bus_register_driver(&eeepc_acpi_driver);
+	if (result < 0)
+		goto fail_acpi_driver;
+
+	if (!eeepc_device_present) {
+		result = -ENODEV;
+		goto fail_no_device;
 	}
+
 	return 0;
+
+fail_no_device:
+	acpi_bus_unregister_driver(&eeepc_acpi_driver);
+fail_acpi_driver:
+	platform_driver_unregister(&platform_driver);
+	return result;
 }
 
 static void __exit eeepc_laptop_exit(void)
 {
-	acpi_bus_unregister_driver(&eeepc_hotk_driver);
+	acpi_bus_unregister_driver(&eeepc_acpi_driver);
+	platform_driver_unregister(&platform_driver);
 }
 
 module_init(eeepc_laptop_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/fujitsu-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/fujitsu-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/fujitsu-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/fujitsu-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -164,7 +164,7 @@ struct fujitsu_hotkey_t {
 	struct input_dev *input;
 	char phys[32];
 	struct platform_device *pf_device;
-	struct kfifo *fifo;
+	struct kfifo fifo;
 	spinlock_t fifo_lock;
 	int rfkill_supported;
 	int rfkill_state;
@@ -376,8 +376,8 @@ static int get_lcd_level(void)
 
 	status =
 	    acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
-	if (status < 0)
-		return status;
+	if (ACPI_FAILURE(status))
+		return 0;
 
 	fujitsu->brightness_level = state & 0x0fffffff;
 
@@ -398,8 +398,8 @@ static int get_max_brightness(void)
 
 	status =
 	    acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
-	if (status < 0)
-		return status;
+	if (ACPI_FAILURE(status))
+		return -1;
 
 	fujitsu->max_brightness = state;
 
@@ -824,12 +824,10 @@ static int acpi_fujitsu_hotkey_add(struc
 
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
-	fujitsu_hotkey->fifo =
-	    kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
-			&fujitsu_hotkey->fifo_lock);
-	if (IS_ERR(fujitsu_hotkey->fifo)) {
+	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
+			GFP_KERNEL);
+	if (error) {
 		printk(KERN_ERR "kfifo_alloc failed\n");
-		error = PTR_ERR(fujitsu_hotkey->fifo);
 		goto err_stop;
 	}
 
@@ -934,7 +932,7 @@ err_unregister_input_dev:
 err_free_input_dev:
 	input_free_device(input);
 err_free_fifo:
-	kfifo_free(fujitsu_hotkey->fifo);
+	kfifo_free(&fujitsu_hotkey->fifo);
 err_stop:
 	return result;
 }
@@ -956,7 +954,7 @@ static int acpi_fujitsu_hotkey_remove(st
 
 	input_free_device(input);
 
-	kfifo_free(fujitsu_hotkey->fifo);
+	kfifo_free(&fujitsu_hotkey->fifo);
 
 	fujitsu_hotkey->acpi_handle = NULL;
 
@@ -1008,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(s
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put(fujitsu_hotkey->fifo,
+				status = kfifo_in_locked(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
-						   sizeof(keycode));
+						   sizeof(keycode),
+						   &fujitsu_hotkey->fifo_lock);
 				if (status != sizeof(keycode)) {
 					vdbg_printk(FUJLAPTOP_DBG_WARN,
 					    "Could not push keycode [0x%x]\n",
@@ -1021,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(s
 				}
 			} else if (keycode == 0) {
 				while ((status =
-					kfifo_get
-					(fujitsu_hotkey->fifo, (unsigned char *)
-					 &keycode_r,
-					 sizeof
-					 (keycode_r))) == sizeof(keycode_r)) {
+					kfifo_out_locked(
+					 &fujitsu_hotkey->fifo,
+					 (unsigned char *) &keycode_r,
+					 sizeof(keycode_r),
+					 &fujitsu_hotkey->fifo_lock))
+					 == sizeof(keycode_r)) {
 					input_report_key(input, keycode_r, 0);
 					input_sync(input);
 					vdbg_printk(FUJLAPTOP_DBG_TRACE,
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/hp-wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/hp-wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/hp-wmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/hp-wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,12 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE9
 #define HPWMI_WIRELESS_QUERY 0x5
 #define HPWMI_HOTKEY_QUERY 0xc
 
+enum hp_wmi_radio {
+	HPWMI_WIFI = 0,
+	HPWMI_BLUETOOTH = 1,
+	HPWMI_WWAN = 2,
+};
+
 static int __init hp_wmi_bios_setup(struct platform_device *device);
 static int __exit hp_wmi_bios_remove(struct platform_device *device);
 static int hp_wmi_resume_handler(struct device *device);
@@ -94,7 +100,7 @@ static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
 
-static struct dev_pm_ops hp_wmi_pm_ops = {
+static const struct dev_pm_ops hp_wmi_pm_ops = {
 	.resume  = hp_wmi_resume_handler,
 	.restore  = hp_wmi_resume_handler,
 };
@@ -128,10 +134,15 @@ static int hp_wmi_perform_query(int quer
 
 	obj = output.pointer;
 
-	if (!obj || obj->type != ACPI_TYPE_BUFFER)
+	if (!obj)
 		return -EINVAL;
+	else if (obj->type != ACPI_TYPE_BUFFER) {
+		kfree(obj);
+		return -EINVAL;
+	}
 
 	bios_return = *((struct bios_return *)obj->buffer.pointer);
+	kfree(obj);
 	if (bios_return.return_code > 0)
 		return bios_return.return_code * -1;
 	else
@@ -175,8 +186,8 @@ static int hp_wmi_tablet_state(void)
 
 static int hp_wmi_set_block(void *data, bool blocked)
 {
-	unsigned long b = (unsigned long) data;
-	int query = BIT(b + 8) | ((!blocked) << b);
+	enum hp_wmi_radio r = (enum hp_wmi_radio) data;
+	int query = BIT(r + 8) | ((!blocked) << r);
 
 	return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
 }
@@ -185,31 +196,23 @@ static const struct rfkill_ops hp_wmi_rf
 	.set_block = hp_wmi_set_block,
 };
 
-static bool hp_wmi_wifi_state(void)
-{
-	int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
-
-	if (wireless & 0x100)
-		return false;
-	else
-		return true;
-}
-
-static bool hp_wmi_bluetooth_state(void)
+static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
 {
 	int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
+	int mask = 0x200 << (r * 8);
 
-	if (wireless & 0x10000)
+	if (wireless & mask)
 		return false;
 	else
 		return true;
 }
 
-static bool hp_wmi_wwan_state(void)
+static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
 {
 	int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
+	int mask = 0x800 << (r * 8);
 
-	if (wireless & 0x1000000)
+	if (wireless & mask)
 		return false;
 	else
 		return true;
@@ -334,49 +337,62 @@ static void hp_wmi_notify(u32 value, voi
 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
 	static struct key_entry *key;
 	union acpi_object *obj;
+	int eventcode;
+	acpi_status status;
 
-	wmi_get_event_data(value, &response);
+	status = wmi_get_event_data(value, &response);
+	if (status != AE_OK) {
+		printk(KERN_INFO "hp-wmi: bad event status 0x%x\n", status);
+		return;
+	}
 
 	obj = (union acpi_object *)response.pointer;
 
-	if (obj && obj->type == ACPI_TYPE_BUFFER && obj->buffer.length == 8) {
-		int eventcode = *((u8 *) obj->buffer.pointer);
-		if (eventcode == 0x4)
-			eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
-							 0);
-		key = hp_wmi_get_entry_by_scancode(eventcode);
-		if (key) {
-			switch (key->type) {
-			case KE_KEY:
-				input_report_key(hp_wmi_input_dev,
-						 key->keycode, 1);
-				input_sync(hp_wmi_input_dev);
-				input_report_key(hp_wmi_input_dev,
-						 key->keycode, 0);
-				input_sync(hp_wmi_input_dev);
-				break;
-			}
-		} else if (eventcode == 0x1) {
-			input_report_switch(hp_wmi_input_dev, SW_DOCK,
-					    hp_wmi_dock_state());
-			input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
-					    hp_wmi_tablet_state());
+	if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
+		printk(KERN_INFO "HP WMI: Unknown response received\n");
+		kfree(obj);
+		return;
+	}
+
+	eventcode = *((u8 *) obj->buffer.pointer);
+	kfree(obj);
+	if (eventcode == 0x4)
+		eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
+						0);
+	key = hp_wmi_get_entry_by_scancode(eventcode);
+	if (key) {
+		switch (key->type) {
+		case KE_KEY:
+			input_report_key(hp_wmi_input_dev,
+					 key->keycode, 1);
 			input_sync(hp_wmi_input_dev);
-		} else if (eventcode == 0x5) {
-			if (wifi_rfkill)
-				rfkill_set_sw_state(wifi_rfkill,
-						    hp_wmi_wifi_state());
-			if (bluetooth_rfkill)
-				rfkill_set_sw_state(bluetooth_rfkill,
-						    hp_wmi_bluetooth_state());
-			if (wwan_rfkill)
-				rfkill_set_sw_state(wwan_rfkill,
-						    hp_wmi_wwan_state());
-		} else
-			printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
-			       eventcode);
+			input_report_key(hp_wmi_input_dev,
+					 key->keycode, 0);
+			input_sync(hp_wmi_input_dev);
+			break;
+		}
+	} else if (eventcode == 0x1) {
+		input_report_switch(hp_wmi_input_dev, SW_DOCK,
+				    hp_wmi_dock_state());
+		input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+				    hp_wmi_tablet_state());
+		input_sync(hp_wmi_input_dev);
+	} else if (eventcode == 0x5) {
+		if (wifi_rfkill)
+			rfkill_set_states(wifi_rfkill,
+					  hp_wmi_get_sw_state(HPWMI_WIFI),
+					  hp_wmi_get_hw_state(HPWMI_WIFI));
+		if (bluetooth_rfkill)
+			rfkill_set_states(bluetooth_rfkill,
+					  hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
+					  hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
+		if (wwan_rfkill)
+			rfkill_set_states(wwan_rfkill,
+					  hp_wmi_get_sw_state(HPWMI_WWAN),
+					  hp_wmi_get_hw_state(HPWMI_WWAN));
 	} else
-		printk(KERN_INFO "HP WMI: Unknown response received\n");
+		printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
+			eventcode);
 }
 
 static int __init hp_wmi_input_setup(void)
@@ -455,7 +471,11 @@ static int __init hp_wmi_bios_setup(stru
 		wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
 					   RFKILL_TYPE_WLAN,
 					   &hp_wmi_rfkill_ops,
-					   (void *) 0);
+					   (void *) HPWMI_WIFI);
+		rfkill_init_sw_state(wifi_rfkill,
+				     hp_wmi_get_sw_state(HPWMI_WIFI));
+		rfkill_set_hw_state(wifi_rfkill,
+				    hp_wmi_get_hw_state(HPWMI_WIFI));
 		err = rfkill_register(wifi_rfkill);
 		if (err)
 			goto register_wifi_error;
@@ -465,7 +485,11 @@ static int __init hp_wmi_bios_setup(stru
 		bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
 						RFKILL_TYPE_BLUETOOTH,
 						&hp_wmi_rfkill_ops,
-						(void *) 1);
+						(void *) HPWMI_BLUETOOTH);
+		rfkill_init_sw_state(bluetooth_rfkill,
+				     hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
+		rfkill_set_hw_state(bluetooth_rfkill,
+				    hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
 		err = rfkill_register(bluetooth_rfkill);
 		if (err)
 			goto register_bluetooth_error;
@@ -475,7 +499,11 @@ static int __init hp_wmi_bios_setup(stru
 		wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
 					   RFKILL_TYPE_WWAN,
 					   &hp_wmi_rfkill_ops,
-					   (void *) 2);
+					   (void *) HPWMI_WWAN);
+		rfkill_init_sw_state(wwan_rfkill,
+				     hp_wmi_get_sw_state(HPWMI_WWAN));
+		rfkill_set_hw_state(wwan_rfkill,
+				    hp_wmi_get_hw_state(HPWMI_WWAN));
 		err = rfkill_register(wwan_rfkill);
 		if (err)
 			goto register_wwan_err;
@@ -533,6 +561,19 @@ static int hp_wmi_resume_handler(struct
 		input_sync(hp_wmi_input_dev);
 	}
 
+	if (wifi_rfkill)
+		rfkill_set_states(wifi_rfkill,
+				  hp_wmi_get_sw_state(HPWMI_WIFI),
+				  hp_wmi_get_hw_state(HPWMI_WIFI));
+	if (bluetooth_rfkill)
+		rfkill_set_states(bluetooth_rfkill,
+				  hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
+				  hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
+	if (wwan_rfkill)
+		rfkill_set_states(wwan_rfkill,
+				  hp_wmi_get_sw_state(HPWMI_WWAN),
+				  hp_wmi_get_hw_state(HPWMI_WWAN));
+
 	return 0;
 }
 
@@ -543,7 +584,7 @@ static int __init hp_wmi_init(void)
 	if (wmi_has_guid(HPWMI_EVENT_GUID)) {
 		err = wmi_install_notify_handler(HPWMI_EVENT_GUID,
 						 hp_wmi_notify, NULL);
-		if (!err)
+		if (ACPI_SUCCESS(err))
 			hp_wmi_input_setup();
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/intel_menlow.c linux-libre-2.6.33-gnu1/drivers/platform/x86/intel_menlow.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/intel_menlow.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/intel_menlow.c	2010-02-24 13:52:17.000000000 -0500
@@ -510,7 +510,7 @@ static int __init intel_menlow_module_in
 	/* Looking for sensors in each ACPI thermal zone */
 	status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT,
 				     ACPI_UINT32_MAX,
-				     intel_menlow_register_sensor, NULL, NULL);
+				     intel_menlow_register_sensor, NULL, NULL, NULL);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/Kconfig linux-libre-2.6.33-gnu1/drivers/platform/x86/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -231,8 +231,36 @@ config THINKPAD_ACPI
 
 	  This driver was formerly known as ibm-acpi.
 
+	  Extra functionality will be available if the rfkill (CONFIG_RFKILL)
+	  and/or ALSA (CONFIG_SND) subsystems are available in the kernel.
+	  Note that if you want ThinkPad-ACPI to be built-in instead of
+	  modular, ALSA and rfkill will also have to be built-in.
+
 	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
 
+config THINKPAD_ACPI_ALSA_SUPPORT
+	bool "Console audio control ALSA interface"
+	depends on THINKPAD_ACPI
+	depends on SND
+	depends on SND = y || THINKPAD_ACPI = SND
+	default y
+	---help---
+	  Enables monitoring of the built-in console audio output control
+	  (headphone and speakers), which is operated by the mute and (in
+	  some ThinkPad models) volume hotkeys.
+
+	  If this option is enabled, ThinkPad-ACPI will export an ALSA card
+	  with a single read-only mixer control, which should be used for
+	  on-screen-display feedback purposes by the Desktop Environment.
+
+	  Optionally, the driver will also allow software control (the
+	  ALSA mixer will be made read-write).  Please refer to the driver
+	  documentation for details.
+
+	  All IBM models have both volume and mute control.  Newer Lenovo
+	  models only have mute control (the volume hotkeys are just normal
+	  keys and volume control is done through the main HDA mixer).
+
 config THINKPAD_ACPI_DEBUGFACILITIES
 	bool "Maintainer debug facilities"
 	depends on THINKPAD_ACPI
@@ -334,6 +362,9 @@ config EEEPC_LAPTOP
 	depends on HOTPLUG_PCI
 	select BACKLIGHT_CLASS_DEVICE
 	select HWMON
+	select LEDS_CLASS
+	select NEW_LEDS
+	select INPUT_SPARSEKMAP
 	---help---
 	  This driver supports the Fn-Fx keys on Eee PC laptops.
 
@@ -365,6 +396,18 @@ config ACPI_WMI
 	  It is safe to enable this driver even if your DSDT doesn't define
 	  any ACPI-WMI devices.
 
+config MSI_WMI
+	tristate "MSI WMI extras"
+	depends on ACPI_WMI
+	depends on INPUT
+	depends on BACKLIGHT_CLASS_DEVICE
+	select INPUT_SPARSEKMAP
+	help
+	 Say Y here if you want to support WMI-based hotkeys on MSI laptops.
+
+	 To compile this driver as a module, choose M here: the module will
+	 be called msi-wmi.
+
 config ACPI_ASUS
 	tristate "ASUS/Medion Laptop Extras (DEPRECATED)"
 	depends on ACPI
@@ -435,4 +478,31 @@ config ACPI_TOSHIBA
 
 	  If you have a legacy free Toshiba laptop (such as the Libretto L1
 	  series), say Y.
+
+config TOSHIBA_BT_RFKILL
+	tristate "Toshiba Bluetooth RFKill switch support"
+	depends on ACPI
+	---help---
+	  This driver adds support for Bluetooth events for the RFKill
+	  switch on modern Toshiba laptops with full ACPI support and
+	  an RFKill switch.
+
+	  This driver handles RFKill events for the TOS6205 Bluetooth,
+	  and re-enables it when the switch is set back to the 'on'
+	  position.
+
+	  If you have a modern Toshiba laptop with a Bluetooth and an
+	  RFKill switch (such as the Portege R500), say Y.
+
+config ACPI_CMPC
+	tristate "CMPC Laptop Extras"
+	depends on X86 && ACPI
+	select INPUT
+	select BACKLIGHT_CLASS_DEVICE
+	default n
+	help
+	  Support for Intel Classmate PC ACPI devices, including some
+	  keys as input device, backlight device, tablet and accelerometer
+	  devices.
+
 endif # X86_PLATFORM_DEVICES
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/Makefile linux-libre-2.6.33-gnu1/drivers/platform/x86/Makefile
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -5,6 +5,7 @@
 obj-$(CONFIG_ASUS_LAPTOP)	+= asus-laptop.o
 obj-$(CONFIG_EEEPC_LAPTOP)	+= eeepc-laptop.o
 obj-$(CONFIG_MSI_LAPTOP)	+= msi-laptop.o
+obj-$(CONFIG_ACPI_CMPC)		+= classmate-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)	+= compal-laptop.o
 obj-$(CONFIG_DELL_LAPTOP)	+= dell-laptop.o
 obj-$(CONFIG_DELL_WMI)		+= dell-wmi.o
@@ -18,6 +19,8 @@ obj-$(CONFIG_FUJITSU_LAPTOP)	+= fujitsu-
 obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
 obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
 obj-$(CONFIG_ACPI_WMI)		+= wmi.o
+obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o
 obj-$(CONFIG_ACPI_ASUS)		+= asus_acpi.o
 obj-$(CONFIG_TOPSTAR_LAPTOP)	+= topstar-laptop.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
+obj-$(CONFIG_TOSHIBA_BT_RFKILL)	+= toshiba_bluetooth.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/msi-wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/msi-wmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/msi-wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,288 @@
+/*
+ * MSI WMI hotkeys
+ *
+ * Copyright (C) 2009 Novell <trenn@suse.de>
+ *
+ * Most stuff taken over from hp-wmi
+ *
+ *  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/kernel.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/acpi.h>
+#include <linux/backlight.h>
+
+MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
+MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45");
+MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
+
+#define DRV_NAME "msi-wmi"
+#define DRV_PFX DRV_NAME ": "
+
+#define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45"
+#define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"
+
+#define dprintk(msg...) pr_debug(DRV_PFX msg)
+
+#define KEYCODE_BASE 0xD0
+#define MSI_WMI_BRIGHTNESSUP   KEYCODE_BASE
+#define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1)
+#define MSI_WMI_VOLUMEUP       (KEYCODE_BASE + 2)
+#define MSI_WMI_VOLUMEDOWN     (KEYCODE_BASE + 3)
+static struct key_entry msi_wmi_keymap[] = {
+	{ KE_KEY, MSI_WMI_BRIGHTNESSUP,   {KEY_BRIGHTNESSUP} },
+	{ KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} },
+	{ KE_KEY, MSI_WMI_VOLUMEUP,       {KEY_VOLUMEUP} },
+	{ KE_KEY, MSI_WMI_VOLUMEDOWN,     {KEY_VOLUMEDOWN} },
+	{ KE_END, 0}
+};
+static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1];
+
+struct backlight_device *backlight;
+
+static int backlight_map[] = { 0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF };
+
+static struct input_dev *msi_wmi_input_dev;
+
+static int msi_wmi_query_block(int instance, int *ret)
+{
+	acpi_status status;
+	union acpi_object *obj;
+
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	status = wmi_query_block(MSIWMI_BIOS_GUID, instance, &output);
+
+	obj = output.pointer;
+
+	if (!obj || obj->type != ACPI_TYPE_INTEGER) {
+		if (obj) {
+			printk(KERN_ERR DRV_PFX "query block returned object "
+			       "type: %d - buffer length:%d\n", obj->type,
+			       obj->type == ACPI_TYPE_BUFFER ?
+			       obj->buffer.length : 0);
+		}
+		kfree(obj);
+		return -EINVAL;
+	}
+	*ret = obj->integer.value;
+	kfree(obj);
+	return 0;
+}
+
+static int msi_wmi_set_block(int instance, int value)
+{
+	acpi_status status;
+
+	struct acpi_buffer input = { sizeof(int), &value };
+
+	dprintk("Going to set block of instance: %d - value: %d\n",
+		instance, value);
+
+	status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input);
+
+	return ACPI_SUCCESS(status) ? 0 : 1;
+}
+
+static int bl_get(struct backlight_device *bd)
+{
+	int level, err, ret;
+
+	/* Instance 1 is "get backlight", cmp with DSDT */
+	err = msi_wmi_query_block(1, &ret);
+	if (err) {
+		printk(KERN_ERR DRV_PFX "Could not query backlight: %d\n", err);
+		return -EINVAL;
+	}
+	dprintk("Get: Query block returned: %d\n", ret);
+	for (level = 0; level < ARRAY_SIZE(backlight_map); level++) {
+		if (backlight_map[level] == ret) {
+			dprintk("Current backlight level: 0x%X - index: %d\n",
+				backlight_map[level], level);
+			break;
+		}
+	}
+	if (level == ARRAY_SIZE(backlight_map)) {
+		printk(KERN_ERR DRV_PFX "get: Invalid brightness value: 0x%X\n",
+		       ret);
+		return -EINVAL;
+	}
+	return level;
+}
+
+static int bl_set_status(struct backlight_device *bd)
+{
+	int bright = bd->props.brightness;
+	if (bright >= ARRAY_SIZE(backlight_map) || bright < 0)
+		return -EINVAL;
+
+	/* Instance 0 is "set backlight" */
+	return msi_wmi_set_block(0, backlight_map[bright]);
+}
+
+static struct backlight_ops msi_backlight_ops = {
+	.get_brightness	= bl_get,
+	.update_status	= bl_set_status,
+};
+
+static void msi_wmi_notify(u32 value, void *context)
+{
+	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+	static struct key_entry *key;
+	union acpi_object *obj;
+	ktime_t cur;
+	acpi_status status;
+
+	status = wmi_get_event_data(value, &response);
+	if (status != AE_OK) {
+		printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status);
+		return;
+	}
+
+	obj = (union acpi_object *)response.pointer;
+
+	if (obj && obj->type == ACPI_TYPE_INTEGER) {
+		int eventcode = obj->integer.value;
+		dprintk("Eventcode: 0x%x\n", eventcode);
+		key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev,
+				eventcode);
+		if (key) {
+			ktime_t diff;
+			cur = ktime_get_real();
+			diff = ktime_sub(cur, last_pressed[key->code -
+					KEYCODE_BASE]);
+			/* Ignore event if the same event happened in a 50 ms
+			   timeframe -> Key press may result in 10-20 GPEs */
+			if (ktime_to_us(diff) < 1000 * 50) {
+				dprintk("Suppressed key event 0x%X - "
+					"Last press was %lld us ago\n",
+					 key->code, ktime_to_us(diff));
+				return;
+			}
+			last_pressed[key->code - KEYCODE_BASE] = cur;
+
+			if (key->type == KE_KEY &&
+			/* Brightness is served via acpi video driver */
+			(!acpi_video_backlight_support() ||
+			(key->code != MSI_WMI_BRIGHTNESSUP &&
+			key->code != MSI_WMI_BRIGHTNESSDOWN))) {
+				dprintk("Send key: 0x%X - "
+					"Input layer keycode: %d\n", key->code,
+					 key->keycode);
+				sparse_keymap_report_entry(msi_wmi_input_dev,
+						key, 1, true);
+			}
+		} else
+			printk(KERN_INFO "Unknown key pressed - %x\n",
+			       eventcode);
+	} else
+		printk(KERN_INFO DRV_PFX "Unknown event received\n");
+	kfree(response.pointer);
+}
+
+static int __init msi_wmi_input_setup(void)
+{
+	int err;
+
+	msi_wmi_input_dev = input_allocate_device();
+	if (!msi_wmi_input_dev)
+		return -ENOMEM;
+
+	msi_wmi_input_dev->name = "MSI WMI hotkeys";
+	msi_wmi_input_dev->phys = "wmi/input0";
+	msi_wmi_input_dev->id.bustype = BUS_HOST;
+
+	err = sparse_keymap_setup(msi_wmi_input_dev, msi_wmi_keymap, NULL);
+	if (err)
+		goto err_free_dev;
+
+	err = input_register_device(msi_wmi_input_dev);
+
+	if (err)
+		goto err_free_keymap;
+
+	memset(last_pressed, 0, sizeof(last_pressed));
+
+	return 0;
+
+err_free_keymap:
+	sparse_keymap_free(msi_wmi_input_dev);
+err_free_dev:
+	input_free_device(msi_wmi_input_dev);
+	return err;
+}
+
+static int __init msi_wmi_init(void)
+{
+	int err;
+
+	if (!wmi_has_guid(MSIWMI_EVENT_GUID)) {
+		printk(KERN_ERR
+		       "This machine doesn't have MSI-hotkeys through WMI\n");
+		return -ENODEV;
+	}
+	err = wmi_install_notify_handler(MSIWMI_EVENT_GUID,
+			msi_wmi_notify, NULL);
+	if (ACPI_FAILURE(err))
+		return -EINVAL;
+
+	err = msi_wmi_input_setup();
+	if (err)
+		goto err_uninstall_notifier;
+
+	if (!acpi_video_backlight_support()) {
+		backlight = backlight_device_register(DRV_NAME,
+				NULL, NULL, &msi_backlight_ops);
+		if (IS_ERR(backlight))
+			goto err_free_input;
+
+		backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
+		err = bl_get(NULL);
+		if (err < 0)
+			goto err_free_backlight;
+
+		backlight->props.brightness = err;
+	}
+	dprintk("Event handler installed\n");
+
+	return 0;
+
+err_free_backlight:
+	backlight_device_unregister(backlight);
+err_free_input:
+	input_unregister_device(msi_wmi_input_dev);
+err_uninstall_notifier:
+	wmi_remove_notify_handler(MSIWMI_EVENT_GUID);
+	return err;
+}
+
+static void __exit msi_wmi_exit(void)
+{
+	if (wmi_has_guid(MSIWMI_EVENT_GUID)) {
+		wmi_remove_notify_handler(MSIWMI_EVENT_GUID);
+		sparse_keymap_free(msi_wmi_input_dev);
+		input_unregister_device(msi_wmi_input_dev);
+		backlight_device_unregister(backlight);
+	}
+}
+
+module_init(msi_wmi_init);
+module_exit(msi_wmi_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/sony-laptop.c linux-libre-2.6.33-gnu1/drivers/platform/x86/sony-laptop.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/sony-laptop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/sony-laptop.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,6 +131,7 @@ enum sony_nc_rfkill {
 	N_SONY_RFKILL,
 };
 
+static int sony_rfkill_handle;
 static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
 static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900};
 static void sony_nc_rfkill_update(void);
@@ -142,7 +143,7 @@ struct sony_laptop_input_s {
 	atomic_t		users;
 	struct input_dev	*jog_dev;
 	struct input_dev	*key_dev;
-	struct kfifo		*fifo;
+	struct kfifo		fifo;
 	spinlock_t		fifo_lock;
 	struct workqueue_struct	*wq;
 };
@@ -232,6 +233,7 @@ static int sony_laptop_input_index[] = {
 	56,	/* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
 	57,	/* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
 	-1,	/* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
+	58,	/* 72 SONYPI_EVENT_MEDIA_PRESSED */
 };
 
 static int sony_laptop_input_keycode_map[] = {
@@ -293,6 +295,7 @@ static int sony_laptop_input_keycode_map
 	KEY_F15,	/* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
 	KEY_VOLUMEUP,	/* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
 	KEY_VOLUMEDOWN,	/* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+	KEY_MEDIA,	/* 58 SONYPI_EVENT_MEDIA_PRESSED */
 };
 
 /* release buttons after a short delay if pressed */
@@ -300,8 +303,9 @@ static void do_sony_laptop_release_key(s
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+			sizeof(kp), &sony_laptop_input.fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -362,8 +366,9 @@ static void sony_laptop_report_input_eve
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put(sony_laptop_input.fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_in_locked(&sony_laptop_input.fifo,
+			  (unsigned char *)&kp, sizeof(kp),
+			  &sony_laptop_input.fifo_lock);
 
 		if (!work_pending(&sony_laptop_release_key_work))
 			queue_work(sony_laptop_input.wq,
@@ -385,12 +390,10 @@ static int sony_laptop_setup_input(struc
 
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
-	sony_laptop_input.fifo =
-		kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-			    &sony_laptop_input.fifo_lock);
-	if (IS_ERR(sony_laptop_input.fifo)) {
+	error =
+	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-		error = PTR_ERR(sony_laptop_input.fifo);
 		goto err_dec_users;
 	}
 
@@ -474,7 +477,7 @@ err_destroy_wq:
 	destroy_workqueue(sony_laptop_input.wq);
 
 err_free_kfifo:
-	kfifo_free(sony_laptop_input.fifo);
+	kfifo_free(&sony_laptop_input.fifo);
 
 err_dec_users:
 	atomic_dec(&sony_laptop_input.users);
@@ -500,7 +503,7 @@ static void sony_laptop_remove_input(voi
 	}
 
 	destroy_workqueue(sony_laptop_input.wq);
-	kfifo_free(sony_laptop_input.fifo);
+	kfifo_free(&sony_laptop_input.fifo);
 }
 
 /*********** Platform Device ***********/
@@ -890,6 +893,8 @@ static struct sony_nc_event sony_100_eve
 	{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
 	{ 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0xa1, SONYPI_EVENT_MEDIA_PRESSED },
+	{ 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0, 0 },
 };
 
@@ -961,7 +966,7 @@ static void sony_nc_notify(struct acpi_d
 				else
 					sony_laptop_report_input_event(ev);
 			}
-		} else if (sony_find_snc_handle(0x124) == ev) {
+		} else if (sony_find_snc_handle(sony_rfkill_handle) == ev) {
 			sony_nc_rfkill_update();
 			return;
 		}
@@ -1067,7 +1072,7 @@ static int sony_nc_rfkill_set(void *data
 	if (!blocked)
 		argument |= 0xff0000;
 
-	return sony_call_snc_handle(0x124, argument, &result);
+	return sony_call_snc_handle(sony_rfkill_handle, argument, &result);
 }
 
 static const struct rfkill_ops sony_rfkill_ops = {
@@ -1110,7 +1115,7 @@ static int sony_nc_setup_rfkill(struct a
 	if (!rfk)
 		return -ENOMEM;
 
-	sony_call_snc_handle(0x124, 0x200, &result);
+	sony_call_snc_handle(sony_rfkill_handle, 0x200, &result);
 	hwblock = !(result & 0x1);
 	rfkill_set_hw_state(rfk, hwblock);
 
@@ -1129,7 +1134,7 @@ static void sony_nc_rfkill_update()
 	int result;
 	bool hwblock;
 
-	sony_call_snc_handle(0x124, 0x200, &result);
+	sony_call_snc_handle(sony_rfkill_handle, 0x200, &result);
 	hwblock = !(result & 0x1);
 
 	for (i = 0; i < N_SONY_RFKILL; i++) {
@@ -1145,36 +1150,82 @@ static void sony_nc_rfkill_update()
 			continue;
 		}
 
-		sony_call_snc_handle(0x124, argument, &result);
+		sony_call_snc_handle(sony_rfkill_handle, argument, &result);
 		rfkill_set_states(sony_rfkill_devices[i],
 				  !(result & 0xf), false);
 	}
 }
 
-static int sony_nc_rfkill_setup(struct acpi_device *device)
+static void sony_nc_rfkill_setup(struct acpi_device *device)
 {
-	int result, ret;
+	int offset;
+	u8 dev_code, i;
+	acpi_status status;
+	struct acpi_object_list params;
+	union acpi_object in_obj;
+	union acpi_object *device_enum;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
-	if (sony_find_snc_handle(0x124) == -1)
-		return -1;
+	offset = sony_find_snc_handle(0x124);
+	if (offset == -1) {
+		offset = sony_find_snc_handle(0x135);
+		if (offset == -1)
+			return;
+		else
+			sony_rfkill_handle = 0x135;
+	} else
+		sony_rfkill_handle = 0x124;
+	dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle);
 
-	ret = sony_call_snc_handle(0x124, 0xb00, &result);
-	if (ret) {
-		printk(KERN_INFO DRV_PFX
-		       "Unable to enumerate rfkill devices: %x\n", ret);
-		return ret;
+	/* need to read the whole buffer returned by the acpi call to SN06
+	 * here otherwise we may miss some features
+	 */
+	params.count = 1;
+	params.pointer = &in_obj;
+	in_obj.type = ACPI_TYPE_INTEGER;
+	in_obj.integer.value = offset;
+	status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", &params,
+			&buffer);
+	if (ACPI_FAILURE(status)) {
+		dprintk("Radio device enumeration failed\n");
+		return;
 	}
 
-	if (result & 0x1)
-		sony_nc_setup_rfkill(device, SONY_WIFI);
-	if (result & 0x2)
-		sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
-	if (result & 0x1c)
-		sony_nc_setup_rfkill(device, SONY_WWAN);
-	if (result & 0x20)
-		sony_nc_setup_rfkill(device, SONY_WIMAX);
+	device_enum = (union acpi_object *) buffer.pointer;
+	if (!device_enum || device_enum->type != ACPI_TYPE_BUFFER) {
+		printk(KERN_ERR "Invalid SN06 return object 0x%.2x\n",
+				device_enum->type);
+		goto out_no_enum;
+	}
 
-	return 0;
+	/* the buffer is filled with magic numbers describing the devices
+	 * available, 0xff terminates the enumeration
+	 */
+	for (i = 0; i < device_enum->buffer.length; i++) {
+
+		dev_code = *(device_enum->buffer.pointer + i);
+		if (dev_code == 0xff)
+			break;
+
+		dprintk("Radio devices, looking at 0x%.2x\n", dev_code);
+
+		if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI])
+			sony_nc_setup_rfkill(device, SONY_WIFI);
+
+		if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH])
+			sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
+
+		if ((0xf0 & dev_code) == 0x20 &&
+				!sony_rfkill_devices[SONY_WWAN])
+			sony_nc_setup_rfkill(device, SONY_WWAN);
+
+		if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX])
+			sony_nc_setup_rfkill(device, SONY_WIMAX);
+	}
+
+out_no_enum:
+	kfree(buffer.pointer);
+	return;
 }
 
 static int sony_nc_add(struct acpi_device *device)
@@ -1203,7 +1254,7 @@ static int sony_nc_add(struct acpi_devic
 
 	if (debug) {
 		status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
-					     1, sony_walk_callback, NULL, NULL);
+					     1, sony_walk_callback, NULL, NULL, NULL);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
 			result = -ENODEV;
@@ -2079,7 +2130,7 @@ static struct attribute_group spic_attri
 
 struct sonypi_compat_s {
 	struct fasync_struct	*fifo_async;
-	struct kfifo		*fifo;
+	struct kfifo		fifo;
 	spinlock_t		fifo_lock;
 	wait_queue_head_t	fifo_proc_list;
 	atomic_t		open_count;
@@ -2104,12 +2155,12 @@ static int sonypi_misc_open(struct inode
 	/* Flush input queue on first open */
 	unsigned long flags;
 
-	spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+	spin_lock_irqsave(&sonypi_compat.fifo_lock, flags);
 
 	if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-		__kfifo_reset(sonypi_compat.fifo);
+		kfifo_reset(&sonypi_compat.fifo);
 
-	spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+	spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags);
 
 	return 0;
 }
@@ -2120,17 +2171,18 @@ static ssize_t sonypi_misc_read(struct f
 	ssize_t ret;
 	unsigned char c;
 
-	if ((kfifo_len(sonypi_compat.fifo) == 0) &&
+	if ((kfifo_len(&sonypi_compat.fifo) == 0) &&
 	    (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	ret = wait_event_interruptible(sonypi_compat.fifo_proc_list,
-				       kfifo_len(sonypi_compat.fifo) != 0);
+				       kfifo_len(&sonypi_compat.fifo) != 0);
 	if (ret)
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c),
+			  &sonypi_compat.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -2147,7 +2199,7 @@ static ssize_t sonypi_misc_read(struct f
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &sonypi_compat.fifo_proc_list, wait);
-	if (kfifo_len(sonypi_compat.fifo))
+	if (kfifo_len(&sonypi_compat.fifo))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -2309,7 +2361,8 @@ static struct miscdevice sonypi_misc_dev
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_compat.fifo_lock);
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2319,11 +2372,11 @@ static int sonypi_compat_init(void)
 	int error;
 
 	spin_lock_init(&sonypi_compat.fifo_lock);
-	sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-					 &sonypi_compat.fifo_lock);
-	if (IS_ERR(sonypi_compat.fifo)) {
+	error =
+	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-		return PTR_ERR(sonypi_compat.fifo);
+		return error;
 	}
 
 	init_waitqueue_head(&sonypi_compat.fifo_proc_list);
@@ -2342,14 +2395,14 @@ static int sonypi_compat_init(void)
 	return 0;
 
 err_free_kfifo:
-	kfifo_free(sonypi_compat.fifo);
+	kfifo_free(&sonypi_compat.fifo);
 	return error;
 }
 
 static void sonypi_compat_exit(void)
 {
 	misc_deregister(&sonypi_misc_device);
-	kfifo_free(sonypi_compat.fifo);
+	kfifo_free(&sonypi_compat.fifo);
 }
 #else
 static int sonypi_compat_init(void) { return 0; }
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/tc1100-wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/tc1100-wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/tc1100-wmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/tc1100-wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,22 +47,6 @@ MODULE_DESCRIPTION("HP Compaq TC1100 Tab
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505");
 
-static int tc1100_probe(struct platform_device *device);
-static int tc1100_remove(struct platform_device *device);
-static int tc1100_suspend(struct platform_device *device, pm_message_t state);
-static int tc1100_resume(struct platform_device *device);
-
-static struct platform_driver tc1100_driver = {
-	.driver = {
-		.name = "tc1100-wmi",
-		.owner = THIS_MODULE,
-	},
-	.probe = tc1100_probe,
-	.remove = tc1100_remove,
-	.suspend = tc1100_suspend,
-	.resume = tc1100_resume,
-};
-
 static struct platform_device *tc1100_device;
 
 struct tc1100_data {
@@ -183,51 +167,35 @@ static DEVICE_ATTR(value, S_IWUGO | S_IR
 show_set_bool(wireless, TC1100_INSTANCE_WIRELESS);
 show_set_bool(jogdial, TC1100_INSTANCE_JOGDIAL);
 
-static void remove_fs(void)
-{
-	device_remove_file(&tc1100_device->dev, &dev_attr_wireless);
-	device_remove_file(&tc1100_device->dev, &dev_attr_jogdial);
-}
-
-static int add_fs(void)
-{
-	int ret;
-
-	ret = device_create_file(&tc1100_device->dev, &dev_attr_wireless);
-	if (ret)
-		goto add_sysfs_error;
-
-	ret = device_create_file(&tc1100_device->dev, &dev_attr_jogdial);
-	if (ret)
-		goto add_sysfs_error;
-
-	return ret;
+static struct attribute *tc1100_attributes[] = {
+	&dev_attr_wireless.attr,
+	&dev_attr_jogdial.attr,
+	NULL
+};
 
-add_sysfs_error:
-	remove_fs();
-	return ret;
-}
+static struct attribute_group tc1100_attribute_group = {
+	.attrs	= tc1100_attributes,
+};
 
 /* --------------------------------------------------------------------------
 				Driver Model
    -------------------------------------------------------------------------- */
 
-static int tc1100_probe(struct platform_device *device)
+static int __init tc1100_probe(struct platform_device *device)
 {
-	int result = 0;
-
-	result = add_fs();
-	return result;
+	return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group);
 }
 
 
-static int tc1100_remove(struct platform_device *device)
+static int __devexit tc1100_remove(struct platform_device *device)
 {
-	remove_fs();
+	sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group);
+
 	return 0;
 }
 
-static int tc1100_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM
+static int tc1100_suspend(struct device *dev)
 {
 	int ret;
 
@@ -239,10 +207,10 @@ static int tc1100_suspend(struct platfor
 	if (ret)
 		return ret;
 
-	return ret;
+	return 0;
 }
 
-static int tc1100_resume(struct platform_device *dev)
+static int tc1100_resume(struct device *dev)
 {
 	int ret;
 
@@ -254,34 +222,61 @@ static int tc1100_resume(struct platform
 	if (ret)
 		return ret;
 
-	return ret;
+	return 0;
 }
 
+static const struct dev_pm_ops tc1100_pm_ops = {
+	.suspend	= tc1100_suspend,
+	.resume		= tc1100_resume,
+	.freeze		= tc1100_suspend,
+	.restore	= tc1100_resume,
+};
+#endif
+
+static struct platform_driver tc1100_driver = {
+	.driver = {
+		.name = "tc1100-wmi",
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm = &tc1100_pm_ops,
+#endif
+	},
+	.remove = __devexit_p(tc1100_remove),
+};
+
 static int __init tc1100_init(void)
 {
-	int result = 0;
+	int error;
 
 	if (!wmi_has_guid(GUID))
 		return -ENODEV;
 
-	result = platform_driver_register(&tc1100_driver);
-	if (result)
-		return result;
-
 	tc1100_device = platform_device_alloc("tc1100-wmi", -1);
-	platform_device_add(tc1100_device);
+	if (!tc1100_device)
+		return -ENOMEM;
+
+	error = platform_device_add(tc1100_device);
+	if (error)
+		goto err_device_put;
+
+	error = platform_driver_probe(&tc1100_driver, tc1100_probe);
+	if (error)
+		goto err_device_del;
 
 	printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n");
+	return 0;
 
-	return result;
+ err_device_del:
+	platform_device_del(tc1100_device);
+ err_device_put:
+	platform_device_put(tc1100_device);
+	return error;
 }
 
 static void __exit tc1100_exit(void)
 {
-	platform_device_del(tc1100_device);
+	platform_device_unregister(tc1100_device);
 	platform_driver_unregister(&tc1100_driver);
-
-	printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras unloaded\n");
 }
 
 module_init(tc1100_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/thinkpad_acpi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/thinkpad_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/thinkpad_acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/thinkpad_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,8 +21,8 @@
  *  02110-1301, USA.
  */
 
-#define TPACPI_VERSION "0.23"
-#define TPACPI_SYSFS_VERSION 0x020500
+#define TPACPI_VERSION "0.24"
+#define TPACPI_SYSFS_VERSION 0x020700
 
 /*
  *  Changelog:
@@ -61,6 +61,7 @@
 
 #include <linux/nvram.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/sysfs.h>
 #include <linux/backlight.h>
 #include <linux/fb.h>
@@ -76,6 +77,10 @@
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
 
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+
 #include <acpi/acpi_drivers.h>
 
 #include <linux/pci_ids.h>
@@ -231,6 +236,7 @@ enum tpacpi_hkey_event_t {
 #define TPACPI_DBG_HKEY		0x0008
 #define TPACPI_DBG_FAN		0x0010
 #define TPACPI_DBG_BRGHT	0x0020
+#define TPACPI_DBG_MIXER	0x0040
 
 #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -256,7 +262,7 @@ struct tp_acpi_drv_struct {
 struct ibm_struct {
 	char *name;
 
-	int (*read) (char *);
+	int (*read) (struct seq_file *);
 	int (*write) (char *);
 	void (*exit) (void);
 	void (*resume) (void);
@@ -298,6 +304,7 @@ static struct {
 	u32 fan_ctrl_status_undef:1;
 	u32 second_fan:1;
 	u32 beep_needs_two_args:1;
+	u32 mixer_no_level_control:1;
 	u32 input_device_registered:1;
 	u32 platform_drv_registered:1;
 	u32 platform_drv_attrs_registered:1;
@@ -309,6 +316,7 @@ static struct {
 
 static struct {
 	u16 hotkey_mask_ff:1;
+	u16 volume_ctrl_forbidden:1;
 } tp_warned;
 
 struct thinkpad_id_data {
@@ -425,6 +433,12 @@ static void tpacpi_log_usertask(const ch
 	  .ec = TPACPI_MATCH_ANY,		\
 	  .quirks = (__quirk) }
 
+#define TPACPI_QEC_LNV(__id1, __id2, __quirk)	\
+	{ .vendor = PCI_VENDOR_ID_LENOVO,	\
+	  .bios = TPACPI_MATCH_ANY,		\
+	  .ec = TPID(__id1, __id2),		\
+	  .quirks = (__quirk) }
+
 struct tpacpi_quirk {
 	unsigned int vendor;
 	u16 bios;
@@ -776,36 +790,25 @@ static int __init register_tpacpi_subdri
  ****************************************************************************
  ****************************************************************************/
 
-static int dispatch_procfs_read(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
+static int dispatch_proc_show(struct seq_file *m, void *v)
 {
-	struct ibm_struct *ibm = data;
-	int len;
+	struct ibm_struct *ibm = m->private;
 
 	if (!ibm || !ibm->read)
 		return -EINVAL;
+	return ibm->read(m);
+}
 
-	len = ibm->read(page);
-	if (len < 0)
-		return len;
-
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-
-	return len;
+static int dispatch_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dispatch_proc_show, PDE(inode)->data);
 }
 
-static int dispatch_procfs_write(struct file *file,
+static ssize_t dispatch_proc_write(struct file *file,
 			const char __user *userbuf,
-			unsigned long count, void *data)
+			size_t count, loff_t *pos)
 {
-	struct ibm_struct *ibm = data;
+	struct ibm_struct *ibm = PDE(file->f_path.dentry->d_inode)->data;
 	char *kernbuf;
 	int ret;
 
@@ -834,6 +837,15 @@ static int dispatch_procfs_write(struct
 	return ret;
 }
 
+static const struct file_operations dispatch_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= dispatch_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= dispatch_proc_write,
+};
+
 static char *next_cmd(char **cmds)
 {
 	char *start = *cmds;
@@ -1006,11 +1018,8 @@ static int parse_strtoul(const char *buf
 {
 	char *endp;
 
-	while (*buf && isspace(*buf))
-		buf++;
-	*value = simple_strtoul(buf, &endp, 0);
-	while (*endp && isspace(*endp))
-		endp++;
+	*value = simple_strtoul(skip_spaces(buf), &endp, 0);
+	endp = skip_spaces(endp);
 	if (*endp || *value > max)
 		return -EINVAL;
 
@@ -1087,7 +1096,7 @@ static int __init tpacpi_check_std_acpi_
 	 */
 
 	status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
-				     tpacpi_acpi_walk_find_bcl, NULL,
+				     tpacpi_acpi_walk_find_bcl, NULL, NULL,
 				     &bcl_ptr);
 
 	if (ACPI_SUCCESS(status) && bcl_levels > 2) {
@@ -1264,6 +1273,7 @@ static int __init tpacpi_new_rfkill(cons
 	struct tpacpi_rfk *atp_rfk;
 	int res;
 	bool sw_state = false;
+	bool hw_state;
 	int sw_status;
 
 	BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
@@ -1298,7 +1308,8 @@ static int __init tpacpi_new_rfkill(cons
 			rfkill_init_sw_state(atp_rfk->rfkill, sw_state);
 		}
 	}
-	rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state());
+	hw_state = tpacpi_rfk_check_hwblock_state();
+	rfkill_set_hw_state(atp_rfk->rfkill, hw_state);
 
 	res = rfkill_register(atp_rfk->rfkill);
 	if (res < 0) {
@@ -1311,6 +1322,9 @@ static int __init tpacpi_new_rfkill(cons
 	}
 
 	tpacpi_rfkill_switches[id] = atp_rfk;
+
+	printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n",
+		name, (sw_state || hw_state) ? "" : "un");
 	return 0;
 }
 
@@ -1383,12 +1397,10 @@ static ssize_t tpacpi_rfk_sysfs_enable_s
 }
 
 /* procfs -------------------------------------------------------------- */
-static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
+static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)
 {
-	int len = 0;
-
 	if (id >= TPACPI_RFK_SW_MAX)
-		len += sprintf(p + len, "status:\t\tnot supported\n");
+		seq_printf(m, "status:\t\tnot supported\n");
 	else {
 		int status;
 
@@ -1402,13 +1414,13 @@ static int tpacpi_rfk_procfs_read(const
 				return status;
 		}
 
-		len += sprintf(p + len, "status:\t\t%s\n",
+		seq_printf(m, "status:\t\t%s\n",
 				(status == TPACPI_RFK_RADIO_ON) ?
 					"enabled" : "disabled");
-		len += sprintf(p + len, "commands:\tenable, disable\n");
+		seq_printf(m, "commands:\tenable, disable\n");
 	}
 
-	return len;
+	return 0;
 }
 
 static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
@@ -1779,7 +1791,7 @@ static const struct tpacpi_quirk tpacpi_
 
 	TPV_QL1('7', '9',  'E', '3',  '5', '0'), /* T60/p */
 	TPV_QL1('7', 'C',  'D', '2',  '2', '2'), /* R60, R60i */
-	TPV_QL0('7', 'E',  'D', '0'),		 /* R60e, R60i */
+	TPV_QL1('7', 'E',  'D', '0',  '1', '5'), /* R60e, R60i */
 
 	/*      BIOS FW    BIOS VERS  EC FW     EC VERS */
 	TPV_QI2('1', 'W',  '9', '0',  '1', 'V', '2', '8'), /* R50e (1) */
@@ -1795,8 +1807,8 @@ static const struct tpacpi_quirk tpacpi_
 	TPV_QI1('7', '4',  '6', '4',  '2', '7'), /* X41 (0) */
 	TPV_QI1('7', '5',  '6', '0',  '2', '0'), /* X41t (0) */
 
-	TPV_QL0('7', 'B',  'D', '7'),		 /* X60/s */
-	TPV_QL0('7', 'J',  '3', '0'),		 /* X60t */
+	TPV_QL1('7', 'B',  'D', '7',  '4', '0'), /* X60/s */
+	TPV_QL1('7', 'J',  '3', '0',  '1', '3'), /* X60t */
 
 	/* (0) - older versions lack DMI EC fw string and functionality */
 	/* (1) - older versions known to lack functionality */
@@ -1886,14 +1898,11 @@ static int __init thinkpad_acpi_driver_i
 	return 0;
 }
 
-static int thinkpad_acpi_driver_read(char *p)
+static int thinkpad_acpi_driver_read(struct seq_file *m)
 {
-	int len = 0;
-
-	len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC);
-	len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION);
-
-	return len;
+	seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);
+	seq_printf(m, "version:\t%s\n", TPACPI_VERSION);
+	return 0;
 }
 
 static struct ibm_struct thinkpad_acpi_driver_data = {
@@ -2189,7 +2198,8 @@ static int hotkey_mask_set(u32 mask)
 		       fwmask, hotkey_acpi_mask);
 	}
 
-	hotkey_mask_warn_incomplete_mask();
+	if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)
+		hotkey_mask_warn_incomplete_mask();
 
 	return rc;
 }
@@ -3185,6 +3195,8 @@ static int __init hotkey_init(struct ibm
 	int res, i;
 	int status;
 	int hkeyv;
+	bool radiosw_state  = false;
+	bool tabletsw_state = false;
 
 	unsigned long quirks;
 
@@ -3290,6 +3302,7 @@ static int __init hotkey_init(struct ibm
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_wlswemul) {
 		tp_features.hotkey_wlsw = 1;
+		radiosw_state = !!tpacpi_wlsw_emulstate;
 		printk(TPACPI_INFO
 			"radio switch emulation enabled\n");
 	} else
@@ -3297,6 +3310,7 @@ static int __init hotkey_init(struct ibm
 	/* Not all thinkpads have a hardware radio switch */
 	if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
 		tp_features.hotkey_wlsw = 1;
+		radiosw_state = !!status;
 		printk(TPACPI_INFO
 			"radio switch found; radios are %s\n",
 			enabled(status, 0));
@@ -3308,11 +3322,11 @@ static int __init hotkey_init(struct ibm
 	/* For X41t, X60t, X61t Tablets... */
 	if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
 		tp_features.hotkey_tablet = 1;
+		tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
 		printk(TPACPI_INFO
 			"possible tablet mode switch found; "
 			"ThinkPad in %s mode\n",
-			(status & TP_HOTKEY_TABLET_MASK)?
-				"tablet" : "laptop");
+			(tabletsw_state) ? "tablet" : "laptop");
 		res = add_to_attr_set(hotkey_dev_attributes,
 				&dev_attr_hotkey_tablet_mode.attr);
 	}
@@ -3347,16 +3361,14 @@ static int __init hotkey_init(struct ibm
 			TPACPI_HOTKEY_MAP_SIZE);
 	}
 
-	set_bit(EV_KEY, tpacpi_inputdev->evbit);
-	set_bit(EV_MSC, tpacpi_inputdev->evbit);
-	set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
+	input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
 	tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
 	tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
 	tpacpi_inputdev->keycode = hotkey_keycode_map;
 	for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
 		if (hotkey_keycode_map[i] != KEY_RESERVED) {
-			set_bit(hotkey_keycode_map[i],
-				tpacpi_inputdev->keybit);
+			input_set_capability(tpacpi_inputdev, EV_KEY,
+						hotkey_keycode_map[i]);
 		} else {
 			if (i < sizeof(hotkey_reserved_mask)*8)
 				hotkey_reserved_mask |= 1 << i;
@@ -3364,12 +3376,14 @@ static int __init hotkey_init(struct ibm
 	}
 
 	if (tp_features.hotkey_wlsw) {
-		set_bit(EV_SW, tpacpi_inputdev->evbit);
-		set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit);
+		input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);
+		input_report_switch(tpacpi_inputdev,
+				    SW_RFKILL_ALL, radiosw_state);
 	}
 	if (tp_features.hotkey_tablet) {
-		set_bit(EV_SW, tpacpi_inputdev->evbit);
-		set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
+		input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);
+		input_report_switch(tpacpi_inputdev,
+				    SW_TABLET_MODE, tabletsw_state);
 	}
 
 	/* Do not issue duplicate brightness change events to
@@ -3436,8 +3450,6 @@ static int __init hotkey_init(struct ibm
 	tpacpi_inputdev->close = &hotkey_inputdev_close;
 
 	hotkey_poll_setup_safe(true);
-	tpacpi_send_radiosw_update();
-	tpacpi_input_send_tabletsw();
 
 	return 0;
 
@@ -3545,49 +3557,57 @@ static bool hotkey_notify_usrevent(const
 	}
 }
 
+static void thermal_dump_all_sensors(void);
+
 static bool hotkey_notify_thermal(const u32 hkey,
 				 bool *send_acpi_ev,
 				 bool *ignore_acpi_ev)
 {
+	bool known = true;
+
 	/* 0x6000-0x6FFF: thermal alarms */
 	*send_acpi_ev = true;
 	*ignore_acpi_ev = false;
 
 	switch (hkey) {
+	case TP_HKEY_EV_THM_TABLE_CHANGED:
+		printk(TPACPI_INFO
+			"EC reports that Thermal Table has changed\n");
+		/* recommended action: do nothing, we don't have
+		 * Lenovo ATM information */
+		return true;
 	case TP_HKEY_EV_ALARM_BAT_HOT:
 		printk(TPACPI_CRIT
 			"THERMAL ALARM: battery is too hot!\n");
 		/* recommended action: warn user through gui */
-		return true;
+		break;
 	case TP_HKEY_EV_ALARM_BAT_XHOT:
 		printk(TPACPI_ALERT
 			"THERMAL EMERGENCY: battery is extremely hot!\n");
 		/* recommended action: immediate sleep/hibernate */
-		return true;
+		break;
 	case TP_HKEY_EV_ALARM_SENSOR_HOT:
 		printk(TPACPI_CRIT
 			"THERMAL ALARM: "
 			"a sensor reports something is too hot!\n");
 		/* recommended action: warn user through gui, that */
 		/* some internal component is too hot */
-		return true;
+		break;
 	case TP_HKEY_EV_ALARM_SENSOR_XHOT:
 		printk(TPACPI_ALERT
 			"THERMAL EMERGENCY: "
 			"a sensor reports something is extremely hot!\n");
 		/* recommended action: immediate sleep/hibernate */
-		return true;
-	case TP_HKEY_EV_THM_TABLE_CHANGED:
-		printk(TPACPI_INFO
-			"EC reports that Thermal Table has changed\n");
-		/* recommended action: do nothing, we don't have
-		 * Lenovo ATM information */
-		return true;
+		break;
 	default:
 		printk(TPACPI_ALERT
 			 "THERMAL ALERT: unknown thermal alarm received\n");
-		return false;
+		known = false;
 	}
+
+	thermal_dump_all_sensors();
+
+	return known;
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -3730,14 +3750,13 @@ static void hotkey_resume(void)
 }
 
 /* procfs -------------------------------------------------------------- */
-static int hotkey_read(char *p)
+static int hotkey_read(struct seq_file *m)
 {
 	int res, status;
-	int len = 0;
 
 	if (!tp_features.hotkey) {
-		len += sprintf(p + len, "status:\t\tnot supported\n");
-		return len;
+		seq_printf(m, "status:\t\tnot supported\n");
+		return 0;
 	}
 
 	if (mutex_lock_killable(&hotkey_mutex))
@@ -3749,17 +3768,16 @@ static int hotkey_read(char *p)
 	if (res)
 		return res;
 
-	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
+	seq_printf(m, "status:\t\t%s\n", enabled(status, 0));
 	if (hotkey_all_mask) {
-		len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask);
-		len += sprintf(p + len,
-			       "commands:\tenable, disable, reset, <mask>\n");
+		seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);
+		seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");
 	} else {
-		len += sprintf(p + len, "mask:\t\tnot supported\n");
-		len += sprintf(p + len, "commands:\tenable, disable, reset\n");
+		seq_printf(m, "mask:\t\tnot supported\n");
+		seq_printf(m, "commands:\tenable, disable, reset\n");
 	}
 
-	return len;
+	return 0;
 }
 
 static void hotkey_enabledisable_warn(bool enable)
@@ -3866,15 +3884,6 @@ enum {
 
 #define TPACPI_RFK_BLUETOOTH_SW_NAME	"tpacpi_bluetooth_sw"
 
-static void bluetooth_suspend(pm_message_t state)
-{
-	/* Try to make sure radio will resume powered off */
-	if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
-		   TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
-		vdbg_printk(TPACPI_DBG_RFKILL,
-			"bluetooth power down on resume request failed\n");
-}
-
 static int bluetooth_get_status(void)
 {
 	int status;
@@ -3908,10 +3917,9 @@ static int bluetooth_set_status(enum tpa
 #endif
 
 	/* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
+	status = TP_ACPI_BLUETOOTH_RESUMECTRL;
 	if (state == TPACPI_RFK_RADIO_ON)
-		status = TP_ACPI_BLUETOOTH_RADIOSSW;
-	else
-		status = 0;
+		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
 
 	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
 		return -EIO;
@@ -4035,9 +4043,9 @@ static int __init bluetooth_init(struct
 }
 
 /* procfs -------------------------------------------------------------- */
-static int bluetooth_read(char *p)
+static int bluetooth_read(struct seq_file *m)
 {
-	return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
+	return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);
 }
 
 static int bluetooth_write(char *buf)
@@ -4050,7 +4058,6 @@ static struct ibm_struct bluetooth_drive
 	.read = bluetooth_read,
 	.write = bluetooth_write,
 	.exit = bluetooth_exit,
-	.suspend = bluetooth_suspend,
 	.shutdown = bluetooth_shutdown,
 };
 
@@ -4068,15 +4075,6 @@ enum {
 
 #define TPACPI_RFK_WWAN_SW_NAME		"tpacpi_wwan_sw"
 
-static void wan_suspend(pm_message_t state)
-{
-	/* Try to make sure radio will resume powered off */
-	if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
-		   TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
-		vdbg_printk(TPACPI_DBG_RFKILL,
-			"WWAN power down on resume request failed\n");
-}
-
 static int wan_get_status(void)
 {
 	int status;
@@ -4109,11 +4107,10 @@ static int wan_set_status(enum tpacpi_rf
 	}
 #endif
 
-	/* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
+	/* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
+	status = TP_ACPI_WANCARD_RESUMECTRL;
 	if (state == TPACPI_RFK_RADIO_ON)
-		status = TP_ACPI_WANCARD_RADIOSSW;
-	else
-		status = 0;
+		status |= TP_ACPI_WANCARD_RADIOSSW;
 
 	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
 		return -EIO;
@@ -4236,9 +4233,9 @@ static int __init wan_init(struct ibm_in
 }
 
 /* procfs -------------------------------------------------------------- */
-static int wan_read(char *p)
+static int wan_read(struct seq_file *m)
 {
-	return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
+	return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);
 }
 
 static int wan_write(char *buf)
@@ -4251,7 +4248,6 @@ static struct ibm_struct wan_driver_data
 	.read = wan_read,
 	.write = wan_write,
 	.exit = wan_exit,
-	.suspend = wan_suspend,
 	.shutdown = wan_shutdown,
 };
 
@@ -4614,14 +4610,13 @@ static int video_expand_toggle(void)
 	/* not reached */
 }
 
-static int video_read(char *p)
+static int video_read(struct seq_file *m)
 {
 	int status, autosw;
-	int len = 0;
 
 	if (video_supported == TPACPI_VIDEO_NONE) {
-		len += sprintf(p + len, "status:\t\tnot supported\n");
-		return len;
+		seq_printf(m, "status:\t\tnot supported\n");
+		return 0;
 	}
 
 	status = video_outputsw_get();
@@ -4632,20 +4627,20 @@ static int video_read(char *p)
 	if (autosw < 0)
 		return autosw;
 
-	len += sprintf(p + len, "status:\t\tsupported\n");
-	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
-	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
+	seq_printf(m, "status:\t\tsupported\n");
+	seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0));
+	seq_printf(m, "crt:\t\t%s\n", enabled(status, 1));
 	if (video_supported == TPACPI_VIDEO_NEW)
-		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
-	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
-	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
-	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
+		seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3));
+	seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0));
+	seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");
+	seq_printf(m, "commands:\tcrt_enable, crt_disable\n");
 	if (video_supported == TPACPI_VIDEO_NEW)
-		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
-	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
-	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
+		seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");
+	seq_printf(m, "commands:\tauto_enable, auto_disable\n");
+	seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");
 
-	return len;
+	return 0;
 }
 
 static int video_write(char *buf)
@@ -4837,25 +4832,24 @@ static void light_exit(void)
 		flush_workqueue(tpacpi_wq);
 }
 
-static int light_read(char *p)
+static int light_read(struct seq_file *m)
 {
-	int len = 0;
 	int status;
 
 	if (!tp_features.light) {
-		len += sprintf(p + len, "status:\t\tnot supported\n");
+		seq_printf(m, "status:\t\tnot supported\n");
 	} else if (!tp_features.light_status) {
-		len += sprintf(p + len, "status:\t\tunknown\n");
-		len += sprintf(p + len, "commands:\ton, off\n");
+		seq_printf(m, "status:\t\tunknown\n");
+		seq_printf(m, "commands:\ton, off\n");
 	} else {
 		status = light_get_status();
 		if (status < 0)
 			return status;
-		len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
-		len += sprintf(p + len, "commands:\ton, off\n");
+		seq_printf(m, "status:\t\t%s\n", onoff(status, 0));
+		seq_printf(m, "commands:\ton, off\n");
 	}
 
-	return len;
+	return 0;
 }
 
 static int light_write(char *buf)
@@ -4933,20 +4927,18 @@ static void cmos_exit(void)
 	device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
 }
 
-static int cmos_read(char *p)
+static int cmos_read(struct seq_file *m)
 {
-	int len = 0;
-
 	/* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 	   R30, R31, T20-22, X20-21 */
 	if (!cmos_handle)
-		len += sprintf(p + len, "status:\t\tnot supported\n");
+		seq_printf(m, "status:\t\tnot supported\n");
 	else {
-		len += sprintf(p + len, "status:\t\tsupported\n");
-		len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n");
+		seq_printf(m, "status:\t\tsupported\n");
+		seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");
 	}
 
-	return len;
+	return 0;
 }
 
 static int cmos_write(char *buf)
@@ -5321,15 +5313,13 @@ static int __init led_init(struct ibm_in
 	((s) == TPACPI_LED_OFF ? "off" : \
 		((s) == TPACPI_LED_ON ? "on" : "blinking"))
 
-static int led_read(char *p)
+static int led_read(struct seq_file *m)
 {
-	int len = 0;
-
 	if (!led_supported) {
-		len += sprintf(p + len, "status:\t\tnot supported\n");
-		return len;
+		seq_printf(m, "status:\t\tnot supported\n");
+		return 0;
 	}
-	len += sprintf(p + len, "status:\t\tsupported\n");
+	seq_printf(m, "status:\t\tsupported\n");
 
 	if (led_supported == TPACPI_LED_570) {
 		/* 570 */
@@ -5338,15 +5328,15 @@ static int led_read(char *p)
 			status = led_get_status(i);
 			if (status < 0)
 				return -EIO;
-			len += sprintf(p + len, "%d:\t\t%s\n",
+			seq_printf(m, "%d:\t\t%s\n",
 				       i, str_led_status(status));
 		}
 	}
 
-	len += sprintf(p + len, "commands:\t"
+	seq_printf(m, "commands:\t"
 		       "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
 
-	return len;
+	return 0;
 }
 
 static int led_write(char *buf)
@@ -5419,18 +5409,16 @@ static int __init beep_init(struct ibm_i
 	return (beep_handle)? 0 : 1;
 }
 
-static int beep_read(char *p)
+static int beep_read(struct seq_file *m)
 {
-	int len = 0;
-
 	if (!beep_handle)
-		len += sprintf(p + len, "status:\t\tnot supported\n");
+		seq_printf(m, "status:\t\tnot supported\n");
 	else {
-		len += sprintf(p + len, "status:\t\tsupported\n");
-		len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
+		seq_printf(m, "status:\t\tsupported\n");
+		seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");
 	}
 
-	return len;
+	return 0;
 }
 
 static int beep_write(char *buf)
@@ -5483,8 +5471,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */
 	TP_EC_THERMAL_TMP0 = 0x78,	/* ACPI EC regs TMP 0..7 */
 	TP_EC_THERMAL_TMP8 = 0xC0,	/* ACPI EC regs TMP 8..15 */
 	TP_EC_THERMAL_TMP_NA = -128,	/* ACPI EC sensor not available */
+
+	TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */
 };
 
+
 #define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
 struct ibm_thermal_sensors_struct {
 	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
@@ -5574,6 +5565,28 @@ static int thermal_get_sensors(struct ib
 	return n;
 }
 
+static void thermal_dump_all_sensors(void)
+{
+	int n, i;
+	struct ibm_thermal_sensors_struct t;
+
+	n = thermal_get_sensors(&t);
+	if (n <= 0)
+		return;
+
+	printk(TPACPI_NOTICE
+		"temperatures (Celsius):");
+
+	for (i = 0; i < n; i++) {
+		if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
+			printk(KERN_CONT " %d", (int)(t.temp[i] / 1000));
+		else
+			printk(KERN_CONT " N/A");
+	}
+
+	printk(KERN_CONT "\n");
+}
+
 /* sysfs temp##_input -------------------------------------------------- */
 
 static ssize_t thermal_temp_input_show(struct device *dev,
@@ -5589,7 +5602,7 @@ static ssize_t thermal_temp_input_show(s
 	res = thermal_get_sensor(idx, &value);
 	if (res)
 		return res;
-	if (value == TP_EC_THERMAL_TMP_NA * 1000)
+	if (value == TPACPI_THERMAL_SENSOR_NA)
 		return -ENXIO;
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", value);
@@ -5758,7 +5771,7 @@ static void thermal_exit(void)
 	case TPACPI_THERMAL_ACPI_TMP07:
 	case TPACPI_THERMAL_ACPI_UPDT:
 		sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
-				   &thermal_temp_input16_group);
+				   &thermal_temp_input8_group);
 		break;
 	case TPACPI_THERMAL_NONE:
 	default:
@@ -5766,9 +5779,8 @@ static void thermal_exit(void)
 	}
 }
 
-static int thermal_read(char *p)
+static int thermal_read(struct seq_file *m)
 {
-	int len = 0;
 	int n, i;
 	struct ibm_thermal_sensors_struct t;
 
@@ -5776,16 +5788,16 @@ static int thermal_read(char *p)
 	if (unlikely(n < 0))
 		return n;
 
-	len += sprintf(p + len, "temperatures:\t");
+	seq_printf(m, "temperatures:\t");
 
 	if (n > 0) {
 		for (i = 0; i < (n - 1); i++)
-			len += sprintf(p + len, "%d ", t.temp[i] / 1000);
-		len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
+			seq_printf(m, "%d ", t.temp[i] / 1000);
+		seq_printf(m, "%d\n", t.temp[i] / 1000);
 	} else
-		len += sprintf(p + len, "not supported\n");
+		seq_printf(m, "not supported\n");
 
-	return len;
+	return 0;
 }
 
 static struct ibm_struct thermal_driver_data = {
@@ -5800,39 +5812,38 @@ static struct ibm_struct thermal_driver_
 
 static u8 ecdump_regs[256];
 
-static int ecdump_read(char *p)
+static int ecdump_read(struct seq_file *m)
 {
-	int len = 0;
 	int i, j;
 	u8 v;
 
-	len += sprintf(p + len, "EC      "
+	seq_printf(m, "EC      "
 		       " +00 +01 +02 +03 +04 +05 +06 +07"
 		       " +08 +09 +0a +0b +0c +0d +0e +0f\n");
 	for (i = 0; i < 256; i += 16) {
-		len += sprintf(p + len, "EC 0x%02x:", i);
+		seq_printf(m, "EC 0x%02x:", i);
 		for (j = 0; j < 16; j++) {
 			if (!acpi_ec_read(i + j, &v))
 				break;
 			if (v != ecdump_regs[i + j])
-				len += sprintf(p + len, " *%02x", v);
+				seq_printf(m, " *%02x", v);
 			else
-				len += sprintf(p + len, "  %02x", v);
+				seq_printf(m, "  %02x", v);
 			ecdump_regs[i + j] = v;
 		}
-		len += sprintf(p + len, "\n");
+		seq_putc(m, '\n');
 		if (j != 16)
 			break;
 	}
 
 	/* These are way too dangerous to advertise openly... */
 #if 0
-	len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
+	seq_printf(m, "commands:\t0x<offset> 0x<value>"
 		       " (<offset> is 00-ff, <value> is 00-ff)\n");
-	len += sprintf(p + len, "commands:\t0x<offset> <value>  "
+	seq_printf(m, "commands:\t0x<offset> <value>  "
 		       " (<offset> is 00-ff, <value> is 0-255)\n");
 #endif
-	return len;
+	return 0;
 }
 
 static int ecdump_write(char *buf)
@@ -6095,6 +6106,12 @@ static int brightness_get(struct backlig
 	return status & TP_EC_BACKLIGHT_LVLMSK;
 }
 
+static void tpacpi_brightness_notify_change(void)
+{
+	backlight_force_update(ibm_backlight_device,
+			       BACKLIGHT_UPDATE_HOTKEY);
+}
+
 static struct backlight_ops ibm_backlight_data = {
 	.get_brightness = brightness_get,
 	.update_status  = brightness_update_status,
@@ -6123,8 +6140,8 @@ static const struct tpacpi_quirk brightn
 
 	/* Models with Intel Extreme Graphics 2 */
 	TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
-	TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
-	TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
+	TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
 
 	/* Models with Intel GMA900 */
 	TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC),	/* T43, R52 */
@@ -6249,6 +6266,12 @@ static int __init brightness_init(struct
 	ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
 	backlight_update_status(ibm_backlight_device);
 
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+			"brightness: registering brightness hotkeys "
+			"as change notification\n");
+	tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
+				| TP_ACPI_HKEY_BRGHTUP_MASK
+				| TP_ACPI_HKEY_BRGHTDWN_MASK);;
 	return 0;
 }
 
@@ -6273,23 +6296,22 @@ static void brightness_exit(void)
 	tpacpi_brightness_checkpoint_nvram();
 }
 
-static int brightness_read(char *p)
+static int brightness_read(struct seq_file *m)
 {
-	int len = 0;
 	int level;
 
 	level = brightness_get(NULL);
 	if (level < 0) {
-		len += sprintf(p + len, "level:\t\tunreadable\n");
+		seq_printf(m, "level:\t\tunreadable\n");
 	} else {
-		len += sprintf(p + len, "level:\t\t%d\n", level);
-		len += sprintf(p + len, "commands:\tup, down\n");
-		len += sprintf(p + len, "commands:\tlevel <level>"
+		seq_printf(m, "level:\t\t%d\n", level);
+		seq_printf(m, "commands:\tup, down\n");
+		seq_printf(m, "commands:\tlevel <level>"
 			       " (<level> is 0-%d)\n",
 			       (tp_features.bright_16levels) ? 15 : 7);
 	}
 
-	return len;
+	return 0;
 }
 
 static int brightness_write(char *buf)
@@ -6325,6 +6347,9 @@ static int brightness_write(char *buf)
 	 * Doing it this way makes the syscall restartable in case of EINTR
 	 */
 	rc = brightness_set(level);
+	if (!rc && ibm_backlight_device)
+		backlight_force_update(ibm_backlight_device,
+					BACKLIGHT_UPDATE_SYSFS);
 	return (rc == -EINTR)? -ERESTARTSYS : rc;
 }
 
@@ -6341,101 +6366,685 @@ static struct ibm_struct brightness_driv
  * Volume subdriver
  */
 
-static int volume_offset = 0x30;
+/*
+ * IBM ThinkPads have a simple volume controller with MUTE gating.
+ * Very early Lenovo ThinkPads follow the IBM ThinkPad spec.
+ *
+ * Since the *61 series (and probably also the later *60 series), Lenovo
+ * ThinkPads only implement the MUTE gate.
+ *
+ * EC register 0x30
+ *   Bit 6: MUTE (1 mutes sound)
+ *   Bit 3-0: Volume
+ *   Other bits should be zero as far as we know.
+ *
+ * This is also stored in CMOS NVRAM, byte 0x60, bit 6 (MUTE), and
+ * bits 3-0 (volume).  Other bits in NVRAM may have other functions,
+ * such as bit 7 which is used to detect repeated presses of MUTE,
+ * and we leave them unchanged.
+ */
 
-static int volume_read(char *p)
+#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
+
+#define TPACPI_ALSA_DRVNAME  "ThinkPad EC"
+#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
+#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
+
+static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
+static char *alsa_id = "ThinkPadEC";
+static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
+
+struct tpacpi_alsa_data {
+	struct snd_card *card;
+	struct snd_ctl_elem_id *ctl_mute_id;
+	struct snd_ctl_elem_id *ctl_vol_id;
+};
+
+static struct snd_card *alsa_card;
+
+enum {
+	TP_EC_AUDIO = 0x30,
+
+	/* TP_EC_AUDIO bits */
+	TP_EC_AUDIO_MUTESW = 6,
+
+	/* TP_EC_AUDIO bitmasks */
+	TP_EC_AUDIO_LVL_MSK = 0x0F,
+	TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),
+
+	/* Maximum volume */
+	TP_EC_VOLUME_MAX = 14,
+};
+
+enum tpacpi_volume_access_mode {
+	TPACPI_VOL_MODE_AUTO = 0,	/* Not implemented yet */
+	TPACPI_VOL_MODE_EC,		/* Pure EC control */
+	TPACPI_VOL_MODE_UCMS_STEP,	/* UCMS step-based control: N/A */
+	TPACPI_VOL_MODE_ECNVRAM,	/* EC control w/ NVRAM store */
+	TPACPI_VOL_MODE_MAX
+};
+
+enum tpacpi_volume_capabilities {
+	TPACPI_VOL_CAP_AUTO = 0,	/* Use white/blacklist */
+	TPACPI_VOL_CAP_VOLMUTE,		/* Output vol and mute */
+	TPACPI_VOL_CAP_MUTEONLY,	/* Output mute only */
+	TPACPI_VOL_CAP_MAX
+};
+
+static enum tpacpi_volume_access_mode volume_mode =
+	TPACPI_VOL_MODE_MAX;
+
+static enum tpacpi_volume_capabilities volume_capabilities;
+static int volume_control_allowed;
+
+/*
+ * Used to syncronize writers to TP_EC_AUDIO and
+ * TP_NVRAM_ADDR_MIXER, as we need to do read-modify-write
+ */
+static struct mutex volume_mutex;
+
+static void tpacpi_volume_checkpoint_nvram(void)
 {
-	int len = 0;
-	u8 level;
+	u8 lec = 0;
+	u8 b_nvram;
+	u8 ec_mask;
 
-	if (!acpi_ec_read(volume_offset, &level)) {
-		len += sprintf(p + len, "level:\t\tunreadable\n");
+	if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
+		return;
+	if (!volume_control_allowed)
+		return;
+
+	vdbg_printk(TPACPI_DBG_MIXER,
+		"trying to checkpoint mixer state to NVRAM...\n");
+
+	if (tp_features.mixer_no_level_control)
+		ec_mask = TP_EC_AUDIO_MUTESW_MSK;
+	else
+		ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;
+
+	if (mutex_lock_killable(&volume_mutex) < 0)
+		return;
+
+	if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
+		goto unlock;
+	lec &= ec_mask;
+	b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
+
+	if (lec != (b_nvram & ec_mask)) {
+		/* NVRAM needs update */
+		b_nvram &= ~ec_mask;
+		b_nvram |= lec;
+		nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
+		dbg_printk(TPACPI_DBG_MIXER,
+			   "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
 	} else {
-		len += sprintf(p + len, "level:\t\t%d\n", level & 0xf);
-		len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6));
-		len += sprintf(p + len, "commands:\tup, down, mute\n");
-		len += sprintf(p + len, "commands:\tlevel <level>"
-			       " (<level> is 0-15)\n");
+		vdbg_printk(TPACPI_DBG_MIXER,
+			   "NVRAM mixer status already is 0x%02x (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
 	}
 
-	return len;
+unlock:
+	mutex_unlock(&volume_mutex);
 }
 
-static int volume_write(char *buf)
+static int volume_get_status_ec(u8 *status)
 {
-	int cmos_cmd, inc, i;
-	u8 level, mute;
-	int new_level, new_mute;
-	char *cmd;
+	u8 s;
 
-	while ((cmd = next_cmd(&buf))) {
-		if (!acpi_ec_read(volume_offset, &level))
-			return -EIO;
-		new_mute = mute = level & 0x40;
-		new_level = level = level & 0xf;
+	if (!acpi_ec_read(TP_EC_AUDIO, &s))
+		return -EIO;
 
-		if (strlencmp(cmd, "up") == 0) {
-			if (mute)
-				new_mute = 0;
-			else
-				new_level = level == 15 ? 15 : level + 1;
-		} else if (strlencmp(cmd, "down") == 0) {
-			if (mute)
-				new_mute = 0;
-			else
-				new_level = level == 0 ? 0 : level - 1;
-		} else if (sscanf(cmd, "level %d", &new_level) == 1 &&
-			   new_level >= 0 && new_level <= 15) {
-			/* new_level set */
-		} else if (strlencmp(cmd, "mute") == 0) {
-			new_mute = 0x40;
-		} else
-			return -EINVAL;
+	*status = s;
 
-		if (new_level != level) {
-			/* mute doesn't change */
+	dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);
 
-			cmos_cmd = (new_level > level) ?
-					TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
-			inc = new_level > level ? 1 : -1;
+	return 0;
+}
 
-			if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
-				     !acpi_ec_write(volume_offset, level)))
-				return -EIO;
+static int volume_get_status(u8 *status)
+{
+	return volume_get_status_ec(status);
+}
 
-			for (i = level; i != new_level; i += inc)
-				if (issue_thinkpad_cmos_command(cmos_cmd) ||
-				    !acpi_ec_write(volume_offset, i + inc))
-					return -EIO;
+static int volume_set_status_ec(const u8 status)
+{
+	if (!acpi_ec_write(TP_EC_AUDIO, status))
+		return -EIO;
 
-			if (mute &&
-			    (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
-			     !acpi_ec_write(volume_offset, new_level + mute))) {
-				return -EIO;
-			}
+	dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
+
+	return 0;
+}
+
+static int volume_set_status(const u8 status)
+{
+	return volume_set_status_ec(status);
+}
+
+static int volume_set_mute_ec(const bool mute)
+{
+	int rc;
+	u8 s, n;
+
+	if (mutex_lock_killable(&volume_mutex) < 0)
+		return -EINTR;
+
+	rc = volume_get_status_ec(&s);
+	if (rc)
+		goto unlock;
+
+	n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
+		     s & ~TP_EC_AUDIO_MUTESW_MSK;
+
+	if (n != s)
+		rc = volume_set_status_ec(n);
+
+unlock:
+	mutex_unlock(&volume_mutex);
+	return rc;
+}
+
+static int volume_set_mute(const bool mute)
+{
+	dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
+		   (mute) ? "" : "un");
+	return volume_set_mute_ec(mute);
+}
+
+static int volume_set_volume_ec(const u8 vol)
+{
+	int rc;
+	u8 s, n;
+
+	if (vol > TP_EC_VOLUME_MAX)
+		return -EINVAL;
+
+	if (mutex_lock_killable(&volume_mutex) < 0)
+		return -EINTR;
+
+	rc = volume_get_status_ec(&s);
+	if (rc)
+		goto unlock;
+
+	n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
+
+	if (n != s)
+		rc = volume_set_status_ec(n);
+
+unlock:
+	mutex_unlock(&volume_mutex);
+	return rc;
+}
+
+static int volume_set_volume(const u8 vol)
+{
+	dbg_printk(TPACPI_DBG_MIXER,
+		   "trying to set volume level to %hu\n", vol);
+	return volume_set_volume_ec(vol);
+}
+
+static void volume_alsa_notify_change(void)
+{
+	struct tpacpi_alsa_data *d;
+
+	if (alsa_card && alsa_card->private_data) {
+		d = alsa_card->private_data;
+		if (d->ctl_mute_id)
+			snd_ctl_notify(alsa_card,
+					SNDRV_CTL_EVENT_MASK_VALUE,
+					d->ctl_mute_id);
+		if (d->ctl_vol_id)
+			snd_ctl_notify(alsa_card,
+					SNDRV_CTL_EVENT_MASK_VALUE,
+					d->ctl_vol_id);
+	}
+}
+
+static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = TP_EC_VOLUME_MAX;
+	return 0;
+}
+
+static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 s;
+	int rc;
+
+	rc = volume_get_status(&s);
+	if (rc < 0)
+		return rc;
+
+	ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;
+	return 0;
+}
+
+static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	return volume_set_volume(ucontrol->value.integer.value[0]);
+}
+
+#define volume_alsa_mute_info snd_ctl_boolean_mono_info
+
+static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	u8 s;
+	int rc;
+
+	rc = volume_get_status(&s);
+	if (rc < 0)
+		return rc;
+
+	ucontrol->value.integer.value[0] =
+				(s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;
+	return 0;
+}
+
+static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	return volume_set_mute(!ucontrol->value.integer.value[0]);
+}
+
+static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Console Playback Volume",
+	.index = 0,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.info = volume_alsa_vol_info,
+	.get = volume_alsa_vol_get,
+};
+
+static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Console Playback Switch",
+	.index = 0,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.info = volume_alsa_mute_info,
+	.get = volume_alsa_mute_get,
+};
+
+static void volume_suspend(pm_message_t state)
+{
+	tpacpi_volume_checkpoint_nvram();
+}
+
+static void volume_resume(void)
+{
+	volume_alsa_notify_change();
+}
+
+static void volume_shutdown(void)
+{
+	tpacpi_volume_checkpoint_nvram();
+}
+
+static void volume_exit(void)
+{
+	if (alsa_card) {
+		snd_card_free(alsa_card);
+		alsa_card = NULL;
+	}
+
+	tpacpi_volume_checkpoint_nvram();
+}
+
+static int __init volume_create_alsa_mixer(void)
+{
+	struct snd_card *card;
+	struct tpacpi_alsa_data *data;
+	struct snd_kcontrol *ctl_vol;
+	struct snd_kcontrol *ctl_mute;
+	int rc;
+
+	rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
+			    sizeof(struct tpacpi_alsa_data), &card);
+	if (rc < 0 || !card) {
+		printk(TPACPI_ERR
+			"Failed to create ALSA card structures: %d\n", rc);
+		return 1;
+	}
+
+	BUG_ON(!card->private_data);
+	data = card->private_data;
+	data->card = card;
+
+	strlcpy(card->driver, TPACPI_ALSA_DRVNAME,
+		sizeof(card->driver));
+	strlcpy(card->shortname, TPACPI_ALSA_SHRTNAME,
+		sizeof(card->shortname));
+	snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",
+		 (thinkpad_id.ec_version_str) ?
+			thinkpad_id.ec_version_str : "(unknown)");
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,
+		 (thinkpad_id.ec_version_str) ?
+			thinkpad_id.ec_version_str : "unknown");
+
+	if (volume_control_allowed) {
+		volume_alsa_control_vol.put = volume_alsa_vol_put;
+		volume_alsa_control_vol.access =
+				SNDRV_CTL_ELEM_ACCESS_READWRITE;
+
+		volume_alsa_control_mute.put = volume_alsa_mute_put;
+		volume_alsa_control_mute.access =
+				SNDRV_CTL_ELEM_ACCESS_READWRITE;
+	}
+
+	if (!tp_features.mixer_no_level_control) {
+		ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
+		rc = snd_ctl_add(card, ctl_vol);
+		if (rc < 0) {
+			printk(TPACPI_ERR
+				"Failed to create ALSA volume control: %d\n",
+				rc);
+			goto err_exit;
 		}
+		data->ctl_vol_id = &ctl_vol->id;
+	}
 
-		if (new_mute != mute) {
-			/* level doesn't change */
+	ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
+	rc = snd_ctl_add(card, ctl_mute);
+	if (rc < 0) {
+		printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n",
+			rc);
+		goto err_exit;
+	}
+	data->ctl_mute_id = &ctl_mute->id;
 
-			cmos_cmd = (new_mute) ?
-				   TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
+	snd_card_set_dev(card, &tpacpi_pdev->dev);
+	rc = snd_card_register(card);
+	if (rc < 0) {
+		printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc);
+		goto err_exit;
+	}
 
-			if (issue_thinkpad_cmos_command(cmos_cmd) ||
-			    !acpi_ec_write(volume_offset, level + new_mute))
-				return -EIO;
+	alsa_card = card;
+	return 0;
+
+err_exit:
+	snd_card_free(card);
+	return 1;
+}
+
+#define TPACPI_VOL_Q_MUTEONLY	0x0001	/* Mute-only control available */
+#define TPACPI_VOL_Q_LEVEL	0x0002  /* Volume control available */
+
+static const struct tpacpi_quirk volume_quirk_table[] __initconst = {
+	/* Whitelist volume level on all IBM by default */
+	{ .vendor = PCI_VENDOR_ID_IBM,
+	  .bios   = TPACPI_MATCH_ANY,
+	  .ec     = TPACPI_MATCH_ANY,
+	  .quirks = TPACPI_VOL_Q_LEVEL },
+
+	/* Lenovo models with volume control (needs confirmation) */
+	TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL), /* R60/i */
+	TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL), /* R60e/i */
+	TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL), /* T60/p */
+	TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL), /* X60/s */
+	TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL), /* X60t */
+	TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL), /* Z60 */
+	TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL), /* Z61 */
+
+	/* Whitelist mute-only on all Lenovo by default */
+	{ .vendor = PCI_VENDOR_ID_LENOVO,
+	  .bios   = TPACPI_MATCH_ANY,
+	  .ec	  = TPACPI_MATCH_ANY,
+	  .quirks = TPACPI_VOL_Q_MUTEONLY }
+};
+
+static int __init volume_init(struct ibm_init_struct *iibm)
+{
+	unsigned long quirks;
+	int rc;
+
+	vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");
+
+	mutex_init(&volume_mutex);
+
+	/*
+	 * Check for module parameter bogosity, note that we
+	 * init volume_mode to TPACPI_VOL_MODE_MAX in order to be
+	 * able to detect "unspecified"
+	 */
+	if (volume_mode > TPACPI_VOL_MODE_MAX)
+		return -EINVAL;
+
+	if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
+		printk(TPACPI_ERR
+			"UCMS step volume mode not implemented, "
+			"please contact %s\n", TPACPI_MAIL);
+		return 1;
+	}
+
+	if (volume_capabilities >= TPACPI_VOL_CAP_MAX)
+		return -EINVAL;
+
+	/*
+	 * The ALSA mixer is our primary interface.
+	 * When disabled, don't install the subdriver at all
+	 */
+	if (!alsa_enable) {
+		vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+			    "ALSA mixer disabled by parameter, "
+			    "not loading volume subdriver...\n");
+		return 1;
+	}
+
+	quirks = tpacpi_check_quirks(volume_quirk_table,
+				     ARRAY_SIZE(volume_quirk_table));
+
+	switch (volume_capabilities) {
+	case TPACPI_VOL_CAP_AUTO:
+		if (quirks & TPACPI_VOL_Q_MUTEONLY)
+			tp_features.mixer_no_level_control = 1;
+		else if (quirks & TPACPI_VOL_Q_LEVEL)
+			tp_features.mixer_no_level_control = 0;
+		else
+			return 1; /* no mixer */
+		break;
+	case TPACPI_VOL_CAP_VOLMUTE:
+		tp_features.mixer_no_level_control = 0;
+		break;
+	case TPACPI_VOL_CAP_MUTEONLY:
+		tp_features.mixer_no_level_control = 1;
+		break;
+	default:
+		return 1;
+	}
+
+	if (volume_capabilities != TPACPI_VOL_CAP_AUTO)
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+				"using user-supplied volume_capabilities=%d\n",
+				volume_capabilities);
+
+	if (volume_mode == TPACPI_VOL_MODE_AUTO ||
+	    volume_mode == TPACPI_VOL_MODE_MAX) {
+		volume_mode = TPACPI_VOL_MODE_ECNVRAM;
+
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+				"driver auto-selected volume_mode=%d\n",
+				volume_mode);
+	} else {
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+				"using user-supplied volume_mode=%d\n",
+				volume_mode);
+	}
+
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+			"mute is supported, volume control is %s\n",
+			str_supported(!tp_features.mixer_no_level_control));
+
+	rc = volume_create_alsa_mixer();
+	if (rc) {
+		printk(TPACPI_ERR
+			"Could not create the ALSA mixer interface\n");
+		return rc;
+	}
+
+	printk(TPACPI_INFO
+		"Console audio control enabled, mode: %s\n",
+		(volume_control_allowed) ?
+			"override (read/write)" :
+			"monitor (read only)");
+
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
+		"registering volume hotkeys as change notification\n");
+	tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
+			| TP_ACPI_HKEY_VOLUP_MASK
+			| TP_ACPI_HKEY_VOLDWN_MASK
+			| TP_ACPI_HKEY_MUTE_MASK);
+
+	return 0;
+}
+
+static int volume_read(struct seq_file *m)
+{
+	u8 status;
+
+	if (volume_get_status(&status) < 0) {
+		seq_printf(m, "level:\t\tunreadable\n");
+	} else {
+		if (tp_features.mixer_no_level_control)
+			seq_printf(m, "level:\t\tunsupported\n");
+		else
+			seq_printf(m, "level:\t\t%d\n",
+					status & TP_EC_AUDIO_LVL_MSK);
+
+		seq_printf(m, "mute:\t\t%s\n",
+				onoff(status, TP_EC_AUDIO_MUTESW));
+
+		if (volume_control_allowed) {
+			seq_printf(m, "commands:\tunmute, mute\n");
+			if (!tp_features.mixer_no_level_control) {
+				seq_printf(m,
+					       "commands:\tup, down\n");
+				seq_printf(m,
+					       "commands:\tlevel <level>"
+					       " (<level> is 0-%d)\n",
+					       TP_EC_VOLUME_MAX);
+			}
 		}
 	}
 
 	return 0;
 }
 
+static int volume_write(char *buf)
+{
+	u8 s;
+	u8 new_level, new_mute;
+	int l;
+	char *cmd;
+	int rc;
+
+	/*
+	 * We do allow volume control at driver startup, so that the
+	 * user can set initial state through the volume=... parameter hack.
+	 */
+	if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
+		if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
+			tp_warned.volume_ctrl_forbidden = 1;
+			printk(TPACPI_NOTICE
+				"Console audio control in monitor mode, "
+				"changes are not allowed.\n");
+			printk(TPACPI_NOTICE
+				"Use the volume_control=1 module parameter "
+				"to enable volume control\n");
+		}
+		return -EPERM;
+	}
+
+	rc = volume_get_status(&s);
+	if (rc < 0)
+		return rc;
+
+	new_level = s & TP_EC_AUDIO_LVL_MSK;
+	new_mute  = s & TP_EC_AUDIO_MUTESW_MSK;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (!tp_features.mixer_no_level_control) {
+			if (strlencmp(cmd, "up") == 0) {
+				if (new_mute)
+					new_mute = 0;
+				else if (new_level < TP_EC_VOLUME_MAX)
+					new_level++;
+				continue;
+			} else if (strlencmp(cmd, "down") == 0) {
+				if (new_mute)
+					new_mute = 0;
+				else if (new_level > 0)
+					new_level--;
+				continue;
+			} else if (sscanf(cmd, "level %u", &l) == 1 &&
+				   l >= 0 && l <= TP_EC_VOLUME_MAX) {
+					new_level = l;
+				continue;
+			}
+		}
+		if (strlencmp(cmd, "mute") == 0)
+			new_mute = TP_EC_AUDIO_MUTESW_MSK;
+		else if (strlencmp(cmd, "unmute") == 0)
+			new_mute = 0;
+		else
+			return -EINVAL;
+	}
+
+	if (tp_features.mixer_no_level_control) {
+		tpacpi_disclose_usertask("procfs volume", "%smute\n",
+					new_mute ? "" : "un");
+		rc = volume_set_mute(!!new_mute);
+	} else {
+		tpacpi_disclose_usertask("procfs volume",
+					"%smute and set level to %d\n",
+					new_mute ? "" : "un", new_level);
+		rc = volume_set_status(new_mute | new_level);
+	}
+	volume_alsa_notify_change();
+
+	return (rc == -EINTR) ? -ERESTARTSYS : rc;
+}
+
 static struct ibm_struct volume_driver_data = {
 	.name = "volume",
 	.read = volume_read,
 	.write = volume_write,
+	.exit = volume_exit,
+	.suspend = volume_suspend,
+	.resume = volume_resume,
+	.shutdown = volume_shutdown,
+};
+
+#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
+
+#define alsa_card NULL
+
+static void inline volume_alsa_notify_change(void)
+{
+}
+
+static int __init volume_init(struct ibm_init_struct *iibm)
+{
+	printk(TPACPI_INFO
+		"volume: disabled as there is no ALSA support in this kernel\n");
+
+	return 1;
+}
+
+static struct ibm_struct volume_driver_data = {
+	.name = "volume",
 };
 
+#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
+
 /*************************************************************************
  * Fan subdriver
  */
@@ -6545,7 +7154,7 @@ static struct ibm_struct volume_driver_d
  * 	The speeds are stored on handles
  * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
  *
- * 	There are three default speed sets, acessible as handles:
+ * 	There are three default speed sets, accessible as handles:
  * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
  *
  * 	ACPI DSDT switches which set is in use depending on various
@@ -7510,9 +8119,8 @@ static void fan_resume(void)
 	}
 }
 
-static int fan_read(char *p)
+static int fan_read(struct seq_file *m)
 {
-	int len = 0;
 	int rc;
 	u8 status;
 	unsigned int speed = 0;
@@ -7524,7 +8132,7 @@ static int fan_read(char *p)
 		if (rc < 0)
 			return rc;
 
-		len += sprintf(p + len, "status:\t\t%s\n"
+		seq_printf(m, "status:\t\t%s\n"
 			       "level:\t\t%d\n",
 			       (status != 0) ? "enabled" : "disabled", status);
 		break;
@@ -7535,54 +8143,54 @@ static int fan_read(char *p)
 		if (rc < 0)
 			return rc;
 
-		len += sprintf(p + len, "status:\t\t%s\n",
+		seq_printf(m, "status:\t\t%s\n",
 			       (status != 0) ? "enabled" : "disabled");
 
 		rc = fan_get_speed(&speed);
 		if (rc < 0)
 			return rc;
 
-		len += sprintf(p + len, "speed:\t\t%d\n", speed);
+		seq_printf(m, "speed:\t\t%d\n", speed);
 
 		if (status & TP_EC_FAN_FULLSPEED)
 			/* Disengaged mode takes precedence */
-			len += sprintf(p + len, "level:\t\tdisengaged\n");
+			seq_printf(m, "level:\t\tdisengaged\n");
 		else if (status & TP_EC_FAN_AUTO)
-			len += sprintf(p + len, "level:\t\tauto\n");
+			seq_printf(m, "level:\t\tauto\n");
 		else
-			len += sprintf(p + len, "level:\t\t%d\n", status);
+			seq_printf(m, "level:\t\t%d\n", status);
 		break;
 
 	case TPACPI_FAN_NONE:
 	default:
-		len += sprintf(p + len, "status:\t\tnot supported\n");
+		seq_printf(m, "status:\t\tnot supported\n");
 	}
 
 	if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
-		len += sprintf(p + len, "commands:\tlevel <level>");
+		seq_printf(m, "commands:\tlevel <level>");
 
 		switch (fan_control_access_mode) {
 		case TPACPI_FAN_WR_ACPI_SFAN:
-			len += sprintf(p + len, " (<level> is 0-7)\n");
+			seq_printf(m, " (<level> is 0-7)\n");
 			break;
 
 		default:
-			len += sprintf(p + len, " (<level> is 0-7, "
+			seq_printf(m, " (<level> is 0-7, "
 				       "auto, disengaged, full-speed)\n");
 			break;
 		}
 	}
 
 	if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
-		len += sprintf(p + len, "commands:\tenable, disable\n"
+		seq_printf(m, "commands:\tenable, disable\n"
 			       "commands:\twatchdog <timeout> (<timeout> "
 			       "is 0 (off), 1-120 (seconds))\n");
 
 	if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
-		len += sprintf(p + len, "commands:\tspeed <speed>"
+		seq_printf(m, "commands:\tspeed <speed>"
 			       " (<speed> is 0-65535)\n");
 
-	return len;
+	return 0;
 }
 
 static int fan_write_cmd_level(const char *cmd, int *rc)
@@ -7724,10 +8332,23 @@ static struct ibm_struct fan_driver_data
  */
 static void tpacpi_driver_event(const unsigned int hkey_event)
 {
+	if (ibm_backlight_device) {
+		switch (hkey_event) {
+		case TP_HKEY_EV_BRGHT_UP:
+		case TP_HKEY_EV_BRGHT_DOWN:
+			tpacpi_brightness_notify_change();
+		}
+	}
+	if (alsa_card) {
+		switch (hkey_event) {
+		case TP_HKEY_EV_VOL_UP:
+		case TP_HKEY_EV_VOL_DOWN:
+		case TP_HKEY_EV_VOL_MUTE:
+			volume_alsa_notify_change();
+		}
+	}
 }
 
-
-
 static void hotkey_driver_event(const unsigned int scancode)
 {
 	tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
@@ -7856,19 +8477,19 @@ static int __init ibm_init(struct ibm_in
 		"%s installed\n", ibm->name);
 
 	if (ibm->read) {
-		entry = create_proc_entry(ibm->name,
-					  S_IFREG | S_IRUGO | S_IWUSR,
-					  proc_dir);
+		mode_t mode;
+
+		mode = S_IRUGO;
+		if (ibm->write)
+			mode |= S_IWUSR;
+		entry = proc_create_data(ibm->name, mode, proc_dir,
+					 &dispatch_proc_fops, ibm);
 		if (!entry) {
 			printk(TPACPI_ERR "unable to create proc entry %s\n",
 			       ibm->name);
 			ret = -ENODEV;
 			goto err_out;
 		}
-		entry->data = ibm;
-		entry->read_proc = &dispatch_procfs_read;
-		if (ibm->write)
-			entry->write_proc = &dispatch_procfs_write;
 		ibm->flags.proc_created = 1;
 	}
 
@@ -8080,6 +8701,7 @@ static struct ibm_init_struct ibms_init[
 		.data = &brightness_driver_data,
 	},
 	{
+		.init = volume_init,
 		.data = &volume_driver_data,
 	},
 	{
@@ -8115,36 +8737,61 @@ static int __init set_ibm_param(const ch
 	return -EINVAL;
 }
 
-module_param(experimental, int, 0);
+module_param(experimental, int, 0444);
 MODULE_PARM_DESC(experimental,
 		 "Enables experimental features when non-zero");
 
 module_param_named(debug, dbg_level, uint, 0);
 MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
 
-module_param(force_load, bool, 0);
+module_param(force_load, bool, 0444);
 MODULE_PARM_DESC(force_load,
 		 "Attempts to load the driver even on a "
 		 "mis-identified ThinkPad when true");
 
-module_param_named(fan_control, fan_control_allowed, bool, 0);
+module_param_named(fan_control, fan_control_allowed, bool, 0444);
 MODULE_PARM_DESC(fan_control,
 		 "Enables setting fan parameters features when true");
 
-module_param_named(brightness_mode, brightness_mode, uint, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0444);
 MODULE_PARM_DESC(brightness_mode,
 		 "Selects brightness control strategy: "
 		 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
 
-module_param(brightness_enable, uint, 0);
+module_param(brightness_enable, uint, 0444);
 MODULE_PARM_DESC(brightness_enable,
 		 "Enables backlight control when 1, disables when 0");
 
-module_param(hotkey_report_mode, uint, 0);
+module_param(hotkey_report_mode, uint, 0444);
 MODULE_PARM_DESC(hotkey_report_mode,
 		 "used for backwards compatibility with userspace, "
 		 "see documentation");
 
+#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
+module_param_named(volume_mode, volume_mode, uint, 0444);
+MODULE_PARM_DESC(volume_mode,
+		 "Selects volume control strategy: "
+		 "0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");
+
+module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
+MODULE_PARM_DESC(volume_capabilities,
+		 "Selects the mixer capabilites: "
+		 "0=auto, 1=volume and mute, 2=mute only");
+
+module_param_named(volume_control, volume_control_allowed, bool, 0444);
+MODULE_PARM_DESC(volume_control,
+		 "Enables software override for the console audio "
+		 "control when true");
+
+/* ALSA module API parameters */
+module_param_named(index, alsa_index, int, 0444);
+MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
+module_param_named(id, alsa_id, charp, 0444);
+MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
+module_param_named(enable, alsa_enable, bool, 0444);
+MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
+#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
+
 #define TPACPI_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
 	MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
@@ -8163,25 +8810,25 @@ TPACPI_PARAM(volume);
 TPACPI_PARAM(fan);
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
-module_param(dbg_wlswemul, uint, 0);
+module_param(dbg_wlswemul, uint, 0444);
 MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
 module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
 MODULE_PARM_DESC(wlsw_state,
 		 "Initial state of the emulated WLSW switch");
 
-module_param(dbg_bluetoothemul, uint, 0);
+module_param(dbg_bluetoothemul, uint, 0444);
 MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
 module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
 MODULE_PARM_DESC(bluetooth_state,
 		 "Initial state of the emulated bluetooth switch");
 
-module_param(dbg_wwanemul, uint, 0);
+module_param(dbg_wwanemul, uint, 0444);
 MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
 module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
 MODULE_PARM_DESC(wwan_state,
 		 "Initial state of the emulated WWAN switch");
 
-module_param(dbg_uwbemul, uint, 0);
+module_param(dbg_uwbemul, uint, 0444);
 MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
 module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
 MODULE_PARM_DESC(uwb_state,
@@ -8374,6 +9021,7 @@ static int __init thinkpad_acpi_module_i
 						PCI_VENDOR_ID_IBM;
 		tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
 		tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
+		tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
 	}
 	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
 		ret = ibm_init(&ibms_init[i]);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/toshiba_acpi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_acpi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/toshiba_acpi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_acpi.c	2010-02-24 13:52:17.000000000 -0500
@@ -42,6 +42,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
 #include <linux/rfkill.h>
@@ -357,63 +358,6 @@ static int force_fan;
 static int last_key_event;
 static int key_event_valid;
 
-typedef struct _ProcItem {
-	const char *name;
-	char *(*read_func) (char *);
-	unsigned long (*write_func) (const char *, unsigned long);
-} ProcItem;
-
-/* proc file handlers
- */
-
-static int
-dispatch_read(char *page, char **start, off_t off, int count, int *eof,
-	      ProcItem * item)
-{
-	char *p = page;
-	int len;
-
-	if (off == 0)
-		p = item->read_func(p);
-
-	/* ISSUE: I don't understand this code */
-	len = (p - page);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
-}
-
-static int
-dispatch_write(struct file *file, const char __user * buffer,
-	       unsigned long count, ProcItem * item)
-{
-	int result;
-	char *tmp_buffer;
-
-	/* Arg buffer points to userspace memory, which can't be accessed
-	 * directly.  Since we're making a copy, zero-terminate the
-	 * destination so that sscanf can be used on it safely.
-	 */
-	tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
-	if (!tmp_buffer)
-		return -ENOMEM;
-
-	if (copy_from_user(tmp_buffer, buffer, count)) {
-		result = -EFAULT;
-	} else {
-		tmp_buffer[count] = 0;
-		result = item->write_func(tmp_buffer, count);
-	}
-	kfree(tmp_buffer);
-	return result;
-}
-
 static int get_lcd(struct backlight_device *bd)
 {
 	u32 hci_result;
@@ -426,19 +370,24 @@ static int get_lcd(struct backlight_devi
 		return -EFAULT;
 }
 
-static char *read_lcd(char *p)
+static int lcd_proc_show(struct seq_file *m, void *v)
 {
 	int value = get_lcd(NULL);
 
 	if (value >= 0) {
-		p += sprintf(p, "brightness:              %d\n", value);
-		p += sprintf(p, "brightness_levels:       %d\n",
+		seq_printf(m, "brightness:              %d\n", value);
+		seq_printf(m, "brightness_levels:       %d\n",
 			     HCI_LCD_BRIGHTNESS_LEVELS);
 	} else {
 		printk(MY_ERR "Error reading LCD brightness\n");
 	}
 
-	return p;
+	return 0;
+}
+
+static int lcd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, lcd_proc_show, NULL);
 }
 
 static int set_lcd(int value)
@@ -458,12 +407,20 @@ static int set_lcd_status(struct backlig
 	return set_lcd(bd->props.brightness);
 }
 
-static unsigned long write_lcd(const char *buffer, unsigned long count)
+static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
+			      size_t count, loff_t *pos)
 {
+	char cmd[42];
+	size_t len;
 	int value;
 	int ret;
 
-	if (sscanf(buffer, " brightness : %i", &value) == 1 &&
+	len = min(count, sizeof(cmd) - 1);
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+	cmd[len] = '\0';
+
+	if (sscanf(cmd, " brightness : %i", &value) == 1 &&
 	    value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
 		ret = set_lcd(value);
 		if (ret == 0)
@@ -474,7 +431,16 @@ static unsigned long write_lcd(const cha
 	return ret;
 }
 
-static char *read_video(char *p)
+static const struct file_operations lcd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= lcd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= lcd_proc_write,
+};
+
+static int video_proc_show(struct seq_file *m, void *v)
 {
 	u32 hci_result;
 	u32 value;
@@ -484,18 +450,25 @@ static char *read_video(char *p)
 		int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
 		int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
 		int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
-		p += sprintf(p, "lcd_out:                 %d\n", is_lcd);
-		p += sprintf(p, "crt_out:                 %d\n", is_crt);
-		p += sprintf(p, "tv_out:                  %d\n", is_tv);
+		seq_printf(m, "lcd_out:                 %d\n", is_lcd);
+		seq_printf(m, "crt_out:                 %d\n", is_crt);
+		seq_printf(m, "tv_out:                  %d\n", is_tv);
 	} else {
 		printk(MY_ERR "Error reading video out status\n");
 	}
 
-	return p;
+	return 0;
 }
 
-static unsigned long write_video(const char *buffer, unsigned long count)
+static int video_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, video_proc_show, NULL);
+}
+
+static ssize_t video_proc_write(struct file *file, const char __user *buf,
+				size_t count, loff_t *pos)
 {
+	char *cmd, *buffer;
 	int value;
 	int remain = count;
 	int lcd_out = -1;
@@ -504,6 +477,17 @@ static unsigned long write_video(const c
 	u32 hci_result;
 	u32 video_out;
 
+	cmd = kmalloc(count + 1, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	if (copy_from_user(cmd, buf, count)) {
+		kfree(cmd);
+		return -EFAULT;
+	}
+	cmd[count] = '\0';
+
+	buffer = cmd;
+
 	/* scan expression.  Multiple expressions may be delimited with ;
 	 *
 	 *  NOTE: to keep scanning simple, invalid fields are ignored
@@ -523,6 +507,8 @@ static unsigned long write_video(const c
 		while (remain && *(buffer - 1) != ';');
 	}
 
+	kfree(cmd);
+
 	hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
 	if (hci_result == HCI_SUCCESS) {
 		unsigned int new_video_out = video_out;
@@ -543,28 +529,50 @@ static unsigned long write_video(const c
 	return count;
 }
 
-static char *read_fan(char *p)
+static const struct file_operations video_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= video_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= video_proc_write,
+};
+
+static int fan_proc_show(struct seq_file *m, void *v)
 {
 	u32 hci_result;
 	u32 value;
 
 	hci_read1(HCI_FAN, &value, &hci_result);
 	if (hci_result == HCI_SUCCESS) {
-		p += sprintf(p, "running:                 %d\n", (value > 0));
-		p += sprintf(p, "force_on:                %d\n", force_fan);
+		seq_printf(m, "running:                 %d\n", (value > 0));
+		seq_printf(m, "force_on:                %d\n", force_fan);
 	} else {
 		printk(MY_ERR "Error reading fan status\n");
 	}
 
-	return p;
+	return 0;
 }
 
-static unsigned long write_fan(const char *buffer, unsigned long count)
+static int fan_proc_open(struct inode *inode, struct file *file)
 {
+	return single_open(file, fan_proc_show, NULL);
+}
+
+static ssize_t fan_proc_write(struct file *file, const char __user *buf,
+			      size_t count, loff_t *pos)
+{
+	char cmd[42];
+	size_t len;
 	int value;
 	u32 hci_result;
 
-	if (sscanf(buffer, " force_on : %i", &value) == 1 &&
+	len = min(count, sizeof(cmd) - 1);
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+	cmd[len] = '\0';
+
+	if (sscanf(cmd, " force_on : %i", &value) == 1 &&
 	    value >= 0 && value <= 1) {
 		hci_write1(HCI_FAN, value, &hci_result);
 		if (hci_result != HCI_SUCCESS)
@@ -578,7 +586,16 @@ static unsigned long write_fan(const cha
 	return count;
 }
 
-static char *read_keys(char *p)
+static const struct file_operations fan_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fan_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= fan_proc_write,
+};
+
+static int keys_proc_show(struct seq_file *m, void *v)
 {
 	u32 hci_result;
 	u32 value;
@@ -602,18 +619,30 @@ static char *read_keys(char *p)
 		}
 	}
 
-	p += sprintf(p, "hotkey_ready:            %d\n", key_event_valid);
-	p += sprintf(p, "hotkey:                  0x%04x\n", last_key_event);
+	seq_printf(m, "hotkey_ready:            %d\n", key_event_valid);
+	seq_printf(m, "hotkey:                  0x%04x\n", last_key_event);
+end:
+	return 0;
+}
 
-      end:
-	return p;
+static int keys_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, keys_proc_show, NULL);
 }
 
-static unsigned long write_keys(const char *buffer, unsigned long count)
+static ssize_t keys_proc_write(struct file *file, const char __user *buf,
+			       size_t count, loff_t *pos)
 {
+	char cmd[42];
+	size_t len;
 	int value;
 
-	if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) {
+	len = min(count, sizeof(cmd) - 1);
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+	cmd[len] = '\0';
+
+	if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) {
 		key_event_valid = 0;
 	} else {
 		return -EINVAL;
@@ -622,52 +651,58 @@ static unsigned long write_keys(const ch
 	return count;
 }
 
-static char *read_version(char *p)
+static const struct file_operations keys_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= keys_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= keys_proc_write,
+};
+
+static int version_proc_show(struct seq_file *m, void *v)
 {
-	p += sprintf(p, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
-	p += sprintf(p, "proc_interface:          %d\n",
-		     PROC_INTERFACE_VERSION);
-	return p;
+	seq_printf(m, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
+	seq_printf(m, "proc_interface:          %d\n", PROC_INTERFACE_VERSION);
+	return 0;
 }
 
+static int version_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, version_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations version_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= version_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* proc and module init
  */
 
 #define PROC_TOSHIBA		"toshiba"
 
-static ProcItem proc_items[] = {
-	{"lcd", read_lcd, write_lcd},
-	{"video", read_video, write_video},
-	{"fan", read_fan, write_fan},
-	{"keys", read_keys, write_keys},
-	{"version", read_version, NULL},
-	{NULL}
-};
-
 static acpi_status __init add_device(void)
 {
-	struct proc_dir_entry *proc;
-	ProcItem *item;
-
-	for (item = proc_items; item->name; ++item) {
-		proc = create_proc_read_entry(item->name,
-					      S_IFREG | S_IRUGO | S_IWUSR,
-					      toshiba_proc_dir,
-					      (read_proc_t *) dispatch_read,
-					      item);
-		if (proc && item->write_func)
-			proc->write_proc = (write_proc_t *) dispatch_write;
-	}
+	proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops);
+	proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops);
+	proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops);
+	proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops);
+	proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops);
 
 	return AE_OK;
 }
 
 static acpi_status remove_device(void)
 {
-	ProcItem *item;
-
-	for (item = proc_items; item->name; ++item)
-		remove_proc_entry(item->name, toshiba_proc_dir);
+	remove_proc_entry("lcd", toshiba_proc_dir);
+	remove_proc_entry("video", toshiba_proc_dir);
+	remove_proc_entry("fan", toshiba_proc_dir);
+	remove_proc_entry("keys", toshiba_proc_dir);
+	remove_proc_entry("version", toshiba_proc_dir);
 	return AE_OK;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/toshiba_bluetooth.c linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_bluetooth.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/toshiba_bluetooth.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/toshiba_bluetooth.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,144 @@
+/*
+ * Toshiba Bluetooth Enable Driver
+ *
+ * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com>
+ *
+ * Thanks to Matthew Garrett for background info on ACPI innards which
+ * normal people aren't meant to understand :-)
+ *
+ * This 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.
+ *
+ * Note the Toshiba Bluetooth RFKill switch seems to be a strange
+ * fish. It only provides a BT event when the switch is flipped to
+ * the 'on' position. When flipping it to 'off', the USB device is
+ * simply pulled away underneath us, without any BT event being
+ * delivered.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
+MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver");
+MODULE_LICENSE("GPL");
+
+
+static int toshiba_bt_rfkill_add(struct acpi_device *device);
+static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type);
+static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
+static int toshiba_bt_resume(struct acpi_device *device);
+
+static const struct acpi_device_id bt_device_ids[] = {
+	{ "TOS6205", 0},
+	{ "", 0},
+};
+MODULE_DEVICE_TABLE(acpi, bt_device_ids);
+
+static struct acpi_driver toshiba_bt_rfkill_driver = {
+	.name =		"Toshiba BT",
+	.class =	"Toshiba",
+	.ids =		bt_device_ids,
+	.ops =		{
+				.add =		toshiba_bt_rfkill_add,
+				.remove =	toshiba_bt_rfkill_remove,
+				.notify =	toshiba_bt_rfkill_notify,
+				.resume =	toshiba_bt_resume,
+			},
+	.owner = 	THIS_MODULE,
+};
+
+
+static int toshiba_bluetooth_enable(acpi_handle handle)
+{
+	acpi_status res1, res2;
+	acpi_integer result;
+
+	/*
+	 * Query ACPI to verify RFKill switch is set to 'on'.
+	 * If not, we return silently, no need to report it as
+	 * an error.
+	 */
+	res1 = acpi_evaluate_integer(handle, "BTST", NULL, &result);
+	if (ACPI_FAILURE(res1))
+		return res1;
+	if (!(result & 0x01))
+		return 0;
+
+	printk(KERN_INFO "toshiba_bluetooth: Re-enabling Toshiba Bluetooth\n");
+	res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL);
+	res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL);
+	if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2))
+		return 0;
+
+	printk(KERN_WARNING "toshiba_bluetooth: Failed to re-enable "
+	       "Toshiba Bluetooth\n");
+
+	return -ENODEV;
+}
+
+static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event)
+{
+	toshiba_bluetooth_enable(device->handle);
+}
+
+static int toshiba_bt_resume(struct acpi_device *device)
+{
+	return toshiba_bluetooth_enable(device->handle);
+}
+
+static int toshiba_bt_rfkill_add(struct acpi_device *device)
+{
+	acpi_status status;
+	acpi_integer bt_present;
+	int result = -ENODEV;
+
+	/*
+	 * Some Toshiba laptops may have a fake TOS6205 device in
+	 * their ACPI BIOS, so query the _STA method to see if there
+	 * is really anything there, before trying to enable it.
+	 */
+	status = acpi_evaluate_integer(device->handle, "_STA", NULL,
+				       &bt_present);
+
+	if (!ACPI_FAILURE(status) && bt_present) {
+		printk(KERN_INFO "Detected Toshiba ACPI Bluetooth device - "
+		      "installing RFKill handler\n");
+		result = toshiba_bluetooth_enable(device->handle);
+	}
+
+	return result;
+}
+
+static int __init toshiba_bt_rfkill_init(void)
+{
+	int result;
+
+	result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver);
+	if (result < 0) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Error registering driver\n"));
+		return result;
+	}
+
+	return 0;
+}
+
+static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
+{
+	/* clean up */
+	return 0;
+}
+
+static void __exit toshiba_bt_rfkill_exit(void)
+{
+	acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver);
+}
+
+module_init(toshiba_bt_rfkill_init);
+module_exit(toshiba_bt_rfkill_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/platform/x86/wmi.c linux-libre-2.6.33-gnu1/drivers/platform/x86/wmi.c
--- linux-libre-2.6.32-gnu1/drivers/platform/x86/wmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/platform/x86/wmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/device.h>
 #include <linux/list.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
@@ -65,6 +66,7 @@ struct wmi_block {
 	acpi_handle handle;
 	wmi_notify_handler handler;
 	void *handler_data;
+	struct device *dev;
 };
 
 static struct wmi_block wmi_blocks;
@@ -195,6 +197,34 @@ static bool wmi_parse_guid(const u8 *src
 	return true;
 }
 
+/*
+ * Convert a raw GUID to the ACII string representation
+ */
+static int wmi_gtoa(const char *in, char *out)
+{
+	int i;
+
+	for (i = 3; i >= 0; i--)
+		out += sprintf(out, "%02X", in[i] & 0xFF);
+
+	out += sprintf(out, "-");
+	out += sprintf(out, "%02X", in[5] & 0xFF);
+	out += sprintf(out, "%02X", in[4] & 0xFF);
+	out += sprintf(out, "-");
+	out += sprintf(out, "%02X", in[7] & 0xFF);
+	out += sprintf(out, "%02X", in[6] & 0xFF);
+	out += sprintf(out, "-");
+	out += sprintf(out, "%02X", in[8] & 0xFF);
+	out += sprintf(out, "%02X", in[9] & 0xFF);
+	out += sprintf(out, "-");
+
+	for (i = 10; i <= 15; i++)
+		out += sprintf(out, "%02X", in[i] & 0xFF);
+
+	out = '\0';
+	return 0;
+}
+
 static bool find_guid(const char *guid_string, struct wmi_block **out)
 {
 	char tmp[16], guid_input[16];
@@ -462,8 +492,7 @@ wmi_notify_handler handler, void *data)
 	if (!guid || !handler)
 		return AE_BAD_PARAMETER;
 
-	find_guid(guid, &block);
-	if (!block)
+	if (!find_guid(guid, &block))
 		return AE_NOT_EXIST;
 
 	if (block->handler)
@@ -491,8 +520,7 @@ acpi_status wmi_remove_notify_handler(co
 	if (!guid)
 		return AE_BAD_PARAMETER;
 
-	find_guid(guid, &block);
-	if (!block)
+	if (!find_guid(guid, &block))
 		return AE_NOT_EXIST;
 
 	if (!block->handler)
@@ -510,8 +538,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_hand
 /**
  * wmi_get_event_data - Get WMI data associated with an event
  *
- * @event - Event to find
- * &out - Buffer to hold event data
+ * @event: Event to find
+ * @out: Buffer to hold event data. out->pointer should be freed with kfree()
  *
  * Returns extra data associated with an event in WMI.
  */
@@ -555,6 +583,154 @@ bool wmi_has_guid(const char *guid_strin
 EXPORT_SYMBOL_GPL(wmi_has_guid);
 
 /*
+ * sysfs interface
+ */
+static ssize_t show_modalias(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	char guid_string[37];
+	struct wmi_block *wblock;
+
+	wblock = dev_get_drvdata(dev);
+	if (!wblock)
+		return -ENOMEM;
+
+	wmi_gtoa(wblock->gblock.guid, guid_string);
+
+	return sprintf(buf, "wmi:%s\n", guid_string);
+}
+static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+
+static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	char guid_string[37];
+
+	struct wmi_block *wblock;
+
+	if (add_uevent_var(env, "MODALIAS="))
+		return -ENOMEM;
+
+	wblock = dev_get_drvdata(dev);
+	if (!wblock)
+		return -ENOMEM;
+
+	wmi_gtoa(wblock->gblock.guid, guid_string);
+
+	strcpy(&env->buf[env->buflen - 1], "wmi:");
+	memcpy(&env->buf[env->buflen - 1 + 4], guid_string, 36);
+	env->buflen += 40;
+
+	return 0;
+}
+
+static void wmi_dev_free(struct device *dev)
+{
+	kfree(dev);
+}
+
+static struct class wmi_class = {
+	.name = "wmi",
+	.dev_release = wmi_dev_free,
+	.dev_uevent = wmi_dev_uevent,
+};
+
+static int wmi_create_devs(void)
+{
+	int result;
+	char guid_string[37];
+	struct guid_block *gblock;
+	struct wmi_block *wblock;
+	struct list_head *p;
+	struct device *guid_dev;
+
+	/* Create devices for all the GUIDs */
+	list_for_each(p, &wmi_blocks.list) {
+		wblock = list_entry(p, struct wmi_block, list);
+
+		guid_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+		if (!guid_dev)
+			return -ENOMEM;
+
+		wblock->dev = guid_dev;
+
+		guid_dev->class = &wmi_class;
+		dev_set_drvdata(guid_dev, wblock);
+
+		gblock = &wblock->gblock;
+
+		wmi_gtoa(gblock->guid, guid_string);
+		dev_set_name(guid_dev, guid_string);
+
+		result = device_register(guid_dev);
+		if (result)
+			return result;
+
+		result = device_create_file(guid_dev, &dev_attr_modalias);
+		if (result)
+			return result;
+	}
+
+	return 0;
+}
+
+static void wmi_remove_devs(void)
+{
+	struct guid_block *gblock;
+	struct wmi_block *wblock;
+	struct list_head *p;
+	struct device *guid_dev;
+
+	/* Delete devices for all the GUIDs */
+	list_for_each(p, &wmi_blocks.list) {
+		wblock = list_entry(p, struct wmi_block, list);
+
+		guid_dev = wblock->dev;
+		gblock = &wblock->gblock;
+
+		device_remove_file(guid_dev, &dev_attr_modalias);
+
+		device_unregister(guid_dev);
+	}
+}
+
+static void wmi_class_exit(void)
+{
+	wmi_remove_devs();
+	class_unregister(&wmi_class);
+}
+
+static int wmi_class_init(void)
+{
+	int ret;
+
+	ret = class_register(&wmi_class);
+	if (ret)
+		return ret;
+
+	ret = wmi_create_devs();
+	if (ret)
+		wmi_class_exit();
+
+	return ret;
+}
+
+static bool guid_already_parsed(const char *guid_string)
+{
+	struct guid_block *gblock;
+	struct wmi_block *wblock;
+	struct list_head *p;
+
+	list_for_each(p, &wmi_blocks.list) {
+		wblock = list_entry(p, struct wmi_block, list);
+		gblock = &wblock->gblock;
+
+		if (strncmp(gblock->guid, guid_string, 16) == 0)
+			return true;
+	}
+	return false;
+}
+
+/*
  * Parse the _WDG method for the GUID data blocks
  */
 static __init acpi_status parse_wdg(acpi_handle handle)
@@ -563,6 +739,7 @@ static __init acpi_status parse_wdg(acpi
 	union acpi_object *obj;
 	struct guid_block *gblock;
 	struct wmi_block *wblock;
+	char guid_string[37];
 	acpi_status status;
 	u32 i, total;
 
@@ -585,6 +762,19 @@ static __init acpi_status parse_wdg(acpi
 	memcpy(gblock, obj->buffer.pointer, obj->buffer.length);
 
 	for (i = 0; i < total; i++) {
+		/*
+		  Some WMI devices, like those for nVidia hooks, have a
+		  duplicate GUID. It's not clear what we should do in this
+		  case yet, so for now, we'll just ignore the duplicate.
+		  Anyone who wants to add support for that device can come
+		  up with a better workaround for the mess then.
+		*/
+		if (guid_already_parsed(gblock[i].guid) == true) {
+			wmi_gtoa(gblock[i].guid, guid_string);
+			printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n",
+				guid_string);
+			continue;
+		}
 		wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
 		if (!wblock)
 			return AE_NO_MEMORY;
@@ -709,10 +899,17 @@ static int __init acpi_wmi_init(void)
 
 	if (result < 0) {
 		printk(KERN_INFO PREFIX "Error loading mapper\n");
-	} else {
-		printk(KERN_INFO PREFIX "Mapper loaded\n");
+		return -ENODEV;
 	}
 
+	result = wmi_class_init();
+	if (result) {
+		acpi_bus_unregister_driver(&acpi_wmi_driver);
+		return result;
+	}
+
+	printk(KERN_INFO PREFIX "Mapper loaded\n");
+
 	return result;
 }
 
@@ -721,6 +918,8 @@ static void __exit acpi_wmi_exit(void)
 	struct list_head *p, *tmp;
 	struct wmi_block *wblock;
 
+	wmi_class_exit();
+
 	acpi_bus_unregister_driver(&acpi_wmi_driver);
 
 	list_for_each_safe(p, tmp, &wmi_blocks.list) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/interface.c linux-libre-2.6.33-gnu1/drivers/pnp/interface.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/interface.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/interface.c	2010-02-24 13:52:17.000000000 -0500
@@ -310,8 +310,7 @@ static ssize_t pnp_set_current_resources
 		goto done;
 	}
 
-	while (isspace(*buf))
-		++buf;
+	buf = skip_spaces(buf);
 	if (!strnicmp(buf, "disable", 7)) {
 		retval = pnp_disable_dev(dev);
 		goto done;
@@ -353,19 +352,13 @@ static ssize_t pnp_set_current_resources
 		pnp_init_resources(dev);
 		mutex_lock(&pnp_res_mutex);
 		while (1) {
-			while (isspace(*buf))
-				++buf;
+			buf = skip_spaces(buf);
 			if (!strnicmp(buf, "io", 2)) {
-				buf += 2;
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf + 2);
 				start = simple_strtoul(buf, &buf, 0);
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf);
 				if (*buf == '-') {
-					buf += 1;
-					while (isspace(*buf))
-						++buf;
+					buf = skip_spaces(buf + 1);
 					end = simple_strtoul(buf, &buf, 0);
 				} else
 					end = start;
@@ -373,16 +366,11 @@ static ssize_t pnp_set_current_resources
 				continue;
 			}
 			if (!strnicmp(buf, "mem", 3)) {
-				buf += 3;
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf + 3);
 				start = simple_strtoul(buf, &buf, 0);
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf);
 				if (*buf == '-') {
-					buf += 1;
-					while (isspace(*buf))
-						++buf;
+					buf = skip_spaces(buf + 1);
 					end = simple_strtoul(buf, &buf, 0);
 				} else
 					end = start;
@@ -390,17 +378,13 @@ static ssize_t pnp_set_current_resources
 				continue;
 			}
 			if (!strnicmp(buf, "irq", 3)) {
-				buf += 3;
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf + 3);
 				start = simple_strtoul(buf, &buf, 0);
 				pnp_add_irq_resource(dev, start, 0);
 				continue;
 			}
 			if (!strnicmp(buf, "dma", 3)) {
-				buf += 3;
-				while (isspace(*buf))
-					++buf;
+				buf = skip_spaces(buf + 3);
 				start = simple_strtoul(buf, &buf, 0);
 				pnp_add_dma_resource(dev, start, 0);
 				continue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/pnpacpi/core.c linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/core.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/pnpacpi/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -80,7 +80,8 @@ static int pnpacpi_get_resources(struct
 
 static int pnpacpi_set_resources(struct pnp_dev *dev)
 {
-	acpi_handle handle = dev->data;
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	struct acpi_buffer buffer;
 	int ret;
 
@@ -103,7 +104,8 @@ static int pnpacpi_set_resources(struct
 
 static int pnpacpi_disable_resources(struct pnp_dev *dev)
 {
-	acpi_handle handle = dev->data;
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	int ret;
 
 	dev_dbg(&dev->dev, "disable resources\n");
@@ -121,6 +123,8 @@ static int pnpacpi_disable_resources(str
 #ifdef CONFIG_ACPI_SLEEP
 static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
 {
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	int power_state;
 
 	power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
@@ -128,16 +132,19 @@ static int pnpacpi_suspend(struct pnp_de
 		power_state = (state.event == PM_EVENT_ON) ?
 				ACPI_STATE_D0 : ACPI_STATE_D3;
 
-	return acpi_bus_set_power((acpi_handle) dev->data, power_state);
+	return acpi_bus_set_power(handle, power_state);
 }
 
 static int pnpacpi_resume(struct pnp_dev *dev)
 {
-	return acpi_bus_set_power((acpi_handle) dev->data, ACPI_STATE_D0);
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
+
+	return acpi_bus_set_power(handle, ACPI_STATE_D0);
 }
 #endif
 
-static struct pnp_protocol pnpacpi_protocol = {
+struct pnp_protocol pnpacpi_protocol = {
 	.name	 = "Plug and Play ACPI",
 	.get	 = pnpacpi_get_resources,
 	.set	 = pnpacpi_set_resources,
@@ -147,6 +154,7 @@ static struct pnp_protocol pnpacpi_proto
 	.resume = pnpacpi_resume,
 #endif
 };
+EXPORT_SYMBOL(pnpacpi_protocol);
 
 static int __init pnpacpi_add_device(struct acpi_device *device)
 {
@@ -168,7 +176,7 @@ static int __init pnpacpi_add_device(str
 	if (!dev)
 		return -ENOMEM;
 
-	dev->data = device->handle;
+	dev->data = device;
 	/* .enabled means the device can decode the resources */
 	dev->active = device->status.enabled;
 	status = acpi_get_handle(device->handle, "_SRS", &temp);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/pnpacpi/rsparser.c linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/rsparser.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/pnpacpi/rsparser.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/pnpacpi/rsparser.c	2010-02-24 13:52:17.000000000 -0500
@@ -465,7 +465,8 @@ static acpi_status pnpacpi_allocated_res
 
 int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
 {
-	acpi_handle handle = dev->data;
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	acpi_status status;
 
 	pnp_dbg(&dev->dev, "parse allocated resources\n");
@@ -773,7 +774,8 @@ static __init acpi_status pnpacpi_option
 
 int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
 {
-	acpi_handle handle = dev->data;
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	acpi_status status;
 	struct acpipnp_parse_option_s parse_data;
 
@@ -845,7 +847,8 @@ static acpi_status pnpacpi_type_resource
 int pnpacpi_build_resource_template(struct pnp_dev *dev,
 				    struct acpi_buffer *buffer)
 {
-	acpi_handle handle = dev->data;
+	struct acpi_device *acpi_dev = dev->data;
+	acpi_handle handle = acpi_dev->handle;
 	struct acpi_resource *resource;
 	int res_cnt = 0;
 	acpi_status status;
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/pnpbios/proc.c linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/proc.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/pnpbios/proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/pnp.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 
 #include <asm/uaccess.h>
@@ -33,42 +34,65 @@
 static struct proc_dir_entry *proc_pnp = NULL;
 static struct proc_dir_entry *proc_pnp_boot = NULL;
 
-static int proc_read_pnpconfig(char *buf, char **start, off_t pos,
-			       int count, int *eof, void *data)
+static int pnpconfig_proc_show(struct seq_file *m, void *v)
 {
 	struct pnp_isa_config_struc pnps;
 
 	if (pnp_bios_isapnp_config(&pnps))
 		return -EIO;
-	return snprintf(buf, count,
-			"structure_revision %d\n"
-			"number_of_CSNs %d\n"
-			"ISA_read_data_port 0x%x\n",
-			pnps.revision, pnps.no_csns, pnps.isa_rd_data_port);
+	seq_printf(m, "structure_revision %d\n"
+		      "number_of_CSNs %d\n"
+		      "ISA_read_data_port 0x%x\n",
+		   pnps.revision, pnps.no_csns, pnps.isa_rd_data_port);
+	return 0;
 }
 
-static int proc_read_escdinfo(char *buf, char **start, off_t pos,
-			      int count, int *eof, void *data)
+static int pnpconfig_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pnpconfig_proc_show, NULL);
+}
+
+static const struct file_operations pnpconfig_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pnpconfig_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int escd_info_proc_show(struct seq_file *m, void *v)
 {
 	struct escd_info_struc escd;
 
 	if (pnp_bios_escd_info(&escd))
 		return -EIO;
-	return snprintf(buf, count,
-			"min_ESCD_write_size %d\n"
+	seq_printf(m, "min_ESCD_write_size %d\n"
 			"ESCD_size %d\n"
 			"NVRAM_base 0x%x\n",
 			escd.min_escd_write_size,
 			escd.escd_size, escd.nv_storage_base);
+	return 0;
+}
+
+static int escd_info_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, escd_info_proc_show, NULL);
 }
 
+static const struct file_operations escd_info_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= escd_info_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 #define MAX_SANE_ESCD_SIZE (32*1024)
-static int proc_read_escd(char *buf, char **start, off_t pos,
-			  int count, int *eof, void *data)
+static int escd_proc_show(struct seq_file *m, void *v)
 {
 	struct escd_info_struc escd;
 	char *tmpbuf;
-	int escd_size, escd_left_to_read, n;
+	int escd_size;
 
 	if (pnp_bios_escd_info(&escd))
 		return -EIO;
@@ -76,7 +100,7 @@ static int proc_read_escd(char *buf, cha
 	/* sanity check */
 	if (escd.escd_size > MAX_SANE_ESCD_SIZE) {
 		printk(KERN_ERR
-		       "PnPBIOS: proc_read_escd: ESCD size reported by BIOS escd_info call is too great\n");
+		       "PnPBIOS: %s: ESCD size reported by BIOS escd_info call is too great\n", __func__);
 		return -EFBIG;
 	}
 
@@ -94,56 +118,75 @@ static int proc_read_escd(char *buf, cha
 
 	/* sanity check */
 	if (escd_size > MAX_SANE_ESCD_SIZE) {
-		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by"
-				" BIOS read_escd call is too great\n");
+		printk(KERN_ERR "PnPBIOS: %s: ESCD size reported by"
+				" BIOS read_escd call is too great\n", __func__);
 		kfree(tmpbuf);
 		return -EFBIG;
 	}
 
-	escd_left_to_read = escd_size - pos;
-	if (escd_left_to_read < 0)
-		escd_left_to_read = 0;
-	if (escd_left_to_read == 0)
-		*eof = 1;
-	n = min(count, escd_left_to_read);
-	memcpy(buf, tmpbuf + pos, n);
+	seq_write(m, tmpbuf, escd_size);
 	kfree(tmpbuf);
-	*start = buf;
-	return n;
+	return 0;
 }
 
-static int proc_read_legacyres(char *buf, char **start, off_t pos,
-			       int count, int *eof, void *data)
+static int escd_proc_open(struct inode *inode, struct file *file)
 {
-	/* Assume that the following won't overflow the buffer */
-	if (pnp_bios_get_stat_res(buf))
+	return single_open(file, escd_proc_show, NULL);
+}
+
+static const struct file_operations escd_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= escd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pnp_legacyres_proc_show(struct seq_file *m, void *v)
+{
+	void *buf;
+
+	buf = kmalloc(65536, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	if (pnp_bios_get_stat_res(buf)) {
+		kfree(buf);
 		return -EIO;
+	}
 
-	return count;		// FIXME: Return actual length
+	seq_write(m, buf, 65536);
+	kfree(buf);
+	return 0;
 }
 
-static int proc_read_devices(char *buf, char **start, off_t pos,
-			     int count, int *eof, void *data)
+static int pnp_legacyres_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pnp_legacyres_proc_show, NULL);
+}
+
+static const struct file_operations pnp_legacyres_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pnp_legacyres_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pnp_devices_proc_show(struct seq_file *m, void *v)
 {
 	struct pnp_bios_node *node;
 	u8 nodenum;
-	char *p = buf;
-
-	if (pos >= 0xff)
-		return 0;
 
 	node = kzalloc(node_info.max_node_size, GFP_KERNEL);
 	if (!node)
 		return -ENOMEM;
 
-	for (nodenum = pos; nodenum < 0xff;) {
+	for (nodenum = 0; nodenum < 0xff;) {
 		u8 thisnodenum = nodenum;
-		/* 26 = the number of characters per line sprintf'ed */
-		if ((p - buf + 26) > count)
-			break;
+
 		if (pnp_bios_get_dev_node(&nodenum, PNPMODE_DYNAMIC, node))
 			break;
-		p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
+		seq_printf(m, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
 			     node->handle, node->eisa_id,
 			     node->type_code[0], node->type_code[1],
 			     node->type_code[2], node->flags);
@@ -153,20 +196,29 @@ static int proc_read_devices(char *buf,
 			       "PnPBIOS: proc_read_devices:",
 			       (unsigned int)nodenum,
 			       (unsigned int)thisnodenum);
-			*eof = 1;
 			break;
 		}
 	}
 	kfree(node);
-	if (nodenum == 0xff)
-		*eof = 1;
-	*start = (char *)((off_t) nodenum - pos);
-	return p - buf;
+	return 0;
 }
 
-static int proc_read_node(char *buf, char **start, off_t pos,
-			  int count, int *eof, void *data)
+static int pnp_devices_proc_open(struct inode *inode, struct file *file)
 {
+	return single_open(file, pnp_devices_proc_show, NULL);
+}
+
+static const struct file_operations pnp_devices_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pnp_devices_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pnpbios_proc_show(struct seq_file *m, void *v)
+{
+	void *data = m->private;
 	struct pnp_bios_node *node;
 	int boot = (long)data >> 8;
 	u8 nodenum = (long)data;
@@ -180,14 +232,20 @@ static int proc_read_node(char *buf, cha
 		return -EIO;
 	}
 	len = node->size - sizeof(struct pnp_bios_node);
-	memcpy(buf, node->data, len);
+	seq_write(m, node->data, len);
 	kfree(node);
-	return len;
+	return 0;
 }
 
-static int proc_write_node(struct file *file, const char __user * buf,
-			   unsigned long count, void *data)
+static int pnpbios_proc_open(struct inode *inode, struct file *file)
 {
+	return single_open(file, pnpbios_proc_show, PDE(inode)->data);
+}
+
+static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf,
+				  size_t count, loff_t *pos)
+{
+	void *data = PDE(file->f_path.dentry->d_inode)->data;
 	struct pnp_bios_node *node;
 	int boot = (long)data >> 8;
 	u8 nodenum = (long)data;
@@ -218,34 +276,33 @@ out:
 	return ret;
 }
 
+static const struct file_operations pnpbios_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pnpbios_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= pnpbios_proc_write,
+};
+
 int pnpbios_interface_attach_device(struct pnp_bios_node *node)
 {
 	char name[3];
-	struct proc_dir_entry *ent;
 
 	sprintf(name, "%02x", node->handle);
 
 	if (!proc_pnp)
 		return -EIO;
 	if (!pnpbios_dont_use_current_config) {
-		ent = create_proc_entry(name, 0, proc_pnp);
-		if (ent) {
-			ent->read_proc = proc_read_node;
-			ent->write_proc = proc_write_node;
-			ent->data = (void *)(long)(node->handle);
-		}
+		proc_create_data(name, 0644, proc_pnp, &pnpbios_proc_fops,
+				 (void *)(long)(node->handle));
 	}
 
 	if (!proc_pnp_boot)
 		return -EIO;
-	ent = create_proc_entry(name, 0, proc_pnp_boot);
-	if (ent) {
-		ent->read_proc = proc_read_node;
-		ent->write_proc = proc_write_node;
-		ent->data = (void *)(long)(node->handle + 0x100);
+	if (proc_create_data(name, 0644, proc_pnp_boot, &pnpbios_proc_fops,
+			     (void *)(long)(node->handle + 0x100)))
 		return 0;
-	}
-
 	return -EIO;
 }
 
@@ -262,14 +319,11 @@ int __init pnpbios_proc_init(void)
 	proc_pnp_boot = proc_mkdir("boot", proc_pnp);
 	if (!proc_pnp_boot)
 		return -EIO;
-	create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
-	create_proc_read_entry("configuration_info", 0, proc_pnp,
-			       proc_read_pnpconfig, NULL);
-	create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo,
-			       NULL);
-	create_proc_read_entry("escd", S_IRUSR, proc_pnp, proc_read_escd, NULL);
-	create_proc_read_entry("legacy_device_resources", 0, proc_pnp,
-			       proc_read_legacyres, NULL);
+	proc_create("devices", 0, proc_pnp, &pnp_devices_proc_fops);
+	proc_create("configuration_info", 0, proc_pnp, &pnpconfig_proc_fops);
+	proc_create("escd_info", 0, proc_pnp, &escd_info_proc_fops);
+	proc_create("escd", S_IRUSR, proc_pnp, &escd_proc_fops);
+	proc_create("legacy_device_resources", 0, proc_pnp, &pnp_legacyres_proc_fops);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/pnpbios/rsparser.c linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/rsparser.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/pnpbios/rsparser.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/pnpbios/rsparser.c	2010-02-24 13:52:17.000000000 -0500
@@ -191,7 +191,7 @@ static unsigned char *pnpbios_parse_allo
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -405,7 +405,7 @@ pnpbios_parse_resource_option_data(unsig
 		case SMALL_TAG_END:
 			return p + 2;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -475,7 +475,7 @@ static unsigned char *pnpbios_parse_comp
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
@@ -744,7 +744,7 @@ static unsigned char *pnpbios_encode_all
 			return (unsigned char *)p;
 			break;
 
-		default:	/* an unkown tag */
+		default:	/* an unknown tag */
 len_err:
 			dev_err(&dev->dev, "unknown tag %#x length %d\n",
 				tag, len);
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/quirks.c linux-libre-2.6.33-gnu1/drivers/pnp/quirks.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/quirks.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/quirks.c	2010-02-24 13:52:17.000000000 -0500
@@ -285,15 +285,10 @@ static void quirk_system_pci_resources(s
 				 * the PCI region, and that might prevent a PCI
 				 * driver from requesting its resources.
 				 */
-				dev_warn(&dev->dev, "%s resource "
-					"(0x%llx-0x%llx) overlaps %s BAR %d "
-					"(0x%llx-0x%llx), disabling\n",
-					pnp_resource_type_name(res),
-					(unsigned long long) pnp_start,
-					(unsigned long long) pnp_end,
-					pci_name(pdev), i,
-					(unsigned long long) pci_start,
-					(unsigned long long) pci_end);
+				dev_warn(&dev->dev,
+					 "disabling %pR because it overlaps "
+					 "%s BAR %d %pR\n", res,
+					 pci_name(pdev), i, &pdev->resource[i]);
 				res->flags |= IORESOURCE_DISABLED;
 			}
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/resource.c linux-libre-2.6.33-gnu1/drivers/pnp/resource.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/resource.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/resource.c	2010-02-24 13:52:17.000000000 -0500
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resourc
 	res->start = irq;
 	res->end = irq;
 
-	pnp_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resourc
 	res->start = dma;
 	res->end = dma;
 
-	pnp_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -562,8 +562,7 @@ struct pnp_resource *pnp_add_io_resource
 	res->start = start;
 	res->end = end;
 
-	pnp_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
-		(unsigned long long) start, (unsigned long long) end, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
@@ -587,8 +586,7 @@ struct pnp_resource *pnp_add_mem_resourc
 	res->start = start;
 	res->end = end;
 
-	pnp_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
-		(unsigned long long) start, (unsigned long long) end, flags);
+	pnp_dbg(&dev->dev, "  add %pr\n", res);
 	return pnp_res;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/support.c linux-libre-2.6.33-gnu1/drivers/pnp/support.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/support.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/support.c	2010-02-24 13:52:17.000000000 -0500
@@ -75,47 +75,14 @@ char *pnp_resource_type_name(struct reso
 
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 {
-	char buf[128];
-	int len;
 	struct pnp_resource *pnp_res;
-	struct resource *res;
 
-	if (list_empty(&dev->resources)) {
+	if (list_empty(&dev->resources))
 		pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
-		return;
-	}
-
-	pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
-	list_for_each_entry(pnp_res, &dev->resources, list) {
-		res = &pnp_res->res;
-		len = 0;
-
-		len += scnprintf(buf + len, sizeof(buf) - len, "  %-3s ",
-				 pnp_resource_type_name(res));
-
-		if (res->flags & IORESOURCE_DISABLED) {
-			pnp_dbg(&dev->dev, "%sdisabled\n", buf);
-			continue;
-		}
-
-		switch (pnp_resource_type(res)) {
-		case IORESOURCE_IO:
-		case IORESOURCE_MEM:
-			len += scnprintf(buf + len, sizeof(buf) - len,
-					 "%#llx-%#llx flags %#lx",
-					 (unsigned long long) res->start,
-					 (unsigned long long) res->end,
-					 res->flags);
-			break;
-		case IORESOURCE_IRQ:
-		case IORESOURCE_DMA:
-			len += scnprintf(buf + len, sizeof(buf) - len,
-					 "%lld flags %#lx",
-					 (unsigned long long) res->start,
-					 res->flags);
-			break;
-		}
-		pnp_dbg(&dev->dev, "%s\n", buf);
+	else {
+		pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
+		list_for_each_entry(pnp_res, &dev->resources, list)
+			pnp_dbg(&dev->dev, "%pr\n", &pnp_res->res);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/pnp/system.c linux-libre-2.6.33-gnu1/drivers/pnp/system.c
--- linux-libre-2.6.32-gnu1/drivers/pnp/system.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/pnp/system.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,11 +22,11 @@ static const struct pnp_device_id pnp_de
 	{"", 0}
 };
 
-static void reserve_range(struct pnp_dev *dev, resource_size_t start,
-			  resource_size_t end, int port)
+static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
 {
 	char *regionid;
 	const char *pnpid = dev_name(&dev->dev);
+	resource_size_t start = r->start, end = r->end;
 	struct resource *res;
 
 	regionid = kmalloc(16, GFP_KERNEL);
@@ -48,10 +48,8 @@ static void reserve_range(struct pnp_dev
 	 * example do reserve stuff they know about too, so we may well
 	 * have double reservations.
 	 */
-	dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n",
-		port ? "ioport" : "iomem",
-		(unsigned long long) start, (unsigned long long) end,
-		res ? "has been" : "could not be");
+	dev_info(&dev->dev, "%pR %s reserved\n", r,
+		 res ? "has been" : "could not be");
 }
 
 static void reserve_resources_of_dev(struct pnp_dev *dev)
@@ -77,14 +75,14 @@ static void reserve_resources_of_dev(str
 		if (res->end < res->start)
 			continue;	/* invalid */
 
-		reserve_range(dev, res->start, res->end, 1);
+		reserve_range(dev, res, 1);
 	}
 
 	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
 		if (res->flags & IORESOURCE_DISABLED)
 			continue;
 
-		reserve_range(dev, res->start, res->end, 0);
+		reserve_range(dev, res, 0);
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/collie_battery.c linux-libre-2.6.33-gnu1/drivers/power/collie_battery.c
--- linux-libre-2.6.32-gnu1/drivers/power/collie_battery.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/collie_battery.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,418 @@
+/*
+ * Battery and Power Management code for the Sharp SL-5x00
+ *
+ * Copyright (C) 2009 Thomas Kunze
+ *
+ * based on tosa_battery.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/module.h>
+#include <linux/power_supply.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/mfd/ucb1x00.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/mach-types.h>
+#include <mach/collie.h>
+
+static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
+static struct work_struct bat_work;
+static struct ucb1x00 *ucb;
+
+struct collie_bat {
+	int status;
+	struct power_supply psy;
+	int full_chrg;
+
+	struct mutex work_lock; /* protects data */
+
+	bool (*is_present)(struct collie_bat *bat);
+	int gpio_full;
+	int gpio_charge_on;
+
+	int technology;
+
+	int gpio_bat;
+	int adc_bat;
+	int adc_bat_divider;
+	int bat_max;
+	int bat_min;
+
+	int gpio_temp;
+	int adc_temp;
+	int adc_temp_divider;
+};
+
+static struct collie_bat collie_bat_main;
+
+static unsigned long collie_read_bat(struct collie_bat *bat)
+{
+	unsigned long value = 0;
+
+	if (bat->gpio_bat < 0 || bat->adc_bat < 0)
+		return 0;
+	mutex_lock(&bat_lock);
+	gpio_set_value(bat->gpio_bat, 1);
+	msleep(5);
+	ucb1x00_adc_enable(ucb);
+	value = ucb1x00_adc_read(ucb, bat->adc_bat, UCB_SYNC);
+	ucb1x00_adc_disable(ucb);
+	gpio_set_value(bat->gpio_bat, 0);
+	mutex_unlock(&bat_lock);
+	value = value * 1000000 / bat->adc_bat_divider;
+
+	return value;
+}
+
+static unsigned long collie_read_temp(struct collie_bat *bat)
+{
+	unsigned long value = 0;
+	if (bat->gpio_temp < 0 || bat->adc_temp < 0)
+		return 0;
+
+	mutex_lock(&bat_lock);
+	gpio_set_value(bat->gpio_temp, 1);
+	msleep(5);
+	ucb1x00_adc_enable(ucb);
+	value = ucb1x00_adc_read(ucb, bat->adc_temp, UCB_SYNC);
+	ucb1x00_adc_disable(ucb);
+	gpio_set_value(bat->gpio_temp, 0);
+	mutex_unlock(&bat_lock);
+
+	value = value * 10000 / bat->adc_temp_divider;
+
+	return value;
+}
+
+static int collie_bat_get_property(struct power_supply *psy,
+			    enum power_supply_property psp,
+			    union power_supply_propval *val)
+{
+	int ret = 0;
+	struct collie_bat *bat = container_of(psy, struct collie_bat, psy);
+
+	if (bat->is_present && !bat->is_present(bat)
+			&& psp != POWER_SUPPLY_PROP_PRESENT) {
+		return -ENODEV;
+	}
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = bat->status;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = bat->technology;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = collie_read_bat(bat);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+		if (bat->full_chrg == -1)
+			val->intval = bat->bat_max;
+		else
+			val->intval = bat->full_chrg;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		val->intval = bat->bat_max;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = bat->bat_min;
+		break;
+	case POWER_SUPPLY_PROP_TEMP:
+		val->intval = collie_read_temp(bat);
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = bat->is_present ? bat->is_present(bat) : 1;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static void collie_bat_external_power_changed(struct power_supply *psy)
+{
+	schedule_work(&bat_work);
+}
+
+static irqreturn_t collie_bat_gpio_isr(int irq, void *data)
+{
+	pr_info("collie_bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
+	schedule_work(&bat_work);
+	return IRQ_HANDLED;
+}
+
+static void collie_bat_update(struct collie_bat *bat)
+{
+	int old;
+	struct power_supply *psy = &bat->psy;
+
+	mutex_lock(&bat->work_lock);
+
+	old = bat->status;
+
+	if (bat->is_present && !bat->is_present(bat)) {
+		printk(KERN_NOTICE "%s not present\n", psy->name);
+		bat->status = POWER_SUPPLY_STATUS_UNKNOWN;
+		bat->full_chrg = -1;
+	} else if (power_supply_am_i_supplied(psy)) {
+		if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) {
+			gpio_set_value(bat->gpio_charge_on, 1);
+			mdelay(15);
+		}
+
+		if (gpio_get_value(bat->gpio_full)) {
+			if (old == POWER_SUPPLY_STATUS_CHARGING ||
+					bat->full_chrg == -1)
+				bat->full_chrg = collie_read_bat(bat);
+
+			gpio_set_value(bat->gpio_charge_on, 0);
+			bat->status = POWER_SUPPLY_STATUS_FULL;
+		} else {
+			gpio_set_value(bat->gpio_charge_on, 1);
+			bat->status = POWER_SUPPLY_STATUS_CHARGING;
+		}
+	} else {
+		gpio_set_value(bat->gpio_charge_on, 0);
+		bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
+	}
+
+	if (old != bat->status)
+		power_supply_changed(psy);
+
+	mutex_unlock(&bat->work_lock);
+}
+
+static void collie_bat_work(struct work_struct *work)
+{
+	collie_bat_update(&collie_bat_main);
+}
+
+
+static enum power_supply_property collie_bat_main_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TEMP,
+};
+
+static enum power_supply_property collie_bat_bu_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX,
+	POWER_SUPPLY_PROP_PRESENT,
+};
+
+static struct collie_bat collie_bat_main = {
+	.status = POWER_SUPPLY_STATUS_DISCHARGING,
+	.full_chrg = -1,
+	.psy = {
+		.name		= "main-battery",
+		.type		= POWER_SUPPLY_TYPE_BATTERY,
+		.properties	= collie_bat_main_props,
+		.num_properties	= ARRAY_SIZE(collie_bat_main_props),
+		.get_property	= collie_bat_get_property,
+		.external_power_changed = collie_bat_external_power_changed,
+		.use_for_apm	= 1,
+	},
+
+	.gpio_full = COLLIE_GPIO_CO,
+	.gpio_charge_on = COLLIE_GPIO_CHARGE_ON,
+
+	.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+
+	.gpio_bat = COLLIE_GPIO_MBAT_ON,
+	.adc_bat = UCB_ADC_INP_AD1,
+	.adc_bat_divider = 155,
+	.bat_max = 4310000,
+	.bat_min = 1551 * 1000000 / 414,
+
+	.gpio_temp = COLLIE_GPIO_TMP_ON,
+	.adc_temp = UCB_ADC_INP_AD0,
+	.adc_temp_divider = 10000,
+};
+
+static struct collie_bat collie_bat_bu = {
+	.status = POWER_SUPPLY_STATUS_UNKNOWN,
+	.full_chrg = -1,
+
+	.psy = {
+		.name		= "backup-battery",
+		.type		= POWER_SUPPLY_TYPE_BATTERY,
+		.properties	= collie_bat_bu_props,
+		.num_properties	= ARRAY_SIZE(collie_bat_bu_props),
+		.get_property	= collie_bat_get_property,
+		.external_power_changed = collie_bat_external_power_changed,
+	},
+
+	.gpio_full = -1,
+	.gpio_charge_on = -1,
+
+	.technology = POWER_SUPPLY_TECHNOLOGY_LiMn,
+
+	.gpio_bat = COLLIE_GPIO_BBAT_ON,
+	.adc_bat = UCB_ADC_INP_AD1,
+	.adc_bat_divider = 155,
+	.bat_max = 3000000,
+	.bat_min = 1900000,
+
+	.gpio_temp = -1,
+	.adc_temp = -1,
+	.adc_temp_divider = -1,
+};
+
+static struct {
+	int gpio;
+	char *name;
+	bool output;
+	int value;
+} gpios[] = {
+	{ COLLIE_GPIO_CO,		"main battery full",	0, 0 },
+	{ COLLIE_GPIO_MAIN_BAT_LOW,	"main battery low",	0, 0 },
+	{ COLLIE_GPIO_CHARGE_ON,	"main charge on",	1, 0 },
+	{ COLLIE_GPIO_MBAT_ON,		"main battery",		1, 0 },
+	{ COLLIE_GPIO_TMP_ON,		"main battery temp",	1, 0 },
+	{ COLLIE_GPIO_BBAT_ON,		"backup battery",	1, 0 },
+};
+
+#ifdef CONFIG_PM
+static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state)
+{
+	/* flush all pending status updates */
+	flush_scheduled_work();
+	return 0;
+}
+
+static int collie_bat_resume(struct ucb1x00_dev *dev)
+{
+	/* things may have changed while we were away */
+	schedule_work(&bat_work);
+	return 0;
+}
+#else
+#define collie_bat_suspend NULL
+#define collie_bat_resume NULL
+#endif
+
+static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
+{
+	int ret;
+	int i;
+
+	if (!machine_is_collie())
+		return -ENODEV;
+
+	ucb = dev->ucb;
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+		ret = gpio_request(gpios[i].gpio, gpios[i].name);
+		if (ret) {
+			i--;
+			goto err_gpio;
+		}
+
+		if (gpios[i].output)
+			ret = gpio_direction_output(gpios[i].gpio,
+					gpios[i].value);
+		else
+			ret = gpio_direction_input(gpios[i].gpio);
+
+		if (ret)
+			goto err_gpio;
+	}
+
+	mutex_init(&collie_bat_main.work_lock);
+
+	INIT_WORK(&bat_work, collie_bat_work);
+
+	ret = power_supply_register(&dev->ucb->dev, &collie_bat_main.psy);
+	if (ret)
+		goto err_psy_reg_main;
+	ret = power_supply_register(&dev->ucb->dev, &collie_bat_bu.psy);
+	if (ret)
+		goto err_psy_reg_bu;
+
+	ret = request_irq(gpio_to_irq(COLLIE_GPIO_CO),
+				collie_bat_gpio_isr,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"main full", &collie_bat_main);
+	if (!ret) {
+		schedule_work(&bat_work);
+		return 0;
+	}
+	power_supply_unregister(&collie_bat_bu.psy);
+err_psy_reg_bu:
+	power_supply_unregister(&collie_bat_main.psy);
+err_psy_reg_main:
+
+	/* see comment in collie_bat_remove */
+	flush_scheduled_work();
+
+	i--;
+err_gpio:
+	for (; i >= 0; i--)
+		gpio_free(gpios[i].gpio);
+
+	return ret;
+}
+
+static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
+{
+	int i;
+
+	free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main);
+
+	power_supply_unregister(&collie_bat_bu.psy);
+	power_supply_unregister(&collie_bat_main.psy);
+
+	/*
+	 * now flush all pending work.
+	 * we won't get any more schedules, since all
+	 * sources (isr and external_power_changed)
+	 * are unregistered now.
+	 */
+	flush_scheduled_work();
+
+	for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
+		gpio_free(gpios[i].gpio);
+}
+
+static struct ucb1x00_driver collie_bat_driver = {
+	.add		= collie_bat_probe,
+	.remove		= __devexit_p(collie_bat_remove),
+	.suspend	= collie_bat_suspend,
+	.resume		= collie_bat_resume,
+};
+
+static int __init collie_bat_init(void)
+{
+	return ucb1x00_register_driver(&collie_bat_driver);
+}
+
+static void __exit collie_bat_exit(void)
+{
+	ucb1x00_unregister_driver(&collie_bat_driver);
+}
+
+module_init(collie_bat_init);
+module_exit(collie_bat_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Thomas Kunze");
+MODULE_DESCRIPTION("Collie battery driver");
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/Kconfig linux-libre-2.6.33-gnu1/drivers/power/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/power/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -29,6 +29,13 @@ config APM_POWER
 	  Say Y here to enable support APM status emulation using
 	  battery class devices.
 
+config WM831X_BACKUP
+	tristate "WM831X backup battery charger support"
+	depends on MFD_WM831X
+	help
+	  Say Y here to enable support for the backup battery charger
+	  in the Wolfson Microelectronics WM831x PMICs.
+
 config WM831X_POWER
 	tristate "WM831X PMU support"
 	depends on MFD_WM831X
@@ -77,6 +84,13 @@ config BATTERY_TOSA
 	  Say Y to enable support for the battery on the Sharp Zaurus
 	  SL-6000 (tosa) models.
 
+config BATTERY_COLLIE
+	tristate "Sharp SL-5500 (collie) battery"
+	depends on SA1100_COLLIE && MCP_UCB1200
+	help
+	  Say Y to enable support for the battery on the Sharp Zaurus
+	  SL-5500 (collie) models.
+
 config BATTERY_WM97XX
 	bool "WM97xx generic battery driver"
 	depends on TOUCHSCREEN_WM97XX=y
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/Makefile linux-libre-2.6.33-gnu1/drivers/power/Makefile
--- linux-libre-2.6.32-gnu1/drivers/power/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY)	+= power_supp
 
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
+obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
 obj-$(CONFIG_WM831X_POWER)	+= wm831x_power.o
 obj-$(CONFIG_WM8350_POWER)	+= wm8350_power.o
 
@@ -24,6 +25,7 @@ obj-$(CONFIG_BATTERY_DS2782)	+= ds2782_b
 obj-$(CONFIG_BATTERY_PMU)	+= pmu_battery.o
 obj-$(CONFIG_BATTERY_OLPC)	+= olpc_battery.o
 obj-$(CONFIG_BATTERY_TOSA)	+= tosa_battery.o
+obj-$(CONFIG_BATTERY_COLLIE)	+= collie_battery.o
 obj-$(CONFIG_BATTERY_WM97XX)	+= wm97xx_battery.o
 obj-$(CONFIG_BATTERY_BQ27x00)	+= bq27x00_battery.o
 obj-$(CONFIG_BATTERY_DA9030)	+= da9030_battery.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/pcf50633-charger.c linux-libre-2.6.33-gnu1/drivers/power/pcf50633-charger.c
--- linux-libre-2.6.32-gnu1/drivers/power/pcf50633-charger.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/pcf50633-charger.c	2010-02-24 13:52:17.000000000 -0500
@@ -29,15 +29,12 @@
 struct pcf50633_mbc {
 	struct pcf50633 *pcf;
 
-	int adapter_active;
 	int adapter_online;
-	int usb_active;
 	int usb_online;
 
 	struct power_supply usb;
 	struct power_supply adapter;
-
-	struct delayed_work charging_restart_work;
+	struct power_supply ac;
 };
 
 int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
@@ -47,16 +44,21 @@ int pcf50633_mbc_usb_curlim_set(struct p
 	u8 bits;
 	int charging_start = 1;
 	u8 mbcs2, chgmod;
+	unsigned int mbcc5;
 
-	if (ma >= 1000)
+	if (ma >= 1000) {
 		bits = PCF50633_MBCC7_USB_1000mA;
-	else if (ma >= 500)
+		ma = 1000;
+	} else if (ma >= 500) {
 		bits = PCF50633_MBCC7_USB_500mA;
-	else if (ma >= 100)
+		ma = 500;
+	} else if (ma >= 100) {
 		bits = PCF50633_MBCC7_USB_100mA;
-	else {
+		ma = 100;
+	} else {
 		bits = PCF50633_MBCC7_USB_SUSPEND;
 		charging_start = 0;
+		ma = 0;
 	}
 
 	ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
@@ -66,21 +68,40 @@ int pcf50633_mbc_usb_curlim_set(struct p
 	else
 		dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
 
-	/* Manual charging start */
-	mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
+	/*
+	 * We limit the charging current to be the USB current limit.
+	 * The reason is that on pcf50633, when it enters PMU Standby mode,
+	 * which it does when the device goes "off", the USB current limit
+	 * reverts to the variant default.  In at least one common case, that
+	 * default is 500mA.  By setting the charging current to be the same
+	 * as the USB limit we set here before PMU standby, we enforce it only
+	 * using the correct amount of current even when the USB current limit
+	 * gets reset to the wrong thing
+	 */
+
+	if (mbc->pcf->pdata->charger_reference_current_ma) {
+		mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
+		if (mbcc5 > 255)
+			mbcc5 = 255;
+		pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
+	}
+
+	mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
 	chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
 
 	/* If chgmod == BATFULL, setting chgena has no effect.
-	 * We need to set resume instead.
+	 * Datasheet says we need to set resume instead but when autoresume is
+	 * used resume doesn't work. Clear and set chgena instead.
 	 */
 	if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
 		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
 				PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
-	else
+	else {
+		pcf50633_reg_clear_bits(pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_CHGENA);
 		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
-				PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
-
-	mbc->usb_active = charging_start;
+				PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
+	}
 
 	power_supply_changed(&mbc->usb);
 
@@ -92,20 +113,44 @@ int pcf50633_mbc_get_status(struct pcf50
 {
 	struct pcf50633_mbc *mbc  = platform_get_drvdata(pcf->mbc_pdev);
 	int status = 0;
+	u8 chgmod;
+
+	if (!mbc)
+		return 0;
+
+	chgmod = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2)
+		& PCF50633_MBCS2_MBC_MASK;
 
 	if (mbc->usb_online)
 		status |= PCF50633_MBC_USB_ONLINE;
-	if (mbc->usb_active)
+	if (chgmod == PCF50633_MBCS2_MBC_USB_PRE ||
+	    chgmod == PCF50633_MBCS2_MBC_USB_PRE_WAIT ||
+	    chgmod == PCF50633_MBCS2_MBC_USB_FAST ||
+	    chgmod == PCF50633_MBCS2_MBC_USB_FAST_WAIT)
 		status |= PCF50633_MBC_USB_ACTIVE;
 	if (mbc->adapter_online)
 		status |= PCF50633_MBC_ADAPTER_ONLINE;
-	if (mbc->adapter_active)
+	if (chgmod == PCF50633_MBCS2_MBC_ADP_PRE ||
+	    chgmod == PCF50633_MBCS2_MBC_ADP_PRE_WAIT ||
+	    chgmod == PCF50633_MBCS2_MBC_ADP_FAST ||
+	    chgmod == PCF50633_MBCS2_MBC_ADP_FAST_WAIT)
 		status |= PCF50633_MBC_ADAPTER_ACTIVE;
 
 	return status;
 }
 EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
 
+int pcf50633_mbc_get_usb_online_status(struct pcf50633 *pcf)
+{
+	struct pcf50633_mbc *mbc  = platform_get_drvdata(pcf->mbc_pdev);
+
+	if (!mbc)
+		return 0;
+
+	return mbc->usb_online;
+}
+EXPORT_SYMBOL_GPL(pcf50633_mbc_get_usb_online_status);
+
 static ssize_t
 show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -156,9 +201,55 @@ static ssize_t set_usblim(struct device
 
 static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim);
 
+static ssize_t
+show_chglim(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
+	u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5);
+	unsigned int ma;
+
+	if (!mbc->pcf->pdata->charger_reference_current_ma)
+		return -ENODEV;
+
+	ma = (mbc->pcf->pdata->charger_reference_current_ma *  mbcc5) >> 8;
+
+	return sprintf(buf, "%u\n", ma);
+}
+
+static ssize_t set_chglim(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
+	unsigned long ma;
+	unsigned int mbcc5;
+	int ret;
+
+	if (!mbc->pcf->pdata->charger_reference_current_ma)
+		return -ENODEV;
+
+	ret = strict_strtoul(buf, 10, &ma);
+	if (ret)
+		return -EINVAL;
+
+	mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
+	if (mbcc5 > 255)
+		mbcc5 = 255;
+	pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
+
+	return count;
+}
+
+/*
+ * This attribute allows to change MBC charging limit on the fly
+ * independently of usb current limit. It also gets set automatically every
+ * time usb current limit is changed.
+ */
+static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim);
+
 static struct attribute *pcf50633_mbc_sysfs_entries[] = {
 	&dev_attr_chgmode.attr,
 	&dev_attr_usb_curlim.attr,
+	&dev_attr_chg_curlim.attr,
 	NULL,
 };
 
@@ -167,76 +258,26 @@ static struct attribute_group mbc_attr_g
 	.attrs	= pcf50633_mbc_sysfs_entries,
 };
 
-/* MBC state machine switches into charging mode when the battery voltage
- * falls below 96% of a battery float voltage. But the voltage drop in Li-ion
- * batteries is marginal(1~2 %) till about 80% of its capacity - which means,
- * after a BATFULL, charging won't be restarted until 80%.
- *
- * This work_struct function restarts charging at regular intervals to make
- * sure we don't discharge too much
- */
-
-static void pcf50633_mbc_charging_restart(struct work_struct *work)
-{
-	struct pcf50633_mbc *mbc;
-	u8 mbcs2, chgmod;
-
-	mbc = container_of(work, struct pcf50633_mbc,
-				charging_restart_work.work);
-
-	mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
-	chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
-
-	if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
-		return;
-
-	/* Restart charging */
-	pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1,
-				PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
-	mbc->usb_active = 1;
-	power_supply_changed(&mbc->usb);
-
-	dev_info(mbc->pcf->dev, "Charging restarted\n");
-}
-
 static void
 pcf50633_mbc_irq_handler(int irq, void *data)
 {
 	struct pcf50633_mbc *mbc = data;
-	int chg_restart_interval =
-			mbc->pcf->pdata->charging_restart_interval;
 
 	/* USB */
 	if (irq == PCF50633_IRQ_USBINS) {
 		mbc->usb_online = 1;
 	} else if (irq == PCF50633_IRQ_USBREM) {
 		mbc->usb_online = 0;
-		mbc->usb_active = 0;
 		pcf50633_mbc_usb_curlim_set(mbc->pcf, 0);
-		cancel_delayed_work_sync(&mbc->charging_restart_work);
 	}
 
 	/* Adapter */
-	if (irq == PCF50633_IRQ_ADPINS) {
+	if (irq == PCF50633_IRQ_ADPINS)
 		mbc->adapter_online = 1;
-		mbc->adapter_active = 1;
-	} else if (irq == PCF50633_IRQ_ADPREM) {
+	else if (irq == PCF50633_IRQ_ADPREM)
 		mbc->adapter_online = 0;
-		mbc->adapter_active = 0;
-	}
-
-	if (irq == PCF50633_IRQ_BATFULL) {
-		mbc->usb_active = 0;
-		mbc->adapter_active = 0;
-
-		if (chg_restart_interval > 0)
-			schedule_delayed_work(&mbc->charging_restart_work,
-							chg_restart_interval);
-	} else if (irq == PCF50633_IRQ_USBLIMON)
-		mbc->usb_active = 0;
-	else if (irq == PCF50633_IRQ_USBLIMOFF)
-		mbc->usb_active = 1;
 
+	power_supply_changed(&mbc->ac);
 	power_supply_changed(&mbc->usb);
 	power_supply_changed(&mbc->adapter);
 
@@ -269,10 +310,34 @@ static int usb_get_property(struct power
 {
 	struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
 	int ret = 0;
+	u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
+						PCF50633_MBCC7_USB_MASK;
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_ONLINE:
-		val->intval = mbc->usb_online;
+		val->intval = mbc->usb_online &&
+				(usblim <= PCF50633_MBCC7_USB_500mA);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int ac_get_property(struct power_supply *psy,
+			enum power_supply_property psp,
+			union power_supply_propval *val)
+{
+	struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac);
+	int ret = 0;
+	u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
+						PCF50633_MBCC7_USB_MASK;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = mbc->usb_online &&
+				(usblim == PCF50633_MBCC7_USB_1000mA);
 		break;
 	default:
 		ret = -EINVAL;
@@ -303,7 +368,6 @@ static const u8 mbc_irq_handlers[] = {
 static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
 {
 	struct pcf50633_mbc *mbc;
-	struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
 	int ret;
 	int i;
 	u8 mbcs1;
@@ -313,7 +377,7 @@ static int __devinit pcf50633_mbc_probe(
 		return -ENOMEM;
 
 	platform_set_drvdata(pdev, mbc);
-	mbc->pcf = pdata->pcf;
+	mbc->pcf = dev_to_pcf50633(pdev->dev.parent);
 
 	/* Set up IRQ handlers */
 	for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
@@ -337,6 +401,14 @@ static int __devinit pcf50633_mbc_probe(
 	mbc->usb.supplied_to		= mbc->pcf->pdata->batteries;
 	mbc->usb.num_supplicants	= mbc->pcf->pdata->num_batteries;
 
+	mbc->ac.name			= "ac";
+	mbc->ac.type			= POWER_SUPPLY_TYPE_MAINS;
+	mbc->ac.properties		= power_props;
+	mbc->ac.num_properties		= ARRAY_SIZE(power_props);
+	mbc->ac.get_property		= ac_get_property;
+	mbc->ac.supplied_to		= mbc->pcf->pdata->batteries;
+	mbc->ac.num_supplicants		= mbc->pcf->pdata->num_batteries;
+
 	ret = power_supply_register(&pdev->dev, &mbc->adapter);
 	if (ret) {
 		dev_err(mbc->pcf->dev, "failed to register adapter\n");
@@ -352,8 +424,14 @@ static int __devinit pcf50633_mbc_probe(
 		return ret;
 	}
 
-	INIT_DELAYED_WORK(&mbc->charging_restart_work,
-				pcf50633_mbc_charging_restart);
+	ret = power_supply_register(&pdev->dev, &mbc->ac);
+	if (ret) {
+		dev_err(mbc->pcf->dev, "failed to register ac\n");
+		power_supply_unregister(&mbc->adapter);
+		power_supply_unregister(&mbc->usb);
+		kfree(mbc);
+		return ret;
+	}
 
 	ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
 	if (ret)
@@ -379,8 +457,7 @@ static int __devexit pcf50633_mbc_remove
 
 	power_supply_unregister(&mbc->usb);
 	power_supply_unregister(&mbc->adapter);
-
-	cancel_delayed_work_sync(&mbc->charging_restart_work);
+	power_supply_unregister(&mbc->ac);
 
 	kfree(mbc);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/pmu_battery.c linux-libre-2.6.33-gnu1/drivers/power/pmu_battery.c
--- linux-libre-2.6.32-gnu1/drivers/power/pmu_battery.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/pmu_battery.c	2010-02-24 13:52:17.000000000 -0500
@@ -89,6 +89,8 @@ static int pmu_bat_get_property(struct p
 	case POWER_SUPPLY_PROP_STATUS:
 		if (pbi->flags & PMU_BATT_CHARGING)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else if (pmu_power_flags & PMU_PWR_AC_PRESENT)
+			val->intval = POWER_SUPPLY_STATUS_FULL;
 		else
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 		break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/power_supply_sysfs.c linux-libre-2.6.33-gnu1/drivers/power/power_supply_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/power/power_supply_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/power_supply_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,10 @@ static ssize_t power_supply_show_propert
 	ret = psy->get_property(psy, off, &value);
 
 	if (ret < 0) {
-		if (ret != -ENODEV)
+		if (ret == -ENODATA)
+			dev_dbg(dev, "driver has no data for `%s' property\n",
+				attr->attr.name);
+		else if (ret != -ENODEV)
 			dev_err(dev, "driver failed to report `%s' property\n",
 				attr->attr.name);
 		return ret;
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/wm831x_backup.c linux-libre-2.6.33-gnu1/drivers/power/wm831x_backup.c
--- linux-libre-2.6.32-gnu1/drivers/power/wm831x_backup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/wm831x_backup.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,233 @@
+/*
+ * Backup battery driver for Wolfson Microelectronics wm831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * This 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/err.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/pmu.h>
+#include <linux/mfd/wm831x/pdata.h>
+
+struct wm831x_backup {
+	struct wm831x *wm831x;
+	struct power_supply backup;
+};
+
+static int wm831x_backup_read_voltage(struct wm831x *wm831x,
+				     enum wm831x_auxadc src,
+				     union power_supply_propval *val)
+{
+	int ret;
+
+	ret = wm831x_auxadc_read_uv(wm831x, src);
+	if (ret >= 0)
+		val->intval = ret;
+
+	return ret;
+}
+
+/*********************************************************************
+ *		Backup supply properties
+ *********************************************************************/
+
+static void wm831x_config_backup(struct wm831x *wm831x)
+{
+	struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
+	struct wm831x_backup_pdata *pdata;
+	int ret, reg;
+
+	if (!wm831x_pdata || !wm831x_pdata->backup) {
+		dev_warn(wm831x->dev,
+			 "No backup battery charger configuration\n");
+		return;
+	}
+
+	pdata = wm831x_pdata->backup;
+
+	reg = 0;
+
+	if (pdata->charger_enable)
+		reg |= WM831X_BKUP_CHG_ENA | WM831X_BKUP_BATT_DET_ENA;
+	if (pdata->no_constant_voltage)
+		reg |= WM831X_BKUP_CHG_MODE;
+
+	switch (pdata->vlim) {
+	case 2500:
+		break;
+	case 3100:
+		reg |= WM831X_BKUP_CHG_VLIM;
+		break;
+	default:
+		dev_err(wm831x->dev, "Invalid backup voltage limit %dmV\n",
+			pdata->vlim);
+	}
+
+	switch (pdata->ilim) {
+	case 100:
+		break;
+	case 200:
+		reg |= 1;
+		break;
+	case 300:
+		reg |= 2;
+		break;
+	case 400:
+		reg |= 3;
+		break;
+	default:
+		dev_err(wm831x->dev, "Invalid backup current limit %duA\n",
+			pdata->ilim);
+	}
+
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret != 0) {
+		dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret);
+		return;
+	}
+
+	ret = wm831x_set_bits(wm831x, WM831X_BACKUP_CHARGER_CONTROL,
+			      WM831X_BKUP_CHG_ENA_MASK |
+			      WM831X_BKUP_CHG_MODE_MASK |
+			      WM831X_BKUP_BATT_DET_ENA_MASK |
+			      WM831X_BKUP_CHG_VLIM_MASK |
+			      WM831X_BKUP_CHG_ILIM_MASK,
+			      reg);
+	if (ret != 0)
+		dev_err(wm831x->dev,
+			"Failed to set backup charger config: %d\n", ret);
+
+	wm831x_reg_lock(wm831x);
+}
+
+static int wm831x_backup_get_prop(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  union power_supply_propval *val)
+{
+	struct wm831x_backup *devdata = dev_get_drvdata(psy->dev->parent);
+	struct wm831x *wm831x = devdata->wm831x;
+	int ret = 0;
+
+	ret = wm831x_reg_read(wm831x, WM831X_BACKUP_CHARGER_CONTROL);
+	if (ret < 0)
+		return ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		if (ret & WM831X_BKUP_CHG_STS)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		break;
+
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = wm831x_backup_read_voltage(wm831x, WM831X_AUX_BKUP_BATT,
+						val);
+		break;
+
+	case POWER_SUPPLY_PROP_PRESENT:
+		if (ret & WM831X_BKUP_CHG_STS)
+			val->intval = 1;
+		else
+			val->intval = 0;
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static enum power_supply_property wm831x_backup_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_PRESENT,
+};
+
+/*********************************************************************
+ *		Initialisation
+ *********************************************************************/
+
+static __devinit int wm831x_backup_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_backup *devdata;
+	struct power_supply *backup;
+	int ret;
+
+	devdata = kzalloc(sizeof(struct wm831x_backup), GFP_KERNEL);
+	if (devdata == NULL)
+		return -ENOMEM;
+
+	devdata->wm831x = wm831x;
+	platform_set_drvdata(pdev, devdata);
+
+	backup = &devdata->backup;
+
+	/* We ignore configuration failures since we can still read
+	 * back the status without enabling the charger (which may
+	 * already be enabled anyway).
+	 */
+	wm831x_config_backup(wm831x);
+
+	backup->name = "wm831x-backup";
+	backup->type = POWER_SUPPLY_TYPE_BATTERY;
+	backup->properties = wm831x_backup_props;
+	backup->num_properties = ARRAY_SIZE(wm831x_backup_props);
+	backup->get_property = wm831x_backup_get_prop;
+	ret = power_supply_register(&pdev->dev, backup);
+	if (ret)
+		goto err_kmalloc;
+
+	return ret;
+
+err_kmalloc:
+	kfree(devdata);
+	return ret;
+}
+
+static __devexit int wm831x_backup_remove(struct platform_device *pdev)
+{
+	struct wm831x_backup *devdata = platform_get_drvdata(pdev);
+
+	power_supply_unregister(&devdata->backup);
+	kfree(devdata);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_backup_driver = {
+	.probe = wm831x_backup_probe,
+	.remove = __devexit_p(wm831x_backup_remove),
+	.driver = {
+		.name = "wm831x-backup",
+	},
+};
+
+static int __init wm831x_backup_init(void)
+{
+	return platform_driver_register(&wm831x_backup_driver);
+}
+module_init(wm831x_backup_init);
+
+static void __exit wm831x_backup_exit(void)
+{
+	platform_driver_unregister(&wm831x_backup_driver);
+}
+module_exit(wm831x_backup_exit);
+
+MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-backup");
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/wm831x_power.c linux-libre-2.6.33-gnu1/drivers/power/wm831x_power.c
--- linux-libre-2.6.32-gnu1/drivers/power/wm831x_power.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/wm831x_power.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@
 struct wm831x_power {
 	struct wm831x *wm831x;
 	struct power_supply wall;
-	struct power_supply backup;
 	struct power_supply usb;
 	struct power_supply battery;
 };
@@ -454,125 +453,6 @@ static irqreturn_t wm831x_bat_irq(int ir
 
 
 /*********************************************************************
- *		Backup supply properties
- *********************************************************************/
-
-static void wm831x_config_backup(struct wm831x *wm831x)
-{
-	struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
-	struct wm831x_backup_pdata *pdata;
-	int ret, reg;
-
-	if (!wm831x_pdata || !wm831x_pdata->backup) {
-		dev_warn(wm831x->dev,
-			 "No backup battery charger configuration\n");
-		return;
-	}
-
-	pdata = wm831x_pdata->backup;
-
-	reg = 0;
-
-	if (pdata->charger_enable)
-		reg |= WM831X_BKUP_CHG_ENA | WM831X_BKUP_BATT_DET_ENA;
-	if (pdata->no_constant_voltage)
-		reg |= WM831X_BKUP_CHG_MODE;
-
-	switch (pdata->vlim) {
-	case 2500:
-		break;
-	case 3100:
-		reg |= WM831X_BKUP_CHG_VLIM;
-		break;
-	default:
-		dev_err(wm831x->dev, "Invalid backup voltage limit %dmV\n",
-			pdata->vlim);
-	}
-
-	switch (pdata->ilim) {
-	case 100:
-		break;
-	case 200:
-		reg |= 1;
-		break;
-	case 300:
-		reg |= 2;
-		break;
-	case 400:
-		reg |= 3;
-		break;
-	default:
-		dev_err(wm831x->dev, "Invalid backup current limit %duA\n",
-			pdata->ilim);
-	}
-
-	ret = wm831x_reg_unlock(wm831x);
-	if (ret != 0) {
-		dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret);
-		return;
-	}
-
-	ret = wm831x_set_bits(wm831x, WM831X_BACKUP_CHARGER_CONTROL,
-			      WM831X_BKUP_CHG_ENA_MASK |
-			      WM831X_BKUP_CHG_MODE_MASK |
-			      WM831X_BKUP_BATT_DET_ENA_MASK |
-			      WM831X_BKUP_CHG_VLIM_MASK |
-			      WM831X_BKUP_CHG_ILIM_MASK,
-			      reg);
-	if (ret != 0)
-		dev_err(wm831x->dev,
-			"Failed to set backup charger config: %d\n", ret);
-
-	wm831x_reg_lock(wm831x);
-}
-
-static int wm831x_backup_get_prop(struct power_supply *psy,
-				  enum power_supply_property psp,
-				  union power_supply_propval *val)
-{
-	struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent);
-	struct wm831x *wm831x = wm831x_power->wm831x;
-	int ret = 0;
-
-	ret = wm831x_reg_read(wm831x, WM831X_BACKUP_CHARGER_CONTROL);
-	if (ret < 0)
-		return ret;
-
-	switch (psp) {
-	case POWER_SUPPLY_PROP_STATUS:
-		if (ret & WM831X_BKUP_CHG_STS)
-			val->intval = POWER_SUPPLY_STATUS_CHARGING;
-		else
-			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
-		break;
-
-	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BKUP_BATT,
-						val);
-		break;
-
-	case POWER_SUPPLY_PROP_PRESENT:
-		if (ret & WM831X_BKUP_CHG_STS)
-			val->intval = 1;
-		else
-			val->intval = 0;
-		break;
-
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static enum power_supply_property wm831x_backup_props[] = {
-	POWER_SUPPLY_PROP_STATUS,
-	POWER_SUPPLY_PROP_VOLTAGE_NOW,
-	POWER_SUPPLY_PROP_PRESENT,
-};
-
-/*********************************************************************
  *		Initialisation
  *********************************************************************/
 
@@ -595,10 +475,7 @@ static irqreturn_t wm831x_pwr_src_irq(in
 
 	dev_dbg(wm831x->dev, "Power source changed\n");
 
-	/* Just notify for everything - little harm in overnotifying.
-	 * The backup battery is not a power source while the system
-	 * is running so skip that.
-	 */
+	/* Just notify for everything - little harm in overnotifying. */
 	power_supply_changed(&wm831x_power->battery);
 	power_supply_changed(&wm831x_power->usb);
 	power_supply_changed(&wm831x_power->wall);
@@ -613,7 +490,6 @@ static __devinit int wm831x_power_probe(
 	struct power_supply *usb;
 	struct power_supply *battery;
 	struct power_supply *wall;
-	struct power_supply *backup;
 	int ret, irq, i;
 
 	power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL);
@@ -626,13 +502,11 @@ static __devinit int wm831x_power_probe(
 	usb = &power->usb;
 	battery = &power->battery;
 	wall = &power->wall;
-	backup = &power->backup;
 
 	/* We ignore configuration failures since we can still read back
-	 * the status without enabling either of the chargers.
+	 * the status without enabling the charger.
 	 */
 	wm831x_config_battery(wm831x);
-	wm831x_config_backup(wm831x);
 
 	wall->name = "wm831x-wall";
 	wall->type = POWER_SUPPLY_TYPE_MAINS;
@@ -661,15 +535,6 @@ static __devinit int wm831x_power_probe(
 	if (ret)
 		goto err_battery;
 
-	backup->name = "wm831x-backup";
-	backup->type = POWER_SUPPLY_TYPE_BATTERY;
-	backup->properties = wm831x_backup_props;
-	backup->num_properties = ARRAY_SIZE(wm831x_backup_props);
-	backup->get_property = wm831x_backup_get_prop;
-	ret = power_supply_register(&pdev->dev, backup);
-	if (ret)
-		goto err_usb;
-
 	irq = platform_get_irq_byname(pdev, "SYSLO");
 	ret = wm831x_request_irq(wm831x, irq, wm831x_syslo_irq,
 				 IRQF_TRIGGER_RISING, "SYSLO",
@@ -677,7 +542,7 @@ static __devinit int wm831x_power_probe(
 	if (ret != 0) {
 		dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
 			irq, ret);
-		goto err_backup;
+		goto err_usb;
 	}
 
 	irq = platform_get_irq_byname(pdev, "PWR SRC");
@@ -716,8 +581,6 @@ err_bat_irq:
 err_syslo:
 	irq = platform_get_irq_byname(pdev, "SYSLO");
 	wm831x_free_irq(wm831x, irq, power);
-err_backup:
-	power_supply_unregister(backup);
 err_usb:
 	power_supply_unregister(usb);
 err_battery:
@@ -746,7 +609,6 @@ static __devexit int wm831x_power_remove
 	irq = platform_get_irq_byname(pdev, "SYSLO");
 	wm831x_free_irq(wm831x, irq, wm831x_power);
 
-	power_supply_unregister(&wm831x_power->backup);
 	power_supply_unregister(&wm831x_power->battery);
 	power_supply_unregister(&wm831x_power->wall);
 	power_supply_unregister(&wm831x_power->usb);
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/wm8350_power.c linux-libre-2.6.33-gnu1/drivers/power/wm8350_power.c
--- linux-libre-2.6.32-gnu1/drivers/power/wm8350_power.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/wm8350_power.c	2010-02-24 13:52:17.000000000 -0500
@@ -184,8 +184,9 @@ static ssize_t charger_state_show(struct
 
 static DEVICE_ATTR(charger_state, 0444, charger_state_show, NULL);
 
-static void wm8350_charger_handler(struct wm8350 *wm8350, int irq, void *data)
+static irqreturn_t wm8350_charger_handler(int irq, void *data)
 {
+	struct wm8350 *wm8350 = data;
 	struct wm8350_power *power = &wm8350->power;
 	struct wm8350_charger_policy *policy = power->policy;
 
@@ -238,6 +239,8 @@ static void wm8350_charger_handler(struc
 	default:
 		dev_err(wm8350->dev, "Unknown interrupt %d\n", irq);
 	}
+
+	return IRQ_HANDLED;
 }
 
 /*********************************************************************
@@ -387,73 +390,55 @@ static void wm8350_init_charger(struct w
 {
 	/* register our interest in charger events */
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
+			    wm8350_charger_handler, 0, "Battery hot", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
+			    wm8350_charger_handler, 0, "Battery cold", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
+			    wm8350_charger_handler, 0, "Battery fail", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_TO);
+			    wm8350_charger_handler, 0,
+			    "Charger timeout", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_END);
+			    wm8350_charger_handler, 0,
+			    "Charge end", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_START);
+			    wm8350_charger_handler, 0,
+			    "Charge start", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY);
+			    wm8350_charger_handler, 0,
+			    "Fast charge ready", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
+			    wm8350_charger_handler, 0,
+			    "Battery <3.9V", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
+			    wm8350_charger_handler, 0,
+			    "Battery <3.1V", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
+			    wm8350_charger_handler, 0,
+			    "Battery <2.85V", wm8350);
 
 	/* and supply change events */
 	wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
+			    wm8350_charger_handler, 0, "USB", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
+			    wm8350_charger_handler, 0, "Wall", wm8350);
 	wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB,
-			    wm8350_charger_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
+			    wm8350_charger_handler, 0, "Battery", wm8350);
 }
 
 static void free_charger_irq(struct wm8350 *wm8350)
 {
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_TO);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_END);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_START);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
 	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
 	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
 	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
 	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/power/wm97xx_battery.c linux-libre-2.6.33-gnu1/drivers/power/wm97xx_battery.c
--- linux-libre-2.6.32-gnu1/drivers/power/wm97xx_battery.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/power/wm97xx_battery.c	2010-02-24 13:52:17.000000000 -0500
@@ -157,7 +157,7 @@ static int wm97xx_bat_resume(struct devi
 	return 0;
 }
 
-static struct dev_pm_ops wm97xx_bat_pm_ops = {
+static const struct dev_pm_ops wm97xx_bat_pm_ops = {
 	.suspend	= wm97xx_bat_suspend,
 	.resume		= wm97xx_bat_resume,
 };
@@ -175,8 +175,14 @@ static int __devinit wm97xx_bat_probe(st
 		dev_err(&dev->dev, "Do not pass platform_data through "
 			"wm97xx_bat_set_pdata!\n");
 		return -EINVAL;
-	} else
-		pdata = wmdata->batt_pdata;
+	}
+
+	if (!wmdata) {
+		dev_err(&dev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
+	pdata = wmdata->batt_pdata;
 
 	if (dev->id != -1)
 		return -EINVAL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/ps3/ps3-sys-manager.c linux-libre-2.6.33-gnu1/drivers/ps3/ps3-sys-manager.c
--- linux-libre-2.6.32-gnu1/drivers/ps3/ps3-sys-manager.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/ps3/ps3-sys-manager.c	2010-02-24 13:52:17.000000000 -0500
@@ -46,7 +46,7 @@
 /**
  * struct ps3_sys_manager_header - System manager message header.
  * @version: Header version, currently 1.
- * @size: Header size in bytes, curently 16.
+ * @size: Header size in bytes, currently 16.
  * @payload_size: Message payload size in bytes.
  * @service_id: Message type, one of enum ps3_sys_manager_service_id.
  * @request_tag: Unique number to identify reply.
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/88pm8607.c linux-libre-2.6.33-gnu1/drivers/regulator/88pm8607.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/88pm8607.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/88pm8607.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,685 @@
+/*
+ * Regulators driver for Marvell 88PM8607
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * 	Haojian Zhuang <haojian.zhuang@marvell.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/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/88pm8607.h>
+
+struct pm8607_regulator_info {
+	struct regulator_desc	desc;
+	struct pm8607_chip	*chip;
+	struct regulator_dev	*regulator;
+
+	int	min_uV;
+	int	max_uV;
+	int	step_uV;
+	int	vol_reg;
+	int	vol_shift;
+	int	vol_nbits;
+	int	update_reg;
+	int	update_bit;
+	int	enable_reg;
+	int	enable_bit;
+	int	slope_double;
+};
+
+static inline int check_range(struct pm8607_regulator_info *info,
+				int min_uV, int max_uV)
+{
+	if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	uint8_t chip_id = info->chip->chip_id;
+	int ret = -EINVAL;
+
+	switch (info->desc.id) {
+	case PM8607_ID_BUCK1:
+		ret = (index < 0x1d) ? (index * 25000 + 800000) :
+			((index < 0x20) ? 1500000 :
+			((index < 0x40) ? ((index - 0x20) * 25000) :
+			-EINVAL));
+		break;
+	case PM8607_ID_BUCK3:
+		ret = (index < 0x3d) ? (index * 25000) :
+			((index < 0x40) ? 1500000 : -EINVAL);
+		if (ret < 0)
+			break;
+		if (info->slope_double)
+			ret <<= 1;
+		break;
+	case PM8607_ID_LDO1:
+		ret = (index == 0) ? 1800000 :
+			((index == 1) ? 1200000 :
+			((index == 2) ? 2800000 : -EINVAL));
+		break;
+	case PM8607_ID_LDO5:
+		ret = (index == 0) ? 2900000 :
+			((index == 1) ? 3000000 :
+			((index == 2) ? 3100000 : 3300000));
+		break;
+	case PM8607_ID_LDO7:
+	case PM8607_ID_LDO8:
+		ret = (index < 3) ? (index * 50000 + 1800000) :
+			((index < 8) ? (index * 50000 + 2550000) :
+			 -EINVAL);
+		break;
+	case PM8607_ID_LDO12:
+		ret = (index < 2) ? (index * 100000 + 1800000) :
+			((index < 7) ? (index * 100000 + 2500000) :
+			((index == 7) ? 3300000 : 1200000));
+		break;
+	case PM8607_ID_LDO2:
+	case PM8607_ID_LDO3:
+	case PM8607_ID_LDO9:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 8) ? (index * 50000 + 2550000) :
+				 -EINVAL);
+			break;
+		case PM8607_CHIP_B0:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 7) ? (index * 50000 + 2550000) :
+				3300000);
+			break;
+		}
+		break;
+	case PM8607_ID_LDO4:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 8) ? (index * 50000 + 2550000) :
+				 -EINVAL);
+			break;
+		case PM8607_CHIP_B0:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 6) ? (index * 50000 + 2550000) :
+				((index == 6) ? 2900000 : 3300000));
+			break;
+		}
+		break;
+	case PM8607_ID_LDO6:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 8) ? (index * 50000 + 2450000) :
+				-EINVAL);
+			break;
+		case PM8607_CHIP_B0:
+			ret = (index < 2) ? (index * 50000 + 1800000) :
+				((index < 7) ? (index * 50000 + 2500000) :
+				3300000);
+			break;
+		}
+		break;
+	case PM8607_ID_LDO10:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 8) ? (index * 50000 + 2550000) :
+				1200000);
+			break;
+		case PM8607_CHIP_B0:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 7) ? (index * 50000 + 2550000) :
+				((index == 7) ? 3300000 : 1200000));
+			break;
+		}
+		break;
+	case PM8607_ID_LDO14:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			ret = (index < 3) ? (index * 50000 + 1800000) :
+				((index < 8) ? (index * 50000 + 2550000) :
+				 -EINVAL);
+			break;
+		case PM8607_CHIP_B0:
+			ret = (index < 2) ? (index * 50000 + 1800000) :
+				((index < 7) ? (index * 50000 + 2600000) :
+				3300000);
+			break;
+		}
+		break;
+	}
+	return ret;
+}
+
+static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	uint8_t chip_id = info->chip->chip_id;
+	int val = -ENOENT;
+	int ret;
+
+	switch (info->desc.id) {
+	case PM8607_ID_BUCK1:
+		if (min_uV >= 800000) 		/* 800mV ~ 1500mV / 25mV */
+			val = (min_uV - 775001) / 25000;
+		else {				/* 25mV ~ 775mV / 25mV */
+			val = (min_uV + 249999) / 25000;
+			val += 32;
+		}
+		break;
+	case PM8607_ID_BUCK3:
+		if (info->slope_double)
+			min_uV = min_uV >> 1;
+		val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */
+
+		break;
+	case PM8607_ID_LDO1:
+		if (min_uV > 1800000)
+			val = 2;
+		else if (min_uV > 1200000)
+			val = 0;
+		else
+			val = 1;
+		break;
+	case PM8607_ID_LDO5:
+		if (min_uV > 3100000)
+			val = 3;
+		else				/* 2900mV ~ 3100mV / 100mV */
+			val = (min_uV - 2800001) / 100000;
+		break;
+	case PM8607_ID_LDO7:
+	case PM8607_ID_LDO8:
+		if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+			if (min_uV <= 1800000)
+				val = 0;	/* 1800mv */
+			else if (min_uV <= 1900000)
+				val = (min_uV - 1750001) / 50000;
+			else
+				val = 3;	/* 2700mV */
+		} else {		 /* 2700mV ~ 2900mV / 50mV */
+			if (min_uV <= 2900000) {
+				val = (min_uV - 2650001) / 50000;
+				val += 3;
+			} else
+				val = -EINVAL;
+		}
+		break;
+	case PM8607_ID_LDO10:
+		if (min_uV > 2850000)
+			val = 7;
+		else if (min_uV <= 1200000)
+			val = 8;
+		else if (min_uV < 2700000)	/* 1800mV ~ 1900mV / 50mV */
+			val = (min_uV - 1750001) / 50000;
+		else {				/* 2700mV ~ 2850mV / 50mV */
+			val = (min_uV - 2650001) / 50000;
+			val += 3;
+		}
+		break;
+	case PM8607_ID_LDO12:
+		if (min_uV < 2700000) {		/* 1800mV ~ 1900mV / 100mV */
+			if (min_uV <= 1200000)
+				val = 8;	/* 1200mV */
+			else if (min_uV <= 1800000)
+				val = 0;	/* 1800mV */
+			else if (min_uV <= 1900000)
+				val = (min_uV - 1700001) / 100000;
+			else
+				val = 2;	/* 2700mV */
+		} else {			/* 2700mV ~ 3100mV / 100mV */
+			if (min_uV <= 3100000) {
+				val = (min_uV - 2600001) / 100000;
+				val += 2;
+			} else if (min_uV <= 3300000)
+				val = 7;
+			else
+				val = -EINVAL;
+		}
+		break;
+	case PM8607_ID_LDO2:
+	case PM8607_ID_LDO3:
+	case PM8607_ID_LDO9:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			if (min_uV < 2700000)	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2700mV */
+			else {			/* 2700mV ~ 2900mV / 50mV */
+				if (min_uV <= 2900000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 3;
+				} else
+					val = -EINVAL;
+			}
+			break;
+		case PM8607_CHIP_B0:
+			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2700mV */
+			} else {		 /* 2700mV ~ 2850mV / 50mV */
+				if (min_uV <= 2850000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 3;
+				} else if (min_uV <= 3300000)
+					val = 7;
+				else
+					val = -EINVAL;
+			}
+			break;
+		}
+		break;
+	case PM8607_ID_LDO4:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			if (min_uV < 2700000)	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2700mV */
+			else {			/* 2700mV ~ 2900mV / 50mV */
+				if (min_uV <= 2900000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 3;
+				} else
+					val = -EINVAL;
+			}
+			break;
+		case PM8607_CHIP_B0:
+			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2700mV */
+			} else {		 /* 2700mV ~ 2800mV / 50mV */
+				if (min_uV <= 2850000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 3;
+				} else if (min_uV <= 2900000)
+					val = 6;
+				else if (min_uV <= 3300000)
+					val = 7;
+				else
+					val = -EINVAL;
+			}
+			break;
+		}
+		break;
+	case PM8607_ID_LDO6:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			if (min_uV < 2600000) {	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2600mV */
+			} else {		/* 2600mV ~ 2800mV / 50mV */
+				if (min_uV <= 2800000) {
+					val = (min_uV - 2550001) / 50000;
+					val += 3;
+				} else
+					val = -EINVAL;
+			}
+			break;
+		case PM8607_CHIP_B0:
+			if (min_uV < 2600000) {	/* 1800mV ~ 1850mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1850000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 2;	/* 2600mV */
+			} else {		/* 2600mV ~ 2800mV / 50mV */
+				if (min_uV <= 2800000) {
+					val = (min_uV - 2550001) / 50000;
+					val += 2;
+				} else if (min_uV <= 3300000)
+					val = 7;
+				else
+					val = -EINVAL;
+			}
+			break;
+		}
+		break;
+	case PM8607_ID_LDO14:
+		switch (chip_id) {
+		case PM8607_CHIP_A0:
+		case PM8607_CHIP_A1:
+			if (min_uV < 2700000) {	/* 1800mV ~ 1900mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1900000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 3;	/* 2700mV */
+			} else {		 /* 2700mV ~ 2900mV / 50mV */
+				if (min_uV <= 2900000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 3;
+				} else
+					val = -EINVAL;
+			}
+			break;
+		case PM8607_CHIP_B0:
+			if (min_uV < 2700000) {	/* 1800mV ~ 1850mV / 50mV */
+				if (min_uV <= 1800000)
+					val = 0;
+				else if (min_uV <= 1850000)
+					val = (min_uV - 1750001) / 50000;
+				else
+					val = 2;	/* 2700mV */
+			} else {		 /* 2700mV ~ 2900mV / 50mV */
+				if (min_uV <= 2900000) {
+					val = (min_uV - 2650001) / 50000;
+					val += 2;
+				} else if (min_uV <= 3300000)
+					val = 7;
+				else
+					val = -EINVAL;
+			}
+			break;
+		}
+		break;
+	}
+	if (val >= 0) {
+		ret = pm8607_list_voltage(rdev, val);
+		if (ret > max_uV) {
+			pr_err("exceed voltage range (%d %d) uV",
+				min_uV, max_uV);
+			return -EINVAL;
+		}
+	} else
+		pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV);
+	return val;
+}
+
+static int pm8607_set_voltage(struct regulator_dev *rdev,
+			      int min_uV, int max_uV)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	struct pm8607_chip *chip = info->chip;
+	uint8_t val, mask;
+	int ret;
+
+	if (check_range(info, min_uV, max_uV)) {
+		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+		return -EINVAL;
+	}
+
+	ret = choose_voltage(rdev, min_uV, max_uV);
+	if (ret < 0)
+		return -EINVAL;
+	val = (uint8_t)(ret << info->vol_shift);
+	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+
+	ret = pm8607_set_bits(chip, info->vol_reg, mask, val);
+	if (ret)
+		return ret;
+	switch (info->desc.id) {
+	case PM8607_ID_BUCK1:
+	case PM8607_ID_BUCK3:
+		ret = pm8607_set_bits(chip, info->update_reg,
+				      1 << info->update_bit,
+				      1 << info->update_bit);
+		break;
+	}
+	return ret;
+}
+
+static int pm8607_get_voltage(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	struct pm8607_chip *chip = info->chip;
+	uint8_t val, mask;
+	int ret;
+
+	ret = pm8607_reg_read(chip, info->vol_reg);
+	if (ret < 0)
+		return ret;
+
+	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+	val = ((unsigned char)ret & mask) >> info->vol_shift;
+
+	return pm8607_list_voltage(rdev, val);
+}
+
+static int pm8607_enable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	struct pm8607_chip *chip = info->chip;
+
+	return pm8607_set_bits(chip, info->enable_reg,
+			       1 << info->enable_bit,
+			       1 << info->enable_bit);
+}
+
+static int pm8607_disable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	struct pm8607_chip *chip = info->chip;
+
+	return pm8607_set_bits(chip, info->enable_reg,
+			       1 << info->enable_bit, 0);
+}
+
+static int pm8607_is_enabled(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	struct pm8607_chip *chip = info->chip;
+	int ret;
+
+	ret = pm8607_reg_read(chip, info->enable_reg);
+	if (ret < 0)
+		return ret;
+
+	return !!((unsigned char)ret & (1 << info->enable_bit));
+}
+
+static struct regulator_ops pm8607_regulator_ops = {
+	.set_voltage	= pm8607_set_voltage,
+	.get_voltage	= pm8607_get_voltage,
+	.enable		= pm8607_enable,
+	.disable	= pm8607_disable,
+	.is_enabled	= pm8607_is_enabled,
+};
+
+#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
+{									\
+	.desc	= {							\
+		.name	= "BUCK" #_id,					\
+		.ops	= &pm8607_regulator_ops,			\
+		.type	= REGULATOR_VOLTAGE,				\
+		.id	= PM8607_ID_BUCK##_id,				\
+		.owner	= THIS_MODULE,					\
+	},								\
+	.min_uV		= (min) * 1000,					\
+	.max_uV		= (max) * 1000,					\
+	.step_uV	= (step) * 1000,				\
+	.vol_reg	= PM8607_##vreg,				\
+	.vol_shift	= (0),						\
+	.vol_nbits	= (nbits),					\
+	.update_reg	= PM8607_##ureg,				\
+	.update_bit	= (ubit),					\
+	.enable_reg	= PM8607_##ereg,				\
+	.enable_bit	= (ebit),					\
+	.slope_double	= (0),						\
+}
+
+#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
+{									\
+	.desc	= {							\
+		.name	= "LDO" #_id,					\
+		.ops	= &pm8607_regulator_ops,			\
+		.type	= REGULATOR_VOLTAGE,				\
+		.id	= PM8607_ID_LDO##_id,				\
+		.owner	= THIS_MODULE,					\
+	},								\
+	.min_uV		= (min) * 1000,					\
+	.max_uV		= (max) * 1000,					\
+	.step_uV	= (step) * 1000,				\
+	.vol_reg	= PM8607_##vreg,				\
+	.vol_shift	= (shift),					\
+	.vol_nbits	= (nbits),					\
+	.enable_reg	= PM8607_##ereg,				\
+	.enable_bit	= (ebit),					\
+	.slope_double	= (0),						\
+}
+
+static struct pm8607_regulator_info pm8607_regulator_info[] = {
+	PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
+	PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
+
+	PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3),
+	PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4),
+	PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5),
+	PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6),
+	PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7),
+	PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0),
+	PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1),
+	PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2),
+	PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3),
+	PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4),
+	PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5),
+	PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6),
+};
+
+static inline struct pm8607_regulator_info *find_regulator_info(int id)
+{
+	struct pm8607_regulator_info *info;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
+		info = &pm8607_regulator_info[i];
+		if (info->desc.id == id)
+			return info;
+	}
+	return NULL;
+}
+
+static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
+{
+	struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm8607_platform_data *pdata = chip->dev->platform_data;
+	struct pm8607_regulator_info *info = NULL;
+
+	info = find_regulator_info(pdev->id);
+	if (info == NULL) {
+		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+		return -EINVAL;
+	}
+
+	info->chip = chip;
+
+	info->regulator = regulator_register(&info->desc, &pdev->dev,
+					     pdata->regulator[pdev->id], info);
+	if (IS_ERR(info->regulator)) {
+		dev_err(&pdev->dev, "failed to register regulator %s\n",
+			info->desc.name);
+		return PTR_ERR(info->regulator);
+	}
+
+	/* check DVC ramp slope double */
+	if (info->desc.id == PM8607_ID_BUCK3)
+		if (info->chip->buck3_double)
+			info->slope_double = 1;
+
+	platform_set_drvdata(pdev, info);
+	return 0;
+}
+
+static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
+{
+	struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
+
+	regulator_unregister(info->regulator);
+	return 0;
+}
+
+#define PM8607_REGULATOR_DRIVER(_name)				\
+{								\
+	.driver		= {					\
+		.name	= "88pm8607-" #_name,			\
+		.owner	= THIS_MODULE,				\
+	},							\
+	.probe		= pm8607_regulator_probe,		\
+	.remove		= __devexit_p(pm8607_regulator_remove),	\
+}
+
+static struct platform_driver pm8607_regulator_driver[] = {
+	PM8607_REGULATOR_DRIVER(buck1),
+	PM8607_REGULATOR_DRIVER(buck2),
+	PM8607_REGULATOR_DRIVER(buck3),
+	PM8607_REGULATOR_DRIVER(ldo1),
+	PM8607_REGULATOR_DRIVER(ldo2),
+	PM8607_REGULATOR_DRIVER(ldo3),
+	PM8607_REGULATOR_DRIVER(ldo4),
+	PM8607_REGULATOR_DRIVER(ldo5),
+	PM8607_REGULATOR_DRIVER(ldo6),
+	PM8607_REGULATOR_DRIVER(ldo7),
+	PM8607_REGULATOR_DRIVER(ldo8),
+	PM8607_REGULATOR_DRIVER(ldo9),
+	PM8607_REGULATOR_DRIVER(ldo10),
+	PM8607_REGULATOR_DRIVER(ldo12),
+	PM8607_REGULATOR_DRIVER(ldo14),
+};
+
+static int __init pm8607_regulator_init(void)
+{
+	int i, count, ret;
+
+	count = ARRAY_SIZE(pm8607_regulator_driver);
+	for (i = 0; i < count; i++) {
+		ret = platform_driver_register(&pm8607_regulator_driver[i]);
+		if (ret != 0)
+			pr_err("Failed to register regulator driver: %d\n",
+				ret);
+	}
+	return 0;
+}
+subsys_initcall(pm8607_regulator_init);
+
+static void __exit pm8607_regulator_exit(void)
+{
+	int i, count;
+
+	count = ARRAY_SIZE(pm8607_regulator_driver);
+	for (i = 0; i < count; i++)
+		platform_driver_unregister(&pm8607_regulator_driver[i]);
+}
+module_exit(pm8607_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC");
+MODULE_ALIAS("platform:88pm8607-regulator");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/ab3100.c linux-libre-2.6.33-gnu1/drivers/regulator/ab3100.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/ab3100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/ab3100.c	2010-02-24 13:52:17.000000000 -0500
@@ -81,7 +81,7 @@ static const u8 ab3100_reg_init_order[AB
 #define LDO_C_VOLTAGE 2650000
 #define LDO_D_VOLTAGE 2650000
 
-static const int const ldo_e_buck_typ_voltages[] = {
+static const int ldo_e_buck_typ_voltages[] = {
 	1800000,
 	1400000,
 	1300000,
@@ -91,7 +91,7 @@ static const int const ldo_e_buck_typ_vo
 	900000,
 };
 
-static const int const ldo_f_typ_voltages[] = {
+static const int ldo_f_typ_voltages[] = {
 	1800000,
 	1400000,
 	1300000,
@@ -102,21 +102,21 @@ static const int const ldo_f_typ_voltage
 	2650000,
 };
 
-static const int const ldo_g_typ_voltages[] = {
+static const int ldo_g_typ_voltages[] = {
 	2850000,
 	2750000,
 	1800000,
 	1500000,
 };
 
-static const int const ldo_h_typ_voltages[] = {
+static const int ldo_h_typ_voltages[] = {
 	2750000,
 	1800000,
 	1500000,
 	1200000,
 };
 
-static const int const ldo_k_typ_voltages[] = {
+static const int ldo_k_typ_voltages[] = {
 	2750000,
 	1800000,
 };
@@ -241,24 +241,12 @@ static int ab3100_disable_regulator(stru
 	 * LDO D is a special regulator. When it is disabled, the entire
 	 * system is shut down. So this is handled specially.
 	 */
+	pr_info("Called ab3100_disable_regulator\n");
 	if (abreg->regreg == AB3100_LDO_D) {
-		int i;
-
 		dev_info(&reg->dev, "disabling LDO D - shut down system\n");
-		/*
-		 * Set regulators to default values, ignore any errors,
-		 * we're going DOWN
-		 */
-		for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
-			(void) ab3100_set_register_interruptible(abreg->ab3100,
-					ab3100_reg_init_order[i],
-					abreg->plfdata->reg_initvals[i]);
-		}
-
 		/* Setting LDO D to 0x00 cuts the power to the SoC */
 		return ab3100_set_register_interruptible(abreg->ab3100,
 							 AB3100_LDO_D, 0x00U);
-
 	}
 
 	/*
@@ -607,13 +595,6 @@ static int __init ab3100_regulators_prob
 		}
 	}
 
-	if (err) {
-		dev_err(&pdev->dev,
-			"LDO D regulator initialization failed with error %d\n",
-			err);
-		return err;
-	}
-
 	/* Register the regulators */
 	for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
 		struct ab3100_regulator *reg = &ab3100_regulators[i];
@@ -688,7 +669,7 @@ static __init int ab3100_regulators_init
 
 static __exit void ab3100_regulators_exit(void)
 {
-	platform_driver_register(&ab3100_regulators_driver);
+	platform_driver_unregister(&ab3100_regulators_driver);
 }
 
 subsys_initcall(ab3100_regulators_init);
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/core.c linux-libre-2.6.33-gnu1/drivers/regulator/core.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/core.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,6 +66,16 @@ static unsigned int _regulator_get_mode(
 static void _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data);
 
+static const char *rdev_get_name(struct regulator_dev *rdev)
+{
+	if (rdev->constraints && rdev->constraints->name)
+		return rdev->constraints->name;
+	else if (rdev->desc->name)
+		return rdev->desc->name;
+	else
+		return "";
+}
+
 /* gets the regulator for a given consumer device */
 static struct regulator *get_device_regulator(struct device *dev)
 {
@@ -96,12 +106,12 @@ static int regulator_check_voltage(struc
 
 	if (!rdev->constraints) {
 		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
-		       rdev->desc->name);
+		       rdev_get_name(rdev));
 		return -ENODEV;
 	}
 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
 		printk(KERN_ERR "%s: operation not allowed for %s\n",
-		       __func__, rdev->desc->name);
+		       __func__, rdev_get_name(rdev));
 		return -EPERM;
 	}
 
@@ -124,12 +134,12 @@ static int regulator_check_current_limit
 
 	if (!rdev->constraints) {
 		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
-		       rdev->desc->name);
+		       rdev_get_name(rdev));
 		return -ENODEV;
 	}
 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
 		printk(KERN_ERR "%s: operation not allowed for %s\n",
-		       __func__, rdev->desc->name);
+		       __func__, rdev_get_name(rdev));
 		return -EPERM;
 	}
 
@@ -159,17 +169,17 @@ static int regulator_check_mode(struct r
 
 	if (!rdev->constraints) {
 		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
-		       rdev->desc->name);
+		       rdev_get_name(rdev));
 		return -ENODEV;
 	}
 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
 		printk(KERN_ERR "%s: operation not allowed for %s\n",
-		       __func__, rdev->desc->name);
+		       __func__, rdev_get_name(rdev));
 		return -EPERM;
 	}
 	if (!(rdev->constraints->valid_modes_mask & mode)) {
 		printk(KERN_ERR "%s: invalid mode %x for %s\n",
-		       __func__, mode, rdev->desc->name);
+		       __func__, mode, rdev_get_name(rdev));
 		return -EINVAL;
 	}
 	return 0;
@@ -180,12 +190,12 @@ static int regulator_check_drms(struct r
 {
 	if (!rdev->constraints) {
 		printk(KERN_ERR "%s: no constraints for %s\n", __func__,
-		       rdev->desc->name);
+		       rdev_get_name(rdev));
 		return -ENODEV;
 	}
 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
 		printk(KERN_ERR "%s: operation not allowed for %s\n",
-		       __func__, rdev->desc->name);
+		       __func__, rdev_get_name(rdev));
 		return -EPERM;
 	}
 	return 0;
@@ -230,16 +240,8 @@ static ssize_t regulator_name_show(struc
 			     struct device_attribute *attr, char *buf)
 {
 	struct regulator_dev *rdev = dev_get_drvdata(dev);
-	const char *name;
 
-	if (rdev->constraints && rdev->constraints->name)
-		name = rdev->constraints->name;
-	else if (rdev->desc->name)
-		name = rdev->desc->name;
-	else
-		name = "";
-
-	return sprintf(buf, "%s\n", name);
+	return sprintf(buf, "%s\n", rdev_get_name(rdev));
 }
 
 static ssize_t regulator_print_opmode(char *buf, int mode)
@@ -388,7 +390,7 @@ static ssize_t regulator_total_uA_show(s
 
 	mutex_lock(&rdev->mutex);
 	list_for_each_entry(regulator, &rdev->consumer_list, list)
-	    uA += regulator->uA_load;
+		uA += regulator->uA_load;
 	mutex_unlock(&rdev->mutex);
 	return sprintf(buf, "%d\n", uA);
 }
@@ -563,7 +565,7 @@ static void drms_uA_update(struct regula
 
 	/* calc total requested load */
 	list_for_each_entry(sibling, &rdev->consumer_list, list)
-	    current_uA += sibling->uA_load;
+		current_uA += sibling->uA_load;
 
 	/* now get the optimum mode for our new total regulator load */
 	mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
@@ -579,10 +581,29 @@ static int suspend_set_state(struct regu
 	struct regulator_state *rstate)
 {
 	int ret = 0;
+	bool can_set_state;
 
-	/* enable & disable are mandatory for suspend control */
-	if (!rdev->desc->ops->set_suspend_enable ||
-		!rdev->desc->ops->set_suspend_disable) {
+	can_set_state = rdev->desc->ops->set_suspend_enable &&
+		rdev->desc->ops->set_suspend_disable;
+
+	/* If we have no suspend mode configration don't set anything;
+	 * only warn if the driver actually makes the suspend mode
+	 * configurable.
+	 */
+	if (!rstate->enabled && !rstate->disabled) {
+		if (can_set_state)
+			printk(KERN_WARNING "%s: No configuration for %s\n",
+			       __func__, rdev_get_name(rdev));
+		return 0;
+	}
+
+	if (rstate->enabled && rstate->disabled) {
+		printk(KERN_ERR "%s: invalid configuration for %s\n",
+		       __func__, rdev_get_name(rdev));
+		return -EINVAL;
+	}
+
+	if (!can_set_state) {
 		printk(KERN_ERR "%s: no way to set suspend state\n",
 			__func__);
 		return -EINVAL;
@@ -640,26 +661,44 @@ static int suspend_prepare(struct regula
 static void print_constraints(struct regulator_dev *rdev)
 {
 	struct regulation_constraints *constraints = rdev->constraints;
-	char buf[80];
-	int count;
+	char buf[80] = "";
+	int count = 0;
+	int ret;
 
-	if (rdev->desc->type == REGULATOR_VOLTAGE) {
+	if (constraints->min_uV && constraints->max_uV) {
 		if (constraints->min_uV == constraints->max_uV)
-			count = sprintf(buf, "%d mV ",
-					constraints->min_uV / 1000);
+			count += sprintf(buf + count, "%d mV ",
+					 constraints->min_uV / 1000);
 		else
-			count = sprintf(buf, "%d <--> %d mV ",
-					constraints->min_uV / 1000,
-					constraints->max_uV / 1000);
-	} else {
+			count += sprintf(buf + count, "%d <--> %d mV ",
+					 constraints->min_uV / 1000,
+					 constraints->max_uV / 1000);
+	}
+
+	if (!constraints->min_uV ||
+	    constraints->min_uV != constraints->max_uV) {
+		ret = _regulator_get_voltage(rdev);
+		if (ret > 0)
+			count += sprintf(buf + count, "at %d mV ", ret / 1000);
+	}
+
+	if (constraints->min_uA && constraints->max_uA) {
 		if (constraints->min_uA == constraints->max_uA)
-			count = sprintf(buf, "%d mA ",
-					constraints->min_uA / 1000);
+			count += sprintf(buf + count, "%d mA ",
+					 constraints->min_uA / 1000);
 		else
-			count = sprintf(buf, "%d <--> %d mA ",
-					constraints->min_uA / 1000,
-					constraints->max_uA / 1000);
+			count += sprintf(buf + count, "%d <--> %d mA ",
+					 constraints->min_uA / 1000,
+					 constraints->max_uA / 1000);
 	}
+
+	if (!constraints->min_uA ||
+	    constraints->min_uA != constraints->max_uA) {
+		ret = _regulator_get_current_limit(rdev);
+		if (ret > 0)
+			count += sprintf(buf + count, "at %d uA ", ret / 1000);
+	}
+
 	if (constraints->valid_modes_mask & REGULATOR_MODE_FAST)
 		count += sprintf(buf + count, "fast ");
 	if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL)
@@ -669,33 +708,30 @@ static void print_constraints(struct reg
 	if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
 		count += sprintf(buf + count, "standby");
 
-	printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf);
+	printk(KERN_INFO "regulator: %s: %s\n", rdev_get_name(rdev), buf);
 }
 
-/**
- * set_machine_constraints - sets regulator constraints
- * @rdev: regulator source
- * @constraints: constraints to apply
- *
- * Allows platform initialisation code to define and constrain
- * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
- * Constraints *must* be set by platform code in order for some
- * regulator operations to proceed i.e. set_voltage, set_current_limit,
- * set_mode.
- */
-static int set_machine_constraints(struct regulator_dev *rdev,
+static int machine_constraints_voltage(struct regulator_dev *rdev,
 	struct regulation_constraints *constraints)
 {
-	int ret = 0;
-	const char *name;
 	struct regulator_ops *ops = rdev->desc->ops;
+	const char *name = rdev_get_name(rdev);
+	int ret;
 
-	if (constraints->name)
-		name = constraints->name;
-	else if (rdev->desc->name)
-		name = rdev->desc->name;
-	else
-		name = "regulator";
+	/* do we need to apply the constraint voltage */
+	if (rdev->constraints->apply_uV &&
+		rdev->constraints->min_uV == rdev->constraints->max_uV &&
+		ops->set_voltage) {
+		ret = ops->set_voltage(rdev,
+			rdev->constraints->min_uV, rdev->constraints->max_uV);
+			if (ret < 0) {
+				printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n",
+				       __func__,
+				       rdev->constraints->min_uV, name);
+				rdev->constraints = NULL;
+				return ret;
+			}
+	}
 
 	/* constrain machine-level voltage specs to fit
 	 * the actual range supported by this regulator.
@@ -719,14 +755,13 @@ static int set_machine_constraints(struc
 
 		/* voltage constraints are optional */
 		if ((cmin == 0) && (cmax == 0))
-			goto out;
+			return 0;
 
 		/* else require explicit machine-level constraints */
 		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
 			pr_err("%s: %s '%s' voltage constraints\n",
 				       __func__, "invalid", name);
-			ret = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
@@ -748,8 +783,7 @@ static int set_machine_constraints(struc
 		if (max_uV < min_uV) {
 			pr_err("%s: %s '%s' voltage constraints\n",
 				       __func__, "unsupportable", name);
-			ret = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		/* use regulator's subset of machine constraints */
@@ -767,22 +801,34 @@ static int set_machine_constraints(struc
 		}
 	}
 
+	return 0;
+}
+
+/**
+ * set_machine_constraints - sets regulator constraints
+ * @rdev: regulator source
+ * @constraints: constraints to apply
+ *
+ * Allows platform initialisation code to define and constrain
+ * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
+ * Constraints *must* be set by platform code in order for some
+ * regulator operations to proceed i.e. set_voltage, set_current_limit,
+ * set_mode.
+ */
+static int set_machine_constraints(struct regulator_dev *rdev,
+	struct regulation_constraints *constraints)
+{
+	int ret = 0;
+	const char *name;
+	struct regulator_ops *ops = rdev->desc->ops;
+
 	rdev->constraints = constraints;
 
-	/* do we need to apply the constraint voltage */
-	if (rdev->constraints->apply_uV &&
-		rdev->constraints->min_uV == rdev->constraints->max_uV &&
-		ops->set_voltage) {
-		ret = ops->set_voltage(rdev,
-			rdev->constraints->min_uV, rdev->constraints->max_uV);
-			if (ret < 0) {
-				printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n",
-				       __func__,
-				       rdev->constraints->min_uV, name);
-				rdev->constraints = NULL;
-				goto out;
-			}
-	}
+	name = rdev_get_name(rdev);
+
+	ret = machine_constraints_voltage(rdev, constraints);
+	if (ret != 0)
+		goto out;
 
 	/* do we need to setup our suspend state */
 	if (constraints->initial_state) {
@@ -903,7 +949,7 @@ static int set_consumer_device_supply(st
 				dev_name(&node->regulator->dev),
 				node->regulator->desc->name,
 				supply,
-				dev_name(&rdev->dev), rdev->desc->name);
+				dev_name(&rdev->dev), rdev_get_name(rdev));
 		return -EBUSY;
 	}
 
@@ -1212,7 +1258,7 @@ static int _regulator_enable(struct regu
 		ret = _regulator_enable(rdev->supply);
 		if (ret < 0) {
 			printk(KERN_ERR "%s: failed to enable %s: %d\n",
-			       __func__, rdev->desc->name, ret);
+			       __func__, rdev_get_name(rdev), ret);
 			return ret;
 		}
 	}
@@ -1238,7 +1284,7 @@ static int _regulator_enable(struct regu
 			}
 		} else if (ret < 0) {
 			printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
-			       __func__, rdev->desc->name, ret);
+			       __func__, rdev_get_name(rdev), ret);
 			return ret;
 		}
 		/* Fallthrough on positive return values - already enabled */
@@ -1279,7 +1325,7 @@ static int _regulator_disable(struct reg
 
 	if (WARN(rdev->use_count <= 0,
 			"unbalanced disables for %s\n",
-			rdev->desc->name))
+			rdev_get_name(rdev)))
 		return -EIO;
 
 	/* are we the last user and permitted to disable ? */
@@ -1292,7 +1338,7 @@ static int _regulator_disable(struct reg
 			ret = rdev->desc->ops->disable(rdev);
 			if (ret < 0) {
 				printk(KERN_ERR "%s: failed to disable %s\n",
-				       __func__, rdev->desc->name);
+				       __func__, rdev_get_name(rdev));
 				return ret;
 			}
 		}
@@ -1349,7 +1395,7 @@ static int _regulator_force_disable(stru
 		ret = rdev->desc->ops->disable(rdev);
 		if (ret < 0) {
 			printk(KERN_ERR "%s: failed to force disable %s\n",
-			       __func__, rdev->desc->name);
+			       __func__, rdev_get_name(rdev));
 			return ret;
 		}
 		/* notify other consumers that power has been forced off */
@@ -1766,7 +1812,7 @@ int regulator_set_optimum_mode(struct re
 	output_uV = rdev->desc->ops->get_voltage(rdev);
 	if (output_uV <= 0) {
 		printk(KERN_ERR "%s: invalid output voltage found for %s\n",
-			__func__, rdev->desc->name);
+			__func__, rdev_get_name(rdev));
 		goto out;
 	}
 
@@ -1777,13 +1823,13 @@ int regulator_set_optimum_mode(struct re
 		input_uV = rdev->constraints->input_uV;
 	if (input_uV <= 0) {
 		printk(KERN_ERR "%s: invalid input voltage found for %s\n",
-			__func__, rdev->desc->name);
+			__func__, rdev_get_name(rdev));
 		goto out;
 	}
 
 	/* calc total requested load for this regulator */
 	list_for_each_entry(consumer, &rdev->consumer_list, list)
-	    total_uA_load += consumer->uA_load;
+		total_uA_load += consumer->uA_load;
 
 	mode = rdev->desc->ops->get_optimum_mode(rdev,
 						 input_uV, output_uV,
@@ -1791,7 +1837,7 @@ int regulator_set_optimum_mode(struct re
 	ret = regulator_check_mode(rdev, mode);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: failed to get optimum mode for %s @"
-			" %d uA %d -> %d uV\n", __func__, rdev->desc->name,
+			" %d uA %d -> %d uV\n", __func__, rdev_get_name(rdev),
 			total_uA_load, input_uV, output_uV);
 		goto out;
 	}
@@ -1799,7 +1845,7 @@ int regulator_set_optimum_mode(struct re
 	ret = rdev->desc->ops->set_mode(rdev, mode);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n",
-			__func__, mode, rdev->desc->name);
+			__func__, mode, rdev_get_name(rdev));
 		goto out;
 	}
 	ret = mode;
@@ -1852,9 +1898,9 @@ static void _notifier_call_chain(struct
 
 	/* now notify regulator we supply */
 	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
-	  mutex_lock(&_rdev->mutex);
-	  _notifier_call_chain(_rdev, event, data);
-	  mutex_unlock(&_rdev->mutex);
+		mutex_lock(&_rdev->mutex);
+		_notifier_call_chain(_rdev, event, data);
+		mutex_unlock(&_rdev->mutex);
 	}
 }
 
@@ -1885,9 +1931,9 @@ int regulator_bulk_get(struct device *de
 		consumers[i].consumer = regulator_get(dev,
 						      consumers[i].supply);
 		if (IS_ERR(consumers[i].consumer)) {
-			dev_err(dev, "Failed to get supply '%s'\n",
-				consumers[i].supply);
 			ret = PTR_ERR(consumers[i].consumer);
+			dev_err(dev, "Failed to get supply '%s': %d\n",
+				consumers[i].supply, ret);
 			consumers[i].consumer = NULL;
 			goto err;
 		}
@@ -1930,8 +1976,8 @@ int regulator_bulk_enable(int num_consum
 	return 0;
 
 err:
-	printk(KERN_ERR "Failed to enable %s\n", consumers[i].supply);
-	for (i = 0; i < num_consumers; i++)
+	printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret);
+	for (--i; i >= 0; --i)
 		regulator_disable(consumers[i].consumer);
 
 	return ret;
@@ -1965,8 +2011,9 @@ int regulator_bulk_disable(int num_consu
 	return 0;
 
 err:
-	printk(KERN_ERR "Failed to disable %s\n", consumers[i].supply);
-	for (i = 0; i < num_consumers; i++)
+	printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply,
+	       ret);
+	for (--i; i >= 0; --i)
 		regulator_enable(consumers[i].consumer);
 
 	return ret;
@@ -2316,7 +2363,7 @@ int regulator_suspend_prepare(suspend_st
 
 		if (ret < 0) {
 			printk(KERN_ERR "%s: failed to prepare %s\n",
-				__func__, rdev->desc->name);
+				__func__, rdev_get_name(rdev));
 			goto out;
 		}
 	}
@@ -2429,12 +2476,7 @@ static int __init regulator_init_complet
 		ops = rdev->desc->ops;
 		c = rdev->constraints;
 
-		if (c && c->name)
-			name = c->name;
-		else if (rdev->desc->name)
-			name = rdev->desc->name;
-		else
-			name = "regulator";
+		name = rdev_get_name(rdev);
 
 		if (!ops->disable || (c && c->always_on))
 			continue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/da903x.c linux-libre-2.6.33-gnu1/drivers/regulator/da903x.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/da903x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/da903x.c	2010-02-24 13:52:17.000000000 -0500
@@ -331,7 +331,7 @@ static int da9034_get_ldo12_voltage(stru
 static int da9034_list_ldo12_voltage(struct regulator_dev *rdev,
 				     unsigned selector)
 {
-	if (selector > ARRAY_SIZE(da9034_ldo12_data))
+	if (selector >= ARRAY_SIZE(da9034_ldo12_data))
 		return -EINVAL;
 	return da9034_ldo12_data[selector] * 1000;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/Kconfig linux-libre-2.6.33-gnu1/drivers/regulator/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/regulator/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -69,8 +69,15 @@ config REGULATOR_MAX1586
 	  regulator via I2C bus. The provided regulator is suitable
 	  for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
 
+config REGULATOR_MAX8660
+	tristate "Maxim 8660/8661 voltage regulator"
+	depends on I2C
+	help
+	  This driver controls a Maxim 8660/8661 voltage output
+	  regulator via I2C bus.
+
 config REGULATOR_TWL4030
-	bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+	bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
 	depends on TWL4030_CORE
 	help
 	  This driver supports the voltage regulators provided by
@@ -157,5 +164,11 @@ config REGULATOR_TPS6507X
 	  three step-down converters and two general-purpose LDO voltage regulators.
 	  It supports TI's software based Class-2 SmartReflex implementation.
 
+config REGULATOR_88PM8607
+	bool "Marvell 88PM8607 Power regulators"
+	depends on MFD_88PM8607=y
+	help
+	  This driver supports 88PM8607 voltage regulator chips.
+
 endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/lp3971.c linux-libre-2.6.33-gnu1/drivers/regulator/lp3971.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/lp3971.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/lp3971.c	2010-02-24 13:52:17.000000000 -0500
@@ -183,7 +183,7 @@ static int lp3971_ldo_set_voltage(struct
 		if (vol_map[val] >= min_vol)
 			break;
 
-	if (vol_map[val] > max_vol)
+	if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
 		return -EINVAL;
 
 	return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
@@ -272,7 +272,7 @@ static int lp3971_dcdc_set_voltage(struc
 		if (vol_map[val] >= min_vol)
 			break;
 
-	if (vol_map[val] > max_vol)
+	if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
 		return -EINVAL;
 
 	ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
@@ -446,8 +446,8 @@ static int setup_regulators(struct lp397
 		lp3971->rdev[i] = regulator_register(&regulators[id],
 			lp3971->dev, pdata->regulators[i].initdata, lp3971);
 
-		err = IS_ERR(lp3971->rdev[i]);
-		if (err) {
+		if (IS_ERR(lp3971->rdev[i])) {
+			err = PTR_ERR(lp3971->rdev[i]);
 			dev_err(lp3971->dev, "regulator init failed: %d\n",
 				err);
 			goto error;
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/Makefile linux-libre-2.6.33-gnu1/drivers/regulator/Makefile
--- linux-libre-2.6.32-gnu1/drivers/regulator/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -11,7 +11,8 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUME
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
-obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
+obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
@@ -20,10 +21,11 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
-obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
+obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
 
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
+obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/max8660.c linux-libre-2.6.33-gnu1/drivers/regulator/max8660.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/max8660.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/max8660.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,510 @@
+/*
+ * max8660.c  --  Voltage regulation for the Maxim 8660/8661
+ *
+ * based on max1586.c and wm8400-regulator.c
+ *
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Some info:
+ *
+ * Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8660-MAX8661.pdf
+ *
+ * This chip is a bit nasty because it is a write-only device. Thus, the driver
+ * uses shadow registers to keep track of its values. The main problem appears
+ * to be the initialization: When Linux boots up, we cannot know if the chip is
+ * in the default state or not, so we would have to pass such information in
+ * platform_data. As this adds a bit of complexity to the driver, this is left
+ * out for now until it is really needed.
+ *
+ * [A|S|M]DTV1 registers are currently not used, but [A|S|M]DTV2.
+ *
+ * If the driver is feature complete, it might be worth to check if one set of
+ * functions for V3-V7 is sufficient. For maximum flexibility during
+ * development, they are separated for now.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max8660.h>
+
+#define MAX8660_DCDC_MIN_UV	 725000
+#define MAX8660_DCDC_MAX_UV	1800000
+#define MAX8660_DCDC_STEP	  25000
+#define MAX8660_DCDC_MAX_SEL	0x2b
+
+#define MAX8660_LDO5_MIN_UV	1700000
+#define MAX8660_LDO5_MAX_UV	2000000
+#define MAX8660_LDO5_STEP	  25000
+#define MAX8660_LDO5_MAX_SEL	0x0c
+
+#define MAX8660_LDO67_MIN_UV	1800000
+#define MAX8660_LDO67_MAX_UV	3300000
+#define MAX8660_LDO67_STEP	 100000
+#define MAX8660_LDO67_MAX_SEL	0x0f
+
+enum {
+	MAX8660_OVER1,
+	MAX8660_OVER2,
+	MAX8660_VCC1,
+	MAX8660_ADTV1,
+	MAX8660_ADTV2,
+	MAX8660_SDTV1,
+	MAX8660_SDTV2,
+	MAX8660_MDTV1,
+	MAX8660_MDTV2,
+	MAX8660_L12VCR,
+	MAX8660_FPWM,
+	MAX8660_N_REGS,	/* not a real register */
+};
+
+struct max8660 {
+	struct i2c_client *client;
+	u8 shadow_regs[MAX8660_N_REGS];		/* as chip is write only */
+	struct regulator_dev *rdev[];
+};
+
+static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val)
+{
+	static const u8 max8660_addresses[MAX8660_N_REGS] =
+	  { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 };
+
+	int ret;
+	u8 reg_val = (max8660->shadow_regs[reg] & mask) | val;
+	dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n",
+			max8660_addresses[reg], reg_val);
+
+	ret = i2c_smbus_write_byte_data(max8660->client,
+			max8660_addresses[reg], reg_val);
+	if (ret == 0)
+		max8660->shadow_regs[reg] = reg_val;
+
+	return ret;
+}
+
+
+/*
+ * DCDC functions
+ */
+
+static int max8660_dcdc_is_enabled(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 val = max8660->shadow_regs[MAX8660_OVER1];
+	u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
+	return !!(val & mask);
+}
+
+static int max8660_dcdc_enable(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
+	return max8660_write(max8660, MAX8660_OVER1, 0xff, bit);
+}
+
+static int max8660_dcdc_disable(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4;
+	return max8660_write(max8660, MAX8660_OVER1, mask, 0);
+}
+
+static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector)
+{
+	if (selector > MAX8660_DCDC_MAX_SEL)
+		return -EINVAL;
+	return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
+}
+
+static int max8660_dcdc_get(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
+	u8 selector = max8660->shadow_regs[reg];
+	return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
+}
+
+static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 reg, selector, bits;
+	int ret;
+
+	if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV)
+		return -EINVAL;
+	if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV)
+		return -EINVAL;
+
+	selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1))
+			/ MAX8660_DCDC_STEP;
+
+	ret = max8660_dcdc_list(rdev, selector);
+	if (ret < 0 || ret > max_uV)
+		return -EINVAL;
+
+	reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
+	ret = max8660_write(max8660, reg, 0, selector);
+	if (ret)
+		return ret;
+
+	/* Select target voltage register and activate regulation */
+	bits = (rdev_get_id(rdev) == MAX8660_V3) ? 0x03 : 0x30;
+	return max8660_write(max8660, MAX8660_VCC1, 0xff, bits);
+}
+
+static struct regulator_ops max8660_dcdc_ops = {
+	.is_enabled = max8660_dcdc_is_enabled,
+	.list_voltage = max8660_dcdc_list,
+	.set_voltage = max8660_dcdc_set,
+	.get_voltage = max8660_dcdc_get,
+};
+
+
+/*
+ * LDO5 functions
+ */
+
+static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector)
+{
+	if (selector > MAX8660_LDO5_MAX_SEL)
+		return -EINVAL;
+	return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
+}
+
+static int max8660_ldo5_get(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
+
+	return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
+}
+
+static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 selector;
+	int ret;
+
+	if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV)
+		return -EINVAL;
+	if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV)
+		return -EINVAL;
+
+	selector = (min_uV - (MAX8660_LDO5_MIN_UV - MAX8660_LDO5_STEP + 1))
+			/ MAX8660_LDO5_STEP;
+	ret = max8660_ldo5_list(rdev, selector);
+	if (ret < 0 || ret > max_uV)
+		return -EINVAL;
+
+	ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector);
+	if (ret)
+		return ret;
+
+	/* Select target voltage register and activate regulation */
+	return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0);
+}
+
+static struct regulator_ops max8660_ldo5_ops = {
+	.list_voltage = max8660_ldo5_list,
+	.set_voltage = max8660_ldo5_set,
+	.get_voltage = max8660_ldo5_get,
+};
+
+
+/*
+ * LDO67 functions
+ */
+
+static int max8660_ldo67_is_enabled(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 val = max8660->shadow_regs[MAX8660_OVER2];
+	u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
+	return !!(val & mask);
+}
+
+static int max8660_ldo67_enable(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
+	return max8660_write(max8660, MAX8660_OVER2, 0xff, bit);
+}
+
+static int max8660_ldo67_disable(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4;
+	return max8660_write(max8660, MAX8660_OVER2, mask, 0);
+}
+
+static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector)
+{
+	if (selector > MAX8660_LDO67_MAX_SEL)
+		return -EINVAL;
+	return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
+}
+
+static int max8660_ldo67_get(struct regulator_dev *rdev)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4;
+	u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf;
+
+	return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
+}
+
+static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct max8660 *max8660 = rdev_get_drvdata(rdev);
+	u8 selector;
+	int ret;
+
+	if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV)
+		return -EINVAL;
+	if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV)
+		return -EINVAL;
+
+	selector = (min_uV - (MAX8660_LDO67_MIN_UV - MAX8660_LDO67_STEP + 1))
+			/ MAX8660_LDO67_STEP;
+
+	ret = max8660_ldo67_list(rdev, selector);
+	if (ret < 0 || ret > max_uV)
+		return -EINVAL;
+
+	if (rdev_get_id(rdev) == MAX8660_V6)
+		return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector);
+	else
+		return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4);
+}
+
+static struct regulator_ops max8660_ldo67_ops = {
+	.is_enabled = max8660_ldo67_is_enabled,
+	.enable = max8660_ldo67_enable,
+	.disable = max8660_ldo67_disable,
+	.list_voltage = max8660_ldo67_list,
+	.get_voltage = max8660_ldo67_get,
+	.set_voltage = max8660_ldo67_set,
+};
+
+static struct regulator_desc max8660_reg[] = {
+	{
+		.name = "V3(DCDC)",
+		.id = MAX8660_V3,
+		.ops = &max8660_dcdc_ops,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = MAX8660_DCDC_MAX_SEL + 1,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "V4(DCDC)",
+		.id = MAX8660_V4,
+		.ops = &max8660_dcdc_ops,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = MAX8660_DCDC_MAX_SEL + 1,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "V5(LDO)",
+		.id = MAX8660_V5,
+		.ops = &max8660_ldo5_ops,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = MAX8660_LDO5_MAX_SEL + 1,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "V6(LDO)",
+		.id = MAX8660_V6,
+		.ops = &max8660_ldo67_ops,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = MAX8660_LDO67_MAX_SEL + 1,
+		.owner = THIS_MODULE,
+	},
+	{
+		.name = "V7(LDO)",
+		.id = MAX8660_V7,
+		.ops = &max8660_ldo67_ops,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = MAX8660_LDO67_MAX_SEL + 1,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int max8660_probe(struct i2c_client *client,
+			      const struct i2c_device_id *i2c_id)
+{
+	struct regulator_dev **rdev;
+	struct max8660_platform_data *pdata = client->dev.platform_data;
+	struct max8660 *max8660;
+	int boot_on, i, id, ret = -EINVAL;
+
+	if (pdata->num_subdevs > MAX8660_V_END) {
+		dev_err(&client->dev, "Too much regulators found!\n");
+		goto out;
+	}
+
+	max8660 = kzalloc(sizeof(struct max8660) +
+			sizeof(struct regulator_dev *) * MAX8660_V_END,
+			GFP_KERNEL);
+	if (!max8660) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	max8660->client = client;
+	rdev = max8660->rdev;
+
+	if (pdata->en34_is_high) {
+		/* Simulate always on */
+		max8660->shadow_regs[MAX8660_OVER1] = 5;
+	} else {
+		/* Otherwise devices can be toggled via software */
+		max8660_dcdc_ops.enable = max8660_dcdc_enable;
+		max8660_dcdc_ops.disable = max8660_dcdc_disable;
+	}
+
+	/*
+	 * First, set up shadow registers to prevent glitches. As some
+	 * registers are shared between regulators, everything must be properly
+	 * set up for all regulators in advance.
+	 */
+	max8660->shadow_regs[MAX8660_ADTV1] =
+		max8660->shadow_regs[MAX8660_ADTV2] =
+		max8660->shadow_regs[MAX8660_SDTV1] =
+		max8660->shadow_regs[MAX8660_SDTV2] = 0x1b;
+	max8660->shadow_regs[MAX8660_MDTV1] =
+		max8660->shadow_regs[MAX8660_MDTV2] = 0x04;
+
+	for (i = 0; i < pdata->num_subdevs; i++) {
+
+		if (!pdata->subdevs[i].platform_data)
+			goto err_free;
+
+		boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
+
+		switch (pdata->subdevs[i].id) {
+		case MAX8660_V3:
+			if (boot_on)
+				max8660->shadow_regs[MAX8660_OVER1] |= 1;
+			break;
+
+		case MAX8660_V4:
+			if (boot_on)
+				max8660->shadow_regs[MAX8660_OVER1] |= 4;
+			break;
+
+		case MAX8660_V5:
+			break;
+
+		case MAX8660_V6:
+			if (boot_on)
+				max8660->shadow_regs[MAX8660_OVER2] |= 2;
+			break;
+
+		case MAX8660_V7:
+			if (!strcmp(i2c_id->name, "max8661")) {
+				dev_err(&client->dev, "Regulator not on this chip!\n");
+				goto err_free;
+			}
+
+			if (boot_on)
+				max8660->shadow_regs[MAX8660_OVER2] |= 4;
+			break;
+
+		default:
+			dev_err(&client->dev, "invalid regulator %s\n",
+				 pdata->subdevs[i].name);
+			goto err_free;
+		}
+	}
+
+	/* Finally register devices */
+	for (i = 0; i < pdata->num_subdevs; i++) {
+
+		id = pdata->subdevs[i].id;
+
+		rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
+					     pdata->subdevs[i].platform_data,
+					     max8660);
+		if (IS_ERR(rdev[i])) {
+			ret = PTR_ERR(rdev[i]);
+			dev_err(&client->dev, "failed to register %s\n",
+				max8660_reg[id].name);
+			goto err_unregister;
+		}
+	}
+
+	i2c_set_clientdata(client, rdev);
+	dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
+	return 0;
+
+err_unregister:
+	while (--i >= 0)
+		regulator_unregister(rdev[i]);
+err_free:
+	kfree(max8660);
+out:
+	return ret;
+}
+
+static int max8660_remove(struct i2c_client *client)
+{
+	struct regulator_dev **rdev = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < MAX8660_V_END; i++)
+		if (rdev[i])
+			regulator_unregister(rdev[i]);
+	kfree(rdev);
+	i2c_set_clientdata(client, NULL);
+
+	return 0;
+}
+
+static const struct i2c_device_id max8660_id[] = {
+	{ "max8660", 0 },
+	{ "max8661", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max8660_id);
+
+static struct i2c_driver max8660_driver = {
+	.probe = max8660_probe,
+	.remove = max8660_remove,
+	.driver		= {
+		.name	= "max8660",
+	},
+	.id_table	= max8660_id,
+};
+
+static int __init max8660_init(void)
+{
+	return i2c_add_driver(&max8660_driver);
+}
+subsys_initcall(max8660_init);
+
+static void __exit max8660_exit(void)
+{
+	i2c_del_driver(&max8660_driver);
+}
+module_exit(max8660_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAXIM 8660/8661 voltage regulator driver");
+MODULE_AUTHOR("Wolfram Sang");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/mc13783.c linux-libre-2.6.33-gnu1/drivers/regulator/mc13783.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/mc13783.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/mc13783.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,410 +0,0 @@
-/*
- * Regulator Driver for Freescale MC13783 PMIC
- *
- * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.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/mfd/mc13783-private.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/driver.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-
-struct mc13783_regulator {
-	struct regulator_desc desc;
-	int reg;
-	int enable_bit;
-};
-
-static struct regulator_ops mc13783_regulator_ops;
-
-static struct mc13783_regulator mc13783_regulators[] = {
-	[MC13783_SW_SW3] = {
-		.desc = {
-			.name	= "SW_SW3",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_SW_SW3,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_SWITCHERS_5,
-		.enable_bit = MC13783_SWCTRL_SW3_EN,
-	},
-	[MC13783_SW_PLL] = {
-		.desc = {
-			.name	= "SW_PLL",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_SW_PLL,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_SWITCHERS_4,
-		.enable_bit = MC13783_SWCTRL_PLL_EN,
-	},
-	[MC13783_REGU_VAUDIO] = {
-		.desc = {
-			.name	= "REGU_VAUDIO",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VAUDIO,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VAUDIO_EN,
-	},
-	[MC13783_REGU_VIOHI] = {
-		.desc = {
-			.name	= "REGU_VIOHI",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VIOHI,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VIOHI_EN,
-	},
-	[MC13783_REGU_VIOLO] = {
-		.desc = {
-			.name	= "REGU_VIOLO",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VIOLO,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VIOLO_EN,
-	},
-	[MC13783_REGU_VDIG] = {
-		.desc = {
-			.name	= "REGU_VDIG",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VDIG,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VDIG_EN,
-	},
-	[MC13783_REGU_VGEN] = {
-		.desc = {
-			.name	= "REGU_VGEN",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VGEN,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VGEN_EN,
-	},
-	[MC13783_REGU_VRFDIG] = {
-		.desc = {
-			.name	= "REGU_VRFDIG",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRFDIG,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VRFDIG_EN,
-	},
-	[MC13783_REGU_VRFREF] = {
-		.desc = {
-			.name	= "REGU_VRFREF",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRFREF,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VRFREF_EN,
-	},
-	[MC13783_REGU_VRFCP] = {
-		.desc = {
-			.name	= "REGU_VRFCP",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRFCP,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_0,
-		.enable_bit = MC13783_REGCTRL_VRFCP_EN,
-	},
-	[MC13783_REGU_VSIM] = {
-		.desc = {
-			.name	= "REGU_VSIM",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VSIM,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VSIM_EN,
-	},
-	[MC13783_REGU_VESIM] = {
-		.desc = {
-			.name	= "REGU_VESIM",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VESIM,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VESIM_EN,
-	},
-	[MC13783_REGU_VCAM] = {
-		.desc = {
-			.name	= "REGU_VCAM",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VCAM,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VCAM_EN,
-	},
-	[MC13783_REGU_VRFBG] = {
-		.desc = {
-			.name	= "REGU_VRFBG",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRFBG,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VRFBG_EN,
-	},
-	[MC13783_REGU_VVIB] = {
-		.desc = {
-			.name	= "REGU_VVIB",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VVIB,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VVIB_EN,
-	},
-	[MC13783_REGU_VRF1] = {
-		.desc = {
-			.name	= "REGU_VRF1",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRF1,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VRF1_EN,
-	},
-	[MC13783_REGU_VRF2] = {
-		.desc = {
-			.name	= "REGU_VRF2",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VRF2,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VRF2_EN,
-	},
-	[MC13783_REGU_VMMC1] = {
-		.desc = {
-			.name	= "REGU_VMMC1",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VMMC1,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VMMC1_EN,
-	},
-	[MC13783_REGU_VMMC2] = {
-		.desc = {
-			.name	= "REGU_VMMC2",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_VMMC2,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_REGULATOR_MODE_1,
-		.enable_bit = MC13783_REGCTRL_VMMC2_EN,
-	},
-	[MC13783_REGU_GPO1] = {
-		.desc = {
-			.name	= "REGU_GPO1",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_GPO1,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_POWER_MISCELLANEOUS,
-		.enable_bit = MC13783_REGCTRL_GPO1_EN,
-	},
-	[MC13783_REGU_GPO2] = {
-		.desc = {
-			.name	= "REGU_GPO2",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_GPO2,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_POWER_MISCELLANEOUS,
-		.enable_bit = MC13783_REGCTRL_GPO2_EN,
-	},
-	[MC13783_REGU_GPO3] = {
-		.desc = {
-			.name	= "REGU_GPO3",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_GPO3,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_POWER_MISCELLANEOUS,
-		.enable_bit = MC13783_REGCTRL_GPO3_EN,
-	},
-	[MC13783_REGU_GPO4] = {
-		.desc = {
-			.name	= "REGU_GPO4",
-			.ops	= &mc13783_regulator_ops,
-			.type	= REGULATOR_VOLTAGE,
-			.id	= MC13783_REGU_GPO4,
-			.owner	= THIS_MODULE,
-		},
-		.reg = MC13783_REG_POWER_MISCELLANEOUS,
-		.enable_bit = MC13783_REGCTRL_GPO4_EN,
-	},
-};
-
-struct mc13783_priv {
-	struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)];
-	struct mc13783 *mc13783;
-	struct regulator_dev *regulators[0];
-};
-
-static int mc13783_enable(struct regulator_dev *rdev)
-{
-	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
-
-	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
-
-	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
-			mc13783_regulators[id].enable_bit,
-			mc13783_regulators[id].enable_bit);
-}
-
-static int mc13783_disable(struct regulator_dev *rdev)
-{
-	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
-	int id = rdev_get_id(rdev);
-
-	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
-
-	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
-			mc13783_regulators[id].enable_bit, 0);
-}
-
-static int mc13783_is_enabled(struct regulator_dev *rdev)
-{
-	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
-	int ret, id = rdev_get_id(rdev);
-	unsigned int val;
-
-	ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
-	if (ret)
-		return ret;
-
-	return (val & mc13783_regulators[id].enable_bit) != 0;
-}
-
-static struct regulator_ops mc13783_regulator_ops = {
-	.enable		= mc13783_enable,
-	.disable	= mc13783_disable,
-	.is_enabled	= mc13783_is_enabled,
-};
-
-static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
-{
-	struct mc13783_priv *priv;
-	struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
-	struct mc13783_regulator_init_data *init_data;
-	int i, ret;
-
-	dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
-
-	priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *),
-			GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	priv->mc13783 = mc13783;
-
-	for (i = 0; i < mc13783->num_regulators; i++) {
-		init_data = &mc13783->regulators[i];
-		priv->regulators[i] = regulator_register(
-				&mc13783_regulators[init_data->id].desc,
-				&pdev->dev, init_data->init_data, priv);
-
-		if (IS_ERR(priv->regulators[i])) {
-			dev_err(&pdev->dev, "failed to register regulator %s\n",
-				mc13783_regulators[i].desc.name);
-			ret = PTR_ERR(priv->regulators[i]);
-			goto err;
-		}
-	}
-
-	platform_set_drvdata(pdev, priv);
-
-	return 0;
-err:
-	while (--i >= 0)
-		regulator_unregister(priv->regulators[i]);
-
-	kfree(priv);
-
-	return ret;
-}
-
-static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
-{
-	struct mc13783_priv *priv = platform_get_drvdata(pdev);
-	struct mc13783 *mc13783 = priv->mc13783;
-	int i;
-
-	for (i = 0; i < mc13783->num_regulators; i++)
-		regulator_unregister(priv->regulators[i]);
-
-	return 0;
-}
-
-static struct platform_driver mc13783_regulator_driver = {
-	.driver	= {
-		.name	= "mc13783-regulator",
-		.owner	= THIS_MODULE,
-	},
-	.remove		= __devexit_p(mc13783_regulator_remove),
-};
-
-static int __init mc13783_regulator_init(void)
-{
-	return platform_driver_probe(&mc13783_regulator_driver,
-			mc13783_regulator_probe);
-}
-subsys_initcall(mc13783_regulator_init);
-
-static void __exit mc13783_regulator_exit(void)
-{
-	platform_driver_unregister(&mc13783_regulator_driver);
-}
-module_exit(mc13783_regulator_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
-MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
-MODULE_ALIAS("platform:mc13783-regulator");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/mc13783-regulator.c linux-libre-2.6.33-gnu1/drivers/regulator/mc13783-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/mc13783-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/mc13783-regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,245 @@
+/*
+ * Regulator Driver for Freescale MC13783 PMIC
+ *
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.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/mfd/mc13783.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#define MC13783_REG_SWITCHERS4			28
+#define MC13783_REG_SWITCHERS4_PLLEN			(1 << 18)
+
+#define MC13783_REG_SWITCHERS5			29
+#define MC13783_REG_SWITCHERS5_SW3EN			(1 << 20)
+
+#define MC13783_REG_REGULATORMODE0		32
+#define MC13783_REG_REGULATORMODE0_VAUDIOEN		(1 << 0)
+#define MC13783_REG_REGULATORMODE0_VIOHIEN		(1 << 3)
+#define MC13783_REG_REGULATORMODE0_VIOLOEN		(1 << 6)
+#define MC13783_REG_REGULATORMODE0_VDIGEN		(1 << 9)
+#define MC13783_REG_REGULATORMODE0_VGENEN		(1 << 12)
+#define MC13783_REG_REGULATORMODE0_VRFDIGEN		(1 << 15)
+#define MC13783_REG_REGULATORMODE0_VRFREFEN		(1 << 18)
+#define MC13783_REG_REGULATORMODE0_VRFCPEN		(1 << 21)
+
+#define MC13783_REG_REGULATORMODE1		33
+#define MC13783_REG_REGULATORMODE1_VSIMEN		(1 << 0)
+#define MC13783_REG_REGULATORMODE1_VESIMEN		(1 << 3)
+#define MC13783_REG_REGULATORMODE1_VCAMEN		(1 << 6)
+#define MC13783_REG_REGULATORMODE1_VRFBGEN		(1 << 9)
+#define MC13783_REG_REGULATORMODE1_VVIBEN		(1 << 11)
+#define MC13783_REG_REGULATORMODE1_VRF1EN		(1 << 12)
+#define MC13783_REG_REGULATORMODE1_VRF2EN		(1 << 15)
+#define MC13783_REG_REGULATORMODE1_VMMC1EN		(1 << 18)
+#define MC13783_REG_REGULATORMODE1_VMMC2EN		(1 << 21)
+
+#define MC13783_REG_POWERMISC			34
+#define MC13783_REG_POWERMISC_GPO1EN			(1 << 6)
+#define MC13783_REG_POWERMISC_GPO2EN			(1 << 8)
+#define MC13783_REG_POWERMISC_GPO3EN			(1 << 10)
+#define MC13783_REG_POWERMISC_GPO4EN			(1 << 12)
+
+struct mc13783_regulator {
+	struct regulator_desc desc;
+	int reg;
+	int enable_bit;
+};
+
+static struct regulator_ops mc13783_regulator_ops;
+
+#define MC13783_DEFINE(prefix, _name, _reg)				\
+	[MC13783_ ## prefix ## _ ## _name] = {				\
+		.desc = {						\
+			.name = #prefix "_" #_name,			\
+			.ops = &mc13783_regulator_ops,			\
+			.type = REGULATOR_VOLTAGE,			\
+			.id = MC13783_ ## prefix ## _ ## _name,		\
+			.owner = THIS_MODULE,				\
+		},							\
+		.reg = MC13783_REG_ ## _reg,				\
+		.enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN,	\
+	}
+
+#define MC13783_DEFINE_SW(_name, _reg) MC13783_DEFINE(SW, _name, _reg)
+#define MC13783_DEFINE_REGU(_name, _reg) MC13783_DEFINE(REGU, _name, _reg)
+
+static struct mc13783_regulator mc13783_regulators[] = {
+	MC13783_DEFINE_SW(SW3, SWITCHERS5),
+	MC13783_DEFINE_SW(PLL, SWITCHERS4),
+
+	MC13783_DEFINE_REGU(VAUDIO, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VIOHI, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VDIG, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VGEN, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0),
+	MC13783_DEFINE_REGU(VSIM, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VESIM, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VCAM, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VRFBG, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VVIB, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VRF1, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VRF2, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1),
+	MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1),
+	MC13783_DEFINE_REGU(GPO1, POWERMISC),
+	MC13783_DEFINE_REGU(GPO2, POWERMISC),
+	MC13783_DEFINE_REGU(GPO3, POWERMISC),
+	MC13783_DEFINE_REGU(GPO4, POWERMISC),
+};
+
+struct mc13783_regulator_priv {
+	struct mc13783 *mc13783;
+	struct regulator_dev *regulators[];
+};
+
+static int mc13783_regulator_enable(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+	int ret;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit,
+			mc13783_regulators[id].enable_bit);
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static int mc13783_regulator_disable(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+	int ret;
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit, 0);
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static int mc13783_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
+	int ret, id = rdev_get_id(rdev);
+	unsigned int val;
+
+	mc13783_lock(priv->mc13783);
+	ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+	mc13783_unlock(priv->mc13783);
+
+	if (ret)
+		return ret;
+
+	return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_regulator_ops = {
+	.enable = mc13783_regulator_enable,
+	.disable = mc13783_regulator_disable,
+	.is_enabled = mc13783_regulator_is_enabled,
+};
+
+static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
+{
+	struct mc13783_regulator_priv *priv;
+	struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
+	struct mc13783_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
+	struct mc13783_regulator_init_data *init_data;
+	int i, ret;
+
+	dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
+
+	priv = kzalloc(sizeof(*priv) +
+			pdata->num_regulators * sizeof(priv->regulators[0]),
+			GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = mc13783;
+
+	for (i = 0; i < pdata->num_regulators; i++) {
+		init_data = &pdata->regulators[i];
+		priv->regulators[i] = regulator_register(
+				&mc13783_regulators[init_data->id].desc,
+				&pdev->dev, init_data->init_data, priv);
+
+		if (IS_ERR(priv->regulators[i])) {
+			dev_err(&pdev->dev, "failed to register regulator %s\n",
+				mc13783_regulators[i].desc.name);
+			ret = PTR_ERR(priv->regulators[i]);
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+err:
+	while (--i >= 0)
+		regulator_unregister(priv->regulators[i]);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
+{
+	struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev);
+	struct mc13783_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
+	int i;
+
+	for (i = 0; i < pdata->num_regulators; i++)
+		regulator_unregister(priv->regulators[i]);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_regulator_driver = {
+	.driver	= {
+		.name	= "mc13783-regulator",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __devexit_p(mc13783_regulator_remove),
+	.probe		= mc13783_regulator_probe,
+};
+
+static int __init mc13783_regulator_init(void)
+{
+	return platform_driver_register(&mc13783_regulator_driver);
+}
+subsys_initcall(mc13783_regulator_init);
+
+static void __exit mc13783_regulator_exit(void)
+{
+	platform_driver_unregister(&mc13783_regulator_driver);
+}
+module_exit(mc13783_regulator_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
+MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
+MODULE_ALIAS("platform:mc13783-regulator");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/pcf50633-regulator.c linux-libre-2.6.33-gnu1/drivers/regulator/pcf50633-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/pcf50633-regulator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/pcf50633-regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -314,13 +314,15 @@ static int __devinit pcf50633_regulator_
 	struct pcf50633 *pcf;
 
 	/* Already set by core driver */
-	pcf = platform_get_drvdata(pdev);
+	pcf = dev_to_pcf50633(pdev->dev.parent);
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
 				  pdev->dev.platform_data, pcf);
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
+	platform_set_drvdata(pdev, rdev);
+
 	if (pcf->pdata->regulator_registered)
 		pcf->pdata->regulator_registered(pcf, pdev->id);
 
@@ -331,6 +333,7 @@ static int __devexit pcf50633_regulator_
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
+	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(rdev);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/twl4030-regulator.c linux-libre-2.6.33-gnu1/drivers/regulator/twl4030-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/twl4030-regulator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/twl4030-regulator.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,500 +0,0 @@
-/*
- * twl4030-regulator.c -- support regulators in twl4030 family chips
- *
- * Copyright (C) 2008 David Brownell
- *
- * 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/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
-
-
-/*
- * The TWL4030/TW5030/TPS659x0 family chips include power management, a
- * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
- * include an audio codec, battery charger, and more voltage regulators.
- * These chips are often used in OMAP-based systems.
- *
- * This driver implements software-based resource control for various
- * voltage regulators.  This is usually augmented with state machine
- * based control.
- */
-
-struct twlreg_info {
-	/* start of regulator's PM_RECEIVER control register bank */
-	u8			base;
-
-	/* twl4030 resource ID, for resource control state machine */
-	u8			id;
-
-	/* voltage in mV = table[VSEL]; table_len must be a power-of-two */
-	u8			table_len;
-	const u16		*table;
-
-	/* chip constraints on regulator behavior */
-	u16			min_mV;
-
-	/* used by regulator core */
-	struct regulator_desc	desc;
-};
-
-
-/* LDO control registers ... offset is from the base of its register bank.
- * The first three registers of all power resource banks help hardware to
- * manage the various resource groups.
- */
-#define VREG_GRP		0
-#define VREG_TYPE		1
-#define VREG_REMAP		2
-#define VREG_DEDICATED		3	/* LDO control */
-
-
-static inline int
-twl4030reg_read(struct twlreg_info *info, unsigned offset)
-{
-	u8 value;
-	int status;
-
-	status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
-			&value, info->base + offset);
-	return (status < 0) ? status : value;
-}
-
-static inline int
-twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
-{
-	return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
-			value, info->base + offset);
-}
-
-/*----------------------------------------------------------------------*/
-
-/* generic power resource operations, which work on all regulators */
-
-static int twl4030reg_grp(struct regulator_dev *rdev)
-{
-	return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
-}
-
-/*
- * Enable/disable regulators by joining/leaving the P1 (processor) group.
- * We assume nobody else is updating the DEV_GRP registers.
- */
-
-#define P3_GRP		BIT(7)		/* "peripherals" */
-#define P2_GRP		BIT(6)		/* secondary processor, modem, etc */
-#define P1_GRP		BIT(5)		/* CPU/Linux */
-
-static int twl4030reg_is_enabled(struct regulator_dev *rdev)
-{
-	int	state = twl4030reg_grp(rdev);
-
-	if (state < 0)
-		return state;
-
-	return (state & P1_GRP) != 0;
-}
-
-static int twl4030reg_enable(struct regulator_dev *rdev)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	int			grp;
-
-	grp = twl4030reg_read(info, VREG_GRP);
-	if (grp < 0)
-		return grp;
-
-	grp |= P1_GRP;
-	return twl4030reg_write(info, VREG_GRP, grp);
-}
-
-static int twl4030reg_disable(struct regulator_dev *rdev)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	int			grp;
-
-	grp = twl4030reg_read(info, VREG_GRP);
-	if (grp < 0)
-		return grp;
-
-	grp &= ~P1_GRP;
-	return twl4030reg_write(info, VREG_GRP, grp);
-}
-
-static int twl4030reg_get_status(struct regulator_dev *rdev)
-{
-	int	state = twl4030reg_grp(rdev);
-
-	if (state < 0)
-		return state;
-	state &= 0x0f;
-
-	/* assume state != WARM_RESET; we'd not be running...  */
-	if (!state)
-		return REGULATOR_STATUS_OFF;
-	return (state & BIT(3))
-		? REGULATOR_STATUS_NORMAL
-		: REGULATOR_STATUS_STANDBY;
-}
-
-static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	unsigned		message;
-	int			status;
-
-	/* We can only set the mode through state machine commands... */
-	switch (mode) {
-	case REGULATOR_MODE_NORMAL:
-		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
-		break;
-	case REGULATOR_MODE_STANDBY:
-		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* Ensure the resource is associated with some group */
-	status = twl4030reg_grp(rdev);
-	if (status < 0)
-		return status;
-	if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
-		return -EACCES;
-
-	status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-			message >> 8, 0x15 /* PB_WORD_MSB */ );
-	if (status >= 0)
-		return status;
-
-	return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-			message, 0x16 /* PB_WORD_LSB */ );
-}
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
- * select field in its control register.   We use tables indexed by VSEL
- * to record voltages in milliVolts.  (Accuracy is about three percent.)
- *
- * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
- * currently handled by listing two slightly different VAUX2 regulators,
- * only one of which will be configured.
- *
- * VSEL values documented as "TI cannot support these values" are flagged
- * in these tables as UNSUP() values; we normally won't assign them.
- *
- * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
- * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
- */
-#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
-#define UNSUP_MASK	0x0000
-#else
-#define UNSUP_MASK	0x8000
-#endif
-
-#define UNSUP(x)	(UNSUP_MASK | (x))
-#define IS_UNSUP(x)	(UNSUP_MASK & (x))
-#define LDO_MV(x)	(~UNSUP_MASK & (x))
-
-
-static const u16 VAUX1_VSEL_table[] = {
-	UNSUP(1500), UNSUP(1800), 2500, 2800,
-	3000, 3000, 3000, 3000,
-};
-static const u16 VAUX2_4030_VSEL_table[] = {
-	UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
-	1500, 1800, UNSUP(1850), 2500,
-	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
-	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VAUX2_VSEL_table[] = {
-	1700, 1700, 1900, 1300,
-	1500, 1800, 2000, 2500,
-	2100, 2800, 2200, 2300,
-	2400, 2400, 2400, 2400,
-};
-static const u16 VAUX3_VSEL_table[] = {
-	1500, 1800, 2500, 2800,
-	3000, 3000, 3000, 3000,
-};
-static const u16 VAUX4_VSEL_table[] = {
-	700, 1000, 1200, UNSUP(1300),
-	1500, 1800, UNSUP(1850), 2500,
-	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
-	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VMMC1_VSEL_table[] = {
-	1850, 2850, 3000, 3150,
-};
-static const u16 VMMC2_VSEL_table[] = {
-	UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
-	UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
-	2600, 2800, 2850, 3000,
-	3150, 3150, 3150, 3150,
-};
-static const u16 VPLL1_VSEL_table[] = {
-	1000, 1200, 1300, 1800,
-	UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
-};
-static const u16 VPLL2_VSEL_table[] = {
-	700, 1000, 1200, 1300,
-	UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
-	UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
-	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VSIM_VSEL_table[] = {
-	UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
-	2800, 3000, 3000, 3000,
-};
-static const u16 VDAC_VSEL_table[] = {
-	1200, 1300, 1800, 1800,
-};
-
-
-static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	int			mV = info->table[index];
-
-	return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
-}
-
-static int
-twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	int			vsel;
-
-	for (vsel = 0; vsel < info->table_len; vsel++) {
-		int mV = info->table[vsel];
-		int uV;
-
-		if (IS_UNSUP(mV))
-			continue;
-		uV = LDO_MV(mV) * 1000;
-
-		/* REVISIT for VAUX2, first match may not be best/lowest */
-
-		/* use the first in-range value */
-		if (min_uV <= uV && uV <= max_uV)
-			return twl4030reg_write(info, VREG_DEDICATED, vsel);
-	}
-
-	return -EDOM;
-}
-
-static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-	int			vsel = twl4030reg_read(info, VREG_DEDICATED);
-
-	if (vsel < 0)
-		return vsel;
-
-	vsel &= info->table_len - 1;
-	return LDO_MV(info->table[vsel]) * 1000;
-}
-
-static struct regulator_ops twl4030ldo_ops = {
-	.list_voltage	= twl4030ldo_list_voltage,
-
-	.set_voltage	= twl4030ldo_set_voltage,
-	.get_voltage	= twl4030ldo_get_voltage,
-
-	.enable		= twl4030reg_enable,
-	.disable	= twl4030reg_disable,
-	.is_enabled	= twl4030reg_is_enabled,
-
-	.set_mode	= twl4030reg_set_mode,
-
-	.get_status	= twl4030reg_get_status,
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Fixed voltage LDOs don't have a VSEL field to update.
- */
-static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-
-	return info->min_mV * 1000;
-}
-
-static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
-{
-	struct twlreg_info	*info = rdev_get_drvdata(rdev);
-
-	return info->min_mV * 1000;
-}
-
-static struct regulator_ops twl4030fixed_ops = {
-	.list_voltage	= twl4030fixed_list_voltage,
-
-	.get_voltage	= twl4030fixed_get_voltage,
-
-	.enable		= twl4030reg_enable,
-	.disable	= twl4030reg_disable,
-	.is_enabled	= twl4030reg_is_enabled,
-
-	.set_mode	= twl4030reg_set_mode,
-
-	.get_status	= twl4030reg_get_status,
-};
-
-/*----------------------------------------------------------------------*/
-
-#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
-	.base = offset, \
-	.id = num, \
-	.table_len = ARRAY_SIZE(label##_VSEL_table), \
-	.table = label##_VSEL_table, \
-	.desc = { \
-		.name = #label, \
-		.id = TWL4030_REG_##label, \
-		.n_voltages = ARRAY_SIZE(label##_VSEL_table), \
-		.ops = &twl4030ldo_ops, \
-		.type = REGULATOR_VOLTAGE, \
-		.owner = THIS_MODULE, \
-		}, \
-	}
-
-#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
-	.base = offset, \
-	.id = num, \
-	.min_mV = mVolts, \
-	.desc = { \
-		.name = #label, \
-		.id = TWL4030_REG_##label, \
-		.n_voltages = 1, \
-		.ops = &twl4030fixed_ops, \
-		.type = REGULATOR_VOLTAGE, \
-		.owner = THIS_MODULE, \
-		}, \
-	}
-
-/*
- * We list regulators here if systems need some level of
- * software control over them after boot.
- */
-static struct twlreg_info twl4030_regs[] = {
-	TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
-	TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
-	TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
-	TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
-	TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
-	TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
-	TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
-	/*
-	TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
-	*/
-	TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
-	TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
-	TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
-	/*
-	TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
-	TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
-	TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
-	TWL_SMPS(VIO, 0x4b, 14),
-	TWL_SMPS(VDD1, 0x55, 15),
-	TWL_SMPS(VDD2, 0x63, 16),
-	 */
-	TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
-	TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
-	TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
-	/* VUSBCP is managed *only* by the USB subchip */
-};
-
-static int twl4030reg_probe(struct platform_device *pdev)
-{
-	int				i;
-	struct twlreg_info		*info;
-	struct regulator_init_data	*initdata;
-	struct regulation_constraints	*c;
-	struct regulator_dev		*rdev;
-
-	for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
-		if (twl4030_regs[i].desc.id != pdev->id)
-			continue;
-		info = twl4030_regs + i;
-		break;
-	}
-	if (!info)
-		return -ENODEV;
-
-	initdata = pdev->dev.platform_data;
-	if (!initdata)
-		return -EINVAL;
-
-	/* Constrain board-specific capabilities according to what
-	 * this driver and the chip itself can actually do.
-	 */
-	c = &initdata->constraints;
-	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
-	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
-				| REGULATOR_CHANGE_MODE
-				| REGULATOR_CHANGE_STATUS;
-
-	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
-	if (IS_ERR(rdev)) {
-		dev_err(&pdev->dev, "can't register %s, %ld\n",
-				info->desc.name, PTR_ERR(rdev));
-		return PTR_ERR(rdev);
-	}
-	platform_set_drvdata(pdev, rdev);
-
-	/* NOTE:  many regulators support short-circuit IRQs (presentable
-	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
-	 *  - SC_CONFIG
-	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
-	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
-	 *  - IT_CONFIG
-	 */
-
-	return 0;
-}
-
-static int __devexit twl4030reg_remove(struct platform_device *pdev)
-{
-	regulator_unregister(platform_get_drvdata(pdev));
-	return 0;
-}
-
-MODULE_ALIAS("platform:twl4030_reg");
-
-static struct platform_driver twl4030reg_driver = {
-	.probe		= twl4030reg_probe,
-	.remove		= __devexit_p(twl4030reg_remove),
-	/* NOTE: short name, to work around driver model truncation of
-	 * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
-	 */
-	.driver.name	= "twl4030_reg",
-	.driver.owner	= THIS_MODULE,
-};
-
-static int __init twl4030reg_init(void)
-{
-	return platform_driver_register(&twl4030reg_driver);
-}
-subsys_initcall(twl4030reg_init);
-
-static void __exit twl4030reg_exit(void)
-{
-	platform_driver_unregister(&twl4030reg_driver);
-}
-module_exit(twl4030reg_exit)
-
-MODULE_DESCRIPTION("TWL4030 regulator driver");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/twl-regulator.c linux-libre-2.6.33-gnu1/drivers/regulator/twl-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/twl-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/twl-regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,630 @@
+/*
+ * twl-regulator.c -- support regulators in twl4030/twl6030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * 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/init.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0/TWL6030 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators.  This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+	/* start of regulator's PM_RECEIVER control register bank */
+	u8			base;
+
+	/* twl resource ID, for resource control state machine */
+	u8			id;
+
+	/* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+	u8			table_len;
+	const u16		*table;
+
+	/* regulator specific turn-on delay */
+	u16			delay;
+
+	/* State REMAP default configuration */
+	u8			remap;
+
+	/* chip constraints on regulator behavior */
+	u16			min_mV;
+
+	/* used by regulator core */
+	struct regulator_desc	desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+/* Common offset in TWL4030/6030 */
+#define VREG_GRP		0
+/* TWL4030 register offsets */
+#define VREG_TYPE		1
+#define VREG_REMAP		2
+#define VREG_DEDICATED		3	/* LDO control */
+/* TWL6030 register offsets */
+#define VREG_TRANS		1
+#define VREG_STATE		2
+#define VREG_VOLTAGE		3
+/* TWL6030 Misc register offsets */
+#define VREG_BC_ALL		1
+#define VREG_BC_REF		2
+#define VREG_BC_PROC		3
+#define VREG_BC_CLK_RST		4
+
+static inline int
+twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
+{
+	u8 value;
+	int status;
+
+	status = twl_i2c_read_u8(slave_subgp,
+			&value, info->base + offset);
+	return (status < 0) ? status : value;
+}
+
+static inline int
+twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset,
+						 u8 value)
+{
+	return twl_i2c_write_u8(slave_subgp,
+			value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twlreg_grp(struct regulator_dev *rdev)
+{
+	return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_RECEIVER,
+								 VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+/* definition for 4030 family */
+#define P3_GRP_4030	BIT(7)		/* "peripherals" */
+#define P2_GRP_4030	BIT(6)		/* secondary processor, modem, etc */
+#define P1_GRP_4030	BIT(5)		/* CPU/Linux */
+/* definition for 6030 family */
+#define P3_GRP_6030	BIT(2)		/* secondary processor, modem, etc */
+#define P2_GRP_6030	BIT(1)		/* "peripherals" */
+#define P1_GRP_6030	BIT(0)		/* CPU/Linux */
+
+static int twlreg_is_enabled(struct regulator_dev *rdev)
+{
+	int	state = twlreg_grp(rdev);
+
+	if (state < 0)
+		return state;
+
+	if (twl_class_is_4030())
+		state &= P1_GRP_4030;
+	else
+		state &= P1_GRP_6030;
+	return state;
+}
+
+static int twlreg_enable(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp;
+	int			ret;
+
+	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	if (twl_class_is_4030())
+		grp |= P1_GRP_4030;
+	else
+		grp |= P1_GRP_6030;
+
+	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
+
+	udelay(info->delay);
+
+	return ret;
+}
+
+static int twlreg_disable(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp;
+
+	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	if (twl_class_is_4030())
+		grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
+	else
+		grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);
+
+	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
+}
+
+static int twlreg_get_status(struct regulator_dev *rdev)
+{
+	int	state = twlreg_grp(rdev);
+
+	if (twl_class_is_6030())
+		return 0; /* FIXME return for 6030 regulator */
+
+	if (state < 0)
+		return state;
+	state &= 0x0f;
+
+	/* assume state != WARM_RESET; we'd not be running...  */
+	if (!state)
+		return REGULATOR_STATUS_OFF;
+	return (state & BIT(3))
+		? REGULATOR_STATUS_NORMAL
+		: REGULATOR_STATUS_STANDBY;
+}
+
+static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	unsigned		message;
+	int			status;
+
+	if (twl_class_is_6030())
+		return 0; /* FIXME return for 6030 regulator */
+
+	/* We can only set the mode through state machine commands... */
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+		break;
+	case REGULATOR_MODE_STANDBY:
+		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Ensure the resource is associated with some group */
+	status = twlreg_grp(rdev);
+	if (status < 0)
+		return status;
+	if (!(status & (P3_GRP_4030 | P2_GRP_4030 | P1_GRP_4030)))
+		return -EACCES;
+
+	status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
+			message >> 8, 0x15 /* PB_WORD_MSB */ );
+	if (status >= 0)
+		return status;
+
+	return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
+			message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register.   We use tables indexed by VSEL
+ * to record voltages in milliVolts.  (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK	0x0000
+#else
+#define UNSUP_MASK	0x8000
+#endif
+
+#define UNSUP(x)	(UNSUP_MASK | (x))
+#define IS_UNSUP(x)	(UNSUP_MASK & (x))
+#define LDO_MV(x)	(~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+	UNSUP(1500), UNSUP(1800), 2500, 2800,
+	3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+	1500, 1800, UNSUP(1850), 2500,
+	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+	1700, 1700, 1900, 1300,
+	1500, 1800, 2000, 2500,
+	2100, 2800, 2200, 2300,
+	2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+	1500, 1800, 2500, 2800,
+	3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+	700, 1000, 1200, UNSUP(1300),
+	1500, 1800, UNSUP(1850), 2500,
+	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+	1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+	UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+	2600, 2800, 2850, 3000,
+	3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+	1000, 1200, 1300, 1800,
+	UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+	700, 1000, 1200, 1300,
+	UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+	UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+	2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+	1200, 1300, 1800, 1800,
+};
+static const u16 VDD1_VSEL_table[] = {
+	800, 1450,
+};
+static const u16 VDD2_VSEL_table[] = {
+	800, 1450, 1500,
+};
+static const u16 VIO_VSEL_table[] = {
+	1800, 1850,
+};
+static const u16 VINTANA2_VSEL_table[] = {
+	2500, 2750,
+};
+static const u16 VAUX1_6030_VSEL_table[] = {
+	1000, 1300, 1800, 2500,
+	2800, 2900, 3000, 3000,
+};
+static const u16 VAUX2_6030_VSEL_table[] = {
+	1200, 1800, 2500, 2750,
+	2800, 2800, 2800, 2800,
+};
+static const u16 VAUX3_6030_VSEL_table[] = {
+	1000, 1200, 1300, 1800,
+	2500, 2800, 3000, 3000,
+};
+static const u16 VMMC_VSEL_table[] = {
+	1200, 1800, 2800, 2900,
+	3000, 3000, 3000, 3000,
+};
+static const u16 VPP_VSEL_table[] = {
+	1800, 1900, 2000, 2100,
+	2200, 2300, 2400, 2500,
+};
+static const u16 VUSIM_VSEL_table[] = {
+	1200, 1800, 2500, 2900,
+};
+
+static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			mV = info->table[index];
+
+	return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			vsel;
+
+	for (vsel = 0; vsel < info->table_len; vsel++) {
+		int mV = info->table[vsel];
+		int uV;
+
+		if (IS_UNSUP(mV))
+			continue;
+		uV = LDO_MV(mV) * 1000;
+
+		/* REVISIT for VAUX2, first match may not be best/lowest */
+
+		/* use the first in-range value */
+		if (min_uV <= uV && uV <= max_uV)
+			return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
+							VREG_VOLTAGE, vsel);
+	}
+
+	return -EDOM;
+}
+
+static int twlldo_get_voltage(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int		vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
+								VREG_VOLTAGE);
+
+	if (vsel < 0)
+		return vsel;
+
+	vsel &= info->table_len - 1;
+	return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twlldo_ops = {
+	.list_voltage	= twlldo_list_voltage,
+
+	.set_voltage	= twlldo_set_voltage,
+	.get_voltage	= twlldo_get_voltage,
+
+	.enable		= twlreg_enable,
+	.disable	= twlreg_disable,
+	.is_enabled	= twlreg_is_enabled,
+
+	.set_mode	= twlreg_set_mode,
+
+	.get_status	= twlreg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	return info->min_mV * 1000;
+}
+
+static int twlfixed_get_voltage(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	return info->min_mV * 1000;
+}
+
+static struct regulator_ops twlfixed_ops = {
+	.list_voltage	= twlfixed_list_voltage,
+
+	.get_voltage	= twlfixed_get_voltage,
+
+	.enable		= twlreg_enable,
+	.disable	= twlreg_disable,
+	.is_enabled	= twlreg_is_enabled,
+
+	.set_mode	= twlreg_set_mode,
+
+	.get_status	= twlreg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
+		TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
+			remap_conf, TWL4030)
+#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
+			remap_conf) \
+		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
+			remap_conf, TWL4030)
+#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
+			remap_conf) \
+		TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \
+			remap_conf, TWL6030)
+#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
+			remap_conf) \
+		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
+			remap_conf, TWL6030)
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \
+		family) { \
+	.base = offset, \
+	.id = num, \
+	.table_len = ARRAY_SIZE(label##_VSEL_table), \
+	.table = label##_VSEL_table, \
+	.delay = turnon_delay, \
+	.remap = remap_conf, \
+	.desc = { \
+		.name = #label, \
+		.id = family##_REG_##label, \
+		.n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+		.ops = &twlldo_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
+		family) { \
+	.base = offset, \
+	.id = num, \
+	.min_mV = mVolts, \
+	.delay = turnon_delay, \
+	.remap = remap_conf, \
+	.desc = { \
+		.name = #label, \
+		.id = family##_REG_##label, \
+		.n_voltages = 1, \
+		.ops = &twlfixed_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl_regs[] = {
+	TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00),
+	TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00),
+	TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08),
+	TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
+	TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08),
+	TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08),
+	TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
+	TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
+	TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
+	/* VUSBCP is managed *only* by the USB subchip */
+
+	/* 6030 REG with base as PMC Slave Misc : 0x0030 */
+	/* Turnon-delay and remap configuration values for 6030 are not
+	   verified since the specification is not public */
+	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x08),
+	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x08),
+	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x08),
+	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x08),
+	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x08),
+	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x08),
+	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x08),
+	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x08),
+	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x08),
+	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x08)
+};
+
+static int twlreg_probe(struct platform_device *pdev)
+{
+	int				i;
+	struct twlreg_info		*info;
+	struct regulator_init_data	*initdata;
+	struct regulation_constraints	*c;
+	struct regulator_dev		*rdev;
+
+	for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
+		if (twl_regs[i].desc.id != pdev->id)
+			continue;
+		info = twl_regs + i;
+		break;
+	}
+	if (!info)
+		return -ENODEV;
+
+	initdata = pdev->dev.platform_data;
+	if (!initdata)
+		return -EINVAL;
+
+	/* Constrain board-specific capabilities according to what
+	 * this driver and the chip itself can actually do.
+	 */
+	c = &initdata->constraints;
+	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+				| REGULATOR_CHANGE_MODE
+				| REGULATOR_CHANGE_STATUS;
+	switch (pdev->id) {
+	case TWL4030_REG_VIO:
+	case TWL4030_REG_VDD1:
+	case TWL4030_REG_VDD2:
+	case TWL4030_REG_VPLL1:
+	case TWL4030_REG_VINTANA1:
+	case TWL4030_REG_VINTANA2:
+	case TWL4030_REG_VINTDIG:
+		c->always_on = true;
+		break;
+	default:
+		break;
+	}
+
+	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "can't register %s, %ld\n",
+				info->desc.name, PTR_ERR(rdev));
+		return PTR_ERR(rdev);
+	}
+	platform_set_drvdata(pdev, rdev);
+
+	twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
+						info->remap);
+
+	/* NOTE:  many regulators support short-circuit IRQs (presentable
+	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
+	 *  - SC_CONFIG
+	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+	 *  - IT_CONFIG
+	 */
+
+	return 0;
+}
+
+static int __devexit twlreg_remove(struct platform_device *pdev)
+{
+	regulator_unregister(platform_get_drvdata(pdev));
+	return 0;
+}
+
+MODULE_ALIAS("platform:twl_reg");
+
+static struct platform_driver twlreg_driver = {
+	.probe		= twlreg_probe,
+	.remove		= __devexit_p(twlreg_remove),
+	/* NOTE: short name, to work around driver model truncation of
+	 * "twl_regulator.12" (and friends) to "twl_regulator.1".
+	 */
+	.driver.name	= "twl_reg",
+	.driver.owner	= THIS_MODULE,
+};
+
+static int __init twlreg_init(void)
+{
+	return platform_driver_register(&twlreg_driver);
+}
+subsys_initcall(twlreg_init);
+
+static void __exit twlreg_exit(void)
+{
+	platform_driver_unregister(&twlreg_driver);
+}
+module_exit(twlreg_exit)
+
+MODULE_DESCRIPTION("TWL regulator driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/wm831x-dcdc.c linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-dcdc.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/wm831x-dcdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-dcdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,8 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
@@ -39,6 +41,7 @@
 #define WM831X_DCDC_CONTROL_2     1
 #define WM831X_DCDC_ON_CONFIG     2
 #define WM831X_DCDC_SLEEP_CONTROL 3
+#define WM831X_DCDC_DVS_CONTROL   4
 
 /*
  * Shared
@@ -50,6 +53,10 @@ struct wm831x_dcdc {
 	int base;
 	struct wm831x *wm831x;
 	struct regulator_dev *regulator;
+	int dvs_gpio;
+	int dvs_gpio_state;
+	int on_vsel;
+	int dvs_vsel;
 };
 
 static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
@@ -240,11 +247,9 @@ static int wm831x_buckv_list_voltage(str
 	return -EINVAL;
 }
 
-static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
-					 int min_uV, int max_uV)
+static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev,
+					   int min_uV, int max_uV)
 {
-	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-	struct wm831x *wm831x = dcdc->wm831x;
 	u16 vsel;
 
 	if (min_uV < 600000)
@@ -257,39 +262,126 @@ static int wm831x_buckv_set_voltage_int(
 	if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
 		return -EINVAL;
 
-	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel);
+	return vsel;
+}
+
+static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev,
+					   int min_uV, int max_uV)
+{
+	u16 vsel;
+
+	if (max_uV < 600000 || max_uV > 1800000)
+		return -EINVAL;
+
+	vsel = ((max_uV - 600000) / 12500) + 8;
+
+	if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV ||
+	    wm831x_buckv_list_voltage(rdev, vsel) < max_uV)
+		return -EINVAL;
+
+	return vsel;
+}
+
+static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+
+	if (state == dcdc->dvs_gpio_state)
+		return 0;
+
+	dcdc->dvs_gpio_state = state;
+	gpio_set_value(dcdc->dvs_gpio, state);
+
+	/* Should wait for DVS state change to be asserted if we have
+	 * a GPIO for it, for now assume the device is configured
+	 * for the fastest possible transition.
+	 */
+
+	return 0;
 }
 
 static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
-				     int min_uV, int max_uV)
+				    int min_uV, int max_uV)
 {
 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+	struct wm831x *wm831x = dcdc->wm831x;
+	int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+	int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL;
+	int vsel, ret;
 
-	return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV);
+	vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV);
+	if (vsel < 0)
+		return vsel;
+
+	/* If this value is already set then do a GPIO update if we can */
+	if (dcdc->dvs_gpio && dcdc->on_vsel == vsel)
+		return wm831x_buckv_set_dvs(rdev, 0);
+
+	if (dcdc->dvs_gpio && dcdc->dvs_vsel == vsel)
+		return wm831x_buckv_set_dvs(rdev, 1);
+
+	/* Always set the ON status to the minimum voltage */
+	ret = wm831x_set_bits(wm831x, on_reg, WM831X_DC1_ON_VSEL_MASK, vsel);
+	if (ret < 0)
+		return ret;
+	dcdc->on_vsel = vsel;
+
+	if (!dcdc->dvs_gpio)
+		return ret;
+
+	/* Kick the voltage transition now */
+	ret = wm831x_buckv_set_dvs(rdev, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Set the high voltage as the DVS voltage.  This is optimised
+	 * for CPUfreq usage, most processors will keep the maximum
+	 * voltage constant and lower the minimum with the frequency. */
+	vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV);
+	if (vsel < 0) {
+		/* This should never happen - at worst the same vsel
+		 * should be chosen */
+		WARN_ON(vsel < 0);
+		return 0;
+	}
+
+	/* Don't bother if it's the same VSEL we're already using */
+	if (vsel == dcdc->on_vsel)
+		return 0;
+
+	ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel);
+	if (ret == 0)
+		dcdc->dvs_vsel = vsel;
+	else
+		dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n",
+			 ret);
+
+	return 0;
 }
 
 static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
-					     int uV)
+					    int uV)
 {
 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
 	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
+	int vsel;
 
-	return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV);
+	vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV);
+	if (vsel < 0)
+		return vsel;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel);
 }
 
 static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
 {
 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-	struct wm831x *wm831x = dcdc->wm831x;
-	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
-	int val;
 
-	val = wm831x_reg_read(wm831x, reg);
-	if (val < 0)
-		return val;
-
-	return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
+	if (dcdc->dvs_gpio && dcdc->dvs_gpio_state)
+		return wm831x_buckv_list_voltage(rdev, dcdc->dvs_vsel);
+	else
+		return wm831x_buckv_list_voltage(rdev, dcdc->on_vsel);
 }
 
 /* Current limit options */
@@ -346,6 +438,64 @@ static struct regulator_ops wm831x_buckv
 	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
 };
 
+/*
+ * Set up DVS control.  We just log errors since we can still run
+ * (with reduced performance) if we fail.
+ */
+static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
+					    struct wm831x_buckv_pdata *pdata)
+{
+	struct wm831x *wm831x = dcdc->wm831x;
+	int ret;
+	u16 ctrl;
+
+	if (!pdata || !pdata->dvs_gpio)
+		return;
+
+	switch (pdata->dvs_control_src) {
+	case 1:
+		ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
+		break;
+	case 2:
+		ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
+		break;
+	default:
+		dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
+			pdata->dvs_control_src, dcdc->name);
+		return;
+	}
+
+	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
+			      WM831X_DC1_DVS_SRC_MASK, ctrl);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
+			dcdc->name, ret);
+		return;
+	}
+
+	ret = gpio_request(pdata->dvs_gpio, "DCDC DVS");
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
+			dcdc->name, ret);
+		return;
+	}
+
+	/* gpiolib won't let us read the GPIO status so pick the higher
+	 * of the two existing voltages so we take it as platform data.
+	 */
+	dcdc->dvs_gpio_state = pdata->dvs_init_state;
+
+	ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n",
+			dcdc->name, ret);
+		gpio_free(pdata->dvs_gpio);
+		return;
+	}
+
+	dcdc->dvs_gpio = pdata->dvs_gpio;
+}
+
 static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -384,6 +534,23 @@ static __devinit int wm831x_buckv_probe(
 	dcdc->desc.ops = &wm831x_buckv_ops;
 	dcdc->desc.owner = THIS_MODULE;
 
+	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read ON VSEL: %d\n", ret);
+		goto err;
+	}
+	dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK;
+
+	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret);
+		goto err;
+	}
+	dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK;
+
+	if (pdata->dcdc[id])
+		wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
+
 	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
 					     pdata->dcdc[id], dcdc);
 	if (IS_ERR(dcdc->regulator)) {
@@ -422,6 +589,8 @@ err_uv:
 err_regulator:
 	regulator_unregister(dcdc->regulator);
 err:
+	if (dcdc->dvs_gpio)
+		gpio_free(dcdc->dvs_gpio);
 	kfree(dcdc);
 	return ret;
 }
@@ -434,6 +603,8 @@ static __devexit int wm831x_buckv_remove
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
 	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
 	regulator_unregister(dcdc->regulator);
+	if (dcdc->dvs_gpio)
+		gpio_free(dcdc->dvs_gpio);
 	kfree(dcdc);
 
 	return 0;
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/wm831x-ldo.c linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-ldo.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/wm831x-ldo.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/wm831x-ldo.c	2010-02-24 13:52:17.000000000 -0500
@@ -470,7 +470,7 @@ static unsigned int wm831x_aldo_get_mode
 	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
 	struct wm831x *wm831x = ldo->wm831x;
 	int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
-	unsigned int ret;
+	int ret;
 
 	ret = wm831x_reg_read(wm831x, on_reg);
 	if (ret < 0)
diff -druNp linux-libre-2.6.32-gnu1/drivers/regulator/wm8350-regulator.c linux-libre-2.6.33-gnu1/drivers/regulator/wm8350-regulator.c
--- linux-libre-2.6.32-gnu1/drivers/regulator/wm8350-regulator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/regulator/wm8350-regulator.c	2010-02-24 13:52:17.000000000 -0500
@@ -1330,9 +1330,10 @@ static struct regulator_desc wm8350_reg[
 	 },
 };
 
-static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
+static irqreturn_t pmic_uv_handler(int irq, void *data)
 {
 	struct regulator_dev *rdev = (struct regulator_dev *)data;
+	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
 
 	mutex_lock(&rdev->mutex);
 	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
@@ -1344,6 +1345,8 @@ static void pmic_uv_handler(struct wm835
 					      REGULATOR_EVENT_UNDER_VOLTAGE,
 					      wm8350);
 	mutex_unlock(&rdev->mutex);
+
+	return IRQ_HANDLED;
 }
 
 static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1388,7 +1391,7 @@ static int wm8350_regulator_probe(struct
 
 	/* register regulator IRQ */
 	ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,
-				  pmic_uv_handler, rdev);
+				  pmic_uv_handler, 0, "UV", rdev);
 	if (ret < 0) {
 		regulator_unregister(rdev);
 		dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",
@@ -1396,8 +1399,6 @@ static int wm8350_regulator_probe(struct
 		return ret;
 	}
 
-	wm8350_unmask_irq(wm8350, wm8350_reg[pdev->id].irq);
-
 	return 0;
 }
 
@@ -1406,7 +1407,6 @@ static int wm8350_regulator_remove(struc
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
 
-	wm8350_mask_irq(wm8350, wm8350_reg[pdev->id].irq);
 	wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq);
 
 	regulator_unregister(rdev);
@@ -1504,7 +1504,8 @@ int wm8350_register_led(struct wm8350 *w
 	led->isink_init.consumer_supplies = &led->isink_consumer;
 	led->isink_init.constraints.min_uA = 0;
 	led->isink_init.constraints.max_uA = pdata->max_uA;
-	led->isink_init.constraints.valid_ops_mask = REGULATOR_CHANGE_CURRENT;
+	led->isink_init.constraints.valid_ops_mask
+		= REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;
 	led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
 	ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);
 	if (ret != 0) {
@@ -1517,6 +1518,7 @@ int wm8350_register_led(struct wm8350 *w
 	led->dcdc_init.num_consumer_supplies = 1;
 	led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
 	led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+	led->dcdc_init.constraints.valid_ops_mask =  REGULATOR_CHANGE_STATUS;
 	ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);
 	if (ret != 0) {
 		platform_device_put(pdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/Kconfig linux-libre-2.6.33-gnu1/drivers/rtc/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/rtc/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -242,6 +242,15 @@ config RTC_DRV_M41T80_WDT
 	  If you say Y here you will get support for the
 	  watchdog timer in the ST M41T60 and M41T80 RTC chips series.
 
+config RTC_DRV_BQ32K
+	tristate "TI BQ32000"
+	help
+	  If you say Y here you will get support for the TI
+	  BQ32000 I2C RTC chip.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-bq32k.
+
 config RTC_DRV_DM355EVM
 	tristate "TI DaVinci DM355 EVM RTC"
 	depends on MFD_DM355EVM_MSP
@@ -258,14 +267,14 @@ config RTC_DRV_TWL92330
 	  the Menelaus driver; it's not separate module.
 
 config RTC_DRV_TWL4030
-	tristate "TI TWL4030/TWL5030/TPS659x0"
+	tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
 	depends on RTC_CLASS && TWL4030_CORE
 	help
 	  If you say yes here you get support for the RTC on the
-	  TWL4030 family chips, used mostly with OMAP3 platforms.
+	  TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms.
 
 	  This driver can also be built as a module. If so, the module
-	  will be called rtc-twl4030.
+	  will be called rtc-twl.
 
 config RTC_DRV_S35390A
 	tristate "Seiko Instruments S-35390A"
@@ -509,6 +518,15 @@ config RTC_DRV_M48T59
 	  This driver can also be built as a module, if so, the module
 	  will be called "rtc-m48t59".
 
+config RTC_DRV_MSM6242
+	tristate "Oki MSM6242"
+	help
+	  If you say yes here you get support for the Oki MSM6242
+	  timekeeping chip. It is used in some Amiga models (e.g. A2000).
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-msm6242.
+
 config RTC_MXC
 	tristate "Freescale MXC Real Time Clock"
 	depends on ARCH_MXC
@@ -529,6 +547,16 @@ config RTC_DRV_BQ4802
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-bq4802.
 
+config RTC_DRV_RP5C01
+	tristate "Ricoh RP5C01"
+	help
+	  If you say yes here you get support for the Ricoh RP5C01
+	  timekeeping chip. It is used in some Amiga models (e.g. A3000
+	  and A4000).
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rp5c01.
+
 config RTC_DRV_V3020
 	tristate "EM Microelectronic V3020"
 	help
@@ -573,15 +601,22 @@ config RTC_DRV_AB3100
 	  Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC
 	  support. This chip contains a battery- and capacitor-backed RTC.
 
+config RTC_DRV_NUC900
+	tristate "NUC910/NUC920 RTC driver"
+	depends on RTC_CLASS && ARCH_W90X900
+	help
+	  If you say yes here you get support for the RTC subsystem of the
+	  NUC910/NUC920 used in embedded systems.
 
 comment "on-CPU RTC drivers"
 
 config RTC_DRV_OMAP
 	tristate "TI OMAP1"
-	depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730
+	depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX
 	help
-	  Say "yes" here to support the real time clock on TI OMAP1 chips.
-	  This driver can also be built as a module called rtc-omap.
+	  Say "yes" here to support the real time clock on TI OMAP1 and
+	  DA8xx/OMAP-L13x chips.  This driver can also be built as a
+	  module called rtc-omap.
 
 config RTC_DRV_S3C
 	tristate "Samsung S3C series SoC RTC"
@@ -780,7 +815,7 @@ config RTC_DRV_TX4939
 
 config RTC_DRV_MV
 	tristate "Marvell SoC RTC"
-	depends on ARCH_KIRKWOOD
+	depends on ARCH_KIRKWOOD || ARCH_DOVE
 	help
 	  If you say yes here you will get support for the in-chip RTC
 	  that can be found in some of Marvell's SoC devices, such as
@@ -827,4 +862,10 @@ config RTC_DRV_PCAP
 	  If you say Y here you will get support for the RTC found on
 	  the PCAP2 ASIC used on some Motorola phones.
 
+config RTC_DRV_MC13783
+	depends on MFD_MC13783
+	tristate "Freescale MC13783 RTC"
+	help
+	  This enables support for the Freescale MC13783 PMIC RTC
+
 endif # RTC_CLASS
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/Makefile linux-libre-2.6.33-gnu1/drivers/rtc/Makefile
--- linux-libre-2.6.32-gnu1/drivers/rtc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-a
 obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
 obj-$(CONFIG_RTC_DRV_AU1XXX)	+= rtc-au1xxx.o
 obj-$(CONFIG_RTC_DRV_BFIN)	+= rtc-bfin.o
+obj-$(CONFIG_RTC_DRV_BQ32K)	+= rtc-bq32k.o
 obj-$(CONFIG_RTC_DRV_BQ4802)	+= rtc-bq4802.o
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)	+= rtc-coh901331.o
@@ -52,7 +53,10 @@ obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t
 obj-$(CONFIG_RTC_MXC)		+= rtc-mxc.o
 obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
 obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
+obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o
+obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
+obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc900.o
 obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
 obj-$(CONFIG_RTC_DRV_PCAP)	+= rtc-pcap.o
 obj-$(CONFIG_RTC_DRV_PCF8563)	+= rtc-pcf8563.o
@@ -64,6 +68,7 @@ obj-$(CONFIG_RTC_DRV_PL031)	+= rtc-pl031
 obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
 obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
+obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
 obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
 obj-$(CONFIG_RTC_DRV_RS5C372)	+= rtc-rs5c372.o
@@ -78,7 +83,7 @@ obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-st
 obj-$(CONFIG_RTC_DRV_STMP)	+= rtc-stmp3xxx.o
 obj-$(CONFIG_RTC_DRV_SUN4V)	+= rtc-sun4v.o
 obj-$(CONFIG_RTC_DRV_TEST)	+= rtc-test.o
-obj-$(CONFIG_RTC_DRV_TWL4030)	+= rtc-twl4030.o
+obj-$(CONFIG_RTC_DRV_TWL4030)	+= rtc-twl.o
 obj-$(CONFIG_RTC_DRV_TX4939)	+= rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-at32ap700x.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at32ap700x.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-at32ap700x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-at32ap700x.c	2010-02-24 13:52:17.000000000 -0500
@@ -256,6 +256,8 @@ static int __init at32_rtc_probe(struct
 		goto out_iounmap;
 	}
 
+	platform_set_drvdata(pdev, rtc);
+
 	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
 				&at32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc)) {
@@ -264,7 +266,6 @@ static int __init at32_rtc_probe(struct
 		goto out_free_irq;
 	}
 
-	platform_set_drvdata(pdev, rtc);
 	device_init_wakeup(&pdev->dev, 1);
 
 	dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n",
@@ -273,6 +274,7 @@ static int __init at32_rtc_probe(struct
 	return 0;
 
 out_free_irq:
+	platform_set_drvdata(pdev, NULL);
 	free_irq(irq, rtc);
 out_iounmap:
 	iounmap(rtc->regs);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-bq32k.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq32k.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-bq32k.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq32k.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,204 @@
+/*
+ * Driver for TI BQ32000 RTC.
+ *
+ * Copyright (C) 2009 Semihalf.
+ *
+ * This 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/i2c.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/bcd.h>
+
+#define BQ32K_SECONDS		0x00	/* Seconds register address */
+#define BQ32K_SECONDS_MASK	0x7F	/* Mask over seconds value */
+#define BQ32K_STOP		0x80	/* Oscillator Stop flat */
+
+#define BQ32K_MINUTES		0x01	/* Minutes register address */
+#define BQ32K_MINUTES_MASK	0x7F	/* Mask over minutes value */
+#define BQ32K_OF		0x80	/* Oscillator Failure flag */
+
+#define BQ32K_HOURS_MASK	0x3F	/* Mask over hours value */
+#define BQ32K_CENT		0x40	/* Century flag */
+#define BQ32K_CENT_EN		0x80	/* Century flag enable bit */
+
+struct bq32k_regs {
+	uint8_t		seconds;
+	uint8_t		minutes;
+	uint8_t		cent_hours;
+	uint8_t		day;
+	uint8_t		date;
+	uint8_t		month;
+	uint8_t		years;
+};
+
+static struct i2c_driver bq32k_driver;
+
+static int bq32k_read(struct device *dev, void *data, uint8_t off, uint8_t len)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &off,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = data,
+		}
+	};
+
+	if (i2c_transfer(client->adapter, msgs, 2) == 2)
+		return 0;
+
+	return -EIO;
+}
+
+static int bq32k_write(struct device *dev, void *data, uint8_t off, uint8_t len)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	uint8_t buffer[len + 1];
+
+	buffer[0] = off;
+	memcpy(&buffer[1], data, len);
+
+	if (i2c_master_send(client, buffer, len + 1) == len + 1)
+		return 0;
+
+	return -EIO;
+}
+
+static int bq32k_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct bq32k_regs regs;
+	int error;
+
+	error = bq32k_read(dev, &regs, 0, sizeof(regs));
+	if (error)
+		return error;
+
+	tm->tm_sec = bcd2bin(regs.seconds & BQ32K_SECONDS_MASK);
+	tm->tm_min = bcd2bin(regs.minutes & BQ32K_SECONDS_MASK);
+	tm->tm_hour = bcd2bin(regs.cent_hours & BQ32K_HOURS_MASK);
+	tm->tm_mday = bcd2bin(regs.date);
+	tm->tm_wday = bcd2bin(regs.day) - 1;
+	tm->tm_mon = bcd2bin(regs.month) - 1;
+	tm->tm_year = bcd2bin(regs.years) +
+				((regs.cent_hours & BQ32K_CENT) ? 100 : 0);
+
+	return rtc_valid_tm(tm);
+}
+
+static int bq32k_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct bq32k_regs regs;
+
+	regs.seconds = bin2bcd(tm->tm_sec);
+	regs.minutes = bin2bcd(tm->tm_min);
+	regs.cent_hours = bin2bcd(tm->tm_hour) | BQ32K_CENT_EN;
+	regs.day = bin2bcd(tm->tm_wday + 1);
+	regs.date = bin2bcd(tm->tm_mday);
+	regs.month = bin2bcd(tm->tm_mon + 1);
+
+	if (tm->tm_year >= 100) {
+		regs.cent_hours |= BQ32K_CENT;
+		regs.years = bin2bcd(tm->tm_year - 100);
+	} else
+		regs.years = bin2bcd(tm->tm_year);
+
+	return bq32k_write(dev, &regs, 0, sizeof(regs));
+}
+
+static const struct rtc_class_ops bq32k_rtc_ops = {
+	.read_time	= bq32k_rtc_read_time,
+	.set_time	= bq32k_rtc_set_time,
+};
+
+static int bq32k_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct rtc_device *rtc;
+	uint8_t reg;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	/* Check Oscillator Stop flag */
+	error = bq32k_read(dev, &reg, BQ32K_SECONDS, 1);
+	if (!error && (reg & BQ32K_STOP)) {
+		dev_warn(dev, "Oscillator was halted. Restarting...\n");
+		reg &= ~BQ32K_STOP;
+		error = bq32k_write(dev, &reg, BQ32K_SECONDS, 1);
+	}
+	if (error)
+		return error;
+
+	/* Check Oscillator Failure flag */
+	error = bq32k_read(dev, &reg, BQ32K_MINUTES, 1);
+	if (!error && (reg & BQ32K_OF)) {
+		dev_warn(dev, "Oscillator Failure. Check RTC battery.\n");
+		reg &= ~BQ32K_OF;
+		error = bq32k_write(dev, &reg, BQ32K_MINUTES, 1);
+	}
+	if (error)
+		return error;
+
+	rtc = rtc_device_register(bq32k_driver.driver.name, &client->dev,
+						&bq32k_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	i2c_set_clientdata(client, rtc);
+
+	return 0;
+}
+
+static int __devexit bq32k_remove(struct i2c_client *client)
+{
+	struct rtc_device *rtc = i2c_get_clientdata(client);
+
+	rtc_device_unregister(rtc);
+	return 0;
+}
+
+static const struct i2c_device_id bq32k_id[] = {
+	{ "bq32000", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bq32k_id);
+
+static struct i2c_driver bq32k_driver = {
+	.driver = {
+		.name	= "bq32k",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= bq32k_probe,
+	.remove		= __devexit_p(bq32k_remove),
+	.id_table	= bq32k_id,
+};
+
+static __init int bq32k_init(void)
+{
+	return i2c_add_driver(&bq32k_driver);
+}
+module_init(bq32k_init);
+
+static __exit void bq32k_exit(void)
+{
+	i2c_del_driver(&bq32k_driver);
+}
+module_exit(bq32k_exit);
+
+MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
+MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-bq4802.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq4802.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-bq4802.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-bq4802.c	2010-02-24 13:52:17.000000000 -0500
@@ -169,6 +169,8 @@ static int __devinit bq4802_probe(struct
 		goto out_free;
 	}
 
+	platform_set_drvdata(pdev, p);
+
 	p->rtc = rtc_device_register("bq4802", &pdev->dev,
 				     &bq4802_ops, THIS_MODULE);
 	if (IS_ERR(p->rtc)) {
@@ -176,7 +178,6 @@ static int __devinit bq4802_probe(struct
 		goto out_iounmap;
 	}
 
-	platform_set_drvdata(pdev, p);
 	err = 0;
 out:
 	return err;
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-cmos.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-cmos.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-cmos.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-cmos.c	2010-02-24 13:52:17.000000000 -0500
@@ -420,49 +420,43 @@ static int cmos_irq_set_state(struct dev
 	return 0;
 }
 
-#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
-
-static int
-cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
 	unsigned long	flags;
 
-	switch (cmd) {
-	case RTC_AIE_OFF:
-	case RTC_AIE_ON:
-	case RTC_UIE_OFF:
-	case RTC_UIE_ON:
-		if (!is_valid_irq(cmos->irq))
-			return -EINVAL;
-		break;
-	/* PIE ON/OFF is handled by cmos_irq_set_state() */
-	default:
-		return -ENOIOCTLCMD;
-	}
+	if (!is_valid_irq(cmos->irq))
+		return -EINVAL;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	switch (cmd) {
-	case RTC_AIE_OFF:	/* alarm off */
-		cmos_irq_disable(cmos, RTC_AIE);
-		break;
-	case RTC_AIE_ON:	/* alarm on */
+
+	if (enabled)
 		cmos_irq_enable(cmos, RTC_AIE);
-		break;
-	case RTC_UIE_OFF:	/* update off */
-		cmos_irq_disable(cmos, RTC_UIE);
-		break;
-	case RTC_UIE_ON:	/* update on */
-		cmos_irq_enable(cmos, RTC_UIE);
-		break;
-	}
+	else
+		cmos_irq_disable(cmos, RTC_AIE);
+
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return 0;
 }
 
-#else
-#define	cmos_rtc_ioctl	NULL
-#endif
+static int cmos_update_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+	unsigned long	flags;
+
+	if (!is_valid_irq(cmos->irq))
+		return -EINVAL;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+
+	if (enabled)
+		cmos_irq_enable(cmos, RTC_UIE);
+	else
+		cmos_irq_disable(cmos, RTC_UIE);
+
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	return 0;
+}
 
 #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
 
@@ -503,14 +497,15 @@ static int cmos_procfs(struct device *de
 #endif
 
 static const struct rtc_class_ops cmos_rtc_ops = {
-	.ioctl		= cmos_rtc_ioctl,
-	.read_time	= cmos_read_time,
-	.set_time	= cmos_set_time,
-	.read_alarm	= cmos_read_alarm,
-	.set_alarm	= cmos_set_alarm,
-	.proc		= cmos_procfs,
-	.irq_set_freq	= cmos_irq_set_freq,
-	.irq_set_state	= cmos_irq_set_state,
+	.read_time		= cmos_read_time,
+	.set_time		= cmos_set_time,
+	.read_alarm		= cmos_read_alarm,
+	.set_alarm		= cmos_set_alarm,
+	.proc			= cmos_procfs,
+	.irq_set_freq		= cmos_irq_set_freq,
+	.irq_set_state		= cmos_irq_set_state,
+	.alarm_irq_enable	= cmos_alarm_irq_enable,
+	.update_irq_enable	= cmos_update_irq_enable,
 };
 
 /*----------------------------------------------------------------*/
@@ -691,7 +686,8 @@ cmos_do_probe(struct device *dev, struct
 	 */
 #if	defined(CONFIG_ATARI)
 	address_space = 64;
-#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__sparc__)
+#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \
+			|| defined(__sparc__) || defined(__mips__)
 	address_space = 128;
 #else
 #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
@@ -871,8 +867,9 @@ static int cmos_suspend(struct device *d
 			mask = RTC_IRQMASK;
 		tmp &= ~mask;
 		CMOS_WRITE(tmp, RTC_CONTROL);
-		hpet_mask_rtc_irq_bit(mask);
 
+		/* shut down hpet emulation - we don't need it for alarm */
+		hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE);
 		cmos_checkintr(cmos, tmp);
 	}
 	spin_unlock_irq(&rtc_lock);
@@ -1099,9 +1096,9 @@ static int cmos_pnp_resume(struct pnp_de
 #define	cmos_pnp_resume		NULL
 #endif
 
-static void cmos_pnp_shutdown(struct device *pdev)
+static void cmos_pnp_shutdown(struct pnp_dev *pnp)
 {
-	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev))
+	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev))
 		return;
 
 	cmos_do_shutdown();
@@ -1120,15 +1117,12 @@ static struct pnp_driver cmos_pnp_driver
 	.id_table	= rtc_ids,
 	.probe		= cmos_pnp_probe,
 	.remove		= __exit_p(cmos_pnp_remove),
+	.shutdown	= cmos_pnp_shutdown,
 
 	/* flag ensures resume() gets called, and stops syslog spam */
 	.flags		= PNP_DRIVER_RES_DO_NOT_CHANGE,
 	.suspend	= cmos_pnp_suspend,
 	.resume		= cmos_pnp_resume,
-	.driver		= {
-		.name	  = (char *)driver_name,
-		.shutdown = cmos_pnp_shutdown,
-	}
 };
 
 #endif	/* CONFIG_PNP */
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1302.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1302.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1302.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1302.c	2010-02-24 13:52:17.000000000 -0500
@@ -143,7 +143,6 @@ static int ds1302_rtc_ioctl(struct devic
 #ifdef RTC_SET_CHARGE
 	case RTC_SET_CHARGE:
 	{
-		struct ds1302_rtc *rtc = dev_get_drvdata(dev);
 		int tcs_val;
 
 		if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
@@ -201,7 +200,7 @@ static struct platform_driver ds1302_pla
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(ds1302_rtc_remove),
+	.remove		= __devexit_p(ds1302_rtc_remove),
 };
 
 static int __init ds1302_rtc_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1305.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1305.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1305.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1305.c	2010-02-24 13:52:17.000000000 -0500
@@ -617,7 +617,6 @@ static struct bin_attribute nvram = {
 static int __devinit ds1305_probe(struct spi_device *spi)
 {
 	struct ds1305			*ds1305;
-	struct rtc_device		*rtc;
 	int				status;
 	u8				addr, value;
 	struct ds1305_platform_data	*pdata = spi->dev.platform_data;
@@ -756,14 +755,13 @@ static int __devinit ds1305_probe(struct
 		dev_dbg(&spi->dev, "AM/PM\n");
 
 	/* register RTC ... from here on, ds1305->ctrl needs locking */
-	rtc = rtc_device_register("ds1305", &spi->dev,
+	ds1305->rtc = rtc_device_register("ds1305", &spi->dev,
 			&ds1305_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		status = PTR_ERR(rtc);
+	if (IS_ERR(ds1305->rtc)) {
+		status = PTR_ERR(ds1305->rtc);
 		dev_dbg(&spi->dev, "register rtc --> %d\n", status);
 		goto fail0;
 	}
-	ds1305->rtc = rtc;
 
 	/* Maybe set up alarm IRQ; be ready to handle it triggering right
 	 * away.  NOTE that we don't share this.  The signal is active low,
@@ -774,12 +772,14 @@ static int __devinit ds1305_probe(struct
 	if (spi->irq) {
 		INIT_WORK(&ds1305->work, ds1305_work);
 		status = request_irq(spi->irq, ds1305_irq,
-				0, dev_name(&rtc->dev), ds1305);
+				0, dev_name(&ds1305->rtc->dev), ds1305);
 		if (status < 0) {
 			dev_dbg(&spi->dev, "request_irq %d --> %d\n",
 					spi->irq, status);
 			goto fail1;
 		}
+
+		device_set_wakeup_capable(&spi->dev, 1);
 	}
 
 	/* export NVRAM */
@@ -794,7 +794,7 @@ static int __devinit ds1305_probe(struct
 fail2:
 	free_irq(spi->irq, ds1305);
 fail1:
-	rtc_device_unregister(rtc);
+	rtc_device_unregister(ds1305->rtc);
 fail0:
 	kfree(ds1305);
 	return status;
@@ -802,7 +802,7 @@ fail0:
 
 static int __devexit ds1305_remove(struct spi_device *spi)
 {
-	struct ds1305	*ds1305 = spi_get_drvdata(spi);
+	struct ds1305 *ds1305 = spi_get_drvdata(spi);
 
 	sysfs_remove_bin_file(&spi->dev.kobj, &nvram);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1307.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1307.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1307.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1307.c	2010-02-24 13:52:17.000000000 -0500
@@ -874,13 +874,15 @@ read_rtc:
 	}
 
 	if (want_irq) {
-		err = request_irq(client->irq, ds1307_irq, 0,
+		err = request_irq(client->irq, ds1307_irq, IRQF_SHARED,
 			  ds1307->rtc->name, client);
 		if (err) {
 			dev_err(&client->dev,
 				"unable to request IRQ!\n");
 			goto exit_irq;
 		}
+
+		device_set_wakeup_capable(&client->dev, 1);
 		set_bit(HAS_ALARM, &ds1307->flags);
 		dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1374.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1374.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1374.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1374.c	2010-02-24 13:52:17.000000000 -0500
@@ -383,6 +383,8 @@ static int ds1374_probe(struct i2c_clien
 			dev_err(&client->dev, "unable to request IRQ\n");
 			goto out_free;
 		}
+
+		device_set_wakeup_capable(&client->dev, 1);
 	}
 
 	ds1374->rtc = rtc_device_register(client->name, &client->dev,
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1511.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1511.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1511.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1511.c	2010-02-24 13:52:17.000000000 -0500
@@ -2,7 +2,7 @@
  * An rtc driver for the Dallas DS1511
  *
  * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
- * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.com>
+ * Copyright (C) 2007 Andrew Sharp <andy.sharp@lsi.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
@@ -87,7 +87,6 @@ enum ds1511reg {
 struct rtc_plat_data {
 	struct rtc_device *rtc;
 	void __iomem *ioaddr;		/* virtual base address */
-	unsigned long baseaddr;		/* physical base address */
 	int size;				/* amount of memory mapped */
 	int irq;
 	unsigned int irqen;
@@ -95,6 +94,7 @@ struct rtc_plat_data {
 	int alrm_min;
 	int alrm_hour;
 	int alrm_mday;
+	spinlock_t lock;
 };
 
 static DEFINE_SPINLOCK(ds1511_lock);
@@ -302,7 +302,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
+	spin_lock_irqsave(&pdata->lock, flags);
 	rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
 	       0x80 : bin2bcd(pdata->alrm_mday) & 0x3f,
 	       RTC_ALARM_DATE);
@@ -317,7 +317,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_
 	       RTC_ALARM_SEC);
 	rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD);
 	rtc_read(RTC_CMD1);	/* clear interrupts */
-	spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
+	spin_unlock_irqrestore(&pdata->lock, flags);
 }
 
  static int
@@ -362,61 +362,63 @@ ds1511_interrupt(int irq, void *dev_id)
 {
 	struct platform_device *pdev = dev_id;
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-	unsigned long events = RTC_IRQF;
+	unsigned long events = 0;
 
+	spin_lock(&pdata->lock);
 	/*
 	 * read and clear interrupt
 	 */
-	if (!(rtc_read(RTC_CMD1) & DS1511_IRQF)) {
-		return IRQ_NONE;
-	}
-	if (rtc_read(RTC_ALARM_SEC) & 0x80) {
-		events |= RTC_UF;
-	} else {
-		events |= RTC_AF;
+	if (rtc_read(RTC_CMD1) & DS1511_IRQF) {
+		events = RTC_IRQF;
+		if (rtc_read(RTC_ALARM_SEC) & 0x80)
+			events |= RTC_UF;
+		else
+			events |= RTC_AF;
+		if (likely(pdata->rtc))
+			rtc_update_irq(pdata->rtc, 1, events);
 	}
-	rtc_update_irq(pdata->rtc, 1, events);
-	return IRQ_HANDLED;
+	spin_unlock(&pdata->lock);
+	return events ? IRQ_HANDLED : IRQ_NONE;
 }
 
- static int
-ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
-	if (pdata->irq <= 0) {
-		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
-	}
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		pdata->irqen &= ~RTC_AF;
-		ds1511_rtc_update_alarm(pdata);
-		break;
-	case RTC_AIE_ON:
+	if (pdata->irq <= 0)
+		return -EINVAL;
+	if (enabled)
 		pdata->irqen |= RTC_AF;
-		ds1511_rtc_update_alarm(pdata);
-		break;
-	case RTC_UIE_OFF:
-		pdata->irqen &= ~RTC_UF;
-		ds1511_rtc_update_alarm(pdata);
-		break;
-	case RTC_UIE_ON:
+	else
+		pdata->irqen &= ~RTC_AF;
+	ds1511_rtc_update_alarm(pdata);
+	return 0;
+}
+
+static int ds1511_rtc_update_irq_enable(struct device *dev,
+	unsigned int enabled)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq <= 0)
+		return -EINVAL;
+	if (enabled)
 		pdata->irqen |= RTC_UF;
-		ds1511_rtc_update_alarm(pdata);
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
+	else
+		pdata->irqen &= ~RTC_UF;
+	ds1511_rtc_update_alarm(pdata);
 	return 0;
 }
 
 static const struct rtc_class_ops ds1511_rtc_ops = {
-	.read_time	= ds1511_rtc_read_time,
-	.set_time	= ds1511_rtc_set_time,
-	.read_alarm	= ds1511_rtc_read_alarm,
-	.set_alarm	= ds1511_rtc_set_alarm,
-	.ioctl		= ds1511_rtc_ioctl,
+	.read_time		= ds1511_rtc_read_time,
+	.set_time		= ds1511_rtc_set_time,
+	.read_alarm		= ds1511_rtc_read_alarm,
+	.set_alarm		= ds1511_rtc_set_alarm,
+	.alarm_irq_enable	= ds1511_rtc_alarm_irq_enable,
+	.update_irq_enable	= ds1511_rtc_update_irq_enable,
 };
 
  static ssize_t
@@ -492,29 +494,23 @@ ds1511_rtc_probe(struct platform_device
 {
 	struct rtc_device *rtc;
 	struct resource *res;
-	struct rtc_plat_data *pdata = NULL;
+	struct rtc_plat_data *pdata;
 	int ret = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		return -ENODEV;
 	}
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
 		return -ENOMEM;
-	}
 	pdata->size = res->end - res->start + 1;
-	if (!request_mem_region(res->start, pdata->size, pdev->name)) {
-		ret = -EBUSY;
-		goto out;
-	}
-	pdata->baseaddr = res->start;
-	pdata->size = pdata->size;
-	ds1511_base = ioremap(pdata->baseaddr, pdata->size);
-	if (!ds1511_base) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devm_request_mem_region(&pdev->dev, res->start, pdata->size,
+			pdev->name))
+		return -EBUSY;
+	ds1511_base = devm_ioremap(&pdev->dev, res->start, pdata->size);
+	if (!ds1511_base)
+		return -ENOMEM;
 	pdata->ioaddr = ds1511_base;
 	pdata->irq = platform_get_irq(pdev, 0);
 
@@ -540,13 +536,15 @@ ds1511_rtc_probe(struct platform_device
 		dev_warn(&pdev->dev, "voltage-low detected.\n");
 	}
 
+	spin_lock_init(&pdata->lock);
+	platform_set_drvdata(pdev, pdata);
 	/*
 	 * if the platform has an interrupt in mind for this device,
 	 * then by all means, set it
 	 */
 	if (pdata->irq > 0) {
 		rtc_read(RTC_CMD1);
-		if (request_irq(pdata->irq, ds1511_interrupt,
+		if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
 			IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) {
 
 			dev_warn(&pdev->dev, "interrupt not available.\n");
@@ -556,33 +554,13 @@ ds1511_rtc_probe(struct platform_device
 
 	rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops,
 		THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 	pdata->rtc = rtc;
-	platform_set_drvdata(pdev, pdata);
+
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
-	if (ret) {
-		goto out;
-	}
-	return 0;
- out:
-	if (pdata->rtc) {
+	if (ret)
 		rtc_device_unregister(pdata->rtc);
-	}
-	if (pdata->irq > 0) {
-		free_irq(pdata->irq, pdev);
-	}
-	if (ds1511_base) {
-		iounmap(ds1511_base);
-		ds1511_base = NULL;
-	}
-	if (pdata->baseaddr) {
-		release_mem_region(pdata->baseaddr, pdata->size);
-	}
-
-	kfree(pdata);
 	return ret;
 }
 
@@ -593,19 +571,13 @@ ds1511_rtc_remove(struct platform_device
 
 	sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
 	rtc_device_unregister(pdata->rtc);
-	pdata->rtc = NULL;
 	if (pdata->irq > 0) {
 		/*
 		 * disable the alarm interrupt
 		 */
 		rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD);
 		rtc_read(RTC_CMD1);
-		free_irq(pdata->irq, pdev);
 	}
-	iounmap(pdata->ioaddr);
-	ds1511_base = NULL;
-	release_mem_region(pdata->baseaddr, pdata->size);
-	kfree(pdata);
 	return 0;
 }
 
@@ -636,7 +608,7 @@ ds1511_rtc_exit(void)
 module_init(ds1511_rtc_init);
 module_exit(ds1511_rtc_exit);
 
-MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>");
+MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
 MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1553.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1553.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1553.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1553.c	2010-02-24 13:52:17.000000000 -0500
@@ -18,7 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
 
 #define RTC_REG_SIZE		0x2000
 #define RTC_OFFSET		0x1ff0
@@ -61,7 +61,6 @@
 struct rtc_plat_data {
 	struct rtc_device *rtc;
 	void __iomem *ioaddr;
-	resource_size_t baseaddr;
 	unsigned long last_jiffies;
 	int irq;
 	unsigned int irqen;
@@ -69,6 +68,7 @@ struct rtc_plat_data {
 	int alrm_min;
 	int alrm_hour;
 	int alrm_mday;
+	spinlock_t lock;
 };
 
 static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -139,7 +139,7 @@ static void ds1553_rtc_update_alarm(stru
 	void __iomem *ioaddr = pdata->ioaddr;
 	unsigned long flags;
 
-	spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
+	spin_lock_irqsave(&pdata->lock, flags);
 	writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
 	       0x80 : bin2bcd(pdata->alrm_mday),
 	       ioaddr + RTC_DATE_ALARM);
@@ -154,7 +154,7 @@ static void ds1553_rtc_update_alarm(stru
 	       ioaddr + RTC_SECONDS_ALARM);
 	writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS);
 	readb(ioaddr + RTC_FLAGS);	/* clear interrupts */
-	spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
+	spin_unlock_irqrestore(&pdata->lock, flags);
 }
 
 static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -194,64 +194,69 @@ static irqreturn_t ds1553_rtc_interrupt(
 	struct platform_device *pdev = dev_id;
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
-	unsigned long events = RTC_IRQF;
+	unsigned long events = 0;
 
+	spin_lock(&pdata->lock);
 	/* read and clear interrupt */
-	if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF))
-		return IRQ_NONE;
-	if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
-		events |= RTC_UF;
-	else
-		events |= RTC_AF;
-	rtc_update_irq(pdata->rtc, 1, events);
-	return IRQ_HANDLED;
+	if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF) {
+		events = RTC_IRQF;
+		if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
+			events |= RTC_UF;
+		else
+			events |= RTC_AF;
+		if (likely(pdata->rtc))
+			rtc_update_irq(pdata->rtc, 1, events);
+	}
+	spin_unlock(&pdata->lock);
+	return events ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
-			    unsigned long arg)
+static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
 	if (pdata->irq <= 0)
-		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		pdata->irqen &= ~RTC_AF;
-		ds1553_rtc_update_alarm(pdata);
-		break;
-	case RTC_AIE_ON:
+		return -EINVAL;
+	if (enabled)
 		pdata->irqen |= RTC_AF;
-		ds1553_rtc_update_alarm(pdata);
-		break;
-	case RTC_UIE_OFF:
-		pdata->irqen &= ~RTC_UF;
-		ds1553_rtc_update_alarm(pdata);
-		break;
-	case RTC_UIE_ON:
+	else
+		pdata->irqen &= ~RTC_AF;
+	ds1553_rtc_update_alarm(pdata);
+	return 0;
+}
+
+static int ds1553_rtc_update_irq_enable(struct device *dev,
+	unsigned int enabled)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq <= 0)
+		return -EINVAL;
+	if (enabled)
 		pdata->irqen |= RTC_UF;
-		ds1553_rtc_update_alarm(pdata);
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
+	else
+		pdata->irqen &= ~RTC_UF;
+	ds1553_rtc_update_alarm(pdata);
 	return 0;
 }
 
 static const struct rtc_class_ops ds1553_rtc_ops = {
-	.read_time	= ds1553_rtc_read_time,
-	.set_time	= ds1553_rtc_set_time,
-	.read_alarm	= ds1553_rtc_read_alarm,
-	.set_alarm	= ds1553_rtc_set_alarm,
-	.ioctl		= ds1553_rtc_ioctl,
+	.read_time		= ds1553_rtc_read_time,
+	.set_time		= ds1553_rtc_set_time,
+	.read_alarm		= ds1553_rtc_read_alarm,
+	.set_alarm		= ds1553_rtc_set_alarm,
+	.alarm_irq_enable	= ds1553_rtc_alarm_irq_enable,
+	.update_irq_enable	= ds1553_rtc_update_irq_enable,
 };
 
 static ssize_t ds1553_nvram_read(struct kobject *kobj,
 				 struct bin_attribute *bin_attr,
 				 char *buf, loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 	ssize_t count;
@@ -265,8 +270,8 @@ static ssize_t ds1553_nvram_write(struct
 				  struct bin_attribute *bin_attr,
 				  char *buf, loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 	ssize_t count;
@@ -291,26 +296,23 @@ static int __devinit ds1553_rtc_probe(st
 	struct rtc_device *rtc;
 	struct resource *res;
 	unsigned int cen, sec;
-	struct rtc_plat_data *pdata = NULL;
-	void __iomem *ioaddr = NULL;
+	struct rtc_plat_data *pdata;
+	void __iomem *ioaddr;
 	int ret = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
-	if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
-		ret = -EBUSY;
-		goto out;
-	}
-	pdata->baseaddr = res->start;
-	ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
-	if (!ioaddr) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devm_request_mem_region(&pdev->dev, res->start, RTC_REG_SIZE,
+			pdev->name))
+		return -EBUSY;
+
+	ioaddr = devm_ioremap(&pdev->dev, res->start, RTC_REG_SIZE);
+	if (!ioaddr)
+		return -ENOMEM;
 	pdata->ioaddr = ioaddr;
 	pdata->irq = platform_get_irq(pdev, 0);
 
@@ -326,9 +328,13 @@ static int __devinit ds1553_rtc_probe(st
 	if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF)
 		dev_warn(&pdev->dev, "voltage-low detected.\n");
 
+	spin_lock_init(&pdata->lock);
+	pdata->last_jiffies = jiffies;
+	platform_set_drvdata(pdev, pdata);
 	if (pdata->irq > 0) {
 		writeb(0, ioaddr + RTC_INTERRUPTS);
-		if (request_irq(pdata->irq, ds1553_rtc_interrupt,
+		if (devm_request_irq(&pdev->dev, pdata->irq,
+				ds1553_rtc_interrupt,
 				IRQF_DISABLED, pdev->name, pdev) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = 0;
@@ -337,27 +343,13 @@ static int __devinit ds1553_rtc_probe(st
 
 	rtc = rtc_device_register(pdev->name, &pdev->dev,
 				  &ds1553_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 	pdata->rtc = rtc;
-	pdata->last_jiffies = jiffies;
-	platform_set_drvdata(pdev, pdata);
+
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
 	if (ret)
-		goto out;
-	return 0;
- out:
-	if (pdata->rtc)
-		rtc_device_unregister(pdata->rtc);
-	if (pdata->irq > 0)
-		free_irq(pdata->irq, pdev);
-	if (ioaddr)
-		iounmap(ioaddr);
-	if (pdata->baseaddr)
-		release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
-	kfree(pdata);
+		rtc_device_unregister(rtc);
 	return ret;
 }
 
@@ -367,13 +359,8 @@ static int __devexit ds1553_rtc_remove(s
 
 	sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
 	rtc_device_unregister(pdata->rtc);
-	if (pdata->irq > 0) {
+	if (pdata->irq > 0)
 		writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
-		free_irq(pdata->irq, pdev);
-	}
-	iounmap(pdata->ioaddr);
-	release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
-	kfree(pdata);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1742.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1742.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-ds1742.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-ds1742.c	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#define DRV_VERSION "0.3"
+#define DRV_VERSION "0.4"
 
 #define RTC_SIZE		8
 
@@ -55,7 +55,6 @@ struct rtc_plat_data {
 	void __iomem *ioaddr_rtc;
 	size_t size_nvram;
 	size_t size;
-	resource_size_t baseaddr;
 	unsigned long last_jiffies;
 	struct bin_attribute nvram_attr;
 };
@@ -132,8 +131,8 @@ static ssize_t ds1742_nvram_read(struct
 				 struct bin_attribute *bin_attr,
 				 char *buf, loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr_nvram;
 	ssize_t count;
@@ -147,8 +146,8 @@ static ssize_t ds1742_nvram_write(struct
 				  struct bin_attribute *bin_attr,
 				  char *buf, loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr_nvram;
 	ssize_t count;
@@ -163,27 +162,24 @@ static int __devinit ds1742_rtc_probe(st
 	struct rtc_device *rtc;
 	struct resource *res;
 	unsigned int cen, sec;
-	struct rtc_plat_data *pdata = NULL;
-	void __iomem *ioaddr = NULL;
+	struct rtc_plat_data *pdata;
+	void __iomem *ioaddr;
 	int ret = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 	pdata->size = res->end - res->start + 1;
-	if (!request_mem_region(res->start, pdata->size, pdev->name)) {
-		ret = -EBUSY;
-		goto out;
-	}
-	pdata->baseaddr = res->start;
-	ioaddr = ioremap(pdata->baseaddr, pdata->size);
-	if (!ioaddr) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devm_request_mem_region(&pdev->dev, res->start, pdata->size,
+		pdev->name))
+		return -EBUSY;
+	ioaddr = devm_ioremap(&pdev->dev, res->start, pdata->size);
+	if (!ioaddr)
+		return -ENOMEM;
+
 	pdata->ioaddr_nvram = ioaddr;
 	pdata->size_nvram = pdata->size - RTC_SIZE;
 	pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
@@ -207,31 +203,19 @@ static int __devinit ds1742_rtc_probe(st
 	if (!(readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG))
 		dev_warn(&pdev->dev, "voltage-low detected.\n");
 
+	pdata->last_jiffies = jiffies;
+	platform_set_drvdata(pdev, pdata);
 	rtc = rtc_device_register(pdev->name, &pdev->dev,
 				  &ds1742_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 	pdata->rtc = rtc;
-	pdata->last_jiffies = jiffies;
-	platform_set_drvdata(pdev, pdata);
 
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
 	if (ret) {
 		dev_err(&pdev->dev, "creating nvram file in sysfs failed\n");
-		goto out;
+		rtc_device_unregister(rtc);
 	}
-
-	return 0;
- out:
-	if (pdata->rtc)
-		rtc_device_unregister(pdata->rtc);
-	if (pdata->ioaddr_nvram)
-		iounmap(pdata->ioaddr_nvram);
-	if (pdata->baseaddr)
-		release_mem_region(pdata->baseaddr, pdata->size);
-	kfree(pdata);
 	return ret;
 }
 
@@ -241,9 +225,6 @@ static int __devexit ds1742_rtc_remove(s
 
 	sysfs_remove_bin_file(&pdev->dev.kobj, &pdata->nvram_attr);
 	rtc_device_unregister(pdata->rtc);
-	iounmap(pdata->ioaddr_nvram);
-	release_mem_region(pdata->baseaddr, pdata->size);
-	kfree(pdata);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-fm3130.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-fm3130.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-fm3130.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-fm3130.c	2010-02-24 13:52:17.000000000 -0500
@@ -376,20 +376,22 @@ static int __devinit fm3130_probe(struct
 	}
 
 	/* Disabling calibration mode */
-	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL)
+	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) {
 		i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
 			fm3130->regs[FM3130_RTC_CONTROL] &
 				~(FM3130_RTC_CONTROL_BIT_CAL));
 		dev_warn(&client->dev, "Disabling calibration mode!\n");
+	}
 
 	/* Disabling read and write modes */
 	if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE ||
-	    fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ)
+	    fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) {
 		i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL,
 			fm3130->regs[FM3130_RTC_CONTROL] &
 				~(FM3130_RTC_CONTROL_BIT_READ |
 					FM3130_RTC_CONTROL_BIT_WRITE));
 		dev_warn(&client->dev, "Disabling READ or WRITE mode!\n");
+	}
 
 	/* oscillator off?  turn it on, so clock can tick. */
 	if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN)
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-m48t35.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t35.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-m48t35.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t35.c	2010-02-24 13:52:17.000000000 -0500
@@ -142,7 +142,6 @@ static const struct rtc_class_ops m48t35
 
 static int __devinit m48t35_probe(struct platform_device *pdev)
 {
-	struct rtc_device *rtc;
 	struct resource *res;
 	struct m48t35_priv *priv;
 	int ret = 0;
@@ -171,20 +170,21 @@ static int __devinit m48t35_probe(struct
 		ret = -ENOMEM;
 		goto out;
 	}
+
 	spin_lock_init(&priv->lock);
-	rtc = rtc_device_register("m48t35", &pdev->dev,
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->rtc = rtc_device_register("m48t35", &pdev->dev,
 				  &m48t35_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
+	if (IS_ERR(priv->rtc)) {
+		ret = PTR_ERR(priv->rtc);
 		goto out;
 	}
-	priv->rtc = rtc;
-	platform_set_drvdata(pdev, priv);
+
 	return 0;
 
 out:
-	if (priv->rtc)
-		rtc_device_unregister(priv->rtc);
 	if (priv->reg)
 		iounmap(priv->reg);
 	if (priv->baseaddr)
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-m48t59.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t59.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-m48t59.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-m48t59.c	2010-02-24 13:52:17.000000000 -0500
@@ -481,6 +481,9 @@ static int __devinit m48t59_rtc_probe(st
 		goto out;
 	}
 
+	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);
@@ -490,16 +493,14 @@ static int __devinit m48t59_rtc_probe(st
 	m48t59_nvram_attr.size = pdata->offset;
 
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
-	if (ret)
+	if (ret) {
+		rtc_device_unregister(m48t59->rtc);
 		goto out;
+	}
 
-	spin_lock_init(&m48t59->lock);
-	platform_set_drvdata(pdev, m48t59);
 	return 0;
 
 out:
-	if (!IS_ERR(m48t59->rtc))
-		rtc_device_unregister(m48t59->rtc);
 	if (m48t59->irq != NO_IRQ)
 		free_irq(m48t59->irq, &pdev->dev);
 	if (m48t59->ioaddr)
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-mc13783.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mc13783.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-mc13783.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mc13783.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,262 @@
+/*
+ * Real Time Clock driver for Freescale MC13783 PMIC
+ *
+ * (C) 2009 Sascha Hauer, Pengutronix
+ * (C) 2009 Uwe Kleine-Koenig, 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.
+ */
+
+#include <linux/mfd/mc13783.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+
+#define DRIVER_NAME "mc13783-rtc"
+
+#define MC13783_RTCTOD	20
+#define MC13783_RTCTODA	21
+#define MC13783_RTCDAY	22
+#define MC13783_RTCDAYA	23
+
+struct mc13783_rtc {
+	struct rtc_device *rtc;
+	struct mc13783 *mc13783;
+	int valid;
+};
+
+static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	unsigned int seconds, days1, days2;
+	unsigned long s1970;
+	int ret;
+
+	mc13783_lock(priv->mc13783);
+
+	if (!priv->valid) {
+		ret = -ENODATA;
+		goto out;
+	}
+
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days1);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTOD, &seconds);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days2);
+out:
+	mc13783_unlock(priv->mc13783);
+
+	if (ret)
+		return ret;
+
+	if (days2 == days1 + 1) {
+		if (seconds >= 86400 / 2)
+			days2 = days1;
+		else
+			days1 = days2;
+	}
+
+	if (days1 != days2)
+		return -EIO;
+
+	s1970 = days1 * 86400 + seconds;
+
+	rtc_time_to_tm(s1970, tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	unsigned int seconds, days;
+	int ret;
+
+	seconds = secs % 86400;
+	days = secs / 86400;
+
+	mc13783_lock(priv->mc13783);
+
+	/*
+	 * first write seconds=0 to prevent a day switch between writing days
+	 * and seconds below
+	 */
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAY, days);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, seconds);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_ackirq(priv->mc13783, MC13783_IRQ_RTCRST);
+	if (unlikely(ret))
+		goto out;
+
+	ret = mc13783_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
+out:
+	priv->valid = !ret;
+
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
+{
+	struct mc13783_rtc *priv = dev;
+	struct mc13783 *mc13783 = priv->mc13783;
+
+	dev_dbg(&priv->rtc->dev, "1HZ\n");
+
+	rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
+
+	mc13783_ackirq(mc13783, irq);
+
+	return IRQ_HANDLED;
+}
+
+static int mc13783_rtc_update_irq_enable(struct device *dev,
+		unsigned int enabled)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	int ret = -ENODATA;
+
+	mc13783_lock(priv->mc13783);
+	if (!priv->valid)
+		goto out;
+
+	ret = (enabled ? mc13783_unmask : mc13783_mask)(priv->mc13783,
+			MC13783_IRQ_1HZ);
+out:
+	mc13783_unlock(priv->mc13783);
+
+	return ret;
+}
+
+static const struct rtc_class_ops mc13783_rtc_ops = {
+	.read_time = mc13783_rtc_read_time,
+	.set_mmss = mc13783_rtc_set_mmss,
+	.update_irq_enable = mc13783_rtc_update_irq_enable,
+};
+
+static irqreturn_t mc13783_rtc_reset_handler(int irq, void *dev)
+{
+	struct mc13783_rtc *priv = dev;
+	struct mc13783 *mc13783 = priv->mc13783;
+
+	dev_dbg(&priv->rtc->dev, "RTCRST\n");
+	priv->valid = 0;
+
+	mc13783_mask(mc13783, irq);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct mc13783_rtc *priv;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+	platform_set_drvdata(pdev, priv);
+
+	priv->valid = 1;
+
+	mc13783_lock(priv->mc13783);
+
+	ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
+			mc13783_rtc_reset_handler, DRIVER_NAME, priv);
+	if (ret)
+		goto err_reset_irq_request;
+
+	ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
+			mc13783_rtc_update_handler, DRIVER_NAME, priv);
+	if (ret)
+		goto err_update_irq_request;
+
+	mc13783_unlock(priv->mc13783);
+
+	priv->rtc = rtc_device_register(pdev->name,
+			&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(priv->rtc)) {
+		ret = PTR_ERR(priv->rtc);
+
+		mc13783_lock(priv->mc13783);
+
+		mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
+err_update_irq_request:
+
+		mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
+err_reset_irq_request:
+
+		mc13783_unlock(priv->mc13783);
+
+		platform_set_drvdata(pdev, NULL);
+		kfree(priv);
+	}
+
+	return ret;
+}
+
+static int __devexit mc13783_rtc_remove(struct platform_device *pdev)
+{
+	struct mc13783_rtc *priv = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(priv->rtc);
+
+	mc13783_lock(priv->mc13783);
+
+	mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
+	mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
+
+	mc13783_unlock(priv->mc13783);
+
+	platform_set_drvdata(pdev, NULL);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_rtc_driver = {
+	.remove = __devexit_p(mc13783_rtc_remove),
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mc13783_rtc_init(void)
+{
+	return platform_driver_probe(&mc13783_rtc_driver, &mc13783_rtc_probe);
+}
+module_init(mc13783_rtc_init);
+
+static void __exit mc13783_rtc_exit(void)
+{
+	platform_driver_unregister(&mc13783_rtc_driver);
+}
+module_exit(mc13783_rtc_exit);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-msm6242.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-msm6242.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-msm6242.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-msm6242.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,269 @@
+/*
+ *  Oki MSM6242 RTC Driver
+ *
+ *  Copyright 2009 Geert Uytterhoeven
+ *
+ *  Based on the A2000 TOD code in arch/m68k/amiga/config.c
+ *  Copyright (C) 1993 Hamish Macdonald
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+
+enum {
+	MSM6242_SECOND1		= 0x0,	/* 1-second digit register */
+	MSM6242_SECOND10	= 0x1,	/* 10-second digit register */
+	MSM6242_MINUTE1		= 0x2,	/* 1-minute digit register */
+	MSM6242_MINUTE10	= 0x3,	/* 10-minute digit register */
+	MSM6242_HOUR1		= 0x4,	/* 1-hour digit register */
+	MSM6242_HOUR10		= 0x5,	/* PM/AM, 10-hour digit register */
+	MSM6242_DAY1		= 0x6,	/* 1-day digit register */
+	MSM6242_DAY10		= 0x7,	/* 10-day digit register */
+	MSM6242_MONTH1		= 0x8,	/* 1-month digit register */
+	MSM6242_MONTH10		= 0x9,	/* 10-month digit register */
+	MSM6242_YEAR1		= 0xa,	/* 1-year digit register */
+	MSM6242_YEAR10		= 0xb,	/* 10-year digit register */
+	MSM6242_WEEK		= 0xc,	/* Week register */
+	MSM6242_CD		= 0xd,	/* Control Register D */
+	MSM6242_CE		= 0xe,	/* Control Register E */
+	MSM6242_CF		= 0xf,	/* Control Register F */
+};
+
+#define MSM6242_HOUR10_AM	(0 << 2)
+#define MSM6242_HOUR10_PM	(1 << 2)
+#define MSM6242_HOUR10_HR_MASK	(3 << 0)
+
+#define MSM6242_WEEK_SUNDAY	0
+#define MSM6242_WEEK_MONDAY	1
+#define MSM6242_WEEK_TUESDAY	2
+#define MSM6242_WEEK_WEDNESDAY	3
+#define MSM6242_WEEK_THURSDAY	4
+#define MSM6242_WEEK_FRIDAY	5
+#define MSM6242_WEEK_SATURDAY	6
+
+#define MSM6242_CD_30_S_ADJ	(1 << 3)	/* 30-second adjustment */
+#define MSM6242_CD_IRQ_FLAG	(1 << 2)
+#define MSM6242_CD_BUSY		(1 << 1)
+#define MSM6242_CD_HOLD		(1 << 0)
+
+#define MSM6242_CE_T_MASK	(3 << 2)
+#define MSM6242_CE_T_64HZ	(0 << 2)	/* period 1/64 second */
+#define MSM6242_CE_T_1HZ	(1 << 2)	/* period 1 second */
+#define MSM6242_CE_T_1MINUTE	(2 << 2)	/* period 1 minute */
+#define MSM6242_CE_T_1HOUR	(3 << 2)	/* period 1 hour */
+
+#define MSM6242_CE_ITRPT_STND	(1 << 1)
+#define MSM6242_CE_MASK		(1 << 0)	/* STD.P output control */
+
+#define MSM6242_CF_TEST		(1 << 3)
+#define MSM6242_CF_12H		(0 << 2)
+#define MSM6242_CF_24H		(1 << 2)
+#define MSM6242_CF_STOP		(1 << 1)
+#define MSM6242_CF_REST		(1 << 0)	/* reset */
+
+
+struct msm6242_priv {
+	u32 __iomem *regs;
+	struct rtc_device *rtc;
+};
+
+static inline unsigned int msm6242_read(struct msm6242_priv *priv,
+				       unsigned int reg)
+{
+	return __raw_readl(&priv->regs[reg]) & 0xf;
+}
+
+static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
+				unsigned int reg)
+{
+	return __raw_writel(val, &priv->regs[reg]);
+}
+
+static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
+			       unsigned int reg)
+{
+	msm6242_write(priv, msm6242_read(priv, reg) | val, reg);
+}
+
+static inline void msm6242_clear(struct msm6242_priv *priv, unsigned int val,
+				 unsigned int reg)
+{
+	msm6242_write(priv, msm6242_read(priv, reg) & ~val, reg);
+}
+
+static void msm6242_lock(struct msm6242_priv *priv)
+{
+	int cnt = 5;
+
+	msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+
+	while ((msm6242_read(priv, MSM6242_CD) & MSM6242_CD_BUSY) && cnt) {
+		msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+		udelay(70);
+		msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
+		cnt--;
+	}
+
+	if (!cnt)
+		pr_warning("msm6242: timed out waiting for RTC (0x%x)\n",
+			   msm6242_read(priv, MSM6242_CD));
+}
+
+static void msm6242_unlock(struct msm6242_priv *priv)
+{
+	msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
+}
+
+static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msm6242_priv *priv = dev_get_drvdata(dev);
+
+	msm6242_lock(priv);
+
+	tm->tm_sec  = msm6242_read(priv, MSM6242_SECOND10) * 10 +
+		      msm6242_read(priv, MSM6242_SECOND1);
+	tm->tm_min  = msm6242_read(priv, MSM6242_MINUTE10) * 10 +
+		      msm6242_read(priv, MSM6242_MINUTE1);
+	tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 +
+		      msm6242_read(priv, MSM6242_HOUR1);
+	tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 +
+		      msm6242_read(priv, MSM6242_DAY1);
+	tm->tm_wday = msm6242_read(priv, MSM6242_WEEK);
+	tm->tm_mon  = msm6242_read(priv, MSM6242_MONTH10) * 10 +
+		      msm6242_read(priv, MSM6242_MONTH1) - 1;
+	tm->tm_year = msm6242_read(priv, MSM6242_YEAR10) * 10 +
+		      msm6242_read(priv, MSM6242_YEAR1);
+	if (tm->tm_year <= 69)
+		tm->tm_year += 100;
+
+	if (!(msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)) {
+		unsigned int pm = msm6242_read(priv, MSM6242_HOUR10) &
+				  MSM6242_HOUR10_PM;
+		if (!pm && tm->tm_hour == 12)
+			tm->tm_hour = 0;
+		else if (pm && tm->tm_hour != 12)
+			tm->tm_hour += 12;
+	}
+
+	msm6242_unlock(priv);
+
+	return rtc_valid_tm(tm);
+}
+
+static int msm6242_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msm6242_priv *priv = dev_get_drvdata(dev);
+
+	msm6242_lock(priv);
+
+	msm6242_write(priv, tm->tm_sec / 10, MSM6242_SECOND10);
+	msm6242_write(priv, tm->tm_sec % 10, MSM6242_SECOND1);
+	msm6242_write(priv, tm->tm_min / 10, MSM6242_MINUTE10);
+	msm6242_write(priv, tm->tm_min % 10, MSM6242_MINUTE1);
+	if (msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)
+		msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
+	else if (tm->tm_hour >= 12)
+		msm6242_write(priv, MSM6242_HOUR10_PM + (tm->tm_hour - 12) / 10,
+			      MSM6242_HOUR10);
+	else
+		msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
+	msm6242_write(priv, tm->tm_hour % 10, MSM6242_HOUR1);
+	msm6242_write(priv, tm->tm_mday / 10, MSM6242_DAY10);
+	msm6242_write(priv, tm->tm_mday % 10, MSM6242_DAY1);
+	if (tm->tm_wday != -1)
+		msm6242_write(priv, tm->tm_wday, MSM6242_WEEK);
+	msm6242_write(priv, (tm->tm_mon + 1) / 10, MSM6242_MONTH10);
+	msm6242_write(priv, (tm->tm_mon + 1) % 10, MSM6242_MONTH1);
+	if (tm->tm_year >= 100)
+		tm->tm_year -= 100;
+	msm6242_write(priv, tm->tm_year / 10, MSM6242_YEAR10);
+	msm6242_write(priv, tm->tm_year % 10, MSM6242_YEAR1);
+
+	msm6242_unlock(priv);
+	return 0;
+}
+
+static const struct rtc_class_ops msm6242_rtc_ops = {
+	.read_time	= msm6242_read_time,
+	.set_time	= msm6242_set_time,
+};
+
+static int __init msm6242_rtc_probe(struct platform_device *dev)
+{
+	struct resource *res;
+	struct msm6242_priv *priv;
+	struct rtc_device *rtc;
+	int error;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->regs = ioremap(res->start, resource_size(res));
+	if (!priv->regs) {
+		error = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		error = PTR_ERR(rtc);
+		goto out_unmap;
+	}
+
+	priv->rtc = rtc;
+	platform_set_drvdata(dev, priv);
+	return 0;
+
+out_unmap:
+	iounmap(priv->regs);
+out_free_priv:
+	kfree(priv);
+	return error;
+}
+
+static int __exit msm6242_rtc_remove(struct platform_device *dev)
+{
+	struct msm6242_priv *priv = platform_get_drvdata(dev);
+
+	rtc_device_unregister(priv->rtc);
+	iounmap(priv->regs);
+	kfree(priv);
+	return 0;
+}
+
+static struct platform_driver msm6242_rtc_driver = {
+	.driver	= {
+		.name	= "rtc-msm6242",
+		.owner	= THIS_MODULE,
+	},
+	.remove	= __exit_p(msm6242_rtc_remove),
+};
+
+static int __init msm6242_rtc_init(void)
+{
+	return platform_driver_probe(&msm6242_rtc_driver, msm6242_rtc_probe);
+}
+
+static void __exit msm6242_rtc_fini(void)
+{
+	platform_driver_unregister(&msm6242_rtc_driver);
+}
+
+module_init(msm6242_rtc_init);
+module_exit(msm6242_rtc_fini);
+
+MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Oki MSM6242 RTC driver");
+MODULE_ALIAS("platform:rtc-msm6242");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-mv.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mv.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-mv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-mv.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,10 +27,17 @@
 #define RTC_MONTH_OFFS		8
 #define RTC_YEAR_OFFS		16
 
+#define RTC_ALARM_TIME_REG_OFFS	8
+#define RTC_ALARM_DATE_REG_OFFS	0xc
+#define RTC_ALARM_VALID		(1 << 7)
+
+#define RTC_ALARM_INTERRUPT_MASK_REG_OFFS	0x10
+#define RTC_ALARM_INTERRUPT_CASUE_REG_OFFS	0x14
 
 struct rtc_plat_data {
 	struct rtc_device *rtc;
 	void __iomem *ioaddr;
+	int		irq;
 };
 
 static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -84,12 +91,134 @@ static int mv_rtc_read_time(struct devic
 	return rtc_valid_tm(tm);
 }
 
+static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_plat_data *pdata = dev_get_drvdata(dev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	u32	rtc_time, rtc_date;
+	unsigned int year, month, day, hour, minute, second, wday;
+
+	rtc_time = readl(ioaddr + RTC_ALARM_TIME_REG_OFFS);
+	rtc_date = readl(ioaddr + RTC_ALARM_DATE_REG_OFFS);
+
+	second = rtc_time & 0x7f;
+	minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f;
+	hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hours mode */
+	wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7;
+
+	day = rtc_date & 0x3f;
+	month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f;
+	year = (rtc_date >> RTC_YEAR_OFFS) & 0xff;
+
+	alm->time.tm_sec = bcd2bin(second);
+	alm->time.tm_min = bcd2bin(minute);
+	alm->time.tm_hour = bcd2bin(hour);
+	alm->time.tm_mday = bcd2bin(day);
+	alm->time.tm_wday = bcd2bin(wday);
+	alm->time.tm_mon = bcd2bin(month) - 1;
+	/* hw counts from year 2000, but tm_year is relative to 1900 */
+	alm->time.tm_year = bcd2bin(year) + 100;
+
+	if (rtc_valid_tm(&alm->time) < 0) {
+		dev_err(dev, "retrieved alarm date/time is not valid.\n");
+		rtc_time_to_tm(0, &alm->time);
+	}
+
+	alm->enabled = !!readl(ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+	return 0;
+}
+
+static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_plat_data *pdata = dev_get_drvdata(dev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	u32 rtc_reg = 0;
+
+	if (alm->time.tm_sec >= 0)
+		rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_sec))
+			<< RTC_SECONDS_OFFS;
+	if (alm->time.tm_min >= 0)
+		rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_min))
+			<< RTC_MINUTES_OFFS;
+	if (alm->time.tm_hour >= 0)
+		rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_hour))
+			<< RTC_HOURS_OFFS;
+
+	writel(rtc_reg, ioaddr + RTC_ALARM_TIME_REG_OFFS);
+
+	if (alm->time.tm_mday >= 0)
+		rtc_reg = (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mday))
+			<< RTC_MDAY_OFFS;
+	else
+		rtc_reg = 0;
+
+	if (alm->time.tm_mon >= 0)
+		rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_mon + 1))
+			<< RTC_MONTH_OFFS;
+
+	if (alm->time.tm_year >= 0)
+		rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_year % 100))
+			<< RTC_YEAR_OFFS;
+
+	writel(rtc_reg, ioaddr + RTC_ALARM_DATE_REG_OFFS);
+	writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
+	writel(alm->enabled ? 1 : 0,
+	       ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+
+	return 0;
+}
+
+static int mv_rtc_ioctl(struct device *dev, unsigned int cmd,
+			unsigned long arg)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+
+	if (pdata->irq < 0)
+		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
+	switch (cmd) {
+	case RTC_AIE_OFF:
+		writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+		break;
+	case RTC_AIE_ON:
+		writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static irqreturn_t mv_rtc_interrupt(int irq, void *data)
+{
+	struct rtc_plat_data *pdata = data;
+	void __iomem *ioaddr = pdata->ioaddr;
+
+	/* alarm irq? */
+	if (!readl(ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS))
+		return IRQ_NONE;
+
+	/* clear interrupt */
+	writel(0, ioaddr + RTC_ALARM_INTERRUPT_CASUE_REG_OFFS);
+	rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
+	return IRQ_HANDLED;
+}
+
 static const struct rtc_class_ops mv_rtc_ops = {
 	.read_time	= mv_rtc_read_time,
 	.set_time	= mv_rtc_set_time,
 };
 
-static int __init mv_rtc_probe(struct platform_device *pdev)
+static const struct rtc_class_ops mv_rtc_alarm_ops = {
+	.read_time	= mv_rtc_read_time,
+	.set_time	= mv_rtc_set_time,
+	.read_alarm	= mv_rtc_read_alarm,
+	.set_alarm	= mv_rtc_set_alarm,
+	.ioctl		= mv_rtc_ioctl,
+};
+
+static int __devinit mv_rtc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct rtc_plat_data *pdata;
@@ -130,12 +259,31 @@ static int __init mv_rtc_probe(struct pl
 		}
 	}
 
+	pdata->irq = platform_get_irq(pdev, 0);
+
 	platform_set_drvdata(pdev, pdata);
-	pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
-					 &mv_rtc_ops, THIS_MODULE);
+
+	if (pdata->irq >= 0) {
+		device_init_wakeup(&pdev->dev, 1);
+		pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+						 &mv_rtc_alarm_ops,
+						 THIS_MODULE);
+	} else
+		pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+						 &mv_rtc_ops, THIS_MODULE);
 	if (IS_ERR(pdata->rtc))
 		return PTR_ERR(pdata->rtc);
 
+	if (pdata->irq >= 0) {
+		writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+		if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
+				     IRQF_DISABLED | IRQF_SHARED,
+				     pdev->name, pdata) < 0) {
+			dev_warn(&pdev->dev, "interrupt not available.\n");
+			pdata->irq = -1;
+		}
+	}
+
 	return 0;
 }
 
@@ -143,6 +291,9 @@ static int __exit mv_rtc_remove(struct p
 {
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
+	if (pdata->irq >= 0)
+		device_init_wakeup(&pdev->dev, 0);
+
 	rtc_device_unregister(pdata->rtc);
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-nuc900.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-nuc900.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-nuc900.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-nuc900.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2008-2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/bcd.h>
+
+/* RTC Control Registers */
+#define REG_RTC_INIR		0x00
+#define REG_RTC_AER		0x04
+#define REG_RTC_FCR		0x08
+#define REG_RTC_TLR		0x0C
+#define REG_RTC_CLR		0x10
+#define REG_RTC_TSSR		0x14
+#define REG_RTC_DWR		0x18
+#define REG_RTC_TAR		0x1C
+#define REG_RTC_CAR		0x20
+#define REG_RTC_LIR		0x24
+#define REG_RTC_RIER		0x28
+#define REG_RTC_RIIR		0x2C
+#define REG_RTC_TTR		0x30
+
+#define RTCSET			0x01
+#define AERRWENB		0x10000
+#define INIRRESET		0xa5eb1357
+#define AERPOWERON		0xA965
+#define AERPOWEROFF		0x0000
+#define LEAPYEAR		0x0001
+#define TICKENB			0x80
+#define TICKINTENB		0x0002
+#define ALARMINTENB		0x0001
+#define MODE24			0x0001
+
+struct nuc900_rtc {
+	int			irq_num;
+	void __iomem		*rtc_reg;
+	struct rtc_device	*rtcdev;
+};
+
+struct nuc900_bcd_time {
+	int bcd_sec;
+	int bcd_min;
+	int bcd_hour;
+	int bcd_mday;
+	int bcd_mon;
+	int bcd_year;
+};
+
+static irqreturn_t nuc900_rtc_interrupt(int irq, void *_rtc)
+{
+	struct nuc900_rtc *rtc = _rtc;
+	unsigned long events = 0, rtc_irq;
+
+	rtc_irq = __raw_readl(rtc->rtc_reg + REG_RTC_RIIR);
+
+	if (rtc_irq & ALARMINTENB) {
+		rtc_irq &= ~ALARMINTENB;
+		__raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR);
+		events |= RTC_AF | RTC_IRQF;
+	}
+
+	if (rtc_irq & TICKINTENB) {
+		rtc_irq &= ~TICKINTENB;
+		__raw_writel(rtc_irq, rtc->rtc_reg + REG_RTC_RIIR);
+		events |= RTC_UF | RTC_IRQF;
+	}
+
+	rtc_update_irq(rtc->rtcdev, 1, events);
+
+	return IRQ_HANDLED;
+}
+
+static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc)
+{
+	unsigned int i;
+	__raw_writel(INIRRESET, nuc900_rtc->rtc_reg + REG_RTC_INIR);
+
+	mdelay(10);
+
+	__raw_writel(AERPOWERON, nuc900_rtc->rtc_reg + REG_RTC_AER);
+
+	for (i = 0; i < 1000; i++) {
+		if (__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB)
+			return 0;
+	}
+
+	if ((__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_AER) & AERRWENB) == 0x0)
+		return ERR_PTR(-ENODEV);
+
+	return ERR_PTR(-EPERM);
+}
+
+static void nuc900_rtc_bcd2bin(unsigned int timereg,
+				unsigned int calreg, struct rtc_time *tm)
+{
+	tm->tm_mday	= bcd2bin(calreg >> 0);
+	tm->tm_mon	= bcd2bin(calreg >> 8);
+	tm->tm_year	= bcd2bin(calreg >> 16) + 100;
+
+	tm->tm_sec	= bcd2bin(timereg >> 0);
+	tm->tm_min	= bcd2bin(timereg >> 8);
+	tm->tm_hour	= bcd2bin(timereg >> 16);
+
+	rtc_valid_tm(tm);
+}
+
+static void nuc900_rtc_bin2bcd(struct rtc_time *settm,
+						struct nuc900_bcd_time *gettm)
+{
+	gettm->bcd_mday = bin2bcd(settm->tm_mday) << 0;
+	gettm->bcd_mon  = bin2bcd(settm->tm_mon) << 8;
+	gettm->bcd_year = bin2bcd(settm->tm_year - 100) << 16;
+
+	gettm->bcd_sec  = bin2bcd(settm->tm_sec) << 0;
+	gettm->bcd_min  = bin2bcd(settm->tm_min) << 8;
+	gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16;
+}
+
+static int nuc900_update_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+
+	if (enabled)
+		__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)|
+				(TICKINTENB), rtc->rtc_reg + REG_RTC_RIER);
+	else
+		__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)&
+				(~TICKINTENB), rtc->rtc_reg + REG_RTC_RIER);
+
+	return 0;
+}
+
+static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+
+	if (enabled)
+		__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)|
+				(ALARMINTENB), rtc->rtc_reg + REG_RTC_RIER);
+	else
+		__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)&
+				(~ALARMINTENB), rtc->rtc_reg + REG_RTC_RIER);
+
+	return 0;
+}
+
+static int nuc900_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+	unsigned int timeval, clrval;
+
+	timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR);
+	clrval	= __raw_readl(rtc->rtc_reg + REG_RTC_CLR);
+
+	nuc900_rtc_bcd2bin(timeval, clrval, tm);
+
+	return 0;
+}
+
+static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+	struct nuc900_bcd_time gettm;
+	unsigned long val;
+	int *err;
+
+	nuc900_rtc_bin2bcd(tm, &gettm);
+
+	err = check_rtc_access_enable(rtc);
+	if (IS_ERR(err))
+		return PTR_ERR(err);
+
+	val = gettm.bcd_mday | gettm.bcd_mon | gettm.bcd_year;
+	__raw_writel(val, rtc->rtc_reg + REG_RTC_CLR);
+
+	val = gettm.bcd_sec | gettm.bcd_min | gettm.bcd_hour;
+	__raw_writel(val, rtc->rtc_reg + REG_RTC_TLR);
+
+	return 0;
+}
+
+static int nuc900_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+	unsigned int timeval, carval;
+
+	timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR);
+	carval	= __raw_readl(rtc->rtc_reg + REG_RTC_CAR);
+
+	nuc900_rtc_bcd2bin(timeval, carval, &alrm->time);
+
+	return 0;
+}
+
+static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct nuc900_rtc *rtc = dev_get_drvdata(dev);
+	struct nuc900_bcd_time tm;
+	unsigned long val;
+	int *err;
+
+	nuc900_rtc_bin2bcd(&alrm->time, &tm);
+
+	err = check_rtc_access_enable(rtc);
+	if (IS_ERR(err))
+		return PTR_ERR(err);
+
+	val = tm.bcd_mday | tm.bcd_mon | tm.bcd_year;
+	__raw_writel(val, rtc->rtc_reg + REG_RTC_CAR);
+
+	val = tm.bcd_sec | tm.bcd_min | tm.bcd_hour;
+	__raw_writel(val, rtc->rtc_reg + REG_RTC_TAR);
+
+	return 0;
+}
+
+static struct rtc_class_ops nuc900_rtc_ops = {
+	.read_time = nuc900_rtc_read_time,
+	.set_time = nuc900_rtc_set_time,
+	.read_alarm = nuc900_rtc_read_alarm,
+	.set_alarm = nuc900_rtc_set_alarm,
+	.alarm_irq_enable = nuc900_alarm_irq_enable,
+	.update_irq_enable = nuc900_update_irq_enable,
+};
+
+static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct nuc900_rtc *nuc900_rtc;
+	int err = 0;
+
+	nuc900_rtc = kzalloc(sizeof(struct nuc900_rtc), GFP_KERNEL);
+	if (!nuc900_rtc) {
+		dev_err(&pdev->dev, "kzalloc nuc900_rtc failed\n");
+		return -ENOMEM;
+	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "platform_get_resource failed\n");
+		err = -ENXIO;
+		goto fail1;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res),
+				pdev->name)) {
+		dev_err(&pdev->dev, "request_mem_region failed\n");
+		err = -EBUSY;
+		goto fail1;
+	}
+
+	nuc900_rtc->rtc_reg = ioremap(res->start, resource_size(res));
+	if (!nuc900_rtc->rtc_reg) {
+		dev_err(&pdev->dev, "ioremap rtc_reg failed\n");
+		err = -ENOMEM;
+		goto fail2;
+	}
+
+	nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
+	if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
+				IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) {
+		dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
+		err = -EBUSY;
+		goto fail3;
+	}
+
+	nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev,
+						&nuc900_rtc_ops, THIS_MODULE);
+	if (IS_ERR(nuc900_rtc->rtcdev)) {
+		dev_err(&pdev->dev, "rtc device register faild\n");
+		err = PTR_ERR(nuc900_rtc->rtcdev);
+		goto fail4;
+	}
+
+	platform_set_drvdata(pdev, nuc900_rtc);
+	__raw_writel(__raw_readl(nuc900_rtc->rtc_reg + REG_RTC_TSSR) | MODE24,
+					nuc900_rtc->rtc_reg + REG_RTC_TSSR);
+
+	return 0;
+
+fail4:	free_irq(nuc900_rtc->irq_num, nuc900_rtc);
+fail3:	iounmap(nuc900_rtc->rtc_reg);
+fail2:	release_mem_region(res->start, resource_size(res));
+fail1:	kfree(nuc900_rtc);
+	return err;
+}
+
+static int __devexit nuc900_rtc_remove(struct platform_device *pdev)
+{
+	struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	rtc_device_unregister(nuc900_rtc->rtcdev);
+	free_irq(nuc900_rtc->irq_num, nuc900_rtc);
+	iounmap(nuc900_rtc->rtc_reg);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(nuc900_rtc);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver nuc900_rtc_driver = {
+	.remove		= __devexit_p(nuc900_rtc_remove),
+	.driver		= {
+		.name	= "nuc900-rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init nuc900_rtc_init(void)
+{
+	return platform_driver_probe(&nuc900_rtc_driver, nuc900_rtc_probe);
+}
+
+static void __exit nuc900_rtc_exit(void)
+{
+	platform_driver_unregister(&nuc900_rtc_driver);
+}
+
+module_init(nuc900_rtc_init);
+module_exit(nuc900_rtc_exit);
+
+MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
+MODULE_DESCRIPTION("nuc910/nuc920 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:nuc900-rtc");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-omap.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-omap.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-omap.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-omap.c	2010-02-24 13:52:17.000000000 -0500
@@ -87,9 +87,10 @@
 #define OMAP_RTC_INTERRUPTS_IT_ALARM    (1<<3)
 #define OMAP_RTC_INTERRUPTS_IT_TIMER    (1<<2)
 
+static void __iomem	*rtc_base;
 
-#define rtc_read(addr)		omap_readb(OMAP_RTC_BASE + (addr))
-#define rtc_write(val, addr)	omap_writeb(val, OMAP_RTC_BASE + (addr))
+#define rtc_read(addr)		__raw_readb(rtc_base + (addr))
+#define rtc_write(val, addr)	__raw_writeb(val, rtc_base + (addr))
 
 
 /* we rely on the rtc framework to handle locking (rtc->ops_lock),
@@ -330,32 +331,31 @@ static int __init omap_rtc_probe(struct
 		return -ENOENT;
 	}
 
-	/* NOTE:  using static mapping for RTC registers */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res && res->start != OMAP_RTC_BASE) {
-		pr_debug("%s: RTC registers at %08x, expected %08x\n",
-			pdev->name, (unsigned) res->start, OMAP_RTC_BASE);
+	if (!res) {
+		pr_debug("%s: RTC resource data missing\n", pdev->name);
 		return -ENOENT;
 	}
 
-	if (res)
-		mem = request_mem_region(res->start,
-				res->end - res->start + 1,
-				pdev->name);
-	else
-		mem = NULL;
+	mem = request_mem_region(res->start, resource_size(res), pdev->name);
 	if (!mem) {
 		pr_debug("%s: RTC registers at %08x are not free\n",
-			pdev->name, OMAP_RTC_BASE);
+			pdev->name, res->start);
 		return -EBUSY;
 	}
 
+	rtc_base = ioremap(res->start, resource_size(res));
+	if (!rtc_base) {
+		pr_debug("%s: RTC registers can't be mapped\n", pdev->name);
+		goto fail;
+	}
+
 	rtc = rtc_device_register(pdev->name, &pdev->dev,
 			&omap_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {
 		pr_debug("%s: can't register RTC device, err %ld\n",
 			pdev->name, PTR_ERR(rtc));
-		goto fail;
+		goto fail0;
 	}
 	platform_set_drvdata(pdev, rtc);
 	dev_set_drvdata(&rtc->dev, mem);
@@ -380,13 +380,14 @@ static int __init omap_rtc_probe(struct
 			dev_name(&rtc->dev), rtc)) {
 		pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_timer);
-		goto fail0;
+		goto fail1;
 	}
-	if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
-			dev_name(&rtc->dev), rtc)) {
+	if ((omap_rtc_timer != omap_rtc_alarm) &&
+		(request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
+			dev_name(&rtc->dev), rtc))) {
 		pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_alarm);
-		goto fail1;
+		goto fail2;
 	}
 
 	/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
@@ -419,10 +420,12 @@ static int __init omap_rtc_probe(struct
 
 	return 0;
 
-fail1:
+fail2:
 	free_irq(omap_rtc_timer, NULL);
-fail0:
+fail1:
 	rtc_device_unregister(rtc);
+fail0:
+	iounmap(rtc_base);
 fail:
 	release_resource(mem);
 	return -EIO;
@@ -438,7 +441,9 @@ static int __exit omap_rtc_remove(struct
 	rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 
 	free_irq(omap_rtc_timer, rtc);
-	free_irq(omap_rtc_alarm, rtc);
+
+	if (omap_rtc_timer != omap_rtc_alarm)
+		free_irq(omap_rtc_alarm, rtc);
 
 	release_resource(dev_get_drvdata(&rtc->dev));
 	rtc_device_unregister(rtc);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf50633.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf50633.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf50633.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf50633.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,6 +58,7 @@ struct pcf50633_time {
 struct pcf50633_rtc {
 	int alarm_enabled;
 	int second_enabled;
+	int alarm_pending;
 
 	struct pcf50633 *pcf;
 	struct rtc_device *rtc_dev;
@@ -209,6 +210,7 @@ static int pcf50633_rtc_read_alarm(struc
 	rtc = dev_get_drvdata(dev);
 
 	alrm->enabled = rtc->alarm_enabled;
+	alrm->pending = rtc->alarm_pending;
 
 	ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA,
 				PCF50633_TI_EXTENT, &pcf_tm.time[0]);
@@ -244,6 +246,8 @@ static int pcf50633_rtc_set_alarm(struct
 	/* Returns 0 on success */
 	ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
 				PCF50633_TI_EXTENT, &pcf_tm.time[0]);
+	if (!alrm->enabled)
+		rtc->alarm_pending = 0;
 
 	if (!alarm_masked || alrm->enabled)
 		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
@@ -268,6 +272,7 @@ static void pcf50633_rtc_irq(int irq, vo
 	switch (irq) {
 	case PCF50633_IRQ_ALARM:
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+		rtc->alarm_pending = 1;
 		break;
 	case PCF50633_IRQ_SECOND:
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
@@ -277,16 +282,13 @@ static void pcf50633_rtc_irq(int irq, vo
 
 static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
 {
-	struct pcf50633_subdev_pdata *pdata;
 	struct pcf50633_rtc *rtc;
 
-
 	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
 	if (!rtc)
 		return -ENOMEM;
 
-	pdata = pdev->dev.platform_data;
-	rtc->pcf = pdata->pcf;
+	rtc->pcf = dev_to_pcf50633(pdev->dev.parent);
 	platform_set_drvdata(pdev, rtc);
 	rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev,
 				&pcf50633_rtc_ops, THIS_MODULE);
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf8563.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8563.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf8563.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8563.c	2010-02-24 13:52:17.000000000 -0500
@@ -212,6 +212,8 @@ static int pcf8563_probe(struct i2c_clie
 
 	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
 
+	i2c_set_clientdata(client, pcf8563);
+
 	pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
 				&client->dev, &pcf8563_rtc_ops, THIS_MODULE);
 
@@ -220,8 +222,6 @@ static int pcf8563_probe(struct i2c_clie
 		goto exit_kfree;
 	}
 
-	i2c_set_clientdata(client, pcf8563);
-
 	return 0;
 
 exit_kfree:
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf8583.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8583.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pcf8583.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pcf8583.c	2010-02-24 13:52:17.000000000 -0500
@@ -277,6 +277,8 @@ static int pcf8583_probe(struct i2c_clie
 	if (!pcf8583)
 		return -ENOMEM;
 
+	i2c_set_clientdata(client, pcf8583);
+
 	pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name,
 			&client->dev, &pcf8583_rtc_ops, THIS_MODULE);
 
@@ -285,7 +287,6 @@ static int pcf8583_probe(struct i2c_clie
 		goto exit_kfree;
 	}
 
-	i2c_set_clientdata(client, pcf8583);
 	return 0;
 
 exit_kfree:
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pl031.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl031.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pl031.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pl031.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,10 +51,10 @@ static int pl031_ioctl(struct device *de
 
 	switch (cmd) {
 	case RTC_AIE_OFF:
-		__raw_writel(1, ldata->base + RTC_MIS);
+		writel(1, ldata->base + RTC_MIS);
 		return 0;
 	case RTC_AIE_ON:
-		__raw_writel(0, ldata->base + RTC_MIS);
+		writel(0, ldata->base + RTC_MIS);
 		return 0;
 	}
 
@@ -65,7 +65,7 @@ static int pl031_read_time(struct device
 {
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 
-	rtc_time_to_tm(__raw_readl(ldata->base + RTC_DR), tm);
+	rtc_time_to_tm(readl(ldata->base + RTC_DR), tm);
 
 	return 0;
 }
@@ -76,7 +76,7 @@ static int pl031_set_time(struct device
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 
 	rtc_tm_to_time(tm, &time);
-	__raw_writel(time, ldata->base + RTC_LR);
+	writel(time, ldata->base + RTC_LR);
 
 	return 0;
 }
@@ -85,9 +85,9 @@ static int pl031_read_alarm(struct devic
 {
 	struct pl031_local *ldata = dev_get_drvdata(dev);
 
-	rtc_time_to_tm(__raw_readl(ldata->base + RTC_MR), &alarm->time);
-	alarm->pending = __raw_readl(ldata->base + RTC_RIS);
-	alarm->enabled = __raw_readl(ldata->base + RTC_IMSC);
+	rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time);
+	alarm->pending = readl(ldata->base + RTC_RIS);
+	alarm->enabled = readl(ldata->base + RTC_IMSC);
 
 	return 0;
 }
@@ -99,8 +99,8 @@ static int pl031_set_alarm(struct device
 
 	rtc_tm_to_time(&alarm->time, &time);
 
-	__raw_writel(time, ldata->base + RTC_MR);
-	__raw_writel(!alarm->enabled, ldata->base + RTC_MIS);
+	writel(time, ldata->base + RTC_MR);
+	writel(!alarm->enabled, ldata->base + RTC_MIS);
 
 	return 0;
 }
@@ -180,8 +180,9 @@ err_req:
 
 static struct amba_id pl031_ids[] __initdata = {
 	{
-		 .id = 0x00041031,
-	 	.mask = 0x000fffff, },
+		.id = 0x00041031,
+		.mask = 0x000fffff,
+	},
 	{0, 0},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pxa.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pxa.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-pxa.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-pxa.c	2010-02-24 13:52:17.000000000 -0500
@@ -456,7 +456,7 @@ static int pxa_rtc_resume(struct device
 	return 0;
 }
 
-static struct dev_pm_ops pxa_rtc_pm_ops = {
+static const struct dev_pm_ops pxa_rtc_pm_ops = {
 	.suspend	= pxa_rtc_suspend,
 	.resume		= pxa_rtc_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-rp5c01.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rp5c01.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-rp5c01.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-rp5c01.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,222 @@
+/*
+ *  Ricoh RP5C01 RTC Driver
+ *
+ *  Copyright 2009 Geert Uytterhoeven
+ *
+ *  Based on the A3000 TOD code in arch/m68k/amiga/config.c
+ *  Copyright (C) 1993 Hamish Macdonald
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+
+enum {
+	RP5C01_1_SECOND		= 0x0,	/* MODE 00 */
+	RP5C01_10_SECOND	= 0x1,	/* MODE 00 */
+	RP5C01_1_MINUTE		= 0x2,	/* MODE 00 and MODE 01 */
+	RP5C01_10_MINUTE	= 0x3,	/* MODE 00 and MODE 01 */
+	RP5C01_1_HOUR		= 0x4,	/* MODE 00 and MODE 01 */
+	RP5C01_10_HOUR		= 0x5,	/* MODE 00 and MODE 01 */
+	RP5C01_DAY_OF_WEEK	= 0x6,	/* MODE 00 and MODE 01 */
+	RP5C01_1_DAY		= 0x7,	/* MODE 00 and MODE 01 */
+	RP5C01_10_DAY		= 0x8,	/* MODE 00 and MODE 01 */
+	RP5C01_1_MONTH		= 0x9,	/* MODE 00 */
+	RP5C01_10_MONTH		= 0xa,	/* MODE 00 */
+	RP5C01_1_YEAR		= 0xb,	/* MODE 00 */
+	RP5C01_10_YEAR		= 0xc,	/* MODE 00 */
+
+	RP5C01_12_24_SELECT	= 0xa,	/* MODE 01 */
+	RP5C01_LEAP_YEAR	= 0xb,	/* MODE 01 */
+
+	RP5C01_MODE		= 0xd,	/* all modes */
+	RP5C01_TEST		= 0xe,	/* all modes */
+	RP5C01_RESET		= 0xf,	/* all modes */
+};
+
+#define RP5C01_12_24_SELECT_12	(0 << 0)
+#define RP5C01_12_24_SELECT_24	(1 << 0)
+
+#define RP5C01_10_HOUR_AM	(0 << 1)
+#define RP5C01_10_HOUR_PM	(1 << 1)
+
+#define RP5C01_MODE_TIMER_EN	(1 << 3)	/* timer enable */
+#define RP5C01_MODE_ALARM_EN	(1 << 2)	/* alarm enable */
+
+#define RP5C01_MODE_MODE_MASK	(3 << 0)
+#define RP5C01_MODE_MODE00	(0 << 0)	/* time */
+#define RP5C01_MODE_MODE01	(1 << 0)	/* alarm, 12h/24h, leap year */
+#define RP5C01_MODE_RAM_BLOCK10	(2 << 0)	/* RAM 4 bits x 13 */
+#define RP5C01_MODE_RAM_BLOCK11	(3 << 0)	/* RAM 4 bits x 13 */
+
+#define RP5C01_RESET_1HZ_PULSE	(1 << 3)
+#define RP5C01_RESET_16HZ_PULSE	(1 << 2)
+#define RP5C01_RESET_SECOND	(1 << 1)	/* reset divider stages for */
+						/* seconds or smaller units */
+#define RP5C01_RESET_ALARM	(1 << 0)	/* reset all alarm registers */
+
+
+struct rp5c01_priv {
+	u32 __iomem *regs;
+	struct rtc_device *rtc;
+};
+
+static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
+				       unsigned int reg)
+{
+	return __raw_readl(&priv->regs[reg]) & 0xf;
+}
+
+static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
+				unsigned int reg)
+{
+	return __raw_writel(val, &priv->regs[reg]);
+}
+
+static void rp5c01_lock(struct rp5c01_priv *priv)
+{
+	rp5c01_write(priv, RP5C01_MODE_MODE00, RP5C01_MODE);
+}
+
+static void rp5c01_unlock(struct rp5c01_priv *priv)
+{
+	rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01,
+		     RP5C01_MODE);
+}
+
+static int rp5c01_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rp5c01_priv *priv = dev_get_drvdata(dev);
+
+	rp5c01_lock(priv);
+
+	tm->tm_sec  = rp5c01_read(priv, RP5C01_10_SECOND) * 10 +
+		      rp5c01_read(priv, RP5C01_1_SECOND);
+	tm->tm_min  = rp5c01_read(priv, RP5C01_10_MINUTE) * 10 +
+		      rp5c01_read(priv, RP5C01_1_MINUTE);
+	tm->tm_hour = rp5c01_read(priv, RP5C01_10_HOUR) * 10 +
+		      rp5c01_read(priv, RP5C01_1_HOUR);
+	tm->tm_mday = rp5c01_read(priv, RP5C01_10_DAY) * 10 +
+		      rp5c01_read(priv, RP5C01_1_DAY);
+	tm->tm_wday = rp5c01_read(priv, RP5C01_DAY_OF_WEEK);
+	tm->tm_mon  = rp5c01_read(priv, RP5C01_10_MONTH) * 10 +
+		      rp5c01_read(priv, RP5C01_1_MONTH) - 1;
+	tm->tm_year = rp5c01_read(priv, RP5C01_10_YEAR) * 10 +
+		      rp5c01_read(priv, RP5C01_1_YEAR);
+	if (tm->tm_year <= 69)
+		tm->tm_year += 100;
+
+	rp5c01_unlock(priv);
+
+	return rtc_valid_tm(tm);
+}
+
+static int rp5c01_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rp5c01_priv *priv = dev_get_drvdata(dev);
+
+	rp5c01_lock(priv);
+
+	rp5c01_write(priv, tm->tm_sec / 10, RP5C01_10_SECOND);
+	rp5c01_write(priv, tm->tm_sec % 10, RP5C01_1_SECOND);
+	rp5c01_write(priv, tm->tm_min / 10, RP5C01_10_MINUTE);
+	rp5c01_write(priv, tm->tm_min % 10, RP5C01_1_MINUTE);
+	rp5c01_write(priv, tm->tm_hour / 10, RP5C01_10_HOUR);
+	rp5c01_write(priv, tm->tm_hour % 10, RP5C01_1_HOUR);
+	rp5c01_write(priv, tm->tm_mday / 10, RP5C01_10_DAY);
+	rp5c01_write(priv, tm->tm_mday % 10, RP5C01_1_DAY);
+	if (tm->tm_wday != -1)
+		rp5c01_write(priv, tm->tm_wday, RP5C01_DAY_OF_WEEK);
+	rp5c01_write(priv, (tm->tm_mon + 1) / 10, RP5C01_10_MONTH);
+	rp5c01_write(priv, (tm->tm_mon + 1) % 10, RP5C01_1_MONTH);
+	if (tm->tm_year >= 100)
+		tm->tm_year -= 100;
+	rp5c01_write(priv, tm->tm_year / 10, RP5C01_10_YEAR);
+	rp5c01_write(priv, tm->tm_year % 10, RP5C01_1_YEAR);
+
+	rp5c01_unlock(priv);
+	return 0;
+}
+
+static const struct rtc_class_ops rp5c01_rtc_ops = {
+	.read_time	= rp5c01_read_time,
+	.set_time	= rp5c01_set_time,
+};
+
+static int __init rp5c01_rtc_probe(struct platform_device *dev)
+{
+	struct resource *res;
+	struct rp5c01_priv *priv;
+	struct rtc_device *rtc;
+	int error;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->regs = ioremap(res->start, resource_size(res));
+	if (!priv->regs) {
+		error = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		error = PTR_ERR(rtc);
+		goto out_unmap;
+	}
+
+	priv->rtc = rtc;
+	platform_set_drvdata(dev, priv);
+	return 0;
+
+out_unmap:
+	iounmap(priv->regs);
+out_free_priv:
+	kfree(priv);
+	return error;
+}
+
+static int __exit rp5c01_rtc_remove(struct platform_device *dev)
+{
+	struct rp5c01_priv *priv = platform_get_drvdata(dev);
+
+	rtc_device_unregister(priv->rtc);
+	iounmap(priv->regs);
+	kfree(priv);
+	return 0;
+}
+
+static struct platform_driver rp5c01_rtc_driver = {
+	.driver	= {
+		.name	= "rtc-rp5c01",
+		.owner	= THIS_MODULE,
+	},
+	.remove	= __exit_p(rp5c01_rtc_remove),
+};
+
+static int __init rp5c01_rtc_init(void)
+{
+	return platform_driver_probe(&rp5c01_rtc_driver, rp5c01_rtc_probe);
+}
+
+static void __exit rp5c01_rtc_fini(void)
+{
+	platform_driver_unregister(&rp5c01_rtc_driver);
+}
+
+module_init(rp5c01_rtc_init);
+module_exit(rp5c01_rtc_fini);
+
+MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ricoh RP5C01 RTC driver");
+MODULE_ALIAS("platform:rtc-rp5c01");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-sa1100.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sa1100.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-sa1100.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sa1100.c	2010-02-24 13:52:17.000000000 -0500
@@ -407,7 +407,7 @@ static int sa1100_rtc_resume(struct devi
 	return 0;
 }
 
-static struct dev_pm_ops sa1100_rtc_pm_ops = {
+static const struct dev_pm_ops sa1100_rtc_pm_ops = {
 	.suspend	= sa1100_rtc_suspend,
 	.resume		= sa1100_rtc_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-sh.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sh.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-sh.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-sh.c	2010-02-24 13:52:17.000000000 -0500
@@ -826,7 +826,7 @@ static int sh_rtc_resume(struct device *
 	return 0;
 }
 
-static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+static const struct dev_pm_ops sh_rtc_dev_pm_ops = {
 	.suspend = sh_rtc_suspend,
 	.resume = sh_rtc_resume,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-stk17ta8.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stk17ta8.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-stk17ta8.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-stk17ta8.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,7 +62,6 @@
 struct rtc_plat_data {
 	struct rtc_device *rtc;
 	void __iomem *ioaddr;
-	unsigned long baseaddr;
 	unsigned long last_jiffies;
 	int irq;
 	unsigned int irqen;
@@ -70,6 +69,7 @@ struct rtc_plat_data {
 	int alrm_min;
 	int alrm_hour;
 	int alrm_mday;
+	spinlock_t lock;
 };
 
 static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -142,7 +142,7 @@ static void stk17ta8_rtc_update_alarm(st
 	unsigned long irqflags;
 	u8 flags;
 
-	spin_lock_irqsave(&pdata->rtc->irq_lock, irqflags);
+	spin_lock_irqsave(&pdata->lock, irqflags);
 
 	flags = readb(ioaddr + RTC_FLAGS);
 	writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
@@ -162,7 +162,7 @@ static void stk17ta8_rtc_update_alarm(st
 	writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS);
 	readb(ioaddr + RTC_FLAGS);	/* clear interrupts */
 	writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS);
-	spin_unlock_irqrestore(&pdata->rtc->irq_lock, irqflags);
+	spin_unlock_irqrestore(&pdata->lock, irqflags);
 }
 
 static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -202,56 +202,53 @@ static irqreturn_t stk17ta8_rtc_interrup
 	struct platform_device *pdev = dev_id;
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
-	unsigned long events = RTC_IRQF;
+	unsigned long events = 0;
 
+	spin_lock(&pdata->lock);
 	/* read and clear interrupt */
-	if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF))
-		return IRQ_NONE;
-	if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
-		events |= RTC_UF;
-	else
-		events |= RTC_AF;
-	rtc_update_irq(pdata->rtc, 1, events);
-	return IRQ_HANDLED;
+	if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF) {
+		events = RTC_IRQF;
+		if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
+			events |= RTC_UF;
+		else
+			events |= RTC_AF;
+		if (likely(pdata->rtc))
+			rtc_update_irq(pdata->rtc, 1, events);
+	}
+	spin_unlock(&pdata->lock);
+	return events ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd,
-			    unsigned long arg)
+static int stk17ta8_rtc_alarm_irq_enable(struct device *dev,
+	unsigned int enabled)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
 	if (pdata->irq <= 0)
-		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		pdata->irqen &= ~RTC_AF;
-		stk17ta8_rtc_update_alarm(pdata);
-		break;
-	case RTC_AIE_ON:
+		return -EINVAL;
+	if (enabled)
 		pdata->irqen |= RTC_AF;
-		stk17ta8_rtc_update_alarm(pdata);
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
+	else
+		pdata->irqen &= ~RTC_AF;
+	stk17ta8_rtc_update_alarm(pdata);
 	return 0;
 }
 
 static const struct rtc_class_ops stk17ta8_rtc_ops = {
-	.read_time	= stk17ta8_rtc_read_time,
-	.set_time	= stk17ta8_rtc_set_time,
-	.read_alarm	= stk17ta8_rtc_read_alarm,
-	.set_alarm	= stk17ta8_rtc_set_alarm,
-	.ioctl		= stk17ta8_rtc_ioctl,
+	.read_time		= stk17ta8_rtc_read_time,
+	.set_time		= stk17ta8_rtc_set_time,
+	.read_alarm		= stk17ta8_rtc_read_alarm,
+	.set_alarm		= stk17ta8_rtc_set_alarm,
+	.alarm_irq_enable	= stk17ta8_rtc_alarm_irq_enable,
 };
 
 static ssize_t stk17ta8_nvram_read(struct kobject *kobj,
 				 struct bin_attribute *attr, char *buf,
 				 loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 	ssize_t count;
@@ -265,8 +262,8 @@ static ssize_t stk17ta8_nvram_write(stru
 				  struct bin_attribute *attr, char *buf,
 				  loff_t pos, size_t size)
 {
-	struct platform_device *pdev =
-		to_platform_device(container_of(kobj, struct device, kobj));
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 	ssize_t count;
@@ -286,33 +283,28 @@ static struct bin_attribute stk17ta8_nvr
 	.write = stk17ta8_nvram_write,
 };
 
-static int __init stk17ta8_rtc_probe(struct platform_device *pdev)
+static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
 {
-	struct rtc_device *rtc;
 	struct resource *res;
 	unsigned int cal;
 	unsigned int flags;
 	struct rtc_plat_data *pdata;
-	void __iomem *ioaddr = NULL;
+	void __iomem *ioaddr;
 	int ret = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
 
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
-	if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
-		ret = -EBUSY;
-		goto out;
-	}
-	pdata->baseaddr = res->start;
-	ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
-	if (!ioaddr) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!devm_request_mem_region(&pdev->dev, res->start, RTC_REG_SIZE,
+			pdev->name))
+		return -EBUSY;
+	ioaddr = devm_ioremap(&pdev->dev, res->start, RTC_REG_SIZE);
+	if (!ioaddr)
+		return -ENOMEM;
 	pdata->ioaddr = ioaddr;
 	pdata->irq = platform_get_irq(pdev, 0);
 
@@ -328,9 +320,13 @@ static int __init stk17ta8_rtc_probe(str
 	if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF)
 		dev_warn(&pdev->dev, "voltage-low detected.\n");
 
+	spin_lock_init(&pdata->lock);
+	pdata->last_jiffies = jiffies;
+	platform_set_drvdata(pdev, pdata);
 	if (pdata->irq > 0) {
 		writeb(0, ioaddr + RTC_INTERRUPTS);
-		if (request_irq(pdata->irq, stk17ta8_rtc_interrupt,
+		if (devm_request_irq(&pdev->dev, pdata->irq,
+				stk17ta8_rtc_interrupt,
 				IRQF_DISABLED | IRQF_SHARED,
 				pdev->name, pdev) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
@@ -338,29 +334,14 @@ static int __init stk17ta8_rtc_probe(str
 		}
 	}
 
-	rtc = rtc_device_register(pdev->name, &pdev->dev,
+	pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
 				  &stk17ta8_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		goto out;
-	}
-	pdata->rtc = rtc;
-	pdata->last_jiffies = jiffies;
-	platform_set_drvdata(pdev, pdata);
+	if (IS_ERR(pdata->rtc))
+		return PTR_ERR(pdata->rtc);
+
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
 	if (ret)
-		goto out;
-	return 0;
- out:
-	if (pdata->rtc)
 		rtc_device_unregister(pdata->rtc);
-	if (pdata->irq > 0)
-		free_irq(pdata->irq, pdev);
-	if (ioaddr)
-		iounmap(ioaddr);
-	if (pdata->baseaddr)
-		release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
-	kfree(pdata);
 	return ret;
 }
 
@@ -370,13 +351,8 @@ static int __devexit stk17ta8_rtc_remove
 
 	sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
 	rtc_device_unregister(pdata->rtc);
-	if (pdata->irq > 0) {
+	if (pdata->irq > 0)
 		writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
-		free_irq(pdata->irq, pdev);
-	}
-	iounmap(pdata->ioaddr);
-	release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
-	kfree(pdata);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-twl4030.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl4030.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-twl4030.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl4030.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,540 +0,0 @@
-/*
- * rtc-twl4030.c -- TWL4030 Real Time Clock interface
- *
- * Copyright (C) 2007 MontaVista Software, Inc
- * Author: Alexandre Rusev <source@mvista.com>
- *
- * Based on original TI driver twl4030-rtc.c
- *   Copyright (C) 2006 Texas Instruments, Inc.
- *
- * Based on rtc-omap.c
- *   Copyright (C) 2003 MontaVista Software, Inc.
- *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
- *   Copyright (C) 2006 David Brownell
- *
- * 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/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-
-#include <linux/i2c/twl4030.h>
-
-
-/*
- * RTC block register offsets (use TWL_MODULE_RTC)
- */
-#define REG_SECONDS_REG                          0x00
-#define REG_MINUTES_REG                          0x01
-#define REG_HOURS_REG                            0x02
-#define REG_DAYS_REG                             0x03
-#define REG_MONTHS_REG                           0x04
-#define REG_YEARS_REG                            0x05
-#define REG_WEEKS_REG                            0x06
-
-#define REG_ALARM_SECONDS_REG                    0x07
-#define REG_ALARM_MINUTES_REG                    0x08
-#define REG_ALARM_HOURS_REG                      0x09
-#define REG_ALARM_DAYS_REG                       0x0A
-#define REG_ALARM_MONTHS_REG                     0x0B
-#define REG_ALARM_YEARS_REG                      0x0C
-
-#define REG_RTC_CTRL_REG                         0x0D
-#define REG_RTC_STATUS_REG                       0x0E
-#define REG_RTC_INTERRUPTS_REG                   0x0F
-
-#define REG_RTC_COMP_LSB_REG                     0x10
-#define REG_RTC_COMP_MSB_REG                     0x11
-
-/* RTC_CTRL_REG bitfields */
-#define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
-#define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
-#define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
-#define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
-#define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
-#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
-#define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
-
-/* RTC_STATUS_REG bitfields */
-#define BIT_RTC_STATUS_REG_RUN_M                 0x02
-#define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
-#define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
-#define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
-#define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
-#define BIT_RTC_STATUS_REG_ALARM_M               0x40
-#define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
-
-/* RTC_INTERRUPTS_REG bitfields */
-#define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
-#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
-#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
-
-
-/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
-#define ALL_TIME_REGS		6
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Supports 1 byte read from TWL4030 RTC register.
- */
-static int twl4030_rtc_read_u8(u8 *data, u8 reg)
-{
-	int ret;
-
-	ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
-	if (ret < 0)
-		pr_err("twl4030_rtc: Could not read TWL4030"
-		       "register %X - error %d\n", reg, ret);
-	return ret;
-}
-
-/*
- * Supports 1 byte write to TWL4030 RTC registers.
- */
-static int twl4030_rtc_write_u8(u8 data, u8 reg)
-{
-	int ret;
-
-	ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
-	if (ret < 0)
-		pr_err("twl4030_rtc: Could not write TWL4030"
-		       "register %X - error %d\n", reg, ret);
-	return ret;
-}
-
-/*
- * Cache the value for timer/alarm interrupts register; this is
- * only changed by callers holding rtc ops lock (or resume).
- */
-static unsigned char rtc_irq_bits;
-
-/*
- * Enable 1/second update and/or alarm interrupts.
- */
-static int set_rtc_irq_bit(unsigned char bit)
-{
-	unsigned char val;
-	int ret;
-
-	val = rtc_irq_bits | bit;
-	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
-	ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
-	if (ret == 0)
-		rtc_irq_bits = val;
-
-	return ret;
-}
-
-/*
- * Disable update and/or alarm interrupts.
- */
-static int mask_rtc_irq_bit(unsigned char bit)
-{
-	unsigned char val;
-	int ret;
-
-	val = rtc_irq_bits & ~bit;
-	ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
-	if (ret == 0)
-		rtc_irq_bits = val;
-
-	return ret;
-}
-
-static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
-{
-	int ret;
-
-	if (enabled)
-		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-	else
-		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-
-	return ret;
-}
-
-static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled)
-{
-	int ret;
-
-	if (enabled)
-		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-	else
-		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-
-	return ret;
-}
-
-/*
- * Gets current TWL4030 RTC time and date parameters.
- *
- * The RTC's time/alarm representation is not what gmtime(3) requires
- * Linux to use:
- *
- *  - Months are 1..12 vs Linux 0-11
- *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
- */
-static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	unsigned char rtc_data[ALL_TIME_REGS + 1];
-	int ret;
-	u8 save_control;
-
-	ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
-	if (ret < 0)
-		return ret;
-
-	save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
-
-	ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-	if (ret < 0)
-		return ret;
-
-	ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
-			       REG_SECONDS_REG, ALL_TIME_REGS);
-
-	if (ret < 0) {
-		dev_err(dev, "rtc_read_time error %d\n", ret);
-		return ret;
-	}
-
-	tm->tm_sec = bcd2bin(rtc_data[0]);
-	tm->tm_min = bcd2bin(rtc_data[1]);
-	tm->tm_hour = bcd2bin(rtc_data[2]);
-	tm->tm_mday = bcd2bin(rtc_data[3]);
-	tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
-	tm->tm_year = bcd2bin(rtc_data[5]) + 100;
-
-	return ret;
-}
-
-static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	unsigned char save_control;
-	unsigned char rtc_data[ALL_TIME_REGS + 1];
-	int ret;
-
-	rtc_data[1] = bin2bcd(tm->tm_sec);
-	rtc_data[2] = bin2bcd(tm->tm_min);
-	rtc_data[3] = bin2bcd(tm->tm_hour);
-	rtc_data[4] = bin2bcd(tm->tm_mday);
-	rtc_data[5] = bin2bcd(tm->tm_mon + 1);
-	rtc_data[6] = bin2bcd(tm->tm_year - 100);
-
-	/* Stop RTC while updating the TC registers */
-	ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
-	if (ret < 0)
-		goto out;
-
-	save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
-	twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-	if (ret < 0)
-		goto out;
-
-	/* update all the time registers in one shot */
-	ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
-			REG_SECONDS_REG, ALL_TIME_REGS);
-	if (ret < 0) {
-		dev_err(dev, "rtc_set_time error %d\n", ret);
-		goto out;
-	}
-
-	/* Start back RTC */
-	save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
-	ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-
-out:
-	return ret;
-}
-
-/*
- * Gets current TWL4030 RTC alarm time.
- */
-static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
-	unsigned char rtc_data[ALL_TIME_REGS + 1];
-	int ret;
-
-	ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
-			       REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
-	if (ret < 0) {
-		dev_err(dev, "rtc_read_alarm error %d\n", ret);
-		return ret;
-	}
-
-	/* some of these fields may be wildcard/"match all" */
-	alm->time.tm_sec = bcd2bin(rtc_data[0]);
-	alm->time.tm_min = bcd2bin(rtc_data[1]);
-	alm->time.tm_hour = bcd2bin(rtc_data[2]);
-	alm->time.tm_mday = bcd2bin(rtc_data[3]);
-	alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
-	alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
-
-	/* report cached alarm enable state */
-	if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
-		alm->enabled = 1;
-
-	return ret;
-}
-
-static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
-	unsigned char alarm_data[ALL_TIME_REGS + 1];
-	int ret;
-
-	ret = twl4030_rtc_alarm_irq_enable(dev, 0);
-	if (ret)
-		goto out;
-
-	alarm_data[1] = bin2bcd(alm->time.tm_sec);
-	alarm_data[2] = bin2bcd(alm->time.tm_min);
-	alarm_data[3] = bin2bcd(alm->time.tm_hour);
-	alarm_data[4] = bin2bcd(alm->time.tm_mday);
-	alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
-	alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
-
-	/* update all the alarm registers in one shot */
-	ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
-			REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
-	if (ret) {
-		dev_err(dev, "rtc_set_alarm error %d\n", ret);
-		goto out;
-	}
-
-	if (alm->enabled)
-		ret = twl4030_rtc_alarm_irq_enable(dev, 1);
-out:
-	return ret;
-}
-
-static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
-{
-	unsigned long events = 0;
-	int ret = IRQ_NONE;
-	int res;
-	u8 rd_reg;
-
-#ifdef CONFIG_LOCKDEP
-	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-	 * we don't want and can't tolerate.  Although it might be
-	 * friendlier not to borrow this thread context...
-	 */
-	local_irq_enable();
-#endif
-
-	res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
-	if (res)
-		goto out;
-	/*
-	 * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
-	 * only one (ALARM or RTC) interrupt source may be enabled
-	 * at time, we also could check our results
-	 * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
-	 */
-	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-		events |= RTC_IRQF | RTC_AF;
-	else
-		events |= RTC_IRQF | RTC_UF;
-
-	res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
-				   REG_RTC_STATUS_REG);
-	if (res)
-		goto out;
-
-	/* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
-	 * needs 2 reads to clear the interrupt. One read is done in
-	 * do_twl4030_pwrirq(). Doing the second read, to clear
-	 * the bit.
-	 *
-	 * FIXME the reason PWR_ISR1 needs an extra read is that
-	 * RTC_IF retriggered until we cleared REG_ALARM_M above.
-	 * But re-reading like this is a bad hack; by doing so we
-	 * risk wrongly clearing status for some other IRQ (losing
-	 * the interrupt).  Be smarter about handling RTC_UF ...
-	 */
-	res = twl4030_i2c_read_u8(TWL4030_MODULE_INT,
-			&rd_reg, TWL4030_INT_PWR_ISR1);
-	if (res)
-		goto out;
-
-	/* Notify RTC core on event */
-	rtc_update_irq(rtc, 1, events);
-
-	ret = IRQ_HANDLED;
-out:
-	return ret;
-}
-
-static struct rtc_class_ops twl4030_rtc_ops = {
-	.read_time	= twl4030_rtc_read_time,
-	.set_time	= twl4030_rtc_set_time,
-	.read_alarm	= twl4030_rtc_read_alarm,
-	.set_alarm	= twl4030_rtc_set_alarm,
-	.alarm_irq_enable = twl4030_rtc_alarm_irq_enable,
-	.update_irq_enable = twl4030_rtc_update_irq_enable,
-};
-
-/*----------------------------------------------------------------------*/
-
-static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
-{
-	struct rtc_device *rtc;
-	int ret = 0;
-	int irq = platform_get_irq(pdev, 0);
-	u8 rd_reg;
-
-	if (irq <= 0)
-		return -EINVAL;
-
-	rtc = rtc_device_register(pdev->name,
-				  &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-			PTR_ERR(rtc));
-		goto out0;
-
-	}
-
-	platform_set_drvdata(pdev, rtc);
-
-	ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
-	if (ret < 0)
-		goto out1;
-
-	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
-		dev_warn(&pdev->dev, "Power up reset detected.\n");
-
-	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
-
-	/* Clear RTC Power up reset and pending alarm interrupts */
-	ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
-	if (ret < 0)
-		goto out1;
-
-	ret = request_irq(irq, twl4030_rtc_interrupt,
-				IRQF_TRIGGER_RISING,
-				dev_name(&rtc->dev), rtc);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "IRQ is not free.\n");
-		goto out1;
-	}
-
-	/* Check RTC module status, Enable if it is off */
-	ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
-	if (ret < 0)
-		goto out2;
-
-	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
-		dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
-		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
-		ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
-		if (ret < 0)
-			goto out2;
-	}
-
-	/* init cached IRQ enable bits */
-	ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
-	if (ret < 0)
-		goto out2;
-
-	return ret;
-
-out2:
-	free_irq(irq, rtc);
-out1:
-	rtc_device_unregister(rtc);
-out0:
-	return ret;
-}
-
-/*
- * Disable all TWL4030 RTC module interrupts.
- * Sets status flag to free.
- */
-static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
-{
-	/* leave rtc running, but disable irqs */
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	int irq = platform_get_irq(pdev, 0);
-
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-
-	free_irq(irq, rtc);
-
-	rtc_device_unregister(rtc);
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
-static void twl4030_rtc_shutdown(struct platform_device *pdev)
-{
-	/* mask timer interrupts, but leave alarm interrupts on to enable
-	   power-on when alarm is triggered */
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-}
-
-#ifdef CONFIG_PM
-
-static unsigned char irqstat;
-
-static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	irqstat = rtc_irq_bits;
-
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-	return 0;
-}
-
-static int twl4030_rtc_resume(struct platform_device *pdev)
-{
-	set_rtc_irq_bit(irqstat);
-	return 0;
-}
-
-#else
-#define twl4030_rtc_suspend NULL
-#define twl4030_rtc_resume  NULL
-#endif
-
-MODULE_ALIAS("platform:twl4030_rtc");
-
-static struct platform_driver twl4030rtc_driver = {
-	.probe		= twl4030_rtc_probe,
-	.remove		= __devexit_p(twl4030_rtc_remove),
-	.shutdown	= twl4030_rtc_shutdown,
-	.suspend	= twl4030_rtc_suspend,
-	.resume		= twl4030_rtc_resume,
-	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= "twl4030_rtc",
-	},
-};
-
-static int __init twl4030_rtc_init(void)
-{
-	return platform_driver_register(&twl4030rtc_driver);
-}
-module_init(twl4030_rtc_init);
-
-static void __exit twl4030_rtc_exit(void)
-{
-	platform_driver_unregister(&twl4030rtc_driver);
-}
-module_exit(twl4030_rtc_exit);
-
-MODULE_AUTHOR("Texas Instruments, MontaVista Software");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-twl.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-twl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-twl.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,610 @@
+/*
+ * rtc-twl.c -- TWL Real Time Clock interface
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc
+ * Author: Alexandre Rusev <source@mvista.com>
+ *
+ * Based on original TI driver twl4030-rtc.c
+ *   Copyright (C) 2006 Texas Instruments, Inc.
+ *
+ * Based on rtc-omap.c
+ *   Copyright (C) 2003 MontaVista Software, Inc.
+ *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
+ *   Copyright (C) 2006 David Brownell
+ *
+ * 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/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <linux/i2c/twl.h>
+
+
+/*
+ * RTC block register offsets (use TWL_MODULE_RTC)
+ */
+enum {
+	REG_SECONDS_REG = 0,
+	REG_MINUTES_REG,
+	REG_HOURS_REG,
+	REG_DAYS_REG,
+	REG_MONTHS_REG,
+	REG_YEARS_REG,
+	REG_WEEKS_REG,
+
+	REG_ALARM_SECONDS_REG,
+	REG_ALARM_MINUTES_REG,
+	REG_ALARM_HOURS_REG,
+	REG_ALARM_DAYS_REG,
+	REG_ALARM_MONTHS_REG,
+	REG_ALARM_YEARS_REG,
+
+	REG_RTC_CTRL_REG,
+	REG_RTC_STATUS_REG,
+	REG_RTC_INTERRUPTS_REG,
+
+	REG_RTC_COMP_LSB_REG,
+	REG_RTC_COMP_MSB_REG,
+};
+const static u8 twl4030_rtc_reg_map[] = {
+	[REG_SECONDS_REG] = 0x00,
+	[REG_MINUTES_REG] = 0x01,
+	[REG_HOURS_REG] = 0x02,
+	[REG_DAYS_REG] = 0x03,
+	[REG_MONTHS_REG] = 0x04,
+	[REG_YEARS_REG] = 0x05,
+	[REG_WEEKS_REG] = 0x06,
+
+	[REG_ALARM_SECONDS_REG] = 0x07,
+	[REG_ALARM_MINUTES_REG] = 0x08,
+	[REG_ALARM_HOURS_REG] = 0x09,
+	[REG_ALARM_DAYS_REG] = 0x0A,
+	[REG_ALARM_MONTHS_REG] = 0x0B,
+	[REG_ALARM_YEARS_REG] = 0x0C,
+
+	[REG_RTC_CTRL_REG] = 0x0D,
+	[REG_RTC_STATUS_REG] = 0x0E,
+	[REG_RTC_INTERRUPTS_REG] = 0x0F,
+
+	[REG_RTC_COMP_LSB_REG] = 0x10,
+	[REG_RTC_COMP_MSB_REG] = 0x11,
+};
+const static u8 twl6030_rtc_reg_map[] = {
+	[REG_SECONDS_REG] = 0x00,
+	[REG_MINUTES_REG] = 0x01,
+	[REG_HOURS_REG] = 0x02,
+	[REG_DAYS_REG] = 0x03,
+	[REG_MONTHS_REG] = 0x04,
+	[REG_YEARS_REG] = 0x05,
+	[REG_WEEKS_REG] = 0x06,
+
+	[REG_ALARM_SECONDS_REG] = 0x08,
+	[REG_ALARM_MINUTES_REG] = 0x09,
+	[REG_ALARM_HOURS_REG] = 0x0A,
+	[REG_ALARM_DAYS_REG] = 0x0B,
+	[REG_ALARM_MONTHS_REG] = 0x0C,
+	[REG_ALARM_YEARS_REG] = 0x0D,
+
+	[REG_RTC_CTRL_REG] = 0x10,
+	[REG_RTC_STATUS_REG] = 0x11,
+	[REG_RTC_INTERRUPTS_REG] = 0x12,
+
+	[REG_RTC_COMP_LSB_REG] = 0x13,
+	[REG_RTC_COMP_MSB_REG] = 0x14,
+};
+
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
+#define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
+#define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
+#define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
+#define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
+#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
+#define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
+
+/* RTC_STATUS_REG bitfields */
+#define BIT_RTC_STATUS_REG_RUN_M                 0x02
+#define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
+#define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
+#define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
+#define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
+#define BIT_RTC_STATUS_REG_ALARM_M               0x40
+#define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
+
+/* RTC_INTERRUPTS_REG bitfields */
+#define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
+#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
+#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
+
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+#define ALL_TIME_REGS		6
+
+/*----------------------------------------------------------------------*/
+static u8  *rtc_reg_map;
+
+/*
+ * Supports 1 byte read from TWL RTC register.
+ */
+static int twl_rtc_read_u8(u8 *data, u8 reg)
+{
+	int ret;
+
+	ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
+	if (ret < 0)
+		pr_err("twl_rtc: Could not read TWL"
+		       "register %X - error %d\n", reg, ret);
+	return ret;
+}
+
+/*
+ * Supports 1 byte write to TWL RTC registers.
+ */
+static int twl_rtc_write_u8(u8 data, u8 reg)
+{
+	int ret;
+
+	ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
+	if (ret < 0)
+		pr_err("twl_rtc: Could not write TWL"
+		       "register %X - error %d\n", reg, ret);
+	return ret;
+}
+
+/*
+ * Cache the value for timer/alarm interrupts register; this is
+ * only changed by callers holding rtc ops lock (or resume).
+ */
+static unsigned char rtc_irq_bits;
+
+/*
+ * Enable 1/second update and/or alarm interrupts.
+ */
+static int set_rtc_irq_bit(unsigned char bit)
+{
+	unsigned char val;
+	int ret;
+
+	val = rtc_irq_bits | bit;
+	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
+	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+	if (ret == 0)
+		rtc_irq_bits = val;
+
+	return ret;
+}
+
+/*
+ * Disable update and/or alarm interrupts.
+ */
+static int mask_rtc_irq_bit(unsigned char bit)
+{
+	unsigned char val;
+	int ret;
+
+	val = rtc_irq_bits & ~bit;
+	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+	if (ret == 0)
+		rtc_irq_bits = val;
+
+	return ret;
+}
+
+static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+	int ret;
+
+	if (enabled)
+		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+	else
+		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+
+	return ret;
+}
+
+static int twl_rtc_update_irq_enable(struct device *dev, unsigned enabled)
+{
+	int ret;
+
+	if (enabled)
+		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	else
+		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+
+	return ret;
+}
+
+/*
+ * Gets current TWL RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ *  - Months are 1..12 vs Linux 0-11
+ *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned char rtc_data[ALL_TIME_REGS + 1];
+	int ret;
+	u8 save_control;
+
+	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+	if (ret < 0)
+		return ret;
+
+	save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
+
+	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+	if (ret < 0)
+		return ret;
+
+	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
+			(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
+
+	if (ret < 0) {
+		dev_err(dev, "rtc_read_time error %d\n", ret);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(rtc_data[0]);
+	tm->tm_min = bcd2bin(rtc_data[1]);
+	tm->tm_hour = bcd2bin(rtc_data[2]);
+	tm->tm_mday = bcd2bin(rtc_data[3]);
+	tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+	tm->tm_year = bcd2bin(rtc_data[5]) + 100;
+
+	return ret;
+}
+
+static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned char save_control;
+	unsigned char rtc_data[ALL_TIME_REGS + 1];
+	int ret;
+
+	rtc_data[1] = bin2bcd(tm->tm_sec);
+	rtc_data[2] = bin2bcd(tm->tm_min);
+	rtc_data[3] = bin2bcd(tm->tm_hour);
+	rtc_data[4] = bin2bcd(tm->tm_mday);
+	rtc_data[5] = bin2bcd(tm->tm_mon + 1);
+	rtc_data[6] = bin2bcd(tm->tm_year - 100);
+
+	/* Stop RTC while updating the TC registers */
+	ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+	if (ret < 0)
+		goto out;
+
+	save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
+	twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+	if (ret < 0)
+		goto out;
+
+	/* update all the time registers in one shot */
+	ret = twl_i2c_write(TWL_MODULE_RTC, rtc_data,
+		(rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "rtc_set_time error %d\n", ret);
+		goto out;
+	}
+
+	/* Start back RTC */
+	save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
+	ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+
+out:
+	return ret;
+}
+
+/*
+ * Gets current TWL RTC alarm time.
+ */
+static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	unsigned char rtc_data[ALL_TIME_REGS + 1];
+	int ret;
+
+	ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data,
+			(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
+	if (ret < 0) {
+		dev_err(dev, "rtc_read_alarm error %d\n", ret);
+		return ret;
+	}
+
+	/* some of these fields may be wildcard/"match all" */
+	alm->time.tm_sec = bcd2bin(rtc_data[0]);
+	alm->time.tm_min = bcd2bin(rtc_data[1]);
+	alm->time.tm_hour = bcd2bin(rtc_data[2]);
+	alm->time.tm_mday = bcd2bin(rtc_data[3]);
+	alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
+	alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
+
+	/* report cached alarm enable state */
+	if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
+		alm->enabled = 1;
+
+	return ret;
+}
+
+static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	unsigned char alarm_data[ALL_TIME_REGS + 1];
+	int ret;
+
+	ret = twl_rtc_alarm_irq_enable(dev, 0);
+	if (ret)
+		goto out;
+
+	alarm_data[1] = bin2bcd(alm->time.tm_sec);
+	alarm_data[2] = bin2bcd(alm->time.tm_min);
+	alarm_data[3] = bin2bcd(alm->time.tm_hour);
+	alarm_data[4] = bin2bcd(alm->time.tm_mday);
+	alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
+	alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
+
+	/* update all the alarm registers in one shot */
+	ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data,
+		(rtc_reg_map[REG_ALARM_SECONDS_REG]), ALL_TIME_REGS);
+	if (ret) {
+		dev_err(dev, "rtc_set_alarm error %d\n", ret);
+		goto out;
+	}
+
+	if (alm->enabled)
+		ret = twl_rtc_alarm_irq_enable(dev, 1);
+out:
+	return ret;
+}
+
+static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
+{
+	unsigned long events = 0;
+	int ret = IRQ_NONE;
+	int res;
+	u8 rd_reg;
+
+#ifdef CONFIG_LOCKDEP
+	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+	 * we don't want and can't tolerate.  Although it might be
+	 * friendlier not to borrow this thread context...
+	 */
+	local_irq_enable();
+#endif
+
+	res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+	if (res)
+		goto out;
+	/*
+	 * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
+	 * only one (ALARM or RTC) interrupt source may be enabled
+	 * at time, we also could check our results
+	 * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
+	 */
+	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+		events |= RTC_IRQF | RTC_AF;
+	else
+		events |= RTC_IRQF | RTC_UF;
+
+	res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
+				   REG_RTC_STATUS_REG);
+	if (res)
+		goto out;
+
+	if (twl_class_is_4030()) {
+		/* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
+		 * needs 2 reads to clear the interrupt. One read is done in
+		 * do_twl_pwrirq(). Doing the second read, to clear
+		 * the bit.
+		 *
+		 * FIXME the reason PWR_ISR1 needs an extra read is that
+		 * RTC_IF retriggered until we cleared REG_ALARM_M above.
+		 * But re-reading like this is a bad hack; by doing so we
+		 * risk wrongly clearing status for some other IRQ (losing
+		 * the interrupt).  Be smarter about handling RTC_UF ...
+		 */
+		res = twl_i2c_read_u8(TWL4030_MODULE_INT,
+			&rd_reg, TWL4030_INT_PWR_ISR1);
+		if (res)
+			goto out;
+	}
+
+	/* Notify RTC core on event */
+	rtc_update_irq(rtc, 1, events);
+
+	ret = IRQ_HANDLED;
+out:
+	return ret;
+}
+
+static struct rtc_class_ops twl_rtc_ops = {
+	.read_time	= twl_rtc_read_time,
+	.set_time	= twl_rtc_set_time,
+	.read_alarm	= twl_rtc_read_alarm,
+	.set_alarm	= twl_rtc_set_alarm,
+	.alarm_irq_enable = twl_rtc_alarm_irq_enable,
+	.update_irq_enable = twl_rtc_update_irq_enable,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit twl_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	int ret = 0;
+	int irq = platform_get_irq(pdev, 0);
+	u8 rd_reg;
+
+	if (irq <= 0)
+		return -EINVAL;
+
+	rtc = rtc_device_register(pdev->name,
+				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		ret = PTR_ERR(rtc);
+		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+			PTR_ERR(rtc));
+		goto out0;
+
+	}
+
+	platform_set_drvdata(pdev, rtc);
+
+	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+	if (ret < 0)
+		goto out1;
+
+	if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
+		dev_warn(&pdev->dev, "Power up reset detected.\n");
+
+	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+		dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
+
+	/* Clear RTC Power up reset and pending alarm interrupts */
+	ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
+	if (ret < 0)
+		goto out1;
+
+	ret = request_irq(irq, twl_rtc_interrupt,
+				IRQF_TRIGGER_RISING,
+				dev_name(&rtc->dev), rtc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "IRQ is not free.\n");
+		goto out1;
+	}
+
+	if (twl_class_is_6030()) {
+		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
+			REG_INT_MSK_LINE_A);
+		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
+			REG_INT_MSK_STS_A);
+	}
+
+	/* Check RTC module status, Enable if it is off */
+	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
+	if (ret < 0)
+		goto out2;
+
+	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
+		dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
+		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
+		ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
+		if (ret < 0)
+			goto out2;
+	}
+
+	/* init cached IRQ enable bits */
+	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
+	if (ret < 0)
+		goto out2;
+
+	return ret;
+
+out2:
+	free_irq(irq, rtc);
+out1:
+	rtc_device_unregister(rtc);
+out0:
+	return ret;
+}
+
+/*
+ * Disable all TWL RTC module interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit twl_rtc_remove(struct platform_device *pdev)
+{
+	/* leave rtc running, but disable irqs */
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
+
+	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	if (twl_class_is_6030()) {
+		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
+			REG_INT_MSK_LINE_A);
+		twl6030_interrupt_mask(TWL6030_RTC_INT_MASK,
+			REG_INT_MSK_STS_A);
+	}
+
+
+	free_irq(irq, rtc);
+
+	rtc_device_unregister(rtc);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static void twl_rtc_shutdown(struct platform_device *pdev)
+{
+	/* mask timer interrupts, but leave alarm interrupts on to enable
+	   power-on when alarm is triggered */
+	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+}
+
+#ifdef CONFIG_PM
+
+static unsigned char irqstat;
+
+static int twl_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	irqstat = rtc_irq_bits;
+
+	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+	return 0;
+}
+
+static int twl_rtc_resume(struct platform_device *pdev)
+{
+	set_rtc_irq_bit(irqstat);
+	return 0;
+}
+
+#else
+#define twl_rtc_suspend NULL
+#define twl_rtc_resume  NULL
+#endif
+
+MODULE_ALIAS("platform:twl_rtc");
+
+static struct platform_driver twl4030rtc_driver = {
+	.probe		= twl_rtc_probe,
+	.remove		= __devexit_p(twl_rtc_remove),
+	.shutdown	= twl_rtc_shutdown,
+	.suspend	= twl_rtc_suspend,
+	.resume		= twl_rtc_resume,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "twl_rtc",
+	},
+};
+
+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_AUTHOR("Texas Instruments, MontaVista Software");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-tx4939.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-tx4939.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-tx4939.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-tx4939.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,6 +17,7 @@
 struct tx4939rtc_plat_data {
 	struct rtc_device *rtc;
 	struct tx4939_rtc_reg __iomem *rtcreg;
+	spinlock_t lock;
 };
 
 static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev)
@@ -52,14 +53,14 @@ static int tx4939_rtc_set_mmss(struct de
 	buf[3] = secs >> 8;
 	buf[4] = secs >> 16;
 	buf[5] = secs >> 24;
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	__raw_writel(0, &rtcreg->adr);
 	for (i = 0; i < 6; i++)
 		__raw_writel(buf[i], &rtcreg->dat);
 	ret = tx4939_rtc_cmd(rtcreg,
 			     TX4939_RTCCTL_COMMAND_SETTIME |
 			     (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	return ret;
 }
 
@@ -71,18 +72,18 @@ static int tx4939_rtc_read_time(struct d
 	unsigned long sec;
 	unsigned char buf[6];
 
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	ret = tx4939_rtc_cmd(rtcreg,
 			     TX4939_RTCCTL_COMMAND_GETTIME |
 			     (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
 	if (ret) {
-		spin_unlock_irq(&pdata->rtc->irq_lock);
+		spin_unlock_irq(&pdata->lock);
 		return ret;
 	}
 	__raw_writel(2, &rtcreg->adr);
 	for (i = 2; i < 6; i++)
 		buf[i] = __raw_readl(&rtcreg->dat);
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
 	rtc_time_to_tm(sec, tm);
 	return rtc_valid_tm(tm);
@@ -110,13 +111,13 @@ static int tx4939_rtc_set_alarm(struct d
 	buf[3] = sec >> 8;
 	buf[4] = sec >> 16;
 	buf[5] = sec >> 24;
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	__raw_writel(0, &rtcreg->adr);
 	for (i = 0; i < 6; i++)
 		__raw_writel(buf[i], &rtcreg->dat);
 	ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM |
 			     (alrm->enabled ? TX4939_RTCCTL_ALME : 0));
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	return ret;
 }
 
@@ -129,12 +130,12 @@ static int tx4939_rtc_read_alarm(struct
 	unsigned char buf[6];
 	u32 ctl;
 
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	ret = tx4939_rtc_cmd(rtcreg,
 			     TX4939_RTCCTL_COMMAND_GETALARM |
 			     (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
 	if (ret) {
-		spin_unlock_irq(&pdata->rtc->irq_lock);
+		spin_unlock_irq(&pdata->lock);
 		return ret;
 	}
 	__raw_writel(2, &rtcreg->adr);
@@ -143,7 +144,7 @@ static int tx4939_rtc_read_alarm(struct
 	ctl = __raw_readl(&rtcreg->ctl);
 	alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
 	alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2];
 	rtc_time_to_tm(sec, &alrm->time);
 	return rtc_valid_tm(&alrm->time);
@@ -153,11 +154,11 @@ static int tx4939_rtc_alarm_irq_enable(s
 {
 	struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
 
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	tx4939_rtc_cmd(pdata->rtcreg,
 		       TX4939_RTCCTL_COMMAND_NOP |
 		       (enabled ? TX4939_RTCCTL_ALME : 0));
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	return 0;
 }
 
@@ -167,13 +168,14 @@ static irqreturn_t tx4939_rtc_interrupt(
 	struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 	unsigned long events = RTC_IRQF;
 
-	spin_lock(&pdata->rtc->irq_lock);
+	spin_lock(&pdata->lock);
 	if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) {
 		events |= RTC_AF;
 		tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 	}
-	spin_unlock(&pdata->rtc->irq_lock);
-	rtc_update_irq(pdata->rtc, 1, events);
+	spin_unlock(&pdata->lock);
+	if (likely(pdata->rtc))
+		rtc_update_irq(pdata->rtc, 1, events);
 	return IRQ_HANDLED;
 }
 
@@ -194,13 +196,13 @@ static ssize_t tx4939_rtc_nvram_read(str
 	struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 	ssize_t count;
 
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE;
 	     count++, size--) {
 		__raw_writel(pos++, &rtcreg->adr);
 		*buf++ = __raw_readl(&rtcreg->dat);
 	}
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	return count;
 }
 
@@ -213,13 +215,13 @@ static ssize_t tx4939_rtc_nvram_write(st
 	struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 	ssize_t count;
 
-	spin_lock_irq(&pdata->rtc->irq_lock);
+	spin_lock_irq(&pdata->lock);
 	for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE;
 	     count++, size--) {
 		__raw_writel(pos++, &rtcreg->adr);
 		__raw_writel(*buf++, &rtcreg->dat);
 	}
-	spin_unlock_irq(&pdata->rtc->irq_lock);
+	spin_unlock_irq(&pdata->lock);
 	return count;
 }
 
@@ -259,6 +261,7 @@ static int __init tx4939_rtc_probe(struc
 	if (!pdata->rtcreg)
 		return -EBUSY;
 
+	spin_lock_init(&pdata->lock);
 	tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 	if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
 			     IRQF_DISABLED, pdev->name, &pdev->dev) < 0)
@@ -277,14 +280,12 @@ static int __init tx4939_rtc_probe(struc
 static int __exit tx4939_rtc_remove(struct platform_device *pdev)
 {
 	struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
-	struct rtc_device *rtc = pdata->rtc;
 
-	spin_lock_irq(&rtc->irq_lock);
-	tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
-	spin_unlock_irq(&rtc->irq_lock);
 	sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr);
-	rtc_device_unregister(rtc);
-	platform_set_drvdata(pdev, NULL);
+	rtc_device_unregister(pdata->rtc);
+	spin_lock_irq(&pdata->lock);
+	tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
+	spin_unlock_irq(&pdata->lock);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-v3020.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-v3020.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-v3020.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-v3020.c	2010-02-24 13:52:17.000000000 -0500
@@ -304,7 +304,6 @@ static int rtc_probe(struct platform_dev
 {
 	struct v3020_platform_data *pdata = pdev->dev.platform_data;
 	struct v3020 *chip;
-	struct rtc_device *rtc;
 	int retval = -EBUSY;
 	int i;
 	int temp;
@@ -335,7 +334,7 @@ static int rtc_probe(struct platform_dev
 		goto err_io;
 	}
 
-	/* Make sure frequency measurment mode, test modes, and lock
+	/* Make sure frequency measurement mode, test modes, and lock
 	 * are all disabled */
 	v3020_set_reg(chip, V3020_STATUS_0, 0x0);
 
@@ -353,13 +352,12 @@ static int rtc_probe(struct platform_dev
 
 	platform_set_drvdata(pdev, chip);
 
-	rtc = rtc_device_register("v3020",
+	chip->rtc = rtc_device_register("v3020",
 				&pdev->dev, &v3020_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		retval = PTR_ERR(rtc);
+	if (IS_ERR(chip->rtc)) {
+		retval = PTR_ERR(chip->rtc);
 		goto err_io;
 	}
-	chip->rtc = rtc;
 
 	return 0;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-vr41xx.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-vr41xx.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-vr41xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-vr41xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -327,7 +327,7 @@ static int __devinit rtc_probe(struct pl
 	if (!res)
 		return -EBUSY;
 
-	rtc1_base = ioremap(res->start, res->end - res->start + 1);
+	rtc1_base = ioremap(res->start, resource_size(res));
 	if (!rtc1_base)
 		return -EBUSY;
 
@@ -337,7 +337,7 @@ static int __devinit rtc_probe(struct pl
 		goto err_rtc1_iounmap;
 	}
 
-	rtc2_base = ioremap(res->start, res->end - res->start + 1);
+	rtc2_base = ioremap(res->start, resource_size(res));
 	if (!rtc2_base) {
 		retval = -EBUSY;
 		goto err_rtc1_iounmap;
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-wm831x.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm831x.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-wm831x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm831x.c	2010-02-24 13:52:17.000000000 -0500
@@ -485,7 +485,7 @@ static int __devexit wm831x_rtc_remove(s
 	return 0;
 }
 
-static struct dev_pm_ops wm831x_rtc_pm_ops = {
+static const struct dev_pm_ops wm831x_rtc_pm_ops = {
 	.suspend = wm831x_rtc_suspend,
 	.resume = wm831x_rtc_resume,
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-wm8350.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm8350.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-wm8350.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-wm8350.c	2010-02-24 13:52:17.000000000 -0500
@@ -315,9 +315,9 @@ static int wm8350_rtc_update_irq_enable(
 	return 0;
 }
 
-static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq,
-				     void *data)
+static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data)
 {
+	struct wm8350 *wm8350 = data;
 	struct rtc_device *rtc = wm8350->rtc.rtc;
 	int ret;
 
@@ -330,14 +330,18 @@ static void wm8350_rtc_alarm_handler(str
 		dev_err(&(wm8350->rtc.pdev->dev),
 			"Failed to disable alarm: %d\n", ret);
 	}
+
+	return IRQ_HANDLED;
 }
 
-static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq,
-				      void *data)
+static irqreturn_t wm8350_rtc_update_handler(int irq, void *data)
 {
+	struct wm8350 *wm8350 = data;
 	struct rtc_device *rtc = wm8350->rtc.rtc;
 
 	rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF);
+
+	return IRQ_HANDLED;
 }
 
 static const struct rtc_class_ops wm8350_rtc_ops = {
@@ -350,8 +354,9 @@ static const struct rtc_class_ops wm8350
 };
 
 #ifdef CONFIG_PM
-static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8350_rtc_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
 	int ret = 0;
 	u16 reg;
@@ -369,8 +374,9 @@ static int wm8350_rtc_suspend(struct pla
 	return ret;
 }
 
-static int wm8350_rtc_resume(struct platform_device *pdev)
+static int wm8350_rtc_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
 	int ret;
 
@@ -455,15 +461,14 @@ static int wm8350_rtc_probe(struct platf
 		return ret;
 	}
 
-	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER);
-
 	wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
-			    wm8350_rtc_update_handler, NULL);
+			    wm8350_rtc_update_handler, 0,
+			    "RTC Seconds", wm8350);
+	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 
 	wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
-			    wm8350_rtc_alarm_handler, NULL);
-	wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM);
+			    wm8350_rtc_alarm_handler, 0,
+			    "RTC Alarm", wm8350);
 
 	return 0;
 }
@@ -473,8 +478,6 @@ static int __devexit wm8350_rtc_remove(s
 	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 	struct wm8350_rtc *wm_rtc = &wm8350->rtc;
 
-	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-
 	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
 	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);
 
@@ -483,13 +486,17 @@ static int __devexit wm8350_rtc_remove(s
 	return 0;
 }
 
+static struct dev_pm_ops wm8350_rtc_pm_ops = {
+	.suspend = wm8350_rtc_suspend,
+	.resume = wm8350_rtc_resume,
+};
+
 static struct platform_driver wm8350_rtc_driver = {
 	.probe = wm8350_rtc_probe,
 	.remove = __devexit_p(wm8350_rtc_remove),
-	.suspend = wm8350_rtc_suspend,
-	.resume = wm8350_rtc_resume,
 	.driver = {
 		.name = "wm8350-rtc",
+		.pm = &wm8350_rtc_pm_ops,
 	},
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/rtc/rtc-x1205.c linux-libre-2.6.33-gnu1/drivers/rtc/rtc-x1205.c
--- linux-libre-2.6.32-gnu1/drivers/rtc/rtc-x1205.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/rtc/rtc-x1205.c	2010-02-24 13:52:17.000000000 -0500
@@ -155,11 +155,11 @@ static int x1205_get_status(struct i2c_c
 }
 
 static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
-			int datetoo, u8 reg_base, unsigned char alm_enable)
+			u8 reg_base, unsigned char alm_enable)
 {
-	int i, xfer, nbytes;
-	unsigned char buf[8];
+	int i, xfer;
 	unsigned char rdata[10] = { 0, reg_base };
+	unsigned char *buf = rdata + 2;
 
 	static const unsigned char wel[3] = { 0, X1205_REG_SR,
 						X1205_SR_WEL };
@@ -170,9 +170,9 @@ static int x1205_set_datetime(struct i2c
 	static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
 
 	dev_dbg(&client->dev,
-		"%s: secs=%d, mins=%d, hours=%d\n",
-		__func__,
-		tm->tm_sec, tm->tm_min, tm->tm_hour);
+		"%s: sec=%d min=%d hour=%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);
 
 	buf[CCR_SEC] = bin2bcd(tm->tm_sec);
 	buf[CCR_MIN] = bin2bcd(tm->tm_min);
@@ -180,23 +180,15 @@ static int x1205_set_datetime(struct i2c
 	/* set hour and 24hr bit */
 	buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
 
-	/* should we also set the date? */
-	if (datetoo) {
-		dev_dbg(&client->dev,
-			"%s: mday=%d, mon=%d, year=%d, wday=%d\n",
-			__func__,
-			tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-
-		buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
+	buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
 
-		/* month, 1 - 12 */
-		buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1);
+	/* month, 1 - 12 */
+	buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1);
 
-		/* year, since the rtc epoch*/
-		buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
-		buf[CCR_WDAY] = tm->tm_wday & 0x07;
-		buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
-	}
+	/* year, since the rtc epoch*/
+	buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
+	buf[CCR_WDAY] = tm->tm_wday & 0x07;
+	buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
 
 	/* If writing alarm registers, set compare bits on registers 0-4 */
 	if (reg_base < X1205_CCR_BASE)
@@ -214,17 +206,8 @@ static int x1205_set_datetime(struct i2c
 		return -EIO;
 	}
 
-
-	/* write register's data */
-	if (datetoo)
-		nbytes = 8;
-	else
-		nbytes = 3;
-	for (i = 0; i < nbytes; i++)
-		rdata[2+i] = buf[i];
-
-	xfer = i2c_master_send(client, rdata, nbytes+2);
-	if (xfer != nbytes+2) {
+	xfer = i2c_master_send(client, rdata, sizeof(rdata));
+	if (xfer != sizeof(rdata)) {
 		dev_err(&client->dev,
 			"%s: result=%d addr=%02x, data=%02x\n",
 			__func__,
@@ -282,7 +265,7 @@ static int x1205_fix_osc(struct i2c_clie
 
 	memset(&tm, 0, sizeof(tm));
 
-	err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0);
+	err = x1205_set_datetime(client, &tm, X1205_CCR_BASE, 0);
 	if (err < 0)
 		dev_err(&client->dev, "unable to restart the oscillator\n");
 
@@ -481,7 +464,7 @@ static int x1205_rtc_read_alarm(struct d
 static int x1205_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	return x1205_set_datetime(to_i2c_client(dev),
-		&alrm->time, 1, X1205_ALM0_BASE, alrm->enabled);
+		&alrm->time, X1205_ALM0_BASE, alrm->enabled);
 }
 
 static int x1205_rtc_read_time(struct device *dev, struct rtc_time *tm)
@@ -493,7 +476,7 @@ static int x1205_rtc_read_time(struct de
 static int x1205_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	return x1205_set_datetime(to_i2c_client(dev),
-		tm, 1, X1205_CCR_BASE, 0);
+		tm, X1205_CCR_BASE, 0);
 }
 
 static int x1205_rtc_proc(struct device *dev, struct seq_file *seq)
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_3990_erp.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_3990_erp.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_3990_erp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_3990_erp.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,6 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <asm/idals.h>
-#include <asm/todclk.h>
 
 #define PRINTK_HEADER "dasd_erp(3990): "
 
@@ -70,8 +69,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_re
  *   processing until the started timer has expired or an related
  *   interrupt was received.
  */
-static void
-dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
+static void dasd_3990_erp_block_queue(struct dasd_ccw_req *erp, int expires)
 {
 
 	struct dasd_device *device = erp->startdev;
@@ -81,10 +79,13 @@ dasd_3990_erp_block_queue(struct dasd_cc
 		    "blocking request queue for %is", expires/HZ);
 
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-	device->stopped |= DASD_STOPPED_PENDING;
+	dasd_device_set_stop_bits(device, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	erp->status = DASD_CQR_FILLED;
-	dasd_block_set_timer(device->block, expires);
+	if (erp->block)
+		dasd_block_set_timer(erp->block, expires);
+	else
+		dasd_device_set_timer(device, expires);
 }
 
 /*
@@ -243,9 +244,13 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req *
  * DESCRIPTION
  *   Setup ERP to do the ERP action 1 (see Reference manual).
  *   Repeat the operation on a different channel path.
- *   If all alternate paths have been tried, the request is posted with a
- *   permanent error.
- *   Note: duplex handling is not implemented (yet).
+ *   As deviation from the recommended recovery action, we reset the path mask
+ *   after we have tried each path and go through all paths a second time.
+ *   This will cover situations where only one path at a time is actually down,
+ *   but all paths fail and recover just with the same sequence and timing as
+ *   we try to use them (flapping links).
+ *   If all alternate paths have been tried twice, the request is posted with
+ *   a permanent error.
  *
  *  PARAMETER
  *   erp		pointer to the current ERP
@@ -254,17 +259,25 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req *
  *   erp		pointer to the ERP
  *
  */
-static struct dasd_ccw_req *
-dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
+static struct dasd_ccw_req *dasd_3990_erp_action_1_sec(struct dasd_ccw_req *erp)
 {
+	erp->function = dasd_3990_erp_action_1_sec;
+	dasd_3990_erp_alternate_path(erp);
+	return erp;
+}
 
+static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
+{
 	erp->function = dasd_3990_erp_action_1;
-
 	dasd_3990_erp_alternate_path(erp);
-
+	if (erp->status == DASD_CQR_FAILED) {
+		erp->status = DASD_CQR_FILLED;
+		erp->retries = 10;
+		erp->lpm = LPM_ANYPATH;
+		erp->function = dasd_3990_erp_action_1_sec;
+	}
 	return erp;
-
-}				/* end dasd_3990_erp_action_1 */
+}				/* end dasd_3990_erp_action_1(b) */
 
 /*
  * DASD_3990_ERP_ACTION_4
@@ -2295,6 +2308,7 @@ static struct dasd_ccw_req *dasd_3990_er
 		return cqr;
 	}
 
+	ccw = cqr->cpaddr;
 	if (cqr->cpmode == 1) {
 		/* make a shallow copy of the original tcw but set new tsb */
 		erp->cpmode = 1;
@@ -2303,6 +2317,9 @@ static struct dasd_ccw_req *dasd_3990_er
 		tsb = (struct tsb *) &tcw[1];
 		*tcw = *((struct tcw *)cqr->cpaddr);
 		tcw->tsb = (long)tsb;
+	} else if (ccw->cmd_code == DASD_ECKD_CCW_PSF) {
+		/* PSF cannot be chained from NOOP/TIC */
+		erp->cpaddr = cqr->cpaddr;
 	} else {
 		/* initialize request with default TIC to current ERP/CQR */
 		ccw = erp->cpaddr;
@@ -2487,6 +2504,8 @@ dasd_3990_erp_further_erp(struct dasd_cc
 
 		erp = dasd_3990_erp_action_1(erp);
 
+	} else if (erp->function == dasd_3990_erp_action_1_sec) {
+		erp = dasd_3990_erp_action_1_sec(erp);
 	} else if (erp->function == dasd_3990_erp_action_5) {
 
 		/* retries have not been successful */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_alias.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_alias.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_alias.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_alias.c	2010-02-24 13:52:17.000000000 -0500
@@ -152,6 +152,7 @@ static struct alias_lcu *_allocate_lcu(s
 	INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
 	INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
 	spin_lock_init(&lcu->lock);
+	init_completion(&lcu->lcu_setup);
 	return lcu;
 
 out_err4:
@@ -217,7 +218,7 @@ int dasd_alias_make_device_known_to_lcu(
 		spin_unlock_irqrestore(&aliastree.lock, flags);
 		newlcu = _allocate_lcu(uid);
 		if (IS_ERR(newlcu))
-			return PTR_ERR(lcu);
+			return PTR_ERR(newlcu);
 		spin_lock_irqsave(&aliastree.lock, flags);
 		lcu = _find_lcu(server, uid);
 		if (!lcu) {
@@ -240,6 +241,67 @@ int dasd_alias_make_device_known_to_lcu(
 }
 
 /*
+ * The first device to be registered on an LCU will have to do
+ * some additional setup steps to configure that LCU on the
+ * storage server. All further devices should wait with their
+ * initialization until the first device is done.
+ * To synchronize this work, the first device will call
+ * dasd_alias_lcu_setup_complete when it is done, and all
+ * other devices will wait for it with dasd_alias_wait_for_lcu_setup.
+ */
+void dasd_alias_lcu_setup_complete(struct dasd_device *device)
+{
+	struct dasd_eckd_private *private;
+	unsigned long flags;
+	struct alias_server *server;
+	struct alias_lcu *lcu;
+	struct dasd_uid *uid;
+
+	private = (struct dasd_eckd_private *) device->private;
+	uid = &private->uid;
+	lcu = NULL;
+	spin_lock_irqsave(&aliastree.lock, flags);
+	server = _find_server(uid);
+	if (server)
+		lcu = _find_lcu(server, uid);
+	spin_unlock_irqrestore(&aliastree.lock, flags);
+	if (!lcu) {
+		DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+				"could not find lcu for %04x %02x",
+				uid->ssid, uid->real_unit_addr);
+		WARN_ON(1);
+		return;
+	}
+	complete_all(&lcu->lcu_setup);
+}
+
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
+{
+	struct dasd_eckd_private *private;
+	unsigned long flags;
+	struct alias_server *server;
+	struct alias_lcu *lcu;
+	struct dasd_uid *uid;
+
+	private = (struct dasd_eckd_private *) device->private;
+	uid = &private->uid;
+	lcu = NULL;
+	spin_lock_irqsave(&aliastree.lock, flags);
+	server = _find_server(uid);
+	if (server)
+		lcu = _find_lcu(server, uid);
+	spin_unlock_irqrestore(&aliastree.lock, flags);
+	if (!lcu) {
+		DBF_EVENT_DEVID(DBF_ERR, device->cdev,
+				"could not find lcu for %04x %02x",
+				uid->ssid, uid->real_unit_addr);
+		WARN_ON(1);
+		return;
+	}
+	wait_for_completion(&lcu->lcu_setup);
+}
+
+/*
  * This function removes a device from the scope of alias management.
  * The complicated part is to make sure that it is not in use by
  * any of the workers. If necessary cancel the work.
@@ -755,11 +817,11 @@ static void __stop_device_on_lcu(struct
 {
 	/* If pos == device then device is already locked! */
 	if (pos == device) {
-		pos->stopped |= DASD_STOPPED_SU;
+		dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 		return;
 	}
 	spin_lock(get_ccwdev_lock(pos->cdev));
-	pos->stopped |= DASD_STOPPED_SU;
+	dasd_device_set_stop_bits(pos, DASD_STOPPED_SU);
 	spin_unlock(get_ccwdev_lock(pos->cdev));
 }
 
@@ -793,26 +855,26 @@ static void _unstop_all_devices_on_lcu(s
 
 	list_for_each_entry(device, &lcu->active_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
 		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-		device->stopped &= ~DASD_STOPPED_SU;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	}
 
 	list_for_each_entry(pavgroup, &lcu->grouplist, group) {
 		list_for_each_entry(device, &pavgroup->baselist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
 		list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
 			spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-			device->stopped &= ~DASD_STOPPED_SU;
+			dasd_device_remove_stop_bits(device, DASD_STOPPED_SU);
 			spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 					       flags);
 		}
@@ -836,7 +898,8 @@ static void summary_unit_check_handling_
 
 	/* 2. reset summary unit check */
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
-	device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING);
+	dasd_device_remove_stop_bits(device,
+				     (DASD_STOPPED_SU | DASD_STOPPED_PENDING));
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	reset_summary_unit_check(lcu, device, suc_data->reason);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd.c	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,6 @@
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
-#include <asm/todclk.h>
 #include <asm/itcw.h>
 
 /* This is ugly... */
@@ -64,6 +63,7 @@ static void do_restore_device(struct wor
 static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
 static void dasd_device_timeout(unsigned long);
 static void dasd_block_timeout(unsigned long);
+static void __dasd_process_erp(struct dasd_device *, struct dasd_ccw_req *);
 
 /*
  * SECTION: Operations on the device structure.
@@ -960,7 +960,7 @@ static void dasd_device_timeout(unsigned
 	device = (struct dasd_device *) ptr;
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	/* re-activate request queue */
-        device->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	dasd_schedule_device_bh(device);
 }
@@ -994,10 +994,9 @@ static void dasd_handle_killed_request(s
 		return;
 	cqr = (struct dasd_ccw_req *) intparm;
 	if (cqr->status != DASD_CQR_IN_IO) {
-		DBF_EVENT(DBF_DEBUG,
-			"invalid status in handle_killed_request: "
-			"bus_id %s, status %02x",
-			dev_name(&cdev->dev), cqr->status);
+		DBF_EVENT_DEVID(DBF_DEBUG, cdev,
+				"invalid status in handle_killed_request: "
+				"%02x", cqr->status);
 		return;
 	}
 
@@ -1005,8 +1004,8 @@ static void dasd_handle_killed_request(s
 	if (device == NULL ||
 	    device != dasd_device_from_cdev_locked(cdev) ||
 	    strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
-			      "bus_id %s", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+				"invalid device in request");
 		return;
 	}
 
@@ -1023,7 +1022,7 @@ void dasd_generic_handle_state_change(st
 	/* First of all start sense subsystem status request. */
 	dasd_eer_snss(device);
 
-	device->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING);
 	dasd_schedule_device_bh(device);
 	if (device->block)
 		dasd_schedule_block_bh(device->block);
@@ -1045,12 +1044,13 @@ void dasd_int_handler(struct ccw_device
 		case -EIO:
 			break;
 		case -ETIMEDOUT:
-			DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
-			       __func__, dev_name(&cdev->dev));
+			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+					"request timed out\n", __func__);
 			break;
 		default:
-			DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
-			       __func__, dev_name(&cdev->dev), PTR_ERR(irb));
+			DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: "
+					"unknown error %ld\n", __func__,
+					PTR_ERR(irb));
 		}
 		dasd_handle_killed_request(cdev, intparm);
 		return;
@@ -1078,8 +1078,8 @@ void dasd_int_handler(struct ccw_device
 	device = (struct dasd_device *) cqr->startdev;
 	if (!device ||
 	    strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
-			      "bus_id %s", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
+				"invalid device in request");
 		return;
 	}
 
@@ -1405,6 +1405,20 @@ void dasd_schedule_device_bh(struct dasd
 	tasklet_hi_schedule(&device->tasklet);
 }
 
+void dasd_device_set_stop_bits(struct dasd_device *device, int bits)
+{
+	device->stopped |= bits;
+}
+EXPORT_SYMBOL_GPL(dasd_device_set_stop_bits);
+
+void dasd_device_remove_stop_bits(struct dasd_device *device, int bits)
+{
+	device->stopped &= ~bits;
+	if (!device->stopped)
+		wake_up(&generic_waitq);
+}
+EXPORT_SYMBOL_GPL(dasd_device_remove_stop_bits);
+
 /*
  * Queue a request to the head of the device ccw_queue.
  * Start the I/O if possible.
@@ -1465,58 +1479,135 @@ static inline int _wait_for_wakeup(struc
 }
 
 /*
- * Queue a request to the tail of the device ccw_queue and wait for
- * it's completion.
+ * checks if error recovery is necessary, returns 1 if yes, 0 otherwise.
  */
-int dasd_sleep_on(struct dasd_ccw_req *cqr)
+static int __dasd_sleep_on_erp(struct dasd_ccw_req *cqr)
 {
 	struct dasd_device *device;
-	int rc;
+	dasd_erp_fn_t erp_fn;
 
+	if (cqr->status == DASD_CQR_FILLED)
+		return 0;
 	device = cqr->startdev;
+	if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) {
+		if (cqr->status == DASD_CQR_TERMINATED) {
+			device->discipline->handle_terminated_request(cqr);
+			return 1;
+		}
+		if (cqr->status == DASD_CQR_NEED_ERP) {
+			erp_fn = device->discipline->erp_action(cqr);
+			erp_fn(cqr);
+			return 1;
+		}
+		if (cqr->status == DASD_CQR_FAILED)
+			dasd_log_sense(cqr, &cqr->irb);
+		if (cqr->refers) {
+			__dasd_process_erp(device, cqr);
+			return 1;
+		}
+	}
+	return 0;
+}
 
-	cqr->callback = dasd_wakeup_cb;
-	cqr->callback_data = (void *) &generic_waitq;
-	dasd_add_request_tail(cqr);
-	wait_event(generic_waitq, _wait_for_wakeup(cqr));
+static int __dasd_sleep_on_loop_condition(struct dasd_ccw_req *cqr)
+{
+	if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) {
+		if (cqr->refers) /* erp is not done yet */
+			return 1;
+		return ((cqr->status != DASD_CQR_DONE) &&
+			(cqr->status != DASD_CQR_FAILED));
+	} else
+		return (cqr->status == DASD_CQR_FILLED);
+}
 
-	if (cqr->status == DASD_CQR_DONE)
+static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
+{
+	struct dasd_device *device;
+	int rc;
+	struct list_head ccw_queue;
+	struct dasd_ccw_req *cqr;
+
+	INIT_LIST_HEAD(&ccw_queue);
+	maincqr->status = DASD_CQR_FILLED;
+	device = maincqr->startdev;
+	list_add(&maincqr->blocklist, &ccw_queue);
+	for (cqr = maincqr;  __dasd_sleep_on_loop_condition(cqr);
+	     cqr = list_first_entry(&ccw_queue,
+				    struct dasd_ccw_req, blocklist)) {
+
+		if (__dasd_sleep_on_erp(cqr))
+			continue;
+		if (cqr->status != DASD_CQR_FILLED) /* could be failed */
+			continue;
+
+		/* Non-temporary stop condition will trigger fail fast */
+		if (device->stopped & ~DASD_STOPPED_PENDING &&
+		    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+		    (!dasd_eer_enabled(device))) {
+			cqr->status = DASD_CQR_FAILED;
+			continue;
+		}
+
+		/* Don't try to start requests if device is stopped */
+		if (interruptible) {
+			rc = wait_event_interruptible(
+				generic_waitq, !(device->stopped));
+			if (rc == -ERESTARTSYS) {
+				cqr->status = DASD_CQR_FAILED;
+				maincqr->intrc = rc;
+				continue;
+			}
+		} else
+			wait_event(generic_waitq, !(device->stopped));
+
+		cqr->callback = dasd_wakeup_cb;
+		cqr->callback_data = (void *) &generic_waitq;
+		dasd_add_request_tail(cqr);
+		if (interruptible) {
+			rc = wait_event_interruptible(
+				generic_waitq, _wait_for_wakeup(cqr));
+			if (rc == -ERESTARTSYS) {
+				dasd_cancel_req(cqr);
+				/* wait (non-interruptible) for final status */
+				wait_event(generic_waitq,
+					   _wait_for_wakeup(cqr));
+				cqr->status = DASD_CQR_FAILED;
+				maincqr->intrc = rc;
+				continue;
+			}
+		} else
+			wait_event(generic_waitq, _wait_for_wakeup(cqr));
+	}
+
+	maincqr->endclk = get_clock();
+	if ((maincqr->status != DASD_CQR_DONE) &&
+	    (maincqr->intrc != -ERESTARTSYS))
+		dasd_log_sense(maincqr, &maincqr->irb);
+	if (maincqr->status == DASD_CQR_DONE)
 		rc = 0;
-	else if (cqr->intrc)
-		rc = cqr->intrc;
+	else if (maincqr->intrc)
+		rc = maincqr->intrc;
 	else
 		rc = -EIO;
 	return rc;
 }
 
 /*
+ * Queue a request to the tail of the device ccw_queue and wait for
+ * it's completion.
+ */
+int dasd_sleep_on(struct dasd_ccw_req *cqr)
+{
+	return _dasd_sleep_on(cqr, 0);
+}
+
+/*
  * Queue a request to the tail of the device ccw_queue and wait
  * interruptible for it's completion.
  */
 int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
 {
-	struct dasd_device *device;
-	int rc;
-
-	device = cqr->startdev;
-	cqr->callback = dasd_wakeup_cb;
-	cqr->callback_data = (void *) &generic_waitq;
-	dasd_add_request_tail(cqr);
-	rc = wait_event_interruptible(generic_waitq, _wait_for_wakeup(cqr));
-	if (rc == -ERESTARTSYS) {
-		dasd_cancel_req(cqr);
-		/* wait (non-interruptible) for final status */
-		wait_event(generic_waitq, _wait_for_wakeup(cqr));
-		cqr->intrc = rc;
-	}
-
-	if (cqr->status == DASD_CQR_DONE)
-		rc = 0;
-	else if (cqr->intrc)
-		rc = cqr->intrc;
-	else
-		rc = -EIO;
-	return rc;
+	return _dasd_sleep_on(cqr, 1);
 }
 
 /*
@@ -1630,7 +1721,7 @@ static void dasd_block_timeout(unsigned
 	block = (struct dasd_block *) ptr;
 	spin_lock_irqsave(get_ccwdev_lock(block->base->cdev), flags);
 	/* re-activate request queue */
-	block->base->stopped &= ~DASD_STOPPED_PENDING;
+	dasd_device_remove_stop_bits(block->base, DASD_STOPPED_PENDING);
 	spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags);
 	dasd_schedule_block_bh(block);
 }
@@ -1657,11 +1748,10 @@ void dasd_block_clear_timer(struct dasd_
 /*
  * Process finished error recovery ccw.
  */
-static inline void __dasd_block_process_erp(struct dasd_block *block,
-					    struct dasd_ccw_req *cqr)
+static void __dasd_process_erp(struct dasd_device *device,
+			       struct dasd_ccw_req *cqr)
 {
 	dasd_erp_fn_t erp_fn;
-	struct dasd_device *device = block->base;
 
 	if (cqr->status == DASD_CQR_DONE)
 		DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
@@ -1725,9 +1815,12 @@ static void __dasd_process_request_queue
 				 */
 				if (!list_empty(&block->ccw_queue))
 					break;
-				spin_lock_irqsave(get_ccwdev_lock(basedev->cdev), flags);
-				basedev->stopped |= DASD_STOPPED_PENDING;
-				spin_unlock_irqrestore(get_ccwdev_lock(basedev->cdev), flags);
+				spin_lock_irqsave(
+					get_ccwdev_lock(basedev->cdev), flags);
+				dasd_device_set_stop_bits(basedev,
+							  DASD_STOPPED_PENDING);
+				spin_unlock_irqrestore(
+					get_ccwdev_lock(basedev->cdev), flags);
 				dasd_block_set_timer(block, HZ/2);
 				break;
 			}
@@ -1813,7 +1906,7 @@ restart:
 			cqr->status = DASD_CQR_FILLED;
 			cqr->retries = 255;
 			spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-			base->stopped |= DASD_STOPPED_QUIESCE;
+			dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
 			spin_unlock_irqrestore(get_ccwdev_lock(base->cdev),
 					       flags);
 			goto restart;
@@ -1821,7 +1914,7 @@ restart:
 
 		/* Process finished ERP request. */
 		if (cqr->refers) {
-			__dasd_block_process_erp(block, cqr);
+			__dasd_process_erp(base, cqr);
 			goto restart;
 		}
 
@@ -1952,7 +2045,7 @@ restart_cb:
 		/* Process finished ERP request. */
 		if (cqr->refers) {
 			spin_lock_bh(&block->queue_lock);
-			__dasd_block_process_erp(block, cqr);
+			__dasd_process_erp(block->base, cqr);
 			spin_unlock_bh(&block->queue_lock);
 			/* restart list_for_xx loop since dasd_process_erp
 			 * might remove multiple elements */
@@ -2208,18 +2301,11 @@ int dasd_generic_probe(struct ccw_device
 {
 	int ret;
 
-	ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
-	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_generic_probe: could not set ccw-device options "
-		       "for %s\n", dev_name(&cdev->dev));
-		return ret;
-	}
 	ret = dasd_add_sysfs_files(cdev);
 	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_generic_probe: could not add sysfs entries "
-		       "for %s\n", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+				"dasd_generic_probe: could not add "
+				"sysfs entries");
 		return ret;
 	}
 	cdev->handler = &dasd_int_handler;
@@ -2418,16 +2504,16 @@ int dasd_generic_notify(struct ccw_devic
 				cqr->status = DASD_CQR_QUEUED;
 				cqr->retries++;
 			}
-		device->stopped |= DASD_STOPPED_DC_WAIT;
+		dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
 		dasd_device_clear_timer(device);
 		dasd_schedule_device_bh(device);
 		ret = 1;
 		break;
 	case CIO_OPER:
 		/* FIXME: add a sanity check. */
-		device->stopped &= ~DASD_STOPPED_DC_WAIT;
+		dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
 		if (device->stopped & DASD_UNRESUMED_PM) {
-			device->stopped &= ~DASD_UNRESUMED_PM;
+			dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
 			dasd_restore_device(device);
 			ret = 1;
 			break;
@@ -2452,7 +2538,7 @@ int dasd_generic_pm_freeze(struct ccw_de
 	if (IS_ERR(device))
 		return PTR_ERR(device);
 	/* disallow new I/O  */
-	device->stopped |= DASD_STOPPED_PM;
+	dasd_device_set_stop_bits(device, DASD_STOPPED_PM);
 	/* clear active requests */
 	INIT_LIST_HEAD(&freeze_queue);
 	spin_lock_irq(get_ccwdev_lock(cdev));
@@ -2504,14 +2590,18 @@ int dasd_generic_restore_device(struct c
 		return PTR_ERR(device);
 
 	/* allow new IO again */
-	device->stopped &= ~DASD_STOPPED_PM;
-	device->stopped &= ~DASD_UNRESUMED_PM;
+	dasd_device_remove_stop_bits(device,
+				     (DASD_STOPPED_PM | DASD_UNRESUMED_PM));
 
 	dasd_schedule_device_bh(device);
 
-	if (device->discipline->restore)
+	/*
+	 * call discipline restore function
+	 * if device is stopped do nothing e.g. for disconnected devices
+	 */
+	if (device->discipline->restore && !(device->stopped))
 		rc = device->discipline->restore(device);
-	if (rc)
+	if (rc || device->stopped)
 		/*
 		 * if the resume failed for the DASD we put it in
 		 * an UNRESUMED stop state
@@ -2561,8 +2651,7 @@ static struct dasd_ccw_req *dasd_generic
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->expires = 10*HZ;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 2;
+	cqr->retries = 256;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_diag.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_diag.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_diag.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_diag.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
  *
  */
 
-#define KMSG_COMPONENT "dasd-diag"
+#define KMSG_COMPONENT "dasd"
 
 #include <linux/stddef.h>
 #include <linux/kernel.h>
@@ -24,7 +24,6 @@
 #include <asm/ebcdic.h>
 #include <asm/io.h>
 #include <asm/s390_ext.h>
-#include <asm/todclk.h>
 #include <asm/vtoc.h>
 #include <asm/diag.h>
 
@@ -145,9 +144,18 @@ dasd_diag_erp(struct dasd_device *device
 
 	mdsk_term_io(device);
 	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
+	if (rc == 4) {
+		if (!(device->features & DASD_FEATURE_READONLY)) {
+			pr_warning("%s: The access mode of a DIAG device "
+				   "changed to read-only\n",
+				   dev_name(&device->cdev->dev));
+			device->features |= DASD_FEATURE_READONLY;
+		}
+		rc = 0;
+	}
 	if (rc)
-		dev_warn(&device->cdev->dev, "DIAG ERP failed with "
-			    "rc=%d\n", rc);
+		pr_warning("%s: DIAG ERP failed with "
+			    "rc=%d\n", dev_name(&device->cdev->dev), rc);
 }
 
 /* Start a given request at the device. Return zero on success, non-zero
@@ -363,8 +371,9 @@ dasd_diag_check_device(struct dasd_devic
 		private->pt_block = 2;
 		break;
 	default:
-		dev_warn(&device->cdev->dev, "Device type %d is not supported "
-			    "in DIAG mode\n", private->rdc_data.vdev_class);
+		pr_warning("%s: Device type %d is not supported "
+			   "in DIAG mode\n", dev_name(&device->cdev->dev),
+			   private->rdc_data.vdev_class);
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
@@ -405,8 +414,8 @@ dasd_diag_check_device(struct dasd_devic
 		private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
 		rc = dia250(&private->iob, RW_BIO);
 		if (rc == 3) {
-			dev_warn(&device->cdev->dev,
-				"A 64-bit DIAG call failed\n");
+			pr_warning("%s: A 64-bit DIAG call failed\n",
+				   dev_name(&device->cdev->dev));
 			rc = -EOPNOTSUPP;
 			goto out_label;
 		}
@@ -415,8 +424,9 @@ dasd_diag_check_device(struct dasd_devic
 			break;
 	}
 	if (bsize > PAGE_SIZE) {
-		dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
-			 " of an incorrect format (rc=%d)\n", rc);
+		pr_warning("%s: Accessing the DASD failed because of an "
+			   "incorrect format (rc=%d)\n",
+			   dev_name(&device->cdev->dev), rc);
 		rc = -EIO;
 		goto out_label;
 	}
@@ -433,16 +443,20 @@ dasd_diag_check_device(struct dasd_devic
 	for (sb = 512; sb < bsize; sb = sb << 1)
 		block->s2b_shift++;
 	rc = mdsk_init_io(device, block->bp_block, 0, NULL);
-	if (rc) {
-		dev_warn(&device->cdev->dev, "DIAG initialization "
-			"failed with rc=%d\n", rc);
+	if (rc && (rc != 4)) {
+		pr_warning("%s: DIAG initialization failed with rc=%d\n",
+			   dev_name(&device->cdev->dev), rc);
 		rc = -EIO;
 	} else {
-		dev_info(&device->cdev->dev,
-			 "New DASD with %ld byte/block, total size %ld KB\n",
-			 (unsigned long) block->bp_block,
-			 (unsigned long) (block->blocks <<
-					  block->s2b_shift) >> 1);
+		if (rc == 4)
+			device->features |= DASD_FEATURE_READONLY;
+		pr_info("%s: New DASD with %ld byte/block, total size %ld "
+			"KB%s\n", dev_name(&device->cdev->dev),
+			(unsigned long) block->bp_block,
+			(unsigned long) (block->blocks <<
+					 block->s2b_shift) >> 1,
+			(rc == 4) ? ", read-only device" : "");
+		rc = 0;
 	}
 out_label:
 	free_page((long) label);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eckd.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eckd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,8 +23,8 @@
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
+#include <asm/compat.h>
 #include <asm/io.h>
-#include <asm/todclk.h>
 #include <asm/uaccess.h>
 #include <asm/cio.h>
 #include <asm/ccwdev.h>
@@ -78,6 +78,11 @@ MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
 
 static struct ccw_driver dasd_eckd_driver; /* see below */
 
+#define INIT_CQR_OK 0
+#define INIT_CQR_UNFORMATTED 1
+#define INIT_CQR_ERROR 2
+
+
 /* initial attempt at a probe function. this can be simplified once
  * the other detection code is gone */
 static int
@@ -86,11 +91,12 @@ dasd_eckd_probe (struct ccw_device *cdev
 	int ret;
 
 	/* set ECKD specific ccw-device options */
-	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
+	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE |
+				     CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH);
 	if (ret) {
-		DBF_EVENT(DBF_WARNING,
-		       "dasd_eckd_probe: could not set ccw-device options "
-		       "for %s\n", dev_name(&cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",
+				"dasd_eckd_probe: could not set "
+				"ccw-device options");
 		return ret;
 	}
 	ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
@@ -749,8 +755,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr->block = NULL;
 	cqr->expires = 10*HZ;
 	cqr->lpm = lpm;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 2;
+	cqr->retries = 256;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -885,16 +890,15 @@ static int dasd_eckd_read_conf(struct da
 			rc = dasd_eckd_read_conf_lpm(device, &conf_data,
 						     &conf_len, lpm);
 			if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
-				DBF_EVENT(DBF_WARNING,
+				DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
 					  "Read configuration data returned "
-					  "error %d for device: %s", rc,
-					  dev_name(&device->cdev->dev));
+					  "error %d", rc);
 				return rc;
 			}
 			if (conf_data == NULL) {
-				DBF_EVENT(DBF_WARNING, "No configuration "
-					  "data retrieved for device: %s",
-					  dev_name(&device->cdev->dev));
+				DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+						"No configuration data "
+						"retrieved");
 				continue;	/* no error */
 			}
 			/* save first valid configuration data */
@@ -941,16 +945,14 @@ static int dasd_eckd_read_features(struc
 				    sizeof(struct dasd_rssd_features)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
-			  "request for device: %s",
-			  dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not "
+				"allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->block = NULL;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
-	cqr->retries = 5;
+	cqr->retries = 256;
 	cqr->expires = 10 * HZ;
 
 	/* Prepare for Read Subsystem Data */
@@ -1012,9 +1014,9 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	}
 	psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
 	psf_ssc_data->order = PSF_ORDER_SSC;
-	psf_ssc_data->suborder = 0x40;
+	psf_ssc_data->suborder = 0xc0;
 	if (enable_pav) {
-		psf_ssc_data->suborder |= 0x88;
+		psf_ssc_data->suborder |= 0x08;
 		psf_ssc_data->reserved[0] = 0x88;
 	}
 	ccw = cqr->cpaddr;
@@ -1025,6 +1027,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->block = NULL;
+	cqr->retries = 256;
 	cqr->expires = 10*HZ;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
@@ -1057,7 +1060,7 @@ dasd_eckd_psf_ssc(struct dasd_device *de
 /*
  * Valide storage server of current device.
  */
-static int dasd_eckd_validate_server(struct dasd_device *device)
+static void dasd_eckd_validate_server(struct dasd_device *device)
 {
 	int rc;
 	struct dasd_eckd_private *private;
@@ -1068,15 +1071,12 @@ static int dasd_eckd_validate_server(str
 	else
 		enable_pav = 1;
 	rc = dasd_eckd_psf_ssc(device, enable_pav);
+
 	/* may be requested feature is not available on server,
 	 * therefore just report error and go ahead */
 	private = (struct dasd_eckd_private *) device->private;
-	DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
-		  "returned rc=%d for device: %s",
-		  private->uid.vendor, private->uid.serial,
-		  private->uid.ssid, rc, dev_name(&device->cdev->dev));
-	/* RE-Read Configuration Data */
-	return dasd_eckd_read_conf(device);
+	DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
+			"returned rc=%d", private->uid.ssid, rc);
 }
 
 /*
@@ -1090,6 +1090,15 @@ dasd_eckd_check_characteristics(struct d
 	struct dasd_block *block;
 	int is_known, rc;
 
+	if (!ccw_device_is_pathgroup(device->cdev)) {
+		dev_warn(&device->cdev->dev,
+			 "A channel path group could not be established\n");
+		return -EIO;
+	}
+	if (!ccw_device_is_multipath(device->cdev)) {
+		dev_info(&device->cdev->dev,
+			 "The DASD is not operating in multipath mode\n");
+	}
 	private = (struct dasd_eckd_private *) device->private;
 	if (!private) {
 		private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
@@ -1123,9 +1132,9 @@ dasd_eckd_check_characteristics(struct d
 	if (private->uid.type == UA_BASE_DEVICE) {
 		block = dasd_alloc_block();
 		if (IS_ERR(block)) {
-			DBF_EVENT(DBF_WARNING, "could not allocate dasd "
-				  "block structure for device: %s",
-				  dev_name(&device->cdev->dev));
+			DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
+					"could not allocate dasd "
+					"block structure");
 			rc = PTR_ERR(block);
 			goto out_err1;
 		}
@@ -1139,12 +1148,21 @@ dasd_eckd_check_characteristics(struct d
 		rc = is_known;
 		goto out_err2;
 	}
+	/*
+	 * dasd_eckd_vaildate_server is done on the first device that
+	 * is found for an LCU. All later other devices have to wait
+	 * for it, so they will read the correct feature codes.
+	 */
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err3;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* device may report different configuration data after LCU setup */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err3;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);
@@ -1153,9 +1171,8 @@ dasd_eckd_check_characteristics(struct d
 	rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
 					 &private->rdc_data, 64);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING,
-			  "Read device characteristics failed, rc=%d for "
-			  "device: %s", rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+				"Read device characteristic failed, rc=%d", rc);
 		goto out_err3;
 	}
 	/* find the vaild cylinder size */
@@ -1256,12 +1273,29 @@ dasd_eckd_analysis_ccw(struct dasd_devic
 	cqr->block = NULL;
 	cqr->startdev = device;
 	cqr->memdev = device;
-	cqr->retries = 0;
+	cqr->retries = 255;
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
 }
 
+/* differentiate between 'no record found' and any other error */
+static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr)
+{
+	char *sense;
+	if (init_cqr->status == DASD_CQR_DONE)
+		return INIT_CQR_OK;
+	else if (init_cqr->status == DASD_CQR_NEED_ERP ||
+		 init_cqr->status == DASD_CQR_FAILED) {
+		sense = dasd_get_sense(&init_cqr->irb);
+		if (sense && (sense[1] & SNS1_NO_REC_FOUND))
+			return INIT_CQR_UNFORMATTED;
+		else
+			return INIT_CQR_ERROR;
+	} else
+		return INIT_CQR_ERROR;
+}
+
 /*
  * This is the callback function for the init_analysis cqr. It saves
  * the status of the initial analysis ccw before it frees it and kicks
@@ -1269,21 +1303,20 @@ dasd_eckd_analysis_ccw(struct dasd_devic
  * dasd_eckd_do_analysis again (if the devices has not been marked
  * for deletion in the meantime).
  */
-static void
-dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data)
+static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,
+					void *data)
 {
 	struct dasd_eckd_private *private;
 	struct dasd_device *device;
 
 	device = init_cqr->startdev;
 	private = (struct dasd_eckd_private *) device->private;
-	private->init_cqr_status = init_cqr->status;
+	private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr);
 	dasd_sfree_request(init_cqr, device);
 	dasd_kick_device(device);
 }
 
-static int
-dasd_eckd_start_analysis(struct dasd_block *block)
+static int dasd_eckd_start_analysis(struct dasd_block *block)
 {
 	struct dasd_eckd_private *private;
 	struct dasd_ccw_req *init_cqr;
@@ -1295,27 +1328,44 @@ dasd_eckd_start_analysis(struct dasd_blo
 	init_cqr->callback = dasd_eckd_analysis_callback;
 	init_cqr->callback_data = NULL;
 	init_cqr->expires = 5*HZ;
+	/* first try without ERP, so we can later handle unformatted
+	 * devices as special case
+	 */
+	clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags);
+	init_cqr->retries = 0;
 	dasd_add_request_head(init_cqr);
 	return -EAGAIN;
 }
 
-static int
-dasd_eckd_end_analysis(struct dasd_block *block)
+static int dasd_eckd_end_analysis(struct dasd_block *block)
 {
 	struct dasd_device *device;
 	struct dasd_eckd_private *private;
 	struct eckd_count *count_area;
 	unsigned int sb, blk_per_trk;
 	int status, i;
+	struct dasd_ccw_req *init_cqr;
 
 	device = block->base;
 	private = (struct dasd_eckd_private *) device->private;
 	status = private->init_cqr_status;
 	private->init_cqr_status = -1;
-	if (status != DASD_CQR_DONE) {
-		dev_warn(&device->cdev->dev,
-			    "The DASD is not formatted\n");
+	if (status == INIT_CQR_ERROR) {
+		/* try again, this time with full ERP */
+		init_cqr = dasd_eckd_analysis_ccw(device);
+		dasd_sleep_on(init_cqr);
+		status = dasd_eckd_analysis_evaluation(init_cqr);
+		dasd_sfree_request(init_cqr, device);
+	}
+
+	if (status == INIT_CQR_UNFORMATTED) {
+		dev_warn(&device->cdev->dev, "The DASD is not formatted\n");
 		return -EMEDIUMTYPE;
+	} else if (status == INIT_CQR_ERROR) {
+		dev_err(&device->cdev->dev,
+			"Detecting the DASD disk layout failed because "
+			"of an I/O error\n");
+		return -EIO;
 	}
 
 	private->uses_cdl = 1;
@@ -1607,8 +1657,7 @@ dasd_eckd_format_device(struct dasd_devi
 	}
 	fcp->startdev = device;
 	fcp->memdev = device;
-	clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags);
-	fcp->retries = 5;	/* set retry counter to enable default ERP */
+	fcp->retries = 256;
 	fcp->buildclk = get_clock();
 	fcp->status = DASD_CQR_FILLED;
 	return fcp;
@@ -2690,6 +2739,7 @@ dasd_eckd_performance(struct dasd_device
 	cqr->startdev = device;
 	cqr->memdev = device;
 	cqr->retries = 0;
+	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 	cqr->expires = 10 * HZ;
 
 	/* Prepare for Read Subsystem Data */
@@ -2795,13 +2845,16 @@ static int dasd_symm_io(struct dasd_devi
 	rc = -EFAULT;
 	if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
 		goto out;
-#ifndef CONFIG_64BIT
-	/* Make sure pointers are sane even on 31 bit. */
-	if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) {
+	if (is_compat_task() || sizeof(long) == 4) {
+		/* Make sure pointers are sane even on 31 bit. */
 		rc = -EINVAL;
-		goto out;
+		if ((usrparm.psf_data >> 32) != 0)
+			goto out;
+		if ((usrparm.rssd_result >> 32) != 0)
+			goto out;
+		usrparm.psf_data &= 0x7fffffffULL;
+		usrparm.rssd_result &= 0x7fffffffULL;
 	}
-#endif
 	/* alloc I/O data area */
 	psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
 	rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
@@ -2980,7 +3033,7 @@ static void dasd_eckd_dump_sense_ccw(str
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
 		       req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
-		       scsw_cc(&irb->scsw), req->intrc);
+		       scsw_cc(&irb->scsw), req ? req->intrc : 0);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " device %s: Failing CCW: %p\n",
 		       dev_name(&device->cdev->dev),
@@ -3240,11 +3293,15 @@ int dasd_eckd_restore_device(struct dasd
 	if (is_known < 0)
 		return is_known;
 	if (!is_known) {
-		/* new lcu found */
-		rc = dasd_eckd_validate_server(device); /* will switch pav on */
-		if (rc)
-			goto out_err;
-	}
+		dasd_eckd_validate_server(device);
+		dasd_alias_lcu_setup_complete(device);
+	} else
+		dasd_alias_wait_for_lcu_setup(device);
+
+	/* RE-Read Configuration Data */
+	rc = dasd_eckd_read_conf(device);
+	if (rc)
+		goto out_err;
 
 	/* Read Feature Codes */
 	dasd_eckd_read_features(device);
@@ -3253,9 +3310,8 @@ int dasd_eckd_restore_device(struct dasd
 	rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
 					 &temp_rdc_data, 64);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING,
-			  "Read device characteristics failed, rc=%d for "
-			  "device: %s", rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+				"Read device characteristic failed, rc=%d", rc);
 		goto out_err;
 	}
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eckd.h linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.h
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eckd.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eckd.h	2010-02-24 13:52:17.000000000 -0500
@@ -414,6 +414,7 @@ struct alias_lcu {
 	struct summary_unit_check_work_data suc_data;
 	struct read_uac_work_data ruac_data;
 	struct dasd_ccw_req *rsu_cqr;
+	struct completion lcu_setup;
 };
 
 struct alias_pav_group {
@@ -460,5 +461,6 @@ int dasd_alias_remove_device(struct dasd
 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
 void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
-
+void dasd_alias_lcu_setup_complete(struct dasd_device *);
+void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
 #endif				/* DASD_ECKD_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eer.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eer.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_eer.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_eer.c	2010-02-24 13:52:17.000000000 -0500
@@ -536,7 +536,6 @@ static int dasd_eer_open(struct inode *i
 	eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
 	if (!eerb)
 		return -ENOMEM;
-	lock_kernel();
 	eerb->buffer_page_count = eer_pages;
 	if (eerb->buffer_page_count < 1 ||
 	    eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
@@ -544,7 +543,6 @@ static int dasd_eer_open(struct inode *i
 		DBF_EVENT(DBF_WARNING, "can't open device since module "
 			"parameter eer_pages is smaller than 1 or"
 			" bigger than %d", (int)(INT_MAX / PAGE_SIZE));
-		unlock_kernel();
 		return -EINVAL;
 	}
 	eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
@@ -552,14 +550,12 @@ static int dasd_eer_open(struct inode *i
 			       GFP_KERNEL);
         if (!eerb->buffer) {
 		kfree(eerb);
-		unlock_kernel();
                 return -ENOMEM;
 	}
 	if (dasd_eer_allocate_buffer_pages(eerb->buffer,
 					   eerb->buffer_page_count)) {
 		kfree(eerb->buffer);
 		kfree(eerb);
-		unlock_kernel();
 		return -ENOMEM;
 	}
 	filp->private_data = eerb;
@@ -567,7 +563,6 @@ static int dasd_eer_open(struct inode *i
 	list_add(&eerb->list, &bufferlist);
 	spin_unlock_irqrestore(&bufferlock, flags);
 
-	unlock_kernel();
 	return nonseekable_open(inp,filp);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_fba.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_fba.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_fba.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_fba.c	2010-02-24 13:52:17.000000000 -0500
@@ -20,7 +20,6 @@
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/todclk.h>
 #include <asm/ccwdev.h>
 
 #include "dasd_int.h"
@@ -141,9 +140,8 @@ dasd_fba_check_characteristics(struct da
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
-			  "structure for device: %s",
-			  dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", "could not allocate "
+				"dasd block structure");
 		device->private = NULL;
 		kfree(private);
 		return PTR_ERR(block);
@@ -155,9 +153,8 @@ dasd_fba_check_characteristics(struct da
 	rc = dasd_generic_read_dev_chars(device, DASD_FBA_MAGIC,
 					 &private->rdc_data, 32);
 	if (rc) {
-		DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
-			  "error %d for device: %s",
-			  rc, dev_name(&device->cdev->dev));
+		DBF_EVENT_DEVID(DBF_WARNING, cdev, "Read device "
+				"characteristics returned error %d", rc);
 		device->block = NULL;
 		dasd_free_block(block);
 		device->private = NULL;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_int.h linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_int.h
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_int.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_int.h	2010-02-24 13:52:17.000000000 -0500
@@ -108,6 +108,16 @@ do { \
 			    d_data); \
 } while(0)
 
+#define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...)	\
+do { \
+	struct ccw_dev_id __dev_id;			\
+	ccw_device_get_id(d_cdev, &__dev_id);		\
+	debug_sprintf_event(dasd_debug_area,		\
+			    d_level,					\
+			    "0.%x.%04x " d_str "\n",			\
+			    __dev_id.ssid, __dev_id.devno, d_data);	\
+} while (0)
+
 #define DBF_EXC(d_level, d_str, d_data...)\
 do { \
 	debug_sprintf_exception(dasd_debug_area, \
@@ -595,6 +605,9 @@ int dasd_generic_restore_device(struct c
 int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
 char *dasd_get_sense(struct irb *);
 
+void dasd_device_set_stop_bits(struct dasd_device *, int);
+void dasd_device_remove_stop_bits(struct dasd_device *, int);
+
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
 extern int dasd_probeonly;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_ioctl.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_ioctl.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_ioctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_ioctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,7 +17,7 @@
 #include <linux/fs.h>
 #include <linux/blkpg.h>
 #include <linux/smp_lock.h>
-
+#include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include <asm/cmb.h>
 #include <asm/uaccess.h>
@@ -101,7 +101,7 @@ static int dasd_ioctl_quiesce(struct das
 	pr_info("%s: The DASD has been put in the quiesce "
 		"state\n", dev_name(&base->cdev->dev));
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-	base->stopped |= DASD_STOPPED_QUIESCE;
+	dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 	return 0;
 }
@@ -122,7 +122,7 @@ static int dasd_ioctl_resume(struct dasd
 	pr_info("%s: I/O operations have been resumed "
 		"on the DASD\n", dev_name(&base->cdev->dev));
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
-	base->stopped &= ~DASD_STOPPED_QUIESCE;
+	dasd_device_remove_stop_bits(base, DASD_STOPPED_QUIESCE);
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
 
 	dasd_schedule_block_bh(block);
@@ -260,7 +260,7 @@ static int dasd_ioctl_information(struct
 	struct ccw_dev_id dev_id;
 
 	base = block->base;
-	if (!base->discipline->fill_info)
+	if (!base->discipline || !base->discipline->fill_info)
 		return -EINVAL;
 
 	dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
@@ -303,10 +303,7 @@ static int dasd_ioctl_information(struct
 	dasd_info->features |=
 		((base->features & DASD_FEATURE_READONLY) != 0);
 
-	if (base->discipline)
-		memcpy(dasd_info->type, base->discipline->name, 4);
-	else
-		memcpy(dasd_info->type, "none", 4);
+	memcpy(dasd_info->type, base->discipline->name, 4);
 
 	if (block->request_queue->request_fn) {
 		struct list_head *l;
@@ -358,9 +355,8 @@ dasd_ioctl_set_ro(struct block_device *b
 }
 
 static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
-		unsigned long arg)
+				  struct cmbdata __user *argp)
 {
-	struct cmbdata __user *argp = (void __user *) arg;
 	size_t size = _IOC_SIZE(cmd);
 	struct cmbdata data;
 	int ret;
@@ -376,7 +372,12 @@ dasd_do_ioctl(struct block_device *bdev,
 	      unsigned int cmd, unsigned long arg)
 {
 	struct dasd_block *block = bdev->bd_disk->private_data;
-	void __user *argp = (void __user *)arg;
+	void __user *argp;
+
+	if (is_compat_task())
+		argp = compat_ptr(arg);
+	else
+		argp = (void __user *)arg;
 
 	if (!block)
                 return -ENODEV;
@@ -414,7 +415,7 @@ dasd_do_ioctl(struct block_device *bdev,
 	case BIODASDCMFDISABLE:
 		return disable_cmf(block->base->cdev);
 	case BIODASDREADALLCMB:
-		return dasd_ioctl_readall_cmb(block, cmd, arg);
+		return dasd_ioctl_readall_cmb(block, cmd, argp);
 	default:
 		/* if the discipline has an ioctl method try it. */
 		if (block->base->discipline->ioctl) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_proc.c linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_proc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dasd_proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dasd_proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -14,6 +14,7 @@
 #define KMSG_COMPONENT "dasd"
 
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>
@@ -71,7 +72,7 @@ dasd_devices_show(struct seq_file *m, vo
 	/* Print device number. */
 	seq_printf(m, "%s", dev_name(&device->cdev->dev));
 	/* Print discipline string. */
-	if (device != NULL && device->discipline != NULL)
+	if (device->discipline != NULL)
 		seq_printf(m, "(%s)", device->discipline->name);
 	else
 		seq_printf(m, "(none)");
@@ -91,10 +92,7 @@ dasd_devices_show(struct seq_file *m, vo
 	substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " ";
 	seq_printf(m, "%4s: ", substr);
 	/* Print device status information. */
-	switch ((device != NULL) ? device->state : -1) {
-	case -1:
-		seq_printf(m, "unknown");
-		break;
+	switch (device->state) {
 	case DASD_STATE_NEW:
 		seq_printf(m, "new");
 		break;
@@ -215,7 +213,7 @@ dasd_statistics_read(char *page, char **
 	}
 
 	prof = &dasd_global_profile;
-	/* prevent couter 'overflow' on output */
+	/* prevent counter 'overflow' on output */
 	for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999;
 	     factor *= 10);
 
@@ -272,10 +270,10 @@ dasd_statistics_write(struct file *file,
 	DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer);
 
 	/* check for valid verbs */
-	for (str = buffer; isspace(*str); str++);
+	str = skip_spaces(buffer);
 	if (strncmp(str, "set", 3) == 0 && isspace(str[3])) {
 		/* 'set xxx' was given */
-		for (str = str + 4; isspace(*str); str++);
+		str = skip_spaces(str + 4);
 		if (strcmp(str, "on") == 0) {
 			/* switch on statistics profiling */
 			dasd_profile_level = DASD_PROFILE_ON;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/dcssblk.c linux-libre-2.6.33-gnu1/drivers/s390/block/dcssblk.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/dcssblk.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/dcssblk.c	2010-02-24 13:52:17.000000000 -0500
@@ -1005,7 +1005,7 @@ static int dcssblk_thaw(struct device *d
 	return 0;
 }
 
-static struct dev_pm_ops dcssblk_pm_ops = {
+static const struct dev_pm_ops dcssblk_pm_ops = {
 	.freeze		= dcssblk_freeze,
 	.thaw		= dcssblk_thaw,
 	.restore	= dcssblk_restore,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/block/xpram.c linux-libre-2.6.33-gnu1/drivers/s390/block/xpram.c
--- linux-libre-2.6.32-gnu1/drivers/s390/block/xpram.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/block/xpram.c	2010-02-24 13:52:17.000000000 -0500
@@ -407,7 +407,7 @@ static int xpram_restore(struct device *
 	return 0;
 }
 
-static struct dev_pm_ops xpram_pm_ops = {
+static const struct dev_pm_ops xpram_pm_ops = {
 	.restore	= xpram_restore,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/con3215.c linux-libre-2.6.33-gnu1/drivers/s390/char/con3215.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/con3215.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/con3215.c	2010-02-24 13:52:17.000000000 -0500
@@ -857,7 +857,6 @@ static struct console con3215 = {
 
 /*
  * 3215 console initialization code called from console_init().
- * NOTE: This is called before kmalloc is available.
  */
 static int __init con3215_init(void)
 {
@@ -1038,22 +1037,6 @@ static void tty3215_flush_buffer(struct
 }
 
 /*
- * Currently we don't have any io controls for 3215 ttys
- */
-static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
-			 unsigned int cmd, unsigned long arg)
-{
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	switch (cmd) {
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
-/*
  * Disable reading from a 3215 tty
  */
 static void tty3215_throttle(struct tty_struct * tty)
@@ -1118,7 +1101,6 @@ static const struct tty_operations tty32
 	.write_room = tty3215_write_room,
 	.chars_in_buffer = tty3215_chars_in_buffer,
 	.flush_buffer = tty3215_flush_buffer,
-	.ioctl = tty3215_ioctl,
 	.throttle = tty3215_throttle,
 	.unthrottle = tty3215_unthrottle,
 	.stop = tty3215_stop,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/con3270.c linux-libre-2.6.33-gnu1/drivers/s390/char/con3270.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/con3270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/con3270.c	2010-02-24 13:52:17.000000000 -0500
@@ -572,7 +572,6 @@ static struct console con3270 = {
 
 /*
  * 3270 console initialization code called from console_init().
- * NOTE: This is called before kmalloc is available.
  */
 static int __init
 con3270_init(void)
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/fs3270.c linux-libre-2.6.33-gnu1/drivers/s390/char/fs3270.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/fs3270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/fs3270.c	2010-02-24 13:52:17.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/smp_lock.h>
 
+#include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
 #include <asm/ebcdic.h>
@@ -38,6 +39,8 @@ struct fs3270 {
 	size_t rdbuf_size;		/* size of data returned by RDBUF */
 };
 
+static DEFINE_MUTEX(fs3270_mutex);
+
 static void
 fs3270_wake_up(struct raw3270_request *rq, void *data)
 {
@@ -74,7 +77,7 @@ fs3270_do_io(struct raw3270_view *view,
 		}
 		rc = raw3270_start(view, rq);
 		if (rc == 0) {
-			/* Started sucessfully. Now wait for completion. */
+			/* Started successfully. Now wait for completion. */
 			wait_event(fp->wait, raw3270_request_final(rq));
 		}
 	} while (rc == -EACCES);
@@ -320,6 +323,7 @@ fs3270_write(struct file *filp, const ch
 static long
 fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+	char __user *argp;
 	struct fs3270 *fp;
 	struct raw3270_iocb iocb;
 	int rc;
@@ -327,8 +331,12 @@ fs3270_ioctl(struct file *filp, unsigned
 	fp = filp->private_data;
 	if (!fp)
 		return -ENODEV;
+	if (is_compat_task())
+		argp = compat_ptr(arg);
+	else
+		argp = (char __user *)arg;
 	rc = 0;
-	lock_kernel();
+	mutex_lock(&fs3270_mutex);
 	switch (cmd) {
 	case TUBICMD:
 		fp->read_command = arg;
@@ -337,10 +345,10 @@ fs3270_ioctl(struct file *filp, unsigned
 		fp->write_command = arg;
 		break;
 	case TUBGETI:
-		rc = put_user(fp->read_command, (char __user *) arg);
+		rc = put_user(fp->read_command, argp);
 		break;
 	case TUBGETO:
-		rc = put_user(fp->write_command,(char __user *) arg);
+		rc = put_user(fp->write_command, argp);
 		break;
 	case TUBGETMOD:
 		iocb.model = fp->view.model;
@@ -349,12 +357,11 @@ fs3270_ioctl(struct file *filp, unsigned
 		iocb.pf_cnt = 24;
 		iocb.re_cnt = 20;
 		iocb.map = 0;
-		if (copy_to_user((char __user *) arg, &iocb,
-				 sizeof(struct raw3270_iocb)))
+		if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb)))
 			rc = -EFAULT;
 		break;
 	}
-	unlock_kernel();
+	mutex_unlock(&fs3270_mutex);
 	return rc;
 }
 
@@ -437,7 +444,7 @@ fs3270_open(struct inode *inode, struct
 		minor = tty->index + RAW3270_FIRSTMINOR;
 		tty_kref_put(tty);
 	}
-	lock_kernel();
+	mutex_lock(&fs3270_mutex);
 	/* Check if some other program is already using fullscreen mode. */
 	fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
 	if (!IS_ERR(fp)) {
@@ -465,7 +472,7 @@ fs3270_open(struct inode *inode, struct
 	if (IS_ERR(ib)) {
 		raw3270_put_view(&fp->view);
 		raw3270_del_view(&fp->view);
-		rc = PTR_ERR(fp);
+		rc = PTR_ERR(ib);
 		goto out;
 	}
 	fp->rdbuf = ib;
@@ -478,7 +485,7 @@ fs3270_open(struct inode *inode, struct
 	}
 	filp->private_data = fp;
 out:
-	unlock_kernel();
+	mutex_unlock(&fs3270_mutex);
 	return rc;
 }
 
@@ -509,8 +516,8 @@ static const struct file_operations fs32
 	.write		 = fs3270_write,	/* write */
 	.unlocked_ioctl	 = fs3270_ioctl,	/* ioctl */
 	.compat_ioctl	 = fs3270_ioctl,	/* ioctl */
-	.open	 	= fs3270_open,		/* open */
-	.release 	= fs3270_close,		/* release */
+	.open		 = fs3270_open,		/* open */
+	.release	 = fs3270_close,	/* release */
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/monreader.c linux-libre-2.6.33-gnu1/drivers/s390/char/monreader.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/monreader.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/monreader.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -283,7 +282,6 @@ static int mon_open(struct inode *inode,
 	/*
 	 * only one user allowed
 	 */
-	lock_kernel();
 	rc = -EBUSY;
 	if (test_and_set_bit(MON_IN_USE, &mon_in_use))
 		goto out;
@@ -321,7 +319,6 @@ static int mon_open(struct inode *inode,
 	}
 	filp->private_data = monpriv;
 	dev_set_drvdata(monreader_device, monpriv);
-	unlock_kernel();
 	return nonseekable_open(inode, filp);
 
 out_path:
@@ -331,7 +328,6 @@ out_priv:
 out_use:
 	clear_bit(MON_IN_USE, &mon_in_use);
 out:
-	unlock_kernel();
 	return rc;
 }
 
@@ -533,7 +529,7 @@ static int monreader_restore(struct devi
 	return monreader_thaw(dev);
 }
 
-static struct dev_pm_ops monreader_pm_ops = {
+static const struct dev_pm_ops monreader_pm_ops = {
 	.freeze  = monreader_freeze,
 	.thaw	 = monreader_thaw,
 	.restore = monreader_restore,
@@ -607,6 +603,10 @@ static int __init mon_init(void)
 	}
 	dcss_mkname(mon_dcss_name, &user_data_connect[8]);
 
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	rc = misc_register(&mon_dev);
 	if (rc < 0 )
 		goto out;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/monwriter.c linux-libre-2.6.33-gnu1/drivers/s390/char/monwriter.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/monwriter.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/monwriter.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,7 +13,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -185,13 +184,11 @@ static int monwrite_open(struct inode *i
 	monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
 	if (!monpriv)
 		return -ENOMEM;
-	lock_kernel();
 	INIT_LIST_HEAD(&monpriv->list);
 	monpriv->hdr_to_read = sizeof(monpriv->hdr);
 	mutex_init(&monpriv->thread_mutex);
 	filp->private_data = monpriv;
 	list_add_tail(&monpriv->priv_list, &mon_priv_list);
-	unlock_kernel();
 	return nonseekable_open(inode, filp);
 }
 
@@ -326,7 +323,7 @@ static int monwriter_thaw(struct device
 	return monwriter_restore(dev);
 }
 
-static struct dev_pm_ops monwriter_pm_ops = {
+static const struct dev_pm_ops monwriter_pm_ops = {
 	.freeze		= monwriter_freeze,
 	.thaw		= monwriter_thaw,
 	.restore	= monwriter_restore,
@@ -364,6 +361,10 @@ static int __init mon_init(void)
 		goto out_driver;
 	}
 
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	rc = misc_register(&mon_dev);
 	if (rc)
 		goto out_device;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_async.c linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_async.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_async.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_async.c	2010-02-24 13:52:17.000000000 -0500
@@ -101,18 +101,17 @@ static struct ctl_table callhome_table[]
 		.mode		= 0644,
 		.proc_handler	= proc_handler_callhome,
 	},
-	{ .ctl_name = 0 }
+	{}
 };
 
 static struct ctl_table kern_dir_table[] = {
 	{
-		.ctl_name	= CTL_KERN,
 		.procname	= "kernel",
 		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= callhome_table,
 	},
-	{ .ctl_name = 0 }
+	{}
 };
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/sclp.c linux-libre-2.6.33-gnu1/drivers/s390/char/sclp.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/sclp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/sclp.c	2010-02-24 13:52:17.000000000 -0500
@@ -1019,7 +1019,7 @@ static int sclp_restore(struct device *d
 	return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE);
 }
 
-static struct dev_pm_ops sclp_pm_ops = {
+static const struct dev_pm_ops sclp_pm_ops = {
 	.freeze		= sclp_freeze,
 	.thaw		= sclp_thaw,
 	.restore	= sclp_restore,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_cmd.c linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_cmd.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_cmd.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_cmd.c	2010-02-24 13:52:17.000000000 -0500
@@ -84,6 +84,7 @@ static void __init sclp_read_info_early(
 		do {
 			memset(sccb, 0, sizeof(*sccb));
 			sccb->header.length = sizeof(*sccb);
+			sccb->header.function_code = 0x80;
 			sccb->header.control_mask[2] = 0x80;
 			rc = sclp_cmd_sync_early(commands[i], sccb);
 		} while (rc == -EBUSY);
@@ -546,7 +547,7 @@ struct read_storage_sccb {
 	u32 entries[0];
 } __packed;
 
-static struct dev_pm_ops sclp_mem_pm_ops = {
+static const struct dev_pm_ops sclp_mem_pm_ops = {
 	.freeze		= sclp_mem_freeze,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_vt220.c linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_vt220.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/sclp_vt220.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/sclp_vt220.c	2010-02-24 13:52:17.000000000 -0500
@@ -495,6 +495,10 @@ sclp_vt220_open(struct tty_struct *tty,
 		if (tty->driver_data == NULL)
 			return -ENOMEM;
 		tty->low_latency = 0;
+		if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+			tty->winsize.ws_row = 24;
+			tty->winsize.ws_col = 80;
+		}
 	}
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_34xx.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_34xx.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_34xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_34xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
  */
 
 #define KMSG_COMPONENT "tape_34xx"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -113,16 +114,16 @@ tape_34xx_work_handler(struct work_struc
 {
 	struct tape_34xx_work *p =
 		container_of(work, struct tape_34xx_work, work);
+	struct tape_device *device = p->device;
 
 	switch(p->op) {
 		case TO_MSEN:
-			tape_34xx_medium_sense(p->device);
+			tape_34xx_medium_sense(device);
 			break;
 		default:
 			DBF_EVENT(3, "T34XX: internal error: unknown work\n");
 	}
-
-	p->device = tape_put_device(p->device);
+	tape_put_device(device);
 	kfree(p);
 }
 
@@ -136,7 +137,7 @@ tape_34xx_schedule_work(struct tape_devi
 
 	INIT_WORK(&p->work, tape_34xx_work_handler);
 
-	p->device = tape_get_device_reference(device);
+	p->device = tape_get_device(device);
 	p->op     = op;
 
 	schedule_work(&p->work);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_3590.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_3590.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_3590.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_3590.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,6 +9,7 @@
  */
 
 #define KMSG_COMPONENT "tape_3590"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -136,7 +137,7 @@ static void int_to_ext_kekl(struct tape3
 		out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
 	memcpy(out->label, in->label, sizeof(in->label));
 	EBCASC(out->label, sizeof(in->label));
-	strstrip(out->label);
+	strim(out->label);
 }
 
 static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
@@ -608,7 +609,7 @@ tape_3590_schedule_work(struct tape_devi
 
 	INIT_WORK(&p->work, tape_3590_work_handler);
 
-	p->device = tape_get_device_reference(device);
+	p->device = tape_get_device(device);
 	p->op = op;
 
 	schedule_work(&p->work);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_block.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_block.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_block.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_block.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
  */
 
 #define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/fs.h>
 #include <linux/module.h>
@@ -45,8 +46,6 @@
  */
 static int tapeblock_open(struct block_device *, fmode_t);
 static int tapeblock_release(struct gendisk *, fmode_t);
-static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int,
-				unsigned long);
 static int tapeblock_medium_changed(struct gendisk *);
 static int tapeblock_revalidate_disk(struct gendisk *);
 
@@ -54,7 +53,6 @@ static const struct block_device_operati
 	.owner		 = THIS_MODULE,
 	.open		 = tapeblock_open,
 	.release	 = tapeblock_release,
-	.locked_ioctl           = tapeblock_ioctl,
 	.media_changed   = tapeblock_medium_changed,
 	.revalidate_disk = tapeblock_revalidate_disk,
 };
@@ -239,7 +237,7 @@ tapeblock_setup_device(struct tape_devic
 	disk->major = tapeblock_major;
 	disk->first_minor = device->first_minor;
 	disk->fops = &tapeblock_fops;
-	disk->private_data = tape_get_device_reference(device);
+	disk->private_data = tape_get_device(device);
 	disk->queue = blkdat->request_queue;
 	set_capacity(disk, 0);
 	sprintf(disk->disk_name, "btibm%d",
@@ -247,11 +245,11 @@ tapeblock_setup_device(struct tape_devic
 
 	blkdat->disk = disk;
 	blkdat->medium_changed = 1;
-	blkdat->request_queue->queuedata = tape_get_device_reference(device);
+	blkdat->request_queue->queuedata = tape_get_device(device);
 
 	add_disk(disk);
 
-	tape_get_device_reference(device);
+	tape_get_device(device);
 	INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
 
 	return 0;
@@ -274,13 +272,14 @@ tapeblock_cleanup_device(struct tape_dev
 	}
 
 	del_gendisk(device->blk_data.disk);
-	device->blk_data.disk->private_data =
-		tape_put_device(device->blk_data.disk->private_data);
+	device->blk_data.disk->private_data = NULL;
+	tape_put_device(device);
 	put_disk(device->blk_data.disk);
 
 	device->blk_data.disk = NULL;
 cleanup_queue:
-	device->blk_data.request_queue->queuedata = tape_put_device(device);
+	device->blk_data.request_queue->queuedata = NULL;
+	tape_put_device(device);
 
 	blk_cleanup_queue(device->blk_data.request_queue);
 	device->blk_data.request_queue = NULL;
@@ -363,7 +362,7 @@ tapeblock_open(struct block_device *bdev
 	struct tape_device *	device;
 	int			rc;
 
-	device = tape_get_device_reference(disk->private_data);
+	device = tape_get_device(disk->private_data);
 
 	if (device->required_tapemarks) {
 		DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
@@ -414,42 +413,6 @@ tapeblock_release(struct gendisk *disk,
 }
 
 /*
- * Support of some generic block device IOCTLs.
- */
-static int
-tapeblock_ioctl(
-	struct block_device *	bdev,
-	fmode_t			mode,
-	unsigned int		command,
-	unsigned long		arg
-) {
-	int rc;
-	int minor;
-	struct gendisk *disk = bdev->bd_disk;
-	struct tape_device *device;
-
-	rc     = 0;
-	BUG_ON(!disk);
-	device = disk->private_data;
-	BUG_ON(!device);
-	minor  = MINOR(bdev->bd_dev);
-
-	DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command);
-	DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor);
-
-	switch (command) {
-		/* Refuse some IOCTL calls without complaining (mount). */
-		case 0x5310:		/* CDROMMULTISESSION */
-			rc = -EINVAL;
-			break;
-		default:
-			rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-/*
  * Initialize block device frontend.
  */
 int
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_char.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_char.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_char.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_char.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,11 +10,15 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/mtio.h>
 #include <linux/smp_lock.h>
+#include <linux/compat.h>
 
 #include <asm/uaccess.h>
 
@@ -33,18 +37,20 @@ static ssize_t tapechar_read(struct file
 static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
 static int tapechar_open(struct inode *,struct file *);
 static int tapechar_release(struct inode *,struct file *);
-static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
-			  unsigned long);
-static long tapechar_compat_ioctl(struct file *, unsigned int,
-			  unsigned long);
+static long tapechar_ioctl(struct file *, unsigned int, unsigned long);
+#ifdef CONFIG_COMPAT
+static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long);
+#endif
 
 static const struct file_operations tape_fops =
 {
 	.owner = THIS_MODULE,
 	.read = tapechar_read,
 	.write = tapechar_write,
-	.ioctl = tapechar_ioctl,
+	.unlocked_ioctl = tapechar_ioctl,
+#ifdef CONFIG_COMPAT
 	.compat_ioctl = tapechar_compat_ioctl,
+#endif
 	.open = tapechar_open,
 	.release = tapechar_release,
 };
@@ -170,7 +176,6 @@ tapechar_read(struct file *filp, char __
 	if (rc == 0) {
 		rc = block_size - request->rescnt;
 		DBF_EVENT(6, "TCHAR:rbytes:  %x\n", rc);
-		filp->f_pos += rc;
 		/* Copy data from idal buffer to user space. */
 		if (idal_buffer_to_user(device->char_data.idal_buf,
 					data, rc) != 0)
@@ -238,7 +243,6 @@ tapechar_write(struct file *filp, const
 			break;
 		DBF_EVENT(6, "TCHAR:wbytes: %lx\n",
 			  block_size - request->rescnt);
-		filp->f_pos += block_size - request->rescnt;
 		written += block_size - request->rescnt;
 		if (request->rescnt != 0)
 			break;
@@ -286,26 +290,20 @@ tapechar_open (struct inode *inode, stru
 	if (imajor(filp->f_path.dentry->d_inode) != tapechar_major)
 		return -ENODEV;
 
-	lock_kernel();
 	minor = iminor(filp->f_path.dentry->d_inode);
-	device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
+	device = tape_find_device(minor / TAPE_MINORS_PER_DEV);
 	if (IS_ERR(device)) {
-		DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n");
-		rc = PTR_ERR(device);
-		goto out;
+		DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n");
+		return PTR_ERR(device);
 	}
 
-
 	rc = tape_open(device);
 	if (rc == 0) {
 		filp->private_data = device;
-		rc = nonseekable_open(inode, filp);
-	}
-	else
+		nonseekable_open(inode, filp);
+	} else
 		tape_put_device(device);
 
-out:
-	unlock_kernel();
 	return rc;
 }
 
@@ -342,7 +340,8 @@ tapechar_release(struct inode *inode, st
 		device->char_data.idal_buf = NULL;
 	}
 	tape_release(device);
-	filp->private_data = tape_put_device(device);
+	filp->private_data = NULL;
+	tape_put_device(device);
 
 	return 0;
 }
@@ -351,16 +350,11 @@ tapechar_release(struct inode *inode, st
  * Tape device io controls.
  */
 static int
-tapechar_ioctl(struct inode *inp, struct file *filp,
-	       unsigned int no, unsigned long data)
+__tapechar_ioctl(struct tape_device *device,
+		 unsigned int no, unsigned long data)
 {
-	struct tape_device *device;
 	int rc;
 
-	DBF_EVENT(6, "TCHAR:ioct\n");
-
-	device = (struct tape_device *) filp->private_data;
-
 	if (no == MTIOCTOP) {
 		struct mtop op;
 
@@ -453,21 +447,44 @@ tapechar_ioctl(struct inode *inp, struct
 }
 
 static long
+tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data)
+{
+	struct tape_device *device;
+	long rc;
+
+	DBF_EVENT(6, "TCHAR:ioct\n");
+
+	device = (struct tape_device *) filp->private_data;
+	mutex_lock(&device->mutex);
+	rc = __tapechar_ioctl(device, no, data);
+	mutex_unlock(&device->mutex);
+	return rc;
+}
+
+#ifdef CONFIG_COMPAT
+static long
 tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data)
 {
 	struct tape_device *device = filp->private_data;
 	int rval = -ENOIOCTLCMD;
+	unsigned long argp;
 
+	/* The 'arg' argument of any ioctl function may only be used for
+	 * pointers because of the compat pointer conversion.
+	 * Consider this when adding new ioctls.
+	 */
+	argp = (unsigned long) compat_ptr(data);
 	if (device->discipline->ioctl_fn) {
-		lock_kernel();
-		rval = device->discipline->ioctl_fn(device, no, data);
-		unlock_kernel();
+		mutex_lock(&device->mutex);
+		rval = device->discipline->ioctl_fn(device, no, argp);
+		mutex_unlock(&device->mutex);
 		if (rval == -EINVAL)
 			rval = -ENOIOCTLCMD;
 	}
 
 	return rval;
 }
+#endif /* CONFIG_COMPAT */
 
 /*
  * Initialize character device frontend.
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_class.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_class.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_class.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_class.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,10 @@
  * Author: Stefan Bader <shbader@de.ibm.com>
  * Based on simple class device code by Greg K-H
  */
+
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include "tape_class.h"
 
 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_core.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_core.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,8 @@
  */
 
 #define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>	     // for kernel parameters
 #include <linux/kmod.h>	     // for requesting modules
@@ -492,6 +494,7 @@ tape_alloc_device(void)
 		kfree(device);
 		return ERR_PTR(-ENOMEM);
 	}
+	mutex_init(&device->mutex);
 	INIT_LIST_HEAD(&device->req_queue);
 	INIT_LIST_HEAD(&device->node);
 	init_waitqueue_head(&device->state_change_wq);
@@ -511,11 +514,12 @@ tape_alloc_device(void)
  * increment the reference count.
  */
 struct tape_device *
-tape_get_device_reference(struct tape_device *device)
+tape_get_device(struct tape_device *device)
 {
-	DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device,
-		atomic_inc_return(&device->ref_count));
+	int count;
 
+	count = atomic_inc_return(&device->ref_count);
+	DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count);
 	return device;
 }
 
@@ -525,32 +529,25 @@ tape_get_device_reference(struct tape_de
  * The function returns a NULL pointer to be used by the caller
  * for clearing reference pointers.
  */
-struct tape_device *
+void
 tape_put_device(struct tape_device *device)
 {
-	int remain;
+	int count;
 
-	remain = atomic_dec_return(&device->ref_count);
-	if (remain > 0) {
-		DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain);
-	} else {
-		if (remain < 0) {
-			DBF_EVENT(4, "put device without reference\n");
-		} else {
-			DBF_EVENT(4, "tape_free_device(%p)\n", device);
-			kfree(device->modeset_byte);
-			kfree(device);
-		}
+	count = atomic_dec_return(&device->ref_count);
+	DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count);
+	BUG_ON(count < 0);
+	if (count == 0) {
+		kfree(device->modeset_byte);
+		kfree(device);
 	}
-
-	return NULL;			
 }
 
 /*
  * Find tape device by a device index.
  */
 struct tape_device *
-tape_get_device(int devindex)
+tape_find_device(int devindex)
 {
 	struct tape_device *device, *tmp;
 
@@ -558,7 +555,7 @@ tape_get_device(int devindex)
 	read_lock(&tape_device_lock);
 	list_for_each_entry(tmp, &tape_device_list, node) {
 		if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
-			device = tape_get_device_reference(tmp);
+			device = tape_get_device(tmp);
 			break;
 		}
 	}
@@ -579,7 +576,8 @@ tape_generic_probe(struct ccw_device *cd
 	device = tape_alloc_device();
 	if (IS_ERR(device))
 		return -ENODEV;
-	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+	ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP |
+				     CCWDEV_DO_MULTIPATH);
 	ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
 	if (ret) {
 		tape_put_device(device);
@@ -606,7 +604,8 @@ __tape_discard_requests(struct tape_devi
 		list_del(&request->list);
 
 		/* Decrease ref_count for removed request. */
-		request->device = tape_put_device(device);
+		request->device = NULL;
+		tape_put_device(device);
 		request->rc = -EIO;
 		if (request->callback != NULL)
 			request->callback(request, request->callback_data);
@@ -664,9 +663,11 @@ tape_generic_remove(struct ccw_device *c
 			tape_cleanup_device(device);
 	}
 
-	if (!dev_get_drvdata(&cdev->dev)) {
+	device = dev_get_drvdata(&cdev->dev);
+	if (device) {
 		sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
-		dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev)));
+		dev_set_drvdata(&cdev->dev, NULL);
+		tape_put_device(device);
 	}
 }
 
@@ -721,9 +722,8 @@ tape_free_request (struct tape_request *
 {
 	DBF_LH(6, "Free request %p\n", request);
 
-	if (request->device != NULL) {
-		request->device = tape_put_device(request->device);
-	}
+	if (request->device)
+		tape_put_device(request->device);
 	kfree(request->cpdata);
 	kfree(request->cpaddr);
 	kfree(request);
@@ -838,7 +838,8 @@ static void tape_long_busy_timeout(unsig
 	BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
 	DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
 	__tape_start_next_request(device);
-	device->lb_timeout.data = (unsigned long) tape_put_device(device);
+	device->lb_timeout.data = 0UL;
+	tape_put_device(device);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 }
 
@@ -918,7 +919,7 @@ __tape_start_request(struct tape_device
 	}
 
 	/* Increase use count of device for the added request. */
-	request->device = tape_get_device_reference(device);
+	request->device = tape_get_device(device);
 
 	if (list_empty(&device->req_queue)) {
 		/* No other requests are on the queue. Start this one. */
@@ -1117,8 +1118,8 @@ __tape_do_irq (struct ccw_device *cdev,
 		if (req->status == TAPE_REQUEST_LONG_BUSY) {
 			DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id);
 			if (del_timer(&device->lb_timeout)) {
-				device->lb_timeout.data = (unsigned long)
-					tape_put_device(device);
+				device->lb_timeout.data = 0UL;
+				tape_put_device(device);
 				__tape_start_next_request(device);
 			}
 			return;
@@ -1173,7 +1174,7 @@ __tape_do_irq (struct ccw_device *cdev,
 			break;
 		case TAPE_IO_LONG_BUSY:
 			device->lb_timeout.data =
-				(unsigned long)tape_get_device_reference(device);
+				(unsigned long) tape_get_device(device);
 			device->lb_timeout.expires = jiffies +
 				LONG_BUSY_TIMEOUT * HZ;
 			DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id);
@@ -1326,7 +1327,7 @@ EXPORT_SYMBOL(tape_generic_online);
 EXPORT_SYMBOL(tape_generic_offline);
 EXPORT_SYMBOL(tape_generic_pm_suspend);
 EXPORT_SYMBOL(tape_put_device);
-EXPORT_SYMBOL(tape_get_device_reference);
+EXPORT_SYMBOL(tape_get_device);
 EXPORT_SYMBOL(tape_state_verbose);
 EXPORT_SYMBOL(tape_op_verbose);
 EXPORT_SYMBOL(tape_state_set);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape.h linux-libre-2.6.33-gnu1/drivers/s390/char/tape.h
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape.h	2010-02-24 13:52:17.000000000 -0500
@@ -212,6 +212,9 @@ struct tape_device {
 	struct tape_class_device *	nt;
 	struct tape_class_device *	rt;
 
+	/* Device mutex to serialize tape commands. */
+	struct mutex			mutex;
+
 	/* Device discipline information. */
 	struct tape_discipline *	discipline;
 	void *				discdata;
@@ -292,9 +295,9 @@ extern int tape_generic_pm_suspend(struc
 extern int tape_generic_probe(struct ccw_device *);
 extern void tape_generic_remove(struct ccw_device *);
 
-extern struct tape_device *tape_get_device(int devindex);
-extern struct tape_device *tape_get_device_reference(struct tape_device *);
-extern struct tape_device *tape_put_device(struct tape_device *);
+extern struct tape_device *tape_find_device(int devindex);
+extern struct tape_device *tape_get_device(struct tape_device *);
+extern void tape_put_device(struct tape_device *);
 
 /* Externals from tape_char.c */
 extern int tapechar_init(void);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_proc.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_proc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_proc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_proc.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,9 @@
  * PROCFS Functions
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/seq_file.h>
@@ -45,7 +48,7 @@ static int tape_proc_show(struct seq_fil
 		seq_printf(m, "TapeNo\tBusID      CuType/Model\t"
 			"DevType/Model\tBlkSize\tState\tOp\tMedState\n");
 	}
-	device = tape_get_device(n);
+	device = tape_find_device(n);
 	if (IS_ERR(device))
 		return 0;
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tape_std.c linux-libre-2.6.33-gnu1/drivers/s390/char/tape_std.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tape_std.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tape_std.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,9 @@
  *		 Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/bio.h>
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/tty3270.c linux-libre-2.6.33-gnu1/drivers/s390/char/tty3270.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/tty3270.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/tty3270.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/compat.h>
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
@@ -1731,6 +1732,22 @@ tty3270_ioctl(struct tty_struct *tty, st
 	return kbd_ioctl(tp->kbd, file, cmd, arg);
 }
 
+#ifdef CONFIG_COMPAT
+static long
+tty3270_compat_ioctl(struct tty_struct *tty, struct file *file,
+	      unsigned int cmd, unsigned long arg)
+{
+	struct tty3270 *tp;
+
+	tp = tty->driver_data;
+	if (!tp)
+		return -ENODEV;
+	if (tty->flags & (1 << TTY_IO_ERROR))
+		return -EIO;
+	return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
 static const struct tty_operations tty3270_ops = {
 	.open = tty3270_open,
 	.close = tty3270_close,
@@ -1745,6 +1762,9 @@ static const struct tty_operations tty32
 	.hangup = tty3270_hangup,
 	.wait_until_sent = tty3270_wait_until_sent,
 	.ioctl = tty3270_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = tty3270_compat_ioctl,
+#endif
 	.set_termios = tty3270_set_termios
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/vmcp.c linux-libre-2.6.33-gnu1/drivers/s390/char/vmcp.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/vmcp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/vmcp.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
+#include <asm/compat.h>
 #include <asm/cpcmd.h>
 #include <asm/debug.h>
 #include <asm/uaccess.h>
@@ -139,21 +140,26 @@ vmcp_write(struct file *file, const char
 static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct vmcp_session *session;
+	int __user *argp;
 	int temp;
 
 	session = (struct vmcp_session *)file->private_data;
+	if (is_compat_task())
+		argp = compat_ptr(arg);
+	else
+		argp = (int __user *)arg;
 	if (mutex_lock_interruptible(&session->mutex))
 		return -ERESTARTSYS;
 	switch (cmd) {
 	case VMCP_GETCODE:
 		temp = session->resp_code;
 		mutex_unlock(&session->mutex);
-		return put_user(temp, (int __user *)arg);
+		return put_user(temp, argp);
 	case VMCP_SETBUF:
 		free_pages((unsigned long)session->response,
 				get_order(session->bufsize));
 		session->response=NULL;
-		temp = get_user(session->bufsize, (int __user *)arg);
+		temp = get_user(session->bufsize, argp);
 		if (get_order(session->bufsize) > 8) {
 			session->bufsize = PAGE_SIZE;
 			temp = -EINVAL;
@@ -163,7 +169,7 @@ static long vmcp_ioctl(struct file *file
 	case VMCP_GETSIZE:
 		temp = session->resp_size;
 		mutex_unlock(&session->mutex);
-		return put_user(temp, (int __user *)arg);
+		return put_user(temp, argp);
 	default:
 		mutex_unlock(&session->mutex);
 		return -ENOIOCTLCMD;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/vmlogrdr.c linux-libre-2.6.33-gnu1/drivers/s390/char/vmlogrdr.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/vmlogrdr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/vmlogrdr.c	2010-02-24 13:52:17.000000000 -0500
@@ -312,11 +312,9 @@ static int vmlogrdr_open (struct inode *
 		return -ENOSYS;
 
 	/* Besure this device hasn't already been opened */
-	lock_kernel();
 	spin_lock_bh(&logptr->priv_lock);
 	if (logptr->dev_in_use)	{
 		spin_unlock_bh(&logptr->priv_lock);
-		unlock_kernel();
 		return -EBUSY;
 	}
 	logptr->dev_in_use = 1;
@@ -360,9 +358,8 @@ static int vmlogrdr_open (struct inode *
 		   || (logptr->iucv_path_severed));
 	if (logptr->iucv_path_severed)
 		goto out_record;
- 	ret = nonseekable_open(inode, filp);
-	unlock_kernel();
-	return ret;
+	nonseekable_open(inode, filp);
+	return 0;
 
 out_record:
 	if (logptr->autorecording)
@@ -372,7 +369,6 @@ out_path:
 	logptr->path = NULL;
 out_dev:
 	logptr->dev_in_use = 0;
-	unlock_kernel();
 	return -EIO;
 }
 
@@ -679,7 +675,7 @@ static int vmlogrdr_pm_prepare(struct de
 }
 
 
-static struct dev_pm_ops vmlogrdr_pm_ops = {
+static const struct dev_pm_ops vmlogrdr_pm_ops = {
 	.prepare = vmlogrdr_pm_prepare,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/vmur.c linux-libre-2.6.33-gnu1/drivers/s390/char/vmur.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/vmur.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/vmur.c	2010-02-24 13:52:17.000000000 -0500
@@ -695,7 +695,6 @@ static int ur_open(struct inode *inode,
 
 	if (accmode == O_RDWR)
 		return -EACCES;
-	lock_kernel();
 	/*
 	 * We treat the minor number as the devno of the ur device
 	 * to find in the driver tree.
@@ -749,7 +748,6 @@ static int ur_open(struct inode *inode,
 		goto fail_urfile_free;
 	urf->file_reclen = rc;
 	file->private_data = urf;
-	unlock_kernel();
 	return 0;
 
 fail_urfile_free:
@@ -761,7 +759,6 @@ fail_unlock:
 fail_put:
 	urdev_put(urd);
 out:
-	unlock_kernel();
 	return rc;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/char/vmwatchdog.c linux-libre-2.6.33-gnu1/drivers/s390/char/vmwatchdog.c
--- linux-libre-2.6.32-gnu1/drivers/s390/char/vmwatchdog.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/char/vmwatchdog.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,6 @@
 #include <linux/moduleparam.h>
 #include <linux/suspend.h>
 #include <linux/watchdog.h>
-#include <linux/smp_lock.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
@@ -49,6 +48,8 @@ static unsigned int vmwdt_interval = 60;
 static unsigned long vmwdt_is_open;
 static int vmwdt_expect_close;
 
+static DEFINE_MUTEX(vmwdt_mutex);
+
 #define VMWDT_OPEN	0	/* devnode is open or suspend in progress */
 #define VMWDT_RUNNING	1	/* The watchdog is armed */
 
@@ -133,15 +134,11 @@ static int __init vmwdt_probe(void)
 static int vmwdt_open(struct inode *i, struct file *f)
 {
 	int ret;
-	lock_kernel();
-	if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
-		unlock_kernel();
+	if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open))
 		return -EBUSY;
-	}
 	ret = vmwdt_keepalive();
 	if (ret)
 		clear_bit(VMWDT_OPEN, &vmwdt_is_open);
-	unlock_kernel();
 	return ret ? ret : nonseekable_open(i, f);
 }
 
@@ -160,8 +157,7 @@ static struct watchdog_info vmwdt_info =
 	.identity = "z/VM Watchdog Timer",
 };
 
-static int vmwdt_ioctl(struct inode *i, struct file *f,
-			  unsigned int cmd, unsigned long arg)
+static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg)
 {
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
@@ -205,10 +201,19 @@ static int vmwdt_ioctl(struct inode *i,
 	case WDIOC_KEEPALIVE:
 		return vmwdt_keepalive();
 	}
-
 	return -EINVAL;
 }
 
+static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+	int rc;
+
+	mutex_lock(&vmwdt_mutex);
+	rc = __vmwdt_ioctl(cmd, arg);
+	mutex_unlock(&vmwdt_mutex);
+	return (long) rc;
+}
+
 static ssize_t vmwdt_write(struct file *f, const char __user *buf,
 				size_t count, loff_t *ppos)
 {
@@ -288,7 +293,7 @@ static struct notifier_block vmwdt_power
 static const struct file_operations vmwdt_fops = {
 	.open    = &vmwdt_open,
 	.release = &vmwdt_close,
-	.ioctl   = &vmwdt_ioctl,
+	.unlocked_ioctl = &vmwdt_ioctl,
 	.write   = &vmwdt_write,
 	.owner   = THIS_MODULE,
 };
@@ -309,6 +314,10 @@ static int __init vmwdt_init(void)
 	ret = register_pm_notifier(&vmwdt_power_notifier);
 	if (ret)
 		return ret;
+	/*
+	 * misc_register() has to be the last action in module_init(), because
+	 * file operations will be available right after this.
+	 */
 	ret = misc_register(&vmwdt_dev);
 	if (ret) {
 		unregister_pm_notifier(&vmwdt_power_notifier);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/ccwgroup.c linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwgroup.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/ccwgroup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwgroup.c	2010-02-24 13:52:17.000000000 -0500
@@ -560,7 +560,7 @@ static int ccwgroup_pm_restore(struct de
 	return gdrv->restore ? gdrv->restore(gdev) : 0;
 }
 
-static struct dev_pm_ops ccwgroup_pm_ops = {
+static const struct dev_pm_ops ccwgroup_pm_ops = {
 	.prepare = ccwgroup_pm_prepare,
 	.complete = ccwgroup_pm_complete,
 	.freeze = ccwgroup_pm_freeze,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/ccwreq.c linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwreq.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/ccwreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/ccwreq.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,325 @@
+/*
+ *  Handling of internal CCW device requests.
+ *
+ *    Copyright IBM Corp. 2009
+ *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/err.h>
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
+
+#include "io_sch.h"
+#include "cio.h"
+#include "device.h"
+#include "cio_debug.h"
+
+/**
+ * lpm_adjust - adjust path mask
+ * @lpm: path mask to adjust
+ * @mask: mask of available paths
+ *
+ * Shift @lpm right until @lpm and @mask have at least one bit in common or
+ * until @lpm is zero. Return the resulting lpm.
+ */
+int lpm_adjust(int lpm, int mask)
+{
+	while (lpm && ((lpm & mask) == 0))
+		lpm >>= 1;
+	return lpm;
+}
+
+/*
+ * Adjust path mask to use next path and reset retry count. Return resulting
+ * path mask.
+ */
+static u16 ccwreq_next_path(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	req->retries	= req->maxretries;
+	req->mask	= lpm_adjust(req->mask >>= 1, req->lpm);
+
+	return req->mask;
+}
+
+/*
+ * Clean up device state and report to callback.
+ */
+static void ccwreq_stop(struct ccw_device *cdev, int rc)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	if (req->done)
+		return;
+	req->done = 1;
+	ccw_device_set_timeout(cdev, 0);
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+	if (rc && rc != -ENODEV && req->drc)
+		rc = req->drc;
+	req->callback(cdev, req->data, rc);
+}
+
+/*
+ * (Re-)Start the operation until retries and paths are exhausted.
+ */
+static void ccwreq_do(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw1 *cp = req->cp;
+	int rc = -EACCES;
+
+	while (req->mask) {
+		if (req->retries-- == 0) {
+			/* Retries exhausted, try next path. */
+			ccwreq_next_path(cdev);
+			continue;
+		}
+		/* Perform start function. */
+		memset(&cdev->private->irb, 0, sizeof(struct irb));
+		rc = cio_start(sch, cp, (u8) req->mask);
+		if (rc == 0) {
+			/* I/O started successfully. */
+			ccw_device_set_timeout(cdev, req->timeout);
+			return;
+		}
+		if (rc == -ENODEV) {
+			/* Permanent device error. */
+			break;
+		}
+		if (rc == -EACCES) {
+			/* Permant path error. */
+			ccwreq_next_path(cdev);
+			continue;
+		}
+		/* Temporary improper status. */
+		rc = cio_clear(sch);
+		if (rc)
+			break;
+		return;
+	}
+	ccwreq_stop(cdev, rc);
+}
+
+/**
+ * ccw_request_start - perform I/O request
+ * @cdev: ccw device
+ *
+ * Perform the I/O request specified by cdev->req.
+ */
+void ccw_request_start(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	/* Try all paths twice to counter link flapping. */
+	req->mask	= 0x8080;
+	req->retries	= req->maxretries;
+	req->mask	= lpm_adjust(req->mask, req->lpm);
+	req->drc	= 0;
+	req->done	= 0;
+	req->cancel	= 0;
+	if (!req->mask)
+		goto out_nopath;
+	ccwreq_do(cdev);
+	return;
+
+out_nopath:
+	ccwreq_stop(cdev, -EACCES);
+}
+
+/**
+ * ccw_request_cancel - cancel running I/O request
+ * @cdev: ccw device
+ *
+ * Cancel the I/O request specified by cdev->req. Return non-zero if request
+ * has already finished, zero otherwise.
+ */
+int ccw_request_cancel(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	int rc;
+
+	if (req->done)
+		return 1;
+	req->cancel = 1;
+	rc = cio_clear(sch);
+	if (rc)
+		ccwreq_stop(cdev, rc);
+	return 0;
+}
+
+/*
+ * Return the status of the internal I/O started on the specified ccw device.
+ * Perform BASIC SENSE if required.
+ */
+static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb)
+{
+	struct irb *irb = &cdev->private->irb;
+	struct cmd_scsw *scsw = &irb->scsw.cmd;
+
+	/* Perform BASIC SENSE if needed. */
+	if (ccw_device_accumulate_and_sense(cdev, lcirb))
+		return IO_RUNNING;
+	/* Check for halt/clear interrupt. */
+	if (scsw->fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+		return IO_KILLED;
+	/* Check for path error. */
+	if (scsw->cc == 3 || scsw->pno)
+		return IO_PATH_ERROR;
+	/* Handle BASIC SENSE data. */
+	if (irb->esw.esw0.erw.cons) {
+		CIO_TRACE_EVENT(2, "sensedata");
+		CIO_HEX_EVENT(2, &cdev->private->dev_id,
+			      sizeof(struct ccw_dev_id));
+		CIO_HEX_EVENT(2, &cdev->private->irb.ecw, SENSE_MAX_COUNT);
+		/* Check for command reject. */
+		if (irb->ecw[0] & SNS0_CMD_REJECT)
+			return IO_REJECTED;
+		/* Assume that unexpected SENSE data implies an error. */
+		return IO_STATUS_ERROR;
+	}
+	/* Check for channel errors. */
+	if (scsw->cstat != 0)
+		return IO_STATUS_ERROR;
+	/* Check for device errors. */
+	if (scsw->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+		return IO_STATUS_ERROR;
+	/* Check for final state. */
+	if (!(scsw->dstat & DEV_STAT_DEV_END))
+		return IO_RUNNING;
+	/* Check for other improper status. */
+	if (scsw->cc == 1 && (scsw->stctl & SCSW_STCTL_ALERT_STATUS))
+		return IO_STATUS_ERROR;
+	return IO_DONE;
+}
+
+/*
+ * Log ccw request status.
+ */
+static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct {
+		struct ccw_dev_id dev_id;
+		u16 retries;
+		u8 lpm;
+		u8 status;
+	}  __attribute__ ((packed)) data;
+	data.dev_id	= cdev->private->dev_id;
+	data.retries	= req->retries;
+	data.lpm	= (u8) req->mask;
+	data.status	= (u8) status;
+	CIO_TRACE_EVENT(2, "reqstat");
+	CIO_HEX_EVENT(2, &data, sizeof(data));
+}
+
+/**
+ * ccw_request_handler - interrupt handler for I/O request procedure.
+ * @cdev: ccw device
+ *
+ * Handle interrupt during I/O request procedure.
+ */
+void ccw_request_handler(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct irb *irb = (struct irb *) __LC_IRB;
+	enum io_status status;
+	int rc = -EOPNOTSUPP;
+
+	/* Check status of I/O request. */
+	status = ccwreq_status(cdev, irb);
+	if (req->filter)
+		status = req->filter(cdev, req->data, irb, status);
+	if (status != IO_RUNNING)
+		ccw_device_set_timeout(cdev, 0);
+	if (status != IO_DONE && status != IO_RUNNING)
+		ccwreq_log_status(cdev, status);
+	switch (status) {
+	case IO_DONE:
+		break;
+	case IO_RUNNING:
+		return;
+	case IO_REJECTED:
+		goto err;
+	case IO_PATH_ERROR:
+		goto out_next_path;
+	case IO_STATUS_ERROR:
+		goto out_restart;
+	case IO_KILLED:
+		/* Check if request was cancelled on purpose. */
+		if (req->cancel) {
+			rc = -EIO;
+			goto err;
+		}
+		goto out_restart;
+	}
+	/* Check back with request initiator. */
+	if (!req->check)
+		goto out;
+	switch (req->check(cdev, req->data)) {
+	case 0:
+		break;
+	case -EAGAIN:
+		goto out_restart;
+	case -EACCES:
+		goto out_next_path;
+	default:
+		goto err;
+	}
+out:
+	ccwreq_stop(cdev, 0);
+	return;
+
+out_next_path:
+	/* Try next path and restart I/O. */
+	if (!ccwreq_next_path(cdev)) {
+		rc = -EACCES;
+		goto err;
+	}
+out_restart:
+	/* Restart. */
+	ccwreq_do(cdev);
+	return;
+err:
+	ccwreq_stop(cdev, rc);
+}
+
+
+/**
+ * ccw_request_timeout - timeout handler for I/O request procedure
+ * @cdev: ccw device
+ *
+ * Handle timeout during I/O request procedure.
+ */
+void ccw_request_timeout(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	int rc;
+
+	if (!ccwreq_next_path(cdev)) {
+		/* set the final return code for this request */
+		req->drc = -ETIME;
+	}
+	rc = cio_clear(sch);
+	if (rc)
+		goto err;
+	return;
+
+err:
+	ccwreq_stop(cdev, rc);
+}
+
+/**
+ * ccw_request_notoper - notoper handler for I/O request procedure
+ * @cdev: ccw device
+ *
+ * Handle timeout during I/O request procedure.
+ */
+void ccw_request_notoper(struct ccw_device *cdev)
+{
+	ccwreq_stop(cdev, -ENODEV);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/chp.c linux-libre-2.6.33-gnu1/drivers/s390/cio/chp.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/chp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/chp.c	2010-02-24 13:52:17.000000000 -0500
@@ -65,7 +65,7 @@ static void set_chp_logically_online(str
 	chpid_to_chp(chpid)->state = onoff;
 }
 
-/* On succes return 0 if channel-path is varied offline, 1 if it is varied
+/* On success return 0 if channel-path is varied offline, 1 if it is varied
  * online. Return -ENODEV if channel-path is not registered. */
 int chp_get_status(struct chp_id chpid)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/chsc_sch.c linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc_sch.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/chsc_sch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/chsc_sch.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
 
+#include <asm/compat.h>
 #include <asm/cio.h>
 #include <asm/chsc.h>
 #include <asm/isc.h>
@@ -770,24 +771,30 @@ out_free:
 static long chsc_ioctl(struct file *filp, unsigned int cmd,
 		       unsigned long arg)
 {
+	void __user *argp;
+
 	CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd);
+	if (is_compat_task())
+		argp = compat_ptr(arg);
+	else
+		argp = (void __user *)arg;
 	switch (cmd) {
 	case CHSC_START:
-		return chsc_ioctl_start((void __user *)arg);
+		return chsc_ioctl_start(argp);
 	case CHSC_INFO_CHANNEL_PATH:
-		return chsc_ioctl_info_channel_path((void __user *)arg);
+		return chsc_ioctl_info_channel_path(argp);
 	case CHSC_INFO_CU:
-		return chsc_ioctl_info_cu((void __user *)arg);
+		return chsc_ioctl_info_cu(argp);
 	case CHSC_INFO_SCH_CU:
-		return chsc_ioctl_info_sch_cu((void __user *)arg);
+		return chsc_ioctl_info_sch_cu(argp);
 	case CHSC_INFO_CI:
-		return chsc_ioctl_conf_info((void __user *)arg);
+		return chsc_ioctl_conf_info(argp);
 	case CHSC_INFO_CCL:
-		return chsc_ioctl_conf_comp_list((void __user *)arg);
+		return chsc_ioctl_conf_comp_list(argp);
 	case CHSC_INFO_CPD:
-		return chsc_ioctl_chpd((void __user *)arg);
+		return chsc_ioctl_chpd(argp);
 	case CHSC_INFO_DCAL:
-		return chsc_ioctl_dcal((void __user *)arg);
+		return chsc_ioctl_dcal(argp);
 	default: /* unknown ioctl number */
 		return -ENOIOCTLCMD;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/cio.c linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/cio.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.c	2010-02-24 13:52:17.000000000 -0500
@@ -618,6 +618,7 @@ void __irq_entry do_IRQ(struct pt_regs *
 	old_regs = set_irq_regs(regs);
 	s390_idle_check();
 	irq_enter();
+	__get_cpu_var(s390_idle).nohz_delay = 1;
 	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/cio.h linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/cio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/cio.h	2010-02-24 13:52:17.000000000 -0500
@@ -68,6 +68,11 @@ struct schib {
 	__u8 mda[4];		 /* model dependent area */
 } __attribute__ ((packed,aligned(4)));
 
+enum sch_todo {
+	SCH_TODO_NOTHING,
+	SCH_TODO_UNREG,
+};
+
 /* subchannel data structure used by I/O subroutines */
 struct subchannel {
 	struct subchannel_id schid;
@@ -95,7 +100,8 @@ struct subchannel {
 	struct device dev;	/* entry in device tree */
 	struct css_driver *driver;
 	void *private; /* private per subchannel type data */
-	struct work_struct work;
+	enum sch_todo todo;
+	struct work_struct todo_work;
 	struct schib_config config;
 } __attribute__ ((aligned(8)));
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/cmf.c linux-libre-2.6.33-gnu1/drivers/s390/cio/cmf.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/cmf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/cmf.c	2010-02-24 13:52:17.000000000 -0500
@@ -462,7 +462,7 @@ static struct cmb_area cmb_area = {
  * block of memory, which can not be moved as long as any channel
  * is active. Therefore, a maximum number of subchannels needs to
  * be defined somewhere. This is a module parameter, defaulting to
- * a resonable value of 1024, or 32 kb of memory.
+ * a reasonable value of 1024, or 32 kb of memory.
  * Current kernels don't allow kmalloc with more than 128kb, so the
  * maximum is 4096.
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/css.c linux-libre-2.6.33-gnu1/drivers/s390/cio/css.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/css.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/css.c	2010-02-24 13:52:17.000000000 -0500
@@ -133,6 +133,8 @@ out:
 	return rc;
 }
 
+static void css_sch_todo(struct work_struct *work);
+
 static struct subchannel *
 css_alloc_subchannel(struct subchannel_id schid)
 {
@@ -147,6 +149,7 @@ css_alloc_subchannel(struct subchannel_i
 		kfree(sch);
 		return ERR_PTR(ret);
 	}
+	INIT_WORK(&sch->todo_work, css_sch_todo);
 	return sch;
 }
 
@@ -190,6 +193,51 @@ void css_sch_device_unregister(struct su
 }
 EXPORT_SYMBOL_GPL(css_sch_device_unregister);
 
+static void css_sch_todo(struct work_struct *work)
+{
+	struct subchannel *sch;
+	enum sch_todo todo;
+
+	sch = container_of(work, struct subchannel, todo_work);
+	/* Find out todo. */
+	spin_lock_irq(sch->lock);
+	todo = sch->todo;
+	CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
+		      sch->schid.sch_no, todo);
+	sch->todo = SCH_TODO_NOTHING;
+	spin_unlock_irq(sch->lock);
+	/* Perform todo. */
+	if (todo == SCH_TODO_UNREG)
+		css_sch_device_unregister(sch);
+	/* Release workqueue ref. */
+	put_device(&sch->dev);
+}
+
+/**
+ * css_sched_sch_todo - schedule a subchannel operation
+ * @sch: subchannel
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with subchannel lock held.
+ */
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
+{
+	CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
+		      sch->schid.ssid, sch->schid.sch_no, todo);
+	if (sch->todo >= todo)
+		return;
+	/* Get workqueue ref. */
+	if (!get_device(&sch->dev))
+		return;
+	sch->todo = todo;
+	if (!queue_work(slow_path_wq, &sch->todo_work)) {
+		/* Already queued, release workqueue ref. */
+		put_device(&sch->dev);
+	}
+}
+
 static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
 {
 	int i;
@@ -376,8 +424,8 @@ static int css_evaluate_new_subchannel(s
 		/* Unusable - ignore. */
 		return 0;
 	}
-	CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, unknown, "
-			 "slow path.\n", schid.ssid, schid.sch_no, CIO_OPER);
+	CIO_MSG_EVENT(4, "event: sch 0.%x.%04x, new\n", schid.ssid,
+		      schid.sch_no);
 
 	return css_probe_device(schid);
 }
@@ -394,6 +442,10 @@ static int css_evaluate_known_subchannel
 				"Got subchannel machine check but "
 				"no sch_event handler provided.\n");
 	}
+	if (ret != 0 && ret != -EAGAIN) {
+		CIO_MSG_EVENT(2, "eval: sch 0.%x.%04x, rc=%d\n",
+			      sch->schid.ssid, sch->schid.sch_no, ret);
+	}
 	return ret;
 }
 
@@ -684,6 +736,7 @@ static int __init setup_css(int nr)
 	css->pseudo_subchannel->dev.parent = &css->device;
 	css->pseudo_subchannel->dev.release = css_subchannel_release;
 	dev_set_name(&css->pseudo_subchannel->dev, "defunct");
+	mutex_init(&css->pseudo_subchannel->reg_mutex);
 	ret = cio_create_sch_lock(css->pseudo_subchannel);
 	if (ret) {
 		kfree(css->pseudo_subchannel);
@@ -1095,7 +1148,7 @@ static int css_pm_restore(struct device
 	return drv->restore ? drv->restore(sch) : 0;
 }
 
-static struct dev_pm_ops css_pm_ops = {
+static const struct dev_pm_ops css_pm_ops = {
 	.prepare = css_pm_prepare,
 	.complete = css_pm_complete,
 	.freeze = css_pm_freeze,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/css.h linux-libre-2.6.33-gnu1/drivers/s390/cio/css.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/css.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/css.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,8 @@
 #include <asm/chpid.h>
 #include <asm/schid.h>
 
+#include "cio.h"
+
 /*
  * path grouping stuff
  */
@@ -151,4 +153,5 @@ int css_sch_is_valid(struct schib *);
 
 extern struct workqueue_struct *slow_path_wq;
 void css_wait_for_slow_path(void);
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device.c	2010-02-24 13:52:17.000000000 -0500
@@ -7,6 +7,10 @@
  *		 Cornelia Huck (cornelia.huck@de.ibm.com)
  *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
+
+#define KMSG_COMPONENT "cio"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -299,53 +303,18 @@ int ccw_device_is_orphan(struct ccw_devi
 
 static void ccw_device_unregister(struct ccw_device *cdev)
 {
-	if (test_and_clear_bit(1, &cdev->private->registered)) {
+	if (device_is_registered(&cdev->dev)) {
+		/* Undo device_add(). */
 		device_del(&cdev->dev);
+	}
+	if (cdev->private->flags.initialized) {
+		cdev->private->flags.initialized = 0;
 		/* Release reference from device_initialize(). */
 		put_device(&cdev->dev);
 	}
 }
 
-static void ccw_device_remove_orphan_cb(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	ccw_device_unregister(cdev);
-	/* Release cdev reference for workqueue processing. */
-	put_device(&cdev->dev);
-}
-
-static void
-ccw_device_remove_disconnected(struct ccw_device *cdev)
-{
-	unsigned long flags;
-
-	/*
-	 * Forced offline in disconnected state means
-	 * 'throw away device'.
-	 */
-	if (ccw_device_is_orphan(cdev)) {
-		/*
-		 * Deregister ccw device.
-		 * Unfortunately, we cannot do this directly from the
-		 * attribute method.
-		 */
-		/* Get cdev reference for workqueue processing. */
-		if (!get_device(&cdev->dev))
-			return;
-		spin_lock_irqsave(cdev->ccwlock, flags);
-		cdev->private->state = DEV_STATE_NOT_OPER;
-		spin_unlock_irqrestore(cdev->ccwlock, flags);
-		PREPARE_WORK(&cdev->private->kick_work,
-				ccw_device_remove_orphan_cb);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-	} else
-		/* Deregister subchannel, which will kill the ccw device. */
-		ccw_device_schedule_sch_unregister(cdev);
-}
+static void io_subchannel_quiesce(struct subchannel *);
 
 /**
  * ccw_device_set_offline() - disable a ccw device for I/O
@@ -360,7 +329,8 @@ ccw_device_remove_disconnected(struct cc
  */
 int ccw_device_set_offline(struct ccw_device *cdev)
 {
-	int ret;
+	struct subchannel *sch;
+	int ret, state;
 
 	if (!cdev)
 		return -ENODEV;
@@ -374,6 +344,7 @@ int ccw_device_set_offline(struct ccw_de
 	}
 	cdev->online = 0;
 	spin_lock_irq(cdev->ccwlock);
+	sch = to_subchannel(cdev->dev.parent);
 	/* Wait until a final state or DISCONNECTED is reached */
 	while (!dev_fsm_final_state(cdev) &&
 	       cdev->private->state != DEV_STATE_DISCONNECTED) {
@@ -382,20 +353,37 @@ int ccw_device_set_offline(struct ccw_de
 			   cdev->private->state == DEV_STATE_DISCONNECTED));
 		spin_lock_irq(cdev->ccwlock);
 	}
-	ret = ccw_device_offline(cdev);
-	if (ret)
-		goto error;
+	do {
+		ret = ccw_device_offline(cdev);
+		if (!ret)
+			break;
+		CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device "
+			      "0.%x.%04x\n", ret, cdev->private->dev_id.ssid,
+			      cdev->private->dev_id.devno);
+		if (ret != -EBUSY)
+			goto error;
+		state = cdev->private->state;
+		spin_unlock_irq(cdev->ccwlock);
+		io_subchannel_quiesce(sch);
+		spin_lock_irq(cdev->ccwlock);
+		cdev->private->state = state;
+	} while (ret == -EBUSY);
 	spin_unlock_irq(cdev->ccwlock);
 	wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
 		   cdev->private->state == DEV_STATE_DISCONNECTED));
+	/* Inform the user if set offline failed. */
+	if (cdev->private->state == DEV_STATE_BOXED) {
+		pr_warning("%s: The device entered boxed state while "
+			   "being set offline\n", dev_name(&cdev->dev));
+	} else if (cdev->private->state == DEV_STATE_NOT_OPER) {
+		pr_warning("%s: The device stopped operating while "
+			   "being set offline\n", dev_name(&cdev->dev));
+	}
 	/* Give up reference from ccw_device_set_online(). */
 	put_device(&cdev->dev);
 	return 0;
 
 error:
-	CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device 0.%x.%04x\n",
-		      ret, cdev->private->dev_id.ssid,
-		      cdev->private->dev_id.devno);
 	cdev->private->state = DEV_STATE_OFFLINE;
 	dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 	spin_unlock_irq(cdev->ccwlock);
@@ -448,6 +436,16 @@ int ccw_device_set_online(struct ccw_dev
 	if ((cdev->private->state != DEV_STATE_ONLINE) &&
 	    (cdev->private->state != DEV_STATE_W4SENSE)) {
 		spin_unlock_irq(cdev->ccwlock);
+		/* Inform the user that set online failed. */
+		if (cdev->private->state == DEV_STATE_BOXED) {
+			pr_warning("%s: Setting the device online failed "
+				   "because it is boxed\n",
+				   dev_name(&cdev->dev));
+		} else if (cdev->private->state == DEV_STATE_NOT_OPER) {
+			pr_warning("%s: Setting the device online failed "
+				   "because it is not operational\n",
+				   dev_name(&cdev->dev));
+		}
 		/* Give up online reference since onlining failed. */
 		put_device(&cdev->dev);
 		return -ENODEV;
@@ -494,27 +492,22 @@ error:
 
 static int online_store_handle_offline(struct ccw_device *cdev)
 {
-	if (cdev->private->state == DEV_STATE_DISCONNECTED)
-		ccw_device_remove_disconnected(cdev);
-	else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+	if (cdev->private->state == DEV_STATE_DISCONNECTED) {
+		spin_lock_irq(cdev->ccwlock);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
+		spin_unlock_irq(cdev->ccwlock);
+	} else if (cdev->online && cdev->drv && cdev->drv->set_offline)
 		return ccw_device_set_offline(cdev);
 	return 0;
 }
 
 static int online_store_recog_and_online(struct ccw_device *cdev)
 {
-	int ret;
-
 	/* Do device recognition, if needed. */
 	if (cdev->private->state == DEV_STATE_BOXED) {
-		ret = ccw_device_recognition(cdev);
-		if (ret) {
-			CIO_MSG_EVENT(0, "Couldn't start recognition "
-				      "for device 0.%x.%04x (ret=%d)\n",
-				      cdev->private->dev_id.ssid,
-				      cdev->private->dev_id.devno, ret);
-			return ret;
-		}
+		spin_lock_irq(cdev->ccwlock);
+		ccw_device_recognition(cdev);
+		spin_unlock_irq(cdev->ccwlock);
 		wait_event(cdev->private->wait_q,
 			   cdev->private->flags.recog_done);
 		if (cdev->private->state != DEV_STATE_OFFLINE)
@@ -553,11 +546,10 @@ static ssize_t online_store (struct devi
 	int force, ret;
 	unsigned long i;
 
-	if ((cdev->private->state != DEV_STATE_OFFLINE &&
-	     cdev->private->state != DEV_STATE_ONLINE &&
-	     cdev->private->state != DEV_STATE_BOXED &&
-	     cdev->private->state != DEV_STATE_DISCONNECTED) ||
-	    atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+	if (!dev_fsm_final_state(cdev) &&
+	    cdev->private->state != DEV_STATE_DISCONNECTED)
+		return -EAGAIN;
+	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
 		return -EAGAIN;
 
 	if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -665,81 +657,31 @@ static int ccw_device_register(struct cc
 			   cdev->private->dev_id.devno);
 	if (ret)
 		return ret;
-	ret = device_add(dev);
-	if (ret)
-		return ret;
-
-	set_bit(1, &cdev->private->registered);
-	return ret;
-}
-
-struct match_data {
-	struct ccw_dev_id dev_id;
-	struct ccw_device * sibling;
-};
-
-static int
-match_devno(struct device * dev, void * data)
-{
-	struct match_data * d = data;
-	struct ccw_device * cdev;
-
-	cdev = to_ccwdev(dev);
-	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-	    !ccw_device_is_orphan(cdev) &&
-	    ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) &&
-	    (cdev != d->sibling))
-		return 1;
-	return 0;
-}
-
-static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
-						     struct ccw_device *sibling)
-{
-	struct device *dev;
-	struct match_data data;
-
-	data.dev_id = *dev_id;
-	data.sibling = sibling;
-	dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
-
-	return dev ? to_ccwdev(dev) : NULL;
+	return device_add(dev);
 }
 
-static int match_orphan(struct device *dev, void *data)
+static int match_dev_id(struct device *dev, void *data)
 {
-	struct ccw_dev_id *dev_id;
-	struct ccw_device *cdev;
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_dev_id *dev_id = data;
 
-	dev_id = data;
-	cdev = to_ccwdev(dev);
 	return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id);
 }
 
-static struct ccw_device *
-get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
-			      struct ccw_dev_id *dev_id)
+static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
 {
 	struct device *dev;
 
-	dev = device_find_child(&css->pseudo_subchannel->dev, dev_id,
-				match_orphan);
+	dev = bus_find_device(&ccw_bus_type, NULL, dev_id, match_dev_id);
 
 	return dev ? to_ccwdev(dev) : NULL;
 }
 
-void ccw_device_do_unbind_bind(struct work_struct *work)
+static void ccw_device_do_unbind_bind(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-	struct subchannel *sch;
 	int ret;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	sch = to_subchannel(cdev->dev.parent);
-
-	if (test_bit(1, &cdev->private->registered)) {
+	if (device_is_registered(&cdev->dev)) {
 		device_release_driver(&cdev->dev);
 		ret = device_attach(&cdev->dev);
 		WARN_ON(ret == -ENODEV);
@@ -773,6 +715,8 @@ static struct ccw_device * io_subchannel
 	return ERR_PTR(-ENOMEM);
 }
 
+static void ccw_device_todo(struct work_struct *work);
+
 static int io_subchannel_initialize_dev(struct subchannel *sch,
 					struct ccw_device *cdev)
 {
@@ -780,7 +724,7 @@ static int io_subchannel_initialize_dev(
 	atomic_set(&cdev->private->onoff, 0);
 	cdev->dev.parent = &sch->dev;
 	cdev->dev.release = ccw_device_release;
-	INIT_WORK(&cdev->private->kick_work, NULL);
+	INIT_WORK(&cdev->private->todo_work, ccw_device_todo);
 	cdev->dev.groups = ccwdev_attr_groups;
 	/* Do first half of device_register. */
 	device_initialize(&cdev->dev);
@@ -789,6 +733,7 @@ static int io_subchannel_initialize_dev(
 		put_device(&cdev->dev);
 		return -ENODEV;
 	}
+	cdev->private->flags.initialized = 1;
 	return 0;
 }
 
@@ -806,76 +751,7 @@ static struct ccw_device * io_subchannel
 	return cdev;
 }
 
-static int io_subchannel_recog(struct ccw_device *, struct subchannel *);
-
-static void sch_attach_device(struct subchannel *sch,
-			      struct ccw_device *cdev)
-{
-	css_update_ssd_info(sch);
-	spin_lock_irq(sch->lock);
-	sch_set_cdev(sch, cdev);
-	cdev->private->schid = sch->schid;
-	cdev->ccwlock = sch->lock;
-	ccw_device_trigger_reprobe(cdev);
-	spin_unlock_irq(sch->lock);
-}
-
-static void sch_attach_disconnected_device(struct subchannel *sch,
-					   struct ccw_device *cdev)
-{
-	struct subchannel *other_sch;
-	int ret;
-
-	/* Get reference for new parent. */
-	if (!get_device(&sch->dev))
-		return;
-	other_sch = to_subchannel(cdev->dev.parent);
-	/* Note: device_move() changes cdev->dev.parent */
-	ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
-			      "(ret=%d)!\n", cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Put reference for new parent. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_set_cdev(other_sch, NULL);
-	/* No need to keep a subchannel without ccw device around. */
-	css_sch_device_unregister(other_sch);
-	sch_attach_device(sch, cdev);
-	/* Put reference for old parent. */
-	put_device(&other_sch->dev);
-}
-
-static void sch_attach_orphaned_device(struct subchannel *sch,
-				       struct ccw_device *cdev)
-{
-	int ret;
-	struct subchannel *pseudo_sch;
-
-	/* Get reference for new parent. */
-	if (!get_device(&sch->dev))
-		return;
-	pseudo_sch = to_subchannel(cdev->dev.parent);
-	/*
-	 * Try to move the ccw device to its new subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
-	ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
-			      "failed (ret=%d)!\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Put reference for new parent. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_attach_device(sch, cdev);
-	/* Put reference on pseudo subchannel. */
-	put_device(&pseudo_sch->dev);
-}
+static void io_subchannel_recog(struct ccw_device *, struct subchannel *);
 
 static void sch_create_and_recog_new_device(struct subchannel *sch)
 {
@@ -888,100 +764,19 @@ static void sch_create_and_recog_new_dev
 		css_sch_device_unregister(sch);
 		return;
 	}
-	spin_lock_irq(sch->lock);
-	sch_set_cdev(sch, cdev);
-	spin_unlock_irq(sch->lock);
 	/* Start recognition for the new ccw device. */
-	if (io_subchannel_recog(cdev, sch)) {
-		spin_lock_irq(sch->lock);
-		sch_set_cdev(sch, NULL);
-		spin_unlock_irq(sch->lock);
-		css_sch_device_unregister(sch);
-		/* Put reference from io_subchannel_create_ccwdev(). */
-		put_device(&sch->dev);
-		/* Give up initial reference. */
-		put_device(&cdev->dev);
-	}
-}
-
-
-void ccw_device_move_to_orphanage(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-	struct ccw_device *replacing_cdev;
-	struct subchannel *sch;
-	int ret;
-	struct channel_subsystem *css;
-	struct ccw_dev_id dev_id;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	sch = to_subchannel(cdev->dev.parent);
-	css = to_css(sch->dev.parent);
-	dev_id.devno = sch->schib.pmcw.dev;
-	dev_id.ssid = sch->schid.ssid;
-
-	/* Increase refcount for pseudo subchannel. */
-	get_device(&css->pseudo_subchannel->dev);
-	/*
-	 * Move the orphaned ccw device to the orphanage so the replacing
-	 * ccw device can take its place on the subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
-	ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
-		DPM_ORDER_NONE);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
-			      "(ret=%d)!\n", cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		/* Decrease refcount for pseudo subchannel again. */
-		put_device(&css->pseudo_subchannel->dev);
-		return;
-	}
-	cdev->ccwlock = css->pseudo_subchannel->lock;
-	/*
-	 * Search for the replacing ccw device
-	 * - among the disconnected devices
-	 * - in the orphanage
-	 */
-	replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
-	if (replacing_cdev) {
-		sch_attach_disconnected_device(sch, replacing_cdev);
-		/* Release reference from get_disc_ccwdev_by_dev_id() */
-		put_device(&replacing_cdev->dev);
-		/* Release reference of subchannel from old cdev. */
-		put_device(&sch->dev);
-		return;
-	}
-	replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id);
-	if (replacing_cdev) {
-		sch_attach_orphaned_device(sch, replacing_cdev);
-		/* Release reference from get_orphaned_ccwdev_by_dev_id() */
-		put_device(&replacing_cdev->dev);
-		/* Release reference of subchannel from old cdev. */
-		put_device(&sch->dev);
-		return;
-	}
-	sch_create_and_recog_new_device(sch);
-	/* Release reference of subchannel from old cdev. */
-	put_device(&sch->dev);
+	io_subchannel_recog(cdev, sch);
 }
 
 /*
  * Register recognized device.
  */
-static void
-io_subchannel_register(struct work_struct *work)
+static void io_subchannel_register(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
 	struct subchannel *sch;
 	int ret;
 	unsigned long flags;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
 	sch = to_subchannel(cdev->dev.parent);
 	/*
 	 * Check if subchannel is still registered. It may have become
@@ -1033,41 +828,23 @@ out:
 	cdev->private->flags.recog_done = 1;
 	wake_up(&cdev->private->wait_q);
 out_err:
-	/* Release reference for workqueue processing. */
-	put_device(&cdev->dev);
 	if (atomic_dec_and_test(&ccw_device_init_count))
 		wake_up(&ccw_device_init_wq);
 }
 
-static void ccw_device_call_sch_unregister(struct work_struct *work)
+static void ccw_device_call_sch_unregister(struct ccw_device *cdev)
 {
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
 	struct subchannel *sch;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
 	/* Get subchannel reference for local processing. */
 	if (!get_device(cdev->dev.parent))
 		return;
 	sch = to_subchannel(cdev->dev.parent);
 	css_sch_device_unregister(sch);
-	/* Release cdev reference for workqueue processing.*/
-	put_device(&cdev->dev);
 	/* Release subchannel reference for local processing. */
 	put_device(&sch->dev);
 }
 
-void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
-{
-	/* Get cdev reference for workqueue processing. */
-	if (!get_device(&cdev->dev))
-		return;
-	PREPARE_WORK(&cdev->private->kick_work,
-		     ccw_device_call_sch_unregister);
-	queue_work(slow_path_wq, &cdev->private->kick_work);
-}
-
 /*
  * subchannel recognition done. Called from the state machine.
  */
@@ -1083,7 +860,8 @@ io_subchannel_recog_done(struct ccw_devi
 		/* Device did not respond in time. */
 	case DEV_STATE_NOT_OPER:
 		cdev->private->flags.recog_done = 1;
-		ccw_device_schedule_sch_unregister(cdev);
+		/* Remove device found not operational. */
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		if (atomic_dec_and_test(&ccw_device_init_count))
 			wake_up(&ccw_device_init_wq);
 		break;
@@ -1092,22 +870,15 @@ io_subchannel_recog_done(struct ccw_devi
 		 * We can't register the device in interrupt context so
 		 * we schedule a work item.
 		 */
-		if (!get_device(&cdev->dev))
-			break;
-		PREPARE_WORK(&cdev->private->kick_work,
-			     io_subchannel_register);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_REGISTER);
 		break;
 	}
 }
 
-static int
-io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
+static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
 {
-	int rc;
 	struct ccw_device_private *priv;
 
-	sch_set_cdev(sch, cdev);
 	cdev->ccwlock = sch->lock;
 
 	/* Init private data. */
@@ -1125,62 +896,81 @@ io_subchannel_recog(struct ccw_device *c
 
 	/* Start async. device sensing. */
 	spin_lock_irq(sch->lock);
-	rc = ccw_device_recognition(cdev);
+	sch_set_cdev(sch, cdev);
+	ccw_device_recognition(cdev);
 	spin_unlock_irq(sch->lock);
-	if (rc) {
-		if (atomic_dec_and_test(&ccw_device_init_count))
-			wake_up(&ccw_device_init_wq);
-	}
-	return rc;
 }
 
-static void ccw_device_move_to_sch(struct work_struct *work)
+static int ccw_device_move_to_sch(struct ccw_device *cdev,
+				  struct subchannel *sch)
 {
-	struct ccw_device_private *priv;
-	int rc;
-	struct subchannel *sch;
-	struct ccw_device *cdev;
-	struct subchannel *former_parent;
+	struct subchannel *old_sch;
+	int rc, old_enabled = 0;
 
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	sch = priv->sch;
-	cdev = priv->cdev;
-	former_parent = to_subchannel(cdev->dev.parent);
-	/* Get reference for new parent. */
+	old_sch = to_subchannel(cdev->dev.parent);
+	/* Obtain child reference for new parent. */
 	if (!get_device(&sch->dev))
-		return;
+		return -ENODEV;
+
+	if (!sch_is_pseudo_sch(old_sch)) {
+		spin_lock_irq(old_sch->lock);
+		old_enabled = old_sch->schib.pmcw.ena;
+		rc = 0;
+		if (old_enabled)
+			rc = cio_disable_subchannel(old_sch);
+		spin_unlock_irq(old_sch->lock);
+		if (rc == -EBUSY) {
+			/* Release child reference for new parent. */
+			put_device(&sch->dev);
+			return rc;
+		}
+	}
+
 	mutex_lock(&sch->reg_mutex);
-	/*
-	 * Try to move the ccw device to its new subchannel.
-	 * Note: device_move() changes cdev->dev.parent
-	 */
 	rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
 	mutex_unlock(&sch->reg_mutex);
 	if (rc) {
-		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
-			      "0.%x.%04x failed (ret=%d)!\n",
+		CIO_MSG_EVENT(0, "device_move(0.%x.%04x,0.%x.%04x)=%d\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, rc);
-		css_sch_device_unregister(sch);
-		/* Put reference for new parent again. */
+			      sch->schib.pmcw.dev, rc);
+		if (old_enabled) {
+			/* Try to reenable the old subchannel. */
+			spin_lock_irq(old_sch->lock);
+			cio_enable_subchannel(old_sch, (u32)(addr_t)old_sch);
+			spin_unlock_irq(old_sch->lock);
+		}
+		/* Release child reference for new parent. */
 		put_device(&sch->dev);
-		goto out;
+		return rc;
 	}
-	if (!sch_is_pseudo_sch(former_parent)) {
-		spin_lock_irq(former_parent->lock);
-		sch_set_cdev(former_parent, NULL);
-		spin_unlock_irq(former_parent->lock);
-		css_sch_device_unregister(former_parent);
-		/* Reset intparm to zeroes. */
-		former_parent->config.intparm = 0;
-		cio_commit_config(former_parent);
+	/* Clean up old subchannel. */
+	if (!sch_is_pseudo_sch(old_sch)) {
+		spin_lock_irq(old_sch->lock);
+		sch_set_cdev(old_sch, NULL);
+		spin_unlock_irq(old_sch->lock);
+		css_schedule_eval(old_sch->schid);
 	}
-	sch_attach_device(sch, cdev);
-out:
-	/* Put reference for old parent. */
-	put_device(&former_parent->dev);
-	put_device(&cdev->dev);
+	/* Release child reference for old parent. */
+	put_device(&old_sch->dev);
+	/* Initialize new subchannel. */
+	spin_lock_irq(sch->lock);
+	cdev->private->schid = sch->schid;
+	cdev->ccwlock = sch->lock;
+	if (!sch_is_pseudo_sch(sch))
+		sch_set_cdev(sch, cdev);
+	spin_unlock_irq(sch->lock);
+	if (!sch_is_pseudo_sch(sch))
+		css_update_ssd_info(sch);
+	return 0;
+}
+
+static int ccw_device_move_to_orph(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct channel_subsystem *css = to_css(sch->dev.parent);
+
+	return ccw_device_move_to_sch(cdev, css->pseudo_subchannel);
 }
 
 static void io_subchannel_irq(struct subchannel *sch)
@@ -1199,9 +989,6 @@ void io_subchannel_init_config(struct su
 {
 	memset(&sch->config, 0, sizeof(sch->config));
 	sch->config.csense = 1;
-	/* Use subchannel mp mode when there is more than 1 installed CHPID. */
-	if ((sch->schib.pmcw.pim & (sch->schib.pmcw.pim - 1)) != 0)
-		sch->config.mp = 1;
 }
 
 static void io_subchannel_init_fields(struct subchannel *sch)
@@ -1222,23 +1009,6 @@ static void io_subchannel_init_fields(st
 	io_subchannel_init_config(sch);
 }
 
-static void io_subchannel_do_unreg(struct work_struct *work)
-{
-	struct subchannel *sch;
-
-	sch = container_of(work, struct subchannel, work);
-	css_sch_device_unregister(sch);
-	put_device(&sch->dev);
-}
-
-/* Schedule unregister if we have no cdev. */
-static void io_subchannel_schedule_removal(struct subchannel *sch)
-{
-	get_device(&sch->dev);
-	INIT_WORK(&sch->work, io_subchannel_do_unreg);
-	queue_work(slow_path_wq, &sch->work);
-}
-
 /*
  * Note: We always return 0 so that we bind to the device even on error.
  * This is needed so that our remove function is called on unregister.
@@ -1247,8 +1017,6 @@ static int io_subchannel_probe(struct su
 {
 	struct ccw_device *cdev;
 	int rc;
-	unsigned long flags;
-	struct ccw_dev_id dev_id;
 
 	if (cio_is_console(sch->schid)) {
 		rc = sysfs_create_group(&sch->dev.kobj,
@@ -1268,6 +1036,7 @@ static int io_subchannel_probe(struct su
 		cdev = sch_get_cdev(sch);
 		cdev->dev.groups = ccwdev_attr_groups;
 		device_initialize(&cdev->dev);
+		cdev->private->flags.initialized = 1;
 		ccw_device_register(cdev);
 		/*
 		 * Check if the device is already online. If it is
@@ -1292,44 +1061,14 @@ static int io_subchannel_probe(struct su
 	sch->private = kzalloc(sizeof(struct io_subchannel_private),
 			       GFP_KERNEL | GFP_DMA);
 	if (!sch->private)
-		goto out_err;
-	/*
-	 * First check if a fitting device may be found amongst the
-	 * disconnected devices or in the orphanage.
-	 */
-	dev_id.devno = sch->schib.pmcw.dev;
-	dev_id.ssid = sch->schid.ssid;
-	cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL);
-	if (!cdev)
-		cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent),
-						     &dev_id);
-	if (cdev) {
-		/*
-		 * Schedule moving the device until when we have a registered
-		 * subchannel to move to and succeed the probe. We can
-		 * unregister later again, when the probe is through.
-		 */
-		cdev->private->sch = sch;
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_move_to_sch);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-		return 0;
-	}
-	cdev = io_subchannel_create_ccwdev(sch);
-	if (IS_ERR(cdev))
-		goto out_err;
-	rc = io_subchannel_recog(cdev, sch);
-	if (rc) {
-		spin_lock_irqsave(sch->lock, flags);
-		io_subchannel_recog_done(cdev);
-		spin_unlock_irqrestore(sch->lock, flags);
-	}
+		goto out_schedule;
+	css_schedule_eval(sch->schid);
 	return 0;
-out_err:
-	kfree(sch->private);
-	sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
+
 out_schedule:
-	io_subchannel_schedule_removal(sch);
+	spin_lock_irq(sch->lock);
+	css_sched_sch_todo(sch, SCH_TODO_UNREG);
+	spin_unlock_irq(sch->lock);
 	return 0;
 }
 
@@ -1337,32 +1076,23 @@ static int
 io_subchannel_remove (struct subchannel *sch)
 {
 	struct ccw_device *cdev;
-	unsigned long flags;
 
 	cdev = sch_get_cdev(sch);
 	if (!cdev)
-		return 0;
+		goto out_free;
+	io_subchannel_quiesce(sch);
 	/* Set ccw device to not operational and drop reference. */
-	spin_lock_irqsave(cdev->ccwlock, flags);
+	spin_lock_irq(cdev->ccwlock);
 	sch_set_cdev(sch, NULL);
 	cdev->private->state = DEV_STATE_NOT_OPER;
-	spin_unlock_irqrestore(cdev->ccwlock, flags);
+	spin_unlock_irq(cdev->ccwlock);
 	ccw_device_unregister(cdev);
+out_free:
 	kfree(sch->private);
 	sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
 	return 0;
 }
 
-static int io_subchannel_notify(struct subchannel *sch, int event)
-{
-	struct ccw_device *cdev;
-
-	cdev = sch_get_cdev(sch);
-	if (!cdev)
-		return 0;
-	return ccw_device_notify(cdev, event);
-}
-
 static void io_subchannel_verify(struct subchannel *sch)
 {
 	struct ccw_device *cdev;
@@ -1372,36 +1102,6 @@ static void io_subchannel_verify(struct
 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
 }
 
-static int check_for_io_on_path(struct subchannel *sch, int mask)
-{
-	if (cio_update_schib(sch))
-		return 0;
-	if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask)
-		return 1;
-	return 0;
-}
-
-static void terminate_internal_io(struct subchannel *sch,
-				  struct ccw_device *cdev)
-{
-	if (cio_clear(sch)) {
-		/* Recheck device in case clear failed. */
-		sch->lpm = 0;
-		if (cdev->online)
-			dev_fsm_event(cdev, DEV_EVENT_VERIFY);
-		else
-			css_schedule_eval(sch->schid);
-		return;
-	}
-	cdev->private->state = DEV_STATE_CLEAR_VERIFY;
-	/* Request retry of internal operation. */
-	cdev->private->flags.intretry = 1;
-	/* Call handler. */
-	if (cdev->handler)
-		cdev->handler(cdev, cdev->private->intparm,
-			      ERR_PTR(-EIO));
-}
-
 static void io_subchannel_terminate_path(struct subchannel *sch, u8 mask)
 {
 	struct ccw_device *cdev;
@@ -1409,18 +1109,24 @@ static void io_subchannel_terminate_path
 	cdev = sch_get_cdev(sch);
 	if (!cdev)
 		return;
-	if (check_for_io_on_path(sch, mask)) {
-		if (cdev->private->state == DEV_STATE_ONLINE)
-			ccw_device_kill_io(cdev);
-		else {
-			terminate_internal_io(sch, cdev);
-			/* Re-start path verification. */
-			dev_fsm_event(cdev, DEV_EVENT_VERIFY);
-		}
-	} else
-		/* trigger path verification. */
-		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+	if (cio_update_schib(sch))
+		goto err;
+	/* Check for I/O on path. */
+	if (scsw_actl(&sch->schib.scsw) == 0 || sch->schib.pmcw.lpum != mask)
+		goto out;
+	if (cdev->private->state == DEV_STATE_ONLINE) {
+		ccw_device_kill_io(cdev);
+		goto out;
+	}
+	if (cio_clear(sch))
+		goto err;
+out:
+	/* Trigger path verification. */
+	dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+	return;
 
+err:
+	dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 }
 
 static int io_subchannel_chp_event(struct subchannel *sch,
@@ -1457,46 +1163,41 @@ static int io_subchannel_chp_event(struc
 	return 0;
 }
 
-static void
-io_subchannel_shutdown(struct subchannel *sch)
+static void io_subchannel_quiesce(struct subchannel *sch)
 {
 	struct ccw_device *cdev;
 	int ret;
 
+	spin_lock_irq(sch->lock);
 	cdev = sch_get_cdev(sch);
-
 	if (cio_is_console(sch->schid))
-		return;
+		goto out_unlock;
 	if (!sch->schib.pmcw.ena)
-		/* Nothing to do. */
-		return;
+		goto out_unlock;
 	ret = cio_disable_subchannel(sch);
 	if (ret != -EBUSY)
-		/* Subchannel is disabled, we're done. */
-		return;
-	cdev->private->state = DEV_STATE_QUIESCE;
+		goto out_unlock;
 	if (cdev->handler)
-		cdev->handler(cdev, cdev->private->intparm,
-			      ERR_PTR(-EIO));
-	ret = ccw_device_cancel_halt_clear(cdev);
-	if (ret == -EBUSY) {
-		ccw_device_set_timeout(cdev, HZ/10);
-		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+		cdev->handler(cdev, cdev->private->intparm, ERR_PTR(-EIO));
+	while (ret == -EBUSY) {
+		cdev->private->state = DEV_STATE_QUIESCE;
+		ret = ccw_device_cancel_halt_clear(cdev);
+		if (ret == -EBUSY) {
+			ccw_device_set_timeout(cdev, HZ/10);
+			spin_unlock_irq(sch->lock);
+			wait_event(cdev->private->wait_q,
+				   cdev->private->state != DEV_STATE_QUIESCE);
+			spin_lock_irq(sch->lock);
+		}
+		ret = cio_disable_subchannel(sch);
 	}
-	cio_disable_subchannel(sch);
+out_unlock:
+	spin_unlock_irq(sch->lock);
 }
 
-static int io_subchannel_get_status(struct subchannel *sch)
+static void io_subchannel_shutdown(struct subchannel *sch)
 {
-	struct schib schib;
-
-	if (stsch(sch->schid, &schib) || !schib.pmcw.dnv)
-		return CIO_GONE;
-	if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev))
-		return CIO_REVALIDATE;
-	if (!sch->lpm)
-		return CIO_NO_PATH;
-	return CIO_OPER;
+	io_subchannel_quiesce(sch);
 }
 
 static int device_is_disconnected(struct ccw_device *cdev)
@@ -1575,20 +1276,16 @@ static void ccw_device_schedule_recovery
 static int purge_fn(struct device *dev, void *data)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
-	struct ccw_device_private *priv = cdev->private;
-	int unreg;
+	struct ccw_dev_id *id = &cdev->private->dev_id;
 
 	spin_lock_irq(cdev->ccwlock);
-	unreg = is_blacklisted(priv->dev_id.ssid, priv->dev_id.devno) &&
-		(priv->state == DEV_STATE_OFFLINE);
+	if (is_blacklisted(id->ssid, id->devno) &&
+	    (cdev->private->state == DEV_STATE_OFFLINE)) {
+		CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", id->ssid,
+			      id->devno);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
+	}
 	spin_unlock_irq(cdev->ccwlock);
-	if (!unreg)
-		goto out;
-	CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
-		      priv->dev_id.devno);
-	ccw_device_schedule_sch_unregister(cdev);
-
-out:
 	/* Abort loop in case of pending signal. */
 	if (signal_pending(current))
 		return -EINTR;
@@ -1630,91 +1327,169 @@ void ccw_device_set_notoper(struct ccw_d
 	cdev->private->state = DEV_STATE_NOT_OPER;
 }
 
-static int io_subchannel_sch_event(struct subchannel *sch, int slow)
+enum io_sch_action {
+	IO_SCH_UNREG,
+	IO_SCH_ORPH_UNREG,
+	IO_SCH_ATTACH,
+	IO_SCH_UNREG_ATTACH,
+	IO_SCH_ORPH_ATTACH,
+	IO_SCH_REPROBE,
+	IO_SCH_VERIFY,
+	IO_SCH_DISC,
+	IO_SCH_NOP,
+};
+
+static enum io_sch_action sch_get_action(struct subchannel *sch)
+{
+	struct ccw_device *cdev;
+
+	cdev = sch_get_cdev(sch);
+	if (cio_update_schib(sch)) {
+		/* Not operational. */
+		if (!cdev)
+			return IO_SCH_UNREG;
+		if (!ccw_device_notify(cdev, CIO_GONE))
+			return IO_SCH_UNREG;
+		return IO_SCH_ORPH_UNREG;
+	}
+	/* Operational. */
+	if (!cdev)
+		return IO_SCH_ATTACH;
+	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
+		if (!ccw_device_notify(cdev, CIO_GONE))
+			return IO_SCH_UNREG_ATTACH;
+		return IO_SCH_ORPH_ATTACH;
+	}
+	if ((sch->schib.pmcw.pam & sch->opm) == 0) {
+		if (!ccw_device_notify(cdev, CIO_NO_PATH))
+			return IO_SCH_UNREG;
+		return IO_SCH_DISC;
+	}
+	if (device_is_disconnected(cdev))
+		return IO_SCH_REPROBE;
+	if (cdev->online)
+		return IO_SCH_VERIFY;
+	return IO_SCH_NOP;
+}
+
+/**
+ * io_subchannel_sch_event - process subchannel event
+ * @sch: subchannel
+ * @process: non-zero if function is called in process context
+ *
+ * An unspecified event occurred for this subchannel. Adjust data according
+ * to the current operational state of the subchannel and device. Return
+ * zero when the event has been handled sufficiently or -EAGAIN when this
+ * function should be called again in process context.
+ */
+static int io_subchannel_sch_event(struct subchannel *sch, int process)
 {
-	int event, ret, disc;
 	unsigned long flags;
-	enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE, DISC } action;
 	struct ccw_device *cdev;
+	struct ccw_dev_id dev_id;
+	enum io_sch_action action;
+	int rc = -EAGAIN;
 
 	spin_lock_irqsave(sch->lock, flags);
+	if (!device_is_registered(&sch->dev))
+		goto out_unlock;
+	if (work_pending(&sch->todo_work))
+		goto out_unlock;
 	cdev = sch_get_cdev(sch);
-	disc = device_is_disconnected(cdev);
-	if (disc && slow) {
-		/* Disconnected devices are evaluated directly only.*/
-		spin_unlock_irqrestore(sch->lock, flags);
-		return 0;
-	}
-	/* No interrupt after machine check - kill pending timers. */
-	if (cdev)
-		ccw_device_set_timeout(cdev, 0);
-	if (!disc && !slow) {
-		/* Non-disconnected devices are evaluated on the slow path. */
-		spin_unlock_irqrestore(sch->lock, flags);
-		return -EAGAIN;
+	if (cdev && work_pending(&cdev->private->todo_work))
+		goto out_unlock;
+	action = sch_get_action(sch);
+	CIO_MSG_EVENT(2, "event: sch 0.%x.%04x, process=%d, action=%d\n",
+		      sch->schid.ssid, sch->schid.sch_no, process,
+		      action);
+	/* Perform immediate actions while holding the lock. */
+	switch (action) {
+	case IO_SCH_REPROBE:
+		/* Trigger device recognition. */
+		ccw_device_trigger_reprobe(cdev);
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_VERIFY:
+		/* Trigger path verification. */
+		io_subchannel_verify(sch);
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_DISC:
+		ccw_device_set_disconnected(cdev);
+		rc = 0;
+		goto out_unlock;
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_ORPH_ATTACH:
+		ccw_device_set_disconnected(cdev);
+		break;
+	case IO_SCH_UNREG_ATTACH:
+	case IO_SCH_UNREG:
+		if (cdev)
+			ccw_device_set_notoper(cdev);
+		break;
+	case IO_SCH_NOP:
+		rc = 0;
+		goto out_unlock;
+	default:
+		break;
 	}
-	event = io_subchannel_get_status(sch);
-	CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n",
-		      sch->schid.ssid, sch->schid.sch_no, event,
-		      disc ? "disconnected" : "normal",
-		      slow ? "slow" : "fast");
-	/* Analyze subchannel status. */
-	action = NONE;
-	switch (event) {
-	case CIO_NO_PATH:
-		if (disc) {
-			/* Check if paths have become available. */
-			action = REPROBE;
-			break;
-		}
-		/* fall through */
-	case CIO_GONE:
-		/* Ask driver what to do with device. */
-		if (io_subchannel_notify(sch, event))
-			action = DISC;
-		else
-			action = UNREGISTER;
+	spin_unlock_irqrestore(sch->lock, flags);
+	/* All other actions require process context. */
+	if (!process)
+		goto out;
+	/* Handle attached ccw device. */
+	switch (action) {
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_ORPH_ATTACH:
+		/* Move ccw device to orphanage. */
+		rc = ccw_device_move_to_orph(cdev);
+		if (rc)
+			goto out;
 		break;
-	case CIO_REVALIDATE:
-		/* Device will be removed, so no notify necessary. */
-		if (disc)
-			/* Reprobe because immediate unregister might block. */
-			action = REPROBE;
-		else
-			action = UNREGISTER_PROBE;
+	case IO_SCH_UNREG_ATTACH:
+		/* Unregister ccw device. */
+		ccw_device_unregister(cdev);
 		break;
-	case CIO_OPER:
-		if (disc)
-			/* Get device operational again. */
-			action = REPROBE;
+	default:
 		break;
 	}
-	/* Perform action. */
-	ret = 0;
+	/* Handle subchannel. */
 	switch (action) {
-	case UNREGISTER:
-	case UNREGISTER_PROBE:
-		ccw_device_set_notoper(cdev);
-		/* Unregister device (will use subchannel lock). */
-		spin_unlock_irqrestore(sch->lock, flags);
+	case IO_SCH_ORPH_UNREG:
+	case IO_SCH_UNREG:
 		css_sch_device_unregister(sch);
-		spin_lock_irqsave(sch->lock, flags);
 		break;
-	case REPROBE:
+	case IO_SCH_ORPH_ATTACH:
+	case IO_SCH_UNREG_ATTACH:
+	case IO_SCH_ATTACH:
+		dev_id.ssid = sch->schid.ssid;
+		dev_id.devno = sch->schib.pmcw.dev;
+		cdev = get_ccwdev_by_dev_id(&dev_id);
+		if (!cdev) {
+			sch_create_and_recog_new_device(sch);
+			break;
+		}
+		rc = ccw_device_move_to_sch(cdev, sch);
+		if (rc) {
+			/* Release reference from get_ccwdev_by_dev_id() */
+			put_device(&cdev->dev);
+			goto out;
+		}
+		spin_lock_irqsave(sch->lock, flags);
 		ccw_device_trigger_reprobe(cdev);
-		break;
-	case DISC:
-		ccw_device_set_disconnected(cdev);
+		spin_unlock_irqrestore(sch->lock, flags);
+		/* Release reference from get_ccwdev_by_dev_id() */
+		put_device(&cdev->dev);
 		break;
 	default:
 		break;
 	}
-	spin_unlock_irqrestore(sch->lock, flags);
-	/* Probe if necessary. */
-	if (action == UNREGISTER_PROBE)
-		ret = css_probe_device(sch->schid);
+	return 0;
 
-	return ret;
+out_unlock:
+	spin_unlock_irqrestore(sch->lock, flags);
+out:
+	return rc;
 }
 
 #ifdef CONFIG_CCW_CONSOLE
@@ -1744,10 +1519,8 @@ static int ccw_device_console_enable(str
 	sch->driver = &io_subchannel_driver;
 	/* Initialize the ccw_device structure. */
 	cdev->dev.parent= &sch->dev;
-	rc = io_subchannel_recog(cdev, sch);
-	if (rc)
-		return rc;
-
+	sch_set_cdev(sch, cdev);
+	io_subchannel_recog(cdev, sch);
 	/* Now wait for the async. recognition to come to an end. */
 	spin_lock_irq(cdev->ccwlock);
 	while (!dev_fsm_final_state(cdev))
@@ -1763,7 +1536,7 @@ static int ccw_device_console_enable(str
 	rc = 0;
 out_unlock:
 	spin_unlock_irq(cdev->ccwlock);
-	return 0;
+	return rc;
 }
 
 struct ccw_device *
@@ -1919,7 +1692,7 @@ static int ccw_device_pm_prepare(struct
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 
-	if (work_pending(&cdev->private->kick_work))
+	if (work_pending(&cdev->private->todo_work))
 		return -EAGAIN;
 	/* Fail while device is being set online/offline. */
 	if (atomic_read(&cdev->private->onoff))
@@ -2005,7 +1778,6 @@ static int ccw_device_pm_thaw(struct dev
 static void __ccw_device_pm_restore(struct ccw_device *cdev)
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
-	int ret;
 
 	if (cio_is_console(sch->schid))
 		goto out;
@@ -2015,22 +1787,10 @@ static void __ccw_device_pm_restore(stru
 	 */
 	spin_lock_irq(sch->lock);
 	cdev->private->flags.resuming = 1;
-	ret = ccw_device_recognition(cdev);
+	ccw_device_recognition(cdev);
 	spin_unlock_irq(sch->lock);
-	if (ret) {
-		CIO_MSG_EVENT(0, "Couldn't start recognition for device "
-			      "0.%x.%04x (ret=%d)\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno, ret);
-		spin_lock_irq(sch->lock);
-		cdev->private->state = DEV_STATE_DISCONNECTED;
-		spin_unlock_irq(sch->lock);
-		/* notify driver after the resume cb */
-		goto out;
-	}
 	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) ||
 		   cdev->private->state == DEV_STATE_DISCONNECTED);
-
 out:
 	cdev->private->flags.resuming = 0;
 }
@@ -2040,7 +1800,7 @@ static int resume_handle_boxed(struct cc
 	cdev->private->state = DEV_STATE_BOXED;
 	if (ccw_device_notify(cdev, CIO_BOXED))
 		return 0;
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
 }
 
@@ -2049,7 +1809,7 @@ static int resume_handle_disc(struct ccw
 	cdev->private->state = DEV_STATE_DISCONNECTED;
 	if (ccw_device_notify(cdev, CIO_GONE))
 		return 0;
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	return -ENODEV;
 }
 
@@ -2094,9 +1854,7 @@ static int ccw_device_pm_restore(struct
 	/* check if the device type has changed */
 	if (!ccw_device_test_sense_data(cdev)) {
 		ccw_device_update_sense_data(cdev);
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_do_unbind_bind);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 		ret = -ENODEV;
 		goto out_unlock;
 	}
@@ -2140,14 +1898,14 @@ out_disc_unlock:
 	goto out_restore;
 
 out_unreg_unlock:
-	ccw_device_schedule_sch_unregister(cdev);
+	ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
 	ret = -ENODEV;
 out_unlock:
 	spin_unlock_irq(sch->lock);
 	return ret;
 }
 
-static struct dev_pm_ops ccw_pm_ops = {
+static const struct dev_pm_ops ccw_pm_ops = {
 	.prepare = ccw_device_pm_prepare,
 	.complete = ccw_device_pm_complete,
 	.freeze = ccw_device_pm_freeze,
@@ -2205,6 +1963,77 @@ ccw_device_get_subchannel_id(struct ccw_
 	return sch->schid;
 }
 
+static void ccw_device_todo(struct work_struct *work)
+{
+	struct ccw_device_private *priv;
+	struct ccw_device *cdev;
+	struct subchannel *sch;
+	enum cdev_todo todo;
+
+	priv = container_of(work, struct ccw_device_private, todo_work);
+	cdev = priv->cdev;
+	sch = to_subchannel(cdev->dev.parent);
+	/* Find out todo. */
+	spin_lock_irq(cdev->ccwlock);
+	todo = priv->todo;
+	priv->todo = CDEV_TODO_NOTHING;
+	CIO_MSG_EVENT(4, "cdev_todo: cdev=0.%x.%04x todo=%d\n",
+		      priv->dev_id.ssid, priv->dev_id.devno, todo);
+	spin_unlock_irq(cdev->ccwlock);
+	/* Perform todo. */
+	switch (todo) {
+	case CDEV_TODO_ENABLE_CMF:
+		cmf_reenable(cdev);
+		break;
+	case CDEV_TODO_REBIND:
+		ccw_device_do_unbind_bind(cdev);
+		break;
+	case CDEV_TODO_REGISTER:
+		io_subchannel_register(cdev);
+		break;
+	case CDEV_TODO_UNREG_EVAL:
+		if (!sch_is_pseudo_sch(sch))
+			css_schedule_eval(sch->schid);
+		/* fall-through */
+	case CDEV_TODO_UNREG:
+		if (sch_is_pseudo_sch(sch))
+			ccw_device_unregister(cdev);
+		else
+			ccw_device_call_sch_unregister(cdev);
+		break;
+	default:
+		break;
+	}
+	/* Release workqueue ref. */
+	put_device(&cdev->dev);
+}
+
+/**
+ * ccw_device_sched_todo - schedule ccw device operation
+ * @cdev: ccw device
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with ccwdev lock held.
+ */
+void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo)
+{
+	CIO_MSG_EVENT(4, "cdev_todo: sched cdev=0.%x.%04x todo=%d\n",
+		      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
+		      todo);
+	if (cdev->private->todo >= todo)
+		return;
+	cdev->private->todo = todo;
+	/* Get workqueue ref. */
+	if (!get_device(&cdev->dev))
+		return;
+	if (!queue_work(slow_path_wq, &cdev->private->todo_work)) {
+		/* Already queued, release workqueue ref. */
+		put_device(&cdev->dev);
+	}
+}
+
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(ccw_device_set_online);
 EXPORT_SYMBOL(ccw_device_set_offline);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device_fsm.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device_fsm.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device_fsm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device_fsm.c	2010-02-24 13:52:17.000000000 -0500
@@ -229,8 +229,8 @@ ccw_device_recog_done(struct ccw_device
 
 	sch = to_subchannel(cdev->dev.parent);
 
-	ccw_device_set_timeout(cdev, 0);
-	cio_disable_subchannel(sch);
+	if (cio_disable_subchannel(sch))
+		state = DEV_STATE_NOT_OPER;
 	/*
 	 * Now that we tried recognition, we have performed device selection
 	 * through ssch() and the path information is up to date.
@@ -263,22 +263,10 @@ ccw_device_recog_done(struct ccw_device
 	}
 	switch (state) {
 	case DEV_STATE_NOT_OPER:
-		CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
-			      "subchannel 0.%x.%04x\n",
-			      cdev->private->dev_id.devno,
-			      sch->schid.ssid, sch->schid.sch_no);
 		break;
 	case DEV_STATE_OFFLINE:
 		if (!cdev->online) {
 			ccw_device_update_sense_data(cdev);
-			/* Issue device info message. */
-			CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
-				      "CU  Type/Mod = %04X/%02X, Dev Type/Mod "
-				      "= %04X/%02X\n",
-				      cdev->private->dev_id.ssid,
-				      cdev->private->dev_id.devno,
-				      cdev->id.cu_type, cdev->id.cu_model,
-				      cdev->id.dev_type, cdev->id.dev_model);
 			break;
 		}
 		cdev->private->state = DEV_STATE_OFFLINE;
@@ -289,16 +277,10 @@ ccw_device_recog_done(struct ccw_device
 			wake_up(&cdev->private->wait_q);
 		} else {
 			ccw_device_update_sense_data(cdev);
-			PREPARE_WORK(&cdev->private->kick_work,
-				     ccw_device_do_unbind_bind);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
+			ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 		}
 		return;
 	case DEV_STATE_BOXED:
-		CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
-			      " subchannel 0.%x.%04x\n",
-			      cdev->private->dev_id.devno,
-			      sch->schid.ssid, sch->schid.sch_no);
 		if (cdev->id.cu_type != 0) { /* device was recognized before */
 			cdev->private->flags.recog_done = 1;
 			cdev->private->state = DEV_STATE_BOXED;
@@ -343,28 +325,16 @@ int ccw_device_notify(struct ccw_device
 	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
 }
 
-static void cmf_reenable_delayed(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	cmf_reenable(cdev);
-}
-
 static void ccw_device_oper_notify(struct ccw_device *cdev)
 {
 	if (ccw_device_notify(cdev, CIO_OPER)) {
 		/* Reenable channel measurements, if needed. */
-		PREPARE_WORK(&cdev->private->kick_work, cmf_reenable_delayed);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
 		return;
 	}
 	/* Driver doesn't want device back. */
 	ccw_device_set_notoper(cdev);
-	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
-	queue_work(ccw_device_work, &cdev->private->kick_work);
+	ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 }
 
 /*
@@ -392,14 +362,14 @@ ccw_device_done(struct ccw_device *cdev,
 		CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
 			      cdev->private->dev_id.devno, sch->schid.sch_no);
 		if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		cdev->private->flags.donotify = 0;
 		break;
 	case DEV_STATE_NOT_OPER:
 		CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
 			      cdev->private->dev_id.devno, sch->schid.sch_no);
 		if (!ccw_device_notify(cdev, CIO_GONE))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
 		cdev->private->flags.donotify = 0;
@@ -409,7 +379,7 @@ ccw_device_done(struct ccw_device *cdev,
 			      "%04x\n", cdev->private->dev_id.devno,
 			      sch->schid.sch_no);
 		if (!ccw_device_notify(cdev, CIO_NO_PATH))
-			ccw_device_schedule_sch_unregister(cdev);
+			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 		else
 			ccw_device_set_disconnected(cdev);
 		cdev->private->flags.donotify = 0;
@@ -425,107 +395,12 @@ ccw_device_done(struct ccw_device *cdev,
 	wake_up(&cdev->private->wait_q);
 }
 
-static int cmp_pgid(struct pgid *p1, struct pgid *p2)
-{
-	char *c1;
-	char *c2;
-
-	c1 = (char *)p1;
-	c2 = (char *)p2;
-
-	return memcmp(c1 + 1, c2 + 1, sizeof(struct pgid) - 1);
-}
-
-static void __ccw_device_get_common_pgid(struct ccw_device *cdev)
-{
-	int i;
-	int last;
-
-	last = 0;
-	for (i = 0; i < 8; i++) {
-		if (cdev->private->pgid[i].inf.ps.state1 == SNID_STATE1_RESET)
-			/* No PGID yet */
-			continue;
-		if (cdev->private->pgid[last].inf.ps.state1 ==
-		    SNID_STATE1_RESET) {
-			/* First non-zero PGID */
-			last = i;
-			continue;
-		}
-		if (cmp_pgid(&cdev->private->pgid[i],
-			     &cdev->private->pgid[last]) == 0)
-			/* Non-conflicting PGIDs */
-			continue;
-
-		/* PGID mismatch, can't pathgroup. */
-		CIO_MSG_EVENT(0, "SNID - pgid mismatch for device "
-			      "0.%x.%04x, can't pathgroup\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno);
-		cdev->private->options.pgroup = 0;
-		return;
-	}
-	if (cdev->private->pgid[last].inf.ps.state1 ==
-	    SNID_STATE1_RESET)
-		/* No previous pgid found */
-		memcpy(&cdev->private->pgid[0],
-		       &channel_subsystems[0]->global_pgid,
-		       sizeof(struct pgid));
-	else
-		/* Use existing pgid */
-		memcpy(&cdev->private->pgid[0], &cdev->private->pgid[last],
-		       sizeof(struct pgid));
-}
-
-/*
- * Function called from device_pgid.c after sense path ground has completed.
- */
-void
-ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
-{
-	struct subchannel *sch;
-
-	sch = to_subchannel(cdev->dev.parent);
-	switch (err) {
-	case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */
-		cdev->private->options.pgroup = 0;
-		break;
-	case 0: /* success */
-	case -EACCES: /* partial success, some paths not operational */
-		/* Check if all pgids are equal or 0. */
-		__ccw_device_get_common_pgid(cdev);
-		break;
-	case -ETIME:		/* Sense path group id stopped by timeout. */
-	case -EUSERS:		/* device is reserved for someone else. */
-		ccw_device_done(cdev, DEV_STATE_BOXED);
-		return;
-	default:
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		return;
-	}
-	/* Start Path Group verification. */
-	cdev->private->state = DEV_STATE_VERIFY;
-	cdev->private->flags.doverify = 0;
-	ccw_device_verify_start(cdev);
-}
-
 /*
  * Start device recognition.
  */
-int
-ccw_device_recognition(struct ccw_device *cdev)
+void ccw_device_recognition(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-	ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
-	if (ret != 0)
-		/* Couldn't enable the subchannel for i/o. Sick device. */
-		return ret;
-
-	/* After 60s the device recognition is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
 	/*
 	 * We used to start here with a sense pgid to find out whether a device
@@ -537,32 +412,33 @@ ccw_device_recognition(struct ccw_device
 	 */
 	cdev->private->flags.recog_done = 0;
 	cdev->private->state = DEV_STATE_SENSE_ID;
+	if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) {
+		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+		return;
+	}
 	ccw_device_sense_id_start(cdev);
-	return 0;
 }
 
 /*
- * Handle timeout in device recognition.
+ * Handle events for states that use the ccw request infrastructure.
  */
-static void
-ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+static void ccw_device_request_event(struct ccw_device *cdev, enum dev_event e)
 {
-	int ret;
-
-	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+	switch (e) {
+	case DEV_EVENT_NOTOPER:
+		ccw_request_notoper(cdev);
 		break;
-	case -ENODEV:
-		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+	case DEV_EVENT_INTERRUPT:
+		ccw_request_handler(cdev);
+		break;
+	case DEV_EVENT_TIMEOUT:
+		ccw_request_timeout(cdev);
 		break;
 	default:
-		ccw_device_set_timeout(cdev, 3*HZ);
+		break;
 	}
 }
 
-
 void
 ccw_device_verify_done(struct ccw_device *cdev, int err)
 {
@@ -571,21 +447,18 @@ ccw_device_verify_done(struct ccw_device
 	sch = to_subchannel(cdev->dev.parent);
 	/* Update schib - pom may have changed. */
 	if (cio_update_schib(sch)) {
-		cdev->private->flags.donotify = 0;
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		return;
+		err = -ENODEV;
+		goto callback;
 	}
 	/* Update lpm with verified path mask. */
 	sch->lpm = sch->vpm;
 	/* Repeat path verification? */
 	if (cdev->private->flags.doverify) {
-		cdev->private->flags.doverify = 0;
 		ccw_device_verify_start(cdev);
 		return;
 	}
+callback:
 	switch (err) {
-	case -EOPNOTSUPP: /* path grouping not supported, just set online. */
-		cdev->private->options.pgroup = 0;
 	case 0:
 		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		/* Deliver fake irb to device driver, if needed. */
@@ -604,18 +477,20 @@ ccw_device_verify_done(struct ccw_device
 		}
 		break;
 	case -ETIME:
+	case -EUSERS:
 		/* Reset oper notify indication after verify error. */
 		cdev->private->flags.donotify = 0;
 		ccw_device_done(cdev, DEV_STATE_BOXED);
 		break;
+	case -EACCES:
+		/* Reset oper notify indication after verify error. */
+		cdev->private->flags.donotify = 0;
+		ccw_device_done(cdev, DEV_STATE_DISCONNECTED);
+		break;
 	default:
 		/* Reset oper notify indication after verify error. */
 		cdev->private->flags.donotify = 0;
-		if (cdev->online) {
-			ccw_device_set_timeout(cdev, 0);
-			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
-		} else
-			ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
 }
@@ -640,17 +515,9 @@ ccw_device_online(struct ccw_device *cde
 			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		return ret;
 	}
-	/* Do we want to do path grouping? */
-	if (!cdev->private->options.pgroup) {
-		/* Start initial path verification. */
-		cdev->private->state = DEV_STATE_VERIFY;
-		cdev->private->flags.doverify = 0;
-		ccw_device_verify_start(cdev);
-		return 0;
-	}
-	/* Do a SensePGID first. */
-	cdev->private->state = DEV_STATE_SENSE_PGID;
-	ccw_device_sense_pgid_start(cdev);
+	/* Start initial path verification. */
+	cdev->private->state = DEV_STATE_VERIFY;
+	ccw_device_verify_start(cdev);
 	return 0;
 }
 
@@ -666,7 +533,6 @@ ccw_device_disband_done(struct ccw_devic
 		break;
 	default:
 		cdev->private->flags.donotify = 0;
-		dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
@@ -703,7 +569,7 @@ ccw_device_offline(struct ccw_device *cd
 	if (cdev->private->state != DEV_STATE_ONLINE)
 		return -EINVAL;
 	/* Are we doing path grouping? */
-	if (!cdev->private->options.pgroup) {
+	if (!cdev->private->flags.pgroup) {
 		/* No, set state offline immediately. */
 		ccw_device_done(cdev, DEV_STATE_OFFLINE);
 		return 0;
@@ -715,43 +581,13 @@ ccw_device_offline(struct ccw_device *cd
 }
 
 /*
- * Handle timeout in device online/offline process.
- */
-static void
-ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	int ret;
-
-	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		ccw_device_done(cdev, DEV_STATE_BOXED);
-		break;
-	case -ENODEV:
-		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
-		break;
-	default:
-		ccw_device_set_timeout(cdev, 3*HZ);
-	}
-}
-
-/*
- * Handle not oper event in device recognition.
- */
-static void
-ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
-}
-
-/*
  * Handle not operational event in non-special state.
  */
 static void ccw_device_generic_notoper(struct ccw_device *cdev,
 				       enum dev_event dev_event)
 {
 	if (!ccw_device_notify(cdev, CIO_GONE))
-		ccw_device_schedule_sch_unregister(cdev);
+		ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 	else
 		ccw_device_set_disconnected(cdev);
 }
@@ -802,11 +638,27 @@ ccw_device_online_verify(struct ccw_devi
 	}
 	/* Device is idle, we can do the path verification. */
 	cdev->private->state = DEV_STATE_VERIFY;
-	cdev->private->flags.doverify = 0;
 	ccw_device_verify_start(cdev);
 }
 
 /*
+ * Handle path verification event in boxed state.
+ */
+static void ccw_device_boxed_verify(struct ccw_device *cdev,
+				    enum dev_event dev_event)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+	if (cdev->online) {
+		if (cio_enable_subchannel(sch, (u32) (addr_t) sch))
+			ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		else
+			ccw_device_online_verify(cdev, dev_event);
+	} else
+		css_schedule_eval(sch->schid);
+}
+
+/*
  * Got an interrupt for a normal io (state online).
  */
 static void
@@ -904,12 +756,6 @@ ccw_device_w4sense(struct ccw_device *cd
 	 */
 	if (scsw_fctl(&irb->scsw) &
 	    (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
-		/* Retry Basic Sense if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			ccw_device_do_sense(cdev, irb);
-			return;
-		}
 		cdev->private->flags.dosense = 0;
 		memset(&cdev->private->irb, 0, sizeof(struct irb));
 		ccw_device_accumulate_irb(cdev, irb);
@@ -933,21 +779,6 @@ call_handler:
 }
 
 static void
-ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct irb *irb;
-
-	irb = (struct irb *) __LC_IRB;
-	/* Accumulate status. We don't do basic sense. */
-	ccw_device_accumulate_irb(cdev, irb);
-	/* Remember to clear irb to avoid residuals. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	/* Try to start delayed device verification. */
-	ccw_device_online_verify(cdev, 0);
-	/* Note: Don't call handler for cio initiated clear! */
-}
-
-static void
 ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	struct subchannel *sch;
@@ -1004,32 +835,6 @@ ccw_device_delay_verify(struct ccw_devic
 }
 
 static void
-ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	struct irb *irb;
-
-	switch (dev_event) {
-	case DEV_EVENT_INTERRUPT:
-		irb = (struct irb *) __LC_IRB;
-		/* Check for unsolicited interrupt. */
-		if ((scsw_stctl(&irb->scsw) ==
-		     (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
-		    (!scsw_cc(&irb->scsw)))
-			/* FIXME: we should restart stlck here, but this
-			 * is extremely unlikely ... */
-			goto out_wakeup;
-
-		ccw_device_accumulate_irb(cdev, irb);
-		/* We don't care about basic sense etc. */
-		break;
-	default: /* timeout */
-		break;
-	}
-out_wakeup:
-	wake_up(&cdev->private->wait_q);
-}
-
-static void
 ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	struct subchannel *sch;
@@ -1038,10 +843,6 @@ ccw_device_start_id(struct ccw_device *c
 	if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0)
 		/* Couldn't enable the subchannel for i/o. Sick device. */
 		return;
-
-	/* After 60s the device recognition is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
-
 	cdev->private->state = DEV_STATE_DISCONNECTED_SENSE_ID;
 	ccw_device_sense_id_start(cdev);
 }
@@ -1072,22 +873,20 @@ void ccw_device_trigger_reprobe(struct c
 
 	/* We should also udate ssd info, but this has to wait. */
 	/* Check if this is another device which appeared on the same sch. */
-	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_move_to_orphanage);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
-	} else
+	if (sch->schib.pmcw.dev != cdev->private->dev_id.devno)
+		css_schedule_eval(sch->schid);
+	else
 		ccw_device_start_id(cdev, 0);
 }
 
-static void
-ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void ccw_device_disabled_irq(struct ccw_device *cdev,
+				    enum dev_event dev_event)
 {
 	struct subchannel *sch;
 
 	sch = to_subchannel(cdev->dev.parent);
 	/*
-	 * An interrupt in state offline means a previous disable was not
+	 * An interrupt in a disabled state means a previous disable was not
 	 * successful - should not happen, but we try to disable again.
 	 */
 	cio_disable_subchannel(sch);
@@ -1113,10 +912,7 @@ static void
 ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
 {
 	ccw_device_set_timeout(cdev, 0);
-	if (dev_event == DEV_EVENT_NOTOPER)
-		cdev->private->state = DEV_STATE_NOT_OPER;
-	else
-		cdev->private->state = DEV_STATE_OFFLINE;
+	cdev->private->state = DEV_STATE_NOT_OPER;
 	wake_up(&cdev->private->wait_q);
 }
 
@@ -1126,17 +922,11 @@ ccw_device_quiesce_timeout(struct ccw_de
 	int ret;
 
 	ret = ccw_device_cancel_halt_clear(cdev);
-	switch (ret) {
-	case 0:
-		cdev->private->state = DEV_STATE_OFFLINE;
-		wake_up(&cdev->private->wait_q);
-		break;
-	case -ENODEV:
+	if (ret == -EBUSY) {
+		ccw_device_set_timeout(cdev, HZ/10);
+	} else {
 		cdev->private->state = DEV_STATE_NOT_OPER;
 		wake_up(&cdev->private->wait_q);
-		break;
-	default:
-		ccw_device_set_timeout(cdev, HZ/10);
 	}
 }
 
@@ -1150,50 +940,37 @@ ccw_device_nop(struct ccw_device *cdev,
 }
 
 /*
- * Bug operation action. 
- */
-static void
-ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
-{
-	CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device "
-		      "0.%x.%04x\n", cdev->private->state, dev_event,
-		      cdev->private->dev_id.ssid,
-		      cdev->private->dev_id.devno);
-	BUG();
-}
-
-/*
  * device statemachine
  */
 fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
 	[DEV_STATE_NOT_OPER] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_nop,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_bug,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_disabled_irq,
 		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_PGID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_pgid_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_SENSE_ID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_recog_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_id_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_recog_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_OFFLINE] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_offline_irq,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_disabled_irq,
 		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_offline_verify,
 	},
 	[DEV_STATE_VERIFY] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_verify_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_delay_verify,
 	},
 	[DEV_STATE_ONLINE] = {
@@ -1209,24 +986,18 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES]
 		[DEV_EVENT_VERIFY]	= ccw_device_online_verify,
 	},
 	[DEV_STATE_DISBAND_PGID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_disband_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_BOXED] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_stlck_done,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_stlck_done,
-		[DEV_EVENT_VERIFY]	= ccw_device_nop,
-	},
-	/* states to wait for i/o completion before doing something */
-	[DEV_STATE_CLEAR_VERIFY] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
-		[DEV_EVENT_INTERRUPT]   = ccw_device_clear_verify,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_nop,
 		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
-		[DEV_EVENT_VERIFY]	= ccw_device_nop,
+		[DEV_EVENT_VERIFY]	= ccw_device_boxed_verify,
 	},
+	/* states to wait for i/o completion before doing something */
 	[DEV_STATE_TIMEOUT_KILL] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
 		[DEV_EVENT_INTERRUPT]	= ccw_device_killing_irq,
@@ -1243,13 +1014,13 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES]
 	[DEV_STATE_DISCONNECTED] = {
 		[DEV_EVENT_NOTOPER]	= ccw_device_nop,
 		[DEV_EVENT_INTERRUPT]	= ccw_device_start_id,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_bug,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_nop,
 		[DEV_EVENT_VERIFY]	= ccw_device_start_id,
 	},
 	[DEV_STATE_DISCONNECTED_SENSE_ID] = {
-		[DEV_EVENT_NOTOPER]	= ccw_device_recog_notoper,
-		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_id_irq,
-		[DEV_EVENT_TIMEOUT]	= ccw_device_recog_timeout,
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
 		[DEV_EVENT_VERIFY]	= ccw_device_nop,
 	},
 	[DEV_STATE_CMFCHANGE] = {
@@ -1264,6 +1035,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES]
 		[DEV_EVENT_TIMEOUT]	= ccw_device_update_cmfblock,
 		[DEV_EVENT_VERIFY]	= ccw_device_update_cmfblock,
 	},
+	[DEV_STATE_STEAL_LOCK] = {
+		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
+		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
+		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
+		[DEV_EVENT_VERIFY]	= ccw_device_nop,
+	},
 };
 
 EXPORT_SYMBOL_GPL(ccw_device_set_timeout);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device.h linux-libre-2.6.33-gnu1/drivers/s390/cio/device.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,7 +21,6 @@ enum dev_state {
 	DEV_STATE_DISBAND_PGID,
 	DEV_STATE_BOXED,
 	/* states to wait for i/o completion before doing something */
-	DEV_STATE_CLEAR_VERIFY,
 	DEV_STATE_TIMEOUT_KILL,
 	DEV_STATE_QUIESCE,
 	/* special states for devices gone not operational */
@@ -29,6 +28,7 @@ enum dev_state {
 	DEV_STATE_DISCONNECTED_SENSE_ID,
 	DEV_STATE_CMFCHANGE,
 	DEV_STATE_CMFUPDATE,
+	DEV_STATE_STEAL_LOCK,
 	/* last element! */
 	NR_DEV_STATES
 };
@@ -81,17 +81,16 @@ void io_subchannel_init_config(struct su
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-void ccw_device_do_unbind_bind(struct work_struct *);
-void ccw_device_move_to_orphanage(struct work_struct *);
 int ccw_device_is_orphan(struct ccw_device *);
 
-int ccw_device_recognition(struct ccw_device *);
+void ccw_device_recognition(struct ccw_device *);
 int ccw_device_online(struct ccw_device *);
 int ccw_device_offline(struct ccw_device *);
 void ccw_device_update_sense_data(struct ccw_device *);
 int ccw_device_test_sense_data(struct ccw_device *);
 void ccw_device_schedule_sch_unregister(struct ccw_device *);
 int ccw_purge_blacklisted(void);
+void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo);
 
 /* Function prototypes for device status and basic sense stuff. */
 void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
@@ -99,24 +98,28 @@ void ccw_device_accumulate_basic_sense(s
 int ccw_device_accumulate_and_sense(struct ccw_device *, struct irb *);
 int ccw_device_do_sense(struct ccw_device *, struct irb *);
 
+/* Function prototype for internal request handling. */
+int lpm_adjust(int lpm, int mask);
+void ccw_request_start(struct ccw_device *);
+int ccw_request_cancel(struct ccw_device *cdev);
+void ccw_request_handler(struct ccw_device *cdev);
+void ccw_request_timeout(struct ccw_device *cdev);
+void ccw_request_notoper(struct ccw_device *cdev);
+
 /* Function prototypes for sense id stuff. */
 void ccw_device_sense_id_start(struct ccw_device *);
-void ccw_device_sense_id_irq(struct ccw_device *, enum dev_event);
 void ccw_device_sense_id_done(struct ccw_device *, int);
 
 /* Function prototypes for path grouping stuff. */
-void ccw_device_sense_pgid_start(struct ccw_device *);
-void ccw_device_sense_pgid_irq(struct ccw_device *, enum dev_event);
-void ccw_device_sense_pgid_done(struct ccw_device *, int);
-
 void ccw_device_verify_start(struct ccw_device *);
-void ccw_device_verify_irq(struct ccw_device *, enum dev_event);
 void ccw_device_verify_done(struct ccw_device *, int);
 
 void ccw_device_disband_start(struct ccw_device *);
-void ccw_device_disband_irq(struct ccw_device *, enum dev_event);
 void ccw_device_disband_done(struct ccw_device *, int);
 
+void ccw_device_stlck_start(struct ccw_device *, void *, void *, void *);
+void ccw_device_stlck_done(struct ccw_device *, void *, int);
+
 int ccw_device_call_handler(struct ccw_device *);
 
 int ccw_device_stlck(struct ccw_device *);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device_id.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device_id.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device_id.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device_id.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,40 +1,39 @@
 /*
- * drivers/s390/cio/device_id.c
- *
- *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
- *			 IBM Corporation
- *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
- *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *  CCW device SENSE ID I/O handling.
  *
- * Sense ID functions.
+ *    Copyright IBM Corp. 2002,2009
+ *    Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
 #include <asm/ccwdev.h>
-#include <asm/delay.h>
+#include <asm/setup.h>
 #include <asm/cio.h>
-#include <asm/lowcore.h>
 #include <asm/diag.h>
 
 #include "cio.h"
 #include "cio_debug.h"
-#include "css.h"
 #include "device.h"
-#include "ioasm.h"
 #include "io_sch.h"
 
+#define SENSE_ID_RETRIES	256
+#define SENSE_ID_TIMEOUT	(10 * HZ)
+#define SENSE_ID_MIN_LEN	4
+#define SENSE_ID_BASIC_LEN	7
+
 /**
- * vm_vdev_to_cu_type - Convert vm virtual device into control unit type
- *			for certain devices.
- * @class: virtual device class
- * @type: virtual device type
+ * diag210_to_senseid - convert diag 0x210 data to sense id information
+ * @senseid: sense id
+ * @diag: diag 0x210 data
  *
- * Returns control unit type if a match was made or %0xffff otherwise.
+ * Return 0 on success, non-zero otherwise.
  */
-static int vm_vdev_to_cu_type(int class, int type)
+static int diag210_to_senseid(struct senseid *senseid, struct diag210 *diag)
 {
 	static struct {
 		int class, type, cu_type;
@@ -71,253 +70,153 @@ static int vm_vdev_to_cu_type(int class,
 	};
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vm_devices); i++)
-		if (class == vm_devices[i].class && type == vm_devices[i].type)
-			return vm_devices[i].cu_type;
+	/* Special case for osa devices. */
+	if (diag->vrdcvcla == 0x02 && diag->vrdcvtyp == 0x20) {
+		senseid->cu_type = 0x3088;
+		senseid->cu_model = 0x60;
+		senseid->reserved = 0xff;
+		return 0;
+	}
+	for (i = 0; i < ARRAY_SIZE(vm_devices); i++) {
+		if (diag->vrdcvcla == vm_devices[i].class &&
+		    diag->vrdcvtyp == vm_devices[i].type) {
+			senseid->cu_type = vm_devices[i].cu_type;
+			senseid->reserved = 0xff;
+			return 0;
+		}
+	}
 
-	return 0xffff;
+	return -ENODEV;
 }
 
 /**
- * diag_get_dev_info - retrieve device information via DIAG X'210'
- * @devno: device number
- * @ps: pointer to sense ID data area
+ * diag_get_dev_info - retrieve device information via diag 0x210
+ * @cdev: ccw device
  *
  * Returns zero on success, non-zero otherwise.
  */
-static int diag_get_dev_info(u16 devno, struct senseid *ps)
+static int diag210_get_dev_info(struct ccw_device *cdev)
 {
+	struct ccw_dev_id *dev_id = &cdev->private->dev_id;
+	struct senseid *senseid = &cdev->private->senseid;
 	struct diag210 diag_data;
-	int ccode;
-
-	CIO_TRACE_EVENT (4, "VMvdinf");
-
-	diag_data = (struct diag210) {
-		.vrdcdvno = devno,
-		.vrdclen = sizeof (diag_data),
-	};
-
-	ccode = diag210 (&diag_data);
-	if ((ccode == 0) || (ccode == 2)) {
-		ps->reserved = 0xff;
-
-		/* Special case for osa devices. */
-		if (diag_data.vrdcvcla == 0x02 && diag_data.vrdcvtyp == 0x20) {
-			ps->cu_type = 0x3088;
-			ps->cu_model = 0x60;
-			return 0;
-		}
-		ps->cu_type = vm_vdev_to_cu_type(diag_data.vrdcvcla,
-						diag_data.vrdcvtyp);
-		if (ps->cu_type != 0xffff)
-			return 0;
-	}
+	int rc;
 
-	CIO_MSG_EVENT(0, "DIAG X'210' for device %04X returned (cc = %d):"
-		      "vdev class : %02X, vdev type : %04X \n ...  "
-		      "rdev class : %02X, rdev type : %04X, "
-		      "rdev model: %02X\n",
-		      devno, ccode,
-		      diag_data.vrdcvcla, diag_data.vrdcvtyp,
-		      diag_data.vrdcrccl, diag_data.vrdccrty,
-		      diag_data.vrdccrmd);
+	if (dev_id->ssid != 0)
+		return -ENODEV;
+	memset(&diag_data, 0, sizeof(diag_data));
+	diag_data.vrdcdvno	= dev_id->devno;
+	diag_data.vrdclen	= sizeof(diag_data);
+	rc = diag210(&diag_data);
+	CIO_TRACE_EVENT(4, "diag210");
+	CIO_HEX_EVENT(4, &rc, sizeof(rc));
+	CIO_HEX_EVENT(4, &diag_data, sizeof(diag_data));
+	if (rc != 0 && rc != 2)
+		goto err_failed;
+	if (diag210_to_senseid(senseid, &diag_data))
+		goto err_unknown;
+	return 0;
 
+err_unknown:
+	CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: unknown diag210 data\n",
+		      dev_id->ssid, dev_id->devno);
+	return -ENODEV;
+err_failed:
+	CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: diag210 failed (rc=%d)\n",
+		      dev_id->ssid, dev_id->devno, rc);
 	return -ENODEV;
 }
 
 /*
- * Start Sense ID helper function.
- * Try to obtain the 'control unit'/'device type' information
- *  associated with the subchannel.
+ * Initialize SENSE ID data.
  */
-static int
-__ccw_device_sense_id_start(struct ccw_device *cdev)
-{
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
-	/* Setup sense channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_SENSE_ID;
-	ccw->cda = (__u32) __pa (&cdev->private->senseid);
-	ccw->count = sizeof (struct senseid);
-	ccw->flags = CCW_FLAG_SLI;
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	/* Try on every path. */
-	ret = -ENODEV;
-	while (cdev->private->imask != 0) {
-		cdev->private->senseid.cu_type = 0xFFFF;
-		if ((sch->opm & cdev->private->imask) != 0 &&
-		    cdev->private->iretry > 0) {
-			cdev->private->iretry--;
-			/* Reset internal retry indication. */
-			cdev->private->flags.intretry = 0;
-			ret = cio_start (sch, cdev->private->iccws,
-					 cdev->private->imask);
-			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
-			if (ret != -EACCES)
-				return ret;
-		}
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-	}
-	return ret;
-}
-
-void
-ccw_device_sense_id_start(struct ccw_device *cdev)
+static void snsid_init(struct ccw_device *cdev)
 {
-	int ret;
-
-	memset (&cdev->private->senseid, 0, sizeof (struct senseid));
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
-	ret = __ccw_device_sense_id_start(cdev);
-	if (ret && ret != -EBUSY)
-		ccw_device_sense_id_done(cdev, ret);
+	cdev->private->flags.esid = 0;
+	memset(&cdev->private->senseid, 0, sizeof(cdev->private->senseid));
+	cdev->private->senseid.cu_type = 0xffff;
 }
 
 /*
- * Called from interrupt context to check if a valid answer
- * to Sense ID was received.
+ * Check for complete SENSE ID data.
  */
-static int
-ccw_device_check_sense_id(struct ccw_device *cdev)
+static int snsid_check(struct ccw_device *cdev, void *data)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
+	struct cmd_scsw *scsw = &cdev->private->irb.scsw.cmd;
+	int len = sizeof(struct senseid) - scsw->count;
 
-	/* Check the error cases. */
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Sense ID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) {
-		/*
-		 * if the device doesn't support the SenseID
-		 *  command further retries wouldn't help ...
-		 * NB: We don't check here for intervention required like we
-		 *     did before, because tape devices with no tape inserted
-		 *     may present this status *in conjunction with* the
-		 *     sense id information. So, for intervention required,
-		 *     we use the "whack it until it talks" strategy...
-		 */
-		CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel "
-			      "0.%x.%04x reports cmd reject\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no);
+	/* Check for incomplete SENSE ID data. */
+	if (len < SENSE_ID_MIN_LEN)
+		goto out_restart;
+	if (cdev->private->senseid.cu_type == 0xffff)
+		goto out_restart;
+	/* Check for incompatible SENSE ID data. */
+	if (cdev->private->senseid.reserved != 0xff)
 		return -EOPNOTSUPP;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, "
-			      "lpum %02X, cnt %02d, sns :"
-			      " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.sublog.lpum,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		u8 lpm;
-
-		lpm = to_io_private(sch)->orb.cmd.lpm;
-		if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0)
-			CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x "
-				      "on subchannel 0.%x.%04x is "
-				      "'not operational'\n", lpm,
-				      cdev->private->dev_id.devno,
-				      sch->schid.ssid, sch->schid.sch_no);
-		return -EACCES;
-	}
-
-	/* Did we get a proper answer ? */
-	if (irb->scsw.cmd.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF &&
-	    cdev->private->senseid.reserved == 0xFF) {
-		if (irb->scsw.cmd.count < sizeof(struct senseid) - 8)
-			cdev->private->flags.esid = 1;
-		return 0; /* Success */
-	}
+	/* Check for extended-identification information. */
+	if (len > SENSE_ID_BASIC_LEN)
+		cdev->private->flags.esid = 1;
+	return 0;
 
-	/* Hmm, whatever happened, try again. */
-	CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on "
-		      "subchannel 0.%x.%04x returns status %02X%02X\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no,
-		      irb->scsw.cmd.dstat, irb->scsw.cmd.cstat);
+out_restart:
+	snsid_init(cdev);
 	return -EAGAIN;
 }
 
 /*
- * Got interrupt for Sense ID.
+ * Process SENSE ID request result.
  */
-void
-ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void snsid_callback(struct ccw_device *cdev, void *data, int rc)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	struct senseid *senseid = &cdev->private->senseid;
+	int vm = 0;
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = (struct irb *) __LC_IRB;
-	/* Retry sense id, if needed. */
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if ((irb->scsw.cmd.cc == 1) || !irb->scsw.cmd.actl) {
-			ret = __ccw_device_sense_id_start(cdev);
-			if (ret && ret != -EBUSY)
-				ccw_device_sense_id_done(cdev, ret);
+	if (rc && MACHINE_IS_VM) {
+		/* Try diag 0x210 fallback on z/VM. */
+		snsid_init(cdev);
+		if (diag210_get_dev_info(cdev) == 0) {
+			rc = 0;
+			vm = 1;
 		}
-		return;
 	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	ret = ccw_device_check_sense_id(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN or -EACCES */
-	case 0:			/* Sense id succeeded. */
-	case -ETIME:		/* Sense id stopped by timeout. */
-		ccw_device_sense_id_done(cdev, ret);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		sch->lpm &= ~cdev->private->imask;
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		/* fall through. */
-	case -EAGAIN:		/* try again. */
-		ret = __ccw_device_sense_id_start(cdev);
-		if (ret == 0 || ret == -EBUSY)
-			break;
-		/* fall through. */
-	default:		/* Sense ID failed. Try asking VM. */
-		if (MACHINE_IS_VM)
-			ret = diag_get_dev_info(cdev->private->dev_id.devno,
-						&cdev->private->senseid);
-		else
-			/*
-			 * If we can't couldn't identify the device type we
-			 *  consider the device "not operational".
-			 */
-			ret = -ENODEV;
+	CIO_MSG_EVENT(2, "snsid: device 0.%x.%04x: rc=%d %04x/%02x "
+		      "%04x/%02x%s\n", id->ssid, id->devno, rc,
+		      senseid->cu_type, senseid->cu_model, senseid->dev_type,
+		      senseid->dev_model, vm ? " (diag210)" : "");
+	ccw_device_sense_id_done(cdev, rc);
+}
 
-		ccw_device_sense_id_done(cdev, ret);
-		break;
-	}
+/**
+ * ccw_device_sense_id_start - perform SENSE ID
+ * @cdev: ccw device
+ *
+ * Execute a SENSE ID channel program on @cdev to update its sense id
+ * information. When finished, call ccw_device_sense_id_done with a
+ * return code specifying the result.
+ */
+void ccw_device_sense_id_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+
+	CIO_TRACE_EVENT(4, "snsid");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Data setup. */
+	snsid_init(cdev);
+	/* Channel program setup. */
+	cp->cmd_code	= CCW_CMD_SENSE_ID;
+	cp->cda		= (u32) (addr_t) &cdev->private->senseid;
+	cp->count	= sizeof(struct senseid);
+	cp->flags	= CCW_FLAG_SLI;
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->cp		= cp;
+	req->timeout	= SENSE_ID_TIMEOUT;
+	req->maxretries	= SENSE_ID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->check	= snsid_check;
+	req->callback	= snsid_callback;
+	ccw_request_start(cdev);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device_ops.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device_ops.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device_ops.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device_ops.c	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 #include <linux/list.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/completion.h>
 
 #include <asm/ccwdev.h>
 #include <asm/idals.h>
@@ -46,6 +47,7 @@ int ccw_device_set_options_mask(struct c
 	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
 	cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
 	cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
+	cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
 	return 0;
 }
 
@@ -74,6 +76,7 @@ int ccw_device_set_options(struct ccw_de
 	cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
 	cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
 	cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
+	cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
 	return 0;
 }
 
@@ -90,7 +93,32 @@ void ccw_device_clear_options(struct ccw
 	cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
 	cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
 	cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
+	cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
+}
+
+/**
+ * ccw_device_is_pathgroup - determine if paths to this device are grouped
+ * @cdev: ccw device
+ *
+ * Return non-zero if there is a path group, zero otherwise.
+ */
+int ccw_device_is_pathgroup(struct ccw_device *cdev)
+{
+	return cdev->private->flags.pgroup;
+}
+EXPORT_SYMBOL(ccw_device_is_pathgroup);
+
+/**
+ * ccw_device_is_multipath - determine if device is operating in multipath mode
+ * @cdev: ccw device
+ *
+ * Return non-zero if device is operating in multipath mode, zero otherwise.
+ */
+int ccw_device_is_multipath(struct ccw_device *cdev)
+{
+	return cdev->private->flags.mpath;
 }
+EXPORT_SYMBOL(ccw_device_is_multipath);
 
 /**
  * ccw_device_clear() - terminate I/O request processing
@@ -167,8 +195,7 @@ int ccw_device_start_key(struct ccw_devi
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
 		return -ENODEV;
-	if (cdev->private->state == DEV_STATE_VERIFY ||
-	    cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
+	if (cdev->private->state == DEV_STATE_VERIFY) {
 		/* Remember to fake irb when finished. */
 		if (!cdev->private->flags.fake_irb) {
 			cdev->private->flags.fake_irb = 1;
@@ -478,74 +505,65 @@ __u8 ccw_device_get_path_mask(struct ccw
 	return sch->lpm;
 }
 
-/*
- * Try to break the lock on a boxed device.
- */
-int
-ccw_device_stlck(struct ccw_device *cdev)
-{
-	void *buf, *buf2;
-	unsigned long flags;
-	struct subchannel *sch;
-	int ret;
+struct stlck_data {
+	struct completion done;
+	int rc;
+};
 
-	if (!cdev)
-		return -ENODEV;
+void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc)
+{
+	struct stlck_data *sdata = data;
 
-	if (cdev->drv && !cdev->private->options.force)
-		return -EINVAL;
+	sdata->rc = rc;
+	complete(&sdata->done);
+}
 
-	sch = to_subchannel(cdev->dev.parent);
-	
-	CIO_TRACE_EVENT(2, "stl lock");
-	CIO_TRACE_EVENT(2, dev_name(&cdev->dev));
+/*
+ * Perform unconditional reserve + release.
+ */
+int ccw_device_stlck(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct stlck_data data;
+	u8 *buffer;
+	int rc;
 
-	buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-	buf2 = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
-	if (!buf2) {
-		kfree(buf);
-		return -ENOMEM;
+	/* Check if steal lock operation is valid for this device. */
+	if (cdev->drv) {
+		if (!cdev->private->options.force)
+			return -EINVAL;
 	}
-	spin_lock_irqsave(sch->lock, flags);
-	ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
-	if (ret)
-		goto out_unlock;
-	/*
-	 * Setup ccw. We chain an unconditional reserve and a release so we
-	 * only break the lock.
-	 */
-	cdev->private->iccws[0].cmd_code = CCW_CMD_STLCK;
-	cdev->private->iccws[0].cda = (__u32) __pa(buf);
-	cdev->private->iccws[0].count = 32;
-	cdev->private->iccws[0].flags = CCW_FLAG_CC;
-	cdev->private->iccws[1].cmd_code = CCW_CMD_RELEASE;
-	cdev->private->iccws[1].cda = (__u32) __pa(buf2);
-	cdev->private->iccws[1].count = 32;
-	cdev->private->iccws[1].flags = 0;
-	ret = cio_start(sch, cdev->private->iccws, 0);
-	if (ret) {
-		cio_disable_subchannel(sch); //FIXME: return code?
+	buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+	init_completion(&data.done);
+	data.rc = -EIO;
+	spin_lock_irq(sch->lock);
+	rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
+	if (rc)
 		goto out_unlock;
+	/* Perform operation. */
+	cdev->private->state = DEV_STATE_STEAL_LOCK,
+	ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
+	spin_unlock_irq(sch->lock);
+	/* Wait for operation to finish. */
+	if (wait_for_completion_interruptible(&data.done)) {
+		/* Got a signal. */
+		spin_lock_irq(sch->lock);
+		ccw_request_cancel(cdev);
+		spin_unlock_irq(sch->lock);
+		wait_for_completion(&data.done);
 	}
-	cdev->private->irb.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
-	spin_unlock_irqrestore(sch->lock, flags);
-	wait_event(cdev->private->wait_q,
-		   cdev->private->irb.scsw.cmd.actl == 0);
-	spin_lock_irqsave(sch->lock, flags);
-	cio_disable_subchannel(sch); //FIXME: return code?
-	if ((cdev->private->irb.scsw.cmd.dstat !=
-	     (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
-	    (cdev->private->irb.scsw.cmd.cstat != 0))
-		ret = -EIO;
-	/* Clear irb. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
+	rc = data.rc;
+	/* Check results. */
+	spin_lock_irq(sch->lock);
+	cio_disable_subchannel(sch);
+	cdev->private->state = DEV_STATE_BOXED;
 out_unlock:
-	kfree(buf);
-	kfree(buf2);
-	spin_unlock_irqrestore(sch->lock, flags);
-	return ret;
+	spin_unlock_irq(sch->lock);
+	kfree(buffer);
+
+	return rc;
 }
 
 void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device_pgid.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device_pgid.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device_pgid.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device_pgid.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,594 +1,568 @@
 /*
- * drivers/s390/cio/device_pgid.c
- *
- *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
- *			 IBM Corporation
- *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
- *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *  CCW device PGID and path verification I/O handling.
  *
- * Path Group ID functions.
+ *    Copyright IBM Corp. 2002,2009
+ *    Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
-
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
-#include <asm/delay.h>
-#include <asm/lowcore.h>
 
 #include "cio.h"
 #include "cio_debug.h"
-#include "css.h"
 #include "device.h"
-#include "ioasm.h"
 #include "io_sch.h"
 
+#define PGID_RETRIES	256
+#define PGID_TIMEOUT	(10 * HZ)
+
 /*
- * Helper function called from interrupt context to decide whether an
- * operation should be tried again.
+ * Process path verification data and report result.
  */
-static int __ccw_device_should_retry(union scsw *scsw)
+static void verify_done(struct ccw_device *cdev, int rc)
 {
-	/* CC is only valid if start function bit is set. */
-	if ((scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && scsw->cmd.cc == 1)
-		return 1;
-	/* No more activity. For sense and set PGID we stubbornly try again. */
-	if (!scsw->cmd.actl)
-		return 1;
-	return 0;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	int mpath = cdev->private->flags.mpath;
+	int pgroup = cdev->private->flags.pgroup;
+
+	if (rc)
+		goto out;
+	/* Ensure consistent multipathing state at device and channel. */
+	if (sch->config.mp != mpath) {
+		sch->config.mp = mpath;
+		rc = cio_commit_config(sch);
+	}
+out:
+	CIO_MSG_EVENT(2, "vrfy: device 0.%x.%04x: rc=%d pgroup=%d mpath=%d "
+			 "vpm=%02x\n", id->ssid, id->devno, rc, pgroup, mpath,
+			 sch->vpm);
+	ccw_device_verify_done(cdev, rc);
 }
 
 /*
- * Start Sense Path Group ID helper function. Used in ccw_device_recog
- * and ccw_device_sense_pgid.
+ * Create channel program to perform a NOOP.
  */
-static int
-__ccw_device_sense_pgid_start(struct ccw_device *cdev)
+static void nop_build_cp(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-	int i;
-
-	sch = to_subchannel(cdev->dev.parent);
-	/* Return if we already checked on all paths. */
-	if (cdev->private->imask == 0)
-		return (sch->lpm == 0) ? -ENODEV : -EACCES;
-	i = 8 - ffs(cdev->private->imask);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
 
-	/* Setup sense path group id channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_SENSE_PGID;
-	ccw->count = sizeof (struct pgid);
-	ccw->flags = CCW_FLAG_SLI;
+	cp->cmd_code	= CCW_CMD_NOOP;
+	cp->cda		= 0;
+	cp->count	= 0;
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
+}
 
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	/* Try on every path. */
-	ret = -ENODEV;
-	while (cdev->private->imask != 0) {
-		/* Try every path multiple times. */
-		ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
-		if (cdev->private->iretry > 0) {
-			cdev->private->iretry--;
-			/* Reset internal retry indication. */
-			cdev->private->flags.intretry = 0;
-			ret = cio_start (sch, cdev->private->iccws, 
-					 cdev->private->imask);
-			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
-			if (ret != -EACCES)
-				return ret;
-			CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel "
-				      "0.%x.%04x, lpm %02X, became 'not "
-				      "operational'\n",
-				      cdev->private->dev_id.devno,
-				      sch->schid.ssid,
-				      sch->schid.sch_no, cdev->private->imask);
+/*
+ * Perform NOOP on a single path.
+ */
+static void nop_do(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
 
-		}
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		i++;
-	}
+	/* Adjust lpm. */
+	req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & sch->opm);
+	if (!req->lpm)
+		goto out_nopath;
+	nop_build_cp(cdev);
+	ccw_request_start(cdev);
+	return;
 
-	return ret;
+out_nopath:
+	verify_done(cdev, sch->vpm ? 0 : -EACCES);
 }
 
-void
-ccw_device_sense_pgid_start(struct ccw_device *cdev)
+/*
+ * Adjust NOOP I/O status.
+ */
+static enum io_status nop_filter(struct ccw_device *cdev, void *data,
+				 struct irb *irb, enum io_status status)
 {
-	int ret;
-
-	/* Set a timeout of 60s */
-	ccw_device_set_timeout(cdev, 60*HZ);
-
-	cdev->private->state = DEV_STATE_SENSE_PGID;
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
-	memset (&cdev->private->pgid, 0, sizeof (cdev->private->pgid));
-	ret = __ccw_device_sense_pgid_start(cdev);
-	if (ret && ret != -EBUSY)
-		ccw_device_sense_pgid_done(cdev, ret);
+	/* Only subchannel status might indicate a path error. */
+	if (status == IO_STATUS_ERROR && irb->scsw.cmd.cstat == 0)
+		return IO_DONE;
+	return status;
 }
 
 /*
- * Called from interrupt context to check if a valid answer
- * to Sense Path Group ID was received.
+ * Process NOOP request result for a single path.
  */
-static int
-__ccw_device_check_sense_pgid(struct ccw_device *cdev)
+static void nop_callback(struct ccw_device *cdev, void *data, int rc)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int i;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Sense PGID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
-		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons &&
-	    (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
-		/*
-		 * If the device doesn't support the Sense Path Group ID
-		 *  command further retries wouldn't help ...
-		 */
-		return -EOPNOTSUPP;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, "
-			      "lpum %02X, cnt %02d, sns : "
-			      "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.sublog.lpum,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		u8 lpm;
+	if (rc == 0)
+		sch->vpm |= req->lpm;
+	else if (rc != -EACCES)
+		goto err;
+	req->lpm >>= 1;
+	nop_do(cdev);
+	return;
 
-		lpm = to_io_private(sch)->orb.cmd.lpm;
-		CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, lpm);
-		return -EACCES;
-	}
-	i = 8 - ffs(cdev->private->imask);
-	if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
-		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x "
-			      "is reserved by someone else\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no);
-		return -EUSERS;
-	}
-	return 0;
+err:
+	verify_done(cdev, rc);
 }
 
 /*
- * Got interrupt for Sense Path Group ID.
+ * Create channel program to perform SET PGID on a single path.
  */
-void
-ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void spid_build_cp(struct ccw_device *cdev, u8 fn)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
-
-	irb = (struct irb *) __LC_IRB;
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+	int i = 8 - ffs(req->lpm);
+	struct pgid *pgid = &cdev->private->pgid[i];
 
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw)) {
-			ret = __ccw_device_sense_pgid_start(cdev);
-			if (ret && ret != -EBUSY)
-				ccw_device_sense_pgid_done(cdev, ret);
-		}
-		return;
-	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	ret = __ccw_device_check_sense_pgid(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
-	case -EOPNOTSUPP:	/* Sense Path Group ID not supported */
-		ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP);
-		break;
-	case -ETIME:		/* Sense path group id stopped by timeout. */
-		ccw_device_sense_pgid_done(cdev, -ETIME);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		sch->lpm &= ~cdev->private->imask;
-		/* Fall through. */
-	case 0:			/* Sense Path Group ID successful. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		/* Fall through. */
-	case -EAGAIN:		/* Try again. */
-		ret = __ccw_device_sense_pgid_start(cdev);
-		if (ret != 0 && ret != -EBUSY)
-			ccw_device_sense_pgid_done(cdev, ret);
-		break;
-	case -EUSERS:		/* device is reserved for someone else. */
-		ccw_device_sense_pgid_done(cdev, -EUSERS);
-		break;
-	}
+	pgid->inf.fc	= fn;
+	cp->cmd_code	= CCW_CMD_SET_PGID;
+	cp->cda		= (u32) (addr_t) pgid;
+	cp->count	= sizeof(*pgid);
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
 }
 
 /*
- * Path Group ID helper function.
+ * Perform establish/resign SET PGID on a single path.
  */
-static int
-__ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
+static void spid_do(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
-
-	sch = to_subchannel(cdev->dev.parent);
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	u8 fn;
 
-	/* Setup sense path group id channel program. */
-	cdev->private->pgid[0].inf.fc = func;
-	ccw = cdev->private->iccws;
-	if (cdev->private->flags.pgid_single)
-		cdev->private->pgid[0].inf.fc |= SPID_FUNC_SINGLE_PATH;
+	/* Use next available path that is not already in correct state. */
+	req->lpm = lpm_adjust(req->lpm, cdev->private->pgid_todo_mask);
+	if (!req->lpm)
+		goto out_nopath;
+	/* Channel program setup. */
+	if (req->lpm & sch->opm)
+		fn = SPID_FUNC_ESTABLISH;
 	else
-		cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH;
-	ccw->cmd_code = CCW_CMD_SET_PGID;
-	ccw->cda = (__u32) __pa (&cdev->private->pgid[0]);
-	ccw->count = sizeof (struct pgid);
-	ccw->flags = CCW_FLAG_SLI;
-
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
+		fn = SPID_FUNC_RESIGN;
+	if (cdev->private->flags.mpath)
+		fn |= SPID_FUNC_MULTI_PATH;
+	spid_build_cp(cdev, fn);
+	ccw_request_start(cdev);
+	return;
 
-	/* Try multiple times. */
-	ret = -EACCES;
-	if (cdev->private->iretry > 0) {
-		cdev->private->iretry--;
-		/* Reset internal retry indication. */
-		cdev->private->flags.intretry = 0;
-		ret = cio_start (sch, cdev->private->iccws,
-				 cdev->private->imask);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if ((ret == 0) || (ret == -EBUSY))
-			return ret;
-	}
-	/* PGID command failed on this path. */
-	CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel "
-		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no, cdev->private->imask);
-	return ret;
+out_nopath:
+	verify_done(cdev, sch->vpm ? 0 : -EACCES);
 }
 
+static void verify_start(struct ccw_device *cdev);
+
 /*
- * Helper function to send a nop ccw down a path.
+ * Process SET PGID request result for a single path.
  */
-static int __ccw_device_do_nop(struct ccw_device *cdev)
+static void spid_callback(struct ccw_device *cdev, void *data, int rc)
 {
-	struct subchannel *sch;
-	struct ccw1 *ccw;
-	int ret;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
 
-	sch = to_subchannel(cdev->dev.parent);
+	switch (rc) {
+	case 0:
+		sch->vpm |= req->lpm & sch->opm;
+		break;
+	case -EACCES:
+		break;
+	case -EOPNOTSUPP:
+		if (cdev->private->flags.mpath) {
+			/* Try without multipathing. */
+			cdev->private->flags.mpath = 0;
+			goto out_restart;
+		}
+		/* Try without pathgrouping. */
+		cdev->private->flags.pgroup = 0;
+		goto out_restart;
+	default:
+		goto err;
+	}
+	req->lpm >>= 1;
+	spid_do(cdev);
+	return;
 
-	/* Setup nop channel program. */
-	ccw = cdev->private->iccws;
-	ccw->cmd_code = CCW_CMD_NOOP;
-	ccw->cda = 0;
-	ccw->count = 0;
-	ccw->flags = CCW_FLAG_SLI;
+out_restart:
+	verify_start(cdev);
+	return;
+err:
+	verify_done(cdev, rc);
+}
 
-	/* Reset device status. */
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
+static void spid_start(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
 
-	/* Try multiple times. */
-	ret = -EACCES;
-	if (cdev->private->iretry > 0) {
-		cdev->private->iretry--;
-		/* Reset internal retry indication. */
-		cdev->private->flags.intretry = 0;
-		ret = cio_start (sch, cdev->private->iccws,
-				 cdev->private->imask);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if ((ret == 0) || (ret == -EBUSY))
-			return ret;
-	}
-	/* nop command failed on this path. */
-	CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel "
-		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-		      cdev->private->dev_id.devno, sch->schid.ssid,
-		      sch->schid.sch_no, cdev->private->imask);
-	return ret;
+	/* Initialize request data. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= 0x80;
+	req->callback	= spid_callback;
+	spid_do(cdev);
 }
 
+static int pgid_cmp(struct pgid *p1, struct pgid *p2)
+{
+	return memcmp((char *) p1 + 1, (char *) p2 + 1,
+		      sizeof(struct pgid) - 1);
+}
 
 /*
- * Called from interrupt context to check if a valid answer
- * to Set Path Group ID was received.
+ * Determine pathgroup state from PGID data.
  */
-static int
-__ccw_device_check_pgid(struct ccw_device *cdev)
+static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
+			 int *mismatch, int *reserved, int *reset)
 {
-	struct subchannel *sch;
-	struct irb *irb;
+	struct pgid *pgid = &cdev->private->pgid[0];
+	struct pgid *first = NULL;
+	int lpm;
+	int i;
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry Set PGID if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
+	*mismatch = 0;
+	*reserved = 0;
+	*reset = 0;
+	for (i = 0, lpm = 0x80; i < 8; i++, pgid++, lpm >>= 1) {
+		if ((cdev->private->pgid_valid_mask & lpm) == 0)
+			continue;
+		if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE)
+			*reserved = 1;
+		if (pgid->inf.ps.state1 == SNID_STATE1_RESET) {
+			/* A PGID was reset. */
+			*reset = 1;
+			continue;
 		}
-		return -ETIME;
-	}
-	if (irb->esw.esw0.erw.cons) {
-		if (irb->ecw[0] & SNS0_CMD_REJECT)
-			return -EOPNOTSUPP;
-		/* Hmm, whatever happened, try again. */
-		CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, "
-			      "cnt %02d, "
-			      "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->dev_id.ssid,
-			      cdev->private->dev_id.devno,
-			      irb->esw.esw0.erw.scnt,
-			      irb->ecw[0], irb->ecw[1],
-			      irb->ecw[2], irb->ecw[3],
-			      irb->ecw[4], irb->ecw[5],
-			      irb->ecw[6], irb->ecw[7]);
-		return -EAGAIN;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, cdev->private->imask);
-		return -EACCES;
+		if (!first) {
+			first = pgid;
+			continue;
+		}
+		if (pgid_cmp(pgid, first) != 0)
+			*mismatch = 1;
 	}
-	return 0;
+	if (!first)
+		first = &channel_subsystems[0]->global_pgid;
+	*p = first;
 }
 
-/*
- * Called from interrupt context to check the path status after a nop has
- * been send.
- */
-static int __ccw_device_check_nop(struct ccw_device *cdev)
+static u8 pgid_to_donepm(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct irb *irb;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct pgid *pgid;
+	int i;
+	int lpm;
+	u8 donepm = 0;
 
-	sch = to_subchannel(cdev->dev.parent);
-	irb = &cdev->private->irb;
-	if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
-		/* Retry NOP if requested. */
-		if (cdev->private->flags.intretry) {
-			cdev->private->flags.intretry = 0;
-			return -EAGAIN;
+	/* Set bits for paths which are already in the target state. */
+	for (i = 0; i < 8; i++) {
+		lpm = 0x80 >> i;
+		if ((cdev->private->pgid_valid_mask & lpm) == 0)
+			continue;
+		pgid = &cdev->private->pgid[i];
+		if (sch->opm & lpm) {
+			if (pgid->inf.ps.state1 != SNID_STATE1_GROUPED)
+				continue;
+		} else {
+			if (pgid->inf.ps.state1 != SNID_STATE1_UNGROUPED)
+				continue;
 		}
-		return -ETIME;
-	}
-	if (irb->scsw.cmd.cc == 3) {
-		CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x,"
-			      " lpm %02X, became 'not operational'\n",
-			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schid.sch_no, cdev->private->imask);
-		return -EACCES;
+		if (cdev->private->flags.mpath) {
+			if (pgid->inf.ps.state3 != SNID_STATE3_MULTI_PATH)
+				continue;
+		} else {
+			if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH)
+				continue;
+		}
+		donepm |= lpm;
 	}
-	return 0;
+
+	return donepm;
 }
 
-static void
-__ccw_device_verify_start(struct ccw_device *cdev)
+static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid)
 {
-	struct subchannel *sch;
-	__u8 func;
-	int ret;
+	int i;
 
-	sch = to_subchannel(cdev->dev.parent);
-	/* Repeat for all paths. */
-	for (; cdev->private->imask; cdev->private->imask >>= 1,
-				     cdev->private->iretry = 5) {
-		if ((cdev->private->imask & sch->schib.pmcw.pam) == 0)
-			/* Path not available, try next. */
-			continue;
-		if (cdev->private->options.pgroup) {
-			if (sch->opm & cdev->private->imask)
-				func = SPID_FUNC_ESTABLISH;
-			else
-				func = SPID_FUNC_RESIGN;
-			ret = __ccw_device_do_pgid(cdev, func);
-		} else
-			ret = __ccw_device_do_nop(cdev);
-		/* We expect an interrupt in case of success or busy
-		 * indication. */
-		if (ret == 0 || ret == -EBUSY)
-			return;
-		/* Permanent path failure, try next. */
-	}
-	/* Done with all paths. */
-	ccw_device_verify_done(cdev, (sch->vpm != 0) ? 0 : -ENODEV);
+	for (i = 0; i < 8; i++)
+		memcpy(&cdev->private->pgid[i], pgid, sizeof(struct pgid));
 }
-		
+
 /*
- * Got interrupt for Set Path Group ID.
+ * Process SENSE PGID data and report result.
  */
-void
-ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
+static void snid_done(struct ccw_device *cdev, int rc)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
-
-	irb = (struct irb *) __LC_IRB;
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct pgid *pgid;
+	int mismatch = 0;
+	int reserved = 0;
+	int reset = 0;
+	u8 donepm;
 
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw))
-			__ccw_device_verify_start(cdev);
-		return;
+	if (rc)
+		goto out;
+	pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset);
+	if (reserved)
+		rc = -EUSERS;
+	else if (mismatch)
+		rc = -EOPNOTSUPP;
+	else {
+		donepm = pgid_to_donepm(cdev);
+		sch->vpm = donepm & sch->opm;
+		cdev->private->pgid_todo_mask &= ~donepm;
+		pgid_fill(cdev, pgid);
 	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	if (cdev->private->options.pgroup)
-		ret = __ccw_device_check_pgid(cdev);
-	else
-		ret = __ccw_device_check_nop(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-	switch (ret) {
-	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
+out:
+	CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
+		      "todo=%02x mism=%d rsvd=%d reset=%d\n", id->ssid,
+		      id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm,
+		      cdev->private->pgid_todo_mask, mismatch, reserved, reset);
+	switch (rc) {
 	case 0:
-		/* Path verification ccw finished successfully, update lpm. */
-		sch->vpm |= sch->opm & cdev->private->imask;
-		/* Go on with next path. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_verify_start(cdev);
+		/* Anything left to do? */
+		if (cdev->private->pgid_todo_mask == 0) {
+			verify_done(cdev, sch->vpm == 0 ? -EACCES : 0);
+			return;
+		}
+		/* Perform path-grouping. */
+		spid_start(cdev);
 		break;
 	case -EOPNOTSUPP:
-		/*
-		 * One of those strange devices which claim to be able
-		 * to do multipathing but not for Set Path Group ID.
-		 */
-		if (cdev->private->flags.pgid_single)
-			cdev->private->options.pgroup = 0;
-		else
-			cdev->private->flags.pgid_single = 1;
-		/* Retry */
-		sch->vpm = 0;
-		cdev->private->imask = 0x80;
-		cdev->private->iretry = 5;
-		/* fall through. */
-	case -EAGAIN:		/* Try again. */
-		__ccw_device_verify_start(cdev);
-		break;
-	case -ETIME:		/* Set path group id stopped by timeout. */
-		ccw_device_verify_done(cdev, -ETIME);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_verify_start(cdev);
+		/* Path-grouping not supported. */
+		cdev->private->flags.pgroup = 0;
+		cdev->private->flags.mpath = 0;
+		verify_start(cdev);
 		break;
+	default:
+		verify_done(cdev, rc);
 	}
 }
 
-void
-ccw_device_verify_start(struct ccw_device *cdev)
+/*
+ * Create channel program to perform a SENSE PGID on a single path.
+ */
+static void snid_build_cp(struct ccw_device *cdev)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+	int i = 8 - ffs(req->lpm);
+
+	/* Channel program setup. */
+	cp->cmd_code	= CCW_CMD_SENSE_PGID;
+	cp->cda		= (u32) (addr_t) &cdev->private->pgid[i];
+	cp->count	= sizeof(struct pgid);
+	cp->flags	= CCW_FLAG_SLI;
+	req->cp		= cp;
+}
+
+/*
+ * Perform SENSE PGID on a single path.
+ */
+static void snid_do(struct ccw_device *cdev)
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
 
-	cdev->private->flags.pgid_single = 0;
-	cdev->private->imask = 0x80;
-	cdev->private->iretry = 5;
+	/* Adjust lpm if paths are not set in pam. */
+	req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam);
+	if (!req->lpm)
+		goto out_nopath;
+	snid_build_cp(cdev);
+	ccw_request_start(cdev);
+	return;
 
-	/* Start with empty vpm. */
-	sch->vpm = 0;
+out_nopath:
+	snid_done(cdev, cdev->private->pgid_valid_mask ? 0 : -EACCES);
+}
 
-	/* Get current pam. */
-	if (cio_update_schib(sch)) {
-		ccw_device_verify_done(cdev, -ENODEV);
-		return;
-	}
-	/* After 60s path verification is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
-	__ccw_device_verify_start(cdev);
+/*
+ * Process SENSE PGID request result for single path.
+ */
+static void snid_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct ccw_request *req = &cdev->private->req;
+
+	if (rc == 0)
+		cdev->private->pgid_valid_mask |= req->lpm;
+	else if (rc != -EACCES)
+		goto err;
+	req->lpm >>= 1;
+	snid_do(cdev);
+	return;
+
+err:
+	snid_done(cdev, rc);
 }
 
-static void
-__ccw_device_disband_start(struct ccw_device *cdev)
+/*
+ * Perform path verification.
+ */
+static void verify_start(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	int ret;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw_dev_id *devid = &cdev->private->dev_id;
 
-	sch = to_subchannel(cdev->dev.parent);
-	while (cdev->private->imask != 0) {
-		if (sch->lpm & cdev->private->imask) {
-			ret = __ccw_device_do_pgid(cdev, SPID_FUNC_DISBAND);
-			if (ret == 0)
-				return;
-		}
-		cdev->private->iretry = 5;
-		cdev->private->imask >>= 1;
+	sch->vpm = 0;
+	sch->lpm = sch->schib.pmcw.pam;
+	/* Initialize request data. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= 0x80;
+	if (cdev->private->flags.pgroup) {
+		CIO_TRACE_EVENT(4, "snid");
+		CIO_HEX_EVENT(4, devid, sizeof(*devid));
+		req->callback	= snid_callback;
+		snid_do(cdev);
+	} else {
+		CIO_TRACE_EVENT(4, "nop");
+		CIO_HEX_EVENT(4, devid, sizeof(*devid));
+		req->filter	= nop_filter;
+		req->callback	= nop_callback;
+		nop_do(cdev);
 	}
-	ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV);
 }
 
-/*
- * Got interrupt for Unset Path Group ID.
+/**
+ * ccw_device_verify_start - perform path verification
+ * @cdev: ccw device
+ *
+ * Perform an I/O on each available channel path to @cdev to determine which
+ * paths are operational. The resulting path mask is stored in sch->vpm.
+ * If device options specify pathgrouping, establish a pathgroup for the
+ * operational paths. When finished, call ccw_device_verify_done with a
+ * return code specifying the result.
  */
-void
-ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
+void ccw_device_verify_start(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-	struct irb *irb;
-	int ret;
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
-	irb = (struct irb *) __LC_IRB;
+	CIO_TRACE_EVENT(4, "vrfy");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Initialize PGID data. */
+	memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid));
+	cdev->private->pgid_valid_mask = 0;
+	cdev->private->pgid_todo_mask = sch->schib.pmcw.pam;
+	/*
+	 * Initialize pathgroup and multipath state with target values.
+	 * They may change in the course of path verification.
+	 */
+	cdev->private->flags.pgroup = cdev->private->options.pgroup;
+	cdev->private->flags.mpath = cdev->private->options.mpath;
+	cdev->private->flags.doverify = 0;
+	verify_start(cdev);
+}
 
-	if (irb->scsw.cmd.stctl ==
-	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
-		if (__ccw_device_should_retry(&irb->scsw))
-			__ccw_device_disband_start(cdev);
-		return;
-	}
-	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
-		return;
-	sch = to_subchannel(cdev->dev.parent);
-	ret = __ccw_device_check_pgid(cdev);
-	memset(&cdev->private->irb, 0, sizeof(struct irb));
-	switch (ret) {
-	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
-	case 0:			/* disband successful. */
-		ccw_device_disband_done(cdev, ret);
-		break;
-	case -EOPNOTSUPP:
-		/*
-		 * One of those strange devices which claim to be able
-		 * to do multipathing but not for Unset Path Group ID.
-		 */
-		cdev->private->flags.pgid_single = 1;
-		/* fall through. */
-	case -EAGAIN:		/* Try again. */
-		__ccw_device_disband_start(cdev);
-		break;
-	case -ETIME:		/* Set path group id stopped by timeout. */
-		ccw_device_disband_done(cdev, -ETIME);
-		break;
-	case -EACCES:		/* channel is not operational. */
-		cdev->private->imask >>= 1;
-		cdev->private->iretry = 5;
-		__ccw_device_disband_start(cdev);
-		break;
+/*
+ * Process disband SET PGID request result.
+ */
+static void disband_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_dev_id *id = &cdev->private->dev_id;
+
+	if (rc)
+		goto out;
+	/* Ensure consistent multipathing state at device and channel. */
+	cdev->private->flags.mpath = 0;
+	if (sch->config.mp) {
+		sch->config.mp = 0;
+		rc = cio_commit_config(sch);
 	}
+out:
+	CIO_MSG_EVENT(0, "disb: device 0.%x.%04x: rc=%d\n", id->ssid, id->devno,
+		      rc);
+	ccw_device_disband_done(cdev, rc);
 }
 
-void
-ccw_device_disband_start(struct ccw_device *cdev)
+/**
+ * ccw_device_disband_start - disband pathgroup
+ * @cdev: ccw device
+ *
+ * Execute a SET PGID channel program on @cdev to disband a previously
+ * established pathgroup. When finished, call ccw_device_disband_done with
+ * a return code specifying the result.
+ */
+void ccw_device_disband_start(struct ccw_device *cdev)
 {
-	/* After 60s disbanding is considered to have failed. */
-	ccw_device_set_timeout(cdev, 60*HZ);
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+	u8 fn;
 
-	cdev->private->flags.pgid_single = 0;
-	cdev->private->iretry = 5;
-	cdev->private->imask = 0x80;
-	__ccw_device_disband_start(cdev);
+	CIO_TRACE_EVENT(4, "disb");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->callback	= disband_callback;
+	fn = SPID_FUNC_DISBAND;
+	if (cdev->private->flags.mpath)
+		fn |= SPID_FUNC_MULTI_PATH;
+	spid_build_cp(cdev, fn);
+	ccw_request_start(cdev);
+}
+
+static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
+{
+	struct ccw_request *req = &cdev->private->req;
+	struct ccw1 *cp = cdev->private->iccws;
+
+	cp[0].cmd_code = CCW_CMD_STLCK;
+	cp[0].cda = (u32) (addr_t) buf1;
+	cp[0].count = 32;
+	cp[0].flags = CCW_FLAG_CC;
+	cp[1].cmd_code = CCW_CMD_RELEASE;
+	cp[1].cda = (u32) (addr_t) buf2;
+	cp[1].count = 32;
+	cp[1].flags = 0;
+	req->cp = cp;
+}
+
+static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
+{
+	ccw_device_stlck_done(cdev, data, rc);
+}
+
+/**
+ * ccw_device_stlck_start - perform unconditional release
+ * @cdev: ccw device
+ * @data: data pointer to be passed to ccw_device_stlck_done
+ * @buf1: data pointer used in channel program
+ * @buf2: data pointer used in channel program
+ *
+ * Execute a channel program on @cdev to release an existing PGID reservation.
+ * When finished, call ccw_device_stlck_done with a return code specifying the
+ * result.
+ */
+void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
+			    void *buf2)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+	struct ccw_request *req = &cdev->private->req;
+
+	CIO_TRACE_EVENT(4, "stlck");
+	CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
+	/* Request setup. */
+	memset(req, 0, sizeof(*req));
+	req->timeout	= PGID_TIMEOUT;
+	req->maxretries	= PGID_RETRIES;
+	req->lpm	= sch->schib.pmcw.pam & sch->opm;
+	req->data	= data;
+	req->callback	= stlck_callback;
+	stlck_build_cp(cdev, buf1, buf2);
+	ccw_request_start(cdev);
 }
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/device_status.c linux-libre-2.6.33-gnu1/drivers/s390/cio/device_status.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/device_status.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/device_status.c	2010-02-24 13:52:17.000000000 -0500
@@ -336,9 +336,6 @@ ccw_device_do_sense(struct ccw_device *c
 	sense_ccw->count = SENSE_MAX_COUNT;
 	sense_ccw->flags = CCW_FLAG_SLI;
 
-	/* Reset internal retry indication. */
-	cdev->private->flags.intretry = 0;
-
 	rc = cio_start(sch, sense_ccw, 0xff);
 	if (rc == -ENODEV || rc == -EACCES)
 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/fcx.c linux-libre-2.6.33-gnu1/drivers/s390/cio/fcx.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/fcx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/fcx.c	2010-02-24 13:52:17.000000000 -0500
@@ -163,7 +163,7 @@ void tcw_finalize(struct tcw *tcw, int n
 	/* Add tcat to tccb. */
 	tccb = tcw_get_tccb(tcw);
 	tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)];
-	memset(tcat, 0, sizeof(tcat));
+	memset(tcat, 0, sizeof(*tcat));
 	/* Calculate tcw input/output count and tcat transport count. */
 	count = calc_dcw_count(tccb);
 	if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA))
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(tccb_init);
  */
 void tsb_init(struct tsb *tsb)
 {
-	memset(tsb, 0, sizeof(tsb));
+	memset(tsb, 0, sizeof(*tsb));
 }
 EXPORT_SYMBOL(tsb_init);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/io_sch.h linux-libre-2.6.33-gnu1/drivers/s390/cio/io_sch.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/io_sch.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/io_sch.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,7 +1,10 @@
 #ifndef S390_IO_SCH_H
 #define S390_IO_SCH_H
 
+#include <linux/types.h>
 #include <asm/schid.h>
+#include <asm/ccwdev.h>
+#include "css.h"
 
 /*
  * command-mode operation request block
@@ -68,6 +71,52 @@ struct io_subchannel_private {
 #define MAX_CIWS 8
 
 /*
+ * Possible status values for a CCW request's I/O.
+ */
+enum io_status {
+	IO_DONE,
+	IO_RUNNING,
+	IO_STATUS_ERROR,
+	IO_PATH_ERROR,
+	IO_REJECTED,
+	IO_KILLED
+};
+
+/**
+ * ccw_request - Internal CCW request.
+ * @cp: channel program to start
+ * @timeout: maximum allowable time in jiffies between start I/O and interrupt
+ * @maxretries: number of retries per I/O operation and path
+ * @lpm: mask of paths to use
+ * @check: optional callback that determines if results are final
+ * @filter: optional callback to adjust request status based on IRB data
+ * @callback: final callback
+ * @data: user-defined pointer passed to all callbacks
+ * @mask: current path mask
+ * @retries: current number of retries
+ * @drc: delayed return code
+ * @cancel: non-zero if request was cancelled
+ * @done: non-zero if request was finished
+ */
+struct ccw_request {
+	struct ccw1 *cp;
+	unsigned long timeout;
+	u16 maxretries;
+	u8 lpm;
+	int (*check)(struct ccw_device *, void *);
+	enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
+				 enum io_status);
+	void (*callback)(struct ccw_device *, void *, int);
+	void *data;
+	/* These fields are used internally. */
+	u16 mask;
+	u16 retries;
+	int drc;
+	int cancel:1;
+	int done:1;
+} __attribute__((packed));
+
+/*
  * sense-id response buffer layout
  */
 struct senseid {
@@ -82,32 +131,44 @@ struct senseid {
 	struct ciw ciw[MAX_CIWS];	/* variable # of CIWs */
 }  __attribute__ ((packed, aligned(4)));
 
+enum cdev_todo {
+	CDEV_TODO_NOTHING,
+	CDEV_TODO_ENABLE_CMF,
+	CDEV_TODO_REBIND,
+	CDEV_TODO_REGISTER,
+	CDEV_TODO_UNREG,
+	CDEV_TODO_UNREG_EVAL,
+};
+
 struct ccw_device_private {
 	struct ccw_device *cdev;
 	struct subchannel *sch;
 	int state;		/* device state */
 	atomic_t onoff;
-	unsigned long registered;
 	struct ccw_dev_id dev_id;	/* device id */
 	struct subchannel_id schid;	/* subchannel number */
-	u8 imask;		/* lpm mask for SNID/SID/SPGID */
-	int iretry;		/* retry counter SNID/SID/SPGID */
+	struct ccw_request req;		/* internal I/O request */
+	int iretry;
+	u8 pgid_valid_mask;		/* mask of valid PGIDs */
+	u8 pgid_todo_mask;		/* mask of PGIDs to be adjusted */
 	struct {
 		unsigned int fast:1;	/* post with "channel end" */
 		unsigned int repall:1;	/* report every interrupt status */
 		unsigned int pgroup:1;	/* do path grouping */
 		unsigned int force:1;	/* allow forced online */
+		unsigned int mpath:1;	/* do multipathing */
 	} __attribute__ ((packed)) options;
 	struct {
-		unsigned int pgid_single:1; /* use single path for Set PGID */
 		unsigned int esid:1;	    /* Ext. SenseID supported by HW */
 		unsigned int dosense:1;	    /* delayed SENSE required */
 		unsigned int doverify:1;    /* delayed path verification */
 		unsigned int donotify:1;    /* call notify function */
 		unsigned int recog_done:1;  /* dev. recog. complete */
 		unsigned int fake_irb:1;    /* deliver faked irb */
-		unsigned int intretry:1;    /* retry internal operation */
 		unsigned int resuming:1;    /* recognition while resume */
+		unsigned int pgroup:1;	    /* pathgroup is set up */
+		unsigned int mpath:1;	    /* multipathing is set up */
+		unsigned int initialized:1; /* set if initial reference held */
 	} __attribute__((packed)) flags;
 	unsigned long intparm;	/* user interruption parameter */
 	struct qdio_irq *qdio_data;
@@ -115,7 +176,8 @@ struct ccw_device_private {
 	struct senseid senseid;	/* SenseID info */
 	struct pgid pgid[8];	/* path group IDs per chpid*/
 	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
-	struct work_struct kick_work;
+	struct work_struct todo_work;
+	enum cdev_todo todo;
 	wait_queue_head_t wait_q;
 	struct timer_list timer;
 	void *cmb;			/* measurement information */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/Makefile linux-libre-2.6.33-gnu1/drivers/s390/cio/Makefile
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,12 +3,12 @@
 #
 
 obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \
-	fcx.o itcw.o crw.o
+	fcx.o itcw.o crw.o ccwreq.o
 ccw_device-objs += device.o device_fsm.o device_ops.o
 ccw_device-objs += device_id.o device_pgid.o device_status.o
 obj-y += ccw_device.o cmf.o
 obj-$(CONFIG_CHSC_SCH) += chsc_sch.o
 obj-$(CONFIG_CCWGROUP) += ccwgroup.o
 
-qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_perf.o qdio_setup.o
+qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o
 obj-$(CONFIG_QDIO) += qdio.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_debug.c linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_debug.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_debug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_debug.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,13 +55,11 @@ static int qstat_show(struct seq_file *m
 	if (!q)
 		return 0;
 
-	seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
-	seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
-	seq_printf(m, "ftc: %d\n", q->first_to_check);
-	seq_printf(m, "last_move: %d\n", q->last_move);
-	seq_printf(m, "polling: %d\n", q->u.in.polling);
-	seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
-	seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
+	seq_printf(m, "DSCI: %d   nr_used: %d\n",
+		   *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
+	seq_printf(m, "ftc: %d  last_move: %d\n", q->first_to_check, q->last_move);
+	seq_printf(m, "polling: %d  ack start: %d  ack count: %d\n",
+		   q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count);
 	seq_printf(m, "slsb buffer states:\n");
 	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
 
@@ -110,7 +108,6 @@ static ssize_t qstat_seq_write(struct fi
 
 	if (!q)
 		return 0;
-
 	if (q->is_input_q)
 		xchg(q->irq_ptr->dsci, 1);
 	local_bh_disable();
@@ -134,6 +131,98 @@ static const struct file_operations debu
 	.release = single_release,
 };
 
+static char *qperf_names[] = {
+	"Assumed adapter interrupts",
+	"QDIO interrupts",
+	"Requested PCIs",
+	"Inbound tasklet runs",
+	"Inbound tasklet resched",
+	"Inbound tasklet resched2",
+	"Outbound tasklet runs",
+	"SIGA read",
+	"SIGA write",
+	"SIGA sync",
+	"Inbound calls",
+	"Inbound handler",
+	"Inbound stop_polling",
+	"Inbound queue full",
+	"Outbound calls",
+	"Outbound handler",
+	"Outbound fast_requeue",
+	"Outbound target_full",
+	"QEBSM eqbs",
+	"QEBSM eqbs partial",
+	"QEBSM sqbs",
+	"QEBSM sqbs partial"
+};
+
+static int qperf_show(struct seq_file *m, void *v)
+{
+	struct qdio_irq *irq_ptr = m->private;
+	unsigned int *stat;
+	int i;
+
+	if (!irq_ptr)
+		return 0;
+	if (!irq_ptr->perf_stat_enabled) {
+		seq_printf(m, "disabled\n");
+		return 0;
+	}
+	stat = (unsigned int *)&irq_ptr->perf_stat;
+
+	for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
+		seq_printf(m, "%26s:\t%u\n",
+			   qperf_names[i], *(stat + i));
+	return 0;
+}
+
+static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
+			       size_t count, loff_t *off)
+{
+	struct seq_file *seq = file->private_data;
+	struct qdio_irq *irq_ptr = seq->private;
+	unsigned long val;
+	char buf[8];
+	int ret;
+
+	if (!irq_ptr)
+		return 0;
+	if (count >= sizeof(buf))
+		return -EINVAL;
+	if (copy_from_user(&buf, ubuf, count))
+		return -EFAULT;
+	buf[count] = 0;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	switch (val) {
+	case 0:
+		irq_ptr->perf_stat_enabled = 0;
+		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
+		break;
+	case 1:
+		irq_ptr->perf_stat_enabled = 1;
+		break;
+	}
+	return count;
+}
+
+static int qperf_seq_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, qperf_show,
+			   filp->f_path.dentry->d_inode->i_private);
+}
+
+static struct file_operations debugfs_perf_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = qperf_seq_open,
+	.read	 = seq_read,
+	.write	 = qperf_seq_write,
+	.llseek  = seq_lseek,
+	.release = single_release,
+};
 static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev)
 {
 	char name[QDIO_DEBUGFS_NAME_LEN];
@@ -156,6 +245,14 @@ void qdio_setup_debug_entries(struct qdi
 						  debugfs_root);
 	if (IS_ERR(irq_ptr->debugfs_dev))
 		irq_ptr->debugfs_dev = NULL;
+
+	irq_ptr->debugfs_perf = debugfs_create_file("statistics",
+				S_IFREG | S_IRUGO | S_IWUSR,
+				irq_ptr->debugfs_dev, irq_ptr,
+				&debugfs_perf_fops);
+	if (IS_ERR(irq_ptr->debugfs_perf))
+		irq_ptr->debugfs_perf = NULL;
+
 	for_each_input_queue(irq_ptr, q, i)
 		setup_debugfs_entry(q, cdev);
 	for_each_output_queue(irq_ptr, q, i)
@@ -171,6 +268,7 @@ void qdio_shutdown_debug_entries(struct
 		debugfs_remove(q->debugfs_q);
 	for_each_output_queue(irq_ptr, q, i)
 		debugfs_remove(q->debugfs_q);
+	debugfs_remove(irq_ptr->debugfs_perf);
 	debugfs_remove(irq_ptr->debugfs_dev);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio.h linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio.h	2010-02-24 13:52:17.000000000 -0500
@@ -182,6 +182,34 @@ struct scssc_area {
 	u32:32;
 } __attribute__ ((packed));
 
+struct qdio_dev_perf_stat {
+	unsigned int adapter_int;
+	unsigned int qdio_int;
+	unsigned int pci_request_int;
+
+	unsigned int tasklet_inbound;
+	unsigned int tasklet_inbound_resched;
+	unsigned int tasklet_inbound_resched2;
+	unsigned int tasklet_outbound;
+
+	unsigned int siga_read;
+	unsigned int siga_write;
+	unsigned int siga_sync;
+
+	unsigned int inbound_call;
+	unsigned int inbound_handler;
+	unsigned int stop_polling;
+	unsigned int inbound_queue_full;
+	unsigned int outbound_call;
+	unsigned int outbound_handler;
+	unsigned int fast_requeue;
+	unsigned int target_full;
+	unsigned int eqbs;
+	unsigned int eqbs_partial;
+	unsigned int sqbs;
+	unsigned int sqbs_partial;
+};
+
 struct qdio_input_q {
 	/* input buffer acknowledgement flag */
 	int polling;
@@ -269,6 +297,7 @@ struct qdio_irq {
 	u32 *dsci;		/* address of device state change indicator */
 	struct ccw_device *cdev;
 	struct dentry *debugfs_dev;
+	struct dentry *debugfs_perf;
 
 	unsigned long int_parm;
 	struct subchannel_id schid;
@@ -286,9 +315,10 @@ struct qdio_irq {
 	struct ciw aqueue;
 
 	struct qdio_ssqd_desc ssqd_desc;
-
 	void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);
 
+	struct qdio_dev_perf_stat perf_stat;
+	int perf_stat_enabled;
 	/*
 	 * Warning: Leave these members together at the end so they won't be
 	 * cleared in qdio_setup_irq.
@@ -311,6 +341,10 @@ struct qdio_irq {
 	(irq->qib.qfmt == QDIO_IQDIO_QFMT || \
 	 css_general_characteristics.aif_osa)
 
+#define qperf(qdev,attr)	qdev->perf_stat.attr
+#define qperf_inc(q,attr)	if (q->irq_ptr->perf_stat_enabled) \
+					q->irq_ptr->perf_stat.attr++
+
 /* the highest iqdio queue is used for multicast */
 static inline int multicast_outbound(struct qdio_q *q)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_main.c linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_main.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,7 +22,6 @@
 #include "device.h"
 #include "qdio.h"
 #include "qdio_debug.h"
-#include "qdio_perf.h"
 
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\
 	"Jan Glauber <jang@linux.vnet.ibm.com>");
@@ -126,7 +125,7 @@ static int qdio_do_eqbs(struct qdio_q *q
 	int rc;
 
 	BUG_ON(!q->irq_ptr->sch_token);
-	qdio_perf_stat_inc(&perf_stats.debug_eqbs_all);
+	qperf_inc(q, eqbs);
 
 	if (!q->is_input_q)
 		nr += q->irq_ptr->nr_input_qs;
@@ -139,7 +138,7 @@ again:
 	 * buffers later.
 	 */
 	if ((ccq == 96) && (count != tmp_count)) {
-		qdio_perf_stat_inc(&perf_stats.debug_eqbs_incomplete);
+		qperf_inc(q, eqbs_partial);
 		return (count - tmp_count);
 	}
 
@@ -182,7 +181,7 @@ static int qdio_do_sqbs(struct qdio_q *q
 		return 0;
 
 	BUG_ON(!q->irq_ptr->sch_token);
-	qdio_perf_stat_inc(&perf_stats.debug_sqbs_all);
+	qperf_inc(q, sqbs);
 
 	if (!q->is_input_q)
 		nr += q->irq_ptr->nr_input_qs;
@@ -191,7 +190,7 @@ again:
 	rc = qdio_check_ccq(q, ccq);
 	if (rc == 1) {
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq);
-		qdio_perf_stat_inc(&perf_stats.debug_sqbs_incomplete);
+		qperf_inc(q, sqbs_partial);
 		goto again;
 	}
 	if (rc < 0) {
@@ -285,7 +284,7 @@ static inline int qdio_siga_sync(struct
 		return 0;
 
 	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr);
-	qdio_perf_stat_inc(&perf_stats.siga_sync);
+	qperf_inc(q, siga_sync);
 
 	cc = do_siga_sync(q->irq_ptr->schid, output, input);
 	if (cc)
@@ -350,7 +349,7 @@ static inline int qdio_siga_input(struct
 	int cc;
 
 	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr);
-	qdio_perf_stat_inc(&perf_stats.siga_in);
+	qperf_inc(q, siga_read);
 
 	cc = do_siga_input(q->irq_ptr->schid, q->mask);
 	if (cc)
@@ -382,7 +381,7 @@ static inline void qdio_stop_polling(str
 		return;
 
 	q->u.in.polling = 0;
-	qdio_perf_stat_inc(&perf_stats.debug_stop_polling);
+	qperf_inc(q, stop_polling);
 
 	/* show the card that we are not polling anymore */
 	if (is_qebsm(q)) {
@@ -400,7 +399,7 @@ static void announce_buffer_error(struct
 	/* special handling for no target buffer empty */
 	if ((!q->is_input_q &&
 	    (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
-		qdio_perf_stat_inc(&perf_stats.outbound_target_full);
+		qperf_inc(q, target_full);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
 			      q->first_to_check);
 		return;
@@ -486,7 +485,8 @@ static int get_inbound_buffer_frontier(s
 	case SLSB_P_INPUT_PRIMED:
 		inbound_primed(q, count);
 		q->first_to_check = add_buf(q->first_to_check, count);
-		atomic_sub(count, &q->nr_buf_used);
+		if (atomic_sub(count, &q->nr_buf_used) == 0)
+			qperf_inc(q, inbound_queue_full);
 		break;
 	case SLSB_P_INPUT_ERROR:
 		announce_buffer_error(q, count);
@@ -531,7 +531,7 @@ static inline int qdio_inbound_q_done(st
 	qdio_siga_sync_q(q);
 	get_buf_state(q, q->first_to_check, &state, 0);
 
-	if (state == SLSB_P_INPUT_PRIMED)
+	if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
 		/* more work coming */
 		return 0;
 
@@ -566,9 +566,10 @@ static void qdio_kick_handler(struct qdi
 	count = sub_buf(end, start);
 
 	if (q->is_input_q) {
-		qdio_perf_stat_inc(&perf_stats.inbound_handler);
+		qperf_inc(q, inbound_handler);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
 	} else
+		qperf_inc(q, outbound_handler);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
 			      start, count);
 
@@ -582,24 +583,28 @@ static void qdio_kick_handler(struct qdi
 
 static void __qdio_inbound_processing(struct qdio_q *q)
 {
-	qdio_perf_stat_inc(&perf_stats.tasklet_inbound);
+	qperf_inc(q, tasklet_inbound);
 again:
 	if (!qdio_inbound_q_moved(q))
 		return;
 
 	qdio_kick_handler(q);
 
-	if (!qdio_inbound_q_done(q))
+	if (!qdio_inbound_q_done(q)) {
 		/* means poll time is not yet over */
+		qperf_inc(q, tasklet_inbound_resched);
 		goto again;
+	}
 
 	qdio_stop_polling(q);
 	/*
 	 * We need to check again to not lose initiative after
 	 * resetting the ACK state.
 	 */
-	if (!qdio_inbound_q_done(q))
+	if (!qdio_inbound_q_done(q)) {
+		qperf_inc(q, tasklet_inbound_resched2);
 		goto again;
+	}
 }
 
 void qdio_inbound_processing(unsigned long data)
@@ -687,7 +692,7 @@ static int qdio_kick_outbound_q(struct q
 		return 0;
 
 	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
-	qdio_perf_stat_inc(&perf_stats.siga_out);
+	qperf_inc(q, siga_write);
 
 	cc = qdio_siga_output(q, &busy_bit);
 	switch (cc) {
@@ -710,7 +715,7 @@ static int qdio_kick_outbound_q(struct q
 
 static void __qdio_outbound_processing(struct qdio_q *q)
 {
-	qdio_perf_stat_inc(&perf_stats.tasklet_outbound);
+	qperf_inc(q, tasklet_outbound);
 	BUG_ON(atomic_read(&q->nr_buf_used) < 0);
 
 	if (qdio_outbound_q_moved(q))
@@ -738,12 +743,9 @@ static void __qdio_outbound_processing(s
 	 */
 	if (qdio_outbound_q_done(q))
 		del_timer(&q->u.out.timer);
-	else {
-		if (!timer_pending(&q->u.out.timer)) {
+	else
+		if (!timer_pending(&q->u.out.timer))
 			mod_timer(&q->u.out.timer, jiffies + 10 * HZ);
-			qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
-		}
-	}
 	return;
 
 sched:
@@ -783,7 +785,7 @@ static inline void qdio_check_outbound_a
 
 static void __tiqdio_inbound_processing(struct qdio_q *q)
 {
-	qdio_perf_stat_inc(&perf_stats.thinint_inbound);
+	qperf_inc(q, tasklet_inbound);
 	qdio_sync_after_thinint(q);
 
 	/*
@@ -798,7 +800,7 @@ static void __tiqdio_inbound_processing(
 	qdio_kick_handler(q);
 
 	if (!qdio_inbound_q_done(q)) {
-		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
+		qperf_inc(q, tasklet_inbound_resched);
 		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) {
 			tasklet_schedule(&q->tasklet);
 			return;
@@ -811,7 +813,7 @@ static void __tiqdio_inbound_processing(
 	 * resetting the ACK state.
 	 */
 	if (!qdio_inbound_q_done(q)) {
-		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
+		qperf_inc(q, tasklet_inbound_resched2);
 		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
 			tasklet_schedule(&q->tasklet);
 	}
@@ -850,8 +852,6 @@ static void qdio_int_handler_pci(struct
 	if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
 		return;
 
-	qdio_perf_stat_inc(&perf_stats.pci_int);
-
 	for_each_input_queue(irq_ptr, q, i)
 		tasklet_schedule(&q->tasklet);
 
@@ -922,8 +922,6 @@ void qdio_int_handler(struct ccw_device
 	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
 	int cstat, dstat;
 
-	qdio_perf_stat_inc(&perf_stats.qdio_int);
-
 	if (!intparm || !irq_ptr) {
 		DBF_ERROR("qint:%4x", cdev->private->schid.sch_no);
 		return;
@@ -962,6 +960,8 @@ void qdio_int_handler(struct ccw_device
 			qdio_handle_activate_check(cdev, intparm, cstat,
 						   dstat);
 		break;
+	case QDIO_IRQ_STATE_STOPPED:
+		break;
 	default:
 		WARN_ON(1);
 	}
@@ -1382,6 +1382,8 @@ static int handle_inbound(struct qdio_q
 {
 	int used, diff;
 
+	qperf_inc(q, inbound_call);
+
 	if (!q->u.in.polling)
 		goto set;
 
@@ -1437,14 +1439,16 @@ static int handle_outbound(struct qdio_q
 	unsigned char state;
 	int used, rc = 0;
 
-	qdio_perf_stat_inc(&perf_stats.outbound_handler);
+	qperf_inc(q, outbound_call);
 
 	count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count);
 	used = atomic_add_return(count, &q->nr_buf_used);
 	BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q);
 
-	if (callflags & QDIO_FLAG_PCI_OUT)
+	if (callflags & QDIO_FLAG_PCI_OUT) {
 		q->u.out.pci_out_enabled = 1;
+		qperf_inc(q, pci_request_int);
+	}
 	else
 		q->u.out.pci_out_enabled = 0;
 
@@ -1483,7 +1487,7 @@ static int handle_outbound(struct qdio_q
 	if (state != SLSB_CU_OUTPUT_PRIMED)
 		rc = qdio_kick_outbound_q(q);
 	else
-		qdio_perf_stat_inc(&perf_stats.fast_requeue);
+		qperf_inc(q, fast_requeue);
 
 out:
 	tasklet_schedule(&q->tasklet);
@@ -1539,16 +1543,11 @@ static int __init init_QDIO(void)
 	rc = qdio_debug_init();
 	if (rc)
 		goto out_ti;
-	rc = qdio_setup_perf_stats();
-	if (rc)
-		goto out_debug;
 	rc = tiqdio_register_thinints();
 	if (rc)
-		goto out_perf;
+		goto out_debug;
 	return 0;
 
-out_perf:
-	qdio_remove_perf_stats();
 out_debug:
 	qdio_debug_exit();
 out_ti:
@@ -1562,7 +1561,6 @@ static void __exit exit_QDIO(void)
 {
 	tiqdio_unregister_thinints();
 	tiqdio_free_memory();
-	qdio_remove_perf_stats();
 	qdio_debug_exit();
 	qdio_setup_exit();
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_perf.c linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_perf.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_perf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_perf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,147 +0,0 @@
-/*
- *  drivers/s390/cio/qdio_perf.c
- *
- *  Copyright IBM Corp. 2008
- *
- *  Author: Jan Glauber (jang@linux.vnet.ibm.com)
- */
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <asm/ccwdev.h>
-
-#include "cio.h"
-#include "css.h"
-#include "device.h"
-#include "ioasm.h"
-#include "chsc.h"
-#include "qdio_debug.h"
-#include "qdio_perf.h"
-
-int qdio_performance_stats;
-struct qdio_perf_stats perf_stats;
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *qdio_perf_pde;
-#endif
-
-/*
- * procfs functions
- */
-static int qdio_perf_proc_show(struct seq_file *m, void *v)
-{
-	seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.qdio_int));
-	seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.pci_int));
-	seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.thin_int));
-	seq_printf(m, "\n");
-	seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.tasklet_inbound));
-	seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.tasklet_outbound));
-	seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n",
-		   (long)atomic_long_read(&perf_stats.tasklet_thinint),
-		   (long)atomic_long_read(&perf_stats.tasklet_thinint_loop));
-	seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n",
-		   (long)atomic_long_read(&perf_stats.thinint_inbound),
-		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop));
-	seq_printf(m, "\n");
-	seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.siga_in));
-	seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.siga_out));
-	seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.siga_sync));
-	seq_printf(m, "\n");
-	seq_printf(m, "Number of inbound transfers\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.inbound_handler));
-	seq_printf(m, "Number of outbound transfers\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.outbound_handler));
-	seq_printf(m, "\n");
-	seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.fast_requeue));
-	seq_printf(m, "Number of outbound target full condition\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.outbound_target_full));
-	seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.debug_tl_out_timer));
-	seq_printf(m, "Number of stop polling calls\t\t\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.debug_stop_polling));
-	seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n",
-		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop2));
-	seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n",
-		   (long)atomic_long_read(&perf_stats.debug_eqbs_all),
-		   (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete));
-	seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n",
-		   (long)atomic_long_read(&perf_stats.debug_sqbs_all),
-		   (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete));
-	seq_printf(m, "\n");
-	return 0;
-}
-static int qdio_perf_seq_open(struct inode *inode, struct file *filp)
-{
-	return single_open(filp, qdio_perf_proc_show, NULL);
-}
-
-static const struct file_operations qdio_perf_proc_fops = {
-	.owner	 = THIS_MODULE,
-	.open	 = qdio_perf_seq_open,
-	.read	 = seq_read,
-	.llseek  = seq_lseek,
-	.release = single_release,
-};
-
-/*
- * sysfs functions
- */
-static ssize_t qdio_perf_stats_show(struct bus_type *bus, char *buf)
-{
-	return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0);
-}
-
-static ssize_t qdio_perf_stats_store(struct bus_type *bus,
-			      const char *buf, size_t count)
-{
-	unsigned long i;
-
-	if (strict_strtoul(buf, 16, &i) != 0)
-		return -EINVAL;
-	if ((i != 0) && (i != 1))
-		return -EINVAL;
-	if (i == qdio_performance_stats)
-		return count;
-
-	qdio_performance_stats = i;
-	/* reset performance statistics */
-	if (i == 0)
-		memset(&perf_stats, 0, sizeof(struct qdio_perf_stats));
-	return count;
-}
-
-static BUS_ATTR(qdio_performance_stats, 0644, qdio_perf_stats_show,
-		qdio_perf_stats_store);
-
-int __init qdio_setup_perf_stats(void)
-{
-	int rc;
-
-	rc = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
-	if (rc)
-		return rc;
-
-#ifdef CONFIG_PROC_FS
-	memset(&perf_stats, 0, sizeof(struct qdio_perf_stats));
-	qdio_perf_pde = proc_create("qdio_perf", S_IFREG | S_IRUGO,
-				    NULL, &qdio_perf_proc_fops);
-#endif
-	return 0;
-}
-
-void qdio_remove_perf_stats(void)
-{
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("qdio_perf", NULL);
-#endif
-	bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_perf.h linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_perf.h
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_perf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_perf.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/*
- *  drivers/s390/cio/qdio_perf.h
- *
- *  Copyright IBM Corp. 2008
- *
- *  Author: Jan Glauber (jang@linux.vnet.ibm.com)
- */
-#ifndef QDIO_PERF_H
-#define QDIO_PERF_H
-
-#include <linux/types.h>
-#include <asm/atomic.h>
-
-struct qdio_perf_stats {
-	/* interrupt handler calls */
-	atomic_long_t qdio_int;
-	atomic_long_t pci_int;
-	atomic_long_t thin_int;
-
-	/* tasklet runs */
-	atomic_long_t tasklet_inbound;
-	atomic_long_t tasklet_outbound;
-	atomic_long_t tasklet_thinint;
-	atomic_long_t tasklet_thinint_loop;
-	atomic_long_t thinint_inbound;
-	atomic_long_t thinint_inbound_loop;
-	atomic_long_t thinint_inbound_loop2;
-
-	/* signal adapter calls */
-	atomic_long_t siga_out;
-	atomic_long_t siga_in;
-	atomic_long_t siga_sync;
-
-	/* misc */
-	atomic_long_t inbound_handler;
-	atomic_long_t outbound_handler;
-	atomic_long_t fast_requeue;
-	atomic_long_t outbound_target_full;
-
-	/* for debugging */
-	atomic_long_t debug_tl_out_timer;
-	atomic_long_t debug_stop_polling;
-	atomic_long_t debug_eqbs_all;
-	atomic_long_t debug_eqbs_incomplete;
-	atomic_long_t debug_sqbs_all;
-	atomic_long_t debug_sqbs_incomplete;
-};
-
-extern struct qdio_perf_stats perf_stats;
-extern int qdio_performance_stats;
-
-static inline void qdio_perf_stat_inc(atomic_long_t *count)
-{
-	if (qdio_performance_stats)
-		atomic_long_inc(count);
-}
-
-int qdio_setup_perf_stats(void);
-void qdio_remove_perf_stats(void);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_setup.c linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_setup.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_setup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_setup.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,7 +48,6 @@ static void set_impl_params(struct qdio_
 	if (!irq_ptr)
 		return;
 
-	WARN_ON((unsigned long)&irq_ptr->qib & 0xff);
 	irq_ptr->qib.pfmt = qib_param_field_format;
 	if (qib_param_field)
 		memcpy(irq_ptr->qib.parm, qib_param_field,
@@ -82,14 +81,12 @@ static int __qdio_allocate_qs(struct qdi
 		q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
 		if (!q)
 			return -ENOMEM;
-		WARN_ON((unsigned long)q & 0xff);
 
 		q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
 		if (!q->slib) {
 			kmem_cache_free(qdio_q_cache, q);
 			return -ENOMEM;
 		}
-		WARN_ON((unsigned long)q->slib & 0x7ff);
 		irq_ptr_qs[i] = q;
 	}
 	return 0;
@@ -131,7 +128,7 @@ static void setup_storage_lists(struct q
 	/* fill in sbal */
 	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) {
 		q->sbal[j] = *sbals_array++;
-		WARN_ON((unsigned long)q->sbal[j] & 0xff);
+		BUG_ON((unsigned long)q->sbal[j] & 0xff);
 	}
 
 	/* fill in slib */
@@ -147,11 +144,6 @@ static void setup_storage_lists(struct q
 	/* fill in sl */
 	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
 		q->sl->element[j].sbal = (unsigned long)q->sbal[j];
-
-	DBF_EVENT("sl-slsb-sbal");
-	DBF_HEX(q->sl, sizeof(void *));
-	DBF_HEX(&q->slsb, sizeof(void *));
-	DBF_HEX(q->sbal, sizeof(void *));
 }
 
 static void setup_queues(struct qdio_irq *irq_ptr,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_thinint.c linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_thinint.c
--- linux-libre-2.6.32-gnu1/drivers/s390/cio/qdio_thinint.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/cio/qdio_thinint.c	2010-02-24 13:52:17.000000000 -0500
@@ -1,9 +1,7 @@
 /*
  * linux/drivers/s390/cio/thinint_qdio.c
  *
- * thin interrupt support for qdio
- *
- * Copyright 2000-2008 IBM Corp.
+ * Copyright 2000,2009 IBM Corp.
  * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
  *	      Cornelia Huck <cornelia.huck@de.ibm.com>
  *	      Jan Glauber <jang@linux.vnet.ibm.com>
@@ -19,7 +17,6 @@
 #include "ioasm.h"
 #include "qdio.h"
 #include "qdio_debug.h"
-#include "qdio_perf.h"
 
 /*
  * Restriction: only 63 iqdio subchannels would have its own indicator,
@@ -132,8 +129,6 @@ static void tiqdio_thinint_handler(void
 {
 	struct qdio_q *q;
 
-	qdio_perf_stat_inc(&perf_stats.thin_int);
-
 	/*
 	 * SVS only when needed: issue SVS to benefit from iqdio interrupt
 	 * avoidance (SVS clears adapter interrupt suppression overwrite)
@@ -154,6 +149,7 @@ static void tiqdio_thinint_handler(void
 	list_for_each_entry_rcu(q, &tiq_list, entry)
 		/* only process queues from changed sets */
 		if (*q->irq_ptr->dsci) {
+			qperf_inc(q, adapter_int);
 
 			/* only clear it if the indicator is non-shared */
 			if (!shared_ind(q->irq_ptr))
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/ap_bus.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/ap_bus.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.c	2010-02-24 13:52:17.000000000 -0500
@@ -102,6 +102,7 @@ static atomic_t ap_poll_requests = ATOMI
 static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
 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.
@@ -282,6 +283,7 @@ static int ap_queue_enable_interruption(
  * @psmid: The program supplied message identifier
  * @msg: The message text
  * @length: The message length
+ * @special: Special Bit
  *
  * Returns AP queue status structure.
  * Condition code 1 on NQAP can't happen because the L bit is 1.
@@ -289,7 +291,8 @@ static int ap_queue_enable_interruption(
  * because a segment boundary was reached. The NQAP is repeated.
  */
 static inline struct ap_queue_status
-__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
+__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
+	  unsigned int special)
 {
 	typedef struct { char _[length]; } msgblock;
 	register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
@@ -299,6 +302,9 @@ __ap_send(ap_qid_t qid, unsigned long lo
 	register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
 	register unsigned long reg5 asm ("5") = (unsigned int) psmid;
 
+	if (special == 1)
+		reg0 |= 0x400000UL;
+
 	asm volatile (
 		"0: .long 0xb2ad0042\n"		/* DQAP */
 		"   brc   2,0b"
@@ -312,13 +318,15 @@ int ap_send(ap_qid_t qid, unsigned long
 {
 	struct ap_queue_status status;
 
-	status = __ap_send(qid, psmid, msg, length);
+	status = __ap_send(qid, psmid, msg, length, 0);
 	switch (status.response_code) {
 	case AP_RESPONSE_NORMAL:
 		return 0;
 	case AP_RESPONSE_Q_FULL:
 	case AP_RESPONSE_RESET_IN_PROGRESS:
 		return -EBUSY;
+	case AP_RESPONSE_REQ_FAC_NOT_INST:
+		return -EINVAL;
 	default:	/* Device is gone. */
 		return -ENODEV;
 	}
@@ -1008,7 +1016,7 @@ static int ap_probe_device_type(struct a
 	}
 
 	status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
-			   msg, sizeof(msg));
+			   msg, sizeof(msg), 0);
 	if (status.response_code != AP_RESPONSE_NORMAL) {
 		rc = -ENODEV;
 		goto out_free;
@@ -1163,16 +1171,19 @@ ap_config_timeout(unsigned long ptr)
 static inline void ap_schedule_poll_timer(void)
 {
 	ktime_t hr_time;
+
+	spin_lock_bh(&ap_poll_timer_lock);
 	if (ap_using_interrupts() || ap_suspend_flag)
-		return;
+		goto out;
 	if (hrtimer_is_queued(&ap_poll_timer))
-		return;
+		goto out;
 	if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
 		hr_time = ktime_set(0, poll_timeout);
 		hrtimer_forward_now(&ap_poll_timer, hr_time);
 		hrtimer_restart(&ap_poll_timer);
 	}
-	return;
+out:
+	spin_unlock_bh(&ap_poll_timer_lock);
 }
 
 /**
@@ -1243,7 +1254,7 @@ static int ap_poll_write(struct ap_devic
 	/* Start the next request on the queue. */
 	ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
 	status = __ap_send(ap_dev->qid, ap_msg->psmid,
-			   ap_msg->message, ap_msg->length);
+			   ap_msg->message, ap_msg->length, ap_msg->special);
 	switch (status.response_code) {
 	case AP_RESPONSE_NORMAL:
 		atomic_inc(&ap_poll_requests);
@@ -1261,6 +1272,7 @@ static int ap_poll_write(struct ap_devic
 		*flags |= 2;
 		break;
 	case AP_RESPONSE_MESSAGE_TOO_BIG:
+	case AP_RESPONSE_REQ_FAC_NOT_INST:
 		return -EINVAL;
 	default:
 		return -ENODEV;
@@ -1302,7 +1314,8 @@ static int __ap_queue_message(struct ap_
 	if (list_empty(&ap_dev->requestq) &&
 	    ap_dev->queue_count < ap_dev->queue_depth) {
 		status = __ap_send(ap_dev->qid, ap_msg->psmid,
-				   ap_msg->message, ap_msg->length);
+				   ap_msg->message, ap_msg->length,
+				   ap_msg->special);
 		switch (status.response_code) {
 		case AP_RESPONSE_NORMAL:
 			list_add_tail(&ap_msg->list, &ap_dev->pendingq);
@@ -1317,6 +1330,7 @@ static int __ap_queue_message(struct ap_
 			ap_dev->requestq_count++;
 			ap_dev->total_request_count++;
 			return -EBUSY;
+		case AP_RESPONSE_REQ_FAC_NOT_INST:
 		case AP_RESPONSE_MESSAGE_TOO_BIG:
 			ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
 			return -EINVAL;
@@ -1658,6 +1672,7 @@ int __init ap_module_init(void)
 	 */
 	if (MACHINE_IS_VM)
 		poll_timeout = 1500000;
+	spin_lock_init(&ap_poll_timer_lock);
 	hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 	ap_poll_timer.function = ap_poll_timeout;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/ap_bus.h linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.h
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/ap_bus.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/ap_bus.h	2010-02-24 13:52:17.000000000 -0500
@@ -87,6 +87,7 @@ struct ap_queue_status {
 #define AP_RESPONSE_INDEX_TOO_BIG	0x11
 #define AP_RESPONSE_NO_FIRST_PART	0x13
 #define AP_RESPONSE_MESSAGE_TOO_BIG	0x15
+#define AP_RESPONSE_REQ_FAC_NOT_INST	0x16
 
 /*
  * Known device types
@@ -96,8 +97,8 @@ struct ap_queue_status {
 #define AP_DEVICE_TYPE_PCIXCC	5
 #define AP_DEVICE_TYPE_CEX2A	6
 #define AP_DEVICE_TYPE_CEX2C	7
-#define AP_DEVICE_TYPE_CEX2A2	8
-#define AP_DEVICE_TYPE_CEX2C2	9
+#define AP_DEVICE_TYPE_CEX3A	8
+#define AP_DEVICE_TYPE_CEX3C	9
 
 /*
  * AP reset flag states
@@ -161,12 +162,25 @@ struct ap_message {
 	size_t length;			/* Message length. */
 
 	void *private;			/* ap driver private pointer. */
+	unsigned int special:1;		/* Used for special commands. */
 };
 
 #define AP_DEVICE(dt)					\
 	.dev_type=(dt),					\
 	.match_flags=AP_DEVICE_ID_MATCH_DEVICE_TYPE,
 
+/**
+ * ap_init_message() - Initialize ap_message.
+ * Initialize a message before using. Otherwise this might result in
+ * unexpected behaviour.
+ */
+static inline void ap_init_message(struct ap_message *ap_msg)
+{
+	ap_msg->psmid = 0;
+	ap_msg->length = 0;
+	ap_msg->special = 0;
+}
+
 /*
  * Note: don't use ap_send/ap_recv after using ap_queue_message
  * for the first time. Otherwise the ap message queue will get
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_api.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_api.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.c	2010-02-24 13:52:17.000000000 -0500
@@ -299,9 +299,7 @@ static ssize_t zcrypt_write(struct file
  */
 static int zcrypt_open(struct inode *inode, struct file *filp)
 {
-	lock_kernel();
 	atomic_inc(&zcrypt_open_count);
-	unlock_kernel();
 	return 0;
 }
 
@@ -395,10 +393,12 @@ static long zcrypt_rsa_crt(struct ica_rs
 			 * u_mult_inv > 128 bytes.
 			 */
 			if (copied == 0) {
-				int len;
+				unsigned int len;
 				spin_unlock_bh(&zcrypt_device_lock);
 				/* len is max 256 / 2 - 120 = 8 */
 				len = crt->inputdatalength / 2 - 120;
+				if (len > sizeof(z1))
+					return -EFAULT;
 				z1 = z2 = z3 = 0;
 				if (copy_from_user(&z1, crt->np_prime, len) ||
 				    copy_from_user(&z2, crt->bp_key, len) ||
@@ -1009,6 +1009,10 @@ static int zcrypt_status_read(char *resp
 		       zcrypt_count_type(ZCRYPT_CEX2C));
 	len += sprintf(resp_buff + len, "CEX2A count: %d\n",
 		       zcrypt_count_type(ZCRYPT_CEX2A));
+	len += sprintf(resp_buff + len, "CEX3C count: %d\n",
+		       zcrypt_count_type(ZCRYPT_CEX3C));
+	len += sprintf(resp_buff + len, "CEX3A count: %d\n",
+		       zcrypt_count_type(ZCRYPT_CEX3A));
 	len += sprintf(resp_buff + len, "requestq count: %d\n",
 		       zcrypt_requestq_count());
 	len += sprintf(resp_buff + len, "pendingq count: %d\n",
@@ -1017,7 +1021,7 @@ static int zcrypt_status_read(char *resp
 		       atomic_read(&zcrypt_open_count));
 	zcrypt_status_mask(workarea);
 	len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
-			"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A",
+			"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
 			resp_buff+len, workarea, AP_DEVICES);
 	zcrypt_qdepth_mask(workarea);
 	len += sprinthx("Waiting work element counts",
@@ -1095,8 +1099,9 @@ static int zcrypt_status_write(struct fi
 		 * '0' for no device, '1' for PCICA, '2' for PCICC,
 		 * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3,
 		 * '5' for CEX2C and '6' for CEX2A'
+		 * '7' for CEX3C and '8' for CEX3A
 		 */
-		if (*ptr >= '0' && *ptr <= '6')
+		if (*ptr >= '0' && *ptr <= '8')
 			j++;
 		else if (*ptr == 'd' || *ptr == 'D')
 			zcrypt_disable_card(j++);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_api.h linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.h
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_api.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_api.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,6 +71,8 @@ struct ica_z90_status {
 #define ZCRYPT_PCIXCC_MCL3	4
 #define ZCRYPT_CEX2C		5
 #define ZCRYPT_CEX2A		6
+#define ZCRYPT_CEX3C		7
+#define ZCRYPT_CEX3A		8
 
 /**
  * Large random numbers are pulled in 4096 byte chunks from the crypto cards
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_cex2a.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_cex2a.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_cex2a.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_cex2a.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,17 +39,24 @@
 
 #define CEX2A_MIN_MOD_SIZE	  1	/*    8 bits	*/
 #define CEX2A_MAX_MOD_SIZE	256	/* 2048 bits	*/
+#define CEX3A_MIN_MOD_SIZE	CEX2A_MIN_MOD_SIZE
+#define CEX3A_MAX_MOD_SIZE	CEX2A_MAX_MOD_SIZE
 
 #define CEX2A_SPEED_RATING	970
+#define CEX3A_SPEED_RATING	900 /* Fixme: Needs finetuning */
 
 #define CEX2A_MAX_MESSAGE_SIZE	0x390	/* sizeof(struct type50_crb2_msg)    */
 #define CEX2A_MAX_RESPONSE_SIZE 0x110	/* max outputdatalength + type80_hdr */
 
+#define CEX3A_MAX_MESSAGE_SIZE	CEX2A_MAX_MESSAGE_SIZE
+#define CEX3A_MAX_RESPONSE_SIZE	CEX2A_MAX_RESPONSE_SIZE
+
 #define CEX2A_CLEANUP_TIME	(15*HZ)
+#define CEX3A_CLEANUP_TIME	CEX2A_CLEANUP_TIME
 
 static struct ap_device_id zcrypt_cex2a_ids[] = {
 	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2A) },
-	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2A2) },
+	{ AP_DEVICE(AP_DEVICE_TYPE_CEX3A) },
 	{ /* end of list */ },
 };
 
@@ -298,6 +305,7 @@ static long zcrypt_cex2a_modexpo(struct
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -335,6 +343,7 @@ static long zcrypt_cex2a_modexpo_crt(str
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -373,31 +382,45 @@ static struct zcrypt_ops zcrypt_cex2a_op
  */
 static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
 {
-	struct zcrypt_device *zdev;
-	int rc;
-
-	zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE);
-	if (!zdev)
-		return -ENOMEM;
-	zdev->ap_dev = ap_dev;
-	zdev->ops = &zcrypt_cex2a_ops;
-	zdev->online = 1;
-	zdev->user_space_type = ZCRYPT_CEX2A;
-	zdev->type_string = "CEX2A";
-	zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
-	zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
-	zdev->short_crt = 1;
-	zdev->speed_rating = CEX2A_SPEED_RATING;
-	ap_dev->reply = &zdev->reply;
-	ap_dev->private = zdev;
-	rc = zcrypt_device_register(zdev);
-	if (rc)
-		goto out_free;
-	return 0;
+	struct zcrypt_device *zdev = NULL;
+	int rc = 0;
 
-out_free:
-	ap_dev->private = NULL;
-	zcrypt_device_free(zdev);
+	switch (ap_dev->device_type) {
+	case AP_DEVICE_TYPE_CEX2A:
+		zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE);
+		if (!zdev)
+			return -ENOMEM;
+		zdev->user_space_type = ZCRYPT_CEX2A;
+		zdev->type_string = "CEX2A";
+		zdev->min_mod_size = CEX2A_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX2A_MAX_MOD_SIZE;
+		zdev->short_crt = 1;
+		zdev->speed_rating = CEX2A_SPEED_RATING;
+		break;
+	case AP_DEVICE_TYPE_CEX3A:
+		zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE);
+		if (!zdev)
+			return -ENOMEM;
+		zdev->user_space_type = ZCRYPT_CEX3A;
+		zdev->type_string = "CEX3A";
+		zdev->min_mod_size = CEX3A_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX3A_MAX_MOD_SIZE;
+		zdev->short_crt = 1;
+		zdev->speed_rating = CEX3A_SPEED_RATING;
+		break;
+	}
+	if (zdev != NULL) {
+		zdev->ap_dev = ap_dev;
+		zdev->ops = &zcrypt_cex2a_ops;
+		zdev->online = 1;
+		ap_dev->reply = &zdev->reply;
+		ap_dev->private = zdev;
+		rc = zcrypt_device_register(zdev);
+	}
+	if (rc) {
+		ap_dev->private = NULL;
+		zcrypt_device_free(zdev);
+	}
 	return rc;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcica.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcica.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcica.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcica.c	2010-02-24 13:52:17.000000000 -0500
@@ -281,6 +281,7 @@ static long zcrypt_pcica_modexpo(struct
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -318,6 +319,7 @@ static long zcrypt_pcica_modexpo_crt(str
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcicc.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcicc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcicc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcicc.c	2010-02-24 13:52:17.000000000 -0500
@@ -373,6 +373,8 @@ static int convert_type86(struct zcrypt_
 			zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
 			return -EAGAIN;
 		}
+		if (service_rc == 8 && service_rs == 72)
+			return -EINVAL;
 		zdev->online = 0;
 		return -EAGAIN;	/* repeat the request on a different device. */
 	}
@@ -483,6 +485,7 @@ static long zcrypt_pcicc_modexpo(struct
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -521,6 +524,7 @@ static long zcrypt_pcicc_modexpo_crt(str
 	struct completion work;
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,10 +43,13 @@
 #define PCIXCC_MIN_MOD_SIZE	 16	/*  128 bits	*/
 #define PCIXCC_MIN_MOD_SIZE_OLD	 64	/*  512 bits	*/
 #define PCIXCC_MAX_MOD_SIZE	256	/* 2048 bits	*/
+#define CEX3C_MIN_MOD_SIZE	PCIXCC_MIN_MOD_SIZE
+#define CEX3C_MAX_MOD_SIZE	PCIXCC_MAX_MOD_SIZE
 
-#define PCIXCC_MCL2_SPEED_RATING	7870	/* FIXME: needs finetuning */
+#define PCIXCC_MCL2_SPEED_RATING	7870
 #define PCIXCC_MCL3_SPEED_RATING	7870
-#define CEX2C_SPEED_RATING		8540
+#define CEX2C_SPEED_RATING		7000
+#define CEX3C_SPEED_RATING		6500	/* FIXME: needs finetuning */
 
 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply	    */
@@ -72,7 +75,7 @@ struct response_type {
 static struct ap_device_id zcrypt_pcixcc_ids[] = {
 	{ AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
 	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
-	{ AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) },
+	{ AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
 	{ /* end of list */ },
 };
 
@@ -326,6 +329,11 @@ static int XCRB_msg_to_type6CPRB_msgX(st
 	function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
 	memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
 
+	if (memcmp(function_code, "US", 2) == 0)
+		ap_msg->special = 1;
+	else
+		ap_msg->special = 0;
+
 	/* copy data block */
 	if (xcRB->request_data_length &&
 	    copy_from_user(req_data, xcRB->request_data_address,
@@ -462,6 +470,8 @@ static int convert_type86_ica(struct zcr
 		}
 		if (service_rc == 12 && service_rs == 769)
 			return -EINVAL;
+		if (service_rc == 8 && service_rs == 72)
+			return -EINVAL;
 		zdev->online = 0;
 		return -EAGAIN;	/* repeat the request on a different device. */
 	}
@@ -688,6 +698,7 @@ static long zcrypt_pcixcc_modexpo(struct
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -727,6 +738,7 @@ static long zcrypt_pcixcc_modexpo_crt(st
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -766,6 +778,7 @@ static long zcrypt_pcixcc_send_cprb(stru
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -805,6 +818,7 @@ static long zcrypt_pcixcc_rng(struct zcr
 	};
 	int rc;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -972,6 +986,7 @@ static int zcrypt_pcixcc_rng_supported(s
 	} __attribute__((packed)) *reply;
 	int rc, i;
 
+	ap_init_message(&ap_msg);
 	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!ap_msg.message)
 		return -ENOMEM;
@@ -1016,14 +1031,15 @@ out_free:
 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
 {
 	struct zcrypt_device *zdev;
-	int rc;
+	int rc = 0;
 
 	zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
 	if (!zdev)
 		return -ENOMEM;
 	zdev->ap_dev = ap_dev;
 	zdev->online = 1;
-	if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
+	switch (ap_dev->device_type) {
+	case AP_DEVICE_TYPE_PCIXCC:
 		rc = zcrypt_pcixcc_mcl(ap_dev);
 		if (rc < 0) {
 			zcrypt_device_free(zdev);
@@ -1041,13 +1057,25 @@ static int zcrypt_pcixcc_probe(struct ap
 			zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 			zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
 		}
-	} else {
+		break;
+	case AP_DEVICE_TYPE_CEX2C:
 		zdev->user_space_type = ZCRYPT_CEX2C;
 		zdev->type_string = "CEX2C";
 		zdev->speed_rating = CEX2C_SPEED_RATING;
 		zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
 		zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
+		break;
+	case AP_DEVICE_TYPE_CEX3C:
+		zdev->user_space_type = ZCRYPT_CEX3C;
+		zdev->type_string = "CEX3C";
+		zdev->speed_rating = CEX3C_SPEED_RATING;
+		zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
+		zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
+		break;
+	default:
+		goto out_free;
 	}
+
 	rc = zcrypt_pcixcc_rng_supported(ap_dev);
 	if (rc < 0) {
 		zcrypt_device_free(zdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/claw.c linux-libre-2.6.33-gnu1/drivers/s390/net/claw.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/claw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/claw.c	2010-02-24 13:52:17.000000000 -0500
@@ -90,7 +90,6 @@
 #include <linux/timer.h>
 #include <linux/types.h>
 
-#include "cu3088.h"
 #include "claw.h"
 
 /*
@@ -258,6 +257,9 @@ static int claw_pm_prepare(struct ccwgro
 	return -EPERM;
 }
 
+/* the root device for claw group devices */
+static struct device *claw_root_dev;
+
 /* ccwgroup table  */
 
 static struct ccwgroup_driver claw_group_driver = {
@@ -272,6 +274,47 @@ static struct ccwgroup_driver claw_group
 	.prepare     = claw_pm_prepare,
 };
 
+static struct ccw_device_id claw_ids[] = {
+	{CCW_DEVICE(0x3088, 0x61), .driver_info = claw_channel_type_claw},
+	{},
+};
+MODULE_DEVICE_TABLE(ccw, claw_ids);
+
+static struct ccw_driver claw_ccw_driver = {
+	.owner	= THIS_MODULE,
+	.name	= "claw",
+	.ids	= claw_ids,
+	.probe	= ccwgroup_probe_ccwdev,
+	.remove	= ccwgroup_remove_ccwdev,
+};
+
+static ssize_t
+claw_driver_group_store(struct device_driver *ddrv, const char *buf,
+			size_t count)
+{
+	int err;
+	err = ccwgroup_create_from_string(claw_root_dev,
+					  claw_group_driver.driver_id,
+					  &claw_ccw_driver, 3, buf);
+	return err ? err : count;
+}
+
+static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store);
+
+static struct attribute *claw_group_attrs[] = {
+	&driver_attr_group.attr,
+	NULL,
+};
+
+static struct attribute_group claw_group_attr_group = {
+	.attrs = claw_group_attrs,
+};
+
+static const struct attribute_group *claw_group_attr_groups[] = {
+	&claw_group_attr_group,
+	NULL,
+};
+
 /*
 *       Key functions
 */
@@ -3326,7 +3369,11 @@ claw_remove_files(struct device *dev)
 static void __exit
 claw_cleanup(void)
 {
-	unregister_cu3088_discipline(&claw_group_driver);
+	driver_remove_file(&claw_group_driver.driver,
+			   &driver_attr_group);
+	ccwgroup_driver_unregister(&claw_group_driver);
+	ccw_driver_unregister(&claw_ccw_driver);
+	root_device_unregister(claw_root_dev);
 	claw_unregister_debug_facility();
 	pr_info("Driver unloaded\n");
 
@@ -3348,16 +3395,31 @@ claw_init(void)
 	if (ret) {
 		pr_err("Registering with the S/390 debug feature"
 			" failed with error code %d\n", ret);
-		return ret;
+		goto out_err;
 	}
 	CLAW_DBF_TEXT(2, setup, "init_mod");
-	ret = register_cu3088_discipline(&claw_group_driver);
-	if (ret) {
-		CLAW_DBF_TEXT(2, setup, "init_bad");
-		claw_unregister_debug_facility();
-		pr_err("Registering with the cu3088 device driver failed "
-			   "with error code %d\n", ret);
-	}
+	claw_root_dev = root_device_register("claw");
+	ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0;
+	if (ret)
+		goto register_err;
+	ret = ccw_driver_register(&claw_ccw_driver);
+	if (ret)
+		goto ccw_err;
+	claw_group_driver.driver.groups = claw_group_attr_groups;
+	ret = ccwgroup_driver_register(&claw_group_driver);
+	if (ret)
+		goto ccwgroup_err;
+	return 0;
+
+ccwgroup_err:
+	ccw_driver_unregister(&claw_ccw_driver);
+ccw_err:
+	root_device_unregister(claw_root_dev);
+register_err:
+	CLAW_DBF_TEXT(2, setup, "init_bad");
+	claw_unregister_debug_facility();
+out_err:
+	pr_err("Initializing the claw device driver failed\n");
 	return ret;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/claw.h linux-libre-2.6.33-gnu1/drivers/s390/net/claw.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/claw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/claw.h	2010-02-24 13:52:17.000000000 -0500
@@ -129,6 +129,18 @@ static inline int claw_dbf_passes(debug_
 		} \
 	} while (0)
 
+/**
+ * Enum for classifying detected devices.
+ */
+enum claw_channel_types {
+	/* Device is not a channel  */
+	claw_channel_type_none,
+
+	/* Device is a CLAW channel device */
+	claw_channel_type_claw
+};
+
+
 /*******************************************************
 *  Define Control Blocks                               *
 *                                                      *
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_fsms.c linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_fsms.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_fsms.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_fsms.c	2010-02-24 13:52:17.000000000 -0500
@@ -44,7 +44,6 @@
 #include <asm/idals.h>
 
 #include "fsm.h"
-#include "cu3088.h"
 
 #include "ctcm_dbug.h"
 #include "ctcm_main.h"
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_fsms.h linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_fsms.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_fsms.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_fsms.h	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,6 @@
 #include <asm/idals.h>
 
 #include "fsm.h"
-#include "cu3088.h"
 #include "ctcm_main.h"
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_main.c linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_main.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,12 +51,16 @@
 
 #include <asm/idals.h>
 
-#include "cu3088.h"
 #include "ctcm_fsms.h"
 #include "ctcm_main.h"
 
 /* Some common global variables */
 
+/**
+ * The root device for ctcm group devices
+ */
+static struct device *ctcm_root_dev;
+
 /*
  * Linked list of all detected channels.
  */
@@ -246,7 +250,7 @@ static void channel_remove(struct channe
  *
  * returns Pointer to a channel or NULL if no matching channel available.
  */
-static struct channel *channel_get(enum channel_types type,
+static struct channel *channel_get(enum ctcm_channel_types type,
 					char *id, int direction)
 {
 	struct channel *ch = channels;
@@ -1342,7 +1346,7 @@ static int ctcm_probe_device(struct ccwg
  *
  * returns 0 on success, !0 on error.
  */
-static int add_channel(struct ccw_device *cdev, enum channel_types type,
+static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type,
 				struct ctcm_priv *priv)
 {
 	struct channel **c = &channels;
@@ -1501,13 +1505,13 @@ free_return:	/* note that all channel po
 /*
  * Return type of a detected device.
  */
-static enum channel_types get_channel_type(struct ccw_device_id *id)
+static enum ctcm_channel_types get_channel_type(struct ccw_device_id *id)
 {
-	enum channel_types type;
-	type = (enum channel_types)id->driver_info;
+	enum ctcm_channel_types type;
+	type = (enum ctcm_channel_types)id->driver_info;
 
-	if (type == channel_type_ficon)
-		type = channel_type_escon;
+	if (type == ctcm_channel_type_ficon)
+		type = ctcm_channel_type_escon;
 
 	return type;
 }
@@ -1525,16 +1529,21 @@ static int ctcm_new_device(struct ccwgro
 	char read_id[CTCM_ID_SIZE];
 	char write_id[CTCM_ID_SIZE];
 	int direction;
-	enum channel_types type;
+	enum ctcm_channel_types type;
 	struct ctcm_priv *priv;
 	struct net_device *dev;
 	struct ccw_device *cdev0;
 	struct ccw_device *cdev1;
+	struct channel *readc;
+	struct channel *writec;
 	int ret;
+	int result;
 
 	priv = dev_get_drvdata(&cgdev->dev);
-	if (!priv)
-		return -ENODEV;
+	if (!priv) {
+		result = -ENODEV;
+		goto out_err_result;
+	}
 
 	cdev0 = cgdev->cdev[0];
 	cdev1 = cgdev->cdev[1];
@@ -1545,31 +1554,40 @@ static int ctcm_new_device(struct ccwgro
 	snprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev));
 
 	ret = add_channel(cdev0, type, priv);
-	if (ret)
-		return ret;
+	if (ret) {
+		result = ret;
+		goto out_err_result;
+	}
 	ret = add_channel(cdev1, type, priv);
-	if (ret)
-		return ret;
+	if (ret) {
+		result = ret;
+		goto out_remove_channel1;
+	}
 
 	ret = ccw_device_set_online(cdev0);
 	if (ret != 0) {
-		/* may be ok to fail now - can be done later */
 		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
 			"%s(%s) set_online rc=%d",
 				CTCM_FUNTAIL, read_id, ret);
+		result = -EIO;
+		goto out_remove_channel2;
 	}
 
 	ret = ccw_device_set_online(cdev1);
 	if (ret != 0) {
-		/* may be ok to fail now - can be done later */
 		CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
 			"%s(%s) set_online rc=%d",
 				CTCM_FUNTAIL, write_id, ret);
+
+		result = -EIO;
+		goto out_ccw1;
 	}
 
 	dev = ctcm_init_netdevice(priv);
-	if (dev == NULL)
-			goto out;
+	if (dev == NULL) {
+		result = -ENODEV;
+		goto out_ccw2;
+	}
 
 	for (direction = READ; direction <= WRITE; direction++) {
 		priv->channel[direction] =
@@ -1587,12 +1605,14 @@ static int ctcm_new_device(struct ccwgro
 	/* sysfs magic */
 	SET_NETDEV_DEV(dev, &cgdev->dev);
 
-	if (register_netdev(dev))
-			goto out_dev;
+	if (register_netdev(dev)) {
+		result = -ENODEV;
+		goto out_dev;
+	}
 
 	if (ctcm_add_attributes(&cgdev->dev)) {
-		unregister_netdev(dev);
-			goto out_dev;
+		result = -ENODEV;
+		goto out_unregister;
 	}
 
 	strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
@@ -1608,13 +1628,22 @@ static int ctcm_new_device(struct ccwgro
 			priv->channel[WRITE]->id, priv->protocol);
 
 	return 0;
+out_unregister:
+	unregister_netdev(dev);
 out_dev:
 	ctcm_free_netdevice(dev);
-out:
+out_ccw2:
 	ccw_device_set_offline(cgdev->cdev[1]);
+out_ccw1:
 	ccw_device_set_offline(cgdev->cdev[0]);
-
-	return -ENODEV;
+out_remove_channel2:
+	readc = channel_get(type, read_id, READ);
+	channel_remove(readc);
+out_remove_channel1:
+	writec = channel_get(type, write_id, WRITE);
+	channel_remove(writec);
+out_err_result:
+	return result;
 }
 
 /**
@@ -1695,6 +1724,11 @@ static int ctcm_pm_suspend(struct ccwgro
 		return 0;
 	netif_device_detach(priv->channel[READ]->netdev);
 	ctcm_close(priv->channel[READ]->netdev);
+	if (!wait_event_timeout(priv->fsm->wait_q,
+	    fsm_getstate(priv->fsm) == DEV_STATE_STOPPED, CTCM_TIME_5_SEC)) {
+		netif_device_attach(priv->channel[READ]->netdev);
+		return -EBUSY;
+	}
 	ccw_device_set_offline(gdev->cdev[1]);
 	ccw_device_set_offline(gdev->cdev[0]);
 	return 0;
@@ -1719,6 +1753,22 @@ err_out:
 	return rc;
 }
 
+static struct ccw_device_id ctcm_ids[] = {
+	{CCW_DEVICE(0x3088, 0x08), .driver_info = ctcm_channel_type_parallel},
+	{CCW_DEVICE(0x3088, 0x1e), .driver_info = ctcm_channel_type_ficon},
+	{CCW_DEVICE(0x3088, 0x1f), .driver_info = ctcm_channel_type_escon},
+	{},
+};
+MODULE_DEVICE_TABLE(ccw, ctcm_ids);
+
+static struct ccw_driver ctcm_ccw_driver = {
+	.owner	= THIS_MODULE,
+	.name	= "ctcm",
+	.ids	= ctcm_ids,
+	.probe	= ccwgroup_probe_ccwdev,
+	.remove	= ccwgroup_remove_ccwdev,
+};
+
 static struct ccwgroup_driver ctcm_group_driver = {
 	.owner       = THIS_MODULE,
 	.name        = CTC_DRIVER_NAME,
@@ -1733,6 +1783,33 @@ static struct ccwgroup_driver ctcm_group
 	.restore     = ctcm_pm_resume,
 };
 
+static ssize_t
+ctcm_driver_group_store(struct device_driver *ddrv, const char *buf,
+			size_t count)
+{
+	int err;
+
+	err = ccwgroup_create_from_string(ctcm_root_dev,
+					  ctcm_group_driver.driver_id,
+					  &ctcm_ccw_driver, 2, buf);
+	return err ? err : count;
+}
+
+static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store);
+
+static struct attribute *ctcm_group_attrs[] = {
+	&driver_attr_group.attr,
+	NULL,
+};
+
+static struct attribute_group ctcm_group_attr_group = {
+	.attrs = ctcm_group_attrs,
+};
+
+static const struct attribute_group *ctcm_group_attr_groups[] = {
+	&ctcm_group_attr_group,
+	NULL,
+};
 
 /*
  * Module related routines
@@ -1746,7 +1823,10 @@ static struct ccwgroup_driver ctcm_group
  */
 static void __exit ctcm_exit(void)
 {
-	unregister_cu3088_discipline(&ctcm_group_driver);
+	driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group);
+	ccwgroup_driver_unregister(&ctcm_group_driver);
+	ccw_driver_unregister(&ctcm_ccw_driver);
+	root_device_unregister(ctcm_root_dev);
 	ctcm_unregister_dbf_views();
 	pr_info("CTCM driver unloaded\n");
 }
@@ -1772,17 +1852,31 @@ static int __init ctcm_init(void)
 	channels = NULL;
 
 	ret = ctcm_register_dbf_views();
-	if (ret) {
-		return ret;
-	}
-	ret = register_cu3088_discipline(&ctcm_group_driver);
-	if (ret) {
-		ctcm_unregister_dbf_views();
-		pr_err("%s / register_cu3088_discipline failed, ret = %d\n",
-			__func__, ret);
-		return ret;
-	}
+	if (ret)
+		goto out_err;
+	ctcm_root_dev = root_device_register("ctcm");
+	ret = IS_ERR(ctcm_root_dev) ? PTR_ERR(ctcm_root_dev) : 0;
+	if (ret)
+		goto register_err;
+	ret = ccw_driver_register(&ctcm_ccw_driver);
+	if (ret)
+		goto ccw_err;
+	ctcm_group_driver.driver.groups = ctcm_group_attr_groups;
+	ret = ccwgroup_driver_register(&ctcm_group_driver);
+	if (ret)
+		goto ccwgroup_err;
 	print_banner();
+	return 0;
+
+ccwgroup_err:
+	ccw_driver_unregister(&ctcm_ccw_driver);
+ccw_err:
+	root_device_unregister(ctcm_root_dev);
+register_err:
+	ctcm_unregister_dbf_views();
+out_err:
+	pr_err("%s / Initializing the ctcm device driver failed, ret = %d\n",
+		__func__, ret);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_main.h linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_main.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_main.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_main.h	2010-02-24 13:52:17.000000000 -0500
@@ -16,7 +16,6 @@
 #include <linux/netdevice.h>
 
 #include "fsm.h"
-#include "cu3088.h"
 #include "ctcm_dbug.h"
 #include "ctcm_mpc.h"
 
@@ -66,6 +65,23 @@
 			ctcmpc_dumpit(buf, len); \
 	} while (0)
 
+/**
+ * Enum for classifying detected devices
+ */
+enum ctcm_channel_types {
+	/* Device is not a channel  */
+	ctcm_channel_type_none,
+
+	/* Device is a CTC/A */
+	ctcm_channel_type_parallel,
+
+	/* Device is a FICON channel */
+	ctcm_channel_type_ficon,
+
+	/* Device is a ESCON channel */
+	ctcm_channel_type_escon
+};
+
 /*
  * CCW commands, used in this driver.
  */
@@ -121,7 +137,7 @@ struct channel {
 	 * Type of this channel.
 	 * CTC/A or Escon for valid channels.
 	 */
-	enum channel_types type;
+	enum ctcm_channel_types type;
 	/*
 	 * Misc. flags. See CHANNEL_FLAGS_... below
 	 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_mpc.c linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_mpc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_mpc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_mpc.c	2010-02-24 13:52:17.000000000 -0500
@@ -53,7 +53,6 @@
 #include <linux/moduleparam.h>
 #include <asm/idals.h>
 
-#include "cu3088.h"
 #include "ctcm_mpc.h"
 #include "ctcm_main.h"
 #include "ctcm_fsms.h"
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_sysfs.c linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/ctcm_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/ctcm_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -158,6 +158,15 @@ static ssize_t ctcm_proto_store(struct d
 	return count;
 }
 
+const char *ctcm_type[] = {
+	"not a channel",
+	"CTC/A",
+	"FICON channel",
+	"ESCON channel",
+	"unknown channel type",
+	"unsupported channel type",
+};
+
 static ssize_t ctcm_type_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -168,7 +177,7 @@ static ssize_t ctcm_type_show(struct dev
 		return -ENODEV;
 
 	return sprintf(buf, "%s\n",
-			cu3088_type[cgdev->cdev[0]->id.driver_info]);
+			ctcm_type[cgdev->cdev[0]->id.driver_info]);
 }
 
 static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/cu3088.c linux-libre-2.6.33-gnu1/drivers/s390/net/cu3088.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/cu3088.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/cu3088.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,148 +0,0 @@
-/*
- * CTC / LCS ccw_device driver
- *
- * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Arnd Bergmann <arndb@de.ibm.com>
- *            Cornelia Huck <cornelia.huck@de.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, 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/init.h>
-#include <linux/module.h>
-#include <linux/err.h>
-
-#include <asm/ccwdev.h>
-#include <asm/ccwgroup.h>
-
-#include "cu3088.h"
-
-const char *cu3088_type[] = {
-	"not a channel",
-	"CTC/A",
-	"ESCON channel",
-	"FICON channel",
-	"OSA LCS card",
-	"CLAW channel device",
-	"unknown channel type",
-	"unsupported channel type",
-};
-
-/* static definitions */
-
-static struct ccw_device_id cu3088_ids[] = {
-	{ CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel },
-	{ CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon },
-	{ CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
-	{ CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
-	{ CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw },
-	{ /* end of list */ }
-};
-
-static struct ccw_driver cu3088_driver;
-
-static struct device *cu3088_root_dev;
-
-static ssize_t
-group_write(struct device_driver *drv, const char *buf, size_t count)
-{
-	int ret;
-	struct ccwgroup_driver *cdrv;
-
-	cdrv = to_ccwgroupdrv(drv);
-	if (!cdrv)
-		return -EINVAL;
-	ret = ccwgroup_create_from_string(cu3088_root_dev, cdrv->driver_id,
-					  &cu3088_driver, 2, buf);
-
-	return (ret == 0) ? count : ret;
-}
-
-static DRIVER_ATTR(group, 0200, NULL, group_write);
-
-/* Register-unregister for ctc&lcs */
-int
-register_cu3088_discipline(struct ccwgroup_driver *dcp)
-{
-	int rc;
-
-	if (!dcp)
-		return -EINVAL;
-
-	/* Register discipline.*/
-	rc = ccwgroup_driver_register(dcp);
-	if (rc)
-		return rc;
-
-	rc = driver_create_file(&dcp->driver, &driver_attr_group);
-	if (rc)
-		ccwgroup_driver_unregister(dcp);
-
-	return rc;
-
-}
-
-void
-unregister_cu3088_discipline(struct ccwgroup_driver *dcp)
-{
-	if (!dcp)
-		return;
-
-	driver_remove_file(&dcp->driver, &driver_attr_group);
-	ccwgroup_driver_unregister(dcp);
-}
-
-static struct ccw_driver cu3088_driver = {
-	.owner	     = THIS_MODULE,
-	.ids	     = cu3088_ids,
-	.name        = "cu3088",
-	.probe	     = ccwgroup_probe_ccwdev,
-	.remove	     = ccwgroup_remove_ccwdev,
-};
-
-/* module setup */
-static int __init
-cu3088_init (void)
-{
-	int rc;
-
-	cu3088_root_dev = root_device_register("cu3088");
-	if (IS_ERR(cu3088_root_dev))
-		return PTR_ERR(cu3088_root_dev);
-	rc = ccw_driver_register(&cu3088_driver);
-	if (rc)
-		root_device_unregister(cu3088_root_dev);
-
-	return rc;
-}
-
-static void __exit
-cu3088_exit (void)
-{
-	ccw_driver_unregister(&cu3088_driver);
-	root_device_unregister(cu3088_root_dev);
-}
-
-MODULE_DEVICE_TABLE(ccw,cu3088_ids);
-MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
-MODULE_LICENSE("GPL");
-
-module_init(cu3088_init);
-module_exit(cu3088_exit);
-
-EXPORT_SYMBOL_GPL(cu3088_type);
-EXPORT_SYMBOL_GPL(register_cu3088_discipline);
-EXPORT_SYMBOL_GPL(unregister_cu3088_discipline);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/cu3088.h linux-libre-2.6.33-gnu1/drivers/s390/net/cu3088.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/cu3088.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/cu3088.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-#ifndef _CU3088_H
-#define _CU3088_H
-
-/**
- * Enum for classifying detected devices.
- */
-enum channel_types {
-        /* Device is not a channel  */
-	channel_type_none,
-
-        /* Device is a CTC/A */
-	channel_type_parallel,
-
-	/* Device is a ESCON channel */
-	channel_type_escon,
-
-	/* Device is a FICON channel */
-	channel_type_ficon,
-
-	/* Device is a OSA2 card */
-	channel_type_osa2,
-
-	/* Device is a CLAW channel device */
-	channel_type_claw,
-
-	/* Device is a channel, but we don't know
-	 * anything about it */
-	channel_type_unknown,
-
-	/* Device is an unsupported model */
-	channel_type_unsupported,
-
-	/* number of type entries */
-	num_channel_types
-};
-
-extern const char *cu3088_type[num_channel_types];
-extern int register_cu3088_discipline(struct ccwgroup_driver *);
-extern void unregister_cu3088_discipline(struct ccwgroup_driver *);
-
-#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/fsm.c linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/fsm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.c	2010-02-24 13:52:17.000000000 -0500
@@ -27,6 +27,7 @@ init_fsm(char *name, const char **state_
 		return NULL;
 	}
 	strlcpy(this->name, name, sizeof(this->name));
+	init_waitqueue_head(&this->wait_q);
 
 	f = kzalloc(sizeof(fsm), order);
 	if (f == NULL) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/fsm.h linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/fsm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/fsm.h	2010-02-24 13:52:17.000000000 -0500
@@ -66,6 +66,7 @@ typedef struct fsm_instance_t {
 	char name[16];
 	void *userdata;
 	int userint;
+	wait_queue_head_t wait_q;
 #if FSM_DEBUG_HISTORY
 	int         history_index;
 	int         history_size;
@@ -197,6 +198,7 @@ fsm_newstate(fsm_instance *fi, int newst
 	printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name,
 		fi->f->state_names[newstate]);
 #endif
+	wake_up(&fi->wait_q);
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/lcs.c linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/lcs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,7 +47,6 @@
 #include <asm/ccwgroup.h>
 
 #include "lcs.h"
-#include "cu3088.h"
 
 
 #if !defined(CONFIG_NET_ETHERNET) && \
@@ -60,7 +59,11 @@
  */
 
 static char version[] __initdata = "LCS driver";
-static char debug_buffer[255];
+
+/**
+  * the root device for lcs group devices
+  */
+static struct device *lcs_root_dev;
 
 /**
  * Some prototypes.
@@ -76,6 +79,7 @@ static int lcs_recovery(void *ptr);
 /**
  * Debug Facility Stuff
  */
+static char debug_buffer[255];
 static debug_info_t *lcs_dbf_setup;
 static debug_info_t *lcs_dbf_trace;
 
@@ -889,7 +893,7 @@ lcs_send_lancmd(struct lcs_card *card, s
 	rc = lcs_ready_buffer(&card->write, buffer);
 	if (rc)
 		return rc;
-	init_timer(&timer);
+	init_timer_on_stack(&timer);
 	timer.function = lcs_lancmd_timeout;
 	timer.data = (unsigned long) reply;
 	timer.expires = jiffies + HZ*card->lancmd_timeout;
@@ -1968,6 +1972,15 @@ lcs_portno_store (struct device *dev, st
 
 static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
 
+const char *lcs_type[] = {
+	"not a channel",
+	"2216 parallel",
+	"2216 channel",
+	"OSA LCS card",
+	"unknown channel type",
+	"unsupported channel type",
+};
+
 static ssize_t
 lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1977,7 +1990,7 @@ lcs_type_show(struct device *dev, struct
 	if (!cgdev)
 		return -ENODEV;
 
-	return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]);
+	return sprintf(buf, "%s\n", lcs_type[cgdev->cdev[0]->id.driver_info]);
 }
 
 static DEVICE_ATTR(type, 0444, lcs_type_show, NULL);
@@ -2130,8 +2143,12 @@ lcs_new_device(struct ccwgroup_device *c
 	card->write.ccwdev = ccwgdev->cdev[1];
 
 	recover_state = card->state;
-	ccw_device_set_online(card->read.ccwdev);
-	ccw_device_set_online(card->write.ccwdev);
+	rc = ccw_device_set_online(card->read.ccwdev);
+	if (rc)
+		goto out_err;
+	rc = ccw_device_set_online(card->write.ccwdev);
+	if (rc)
+		goto out_werr;
 
 	LCS_DBF_TEXT(3, setup, "lcsnewdv");
 
@@ -2210,8 +2227,10 @@ netdev_out:
 	return 0;
 out:
 
-	ccw_device_set_offline(card->read.ccwdev);
 	ccw_device_set_offline(card->write.ccwdev);
+out_werr:
+	ccw_device_set_offline(card->read.ccwdev);
+out_err:
 	return -ENODEV;
 }
 
@@ -2364,6 +2383,22 @@ static int lcs_restore(struct ccwgroup_d
 	return lcs_pm_resume(card);
 }
 
+static struct ccw_device_id lcs_ids[] = {
+	{CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel},
+	{CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216},
+	{CCW_DEVICE(0x3088, 0x60), .driver_info = lcs_channel_type_osa2},
+	{},
+};
+MODULE_DEVICE_TABLE(ccw, lcs_ids);
+
+static struct ccw_driver lcs_ccw_driver = {
+	.owner	= THIS_MODULE,
+	.name	= "lcs",
+	.ids	= lcs_ids,
+	.probe	= ccwgroup_probe_ccwdev,
+	.remove	= ccwgroup_remove_ccwdev,
+};
+
 /**
  * LCS ccwgroup driver registration
  */
@@ -2383,6 +2418,33 @@ static struct ccwgroup_driver lcs_group_
 	.restore     = lcs_restore,
 };
 
+static ssize_t
+lcs_driver_group_store(struct device_driver *ddrv, const char *buf,
+		       size_t count)
+{
+	int err;
+	err = ccwgroup_create_from_string(lcs_root_dev,
+					  lcs_group_driver.driver_id,
+					  &lcs_ccw_driver, 2, buf);
+	return err ? err : count;
+}
+
+static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store);
+
+static struct attribute *lcs_group_attrs[] = {
+	&driver_attr_group.attr,
+	NULL,
+};
+
+static struct attribute_group lcs_group_attr_group = {
+	.attrs = lcs_group_attrs,
+};
+
+static const struct attribute_group *lcs_group_attr_groups[] = {
+	&lcs_group_attr_group,
+	NULL,
+};
+
 /**
  *  LCS Module/Kernel initialization function
  */
@@ -2394,17 +2456,30 @@ __init lcs_init_module(void)
 	pr_info("Loading %s\n", version);
 	rc = lcs_register_debug_facility();
 	LCS_DBF_TEXT(0, setup, "lcsinit");
-	if (rc) {
-		pr_err("Initialization failed\n");
-		return rc;
-	}
-
-	rc = register_cu3088_discipline(&lcs_group_driver);
-	if (rc) {
-		pr_err("Initialization failed\n");
-		return rc;
-	}
+	if (rc)
+		goto out_err;
+	lcs_root_dev = root_device_register("lcs");
+	rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0;
+	if (rc)
+		goto register_err;
+	rc = ccw_driver_register(&lcs_ccw_driver);
+	if (rc)
+		goto ccw_err;
+	lcs_group_driver.driver.groups = lcs_group_attr_groups;
+	rc = ccwgroup_driver_register(&lcs_group_driver);
+	if (rc)
+		goto ccwgroup_err;
 	return 0;
+
+ccwgroup_err:
+	ccw_driver_unregister(&lcs_ccw_driver);
+ccw_err:
+	root_device_unregister(lcs_root_dev);
+register_err:
+	lcs_unregister_debug_facility();
+out_err:
+	pr_err("Initializing the lcs device driver failed\n");
+	return rc;
 }
 
 
@@ -2416,7 +2491,11 @@ __exit lcs_cleanup_module(void)
 {
 	pr_info("Terminating lcs module.\n");
 	LCS_DBF_TEXT(0, trace, "cleanup");
-	unregister_cu3088_discipline(&lcs_group_driver);
+	driver_remove_file(&lcs_group_driver.driver,
+			   &driver_attr_group);
+	ccwgroup_driver_unregister(&lcs_group_driver);
+	ccw_driver_unregister(&lcs_ccw_driver);
+	root_device_unregister(lcs_root_dev);
 	lcs_unregister_debug_facility();
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/lcs.h linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/lcs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/lcs.h	2010-02-24 13:52:17.000000000 -0500
@@ -36,6 +36,24 @@ static inline int lcs_dbf_passes(debug_i
 #define CARD_FROM_DEV(cdev) \
 	(struct lcs_card *) dev_get_drvdata( \
 		&((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev);
+
+/**
+ * Enum for classifying detected devices.
+ */
+enum lcs_channel_types {
+	/* Device is not a channel  */
+	lcs_channel_type_none,
+
+	/* Device is a 2216 channel */
+	lcs_channel_type_parallel,
+
+	/* Device is a 2216 channel */
+	lcs_channel_type_2216,
+
+	/* Device is a OSA2 card */
+	lcs_channel_type_osa2
+};
+
 /**
  * CCW commands used in this driver
  */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/Makefile linux-libre-2.6.33-gnu1/drivers/s390/net/Makefile
--- linux-libre-2.6.32-gnu1/drivers/s390/net/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,11 +3,11 @@
 #
 
 ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
-obj-$(CONFIG_CTCM) += ctcm.o fsm.o cu3088.o
+obj-$(CONFIG_CTCM) += ctcm.o fsm.o
 obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
-obj-$(CONFIG_LCS) += lcs.o cu3088.o
-obj-$(CONFIG_CLAW) += claw.o cu3088.o
+obj-$(CONFIG_LCS) += lcs.o
+obj-$(CONFIG_CLAW) += claw.o
 qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
 obj-$(CONFIG_QETH) += qeth.o
 qeth_l2-y += qeth_l2_main.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/netiucv.c linux-libre-2.6.33-gnu1/drivers/s390/net/netiucv.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/netiucv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/netiucv.c	2010-02-24 13:52:17.000000000 -0500
@@ -113,11 +113,9 @@ static inline int iucv_dbf_passes(debug_
 #define IUCV_DBF_TEXT_(name, level, text...) \
 	do { \
 		if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
-			char* iucv_dbf_txt_buf = \
-					get_cpu_var(iucv_dbf_txt_buf); \
-			sprintf(iucv_dbf_txt_buf, text); \
-			debug_text_event(iucv_dbf_##name, level, \
-						iucv_dbf_txt_buf); \
+			char* __buf = get_cpu_var(iucv_dbf_txt_buf); \
+			sprintf(__buf, text); \
+			debug_text_event(iucv_dbf_##name, level, __buf); \
 			put_cpu_var(iucv_dbf_txt_buf); \
 		} \
 	} while (0)
@@ -161,7 +159,7 @@ static void netiucv_pm_complete(struct d
 static int netiucv_pm_freeze(struct device *);
 static int netiucv_pm_restore_thaw(struct device *);
 
-static struct dev_pm_ops netiucv_pm_ops = {
+static const struct dev_pm_ops netiucv_pm_ops = {
 	.prepare = netiucv_pm_prepare,
 	.complete = netiucv_pm_complete,
 	.freeze = netiucv_pm_freeze,
@@ -741,13 +739,13 @@ static void conn_action_txdone(fsm_insta
 	if (single_flag) {
 		if ((skb = skb_dequeue(&conn->commit_queue))) {
 			atomic_dec(&skb->users);
-			dev_kfree_skb_any(skb);
 			if (privptr) {
 				privptr->stats.tx_packets++;
 				privptr->stats.tx_bytes +=
 					(skb->len - NETIUCV_HDRLEN
-					 	  - NETIUCV_HDRLEN);
+						  - NETIUCV_HDRLEN);
 			}
+			dev_kfree_skb_any(skb);
 		}
 	}
 	conn->tx_buff->data = conn->tx_buff->head;
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core.h linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core.h	2010-02-24 13:52:17.000000000 -0500
@@ -122,7 +122,6 @@ struct qeth_perf_stats {
 	__u64 outbound_do_qdio_start_time;
 	unsigned int outbound_do_qdio_cnt;
 	unsigned int outbound_do_qdio_time;
-	/* eddp data */
 	unsigned int large_send_bytes;
 	unsigned int large_send_cnt;
 	unsigned int sg_skbs_sent;
@@ -135,6 +134,7 @@ struct qeth_perf_stats {
 	unsigned int sg_frags_rx;
 	unsigned int sg_alloc_page_rx;
 	unsigned int tx_csum;
+	unsigned int tx_lin;
 };
 
 /* Routing stuff */
@@ -648,6 +648,7 @@ struct qeth_card_options {
 	enum qeth_large_send_types large_send;
 	int performance_stats;
 	int rx_sg_cb;
+	enum qeth_ipa_isolation_modes isolation;
 };
 
 /*
@@ -776,7 +777,6 @@ static inline void qeth_put_buffer_pool_
 	list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
 }
 
-struct qeth_eddp_context;
 extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
 extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
 const char *qeth_get_cardname_short(struct qeth_card *);
@@ -836,7 +836,6 @@ void qeth_prepare_ipa_cmd(struct qeth_ca
 struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
 int qeth_mdio_read(struct net_device *, int, int);
 int qeth_snmp_command(struct qeth_card *, char __user *);
-int qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
 struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
 int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
 					unsigned long);
@@ -849,13 +848,14 @@ int qeth_do_send_packet_fast(struct qeth
 			struct sk_buff *, struct qeth_hdr *, int, int, int);
 int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
 		    struct sk_buff *, struct qeth_hdr *, int);
-int qeth_core_get_stats_count(struct net_device *);
+int qeth_core_get_sset_count(struct net_device *, int);
 void qeth_core_get_ethtool_stats(struct net_device *,
 				struct ethtool_stats *, u64 *);
 void qeth_core_get_strings(struct net_device *, u32, u8 *);
 void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
 void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...);
 int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
+int qeth_set_access_ctrl_online(struct qeth_card *card);
 
 /* exports for OSN */
 int qeth_osn_assist(struct net_device *, void *, int);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_main.c linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_main.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -270,41 +270,6 @@ int qeth_realloc_buffer_pool(struct qeth
 	return qeth_alloc_buffer_pool(card);
 }
 
-int qeth_set_large_send(struct qeth_card *card,
-		enum qeth_large_send_types type)
-{
-	int rc = 0;
-
-	if (card->dev == NULL) {
-		card->options.large_send = type;
-		return 0;
-	}
-	if (card->state == CARD_STATE_UP)
-		netif_tx_disable(card->dev);
-	card->options.large_send = type;
-	switch (card->options.large_send) {
-	case QETH_LARGE_SEND_TSO:
-		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
-			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
-						NETIF_F_HW_CSUM;
-		} else {
-			card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
-						NETIF_F_HW_CSUM);
-			card->options.large_send = QETH_LARGE_SEND_NO;
-			rc = -EOPNOTSUPP;
-		}
-		break;
-	default: /* includes QETH_LARGE_SEND_NO */
-		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
-					NETIF_F_HW_CSUM);
-		break;
-	}
-	if (card->state == CARD_STATE_UP)
-		netif_wake_queue(card->dev);
-	return rc;
-}
-EXPORT_SYMBOL_GPL(qeth_set_large_send);
-
 static int qeth_issue_next_read(struct qeth_card *card)
 {
 	int rc;
@@ -1079,6 +1044,7 @@ static void qeth_set_intial_options(stru
 	card->options.add_hhlen = DEFAULT_ADD_HHLEN;
 	card->options.performance_stats = 0;
 	card->options.rx_sg_cb = QETH_RX_SG_CB;
+	card->options.isolation = ISOLATION_MODE_NONE;
 }
 
 static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -3389,6 +3355,156 @@ int qeth_setadpparms_change_macaddr(stru
 }
 EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
 
+static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
+		struct qeth_reply *reply, unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	struct qeth_set_access_ctrl *access_ctrl_req;
+	int rc;
+
+	QETH_DBF_TEXT(TRACE, 4, "setaccb");
+
+	cmd = (struct qeth_ipa_cmd *) data;
+	access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
+	QETH_DBF_TEXT_(SETUP, 2, "setaccb");
+	QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
+	QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
+		cmd->data.setadapterparms.hdr.return_code);
+	switch (cmd->data.setadapterparms.hdr.return_code) {
+	case SET_ACCESS_CTRL_RC_SUCCESS:
+	case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
+	case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
+	{
+		card->options.isolation = access_ctrl_req->subcmd_code;
+		if (card->options.isolation == ISOLATION_MODE_NONE) {
+			dev_info(&card->gdev->dev,
+			    "QDIO data connection isolation is deactivated\n");
+		} else {
+			dev_info(&card->gdev->dev,
+			    "QDIO data connection isolation is activated\n");
+		}
+		QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
+			card->gdev->dev.kobj.name,
+			access_ctrl_req->subcmd_code,
+			cmd->data.setadapterparms.hdr.return_code);
+		rc = 0;
+		break;
+	}
+	case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
+	{
+		QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
+			card->gdev->dev.kobj.name,
+			access_ctrl_req->subcmd_code,
+			cmd->data.setadapterparms.hdr.return_code);
+		dev_err(&card->gdev->dev, "Adapter does not "
+			"support QDIO data connection isolation\n");
+
+		/* ensure isolation mode is "none" */
+		card->options.isolation = ISOLATION_MODE_NONE;
+		rc = -EOPNOTSUPP;
+		break;
+	}
+	case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
+	{
+		QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
+			card->gdev->dev.kobj.name,
+			access_ctrl_req->subcmd_code,
+			cmd->data.setadapterparms.hdr.return_code);
+		dev_err(&card->gdev->dev,
+			"Adapter is dedicated. "
+			"QDIO data connection isolation not supported\n");
+
+		/* ensure isolation mode is "none" */
+		card->options.isolation = ISOLATION_MODE_NONE;
+		rc = -EOPNOTSUPP;
+		break;
+	}
+	case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
+	{
+		QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
+			card->gdev->dev.kobj.name,
+			access_ctrl_req->subcmd_code,
+			cmd->data.setadapterparms.hdr.return_code);
+		dev_err(&card->gdev->dev,
+			"TSO does not permit QDIO data connection isolation\n");
+
+		/* ensure isolation mode is "none" */
+		card->options.isolation = ISOLATION_MODE_NONE;
+		rc = -EPERM;
+		break;
+	}
+	default:
+	{
+		/* this should never happen */
+		QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d"
+			"==UNKNOWN\n",
+			card->gdev->dev.kobj.name,
+			access_ctrl_req->subcmd_code,
+			cmd->data.setadapterparms.hdr.return_code);
+
+		/* ensure isolation mode is "none" */
+		card->options.isolation = ISOLATION_MODE_NONE;
+		rc = 0;
+		break;
+	}
+	}
+	qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
+	return rc;
+}
+
+static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
+		enum qeth_ipa_isolation_modes isolation)
+{
+	int rc;
+	struct qeth_cmd_buffer *iob;
+	struct qeth_ipa_cmd *cmd;
+	struct qeth_set_access_ctrl *access_ctrl_req;
+
+	QETH_DBF_TEXT(TRACE, 4, "setacctl");
+
+	QETH_DBF_TEXT_(SETUP, 2, "setacctl");
+	QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
+
+	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL,
+				   sizeof(struct qeth_ipacmd_setadpparms_hdr) +
+				   sizeof(struct qeth_set_access_ctrl));
+	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+	access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
+	access_ctrl_req->subcmd_code = isolation;
+
+	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
+			       NULL);
+	QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
+	return rc;
+}
+
+int qeth_set_access_ctrl_online(struct qeth_card *card)
+{
+	int rc = 0;
+
+	QETH_DBF_TEXT(TRACE, 4, "setactlo");
+
+	if (card->info.type == QETH_CARD_TYPE_OSAE &&
+	    qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
+		rc = qeth_setadpparms_set_access_ctrl(card,
+			card->options.isolation);
+		if (rc) {
+			QETH_DBF_MESSAGE(3,
+				"IPA(SET_ACCESS_CTRL,%s,%d) sent failed",
+				card->gdev->dev.kobj.name,
+				rc);
+		}
+	} else if (card->options.isolation != ISOLATION_MODE_NONE) {
+		card->options.isolation = ISOLATION_MODE_NONE;
+
+		dev_err(&card->gdev->dev, "Adapter does not "
+			"support QDIO data connection isolation\n");
+		rc = -EOPNOTSUPP;
+	}
+	return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_set_access_ctrl_online);
+
 void qeth_tx_timeout(struct net_device *dev)
 {
 	struct qeth_card *card;
@@ -3732,30 +3848,36 @@ static int qeth_core_driver_group(const
 int qeth_core_hardsetup_card(struct qeth_card *card)
 {
 	struct qdio_ssqd_desc *ssqd;
-	int retries = 3;
+	int retries = 0;
 	int mpno = 0;
 	int rc;
 
 	QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
 	atomic_set(&card->force_alloc_skb, 0);
 retry:
-	if (retries < 3) {
+	if (retries)
 		QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n",
 			dev_name(&card->gdev->dev));
-		ccw_device_set_offline(CARD_DDEV(card));
-		ccw_device_set_offline(CARD_WDEV(card));
-		ccw_device_set_offline(CARD_RDEV(card));
-		ccw_device_set_online(CARD_RDEV(card));
-		ccw_device_set_online(CARD_WDEV(card));
-		ccw_device_set_online(CARD_DDEV(card));
-	}
+	ccw_device_set_offline(CARD_DDEV(card));
+	ccw_device_set_offline(CARD_WDEV(card));
+	ccw_device_set_offline(CARD_RDEV(card));
+	rc = ccw_device_set_online(CARD_RDEV(card));
+	if (rc)
+		goto retriable;
+	rc = ccw_device_set_online(CARD_WDEV(card));
+	if (rc)
+		goto retriable;
+	rc = ccw_device_set_online(CARD_DDEV(card));
+	if (rc)
+		goto retriable;
 	rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD);
+retriable:
 	if (rc == -ERESTARTSYS) {
 		QETH_DBF_TEXT(SETUP, 2, "break1");
 		return rc;
 	} else if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		if (--retries < 0)
+		if (++retries > 3)
 			goto out;
 		else
 			goto retry;
@@ -4303,13 +4425,19 @@ static struct {
 	{"tx do_QDIO time"},
 	{"tx do_QDIO count"},
 	{"tx csum"},
+	{"tx lin"},
 };
 
-int qeth_core_get_stats_count(struct net_device *dev)
+int qeth_core_get_sset_count(struct net_device *dev, int stringset)
 {
-	return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN);
+	switch (stringset) {
+	case ETH_SS_STATS:
+		return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN);
+	default:
+		return -EINVAL;
+	}
 }
-EXPORT_SYMBOL_GPL(qeth_core_get_stats_count);
+EXPORT_SYMBOL_GPL(qeth_core_get_sset_count);
 
 void qeth_core_get_ethtool_stats(struct net_device *dev,
 		struct ethtool_stats *stats, u64 *data)
@@ -4355,6 +4483,7 @@ void qeth_core_get_ethtool_stats(struct
 	data[31] = card->perf_stats.outbound_do_qdio_time;
 	data[32] = card->perf_stats.outbound_do_qdio_cnt;
 	data[33] = card->perf_stats.tx_csum;
+	data[34] = card->perf_stats.tx_lin;
 }
 EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_mpc.h linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_mpc.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_mpc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_mpc.h	2010-02-24 13:52:17.000000000 -0500
@@ -234,18 +234,19 @@ enum qeth_ipa_setdelip_flags {
 
 /* SETADAPTER IPA Command: ****************************************************/
 enum qeth_ipa_setadp_cmd {
-	IPA_SETADP_QUERY_COMMANDS_SUPPORTED	= 0x0001,
-	IPA_SETADP_ALTER_MAC_ADDRESS		= 0x0002,
-	IPA_SETADP_ADD_DELETE_GROUP_ADDRESS	= 0x0004,
-	IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR	= 0x0008,
-	IPA_SETADP_SET_ADDRESSING_MODE		= 0x0010,
-	IPA_SETADP_SET_CONFIG_PARMS		= 0x0020,
-	IPA_SETADP_SET_CONFIG_PARMS_EXTENDED	= 0x0040,
-	IPA_SETADP_SET_BROADCAST_MODE		= 0x0080,
-	IPA_SETADP_SEND_OSA_MESSAGE		= 0x0100,
-	IPA_SETADP_SET_SNMP_CONTROL		= 0x0200,
-	IPA_SETADP_QUERY_CARD_INFO		= 0x0400,
-	IPA_SETADP_SET_PROMISC_MODE		= 0x0800,
+	IPA_SETADP_QUERY_COMMANDS_SUPPORTED	= 0x00000001L,
+	IPA_SETADP_ALTER_MAC_ADDRESS		= 0x00000002L,
+	IPA_SETADP_ADD_DELETE_GROUP_ADDRESS	= 0x00000004L,
+	IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR	= 0x00000008L,
+	IPA_SETADP_SET_ADDRESSING_MODE		= 0x00000010L,
+	IPA_SETADP_SET_CONFIG_PARMS		= 0x00000020L,
+	IPA_SETADP_SET_CONFIG_PARMS_EXTENDED	= 0x00000040L,
+	IPA_SETADP_SET_BROADCAST_MODE		= 0x00000080L,
+	IPA_SETADP_SEND_OSA_MESSAGE		= 0x00000100L,
+	IPA_SETADP_SET_SNMP_CONTROL		= 0x00000200L,
+	IPA_SETADP_QUERY_CARD_INFO		= 0x00000400L,
+	IPA_SETADP_SET_PROMISC_MODE		= 0x00000800L,
+	IPA_SETADP_SET_ACCESS_CONTROL		= 0x00010000L,
 };
 enum qeth_ipa_mac_ops {
 	CHANGE_ADDR_READ_MAC		= 0,
@@ -264,6 +265,20 @@ enum qeth_ipa_promisc_modes {
 	SET_PROMISC_MODE_OFF		= 0,
 	SET_PROMISC_MODE_ON		= 1,
 };
+enum qeth_ipa_isolation_modes {
+	ISOLATION_MODE_NONE		= 0x00000000L,
+	ISOLATION_MODE_FWD		= 0x00000001L,
+	ISOLATION_MODE_DROP		= 0x00000002L,
+};
+enum qeth_ipa_set_access_mode_rc {
+	SET_ACCESS_CTRL_RC_SUCCESS		= 0x0000,
+	SET_ACCESS_CTRL_RC_NOT_SUPPORTED	= 0x0004,
+	SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED	= 0x0008,
+	SET_ACCESS_CTRL_RC_ALREADY_ISOLATED	= 0x0010,
+	SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER	= 0x0014,
+	SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF	= 0x0018,
+};
+
 
 /* (SET)DELIP(M) IPA stuff ***************************************************/
 struct qeth_ipacmd_setdelip4 {
@@ -376,6 +391,11 @@ struct qeth_snmp_ureq {
 	struct qeth_snmp_cmd cmd;
 } __attribute__((packed));
 
+/* SET_ACCESS_CONTROL: same format for request and reply */
+struct qeth_set_access_ctrl {
+	__u32 subcmd_code;
+} __attribute__((packed));
+
 struct qeth_ipacmd_setadpparms_hdr {
 	__u32 supp_hw_cmds;
 	__u32 reserved1;
@@ -394,6 +414,7 @@ struct qeth_ipacmd_setadpparms {
 		struct qeth_query_cmds_supp query_cmds_supp;
 		struct qeth_change_addr change_addr;
 		struct qeth_snmp_cmd snmp;
+		struct qeth_set_access_ctrl set_access_ctrl;
 		__u32 mode;
 	} data;
 } __attribute__ ((packed));
@@ -507,7 +528,7 @@ extern unsigned char ULP_ENABLE[];
 		(PDU_ENCAPSULATION(buffer) + 0x17)
 #define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
 		(PDU_ENCAPSULATION(buffer) + 0x2b)
-/* Layer 2 defintions */
+/* Layer 2 definitions */
 #define QETH_PROT_LAYER2 0x08
 #define QETH_PROT_TCPIP  0x03
 #define QETH_PROT_OSN2   0x0a
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_sys.c linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_sys.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_core_sys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_core_sys.c	2010-02-24 13:52:17.000000000 -0500
@@ -416,7 +416,11 @@ static ssize_t qeth_dev_layer2_store(str
 static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
 		   qeth_dev_layer2_store);
 
-static ssize_t qeth_dev_large_send_show(struct device *dev,
+#define ATTR_QETH_ISOLATION_NONE	("none")
+#define ATTR_QETH_ISOLATION_FWD		("forward")
+#define ATTR_QETH_ISOLATION_DROP	("drop")
+
+static ssize_t qeth_dev_isolation_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev_get_drvdata(dev);
@@ -424,44 +428,69 @@ static ssize_t qeth_dev_large_send_show(
 	if (!card)
 		return -EINVAL;
 
-	switch (card->options.large_send) {
-	case QETH_LARGE_SEND_NO:
-		return sprintf(buf, "%s\n", "no");
-	case QETH_LARGE_SEND_TSO:
-		return sprintf(buf, "%s\n", "TSO");
+	switch (card->options.isolation) {
+	case ISOLATION_MODE_NONE:
+		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_NONE);
+	case ISOLATION_MODE_FWD:
+		return snprintf(buf, 9, "%s\n", ATTR_QETH_ISOLATION_FWD);
+	case ISOLATION_MODE_DROP:
+		return snprintf(buf, 6, "%s\n", ATTR_QETH_ISOLATION_DROP);
 	default:
-		return sprintf(buf, "%s\n", "N/A");
+		return snprintf(buf, 5, "%s\n", "N/A");
 	}
 }
 
-static ssize_t qeth_dev_large_send_store(struct device *dev,
+static ssize_t qeth_dev_isolation_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev_get_drvdata(dev);
-	enum qeth_large_send_types type;
+	enum qeth_ipa_isolation_modes isolation;
 	int rc = 0;
-	char *tmp;
+	char *tmp, *curtoken;
+	curtoken = (char *) buf;
 
-	if (!card)
-		return -EINVAL;
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "no")) {
-		type = QETH_LARGE_SEND_NO;
-	} else if (!strcmp(tmp, "TSO")) {
-		type = QETH_LARGE_SEND_TSO;
+	if (!card) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* check for unknown, too, in case we do not yet know who we are */
+	if (card->info.type != QETH_CARD_TYPE_OSAE &&
+	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
+		rc = -EOPNOTSUPP;
+		dev_err(&card->gdev->dev, "Adapter does not "
+			"support QDIO data connection isolation\n");
+		goto out;
+	}
+
+	/* parse input into isolation mode */
+	tmp = strsep(&curtoken, "\n");
+	if (!strcmp(tmp, ATTR_QETH_ISOLATION_NONE)) {
+		isolation = ISOLATION_MODE_NONE;
+	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_FWD)) {
+		isolation = ISOLATION_MODE_FWD;
+	} else if (!strcmp(tmp, ATTR_QETH_ISOLATION_DROP)) {
+		isolation = ISOLATION_MODE_DROP;
 	} else {
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
-	if (card->options.large_send == type)
-		return count;
-	rc = qeth_set_large_send(card, type);
-	if (rc)
-		return rc;
-	return count;
+	rc = count;
+
+	/* defer IP assist if device is offline (until discipline->set_online)*/
+	card->options.isolation = isolation;
+	if (card->state == CARD_STATE_SOFTSETUP ||
+	    card->state == CARD_STATE_UP) {
+		int ipa_rc = qeth_set_access_ctrl_online(card);
+		if (ipa_rc != 0)
+			rc = ipa_rc;
+	}
+out:
+	return rc;
 }
 
-static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
-		   qeth_dev_large_send_store);
+static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
+		   qeth_dev_isolation_store);
 
 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
 {
@@ -582,7 +611,7 @@ static struct attribute *qeth_device_att
 	&dev_attr_recover.attr,
 	&dev_attr_performance_stats.attr,
 	&dev_attr_layer2.attr,
-	&dev_attr_large_send.attr,
+	&dev_attr_isolation.attr,
 	NULL,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l2_main.c linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l2_main.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l2_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l2_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -866,7 +866,7 @@ static const struct ethtool_ops qeth_l2_
 	.get_link = ethtool_op_get_link,
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
-	.get_stats_count = qeth_core_get_stats_count,
+	.get_sset_count = qeth_core_get_sset_count,
 	.get_drvinfo = qeth_core_get_drvinfo,
 	.get_settings = qeth_core_ethtool_get_settings,
 };
@@ -874,7 +874,7 @@ static const struct ethtool_ops qeth_l2_
 static const struct ethtool_ops qeth_l2_osn_ops = {
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
-	.get_stats_count = qeth_core_get_stats_count,
+	.get_sset_count = qeth_core_get_sset_count,
 	.get_drvinfo = qeth_core_get_drvinfo,
 };
 
@@ -940,30 +940,17 @@ static int __qeth_l2_set_online(struct c
 
 	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
 	recover_flag = card->state;
-	rc = ccw_device_set_online(CARD_RDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-	rc = ccw_device_set_online(CARD_WDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-	rc = ccw_device_set_online(CARD_DDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-
 	rc = qeth_core_hardsetup_card(card);
 	if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
+		rc = -ENODEV;
 		goto out_remove;
 	}
 
-	if (!card->dev && qeth_l2_setup_netdev(card))
+	if (!card->dev && qeth_l2_setup_netdev(card)) {
+		rc = -ENODEV;
 		goto out_remove;
+	}
 
 	if (card->info.type != QETH_CARD_TYPE_OSN)
 		qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
@@ -983,12 +970,14 @@ static int __qeth_l2_set_online(struct c
 			card->lan_online = 0;
 			return 0;
 		}
+		rc = -ENODEV;
 		goto out_remove;
 	} else
 		card->lan_online = 1;
 
 	if (card->info.type != QETH_CARD_TYPE_OSN) {
-		qeth_set_large_send(card, card->options.large_send);
+		/* configure isolation level */
+		qeth_set_access_ctrl_online(card);
 		qeth_l2_process_vlans(card, 0);
 	}
 
@@ -997,6 +986,7 @@ static int __qeth_l2_set_online(struct c
 	rc = qeth_init_qdio_queues(card);
 	if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
+		rc = -ENODEV;
 		goto out_remove;
 	}
 	card->state = CARD_STATE_SOFTSETUP;
@@ -1018,6 +1008,7 @@ static int __qeth_l2_set_online(struct c
 	/* let user_space know that device is online */
 	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
 	return 0;
+
 out_remove:
 	card->use_hard_stop = 1;
 	qeth_l2_stop_card(card, 0);
@@ -1028,7 +1019,7 @@ out_remove:
 		card->state = CARD_STATE_RECOVER;
 	else
 		card->state = CARD_STATE_DOWN;
-	return -ENODEV;
+	return rc;
 }
 
 static int qeth_l2_set_online(struct ccwgroup_device *gdev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3.h linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3.h
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3.h	2010-02-24 13:52:17.000000000 -0500
@@ -60,5 +60,7 @@ void qeth_l3_del_vipa(struct qeth_card *
 int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
 void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
 			const u8 *);
+int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
+int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
 
 #endif /* __QETH_L3_H__ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3_main.c linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_main.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -41,6 +41,32 @@ static int qeth_l3_deregister_addr_entry
 static int __qeth_l3_set_online(struct ccwgroup_device *, int);
 static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
 
+int qeth_l3_set_large_send(struct qeth_card *card,
+		enum qeth_large_send_types type)
+{
+	int rc = 0;
+
+	card->options.large_send = type;
+	if (card->dev == NULL)
+		return 0;
+
+	if (card->options.large_send == QETH_LARGE_SEND_TSO) {
+		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
+			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
+					NETIF_F_HW_CSUM;
+		} else {
+			card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
+					NETIF_F_HW_CSUM);
+			card->options.large_send = QETH_LARGE_SEND_NO;
+			rc = -EOPNOTSUPP;
+		}
+	} else {
+		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
+					NETIF_F_HW_CSUM);
+		card->options.large_send = QETH_LARGE_SEND_NO;
+	}
+	return rc;
+}
 
 static int qeth_l3_isxdigit(char *buf)
 {
@@ -1439,6 +1465,35 @@ static int qeth_l3_send_checksum_command
 	return 0;
 }
 
+int qeth_l3_set_rx_csum(struct qeth_card *card,
+	enum qeth_checksum_types csum_type)
+{
+	int rc = 0;
+
+	if (card->options.checksum_type == HW_CHECKSUMMING) {
+		if ((csum_type != HW_CHECKSUMMING) &&
+			(card->state != CARD_STATE_DOWN)) {
+			rc = qeth_l3_send_simple_setassparms(card,
+				IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
+			if (rc)
+				return -EIO;
+		}
+	} else {
+		if (csum_type == HW_CHECKSUMMING) {
+			if (card->state != CARD_STATE_DOWN) {
+				if (!qeth_is_supported(card,
+				    IPA_INBOUND_CHECKSUM))
+					return -EPERM;
+				rc = qeth_l3_send_checksum_command(card);
+				if (rc)
+					return -EIO;
+			}
+		}
+	}
+	card->options.checksum_type = csum_type;
+	return rc;
+}
+
 static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
 {
 	int rc = 0;
@@ -1506,6 +1561,8 @@ static int qeth_l3_start_ipa_tso(struct
 static int qeth_l3_start_ipassists(struct qeth_card *card)
 {
 	QETH_DBF_TEXT(TRACE, 3, "strtipas");
+
+	qeth_set_access_ctrl_online(card);	/* go on*/
 	qeth_l3_start_ipa_arp_processing(card);	/* go on*/
 	qeth_l3_start_ipa_ip_fragmentation(card);	/* go on*/
 	qeth_l3_start_ipa_source_mac(card);	/* go on*/
@@ -2684,6 +2741,24 @@ static void qeth_tx_csum(struct sk_buff
 	*(__sum16 *)(skb->data + offset) = csum_fold(csum);
 }
 
+static inline int qeth_l3_tso_elements(struct sk_buff *skb)
+{
+	unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
+		tcp_hdr(skb)->doff * 4;
+	int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
+	int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
+	elements += skb_shinfo(skb)->nr_frags;
+	return elements;
+}
+
+static inline int qeth_l3_tso_check(struct sk_buff *skb)
+{
+	int len = ((unsigned long)tcp_hdr(skb) + tcp_hdr(skb)->doff * 4) -
+		(unsigned long)skb->data;
+	return (((unsigned long)skb->data & PAGE_MASK) !=
+		(((unsigned long)skb->data + len) & PAGE_MASK));
+}
+
 static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	int rc;
@@ -2777,16 +2852,21 @@ static int qeth_l3_hard_start_xmit(struc
 	/* fix hardware limitation: as long as we do not have sbal
 	 * chaining we can not send long frag lists
 	 */
-	if ((large_send == QETH_LARGE_SEND_TSO) &&
-	    ((skb_shinfo(new_skb)->nr_frags + 2) > 16)) {
-		if (skb_linearize(new_skb))
-			goto tx_drop;
+	if (large_send == QETH_LARGE_SEND_TSO) {
+		if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
+			if (skb_linearize(new_skb))
+				goto tx_drop;
+			if (card->options.performance_stats)
+				card->perf_stats.tx_lin++;
+		}
 	}
 
 	if ((large_send == QETH_LARGE_SEND_TSO) &&
 	    (cast_type == RTN_UNSPEC)) {
 		hdr = (struct qeth_hdr *)skb_push(new_skb,
 						sizeof(struct qeth_hdr_tso));
+		if (qeth_l3_tso_check(new_skb))
+			QETH_DBF_MESSAGE(2, "tso skb misaligned\n");
 		memset(hdr, 0, sizeof(struct qeth_hdr_tso));
 		qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type);
 		qeth_tso_fill_header(card, hdr, new_skb);
@@ -2903,46 +2983,28 @@ static u32 qeth_l3_ethtool_get_rx_csum(s
 static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
 {
 	struct qeth_card *card = dev->ml_priv;
-	enum qeth_card_states old_state;
 	enum qeth_checksum_types csum_type;
 
-	if ((card->state != CARD_STATE_UP) &&
-	    (card->state != CARD_STATE_DOWN))
-		return -EPERM;
-
 	if (data)
 		csum_type = HW_CHECKSUMMING;
 	else
 		csum_type = SW_CHECKSUMMING;
 
-	if (card->options.checksum_type != csum_type) {
-		old_state = card->state;
-		if (card->state == CARD_STATE_UP)
-			__qeth_l3_set_offline(card->gdev, 1);
-		card->options.checksum_type = csum_type;
-		if (old_state == CARD_STATE_UP)
-			__qeth_l3_set_online(card->gdev, 1);
-	}
-	return 0;
+	return qeth_l3_set_rx_csum(card, csum_type);
 }
 
 static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
 {
 	struct qeth_card *card = dev->ml_priv;
+	int rc = 0;
 
 	if (data) {
-		if (card->options.large_send == QETH_LARGE_SEND_NO) {
-			if (card->info.type == QETH_CARD_TYPE_IQD)
-				return -EPERM;
-			else
-				card->options.large_send = QETH_LARGE_SEND_TSO;
-			dev->features |= NETIF_F_TSO;
-		}
+		rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
 	} else {
 		dev->features &= ~NETIF_F_TSO;
 		card->options.large_send = QETH_LARGE_SEND_NO;
 	}
-	return 0;
+	return rc;
 }
 
 static const struct ethtool_ops qeth_l3_ethtool_ops = {
@@ -2957,7 +3019,7 @@ static const struct ethtool_ops qeth_l3_
 	.set_tso     = qeth_l3_ethtool_set_tso,
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
-	.get_stats_count = qeth_core_get_stats_count,
+	.get_sset_count = qeth_core_get_sset_count,
 	.get_drvinfo = qeth_core_get_drvinfo,
 	.get_settings = qeth_core_ethtool_get_settings,
 };
@@ -3058,6 +3120,7 @@ static int qeth_l3_setup_netdev(struct q
 				NETIF_F_HW_VLAN_RX |
 				NETIF_F_HW_VLAN_FILTER;
 	card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+	card->dev->gso_max_size = 15 * PAGE_SIZE;
 
 	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
 	return register_netdev(card->dev);
@@ -3154,32 +3217,19 @@ static int __qeth_l3_set_online(struct c
 	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
 
 	recover_flag = card->state;
-	rc = ccw_device_set_online(CARD_RDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-	rc = ccw_device_set_online(CARD_WDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-	rc = ccw_device_set_online(CARD_DDEV(card));
-	if (rc) {
-		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
-		return -EIO;
-	}
-
 	rc = qeth_core_hardsetup_card(card);
 	if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
+		rc = -ENODEV;
 		goto out_remove;
 	}
 
 	qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
 
-	if (!card->dev && qeth_l3_setup_netdev(card))
+	if (!card->dev && qeth_l3_setup_netdev(card)) {
+		rc = -ENODEV;
 		goto out_remove;
+	}
 
 	card->state = CARD_STATE_HARDSETUP;
 	qeth_print_status_message(card);
@@ -3196,10 +3246,11 @@ static int __qeth_l3_set_online(struct c
 			card->lan_online = 0;
 			return 0;
 		}
+		rc = -ENODEV;
 		goto out_remove;
 	} else
 		card->lan_online = 1;
-	qeth_set_large_send(card, card->options.large_send);
+	qeth_l3_set_large_send(card, card->options.large_send);
 
 	rc = qeth_l3_setadapter_parms(card);
 	if (rc)
@@ -3218,6 +3269,7 @@ static int __qeth_l3_set_online(struct c
 	rc = qeth_init_qdio_queues(card);
 	if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
+		rc = -ENODEV;
 		goto out_remove;
 	}
 	card->state = CARD_STATE_SOFTSETUP;
@@ -3248,7 +3300,7 @@ out_remove:
 		card->state = CARD_STATE_RECOVER;
 	else
 		card->state = CARD_STATE_DOWN;
-	return -ENODEV;
+	return rc;
 }
 
 static int qeth_l3_set_online(struct ccwgroup_device *gdev)
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3_sys.c linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_sys.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/qeth_l3_sys.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/qeth_l3_sys.c	2010-02-24 13:52:17.000000000 -0500
@@ -293,31 +293,79 @@ static ssize_t qeth_l3_dev_checksum_stor
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev_get_drvdata(dev);
+	enum qeth_checksum_types csum_type;
 	char *tmp;
+	int rc;
 
 	if (!card)
 		return -EINVAL;
 
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
 	tmp = strsep((char **) &buf, "\n");
 	if (!strcmp(tmp, "sw_checksumming"))
-		card->options.checksum_type = SW_CHECKSUMMING;
+		csum_type = SW_CHECKSUMMING;
 	else if (!strcmp(tmp, "hw_checksumming"))
-		card->options.checksum_type = HW_CHECKSUMMING;
+		csum_type = HW_CHECKSUMMING;
 	else if (!strcmp(tmp, "no_checksumming"))
-		card->options.checksum_type = NO_CHECKSUMMING;
-	else {
+		csum_type = NO_CHECKSUMMING;
+	else
 		return -EINVAL;
-	}
+
+	rc = qeth_l3_set_rx_csum(card, csum_type);
+	if (rc)
+		return rc;
 	return count;
 }
 
 static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
 		qeth_l3_dev_checksum_store);
 
+static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+
+	if (!card)
+		return -EINVAL;
+
+	switch (card->options.large_send) {
+	case QETH_LARGE_SEND_NO:
+		return sprintf(buf, "%s\n", "no");
+	case QETH_LARGE_SEND_TSO:
+		return sprintf(buf, "%s\n", "TSO");
+	default:
+		return sprintf(buf, "%s\n", "N/A");
+	}
+}
+
+static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+	enum qeth_large_send_types type;
+	int rc = 0;
+	char *tmp;
+
+	if (!card)
+		return -EINVAL;
+	tmp = strsep((char **) &buf, "\n");
+	if (!strcmp(tmp, "no"))
+		type = QETH_LARGE_SEND_NO;
+	else if (!strcmp(tmp, "TSO"))
+		type = QETH_LARGE_SEND_TSO;
+	else
+		return -EINVAL;
+
+	if (card->options.large_send == type)
+		return count;
+	rc = qeth_l3_set_large_send(card, type);
+	if (rc)
+		return rc;
+	return count;
+}
+
+static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
+		   qeth_l3_dev_large_send_store);
+
 static struct attribute *qeth_l3_device_attrs[] = {
 	&dev_attr_route4.attr,
 	&dev_attr_route6.attr,
@@ -325,6 +373,7 @@ static struct attribute *qeth_l3_device_
 	&dev_attr_broadcast_mode.attr,
 	&dev_attr_canonical_macaddr.attr,
 	&dev_attr_checksumming.attr,
+	&dev_attr_large_send.attr,
 	NULL,
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/net/smsgiucv.c linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.c
--- linux-libre-2.6.32-gnu1/drivers/s390/net/smsgiucv.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/net/smsgiucv.c	2010-02-24 13:52:17.000000000 -0500
@@ -168,7 +168,7 @@ static int smsg_pm_restore_thaw(struct d
 	return 0;
 }
 
-static struct dev_pm_ops smsg_pm_ops = {
+static const struct dev_pm_ops smsg_pm_ops = {
 	.freeze = smsg_pm_freeze,
 	.thaw = smsg_pm_restore_thaw,
 	.restore = smsg_pm_restore_thaw,
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_aux.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_aux.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_aux.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_aux.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <linux/miscdevice.h>
 #include <linux/seq_file.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
 #define ZFCP_BUS_ID_SIZE	20
 
@@ -80,48 +81,40 @@ int zfcp_reqlist_isempty(struct zfcp_ada
 
 static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 {
-	struct ccw_device *ccwdev;
+	struct ccw_device *cdev;
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
 
-	ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
-	if (!ccwdev)
+	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
+	if (!cdev)
 		return;
 
-	if (ccw_device_set_online(ccwdev))
-		goto out_ccwdev;
+	if (ccw_device_set_online(cdev))
+		goto out_ccw_device;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccwdev->dev);
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	if (!adapter)
-		goto out_unlock;
-	zfcp_adapter_get(adapter);
+		goto out_ccw_device;
 
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
 	if (!port)
 		goto out_port;
 
-	zfcp_port_get(port);
 	unit = zfcp_unit_enqueue(port, lun);
 	if (IS_ERR(unit))
 		goto out_unit;
-	mutex_unlock(&zfcp_data.config_mutex);
 
 	zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
 	zfcp_erp_wait(adapter);
 	flush_work(&unit->scsi_work);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	zfcp_unit_put(unit);
 out_unit:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 out_port:
-	zfcp_adapter_put(adapter);
-out_unlock:
-	mutex_unlock(&zfcp_data.config_mutex);
-out_ccwdev:
-	put_device(&ccwdev->dev);
+	zfcp_ccw_adapter_put(adapter);
+out_ccw_device:
+	put_device(&cdev->dev);
 	return;
 }
 
@@ -167,7 +160,7 @@ static int __init zfcp_module_init(void)
 	int retval = -ENOMEM;
 
 	zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn",
-					sizeof(struct ct_iu_gpn_ft_req));
+					sizeof(struct zfcp_fc_gpn_ft_req));
 	if (!zfcp_data.gpn_ft_cache)
 		goto out;
 
@@ -182,12 +175,14 @@ static int __init zfcp_module_init(void)
 		goto out_sr_cache;
 
 	zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid",
-					sizeof(struct zfcp_gid_pn_data));
+					sizeof(struct zfcp_fc_gid_pn));
 	if (!zfcp_data.gid_pn_cache)
 		goto out_gid_cache;
 
-	mutex_init(&zfcp_data.config_mutex);
-	rwlock_init(&zfcp_data.config_lock);
+	zfcp_data.adisc_cache = zfcp_cache_hw_align("zfcp_adisc",
+					sizeof(struct zfcp_fc_els_adisc));
+	if (!zfcp_data.adisc_cache)
+		goto out_adisc_cache;
 
 	zfcp_data.scsi_transport_template =
 		fc_attach_transport(&zfcp_transport_functions);
@@ -200,7 +195,7 @@ static int __init zfcp_module_init(void)
 		goto out_misc;
 	}
 
-	retval = zfcp_ccw_register();
+	retval = ccw_driver_register(&zfcp_ccw_driver);
 	if (retval) {
 		pr_err("The zfcp device driver could not register with "
 		       "the common I/O layer\n");
@@ -216,6 +211,8 @@ out_ccw_register:
 out_misc:
 	fc_release_transport(zfcp_data.scsi_transport_template);
 out_transport:
+	kmem_cache_destroy(zfcp_data.adisc_cache);
+out_adisc_cache:
 	kmem_cache_destroy(zfcp_data.gid_pn_cache);
 out_gid_cache:
 	kmem_cache_destroy(zfcp_data.sr_buffer_cache);
@@ -229,6 +226,20 @@ out:
 
 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_data.scsi_transport_template);
+	kmem_cache_destroy(zfcp_data.adisc_cache);
+	kmem_cache_destroy(zfcp_data.gid_pn_cache);
+	kmem_cache_destroy(zfcp_data.sr_buffer_cache);
+	kmem_cache_destroy(zfcp_data.qtcb_cache);
+	kmem_cache_destroy(zfcp_data.gpn_ft_cache);
+}
+
+module_exit(zfcp_module_exit);
+
 /**
  * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN
  * @port: pointer to port to search for unit
@@ -238,12 +249,18 @@ module_init(zfcp_module_init);
  */
 struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
 {
+	unsigned long flags;
 	struct zfcp_unit *unit;
 
-	list_for_each_entry(unit, &port->unit_list_head, list)
-		if ((unit->fcp_lun == fcp_lun) &&
-		    !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE))
-		    return unit;
+	read_lock_irqsave(&port->unit_list_lock, flags);
+	list_for_each_entry(unit, &port->unit_list, list)
+		if (unit->fcp_lun == fcp_lun) {
+			if (!get_device(&unit->sysfs_device))
+				unit = NULL;
+			read_unlock_irqrestore(&port->unit_list_lock, flags);
+			return unit;
+		}
+	read_unlock_irqrestore(&port->unit_list_lock, flags);
 	return NULL;
 }
 
@@ -257,18 +274,35 @@ struct zfcp_unit *zfcp_get_unit_by_lun(s
 struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
 					u64 wwpn)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if ((port->wwpn == wwpn) &&
-		    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE))
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
+		if (port->wwpn == wwpn) {
+			if (!get_device(&port->sysfs_device))
+				port = NULL;
+			read_unlock_irqrestore(&adapter->port_list_lock, flags);
 			return port;
+		}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 	return NULL;
 }
 
-static void zfcp_sysfs_unit_release(struct device *dev)
+/**
+ * zfcp_unit_release - dequeue unit
+ * @dev: pointer to device
+ *
+ * waits until all work is done on unit and removes it then from the unit->list
+ * of the associated port.
+ */
+static void zfcp_unit_release(struct device *dev)
 {
-	kfree(container_of(dev, struct zfcp_unit, sysfs_device));
+	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit,
+					      sysfs_device);
+
+	put_device(&unit->port->sysfs_device);
+	kfree(unit);
 }
 
 /**
@@ -276,43 +310,40 @@ static void zfcp_sysfs_unit_release(stru
  * @port: pointer to port where unit is added
  * @fcp_lun: FCP LUN of unit to be enqueued
  * Returns: pointer to enqueued unit on success, ERR_PTR on error
- * Locks: config_mutex must be held to serialize changes to the unit list
  *
  * Sets up some unit internal structures and creates sysfs entry.
  */
 struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 {
 	struct zfcp_unit *unit;
+	int retval = -ENOMEM;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_unit_by_lun(port, fcp_lun)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		return ERR_PTR(-EINVAL);
+	get_device(&port->sysfs_device);
+
+	unit = zfcp_get_unit_by_lun(port, fcp_lun);
+	if (unit) {
+		put_device(&unit->sysfs_device);
+		retval = -EEXIST;
+		goto err_out;
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
 
 	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
 	if (!unit)
-		return ERR_PTR(-ENOMEM);
-
-	atomic_set(&unit->refcount, 0);
-	init_waitqueue_head(&unit->remove_wq);
-	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
+		goto err_out;
 
 	unit->port = port;
 	unit->fcp_lun = fcp_lun;
+	unit->sysfs_device.parent = &port->sysfs_device;
+	unit->sysfs_device.release = zfcp_unit_release;
 
 	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
 			 (unsigned long long) fcp_lun)) {
 		kfree(unit);
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
 	}
-	unit->sysfs_device.parent = &port->sysfs_device;
-	unit->sysfs_device.release = zfcp_sysfs_unit_release;
-	dev_set_drvdata(&unit->sysfs_device, unit);
+	retval = -EINVAL;
 
-	/* mark unit unusable as long as sysfs registration is not complete */
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
+	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
 
 	spin_lock_init(&unit->latencies.lock);
 	unit->latencies.write.channel.min = 0xFFFFFFFF;
@@ -324,50 +355,30 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
 
 	if (device_register(&unit->sysfs_device)) {
 		put_device(&unit->sysfs_device);
-		return ERR_PTR(-EINVAL);
+		goto err_out;
 	}
 
 	if (sysfs_create_group(&unit->sysfs_device.kobj,
-			       &zfcp_sysfs_unit_attrs)) {
-		device_unregister(&unit->sysfs_device);
-		return ERR_PTR(-EINVAL);
-	}
+			       &zfcp_sysfs_unit_attrs))
+		goto err_out_put;
 
-	zfcp_unit_get(unit);
+	write_lock_irq(&port->unit_list_lock);
+	list_add_tail(&unit->list, &port->unit_list);
+	write_unlock_irq(&port->unit_list_lock);
 
-	write_lock_irq(&zfcp_data.config_lock);
-	list_add_tail(&unit->list, &port->unit_list_head);
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
 	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
 
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	zfcp_port_get(port);
-
 	return unit;
-}
 
-/**
- * zfcp_unit_dequeue - dequeue unit
- * @unit: pointer to zfcp_unit
- *
- * waits until all work is done on unit and removes it then from the unit->list
- * of the associated port.
- */
-void zfcp_unit_dequeue(struct zfcp_unit *unit)
-{
-	wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
-	write_lock_irq(&zfcp_data.config_lock);
-	list_del(&unit->list);
-	write_unlock_irq(&zfcp_data.config_lock);
-	zfcp_port_put(unit->port);
-	sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
+err_out_put:
 	device_unregister(&unit->sysfs_device);
+err_out:
+	put_device(&port->sysfs_device);
+	return ERR_PTR(retval);
 }
 
 static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* must only be called with zfcp_data.config_mutex taken */
 	adapter->pool.erp_req =
 		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
 	if (!adapter->pool.erp_req)
@@ -405,9 +416,9 @@ static int zfcp_allocate_low_mem_buffers
 	if (!adapter->pool.status_read_data)
 		return -ENOMEM;
 
-	adapter->pool.gid_pn_data =
+	adapter->pool.gid_pn =
 		mempool_create_slab_pool(1, zfcp_data.gid_pn_cache);
-	if (!adapter->pool.gid_pn_data)
+	if (!adapter->pool.gid_pn)
 		return -ENOMEM;
 
 	return 0;
@@ -415,7 +426,6 @@ static int zfcp_allocate_low_mem_buffers
 
 static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* zfcp_data.config_mutex must be held */
 	if (adapter->pool.erp_req)
 		mempool_destroy(adapter->pool.erp_req);
 	if (adapter->pool.scsi_req)
@@ -428,8 +438,8 @@ static void zfcp_free_low_mem_buffers(st
 		mempool_destroy(adapter->pool.status_read_req);
 	if (adapter->pool.status_read_data)
 		mempool_destroy(adapter->pool.status_read_data);
-	if (adapter->pool.gid_pn_data)
-		mempool_destroy(adapter->pool.gid_pn_data);
+	if (adapter->pool.gid_pn)
+		mempool_destroy(adapter->pool.gid_pn);
 }
 
 /**
@@ -497,53 +507,56 @@ static void zfcp_destroy_adapter_work_qu
  * zfcp_adapter_enqueue - enqueue a new adapter to the list
  * @ccw_device: pointer to the struct cc_device
  *
- * Returns:	0             if a new adapter was successfully enqueued
- *		-ENOMEM       if alloc failed
+ * Returns:	struct zfcp_adapter*
  * Enqueues an adapter at the end of the adapter list in the driver data.
  * All adapter internal structures are set up.
  * Proc-fs entries are also created.
- * locks: config_mutex must be held to serialize changes to the adapter list
  */
-int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
+struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 {
 	struct zfcp_adapter *adapter;
 
-	/*
-	 * Note: It is safe to release the list_lock, as any list changes
-	 * are protected by the config_mutex, which must be held to get here
-	 */
+	if (!get_device(&ccw_device->dev))
+		return ERR_PTR(-ENODEV);
 
 	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
-	if (!adapter)
-		return -ENOMEM;
+	if (!adapter) {
+		put_device(&ccw_device->dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	kref_init(&adapter->ref);
 
 	ccw_device->handler = NULL;
 	adapter->ccw_device = ccw_device;
-	atomic_set(&adapter->refcount, 0);
+
+	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
+	INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
 
 	if (zfcp_qdio_setup(adapter))
-		goto qdio_failed;
+		goto failed;
 
 	if (zfcp_allocate_low_mem_buffers(adapter))
-		goto low_mem_buffers_failed;
+		goto failed;
 
 	if (zfcp_reqlist_alloc(adapter))
-		goto low_mem_buffers_failed;
+		goto failed;
 
 	if (zfcp_dbf_adapter_register(adapter))
-		goto debug_register_failed;
+		goto failed;
 
 	if (zfcp_setup_adapter_work_queue(adapter))
-		goto work_queue_failed;
+		goto failed;
 
 	if (zfcp_fc_gs_setup(adapter))
-		goto generic_services_failed;
+		goto failed;
+
+	rwlock_init(&adapter->port_list_lock);
+	INIT_LIST_HEAD(&adapter->port_list);
 
-	init_waitqueue_head(&adapter->remove_wq);
 	init_waitqueue_head(&adapter->erp_ready_wq);
 	init_waitqueue_head(&adapter->erp_done_wqh);
 
-	INIT_LIST_HEAD(&adapter->port_list_head);
 	INIT_LIST_HEAD(&adapter->erp_ready_head);
 	INIT_LIST_HEAD(&adapter->erp_running_head);
 
@@ -553,83 +566,85 @@ int zfcp_adapter_enqueue(struct ccw_devi
 	rwlock_init(&adapter->abort_lock);
 
 	if (zfcp_erp_thread_setup(adapter))
-		goto erp_thread_failed;
-
-	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
-	INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
+		goto failed;
 
 	adapter->service_level.seq_print = zfcp_print_sl;
 
-	/* mark adapter unusable as long as sysfs registration is not complete */
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-
 	dev_set_drvdata(&ccw_device->dev, adapter);
 
 	if (sysfs_create_group(&ccw_device->dev.kobj,
 			       &zfcp_sysfs_adapter_attrs))
-		goto sysfs_failed;
-
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
+		goto failed;
 
 	if (!zfcp_adapter_scsi_register(adapter))
-		return 0;
+		return adapter;
 
-sysfs_failed:
-	zfcp_erp_thread_kill(adapter);
-erp_thread_failed:
-	zfcp_fc_gs_destroy(adapter);
-generic_services_failed:
+failed:
+	zfcp_adapter_unregister(adapter);
+	return ERR_PTR(-ENOMEM);
+}
+
+void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
+{
+	struct ccw_device *cdev = adapter->ccw_device;
+
+	cancel_work_sync(&adapter->scan_work);
+	cancel_work_sync(&adapter->stat_work);
 	zfcp_destroy_adapter_work_queue(adapter);
-work_queue_failed:
+
+	zfcp_fc_wka_ports_force_offline(adapter->gs);
+	zfcp_adapter_scsi_unregister(adapter);
+	sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
+
+	zfcp_erp_thread_kill(adapter);
 	zfcp_dbf_adapter_unregister(adapter->dbf);
-debug_register_failed:
-	dev_set_drvdata(&ccw_device->dev, NULL);
-	kfree(adapter->req_list);
-low_mem_buffers_failed:
-	zfcp_free_low_mem_buffers(adapter);
-qdio_failed:
 	zfcp_qdio_destroy(adapter->qdio);
-	kfree(adapter);
-	return -ENOMEM;
+
+	zfcp_ccw_adapter_put(adapter); /* final put to release */
 }
 
 /**
- * zfcp_adapter_dequeue - remove the adapter from the resource list
- * @adapter: pointer to struct zfcp_adapter which should be removed
+ * zfcp_adapter_release - remove the adapter from the resource list
+ * @ref: pointer to struct kref
  * locks:	adapter list write lock is assumed to be held by caller
  */
-void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
+void zfcp_adapter_release(struct kref *ref)
 {
-	int retval = 0;
-	unsigned long flags;
+	struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
+						    ref);
+	struct ccw_device *cdev = adapter->ccw_device;
 
-	cancel_work_sync(&adapter->stat_work);
-	zfcp_fc_wka_ports_force_offline(adapter->gs);
-	sysfs_remove_group(&adapter->ccw_device->dev.kobj,
-			   &zfcp_sysfs_adapter_attrs);
 	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
-	/* sanity check: no pending FSF requests */
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	retval = zfcp_reqlist_isempty(adapter);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-	if (!retval)
-		return;
-
 	zfcp_fc_gs_destroy(adapter);
-	zfcp_erp_thread_kill(adapter);
-	zfcp_destroy_adapter_work_queue(adapter);
-	zfcp_dbf_adapter_unregister(adapter->dbf);
 	zfcp_free_low_mem_buffers(adapter);
-	zfcp_qdio_destroy(adapter->qdio);
 	kfree(adapter->req_list);
 	kfree(adapter->fc_stats);
 	kfree(adapter->stats_reset_data);
 	kfree(adapter);
+	put_device(&cdev->dev);
 }
 
-static void zfcp_sysfs_port_release(struct device *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)
 {
-	kfree(container_of(dev, struct zfcp_port, sysfs_device));
+	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,
+					      sysfs_device);
+
+	zfcp_ccw_adapter_put(port->adapter);
+	kfree(port);
 }
 
 /**
@@ -639,7 +654,6 @@ static void zfcp_sysfs_port_release(stru
  * @status: initial status for the port
  * @d_id: destination id of the remote port to be enqueued
  * Returns: pointer to enqueued port on success, ERR_PTR on error
- * Locks: config_mutex must be held to serialize changes to the port list
  *
  * All port internal structures are set up and the sysfs entry is generated.
  * d_id is used to enqueue ports with a well known address like the Directory
@@ -649,20 +663,24 @@ struct zfcp_port *zfcp_port_enqueue(stru
 				     u32 status, u32 d_id)
 {
 	struct zfcp_port *port;
+	int retval = -ENOMEM;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		return ERR_PTR(-EINVAL);
+	kref_get(&adapter->ref);
+
+	port = zfcp_get_port_by_wwpn(adapter, wwpn);
+	if (port) {
+		put_device(&port->sysfs_device);
+		retval = -EEXIST;
+		goto err_out;
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
 
 	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
 	if (!port)
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
+
+	rwlock_init(&port->unit_list_lock);
+	INIT_LIST_HEAD(&port->unit_list);
 
-	init_waitqueue_head(&port->remove_wq);
-	INIT_LIST_HEAD(&port->unit_list_head);
 	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
 	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
 	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
@@ -671,58 +689,38 @@ struct zfcp_port *zfcp_port_enqueue(stru
 	port->d_id = d_id;
 	port->wwpn = wwpn;
 	port->rport_task = RPORT_NONE;
-
-	/* mark port unusable as long as sysfs registration is not complete */
-	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
-	atomic_set(&port->refcount, 0);
+	port->sysfs_device.parent = &adapter->ccw_device->dev;
+	port->sysfs_device.release = zfcp_port_release;
 
 	if (dev_set_name(&port->sysfs_device, "0x%016llx",
 			 (unsigned long long)wwpn)) {
 		kfree(port);
-		return ERR_PTR(-ENOMEM);
+		goto err_out;
 	}
-	port->sysfs_device.parent = &adapter->ccw_device->dev;
-	port->sysfs_device.release = zfcp_sysfs_port_release;
-	dev_set_drvdata(&port->sysfs_device, port);
+	retval = -EINVAL;
 
 	if (device_register(&port->sysfs_device)) {
 		put_device(&port->sysfs_device);
-		return ERR_PTR(-EINVAL);
+		goto err_out;
 	}
 
 	if (sysfs_create_group(&port->sysfs_device.kobj,
-			       &zfcp_sysfs_port_attrs)) {
-		device_unregister(&port->sysfs_device);
-		return ERR_PTR(-EINVAL);
-	}
-
-	zfcp_port_get(port);
+			       &zfcp_sysfs_port_attrs))
+		goto err_out_put;
 
-	write_lock_irq(&zfcp_data.config_lock);
-	list_add_tail(&port->list, &adapter->port_list_head);
-	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
-	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
+	write_lock_irq(&adapter->port_list_lock);
+	list_add_tail(&port->list, &adapter->port_list);
+	write_unlock_irq(&adapter->port_list_lock);
 
-	write_unlock_irq(&zfcp_data.config_lock);
+	atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);
 
-	zfcp_adapter_get(adapter);
 	return port;
-}
 
-/**
- * zfcp_port_dequeue - dequeues a port from the port list of the adapter
- * @port: pointer to struct zfcp_port which should be removed
- */
-void zfcp_port_dequeue(struct zfcp_port *port)
-{
-	write_lock_irq(&zfcp_data.config_lock);
-	list_del(&port->list);
-	write_unlock_irq(&zfcp_data.config_lock);
-	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
-	cancel_work_sync(&port->rport_work); /* usually not necessary */
-	zfcp_adapter_put(port->adapter);
-	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
+err_out_put:
 	device_unregister(&port->sysfs_device);
+err_out:
+	zfcp_ccw_adapter_put(adapter);
+	return ERR_PTR(retval);
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_ccw.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ccw.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_ccw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ccw.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,28 +13,34 @@
 
 #define ZFCP_MODEL_PRIV 0x4
 
-static int zfcp_ccw_suspend(struct ccw_device *cdev)
+static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
 
+struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
-
-	if (!adapter)
-		return 0;
-
-	mutex_lock(&zfcp_data.config_mutex);
+	struct zfcp_adapter *adapter;
+	unsigned long flags;
 
-	zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
-	zfcp_erp_wait(adapter);
+	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
+	adapter = dev_get_drvdata(&cdev->dev);
+	if (adapter)
+		kref_get(&adapter->ref);
+	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
+	return adapter;
+}
 
-	mutex_unlock(&zfcp_data.config_mutex);
+void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
+{
+	unsigned long flags;
 
-	return 0;
+	spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
+	kref_put(&adapter->ref, zfcp_adapter_release);
+	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
 }
 
 static int zfcp_ccw_activate(struct ccw_device *cdev)
 
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter)
 		return 0;
@@ -46,6 +52,8 @@ static int zfcp_ccw_activate(struct ccw_
 	zfcp_erp_wait(adapter);
 	flush_work(&adapter->scan_work);
 
+	zfcp_ccw_adapter_put(adapter);
+
 	return 0;
 }
 
@@ -67,28 +75,28 @@ int zfcp_ccw_priv_sch(struct zfcp_adapte
 
 /**
  * zfcp_ccw_probe - probe function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer for each FCP
  * device found on the current system. This is only a stub to make cio
  * work: To only allocate adapter resources for devices actually used,
  * the allocation is deferred to the first call to ccw_set_online.
  */
-static int zfcp_ccw_probe(struct ccw_device *ccw_device)
+static int zfcp_ccw_probe(struct ccw_device *cdev)
 {
 	return 0;
 }
 
 /**
  * zfcp_ccw_remove - remove function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and removes an adapter
  * from the system. Task of this function is to get rid of all units and
  * ports that belong to this adapter. And in addition all resources of this
  * adapter will be freed too.
  */
-static void zfcp_ccw_remove(struct ccw_device *ccw_device)
+static void zfcp_ccw_remove(struct ccw_device *cdev)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port, *p;
@@ -96,49 +104,37 @@ static void zfcp_ccw_remove(struct ccw_d
 	LIST_HEAD(unit_remove_lh);
 	LIST_HEAD(port_remove_lh);
 
-	ccw_device_set_offline(ccw_device);
+	ccw_device_set_offline(cdev);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	if (!adapter)
-		goto out;
-	mutex_unlock(&zfcp_data.config_mutex);
-
-	cancel_work_sync(&adapter->scan_work);
-
-	mutex_lock(&zfcp_data.config_mutex);
-
-	/* this also removes the scsi devices, so call it first */
-	zfcp_adapter_scsi_unregister(adapter);
+		return;
 
-	write_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
-		list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
+	write_lock_irq(&adapter->port_list_lock);
+	list_for_each_entry_safe(port, p, &adapter->port_list, list) {
+		write_lock(&port->unit_list_lock);
+		list_for_each_entry_safe(unit, u, &port->unit_list, list)
 			list_move(&unit->list, &unit_remove_lh);
-			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
-					&unit->status);
-		}
+		write_unlock(&port->unit_list_lock);
 		list_move(&port->list, &port_remove_lh);
-		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
 	}
-	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-	write_unlock_irq(&zfcp_data.config_lock);
+	write_unlock_irq(&adapter->port_list_lock);
+	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 
-	list_for_each_entry_safe(port, p, &port_remove_lh, list) {
-		list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
-			zfcp_unit_dequeue(unit);
-		zfcp_port_dequeue(port);
-	}
-	wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
-	zfcp_adapter_dequeue(adapter);
+	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
+		zfcp_device_unregister(&unit->sysfs_device,
+				       &zfcp_sysfs_unit_attrs);
 
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	list_for_each_entry_safe(port, p, &port_remove_lh, list)
+		zfcp_device_unregister(&port->sysfs_device,
+				       &zfcp_sysfs_port_attrs);
+
+	zfcp_adapter_unregister(adapter);
 }
 
 /**
  * zfcp_ccw_set_online - set_online function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an
  * adapter into state online.  The first call will allocate all
@@ -149,23 +145,20 @@ out:
  * the SCSI stack, that the QDIO queues will be set up and that the
  * adapter will be opened.
  */
-static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
+static int zfcp_ccw_set_online(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
-	int ret = 0;
-
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter) {
-		ret = zfcp_adapter_enqueue(ccw_device);
-		if (ret) {
-			dev_err(&ccw_device->dev,
+		adapter = zfcp_adapter_enqueue(cdev);
+
+		if (IS_ERR(adapter)) {
+			dev_err(&cdev->dev,
 				"Setting up data structures for the "
 				"FCP adapter failed\n");
-			goto out;
+			return PTR_ERR(adapter);
 		}
-		adapter = dev_get_drvdata(&ccw_device->dev);
+		kref_get(&adapter->ref);
 	}
 
 	/* initialize request counter */
@@ -177,58 +170,61 @@ static int zfcp_ccw_set_online(struct cc
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 				"ccsonl2", NULL);
 	zfcp_erp_wait(adapter);
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
-	if (!ret)
-		flush_work(&adapter->scan_work);
-	return ret;
+
+	flush_work(&adapter->scan_work);
+
+	zfcp_ccw_adapter_put(adapter);
+	return 0;
 }
 
 /**
  * zfcp_ccw_set_offline - set_offline function of zfcp driver
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  *
  * This function gets called by the common i/o layer and sets an adapter
  * into state offline.
  */
-static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
+static int zfcp_ccw_set_offline(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+
+	if (!adapter)
+		return 0;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&ccw_device->dev);
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
 	zfcp_erp_wait(adapter);
-	mutex_unlock(&zfcp_data.config_mutex);
+
+	zfcp_ccw_adapter_put(adapter);
 	return 0;
 }
 
 /**
  * zfcp_ccw_notify - ccw notify function
- * @ccw_device: pointer to belonging ccw device
+ * @cdev: pointer to belonging ccw device
  * @event: indicates if adapter was detached or attached
  *
  * This function gets called by the common i/o layer if an adapter has gone
  * or reappeared.
  */
-static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
+static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+
+	if (!adapter)
+		return 1;
 
 	switch (event) {
 	case CIO_GONE:
-		dev_warn(&adapter->ccw_device->dev,
-			 "The FCP device has been detached\n");
+		dev_warn(&cdev->dev, "The FCP device has been detached\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
 		break;
 	case CIO_NO_PATH:
-		dev_warn(&adapter->ccw_device->dev,
+		dev_warn(&cdev->dev,
 			 "The CHPID for the FCP device is offline\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
 		break;
 	case CIO_OPER:
-		dev_info(&adapter->ccw_device->dev,
-			 "The FCP device is operational again\n");
+		dev_info(&cdev->dev, "The FCP device is operational again\n");
 		zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_SET);
@@ -236,11 +232,13 @@ static int zfcp_ccw_notify(struct ccw_de
 					"ccnoti4", NULL);
 		break;
 	case CIO_BOXED:
-		dev_warn(&adapter->ccw_device->dev, "The FCP device "
-			 "did not respond within the specified time\n");
+		dev_warn(&cdev->dev, "The FCP device did not respond within "
+				     "the specified time\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
 		break;
 	}
+
+	zfcp_ccw_adapter_put(adapter);
 	return 1;
 }
 
@@ -250,18 +248,16 @@ static int zfcp_ccw_notify(struct ccw_de
  */
 static void zfcp_ccw_shutdown(struct ccw_device *cdev)
 {
-	struct zfcp_adapter *adapter;
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	mutex_lock(&zfcp_data.config_mutex);
-	adapter = dev_get_drvdata(&cdev->dev);
 	if (!adapter)
-		goto out;
+		return;
 
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_thread_kill(adapter);
-out:
-	mutex_unlock(&zfcp_data.config_mutex);
+
+	zfcp_ccw_adapter_put(adapter);
 }
 
 struct ccw_driver zfcp_ccw_driver = {
@@ -274,18 +270,7 @@ struct ccw_driver zfcp_ccw_driver = {
 	.set_offline = zfcp_ccw_set_offline,
 	.notify      = zfcp_ccw_notify,
 	.shutdown    = zfcp_ccw_shutdown,
-	.freeze      = zfcp_ccw_suspend,
+	.freeze      = zfcp_ccw_set_offline,
 	.thaw	     = zfcp_ccw_activate,
 	.restore     = zfcp_ccw_activate,
 };
-
-/**
- * zfcp_ccw_register - ccw register function
- *
- * Registers the driver at the common i/o layer. This function will be called
- * at module load time/system start.
- */
-int __init zfcp_ccw_register(void)
-{
-	return ccw_driver_register(&zfcp_ccw_driver);
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_cfdc.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_cfdc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_cfdc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_cfdc.c	2010-02-24 13:52:17.000000000 -0500
@@ -12,6 +12,7 @@
 
 #include <linux/types.h>
 #include <linux/miscdevice.h>
+#include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include "zfcp_def.h"
 #include "zfcp_ext.h"
@@ -86,22 +87,17 @@ static int zfcp_cfdc_copy_to_user(void _
 static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
 {
 	char busid[9];
-	struct ccw_device *ccwdev;
-	struct zfcp_adapter *adapter = NULL;
+	struct ccw_device *cdev;
+	struct zfcp_adapter *adapter;
 
 	snprintf(busid, sizeof(busid), "0.0.%04x", devno);
-	ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
-	if (!ccwdev)
-		goto out;
+	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
+	if (!cdev)
+		return NULL;
 
-	adapter = dev_get_drvdata(&ccwdev->dev);
-	if (!adapter)
-		goto out_put;
+	adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	zfcp_adapter_get(adapter);
-out_put:
-	put_device(&ccwdev->dev);
-out:
+	put_device(&cdev->dev);
 	return adapter;
 }
 
@@ -168,7 +164,7 @@ static void zfcp_cfdc_req_to_sense(struc
 }
 
 static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
-				unsigned long buffer)
+				unsigned long arg)
 {
 	struct zfcp_cfdc_data *data;
 	struct zfcp_cfdc_data __user *data_user;
@@ -180,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct f
 	if (command != ZFCP_CFDC_IOC)
 		return -ENOTTY;
 
-	data_user = (void __user *) buffer;
+	if (is_compat_task())
+		data_user = compat_ptr(arg);
+	else
+		data_user = (void __user *)arg;
+
 	if (!data_user)
 		return -EINVAL;
 
@@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct f
 		retval = -ENXIO;
 		goto free_buffer;
 	}
-	zfcp_adapter_get(adapter);
 
 	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
 				    data_user->control_file);
@@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct f
  free_sg:
 	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
  adapter_put:
-	zfcp_adapter_put(adapter);
+	zfcp_ccw_adapter_put(adapter);
  free_buffer:
 	kfree(data);
  no_mem_sense:
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_dbf.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_dbf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.c	2010-02-24 13:52:17.000000000 -0500
@@ -13,6 +13,7 @@
 #include <asm/debug.h>
 #include "zfcp_dbf.h"
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
 static u32 dbfsize = 4;
 
@@ -177,8 +178,7 @@ void _zfcp_dbf_hba_fsf_response(const ch
 
 	case FSF_QTCB_SEND_ELS:
 		send_els = (struct zfcp_send_els *)fsf_req->data;
-		response->u.els.d_id = qtcb->bottom.support.d_id;
-		response->u.els.ls_code = send_els->ls_code >> 24;
+		response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id);
 		break;
 
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(c
 			break;
 		zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
 		zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
-		p += sprintf(*p, "\n");
+		*p += sprintf(*p, "\n");
 		break;
 
 	case FSF_QTCB_OPEN_PORT_WITH_DID:
@@ -348,7 +348,6 @@ static void zfcp_dbf_hba_view_response(c
 
 	case FSF_QTCB_SEND_ELS:
 		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
-		zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code);
 		break;
 
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -677,14 +676,14 @@ void zfcp_dbf_rec_action(char *id2, stru
 /**
  * zfcp_dbf_san_ct_request - trace event for issued CT request
  * @fsf_req: request containing issued CT data
+ * @d_id: destination id where ct request is sent to
  */
-void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id)
 {
-	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-	struct zfcp_wka_port *wka_port = ct->wka_port;
-	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_dbf *dbf = adapter->dbf;
-	struct ct_hdr *hdr = sg_virt(ct->req);
+	struct fc_ct_hdr *hdr = sg_virt(ct->req);
 	struct zfcp_dbf_san_record *r = &dbf->san_buf;
 	struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
 	int level = 3;
@@ -695,19 +694,18 @@ void zfcp_dbf_san_ct_request(struct zfcp
 	strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
 	r->fsf_seqno = fsf_req->seq_no;
-	r->s_id = fc_host_port_id(adapter->scsi_host);
-	r->d_id = wka_port->d_id;
-	oct->cmd_req_code = hdr->cmd_rsp_code;
-	oct->revision = hdr->revision;
-	oct->gs_type = hdr->gs_type;
-	oct->gs_subtype = hdr->gs_subtype;
-	oct->options = hdr->options;
-	oct->max_res_size = hdr->max_res_size;
-	oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
+	oct->d_id = d_id;
+	oct->cmd_req_code = hdr->ct_cmd;
+	oct->revision = hdr->ct_rev;
+	oct->gs_type = hdr->ct_fs_type;
+	oct->gs_subtype = hdr->ct_fs_subtype;
+	oct->options = hdr->ct_options;
+	oct->max_res_size = hdr->ct_mr_size;
+	oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
 	debug_event(dbf->san, level, r, sizeof(*r));
 	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-			 (void *)hdr + sizeof(struct ct_hdr), oct->len);
+			 (void *)hdr + sizeof(struct fc_ct_hdr), oct->len);
 	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
@@ -717,10 +715,9 @@ void zfcp_dbf_san_ct_request(struct zfcp
  */
 void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-	struct zfcp_wka_port *wka_port = ct->wka_port;
-	struct zfcp_adapter *adapter = wka_port->adapter;
-	struct ct_hdr *hdr = sg_virt(ct->resp);
+	struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
+	struct fc_ct_hdr *hdr = sg_virt(ct->resp);
 	struct zfcp_dbf *dbf = adapter->dbf;
 	struct zfcp_dbf_san_record *r = &dbf->san_buf;
 	struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
@@ -732,25 +729,23 @@ void zfcp_dbf_san_ct_response(struct zfc
 	strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
 	r->fsf_seqno = fsf_req->seq_no;
-	r->s_id = wka_port->d_id;
-	r->d_id = fc_host_port_id(adapter->scsi_host);
-	rct->cmd_rsp_code = hdr->cmd_rsp_code;
-	rct->revision = hdr->revision;
-	rct->reason_code = hdr->reason_code;
-	rct->expl = hdr->reason_code_expl;
-	rct->vendor_unique = hdr->vendor_unique;
-	rct->max_res_size = hdr->max_res_size;
-	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
+	rct->cmd_rsp_code = hdr->ct_cmd;
+	rct->revision = hdr->ct_rev;
+	rct->reason_code = hdr->ct_reason;
+	rct->expl = hdr->ct_explan;
+	rct->vendor_unique = hdr->ct_vendor;
+	rct->max_res_size = hdr->ct_mr_size;
+	rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
 	debug_event(dbf->san, level, r, sizeof(*r));
 	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
-			 (void *)hdr + sizeof(struct ct_hdr), rct->len);
+			 (void *)hdr + sizeof(struct fc_ct_hdr), rct->len);
 	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
 static void zfcp_dbf_san_els(const char *tag, int level,
-			     struct zfcp_fsf_req *fsf_req, u32 s_id, u32 d_id,
-			     u8 ls_code, void *buffer, int buflen)
+			     struct zfcp_fsf_req *fsf_req, u32 d_id,
+			     void *buffer, int buflen)
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_dbf *dbf = adapter->dbf;
@@ -762,9 +757,7 @@ static void zfcp_dbf_san_els(const char
 	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
 	rec->fsf_reqid = fsf_req->req_id;
 	rec->fsf_seqno = fsf_req->seq_no;
-	rec->s_id = s_id;
-	rec->d_id = d_id;
-	rec->u.els.ls_code = ls_code;
+	rec->u.els.d_id = d_id;
 	debug_event(dbf->san, level, rec, sizeof(*rec));
 	zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
 			 buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
@@ -777,12 +770,11 @@ static void zfcp_dbf_san_els(const char
  */
 void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+	struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
 
-	zfcp_dbf_san_els("oels", 2, fsf_req,
-			       fc_host_port_id(els->adapter->scsi_host),
-			       els->d_id, *(u8 *) sg_virt(els->req),
-			       sg_virt(els->req), els->req->length);
+	zfcp_dbf_san_els("oels", 2, fsf_req, d_id,
+			 sg_virt(els->req), els->req->length);
 }
 
 /**
@@ -791,12 +783,11 @@ void zfcp_dbf_san_els_request(struct zfc
  */
 void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
+	struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
+	u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
 
-	zfcp_dbf_san_els("rels", 2, fsf_req, els->d_id,
-			       fc_host_port_id(els->adapter->scsi_host),
-			       *(u8 *)sg_virt(els->req), sg_virt(els->resp),
-			       els->resp->length);
+	zfcp_dbf_san_els("rels", 2, fsf_req, d_id,
+			       sg_virt(els->resp), els->resp->length);
 }
 
 /**
@@ -805,16 +796,13 @@ void zfcp_dbf_san_els_response(struct zf
  */
 void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
 {
-	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_status_read_buffer *buf =
 			(struct fsf_status_read_buffer *)fsf_req->data;
 	int length = (int)buf->length -
 		     (int)((void *)&buf->payload - (void *)buf);
 
-	zfcp_dbf_san_els("iels", 1, fsf_req, buf->d_id,
-			       fc_host_port_id(adapter->scsi_host),
-			       buf->payload.data[0], (void *)buf->payload.data,
-			       length);
+	zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id),
+			       (void *)buf->payload.data, length);
 }
 
 static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
@@ -829,11 +817,10 @@ static int zfcp_dbf_san_view_format(debu
 	zfcp_dbf_tag(&p, "tag", r->tag);
 	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
 	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-	zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id);
-	zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);
 
 	if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
 		struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
+		zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id);
 		zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
 		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
 		zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
@@ -852,7 +839,7 @@ static int zfcp_dbf_san_view_format(debu
 		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
 		struct zfcp_dbf_san_record_els *els = &r->u.els;
-		zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
+		zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id);
 	}
 	return p - out_buf;
 }
@@ -870,8 +857,9 @@ void _zfcp_dbf_scsi(const char *tag, con
 	struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
 	unsigned long flags;
-	struct fcp_rsp_iu *fcp_rsp;
-	char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
+	struct fcp_resp_with_ext *fcp_rsp;
+	struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
+	char *fcp_sns_info = NULL;
 	int offset = 0, buflen = 0;
 
 	spin_lock_irqsave(&dbf->scsi_lock, flags);
@@ -895,20 +883,22 @@ void _zfcp_dbf_scsi(const char *tag, con
 				rec->scsi_allowed = scsi_cmnd->allowed;
 			}
 			if (fsf_req != NULL) {
-				fcp_rsp = (struct fcp_rsp_iu *)
-				    &(fsf_req->qtcb->bottom.io.fcp_rsp);
-				fcp_rsp_info = (unsigned char *) &fcp_rsp[1];
-				fcp_sns_info =
-				    zfcp_get_fcp_sns_info_ptr(fcp_rsp);
+				fcp_rsp = (struct fcp_resp_with_ext *)
+					&(fsf_req->qtcb->bottom.io.fcp_rsp);
+				fcp_rsp_info = (struct fcp_resp_rsp_info *)
+					&fcp_rsp[1];
+				fcp_sns_info = (char *) &fcp_rsp[1];
+				if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
+					fcp_sns_info += fcp_rsp->ext.fr_sns_len;
 
-				rec->rsp_validity = fcp_rsp->validity.value;
-				rec->rsp_scsi_status = fcp_rsp->scsi_status;
-				rec->rsp_resid = fcp_rsp->fcp_resid;
-				if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
-					rec->rsp_code = *(fcp_rsp_info + 3);
-				if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
-					buflen = min((int)fcp_rsp->fcp_sns_len,
-						     ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
+				rec->rsp_validity = fcp_rsp->resp.fr_flags;
+				rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
+				rec->rsp_resid = fcp_rsp->ext.fr_resid;
+				if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
+					rec->rsp_code = fcp_rsp_info->rsp_code;
+				if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
+					buflen = min(fcp_rsp->ext.fr_sns_len,
+					   (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
 					rec->sns_info_len = buflen;
 					memcpy(rec->sns_info, fcp_sns_info,
 					       min(buflen,
@@ -1067,6 +1057,8 @@ err_out:
  */
 void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
 {
+	if (!dbf)
+		return;
 	debug_unregister(dbf->scsi);
 	debug_unregister(dbf->san);
 	debug_unregister(dbf->hba);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_dbf.h linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.h
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_dbf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_dbf.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #ifndef ZFCP_DBF_H
 #define ZFCP_DBF_H
 
+#include <scsi/fc/fc_fcp.h>
 #include "zfcp_ext.h"
 #include "zfcp_fsf.h"
 #include "zfcp_def.h"
@@ -122,7 +123,6 @@ struct zfcp_dbf_hba_record_response {
 		} unit;
 		struct {
 			u32 d_id;
-			u8 ls_code;
 		} els;
 	} u;
 } __attribute__ ((packed));
@@ -166,6 +166,7 @@ struct zfcp_dbf_san_record_ct_request {
 	u8 options;
 	u16 max_res_size;
 	u32 len;
+	u32 d_id;
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record_ct_response {
@@ -179,16 +180,13 @@ struct zfcp_dbf_san_record_ct_response {
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record_els {
-	u8 ls_code;
-	u32 len;
+	u32 d_id;
 } __attribute__ ((packed));
 
 struct zfcp_dbf_san_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u64 fsf_reqid;
 	u32 fsf_seqno;
-	u32 s_id;
-	u32 d_id;
 	union {
 		struct zfcp_dbf_san_record_ct_request ct_req;
 		struct zfcp_dbf_san_record_ct_response ct_resp;
@@ -343,7 +341,7 @@ static inline
 void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
 			    struct scsi_cmnd *scsi_cmnd)
 {
-	zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
+	zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
 			    unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_def.h linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_def.h
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_def.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_def.h	2010-02-24 13:52:17.000000000 -0500
@@ -71,131 +71,6 @@
 /* timeout value for "default timer" for fsf requests */
 #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
 
-/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
-
-/* task attribute values in FCP-2 FCP_CMND IU */
-#define SIMPLE_Q	0
-#define HEAD_OF_Q	1
-#define ORDERED_Q	2
-#define ACA_Q		4
-#define UNTAGGED	5
-
-/* task management flags in FCP-2 FCP_CMND IU */
-#define FCP_CLEAR_ACA		0x40
-#define FCP_TARGET_RESET	0x20
-#define FCP_LOGICAL_UNIT_RESET	0x10
-#define FCP_CLEAR_TASK_SET	0x04
-#define FCP_ABORT_TASK_SET	0x02
-
-#define FCP_CDB_LENGTH		16
-
-#define ZFCP_DID_MASK           0x00FFFFFF
-
-/* FCP(-2) FCP_CMND IU */
-struct fcp_cmnd_iu {
-	u64 fcp_lun;	   /* FCP logical unit number */
-	u8  crn;	           /* command reference number */
-	u8  reserved0:5;	   /* reserved */
-	u8  task_attribute:3;	   /* task attribute */
-	u8  task_management_flags; /* task management flags */
-	u8  add_fcp_cdb_length:6;  /* additional FCP_CDB length */
-	u8  rddata:1;              /* read data */
-	u8  wddata:1;              /* write data */
-	u8  fcp_cdb[FCP_CDB_LENGTH];
-} __attribute__((packed));
-
-/* FCP(-2) FCP_RSP IU */
-struct fcp_rsp_iu {
-	u8  reserved0[10];
-	union {
-		struct {
-			u8 reserved1:3;
-			u8 fcp_conf_req:1;
-			u8 fcp_resid_under:1;
-			u8 fcp_resid_over:1;
-			u8 fcp_sns_len_valid:1;
-			u8 fcp_rsp_len_valid:1;
-		} bits;
-		u8 value;
-	} validity;
-	u8  scsi_status;
-	u32 fcp_resid;
-	u32 fcp_sns_len;
-	u32 fcp_rsp_len;
-} __attribute__((packed));
-
-
-#define RSP_CODE_GOOD		 0
-#define RSP_CODE_LENGTH_MISMATCH 1
-#define RSP_CODE_FIELD_INVALID	 2
-#define RSP_CODE_RO_MISMATCH	 3
-#define RSP_CODE_TASKMAN_UNSUPP	 4
-#define RSP_CODE_TASKMAN_FAILED	 5
-
-/* see fc-fs */
-#define LS_RSCN  0x61
-#define LS_LOGO  0x05
-#define LS_PLOGI 0x03
-
-struct fcp_rscn_head {
-        u8  command;
-        u8  page_length; /* always 0x04 */
-        u16 payload_len;
-} __attribute__((packed));
-
-struct fcp_rscn_element {
-        u8  reserved:2;
-        u8  event_qual:4;
-        u8  addr_format:2;
-        u32 nport_did:24;
-} __attribute__((packed));
-
-/* see fc-ph */
-struct fcp_logo {
-        u32 command;
-        u32 nport_did;
-	u64 nport_wwpn;
-} __attribute__((packed));
-
-/*
- * FC-FS stuff
- */
-#define R_A_TOV				10 /* seconds */
-
-#define ZFCP_LS_RLS			0x0f
-#define ZFCP_LS_ADISC			0x52
-#define ZFCP_LS_RPS			0x56
-#define ZFCP_LS_RSCN			0x61
-#define ZFCP_LS_RNID			0x78
-
-struct zfcp_ls_adisc {
-	u8		code;
-	u8		field[3];
-	u32		hard_nport_id;
-	u64		wwpn;
-	u64		wwnn;
-	u32		nport_id;
-} __attribute__ ((packed));
-
-/*
- * FC-GS-2 stuff
- */
-#define ZFCP_CT_REVISION		0x01
-#define ZFCP_CT_DIRECTORY_SERVICE	0xFC
-#define ZFCP_CT_NAME_SERVER		0x02
-#define ZFCP_CT_SYNCHRONOUS		0x00
-#define ZFCP_CT_SCSI_FCP		0x08
-#define ZFCP_CT_UNABLE_TO_PERFORM_CMD	0x09
-#define ZFCP_CT_GID_PN			0x0121
-#define ZFCP_CT_GPN_FT			0x0172
-#define ZFCP_CT_ACCEPT			0x8002
-#define ZFCP_CT_REJECT			0x8001
-
-/*
- * FC-GS-4 stuff
- */
-#define ZFCP_CT_TIMEOUT			(3 * R_A_TOV)
-
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
 /*
@@ -205,7 +80,6 @@ struct zfcp_ls_adisc {
 #define ZFCP_COMMON_FLAGS			0xfff00000
 
 /* common status bits */
-#define ZFCP_STATUS_COMMON_REMOVE		0x80000000
 #define ZFCP_STATUS_COMMON_RUNNING		0x40000000
 #define ZFCP_STATUS_COMMON_ERP_FAILED		0x20000000
 #define ZFCP_STATUS_COMMON_UNBLOCKED		0x10000000
@@ -222,21 +96,10 @@ struct zfcp_ls_adisc {
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING		0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED	0x00000200
 
-/* FC-PH/FC-GS well-known address identifiers for generic services */
-#define ZFCP_DID_WKA				0xFFFFF0
-
 /* remote port status */
 #define ZFCP_STATUS_PORT_PHYS_OPEN		0x00000001
 #define ZFCP_STATUS_PORT_LINK_TEST		0x00000002
 
-/* well known address (WKA) port status*/
-enum zfcp_wka_status {
-	ZFCP_WKA_PORT_OFFLINE,
-	ZFCP_WKA_PORT_CLOSING,
-	ZFCP_WKA_PORT_OPENING,
-	ZFCP_WKA_PORT_ONLINE,
-};
-
 /* logical unit status */
 #define ZFCP_STATUS_UNIT_SHARED			0x00000004
 #define ZFCP_STATUS_UNIT_READONLY		0x00000008
@@ -247,10 +110,7 @@ enum zfcp_wka_status {
 #define ZFCP_STATUS_FSFREQ_CLEANUP		0x00000010
 #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED	0x00000040
 #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED       0x00000080
-#define ZFCP_STATUS_FSFREQ_ABORTED              0x00000100
 #define ZFCP_STATUS_FSFREQ_TMFUNCFAILED         0x00000200
-#define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP        0x00000400
-#define ZFCP_STATUS_FSFREQ_RETRY                0x00000800
 #define ZFCP_STATUS_FSFREQ_DISMISSED            0x00001000
 
 /************************* STRUCTURE DEFINITIONS *****************************/
@@ -265,125 +125,10 @@ struct zfcp_adapter_mempool {
 	mempool_t *scsi_abort;
 	mempool_t *status_read_req;
 	mempool_t *status_read_data;
-	mempool_t *gid_pn_data;
+	mempool_t *gid_pn;
 	mempool_t *qtcb_pool;
 };
 
-/*
- * header for CT_IU
- */
-struct ct_hdr {
-	u8 revision;		// 0x01
-	u8 in_id[3];		// 0x00
-	u8 gs_type;		// 0xFC	Directory Service
-	u8 gs_subtype;		// 0x02	Name Server
-	u8 options;		// 0x00 single bidirectional exchange
-	u8 reserved0;
-	u16 cmd_rsp_code;	// 0x0121 GID_PN, or 0x0100 GA_NXT
-	u16 max_res_size;	// <= (4096 - 16) / 4
-	u8 reserved1;
-	u8 reason_code;
-	u8 reason_code_expl;
-	u8 vendor_unique;
-} __attribute__ ((packed));
-
-/* nameserver request CT_IU -- for requests where
- * a port name is required */
-struct ct_iu_gid_pn_req {
-	struct ct_hdr header;
-	u64 wwpn;
-} __attribute__ ((packed));
-
-/* FS_ACC IU and data unit for GID_PN nameserver request */
-struct ct_iu_gid_pn_resp {
-	struct ct_hdr header;
-	u32 d_id;
-} __attribute__ ((packed));
-
-struct ct_iu_gpn_ft_req {
-	struct ct_hdr header;
-	u8 flags;
-	u8 domain_id_scope;
-	u8 area_id_scope;
-	u8 fc4_type;
-} __attribute__ ((packed));
-
-
-/**
- * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
- * @wka_port: port where the request is sent to
- * @req: scatter-gather list for request
- * @resp: scatter-gather list for response
- * @handler: handler function (called for response to the request)
- * @handler_data: data passed to handler function
- * @completion: completion for synchronization purposes
- * @status: used to pass error status to calling function
- */
-struct zfcp_send_ct {
-	struct zfcp_wka_port *wka_port;
-	struct scatterlist *req;
-	struct scatterlist *resp;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
-	struct completion *completion;
-	int status;
-};
-
-/* used for name server requests in error recovery */
-struct zfcp_gid_pn_data {
-	struct zfcp_send_ct ct;
-	struct scatterlist req;
-	struct scatterlist resp;
-	struct ct_iu_gid_pn_req ct_iu_req;
-	struct ct_iu_gid_pn_resp ct_iu_resp;
-        struct zfcp_port *port;
-};
-
-/**
- * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
- * @adapter: adapter where request is sent from
- * @port: port where ELS is destinated (port reference count has to be increased)
- * @d_id: destiniation id of port where request is sent to
- * @req: scatter-gather list for request
- * @resp: scatter-gather list for response
- * @handler: handler function (called for response to the request)
- * @handler_data: data passed to handler function
- * @completion: completion for synchronization purposes
- * @ls_code: hex code of ELS command
- * @status: used to pass error status to calling function
- */
-struct zfcp_send_els {
-	struct zfcp_adapter *adapter;
-	struct zfcp_port *port;
-	u32 d_id;
-	struct scatterlist *req;
-	struct scatterlist *resp;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
-	struct completion *completion;
-	int ls_code;
-	int status;
-};
-
-struct zfcp_wka_port {
-	struct zfcp_adapter	*adapter;
-	wait_queue_head_t	completion_wq;
-	enum zfcp_wka_status	status;
-	atomic_t		refcount;
-	u32			d_id;
-	u32			handle;
-	struct mutex		mutex;
-	struct delayed_work	work;
-};
-
-struct zfcp_wka_ports {
-	struct zfcp_wka_port ms; 	/* management service */
-	struct zfcp_wka_port ts; 	/* time service */
-	struct zfcp_wka_port ds; 	/* directory service */
-	struct zfcp_wka_port as; 	/* alias service */
-	struct zfcp_wka_port ks; 	/* key distribution service */
-};
-
 struct zfcp_qdio_queue {
 	struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
 	u8		   first;	/* index of next free bfr in queue */
@@ -446,9 +191,7 @@ struct zfcp_qdio {
 };
 
 struct zfcp_adapter {
-	atomic_t                refcount;          /* reference count */
-	wait_queue_head_t	remove_wq;         /* can be used to wait for
-						      refcount drop to zero */
+	struct kref		ref;
 	u64			peer_wwnn;	   /* P2P peer WWNN */
 	u64			peer_wwpn;	   /* P2P peer WWPN */
 	u32			peer_d_id;	   /* P2P peer D_ID */
@@ -461,7 +204,8 @@ struct zfcp_adapter {
         u32			hardware_version;  /* of FCP channel */
 	u16			timer_ticks;       /* time int for a tick */
 	struct Scsi_Host	*scsi_host;	   /* Pointer to mid-layer */
-	struct list_head	port_list_head;	   /* remote port list */
+	struct list_head	port_list;	   /* remote port list */
+	rwlock_t		port_list_lock;    /* port list lock */
 	unsigned long		req_no;		   /* unique FSF req number */
 	struct list_head	*req_list;	   /* list of pending reqs */
 	spinlock_t		req_list_lock;	   /* request list lock */
@@ -485,7 +229,7 @@ struct zfcp_adapter {
 	u32			erp_low_mem_count; /* nr of erp actions waiting
 						      for memory */
 	struct task_struct	*erp_thread;
-	struct zfcp_wka_ports	*gs;		   /* generic services */
+	struct zfcp_fc_wka_ports *gs;		   /* generic services */
 	struct zfcp_dbf		*dbf;		   /* debug traces */
 	struct zfcp_adapter_mempool	pool;      /* Adapter memory pools */
 	struct fc_host_statistics *fc_stats;
@@ -500,11 +244,9 @@ struct zfcp_port {
 	struct device          sysfs_device;   /* sysfs device */
 	struct fc_rport        *rport;         /* rport of fc transport class */
 	struct list_head       list;	       /* list of remote ports */
-	atomic_t               refcount;       /* reference count */
-	wait_queue_head_t      remove_wq;      /* can be used to wait for
-						  refcount drop to zero */
 	struct zfcp_adapter    *adapter;       /* adapter used to access port */
-	struct list_head       unit_list_head; /* head of logical unit list */
+	struct list_head	unit_list;	/* head of logical unit list */
+	rwlock_t		unit_list_lock; /* unit list lock */
 	atomic_t	       status;	       /* status of this remote port */
 	u64		       wwnn;	       /* WWNN if known */
 	u64		       wwpn;	       /* WWPN */
@@ -523,9 +265,6 @@ struct zfcp_port {
 struct zfcp_unit {
 	struct device          sysfs_device;   /* sysfs device */
 	struct list_head       list;	       /* list of logical units */
-	atomic_t               refcount;       /* reference count */
-	wait_queue_head_t      remove_wq;      /* can be used to wait for
-						  refcount drop to zero */
 	struct zfcp_port       *port;	       /* remote port of unit */
 	atomic_t	       status;	       /* status of this logical unit */
 	u64		       fcp_lun;	       /* own FCP_LUN */
@@ -601,14 +340,11 @@ struct zfcp_fsf_req {
 struct zfcp_data {
 	struct scsi_host_template scsi_host_template;
 	struct scsi_transport_template *scsi_transport_template;
-	rwlock_t                config_lock;        /* serialises changes
-						       to adapter/port/unit
-						       lists */
-	struct mutex		config_mutex;
 	struct kmem_cache	*gpn_ft_cache;
 	struct kmem_cache	*qtcb_cache;
 	struct kmem_cache	*sr_buffer_cache;
 	struct kmem_cache	*gid_pn_cache;
+	struct kmem_cache	*adisc_cache;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
@@ -657,47 +393,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapt
 	return NULL;
 }
 
-/*
- *  functions needed for reference/usage counting
- */
-
-static inline void
-zfcp_unit_get(struct zfcp_unit *unit)
-{
-	atomic_inc(&unit->refcount);
-}
-
-static inline void
-zfcp_unit_put(struct zfcp_unit *unit)
-{
-	if (atomic_dec_return(&unit->refcount) == 0)
-		wake_up(&unit->remove_wq);
-}
-
-static inline void
-zfcp_port_get(struct zfcp_port *port)
-{
-	atomic_inc(&port->refcount);
-}
-
-static inline void
-zfcp_port_put(struct zfcp_port *port)
-{
-	if (atomic_dec_return(&port->refcount) == 0)
-		wake_up(&port->remove_wq);
-}
-
-static inline void
-zfcp_adapter_get(struct zfcp_adapter *adapter)
-{
-	atomic_inc(&adapter->refcount);
-}
-
-static inline void
-zfcp_adapter_put(struct zfcp_adapter *adapter)
-{
-	if (atomic_dec_return(&adapter->refcount) == 0)
-		wake_up(&adapter->remove_wq);
-}
-
 #endif /* ZFCP_DEF_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_erp.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_erp.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_erp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_erp.c	2010-02-24 13:52:17.000000000 -0500
@@ -99,9 +99,12 @@ 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
-		list_for_each_entry(unit, &port->unit_list_head, list)
-		    zfcp_erp_action_dismiss_unit(unit);
+	else {
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
+			zfcp_erp_action_dismiss_unit(unit);
+		read_unlock(&port->unit_list_lock);
+	}
 }
 
 static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
@@ -110,9 +113,12 @@ static void zfcp_erp_action_dismiss_adap
 
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
 		zfcp_erp_action_dismiss(&adapter->erp_action);
-	else
-		list_for_each_entry(port, &adapter->port_list_head, list)
+	else {
+		read_lock(&adapter->port_list_lock);
+		list_for_each_entry(port, &adapter->port_list, list)
 		    zfcp_erp_action_dismiss_port(port);
+		read_unlock(&adapter->port_list_lock);
+	}
 }
 
 static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
@@ -168,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_
 
 	switch (need) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
-		zfcp_unit_get(unit);
+		if (!get_device(&unit->sysfs_device))
+			return NULL;
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
 		erp_action = &unit->erp_action;
 		if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
@@ -177,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-		zfcp_port_get(port);
+		if (!get_device(&port->sysfs_device))
+			return NULL;
 		zfcp_erp_action_dismiss_port(port);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
 		erp_action = &port->erp_action;
@@ -186,7 +194,7 @@ static struct zfcp_erp_action *zfcp_erp_
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
-		zfcp_adapter_get(adapter);
+		kref_get(&adapter->ref);
 		zfcp_erp_action_dismiss_adapter(adapter);
 		atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
 		erp_action = &adapter->erp_action;
@@ -264,11 +272,16 @@ void zfcp_erp_adapter_reopen(struct zfcp
 {
 	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
-	_zfcp_erp_adapter_reopen(adapter, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	zfcp_erp_adapter_block(adapter, clear);
+	zfcp_scsi_schedule_rports_block(adapter);
+
+	write_lock_irqsave(&adapter->erp_lock, flags);
+	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
+	else
+		zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
+					NULL, NULL, id, ref);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 /**
@@ -345,11 +358,9 @@ void zfcp_erp_port_forced_reopen(struct
 	unsigned long flags;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	_zfcp_erp_port_forced_reopen(port, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
@@ -377,15 +388,13 @@ static int _zfcp_erp_port_reopen(struct
  */
 int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
 {
-	unsigned long flags;
 	int retval;
+	unsigned long flags;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	retval = _zfcp_erp_port_reopen(port, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 
 	return retval;
 }
@@ -424,11 +433,9 @@ void zfcp_erp_unit_reopen(struct zfcp_un
 	struct zfcp_port *port = unit->port;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	_zfcp_erp_unit_reopen(unit, clear, id, ref);
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int status_change_set(unsigned long mask, atomic_t *status)
@@ -540,8 +547,10 @@ static void _zfcp_erp_port_reopen_all(st
 {
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock(&adapter->port_list_lock);
+	list_for_each_entry(port, &adapter->port_list, list)
 		_zfcp_erp_port_reopen(port, clear, id, ref);
+	read_unlock(&adapter->port_list_lock);
 }
 
 static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
@@ -549,8 +558,10 @@ static void _zfcp_erp_unit_reopen_all(st
 {
 	struct zfcp_unit *unit;
 
-	list_for_each_entry(unit, &port->unit_list_head, list)
+	read_lock(&port->unit_list_lock);
+	list_for_each_entry(unit, &port->unit_list, list)
 		_zfcp_erp_unit_reopen(unit, clear, id, ref);
+	read_unlock(&port->unit_list_lock);
 }
 
 static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
@@ -590,16 +601,14 @@ static void zfcp_erp_wakeup(struct zfcp_
 {
 	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	read_lock(&adapter->erp_lock);
+	read_lock_irqsave(&adapter->erp_lock, flags);
 	if (list_empty(&adapter->erp_ready_head) &&
 	    list_empty(&adapter->erp_running_head)) {
 			atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
 					  &adapter->status);
 			wake_up(&adapter->erp_done_wqh);
 	}
-	read_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
 static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
@@ -1170,28 +1179,28 @@ static void zfcp_erp_action_cleanup(stru
 	switch (act->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
-			zfcp_unit_get(unit);
+			get_device(&unit->sysfs_device);
 			if (scsi_queue_work(unit->port->adapter->scsi_host,
 					    &unit->scsi_work) <= 0)
-				zfcp_unit_put(unit);
+				put_device(&unit->sysfs_device);
 		}
-		zfcp_unit_put(unit);
+		put_device(&unit->sysfs_device);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (result == ZFCP_ERP_SUCCEEDED)
 			zfcp_scsi_schedule_rport_register(port);
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 		break;
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 		if (result == ZFCP_ERP_SUCCEEDED) {
 			register_service_level(&adapter->service_level);
-			schedule_work(&adapter->scan_work);
+			queue_work(adapter->work_queue, &adapter->scan_work);
 		} else
 			unregister_service_level(&adapter->service_level);
-		zfcp_adapter_put(adapter);
+		kref_put(&adapter->ref, zfcp_adapter_release);
 		break;
 	}
 }
@@ -1214,12 +1223,12 @@ static int zfcp_erp_strategy_do_action(s
 static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 {
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 	unsigned long flags;
+	struct zfcp_adapter *adapter = erp_action->adapter;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	kref_get(&adapter->ref);
 
+	write_lock_irqsave(&adapter->erp_lock, flags);
 	zfcp_erp_strategy_check_fsfreq(erp_action);
 
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
@@ -1231,11 +1240,9 @@ static int zfcp_erp_strategy(struct zfcp
 	zfcp_erp_action_to_running(erp_action);
 
 	/* no lock to allow for blocking operations */
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 	retval = zfcp_erp_strategy_do_action(erp_action);
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	write_lock(&adapter->erp_lock);
+	write_lock_irqsave(&adapter->erp_lock, flags);
 
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
 		retval = ZFCP_ERP_CONTINUES;
@@ -1273,12 +1280,12 @@ static int zfcp_erp_strategy(struct zfcp
 		zfcp_erp_strategy_followup_failed(erp_action);
 
  unlock:
-	write_unlock(&adapter->erp_lock);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	write_unlock_irqrestore(&adapter->erp_lock, flags);
 
 	if (retval != ZFCP_ERP_CONTINUES)
 		zfcp_erp_action_cleanup(erp_action, retval);
 
+	kref_put(&adapter->ref, zfcp_adapter_release);
 	return retval;
 }
 
@@ -1415,6 +1422,7 @@ void zfcp_erp_modify_adapter_status(stru
 				    void *ref, u32 mask, int set_or_clear)
 {
 	struct zfcp_port *port;
+	unsigned long flags;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
 
 	if (set_or_clear == ZFCP_SET) {
@@ -1429,10 +1437,13 @@ void zfcp_erp_modify_adapter_status(stru
 			atomic_set(&adapter->erp_counter, 0);
 	}
 
-	if (common_mask)
-		list_for_each_entry(port, &adapter->port_list_head, list)
+	if (common_mask) {
+		read_lock_irqsave(&adapter->port_list_lock, flags);
+		list_for_each_entry(port, &adapter->port_list, list)
 			zfcp_erp_modify_port_status(port, id, ref, common_mask,
 						    set_or_clear);
+		read_unlock_irqrestore(&adapter->port_list_lock, flags);
+	}
 }
 
 /**
@@ -1449,6 +1460,7 @@ void zfcp_erp_modify_port_status(struct
 				 u32 mask, int set_or_clear)
 {
 	struct zfcp_unit *unit;
+	unsigned long flags;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
 
 	if (set_or_clear == ZFCP_SET) {
@@ -1463,10 +1475,13 @@ void zfcp_erp_modify_port_status(struct
 			atomic_set(&port->erp_counter, 0);
 	}
 
-	if (common_mask)
-		list_for_each_entry(unit, &port->unit_list_head, list)
+	if (common_mask) {
+		read_lock_irqsave(&port->unit_list_lock, flags);
+		list_for_each_entry(unit, &port->unit_list, list)
 			zfcp_erp_modify_unit_status(unit, id, ref, common_mask,
 						    set_or_clear);
+		read_unlock_irqrestore(&port->unit_list_lock, flags);
+	}
 }
 
 /**
@@ -1502,12 +1517,8 @@ void zfcp_erp_modify_unit_status(struct
  */
 void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
 {
-	unsigned long flags;
-
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_erp_modify_port_status(port, id, ref,
 				    ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
 }
 
@@ -1535,13 +1546,9 @@ void zfcp_erp_unit_boxed(struct zfcp_uni
  */
 void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
 {
-	unsigned long flags;
-
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_erp_modify_port_status(port, id, ref,
 				    ZFCP_STATUS_COMMON_ERP_FAILED |
 				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
 /**
@@ -1574,12 +1581,15 @@ static void zfcp_erp_port_access_changed
 					 void *ref)
 {
 	struct zfcp_unit *unit;
+	unsigned long flags;
 	int status = atomic_read(&port->status);
 
 	if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
 			ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock_irqsave(&port->unit_list_lock, flags);
+		list_for_each_entry(unit, &port->unit_list, list)
 				    zfcp_erp_unit_access_changed(unit, id, ref);
+		read_unlock_irqrestore(&port->unit_list_lock, flags);
 		return;
 	}
 
@@ -1595,14 +1605,14 @@ static void zfcp_erp_port_access_changed
 void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
 				     void *ref)
 {
-	struct zfcp_port *port;
 	unsigned long flags;
+	struct zfcp_port *port;
 
 	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
 		return;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		zfcp_erp_port_access_changed(port, id, ref);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_ext.h linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ext.h
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_ext.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_ext.h	2010-02-24 13:52:17.000000000 -0500
@@ -9,26 +9,31 @@
 #ifndef ZFCP_EXT_H
 #define ZFCP_EXT_H
 
+#include <linux/types.h>
+#include <scsi/fc/fc_els.h>
 #include "zfcp_def.h"
+#include "zfcp_fc.h"
 
 /* zfcp_aux.c */
 extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
 extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
-extern int zfcp_adapter_enqueue(struct ccw_device *);
-extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
+extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
 extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
 					   u32);
-extern void zfcp_port_dequeue(struct zfcp_port *);
 extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
-extern void zfcp_unit_dequeue(struct zfcp_unit *);
 extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
 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_register(void);
 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;
@@ -51,7 +56,7 @@ extern void _zfcp_dbf_hba_fsf_unsol(cons
 					  struct fsf_status_read_buffer *);
 extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
 extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *, u32);
 extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
@@ -92,24 +97,23 @@ extern void zfcp_erp_adapter_access_chan
 extern void zfcp_erp_timeout_handler(unsigned long);
 
 /* zfcp_fc.c */
-extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
-extern void _zfcp_fc_scan_ports_later(struct work_struct *);
+extern void zfcp_fc_scan_ports(struct work_struct *);
 extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
 extern void zfcp_fc_port_did_lookup(struct work_struct *);
 extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
-extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
+extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fc_els_flogi *);
 extern void zfcp_fc_test_link(struct zfcp_port *);
 extern void zfcp_fc_link_test_work(struct work_struct *);
-extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *);
+extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
 extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
 extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
-extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *);
-extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
+extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
+extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
 
 /* zfcp_fsf.c */
 extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
-extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *);
-extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *);
+extern int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *);
+extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *);
 extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
@@ -125,8 +129,10 @@ extern struct zfcp_fsf_req *zfcp_fsf_con
 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);
-extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *);
-extern int zfcp_fsf_send_els(struct zfcp_send_els *);
+extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
+			    mempool_t *, unsigned int);
+extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
+			     struct zfcp_fsf_ct_els *, unsigned int);
 extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
 					  struct scsi_cmnd *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
@@ -153,7 +159,6 @@ extern void zfcp_qdio_close(struct zfcp_
 extern struct zfcp_data zfcp_data;
 extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
 extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
-extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
 extern struct fc_function_template zfcp_transport_functions;
 extern void zfcp_scsi_rport_work(struct work_struct *);
 extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fc.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,73 +9,38 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/types.h>
+#include <scsi/fc/fc_els.h>
+#include <scsi/libfc.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 
-enum rscn_address_format {
-	RSCN_PORT_ADDRESS	= 0x0,
-	RSCN_AREA_ADDRESS	= 0x1,
-	RSCN_DOMAIN_ADDRESS	= 0x2,
-	RSCN_FABRIC_ADDRESS	= 0x3,
-};
-
-static u32 rscn_range_mask[] = {
-	[RSCN_PORT_ADDRESS]		= 0xFFFFFF,
-	[RSCN_AREA_ADDRESS]		= 0xFFFF00,
-	[RSCN_DOMAIN_ADDRESS]		= 0xFF0000,
-	[RSCN_FABRIC_ADDRESS]		= 0x000000,
-};
-
-struct gpn_ft_resp_acc {
-	u8 control;
-	u8 port_id[3];
-	u8 reserved[4];
-	u64 wwpn;
-} __attribute__ ((packed));
-
-#define ZFCP_CT_SIZE_ONE_PAGE	(PAGE_SIZE - sizeof(struct ct_hdr))
-#define ZFCP_GPN_FT_ENTRIES	(ZFCP_CT_SIZE_ONE_PAGE \
-					/ sizeof(struct gpn_ft_resp_acc))
-#define ZFCP_GPN_FT_BUFFERS 4
-#define ZFCP_GPN_FT_MAX_SIZE (ZFCP_GPN_FT_BUFFERS * PAGE_SIZE \
-				- sizeof(struct ct_hdr))
-#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1)
-
-struct ct_iu_gpn_ft_resp {
-	struct ct_hdr header;
-	struct gpn_ft_resp_acc accept[ZFCP_GPN_FT_ENTRIES];
-} __attribute__ ((packed));
-
-struct zfcp_gpn_ft {
-	struct zfcp_send_ct ct;
-	struct scatterlist sg_req;
-	struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
-};
-
-struct zfcp_fc_ns_handler_data {
-	struct completion done;
-	void (*handler)(unsigned long);
-	unsigned long handler_data;
+static u32 zfcp_fc_rscn_range_mask[] = {
+	[ELS_ADDR_FMT_PORT]		= 0xFFFFFF,
+	[ELS_ADDR_FMT_AREA]		= 0xFFFF00,
+	[ELS_ADDR_FMT_DOM]		= 0xFF0000,
+	[ELS_ADDR_FMT_FAB]		= 0x000000,
 };
 
-static int zfcp_fc_wka_port_get(struct zfcp_wka_port *wka_port)
+static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port)
 {
 	if (mutex_lock_interruptible(&wka_port->mutex))
 		return -ERESTARTSYS;
 
-	if (wka_port->status == ZFCP_WKA_PORT_OFFLINE ||
-	    wka_port->status == ZFCP_WKA_PORT_CLOSING) {
-		wka_port->status = ZFCP_WKA_PORT_OPENING;
+	if (wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE ||
+	    wka_port->status == ZFCP_FC_WKA_PORT_CLOSING) {
+		wka_port->status = ZFCP_FC_WKA_PORT_OPENING;
 		if (zfcp_fsf_open_wka_port(wka_port))
-			wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+			wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	}
 
 	mutex_unlock(&wka_port->mutex);
 
 	wait_event(wka_port->completion_wq,
-		   wka_port->status == ZFCP_WKA_PORT_ONLINE ||
-		   wka_port->status == ZFCP_WKA_PORT_OFFLINE);
+		   wka_port->status == ZFCP_FC_WKA_PORT_ONLINE ||
+		   wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE);
 
-	if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {
+	if (wka_port->status == ZFCP_FC_WKA_PORT_ONLINE) {
 		atomic_inc(&wka_port->refcount);
 		return 0;
 	}
@@ -85,24 +50,24 @@ static int zfcp_fc_wka_port_get(struct z
 static void zfcp_fc_wka_port_offline(struct work_struct *work)
 {
 	struct delayed_work *dw = to_delayed_work(work);
-	struct zfcp_wka_port *wka_port =
-			container_of(dw, struct zfcp_wka_port, work);
+	struct zfcp_fc_wka_port *wka_port =
+			container_of(dw, struct zfcp_fc_wka_port, work);
 
 	mutex_lock(&wka_port->mutex);
 	if ((atomic_read(&wka_port->refcount) != 0) ||
-	    (wka_port->status != ZFCP_WKA_PORT_ONLINE))
+	    (wka_port->status != ZFCP_FC_WKA_PORT_ONLINE))
 		goto out;
 
-	wka_port->status = ZFCP_WKA_PORT_CLOSING;
+	wka_port->status = ZFCP_FC_WKA_PORT_CLOSING;
 	if (zfcp_fsf_close_wka_port(wka_port)) {
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		wake_up(&wka_port->completion_wq);
 	}
 out:
 	mutex_unlock(&wka_port->mutex);
 }
 
-static void zfcp_fc_wka_port_put(struct zfcp_wka_port *wka_port)
+static void zfcp_fc_wka_port_put(struct zfcp_fc_wka_port *wka_port)
 {
 	if (atomic_dec_return(&wka_port->refcount) != 0)
 		return;
@@ -110,7 +75,7 @@ static void zfcp_fc_wka_port_put(struct
 	schedule_delayed_work(&wka_port->work, HZ / 100);
 }
 
-static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id,
+static void zfcp_fc_wka_port_init(struct zfcp_fc_wka_port *wka_port, u32 d_id,
 				  struct zfcp_adapter *adapter)
 {
 	init_waitqueue_head(&wka_port->completion_wq);
@@ -118,107 +83,107 @@ static void zfcp_fc_wka_port_init(struct
 	wka_port->adapter = adapter;
 	wka_port->d_id = d_id;
 
-	wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	atomic_set(&wka_port->refcount, 0);
 	mutex_init(&wka_port->mutex);
 	INIT_DELAYED_WORK(&wka_port->work, zfcp_fc_wka_port_offline);
 }
 
-static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
+static void zfcp_fc_wka_port_force_offline(struct zfcp_fc_wka_port *wka)
 {
 	cancel_delayed_work_sync(&wka->work);
 	mutex_lock(&wka->mutex);
-	wka->status = ZFCP_WKA_PORT_OFFLINE;
+	wka->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	mutex_unlock(&wka->mutex);
 }
 
-void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
+void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *gs)
 {
+	if (!gs)
+		return;
 	zfcp_fc_wka_port_force_offline(&gs->ms);
 	zfcp_fc_wka_port_force_offline(&gs->ts);
 	zfcp_fc_wka_port_force_offline(&gs->ds);
 	zfcp_fc_wka_port_force_offline(&gs->as);
-	zfcp_fc_wka_port_force_offline(&gs->ks);
 }
 
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
-				   struct fcp_rscn_element *elem)
+				   struct fc_els_rscn_page *page)
 {
 	unsigned long flags;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_port *port;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
-		if ((port->d_id & range) == (elem->nport_did & range))
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
+		if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
 			zfcp_fc_test_link(port);
 		if (!port->d_id)
 			zfcp_erp_port_reopen(port,
 					     ZFCP_STATUS_COMMON_ERP_FAILED,
 					     "fcrscn1", NULL);
 	}
-
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
 {
 	struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
-	struct fcp_rscn_head *fcp_rscn_head;
-	struct fcp_rscn_element *fcp_rscn_element;
+	struct fc_els_rscn *head;
+	struct fc_els_rscn_page *page;
 	u16 i;
 	u16 no_entries;
-	u32 range_mask;
+	unsigned int afmt;
 
-	fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload.data;
-	fcp_rscn_element = (struct fcp_rscn_element *) fcp_rscn_head;
+	head = (struct fc_els_rscn *) status_buffer->payload.data;
+	page = (struct fc_els_rscn_page *) head;
 
 	/* see FC-FS */
-	no_entries = fcp_rscn_head->payload_len /
-			sizeof(struct fcp_rscn_element);
+	no_entries = head->rscn_plen / sizeof(struct fc_els_rscn_page);
 
 	for (i = 1; i < no_entries; i++) {
 		/* skip head and start with 1st element */
-		fcp_rscn_element++;
-		range_mask = rscn_range_mask[fcp_rscn_element->addr_format];
-		_zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
+		page++;
+		afmt = page->rscn_page_flags & ELS_RSCN_ADDR_FMT_MASK;
+		_zfcp_fc_incoming_rscn(fsf_req, zfcp_fc_rscn_range_mask[afmt],
+				       page);
 	}
-	schedule_work(&fsf_req->adapter->scan_work);
+	queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
 }
 
 static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
 {
+	unsigned long flags;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct zfcp_port *port;
-	unsigned long flags;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if (port->wwpn == wwpn)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
+		if (port->wwpn == wwpn) {
+			zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
 			break;
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
-
-	if (port && (port->wwpn == wwpn))
-		zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
+		}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
 {
-	struct fsf_status_read_buffer *status_buffer =
-		(struct fsf_status_read_buffer *)req->data;
-	struct fsf_plogi *els_plogi =
-		(struct fsf_plogi *) status_buffer->payload.data;
+	struct fsf_status_read_buffer *status_buffer;
+	struct fc_els_flogi *plogi;
 
-	zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn);
+	status_buffer = (struct fsf_status_read_buffer *) req->data;
+	plogi = (struct fc_els_flogi *) status_buffer->payload.data;
+	zfcp_fc_incoming_wwpn(req, plogi->fl_wwpn);
 }
 
 static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req)
 {
 	struct fsf_status_read_buffer *status_buffer =
 		(struct fsf_status_read_buffer *)req->data;
-	struct fcp_logo *els_logo =
-		(struct fcp_logo *) status_buffer->payload.data;
+	struct fc_els_logo *logo =
+		(struct fc_els_logo *) status_buffer->payload.data;
 
-	zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn);
+	zfcp_fc_incoming_wwpn(req, logo->fl_n_port_wwn);
 }
 
 /**
@@ -232,79 +197,73 @@ void zfcp_fc_incoming_els(struct zfcp_fs
 	unsigned int els_type = status_buffer->payload.data[0];
 
 	zfcp_dbf_san_incoming_els(fsf_req);
-	if (els_type == LS_PLOGI)
+	if (els_type == ELS_PLOGI)
 		zfcp_fc_incoming_plogi(fsf_req);
-	else if (els_type == LS_LOGO)
+	else if (els_type == ELS_LOGO)
 		zfcp_fc_incoming_logo(fsf_req);
-	else if (els_type == LS_RSCN)
+	else if (els_type == ELS_RSCN)
 		zfcp_fc_incoming_rscn(fsf_req);
 }
 
-static void zfcp_fc_ns_handler(unsigned long data)
-{
-	struct zfcp_fc_ns_handler_data *compl_rec =
-			(struct zfcp_fc_ns_handler_data *) data;
-
-	if (compl_rec->handler)
-		compl_rec->handler(compl_rec->handler_data);
-
-	complete(&compl_rec->done);
-}
-
-static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
+static void zfcp_fc_ns_gid_pn_eval(void *data)
 {
-	struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data;
-	struct zfcp_send_ct *ct = &gid_pn->ct;
-	struct ct_iu_gid_pn_req *ct_iu_req = sg_virt(ct->req);
-	struct ct_iu_gid_pn_resp *ct_iu_resp = sg_virt(ct->resp);
+	struct zfcp_fc_gid_pn *gid_pn = data;
+	struct zfcp_fsf_ct_els *ct = &gid_pn->ct;
+	struct zfcp_fc_gid_pn_req *gid_pn_req = sg_virt(ct->req);
+	struct zfcp_fc_gid_pn_resp *gid_pn_resp = sg_virt(ct->resp);
 	struct zfcp_port *port = gid_pn->port;
 
 	if (ct->status)
 		return;
-	if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT)
+	if (gid_pn_resp->ct_hdr.ct_cmd != FC_FS_ACC)
 		return;
 
 	/* paranoia */
-	if (ct_iu_req->wwpn != port->wwpn)
+	if (gid_pn_req->gid_pn.fn_wwpn != port->wwpn)
 		return;
 	/* looks like a valid d_id */
-	port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
+	port->d_id = ntoh24(gid_pn_resp->gid_pn.fp_fid);
+}
+
+static void zfcp_fc_complete(void *data)
+{
+	complete(data);
 }
 
 static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
-				     struct zfcp_gid_pn_data *gid_pn)
+				     struct zfcp_fc_gid_pn *gid_pn)
 {
 	struct zfcp_adapter *adapter = port->adapter;
-	struct zfcp_fc_ns_handler_data compl_rec;
+	DECLARE_COMPLETION_ONSTACK(completion);
 	int ret;
 
 	/* setup parameters for send generic command */
 	gid_pn->port = port;
-	gid_pn->ct.wka_port = &adapter->gs->ds;
-	gid_pn->ct.handler = zfcp_fc_ns_handler;
-	gid_pn->ct.handler_data = (unsigned long) &compl_rec;
-	gid_pn->ct.req = &gid_pn->req;
-	gid_pn->ct.resp = &gid_pn->resp;
-	sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
-		    sizeof(struct ct_iu_gid_pn_req));
-	sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp,
-		    sizeof(struct ct_iu_gid_pn_resp));
+	gid_pn->ct.handler = zfcp_fc_complete;
+	gid_pn->ct.handler_data = &completion;
+	gid_pn->ct.req = &gid_pn->sg_req;
+	gid_pn->ct.resp = &gid_pn->sg_resp;
+	sg_init_one(&gid_pn->sg_req, &gid_pn->gid_pn_req,
+		    sizeof(struct zfcp_fc_gid_pn_req));
+	sg_init_one(&gid_pn->sg_resp, &gid_pn->gid_pn_resp,
+		    sizeof(struct zfcp_fc_gid_pn_resp));
 
 	/* setup nameserver request */
-	gid_pn->ct_iu_req.header.revision = ZFCP_CT_REVISION;
-	gid_pn->ct_iu_req.header.gs_type = ZFCP_CT_DIRECTORY_SERVICE;
-	gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER;
-	gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
-	gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
-	gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
-	gid_pn->ct_iu_req.wwpn = port->wwpn;
+	gid_pn->gid_pn_req.ct_hdr.ct_rev = FC_CT_REV;
+	gid_pn->gid_pn_req.ct_hdr.ct_fs_type = FC_FST_DIR;
+	gid_pn->gid_pn_req.ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
+	gid_pn->gid_pn_req.ct_hdr.ct_options = 0;
+	gid_pn->gid_pn_req.ct_hdr.ct_cmd = FC_NS_GID_PN;
+	gid_pn->gid_pn_req.ct_hdr.ct_mr_size = ZFCP_FC_CT_SIZE_PAGE / 4;
+	gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
 
-	init_completion(&compl_rec.done);
-	compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
-	compl_rec.handler_data = (unsigned long) gid_pn;
-	ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req);
-	if (!ret)
-		wait_for_completion(&compl_rec.done);
+	ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
+			       adapter->pool.gid_pn_req,
+			       ZFCP_FC_CTELS_TMO);
+	if (!ret) {
+		wait_for_completion(&completion);
+		zfcp_fc_ns_gid_pn_eval(gid_pn);
+	}
 	return ret;
 }
 
@@ -316,10 +275,10 @@ static int zfcp_fc_ns_gid_pn_request(str
 static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
 {
 	int ret;
-	struct zfcp_gid_pn_data *gid_pn;
+	struct zfcp_fc_gid_pn *gid_pn;
 	struct zfcp_adapter *adapter = port->adapter;
 
-	gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
+	gid_pn = mempool_alloc(adapter->pool.gid_pn, GFP_ATOMIC);
 	if (!gid_pn)
 		return -ENOMEM;
 
@@ -333,7 +292,7 @@ static int zfcp_fc_ns_gid_pn(struct zfcp
 
 	zfcp_fc_wka_port_put(&adapter->gs->ds);
 out:
-	mempool_free(gid_pn, adapter->pool.gid_pn_data);
+	mempool_free(gid_pn, adapter->pool.gid_pn);
 	return ret;
 }
 
@@ -357,7 +316,7 @@ void zfcp_fc_port_did_lookup(struct work
 
 	zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -366,9 +325,9 @@ out:
  */
 void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
 /**
@@ -378,33 +337,36 @@ void zfcp_fc_trigger_did_lookup(struct z
  *
  * Evaluate PLOGI playload and copy important fields into zfcp_port structure
  */
-void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
+void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi)
 {
-	port->maxframe_size = plogi->serv_param.common_serv_param[7] |
-		((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
-	if (plogi->serv_param.class1_serv_param[0] & 0x80)
+	if (plogi->fl_wwpn != port->wwpn) {
+		port->d_id = 0;
+		dev_warn(&port->adapter->ccw_device->dev,
+			 "A port opened with WWPN 0x%016Lx returned data that "
+			 "identifies it as WWPN 0x%016Lx\n",
+			 (unsigned long long) port->wwpn,
+			 (unsigned long long) plogi->fl_wwpn);
+		return;
+	}
+
+	port->wwnn = plogi->fl_wwnn;
+	port->maxframe_size = plogi->fl_csp.sp_bb_data;
+
+	if (plogi->fl_cssp[0].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS1;
-	if (plogi->serv_param.class2_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[1].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS2;
-	if (plogi->serv_param.class3_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[2].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS3;
-	if (plogi->serv_param.class4_serv_param[0] & 0x80)
+	if (plogi->fl_cssp[3].cp_class & FC_CPC_VALID)
 		port->supported_classes |= FC_COS_CLASS4;
 }
 
-struct zfcp_els_adisc {
-	struct zfcp_send_els els;
-	struct scatterlist req;
-	struct scatterlist resp;
-	struct zfcp_ls_adisc ls_adisc;
-	struct zfcp_ls_adisc ls_adisc_acc;
-};
-
-static void zfcp_fc_adisc_handler(unsigned long data)
+static void zfcp_fc_adisc_handler(void *data)
 {
-	struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data;
+	struct zfcp_fc_els_adisc *adisc = data;
 	struct zfcp_port *port = adisc->els.port;
-	struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc;
+	struct fc_els_adisc *adisc_resp = &adisc->adisc_resp;
 
 	if (adisc->els.status) {
 		/* request rejected or timed out */
@@ -414,9 +376,9 @@ static void zfcp_fc_adisc_handler(unsign
 	}
 
 	if (!port->wwnn)
-		port->wwnn = ls_adisc->wwnn;
+		port->wwnn = adisc_resp->adisc_wwnn;
 
-	if ((port->wwpn != ls_adisc->wwpn) ||
+	if ((port->wwpn != adisc_resp->adisc_wwpn) ||
 	    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
 		zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
 				     "fcadh_2", NULL);
@@ -427,40 +389,45 @@ static void zfcp_fc_adisc_handler(unsign
 	zfcp_scsi_schedule_rport_register(port);
  out:
 	atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
-	zfcp_port_put(port);
-	kfree(adisc);
+	put_device(&port->sysfs_device);
+	kmem_cache_free(zfcp_data.adisc_cache, adisc);
 }
 
 static int zfcp_fc_adisc(struct zfcp_port *port)
 {
-	struct zfcp_els_adisc *adisc;
+	struct zfcp_fc_els_adisc *adisc;
 	struct zfcp_adapter *adapter = port->adapter;
+	int ret;
 
-	adisc = kzalloc(sizeof(struct zfcp_els_adisc), GFP_ATOMIC);
+	adisc = kmem_cache_alloc(zfcp_data.adisc_cache, GFP_ATOMIC);
 	if (!adisc)
 		return -ENOMEM;
 
+	adisc->els.port = port;
 	adisc->els.req = &adisc->req;
 	adisc->els.resp = &adisc->resp;
-	sg_init_one(adisc->els.req, &adisc->ls_adisc,
-		    sizeof(struct zfcp_ls_adisc));
-	sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
-		    sizeof(struct zfcp_ls_adisc));
+	sg_init_one(adisc->els.req, &adisc->adisc_req,
+		    sizeof(struct fc_els_adisc));
+	sg_init_one(adisc->els.resp, &adisc->adisc_resp,
+		    sizeof(struct fc_els_adisc));
 
-	adisc->els.adapter = adapter;
-	adisc->els.port = port;
-	adisc->els.d_id = port->d_id;
 	adisc->els.handler = zfcp_fc_adisc_handler;
-	adisc->els.handler_data = (unsigned long) adisc;
-	adisc->els.ls_code = adisc->ls_adisc.code = ZFCP_LS_ADISC;
+	adisc->els.handler_data = adisc;
 
 	/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
 	   without FC-AL-2 capability, so we don't set it */
-	adisc->ls_adisc.wwpn = fc_host_port_name(adapter->scsi_host);
-	adisc->ls_adisc.wwnn = fc_host_node_name(adapter->scsi_host);
-	adisc->ls_adisc.nport_id = fc_host_port_id(adapter->scsi_host);
+	adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host);
+	adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host);
+	adisc->adisc_req.adisc_cmd = ELS_ADISC;
+	hton24(adisc->adisc_req.adisc_port_id,
+	       fc_host_port_id(adapter->scsi_host));
 
-	return zfcp_fsf_send_els(&adisc->els);
+	ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els,
+				ZFCP_FC_CTELS_TMO);
+	if (ret)
+		kmem_cache_free(zfcp_data.adisc_cache, adisc);
+
+	return ret;
 }
 
 void zfcp_fc_link_test_work(struct work_struct *work)
@@ -469,7 +436,7 @@ void zfcp_fc_link_test_work(struct work_
 		container_of(work, struct zfcp_port, test_link_work);
 	int retval;
 
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_DEL;
 	zfcp_scsi_rport_work(&port->rport_work);
 
@@ -488,7 +455,7 @@ void zfcp_fc_link_test_work(struct work_
 	zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
 
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -501,12 +468,12 @@ out:
  */
 void zfcp_fc_test_link(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	if (!queue_work(port->adapter->work_queue, &port->test_link_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
-static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
+static void zfcp_free_sg_env(struct zfcp_fc_gpn_ft *gpn_ft, int buf_num)
 {
 	struct scatterlist *sg = &gpn_ft->sg_req;
 
@@ -516,10 +483,10 @@ static void zfcp_free_sg_env(struct zfcp
 	kfree(gpn_ft);
 }
 
-static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
+static struct zfcp_fc_gpn_ft *zfcp_alloc_sg_env(int buf_num)
 {
-	struct zfcp_gpn_ft *gpn_ft;
-	struct ct_iu_gpn_ft_req *req;
+	struct zfcp_fc_gpn_ft *gpn_ft;
+	struct zfcp_fc_gpn_ft_req *req;
 
 	gpn_ft = kzalloc(sizeof(*gpn_ft), GFP_KERNEL);
 	if (!gpn_ft)
@@ -542,159 +509,153 @@ out:
 }
 
 
-static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
+static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
 			       struct zfcp_adapter *adapter, int max_bytes)
 {
-	struct zfcp_send_ct *ct = &gpn_ft->ct;
-	struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
-	struct zfcp_fc_ns_handler_data compl_rec;
+	struct zfcp_fsf_ct_els *ct = &gpn_ft->ct;
+	struct zfcp_fc_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
+	DECLARE_COMPLETION_ONSTACK(completion);
 	int ret;
 
 	/* prepare CT IU for GPN_FT */
-	req->header.revision = ZFCP_CT_REVISION;
-	req->header.gs_type = ZFCP_CT_DIRECTORY_SERVICE;
-	req->header.gs_subtype = ZFCP_CT_NAME_SERVER;
-	req->header.options = ZFCP_CT_SYNCHRONOUS;
-	req->header.cmd_rsp_code = ZFCP_CT_GPN_FT;
-	req->header.max_res_size = max_bytes / 4;
-	req->flags = 0;
-	req->domain_id_scope = 0;
-	req->area_id_scope = 0;
-	req->fc4_type = ZFCP_CT_SCSI_FCP;
+	req->ct_hdr.ct_rev = FC_CT_REV;
+	req->ct_hdr.ct_fs_type = FC_FST_DIR;
+	req->ct_hdr.ct_fs_subtype = FC_NS_SUBTYPE;
+	req->ct_hdr.ct_options = 0;
+	req->ct_hdr.ct_cmd = FC_NS_GPN_FT;
+	req->ct_hdr.ct_mr_size = max_bytes / 4;
+	req->gpn_ft.fn_domain_id_scope = 0;
+	req->gpn_ft.fn_area_id_scope = 0;
+	req->gpn_ft.fn_fc4_type = FC_TYPE_FCP;
 
 	/* prepare zfcp_send_ct */
-	ct->wka_port = &adapter->gs->ds;
-	ct->handler = zfcp_fc_ns_handler;
-	ct->handler_data = (unsigned long)&compl_rec;
+	ct->handler = zfcp_fc_complete;
+	ct->handler_data = &completion;
 	ct->req = &gpn_ft->sg_req;
 	ct->resp = gpn_ft->sg_resp;
 
-	init_completion(&compl_rec.done);
-	compl_rec.handler = NULL;
-	ret = zfcp_fsf_send_ct(ct, NULL);
+	ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL,
+			       ZFCP_FC_CTELS_TMO);
 	if (!ret)
-		wait_for_completion(&compl_rec.done);
+		wait_for_completion(&completion);
 	return ret;
 }
 
-static void zfcp_fc_validate_port(struct zfcp_port *port)
+static void zfcp_fc_validate_port(struct zfcp_port *port, struct list_head *lh)
 {
-	struct zfcp_adapter *adapter = port->adapter;
-
 	if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC))
 		return;
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
 
 	if ((port->supported_classes != 0) ||
-	    !list_empty(&port->unit_list_head)) {
-		zfcp_port_put(port);
+	    !list_empty(&port->unit_list))
 		return;
-	}
-	zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
-	zfcp_erp_wait(adapter);
-	zfcp_port_put(port);
-	zfcp_port_dequeue(port);
+
+	list_move_tail(&port->list, lh);
 }
 
-static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
+static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
+			       struct zfcp_adapter *adapter, int max_entries)
 {
-	struct zfcp_send_ct *ct = &gpn_ft->ct;
+	struct zfcp_fsf_ct_els *ct = &gpn_ft->ct;
 	struct scatterlist *sg = gpn_ft->sg_resp;
-	struct ct_hdr *hdr = sg_virt(sg);
-	struct gpn_ft_resp_acc *acc = sg_virt(sg);
-	struct zfcp_adapter *adapter = ct->wka_port->adapter;
+	struct fc_ct_hdr *hdr = sg_virt(sg);
+	struct fc_gpn_ft_resp *acc = sg_virt(sg);
 	struct zfcp_port *port, *tmp;
+	unsigned long flags;
+	LIST_HEAD(remove_lh);
 	u32 d_id;
 	int ret = 0, x, last = 0;
 
 	if (ct->status)
 		return -EIO;
 
-	if (hdr->cmd_rsp_code != ZFCP_CT_ACCEPT) {
-		if (hdr->reason_code == ZFCP_CT_UNABLE_TO_PERFORM_CMD)
+	if (hdr->ct_cmd != FC_FS_ACC) {
+		if (hdr->ct_reason == FC_BA_RJT_UNABLE)
 			return -EAGAIN; /* might be a temporary condition */
 		return -EIO;
 	}
 
-	if (hdr->max_res_size) {
+	if (hdr->ct_mr_size) {
 		dev_warn(&adapter->ccw_device->dev,
 			 "The name server reported %d words residual data\n",
-			 hdr->max_res_size);
+			 hdr->ct_mr_size);
 		return -E2BIG;
 	}
 
-	mutex_lock(&zfcp_data.config_mutex);
-
 	/* first entry is the header */
 	for (x = 1; x < max_entries && !last; x++) {
-		if (x % (ZFCP_GPN_FT_ENTRIES + 1))
+		if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
 			acc++;
 		else
 			acc = sg_virt(++sg);
 
-		last = acc->control & 0x80;
-		d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
-		       acc->port_id[2];
+		last = acc->fp_flags & FC_NS_FID_LAST;
+		d_id = ntoh24(acc->fp_fid);
 
 		/* don't attach ports with a well known address */
-		if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA)
+		if (d_id >= FC_FID_WELL_KNOWN_BASE)
 			continue;
 		/* skip the adapter's port and known remote ports */
-		if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
-			continue;
-		port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
-		if (port)
+		if (acc->fp_wwpn == fc_host_port_name(adapter->scsi_host))
 			continue;
 
-		port = zfcp_port_enqueue(adapter, acc->wwpn,
+		port = zfcp_port_enqueue(adapter, acc->fp_wwpn,
 					 ZFCP_STATUS_COMMON_NOESC, d_id);
-		if (IS_ERR(port))
-			ret = PTR_ERR(port);
-		else
+		if (!IS_ERR(port))
 			zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
+		else if (PTR_ERR(port) != -EEXIST)
+			ret = PTR_ERR(port);
 	}
 
 	zfcp_erp_wait(adapter);
-	list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list)
-		zfcp_fc_validate_port(port);
-	mutex_unlock(&zfcp_data.config_mutex);
+	write_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry_safe(port, tmp, &adapter->port_list, list)
+		zfcp_fc_validate_port(port, &remove_lh);
+	write_unlock_irqrestore(&adapter->port_list_lock, flags);
+
+	list_for_each_entry_safe(port, tmp, &remove_lh, list) {
+		zfcp_erp_port_shutdown(port, 0, "fcegpf2", NULL);
+		zfcp_device_unregister(&port->sysfs_device,
+				       &zfcp_sysfs_port_attrs);
+	}
+
 	return ret;
 }
 
 /**
  * zfcp_fc_scan_ports - scan remote ports and attach new ports
- * @adapter: pointer to struct zfcp_adapter
+ * @work: reference to scheduled work
  */
-int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
+void zfcp_fc_scan_ports(struct work_struct *work)
 {
+	struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
+						    scan_work);
 	int ret, i;
-	struct zfcp_gpn_ft *gpn_ft;
+	struct zfcp_fc_gpn_ft *gpn_ft;
 	int chain, max_entries, buf_num, max_bytes;
 
 	chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
-	buf_num = chain ? ZFCP_GPN_FT_BUFFERS : 1;
-	max_entries = chain ? ZFCP_GPN_FT_MAX_ENTRIES : ZFCP_GPN_FT_ENTRIES;
-	max_bytes = chain ? ZFCP_GPN_FT_MAX_SIZE : ZFCP_CT_SIZE_ONE_PAGE;
+	buf_num = chain ? ZFCP_FC_GPN_FT_NUM_BUFS : 1;
+	max_entries = chain ? ZFCP_FC_GPN_FT_MAX_ENT : ZFCP_FC_GPN_FT_ENT_PAGE;
+	max_bytes = chain ? ZFCP_FC_GPN_FT_MAX_SIZE : ZFCP_FC_CT_SIZE_PAGE;
 
 	if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
 	    fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
-		return 0;
+		return;
 
-	ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
-	if (ret)
-		return ret;
+	if (zfcp_fc_wka_port_get(&adapter->gs->ds))
+		return;
 
 	gpn_ft = zfcp_alloc_sg_env(buf_num);
-	if (!gpn_ft) {
-		ret = -ENOMEM;
+	if (!gpn_ft)
 		goto out;
-	}
 
 	for (i = 0; i < 3; i++) {
 		ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes);
 		if (!ret) {
-			ret = zfcp_fc_eval_gpn_ft(gpn_ft, max_entries);
+			ret = zfcp_fc_eval_gpn_ft(gpn_ft, adapter, max_entries);
 			if (ret == -EAGAIN)
 				ssleep(1);
 			else
@@ -704,174 +665,142 @@ int zfcp_fc_scan_ports(struct zfcp_adapt
 	zfcp_free_sg_env(gpn_ft, buf_num);
 out:
 	zfcp_fc_wka_port_put(&adapter->gs->ds);
-	return ret;
 }
 
-
-void _zfcp_fc_scan_ports_later(struct work_struct *work)
+static void zfcp_fc_ct_els_job_handler(void *data)
 {
-	zfcp_fc_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
-}
+	struct fc_bsg_job *job = data;
+	struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data;
+	struct fc_bsg_reply *jr = job->reply;
 
-struct zfcp_els_fc_job {
-	struct zfcp_send_els els;
-	struct fc_bsg_job *job;
-};
+	jr->reply_payload_rcv_len = job->reply_payload.payload_len;
+	jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+	jr->result = zfcp_ct_els->status ? -EIO : 0;
+	job->job_done(job);
+}
 
-static void zfcp_fc_generic_els_handler(unsigned long data)
+static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
 {
-	struct zfcp_els_fc_job *els_fc_job = (struct zfcp_els_fc_job *) data;
-	struct fc_bsg_job *job = els_fc_job->job;
-	struct fc_bsg_reply *reply = job->reply;
+	u32 preamble_word1;
+	u8 gs_type;
+	struct zfcp_adapter *adapter;
 
-	if (els_fc_job->els.status) {
-		/* request rejected or timed out */
-		reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_REJECT;
-		goto out;
-	}
+	preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
+	gs_type = (preamble_word1 & 0xff000000) >> 24;
 
-	reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
-	reply->reply_payload_rcv_len = job->reply_payload.payload_len;
+	adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
 
-out:
-	job->state_flags = FC_RQST_STATE_DONE;
-	job->job_done(job);
-	kfree(els_fc_job);
+	switch (gs_type) {
+	case FC_FST_ALIAS:
+		return &adapter->gs->as;
+	case FC_FST_MGMT:
+		return &adapter->gs->ms;
+	case FC_FST_TIME:
+		return &adapter->gs->ts;
+		break;
+	case FC_FST_DIR:
+		return &adapter->gs->ds;
+		break;
+	default:
+		return NULL;
+	}
 }
 
-int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
+static void zfcp_fc_ct_job_handler(void *data)
 {
-	struct zfcp_els_fc_job *els_fc_job;
-	struct fc_rport *rport = job->rport;
-	struct Scsi_Host *shost;
-	struct zfcp_adapter *adapter;
-	struct zfcp_port *port;
-	u8 *port_did;
+	struct fc_bsg_job *job = data;
+	struct zfcp_fc_wka_port *wka_port;
 
-	shost = rport ? rport_to_shost(rport) : job->shost;
-	adapter = (struct zfcp_adapter *)shost->hostdata[0];
+	wka_port = zfcp_fc_job_wka_port(job);
+	zfcp_fc_wka_port_put(wka_port);
 
-	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
-		return -EINVAL;
+	zfcp_fc_ct_els_job_handler(data);
+}
 
-	els_fc_job = kzalloc(sizeof(struct zfcp_els_fc_job), GFP_KERNEL);
-	if (!els_fc_job)
-		return -ENOMEM;
+static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
+				struct zfcp_adapter *adapter)
+{
+	struct zfcp_fsf_ct_els *els = job->dd_data;
+	struct fc_rport *rport = job->rport;
+	struct zfcp_port *port;
+	u32 d_id;
 
-	els_fc_job->els.adapter = adapter;
 	if (rport) {
-		read_lock_irq(&zfcp_data.config_lock);
 		port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
-		if (port)
-			els_fc_job->els.d_id = port->d_id;
-		read_unlock_irq(&zfcp_data.config_lock);
-		if (!port) {
-			kfree(els_fc_job);
+		if (!port)
 			return -EINVAL;
-		}
-	} else {
-		port_did = job->request->rqst_data.h_els.port_id;
-		els_fc_job->els.d_id = (port_did[0] << 16) +
-					(port_did[1] << 8) + port_did[2];
-	}
 
-	els_fc_job->els.req = job->request_payload.sg_list;
-	els_fc_job->els.resp = job->reply_payload.sg_list;
-	els_fc_job->els.handler = zfcp_fc_generic_els_handler;
-	els_fc_job->els.handler_data = (unsigned long) els_fc_job;
-	els_fc_job->job = job;
+		d_id = port->d_id;
+		put_device(&port->sysfs_device);
+	} else
+		d_id = ntoh24(job->request->rqst_data.h_els.port_id);
 
-	return zfcp_fsf_send_els(&els_fc_job->els);
+	els->handler = zfcp_fc_ct_els_job_handler;
+	return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
 }
 
-struct zfcp_ct_fc_job {
-	struct zfcp_send_ct ct;
-	struct fc_bsg_job *job;
-};
-
-static void zfcp_fc_generic_ct_handler(unsigned long data)
+static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
+			       struct zfcp_adapter *adapter)
 {
-	struct zfcp_ct_fc_job *ct_fc_job = (struct zfcp_ct_fc_job *) data;
-	struct fc_bsg_job *job = ct_fc_job->job;
+	int ret;
+	struct zfcp_fsf_ct_els *ct = job->dd_data;
+	struct zfcp_fc_wka_port *wka_port;
 
-	job->reply->reply_data.ctels_reply.status = ct_fc_job->ct.status ?
-				FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK;
-	job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
-	job->state_flags = FC_RQST_STATE_DONE;
-	job->job_done(job);
+	wka_port = zfcp_fc_job_wka_port(job);
+	if (!wka_port)
+		return -EINVAL;
 
-	zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
+	ret = zfcp_fc_wka_port_get(wka_port);
+	if (ret)
+		return ret;
 
-	kfree(ct_fc_job);
+	ct->handler = zfcp_fc_ct_job_handler;
+	ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ);
+	if (ret)
+		zfcp_fc_wka_port_put(wka_port);
+
+	return ret;
 }
 
-int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
+int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
 {
-	int ret;
-	u8 gs_type;
-	struct fc_rport *rport = job->rport;
 	struct Scsi_Host *shost;
 	struct zfcp_adapter *adapter;
-	struct zfcp_ct_fc_job *ct_fc_job;
-	u32 preamble_word1;
-
-	shost = rport ? rport_to_shost(rport) : job->shost;
+	struct zfcp_fsf_ct_els *ct_els = job->dd_data;
 
+	shost = job->rport ? rport_to_shost(job->rport) : job->shost;
 	adapter = (struct zfcp_adapter *)shost->hostdata[0];
+
 	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
 		return -EINVAL;
 
-	ct_fc_job = kzalloc(sizeof(struct zfcp_ct_fc_job), GFP_KERNEL);
-	if (!ct_fc_job)
-		return -ENOMEM;
-
-	preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
-	gs_type = (preamble_word1 & 0xff000000) >> 24;
+	ct_els->req = job->request_payload.sg_list;
+	ct_els->resp = job->reply_payload.sg_list;
+	ct_els->handler_data = job;
 
-	switch (gs_type) {
-	case FC_FST_ALIAS:
-		ct_fc_job->ct.wka_port = &adapter->gs->as;
-		break;
-	case FC_FST_MGMT:
-		ct_fc_job->ct.wka_port = &adapter->gs->ms;
-		break;
-	case FC_FST_TIME:
-		ct_fc_job->ct.wka_port = &adapter->gs->ts;
-		break;
-	case FC_FST_DIR:
-		ct_fc_job->ct.wka_port = &adapter->gs->ds;
-		break;
+	switch (job->request->msgcode) {
+	case FC_BSG_RPT_ELS:
+	case FC_BSG_HST_ELS_NOLOGIN:
+		return zfcp_fc_exec_els_job(job, adapter);
+	case FC_BSG_RPT_CT:
+	case FC_BSG_HST_CT:
+		return zfcp_fc_exec_ct_job(job, adapter);
 	default:
-		kfree(ct_fc_job);
-		return -EINVAL; /* no such service */
-	}
-
-	ret = zfcp_fc_wka_port_get(ct_fc_job->ct.wka_port);
-	if (ret) {
-		kfree(ct_fc_job);
-		return ret;
+		return -EINVAL;
 	}
+}
 
-	ct_fc_job->ct.req = job->request_payload.sg_list;
-	ct_fc_job->ct.resp = job->reply_payload.sg_list;
-	ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler;
-	ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job;
-	ct_fc_job->ct.completion = NULL;
-	ct_fc_job->job = job;
-
-	ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL);
-	if (ret) {
-		kfree(ct_fc_job);
-		zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
-	}
-	return ret;
+int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job)
+{
+	/* hardware tracks timeout, reset bsg timeout to not interfere */
+	return -EAGAIN;
 }
 
 int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
 {
-	struct zfcp_wka_ports *wka_ports;
+	struct zfcp_fc_wka_ports *wka_ports;
 
-	wka_ports = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL);
+	wka_ports = kzalloc(sizeof(struct zfcp_fc_wka_ports), GFP_KERNEL);
 	if (!wka_ports)
 		return -ENOMEM;
 
@@ -880,7 +809,6 @@ int zfcp_fc_gs_setup(struct zfcp_adapter
 	zfcp_fc_wka_port_init(&wka_ports->ts, FC_FID_TIME_SERV, adapter);
 	zfcp_fc_wka_port_init(&wka_ports->ds, FC_FID_DIR_SERV, adapter);
 	zfcp_fc_wka_port_init(&wka_ports->as, FC_FID_ALIASES, adapter);
-	zfcp_fc_wka_port_init(&wka_ports->ks, FC_FID_SEC_KEY, adapter);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fc.h linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.h
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,262 @@
+/*
+ * zfcp device driver
+ *
+ * Fibre Channel related definitions and inline functions for the zfcp
+ * device driver
+ *
+ * Copyright IBM Corporation 2009
+ */
+
+#ifndef ZFCP_FC_H
+#define ZFCP_FC_H
+
+#include <scsi/fc/fc_els.h>
+#include <scsi/fc/fc_fcp.h>
+#include <scsi/fc/fc_ns.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include "zfcp_fsf.h"
+
+#define ZFCP_FC_CT_SIZE_PAGE	  (PAGE_SIZE - sizeof(struct fc_ct_hdr))
+#define ZFCP_FC_GPN_FT_ENT_PAGE	  (ZFCP_FC_CT_SIZE_PAGE \
+					/ sizeof(struct fc_gpn_ft_resp))
+#define ZFCP_FC_GPN_FT_NUM_BUFS	  4 /* memory pages */
+
+#define ZFCP_FC_GPN_FT_MAX_SIZE	  (ZFCP_FC_GPN_FT_NUM_BUFS * PAGE_SIZE \
+					- sizeof(struct fc_ct_hdr))
+#define ZFCP_FC_GPN_FT_MAX_ENT	  (ZFCP_FC_GPN_FT_NUM_BUFS * \
+					(ZFCP_FC_GPN_FT_ENT_PAGE + 1))
+
+#define ZFCP_FC_CTELS_TMO	(2 * FC_DEF_R_A_TOV / 1000)
+
+/**
+ * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
+ * @ct_hdr: FC GS common transport header
+ * @gid_pn: GID_PN request
+ */
+struct zfcp_fc_gid_pn_req {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_ns_gid_pn	gid_pn;
+} __packed;
+
+/**
+ * struct zfcp_fc_gid_pn_resp - container for ct header plus gid_pn response
+ * @ct_hdr: FC GS common transport header
+ * @gid_pn: GID_PN response
+ */
+struct zfcp_fc_gid_pn_resp {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_gid_pn_resp	gid_pn;
+} __packed;
+
+/**
+ * struct zfcp_fc_gid_pn - everything required in zfcp for gid_pn request
+ * @ct: data passed to zfcp_fsf for issuing fsf request
+ * @sg_req: scatterlist entry for request data
+ * @sg_resp: scatterlist entry for response data
+ * @gid_pn_req: GID_PN request data
+ * @gid_pn_resp: GID_PN response data
+ */
+struct zfcp_fc_gid_pn {
+	struct zfcp_fsf_ct_els ct;
+	struct scatterlist sg_req;
+	struct scatterlist sg_resp;
+	struct zfcp_fc_gid_pn_req gid_pn_req;
+	struct zfcp_fc_gid_pn_resp gid_pn_resp;
+	struct zfcp_port *port;
+};
+
+/**
+ * struct zfcp_fc_gpn_ft - container for ct header plus gpn_ft request
+ * @ct_hdr: FC GS common transport header
+ * @gpn_ft: GPN_FT request
+ */
+struct zfcp_fc_gpn_ft_req {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_ns_gid_ft	gpn_ft;
+} __packed;
+
+/**
+ * struct zfcp_fc_gpn_ft_resp - container for ct header plus gpn_ft response
+ * @ct_hdr: FC GS common transport header
+ * @gpn_ft: Array of gpn_ft response data to fill one memory page
+ */
+struct zfcp_fc_gpn_ft_resp {
+	struct fc_ct_hdr	ct_hdr;
+	struct fc_gpn_ft_resp	gpn_ft[ZFCP_FC_GPN_FT_ENT_PAGE];
+} __packed;
+
+/**
+ * struct zfcp_fc_gpn_ft - zfcp data for gpn_ft request
+ * @ct: data passed to zfcp_fsf for issuing fsf request
+ * @sg_req: scatter list entry for gpn_ft request
+ * @sg_resp: scatter list entries for gpn_ft responses (per memory page)
+ */
+struct zfcp_fc_gpn_ft {
+	struct zfcp_fsf_ct_els ct;
+	struct scatterlist sg_req;
+	struct scatterlist sg_resp[ZFCP_FC_GPN_FT_NUM_BUFS];
+};
+
+/**
+ * struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC
+ * @els: data required for issuing els fsf command
+ * @req: scatterlist entry for ELS ADISC request
+ * @resp: scatterlist entry for ELS ADISC response
+ * @adisc_req: ELS ADISC request data
+ * @adisc_resp: ELS ADISC response data
+ */
+struct zfcp_fc_els_adisc {
+	struct zfcp_fsf_ct_els els;
+	struct scatterlist req;
+	struct scatterlist resp;
+	struct fc_els_adisc adisc_req;
+	struct fc_els_adisc adisc_resp;
+};
+
+/**
+ * enum zfcp_fc_wka_status - FC WKA port status in zfcp
+ * @ZFCP_FC_WKA_PORT_OFFLINE: Port is closed and not in use
+ * @ZFCP_FC_WKA_PORT_CLOSING: The FSF "close port" request is pending
+ * @ZFCP_FC_WKA_PORT_OPENING: The FSF "open port" request is pending
+ * @ZFCP_FC_WKA_PORT_ONLINE: The port is open and the port handle is valid
+ */
+enum zfcp_fc_wka_status {
+	ZFCP_FC_WKA_PORT_OFFLINE,
+	ZFCP_FC_WKA_PORT_CLOSING,
+	ZFCP_FC_WKA_PORT_OPENING,
+	ZFCP_FC_WKA_PORT_ONLINE,
+};
+
+/**
+ * struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port
+ * @adapter: Pointer to adapter structure this WKA port belongs to
+ * @completion_wq: Wait for completion of open/close command
+ * @status: Current status of WKA port
+ * @refcount: Reference count to keep port open as long as it is in use
+ * @d_id: FC destination id or well-known-address
+ * @handle: FSF handle for the open WKA port
+ * @mutex: Mutex used during opening/closing state changes
+ * @work: For delaying the closing of the WKA port
+ */
+struct zfcp_fc_wka_port {
+	struct zfcp_adapter	*adapter;
+	wait_queue_head_t	completion_wq;
+	enum zfcp_fc_wka_status	status;
+	atomic_t		refcount;
+	u32			d_id;
+	u32			handle;
+	struct mutex		mutex;
+	struct delayed_work	work;
+};
+
+/**
+ * struct zfcp_fc_wka_ports - Data structures for FC generic services
+ * @ms: FC Management service
+ * @ts: FC time service
+ * @ds: FC directory service
+ * @as: FC alias service
+ */
+struct zfcp_fc_wka_ports {
+	struct zfcp_fc_wka_port ms;
+	struct zfcp_fc_wka_port ts;
+	struct zfcp_fc_wka_port ds;
+	struct zfcp_fc_wka_port as;
+};
+
+/**
+ * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
+ * @fcp: fcp_cmnd to setup
+ * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
+ */
+static inline
+void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
+{
+	char tag[2];
+
+	int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
+
+	if (scsi_populate_tag_msg(scsi, tag)) {
+		switch (tag[0]) {
+		case MSG_ORDERED_TAG:
+			fcp->fc_pri_ta |= FCP_PTA_ORDERED;
+			break;
+		case MSG_SIMPLE_TAG:
+			fcp->fc_pri_ta |= FCP_PTA_SIMPLE;
+			break;
+		};
+	} else
+		fcp->fc_pri_ta = FCP_PTA_SIMPLE;
+
+	if (scsi->sc_data_direction == DMA_FROM_DEVICE)
+		fcp->fc_flags |= FCP_CFL_RDDATA;
+	if (scsi->sc_data_direction == DMA_TO_DEVICE)
+		fcp->fc_flags |= FCP_CFL_WRDATA;
+
+	memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
+
+	fcp->fc_dl = scsi_bufflen(scsi);
+}
+
+/**
+ * zfcp_fc_fcp_tm - setup FCP command as task management command
+ * @fcp: fcp_cmnd to setup
+ * @dev: scsi_device where to send the task management command
+ * @tm: task management flags to setup tm command
+ */
+static inline
+void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
+{
+	int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
+	fcp->fc_tm_flags |= tm_flags;
+}
+
+/**
+ * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
+ * @fcp_rsp: FCP RSP IU to evaluate
+ * @scsi: SCSI command where to update status and sense buffer
+ */
+static inline
+void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
+			  struct scsi_cmnd *scsi)
+{
+	struct fcp_resp_rsp_info *rsp_info;
+	char *sense;
+	u32 sense_len, resid;
+	u8 rsp_flags;
+
+	set_msg_byte(scsi, COMMAND_COMPLETE);
+	scsi->result |= fcp_rsp->resp.fr_status;
+
+	rsp_flags = fcp_rsp->resp.fr_flags;
+
+	if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
+		rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+		if (rsp_info->rsp_code == FCP_TMF_CMPL)
+			set_host_byte(scsi, DID_OK);
+		else {
+			set_host_byte(scsi, DID_ERROR);
+			return;
+		}
+	}
+
+	if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
+		sense = (char *) &fcp_rsp[1];
+		if (rsp_flags & FCP_RSP_LEN_VAL)
+			sense += fcp_rsp->ext.fr_sns_len;
+		sense_len = min(fcp_rsp->ext.fr_sns_len,
+				(u32) SCSI_SENSE_BUFFERSIZE);
+		memcpy(scsi->sense_buffer, sense, sense_len);
+	}
+
+	if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
+		resid = fcp_rsp->ext.fr_resid;
+		scsi_set_resid(scsi, resid);
+		if (scsi_bufflen(scsi) - resid < scsi->underflow &&
+		     !(rsp_flags & FCP_SNS_LEN_VAL) &&
+		     fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+			set_host_byte(scsi, DID_ERROR);
+	}
+}
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fsf.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fsf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,9 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/blktrace_api.h>
+#include <scsi/fc/fc_els.h>
 #include "zfcp_ext.h"
+#include "zfcp_fc.h"
 #include "zfcp_dbf.h"
 
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
@@ -122,36 +124,32 @@ void zfcp_fsf_req_free(struct zfcp_fsf_r
 
 static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
 {
+	unsigned long flags;
 	struct fsf_status_read_buffer *sr_buf = req->data;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct zfcp_port *port;
-	int d_id = sr_buf->d_id & ZFCP_DID_MASK;
-	unsigned long flags;
+	int d_id = ntoh24(sr_buf->d_id);
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		if (port->d_id == d_id) {
-			read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 			zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
-			return;
+			break;
 		}
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
 					 struct fsf_link_down_info *link_down)
 {
 	struct zfcp_adapter *adapter = req->adapter;
-	unsigned long flags;
 
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED)
 		return;
 
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	zfcp_scsi_schedule_rports_block(adapter);
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 	if (!link_down)
 		goto out;
@@ -291,7 +289,7 @@ static void zfcp_fsf_status_read_handler
 			zfcp_erp_adapter_access_changed(adapter, "fssrh_3",
 							req);
 		if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
-			schedule_work(&adapter->scan_work);
+			queue_work(adapter->work_queue, &adapter->scan_work);
 		break;
 	case FSF_STATUS_READ_CFDC_UPDATED:
 		zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req);
@@ -317,7 +315,6 @@ static void zfcp_fsf_fsfstatus_qual_eval
 	case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		return;
 	case FSF_SQ_COMMAND_ABORTED:
-		req->status |= ZFCP_STATUS_FSFREQ_ABORTED;
 		break;
 	case FSF_SQ_NO_RECOM:
 		dev_err(&req->adapter->ccw_device->dev,
@@ -358,8 +355,7 @@ static void zfcp_fsf_protstatus_eval(str
 	zfcp_dbf_hba_fsf_response(req);
 
 	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		return;
 	}
 
@@ -377,7 +373,7 @@ static void zfcp_fsf_protstatus_eval(str
 	case FSF_PROT_ERROR_STATE:
 	case FSF_PROT_SEQ_NUMB_ERROR:
 		zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_PROT_UNSUPP_QTCB_TYPE:
 		dev_err(&adapter->ccw_device->dev,
@@ -480,20 +476,27 @@ void zfcp_fsf_req_dismiss_all(struct zfc
 
 static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
 {
-	struct fsf_qtcb_bottom_config *bottom;
+	struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
 	struct zfcp_adapter *adapter = req->adapter;
 	struct Scsi_Host *shost = adapter->scsi_host;
+	struct fc_els_flogi *nsp, *plogi;
 
-	bottom = &req->qtcb->bottom.config;
+	/* adjust pointers for missing command code */
+	nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param
+					- sizeof(u32));
+	plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload
+					- sizeof(u32));
 
 	if (req->data)
 		memcpy(req->data, bottom, sizeof(*bottom));
 
-	fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
-	fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
-	fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
+	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) = bottom->fc_link_speed;
 	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+	fc_host_supported_fc4s(shost)[2] = 1; /* FCP */
+	fc_host_active_fc4s(shost)[2] = 1; /* FCP */
 
 	adapter->hydra_version = bottom->adapter_type;
 	adapter->timer_ticks = bottom->timer_interval;
@@ -503,9 +506,9 @@ static int zfcp_fsf_exchange_config_eval
 
 	switch (bottom->fc_topology) {
 	case FSF_TOPO_P2P:
-		adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
-		adapter->peer_wwpn = bottom->plogi_payload.wwpn;
-		adapter->peer_wwnn = bottom->plogi_payload.wwnn;
+		adapter->peer_d_id = ntoh24(bottom->peer_d_id);
+		adapter->peer_wwpn = plogi->fl_wwpn;
+		adapter->peer_wwnn = plogi->fl_wwnn;
 		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
 		break;
 	case FSF_TOPO_FABRIC:
@@ -881,13 +884,11 @@ static void zfcp_fsf_abort_fcp_command_h
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fsafch3", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_BOXED:
 		zfcp_erp_unit_boxed(unit, "fsafch4", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                 break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (fsq->word[0]) {
@@ -958,10 +959,10 @@ out:
 static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
 {
 	struct zfcp_adapter *adapter = req->adapter;
-	struct zfcp_send_ct *send_ct = req->data;
+	struct zfcp_fsf_ct_els *ct = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
-	send_ct->status = -EINVAL;
+	ct->status = -EINVAL;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		goto skip_fsfstatus;
@@ -969,7 +970,7 @@ static void zfcp_fsf_send_ct_handler(str
 	switch (header->fsf_status) {
         case FSF_GOOD:
 		zfcp_dbf_san_ct_response(req);
-		send_ct->status = 0;
+		ct->status = 0;
 		break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
 		zfcp_fsf_class_not_supp(req);
@@ -985,8 +986,7 @@ static void zfcp_fsf_send_ct_handler(str
 	case FSF_ACCESS_DENIED:
 		break;
         case FSF_PORT_BOXED:
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_PORT_HANDLE_NOT_VALID:
 		zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
@@ -1001,8 +1001,8 @@ static void zfcp_fsf_send_ct_handler(str
 	}
 
 skip_fsfstatus:
-	if (send_ct->handler)
-		send_ct->handler(send_ct->handler_data);
+	if (ct->handler)
+		ct->handler(ct->handler_data);
 }
 
 static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
@@ -1068,7 +1068,7 @@ static int zfcp_fsf_setup_ct_els_sbals(s
 static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
 				 struct scatterlist *sg_req,
 				 struct scatterlist *sg_resp,
-				 int max_sbals)
+				 int max_sbals, unsigned int timeout)
 {
 	int ret;
 
@@ -1077,9 +1077,11 @@ static int zfcp_fsf_setup_ct_els(struct
 		return ret;
 
 	/* common settings for ct/gs and els requests */
+	if (timeout > 255)
+		timeout = 255; /* max value accepted by hardware */
 	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
-	req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
-	zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);
+	req->qtcb->bottom.support.timeout = timeout;
+	zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
 
 	return 0;
 }
@@ -1089,9 +1091,10 @@ static int zfcp_fsf_setup_ct_els(struct
  * @ct: pointer to struct zfcp_send_ct with data for request
  * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
  */
-int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
+int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
+		     struct zfcp_fsf_ct_els *ct, mempool_t *pool,
+		     unsigned int timeout)
 {
-	struct zfcp_wka_port *wka_port = ct->wka_port;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int ret = -EIO;
@@ -1109,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
 	ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
-				    FSF_MAX_SBALS_PER_REQ);
+				    FSF_MAX_SBALS_PER_REQ, timeout);
 	if (ret)
 		goto failed_send;
 
@@ -1117,7 +1120,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct
 	req->qtcb->header.port_handle = wka_port->handle;
 	req->data = ct;
 
-	zfcp_dbf_san_ct_request(req);
+	zfcp_dbf_san_ct_request(req, wka_port->d_id);
 
 	ret = zfcp_fsf_req_send(req);
 	if (ret)
@@ -1134,7 +1137,7 @@ out:
 
 static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_send_els *send_els = req->data;
+	struct zfcp_fsf_ct_els *send_els = req->data;
 	struct zfcp_port *port = send_els->port;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
@@ -1154,9 +1157,6 @@ static void zfcp_fsf_send_els_handler(st
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]){
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
-				zfcp_fc_test_link(port);
-			/*fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_RETRY_IF_POSSIBLE:
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1188,10 +1188,11 @@ skip_fsfstatus:
  * zfcp_fsf_send_els - initiate an ELS command (FC-FS)
  * @els: pointer to struct zfcp_send_els with data for the command
  */
-int zfcp_fsf_send_els(struct zfcp_send_els *els)
+int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
+		      struct zfcp_fsf_ct_els *els, unsigned int timeout)
 {
 	struct zfcp_fsf_req *req;
-	struct zfcp_qdio *qdio = els->adapter->qdio;
+	struct zfcp_qdio *qdio = adapter->qdio;
 	int ret = -EIO;
 
 	spin_lock_bh(&qdio->req_q_lock);
@@ -1206,12 +1207,12 @@ int zfcp_fsf_send_els(struct zfcp_send_e
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
+	ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout);
 
 	if (ret)
 		goto failed_send;
 
-	req->qtcb->bottom.support.d_id = els->d_id;
+	hton24(req->qtcb->bottom.support.d_id, d_id);
 	req->handler = zfcp_fsf_send_els_handler;
 	req->data = els;
 
@@ -1422,7 +1423,7 @@ static void zfcp_fsf_open_port_handler(s
 {
 	struct zfcp_port *port = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
-	struct fsf_plogi *plogi;
+	struct fc_els_flogi *plogi;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		goto out;
@@ -1472,23 +1473,10 @@ static void zfcp_fsf_open_port_handler(s
 		 * another GID_PN straight after a port has been opened.
 		 * Alternately, an ADISC/PDISC ELS should suffice, as well.
 		 */
-		plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
+		plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els;
 		if (req->qtcb->bottom.support.els1_length >=
-		    FSF_PLOGI_MIN_LEN) {
-			if (plogi->serv_param.wwpn != port->wwpn) {
-				port->d_id = 0;
-				dev_warn(&port->adapter->ccw_device->dev,
-					 "A port opened with WWPN 0x%016Lx "
-					 "returned data that identifies it as "
-					 "WWPN 0x%016Lx\n",
-					 (unsigned long long) port->wwpn,
-					 (unsigned long long)
-					  plogi->serv_param.wwpn);
-			} else {
-				port->wwnn = plogi->serv_param.wwnn;
+		    FSF_PLOGI_MIN_LEN)
 				zfcp_fc_plogi_evaluate(port, plogi);
-			}
-		}
 		break;
 	case FSF_UNKNOWN_OP_SUBTYPE:
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1496,7 +1484,7 @@ static void zfcp_fsf_open_port_handler(s
 	}
 
 out:
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 /**
@@ -1530,18 +1518,18 @@ int zfcp_fsf_open_port(struct zfcp_erp_a
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_open_port_handler;
-	req->qtcb->bottom.support.d_id = port->d_id;
+	hton24(req->qtcb->bottom.support.d_id, port->d_id);
 	req->data = port;
 	req->erp_action = erp_action;
 	erp_action->fsf_req = req;
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 
 	zfcp_fsf_start_erp_timer(req);
 	retval = zfcp_fsf_req_send(req);
 	if (retval) {
 		zfcp_fsf_req_free(req);
 		erp_action->fsf_req = NULL;
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 	}
 out:
 	spin_unlock_bh(&qdio->req_q_lock);
@@ -1618,11 +1606,11 @@ out:
 
 static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_wka_port *wka_port = req->data;
+	struct zfcp_fc_wka_port *wka_port = req->data;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		goto out;
 	}
 
@@ -1635,13 +1623,13 @@ static void zfcp_fsf_open_wka_port_handl
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		/* fall through */
 	case FSF_ACCESS_DENIED:
-		wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		break;
 	case FSF_GOOD:
 		wka_port->handle = header->port_handle;
 		/* fall through */
 	case FSF_PORT_ALREADY_OPEN:
-		wka_port->status = ZFCP_WKA_PORT_ONLINE;
+		wka_port->status = ZFCP_FC_WKA_PORT_ONLINE;
 	}
 out:
 	wake_up(&wka_port->completion_wq);
@@ -1649,10 +1637,10 @@ out:
 
 /**
  * zfcp_fsf_open_wka_port - create and send open wka-port request
- * @wka_port: pointer to struct zfcp_wka_port
+ * @wka_port: pointer to struct zfcp_fc_wka_port
  * Returns: 0 on success, error otherwise
  */
-int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
+int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1677,7 +1665,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_w
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_open_wka_port_handler;
-	req->qtcb->bottom.support.d_id = wka_port->d_id;
+	hton24(req->qtcb->bottom.support.d_id, wka_port->d_id);
 	req->data = wka_port;
 
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
@@ -1691,23 +1679,23 @@ out:
 
 static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
 {
-	struct zfcp_wka_port *wka_port = req->data;
+	struct zfcp_fc_wka_port *wka_port = req->data;
 
 	if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
 	}
 
-	wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 	wake_up(&wka_port->completion_wq);
 }
 
 /**
  * zfcp_fsf_close_wka_port - create and send close wka port request
- * @erp_action: pointer to struct zfcp_erp_action
+ * @wka_port: WKA port to open
  * Returns: 0 on success, error otherwise
  */
-int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
+int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1765,13 +1753,13 @@ static void zfcp_fsf_close_physical_port
 		/* can't use generic zfcp_erp_modify_port_status because
 		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
 		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
 			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
 					  &unit->status);
+		read_unlock(&port->unit_list_lock);
 		zfcp_erp_port_boxed(port, "fscpph2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
-
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]) {
@@ -1787,9 +1775,11 @@ static void zfcp_fsf_close_physical_port
 		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port
 		 */
 		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
-		list_for_each_entry(unit, &port->unit_list_head, list)
+		read_lock(&port->unit_list_lock);
+		list_for_each_entry(unit, &port->unit_list, list)
 			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
 					  &unit->status);
+		read_unlock(&port->unit_list_lock);
 		break;
 	}
 }
@@ -1873,8 +1863,7 @@ static void zfcp_fsf_open_unit_handler(s
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fsouh_2", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_SHARING_VIOLATION:
 		if (header->fsf_status_qual.word[0])
@@ -2036,8 +2025,7 @@ static void zfcp_fsf_close_unit_handler(
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fscuh_3", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (req->qtcb->header.fsf_status_qual.word[0]) {
@@ -2109,72 +2097,57 @@ static void zfcp_fsf_update_lat(struct f
 	lat_rec->max = max(lat_rec->max, lat);
 }
 
-static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
+static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
 {
-	struct fsf_qual_latency_info *lat_inf;
-	struct latency_cont *lat;
+	struct fsf_qual_latency_info *lat_in;
+	struct latency_cont *lat = NULL;
 	struct zfcp_unit *unit = req->unit;
+	struct zfcp_blk_drv_data blktrc;
+	int ticks = req->adapter->timer_ticks;
 
-	lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info;
+	lat_in = &req->qtcb->prefix.prot_status_qual.latency_info;
 
-	switch (req->qtcb->bottom.io.data_direction) {
-	case FSF_DATADIR_READ:
-		lat = &unit->latencies.read;
-		break;
-	case FSF_DATADIR_WRITE:
-		lat = &unit->latencies.write;
-		break;
-	case FSF_DATADIR_CMND:
-		lat = &unit->latencies.cmd;
-		break;
-	default:
-		return;
-	}
+	blktrc.flags = 0;
+	blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC;
+	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
+		blktrc.flags |= ZFCP_BLK_REQ_ERROR;
+	blktrc.inb_usage = req->queue_req.qdio_inb_usage;
+	blktrc.outb_usage = req->queue_req.qdio_outb_usage;
 
-	spin_lock(&unit->latencies.lock);
-	zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat);
-	zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat);
-	lat->counter++;
-	spin_unlock(&unit->latencies.lock);
-}
+	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+		blktrc.flags |= ZFCP_BLK_LAT_VALID;
+		blktrc.channel_lat = lat_in->channel_lat * ticks;
+		blktrc.fabric_lat = lat_in->fabric_lat * ticks;
 
-#ifdef CONFIG_BLK_DEV_IO_TRACE
-static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
-{
-	struct fsf_qual_latency_info *lat_inf;
-	struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
-	struct request *req = scsi_cmnd->request;
-	struct zfcp_blk_drv_data trace;
-	int ticks = fsf_req->adapter->timer_ticks;
+		switch (req->qtcb->bottom.io.data_direction) {
+		case FSF_DATADIR_READ:
+			lat = &unit->latencies.read;
+			break;
+		case FSF_DATADIR_WRITE:
+			lat = &unit->latencies.write;
+			break;
+		case FSF_DATADIR_CMND:
+			lat = &unit->latencies.cmd;
+			break;
+		}
 
-	trace.flags = 0;
-	trace.magic = ZFCP_BLK_DRV_DATA_MAGIC;
-	if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
-		trace.flags |= ZFCP_BLK_LAT_VALID;
-		lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
-		trace.channel_lat = lat_inf->channel_lat * ticks;
-		trace.fabric_lat = lat_inf->fabric_lat * ticks;
+		if (lat) {
+			spin_lock(&unit->latencies.lock);
+			zfcp_fsf_update_lat(&lat->channel, lat_in->channel_lat);
+			zfcp_fsf_update_lat(&lat->fabric, lat_in->fabric_lat);
+			lat->counter++;
+			spin_unlock(&unit->latencies.lock);
+		}
 	}
-	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
-		trace.flags |= ZFCP_BLK_REQ_ERROR;
-	trace.inb_usage = fsf_req->queue_req.qdio_inb_usage;
-	trace.outb_usage = fsf_req->queue_req.qdio_outb_usage;
 
-	blk_add_driver_data(req->q, req, &trace, sizeof(trace));
-}
-#else
-static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
-{
+	blk_add_driver_data(scsi->request->q, scsi->request, &blktrc,
+			    sizeof(blktrc));
 }
-#endif
 
 static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
 {
 	struct scsi_cmnd *scpnt;
-	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
-	    &(req->qtcb->bottom.io.fcp_rsp);
-	u32 sns_len;
-	char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
+	struct fcp_resp_with_ext *fcp_rsp;
 	unsigned long flags;
 
 	read_lock_irqsave(&req->adapter->abort_lock, flags);
@@ -2185,50 +2158,16 @@ static void zfcp_fsf_send_fcp_command_ta
 		return;
 	}
 
-	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) {
-		set_host_byte(scpnt, DID_SOFT_ERROR);
-		goto skip_fsfstatus;
-	}
-
 	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
-		set_host_byte(scpnt, DID_ERROR);
+		set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
 		goto skip_fsfstatus;
 	}
 
-	set_msg_byte(scpnt, COMMAND_COMPLETE);
-
-	scpnt->result |= fcp_rsp_iu->scsi_status;
-
-	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
-		zfcp_fsf_req_latency(req);
-
-	zfcp_fsf_trace_latency(req);
-
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
-		if (fcp_rsp_info[3] == RSP_CODE_GOOD)
-			set_host_byte(scpnt, DID_OK);
-		else {
-			set_host_byte(scpnt, DID_ERROR);
-			goto skip_fsfstatus;
-		}
-	}
-
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) {
-		sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) +
-			  fcp_rsp_iu->fcp_rsp_len;
-		sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE);
-		sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len);
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
 
-		memcpy(scpnt->sense_buffer,
-		       zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len);
-	}
+	zfcp_fsf_req_trace(req, scpnt);
 
-	if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) {
-		scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid);
-		if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) <
-		    scpnt->underflow)
-			set_host_byte(scpnt, DID_ERROR);
-	}
 skip_fsfstatus:
 	if (scpnt->result != 0)
 		zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req);
@@ -2250,11 +2189,13 @@ skip_fsfstatus:
 
 static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req)
 {
-	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
-	    &(req->qtcb->bottom.io.fcp_rsp);
-	char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
+	struct fcp_resp_with_ext *fcp_rsp;
+	struct fcp_resp_rsp_info *rsp_info;
 
-	if ((fcp_rsp_info[3] != RSP_CODE_GOOD) ||
+	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
+	rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
+
+	if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
 	     (req->status & ZFCP_STATUS_FSFREQ_ERROR))
 		req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
 }
@@ -2314,13 +2255,11 @@ static void zfcp_fsf_send_fcp_command_ha
 		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_port_boxed(unit->port, "fssfch5", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_BOXED:
 		zfcp_erp_unit_boxed(unit, "fssfch6", req);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
-			       ZFCP_STATUS_FSFREQ_RETRY;
+		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		if (header->fsf_status_qual.word[0] ==
@@ -2335,24 +2274,10 @@ skip_fsfstatus:
 	else {
 		zfcp_fsf_send_fcp_command_task_handler(req);
 		req->unit = NULL;
-		zfcp_unit_put(unit);
+		put_device(&unit->sysfs_device);
 	}
 }
 
-static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
-{
-	u32 *fcp_dl_ptr;
-
-	/*
-	 * fcp_dl_addr = start address of fcp_cmnd structure +
-	 * size of fixed part + size of dynamically sized add_dcp_cdb field
-	 * SEE FCP-2 documentation
-	 */
-	fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] +
-			(fcp_cmd->add_fcp_cdb_length << 2));
-	*fcp_dl_ptr = fcp_dl;
-}
-
 /**
  * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
  * @unit: unit where command is sent to
@@ -2362,7 +2287,7 @@ int zfcp_fsf_send_fcp_command_task(struc
 				   struct scsi_cmnd *scsi_cmnd)
 {
 	struct zfcp_fsf_req *req;
-	struct fcp_cmnd_iu *fcp_cmnd_iu;
+	struct fcp_cmnd *fcp_cmnd;
 	unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
 	int real_bytes, retval = -EIO;
 	struct zfcp_adapter *adapter = unit->port->adapter;
@@ -2387,23 +2312,21 @@ int zfcp_fsf_send_fcp_command_task(struc
 	}
 
 	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-	zfcp_unit_get(unit);
+	get_device(&unit->sysfs_device);
 	req->unit = unit;
 	req->data = scsi_cmnd;
 	req->handler = zfcp_fsf_send_fcp_command_handler;
 	req->qtcb->header.lun_handle = unit->handle;
 	req->qtcb->header.port_handle = unit->port->handle;
 	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
+	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
 
 	scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
 
-	fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd);
-	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
 	/*
 	 * set depending on data direction:
 	 *      data direction bits in SBALE (SB Type)
 	 *      data direction bits in QTCB
-	 *      data direction bits in FCP_CMND IU
 	 */
 	switch (scsi_cmnd->sc_data_direction) {
 	case DMA_NONE:
@@ -2411,32 +2334,17 @@ int zfcp_fsf_send_fcp_command_task(struc
 		break;
 	case DMA_FROM_DEVICE:
 		req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
-		fcp_cmnd_iu->rddata = 1;
 		break;
 	case DMA_TO_DEVICE:
 		req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
 		sbtype = SBAL_FLAGS0_TYPE_WRITE;
-		fcp_cmnd_iu->wddata = 1;
 		break;
 	case DMA_BIDIRECTIONAL:
 		goto failed_scsi_cmnd;
 	}
 
-	if (likely((scsi_cmnd->device->simple_tags) ||
-		   ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) &&
-		    (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED))))
-		fcp_cmnd_iu->task_attribute = SIMPLE_Q;
-	else
-		fcp_cmnd_iu->task_attribute = UNTAGGED;
-
-	if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH))
-		fcp_cmnd_iu->add_fcp_cdb_length =
-			(scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2;
-
-	memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
-
-	req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
-		fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
+	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
+	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
 
 	real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype,
 					     scsi_sglist(scsi_cmnd),
@@ -2454,8 +2362,6 @@ int zfcp_fsf_send_fcp_command_task(struc
 		goto failed_scsi_cmnd;
 	}
 
-	zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);
-
 	retval = zfcp_fsf_req_send(req);
 	if (unlikely(retval))
 		goto failed_scsi_cmnd;
@@ -2463,7 +2369,7 @@ int zfcp_fsf_send_fcp_command_task(struc
 	goto out;
 
 failed_scsi_cmnd:
-	zfcp_unit_put(unit);
+	put_device(&unit->sysfs_device);
 	zfcp_fsf_req_free(req);
 	scsi_cmnd->host_scribble = NULL;
 out:
@@ -2481,7 +2387,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_c
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
-	struct fcp_cmnd_iu *fcp_cmnd_iu;
+	struct fcp_cmnd *fcp_cmnd;
 	struct zfcp_qdio *qdio = unit->port->adapter->qdio;
 
 	if (unlikely(!(atomic_read(&unit->status) &
@@ -2507,16 +2413,14 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_c
 	req->qtcb->header.port_handle = unit->port->handle;
 	req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
 	req->qtcb->bottom.io.service_class = FSF_CLASS_3;
-	req->qtcb->bottom.io.fcp_cmnd_length = 	sizeof(struct fcp_cmnd_iu) +
-						sizeof(u32);
+	req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
 
 	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-	fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd;
-	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
-	fcp_cmnd_iu->task_management_flags = tm_flags;
+	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
+	zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags);
 
 	zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
 	if (!zfcp_fsf_req_send(req))
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fsf.h linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.h
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_fsf.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_fsf.h	2010-02-24 13:52:17.000000000 -0500
@@ -11,6 +11,7 @@
 
 #include <linux/pfn.h>
 #include <linux/scatterlist.h>
+#include <scsi/libfc.h>
 
 #define FSF_QTCB_CURRENT_VERSION		0x00000001
 
@@ -228,7 +229,8 @@ struct fsf_status_read_buffer {
 	u32 length;
 	u32 res1;
 	struct fsf_queue_designator queue_designator;
-	u32 d_id;
+	u8 res2;
+	u8 d_id[3];
 	u32 class;
 	u64 fcp_lun;
 	u8  res3[24];
@@ -309,22 +311,7 @@ struct fsf_qtcb_header {
 	u8  res4[16];
 } __attribute__ ((packed));
 
-struct fsf_nport_serv_param {
-	u8  common_serv_param[16];
-	u64 wwpn;
-	u64 wwnn;
-	u8  class1_serv_param[16];
-	u8  class2_serv_param[16];
-	u8  class3_serv_param[16];
-	u8  class4_serv_param[16];
-	u8  vendor_version_level[16];
-} __attribute__ ((packed));
-
 #define FSF_PLOGI_MIN_LEN	112
-struct fsf_plogi {
-	u32    code;
-	struct fsf_nport_serv_param serv_param;
-} __attribute__ ((packed));
 
 #define FSF_FCP_CMND_SIZE	288
 #define FSF_FCP_RSP_SIZE	128
@@ -342,8 +329,8 @@ struct fsf_qtcb_bottom_io {
 
 struct fsf_qtcb_bottom_support {
 	u32 operation_subtype;
-	u8  res1[12];
-	u32 d_id;
+	u8  res1[13];
+	u8 d_id[3];
 	u32 option;
 	u64 fcp_lun;
 	u64 res2;
@@ -372,18 +359,18 @@ struct fsf_qtcb_bottom_config {
 	u32 fc_topology;
 	u32 fc_link_speed;
 	u32 adapter_type;
-	u32 peer_d_id;
+	u8 res0;
+	u8 peer_d_id[3];
 	u8 res1[2];
 	u16 timer_interval;
-	u8 res2[8];
-	u32 s_id;
-	struct fsf_nport_serv_param nport_serv_param;
-	u8 reserved_nport_serv_param[16];
+	u8 res2[9];
+	u8 s_id[3];
+	u8 nport_serv_param[128];
 	u8 res3[8];
 	u32 adapter_ports;
 	u32 hardware_version;
 	u8 serial_number[32];
-	struct fsf_nport_serv_param plogi_payload;
+	u8 plogi_payload[112];
 	struct fsf_statistics_info stat_info;
 	u8 res4[112];
 } __attribute__ ((packed));
@@ -450,4 +437,22 @@ struct zfcp_blk_drv_data {
 	u64 fabric_lat;
 } __attribute__ ((packed));
 
+/**
+ * struct zfcp_fsf_ct_els - zfcp data for ct or els request
+ * @req: scatter-gather list for request
+ * @resp: scatter-gather list for response
+ * @handler: handler function (called for response to the request)
+ * @handler_data: data passed to handler function
+ * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
+ * @status: used to pass error status to calling function
+ */
+struct zfcp_fsf_ct_els {
+	struct scatterlist *req;
+	struct scatterlist *resp;
+	void (*handler)(void *);
+	void *handler_data;
+	struct zfcp_port *port;
+	int status;
+};
+
 #endif				/* FSF_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_scsi.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_scsi.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_scsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_scsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -9,29 +9,33 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/types.h>
+#include <scsi/fc/fc_fcp.h>
 #include <asm/atomic.h>
 #include "zfcp_ext.h"
 #include "zfcp_dbf.h"
+#include "zfcp_fc.h"
 
 static unsigned int default_depth = 32;
 module_param_named(queue_depth, default_depth, uint, 0600);
 MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
 
-/* Find start of Sense Information in FCP response unit*/
-char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
-{
-	char *fcp_sns_info_ptr;
-
-	fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1];
-	if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)
-		fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len;
-
-	return fcp_sns_info_ptr;
-}
-
-static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth)
+static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
+					int reason)
 {
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, depth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 
@@ -39,7 +43,7 @@ static void zfcp_scsi_slave_destroy(stru
 {
 	struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
 	unit->device = NULL;
-	zfcp_unit_put(unit);
+	put_device(&unit->sysfs_device);
 }
 
 static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
@@ -99,12 +103,26 @@ static int zfcp_scsi_queuecommand(struct
 	}
 
 	status = atomic_read(&unit->status);
-	if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
-		     !(status & ZFCP_STATUS_COMMON_RUNNING))) {
+	if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) &&
+		     !(atomic_read(&unit->port->status) &
+		       ZFCP_STATUS_COMMON_ERP_FAILED)) {
+		/* only unit access denied, but port is good
+		 * not covered by FC transport, have to fail here */
 		zfcp_scsi_command_fail(scpnt, DID_ERROR);
 		return 0;
 	}
 
+	if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
+		/* This could be either
+		 * open unit pending: this is temporary, will result in
+		 * 	open unit or ERP_FAILED, so retry command
+		 * call to rport_delete pending: mimic retry from
+		 * 	fc_remote_port_chkready until rport is BLOCKED
+		 */
+		zfcp_scsi_command_fail(scpnt, DID_IMM_RETRY);
+		return 0;
+	}
+
 	ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
 	if (unlikely(ret == -EBUSY))
 		return SCSI_MLQUEUE_DEVICE_BUSY;
@@ -115,49 +133,44 @@ static int zfcp_scsi_queuecommand(struct
 }
 
 static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
-					  int channel, unsigned int id,
-					  unsigned int lun)
+					  unsigned int id, u64 lun)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
-	struct zfcp_unit *unit;
-	int scsi_lun;
+	struct zfcp_unit *unit = NULL;
 
-	list_for_each_entry(port, &adapter->port_list_head, list) {
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
 		if (!port->rport || (id != port->rport->scsi_target_id))
 			continue;
-		list_for_each_entry(unit, &port->unit_list_head, list) {
-			scsi_lun = scsilun_to_int(
-				(struct scsi_lun *)&unit->fcp_lun);
-			if (lun == scsi_lun)
-				return unit;
-		}
+		unit = zfcp_get_unit_by_lun(port, lun);
+		if (unit)
+			break;
 	}
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
-	return NULL;
+	return unit;
 }
 
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_unit *unit;
-	unsigned long flags;
-	int retval = -ENXIO;
+	u64 lun;
 
 	adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
 	if (!adapter)
 		goto out;
 
-	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun);
+	int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun);
+	unit = zfcp_unit_lookup(adapter, sdp->id, lun);
 	if (unit) {
 		sdp->hostdata = unit;
 		unit->device = sdp;
-		zfcp_unit_get(unit);
-		retval = 0;
+		return 0;
 	}
-	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 out:
-	return retval;
+	return -ENXIO;
 }
 
 static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
@@ -196,6 +209,7 @@ static int zfcp_scsi_eh_abort_handler(st
 			break;
 
 		zfcp_erp_wait(adapter);
+		fc_block_scsi_eh(scpnt);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
 			zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
@@ -235,6 +249,7 @@ static int zfcp_task_mgmt_function(struc
 			break;
 
 		zfcp_erp_wait(adapter);
+		fc_block_scsi_eh(scpnt);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
 			zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt);
@@ -249,9 +264,6 @@ static int zfcp_task_mgmt_function(struc
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
 		zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt);
 		retval = FAILED;
-	} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {
-		zfcp_dbf_scsi_devreset("nsup", tm_flags, unit, scpnt);
-		retval = FAILED;
 	} else
 		zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt);
 
@@ -261,12 +273,12 @@ static int zfcp_task_mgmt_function(struc
 
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET);
+	return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
 }
 
 static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET);
+	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
 }
 
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
@@ -276,6 +288,7 @@ static int zfcp_scsi_eh_host_reset_handl
 
 	zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
 	zfcp_erp_wait(adapter);
+	fc_block_scsi_eh(scpnt);
 
 	return SUCCESS;
 }
@@ -303,7 +316,7 @@ int zfcp_adapter_scsi_register(struct zf
 	adapter->scsi_host->max_lun = 1;
 	adapter->scsi_host->max_channel = 0;
 	adapter->scsi_host->unique_id = dev_id.devno;
-	adapter->scsi_host->max_cmd_len = 255;
+	adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
 	adapter->scsi_host->transportt = zfcp_data.scsi_transport_template;
 
 	adapter->scsi_host->hostdata[0] = (unsigned long) adapter;
@@ -325,12 +338,11 @@ void zfcp_adapter_scsi_unregister(struct
 	if (!shost)
 		return;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry(port, &adapter->port_list_head, list)
-		if (port->rport)
-			port->rport = NULL;
+	read_lock_irq(&adapter->port_list_lock);
+	list_for_each_entry(port, &adapter->port_list, list)
+		port->rport = NULL;
+	read_unlock_irq(&adapter->port_list_lock);
 
-	read_unlock_irq(&zfcp_data.config_lock);
 	fc_remove_host(shost);
 	scsi_remove_host(shost);
 	scsi_host_put(shost);
@@ -348,7 +360,7 @@ zfcp_init_fc_host_stats(struct zfcp_adap
 		fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL);
 		if (!fc_stats)
 			return NULL;
-		adapter->fc_stats = fc_stats; /* freed in adater_dequeue */
+		adapter->fc_stats = fc_stats; /* freed in adapter_release */
 	}
 	memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats));
 	return adapter->fc_stats;
@@ -464,7 +476,7 @@ static void zfcp_reset_fc_host_stats(str
 		adapter->stats_reset = jiffies/HZ;
 		kfree(adapter->stats_reset_data);
 		adapter->stats_reset_data = data; /* finally freed in
-						     adapter_dequeue */
+						     adapter_release */
 	}
 }
 
@@ -495,7 +507,7 @@ static void zfcp_set_rport_dev_loss_tmo(
  * @rport: The FC rport where to teminate I/O
  *
  * Abort all pending SCSI commands for a port by closing the
- * port. Using a reopen for avoids a conflict with a shutdown
+ * port. Using a reopen avoiding a conflict with a shutdown
  * overwriting a reopen.
  */
 static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
@@ -505,15 +517,11 @@ static void zfcp_scsi_terminate_rport_io
 	struct zfcp_adapter *adapter =
 		(struct zfcp_adapter *)shost->hostdata[0];
 
-	write_lock_irq(&zfcp_data.config_lock);
 	port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
-	if (port)
-		zfcp_port_get(port);
-	write_unlock_irq(&zfcp_data.config_lock);
 
 	if (port) {
 		zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 	}
 }
 
@@ -555,31 +563,34 @@ static void zfcp_scsi_rport_block(struct
 
 void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_ADD;
 
 	if (!queue_work(port->adapter->work_queue, &port->rport_work))
-		zfcp_port_put(port);
+		put_device(&port->sysfs_device);
 }
 
 void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
 {
-	zfcp_port_get(port);
+	get_device(&port->sysfs_device);
 	port->rport_task = RPORT_DEL;
 
 	if (port->rport && queue_work(port->adapter->work_queue,
 				      &port->rport_work))
 		return;
 
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
 {
+	unsigned long flags;
 	struct zfcp_port *port;
 
-	list_for_each_entry(port, &adapter->port_list_head, list)
+	read_lock_irqsave(&adapter->port_list_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list)
 		zfcp_scsi_schedule_rport_block(port);
+	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 }
 
 void zfcp_scsi_rport_work(struct work_struct *work)
@@ -597,7 +608,7 @@ void zfcp_scsi_rport_work(struct work_st
 		}
 	}
 
-	zfcp_port_put(port);
+	put_device(&port->sysfs_device);
 }
 
 
@@ -615,21 +626,7 @@ void zfcp_scsi_scan(struct work_struct *
 				 scsilun_to_int((struct scsi_lun *)
 						&unit->fcp_lun), 0);
 
-	zfcp_unit_put(unit);
-}
-
-static int zfcp_execute_fc_job(struct fc_bsg_job *job)
-{
-	switch (job->request->msgcode) {
-	case FC_BSG_RPT_ELS:
-	case FC_BSG_HST_ELS_NOLOGIN:
-		return zfcp_fc_execute_els_fc_job(job);
-	case FC_BSG_RPT_CT:
-	case FC_BSG_HST_CT:
-		return zfcp_fc_execute_ct_fc_job(job);
-	default:
-		return -EINVAL;
-	}
+	put_device(&unit->sysfs_device);
 }
 
 struct fc_function_template zfcp_transport_functions = {
@@ -643,6 +640,7 @@ struct fc_function_template zfcp_transpo
 	.show_host_port_name = 1,
 	.show_host_permanent_port_name = 1,
 	.show_host_supported_classes = 1,
+	.show_host_supported_fc4s = 1,
 	.show_host_supported_speeds = 1,
 	.show_host_maxframe_size = 1,
 	.show_host_serial_number = 1,
@@ -652,13 +650,16 @@ struct fc_function_template zfcp_transpo
 	.get_host_port_state = zfcp_get_host_port_state,
 	.terminate_rport_io = zfcp_scsi_terminate_rport_io,
 	.show_host_port_state = 1,
-	.bsg_request = zfcp_execute_fc_job,
+	.show_host_active_fc4s = 1,
+	.bsg_request = zfcp_fc_exec_bsg_job,
+	.bsg_timeout = zfcp_fc_timeout_bsg_job,
 	/* no functions registered for following dynamic attributes but
 	   directly set by LLDD */
 	.show_host_port_type = 1,
 	.show_host_speed = 1,
 	.show_host_port_id = 1,
 	.disable_target_scan = 1,
+	.dd_bsg_size = sizeof(struct zfcp_fsf_ct_els),
 };
 
 struct zfcp_data zfcp_data = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_sysfs.c linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_sysfs.c
--- linux-libre-2.6.32-gnu1/drivers/s390/scsi/zfcp_sysfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/s390/scsi/zfcp_sysfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * sysfs attributes.
  *
- * Copyright IBM Corporation 2008
+ * Copyright IBM Corporation 2008, 2009
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -19,30 +19,44 @@ static ssize_t zfcp_sysfs_##_feat##_##_n
 						   struct device_attribute *at,\
 						   char *buf)		       \
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 									       \
 	return sprintf(buf, _format, _value);				       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
 		     zfcp_sysfs_##_feat##_##_name##_show, NULL);
 
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n",
-		 atomic_read(&adapter->status));
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n",
-		 (unsigned long long) adapter->peer_wwnn);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n",
-		 (unsigned long long) adapter->peer_wwpn);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n",
-		 adapter->peer_d_id);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n",
-		 adapter->hydra_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, lic_version, "0x%08x\n",
-		 adapter->fsf_lic_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, hardware_version, "0x%08x\n",
-		 adapter->hardware_version);
-ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, in_recovery, "%d\n",
-		 (atomic_read(&adapter->status) &
-		  ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
+#define ZFCP_DEFINE_A_ATTR(_name, _format, _value)			     \
+static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,	     \
+						 struct device_attribute *at,\
+						 char *buf)		     \
+{									     \
+	struct ccw_device *cdev = to_ccwdev(dev);			     \
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);	     \
+	int i;								     \
+									     \
+	if (!adapter)							     \
+		return -ENODEV;						     \
+									     \
+	i = sprintf(buf, _format, _value);				     \
+	zfcp_ccw_adapter_put(adapter);					     \
+	return i;							     \
+}									     \
+static ZFCP_DEV_ATTR(adapter, _name, S_IRUGO,				     \
+		     zfcp_sysfs_adapter_##_name##_show, NULL);
+
+ZFCP_DEFINE_A_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
+ZFCP_DEFINE_A_ATTR(peer_wwnn, "0x%016llx\n",
+		   (unsigned long long) adapter->peer_wwnn);
+ZFCP_DEFINE_A_ATTR(peer_wwpn, "0x%016llx\n",
+		   (unsigned long long) adapter->peer_wwpn);
+ZFCP_DEFINE_A_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
+ZFCP_DEFINE_A_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
+ZFCP_DEFINE_A_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
+ZFCP_DEFINE_A_ATTR(hardware_version, "0x%08x\n", adapter->hardware_version);
+ZFCP_DEFINE_A_ATTR(in_recovery, "%d\n", (atomic_read(&adapter->status) &
+					 ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
 
 ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n",
 		 atomic_read(&port->status));
@@ -73,7 +87,8 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 						struct device_attribute *attr, \
 						char *buf)		       \
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 									       \
 	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED)       \
 		return sprintf(buf, "1\n");				       \
@@ -84,15 +99,13 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 						 struct device_attribute *attr,\
 						 const char *buf, size_t count)\
 {									       \
-	struct _feat_def *_feat = dev_get_drvdata(dev);			       \
+	struct _feat_def *_feat = container_of(dev, struct _feat_def,	       \
+					       sysfs_device);		       \
 	unsigned long val;						       \
 	int retval = 0;							       \
 									       \
-	mutex_lock(&zfcp_data.config_mutex);				       \
-	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) {	       \
-		retval = -EBUSY;					       \
-		goto out;						       \
-	}								       \
+	if (!(_feat && get_device(&_feat->sysfs_device)))		       \
+		return -EBUSY;						       \
 									       \
 	if (strict_strtoul(buf, 0, &val) || val != 0) {			       \
 		retval = -EINVAL;					       \
@@ -105,29 +118,82 @@ static ssize_t zfcp_sysfs_##_feat##_fail
 				  _reopen_id, NULL);			       \
 	zfcp_erp_wait(_adapter);					       \
 out:									       \
-	mutex_unlock(&zfcp_data.config_mutex);				       \
+	put_device(&_feat->sysfs_device);				       \
 	return retval ? retval : (ssize_t) count;			       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO,			       \
 		     zfcp_sysfs_##_feat##_failed_show,			       \
 		     zfcp_sysfs_##_feat##_failed_store);
 
-ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, "syafai1", "syafai2");
 ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
 ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
 
+static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+	int i;
+
+	if (!adapter)
+		return -ENODEV;
+
+	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
+		i = sprintf(buf, "1\n");
+	else
+		i = sprintf(buf, "0\n");
+
+	zfcp_ccw_adapter_put(adapter);
+	return i;
+}
+
+static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev,
+					       struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+	unsigned long val;
+	int retval = 0;
+
+	if (!adapter)
+		return -ENODEV;
+
+	if (strict_strtoul(buf, 0, &val) || val != 0) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL,
+				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+				"syafai2", NULL);
+	zfcp_erp_wait(adapter);
+out:
+	zfcp_ccw_adapter_put(adapter);
+	return retval ? retval : (ssize_t) count;
+}
+static ZFCP_DEV_ATTR(adapter, failed, S_IWUSR | S_IRUGO,
+		     zfcp_sysfs_adapter_failed_show,
+		     zfcp_sysfs_adapter_failed_store);
+
 static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(dev);
-	int ret;
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
-	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE)
-		return -EBUSY;
+	if (!adapter)
+		return -ENODEV;
 
-	ret = zfcp_fc_scan_ports(adapter);
-	return ret ? ret : (ssize_t) count;
+	/* sync the user-space- with the kernel-invocation of scan_work */
+	queue_work(adapter->work_queue, &adapter->scan_work);
+	flush_work(&adapter->scan_work);
+	zfcp_ccw_adapter_put(adapter);
+
+	return (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
 		     zfcp_sysfs_port_rescan_store);
@@ -136,44 +202,34 @@ static ssize_t zfcp_sysfs_port_remove_st
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_adapter *adapter = dev_get_drvdata(dev);
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 	struct zfcp_port *port;
 	u64 wwpn;
-	int retval = 0;
-	LIST_HEAD(port_remove_lh);
+	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
-		goto out;
-	}
+	if (!adapter)
+		return -ENODEV;
 
-	if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
-		retval = -EINVAL;
+	if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn))
 		goto out;
-	}
 
-	write_lock_irq(&zfcp_data.config_lock);
 	port = zfcp_get_port_by_wwpn(adapter, wwpn);
-	if (port && (atomic_read(&port->refcount) == 0)) {
-		zfcp_port_get(port);
-		atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
-		list_move(&port->list, &port_remove_lh);
-	} else
-		port = NULL;
-	write_unlock_irq(&zfcp_data.config_lock);
-
-	if (!port) {
-		retval = -ENXIO;
+	if (!port)
 		goto out;
-	}
+	else
+		retval = 0;
+
+	write_lock_irq(&adapter->port_list_lock);
+	list_del(&port->list);
+	write_unlock_irq(&adapter->port_list_lock);
+
+	put_device(&port->sysfs_device);
 
 	zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
-	zfcp_erp_wait(adapter);
-	zfcp_port_put(port);
-	zfcp_port_dequeue(port);
+	zfcp_device_unregister(&port->sysfs_device, &zfcp_sysfs_port_attrs);
  out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	zfcp_ccw_adapter_put(adapter);
 	return retval ? retval : (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
@@ -202,16 +258,14 @@ static ssize_t zfcp_sysfs_unit_add_store
 					 struct device_attribute *attr,
 					 const char *buf, size_t count)
 {
-	struct zfcp_port *port = dev_get_drvdata(dev);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port,
+					      sysfs_device);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
 	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
-		goto out;
-	}
+	if (!(port && get_device(&port->sysfs_device)))
+		return -EBUSY;
 
 	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
 		goto out;
@@ -219,15 +273,14 @@ static ssize_t zfcp_sysfs_unit_add_store
 	unit = zfcp_unit_enqueue(port, fcp_lun);
 	if (IS_ERR(unit))
 		goto out;
-
-	retval = 0;
+	else
+		retval = 0;
 
 	zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
 	zfcp_erp_wait(unit->port->adapter);
 	flush_work(&unit->scsi_work);
-	zfcp_unit_put(unit);
 out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	put_device(&port->sysfs_device);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -236,54 +289,37 @@ static ssize_t zfcp_sysfs_unit_remove_st
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
 {
-	struct zfcp_port *port = dev_get_drvdata(dev);
+	struct zfcp_port *port = container_of(dev, struct zfcp_port,
+					      sysfs_device);
 	struct zfcp_unit *unit;
 	u64 fcp_lun;
-	int retval = 0;
-	LIST_HEAD(unit_remove_lh);
+	int retval = -EINVAL;
 
-	mutex_lock(&zfcp_data.config_mutex);
-	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
-		retval = -EBUSY;
-		goto out;
-	}
+	if (!(port && get_device(&port->sysfs_device)))
+		return -EBUSY;
 
-	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) {
-		retval = -EINVAL;
+	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
 		goto out;
-	}
 
-	write_lock_irq(&zfcp_data.config_lock);
 	unit = zfcp_get_unit_by_lun(port, fcp_lun);
-	if (unit) {
-		write_unlock_irq(&zfcp_data.config_lock);
-		/* wait for possible timeout during SCSI probe */
-		flush_work(&unit->scsi_work);
-		write_lock_irq(&zfcp_data.config_lock);
+	if (!unit)
+		goto out;
+	else
+		retval = 0;
 
-		if (atomic_read(&unit->refcount) == 0) {
-			zfcp_unit_get(unit);
-			atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
-					&unit->status);
-			list_move(&unit->list, &unit_remove_lh);
-		} else {
-			unit = NULL;
-		}
-	}
+	/* wait for possible timeout during SCSI probe */
+	flush_work(&unit->scsi_work);
 
-	write_unlock_irq(&zfcp_data.config_lock);
+	write_lock_irq(&port->unit_list_lock);
+	list_del(&unit->list);
+	write_unlock_irq(&port->unit_list_lock);
 
-	if (!unit) {
-		retval = -ENXIO;
-		goto out;
-	}
+	put_device(&unit->sysfs_device);
 
 	zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
-	zfcp_erp_wait(unit->port->adapter);
-	zfcp_unit_put(unit);
-	zfcp_unit_dequeue(unit);
+	zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
 out:
-	mutex_unlock(&zfcp_data.config_mutex);
+	put_device(&port->sysfs_device);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
diff -druNp linux-libre-2.6.32-gnu1/drivers/sbus/char/bbc_envctrl.c linux-libre-2.6.33-gnu1/drivers/sbus/char/bbc_envctrl.c
--- linux-libre-2.6.32-gnu1/drivers/sbus/char/bbc_envctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/sbus/char/bbc_envctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -522,6 +522,40 @@ static void attach_one_fan(struct bbc_i2
 	set_fan_speeds(fp);
 }
 
+static void destroy_one_temp(struct bbc_cpu_temperature *tp)
+{
+	bbc_i2c_detach(tp->client);
+	kfree(tp);
+}
+
+static void destroy_all_temps(struct bbc_i2c_bus *bp)
+{
+	struct bbc_cpu_temperature *tp, *tpos;
+
+	list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) {
+		list_del(&tp->bp_list);
+		list_del(&tp->glob_list);
+		destroy_one_temp(tp);
+	}
+}
+
+static void destroy_one_fan(struct bbc_fan_control *fp)
+{
+	bbc_i2c_detach(fp->client);
+	kfree(fp);
+}
+
+static void destroy_all_fans(struct bbc_i2c_bus *bp)
+{
+	struct bbc_fan_control *fp, *fpos;
+
+	list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) {
+		list_del(&fp->bp_list);
+		list_del(&fp->glob_list);
+		destroy_one_fan(fp);
+	}
+}
+
 int bbc_envctrl_init(struct bbc_i2c_bus *bp)
 {
 	struct of_device *op;
@@ -541,6 +575,8 @@ int bbc_envctrl_init(struct bbc_i2c_bus
 			int err = PTR_ERR(kenvctrld_task);
 
 			kenvctrld_task = NULL;
+			destroy_all_temps(bp);
+			destroy_all_fans(bp);
 			return err;
 		}
 	}
@@ -548,35 +584,11 @@ int bbc_envctrl_init(struct bbc_i2c_bus
 	return 0;
 }
 
-static void destroy_one_temp(struct bbc_cpu_temperature *tp)
-{
-	bbc_i2c_detach(tp->client);
-	kfree(tp);
-}
-
-static void destroy_one_fan(struct bbc_fan_control *fp)
-{
-	bbc_i2c_detach(fp->client);
-	kfree(fp);
-}
-
 void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp)
 {
-	struct bbc_cpu_temperature *tp, *tpos;
-	struct bbc_fan_control *fp, *fpos;
-
 	if (kenvctrld_task)
 		kthread_stop(kenvctrld_task);
 
-	list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) {
-		list_del(&tp->bp_list);
-		list_del(&tp->glob_list);
-		destroy_one_temp(tp);
-	}
-
-	list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) {
-		list_del(&fp->bp_list);
-		list_del(&fp->glob_list);
-		destroy_one_fan(fp);
-	}
+	destroy_all_temps(bp);
+	destroy_all_fans(bp);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/sbus/char/envctrl.c linux-libre-2.6.33-gnu1/drivers/sbus/char/envctrl.c
--- linux-libre-2.6.32-gnu1/drivers/sbus/char/envctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/sbus/char/envctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -92,11 +92,11 @@
 #define ENVCTRL_CPUTEMP_MON			1    /* cpu temperature monitor */
 #define ENVCTRL_CPUVOLTAGE_MON	  	2    /* voltage monitor         */
 #define ENVCTRL_FANSTAT_MON  		3    /* fan status monitor      */
-#define ENVCTRL_ETHERTEMP_MON		4    /* ethernet temperarture */
+#define ENVCTRL_ETHERTEMP_MON		4    /* ethernet temperature */
 					     /* monitor                     */
 #define ENVCTRL_VOLTAGESTAT_MON	  	5    /* voltage status monitor  */
 #define ENVCTRL_MTHRBDTEMP_MON		6    /* motherboard temperature */
-#define ENVCTRL_SCSITEMP_MON		7    /* scsi temperarture */
+#define ENVCTRL_SCSITEMP_MON		7    /* scsi temperature */
 #define ENVCTRL_GLOBALADDR_MON		8    /* global address */
 
 /* Child device type.
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/3w-9xxx.c linux-libre-2.6.33-gnu1/drivers/scsi/3w-9xxx.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/3w-9xxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/3w-9xxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,6 +76,7 @@
                  Fix bug in twa_get_param() on 4GB+.
                  Use pci_resource_len() for ioremap().
    2.26.02.012 - Add power management support.
+   2.26.02.013 - Fix bug in twa_load_sgl().
 */
 
 #include <linux/module.h>
@@ -100,7 +101,7 @@
 #include "3w-9xxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "2.26.02.012"
+#define TW_DRIVER_VERSION "2.26.02.013"
 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
 static unsigned int twa_device_extension_count;
 static int twa_major = -1;
@@ -186,8 +187,12 @@ static ssize_t twa_show_stats(struct dev
 } /* End twa_show_stats() */
 
 /* This function will set a devices queue depth */
-static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > TW_Q_LENGTH-2)
 		queue_depth = TW_Q_LENGTH-2;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
@@ -732,7 +737,7 @@ static int twa_chrdev_ioctl(struct inode
 		break;
 	case TW_IOCTL_GET_COMPATIBILITY_INFO:
 		tw_ioctl->driver_command.status = 0;
-		/* Copy compatiblity struct into ioctl data buffer */
+		/* Copy compatibility struct into ioctl data buffer */
 		tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
 		memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
 		break;
@@ -1378,10 +1383,12 @@ static void twa_load_sgl(TW_Device_Exten
 		newcommand = &full_command_packet->command.newcommand;
 		newcommand->request_id__lunl =
 			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
-		newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
-		newcommand->sg_list[0].length = cpu_to_le32(length);
+		if (length) {
+			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+			newcommand->sg_list[0].length = cpu_to_le32(length);
+		}
 		newcommand->sgl_entries__lunh =
-			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1));
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
 	} else {
 		oldcommand = &full_command_packet->command.oldcommand;
 		oldcommand->request_id = request_id;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/3w-sas.c linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/3w-sas.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,1924 @@
+/*
+   3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@lsi.com>
+
+   Copyright (C) 2009 LSI 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 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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   You 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
+
+   Controllers supported by this driver:
+
+   LSI 3ware 9750 6Gb/s SAS/SATA-RAID
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@lsi.com
+
+   For more information, goto:
+   http://www.lsi.com
+
+   History
+   -------
+   3.26.02.000 - Initial driver release.
+*/
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/mutex.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_cmnd.h>
+#include "3w-sas.h"
+
+/* Globals */
+#define TW_DRIVER_VERSION "3.26.02.000"
+static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
+static unsigned int twl_device_extension_count;
+static int twl_major = -1;
+extern struct timezone sys_tz;
+
+/* Module parameters */
+MODULE_AUTHOR ("LSI");
+MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(TW_DRIVER_VERSION);
+
+static int use_msi;
+module_param(use_msi, int, S_IRUGO);
+MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
+
+/* Function prototypes */
+static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
+
+/* Functions */
+
+/* This function returns AENs through sysfs */
+static ssize_t twl_sysfs_aen_read(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
+				  char *outbuf, loff_t offset, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct Scsi_Host *shost = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
+	unsigned long flags = 0;
+	ssize_t ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	return ret;
+} /* End twl_sysfs_aen_read() */
+
+/* aen_read sysfs attribute initializer */
+static struct bin_attribute twl_sysfs_aen_read_attr = {
+	.attr = {
+		.name = "3ware_aen_read",
+		.mode = S_IRUSR,
+	}, 
+	.size = 0,
+	.read = twl_sysfs_aen_read
+};
+
+/* This function returns driver compatibility info through sysfs */
+static ssize_t twl_sysfs_compat_info(struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *outbuf, loff_t offset, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct Scsi_Host *shost = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
+	unsigned long flags = 0;
+	ssize_t ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	return ret;
+} /* End twl_sysfs_compat_info() */
+
+/* compat_info sysfs attribute initializer */
+static struct bin_attribute twl_sysfs_compat_info_attr = {
+	.attr = {
+		.name = "3ware_compat_info",
+		.mode = S_IRUSR,
+	}, 
+	.size = 0,
+	.read = twl_sysfs_compat_info
+};
+
+/* Show some statistics about the card */
+static ssize_t twl_show_stats(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+	unsigned long flags = 0;
+	ssize_t len;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
+		       "Current commands posted:   %4d\n"
+		       "Max commands posted:       %4d\n"
+		       "Last sgl length:           %4d\n"
+		       "Max sgl length:            %4d\n"
+		       "Last sector count:         %4d\n"
+		       "Max sector count:          %4d\n"
+		       "SCSI Host Resets:          %4d\n"
+		       "AEN's:                     %4d\n", 
+		       TW_DRIVER_VERSION,
+		       tw_dev->posted_request_count,
+		       tw_dev->max_posted_request_count,
+		       tw_dev->sgl_entries,
+		       tw_dev->max_sgl_entries,
+		       tw_dev->sector_count,
+		       tw_dev->max_sector_count,
+		       tw_dev->num_resets,
+		       tw_dev->aen_count);
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+	return len;
+} /* End twl_show_stats() */
+
+/* This function will set a devices queue depth */
+static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				  int reason)
+{
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
+	if (queue_depth > TW_Q_LENGTH-2)
+		queue_depth = TW_Q_LENGTH-2;
+	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
+	return queue_depth;
+} /* End twl_change_queue_depth() */
+
+/* stats sysfs attribute initializer */
+static struct device_attribute twl_host_stats_attr = {
+	.attr = {
+		.name = 	"3ware_stats",
+		.mode =		S_IRUGO,
+	},
+	.show = twl_show_stats
+};
+
+/* Host attributes initializer */
+static struct device_attribute *twl_host_attrs[] = {
+	&twl_host_stats_attr,
+	NULL,
+};
+
+/* This function will look up an AEN severity string */
+static char *twl_aen_severity_lookup(unsigned char severity_code)
+{
+	char *retval = NULL;
+
+	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
+	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
+		goto out;
+
+	retval = twl_aen_severity_table[severity_code];
+out:
+	return retval;
+} /* End twl_aen_severity_lookup() */
+
+/* This function will queue an event */
+static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
+{
+	u32 local_time;
+	struct timeval time;
+	TW_Event *event;
+	unsigned short aen;
+	char host[16];
+	char *error_str;
+
+	tw_dev->aen_count++;
+
+	/* Fill out event info */
+	event = tw_dev->event_queue[tw_dev->error_index];
+
+	host[0] = '\0';
+	if (tw_dev->host)
+		sprintf(host, " scsi%d:", tw_dev->host->host_no);
+
+	aen = le16_to_cpu(header->status_block.error);
+	memset(event, 0, sizeof(TW_Event));
+
+	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
+	do_gettimeofday(&time);
+	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	event->time_stamp_sec = local_time;
+	event->aen_code = aen;
+	event->retrieved = TW_AEN_NOT_RETRIEVED;
+	event->sequence_id = tw_dev->error_sequence_id;
+	tw_dev->error_sequence_id++;
+
+	/* Check for embedded error string */
+	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
+
+	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
+	event->parameter_len = strlen(header->err_specific_desc);
+	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
+	if (event->severity != TW_AEN_SEVERITY_DEBUG)
+		printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
+		       host,
+		       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
+		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
+		       header->err_specific_desc);
+	else
+		tw_dev->aen_count--;
+
+	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
+} /* End twl_aen_queue_event() */
+
+/* This function will attempt to post a command packet to the board */
+static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
+{
+	dma_addr_t command_que_value;
+
+	command_que_value = tw_dev->command_packet_phys[request_id];
+	command_que_value += TW_COMMAND_OFFSET;
+
+	/* First write upper 4 bytes */
+	writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
+	/* Then the lower 4 bytes */
+	writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
+
+	tw_dev->state[request_id] = TW_S_POSTED;
+	tw_dev->posted_request_count++;
+	if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
+		tw_dev->max_posted_request_count = tw_dev->posted_request_count;
+
+	return 0;
+} /* End twl_post_command_packet() */
+
+/* This function will perform a pci-dma mapping for a scatter gather list */
+static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	int use_sg;
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+	use_sg = scsi_dma_map(cmd);
+	if (!use_sg)
+		return 0;
+	else if (use_sg < 0) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
+		return 0;
+	}
+
+	cmd->SCp.phase = TW_PHASE_SGLIST;
+	cmd->SCp.have_data_in = use_sg;
+
+	return use_sg;
+} /* End twl_map_scsi_sg_data() */
+
+/* This function hands scsi cdb's to the firmware */
+static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache *command_packet;
+	int i, sg_count;
+	struct scsi_cmnd *srb = NULL;
+	struct scatterlist *sglist = NULL, *sg;
+	int retval = 1;
+
+	if (tw_dev->srb[request_id]) {
+		srb = tw_dev->srb[request_id];
+		if (scsi_sglist(srb))
+			sglist = scsi_sglist(srb);
+	}
+
+	/* Initialize command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	full_command_packet->header.header_desc.size_header = 128;
+	full_command_packet->header.status_block.error = 0;
+	full_command_packet->header.status_block.severity__reserved = 0;
+
+	command_packet = &full_command_packet->command.newcommand;
+	command_packet->status = 0;
+	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
+
+	/* We forced 16 byte cdb use earlier */
+	if (!cdb)
+		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
+	else
+		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
+
+	if (srb) {
+		command_packet->unit = srb->device->id;
+		command_packet->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
+	} else {
+		command_packet->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
+		command_packet->unit = 0;
+	}
+
+	command_packet->sgl_offset = 16;
+
+	if (!sglistarg) {
+		/* Map sglist from scsi layer to cmd packet */
+		if (scsi_sg_count(srb)) {
+			sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
+			if (sg_count == 0)
+				goto out;
+
+			scsi_for_each_sg(srb, sg, sg_count, i) {
+				command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
+				command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
+			}
+			command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
+		}
+	} else {
+		/* Internal cdb post */
+		for (i = 0; i < use_sg; i++) {
+			command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
+			command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
+		}
+		command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
+	}
+
+	/* Update some stats */
+	if (srb) {
+		tw_dev->sector_count = scsi_bufflen(srb) / 512;
+		if (tw_dev->sector_count > tw_dev->max_sector_count)
+			tw_dev->max_sector_count = tw_dev->sector_count;
+		tw_dev->sgl_entries = scsi_sg_count(srb);
+		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
+			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
+	}
+
+	/* Now post the command to the board */
+	retval = twl_post_command_packet(tw_dev, request_id);
+
+out:
+	return retval;
+} /* End twl_scsiop_execute_scsi() */
+
+/* This function will read the aen queue from the isr */
+static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
+{
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Entry_ISO sglist[1];
+	TW_Command_Full *full_command_packet;
+	int retval = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command packet */
+	if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
+		goto out;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_aen_read_queue() */
+
+/* This function will sync firmware time with the host time */
+static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
+{
+	u32 schedulertime;
+	struct timeval utc;
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	u32 local_time;
+
+	/* Fill out the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
+	command_packet->request_id = request_id;
+	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
+	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
+	command_packet->size = TW_COMMAND_SIZE;
+	command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
+
+	/* Setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
+	param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
+	param->parameter_size_bytes = cpu_to_le16(4);
+
+	/* Convert system time in UTC to local time seconds since last 
+           Sunday 12:00AM */
+	do_gettimeofday(&utc);
+	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
+	schedulertime = local_time - (3 * 86400);
+	schedulertime = cpu_to_le32(schedulertime % 604800);
+
+	memcpy(param->data, &schedulertime, sizeof(u32));
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command */
+	twl_post_command_packet(tw_dev, request_id);
+} /* End twl_aen_sync_time() */
+
+/* This function will assign an available request id */
+static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
+{
+	*request_id = tw_dev->free_queue[tw_dev->free_head];
+	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
+	tw_dev->state[*request_id] = TW_S_STARTED;
+} /* End twl_get_request_id() */
+
+/* This function will free a request id */
+static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
+{
+	tw_dev->free_queue[tw_dev->free_tail] = request_id;
+	tw_dev->state[request_id] = TW_S_FINISHED;
+	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
+} /* End twl_free_request_id() */
+
+/* This function will complete an aen request from the isr */
+static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int retval = 1;
+
+	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+	tw_dev->posted_request_count--;
+	aen = le16_to_cpu(header->status_block.error);
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	command_packet = &full_command_packet->command.oldcommand;
+
+	/* First check for internal completion of set param for time sync */
+	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
+		/* Keep reading the queue in case there are more aen's */
+		if (twl_aen_read_queue(tw_dev, request_id))
+			goto out2;
+	        else {
+			retval = 0;
+			goto out;
+		}
+	}
+
+	switch (aen) {
+	case TW_AEN_QUEUE_EMPTY:
+		/* Quit reading the queue if this is the last one */
+		break;
+	case TW_AEN_SYNC_TIME_WITH_HOST:
+		twl_aen_sync_time(tw_dev, request_id);
+		retval = 0;
+		goto out;
+	default:
+		twl_aen_queue_event(tw_dev, header);
+
+		/* If there are more aen's, keep reading the queue */
+		if (twl_aen_read_queue(tw_dev, request_id))
+			goto out2;
+		else {
+			retval = 0;
+			goto out;
+		}
+	}
+	retval = 0;
+out2:
+	tw_dev->state[request_id] = TW_S_COMPLETED;
+	twl_free_request_id(tw_dev, request_id);
+	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+out:
+	return retval;
+} /* End twl_aen_complete() */
+
+/* This function will poll for a response */
+static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
+{
+	unsigned long before;
+	dma_addr_t mfa;
+	u32 regh, regl;
+	u32 response;
+	int retval = 1;
+	int found = 0;
+
+	before = jiffies;
+
+	while (!found) {
+		if (sizeof(dma_addr_t) > 4) {
+			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
+			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+			mfa = ((u64)regh << 32) | regl;
+		} else
+			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+
+		response = (u32)mfa;
+
+		if (TW_RESID_OUT(response) == request_id)
+			found = 1;
+
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+
+		msleep(50);
+	}
+	retval = 0;
+out: 
+	return retval;
+} /* End twl_poll_response() */
+
+/* This function will drain the aen queue */
+static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
+{
+	int request_id = 0;
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Entry_ISO sglist[1];
+	int finished = 0, count = 0;
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int first_reset = 0, queue = 0, retval = 1;
+
+	if (no_check_reset)
+		first_reset = 0;
+	else
+		first_reset = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	do {
+		/* Send command to the board */
+		if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
+			goto out;
+		}
+
+		/* Now poll for completion */
+		if (twl_poll_response(tw_dev, request_id, 30)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
+			tw_dev->posted_request_count--;
+			goto out;
+		}
+
+		tw_dev->posted_request_count--;
+		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+		aen = le16_to_cpu(header->status_block.error);
+		queue = 0;
+		count++;
+
+		switch (aen) {
+		case TW_AEN_QUEUE_EMPTY:
+			if (first_reset != 1)
+				goto out;
+			else
+				finished = 1;
+			break;
+		case TW_AEN_SOFT_RESET:
+			if (first_reset == 0)
+				first_reset = 1;
+			else
+				queue = 1;
+			break;
+		case TW_AEN_SYNC_TIME_WITH_HOST:
+			break;
+		default:
+			queue = 1;
+		}
+
+		/* Now queue an event info */
+		if (queue)
+			twl_aen_queue_event(tw_dev, header);
+	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
+
+	if (count == TW_MAX_AEN_DRAIN)
+		goto out;
+
+	retval = 0;
+out:
+	tw_dev->state[request_id] = TW_S_INITIAL;
+	return retval;
+} /* End twl_aen_drain_queue() */
+
+/* This function will allocate memory and check if it is correctly aligned */
+static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
+{
+	int i;
+	dma_addr_t dma_handle;
+	unsigned long *cpu_addr;
+	int retval = 1;
+
+	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
+	if (!cpu_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
+		goto out;
+	}
+
+	memset(cpu_addr, 0, size*TW_Q_LENGTH);
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		switch(which) {
+		case 0:
+			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
+			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		case 1:
+			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
+			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		case 2:
+			tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
+			tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		}
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_allocate_memory() */
+
+/* This function will load the request id and various sgls for ioctls */
+static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+{
+	TW_Command *oldcommand;
+	TW_Command_Apache *newcommand;
+	TW_SG_Entry_ISO *sgl;
+	unsigned int pae = 0;
+
+	if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
+		pae = 1;
+
+	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+		newcommand = &full_command_packet->command.newcommand;
+		newcommand->request_id__lunl =
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
+		if (length) {
+			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+			newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
+		}
+		newcommand->sgl_entries__lunh =
+			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
+	} else {
+		oldcommand = &full_command_packet->command.oldcommand;
+		oldcommand->request_id = request_id;
+
+		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
+			/* Load the sg list */
+			sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
+			sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
+			sgl->length = TW_CPU_TO_SGL(length);
+			oldcommand->size += pae;
+			oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
+		}
+	}
+} /* End twl_load_sgl() */
+
+/* This function handles ioctl for the character device
+   This interface is used by smartmontools open source software */
+static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long timeout;
+	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
+	dma_addr_t dma_handle;
+	int request_id = 0;
+	TW_Ioctl_Driver_Command driver_command;
+	TW_Ioctl_Buf_Apache *tw_ioctl;
+	TW_Command_Full *full_command_packet;
+	TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
+	int retval = -EFAULT;
+	void __user *argp = (void __user *)arg;
+
+	/* Only let one of these through at a time */
+	if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
+		retval = -EINTR;
+		goto out;
+	}
+
+	/* First copy down the driver command */
+	if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
+		goto out2;
+
+	/* Check data buffer size */
+	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
+		retval = -EINVAL;
+		goto out2;
+	}
+
+	/* Hardware can only do multiple of 512 byte transfers */
+	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
+
+	/* Now allocate ioctl buf memory */
+	cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle, GFP_KERNEL);
+	if (!cpu_addr) {
+		retval = -ENOMEM;
+		goto out2;
+	}
+
+	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
+
+	/* Now copy down the entire ioctl */
+	if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
+		goto out3;
+
+	/* See which ioctl we are doing */
+	switch (cmd) {
+	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		twl_get_request_id(tw_dev, &request_id);
+
+		/* Flag internal command */
+		tw_dev->srb[request_id] = NULL;
+
+		/* Flag chrdev ioctl */
+		tw_dev->chrdev_request_id = request_id;
+
+		full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
+
+		/* Load request id and sglist for both command types */
+		twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+
+		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
+
+		/* Now post the command packet to the controller */
+		twl_post_command_packet(tw_dev, request_id);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
+
+		/* Now wait for command to complete */
+		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
+
+		/* We timed out, and didn't get an interrupt */
+		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
+			/* Now we need to reset the board */
+			printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
+			       tw_dev->host->host_no, TW_DRIVER, 0x6,
+			       cmd);
+			retval = -EIO;
+			twl_reset_device_extension(tw_dev, 1);
+			goto out3;
+		}
+
+		/* Now copy in the command packet response */
+		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
+		
+		/* Now complete the io */
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		tw_dev->posted_request_count--;
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twl_free_request_id(tw_dev, request_id);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+		break;
+	default:
+		retval = -ENOTTY;
+		goto out3;
+	}
+
+	/* Now copy the entire response to userspace */
+	if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
+		retval = 0;
+out3:
+	/* Now free ioctl buf memory */
+	dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
+out2:
+	mutex_unlock(&tw_dev->ioctl_lock);
+out:
+	return retval;
+} /* End twl_chrdev_ioctl() */
+
+/* This function handles open for the character device */
+static int twl_chrdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor_number;
+	int retval = -ENODEV;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		retval = -EACCES;
+		goto out;
+	}
+
+	cycle_kernel_lock();
+	minor_number = iminor(inode);
+	if (minor_number >= twl_device_extension_count)
+		goto out;
+	retval = 0;
+out:
+	return retval;
+} /* End twl_chrdev_open() */
+
+/* File operations struct for character device */
+static const struct file_operations twl_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= twl_chrdev_ioctl,
+	.open		= twl_chrdev_open,
+	.release	= NULL
+};
+
+/* This function passes sense data from firmware to scsi layer */
+static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
+{
+	TW_Command_Apache_Header *header;
+	TW_Command_Full *full_command_packet;
+	unsigned short error;
+	char *error_str;
+	int retval = 1;
+
+	header = tw_dev->sense_buffer_virt[i];
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+
+	/* Get embedded firmware error string */
+	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
+
+	/* Don't print error for Logical unit not supported during rollcall */
+	error = le16_to_cpu(header->status_block.error);
+	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
+		if (print_host)
+			printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       tw_dev->host->host_no,
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       header->status_block.error,
+			       error_str, 
+			       header->err_specific_desc);
+		else
+			printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       header->status_block.error,
+			       error_str,
+			       header->err_specific_desc);
+	}
+
+	if (copy_sense) {
+		memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
+		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
+		goto out;
+	}
+out:
+	return retval;
+} /* End twl_fill_sense() */
+
+/* This function will free up device extension resources */
+static void twl_free_device_extension(TW_Device_Extension *tw_dev)
+{
+	if (tw_dev->command_packet_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
+				    tw_dev->command_packet_virt[0],
+				    tw_dev->command_packet_phys[0]);
+
+	if (tw_dev->generic_buffer_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    TW_SECTOR_SIZE*TW_Q_LENGTH,
+				    tw_dev->generic_buffer_virt[0],
+				    tw_dev->generic_buffer_phys[0]);
+
+	if (tw_dev->sense_buffer_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    sizeof(TW_Command_Apache_Header)*
+				    TW_Q_LENGTH,
+				    tw_dev->sense_buffer_virt[0],
+				    tw_dev->sense_buffer_phys[0]);
+
+	kfree(tw_dev->event_queue[0]);
+} /* End twl_free_device_extension() */
+
+/* This function will get parameter table entries from the firmware */
+static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	void *retval = NULL;
+
+	/* Setup the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
+	command_packet->size              = TW_COMMAND_SIZE;
+	command_packet->request_id        = request_id;
+	command_packet->byte6_offset.block_count = cpu_to_le16(1);
+
+	/* Now setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = cpu_to_le16(table_id | 0x8000);
+	param->parameter_id = cpu_to_le16(parameter_id);
+	param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
+
+	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
+	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
+
+	/* Post the command packet to the board */
+	twl_post_command_packet(tw_dev, request_id);
+
+	/* Poll for completion */
+	if (twl_poll_response(tw_dev, request_id, 30))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
+	else
+		retval = (void *)&(param->data[0]);
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twl_get_param() */
+
+/* This function will send an initconnection command to controller */
+static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+ 			      u32 set_features, unsigned short current_fw_srl, 
+			      unsigned short current_fw_arch_id, 
+			      unsigned short current_fw_branch, 
+			      unsigned short current_fw_build, 
+			      unsigned short *fw_on_ctlr_srl, 
+			      unsigned short *fw_on_ctlr_arch_id, 
+			      unsigned short *fw_on_ctlr_branch, 
+			      unsigned short *fw_on_ctlr_build, 
+			      u32 *init_connect_result)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Initconnect *tw_initconnect;
+	int request_id = 0, retval = 1;
+
+	/* Initialize InitConnection command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	full_command_packet->header.header_desc.size_header = 128;
+	
+	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
+	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
+	tw_initconnect->request_id = request_id;
+	tw_initconnect->message_credits = cpu_to_le16(message_credits);
+	tw_initconnect->features = set_features;
+
+	/* Turn on 64-bit sgl support if we need to */
+	tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
+
+	tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
+
+	if (set_features & TW_EXTENDED_INIT_CONNECT) {
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
+		tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
+		tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
+		tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
+		tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
+	} else 
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
+
+	/* Send command packet to the board */
+	twl_post_command_packet(tw_dev, request_id);
+
+	/* Poll for completion */
+	if (twl_poll_response(tw_dev, request_id, 30)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
+	} else {
+		if (set_features & TW_EXTENDED_INIT_CONNECT) {
+			*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
+			*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
+			*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
+			*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
+			*init_connect_result = le32_to_cpu(tw_initconnect->result);
+		}
+		retval = 0;
+	}
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twl_initconnection() */
+
+/* This function will initialize the fields of a device extension */
+static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
+{
+	int i, retval = 1;
+
+	/* Initialize command packet buffers */
+	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
+		goto out;
+	}
+
+	/* Initialize generic buffer */
+	if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
+		goto out;
+	}
+
+	/* Allocate sense buffers */
+	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
+		goto out;
+	}
+
+	/* Allocate event info space */
+	tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
+	if (!tw_dev->event_queue[0]) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
+		goto out;
+	}
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->error_sequence_id = 1;
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+	mutex_init(&tw_dev->ioctl_lock);
+	init_waitqueue_head(&tw_dev->ioctl_wqueue);
+
+	retval = 0;
+out:
+	return retval;
+} /* End twl_initialize_device_extension() */
+
+/* This function will perform a pci-dma unmap */
+static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+	if (cmd->SCp.phase == TW_PHASE_SGLIST)
+		scsi_dma_unmap(cmd);
+} /* End twl_unmap_scsi_data() */
+
+/* This function will handle attention interrupts */
+static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
+{
+	int retval = 1;
+	u32 request_id, doorbell;
+
+	/* Read doorbell status */
+	doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
+
+	/* Check for controller errors */
+	if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
+		goto out;
+	}
+
+	/* Check if we need to perform an AEN drain */
+	if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
+		if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
+			twl_get_request_id(tw_dev, &request_id);
+			if (twl_aen_read_queue(tw_dev, request_id)) {
+				tw_dev->state[request_id] = TW_S_COMPLETED;
+				twl_free_request_id(tw_dev, request_id);
+				clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+			}
+		}
+	}
+
+	retval = 0;
+out:
+	/* Clear doorbell interrupt */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	/* Make sure the clear was flushed by reading it back */
+	readl(TWL_HOBDBC_REG_ADDR(tw_dev));
+
+	return retval;
+} /* End twl_handle_attention_interrupt() */
+
+/* Interrupt service routine */
+static irqreturn_t twl_interrupt(int irq, void *dev_instance)
+{
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
+	int i, handled = 0, error = 0;
+	dma_addr_t mfa = 0;
+	u32 reg, regl, regh, response, request_id = 0;
+	struct scsi_cmnd *cmd;
+	TW_Command_Full *full_command_packet;
+
+	spin_lock(tw_dev->host->host_lock);
+
+	/* Read host interrupt status */
+	reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
+
+	/* Check if this is our interrupt, otherwise bail */
+	if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
+		goto twl_interrupt_bail;
+
+	handled = 1;
+
+	/* If we are resetting, bail */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags))
+		goto twl_interrupt_bail;
+
+	/* Attention interrupt */
+	if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
+		if (twl_handle_attention_interrupt(tw_dev)) {
+			TWL_MASK_INTERRUPTS(tw_dev);
+			goto twl_interrupt_bail;
+		}
+	}
+
+	/* Response interrupt */
+	while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
+		if (sizeof(dma_addr_t) > 4) {
+			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
+			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+			mfa = ((u64)regh << 32) | regl;
+		} else
+			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
+
+		error = 0;
+		response = (u32)mfa;
+
+		/* Check for command packet error */
+		if (!TW_NOTMFA_OUT(response)) {
+			for (i=0;i<TW_Q_LENGTH;i++) {
+				if (tw_dev->sense_buffer_phys[i] == mfa) {
+					request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
+					if (tw_dev->srb[request_id] != NULL)
+						error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
+					else {
+						/* Skip ioctl error prints */
+						if (request_id != tw_dev->chrdev_request_id)
+							error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
+						else
+							memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
+					}
+
+					/* Now re-post the sense buffer */
+					writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
+					writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
+					break;
+				}
+			}
+		} else
+			request_id = TW_RESID_OUT(response);
+
+		full_command_packet = tw_dev->command_packet_virt[request_id];
+
+		/* Check for correct state */
+		if (tw_dev->state[request_id] != TW_S_POSTED) {
+			if (tw_dev->srb[request_id] != NULL) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
+				TWL_MASK_INTERRUPTS(tw_dev);
+				goto twl_interrupt_bail;
+			}
+		}
+
+		/* Check for internal command completion */
+		if (tw_dev->srb[request_id] == NULL) {
+			if (request_id != tw_dev->chrdev_request_id) {
+				if (twl_aen_complete(tw_dev, request_id))
+					TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
+			} else {
+				tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+				wake_up(&tw_dev->ioctl_wqueue);
+			}
+		} else {
+			cmd = tw_dev->srb[request_id];
+
+			if (!error)
+				cmd->result = (DID_OK << 16);
+			
+			/* Report residual bytes for single sgl */
+			if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
+				if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
+					scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
+			}
+
+			/* Now complete the io */
+			tw_dev->state[request_id] = TW_S_COMPLETED;
+			twl_free_request_id(tw_dev, request_id);
+			tw_dev->posted_request_count--;
+			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+			twl_unmap_scsi_data(tw_dev, request_id);
+		}
+
+		/* Check for another response interrupt */
+		reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
+	}
+
+twl_interrupt_bail:
+	spin_unlock(tw_dev->host->host_lock);
+	return IRQ_RETVAL(handled);
+} /* End twl_interrupt() */
+
+/* This function will poll for a register change */
+static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
+{
+	unsigned long before;
+	int retval = 1;
+	u32 reg_value;
+
+	reg_value = readl(reg);
+	before = jiffies;
+
+        while ((reg_value & value) != result) {
+		reg_value = readl(reg);
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+		msleep(50);
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twl_poll_register() */
+
+/* This function will reset a controller */
+static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
+{
+	int retval = 1;
+	int i = 0;
+	u32 status = 0;
+	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
+	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
+	u32 init_connect_result = 0;
+	int tries = 0;
+	int do_soft_reset = soft_reset;
+
+	while (tries < TW_MAX_RESET_TRIES) {
+		/* Do a soft reset if one is needed */
+		if (do_soft_reset) {
+			TWL_SOFT_RESET(tw_dev);
+
+			/* Make sure controller is in a good state */
+			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
+				tries++;
+				continue;
+			}
+			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
+				tries++;
+				continue;
+			}
+		}
+
+		/* Initconnect */
+		if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+				       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
+				       TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
+				       TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
+				       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
+				       &fw_on_ctlr_build, &init_connect_result)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Load sense buffers */
+		while (i < TW_Q_LENGTH) {
+			writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
+			writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
+
+			/* Check status for over-run after each write */
+			status = readl(TWL_STATUS_REG_ADDR(tw_dev));
+			if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
+			    i++;
+		}
+
+		/* Now check status */
+		status = readl(TWL_STATUS_REG_ADDR(tw_dev));
+		if (status) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Drain the AEN queue */
+		if (twl_aen_drain_queue(tw_dev, soft_reset)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Load rest of compatibility struct */
+		strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
+		tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
+		tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
+		tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
+		tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
+		tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
+		tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
+		tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
+		tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
+		tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
+
+		/* If we got here, controller is in a good state */
+		retval = 0;
+		goto out;
+	}
+out:
+	return retval;
+} /* End twl_reset_sequence() */
+
+/* This function will reset a device extension */
+static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
+{
+	int i = 0, retval = 1;
+	unsigned long flags = 0;
+
+	/* Block SCSI requests while we are resetting */
+	if (ioctl_reset)
+		scsi_block_requests(tw_dev->host);
+
+	set_bit(TW_IN_RESET, &tw_dev->flags);
+	TWL_MASK_INTERRUPTS(tw_dev);
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+
+	/* Abort all requests that are in progress */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		if ((tw_dev->state[i] != TW_S_FINISHED) &&
+		    (tw_dev->state[i] != TW_S_INITIAL) &&
+		    (tw_dev->state[i] != TW_S_COMPLETED)) {
+			if (tw_dev->srb[i]) {
+				tw_dev->srb[i]->result = (DID_RESET << 16);
+				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+				twl_unmap_scsi_data(tw_dev, i);
+			}
+		}
+	}
+
+	/* Reset queues and counts */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->posted_request_count = 0;
+
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+	if (twl_reset_sequence(tw_dev, 1))
+		goto out;
+
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+
+	clear_bit(TW_IN_RESET, &tw_dev->flags);
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+	retval = 0;
+out:
+	if (ioctl_reset)
+		scsi_unblock_requests(tw_dev->host);
+	return retval;
+} /* End twl_reset_device_extension() */
+
+/* This funciton returns unit geometry in cylinders/heads/sectors */
+static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
+{
+	int heads, sectors;
+	TW_Device_Extension *tw_dev;
+
+	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
+
+	if (capacity >= 0x200000) {
+		heads = 255;
+		sectors = 63;
+	} else {
+		heads = 64;
+		sectors = 32;
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
+
+	return 0;
+} /* End twl_scsi_biosparam() */
+
+/* This is the new scsi eh reset function */
+static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+{
+	TW_Device_Extension *tw_dev = NULL;
+	int retval = FAILED;
+
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	tw_dev->num_resets++;
+
+	sdev_printk(KERN_WARNING, SCpnt->device,
+		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
+		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
+
+	/* Make sure we are not issuing an ioctl or resetting from ioctl */
+	mutex_lock(&tw_dev->ioctl_lock);
+
+	/* Now reset the card and some of the device extension data */
+	if (twl_reset_device_extension(tw_dev, 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
+		goto out;
+	}
+
+	retval = SUCCESS;
+out:
+	mutex_unlock(&tw_dev->ioctl_lock);
+	return retval;
+} /* End twl_scsi_eh_reset() */
+
+/* This is the main scsi queue function to handle scsi opcodes */
+static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+	int request_id, retval;
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	/* If we are resetting due to timed out ioctl, report as busy */
+	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
+		retval = SCSI_MLQUEUE_HOST_BUSY;
+		goto out;
+	}
+
+	/* Save done function into scsi_cmnd struct */
+	SCpnt->scsi_done = done;
+		
+	/* Get a free request id */
+	twl_get_request_id(tw_dev, &request_id);
+
+	/* Save the scsi command for use by the ISR */
+	tw_dev->srb[request_id] = SCpnt;
+
+	/* Initialize phase to zero */
+	SCpnt->SCp.phase = TW_PHASE_INITIAL;
+
+	retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+	if (retval) {
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twl_free_request_id(tw_dev, request_id);
+		SCpnt->result = (DID_ERROR << 16);
+		done(SCpnt);
+		retval = 0;
+	}
+out:
+	return retval;
+} /* End twl_scsi_queue() */
+
+/* This function tells the controller to shut down */
+static void __twl_shutdown(TW_Device_Extension *tw_dev)
+{
+	/* Disable interrupts */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	/* Free up the IRQ */
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+	printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
+
+	/* Tell the card we are shutting down */
+	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
+	} else {
+		printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
+	}
+
+	/* Clear doorbell interrupt just before exit */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+} /* End __twl_shutdown() */
+
+/* Wrapper for __twl_shutdown */
+static void twl_shutdown(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev;
+
+	if (!host)
+		return;
+
+	tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	if (tw_dev->online) 
+		__twl_shutdown(tw_dev);
+} /* End twl_shutdown() */
+
+/* This function configures unit settings when a unit is coming on-line */
+static int twl_slave_configure(struct scsi_device *sdev)
+{
+	/* Force 60 second timeout */
+	blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
+
+	return 0;
+} /* End twl_slave_configure() */
+
+/* scsi_host_template initializer */
+static struct scsi_host_template driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "3w-sas",
+	.queuecommand		= twl_scsi_queue,
+	.eh_host_reset_handler	= twl_scsi_eh_reset,
+	.bios_param		= twl_scsi_biosparam,
+	.change_queue_depth	= twl_change_queue_depth,
+	.can_queue		= TW_Q_LENGTH-2,
+	.slave_configure	= twl_slave_configure,
+	.this_id		= -1,
+	.sg_tablesize		= TW_LIBERATOR_MAX_SGL_LENGTH,
+	.max_sectors		= TW_MAX_SECTORS,
+	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.shost_attrs		= twl_host_attrs,
+	.emulated		= 1
+};
+
+/* This function will probe and initialize a card */
+static int __devinit twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+{
+	struct Scsi_Host *host = NULL;
+	TW_Device_Extension *tw_dev;
+	int retval = -ENODEV;
+	int *ptr_phycount, phycount=0;
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
+		goto out_disable_device;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+			TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
+			retval = -ENODEV;
+			goto out_disable_device;
+		}
+
+	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
+	if (!host) {
+		TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
+		retval = -ENOMEM;
+		goto out_disable_device;
+	}
+	tw_dev = shost_priv(host);
+
+	/* Save values to device extension */
+	tw_dev->host = host;
+	tw_dev->tw_pci_dev = pdev;
+
+	if (twl_initialize_device_extension(tw_dev)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
+		goto out_free_device_extension;
+	}
+
+	/* Request IO regions */
+	retval = pci_request_regions(pdev, "3w-sas");
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
+		goto out_free_device_extension;
+	}
+
+	/* Save base address, use region 1 */
+	tw_dev->base_addr = pci_iomap(pdev, 1, 0);
+	if (!tw_dev->base_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
+		goto out_release_mem_region;
+	}
+
+	/* Disable interrupts on the card */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	/* Initialize the card */
+	if (twl_reset_sequence(tw_dev, 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
+		goto out_iounmap;
+	}
+
+	/* Set host specific parameters */
+	host->max_id = TW_MAX_UNITS;
+	host->max_cmd_len = TW_MAX_CDB_LEN;
+	host->max_lun = TW_MAX_LUNS;
+	host->max_channel = 0;
+
+	/* Register the card with the kernel SCSI layer */
+	retval = scsi_add_host(host, &pdev->dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
+		goto out_iounmap;
+	}
+
+	pci_set_drvdata(pdev, host);
+
+	printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
+	       host->host_no,
+	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
+				     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
+	       (u64)pci_resource_start(pdev, 1), pdev->irq);
+
+	ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
+				     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
+	if (ptr_phycount)
+		phycount = le32_to_cpu(*(int *)ptr_phycount);
+
+	printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
+	       host->host_no,
+	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
+				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
+	       (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
+				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
+	       phycount);
+
+	/* Try to enable MSI */
+	if (use_msi && !pci_enable_msi(pdev))
+		set_bit(TW_USING_MSI, &tw_dev->flags);
+
+	/* Now setup the interrupt handler */
+	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
+		goto out_remove_host;
+	}
+
+	twl_device_extension_list[twl_device_extension_count] = tw_dev;
+	twl_device_extension_count++;
+
+	/* Re-enable interrupts on the card */
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+	
+	/* Finally, scan the host */
+	scsi_scan_host(host);
+
+	/* Add sysfs binary files */
+	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
+	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
+
+	if (twl_major == -1) {
+		if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
+			TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
+	}
+	tw_dev->online = 1;
+	return 0;
+
+out_remove_host:
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_disable_msi(pdev);
+	scsi_remove_host(host);
+out_iounmap:
+	iounmap(tw_dev->base_addr);
+out_release_mem_region:
+	pci_release_regions(pdev);
+out_free_device_extension:
+	twl_free_device_extension(tw_dev);
+	scsi_host_put(host);
+out_disable_device:
+	pci_disable_device(pdev);
+
+	return retval;
+} /* End twl_probe() */
+
+/* This function is called to remove a device */
+static void twl_remove(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev;
+
+	if (!host)
+		return;
+
+	tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	if (!tw_dev->online)
+		return;
+
+	/* Remove sysfs binary files */
+	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
+	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
+
+	scsi_remove_host(tw_dev->host);
+
+	/* Unregister character device */
+	if (twl_major >= 0) {
+		unregister_chrdev(twl_major, "twl");
+		twl_major = -1;
+	}
+
+	/* Shutdown the card */
+	__twl_shutdown(tw_dev);
+
+	/* Disable MSI if enabled */
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_disable_msi(pdev);
+
+	/* Free IO remapping */
+	iounmap(tw_dev->base_addr);
+
+	/* Free up the mem region */
+	pci_release_regions(pdev);
+
+	/* Free up device extension resources */
+	twl_free_device_extension(tw_dev);
+
+	scsi_host_put(tw_dev->host);
+	pci_disable_device(pdev);
+	twl_device_extension_count--;
+} /* End twl_remove() */
+
+#ifdef CONFIG_PM
+/* This function is called on PCI suspend */
+static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
+	/* Disable interrupts */
+	TWL_MASK_INTERRUPTS(tw_dev);
+
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+	/* Tell the card we are shutting down */
+	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
+	} else {
+		printk(KERN_WARNING "3w-sas: Suspend complete.\n");
+	}
+
+	/* Clear doorbell interrupt */
+	TWL_CLEAR_DB_INTERRUPT(tw_dev);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+} /* End twl_suspend() */
+
+/* This function is called on PCI resume */
+static int twl_resume(struct pci_dev *pdev)
+{
+	int retval = 0;
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
+		return retval;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+			TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
+			retval = -ENODEV;
+			goto out_disable_device;
+		}
+
+	/* Initialize the card */
+	if (twl_reset_sequence(tw_dev, 0)) {
+		retval = -ENODEV;
+		goto out_disable_device;
+	}
+
+	/* Now setup the interrupt handler */
+	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
+		retval = -ENODEV;
+		goto out_disable_device;
+	}
+
+	/* Now enable MSI if enabled */
+	if (test_bit(TW_USING_MSI, &tw_dev->flags))
+		pci_enable_msi(pdev);
+
+	/* Re-enable interrupts on the card */
+	TWL_UNMASK_INTERRUPTS(tw_dev);
+
+	printk(KERN_WARNING "3w-sas: Resume complete.\n");
+	return 0;
+
+out_disable_device:
+	scsi_remove_host(host);
+	pci_disable_device(pdev);
+
+	return retval;
+} /* End twl_resume() */
+#endif
+
+/* PCI Devices supported by this driver */
+static struct pci_device_id twl_pci_tbl[] __devinitdata = {
+	{ PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
+
+/* pci_driver initializer */
+static struct pci_driver twl_driver = {
+	.name		= "3w-sas",
+	.id_table	= twl_pci_tbl,
+	.probe		= twl_probe,
+	.remove		= twl_remove,
+#ifdef CONFIG_PM
+	.suspend	= twl_suspend,
+	.resume		= twl_resume,
+#endif
+	.shutdown	= twl_shutdown
+};
+
+/* This function is called on driver initialization */
+static int __init twl_init(void)
+{
+	printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
+
+	return pci_register_driver(&twl_driver);
+} /* End twl_init() */
+
+/* This function is called on driver exit */
+static void __exit twl_exit(void)
+{
+	pci_unregister_driver(&twl_driver);
+} /* End twl_exit() */
+
+module_init(twl_init);
+module_exit(twl_exit);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/3w-sas.h linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/3w-sas.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/3w-sas.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,396 @@
+/*
+   3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@lsi.com>
+
+   Copyright (C) 2009 LSI 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 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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   You 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
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@lsi.com
+
+   For more information, goto:
+   http://www.lsi.com
+*/
+
+#ifndef _3W_SAS_H
+#define _3W_SAS_H
+
+/* AEN severity table */
+static char *twl_aen_severity_table[] =
+{
+	"None", "ERROR", "WARNING", "INFO", "DEBUG", NULL
+};
+
+/* Liberator register offsets */
+#define TWL_STATUS                         0x0  /* Status */
+#define TWL_HIBDB                          0x20 /* Inbound doorbell */
+#define TWL_HISTAT                         0x30 /* Host interrupt status */
+#define TWL_HIMASK                         0x34 /* Host interrupt mask */
+#define TWL_HOBDB			   0x9C /* Outbound doorbell */
+#define TWL_HOBDBC                         0xA0 /* Outbound doorbell clear */
+#define TWL_SCRPD3                         0xBC /* Scratchpad */
+#define TWL_HIBQPL                         0xC0 /* Host inbound Q low */
+#define TWL_HIBQPH                         0xC4 /* Host inbound Q high */
+#define TWL_HOBQPL                         0xC8 /* Host outbound Q low */
+#define TWL_HOBQPH                         0xCC /* Host outbound Q high */
+#define TWL_HISTATUS_VALID_INTERRUPT	   0xC
+#define TWL_HISTATUS_ATTENTION_INTERRUPT   0x4
+#define TWL_HISTATUS_RESPONSE_INTERRUPT	   0x8
+#define TWL_STATUS_OVERRUN_SUBMIT	   0x2000
+#define TWL_ISSUE_SOFT_RESET		   0x100
+#define TWL_CONTROLLER_READY		   0x2000
+#define TWL_DOORBELL_CONTROLLER_ERROR	   0x200000
+#define TWL_DOORBELL_ATTENTION_INTERRUPT   0x40000
+#define TWL_PULL_MODE			   0x1
+
+/* Command packet opcodes used by the driver */
+#define TW_OP_INIT_CONNECTION 0x1
+#define TW_OP_GET_PARAM	      0x12
+#define TW_OP_SET_PARAM	      0x13
+#define TW_OP_EXECUTE_SCSI    0x10
+
+/* Asynchronous Event Notification (AEN) codes used by the driver */
+#define TW_AEN_QUEUE_EMPTY       0x0000
+#define TW_AEN_SOFT_RESET        0x0001
+#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
+#define TW_AEN_SEVERITY_ERROR    0x1
+#define TW_AEN_SEVERITY_DEBUG    0x4
+#define TW_AEN_NOT_RETRIEVED 0x1
+
+/* Command state defines */
+#define TW_S_INITIAL   0x1  /* Initial state */
+#define TW_S_STARTED   0x2  /* Id in use */
+#define TW_S_POSTED    0x4  /* Posted to the controller */
+#define TW_S_COMPLETED 0x8  /* Completed by isr */
+#define TW_S_FINISHED  0x10 /* I/O completely done */
+
+/* Compatibility defines */
+#define TW_9750_ARCH_ID 10
+#define TW_CURRENT_DRIVER_SRL 40
+#define TW_CURRENT_DRIVER_BUILD 0
+#define TW_CURRENT_DRIVER_BRANCH 0
+
+/* Phase defines */
+#define TW_PHASE_INITIAL 0
+#define TW_PHASE_SGLIST  2
+
+/* Misc defines */
+#define TW_SECTOR_SIZE                        512
+#define TW_MAX_UNITS			      32
+#define TW_INIT_MESSAGE_CREDITS		      0x100
+#define TW_INIT_COMMAND_PACKET_SIZE	      0x3
+#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
+#define TW_EXTENDED_INIT_CONNECT	      0x2
+#define TW_BASE_FW_SRL			      24
+#define TW_BASE_FW_BRANCH		      0
+#define TW_BASE_FW_BUILD		      1
+#define TW_Q_LENGTH			      256
+#define TW_Q_START			      0
+#define TW_MAX_SLOT			      32
+#define TW_MAX_RESET_TRIES		      2
+#define TW_MAX_CMDS_PER_LUN		      254
+#define TW_MAX_AEN_DRAIN		      255
+#define TW_IN_RESET                           2
+#define TW_USING_MSI			      3
+#define TW_IN_ATTENTION_LOOP		      4
+#define TW_MAX_SECTORS                        256
+#define TW_MAX_CDB_LEN                        16
+#define TW_IOCTL_CHRDEV_TIMEOUT               60 /* 60 seconds */
+#define TW_IOCTL_CHRDEV_FREE                  -1
+#define TW_COMMAND_OFFSET                     128 /* 128 bytes */
+#define TW_VERSION_TABLE                      0x0402
+#define TW_TIMEKEEP_TABLE		      0x040A
+#define TW_INFORMATION_TABLE		      0x0403
+#define TW_PARAM_FWVER			      3
+#define TW_PARAM_FWVER_LENGTH		      16
+#define TW_PARAM_BIOSVER		      4
+#define TW_PARAM_BIOSVER_LENGTH		      16
+#define TW_PARAM_MODEL			      8
+#define TW_PARAM_MODEL_LENGTH		      16
+#define TW_PARAM_PHY_SUMMARY_TABLE	      1
+#define TW_PARAM_PHYCOUNT		      2
+#define TW_PARAM_PHYCOUNT_LENGTH	      1
+#define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108  // Used by smartmontools
+#define TW_ALLOCATION_LENGTH		      128
+#define TW_SENSE_DATA_LENGTH		      18
+#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
+#define TW_ERROR_INVALID_FIELD_IN_CDB	      0x10d
+#define TW_ERROR_UNIT_OFFLINE                 0x128
+#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
+#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
+#define TW_DRIVER 			      6
+#ifndef PCI_DEVICE_ID_3WARE_9750
+#define PCI_DEVICE_ID_3WARE_9750 0x1010
+#endif
+
+/* Bitmask macros to eliminate bitfields */
+
+/* opcode: 5, reserved: 3 */
+#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_OP_OUT(x) (x & 0x1f)
+
+/* opcode: 5, sgloffset: 3 */
+#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
+
+/* severity: 3, reserved: 5 */
+#define TW_SEV_OUT(x) (x & 0x7)
+
+/* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */
+#define TW_RESID_OUT(x) ((x >> 16) & 0xffff)
+#define TW_NOTMFA_OUT(x) (x & 0x1)
+
+/* request_id: 12, lun: 4 */
+#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
+#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
+
+/* Register access macros */
+#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
+#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
+#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
+#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
+#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
+#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
+#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
+#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
+#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
+#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
+#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
+#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
+#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
+#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
+#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
+
+/* Macros */
+#define TW_PRINTK(h,a,b,c) { \
+if (h) \
+printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
+else \
+printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
+}
+#define TW_MAX_LUNS 16
+#define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)
+#define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)
+#define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)
+#define TW_PADDING_LENGTH_LIBERATOR 136
+#define TW_PADDING_LENGTH_LIBERATOR_OLD 132
+#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
+
+#pragma pack(1)
+
+/* SGL entry */
+typedef struct TAG_TW_SG_Entry_ISO {
+	dma_addr_t address;
+	dma_addr_t length;
+} TW_SG_Entry_ISO;
+
+/* Old Command Packet with ISO SGL */
+typedef struct TW_Command {
+	unsigned char opcode__sgloffset;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char unit__hostid;
+	/* Second DWORD */
+	unsigned char status;
+	unsigned char flags;
+	union {
+		unsigned short block_count;
+		unsigned short parameter_count;
+	} byte6_offset;
+	union {
+		struct {
+			u32 lba;
+			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
+			unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];
+		} io;
+		struct {
+			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
+			u32 padding;
+			unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];
+		} param;
+	} byte8_offset;
+} TW_Command;
+
+/* New Command Packet with ISO SGL */
+typedef struct TAG_TW_Command_Apache {
+	unsigned char opcode__reserved;
+	unsigned char unit;
+	unsigned short request_id__lunl;
+	unsigned char status;
+	unsigned char sgl_offset;
+	unsigned short sgl_entries__lunh;
+	unsigned char cdb[16];
+	TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];
+	unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];
+} TW_Command_Apache;
+
+/* New command packet header */
+typedef struct TAG_TW_Command_Apache_Header {
+	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
+	struct {
+		char reserved[4];
+		unsigned short error;
+		unsigned char padding;
+		unsigned char severity__reserved;
+	} status_block;
+	unsigned char err_specific_desc[98];
+	struct {
+		unsigned char size_header;
+		unsigned short request_id;
+		unsigned char size_sense;
+	} header_desc;
+} TW_Command_Apache_Header;
+
+/* This struct is a union of the 2 command packets */
+typedef struct TAG_TW_Command_Full {
+	TW_Command_Apache_Header header;
+	union {
+		TW_Command oldcommand;
+		TW_Command_Apache newcommand;
+	} command;
+} TW_Command_Full;
+
+/* Initconnection structure */
+typedef struct TAG_TW_Initconnect {
+	unsigned char opcode__reserved;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char res2;
+	unsigned char status;
+	unsigned char flags;
+	unsigned short message_credits;
+	u32 features;
+	unsigned short fw_srl;
+	unsigned short fw_arch_id;
+	unsigned short fw_branch;
+	unsigned short fw_build;
+	u32 result;
+} TW_Initconnect;
+
+/* Event info structure */
+typedef struct TAG_TW_Event
+{
+	unsigned int sequence_id;
+	unsigned int time_stamp_sec;
+	unsigned short aen_code;
+	unsigned char severity;
+	unsigned char retrieved;
+	unsigned char repeat_count;
+	unsigned char parameter_len;
+	unsigned char parameter_data[98];
+} TW_Event;
+
+typedef struct TAG_TW_Ioctl_Driver_Command {
+	unsigned int control_code;
+	unsigned int status;
+	unsigned int unique_id;
+	unsigned int sequence_id;
+	unsigned int os_specific;
+	unsigned int buffer_length;
+} TW_Ioctl_Driver_Command;
+
+typedef struct TAG_TW_Ioctl_Apache {
+	TW_Ioctl_Driver_Command driver_command;
+        char padding[488];
+	TW_Command_Full firmware_command;
+	char data_buffer[1];
+} TW_Ioctl_Buf_Apache;
+
+/* GetParam descriptor */
+typedef struct {
+	unsigned short	table_id;
+	unsigned short	parameter_id;
+	unsigned short	parameter_size_bytes;
+	unsigned short  actual_parameter_size_bytes;
+	unsigned char	data[1];
+} TW_Param_Apache;
+
+/* Compatibility information structure */
+typedef struct TAG_TW_Compatibility_Info
+{
+	char driver_version[32];
+	unsigned short working_srl;
+	unsigned short working_branch;
+	unsigned short working_build;
+	unsigned short driver_srl_high;
+	unsigned short driver_branch_high;
+	unsigned short driver_build_high;
+	unsigned short driver_srl_low;
+	unsigned short driver_branch_low;
+	unsigned short driver_build_low;
+	unsigned short fw_on_ctlr_srl;
+	unsigned short fw_on_ctlr_branch;
+	unsigned short fw_on_ctlr_build;
+} TW_Compatibility_Info;
+
+#pragma pack()
+
+typedef struct TAG_TW_Device_Extension {
+	void                     __iomem *base_addr;
+	unsigned long	       	*generic_buffer_virt[TW_Q_LENGTH];
+	dma_addr_t	       	generic_buffer_phys[TW_Q_LENGTH];
+	TW_Command_Full	       	*command_packet_virt[TW_Q_LENGTH];
+	dma_addr_t		command_packet_phys[TW_Q_LENGTH];
+	TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
+	dma_addr_t		sense_buffer_phys[TW_Q_LENGTH];
+	struct pci_dev		*tw_pci_dev;
+	struct scsi_cmnd	*srb[TW_Q_LENGTH];
+	unsigned char		free_queue[TW_Q_LENGTH];
+	unsigned char		free_head;
+	unsigned char		free_tail;
+	int     		state[TW_Q_LENGTH];
+	unsigned int		posted_request_count;
+	unsigned int		max_posted_request_count;
+	unsigned int		max_sgl_entries;
+	unsigned int		sgl_entries;
+	unsigned int		num_resets;
+	unsigned int		sector_count;
+	unsigned int		max_sector_count;
+	unsigned int		aen_count;
+	struct Scsi_Host	*host;
+	long			flags;
+	TW_Event                *event_queue[TW_Q_LENGTH];
+	unsigned char           error_index;
+	unsigned int            error_sequence_id;
+	int			chrdev_request_id;
+	wait_queue_head_t	ioctl_wqueue;
+	struct mutex		ioctl_lock;
+	TW_Compatibility_Info	tw_compat_info;
+	char			online;
+} TW_Device_Extension;
+
+#endif /* _3W_SAS_H */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/3w-xxxx.c linux-libre-2.6.33-gnu1/drivers/scsi/3w-xxxx.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/3w-xxxx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/3w-xxxx.c	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
 
    Copyright (C) 1999-2009 3ware Inc.
 
-   Kernel compatiblity By: 	Andre Hedrick <andre@suse.com>
+   Kernel compatibility By: 	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
    
    Further tiny build fixes and trivial hoovering    Alan Cox
@@ -521,8 +521,12 @@ static ssize_t tw_show_stats(struct devi
 } /* End tw_show_stats() */
 
 /* This function will set a devices queue depth */
-static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth)
+static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
+				 int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > TW_Q_LENGTH-2)
 		queue_depth = TW_Q_LENGTH-2;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/53c700.c linux-libre-2.6.33-gnu1/drivers/scsi/53c700.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/53c700.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/53c700.c	2010-02-24 13:52:17.000000000 -0500
@@ -175,7 +175,7 @@ STATIC void NCR_700_chip_reset(struct Sc
 STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
 STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
 STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
-static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
+static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth, int reason);
 static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
@@ -1491,7 +1491,7 @@ NCR_700_intr(int irq, void *dev_id)
 	unsigned long flags;
 	int handled = 0;
 
-	/* Use the host lock to serialise acess to the 53c700
+	/* Use the host lock to serialise access to the 53c700
 	 * hardware.  Note: In future, we may need to take the queue
 	 * lock to enter the done routines.  When that happens, we
 	 * need to ensure that for this driver, the host lock and the
@@ -2082,8 +2082,11 @@ NCR_700_slave_destroy(struct scsi_device
 }
 
 static int
-NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (depth > NCR_700_MAX_TAGS)
 		depth = NCR_700_MAX_TAGS;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/aachba.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/aachba.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/aachba.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/aachba.c	2010-02-24 13:52:17.000000000 -0500
@@ -293,7 +293,10 @@ int aac_get_config_status(struct aac_dev
 			status = -EINVAL;
 		}
 	}
-	aac_fib_complete(fibptr);
+	/* Do not set XferState to zero unless receives a response from F/W */
+	if (status >= 0)
+		aac_fib_complete(fibptr);
+
 	/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
 	if (status >= 0) {
 		if ((aac_commit == 1) || commit_flag) {
@@ -310,13 +313,18 @@ int aac_get_config_status(struct aac_dev
 				    FsaNormal,
 				    1, 1,
 				    NULL, NULL);
-			aac_fib_complete(fibptr);
+			/* Do not set XferState to zero unless
+			 * receives a response from F/W */
+			if (status >= 0)
+				aac_fib_complete(fibptr);
 		} else if (aac_commit == 0) {
 			printk(KERN_WARNING
 			  "aac_get_config_status: Foreign device configurations are being ignored\n");
 		}
 	}
-	aac_fib_free(fibptr);
+	/* FIB should be freed only after getting the response from the F/W */
+	if (status != -ERESTARTSYS)
+		aac_fib_free(fibptr);
 	return status;
 }
 
@@ -355,7 +363,9 @@ int aac_get_containers(struct aac_dev *d
 		maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
 		aac_fib_complete(fibptr);
 	}
-	aac_fib_free(fibptr);
+	/* FIB should be freed only after getting the response from the F/W */
+	if (status != -ERESTARTSYS)
+		aac_fib_free(fibptr);
 
 	if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
 		maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
@@ -1245,8 +1255,12 @@ int aac_get_adapter_info(struct aac_dev*
 			 NULL);
 
 	if (rcode < 0) {
-		aac_fib_complete(fibptr);
-		aac_fib_free(fibptr);
+		/* FIB should be freed only after
+		 * getting the response from the F/W */
+		if (rcode != -ERESTARTSYS) {
+			aac_fib_complete(fibptr);
+			aac_fib_free(fibptr);
+		}
 		return rcode;
 	}
 	memcpy(&dev->adapter_info, info, sizeof(*info));
@@ -1270,6 +1284,12 @@ int aac_get_adapter_info(struct aac_dev*
 
 		if (rcode >= 0)
 			memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
+		if (rcode == -ERESTARTSYS) {
+			fibptr = aac_fib_alloc(dev);
+			if (!fibptr)
+				return -ENOMEM;
+		}
+
 	}
 
 
@@ -1470,9 +1490,11 @@ int aac_get_adapter_info(struct aac_dev*
 			  (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
 		}
 	}
-
-	aac_fib_complete(fibptr);
-	aac_fib_free(fibptr);
+	/* FIB should be freed only after getting the response from the F/W */
+	if (rcode != -ERESTARTSYS) {
+		aac_fib_complete(fibptr);
+		aac_fib_free(fibptr);
+	}
 
 	return rcode;
 }
@@ -1633,6 +1655,7 @@ static int aac_read(struct scsi_cmnd * s
 	 *	Alocate and initialize a Fib
 	 */
 	if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
+		printk(KERN_WARNING "aac_read: fib allocation failed\n");
 		return -1;
 	}
 
@@ -1712,9 +1735,14 @@ static int aac_write(struct scsi_cmnd *
 	 *	Allocate and initialize a Fib then setup a BlockWrite command
 	 */
 	if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
-		scsicmd->result = DID_ERROR << 16;
-		scsicmd->scsi_done(scsicmd);
-		return 0;
+		/* FIB temporarily unavailable,not catastrophic failure */
+
+		/* scsicmd->result = DID_ERROR << 16;
+		 * scsicmd->scsi_done(scsicmd);
+		 * return 0;
+		 */
+		printk(KERN_WARNING "aac_write: fib allocation failed\n");
+		return -1;
 	}
 
 	status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/aacraid.h linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/aacraid.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/aacraid.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/aacraid.h	2010-02-24 13:52:17.000000000 -0500
@@ -12,7 +12,7 @@
  *----------------------------------------------------------------------------*/
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2461
+# define AAC_DRIVER_BUILD 24702
 # define AAC_DRIVER_BRANCH "-ms"
 #endif
 #define MAXIMUM_NUM_CONTAINERS	32
@@ -526,10 +526,10 @@ struct aac_driver_ident
 
 /*
  *	The adapter interface specs all queues to be located in the same
- *	physically contigous block. The host structure that defines the
+ *	physically contiguous block. The host structure that defines the
  *	commuication queues will assume they are each a separate physically
- *	contigous memory region that will support them all being one big
- *	contigous block.
+ *	contiguous memory region that will support them all being one big
+ *	contiguous block.
  *	There is a command and response queue for each level and direction of
  *	commuication. These regions are accessed by both the host and adapter.
  */
@@ -1036,6 +1036,9 @@ struct aac_dev
 	u8			printf_enabled;
 	u8			in_reset;
 	u8			msi;
+	int			management_fib_count;
+	spinlock_t		manage_lock;
+
 };
 
 #define aac_adapter_interrupt(dev) \
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/commctrl.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/commctrl.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/commctrl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/commctrl.c	2010-02-24 13:52:17.000000000 -0500
@@ -153,7 +153,7 @@ cleanup:
 		fibptr->hw_fib_pa = hw_fib_pa;
 		fibptr->hw_fib_va = hw_fib;
 	}
-	if (retval != -EINTR)
+	if (retval != -ERESTARTSYS)
 		aac_fib_free(fibptr);
 	return retval;
 }
@@ -322,7 +322,7 @@ return_fib:
 		}
 		if (f.wait) {
 			if(down_interruptible(&fibctx->wait_sem) < 0) {
-				status = -EINTR;
+				status = -ERESTARTSYS;
 			} else {
 				/* Lock again and retry */
 				spin_lock_irqsave(&dev->fib_lock, flags);
@@ -593,10 +593,10 @@ static int aac_send_raw_srb(struct aac_d
 				u64 addr;
 				void* p;
 				if (upsg->sg[i].count >
-				    (dev->adapter_info.options &
+				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
-				      65536) {
+				      65536)) {
 					rcode = -EINVAL;
 					goto cleanup;
 				}
@@ -645,10 +645,10 @@ static int aac_send_raw_srb(struct aac_d
 				u64 addr;
 				void* p;
 				if (usg->sg[i].count >
-				    (dev->adapter_info.options &
+				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
-				      65536) {
+				      65536)) {
 					rcode = -EINVAL;
 					goto cleanup;
 				}
@@ -695,10 +695,10 @@ static int aac_send_raw_srb(struct aac_d
 				uintptr_t addr;
 				void* p;
 				if (usg->sg[i].count >
-				    (dev->adapter_info.options &
+				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
-				      65536) {
+				      65536)) {
 					rcode = -EINVAL;
 					goto cleanup;
 				}
@@ -734,10 +734,10 @@ static int aac_send_raw_srb(struct aac_d
 				dma_addr_t addr;
 				void* p;
 				if (upsg->sg[i].count >
-				    (dev->adapter_info.options &
+				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
-				      65536) {
+				      65536)) {
 					rcode = -EINVAL;
 					goto cleanup;
 				}
@@ -772,8 +772,8 @@ static int aac_send_raw_srb(struct aac_d
 		psg->count = cpu_to_le32(sg_indx+1);
 		status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
 	}
-	if (status == -EINTR) {
-		rcode = -EINTR;
+	if (status == -ERESTARTSYS) {
+		rcode = -ERESTARTSYS;
 		goto cleanup;
 	}
 
@@ -810,7 +810,7 @@ cleanup:
 	for(i=0; i <= sg_indx; i++){
 		kfree(sg_list[i]);
 	}
-	if (rcode != -EINTR) {
+	if (rcode != -ERESTARTSYS) {
 		aac_fib_complete(srbfib);
 		aac_fib_free(srbfib);
 	}
@@ -848,7 +848,7 @@ int aac_do_ioctl(struct aac_dev * dev, i
 	 */
 
 	status = aac_dev_ioctl(dev, cmd, arg);
-	if(status != -ENOTTY)
+	if (status != -ENOTTY)
 		return status;
 
 	switch (cmd) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/comminit.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/comminit.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/comminit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/comminit.c	2010-02-24 13:52:17.000000000 -0500
@@ -194,7 +194,9 @@ int aac_send_shutdown(struct aac_dev * d
 
 	if (status >= 0)
 		aac_fib_complete(fibctx);
-	aac_fib_free(fibctx);
+	/* FIB should be freed only after getting the response from the F/W */
+	if (status != -ERESTARTSYS)
+		aac_fib_free(fibctx);
 	return status;
 }
 
@@ -226,7 +228,7 @@ static int aac_comm_init(struct aac_dev
 	spin_lock_init(&dev->fib_lock);
 
 	/*
-	 *	Allocate the physically contigous space for the commuication
+	 *	Allocate the physically contiguous space for the commuication
 	 *	queue headers. 
 	 */
 
@@ -304,6 +306,8 @@ struct aac_dev *aac_init_adapter(struct
 	/*
 	 *	Check the preferred comm settings, defaults from template.
 	 */
+	dev->management_fib_count = 0;
+	spin_lock_init(&dev->manage_lock);
 	dev->max_fib_size = sizeof(struct hw_fib);
 	dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
 		- sizeof(struct aac_fibhdr)
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/commsup.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/commsup.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/commsup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/commsup.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,14 @@ struct fib *aac_fib_alloc(struct aac_dev
 
 void aac_fib_free(struct fib *fibptr)
 {
-	unsigned long flags;
+	unsigned long flags, flagsv;
+
+	spin_lock_irqsave(&fibptr->event_lock, flagsv);
+	if (fibptr->done == 2) {
+		spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
+		return;
+	}
+	spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
 
 	spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
 	if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
@@ -390,6 +397,8 @@ int aac_fib_send(u16 command, struct fib
 	struct hw_fib * hw_fib = fibptr->hw_fib_va;
 	unsigned long flags = 0;
 	unsigned long qflags;
+	unsigned long mflags = 0;
+
 
 	if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
 		return -EBUSY;
@@ -471,9 +480,31 @@ int aac_fib_send(u16 command, struct fib
 	if (!dev->queues)
 		return -EBUSY;
 
-	if(wait)
+	if (wait) {
+
+		spin_lock_irqsave(&dev->manage_lock, mflags);
+		if (dev->management_fib_count >= AAC_NUM_MGT_FIB) {
+			printk(KERN_INFO "No management Fibs Available:%d\n",
+						dev->management_fib_count);
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+			return -EBUSY;
+		}
+		dev->management_fib_count++;
+		spin_unlock_irqrestore(&dev->manage_lock, mflags);
 		spin_lock_irqsave(&fibptr->event_lock, flags);
-	aac_adapter_deliver(fibptr);
+	}
+
+	if (aac_adapter_deliver(fibptr) != 0) {
+		printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
+		if (wait) {
+			spin_unlock_irqrestore(&fibptr->event_lock, flags);
+			spin_lock_irqsave(&dev->manage_lock, mflags);
+			dev->management_fib_count--;
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+		}
+		return -EBUSY;
+	}
+
 
 	/*
 	 *	If the caller wanted us to wait for response wait now.
@@ -516,14 +547,15 @@ int aac_fib_send(u16 command, struct fib
 				udelay(5);
 			}
 		} else if (down_interruptible(&fibptr->event_wait)) {
-			fibptr->done = 2;
-			up(&fibptr->event_wait);
+			/* Do nothing ... satisfy
+			 * down_interruptible must_check */
 		}
+
 		spin_lock_irqsave(&fibptr->event_lock, flags);
-		if ((fibptr->done == 0) || (fibptr->done == 2)) {
+		if (fibptr->done == 0) {
 			fibptr->done = 2; /* Tell interrupt we aborted */
 			spin_unlock_irqrestore(&fibptr->event_lock, flags);
-			return -EINTR;
+			return -ERESTARTSYS;
 		}
 		spin_unlock_irqrestore(&fibptr->event_lock, flags);
 		BUG_ON(fibptr->done == 0);
@@ -689,6 +721,7 @@ int aac_fib_adapter_complete(struct fib
 
 int aac_fib_complete(struct fib *fibptr)
 {
+	unsigned long flags;
 	struct hw_fib * hw_fib = fibptr->hw_fib_va;
 
 	/*
@@ -709,6 +742,13 @@ int aac_fib_complete(struct fib *fibptr)
 	 *	command is complete that we had sent to the adapter and this
 	 *	cdb could be reused.
 	 */
+	spin_lock_irqsave(&fibptr->event_lock, flags);
+	if (fibptr->done == 2) {
+		spin_unlock_irqrestore(&fibptr->event_lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&fibptr->event_lock, flags);
+
 	if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
 		(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
 	{
@@ -1355,7 +1395,10 @@ int aac_reset_adapter(struct aac_dev * a
 
 			if (status >= 0)
 				aac_fib_complete(fibctx);
-			aac_fib_free(fibctx);
+			/* FIB should be freed only after getting
+			 * the response from the F/W */
+			if (status != -ERESTARTSYS)
+				aac_fib_free(fibctx);
 		}
 	}
 
@@ -1759,6 +1802,7 @@ int aac_command_thread(void *data)
 				struct fib *fibptr;
 
 				if ((fibptr = aac_fib_alloc(dev))) {
+					int status;
 					__le32 *info;
 
 					aac_fib_init(fibptr);
@@ -1769,15 +1813,21 @@ int aac_command_thread(void *data)
 
 					*info = cpu_to_le32(now.tv_sec);
 
-					(void)aac_fib_send(SendHostTime,
+					status = aac_fib_send(SendHostTime,
 						fibptr,
 						sizeof(*info),
 						FsaNormal,
 						1, 1,
 						NULL,
 						NULL);
-					aac_fib_complete(fibptr);
-					aac_fib_free(fibptr);
+					/* Do not set XferState to zero unless
+					 * receives a response from F/W */
+					if (status >= 0)
+						aac_fib_complete(fibptr);
+					/* FIB should be freed only after
+					 * getting the response from the F/W */
+					if (status != -ERESTARTSYS)
+						aac_fib_free(fibptr);
 				}
 				difference = (long)(unsigned)update_interval*HZ;
 			} else {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/dpcsup.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/dpcsup.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/dpcsup.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/dpcsup.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct
 	struct hw_fib * hwfib;
 	struct fib * fib;
 	int consumed = 0;
-	unsigned long flags;
+	unsigned long flags, mflags;
 
-	spin_lock_irqsave(q->lock, flags);	
+	spin_lock_irqsave(q->lock, flags);
 	/*
 	 *	Keep pulling response QEs off the response queue and waking
 	 *	up the waiters until there are no more QEs. We then return
@@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct
 		} else {
 			unsigned long flagv;
 			spin_lock_irqsave(&fib->event_lock, flagv);
-			if (!fib->done)
+			if (!fib->done) {
 				fib->done = 1;
-			up(&fib->event_wait);
+				up(&fib->event_wait);
+			}
 			spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+			spin_lock_irqsave(&dev->manage_lock, mflags);
+			dev->management_fib_count--;
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+
 			FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
 			if (fib->done == 2) {
+				spin_lock_irqsave(&fib->event_lock, flagv);
+				fib->done = 0;
+				spin_unlock_irqrestore(&fib->event_lock, flagv);
 				aac_fib_complete(fib);
 				aac_fib_free(fib);
 			}
@@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct a
 
 unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
 {
+	unsigned long mflags;
 	dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
 	if ((index & 0x00000002L)) {
 		struct hw_fib * hw_fib;
@@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_
 			unsigned long flagv;
 	  		dprintk((KERN_INFO "event_wait up\n"));
 			spin_lock_irqsave(&fib->event_lock, flagv);
-			if (!fib->done)
+			if (!fib->done) {
 				fib->done = 1;
-			up(&fib->event_wait);
+				up(&fib->event_wait);
+			}
 			spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+			spin_lock_irqsave(&dev->manage_lock, mflags);
+			dev->management_fib_count--;
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+
 			FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+			if (fib->done == 2) {
+				spin_lock_irqsave(&fib->event_lock, flagv);
+				fib->done = 0;
+				spin_unlock_irqrestore(&fib->event_lock, flagv);
+				aac_fib_complete(fib);
+				aac_fib_free(fib);
+			}
+
 		}
 		return 0;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/linit.c linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/linit.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aacraid/linit.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aacraid/linit.c	2010-02-24 13:52:17.000000000 -0500
@@ -472,8 +472,12 @@ static int aac_slave_configure(struct sc
  *	total capacity and the queue depth supported by the target device.
  */
 
-static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
+static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
+				  int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
 		struct scsi_device * dev;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/advansys.c linux-libre-2.6.33-gnu1/drivers/scsi/advansys.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/advansys.c	2013-05-03 14:05:00.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/scsi/advansys.c	2013-05-03 12:12:36.000000000 -0400
@@ -7969,7 +7969,7 @@ static int advansys_reset(struct scsi_cm
 		ASC_DBG(1, "before AscInitAsc1000Driver()\n");
 		status = AscInitAsc1000Driver(asc_dvc);
 
-		/* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
+		/* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
 		if (asc_dvc->err_code) {
 			scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
 				    "0x%x\n", asc_dvc->err_code);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx_core.c linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_core.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -2487,7 +2487,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd
 		/*
 		 * Although the driver does not care about the
 		 * 'Selection in Progress' status bit, the busy
-		 * LED does.  SELINGO is only cleared by a sucessfull
+		 * LED does.  SELINGO is only cleared by a successfull
 		 * selection, so we must manually clear it to insure
 		 * the LED turns off just incase no future successful
 		 * selections occur (e.g. no devices on the bus).
@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 				tinfo->curr.transport_version = 2;
 				tinfo->goal.transport_version = 2;
 				tinfo->goal.ppr_options = 0;
-				/*
-				 * Remove any SCBs in the waiting for selection
-				 * queue that may also be for this target so
-				 * that command ordering is preserved.
-				 */
-				ahd_freeze_devq(ahd, scb);
-				ahd_qinfifo_requeue_tail(ahd, scb);
+				if (scb != NULL) {
+					/*
+					 * Remove any SCBs in the waiting
+					 * for selection queue that may
+					 * also be for this target so that
+					 * command ordering is preserved.
+					 */
+					ahd_freeze_devq(ahd, scb);
+					ahd_qinfifo_requeue_tail(ahd, scb);
+				}
 				printerror = 0;
 			}
 		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 				      MSG_EXT_WDTR_BUS_8_BIT,
 				      AHD_TRANS_CUR|AHD_TRANS_GOAL,
 				      /*paused*/TRUE);
-			/*
-			 * Remove any SCBs in the waiting for selection
-			 * queue that may also be for this target so that
-			 * command ordering is preserved.
-			 */
-			ahd_freeze_devq(ahd, scb);
-			ahd_qinfifo_requeue_tail(ahd, scb);
+			if (scb != NULL) {
+				/*
+				 * Remove any SCBs in the waiting for
+				 * selection queue that may also be for
+				 * this target so that command ordering
+				 * is preserved.
+				 */
+				ahd_freeze_devq(ahd, scb);
+				ahd_qinfifo_requeue_tail(ahd, scb);
+			}
 			printerror = 0;
 		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
 			&& ppr_busfree == 0) {
@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 					/*ppr_options*/0,
 					AHD_TRANS_CUR|AHD_TRANS_GOAL,
 					/*paused*/TRUE);
-			/*
-			 * Remove any SCBs in the waiting for selection
-			 * queue that may also be for this target so that
-			 * command ordering is preserved.
-			 */
-			ahd_freeze_devq(ahd, scb);
-			ahd_qinfifo_requeue_tail(ahd, scb);
+			if (scb != NULL) {
+				/*
+				 * Remove any SCBs in the waiting for
+				 * selection queue that may also be for
+				 * this target so that command ordering
+				 * is preserved.
+				 */
+				ahd_freeze_devq(ahd, scb);
+				ahd_qinfifo_requeue_tail(ahd, scb);
+			}
 			printerror = 0;
 		} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
 			&& ahd_sent_msg(ahd, AHDMSG_1B,
@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 	 * the message phases.  We check it last in case we
 	 * had to send some other message that caused a busfree.
 	 */
-	if (printerror != 0
+	if (scb != NULL && printerror != 0
 	 && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
 	 && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx_osm.c	2010-02-24 13:52:17.000000000 -0500
@@ -2335,7 +2335,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cm
 			/*
 			 * The sequencer will never re-reference the
 			 * in-core SCB.  To make sure we are notified
-			 * during reslection, set the MK_MESSAGE flag in
+			 * during reselection, set the MK_MESSAGE flag in
 			 * the card's copy of the SCB.
 			 */
 			ahd_outb(ahd, SCB_CONTROL,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx.seq linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx.seq
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic79xx.seq	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic79xx.seq	2010-02-24 13:52:17.000000000 -0500
@@ -217,7 +217,7 @@ BEGIN_CRITICAL;
 scbdma_tohost_done:
 	test	CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
 	/*
-	 * An SCB has been succesfully uploaded to the host.
+	 * An SCB has been successfully uploaded to the host.
 	 * If the SCB was uploaded for some reason other than
 	 * bad SCSI status (currently only for underruns), we
 	 * queue the SCB for normal completion.  Otherwise, we
@@ -1281,7 +1281,7 @@ END_CRITICAL;
  * Is it a disconnect message?  Set a flag in the SCB to remind us
  * and await the bus going free.  If this is an untagged transaction
  * store the SCB id for it in our untagged target table for lookup on
- * a reselction.
+ * a reselection.
  */
 mesgin_disconnect:
 	/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx_core.c linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_core.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx_core.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_core.c	2010-02-24 13:52:17.000000000 -0500
@@ -1733,7 +1733,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc
 		/*
 		 * Although the driver does not care about the
 		 * 'Selection in Progress' status bit, the busy
-		 * LED does.  SELINGO is only cleared by a sucessfull
+		 * LED does.  SELINGO is only cleared by a successfull
 		 * selection, so we must manually clear it to insure
 		 * the LED turns off just incase no future successful
 		 * selections occur (e.g. no devices on the bus).
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx_osm.c	2010-02-24 13:52:17.000000000 -0500
@@ -2290,7 +2290,7 @@ ahc_linux_queue_recovery_cmd(struct scsi
 		 * In the non-paging case, the sequencer will
 		 * never re-reference the in-core SCB.
 		 * To make sure we are notified during
-		 * reslection, set the MK_MESSAGE flag in
+		 * reselection, set the MK_MESSAGE flag in
 		 * the card's copy of the SCB.
 		 */
 		if ((ahc->flags & AHC_PAGESCBS) == 0) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx.seq linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx.seq
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic7xxx/aic7xxx.seq	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic7xxx/aic7xxx.seq	2010-02-24 13:52:17.000000000 -0500
@@ -1693,7 +1693,7 @@ if ((ahc->flags & AHC_INITIATORROLE) !=
  * Is it a disconnect message?  Set a flag in the SCB to remind us
  * and await the bus going free.  If this is an untagged transaction
  * store the SCB id for it in our untagged target table for lookup on
- * a reselction.
+ * a reselection.
  */
 mesgin_disconnect:
 	/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/aic94xx/aic94xx_reg_def.h linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_reg_def.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/aic94xx/aic94xx_reg_def.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/aic94xx/aic94xx_reg_def.h	2010-02-24 13:52:17.000000000 -0500
@@ -1,5 +1,5 @@
 /*
- * Aic94xx SAS/SATA driver hardware registers defintions.
+ * Aic94xx SAS/SATA driver hardware registers definitions.
  *
  * Copyright (C) 2004 Adaptec, Inc.  All rights reserved.
  * Copyright (C) 2004 David Chaw <david_chaw@adaptec.com>
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c linux-libre-2.6.33-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/arcmsr/arcmsr_hba.c	2010-02-24 13:52:17.000000000 -0500
@@ -98,8 +98,11 @@ static void arcmsr_flush_hbb_cache(struc
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
-								int queue_depth)
+					  int queue_depth, int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
 		queue_depth = ARCMSR_MAX_CMD_PERLUN;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/arm/fas216.c linux-libre-2.6.33-gnu1/drivers/scsi/arm/fas216.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/arm/fas216.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/arm/fas216.c	2010-02-24 13:52:17.000000000 -0500
@@ -2516,7 +2516,7 @@ int fas216_eh_device_reset(struct scsi_c
 		if (info->scsi.phase == PHASE_IDLE)
 			fas216_kick(info);
 
-		mod_timer(&info->eh_timer, 30 * HZ);
+		mod_timer(&info->eh_timer, jiffies + 30 * HZ);
 		spin_unlock_irqrestore(&info->host_lock, flags);
 
 		/*
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_cmds.c linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_cmds.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.c	2010-02-24 13:52:17.000000000 -0500
@@ -19,6 +19,16 @@
 #include "be_mgmt.h"
 #include "be_main.h"
 
+static void be_mcc_notify(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+	u32 val = 0;
+
+	val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+	val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+	iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
+}
+
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
 	if (compl->flags != 0) {
@@ -54,13 +64,56 @@ static int be_mcc_compl_process(struct b
 	return 0;
 }
 
+
 static inline bool is_link_state_evt(u32 trailer)
 {
 	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
-		ASYNC_TRAILER_EVENT_CODE_MASK) == ASYNC_EVENT_CODE_LINK_STATE);
+		  ASYNC_TRAILER_EVENT_CODE_MASK) ==
+		  ASYNC_EVENT_CODE_LINK_STATE);
 }
 
-void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
+static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mcc_cq = &phba->ctrl.mcc_obj.cq;
+	struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
+
+	if (be_mcc_compl_is_new(compl)) {
+		queue_tail_inc(mcc_cq);
+		return compl;
+	}
+	return NULL;
+}
+
+static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+{
+	iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
+}
+
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+		struct be_async_event_link_state *evt)
+{
+	switch (evt->port_link_status) {
+	case ASYNC_EVENT_LINK_DOWN:
+		SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
+						evt->physical_port);
+		phba->state |= BE_ADAPTER_LINK_DOWN;
+		break;
+	case ASYNC_EVENT_LINK_UP:
+		phba->state = BE_ADAPTER_UP;
+		SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
+						evt->physical_port);
+		iscsi_host_for_each_session(phba->shost,
+					    be2iscsi_fail_session);
+		break;
+	default:
+		SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
+				    "Physical Port %d \n",
+				     evt->port_link_status,
+				     evt->physical_port);
+	}
+}
+
+static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm,
 		       u16 num_popped)
 {
 	u32 val = 0;
@@ -68,7 +121,70 @@ void beiscsi_cq_notify(struct be_ctrl_in
 	if (arm)
 		val |= 1 << DB_CQ_REARM_SHIFT;
 	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
-	iowrite32(val, ctrl->db + DB_CQ_OFFSET);
+	iowrite32(val, phba->db_va + DB_CQ_OFFSET);
+}
+
+
+int beiscsi_process_mcc(struct beiscsi_hba *phba)
+{
+	struct be_mcc_compl *compl;
+	int num = 0, status = 0;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	spin_lock_bh(&phba->ctrl.mcc_cq_lock);
+	while ((compl = be_mcc_compl_get(phba))) {
+		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
+			/* Interpret flags as an async trailer */
+			if (is_link_state_evt(compl->flags))
+				/* Interpret compl as a async link evt */
+				beiscsi_async_link_state_process(phba,
+				   (struct be_async_event_link_state *) compl);
+			else
+				SE_DEBUG(DBG_LVL_1,
+					 " Unsupported Async Event, flags"
+					 " = 0x%08x \n", compl->flags);
+
+		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+				status = be_mcc_compl_process(ctrl, compl);
+				atomic_dec(&phba->ctrl.mcc_obj.q.used);
+		}
+		be_mcc_compl_use(compl);
+		num++;
+	}
+
+	if (num)
+		beiscsi_cq_notify(phba, phba->ctrl.mcc_obj.cq.id, true, num);
+
+	spin_unlock_bh(&phba->ctrl.mcc_cq_lock);
+	return status;
+}
+
+/* Wait till no more pending mcc requests are present */
+static int be_mcc_wait_compl(struct beiscsi_hba *phba)
+{
+#define mcc_timeout		120000 /* 5s timeout */
+	int i, status;
+	for (i = 0; i < mcc_timeout; i++) {
+		status = beiscsi_process_mcc(phba);
+		if (status)
+			return status;
+
+		if (atomic_read(&phba->ctrl.mcc_obj.q.used) == 0)
+			break;
+		udelay(100);
+	}
+	if (i == mcc_timeout) {
+		dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
+		return -1;
+	}
+	return 0;
+}
+
+/* Notify MCC requests and wait for completion */
+int be_mcc_notify_wait(struct beiscsi_hba *phba)
+{
+	be_mcc_notify(phba);
+	return be_mcc_wait_compl(phba);
 }
 
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
@@ -142,6 +258,52 @@ int be_mbox_notify(struct be_ctrl_info *
 	return 0;
 }
 
+/*
+ * Insert the mailbox address into the doorbell in two steps
+ * Polls on the mbox doorbell till a command completion (or a timeout) occurs
+ */
+static int be_mbox_notify_wait(struct beiscsi_hba *phba)
+{
+	int status;
+	u32 val = 0;
+	void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
+	struct be_dma_mem *mbox_mem = &phba->ctrl.mbox_mem;
+	struct be_mcc_mailbox *mbox = mbox_mem->va;
+	struct be_mcc_compl *compl = &mbox->compl;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	val |= MPU_MAILBOX_DB_HI_MASK;
+	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
+	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
+	iowrite32(val, db);
+
+	/* wait for ready to be set */
+	status = be_mbox_db_ready_wait(ctrl);
+	if (status != 0)
+		return status;
+
+	val = 0;
+	/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
+	val |= (u32)(mbox_mem->dma >> 4) << 2;
+	iowrite32(val, db);
+
+	status = be_mbox_db_ready_wait(ctrl);
+	if (status != 0)
+		return status;
+
+	/* A cq entry has been made now */
+	if (be_mcc_compl_is_new(compl)) {
+		status = be_mcc_compl_process(ctrl, &mbox->compl);
+		be_mcc_compl_use(compl);
+		if (status)
+			return status;
+	} else {
+		dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
+		return -1;
+	}
+	return 0;
+}
+
 void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
 				bool embedded, u8 sge_cnt)
 {
@@ -203,6 +365,20 @@ struct be_mcc_wrb *wrb_from_mbox(struct
 	return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
 }
 
+struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+	struct be_mcc_wrb *wrb;
+
+	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+	wrb = queue_head_node(mccq);
+	queue_head_inc(mccq);
+	atomic_inc(&mccq->used);
+	memset(wrb, 0, sizeof(*wrb));
+	return wrb;
+}
+
+
 int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
 			  struct be_queue_info *eq, int eq_delay)
 {
@@ -212,6 +388,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl
 	struct be_dma_mem *q_mem = &eq->dma_mem;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -249,6 +426,7 @@ int be_cmd_fw_initialize(struct be_ctrl_
 	int status;
 	u8 *endian_check;
 
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -282,6 +460,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl
 	void *ctxt = &req->context;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -289,7 +468,6 @@ int beiscsi_cmd_cq_create(struct be_ctrl
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			OPCODE_COMMON_CQ_CREATE, sizeof(*req));
-
 	if (!q_mem->va)
 		SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
 
@@ -329,6 +507,53 @@ static u32 be_encoded_q_len(int q_len)
 		len_encoded = 0;
 	return len_encoded;
 }
+
+int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
+			struct be_queue_info *mccq,
+			struct be_queue_info *cq)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_mcc_create *req;
+	struct be_dma_mem *q_mem = &mccq->dma_mem;
+	struct be_ctrl_info *ctrl;
+	void *ctxt;
+	int status;
+
+	spin_lock(&phba->ctrl.mbox_lock);
+	ctrl = &phba->ctrl;
+	wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	req = embedded_payload(wrb);
+	ctxt = &req->context;
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
+
+	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+
+	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
+		      PCI_FUNC(phba->pcidev->devfn));
+	AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
+	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
+		be_encoded_q_len(mccq->len));
+	AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
+
+	be_dws_cpu_to_le(ctxt, sizeof(req->context));
+
+	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+
+	status = be_mbox_notify_wait(phba);
+	if (!status) {
+		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
+		mccq->id = le16_to_cpu(resp->id);
+		mccq->created = true;
+	}
+	spin_unlock(&phba->ctrl.mbox_lock);
+
+	return status;
+}
+
 int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 			  int queue_type)
 {
@@ -337,6 +562,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl
 	u8 subsys = 0, opcode = 0;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -350,6 +576,10 @@ int beiscsi_cmd_q_destroy(struct be_ctrl
 		subsys = CMD_SUBSYSTEM_COMMON;
 		opcode = OPCODE_COMMON_CQ_DESTROY;
 		break;
+	case QTYPE_MCCQ:
+		subsys = CMD_SUBSYSTEM_COMMON;
+		opcode = OPCODE_COMMON_MCC_DESTROY;
+		break;
 	case QTYPE_WRBQ:
 		subsys = CMD_SUBSYSTEM_ISCSI;
 		opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
@@ -377,30 +607,6 @@ int beiscsi_cmd_q_destroy(struct be_ctrl
 	return status;
 }
 
-int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr)
-{
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
-	int status;
-
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
-			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
-			   sizeof(*req));
-
-	status = be_mbox_notify(ctrl);
-	if (!status) {
-		struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
-
-		memcpy(mac_addr, resp->mac_address, ETH_ALEN);
-	}
-
-	spin_unlock(&ctrl->mbox_lock);
-	return status;
-}
-
 int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
 				    struct be_queue_info *cq,
 				    struct be_queue_info *dq, int length,
@@ -412,6 +618,7 @@ int be_cmd_create_default_pdu_queue(stru
 	void *ctxt = &req->context;
 	int status;
 
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n");
 	spin_lock(&ctrl->mbox_lock);
 	memset(wrb, 0, sizeof(*wrb));
 
@@ -468,8 +675,10 @@ int be_cmd_wrbq_create(struct be_ctrl_in
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
 	status = be_mbox_notify(ctrl);
-	if (!status)
+	if (!status) {
 		wrbq->id = le16_to_cpu(resp->cid);
+		wrbq->created = true;
+	}
 	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_cmds.h linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_cmds.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_cmds.h	2010-02-24 13:52:17.000000000 -0500
@@ -47,6 +47,8 @@ struct be_mcc_wrb {
 
 #define CQE_FLAGS_VALID_MASK (1 << 31)
 #define CQE_FLAGS_ASYNC_MASK (1 << 30)
+#define CQE_FLAGS_COMPLETED_MASK 	(1 << 28)
+#define CQE_FLAGS_CONSUMED_MASK 	(1 << 27)
 
 /* Completion Status */
 #define MCC_STATUS_SUCCESS 0x0
@@ -173,7 +175,7 @@ struct be_cmd_req_hdr {
 	u8 domain;		/* dword 0 */
 	u32 timeout;		/* dword 1 */
 	u32 request_length;	/* dword 2 */
-	u32 rsvd;		/* dword 3 */
+	u32 rsvd0;		/* dword 3 */
 };
 
 struct be_cmd_resp_hdr {
@@ -382,7 +384,6 @@ struct be_cmd_req_modify_eq_delay {
 
 #define ETH_ALEN	6
 
-
 struct be_cmd_req_get_mac_addr {
 	struct be_cmd_req_hdr hdr;
 	u32 nic_port_count;
@@ -417,14 +418,21 @@ int beiscsi_cmd_cq_create(struct be_ctrl
 
 int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 			  int type);
+int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
+			struct be_queue_info *mccq,
+			struct be_queue_info *cq);
+
 int be_poll_mcc(struct be_ctrl_info *ctrl);
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl);
-int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr);
+unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+				      struct beiscsi_hba *phba);
+int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr);
 
 /*ISCSI Functuions */
 int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
 
 struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
+struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba);
+int be_mcc_notify_wait(struct beiscsi_hba *phba);
 
 int be_mbox_notify(struct be_ctrl_info *ctrl);
 
@@ -531,6 +539,23 @@ struct amap_sol_cqe {
 	u8 valid;		/* dword 3 */
 } __packed;
 
+#define SOL_ICD_INDEX_MASK	0x0003FFC0
+struct amap_sol_cqe_ring {
+	u8 hw_sts[8];		/* dword 0 */
+	u8 i_sts[8];		/* dword 0 */
+	u8 i_resp[8];		/* dword 0 */
+	u8 i_flags[7];		/* dword 0 */
+	u8 s;			/* dword 0 */
+	u8 i_exp_cmd_sn[32];	/* dword 1 */
+	u8 code[6];		/* dword 2 */
+	u8 icd_index[12];	/* dword 2 */
+	u8 rsvd[6];		/* dword 2 */
+	u8 i_cmd_wnd[8];	/* dword 2 */
+	u8 i_res_cnt[31];	/* dword 3 */
+	u8 valid;		/* dword 3 */
+} __packed;
+
+
 
 /**
  * Post WRB Queue Doorbell Register used by the host Storage
@@ -664,8 +689,8 @@ struct be_fw_cfg {
 #define	OPCODE_COMMON_TCP_UPLOAD	56
 #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
 /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
-#define CMD_ISCSI_CONNECTION_INVALIDATE 1
-#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2
+#define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001
+#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002
 #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
 
 #define INI_WR_CMD			1	/* Initiator write command */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be.h linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be.h	2010-02-24 13:52:17.000000000 -0500
@@ -20,8 +20,10 @@
 
 #include <linux/pci.h>
 #include <linux/if_vlan.h>
-
-#define FW_VER_LEN 32
+#include <linux/blk-iopoll.h>
+#define FW_VER_LEN	32
+#define MCC_Q_LEN	128
+#define MCC_CQ_LEN	256
 
 struct be_dma_mem {
 	void *va;
@@ -74,18 +76,14 @@ static inline void queue_tail_inc(struct
 
 struct be_eq_obj {
 	struct be_queue_info q;
-	char desc[32];
-
-	/* Adaptive interrupt coalescing (AIC) info */
-	bool enable_aic;
-	u16 min_eqd;		/* in usecs */
-	u16 max_eqd;		/* in usecs */
-	u16 cur_eqd;		/* in usecs */
+	struct beiscsi_hba *phba;
+	struct be_queue_info *cq;
+	struct blk_iopoll	iopoll;
 };
 
 struct be_mcc_obj {
-	struct be_queue_info *q;
-	struct be_queue_info *cq;
+	struct be_queue_info q;
+	struct be_queue_info cq;
 };
 
 struct be_ctrl_info {
@@ -176,8 +174,4 @@ static inline void swap_dws(void *wrb, i
 	} while (len);
 #endif /* __BIG_ENDIAN */
 }
-
-extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
-			      u16 num_popped);
-
 #endif /* BEISCSI_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_iscsi.c linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_iscsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_iscsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -67,11 +67,11 @@ struct iscsi_cls_session *beiscsi_sessio
 		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
 	}
 
-	 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
-					   shost, cmds_max,
-					   sizeof(*beiscsi_sess),
-					   sizeof(*io_task),
-					   initial_cmdsn, ISCSI_MAX_TARGET);
+	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
+					  shost, cmds_max,
+					  sizeof(*beiscsi_sess),
+					  sizeof(*io_task),
+					  initial_cmdsn, ISCSI_MAX_TARGET);
 	if (!cls_session)
 		return NULL;
 	sess = cls_session->dd_data;
@@ -297,7 +297,7 @@ int beiscsi_get_host_param(struct Scsi_H
 
 	switch (param) {
 	case ISCSI_HOST_PARAM_HWADDRESS:
-		be_cmd_get_mac_addr(&phba->ctrl, phba->mac_address);
+		be_cmd_get_mac_addr(phba, phba->mac_address);
 		len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
 		break;
 	default:
@@ -377,16 +377,12 @@ int beiscsi_conn_start(struct iscsi_cls_
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct beiscsi_endpoint *beiscsi_ep;
 	struct beiscsi_offload_params params;
-	struct iscsi_session *session = conn->session;
-	struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
-	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 
 	memset(&params, 0, sizeof(struct beiscsi_offload_params));
 	beiscsi_ep = beiscsi_conn->ep;
 	if (!beiscsi_ep)
 		SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
 
-	free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle);
 	beiscsi_conn->login_in_progress = 0;
 	beiscsi_set_params_for_offld(beiscsi_conn, &params);
 	beiscsi_offload_connection(beiscsi_conn, &params);
@@ -498,6 +494,13 @@ beiscsi_ep_connect(struct Scsi_Host *sho
 		SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
 		return ERR_PTR(ret);
 	}
+
+	if (phba->state) {
+		ret = -EBUSY;
+		SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n");
+		return ERR_PTR(ret);
+	}
+
 	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
 	if (!ep) {
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_main.c linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,7 +39,8 @@
 
 static unsigned int be_iopoll_budget = 10;
 static unsigned int be_max_phys_size = 64;
-static unsigned int enable_msix;
+static unsigned int enable_msix = 1;
+static unsigned int ring_mode;
 
 MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
 MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -58,6 +59,17 @@ static int beiscsi_slave_configure(struc
 	return 0;
 }
 
+/*------------------- PCI Driver operations and data ----------------- */
+static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
+	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
+	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
+
 static struct scsi_host_template beiscsi_sht = {
 	.module = THIS_MODULE,
 	.name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
@@ -76,16 +88,8 @@ static struct scsi_host_template beiscsi
 	.cmd_per_lun = BEISCSI_CMD_PER_LUN,
 	.use_clustering = ENABLE_CLUSTERING,
 };
-static struct scsi_transport_template *beiscsi_scsi_transport;
 
-/*------------------- PCI Driver operations and data ----------------- */
-static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
-	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
+static struct scsi_transport_template *beiscsi_scsi_transport;
 
 static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
 {
@@ -104,7 +108,6 @@ static struct beiscsi_hba *beiscsi_hba_a
 	shost->max_cmd_len = BEISCSI_MAX_CMD_LEN;
 	shost->max_lun = BEISCSI_NUM_MAX_LUN;
 	shost->transportt = beiscsi_scsi_transport;
-
 	phba = iscsi_host_priv(shost);
 	memset(phba, 0, sizeof(*phba));
 	phba->shost = shost;
@@ -181,6 +184,7 @@ static int beiscsi_enable_pci(struct pci
 		return ret;
 	}
 
+	pci_set_master(pcidev);
 	if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
 		ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
 		if (ret) {
@@ -203,7 +207,6 @@ static int be_ctrl_init(struct beiscsi_h
 	status = beiscsi_map_pci_bars(phba, pdev);
 	if (status)
 		return status;
-
 	mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
 	mbox_mem_alloc->va = pci_alloc_consistent(pdev,
 						  mbox_mem_alloc->size,
@@ -219,6 +222,9 @@ static int be_ctrl_init(struct beiscsi_h
 	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
 	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
 	spin_lock_init(&ctrl->mbox_lock);
+	spin_lock_init(&phba->ctrl.mcc_lock);
+	spin_lock_init(&phba->ctrl.mcc_cq_lock);
+
 	return status;
 }
 
@@ -268,6 +274,113 @@ static void hwi_ring_eq_db(struct beiscs
 }
 
 /**
+ * be_isr_mcc - The isr routine of the driver.
+ * @irq: Not used
+ * @dev_id: Pointer to host adapter structure
+ */
+static irqreturn_t be_isr_mcc(int irq, void *dev_id)
+{
+	struct beiscsi_hba *phba;
+	struct be_eq_entry *eqe = NULL;
+	struct be_queue_info *eq;
+	struct be_queue_info *mcc;
+	unsigned int num_eq_processed;
+	struct be_eq_obj *pbe_eq;
+	unsigned long flags;
+
+	pbe_eq = dev_id;
+	eq = &pbe_eq->q;
+	phba =  pbe_eq->phba;
+	mcc = &phba->ctrl.mcc_obj.cq;
+	eqe = queue_tail_node(eq);
+	if (!eqe)
+		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
+
+	num_eq_processed = 0;
+
+	while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+				& EQE_VALID_MASK) {
+		if (((eqe->dw[offsetof(struct amap_eq_entry,
+		     resource_id) / 32] &
+		     EQE_RESID_MASK) >> 16) == mcc->id) {
+			spin_lock_irqsave(&phba->isr_lock, flags);
+			phba->todo_mcc_cq = 1;
+			spin_unlock_irqrestore(&phba->isr_lock, flags);
+		}
+		AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+		queue_tail_inc(eq);
+		eqe = queue_tail_node(eq);
+		num_eq_processed++;
+	}
+	if (phba->todo_mcc_cq)
+		queue_work(phba->wq, &phba->work_cqs);
+	if (num_eq_processed)
+		hwi_ring_eq_db(phba, eq->id, 1,	num_eq_processed, 1, 1);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * be_isr_msix - The isr routine of the driver.
+ * @irq: Not used
+ * @dev_id: Pointer to host adapter structure
+ */
+static irqreturn_t be_isr_msix(int irq, void *dev_id)
+{
+	struct beiscsi_hba *phba;
+	struct be_eq_entry *eqe = NULL;
+	struct be_queue_info *eq;
+	struct be_queue_info *cq;
+	unsigned int num_eq_processed;
+	struct be_eq_obj *pbe_eq;
+	unsigned long flags;
+
+	pbe_eq = dev_id;
+	eq = &pbe_eq->q;
+	cq = pbe_eq->cq;
+	eqe = queue_tail_node(eq);
+	if (!eqe)
+		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
+
+	phba = pbe_eq->phba;
+	num_eq_processed = 0;
+	if (blk_iopoll_enabled) {
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+					& EQE_VALID_MASK) {
+			if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
+				blk_iopoll_sched(&pbe_eq->iopoll);
+
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+			num_eq_processed++;
+		}
+		if (num_eq_processed)
+			hwi_ring_eq_db(phba, eq->id, 1,	num_eq_processed, 0, 1);
+
+		return IRQ_HANDLED;
+	} else {
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+						& EQE_VALID_MASK) {
+			spin_lock_irqsave(&phba->isr_lock, flags);
+			phba->todo_cq = 1;
+			spin_unlock_irqrestore(&phba->isr_lock, flags);
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+			num_eq_processed++;
+		}
+		if (phba->todo_cq)
+			queue_work(phba->wq, &phba->work_cqs);
+
+		if (num_eq_processed)
+			hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 1, 1);
+
+		return IRQ_HANDLED;
+	}
+}
+
+/**
  * be_isr - The isr routine of the driver.
  * @irq: Not used
  * @dev_id: Pointer to host adapter structure
@@ -280,48 +393,70 @@ static irqreturn_t be_isr(int irq, void
 	struct be_eq_entry *eqe = NULL;
 	struct be_queue_info *eq;
 	struct be_queue_info *cq;
+	struct be_queue_info *mcc;
 	unsigned long flags, index;
-	unsigned int num_eq_processed;
+	unsigned int num_mcceq_processed, num_ioeq_processed;
 	struct be_ctrl_info *ctrl;
+	struct be_eq_obj *pbe_eq;
 	int isr;
 
 	phba = dev_id;
-	if (!enable_msix) {
-		ctrl = &phba->ctrl;;
-		isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
-			       (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
-		if (!isr)
-			return IRQ_NONE;
-	}
+	ctrl = &phba->ctrl;;
+	isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
+		       (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
+	if (!isr)
+		return IRQ_NONE;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	eq = &phwi_context->be_eq.q;
-	cq = &phwi_context->be_cq;
+	pbe_eq = &phwi_context->be_eq[0];
+
+	eq = &phwi_context->be_eq[0].q;
+	mcc = &phba->ctrl.mcc_obj.cq;
 	index = 0;
 	eqe = queue_tail_node(eq);
 	if (!eqe)
 		SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
 
-	num_eq_processed = 0;
+	num_ioeq_processed = 0;
+	num_mcceq_processed = 0;
 	if (blk_iopoll_enabled) {
 		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 					& EQE_VALID_MASK) {
-			if (!blk_iopoll_sched_prep(&phba->iopoll))
-				blk_iopoll_sched(&phba->iopoll);
-
+			if (((eqe->dw[offsetof(struct amap_eq_entry,
+			     resource_id) / 32] &
+			     EQE_RESID_MASK) >> 16) == mcc->id) {
+				spin_lock_irqsave(&phba->isr_lock, flags);
+				phba->todo_mcc_cq = 1;
+				spin_unlock_irqrestore(&phba->isr_lock, flags);
+				num_mcceq_processed++;
+			} else {
+				if (!blk_iopoll_sched_prep(&pbe_eq->iopoll))
+					blk_iopoll_sched(&pbe_eq->iopoll);
+				num_ioeq_processed++;
+			}
 			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 			queue_tail_inc(eq);
 			eqe = queue_tail_node(eq);
-			num_eq_processed++;
-			SE_DEBUG(DBG_LVL_8, "Valid EQE\n");
 		}
-		if (num_eq_processed) {
-			hwi_ring_eq_db(phba, eq->id, 0,	num_eq_processed, 0, 1);
+		if (num_ioeq_processed || num_mcceq_processed) {
+			if (phba->todo_mcc_cq)
+				queue_work(phba->wq, &phba->work_cqs);
+
+		if ((num_mcceq_processed) && (!num_ioeq_processed))
+				hwi_ring_eq_db(phba, eq->id, 0,
+					      (num_ioeq_processed +
+					       num_mcceq_processed) , 1, 1);
+			else
+				hwi_ring_eq_db(phba, eq->id, 0,
+					       (num_ioeq_processed +
+						num_mcceq_processed), 0, 1);
+
 			return IRQ_HANDLED;
 		} else
 			return IRQ_NONE;
 	} else {
+		cq = &phwi_context->be_cq[0];
 		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 						& EQE_VALID_MASK) {
 
@@ -339,13 +474,14 @@ static irqreturn_t be_isr(int irq, void
 			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 			queue_tail_inc(eq);
 			eqe = queue_tail_node(eq);
-			num_eq_processed++;
+			num_ioeq_processed++;
 		}
 		if (phba->todo_cq || phba->todo_mcc_cq)
 			queue_work(phba->wq, &phba->work_cqs);
 
-		if (num_eq_processed) {
-			hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 1, 1);
+		if (num_ioeq_processed) {
+			hwi_ring_eq_db(phba, eq->id, 0,
+				       num_ioeq_processed, 1, 1);
 			return IRQ_HANDLED;
 		} else
 			return IRQ_NONE;
@@ -355,13 +491,32 @@ static irqreturn_t be_isr(int irq, void
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
 	struct pci_dev *pcidev = phba->pcidev;
-	int ret;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	int ret, msix_vec, i = 0;
+	char desc[32];
 
-	ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
-			     "Failed to register irq\\n");
-		return ret;
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
+
+	if (phba->msix_enabled) {
+		for (i = 0; i < phba->num_cpus; i++) {
+			sprintf(desc, "beiscsi_msix_%04x", i);
+			msix_vec = phba->msix_entries[i].vector;
+			ret = request_irq(msix_vec, be_isr_msix, 0, desc,
+					  &phwi_context->be_eq[i]);
+		}
+		msix_vec = phba->msix_entries[i].vector;
+		ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc",
+				  &phwi_context->be_eq[i]);
+	} else {
+		ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
+				  "beiscsi", phba);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
+				     "Failed to register irq\\n");
+			return ret;
+		}
 	}
 	return 0;
 }
@@ -378,15 +533,6 @@ static void hwi_ring_cq_db(struct beiscs
 	iowrite32(val, phba->db_va + DB_CQ_OFFSET);
 }
 
-/*
- * async pdus include
- * a. unsolicited NOP-In (target initiated NOP-In)
- * b. Async Messages
- * c. Reject PDU
- * d. Login response
- * These headers arrive unprocessed by the EP firmware and iSCSI layer
- * process them
- */
 static unsigned int
 beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
 			  struct beiscsi_hba *phba,
@@ -397,6 +543,9 @@ beiscsi_process_async_pdu(struct beiscsi
 {
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
+	struct iscsi_task *task;
+	struct beiscsi_io_task *io_task;
+	struct iscsi_hdr *login_hdr;
 
 	switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] &
 						PDUBASE_OPCODE_MASK) {
@@ -412,6 +561,10 @@ beiscsi_process_async_pdu(struct beiscsi
 		SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
 		break;
 	case ISCSI_OP_LOGIN_RSP:
+		task = conn->login_task;
+		io_task = task->dd_data;
+		login_hdr = (struct iscsi_hdr *)ppdu;
+		login_hdr->itt = io_task->libiscsi_itt;
 		break;
 	default:
 		shost_printk(KERN_WARNING, phba->shost,
@@ -440,7 +593,8 @@ static struct sgl_handle *alloc_io_sgl_h
 						io_sgl_alloc_index];
 		phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL;
 		phba->io_sgl_hndl_avbl--;
-		if (phba->io_sgl_alloc_index == (phba->params.ios_per_ctrl - 1))
+		if (phba->io_sgl_alloc_index == (phba->params.
+						 ios_per_ctrl - 1))
 			phba->io_sgl_alloc_index = 0;
 		else
 			phba->io_sgl_alloc_index++;
@@ -490,9 +644,18 @@ struct wrb_handle *alloc_wrb_handle(stru
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	pwrb_context = &phwi_ctrlr->wrb_context[cid];
-	pwrb_handle = pwrb_context->pwrb_handle_base[index];
-	pwrb_handle->wrb_index = index;
-	pwrb_handle->nxt_wrb_index = index;
+	if (pwrb_context->wrb_handles_available) {
+		pwrb_handle = pwrb_context->pwrb_handle_base[
+					    pwrb_context->alloc_index];
+		pwrb_context->wrb_handles_available--;
+		pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index;
+		if (pwrb_context->alloc_index ==
+						(phba->params.wrbs_per_cxn - 1))
+			pwrb_context->alloc_index = 0;
+		else
+			pwrb_context->alloc_index++;
+	} else
+		pwrb_handle = NULL;
 	return pwrb_handle;
 }
 
@@ -508,11 +671,20 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
 		struct wrb_handle *pwrb_handle)
 {
+	if (!ring_mode)
+		pwrb_context->pwrb_handle_base[pwrb_context->free_index] =
+					       pwrb_handle;
+	pwrb_context->wrb_handles_available++;
+	if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
+		pwrb_context->free_index = 0;
+	else
+		pwrb_context->free_index++;
+
 	SE_DEBUG(DBG_LVL_8,
-		 "FREE WRB: pwrb_handle=%p free_index=%d=0x%x"
+		 "FREE WRB: pwrb_handle=%p free_index=0x%x"
 		 "wrb_handles_available=%d \n",
 		 pwrb_handle, pwrb_context->free_index,
-		 pwrb_context->free_index, pwrb_context->wrb_handles_available);
+		 pwrb_context->wrb_handles_available);
 }
 
 static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
@@ -540,6 +712,8 @@ void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
 
+	SE_DEBUG(DBG_LVL_8, "In  free_mgmt_sgl_handle,eh_sgl_free_index=%d \n",
+			     phba->eh_sgl_free_index);
 	if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
 		/*
 		 * this can happen if clean_task is called on a task that
@@ -572,10 +746,10 @@ be_complete_io(struct beiscsi_conn *beis
 	u32 resid = 0, exp_cmdsn, max_cmdsn;
 	u8 rsp, status, flags;
 
-	exp_cmdsn = be32_to_cpu(psol->
+	exp_cmdsn = (psol->
 			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
 			& SOL_EXP_CMD_SN_MASK);
-	max_cmdsn = be32_to_cpu((psol->
+	max_cmdsn = ((psol->
 			dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
 			& SOL_EXP_CMD_SN_MASK) +
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
@@ -610,9 +784,9 @@ be_complete_io(struct beiscsi_conn *beis
 	}
 
 	if (status == SAM_STAT_CHECK_CONDITION) {
+		unsigned short *slen = (unsigned short *)sts_bhs->sense_info;
 		sense = sts_bhs->sense_info + sizeof(unsigned short);
-		sense_len =
-		    cpu_to_be16((unsigned short)(sts_bhs->sense_info[0]));
+		sense_len =  cpu_to_be16(*slen);
 		memcpy(task->sc->sense_buffer, sense,
 		       min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
 	}
@@ -620,8 +794,8 @@ be_complete_io(struct beiscsi_conn *beis
 		if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
 							& SOL_RES_CNT_MASK)
 			 conn->rxdata_octets += (psol->
-			      dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
-							& SOL_RES_CNT_MASK);
+			     dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
+			     & SOL_RES_CNT_MASK);
 	}
 unmap:
 	scsi_dma_unmap(io_task->scsi_cmnd);
@@ -633,6 +807,7 @@ be_complete_logout(struct beiscsi_conn *
 		   struct iscsi_task *task, struct sol_cqe *psol)
 {
 	struct iscsi_logout_rsp *hdr;
+	struct beiscsi_io_task *io_task = task->dd_data;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 
 	hdr = (struct iscsi_logout_rsp *)task->hdr;
@@ -651,7 +826,7 @@ be_complete_logout(struct beiscsi_conn *
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 					/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
 	hdr->hlength = 0;
-
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -661,6 +836,7 @@ be_complete_tmf(struct beiscsi_conn *bei
 {
 	struct iscsi_tm_rsp *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
+	struct beiscsi_io_task *io_task = task->dd_data;
 
 	hdr = (struct iscsi_tm_rsp *)task->hdr;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -668,11 +844,12 @@ be_complete_tmf(struct beiscsi_conn *bei
 	hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
 					32] & SOL_RESP_MASK);
 	hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
-				     i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
+				    i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
 	hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
 			i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -681,18 +858,36 @@ hwi_complete_drvr_msgs(struct beiscsi_co
 		       struct beiscsi_hba *phba, struct sol_cqe *psol)
 {
 	struct hwi_wrb_context *pwrb_context;
-	struct wrb_handle *pwrb_handle;
+	struct wrb_handle *pwrb_handle = NULL;
+	struct sgl_handle *psgl_handle = NULL;
 	struct hwi_controller *phwi_ctrlr;
+	struct iscsi_task *task;
+	struct beiscsi_io_task *io_task;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-	pwrb_context = &phwi_ctrlr->wrb_context[((psol->
+	if (ring_mode) {
+		psgl_handle = phba->sgl_hndl_array[((psol->
+			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
+				32] & SOL_ICD_INDEX_MASK) >> 6)];
+		pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid];
+		task = psgl_handle->task;
+		pwrb_handle = NULL;
+	} else {
+		pwrb_context = &phwi_ctrlr->wrb_context[((psol->
 				dw[offsetof(struct amap_sol_cqe, cid) / 32] &
 				SOL_CID_MASK) >> 6)];
-	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
+		task = pwrb_handle->pio_handle;
+	}
+
+	io_task = task->dd_data;
+	spin_lock(&phba->mgmt_sgl_lock);
+	free_mgmt_sgl_handle(phba, io_task->psgl_handle);
+	spin_unlock(&phba->mgmt_sgl_lock);
 	spin_lock_bh(&session->lock);
 	free_wrb_handle(phba, pwrb_context, pwrb_handle);
 	spin_unlock_bh(&session->lock);
@@ -704,6 +899,7 @@ be_complete_nopin_resp(struct beiscsi_co
 {
 	struct iscsi_nopin *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
+	struct beiscsi_io_task *io_task = task->dd_data;
 
 	hdr = (struct iscsi_nopin *)task->hdr;
 	hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
@@ -715,6 +911,7 @@ be_complete_nopin_resp(struct beiscsi_co
 			((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
 			/ 32] & SOL_CMD_WND_MASK) >> 24) - 1);
 	hdr->opcode = ISCSI_OP_NOOP_IN;
+	hdr->itt = io_task->libiscsi_itt;
 	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
 }
 
@@ -726,25 +923,33 @@ static void hwi_complete_cmd(struct beis
 	struct iscsi_wrb *pwrb = NULL;
 	struct hwi_controller *phwi_ctrlr;
 	struct iscsi_task *task;
-	struct beiscsi_io_task *io_task;
+	struct sgl_handle *psgl_handle = NULL;
+	unsigned int type;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
 	struct iscsi_session *session = conn->session;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
-
-	pwrb_context = &phwi_ctrlr->
-		wrb_context[((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
-		& SOL_CID_MASK) >> 6)];
-	pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
+	if (ring_mode) {
+		psgl_handle = phba->sgl_hndl_array[((psol->
+			      dw[offsetof(struct amap_sol_cqe_ring, icd_index) /
+			      32] & SOL_ICD_INDEX_MASK) >> 6)];
+		task = psgl_handle->task;
+		type = psgl_handle->type;
+	} else {
+		pwrb_context = &phwi_ctrlr->
+				wrb_context[((psol->dw[offsetof
+				(struct amap_sol_cqe, cid) / 32]
+				& SOL_CID_MASK) >> 6)];
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
 				dw[offsetof(struct amap_sol_cqe, wrb_index) /
 				32] & SOL_WRB_INDEX_MASK) >> 16)];
-
-	task = pwrb_handle->pio_handle;
-	io_task = task->dd_data;
+		task = pwrb_handle->pio_handle;
+		pwrb = pwrb_handle->pwrb;
+		type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
+			 WRB_TYPE_MASK) >> 28;
+	}
 	spin_lock_bh(&session->lock);
-	pwrb = pwrb_handle->pwrb;
-	switch ((pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
-		 WRB_TYPE_MASK) >> 28) {
+	switch (type) {
 	case HWH_TYPE_IO:
 	case HWH_TYPE_IO_RD:
 		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
@@ -773,12 +978,21 @@ static void hwi_complete_cmd(struct beis
 		break;
 
 	default:
-		shost_printk(KERN_WARNING, phba->shost,
-			    "wrb_index 0x%x CID 0x%x\n",
-			    ((psol->dw[offsetof(struct amap_iscsi_wrb, type) /
-					32] & SOL_WRB_INDEX_MASK) >> 16),
-			    ((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
-					& SOL_CID_MASK) >> 6));
+		if (ring_mode)
+			shost_printk(KERN_WARNING, phba->shost,
+				"In hwi_complete_cmd, unknown type = %d"
+				"icd_index 0x%x CID 0x%x\n", type,
+				((psol->dw[offsetof(struct amap_sol_cqe_ring,
+				icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6),
+				psgl_handle->cid);
+		else
+			shost_printk(KERN_WARNING, phba->shost,
+				"In hwi_complete_cmd, unknown type = %d"
+				"wrb_index 0x%x CID 0x%x\n", type,
+				((psol->dw[offsetof(struct amap_iscsi_wrb,
+				type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
+				((psol->dw[offsetof(struct amap_sol_cqe,
+				cid) / 32] & SOL_CID_MASK) >> 6));
 		break;
 	}
 
@@ -1208,40 +1422,55 @@ static void hwi_process_default_pdu_ring
 	hwi_post_async_buffers(phba, pasync_handle->is_header);
 }
 
-static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
+
+static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
 {
-	struct hwi_controller *phwi_ctrlr;
-	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *cq;
 	struct sol_cqe *sol;
 	struct dmsg_cqe *dmsg;
 	unsigned int num_processed = 0;
 	unsigned int tot_nump = 0;
 	struct beiscsi_conn *beiscsi_conn;
+	struct sgl_handle *psgl_handle = NULL;
+	struct beiscsi_hba *phba;
 
-	phwi_ctrlr = phba->phwi_ctrlr;
-	phwi_context = phwi_ctrlr->phwi_ctxt;
-	cq = &phwi_context->be_cq;
+	cq = pbe_eq->cq;
 	sol = queue_tail_node(cq);
+	phba = pbe_eq->phba;
 
 	while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] &
 	       CQE_VALID_MASK) {
 		be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
 
-		beiscsi_conn = phba->conn_table[(u32) (sol->
+		if (ring_mode) {
+			psgl_handle = phba->sgl_hndl_array[((sol->
+				      dw[offsetof(struct amap_sol_cqe_ring,
+				      icd_index) / 32] & SOL_ICD_INDEX_MASK)
+				      >> 6)];
+			beiscsi_conn = phba->conn_table[psgl_handle->cid];
+			if (!beiscsi_conn || !beiscsi_conn->ep) {
+				shost_printk(KERN_WARNING, phba->shost,
+				     "Connection table empty for cid = %d\n",
+				      psgl_handle->cid);
+				return 0;
+			}
+
+		} else {
+			beiscsi_conn = phba->conn_table[(u32) (sol->
 				 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
 				 SOL_CID_MASK) >> 6];
 
-		if (!beiscsi_conn || !beiscsi_conn->ep) {
-			shost_printk(KERN_WARNING, phba->shost,
+			if (!beiscsi_conn || !beiscsi_conn->ep) {
+				shost_printk(KERN_WARNING, phba->shost,
 				     "Connection table empty for cid = %d\n",
 				     (u32)(sol->dw[offsetof(struct amap_sol_cqe,
 				     cid) / 32] & SOL_CID_MASK) >> 6);
-			return 0;
+				return 0;
+			}
 		}
 
 		if (num_processed >= 32) {
-			hwi_ring_cq_db(phba, phwi_context->be_cq.id,
+			hwi_ring_cq_db(phba, cq->id,
 					num_processed, 0, 0);
 			tot_nump += num_processed;
 			num_processed = 0;
@@ -1258,8 +1487,12 @@ static unsigned int beiscsi_process_cq(s
 			hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
 			break;
 		case UNSOL_HDR_NOTIFY:
+			SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR_ NOTIFY\n");
+			hwi_process_default_pdu_ring(beiscsi_conn, phba,
+					     (struct i_t_dpdu_cqe *)sol);
+			break;
 		case UNSOL_DATA_NOTIFY:
-			SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR/DATA_NOTIFY\n");
+			SE_DEBUG(DBG_LVL_8, "Received UNSOL_DATA_NOTIFY\n");
 			hwi_process_default_pdu_ring(beiscsi_conn, phba,
 					     (struct i_t_dpdu_cqe *)sol);
 			break;
@@ -1278,13 +1511,21 @@ static unsigned int beiscsi_process_cq(s
 		case CMD_CXN_KILLED_ITT_INVALID:
 		case CMD_CXN_KILLED_SEQ_OUTOFORDER:
 		case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
-			SE_DEBUG(DBG_LVL_1,
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1,
+				 "CQ Error notification for cmd.. "
+				 "code %d cid 0x%x\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1,
 				 "CQ Error notification for cmd.. "
 				 "code %d cid 0x%x\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & SOL_CID_MASK));
+			}
 			break;
 		case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
 			SE_DEBUG(DBG_LVL_1,
@@ -1306,23 +1547,37 @@ static unsigned int beiscsi_process_cq(s
 		case CXN_KILLED_OVER_RUN_RESIDUAL:
 		case CXN_KILLED_UNDER_RUN_RESIDUAL:
 		case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
-			SE_DEBUG(DBG_LVL_1, "CQ Error %d, resetting CID "
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
+				 "0x%x...\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
 				 "0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & CQE_CID_MASK);
+			}
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
 		case CXN_KILLED_RST_SENT:
 		case CXN_KILLED_RST_RCVD:
-			SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset received/sent "
-				 "on CID 0x%x...\n",
+			if (ring_mode) {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
+				"received/sent on CID 0x%x...\n",
+				 sol->dw[offsetof(struct amap_sol_cqe, code) /
+				 32] & CQE_CODE_MASK, psgl_handle->cid);
+			} else {
+				SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
+				"received/sent on CID 0x%x...\n",
 				 sol->dw[offsetof(struct amap_sol_cqe, code) /
 				 32] & CQE_CODE_MASK,
 				 sol->dw[offsetof(struct amap_sol_cqe, cid) /
 				 32] & CQE_CID_MASK);
+			}
 			iscsi_conn_failure(beiscsi_conn->conn,
 					   ISCSI_ERR_CONN_FAILED);
 			break;
@@ -1344,8 +1599,7 @@ static unsigned int beiscsi_process_cq(s
 
 	if (num_processed > 0) {
 		tot_nump += num_processed;
-		hwi_ring_cq_db(phba, phwi_context->be_cq.id, num_processed,
-			       1, 0);
+		hwi_ring_cq_db(phba, cq->id, num_processed, 1, 0);
 	}
 	return tot_nump;
 }
@@ -1353,21 +1607,30 @@ static unsigned int beiscsi_process_cq(s
 static void beiscsi_process_all_cqs(struct work_struct *work)
 {
 	unsigned long flags;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
 	struct beiscsi_hba *phba =
 	    container_of(work, struct beiscsi_hba, work_cqs);
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
+	if (phba->msix_enabled)
+		pbe_eq = &phwi_context->be_eq[phba->num_cpus];
+	else
+		pbe_eq = &phwi_context->be_eq[0];
+
 	if (phba->todo_mcc_cq) {
 		spin_lock_irqsave(&phba->isr_lock, flags);
 		phba->todo_mcc_cq = 0;
 		spin_unlock_irqrestore(&phba->isr_lock, flags);
-		SE_DEBUG(DBG_LVL_1, "MCC Interrupt Not expected \n");
 	}
 
 	if (phba->todo_cq) {
 		spin_lock_irqsave(&phba->isr_lock, flags);
 		phba->todo_cq = 0;
 		spin_unlock_irqrestore(&phba->isr_lock, flags);
-		beiscsi_process_cq(phba);
+		beiscsi_process_cq(pbe_eq);
 	}
 }
 
@@ -1375,19 +1638,15 @@ static int be_iopoll(struct blk_iopoll *
 {
 	static unsigned int ret;
 	struct beiscsi_hba *phba;
+	struct be_eq_obj *pbe_eq;
 
-	phba = container_of(iop, struct beiscsi_hba, iopoll);
-
-	ret = beiscsi_process_cq(phba);
+	pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
+	ret = beiscsi_process_cq(pbe_eq);
 	if (ret < budget) {
-		struct hwi_controller *phwi_ctrlr;
-		struct hwi_context_memory *phwi_context;
-
-		phwi_ctrlr = phba->phwi_ctrlr;
-		phwi_context = phwi_ctrlr->phwi_ctxt;
+		phba = pbe_eq->phba;
 		blk_iopoll_complete(iop);
-		hwi_ring_eq_db(phba, phwi_context->be_eq.q.id, 0,
-							0, 1, 1);
+		SE_DEBUG(DBG_LVL_8, "rearm pbe_eq->q.id =%d\n", pbe_eq->q.id);
+		hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
 	}
 	return ret;
 }
@@ -1537,14 +1796,12 @@ static void hwi_write_buffer(struct iscs
 
 static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
 {
-	unsigned int num_cq_pages, num_eq_pages, num_async_pdu_buf_pages;
+	unsigned int num_cq_pages, num_async_pdu_buf_pages;
 	unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn;
 	unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages;
 
 	num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
 				      sizeof(struct sol_cqe));
-	num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
-				      sizeof(struct be_eq_entry));
 	num_async_pdu_buf_pages =
 			PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
 				       phba->params.defpdu_hdr_sz);
@@ -1565,8 +1822,6 @@ static void beiscsi_find_mem_req(struct
 	phba->mem_req[HWI_MEM_ADDN_CONTEXT] =
 					    sizeof(struct hwi_context_memory);
 
-	phba->mem_req[HWI_MEM_CQ] = num_cq_pages * PAGE_SIZE;
-	phba->mem_req[HWI_MEM_EQ] = num_eq_pages * PAGE_SIZE;
 
 	phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb)
 	    * (phba->params.wrbs_per_cxn)
@@ -1751,8 +2006,6 @@ static void beiscsi_init_wrb_handle(stru
 
 	for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
 		pwrb_context = &phwi_ctrlr->wrb_context[index];
-		SE_DEBUG(DBG_LVL_8, "cid=%d pwrb_context=%p \n", index,
-						pwrb_context);
 		pwrb_context->pwrb_handle_base =
 				kzalloc(sizeof(struct wrb_handle *) *
 					phba->params.wrbs_per_cxn, GFP_KERNEL);
@@ -1767,6 +2020,7 @@ static void beiscsi_init_wrb_handle(stru
 				pwrb_context->pwrb_handle_basestd[j] =
 								pwrb_handle;
 				pwrb_context->wrb_handles_available++;
+				pwrb_handle->wrb_index = j;
 				pwrb_handle++;
 			}
 			pwrb_context->free_index = 0;
@@ -1785,6 +2039,7 @@ static void beiscsi_init_wrb_handle(stru
 				pwrb_context->pwrb_handle_basestd[j] =
 				    pwrb_handle;
 				pwrb_context->wrb_handles_available++;
+				pwrb_handle->wrb_index = j;
 				pwrb_handle++;
 			}
 			pwrb_context->free_index = 0;
@@ -2042,79 +2297,126 @@ static int be_fill_queue(struct be_queue
 	return 0;
 }
 
-static int beiscsi_create_eq(struct beiscsi_hba *phba,
+static int beiscsi_create_eqs(struct beiscsi_hba *phba,
 			     struct hwi_context_memory *phwi_context)
 {
-	unsigned int idx;
-	int ret;
+	unsigned int i, num_eq_pages;
+	int ret, eq_for_mcc;
 	struct be_queue_info *eq;
 	struct be_dma_mem *mem;
-	struct be_mem_descriptor *mem_descr;
 	void *eq_vaddress;
+	dma_addr_t paddr;
 
-	idx = 0;
-	eq = &phwi_context->be_eq.q;
-	mem = &eq->dma_mem;
-	mem_descr = phba->init_mem;
-	mem_descr += HWI_MEM_EQ;
-	eq_vaddress = mem_descr->mem_array[idx].virtual_address;
+	num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
+				      sizeof(struct be_eq_entry));
 
-	ret = be_fill_queue(eq, phba->params.num_eq_entries,
-			    sizeof(struct be_eq_entry), eq_vaddress);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "be_fill_queue Failed for EQ \n");
-		return ret;
-	}
+	if (phba->msix_enabled)
+		eq_for_mcc = 1;
+	else
+		eq_for_mcc = 0;
+	for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
+		eq = &phwi_context->be_eq[i].q;
+		mem = &eq->dma_mem;
+		phwi_context->be_eq[i].phba = phba;
+		eq_vaddress = pci_alloc_consistent(phba->pcidev,
+						     num_eq_pages * PAGE_SIZE,
+						     &paddr);
+		if (!eq_vaddress)
+			goto create_eq_error;
 
-	mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
+		mem->va = eq_vaddress;
+		ret = be_fill_queue(eq, phba->params.num_eq_entries,
+				    sizeof(struct be_eq_entry), eq_vaddress);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "be_fill_queue Failed for EQ \n");
+			goto create_eq_error;
+		}
 
-	ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
-				    phwi_context->be_eq.cur_eqd);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create"
-			     "Failedfor EQ \n");
-		return ret;
+		mem->dma = paddr;
+		ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
+					    phwi_context->cur_eqd);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "beiscsi_cmd_eq_create"
+				     "Failedfor EQ \n");
+			goto create_eq_error;
+		}
+		SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id);
 	}
-	SE_DEBUG(DBG_LVL_8, "eq id is %d\n", phwi_context->be_eq.q.id);
 	return 0;
+create_eq_error:
+	for (i = 0; i < (phba->num_cpus + 1); i++) {
+		eq = &phwi_context->be_eq[i].q;
+		mem = &eq->dma_mem;
+		if (mem->va)
+			pci_free_consistent(phba->pcidev, num_eq_pages
+					    * PAGE_SIZE,
+					    mem->va, mem->dma);
+	}
+	return ret;
 }
 
-static int beiscsi_create_cq(struct beiscsi_hba *phba,
+static int beiscsi_create_cqs(struct beiscsi_hba *phba,
 			     struct hwi_context_memory *phwi_context)
 {
-	unsigned int idx;
+	unsigned int i, num_cq_pages;
 	int ret;
 	struct be_queue_info *cq, *eq;
 	struct be_dma_mem *mem;
-	struct be_mem_descriptor *mem_descr;
+	struct be_eq_obj *pbe_eq;
 	void *cq_vaddress;
+	dma_addr_t paddr;
 
-	idx = 0;
-	cq = &phwi_context->be_cq;
-	eq = &phwi_context->be_eq.q;
-	mem = &cq->dma_mem;
-	mem_descr = phba->init_mem;
-	mem_descr += HWI_MEM_CQ;
-	cq_vaddress = mem_descr->mem_array[idx].virtual_address;
-	ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
-			    sizeof(struct sol_cqe), cq_vaddress);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "be_fill_queue Failed for ISCSI CQ \n");
-		return ret;
-	}
+	num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
+				      sizeof(struct sol_cqe));
 
-	mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
-	ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0);
-	if (ret) {
-		shost_printk(KERN_ERR, phba->shost,
-			     "beiscsi_cmd_eq_create Failed for ISCSI CQ \n");
-		return ret;
+	for (i = 0; i < phba->num_cpus; i++) {
+		cq = &phwi_context->be_cq[i];
+		eq = &phwi_context->be_eq[i].q;
+		pbe_eq = &phwi_context->be_eq[i];
+		pbe_eq->cq = cq;
+		pbe_eq->phba = phba;
+		mem = &cq->dma_mem;
+		cq_vaddress = pci_alloc_consistent(phba->pcidev,
+						     num_cq_pages * PAGE_SIZE,
+						     &paddr);
+		if (!cq_vaddress)
+			goto create_cq_error;
+		ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
+				    sizeof(struct sol_cqe), cq_vaddress);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "be_fill_queue Failed for ISCSI CQ \n");
+			goto create_cq_error;
+		}
+
+		mem->dma = paddr;
+		ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false,
+					    false, 0);
+		if (ret) {
+			shost_printk(KERN_ERR, phba->shost,
+				     "beiscsi_cmd_eq_create"
+				     "Failed for ISCSI CQ \n");
+			goto create_cq_error;
+		}
+		SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n",
+						 cq->id, eq->id);
+		SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
 	}
-	SE_DEBUG(DBG_LVL_8, "iscsi cq id is %d\n", phwi_context->be_cq.id);
-	SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
 	return 0;
+
+create_cq_error:
+	for (i = 0; i < phba->num_cpus; i++) {
+		cq = &phwi_context->be_cq[i];
+		mem = &cq->dma_mem;
+		if (mem->va)
+			pci_free_consistent(phba->pcidev, num_cq_pages
+					    * PAGE_SIZE,
+					    mem->va, mem->dma);
+	}
+	return ret;
+
 }
 
 static int
@@ -2132,7 +2434,7 @@ beiscsi_create_def_hdr(struct beiscsi_hb
 
 	idx = 0;
 	dq = &phwi_context->be_def_hdrq;
-	cq = &phwi_context->be_cq;
+	cq = &phwi_context->be_cq[0];
 	mem = &dq->dma_mem;
 	mem_descr = phba->init_mem;
 	mem_descr += HWI_MEM_ASYNC_HEADER_RING;
@@ -2176,7 +2478,7 @@ beiscsi_create_def_data(struct beiscsi_h
 
 	idx = 0;
 	dataq = &phwi_context->be_def_dataq;
-	cq = &phwi_context->be_cq;
+	cq = &phwi_context->be_cq[0];
 	mem = &dataq->dma_mem;
 	mem_descr = phba->init_mem;
 	mem_descr += HWI_MEM_ASYNC_DATA_RING;
@@ -2239,6 +2541,30 @@ beiscsi_post_pages(struct beiscsi_hba *p
 	return 0;
 }
 
+static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q)
+{
+	struct be_dma_mem *mem = &q->dma_mem;
+	if (mem->va)
+		pci_free_consistent(phba->pcidev, mem->size,
+			mem->va, mem->dma);
+}
+
+static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q,
+		u16 len, u16 entry_size)
+{
+	struct be_dma_mem *mem = &q->dma_mem;
+
+	memset(q, 0, sizeof(*q));
+	q->len = len;
+	q->entry_size = entry_size;
+	mem->size = len * entry_size;
+	mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma);
+	if (!mem->va)
+		return -1;
+	memset(mem->va, 0, mem->size);
+	return 0;
+}
+
 static int
 beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
 			 struct hwi_context_memory *phwi_context,
@@ -2328,13 +2654,29 @@ static void free_wrb_handles(struct beis
 	}
 }
 
+static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
+{
+	struct be_queue_info *q;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	q = &phba->ctrl.mcc_obj.q;
+	if (q->created)
+		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
+	be_queue_free(phba, q);
+
+	q = &phba->ctrl.mcc_obj.cq;
+	if (q->created)
+		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	be_queue_free(phba, q);
+}
+
 static void hwi_cleanup(struct beiscsi_hba *phba)
 {
 	struct be_queue_info *q;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
 	struct hwi_controller *phwi_ctrlr;
 	struct hwi_context_memory *phwi_context;
-	int i;
+	int i, eq_num;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -2343,7 +2685,6 @@ static void hwi_cleanup(struct beiscsi_h
 		if (q->created)
 			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
 	}
-
 	free_wrb_handles(phba);
 
 	q = &phwi_context->be_def_hdrq;
@@ -2356,13 +2697,76 @@ static void hwi_cleanup(struct beiscsi_h
 
 	beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
 
-	q = &phwi_context->be_cq;
-	if (q->created)
-		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	for (i = 0; i < (phba->num_cpus); i++) {
+		q = &phwi_context->be_cq[i];
+		if (q->created)
+			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+	}
+	if (phba->msix_enabled)
+		eq_num = 1;
+	else
+		eq_num = 0;
+	for (i = 0; i < (phba->num_cpus + eq_num); i++) {
+		q = &phwi_context->be_eq[i].q;
+		if (q->created)
+			beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
+	}
+	be_mcc_queues_destroy(phba);
+}
 
-	q = &phwi_context->be_eq.q;
-	if (q->created)
-		beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
+static int be_mcc_queues_create(struct beiscsi_hba *phba,
+				struct hwi_context_memory *phwi_context)
+{
+	struct be_queue_info *q, *cq;
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+
+	/* Alloc MCC compl queue */
+	cq = &phba->ctrl.mcc_obj.cq;
+	if (be_queue_alloc(phba, cq, MCC_CQ_LEN,
+			sizeof(struct be_mcc_compl)))
+		goto err;
+	/* Ask BE to create MCC compl queue; */
+	if (phba->msix_enabled) {
+		if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq
+					 [phba->num_cpus].q, false, true, 0))
+		goto mcc_cq_free;
+	} else {
+		if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq[0].q,
+					  false, true, 0))
+		goto mcc_cq_free;
+	}
+
+	/* Alloc MCC queue */
+	q = &phba->ctrl.mcc_obj.q;
+	if (be_queue_alloc(phba, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
+		goto mcc_cq_destroy;
+
+	/* Ask BE to create MCC queue */
+	if (beiscsi_cmd_mccq_create(phba, q, cq))
+		goto mcc_q_free;
+
+	return 0;
+
+mcc_q_free:
+	be_queue_free(phba, q);
+mcc_cq_destroy:
+	beiscsi_cmd_q_destroy(ctrl, cq, QTYPE_CQ);
+mcc_cq_free:
+	be_queue_free(phba, cq);
+err:
+	return -1;
+}
+
+static int find_num_cpus(void)
+{
+	int  num_cpus = 0;
+
+	num_cpus = num_online_cpus();
+	if (num_cpus >= MAX_CPUS)
+		num_cpus = MAX_CPUS - 1;
+
+	SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus);
+	return num_cpus;
 }
 
 static int hwi_init_port(struct beiscsi_hba *phba)
@@ -2376,26 +2780,33 @@ static int hwi_init_port(struct beiscsi_
 	def_pdu_ring_sz =
 		phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr);
 	phwi_ctrlr = phba->phwi_ctrlr;
-
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	phwi_context->be_eq.max_eqd = 0;
-	phwi_context->be_eq.min_eqd = 0;
-	phwi_context->be_eq.cur_eqd = 64;
-	phwi_context->be_eq.enable_aic = false;
+	phwi_context->max_eqd = 0;
+	phwi_context->min_eqd = 0;
+	phwi_context->cur_eqd = 64;
 	be_cmd_fw_initialize(&phba->ctrl);
-	status = beiscsi_create_eq(phba, phwi_context);
+
+	status = beiscsi_create_eqs(phba, phwi_context);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost, "EQ not created \n");
 		goto error;
 	}
 
-	status = mgmt_check_supported_fw(ctrl);
+	status = be_mcc_queues_create(phba, phwi_context);
+	if (status != 0)
+		goto error;
+
+	status = mgmt_check_supported_fw(ctrl, phba);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost,
 			     "Unsupported fw version \n");
 		goto error;
 	}
 
+	if (phba->fw_config.iscsi_features == 0x1)
+		ring_mode = 1;
+	else
+		ring_mode = 0;
 	status = mgmt_get_fw_config(ctrl, phba);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost,
@@ -2403,7 +2814,7 @@ static int hwi_init_port(struct beiscsi_
 		goto error;
 	}
 
-	status = beiscsi_create_cq(phba, phwi_context);
+	status = beiscsi_create_cqs(phba, phwi_context);
 	if (status != 0) {
 		shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
 		goto error;
@@ -2447,7 +2858,6 @@ error:
 	return -ENOMEM;
 }
 
-
 static int hwi_init_controller(struct beiscsi_hba *phba)
 {
 	struct hwi_controller *phwi_ctrlr;
@@ -2530,6 +2940,18 @@ static int beiscsi_init_sgl_handle(struc
 
 	phba->io_sgl_hndl_avbl = 0;
 	phba->eh_sgl_hndl_avbl = 0;
+
+	if (ring_mode) {
+		phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) *
+					      phba->params.icds_per_ctrl,
+						 GFP_KERNEL);
+		if (!phba->sgl_hndl_array) {
+			shost_printk(KERN_ERR, phba->shost,
+			     "Mem Alloc Failed. Failing to load\n");
+			return -ENOMEM;
+		}
+	}
+
 	mem_descr_sglh = phba->init_mem;
 	mem_descr_sglh += HWI_MEM_SGLH;
 	if (1 == mem_descr_sglh->num_elements) {
@@ -2537,6 +2959,8 @@ static int beiscsi_init_sgl_handle(struc
 						 phba->params.ios_per_ctrl,
 						 GFP_KERNEL);
 		if (!phba->io_sgl_hndl_base) {
+			if (ring_mode)
+				kfree(phba->sgl_hndl_array);
 			shost_printk(KERN_ERR, phba->shost,
 				     "Mem Alloc Failed. Failing to load\n");
 			return -ENOMEM;
@@ -2656,13 +3080,12 @@ static unsigned char hwi_enable_intr(str
 	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *eq;
 	u8 __iomem *addr;
-	u32 reg;
+	u32 reg, i;
 	u32 enabled;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
 
-	eq = &phwi_context->be_eq.q;
 	addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
 			PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
 	reg = ioread32(addr);
@@ -2673,9 +3096,11 @@ static unsigned char hwi_enable_intr(str
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 		SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
 		iowrite32(reg, addr);
-		SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
-
-		hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+		for (i = 0; i <= phba->num_cpus; i++) {
+			eq = &phwi_context->be_eq[i].q;
+			SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+			hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+		}
 	} else
 		shost_printk(KERN_WARNING, phba->shost,
 			     "In hwi_enable_intr, Not Enabled \n");
@@ -2720,6 +3145,8 @@ static int beiscsi_init_port(struct beis
 	if (hba_setup_cid_tbls(phba)) {
 		shost_printk(KERN_ERR, phba->shost,
 			     "Failed in hba_setup_cid_tbls\n");
+		if (ring_mode)
+			kfree(phba->sgl_hndl_array);
 		kfree(phba->io_sgl_hndl_base);
 		kfree(phba->eh_sgl_hndl_base);
 		goto do_cleanup_ctrlr;
@@ -2738,17 +3165,25 @@ static void hwi_purge_eq(struct beiscsi_
 	struct hwi_context_memory *phwi_context;
 	struct be_queue_info *eq;
 	struct be_eq_entry *eqe = NULL;
+	int i, eq_msix;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	eq = &phwi_context->be_eq.q;
-	eqe = queue_tail_node(eq);
+	if (phba->msix_enabled)
+		eq_msix = 1;
+	else
+		eq_msix = 0;
 
-	while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-						& EQE_VALID_MASK) {
-		AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-		queue_tail_inc(eq);
+	for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
+		eq = &phwi_context->be_eq[i].q;
 		eqe = queue_tail_node(eq);
+
+		while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
+					& EQE_VALID_MASK) {
+			AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
+			queue_tail_inc(eq);
+			eqe = queue_tail_node(eq);
+		}
 	}
 }
 
@@ -2762,6 +3197,8 @@ static void beiscsi_clean_port(struct be
 			     "mgmt_epfw_cleanup FAILED \n");
 	hwi_cleanup(phba);
 	hwi_purge_eq(phba);
+	if (ring_mode)
+		kfree(phba->sgl_hndl_array);
 	kfree(phba->io_sgl_hndl_base);
 	kfree(phba->eh_sgl_hndl_base);
 	kfree(phba->cid_array);
@@ -2846,8 +3283,9 @@ beiscsi_offload_connection(struct beiscs
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) <<
-					DB_DEF_PDU_WRB_INDEX_SHIFT;
+	if (!ring_mode)
+		doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK)
+			     << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
 	iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -2856,7 +3294,7 @@ beiscsi_offload_connection(struct beiscs
 static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
 			      int *index, int *age)
 {
-	*index = be32_to_cpu(itt) >> 16;
+	*index = (int)itt;
 	if (age)
 		*age = conn->session->age;
 }
@@ -2885,15 +3323,13 @@ static int beiscsi_alloc_pdu(struct iscs
 
 	io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool,
 					  GFP_KERNEL, &paddr);
-
 	if (!io_task->cmd_bhs)
 		return -ENOMEM;
-
 	io_task->bhs_pa.u.a64.address = paddr;
+	io_task->libiscsi_itt = (itt_t)task->itt;
 	io_task->pwrb_handle = alloc_wrb_handle(phba,
 						beiscsi_conn->beiscsi_conn_cid,
 						task->itt);
-	io_task->pwrb_handle->pio_handle = task;
 	io_task->conn = beiscsi_conn;
 
 	task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
@@ -2905,7 +3341,6 @@ static int beiscsi_alloc_pdu(struct iscs
 		spin_unlock(&phba->io_sgl_lock);
 		if (!io_task->psgl_handle)
 			goto free_hndls;
-
 	} else {
 		io_task->scsi_cmnd = NULL;
 		if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
@@ -2932,8 +3367,18 @@ static int beiscsi_alloc_pdu(struct iscs
 				goto free_hndls;
 		}
 	}
-	itt = (itt_t) cpu_to_be32(((unsigned int)task->itt << 16) |
-			(unsigned int)(io_task->psgl_handle->sgl_index));
+	itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
+				 wrb_index << 16) | (unsigned int)
+				(io_task->psgl_handle->sgl_index));
+	if (ring_mode) {
+		phba->sgl_hndl_array[io_task->psgl_handle->sgl_index -
+				     phba->fw_config.iscsi_cid_start] =
+				     io_task->psgl_handle;
+		io_task->psgl_handle->task = task;
+		io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid;
+	} else
+		io_task->pwrb_handle->pio_handle = task;
+
 	io_task->cmd_bhs->iscsi_hdr.itt = itt;
 	return 0;
 
@@ -3006,7 +3451,6 @@ static int beiscsi_iotask(struct iscsi_t
 	io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
 	if (writedir) {
-		SE_DEBUG(DBG_LVL_4, " WRITE Command \t");
 		memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48);
 		AMAP_SET_BITS(struct amap_pdu_data_out, itt,
 			      &io_task->cmd_bhs->iscsi_data_pdu,
@@ -3016,11 +3460,18 @@ static int beiscsi_iotask(struct iscsi_t
 			      ISCSI_OPCODE_SCSI_DATA_OUT);
 		AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
 			      &io_task->cmd_bhs->iscsi_data_pdu, 1);
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_WR_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_WR_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
 	} else {
-		SE_DEBUG(DBG_LVL_4, "READ Command \t");
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_RD_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_RD_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
 	}
 	memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
@@ -3045,7 +3496,8 @@ static int beiscsi_iotask(struct iscsi_t
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
 	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (io_task->pwrb_handle->wrb_index &
+	if (!ring_mode)
+		doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 
@@ -3059,10 +3511,16 @@ static int beiscsi_mtask(struct iscsi_ta
 	struct iscsi_conn *conn = task->conn;
 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
+	struct iscsi_session *session;
 	struct iscsi_wrb *pwrb = NULL;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_wrb_context *pwrb_context;
+	struct wrb_handle *pwrb_handle;
 	unsigned int doorbell = 0;
+	unsigned int i, cid;
 	struct iscsi_task *aborted_task;
 
+	cid = beiscsi_conn->beiscsi_conn_cid;
 	pwrb = io_task->pwrb_handle->pwrb;
 	AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
 		      be32_to_cpu(task->cmdsn));
@@ -3073,38 +3531,63 @@ static int beiscsi_mtask(struct iscsi_ta
 
 	switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
 	case ISCSI_OP_LOGIN:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, TGT_DM_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = TGT_DM_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      TGT_DM_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_NOOP_OUT:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_RD_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_RD_CMD);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_TEXT:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_WR_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_WR_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_SCSI_TMFUNC:
-		aborted_task = iscsi_itt_to_task(conn,
-					((struct iscsi_tm *)task->hdr)->rtt);
+		session = conn->session;
+		i = ((struct iscsi_tm *)task->hdr)->rtt;
+		phwi_ctrlr = phba->phwi_ctrlr;
+		pwrb_context = &phwi_ctrlr->wrb_context[cid];
+		pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
+								>> 16];
+		aborted_task = pwrb_handle->pio_handle;
 		 if (!aborted_task)
 			return 0;
+
 		aborted_io_task = aborted_task->dd_data;
 		if (!aborted_io_task->scsi_cmnd)
 			return 0;
 
 		mgmt_invalidate_icds(phba,
 				     aborted_io_task->psgl_handle->sgl_index,
-				     beiscsi_conn->beiscsi_conn_cid);
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD);
+				     cid);
+		if (ring_mode)
+			io_task->psgl_handle->type = INI_TMF_CMD;
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      INI_TMF_CMD);
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_LOGOUT:
 		AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
+		if (ring_mode)
+			io_task->psgl_handle->type = HWH_TYPE_LOGOUT;
+		else
 		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
 				HWH_TYPE_LOGOUT);
 		hwi_write_buffer(pwrb, task);
@@ -3122,8 +3605,9 @@ static int beiscsi_mtask(struct iscsi_ta
 		      io_task->pwrb_handle->nxt_wrb_index);
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
 
-	doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
-	doorbell |= (io_task->pwrb_handle->wrb_index &
+	doorbell |= cid & DB_WRB_POST_CID_MASK;
+	if (!ring_mode)
+		doorbell |= (io_task->pwrb_handle->wrb_index &
 		     DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
 	doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
 	iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
@@ -3165,9 +3649,14 @@ static int beiscsi_task_xmit(struct iscs
 	return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
 }
 
+
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
 	struct beiscsi_hba *phba = NULL;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
+	unsigned int i, msix_vec;
 
 	phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
 	if (!phba) {
@@ -3175,12 +3664,24 @@ static void beiscsi_remove(struct pci_de
 		return;
 	}
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
 	hwi_disable_intr(phba);
-	if (phba->pcidev->irq)
-		free_irq(phba->pcidev->irq, phba);
+	if (phba->msix_enabled) {
+		for (i = 0; i <= phba->num_cpus; i++) {
+			msix_vec = phba->msix_entries[i].vector;
+			free_irq(msix_vec, &phwi_context->be_eq[i]);
+		}
+	} else
+		if (phba->pcidev->irq)
+			free_irq(phba->pcidev->irq, phba);
+	pci_disable_msix(phba->pcidev);
 	destroy_workqueue(phba->wq);
 	if (blk_iopoll_enabled)
-		blk_iopoll_disable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_disable(&pbe_eq->iopoll);
+		}
 
 	beiscsi_clean_port(phba);
 	beiscsi_free_mem(phba);
@@ -3194,11 +3695,29 @@ static void beiscsi_remove(struct pci_de
 	iscsi_host_free(phba->shost);
 }
 
+static void beiscsi_msix_enable(struct beiscsi_hba *phba)
+{
+	int i, status;
+
+	for (i = 0; i <= phba->num_cpus; i++)
+		phba->msix_entries[i].entry = i;
+
+	status = pci_enable_msix(phba->pcidev, phba->msix_entries,
+				 (phba->num_cpus + 1));
+	if (!status)
+		phba->msix_enabled = true;
+
+	return;
+}
+
 static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
 				const struct pci_device_id *id)
 {
 	struct beiscsi_hba *phba = NULL;
-	int ret;
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+	struct be_eq_obj *pbe_eq;
+	int ret, msix_vec, num_cpus, i;
 
 	ret = beiscsi_enable_pci(pcidev);
 	if (ret < 0) {
@@ -3213,8 +3732,18 @@ static int __devinit beiscsi_dev_probe(s
 			" Failed in beiscsi_hba_alloc \n");
 		goto disable_pci;
 	}
+	SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
 
 	pci_set_drvdata(pcidev, phba);
+	if (enable_msix)
+		num_cpus = find_num_cpus();
+	else
+		num_cpus = 1;
+	phba->num_cpus = num_cpus;
+	SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus);
+
+	if (enable_msix)
+		beiscsi_msix_enable(phba);
 	ret = be_ctrl_init(phba, pcidev);
 	if (ret) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3235,7 +3764,7 @@ static int __devinit beiscsi_dev_probe(s
 
 	snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
 		 phba->shost->host_no);
-	phba->wq = create_singlethread_workqueue(phba->wq_name);
+	phba->wq = create_workqueue(phba->wq_name);
 	if (!phba->wq) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
 				"Failed to allocate work queue\n");
@@ -3244,11 +3773,16 @@ static int __devinit beiscsi_dev_probe(s
 
 	INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs);
 
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
 	if (blk_iopoll_enabled) {
-		blk_iopoll_init(&phba->iopoll, be_iopoll_budget, be_iopoll);
-		blk_iopoll_enable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_init(&pbe_eq->iopoll, be_iopoll_budget,
+					be_iopoll);
+			blk_iopoll_enable(&pbe_eq->iopoll);
+		}
 	}
-
 	ret = beiscsi_init_irqs(phba);
 	if (ret < 0) {
 		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
@@ -3261,17 +3795,26 @@ static int __devinit beiscsi_dev_probe(s
 			     "Failed to hwi_enable_intr\n");
 		goto free_ctrlr;
 	}
-
 	SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n");
 	return 0;
 
 free_ctrlr:
-	if (phba->pcidev->irq)
-		free_irq(phba->pcidev->irq, phba);
+	if (phba->msix_enabled) {
+		for (i = 0; i <= phba->num_cpus; i++) {
+			msix_vec = phba->msix_entries[i].vector;
+			free_irq(msix_vec, &phwi_context->be_eq[i]);
+		}
+	} else
+		if (phba->pcidev->irq)
+			free_irq(phba->pcidev->irq, phba);
+	pci_disable_msix(phba->pcidev);
 free_blkenbld:
 	destroy_workqueue(phba->wq);
 	if (blk_iopoll_enabled)
-		blk_iopoll_disable(&phba->iopoll);
+		for (i = 0; i < phba->num_cpus; i++) {
+			pbe_eq = &phwi_context->be_eq[i];
+			blk_iopoll_disable(&pbe_eq->iopoll);
+		}
 free_twq:
 	beiscsi_clean_port(phba);
 	beiscsi_free_mem(phba);
@@ -3316,7 +3859,7 @@ struct iscsi_transport beiscsi_iscsi_tra
 		ISCSI_USERNAME | ISCSI_PASSWORD |
 		ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 		ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-		ISCSI_LU_RESET_TMO |
+		ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 		ISCSI_PING_TMO | ISCSI_RECV_TMO |
 		ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
@@ -3351,6 +3894,7 @@ static struct pci_driver beiscsi_pci_dri
 	.id_table = beiscsi_pci_id_table
 };
 
+
 static int __init beiscsi_module_init(void)
 {
 	int ret;
@@ -3373,6 +3917,7 @@ static int __init beiscsi_module_init(vo
 			 "beiscsi pci driver.\n");
 		goto unregister_iscsi_transport;
 	}
+	ring_mode = 0;
 	return 0;
 
 unregister_iscsi_transport:
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_main.h linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_main.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_main.h	2010-02-24 13:52:17.000000000 -0500
@@ -21,11 +21,9 @@
 #ifndef _BEISCSI_MAIN_
 #define _BEISCSI_MAIN_
 
-
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/in.h>
-#include <linux/blk-iopoll.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -35,12 +33,8 @@
 #include <scsi/scsi_transport_iscsi.h>
 
 #include "be.h"
-
-
-
 #define DRV_NAME		"be2iscsi"
 #define BUILD_STR		"2.0.527.0"
-
 #define BE_NAME			"ServerEngines BladeEngine2" \
 				"Linux iSCSI Driver version" BUILD_STR
 #define DRV_DESC		BE_NAME " " "Driver"
@@ -49,6 +43,8 @@
 #define BE_DEVICE_ID1		0x212
 #define OC_DEVICE_ID1		0x702
 #define OC_DEVICE_ID2		0x703
+#define OC_DEVICE_ID3		0x712
+#define OC_DEVICE_ID4		0x222
 
 #define BE2_MAX_SESSIONS	64
 #define BE2_CMDS_PER_CXN	128
@@ -63,6 +59,7 @@
 #define BE2_IO_DEPTH \
 	(BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
 
+#define MAX_CPUS		31
 #define BEISCSI_SGLIST_ELEMENTS	BE2_SGE
 
 #define BEISCSI_MAX_CMNDS	1024	/* Max IO's per Ctrlr sht->can_queue */
@@ -79,7 +76,7 @@
 #define BE_SENSE_INFO_SIZE		258
 #define BE_ISCSI_PDU_HEADER_SIZE	64
 #define BE_MIN_MEM_SIZE			16384
-
+#define MAX_CMD_SZ			65536
 #define IIOC_SCSI_DATA                  0x05	/* Write Operation */
 
 #define DBG_LVL				0x00000001
@@ -100,6 +97,8 @@ do {							\
 	}						\
 } while (0);
 
+#define BE_ADAPTER_UP		0x00000000
+#define BE_ADAPTER_LINK_DOWN	0x00000001
 /**
  * hardware needs the async PDU buffers to be posted in multiples of 8
  * So have atleast 8 of them by default
@@ -160,21 +159,19 @@ do {							\
 
 enum be_mem_enum {
 	HWI_MEM_ADDN_CONTEXT,
-	HWI_MEM_CQ,
-	HWI_MEM_EQ,
 	HWI_MEM_WRB,
 	HWI_MEM_WRBH,
-	HWI_MEM_SGLH,	/* 5 */
+	HWI_MEM_SGLH,
 	HWI_MEM_SGE,
-	HWI_MEM_ASYNC_HEADER_BUF,
+	HWI_MEM_ASYNC_HEADER_BUF, 	/* 5 */
 	HWI_MEM_ASYNC_DATA_BUF,
 	HWI_MEM_ASYNC_HEADER_RING,
-	HWI_MEM_ASYNC_DATA_RING,	/* 10 */
+	HWI_MEM_ASYNC_DATA_RING,
 	HWI_MEM_ASYNC_HEADER_HANDLE,
-	HWI_MEM_ASYNC_DATA_HANDLE,
+	HWI_MEM_ASYNC_DATA_HANDLE, 	/* 10 */
 	HWI_MEM_ASYNC_PDU_CONTEXT,
 	ISCSI_MEM_GLOBAL_HEADER,
-	SE_MEM_MAX  	/* 15 */
+	SE_MEM_MAX
 };
 
 struct be_bus_address32 {
@@ -212,6 +209,9 @@ struct be_mem_descriptor {
 
 struct sgl_handle {
 	unsigned int sgl_index;
+	unsigned int type;
+	unsigned int cid;
+	struct iscsi_task *task;
 	struct iscsi_sge *pfrag;
 };
 
@@ -274,13 +274,17 @@ struct beiscsi_hba {
 	struct pci_dev *pcidev;
 	unsigned int state;
 	unsigned short asic_revision;
-	struct blk_iopoll	iopoll;
+	unsigned int num_cpus;
+	unsigned int nxt_cqid;
+	struct msix_entry msix_entries[MAX_CPUS + 1];
+	bool msix_enabled;
 	struct be_mem_descriptor *init_mem;
 
 	unsigned short io_sgl_alloc_index;
 	unsigned short io_sgl_free_index;
 	unsigned short io_sgl_hndl_avbl;
 	struct sgl_handle **io_sgl_hndl_base;
+	struct sgl_handle **sgl_hndl_array;
 
 	unsigned short eh_sgl_alloc_index;
 	unsigned short eh_sgl_free_index;
@@ -315,6 +319,7 @@ struct beiscsi_hba {
 		unsigned short cid_alloc;
 		unsigned short cid_free;
 		unsigned short avlbl_cids;
+		unsigned short iscsi_features;
 		spinlock_t cid_lock;
 	} fw_config;
 
@@ -343,6 +348,7 @@ struct beiscsi_conn {
 	unsigned short login_in_progress;
 	struct sgl_handle *plogin_sgl_handle;
 	struct beiscsi_session *beiscsi_sess;
+	struct iscsi_task *task;
 };
 
 /* This structure is used by the chip */
@@ -390,7 +396,7 @@ struct beiscsi_io_task {
 	unsigned int flags;
 	unsigned short cid;
 	unsigned short header_len;
-
+	itt_t libiscsi_itt;
 	struct be_cmd_bhs *cmd_bhs;
 	struct be_bus_address bhs_pa;
 	unsigned short bhs_len;
@@ -599,7 +605,6 @@ struct amap_cq_db {
 
 void beiscsi_process_eq(struct beiscsi_hba *phba);
 
-
 struct iscsi_wrb {
 	u32 dw[16];
 } __packed;
@@ -820,10 +825,12 @@ struct wrb_handle {
 };
 
 struct hwi_context_memory {
-	struct be_eq_obj be_eq;
-	struct be_queue_info be_cq;
-	struct be_queue_info be_mcc_cq;
-	struct be_queue_info be_mcc;
+	/* Adaptive interrupt coalescing (AIC) info */
+	u16 min_eqd;		/* in usecs */
+	u16 max_eqd;		/* in usecs */
+	u16 cur_eqd;		/* in usecs */
+	struct be_eq_obj be_eq[MAX_CPUS];
+	struct be_queue_info be_cq[MAX_CPUS];
 
 	struct be_queue_info be_def_hdrq;
 	struct be_queue_info be_def_dataq;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_mgmt.c linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_mgmt.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.c	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,6 @@ unsigned char mgmt_get_fw_config(struct
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 			   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
-
 	status = be_mbox_notify(ctrl);
 	if (!status) {
 		struct be_fw_cfg *pfw_cfg;
@@ -58,7 +57,8 @@ unsigned char mgmt_get_fw_config(struct
 	return status;
 }
 
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl)
+unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+				      struct beiscsi_hba *phba)
 {
 	struct be_dma_mem nonemb_cmd;
 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
@@ -85,7 +85,6 @@ unsigned char mgmt_check_supported_fw(st
 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd.size);
-
 	status = be_mbox_notify(ctrl);
 	if (!status) {
 		struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
@@ -95,21 +94,25 @@ unsigned char mgmt_check_supported_fw(st
 			resp->params.hba_attribs.firmware_version_string);
 		SE_DEBUG(DBG_LVL_8,
 			"Developer Build, not performing version check...\n");
-
+		phba->fw_config.iscsi_features =
+				resp->params.hba_attribs.iscsi_features;
+		SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n",
+				      phba->fw_config.iscsi_features);
 	} else
 		SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
+	spin_unlock(&ctrl->mbox_lock);
 	if (nonemb_cmd.va)
 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
 				    nonemb_cmd.va, nonemb_cmd.dma);
 
-	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
 
+
 unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct iscsi_cleanup_req *req = embedded_payload(wrb);
 	int status = 0;
 
@@ -124,7 +127,7 @@ unsigned char mgmt_epfw_cleanup(struct b
 	req->hdr_ring_id = 0;
 	req->data_ring_id = 0;
 
-	status = be_mbox_notify(ctrl);
+	status =  be_mcc_notify_wait(phba);
 	if (status)
 		shost_printk(KERN_WARNING, phba->shost,
 			     " mgmt_epfw_cleanup , FAILED\n");
@@ -137,7 +140,7 @@ unsigned char mgmt_invalidate_icds(struc
 {
 	struct be_dma_mem nonemb_cmd;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct be_sge *sge = nonembedded_sgl(wrb);
 	struct invalidate_commands_params_in *req;
 	int status = 0;
@@ -169,7 +172,7 @@ unsigned char mgmt_invalidate_icds(struc
 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd.size);
 
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
 	spin_unlock(&ctrl->mbox_lock);
@@ -186,7 +189,7 @@ unsigned char mgmt_invalidate_connection
 					 unsigned short savecfg_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct iscsi_invalidate_connection_params_in *req =
 						embedded_payload(wrb);
 	int status = 0;
@@ -205,7 +208,7 @@ unsigned char mgmt_invalidate_connection
 	else
 		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
 	req->save_cfg = savecfg_flag;
-	status = be_mbox_notify(ctrl);
+	status =  be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
 
@@ -217,7 +220,7 @@ unsigned char mgmt_upload_connection(str
 				unsigned short cid, unsigned int upload_flag)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct tcp_upload_params_in *req = embedded_payload(wrb);
 	int status = 0;
 
@@ -229,7 +232,7 @@ unsigned char mgmt_upload_connection(str
 			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
 	req->id = (unsigned short)cid;
 	req->upload_type = (unsigned char)upload_flag;
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (status)
 		SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
 	spin_unlock(&ctrl->mbox_lock);
@@ -245,13 +248,14 @@ int mgmt_open_connection(struct beiscsi_
 	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
 	struct tcp_connect_and_offload_in *req = embedded_payload(wrb);
 	unsigned short def_hdr_id;
 	unsigned short def_data_id;
 	struct phys_addr template_address = { 0, 0 };
 	struct phys_addr *ptemplate_address;
 	int status = 0;
+	unsigned int i;
 	unsigned short cid = beiscsi_ep->ep_cid;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
@@ -296,14 +300,18 @@ int mgmt_open_connection(struct beiscsi_
 
 	}
 	req->cid = cid;
-	req->cq_id = phwi_context->be_cq.id;
+	i = phba->nxt_cqid++;
+	if (phba->nxt_cqid == phba->num_cpus)
+		phba->nxt_cqid = 0;
+	req->cq_id = phwi_context->be_cq[i].id;
+	SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id);
 	req->defq_id = def_hdr_id;
 	req->hdr_ring_id = def_hdr_id;
 	req->data_ring_id = def_data_id;
 	req->do_offload = 1;
 	req->dataout_template_pa.lo = ptemplate_address->lo;
 	req->dataout_template_pa.hi = ptemplate_address->hi;
-	status = be_mbox_notify(ctrl);
+	status = be_mcc_notify_wait(phba);
 	if (!status) {
 		struct iscsi_endpoint *ep;
 		struct tcp_connect_and_offload_out *ptcpcnct_out =
@@ -311,7 +319,7 @@ int mgmt_open_connection(struct beiscsi_
 
 		ep = phba->ep_array[ptcpcnct_out->cid];
 		beiscsi_ep = ep->dd_data;
-		beiscsi_ep->fw_handle = 0;
+		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
 		beiscsi_ep->cid_vld = 1;
 		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
 	} else
@@ -319,3 +327,30 @@ int mgmt_open_connection(struct beiscsi_
 	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
+
+int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr)
+{
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
+	struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
+	int status;
+
+	SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
+	spin_lock(&ctrl->mbox_lock);
+	memset(wrb, 0, sizeof(*wrb));
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
+			   sizeof(*req));
+
+	status = be_mcc_notify_wait(phba);
+	if (!status) {
+		struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
+
+		memcpy(mac_addr, resp->mac_address, ETH_ALEN);
+	}
+
+	spin_unlock(&ctrl->mbox_lock);
+	return status;
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_mgmt.h linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/be2iscsi/be_mgmt.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/be2iscsi/be_mgmt.h	2010-02-24 13:52:17.000000000 -0500
@@ -175,7 +175,9 @@ struct mgmt_hba_attributes {
 	u8 phy_port;
 	u32 firmware_post_status;
 	u32 hba_mtu[8];
-	u32 future_u32[4];
+	u8 iscsi_features;
+	u8 future_u8[3];
+	u32 future_u32[3];
 } __packed;
 
 struct mgmt_controller_attributes {
@@ -246,4 +248,8 @@ unsigned char mgmt_invalidate_connection
 					 unsigned short cid,
 					 unsigned short issue_reset,
 					 unsigned short savecfg_flag);
+
+unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl,
+			  struct beiscsi_hba *phba,
+			  char *buf, unsigned int len);
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_cb_ioim_macros.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_cb_ioim_macros.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_cb_ioim_macros.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_cb_ioim_macros.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ bfad_int_to_lun(u32 luno)
 	lun.bfa_lun     = 0;
 	lun.scsi_lun[0] = bfa_os_htons(luno);
 
-	return (lun.bfa_lun);
+	return lun.bfa_lun;
 }
 
 /**
@@ -68,7 +68,7 @@ bfa_cb_ioim_get_cdb(struct bfad_ioim_s *
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return ((u8 *) cmnd->cmnd);
+	return (u8 *) cmnd->cmnd;
 }
 
 /**
@@ -97,7 +97,7 @@ bfa_cb_ioim_get_size(struct bfad_ioim_s
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return (scsi_bufflen(cmnd));
+	return scsi_bufflen(cmnd);
 }
 
 /**
@@ -129,7 +129,7 @@ bfa_cb_ioim_get_sgaddr(struct bfad_ioim_
 	sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
 	addr = (u64) sg_dma_address(sge);
 
-	return (*(union bfi_addr_u *) &addr);
+	return *((union bfi_addr_u *) &addr);
 }
 
 static inline u32
@@ -197,7 +197,7 @@ bfa_cb_ioim_get_cdblen(struct bfad_ioim_
 {
 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
 
-	return (cmnd->cmd_len);
+	return cmnd->cmd_len;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_cee.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_cee.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_cee.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_cee.c	2010-02-24 13:52:17.000000000 -0500
@@ -228,7 +228,7 @@ bfa_cee_reset_stats_isr(struct bfa_cee_s
 u32
 bfa_cee_meminfo(void)
 {
-	return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
+	return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_csdebug.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_csdebug.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_csdebug.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_csdebug.c	2010-02-24 13:52:17.000000000 -0500
@@ -47,12 +47,12 @@ bfa_q_is_on_q_func(struct list_head *q,
 	tqe = bfa_q_next(q);
 	while (tqe != q) {
 		if (tqe == qe)
-			return (1);
+			return 1;
 		tqe = bfa_q_next(tqe);
 		if (tqe == NULL)
 			break;
 	}
-	return (0);
+	return 0;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad.c	2010-02-24 13:52:17.000000000 -0500
@@ -188,8 +188,8 @@ static struct bfad_port_s *
 bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
 		  struct bfad_vport_s *vp_drv)
 {
-	return ((vp_drv) ? (&(vp_drv)->drv_port)
-		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)));
+	return (vp_drv) ? (&(vp_drv)->drv_port)
+		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
 }
 
 struct bfad_port_s *
@@ -716,7 +716,7 @@ bfad_drv_init(struct bfad_s *bfad)
 	if ((bfad->bfad_flags & BFAD_MSIX_ON)
 	    && bfad_install_msix_handler(bfad)) {
 		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
-		       __FUNCTION__, bfad->inst_no);
+		       __func__, bfad->inst_no);
 	}
 
 	bfad_init_timer(bfad);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_fwimg.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_fwimg.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_fwimg.c	2013-05-03 14:05:11.000000000 -0400
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_fwimg.c	2013-05-03 12:12:46.000000000 -0400
@@ -64,10 +64,10 @@ bfad_read_firmware(struct pci_dev *pdev,
 	memcpy(*bfi_image, fw->data, fw->size);
 	*bfi_image_size = fw->size/sizeof(u32);
 
-	return(*bfi_image);
+	return *bfi_image;
 
 error:
-	return(NULL);
+	return NULL;
 }
 
 u32 *
@@ -77,12 +77,12 @@ bfad_get_firmware_buf(struct pci_dev *pd
 		if (bfi_image_ct_size == 0)
 			bfad_read_firmware(pdev, &bfi_image_ct,
 				&bfi_image_ct_size, BFAD_FW_FILE_CT);
-		return(bfi_image_ct);
+		return bfi_image_ct;
 	} else {
 		if (bfi_image_cb_size == 0)
 			bfad_read_firmware(pdev, &bfi_image_cb,
 				&bfi_image_cb_size, BFAD_FW_FILE_CB);
-		return(bfi_image_cb);
+		return bfi_image_cb;
 	}
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_im.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_im.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im.c	2010-02-24 13:52:17.000000000 -0500
@@ -1050,7 +1050,7 @@ bfad_im_itnim_work_handler(struct work_s
 		} else {
 			printk(KERN_WARNING
 				"%s: itnim %llx is already in online state\n",
-				__FUNCTION__,
+				__func__,
 				bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
 		}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_im_compat.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im_compat.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_im_compat.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_im_compat.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@ u32 *bfad_read_firmware(struct pci_dev *
 static inline u32 *
 bfad_load_fwimg(struct pci_dev *pdev)
 {
-	return(bfad_get_firmware_buf(pdev));
+	return bfad_get_firmware_buf(pdev);
 }
 
 static inline void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_intr.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_intr.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfad_intr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfad_intr.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,13 +23,12 @@ BFA_TRC_FILE(LDRV, INTR);
 /**
  *  bfa_isr BFA driver interrupt functions
  */
-irqreturn_t bfad_intx(int irq, void *dev_id);
 static int msix_disable;
 module_param(msix_disable, int, S_IRUGO | S_IWUSR);
 /**
  * Line based interrupt handler.
  */
-irqreturn_t
+static irqreturn_t
 bfad_intx(int irq, void *dev_id)
 {
 	struct bfad_s         *bfad = dev_id;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcpim.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcpim.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcpim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcpim.c	2010-02-24 13:52:17.000000000 -0500
@@ -131,7 +131,7 @@ bfa_fcpim_path_tov_get(struct bfa_s *bfa
 {
 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 
-	return (fcpim->path_tov / 1000);
+	return fcpim->path_tov / 1000;
 }
 
 bfa_status_t
@@ -169,7 +169,7 @@ bfa_fcpim_qdepth_get(struct bfa_s *bfa)
 {
 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 
-	return (fcpim->q_depth);
+	return fcpim->q_depth;
 }
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcpim_priv.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcpim_priv.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcpim_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcpim_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -35,7 +35,7 @@
 #define BFA_FCPIM_PATHTOV_MAX	(90 * 1000)	/* in millisecs */
 
 #define bfa_fcpim_stats(__fcpim, __stats)   \
-    (__fcpim)->stats.__stats ++
+    ((__fcpim)->stats.__stats++)
 
 struct bfa_fcpim_mod_s {
 	struct bfa_s 	*bfa;
@@ -143,7 +143,7 @@ struct bfa_itnim_s {
 	struct bfa_itnim_hal_stats_s	stats;
 };
 
-#define bfa_itnim_is_online(_itnim) (_itnim)->is_online
+#define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
 #define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
 #define BFA_IOIM_FROM_TAG(_fcpim, _iotag)	\
 	(&fcpim->ioim_arr[_iotag])
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcport.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcport.c	2010-02-24 13:52:17.000000000 -0500
@@ -388,32 +388,29 @@ bfa_pport_sm_linkup(struct bfa_pport_s *
 		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
 		bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
 			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	case BFA_PPORT_SM_STOP:
 		bfa_sm_set_state(pport, bfa_pport_sm_stopped);
 		bfa_pport_reset_linkinfo(pport);
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	case BFA_PPORT_SM_HWFAIL:
 		bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
 		bfa_pport_reset_linkinfo(pport);
 		bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-		if (BFA_PORT_IS_DISABLED(pport->bfa)) {
+		if (BFA_PORT_IS_DISABLED(pport->bfa))
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-		} else {
+		else
 			bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
-		}
 		break;
 
 	default:
@@ -999,10 +996,10 @@ bfa_pport_enable(struct bfa_s *bfa)
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
 	if (pport->diag_busy)
-		return (BFA_STATUS_DIAG_BUSY);
+		return BFA_STATUS_DIAG_BUSY;
 	else if (bfa_sm_cmp_state
 		 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 
 	bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
 	return BFA_STATUS_OK;
@@ -1032,7 +1029,7 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, e
 
 	pport->cfg.speed = speed;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1068,7 +1065,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa
 	}
 
 	pport->cfg.topology = topology;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1094,7 +1091,7 @@ bfa_pport_cfg_hardalpa(struct bfa_s *bfa
 	pport->cfg.cfg_hardalpa = BFA_TRUE;
 	pport->cfg.hardalpa = alpa;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1106,7 +1103,7 @@ bfa_pport_clr_hardalpa(struct bfa_s *bfa
 	bfa_trc(bfa, pport->cfg.hardalpa);
 
 	pport->cfg.cfg_hardalpa = BFA_FALSE;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
@@ -1138,16 +1135,16 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bf
 	 * with in range
 	 */
 	if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
-		return (BFA_STATUS_INVLD_DFSZ);
+		return BFA_STATUS_INVLD_DFSZ;
 
 	/*
 	 * power of 2, if not the max frame size of 2112
 	 */
 	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
-		return (BFA_STATUS_INVLD_DFSZ);
+		return BFA_STATUS_INVLD_DFSZ;
 
 	pport->cfg.maxfrsize = maxfrsize;
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 u16
@@ -1415,7 +1412,7 @@ bfa_pport_get_stats(struct bfa_s *bfa, u
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1427,7 +1424,7 @@ bfa_pport_get_stats(struct bfa_s *bfa, u
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1437,7 +1434,7 @@ bfa_pport_clear_stats(struct bfa_s *bfa,
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1448,7 +1445,7 @@ bfa_pport_clear_stats(struct bfa_s *bfa,
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -1515,7 +1512,7 @@ bfa_pport_get_qos_stats(struct bfa_s *bf
 	/*
 	 * QoS stats is embedded in port stats
 	 */
-	return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg));
+	return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
 bfa_status_t
@@ -1525,7 +1522,7 @@ bfa_pport_clear_qos_stats(struct bfa_s *
 
 	if (port->stats_busy) {
 		bfa_trc(bfa, port->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	port->stats_busy = BFA_TRUE;
@@ -1536,7 +1533,7 @@ bfa_pport_clear_qos_stats(struct bfa_s *
 
 	bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
 			BFA_PORT_STATS_TOV);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1545,7 +1542,7 @@ bfa_pport_clear_qos_stats(struct bfa_s *
 bfa_status_t
 bfa_pport_trunk_disable(struct bfa_s *bfa)
 {
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
@@ -1562,8 +1559,8 @@ bfa_pport_is_disabled(struct bfa_s *bfa)
 {
 	struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
 
-	return (bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
-		BFA_PPORT_ST_DISABLED);
+	return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+		BFA_PPORT_ST_DISABLED;
 
 }
 
@@ -1572,7 +1569,7 @@ bfa_pport_is_ratelim(struct bfa_s *bfa)
 {
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
-return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE);
+	return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
 
 }
 
@@ -1620,7 +1617,7 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s
 
 	pport->cfg.trl_def_speed = speed;
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
@@ -1632,7 +1629,7 @@ bfa_pport_get_ratelim_speed(struct bfa_s
 	struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
 
 	bfa_trc(bfa, pport->cfg.trl_def_speed);
-	return (pport->cfg.trl_def_speed);
+	return pport->cfg.trl_def_speed;
 
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcs_lport.c	2010-02-24 13:52:17.000000000 -0500
@@ -568,11 +568,10 @@ bfa_fcs_port_offline_actions(struct bfa_
 
 	__port_action[port->fabric->fab_type].offline(port);
 
-	if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) {
+	if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
 		bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
-	} else {
+	else
 		bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
-	}
 	bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
 			port->fabric->vf_drv,
 			(port->vport == NULL) ? NULL : port->vport->vport_drv);
@@ -777,7 +776,7 @@ bfa_fcs_port_get_rport_by_pwwn(struct bf
 	}
 
 	bfa_trc(port->fcs, pwwn);
-	return (NULL);
+	return NULL;
 }
 
 /**
@@ -796,7 +795,7 @@ bfa_fcs_port_get_rport_by_nwwn(struct bf
 	}
 
 	bfa_trc(port->fcs, nwwn);
-	return (NULL);
+	return NULL;
 }
 
 /**
@@ -870,7 +869,7 @@ bfa_fcs_port_lip(struct bfa_fcs_port_s *
 bfa_boolean_t
 bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
 {
-	return (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online));
+	return bfa_sm_cmp_state(port, bfa_fcs_port_sm_online);
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcxp.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcxp.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_fcxp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_fcxp.c	2010-02-24 13:52:17.000000000 -0500
@@ -199,7 +199,7 @@ bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
 	if (fcxp)
 		list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
 
-	return (fcxp);
+	return fcxp;
 }
 
 static void
@@ -503,7 +503,7 @@ bfa_fcxp_alloc(void *caller, struct bfa_
 
 	fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
 	if (fcxp == NULL)
-		return (NULL);
+		return NULL;
 
 	bfa_trc(bfa, fcxp->fcxp_tag);
 
@@ -568,7 +568,7 @@ bfa_fcxp_alloc(void *caller, struct bfa_
 		}
 	}
 
-	return (fcxp);
+	return fcxp;
 }
 
 /**
@@ -709,7 +709,7 @@ bfa_status_t
 bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
 {
 	bfa_assert(0);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_intr.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_intr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,7 +59,7 @@ bfa_intx(struct bfa_s *bfa)
 	qintr = intr & __HFN_INT_RME_MASK;
 	bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
 
-	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue ++) {
+	for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
 		if (intr & (__HFN_INT_RME_Q0 << queue))
 			bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_intr_priv.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr_priv.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_intr_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_intr_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -26,9 +26,9 @@ void bfa_isr_unhandled(struct bfa_s *bfa
 void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
 
 
-#define bfa_reqq_pi(__bfa, __reqq)	(__bfa)->iocfc.req_cq_pi[__reqq]
+#define bfa_reqq_pi(__bfa, __reqq)	((__bfa)->iocfc.req_cq_pi[__reqq])
 #define bfa_reqq_ci(__bfa, __reqq)					\
-	*(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva)
+	(*(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva))
 
 #define bfa_reqq_full(__bfa, __reqq)				\
 	(((bfa_reqq_pi(__bfa, __reqq) + 1) &			\
@@ -50,14 +50,16 @@ void bfa_isr_bind(enum bfi_mclass mc, bf
 } while (0)
 
 #define bfa_rspq_pi(__bfa, __rspq)					\
-	*(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva)
+	(*(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva))
 
-#define bfa_rspq_ci(__bfa, __rspq)	(__bfa)->iocfc.rsp_cq_ci[__rspq]
+#define bfa_rspq_ci(__bfa, __rspq)	((__bfa)->iocfc.rsp_cq_ci[__rspq])
 #define bfa_rspq_elem(__bfa, __rspq, __ci)				\
-	&((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci]
+	(&((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci])
 
-#define CQ_INCR(__index, __size)					\
-			(__index)++; (__index) &= ((__size) - 1)
+#define CQ_INCR(__index, __size) do {					\
+			(__index)++;					\
+			(__index) &= ((__size) - 1);      \
+} while (0)
 
 /**
  * Queue element to wait for room in request queue. FIFO order is
@@ -94,7 +96,7 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *w
 	wqe->cbarg = cbarg;
 }
 
-#define bfa_reqq(__bfa, __reqq)	&(__bfa)->reqq_waitq[__reqq]
+#define bfa_reqq(__bfa, __reqq)	(&(__bfa)->reqq_waitq[__reqq])
 
 /**
  * static inline void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioc.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,7 +51,7 @@ BFA_TRC_FILE(HAL, IOC);
 	 (sizeof(struct bfa_trc_mod_s) -			\
 	  BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn)	(BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats)	(_ioc)->stats._stats ++
+#define bfa_ioc_stats(_ioc, _stats)	((_ioc)->stats._stats++)
 
 #define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
@@ -1953,8 +1953,8 @@ bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
 bfa_boolean_t
 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
 {
-	return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
-		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled));
+	return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
+		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
 }
 
 /**
@@ -1963,9 +1963,9 @@ bfa_ioc_is_disabled(struct bfa_ioc_s *io
 bfa_boolean_t
 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
 {
-	return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
+	return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
 		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
-		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch));
+		|| bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch);
 }
 
 #define bfa_ioc_state_disabled(__sm)		\
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_iocfc.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_iocfc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.c	2010-02-24 13:52:17.000000000 -0500
@@ -794,7 +794,7 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, s
 
 	if (iocfc->stats_busy) {
 		bfa_trc(bfa, iocfc->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	iocfc->stats_busy = BFA_TRUE;
@@ -804,7 +804,7 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, s
 
 	bfa_iocfc_stats_query(bfa);
 
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 bfa_status_t
@@ -814,7 +814,7 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa,
 
 	if (iocfc->stats_busy) {
 		bfa_trc(bfa, iocfc->stats_busy);
-		return (BFA_STATUS_DEVBUSY);
+		return BFA_STATUS_DEVBUSY;
 	}
 
 	iocfc->stats_busy = BFA_TRUE;
@@ -822,7 +822,7 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa,
 	iocfc->stats_cbarg = cbarg;
 
 	bfa_iocfc_stats_clear(bfa);
-	return (BFA_STATUS_OK);
+	return BFA_STATUS_OK;
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_iocfc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_iocfc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_iocfc.h	2010-02-24 13:52:17.000000000 -0500
@@ -107,13 +107,13 @@ struct bfa_iocfc_s {
 
 #define bfa_lpuid(__bfa)		bfa_ioc_portid(&(__bfa)->ioc)
 #define bfa_msix_init(__bfa, __nvecs)	\
-	(__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs)
+	((__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs))
 #define bfa_msix_install(__bfa)	\
-	(__bfa)->iocfc.hwif.hw_msix_install(__bfa)
+	((__bfa)->iocfc.hwif.hw_msix_install(__bfa))
 #define bfa_msix_uninstall(__bfa)	\
-	(__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)
+	((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
 #define bfa_isr_mode_set(__bfa, __msix)	\
-	(__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix)
+	((__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix))
 #define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)	\
 	(__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioc.h	2010-02-24 13:52:17.000000000 -0500
@@ -179,16 +179,16 @@ struct bfa_ioc_s {
 	struct bfa_ioc_mbox_mod_s mbox_mod;
 };
 
-#define bfa_ioc_pcifn(__ioc)		(__ioc)->pcidev.pci_func
-#define bfa_ioc_devid(__ioc)		(__ioc)->pcidev.device_id
-#define bfa_ioc_bar0(__ioc)		(__ioc)->pcidev.pci_bar_kva
+#define bfa_ioc_pcifn(__ioc)		((__ioc)->pcidev.pci_func)
+#define bfa_ioc_devid(__ioc)		((__ioc)->pcidev.device_id)
+#define bfa_ioc_bar0(__ioc)		((__ioc)->pcidev.pci_bar_kva)
 #define bfa_ioc_portid(__ioc)		((__ioc)->port_id)
 #define bfa_ioc_fetch_stats(__ioc, __stats) \
-		((__stats)->drv_stats) = (__ioc)->stats
+		(((__stats)->drv_stats) = (__ioc)->stats)
 #define bfa_ioc_clr_stats(__ioc)	\
 		bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
-#define bfa_ioc_maxfrsize(__ioc)	(__ioc)->attr->maxfrsize
-#define bfa_ioc_rx_bbcredit(__ioc)	(__ioc)->attr->rx_bbcredit
+#define bfa_ioc_maxfrsize(__ioc)	((__ioc)->attr->maxfrsize)
+#define bfa_ioc_rx_bbcredit(__ioc)	((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)	\
 	BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioim.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioim.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_ioim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_ioim.c	2010-02-24 13:52:17.000000000 -0500
@@ -105,13 +105,13 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *io
 				bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
 				list_del(&ioim->qe);
 				list_add_tail(&ioim->qe,
-					&ioim->fcpim->ioim_comp_q);
+						&ioim->fcpim->ioim_comp_q);
 				bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
 						__bfa_cb_ioim_pathtov, ioim);
 			} else {
 				list_del(&ioim->qe);
 				list_add_tail(&ioim->qe,
-					&ioim->itnim->pending_q);
+						&ioim->itnim->pending_q);
 			}
 			break;
 		}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_itnim.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_itnim.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_itnim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_itnim.c	2010-02-24 13:52:17.000000000 -0500
@@ -1029,7 +1029,7 @@ bfa_itnim_create(struct bfa_s *bfa, stru
 	bfa_stats(itnim, creates);
 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
 
-	return (itnim);
+	return itnim;
 }
 
 void
@@ -1061,7 +1061,7 @@ bfa_itnim_offline(struct bfa_itnim_s *it
 bfa_boolean_t
 bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
 {
-	return (
+	return
 		itnim->fcpim->path_tov && itnim->iotov_active &&
 		(bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
@@ -1069,7 +1069,7 @@ bfa_itnim_hold_io(struct bfa_itnim_s *it
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable))
-);
+	;
 }
 
 void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_log.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_log.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_log.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_log.c	2010-02-24 13:52:17.000000000 -0500
@@ -231,9 +231,9 @@ bfa_log_get_level(struct bfa_log_mod_s *
 		return BFA_LOG_INVALID;
 
 	if (log_mod)
-		return (log_mod->log_level[mod_id]);
+		return log_mod->log_level[mod_id];
 	else
-		return (bfa_log_info[mod_id].level);
+		return bfa_log_info[mod_id].level;
 }
 
 enum bfa_log_severity
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_port_priv.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_port_priv.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_port_priv.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_port_priv.h	2010-02-24 13:52:17.000000000 -0500
@@ -59,8 +59,8 @@ struct bfa_pport_s {
 	u8			*stats_kva;
 	u64		stats_pa;
 	union bfa_pport_stats_u *stats;	/*  pport stats */
-	u32		mypid : 24;
-	u32		rsvd_b : 8;
+	u32		mypid:24;
+	u32		rsvd_b:8;
 	struct bfa_timer_s 	timer;	/*  timer */
 	union bfa_pport_stats_u 	*stats_ret;
 					/*  driver stats location */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_rport.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_rport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_rport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_rport.c	2010-02-24 13:52:17.000000000 -0500
@@ -677,7 +677,7 @@ bfa_rport_alloc(struct bfa_rport_mod_s *
 	if (rport)
 		list_add_tail(&rport->qe, &mod->rp_active_q);
 
-	return (rport);
+	return rport;
 }
 
 static void
@@ -834,7 +834,7 @@ bfa_rport_create(struct bfa_s *bfa, void
 	rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
 
 	if (rp == NULL)
-		return (NULL);
+		return NULL;
 
 	rp->bfa = bfa;
 	rp->rport_drv = rport_drv;
@@ -843,7 +843,7 @@ bfa_rport_create(struct bfa_s *bfa, void
 	bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
 	bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
 
-	return (rp);
+	return rp;
 }
 
 void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_tskim.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_tskim.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_tskim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_tskim.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,13 +23,14 @@ BFA_TRC_FILE(HAL, TSKIM);
 /**
  * task management completion handling
  */
-#define bfa_tskim_qcomp(__tskim, __cbfn) do {			     \
-	bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim)); \
+#define bfa_tskim_qcomp(__tskim, __cbfn) do {			\
+	bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe,	\
+			 __cbfn, (__tskim));      \
 	bfa_tskim_notify_comp(__tskim);      \
 } while (0)
 
-#define bfa_tskim_notify_comp(__tskim) do {				     \
-	if ((__tskim)->notify)					     	     \
+#define bfa_tskim_notify_comp(__tskim) do {			 \
+	if ((__tskim)->notify)					 \
 		bfa_itnim_tskdone((__tskim)->itnim);      \
 } while (0)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_uf.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_uf.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/bfa_uf.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/bfa_uf.c	2010-02-24 13:52:17.000000000 -0500
@@ -185,7 +185,7 @@ bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
 	struct bfa_uf_s   *uf;
 
 	bfa_q_deq(&uf_mod->uf_free_q, &uf);
-	return (uf);
+	return uf;
 }
 
 static void
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fabric.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fabric.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fabric.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fabric.c	2010-02-24 13:52:17.000000000 -0500
@@ -36,12 +36,12 @@ BFA_TRC_FILE(FCS, FABRIC);
 #define BFA_FCS_FABRIC_RETRY_DELAY	(2000)	/* Milliseconds */
 #define BFA_FCS_FABRIC_CLEANUP_DELAY	(10000)	/* Milliseconds */
 
-#define bfa_fcs_fabric_set_opertype(__fabric) do {          \
-    if (bfa_pport_get_topology((__fabric)->fcs->bfa)    \
-				== BFA_PPORT_TOPOLOGY_P2P)   \
-	    (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;       \
-    else                                                    \
-	    (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT;      \
+#define bfa_fcs_fabric_set_opertype(__fabric) do {             \
+	if (bfa_pport_get_topology((__fabric)->fcs->bfa)       \
+				== BFA_PPORT_TOPOLOGY_P2P)     \
+		(__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;  \
+	else                                                   \
+		(__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
 } while (0)
 
 /*
@@ -887,7 +887,7 @@ bfa_fcs_fabric_modsusp(struct bfa_fcs_s
 bfa_boolean_t
 bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
 {
-	return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback));
+	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
 }
 
 enum bfa_pport_type
@@ -974,7 +974,7 @@ bfa_fcs_fabric_port_delete_comp(struct b
 int
 bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
 {
-	return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online));
+	return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
 }
 
 
@@ -1015,7 +1015,7 @@ bfa_fcs_fabric_vport_lookup(struct bfa_f
 u16
 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
 {
-	return (fabric->num_vports);
+	return fabric->num_vports;
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcbuild.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcbuild.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.c	2010-02-24 13:52:17.000000000 -0500
@@ -188,14 +188,14 @@ fc_els_rsp_parse(struct fchs_s *fchs, in
 	switch (els_cmd->els_code) {
 	case FC_ELS_LS_RJT:
 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
-			return (FC_PARSE_BUSY);
+			return FC_PARSE_BUSY;
 		else
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 	case FC_ELS_ACC:
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 static void
@@ -228,7 +228,7 @@ fc_plogi_x_build(struct fchs_s *fchs, vo
 	bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
 	bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -267,7 +267,7 @@ fc_flogi_build(struct fchs_s *fchs, stru
 	flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
 	vvl_info[0]	= bfa_os_htonl(FLOGI_VVL_BRCD);
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -287,7 +287,7 @@ fc_flogi_acc_build(struct fchs_s *fchs,
 
 	flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -306,7 +306,7 @@ fc_fdisc_build(struct fchs_s *fchs, stru
 	flogi->port_name = port_name;
 	flogi->node_name = node_name;
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -338,26 +338,26 @@ fc_plogi_rsp_parse(struct fchs_s *fchs,
 	case FC_ELS_LS_RJT:
 		ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
-			return (FC_PARSE_BUSY);
+			return FC_PARSE_BUSY;
 		else
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 	case FC_ELS_ACC:
 		plogi = (struct fc_logi_s *) (fchs + 1);
 		if (len < sizeof(struct fc_logi_s))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (!wwn_is_equal(plogi->port_name, port_name))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (!plogi->class3.class_valid)
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
 		if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
-			return (FC_PARSE_FAILURE);
+			return FC_PARSE_FAILURE;
 
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 	default:
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 	}
 }
 
@@ -372,7 +372,7 @@ fc_plogi_parse(struct fchs_s *fchs)
 	if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ)
 	    || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ)
 	    || (plogi->class3.rxsz == 0))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	return FC_PARSE_OK;
 }
@@ -393,7 +393,7 @@ fc_prli_build(struct fchs_s *fchs, void
 	prli->parampage.servparams.task_retry_id = 0;
 	prli->parampage.servparams.confirm       = 1;
 
-	return (sizeof(struct fc_prli_s));
+	return sizeof(struct fc_prli_s);
 }
 
 u16
@@ -414,41 +414,41 @@ fc_prli_acc_build(struct fchs_s *fchs, v
 
 	prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
 
-	return (sizeof(struct fc_prli_s));
+	return sizeof(struct fc_prli_s);
 }
 
 enum fc_parse_status
 fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
 {
 	if (len < sizeof(struct fc_prli_s))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (prli->command != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
 	    && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (prli->parampage.servparams.target != 1)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
 fc_prli_parse(struct fc_prli_s *prli)
 {
 	if (prli->parampage.type != FC_TYPE_FCP)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!prli->parampage.imagepair)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!prli->parampage.servparams.initiator)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 u16
@@ -462,7 +462,7 @@ fc_logo_build(struct fchs_s *fchs, struc
 	logo->nport_id = (s_id);
 	logo->orig_port_name = port_name;
 
-	return (sizeof(struct fc_logo_s));
+	return sizeof(struct fc_logo_s);
 }
 
 static          u16
@@ -484,7 +484,7 @@ fc_adisc_x_build(struct fchs_s *fchs, st
 	adisc->orig_node_name = node_name;
 	adisc->nport_id = (s_id);
 
-	return (sizeof(struct fc_adisc_s));
+	return sizeof(struct fc_adisc_s);
 }
 
 u16
@@ -511,15 +511,15 @@ fc_adisc_rsp_parse(struct fc_adisc_s *ad
 {
 
 	if (len < sizeof(struct fc_adisc_s))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(adisc->orig_port_name, port_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
@@ -529,14 +529,14 @@ fc_adisc_parse(struct fchs_s *fchs, void
 	struct fc_adisc_s     *adisc = (struct fc_adisc_s *) pld;
 
 	if (adisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if ((adisc->nport_id == (host_dap))
 	    && wwn_is_equal(adisc->orig_port_name, port_name)
 	    && wwn_is_equal(adisc->orig_node_name, node_name))
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 
-	return (FC_PARSE_FAILURE);
+	return FC_PARSE_FAILURE;
 }
 
 enum fc_parse_status
@@ -550,13 +550,13 @@ fc_pdisc_parse(struct fchs_s *fchs, wwn_
 	if ((bfa_os_ntohs(pdisc->class3.rxsz) <
 		 (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
 	    || (pdisc->class3.rxsz == 0))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(pdisc->port_name, port_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	if (!wwn_is_equal(pdisc->node_name, node_name))
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	return FC_PARSE_OK;
 }
@@ -570,7 +570,7 @@ fc_abts_build(struct fchs_s *fchs, u32 d
 	fchs->s_id = (s_id);
 	fchs->ox_id = bfa_os_htons(ox_id);
 
-	return (sizeof(struct fchs_s));
+	return sizeof(struct fchs_s);
 }
 
 enum fc_parse_status
@@ -578,9 +578,9 @@ fc_abts_rsp_parse(struct fchs_s *fchs, i
 {
 	if ((fchs->cat_info == FC_CAT_BA_ACC)
 	    || (fchs->cat_info == FC_CAT_BA_RJT))
-		return (FC_PARSE_OK);
+		return FC_PARSE_OK;
 
-	return (FC_PARSE_FAILURE);
+	return FC_PARSE_FAILURE;
 }
 
 u16
@@ -597,7 +597,7 @@ fc_rrq_build(struct fchs_s *fchs, struct
 	rrq->ox_id = bfa_os_htons(rrq_oxid);
 	rrq->rx_id = FC_RXID_ANY;
 
-	return (sizeof(struct fc_rrq_s));
+	return sizeof(struct fc_rrq_s);
 }
 
 u16
@@ -611,7 +611,7 @@ fc_logo_acc_build(struct fchs_s *fchs, v
 	memset(acc, 0, sizeof(struct fc_els_cmd_s));
 	acc->els_code = FC_ELS_ACC;
 
-	return (sizeof(struct fc_els_cmd_s));
+	return sizeof(struct fc_els_cmd_s);
 }
 
 u16
@@ -627,7 +627,7 @@ fc_ls_rjt_build(struct fchs_s *fchs, str
 	ls_rjt->reason_code_expl = reason_code_expl;
 	ls_rjt->vendor_unique = 0x00;
 
-	return (sizeof(struct fc_ls_rjt_s));
+	return sizeof(struct fc_ls_rjt_s);
 }
 
 u16
@@ -643,7 +643,7 @@ fc_ba_acc_build(struct fchs_s *fchs, str
 	ba_acc->ox_id = fchs->ox_id;
 	ba_acc->rx_id = fchs->rx_id;
 
-	return (sizeof(struct fc_ba_acc_s));
+	return sizeof(struct fc_ba_acc_s);
 }
 
 u16
@@ -654,7 +654,7 @@ fc_ls_acc_build(struct fchs_s *fchs, str
 	memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
 	els_cmd->els_code = FC_ELS_ACC;
 
-	return (sizeof(struct fc_els_cmd_s));
+	return sizeof(struct fc_els_cmd_s);
 }
 
 int
@@ -696,7 +696,7 @@ fc_tprlo_acc_build(struct fchs_s *fchs,
 		tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
 		tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
 	}
-	return (bfa_os_ntohs(tprlo_acc->payload_len));
+	return bfa_os_ntohs(tprlo_acc->payload_len);
 }
 
 u16
@@ -721,7 +721,7 @@ fc_prlo_acc_build(struct fchs_s *fchs, s
 		prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
 	}
 
-	return (bfa_os_ntohs(prlo_acc->payload_len));
+	return bfa_os_ntohs(prlo_acc->payload_len);
 }
 
 u16
@@ -735,7 +735,7 @@ fc_rnid_build(struct fchs_s *fchs, struc
 	rnid->els_cmd.els_code = FC_ELS_RNID;
 	rnid->node_id_data_format = data_format;
 
-	return (sizeof(struct fc_rnid_cmd_s));
+	return sizeof(struct fc_rnid_cmd_s);
 }
 
 u16
@@ -759,10 +759,10 @@ fc_rnid_acc_build(struct fchs_s *fchs, s
 		rnid_acc->specific_id_data_length =
 			sizeof(struct fc_rnid_general_topology_data_s);
 		bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data);
-		return (sizeof(struct fc_rnid_acc_s));
+		return sizeof(struct fc_rnid_acc_s);
 	} else {
-		return (sizeof(struct fc_rnid_acc_s) -
-			sizeof(struct fc_rnid_general_topology_data_s));
+		return sizeof(struct fc_rnid_acc_s) -
+			sizeof(struct fc_rnid_general_topology_data_s);
 	}
 
 }
@@ -776,7 +776,7 @@ fc_rpsc_build(struct fchs_s *fchs, struc
 	memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
 
 	rpsc->els_cmd.els_code = FC_ELS_RPSC;
-	return (sizeof(struct fc_rpsc_cmd_s));
+	return sizeof(struct fc_rpsc_cmd_s);
 }
 
 u16
@@ -797,8 +797,8 @@ fc_rpsc2_build(struct fchs_s *fchs, stru
 	for (i = 0; i < npids; i++)
 		rpsc2->pid_list[i].pid = pid_list[i];
 
-	return (sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
-			(sizeof(u32))));
+	return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
+			(sizeof(u32)));
 }
 
 u16
@@ -819,7 +819,7 @@ fc_rpsc_acc_build(struct fchs_s *fchs, s
 	rpsc_acc->speed_info[0].port_op_speed =
 		bfa_os_htons(oper_speed->port_op_speed);
 
-	return (sizeof(struct fc_rpsc_acc_s));
+	return sizeof(struct fc_rpsc_acc_s);
 
 }
 
@@ -856,7 +856,7 @@ fc_pdisc_build(struct fchs_s *fchs, u32
 	pdisc->port_name = port_name;
 	pdisc->node_name = node_name;
 
-	return (sizeof(struct fc_logi_s));
+	return sizeof(struct fc_logi_s);
 }
 
 u16
@@ -865,21 +865,21 @@ fc_pdisc_rsp_parse(struct fchs_s *fchs,
 	struct fc_logi_s     *pdisc = (struct fc_logi_s *) (fchs + 1);
 
 	if (len < sizeof(struct fc_logi_s))
-		return (FC_PARSE_LEN_INVAL);
+		return FC_PARSE_LEN_INVAL;
 
 	if (pdisc->els_cmd.els_code != FC_ELS_ACC)
-		return (FC_PARSE_ACC_INVAL);
+		return FC_PARSE_ACC_INVAL;
 
 	if (!wwn_is_equal(pdisc->port_name, port_name))
-		return (FC_PARSE_PWWN_NOT_EQUAL);
+		return FC_PARSE_PWWN_NOT_EQUAL;
 
 	if (!pdisc->class3.class_valid)
-		return (FC_PARSE_NWWN_NOT_EQUAL);
+		return FC_PARSE_NWWN_NOT_EQUAL;
 
 	if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
-		return (FC_PARSE_RXSZ_INVAL);
+		return FC_PARSE_RXSZ_INVAL;
 
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 u16
@@ -903,7 +903,7 @@ fc_prlo_build(struct fchs_s *fchs, u32 d
 		prlo->prlo_params[page].resp_process_assc = 0;
 	}
 
-	return (bfa_os_ntohs(prlo->payload_len));
+	return bfa_os_ntohs(prlo->payload_len);
 }
 
 u16
@@ -916,7 +916,7 @@ fc_prlo_rsp_parse(struct fchs_s *fchs, i
 	len = len;
 
 	if (prlo->command != FC_ELS_ACC)
-		return (FC_PARSE_FAILURE);
+		return FC_PARSE_FAILURE;
 
 	num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16;
 
@@ -936,7 +936,7 @@ fc_prlo_rsp_parse(struct fchs_s *fchs, i
 		if (prlo->prlo_acc_params[page].resp_process_assc != 0)
 			return FC_PARSE_FAILURE;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 
 }
 
@@ -968,7 +968,7 @@ fc_tprlo_build(struct fchs_s *fchs, u32
 		}
 	}
 
-	return (bfa_os_ntohs(tprlo->payload_len));
+	return bfa_os_ntohs(tprlo->payload_len);
 }
 
 u16
@@ -981,23 +981,23 @@ fc_tprlo_rsp_parse(struct fchs_s *fchs,
 	len = len;
 
 	if (tprlo->command != FC_ELS_ACC)
-		return (FC_PARSE_ACC_INVAL);
+		return FC_PARSE_ACC_INVAL;
 
 	num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
 
 	for (page = 0; page < num_pages; page++) {
 		if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
-			return (FC_PARSE_NOT_FCP);
+			return FC_PARSE_NOT_FCP;
 		if (tprlo->tprlo_acc_params[page].opa_valid != 0)
-			return (FC_PARSE_OPAFLAG_INVAL);
+			return FC_PARSE_OPAFLAG_INVAL;
 		if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
-			return (FC_PARSE_RPAFLAG_INVAL);
+			return FC_PARSE_RPAFLAG_INVAL;
 		if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
-			return (FC_PARSE_OPA_INVAL);
+			return FC_PARSE_OPA_INVAL;
 		if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
-			return (FC_PARSE_RPA_INVAL);
+			return FC_PARSE_RPA_INVAL;
 	}
-	return (FC_PARSE_OK);
+	return FC_PARSE_OK;
 }
 
 enum fc_parse_status
@@ -1024,7 +1024,7 @@ fc_ba_rjt_build(struct fchs_s *fchs, u32
 	fchs->cat_info = FC_CAT_BA_RJT;
 	ba_rjt->reason_code = reason_code;
 	ba_rjt->reason_expl = reason_expl;
-	return (sizeof(struct fc_ba_rjt_s));
+	return sizeof(struct fc_ba_rjt_s);
 }
 
 static void
@@ -1073,7 +1073,7 @@ fc_gidpn_build(struct fchs_s *fchs, void
 
 	bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
 	gidpn->port_name = port_name;
-	return (sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1090,7 +1090,7 @@ fc_gpnid_build(struct fchs_s *fchs, void
 
 	bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
 	gpnid->dap = port_id;
-	return (sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s));
+	return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1107,7 +1107,7 @@ fc_gnnid_build(struct fchs_s *fchs, void
 
 	bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
 	gnnid->dap = port_id;
-	return (sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s));
+	return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1137,7 +1137,7 @@ fc_scr_build(struct fchs_s *fchs, struct
 	if (set_br_reg)
 		scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
 
-	return (sizeof(struct fc_scr_s));
+	return sizeof(struct fc_scr_s);
 }
 
 u16
@@ -1157,7 +1157,7 @@ fc_rscn_build(struct fchs_s *fchs, struc
 	rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
 	rscn->event[0].portid = s_id;
 
-	return (sizeof(struct fc_rscn_pl_s));
+	return sizeof(struct fc_rscn_pl_s);
 }
 
 u16
@@ -1188,7 +1188,7 @@ fc_rftid_build(struct fchs_s *fchs, void
 		rftid->fc4_type[index] |= bfa_os_htonl(type_value);
 	}
 
-	return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1210,7 +1210,7 @@ fc_rftid_build_sol(struct fchs_s *fchs,
 	bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
 			(bitmap_size < 32 ? bitmap_size : 32));
 
-	return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1231,7 +1231,7 @@ fc_rffid_build(struct fchs_s *fchs, void
 	rffid->fc4ftr_bits  = fc4_ftrs;
 	rffid->fc4_type		= fc4_type;
 
-	return (sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1253,7 +1253,7 @@ fc_rspnid_build(struct fchs_s *fchs, voi
 	rspnid->spn_len = (u8) strlen((char *)name);
 	strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
 
-	return (sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1275,7 +1275,7 @@ fc_gid_ft_build(struct fchs_s *fchs, voi
 	gidft->domain_id = 0;
 	gidft->area_id = 0;
 
-	return (sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1294,7 +1294,7 @@ fc_rpnid_build(struct fchs_s *fchs, void
 	rpnid->port_id = port_id;
 	rpnid->port_name = port_name;
 
-	return (sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1313,7 +1313,7 @@ fc_rnnid_build(struct fchs_s *fchs, void
 	rnnid->port_id = port_id;
 	rnnid->node_name = node_name;
 
-	return (sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1332,7 +1332,7 @@ fc_rcsid_build(struct fchs_s *fchs, void
 	rcsid->port_id = port_id;
 	rcsid->cos = cos;
 
-	return (sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1351,7 +1351,7 @@ fc_rptid_build(struct fchs_s *fchs, void
 	rptid->port_id = port_id;
 	rptid->port_type = port_type;
 
-	return (sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s));
+	return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
 }
 
 u16
@@ -1368,7 +1368,7 @@ fc_ganxt_build(struct fchs_s *fchs, void
 	bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
 	ganxt->port_id = port_id;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s));
+	return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
 }
 
 /*
@@ -1385,7 +1385,7 @@ fc_fdmi_reqhdr_build(struct fchs_s *fchs
 	fc_gs_fchdr_build(fchs, d_id, s_id, 0);
 	fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
 
-	return (sizeof(struct ct_hdr_s));
+	return sizeof(struct ct_hdr_s);
 }
 
 /*
@@ -1425,7 +1425,7 @@ fc_gmal_req_build(struct fchs_s *fchs, v
 	bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t));
 	gmal->wwn = wwn;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t));
+	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
 }
 
 /*
@@ -1445,5 +1445,5 @@ fc_gfn_req_build(struct fchs_s *fchs, vo
 	bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t));
 	gfn->wwn = wwn;
 
-	return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t));
+	return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcbuild.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcbuild.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcbuild.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,8 +32,8 @@
  * Utility Macros/functions
  */
 
-#define fcif_sof_set(_ifhdr, _sof)	(_ifhdr)->sof = FC_ ## _sof
-#define fcif_eof_set(_ifhdr, _eof)	(_ifhdr)->eof = FC_ ## _eof
+#define fcif_sof_set(_ifhdr, _sof)	((_ifhdr)->sof = FC_ ## _sof)
+#define fcif_eof_set(_ifhdr, _eof)	((_ifhdr)->eof = FC_ ## _eof)
 
 #define wwn_is_equal(_wwn1, _wwn2)		\
 	(memcmp(&(_wwn1), &(_wwn2), sizeof(wwn_t)) == 0)
@@ -49,7 +49,7 @@
 static inline   u32
 fc_get_ctresp_pyld_len(u32 resp_len)
 {
-	return (resp_len - sizeof(struct ct_hdr_s));
+	return resp_len - sizeof(struct ct_hdr_s);
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcpim.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcpim.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcpim.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcpim.c	2010-02-24 13:52:17.000000000 -0500
@@ -286,11 +286,10 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_i
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
 		bfa_fcb_itnim_offline(itnim->itnim_drv);
 		bfa_itnim_offline(itnim->bfa_itnim);
-		if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE) {
+		if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE)
 			bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
-		} else {
+		else
 			bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
-		}
 		break;
 
 	case BFA_FCS_ITNIM_SM_DELETE:
@@ -732,7 +731,7 @@ bfa_fcs_itnim_lookup(struct bfa_fcs_port
 		return NULL;
 
 	bfa_assert(rport->itnim != NULL);
-	return (rport->itnim);
+	return rport->itnim;
 }
 
 bfa_status_t
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcs.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fcs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fcs.h	2010-02-24 13:52:17.000000000 -0500
@@ -23,7 +23,7 @@
 #ifndef __FCS_H__
 #define __FCS_H__
 
-#define __fcs_min_cfg(__fcs)       (__fcs)->min_cfg
+#define __fcs_min_cfg(__fcs)       ((__fcs)->min_cfg)
 
 void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fdmi.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fdmi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/fdmi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/fdmi.c	2010-02-24 13:52:17.000000000 -0500
@@ -72,9 +72,9 @@ static u16 bfa_fcs_port_fdmi_build_rpa_p
 			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
 static u16 bfa_fcs_port_fdmi_build_portattr_block(
 			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
-void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
+static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
-void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
+static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			struct bfa_fcs_fdmi_port_attr_s *port_attr);
 /**
  *  fcs_fdmi_sm FCS FDMI state machine
@@ -1091,7 +1091,7 @@ bfa_fcs_port_fdmi_timeout(void *arg)
 	bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
 }
 
-void
+static void
 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
 {
@@ -1145,7 +1145,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_
 
 }
 
-void
+static void
 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
 			  struct bfa_fcs_fdmi_port_attr_s *port_attr)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/aen/bfa_aen.h	2010-02-24 13:52:17.000000000 -0500
@@ -54,7 +54,7 @@ bfa_aen_get_max_cfg_entry(void)
 static inline s32
 bfa_aen_get_meminfo(void)
 {
-	return (sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry());
+	return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
 }
 
 static inline s32
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfa.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfa.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa.h	2010-02-24 13:52:17.000000000 -0500
@@ -76,11 +76,11 @@ struct bfa_meminfo_s {
 	struct bfa_mem_elem_s meminfo[BFA_MEM_TYPE_MAX];
 };
 #define bfa_meminfo_kva(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp
+	((_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp)
 #define bfa_meminfo_dma_virt(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp
+	((_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp)
 #define bfa_meminfo_dma_phys(_m)	\
-	(_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp
+	((_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp)
 
 /**
  * Generic Scatter Gather Element used by driver
@@ -100,7 +100,7 @@ struct bfa_sge_s {
 /*
  * bfa stats interfaces
  */
-#define bfa_stats(_mod, _stats)	(_mod)->stats._stats ++
+#define bfa_stats(_mod, _stats)	((_mod)->stats._stats++)
 
 #define bfa_ioc_get_stats(__bfa, __ioc_stats)	\
 	bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
@@ -136,7 +136,7 @@ void bfa_isr_enable(struct bfa_s *bfa);
 void bfa_isr_disable(struct bfa_s *bfa);
 void bfa_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
 			u32 *num_vecs, u32 *max_vec_bit);
-#define bfa_msix(__bfa, __vec) (__bfa)->msix.handler[__vec](__bfa, __vec)
+#define bfa_msix(__bfa, __vec) ((__bfa)->msix.handler[__vec](__bfa, __vec))
 
 void bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q);
 void bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfa_svc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_svc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfa_svc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfa_svc.h	2010-02-24 13:52:17.000000000 -0500
@@ -34,10 +34,10 @@ struct bfa_fcxp_s;
  */
 struct bfa_rport_info_s {
 	u16        max_frmsz;	/*  max rcv pdu size               */
-	u32        pid : 24,	/*  remote port ID                 */
-			lp_tag : 8;
-	u32        local_pid : 24,	/*  local port ID		    */
-			cisc : 8;	/*  CIRO supported		    */
+	u32        pid:24,		/*  remote port ID                 */
+			lp_tag:8;
+	u32        local_pid:24,	/*  local port ID		    */
+			cisc:8;		/*  CIRO supported		    */
 	u8         fc_class;	/*  supported FC classes. enum fc_cos */
 	u8         vf_en;		/*  virtual fabric enable          */
 	u16        vf_id;		/*  virtual fabric ID              */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi.h	2010-02-24 13:52:17.000000000 -0500
@@ -93,13 +93,13 @@ union bfi_addr_u {
  */
 struct bfi_sge_s {
 #ifdef __BIGENDIAN
-	u32        flags	: 2,
-			rsvd	: 2,
-			sg_len	: 28;
+	u32        flags:2,
+			rsvd:2,
+			sg_len:28;
 #else
-	u32        sg_len	: 28,
-			rsvd	: 2,
-			flags	: 2;
+	u32        sg_len:28,
+			rsvd:2,
+			flags:2;
 #endif
 	union bfi_addr_u sga;
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_ioc.h	2010-02-24 13:52:17.000000000 -0500
@@ -142,7 +142,7 @@ enum {
 	BFI_ADAPTER_UNSUPP    = 0x400000,	/*  unknown adapter type  */
 };
 
-#define BFI_ADAPTER_GETP(__prop,__adap_prop)          		\
+#define BFI_ADAPTER_GETP(__prop, __adap_prop)          		\
     (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >>         \
      BFI_ADAPTER_ ## __prop ## _SH)
 #define BFI_ADAPTER_SETP(__prop, __val)         		\
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_lps.h	2010-02-24 13:52:17.000000000 -0500
@@ -55,8 +55,8 @@ struct bfi_lps_login_rsp_s {
 	u16	bb_credit;
 	u8		f_port;
 	u8		npiv_en;
-	u32	lp_pid : 24;
-	u32	auth_req : 8;
+	u32	lp_pid:24;
+	u32	auth_req:8;
 	mac_t		lp_mac;
 	mac_t		fcf_mac;
 	u8		ext_status;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_rport.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_rport.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/bfi/bfi_rport.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/bfi/bfi_rport.h	2010-02-24 13:52:17.000000000 -0500
@@ -38,10 +38,10 @@ struct bfi_rport_create_req_s {
 	struct bfi_mhdr_s  mh;		/*  common msg header		*/
 	u16        bfa_handle;	/*  host rport handle		*/
 	u16        max_frmsz;	/*  max rcv pdu size		*/
-	u32        pid       : 24,	/*  remote port ID		*/
-			lp_tag    : 8;	/*  local port tag		*/
-	u32        local_pid : 24,	/*  local port ID		*/
-			cisc      : 8;
+	u32        pid:24,		/*  remote port ID		*/
+			lp_tag:8;	/*  local port tag		*/
+	u32        local_pid:24,	/*  local port ID		*/
+			cisc:8;
 	u8         fc_class;	/*  supported FC classes	*/
 	u8         vf_en;		/*  virtual fabric enable	*/
 	u16        vf_id;		/*  virtual fabric ID		*/
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_checksum.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_checksum.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_checksum.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_checksum.h	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@ bfa_checksum_u32(u32 *buf, int sz)
 	for (i = 0; i < m; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 
 static inline u16
@@ -43,7 +43,7 @@ bfa_checksum_u16(u16 *buf, int sz)
 	for (i = 0; i < m; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 
 static inline u8
@@ -55,6 +55,6 @@ bfa_checksum_u8(u8 *buf, int sz)
 	for (i = 0; i < sz; i++)
 		sum ^= buf[i];
 
-	return (sum);
+	return sum;
 }
 #endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_sm.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,8 +24,8 @@
 
 typedef void (*bfa_sm_t)(void *sm, int event);
 
-#define bfa_sm_set_state(_sm, _state)	(_sm)->sm = (bfa_sm_t)(_state)
-#define bfa_sm_send_event(_sm, _event)	(_sm)->sm((_sm), (_event))
+#define bfa_sm_set_state(_sm, _state)	((_sm)->sm = (bfa_sm_t)(_state))
+#define bfa_sm_send_event(_sm, _event)	((_sm)->sm((_sm), (_event)))
 #define bfa_sm_get_state(_sm)		((_sm)->sm)
 #define bfa_sm_cmp_state(_sm, _state)	((_sm)->sm == (bfa_sm_t)(_state))
 
@@ -62,7 +62,7 @@ typedef void (*bfa_fsm_t)(void *fsm, int
 } while (0)
 
 #define bfa_fsm_send_event(_fsm, _event)	\
-	(_fsm)->fsm((_fsm), (_event))
+	((_fsm)->fsm((_fsm), (_event)))
 #define bfa_fsm_cmp_state(_fsm, _state)		\
 	((_fsm)->fsm == (bfa_fsm_t)(_state))
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_trc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_trc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/cs/bfa_trc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/cs/bfa_trc.h	2010-02-24 13:52:17.000000000 -0500
@@ -24,7 +24,7 @@
 #endif
 
 #ifndef BFA_TRC_TS
-#define BFA_TRC_TS(_trcm)	((_trcm)->ticks ++)
+#define BFA_TRC_TS(_trcm)	((_trcm)->ticks++)
 #endif
 
 struct bfa_trc_s {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_pport.h	2010-02-24 13:52:17.000000000 -0500
@@ -61,7 +61,7 @@ enum bfa_pport_speed {
  * 		Port operational type (in sync with SNIA port type).
  */
 enum bfa_pport_type {
-	BFA_PPORT_TYPE_UNKNOWN = 1,	/*  port type is unkown */
+	BFA_PPORT_TYPE_UNKNOWN = 1,	/*  port type is unknown */
 	BFA_PPORT_TYPE_TRUNKED = 2,	/*  Trunked mode */
 	BFA_PPORT_TYPE_NPORT   = 5,	/*  P2P with switched fabric */
 	BFA_PPORT_TYPE_NLPORT  = 6,	/*  public loop */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h	2010-02-24 13:52:17.000000000 -0500
@@ -25,7 +25,7 @@
  * Temperature sensor status values
  */
 enum bfa_tsensor_status {
-	BFA_TSENSOR_STATUS_UNKNOWN   = 1,   /*  unkown status */
+	BFA_TSENSOR_STATUS_UNKNOWN   = 1,   /*  unknown status */
 	BFA_TSENSOR_STATUS_FAULTY    = 2,   /*  sensor is faulty */
 	BFA_TSENSOR_STATUS_BELOW_MIN = 3,   /*  temperature below mininum */
 	BFA_TSENSOR_STATUS_NOMINAL   = 4,   /*  normal temperature */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h	2010-02-24 13:52:17.000000000 -0500
@@ -75,7 +75,7 @@ struct bfa_fcs_fabric_s {
 							    */
 };
 
-#define bfa_fcs_fabric_npiv_capable(__f)    (__f)->is_npiv
+#define bfa_fcs_fabric_npiv_capable(__f)    ((__f)->is_npiv)
 #define bfa_fcs_fabric_is_switched(__f)			\
 	((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h	2010-02-24 13:52:17.000000000 -0500
@@ -125,12 +125,12 @@ union bfa_fcs_port_topo_u {
 struct bfa_fcs_port_s {
 	struct list_head         qe;	/*  used by port/vport */
 	bfa_sm_t               sm;	/*  state machine */
-	struct bfa_fcs_fabric_s *fabric;	/*  parent fabric */
-	struct bfa_port_cfg_s  port_cfg;	/*  port configuration */
+	struct bfa_fcs_fabric_s *fabric;/*  parent fabric */
+	struct bfa_port_cfg_s  port_cfg;/*  port configuration */
 	struct bfa_timer_s link_timer;	/*  timer for link offline */
-	u32        pid : 24;	/*  FC address */
-	u8         lp_tag;		/*  lport tag */
-	u16        num_rports;	/*  Num of r-ports */
+	u32 pid:24;	/*  FC address */
+	u8  lp_tag;	/*  lport tag */
+	u16 num_rports;	/*  Num of r-ports */
 	struct list_head rport_q;	/*  queue of discovered r-ports */
 	struct bfa_fcs_s *fcs;	/*  FCS instance */
 	union bfa_fcs_port_topo_u port_topo;	/*  fabric/loop/n2n details */
@@ -188,13 +188,14 @@ bfa_fcs_port_get_drvport(struct bfa_fcs_
 }
 
 
-#define bfa_fcs_port_get_opertype(_lport)	(_lport)->fabric->oper_type
+#define bfa_fcs_port_get_opertype(_lport)	((_lport)->fabric->oper_type)
 
 
-#define bfa_fcs_port_get_fabric_name(_lport)	(_lport)->fabric->fabric_name
+#define bfa_fcs_port_get_fabric_name(_lport)	((_lport)->fabric->fabric_name)
 
 
-#define bfa_fcs_port_get_fabric_ipaddr(_lport)	(_lport)->fabric->fabric_ip_addr
+#define bfa_fcs_port_get_fabric_ipaddr(_lport) \
+		((_lport)->fabric->fabric_ip_addr)
 
 /**
  * bfa fcs port public functions
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/protocol/ct.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/ct.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/protocol/ct.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/ct.h	2010-02-24 13:52:17.000000000 -0500
@@ -82,7 +82,7 @@ enum {
 };
 
 /*
- * defintions for CT reason code
+ * definitions for CT reason code
  */
 enum {
 	CT_RSN_INV_CMD		= 0x01,
@@ -129,7 +129,7 @@ enum {
 };
 
 /*
- * defintions for the explanation code for all servers
+ * definitions for the explanation code for all servers
  */
 enum {
 	CT_EXP_AUTH_EXCEPTION			= 0xF1,
@@ -193,11 +193,11 @@ struct fcgs_rftid_req_s {
 #define FC_GS_FCP_FC4_FEATURE_TARGET	 0x01
 
 struct fcgs_rffid_req_s{
-    u32    rsvd          :8;
-    u32    dap        	  :24;		/* port identifier	*/
-    u32    rsvd1         :16;
-    u32    fc4ftr_bits   :8;		/* fc4 feature bits	*/
-    u32    fc4_type      :8;		/* corresponding FC4 Type */
+    u32    rsvd:8;
+    u32    dap:24;		/* port identifier	*/
+    u32    rsvd1:16;
+    u32    fc4ftr_bits:8;	/* fc4 feature bits	*/
+    u32    fc4_type:8;	/* corresponding FC4 Type */
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/protocol/fc.h linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/fc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/include/protocol/fc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/include/protocol/fc.h	2010-02-24 13:52:17.000000000 -0500
@@ -486,14 +486,14 @@ struct fc_rsi_s {
  * see FC-PH-X table 113 & 115 for explanation also FCP table 8
  */
 struct fc_prli_params_s{
-	u32        reserved: 16;
+	u32        reserved:16;
 #ifdef __BIGENDIAN
-	u32        reserved1: 5;
-	u32        rec_support : 1;
-	u32        task_retry_id : 1;
-	u32        retry : 1;
+	u32        reserved1:5;
+	u32        rec_support:1;
+	u32        task_retry_id:1;
+	u32        retry:1;
 
-	u32        confirm : 1;
+	u32        confirm:1;
 	u32        doverlay:1;
 	u32        initiator:1;
 	u32        target:1;
@@ -502,10 +502,10 @@ struct fc_prli_params_s{
 	u32        rxrdisab:1;
 	u32        wxrdisab:1;
 #else
-	u32        retry : 1;
-	u32        task_retry_id : 1;
-	u32        rec_support : 1;
-	u32        reserved1: 5;
+	u32        retry:1;
+	u32        task_retry_id:1;
+	u32        rec_support:1;
+	u32        reserved1:5;
 
 	u32        wxrdisab:1;
 	u32        rxrdisab:1;
@@ -514,7 +514,7 @@ struct fc_prli_params_s{
 	u32        target:1;
 	u32        initiator:1;
 	u32        doverlay:1;
-	u32        confirm : 1;
+	u32        confirm:1;
 #endif
 };
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/loop.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/loop.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/loop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/loop.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,49 +58,16 @@ static const u8   port_loop_alpa_map[] =
 /*
  * Local Functions
  */
-bfa_status_t    bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
-					     u8 alpa);
-
-void            bfa_fcs_port_loop_plogi_response(void *fcsarg,
-						 struct bfa_fcxp_s *fcxp,
-						 void *cbarg,
-						 bfa_status_t req_status,
-						 u32 rsp_len,
-						 u32 resid_len,
-						 struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port,
-					     u8 alpa);
-
-void            bfa_fcs_port_loop_adisc_response(void *fcsarg,
-						 struct bfa_fcxp_s *fcxp,
-						 void *cbarg,
-						 bfa_status_t req_status,
-						 u32 rsp_len,
-						 u32 resid_len,
-						 struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port,
-						 u8 alpa);
-
-void            bfa_fcs_port_loop_plogi_acc_response(void *fcsarg,
-						     struct bfa_fcxp_s *fcxp,
-						     void *cbarg,
-						     bfa_status_t req_status,
-						     u32 rsp_len,
-						     u32 resid_len,
-						     struct fchs_s *rsp_fchs);
-
-bfa_status_t    bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port,
-						 u8 alpa);
+static bfa_status_t bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
+					u8 alpa);
 
-void            bfa_fcs_port_loop_adisc_acc_response(void *fcsarg,
-						     struct bfa_fcxp_s *fcxp,
-						     void *cbarg,
-						     bfa_status_t req_status,
-						     u32 rsp_len,
-						     u32 resid_len,
-						     struct fchs_s *rsp_fchs);
+static void bfa_fcs_port_loop_plogi_response(void *fcsarg,
+					struct bfa_fcxp_s *fcxp,
+					void *cbarg,
+					bfa_status_t req_status,
+					u32 rsp_len,
+					u32 resid_len,
+					struct fchs_s *rsp_fchs);
 /**
  *   Called by port to initializar in provate LOOP topology.
  */
@@ -179,7 +146,7 @@ bfa_fcs_port_loop_lip(struct bfa_fcs_por
 /**
  * Local Functions.
  */
-bfa_status_t
+static bfa_status_t
 bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
 {
 	struct fchs_s          fchs;
@@ -208,7 +175,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_
 /**
  *   Called by fcxp to notify the Plogi response
  */
-void
+static void
 bfa_fcs_port_loop_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
 				 void *cbarg, bfa_status_t req_status,
 				 u32 rsp_len, u32 resid_len,
@@ -244,179 +211,3 @@ bfa_fcs_port_loop_plogi_response(void *f
 		bfa_assert(0);
 	}
 }
-
-bfa_status_t
-bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-				 bfa_fcs_port_get_fcid(port), 0,
-				 port->port_cfg.pwwn, port->port_cfg.nwwn,
-				 bfa_pport_get_maxfrsize(port->fcs->bfa));
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-				 FC_CLASS_3, len, &fchs,
-				 bfa_fcs_port_loop_plogi_acc_response,
-				 (void *)port, FC_MAX_PDUSZ, 0); /* No response
-								  * expected
-								  */
-
-	return BFA_STATUS_OK;
-}
-
-/*
- *  Plogi Acc Response
- * We donot do any processing here.
- */
-void
-bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				     void *cbarg, bfa_status_t req_status,
-				     u32 rsp_len, u32 resid_len,
-				     struct fchs_s *rsp_fchs)
-{
-
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-
-	bfa_trc(port->fcs, port->pid);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		bfa_trc(port->fcs, req_status);
-		return;
-	}
-}
-
-bfa_status_t
-bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-			     bfa_fcs_port_get_fcid(port), 0,
-			     port->port_cfg.pwwn, port->port_cfg.nwwn);
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-			  FC_CLASS_3, len, &fchs,
-			  bfa_fcs_port_loop_adisc_response, (void *)port,
-			  FC_MAX_PDUSZ, FC_RA_TOV);
-
-	return BFA_STATUS_OK;
-}
-
-/**
- *   Called by fcxp to notify the ADISC response
- */
-void
-bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				 void *cbarg, bfa_status_t req_status,
-				 u32 rsp_len, u32 resid_len,
-				 struct fchs_s *rsp_fchs)
-{
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-	struct bfa_fcs_rport_s *rport;
-	struct fc_adisc_s     *adisc_resp;
-	struct fc_els_cmd_s   *els_cmd;
-	u32        pid = rsp_fchs->s_id;
-
-	bfa_trc(port->fcs, req_status);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		/*
-		 * TBD : we may need to retry certain requests
-		 */
-		bfa_fcxp_free(fcxp);
-		return;
-	}
-
-	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
-	adisc_resp = (struct fc_adisc_s *) els_cmd;
-
-	if (els_cmd->els_code == FC_ELS_ACC) {
-	} else {
-		bfa_trc(port->fcs, adisc_resp->els_cmd.els_code);
-
-		/*
-		 * TBD: we may need to check for reject codes and retry
-		 */
-		rport = bfa_fcs_port_get_rport_by_pid(port, pid);
-		if (rport) {
-			list_del(&rport->qe);
-			bfa_fcs_rport_delete(rport);
-		}
-
-	}
-	return;
-}
-
-bfa_status_t
-bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, u8 alpa)
-{
-	struct fchs_s          fchs;
-	struct bfa_fcxp_s *fcxp;
-	int             len;
-
-	bfa_trc(port->fcs, alpa);
-
-	fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
-				  NULL);
-	bfa_assert(fcxp);
-
-	len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
-				 bfa_fcs_port_get_fcid(port), 0,
-				 port->port_cfg.pwwn, port->port_cfg.nwwn);
-
-	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
-				FC_CLASS_3, len, &fchs,
-				bfa_fcs_port_loop_adisc_acc_response,
-				(void *)port, FC_MAX_PDUSZ, 0); /* no reponse
-								 * expected
-								 */
-
-	return BFA_STATUS_OK;
-}
-
-/*
- *  Adisc Acc Response
- * We donot do any processing here.
- */
-void
-bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
-				     void *cbarg, bfa_status_t req_status,
-				     u32 rsp_len, u32 resid_len,
-				     struct fchs_s *rsp_fchs)
-{
-
-	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
-
-	bfa_trc(port->fcs, port->pid);
-
-	/*
-	 * Sanity Checks
-	 */
-	if (req_status != BFA_STATUS_OK) {
-		bfa_trc(port->fcs, req_status);
-		return;
-	}
-}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/lport_api.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/lport_api.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/lport_api.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/lport_api.c	2010-02-24 13:52:17.000000000 -0500
@@ -43,7 +43,7 @@ bfa_fcs_cfg_base_port(struct bfa_fcs_s *
 struct bfa_fcs_port_s *
 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
 {
-	return (&fcs->fabric.bport);
+	return &fcs->fabric.bport;
 }
 
 wwn_t
@@ -88,11 +88,10 @@ bfa_fcs_port_get_rport(struct bfa_fcs_po
 	}
 
 	bfa_trc(fcs, i);
-	if (rport) {
+	if (rport)
 		return rport->pwwn;
-	} else {
+	else
 		return (wwn_t) 0;
-	}
 }
 
 void
@@ -198,17 +197,17 @@ bfa_fcs_lookup_port(struct bfa_fcs_s *fc
 	vf = bfa_fcs_vf_lookup(fcs, vf_id);
 	if (vf == NULL) {
 		bfa_trc(fcs, vf_id);
-		return (NULL);
+		return NULL;
 	}
 
 	if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
-		return (&vf->bport);
+		return &vf->bport;
 
 	vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
 	if (vport)
-		return (&vport->lport);
+		return &vport->lport;
 
-	return (NULL);
+	return NULL;
 }
 
 /*
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/ns.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ns.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/ns.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/ns.c	2010-02-24 13:52:17.000000000 -0500
@@ -932,11 +932,10 @@ bfa_fcs_port_ns_send_rff_id(void *ns_cba
 	}
 	ns->fcxp = fcxp;
 
-	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
+	if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
-	} else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
+	else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port))
 		fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
-	}
 
 	len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
 			     bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/plog.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/plog.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/plog.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/plog.c	2010-02-24 13:52:17.000000000 -0500
@@ -180,5 +180,5 @@ bfa_plog_disable(struct bfa_plog_s *plog
 bfa_boolean_t
 bfa_plog_get_setting(struct bfa_plog_s *plog)
 {
-	return((bfa_boolean_t)plog->plog_enabled);
+	return (bfa_boolean_t)plog->plog_enabled;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/rport_ftrs.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_ftrs.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/rport_ftrs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/rport_ftrs.c	2010-02-24 13:52:17.000000000 -0500
@@ -79,7 +79,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_ONLINE :
+	case RPFSM_EVENT_RPORT_ONLINE:
 		if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 			rpf->rpsc_retries = 0;
@@ -87,7 +87,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf
 			break;
 		};
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		break;
 
 	default:
@@ -107,7 +107,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_f
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
 		rpf->rpsc_retries = 0;
@@ -130,11 +130,10 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
 	case RPFSM_EVENT_RPSC_COMP:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
 		/* Update speed info in f/w via BFA */
-		if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) {
+		if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN)
 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
-		} else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) {
+		else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN)
 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
-		}
 		break;
 
 	case RPFSM_EVENT_RPSC_FAIL:
@@ -154,7 +153,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
 		}
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		bfa_fcxp_discard(rpf->fcxp);
 		rpf->rpsc_retries = 0;
@@ -174,13 +173,13 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_TIMEOUT :
+	case RPFSM_EVENT_TIMEOUT:
 		/* re-send the RPSC */
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_timer_stop(&rpf->timer);
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		rpf->rpsc_retries = 0;
@@ -201,7 +200,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
 		rpf->rpsc_retries = 0;
 		break;
@@ -221,12 +220,12 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rp
 	bfa_trc(rport->fcs, event);
 
 	switch (event) {
-	case RPFSM_EVENT_RPORT_ONLINE :
+	case RPFSM_EVENT_RPORT_ONLINE:
 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
 		break;
 
-	case RPFSM_EVENT_RPORT_OFFLINE :
+	case RPFSM_EVENT_RPORT_OFFLINE:
 		break;
 
 	default:
@@ -366,10 +365,9 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg,
 		bfa_trc(rport->fcs, ls_rjt->reason_code);
 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
 		rport->stats.rpsc_rejects++;
-		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
+		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
-		} else {
+		else
 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
-		}
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/vfapi.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vfapi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/vfapi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vfapi.c	2010-02-24 13:52:17.000000000 -0500
@@ -189,7 +189,7 @@ bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs,
 {
 	bfa_trc(fcs, vf_id);
 	if (vf_id == FC_VF_ID_NULL)
-		return (&fcs->fabric);
+		return &fcs->fabric;
 
 	/**
 	 * @todo vf support
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bfa/vport.c linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bfa/vport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bfa/vport.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,13 +31,13 @@
 
 BFA_TRC_FILE(FCS, VPORT);
 
-#define __vport_fcs(__vp)       (__vp)->lport.fcs
-#define __vport_pwwn(__vp)      (__vp)->lport.port_cfg.pwwn
-#define __vport_nwwn(__vp)      (__vp)->lport.port_cfg.nwwn
-#define __vport_bfa(__vp)       (__vp)->lport.fcs->bfa
-#define __vport_fcid(__vp)      (__vp)->lport.pid
-#define __vport_fabric(__vp)    (__vp)->lport.fabric
-#define __vport_vfid(__vp)      (__vp)->lport.fabric->vf_id
+#define __vport_fcs(__vp)       ((__vp)->lport.fcs)
+#define __vport_pwwn(__vp)      ((__vp)->lport.port_cfg.pwwn)
+#define __vport_nwwn(__vp)      ((__vp)->lport.port_cfg.nwwn)
+#define __vport_bfa(__vp)       ((__vp)->lport.fcs->bfa)
+#define __vport_fcid(__vp)      ((__vp)->lport.pid)
+#define __vport_fabric(__vp)    ((__vp)->lport.fabric)
+#define __vport_vfid(__vp)      ((__vp)->lport.fabric->vf_id)
 
 #define BFA_FCS_VPORT_MAX_RETRIES  5
 /*
@@ -641,9 +641,9 @@ bfa_fcs_vport_get_max(struct bfa_fcs_s *
 	bfa_get_attr(fcs->bfa, &ioc_attr);
 
 	if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
-		return (BFA_FCS_MAX_VPORTS_SUPP_CT);
+		return BFA_FCS_MAX_VPORTS_SUPP_CT;
 	else
-		return (BFA_FCS_MAX_VPORTS_SUPP_CB);
+		return BFA_FCS_MAX_VPORTS_SUPP_CB;
 }
 
 
@@ -675,7 +675,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vpor
 		     struct bfad_vport_s *vport_drv)
 {
 	if (vport_cfg->pwwn == 0)
-		return (BFA_STATUS_INVALID_WWN);
+		return BFA_STATUS_INVALID_WWN;
 
 	if (bfa_fcs_port_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
 		return BFA_STATUS_VPORT_WWN_BP;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i.h linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i.h	2010-02-24 13:52:17.000000000 -0500
@@ -232,7 +232,6 @@ struct bnx2i_conn {
 	struct iscsi_cls_conn *cls_conn;
 	struct bnx2i_hba *hba;
 	struct completion cmd_cleanup_cmpl;
-	int is_bound;
 
 	u32 iscsi_conn_cid;
 #define BNX2I_CID_RESERVED	0x5AFF
@@ -685,6 +684,7 @@ extern unsigned int error_mask1, error_m
 extern u64 iscsi_error_mask;
 extern unsigned int en_tcp_dack;
 extern unsigned int event_coal_div;
+extern unsigned int event_coal_min;
 
 extern struct scsi_transport_template *bnx2i_scsi_xport_template;
 extern struct iscsi_transport bnx2i_iscsi_transport;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_hwi.c	2010-02-24 13:52:17.000000000 -0500
@@ -133,20 +133,38 @@ void bnx2i_arm_cq_event_coalescing(struc
 {
 	struct bnx2i_5771x_cq_db *cq_db;
 	u16 cq_index;
+	u16 next_index;
+	u32 num_active_cmds;
 
+
+	/* Coalesce CQ entries only on 10G devices */
 	if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
 		return;
 
+	/* Do not update CQ DB multiple times before firmware writes
+	 * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious
+	 * interrupts and other unwanted results
+	 */
+	cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
+	if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
+		return;
+
 	if (action == CNIC_ARM_CQE) {
-		cq_index = ep->qp.cqe_exp_seq_sn +
-			   ep->num_active_cmds / event_coal_div;
-		cq_index %= (ep->qp.cqe_size * 2 + 1);
-		if (!cq_index) {
+		num_active_cmds = ep->num_active_cmds;
+		if (num_active_cmds <= event_coal_min)
+			next_index = 1;
+		else
+			next_index = event_coal_min +
+				(num_active_cmds - event_coal_min) / event_coal_div;
+		if (!next_index)
+			next_index = 1;
+		cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
+		if (cq_index > ep->qp.cqe_size * 2)
+			cq_index -= ep->qp.cqe_size * 2;
+		if (!cq_index)
 			cq_index = 1;
-			cq_db = (struct bnx2i_5771x_cq_db *)
-					ep->qp.cq_pgtbl_virt;
-			cq_db->sqn[0] = cq_index;
-		}
+
+		cq_db->sqn[0] = cq_index;
 	}
 }
 
@@ -366,6 +384,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_co
 	struct bnx2i_cmd *bnx2i_cmd;
 	struct bnx2i_tmf_request *tmfabort_wqe;
 	u32 dword;
+	u32 scsi_lun[2];
 
 	bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
 	tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -376,27 +395,35 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_co
 	tmfabort_wqe->op_attr = 0;
 	tmfabort_wqe->op_attr =
 		ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK;
-	tmfabort_wqe->lun[0] = be32_to_cpu(tmfabort_hdr->lun[0]);
-	tmfabort_wqe->lun[1] = be32_to_cpu(tmfabort_hdr->lun[1]);
 
 	tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14));
 	tmfabort_wqe->reserved2 = 0;
 	tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn);
 
 	ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
-	if (!ctask || ctask->sc)
+	if (!ctask || !ctask->sc)
 		/*
 		 * the iscsi layer must have completed the cmd while this
 		 * was starting up.
+		 *
+		 * Note: In the case of a SCSI cmd timeout, the task's sc
+		 *       is still active; hence ctask->sc != 0
+		 *       In this case, the task must be aborted
 		 */
 		return 0;
+
 	ref_sc = ctask->sc;
 
+	/* Retrieve LUN directly from the ref_sc */
+	int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun);
+	tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
+	tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
+
 	if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
 		dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT);
 	else
 		dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT);
-	tmfabort_wqe->ref_itt = (dword | tmfabort_hdr->rtt);
+	tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK));
 	tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
 
 	tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_init.c linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_init.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -17,8 +17,8 @@ static struct list_head adapter_list = L
 static u32 adapter_count;
 
 #define DRV_MODULE_NAME		"bnx2i"
-#define DRV_MODULE_VERSION	"2.0.1e"
-#define DRV_MODULE_RELDATE	"June 22, 2009"
+#define DRV_MODULE_VERSION	"2.1.0"
+#define DRV_MODULE_RELDATE	"Dec 06, 2009"
 
 static char version[] __devinitdata =
 		"Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -32,6 +32,10 @@ MODULE_VERSION(DRV_MODULE_VERSION);
 
 static DEFINE_MUTEX(bnx2i_dev_lock);
 
+unsigned int event_coal_min = 24;
+module_param(event_coal_min, int, 0664);
+MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands");
+
 unsigned int event_coal_div = 1;
 module_param(event_coal_div, int, 0664);
 MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor");
@@ -83,8 +87,12 @@ void bnx2i_identify_device(struct bnx2i_
 		set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type);
 		hba->mail_queue_access = BNX2I_MQ_BIN_MODE;
 	} else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 ||
-		   hba->pci_did == PCI_DEVICE_ID_NX2_57711)
+		   hba->pci_did == PCI_DEVICE_ID_NX2_57711 ||
+		   hba->pci_did == PCI_DEVICE_ID_NX2_57711E)
 		set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type);
+	else
+		printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n",
+				  hba->pci_did);
 }
 
 
@@ -363,7 +371,7 @@ static int __init bnx2i_mod_init(void)
 
 	printk(KERN_INFO "%s", version);
 
-	if (!is_power_of_2(sq_size))
+	if (sq_size && !is_power_of_2(sq_size))
 		sq_size = roundup_pow_of_two(sq_size);
 
 	mutex_init(&bnx2i_dev_lock);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/bnx2i/bnx2i_iscsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -485,7 +485,6 @@ static int bnx2i_setup_cmd_pool(struct b
 		struct iscsi_task *task = session->cmds[i];
 		struct bnx2i_cmd *cmd = task->dd_data;
 
-		/* Anil */
 		task->hdr = &cmd->hdr;
 		task->hdr_max = sizeof(struct iscsi_hdr);
 
@@ -765,7 +764,6 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct
 	hba->pci_svid = hba->pcidev->subsystem_vendor;
 	hba->pci_func = PCI_FUNC(hba->pcidev->devfn);
 	hba->pci_devno = PCI_SLOT(hba->pcidev->devfn);
-	bnx2i_identify_device(hba);
 
 	bnx2i_identify_device(hba);
 	bnx2i_setup_host_queue_size(hba, shost);
@@ -1161,9 +1159,6 @@ static int bnx2i_task_xmit(struct iscsi_
 	struct bnx2i_cmd *cmd = task->dd_data;
 	struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
 
-	if (!bnx2i_conn->is_bound)
-		return -ENOTCONN;
-
 	/*
 	 * If there is no scsi_cmnd this must be a mgmt task
 	 */
@@ -1371,7 +1366,6 @@ static int bnx2i_conn_bind(struct iscsi_
 	bnx2i_conn->ep = bnx2i_ep;
 	bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
 	bnx2i_conn->fw_cid = bnx2i_ep->ep_cid;
-	bnx2i_conn->is_bound = 1;
 
 	ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn,
 						bnx2i_ep->ep_iscsi_cid);
@@ -1883,7 +1877,7 @@ static void bnx2i_ep_disconnect(struct i
 
 	bnx2i_ep = ep->dd_data;
 
-	/* driver should not attempt connection cleanup untill TCP_CONNECT
+	/* driver should not attempt connection cleanup until TCP_CONNECT
 	 * completes either successfully or fails. Timeout is 9-secs, so
 	 * wait for it to complete
 	 */
@@ -1896,9 +1890,7 @@ static void bnx2i_ep_disconnect(struct i
 		conn = bnx2i_conn->cls_conn->dd_data;
 		session = conn->session;
 
-		spin_lock_bh(&session->lock);
-		bnx2i_conn->is_bound = 0;
-		spin_unlock_bh(&session->lock);
+		iscsi_suspend_queue(conn);
 	}
 
 	hba = bnx2i_ep->hba;
@@ -2034,7 +2026,7 @@ struct iscsi_transport bnx2i_iscsi_trans
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				  ISCSI_LU_RESET_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/constants.c linux-libre-2.6.33-gnu1/drivers/scsi/constants.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/constants.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/constants.c	2010-02-24 13:52:17.000000000 -0500
@@ -141,6 +141,7 @@ static const struct value_name_pair serv
 static const struct value_name_pair serv_in16_arr[] = {
 	{0x10, "Read capacity(16)"},
 	{0x11, "Read long(16)"},
+	{0x12, "Get LBA status"},
 };
 #define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr)
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_iscsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -937,7 +937,7 @@ static struct iscsi_transport cxgb3i_isc
 				ISCSI_USERNAME | ISCSI_PASSWORD |
 				ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				ISCSI_LU_RESET_TMO |
+				ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_offload.c	2010-02-24 13:52:17.000000000 -0500
@@ -291,7 +291,7 @@ static void act_open_req_arp_failure(str
 	c3cn_hold(c3cn);
 	spin_lock_bh(&c3cn->lock);
 	if (c3cn->state == C3CN_STATE_CONNECTING)
-		fail_act_open(c3cn, EHOSTUNREACH);
+		fail_act_open(c3cn, -EHOSTUNREACH);
 	spin_unlock_bh(&c3cn->lock);
 	c3cn_put(c3cn);
 	__kfree_skb(skb);
@@ -792,18 +792,18 @@ static int act_open_rpl_status_to_errno(
 {
 	switch (status) {
 	case CPL_ERR_CONN_RESET:
-		return ECONNREFUSED;
+		return -ECONNREFUSED;
 	case CPL_ERR_ARP_MISS:
-		return EHOSTUNREACH;
+		return -EHOSTUNREACH;
 	case CPL_ERR_CONN_TIMEDOUT:
-		return ETIMEDOUT;
+		return -ETIMEDOUT;
 	case CPL_ERR_TCAM_FULL:
-		return ENOMEM;
+		return -ENOMEM;
 	case CPL_ERR_CONN_EXIST:
 		cxgb3i_log_error("ACTIVE_OPEN_RPL: 4-tuple in use\n");
-		return EADDRINUSE;
+		return -EADDRINUSE;
 	default:
-		return EIO;
+		return -EIO;
 	}
 }
 
@@ -817,7 +817,7 @@ static void act_open_retry_timer(unsigne
 	spin_lock_bh(&c3cn->lock);
 	skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC);
 	if (!skb)
-		fail_act_open(c3cn, ENOMEM);
+		fail_act_open(c3cn, -ENOMEM);
 	else {
 		skb->sk = (struct sock *)c3cn;
 		set_arp_failure_handler(skb, act_open_req_arp_failure);
@@ -966,14 +966,14 @@ static int abort_status_to_errno(struct
 	case CPL_ERR_BAD_SYN: /* fall through */
 	case CPL_ERR_CONN_RESET:
 		return c3cn->state > C3CN_STATE_ESTABLISHED ?
-			EPIPE : ECONNRESET;
+			-EPIPE : -ECONNRESET;
 	case CPL_ERR_XMIT_TIMEDOUT:
 	case CPL_ERR_PERSIST_TIMEDOUT:
 	case CPL_ERR_FINWAIT2_TIMEDOUT:
 	case CPL_ERR_KEEPALIVE_TIMEDOUT:
-		return ETIMEDOUT;
+		return -ETIMEDOUT;
 	default:
-		return EIO;
+		return -EIO;
 	}
 }
 
@@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn
 static int is_cxgb3_dev(struct net_device *dev)
 {
 	struct cxgb3i_sdev_data *cdata;
+	struct net_device *ndev = dev;
+
+	if (dev->priv_flags & IFF_802_1Q_VLAN)
+		ndev = vlan_dev_real_dev(dev);
 
 	write_lock(&cdata_rwlock);
 	list_for_each_entry(cdata, &cdata_list, list) {
@@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_devic
 		int i;
 
 		for (i = 0; i < ports->nports; i++)
-			if (dev == ports->lldevs[i]) {
+			if (ndev == ports->lldevs[i]) {
 				write_unlock(&cdata_rwlock);
 				return 1;
 			}
@@ -1563,9 +1567,29 @@ free_tid:
 	s3_free_atid(cdev, c3cn->tid);
 	c3cn->tid = 0;
 out_err:
-	return -1;
+	return -EINVAL;
 }
 
+/**
+ * cxgb3i_find_dev - find the interface associated with the given address
+ * @ipaddr: ip address
+ */
+static struct net_device *
+cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr)
+{
+	struct flowi fl;
+	int err;
+	struct rtable *rt;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.nl_u.ip4_u.daddr = ipaddr;
+
+	err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl);
+	if (!err)
+		return (&rt->u.dst)->dev;
+
+	return NULL;
+}
 
 /**
  * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address
@@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_devic
 	struct cxgb3i_sdev_data *cdata;
 	struct t3cdev *cdev;
 	__be32 sipv4;
+	struct net_device *dstdev;
 	int err;
 
 	c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev);
@@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_devic
 	c3cn->daddr.sin_port = usin->sin_port;
 	c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr;
 
+	dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr);
+	if (!dstdev || !is_cxgb3_dev(dstdev))
+		return -ENETUNREACH;
+
+	if (dstdev->priv_flags & IFF_802_1Q_VLAN)
+		dev = dstdev;
+
 	rt = find_route(dev, c3cn->saddr.sin_addr.s_addr,
 			c3cn->daddr.sin_addr.s_addr,
 			c3cn->saddr.sin_port,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/cxgb3i/cxgb3i_pdu.c	2010-02-24 13:52:17.000000000 -0500
@@ -388,8 +388,8 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_ta
 	if (err > 0) {
 		int pdulen = err;
 
-	cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
-			task, skb, skb->len, skb->data_len, err);
+		cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
+				task, skb, skb->len, skb->data_len, err);
 
 		if (task->conn->hdrdgst_en)
 			pdulen += ISCSI_DIGEST_SIZE;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/dc395x.c linux-libre-2.6.33-gnu1/drivers/scsi/dc395x.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/dc395x.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/dc395x.c	2010-02-24 13:52:17.000000000 -0500
@@ -1509,7 +1509,7 @@ static u8 start_scsi(struct AdapterCtlBl
 		 * Try anyway?
 		 *
 		 * We could, BUT: Sometimes the TRM_S1040 misses to produce a Selection
-		 * Timeout, a Disconnect or a Reselction IRQ, so we would be screwed!
+		 * Timeout, a Disconnect or a Reselection IRQ, so we would be screwed!
 		 * (This is likely to be a bug in the hardware. Obviously, most people
 		 *  only have one initiator per SCSI bus.)
 		 * Instead let this fail and have the timer make sure the command is 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_alua.c	2010-02-24 13:52:17.000000000 -0500
@@ -60,11 +60,17 @@ struct alua_dh_data {
 	int			bufflen;
 	unsigned char		sense[SCSI_SENSE_BUFFERSIZE];
 	int			senselen;
+	struct scsi_device	*sdev;
+	activate_complete	callback_fn;
+	void			*callback_data;
 };
 
 #define ALUA_POLICY_SWITCH_CURRENT	0
 #define ALUA_POLICY_SWITCH_ALL		1
 
+static char print_alua_state(int);
+static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
+
 static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
@@ -231,18 +237,71 @@ done:
 }
 
 /*
+ * alua_stpg - Evaluate SET TARGET GROUP STATES
+ * @sdev: the device to be evaluated
+ * @state: the new target group state
+ *
+ * Send a SET TARGET GROUP STATES command to the device.
+ * We only have to test here if we should resubmit the command;
+ * any other error is assumed as a failure.
+ */
+static void stpg_endio(struct request *req, int error)
+{
+	struct alua_dh_data *h = req->end_io_data;
+	struct scsi_sense_hdr sense_hdr;
+	unsigned err = SCSI_DH_IO;
+
+	if (error || host_byte(req->errors) != DID_OK ||
+			msg_byte(req->errors) != COMMAND_COMPLETE)
+		goto done;
+
+	if (err == SCSI_DH_IO && h->senselen > 0) {
+		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
+					   &sense_hdr);
+		if (!err) {
+			err = SCSI_DH_IO;
+			goto done;
+		}
+		err = alua_check_sense(h->sdev, &sense_hdr);
+		if (err == ADD_TO_MLQUEUE) {
+			err = SCSI_DH_RETRY;
+			goto done;
+		}
+		sdev_printk(KERN_INFO, h->sdev,
+			    "%s: stpg sense code: %02x/%02x/%02x\n",
+			    ALUA_DH_NAME, sense_hdr.sense_key,
+			    sense_hdr.asc, sense_hdr.ascq);
+		err = SCSI_DH_IO;
+	}
+	if (err == SCSI_DH_OK) {
+		h->state = TPGS_STATE_OPTIMIZED;
+		sdev_printk(KERN_INFO, h->sdev,
+			    "%s: port group %02x switched to state %c\n",
+			    ALUA_DH_NAME, h->group_id,
+			    print_alua_state(h->state));
+	}
+done:
+	blk_put_request(req);
+	if (h->callback_fn) {
+		h->callback_fn(h->callback_data, err);
+		h->callback_fn = h->callback_data = NULL;
+	}
+	return;
+}
+
+/*
  * submit_stpg - Issue a SET TARGET GROUP STATES command
- * @sdev: sdev the command should be sent to
  *
  * Currently we're only setting the current target port group state
  * to 'active/optimized' and let the array firmware figure out
  * the states of the remaining groups.
  */
-static unsigned submit_stpg(struct scsi_device *sdev, struct alua_dh_data *h)
+static unsigned submit_stpg(struct alua_dh_data *h)
 {
 	struct request *rq;
 	int err = SCSI_DH_RES_TEMP_UNAVAIL;
 	int stpg_len = 8;
+	struct scsi_device *sdev = h->sdev;
 
 	/* Prepare the data buffer */
 	memset(h->buff, 0, stpg_len);
@@ -252,7 +311,7 @@ static unsigned submit_stpg(struct scsi_
 
 	rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
 	if (!rq)
-		goto done;
+		return SCSI_DH_RES_TEMP_UNAVAIL;
 
 	/* Prepare the command. */
 	rq->cmd[0] = MAINTENANCE_OUT;
@@ -266,17 +325,9 @@ static unsigned submit_stpg(struct scsi_
 	rq->sense = h->sense;
 	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
 	rq->sense_len = h->senselen = 0;
+	rq->end_io_data = h;
 
-	err = blk_execute_rq(rq->q, NULL, rq, 1);
-	if (err == -EIO) {
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: stpg failed with %x\n",
-			    ALUA_DH_NAME, rq->errors);
-		h->senselen = rq->sense_len;
-		err = SCSI_DH_IO;
-	}
-	blk_put_request(rq);
-done:
+	blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
 	return err;
 }
 
@@ -477,50 +528,6 @@ static int alua_check_sense(struct scsi_
 }
 
 /*
- * alua_stpg - Evaluate SET TARGET GROUP STATES
- * @sdev: the device to be evaluated
- * @state: the new target group state
- *
- * Send a SET TARGET GROUP STATES command to the device.
- * We only have to test here if we should resubmit the command;
- * any other error is assumed as a failure.
- */
-static int alua_stpg(struct scsi_device *sdev, int state,
-		     struct alua_dh_data *h)
-{
-	struct scsi_sense_hdr sense_hdr;
-	unsigned err;
-	int retry = ALUA_FAILOVER_RETRIES;
-
- retry:
-	err = submit_stpg(sdev, h);
-	if (err == SCSI_DH_IO && h->senselen > 0) {
-		err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
-					   &sense_hdr);
-		if (!err)
-			return SCSI_DH_IO;
-		err = alua_check_sense(sdev, &sense_hdr);
-		if (retry > 0 && err == ADD_TO_MLQUEUE) {
-			retry--;
-			goto retry;
-		}
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: stpg sense code: %02x/%02x/%02x\n",
-			    ALUA_DH_NAME, sense_hdr.sense_key,
-			    sense_hdr.asc, sense_hdr.ascq);
-		err = SCSI_DH_IO;
-	}
-	if (err == SCSI_DH_OK) {
-		h->state = state;
-		sdev_printk(KERN_INFO, sdev,
-			    "%s: port group %02x switched to state %c\n",
-			    ALUA_DH_NAME, h->group_id,
-			    print_alua_state(h->state) );
-	}
-	return err;
-}
-
-/*
  * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
  * @sdev: the device to be evaluated.
  *
@@ -652,7 +659,8 @@ out:
  * based on a certain policy. But until we actually encounter them it
  * should be okay.
  */
-static int alua_activate(struct scsi_device *sdev)
+static int alua_activate(struct scsi_device *sdev,
+			activate_complete fn, void *data)
 {
 	struct alua_dh_data *h = get_alua_data(sdev);
 	int err = SCSI_DH_OK;
@@ -663,11 +671,19 @@ static int alua_activate(struct scsi_dev
 			goto out;
 	}
 
-	if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED)
-		err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h);
+	if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED) {
+		h->callback_fn = fn;
+		h->callback_data = data;
+		err = submit_stpg(h);
+		if (err == SCSI_DH_OK)
+			return 0;
+		h->callback_fn = h->callback_data = NULL;
+	}
 
 out:
-	return err;
+	if (fn)
+		fn(data, err);
+	return 0;
 }
 
 /*
@@ -745,6 +761,7 @@ static int alua_bus_attach(struct scsi_d
 	h->rel_port = -1;
 	h->buff = h->inq;
 	h->bufflen = ALUA_INQUIRY_SIZE;
+	h->sdev = sdev;
 
 	err = alua_initialize(sdev, h);
 	if (err != SCSI_DH_OK)
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh.c linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh.c	2010-02-24 13:52:17.000000000 -0500
@@ -226,7 +226,7 @@ store_dh_state(struct device *dev, struc
 			 * Activate a device handler
 			 */
 			if (scsi_dh->activate)
-				err = scsi_dh->activate(sdev);
+				err = scsi_dh->activate(sdev, NULL, NULL);
 			else
 				err = 0;
 		}
@@ -304,18 +304,15 @@ static int scsi_dh_notifier(struct notif
 	sdev = to_scsi_device(dev);
 
 	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		err = device_create_file(dev, &scsi_dh_state_attr);
+		/* don't care about err */
 		devinfo = device_handler_match(NULL, sdev);
-		if (!devinfo)
-			goto out;
-
-		err = scsi_dh_handler_attach(sdev, devinfo);
-		if (!err)
-			err = device_create_file(dev, &scsi_dh_state_attr);
+		if (devinfo)
+			err = scsi_dh_handler_attach(sdev, devinfo);
 	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
 		device_remove_file(dev, &scsi_dh_state_attr);
 		scsi_dh_handler_detach(sdev, NULL);
 	}
-out:
 	return err;
 }
 
@@ -423,10 +420,17 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device
 /*
  * scsi_dh_activate - activate the path associated with the scsi_device
  *      corresponding to the given request queue.
- * @q - Request queue that is associated with the scsi_device to be
- *      activated.
+ *     Returns immediately without waiting for activation to be completed.
+ * @q    - Request queue that is associated with the scsi_device to be
+ *         activated.
+ * @fn   - Function to be called upon completion of the activation.
+ *         Function fn is called with data (below) and the error code.
+ *         Function fn may be called from the same calling context. So,
+ *         do not hold the lock in the caller which may be needed in fn.
+ * @data - data passed to the function fn upon completion.
+ *
  */
-int scsi_dh_activate(struct request_queue *q)
+int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
 {
 	int err = 0;
 	unsigned long flags;
@@ -445,7 +449,7 @@ int scsi_dh_activate(struct request_queu
 		return err;
 
 	if (scsi_dh->activate)
-		err = scsi_dh->activate(sdev);
+		err = scsi_dh->activate(sdev, fn, data);
 	put_device(&sdev->sdev_gendev);
 	return err;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_emc.c	2010-02-24 13:52:17.000000000 -0500
@@ -528,7 +528,8 @@ retry:
 	return err;
 }
 
-static int clariion_activate(struct scsi_device *sdev)
+static int clariion_activate(struct scsi_device *sdev,
+				activate_complete fn, void *data)
 {
 	struct clariion_dh_data *csdev = get_clariion_data(sdev);
 	int result;
@@ -559,7 +560,9 @@ done:
 		    csdev->port, lun_state[csdev->lun_state],
 		    csdev->default_sp + 'A');
 
-	return result;
+	if (fn)
+		fn(data, result);
+	return 0;
 }
 /*
  * params - parameters in the following format
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_hp_sw.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,8 +39,14 @@ struct hp_sw_dh_data {
 	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
 	int path_state;
 	int retries;
+	int retry_cnt;
+	struct scsi_device *sdev;
+	activate_complete	callback_fn;
+	void			*callback_data;
 };
 
+static int hp_sw_start_stop(struct hp_sw_dh_data *);
+
 static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
@@ -191,19 +197,53 @@ static int start_done(struct scsi_device
 	return rc;
 }
 
+static void start_stop_endio(struct request *req, int error)
+{
+	struct hp_sw_dh_data *h = req->end_io_data;
+	unsigned err = SCSI_DH_OK;
+
+	if (error || host_byte(req->errors) != DID_OK ||
+			msg_byte(req->errors) != COMMAND_COMPLETE) {
+		sdev_printk(KERN_WARNING, h->sdev,
+			    "%s: sending start_stop_unit failed with %x\n",
+			    HP_SW_NAME, req->errors);
+		err = SCSI_DH_IO;
+		goto done;
+	}
+
+	if (req->sense_len > 0) {
+		err = start_done(h->sdev, h->sense);
+		if (err == SCSI_DH_RETRY) {
+			err = SCSI_DH_IO;
+			if (--h->retry_cnt) {
+				blk_put_request(req);
+				err = hp_sw_start_stop(h);
+				if (err == SCSI_DH_OK)
+					return;
+			}
+		}
+	}
+done:
+	blk_put_request(req);
+	if (h->callback_fn) {
+		h->callback_fn(h->callback_data, err);
+		h->callback_fn = h->callback_data = NULL;
+	}
+	return;
+
+}
+
 /*
  * hp_sw_start_stop - Send START STOP UNIT command
  * @sdev: sdev command should be sent to
  *
  * Sending START STOP UNIT activates the SP.
  */
-static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
+static int hp_sw_start_stop(struct hp_sw_dh_data *h)
 {
 	struct request *req;
-	int ret, retry;
 
-retry:
-	req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO);
+	req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC);
 	if (!req)
 		return SCSI_DH_RES_TEMP_UNAVAIL;
 
@@ -217,32 +257,10 @@ retry:
 	req->sense = h->sense;
 	memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
 	req->sense_len = 0;
-	retry = h->retries;
-
-	ret = blk_execute_rq(req->q, NULL, req, 1);
-	if (ret == -EIO) {
-		if (req->sense_len > 0) {
-			ret = start_done(sdev, h->sense);
-		} else {
-			sdev_printk(KERN_WARNING, sdev,
-				    "%s: sending start_stop_unit failed with %x\n",
-				    HP_SW_NAME, req->errors);
-			ret = SCSI_DH_IO;
-		}
-	} else
-		ret = SCSI_DH_OK;
-
-	if (ret == SCSI_DH_RETRY) {
-		if (--retry) {
-			blk_put_request(req);
-			goto retry;
-		}
-		ret = SCSI_DH_IO;
-	}
-
-	blk_put_request(req);
+	req->end_io_data = h;
 
-	return ret;
+	blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio);
+	return SCSI_DH_OK;
 }
 
 static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
@@ -268,7 +286,8 @@ static int hp_sw_prep_fn(struct scsi_dev
  * activate the passive path (and deactivate the
  * previously active one).
  */
-static int hp_sw_activate(struct scsi_device *sdev)
+static int hp_sw_activate(struct scsi_device *sdev,
+				activate_complete fn, void *data)
 {
 	int ret = SCSI_DH_OK;
 	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
@@ -276,14 +295,18 @@ static int hp_sw_activate(struct scsi_de
 	ret = hp_sw_tur(sdev, h);
 
 	if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) {
-		ret = hp_sw_start_stop(sdev, h);
+		h->retry_cnt = h->retries;
+		h->callback_fn = fn;
+		h->callback_data = data;
+		ret = hp_sw_start_stop(h);
 		if (ret == SCSI_DH_OK)
-			sdev_printk(KERN_INFO, sdev,
-				    "%s: activated path\n",
-				    HP_SW_NAME);
+			return 0;
+		h->callback_fn = h->callback_data = NULL;
 	}
 
-	return ret;
+	if (fn)
+		fn(data, ret);
+	return 0;
 }
 
 static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
@@ -326,6 +349,7 @@ static int hp_sw_bus_attach(struct scsi_
 	h = (struct hp_sw_dh_data *) scsi_dh_data->buf;
 	h->path_state = HP_SW_PATH_UNINITIALIZED;
 	h->retries = HP_SW_RETRIES;
+	h->sdev = sdev;
 
 	ret = hp_sw_tur(sdev, h);
 	if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED)
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/device_handler/scsi_dh_rdac.c	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
+#include <linux/workqueue.h>
 
 #define RDAC_NAME "rdac"
 #define RDAC_RETRY_COUNT 5
@@ -138,7 +139,13 @@ struct rdac_controller {
 	} mode_select;
 	u8	index;
 	u8	array_name[ARRAY_LABEL_LEN];
+	spinlock_t		ms_lock;
+	int			ms_queued;
+	struct work_struct	ms_work;
+	struct scsi_device	*ms_sdev;
+	struct list_head	ms_head;
 };
+
 struct c8_inquiry {
 	u8	peripheral_info;
 	u8	page_code; /* 0xC8 */
@@ -198,8 +205,17 @@ static const char *lun_state[] =
 	"owned (AVT mode)",
 };
 
+struct rdac_queue_data {
+	struct list_head	entry;
+	struct rdac_dh_data	*h;
+	activate_complete	callback_fn;
+	void			*callback_data;
+};
+
 static LIST_HEAD(ctlr_list);
 static DEFINE_SPINLOCK(list_lock);
+static struct workqueue_struct *kmpath_rdacd;
+static void send_mode_select(struct work_struct *work);
 
 /*
  * module parameter to enable rdac debug logging.
@@ -281,7 +297,6 @@ static struct request *rdac_failover_get
 		rdac_pg->subpage_code = 0x1;
 		rdac_pg->page_len[0] = 0x01;
 		rdac_pg->page_len[1] = 0x28;
-		rdac_pg->lun_table[h->lun] = 0x81;
 	} else {
 		struct rdac_pg_legacy *rdac_pg;
 
@@ -291,7 +306,6 @@ static struct request *rdac_failover_get
 		common = &rdac_pg->common;
 		rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
 		rdac_pg->page_len = 0x68;
-		rdac_pg->lun_table[h->lun] = 0x81;
 	}
 	common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
 	common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
@@ -325,6 +339,7 @@ static void release_controller(struct kr
 	struct rdac_controller *ctlr;
 	ctlr = container_of(kref, struct rdac_controller, kref);
 
+	flush_workqueue(kmpath_rdacd);
 	spin_lock(&list_lock);
 	list_del(&ctlr->node);
 	spin_unlock(&list_lock);
@@ -363,6 +378,11 @@ static struct rdac_controller *get_contr
 
 	kref_init(&ctlr->kref);
 	ctlr->use_ms10 = -1;
+	ctlr->ms_queued = 0;
+	ctlr->ms_sdev = NULL;
+	spin_lock_init(&ctlr->ms_lock);
+	INIT_WORK(&ctlr->ms_work, send_mode_select);
+	INIT_LIST_HEAD(&ctlr->ms_head);
 	list_add(&ctlr->node, &ctlr_list);
 done:
 	spin_unlock(&list_lock);
@@ -490,7 +510,7 @@ static int set_mode_select(struct scsi_d
 }
 
 static int mode_select_handle_sense(struct scsi_device *sdev,
-				    unsigned char *sensebuf)
+					unsigned char *sensebuf)
 {
 	struct scsi_sense_hdr sense_hdr;
 	int err = SCSI_DH_IO, ret;
@@ -533,11 +553,29 @@ done:
 	return err;
 }
 
-static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
+static void send_mode_select(struct work_struct *work)
 {
+	struct rdac_controller *ctlr =
+		container_of(work, struct rdac_controller, ms_work);
 	struct request *rq;
+	struct scsi_device *sdev = ctlr->ms_sdev;
+	struct rdac_dh_data *h = get_rdac_data(sdev);
 	struct request_queue *q = sdev->request_queue;
 	int err, retry_cnt = RDAC_RETRY_COUNT;
+	struct rdac_queue_data *tmp, *qdata;
+	LIST_HEAD(list);
+	u8 *lun_table;
+
+	spin_lock(&ctlr->ms_lock);
+	list_splice_init(&ctlr->ms_head, &list);
+	ctlr->ms_queued = 0;
+	ctlr->ms_sdev = NULL;
+	spin_unlock(&ctlr->ms_lock);
+
+	if (ctlr->use_ms10)
+		lun_table = ctlr->mode_select.expanded.lun_table;
+	else
+		lun_table = ctlr->mode_select.legacy.lun_table;
 
 retry:
 	err = SCSI_DH_RES_TEMP_UNAVAIL;
@@ -545,6 +583,10 @@ retry:
 	if (!rq)
 		goto done;
 
+	list_for_each_entry(qdata, &list, entry) {
+		lun_table[qdata->h->lun] = 0x81;
+	}
+
 	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
 		"%s MODE_SELECT command",
 		(char *) h->ctlr->array_name, h->ctlr->index,
@@ -565,10 +607,45 @@ retry:
 	}
 
 done:
-	return err;
+	list_for_each_entry_safe(qdata, tmp, &list, entry) {
+		list_del(&qdata->entry);
+		if (err == SCSI_DH_OK)
+			qdata->h->state = RDAC_STATE_ACTIVE;
+		if (qdata->callback_fn)
+			qdata->callback_fn(qdata->callback_data, err);
+		kfree(qdata);
+	}
+	return;
 }
 
-static int rdac_activate(struct scsi_device *sdev)
+static int queue_mode_select(struct scsi_device *sdev,
+				activate_complete fn, void *data)
+{
+	struct rdac_queue_data *qdata;
+	struct rdac_controller *ctlr;
+
+	qdata = kzalloc(sizeof(*qdata), GFP_KERNEL);
+	if (!qdata)
+		return SCSI_DH_RETRY;
+
+	qdata->h = get_rdac_data(sdev);
+	qdata->callback_fn = fn;
+	qdata->callback_data = data;
+
+	ctlr = qdata->h->ctlr;
+	spin_lock(&ctlr->ms_lock);
+	list_add_tail(&qdata->entry, &ctlr->ms_head);
+	if (!ctlr->ms_queued) {
+		ctlr->ms_queued = 1;
+		ctlr->ms_sdev = sdev;
+		queue_work(kmpath_rdacd, &ctlr->ms_work);
+	}
+	spin_unlock(&ctlr->ms_lock);
+	return SCSI_DH_OK;
+}
+
+static int rdac_activate(struct scsi_device *sdev,
+			activate_complete fn, void *data)
 {
 	struct rdac_dh_data *h = get_rdac_data(sdev);
 	int err = SCSI_DH_OK;
@@ -577,10 +654,15 @@ static int rdac_activate(struct scsi_dev
 	if (err != SCSI_DH_OK)
 		goto done;
 
-	if (h->lun_state == RDAC_LUN_UNOWNED)
-		err = send_mode_select(sdev, h);
+	if (h->lun_state == RDAC_LUN_UNOWNED) {
+		err = queue_mode_select(sdev, fn, data);
+		if (err == SCSI_DH_OK)
+			return 0;
+	}
 done:
-	return err;
+	if (fn)
+		fn(data, err);
+	return 0;
 }
 
 static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
@@ -666,6 +748,8 @@ static const struct scsi_dh_devlist rdac
 	{"IBM", "1724"},
 	{"IBM", "1726"},
 	{"IBM", "1742"},
+	{"IBM", "1745"},
+	{"IBM", "1746"},
 	{"IBM", "1814"},
 	{"IBM", "1815"},
 	{"IBM", "1818"},
@@ -790,13 +874,26 @@ static int __init rdac_init(void)
 	int r;
 
 	r = scsi_register_device_handler(&rdac_dh);
-	if (r != 0)
+	if (r != 0) {
 		printk(KERN_ERR "Failed to register scsi device handler.");
+		goto done;
+	}
+
+	/*
+	 * Create workqueue to handle mode selects for rdac
+	 */
+	kmpath_rdacd = create_singlethread_workqueue("kmpath_rdacd");
+	if (!kmpath_rdacd) {
+		scsi_unregister_device_handler(&rdac_dh);
+		printk(KERN_ERR "kmpath_rdacd creation failed.\n");
+	}
+done:
 	return r;
 }
 
 static void __exit rdac_exit(void)
 {
+	destroy_workqueue(kmpath_rdacd);
 	scsi_unregister_device_handler(&rdac_dh);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/dmx3191d.c linux-libre-2.6.33-gnu1/drivers/scsi/dmx3191d.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/dmx3191d.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/dmx3191d.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,7 +31,7 @@
 #include <scsi/scsi_host.h>
 
 /*
- * Defintions for the generic 5380 driver.
+ * Definitions for the generic 5380 driver.
  */
 #define AUTOSENSE
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/fcoe.c linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/fcoe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.c	2010-02-24 13:52:17.000000000 -0500
@@ -66,14 +66,14 @@ LIST_HEAD(fcoe_hostlist);
 DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
 
 /* Function Prototypes */
-static int fcoe_reset(struct Scsi_Host *shost);
+static int fcoe_reset(struct Scsi_Host *);
 static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
 static int fcoe_rcv(struct sk_buff *, struct net_device *,
 		    struct packet_type *, struct net_device *);
-static int fcoe_percpu_receive_thread(void *arg);
-static void fcoe_clean_pending_queue(struct fc_lport *lp);
-static void fcoe_percpu_clean(struct fc_lport *lp);
-static int fcoe_link_ok(struct fc_lport *lp);
+static int fcoe_percpu_receive_thread(void *);
+static void fcoe_clean_pending_queue(struct fc_lport *);
+static void fcoe_percpu_clean(struct fc_lport *);
+static int fcoe_link_ok(struct fc_lport *);
 
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
 static int fcoe_hostlist_add(const struct fc_lport *);
@@ -82,15 +82,77 @@ static void fcoe_check_wait_queue(struct
 static int fcoe_device_notification(struct notifier_block *, ulong, void *);
 static void fcoe_dev_setup(void);
 static void fcoe_dev_cleanup(void);
-static struct fcoe_interface *
-	fcoe_hostlist_lookup_port(const struct net_device *dev);
+static struct fcoe_interface
+*fcoe_hostlist_lookup_port(const struct net_device *);
 
-/* notification function from net device */
+static int fcoe_fip_recv(struct sk_buff *, struct net_device *,
+			 struct packet_type *, struct net_device *);
+
+static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *);
+static void fcoe_update_src_mac(struct fc_lport *, u8 *);
+static u8 *fcoe_get_src_mac(struct fc_lport *);
+static void fcoe_destroy_work(struct work_struct *);
+
+static int fcoe_ddp_setup(struct fc_lport *, u16, struct scatterlist *,
+			  unsigned int);
+static int fcoe_ddp_done(struct fc_lport *, u16);
+
+static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *);
+
+static int fcoe_create(const char *, struct kernel_param *);
+static int fcoe_destroy(const char *, struct kernel_param *);
+static int fcoe_enable(const char *, struct kernel_param *);
+static int fcoe_disable(const char *, struct kernel_param *);
+
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
+				      u32 did, struct fc_frame *,
+				      unsigned int op,
+				      void (*resp)(struct fc_seq *,
+						   struct fc_frame *,
+						   void *),
+				      void *, u32 timeout);
+static void fcoe_recv_frame(struct sk_buff *skb);
+
+static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
+
+module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(create, "string");
+MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
+module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(destroy, "string");
+MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface");
+module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(enable, "string");
+MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface.");
+module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(disable, "string");
+MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");
+
+/* notification function for packets from net device */
 static struct notifier_block fcoe_notifier = {
 	.notifier_call = fcoe_device_notification,
 };
 
-static struct scsi_transport_template *scsi_transport_fcoe_sw;
+/* notification function for CPU hotplug events */
+static struct notifier_block fcoe_cpu_notifier = {
+	.notifier_call = fcoe_cpu_callback,
+};
+
+static struct scsi_transport_template *fcoe_transport_template;
+static struct scsi_transport_template *fcoe_vport_transport_template;
+
+static int fcoe_vport_destroy(struct fc_vport *);
+static int fcoe_vport_create(struct fc_vport *, bool disabled);
+static int fcoe_vport_disable(struct fc_vport *, bool disable);
+static void fcoe_set_vport_symbolic_name(struct fc_vport *);
+
+static struct libfc_function_template fcoe_libfc_fcn_templ = {
+	.frame_send = fcoe_xmit,
+	.ddp_setup = fcoe_ddp_setup,
+	.ddp_done = fcoe_ddp_done,
+	.elsct_send = fcoe_elsct_send,
+	.get_lesb = fcoe_get_lesb,
+};
 
 struct fc_function_template fcoe_transport_function = {
 	.show_host_node_name = 1,
@@ -123,6 +185,48 @@ struct fc_function_template fcoe_transpo
 	.issue_fc_host_lip = fcoe_reset,
 
 	.terminate_rport_io = fc_rport_terminate_io,
+
+	.vport_create = fcoe_vport_create,
+	.vport_delete = fcoe_vport_destroy,
+	.vport_disable = fcoe_vport_disable,
+	.set_vport_symbolic_name = fcoe_set_vport_symbolic_name,
+
+	.bsg_request = fc_lport_bsg_request,
+};
+
+struct fc_function_template fcoe_vport_transport_function = {
+	.show_host_node_name = 1,
+	.show_host_port_name = 1,
+	.show_host_supported_classes = 1,
+	.show_host_supported_fc4s = 1,
+	.show_host_active_fc4s = 1,
+	.show_host_maxframe_size = 1,
+
+	.show_host_port_id = 1,
+	.show_host_supported_speeds = 1,
+	.get_host_speed = fc_get_host_speed,
+	.show_host_speed = 1,
+	.show_host_port_type = 1,
+	.get_host_port_state = fc_get_host_port_state,
+	.show_host_port_state = 1,
+	.show_host_symbolic_name = 1,
+
+	.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
+	.show_rport_maxframe_size = 1,
+	.show_rport_supported_classes = 1,
+
+	.show_host_fabric_name = 1,
+	.show_starget_node_name = 1,
+	.show_starget_port_name = 1,
+	.show_starget_port_id = 1,
+	.set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
+	.show_rport_dev_loss_tmo = 1,
+	.get_fc_host_stats = fc_get_host_stats,
+	.issue_fc_host_lip = fcoe_reset,
+
+	.terminate_rport_io = fc_rport_terminate_io,
+
+	.bsg_request = fc_lport_bsg_request,
 };
 
 static struct scsi_host_template fcoe_shost_template = {
@@ -137,20 +241,17 @@ static struct scsi_host_template fcoe_sh
 	.change_queue_depth = fc_change_queue_depth,
 	.change_queue_type = fc_change_queue_type,
 	.this_id = -1,
-	.cmd_per_lun = 32,
+	.cmd_per_lun = 3,
 	.can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
 	.use_clustering = ENABLE_CLUSTERING,
 	.sg_tablesize = SG_ALL,
 	.max_sectors = 0xffff,
 };
 
-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
-			 struct packet_type *ptype,
-			 struct net_device *orig_dev);
 /**
- * fcoe_interface_setup()
- * @fcoe: new fcoe_interface
- * @netdev : ptr to the associated netdevice struct
+ * fcoe_interface_setup() - Setup a FCoE interface
+ * @fcoe:   The new FCoE interface
+ * @netdev: The net device that the fcoe interface is on
  *
  * Returns : 0 for success
  * Locking: must be called with the RTNL mutex held
@@ -160,23 +261,36 @@ static int fcoe_interface_setup(struct f
 {
 	struct fcoe_ctlr *fip = &fcoe->ctlr;
 	struct netdev_hw_addr *ha;
+	struct net_device *real_dev;
 	u8 flogi_maddr[ETH_ALEN];
+	const struct net_device_ops *ops;
 
 	fcoe->netdev = netdev;
 
+	/* Let LLD initialize for FCoE */
+	ops = netdev->netdev_ops;
+	if (ops->ndo_fcoe_enable) {
+		if (ops->ndo_fcoe_enable(netdev))
+			FCOE_NETDEV_DBG(netdev, "Failed to enable FCoE"
+					" specific feature for LLD.\n");
+	}
+
 	/* Do not support for bonding device */
 	if ((netdev->priv_flags & IFF_MASTER_ALB) ||
 	    (netdev->priv_flags & IFF_SLAVE_INACTIVE) ||
 	    (netdev->priv_flags & IFF_MASTER_8023AD)) {
+		FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n");
 		return -EOPNOTSUPP;
 	}
 
 	/* look for SAN MAC address, if multiple SAN MACs exist, only
 	 * use the first one for SPMA */
+	real_dev = (netdev->priv_flags & IFF_802_1Q_VLAN) ?
+		vlan_dev_real_dev(netdev) : netdev;
 	rcu_read_lock();
-	for_each_dev_addr(netdev, ha) {
+	for_each_dev_addr(real_dev, ha) {
 		if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
-		    (is_valid_ether_addr(fip->ctl_src_addr))) {
+		    (is_valid_ether_addr(ha->addr))) {
 			memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN);
 			fip->spma = 1;
 			break;
@@ -216,19 +330,16 @@ static int fcoe_interface_setup(struct f
 	return 0;
 }
 
-static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb);
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new);
-static void fcoe_destroy_work(struct work_struct *work);
-
 /**
- * fcoe_interface_create()
- * @netdev: network interface
+ * fcoe_interface_create() - Create a FCoE interface on a net device
+ * @netdev: The net device to create the FCoE interface on
  *
  * Returns: pointer to a struct fcoe_interface or NULL on error
  */
 static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev)
 {
 	struct fcoe_interface *fcoe;
+	int err;
 
 	fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
 	if (!fcoe) {
@@ -245,15 +356,22 @@ static struct fcoe_interface *fcoe_inter
 	fcoe_ctlr_init(&fcoe->ctlr);
 	fcoe->ctlr.send = fcoe_fip_send;
 	fcoe->ctlr.update_mac = fcoe_update_src_mac;
+	fcoe->ctlr.get_src_addr = fcoe_get_src_mac;
 
-	fcoe_interface_setup(fcoe, netdev);
+	err = fcoe_interface_setup(fcoe, netdev);
+	if (err) {
+		fcoe_ctlr_destroy(&fcoe->ctlr);
+		kfree(fcoe);
+		dev_put(netdev);
+		return NULL;
+	}
 
 	return fcoe;
 }
 
 /**
- * fcoe_interface_cleanup() - clean up netdev configurations
- * @fcoe:
+ * fcoe_interface_cleanup() - Clean up a FCoE interface
+ * @fcoe: The FCoE interface to be cleaned up
  *
  * Caller must be holding the RTNL mutex
  */
@@ -262,6 +380,7 @@ void fcoe_interface_cleanup(struct fcoe_
 	struct net_device *netdev = fcoe->netdev;
 	struct fcoe_ctlr *fip = &fcoe->ctlr;
 	u8 flogi_maddr[ETH_ALEN];
+	const struct net_device_ops *ops;
 
 	/*
 	 * Don't listen for Ethernet packets anymore.
@@ -276,16 +395,22 @@ void fcoe_interface_cleanup(struct fcoe_
 	/* Delete secondary MAC addresses */
 	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
 	dev_unicast_delete(netdev, flogi_maddr);
-	if (!is_zero_ether_addr(fip->data_src_addr))
-		dev_unicast_delete(netdev, fip->data_src_addr);
 	if (fip->spma)
 		dev_unicast_delete(netdev, fip->ctl_src_addr);
 	dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+
+	/* Tell the LLD we are done w/ FCoE */
+	ops = netdev->netdev_ops;
+	if (ops->ndo_fcoe_disable) {
+		if (ops->ndo_fcoe_disable(netdev))
+			FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
+					" specific feature for LLD.\n");
+	}
 }
 
 /**
  * fcoe_interface_release() - fcoe_port kref release function
- * @kref: embedded reference count in an fcoe_interface struct
+ * @kref: Embedded reference count in an fcoe_interface struct
  */
 static void fcoe_interface_release(struct kref *kref)
 {
@@ -301,8 +426,8 @@ static void fcoe_interface_release(struc
 }
 
 /**
- * fcoe_interface_get()
- * @fcoe:
+ * fcoe_interface_get() - Get a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be held
  */
 static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
 {
@@ -310,8 +435,8 @@ static inline void fcoe_interface_get(st
 }
 
 /**
- * fcoe_interface_put()
- * @fcoe:
+ * fcoe_interface_put() - Put a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be released
  */
 static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
 {
@@ -319,15 +444,16 @@ static inline void fcoe_interface_put(st
 }
 
 /**
- * fcoe_fip_recv - handle a received FIP frame.
- * @skb: the receive skb
- * @dev: associated &net_device
- * @ptype: the &packet_type structure which was used to register this handler.
- * @orig_dev: original receive &net_device, in case @dev is a bond.
+ * fcoe_fip_recv() - Handler for received FIP frames
+ * @skb:      The receive skb
+ * @netdev:   The associated net device
+ * @ptype:    The packet_type structure which was used to register this handler
+ * @orig_dev: The original net_device the the skb was received on.
+ *	      (in case dev is a bond)
  *
  * Returns: 0 for success
  */
-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev,
 			 struct packet_type *ptype,
 			 struct net_device *orig_dev)
 {
@@ -339,9 +465,9 @@ static int fcoe_fip_recv(struct sk_buff
 }
 
 /**
- * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
- * @fip: FCoE controller.
- * @skb: FIP Packet.
+ * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame
+ * @fip: The FCoE controller
+ * @skb: The FIP packet to be sent
  */
 static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
@@ -350,88 +476,118 @@ static void fcoe_fip_send(struct fcoe_ct
 }
 
 /**
- * fcoe_update_src_mac() - Update Ethernet MAC filters.
- * @fip: FCoE controller.
- * @old: Unicast MAC address to delete if the MAC is non-zero.
- * @new: Unicast MAC address to add.
+ * fcoe_update_src_mac() - Update the Ethernet MAC filters
+ * @lport: The local port to update the source MAC on
+ * @addr:  Unicast MAC address to add
  *
  * Remove any previously-set unicast MAC filter.
  * Add secondary FCoE MAC address filter for our OUI.
  */
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
 {
-	struct fcoe_interface *fcoe;
+	struct fcoe_port *port = lport_priv(lport);
+	struct fcoe_interface *fcoe = port->fcoe;
 
-	fcoe = fcoe_from_ctlr(fip);
 	rtnl_lock();
-	if (!is_zero_ether_addr(old))
-		dev_unicast_delete(fcoe->netdev, old);
-	dev_unicast_add(fcoe->netdev, new);
+	if (!is_zero_ether_addr(port->data_src_addr))
+		dev_unicast_delete(fcoe->netdev, port->data_src_addr);
+	if (!is_zero_ether_addr(addr))
+		dev_unicast_add(fcoe->netdev, addr);
+	memcpy(port->data_src_addr, addr, ETH_ALEN);
 	rtnl_unlock();
 }
 
 /**
- * fcoe_lport_config() - sets up the fc_lport
- * @lp: ptr to the fc_lport
+ * fcoe_get_src_mac() - return the Ethernet source address for an lport
+ * @lport: libfc lport
+ */
+static u8 *fcoe_get_src_mac(struct fc_lport *lport)
+{
+	struct fcoe_port *port = lport_priv(lport);
+
+	return port->data_src_addr;
+}
+
+/**
+ * fcoe_lport_config() - Set up a local port
+ * @lport: The local port to be setup
  *
  * Returns: 0 for success
  */
-static int fcoe_lport_config(struct fc_lport *lp)
+static int fcoe_lport_config(struct fc_lport *lport)
 {
-	lp->link_up = 0;
-	lp->qfull = 0;
-	lp->max_retry_count = 3;
-	lp->max_rport_retry_count = 3;
-	lp->e_d_tov = 2 * 1000;	/* FC-FS default */
-	lp->r_a_tov = 2 * 2 * 1000;
-	lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
-			      FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+	lport->link_up = 0;
+	lport->qfull = 0;
+	lport->max_retry_count = 3;
+	lport->max_rport_retry_count = 3;
+	lport->e_d_tov = 2 * 1000;	/* FC-FS default */
+	lport->r_a_tov = 2 * 2 * 1000;
+	lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
+				 FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+	lport->does_npiv = 1;
 
-	fc_lport_init_stats(lp);
+	fc_lport_init_stats(lport);
 
 	/* lport fc_lport related configuration */
-	fc_lport_config(lp);
+	fc_lport_config(lport);
 
 	/* offload related configuration */
-	lp->crc_offload = 0;
-	lp->seq_offload = 0;
-	lp->lro_enabled = 0;
-	lp->lro_xid = 0;
-	lp->lso_max = 0;
+	lport->crc_offload = 0;
+	lport->seq_offload = 0;
+	lport->lro_enabled = 0;
+	lport->lro_xid = 0;
+	lport->lso_max = 0;
 
 	return 0;
 }
 
 /**
- * fcoe_queue_timer() - fcoe queue timer
- * @lp: the fc_lport pointer
+ * fcoe_queue_timer() - The fcoe queue timer
+ * @lport: The local port
  *
  * Calls fcoe_check_wait_queue on timeout
+ */
+static void fcoe_queue_timer(ulong lport)
+{
+	fcoe_check_wait_queue((struct fc_lport *)lport, NULL);
+}
+
+/**
+ * fcoe_get_wwn() - Get the world wide name from LLD if it supports it
+ * @netdev: the associated net device
+ * @wwn: the output WWN
+ * @type: the type of WWN (WWPN or WWNN)
  *
+ * Returns: 0 for success
  */
-static void fcoe_queue_timer(ulong lp)
+static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
 {
-	fcoe_check_wait_queue((struct fc_lport *)lp, NULL);
+	const struct net_device_ops *ops = netdev->netdev_ops;
+
+	if (ops->ndo_fcoe_get_wwn)
+		return ops->ndo_fcoe_get_wwn(netdev, wwn, type);
+	return -EINVAL;
 }
 
 /**
- * fcoe_netdev_config() - Set up netdev for SW FCoE
- * @lp : ptr to the fc_lport
- * @netdev : ptr to the associated netdevice struct
+ * fcoe_netdev_config() - Set up net devive for SW FCoE
+ * @lport:  The local port that is associated with the net device
+ * @netdev: The associated net device
  *
- * Must be called after fcoe_lport_config() as it will use lport mutex
+ * Must be called after fcoe_lport_config() as it will use local port mutex
  *
- * Returns : 0 for success
+ * Returns: 0 for success
  */
-static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
+static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
 {
 	u32 mfs;
 	u64 wwnn, wwpn;
 	struct fcoe_interface *fcoe;
 	struct fcoe_port *port;
+	int vid = 0;
 
 	/* Setup lport private data to point to fcoe softc */
-	port = lport_priv(lp);
+	port = lport_priv(lport);
 	fcoe = port->fcoe;
 
 	/*
@@ -439,86 +595,116 @@ static int fcoe_netdev_config(struct fc_
 	 * user-configured limit.  If the MFS is too low, fcoe_link_ok()
 	 * will return 0, so do this first.
 	 */
-	mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
-			     sizeof(struct fcoe_crc_eof));
-	if (fc_set_mfs(lp, mfs))
+	mfs = netdev->mtu;
+	if (netdev->features & NETIF_F_FCOE_MTU) {
+		mfs = FCOE_MTU;
+		FCOE_NETDEV_DBG(netdev, "Supports FCOE_MTU of %d bytes\n", mfs);
+	}
+	mfs -= (sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof));
+	if (fc_set_mfs(lport, mfs))
 		return -EINVAL;
 
 	/* offload features support */
 	if (netdev->features & NETIF_F_SG)
-		lp->sg_supp = 1;
+		lport->sg_supp = 1;
 
 	if (netdev->features & NETIF_F_FCOE_CRC) {
-		lp->crc_offload = 1;
+		lport->crc_offload = 1;
 		FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
 	}
 	if (netdev->features & NETIF_F_FSO) {
-		lp->seq_offload = 1;
-		lp->lso_max = netdev->gso_max_size;
+		lport->seq_offload = 1;
+		lport->lso_max = netdev->gso_max_size;
 		FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
-				lp->lso_max);
+				lport->lso_max);
 	}
 	if (netdev->fcoe_ddp_xid) {
-		lp->lro_enabled = 1;
-		lp->lro_xid = netdev->fcoe_ddp_xid;
+		lport->lro_enabled = 1;
+		lport->lro_xid = netdev->fcoe_ddp_xid;
 		FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
-				lp->lro_xid);
+				lport->lro_xid);
 	}
 	skb_queue_head_init(&port->fcoe_pending_queue);
 	port->fcoe_pending_queue_active = 0;
-	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lp);
+	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport);
 
-	wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0);
-	fc_set_wwnn(lp, wwnn);
-	/* XXX - 3rd arg needs to be vlan id */
-	wwpn = fcoe_wwn_from_mac(netdev->dev_addr, 2, 0);
-	fc_set_wwpn(lp, wwpn);
+	if (!lport->vport) {
+		/*
+		 * Use NAA 1&2 (FC-FS Rev. 2.0, Sec. 15) to generate WWNN/WWPN:
+		 * For WWNN, we use NAA 1 w/ bit 27-16 of word 0 as 0.
+		 * For WWPN, we use NAA 2 w/ bit 27-16 of word 0 from VLAN ID
+		 */
+		if (netdev->priv_flags & IFF_802_1Q_VLAN)
+			vid = vlan_dev_vlan_id(netdev);
+
+		if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
+			wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0);
+		fc_set_wwnn(lport, wwnn);
+		if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
+			wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr,
+						 2, vid);
+		fc_set_wwpn(lport, wwpn);
+	}
 
 	return 0;
 }
 
 /**
- * fcoe_shost_config() - Sets up fc_lport->host
- * @lp : ptr to the fc_lport
- * @shost : ptr to the associated scsi host
- * @dev : device associated to scsi host
+ * fcoe_shost_config() - Set up the SCSI host associated with a local port
+ * @lport: The local port
+ * @shost: The SCSI host to associate with the local port
+ * @dev:   The device associated with the SCSI host
  *
  * Must be called after fcoe_lport_config() and fcoe_netdev_config()
  *
- * Returns : 0 for success
+ * Returns: 0 for success
  */
-static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
-				struct device *dev)
+static int fcoe_shost_config(struct fc_lport *lport, struct Scsi_Host *shost,
+			     struct device *dev)
 {
 	int rc = 0;
 
 	/* lport scsi host config */
-	lp->host = shost;
-
-	lp->host->max_lun = FCOE_MAX_LUN;
-	lp->host->max_id = FCOE_MAX_FCP_TARGET;
-	lp->host->max_channel = 0;
-	lp->host->transportt = scsi_transport_fcoe_sw;
+	lport->host->max_lun = FCOE_MAX_LUN;
+	lport->host->max_id = FCOE_MAX_FCP_TARGET;
+	lport->host->max_channel = 0;
+	if (lport->vport)
+		lport->host->transportt = fcoe_vport_transport_template;
+	else
+		lport->host->transportt = fcoe_transport_template;
 
 	/* add the new host to the SCSI-ml */
-	rc = scsi_add_host(lp->host, dev);
+	rc = scsi_add_host(lport->host, dev);
 	if (rc) {
-		FCOE_NETDEV_DBG(fcoe_netdev(lp), "fcoe_shost_config: "
+		FCOE_NETDEV_DBG(fcoe_netdev(lport), "fcoe_shost_config: "
 				"error on scsi_add_host\n");
 		return rc;
 	}
-	sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
-		FCOE_NAME, FCOE_VERSION,
-		fcoe_netdev(lp)->name);
+
+	if (!lport->vport)
+		fc_host_max_npiv_vports(lport->host) = USHORT_MAX;
+
+	snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
+		 "%s v%s over %s", FCOE_NAME, FCOE_VERSION,
+		 fcoe_netdev(lport)->name);
 
 	return 0;
 }
 
-/*
- * fcoe_oem_match() - match for read types IO
- * @fp: the fc_frame for new IO.
+/**
+ * fcoe_oem_match() - The match routine for the offloaded exchange manager
+ * @fp: The I/O frame
  *
- * Returns : true for read types IO, otherwise returns false.
+ * This routine will be associated with an exchange manager (EM). When
+ * the libfc exchange handling code is looking for an EM to use it will
+ * call this routine and pass it the frame that it wishes to send. This
+ * routine will return True if the associated EM is to be used and False
+ * if the echange code should continue looking for an EM.
+ *
+ * The offload EM that this routine is associated with will handle any
+ * packets that are for SCSI read requests.
+ *
+ * Returns: True for read types I/O, otherwise returns false.
  */
 bool fcoe_oem_match(struct fc_frame *fp)
 {
@@ -527,14 +713,14 @@ bool fcoe_oem_match(struct fc_frame *fp)
 }
 
 /**
- * fcoe_em_config() - allocates em for this lport
- * @lp: the fcoe that em is to allocated for
+ * fcoe_em_config() - Allocate and configure an exchange manager
+ * @lport: The local port that the new EM will be associated with
  *
- * Returns : 0 on success
+ * Returns: 0 on success
  */
-static inline int fcoe_em_config(struct fc_lport *lp)
+static inline int fcoe_em_config(struct fc_lport *lport)
 {
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	struct fcoe_interface *fcoe = port->fcoe;
 	struct fcoe_interface *oldfcoe = NULL;
 	struct net_device *old_real_dev, *cur_real_dev;
@@ -545,8 +731,9 @@ static inline int fcoe_em_config(struct
 	 * Check if need to allocate an em instance for
 	 * offload exchange ids to be shared across all VN_PORTs/lport.
 	 */
-	if (!lp->lro_enabled || !lp->lro_xid || (lp->lro_xid >= max_xid)) {
-		lp->lro_xid = 0;
+	if (!lport->lro_enabled || !lport->lro_xid ||
+	    (lport->lro_xid >= max_xid)) {
+		lport->lro_xid = 0;
 		goto skip_oem;
 	}
 
@@ -572,16 +759,16 @@ static inline int fcoe_em_config(struct
 	}
 
 	if (fcoe->oem) {
-		if (!fc_exch_mgr_add(lp, fcoe->oem, fcoe_oem_match)) {
+		if (!fc_exch_mgr_add(lport, fcoe->oem, fcoe_oem_match)) {
 			printk(KERN_ERR "fcoe_em_config: failed to add "
 			       "offload em:%p on interface:%s\n",
 			       fcoe->oem, fcoe->netdev->name);
 			return -ENOMEM;
 		}
 	} else {
-		fcoe->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3,
-					    FCOE_MIN_XID, lp->lro_xid,
-					    fcoe_oem_match);
+		fcoe->oem = fc_exch_mgr_alloc(lport, FC_CLASS_3,
+					      FCOE_MIN_XID, lport->lro_xid,
+					      fcoe_oem_match);
 		if (!fcoe->oem) {
 			printk(KERN_ERR "fcoe_em_config: failed to allocate "
 			       "em for offload exches on interface:%s\n",
@@ -593,10 +780,10 @@ static inline int fcoe_em_config(struct
 	/*
 	 * Exclude offload EM xid range from next EM xid range.
 	 */
-	min_xid += lp->lro_xid + 1;
+	min_xid += lport->lro_xid + 1;
 
 skip_oem:
-	if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) {
+	if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, min_xid, max_xid, NULL)) {
 		printk(KERN_ERR "fcoe_em_config: failed to "
 		       "allocate em on interface %s\n", fcoe->netdev->name);
 		return -ENOMEM;
@@ -606,8 +793,8 @@ skip_oem:
 }
 
 /**
- * fcoe_if_destroy() - FCoE software HBA tear-down function
- * @lport: fc_lport to destroy
+ * fcoe_if_destroy() - Tear down a SW FCoE instance
+ * @lport: The local port to be destroyed
  */
 static void fcoe_if_destroy(struct fc_lport *lport)
 {
@@ -630,6 +817,11 @@ static void fcoe_if_destroy(struct fc_lp
 	/* Free existing transmit skbs */
 	fcoe_clean_pending_queue(lport);
 
+	rtnl_lock();
+	if (!is_zero_ether_addr(port->data_src_addr))
+		dev_unicast_delete(netdev, port->data_src_addr);
+	rtnl_unlock();
+
 	/* receives may not be stopped until after this */
 	fcoe_interface_put(fcoe);
 
@@ -650,82 +842,89 @@ static void fcoe_if_destroy(struct fc_lp
 	scsi_host_put(lport->host);
 }
 
-/*
- * fcoe_ddp_setup - calls LLD's ddp_setup through net_device
- * @lp:	the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- * @sgl: the scatterlist describing this transfer
- * @sgc: number of sg items
+/**
+ * fcoe_ddp_setup() - Call a LLD's ddp_setup through the net device
+ * @lport: The local port to setup DDP for
+ * @xid:   The exchange ID for this DDP transfer
+ * @sgl:   The scatterlist describing this transfer
+ * @sgc:   The number of sg items
  *
- * Returns : 0 no ddp
+ * Returns: 0 if the DDP context was not configured
  */
-static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
-			     struct scatterlist *sgl, unsigned int sgc)
+static int fcoe_ddp_setup(struct fc_lport *lport, u16 xid,
+			  struct scatterlist *sgl, unsigned int sgc)
 {
-	struct net_device *n = fcoe_netdev(lp);
+	struct net_device *netdev = fcoe_netdev(lport);
 
-	if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
-		return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+	if (netdev->netdev_ops->ndo_fcoe_ddp_setup)
+		return netdev->netdev_ops->ndo_fcoe_ddp_setup(netdev,
+							      xid, sgl,
+							      sgc);
 
 	return 0;
 }
 
-/*
- * fcoe_ddp_done - calls LLD's ddp_done through net_device
- * @lp:	the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
+/**
+ * fcoe_ddp_done() - Call a LLD's ddp_done through the net device
+ * @lport: The local port to complete DDP on
+ * @xid:   The exchange ID for this DDP transfer
  *
- * Returns : the length of data that have been completed by ddp
+ * Returns: the length of data that have been completed by DDP
  */
-static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
+static int fcoe_ddp_done(struct fc_lport *lport, u16 xid)
 {
-	struct net_device *n = fcoe_netdev(lp);
+	struct net_device *netdev = fcoe_netdev(lport);
 
-	if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
-		return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
+	if (netdev->netdev_ops->ndo_fcoe_ddp_done)
+		return netdev->netdev_ops->ndo_fcoe_ddp_done(netdev, xid);
 	return 0;
 }
 
-static struct libfc_function_template fcoe_libfc_fcn_templ = {
-	.frame_send = fcoe_xmit,
-	.ddp_setup = fcoe_ddp_setup,
-	.ddp_done = fcoe_ddp_done,
-};
-
 /**
- * fcoe_if_create() - this function creates the fcoe port
- * @fcoe: fcoe_interface structure to create an fc_lport instance on
- * @parent: device pointer to be the parent in sysfs for the SCSI host
+ * fcoe_if_create() - Create a FCoE instance on an interface
+ * @fcoe:   The FCoE interface to create a local port on
+ * @parent: The device pointer to be the parent in sysfs for the SCSI host
+ * @npiv:   Indicates if the port is a vport or not
  *
- * Creates fc_lport struct and scsi_host for lport, configures lport.
+ * Creates a fc_lport instance and a Scsi_Host instance and configure them.
  *
- * Returns : The allocated fc_lport or an error pointer
+ * Returns: The allocated fc_lport or an error pointer
  */
 static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
-				       struct device *parent)
+				       struct device *parent, int npiv)
 {
-	int rc;
+	struct net_device *netdev = fcoe->netdev;
 	struct fc_lport *lport = NULL;
 	struct fcoe_port *port;
 	struct Scsi_Host *shost;
-	struct net_device *netdev = fcoe->netdev;
+	int rc;
+	/*
+	 * parent is only a vport if npiv is 1,
+	 * but we'll only use vport in that case so go ahead and set it
+	 */
+	struct fc_vport *vport = dev_to_vport(parent);
 
 	FCOE_NETDEV_DBG(netdev, "Create Interface\n");
 
-	shost = libfc_host_alloc(&fcoe_shost_template,
-				 sizeof(struct fcoe_port));
-	if (!shost) {
+	if (!npiv) {
+		lport = libfc_host_alloc(&fcoe_shost_template,
+					 sizeof(struct fcoe_port));
+	} else	{
+		lport = libfc_vport_create(vport,
+					   sizeof(struct fcoe_port));
+	}
+	if (!lport) {
 		FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
 		rc = -ENOMEM;
 		goto out;
 	}
-	lport = shost_priv(shost);
+	shost = lport->host;
 	port = lport_priv(lport);
 	port->lport = lport;
 	port->fcoe = fcoe;
 	INIT_WORK(&port->destroy_work, fcoe_destroy_work);
 
-	/* configure fc_lport, e.g., em */
+	/* configure a fc_lport including the exchange manager */
 	rc = fcoe_lport_config(lport);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure lport for the "
@@ -733,6 +932,13 @@ static struct fc_lport *fcoe_if_create(s
 		goto out_host_put;
 	}
 
+	if (npiv) {
+		FCOE_NETDEV_DBG(netdev, "Setting vport names, 0x%llX 0x%llX\n",
+				vport->node_name, vport->port_name);
+		fc_set_wwnn(lport, vport->node_name);
+		fc_set_wwpn(lport, vport->port_name);
+	}
+
 	/* configure lport network properties */
 	rc = fcoe_netdev_config(lport, netdev);
 	if (rc) {
@@ -757,21 +963,24 @@ static struct fc_lport *fcoe_if_create(s
 		goto out_lp_destroy;
 	}
 
-	/*
-	 * fcoe_em_alloc() and fcoe_hostlist_add() both
-	 * need to be atomic with respect to other changes to the hostlist
-	 * since fcoe_em_alloc() looks for an existing EM
-	 * instance on host list updated by fcoe_hostlist_add().
-	 *
-	 * This is currently handled through the fcoe_config_mutex begin held.
-	 */
+	if (!npiv) {
+		/*
+		 * fcoe_em_alloc() and fcoe_hostlist_add() both
+		 * need to be atomic with respect to other changes to the
+		 * hostlist since fcoe_em_alloc() looks for an existing EM
+		 * instance on host list updated by fcoe_hostlist_add().
+		 *
+		 * This is currently handled through the fcoe_config_mutex
+		 * begin held.
+		 */
 
-	/* lport exch manager allocation */
-	rc = fcoe_em_config(lport);
-	if (rc) {
-		FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
-				"interface\n");
-		goto out_lp_destroy;
+		/* lport exch manager allocation */
+		rc = fcoe_em_config(lport);
+		if (rc) {
+			FCOE_NETDEV_DBG(netdev, "Could not configure the EM "
+					"for the interface\n");
+			goto out_lp_destroy;
+		}
 	}
 
 	fcoe_interface_get(fcoe);
@@ -786,17 +995,20 @@ out:
 }
 
 /**
- * fcoe_if_init() - attach to scsi transport
+ * fcoe_if_init() - Initialization routine for fcoe.ko
  *
- * Returns : 0 on success
+ * Attaches the SW FCoE transport to the FC transport
+ *
+ * Returns: 0 on success
  */
 static int __init fcoe_if_init(void)
 {
 	/* attach to scsi transport */
-	scsi_transport_fcoe_sw =
-		fc_attach_transport(&fcoe_transport_function);
+	fcoe_transport_template = fc_attach_transport(&fcoe_transport_function);
+	fcoe_vport_transport_template =
+		fc_attach_transport(&fcoe_vport_transport_function);
 
-	if (!scsi_transport_fcoe_sw) {
+	if (!fcoe_transport_template) {
 		printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n");
 		return -ENODEV;
 	}
@@ -805,20 +1017,24 @@ static int __init fcoe_if_init(void)
 }
 
 /**
- * fcoe_if_exit() - detach from scsi transport
+ * fcoe_if_exit() - Tear down fcoe.ko
  *
- * Returns : 0 on success
+ * Detaches the SW FCoE transport from the FC transport
+ *
+ * Returns: 0 on success
  */
 int __exit fcoe_if_exit(void)
 {
-	fc_release_transport(scsi_transport_fcoe_sw);
-	scsi_transport_fcoe_sw = NULL;
+	fc_release_transport(fcoe_transport_template);
+	fc_release_transport(fcoe_vport_transport_template);
+	fcoe_transport_template = NULL;
+	fcoe_vport_transport_template = NULL;
 	return 0;
 }
 
 /**
- * fcoe_percpu_thread_create() - Create a receive thread for an online cpu
- * @cpu: cpu index for the online cpu
+ * fcoe_percpu_thread_create() - Create a receive thread for an online CPU
+ * @cpu: The CPU index of the CPU to create a receive thread for
  */
 static void fcoe_percpu_thread_create(unsigned int cpu)
 {
@@ -841,8 +1057,8 @@ static void fcoe_percpu_thread_create(un
 }
 
 /**
- * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu
- * @cpu: cpu index the rx thread is to be removed
+ * fcoe_percpu_thread_destroy() - Remove the receive thread of a CPU
+ * @cpu: The CPU index of the CPU whose receive thread is to be destroyed
  *
  * Destroys a per-CPU Rx thread. Any pending skbs are moved to the
  * current CPU's Rx thread. If the thread being destroyed is bound to
@@ -890,7 +1106,7 @@ static void fcoe_percpu_thread_destroy(u
 		} else {
 			/*
 			 * The targeted CPU is not initialized and cannot accept
-			 * new  skbs. Unlock the targeted CPU and drop the skbs
+			 * new	skbs. Unlock the targeted CPU and drop the skbs
 			 * on the CPU that is going offline.
 			 */
 			while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
@@ -931,12 +1147,12 @@ static void fcoe_percpu_thread_destroy(u
 }
 
 /**
- * fcoe_cpu_callback() - fcoe cpu hotplug event callback
- * @nfb: callback data block
- * @action: event triggering the callback
- * @hcpu: index for the cpu of this event
+ * fcoe_cpu_callback() - Handler for CPU hotplug events
+ * @nfb:    The callback data block
+ * @action: The event triggering the callback
+ * @hcpu:   The index of the CPU that the event is for
  *
- * This creates or destroys per cpu data for fcoe
+ * This creates or destroys per-CPU data for fcoe
  *
  * Returns NOTIFY_OK always.
  */
@@ -962,25 +1178,22 @@ static int fcoe_cpu_callback(struct noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block fcoe_cpu_notifier = {
-	.notifier_call = fcoe_cpu_callback,
-};
-
 /**
- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
- * @skb: the receive skb
- * @dev: associated net device
- * @ptype: context
- * @olddev: last device
+ * fcoe_rcv() - Receive packets from a net device
+ * @skb:    The received packet
+ * @netdev: The net device that the packet was received on
+ * @ptype:  The packet type context
+ * @olddev: The last device net device
  *
- * this function will receive the packet and build fc frame and pass it up
+ * This routine is called by NET_RX_SOFTIRQ. It receives a packet, builds a
+ * FC frame and passes the frame to libfc.
  *
  * Returns: 0 for success
  */
-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
+int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
 	     struct packet_type *ptype, struct net_device *olddev)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fcoe_rcv_info *fr;
 	struct fcoe_interface *fcoe;
 	struct fc_frame_header *fh;
@@ -988,15 +1201,15 @@ int fcoe_rcv(struct sk_buff *skb, struct
 	unsigned int cpu;
 
 	fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type);
-	lp = fcoe->ctlr.lp;
-	if (unlikely(lp == NULL)) {
-		FCOE_NETDEV_DBG(dev, "Cannot find hba structure");
+	lport = fcoe->ctlr.lp;
+	if (unlikely(!lport)) {
+		FCOE_NETDEV_DBG(netdev, "Cannot find hba structure");
 		goto err2;
 	}
-	if (!lp->link_up)
+	if (!lport->link_up)
 		goto err2;
 
-	FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p "
+	FCOE_NETDEV_DBG(netdev, "skb_info: len:%d data_len:%d head:%p "
 			"data:%p tail:%p end:%p sum:%d dev:%s",
 			skb->len, skb->data_len, skb->head, skb->data,
 			skb_tail_pointer(skb), skb_end_pointer(skb),
@@ -1004,7 +1217,7 @@ int fcoe_rcv(struct sk_buff *skb, struct
 
 	/* check for FCOE packet type */
 	if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
-		FCOE_NETDEV_DBG(dev, "Wrong FC type frame");
+		FCOE_NETDEV_DBG(netdev, "Wrong FC type frame");
 		goto err;
 	}
 
@@ -1013,14 +1226,14 @@ int fcoe_rcv(struct sk_buff *skb, struct
 	 * and FC headers are pulled into the linear data area.
 	 */
 	if (unlikely((skb->len < FCOE_MIN_FRAME) ||
-	    !pskb_may_pull(skb, FCOE_HEADER_LEN)))
+		     !pskb_may_pull(skb, FCOE_HEADER_LEN)))
 		goto err;
 
 	skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
 	fh = (struct fc_frame_header *) skb_transport_header(skb);
 
 	fr = fcoe_dev_from_skb(skb);
-	fr->fr_dev = lp;
+	fr->fr_dev = lport;
 	fr->ptype = ptype;
 
 	/*
@@ -1042,12 +1255,12 @@ int fcoe_rcv(struct sk_buff *skb, struct
 		 * the first CPU now. For non-SMP systems this
 		 * will check the same CPU twice.
 		 */
-		FCOE_NETDEV_DBG(dev, "CPU is online, but no receive thread "
+		FCOE_NETDEV_DBG(netdev, "CPU is online, but no receive thread "
 				"ready for incoming skb- using first online "
 				"CPU.\n");
 
 		spin_unlock_bh(&fps->fcoe_rx_list.lock);
-		cpu = first_cpu(cpu_online_map);
+		cpu = cpumask_first(cpu_online_mask);
 		fps = &per_cpu(fcoe_percpu, cpu);
 		spin_lock_bh(&fps->fcoe_rx_list.lock);
 		if (!fps->thread) {
@@ -1061,15 +1274,29 @@ int fcoe_rcv(struct sk_buff *skb, struct
 	 * this skb. We also have this receive thread locked,
 	 * so we're free to queue skbs into it's queue.
 	 */
-	__skb_queue_tail(&fps->fcoe_rx_list, skb);
-	if (fps->fcoe_rx_list.qlen == 1)
-		wake_up_process(fps->thread);
 
-	spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	/* If this is a SCSI-FCP frame, and this is already executing on the
+	 * correct CPU, and the queue for this CPU is empty, then go ahead
+	 * and process the frame directly in the softirq context.
+	 * This lets us process completions without context switching from the
+	 * NET_RX softirq, to our receive processing thread, and then back to
+	 * BLOCK softirq context.
+	 */
+	if (fh->fh_type == FC_TYPE_FCP &&
+	    cpu == smp_processor_id() &&
+	    skb_queue_empty(&fps->fcoe_rx_list)) {
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+		fcoe_recv_frame(skb);
+	} else {
+		__skb_queue_tail(&fps->fcoe_rx_list, skb);
+		if (fps->fcoe_rx_list.qlen == 1)
+			wake_up_process(fps->thread);
+		spin_unlock_bh(&fps->fcoe_rx_list.lock);
+	}
 
 	return 0;
 err:
-	fc_lport_get_stats(lp)->ErrorFrames++;
+	fc_lport_get_stats(lport)->ErrorFrames++;
 
 err2:
 	kfree_skb(skb);
@@ -1077,17 +1304,21 @@ err2:
 }
 
 /**
- * fcoe_start_io() - pass to netdev to start xmit for fcoe
- * @skb: the skb to be xmitted
+ * fcoe_start_io() - Start FCoE I/O
+ * @skb: The packet to be transmitted
+ *
+ * This routine is called from the net device to start transmitting
+ * FCoE packets.
  *
  * Returns: 0 for success
  */
 static inline int fcoe_start_io(struct sk_buff *skb)
 {
+	struct sk_buff *nskb;
 	int rc;
 
-	skb_get(skb);
-	rc = dev_queue_xmit(skb);
+	nskb = skb_clone(skb, GFP_ATOMIC);
+	rc = dev_queue_xmit(nskb);
 	if (rc != 0)
 		return rc;
 	kfree_skb(skb);
@@ -1095,9 +1326,15 @@ static inline int fcoe_start_io(struct s
 }
 
 /**
- * fcoe_get_paged_crc_eof() - in case we need to alloc a page for crc_eof
- * @skb: the skb to be xmitted
- * @tlen: total len
+ * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
+ * @skb:  The packet to be transmitted
+ * @tlen: The total length of the trailer
+ *
+ * This routine allocates a page for frame trailers. The page is re-used if
+ * there is enough room left on it for the current trailer. If there isn't
+ * enough buffer left a new page is allocated for the trailer. Reference to
+ * the page from this function as well as the skbs using the page fragments
+ * ensure that the page is freed at the appropriate time.
  *
  * Returns: 0 for success
  */
@@ -1136,11 +1373,12 @@ static int fcoe_get_paged_crc_eof(struct
 }
 
 /**
- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
- * @fp: the fc_frame containing data to be checksummed
+ * fcoe_fc_crc() - Calculates the CRC for a given frame
+ * @fp: The frame to be checksumed
  *
- * This uses crc32() to calculate the crc for port frame
- * Return   : 32 bit crc
+ * This uses crc32() routine to calculate the CRC for a frame
+ *
+ * Return: The 32 bit CRC value
  */
 u32 fcoe_fc_crc(struct fc_frame *fp)
 {
@@ -1171,13 +1409,13 @@ u32 fcoe_fc_crc(struct fc_frame *fp)
 }
 
 /**
- * fcoe_xmit() - FCoE frame transmit function
- * @lp:	the associated local fcoe
- * @fp: the fc_frame to be transmitted
+ * fcoe_xmit() - Transmit a FCoE frame
+ * @lport: The local port that the frame is to be transmitted for
+ * @fp:	   The frame to be transmitted
  *
- * Return   : 0 for success
+ * Return: 0 for success
  */
-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 {
 	int wlen;
 	u32 crc;
@@ -1189,7 +1427,7 @@ int fcoe_xmit(struct fc_lport *lp, struc
 	unsigned int hlen;		/* header length implies the version */
 	unsigned int tlen;		/* trailer length */
 	unsigned int elen;		/* eth header, may include vlan */
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	struct fcoe_interface *fcoe = port->fcoe;
 	u8 sof, eof;
 	struct fcoe_hdr *hp;
@@ -1200,13 +1438,13 @@ int fcoe_xmit(struct fc_lport *lp, struc
 	skb = fp_skb(fp);
 	wlen = skb->len / FCOE_WORD_TO_BYTE;
 
-	if (!lp->link_up) {
+	if (!lport->link_up) {
 		kfree_skb(skb);
 		return 0;
 	}
 
 	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
-	    fcoe_ctlr_els_send(&fcoe->ctlr, skb))
+	    fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb))
 		return 0;
 
 	sof = fr_sof(fp);
@@ -1218,7 +1456,7 @@ int fcoe_xmit(struct fc_lport *lp, struc
 	wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
 
 	/* crc offload */
-	if (likely(lp->crc_offload)) {
+	if (likely(lport->crc_offload)) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_headroom(skb);
 		skb->csum_offset = skb->len;
@@ -1271,7 +1509,7 @@ int fcoe_xmit(struct fc_lport *lp, struc
 	if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN))
 		memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN);
 	else
-		memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN);
+		memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
 
 	hp = (struct fcoe_hdr *)(eh + 1);
 	memset(hp, 0, sizeof(*hp));
@@ -1280,7 +1518,7 @@ int fcoe_xmit(struct fc_lport *lp, struc
 	hp->fcoe_sof = sof;
 
 	/* fcoe lso, mss is in max_payload which is non-zero for FCP data */
-	if (lp->seq_offload && fr_max_payload(fp)) {
+	if (lport->seq_offload && fr_max_payload(fp)) {
 		skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
 		skb_shinfo(skb)->gso_size = fr_max_payload(fp);
 	} else {
@@ -1288,23 +1526,23 @@ int fcoe_xmit(struct fc_lport *lp, struc
 		skb_shinfo(skb)->gso_size = 0;
 	}
 	/* update tx stats: regardless if LLD fails */
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	stats->TxFrames++;
 	stats->TxWords += wlen;
 
 	/* send down to lld */
-	fr_dev(fp) = lp;
+	fr_dev(fp) = lport;
 	if (port->fcoe_pending_queue.qlen)
-		fcoe_check_wait_queue(lp, skb);
+		fcoe_check_wait_queue(lport, skb);
 	else if (fcoe_start_io(skb))
-		fcoe_check_wait_queue(lp, skb);
+		fcoe_check_wait_queue(lport, skb);
 
 	return 0;
 }
 
 /**
- * fcoe_percpu_flush_done() - Indicate percpu queue flush completion.
- * @skb: the skb being completed.
+ * fcoe_percpu_flush_done() - Indicate per-CPU queue flush completion
+ * @skb: The completed skb (argument required by destructor)
  */
 static void fcoe_percpu_flush_done(struct sk_buff *skb)
 {
@@ -1312,26 +1550,134 @@ static void fcoe_percpu_flush_done(struc
 }
 
 /**
- * fcoe_percpu_receive_thread() - recv thread per cpu
- * @arg: ptr to the fcoe per cpu struct
- *
- * Return: 0 for success
+ * fcoe_recv_frame() - process a single received frame
+ * @skb: frame to process
  */
-int fcoe_percpu_receive_thread(void *arg)
+static void fcoe_recv_frame(struct sk_buff *skb)
 {
-	struct fcoe_percpu_s *p = arg;
 	u32 fr_len;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fcoe_rcv_info *fr;
 	struct fcoe_dev_stats *stats;
 	struct fc_frame_header *fh;
-	struct sk_buff *skb;
 	struct fcoe_crc_eof crc_eof;
 	struct fc_frame *fp;
 	u8 *mac = NULL;
 	struct fcoe_port *port;
 	struct fcoe_hdr *hp;
 
+	fr = fcoe_dev_from_skb(skb);
+	lport = fr->fr_dev;
+	if (unlikely(!lport)) {
+		if (skb->destructor != fcoe_percpu_flush_done)
+			FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
+		kfree_skb(skb);
+		return;
+	}
+
+	FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
+			"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
+			skb->len, skb->data_len,
+			skb->head, skb->data, skb_tail_pointer(skb),
+			skb_end_pointer(skb), skb->csum,
+			skb->dev ? skb->dev->name : "<NULL>");
+
+	/*
+	 * Save source MAC address before discarding header.
+	 */
+	port = lport_priv(lport);
+	if (skb_is_nonlinear(skb))
+		skb_linearize(skb);	/* not ideal */
+	mac = eth_hdr(skb)->h_source;
+
+	/*
+	 * Frame length checks and setting up the header pointers
+	 * was done in fcoe_rcv already.
+	 */
+	hp = (struct fcoe_hdr *) skb_network_header(skb);
+	fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+	stats = fc_lport_get_stats(lport);
+	if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
+		if (stats->ErrorFrames < 5)
+			printk(KERN_WARNING "fcoe: FCoE version "
+			       "mismatch: The frame has "
+			       "version %x, but the "
+			       "initiator supports version "
+			       "%x\n", FC_FCOE_DECAPS_VER(hp),
+			       FC_FCOE_VER);
+		stats->ErrorFrames++;
+		kfree_skb(skb);
+		return;
+	}
+
+	skb_pull(skb, sizeof(struct fcoe_hdr));
+	fr_len = skb->len - sizeof(struct fcoe_crc_eof);
+
+	stats->RxFrames++;
+	stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
+	fp = (struct fc_frame *)skb;
+	fc_frame_init(fp);
+	fr_dev(fp) = lport;
+	fr_sof(fp) = hp->fcoe_sof;
+
+	/* Copy out the CRC and EOF trailer for access */
+	if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
+		kfree_skb(skb);
+		return;
+	}
+	fr_eof(fp) = crc_eof.fcoe_eof;
+	fr_crc(fp) = crc_eof.fcoe_crc32;
+	if (pskb_trim(skb, fr_len)) {
+		kfree_skb(skb);
+		return;
+	}
+
+	/*
+	 * We only check CRC if no offload is available and if it is
+	 * it's solicited data, in which case, the FCP layer would
+	 * check it during the copy.
+	 */
+	if (lport->crc_offload &&
+	    skb->ip_summed == CHECKSUM_UNNECESSARY)
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	else
+		fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
+
+	fh = fc_frame_header_get(fp);
+	if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
+	    fh->fh_type == FC_TYPE_FCP) {
+		fc_exch_recv(lport, fp);
+		return;
+	}
+	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+		if (le32_to_cpu(fr_crc(fp)) !=
+		    ~crc32(~0, skb->data, fr_len)) {
+			if (stats->InvalidCRCCount < 5)
+				printk(KERN_WARNING "fcoe: dropping "
+				       "frame with CRC error\n");
+			stats->InvalidCRCCount++;
+			stats->ErrorFrames++;
+			fc_frame_free(fp);
+			return;
+		}
+		fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+	}
+	fc_exch_recv(lport, fp);
+}
+
+/**
+ * fcoe_percpu_receive_thread() - The per-CPU packet receive thread
+ * @arg: The per-CPU context
+ *
+ * Return: 0 for success
+ */
+int fcoe_percpu_receive_thread(void *arg)
+{
+	struct fcoe_percpu_s *p = arg;
+	struct sk_buff *skb;
+
 	set_user_nice(current, -20);
 
 	while (!kthread_should_stop()) {
@@ -1347,129 +1693,27 @@ int fcoe_percpu_receive_thread(void *arg
 			spin_lock_bh(&p->fcoe_rx_list.lock);
 		}
 		spin_unlock_bh(&p->fcoe_rx_list.lock);
-		fr = fcoe_dev_from_skb(skb);
-		lp = fr->fr_dev;
-		if (unlikely(lp == NULL)) {
-			if (skb->destructor != fcoe_percpu_flush_done)
-				FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
-			kfree_skb(skb);
-			continue;
-		}
-
-		FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
-				"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
-				skb->len, skb->data_len,
-				skb->head, skb->data, skb_tail_pointer(skb),
-				skb_end_pointer(skb), skb->csum,
-				skb->dev ? skb->dev->name : "<NULL>");
-
-		/*
-		 * Save source MAC address before discarding header.
-		 */
-		port = lport_priv(lp);
-		if (skb_is_nonlinear(skb))
-			skb_linearize(skb);	/* not ideal */
-		mac = eth_hdr(skb)->h_source;
-
-		/*
-		 * Frame length checks and setting up the header pointers
-		 * was done in fcoe_rcv already.
-		 */
-		hp = (struct fcoe_hdr *) skb_network_header(skb);
-		fh = (struct fc_frame_header *) skb_transport_header(skb);
-
-		stats = fc_lport_get_stats(lp);
-		if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
-			if (stats->ErrorFrames < 5)
-				printk(KERN_WARNING "fcoe: FCoE version "
-				       "mismatch: The frame has "
-				       "version %x, but the "
-				       "initiator supports version "
-				       "%x\n", FC_FCOE_DECAPS_VER(hp),
-				       FC_FCOE_VER);
-			stats->ErrorFrames++;
-			kfree_skb(skb);
-			continue;
-		}
-
-		skb_pull(skb, sizeof(struct fcoe_hdr));
-		fr_len = skb->len - sizeof(struct fcoe_crc_eof);
-
-		stats->RxFrames++;
-		stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
-
-		fp = (struct fc_frame *)skb;
-		fc_frame_init(fp);
-		fr_dev(fp) = lp;
-		fr_sof(fp) = hp->fcoe_sof;
-
-		/* Copy out the CRC and EOF trailer for access */
-		if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
-			kfree_skb(skb);
-			continue;
-		}
-		fr_eof(fp) = crc_eof.fcoe_eof;
-		fr_crc(fp) = crc_eof.fcoe_crc32;
-		if (pskb_trim(skb, fr_len)) {
-			kfree_skb(skb);
-			continue;
-		}
-
-		/*
-		 * We only check CRC if no offload is available and if it is
-		 * it's solicited data, in which case, the FCP layer would
-		 * check it during the copy.
-		 */
-		if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		else
-			fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
-
-		fh = fc_frame_header_get(fp);
-		if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
-		    fh->fh_type == FC_TYPE_FCP) {
-			fc_exch_recv(lp, fp);
-			continue;
-		}
-		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
-			if (le32_to_cpu(fr_crc(fp)) !=
-			    ~crc32(~0, skb->data, fr_len)) {
-				if (stats->InvalidCRCCount < 5)
-					printk(KERN_WARNING "fcoe: dropping "
-					       "frame with CRC error\n");
-				stats->InvalidCRCCount++;
-				stats->ErrorFrames++;
-				fc_frame_free(fp);
-				continue;
-			}
-			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
-		}
-		if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
-		    fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) {
-			fc_frame_free(fp);
-			continue;
-		}
-		fc_exch_recv(lp, fp);
+		fcoe_recv_frame(skb);
 	}
 	return 0;
 }
 
 /**
- * fcoe_check_wait_queue() - attempt to clear the transmit backlog
- * @lp: the fc_lport
+ * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
+ * @lport: The local port whose backlog is to be cleared
  *
- * This empties the wait_queue, dequeue the head of the wait_queue queue
- * and calls fcoe_start_io() for each packet, if all skb have been
- * transmitted, return qlen or -1 if a error occurs, then restore
- * wait_queue and try again later.
+ * This empties the wait_queue, dequeues the head of the wait_queue queue
+ * and calls fcoe_start_io() for each packet. If all skb have been
+ * transmitted it returns the qlen. If an error occurs it restores
+ * wait_queue (to try again later) and returns -1.
  *
- * The wait_queue is used when the skb transmit fails. skb will go
- * in the wait_queue which will be emptied by the timer function or
+ * The wait_queue is used when the skb transmit fails. The failed skb
+ * will go in the wait_queue which will be emptied by the timer function or
  * by the next skb transmit.
  */
-static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb)
+static void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
 {
-	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lport);
 	int rc;
 
 	spin_lock_bh(&port->fcoe_pending_queue.lock);
@@ -1501,19 +1745,19 @@ static void fcoe_check_wait_queue(struct
 	}
 
 	if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
-		lp->qfull = 0;
+		lport->qfull = 0;
 	if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
 		mod_timer(&port->timer, jiffies + 2);
 	port->fcoe_pending_queue_active = 0;
 out:
 	if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
-		lp->qfull = 1;
+		lport->qfull = 1;
 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
 	return;
 }
 
 /**
- * fcoe_dev_setup() - setup link change notification interface
+ * fcoe_dev_setup() - Setup the link change notification interface
  */
 static void fcoe_dev_setup(void)
 {
@@ -1521,7 +1765,7 @@ static void fcoe_dev_setup(void)
 }
 
 /**
- * fcoe_dev_cleanup() - cleanup link change notification interface
+ * fcoe_dev_cleanup() - Cleanup the link change notification interface
  */
 static void fcoe_dev_cleanup(void)
 {
@@ -1529,19 +1773,19 @@ static void fcoe_dev_cleanup(void)
 }
 
 /**
- * fcoe_device_notification() - netdev event notification callback
- * @notifier: context of the notification
- * @event: type of event
- * @ptr: fixed array for output parsed ifname
+ * fcoe_device_notification() - Handler for net device events
+ * @notifier: The context of the notification
+ * @event:    The type of event
+ * @ptr:      The net device that the event was on
  *
- * This function is called by the ethernet driver in case of link change event
+ * This function is called by the Ethernet driver in case of link change event.
  *
  * Returns: 0 for success
  */
 static int fcoe_device_notification(struct notifier_block *notifier,
 				    ulong event, void *ptr)
 {
-	struct fc_lport *lp = NULL;
+	struct fc_lport *lport = NULL;
 	struct net_device *netdev = ptr;
 	struct fcoe_interface *fcoe;
 	struct fcoe_port *port;
@@ -1552,11 +1796,11 @@ static int fcoe_device_notification(stru
 
 	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
 		if (fcoe->netdev == netdev) {
-			lp = fcoe->ctlr.lp;
+			lport = fcoe->ctlr.lp;
 			break;
 		}
 	}
-	if (lp == NULL) {
+	if (!lport) {
 		rc = NOTIFY_DONE;
 		goto out;
 	}
@@ -1570,10 +1814,12 @@ static int fcoe_device_notification(stru
 	case NETDEV_CHANGE:
 		break;
 	case NETDEV_CHANGEMTU:
+		if (netdev->features & NETIF_F_FCOE_MTU)
+			break;
 		mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
 				     sizeof(struct fcoe_crc_eof));
 		if (mfs >= FC_MIN_MAX_FRAME)
-			fc_set_mfs(lp, mfs);
+			fc_set_mfs(lport, mfs);
 		break;
 	case NETDEV_REGISTER:
 		break;
@@ -1588,22 +1834,22 @@ static int fcoe_device_notification(stru
 		FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
 				"from netdev netlink\n", event);
 	}
-	if (link_possible && !fcoe_link_ok(lp))
+	if (link_possible && !fcoe_link_ok(lport))
 		fcoe_ctlr_link_up(&fcoe->ctlr);
 	else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
-		stats = fc_lport_get_stats(lp);
+		stats = fc_lport_get_stats(lport);
 		stats->LinkFailureCount++;
-		fcoe_clean_pending_queue(lp);
+		fcoe_clean_pending_queue(lport);
 	}
 out:
 	return rc;
 }
 
 /**
- * fcoe_if_to_netdev() - parse a name buffer to get netdev
- * @buffer: incoming buffer to be copied
+ * fcoe_if_to_netdev() - Parse a name buffer to get a net device
+ * @buffer: The name of the net device
  *
- * Returns: NULL or ptr to net_device
+ * Returns: NULL or a ptr to net_device
  */
 static struct net_device *fcoe_if_to_netdev(const char *buffer)
 {
@@ -1621,9 +1867,109 @@ static struct net_device *fcoe_if_to_net
 }
 
 /**
- * fcoe_destroy() - handles the destroy from sysfs
- * @buffer: expected to be an eth if name
- * @kp: associated kernel param
+ * fcoe_disable() - Disables a FCoE interface
+ * @buffer: The name of the Ethernet interface to be disabled
+ * @kp:	    The associated kernel parameter
+ *
+ * Called from sysfs.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_disable(const char *buffer, struct kernel_param *kp)
+{
+	struct fcoe_interface *fcoe;
+	struct net_device *netdev;
+	int rc = 0;
+
+	mutex_lock(&fcoe_config_mutex);
+#ifdef CONFIG_FCOE_MODULE
+	/*
+	 * Make sure the module has been initialized, and is not about to be
+	 * removed.  Module paramter sysfs files are writable before the
+	 * module_init function is called and after module_exit.
+	 */
+	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+#endif
+
+	netdev = fcoe_if_to_netdev(buffer);
+	if (!netdev) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+
+	rtnl_lock();
+	fcoe = fcoe_hostlist_lookup_port(netdev);
+	rtnl_unlock();
+
+	if (fcoe)
+		fc_fabric_logoff(fcoe->ctlr.lp);
+	else
+		rc = -ENODEV;
+
+	dev_put(netdev);
+out_nodev:
+	mutex_unlock(&fcoe_config_mutex);
+	return rc;
+}
+
+/**
+ * fcoe_enable() - Enables a FCoE interface
+ * @buffer: The name of the Ethernet interface to be enabled
+ * @kp:     The associated kernel parameter
+ *
+ * Called from sysfs.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_enable(const char *buffer, struct kernel_param *kp)
+{
+	struct fcoe_interface *fcoe;
+	struct net_device *netdev;
+	int rc = 0;
+
+	mutex_lock(&fcoe_config_mutex);
+#ifdef CONFIG_FCOE_MODULE
+	/*
+	 * Make sure the module has been initialized, and is not about to be
+	 * removed.  Module paramter sysfs files are writable before the
+	 * module_init function is called and after module_exit.
+	 */
+	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+#endif
+
+	netdev = fcoe_if_to_netdev(buffer);
+	if (!netdev) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+
+	rtnl_lock();
+	fcoe = fcoe_hostlist_lookup_port(netdev);
+	rtnl_unlock();
+
+	if (fcoe)
+		rc = fc_fabric_login(fcoe->ctlr.lp);
+	else
+		rc = -ENODEV;
+
+	dev_put(netdev);
+out_nodev:
+	mutex_unlock(&fcoe_config_mutex);
+	return rc;
+}
+
+/**
+ * fcoe_destroy() - Destroy a FCoE interface
+ * @buffer: The name of the Ethernet interface to be destroyed
+ * @kp:	    The associated kernel parameter
+ *
+ * Called from sysfs.
  *
  * Returns: 0 for success
  */
@@ -1631,7 +1977,7 @@ static int fcoe_destroy(const char *buff
 {
 	struct fcoe_interface *fcoe;
 	struct net_device *netdev;
-	int rc;
+	int rc = 0;
 
 	mutex_lock(&fcoe_config_mutex);
 #ifdef CONFIG_FCOE_MODULE
@@ -1663,6 +2009,8 @@ static int fcoe_destroy(const char *buff
 	fcoe_interface_cleanup(fcoe);
 	rtnl_unlock();
 	fcoe_if_destroy(fcoe->ctlr.lp);
+	module_put(THIS_MODULE);
+
 out_putdev:
 	dev_put(netdev);
 out_nodev:
@@ -1670,6 +2018,10 @@ out_nodev:
 	return rc;
 }
 
+/**
+ * fcoe_destroy_work() - Destroy a FCoE port in a deferred work context
+ * @work: Handle to the FCoE port to be destroyed
+ */
 static void fcoe_destroy_work(struct work_struct *work)
 {
 	struct fcoe_port *port;
@@ -1681,9 +2033,11 @@ static void fcoe_destroy_work(struct wor
 }
 
 /**
- * fcoe_create() - Handles the create call from sysfs
- * @buffer: expected to be an eth if name
- * @kp: associated kernel param
+ * fcoe_create() - Create a fcoe interface
+ * @buffer: The name of the Ethernet interface to create on
+ * @kp:	    The associated kernel param
+ *
+ * Called from sysfs.
  *
  * Returns: 0 for success
  */
@@ -1707,6 +2061,11 @@ static int fcoe_create(const char *buffe
 	}
 #endif
 
+	if (!try_module_get(THIS_MODULE)) {
+		rc = -EINVAL;
+		goto out_nomod;
+	}
+
 	rtnl_lock();
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
@@ -1726,7 +2085,7 @@ static int fcoe_create(const char *buffe
 		goto out_putdev;
 	}
 
-	lport = fcoe_if_create(fcoe, &netdev->dev);
+	lport = fcoe_if_create(fcoe, &netdev->dev, 0);
 	if (IS_ERR(lport)) {
 		printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
 		       netdev->name);
@@ -1747,31 +2106,31 @@ static int fcoe_create(const char *buffe
 	if (!fcoe_link_ok(lport))
 		fcoe_ctlr_link_up(&fcoe->ctlr);
 
-	rc = 0;
-out_free:
 	/*
 	 * Release from init in fcoe_interface_create(), on success lport
 	 * should be holding a reference taken in fcoe_if_create().
 	 */
 	fcoe_interface_put(fcoe);
+	dev_put(netdev);
+	rtnl_unlock();
+	mutex_unlock(&fcoe_config_mutex);
+
+	return 0;
+out_free:
+	fcoe_interface_put(fcoe);
 out_putdev:
 	dev_put(netdev);
 out_nodev:
 	rtnl_unlock();
+	module_put(THIS_MODULE);
+out_nomod:
 	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
 
-module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(create, "string");
-MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(destroy, "string");
-MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
-
 /**
- * fcoe_link_ok() - Check if link is ok for the fc_lport
- * @lp: ptr to the fc_lport
+ * fcoe_link_ok() - Check if the link is OK for a local port
+ * @lport: The local port to check link on
  *
  * Any permanently-disqualifying conditions have been previously checked.
  * This also updates the speed setting, which may change with link for 100/1000.
@@ -1783,26 +2142,26 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe
  * Returns: 0 if link is OK for use by FCoE.
  *
  */
-int fcoe_link_ok(struct fc_lport *lp)
+int fcoe_link_ok(struct fc_lport *lport)
 {
-	struct fcoe_port *port = lport_priv(lp);
-	struct net_device *dev = port->fcoe->netdev;
+	struct fcoe_port *port = lport_priv(lport);
+	struct net_device *netdev = port->fcoe->netdev;
 	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
 
-	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
-	    (!dev_ethtool_get_settings(dev, &ecmd))) {
-		lp->link_supported_speeds &=
+	if ((netdev->flags & IFF_UP) && netif_carrier_ok(netdev) &&
+	    (!dev_ethtool_get_settings(netdev, &ecmd))) {
+		lport->link_supported_speeds &=
 			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
 		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
 				      SUPPORTED_1000baseT_Full))
-			lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lp->link_supported_speeds |=
+			lport->link_supported_speeds |=
 				FC_PORTSPEED_10GBIT;
 		if (ecmd.speed == SPEED_1000)
-			lp->link_speed = FC_PORTSPEED_1GBIT;
+			lport->link_speed = FC_PORTSPEED_1GBIT;
 		if (ecmd.speed == SPEED_10000)
-			lp->link_speed = FC_PORTSPEED_10GBIT;
+			lport->link_speed = FC_PORTSPEED_10GBIT;
 
 		return 0;
 	}
@@ -1810,8 +2169,8 @@ int fcoe_link_ok(struct fc_lport *lp)
 }
 
 /**
- * fcoe_percpu_clean() - Clear the pending skbs for an lport
- * @lp: the fc_lport
+ * fcoe_percpu_clean() - Clear all pending skbs for an local port
+ * @lport: The local port whose skbs are to be cleared
  *
  * Must be called with fcoe_create_mutex held to single-thread completion.
  *
@@ -1820,7 +2179,7 @@ int fcoe_link_ok(struct fc_lport *lp)
  * there no packets that will be handled by the lport, but also that any
  * threads already handling packet have returned.
  */
-void fcoe_percpu_clean(struct fc_lport *lp)
+void fcoe_percpu_clean(struct fc_lport *lport)
 {
 	struct fcoe_percpu_s *pp;
 	struct fcoe_rcv_info *fr;
@@ -1838,7 +2197,7 @@ void fcoe_percpu_clean(struct fc_lport *
 		     skb = next) {
 			next = skb->next;
 			fr = fcoe_dev_from_skb(skb);
-			if (fr->fr_dev == lp) {
+			if (fr->fr_dev == lport) {
 				__skb_unlink(skb, list);
 				kfree_skb(skb);
 			}
@@ -1867,13 +2226,11 @@ void fcoe_percpu_clean(struct fc_lport *
 
 /**
  * fcoe_clean_pending_queue() - Dequeue a skb and free it
- * @lp: the corresponding fc_lport
- *
- * Returns: none
+ * @lport: The local port to dequeue a skb on
  */
-void fcoe_clean_pending_queue(struct fc_lport *lp)
+void fcoe_clean_pending_queue(struct fc_lport *lport)
 {
-	struct fcoe_port  *port = lport_priv(lp);
+	struct fcoe_port  *port = lport_priv(lport);
 	struct sk_buff *skb;
 
 	spin_lock_bh(&port->fcoe_pending_queue.lock);
@@ -1886,10 +2243,10 @@ void fcoe_clean_pending_queue(struct fc_
 }
 
 /**
- * fcoe_reset() - Resets the fcoe
- * @shost: shost the reset is from
+ * fcoe_reset() - Reset a local port
+ * @shost: The SCSI host associated with the local port to be reset
  *
- * Returns: always 0
+ * Returns: Always 0 (return value required by FC transport template)
  */
 int fcoe_reset(struct Scsi_Host *shost)
 {
@@ -1899,30 +2256,33 @@ int fcoe_reset(struct Scsi_Host *shost)
 }
 
 /**
- * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device
- * @dev: this is currently ptr to net_device
+ * fcoe_hostlist_lookup_port() - Find the FCoE interface associated with a net device
+ * @netdev: The net device used as a key
  *
- * Returns: NULL or the located fcoe_port
- * Locking: must be called with the RNL mutex held
+ * Locking: Must be called with the RNL mutex held.
+ *
+ * Returns: NULL or the FCoE interface
  */
 static struct fcoe_interface *
-fcoe_hostlist_lookup_port(const struct net_device *dev)
+fcoe_hostlist_lookup_port(const struct net_device *netdev)
 {
 	struct fcoe_interface *fcoe;
 
 	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
-		if (fcoe->netdev == dev)
+		if (fcoe->netdev == netdev)
 			return fcoe;
 	}
 	return NULL;
 }
 
 /**
- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
- * @netdev: ptr to net_device
+ * fcoe_hostlist_lookup() - Find the local port associated with a
+ *			    given net device
+ * @netdev: The netdevice used as a key
  *
- * Returns: 0 for success
- * Locking: must be called with the RTNL mutex held
+ * Locking: Must be called with the RTNL mutex held
+ *
+ * Returns: NULL or the local port
  */
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
 {
@@ -1933,11 +2293,13 @@ static struct fc_lport *fcoe_hostlist_lo
 }
 
 /**
- * fcoe_hostlist_add() - Add a lport to lports list
- * @lp: ptr to the fc_lport to be added
+ * fcoe_hostlist_add() - Add the FCoE interface identified by a local
+ *			 port to the hostlist
+ * @lport: The local port that identifies the FCoE interface to be added
  *
- * Returns: 0 for success
  * Locking: must be called with the RTNL mutex held
+ *
+ * Returns: 0 for success
  */
 static int fcoe_hostlist_add(const struct fc_lport *lport)
 {
@@ -1954,15 +2316,15 @@ static int fcoe_hostlist_add(const struc
 }
 
 /**
- * fcoe_init() - fcoe module loading initialization
+ * fcoe_init() - Initialize fcoe.ko
  *
- * Returns 0 on success, negative on failure
+ * Returns: 0 on success, or a negative value on failure
  */
 static int __init fcoe_init(void)
 {
+	struct fcoe_percpu_s *p;
 	unsigned int cpu;
 	int rc = 0;
-	struct fcoe_percpu_s *p;
 
 	mutex_lock(&fcoe_config_mutex);
 
@@ -1999,15 +2361,15 @@ out_free:
 module_init(fcoe_init);
 
 /**
- * fcoe_exit() - fcoe module unloading cleanup
+ * fcoe_exit() - Clean up fcoe.ko
  *
- * Returns 0 on success, negative on failure
+ * Returns: 0 on success or a  negative value on failure
  */
 static void __exit fcoe_exit(void)
 {
-	unsigned int cpu;
 	struct fcoe_interface *fcoe, *tmp;
 	struct fcoe_port *port;
+	unsigned int cpu;
 
 	mutex_lock(&fcoe_config_mutex);
 
@@ -2033,9 +2395,238 @@ static void __exit fcoe_exit(void)
 	/* flush any asyncronous interface destroys,
 	 * this should happen after the netdev notifier is unregistered */
 	flush_scheduled_work();
+	/* That will flush out all the N_Ports on the hostlist, but now we
+	 * may have NPIV VN_Ports scheduled for destruction */
+	flush_scheduled_work();
 
 	/* detach from scsi transport
 	 * must happen after all destroys are done, therefor after the flush */
 	fcoe_if_exit();
 }
 module_exit(fcoe_exit);
+
+/**
+ * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
+ * @seq: active sequence in the FLOGI or FDISC exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc FLOGI response handler.
+ */
+static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+	struct fcoe_ctlr *fip = arg;
+	struct fc_exch *exch = fc_seq_exch(seq);
+	struct fc_lport *lport = exch->lp;
+	u8 *mac;
+
+	if (IS_ERR(fp))
+		goto done;
+
+	mac = fr_cb(fp)->granted_mac;
+	if (is_zero_ether_addr(mac)) {
+		/* pre-FIP */
+		if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
+			fc_frame_free(fp);
+			return;
+		}
+	}
+	fcoe_update_src_mac(lport, mac);
+done:
+	fc_lport_flogi_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_logo_resp() - FCoE specific LOGO response handler
+ * @seq: active sequence in the LOGO exchange
+ * @fp: response frame, or error encoded in a pointer (timeout)
+ * @arg: pointer the the fcoe_ctlr structure
+ *
+ * This handles MAC address managment for FCoE, then passes control on to
+ * the libfc LOGO response handler.
+ */
+static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
+{
+	struct fc_lport *lport = arg;
+	static u8 zero_mac[ETH_ALEN] = { 0 };
+
+	if (!IS_ERR(fp))
+		fcoe_update_src_mac(lport, zero_mac);
+	fc_lport_logo_resp(seq, fp, lport);
+}
+
+/**
+ * fcoe_elsct_send - FCoE specific ELS handler
+ *
+ * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
+ * using FCoE specific response handlers and passing the FIP controller as
+ * the argument (the lport is still available from the exchange).
+ *
+ * Most of the work here is just handed off to the libfc routine.
+ */
+static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
+				      struct fc_frame *fp, unsigned int op,
+				      void (*resp)(struct fc_seq *,
+						   struct fc_frame *,
+						   void *),
+				      void *arg, u32 timeout)
+{
+	struct fcoe_port *port = lport_priv(lport);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct fcoe_ctlr *fip = &fcoe->ctlr;
+	struct fc_frame_header *fh = fc_frame_header_get(fp);
+
+	switch (op) {
+	case ELS_FLOGI:
+	case ELS_FDISC:
+		return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp,
+				     fip, timeout);
+	case ELS_LOGO:
+		/* only hook onto fabric logouts, not port logouts */
+		if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
+			break;
+		return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
+				     lport, timeout);
+	}
+	return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
+}
+
+/**
+ * fcoe_vport_create() - create an fc_host/scsi_host for a vport
+ * @vport: fc_vport object to create a new fc_host for
+ * @disabled: start the new fc_host in a disabled state by default?
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fcoe_port *port = lport_priv(n_port);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct net_device *netdev = fcoe->netdev;
+	struct fc_lport *vn_port;
+
+	mutex_lock(&fcoe_config_mutex);
+	vn_port = fcoe_if_create(fcoe, &vport->dev, 1);
+	mutex_unlock(&fcoe_config_mutex);
+
+	if (IS_ERR(vn_port)) {
+		printk(KERN_ERR "fcoe: fcoe_vport_create(%s) failed\n",
+		       netdev->name);
+		return -EIO;
+	}
+
+	if (disabled) {
+		fc_vport_set_state(vport, FC_VPORT_DISABLED);
+	} else {
+		vn_port->boot_time = jiffies;
+		fc_fabric_login(vn_port);
+		fc_vport_setlink(vn_port);
+	}
+	return 0;
+}
+
+/**
+ * fcoe_vport_destroy() - destroy the fc_host/scsi_host for a vport
+ * @vport: fc_vport object that is being destroyed
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_destroy(struct fc_vport *vport)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fc_lport *vn_port = vport->dd_data;
+	struct fcoe_port *port = lport_priv(vn_port);
+
+	mutex_lock(&n_port->lp_mutex);
+	list_del(&vn_port->list);
+	mutex_unlock(&n_port->lp_mutex);
+	schedule_work(&port->destroy_work);
+	return 0;
+}
+
+/**
+ * fcoe_vport_disable() - change vport state
+ * @vport: vport to bring online/offline
+ * @disable: should the vport be disabled?
+ */
+static int fcoe_vport_disable(struct fc_vport *vport, bool disable)
+{
+	struct fc_lport *lport = vport->dd_data;
+
+	if (disable) {
+		fc_vport_set_state(vport, FC_VPORT_DISABLED);
+		fc_fabric_logoff(lport);
+	} else {
+		lport->boot_time = jiffies;
+		fc_fabric_login(lport);
+		fc_vport_setlink(lport);
+	}
+
+	return 0;
+}
+
+/**
+ * fcoe_vport_set_symbolic_name() - append vport string to symbolic name
+ * @vport: fc_vport with a new symbolic name string
+ *
+ * After generating a new symbolic name string, a new RSPN_ID request is
+ * sent to the name server.  There is no response handler, so if it fails
+ * for some reason it will not be retried.
+ */
+static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
+{
+	struct fc_lport *lport = vport->dd_data;
+	struct fc_frame *fp;
+	size_t len;
+
+	snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE,
+		 "%s v%s over %s : %s", FCOE_NAME, FCOE_VERSION,
+		 fcoe_netdev(lport)->name, vport->symbolic_name);
+
+	if (lport->state != LPORT_ST_READY)
+		return;
+
+	len = strnlen(fc_host_symbolic_name(lport->host), 255);
+	fp = fc_frame_alloc(lport,
+			    sizeof(struct fc_ct_hdr) +
+			    sizeof(struct fc_ns_rspn) + len);
+	if (!fp)
+		return;
+	lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID,
+			     NULL, NULL, 3 * lport->r_a_tov);
+}
+
+/**
+ * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
+ * @lport: the local port
+ * @fc_lesb: the link error status block
+ */
+static void fcoe_get_lesb(struct fc_lport *lport,
+			 struct fc_els_lesb *fc_lesb)
+{
+	unsigned int cpu;
+	u32 lfc, vlfc, mdac;
+	struct fcoe_dev_stats *devst;
+	struct fcoe_fc_els_lesb *lesb;
+	struct net_device *netdev = fcoe_netdev(lport);
+
+	lfc = 0;
+	vlfc = 0;
+	mdac = 0;
+	lesb = (struct fcoe_fc_els_lesb *)fc_lesb;
+	memset(lesb, 0, sizeof(*lesb));
+	for_each_possible_cpu(cpu) {
+		devst = per_cpu_ptr(lport->dev_stats, cpu);
+		lfc += devst->LinkFailureCount;
+		vlfc += devst->VLinkFailureCount;
+		mdac += devst->MissDiscAdvCount;
+	}
+	lesb->lesb_link_fail = htonl(lfc);
+	lesb->lesb_vlink_fail = htonl(vlfc);
+	lesb->lesb_miss_fka = htonl(mdac);
+	lesb->lesb_fcs_error = htonl(dev_get_stats(netdev)->rx_crc_errors);
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/fcoe.h linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/fcoe.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/fcoe.h	2010-02-24 13:52:17.000000000 -0500
@@ -32,7 +32,7 @@
 #define FCOE_NAME	"fcoe"
 #define FCOE_VENDOR	"Open-FCoE.org"
 
-#define FCOE_MAX_LUN		255
+#define FCOE_MAX_LUN		0xFFFF
 #define FCOE_MAX_FCP_TARGET	256
 
 #define FCOE_MAX_OUTSTANDING_COMMANDS	1024
@@ -40,11 +40,17 @@
 #define FCOE_MIN_XID		0x0000	/* the min xid supported by fcoe_sw */
 #define FCOE_MAX_XID		0x0FFF	/* the max xid supported by fcoe_sw */
 
+/*
+ * Max MTU for FCoE: 14 (FCoE header) + 24 (FC header) + 2112 (max FC payload)
+ * + 4 (FC CRC) + 4 (FCoE trailer) =  2158 bytes
+ */
+#define FCOE_MTU	2158
+
 unsigned int fcoe_debug_logging;
 module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
 
-#define FCOE_LOGGING        0x01 /* General logging, not categorized */
+#define FCOE_LOGGING	    0x01 /* General logging, not categorized */
 #define FCOE_NETDEV_LOGGING 0x02 /* Netdevice logging */
 
 #define FCOE_CHECK_LOGGING(LEVEL, CMD)					\
@@ -64,8 +70,13 @@ do {
 			   printk(KERN_INFO "fcoe: %s: " fmt,	\
 				  netdev->name, ##args);)
 
-/*
- * this percpu struct for fcoe
+/**
+ * struct fcoe_percpu_s - The per-CPU context for FCoE receive threads
+ * @thread:	    The thread context
+ * @fcoe_rx_list:   The queue of pending packets to process
+ * @page:	    The memory page for calculating frame trailer CRCs
+ * @crc_eof_offset: The offset into the CRC page pointing to available
+ *		    memory for a new trailer
  */
 struct fcoe_percpu_s {
 	struct task_struct *thread;
@@ -74,37 +85,62 @@ struct fcoe_percpu_s {
 	int crc_eof_offset;
 };
 
-/*
- * an FCoE interface, 1:1 with netdev
+/**
+ * struct fcoe_interface - A FCoE interface
+ * @list:	      Handle for a list of FCoE interfaces
+ * @netdev:	      The associated net device
+ * @fcoe_packet_type: FCoE packet type
+ * @fip_packet_type:  FIP packet type
+ * @ctlr:	      The FCoE controller (for FIP)
+ * @oem:	      The offload exchange manager for all local port
+ *		      instances associated with this port
+ * @kref:	      The kernel reference
+ *
+ * This structure is 1:1 with a net devive.
  */
 struct fcoe_interface {
-	struct list_head list;
-	struct net_device *netdev;
-	struct packet_type  fcoe_packet_type;
-	struct packet_type  fip_packet_type;
-	struct fcoe_ctlr ctlr;
-	struct fc_exch_mgr *oem;		/* offload exchange manager */
-	struct kref kref;
+	struct list_head   list;
+	struct net_device  *netdev;
+	struct packet_type fcoe_packet_type;
+	struct packet_type fip_packet_type;
+	struct fcoe_ctlr   ctlr;
+	struct fc_exch_mgr *oem;
+	struct kref	   kref;
 };
 
-/*
- * the FCoE private structure that's allocated along with the
- * Scsi_Host and libfc fc_lport structures
+/**
+ * struct fcoe_port - The FCoE private structure
+ * @fcoe:		       The associated fcoe interface
+ * @lport:		       The associated local port
+ * @fcoe_pending_queue:	       The pending Rx queue of skbs
+ * @fcoe_pending_queue_active: Indicates if the pending queue is active
+ * @timer:		       The queue timer
+ * @destroy_work:	       Handle for work context
+ *			       (to prevent RTNL deadlocks)
+ * @data_srt_addr:	       Source address for data
+ *
+ * An instance of this structure is to be allocated along with the
+ * Scsi_Host and libfc fc_lport structures.
  */
 struct fcoe_port {
 	struct fcoe_interface *fcoe;
-	struct fc_lport *lport;
-	struct sk_buff_head fcoe_pending_queue;
-	u8	fcoe_pending_queue_active;
-	struct timer_list timer;		/* queue timer */
-	struct work_struct destroy_work;	/* to prevent rtnl deadlocks */
+	struct fc_lport	      *lport;
+	struct sk_buff_head   fcoe_pending_queue;
+	u8		      fcoe_pending_queue_active;
+	struct timer_list     timer;
+	struct work_struct    destroy_work;
+	u8		      data_src_addr[ETH_ALEN];
 };
 
 #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
 
-static inline struct net_device *fcoe_netdev(const struct fc_lport *lp)
+/**
+ * fcoe_netdev() - Return the net device associated with a local port
+ * @lport: The local port to get the net device from
+ */
+static inline struct net_device *fcoe_netdev(const struct fc_lport *lport)
 {
-	return ((struct fcoe_port *)lport_priv(lp))->fcoe->netdev;
+	return ((struct fcoe_port *)lport_priv(lport))->fcoe->netdev;
 }
 
 #endif /* _FCOE_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/libfcoe.c linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/libfcoe.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fcoe/libfcoe.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fcoe/libfcoe.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,26 +59,30 @@ unsigned int libfcoe_debug_logging;
 module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
 
-#define LIBFCOE_LOGGING     0x01 /* General logging, not categorized */
+#define LIBFCOE_LOGGING	    0x01 /* General logging, not categorized */
 #define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */
 
-#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)				\
-do {                                                            	\
-	if (unlikely(libfcoe_debug_logging & LEVEL))			\
-		do {							\
-			CMD;						\
-		} while (0);						\
+#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)		\
+do {							\
+	if (unlikely(libfcoe_debug_logging & LEVEL))	\
+		do {					\
+			CMD;				\
+		} while (0);				\
 } while (0)
 
 #define LIBFCOE_DBG(fmt, args...)					\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,				\
 			      printk(KERN_INFO "libfcoe: " fmt, ##args);)
 
-#define LIBFCOE_FIP_DBG(fmt, args...)					\
+#define LIBFCOE_FIP_DBG(fip, fmt, args...)				\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING,			\
-			      printk(KERN_INFO "fip: " fmt, ##args);)
+			      printk(KERN_INFO "host%d: fip: " fmt, 	\
+				     (fip)->lp->host->host_no, ##args);)
 
-/*
+/**
+ * fcoe_ctlr_mtu_valid() - Check if a FCF's MTU is valid
+ * @fcf: The FCF to check
+ *
  * Return non-zero if FCF fcoe_size has been validated.
  */
 static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
@@ -86,7 +90,10 @@ static inline int fcoe_ctlr_mtu_valid(co
 	return (fcf->flags & FIP_FL_SOL) != 0;
 }
 
-/*
+/**
+ * fcoe_ctlr_fcf_usable() - Check if a FCF is usable
+ * @fcf: The FCF to check
+ *
  * Return non-zero if the FCF is usable.
  */
 static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
@@ -97,12 +104,13 @@ static inline int fcoe_ctlr_fcf_usable(s
 }
 
 /**
- * fcoe_ctlr_init() - Initialize the FCoE Controller instance.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_init() - Initialize the FCoE Controller instance
+ * @fip: The FCoE controller to initialize
  */
 void fcoe_ctlr_init(struct fcoe_ctlr *fip)
 {
 	fip->state = FIP_ST_LINK_WAIT;
+	fip->mode = FIP_ST_AUTO;
 	INIT_LIST_HEAD(&fip->fcfs);
 	spin_lock_init(&fip->lock);
 	fip->flogi_oxid = FC_XID_UNKNOWN;
@@ -114,8 +122,8 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fi
 EXPORT_SYMBOL(fcoe_ctlr_init);
 
 /**
- * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller
+ * @fip: The FCoE controller whose FCFs are to be reset
  *
  * Called with &fcoe_ctlr lock held.
  */
@@ -134,8 +142,8 @@ static void fcoe_ctlr_reset_fcfs(struct
 }
 
 /**
- * fcoe_ctlr_destroy() - Disable and tear-down the FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_destroy() - Disable and tear down a FCoE controller
+ * @fip: The FCoE controller to tear down
  *
  * This is called by FCoE drivers before freeing the &fcoe_ctlr.
  *
@@ -148,9 +156,7 @@ static void fcoe_ctlr_reset_fcfs(struct
 void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
 {
 	cancel_work_sync(&fip->recv_work);
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	__skb_queue_purge(&fip->fip_recv_list);
-	spin_unlock_bh(&fip->fip_recv_list.lock);
+	skb_queue_purge(&fip->fip_recv_list);
 
 	spin_lock_bh(&fip->lock);
 	fip->state = FIP_ST_DISABLED;
@@ -162,8 +168,8 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr
 EXPORT_SYMBOL(fcoe_ctlr_destroy);
 
 /**
- * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port
+ * @fip: The FCoE controller to get the maximum FCoE size from
  *
  * Returns the maximum packet size including the FCoE header and trailer,
  * but not including any Ethernet or VLAN headers.
@@ -180,9 +186,9 @@ static inline u32 fcoe_ctlr_fcoe_size(st
 }
 
 /**
- * fcoe_ctlr_solicit() - Send a solicitation.
- * @fip:	FCoE controller.
- * @fcf:	Destination FCF.  If NULL, a multicast solicitation is sent.
+ * fcoe_ctlr_solicit() - Send a FIP solicitation
+ * @fip: The FCoE controller to send the solicitation on
+ * @fcf: The destination FCF (if NULL, a multicast solicitation is sent)
  */
 static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
 {
@@ -241,8 +247,8 @@ static void fcoe_ctlr_solicit(struct fco
 }
 
 /**
- * fcoe_ctlr_link_up() - Start FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_link_up() - Start FCoE controller
+ * @fip: The FCoE controller to start
  *
  * Called from the LLD when the network link is ready.
  */
@@ -255,11 +261,12 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr
 		spin_unlock_bh(&fip->lock);
 		fc_linkup(fip->lp);
 	} else if (fip->state == FIP_ST_LINK_WAIT) {
-		fip->state = FIP_ST_AUTO;
+		fip->state = fip->mode;
 		fip->last_link = 1;
 		fip->link = 1;
 		spin_unlock_bh(&fip->lock);
-		LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n");
+		if (fip->state == FIP_ST_AUTO)
+			LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n");
 		fc_linkup(fip->lp);
 		fcoe_ctlr_solicit(fip, NULL);
 	} else
@@ -268,45 +275,23 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr
 EXPORT_SYMBOL(fcoe_ctlr_link_up);
 
 /**
- * fcoe_ctlr_reset() - Reset FIP.
- * @fip:	FCoE controller.
- * @new_state:	FIP state to be entered.
- *
- * Returns non-zero if the link was up and now isn't.
+ * fcoe_ctlr_reset() - Reset a FCoE controller
+ * @fip:       The FCoE controller to reset
  */
-static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state)
+static void fcoe_ctlr_reset(struct fcoe_ctlr *fip)
 {
-	struct fc_lport *lp = fip->lp;
-	int link_dropped;
-
-	spin_lock_bh(&fip->lock);
 	fcoe_ctlr_reset_fcfs(fip);
 	del_timer(&fip->timer);
-	fip->state = new_state;
 	fip->ctlr_ka_time = 0;
 	fip->port_ka_time = 0;
 	fip->sol_time = 0;
 	fip->flogi_oxid = FC_XID_UNKNOWN;
 	fip->map_dest = 0;
-	fip->last_link = 0;
-	link_dropped = fip->link;
-	fip->link = 0;
-	spin_unlock_bh(&fip->lock);
-
-	if (link_dropped)
-		fc_linkdown(lp);
-
-	if (new_state == FIP_ST_ENABLED) {
-		fcoe_ctlr_solicit(fip, NULL);
-		fc_linkup(lp);
-		link_dropped = 0;
-	}
-	return link_dropped;
 }
 
 /**
- * fcoe_ctlr_link_down() - Stop FCoE controller.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_link_down() - Stop a FCoE controller
+ * @fip: The FCoE controller to be stopped
  *
  * Returns non-zero if the link was up and now isn't.
  *
@@ -315,15 +300,29 @@ static int fcoe_ctlr_reset(struct fcoe_c
  */
 int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
 {
-	return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
+	int link_dropped;
+
+	LIBFCOE_FIP_DBG(fip, "link down.\n");
+	spin_lock_bh(&fip->lock);
+	fcoe_ctlr_reset(fip);
+	link_dropped = fip->link;
+	fip->link = 0;
+	fip->last_link = 0;
+	fip->state = FIP_ST_LINK_WAIT;
+	spin_unlock_bh(&fip->lock);
+
+	if (link_dropped)
+		fc_linkdown(fip->lp);
+	return link_dropped;
 }
 EXPORT_SYMBOL(fcoe_ctlr_link_down);
 
 /**
- * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
- * @fip:	FCoE controller.
- * @ports:	0 for controller keep-alive, 1 for port keep-alive.
- * @sa:		source MAC address.
+ * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF
+ * @fip:   The FCoE controller to send the FKA on
+ * @lport: libfc fc_lport to send from
+ * @ports: 0 for controller keep-alive, 1 for port keep-alive
+ * @sa:	   The source MAC address
  *
  * A controller keep-alive is sent every fka_period (typically 8 seconds).
  * The source MAC is the native MAC address.
@@ -332,7 +331,9 @@ EXPORT_SYMBOL(fcoe_ctlr_link_down);
  * The source MAC is the assigned mapped source address.
  * The destination is the FCF's F-port.
  */
-static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
+static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
+				      struct fc_lport *lport,
+				      int ports, u8 *sa)
 {
 	struct sk_buff *skb;
 	struct fip_kal {
@@ -350,8 +351,7 @@ static void fcoe_ctlr_send_keep_alive(st
 	if (!fcf || !fc_host_port_id(lp->host))
 		return;
 
-	len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr);
-	BUG_ON(len < sizeof(*kal) + sizeof(*vn));
+	len = sizeof(*kal) + ports * sizeof(*vn);
 	skb = dev_alloc_skb(len);
 	if (!skb)
 		return;
@@ -366,7 +366,7 @@ static void fcoe_ctlr_send_keep_alive(st
 	kal->fip.fip_op = htons(FIP_OP_CTRL);
 	kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
 	kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
-				    ports * sizeof(*vn)) / FIP_BPW);
+				     ports * sizeof(*vn)) / FIP_BPW);
 	kal->fip.fip_flags = htons(FIP_FL_FPMA);
 	if (fip->spma)
 		kal->fip.fip_flags |= htons(FIP_FL_SPMA);
@@ -374,16 +374,14 @@ static void fcoe_ctlr_send_keep_alive(st
 	kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
 	kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
 	memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
-
 	if (ports) {
 		vn = (struct fip_vn_desc *)(kal + 1);
 		vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
 		vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
-		memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
+		memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
 		hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
 		put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
 	}
-
 	skb_put(skb, len);
 	skb->protocol = htons(ETH_P_FIP);
 	skb_reset_mac_header(skb);
@@ -392,10 +390,10 @@ static void fcoe_ctlr_send_keep_alive(st
 }
 
 /**
- * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
- * @fip:	FCoE controller.
- * @dtype:	FIP descriptor type for the frame.
- * @skb:	FCoE ELS frame including FC header but no FCoE headers.
+ * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it
+ * @fip:   The FCoE controller for the ELS frame
+ * @dtype: The FIP descriptor type for the frame
+ * @skb:   The FCoE ELS frame including FC header but no FCoE headers
  *
  * Returns non-zero error code on failure.
  *
@@ -405,7 +403,7 @@ static void fcoe_ctlr_send_keep_alive(st
  * Headroom includes the FIP encapsulation description, FIP header, and
  * Ethernet header.  The tailroom is for the FIP MAC descriptor.
  */
-static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
+static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
 			    u8 dtype, struct sk_buff *skb)
 {
 	struct fip_encaps_head {
@@ -449,8 +447,8 @@ static int fcoe_ctlr_encaps(struct fcoe_
 	memset(mac, 0, sizeof(mac));
 	mac->fd_desc.fip_dtype = FIP_DT_MAC;
 	mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
-	if (dtype != FIP_DT_FLOGI)
-		memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+	if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
+		memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
 	else if (fip->spma)
 		memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
 
@@ -463,6 +461,7 @@ static int fcoe_ctlr_encaps(struct fcoe_
 /**
  * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
  * @fip:	FCoE controller.
+ * @lport:	libfc fc_lport to send from
  * @skb:	FCoE ELS frame including FC header but no FCoE headers.
  *
  * Returns a non-zero error code if the frame should not be sent.
@@ -471,11 +470,13 @@ static int fcoe_ctlr_encaps(struct fcoe_
  * The caller must check that the length is a multiple of 4.
  * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
  */
-int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
+		       struct sk_buff *skb)
 {
 	struct fc_frame_header *fh;
 	u16 old_xid;
 	u8 op;
+	u8 mac[ETH_ALEN];
 
 	fh = (struct fc_frame_header *)skb->data;
 	op = *(u8 *)(fh + 1);
@@ -498,6 +499,8 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr
 
 	if (fip->state == FIP_ST_NON_FIP)
 		return 0;
+	if (!fip->sel_fcf)
+		goto drop;
 
 	switch (op) {
 	case ELS_FLOGI:
@@ -530,14 +533,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr
 		 * FLOGI.
 		 */
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
+		fc_fcoe_set_mac(mac, fh->fh_d_id);
+		fip->update_mac(lport, mac);
 		return 0;
 	default:
 		if (fip->state != FIP_ST_ENABLED)
 			goto drop;
 		return 0;
 	}
-	if (fcoe_ctlr_encaps(fip, op, skb))
+	if (fcoe_ctlr_encaps(fip, lport, op, skb))
 		goto drop;
 	fip->send(fip, skb);
 	return -EINPROGRESS;
@@ -547,9 +551,9 @@ drop:
 }
 EXPORT_SYMBOL(fcoe_ctlr_els_send);
 
-/*
- * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller.
- * @fip:	FCoE controller.
+/**
+ * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller
+ * @fip: The FCoE controller to free FCFs on
  *
  * Called with lock held.
  *
@@ -558,14 +562,28 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
  * times its keep-alive period including fuzz.
  *
  * In addition, determine the time when an FCF selection can occur.
+ *
+ * Also, increment the MissDiscAdvCount when no advertisement is received
+ * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
  */
 static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
 {
 	struct fcoe_fcf *fcf;
 	struct fcoe_fcf *next;
 	unsigned long sel_time = 0;
+	unsigned long mda_time = 0;
 
 	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+		mda_time = fcf->fka_period + (fcf->fka_period >> 1);
+		if ((fip->sel_fcf == fcf) &&
+		    (time_after(jiffies, fcf->time + mda_time))) {
+			mod_timer(&fip->timer, jiffies + mda_time);
+			fc_lport_get_stats(fip->lp)->MissDiscAdvCount++;
+			printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
+			       "Advertisement for fab %llx count %lld\n",
+			       fip->lp->host->host_no, fcf->fabric_name,
+			       fc_lport_get_stats(fip->lp)->MissDiscAdvCount);
+		}
 		if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
 			       msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
 			if (fip->sel_fcf == fcf)
@@ -574,6 +592,7 @@ static void fcoe_ctlr_age_fcfs(struct fc
 			WARN_ON(!fip->fcf_count);
 			fip->fcf_count--;
 			kfree(fcf);
+			fc_lport_get_stats(fip->lp)->VLinkFailureCount++;
 		} else if (fcoe_ctlr_mtu_valid(fcf) &&
 			   (!sel_time || time_before(sel_time, fcf->time))) {
 			sel_time = fcf->time;
@@ -590,14 +609,16 @@ static void fcoe_ctlr_age_fcfs(struct fc
 }
 
 /**
- * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry.
- * @skb:	received FIP advertisement frame
- * @fcf:	resulting FCF entry.
+ * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry
+ * @fip: The FCoE controller receiving the advertisement
+ * @skb: The received FIP advertisement frame
+ * @fcf: The resulting FCF entry
  *
  * Returns zero on a valid parsed advertisement,
  * otherwise returns non zero value.
  */
-static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
+static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
+			       struct sk_buff *skb, struct fcoe_fcf *fcf)
 {
 	struct fip_header *fiph;
 	struct fip_desc *desc = NULL;
@@ -636,7 +657,7 @@ static int fcoe_ctlr_parse_adv(struct sk
 			       ((struct fip_mac_desc *)desc)->fd_mac,
 			       ETH_ALEN);
 			if (!is_valid_ether_addr(fcf->fcf_mac)) {
-				LIBFCOE_FIP_DBG("Invalid MAC address "
+				LIBFCOE_FIP_DBG(fip, "Invalid MAC address "
 						"in FIP adv\n");
 				return -EINVAL;
 			}
@@ -659,6 +680,8 @@ static int fcoe_ctlr_parse_adv(struct sk
 			if (dlen != sizeof(struct fip_fka_desc))
 				goto len_err;
 			fka = (struct fip_fka_desc *)desc;
+			if (fka->fd_flags & FIP_FKA_ADV_D)
+				fcf->fd_flags = 1;
 			t = ntohl(fka->fd_fka_period);
 			if (t >= FCOE_CTLR_MIN_FKA)
 				fcf->fka_period = msecs_to_jiffies(t);
@@ -670,7 +693,7 @@ static int fcoe_ctlr_parse_adv(struct sk
 		case FIP_DT_LOGO:
 		case FIP_DT_ELP:
 		default:
-			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
+			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
 					"in FIP adv\n", desc->fip_dtype);
 			/* standard says ignore unknown descriptors >= 128 */
 			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
@@ -687,15 +710,15 @@ static int fcoe_ctlr_parse_adv(struct sk
 	return 0;
 
 len_err:
-	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
 			desc->fip_dtype, dlen);
 	return -EINVAL;
 }
 
 /**
- * fcoe_ctlr_recv_adv() - Handle an incoming advertisement.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_adv() - Handle an incoming advertisement
+ * @fip: The FCoE controller receiving the advertisement
+ * @skb: The received FIP packet
  */
 static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
@@ -706,7 +729,7 @@ static void fcoe_ctlr_recv_adv(struct fc
 	int first = 0;
 	int mtu_valid;
 
-	if (fcoe_ctlr_parse_adv(skb, &new))
+	if (fcoe_ctlr_parse_adv(fip, skb, &new))
 		return;
 
 	spin_lock_bh(&fip->lock);
@@ -752,7 +775,7 @@ static void fcoe_ctlr_recv_adv(struct fc
 	mtu_valid = fcoe_ctlr_mtu_valid(fcf);
 	fcf->time = jiffies;
 	if (!found) {
-		LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n",
+		LIBFCOE_FIP_DBG(fip, "New FCF for fab %llx map %x val %d\n",
 				fcf->fabric_name, fcf->fc_map, mtu_valid);
 	}
 
@@ -778,7 +801,7 @@ static void fcoe_ctlr_recv_adv(struct fc
 	 */
 	if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) {
 		fip->sel_time = jiffies +
-				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+			msecs_to_jiffies(FCOE_CTLR_START_DELAY);
 		if (!timer_pending(&fip->timer) ||
 		    time_before(fip->sel_time, fip->timer.expires))
 			mod_timer(&fip->timer, fip->sel_time);
@@ -788,15 +811,15 @@ out:
 }
 
 /**
- * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_els() - Handle an incoming FIP encapsulated ELS frame
+ * @fip: The FCoE controller which received the packet
+ * @skb: The received FIP packet
  */
 static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	struct fc_lport *lp = fip->lp;
+	struct fc_lport *lport = fip->lp;
 	struct fip_header *fiph;
-	struct fc_frame *fp;
+	struct fc_frame *fp = (struct fc_frame *)skb;
 	struct fc_frame_header *fh = NULL;
 	struct fip_desc *desc;
 	struct fip_encaps *els;
@@ -831,10 +854,11 @@ static void fcoe_ctlr_recv_els(struct fc
 			       ((struct fip_mac_desc *)desc)->fd_mac,
 			       ETH_ALEN);
 			if (!is_valid_ether_addr(granted_mac)) {
-				LIBFCOE_FIP_DBG("Invalid MAC address "
+				LIBFCOE_FIP_DBG(fip, "Invalid MAC address "
 						"in FIP ELS\n");
 				goto drop;
 			}
+			memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
 			break;
 		case FIP_DT_FLOGI:
 		case FIP_DT_FDISC:
@@ -850,7 +874,7 @@ static void fcoe_ctlr_recv_els(struct fc
 			els_dtype = desc->fip_dtype;
 			break;
 		default:
-			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
+			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
 					"in FIP adv\n", desc->fip_dtype);
 			/* standard says ignore unknown descriptors >= 128 */
 			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
@@ -867,11 +891,8 @@ static void fcoe_ctlr_recv_els(struct fc
 
 	if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
 	    fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
-	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
+	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac))
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		fip->update_mac(fip, fip->data_src_addr, granted_mac);
-		memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
-	}
 
 	/*
 	 * Convert skb into an fc_frame containing only the ELS.
@@ -882,32 +903,32 @@ static void fcoe_ctlr_recv_els(struct fc
 	fc_frame_init(fp);
 	fr_sof(fp) = FC_SOF_I3;
 	fr_eof(fp) = FC_EOF_T;
-	fr_dev(fp) = lp;
+	fr_dev(fp) = lport;
 
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	stats->RxFrames++;
 	stats->RxWords += skb->len / FIP_BPW;
 
-	fc_exch_recv(lp, fp);
+	fc_exch_recv(lport, fp);
 	return;
 
 len_err:
-	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+	LIBFCOE_FIP_DBG(fip, "FIP length error in descriptor type %x len %zu\n",
 			desc->fip_dtype, dlen);
 drop:
 	kfree_skb(skb);
 }
 
 /**
- * fcoe_ctlr_recv_els() - Handle an incoming link reset frame.
- * @fip:	FCoE controller.
- * @fh:		Received FIP header.
+ * fcoe_ctlr_recv_els() - Handle an incoming link reset frame
+ * @fip: The FCoE controller that received the frame
+ * @fh:	 The received FIP header
  *
  * There may be multiple VN_Port descriptors.
  * The overall length has already been checked.
  */
 static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
-				      struct fip_header *fh)
+				     struct fip_header *fh)
 {
 	struct fip_desc *desc;
 	struct fip_mac_desc *mp;
@@ -916,13 +937,13 @@ static void fcoe_ctlr_recv_clr_vlink(str
 	size_t rlen;
 	size_t dlen;
 	struct fcoe_fcf *fcf = fip->sel_fcf;
-	struct fc_lport *lp = fip->lp;
+	struct fc_lport *lport = fip->lp;
 	u32	desc_mask;
 
-	LIBFCOE_FIP_DBG("Clear Virtual Link received\n");
+	LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
 	if (!fcf)
 		return;
-	if (!fcf || !fc_host_port_id(lp->host))
+	if (!fcf || !fc_host_port_id(lport->host))
 		return;
 
 	/*
@@ -958,9 +979,10 @@ static void fcoe_ctlr_recv_clr_vlink(str
 			if (dlen < sizeof(*vp))
 				return;
 			if (compare_ether_addr(vp->fd_mac,
-			    fip->data_src_addr) == 0 &&
-			    get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
-			    ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
+					       fip->get_src_addr(lport)) == 0 &&
+			    get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn &&
+			    ntoh24(vp->fd_fc_id) ==
+			    fc_host_port_id(lport->host))
 				desc_mask &= ~BIT(FIP_DT_VN_ID);
 			break;
 		default:
@@ -977,33 +999,39 @@ static void fcoe_ctlr_recv_clr_vlink(str
 	 * reset only if all required descriptors were present and valid.
 	 */
 	if (desc_mask) {
-		LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask);
+		LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n",
+				desc_mask);
 	} else {
-		LIBFCOE_FIP_DBG("performing Clear Virtual Link\n");
-		fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
+		LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
+
+		spin_lock_bh(&fip->lock);
+		fc_lport_get_stats(lport)->VLinkFailureCount++;
+		fcoe_ctlr_reset(fip);
+		spin_unlock_bh(&fip->lock);
+
+		fc_lport_reset(fip->lp);
+		fcoe_ctlr_solicit(fip, NULL);
 	}
 }
 
 /**
- * fcoe_ctlr_recv() - Receive a FIP frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv() - Receive a FIP packet
+ * @fip: The FCoE controller that received the packet
+ * @skb: The received FIP packet
  *
- * This is called from NET_RX_SOFTIRQ.
+ * This may be called from either NET_RX_SOFTIRQ or IRQ.
  */
 void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	__skb_queue_tail(&fip->fip_recv_list, skb);
-	spin_unlock_bh(&fip->fip_recv_list.lock);
+	skb_queue_tail(&fip->fip_recv_list, skb);
 	schedule_work(&fip->recv_work);
 }
 EXPORT_SYMBOL(fcoe_ctlr_recv);
 
 /**
- * fcoe_ctlr_recv_handler() - Receive a FIP frame.
- * @fip:	FCoE controller.
- * @skb:	Received FIP packet.
+ * fcoe_ctlr_recv_handler() - Receive a FIP frame
+ * @fip: The FCoE controller that received the frame
+ * @skb: The received FIP frame
  *
  * Returns non-zero if the frame is dropped.
  */
@@ -1038,7 +1066,7 @@ static int fcoe_ctlr_recv_handler(struct
 		fip->map_dest = 0;
 		fip->state = FIP_ST_ENABLED;
 		state = FIP_ST_ENABLED;
-		LIBFCOE_FIP_DBG("Using FIP mode\n");
+		LIBFCOE_FIP_DBG(fip, "Using FIP mode\n");
 	}
 	spin_unlock_bh(&fip->lock);
 	if (state != FIP_ST_ENABLED)
@@ -1060,8 +1088,8 @@ drop:
 }
 
 /**
- * fcoe_ctlr_select() - Select the best FCF, if possible.
- * @fip:	FCoE controller.
+ * fcoe_ctlr_select() - Select the best FCF (if possible)
+ * @fip: The FCoE controller
  *
  * If there are conflicting advertisements, no FCF can be chosen.
  *
@@ -1073,11 +1101,11 @@ static void fcoe_ctlr_select(struct fcoe
 	struct fcoe_fcf *best = NULL;
 
 	list_for_each_entry(fcf, &fip->fcfs, list) {
-		LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x "
+		LIBFCOE_FIP_DBG(fip, "consider FCF for fab %llx VFID %d map %x "
 				"val %d\n", fcf->fabric_name, fcf->vfid,
 				fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
 		if (!fcoe_ctlr_fcf_usable(fcf)) {
-			LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid "
+			LIBFCOE_FIP_DBG(fip, "FCF for fab %llx map %x %svalid "
 					"%savailable\n", fcf->fabric_name,
 					fcf->fc_map, (fcf->flags & FIP_FL_SOL)
 					? "" : "in", (fcf->flags & FIP_FL_AVAIL)
@@ -1091,7 +1119,7 @@ static void fcoe_ctlr_select(struct fcoe
 		if (fcf->fabric_name != best->fabric_name ||
 		    fcf->vfid != best->vfid ||
 		    fcf->fc_map != best->fc_map) {
-			LIBFCOE_FIP_DBG("Conflicting fabric, VFID, "
+			LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, "
 					"or FC-MAP\n");
 			return;
 		}
@@ -1102,8 +1130,8 @@ static void fcoe_ctlr_select(struct fcoe
 }
 
 /**
- * fcoe_ctlr_timeout() - FIP timer function.
- * @arg:	&fcoe_ctlr pointer.
+ * fcoe_ctlr_timeout() - FIP timeout handler
+ * @arg: The FCoE controller that timed out
  *
  * Ages FCFs.  Triggers FCF selection if possible.  Sends keep-alives.
  */
@@ -1113,8 +1141,6 @@ static void fcoe_ctlr_timeout(unsigned l
 	struct fcoe_fcf *sel;
 	struct fcoe_fcf *fcf;
 	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
-	u8 send_ctlr_ka;
-	u8 send_port_ka;
 
 	spin_lock_bh(&fip->lock);
 	if (fip->state == FIP_ST_DISABLED) {
@@ -1140,53 +1166,47 @@ static void fcoe_ctlr_timeout(unsigned l
 			       fip->lp->host->host_no, sel->fcf_mac);
 			memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
 			fip->port_ka_time = jiffies +
-					    msecs_to_jiffies(FIP_VN_KA_PERIOD);
+				msecs_to_jiffies(FIP_VN_KA_PERIOD);
 			fip->ctlr_ka_time = jiffies + sel->fka_period;
-			fip->link = 1;
 		} else {
 			printk(KERN_NOTICE "libfcoe: host%d: "
-			       "FIP Fibre-Channel Forwarder timed out.  "
+			       "FIP Fibre-Channel Forwarder timed out.	"
 			       "Starting FCF discovery.\n",
 			       fip->lp->host->host_no);
-			fip->link = 0;
+			fip->reset_req = 1;
+			schedule_work(&fip->link_work);
 		}
-		schedule_work(&fip->link_work);
 	}
 
-	send_ctlr_ka = 0;
-	send_port_ka = 0;
-	if (sel) {
+	if (sel && !sel->fd_flags) {
 		if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
 			fip->ctlr_ka_time = jiffies + sel->fka_period;
-			send_ctlr_ka = 1;
+			fip->send_ctlr_ka = 1;
 		}
 		if (time_after(next_timer, fip->ctlr_ka_time))
 			next_timer = fip->ctlr_ka_time;
 
 		if (time_after_eq(jiffies, fip->port_ka_time)) {
-			fip->port_ka_time += jiffies +
-					msecs_to_jiffies(FIP_VN_KA_PERIOD);
-			send_port_ka = 1;
+			fip->port_ka_time = jiffies +
+				msecs_to_jiffies(FIP_VN_KA_PERIOD);
+			fip->send_port_ka = 1;
 		}
 		if (time_after(next_timer, fip->port_ka_time))
 			next_timer = fip->port_ka_time;
 		mod_timer(&fip->timer, next_timer);
 	} else if (fip->sel_time) {
 		next_timer = fip->sel_time +
-				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+			msecs_to_jiffies(FCOE_CTLR_START_DELAY);
 		mod_timer(&fip->timer, next_timer);
 	}
+	if (fip->send_ctlr_ka || fip->send_port_ka)
+		schedule_work(&fip->link_work);
 	spin_unlock_bh(&fip->lock);
-
-	if (send_ctlr_ka)
-		fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
-	if (send_port_ka)
-		fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
 }
 
 /**
- * fcoe_ctlr_link_work() - worker thread function for link changes.
- * @work:	pointer to link_work member inside &fcoe_ctlr.
+ * fcoe_ctlr_link_work() - Worker thread function for link changes
+ * @work: Handle to a FCoE controller
  *
  * See if the link status has changed and if so, report it.
  *
@@ -1196,27 +1216,49 @@ static void fcoe_ctlr_timeout(unsigned l
 static void fcoe_ctlr_link_work(struct work_struct *work)
 {
 	struct fcoe_ctlr *fip;
+	struct fc_lport *vport;
+	u8 *mac;
 	int link;
 	int last_link;
+	int reset;
 
 	fip = container_of(work, struct fcoe_ctlr, link_work);
 	spin_lock_bh(&fip->lock);
 	last_link = fip->last_link;
 	link = fip->link;
 	fip->last_link = link;
+	reset = fip->reset_req;
+	fip->reset_req = 0;
 	spin_unlock_bh(&fip->lock);
 
 	if (last_link != link) {
 		if (link)
 			fc_linkup(fip->lp);
 		else
-			fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
+			fc_linkdown(fip->lp);
+	} else if (reset && link)
+		fc_lport_reset(fip->lp);
+
+	if (fip->send_ctlr_ka) {
+		fip->send_ctlr_ka = 0;
+		fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr);
+	}
+	if (fip->send_port_ka) {
+		fip->send_port_ka = 0;
+		mutex_lock(&fip->lp->lp_mutex);
+		mac = fip->get_src_addr(fip->lp);
+		fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac);
+		list_for_each_entry(vport, &fip->lp->vports, list) {
+			mac = fip->get_src_addr(vport);
+			fcoe_ctlr_send_keep_alive(fip, vport, 1, mac);
+		}
+		mutex_unlock(&fip->lp->lp_mutex);
 	}
 }
 
 /**
- * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames.
- * @recv_work:	pointer to recv_work member inside &fcoe_ctlr.
+ * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames
+ * @recv_work: Handle to a FCoE controller
  */
 static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
 {
@@ -1224,20 +1266,14 @@ static void fcoe_ctlr_recv_work(struct w
 	struct sk_buff *skb;
 
 	fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
-	spin_lock_bh(&fip->fip_recv_list.lock);
-	while ((skb = __skb_dequeue(&fip->fip_recv_list))) {
-		spin_unlock_bh(&fip->fip_recv_list.lock);
+	while ((skb = skb_dequeue(&fip->fip_recv_list)))
 		fcoe_ctlr_recv_handler(fip, skb);
-		spin_lock_bh(&fip->fip_recv_list.lock);
-	}
-	spin_unlock_bh(&fip->fip_recv_list.lock);
 }
 
 /**
- * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
- * @fip:	FCoE controller.
- * @fp:		FC frame.
- * @sa:		Ethernet source MAC address from received FCoE frame.
+ * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response
+ * @fip: The FCoE controller
+ * @fp:	 The FC frame to snoop
  *
  * Snoop potential response to FLOGI or even incoming FLOGI.
  *
@@ -1245,15 +1281,18 @@ static void fcoe_ctlr_recv_work(struct w
  * by fip->flogi_oxid != FC_XID_UNKNOWN.
  *
  * The caller is responsible for freeing the frame.
+ * Fill in the granted_mac address.
  *
  * Return non-zero if the frame should not be delivered to libfc.
  */
-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
+			 struct fc_frame *fp)
 {
 	struct fc_frame_header *fh;
 	u8 op;
-	u8 mac[ETH_ALEN];
+	u8 *sa;
 
+	sa = eth_hdr(&fp->skb)->h_source;
 	fh = fc_frame_header_get(fp);
 	if (fh->fh_type != FC_TYPE_ELS)
 		return 0;
@@ -1268,7 +1307,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl
 			return -EINVAL;
 		}
 		fip->state = FIP_ST_NON_FIP;
-		LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");
+		LIBFCOE_FIP_DBG(fip,
+				"received FLOGI LS_ACC using non-FIP mode\n");
 
 		/*
 		 * FLOGI accepted.
@@ -1283,11 +1323,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl
 			fip->map_dest = 0;
 		}
 		fip->flogi_oxid = FC_XID_UNKNOWN;
-		memcpy(mac, fip->data_src_addr, ETH_ALEN);
-		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
 		spin_unlock_bh(&fip->lock);
-
-		fip->update_mac(fip, mac, fip->data_src_addr);
+		fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id);
 	} else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
 		/*
 		 * Save source MAC for point-to-point responses.
@@ -1297,7 +1334,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl
 			memcpy(fip->dest_addr, sa, ETH_ALEN);
 			fip->map_dest = 0;
 			if (fip->state == FIP_ST_NON_FIP)
-				LIBFCOE_FIP_DBG("received FLOGI REQ, "
+				LIBFCOE_FIP_DBG(fip, "received FLOGI REQ, "
 						"using non-FIP mode\n");
 			fip->state = FIP_ST_NON_FIP;
 		}
@@ -1308,10 +1345,10 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl
 EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);
 
 /**
- * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
- * @mac: mac address
- * @scheme: check port
- * @port: port indicator for converting
+ * fcoe_wwn_from_mac() - Converts a 48-bit IEEE MAC address to a 64-bit FC WWN
+ * @mac:    The MAC address to convert
+ * @scheme: The scheme to use when converting
+ * @port:   The port indicator for converting
  *
  * Returns: u64 fc world wide name
  */
@@ -1349,24 +1386,26 @@ u64 fcoe_wwn_from_mac(unsigned char mac[
 EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
 
 /**
- * fcoe_libfc_config() - sets up libfc related properties for lport
- * @lp: ptr to the fc_lport
- * @tt: libfc function template
+ * fcoe_libfc_config() - Sets up libfc related properties for local port
+ * @lp: The local port to configure libfc for
+ * @tt: The libfc function template
  *
  * Returns : 0 for success
  */
-int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
+int fcoe_libfc_config(struct fc_lport *lport,
+		      struct libfc_function_template *tt)
 {
 	/* Set the function pointers set by the LLDD */
-	memcpy(&lp->tt, tt, sizeof(*tt));
-	if (fc_fcp_init(lp))
+	memcpy(&lport->tt, tt, sizeof(*tt));
+	if (fc_fcp_init(lport))
 		return -ENOMEM;
-	fc_exch_init(lp);
-	fc_elsct_init(lp);
-	fc_lport_init(lp);
-	fc_rport_init(lp);
-	fc_disc_init(lp);
+	fc_exch_init(lport);
+	fc_elsct_init(lport);
+	fc_lport_init(lport);
+	fc_rport_init(lport);
+	fc_disc_init(lport);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(fcoe_libfc_config);
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_fcs.c linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_fcs.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_fcs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_fcs.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/workqueue.h>
+#include <scsi/fc/fc_fip.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/fc/fc_fcoe.h>
 #include <scsi/fc_frame.h>
@@ -34,6 +35,8 @@
 
 struct workqueue_struct *fnic_event_queue;
 
+static void fnic_set_eth_mode(struct fnic *);
+
 void fnic_handle_link(struct work_struct *work)
 {
 	struct fnic *fnic = container_of(work, struct fnic, link_work);
@@ -64,10 +67,10 @@ void fnic_handle_link(struct work_struct
 				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 					     "link down\n");
-				fc_linkdown(fnic->lport);
+				fcoe_ctlr_link_down(&fnic->ctlr);
 				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 					     "link up\n");
-				fc_linkup(fnic->lport);
+				fcoe_ctlr_link_up(&fnic->ctlr);
 			} else
 				/* UP -> UP */
 				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
@@ -76,13 +79,13 @@ void fnic_handle_link(struct work_struct
 		/* DOWN -> UP */
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
-		fc_linkup(fnic->lport);
+		fcoe_ctlr_link_up(&fnic->ctlr);
 	} else {
 		/* UP -> DOWN */
 		fnic->lport->host_stats.link_failure_count++;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
-		fc_linkdown(fnic->lport);
+		fcoe_ctlr_link_down(&fnic->ctlr);
 	}
 
 }
@@ -107,197 +110,179 @@ void fnic_handle_frame(struct work_struc
 			return;
 		}
 		fp = (struct fc_frame *)skb;
-		/* if Flogi resp frame, register the address */
-		if (fr_flags(fp)) {
-			vnic_dev_add_addr(fnic->vdev,
-					  fnic->data_src_addr);
-			fr_flags(fp) = 0;
+
+		/*
+		 * If we're in a transitional state, just re-queue and return.
+		 * The queue will be serviced when we get to a stable state.
+		 */
+		if (fnic->state != FNIC_IN_FC_MODE &&
+		    fnic->state != FNIC_IN_ETH_MODE) {
+			skb_queue_head(&fnic->frame_queue, skb);
+			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
+			return;
 		}
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 		fc_exch_recv(lp, fp);
 	}
-
 }
 
-static inline void fnic_import_rq_fc_frame(struct sk_buff *skb,
-					   u32 len, u8 sof, u8 eof)
-{
-	struct fc_frame *fp = (struct fc_frame *)skb;
-
-	skb_trim(skb, len);
-	fr_eof(fp) = eof;
-	fr_sof(fp) = sof;
-}
-
-
-static inline int fnic_import_rq_eth_pkt(struct sk_buff *skb, u32 len)
+/**
+ * fnic_import_rq_eth_pkt() - handle received FCoE or FIP frame.
+ * @fnic:	fnic instance.
+ * @skb:	Ethernet Frame.
+ */
+static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
 {
 	struct fc_frame *fp;
 	struct ethhdr *eh;
-	struct vlan_ethhdr *vh;
 	struct fcoe_hdr *fcoe_hdr;
 	struct fcoe_crc_eof *ft;
-	u32    transport_len = 0;
 
+	/*
+	 * Undo VLAN encapsulation if present.
+	 */
 	eh = (struct ethhdr *)skb->data;
-	vh = (struct vlan_ethhdr *)skb->data;
-	if (vh->h_vlan_proto == htons(ETH_P_8021Q) &&
-	    vh->h_vlan_encapsulated_proto == htons(ETH_P_FCOE)) {
-		skb_pull(skb, sizeof(struct vlan_ethhdr));
-		transport_len += sizeof(struct vlan_ethhdr);
-	} else if (eh->h_proto == htons(ETH_P_FCOE)) {
-		transport_len += sizeof(struct ethhdr);
-		skb_pull(skb, sizeof(struct ethhdr));
-	} else
-		return -1;
+	if (eh->h_proto == htons(ETH_P_8021Q)) {
+		memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
+		eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
+		skb_reset_mac_header(skb);
+	}
+	if (eh->h_proto == htons(ETH_P_FIP)) {
+		skb_pull(skb, sizeof(*eh));
+		fcoe_ctlr_recv(&fnic->ctlr, skb);
+		return 1;		/* let caller know packet was used */
+	}
+	if (eh->h_proto != htons(ETH_P_FCOE))
+		goto drop;
+	skb_set_network_header(skb, sizeof(*eh));
+	skb_pull(skb, sizeof(*eh));
 
 	fcoe_hdr = (struct fcoe_hdr *)skb->data;
 	if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER)
-		return -1;
+		goto drop;
 
 	fp = (struct fc_frame *)skb;
 	fc_frame_init(fp);
 	fr_sof(fp) = fcoe_hdr->fcoe_sof;
 	skb_pull(skb, sizeof(struct fcoe_hdr));
-	transport_len += sizeof(struct fcoe_hdr);
+	skb_reset_transport_header(skb);
 
-	ft = (struct fcoe_crc_eof *)(skb->data + len -
-				     transport_len - sizeof(*ft));
+	ft = (struct fcoe_crc_eof *)(skb->data + skb->len - sizeof(*ft));
 	fr_eof(fp) = ft->fcoe_eof;
-	skb_trim(skb, len - transport_len - sizeof(*ft));
+	skb_trim(skb, skb->len - sizeof(*ft));
 	return 0;
+drop:
+	dev_kfree_skb_irq(skb);
+	return -1;
 }
 
-static inline int fnic_handle_flogi_resp(struct fnic *fnic,
-					 struct fc_frame *fp)
+/**
+ * fnic_update_mac_locked() - set data MAC address and filters.
+ * @fnic:	fnic instance.
+ * @new:	newly-assigned FCoE MAC address.
+ *
+ * Called with the fnic lock held.
+ */
+void fnic_update_mac_locked(struct fnic *fnic, u8 *new)
 {
-	u8 mac[ETH_ALEN] = FC_FCOE_FLOGI_MAC;
-	struct ethhdr *eth_hdr;
-	struct fc_frame_header *fh;
-	int ret = 0;
-	unsigned long flags;
-	struct fc_frame *old_flogi_resp = NULL;
+	u8 *ctl = fnic->ctlr.ctl_src_addr;
+	u8 *data = fnic->data_src_addr;
 
-	fh = (struct fc_frame_header *)fr_hdr(fp);
+	if (is_zero_ether_addr(new))
+		new = ctl;
+	if (!compare_ether_addr(data, new))
+		return;
+	FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "update_mac %pM\n", new);
+	if (!is_zero_ether_addr(data) && compare_ether_addr(data, ctl))
+		vnic_dev_del_addr(fnic->vdev, data);
+	memcpy(data, new, ETH_ALEN);
+	if (compare_ether_addr(new, ctl))
+		vnic_dev_add_addr(fnic->vdev, new);
+}
 
-	spin_lock_irqsave(&fnic->fnic_lock, flags);
+/**
+ * fnic_update_mac() - set data MAC address and filters.
+ * @lport:	local port.
+ * @new:	newly-assigned FCoE MAC address.
+ */
+void fnic_update_mac(struct fc_lport *lport, u8 *new)
+{
+	struct fnic *fnic = lport_priv(lport);
 
-	if (fnic->state == FNIC_IN_ETH_MODE) {
+	spin_lock_irq(&fnic->fnic_lock);
+	fnic_update_mac_locked(fnic, new);
+	spin_unlock_irq(&fnic->fnic_lock);
+}
 
-		/*
-		 * Check if oxid matches on taking the lock. A new Flogi
-		 * issued by libFC might have changed the fnic cached oxid
-		 */
-		if (fnic->flogi_oxid != ntohs(fh->fh_ox_id)) {
-			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
-				     "Flogi response oxid not"
-				     " matching cached oxid, dropping frame"
-				     "\n");
-			ret = -1;
-			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-			dev_kfree_skb_irq(fp_skb(fp));
-			goto handle_flogi_resp_end;
-		}
+/**
+ * fnic_set_port_id() - set the port_ID after successful FLOGI.
+ * @lport:	local port.
+ * @port_id:	assigned FC_ID.
+ * @fp:		received frame containing the FLOGI accept or NULL.
+ *
+ * This is called from libfc when a new FC_ID has been assigned.
+ * This causes us to reset the firmware to FC_MODE and setup the new MAC
+ * address and FC_ID.
+ *
+ * It is also called with FC_ID 0 when we're logged off.
+ *
+ * If the FC_ID is due to point-to-point, fp may be NULL.
+ */
+void fnic_set_port_id(struct fc_lport *lport, u32 port_id, struct fc_frame *fp)
+{
+	struct fnic *fnic = lport_priv(lport);
+	u8 *mac;
+	int ret;
 
-		/* Drop older cached flogi response frame, cache this frame */
-		old_flogi_resp = fnic->flogi_resp;
-		fnic->flogi_resp = fp;
-		fnic->flogi_oxid = FC_XID_UNKNOWN;
+	FNIC_FCS_DBG(KERN_DEBUG, lport->host, "set port_id %x fp %p\n",
+		     port_id, fp);
 
-		/*
-		 * this frame is part of flogi get the src mac addr from this
-		 * frame if the src mac is fcoui based then we mark the
-		 * address mode flag to use fcoui base for dst mac addr
-		 * otherwise we have to store the fcoe gateway addr
-		 */
-		eth_hdr = (struct ethhdr *)skb_mac_header(fp_skb(fp));
-		memcpy(mac, eth_hdr->h_source, ETH_ALEN);
+	/*
+	 * If we're clearing the FC_ID, change to use the ctl_src_addr.
+	 * Set ethernet mode to send FLOGI.
+	 */
+	if (!port_id) {
+		fnic_update_mac(lport, fnic->ctlr.ctl_src_addr);
+		fnic_set_eth_mode(fnic);
+		return;
+	}
 
-		if (ntoh24(mac) == FC_FCOE_OUI)
-			fnic->fcoui_mode = 1;
-		else {
-			fnic->fcoui_mode = 0;
-			memcpy(fnic->dest_addr, mac, ETH_ALEN);
+	if (fp) {
+		mac = fr_cb(fp)->granted_mac;
+		if (is_zero_ether_addr(mac)) {
+			/* non-FIP - FLOGI already accepted - ignore return */
+			fcoe_ctlr_recv_flogi(&fnic->ctlr, lport, fp);
 		}
+		fnic_update_mac(lport, mac);
+	}
 
-		/*
-		 * Except for Flogi frame, all outbound frames from us have the
-		 * Eth Src address as FC_FCOE_OUI"our_sid". Flogi frame uses
-		 * the vnic MAC address as the Eth Src address
-		 */
-		fc_fcoe_set_mac(fnic->data_src_addr, fh->fh_d_id);
-
-		/* We get our s_id from the d_id of the flogi resp frame */
-		fnic->s_id = ntoh24(fh->fh_d_id);
-
-		/* Change state to reflect transition from Eth to FC mode */
+	/* Change state to reflect transition to FC mode */
+	spin_lock_irq(&fnic->fnic_lock);
+	if (fnic->state == FNIC_IN_ETH_MODE || fnic->state == FNIC_IN_FC_MODE)
 		fnic->state = FNIC_IN_ETH_TRANS_FC_MODE;
-
-	} else {
+	else {
 		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
 			     "Unexpected fnic state %s while"
 			     " processing flogi resp\n",
 			     fnic_state_to_str(fnic->state));
-		ret = -1;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		dev_kfree_skb_irq(fp_skb(fp));
-		goto handle_flogi_resp_end;
+		spin_unlock_irq(&fnic->fnic_lock);
+		return;
 	}
-
-	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-
-	/* Drop older cached frame */
-	if (old_flogi_resp)
-		dev_kfree_skb_irq(fp_skb(old_flogi_resp));
+	spin_unlock_irq(&fnic->fnic_lock);
 
 	/*
-	 * send flogi reg request to firmware, this will put the fnic in
-	 * in FC mode
+	 * Send FLOGI registration to firmware to set up FC mode.
+	 * The new address will be set up when registration completes.
 	 */
-	ret = fnic_flogi_reg_handler(fnic);
+	ret = fnic_flogi_reg_handler(fnic, port_id);
 
 	if (ret < 0) {
-		int free_fp = 1;
-		spin_lock_irqsave(&fnic->fnic_lock, flags);
-		/*
-		 * free the frame is some other thread is not
-		 * pointing to it
-		 */
-		if (fnic->flogi_resp != fp)
-			free_fp = 0;
-		else
-			fnic->flogi_resp = NULL;
-
+		spin_lock_irq(&fnic->fnic_lock);
 		if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE)
 			fnic->state = FNIC_IN_ETH_MODE;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (free_fp)
-			dev_kfree_skb_irq(fp_skb(fp));
+		spin_unlock_irq(&fnic->fnic_lock);
 	}
-
- handle_flogi_resp_end:
-	return ret;
-}
-
-/* Returns 1 for a response that matches cached flogi oxid */
-static inline int is_matching_flogi_resp_frame(struct fnic *fnic,
-					       struct fc_frame *fp)
-{
-	struct fc_frame_header *fh;
-	int ret = 0;
-	u32 f_ctl;
-
-	fh = fc_frame_header_get(fp);
-	f_ctl = ntoh24(fh->fh_f_ctl);
-
-	if (fnic->flogi_oxid == ntohs(fh->fh_ox_id) &&
-	    fh->fh_r_ctl == FC_RCTL_ELS_REP &&
-	    (f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) == FC_FC_EX_CTX &&
-	    fh->fh_type == FC_TYPE_ELS)
-		ret = 1;
-
-	return ret;
 }
 
 static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
@@ -326,6 +311,7 @@ static void fnic_rq_cmpl_frame_recv(stru
 	pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len,
 			 PCI_DMA_FROMDEVICE);
 	skb = buf->os_buf;
+	fp = (struct fc_frame *)skb;
 	buf->os_buf = NULL;
 
 	cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index);
@@ -338,6 +324,9 @@ static void fnic_rq_cmpl_frame_recv(stru
 				   &fcoe_enc_error, &fcs_ok, &vlan_stripped,
 				   &vlan);
 		eth_hdrs_stripped = 1;
+		skb_trim(skb, fcp_bytes_written);
+		fr_sof(fp) = sof;
+		fr_eof(fp) = eof;
 
 	} else if (type == CQ_DESC_TYPE_RQ_ENET) {
 		cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
@@ -352,6 +341,14 @@ static void fnic_rq_cmpl_frame_recv(stru
 				    &ipv4_csum_ok, &ipv6, &ipv4,
 				    &ipv4_fragment, &fcs_ok);
 		eth_hdrs_stripped = 0;
+		skb_trim(skb, bytes_written);
+		if (!fcs_ok) {
+			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
+				     "fcs error.  dropping packet.\n");
+			goto drop;
+		}
+		if (fnic_import_rq_eth_pkt(fnic, skb))
+			return;
 
 	} else {
 		/* wrong CQ type*/
@@ -370,43 +367,11 @@ static void fnic_rq_cmpl_frame_recv(stru
 		goto drop;
 	}
 
-	if (eth_hdrs_stripped)
-		fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof);
-	else if (fnic_import_rq_eth_pkt(skb, bytes_written))
-		goto drop;
-
-	fp = (struct fc_frame *)skb;
-
-	/*
-	 * If frame is an ELS response that matches the cached FLOGI OX_ID,
-	 * and is accept, issue flogi_reg_request copy wq request to firmware
-	 * to register the S_ID and determine whether FC_OUI mode or GW mode.
-	 */
-	if (is_matching_flogi_resp_frame(fnic, fp)) {
-		if (!eth_hdrs_stripped) {
-			if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
-				fnic_handle_flogi_resp(fnic, fp);
-				return;
-			}
-			/*
-			 * Recd. Flogi reject. No point registering
-			 * with fw, but forward to libFC
-			 */
-			goto forward;
-		}
-		goto drop;
-	}
-	if (!eth_hdrs_stripped)
-		goto drop;
-
-forward:
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 	if (fnic->stop_rx_link_events) {
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		goto drop;
 	}
-	/* Use fr_flags to indicate whether succ. flogi resp or not */
-	fr_flags(fp) = 0;
 	fr_dev(fp) = fnic->lport;
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
@@ -494,12 +459,49 @@ void fnic_free_rq_buf(struct vnic_rq *rq
 	buf->os_buf = NULL;
 }
 
-static inline int is_flogi_frame(struct fc_frame_header *fh)
+/**
+ * fnic_eth_send() - Send Ethernet frame.
+ * @fip:	fcoe_ctlr instance.
+ * @skb:	Ethernet Frame, FIP, without VLAN encapsulation.
+ */
+void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	return fh->fh_r_ctl == FC_RCTL_ELS_REQ && *(u8 *)(fh + 1) == ELS_FLOGI;
+	struct fnic *fnic = fnic_from_ctlr(fip);
+	struct vnic_wq *wq = &fnic->wq[0];
+	dma_addr_t pa;
+	struct ethhdr *eth_hdr;
+	struct vlan_ethhdr *vlan_hdr;
+	unsigned long flags;
+
+	if (!fnic->vlan_hw_insert) {
+		eth_hdr = (struct ethhdr *)skb_mac_header(skb);
+		vlan_hdr = (struct vlan_ethhdr *)skb_push(skb,
+				sizeof(*vlan_hdr) - sizeof(*eth_hdr));
+		memcpy(vlan_hdr, eth_hdr, 2 * ETH_ALEN);
+		vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
+		vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
+		vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
+	}
+
+	pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+
+	spin_lock_irqsave(&fnic->wq_lock[0], flags);
+	if (!vnic_wq_desc_avail(wq)) {
+		pci_unmap_single(fnic->pdev, pa, skb->len, PCI_DMA_TODEVICE);
+		spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
+		kfree_skb(skb);
+		return;
+	}
+
+	fnic_queue_wq_eth_desc(wq, skb, pa, skb->len,
+			       fnic->vlan_hw_insert, fnic->vlan_id, 1);
+	spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
 }
 
-int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
+/*
+ * Send FC frame.
+ */
+static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
 {
 	struct vnic_wq *wq = &fnic->wq[0];
 	struct sk_buff *skb;
@@ -515,6 +517,10 @@ int fnic_send_frame(struct fnic *fnic, s
 	fh = fc_frame_header_get(fp);
 	skb = fp_skb(fp);
 
+	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
+	    fcoe_ctlr_els_send(&fnic->ctlr, fnic->lport, skb))
+		return 0;
+
 	if (!fnic->vlan_hw_insert) {
 		eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr);
 		vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, eth_hdr_len);
@@ -530,16 +536,11 @@ int fnic_send_frame(struct fnic *fnic, s
 		fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1);
 	}
 
-	if (is_flogi_frame(fh)) {
+	if (fnic->ctlr.map_dest)
 		fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
-		memcpy(eth_hdr->h_source, fnic->mac_addr, ETH_ALEN);
-	} else {
-		if (fnic->fcoui_mode)
-			fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
-		else
-			memcpy(eth_hdr->h_dest, fnic->dest_addr, ETH_ALEN);
-		memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
-	}
+	else
+		memcpy(eth_hdr->h_dest, fnic->ctlr.dest_addr, ETH_ALEN);
+	memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);
 
 	tot_len = skb->len;
 	BUG_ON(tot_len % 4);
@@ -578,109 +579,85 @@ fnic_send_frame_end:
 int fnic_send(struct fc_lport *lp, struct fc_frame *fp)
 {
 	struct fnic *fnic = lport_priv(lp);
-	struct fc_frame_header *fh;
-	int ret = 0;
-	enum fnic_state old_state;
 	unsigned long flags;
-	struct fc_frame *old_flogi = NULL;
-	struct fc_frame *old_flogi_resp = NULL;
 
 	if (fnic->in_remove) {
 		dev_kfree_skb(fp_skb(fp));
-		ret = -1;
-		goto fnic_send_end;
+		return -1;
 	}
 
-	fh = fc_frame_header_get(fp);
-	/* if not an Flogi frame, send it out, this is the common case */
-	if (!is_flogi_frame(fh))
-		return fnic_send_frame(fnic, fp);
+	/*
+	 * Queue frame if in a transitional state.
+	 * This occurs while registering the Port_ID / MAC address after FLOGI.
+	 */
+	spin_lock_irqsave(&fnic->fnic_lock, flags);
+	if (fnic->state != FNIC_IN_FC_MODE && fnic->state != FNIC_IN_ETH_MODE) {
+		skb_queue_tail(&fnic->tx_queue, fp_skb(fp));
+		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	/* Flogi frame, now enter the state machine */
+	return fnic_send_frame(fnic, fp);
+}
 
-	spin_lock_irqsave(&fnic->fnic_lock, flags);
-again:
-	/* Get any old cached frames, free them after dropping lock */
-	old_flogi = fnic->flogi;
-	fnic->flogi = NULL;
-	old_flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
+/**
+ * fnic_flush_tx() - send queued frames.
+ * @fnic: fnic device
+ *
+ * Send frames that were waiting to go out in FC or Ethernet mode.
+ * Whenever changing modes we purge queued frames, so these frames should
+ * be queued for the stable mode that we're in, either FC or Ethernet.
+ *
+ * Called without fnic_lock held.
+ */
+void fnic_flush_tx(struct fnic *fnic)
+{
+	struct sk_buff *skb;
+	struct fc_frame *fp;
 
-	fnic->flogi_oxid = FC_XID_UNKNOWN;
+	while ((skb = skb_dequeue(&fnic->frame_queue))) {
+		fp = (struct fc_frame *)skb;
+		fnic_send_frame(fnic, fp);
+	}
+}
+
+/**
+ * fnic_set_eth_mode() - put fnic into ethernet mode.
+ * @fnic: fnic device
+ *
+ * Called without fnic lock held.
+ */
+static void fnic_set_eth_mode(struct fnic *fnic)
+{
+	unsigned long flags;
+	enum fnic_state old_state;
+	int ret;
 
+	spin_lock_irqsave(&fnic->fnic_lock, flags);
+again:
 	old_state = fnic->state;
 	switch (old_state) {
 	case FNIC_IN_FC_MODE:
 	case FNIC_IN_ETH_TRANS_FC_MODE:
 	default:
 		fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-		vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-		if (old_flogi) {
-			dev_kfree_skb(fp_skb(old_flogi));
-			old_flogi = NULL;
-		}
-		if (old_flogi_resp) {
-			dev_kfree_skb(fp_skb(old_flogi_resp));
-			old_flogi_resp = NULL;
-		}
-
 		ret = fnic_fw_reset_handler(fnic);
 
 		spin_lock_irqsave(&fnic->fnic_lock, flags);
 		if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE)
 			goto again;
-		if (ret) {
+		if (ret)
 			fnic->state = old_state;
-			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-			dev_kfree_skb(fp_skb(fp));
-			goto fnic_send_end;
-		}
-		old_flogi = fnic->flogi;
-		fnic->flogi = fp;
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		old_flogi_resp = fnic->flogi_resp;
-		fnic->flogi_resp = NULL;
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 		break;
 
 	case FNIC_IN_FC_TRANS_ETH_MODE:
-		/*
-		 * A reset is pending with the firmware. Store the flogi
-		 * and its oxid. The transition out of this state happens
-		 * only when Firmware completes the reset, either with
-		 * success or failed. If success, transition to
-		 * FNIC_IN_ETH_MODE, if fail, then transition to
-		 * FNIC_IN_FC_MODE
-		 */
-		fnic->flogi = fp;
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		break;
-
 	case FNIC_IN_ETH_MODE:
-		/*
-		 * The fw/hw is already in eth mode. Store the oxid,
-		 * and send the flogi frame out. The transition out of this
-		 * state happens only we receive flogi response from the
-		 * network, and the oxid matches the cached oxid when the
-		 * flogi frame was sent out. If they match, then we issue
-		 * a flogi_reg request and transition to state
-		 * FNIC_IN_ETH_TRANS_FC_MODE
-		 */
-		fnic->flogi_oxid = ntohs(fh->fh_ox_id);
-		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		ret = fnic_send_frame(fnic, fp);
 		break;
 	}
-
-fnic_send_end:
-	if (old_flogi)
-		dev_kfree_skb(fp_skb(old_flogi));
-	if (old_flogi_resp)
-		dev_kfree_skb(fp_skb(old_flogi_resp));
-	return ret;
+	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 }
 
 static void fnic_wq_complete_frame_send(struct vnic_wq *wq,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic.h linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic.h	2010-02-24 13:52:17.000000000 -0500
@@ -22,6 +22,7 @@
 #include <linux/netdevice.h>
 #include <linux/workqueue.h>
 #include <scsi/libfc.h>
+#include <scsi/libfcoe.h>
 #include "fnic_io.h"
 #include "fnic_res.h"
 #include "vnic_dev.h"
@@ -44,7 +45,7 @@
 #define	FNIC_IO_LOCKS		64 /* IO locks: power of 2 */
 #define FNIC_DFLT_QUEUE_DEPTH	32
 #define	FNIC_STATS_RATE_LIMIT	4 /* limit rate at which stats are pulled up */
-
+#define FNIC_MAX_CMD_LEN        16 /* Supported CDB length */
 /*
  * Tag bits used for special requests.
  */
@@ -145,6 +146,7 @@ struct mempool;
 /* Per-instance private data structure */
 struct fnic {
 	struct fc_lport *lport;
+	struct fcoe_ctlr ctlr;		/* FIP FCoE controller structure */
 	struct vnic_dev_bar bar0;
 
 	struct msix_entry msix_entry[FNIC_MSIX_INTR_MAX];
@@ -162,23 +164,16 @@ struct fnic {
 	unsigned int wq_count;
 	unsigned int cq_count;
 
-	u32 fcoui_mode:1;		/* use fcoui address*/
 	u32 vlan_hw_insert:1;	        /* let hw insert the tag */
 	u32 in_remove:1;                /* fnic device in removal */
 	u32 stop_rx_link_events:1;      /* stop proc. rx frames, link events */
 
 	struct completion *remove_wait; /* device remove thread blocks */
 
-	struct fc_frame *flogi;
-	struct fc_frame *flogi_resp;
-	u16 flogi_oxid;
-	unsigned long s_id;
 	enum fnic_state state;
 	spinlock_t fnic_lock;
 
 	u16 vlan_id;	                /* VLAN tag including priority */
-	u8 mac_addr[ETH_ALEN];
-	u8 dest_addr[ETH_ALEN];
 	u8 data_src_addr[ETH_ALEN];
 	u64 fcp_input_bytes;		/* internal statistic */
 	u64 fcp_output_bytes;		/* internal statistic */
@@ -205,6 +200,7 @@ struct fnic {
 	struct work_struct link_work;
 	struct work_struct frame_work;
 	struct sk_buff_head frame_queue;
+	struct sk_buff_head tx_queue;
 
 	/* copy work queue cache line section */
 	____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX];
@@ -224,6 +220,11 @@ struct fnic {
 	____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX];
 };
 
+static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
+{
+	return container_of(fip, struct fnic, ctlr);
+}
+
 extern struct workqueue_struct *fnic_event_queue;
 extern struct device_attribute *fnic_attrs[];
 
@@ -239,7 +240,11 @@ void fnic_handle_link(struct work_struct
 int fnic_rq_cmpl_handler(struct fnic *fnic, int);
 int fnic_alloc_rq_frame(struct vnic_rq *rq);
 void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
-int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp);
+void fnic_flush_tx(struct fnic *);
+void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb);
+void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
+void fnic_update_mac(struct fc_lport *, u8 *new);
+void fnic_update_mac_locked(struct fnic *, u8 *new);
 
 int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
 int fnic_abort_cmd(struct scsi_cmnd *);
@@ -252,7 +257,7 @@ void fnic_empty_scsi_cleanup(struct fc_l
 void fnic_exch_mgr_reset(struct fc_lport *, u32, u32);
 int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int);
 int fnic_wq_cmpl_handler(struct fnic *fnic, int);
-int fnic_flogi_reg_handler(struct fnic *fnic);
+int fnic_flogi_reg_handler(struct fnic *fnic, u32);
 void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
 				  struct fcpio_host_req *desc);
 int fnic_fw_reset_handler(struct fnic *fnic);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_isr.c linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_isr.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_isr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_isr.c	2010-02-24 13:52:17.000000000 -0500
@@ -48,9 +48,9 @@ static irqreturn_t fnic_isr_legacy(int i
 	}
 
 	if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) {
-		work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
-		work_done += fnic_wq_cmpl_handler(fnic, 4);
-		work_done += fnic_rq_cmpl_handler(fnic, 4);
+		work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+		work_done += fnic_wq_cmpl_handler(fnic, -1);
+		work_done += fnic_rq_cmpl_handler(fnic, -1);
 
 		vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ],
 					 work_done,
@@ -66,9 +66,9 @@ static irqreturn_t fnic_isr_msi(int irq,
 	struct fnic *fnic = data;
 	unsigned long work_done = 0;
 
-	work_done += fnic_wq_copy_cmpl_handler(fnic, 8);
-	work_done += fnic_wq_cmpl_handler(fnic, 4);
-	work_done += fnic_rq_cmpl_handler(fnic, 4);
+	work_done += fnic_wq_copy_cmpl_handler(fnic, -1);
+	work_done += fnic_wq_cmpl_handler(fnic, -1);
+	work_done += fnic_rq_cmpl_handler(fnic, -1);
 
 	vnic_intr_return_credits(&fnic->intr[0],
 				 work_done,
@@ -83,7 +83,7 @@ static irqreturn_t fnic_isr_msix_rq(int
 	struct fnic *fnic = data;
 	unsigned long rq_work_done = 0;
 
-	rq_work_done = fnic_rq_cmpl_handler(fnic, 4);
+	rq_work_done = fnic_rq_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_RQ],
 				 rq_work_done,
 				 1 /* unmask intr */,
@@ -97,7 +97,7 @@ static irqreturn_t fnic_isr_msix_wq(int
 	struct fnic *fnic = data;
 	unsigned long wq_work_done = 0;
 
-	wq_work_done = fnic_wq_cmpl_handler(fnic, 4);
+	wq_work_done = fnic_wq_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ],
 				 wq_work_done,
 				 1 /* unmask intr */,
@@ -110,7 +110,7 @@ static irqreturn_t fnic_isr_msix_wq_copy
 	struct fnic *fnic = data;
 	unsigned long wq_copy_work_done = 0;
 
-	wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, 8);
+	wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1);
 	vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY],
 				 wq_copy_work_done,
 				 1 /* unmask intr */,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_main.c linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_main.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_main.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_main.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,6 +25,8 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
+#include <linux/if_ether.h>
+#include <scsi/fc/fc_fip.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_fc.h>
@@ -68,6 +70,7 @@ MODULE_PARM_DESC(fnic_log_level, "bit ma
 
 static struct libfc_function_template fnic_transport_template = {
 	.frame_send = fnic_send,
+	.lport_set_port_id = fnic_set_port_id,
 	.fcp_abort_io = fnic_empty_scsi_cleanup,
 	.fcp_cleanup = fnic_empty_scsi_cleanup,
 	.exch_mgr_reset = fnic_exch_mgr_reset
@@ -140,6 +143,7 @@ static struct fc_function_template fnic_
 	.get_fc_host_stats = fnic_get_stats,
 	.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
 	.terminate_rport_io = fnic_terminate_rport_io,
+	.bsg_request = fc_lport_bsg_request,
 };
 
 static void fnic_get_host_speed(struct Scsi_Host *shost)
@@ -324,9 +328,6 @@ static int fnic_cleanup(struct fnic *fni
 {
 	unsigned int i;
 	int err;
-	unsigned long flags;
-	struct fc_frame *flogi = NULL;
-	struct fc_frame *flogi_resp = NULL;
 
 	vnic_dev_disable(fnic->vdev);
 	for (i = 0; i < fnic->intr_count; i++)
@@ -367,24 +368,6 @@ static int fnic_cleanup(struct fnic *fni
 	for (i = 0; i < fnic->intr_count; i++)
 		vnic_intr_clean(&fnic->intr[i]);
 
-	/*
-	 * Remove cached flogi and flogi resp frames if any
-	 * These frames are not in any queue, and therefore queue
-	 * cleanup does not clean them. So clean them explicitly
-	 */
-	spin_lock_irqsave(&fnic->fnic_lock, flags);
-	flogi = fnic->flogi;
-	fnic->flogi = NULL;
-	flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
-	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-
-	if (flogi)
-		dev_kfree_skb(fp_skb(flogi));
-
-	if (flogi_resp)
-		dev_kfree_skb(fp_skb(flogi_resp));
-
 	mempool_destroy(fnic->io_req_pool);
 	for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
 		mempool_destroy(fnic->io_sgl_pool[i]);
@@ -409,6 +392,17 @@ static void *fnic_alloc_slab_dma(gfp_t g
 	return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA);
 }
 
+/**
+ * fnic_get_mac() - get assigned data MAC address for FIP code.
+ * @lport: 	local port.
+ */
+static u8 *fnic_get_mac(struct fc_lport *lport)
+{
+	struct fnic *fnic = lport_priv(lport);
+
+	return fnic->data_src_addr;
+}
+
 static int __devinit fnic_probe(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
 {
@@ -424,17 +418,16 @@ static int __devinit fnic_probe(struct p
 	 * Allocate SCSI Host and set up association between host,
 	 * local port, and fnic
 	 */
-	host = scsi_host_alloc(&fnic_host_template,
-			       sizeof(struct fc_lport) + sizeof(struct fnic));
-	if (!host) {
-		printk(KERN_ERR PFX "Unable to alloc SCSI host\n");
+	lp = libfc_host_alloc(&fnic_host_template, sizeof(struct fnic));
+	if (!lp) {
+		printk(KERN_ERR PFX "Unable to alloc libfc local port\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
-	lp = shost_priv(host);
-	lp->host = host;
+	host = lp->host;
 	fnic = lport_priv(lp);
 	fnic->lport = lp;
+	fnic->ctlr.lp = lp;
 
 	snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
 		 host->host_no);
@@ -543,12 +536,14 @@ static int __devinit fnic_probe(struct p
 		goto err_out_dev_close;
 	}
 
-	err = vnic_dev_mac_addr(fnic->vdev, fnic->mac_addr);
+	err = vnic_dev_mac_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
 	if (err) {
 		shost_printk(KERN_ERR, fnic->lport->host,
 			     "vNIC get MAC addr failed \n");
 		goto err_out_dev_close;
 	}
+	/* set data_src for point-to-point mode and to keep it non-zero */
+	memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
 
 	/* Get vNIC configuration */
 	err = fnic_get_vnic_config(fnic);
@@ -560,6 +555,7 @@ static int __devinit fnic_probe(struct p
 	}
 	host->max_lun = fnic->config.luns_per_tgt;
 	host->max_id = FNIC_MAX_FCP_TARGET;
+	host->max_cmd_len = FNIC_MAX_CMD_LEN;
 
 	fnic_get_res_counts(fnic);
 
@@ -571,19 +567,12 @@ static int __devinit fnic_probe(struct p
 		goto err_out_dev_close;
 	}
 
-	err = fnic_request_intr(fnic);
-	if (err) {
-		shost_printk(KERN_ERR, fnic->lport->host,
-			     "Unable to request irq.\n");
-		goto err_out_clear_intr;
-	}
-
 	err = fnic_alloc_vnic_resources(fnic);
 	if (err) {
 		shost_printk(KERN_ERR, fnic->lport->host,
 			     "Failed to alloc vNIC resources, "
 			     "aborting.\n");
-		goto err_out_free_intr;
+		goto err_out_clear_intr;
 	}
 
 
@@ -623,9 +612,21 @@ static int __devinit fnic_probe(struct p
 	fnic->vlan_hw_insert = 1;
 	fnic->vlan_id = 0;
 
-	fnic->flogi_oxid = FC_XID_UNKNOWN;
-	fnic->flogi = NULL;
-	fnic->flogi_resp = NULL;
+	/* Initialize the FIP fcoe_ctrl struct */
+	fnic->ctlr.send = fnic_eth_send;
+	fnic->ctlr.update_mac = fnic_update_mac;
+	fnic->ctlr.get_src_addr = fnic_get_mac;
+	fcoe_ctlr_init(&fnic->ctlr);
+	if (fnic->config.flags & VFCF_FIP_CAPABLE) {
+		shost_printk(KERN_INFO, fnic->lport->host,
+			     "firmware supports FIP\n");
+		vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
+		vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
+	} else {
+		shost_printk(KERN_INFO, fnic->lport->host,
+			     "firmware uses non-FIP mode\n");
+		fnic->ctlr.mode = FIP_ST_NON_FIP;
+	}
 	fnic->state = FNIC_IN_FC_MODE;
 
 	/* Enable hardware stripping of vlan header on ingress */
@@ -716,6 +717,7 @@ static int __devinit fnic_probe(struct p
 	INIT_WORK(&fnic->link_work, fnic_handle_link);
 	INIT_WORK(&fnic->frame_work, fnic_handle_frame);
 	skb_queue_head_init(&fnic->frame_queue);
+	skb_queue_head_init(&fnic->tx_queue);
 
 	/* Enable all queues */
 	for (i = 0; i < fnic->raw_wq_count; i++)
@@ -728,6 +730,14 @@ static int __devinit fnic_probe(struct p
 	fc_fabric_login(lp);
 
 	vnic_dev_enable(fnic->vdev);
+
+	err = fnic_request_intr(fnic);
+	if (err) {
+		shost_printk(KERN_ERR, fnic->lport->host,
+			     "Unable to request irq.\n");
+		goto err_out_free_exch_mgr;
+	}
+
 	for (i = 0; i < fnic->intr_count; i++)
 		vnic_intr_unmask(&fnic->intr[i]);
 
@@ -738,8 +748,8 @@ static int __devinit fnic_probe(struct p
 err_out_free_exch_mgr:
 	fc_exch_mgr_free(lp);
 err_out_remove_scsi_host:
-	fc_remove_host(fnic->lport->host);
-	scsi_remove_host(fnic->lport->host);
+	fc_remove_host(lp->host);
+	scsi_remove_host(lp->host);
 err_out_free_rq_buf:
 	for (i = 0; i < fnic->rq_count; i++)
 		vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
@@ -752,8 +762,6 @@ err_out_free_ioreq_pool:
 	mempool_destroy(fnic->io_req_pool);
 err_out_free_resources:
 	fnic_free_vnic_resources(fnic);
-err_out_free_intr:
-	fnic_free_intr(fnic);
 err_out_clear_intr:
 	fnic_clear_intr_mode(fnic);
 err_out_dev_close:
@@ -775,6 +783,7 @@ err_out:
 static void __devexit fnic_remove(struct pci_dev *pdev)
 {
 	struct fnic *fnic = pci_get_drvdata(pdev);
+	struct fc_lport *lp = fnic->lport;
 	unsigned long flags;
 
 	/*
@@ -796,6 +805,7 @@ static void __devexit fnic_remove(struct
 	 */
 	flush_workqueue(fnic_event_queue);
 	skb_queue_purge(&fnic->frame_queue);
+	skb_queue_purge(&fnic->tx_queue);
 
 	/*
 	 * Log off the fabric. This stops all remote ports, dns port,
@@ -808,7 +818,8 @@ static void __devexit fnic_remove(struct
 	fnic->in_remove = 1;
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	fc_lport_destroy(fnic->lport);
+	fcoe_ctlr_destroy(&fnic->ctlr);
+	fc_lport_destroy(lp);
 
 	/*
 	 * This stops the fnic device, masks all interrupts. Completed
@@ -818,6 +829,7 @@ static void __devexit fnic_remove(struct
 	fnic_cleanup(fnic);
 
 	BUG_ON(!skb_queue_empty(&fnic->frame_queue));
+	BUG_ON(!skb_queue_empty(&fnic->tx_queue));
 
 	spin_lock_irqsave(&fnic_list_lock, flags);
 	list_del(&fnic->list);
@@ -827,8 +839,8 @@ static void __devexit fnic_remove(struct
 	scsi_remove_host(fnic->lport->host);
 	fc_exch_mgr_free(fnic->lport);
 	vnic_dev_notify_unset(fnic->vdev);
-	fnic_free_vnic_resources(fnic);
 	fnic_free_intr(fnic);
+	fnic_free_vnic_resources(fnic);
 	fnic_clear_intr_mode(fnic);
 	vnic_dev_close(fnic->vdev);
 	vnic_dev_unregister(fnic->vdev);
@@ -836,7 +848,7 @@ static void __devexit fnic_remove(struct
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	scsi_host_put(fnic->lport->host);
+	scsi_host_put(lp->host);
 }
 
 static struct pci_driver fnic_driver = {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_res.c linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_res.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_res.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_res.c	2010-02-24 13:52:17.000000000 -0500
@@ -144,10 +144,9 @@ int fnic_get_vnic_config(struct fnic *fn
 	c->intr_timer_type = c->intr_timer_type;
 
 	shost_printk(KERN_INFO, fnic->lport->host,
-		     "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
+		     "vNIC MAC addr %pM "
 		     "wq/wq_copy/rq %d/%d/%d\n",
-		     fnic->mac_addr[0], fnic->mac_addr[1], fnic->mac_addr[2],
-		     fnic->mac_addr[3], fnic->mac_addr[4], fnic->mac_addr[5],
+		     fnic->ctlr.ctl_src_addr,
 		     c->wq_enet_desc_count, c->wq_copy_desc_count,
 		     c->rq_desc_count);
 	shost_printk(KERN_INFO, fnic->lport->host,
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_res.h linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_res.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_res.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_res.h	2010-02-24 13:52:17.000000000 -0500
@@ -51,6 +51,31 @@ static inline void fnic_queue_wq_desc(st
 	vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
 }
 
+static inline void fnic_queue_wq_eth_desc(struct vnic_wq *wq,
+				      void *os_buf, dma_addr_t dma_addr,
+				      unsigned int len,
+				      int vlan_tag_insert,
+				      unsigned int vlan_tag,
+				      int cq_entry)
+{
+	struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
+
+	wq_enet_desc_enc(desc,
+			 (u64)dma_addr | VNIC_PADDR_TARGET,
+			 (u16)len,
+			 0, /* mss_or_csum_offset */
+			 0, /* fc_eof */
+			 0, /* offload_mode */
+			 1, /* eop */
+			 (u8)cq_entry,
+			 0, /* fcoe_encap */
+			 (u8)vlan_tag_insert,
+			 (u16)vlan_tag,
+			 0 /* loopback */);
+
+	vnic_wq_post(wq, os_buf, dma_addr, len, 1, 1);
+}
+
 static inline void fnic_queue_wq_copy_desc_icmnd_16(struct vnic_wq_copy *wq,
 						    u32 req_id,
 						    u32 lunmap_id, u8 spl_flags,
@@ -58,6 +83,7 @@ static inline void fnic_queue_wq_copy_de
 						    u64 sgl_addr, u64 sns_addr,
 						    u8 crn, u8 pri_ta,
 						    u8 flags, u8 *scsi_cdb,
+						    u8 cdb_len,
 						    u32 data_len, u8 *lun,
 						    u32 d_id, u16 mss,
 						    u32 ratov, u32 edtov)
@@ -82,7 +108,8 @@ static inline void fnic_queue_wq_copy_de
 	desc->u.icmnd_16.pri_ta = pri_ta; 	/* SCSI Pri & Task attribute */
 	desc->u.icmnd_16._resvd1 = 0;           /* reserved: should be 0 */
 	desc->u.icmnd_16.flags = flags;         /* command flags */
-	memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, CDB_16);    /* SCSI CDB */
+	memset(desc->u.icmnd_16.scsi_cdb, 0, CDB_16);
+	memcpy(desc->u.icmnd_16.scsi_cdb, scsi_cdb, cdb_len);    /* SCSI CDB */
 	desc->u.icmnd_16.data_len = data_len;   /* length of data expected */
 	memcpy(desc->u.icmnd_16.lun, lun, LUN_ADDRESS);  /* LUN address */
 	desc->u.icmnd_16._resvd2 = 0;          	/* reserved */
@@ -132,11 +159,36 @@ static inline void fnic_queue_wq_copy_de
 	desc->hdr.tag.u.req_id = req_id;      /* id for this request */
 
 	desc->u.flogi_reg.format = format;
+	desc->u.flogi_reg._resvd = 0;
 	hton24(desc->u.flogi_reg.s_id, s_id);
 	memcpy(desc->u.flogi_reg.gateway_mac, gw_mac, ETH_ALEN);
 
 	vnic_wq_copy_post(wq);
 }
+
+static inline void fnic_queue_wq_copy_desc_fip_reg(struct vnic_wq_copy *wq,
+						   u32 req_id, u32 s_id,
+						   u8 *fcf_mac, u8 *ha_mac,
+						   u32 r_a_tov, u32 e_d_tov)
+{
+	struct fcpio_host_req *desc = vnic_wq_copy_next_desc(wq);
+
+	desc->hdr.type = FCPIO_FLOGI_FIP_REG; /* enum fcpio_type */
+	desc->hdr.status = 0;                 /* header status entry */
+	desc->hdr._resvd = 0;                 /* reserved */
+	desc->hdr.tag.u.req_id = req_id;      /* id for this request */
+
+	desc->u.flogi_fip_reg._resvd0 = 0;
+	hton24(desc->u.flogi_fip_reg.s_id, s_id);
+	memcpy(desc->u.flogi_fip_reg.fcf_mac, fcf_mac, ETH_ALEN);
+	desc->u.flogi_fip_reg._resvd1 = 0;
+	desc->u.flogi_fip_reg.r_a_tov = r_a_tov;
+	desc->u.flogi_fip_reg.e_d_tov = e_d_tov;
+	memcpy(desc->u.flogi_fip_reg.ha_mac, ha_mac, ETH_ALEN);
+	desc->u.flogi_fip_reg._resvd2 = 0;
+
+	vnic_wq_copy_post(wq);
+}
 
 static inline void fnic_queue_wq_copy_desc_fw_reset(struct vnic_wq_copy *wq,
 						    u32 req_id)
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_scsi.c linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_scsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/fnic_scsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/fnic_scsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -174,6 +174,9 @@ int fnic_fw_reset_handler(struct fnic *f
 	int ret = 0;
 	unsigned long flags;
 
+	skb_queue_purge(&fnic->frame_queue);
+	skb_queue_purge(&fnic->tx_queue);
+
 	spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
 
 	if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0])
@@ -200,9 +203,11 @@ int fnic_fw_reset_handler(struct fnic *f
  * fnic_flogi_reg_handler
  * Routine to send flogi register msg to fw
  */
-int fnic_flogi_reg_handler(struct fnic *fnic)
+int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
 {
 	struct vnic_wq_copy *wq = &fnic->wq_copy[0];
+	enum fcpio_flogi_reg_format_type format;
+	struct fc_lport *lp = fnic->lport;
 	u8 gw_mac[ETH_ALEN];
 	int ret = 0;
 	unsigned long flags;
@@ -217,23 +222,32 @@ int fnic_flogi_reg_handler(struct fnic *
 		goto flogi_reg_ioreq_end;
 	}
 
-	if (fnic->fcoui_mode)
+	if (fnic->ctlr.map_dest) {
 		memset(gw_mac, 0xff, ETH_ALEN);
-	else
-		memcpy(gw_mac, fnic->dest_addr, ETH_ALEN);
+		format = FCPIO_FLOGI_REG_DEF_DEST;
+	} else {
+		memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN);
+		format = FCPIO_FLOGI_REG_GW_DEST;
+	}
 
-	fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
-					  FCPIO_FLOGI_REG_GW_DEST,
-					  fnic->s_id,
-					  gw_mac);
+	if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) {
+		fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG,
+						fc_id, gw_mac,
+						fnic->data_src_addr,
+						lp->r_a_tov, lp->e_d_tov);
+		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+			      "FLOGI FIP reg issued fcid %x src %pM dest %pM\n",
+			      fc_id, fnic->data_src_addr, gw_mac);
+	} else {
+		fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
+						  format, fc_id, gw_mac);
+		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+			      "FLOGI reg issued fcid %x map %d dest %pM\n",
+			      fc_id, fnic->ctlr.map_dest, gw_mac);
+	}
 
 flogi_reg_ioreq_end:
 	spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
-
-	if (!ret)
-		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
-			      "flog reg issued\n");
-
 	return ret;
 }
 
@@ -319,7 +333,8 @@ static inline int fnic_queue_wq_copy_des
 					 0, /* scsi cmd ref, always 0 */
 					 pri_tag, /* scsi pri and tag */
 					 flags,	/* command flags */
-					 sc->cmnd, scsi_bufflen(sc),
+					 sc->cmnd, sc->cmd_len,
+					 scsi_bufflen(sc),
 					 fc_lun.scsi_lun, io_req->port_id,
 					 rport->maxframe_size, rp->r_a_tov,
 					 rp->e_d_tov);
@@ -452,7 +467,6 @@ static int fnic_fcpio_fw_reset_cmpl_hand
 	u8 hdr_status;
 	struct fcpio_tag tag;
 	int ret = 0;
-	struct fc_frame *flogi;
 	unsigned long flags;
 
 	fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
@@ -462,9 +476,6 @@ static int fnic_fcpio_fw_reset_cmpl_hand
 
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 
-	flogi = fnic->flogi;
-	fnic->flogi = NULL;
-
 	/* fnic should be in FC_TRANS_ETH_MODE */
 	if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) {
 		/* Check status of reset completion */
@@ -505,17 +516,14 @@ static int fnic_fcpio_fw_reset_cmpl_hand
 	 * free the flogi frame. Else, send it out
 	 */
 	if (fnic->remove_wait || ret) {
-		fnic->flogi_oxid = FC_XID_UNKNOWN;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (flogi)
-			dev_kfree_skb_irq(fp_skb(flogi));
+		skb_queue_purge(&fnic->tx_queue);
 		goto reset_cmpl_handler_end;
 	}
 
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-	if (flogi)
-		ret = fnic_send_frame(fnic, flogi);
+	fnic_flush_tx(fnic);
 
  reset_cmpl_handler_end:
 	return ret;
@@ -532,18 +540,13 @@ static int fnic_fcpio_flogi_reg_cmpl_han
 	u8 hdr_status;
 	struct fcpio_tag tag;
 	int ret = 0;
-	struct fc_frame *flogi_resp = NULL;
 	unsigned long flags;
-	struct sk_buff *skb;
 
 	fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
 
 	/* Update fnic state based on status of flogi reg completion */
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 
-	flogi_resp = fnic->flogi_resp;
-	fnic->flogi_resp = NULL;
-
 	if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) {
 
 		/* Check flogi registration completion status */
@@ -567,25 +570,17 @@ static int fnic_fcpio_flogi_reg_cmpl_han
 		ret = -1;
 	}
 
-	/* Successful flogi reg cmpl, pass frame to LibFC */
-	if (!ret && flogi_resp) {
+	if (!ret) {
 		if (fnic->stop_rx_link_events) {
 			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 			goto reg_cmpl_handler_end;
 		}
-		skb = (struct sk_buff *)flogi_resp;
-		/* Use fr_flags to indicate whether flogi resp or not */
-		fr_flags(flogi_resp) = 1;
-		fr_dev(flogi_resp) = fnic->lport;
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-		skb_queue_tail(&fnic->frame_queue, skb);
+		fnic_flush_tx(fnic);
 		queue_work(fnic_event_queue, &fnic->frame_work);
-
 	} else {
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
-		if (flogi_resp)
-			dev_kfree_skb_irq(fp_skb(flogi_resp));
 	}
 
 reg_cmpl_handler_end:
@@ -907,6 +902,7 @@ static int fnic_fcpio_cmpl_handler(struc
 		break;
 
 	case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
+	case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
 		ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc);
 		break;
 
@@ -1224,22 +1220,6 @@ void fnic_terminate_rport_io(struct fc_r
 
 }
 
-static void fnic_block_error_handler(struct scsi_cmnd *sc)
-{
-	struct Scsi_Host *shost = sc->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		msleep(1000);
-		spin_lock_irqsave(shost->host_lock, flags);
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
-
-}
-
 /*
  * This function is exported to SCSI for sending abort cmnds.
  * A SCSI IO is represented by a io_req in the driver.
@@ -1259,7 +1239,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
 	DECLARE_COMPLETION_ONSTACK(tm_done);
 
 	/* Wait for rport to unblock */
-	fnic_block_error_handler(sc);
+	fc_block_scsi_eh(sc);
 
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
@@ -1541,7 +1521,7 @@ int fnic_device_reset(struct scsi_cmnd *
 	DECLARE_COMPLETION_ONSTACK(tm_done);
 
 	/* Wait for rport to unblock */
-	fnic_block_error_handler(sc);
+	fc_block_scsi_eh(sc);
 
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
@@ -1762,7 +1742,7 @@ void fnic_scsi_abort_io(struct fc_lport
 	fnic->remove_wait = &remove_wait;
 	old_state = fnic->state;
 	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
+	fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 	err = fnic_fw_reset_handler(fnic);
@@ -1802,7 +1782,7 @@ void fnic_scsi_cleanup(struct fc_lport *
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
 	old_state = fnic->state;
 	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
-	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
+	fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
 	if (fnic_fw_reset_handler(fnic)) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/fnic/vnic_scsi.h linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_scsi.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/fnic/vnic_scsi.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/fnic/vnic_scsi.h	2010-02-24 13:52:17.000000000 -0500
@@ -95,5 +95,6 @@ struct vnic_fc_config {
 
 #define VFCF_FCP_SEQ_LVL_ERR	0x1	/* Enable FCP-2 Error Recovery */
 #define VFCF_PERBI		0x2	/* persistent binding info available */
+#define VFCF_FIP_CAPABLE	0x4	/* firmware can handle FIP */
 
 #endif /* _VNIC_SCSI_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/hosts.c linux-libre-2.6.33-gnu1/drivers/scsi/hosts.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/hosts.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/hosts.c	2010-02-24 13:52:17.000000000 -0500
@@ -180,14 +180,20 @@ void scsi_remove_host(struct Scsi_Host *
 EXPORT_SYMBOL(scsi_remove_host);
 
 /**
- * scsi_add_host - add a scsi host
+ * scsi_add_host_with_dma - add a scsi host with dma device
  * @shost:	scsi host pointer to add
  * @dev:	a struct device of type scsi class
+ * @dma_dev:	dma device for the host
+ *
+ * Note: You rarely need to worry about this unless you're in a
+ * virtualised host environments, so use the simpler scsi_add_host()
+ * function instead.
  *
  * Return value: 
  * 	0 on success / != 0 for error
  **/
-int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+			   struct device *dma_dev)
 {
 	struct scsi_host_template *sht = shost->hostt;
 	int error = -EINVAL;
@@ -207,6 +213,7 @@ int scsi_add_host(struct Scsi_Host *shos
 
 	if (!shost->shost_gendev.parent)
 		shost->shost_gendev.parent = dev ? dev : &platform_bus;
+	shost->dma_dev = dma_dev;
 
 	error = device_add(&shost->shost_gendev);
 	if (error)
@@ -262,7 +269,7 @@ int scsi_add_host(struct Scsi_Host *shos
  fail:
 	return error;
 }
-EXPORT_SYMBOL(scsi_add_host);
+EXPORT_SYMBOL(scsi_add_host_with_dma);
 
 static void scsi_host_dev_release(struct device *dev)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/hpsa.c linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/hpsa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,3531 @@
+/*
+ *    Disk Array driver for HP Smart Array SAS controllers
+ *    Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
+ *
+ *    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, 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.
+ *
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/compat.h>
+#include <linux/blktrace_api.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <linux/cciss_ioctl.h>
+#include <linux/string.h>
+#include <linux/bitmap.h>
+#include <asm/atomic.h>
+#include <linux/kthread.h>
+#include "hpsa_cmd.h"
+#include "hpsa.h"
+
+/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
+#define HPSA_DRIVER_VERSION "1.0.0"
+#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
+
+/* How long to wait (in milliseconds) for board to go into simple mode */
+#define MAX_CONFIG_WAIT 30000
+#define MAX_IOCTL_CONFIG_WAIT 1000
+
+/*define how many times we will try a command because of bus resets */
+#define MAX_CMD_RETRIES 3
+
+/* Embedded module documentation macros - see modules.h */
+MODULE_AUTHOR("Hewlett-Packard Company");
+MODULE_DESCRIPTION("Driver for HP Smart Array Controller version " \
+	HPSA_DRIVER_VERSION);
+MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
+MODULE_VERSION(HPSA_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+static int hpsa_allow_any;
+module_param(hpsa_allow_any, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(hpsa_allow_any,
+		"Allow hpsa driver to access unknown HP Smart Array hardware");
+
+/* define the PCI info for the cards we can control */
+static const struct pci_device_id hpsa_pci_device_id[] = {
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3223},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3234},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x323D},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3241},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3243},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3245},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3247},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324a},
+	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324b},
+	{PCI_VENDOR_ID_HP,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
+		PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, hpsa_pci_device_id);
+
+/*  board_id = Subsystem Device ID & Vendor ID
+ *  product = Marketing Name for the board
+ *  access = Address of the struct of function pointers
+ */
+static struct board_type products[] = {
+	{0x3223103C, "Smart Array P800", &SA5_access},
+	{0x3234103C, "Smart Array P400", &SA5_access},
+	{0x323d103c, "Smart Array P700M", &SA5_access},
+	{0x3241103C, "Smart Array P212", &SA5_access},
+	{0x3243103C, "Smart Array P410", &SA5_access},
+	{0x3245103C, "Smart Array P410i", &SA5_access},
+	{0x3247103C, "Smart Array P411", &SA5_access},
+	{0x3249103C, "Smart Array P812", &SA5_access},
+	{0x324a103C, "Smart Array P712m", &SA5_access},
+	{0x324b103C, "Smart Array P711m", &SA5_access},
+	{0xFFFF103C, "Unknown Smart Array", &SA5_access},
+};
+
+static int number_of_controllers;
+
+static irqreturn_t do_hpsa_intr(int irq, void *dev_id);
+static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
+static void start_io(struct ctlr_info *h);
+
+#ifdef CONFIG_COMPAT
+static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg);
+#endif
+
+static void cmd_free(struct ctlr_info *h, struct CommandList *c);
+static void cmd_special_free(struct ctlr_info *h, struct CommandList *c);
+static struct CommandList *cmd_alloc(struct ctlr_info *h);
+static struct CommandList *cmd_special_alloc(struct ctlr_info *h);
+static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h,
+	void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr,
+	int cmd_type);
+
+static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+		void (*done)(struct scsi_cmnd *));
+
+static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
+static int hpsa_slave_alloc(struct scsi_device *sdev);
+static void hpsa_slave_destroy(struct scsi_device *sdev);
+
+static ssize_t raid_level_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t lunid_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t unique_id_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
+static ssize_t host_store_rescan(struct device *dev,
+	 struct device_attribute *attr, const char *buf, size_t count);
+static int check_for_unit_attention(struct ctlr_info *h,
+	struct CommandList *c);
+static void check_ioctl_unit_attention(struct ctlr_info *h,
+	struct CommandList *c);
+
+static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
+static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
+static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL);
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+
+static struct device_attribute *hpsa_sdev_attrs[] = {
+	&dev_attr_raid_level,
+	&dev_attr_lunid,
+	&dev_attr_unique_id,
+	NULL,
+};
+
+static struct device_attribute *hpsa_shost_attrs[] = {
+	&dev_attr_rescan,
+	NULL,
+};
+
+static struct scsi_host_template hpsa_driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "hpsa",
+	.proc_name		= "hpsa",
+	.queuecommand		= hpsa_scsi_queue_command,
+	.can_queue		= 512,
+	.this_id		= -1,
+	.sg_tablesize		= MAXSGENTRIES,
+	.cmd_per_lun		= 512,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
+	.ioctl			= hpsa_ioctl,
+	.slave_alloc		= hpsa_slave_alloc,
+	.slave_destroy		= hpsa_slave_destroy,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl		= hpsa_compat_ioctl,
+#endif
+	.sdev_attrs = hpsa_sdev_attrs,
+	.shost_attrs = hpsa_shost_attrs,
+};
+
+static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
+{
+	unsigned long *priv = shost_priv(sdev->host);
+	return (struct ctlr_info *) *priv;
+}
+
+static struct task_struct *hpsa_scan_thread;
+static DEFINE_MUTEX(hpsa_scan_mutex);
+static LIST_HEAD(hpsa_scan_q);
+static int hpsa_scan_func(void *data);
+
+/**
+ * add_to_scan_list() - add controller to rescan queue
+ * @h:		      Pointer to the controller.
+ *
+ * Adds the controller to the rescan queue if not already on the queue.
+ *
+ * returns 1 if added to the queue, 0 if skipped (could be on the
+ * queue already, or the controller could be initializing or shutting
+ * down).
+ **/
+static int add_to_scan_list(struct ctlr_info *h)
+{
+	struct ctlr_info *test_h;
+	int found = 0;
+	int ret = 0;
+
+	if (h->busy_initializing)
+		return 0;
+
+	/*
+	 * If we don't get the lock, it means the driver is unloading
+	 * and there's no point in scheduling a new scan.
+	 */
+	if (!mutex_trylock(&h->busy_shutting_down))
+		return 0;
+
+	mutex_lock(&hpsa_scan_mutex);
+	list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
+		if (test_h == h) {
+			found = 1;
+			break;
+		}
+	}
+	if (!found && !h->busy_scanning) {
+		INIT_COMPLETION(h->scan_wait);
+		list_add_tail(&h->scan_list, &hpsa_scan_q);
+		ret = 1;
+	}
+	mutex_unlock(&hpsa_scan_mutex);
+	mutex_unlock(&h->busy_shutting_down);
+
+	return ret;
+}
+
+/**
+ * remove_from_scan_list() - remove controller from rescan queue
+ * @h:			   Pointer to the controller.
+ *
+ * Removes the controller from the rescan queue if present. Blocks if
+ * the controller is currently conducting a rescan.  The controller
+ * can be in one of three states:
+ * 1. Doesn't need a scan
+ * 2. On the scan list, but not scanning yet (we remove it)
+ * 3. Busy scanning (and not on the list). In this case we want to wait for
+ *    the scan to complete to make sure the scanning thread for this
+ *    controller is completely idle.
+ **/
+static void remove_from_scan_list(struct ctlr_info *h)
+{
+	struct ctlr_info *test_h, *tmp_h;
+
+	mutex_lock(&hpsa_scan_mutex);
+	list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
+		if (test_h == h) { /* state 2. */
+			list_del(&h->scan_list);
+			complete_all(&h->scan_wait);
+			mutex_unlock(&hpsa_scan_mutex);
+			return;
+		}
+	}
+	if (h->busy_scanning) { /* state 3. */
+		mutex_unlock(&hpsa_scan_mutex);
+		wait_for_completion(&h->scan_wait);
+	} else { /* state 1, nothing to do. */
+		mutex_unlock(&hpsa_scan_mutex);
+	}
+}
+
+/* hpsa_scan_func() - kernel thread used to rescan controllers
+ * @data:	 Ignored.
+ *
+ * A kernel thread used scan for drive topology changes on
+ * controllers. The thread processes only one controller at a time
+ * using a queue.  Controllers are added to the queue using
+ * add_to_scan_list() and removed from the queue either after done
+ * processing or using remove_from_scan_list().
+ *
+ * returns 0.
+ **/
+static int hpsa_scan_func(__attribute__((unused)) void *data)
+{
+	struct ctlr_info *h;
+	int host_no;
+
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+		if (kthread_should_stop())
+			break;
+
+		while (1) {
+			mutex_lock(&hpsa_scan_mutex);
+			if (list_empty(&hpsa_scan_q)) {
+				mutex_unlock(&hpsa_scan_mutex);
+				break;
+			}
+			h = list_entry(hpsa_scan_q.next, struct ctlr_info,
+					scan_list);
+			list_del(&h->scan_list);
+			h->busy_scanning = 1;
+			mutex_unlock(&hpsa_scan_mutex);
+			host_no = h->scsi_host ?  h->scsi_host->host_no : -1;
+			hpsa_update_scsi_devices(h, host_no);
+			complete_all(&h->scan_wait);
+			mutex_lock(&hpsa_scan_mutex);
+			h->busy_scanning = 0;
+			mutex_unlock(&hpsa_scan_mutex);
+		}
+	}
+	return 0;
+}
+
+static int check_for_unit_attention(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	if (c->err_info->SenseInfo[2] != UNIT_ATTENTION)
+		return 0;
+
+	switch (c->err_info->SenseInfo[12]) {
+	case STATE_CHANGED:
+		dev_warn(&h->pdev->dev, "hpsa%d: a state change "
+			"detected, command retried\n", h->ctlr);
+		break;
+	case LUN_FAILED:
+		dev_warn(&h->pdev->dev, "hpsa%d: LUN failure "
+			"detected, action required\n", h->ctlr);
+		break;
+	case REPORT_LUNS_CHANGED:
+		dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
+			"changed\n", h->ctlr);
+	/*
+	 * Here, we could call add_to_scan_list and wake up the scan thread,
+	 * except that it's quite likely that we will get more than one
+	 * REPORT_LUNS_CHANGED condition in quick succession, which means
+	 * that those which occur after the first one will likely happen
+	 * *during* the hpsa_scan_thread's rescan.  And the rescan code is not
+	 * robust enough to restart in the middle, undoing what it has already
+	 * done, and it's not clear that it's even possible to do this, since
+	 * part of what it does is notify the SCSI mid layer, which starts
+	 * doing it's own i/o to read partition tables and so on, and the
+	 * driver doesn't have visibility to know what might need undoing.
+	 * In any event, if possible, it is horribly complicated to get right
+	 * so we just don't do it for now.
+	 *
+	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
+	 */
+		break;
+	case POWER_OR_RESET:
+		dev_warn(&h->pdev->dev, "hpsa%d: a power on "
+			"or device reset detected\n", h->ctlr);
+		break;
+	case UNIT_ATTENTION_CLEARED:
+		dev_warn(&h->pdev->dev, "hpsa%d: unit attention "
+		    "cleared by another initiator\n", h->ctlr);
+		break;
+	default:
+		dev_warn(&h->pdev->dev, "hpsa%d: unknown "
+			"unit attention detected\n", h->ctlr);
+		break;
+	}
+	return 1;
+}
+
+static ssize_t host_store_rescan(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct ctlr_info *h;
+	struct Scsi_Host *shost = class_to_shost(dev);
+	unsigned long *priv = shost_priv(shost);
+	h = (struct ctlr_info *) *priv;
+	if (add_to_scan_list(h)) {
+		wake_up_process(hpsa_scan_thread);
+		wait_for_completion_interruptible(&h->scan_wait);
+	}
+	return count;
+}
+
+/* Enqueuing and dequeuing functions for cmdlists. */
+static inline void addQ(struct hlist_head *list, struct CommandList *c)
+{
+	hlist_add_head(&c->list, list);
+}
+
+static void enqueue_cmd_and_start_io(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&h->lock, flags);
+	addQ(&h->reqQ, c);
+	h->Qdepth++;
+	start_io(h);
+	spin_unlock_irqrestore(&h->lock, flags);
+}
+
+static inline void removeQ(struct CommandList *c)
+{
+	if (WARN_ON(hlist_unhashed(&c->list)))
+		return;
+	hlist_del_init(&c->list);
+}
+
+static inline int is_hba_lunid(unsigned char scsi3addr[])
+{
+	return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0;
+}
+
+static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
+{
+	return (scsi3addr[3] & 0xC0) == 0x40;
+}
+
+static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
+	"UNKNOWN"
+};
+#define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 1)
+
+static ssize_t raid_level_show(struct device *dev,
+	     struct device_attribute *attr, char *buf)
+{
+	ssize_t l = 0;
+	int rlevel;
+	struct ctlr_info *h;
+	struct scsi_device *sdev;
+	struct hpsa_scsi_dev_t *hdev;
+	unsigned long flags;
+
+	sdev = to_scsi_device(dev);
+	h = sdev_to_hba(sdev);
+	spin_lock_irqsave(&h->lock, flags);
+	hdev = sdev->hostdata;
+	if (!hdev) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		return -ENODEV;
+	}
+
+	/* Is this even a logical drive? */
+	if (!is_logical_dev_addr_mode(hdev->scsi3addr)) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		l = snprintf(buf, PAGE_SIZE, "N/A\n");
+		return l;
+	}
+
+	rlevel = hdev->raid_level;
+	spin_unlock_irqrestore(&h->lock, flags);
+	if (rlevel < 0 || rlevel > RAID_UNKNOWN)
+		rlevel = RAID_UNKNOWN;
+	l = snprintf(buf, PAGE_SIZE, "RAID %s\n", raid_label[rlevel]);
+	return l;
+}
+
+static ssize_t lunid_show(struct device *dev,
+	     struct device_attribute *attr, char *buf)
+{
+	struct ctlr_info *h;
+	struct scsi_device *sdev;
+	struct hpsa_scsi_dev_t *hdev;
+	unsigned long flags;
+	unsigned char lunid[8];
+
+	sdev = to_scsi_device(dev);
+	h = sdev_to_hba(sdev);
+	spin_lock_irqsave(&h->lock, flags);
+	hdev = sdev->hostdata;
+	if (!hdev) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		return -ENODEV;
+	}
+	memcpy(lunid, hdev->scsi3addr, sizeof(lunid));
+	spin_unlock_irqrestore(&h->lock, flags);
+	return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+		lunid[0], lunid[1], lunid[2], lunid[3],
+		lunid[4], lunid[5], lunid[6], lunid[7]);
+}
+
+static ssize_t unique_id_show(struct device *dev,
+	     struct device_attribute *attr, char *buf)
+{
+	struct ctlr_info *h;
+	struct scsi_device *sdev;
+	struct hpsa_scsi_dev_t *hdev;
+	unsigned long flags;
+	unsigned char sn[16];
+
+	sdev = to_scsi_device(dev);
+	h = sdev_to_hba(sdev);
+	spin_lock_irqsave(&h->lock, flags);
+	hdev = sdev->hostdata;
+	if (!hdev) {
+		spin_unlock_irqrestore(&h->lock, flags);
+		return -ENODEV;
+	}
+	memcpy(sn, hdev->device_id, sizeof(sn));
+	spin_unlock_irqrestore(&h->lock, flags);
+	return snprintf(buf, 16 * 2 + 2,
+			"%02X%02X%02X%02X%02X%02X%02X%02X"
+			"%02X%02X%02X%02X%02X%02X%02X%02X\n",
+			sn[0], sn[1], sn[2], sn[3],
+			sn[4], sn[5], sn[6], sn[7],
+			sn[8], sn[9], sn[10], sn[11],
+			sn[12], sn[13], sn[14], sn[15]);
+}
+
+static int hpsa_find_target_lun(struct ctlr_info *h,
+	unsigned char scsi3addr[], int bus, int *target, int *lun)
+{
+	/* finds an unused bus, target, lun for a new physical device
+	 * assumes h->devlock is held
+	 */
+	int i, found = 0;
+	DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA);
+
+	memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3);
+
+	for (i = 0; i < h->ndevices; i++) {
+		if (h->dev[i]->bus == bus && h->dev[i]->target != -1)
+			set_bit(h->dev[i]->target, lun_taken);
+	}
+
+	for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) {
+		if (!test_bit(i, lun_taken)) {
+			/* *bus = 1; */
+			*target = i;
+			*lun = 0;
+			found = 1;
+			break;
+		}
+	}
+	return !found;
+}
+
+/* Add an entry into h->dev[] array. */
+static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
+		struct hpsa_scsi_dev_t *device,
+		struct hpsa_scsi_dev_t *added[], int *nadded)
+{
+	/* assumes h->devlock is held */
+	int n = h->ndevices;
+	int i;
+	unsigned char addr1[8], addr2[8];
+	struct hpsa_scsi_dev_t *sd;
+
+	if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) {
+		dev_err(&h->pdev->dev, "too many devices, some will be "
+			"inaccessible.\n");
+		return -1;
+	}
+
+	/* physical devices do not have lun or target assigned until now. */
+	if (device->lun != -1)
+		/* Logical device, lun is already assigned. */
+		goto lun_assigned;
+
+	/* If this device a non-zero lun of a multi-lun device
+	 * byte 4 of the 8-byte LUN addr will contain the logical
+	 * unit no, zero otherise.
+	 */
+	if (device->scsi3addr[4] == 0) {
+		/* This is not a non-zero lun of a multi-lun device */
+		if (hpsa_find_target_lun(h, device->scsi3addr,
+			device->bus, &device->target, &device->lun) != 0)
+			return -1;
+		goto lun_assigned;
+	}
+
+	/* This is a non-zero lun of a multi-lun device.
+	 * Search through our list and find the device which
+	 * has the same 8 byte LUN address, excepting byte 4.
+	 * Assign the same bus and target for this new LUN.
+	 * Use the logical unit number from the firmware.
+	 */
+	memcpy(addr1, device->scsi3addr, 8);
+	addr1[4] = 0;
+	for (i = 0; i < n; i++) {
+		sd = h->dev[i];
+		memcpy(addr2, sd->scsi3addr, 8);
+		addr2[4] = 0;
+		/* differ only in byte 4? */
+		if (memcmp(addr1, addr2, 8) == 0) {
+			device->bus = sd->bus;
+			device->target = sd->target;
+			device->lun = device->scsi3addr[4];
+			break;
+		}
+	}
+	if (device->lun == -1) {
+		dev_warn(&h->pdev->dev, "physical device with no LUN=0,"
+			" suspect firmware bug or unsupported hardware "
+			"configuration.\n");
+			return -1;
+	}
+
+lun_assigned:
+
+	h->dev[n] = device;
+	h->ndevices++;
+	added[*nadded] = device;
+	(*nadded)++;
+
+	/* initially, (before registering with scsi layer) we don't
+	 * know our hostno and we don't want to print anything first
+	 * time anyway (the scsi layer's inquiries will show that info)
+	 */
+	/* if (hostno != -1) */
+		dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n",
+			scsi_device_type(device->devtype), hostno,
+			device->bus, device->target, device->lun);
+	return 0;
+}
+
+/* Remove an entry from h->dev[] array. */
+static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
+	struct hpsa_scsi_dev_t *removed[], int *nremoved)
+{
+	/* assumes h->devlock is held */
+	int i;
+	struct hpsa_scsi_dev_t *sd;
+
+	if (entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA)
+		BUG();
+
+	sd = h->dev[entry];
+	removed[*nremoved] = h->dev[entry];
+	(*nremoved)++;
+
+	for (i = entry; i < h->ndevices-1; i++)
+		h->dev[i] = h->dev[i+1];
+	h->ndevices--;
+	dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n",
+		scsi_device_type(sd->devtype), hostno, sd->bus, sd->target,
+		sd->lun);
+}
+
+#define SCSI3ADDR_EQ(a, b) ( \
+	(a)[7] == (b)[7] && \
+	(a)[6] == (b)[6] && \
+	(a)[5] == (b)[5] && \
+	(a)[4] == (b)[4] && \
+	(a)[3] == (b)[3] && \
+	(a)[2] == (b)[2] && \
+	(a)[1] == (b)[1] && \
+	(a)[0] == (b)[0])
+
+static void fixup_botched_add(struct ctlr_info *h,
+	struct hpsa_scsi_dev_t *added)
+{
+	/* called when scsi_add_device fails in order to re-adjust
+	 * h->dev[] to match the mid layer's view.
+	 */
+	unsigned long flags;
+	int i, j;
+
+	spin_lock_irqsave(&h->lock, flags);
+	for (i = 0; i < h->ndevices; i++) {
+		if (h->dev[i] == added) {
+			for (j = i; j < h->ndevices-1; j++)
+				h->dev[j] = h->dev[j+1];
+			h->ndevices--;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+	kfree(added);
+}
+
+static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
+	struct hpsa_scsi_dev_t *dev2)
+{
+	if ((is_logical_dev_addr_mode(dev1->scsi3addr) ||
+		(dev1->lun != -1 && dev2->lun != -1)) &&
+		dev1->devtype != 0x0C)
+		return (memcmp(dev1, dev2, sizeof(*dev1)) == 0);
+
+	/* we compare everything except lun and target as these
+	 * are not yet assigned.  Compare parts likely
+	 * to differ first
+	 */
+	if (memcmp(dev1->scsi3addr, dev2->scsi3addr,
+		sizeof(dev1->scsi3addr)) != 0)
+		return 0;
+	if (memcmp(dev1->device_id, dev2->device_id,
+		sizeof(dev1->device_id)) != 0)
+		return 0;
+	if (memcmp(dev1->model, dev2->model, sizeof(dev1->model)) != 0)
+		return 0;
+	if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0)
+		return 0;
+	if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0)
+		return 0;
+	if (dev1->devtype != dev2->devtype)
+		return 0;
+	if (dev1->raid_level != dev2->raid_level)
+		return 0;
+	if (dev1->bus != dev2->bus)
+		return 0;
+	return 1;
+}
+
+/* Find needle in haystack.  If exact match found, return DEVICE_SAME,
+ * and return needle location in *index.  If scsi3addr matches, but not
+ * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle
+ * location in *index.  If needle not found, return DEVICE_NOT_FOUND.
+ */
+static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
+	struct hpsa_scsi_dev_t *haystack[], int haystack_size,
+	int *index)
+{
+	int i;
+#define DEVICE_NOT_FOUND 0
+#define DEVICE_CHANGED 1
+#define DEVICE_SAME 2
+	for (i = 0; i < haystack_size; i++) {
+		if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
+			*index = i;
+			if (device_is_the_same(needle, haystack[i]))
+				return DEVICE_SAME;
+			else
+				return DEVICE_CHANGED;
+		}
+	}
+	*index = -1;
+	return DEVICE_NOT_FOUND;
+}
+
+static int adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
+	struct hpsa_scsi_dev_t *sd[], int nsds)
+{
+	/* sd contains scsi3 addresses and devtypes, and inquiry
+	 * data.  This function takes what's in sd to be the current
+	 * reality and updates h->dev[] to reflect that reality.
+	 */
+	int i, entry, device_change, changes = 0;
+	struct hpsa_scsi_dev_t *csd;
+	unsigned long flags;
+	struct hpsa_scsi_dev_t **added, **removed;
+	int nadded, nremoved;
+	struct Scsi_Host *sh = NULL;
+
+	added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+		GFP_KERNEL);
+	removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+		GFP_KERNEL);
+
+	if (!added || !removed) {
+		dev_warn(&h->pdev->dev, "out of memory in "
+			"adjust_hpsa_scsi_table\n");
+		goto free_and_out;
+	}
+
+	spin_lock_irqsave(&h->devlock, flags);
+
+	/* find any devices in h->dev[] that are not in
+	 * sd[] and remove them from h->dev[], and for any
+	 * devices which have changed, remove the old device
+	 * info and add the new device info.
+	 */
+	i = 0;
+	nremoved = 0;
+	nadded = 0;
+	while (i < h->ndevices) {
+		csd = h->dev[i];
+		device_change = hpsa_scsi_find_entry(csd, sd, nsds, &entry);
+		if (device_change == DEVICE_NOT_FOUND) {
+			changes++;
+			hpsa_scsi_remove_entry(h, hostno, i,
+				removed, &nremoved);
+			continue; /* remove ^^^, hence i not incremented */
+		} else if (device_change == DEVICE_CHANGED) {
+			changes++;
+			hpsa_scsi_remove_entry(h, hostno, i,
+				removed, &nremoved);
+			(void) hpsa_scsi_add_entry(h, hostno, sd[entry],
+				added, &nadded);
+			/* add can't fail, we just removed one. */
+			sd[entry] = NULL; /* prevent it from being freed */
+		}
+		i++;
+	}
+
+	/* Now, make sure every device listed in sd[] is also
+	 * listed in h->dev[], adding them if they aren't found
+	 */
+
+	for (i = 0; i < nsds; i++) {
+		if (!sd[i]) /* if already added above. */
+			continue;
+		device_change = hpsa_scsi_find_entry(sd[i], h->dev,
+					h->ndevices, &entry);
+		if (device_change == DEVICE_NOT_FOUND) {
+			changes++;
+			if (hpsa_scsi_add_entry(h, hostno, sd[i],
+				added, &nadded) != 0)
+				break;
+			sd[i] = NULL; /* prevent from being freed later. */
+		} else if (device_change == DEVICE_CHANGED) {
+			/* should never happen... */
+			changes++;
+			dev_warn(&h->pdev->dev,
+				"device unexpectedly changed.\n");
+			/* but if it does happen, we just ignore that device */
+		}
+	}
+	spin_unlock_irqrestore(&h->devlock, flags);
+
+	/* Don't notify scsi mid layer of any changes the first time through
+	 * (or if there are no changes) scsi_scan_host will do it later the
+	 * first time through.
+	 */
+	if (hostno == -1 || !changes)
+		goto free_and_out;
+
+	sh = h->scsi_host;
+	/* Notify scsi mid layer of any removed devices */
+	for (i = 0; i < nremoved; i++) {
+		struct scsi_device *sdev =
+			scsi_device_lookup(sh, removed[i]->bus,
+				removed[i]->target, removed[i]->lun);
+		if (sdev != NULL) {
+			scsi_remove_device(sdev);
+			scsi_device_put(sdev);
+		} else {
+			/* We don't expect to get here.
+			 * future cmds to this device will get selection
+			 * timeout as if the device was gone.
+			 */
+			dev_warn(&h->pdev->dev, "didn't find c%db%dt%dl%d "
+				" for removal.", hostno, removed[i]->bus,
+				removed[i]->target, removed[i]->lun);
+		}
+		kfree(removed[i]);
+		removed[i] = NULL;
+	}
+
+	/* Notify scsi mid layer of any added devices */
+	for (i = 0; i < nadded; i++) {
+		if (scsi_add_device(sh, added[i]->bus,
+			added[i]->target, added[i]->lun) == 0)
+			continue;
+		dev_warn(&h->pdev->dev, "scsi_add_device c%db%dt%dl%d failed, "
+			"device not added.\n", hostno, added[i]->bus,
+			added[i]->target, added[i]->lun);
+		/* now we have to remove it from h->dev,
+		 * since it didn't get added to scsi mid layer
+		 */
+		fixup_botched_add(h, added[i]);
+	}
+
+free_and_out:
+	kfree(added);
+	kfree(removed);
+	return 0;
+}
+
+/*
+ * Lookup bus/target/lun and retrun corresponding struct hpsa_scsi_dev_t *
+ * Assume's h->devlock is held.
+ */
+static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h,
+	int bus, int target, int lun)
+{
+	int i;
+	struct hpsa_scsi_dev_t *sd;
+
+	for (i = 0; i < h->ndevices; i++) {
+		sd = h->dev[i];
+		if (sd->bus == bus && sd->target == target && sd->lun == lun)
+			return sd;
+	}
+	return NULL;
+}
+
+/* link sdev->hostdata to our per-device structure. */
+static int hpsa_slave_alloc(struct scsi_device *sdev)
+{
+	struct hpsa_scsi_dev_t *sd;
+	unsigned long flags;
+	struct ctlr_info *h;
+
+	h = sdev_to_hba(sdev);
+	spin_lock_irqsave(&h->devlock, flags);
+	sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
+		sdev_id(sdev), sdev->lun);
+	if (sd != NULL)
+		sdev->hostdata = sd;
+	spin_unlock_irqrestore(&h->devlock, flags);
+	return 0;
+}
+
+static void hpsa_slave_destroy(struct scsi_device *sdev)
+{
+	return; /* nothing to do. */
+}
+
+static void hpsa_scsi_setup(struct ctlr_info *h)
+{
+	h->ndevices = 0;
+	h->scsi_host = NULL;
+	spin_lock_init(&h->devlock);
+	return;
+}
+
+static void complete_scsi_command(struct CommandList *cp,
+	int timeout, __u32 tag)
+{
+	struct scsi_cmnd *cmd;
+	struct ctlr_info *h;
+	struct ErrorInfo *ei;
+
+	unsigned char sense_key;
+	unsigned char asc;      /* additional sense code */
+	unsigned char ascq;     /* additional sense code qualifier */
+
+	ei = cp->err_info;
+	cmd = (struct scsi_cmnd *) cp->scsi_cmd;
+	h = cp->h;
+
+	scsi_dma_unmap(cmd); /* undo the DMA mappings */
+
+	cmd->result = (DID_OK << 16); 		/* host byte */
+	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
+	cmd->result |= (ei->ScsiStatus << 1);
+
+	/* copy the sense data whether we need to or not. */
+	memcpy(cmd->sense_buffer, ei->SenseInfo,
+		ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
+			SCSI_SENSE_BUFFERSIZE :
+			ei->SenseLen);
+	scsi_set_resid(cmd, ei->ResidualCnt);
+
+	if (ei->CommandStatus == 0) {
+		cmd->scsi_done(cmd);
+		cmd_free(h, cp);
+		return;
+	}
+
+	/* an error has occurred */
+	switch (ei->CommandStatus) {
+
+	case CMD_TARGET_STATUS:
+		if (ei->ScsiStatus) {
+			/* Get sense key */
+			sense_key = 0xf & ei->SenseInfo[2];
+			/* Get additional sense code */
+			asc = ei->SenseInfo[12];
+			/* Get addition sense code qualifier */
+			ascq = ei->SenseInfo[13];
+		}
+
+		if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) {
+			if (check_for_unit_attention(h, cp)) {
+				cmd->result = DID_SOFT_ERROR << 16;
+				break;
+			}
+			if (sense_key == ILLEGAL_REQUEST) {
+				/*
+				 * SCSI REPORT_LUNS is commonly unsupported on
+				 * Smart Array.  Suppress noisy complaint.
+				 */
+				if (cp->Request.CDB[0] == REPORT_LUNS)
+					break;
+
+				/* If ASC/ASCQ indicate Logical Unit
+				 * Not Supported condition,
+				 */
+				if ((asc == 0x25) && (ascq == 0x0)) {
+					dev_warn(&h->pdev->dev, "cp %p "
+						"has check condition\n", cp);
+					break;
+				}
+			}
+
+			if (sense_key == NOT_READY) {
+				/* If Sense is Not Ready, Logical Unit
+				 * Not ready, Manual Intervention
+				 * required
+				 */
+				if ((asc == 0x04) && (ascq == 0x03)) {
+					cmd->result = DID_NO_CONNECT << 16;
+					dev_warn(&h->pdev->dev, "cp %p "
+						"has check condition: unit "
+						"not ready, manual "
+						"intervention required\n", cp);
+					break;
+				}
+			}
+
+
+			/* Must be some other type of check condition */
+			dev_warn(&h->pdev->dev, "cp %p has check condition: "
+					"unknown type: "
+					"Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "
+					"Returning result: 0x%x, "
+					"cmd=[%02x %02x %02x %02x %02x "
+					"%02x %02x %02x %02x %02x]\n",
+					cp, sense_key, asc, ascq,
+					cmd->result,
+					cmd->cmnd[0], cmd->cmnd[1],
+					cmd->cmnd[2], cmd->cmnd[3],
+					cmd->cmnd[4], cmd->cmnd[5],
+					cmd->cmnd[6], cmd->cmnd[7],
+					cmd->cmnd[8], cmd->cmnd[9]);
+			break;
+		}
+
+
+		/* Problem was not a check condition
+		 * Pass it up to the upper layers...
+		 */
+		if (ei->ScsiStatus) {
+			dev_warn(&h->pdev->dev, "cp %p has status 0x%x "
+				"Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "
+				"Returning result: 0x%x\n",
+				cp, ei->ScsiStatus,
+				sense_key, asc, ascq,
+				cmd->result);
+		} else {  /* scsi status is zero??? How??? */
+			dev_warn(&h->pdev->dev, "cp %p SCSI status was 0. "
+				"Returning no connection.\n", cp),
+
+			/* Ordinarily, this case should never happen,
+			 * but there is a bug in some released firmware
+			 * revisions that allows it to happen if, for
+			 * example, a 4100 backplane loses power and
+			 * the tape drive is in it.  We assume that
+			 * it's a fatal error of some kind because we
+			 * can't show that it wasn't. We will make it
+			 * look like selection timeout since that is
+			 * the most common reason for this to occur,
+			 * and it's severe enough.
+			 */
+
+			cmd->result = DID_NO_CONNECT << 16;
+		}
+		break;
+
+	case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
+		break;
+	case CMD_DATA_OVERRUN:
+		dev_warn(&h->pdev->dev, "cp %p has"
+			" completed with data overrun "
+			"reported\n", cp);
+		break;
+	case CMD_INVALID: {
+		/* print_bytes(cp, sizeof(*cp), 1, 0);
+		print_cmd(cp); */
+		/* We get CMD_INVALID if you address a non-existent device
+		 * instead of a selection timeout (no response).  You will
+		 * see this if you yank out a drive, then try to access it.
+		 * This is kind of a shame because it means that any other
+		 * CMD_INVALID (e.g. driver bug) will get interpreted as a
+		 * missing target. */
+		cmd->result = DID_NO_CONNECT << 16;
+	}
+		break;
+	case CMD_PROTOCOL_ERR:
+		dev_warn(&h->pdev->dev, "cp %p has "
+			"protocol error \n", cp);
+		break;
+	case CMD_HARDWARE_ERR:
+		cmd->result = DID_ERROR << 16;
+		dev_warn(&h->pdev->dev, "cp %p had  hardware error\n", cp);
+		break;
+	case CMD_CONNECTION_LOST:
+		cmd->result = DID_ERROR << 16;
+		dev_warn(&h->pdev->dev, "cp %p had connection lost\n", cp);
+		break;
+	case CMD_ABORTED:
+		cmd->result = DID_ABORT << 16;
+		dev_warn(&h->pdev->dev, "cp %p was aborted with status 0x%x\n",
+				cp, ei->ScsiStatus);
+		break;
+	case CMD_ABORT_FAILED:
+		cmd->result = DID_ERROR << 16;
+		dev_warn(&h->pdev->dev, "cp %p reports abort failed\n", cp);
+		break;
+	case CMD_UNSOLICITED_ABORT:
+		cmd->result = DID_ABORT << 16;
+		dev_warn(&h->pdev->dev, "cp %p aborted do to an unsolicited "
+			"abort\n", cp);
+		break;
+	case CMD_TIMEOUT:
+		cmd->result = DID_TIME_OUT << 16;
+		dev_warn(&h->pdev->dev, "cp %p timedout\n", cp);
+		break;
+	default:
+		cmd->result = DID_ERROR << 16;
+		dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n",
+				cp, ei->CommandStatus);
+	}
+	cmd->scsi_done(cmd);
+	cmd_free(h, cp);
+}
+
+static int hpsa_scsi_detect(struct ctlr_info *h)
+{
+	struct Scsi_Host *sh;
+	int error;
+
+	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
+	if (sh == NULL)
+		goto fail;
+
+	sh->io_port = 0;
+	sh->n_io_port = 0;
+	sh->this_id = -1;
+	sh->max_channel = 3;
+	sh->max_cmd_len = MAX_COMMAND_SIZE;
+	sh->max_lun = HPSA_MAX_LUN;
+	sh->max_id = HPSA_MAX_LUN;
+	h->scsi_host = sh;
+	sh->hostdata[0] = (unsigned long) h;
+	sh->irq = h->intr[SIMPLE_MODE_INT];
+	sh->unique_id = sh->irq;
+	error = scsi_add_host(sh, &h->pdev->dev);
+	if (error)
+		goto fail_host_put;
+	scsi_scan_host(sh);
+	return 0;
+
+ fail_host_put:
+	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_add_host"
+		" failed for controller %d\n", h->ctlr);
+	scsi_host_put(sh);
+	return -1;
+ fail:
+	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_host_alloc"
+		" failed for controller %d\n", h->ctlr);
+	return -1;
+}
+
+static void hpsa_pci_unmap(struct pci_dev *pdev,
+	struct CommandList *c, int sg_used, int data_direction)
+{
+	int i;
+	union u64bit addr64;
+
+	for (i = 0; i < sg_used; i++) {
+		addr64.val32.lower = c->SG[i].Addr.lower;
+		addr64.val32.upper = c->SG[i].Addr.upper;
+		pci_unmap_single(pdev, (dma_addr_t) addr64.val, c->SG[i].Len,
+			data_direction);
+	}
+}
+
+static void hpsa_map_one(struct pci_dev *pdev,
+		struct CommandList *cp,
+		unsigned char *buf,
+		size_t buflen,
+		int data_direction)
+{
+	__u64 addr64;
+
+	if (buflen == 0 || data_direction == PCI_DMA_NONE) {
+		cp->Header.SGList = 0;
+		cp->Header.SGTotal = 0;
+		return;
+	}
+
+	addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
+	cp->SG[0].Addr.lower =
+	  (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+	cp->SG[0].Addr.upper =
+	  (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+	cp->SG[0].Len = buflen;
+	cp->Header.SGList = (__u8) 1;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
+}
+
+static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+
+	c->waiting = &wait;
+	enqueue_cmd_and_start_io(h, c);
+	wait_for_completion(&wait);
+}
+
+static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
+	struct CommandList *c, int data_direction)
+{
+	int retry_count = 0;
+
+	do {
+		memset(c->err_info, 0, sizeof(c->err_info));
+		hpsa_scsi_do_simple_cmd_core(h, c);
+		retry_count++;
+	} while (check_for_unit_attention(h, c) && retry_count <= 3);
+	hpsa_pci_unmap(h->pdev, c, 1, data_direction);
+}
+
+static void hpsa_scsi_interpret_error(struct CommandList *cp)
+{
+	struct ErrorInfo *ei;
+	struct device *d = &cp->h->pdev->dev;
+
+	ei = cp->err_info;
+	switch (ei->CommandStatus) {
+	case CMD_TARGET_STATUS:
+		dev_warn(d, "cmd %p has completed with errors\n", cp);
+		dev_warn(d, "cmd %p has SCSI Status = %x\n", cp,
+				ei->ScsiStatus);
+		if (ei->ScsiStatus == 0)
+			dev_warn(d, "SCSI status is abnormally zero.  "
+			"(probably indicates selection timeout "
+			"reported incorrectly due to a known "
+			"firmware bug, circa July, 2001.)\n");
+		break;
+	case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
+			dev_info(d, "UNDERRUN\n");
+		break;
+	case CMD_DATA_OVERRUN:
+		dev_warn(d, "cp %p has completed with data overrun\n", cp);
+		break;
+	case CMD_INVALID: {
+		/* controller unfortunately reports SCSI passthru's
+		 * to non-existent targets as invalid commands.
+		 */
+		dev_warn(d, "cp %p is reported invalid (probably means "
+			"target device no longer present)\n", cp);
+		/* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
+		print_cmd(cp);  */
+		}
+		break;
+	case CMD_PROTOCOL_ERR:
+		dev_warn(d, "cp %p has protocol error \n", cp);
+		break;
+	case CMD_HARDWARE_ERR:
+		/* cmd->result = DID_ERROR << 16; */
+		dev_warn(d, "cp %p had hardware error\n", cp);
+		break;
+	case CMD_CONNECTION_LOST:
+		dev_warn(d, "cp %p had connection lost\n", cp);
+		break;
+	case CMD_ABORTED:
+		dev_warn(d, "cp %p was aborted\n", cp);
+		break;
+	case CMD_ABORT_FAILED:
+		dev_warn(d, "cp %p reports abort failed\n", cp);
+		break;
+	case CMD_UNSOLICITED_ABORT:
+		dev_warn(d, "cp %p aborted due to an unsolicited abort\n", cp);
+		break;
+	case CMD_TIMEOUT:
+		dev_warn(d, "cp %p timed out\n", cp);
+		break;
+	default:
+		dev_warn(d, "cp %p returned unknown status %x\n", cp,
+				ei->CommandStatus);
+	}
+}
+
+static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr,
+			unsigned char page, unsigned char *buf,
+			unsigned char bufsize)
+{
+	int rc = IO_OK;
+	struct CommandList *c;
+	struct ErrorInfo *ei;
+
+	c = cmd_special_alloc(h);
+
+	if (c == NULL) {			/* trouble... */
+		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
+		return -1;
+	}
+
+	fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, page, scsi3addr, TYPE_CMD);
+	hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+	ei = c->err_info;
+	if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		hpsa_scsi_interpret_error(c);
+		rc = -1;
+	}
+	cmd_special_free(h, c);
+	return rc;
+}
+
+static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr)
+{
+	int rc = IO_OK;
+	struct CommandList *c;
+	struct ErrorInfo *ei;
+
+	c = cmd_special_alloc(h);
+
+	if (c == NULL) {			/* trouble... */
+		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
+		return -1;
+	}
+
+	fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);
+	hpsa_scsi_do_simple_cmd_core(h, c);
+	/* no unmap needed here because no data xfer. */
+
+	ei = c->err_info;
+	if (ei->CommandStatus != 0) {
+		hpsa_scsi_interpret_error(c);
+		rc = -1;
+	}
+	cmd_special_free(h, c);
+	return rc;
+}
+
+static void hpsa_get_raid_level(struct ctlr_info *h,
+	unsigned char *scsi3addr, unsigned char *raid_level)
+{
+	int rc;
+	unsigned char *buf;
+
+	*raid_level = RAID_UNKNOWN;
+	buf = kzalloc(64, GFP_KERNEL);
+	if (!buf)
+		return;
+	rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0xC1, buf, 64);
+	if (rc == 0)
+		*raid_level = buf[8];
+	if (*raid_level > RAID_UNKNOWN)
+		*raid_level = RAID_UNKNOWN;
+	kfree(buf);
+	return;
+}
+
+/* Get the device id from inquiry page 0x83 */
+static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr,
+	unsigned char *device_id, int buflen)
+{
+	int rc;
+	unsigned char *buf;
+
+	if (buflen > 16)
+		buflen = 16;
+	buf = kzalloc(64, GFP_KERNEL);
+	if (!buf)
+		return -1;
+	rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0x83, buf, 64);
+	if (rc == 0)
+		memcpy(device_id, &buf[8], buflen);
+	kfree(buf);
+	return rc != 0;
+}
+
+static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical,
+		struct ReportLUNdata *buf, int bufsize,
+		int extended_response)
+{
+	int rc = IO_OK;
+	struct CommandList *c;
+	unsigned char scsi3addr[8];
+	struct ErrorInfo *ei;
+
+	c = cmd_special_alloc(h);
+	if (c == NULL) {			/* trouble... */
+		dev_err(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
+		return -1;
+	}
+
+	memset(&scsi3addr[0], 0, 8); /* address the controller */
+
+	fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h,
+		buf, bufsize, 0, scsi3addr, TYPE_CMD);
+	if (extended_response)
+		c->Request.CDB[1] = extended_response;
+	hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+	ei = c->err_info;
+	if (ei->CommandStatus != 0 &&
+	    ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		hpsa_scsi_interpret_error(c);
+		rc = -1;
+	}
+	cmd_special_free(h, c);
+	return rc;
+}
+
+static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h,
+		struct ReportLUNdata *buf,
+		int bufsize, int extended_response)
+{
+	return hpsa_scsi_do_report_luns(h, 0, buf, bufsize, extended_response);
+}
+
+static inline int hpsa_scsi_do_report_log_luns(struct ctlr_info *h,
+		struct ReportLUNdata *buf, int bufsize)
+{
+	return hpsa_scsi_do_report_luns(h, 1, buf, bufsize, 0);
+}
+
+static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
+	int bus, int target, int lun)
+{
+	device->bus = bus;
+	device->target = target;
+	device->lun = lun;
+}
+
+static int hpsa_update_device_info(struct ctlr_info *h,
+	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
+{
+#define OBDR_TAPE_INQ_SIZE 49
+	unsigned char *inq_buff = NULL;
+
+	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
+	if (!inq_buff)
+		goto bail_out;
+
+	memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
+	/* Do an inquiry to the device to see what it is. */
+	if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff,
+		(unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
+		/* Inquiry failed (msg printed already) */
+		dev_err(&h->pdev->dev,
+			"hpsa_update_device_info: inquiry failed\n");
+		goto bail_out;
+	}
+
+	/* As a side effect, record the firmware version number
+	 * if we happen to be talking to the RAID controller.
+	 */
+	if (is_hba_lunid(scsi3addr))
+		memcpy(h->firm_ver, &inq_buff[32], 4);
+
+	this_device->devtype = (inq_buff[0] & 0x1f);
+	memcpy(this_device->scsi3addr, scsi3addr, 8);
+	memcpy(this_device->vendor, &inq_buff[8],
+		sizeof(this_device->vendor));
+	memcpy(this_device->model, &inq_buff[16],
+		sizeof(this_device->model));
+	memcpy(this_device->revision, &inq_buff[32],
+		sizeof(this_device->revision));
+	memset(this_device->device_id, 0,
+		sizeof(this_device->device_id));
+	hpsa_get_device_id(h, scsi3addr, this_device->device_id,
+		sizeof(this_device->device_id));
+
+	if (this_device->devtype == TYPE_DISK &&
+		is_logical_dev_addr_mode(scsi3addr))
+		hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level);
+	else
+		this_device->raid_level = RAID_UNKNOWN;
+
+	kfree(inq_buff);
+	return 0;
+
+bail_out:
+	kfree(inq_buff);
+	return 1;
+}
+
+static unsigned char *msa2xxx_model[] = {
+	"MSA2012",
+	"MSA2024",
+	"MSA2312",
+	"MSA2324",
+	NULL,
+};
+
+static int is_msa2xxx(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
+{
+	int i;
+
+	for (i = 0; msa2xxx_model[i]; i++)
+		if (strncmp(device->model, msa2xxx_model[i],
+			strlen(msa2xxx_model[i])) == 0)
+			return 1;
+	return 0;
+}
+
+/* Helper function to assign bus, target, lun mapping of devices.
+ * Puts non-msa2xxx logical volumes on bus 0, msa2xxx logical
+ * volumes on bus 1, physical devices on bus 2. and the hba on bus 3.
+ * Logical drive target and lun are assigned at this time, but
+ * physical device lun and target assignment are deferred (assigned
+ * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.)
+ */
+static void figure_bus_target_lun(struct ctlr_info *h,
+	__u8 *lunaddrbytes, int *bus, int *target, int *lun,
+	struct hpsa_scsi_dev_t *device)
+{
+
+	__u32 lunid;
+
+	if (is_logical_dev_addr_mode(lunaddrbytes)) {
+		/* logical device */
+		memcpy(&lunid, lunaddrbytes, sizeof(lunid));
+		lunid = le32_to_cpu(lunid);
+
+		if (is_msa2xxx(h, device)) {
+			*bus = 1;
+			*target = (lunid >> 16) & 0x3fff;
+			*lun = lunid & 0x00ff;
+		} else {
+			*bus = 0;
+			*lun = 0;
+			*target = lunid & 0x3fff;
+		}
+	} else {
+		/* physical device */
+		if (is_hba_lunid(lunaddrbytes))
+			*bus = 3;
+		else
+			*bus = 2;
+		*target = -1;
+		*lun = -1; /* we will fill these in later. */
+	}
+}
+
+/*
+ * If there is no lun 0 on a target, linux won't find any devices.
+ * For the MSA2xxx boxes, we have to manually detect the enclosure
+ * which is at lun zero, as CCISS_REPORT_PHYSICAL_LUNS doesn't report
+ * it for some reason.  *tmpdevice is the target we're adding,
+ * this_device is a pointer into the current element of currentsd[]
+ * that we're building up in update_scsi_devices(), below.
+ * lunzerobits is a bitmap that tracks which targets already have a
+ * lun 0 assigned.
+ * Returns 1 if an enclosure was added, 0 if not.
+ */
+static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+	struct hpsa_scsi_dev_t *tmpdevice,
+	struct hpsa_scsi_dev_t *this_device, __u8 *lunaddrbytes,
+	int bus, int target, int lun, unsigned long lunzerobits[],
+	int *nmsa2xxx_enclosures)
+{
+	unsigned char scsi3addr[8];
+
+	if (test_bit(target, lunzerobits))
+		return 0; /* There is already a lun 0 on this target. */
+
+	if (!is_logical_dev_addr_mode(lunaddrbytes))
+		return 0; /* It's the logical targets that may lack lun 0. */
+
+	if (!is_msa2xxx(h, tmpdevice))
+		return 0; /* It's only the MSA2xxx that have this problem. */
+
+	if (lun == 0) /* if lun is 0, then obviously we have a lun 0. */
+		return 0;
+
+	if (is_hba_lunid(scsi3addr))
+		return 0; /* Don't add the RAID controller here. */
+
+#define MAX_MSA2XXX_ENCLOSURES 32
+	if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
+		dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
+			"enclosures exceeded.  Check your hardware "
+			"configuration.");
+		return 0;
+	}
+
+	memset(scsi3addr, 0, 8);
+	scsi3addr[3] = target;
+	if (hpsa_update_device_info(h, scsi3addr, this_device))
+		return 0;
+	(*nmsa2xxx_enclosures)++;
+	hpsa_set_bus_target_lun(this_device, bus, target, 0);
+	set_bit(target, lunzerobits);
+	return 1;
+}
+
+/*
+ * Do CISS_REPORT_PHYS and CISS_REPORT_LOG.  Data is returned in physdev,
+ * logdev.  The number of luns in physdev and logdev are returned in
+ * *nphysicals and *nlogicals, respectively.
+ * Returns 0 on success, -1 otherwise.
+ */
+static int hpsa_gather_lun_info(struct ctlr_info *h,
+	int reportlunsize,
+	struct ReportLUNdata *physdev, __u32 *nphysicals,
+	struct ReportLUNdata *logdev, __u32 *nlogicals)
+{
+	if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, 0)) {
+		dev_err(&h->pdev->dev, "report physical LUNs failed.\n");
+		return -1;
+	}
+	memcpy(nphysicals, &physdev->LUNListLength[0], sizeof(*nphysicals));
+	*nphysicals = be32_to_cpu(*nphysicals) / 8;
+#ifdef DEBUG
+	dev_info(&h->pdev->dev, "number of physical luns is %d\n", *nphysicals);
+#endif
+	if (*nphysicals > HPSA_MAX_PHYS_LUN) {
+		dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded."
+			"  %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN,
+			*nphysicals - HPSA_MAX_PHYS_LUN);
+		*nphysicals = HPSA_MAX_PHYS_LUN;
+	}
+	if (hpsa_scsi_do_report_log_luns(h, logdev, reportlunsize)) {
+		dev_err(&h->pdev->dev, "report logical LUNs failed.\n");
+		return -1;
+	}
+	memcpy(nlogicals, &logdev->LUNListLength[0], sizeof(*nlogicals));
+	*nlogicals = be32_to_cpu(*nlogicals) / 8;
+#ifdef DEBUG
+	dev_info(&h->pdev->dev, "number of logical luns is %d\n", *nlogicals);
+#endif
+	/* Reject Logicals in excess of our max capability. */
+	if (*nlogicals > HPSA_MAX_LUN) {
+		dev_warn(&h->pdev->dev,
+			"maximum logical LUNs (%d) exceeded.  "
+			"%d LUNs ignored.\n", HPSA_MAX_LUN,
+			*nlogicals - HPSA_MAX_LUN);
+			*nlogicals = HPSA_MAX_LUN;
+	}
+	if (*nlogicals + *nphysicals > HPSA_MAX_PHYS_LUN) {
+		dev_warn(&h->pdev->dev,
+			"maximum logical + physical LUNs (%d) exceeded. "
+			"%d LUNs ignored.\n", HPSA_MAX_PHYS_LUN,
+			*nphysicals + *nlogicals - HPSA_MAX_PHYS_LUN);
+		*nlogicals = HPSA_MAX_PHYS_LUN - *nphysicals;
+	}
+	return 0;
+}
+
+static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+{
+	/* the idea here is we could get notified
+	 * that some devices have changed, so we do a report
+	 * physical luns and report logical luns cmd, and adjust
+	 * our list of devices accordingly.
+	 *
+	 * The scsi3addr's of devices won't change so long as the
+	 * adapter is not reset.  That means we can rescan and
+	 * tell which devices we already know about, vs. new
+	 * devices, vs.  disappearing devices.
+	 */
+	struct ReportLUNdata *physdev_list = NULL;
+	struct ReportLUNdata *logdev_list = NULL;
+	unsigned char *inq_buff = NULL;
+	__u32 nphysicals = 0;
+	__u32 nlogicals = 0;
+	__u32 ndev_allocated = 0;
+	struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice;
+	int ncurrent = 0;
+	int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8;
+	int i, nmsa2xxx_enclosures, ndevs_to_allocate;
+	int bus, target, lun;
+	DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
+
+	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+		GFP_KERNEL);
+	physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+	logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
+	tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
+
+	if (!currentsd || !physdev_list || !logdev_list ||
+		!inq_buff || !tmpdevice) {
+		dev_err(&h->pdev->dev, "out of memory\n");
+		goto out;
+	}
+	memset(lunzerobits, 0, sizeof(lunzerobits));
+
+	if (hpsa_gather_lun_info(h, reportlunsize, physdev_list, &nphysicals,
+			logdev_list, &nlogicals))
+		goto out;
+
+	/* We might see up to 32 MSA2xxx enclosures, actually 8 of them
+	 * but each of them 4 times through different paths.  The plus 1
+	 * is for the RAID controller.
+	 */
+	ndevs_to_allocate = nphysicals + nlogicals + MAX_MSA2XXX_ENCLOSURES + 1;
+
+	/* Allocate the per device structures */
+	for (i = 0; i < ndevs_to_allocate; i++) {
+		currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL);
+		if (!currentsd[i]) {
+			dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
+				__FILE__, __LINE__);
+			goto out;
+		}
+		ndev_allocated++;
+	}
+
+	/* adjust our table of devices */
+	nmsa2xxx_enclosures = 0;
+	for (i = 0; i < nphysicals + nlogicals + 1; i++) {
+		__u8 *lunaddrbytes;
+
+		/* Figure out where the LUN ID info is coming from */
+		if (i < nphysicals)
+			lunaddrbytes = &physdev_list->LUN[i][0];
+		else
+			if (i < nphysicals + nlogicals)
+				lunaddrbytes =
+					&logdev_list->LUN[i-nphysicals][0];
+			else /* jam in the RAID controller at the end */
+				lunaddrbytes = RAID_CTLR_LUNID;
+
+		/* skip masked physical devices. */
+		if (lunaddrbytes[3] & 0xC0 && i < nphysicals)
+			continue;
+
+		/* Get device type, vendor, model, device id */
+		if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
+			continue; /* skip it if we can't talk to it. */
+		figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
+			tmpdevice);
+		this_device = currentsd[ncurrent];
+
+		/*
+		 * For the msa2xxx boxes, we have to insert a LUN 0 which
+		 * doesn't show up in CCISS_REPORT_PHYSICAL data, but there
+		 * is nonetheless an enclosure device there.  We have to
+		 * present that otherwise linux won't find anything if
+		 * there is no lun 0.
+		 */
+		if (add_msa2xxx_enclosure_device(h, tmpdevice, this_device,
+				lunaddrbytes, bus, target, lun, lunzerobits,
+				&nmsa2xxx_enclosures)) {
+			ncurrent++;
+			this_device = currentsd[ncurrent];
+		}
+
+		*this_device = *tmpdevice;
+		hpsa_set_bus_target_lun(this_device, bus, target, lun);
+
+		switch (this_device->devtype) {
+		case TYPE_ROM: {
+			/* We don't *really* support actual CD-ROM devices,
+			 * just "One Button Disaster Recovery" tape drive
+			 * which temporarily pretends to be a CD-ROM drive.
+			 * So we check that the device is really an OBDR tape
+			 * device by checking for "$DR-10" in bytes 43-48 of
+			 * the inquiry data.
+			 */
+				char obdr_sig[7];
+#define OBDR_TAPE_SIG "$DR-10"
+				strncpy(obdr_sig, &inq_buff[43], 6);
+				obdr_sig[6] = '\0';
+				if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
+					/* Not OBDR device, ignore it. */
+					break;
+			}
+			ncurrent++;
+			break;
+		case TYPE_DISK:
+			if (i < nphysicals)
+				break;
+			ncurrent++;
+			break;
+		case TYPE_TAPE:
+		case TYPE_MEDIUM_CHANGER:
+			ncurrent++;
+			break;
+		case TYPE_RAID:
+			/* Only present the Smartarray HBA as a RAID controller.
+			 * If it's a RAID controller other than the HBA itself
+			 * (an external RAID controller, MSA500 or similar)
+			 * don't present it.
+			 */
+			if (!is_hba_lunid(lunaddrbytes))
+				break;
+			ncurrent++;
+			break;
+		default:
+			break;
+		}
+		if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA)
+			break;
+	}
+	adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
+out:
+	kfree(tmpdevice);
+	for (i = 0; i < ndev_allocated; i++)
+		kfree(currentsd[i]);
+	kfree(currentsd);
+	kfree(inq_buff);
+	kfree(physdev_list);
+	kfree(logdev_list);
+	return;
+}
+
+/* hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci
+ * dma mapping  and fills in the scatter gather entries of the
+ * hpsa command, cp.
+ */
+static int hpsa_scatter_gather(struct pci_dev *pdev,
+		struct CommandList *cp,
+		struct scsi_cmnd *cmd)
+{
+	unsigned int len;
+	struct scatterlist *sg;
+	__u64 addr64;
+	int use_sg, i;
+
+	BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+
+	use_sg = scsi_dma_map(cmd);
+	if (use_sg < 0)
+		return use_sg;
+
+	if (!use_sg)
+		goto sglist_finished;
+
+	scsi_for_each_sg(cmd, sg, use_sg, i) {
+		addr64 = (__u64) sg_dma_address(sg);
+		len  = sg_dma_len(sg);
+		cp->SG[i].Addr.lower =
+			(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
+		cp->SG[i].Addr.upper =
+			(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
+		cp->SG[i].Len = len;
+		cp->SG[i].Ext = 0;  /* we are not chaining */
+	}
+
+sglist_finished:
+
+	cp->Header.SGList = (__u8) use_sg;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
+	return 0;
+}
+
+
+static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+	void (*done)(struct scsi_cmnd *))
+{
+	struct ctlr_info *h;
+	struct hpsa_scsi_dev_t *dev;
+	unsigned char scsi3addr[8];
+	struct CommandList *c;
+	unsigned long flags;
+
+	/* Get the ptr to our adapter structure out of cmd->host. */
+	h = sdev_to_hba(cmd->device);
+	dev = cmd->device->hostdata;
+	if (!dev) {
+		cmd->result = DID_NO_CONNECT << 16;
+		done(cmd);
+		return 0;
+	}
+	memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
+
+	/* Need a lock as this is being allocated from the pool */
+	spin_lock_irqsave(&h->lock, flags);
+	c = cmd_alloc(h);
+	spin_unlock_irqrestore(&h->lock, flags);
+	if (c == NULL) {			/* trouble... */
+		dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n");
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	/* Fill in the command list header */
+
+	cmd->scsi_done = done;    /* save this for use by completion code */
+
+	/* save c in case we have to abort it  */
+	cmd->host_scribble = (unsigned char *) c;
+
+	c->cmd_type = CMD_SCSI;
+	c->scsi_cmd = cmd;
+	c->Header.ReplyQueue = 0;  /* unused in simple mode */
+	memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
+	c->Header.Tag.lower = c->busaddr;  /* Use k. address of cmd as tag */
+
+	/* Fill in the request block... */
+
+	c->Request.Timeout = 0;
+	memset(c->Request.CDB, 0, sizeof(c->Request.CDB));
+	BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB));
+	c->Request.CDBLen = cmd->cmd_len;
+	memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len);
+	c->Request.Type.Type = TYPE_CMD;
+	c->Request.Type.Attribute = ATTR_SIMPLE;
+	switch (cmd->sc_data_direction) {
+	case DMA_TO_DEVICE:
+		c->Request.Type.Direction = XFER_WRITE;
+		break;
+	case DMA_FROM_DEVICE:
+		c->Request.Type.Direction = XFER_READ;
+		break;
+	case DMA_NONE:
+		c->Request.Type.Direction = XFER_NONE;
+		break;
+	case DMA_BIDIRECTIONAL:
+		/* This can happen if a buggy application does a scsi passthru
+		 * and sets both inlen and outlen to non-zero. ( see
+		 * ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )
+		 */
+
+		c->Request.Type.Direction = XFER_RSVD;
+		/* This is technically wrong, and hpsa controllers should
+		 * reject it with CMD_INVALID, which is the most correct
+		 * response, but non-fibre backends appear to let it
+		 * slide by, and give the same results as if this field
+		 * were set correctly.  Either way is acceptable for
+		 * our purposes here.
+		 */
+
+		break;
+
+	default:
+		dev_err(&h->pdev->dev, "unknown data direction: %d\n",
+			cmd->sc_data_direction);
+		BUG();
+		break;
+	}
+
+	if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */
+		cmd_free(h, c);
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+	enqueue_cmd_and_start_io(h, c);
+	/* the cmd'll come back via intr handler in complete_scsi_command()  */
+	return 0;
+}
+
+static void hpsa_unregister_scsi(struct ctlr_info *h)
+{
+	/* we are being forcibly unloaded, and may not refuse. */
+	scsi_remove_host(h->scsi_host);
+	scsi_host_put(h->scsi_host);
+	h->scsi_host = NULL;
+}
+
+static int hpsa_register_scsi(struct ctlr_info *h)
+{
+	int rc;
+
+	hpsa_update_scsi_devices(h, -1);
+	rc = hpsa_scsi_detect(h);
+	if (rc != 0)
+		dev_err(&h->pdev->dev, "hpsa_register_scsi: failed"
+			" hpsa_scsi_detect(), rc is %d\n", rc);
+	return rc;
+}
+
+static int wait_for_device_to_become_ready(struct ctlr_info *h,
+	unsigned char lunaddr[])
+{
+	int rc = 0;
+	int count = 0;
+	int waittime = 1; /* seconds */
+	struct CommandList *c;
+
+	c = cmd_special_alloc(h);
+	if (!c) {
+		dev_warn(&h->pdev->dev, "out of memory in "
+			"wait_for_device_to_become_ready.\n");
+		return IO_ERROR;
+	}
+
+	/* Send test unit ready until device ready, or give up. */
+	while (count < HPSA_TUR_RETRY_LIMIT) {
+
+		/* Wait for a bit.  do this first, because if we send
+		 * the TUR right away, the reset will just abort it.
+		 */
+		msleep(1000 * waittime);
+		count++;
+
+		/* Increase wait time with each try, up to a point. */
+		if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS)
+			waittime = waittime * 2;
+
+		/* Send the Test Unit Ready */
+		fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, lunaddr, TYPE_CMD);
+		hpsa_scsi_do_simple_cmd_core(h, c);
+		/* no unmap needed here because no data xfer. */
+
+		if (c->err_info->CommandStatus == CMD_SUCCESS)
+			break;
+
+		if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+			c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
+			(c->err_info->SenseInfo[2] == NO_SENSE ||
+			c->err_info->SenseInfo[2] == UNIT_ATTENTION))
+			break;
+
+		dev_warn(&h->pdev->dev, "waiting %d secs "
+			"for device to become ready.\n", waittime);
+		rc = 1; /* device not ready. */
+	}
+
+	if (rc)
+		dev_warn(&h->pdev->dev, "giving up on device.\n");
+	else
+		dev_warn(&h->pdev->dev, "device is ready.\n");
+
+	cmd_special_free(h, c);
+	return rc;
+}
+
+/* Need at least one of these error handlers to keep ../scsi/hosts.c from
+ * complaining.  Doing a host- or bus-reset can't do anything good here.
+ */
+static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
+{
+	int rc;
+	struct ctlr_info *h;
+	struct hpsa_scsi_dev_t *dev;
+
+	/* find the controller to which the command to be aborted was sent */
+	h = sdev_to_hba(scsicmd->device);
+	if (h == NULL) /* paranoia */
+		return FAILED;
+	dev_warn(&h->pdev->dev, "resetting drive\n");
+
+	dev = scsicmd->device->hostdata;
+	if (!dev) {
+		dev_err(&h->pdev->dev, "hpsa_eh_device_reset_handler: "
+			"device lookup failed.\n");
+		return FAILED;
+	}
+	/* send a reset to the SCSI LUN which the command was sent to */
+	rc = hpsa_send_reset(h, dev->scsi3addr);
+	if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0)
+		return SUCCESS;
+
+	dev_warn(&h->pdev->dev, "resetting device failed.\n");
+	return FAILED;
+}
+
+/*
+ * For operations that cannot sleep, a command block is allocated at init,
+ * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
+ * which ones are free or in use.  Lock must be held when calling this.
+ * cmd_free() is the complement.
+ */
+static struct CommandList *cmd_alloc(struct ctlr_info *h)
+{
+	struct CommandList *c;
+	int i;
+	union u64bit temp64;
+	dma_addr_t cmd_dma_handle, err_dma_handle;
+
+	do {
+		i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
+		if (i == h->nr_cmds)
+			return NULL;
+	} while (test_and_set_bit
+		 (i & (BITS_PER_LONG - 1),
+		  h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0);
+	c = h->cmd_pool + i;
+	memset(c, 0, sizeof(*c));
+	cmd_dma_handle = h->cmd_pool_dhandle
+	    + i * sizeof(*c);
+	c->err_info = h->errinfo_pool + i;
+	memset(c->err_info, 0, sizeof(*c->err_info));
+	err_dma_handle = h->errinfo_pool_dhandle
+	    + i * sizeof(*c->err_info);
+	h->nr_allocs++;
+
+	c->cmdindex = i;
+
+	INIT_HLIST_NODE(&c->list);
+	c->busaddr = (__u32) cmd_dma_handle;
+	temp64.val = (__u64) err_dma_handle;
+	c->ErrDesc.Addr.lower = temp64.val32.lower;
+	c->ErrDesc.Addr.upper = temp64.val32.upper;
+	c->ErrDesc.Len = sizeof(*c->err_info);
+
+	c->h = h;
+	return c;
+}
+
+/* For operations that can wait for kmalloc to possibly sleep,
+ * this routine can be called. Lock need not be held to call
+ * cmd_special_alloc. cmd_special_free() is the complement.
+ */
+static struct CommandList *cmd_special_alloc(struct ctlr_info *h)
+{
+	struct CommandList *c;
+	union u64bit temp64;
+	dma_addr_t cmd_dma_handle, err_dma_handle;
+
+	c = pci_alloc_consistent(h->pdev, sizeof(*c), &cmd_dma_handle);
+	if (c == NULL)
+		return NULL;
+	memset(c, 0, sizeof(*c));
+
+	c->cmdindex = -1;
+
+	c->err_info = pci_alloc_consistent(h->pdev, sizeof(*c->err_info),
+		    &err_dma_handle);
+
+	if (c->err_info == NULL) {
+		pci_free_consistent(h->pdev,
+			sizeof(*c), c, cmd_dma_handle);
+		return NULL;
+	}
+	memset(c->err_info, 0, sizeof(*c->err_info));
+
+	INIT_HLIST_NODE(&c->list);
+	c->busaddr = (__u32) cmd_dma_handle;
+	temp64.val = (__u64) err_dma_handle;
+	c->ErrDesc.Addr.lower = temp64.val32.lower;
+	c->ErrDesc.Addr.upper = temp64.val32.upper;
+	c->ErrDesc.Len = sizeof(*c->err_info);
+
+	c->h = h;
+	return c;
+}
+
+static void cmd_free(struct ctlr_info *h, struct CommandList *c)
+{
+	int i;
+
+	i = c - h->cmd_pool;
+	clear_bit(i & (BITS_PER_LONG - 1),
+		  h->cmd_pool_bits + (i / BITS_PER_LONG));
+	h->nr_frees++;
+}
+
+static void cmd_special_free(struct ctlr_info *h, struct CommandList *c)
+{
+	union u64bit temp64;
+
+	temp64.val32.lower = c->ErrDesc.Addr.lower;
+	temp64.val32.upper = c->ErrDesc.Addr.upper;
+	pci_free_consistent(h->pdev, sizeof(*c->err_info),
+			    c->err_info, (dma_addr_t) temp64.val);
+	pci_free_consistent(h->pdev, sizeof(*c),
+			    c, (dma_addr_t) c->busaddr);
+}
+
+#ifdef CONFIG_COMPAT
+
+static int do_ioctl(struct scsi_device *dev, int cmd, void *arg)
+{
+	int ret;
+
+	lock_kernel();
+	ret = hpsa_ioctl(dev, cmd, arg);
+	unlock_kernel();
+	return ret;
+}
+
+static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg);
+static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
+	int cmd, void *arg);
+
+static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg)
+{
+	switch (cmd) {
+	case CCISS_GETPCIINFO:
+	case CCISS_GETINTINFO:
+	case CCISS_SETINTINFO:
+	case CCISS_GETNODENAME:
+	case CCISS_SETNODENAME:
+	case CCISS_GETHEARTBEAT:
+	case CCISS_GETBUSTYPES:
+	case CCISS_GETFIRMVER:
+	case CCISS_GETDRIVVER:
+	case CCISS_REVALIDVOLS:
+	case CCISS_DEREGDISK:
+	case CCISS_REGNEWDISK:
+	case CCISS_REGNEWD:
+	case CCISS_RESCANDISK:
+	case CCISS_GETLUNINFO:
+		return do_ioctl(dev, cmd, arg);
+
+	case CCISS_PASSTHRU32:
+		return hpsa_ioctl32_passthru(dev, cmd, arg);
+	case CCISS_BIG_PASSTHRU32:
+		return hpsa_ioctl32_big_passthru(dev, cmd, arg);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg)
+{
+	IOCTL32_Command_struct __user *arg32 =
+	    (IOCTL32_Command_struct __user *) arg;
+	IOCTL_Command_struct arg64;
+	IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64));
+	int err;
+	u32 cp;
+
+	err = 0;
+	err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
+			   sizeof(arg64.LUN_info));
+	err |= copy_from_user(&arg64.Request, &arg32->Request,
+			   sizeof(arg64.Request));
+	err |= copy_from_user(&arg64.error_info, &arg32->error_info,
+			   sizeof(arg64.error_info));
+	err |= get_user(arg64.buf_size, &arg32->buf_size);
+	err |= get_user(cp, &arg32->buf);
+	arg64.buf = compat_ptr(cp);
+	err |= copy_to_user(p, &arg64, sizeof(arg64));
+
+	if (err)
+		return -EFAULT;
+
+	err = do_ioctl(dev, CCISS_PASSTHRU, (void *)p);
+	if (err)
+		return err;
+	err |= copy_in_user(&arg32->error_info, &p->error_info,
+			 sizeof(arg32->error_info));
+	if (err)
+		return -EFAULT;
+	return err;
+}
+
+static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
+	int cmd, void *arg)
+{
+	BIG_IOCTL32_Command_struct __user *arg32 =
+	    (BIG_IOCTL32_Command_struct __user *) arg;
+	BIG_IOCTL_Command_struct arg64;
+	BIG_IOCTL_Command_struct __user *p =
+	    compat_alloc_user_space(sizeof(arg64));
+	int err;
+	u32 cp;
+
+	err = 0;
+	err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
+			   sizeof(arg64.LUN_info));
+	err |= copy_from_user(&arg64.Request, &arg32->Request,
+			   sizeof(arg64.Request));
+	err |= copy_from_user(&arg64.error_info, &arg32->error_info,
+			   sizeof(arg64.error_info));
+	err |= get_user(arg64.buf_size, &arg32->buf_size);
+	err |= get_user(arg64.malloc_size, &arg32->malloc_size);
+	err |= get_user(cp, &arg32->buf);
+	arg64.buf = compat_ptr(cp);
+	err |= copy_to_user(p, &arg64, sizeof(arg64));
+
+	if (err)
+		return -EFAULT;
+
+	err = do_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p);
+	if (err)
+		return err;
+	err |= copy_in_user(&arg32->error_info, &p->error_info,
+			 sizeof(arg32->error_info));
+	if (err)
+		return -EFAULT;
+	return err;
+}
+#endif
+
+static int hpsa_getpciinfo_ioctl(struct ctlr_info *h, void __user *argp)
+{
+	struct hpsa_pci_info pciinfo;
+
+	if (!argp)
+		return -EINVAL;
+	pciinfo.domain = pci_domain_nr(h->pdev->bus);
+	pciinfo.bus = h->pdev->bus->number;
+	pciinfo.dev_fn = h->pdev->devfn;
+	pciinfo.board_id = h->board_id;
+	if (copy_to_user(argp, &pciinfo, sizeof(pciinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp)
+{
+	DriverVer_type DriverVer;
+	unsigned char vmaj, vmin, vsubmin;
+	int rc;
+
+	rc = sscanf(HPSA_DRIVER_VERSION, "%hhu.%hhu.%hhu",
+		&vmaj, &vmin, &vsubmin);
+	if (rc != 3) {
+		dev_info(&h->pdev->dev, "driver version string '%s' "
+			"unrecognized.", HPSA_DRIVER_VERSION);
+		vmaj = 0;
+		vmin = 0;
+		vsubmin = 0;
+	}
+	DriverVer = (vmaj << 16) | (vmin << 8) | vsubmin;
+	if (!argp)
+		return -EINVAL;
+	if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type)))
+		return -EFAULT;
+	return 0;
+}
+
+static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+{
+	IOCTL_Command_struct iocommand;
+	struct CommandList *c;
+	char *buff = NULL;
+	union u64bit temp64;
+
+	if (!argp)
+		return -EINVAL;
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	if (copy_from_user(&iocommand, argp, sizeof(iocommand)))
+		return -EFAULT;
+	if ((iocommand.buf_size < 1) &&
+	    (iocommand.Request.Type.Direction != XFER_NONE)) {
+		return -EINVAL;
+	}
+	if (iocommand.buf_size > 0) {
+		buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+		if (buff == NULL)
+			return -EFAULT;
+	}
+	if (iocommand.Request.Type.Direction == XFER_WRITE) {
+		/* Copy the data into the buffer we created */
+		if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
+			kfree(buff);
+			return -EFAULT;
+		}
+	} else
+		memset(buff, 0, iocommand.buf_size);
+	c = cmd_special_alloc(h);
+	if (c == NULL) {
+		kfree(buff);
+		return -ENOMEM;
+	}
+	/* Fill in the command type */
+	c->cmd_type = CMD_IOCTL_PEND;
+	/* Fill in Command Header */
+	c->Header.ReplyQueue = 0; /* unused in simple mode */
+	if (iocommand.buf_size > 0) {	/* buffer to fill */
+		c->Header.SGList = 1;
+		c->Header.SGTotal = 1;
+	} else	{ /* no buffers to fill */
+		c->Header.SGList = 0;
+		c->Header.SGTotal = 0;
+	}
+	memcpy(&c->Header.LUN, &iocommand.LUN_info, sizeof(c->Header.LUN));
+	/* use the kernel address the cmd block for tag */
+	c->Header.Tag.lower = c->busaddr;
+
+	/* Fill in Request block */
+	memcpy(&c->Request, &iocommand.Request,
+		sizeof(c->Request));
+
+	/* Fill in the scatter gather information */
+	if (iocommand.buf_size > 0) {
+		temp64.val = pci_map_single(h->pdev, buff,
+			iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
+		c->SG[0].Addr.lower = temp64.val32.lower;
+		c->SG[0].Addr.upper = temp64.val32.upper;
+		c->SG[0].Len = iocommand.buf_size;
+		c->SG[0].Ext = 0; /* we are not chaining*/
+	}
+	hpsa_scsi_do_simple_cmd_core(h, c);
+	hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
+	check_ioctl_unit_attention(h, c);
+
+	/* Copy the error information out */
+	memcpy(&iocommand.error_info, c->err_info,
+		sizeof(iocommand.error_info));
+	if (copy_to_user(argp, &iocommand, sizeof(iocommand))) {
+		kfree(buff);
+		cmd_special_free(h, c);
+		return -EFAULT;
+	}
+
+	if (iocommand.Request.Type.Direction == XFER_READ) {
+		/* Copy the data out of the buffer we created */
+		if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
+			kfree(buff);
+			cmd_special_free(h, c);
+			return -EFAULT;
+		}
+	}
+	kfree(buff);
+	cmd_special_free(h, c);
+	return 0;
+}
+
+static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+{
+	BIG_IOCTL_Command_struct *ioc;
+	struct CommandList *c;
+	unsigned char **buff = NULL;
+	int *buff_size = NULL;
+	union u64bit temp64;
+	BYTE sg_used = 0;
+	int status = 0;
+	int i;
+	__u32 left;
+	__u32 sz;
+	BYTE __user *data_ptr;
+
+	if (!argp)
+		return -EINVAL;
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	ioc = (BIG_IOCTL_Command_struct *)
+	    kmalloc(sizeof(*ioc), GFP_KERNEL);
+	if (!ioc) {
+		status = -ENOMEM;
+		goto cleanup1;
+	}
+	if (copy_from_user(ioc, argp, sizeof(*ioc))) {
+		status = -EFAULT;
+		goto cleanup1;
+	}
+	if ((ioc->buf_size < 1) &&
+	    (ioc->Request.Type.Direction != XFER_NONE)) {
+		status = -EINVAL;
+		goto cleanup1;
+	}
+	/* Check kmalloc limits  using all SGs */
+	if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
+		status = -EINVAL;
+		goto cleanup1;
+	}
+	if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
+		status = -EINVAL;
+		goto cleanup1;
+	}
+	buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
+	if (!buff) {
+		status = -ENOMEM;
+		goto cleanup1;
+	}
+	buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
+	if (!buff_size) {
+		status = -ENOMEM;
+		goto cleanup1;
+	}
+	left = ioc->buf_size;
+	data_ptr = ioc->buf;
+	while (left) {
+		sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
+		buff_size[sg_used] = sz;
+		buff[sg_used] = kmalloc(sz, GFP_KERNEL);
+		if (buff[sg_used] == NULL) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		if (ioc->Request.Type.Direction == XFER_WRITE) {
+			if (copy_from_user(buff[sg_used], data_ptr, sz)) {
+				status = -ENOMEM;
+				goto cleanup1;
+			}
+		} else
+			memset(buff[sg_used], 0, sz);
+		left -= sz;
+		data_ptr += sz;
+		sg_used++;
+	}
+	c = cmd_special_alloc(h);
+	if (c == NULL) {
+		status = -ENOMEM;
+		goto cleanup1;
+	}
+	c->cmd_type = CMD_IOCTL_PEND;
+	c->Header.ReplyQueue = 0;
+
+	if (ioc->buf_size > 0) {
+		c->Header.SGList = sg_used;
+		c->Header.SGTotal = sg_used;
+	} else {
+		c->Header.SGList = 0;
+		c->Header.SGTotal = 0;
+	}
+	memcpy(&c->Header.LUN, &ioc->LUN_info, sizeof(c->Header.LUN));
+	c->Header.Tag.lower = c->busaddr;
+	memcpy(&c->Request, &ioc->Request, sizeof(c->Request));
+	if (ioc->buf_size > 0) {
+		int i;
+		for (i = 0; i < sg_used; i++) {
+			temp64.val = pci_map_single(h->pdev, buff[i],
+				    buff_size[i], PCI_DMA_BIDIRECTIONAL);
+			c->SG[i].Addr.lower = temp64.val32.lower;
+			c->SG[i].Addr.upper = temp64.val32.upper;
+			c->SG[i].Len = buff_size[i];
+			/* we are not chaining */
+			c->SG[i].Ext = 0;
+		}
+	}
+	hpsa_scsi_do_simple_cmd_core(h, c);
+	hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
+	check_ioctl_unit_attention(h, c);
+	/* Copy the error information out */
+	memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
+	if (copy_to_user(argp, ioc, sizeof(*ioc))) {
+		cmd_special_free(h, c);
+		status = -EFAULT;
+		goto cleanup1;
+	}
+	if (ioc->Request.Type.Direction == XFER_READ) {
+		/* Copy the data out of the buffer we created */
+		BYTE __user *ptr = ioc->buf;
+		for (i = 0; i < sg_used; i++) {
+			if (copy_to_user(ptr, buff[i], buff_size[i])) {
+				cmd_special_free(h, c);
+				status = -EFAULT;
+				goto cleanup1;
+			}
+			ptr += buff_size[i];
+		}
+	}
+	cmd_special_free(h, c);
+	status = 0;
+cleanup1:
+	if (buff) {
+		for (i = 0; i < sg_used; i++)
+			kfree(buff[i]);
+		kfree(buff);
+	}
+	kfree(buff_size);
+	kfree(ioc);
+	return status;
+}
+
+static void check_ioctl_unit_attention(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+			c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
+		(void) check_for_unit_attention(h, c);
+}
+/*
+ * ioctl
+ */
+static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg)
+{
+	struct ctlr_info *h;
+	void __user *argp = (void __user *)arg;
+
+	h = sdev_to_hba(dev);
+
+	switch (cmd) {
+	case CCISS_DEREGDISK:
+	case CCISS_REGNEWDISK:
+	case CCISS_REGNEWD:
+		hpsa_update_scsi_devices(h, dev->host->host_no);
+		return 0;
+	case CCISS_GETPCIINFO:
+		return hpsa_getpciinfo_ioctl(h, argp);
+	case CCISS_GETDRIVVER:
+		return hpsa_getdrivver_ioctl(h, argp);
+	case CCISS_PASSTHRU:
+		return hpsa_passthru_ioctl(h, argp);
+	case CCISS_BIG_PASSTHRU:
+		return hpsa_big_passthru_ioctl(h, argp);
+	default:
+		return -ENOTTY;
+	}
+}
+
+static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h,
+	void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr,
+	int cmd_type)
+{
+	int pci_dir = XFER_NONE;
+
+	c->cmd_type = CMD_IOCTL_PEND;
+	c->Header.ReplyQueue = 0;
+	if (buff != NULL && size > 0) {
+		c->Header.SGList = 1;
+		c->Header.SGTotal = 1;
+	} else {
+		c->Header.SGList = 0;
+		c->Header.SGTotal = 0;
+	}
+	c->Header.Tag.lower = c->busaddr;
+	memcpy(c->Header.LUN.LunAddrBytes, scsi3addr, 8);
+
+	c->Request.Type.Type = cmd_type;
+	if (cmd_type == TYPE_CMD) {
+		switch (cmd) {
+		case HPSA_INQUIRY:
+			/* are we trying to read a vital product page */
+			if (page_code != 0) {
+				c->Request.CDB[1] = 0x01;
+				c->Request.CDB[2] = page_code;
+			}
+			c->Request.CDBLen = 6;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = HPSA_INQUIRY;
+			c->Request.CDB[4] = size & 0xFF;
+			break;
+		case HPSA_REPORT_LOG:
+		case HPSA_REPORT_PHYS:
+			/* Talking to controller so It's a physical command
+			   mode = 00 target = 0.  Nothing to write.
+			 */
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */
+			c->Request.CDB[7] = (size >> 16) & 0xFF;
+			c->Request.CDB[8] = (size >> 8) & 0xFF;
+			c->Request.CDB[9] = size & 0xFF;
+			break;
+
+		case HPSA_READ_CAPACITY:
+			c->Request.CDBLen = 10;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			break;
+		case HPSA_CACHE_FLUSH:
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = BMIC_WRITE;
+			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
+			break;
+		case TEST_UNIT_READY:
+			c->Request.CDBLen = 6;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_NONE;
+			c->Request.Timeout = 0;
+			break;
+		default:
+			dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd);
+			BUG();
+			return;
+		}
+	} else if (cmd_type == TYPE_MSG) {
+		switch (cmd) {
+
+		case  HPSA_DEVICE_RESET_MSG:
+			c->Request.CDBLen = 16;
+			c->Request.Type.Type =  1; /* It is a MSG not a CMD */
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_NONE;
+			c->Request.Timeout = 0; /* Don't time out */
+			c->Request.CDB[0] =  0x01; /* RESET_MSG is 0x01 */
+			c->Request.CDB[1] = 0x03;  /* Reset target above */
+			/* If bytes 4-7 are zero, it means reset the */
+			/* LunID device */
+			c->Request.CDB[4] = 0x00;
+			c->Request.CDB[5] = 0x00;
+			c->Request.CDB[6] = 0x00;
+			c->Request.CDB[7] = 0x00;
+		break;
+
+		default:
+			dev_warn(&h->pdev->dev, "unknown message type %d\n",
+				cmd);
+			BUG();
+		}
+	} else {
+		dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type);
+		BUG();
+	}
+
+	switch (c->Request.Type.Direction) {
+	case XFER_READ:
+		pci_dir = PCI_DMA_FROMDEVICE;
+		break;
+	case XFER_WRITE:
+		pci_dir = PCI_DMA_TODEVICE;
+		break;
+	case XFER_NONE:
+		pci_dir = PCI_DMA_NONE;
+		break;
+	default:
+		pci_dir = PCI_DMA_BIDIRECTIONAL;
+	}
+
+	hpsa_map_one(h->pdev, c, buff, size, pci_dir);
+
+	return;
+}
+
+/*
+ * Map (physical) PCI mem into (virtual) kernel space
+ */
+static void __iomem *remap_pci_mem(ulong base, ulong size)
+{
+	ulong page_base = ((ulong) base) & PAGE_MASK;
+	ulong page_offs = ((ulong) base) - page_base;
+	void __iomem *page_remapped = ioremap(page_base, page_offs + size);
+
+	return page_remapped ? (page_remapped + page_offs) : NULL;
+}
+
+/* Takes cmds off the submission queue and sends them to the hardware,
+ * then puts them on the queue of cmds waiting for completion.
+ */
+static void start_io(struct ctlr_info *h)
+{
+	struct CommandList *c;
+
+	while (!hlist_empty(&h->reqQ)) {
+		c = hlist_entry(h->reqQ.first, struct CommandList, list);
+		/* can't do anything if fifo is full */
+		if ((h->access.fifo_full(h))) {
+			dev_warn(&h->pdev->dev, "fifo full\n");
+			break;
+		}
+
+		/* Get the first entry from the Request Q */
+		removeQ(c);
+		h->Qdepth--;
+
+		/* Tell the controller execute command */
+		h->access.submit_command(h, c);
+
+		/* Put job onto the completed Q */
+		addQ(&h->cmpQ, c);
+	}
+}
+
+static inline unsigned long get_next_completion(struct ctlr_info *h)
+{
+	return h->access.command_completed(h);
+}
+
+static inline int interrupt_pending(struct ctlr_info *h)
+{
+	return h->access.intr_pending(h);
+}
+
+static inline long interrupt_not_for_us(struct ctlr_info *h)
+{
+	return ((h->access.intr_pending(h) == 0) ||
+		 (h->interrupts_enabled == 0));
+}
+
+static inline int bad_tag(struct ctlr_info *h, __u32 tag_index,
+	__u32 raw_tag)
+{
+	if (unlikely(tag_index >= h->nr_cmds)) {
+		dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag);
+		return 1;
+	}
+	return 0;
+}
+
+static inline void finish_cmd(struct CommandList *c, __u32 raw_tag)
+{
+	removeQ(c);
+	if (likely(c->cmd_type == CMD_SCSI))
+		complete_scsi_command(c, 0, raw_tag);
+	else if (c->cmd_type == CMD_IOCTL_PEND)
+		complete(c->waiting);
+}
+
+static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
+{
+	struct ctlr_info *h = dev_id;
+	struct CommandList *c;
+	unsigned long flags;
+	__u32 raw_tag, tag, tag_index;
+	struct hlist_node *tmp;
+
+	if (interrupt_not_for_us(h))
+		return IRQ_NONE;
+	spin_lock_irqsave(&h->lock, flags);
+	while (interrupt_pending(h)) {
+		while ((raw_tag = get_next_completion(h)) != FIFO_EMPTY) {
+			if (likely(HPSA_TAG_CONTAINS_INDEX(raw_tag))) {
+				tag_index = HPSA_TAG_TO_INDEX(raw_tag);
+				if (bad_tag(h, tag_index, raw_tag))
+					return IRQ_HANDLED;
+				c = h->cmd_pool + tag_index;
+				finish_cmd(c, raw_tag);
+				continue;
+			}
+			tag = HPSA_TAG_DISCARD_ERROR_BITS(raw_tag);
+			c = NULL;
+			hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
+				if (c->busaddr == tag) {
+					finish_cmd(c, raw_tag);
+					break;
+				}
+			}
+		}
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+	return IRQ_HANDLED;
+}
+
+/* Send a message CDB to the firmware. */
+static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+						unsigned char type)
+{
+	struct Command {
+		struct CommandListHeader CommandHeader;
+		struct RequestBlock Request;
+		struct ErrDescriptor ErrorDescriptor;
+	};
+	struct Command *cmd;
+	static const size_t cmd_sz = sizeof(*cmd) +
+					sizeof(cmd->ErrorDescriptor);
+	dma_addr_t paddr64;
+	uint32_t paddr32, tag;
+	void __iomem *vaddr;
+	int i, err;
+
+	vaddr = pci_ioremap_bar(pdev, 0);
+	if (vaddr == NULL)
+		return -ENOMEM;
+
+	/* The Inbound Post Queue only accepts 32-bit physical addresses for the
+	 * CCISS commands, so they must be allocated from the lower 4GiB of
+	 * memory.
+	 */
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err) {
+		iounmap(vaddr);
+		return -ENOMEM;
+	}
+
+	cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64);
+	if (cmd == NULL) {
+		iounmap(vaddr);
+		return -ENOMEM;
+	}
+
+	/* This must fit, because of the 32-bit consistent DMA mask.  Also,
+	 * although there's no guarantee, we assume that the address is at
+	 * least 4-byte aligned (most likely, it's page-aligned).
+	 */
+	paddr32 = paddr64;
+
+	cmd->CommandHeader.ReplyQueue = 0;
+	cmd->CommandHeader.SGList = 0;
+	cmd->CommandHeader.SGTotal = 0;
+	cmd->CommandHeader.Tag.lower = paddr32;
+	cmd->CommandHeader.Tag.upper = 0;
+	memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8);
+
+	cmd->Request.CDBLen = 16;
+	cmd->Request.Type.Type = TYPE_MSG;
+	cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE;
+	cmd->Request.Type.Direction = XFER_NONE;
+	cmd->Request.Timeout = 0; /* Don't time out */
+	cmd->Request.CDB[0] = opcode;
+	cmd->Request.CDB[1] = type;
+	memset(&cmd->Request.CDB[2], 0, 14); /* rest of the CDB is reserved */
+	cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(*cmd);
+	cmd->ErrorDescriptor.Addr.upper = 0;
+	cmd->ErrorDescriptor.Len = sizeof(struct ErrorInfo);
+
+	writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET);
+
+	for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) {
+		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
+		if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32)
+			break;
+		msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
+	}
+
+	iounmap(vaddr);
+
+	/* we leak the DMA buffer here ... no choice since the controller could
+	 *  still complete the command.
+	 */
+	if (i == HPSA_MSG_SEND_RETRY_LIMIT) {
+		dev_err(&pdev->dev, "controller message %02x:%02x timed out\n",
+			opcode, type);
+		return -ETIMEDOUT;
+	}
+
+	pci_free_consistent(pdev, cmd_sz, cmd, paddr64);
+
+	if (tag & HPSA_ERROR_BIT) {
+		dev_err(&pdev->dev, "controller message %02x:%02x failed\n",
+			opcode, type);
+		return -EIO;
+	}
+
+	dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n",
+		opcode, type);
+	return 0;
+}
+
+#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0)
+#define hpsa_noop(p) hpsa_message(p, 3, 0)
+
+static __devinit int hpsa_reset_msi(struct pci_dev *pdev)
+{
+/* the #defines are stolen from drivers/pci/msi.h. */
+#define msi_control_reg(base)		(base + PCI_MSI_FLAGS)
+#define PCI_MSIX_FLAGS_ENABLE		(1 << 15)
+
+	int pos;
+	u16 control = 0;
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+	if (pos) {
+		pci_read_config_word(pdev, msi_control_reg(pos), &control);
+		if (control & PCI_MSI_FLAGS_ENABLE) {
+			dev_info(&pdev->dev, "resetting MSI\n");
+			pci_write_config_word(pdev, msi_control_reg(pos),
+					control & ~PCI_MSI_FLAGS_ENABLE);
+		}
+	}
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+	if (pos) {
+		pci_read_config_word(pdev, msi_control_reg(pos), &control);
+		if (control & PCI_MSIX_FLAGS_ENABLE) {
+			dev_info(&pdev->dev, "resetting MSI-X\n");
+			pci_write_config_word(pdev, msi_control_reg(pos),
+					control & ~PCI_MSIX_FLAGS_ENABLE);
+		}
+	}
+
+	return 0;
+}
+
+/* This does a hard reset of the controller using PCI power management
+ * states.
+ */
+static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev)
+{
+	u16 pmcsr, saved_config_space[32];
+	int i, pos;
+
+	dev_info(&pdev->dev, "using PCI PM to reset controller\n");
+
+	/* This is very nearly the same thing as
+	 *
+	 * pci_save_state(pci_dev);
+	 * pci_set_power_state(pci_dev, PCI_D3hot);
+	 * pci_set_power_state(pci_dev, PCI_D0);
+	 * pci_restore_state(pci_dev);
+	 *
+	 * but we can't use these nice canned kernel routines on
+	 * kexec, because they also check the MSI/MSI-X state in PCI
+	 * configuration space and do the wrong thing when it is
+	 * set/cleared.  Also, the pci_save/restore_state functions
+	 * violate the ordering requirements for restoring the
+	 * configuration space from the CCISS document (see the
+	 * comment below).  So we roll our own ....
+	 */
+
+	for (i = 0; i < 32; i++)
+		pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pos == 0) {
+		dev_err(&pdev->dev,
+			"hpsa_reset_controller: PCI PM not supported\n");
+		return -ENODEV;
+	}
+
+	/* Quoting from the Open CISS Specification: "The Power
+	 * Management Control/Status Register (CSR) controls the power
+	 * state of the device.  The normal operating state is D0,
+	 * CSR=00h.  The software off state is D3, CSR=03h.  To reset
+	 * the controller, place the interface device in D3 then to
+	 * D0, this causes a secondary PCI reset which will reset the
+	 * controller."
+	 */
+
+	/* enter the D3hot power management state */
+	pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
+	pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+	pmcsr |= PCI_D3hot;
+	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+	msleep(500);
+
+	/* enter the D0 power management state */
+	pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+	pmcsr |= PCI_D0;
+	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+	msleep(500);
+
+	/* Restore the PCI configuration space.  The Open CISS
+	 * Specification says, "Restore the PCI Configuration
+	 * Registers, offsets 00h through 60h. It is important to
+	 * restore the command register, 16-bits at offset 04h,
+	 * last. Do not restore the configuration status register,
+	 * 16-bits at offset 06h."  Note that the offset is 2*i.
+	 */
+	for (i = 0; i < 32; i++) {
+		if (i == 2 || i == 3)
+			continue;
+		pci_write_config_word(pdev, 2*i, saved_config_space[i]);
+	}
+	wmb();
+	pci_write_config_word(pdev, 4, saved_config_space[2]);
+
+	return 0;
+}
+
+/*
+ *  We cannot read the structure directly, for portability we must use
+ *   the io functions.
+ *   This is for debug only.
+ */
+#ifdef HPSA_DEBUG
+static void print_cfg_table(struct device *dev, struct CfgTable *tb)
+{
+	int i;
+	char temp_name[17];
+
+	dev_info(dev, "Controller Configuration information\n");
+	dev_info(dev, "------------------------------------\n");
+	for (i = 0; i < 4; i++)
+		temp_name[i] = readb(&(tb->Signature[i]));
+	temp_name[4] = '\0';
+	dev_info(dev, "   Signature = %s\n", temp_name);
+	dev_info(dev, "   Spec Number = %d\n", readl(&(tb->SpecValence)));
+	dev_info(dev, "   Transport methods supported = 0x%x\n",
+	       readl(&(tb->TransportSupport)));
+	dev_info(dev, "   Transport methods active = 0x%x\n",
+	       readl(&(tb->TransportActive)));
+	dev_info(dev, "   Requested transport Method = 0x%x\n",
+	       readl(&(tb->HostWrite.TransportRequest)));
+	dev_info(dev, "   Coalesce Interrupt Delay = 0x%x\n",
+	       readl(&(tb->HostWrite.CoalIntDelay)));
+	dev_info(dev, "   Coalesce Interrupt Count = 0x%x\n",
+	       readl(&(tb->HostWrite.CoalIntCount)));
+	dev_info(dev, "   Max outstanding commands = 0x%d\n",
+	       readl(&(tb->CmdsOutMax)));
+	dev_info(dev, "   Bus Types = 0x%x\n", readl(&(tb->BusTypes)));
+	for (i = 0; i < 16; i++)
+		temp_name[i] = readb(&(tb->ServerName[i]));
+	temp_name[16] = '\0';
+	dev_info(dev, "   Server Name = %s\n", temp_name);
+	dev_info(dev, "   Heartbeat Counter = 0x%x\n\n\n",
+		readl(&(tb->HeartBeat)));
+}
+#endif				/* HPSA_DEBUG */
+
+static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr)
+{
+	int i, offset, mem_type, bar_type;
+
+	if (pci_bar_addr == PCI_BASE_ADDRESS_0)	/* looking for BAR zero? */
+		return 0;
+	offset = 0;
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		bar_type = pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE;
+		if (bar_type == PCI_BASE_ADDRESS_SPACE_IO)
+			offset += 4;
+		else {
+			mem_type = pci_resource_flags(pdev, i) &
+			    PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+			switch (mem_type) {
+			case PCI_BASE_ADDRESS_MEM_TYPE_32:
+			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+				offset += 4;	/* 32 bit */
+				break;
+			case PCI_BASE_ADDRESS_MEM_TYPE_64:
+				offset += 8;
+				break;
+			default:	/* reserved in PCI 2.2 */
+				dev_warn(&pdev->dev,
+				       "base address is invalid\n");
+				return -1;
+				break;
+			}
+		}
+		if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0)
+			return i + 1;
+	}
+	return -1;
+}
+
+/* If MSI/MSI-X is supported by the kernel we will try to enable it on
+ * controllers that are capable. If not, we use IO-APIC mode.
+ */
+
+static void __devinit hpsa_interrupt_mode(struct ctlr_info *h,
+					   struct pci_dev *pdev, __u32 board_id)
+{
+#ifdef CONFIG_PCI_MSI
+	int err;
+	struct msix_entry hpsa_msix_entries[4] = { {0, 0}, {0, 1},
+	{0, 2}, {0, 3}
+	};
+
+	/* Some boards advertise MSI but don't really support it */
+	if ((board_id == 0x40700E11) ||
+	    (board_id == 0x40800E11) ||
+	    (board_id == 0x40820E11) || (board_id == 0x40830E11))
+		goto default_int_mode;
+	if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+		dev_info(&pdev->dev, "MSIX\n");
+		err = pci_enable_msix(pdev, hpsa_msix_entries, 4);
+		if (!err) {
+			h->intr[0] = hpsa_msix_entries[0].vector;
+			h->intr[1] = hpsa_msix_entries[1].vector;
+			h->intr[2] = hpsa_msix_entries[2].vector;
+			h->intr[3] = hpsa_msix_entries[3].vector;
+			h->msix_vector = 1;
+			return;
+		}
+		if (err > 0) {
+			dev_warn(&pdev->dev, "only %d MSI-X vectors "
+			       "available\n", err);
+			goto default_int_mode;
+		} else {
+			dev_warn(&pdev->dev, "MSI-X init failed %d\n",
+			       err);
+			goto default_int_mode;
+		}
+	}
+	if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
+		dev_info(&pdev->dev, "MSI\n");
+		if (!pci_enable_msi(pdev))
+			h->msi_vector = 1;
+		else
+			dev_warn(&pdev->dev, "MSI init failed\n");
+	}
+default_int_mode:
+#endif				/* CONFIG_PCI_MSI */
+	/* if we get here we're going to use the default interrupt mode */
+	h->intr[SIMPLE_MODE_INT] = pdev->irq;
+	return;
+}
+
+static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
+{
+	ushort subsystem_vendor_id, subsystem_device_id, command;
+	__u32 board_id, scratchpad = 0;
+	__u64 cfg_offset;
+	__u32 cfg_base_addr;
+	__u64 cfg_base_addr_index;
+	int i, prod_index, err;
+
+	subsystem_vendor_id = pdev->subsystem_vendor;
+	subsystem_device_id = pdev->subsystem_device;
+	board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
+		    subsystem_vendor_id);
+
+	for (i = 0; i < ARRAY_SIZE(products); i++)
+		if (board_id == products[i].board_id)
+			break;
+
+	prod_index = i;
+
+	if (prod_index == ARRAY_SIZE(products)) {
+		prod_index--;
+		if (subsystem_vendor_id != PCI_VENDOR_ID_HP ||
+				!hpsa_allow_any) {
+			dev_warn(&pdev->dev, "unrecognized board ID:"
+				" 0x%08lx, ignoring.\n",
+				(unsigned long) board_id);
+			return -ENODEV;
+		}
+	}
+	/* check to see if controller has been disabled
+	 * BEFORE trying to enable it
+	 */
+	(void)pci_read_config_word(pdev, PCI_COMMAND, &command);
+	if (!(command & 0x02)) {
+		dev_warn(&pdev->dev, "controller appears to be disabled\n");
+		return -ENODEV;
+	}
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_warn(&pdev->dev, "unable to enable PCI device\n");
+		return err;
+	}
+
+	err = pci_request_regions(pdev, "hpsa");
+	if (err) {
+		dev_err(&pdev->dev, "cannot obtain PCI resources, aborting\n");
+		return err;
+	}
+
+	/* If the kernel supports MSI/MSI-X we will try to enable that,
+	 * else we use the IO-APIC interrupt assigned to us by system ROM.
+	 */
+	hpsa_interrupt_mode(h, pdev, board_id);
+
+	/* find the memory BAR */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		if (pci_resource_flags(pdev, i) & IORESOURCE_MEM)
+			break;
+	}
+	if (i == DEVICE_COUNT_RESOURCE) {
+		dev_warn(&pdev->dev, "no memory BAR found\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+
+	h->paddr = pci_resource_start(pdev, i); /* addressing mode bits
+						 * already removed
+						 */
+
+	h->vaddr = remap_pci_mem(h->paddr, 0x250);
+
+	/* Wait for the board to become ready.  */
+	for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) {
+		scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+		if (scratchpad == HPSA_FIRMWARE_READY)
+			break;
+		msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS);
+	}
+	if (scratchpad != HPSA_FIRMWARE_READY) {
+		dev_warn(&pdev->dev, "board not ready, timed out.\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+
+	/* get the address index number */
+	cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET);
+	cfg_base_addr &= (__u32) 0x0000ffff;
+	cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr);
+	if (cfg_base_addr_index == -1) {
+		dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+
+	cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET);
+	h->cfgtable = remap_pci_mem(pci_resource_start(pdev,
+			       cfg_base_addr_index) + cfg_offset,
+				sizeof(h->cfgtable));
+	h->board_id = board_id;
+
+	/* Query controller for max supported commands: */
+	h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
+
+	h->product_name = products[prod_index].product_name;
+	h->access = *(products[prod_index].access);
+	/* Allow room for some ioctls */
+	h->nr_cmds = h->max_commands - 4;
+
+	if ((readb(&h->cfgtable->Signature[0]) != 'C') ||
+	    (readb(&h->cfgtable->Signature[1]) != 'I') ||
+	    (readb(&h->cfgtable->Signature[2]) != 'S') ||
+	    (readb(&h->cfgtable->Signature[3]) != 'S')) {
+		dev_warn(&pdev->dev, "not a valid CISS config table\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+#ifdef CONFIG_X86
+	{
+		/* Need to enable prefetch in the SCSI core for 6400 in x86 */
+		__u32 prefetch;
+		prefetch = readl(&(h->cfgtable->SCSI_Prefetch));
+		prefetch |= 0x100;
+		writel(prefetch, &(h->cfgtable->SCSI_Prefetch));
+	}
+#endif
+
+	/* Disabling DMA prefetch for the P600
+	 * An ASIC bug may result in a prefetch beyond
+	 * physical memory.
+	 */
+	if (board_id == 0x3225103C) {
+		__u32 dma_prefetch;
+		dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG);
+		dma_prefetch |= 0x8000;
+		writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
+	}
+
+	h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
+	/* Update the field, and then ring the doorbell */
+	writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
+	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+
+	/* under certain very rare conditions, this can take awhile.
+	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
+	 * as we enter this code.)
+	 */
+	for (i = 0; i < MAX_CONFIG_WAIT; i++) {
+		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+			break;
+		/* delay and try again */
+		msleep(10);
+	}
+
+#ifdef HPSA_DEBUG
+	print_cfg_table(&pdev->dev, h->cfgtable);
+#endif				/* HPSA_DEBUG */
+
+	if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) {
+		dev_warn(&pdev->dev, "unable to get board into simple mode\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+	return 0;
+
+err_out_free_res:
+	/*
+	 * Deliberately omit pci_disable_device(): it does something nasty to
+	 * Smart Array controllers that pci_enable_device does not undo
+	 */
+	pci_release_regions(pdev);
+	return err;
+}
+
+static int __devinit hpsa_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
+{
+	int i;
+	int dac;
+	struct ctlr_info *h;
+
+	if (number_of_controllers == 0)
+		printk(KERN_INFO DRIVER_NAME "\n");
+	if (reset_devices) {
+		/* Reset the controller with a PCI power-cycle */
+		if (hpsa_hard_reset_controller(pdev) || hpsa_reset_msi(pdev))
+			return -ENODEV;
+
+		/* Some devices (notably the HP Smart Array 5i Controller)
+		   need a little pause here */
+		msleep(HPSA_POST_RESET_PAUSE_MSECS);
+
+		/* Now try to get the controller to respond to a no-op */
+		for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {
+			if (hpsa_noop(pdev) == 0)
+				break;
+			else
+				dev_warn(&pdev->dev, "no-op failed%s\n",
+						(i < 11 ? "; re-trying" : ""));
+		}
+	}
+
+	BUILD_BUG_ON(sizeof(struct CommandList) % 8);
+	h = kzalloc(sizeof(*h), GFP_KERNEL);
+	if (!h)
+		return -1;
+
+	h->busy_initializing = 1;
+	INIT_HLIST_HEAD(&h->cmpQ);
+	INIT_HLIST_HEAD(&h->reqQ);
+	mutex_init(&h->busy_shutting_down);
+	init_completion(&h->scan_wait);
+	if (hpsa_pci_init(h, pdev) != 0)
+		goto clean1;
+
+	sprintf(h->devname, "hpsa%d", number_of_controllers);
+	h->ctlr = number_of_controllers;
+	number_of_controllers++;
+	h->pdev = pdev;
+
+	/* configure PCI DMA stuff */
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+		dac = 1;
+	else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
+		dac = 0;
+	else {
+		dev_err(&pdev->dev, "no suitable DMA available\n");
+		goto clean1;
+	}
+
+	/* make sure the board interrupts are off */
+	h->access.set_intr_mask(h, HPSA_INTR_OFF);
+	if (request_irq(h->intr[SIMPLE_MODE_INT], do_hpsa_intr,
+			IRQF_DISABLED | IRQF_SHARED, h->devname, h)) {
+		dev_err(&pdev->dev, "unable to get irq %d for %s\n",
+		       h->intr[SIMPLE_MODE_INT], h->devname);
+		goto clean2;
+	}
+
+	dev_info(&pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
+	       h->devname, pdev->device, pci_name(pdev),
+	       h->intr[SIMPLE_MODE_INT], dac ? "" : " not");
+
+	h->cmd_pool_bits =
+	    kmalloc(((h->nr_cmds + BITS_PER_LONG -
+		      1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
+	h->cmd_pool = pci_alloc_consistent(h->pdev,
+		    h->nr_cmds * sizeof(*h->cmd_pool),
+		    &(h->cmd_pool_dhandle));
+	h->errinfo_pool = pci_alloc_consistent(h->pdev,
+		    h->nr_cmds * sizeof(*h->errinfo_pool),
+		    &(h->errinfo_pool_dhandle));
+	if ((h->cmd_pool_bits == NULL)
+	    || (h->cmd_pool == NULL)
+	    || (h->errinfo_pool == NULL)) {
+		dev_err(&pdev->dev, "out of memory");
+		goto clean4;
+	}
+	spin_lock_init(&h->lock);
+
+	pci_set_drvdata(pdev, h);
+	memset(h->cmd_pool_bits, 0,
+	       ((h->nr_cmds + BITS_PER_LONG -
+		 1) / BITS_PER_LONG) * sizeof(unsigned long));
+
+	hpsa_scsi_setup(h);
+
+	/* Turn the interrupts on so we can service requests */
+	h->access.set_intr_mask(h, HPSA_INTR_ON);
+
+	hpsa_register_scsi(h);	/* hook ourselves into SCSI subsystem */
+	h->busy_initializing = 0;
+	return 1;
+
+clean4:
+	kfree(h->cmd_pool_bits);
+	if (h->cmd_pool)
+		pci_free_consistent(h->pdev,
+			    h->nr_cmds * sizeof(struct CommandList),
+			    h->cmd_pool, h->cmd_pool_dhandle);
+	if (h->errinfo_pool)
+		pci_free_consistent(h->pdev,
+			    h->nr_cmds * sizeof(struct ErrorInfo),
+			    h->errinfo_pool,
+			    h->errinfo_pool_dhandle);
+	free_irq(h->intr[SIMPLE_MODE_INT], h);
+clean2:
+clean1:
+	h->busy_initializing = 0;
+	kfree(h);
+	return -1;
+}
+
+static void hpsa_flush_cache(struct ctlr_info *h)
+{
+	char *flush_buf;
+	struct CommandList *c;
+
+	flush_buf = kzalloc(4, GFP_KERNEL);
+	if (!flush_buf)
+		return;
+
+	c = cmd_special_alloc(h);
+	if (!c) {
+		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
+		goto out_of_memory;
+	}
+	fill_cmd(c, HPSA_CACHE_FLUSH, h, flush_buf, 4, 0,
+		RAID_CTLR_LUNID, TYPE_CMD);
+	hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE);
+	if (c->err_info->CommandStatus != 0)
+		dev_warn(&h->pdev->dev,
+			"error flushing cache on controller\n");
+	cmd_special_free(h, c);
+out_of_memory:
+	kfree(flush_buf);
+}
+
+static void hpsa_shutdown(struct pci_dev *pdev)
+{
+	struct ctlr_info *h;
+
+	h = pci_get_drvdata(pdev);
+	/* Turn board interrupts off  and send the flush cache command
+	 * sendcmd will turn off interrupt, and send the flush...
+	 * To write all data in the battery backed cache to disks
+	 */
+	hpsa_flush_cache(h);
+	h->access.set_intr_mask(h, HPSA_INTR_OFF);
+	free_irq(h->intr[2], h);
+#ifdef CONFIG_PCI_MSI
+	if (h->msix_vector)
+		pci_disable_msix(h->pdev);
+	else if (h->msi_vector)
+		pci_disable_msi(h->pdev);
+#endif				/* CONFIG_PCI_MSI */
+}
+
+static void __devexit hpsa_remove_one(struct pci_dev *pdev)
+{
+	struct ctlr_info *h;
+
+	if (pci_get_drvdata(pdev) == NULL) {
+		dev_err(&pdev->dev, "unable to remove device \n");
+		return;
+	}
+	h = pci_get_drvdata(pdev);
+	mutex_lock(&h->busy_shutting_down);
+	remove_from_scan_list(h);
+	hpsa_unregister_scsi(h);	/* unhook from SCSI subsystem */
+	hpsa_shutdown(pdev);
+	iounmap(h->vaddr);
+	pci_free_consistent(h->pdev,
+		h->nr_cmds * sizeof(struct CommandList),
+		h->cmd_pool, h->cmd_pool_dhandle);
+	pci_free_consistent(h->pdev,
+		h->nr_cmds * sizeof(struct ErrorInfo),
+		h->errinfo_pool, h->errinfo_pool_dhandle);
+	kfree(h->cmd_pool_bits);
+	/*
+	 * Deliberately omit pci_disable_device(): it does something nasty to
+	 * Smart Array controllers that pci_enable_device does not undo
+	 */
+	pci_release_regions(pdev);
+	pci_set_drvdata(pdev, NULL);
+	mutex_unlock(&h->busy_shutting_down);
+	kfree(h);
+}
+
+static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev,
+	__attribute__((unused)) pm_message_t state)
+{
+	return -ENOSYS;
+}
+
+static int hpsa_resume(__attribute__((unused)) struct pci_dev *pdev)
+{
+	return -ENOSYS;
+}
+
+static struct pci_driver hpsa_pci_driver = {
+	.name = "hpsa",
+	.probe = hpsa_init_one,
+	.remove = __devexit_p(hpsa_remove_one),
+	.id_table = hpsa_pci_device_id,	/* id_table */
+	.shutdown = hpsa_shutdown,
+	.suspend = hpsa_suspend,
+	.resume = hpsa_resume,
+};
+
+/*
+ *  This is it.  Register the PCI driver information for the cards we control
+ *  the OS will call our registered routines when it finds one of our cards.
+ */
+static int __init hpsa_init(void)
+{
+	int err;
+	/* Start the scan thread */
+	hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
+	if (IS_ERR(hpsa_scan_thread)) {
+		err = PTR_ERR(hpsa_scan_thread);
+		return -ENODEV;
+	}
+	err = pci_register_driver(&hpsa_pci_driver);
+	if (err)
+		kthread_stop(hpsa_scan_thread);
+	return err;
+}
+
+static void __exit hpsa_cleanup(void)
+{
+	pci_unregister_driver(&hpsa_pci_driver);
+	kthread_stop(hpsa_scan_thread);
+}
+
+module_init(hpsa_init);
+module_exit(hpsa_cleanup);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/hpsa_cmd.h linux-libre-2.6.33-gnu1/drivers/scsi/hpsa_cmd.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/hpsa_cmd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/hpsa_cmd.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,326 @@
+/*
+ *    Disk Array driver for HP Smart Array SAS controllers
+ *    Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
+ *
+ *    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, 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.
+ *
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
+ *
+ */
+#ifndef HPSA_CMD_H
+#define HPSA_CMD_H
+
+/* general boundary defintions */
+#define SENSEINFOBYTES          32 /* may vary between hbas */
+#define MAXSGENTRIES            31
+#define MAXREPLYQS              256
+
+/* Command Status value */
+#define CMD_SUCCESS             0x0000
+#define CMD_TARGET_STATUS       0x0001
+#define CMD_DATA_UNDERRUN       0x0002
+#define CMD_DATA_OVERRUN        0x0003
+#define CMD_INVALID             0x0004
+#define CMD_PROTOCOL_ERR        0x0005
+#define CMD_HARDWARE_ERR        0x0006
+#define CMD_CONNECTION_LOST     0x0007
+#define CMD_ABORTED             0x0008
+#define CMD_ABORT_FAILED        0x0009
+#define CMD_UNSOLICITED_ABORT   0x000A
+#define CMD_TIMEOUT             0x000B
+#define CMD_UNABORTABLE		0x000C
+
+/* Unit Attentions ASC's as defined for the MSA2012sa */
+#define POWER_OR_RESET			0x29
+#define STATE_CHANGED			0x2a
+#define UNIT_ATTENTION_CLEARED		0x2f
+#define LUN_FAILED			0x3e
+#define REPORT_LUNS_CHANGED		0x3f
+
+/* Unit Attentions ASCQ's as defined for the MSA2012sa */
+
+	/* These ASCQ's defined for ASC = POWER_OR_RESET */
+#define POWER_ON_RESET			0x00
+#define POWER_ON_REBOOT			0x01
+#define SCSI_BUS_RESET			0x02
+#define MSA_TARGET_RESET		0x03
+#define CONTROLLER_FAILOVER		0x04
+#define TRANSCEIVER_SE			0x05
+#define TRANSCEIVER_LVD			0x06
+
+	/* These ASCQ's defined for ASC = STATE_CHANGED */
+#define RESERVATION_PREEMPTED		0x03
+#define ASYM_ACCESS_CHANGED		0x06
+#define LUN_CAPACITY_CHANGED		0x09
+
+/* transfer direction */
+#define XFER_NONE               0x00
+#define XFER_WRITE              0x01
+#define XFER_READ               0x02
+#define XFER_RSVD               0x03
+
+/* task attribute */
+#define ATTR_UNTAGGED           0x00
+#define ATTR_SIMPLE             0x04
+#define ATTR_HEADOFQUEUE        0x05
+#define ATTR_ORDERED            0x06
+#define ATTR_ACA                0x07
+
+/* cdb type */
+#define TYPE_CMD				0x00
+#define TYPE_MSG				0x01
+
+/* config space register offsets */
+#define CFG_VENDORID            0x00
+#define CFG_DEVICEID            0x02
+#define CFG_I2OBAR              0x10
+#define CFG_MEM1BAR             0x14
+
+/* i2o space register offsets */
+#define I2O_IBDB_SET            0x20
+#define I2O_IBDB_CLEAR          0x70
+#define I2O_INT_STATUS          0x30
+#define I2O_INT_MASK            0x34
+#define I2O_IBPOST_Q            0x40
+#define I2O_OBPOST_Q            0x44
+#define I2O_DMA1_CFG		0x214
+
+/* Configuration Table */
+#define CFGTBL_ChangeReq        0x00000001l
+#define CFGTBL_AccCmds          0x00000001l
+
+#define CFGTBL_Trans_Simple     0x00000002l
+
+#define CFGTBL_BusType_Ultra2   0x00000001l
+#define CFGTBL_BusType_Ultra3   0x00000002l
+#define CFGTBL_BusType_Fibre1G  0x00000100l
+#define CFGTBL_BusType_Fibre2G  0x00000200l
+struct vals32 {
+	__u32   lower;
+	__u32   upper;
+};
+
+union u64bit {
+	struct vals32 val32;
+	__u64 val;
+};
+
+/* FIXME this is a per controller value (barf!) */
+#define HPSA_MAX_TARGETS_PER_CTLR 16
+#define HPSA_MAX_LUN 256
+#define HPSA_MAX_PHYS_LUN 1024
+
+/* SCSI-3 Commands */
+#pragma pack(1)
+
+#define HPSA_INQUIRY 0x12
+struct InquiryData {
+	__u8 data_byte[36];
+};
+
+#define HPSA_REPORT_LOG 0xc2    /* Report Logical LUNs */
+#define HPSA_REPORT_PHYS 0xc3   /* Report Physical LUNs */
+struct ReportLUNdata {
+	__u8 LUNListLength[4];
+	__u32 reserved;
+	__u8 LUN[HPSA_MAX_LUN][8];
+};
+
+struct ReportExtendedLUNdata {
+	__u8 LUNListLength[4];
+	__u8 extended_response_flag;
+	__u8 reserved[3];
+	__u8 LUN[HPSA_MAX_LUN][24];
+};
+
+struct SenseSubsystem_info {
+	__u8 reserved[36];
+	__u8 portname[8];
+	__u8 reserved1[1108];
+};
+
+#define HPSA_READ_CAPACITY 0x25 /* Read Capacity */
+struct ReadCapdata {
+	__u8 total_size[4];	/* Total size in blocks */
+	__u8 block_size[4];	/* Size of blocks in bytes */
+};
+
+#if 0
+/* 12 byte commands not implemented in firmware yet. */
+#define HPSA_READ 	0xa8
+#define HPSA_WRITE	0xaa
+#endif
+
+#define HPSA_READ   0x28    /* Read(10) */
+#define HPSA_WRITE  0x2a    /* Write(10) */
+
+/* BMIC commands */
+#define BMIC_READ 0x26
+#define BMIC_WRITE 0x27
+#define BMIC_CACHE_FLUSH 0xc2
+#define HPSA_CACHE_FLUSH 0x01	/* C2 was already being used by HPSA */
+
+/* Command List Structure */
+union SCSI3Addr {
+	struct {
+		__u8 Dev;
+		__u8 Bus:6;
+		__u8 Mode:2;        /* b00 */
+	} PeripDev;
+	struct {
+		__u8 DevLSB;
+		__u8 DevMSB:6;
+		__u8 Mode:2;        /* b01 */
+	} LogDev;
+	struct {
+		__u8 Dev:5;
+		__u8 Bus:3;
+		__u8 Targ:6;
+		__u8 Mode:2;        /* b10 */
+	} LogUnit;
+};
+
+struct PhysDevAddr {
+	__u32             TargetId:24;
+	__u32             Bus:6;
+	__u32             Mode:2;
+	/* 2 level target device addr */
+	union SCSI3Addr  Target[2];
+};
+
+struct LogDevAddr {
+	__u32            VolId:30;
+	__u32            Mode:2;
+	__u8             reserved[4];
+};
+
+union LUNAddr {
+	__u8               LunAddrBytes[8];
+	union SCSI3Addr    SCSI3Lun[4];
+	struct PhysDevAddr PhysDev;
+	struct LogDevAddr  LogDev;
+};
+
+struct CommandListHeader {
+	__u8              ReplyQueue;
+	__u8              SGList;
+	__u16             SGTotal;
+	struct vals32     Tag;
+	union LUNAddr     LUN;
+};
+
+struct RequestBlock {
+	__u8   CDBLen;
+	struct {
+		__u8 Type:3;
+		__u8 Attribute:3;
+		__u8 Direction:2;
+	} Type;
+	__u16  Timeout;
+	__u8   CDB[16];
+};
+
+struct ErrDescriptor {
+	struct vals32 Addr;
+	__u32  Len;
+};
+
+struct SGDescriptor {
+	struct vals32 Addr;
+	__u32  Len;
+	__u32  Ext;
+};
+
+union MoreErrInfo {
+	struct {
+		__u8  Reserved[3];
+		__u8  Type;
+		__u32 ErrorInfo;
+	} Common_Info;
+	struct {
+		__u8  Reserved[2];
+		__u8  offense_size; /* size of offending entry */
+		__u8  offense_num;  /* byte # of offense 0-base */
+		__u32 offense_value;
+	} Invalid_Cmd;
+};
+struct ErrorInfo {
+	__u8               ScsiStatus;
+	__u8               SenseLen;
+	__u16              CommandStatus;
+	__u32              ResidualCnt;
+	union MoreErrInfo  MoreErrInfo;
+	__u8               SenseInfo[SENSEINFOBYTES];
+};
+/* Command types */
+#define CMD_IOCTL_PEND  0x01
+#define CMD_SCSI	0x03
+
+struct ctlr_info; /* defined in hpsa.h */
+/* The size of this structure needs to be divisible by 8
+ * od on all architectures, because the controller uses 2
+ * lower bits of the address, and the driver uses 1 lower
+ * bit (3 bits total.)
+ */
+struct CommandList {
+	struct CommandListHeader Header;
+	struct RequestBlock      Request;
+	struct ErrDescriptor     ErrDesc;
+	struct SGDescriptor      SG[MAXSGENTRIES];
+	/* information associated with the command */
+	__u32			   busaddr; /* physical addr of this record */
+	struct ErrorInfo *err_info; /* pointer to the allocated mem */
+	struct ctlr_info	   *h;
+	int			   cmd_type;
+	long			   cmdindex;
+	struct hlist_node list;
+	struct CommandList *prev;
+	struct CommandList *next;
+	struct request *rq;
+	struct completion *waiting;
+	int	 retry_count;
+	void   *scsi_cmd;
+};
+
+/* Configuration Table Structure */
+struct HostWrite {
+	__u32 TransportRequest;
+	__u32 Reserved;
+	__u32 CoalIntDelay;
+	__u32 CoalIntCount;
+};
+
+struct CfgTable {
+	__u8             Signature[4];
+	__u32            SpecValence;
+	__u32            TransportSupport;
+	__u32            TransportActive;
+	struct HostWrite HostWrite;
+	__u32            CmdsOutMax;
+	__u32            BusTypes;
+	__u32            Reserved;
+	__u8             ServerName[16];
+	__u32            HeartBeat;
+	__u32            SCSI_Prefetch;
+};
+
+struct hpsa_pci_info {
+	unsigned char	bus;
+	unsigned char	dev_fn;
+	unsigned short	domain;
+	__u32		board_id;
+};
+
+#pragma pack()
+#endif /* HPSA_CMD_H */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/hpsa.h linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/hpsa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/hpsa.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,273 @@
+/*
+ *    Disk Array driver for HP Smart Array SAS controllers
+ *    Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
+ *
+ *    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, 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.
+ *
+ *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
+ *
+ */
+#ifndef HPSA_H
+#define HPSA_H
+
+#include <scsi/scsicam.h>
+
+#define IO_OK		0
+#define IO_ERROR	1
+
+struct ctlr_info;
+
+struct access_method {
+	void (*submit_command)(struct ctlr_info *h,
+		struct CommandList *c);
+	void (*set_intr_mask)(struct ctlr_info *h, unsigned long val);
+	unsigned long (*fifo_full)(struct ctlr_info *h);
+	unsigned long (*intr_pending)(struct ctlr_info *h);
+	unsigned long (*command_completed)(struct ctlr_info *h);
+};
+
+struct hpsa_scsi_dev_t {
+	int devtype;
+	int bus, target, lun;		/* as presented to the OS */
+	unsigned char scsi3addr[8];	/* as presented to the HW */
+#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
+	unsigned char device_id[16];    /* from inquiry pg. 0x83 */
+	unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
+	unsigned char model[16];        /* bytes 16-31 of inquiry data */
+	unsigned char revision[4];      /* bytes 32-35 of inquiry data */
+	unsigned char raid_level;	/* from inquiry page 0xC1 */
+};
+
+struct ctlr_info {
+	int	ctlr;
+	char	devname[8];
+	char    *product_name;
+	char	firm_ver[4]; /* Firmware version */
+	struct pci_dev *pdev;
+	__u32	board_id;
+	void __iomem *vaddr;
+	unsigned long paddr;
+	int 	nr_cmds; /* Number of commands allowed on this controller */
+	struct CfgTable __iomem *cfgtable;
+	int	interrupts_enabled;
+	int	major;
+	int 	max_commands;
+	int	commands_outstanding;
+	int 	max_outstanding; /* Debug */
+	int	usage_count;  /* number of opens all all minor devices */
+#	define DOORBELL_INT	0
+#	define PERF_MODE_INT	1
+#	define SIMPLE_MODE_INT	2
+#	define MEMQ_MODE_INT	3
+	unsigned int intr[4];
+	unsigned int msix_vector;
+	unsigned int msi_vector;
+	struct access_method access;
+
+	/* queue and queue Info */
+	struct hlist_head reqQ;
+	struct hlist_head cmpQ;
+	unsigned int Qdepth;
+	unsigned int maxQsinceinit;
+	unsigned int maxSG;
+	spinlock_t lock;
+
+	/* pointers to command and error info pool */
+	struct CommandList 	*cmd_pool;
+	dma_addr_t		cmd_pool_dhandle;
+	struct ErrorInfo 	*errinfo_pool;
+	dma_addr_t		errinfo_pool_dhandle;
+	unsigned long  		*cmd_pool_bits;
+	int			nr_allocs;
+	int			nr_frees;
+	int			busy_initializing;
+	int			busy_scanning;
+	struct mutex		busy_shutting_down;
+	struct list_head	scan_list;
+	struct completion	scan_wait;
+
+	struct Scsi_Host *scsi_host;
+	spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
+	int ndevices; /* number of used elements in .dev[] array. */
+#define HPSA_MAX_SCSI_DEVS_PER_HBA 256
+	struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
+};
+#define HPSA_ABORT_MSG 0
+#define HPSA_DEVICE_RESET_MSG 1
+#define HPSA_BUS_RESET_MSG 2
+#define HPSA_HOST_RESET_MSG 3
+#define HPSA_MSG_SEND_RETRY_LIMIT 10
+#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000
+
+/* Maximum time in seconds driver will wait for command completions
+ * when polling before giving up.
+ */
+#define HPSA_MAX_POLL_TIME_SECS (20)
+
+/* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines
+ * how many times to retry TEST UNIT READY on a device
+ * while waiting for it to become ready before giving up.
+ * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval
+ * between sending TURs while waiting for a device
+ * to become ready.
+ */
+#define HPSA_TUR_RETRY_LIMIT (20)
+#define HPSA_MAX_WAIT_INTERVAL_SECS (30)
+
+/* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board
+ * to become ready, in seconds, before giving up on it.
+ * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait
+ * between polling the board to see if it is ready, in
+ * milliseconds.  HPSA_BOARD_READY_POLL_INTERVAL and
+ * HPSA_BOARD_READY_ITERATIONS are derived from those.
+ */
+#define HPSA_BOARD_READY_WAIT_SECS (120)
+#define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100)
+#define HPSA_BOARD_READY_POLL_INTERVAL \
+	((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000)
+#define HPSA_BOARD_READY_ITERATIONS \
+	((HPSA_BOARD_READY_WAIT_SECS * 1000) / \
+		HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
+#define HPSA_POST_RESET_PAUSE_MSECS (3000)
+#define HPSA_POST_RESET_NOOP_RETRIES (12)
+
+/*  Defining the diffent access_menthods */
+/*
+ * Memory mapped FIFO interface (SMART 53xx cards)
+ */
+#define SA5_DOORBELL	0x20
+#define SA5_REQUEST_PORT_OFFSET	0x40
+#define SA5_REPLY_INTR_MASK_OFFSET	0x34
+#define SA5_REPLY_PORT_OFFSET		0x44
+#define SA5_INTR_STATUS		0x30
+#define SA5_SCRATCHPAD_OFFSET	0xB0
+
+#define SA5_CTCFG_OFFSET	0xB4
+#define SA5_CTMEM_OFFSET	0xB8
+
+#define SA5_INTR_OFF		0x08
+#define SA5B_INTR_OFF		0x04
+#define SA5_INTR_PENDING	0x08
+#define SA5B_INTR_PENDING	0x04
+#define FIFO_EMPTY		0xffffffff
+#define HPSA_FIRMWARE_READY	0xffff0000 /* value in scratchpad register */
+
+#define HPSA_ERROR_BIT		0x02
+#define HPSA_TAG_CONTAINS_INDEX(tag) ((tag) & 0x04)
+#define HPSA_TAG_TO_INDEX(tag) ((tag) >> 3)
+#define HPSA_TAG_DISCARD_ERROR_BITS(tag) ((tag) & ~3)
+
+#define HPSA_INTR_ON 	1
+#define HPSA_INTR_OFF	0
+/*
+	Send the command to the hardware
+*/
+static void SA5_submit_command(struct ctlr_info *h,
+	struct CommandList *c)
+{
+#ifdef HPSA_DEBUG
+	 printk(KERN_WARNING "hpsa: Sending %x - down to controller\n",
+		c->busaddr);
+#endif /* HPSA_DEBUG */
+	writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
+	h->commands_outstanding++;
+	if (h->commands_outstanding > h->max_outstanding)
+		h->max_outstanding = h->commands_outstanding;
+}
+
+/*
+ *  This card is the opposite of the other cards.
+ *   0 turns interrupts on...
+ *   0x08 turns them off...
+ */
+static void SA5_intr_mask(struct ctlr_info *h, unsigned long val)
+{
+	if (val) { /* Turn interrupts on */
+		h->interrupts_enabled = 1;
+		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+	} else { /* Turn them off */
+		h->interrupts_enabled = 0;
+		writel(SA5_INTR_OFF,
+			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+	}
+}
+/*
+ *  Returns true if fifo is full.
+ *
+ */
+static unsigned long SA5_fifo_full(struct ctlr_info *h)
+{
+	if (h->commands_outstanding >= h->max_commands)
+		return 1;
+	else
+		return 0;
+
+}
+/*
+ *   returns value read from hardware.
+ *     returns FIFO_EMPTY if there is nothing to read
+ */
+static unsigned long SA5_completed(struct ctlr_info *h)
+{
+	unsigned long register_value
+		= readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
+
+	if (register_value != FIFO_EMPTY)
+		h->commands_outstanding--;
+
+#ifdef HPSA_DEBUG
+	if (register_value != FIFO_EMPTY)
+		printk(KERN_INFO "hpsa:  Read %lx back from board\n",
+			register_value);
+	else
+		printk(KERN_INFO "hpsa:  FIFO Empty read\n");
+#endif
+
+	return register_value;
+}
+/*
+ *	Returns true if an interrupt is pending..
+ */
+static unsigned long SA5_intr_pending(struct ctlr_info *h)
+{
+	unsigned long register_value  =
+		readl(h->vaddr + SA5_INTR_STATUS);
+#ifdef HPSA_DEBUG
+	printk(KERN_INFO "hpsa: intr_pending %lx\n", register_value);
+#endif  /* HPSA_DEBUG */
+	if (register_value &  SA5_INTR_PENDING)
+		return  1;
+	return 0 ;
+}
+
+
+static struct access_method SA5_access = {
+	SA5_submit_command,
+	SA5_intr_mask,
+	SA5_fifo_full,
+	SA5_intr_pending,
+	SA5_completed,
+};
+
+struct board_type {
+	__u32	board_id;
+	char	*product_name;
+	struct access_method *access;
+};
+
+
+/* end of old hpsa_scsi.h file */
+
+#endif /* HPSA_H */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/hptiop.c linux-libre-2.6.33-gnu1/drivers/scsi/hptiop.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/hptiop.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/hptiop.c	2010-02-24 13:52:17.000000000 -0500
@@ -834,7 +834,7 @@ static int hptiop_reset_hba(struct hptio
 			atomic_read(&hba->resetting) == 0, 60 * HZ);
 
 	if (atomic_read(&hba->resetting)) {
-		/* IOP is in unkown state, abort reset */
+		/* IOP is in unknown state, abort reset */
 		printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no);
 		return -1;
 	}
@@ -861,10 +861,13 @@ static int hptiop_reset(struct scsi_cmnd
 }
 
 static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
-						int queue_depth)
+					  int queue_depth, int reason)
 {
 	struct hptiop_hba *hba = (struct hptiop_hba *)sdev->host->hostdata;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (queue_depth > hba->max_requests)
 		queue_depth = hba->max_requests;
 	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,6 +39,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_bsg_fc.h>
 #include "ibmvfc.h"
 
 static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT;
@@ -558,12 +559,11 @@ static void ibmvfc_link_down(struct ibmv
 /**
  * ibmvfc_init_host - Start host initialization
  * @vhost:		ibmvfc host struct
- * @relogin:	is this a re-login?
  *
  * Return value:
  *	nothing
  **/
-static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin)
+static void ibmvfc_init_host(struct ibmvfc_host *vhost)
 {
 	struct ibmvfc_target *tgt;
 
@@ -577,10 +577,8 @@ static void ibmvfc_init_host(struct ibmv
 	}
 
 	if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
-		if (!relogin) {
-			memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
-			vhost->async_crq.cur = 0;
-		}
+		memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
+		vhost->async_crq.cur = 0;
 
 		list_for_each_entry(tgt, &vhost->targets, queue)
 			ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
@@ -1678,6 +1676,276 @@ static void ibmvfc_sync_completion(struc
 }
 
 /**
+ * ibmvfc_bsg_timeout_done - Completion handler for cancelling BSG commands
+ * @evt:	struct ibmvfc_event
+ *
+ **/
+static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+
+	ibmvfc_free_event(evt);
+	vhost->aborting_passthru = 0;
+	dev_info(vhost->dev, "Passthru command cancelled\n");
+}
+
+/**
+ * ibmvfc_bsg_timeout - Handle a BSG timeout
+ * @job:	struct fc_bsg_job that timed out
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
+{
+	struct ibmvfc_host *vhost = shost_priv(job->shost);
+	unsigned long port_id = (unsigned long)job->dd_data;
+	struct ibmvfc_event *evt;
+	struct ibmvfc_tmf *tmf;
+	unsigned long flags;
+	int rc;
+
+	ENTER;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	if (vhost->aborting_passthru || vhost->state != IBMVFC_ACTIVE) {
+		__ibmvfc_reset_host(vhost);
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return 0;
+	}
+
+	vhost->aborting_passthru = 1;
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT);
+
+	tmf = &evt->iu.tmf;
+	memset(tmf, 0, sizeof(*tmf));
+	tmf->common.version = 1;
+	tmf->common.opcode = IBMVFC_TMF_MAD;
+	tmf->common.length = sizeof(*tmf);
+	tmf->scsi_id = port_id;
+	tmf->cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
+	tmf->my_cancel_key = IBMVFC_INTERNAL_CANCEL_KEY;
+	rc = ibmvfc_send_event(evt, vhost, default_timeout);
+
+	if (rc != 0) {
+		vhost->aborting_passthru = 0;
+		dev_err(vhost->dev, "Failed to send cancel event. rc=%d\n", rc);
+		rc = -EIO;
+	} else
+		dev_info(vhost->dev, "Cancelling passthru command to port id 0x%lx\n",
+			 port_id);
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	LEAVE;
+	return rc;
+}
+
+/**
+ * ibmvfc_bsg_plogi - PLOGI into a target to handle a BSG command
+ * @vhost:		struct ibmvfc_host to send command
+ * @port_id:	port ID to send command
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id)
+{
+	struct ibmvfc_port_login *plogi;
+	struct ibmvfc_target *tgt;
+	struct ibmvfc_event *evt;
+	union ibmvfc_iu rsp_iu;
+	unsigned long flags;
+	int rc = 0, issue_login = 1;
+
+	ENTER;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	list_for_each_entry(tgt, &vhost->targets, queue) {
+		if (tgt->scsi_id == port_id) {
+			issue_login = 0;
+			break;
+		}
+	}
+
+	if (!issue_login)
+		goto unlock_out;
+	if (unlikely((rc = ibmvfc_host_chkready(vhost))))
+		goto unlock_out;
+
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
+	plogi = &evt->iu.plogi;
+	memset(plogi, 0, sizeof(*plogi));
+	plogi->common.version = 1;
+	plogi->common.opcode = IBMVFC_PORT_LOGIN;
+	plogi->common.length = sizeof(*plogi);
+	plogi->scsi_id = port_id;
+	evt->sync_iu = &rsp_iu;
+	init_completion(&evt->comp);
+
+	rc = ibmvfc_send_event(evt, vhost, default_timeout);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rc)
+		return -EIO;
+
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.plogi.common.status)
+		rc = -EIO;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+unlock_out:
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	LEAVE;
+	return rc;
+}
+
+/**
+ * ibmvfc_bsg_request - Handle a BSG request
+ * @job:	struct fc_bsg_job to be executed
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_bsg_request(struct fc_bsg_job *job)
+{
+	struct ibmvfc_host *vhost = shost_priv(job->shost);
+	struct fc_rport *rport = job->rport;
+	struct ibmvfc_passthru_mad *mad;
+	struct ibmvfc_event *evt;
+	union ibmvfc_iu rsp_iu;
+	unsigned long flags, port_id = -1;
+	unsigned int code = job->request->msgcode;
+	int rc = 0, req_seg, rsp_seg, issue_login = 0;
+	u32 fc_flags, rsp_len;
+
+	ENTER;
+	job->reply->reply_payload_rcv_len = 0;
+	if (rport)
+		port_id = rport->port_id;
+
+	switch (code) {
+	case FC_BSG_HST_ELS_NOLOGIN:
+		port_id = (job->request->rqst_data.h_els.port_id[0] << 16) |
+			(job->request->rqst_data.h_els.port_id[1] << 8) |
+			job->request->rqst_data.h_els.port_id[2];
+	case FC_BSG_RPT_ELS:
+		fc_flags = IBMVFC_FC_ELS;
+		break;
+	case FC_BSG_HST_CT:
+		issue_login = 1;
+		port_id = (job->request->rqst_data.h_ct.port_id[0] << 16) |
+			(job->request->rqst_data.h_ct.port_id[1] << 8) |
+			job->request->rqst_data.h_ct.port_id[2];
+	case FC_BSG_RPT_CT:
+		fc_flags = IBMVFC_FC_CT_IU;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	if (port_id == -1)
+		return -EINVAL;
+	if (!mutex_trylock(&vhost->passthru_mutex))
+		return -EBUSY;
+
+	job->dd_data = (void *)port_id;
+	req_seg = dma_map_sg(vhost->dev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+
+	if (!req_seg) {
+		mutex_unlock(&vhost->passthru_mutex);
+		return -ENOMEM;
+	}
+
+	rsp_seg = dma_map_sg(vhost->dev, job->reply_payload.sg_list,
+			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	if (!rsp_seg) {
+		dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+		mutex_unlock(&vhost->passthru_mutex);
+		return -ENOMEM;
+	}
+
+	if (req_seg > 1 || rsp_seg > 1) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	if (issue_login)
+		rc = ibmvfc_bsg_plogi(vhost, port_id);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+
+	if (unlikely(rc || (rport && (rc = fc_remote_port_chkready(rport)))) ||
+	    unlikely((rc = ibmvfc_host_chkready(vhost)))) {
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		goto out;
+	}
+
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
+	mad = &evt->iu.passthru;
+
+	memset(mad, 0, sizeof(*mad));
+	mad->common.version = 1;
+	mad->common.opcode = IBMVFC_PASSTHRU;
+	mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu);
+
+	mad->cmd_ioba.va = (u64)evt->crq.ioba +
+		offsetof(struct ibmvfc_passthru_mad, iu);
+	mad->cmd_ioba.len = sizeof(mad->iu);
+
+	mad->iu.cmd_len = job->request_payload.payload_len;
+	mad->iu.rsp_len = job->reply_payload.payload_len;
+	mad->iu.flags = fc_flags;
+	mad->iu.cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
+
+	mad->iu.cmd.va = sg_dma_address(job->request_payload.sg_list);
+	mad->iu.cmd.len = sg_dma_len(job->request_payload.sg_list);
+	mad->iu.rsp.va = sg_dma_address(job->reply_payload.sg_list);
+	mad->iu.rsp.len = sg_dma_len(job->reply_payload.sg_list);
+	mad->iu.scsi_id = port_id;
+	mad->iu.tag = (u64)evt;
+	rsp_len = mad->iu.rsp.len;
+
+	evt->sync_iu = &rsp_iu;
+	init_completion(&evt->comp);
+	rc = ibmvfc_send_event(evt, vhost, 0);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rc) {
+		rc = -EIO;
+		goto out;
+	}
+
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.passthru.common.status)
+		rc = -EIO;
+	else
+		job->reply->reply_payload_rcv_len = rsp_len;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	job->reply->result = rc;
+	job->job_done(job);
+	rc = 0;
+out:
+	dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
+		     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	dma_unmap_sg(vhost->dev, job->reply_payload.sg_list,
+		     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	mutex_unlock(&vhost->passthru_mutex);
+	LEAVE;
+	return rc;
+}
+
+/**
  * ibmvfc_reset_device - Reset the device with the specified reset type
  * @sdev:	scsi device to reset
  * @type:	reset type
@@ -1731,7 +1999,10 @@ static int ibmvfc_reset_device(struct sc
 	sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc);
 	wait_for_completion(&evt->comp);
 
-	if (rsp_iu.cmd.status) {
+	if (rsp_iu.cmd.status)
+		rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+
+	if (rsp_code) {
 		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
 			rsp_code = fc_rsp->data.info.rsp_code;
 
@@ -1820,7 +2091,10 @@ static int ibmvfc_abort_task_set(struct
 	sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n");
 	wait_for_completion(&evt->comp);
 
-	if (rsp_iu.cmd.status) {
+	if (rsp_iu.cmd.status)
+		rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
+
+	if (rsp_code) {
 		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
 			rsp_code = fc_rsp->data.info.rsp_code;
 
@@ -2061,12 +2335,24 @@ static int ibmvfc_eh_device_reset_handle
 }
 
 /**
- * ibmvfc_dev_cancel_all - Device iterated cancel all function
+ * ibmvfc_dev_cancel_all_abts - Device iterated cancel all function
  * @sdev:	scsi device struct
  * @data:	return code
  *
  **/
-static void ibmvfc_dev_cancel_all(struct scsi_device *sdev, void *data)
+static void ibmvfc_dev_cancel_all_abts(struct scsi_device *sdev, void *data)
+{
+	unsigned long *rc = data;
+	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
+}
+
+/**
+ * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function
+ * @sdev:	scsi device struct
+ * @data:	return code
+ *
+ **/
+static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
 {
 	unsigned long *rc = data;
 	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET);
@@ -2102,7 +2388,7 @@ static int ibmvfc_eh_target_reset_handle
 
 	ENTER;
 	ibmvfc_wait_while_resetting(vhost);
-	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
 	reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target");
 
 	if (!cancel_rc && !reset_rc)
@@ -2144,7 +2430,7 @@ static void ibmvfc_terminate_rport_io(st
 	int rc = FAILED;
 
 	ENTER;
-	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_abts);
 	starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all);
 
 	if (!cancel_rc && !abort_rc)
@@ -2297,13 +2583,13 @@ static void ibmvfc_handle_crq(struct ibm
 			/* Send back a response */
 			rc = ibmvfc_send_crq_init_complete(vhost);
 			if (rc == 0)
-				ibmvfc_init_host(vhost, 0);
+				ibmvfc_init_host(vhost);
 			else
 				dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc);
 			break;
 		case IBMVFC_CRQ_INIT_COMPLETE:
 			dev_info(vhost->dev, "Partner initialization complete\n");
-			ibmvfc_init_host(vhost, 0);
+			ibmvfc_init_host(vhost);
 			break;
 		default:
 			dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format);
@@ -2478,12 +2764,17 @@ static int ibmvfc_slave_configure(struct
  * ibmvfc_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				     int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
 		qdepth = IBMVFC_MAX_CMDS_PER_LUN;
 
@@ -3725,7 +4016,7 @@ static void ibmvfc_npiv_logout_done(stru
 	case IBMVFC_MAD_SUCCESS:
 		if (list_empty(&vhost->sent) &&
 		    vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) {
-			ibmvfc_init_host(vhost, 0);
+			ibmvfc_init_host(vhost);
 			return;
 		}
 		break;
@@ -3903,6 +4194,8 @@ static void ibmvfc_tgt_add_rport(struct
 			rport->supported_classes |= FC_COS_CLASS2;
 		if (tgt->service_parms.class3_parms[0] & 0x80000000)
 			rport->supported_classes |= FC_COS_CLASS3;
+		if (rport->rqst_q)
+			blk_queue_max_hw_segments(rport->rqst_q, 1);
 	} else
 		tgt_dbg(tgt, "rport add failed\n");
 	spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -4342,6 +4635,7 @@ static int ibmvfc_probe(struct vio_dev *
 	init_waitqueue_head(&vhost->work_wait_q);
 	init_waitqueue_head(&vhost->init_wait_q);
 	INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread);
+	mutex_init(&vhost->passthru_mutex);
 
 	if ((rc = ibmvfc_alloc_mem(vhost)))
 		goto free_scsi_host;
@@ -4374,6 +4668,8 @@ static int ibmvfc_probe(struct vio_dev *
 		goto remove_shost;
 	}
 
+	if (shost_to_fc_host(shost)->rqst_q)
+		blk_queue_max_hw_segments(shost_to_fc_host(shost)->rqst_q, 1);
 	dev_set_drvdata(dev, vhost);
 	spin_lock(&ibmvfc_driver_lock);
 	list_add_tail(&vhost->queue, &ibmvfc_head);
@@ -4414,7 +4710,11 @@ static int ibmvfc_remove(struct vio_dev
 
 	ENTER;
 	ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
 	ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
 	ibmvfc_wait_while_resetting(vhost);
 	ibmvfc_release_crq_queue(vhost);
 	kthread_stop(vhost->work_thread);
@@ -4498,6 +4798,9 @@ static struct fc_function_template ibmvf
 
 	.get_starget_port_id = ibmvfc_get_starget_port_id,
 	.show_starget_port_id = 1,
+
+	.bsg_request = ibmvfc_bsg_request,
+	.bsg_timeout = ibmvfc_bsg_timeout,
 };
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvfc.h linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvfc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvfc.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,8 +29,8 @@
 #include "viosrp.h"
 
 #define IBMVFC_NAME	"ibmvfc"
-#define IBMVFC_DRIVER_VERSION		"1.0.6"
-#define IBMVFC_DRIVER_DATE		"(May 28, 2009)"
+#define IBMVFC_DRIVER_VERSION		"1.0.7"
+#define IBMVFC_DRIVER_DATE		"(October 16, 2009)"
 
 #define IBMVFC_DEFAULT_TIMEOUT	60
 #define IBMVFC_ADISC_CANCEL_TIMEOUT	45
@@ -58,9 +58,10 @@
  * 1 for ERP
  * 1 for initialization
  * 1 for NPIV Logout
+ * 2 for BSG passthru
  * 2 for each discovery thread
  */
-#define IBMVFC_NUM_INTERNAL_REQ	(1 + 1 + 1 + (disc_threads * 2))
+#define IBMVFC_NUM_INTERNAL_REQ	(1 + 1 + 1 + 2 + (disc_threads * 2))
 
 #define IBMVFC_MAD_SUCCESS		0x00
 #define IBMVFC_MAD_NOT_SUPPORTED	0xF1
@@ -466,7 +467,10 @@ struct ibmvfc_passthru_iu {
 	u16 error;
 	u32 flags;
 #define IBMVFC_FC_ELS		0x01
+#define IBMVFC_FC_CT_IU		0x02
 	u32 cancel_key;
+#define IBMVFC_PASSTHRU_CANCEL_KEY	0x80000000
+#define IBMVFC_INTERNAL_CANCEL_KEY	0x80000001
 	u32 reserved;
 	struct srp_direct_buf cmd;
 	struct srp_direct_buf rsp;
@@ -693,6 +697,7 @@ struct ibmvfc_host {
 	int disc_buf_sz;
 	int log_level;
 	struct ibmvfc_discover_targets_buf *disc_buf;
+	struct mutex passthru_mutex;
 	int task_set;
 	int init_retries;
 	int discovery_threads;
@@ -702,6 +707,7 @@ struct ibmvfc_host {
 	int delay_init;
 	int scan_complete;
 	int logged_in;
+	int aborting_passthru;
 	int events_to_log;
 #define IBMVFC_AE_LINKUP	0x0001
 #define IBMVFC_AE_LINKDOWN	0x0002
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/ibmvscsi/ibmvscsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -1637,12 +1637,17 @@ static int ibmvscsi_slave_configure(stru
  * ibmvscsi_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ibmvscsi_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > IBMVSCSI_MAX_CMDS_PER_LUN)
 		qdepth = IBMVSCSI_MAX_CMDS_PER_LUN;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/ipr.c linux-libre-2.6.33-gnu1/drivers/scsi/ipr.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/ipr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/ipr.c	2010-02-24 13:52:17.000000000 -0500
@@ -1333,7 +1333,7 @@ static void ipr_log_enhanced_dual_ioa_er
 
 	error = &hostrcb->hcam.u.error.u.type_17_error;
 	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
-	strstrip(error->failure_reason);
+	strim(error->failure_reason);
 
 	ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason,
 		     be32_to_cpu(hostrcb->hcam.u.error.prc));
@@ -1359,7 +1359,7 @@ static void ipr_log_dual_ioa_error(struc
 
 	error = &hostrcb->hcam.u.error.u.type_07_error;
 	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
-	strstrip(error->failure_reason);
+	strim(error->failure_reason);
 
 	ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason,
 		     be32_to_cpu(hostrcb->hcam.u.error.prc));
@@ -3367,16 +3367,21 @@ static int ipr_free_dump(struct ipr_ioa_
  * ipr_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  **/
-static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				  int reason)
 {
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
 	struct ipr_resource_entry *res;
 	unsigned long lock_flags = 0;
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
 
@@ -6516,6 +6521,7 @@ static int ipr_reset_restore_cfg_space(s
 	int rc;
 
 	ENTER;
+	ioa_cfg->pdev->state_saved = true;
 	rc = pci_restore_state(ioa_cfg->pdev);
 
 	if (rc != PCIBIOS_SUCCESSFUL) {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/iscsi_tcp.c linux-libre-2.6.33-gnu1/drivers/scsi/iscsi_tcp.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/iscsi_tcp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/iscsi_tcp.c	2010-02-24 13:52:17.000000000 -0500
@@ -903,7 +903,7 @@ static struct iscsi_transport iscsi_sw_t
 				  ISCSI_USERNAME | ISCSI_PASSWORD |
 				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
 				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
-				  ISCSI_LU_RESET_TMO |
+				  ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
 				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
 				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
 	.host_param_mask	= ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/Kconfig linux-libre-2.6.33-gnu1/drivers/scsi/Kconfig
--- linux-libre-2.6.32-gnu1/drivers/scsi/Kconfig	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/Kconfig	2010-02-24 13:52:17.000000000 -0500
@@ -388,6 +388,16 @@ config BLK_DEV_3W_XXXX_RAID
 	  Please read the comments at the top of
 	  <file:drivers/scsi/3w-xxxx.c>.
 
+config SCSI_HPSA
+	tristate "HP Smart Array SCSI driver"
+	depends on PCI && SCSI
+	help
+	  This driver supports HP Smart Array Controllers (circa 2009).
+	  It is a SCSI alternative to the cciss driver, which is a block
+	  driver.  Anyone wishing to use HP Smart Array controllers who
+	  would prefer the devices be presented to linux as SCSI devices,
+	  rather than as generic block devices should say Y here.
+
 config SCSI_3W_9XXX
 	tristate "3ware 9xxx SATA-RAID support"
 	depends on PCI && SCSI
@@ -399,6 +409,17 @@ config SCSI_3W_9XXX
 	  Please read the comments at the top of
 	  <file:drivers/scsi/3w-9xxx.c>.
 
+config SCSI_3W_SAS
+	tristate "3ware 97xx SAS/SATA-RAID support"
+	depends on PCI && SCSI
+	help
+	  This driver supports the LSI 3ware 9750 6Gb/s SAS/SATA-RAID cards.
+
+	  <http://www.lsi.com>
+
+	  Please read the comments at the top of
+	  <file:drivers/scsi/3w-sas.c>.
+
 config SCSI_7000FASST
 	tristate "7000FASST SCSI support"
 	depends on ISA && SCSI && ISA_DMA_API
@@ -621,6 +642,14 @@ config SCSI_FLASHPOINT
 	  substantial, so users of MultiMaster Host Adapters may not
 	  wish to include it.
 
+config VMWARE_PVSCSI
+	tristate "VMware PVSCSI driver support"
+	depends on PCI && SCSI && X86
+	help
+	  This driver supports VMware's para virtualized SCSI HBA.
+	  To compile this driver as a module, choose M here: the
+	  module will be called vmw_pvscsi.
+
 config LIBFC
 	tristate "LibFC module"
 	select SCSI_FC_ATTRS
@@ -644,7 +673,7 @@ config FCOE
 config FCOE_FNIC
 	tristate "Cisco FNIC Driver"
 	depends on PCI && X86
-	select LIBFC
+	select LIBFCOE
 	help
 	  This is support for the Cisco PCI-Express FCoE HBA.
 
@@ -1818,6 +1847,14 @@ config SCSI_PMCRAID
 	---help---
 	  This driver supports the PMC SIERRA MaxRAID adapters.
 
+config SCSI_PM8001
+	tristate "PMC-Sierra SPC 8001 SAS/SATA Based Host Adapter driver"
+	depends on PCI && SCSI
+	select SCSI_SAS_LIBSAS
+	help
+	  This driver supports PMC-Sierra PCIE SAS/SATA 8x6G SPC 8001 chip
+	  based host adapters.
+
 config SCSI_SRP
 	tristate "SCSI RDMA Protocol helper library"
 	depends on SCSI && PCI
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_disc.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_disc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_disc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_disc.c	2010-02-24 13:52:17.000000000 -0500
@@ -40,6 +40,8 @@
 
 #include <scsi/libfc.h>
 
+#include "fc_libfc.h"
+
 #define FC_DISC_RETRY_LIMIT	3	/* max retries */
 #define FC_DISC_RETRY_DELAY	500UL	/* (msecs) delay */
 
@@ -51,8 +53,8 @@ static int fc_disc_single(struct fc_lpor
 static void fc_disc_restart(struct fc_disc *);
 
 /**
- * fc_disc_stop_rports() - delete all the remote ports associated with the lport
- * @disc: The discovery job to stop rports on
+ * fc_disc_stop_rports() - Delete all the remote ports associated with the lport
+ * @disc: The discovery job to stop remote ports on
  *
  * Locking Note: This function expects that the lport mutex is locked before
  * calling it.
@@ -72,9 +74,9 @@ void fc_disc_stop_rports(struct fc_disc
 
 /**
  * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
- * @sp: Current sequence of the RSCN exchange
- * @fp: RSCN Frame
- * @lport: Fibre Channel host port instance
+ * @sp:	   The sequence of the RSCN exchange
+ * @fp:	   The RSCN frame
+ * @lport: The local port that the request will be sent on
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -183,9 +185,9 @@ reject:
 
 /**
  * fc_disc_recv_req() - Handle incoming requests
- * @sp: Current sequence of the request exchange
- * @fp: The frame
- * @lport: The FC local port
+ * @sp:	   The sequence of the request exchange
+ * @fp:	   The request frame
+ * @lport: The local port receiving the request
  *
  * Locking Note: This function is called from the EM and will lock
  *		 the disc_mutex before calling the handler for the
@@ -213,7 +215,7 @@ static void fc_disc_recv_req(struct fc_s
 
 /**
  * fc_disc_restart() - Restart discovery
- * @lport: FC discovery context
+ * @disc: The discovery object to be restarted
  *
  * Locking Note: This function expects that the disc mutex
  *		 is already locked.
@@ -240,9 +242,9 @@ static void fc_disc_restart(struct fc_di
 }
 
 /**
- * fc_disc_start() - Fibre Channel Target discovery
- * @lport: FC local port
- * @disc_callback: function to be called when discovery is complete
+ * fc_disc_start() - Start discovery on a local port
+ * @lport:	   The local port to have discovery started on
+ * @disc_callback: Callback function to be called when discovery is complete
  */
 static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
 						enum fc_disc_event),
@@ -263,8 +265,8 @@ static void fc_disc_start(void (*disc_ca
 
 /**
  * fc_disc_done() - Discovery has been completed
- * @disc: FC discovery context
- * @event: discovery completion status
+ * @disc:  The discovery context
+ * @event: The discovery completion status
  *
  * Locking Note: This function expects that the disc mutex is locked before
  * it is called. The discovery callback is then made with the lock released,
@@ -284,8 +286,8 @@ static void fc_disc_done(struct fc_disc
 	}
 
 	/*
-	 * Go through all remote ports.  If they were found in the latest
-	 * discovery, reverify or log them in.  Otherwise, log them out.
+	 * Go through all remote ports.	 If they were found in the latest
+	 * discovery, reverify or log them in.	Otherwise, log them out.
 	 * Skip ports which were never discovered.  These are the dNS port
 	 * and ports which were created by PLOGI.
 	 */
@@ -305,8 +307,8 @@ static void fc_disc_done(struct fc_disc
 
 /**
  * fc_disc_error() - Handle error on dNS request
- * @disc: FC discovery context
- * @fp: The frame pointer
+ * @disc: The discovery context
+ * @fp:	  The error code encoded as a frame pointer
  */
 static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
 {
@@ -342,7 +344,7 @@ static void fc_disc_error(struct fc_disc
 
 /**
  * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request
- * @lport: FC discovery context
+ * @lport: The discovery context
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -368,17 +370,17 @@ static void fc_disc_gpn_ft_req(struct fc
 	if (lport->tt.elsct_send(lport, 0, fp,
 				 FC_NS_GPN_FT,
 				 fc_disc_gpn_ft_resp,
-				 disc, lport->e_d_tov))
+				 disc, 3 * lport->r_a_tov))
 		return;
 err:
-	fc_disc_error(disc, fp);
+	fc_disc_error(disc, NULL);
 }
 
 /**
  * fc_disc_gpn_ft_parse() - Parse the body of the dNS GPN_FT response.
- * @lport: Fibre Channel host port instance
- * @buf: GPN_FT response buffer
- * @len: size of response buffer
+ * @lport: The local port the GPN_FT was received on
+ * @buf:   The GPN_FT response buffer
+ * @len:   The size of response buffer
  *
  * Goes through the list of IDs and names resulting from a request.
  */
@@ -477,10 +479,8 @@ static int fc_disc_gpn_ft_parse(struct f
 }
 
 /**
- * fc_disc_timeout() - Retry handler for the disc component
- * @work: Structure holding disc obj that needs retry discovery
- *
- * Handle retry of memory allocation for remote ports.
+ * fc_disc_timeout() - Handler for discovery timeouts
+ * @work: Structure holding discovery context that needs to retry discovery
  */
 static void fc_disc_timeout(struct work_struct *work)
 {
@@ -494,9 +494,9 @@ static void fc_disc_timeout(struct work_
 
 /**
  * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT)
- * @sp: Current sequence of GPN_FT exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel host port instance
+ * @sp:	    The sequence that the GPN_FT response was received on
+ * @fp:	    The GPN_FT response frame
+ * @lp_arg: The discovery context
  *
  * Locking Note: This function is called without disc mutex held, and
  *		 should do all its processing with the mutex held
@@ -567,9 +567,9 @@ static void fc_disc_gpn_ft_resp(struct f
 
 /**
  * fc_disc_gpn_id_resp() - Handle a response frame from Get Port Names (GPN_ID)
- * @sp: exchange sequence
- * @fp: response frame
- * @rdata_arg: remote port private data
+ * @sp:	       The sequence the GPN_ID is on
+ * @fp:	       The response frame
+ * @rdata_arg: The remote port that sent the GPN_ID response
  *
  * Locking Note: This function is called without disc mutex held.
  */
@@ -637,7 +637,7 @@ out:
 
 /**
  * fc_disc_gpn_id_req() - Send Get Port Names by ID (GPN_ID) request
- * @lport: local port
+ * @lport: The local port to initiate discovery on
  * @rdata: remote port private data
  *
  * Locking Note: This function expects that the disc_mutex is locked
@@ -654,7 +654,8 @@ static int fc_disc_gpn_id_req(struct fc_
 	if (!fp)
 		return -ENOMEM;
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, FC_NS_GPN_ID,
-				 fc_disc_gpn_id_resp, rdata, lport->e_d_tov))
+				  fc_disc_gpn_id_resp, rdata,
+				  3 * lport->r_a_tov))
 		return -ENOMEM;
 	kref_get(&rdata->kref);
 	return 0;
@@ -662,8 +663,8 @@ static int fc_disc_gpn_id_req(struct fc_
 
 /**
  * fc_disc_single() - Discover the directory information for a single target
- * @lport: local port
- * @dp: The port to rediscover
+ * @lport: The local port the remote port is associated with
+ * @dp:	   The port to rediscover
  *
  * Locking Note: This function expects that the disc_mutex is locked
  *		 before it is called.
@@ -681,7 +682,7 @@ static int fc_disc_single(struct fc_lpor
 
 /**
  * fc_disc_stop() - Stop discovery for a given lport
- * @lport: The lport that discovery should stop for
+ * @lport: The local port that discovery should stop on
  */
 void fc_disc_stop(struct fc_lport *lport)
 {
@@ -695,7 +696,7 @@ void fc_disc_stop(struct fc_lport *lport
 
 /**
  * fc_disc_stop_final() - Stop discovery for a given lport
- * @lport: The lport that discovery should stop for
+ * @lport: The lport that discovery should stop on
  *
  * This function will block until discovery has been
  * completely stopped and all rports have been deleted.
@@ -707,8 +708,8 @@ void fc_disc_stop_final(struct fc_lport
 }
 
 /**
- * fc_disc_init() - Initialize the discovery block
- * @lport: FC local port
+ * fc_disc_init() - Initialize the discovery layer for a local port
+ * @lport: The local port that needs the discovery layer to be initialized
  */
 int fc_disc_init(struct fc_lport *lport)
 {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_elsct.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_elsct.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_elsct.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_elsct.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,17 +28,22 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
-/*
- * fc_elsct_send - sends ELS/CT frame
+/**
+ * fc_elsct_send() - Send an ELS or CT frame
+ * @lport:	The local port to send the frame on
+ * @did:	The destination ID for the frame
+ * @fp:		The frame to be sent
+ * @op:		The operational code
+ * @resp:	The callback routine when the response is received
+ * @arg:	The argument to pass to the response callback routine
+ * @timer_msec: The timeout period for the frame (in msecs)
  */
-static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
-				    u32 did,
-				    struct fc_frame *fp,
-				    unsigned int op,
-				    void (*resp)(struct fc_seq *,
-						 struct fc_frame *fp,
-						 void *arg),
-				    void *arg, u32 timer_msec)
+struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
+			     struct fc_frame *fp, unsigned int op,
+			     void (*resp)(struct fc_seq *,
+					  struct fc_frame *,
+					  void *),
+			     void *arg, u32 timer_msec)
 {
 	enum fc_rctl r_ctl;
 	enum fc_fh_type fh_type;
@@ -53,15 +58,22 @@ static struct fc_seq *fc_elsct_send(stru
 		did = FC_FID_DIR_SERV;
 	}
 
-	if (rc)
+	if (rc) {
+		fc_frame_free(fp);
 		return NULL;
+	}
 
 	fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
 	return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
 }
+EXPORT_SYMBOL(fc_elsct_send);
 
+/**
+ * fc_elsct_init() - Initialize the ELS/CT layer
+ * @lport: The local port to initialize the ELS/CT layer for
+ */
 int fc_elsct_init(struct fc_lport *lport)
 {
 	if (!lport->tt.elsct_send)
@@ -72,12 +84,15 @@ int fc_elsct_init(struct fc_lport *lport
 EXPORT_SYMBOL(fc_elsct_init);
 
 /**
- * fc_els_resp_type() - return string describing ELS response for debug.
- * @fp: frame pointer with possible error code.
+ * fc_els_resp_type() - Return a string describing the ELS response
+ * @fp: The frame pointer or possible error code
  */
 const char *fc_els_resp_type(struct fc_frame *fp)
 {
 	const char *msg;
+	struct fc_frame_header *fh;
+	struct fc_ct_hdr *ct;
+
 	if (IS_ERR(fp)) {
 		switch (-PTR_ERR(fp)) {
 		case FC_NO_ERR:
@@ -94,15 +109,41 @@ const char *fc_els_resp_type(struct fc_f
 			break;
 		}
 	} else {
-		switch (fc_frame_payload_op(fp)) {
-		case ELS_LS_ACC:
-			msg = "accept";
+		fh = fc_frame_header_get(fp);
+		switch (fh->fh_type) {
+		case FC_TYPE_ELS:
+			switch (fc_frame_payload_op(fp)) {
+			case ELS_LS_ACC:
+				msg = "accept";
+				break;
+			case ELS_LS_RJT:
+				msg = "reject";
+				break;
+			default:
+				msg = "response unknown ELS";
+				break;
+			}
 			break;
-		case ELS_LS_RJT:
-			msg = "reject";
+		case FC_TYPE_CT:
+			ct = fc_frame_payload_get(fp, sizeof(*ct));
+			if (ct) {
+				switch (ntohs(ct->ct_cmd)) {
+				case FC_FS_ACC:
+					msg = "CT accept";
+					break;
+				case FC_FS_RJT:
+					msg = "CT reject";
+					break;
+				default:
+					msg = "response unknown CT";
+					break;
+				}
+			} else {
+				msg = "short CT response";
+			}
 			break;
 		default:
-			msg = "response unknown ELS";
+			msg = "response not ELS or CT";
 			break;
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_exch.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_exch.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_exch.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_exch.c	2010-02-24 13:52:17.000000000 -0500
@@ -32,10 +32,13 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
+#include "fc_libfc.h"
+
 u16	fc_cpu_mask;		/* cpu mask for possible cpus */
 EXPORT_SYMBOL(fc_cpu_mask);
 static u16	fc_cpu_order;	/* 2's power to represent total possible cpus */
-static struct kmem_cache *fc_em_cachep;        /* cache for exchanges */
+static struct kmem_cache *fc_em_cachep;	       /* cache for exchanges */
+struct workqueue_struct *fc_exch_workqueue;
 
 /*
  * Structure and function definitions for managing Fibre Channel Exchanges
@@ -50,35 +53,46 @@ static struct kmem_cache *fc_em_cachep;
  * fc_seq holds the state for an individual sequence.
  */
 
-/*
- * Per cpu exchange pool
+/**
+ * struct fc_exch_pool - Per cpu exchange pool
+ * @next_index:	  Next possible free exchange index
+ * @total_exches: Total allocated exchanges
+ * @lock:	  Exch pool lock
+ * @ex_list:	  List of exchanges
  *
  * This structure manages per cpu exchanges in array of exchange pointers.
  * This array is allocated followed by struct fc_exch_pool memory for
  * assigned range of exchanges to per cpu pool.
  */
 struct fc_exch_pool {
-	u16		next_index;	/* next possible free exchange index */
-	u16		total_exches;	/* total allocated exchanges */
-	spinlock_t	lock;		/* exch pool lock */
-	struct list_head	ex_list;	/* allocated exchanges list */
+	u16		 next_index;
+	u16		 total_exches;
+	spinlock_t	 lock;
+	struct list_head ex_list;
 };
 
-/*
- * Exchange manager.
+/**
+ * struct fc_exch_mgr - The Exchange Manager (EM).
+ * @class:	    Default class for new sequences
+ * @kref:	    Reference counter
+ * @min_xid:	    Minimum exchange ID
+ * @max_xid:	    Maximum exchange ID
+ * @ep_pool:	    Reserved exchange pointers
+ * @pool_max_index: Max exch array index in exch pool
+ * @pool:	    Per cpu exch pool
+ * @stats:	    Statistics structure
  *
  * This structure is the center for creating exchanges and sequences.
  * It manages the allocation of exchange IDs.
  */
 struct fc_exch_mgr {
-	enum fc_class	class;		/* default class for sequences */
-	struct kref	kref;		/* exchange mgr reference count */
-	u16		min_xid;	/* min exchange ID */
-	u16		max_xid;	/* max exchange ID */
-	struct list_head	ex_list;	/* allocated exchanges list */
-	mempool_t	*ep_pool;	/* reserve ep's */
-	u16		pool_max_index;	/* max exch array index in exch pool */
-	struct fc_exch_pool *pool;	/* per cpu exch pool */
+	enum fc_class	class;
+	struct kref	kref;
+	u16		min_xid;
+	u16		max_xid;
+	mempool_t	*ep_pool;
+	u16		pool_max_index;
+	struct fc_exch_pool *pool;
 
 	/*
 	 * currently exchange mgr stats are updated but not used.
@@ -96,6 +110,18 @@ struct fc_exch_mgr {
 };
 #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
 
+/**
+ * struct fc_exch_mgr_anchor - primary structure for list of EMs
+ * @ema_list: Exchange Manager Anchor list
+ * @mp:	      Exchange Manager associated with this anchor
+ * @match:    Routine to determine if this anchor's EM should be used
+ *
+ * When walking the list of anchors the match routine will be called
+ * for each anchor to determine if that EM should be used. The last
+ * anchor in the list will always match to handle any exchanges not
+ * handled by other EMs. The non-default EMs would be added to the
+ * anchor list by HW that provides FCoE offloads.
+ */
 struct fc_exch_mgr_anchor {
 	struct list_head ema_list;
 	struct fc_exch_mgr *mp;
@@ -108,7 +134,6 @@ static void fc_seq_ls_rjt(struct fc_seq
 			  enum fc_els_rjt_explan);
 static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *);
 static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *);
-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
 
 /*
  * Internal implementation notes.
@@ -196,6 +221,15 @@ static char *fc_exch_rctl_names[] = FC_R
 
 #define FC_TABLE_SIZE(x)   (sizeof(x) / sizeof(x[0]))
 
+/**
+ * fc_exch_name_lookup() - Lookup name by opcode
+ * @op:	       Opcode to be looked up
+ * @table:     Opcode/name table
+ * @max_index: Index not to be exceeded
+ *
+ * This routine is used to determine a human-readable string identifying
+ * a R_CTL opcode.
+ */
 static inline const char *fc_exch_name_lookup(unsigned int op, char **table,
 					      unsigned int max_index)
 {
@@ -208,25 +242,34 @@ static inline const char *fc_exch_name_l
 	return name;
 }
 
+/**
+ * fc_exch_rctl_name() - Wrapper routine for fc_exch_name_lookup()
+ * @op: The opcode to be looked up
+ */
 static const char *fc_exch_rctl_name(unsigned int op)
 {
 	return fc_exch_name_lookup(op, fc_exch_rctl_names,
 				   FC_TABLE_SIZE(fc_exch_rctl_names));
 }
 
-/*
- * Hold an exchange - keep it from being freed.
+/**
+ * fc_exch_hold() - Increment an exchange's reference count
+ * @ep: Echange to be held
  */
-static void fc_exch_hold(struct fc_exch *ep)
+static inline void fc_exch_hold(struct fc_exch *ep)
 {
 	atomic_inc(&ep->ex_refcnt);
 }
 
-/*
- * setup fc hdr by initializing few more FC header fields and sof/eof.
- * Initialized fields by this func:
- *	- fh_ox_id, fh_rx_id, fh_seq_id, fh_seq_cnt
- *	- sof and eof
+/**
+ * fc_exch_setup_hdr() - Initialize a FC header by initializing some fields
+ *			 and determine SOF and EOF.
+ * @ep:	   The exchange to that will use the header
+ * @fp:	   The frame whose header is to be modified
+ * @f_ctl: F_CTL bits that will be used for the frame header
+ *
+ * The fields initialized by this routine are: fh_ox_id, fh_rx_id,
+ * fh_seq_id, fh_seq_cnt and the SOF and EOF.
  */
 static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
 			      u32 f_ctl)
@@ -243,7 +286,7 @@ static void fc_exch_setup_hdr(struct fc_
 		if (fc_sof_needs_ack(ep->class))
 			fr_eof(fp) = FC_EOF_N;
 		/*
-		 * Form f_ctl.
+		 * From F_CTL.
 		 * The number of fill bytes to make the length a 4-byte
 		 * multiple is the low order 2-bits of the f_ctl.
 		 * The fill itself will have been cleared by the frame
@@ -273,10 +316,12 @@ static void fc_exch_setup_hdr(struct fc_
 	fh->fh_seq_cnt = htons(ep->seq.cnt);
 }
 
-
-/*
- * Release a reference to an exchange.
- * If the refcnt goes to zero and the exchange is complete, it is freed.
+/**
+ * fc_exch_release() - Decrement an exchange's reference count
+ * @ep: Exchange to be released
+ *
+ * If the reference count reaches zero and the exchange is complete,
+ * it is freed.
  */
 static void fc_exch_release(struct fc_exch *ep)
 {
@@ -291,6 +336,10 @@ static void fc_exch_release(struct fc_ex
 	}
 }
 
+/**
+ * fc_exch_done_locked() - Complete an exchange with the exchange lock held
+ * @ep: The exchange that is complete
+ */
 static int fc_exch_done_locked(struct fc_exch *ep)
 {
 	int rc = 1;
@@ -315,6 +364,15 @@ static int fc_exch_done_locked(struct fc
 	return rc;
 }
 
+/**
+ * fc_exch_ptr_get() - Return an exchange from an exchange pool
+ * @pool:  Exchange Pool to get an exchange from
+ * @index: Index of the exchange within the pool
+ *
+ * Use the index to get an exchange from within an exchange pool. exches
+ * will point to an array of exchange pointers. The index will select
+ * the exchange within the array.
+ */
 static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
 					      u16 index)
 {
@@ -322,12 +380,22 @@ static inline struct fc_exch *fc_exch_pt
 	return exches[index];
 }
 
+/**
+ * fc_exch_ptr_set() - Assign an exchange to a slot in an exchange pool
+ * @pool:  The pool to assign the exchange to
+ * @index: The index in the pool where the exchange will be assigned
+ * @ep:	   The exchange to assign to the pool
+ */
 static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
 				   struct fc_exch *ep)
 {
 	((struct fc_exch **)(pool + 1))[index] = ep;
 }
 
+/**
+ * fc_exch_delete() - Delete an exchange
+ * @ep: The exchange to be deleted
+ */
 static void fc_exch_delete(struct fc_exch *ep)
 {
 	struct fc_exch_pool *pool;
@@ -343,8 +411,14 @@ static void fc_exch_delete(struct fc_exc
 	fc_exch_release(ep);	/* drop hold for exch in mp */
 }
 
-/*
- * Internal version of fc_exch_timer_set - used with lock held.
+/**
+ * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the
+ *				the exchange lock held
+ * @ep:		The exchange whose timer will start
+ * @timer_msec: The timeout period
+ *
+ * Used for upper level protocols to time out the exchange.
+ * The timer is cancelled when it fires or when the exchange completes.
  */
 static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
 					    unsigned int timer_msec)
@@ -354,17 +428,15 @@ static inline void fc_exch_timer_set_loc
 
 	FC_EXCH_DBG(ep, "Exchange timer armed\n");
 
-	if (schedule_delayed_work(&ep->timeout_work,
-				  msecs_to_jiffies(timer_msec)))
+	if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work,
+			       msecs_to_jiffies(timer_msec)))
 		fc_exch_hold(ep);		/* hold for timer */
 }
 
-/*
- * Set timer for an exchange.
- * The time is a minimum delay in milliseconds until the timer fires.
- * Used for upper level protocols to time out the exchange.
- * The timer is cancelled when it fires or when the exchange completes.
- * Returns non-zero if a timer couldn't be allocated.
+/**
+ * fc_exch_timer_set() - Lock the exchange and set the timer
+ * @ep:		The exchange whose timer will start
+ * @timer_msec: The timeout period
  */
 static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec)
 {
@@ -373,7 +445,115 @@ static void fc_exch_timer_set(struct fc_
 	spin_unlock_bh(&ep->ex_lock);
 }
 
-int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
+/**
+ * fc_seq_send() - Send a frame using existing sequence/exchange pair
+ * @lport: The local port that the exchange will be sent on
+ * @sp:	   The sequence to be sent
+ * @fp:	   The frame to be sent on the exchange
+ */
+static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
+		       struct fc_frame *fp)
+{
+	struct fc_exch *ep;
+	struct fc_frame_header *fh = fc_frame_header_get(fp);
+	int error;
+	u32 f_ctl;
+
+	ep = fc_seq_exch(sp);
+	WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
+
+	f_ctl = ntoh24(fh->fh_f_ctl);
+	fc_exch_setup_hdr(ep, fp, f_ctl);
+
+	/*
+	 * update sequence count if this frame is carrying
+	 * multiple FC frames when sequence offload is enabled
+	 * by LLD.
+	 */
+	if (fr_max_payload(fp))
+		sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
+					fr_max_payload(fp));
+	else
+		sp->cnt++;
+
+	/*
+	 * Send the frame.
+	 */
+	error = lport->tt.frame_send(lport, fp);
+
+	/*
+	 * Update the exchange and sequence flags,
+	 * assuming all frames for the sequence have been sent.
+	 * We can only be called to send once for each sequence.
+	 */
+	spin_lock_bh(&ep->ex_lock);
+	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
+	if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
+		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
+	spin_unlock_bh(&ep->ex_lock);
+	return error;
+}
+
+/**
+ * fc_seq_alloc() - Allocate a sequence for a given exchange
+ * @ep:	    The exchange to allocate a new sequence for
+ * @seq_id: The sequence ID to be used
+ *
+ * We don't support multiple originated sequences on the same exchange.
+ * By implication, any previously originated sequence on this exchange
+ * is complete, and we reallocate the same sequence.
+ */
+static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
+{
+	struct fc_seq *sp;
+
+	sp = &ep->seq;
+	sp->ssb_stat = 0;
+	sp->cnt = 0;
+	sp->id = seq_id;
+	return sp;
+}
+
+/**
+ * fc_seq_start_next_locked() - Allocate a new sequence on the same
+ *				exchange as the supplied sequence
+ * @sp: The sequence/exchange to get a new sequence for
+ */
+static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
+{
+	struct fc_exch *ep = fc_seq_exch(sp);
+
+	sp = fc_seq_alloc(ep, ep->seq_id++);
+	FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
+		    ep->f_ctl, sp->id);
+	return sp;
+}
+
+/**
+ * fc_seq_start_next() - Lock the exchange and get a new sequence
+ *			 for a given sequence/exchange pair
+ * @sp: The sequence/exchange to get a new exchange for
+ */
+static struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
+{
+	struct fc_exch *ep = fc_seq_exch(sp);
+
+	spin_lock_bh(&ep->ex_lock);
+	sp = fc_seq_start_next_locked(sp);
+	spin_unlock_bh(&ep->ex_lock);
+
+	return sp;
+}
+
+/**
+ * fc_seq_exch_abort() - Abort an exchange and sequence
+ * @req_sp:	The sequence to be aborted
+ * @timer_msec: The period of time to wait before aborting
+ *
+ * Generally called because of a timeout or an abort from the upper layer.
+ */
+static int fc_seq_exch_abort(const struct fc_seq *req_sp,
+			     unsigned int timer_msec)
 {
 	struct fc_seq *sp;
 	struct fc_exch *ep;
@@ -422,11 +602,10 @@ int fc_seq_exch_abort(const struct fc_se
 		error = -ENOBUFS;
 	return error;
 }
-EXPORT_SYMBOL(fc_seq_exch_abort);
 
-/*
- * Exchange timeout - handle exchange timer expiration.
- * The timer will have been cancelled before this is called.
+/**
+ * fc_exch_timeout() - Handle exchange timer expiration
+ * @work: The work_struct identifying the exchange that timed out
  */
 static void fc_exch_timeout(struct work_struct *work)
 {
@@ -474,28 +653,10 @@ done:
 	fc_exch_release(ep);
 }
 
-/*
- * Allocate a sequence.
- *
- * We don't support multiple originated sequences on the same exchange.
- * By implication, any previously originated sequence on this exchange
- * is complete, and we reallocate the same sequence.
- */
-static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
-{
-	struct fc_seq *sp;
-
-	sp = &ep->seq;
-	sp->ssb_stat = 0;
-	sp->cnt = 0;
-	sp->id = seq_id;
-	return sp;
-}
-
 /**
- * fc_exch_em_alloc() - allocate an exchange from a specified EM.
- * @lport:	ptr to the local port
- * @mp:		ptr to the exchange manager
+ * fc_exch_em_alloc() - Allocate an exchange from a specified EM.
+ * @lport: The local port that the exchange is for
+ * @mp:	   The exchange manager that will allocate the exchange
  *
  * Returns pointer to allocated fc_exch with exch lock held.
  */
@@ -563,16 +724,18 @@ err:
 }
 
 /**
- * fc_exch_alloc() - allocate an exchange.
- * @lport:	ptr to the local port
- * @fp:		ptr to the FC frame
+ * fc_exch_alloc() - Allocate an exchange from an EM on a
+ *		     local port's list of EMs.
+ * @lport: The local port that will own the exchange
+ * @fp:	   The FC frame that the exchange will be for
  *
- * This function walks the list of the exchange manager(EM)
- * anchors to select a EM for new exchange allocation. The
- * EM is selected having either a NULL match function pointer
- * or call to match function returning true.
+ * This function walks the list of exchange manager(EM)
+ * anchors to select an EM for a new exchange allocation. The
+ * EM is selected when a NULL match function pointer is encountered
+ * or when a call to a match function returns true.
  */
-struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp)
+static struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
+				     struct fc_frame *fp)
 {
 	struct fc_exch_mgr_anchor *ema;
 	struct fc_exch *ep;
@@ -586,10 +749,11 @@ struct fc_exch *fc_exch_alloc(struct fc_
 	}
 	return NULL;
 }
-EXPORT_SYMBOL(fc_exch_alloc);
 
-/*
- * Lookup and hold an exchange.
+/**
+ * fc_exch_find() - Lookup and hold an exchange
+ * @mp:	 The exchange manager to lookup the exchange from
+ * @xid: The XID of the exchange to look up
  */
 static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
 {
@@ -609,7 +773,13 @@ static struct fc_exch *fc_exch_find(stru
 	return ep;
 }
 
-void fc_exch_done(struct fc_seq *sp)
+
+/**
+ * fc_exch_done() - Indicate that an exchange/sequence tuple is complete and
+ *		    the memory allocated for the related objects may be freed.
+ * @sp: The sequence that has completed
+ */
+static void fc_exch_done(struct fc_seq *sp)
 {
 	struct fc_exch *ep = fc_seq_exch(sp);
 	int rc;
@@ -620,10 +790,13 @@ void fc_exch_done(struct fc_seq *sp)
 	if (!rc)
 		fc_exch_delete(ep);
 }
-EXPORT_SYMBOL(fc_exch_done);
 
-/*
- * Allocate a new exchange as responder.
+/**
+ * fc_exch_resp() - Allocate a new exchange for a response frame
+ * @lport: The local port that the exchange was for
+ * @mp:	   The exchange manager to allocate the exchange from
+ * @fp:	   The response frame
+ *
  * Sets the responder ID in the frame header.
  */
 static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
@@ -664,8 +837,13 @@ static struct fc_exch *fc_exch_resp(stru
 	return ep;
 }
 
-/*
- * Find a sequence for receive where the other end is originating the sequence.
+/**
+ * fc_seq_lookup_recip() - Find a sequence where the other end
+ *			   originated the sequence
+ * @lport: The local port that the frame was sent to
+ * @mp:	   The Exchange Manager to lookup the exchange from
+ * @fp:	   The frame associated with the sequence we're looking for
+ *
  * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
  * on the ep that should be released by the caller.
  */
@@ -771,10 +949,12 @@ rel:
 	return reject;
 }
 
-/*
- * Find the sequence for a frame being received.
- * We originated the sequence, so it should be found.
- * We may or may not have originated the exchange.
+/**
+ * fc_seq_lookup_orig() - Find a sequence where this end
+ *			  originated the sequence
+ * @mp:	   The Exchange Manager to lookup the exchange from
+ * @fp:	   The frame associated with the sequence we're looking for
+ *
  * Does not hold the sequence for the caller.
  */
 static struct fc_seq *fc_seq_lookup_orig(struct fc_exch_mgr *mp,
@@ -806,8 +986,12 @@ static struct fc_seq *fc_seq_lookup_orig
 	return sp;
 }
 
-/*
- * Set addresses for an exchange.
+/**
+ * fc_exch_set_addr() - Set the source and destination IDs for an exchange
+ * @ep:	     The exchange to set the addresses for
+ * @orig_id: The originator's ID
+ * @resp_id: The responder's ID
+ *
  * Note this must be done before the first sequence of the exchange is sent.
  */
 static void fc_exch_set_addr(struct fc_exch *ep,
@@ -823,76 +1007,15 @@ static void fc_exch_set_addr(struct fc_e
 	}
 }
 
-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
-{
-	struct fc_exch *ep = fc_seq_exch(sp);
-
-	sp = fc_seq_alloc(ep, ep->seq_id++);
-	FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n",
-		    ep->f_ctl, sp->id);
-	return sp;
-}
-/*
- * Allocate a new sequence on the same exchange as the supplied sequence.
- * This will never return NULL.
+/**
+ * fc_seq_els_rsp_send() - Send an ELS response using infomation from
+ *			   the existing sequence/exchange.
+ * @sp:	      The sequence/exchange to get information from
+ * @els_cmd:  The ELS command to be sent
+ * @els_data: The ELS data to be sent
  */
-struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
-{
-	struct fc_exch *ep = fc_seq_exch(sp);
-
-	spin_lock_bh(&ep->ex_lock);
-	sp = fc_seq_start_next_locked(sp);
-	spin_unlock_bh(&ep->ex_lock);
-
-	return sp;
-}
-EXPORT_SYMBOL(fc_seq_start_next);
-
-int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp)
-{
-	struct fc_exch *ep;
-	struct fc_frame_header *fh = fc_frame_header_get(fp);
-	int error;
-	u32	f_ctl;
-
-	ep = fc_seq_exch(sp);
-	WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
-
-	f_ctl = ntoh24(fh->fh_f_ctl);
-	fc_exch_setup_hdr(ep, fp, f_ctl);
-
-	/*
-	 * update sequence count if this frame is carrying
-	 * multiple FC frames when sequence offload is enabled
-	 * by LLD.
-	 */
-	if (fr_max_payload(fp))
-		sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
-					fr_max_payload(fp));
-	else
-		sp->cnt++;
-
-	/*
-	 * Send the frame.
-	 */
-	error = lp->tt.frame_send(lp, fp);
-
-	/*
-	 * Update the exchange and sequence flags,
-	 * assuming all frames for the sequence have been sent.
-	 * We can only be called to send once for each sequence.
-	 */
-	spin_lock_bh(&ep->ex_lock);
-	ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ;	/* not first seq */
-	if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
-		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
-	spin_unlock_bh(&ep->ex_lock);
-	return error;
-}
-EXPORT_SYMBOL(fc_seq_send);
-
-void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
-			 struct fc_seq_els_data *els_data)
+static void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
+				struct fc_seq_els_data *els_data)
 {
 	switch (els_cmd) {
 	case ELS_LS_RJT:
@@ -911,10 +1034,13 @@ void fc_seq_els_rsp_send(struct fc_seq *
 		FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd);
 	}
 }
-EXPORT_SYMBOL(fc_seq_els_rsp_send);
 
-/*
- * Send a sequence, which is also the last sequence in the exchange.
+/**
+ * fc_seq_send_last() - Send a sequence that is the last in the exchange
+ * @sp:	     The sequence that is to be sent
+ * @fp:	     The frame that will be sent on the sequence
+ * @rctl:    The R_CTL information to be sent
+ * @fh_type: The frame header type
  */
 static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
 			     enum fc_rctl rctl, enum fc_fh_type fh_type)
@@ -928,9 +1054,12 @@ static void fc_seq_send_last(struct fc_s
 	fc_seq_send(ep->lp, sp, fp);
 }
 
-/*
+/**
+ * fc_seq_send_ack() - Send an acknowledgement that we've received a frame
+ * @sp:	   The sequence to send the ACK on
+ * @rx_fp: The received frame that is being acknoledged
+ *
  * Send ACK_1 (or equiv.) indicating we received something.
- * The frame we're acking is supplied.
  */
 static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
 {
@@ -938,14 +1067,14 @@ static void fc_seq_send_ack(struct fc_se
 	struct fc_frame_header *rx_fh;
 	struct fc_frame_header *fh;
 	struct fc_exch *ep = fc_seq_exch(sp);
-	struct fc_lport *lp = ep->lp;
+	struct fc_lport *lport = ep->lp;
 	unsigned int f_ctl;
 
 	/*
 	 * Don't send ACKs for class 3.
 	 */
 	if (fc_sof_needs_ack(fr_sof(rx_fp))) {
-		fp = fc_frame_alloc(lp, 0);
+		fp = fc_frame_alloc(lport, 0);
 		if (!fp)
 			return;
 
@@ -980,12 +1109,16 @@ static void fc_seq_send_ack(struct fc_se
 		else
 			fr_eof(fp) = FC_EOF_N;
 
-		(void) lp->tt.frame_send(lp, fp);
+		lport->tt.frame_send(lport, fp);
 	}
 }
 
-/*
- * Send BLS Reject.
+/**
+ * fc_exch_send_ba_rjt() - Send BLS Reject
+ * @rx_fp:  The frame being rejected
+ * @reason: The reason the frame is being rejected
+ * @explan: The explaination for the rejection
+ *
  * This is for rejecting BA_ABTS only.
  */
 static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
@@ -996,11 +1129,11 @@ static void fc_exch_send_ba_rjt(struct f
 	struct fc_frame_header *rx_fh;
 	struct fc_frame_header *fh;
 	struct fc_ba_rjt *rp;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	unsigned int f_ctl;
 
-	lp = fr_dev(rx_fp);
-	fp = fc_frame_alloc(lp, sizeof(*rp));
+	lport = fr_dev(rx_fp);
+	fp = fc_frame_alloc(lport, sizeof(*rp));
 	if (!fp)
 		return;
 	fh = fc_frame_header_get(fp);
@@ -1045,13 +1178,17 @@ static void fc_exch_send_ba_rjt(struct f
 	if (fc_sof_needs_ack(fr_sof(fp)))
 		fr_eof(fp) = FC_EOF_N;
 
-	(void) lp->tt.frame_send(lp, fp);
+	lport->tt.frame_send(lport, fp);
 }
 
-/*
- * Handle an incoming ABTS.  This would be for target mode usually,
- * but could be due to lost FCP transfer ready, confirm or RRQ.
- * We always handle this as an exchange abort, ignoring the parameter.
+/**
+ * fc_exch_recv_abts() - Handle an incoming ABTS
+ * @ep:	   The exchange the abort was on
+ * @rx_fp: The ABTS frame
+ *
+ * This would be for target mode usually, but could be due to lost
+ * FCP transfer ready, confirm or RRQ. We always handle this as an
+ * exchange abort, ignoring the parameter.
  */
 static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp)
 {
@@ -1100,10 +1237,14 @@ free:
 	fc_frame_free(rx_fp);
 }
 
-/*
- * Handle receive where the other end is originating the sequence.
+/**
+ * fc_exch_recv_req() - Handler for an incoming request where is other
+ *			end is originating the sequence
+ * @lport: The local port that received the request
+ * @mp:	   The EM that the exchange is on
+ * @fp:	   The request frame
  */
-static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
+static void fc_exch_recv_req(struct fc_lport *lport, struct fc_exch_mgr *mp,
 			     struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
@@ -1114,8 +1255,17 @@ static void fc_exch_recv_req(struct fc_l
 	u32 f_ctl;
 	enum fc_pf_rjt_reason reject;
 
+	/* We can have the wrong fc_lport at this point with NPIV, which is a
+	 * problem now that we know a new exchange needs to be allocated
+	 */
+	lport = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
+	if (!lport) {
+		fc_frame_free(fp);
+		return;
+	}
+
 	fr_seq(fp) = NULL;
-	reject = fc_seq_lookup_recip(lp, mp, fp);
+	reject = fc_seq_lookup_recip(lport, mp, fp);
 	if (reject == FC_RJT_NONE) {
 		sp = fr_seq(fp);	/* sequence will be held */
 		ep = fc_seq_exch(sp);
@@ -1138,17 +1288,21 @@ static void fc_exch_recv_req(struct fc_l
 		if (ep->resp)
 			ep->resp(sp, fp, ep->arg);
 		else
-			lp->tt.lport_recv(lp, sp, fp);
+			lport->tt.lport_recv(lport, sp, fp);
 		fc_exch_release(ep);	/* release from lookup */
 	} else {
-		FC_LPORT_DBG(lp, "exch/seq lookup failed: reject %x\n", reject);
+		FC_LPORT_DBG(lport, "exch/seq lookup failed: reject %x\n",
+			     reject);
 		fc_frame_free(fp);
 	}
 }
 
-/*
- * Handle receive where the other end is originating the sequence in
- * response to our exchange.
+/**
+ * fc_exch_recv_seq_resp() - Handler for an incoming response where the other
+ *			     end is the originator of the sequence that is a
+ *			     response to our initial exchange
+ * @mp: The EM that the exchange is on
+ * @fp: The response frame
  */
 static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 {
@@ -1239,8 +1393,11 @@ out:
 	fc_frame_free(fp);
 }
 
-/*
- * Handle receive for a sequence where other end is responding to our sequence.
+/**
+ * fc_exch_recv_resp() - Handler for a sequence where other end is
+ *			 responding to our sequence
+ * @mp: The EM that the exchange is on
+ * @fp: The response frame
  */
 static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 {
@@ -1256,9 +1413,13 @@ static void fc_exch_recv_resp(struct fc_
 	fc_frame_free(fp);
 }
 
-/*
- * Handle the response to an ABTS for exchange or sequence.
- * This can be BA_ACC or BA_RJT.
+/**
+ * fc_exch_abts_resp() - Handler for a response to an ABT
+ * @ep: The exchange that the frame is on
+ * @fp: The response frame
+ *
+ * This response would be to an ABTS cancelling an exchange or sequence.
+ * The response can be either BA_ACC or BA_RJT
  */
 static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
 {
@@ -1333,9 +1494,12 @@ static void fc_exch_abts_resp(struct fc_
 
 }
 
-/*
- * Receive BLS sequence.
- * This is always a sequence initiated by the remote side.
+/**
+ * fc_exch_recv_bls() - Handler for a BLS sequence
+ * @mp: The EM that the exchange is on
+ * @fp: The request frame
+ *
+ * The BLS frame is always a sequence initiated by the remote side.
  * We may be either the originator or recipient of the exchange.
  */
 static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
@@ -1392,8 +1556,10 @@ static void fc_exch_recv_bls(struct fc_e
 		fc_exch_release(ep);	/* release hold taken by fc_exch_find */
 }
 
-/*
- * Accept sequence with LS_ACC.
+/**
+ * fc_seq_ls_acc() - Accept sequence with LS_ACC
+ * @req_sp: The request sequence
+ *
  * If this fails due to allocation or transmit congestion, assume the
  * originator will repeat the sequence.
  */
@@ -1413,8 +1579,12 @@ static void fc_seq_ls_acc(struct fc_seq
 	}
 }
 
-/*
- * Reject sequence with ELS LS_RJT.
+/**
+ * fc_seq_ls_rjt() - Reject a sequence with ELS LS_RJT
+ * @req_sp: The request sequence
+ * @reason: The reason the sequence is being rejected
+ * @explan: The explaination for the rejection
+ *
  * If this fails due to allocation or transmit congestion, assume the
  * originator will repeat the sequence.
  */
@@ -1437,6 +1607,10 @@ static void fc_seq_ls_rjt(struct fc_seq
 	}
 }
 
+/**
+ * fc_exch_reset() - Reset an exchange
+ * @ep: The exchange to be reset
+ */
 static void fc_exch_reset(struct fc_exch *ep)
 {
 	struct fc_seq *sp;
@@ -1446,12 +1620,6 @@ static void fc_exch_reset(struct fc_exch
 
 	spin_lock_bh(&ep->ex_lock);
 	ep->state |= FC_EX_RST_CLEANUP;
-	/*
-	 * we really want to call del_timer_sync, but cannot due
-	 * to the lport calling with the lport lock held (some resp
-	 * functions can also grab the lport lock which could cause
-	 * a deadlock).
-	 */
 	if (cancel_delayed_work(&ep->timeout_work))
 		atomic_dec(&ep->ex_refcnt);	/* drop hold for timer */
 	resp = ep->resp;
@@ -1471,16 +1639,16 @@ static void fc_exch_reset(struct fc_exch
 }
 
 /**
- * fc_exch_pool_reset() - Resets an per cpu exches pool.
- * @lport:	ptr to the local port
- * @pool:	ptr to the per cpu exches pool
- * @sid:	source FC ID
- * @did:	destination FC ID
+ * fc_exch_pool_reset() - Reset a per cpu exchange pool
+ * @lport: The local port that the exchange pool is on
+ * @pool:  The exchange pool to be reset
+ * @sid:   The source ID
+ * @did:   The destination ID
  *
- * Resets an per cpu exches pool, releasing its all sequences
- * and exchanges. If sid is non-zero, then reset only exchanges
- * we sourced from that FID. If did is non-zero, reset only
- * exchanges destined to that FID.
+ * Resets a per cpu exches pool, releasing all of its sequences
+ * and exchanges. If sid is non-zero then reset only exchanges
+ * we sourced from the local port's FID. If did is non-zero then
+ * only reset exchanges destined for the local port's FID.
  */
 static void fc_exch_pool_reset(struct fc_lport *lport,
 			       struct fc_exch_pool *pool,
@@ -1514,15 +1682,15 @@ restart:
 }
 
 /**
- * fc_exch_mgr_reset() - Resets all EMs of a lport
- * @lport:	ptr to the local port
- * @sid:	source FC ID
- * @did:	destination FC ID
+ * fc_exch_mgr_reset() - Reset all EMs of a local port
+ * @lport: The local port whose EMs are to be reset
+ * @sid:   The source ID
+ * @did:   The destination ID
  *
- * Reset all EMs of a lport, releasing its all sequences and
- * exchanges. If sid is non-zero, then reset only exchanges
- * we sourced from that FID. If did is non-zero, reset only
- * exchanges destined to that FID.
+ * Reset all EMs associated with a given local port. Release all
+ * sequences and exchanges. If sid is non-zero then reset only the
+ * exchanges sent from the local port's FID. If did is non-zero then
+ * reset only exchanges destined for the local port's FID.
  */
 void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
 {
@@ -1538,8 +1706,11 @@ void fc_exch_mgr_reset(struct fc_lport *
 }
 EXPORT_SYMBOL(fc_exch_mgr_reset);
 
-/*
- * Handle incoming ELS REC - Read Exchange Concise.
+/**
+ * fc_exch_els_rec() - Handler for ELS REC (Read Exchange Concise) requests
+ * @sp:	 The sequence the REC is on
+ * @rfp: The REC frame
+ *
  * Note that the requesting port may be different than the S_ID in the request.
  */
 static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp)
@@ -1621,10 +1792,11 @@ reject:
 	fc_frame_free(rfp);
 }
 
-/*
- * Handle response from RRQ.
- * Not much to do here, really.
- * Should report errors.
+/**
+ * fc_exch_rrq_resp() - Handler for RRQ responses
+ * @sp:	 The sequence that the RRQ is on
+ * @fp:	 The RRQ frame
+ * @arg: The exchange that the RRQ is on
  *
  * TODO: fix error handler.
  */
@@ -1664,21 +1836,99 @@ cleanup:
 	fc_exch_release(aborted_ep);
 }
 
-/*
- * Send ELS RRQ - Reinstate Recovery Qualifier.
+
+/**
+ * fc_exch_seq_send() - Send a frame using a new exchange and sequence
+ * @lport:	The local port to send the frame on
+ * @fp:		The frame to be sent
+ * @resp:	The response handler for this request
+ * @destructor: The destructor for the exchange
+ * @arg:	The argument to be passed to the response handler
+ * @timer_msec: The timeout period for the exchange
+ *
+ * The frame pointer with some of the header's fields must be
+ * filled before calling this routine, those fields are:
+ *
+ * - routing control
+ * - FC port did
+ * - FC port sid
+ * - FC header type
+ * - frame control
+ * - parameter or relative offset
+ */
+static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
+				       struct fc_frame *fp,
+				       void (*resp)(struct fc_seq *,
+						    struct fc_frame *fp,
+						    void *arg),
+				       void (*destructor)(struct fc_seq *,
+							  void *),
+				       void *arg, u32 timer_msec)
+{
+	struct fc_exch *ep;
+	struct fc_seq *sp = NULL;
+	struct fc_frame_header *fh;
+	int rc = 1;
+
+	ep = fc_exch_alloc(lport, fp);
+	if (!ep) {
+		fc_frame_free(fp);
+		return NULL;
+	}
+	ep->esb_stat |= ESB_ST_SEQ_INIT;
+	fh = fc_frame_header_get(fp);
+	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
+	ep->resp = resp;
+	ep->destructor = destructor;
+	ep->arg = arg;
+	ep->r_a_tov = FC_DEF_R_A_TOV;
+	ep->lp = lport;
+	sp = &ep->seq;
+
+	ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
+	ep->f_ctl = ntoh24(fh->fh_f_ctl);
+	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
+	sp->cnt++;
+
+	if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD)
+		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
+
+	if (unlikely(lport->tt.frame_send(lport, fp)))
+		goto err;
+
+	if (timer_msec)
+		fc_exch_timer_set_locked(ep, timer_msec);
+	ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not first seq */
+
+	if (ep->f_ctl & FC_FC_SEQ_INIT)
+		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
+	spin_unlock_bh(&ep->ex_lock);
+	return sp;
+err:
+	rc = fc_exch_done_locked(ep);
+	spin_unlock_bh(&ep->ex_lock);
+	if (!rc)
+		fc_exch_delete(ep);
+	return NULL;
+}
+
+/**
+ * fc_exch_rrq() - Send an ELS RRQ (Reinstate Recovery Qualifier) command
+ * @ep: The exchange to send the RRQ on
+ *
  * This tells the remote port to stop blocking the use of
  * the exchange and the seq_cnt range.
  */
 static void fc_exch_rrq(struct fc_exch *ep)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_els_rrq *rrq;
 	struct fc_frame *fp;
 	u32 did;
 
-	lp = ep->lp;
+	lport = ep->lp;
 
-	fp = fc_frame_alloc(lp, sizeof(*rrq));
+	fp = fc_frame_alloc(lport, sizeof(*rrq));
 	if (!fp)
 		goto retry;
 
@@ -1694,10 +1944,11 @@ static void fc_exch_rrq(struct fc_exch *
 		did = ep->sid;
 
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
-		       fc_host_port_id(lp->host), FC_TYPE_ELS,
+		       fc_host_port_id(lport->host), FC_TYPE_ELS,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	if (fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, lp->e_d_tov))
+	if (fc_exch_seq_send(lport, fp, fc_exch_rrq_resp, NULL, ep,
+			     lport->e_d_tov))
 		return;
 
 retry:
@@ -1714,12 +1965,14 @@ retry:
 }
 
 
-/*
- * Handle incoming ELS RRQ - Reset Recovery Qualifier.
+/**
+ * fc_exch_els_rrq() - Handler for ELS RRQ (Reset Recovery Qualifier) requests
+ * @sp: The sequence that the RRQ is on
+ * @fp: The RRQ frame
  */
 static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
 {
-	struct fc_exch *ep;		/* request or subject exchange */
+	struct fc_exch *ep = NULL;	/* request or subject exchange */
 	struct fc_els_rrq *rp;
 	u32 sid;
 	u16 xid;
@@ -1769,17 +2022,24 @@ static void fc_exch_els_rrq(struct fc_se
 	 * Send LS_ACC.
 	 */
 	fc_seq_ls_acc(sp);
-	fc_frame_free(fp);
-	return;
+	goto out;
 
 unlock_reject:
 	spin_unlock_bh(&ep->ex_lock);
-	fc_exch_release(ep);	/* drop hold from fc_exch_find */
 reject:
 	fc_seq_ls_rjt(sp, ELS_RJT_LOGIC, explan);
+out:
 	fc_frame_free(fp);
+	if (ep)
+		fc_exch_release(ep);	/* drop hold from fc_exch_find */
 }
 
+/**
+ * fc_exch_mgr_add() - Add an exchange manager to a local port's list of EMs
+ * @lport: The local port to add the exchange manager to
+ * @mp:	   The exchange manager to be added to the local port
+ * @match: The match routine that indicates when this EM should be used
+ */
 struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
 					   struct fc_exch_mgr *mp,
 					   bool (*match)(struct fc_frame *))
@@ -1799,6 +2059,10 @@ struct fc_exch_mgr_anchor *fc_exch_mgr_a
 }
 EXPORT_SYMBOL(fc_exch_mgr_add);
 
+/**
+ * fc_exch_mgr_destroy() - Destroy an exchange manager
+ * @kref: The reference to the EM to be destroyed
+ */
 static void fc_exch_mgr_destroy(struct kref *kref)
 {
 	struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
@@ -1808,6 +2072,10 @@ static void fc_exch_mgr_destroy(struct k
 	kfree(mp);
 }
 
+/**
+ * fc_exch_mgr_del() - Delete an EM from a local port's list
+ * @ema: The exchange manager anchor identifying the EM to be deleted
+ */
 void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
 {
 	/* remove EM anchor from EM anchors list */
@@ -1817,7 +2085,35 @@ void fc_exch_mgr_del(struct fc_exch_mgr_
 }
 EXPORT_SYMBOL(fc_exch_mgr_del);
 
-struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
+/**
+ * fc_exch_mgr_list_clone() - Share all exchange manager objects
+ * @src: Source lport to clone exchange managers from
+ * @dst: New lport that takes references to all the exchange managers
+ */
+int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst)
+{
+	struct fc_exch_mgr_anchor *ema, *tmp;
+
+	list_for_each_entry(ema, &src->ema_list, ema_list) {
+		if (!fc_exch_mgr_add(dst, ema->mp, ema->match))
+			goto err;
+	}
+	return 0;
+err:
+	list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list)
+		fc_exch_mgr_del(ema);
+	return -ENOMEM;
+}
+
+/**
+ * fc_exch_mgr_alloc() - Allocate an exchange manager
+ * @lport:   The local port that the new EM will be associated with
+ * @class:   The default FC class for new exchanges
+ * @min_xid: The minimum XID for exchanges from the new EM
+ * @max_xid: The maximum XID for exchanges from the new EM
+ * @match:   The match routine for the new EM
+ */
+struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
 				      enum fc_class class,
 				      u16 min_xid, u16 max_xid,
 				      bool (*match)(struct fc_frame *))
@@ -1830,7 +2126,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(st
 
 	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
 	    (min_xid & fc_cpu_mask) != 0) {
-		FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
+		FC_LPORT_DBG(lport, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
 			     min_xid, max_xid);
 		return NULL;
 	}
@@ -1873,7 +2169,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(st
 	}
 
 	kref_init(&mp->kref);
-	if (!fc_exch_mgr_add(lp, mp, match)) {
+	if (!fc_exch_mgr_add(lport, mp, match)) {
 		free_percpu(mp->pool);
 		goto free_mempool;
 	}
@@ -1894,76 +2190,26 @@ free_mp:
 }
 EXPORT_SYMBOL(fc_exch_mgr_alloc);
 
+/**
+ * fc_exch_mgr_free() - Free all exchange managers on a local port
+ * @lport: The local port whose EMs are to be freed
+ */
 void fc_exch_mgr_free(struct fc_lport *lport)
 {
 	struct fc_exch_mgr_anchor *ema, *next;
 
+	flush_workqueue(fc_exch_workqueue);
 	list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
 		fc_exch_mgr_del(ema);
 }
 EXPORT_SYMBOL(fc_exch_mgr_free);
 
-
-struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
-				struct fc_frame *fp,
-				void (*resp)(struct fc_seq *,
-					     struct fc_frame *fp,
-					     void *arg),
-				void (*destructor)(struct fc_seq *, void *),
-				void *arg, u32 timer_msec)
-{
-	struct fc_exch *ep;
-	struct fc_seq *sp = NULL;
-	struct fc_frame_header *fh;
-	int rc = 1;
-
-	ep = fc_exch_alloc(lp, fp);
-	if (!ep) {
-		fc_frame_free(fp);
-		return NULL;
-	}
-	ep->esb_stat |= ESB_ST_SEQ_INIT;
-	fh = fc_frame_header_get(fp);
-	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
-	ep->resp = resp;
-	ep->destructor = destructor;
-	ep->arg = arg;
-	ep->r_a_tov = FC_DEF_R_A_TOV;
-	ep->lp = lp;
-	sp = &ep->seq;
-
-	ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
-	ep->f_ctl = ntoh24(fh->fh_f_ctl);
-	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
-	sp->cnt++;
-
-	if (ep->xid <= lp->lro_xid)
-		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
-
-	if (unlikely(lp->tt.frame_send(lp, fp)))
-		goto err;
-
-	if (timer_msec)
-		fc_exch_timer_set_locked(ep, timer_msec);
-	ep->f_ctl &= ~FC_FC_FIRST_SEQ;	/* not first seq */
-
-	if (ep->f_ctl & FC_FC_SEQ_INIT)
-		ep->esb_stat &= ~ESB_ST_SEQ_INIT;
-	spin_unlock_bh(&ep->ex_lock);
-	return sp;
-err:
-	rc = fc_exch_done_locked(ep);
-	spin_unlock_bh(&ep->ex_lock);
-	if (!rc)
-		fc_exch_delete(ep);
-	return NULL;
-}
-EXPORT_SYMBOL(fc_exch_seq_send);
-
-/*
- * Receive a frame
+/**
+ * fc_exch_recv() - Handler for received frames
+ * @lport: The local port the frame was received on
+ * @fp:	   The received frame
  */
-void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp)
+void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
 	struct fc_exch_mgr_anchor *ema;
@@ -1971,8 +2217,8 @@ void fc_exch_recv(struct fc_lport *lp, s
 	u16 oxid;
 
 	/* lport lock ? */
-	if (!lp || lp->state == LPORT_ST_DISABLED) {
-		FC_LPORT_DBG(lp, "Receiving frames for an lport that "
+	if (!lport || lport->state == LPORT_ST_DISABLED) {
+		FC_LPORT_DBG(lport, "Receiving frames for an lport that "
 			     "has not been initialized correctly\n");
 		fc_frame_free(fp);
 		return;
@@ -1981,7 +2227,7 @@ void fc_exch_recv(struct fc_lport *lp, s
 	f_ctl = ntoh24(fh->fh_f_ctl);
 	oxid = ntohs(fh->fh_ox_id);
 	if (f_ctl & FC_FC_EX_CTX) {
-		list_for_each_entry(ema, &lp->ema_list, ema_list) {
+		list_for_each_entry(ema, &lport->ema_list, ema_list) {
 			if ((oxid >= ema->mp->min_xid) &&
 			    (oxid <= ema->mp->max_xid)) {
 				found = 1;
@@ -1990,13 +2236,13 @@ void fc_exch_recv(struct fc_lport *lp, s
 		}
 
 		if (!found) {
-			FC_LPORT_DBG(lp, "Received response for out "
+			FC_LPORT_DBG(lport, "Received response for out "
 				     "of range oxid:%hx\n", oxid);
 			fc_frame_free(fp);
 			return;
 		}
 	} else
-		ema = list_entry(lp->ema_list.prev, typeof(*ema), ema_list);
+		ema = list_entry(lport->ema_list.prev, typeof(*ema), ema_list);
 
 	/*
 	 * If frame is marked invalid, just drop it.
@@ -2015,37 +2261,56 @@ void fc_exch_recv(struct fc_lport *lp, s
 		else if (f_ctl & FC_FC_SEQ_CTX)
 			fc_exch_recv_resp(ema->mp, fp);
 		else
-			fc_exch_recv_req(lp, ema->mp, fp);
+			fc_exch_recv_req(lport, ema->mp, fp);
 		break;
 	default:
-		FC_LPORT_DBG(lp, "dropping invalid frame (eof %x)", fr_eof(fp));
+		FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)",
+			     fr_eof(fp));
 		fc_frame_free(fp);
 	}
 }
 EXPORT_SYMBOL(fc_exch_recv);
 
-int fc_exch_init(struct fc_lport *lp)
+/**
+ * fc_exch_init() - Initialize the exchange layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
+int fc_exch_init(struct fc_lport *lport)
 {
-	if (!lp->tt.seq_start_next)
-		lp->tt.seq_start_next = fc_seq_start_next;
+	if (!lport->tt.seq_start_next)
+		lport->tt.seq_start_next = fc_seq_start_next;
 
-	if (!lp->tt.exch_seq_send)
-		lp->tt.exch_seq_send = fc_exch_seq_send;
+	if (!lport->tt.exch_seq_send)
+		lport->tt.exch_seq_send = fc_exch_seq_send;
 
-	if (!lp->tt.seq_send)
-		lp->tt.seq_send = fc_seq_send;
+	if (!lport->tt.seq_send)
+		lport->tt.seq_send = fc_seq_send;
 
-	if (!lp->tt.seq_els_rsp_send)
-		lp->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
+	if (!lport->tt.seq_els_rsp_send)
+		lport->tt.seq_els_rsp_send = fc_seq_els_rsp_send;
 
-	if (!lp->tt.exch_done)
-		lp->tt.exch_done = fc_exch_done;
+	if (!lport->tt.exch_done)
+		lport->tt.exch_done = fc_exch_done;
 
-	if (!lp->tt.exch_mgr_reset)
-		lp->tt.exch_mgr_reset = fc_exch_mgr_reset;
+	if (!lport->tt.exch_mgr_reset)
+		lport->tt.exch_mgr_reset = fc_exch_mgr_reset;
 
-	if (!lp->tt.seq_exch_abort)
-		lp->tt.seq_exch_abort = fc_seq_exch_abort;
+	if (!lport->tt.seq_exch_abort)
+		lport->tt.seq_exch_abort = fc_seq_exch_abort;
+
+	return 0;
+}
+EXPORT_SYMBOL(fc_exch_init);
+
+/**
+ * fc_setup_exch_mgr() - Setup an exchange manager
+ */
+int fc_setup_exch_mgr()
+{
+	fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
+					 0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!fc_em_cachep)
+		return -ENOMEM;
 
 	/*
 	 * Initialize fc_cpu_mask and fc_cpu_order. The
@@ -2069,20 +2334,17 @@ int fc_exch_init(struct fc_lport *lp)
 	}
 	fc_cpu_mask--;
 
-	return 0;
-}
-EXPORT_SYMBOL(fc_exch_init);
-
-int fc_setup_exch_mgr(void)
-{
-	fc_em_cachep = kmem_cache_create("libfc_em", sizeof(struct fc_exch),
-					 0, SLAB_HWCACHE_ALIGN, NULL);
-	if (!fc_em_cachep)
+	fc_exch_workqueue = create_singlethread_workqueue("fc_exch_workqueue");
+	if (!fc_exch_workqueue)
 		return -ENOMEM;
 	return 0;
 }
 
-void fc_destroy_exch_mgr(void)
+/**
+ * fc_destroy_exch_mgr() - Destroy an exchange manager
+ */
+void fc_destroy_exch_mgr()
 {
+	destroy_workqueue(fc_exch_workqueue);
 	kmem_cache_destroy(fc_em_cachep);
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_fcp.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_fcp.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_fcp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_fcp.c	2010-02-24 13:52:17.000000000 -0500
@@ -39,15 +39,9 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
-MODULE_AUTHOR("Open-FCoE.org");
-MODULE_DESCRIPTION("libfc");
-MODULE_LICENSE("GPL v2");
-
-unsigned int fc_debug_logging;
-module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
+#include "fc_libfc.h"
 
-static struct kmem_cache *scsi_pkt_cachep;
+struct kmem_cache *scsi_pkt_cachep;
 
 /* SRB state definitions */
 #define FC_SRB_FREE		0		/* cmd is free */
@@ -58,7 +52,6 @@ static struct kmem_cache *scsi_pkt_cache
 #define FC_SRB_DISCONTIG	(1 << 4)	/* non-sequential data recvd */
 #define FC_SRB_COMPL		(1 << 5)	/* fc_io_compl has been run */
 #define FC_SRB_FCP_PROCESSING_TMO (1 << 6)	/* timer function processing */
-#define FC_SRB_NOMEM		(1 << 7)	/* dropped to out of mem */
 
 #define FC_SRB_READ		(1 << 1)
 #define FC_SRB_WRITE		(1 << 0)
@@ -73,10 +66,22 @@ static struct kmem_cache *scsi_pkt_cache
 #define CMD_SCSI_STATUS(Cmnd)	    ((Cmnd)->SCp.Status)
 #define CMD_RESID_LEN(Cmnd)	    ((Cmnd)->SCp.buffers_residual)
 
+/**
+ * struct fc_fcp_internal - FCP layer internal data
+ * @scsi_pkt_pool: Memory pool to draw FCP packets from
+ * @scsi_queue_lock: Protects the scsi_pkt_queue
+ * @scsi_pkt_queue: Current FCP packets
+ * @last_can_queue_ramp_down_time: ramp down time
+ * @last_can_queue_ramp_up_time: ramp up time
+ * @max_can_queue: max can_queue size
+ */
 struct fc_fcp_internal {
-	mempool_t	*scsi_pkt_pool;
-	struct list_head scsi_pkt_queue;
-	u8		throttled;
+	mempool_t		*scsi_pkt_pool;
+	spinlock_t		scsi_queue_lock;
+	struct list_head	scsi_pkt_queue;
+	unsigned long		last_can_queue_ramp_down_time;
+	unsigned long		last_can_queue_ramp_up_time;
+	int			max_can_queue;
 };
 
 #define fc_get_scsi_internal(x)	((struct fc_fcp_internal *)(x)->scsi_priv)
@@ -90,9 +95,9 @@ static void fc_fcp_recv(struct fc_seq *,
 static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
 static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
-static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp);
+static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_timeout_error(struct fc_fcp_pkt *);
-static void fc_fcp_timeout(unsigned long data);
+static void fc_fcp_timeout(unsigned long);
 static void fc_fcp_rec(struct fc_fcp_pkt *);
 static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
 static void fc_fcp_rec_resp(struct fc_seq *, struct fc_frame *, void *);
@@ -124,6 +129,7 @@ static void fc_fcp_srr_error(struct fc_f
 #define FC_SCSI_TM_TOV		(10 * HZ)
 #define FC_SCSI_REC_TOV		(2 * HZ)
 #define FC_HOST_RESET_TIMEOUT	(30 * HZ)
+#define FC_CAN_QUEUE_PERIOD	(60 * HZ)
 
 #define FC_MAX_ERROR_CNT	5
 #define FC_MAX_RECOV_RETRY	3
@@ -131,23 +137,22 @@ static void fc_fcp_srr_error(struct fc_f
 #define FC_FCP_DFLT_QUEUE_DEPTH 32
 
 /**
- * fc_fcp_pkt_alloc - allocation routine for scsi_pkt packet
- * @lp:		fc lport struct
- * @gfp:	gfp flags for allocation
+ * fc_fcp_pkt_alloc() - Allocate a fcp_pkt
+ * @lport: The local port that the FCP packet is for
+ * @gfp:   GFP flags for allocation
  *
- * This is used by upper layer scsi driver.
- * Return Value : scsi_pkt structure or null on allocation failure.
- * Context	: call from process context. no locking required.
+ * Return value: fcp_pkt structure or null on allocation failure.
+ * Context:	 Can be called from process context, no lock is required.
  */
-static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp)
+static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lport, gfp_t gfp)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 	struct fc_fcp_pkt *fsp;
 
 	fsp = mempool_alloc(si->scsi_pkt_pool, gfp);
 	if (fsp) {
 		memset(fsp, 0, sizeof(*fsp));
-		fsp->lp = lp;
+		fsp->lp = lport;
 		atomic_set(&fsp->ref_cnt, 1);
 		init_timer(&fsp->timer);
 		INIT_LIST_HEAD(&fsp->list);
@@ -157,12 +162,11 @@ static struct fc_fcp_pkt *fc_fcp_pkt_all
 }
 
 /**
- * fc_fcp_pkt_release() - release hold on scsi_pkt packet
- * @fsp:	fcp packet struct
+ * fc_fcp_pkt_release() - Release hold on a fcp_pkt
+ * @fsp: The FCP packet to be released
  *
- * This is used by upper layer scsi driver.
- * Context	: call from process  and interrupt context.
- *		  no locking required
+ * Context: Can be called from process or interrupt context,
+ *	    no lock is required.
  */
 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
 {
@@ -173,20 +177,25 @@ static void fc_fcp_pkt_release(struct fc
 	}
 }
 
+/**
+ * fc_fcp_pkt_hold() - Hold a fcp_pkt
+ * @fsp: The FCP packet to be held
+ */
 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp)
 {
 	atomic_inc(&fsp->ref_cnt);
 }
 
 /**
- * fc_fcp_pkt_destory() - release hold on scsi_pkt packet
- * @seq:		exchange sequence
- * @fsp:	fcp packet struct
+ * fc_fcp_pkt_destory() - Release hold on a fcp_pkt
+ * @seq: The sequence that the FCP packet is on (required by destructor API)
+ * @fsp: The FCP packet to be released
  *
- * Release hold on scsi_pkt packet set to keep scsi_pkt
- * till EM layer exch resource is not freed.
- * Context	: called from from EM layer.
- *		  no locking required
+ * This routine is called by a destructor callback in the exch_seq_send()
+ * routine of the libfc Transport Template. The 'struct fc_seq' is a required
+ * argument even though it is not used by this routine.
+ *
+ * Context: No locking required.
  */
 static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp)
 {
@@ -194,10 +203,10 @@ static void fc_fcp_pkt_destroy(struct fc
 }
 
 /**
- * fc_fcp_lock_pkt() - lock a packet and get a ref to it.
- * @fsp:	fcp packet
+ * fc_fcp_lock_pkt() - Lock a fcp_pkt and increase its reference count
+ * @fsp: The FCP packet to be locked and incremented
  *
- * We should only return error if we return a command to scsi-ml before
+ * We should only return error if we return a command to SCSI-ml before
  * getting a response. This can happen in cases where we send a abort, but
  * do not wait for the response and the abort and command can be passing
  * each other on the wire/network-layer.
@@ -222,18 +231,33 @@ static inline int fc_fcp_lock_pkt(struct
 	return 0;
 }
 
+/**
+ * fc_fcp_unlock_pkt() - Release a fcp_pkt's lock and decrement its
+ *			 reference count
+ * @fsp: The FCP packet to be unlocked and decremented
+ */
 static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp)
 {
 	spin_unlock_bh(&fsp->scsi_pkt_lock);
 	fc_fcp_pkt_release(fsp);
 }
 
+/**
+ * fc_fcp_timer_set() - Start a timer for a fcp_pkt
+ * @fsp:   The FCP packet to start a timer for
+ * @delay: The timeout period for the timer
+ */
 static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay)
 {
 	if (!(fsp->state & FC_SRB_COMPL))
 		mod_timer(&fsp->timer, jiffies + delay);
 }
 
+/**
+ * fc_fcp_send_abort() - Send an abort for exchanges associated with a
+ *			 fcp_pkt
+ * @fsp: The FCP packet to abort exchanges on
+ */
 static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp)
 {
 	if (!fsp->seq_ptr)
@@ -243,9 +267,14 @@ static int fc_fcp_send_abort(struct fc_f
 	return fsp->lp->tt.seq_exch_abort(fsp->seq_ptr, 0);
 }
 
-/*
- * Retry command.
- * An abort isn't needed.
+/**
+ * fc_fcp_retry_cmd() - Retry a fcp_pkt
+ * @fsp: The FCP packet to be retried
+ *
+ * Sets the status code to be FC_ERROR and then calls
+ * fc_fcp_complete_locked() which in turn calls fc_io_compl().
+ * fc_io_compl() will notify the SCSI-ml that the I/O is done.
+ * The SCSI-ml will retry the command.
  */
 static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp)
 {
@@ -260,64 +289,145 @@ static void fc_fcp_retry_cmd(struct fc_f
 	fc_fcp_complete_locked(fsp);
 }
 
-/*
- * fc_fcp_ddp_setup - calls to LLD's ddp_setup to set up DDP
- * transfer for a read I/O indicated by the fc_fcp_pkt.
- * @fsp: ptr to the fc_fcp_pkt
- *
- * This is called in exch_seq_send() when we have a newly allocated
- * exchange with a valid exchange id to setup ddp.
- *
- * returns: none
+/**
+ * fc_fcp_ddp_setup() - Calls a LLD's ddp_setup routine to set up DDP context
+ * @fsp: The FCP packet that will manage the DDP frames
+ * @xid: The XID that will be used for the DDP exchange
  */
 void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid)
 {
-	struct fc_lport *lp;
-
-	if (!fsp)
-		return;
+	struct fc_lport *lport;
 
-	lp = fsp->lp;
+	lport = fsp->lp;
 	if ((fsp->req_flags & FC_SRB_READ) &&
-	    (lp->lro_enabled) && (lp->tt.ddp_setup)) {
-		if (lp->tt.ddp_setup(lp, xid, scsi_sglist(fsp->cmd),
-				     scsi_sg_count(fsp->cmd)))
+	    (lport->lro_enabled) && (lport->tt.ddp_setup)) {
+		if (lport->tt.ddp_setup(lport, xid, scsi_sglist(fsp->cmd),
+					scsi_sg_count(fsp->cmd)))
 			fsp->xfer_ddp = xid;
 	}
 }
-EXPORT_SYMBOL(fc_fcp_ddp_setup);
 
-/*
- * fc_fcp_ddp_done - calls to LLD's ddp_done to release any
- * DDP related resources for this I/O if it is initialized
- * as a ddp transfer
- * @fsp: ptr to the fc_fcp_pkt
- *
- * returns: none
+/**
+ * fc_fcp_ddp_done() - Calls a LLD's ddp_done routine to release any
+ *		       DDP related resources for a fcp_pkt
+ * @fsp: The FCP packet that DDP had been used on
  */
 static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 
 	if (!fsp)
 		return;
 
-	lp = fsp->lp;
-	if (fsp->xfer_ddp && lp->tt.ddp_done) {
-		fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
-		fsp->xfer_ddp = 0;
+	if (fsp->xfer_ddp == FC_XID_UNKNOWN)
+		return;
+
+	lport = fsp->lp;
+	if (lport->tt.ddp_done) {
+		fsp->xfer_len = lport->tt.ddp_done(lport, fsp->xfer_ddp);
+		fsp->xfer_ddp = FC_XID_UNKNOWN;
 	}
 }
 
+/**
+ * fc_fcp_can_queue_ramp_up() - increases can_queue
+ * @lport: lport to ramp up can_queue
+ *
+ * Locking notes: Called with Scsi_Host lock held
+ */
+static void fc_fcp_can_queue_ramp_up(struct fc_lport *lport)
+{
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	int can_queue;
+
+	if (si->last_can_queue_ramp_up_time &&
+	    (time_before(jiffies, si->last_can_queue_ramp_up_time +
+			 FC_CAN_QUEUE_PERIOD)))
+		return;
+
+	if (time_before(jiffies, si->last_can_queue_ramp_down_time +
+			FC_CAN_QUEUE_PERIOD))
+		return;
+
+	si->last_can_queue_ramp_up_time = jiffies;
+
+	can_queue = lport->host->can_queue << 1;
+	if (can_queue >= si->max_can_queue) {
+		can_queue = si->max_can_queue;
+		si->last_can_queue_ramp_down_time = 0;
+	}
+	lport->host->can_queue = can_queue;
+	shost_printk(KERN_ERR, lport->host, "libfc: increased "
+		     "can_queue to %d.\n", can_queue);
+}
+
+/**
+ * fc_fcp_can_queue_ramp_down() - reduces can_queue
+ * @lport: lport to reduce can_queue
+ *
+ * If we are getting memory allocation failures, then we may
+ * be trying to execute too many commands. We let the running
+ * commands complete or timeout, then try again with a reduced
+ * can_queue. Eventually we will hit the point where we run
+ * on all reserved structs.
+ *
+ * Locking notes: Called with Scsi_Host lock held
+ */
+static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
+{
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	int can_queue;
+
+	if (si->last_can_queue_ramp_down_time &&
+	    (time_before(jiffies, si->last_can_queue_ramp_down_time +
+			 FC_CAN_QUEUE_PERIOD)))
+		return;
+
+	si->last_can_queue_ramp_down_time = jiffies;
+
+	can_queue = lport->host->can_queue;
+	can_queue >>= 1;
+	if (!can_queue)
+		can_queue = 1;
+	lport->host->can_queue = can_queue;
+	shost_printk(KERN_ERR, lport->host, "libfc: Could not allocate frame.\n"
+		     "Reducing can_queue to %d.\n", can_queue);
+}
 
 /*
- * Receive SCSI data from target.
- * Called after receiving solicited data.
+ * fc_fcp_frame_alloc() -  Allocates fc_frame structure and buffer.
+ * @lport:	fc lport struct
+ * @len:	payload length
+ *
+ * Allocates fc_frame structure and buffer but if fails to allocate
+ * then reduce can_queue.
+ */
+static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport,
+						  size_t len)
+{
+	struct fc_frame *fp;
+	unsigned long flags;
+
+	fp = fc_frame_alloc(lport, len);
+	if (likely(fp))
+		return fp;
+
+	/* error case */
+	spin_lock_irqsave(lport->host->host_lock, flags);
+	fc_fcp_can_queue_ramp_down(lport);
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
+	return NULL;
+}
+
+/**
+ * fc_fcp_recv_data() - Handler for receiving SCSI-FCP data from a target
+ * @fsp: The FCP packet the data is on
+ * @fp:	 The data frame
  */
 static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	struct scsi_cmnd *sc = fsp->cmd;
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fcoe_dev_stats *stats;
 	struct fc_frame_header *fh;
 	size_t start_offset;
@@ -327,7 +437,7 @@ static void fc_fcp_recv_data(struct fc_f
 	size_t len;
 	void *buf;
 	struct scatterlist *sg;
-	size_t remaining;
+	u32 nents;
 
 	fh = fc_frame_header_get(fp);
 	offset = ntohl(fh->fh_parm_offset);
@@ -351,65 +461,29 @@ static void fc_fcp_recv_data(struct fc_f
 	if (offset != fsp->xfer_len)
 		fsp->state |= FC_SRB_DISCONTIG;
 
-	crc = 0;
-	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED)
-		crc = crc32(~0, (u8 *) fh, sizeof(*fh));
-
 	sg = scsi_sglist(sc);
-	remaining = len;
-
-	while (remaining > 0 && sg) {
-		size_t off;
-		void *page_addr;
-		size_t sg_bytes;
-
-		if (offset >= sg->length) {
-			offset -= sg->length;
-			sg = sg_next(sg);
-			continue;
-		}
-		sg_bytes = min(remaining, sg->length - offset);
-
-		/*
-		 * The scatterlist item may be bigger than PAGE_SIZE,
-		 * but we are limited to mapping PAGE_SIZE at a time.
-		 */
-		off = offset + sg->offset;
-		sg_bytes = min(sg_bytes, (size_t)
-			       (PAGE_SIZE - (off & ~PAGE_MASK)));
-		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT),
-					KM_SOFTIRQ0);
-		if (!page_addr)
-			break;		/* XXX panic? */
-
-		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED)
-			crc = crc32(crc, buf, sg_bytes);
-		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf,
-		       sg_bytes);
-
-		kunmap_atomic(page_addr, KM_SOFTIRQ0);
-		buf += sg_bytes;
-		offset += sg_bytes;
-		remaining -= sg_bytes;
-		copy_len += sg_bytes;
-	}
+	nents = scsi_sg_count(sc);
 
-	if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+	if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
+		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
+						    &offset, KM_SOFTIRQ0, NULL);
+	} else {
+		crc = crc32(~0, (u8 *) fh, sizeof(*fh));
+		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
+						    &offset, KM_SOFTIRQ0, &crc);
 		buf = fc_frame_payload_get(fp, 0);
-		if (len % 4) {
+		if (len % 4)
 			crc = crc32(crc, buf + len, 4 - (len % 4));
-			len += 4 - (len % 4);
-		}
 
 		if (~crc != le32_to_cpu(fr_crc(fp))) {
 crc_err:
-			stats = fc_lport_get_stats(lp);
+			stats = fc_lport_get_stats(lport);
 			stats->ErrorFrames++;
 			/* FIXME - per cpu count, not total count! */
 			if (stats->InvalidCRCCount++ < 5)
 				printk(KERN_WARNING "libfc: CRC error on data "
 				       "frame for port (%6x)\n",
-				       fc_host_port_id(lp->host));
+				       fc_host_port_id(lport->host));
 			/*
 			 * Assume the frame is total garbage.
 			 * We may have copied it over the good part
@@ -437,18 +511,17 @@ crc_err:
 }
 
 /**
- * fc_fcp_send_data() -  Send SCSI data to target.
- * @fsp: ptr to fc_fcp_pkt
- * @sp: ptr to this sequence
- * @offset: starting offset for this data request
- * @seq_blen: the burst length for this data request
+ * fc_fcp_send_data() - Send SCSI data to a target
+ * @fsp:      The FCP packet the data is on
+ * @sp:	      The sequence the data is to be sent on
+ * @offset:   The starting offset for this data request
+ * @seq_blen: The burst length for this data request
  *
  * Called after receiving a Transfer Ready data descriptor.
- * if LLD is capable of seq offload then send down seq_blen
- * size of data in single frame, otherwise send multiple FC
- * frames of max FC frame payload supported by target port.
- *
- * Returns : 0 for success.
+ * If the LLD is capable of sequence offload then send down the
+ * seq_blen ammount of data in single frame, otherwise send
+ * multiple frames of the maximum frame payload supported by
+ * the target port.
  */
 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
 			    size_t offset, size_t seq_blen)
@@ -457,16 +530,18 @@ static int fc_fcp_send_data(struct fc_fc
 	struct scsi_cmnd *sc;
 	struct scatterlist *sg;
 	struct fc_frame *fp = NULL;
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
+	struct page *page;
 	size_t remaining;
 	size_t t_blen;
 	size_t tlen;
 	size_t sg_bytes;
 	size_t frame_offset, fh_parm_offset;
+	size_t off;
 	int error;
 	void *data = NULL;
 	void *page_addr;
-	int using_sg = lp->sg_supp;
+	int using_sg = lport->sg_supp;
 	u32 f_ctl;
 
 	WARN_ON(seq_blen <= 0);
@@ -488,10 +563,10 @@ static int fc_fcp_send_data(struct fc_fc
 	 * to max FC frame payload previously set in fsp->max_payload.
 	 */
 	t_blen = fsp->max_payload;
-	if (lp->seq_offload) {
-		t_blen = min(seq_blen, (size_t)lp->lso_max);
+	if (lport->seq_offload) {
+		t_blen = min(seq_blen, (size_t)lport->lso_max);
 		FC_FCP_DBG(fsp, "fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n",
-			   fsp, seq_blen, lp->lso_max, t_blen);
+			   fsp, seq_blen, lport->lso_max, t_blen);
 	}
 
 	WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
@@ -503,7 +578,7 @@ static int fc_fcp_send_data(struct fc_fc
 	remaining = seq_blen;
 	fh_parm_offset = frame_offset = offset;
 	tlen = 0;
-	seq = lp->tt.seq_start_next(seq);
+	seq = lport->tt.seq_start_next(seq);
 	f_ctl = FC_FC_REL_OFF;
 	WARN_ON(!seq);
 
@@ -525,43 +600,34 @@ static int fc_fcp_send_data(struct fc_fc
 			 */
 			if (tlen % 4)
 				using_sg = 0;
-			if (using_sg) {
-				fp = _fc_frame_alloc(lp, 0);
-				if (!fp)
-					return -ENOMEM;
-			} else {
-				fp = fc_frame_alloc(lp, tlen);
-				if (!fp)
-					return -ENOMEM;
+			fp = fc_frame_alloc(lport, using_sg ? 0 : tlen);
+			if (!fp)
+				return -ENOMEM;
 
-				data = (void *)(fr_hdr(fp)) +
-					sizeof(struct fc_frame_header);
-			}
+			data = fc_frame_header_get(fp) + 1;
 			fh_parm_offset = frame_offset;
 			fr_max_payload(fp) = fsp->max_payload;
 		}
+
+		off = offset + sg->offset;
 		sg_bytes = min(tlen, sg->length - offset);
+		sg_bytes = min(sg_bytes,
+			       (size_t) (PAGE_SIZE - (off & ~PAGE_MASK)));
+		page = sg_page(sg) + (off >> PAGE_SHIFT);
 		if (using_sg) {
-			get_page(sg_page(sg));
+			get_page(page);
 			skb_fill_page_desc(fp_skb(fp),
 					   skb_shinfo(fp_skb(fp))->nr_frags,
-					   sg_page(sg), sg->offset + offset,
-					   sg_bytes);
+					   page, off & ~PAGE_MASK, sg_bytes);
 			fp_skb(fp)->data_len += sg_bytes;
 			fr_len(fp) += sg_bytes;
 			fp_skb(fp)->truesize += PAGE_SIZE;
 		} else {
-			size_t off = offset + sg->offset;
-
 			/*
 			 * The scatterlist item may be bigger than PAGE_SIZE,
 			 * but we must not cross pages inside the kmap.
 			 */
-			sg_bytes = min(sg_bytes, (size_t) (PAGE_SIZE -
-							   (off & ~PAGE_MASK)));
-			page_addr = kmap_atomic(sg_page(sg) +
-						(off >> PAGE_SHIFT),
-						KM_SOFTIRQ0);
+			page_addr = kmap_atomic(page, KM_SOFTIRQ0);
 			memcpy(data, (char *)page_addr + (off & ~PAGE_MASK),
 			       sg_bytes);
 			kunmap_atomic(page_addr, KM_SOFTIRQ0);
@@ -572,7 +638,8 @@ static int fc_fcp_send_data(struct fc_fc
 		tlen -= sg_bytes;
 		remaining -= sg_bytes;
 
-		if (tlen)
+		if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) &&
+		    (tlen))
 			continue;
 
 		/*
@@ -589,7 +656,7 @@ static int fc_fcp_send_data(struct fc_fc
 		/*
 		 * send fragment using for a sequence.
 		 */
-		error = lp->tt.seq_send(lp, seq, fp);
+		error = lport->tt.seq_send(lport, seq, fp);
 		if (error) {
 			WARN_ON(1);		/* send error should be rare */
 			fc_fcp_retry_cmd(fsp);
@@ -601,6 +668,11 @@ static int fc_fcp_send_data(struct fc_fc
 	return 0;
 }
 
+/**
+ * fc_fcp_abts_resp() - Send an ABTS response
+ * @fsp: The FCP packet that is being aborted
+ * @fp:	 The response frame
+ */
 static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	int ba_done = 1;
@@ -637,46 +709,13 @@ static void fc_fcp_abts_resp(struct fc_f
 }
 
 /**
- * fc_fcp_reduce_can_queue() - drop can_queue
- * @lp: lport to drop queueing for
- *
- * If we are getting memory allocation failures, then we may
- * be trying to execute too many commands. We let the running
- * commands complete or timeout, then try again with a reduced
- * can_queue. Eventually we will hit the point where we run
- * on all reserved structs.
- */
-static void fc_fcp_reduce_can_queue(struct fc_lport *lp)
-{
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
-	unsigned long flags;
-	int can_queue;
-
-	spin_lock_irqsave(lp->host->host_lock, flags);
-	if (si->throttled)
-		goto done;
-	si->throttled = 1;
-
-	can_queue = lp->host->can_queue;
-	can_queue >>= 1;
-	if (!can_queue)
-		can_queue = 1;
-	lp->host->can_queue = can_queue;
-	shost_printk(KERN_ERR, lp->host, "libfc: Could not allocate frame.\n"
-		     "Reducing can_queue to %d.\n", can_queue);
-done:
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
-}
-
-/**
- * fc_fcp_recv() - Reveive FCP frames
+ * fc_fcp_recv() - Reveive an FCP frame
  * @seq: The sequence the frame is on
- * @fp: The FC frame
+ * @fp:	 The received frame
  * @arg: The related FCP packet
  *
- * Return   : None
- * Context  : called from Soft IRQ context
- *	      can not called holding list lock
+ * Context: Called from Soft IRQ context. Can not be called
+ *	    holding the FCP packet list lock.
  */
 static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -687,8 +726,10 @@ static void fc_fcp_recv(struct fc_seq *s
 	u8 r_ctl;
 	int rc = 0;
 
-	if (IS_ERR(fp))
-		goto errout;
+	if (IS_ERR(fp)) {
+		fc_fcp_error(fsp, fp);
+		return;
+	}
 
 	fh = fc_frame_header_get(fp);
 	r_ctl = fh->fh_r_ctl;
@@ -721,8 +762,6 @@ static void fc_fcp_recv(struct fc_seq *s
 				      (size_t) ntohl(dd->ft_burst_len));
 		if (!rc)
 			seq->rec_data = fsp->xfer_len;
-		else if (rc == -ENOMEM)
-			fsp->state |= FC_SRB_NOMEM;
 	} else if (r_ctl == FC_RCTL_DD_SOL_DATA) {
 		/*
 		 * received a DATA frame
@@ -742,13 +781,13 @@ unlock:
 	fc_fcp_unlock_pkt(fsp);
 out:
 	fc_frame_free(fp);
-errout:
-	if (IS_ERR(fp))
-		fc_fcp_error(fsp, fp);
-	else if (rc == -ENOMEM)
-		fc_fcp_reduce_can_queue(lport);
 }
 
+/**
+ * fc_fcp_resp() - Handler for FCP responses
+ * @fsp: The FCP packet the response is for
+ * @fp:	 The response frame
+ */
 static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	struct fc_frame_header *fh;
@@ -862,15 +901,16 @@ err:
 }
 
 /**
- * fc_fcp_complete_locked() - complete processing of a fcp packet
- * @fsp:	fcp packet
+ * fc_fcp_complete_locked() - Complete processing of a fcp_pkt with the
+ *			      fcp_pkt lock held
+ * @fsp: The FCP packet to be completed
  *
  * This function may sleep if a timer is pending. The packet lock must be
  * held, and the host lock must not be held.
  */
 static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fc_seq *seq;
 	struct fc_exch *ep;
 	u32 f_ctl;
@@ -901,8 +941,8 @@ static void fc_fcp_complete_locked(struc
 			struct fc_frame *conf_frame;
 			struct fc_seq *csp;
 
-			csp = lp->tt.seq_start_next(seq);
-			conf_frame = fc_frame_alloc(fsp->lp, 0);
+			csp = lport->tt.seq_start_next(seq);
+			conf_frame = fc_fcp_frame_alloc(fsp->lp, 0);
 			if (conf_frame) {
 				f_ctl = FC_FC_SEQ_INIT;
 				f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
@@ -910,43 +950,48 @@ static void fc_fcp_complete_locked(struc
 				fc_fill_fc_hdr(conf_frame, FC_RCTL_DD_SOL_CTL,
 					       ep->did, ep->sid,
 					       FC_TYPE_FCP, f_ctl, 0);
-				lp->tt.seq_send(lp, csp, conf_frame);
+				lport->tt.seq_send(lport, csp, conf_frame);
 			}
 		}
-		lp->tt.exch_done(seq);
+		lport->tt.exch_done(seq);
 	}
 	fc_io_compl(fsp);
 }
 
+/**
+ * fc_fcp_cleanup_cmd() - Cancel the active exchange on a fcp_pkt
+ * @fsp:   The FCP packet whose exchanges should be canceled
+ * @error: The reason for the cancellation
+ */
 static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 
 	if (fsp->seq_ptr) {
-		lp->tt.exch_done(fsp->seq_ptr);
+		lport->tt.exch_done(fsp->seq_ptr);
 		fsp->seq_ptr = NULL;
 	}
 	fsp->status_code = error;
 }
 
 /**
- * fc_fcp_cleanup_each_cmd() - Cleanup active commads
- * @lp:		logical port
- * @id:		target id
- * @lun:	lun
- * @error:	fsp status code
+ * fc_fcp_cleanup_each_cmd() - Cancel all exchanges on a local port
+ * @lport: The local port whose exchanges should be canceled
+ * @id:	   The target's ID
+ * @lun:   The LUN
+ * @error: The reason for cancellation
  *
  * If lun or id is -1, they are ignored.
  */
-static void fc_fcp_cleanup_each_cmd(struct fc_lport *lp, unsigned int id,
+static void fc_fcp_cleanup_each_cmd(struct fc_lport *lport, unsigned int id,
 				    unsigned int lun, int error)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 	struct fc_fcp_pkt *fsp;
 	struct scsi_cmnd *sc_cmd;
 	unsigned long flags;
 
-	spin_lock_irqsave(lp->host->host_lock, flags);
+	spin_lock_irqsave(&si->scsi_queue_lock, flags);
 restart:
 	list_for_each_entry(fsp, &si->scsi_pkt_queue, list) {
 		sc_cmd = fsp->cmd;
@@ -957,7 +1002,7 @@ restart:
 			continue;
 
 		fc_fcp_pkt_hold(fsp);
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 
 		if (!fc_fcp_lock_pkt(fsp)) {
 			fc_fcp_cleanup_cmd(fsp, error);
@@ -966,35 +1011,37 @@ restart:
 		}
 
 		fc_fcp_pkt_release(fsp);
-		spin_lock_irqsave(lp->host->host_lock, flags);
+		spin_lock_irqsave(&si->scsi_queue_lock, flags);
 		/*
 		 * while we dropped the lock multiple pkts could
 		 * have been released, so we have to start over.
 		 */
 		goto restart;
 	}
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
+	spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 }
 
-static void fc_fcp_abort_io(struct fc_lport *lp)
+/**
+ * fc_fcp_abort_io() - Abort all FCP-SCSI exchanges on a local port
+ * @lport: The local port whose exchanges are to be aborted
+ */
+static void fc_fcp_abort_io(struct fc_lport *lport)
 {
-	fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_HRD_ERROR);
+	fc_fcp_cleanup_each_cmd(lport, -1, -1, FC_HRD_ERROR);
 }
 
 /**
- * fc_fcp_pkt_send() - send a fcp packet to the lower level.
- * @lp:		fc lport
- * @fsp:	fc packet.
+ * fc_fcp_pkt_send() - Send a fcp_pkt
+ * @lport: The local port to send the FCP packet on
+ * @fsp:   The FCP packet to send
  *
- * This is called by upper layer protocol.
- * Return   : zero for success and -1 for failure
- * Context  : called from queuecommand which can be called from process
- *	      or scsi soft irq.
- * Locks    : called with the host lock and irqs disabled.
+ * Return:  Zero for success and -1 for failure
+ * Locks:   Called without locks held
  */
-static int fc_fcp_pkt_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
+static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	unsigned long flags;
 	int rc;
 
 	fsp->cmd->SCp.ptr = (char *)fsp;
@@ -1004,18 +1051,27 @@ static int fc_fcp_pkt_send(struct fc_lpo
 	int_to_scsilun(fsp->cmd->device->lun,
 		       (struct scsi_lun *)fsp->cdb_cmd.fc_lun);
 	memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len);
-	list_add_tail(&fsp->list, &si->scsi_pkt_queue);
 
-	spin_unlock_irq(lp->host->host_lock);
-	rc = lp->tt.fcp_cmd_send(lp, fsp, fc_fcp_recv);
-	spin_lock_irq(lp->host->host_lock);
-	if (rc)
+	spin_lock_irqsave(&si->scsi_queue_lock, flags);
+	list_add_tail(&fsp->list, &si->scsi_pkt_queue);
+	spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
+	rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv);
+	if (unlikely(rc)) {
+		spin_lock_irqsave(&si->scsi_queue_lock, flags);
 		list_del(&fsp->list);
+		spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
+	}
 
 	return rc;
 }
 
-static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
+/**
+ * fc_fcp_cmd_send() - Send a FCP command
+ * @lport: The local port to send the command on
+ * @fsp:   The FCP packet the command is on
+ * @resp:  The handler for the response
+ */
+static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
 			   void (*resp)(struct fc_seq *,
 					struct fc_frame *fp,
 					void *arg))
@@ -1023,14 +1079,14 @@ static int fc_fcp_cmd_send(struct fc_lpo
 	struct fc_frame *fp;
 	struct fc_seq *seq;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	const size_t len = sizeof(fsp->cdb_cmd);
 	int rc = 0;
 
 	if (fc_fcp_lock_pkt(fsp))
 		return 0;
 
-	fp = fc_frame_alloc(lp, sizeof(fsp->cdb_cmd));
+	fp = fc_fcp_frame_alloc(lport, sizeof(fsp->cdb_cmd));
 	if (!fp) {
 		rc = -1;
 		goto unlock;
@@ -1040,15 +1096,15 @@ static int fc_fcp_cmd_send(struct fc_lpo
 	fr_fsp(fp) = fsp;
 	rport = fsp->rport;
 	fsp->max_payload = rport->maxframe_size;
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 
 	fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
+	seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy,
+				      fsp, 0);
 	if (!seq) {
-		fc_frame_free(fp);
 		rc = -1;
 		goto unlock;
 	}
@@ -1065,8 +1121,10 @@ unlock:
 	return rc;
 }
 
-/*
- * transport error handler
+/**
+ * fc_fcp_error() - Handler for FCP layer errors
+ * @fsp: The FCP packet the error is on
+ * @fp:	 The frame that has errored
  */
 static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
@@ -1091,11 +1149,13 @@ unlock:
 	fc_fcp_unlock_pkt(fsp);
 }
 
-/*
- * Scsi abort handler- calls to send an abort
- * and then wait for abort completion
+/**
+ * fc_fcp_pkt_abort() - Abort a fcp_pkt
+ * @fsp:   The FCP packet to abort on
+ *
+ * Called to send an abort and then wait for abort completion
  */
-static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
+static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp)
 {
 	int rc = FAILED;
 
@@ -1122,14 +1182,15 @@ static int fc_fcp_pkt_abort(struct fc_lp
 	return rc;
 }
 
-/*
- * Retry LUN reset after resource allocation failed.
+/**
+ * fc_lun_reset_send() - Send LUN reset command
+ * @data: The FCP packet that identifies the LUN to be reset
  */
 static void fc_lun_reset_send(unsigned long data)
 {
 	struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
-	struct fc_lport *lp = fsp->lp;
-	if (lp->tt.fcp_cmd_send(lp, fsp, fc_tm_done)) {
+	struct fc_lport *lport = fsp->lp;
+	if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
 		if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
 			return;
 		if (fc_fcp_lock_pkt(fsp))
@@ -1140,11 +1201,15 @@ static void fc_lun_reset_send(unsigned l
 	}
 }
 
-/*
- * Scsi device reset handler- send a LUN RESET to the device
- * and wait for reset reply
+/**
+ * fc_lun_reset() - Send a LUN RESET command to a device
+ *		    and wait for the reply
+ * @lport: The local port to sent the comand on
+ * @fsp:   The FCP packet that identifies the LUN to be reset
+ * @id:	   The SCSI command ID
+ * @lun:   The LUN ID to be reset
  */
-static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
+static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
 			unsigned int id, unsigned int lun)
 {
 	int rc;
@@ -1172,14 +1237,14 @@ static int fc_lun_reset(struct fc_lport
 
 	spin_lock_bh(&fsp->scsi_pkt_lock);
 	if (fsp->seq_ptr) {
-		lp->tt.exch_done(fsp->seq_ptr);
+		lport->tt.exch_done(fsp->seq_ptr);
 		fsp->seq_ptr = NULL;
 	}
 	fsp->wait_for_comp = 0;
 	spin_unlock_bh(&fsp->scsi_pkt_lock);
 
 	if (!rc) {
-		FC_SCSI_DBG(lp, "lun reset failed\n");
+		FC_SCSI_DBG(lport, "lun reset failed\n");
 		return FAILED;
 	}
 
@@ -1187,13 +1252,16 @@ static int fc_lun_reset(struct fc_lport
 	if (fsp->cdb_status != FCP_TMF_CMPL)
 		return FAILED;
 
-	FC_SCSI_DBG(lp, "lun reset to lun %u completed\n", lun);
-	fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED);
+	FC_SCSI_DBG(lport, "lun reset to lun %u completed\n", lun);
+	fc_fcp_cleanup_each_cmd(lport, id, lun, FC_CMD_ABORTED);
 	return SUCCESS;
 }
 
-/*
- * Task Managment response handler
+/**
+ * fc_tm_done() - Task Managment response handler
+ * @seq: The sequence that the response is on
+ * @fp:	 The response frame
+ * @arg: The FCP packet the response is for
  */
 static void fc_tm_done(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1230,34 +1298,31 @@ static void fc_tm_done(struct fc_seq *se
 	fc_fcp_unlock_pkt(fsp);
 }
 
-static void fc_fcp_cleanup(struct fc_lport *lp)
+/**
+ * fc_fcp_cleanup() - Cleanup all FCP exchanges on a local port
+ * @lport: The local port to be cleaned up
+ */
+static void fc_fcp_cleanup(struct fc_lport *lport)
 {
-	fc_fcp_cleanup_each_cmd(lp, -1, -1, FC_ERROR);
+	fc_fcp_cleanup_each_cmd(lport, -1, -1, FC_ERROR);
 }
 
-/*
- * fc_fcp_timeout: called by OS timer function.
- *
- * The timer has been inactivated and must be reactivated if desired
- * using fc_fcp_timer_set().
- *
- * Algorithm:
- *
- * If REC is supported, just issue it, and return.  The REC exchange will
- * complete or time out, and recovery can continue at that point.
- *
- * Otherwise, if the response has been received without all the data,
- * it has been ER_TIMEOUT since the response was received.
+/**
+ * fc_fcp_timeout() - Handler for fcp_pkt timeouts
+ * @data: The FCP packet that has timed out
  *
- * If the response has not been received,
- * we see if data was received recently.  If it has been, we continue waiting,
- * otherwise, we abort the command.
+ * If REC is supported then just issue it and return. The REC exchange will
+ * complete or time out and recovery can continue at that point. Otherwise,
+ * if the response has been received without all the data it has been
+ * ER_TIMEOUT since the response was received. If the response has not been
+ * received we see if data was received recently. If it has been then we
+ * continue waiting, otherwise, we abort the command.
  */
 static void fc_fcp_timeout(unsigned long data)
 {
 	struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
 	struct fc_rport *rport = fsp->rport;
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
+	struct fc_rport_libfc_priv *rpriv = rport->dd_data;
 
 	if (fc_fcp_lock_pkt(fsp))
 		return;
@@ -1267,7 +1332,7 @@ static void fc_fcp_timeout(unsigned long
 
 	fsp->state |= FC_SRB_FCP_PROCESSING_TMO;
 
-	if (rp->flags & FC_RP_FLAGS_REC_SUPPORTED)
+	if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
 		fc_fcp_rec(fsp);
 	else if (time_after_eq(fsp->last_pkt_time + (FC_SCSI_ER_TIMEOUT / 2),
 			       jiffies))
@@ -1281,39 +1346,40 @@ unlock:
 	fc_fcp_unlock_pkt(fsp);
 }
 
-/*
- * Send a REC ELS request
+/**
+ * fc_fcp_rec() - Send a REC ELS request
+ * @fsp: The FCP packet to send the REC request on
  */
 static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_frame *fp;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 
-	lp = fsp->lp;
+	lport = fsp->lp;
 	rport = fsp->rport;
-	rp = rport->dd_data;
-	if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) {
+	rpriv = rport->dd_data;
+	if (!fsp->seq_ptr || rpriv->rp_state != RPORT_ST_READY) {
 		fsp->status_code = FC_HRD_ERROR;
 		fsp->io_status = 0;
 		fc_fcp_complete_locked(fsp);
 		return;
 	}
-	fp = fc_frame_alloc(lp, sizeof(struct fc_els_rec));
+	fp = fc_fcp_frame_alloc(lport, sizeof(struct fc_els_rec));
 	if (!fp)
 		goto retry;
 
 	fr_seq(fp) = fsp->seq_ptr;
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_ELS,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_ELS,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
-	if (lp->tt.elsct_send(lp, rport->port_id, fp, ELS_REC, fc_fcp_rec_resp,
-			      fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) {
+	if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
+				 fc_fcp_rec_resp, fsp,
+				 jiffies_to_msecs(FC_SCSI_REC_TOV))) {
 		fc_fcp_pkt_hold(fsp);		/* hold while REC outstanding */
 		return;
 	}
-	fc_frame_free(fp);
 retry:
 	if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
 		fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
@@ -1321,12 +1387,16 @@ retry:
 		fc_timeout_error(fsp);
 }
 
-/*
- * Receive handler for REC ELS frame
- * if it is a reject then let the scsi layer to handle
- * the timeout. if it is a LS_ACC then if the io was not completed
- * then set the timeout and return otherwise complete the exchange
- * and tell the scsi layer to restart the I/O.
+/**
+ * fc_fcp_rec_resp() - Handler for REC ELS responses
+ * @seq: The sequence the response is on
+ * @fp:	 The response frame
+ * @arg: The FCP packet the response is on
+ *
+ * If the response is a reject then the scsi layer will handle
+ * the timeout. If the response is a LS_ACC then if the I/O was not completed
+ * set the timeout and return. If the I/O was completed then complete the
+ * exchange and tell the SCSI layer.
  */
 static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1338,7 +1408,7 @@ static void fc_fcp_rec_resp(struct fc_se
 	u32 offset;
 	enum dma_data_direction data_dir;
 	enum fc_rctl r_ctl;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 
 	if (IS_ERR(fp)) {
 		fc_fcp_rec_error(fsp, fp);
@@ -1361,13 +1431,13 @@ static void fc_fcp_rec_resp(struct fc_se
 			/* fall through */
 		case ELS_RJT_UNSUP:
 			FC_FCP_DBG(fsp, "device does not support REC\n");
-			rp = fsp->rport->dd_data;
+			rpriv = fsp->rport->dd_data;
 			/*
 			 * if we do not spport RECs or got some bogus
 			 * reason then resetup timer so we check for
 			 * making progress.
 			 */
-			rp->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
+			rpriv->flags &= ~FC_RP_FLAGS_REC_SUPPORTED;
 			fc_fcp_timer_set(fsp, FC_SCSI_ER_TIMEOUT);
 			break;
 		case ELS_RJT_LOGIC:
@@ -1464,8 +1534,10 @@ out:
 	fc_frame_free(fp);
 }
 
-/*
- * Handle error response or timeout for REC exchange.
+/**
+ * fc_fcp_rec_error() - Handler for REC errors
+ * @fsp: The FCP packet the error is on
+ * @fp:	 The REC frame
  */
 static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
@@ -1504,10 +1576,9 @@ out:
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding REC */
 }
 
-/*
- * Time out error routine:
- * abort's the I/O close the exchange and
- * send completion notification to scsi layer
+/**
+ * fc_timeout_error() - Handler for fcp_pkt timeouts
+ * @fsp: The FCP packt that has timed out
  */
 static void fc_timeout_error(struct fc_fcp_pkt *fsp)
 {
@@ -1521,16 +1592,18 @@ static void fc_timeout_error(struct fc_f
 	fc_fcp_send_abort(fsp);
 }
 
-/*
- * Sequence retransmission request.
+/**
+ * fc_fcp_srr() - Send a SRR request (Sequence Retransmission Request)
+ * @fsp:   The FCP packet the SRR is to be sent on
+ * @r_ctl: The R_CTL field for the SRR request
  * This is called after receiving status but insufficient data, or
  * when expecting status but the request has timed out.
  */
 static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
 {
-	struct fc_lport *lp = fsp->lp;
+	struct fc_lport *lport = fsp->lp;
 	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr);
 	struct fc_seq *seq;
 	struct fcp_srr *srr;
@@ -1538,12 +1611,13 @@ static void fc_fcp_srr(struct fc_fcp_pkt
 	u8 cdb_op;
 
 	rport = fsp->rport;
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 	cdb_op = fsp->cdb_cmd.fc_cdb[0];
 
-	if (!(rp->flags & FC_RP_FLAGS_RETRY) || rp->rp_state != RPORT_ST_READY)
+	if (!(rpriv->flags & FC_RP_FLAGS_RETRY) ||
+	    rpriv->rp_state != RPORT_ST_READY)
 		goto retry;			/* shouldn't happen */
-	fp = fc_frame_alloc(lp, sizeof(*srr));
+	fp = fc_fcp_frame_alloc(lport, sizeof(*srr));
 	if (!fp)
 		goto retry;
 
@@ -1556,15 +1630,14 @@ static void fc_fcp_srr(struct fc_fcp_pkt
 	srr->srr_rel_off = htonl(offset);
 
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
-		       fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
+		       fc_host_port_id(rpriv->local_port->host), FC_TYPE_FCP,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
 
-	seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
-				   fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
-	if (!seq) {
-		fc_frame_free(fp);
+	seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
+				      fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+	if (!seq)
 		goto retry;
-	}
+
 	fsp->recov_seq = seq;
 	fsp->xfer_len = offset;
 	fsp->xfer_contig_end = offset;
@@ -1575,8 +1648,11 @@ retry:
 	fc_fcp_retry_cmd(fsp);
 }
 
-/*
- * Handle response from SRR.
+/**
+ * fc_fcp_srr_resp() - Handler for SRR response
+ * @seq: The sequence the SRR is on
+ * @fp:	 The SRR frame
+ * @arg: The FCP packet the SRR is on
  */
 static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
 {
@@ -1622,6 +1698,11 @@ out:
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
 }
 
+/**
+ * fc_fcp_srr_error() - Handler for SRR errors
+ * @fsp: The FCP packet that the SRR error is on
+ * @fp:	 The SRR frame
+ */
 static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 {
 	if (fc_fcp_lock_pkt(fsp))
@@ -1646,31 +1727,37 @@ out:
 	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
 }
 
-static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp)
+/**
+ * fc_fcp_lport_queue_ready() - Determine if the lport and it's queue is ready
+ * @lport: The local port to be checked
+ */
+static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
 {
 	/* lock ? */
-	return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull;
+	return (lport->state == LPORT_ST_READY) &&
+		lport->link_up && !lport->qfull;
 }
 
 /**
- * fc_queuecommand - The queuecommand function of the scsi template
- * @cmd:	struct scsi_cmnd to be executed
- * @done:	Callback function to be called when cmd is completed
+ * fc_queuecommand() - The queuecommand function of the SCSI template
+ * @cmd:   The scsi_cmnd to be executed
+ * @done:  The callback function to be called when the scsi_cmnd is complete
  *
- * this is the i/o strategy routine, called by the scsi layer
- * this routine is called with holding the host_lock.
+ * This is the i/o strategy routine, called by the SCSI layer. This routine
+ * is called with the host_lock held.
  */
 int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	struct fc_fcp_pkt *fsp;
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	int rval;
 	int rc = 0;
 	struct fcoe_dev_stats *stats;
 
-	lp = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(sc_cmd->device->host);
+	spin_unlock_irq(lport->host->host_lock);
 
 	rval = fc_remote_port_chkready(rport);
 	if (rval) {
@@ -1689,14 +1776,16 @@ int fc_queuecommand(struct scsi_cmnd *sc
 		goto out;
 	}
 
-	rp = rport->dd_data;
+	rpriv = rport->dd_data;
 
-	if (!fc_fcp_lport_queue_ready(lp)) {
+	if (!fc_fcp_lport_queue_ready(lport)) {
+		if (lport->qfull)
+			fc_fcp_can_queue_ramp_down(lport);
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 		goto out;
 	}
 
-	fsp = fc_fcp_pkt_alloc(lp, GFP_ATOMIC);
+	fsp = fc_fcp_pkt_alloc(lport, GFP_ATOMIC);
 	if (fsp == NULL) {
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 		goto out;
@@ -1706,8 +1795,9 @@ int fc_queuecommand(struct scsi_cmnd *sc
 	 * build the libfc request pkt
 	 */
 	fsp->cmd = sc_cmd;	/* save the cmd */
-	fsp->lp = lp;		/* save the softc ptr */
+	fsp->lp = lport;	/* save the softc ptr */
 	fsp->rport = rport;	/* set the remote port ptr */
+	fsp->xfer_ddp = FC_XID_UNKNOWN;
 	sc_cmd->scsi_done = done;
 
 	/*
@@ -1719,7 +1809,7 @@ int fc_queuecommand(struct scsi_cmnd *sc
 	/*
 	 * setup the data direction
 	 */
-	stats = fc_lport_get_stats(lp);
+	stats = fc_lport_get_stats(lport);
 	if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		fsp->req_flags = FC_SRB_READ;
 		stats->InputRequests++;
@@ -1733,7 +1823,7 @@ int fc_queuecommand(struct scsi_cmnd *sc
 		stats->ControlRequests++;
 	}
 
-	fsp->tgt_flags = rp->flags;
+	fsp->tgt_flags = rpriv->flags;
 
 	init_timer(&fsp->timer);
 	fsp->timer.data = (unsigned long)fsp;
@@ -1743,30 +1833,30 @@ int fc_queuecommand(struct scsi_cmnd *sc
 	 * if we get -1 return then put the request in the pending
 	 * queue.
 	 */
-	rval = fc_fcp_pkt_send(lp, fsp);
+	rval = fc_fcp_pkt_send(lport, fsp);
 	if (rval != 0) {
 		fsp->state = FC_SRB_FREE;
 		fc_fcp_pkt_release(fsp);
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 	}
 out:
+	spin_lock_irq(lport->host->host_lock);
 	return rc;
 }
 EXPORT_SYMBOL(fc_queuecommand);
 
 /**
- * fc_io_compl() -  Handle responses for completed commands
- * @fsp:	scsi packet
- *
- * Translates a error to a Linux SCSI error.
+ * fc_io_compl() - Handle responses for completed commands
+ * @fsp: The FCP packet that is complete
  *
+ * Translates fcp_pkt errors to a Linux SCSI errors.
  * The fcp packet lock must be held when calling.
  */
 static void fc_io_compl(struct fc_fcp_pkt *fsp)
 {
 	struct fc_fcp_internal *si;
 	struct scsi_cmnd *sc_cmd;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	unsigned long flags;
 
 	/* release outstanding ddp context */
@@ -1779,30 +1869,23 @@ static void fc_io_compl(struct fc_fcp_pk
 		spin_lock_bh(&fsp->scsi_pkt_lock);
 	}
 
-	lp = fsp->lp;
-	si = fc_get_scsi_internal(lp);
-	spin_lock_irqsave(lp->host->host_lock, flags);
-	if (!fsp->cmd) {
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+	lport = fsp->lp;
+	si = fc_get_scsi_internal(lport);
+	if (!fsp->cmd)
 		return;
-	}
 
 	/*
-	 * if a command timed out while we had to try and throttle IO
-	 * and it is now getting cleaned up, then we are about to
-	 * try again so clear the throttled flag incase we get more
-	 * time outs.
+	 * if can_queue ramp down is done then try can_queue ramp up
+	 * since commands are completing now.
 	 */
-	if (si->throttled && fsp->state & FC_SRB_NOMEM)
-		si->throttled = 0;
+	if (si->last_can_queue_ramp_down_time)
+		fc_fcp_can_queue_ramp_up(lport);
 
 	sc_cmd = fsp->cmd;
 	fsp->cmd = NULL;
 
-	if (!sc_cmd->SCp.ptr) {
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+	if (!sc_cmd->SCp.ptr)
 		return;
-	}
 
 	CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status;
 	switch (fsp->status_code) {
@@ -1814,21 +1897,6 @@ static void fc_io_compl(struct fc_fcp_pk
 			sc_cmd->result = DID_OK << 16;
 			if (fsp->scsi_resid)
 				CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid;
-		} else if (fsp->cdb_status == QUEUE_FULL) {
-			struct scsi_device *tmp_sdev;
-			struct scsi_device *sdev = sc_cmd->device;
-
-			shost_for_each_device(tmp_sdev, sdev->host) {
-				if (tmp_sdev->id != sdev->id)
-					continue;
-
-				if (tmp_sdev->queue_depth > 1) {
-					scsi_track_queue_full(tmp_sdev,
-							      tmp_sdev->
-							      queue_depth - 1);
-				}
-			}
-			sc_cmd->result = (DID_OK << 16) | fsp->cdb_status;
 		} else {
 			/*
 			 * transport level I/O was ok but scsi
@@ -1846,7 +1914,8 @@ static void fc_io_compl(struct fc_fcp_pk
 			 * scsi status is good but transport level
 			 * underrun.
 			 */
-			sc_cmd->result = DID_OK << 16;
+			sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ?
+					  DID_OK : DID_ERROR) << 16;
 		} else {
 			/*
 			 * scsi got underrun, this is an error
@@ -1878,63 +1947,46 @@ static void fc_io_compl(struct fc_fcp_pk
 		break;
 	}
 
+	spin_lock_irqsave(&si->scsi_queue_lock, flags);
 	list_del(&fsp->list);
+	spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 	sc_cmd->SCp.ptr = NULL;
 	sc_cmd->scsi_done(sc_cmd);
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
 
 	/* release ref from initial allocation in queue command */
 	fc_fcp_pkt_release(fsp);
 }
 
 /**
- * fc_fcp_complete() - complete processing of a fcp packet
- * @fsp:	fcp packet
- *
- * This function may sleep if a fsp timer is pending.
- * The host lock must not be held by caller.
- */
-void fc_fcp_complete(struct fc_fcp_pkt *fsp)
-{
-	if (fc_fcp_lock_pkt(fsp))
-		return;
-
-	fc_fcp_complete_locked(fsp);
-	fc_fcp_unlock_pkt(fsp);
-}
-EXPORT_SYMBOL(fc_fcp_complete);
-
-/**
  * fc_eh_abort() - Abort a command
- * @sc_cmd:	scsi command to abort
+ * @sc_cmd: The SCSI command to abort
  *
- * From scsi host template.
- * send ABTS to the target device  and wait for the response
- * sc_cmd is the pointer to the command to be aborted.
+ * From SCSI host template.
+ * Send an ABTS to the target device and wait for the response.
  */
 int fc_eh_abort(struct scsi_cmnd *sc_cmd)
 {
 	struct fc_fcp_pkt *fsp;
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	int rc = FAILED;
 	unsigned long flags;
 
-	lp = shost_priv(sc_cmd->device->host);
-	if (lp->state != LPORT_ST_READY)
+	lport = shost_priv(sc_cmd->device->host);
+	if (lport->state != LPORT_ST_READY)
 		return rc;
-	else if (!lp->link_up)
+	else if (!lport->link_up)
 		return rc;
 
-	spin_lock_irqsave(lp->host->host_lock, flags);
+	spin_lock_irqsave(lport->host->host_lock, flags);
 	fsp = CMD_SP(sc_cmd);
 	if (!fsp) {
 		/* command completed while scsi eh was setting up */
-		spin_unlock_irqrestore(lp->host->host_lock, flags);
+		spin_unlock_irqrestore(lport->host->host_lock, flags);
 		return SUCCESS;
 	}
 	/* grab a ref so the fsp and sc_cmd cannot be relased from under us */
 	fc_fcp_pkt_hold(fsp);
-	spin_unlock_irqrestore(lp->host->host_lock, flags);
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 
 	if (fc_fcp_lock_pkt(fsp)) {
 		/* completed while we were waiting for timer to be deleted */
@@ -1942,7 +1994,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd
 		goto release_pkt;
 	}
 
-	rc = fc_fcp_pkt_abort(lp, fsp);
+	rc = fc_fcp_pkt_abort(fsp);
 	fc_fcp_unlock_pkt(fsp);
 
 release_pkt:
@@ -1952,37 +2004,34 @@ release_pkt:
 EXPORT_SYMBOL(fc_eh_abort);
 
 /**
- * fc_eh_device_reset() Reset a single LUN
- * @sc_cmd:	scsi command
+ * fc_eh_device_reset() - Reset a single LUN
+ * @sc_cmd: The SCSI command which identifies the device whose
+ *	    LUN is to be reset
  *
- * Set from scsi host template to send tm cmd to the target and wait for the
- * response.
+ * Set from SCSI host template.
  */
 int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 {
-	struct fc_lport *lp;
+	struct fc_lport *lport;
 	struct fc_fcp_pkt *fsp;
 	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	int rc = FAILED;
-	struct fc_rport_libfc_priv *rp;
 	int rval;
 
 	rval = fc_remote_port_chkready(rport);
 	if (rval)
 		goto out;
 
-	rp = rport->dd_data;
-	lp = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(sc_cmd->device->host);
 
-	if (lp->state != LPORT_ST_READY)
+	if (lport->state != LPORT_ST_READY)
 		return rc;
 
-	FC_SCSI_DBG(lp, "Resetting rport (%6x)\n", rport->port_id);
+	FC_SCSI_DBG(lport, "Resetting rport (%6x)\n", rport->port_id);
 
-	fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO);
+	fsp = fc_fcp_pkt_alloc(lport, GFP_NOIO);
 	if (fsp == NULL) {
 		printk(KERN_WARNING "libfc: could not allocate scsi_pkt\n");
-		sc_cmd->result = DID_NO_CONNECT << 16;
 		goto out;
 	}
 
@@ -1991,13 +2040,13 @@ int fc_eh_device_reset(struct scsi_cmnd
 	 * the sc passed in is not setup for execution like when sent
 	 * through the queuecommand callout.
 	 */
-	fsp->lp = lp;		/* save the softc ptr */
+	fsp->lp = lport;	/* save the softc ptr */
 	fsp->rport = rport;	/* set the remote port ptr */
 
 	/*
 	 * flush outstanding commands
 	 */
-	rc = fc_lun_reset(lp, fsp, scmd_id(sc_cmd), sc_cmd->device->lun);
+	rc = fc_lun_reset(lport, fsp, scmd_id(sc_cmd), sc_cmd->device->lun);
 	fsp->state = FC_SRB_FREE;
 	fc_fcp_pkt_release(fsp);
 
@@ -2007,38 +2056,39 @@ out:
 EXPORT_SYMBOL(fc_eh_device_reset);
 
 /**
- * fc_eh_host_reset() - The reset function will reset the ports on the host.
- * @sc_cmd:	scsi command
+ * fc_eh_host_reset() - Reset a Scsi_Host.
+ * @sc_cmd: The SCSI command that identifies the SCSI host to be reset
  */
 int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
 {
 	struct Scsi_Host *shost = sc_cmd->device->host;
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 	unsigned long wait_tmo;
 
-	FC_SCSI_DBG(lp, "Resetting host\n");
+	FC_SCSI_DBG(lport, "Resetting host\n");
 
-	lp->tt.lport_reset(lp);
+	lport->tt.lport_reset(lport);
 	wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
-	while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo))
+	while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies,
+							       wait_tmo))
 		msleep(1000);
 
-	if (fc_fcp_lport_queue_ready(lp)) {
+	if (fc_fcp_lport_queue_ready(lport)) {
 		shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded "
-			     "on port (%6x)\n", fc_host_port_id(lp->host));
+			     "on port (%6x)\n", fc_host_port_id(lport->host));
 		return SUCCESS;
 	} else {
 		shost_printk(KERN_INFO, shost, "libfc: Host reset failed, "
 			     "port (%6x) is not ready.\n",
-			     fc_host_port_id(lp->host));
+			     fc_host_port_id(lport->host));
 		return FAILED;
 	}
 }
 EXPORT_SYMBOL(fc_eh_host_reset);
 
 /**
- * fc_slave_alloc() - configure queue depth
- * @sdev:	scsi device
+ * fc_slave_alloc() - Configure the queue depth of a Scsi_Host
+ * @sdev: The SCSI device that identifies the SCSI host
  *
  * Configures queue depth based on host's cmd_per_len. If not set
  * then we use the libfc default.
@@ -2046,29 +2096,50 @@ EXPORT_SYMBOL(fc_eh_host_reset);
 int fc_slave_alloc(struct scsi_device *sdev)
 {
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
-	int queue_depth;
 
 	if (!rport || fc_remote_port_chkready(rport))
 		return -ENXIO;
 
-	if (sdev->tagged_supported) {
-		if (sdev->host->hostt->cmd_per_lun)
-			queue_depth = sdev->host->hostt->cmd_per_lun;
-		else
-			queue_depth = FC_FCP_DFLT_QUEUE_DEPTH;
-		scsi_activate_tcq(sdev, queue_depth);
-	}
+	if (sdev->tagged_supported)
+		scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
+	else
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+					FC_FCP_DFLT_QUEUE_DEPTH);
+
 	return 0;
 }
 EXPORT_SYMBOL(fc_slave_alloc);
 
-int fc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+/**
+ * fc_change_queue_depth() - Change a device's queue depth
+ * @sdev:   The SCSI device whose queue depth is to change
+ * @qdepth: The new queue depth
+ * @reason: The resason for the change
+ */
+int fc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, qdepth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL(fc_change_queue_depth);
 
+/**
+ * fc_change_queue_type() - Change a device's queue type
+ * @sdev:     The SCSI device whose queue depth is to change
+ * @tag_type: Identifier for queue type
+ */
 int fc_change_queue_type(struct scsi_device *sdev, int tag_type)
 {
 	if (sdev->tagged_supported) {
@@ -2084,39 +2155,71 @@ int fc_change_queue_type(struct scsi_dev
 }
 EXPORT_SYMBOL(fc_change_queue_type);
 
-void fc_fcp_destroy(struct fc_lport *lp)
+/**
+ * fc_fcp_destory() - Tear down the FCP layer for a given local port
+ * @lport: The local port that no longer needs the FCP layer
+ */
+void fc_fcp_destroy(struct fc_lport *lport)
 {
-	struct fc_fcp_internal *si = fc_get_scsi_internal(lp);
+	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
 
 	if (!list_empty(&si->scsi_pkt_queue))
 		printk(KERN_ERR "libfc: Leaked SCSI packets when destroying "
-		       "port (%6x)\n", fc_host_port_id(lp->host));
+		       "port (%6x)\n", fc_host_port_id(lport->host));
 
 	mempool_destroy(si->scsi_pkt_pool);
 	kfree(si);
-	lp->scsi_priv = NULL;
+	lport->scsi_priv = NULL;
 }
 EXPORT_SYMBOL(fc_fcp_destroy);
 
-int fc_fcp_init(struct fc_lport *lp)
+int fc_setup_fcp()
+{
+	int rc = 0;
+
+	scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt",
+					    sizeof(struct fc_fcp_pkt),
+					    0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!scsi_pkt_cachep) {
+		printk(KERN_ERR "libfc: Unable to allocate SRB cache, "
+		       "module load failed!");
+		rc = -ENOMEM;
+	}
+
+	return rc;
+}
+
+void fc_destroy_fcp()
+{
+	if (scsi_pkt_cachep)
+		kmem_cache_destroy(scsi_pkt_cachep);
+}
+
+/**
+ * fc_fcp_init() - Initialize the FCP layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
+int fc_fcp_init(struct fc_lport *lport)
 {
 	int rc;
 	struct fc_fcp_internal *si;
 
-	if (!lp->tt.fcp_cmd_send)
-		lp->tt.fcp_cmd_send = fc_fcp_cmd_send;
+	if (!lport->tt.fcp_cmd_send)
+		lport->tt.fcp_cmd_send = fc_fcp_cmd_send;
 
-	if (!lp->tt.fcp_cleanup)
-		lp->tt.fcp_cleanup = fc_fcp_cleanup;
+	if (!lport->tt.fcp_cleanup)
+		lport->tt.fcp_cleanup = fc_fcp_cleanup;
 
-	if (!lp->tt.fcp_abort_io)
-		lp->tt.fcp_abort_io = fc_fcp_abort_io;
+	if (!lport->tt.fcp_abort_io)
+		lport->tt.fcp_abort_io = fc_fcp_abort_io;
 
 	si = kzalloc(sizeof(struct fc_fcp_internal), GFP_KERNEL);
 	if (!si)
 		return -ENOMEM;
-	lp->scsi_priv = si;
+	lport->scsi_priv = si;
+	si->max_can_queue = lport->host->can_queue;
 	INIT_LIST_HEAD(&si->scsi_pkt_queue);
+	spin_lock_init(&si->scsi_queue_lock);
 
 	si->scsi_pkt_pool = mempool_create_slab_pool(2, scsi_pkt_cachep);
 	if (!si->scsi_pkt_pool) {
@@ -2130,42 +2233,3 @@ free_internal:
 	return rc;
 }
 EXPORT_SYMBOL(fc_fcp_init);
-
-static int __init libfc_init(void)
-{
-	int rc;
-
-	scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt",
-					    sizeof(struct fc_fcp_pkt),
-					    0, SLAB_HWCACHE_ALIGN, NULL);
-	if (scsi_pkt_cachep == NULL) {
-		printk(KERN_ERR "libfc: Unable to allocate SRB cache, "
-		       "module load failed!");
-		return -ENOMEM;
-	}
-
-	rc = fc_setup_exch_mgr();
-	if (rc)
-		goto destroy_pkt_cache;
-
-	rc = fc_setup_rport();
-	if (rc)
-		goto destroy_em;
-
-	return rc;
-destroy_em:
-	fc_destroy_exch_mgr();
-destroy_pkt_cache:
-	kmem_cache_destroy(scsi_pkt_cachep);
-	return rc;
-}
-
-static void __exit libfc_exit(void)
-{
-	kmem_cache_destroy(scsi_pkt_cachep);
-	fc_destroy_exch_mgr();
-	fc_destroy_rport();
-}
-
-module_init(libfc_init);
-module_exit(libfc_exit);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_frame.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_frame.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_frame.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_frame.c	2010-02-24 13:52:17.000000000 -0500
@@ -51,24 +51,24 @@ EXPORT_SYMBOL(fc_frame_crc_check);
  * Allocate a frame intended to be sent via fcoe_xmit.
  * Get an sk_buff for the frame and set the length.
  */
-struct fc_frame *__fc_frame_alloc(size_t len)
+struct fc_frame *_fc_frame_alloc(size_t len)
 {
 	struct fc_frame *fp;
 	struct sk_buff *skb;
 
 	WARN_ON((len % sizeof(u32)) != 0);
 	len += sizeof(struct fc_frame_header);
-	skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM);
+	skb = alloc_skb_fclone(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM +
+			       NET_SKB_PAD, GFP_ATOMIC);
 	if (!skb)
 		return NULL;
+	skb_reserve(skb, NET_SKB_PAD + FC_FRAME_HEADROOM);
 	fp = (struct fc_frame *) skb;
 	fc_frame_init(fp);
-	skb_reserve(skb, FC_FRAME_HEADROOM);
 	skb_put(skb, len);
 	return fp;
 }
-EXPORT_SYMBOL(__fc_frame_alloc);
-
+EXPORT_SYMBOL(_fc_frame_alloc);
 
 struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len)
 {
@@ -78,7 +78,7 @@ struct fc_frame *fc_frame_alloc_fill(str
 	fill = payload_len % 4;
 	if (fill != 0)
 		fill = 4 - fill;
-	fp = __fc_frame_alloc(payload_len + fill);
+	fp = _fc_frame_alloc(payload_len + fill);
 	if (fp) {
 		memset((char *) fr_hdr(fp) + payload_len, 0, fill);
 		/* trim is OK, we just allocated it so there are no fragments */
@@ -87,3 +87,4 @@ struct fc_frame *fc_frame_alloc_fill(str
 	}
 	return fp;
 }
+EXPORT_SYMBOL(fc_frame_alloc_fill);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_libfc.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_libfc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_libfc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_libfc.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,134 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/scatterlist.h>
+#include <linux/crc32.h>
+
+#include <scsi/libfc.h>
+
+#include "fc_libfc.h"
+
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("libfc");
+MODULE_LICENSE("GPL v2");
+
+unsigned int fc_debug_logging;
+module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
+
+/**
+ * libfc_init() - Initialize libfc.ko
+ */
+static int __init libfc_init(void)
+{
+	int rc = 0;
+
+	rc = fc_setup_fcp();
+	if (rc)
+		return rc;
+
+	rc = fc_setup_exch_mgr();
+	if (rc)
+		goto destroy_pkt_cache;
+
+	rc = fc_setup_rport();
+	if (rc)
+		goto destroy_em;
+
+	return rc;
+destroy_em:
+	fc_destroy_exch_mgr();
+destroy_pkt_cache:
+	fc_destroy_fcp();
+	return rc;
+}
+module_init(libfc_init);
+
+/**
+ * libfc_exit() - Tear down libfc.ko
+ */
+static void __exit libfc_exit(void)
+{
+	fc_destroy_fcp();
+	fc_destroy_exch_mgr();
+	fc_destroy_rport();
+}
+module_exit(libfc_exit);
+
+/**
+ * fc_copy_buffer_to_sglist() - This routine copies the data of a buffer
+ *				into a scatter-gather list (SG list).
+ *
+ * @buf: pointer to the data buffer.
+ * @len: the byte-length of the data buffer.
+ * @sg: pointer to the pointer of the SG list.
+ * @nents: pointer to the remaining number of entries in the SG list.
+ * @offset: pointer to the current offset in the SG list.
+ * @km_type: dedicated page table slot type for kmap_atomic.
+ * @crc: pointer to the 32-bit crc value.
+ *	 If crc is NULL, CRC is not calculated.
+ */
+u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
+			     struct scatterlist *sg,
+			     u32 *nents, size_t *offset,
+			     enum km_type km_type, u32 *crc)
+{
+	size_t remaining = len;
+	u32 copy_len = 0;
+
+	while (remaining > 0 && sg) {
+		size_t off, sg_bytes;
+		void *page_addr;
+
+		if (*offset >= sg->length) {
+			/*
+			 * Check for end and drop resources
+			 * from the last iteration.
+			 */
+			if (!(*nents))
+				break;
+			--(*nents);
+			*offset -= sg->length;
+			sg = sg_next(sg);
+			continue;
+		}
+		sg_bytes = min(remaining, sg->length - *offset);
+
+		/*
+		 * The scatterlist item may be bigger than PAGE_SIZE,
+		 * but we are limited to mapping PAGE_SIZE at a time.
+		 */
+		off = *offset + sg->offset;
+		sg_bytes = min(sg_bytes,
+			       (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
+		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT),
+					km_type);
+		if (crc)
+			*crc = crc32(*crc, buf, sg_bytes);
+		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes);
+		kunmap_atomic(page_addr, km_type);
+		buf += sg_bytes;
+		*offset += sg_bytes;
+		remaining -= sg_bytes;
+		copy_len += sg_bytes;
+	}
+	return copy_len;
+}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_libfc.h linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_libfc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_libfc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_libfc.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_LIBFC_H_
+#define _FC_LIBFC_H_
+
+#define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */
+#define FC_LPORT_LOGGING 0x02 /* lport layer logging */
+#define FC_DISC_LOGGING	 0x04 /* discovery layer logging */
+#define FC_RPORT_LOGGING 0x08 /* rport layer logging */
+#define FC_FCP_LOGGING	 0x10 /* I/O path logging */
+#define FC_EM_LOGGING	 0x20 /* Exchange Manager logging */
+#define FC_EXCH_LOGGING	 0x40 /* Exchange/Sequence logging */
+#define FC_SCSI_LOGGING	 0x80 /* SCSI logging (mostly error handling) */
+
+extern unsigned int fc_debug_logging;
+
+#define FC_CHECK_LOGGING(LEVEL, CMD)			\
+	do {						\
+		if (unlikely(fc_debug_logging & LEVEL))	\
+			do {				\
+				CMD;			\
+			} while (0);			\
+	} while (0)
+
+#define FC_LIBFC_DBG(fmt, args...)					\
+	FC_CHECK_LOGGING(FC_LIBFC_LOGGING,				\
+			 printk(KERN_INFO "libfc: " fmt, ##args))
+
+#define FC_LPORT_DBG(lport, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_LPORT_LOGGING,				\
+			 printk(KERN_INFO "host%u: lport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				fc_host_port_id((lport)->host), ##args))
+
+#define FC_DISC_DBG(disc, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_DISC_LOGGING,			\
+			 printk(KERN_INFO "host%u: disc: " fmt,	\
+				(disc)->lport->host->host_no,	\
+				##args))
+
+#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)			\
+	FC_CHECK_LOGGING(FC_RPORT_LOGGING,				\
+			 printk(KERN_INFO "host%u: rport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				(port_id), ##args))
+
+#define FC_RPORT_DBG(rdata, fmt, args...)				\
+	FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
+
+#define FC_FCP_DBG(pkt, fmt, args...)					\
+	FC_CHECK_LOGGING(FC_FCP_LOGGING,				\
+			 printk(KERN_INFO "host%u: fcp: %6x: " fmt,	\
+				(pkt)->lp->host->host_no,		\
+				pkt->rport->port_id, ##args))
+
+#define FC_EXCH_DBG(exch, fmt, args...)					\
+	FC_CHECK_LOGGING(FC_EXCH_LOGGING,				\
+			 printk(KERN_INFO "host%u: xid %4x: " fmt,	\
+				(exch)->lp->host->host_no,		\
+				exch->xid, ##args))
+
+#define FC_SCSI_DBG(lport, fmt, args...)				\
+	FC_CHECK_LOGGING(FC_SCSI_LOGGING,				\
+			 printk(KERN_INFO "host%u: scsi: " fmt,		\
+				(lport)->host->host_no,	##args))
+
+/*
+ * Set up direct-data placement for this I/O request
+ */
+void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
+
+/*
+ * Module setup functions
+ */
+int fc_setup_exch_mgr(void);
+void fc_destroy_exch_mgr(void);
+int fc_setup_rport(void);
+void fc_destroy_rport(void);
+int fc_setup_fcp(void);
+void fc_destroy_fcp(void);
+
+/*
+ * Internal libfc functions
+ */
+const char *fc_els_resp_type(struct fc_frame *);
+
+/*
+ * Copies a buffer into an sg list
+ */
+u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
+			     struct scatterlist *sg,
+			     u32 *nents, size_t *offset,
+			     enum km_type km_type, u32 *crc);
+
+#endif /* _FC_LIBFC_H_ */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_lport.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_lport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_lport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_lport.c	2010-02-24 13:52:17.000000000 -0500
@@ -56,7 +56,7 @@
  * at the same time.
  *
  * When discovery succeeds or fails a callback is made to the lport as
- * notification. Currently, succesful discovery causes the lport to take no
+ * notification. Currently, successful discovery causes the lport to take no
  * action. A failure will cause the lport to reset. There is likely a circular
  * locking problem with this implementation.
  */
@@ -94,6 +94,9 @@
 
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
+#include <linux/scatterlist.h>
+
+#include "fc_libfc.h"
 
 /* Fabric IDs to use for point-to-point mode, chosen on whims. */
 #define FC_LOCAL_PTP_FID_LO   0x010101
@@ -106,8 +109,7 @@ static void fc_lport_error(struct fc_lpo
 static void fc_lport_enter_reset(struct fc_lport *);
 static void fc_lport_enter_flogi(struct fc_lport *);
 static void fc_lport_enter_dns(struct fc_lport *);
-static void fc_lport_enter_rpn_id(struct fc_lport *);
-static void fc_lport_enter_rft_id(struct fc_lport *);
+static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
 static void fc_lport_enter_scr(struct fc_lport *);
 static void fc_lport_enter_ready(struct fc_lport *);
 static void fc_lport_enter_logo(struct fc_lport *);
@@ -116,14 +118,40 @@ static const char *fc_lport_state_names[
 	[LPORT_ST_DISABLED] = "disabled",
 	[LPORT_ST_FLOGI] =    "FLOGI",
 	[LPORT_ST_DNS] =      "dNS",
-	[LPORT_ST_RPN_ID] =   "RPN_ID",
+	[LPORT_ST_RNN_ID] =   "RNN_ID",
+	[LPORT_ST_RSNN_NN] =  "RSNN_NN",
+	[LPORT_ST_RSPN_ID] =  "RSPN_ID",
 	[LPORT_ST_RFT_ID] =   "RFT_ID",
+	[LPORT_ST_RFF_ID] =   "RFF_ID",
 	[LPORT_ST_SCR] =      "SCR",
 	[LPORT_ST_READY] =    "Ready",
 	[LPORT_ST_LOGO] =     "LOGO",
 	[LPORT_ST_RESET] =    "reset",
 };
 
+/**
+ * struct fc_bsg_info - FC Passthrough managemet structure
+ * @job:      The passthrough job
+ * @lport:    The local port to pass through a command
+ * @rsp_code: The expected response code
+ * @sg:	      job->reply_payload.sg_list
+ * @nents:    job->reply_payload.sg_cnt
+ * @offset:   The offset into the response data
+ */
+struct fc_bsg_info {
+	struct fc_bsg_job *job;
+	struct fc_lport *lport;
+	u16 rsp_code;
+	struct scatterlist *sg;
+	u32 nents;
+	size_t offset;
+};
+
+/**
+ * fc_frame_drop() - Dummy frame handler
+ * @lport: The local port the frame was received on
+ * @fp:	   The received frame
+ */
 static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
 {
 	fc_frame_free(fp);
@@ -150,8 +178,8 @@ static void fc_lport_rport_callback(stru
 	switch (event) {
 	case RPORT_EV_READY:
 		if (lport->state == LPORT_ST_DNS) {
-			lport->dns_rp = rdata;
-			fc_lport_enter_rpn_id(lport);
+			lport->dns_rdata = rdata;
+			fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
 		} else {
 			FC_LPORT_DBG(lport, "Received an READY event "
 				     "on port (%6x) for the directory "
@@ -165,7 +193,7 @@ static void fc_lport_rport_callback(stru
 	case RPORT_EV_LOGO:
 	case RPORT_EV_FAILED:
 	case RPORT_EV_STOP:
-		lport->dns_rp = NULL;
+		lport->dns_rdata = NULL;
 		break;
 	case RPORT_EV_NONE:
 		break;
@@ -189,8 +217,8 @@ static const char *fc_lport_state(struct
 
 /**
  * fc_lport_ptp_setup() - Create an rport for point-to-point mode
- * @lport: The lport to attach the ptp rport to
- * @fid: The FID of the ptp rport
+ * @lport:	 The lport to attach the ptp rport to
+ * @remote_fid:	 The FID of the ptp rport
  * @remote_wwpn: The WWPN of the ptp rport
  * @remote_wwnn: The WWNN of the ptp rport
  */
@@ -199,18 +227,22 @@ static void fc_lport_ptp_setup(struct fc
 			       u64 remote_wwnn)
 {
 	mutex_lock(&lport->disc.disc_mutex);
-	if (lport->ptp_rp)
-		lport->tt.rport_logoff(lport->ptp_rp);
-	lport->ptp_rp = lport->tt.rport_create(lport, remote_fid);
-	lport->ptp_rp->ids.port_name = remote_wwpn;
-	lport->ptp_rp->ids.node_name = remote_wwnn;
+	if (lport->ptp_rdata)
+		lport->tt.rport_logoff(lport->ptp_rdata);
+	lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid);
+	lport->ptp_rdata->ids.port_name = remote_wwpn;
+	lport->ptp_rdata->ids.node_name = remote_wwnn;
 	mutex_unlock(&lport->disc.disc_mutex);
 
-	lport->tt.rport_login(lport->ptp_rp);
+	lport->tt.rport_login(lport->ptp_rdata);
 
 	fc_lport_enter_ready(lport);
 }
 
+/**
+ * fc_get_host_port_type() - Return the port type of the given Scsi_Host
+ * @shost: The SCSI host whose port type is to be determined
+ */
 void fc_get_host_port_type(struct Scsi_Host *shost)
 {
 	/* TODO - currently just NPORT */
@@ -218,17 +250,33 @@ void fc_get_host_port_type(struct Scsi_H
 }
 EXPORT_SYMBOL(fc_get_host_port_type);
 
+/**
+ * fc_get_host_port_state() - Return the port state of the given Scsi_Host
+ * @shost:  The SCSI host whose port state is to be determined
+ */
 void fc_get_host_port_state(struct Scsi_Host *shost)
 {
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 
-	if (lp->link_up)
-		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+	mutex_lock(&lport->lp_mutex);
+	if (!lport->link_up)
+		fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
 	else
-		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+		switch (lport->state) {
+		case LPORT_ST_READY:
+			fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+			break;
+		default:
+			fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+		}
+	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_get_host_port_state);
 
+/**
+ * fc_get_host_speed() - Return the speed of the given Scsi_Host
+ * @shost: The SCSI host whose port speed is to be determined
+ */
 void fc_get_host_speed(struct Scsi_Host *shost)
 {
 	struct fc_lport *lport = shost_priv(shost);
@@ -237,24 +285,28 @@ void fc_get_host_speed(struct Scsi_Host
 }
 EXPORT_SYMBOL(fc_get_host_speed);
 
+/**
+ * fc_get_host_stats() - Return the Scsi_Host's statistics
+ * @shost: The SCSI host whose statistics are to be returned
+ */
 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
 {
 	struct fc_host_statistics *fcoe_stats;
-	struct fc_lport *lp = shost_priv(shost);
+	struct fc_lport *lport = shost_priv(shost);
 	struct timespec v0, v1;
 	unsigned int cpu;
 
-	fcoe_stats = &lp->host_stats;
+	fcoe_stats = &lport->host_stats;
 	memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
 
 	jiffies_to_timespec(jiffies, &v0);
-	jiffies_to_timespec(lp->boot_time, &v1);
+	jiffies_to_timespec(lport->boot_time, &v1);
 	fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
 
 	for_each_possible_cpu(cpu) {
 		struct fcoe_dev_stats *stats;
 
-		stats = per_cpu_ptr(lp->dev_stats, cpu);
+		stats = per_cpu_ptr(lport->dev_stats, cpu);
 
 		fcoe_stats->tx_frames += stats->TxFrames;
 		fcoe_stats->tx_words += stats->TxWords;
@@ -279,12 +331,15 @@ struct fc_host_statistics *fc_get_host_s
 }
 EXPORT_SYMBOL(fc_get_host_stats);
 
-/*
- * Fill in FLOGI command for request.
+/**
+ * fc_lport_flogi_fill() - Fill in FLOGI command for request
+ * @lport: The local port the FLOGI is for
+ * @flogi: The FLOGI command
+ * @op:	   The opcode
  */
-static void
-fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi,
-		    unsigned int op)
+static void fc_lport_flogi_fill(struct fc_lport *lport,
+				struct fc_els_flogi *flogi,
+				unsigned int op)
 {
 	struct fc_els_csp *sp;
 	struct fc_els_cssp *cp;
@@ -312,8 +367,10 @@ fc_lport_flogi_fill(struct fc_lport *lpo
 	}
 }
 
-/*
- * Add a supported FC-4 type.
+/**
+ * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
+ * @lport: The local port to add a new FC-4 type to
+ * @type:  The new FC-4 type
  */
 static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
 {
@@ -325,11 +382,11 @@ static void fc_lport_add_fc4_type(struct
 
 /**
  * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
+ * @sp:	   The sequence in the RLIR exchange
+ * @fp:	   The RLIR request frame
  * @lport: Fibre Channel local port recieving the RLIR
- * @sp: current sequence in the RLIR exchange
- * @fp: RLIR request frame
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
@@ -344,11 +401,11 @@ static void fc_lport_recv_rlir_req(struc
 
 /**
  * fc_lport_recv_echo_req() - Handle received ECHO request
- * @lport: Fibre Channel local port recieving the ECHO
- * @sp: current sequence in the ECHO exchange
- * @fp: ECHO request frame
+ * @sp:	   The sequence in the ECHO exchange
+ * @fp:	   ECHO request frame
+ * @lport: The local port recieving the ECHO
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -361,7 +418,7 @@ static void fc_lport_recv_echo_req(struc
 	void *dp;
 	u32 f_ctl;
 
-	FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
+	FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
 		     fc_lport_state(lport));
 
 	len = fr_len(in_fp) - sizeof(struct fc_frame_header);
@@ -374,7 +431,7 @@ static void fc_lport_recv_echo_req(struc
 	if (fp) {
 		dp = fc_frame_payload_get(fp, len);
 		memcpy(dp, pp, len);
-		*((u32 *)dp) = htonl(ELS_LS_ACC << 24);
+		*((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
 		sp = lport->tt.seq_start_next(sp);
 		f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
 		fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
@@ -385,12 +442,12 @@ static void fc_lport_recv_echo_req(struc
 }
 
 /**
- * fc_lport_recv_echo_req() - Handle received Request Node ID data request
- * @lport: Fibre Channel local port recieving the RNID
- * @sp: current sequence in the RNID exchange
- * @fp: RNID request frame
+ * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
+ * @sp:	   The sequence in the RNID exchange
+ * @fp:	   The RNID request frame
+ * @lport: The local port recieving the RNID
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
@@ -453,9 +510,9 @@ static void fc_lport_recv_rnid_req(struc
 
 /**
  * fc_lport_recv_logo_req() - Handle received fabric LOGO request
- * @lport: Fibre Channel local port recieving the LOGO
- * @sp: current sequence in the LOGO exchange
- * @fp: LOGO request frame
+ * @sp:	   The sequence in the LOGO exchange
+ * @fp:	   The LOGO request frame
+ * @lport: The local port recieving the LOGO
  *
  * Locking Note: The lport lock is exected to be held before calling
  * this function.
@@ -470,7 +527,7 @@ static void fc_lport_recv_logo_req(struc
 
 /**
  * fc_fabric_login() - Start the lport state machine
- * @lport: The lport that should log into the fabric
+ * @lport: The local port that should log into the fabric
  *
  * Locking Note: This function should not be called
  *		 with the lport lock held.
@@ -480,7 +537,9 @@ int fc_fabric_login(struct fc_lport *lpo
 	int rc = -1;
 
 	mutex_lock(&lport->lp_mutex);
-	if (lport->state == LPORT_ST_DISABLED) {
+	if (lport->state == LPORT_ST_DISABLED ||
+	    lport->state == LPORT_ST_LOGO) {
+		fc_lport_state_enter(lport, LPORT_ST_RESET);
 		fc_lport_enter_reset(lport);
 		rc = 0;
 	}
@@ -491,47 +550,69 @@ int fc_fabric_login(struct fc_lport *lpo
 EXPORT_SYMBOL(fc_fabric_login);
 
 /**
- * fc_linkup() - Handler for transport linkup events
+ * __fc_linkup() - Handler for transport linkup events
  * @lport: The lport whose link is up
+ *
+ * Locking: must be called with the lp_mutex held
  */
-void fc_linkup(struct fc_lport *lport)
+void __fc_linkup(struct fc_lport *lport)
 {
-	printk(KERN_INFO "libfc: Link up on port (%6x)\n",
-	       fc_host_port_id(lport->host));
-
-	mutex_lock(&lport->lp_mutex);
 	if (!lport->link_up) {
 		lport->link_up = 1;
 
 		if (lport->state == LPORT_ST_RESET)
 			fc_lport_enter_flogi(lport);
 	}
+}
+
+/**
+ * fc_linkup() - Handler for transport linkup events
+ * @lport: The local port whose link is up
+ */
+void fc_linkup(struct fc_lport *lport)
+{
+	printk(KERN_INFO "host%d: libfc: Link up on port (%6x)\n",
+	       lport->host->host_no, fc_host_port_id(lport->host));
+
+	mutex_lock(&lport->lp_mutex);
+	__fc_linkup(lport);
 	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkup);
 
 /**
- * fc_linkdown() - Handler for transport linkdown events
+ * __fc_linkdown() - Handler for transport linkdown events
  * @lport: The lport whose link is down
+ *
+ * Locking: must be called with the lp_mutex held
  */
-void fc_linkdown(struct fc_lport *lport)
+void __fc_linkdown(struct fc_lport *lport)
 {
-	mutex_lock(&lport->lp_mutex);
-	printk(KERN_INFO "libfc: Link down on port (%6x)\n",
-	       fc_host_port_id(lport->host));
-
 	if (lport->link_up) {
 		lport->link_up = 0;
 		fc_lport_enter_reset(lport);
 		lport->tt.fcp_cleanup(lport);
 	}
+}
+
+/**
+ * fc_linkdown() - Handler for transport linkdown events
+ * @lport: The local port whose link is down
+ */
+void fc_linkdown(struct fc_lport *lport)
+{
+	printk(KERN_INFO "host%d: libfc: Link down on port (%6x)\n",
+	       lport->host->host_no, fc_host_port_id(lport->host));
+
+	mutex_lock(&lport->lp_mutex);
+	__fc_linkdown(lport);
 	mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkdown);
 
 /**
  * fc_fabric_logoff() - Logout of the fabric
- * @lport:	      fc_lport pointer to logoff the fabric
+ * @lport: The local port to logoff the fabric
  *
  * Return value:
  *	0 for success, -1 for failure
@@ -540,8 +621,8 @@ int fc_fabric_logoff(struct fc_lport *lp
 {
 	lport->tt.disc_stop_final(lport);
 	mutex_lock(&lport->lp_mutex);
-	if (lport->dns_rp)
-		lport->tt.rport_logoff(lport->dns_rp);
+	if (lport->dns_rdata)
+		lport->tt.rport_logoff(lport->dns_rdata);
 	mutex_unlock(&lport->lp_mutex);
 	lport->tt.rport_flush_queue();
 	mutex_lock(&lport->lp_mutex);
@@ -553,11 +634,9 @@ int fc_fabric_logoff(struct fc_lport *lp
 EXPORT_SYMBOL(fc_fabric_logoff);
 
 /**
- * fc_lport_destroy() - unregister a fc_lport
- * @lport:	      fc_lport pointer to unregister
+ * fc_lport_destroy() - Unregister a fc_lport
+ * @lport: The local port to unregister
  *
- * Return value:
- *	None
  * Note:
  * exit routine for fc_lport instance
  * clean-up all the allocated memory
@@ -580,13 +659,9 @@ int fc_lport_destroy(struct fc_lport *lp
 EXPORT_SYMBOL(fc_lport_destroy);
 
 /**
- * fc_set_mfs() - sets up the mfs for the corresponding fc_lport
- * @lport: fc_lport pointer to unregister
- * @mfs: the new mfs for fc_lport
- *
- * Set mfs for the given fc_lport to the new mfs.
- *
- * Return: 0 for success
+ * fc_set_mfs() - Set the maximum frame size for a local port
+ * @lport: The local port to set the MFS for
+ * @mfs:   The new MFS
  */
 int fc_set_mfs(struct fc_lport *lport, u32 mfs)
 {
@@ -617,7 +692,7 @@ EXPORT_SYMBOL(fc_set_mfs);
 
 /**
  * fc_lport_disc_callback() - Callback for discovery events
- * @lport: FC local port
+ * @lport: The local port receiving the event
  * @event: The discovery event
  */
 void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
@@ -627,8 +702,9 @@ void fc_lport_disc_callback(struct fc_lp
 		FC_LPORT_DBG(lport, "Discovery succeeded\n");
 		break;
 	case DISC_EV_FAILED:
-		printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n",
-		       fc_host_port_id(lport->host));
+		printk(KERN_ERR "host%d: libfc: "
+		       "Discovery failed for port (%6x)\n",
+		       lport->host->host_no, fc_host_port_id(lport->host));
 		mutex_lock(&lport->lp_mutex);
 		fc_lport_enter_reset(lport);
 		mutex_unlock(&lport->lp_mutex);
@@ -641,7 +717,7 @@ void fc_lport_disc_callback(struct fc_lp
 
 /**
  * fc_rport_enter_ready() - Enter the ready state and start discovery
- * @lport: Fibre Channel local port that is ready
+ * @lport: The local port that is ready
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -652,22 +728,46 @@ static void fc_lport_enter_ready(struct
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_READY);
+	if (lport->vport)
+		fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
+	fc_vports_linkchange(lport);
 
-	if (!lport->ptp_rp)
+	if (!lport->ptp_rdata)
 		lport->tt.disc_start(fc_lport_disc_callback, lport);
 }
 
 /**
+ * fc_lport_set_port_id() - set the local port Port ID
+ * @lport: The local port which will have its Port ID set.
+ * @port_id: The new port ID.
+ * @fp: The frame containing the incoming request, or NULL.
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this function.
+ */
+static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
+				 struct fc_frame *fp)
+{
+	if (port_id)
+		printk(KERN_INFO "host%d: Assigned Port ID %6x\n",
+		       lport->host->host_no, port_id);
+
+	fc_host_port_id(lport->host) = port_id;
+	if (lport->tt.lport_set_port_id)
+		lport->tt.lport_set_port_id(lport, port_id, fp);
+}
+
+/**
  * fc_lport_recv_flogi_req() - Receive a FLOGI request
  * @sp_in: The sequence the FLOGI is on
- * @rx_fp: The frame the FLOGI is in
- * @lport: The lport that recieved the request
+ * @rx_fp: The FLOGI frame
+ * @lport: The local port that recieved the request
  *
  * A received FLOGI request indicates a point-to-point connection.
  * Accept it with the common service parameters indicating our N port.
  * Set up to do a PLOGI if we have the higher-number WWPN.
  *
- * Locking Note: The lport lock is exected to be held before calling
+ * Locking Note: The lport lock is expected to be held before calling
  * this function.
  */
 static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
@@ -695,8 +795,9 @@ static void fc_lport_recv_flogi_req(stru
 		goto out;
 	remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
 	if (remote_wwpn == lport->wwpn) {
-		printk(KERN_WARNING "libfc: Received FLOGI from port "
-		       "with same WWPN %llx\n", remote_wwpn);
+		printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
+		       "with same WWPN %llx\n",
+		       lport->host->host_no, remote_wwpn);
 		goto out;
 	}
 	FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn);
@@ -715,7 +816,7 @@ static void fc_lport_recv_flogi_req(stru
 		remote_fid = FC_LOCAL_PTP_FID_HI;
 	}
 
-	fc_host_port_id(lport->host) = local_fid;
+	fc_lport_set_port_id(lport, local_fid, rx_fp);
 
 	fp = fc_frame_alloc(lport, sizeof(*flp));
 	if (fp) {
@@ -747,9 +848,9 @@ out:
 
 /**
  * fc_lport_recv_req() - The generic lport request handler
- * @lport: The lport that received the request
- * @sp: The sequence the request is on
- * @fp: The frame the request is in
+ * @lport: The local port that received the request
+ * @sp:	   The sequence the request is on
+ * @fp:	   The request frame
  *
  * This function will see if the lport handles the request or
  * if an rport should handle the request.
@@ -817,8 +918,8 @@ static void fc_lport_recv_req(struct fc_
 }
 
 /**
- * fc_lport_reset() - Reset an lport
- * @lport: The lport which should be reset
+ * fc_lport_reset() - Reset a local port
+ * @lport: The local port which should be reset
  *
  * Locking Note: This functions should not be called with the
  *		 lport lock held.
@@ -834,29 +935,31 @@ int fc_lport_reset(struct fc_lport *lpor
 EXPORT_SYMBOL(fc_lport_reset);
 
 /**
- * fc_lport_reset_locked() - Reset the local port
- * @lport: Fibre Channel local port to be reset
+ * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
 static void fc_lport_reset_locked(struct fc_lport *lport)
 {
-	if (lport->dns_rp)
-		lport->tt.rport_logoff(lport->dns_rp);
+	if (lport->dns_rdata)
+		lport->tt.rport_logoff(lport->dns_rdata);
 
-	lport->ptp_rp = NULL;
+	lport->ptp_rdata = NULL;
 
 	lport->tt.disc_stop(lport);
 
 	lport->tt.exch_mgr_reset(lport, 0, 0);
 	fc_host_fabric_name(lport->host) = 0;
-	fc_host_port_id(lport->host) = 0;
+
+	if (fc_host_port_id(lport->host))
+		fc_lport_set_port_id(lport, 0, NULL);
 }
 
 /**
  * fc_lport_enter_reset() - Reset the local port
- * @lport: Fibre Channel local port to be reset
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -866,15 +969,25 @@ static void fc_lport_enter_reset(struct
 	FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
 		     fc_lport_state(lport));
 
+	if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
+		return;
+
+	if (lport->vport) {
+		if (lport->link_up)
+			fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
+		else
+			fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
+	}
 	fc_lport_state_enter(lport, LPORT_ST_RESET);
+	fc_vports_linkchange(lport);
 	fc_lport_reset_locked(lport);
 	if (lport->link_up)
 		fc_lport_enter_flogi(lport);
 }
 
 /**
- * fc_lport_enter_disabled() - disable the local port
- * @lport: Fibre Channel local port to be reset
+ * fc_lport_enter_disabled() - Disable the local port
+ * @lport: The local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -885,13 +998,14 @@ static void fc_lport_enter_disabled(stru
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
+	fc_vports_linkchange(lport);
 	fc_lport_reset_locked(lport);
 }
 
 /**
  * fc_lport_error() - Handler for any errors
- * @lport: The fc_lport object
- * @fp: The frame pointer
+ * @lport: The local port that the error was on
+ * @fp:	   The error code encoded in a frame pointer
  *
  * If the error was caused by a resource allocation failure
  * then wait for half a second and retry, otherwise retry
@@ -922,8 +1036,11 @@ static void fc_lport_error(struct fc_lpo
 			case LPORT_ST_DISABLED:
 			case LPORT_ST_READY:
 			case LPORT_ST_RESET:
-			case LPORT_ST_RPN_ID:
+			case LPORT_ST_RNN_ID:
+			case LPORT_ST_RSNN_NN:
+			case LPORT_ST_RSPN_ID:
 			case LPORT_ST_RFT_ID:
+			case LPORT_ST_RFF_ID:
 			case LPORT_ST_SCR:
 			case LPORT_ST_DNS:
 			case LPORT_ST_FLOGI:
@@ -936,33 +1053,33 @@ static void fc_lport_error(struct fc_lpo
 }
 
 /**
- * fc_lport_rft_id_resp() - Handle response to Register Fibre
- *			    Channel Types by ID (RPN_ID) request
- * @sp: current sequence in RPN_ID exchange
- * @fp: response frame
+ * fc_lport_ns_resp() - Handle response to a name server
+ *			registration exchange
+ * @sp:	    current sequence in exchange
+ * @fp:	    response frame
  * @lp_arg: Fibre Channel host port instance
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
-				 void *lp_arg)
+static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
+			     void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	struct fc_frame_header *fh;
 	struct fc_ct_hdr *ct;
 
-	FC_LPORT_DBG(lport, "Received a RFT_ID %s\n", fc_els_resp_type(fp));
+	FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
 
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	if (lport->state != LPORT_ST_RFT_ID) {
-		FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state "
-			     "%s\n", fc_lport_state(lport));
+	if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
+		FC_LPORT_DBG(lport, "Received a name server response, "
+			     "but in state %s\n", fc_lport_state(lport));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
@@ -980,63 +1097,28 @@ static void fc_lport_rft_id_resp(struct
 	    ct->ct_fs_type == FC_FST_DIR &&
 	    ct->ct_fs_subtype == FC_NS_SUBTYPE &&
 	    ntohs(ct->ct_cmd) == FC_FS_ACC)
-		fc_lport_enter_scr(lport);
-	else
-		fc_lport_error(lport, fp);
-out:
-	fc_frame_free(fp);
-err:
-	mutex_unlock(&lport->lp_mutex);
-}
-
-/**
- * fc_lport_rpn_id_resp() - Handle response to Register Port
- *			    Name by ID (RPN_ID) request
- * @sp: current sequence in RPN_ID exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel host port instance
- *
- * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
- * and then unlock the lport.
- */
-static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
-				 void *lp_arg)
-{
-	struct fc_lport *lport = lp_arg;
-	struct fc_frame_header *fh;
-	struct fc_ct_hdr *ct;
-
-	FC_LPORT_DBG(lport, "Received a RPN_ID %s\n", fc_els_resp_type(fp));
-
-	if (fp == ERR_PTR(-FC_EX_CLOSED))
-		return;
-
-	mutex_lock(&lport->lp_mutex);
-
-	if (lport->state != LPORT_ST_RPN_ID) {
-		FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state "
-			     "%s\n", fc_lport_state(lport));
-		if (IS_ERR(fp))
-			goto err;
-		goto out;
-	}
-
-	if (IS_ERR(fp)) {
-		fc_lport_error(lport, fp);
-		goto err;
-	}
-
-	fh = fc_frame_header_get(fp);
-	ct = fc_frame_payload_get(fp, sizeof(*ct));
-	if (fh && ct && fh->fh_type == FC_TYPE_CT &&
-	    ct->ct_fs_type == FC_FST_DIR &&
-	    ct->ct_fs_subtype == FC_NS_SUBTYPE &&
-	    ntohs(ct->ct_cmd) == FC_FS_ACC)
-		fc_lport_enter_rft_id(lport);
+		switch (lport->state) {
+		case LPORT_ST_RNN_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
+			break;
+		case LPORT_ST_RSNN_NN:
+			fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
+			break;
+		case LPORT_ST_RSPN_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+			break;
+		case LPORT_ST_RFT_ID:
+			fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
+			break;
+		case LPORT_ST_RFF_ID:
+			fc_lport_enter_scr(lport);
+			break;
+		default:
+			/* should have already been caught by state checks */
+			break;
+		}
 	else
 		fc_lport_error(lport, fp);
-
 out:
 	fc_frame_free(fp);
 err:
@@ -1045,8 +1127,8 @@ err:
 
 /**
  * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
- * @sp: current sequence in SCR exchange
- * @fp: response frame
+ * @sp:	    current sequence in SCR exchange
+ * @fp:	    response frame
  * @lp_arg: Fibre Channel lport port instance that sent the registration request
  *
  * Locking Note: This function will be called without the lport lock
@@ -1092,8 +1174,8 @@ err:
 }
 
 /**
- * fc_lport_enter_scr() - Send a State Change Register (SCR) request
- * @lport: Fibre Channel local port to register for state changes
+ * fc_lport_enter_scr() - Send a SCR (State Change Register) request
+ * @lport: The local port to register for state changes
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1114,78 +1196,74 @@ static void fc_lport_enter_scr(struct fc
 	}
 
 	if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
-				  fc_lport_scr_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+				  fc_lport_scr_resp, lport,
+				  2 * lport->r_a_tov))
+		fc_lport_error(lport, NULL);
 }
 
 /**
- * fc_lport_enter_rft_id() - Register FC4-types with the name server
+ * fc_lport_enter_ns() - register some object with the name server
  * @lport: Fibre Channel local port to register
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
-static void fc_lport_enter_rft_id(struct fc_lport *lport)
+static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
 {
 	struct fc_frame *fp;
-	struct fc_ns_fts *lps;
-	int i;
+	enum fc_ns_req cmd;
+	int size = sizeof(struct fc_ct_hdr);
+	size_t len;
 
-	FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n",
+	FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
+		     fc_lport_state_names[state],
 		     fc_lport_state(lport));
 
-	fc_lport_state_enter(lport, LPORT_ST_RFT_ID);
-
-	lps = &lport->fcts;
-	i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]);
-	while (--i >= 0)
-		if (ntohl(lps->ff_type_map[i]) != 0)
-			break;
-	if (i < 0) {
-		/* nothing to register, move on to SCR */
-		fc_lport_enter_scr(lport);
-		return;
-	}
+	fc_lport_state_enter(lport, state);
 
-	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
-			    sizeof(struct fc_ns_rft));
-	if (!fp) {
-		fc_lport_error(lport, fp);
+	switch (state) {
+	case LPORT_ST_RNN_ID:
+		cmd = FC_NS_RNN_ID;
+		size += sizeof(struct fc_ns_rn_id);
+		break;
+	case LPORT_ST_RSNN_NN:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		/* if there is no symbolic name, skip to RFT_ID */
+		if (!len)
+			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+		cmd = FC_NS_RSNN_NN;
+		size += sizeof(struct fc_ns_rsnn) + len;
+		break;
+	case LPORT_ST_RSPN_ID:
+		len = strnlen(fc_host_symbolic_name(lport->host), 255);
+		/* if there is no symbolic name, skip to RFT_ID */
+		if (!len)
+			return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
+		cmd = FC_NS_RSPN_ID;
+		size += sizeof(struct fc_ns_rspn) + len;
+		break;
+	case LPORT_ST_RFT_ID:
+		cmd = FC_NS_RFT_ID;
+		size += sizeof(struct fc_ns_rft);
+		break;
+	case LPORT_ST_RFF_ID:
+		cmd = FC_NS_RFF_ID;
+		size += sizeof(struct fc_ns_rff_id);
+		break;
+	default:
+		fc_lport_error(lport, NULL);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID,
-				  fc_lport_rft_id_resp,
-				  lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
-}
-
-/**
- * fc_rport_enter_rft_id() - Register port name with the name server
- * @lport: Fibre Channel local port to register
- *
- * Locking Note: The lport lock is expected to be held before calling
- * this routine.
- */
-static void fc_lport_enter_rpn_id(struct fc_lport *lport)
-{
-	struct fc_frame *fp;
-
-	FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n",
-		     fc_lport_state(lport));
-
-	fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
-
-	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
-			    sizeof(struct fc_ns_rn_id));
+	fp = fc_frame_alloc(lport, size);
 	if (!fp) {
 		fc_lport_error(lport, fp);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID,
-				  fc_lport_rpn_id_resp,
-				  lport, lport->e_d_tov))
+	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
+				  fc_lport_ns_resp,
+				  lport, 3 * lport->r_a_tov))
 		fc_lport_error(lport, fp);
 }
 
@@ -1194,8 +1272,8 @@ static struct fc_rport_operations fc_lpo
 };
 
 /**
- * fc_rport_enter_dns() - Create a rport to the name server
- * @lport: Fibre Channel local port requesting a rport for the name server
+ * fc_rport_enter_dns() - Create a fc_rport for the name server
+ * @lport: The local port requesting a remote port for the name server
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1224,8 +1302,8 @@ err:
 }
 
 /**
- * fc_lport_timeout() - Handler for the retry_work timer.
- * @work: The work struct of the fc_lport
+ * fc_lport_timeout() - Handler for the retry_work timer
+ * @work: The work struct of the local port
  */
 static void fc_lport_timeout(struct work_struct *work)
 {
@@ -1237,21 +1315,25 @@ static void fc_lport_timeout(struct work
 
 	switch (lport->state) {
 	case LPORT_ST_DISABLED:
+		WARN_ON(1);
+		break;
 	case LPORT_ST_READY:
-	case LPORT_ST_RESET:
 		WARN_ON(1);
 		break;
+	case LPORT_ST_RESET:
+		break;
 	case LPORT_ST_FLOGI:
 		fc_lport_enter_flogi(lport);
 		break;
 	case LPORT_ST_DNS:
 		fc_lport_enter_dns(lport);
 		break;
-	case LPORT_ST_RPN_ID:
-		fc_lport_enter_rpn_id(lport);
-		break;
+	case LPORT_ST_RNN_ID:
+	case LPORT_ST_RSNN_NN:
+	case LPORT_ST_RSPN_ID:
 	case LPORT_ST_RFT_ID:
-		fc_lport_enter_rft_id(lport);
+	case LPORT_ST_RFF_ID:
+		fc_lport_enter_ns(lport, lport->state);
 		break;
 	case LPORT_ST_SCR:
 		fc_lport_enter_scr(lport);
@@ -1266,16 +1348,16 @@ static void fc_lport_timeout(struct work
 
 /**
  * fc_lport_logo_resp() - Handle response to LOGO request
- * @sp: current sequence in LOGO exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel lport port instance that sent the LOGO request
+ * @sp:	    The sequence that the LOGO was on
+ * @fp:	    The LOGO frame
+ * @lp_arg: The lport port that received the LOGO request
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
-			       void *lp_arg)
+void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
+			void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	u8 op;
@@ -1311,10 +1393,11 @@ out:
 err:
 	mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_logo_resp);
 
 /**
  * fc_rport_enter_logo() - Logout of the fabric
- * @lport: Fibre Channel local port to be logged out
+ * @lport: The local port to be logged out
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
@@ -1328,6 +1411,7 @@ static void fc_lport_enter_logo(struct f
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_LOGO);
+	fc_vports_linkchange(lport);
 
 	fp = fc_frame_alloc(lport, sizeof(*logo));
 	if (!fp) {
@@ -1336,22 +1420,23 @@ static void fc_lport_enter_logo(struct f
 	}
 
 	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
-				  fc_lport_logo_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+				  fc_lport_logo_resp, lport,
+				  2 * lport->r_a_tov))
+		fc_lport_error(lport, NULL);
 }
 
 /**
  * fc_lport_flogi_resp() - Handle response to FLOGI request
- * @sp: current sequence in FLOGI exchange
- * @fp: response frame
- * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request
+ * @sp:	    The sequence that the FLOGI was on
+ * @fp:	    The FLOGI response frame
+ * @lp_arg: The lport port that received the FLOGI response
  *
  * Locking Note: This function will be called without the lport lock
- * held, but it will lock, call an _enter_* function or fc_lport_error
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
  * and then unlock the lport.
  */
-static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
-				void *lp_arg)
+void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
+			 void *lp_arg)
 {
 	struct fc_lport *lport = lp_arg;
 	struct fc_frame_header *fh;
@@ -1385,11 +1470,6 @@ static void fc_lport_flogi_resp(struct f
 	fh = fc_frame_header_get(fp);
 	did = ntoh24(fh->fh_d_id);
 	if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
-
-		printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n",
-		       did);
-		fc_host_port_id(lport->host) = did;
-
 		flp = fc_frame_payload_get(fp, sizeof(*flp));
 		if (flp) {
 			mfs = ntohs(flp->fl_csp.sp_bb_data) &
@@ -1402,12 +1482,18 @@ static void fc_lport_flogi_resp(struct f
 			e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
 			if (csp_flags & FC_SP_FT_EDTR)
 				e_d_tov /= 1000000;
+
+			lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
+
 			if ((csp_flags & FC_SP_FT_FPORT) == 0) {
 				if (e_d_tov > lport->e_d_tov)
 					lport->e_d_tov = e_d_tov;
 				lport->r_a_tov = 2 * e_d_tov;
-				printk(KERN_INFO "libfc: Port (%6x) entered "
-				       "point to point mode\n", did);
+				fc_lport_set_port_id(lport, did, fp);
+				printk(KERN_INFO "host%d: libfc: "
+				       "Port (%6x) entered "
+				       "point-to-point mode\n",
+				       lport->host->host_no, did);
 				fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
 						   get_unaligned_be64(
 							   &flp->fl_wwpn),
@@ -1418,6 +1504,7 @@ static void fc_lport_flogi_resp(struct f
 				lport->r_a_tov = r_a_tov;
 				fc_host_fabric_name(lport->host) =
 					get_unaligned_be64(&flp->fl_wwnn);
+				fc_lport_set_port_id(lport, did, fp);
 				fc_lport_enter_dns(lport);
 			}
 		}
@@ -1430,6 +1517,7 @@ out:
 err:
 	mutex_unlock(&lport->lp_mutex);
 }
+EXPORT_SYMBOL(fc_lport_flogi_resp);
 
 /**
  * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
@@ -1451,12 +1539,18 @@ void fc_lport_enter_flogi(struct fc_lpor
 	if (!fp)
 		return fc_lport_error(lport, fp);
 
-	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
-				  fc_lport_flogi_resp, lport, lport->e_d_tov))
-		fc_lport_error(lport, fp);
+	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
+				  lport->vport ? ELS_FDISC : ELS_FLOGI,
+				  fc_lport_flogi_resp, lport,
+				  lport->vport ? 2 * lport->r_a_tov :
+				  lport->e_d_tov))
+		fc_lport_error(lport, NULL);
 }
 
-/* Configure a fc_lport */
+/**
+ * fc_lport_config() - Configure a fc_lport
+ * @lport: The local port to be configured
+ */
 int fc_lport_config(struct fc_lport *lport)
 {
 	INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
@@ -1471,6 +1565,10 @@ int fc_lport_config(struct fc_lport *lpo
 }
 EXPORT_SYMBOL(fc_lport_config);
 
+/**
+ * fc_lport_init() - Initialize the lport layer for a local port
+ * @lport: The local port to initialize the exchange layer for
+ */
 int fc_lport_init(struct fc_lport *lport)
 {
 	if (!lport->tt.lport_recv)
@@ -1500,7 +1598,254 @@ int fc_lport_init(struct fc_lport *lport
 	if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
 		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
 
-	INIT_LIST_HEAD(&lport->ema_list);
 	return 0;
 }
 EXPORT_SYMBOL(fc_lport_init);
+
+/**
+ * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
+ * @sp:	      The sequence for the FC Passthrough response
+ * @fp:	      The response frame
+ * @info_arg: The BSG info that the response is for
+ */
+static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
+			      void *info_arg)
+{
+	struct fc_bsg_info *info = info_arg;
+	struct fc_bsg_job *job = info->job;
+	struct fc_lport *lport = info->lport;
+	struct fc_frame_header *fh;
+	size_t len;
+	void *buf;
+
+	if (IS_ERR(fp)) {
+		job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
+			-ECONNABORTED : -ETIMEDOUT;
+		job->reply_len = sizeof(uint32_t);
+		job->state_flags |= FC_RQST_STATE_DONE;
+		job->job_done(job);
+		kfree(info);
+		return;
+	}
+
+	mutex_lock(&lport->lp_mutex);
+	fh = fc_frame_header_get(fp);
+	len = fr_len(fp) - sizeof(*fh);
+	buf = fc_frame_payload_get(fp, 0);
+
+	if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
+		/* Get the response code from the first frame payload */
+		unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
+			ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
+			(unsigned short)fc_frame_payload_op(fp);
+
+		/* Save the reply status of the job */
+		job->reply->reply_data.ctels_reply.status =
+			(cmd == info->rsp_code) ?
+			FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
+	}
+
+	job->reply->reply_payload_rcv_len +=
+		fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
+					 &info->offset, KM_BIO_SRC_IRQ, NULL);
+
+	if (fr_eof(fp) == FC_EOF_T &&
+	    (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
+	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
+		if (job->reply->reply_payload_rcv_len >
+		    job->reply_payload.payload_len)
+			job->reply->reply_payload_rcv_len =
+				job->reply_payload.payload_len;
+		job->reply->result = 0;
+		job->state_flags |= FC_RQST_STATE_DONE;
+		job->job_done(job);
+		kfree(info);
+	}
+	fc_frame_free(fp);
+	mutex_unlock(&lport->lp_mutex);
+}
+
+/**
+ * fc_lport_els_request() - Send ELS passthrough request
+ * @job:   The BSG Passthrough job
+ * @lport: The local port sending the request
+ * @did:   The destination port id
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static int fc_lport_els_request(struct fc_bsg_job *job,
+				struct fc_lport *lport,
+				u32 did, u32 tov)
+{
+	struct fc_bsg_info *info;
+	struct fc_frame *fp;
+	struct fc_frame_header *fh;
+	char *pp;
+	int len;
+
+	fp = fc_frame_alloc(lport, job->request_payload.payload_len);
+	if (!fp)
+		return -ENOMEM;
+
+	len = job->request_payload.payload_len;
+	pp = fc_frame_payload_get(fp, len);
+
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt,
+			  pp, len);
+
+	fh = fc_frame_header_get(fp);
+	fh->fh_r_ctl = FC_RCTL_ELS_REQ;
+	hton24(fh->fh_d_id, did);
+	hton24(fh->fh_s_id, fc_host_port_id(lport->host));
+	fh->fh_type = FC_TYPE_ELS;
+	hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
+	       FC_FC_END_SEQ | FC_FC_SEQ_INIT);
+	fh->fh_cs_ctl = 0;
+	fh->fh_df_ctl = 0;
+	fh->fh_parm_offset = 0;
+
+	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
+	if (!info) {
+		fc_frame_free(fp);
+		return -ENOMEM;
+	}
+
+	info->job = job;
+	info->lport = lport;
+	info->rsp_code = ELS_LS_ACC;
+	info->nents = job->reply_payload.sg_cnt;
+	info->sg = job->reply_payload.sg_list;
+
+	if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
+				     NULL, info, tov))
+		return -ECOMM;
+	return 0;
+}
+
+/**
+ * fc_lport_ct_request() - Send CT Passthrough request
+ * @job:   The BSG Passthrough job
+ * @lport: The local port sending the request
+ * @did:   The destination FC-ID
+ * @tov:   The timeout period to wait for the response
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static int fc_lport_ct_request(struct fc_bsg_job *job,
+			       struct fc_lport *lport, u32 did, u32 tov)
+{
+	struct fc_bsg_info *info;
+	struct fc_frame *fp;
+	struct fc_frame_header *fh;
+	struct fc_ct_req *ct;
+	size_t len;
+
+	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
+			    job->request_payload.payload_len);
+	if (!fp)
+		return -ENOMEM;
+
+	len = job->request_payload.payload_len;
+	ct = fc_frame_payload_get(fp, len);
+
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt,
+			  ct, len);
+
+	fh = fc_frame_header_get(fp);
+	fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
+	hton24(fh->fh_d_id, did);
+	hton24(fh->fh_s_id, fc_host_port_id(lport->host));
+	fh->fh_type = FC_TYPE_CT;
+	hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
+	       FC_FC_END_SEQ | FC_FC_SEQ_INIT);
+	fh->fh_cs_ctl = 0;
+	fh->fh_df_ctl = 0;
+	fh->fh_parm_offset = 0;
+
+	info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
+	if (!info) {
+		fc_frame_free(fp);
+		return -ENOMEM;
+	}
+
+	info->job = job;
+	info->lport = lport;
+	info->rsp_code = FC_FS_ACC;
+	info->nents = job->reply_payload.sg_cnt;
+	info->sg = job->reply_payload.sg_list;
+
+	if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
+				     NULL, info, tov))
+		return -ECOMM;
+	return 0;
+}
+
+/**
+ * fc_lport_bsg_request() - The common entry point for sending
+ *			    FC Passthrough requests
+ * @job: The BSG passthrough job
+ */
+int fc_lport_bsg_request(struct fc_bsg_job *job)
+{
+	struct request *rsp = job->req->next_rq;
+	struct Scsi_Host *shost = job->shost;
+	struct fc_lport *lport = shost_priv(shost);
+	struct fc_rport *rport;
+	struct fc_rport_priv *rdata;
+	int rc = -EINVAL;
+	u32 did;
+
+	job->reply->reply_payload_rcv_len = 0;
+	if (rsp)
+		rsp->resid_len = job->reply_payload.payload_len;
+
+	mutex_lock(&lport->lp_mutex);
+
+	switch (job->request->msgcode) {
+	case FC_BSG_RPT_ELS:
+		rport = job->rport;
+		if (!rport)
+			break;
+
+		rdata = rport->dd_data;
+		rc = fc_lport_els_request(job, lport, rport->port_id,
+					  rdata->e_d_tov);
+		break;
+
+	case FC_BSG_RPT_CT:
+		rport = job->rport;
+		if (!rport)
+			break;
+
+		rdata = rport->dd_data;
+		rc = fc_lport_ct_request(job, lport, rport->port_id,
+					 rdata->e_d_tov);
+		break;
+
+	case FC_BSG_HST_CT:
+		did = ntoh24(job->request->rqst_data.h_ct.port_id);
+		if (did == FC_FID_DIR_SERV)
+			rdata = lport->dns_rdata;
+		else
+			rdata = lport->tt.rport_lookup(lport, did);
+
+		if (!rdata)
+			break;
+
+		rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov);
+		break;
+
+	case FC_BSG_HST_ELS_NOLOGIN:
+		did = ntoh24(job->request->rqst_data.h_els.port_id);
+		rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
+		break;
+	}
+
+	mutex_unlock(&lport->lp_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(fc_lport_bsg_request);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_npiv.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_npiv.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_npiv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_npiv.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,161 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+/*
+ * NPIV VN_Port helper functions for libfc
+ */
+
+#include <scsi/libfc.h>
+
+/**
+ * fc_vport_create() - Create a new NPIV vport instance
+ * @vport: fc_vport structure from scsi_transport_fc
+ * @privsize: driver private data size to allocate along with the Scsi_Host
+ */
+
+struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fc_lport *vn_port;
+
+	vn_port = libfc_host_alloc(shost->hostt, privsize);
+	if (!vn_port)
+		goto err_out;
+	if (fc_exch_mgr_list_clone(n_port, vn_port))
+		goto err_put;
+
+	vn_port->vport = vport;
+	vport->dd_data = vn_port;
+
+	mutex_lock(&n_port->lp_mutex);
+	list_add_tail(&vn_port->list, &n_port->vports);
+	mutex_unlock(&n_port->lp_mutex);
+
+	return vn_port;
+
+err_put:
+	scsi_host_put(vn_port->host);
+err_out:
+	return NULL;
+}
+EXPORT_SYMBOL(libfc_vport_create);
+
+/**
+ * fc_vport_id_lookup() - find NPIV lport that matches a given fabric ID
+ * @n_port: Top level N_Port which may have multiple NPIV VN_Ports
+ * @port_id: Fabric ID to find a match for
+ *
+ * Returns: matching lport pointer or NULL if there is no match
+ */
+struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
+{
+	struct fc_lport *lport = NULL;
+	struct fc_lport *vn_port;
+
+	if (fc_host_port_id(n_port->host) == port_id)
+		return n_port;
+
+	mutex_lock(&n_port->lp_mutex);
+	list_for_each_entry(vn_port, &n_port->vports, list) {
+		if (fc_host_port_id(vn_port->host) == port_id) {
+			lport = vn_port;
+			break;
+		}
+	}
+	mutex_unlock(&n_port->lp_mutex);
+
+	return lport;
+}
+
+/*
+ * When setting the link state of vports during an lport state change, it's
+ * necessary to hold the lp_mutex of both the N_Port and the VN_Port.
+ * This tells the lockdep engine to treat the nested locking of the VN_Port
+ * as a different lock class.
+ */
+enum libfc_lport_mutex_class {
+	LPORT_MUTEX_NORMAL = 0,
+	LPORT_MUTEX_VN_PORT = 1,
+};
+
+/**
+ * __fc_vport_setlink() - update link and status on a VN_Port
+ * @n_port: parent N_Port
+ * @vn_port: VN_Port to update
+ *
+ * Locking: must be called with both the N_Port and VN_Port lp_mutex held
+ */
+static void __fc_vport_setlink(struct fc_lport *n_port,
+			       struct fc_lport *vn_port)
+{
+	struct fc_vport *vport = vn_port->vport;
+
+	if (vn_port->state == LPORT_ST_DISABLED)
+		return;
+
+	if (n_port->state == LPORT_ST_READY) {
+		if (n_port->npiv_enabled) {
+			fc_vport_set_state(vport, FC_VPORT_INITIALIZING);
+			__fc_linkup(vn_port);
+		} else {
+			fc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
+			__fc_linkdown(vn_port);
+		}
+	} else {
+		fc_vport_set_state(vport, FC_VPORT_LINKDOWN);
+		__fc_linkdown(vn_port);
+	}
+}
+
+/**
+ * fc_vport_setlink() - update link and status on a VN_Port
+ * @vn_port: virtual port to update
+ */
+void fc_vport_setlink(struct fc_lport *vn_port)
+{
+	struct fc_vport *vport = vn_port->vport;
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+
+	mutex_lock(&n_port->lp_mutex);
+	mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+	__fc_vport_setlink(n_port, vn_port);
+	mutex_unlock(&vn_port->lp_mutex);
+	mutex_unlock(&n_port->lp_mutex);
+}
+EXPORT_SYMBOL(fc_vport_setlink);
+
+/**
+ * fc_vports_linkchange() - change the link state of all vports
+ * @n_port: Parent N_Port that has changed state
+ *
+ * Locking: called with the n_port lp_mutex held
+ */
+void fc_vports_linkchange(struct fc_lport *n_port)
+{
+	struct fc_lport *vn_port;
+
+	list_for_each_entry(vn_port, &n_port->vports, list) {
+		mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT);
+		__fc_vport_setlink(n_port, vn_port);
+		mutex_unlock(&vn_port->lp_mutex);
+	}
+}
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_rport.c linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_rport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/fc_rport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/fc_rport.c	2010-02-24 13:52:17.000000000 -0500
@@ -55,6 +55,8 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
+#include "fc_libfc.h"
+
 struct workqueue_struct *rport_event_queue;
 
 static void fc_rport_enter_plogi(struct fc_rport_priv *);
@@ -86,12 +88,13 @@ static const char *fc_rport_state_names[
 	[RPORT_ST_LOGO] = "LOGO",
 	[RPORT_ST_ADISC] = "ADISC",
 	[RPORT_ST_DELETE] = "Delete",
+	[RPORT_ST_RESTART] = "Restart",
 };
 
 /**
- * fc_rport_lookup() - lookup a remote port by port_id
- * @lport: Fibre Channel host port instance
- * @port_id: remote port port_id to match
+ * fc_rport_lookup() - Lookup a remote port by port_id
+ * @lport:   The local port to lookup the remote port on
+ * @port_id: The remote port ID to look up
  */
 static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
 					     u32 port_id)
@@ -99,16 +102,17 @@ static struct fc_rport_priv *fc_rport_lo
 	struct fc_rport_priv *rdata;
 
 	list_for_each_entry(rdata, &lport->disc.rports, peers)
-		if (rdata->ids.port_id == port_id &&
-		    rdata->rp_state != RPORT_ST_DELETE)
+		if (rdata->ids.port_id == port_id)
 			return rdata;
 	return NULL;
 }
 
 /**
  * fc_rport_create() - Create a new remote port
- * @lport:   The local port that the new remote port is for
- * @port_id: The port ID for the new remote port
+ * @lport: The local port this remote port will be associated with
+ * @ids:   The identifiers for the new remote port
+ *
+ * The remote port will start in the INIT state.
  *
  * Locking note:  must be called with the disc_mutex held.
  */
@@ -147,8 +151,8 @@ static struct fc_rport_priv *fc_rport_cr
 }
 
 /**
- * fc_rport_destroy() - free a remote port after last reference is released.
- * @kref: pointer to kref inside struct fc_rport_priv
+ * fc_rport_destroy() - Free a remote port after last reference is released
+ * @kref: The remote port's kref
  */
 static void fc_rport_destroy(struct kref *kref)
 {
@@ -159,8 +163,8 @@ static void fc_rport_destroy(struct kref
 }
 
 /**
- * fc_rport_state() - return a string for the state the rport is in
- * @rdata: remote port private data
+ * fc_rport_state() - Return a string identifying the remote port's state
+ * @rdata: The remote port
  */
 static const char *fc_rport_state(struct fc_rport_priv *rdata)
 {
@@ -173,9 +177,9 @@ static const char *fc_rport_state(struct
 }
 
 /**
- * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds.
- * @rport: Pointer to Fibre Channel remote port structure
- * @timeout: timeout in seconds
+ * fc_set_rport_loss_tmo() - Set the remote port loss timeout
+ * @rport:   The remote port that gets a new timeout value
+ * @timeout: The new timeout value (in seconds)
  */
 void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
 {
@@ -187,9 +191,11 @@ void fc_set_rport_loss_tmo(struct fc_rpo
 EXPORT_SYMBOL(fc_set_rport_loss_tmo);
 
 /**
- * fc_plogi_get_maxframe() - Get max payload from the common service parameters
- * @flp: FLOGI payload structure
- * @maxval: upper limit, may be less than what is in the service parameters
+ * fc_plogi_get_maxframe() - Get the maximum payload from the common service
+ *			     parameters in a FLOGI frame
+ * @flp:    The FLOGI payload
+ * @maxval: The maximum frame size upper limit; this may be less than what
+ *	    is in the service parameters
  */
 static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
 					  unsigned int maxval)
@@ -210,9 +216,9 @@ static unsigned int fc_plogi_get_maxfram
 }
 
 /**
- * fc_rport_state_enter() - Change the rport's state
- * @rdata: The rport whose state should change
- * @new: The new state of the rport
+ * fc_rport_state_enter() - Change the state of a remote port
+ * @rdata: The remote port whose state should change
+ * @new:   The new state
  *
  * Locking Note: Called with the rport lock held
  */
@@ -224,17 +230,22 @@ static void fc_rport_state_enter(struct
 	rdata->rp_state = new;
 }
 
+/**
+ * fc_rport_work() - Handler for remote port events in the rport_event_queue
+ * @work: Handle to the remote port being dequeued
+ */
 static void fc_rport_work(struct work_struct *work)
 {
 	u32 port_id;
 	struct fc_rport_priv *rdata =
 		container_of(work, struct fc_rport_priv, event_work);
-	struct fc_rport_libfc_priv *rp;
+	struct fc_rport_libfc_priv *rpriv;
 	enum fc_rport_event event;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_rport_operations *rport_ops;
 	struct fc_rport_identifiers ids;
 	struct fc_rport *rport;
+	int restart = 0;
 
 	mutex_lock(&rdata->rp_mutex);
 	event = rdata->event;
@@ -265,12 +276,12 @@ static void fc_rport_work(struct work_st
 		rport->maxframe_size = rdata->maxframe_size;
 		rport->supported_classes = rdata->supported_classes;
 
-		rp = rport->dd_data;
-		rp->local_port = lport;
-		rp->rp_state = rdata->rp_state;
-		rp->flags = rdata->flags;
-		rp->e_d_tov = rdata->e_d_tov;
-		rp->r_a_tov = rdata->r_a_tov;
+		rpriv = rport->dd_data;
+		rpriv->local_port = lport;
+		rpriv->rp_state = rdata->rp_state;
+		rpriv->flags = rdata->flags;
+		rpriv->e_d_tov = rdata->e_d_tov;
+		rpriv->r_a_tov = rdata->r_a_tov;
 		mutex_unlock(&rdata->rp_mutex);
 
 		if (rport_ops && rport_ops->event_callback) {
@@ -287,8 +298,20 @@ static void fc_rport_work(struct work_st
 		mutex_unlock(&rdata->rp_mutex);
 
 		if (port_id != FC_FID_DIR_SERV) {
+			/*
+			 * We must drop rp_mutex before taking disc_mutex.
+			 * Re-evaluate state to allow for restart.
+			 * A transition to RESTART state must only happen
+			 * while disc_mutex is held and rdata is on the list.
+			 */
 			mutex_lock(&lport->disc.disc_mutex);
-			list_del(&rdata->peers);
+			mutex_lock(&rdata->rp_mutex);
+			if (rdata->rp_state == RPORT_ST_RESTART)
+				restart = 1;
+			else
+				list_del(&rdata->peers);
+			rdata->event = RPORT_EV_NONE;
+			mutex_unlock(&rdata->rp_mutex);
 			mutex_unlock(&lport->disc.disc_mutex);
 		}
 
@@ -305,14 +328,20 @@ static void fc_rport_work(struct work_st
 		lport->tt.exch_mgr_reset(lport, port_id, 0);
 
 		if (rport) {
-			rp = rport->dd_data;
-			rp->rp_state = RPORT_ST_DELETE;
+			rpriv = rport->dd_data;
+			rpriv->rp_state = RPORT_ST_DELETE;
 			mutex_lock(&rdata->rp_mutex);
 			rdata->rport = NULL;
 			mutex_unlock(&rdata->rp_mutex);
 			fc_remote_port_delete(rport);
 		}
-		kref_put(&rdata->kref, lport->tt.rport_destroy);
+		if (restart) {
+			mutex_lock(&rdata->rp_mutex);
+			FC_RPORT_DBG(rdata, "work restart\n");
+			fc_rport_enter_plogi(rdata);
+			mutex_unlock(&rdata->rp_mutex);
+		} else
+			kref_put(&rdata->kref, lport->tt.rport_destroy);
 		break;
 
 	default:
@@ -323,7 +352,7 @@ static void fc_rport_work(struct work_st
 
 /**
  * fc_rport_login() - Start the remote port login state machine
- * @rdata: private remote port
+ * @rdata: The remote port to be logged in to
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -342,6 +371,12 @@ int fc_rport_login(struct fc_rport_priv
 		FC_RPORT_DBG(rdata, "ADISC port\n");
 		fc_rport_enter_adisc(rdata);
 		break;
+	case RPORT_ST_RESTART:
+		break;
+	case RPORT_ST_DELETE:
+		FC_RPORT_DBG(rdata, "Restart deleted port\n");
+		fc_rport_state_enter(rdata, RPORT_ST_RESTART);
+		break;
 	default:
 		FC_RPORT_DBG(rdata, "Login to port\n");
 		fc_rport_enter_plogi(rdata);
@@ -353,9 +388,9 @@ int fc_rport_login(struct fc_rport_priv
 }
 
 /**
- * fc_rport_enter_delete() - schedule a remote port to be deleted.
- * @rdata: private remote port
- * @event: event to report as the reason for deletion
+ * fc_rport_enter_delete() - Schedule a remote port to be deleted
+ * @rdata: The remote port to be deleted
+ * @event: The event to report as the reason for deletion
  *
  * Locking Note: Called with the rport lock held.
  *
@@ -382,8 +417,8 @@ static void fc_rport_enter_delete(struct
 }
 
 /**
- * fc_rport_logoff() - Logoff and remove an rport
- * @rdata: private remote port
+ * fc_rport_logoff() - Logoff and remove a remote port
+ * @rdata: The remote port to be logged off of
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -397,26 +432,27 @@ int fc_rport_logoff(struct fc_rport_priv
 
 	if (rdata->rp_state == RPORT_ST_DELETE) {
 		FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
-		mutex_unlock(&rdata->rp_mutex);
 		goto out;
 	}
 
-	fc_rport_enter_logo(rdata);
+	if (rdata->rp_state == RPORT_ST_RESTART)
+		FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n");
+	else
+		fc_rport_enter_logo(rdata);
 
 	/*
 	 * Change the state to Delete so that we discard
 	 * the response.
 	 */
 	fc_rport_enter_delete(rdata, RPORT_EV_STOP);
-	mutex_unlock(&rdata->rp_mutex);
-
 out:
+	mutex_unlock(&rdata->rp_mutex);
 	return 0;
 }
 
 /**
- * fc_rport_enter_ready() - The rport is ready
- * @rdata: private remote port
+ * fc_rport_enter_ready() - Transition to the RPORT_ST_READY state
+ * @rdata: The remote port that is ready
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -433,8 +469,8 @@ static void fc_rport_enter_ready(struct
 }
 
 /**
- * fc_rport_timeout() - Handler for the retry_work timer.
- * @work: The work struct of the fc_rport_priv
+ * fc_rport_timeout() - Handler for the retry_work timer
+ * @work: Handle to the remote port that has timed out
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -466,6 +502,7 @@ static void fc_rport_timeout(struct work
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
 	case RPORT_ST_DELETE:
+	case RPORT_ST_RESTART:
 		break;
 	}
 
@@ -474,8 +511,8 @@ static void fc_rport_timeout(struct work
 
 /**
  * fc_rport_error() - Error handler, called once retries have been exhausted
- * @rdata: private remote port
- * @fp: The frame pointer
+ * @rdata: The remote port the error is happened on
+ * @fp:	   The error code encapsulated in a frame pointer
  *
  * Locking Note: The rport lock is expected to be held before
  * calling this routine
@@ -499,6 +536,7 @@ static void fc_rport_error(struct fc_rpo
 		fc_rport_enter_logo(rdata);
 		break;
 	case RPORT_ST_DELETE:
+	case RPORT_ST_RESTART:
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
 		break;
@@ -506,9 +544,9 @@ static void fc_rport_error(struct fc_rpo
 }
 
 /**
- * fc_rport_error_retry() - Error handler when retries are desired
- * @rdata: private remote port data
- * @fp: The frame pointer
+ * fc_rport_error_retry() - Handler for remote port state retries
+ * @rdata: The remote port whose state is to be retried
+ * @fp:	   The error code encapsulated in a frame pointer
  *
  * If the error was an exchange timeout retry immediately,
  * otherwise wait for E_D_TOV.
@@ -540,10 +578,10 @@ static void fc_rport_error_retry(struct
 }
 
 /**
- * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_plogi_recv_resp() - Handler for ELS PLOGI responses
+ * @sp:	       The sequence the PLOGI is on
+ * @fp:	       The PLOGI response frame
+ * @rdata_arg: The remote port that sent the PLOGI response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -585,7 +623,7 @@ static void fc_rport_plogi_resp(struct f
 
 		tov = ntohl(plp->fl_csp.sp_e_d_tov);
 		if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
-			tov /= 1000;
+			tov /= 1000000;
 		if (tov > rdata->e_d_tov)
 			rdata->e_d_tov = tov;
 		csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
@@ -606,8 +644,8 @@ err:
 }
 
 /**
- * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
+ * @rdata: The remote port to send a PLOGI to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -631,17 +669,18 @@ static void fc_rport_enter_plogi(struct
 	rdata->e_d_tov = lport->e_d_tov;
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
-				  fc_rport_plogi_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_plogi_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
  * fc_rport_prli_resp() - Process Login (PRLI) response handler
- * @sp: current sequence in the PRLI exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * @sp:	       The sequence the PRLI response was on
+ * @fp:	       The PRLI response frame
+ * @rdata_arg: The remote port that sent the PRLI response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -710,10 +749,10 @@ err:
 }
 
 /**
- * fc_rport_logo_resp() - Logout (LOGO) response handler
- * @sp: current sequence in the LOGO exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_logo_resp() - Handler for logout (LOGO) responses
+ * @sp:	       The sequence the LOGO was on
+ * @fp:	       The LOGO response frame
+ * @rdata_arg: The remote port that sent the LOGO response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
@@ -756,8 +795,8 @@ err:
 }
 
 /**
- * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_prli() - Send Process Login (PRLI) request
+ * @rdata: The remote port to send the PRLI request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -792,17 +831,18 @@ static void fc_rport_enter_prli(struct f
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
-				  fc_rport_prli_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_prli_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_els_rtv_resp() - Request Timeout Value response handler
- * @sp: current sequence in the RTV exchange
- * @fp: response frame
- * @rdata_arg: private remote port data
+ * fc_rport_els_rtv_resp() - Handler for Request Timeout Value (RTV) responses
+ * @sp:	       The sequence the RTV was on
+ * @fp:	       The RTV response frame
+ * @rdata_arg: The remote port that sent the RTV response
  *
  * Many targets don't seem to support this.
  *
@@ -865,8 +905,8 @@ err:
 }
 
 /**
- * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request
+ * @rdata: The remote port to send the RTV request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -888,15 +928,16 @@ static void fc_rport_enter_rtv(struct fc
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
-				     fc_rport_rtv_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_rtv_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_enter_logo() - Send Logout (LOGO) request to peer
- * @rdata: private remote port data
+ * fc_rport_enter_logo() - Send a logout (LOGO) request
+ * @rdata: The remote port to send the LOGO request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -918,24 +959,25 @@ static void fc_rport_enter_logo(struct f
 	}
 
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
-				  fc_rport_logo_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_logo_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_els_adisc_resp() - Address Discovery response handler
- * @sp: current sequence in the ADISC exchange
- * @fp: response frame
- * @rdata_arg: remote port private.
+ * fc_rport_els_adisc_resp() - Handler for Address Discovery (ADISC) responses
+ * @sp:	       The sequence the ADISC response was on
+ * @fp:	       The ADISC response frame
+ * @rdata_arg: The remote port that sent the ADISC response
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
  * and then unlock the rport.
  */
 static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,
-			      void *rdata_arg)
+				void *rdata_arg)
 {
 	struct fc_rport_priv *rdata = rdata_arg;
 	struct fc_els_adisc *adisc;
@@ -983,8 +1025,8 @@ err:
 }
 
 /**
- * fc_rport_enter_adisc() - Send Address Discover (ADISC) request to peer
- * @rdata: remote port private data
+ * fc_rport_enter_adisc() - Send Address Discover (ADISC) request
+ * @rdata: The remote port to send the ADISC request to
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
@@ -1005,17 +1047,18 @@ static void fc_rport_enter_adisc(struct
 		return;
 	}
 	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
-				  fc_rport_adisc_resp, rdata, lport->e_d_tov))
-		fc_rport_error_retry(rdata, fp);
+				  fc_rport_adisc_resp, rdata,
+				  2 * lport->r_a_tov))
+		fc_rport_error_retry(rdata, NULL);
 	else
 		kref_get(&rdata->kref);
 }
 
 /**
- * fc_rport_recv_adisc_req() - Handle incoming Address Discovery (ADISC) Request
- * @rdata: remote port private
- * @sp: current sequence in the ADISC exchange
- * @in_fp: ADISC request frame
+ * fc_rport_recv_adisc_req() - Handler for Address Discovery (ADISC) requests
+ * @rdata: The remote port that sent the ADISC request
+ * @sp:	   The sequence the ADISC request was on
+ * @in_fp: The ADISC request frame
  *
  * Locking Note:  Called with the lport and rport locks held.
  */
@@ -1056,10 +1099,82 @@ drop:
 }
 
 /**
- * fc_rport_recv_els_req() - handle a validated ELS request.
- * @lport: Fibre Channel local port
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
+ * fc_rport_recv_rls_req() - Handle received Read Link Status request
+ * @rdata: The remote port that sent the RLS request
+ * @sp:	The sequence that the RLS was on
+ * @rx_fp: The PRLI request frame
+ *
+ * Locking Note: The rport lock is expected to be held before calling
+ * this function.
+ */
+static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
+				  struct fc_seq *sp, struct fc_frame *rx_fp)
+
+{
+	struct fc_lport *lport = rdata->local_port;
+	struct fc_frame *fp;
+	struct fc_exch *ep = fc_seq_exch(sp);
+	struct fc_els_rls *rls;
+	struct fc_els_rls_resp *rsp;
+	struct fc_els_lesb *lesb;
+	struct fc_seq_els_data rjt_data;
+	struct fc_host_statistics *hst;
+	u32 f_ctl;
+
+	FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",
+		     fc_rport_state(rdata));
+
+	rls = fc_frame_payload_get(rx_fp, sizeof(*rls));
+	if (!rls) {
+		rjt_data.reason = ELS_RJT_PROT;
+		rjt_data.explan = ELS_EXPL_INV_LEN;
+		goto out_rjt;
+	}
+
+	fp = fc_frame_alloc(lport, sizeof(*rsp));
+	if (!fp) {
+		rjt_data.reason = ELS_RJT_UNAB;
+		rjt_data.explan = ELS_EXPL_INSUF_RES;
+		goto out_rjt;
+	}
+
+	rsp = fc_frame_payload_get(fp, sizeof(*rsp));
+	memset(rsp, 0, sizeof(*rsp));
+	rsp->rls_cmd = ELS_LS_ACC;
+	lesb = &rsp->rls_lesb;
+	if (lport->tt.get_lesb) {
+		/* get LESB from LLD if it supports it */
+		lport->tt.get_lesb(lport, lesb);
+	} else {
+		fc_get_host_stats(lport->host);
+		hst = &lport->host_stats;
+		lesb->lesb_link_fail = htonl(hst->link_failure_count);
+		lesb->lesb_sync_loss = htonl(hst->loss_of_sync_count);
+		lesb->lesb_sig_loss = htonl(hst->loss_of_signal_count);
+		lesb->lesb_prim_err = htonl(hst->prim_seq_protocol_err_count);
+		lesb->lesb_inv_word = htonl(hst->invalid_tx_word_count);
+		lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);
+	}
+
+	sp = lport->tt.seq_start_next(sp);
+	f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
+	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
+		       FC_TYPE_ELS, f_ctl, 0);
+	lport->tt.seq_send(lport, sp, fp);
+	goto out;
+
+out_rjt:
+	rjt_data.fp = NULL;
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
+out:
+	fc_frame_free(rx_fp);
+}
+
+/**
+ * fc_rport_recv_els_req() - Handler for validated ELS requests
+ * @lport: The local port that received the ELS request
+ * @sp:	   The sequence that the ELS request was on
+ * @fp:	   The ELS request frame
  *
  * Handle incoming ELS requests that require port login.
  * The ELS opcode has already been validated by the caller.
@@ -1117,6 +1232,9 @@ static void fc_rport_recv_els_req(struct
 		els_data.fp = fp;
 		lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
 		break;
+	case ELS_RLS:
+		fc_rport_recv_rls_req(rdata, sp, fp);
+		break;
 	default:
 		fc_frame_free(fp);	/* can't happen */
 		break;
@@ -1131,10 +1249,10 @@ reject:
 }
 
 /**
- * fc_rport_recv_req() - Handle a received ELS request from a rport
- * @sp: current sequence in the PLOGI exchange
- * @fp: response frame
- * @lport: Fibre Channel local port
+ * fc_rport_recv_req() - Handler for requests
+ * @sp:	   The sequence the request was on
+ * @fp:	   The request frame
+ * @lport: The local port that received the request
  *
  * Locking Note: Called with the lport lock held.
  */
@@ -1161,6 +1279,7 @@ void fc_rport_recv_req(struct fc_seq *sp
 	case ELS_ADISC:
 	case ELS_RRQ:
 	case ELS_REC:
+	case ELS_RLS:
 		fc_rport_recv_els_req(lport, sp, fp);
 		break;
 	default:
@@ -1174,10 +1293,10 @@ void fc_rport_recv_req(struct fc_seq *sp
 }
 
 /**
- * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request
- * @lport: local port
- * @sp: current sequence in the PLOGI exchange
- * @fp: PLOGI request frame
+ * fc_rport_recv_plogi_req() - Handler for Port Login (PLOGI) requests
+ * @lport: The local port that received the PLOGI request
+ * @sp:	   The sequence that the PLOGI request was on
+ * @rx_fp: The PLOGI request frame
  *
  * Locking Note: The rport lock is held before calling this function.
  */
@@ -1248,6 +1367,7 @@ static void fc_rport_recv_plogi_req(stru
 		}
 		break;
 	case RPORT_ST_PRLI:
+	case RPORT_ST_RTV:
 	case RPORT_ST_READY:
 	case RPORT_ST_ADISC:
 		FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
@@ -1255,11 +1375,14 @@ static void fc_rport_recv_plogi_req(stru
 		/* XXX TBD - should reset */
 		break;
 	case RPORT_ST_DELETE:
-	default:
-		FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n",
-			     rdata->rp_state);
-		fc_frame_free(rx_fp);
-		goto out;
+	case RPORT_ST_LOGO:
+	case RPORT_ST_RESTART:
+		FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
+			     fc_rport_state(rdata));
+		mutex_unlock(&rdata->rp_mutex);
+		rjt_data.reason = ELS_RJT_BUSY;
+		rjt_data.explan = ELS_EXPL_NONE;
+		goto reject;
 	}
 
 	/*
@@ -1295,10 +1418,10 @@ reject:
 }
 
 /**
- * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request
- * @rdata: private remote port data
- * @sp: current sequence in the PRLI exchange
- * @fp: PRLI request frame
+ * fc_rport_recv_prli_req() - Handler for process login (PRLI) requests
+ * @rdata: The remote port that sent the PRLI request
+ * @sp:	   The sequence that the PRLI was on
+ * @rx_fp: The PRLI request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1402,7 +1525,7 @@ static void fc_rport_recv_prli_req(struc
 				break;
 			case FC_TYPE_FCP:
 				fcp_parm = ntohl(rspp->spp_params);
-				if (fcp_parm * FCP_SPPF_RETRY)
+				if (fcp_parm & FCP_SPPF_RETRY)
 					rdata->flags |= FC_RP_FLAGS_RETRY;
 				rdata->supported_classes = FC_COS_CLASS3;
 				if (fcp_parm & FCP_SPPF_INIT_FCN)
@@ -1452,10 +1575,10 @@ static void fc_rport_recv_prli_req(struc
 }
 
 /**
- * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request
- * @rdata: private remote port data
- * @sp: current sequence in the PRLO exchange
- * @fp: PRLO request frame
+ * fc_rport_recv_prlo_req() - Handler for process logout (PRLO) requests
+ * @rdata: The remote port that sent the PRLO request
+ * @sp:	   The sequence that the PRLO was on
+ * @fp:	   The PRLO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1482,10 +1605,10 @@ static void fc_rport_recv_prlo_req(struc
 }
 
 /**
- * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request
- * @lport: local port.
- * @sp: current sequence in the LOGO exchange
- * @fp: LOGO request frame
+ * fc_rport_recv_logo_req() - Handler for logout (LOGO) requests
+ * @lport: The local port that received the LOGO request
+ * @sp:	   The sequence that the LOGO request was on
+ * @fp:	   The LOGO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
@@ -1510,14 +1633,14 @@ static void fc_rport_recv_logo_req(struc
 		FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
 			     fc_rport_state(rdata));
 
+		fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+
 		/*
-		 * If the remote port was created due to discovery,
-		 * log back in.  It may have seen a stale RSCN about us.
+		 * If the remote port was created due to discovery, set state
+		 * to log back in.  It may have seen a stale RSCN about us.
 		 */
-		if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id)
-			fc_rport_enter_plogi(rdata);
-		else
-			fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+		if (rdata->disc_id)
+			fc_rport_state_enter(rdata, RPORT_ST_RESTART);
 		mutex_unlock(&rdata->rp_mutex);
 	} else
 		FC_RPORT_ID_DBG(lport, sid,
@@ -1526,11 +1649,18 @@ static void fc_rport_recv_logo_req(struc
 	fc_frame_free(fp);
 }
 
+/**
+ * fc_rport_flush_queue() - Flush the rport_event_queue
+ */
 static void fc_rport_flush_queue(void)
 {
 	flush_workqueue(rport_event_queue);
 }
 
+/**
+ * fc_rport_init() - Initialize the remote port layer for a local port
+ * @lport: The local port to initialize the remote port layer for
+ */
 int fc_rport_init(struct fc_lport *lport)
 {
 	if (!lport->tt.rport_lookup)
@@ -1558,25 +1688,33 @@ int fc_rport_init(struct fc_lport *lport
 }
 EXPORT_SYMBOL(fc_rport_init);
 
-int fc_setup_rport(void)
+/**
+ * fc_setup_rport() - Initialize the rport_event_queue
+ */
+int fc_setup_rport()
 {
 	rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
 	if (!rport_event_queue)
 		return -ENOMEM;
 	return 0;
 }
-EXPORT_SYMBOL(fc_setup_rport);
 
-void fc_destroy_rport(void)
+/**
+ * fc_destroy_rport() - Destroy the rport_event_queue
+ */
+void fc_destroy_rport()
 {
 	destroy_workqueue(rport_event_queue);
 }
-EXPORT_SYMBOL(fc_destroy_rport);
 
+/**
+ * fc_rport_terminate_io() - Stop all outstanding I/O on a remote port
+ * @rport: The remote port whose I/O should be terminated
+ */
 void fc_rport_terminate_io(struct fc_rport *rport)
 {
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	struct fc_lport *lport = rp->local_port;
+	struct fc_rport_libfc_priv *rpriv = rport->dd_data;
+	struct fc_lport *lport = rpriv->local_port;
 
 	lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
 	lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libfc/Makefile linux-libre-2.6.33-gnu1/drivers/scsi/libfc/Makefile
--- linux-libre-2.6.32-gnu1/drivers/scsi/libfc/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libfc/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -3,10 +3,12 @@
 obj-$(CONFIG_LIBFC) += libfc.o
 
 libfc-objs := \
+	fc_libfc.o \
 	fc_disc.o \
 	fc_exch.o \
 	fc_elsct.o \
 	fc_frame.o \
 	fc_lport.o \
 	fc_rport.o \
-	fc_fcp.o
+	fc_fcp.o \
+	fc_npiv.o
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libiscsi.c linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libiscsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -266,6 +266,88 @@ static int iscsi_prep_bidi_ahs(struct is
 }
 
 /**
+ * iscsi_check_tmf_restrictions - check if a task is affected by TMF
+ * @task: iscsi task
+ * @opcode: opcode to check for
+ *
+ * During TMF a task has to be checked if it's affected.
+ * All unrelated I/O can be passed through, but I/O to the
+ * affected LUN should be restricted.
+ * If 'fast_abort' is set we won't be sending any I/O to the
+ * affected LUN.
+ * Otherwise the target is waiting for all TTTs to be completed,
+ * so we have to send all outstanding Data-Out PDUs to the target.
+ */
+static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
+{
+	struct iscsi_conn *conn = task->conn;
+	struct iscsi_tm *tmf = &conn->tmhdr;
+	unsigned int hdr_lun;
+
+	if (conn->tmf_state == TMF_INITIAL)
+		return 0;
+
+	if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
+		return 0;
+
+	switch (ISCSI_TM_FUNC_VALUE(tmf)) {
+	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
+		/*
+		 * Allow PDUs for unrelated LUNs
+		 */
+		hdr_lun = scsilun_to_int((struct scsi_lun *)tmf->lun);
+		if (hdr_lun != task->sc->device->lun)
+			return 0;
+		/* fall through */
+	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
+		/*
+		 * Fail all SCSI cmd PDUs
+		 */
+		if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
+			iscsi_conn_printk(KERN_INFO, conn,
+					  "task [op %x/%x itt "
+					  "0x%x/0x%x] "
+					  "rejected.\n",
+					  task->hdr->opcode, opcode,
+					  task->itt, task->hdr_itt);
+			return -EACCES;
+		}
+		/*
+		 * And also all data-out PDUs in response to R2T
+		 * if fast_abort is set.
+		 */
+		if (conn->session->fast_abort) {
+			iscsi_conn_printk(KERN_INFO, conn,
+					  "task [op %x/%x itt "
+					  "0x%x/0x%x] fast abort.\n",
+					  task->hdr->opcode, opcode,
+					  task->itt, task->hdr_itt);
+			return -EACCES;
+		}
+		break;
+	case ISCSI_TM_FUNC_ABORT_TASK:
+		/*
+		 * the caller has already checked if the task
+		 * they want to abort was in the pending queue so if
+		 * we are here the cmd pdu has gone out already, and
+		 * we will only hit this for data-outs
+		 */
+		if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
+		    task->hdr_itt == tmf->rtt) {
+			ISCSI_DBG_SESSION(conn->session,
+					  "Preventing task %x/%x from sending "
+					  "data-out due to abort task in "
+					  "progress\n", task->itt,
+					  task->hdr_itt);
+			return -EACCES;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+/**
  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
  * @task: iscsi task
  *
@@ -282,6 +364,10 @@ static int iscsi_prep_scsi_cmd_pdu(struc
 	itt_t itt;
 	int rc;
 
+	rc = iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_CMD);
+	if (rc)
+		return rc;
+
 	if (conn->session->tt->alloc_pdu) {
 		rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD);
 		if (rc)
@@ -431,7 +517,7 @@ static void iscsi_free_task(struct iscsi
 	if (conn->login_task == task)
 		return;
 
-	__kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*));
+	kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*));
 
 	if (sc) {
 		task->sc = NULL;
@@ -577,12 +663,12 @@ static int iscsi_prep_mgmt_task(struct i
 	struct iscsi_session *session = conn->session;
 	struct iscsi_hdr *hdr = task->hdr;
 	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
+	uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
 	if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
 		return -ENOTCONN;
 
-	if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) &&
-	    hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+	if (opcode != ISCSI_OP_LOGIN && opcode != ISCSI_OP_TEXT)
 		nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
 	/*
 	 * pre-format CmdSN for outgoing PDU.
@@ -590,9 +676,12 @@ static int iscsi_prep_mgmt_task(struct i
 	nop->cmdsn = cpu_to_be32(session->cmdsn);
 	if (hdr->itt != RESERVED_ITT) {
 		/*
-		 * TODO: We always use immediate, so we never hit this.
+		 * TODO: We always use immediate for normal session pdus.
 		 * If we start to send tmfs or nops as non-immediate then
 		 * we should start checking the cmdsn numbers for mgmt tasks.
+		 *
+		 * During discovery sessions iscsid sends TEXT as non immediate,
+		 * but we always only send one PDU at a time.
 		 */
 		if (conn->c_stage == ISCSI_CONN_STARTED &&
 		    !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
@@ -620,29 +709,35 @@ __iscsi_conn_send_pdu(struct iscsi_conn
 {
 	struct iscsi_session *session = conn->session;
 	struct iscsi_host *ihost = shost_priv(session->host);
+	uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 	struct iscsi_task *task;
 	itt_t itt;
 
 	if (session->state == ISCSI_STATE_TERMINATE)
 		return NULL;
 
-	if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
-	    hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+	if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) {
 		/*
 		 * Login and Text are sent serially, in
 		 * request-followed-by-response sequence.
 		 * Same task can be used. Same ITT must be used.
 		 * Note that login_task is preallocated at conn_create().
 		 */
+		if (conn->login_task->state != ISCSI_TASK_FREE) {
+			iscsi_conn_printk(KERN_ERR, conn, "Login/Text in "
+					  "progress. Cannot start new task.\n");
+			return NULL;
+		}
+
 		task = conn->login_task;
-	else {
+	} else {
 		if (session->state != ISCSI_STATE_LOGGED_IN)
 			return NULL;
 
 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
 
-		if (!__kfifo_get(session->cmdpool.queue,
+		if (!kfifo_out(&session->cmdpool.queue,
 				 (void*)&task, sizeof(void*)))
 			return NULL;
 	}
@@ -1357,6 +1452,7 @@ EXPORT_SYMBOL_GPL(iscsi_requeue_task);
  **/
 static int iscsi_data_xmit(struct iscsi_conn *conn)
 {
+	struct iscsi_task *task;
 	int rc = 0;
 
 	spin_lock_bh(&conn->session->lock);
@@ -1394,11 +1490,8 @@ check_mgmt:
 
 	/* process pending command queue */
 	while (!list_empty(&conn->cmdqueue)) {
-		if (conn->tmf_state == TMF_QUEUED)
-			break;
-
-		conn->task = list_entry(conn->cmdqueue.next,
-					 struct iscsi_task, running);
+		conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task,
+					running);
 		list_del_init(&conn->task->running);
 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
 			fail_scsi_task(conn->task, DID_IMM_RETRY);
@@ -1406,7 +1499,7 @@ check_mgmt:
 		}
 		rc = iscsi_prep_scsi_cmd_pdu(conn->task);
 		if (rc) {
-			if (rc == -ENOMEM) {
+			if (rc == -ENOMEM || rc == -EACCES) {
 				list_add_tail(&conn->task->running,
 					      &conn->cmdqueue);
 				conn->task = NULL;
@@ -1428,17 +1521,18 @@ check_mgmt:
 	}
 
 	while (!list_empty(&conn->requeue)) {
-		if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL)
-			break;
-
 		/*
 		 * we always do fastlogout - conn stop code will clean up.
 		 */
 		if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
 			break;
 
-		conn->task = list_entry(conn->requeue.next,
-					 struct iscsi_task, running);
+		task = list_entry(conn->requeue.next, struct iscsi_task,
+				  running);
+		if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
+			break;
+
+		conn->task = task;
 		list_del_init(&conn->task->running);
 		conn->task->state = ISCSI_TASK_RUNNING;
 		rc = iscsi_xmit_task(conn);
@@ -1473,7 +1567,7 @@ static inline struct iscsi_task *iscsi_a
 {
 	struct iscsi_task *task;
 
-	if (!__kfifo_get(conn->session->cmdpool.queue,
+	if (!kfifo_out(&conn->session->cmdpool.queue,
 			 (void *) &task, sizeof(void *)))
 		return NULL;
 
@@ -1591,7 +1685,7 @@ int iscsi_queuecommand(struct scsi_cmnd
 	if (!ihost->workq) {
 		reason = iscsi_prep_scsi_cmd_pdu(task);
 		if (reason) {
-			if (reason == -ENOMEM) {
+			if (reason == -ENOMEM ||  reason == -EACCES) {
 				reason = FAILURE_OOM;
 				goto prepd_reject;
 			} else {
@@ -1643,9 +1737,21 @@ fault:
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
-int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
 {
-	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	switch (reason) {
+	case SCSI_QDEPTH_DEFAULT:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	case SCSI_QDEPTH_QFULL:
+		scsi_track_queue_full(sdev, depth);
+		break;
+	case SCSI_QDEPTH_RAMP_UP:
+		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 	return sdev->queue_depth;
 }
 EXPORT_SYMBOL_GPL(iscsi_change_queue_depth);
@@ -1660,72 +1766,6 @@ int iscsi_target_alloc(struct scsi_targe
 }
 EXPORT_SYMBOL_GPL(iscsi_target_alloc);
 
-void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
-{
-	struct iscsi_session *session = cls_session->dd_data;
-
-	spin_lock_bh(&session->lock);
-	if (session->state != ISCSI_STATE_LOGGED_IN) {
-		session->state = ISCSI_STATE_RECOVERY_FAILED;
-		if (session->leadconn)
-			wake_up(&session->leadconn->ehwait);
-	}
-	spin_unlock_bh(&session->lock);
-}
-EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
-
-int iscsi_eh_target_reset(struct scsi_cmnd *sc)
-{
-	struct iscsi_cls_session *cls_session;
-	struct iscsi_session *session;
-	struct iscsi_conn *conn;
-
-	cls_session = starget_to_session(scsi_target(sc->device));
-	session = cls_session->dd_data;
-	conn = session->leadconn;
-
-	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->lock);
-	if (session->state == ISCSI_STATE_TERMINATE) {
-failed:
-		ISCSI_DBG_EH(session,
-			     "failing target reset: Could not log back into "
-			     "target [age %d]\n",
-			     session->age);
-		spin_unlock_bh(&session->lock);
-		mutex_unlock(&session->eh_mutex);
-		return FAILED;
-	}
-
-	spin_unlock_bh(&session->lock);
-	mutex_unlock(&session->eh_mutex);
-	/*
-	 * we drop the lock here but the leadconn cannot be destoyed while
-	 * we are in the scsi eh
-	 */
-	iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-
-	ISCSI_DBG_EH(session, "wait for relogin\n");
-	wait_event_interruptible(conn->ehwait,
-				 session->state == ISCSI_STATE_TERMINATE ||
-				 session->state == ISCSI_STATE_LOGGED_IN ||
-				 session->state == ISCSI_STATE_RECOVERY_FAILED);
-	if (signal_pending(current))
-		flush_signals(current);
-
-	mutex_lock(&session->eh_mutex);
-	spin_lock_bh(&session->lock);
-	if (session->state == ISCSI_STATE_LOGGED_IN) {
-		ISCSI_DBG_EH(session,
-			     "target reset succeeded\n");
-	} else
-		goto failed;
-	spin_unlock_bh(&session->lock);
-	mutex_unlock(&session->eh_mutex);
-	return SUCCESS;
-}
-EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
-
 static void iscsi_tmf_timedout(unsigned long data)
 {
 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
@@ -2108,6 +2148,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 		spin_lock_bh(&session->lock);
 		fail_scsi_task(task, DID_ABORT);
 		conn->tmf_state = TMF_INITIAL;
+		memset(hdr, 0, sizeof(*hdr));
 		spin_unlock_bh(&session->lock);
 		iscsi_start_tx(conn);
 		goto success_unlocked;
@@ -2118,6 +2159,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 	case TMF_NOT_FOUND:
 		if (!sc->SCp.ptr) {
 			conn->tmf_state = TMF_INITIAL;
+			memset(hdr, 0, sizeof(*hdr));
 			/* task completed before tmf abort response */
 			ISCSI_DBG_EH(session, "sc completed while abort	in "
 					      "progress\n");
@@ -2212,6 +2254,7 @@ int iscsi_eh_device_reset(struct scsi_cm
 	iscsi_suspend_tx(conn);
 
 	spin_lock_bh(&session->lock);
+	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
 	conn->tmf_state = TMF_INITIAL;
 	spin_unlock_bh(&session->lock);
@@ -2229,6 +2272,172 @@ done:
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_device_reset);
 
+void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
+{
+	struct iscsi_session *session = cls_session->dd_data;
+
+	spin_lock_bh(&session->lock);
+	if (session->state != ISCSI_STATE_LOGGED_IN) {
+		session->state = ISCSI_STATE_RECOVERY_FAILED;
+		if (session->leadconn)
+			wake_up(&session->leadconn->ehwait);
+	}
+	spin_unlock_bh(&session->lock);
+}
+EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
+
+/**
+ * iscsi_eh_session_reset - drop session and attempt relogin
+ * @sc: scsi command
+ *
+ * This function will wait for a relogin, session termination from
+ * userspace, or a recovery/replacement timeout.
+ */
+static int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_session *session;
+	struct iscsi_conn *conn;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+	conn = session->leadconn;
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	if (session->state == ISCSI_STATE_TERMINATE) {
+failed:
+		ISCSI_DBG_EH(session,
+			     "failing session reset: Could not log back into "
+			     "%s, %s [age %d]\n", session->targetname,
+			     conn->persistent_address, session->age);
+		spin_unlock_bh(&session->lock);
+		mutex_unlock(&session->eh_mutex);
+		return FAILED;
+	}
+
+	spin_unlock_bh(&session->lock);
+	mutex_unlock(&session->eh_mutex);
+	/*
+	 * we drop the lock here but the leadconn cannot be destoyed while
+	 * we are in the scsi eh
+	 */
+	iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+	ISCSI_DBG_EH(session, "wait for relogin\n");
+	wait_event_interruptible(conn->ehwait,
+				 session->state == ISCSI_STATE_TERMINATE ||
+				 session->state == ISCSI_STATE_LOGGED_IN ||
+				 session->state == ISCSI_STATE_RECOVERY_FAILED);
+	if (signal_pending(current))
+		flush_signals(current);
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	if (session->state == ISCSI_STATE_LOGGED_IN) {
+		ISCSI_DBG_EH(session,
+			     "session reset succeeded for %s,%s\n",
+			     session->targetname, conn->persistent_address);
+	} else
+		goto failed;
+	spin_unlock_bh(&session->lock);
+	mutex_unlock(&session->eh_mutex);
+	return SUCCESS;
+}
+
+static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
+{
+	memset(hdr, 0, sizeof(*hdr));
+	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+	hdr->flags = ISCSI_TM_FUNC_TARGET_WARM_RESET & ISCSI_FLAG_TM_FUNC_MASK;
+	hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+	hdr->rtt = RESERVED_ITT;
+}
+
+/**
+ * iscsi_eh_target_reset - reset target
+ * @sc: scsi command
+ *
+ * This will attempt to send a warm target reset. If that fails
+ * then we will drop the session and attempt ERL0 recovery.
+ */
+int iscsi_eh_target_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_session *session;
+	struct iscsi_conn *conn;
+	struct iscsi_tm *hdr;
+	int rc = FAILED;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	session = cls_session->dd_data;
+
+	ISCSI_DBG_EH(session, "tgt Reset [sc %p tgt %s]\n", sc,
+		     session->targetname);
+
+	mutex_lock(&session->eh_mutex);
+	spin_lock_bh(&session->lock);
+	/*
+	 * Just check if we are not logged in. We cannot check for
+	 * the phase because the reset could come from a ioctl.
+	 */
+	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+		goto unlock;
+	conn = session->leadconn;
+
+	/* only have one tmf outstanding at a time */
+	if (conn->tmf_state != TMF_INITIAL)
+		goto unlock;
+	conn->tmf_state = TMF_QUEUED;
+
+	hdr = &conn->tmhdr;
+	iscsi_prep_tgt_reset_pdu(sc, hdr);
+
+	if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
+				    session->tgt_reset_timeout)) {
+		rc = FAILED;
+		goto unlock;
+	}
+
+	switch (conn->tmf_state) {
+	case TMF_SUCCESS:
+		break;
+	case TMF_TIMEDOUT:
+		spin_unlock_bh(&session->lock);
+		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+		goto done;
+	default:
+		conn->tmf_state = TMF_INITIAL;
+		goto unlock;
+	}
+
+	rc = SUCCESS;
+	spin_unlock_bh(&session->lock);
+
+	iscsi_suspend_tx(conn);
+
+	spin_lock_bh(&session->lock);
+	memset(hdr, 0, sizeof(*hdr));
+	fail_scsi_tasks(conn, -1, DID_ERROR);
+	conn->tmf_state = TMF_INITIAL;
+	spin_unlock_bh(&session->lock);
+
+	iscsi_start_tx(conn);
+	goto done;
+
+unlock:
+	spin_unlock_bh(&session->lock);
+done:
+	ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
+		     rc == SUCCESS ? "SUCCESS" : "FAILED");
+	mutex_unlock(&session->eh_mutex);
+
+	if (rc == FAILED)
+		rc = iscsi_eh_session_reset(sc);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+
 /*
  * Pre-allocate a pool of @max items of @item_size. By default, the pool
  * should be accessed via kfifo_{get,put} on q->queue.
@@ -2252,12 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, in
 	if (q->pool == NULL)
 		return -ENOMEM;
 
-	q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
-			      GFP_KERNEL, NULL);
-	if (IS_ERR(q->queue)) {
-		q->queue = NULL;
-		goto enomem;
-	}
+	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
 	for (i = 0; i < max; i++) {
 		q->pool[i] = kzalloc(item_size, GFP_KERNEL);
@@ -2265,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, in
 			q->max = i;
 			goto enomem;
 		}
-		__kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
+		kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*));
 	}
 
 	if (items) {
@@ -2288,7 +2492,6 @@ void iscsi_pool_free(struct iscsi_pool *
 	for (i = 0; i < q->max; i++)
 		kfree(q->pool[i]);
 	kfree(q->pool);
-	kfree(q->queue);
 }
 EXPORT_SYMBOL_GPL(iscsi_pool_free);
 
@@ -2495,6 +2698,7 @@ iscsi_session_setup(struct iscsi_transpo
 	session->host = shost;
 	session->state = ISCSI_STATE_FREE;
 	session->fast_abort = 1;
+	session->tgt_reset_timeout = 30;
 	session->lu_reset_timeout = 15;
 	session->abort_timeout = 10;
 	session->scsi_cmds_max = scsi_cmds;
@@ -2615,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio
 
 	/* allocate login_task used for the login/text sequences */
 	spin_lock_bh(&session->lock);
-	if (!__kfifo_get(session->cmdpool.queue,
+	if (!kfifo_out(&session->cmdpool.queue,
                          (void*)&conn->login_task,
 			 sizeof(void*))) {
 		spin_unlock_bh(&session->lock);
@@ -2635,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio
 	return cls_conn;
 
 login_task_data_alloc_fail:
-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 login_task_alloc_fail:
 	iscsi_destroy_conn(cls_conn);
@@ -2698,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cl
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
@@ -2856,6 +3060,7 @@ static void iscsi_start_session_recovery
 	spin_lock_bh(&session->lock);
 	fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED);
 	fail_mgmt_tasks(session, conn);
+	memset(&conn->tmhdr, 0, sizeof(conn->tmhdr));
 	spin_unlock_bh(&session->lock);
 	mutex_unlock(&session->eh_mutex);
 }
@@ -2932,6 +3137,9 @@ int iscsi_set_param(struct iscsi_cls_con
 	case ISCSI_PARAM_LU_RESET_TMO:
 		sscanf(buf, "%d", &session->lu_reset_timeout);
 		break;
+	case ISCSI_PARAM_TGT_RESET_TMO:
+		sscanf(buf, "%d", &session->tgt_reset_timeout);
+		break;
 	case ISCSI_PARAM_PING_TMO:
 		sscanf(buf, "%d", &conn->ping_timeout);
 		break;
@@ -3031,6 +3239,9 @@ int iscsi_session_get_param(struct iscsi
 	case ISCSI_PARAM_LU_RESET_TMO:
 		len = sprintf(buf, "%d\n", session->lu_reset_timeout);
 		break;
+	case ISCSI_PARAM_TGT_RESET_TMO:
+		len = sprintf(buf, "%d\n", session->tgt_reset_timeout);
+		break;
 	case ISCSI_PARAM_INITIAL_R2T_EN:
 		len = sprintf(buf, "%d\n", session->initial_r2t_en);
 		break;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libiscsi_tcp.c linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi_tcp.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libiscsi_tcp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libiscsi_tcp.c	2010-02-24 13:52:17.000000000 -0500
@@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi
 		return;
 
 	/* flush task's r2t queues */
-	while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+	while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
 	}
 
 	r2t = tcp_task->r2t;
 	if (r2t != NULL) {
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		tcp_task->r2t = NULL;
 	}
@@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 		return 0;
 	}
 
-	rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
+	rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
@@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 	if (r2t->data_length == 0) {
 		iscsi_conn_printk(KERN_ERR, conn,
 				  "invalid R2T with zero data len\n");
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 				  "invalid R2T with data len %u at offset %u "
 				  "and total length %d\n", r2t->data_length,
 				  r2t->data_offset, scsi_out(task->sc)->length);
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 	r2t->sent = 0;
 
 	tcp_task->exp_datasn = r2tsn + 1;
-	__kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
+	kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
 	conn->r2t_pdus_cnt++;
 
 	iscsi_requeue_task(task);
@@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_tas
 		return conn->session->tt->init_pdu(task, 0, task->data_count);
 	}
 
-	BUG_ON(__kfifo_len(tcp_task->r2tqueue));
+	BUG_ON(kfifo_len(&tcp_task->r2tqueue));
 	tcp_task->exp_datasn = 0;
 
 	/* Prepare PDU, optionally w/ immediate data */
@@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_
 			if (r2t->data_length <= r2t->sent) {
 				ISCSI_DBG_TCP(task->conn,
 					      "  done with r2t %p\n", r2t);
-				__kfifo_put(tcp_task->r2tpool.queue,
+				kfifo_in(&tcp_task->r2tpool.queue,
 					    (void *)&tcp_task->r2t,
 					    sizeof(void *));
 				tcp_task->r2t = r2t = NULL;
@@ -990,9 +990,12 @@ static struct iscsi_r2t_info *iscsi_tcp_
 		}
 
 		if (r2t == NULL) {
-			__kfifo_get(tcp_task->r2tqueue,
-				    (void *)&tcp_task->r2t, sizeof(void *));
-			r2t = tcp_task->r2t;
+			if (kfifo_out(&tcp_task->r2tqueue,
+			    (void *)&tcp_task->r2t, sizeof(void *)) !=
+			    sizeof(void *))
+				r2t = NULL;
+			else
+				r2t = tcp_task->r2t;
 		}
 		spin_unlock_bh(&session->lock);
 	}
@@ -1004,7 +1007,7 @@ static struct iscsi_r2t_info *iscsi_tcp_
  * iscsi_tcp_task_xmit - xmit normal PDU task
  * @task: iscsi command task
  *
- * We're expected to return 0 when everything was transmitted succesfully,
+ * We're expected to return 0 when everything was transmitted successfully,
  * -EAGAIN if there's still data in the queue, or != 0 for any other kind
  * of error.
  */
@@ -1127,9 +1130,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi
 		}
 
 		/* R2T xmit queue */
-		tcp_task->r2tqueue = kfifo_alloc(
-		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
-		if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) {
+		if (kfifo_alloc(&tcp_task->r2tqueue,
+		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
@@ -1142,7 +1144,7 @@ r2t_alloc_fail:
 		struct iscsi_task *task = session->cmds[i];
 		struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-		kfifo_free(tcp_task->r2tqueue);
+		kfifo_free(&tcp_task->r2tqueue);
 		iscsi_pool_free(&tcp_task->r2tpool);
 	}
 	return -ENOMEM;
@@ -1157,7 +1159,7 @@ void iscsi_tcp_r2tpool_free(struct iscsi
 		struct iscsi_task *task = session->cmds[i];
 		struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-		kfifo_free(tcp_task->r2tqueue);
+		kfifo_free(&tcp_task->r2tqueue);
 		iscsi_pool_free(&tcp_task->r2tpool);
 	}
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libsas/sas_scsi_host.c linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_scsi_host.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libsas/sas_scsi_host.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libsas/sas_scsi_host.c	2010-02-24 13:52:17.000000000 -0500
@@ -820,10 +820,14 @@ void sas_slave_destroy(struct scsi_devic
 		ata_port_disable(dev->sata_dev.ap);
 }
 
-int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
+int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
+			   int reason)
 {
 	int res = min(new_depth, SAS_MAX_QD);
 
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (scsi_dev->tagged_supported)
 		scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
 					res);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/libsrp.c linux-libre-2.6.33-gnu1/drivers/scsi/libsrp.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/libsrp.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/libsrp.c	2010-02-24 13:52:17.000000000 -0500
@@ -58,19 +58,15 @@ static int srp_iu_pool_alloc(struct srp_
 		goto free_pool;
 
 	spin_lock_init(&q->lock);
-	q->queue = kfifo_init((void *) q->pool, max * sizeof(void *),
-			      GFP_KERNEL, &q->lock);
-	if (IS_ERR(q->queue))
-		goto free_item;
+	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
-		__kfifo_put(q->queue, (void *) &iue, sizeof(void *));
+		kfifo_in(&q->queue, (void *) &iue, sizeof(void *));
 		iue->sbuf = ring[i];
 		iue++;
 	}
 	return 0;
 
-free_item:
 	kfree(q->items);
 free_pool:
 	kfree(q->pool);
@@ -167,7 +163,11 @@ struct iu_entry *srp_iu_get(struct srp_t
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue,
+		sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) {
+			WARN_ONCE(1, "unexpected fifo state");
+			return NULL;
+	}
 	if (!iue)
 		return iue;
 	iue->target = target;
@@ -179,7 +179,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get);
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_attr.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_attr.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_attr.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_attr.c	2010-02-24 13:52:17.000000000 -0500
@@ -23,12 +23,14 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/aer.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -98,6 +100,28 @@ lpfc_drvr_version_show(struct device *de
 	return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
 }
 
+/**
+ * lpfc_enable_fip_show - Return the fip mode of the HBA
+ * @dev: class unused variable.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the module description text.
+ *
+ * Returns: size of formatted string.
+ **/
+static ssize_t
+lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
+		       char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+
+	if (phba->hba_flag & HBA_FIP_SUPPORT)
+		return snprintf(buf, PAGE_SIZE, "1\n");
+	else
+		return snprintf(buf, PAGE_SIZE, "0\n");
+}
+
 static ssize_t
 lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
 		  char *buf)
@@ -654,7 +678,7 @@ lpfc_selective_reset(struct lpfc_hba *ph
  * Notes:
  * Assumes any error from lpfc_selective_reset() will be negative.
  * If lpfc_selective_reset() returns zero then the length of the buffer
- * is returned which indicates succcess
+ * is returned which indicates success
  *
  * Returns:
  * -EINVAL if the buffer does not contain the string "selective"
@@ -762,9 +786,15 @@ lpfc_board_mode_store(struct device *dev
 	} else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
 		status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
 	else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
-		status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			return -EINVAL;
+		else
+			status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
 	else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
-		status = lpfc_do_offline(phba, LPFC_EVT_KILL);
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			return -EINVAL;
+		else
+			status = lpfc_do_offline(phba, LPFC_EVT_KILL);
 	else
 		return -EINVAL;
 
@@ -1126,6 +1156,9 @@ lpfc_poll_store(struct device *dev, stru
 	if ((val & 0x3) != val)
 		return -EINVAL;
 
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		val = 0;
+
 	spin_lock_irq(&phba->hbalock);
 
 	old_val = phba->cfg_poll;
@@ -1589,6 +1622,7 @@ static DEVICE_ATTR(num_discovered_ports,
 static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
 static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
 static DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL);
+static DEVICE_ATTR(lpfc_enable_fip, S_IRUGO, lpfc_enable_fip_show, NULL);
 static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
 		   lpfc_board_mode_show, lpfc_board_mode_store);
 static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
@@ -2759,6 +2793,196 @@ static DEVICE_ATTR(lpfc_link_speed, S_IR
 		lpfc_link_speed_show, lpfc_link_speed_store);
 
 /*
+# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
+#       0  = aer disabled or not supported
+#       1  = aer supported and enabled (default)
+# Value range is [0,1]. Default value is 1.
+*/
+
+/**
+ * lpfc_aer_support_store - Set the adapter for aer support
+ *
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string "selective".
+ * @count: unused variable.
+ *
+ * Description:
+ * If the val is 1 and currently the device's AER capability was not
+ * enabled, invoke the kernel's enable AER helper routine, trying to
+ * enable the device's AER capability. If the helper routine enabling
+ * AER returns success, update the device's cfg_aer_support flag to
+ * indicate AER is supported by the device; otherwise, if the device
+ * AER capability is already enabled to support AER, then do nothing.
+ *
+ * If the val is 0 and currently the device's AER support was enabled,
+ * invoke the kernel's disable AER helper routine. After that, update
+ * the device's cfg_aer_support flag to indicate AER is not supported
+ * by the device; otherwise, if the device AER capability is already
+ * disabled from supporting AER, then do nothing.
+ *
+ * Returns:
+ * length of the buf on success if val is in range the intended mode
+ * is supported.
+ * -EINVAL if val out of range or intended mode is not supported.
+ **/
+static ssize_t
+lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	int val = 0, rc = -EINVAL;
+
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
+		return -EPERM;
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+
+	switch (val) {
+	case 0:
+		if (phba->hba_flag & HBA_AER_ENABLED) {
+			rc = pci_disable_pcie_error_reporting(phba->pcidev);
+			if (!rc) {
+				spin_lock_irq(&phba->hbalock);
+				phba->hba_flag &= ~HBA_AER_ENABLED;
+				spin_unlock_irq(&phba->hbalock);
+				phba->cfg_aer_support = 0;
+				rc = strlen(buf);
+			} else
+				rc = -EPERM;
+		} else {
+			phba->cfg_aer_support = 0;
+			rc = strlen(buf);
+		}
+		break;
+	case 1:
+		if (!(phba->hba_flag & HBA_AER_ENABLED)) {
+			rc = pci_enable_pcie_error_reporting(phba->pcidev);
+			if (!rc) {
+				spin_lock_irq(&phba->hbalock);
+				phba->hba_flag |= HBA_AER_ENABLED;
+				spin_unlock_irq(&phba->hbalock);
+				phba->cfg_aer_support = 1;
+				rc = strlen(buf);
+			} else
+				 rc = -EPERM;
+		} else {
+			phba->cfg_aer_support = 1;
+			rc = strlen(buf);
+		}
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static int lpfc_aer_support = 1;
+module_param(lpfc_aer_support, int, 1);
+MODULE_PARM_DESC(lpfc_aer_support, "Enable PCIe device AER support");
+lpfc_param_show(aer_support)
+
+/**
+ * lpfc_aer_support_init - Set the initial adapters aer support flag
+ * @phba: lpfc_hba pointer.
+ * @val: link speed value.
+ *
+ * Description:
+ * If val is in a valid range [0,1], then set the adapter's initial
+ * cfg_aer_support field. It will be up to the driver's probe_one
+ * routine to determine whether the device's AER support can be set
+ * or not.
+ *
+ * Notes:
+ * If the value is not in range log a kernel error message, and
+ * choose the default value of setting AER support and return.
+ *
+ * Returns:
+ * zero if val saved.
+ * -EINVAL val out of range
+ **/
+static int
+lpfc_aer_support_init(struct lpfc_hba *phba, int val)
+{
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
+		phba->cfg_aer_support = 0;
+		return -EPERM;
+	}
+
+	if (val == 0 || val == 1) {
+		phba->cfg_aer_support = val;
+		return 0;
+	}
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2712 lpfc_aer_support attribute value %d out "
+			"of range, allowed values are 0|1, setting it "
+			"to default value of 1\n", val);
+	/* By default, try to enable AER on a device */
+	phba->cfg_aer_support = 1;
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(lpfc_aer_support, S_IRUGO | S_IWUSR,
+		   lpfc_aer_support_show, lpfc_aer_support_store);
+
+/**
+ * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string "selective".
+ * @count: unused variable.
+ *
+ * Description:
+ * If the @buf contains 1 and the device currently has the AER support
+ * enabled, then invokes the kernel AER helper routine
+ * pci_cleanup_aer_uncorrect_error_status to clean up the uncorrectable
+ * error status register.
+ *
+ * Notes:
+ *
+ * Returns:
+ * -EINVAL if the buf does not contain the 1 or the device is not currently
+ * enabled with the AER support.
+ **/
+static ssize_t
+lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct Scsi_Host  *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	int val, rc = -1;
+
+	/* AER not supported on OC devices yet */
+	if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
+		return -EPERM;
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+	if (val != 1)
+		return -EINVAL;
+
+	if (phba->hba_flag & HBA_AER_ENABLED)
+		rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev);
+
+	if (rc == 0)
+		return strlen(buf);
+	else
+		return -EPERM;
+}
+
+static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
+		   lpfc_aer_cleanup_state);
+
+/*
 # lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
 # Value range is [2,3]. Default value is 3.
 */
@@ -2846,7 +3070,7 @@ LPFC_ATTR_R(multi_ring_support, 1, 1, 2,
 # identifies what rctl value to configure the additional ring for.
 # Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
 */
-LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1,
+LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
 	     255, "Identifies RCTL for additional ring configuration");
 
 /*
@@ -2854,7 +3078,7 @@ LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DA
 # identifies what type value to configure the additional ring for.
 # Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
 */
-LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1,
+LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
 	     255, "Identifies TYPE for additional ring configuration");
 
 /*
@@ -2947,15 +3171,6 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0,
 LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
 
 /*
-# lpfc_enable_fip: When set, FIP is required to start discovery. If not
-# set, the driver will add an FCF record manually if the port has no
-# FCF records available and start discovery.
-# Value range is [0,1]. Default value is 1 (enabled)
-*/
-LPFC_ATTR_RW(enable_fip, 0, 0, 1, "Enable FIP Discovery");
-
-
-/*
 # lpfc_prot_mask: i
 #	- Bit mask of host protection capabilities used to register with the
 #	  SCSI mid-layer
@@ -3013,6 +3228,7 @@ struct device_attribute *lpfc_hba_attrs[
 	&dev_attr_num_discovered_ports,
 	&dev_attr_menlo_mgmt_mode,
 	&dev_attr_lpfc_drvr_version,
+	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_temp_sensor,
 	&dev_attr_lpfc_log_verbose,
 	&dev_attr_lpfc_lun_queue_depth,
@@ -3020,7 +3236,6 @@ struct device_attribute *lpfc_hba_attrs[
 	&dev_attr_lpfc_peer_port_login,
 	&dev_attr_lpfc_nodev_tmo,
 	&dev_attr_lpfc_devloss_tmo,
-	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_fcp_class,
 	&dev_attr_lpfc_use_adisc,
 	&dev_attr_lpfc_ack0,
@@ -3061,6 +3276,8 @@ struct device_attribute *lpfc_hba_attrs[
 	&dev_attr_lpfc_max_scsicmpl_time,
 	&dev_attr_lpfc_stat_data_ctrl,
 	&dev_attr_lpfc_prot_sg_seg_cnt,
+	&dev_attr_lpfc_aer_support,
+	&dev_attr_lpfc_aer_state_cleanup,
 	NULL,
 };
 
@@ -3073,7 +3290,6 @@ struct device_attribute *lpfc_vport_attr
 	&dev_attr_lpfc_lun_queue_depth,
 	&dev_attr_lpfc_nodev_tmo,
 	&dev_attr_lpfc_devloss_tmo,
-	&dev_attr_lpfc_enable_fip,
 	&dev_attr_lpfc_hba_queue_depth,
 	&dev_attr_lpfc_peer_port_login,
 	&dev_attr_lpfc_restrict_login,
@@ -3147,7 +3363,7 @@ sysfs_ctlreg_write(struct kobject *kobj,
  * sysfs_ctlreg_read - Read method for reading from ctlreg
  * @kobj: kernel kobject that contains the kernel class device.
  * @bin_attr: kernel attributes passed to us.
- * @buf: if succesful contains the data from the adapter IOREG space.
+ * @buf: if successful contains the data from the adapter IOREG space.
  * @off: offset into buffer to beginning of data.
  * @count: bytes to transfer.
  *
@@ -3815,7 +4031,11 @@ lpfc_get_stats(struct Scsi_Host *shost)
 	hs->invalid_crc_count -= lso->invalid_crc_count;
 	hs->error_frames -= lso->error_frames;
 
-	if (phba->fc_topology == TOPOLOGY_LOOP) {
+	if (phba->hba_flag & HBA_FCOE_SUPPORT) {
+		hs->lip_count = -1;
+		hs->nos_count = (phba->link_events >> 1);
+		hs->nos_count -= lso->link_events;
+	} else if (phba->fc_topology == TOPOLOGY_LOOP) {
 		hs->lip_count = (phba->fc_eventTag >> 1);
 		hs->lip_count -= lso->link_events;
 		hs->nos_count = -1;
@@ -3906,7 +4126,10 @@ lpfc_reset_stats(struct Scsi_Host *shost
 	lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
 	lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
 	lso->error_frames = pmb->un.varRdLnk.crcCnt;
-	lso->link_events = (phba->fc_eventTag >> 1);
+	if (phba->hba_flag & HBA_FCOE_SUPPORT)
+		lso->link_events = (phba->link_events >> 1);
+	else
+		lso->link_events = (phba->fc_eventTag >> 1);
 
 	psli->stats_start = get_seconds();
 
@@ -4222,14 +4445,17 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
 	lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
 	lpfc_enable_bg_init(phba, lpfc_enable_bg);
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		phba->cfg_poll = 0;
+	else
 	phba->cfg_poll = lpfc_poll;
 	phba->cfg_soft_wwnn = 0L;
 	phba->cfg_soft_wwpn = 0L;
 	lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
 	lpfc_prot_sg_seg_cnt_init(phba, lpfc_prot_sg_seg_cnt);
 	lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
-	lpfc_enable_fip_init(phba, lpfc_enable_fip);
 	lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
+	lpfc_aer_support_init(phba, lpfc_aer_support);
 
 	return;
 }
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_bsg.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_bsg.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_bsg.c	2010-02-24 13:52:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/scsi_bsg_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -148,8 +149,8 @@ lpfc_bsg_rport_ct(struct fc_bsg_job *job
 	cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
 	cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
 	cmd->un.genreq64.w5.hcsw.Dfctl = 0;
-	cmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
-	cmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+	cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	cmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
 	cmd->ulpBdeCount = 1;
 	cmd->ulpLe = 1;
 	cmd->ulpClass = CLASS3;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_crtn.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_crtn.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_crtn.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_crtn.h	2010-02-24 13:52:17.000000000 -0500
@@ -49,6 +49,8 @@ void lpfc_init_link(struct lpfc_hba *, L
 void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
 
 struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
+void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
+void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
 void lpfc_cleanup_rpis(struct lpfc_vport *, int);
 int lpfc_linkdown(struct lpfc_hba *);
 void lpfc_linkdown_port(struct lpfc_vport *);
@@ -144,6 +146,8 @@ void lpfc_hb_timeout_handler(struct lpfc
 
 void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
 			 struct lpfc_iocbq *);
+void lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+				    struct lpfc_iocbq *);
 int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
 int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
 void lpfc_fdmi_tmo(unsigned long);
@@ -188,7 +192,7 @@ int lpfc_mbox_tmo_val(struct lpfc_hba *,
 void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *);
 void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t);
 void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t);
-void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t);
+void lpfc_unreg_vfi(struct lpfcMboxq *, struct lpfc_vport *);
 void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *);
 void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
 void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
@@ -212,7 +216,10 @@ void lpfc_stop_vport_timers(struct lpfc_
 void lpfc_poll_timeout(unsigned long ptr);
 void lpfc_poll_start_timer(struct lpfc_hba *);
 void lpfc_poll_eratt(unsigned long);
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba *);
+int
+lpfc_sli_handle_fast_ring_event(struct lpfc_hba *,
+			struct lpfc_sli_ring *, uint32_t);
+
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *);
@@ -235,7 +242,7 @@ void lpfc_sli_mbox_sys_shutdown(struct l
 int lpfc_sli_check_eratt(struct lpfc_hba *);
 void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
 				    struct lpfc_sli_ring *, uint32_t);
-int lpfc_sli4_handle_received_buffer(struct lpfc_hba *);
+void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *);
 void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
 			struct lpfc_iocbq *, uint32_t);
@@ -361,6 +368,7 @@ void lpfc_stop_port(struct lpfc_hba *);
 void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
 int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
 void lpfc_start_fdiscs(struct lpfc_hba *phba);
+struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
 
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
 #define HBA_EVENT_RSCN                   5
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_ct.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_ct.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_ct.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_ct.c	2010-02-24 13:52:17.000000000 -0500
@@ -31,6 +31,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -87,7 +88,6 @@ void
 lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		    struct lpfc_iocbq *piocbq)
 {
-
 	struct lpfc_dmabuf *mp = NULL;
 	IOCB_t *icmd = &piocbq->iocb;
 	int i;
@@ -160,6 +160,39 @@ lpfc_ct_unsol_event(struct lpfc_hba *phb
 	}
 }
 
+/**
+ * lpfc_sli4_ct_abort_unsol_event - Default handle for sli4 unsol abort
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to the driver internal I/O ring.
+ * @piocbq: Pointer to the IOCBQ.
+ *
+ * This function serves as the default handler for the sli4 unsolicited
+ * abort event. It shall be invoked when there is no application interface
+ * registered unsolicited abort handler. This handler does nothing but
+ * just simply releases the dma buffer used by the unsol abort event.
+ **/
+void
+lpfc_sli4_ct_abort_unsol_event(struct lpfc_hba *phba,
+			       struct lpfc_sli_ring *pring,
+			       struct lpfc_iocbq *piocbq)
+{
+	IOCB_t *icmd = &piocbq->iocb;
+	struct lpfc_dmabuf *bdeBuf;
+	uint32_t size;
+
+	/* Forward abort event to any process registered to receive ct event */
+	lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
+
+	/* If there is no BDE associated with IOCB, there is nothing to do */
+	if (icmd->ulpBdeCount == 0)
+		return;
+	bdeBuf = piocbq->context2;
+	piocbq->context2 = NULL;
+	size  = icmd->un.cont64[0].tus.f.bdeSize;
+	lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
+	lpfc_in_buf_free(phba, bdeBuf);
+}
+
 static void
 lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
 {
@@ -304,8 +337,8 @@ lpfc_gen_req(struct lpfc_vport *vport, s
 	/* Fill in rest of iocb */
 	icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
 	icmd->un.genreq64.w5.hcsw.Dfctl = 0;
-	icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
-	icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+	icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+	icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
 
 	if (!tmo) {
 		 /* FC spec states we need 3 * ratov for CT requests */
@@ -363,9 +396,14 @@ lpfc_ct_cmd(struct lpfc_vport *vport, st
 	outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
 	if (!outmp)
 		return -ENOMEM;
-
+	/*
+	 * Form the CT IOCB.  The total number of BDEs in this IOCB
+	 * is the single command plus response count from
+	 * lpfc_alloc_ct_rsp.
+	 */
+	cnt += 1;
 	status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
-			      cnt+1, 0, retry);
+			      cnt, 0, retry);
 	if (status) {
 		lpfc_free_ct_rsp(phba, outmp);
 		return -ENOMEM;
@@ -501,6 +539,9 @@ lpfc_ns_rsp(struct lpfc_vport *vport, st
 							SLI_CTNS_GFF_ID,
 							0, Did) == 0)
 							vport->num_disc_nodes++;
+						else
+							lpfc_setup_disc_node
+								(vport, Did);
 					}
 					else {
 						lpfc_debugfs_disc_trc(vport,
@@ -1209,7 +1250,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, in
 		    be16_to_cpu(SLI_CTNS_RFF_ID);
 		CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
 		CtReq->un.rff.fbits = FC4_FEATURE_INIT;
-		CtReq->un.rff.type_code = FC_FCP_DATA;
+		CtReq->un.rff.type_code = FC_TYPE_FCP;
 		cmpl = lpfc_cmpl_ct_cmd_rff_id;
 		break;
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_debugfs.c	2010-02-24 13:52:17.000000000 -0500
@@ -926,7 +926,7 @@ lpfc_debugfs_dumpData_open(struct inode
 		goto out;
 
 	/* Round to page boundry */
-	printk(KERN_ERR "BLKGRD %s: _dump_buf_data=0x%p\n",
+	printk(KERN_ERR "9059 BLKGRD:  %s: _dump_buf_data=0x%p\n",
 			__func__, _dump_buf_data);
 	debug->buffer = _dump_buf_data;
 	if (!debug->buffer) {
@@ -956,8 +956,8 @@ lpfc_debugfs_dumpDif_open(struct inode *
 		goto out;
 
 	/* Round to page boundry */
-	printk(KERN_ERR "BLKGRD %s: _dump_buf_dif=0x%p file=%s\n", __func__,
-	       _dump_buf_dif, file->f_dentry->d_name.name);
+	printk(KERN_ERR	"9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%s\n",
+		__func__, _dump_buf_dif, file->f_dentry->d_name.name);
 	debug->buffer = _dump_buf_dif;
 	if (!debug->buffer) {
 		kfree(debug);
@@ -1377,7 +1377,7 @@ lpfc_debugfs_initialize(struct lpfc_vpor
 			debugfs_create_dir(name, phba->hba_debugfs_root);
 		if (!vport->vport_debugfs_root) {
 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
-					 "0417 Cant create debugfs");
+					 "0417 Cant create debugfs\n");
 			goto debug_failed;
 		}
 		atomic_inc(&phba->debugfs_vport_count);
@@ -1430,7 +1430,7 @@ lpfc_debugfs_initialize(struct lpfc_vpor
 				 vport, &lpfc_debugfs_op_nodelist);
 	if (!vport->debug_nodelist) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
-				 "0409 Cant create debugfs nodelist");
+				 "0409 Cant create debugfs nodelist\n");
 		goto debug_failed;
 	}
 debug_failed:
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_disc.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_disc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_disc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_disc.h	2010-02-24 13:52:17.000000000 -0500
@@ -19,7 +19,7 @@
  *******************************************************************/
 
 #define FC_MAX_HOLD_RSCN     32	      /* max number of deferred RSCNs */
-#define FC_MAX_NS_RSP        65536    /* max size NameServer rsp */
+#define FC_MAX_NS_RSP        64512    /* max size NameServer rsp */
 #define FC_MAXLOOP           126      /* max devices supported on a fc loop */
 #define LPFC_DISC_FLOGI_TMO  10	      /* Discovery FLOGI ratov */
 
@@ -105,8 +105,6 @@ struct lpfc_nodelist {
 	struct lpfc_vport *vport;
 	struct lpfc_work_evt els_retry_evt;
 	struct lpfc_work_evt dev_loss_evt;
-	unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
-	unsigned long last_q_full_time;		/* jiffy of last queue full */
 	struct kref     kref;
 	atomic_t cmd_pending;
 	uint32_t cmd_qdepth;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_els.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_els.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_els.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_els.c	2010-02-24 13:52:17.000000000 -0500
@@ -173,13 +173,26 @@ lpfc_prep_els_iocb(struct lpfc_vport *vp
 	 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
 	 */
 	if ((did == Fabric_DID) &&
-		bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) &&
+		(phba->hba_flag & HBA_FIP_SUPPORT) &&
 		((elscmd == ELS_CMD_FLOGI) ||
 		 (elscmd == ELS_CMD_FDISC) ||
 		 (elscmd == ELS_CMD_LOGO)))
-		elsiocb->iocb_flag |= LPFC_FIP_ELS;
+		switch (elscmd) {
+		case ELS_CMD_FLOGI:
+		elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		case ELS_CMD_FDISC:
+		elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		case ELS_CMD_LOGO:
+		elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
+					& LPFC_FIP_ELS_ID_MASK);
+		break;
+		}
 	else
-		elsiocb->iocb_flag &= ~LPFC_FIP_ELS;
+		elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
 
 	icmd = &elsiocb->iocb;
 
@@ -591,7 +604,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
 	} else {
 		ndlp->nlp_type |= NLP_FABRIC;
 		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
-		if (vport->vfi_state & LPFC_VFI_REGISTERED) {
+		if (vport->vpi_state & LPFC_VPI_REGISTERED) {
 			lpfc_start_fdiscs(phba);
 			lpfc_do_scr_ns_plogi(phba, vport);
 		} else
@@ -802,7 +815,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phb
 
 	/* FLOGI completes successfully */
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-			 "0101 FLOGI completes sucessfully "
+			 "0101 FLOGI completes successfully "
 			 "Data: x%x x%x x%x x%x\n",
 			 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
 			 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
@@ -2452,6 +2465,7 @@ lpfc_els_retry_delay_handler(struct lpfc
 	 */
 	del_timer_sync(&ndlp->nlp_delayfunc);
 	retry = ndlp->nlp_retry;
+	ndlp->nlp_retry = 0;
 
 	switch (cmd) {
 	case ELS_CMD_FLOGI:
@@ -2711,12 +2725,16 @@ lpfc_els_retry(struct lpfc_hba *phba, st
 	    !lpfc_error_lost_link(irsp)) {
 		/* FLOGI retry policy */
 		retry = 1;
-		maxretry = 48;
-		if (cmdiocb->retry >= 32)
+		/* retry forever */
+		maxretry = 0;
+		if (cmdiocb->retry >= 100)
+			delay = 5000;
+		else if (cmdiocb->retry >= 32)
 			delay = 1000;
 	}
 
-	if ((++cmdiocb->retry) >= maxretry) {
+	cmdiocb->retry++;
+	if (maxretry && (cmdiocb->retry >= maxretry)) {
 		phba->fc_stat.elsRetryExceeded++;
 		retry = 0;
 	}
@@ -4124,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vpo
 	spin_lock_irq(shost->host_lock);
 	if (vport->fc_rscn_flush) {
 		/* Another thread is walking fc_rscn_id_list on this vport */
-		spin_unlock_irq(shost->host_lock);
 		vport->fc_flag |= FC_RSCN_DISCOVERY;
+		spin_unlock_irq(shost->host_lock);
 		/* Send back ACC */
 		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
 		return 0;
@@ -4133,7 +4151,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vpo
 	/* Indicate we are walking fc_rscn_id_list on this vport */
 	vport->fc_rscn_flush = 1;
 	spin_unlock_irq(shost->host_lock);
-	/* Get the array count after sucessfully have the token */
+	/* Get the array count after successfully have the token */
 	rscn_cnt = vport->fc_rscn_id_cnt;
 	/* If we are already processing an RSCN, save the received
 	 * RSCN payload buffer, cmdiocb->context2 to process later.
@@ -4503,6 +4521,29 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vpo
 }
 
 /**
+ * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
+ * received as an ELS unsolicited event. A request to RRQ shall only
+ * be accepted if the Originator Nx_Port N_Port_ID or the Responder
+ * Nx_Port N_Port_ID of the target Exchange is the same as the
+ * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
+ * not accepted, an LS_RJT with reason code "Unable to perform
+ * command request" and reason code explanation "Invalid Originator
+ * S_ID" shall be returned. For now, we just unconditionally accept
+ * RRQ from the target.
+ **/
+static void
+lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+		 struct lpfc_nodelist *ndlp)
+{
+	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+}
+
+/**
  * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
  * @phba: pointer to lpfc hba data structure.
  * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5396,7 +5437,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
 	if (lpfc_els_chk_latt(vport))
 		goto dropit;
 
-	/* Ignore traffic recevied during vport shutdown. */
+	/* Ignore traffic received during vport shutdown. */
 	if (vport->load_flag & FC_UNLOADING)
 		goto dropit;
 
@@ -5618,6 +5659,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *p
 		if (newnode)
 			lpfc_nlp_put(ndlp);
 		break;
+	case ELS_CMD_RRQ:
+		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
+			"RCV RRQ:         did:x%x/ste:x%x flg:x%x",
+			did, vport->port_state, ndlp->nlp_flag);
+
+		phba->fc_stat.elsRcvRRQ++;
+		lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
+		if (newnode)
+			lpfc_nlp_put(ndlp);
+		break;
 	default:
 		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
 			"RCV ELS cmd:     cmd:x%x did:x%x/ste:x%x",
@@ -5670,7 +5721,7 @@ dropit:
  *    NULL - No vport with the matching @vpi found
  *    Otherwise - Address to the vport with the matching @vpi.
  **/
-static struct lpfc_vport *
+struct lpfc_vport *
 lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
 {
 	struct lpfc_vport *vport;
@@ -5897,8 +5948,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
 				lpfc_initial_fdisc(vport);
 			break;
 		}
-
 	} else {
+		vport->vpi_state |= LPFC_VPI_REGISTERED;
 		if (vport == phba->pport)
 			if (phba->sli_rev < LPFC_SLI_REV4)
 				lpfc_issue_fabric_reglogin(vport);
@@ -6024,11 +6075,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phb
 				 irsp->ulpStatus, irsp->un.ulpWord[4]);
 		goto fdisc_failed;
 	}
-		if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
-			lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-		lpfc_nlp_put(ndlp);
-		/* giving up on FDISC. Cancel discovery timer */
-		lpfc_can_disctmo(vport);
 	spin_lock_irq(shost->host_lock);
 	vport->fc_flag |= FC_FABRIC;
 	if (vport->phba->fc_topology == TOPOLOGY_LOOP)
@@ -6107,6 +6153,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *
 	int did = ndlp->nlp_DID;
 	int rc;
 
+	vport->port_state = LPFC_FDISC;
 	cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
 	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
 				     ELS_CMD_FDISC);
@@ -6172,7 +6219,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *
 		return 1;
 	}
 	lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
-	vport->port_state = LPFC_FDISC;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc.h	2010-02-24 13:52:17.000000000 -0500
@@ -109,7 +109,8 @@ struct hbq_dmabuf {
 	struct lpfc_dmabuf dbuf;
 	uint32_t size;
 	uint32_t tag;
-	struct lpfc_rcqe rcqe;
+	struct lpfc_cq_event cq_event;
+	unsigned long time_stamp;
 };
 
 /* Priority bit.  Set value to exceed low water mark in lpfc_mem. */
@@ -201,6 +202,7 @@ struct lpfc_stats {
 	uint32_t elsRcvLIRR;
 	uint32_t elsRcvRPS;
 	uint32_t elsRcvRPL;
+	uint32_t elsRcvRRQ;
 	uint32_t elsXmitFLOGI;
 	uint32_t elsXmitFDISC;
 	uint32_t elsXmitPLOGI;
@@ -289,8 +291,8 @@ struct lpfc_vport {
 
 	uint16_t vpi;
 	uint16_t vfi;
-	uint8_t vfi_state;
-#define LPFC_VFI_REGISTERED	0x1
+	uint8_t vpi_state;
+#define LPFC_VPI_REGISTERED	0x1
 
 	uint32_t fc_flag;	/* FC flags */
 /* Several of these flags are HBA centric and should be moved to
@@ -405,6 +407,7 @@ struct lpfc_vport {
 	uint8_t stat_data_enabled;
 	uint8_t stat_data_blocked;
 	struct list_head rcv_buffer_list;
+	unsigned long rcv_buffer_time_stamp;
 	uint32_t vport_flag;
 #define STATIC_VPORT	1
 };
@@ -527,13 +530,16 @@ struct lpfc_hba {
 #define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */
 #define DEFER_ERATT		0x2 /* Deferred error attention in progress */
 #define HBA_FCOE_SUPPORT	0x4 /* HBA function supports FCOE */
-#define HBA_RECEIVE_BUFFER	0x8 /* Rcv buffer posted to worker thread */
+#define HBA_SP_QUEUE_EVT	0x8 /* Slow-path qevt posted to worker thread*/
 #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
 #define FCP_XRI_ABORT_EVENT	0x20
 #define ELS_XRI_ABORT_EVENT	0x40
 #define ASYNC_EVENT		0x80
 #define LINK_DISABLED		0x100 /* Link disabled by user */
 #define FCF_DISC_INPROGRESS	0x200 /* FCF discovery in progress */
+#define HBA_FIP_SUPPORT		0x400 /* FIP support in HBA */
+#define HBA_AER_ENABLED		0x800 /* AER enabled with HBA */
+	uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
 	struct lpfc_dmabuf slim2p;
 
 	MAILBOX_t *mbox;
@@ -551,6 +557,7 @@ struct lpfc_hba {
 	uint8_t fc_linkspeed;	/* Link speed after last READ_LA */
 
 	uint32_t fc_eventTag;	/* event tag for link attention */
+	uint32_t link_events;
 
 	/* These fields used to be binfo */
 	uint32_t fc_pref_DID;	/* preferred D_ID */
@@ -604,8 +611,8 @@ struct lpfc_hba {
 	uint32_t cfg_enable_hba_reset;
 	uint32_t cfg_enable_hba_heartbeat;
 	uint32_t cfg_enable_bg;
-	uint32_t cfg_enable_fip;
 	uint32_t cfg_log_verbose;
+	uint32_t cfg_aer_support;
 
 	lpfc_vpd_t vpd;		/* vital product data */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hbadisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -525,8 +525,6 @@ lpfc_work_done(struct lpfc_hba *phba)
 			spin_unlock_irq(&phba->hbalock);
 			lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
 		}
-		if (phba->hba_flag & HBA_RECEIVE_BUFFER)
-			lpfc_sli4_handle_received_buffer(phba);
 	}
 
 	vports = lpfc_create_vport_work_array(phba);
@@ -568,8 +566,9 @@ lpfc_work_done(struct lpfc_hba *phba)
 	pring = &phba->sli.ring[LPFC_ELS_RING];
 	status = (ha_copy & (HA_RXMASK  << (4*LPFC_ELS_RING)));
 	status >>= (4*LPFC_ELS_RING);
-	if ((status & HA_RXMASK)
-		|| (pring->flag & LPFC_DEFERRED_RING_EVENT)) {
+	if ((status & HA_RXMASK) ||
+	    (pring->flag & LPFC_DEFERRED_RING_EVENT) ||
+	    (phba->hba_flag & HBA_SP_QUEUE_EVT)) {
 		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
 			pring->flag |= LPFC_DEFERRED_RING_EVENT;
 			/* Set the lpfc data pending flag */
@@ -688,7 +687,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vpo
 			lpfc_unreg_rpi(vport, ndlp);
 
 		/* Leave Fabric nodes alone on link down */
-		if (!remove && ndlp->nlp_type & NLP_FABRIC)
+		if ((phba->sli_rev < LPFC_SLI_REV4) &&
+		    (!remove && ndlp->nlp_type & NLP_FABRIC))
 			continue;
 		rc = lpfc_disc_state_machine(vport, ndlp, NULL,
 					     remove
@@ -706,6 +706,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vpo
 void
 lpfc_port_link_failure(struct lpfc_vport *vport)
 {
+	/* Cleanup any outstanding received buffers */
+	lpfc_cleanup_rcv_buffers(vport);
+
 	/* Cleanup any outstanding RSCN activity */
 	lpfc_els_flush_rscn(vport);
 
@@ -744,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba)
 
 	if (phba->link_state == LPFC_LINK_DOWN)
 		return 0;
+
+	/* Block all SCSI stack I/Os */
+	lpfc_scsi_dev_block(phba);
+
 	spin_lock_irq(&phba->hbalock);
 	phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED);
 	if (phba->link_state > LPFC_LINK_DOWN) {
@@ -1015,13 +1022,12 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *
 		mempool_free(mboxq, phba->mbox_mem_pool);
 		return;
 	}
-	if (vport->port_state != LPFC_FLOGI) {
-		spin_lock_irqsave(&phba->hbalock, flags);
-		phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
-		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-		spin_unlock_irqrestore(&phba->hbalock, flags);
+	spin_lock_irqsave(&phba->hbalock, flags);
+	phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+	phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+	spin_unlock_irqrestore(&phba->hbalock, flags);
+	if (vport->port_state != LPFC_FLOGI)
 		lpfc_initial_flogi(vport);
-	}
 
 	mempool_free(mboxq, phba->mbox_mem_pool);
 	return;
@@ -1199,6 +1205,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
 
 	/* If the FCF is not availabe do nothing. */
 	if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) {
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
 	}
@@ -1216,15 +1223,23 @@ lpfc_register_fcf(struct lpfc_hba *phba)
 
 	fcf_mbxq = mempool_alloc(phba->mbox_mem_pool,
 		GFP_KERNEL);
-	if (!fcf_mbxq)
+	if (!fcf_mbxq) {
+		spin_lock_irqsave(&phba->hbalock, flags);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
+	}
 
 	lpfc_reg_fcfi(phba, fcf_mbxq);
 	fcf_mbxq->vport = phba->pport;
 	fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi;
 	rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT);
-	if (rc == MBX_NOT_FINISHED)
+	if (rc == MBX_NOT_FINISHED) {
+		spin_lock_irqsave(&phba->hbalock, flags);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irqrestore(&phba->hbalock, flags);
 		mempool_free(fcf_mbxq, phba->mbox_mem_pool);
+	}
 
 	return;
 }
@@ -1253,13 +1268,27 @@ lpfc_match_fcf_conn_list(struct lpfc_hba
 			uint16_t *vlan_id)
 {
 	struct lpfc_fcf_conn_entry *conn_entry;
+	int i, j, fcf_vlan_id = 0;
+
+	/* Find the lowest VLAN id in the FCF record */
+	for (i = 0; i < 512; i++) {
+		if (new_fcf_record->vlan_bitmap[i]) {
+			fcf_vlan_id = i * 8;
+			j = 0;
+			while (!((new_fcf_record->vlan_bitmap[i] >> j) & 1)) {
+				j++;
+				fcf_vlan_id++;
+			}
+			break;
+		}
+	}
 
 	/* If FCF not available return 0 */
 	if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) ||
 		!bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record))
 		return 0;
 
-	if (!phba->cfg_enable_fip) {
+	if (!(phba->hba_flag & HBA_FIP_SUPPORT)) {
 		*boot_flag = 0;
 		*addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov,
 				new_fcf_record);
@@ -1286,7 +1315,11 @@ lpfc_match_fcf_conn_list(struct lpfc_hba
 		if (*addr_mode & LPFC_FCF_FPMA)
 			*addr_mode = LPFC_FCF_FPMA;
 
-		*vlan_id = 0xFFFF;
+		/* If FCF record report a vlan id use that vlan id */
+		if (fcf_vlan_id)
+			*vlan_id = fcf_vlan_id;
+		else
+			*vlan_id = 0xFFFF;
 		return 1;
 	}
 
@@ -1384,8 +1417,15 @@ lpfc_match_fcf_conn_list(struct lpfc_hba
 			(*addr_mode & LPFC_FCF_FPMA))
 				*addr_mode = LPFC_FCF_FPMA;
 
+		/* If matching connect list has a vlan id, use it */
 		if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID)
 			*vlan_id = conn_entry->conn_rec.vlan_tag;
+		/*
+		 * If no vlan id is specified in connect list, use the vlan id
+		 * in the FCF record
+		 */
+		else if (fcf_vlan_id)
+			*vlan_id = fcf_vlan_id;
 		else
 			*vlan_id = 0xFFFF;
 
@@ -1423,6 +1463,15 @@ lpfc_check_pending_fcoe_event(struct lpf
 
 	if (phba->link_state >= LPFC_LINK_UP)
 		lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+	else {
+		/*
+		 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
+		 * flag
+		 */
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
+	}
 
 	if (unreg_fcf) {
 		spin_lock_irq(&phba->hbalock);
@@ -1510,10 +1559,16 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpf
 	 * to book keeping the FCFIs can be used.
 	 */
 	if (shdr_status || shdr_add_status) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"2521 READ_FCF_RECORD mailbox failed "
-				"with status x%x add_status x%x, mbx\n",
-				shdr_status, shdr_add_status);
+		if (shdr_status == STATUS_FCF_TABLE_EMPTY) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"2726 READ_FCF_RECORD Indicates empty "
+					"FCF table.\n");
+		} else {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"2521 READ_FCF_RECORD mailbox failed "
+					"with status x%x add_status x%x, mbx\n",
+					shdr_status, shdr_add_status);
+		}
 		goto out;
 	}
 	/* Interpreting the returned information of FCF records */
@@ -1653,15 +1708,16 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		return;
 	}
+	spin_lock_irq(&phba->hbalock);
 	vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
+	spin_unlock_irq(&phba->hbalock);
 
 	if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
 		lpfc_initial_fdisc(vport);
 	else {
 		lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
-		lpfc_printf_vlog(vport, KERN_ERR,
-			LOG_ELS,
-			"2606 No NPIV Fabric support\n");
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+				 "2606 No NPIV Fabric support\n");
 	}
 	return;
 }
@@ -1756,8 +1812,8 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		goto fail_free_mem;
 	}
-	/* Mark the vport has registered with its VFI */
-	vport->vfi_state |= LPFC_VFI_REGISTERED;
+	/* The VPI is implicitly registered when the VFI is registered */
+	vport->vpi_state |= LPFC_VPI_REGISTERED;
 
 	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
 		lpfc_start_fdiscs(phba);
@@ -1861,7 +1917,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 	if (phba->fc_topology == TOPOLOGY_LOOP) {
 		phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
 
-		if (phba->cfg_enable_npiv)
+		/* if npiv is enabled and this adapter supports npiv log
+		 * a message that npiv is not supported in this topology
+		 */
+		if (phba->cfg_enable_npiv && phba->max_vpi)
 			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
 				"1309 Link Up Event npiv not supported in loop "
 				"topology\n");
@@ -1955,7 +2014,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba
 		 * is phase 1 implementation that support FCF index 0 and driver
 		 * defaults.
 		 */
-		if (phba->cfg_enable_fip == 0) {
+		if (!(phba->hba_flag & HBA_FIP_SUPPORT)) {
 			fcf_record = kzalloc(sizeof(struct fcf_record),
 					GFP_KERNEL);
 			if (unlikely(!fcf_record)) {
@@ -2085,6 +2144,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *p
 	else
 		phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
 
+	phba->link_events++;
 	if (la->attType == AT_LINK_UP && (!la->mm)) {
 		phba->fc_stat.LinkUp++;
 		if (phba->link_flag & LS_LOOPBACK_MODE) {
@@ -2211,13 +2271,17 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba
 				 mb->mbxStatus);
 		break;
 	}
+	spin_lock_irq(&phba->hbalock);
+	vport->vpi_state &= ~LPFC_VPI_REGISTERED;
+	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+	spin_unlock_irq(&phba->hbalock);
 	vport->unreg_vpi_cmpl = VPORT_OK;
 	mempool_free(pmb, phba->mbox_mem_pool);
 	/*
 	 * This shost reference might have been taken at the beginning of
 	 * lpfc_vport_delete()
 	 */
-	if (vport->load_flag & FC_UNLOADING)
+	if ((vport->load_flag & FC_UNLOADING) && (vport != phba->pport))
 		scsi_host_put(shost);
 }
 
@@ -2268,6 +2332,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *p
 		goto out;
 	}
 
+	vport->vpi_state |= LPFC_VPI_REGISTERED;
 	vport->num_disc_nodes = 0;
 	/* go thru NPR list and issue ELS PLOGIs */
 	if (vport->fc_npr_cnt)
@@ -3077,7 +3142,7 @@ lpfc_no_rpi(struct lpfc_hba *phba, struc
 	struct lpfc_sli *psli;
 	struct lpfc_sli_ring *pring;
 	struct lpfc_iocbq *iocb, *next_iocb;
-	uint32_t rpi, i;
+	uint32_t i;
 
 	lpfc_fabric_abort_nport(ndlp);
 
@@ -3086,7 +3151,6 @@ lpfc_no_rpi(struct lpfc_hba *phba, struc
 	 * by firmware with a no rpi error.
 	 */
 	psli = &phba->sli;
-	rpi = ndlp->nlp_rpi;
 	if (ndlp->nlp_flag & NLP_RPI_VALID) {
 		/* Now process each ring */
 		for (i = 0; i < psli->num_rings; i++) {
@@ -4322,6 +4386,14 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
 				ret = 1;
 				spin_unlock_irq(shost->host_lock);
 				goto out;
+			} else {
+				lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+					"2624 RPI %x DID %x flg %x still "
+					"logged in\n",
+					ndlp->nlp_rpi, ndlp->nlp_DID,
+					ndlp->nlp_flag);
+				if (ndlp->nlp_flag & NLP_RPI_VALID)
+					ret = 1;
 			}
 		}
 		spin_unlock_irq(shost->host_lock);
@@ -4400,7 +4472,7 @@ lpfc_unregister_unused_fcf(struct lpfc_h
 	 */
 	if (!(phba->hba_flag & HBA_FCOE_SUPPORT) ||
 		!(phba->fcf.fcf_flag & FCF_REGISTERED) ||
-		(phba->cfg_enable_fip == 0)) {
+		(!(phba->hba_flag & HBA_FIP_SUPPORT))) {
 		spin_unlock_irq(&phba->hbalock);
 		return;
 	}
@@ -4409,6 +4481,8 @@ lpfc_unregister_unused_fcf(struct lpfc_h
 	if (lpfc_fcf_inuse(phba))
 		return;
 
+	/* At this point, all discovery is aborted */
+	phba->pport->port_state = LPFC_VPORT_UNKNOWN;
 
 	/* Unregister VPIs */
 	vports = lpfc_create_vport_work_array(phba);
@@ -4416,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_h
 		(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
 		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
 			lpfc_mbx_unreg_vpi(vports[i]);
-			vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-			vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED;
+			spin_lock_irq(&phba->hbalock);
+			vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
+			spin_unlock_irq(&phba->hbalock);
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
 
@@ -4431,7 +4507,7 @@ lpfc_unregister_unused_fcf(struct lpfc_h
 		return;
 	}
 
-	lpfc_unreg_vfi(mbox, phba->pport->vfi);
+	lpfc_unreg_vfi(mbox, phba->pport);
 	mbox->vport = phba->pport;
 	mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl;
 
@@ -4512,8 +4588,10 @@ lpfc_read_fcf_conn_tbl(struct lpfc_hba *
 
 	/* Free the current connect table */
 	list_for_each_entry_safe(conn_entry, next_conn_entry,
-		&phba->fcf_conn_rec_list, list)
+		&phba->fcf_conn_rec_list, list) {
+		list_del_init(&conn_entry->list);
 		kfree(conn_entry);
+	}
 
 	conn_hdr = (struct lpfc_fcf_conn_hdr *) buff;
 	record_count = conn_hdr->length * sizeof(uint32_t)/
@@ -4569,14 +4647,6 @@ lpfc_read_fcoe_param(struct lpfc_hba *ph
 		(fcoe_param_hdr->length != FCOE_PARAM_LENGTH))
 		return;
 
-	if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) ==
-			FIPP_MODE_ON)
-		phba->cfg_enable_fip = 1;
-
-	if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) ==
-		FIPP_MODE_OFF)
-		phba->cfg_enable_fip = 0;
-
 	if (fcoe_param_hdr->parm_flags & FIPP_VLAN_VALID) {
 		phba->valid_vlan = 1;
 		phba->vlan_id = le16_to_cpu(fcoe_param->vlan_tag) &
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hw4.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw4.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hw4.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw4.h	2010-02-24 13:52:17.000000000 -0500
@@ -194,6 +194,26 @@ struct lpfc_sli4_flags {
 #define lpfc_fip_flag_WORD word0
 };
 
+struct sli4_bls_acc {
+	uint32_t word0_rsvd;      /* Word0 must be reserved */
+	uint32_t word1;
+#define lpfc_abts_orig_SHIFT      0
+#define lpfc_abts_orig_MASK       0x00000001
+#define lpfc_abts_orig_WORD       word1
+#define LPFC_ABTS_UNSOL_RSP       1
+#define LPFC_ABTS_UNSOL_INT       0
+	uint32_t word2;
+#define lpfc_abts_rxid_SHIFT      0
+#define lpfc_abts_rxid_MASK       0x0000FFFF
+#define lpfc_abts_rxid_WORD       word2
+#define lpfc_abts_oxid_SHIFT      16
+#define lpfc_abts_oxid_MASK       0x0000FFFF
+#define lpfc_abts_oxid_WORD       word2
+	uint32_t word3;
+	uint32_t word4;
+	uint32_t word5_rsvd;	/* Word5 must be reserved */
+};
+
 /* event queue entry structure */
 struct lpfc_eqe {
 	uint32_t word0;
@@ -425,7 +445,7 @@ struct lpfc_wqe_generic{
 #define lpfc_wqe_gen_status_MASK	0x0000000F
 #define lpfc_wqe_gen_status_WORD	word7
 #define lpfc_wqe_gen_ct_SHIFT		2
-#define lpfc_wqe_gen_ct_MASK		0x00000007
+#define lpfc_wqe_gen_ct_MASK		0x00000003
 #define lpfc_wqe_gen_ct_WORD		word7
 	uint32_t abort_tag;
 	uint32_t word9;
@@ -453,6 +473,13 @@ struct lpfc_wqe_generic{
 #define lpfc_wqe_gen_wqec_SHIFT		7
 #define lpfc_wqe_gen_wqec_MASK		0x00000001
 #define lpfc_wqe_gen_wqec_WORD		word11
+#define ELS_ID_FLOGI 3
+#define ELS_ID_FDISC 2
+#define ELS_ID_LOGO  1
+#define ELS_ID_DEFAULT 0
+#define lpfc_wqe_gen_els_id_SHIFT	4
+#define lpfc_wqe_gen_els_id_MASK	0x00000003
+#define lpfc_wqe_gen_els_id_WORD	word11
 #define lpfc_wqe_gen_cmd_type_SHIFT	0
 #define lpfc_wqe_gen_cmd_type_MASK	0x0000000F
 #define lpfc_wqe_gen_cmd_type_WORD	word11
@@ -487,8 +514,8 @@ struct lpfc_register {
 
 #define LPFC_UERR_STATUS_HI		0x00A4
 #define LPFC_UERR_STATUS_LO		0x00A0
-#define LPFC_ONLINE0			0x00B0
-#define LPFC_ONLINE1			0x00B4
+#define LPFC_UE_MASK_HI			0x00AC
+#define LPFC_UE_MASK_LO			0x00A8
 #define LPFC_SCRATCHPAD			0x0058
 
 /* BAR0 Registers */
@@ -760,6 +787,7 @@ struct mbox_header {
 #define LPFC_MBOX_OPCODE_MQ_DESTROY		0x35
 #define LPFC_MBOX_OPCODE_CQ_DESTROY		0x36
 #define LPFC_MBOX_OPCODE_EQ_DESTROY		0x37
+#define LPFC_MBOX_OPCODE_QUERY_FW_CFG		0x3A
 #define LPFC_MBOX_OPCODE_FUNCTION_RESET		0x3D
 
 /* FCoE Opcodes */
@@ -985,7 +1013,7 @@ struct lpfc_mbx_wq_destroy {
 };
 
 #define LPFC_HDR_BUF_SIZE 128
-#define LPFC_DATA_BUF_SIZE 4096
+#define LPFC_DATA_BUF_SIZE 2048
 struct rq_context {
 	uint32_t word0;
 #define lpfc_rq_context_rq_size_SHIFT	16
@@ -1273,6 +1301,51 @@ struct lpfc_mbx_del_fcf_tbl_entry {
 #define lpfc_mbx_del_fcf_tbl_index_WORD		word10
 };
 
+struct lpfc_mbx_query_fw_cfg {
+	struct mbox_header header;
+	uint32_t config_number;
+	uint32_t asic_rev;
+	uint32_t phys_port;
+	uint32_t function_mode;
+/* firmware Function Mode */
+#define lpfc_function_mode_toe_SHIFT		0
+#define lpfc_function_mode_toe_MASK		0x00000001
+#define lpfc_function_mode_toe_WORD		function_mode
+#define lpfc_function_mode_nic_SHIFT		1
+#define lpfc_function_mode_nic_MASK		0x00000001
+#define lpfc_function_mode_nic_WORD		function_mode
+#define lpfc_function_mode_rdma_SHIFT		2
+#define lpfc_function_mode_rdma_MASK		0x00000001
+#define lpfc_function_mode_rdma_WORD		function_mode
+#define lpfc_function_mode_vm_SHIFT		3
+#define lpfc_function_mode_vm_MASK		0x00000001
+#define lpfc_function_mode_vm_WORD		function_mode
+#define lpfc_function_mode_iscsi_i_SHIFT	4
+#define lpfc_function_mode_iscsi_i_MASK		0x00000001
+#define lpfc_function_mode_iscsi_i_WORD		function_mode
+#define lpfc_function_mode_iscsi_t_SHIFT	5
+#define lpfc_function_mode_iscsi_t_MASK		0x00000001
+#define lpfc_function_mode_iscsi_t_WORD		function_mode
+#define lpfc_function_mode_fcoe_i_SHIFT		6
+#define lpfc_function_mode_fcoe_i_MASK		0x00000001
+#define lpfc_function_mode_fcoe_i_WORD		function_mode
+#define lpfc_function_mode_fcoe_t_SHIFT		7
+#define lpfc_function_mode_fcoe_t_MASK		0x00000001
+#define lpfc_function_mode_fcoe_t_WORD		function_mode
+#define lpfc_function_mode_dal_SHIFT		8
+#define lpfc_function_mode_dal_MASK		0x00000001
+#define lpfc_function_mode_dal_WORD		function_mode
+#define lpfc_function_mode_lro_SHIFT		9
+#define lpfc_function_mode_lro_MASK		0x00000001
+#define lpfc_function_mode_lro_WORD		function_mode9
+#define lpfc_function_mode_flex10_SHIFT		10
+#define lpfc_function_mode_flex10_MASK		0x00000001
+#define lpfc_function_mode_flex10_WORD		function_mode
+#define lpfc_function_mode_ncsi_SHIFT		11
+#define lpfc_function_mode_ncsi_MASK		0x00000001
+#define lpfc_function_mode_ncsi_WORD		function_mode
+};
+
 /* Status field for embedded SLI_CONFIG mailbox command */
 #define STATUS_SUCCESS					0x0
 #define STATUS_FAILED 					0x1
@@ -1298,6 +1371,7 @@ struct lpfc_mbx_del_fcf_tbl_entry {
 #define STATUS_ERROR_ACITMAIN				0x2a
 #define STATUS_REBOOT_REQUIRED				0x2c
 #define STATUS_FCF_IN_USE				0x3a
+#define STATUS_FCF_TABLE_EMPTY				0x43
 
 struct lpfc_mbx_sli4_config {
 	struct mbox_header header;
@@ -1349,8 +1423,7 @@ struct lpfc_mbx_reg_vfi {
 #define lpfc_reg_vfi_fcfi_SHIFT		0
 #define lpfc_reg_vfi_fcfi_MASK		0x0000FFFF
 #define lpfc_reg_vfi_fcfi_WORD		word2
-	uint32_t word3_rsvd;
-	uint32_t word4_rsvd;
+	uint32_t wwn[2];
 	struct ulp_bde64 bde;
 	uint32_t word8_rsvd;
 	uint32_t word9_rsvd;
@@ -1555,6 +1628,11 @@ struct lpfc_mbx_read_rev {
 #define lpfc_mbx_rd_rev_fcoe_SHIFT		20
 #define lpfc_mbx_rd_rev_fcoe_MASK		0x00000001
 #define lpfc_mbx_rd_rev_fcoe_WORD		word1
+#define lpfc_mbx_rd_rev_cee_ver_SHIFT		21
+#define lpfc_mbx_rd_rev_cee_ver_MASK		0x00000003
+#define lpfc_mbx_rd_rev_cee_ver_WORD		word1
+#define LPFC_PREDCBX_CEE_MODE	0
+#define LPFC_DCBX_CEE_MODE	1
 #define lpfc_mbx_rd_rev_vpd_SHIFT		29
 #define lpfc_mbx_rd_rev_vpd_MASK		0x00000001
 #define lpfc_mbx_rd_rev_vpd_WORD		word1
@@ -1804,6 +1882,7 @@ struct lpfc_mqe {
 		struct lpfc_mbx_read_config rd_config;
 		struct lpfc_mbx_request_features req_ftrs;
 		struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
+		struct lpfc_mbx_query_fw_cfg query_fw_cfg;
 		struct lpfc_mbx_nop nop;
 	} un;
 };
@@ -1885,7 +1964,7 @@ struct lpfc_acqe_link {
 };
 
 struct lpfc_acqe_fcoe {
-	uint32_t fcf_index;
+	uint32_t index;
 	uint32_t word1;
 #define lpfc_acqe_fcoe_fcf_count_SHIFT		0
 #define lpfc_acqe_fcoe_fcf_count_MASK		0x0000FFFF
@@ -1896,6 +1975,7 @@ struct lpfc_acqe_fcoe {
 #define LPFC_FCOE_EVENT_TYPE_NEW_FCF		0x1
 #define LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL	0x2
 #define LPFC_FCOE_EVENT_TYPE_FCF_DEAD		0x3
+#define LPFC_FCOE_EVENT_TYPE_CVL		0x4
 	uint32_t event_tag;
 	uint32_t trailer;
 };
@@ -1921,12 +2001,13 @@ struct lpfc_bmbx_create {
 #define SGL_ALIGN_SZ 64
 #define SGL_PAGE_SIZE 4096
 /* align SGL addr on a size boundary - adjust address up */
-#define NO_XRI ((uint16_t)-1)
+#define NO_XRI  ((uint16_t)-1)
+
 struct wqe_common {
 	uint32_t word6;
-#define wqe_xri_SHIFT         0
-#define wqe_xri_MASK          0x0000FFFF
-#define wqe_xri_WORD          word6
+#define wqe_xri_tag_SHIFT     0
+#define wqe_xri_tag_MASK      0x0000FFFF
+#define wqe_xri_tag_WORD      word6
 #define wqe_ctxt_tag_SHIFT    16
 #define wqe_ctxt_tag_MASK     0x0000FFFF
 #define wqe_ctxt_tag_WORD     word6
@@ -1987,7 +2068,7 @@ struct wqe_common {
 #define wqe_wqec_MASK       0x00000001
 #define wqe_wqec_WORD       word11
 #define wqe_cqid_SHIFT      16
-#define wqe_cqid_MASK       0x000003ff
+#define wqe_cqid_MASK       0x0000ffff
 #define wqe_cqid_WORD       word11
 };
 
@@ -1996,6 +2077,9 @@ struct wqe_did {
 #define wqe_els_did_SHIFT         0
 #define wqe_els_did_MASK          0x00FFFFFF
 #define wqe_els_did_WORD          word5
+#define wqe_xmit_bls_pt_SHIFT         28
+#define wqe_xmit_bls_pt_MASK          0x00000003
+#define wqe_xmit_bls_pt_WORD          word5
 #define wqe_xmit_bls_ar_SHIFT         30
 #define wqe_xmit_bls_ar_MASK          0x00000001
 #define wqe_xmit_bls_ar_WORD          word5
@@ -2044,6 +2128,23 @@ struct xmit_els_rsp64_wqe {
 
 struct xmit_bls_rsp64_wqe {
 	uint32_t payload0;
+/* Payload0 for BA_ACC */
+#define xmit_bls_rsp64_acc_seq_id_SHIFT        16
+#define xmit_bls_rsp64_acc_seq_id_MASK         0x000000ff
+#define xmit_bls_rsp64_acc_seq_id_WORD         payload0
+#define xmit_bls_rsp64_acc_seq_id_vald_SHIFT   24
+#define xmit_bls_rsp64_acc_seq_id_vald_MASK    0x000000ff
+#define xmit_bls_rsp64_acc_seq_id_vald_WORD    payload0
+/* Payload0 for BA_RJT */
+#define xmit_bls_rsp64_rjt_vspec_SHIFT   0
+#define xmit_bls_rsp64_rjt_vspec_MASK    0x000000ff
+#define xmit_bls_rsp64_rjt_vspec_WORD    payload0
+#define xmit_bls_rsp64_rjt_expc_SHIFT    8
+#define xmit_bls_rsp64_rjt_expc_MASK     0x000000ff
+#define xmit_bls_rsp64_rjt_expc_WORD     payload0
+#define xmit_bls_rsp64_rjt_rsnc_SHIFT    16
+#define xmit_bls_rsp64_rjt_rsnc_MASK     0x000000ff
+#define xmit_bls_rsp64_rjt_rsnc_WORD     payload0
 	uint32_t word1;
 #define xmit_bls_rsp64_rxid_SHIFT  0
 #define xmit_bls_rsp64_rxid_MASK   0x0000ffff
@@ -2052,18 +2153,19 @@ struct xmit_bls_rsp64_wqe {
 #define xmit_bls_rsp64_oxid_MASK   0x0000ffff
 #define xmit_bls_rsp64_oxid_WORD   word1
 	uint32_t word2;
-#define xmit_bls_rsp64_seqcntlo_SHIFT  0
-#define xmit_bls_rsp64_seqcntlo_MASK   0x0000ffff
-#define xmit_bls_rsp64_seqcntlo_WORD   word2
-#define xmit_bls_rsp64_seqcnthi_SHIFT  16
+#define xmit_bls_rsp64_seqcnthi_SHIFT  0
 #define xmit_bls_rsp64_seqcnthi_MASK   0x0000ffff
 #define xmit_bls_rsp64_seqcnthi_WORD   word2
+#define xmit_bls_rsp64_seqcntlo_SHIFT  16
+#define xmit_bls_rsp64_seqcntlo_MASK   0x0000ffff
+#define xmit_bls_rsp64_seqcntlo_WORD   word2
 	uint32_t rsrvd3;
 	uint32_t rsrvd4;
 	struct wqe_did	wqe_dest;
 	struct wqe_common wqe_com; /* words 6-11 */
 	uint32_t rsvd_12_15[4];
 };
+
 struct wqe_rctl_dfctl {
 	uint32_t word5;
 #define wqe_si_SHIFT 2
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hw.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_hw.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_hw.h	2010-02-24 13:52:17.000000000 -0500
@@ -1124,21 +1124,6 @@ typedef struct {
 /* Number of 4-byte words in an IOCB. */
 #define IOCB_WORD_SZ    8
 
-/* defines for type field in fc header */
-#define FC_ELS_DATA     0x1
-#define FC_LLC_SNAP     0x5
-#define FC_FCP_DATA     0x8
-#define FC_COMMON_TRANSPORT_ULP 0x20
-
-/* defines for rctl field in fc header */
-#define FC_DEV_DATA     0x0
-#define FC_UNSOL_CTL    0x2
-#define FC_SOL_CTL      0x3
-#define FC_UNSOL_DATA   0x4
-#define FC_FCP_CMND     0x6
-#define FC_ELS_REQ      0x22
-#define FC_ELS_RSP      0x23
-
 /* network headers for Dfctl field */
 #define FC_NET_HDR      0x20
 
@@ -1183,6 +1168,8 @@ typedef struct {
 #define PCI_DEVICE_ID_ZEPHYR_DCSP   0xfe12
 #define PCI_VENDOR_ID_SERVERENGINE  0x19a2
 #define PCI_DEVICE_ID_TIGERSHARK    0x0704
+#define PCI_DEVICE_ID_TOMCAT        0x0714
+#define PCI_DEVICE_ID_FALCON        0xf180
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
@@ -1444,6 +1431,7 @@ typedef struct {		/* FireFly BIU registe
 #define CMD_ABORT_MXRI64_CN     0x8C
 #define CMD_RCV_ELS_REQ64_CX    0x8D
 #define CMD_XMIT_ELS_RSP64_CX   0x95
+#define CMD_XMIT_BLS_RSP64_CX   0x97
 #define CMD_FCP_IWRITE64_CR     0x98
 #define CMD_FCP_IWRITE64_CX     0x99
 #define CMD_FCP_IREAD64_CR      0x9A
@@ -2306,8 +2294,7 @@ typedef struct {
 	uint32_t rsvd1;
 	uint32_t rsvd2:8;
 	uint32_t sid:24;
-	uint32_t rsvd3;
-	uint32_t rsvd4;
+	uint32_t wwn[2];
 	uint32_t rsvd5;
 	uint16_t vfi;
 	uint16_t vpi;
@@ -2315,8 +2302,7 @@ typedef struct {
 	uint32_t rsvd1;
 	uint32_t sid:24;
 	uint32_t rsvd2:8;
-	uint32_t rsvd3;
-	uint32_t rsvd4;
+	uint32_t wwn[2];
 	uint32_t rsvd5;
 	uint16_t vpi;
 	uint16_t vfi;
@@ -2326,7 +2312,13 @@ typedef struct {
 /* Structure for MB Command UNREG_VPI (0x97) */
 typedef struct {
 	uint32_t rsvd1;
-	uint32_t rsvd2;
+#ifdef __BIG_ENDIAN_BITFIELD
+	uint16_t rsvd2;
+	uint16_t sli4_vpi;
+#else	/*  __LITTLE_ENDIAN */
+	uint16_t sli4_vpi;
+	uint16_t rsvd2;
+#endif
 	uint32_t rsvd3;
 	uint32_t rsvd4;
 	uint32_t rsvd5;
@@ -3547,7 +3539,7 @@ typedef struct _IOCB {	/* IOCB structure
 		ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */
 		QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */
 		struct rcv_seq64 rcvseq64;	/* RCV_SEQ64 and RCV_CONT64 */
-
+		struct sli4_bls_acc bls_acc; /* UNSOL ABTS BLS_ACC params */
 		uint32_t ulpWord[IOCB_WORD_SZ - 2];	/* generic 6 'words' */
 	} un;
 	union {
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_init.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
+#include <linux/aer.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -645,7 +646,7 @@ lpfc_hba_down_prep(struct lpfc_hba *phba
  * down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 static int
@@ -700,7 +701,7 @@ lpfc_hba_down_post_s3(struct lpfc_hba *p
  * down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 static int
@@ -755,7 +756,7 @@ lpfc_hba_down_post_s4(struct lpfc_hba *p
  * uninitialization after the HBA is reset when bring down the SLI Layer.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 int
@@ -852,12 +853,19 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba
 void
 lpfc_hb_timeout_handler(struct lpfc_hba *phba)
 {
+	struct lpfc_vport **vports;
 	LPFC_MBOXQ_t *pmboxq;
 	struct lpfc_dmabuf *buf_ptr;
-	int retval;
+	int retval, i;
 	struct lpfc_sli *psli = &phba->sli;
 	LIST_HEAD(completions);
 
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports != NULL)
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+			lpfc_rcv_seq_check_edtov(vports[i]);
+	lpfc_destroy_vport_work_array(phba, vports);
+
 	if ((phba->link_state == LPFC_HBA_ERROR) ||
 		(phba->pport->load_flag & FC_UNLOADING) ||
 		(phba->pport->fc_flag & FC_OFFLINE_MODE))
@@ -1254,7 +1262,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *ph
  * routine from the API jump table function pointer from the lpfc_hba struct.
  *
  * Return codes
- *   0 - sucess.
+ *   0 - success.
  *   Any other value - error.
  **/
 void
@@ -1521,10 +1529,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba
 	int GE = 0;
 	int oneConnect = 0; /* default is not a oneConnect */
 	struct {
-		char * name;
-		int    max_speed;
-		char * bus;
-	} m = {"<Unknown>", 0, ""};
+		char *name;
+		char *bus;
+		char *function;
+	} m = {"<Unknown>", "", ""};
 
 	if (mdp && mdp[0] != '\0'
 		&& descp && descp[0] != '\0')
@@ -1545,132 +1553,155 @@ lpfc_get_hba_model_desc(struct lpfc_hba
 
 	switch (dev_id) {
 	case PCI_DEVICE_ID_FIREFLY:
-		m = (typeof(m)){"LP6000", max_speed, "PCI"};
+		m = (typeof(m)){"LP6000", "PCI", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SUPERFLY:
 		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
-			m = (typeof(m)){"LP7000", max_speed,  "PCI"};
+			m = (typeof(m)){"LP7000", "PCI",
+					"Fibre Channel Adapter"};
 		else
-			m = (typeof(m)){"LP7000E", max_speed, "PCI"};
+			m = (typeof(m)){"LP7000E", "PCI",
+					"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_DRAGONFLY:
-		m = (typeof(m)){"LP8000", max_speed, "PCI"};
+		m = (typeof(m)){"LP8000", "PCI",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_CENTAUR:
 		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
-			m = (typeof(m)){"LP9002", max_speed, "PCI"};
+			m = (typeof(m)){"LP9002", "PCI",
+					"Fibre Channel Adapter"};
 		else
-			m = (typeof(m)){"LP9000", max_speed, "PCI"};
+			m = (typeof(m)){"LP9000", "PCI",
+					"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_RFLY:
-		m = (typeof(m)){"LP952", max_speed, "PCI"};
+		m = (typeof(m)){"LP952", "PCI",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PEGASUS:
-		m = (typeof(m)){"LP9802", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP9802", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_THOR:
-		m = (typeof(m)){"LP10000", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP10000", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_VIPER:
-		m = (typeof(m)){"LPX1000", max_speed,  "PCI-X"};
+		m = (typeof(m)){"LPX1000",  "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PFLY:
-		m = (typeof(m)){"LP982", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP982", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_TFLY:
-		m = (typeof(m)){"LP1050", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP1050", "PCI-X",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS:
-		m = (typeof(m)){"LP11000", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11000", "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS_SCSP:
-		m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11000-SP", "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HELIOS_DCSP:
-		m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP11002-SP",  "PCI-X2",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE:
-		m = (typeof(m)){"LPe1000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE_SCSP:
-		m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1000-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_NEPTUNE_DCSP:
-		m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1002-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_BMID:
-		m = (typeof(m)){"LP1150", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP1150", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_BSMB:
-		m = (typeof(m)){"LP111", max_speed, "PCI-X2"};
+		m = (typeof(m)){"LP111", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR:
-		m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR_SCSP:
-		m = (typeof(m)){"LPe11000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZEPHYR_DCSP:
-		m = (typeof(m)){"LP2105", max_speed, "PCIe"};
+		m = (typeof(m)){"LP2105", "PCIe", "FCoE Adapter"};
 		GE = 1;
 		break;
 	case PCI_DEVICE_ID_ZMID:
-		m = (typeof(m)){"LPe1150", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1150", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_ZSMB:
-		m = (typeof(m)){"LPe111", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe111", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP101:
-		m = (typeof(m)){"LP101", max_speed, "PCI-X"};
+		m = (typeof(m)){"LP101", "PCI-X", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP10000S:
-		m = (typeof(m)){"LP10000-S", max_speed, "PCI"};
+		m = (typeof(m)){"LP10000-S", "PCI", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LP11000S:
-		m = (typeof(m)){"LP11000-S", max_speed,
-			"PCI-X2"};
+		m = (typeof(m)){"LP11000-S", "PCI-X2", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LPE11000S:
-		m = (typeof(m)){"LPe11000-S", max_speed,
-			"PCIe"};
+		m = (typeof(m)){"LPe11000-S", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT:
-		m = (typeof(m)){"LPe12000", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_MID:
-		m = (typeof(m)){"LPe1250", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe1250", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_SMB:
-		m = (typeof(m)){"LPe121", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe121", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_DCSP:
-		m = (typeof(m)){"LPe12002-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12002-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_SCSP:
-		m = (typeof(m)){"LPe12000-SP", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000-SP", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_SAT_S:
-		m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"};
+		m = (typeof(m)){"LPe12000-S", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_HORNET:
-		m = (typeof(m)){"LP21000", max_speed, "PCIe"};
+		m = (typeof(m)){"LP21000", "PCIe", "FCoE Adapter"};
 		GE = 1;
 		break;
 	case PCI_DEVICE_ID_PROTEUS_VF:
-		m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPev12000", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PROTEUS_PF:
-		m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPev12000", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_PROTEUS_S:
-		m = (typeof(m)) {"LPemv12002-S", max_speed, "PCIe IOV"};
+		m = (typeof(m)){"LPemv12002-S", "PCIe IOV",
+				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_TIGERSHARK:
 		oneConnect = 1;
-		m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"};
+		m = (typeof(m)){"OCe10100", "PCIe", "FCoE"};
+		break;
+	case PCI_DEVICE_ID_TOMCAT:
+		oneConnect = 1;
+		m = (typeof(m)){"OCe11100", "PCIe", "FCoE"};
+		break;
+	case PCI_DEVICE_ID_FALCON:
+		m = (typeof(m)){"LPSe12002-ML1-E", "PCIe",
+				"EmulexSecure Fibre"};
 		break;
 	default:
-		m = (typeof(m)){ NULL };
+		m = (typeof(m)){"Unknown", "", ""};
 		break;
 	}
 
@@ -1682,17 +1713,14 @@ lpfc_get_hba_model_desc(struct lpfc_hba
 	if (descp && descp[0] == '\0') {
 		if (oneConnect)
 			snprintf(descp, 255,
-				"Emulex OneConnect %s, FCoE Initiator, Port %s",
-				m.name,
+				"Emulex OneConnect %s, %s Initiator, Port %s",
+				m.name, m.function,
 				phba->Port);
 		else
 			snprintf(descp, 255,
 				"Emulex %s %d%s %s %s",
-				m.name, m.max_speed,
-				(GE) ? "GE" : "Gb",
-				m.bus,
-				(GE) ? "FCoE Adapter" :
-					"Fibre Channel Adapter");
+				m.name, max_speed, (GE) ? "GE" : "Gb",
+				m.bus, m.function);
 	}
 }
 
@@ -2217,7 +2245,7 @@ lpfc_offline_prep(struct lpfc_hba * phba
 
 			if (vports[i]->load_flag & FC_UNLOADING)
 				continue;
-			vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED;
+			vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
 			shost =	lpfc_shost_from_vport(vports[i]);
 			list_for_each_entry_safe(ndlp, next_ndlp,
 						 &vports[i]->fc_nodes,
@@ -2308,6 +2336,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
 
 	spin_lock_irq(&phba->hbalock);
 	/* Release all the lpfc_scsi_bufs maintained by this host. */
+	spin_lock(&phba->scsi_buf_list_lock);
 	list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {
 		list_del(&sb->list);
 		pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data,
@@ -2315,6 +2344,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
 		kfree(sb);
 		phba->total_scsi_bufs--;
 	}
+	spin_unlock(&phba->scsi_buf_list_lock);
 
 	/* Release all the lpfc_iocbq entries maintained by this host. */
 	list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) {
@@ -2322,9 +2352,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
 		kfree(io);
 		phba->total_iocbq_bufs--;
 	}
-
 	spin_unlock_irq(&phba->hbalock);
-
 	return 0;
 }
 
@@ -2408,7 +2436,7 @@ lpfc_create_port(struct lpfc_hba *phba,
 	vport->els_tmofunc.function = lpfc_els_timeout;
 	vport->els_tmofunc.data = (unsigned long)vport;
 
-	error = scsi_add_host(shost, dev);
+	error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
 	if (error)
 		goto out_put_shost;
 
@@ -2699,6 +2727,63 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba
 }
 
 /**
+ * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function uses the QUERY_FW_CFG mailbox command to determine if the
+ * firmware loaded supports FCoE. A return of zero indicates that the mailbox
+ * was successful and the firmware supports FCoE. Any other return indicates
+ * a error. It is assumed that this function will be called before interrupts
+ * are enabled.
+ **/
+static int
+lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba)
+{
+	int rc = 0;
+	LPFC_MBOXQ_t *mboxq;
+	struct lpfc_mbx_query_fw_cfg *query_fw_cfg;
+	uint32_t length;
+	uint32_t shdr_status, shdr_add_status;
+
+	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"2621 Failed to allocate mbox for "
+				"query firmware config cmd\n");
+		return -ENOMEM;
+	}
+	query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg;
+	length = (sizeof(struct lpfc_mbx_query_fw_cfg) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_QUERY_FW_CFG,
+			 length, LPFC_SLI4_MBX_EMBED);
+	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+	/* The IOCTL status is embedded in the mailbox subheader. */
+	shdr_status = bf_get(lpfc_mbox_hdr_status,
+			     &query_fw_cfg->header.cfg_shdr.response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+				 &query_fw_cfg->header.cfg_shdr.response);
+	if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2622 Query Firmware Config failed "
+				"mbx status x%x, status x%x add_status x%x\n",
+				rc, shdr_status, shdr_add_status);
+		return -EINVAL;
+	}
+	if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2623 FCoE Function not supported by firmware. "
+				"Function mode = %08x\n",
+				query_fw_cfg->function_mode);
+		return -EINVAL;
+	}
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+	return 0;
+}
+
+/**
  * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async link completion queue entry.
@@ -2918,13 +3003,18 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba
 {
 	uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
 	int rc;
+	struct lpfc_vport *vport;
+	struct lpfc_nodelist *ndlp;
+	struct Scsi_Host  *shost;
+	uint32_t link_state;
 
+	phba->fc_eventTag = acqe_fcoe->event_tag;
 	phba->fcoe_eventtag = acqe_fcoe->event_tag;
 	switch (event_type) {
 	case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 			"2546 New FCF found index 0x%x tag 0x%x\n",
-			acqe_fcoe->fcf_index,
+			acqe_fcoe->index,
 			acqe_fcoe->event_tag);
 		/*
 		 * If the current FCF is in discovered state, or
@@ -2939,12 +3029,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba
 		spin_unlock_irq(&phba->hbalock);
 
 		/* Read the FCF table and re-discover SAN. */
-		rc = lpfc_sli4_read_fcf_record(phba,
-			LPFC_FCOE_FCF_GET_FIRST);
+		rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
 		if (rc)
 			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-				"2547 Read FCF record failed 0x%x\n",
-				rc);
+					"2547 Read FCF record failed 0x%x\n",
+					rc);
 		break;
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -2956,21 +3045,45 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-			"2549 FCF disconnected fron network index 0x%x"
-			" tag 0x%x\n", acqe_fcoe->fcf_index,
+			"2549 FCF disconnected from network index 0x%x"
+			" tag 0x%x\n", acqe_fcoe->index,
 			acqe_fcoe->event_tag);
 		/* If the event is not for currently used fcf do nothing */
-		if (phba->fcf.fcf_indx != acqe_fcoe->fcf_index)
+		if (phba->fcf.fcf_indx != acqe_fcoe->index)
 			break;
 		/*
 		 * Currently, driver support only one FCF - so treat this as
-		 * a link down.
+		 * a link down, but save the link state because we don't want
+		 * it to be changed to Link Down unless it is already down.
 		 */
+		link_state = phba->link_state;
 		lpfc_linkdown(phba);
+		phba->link_state = link_state;
 		/* Unregister FCF if no devices connected to it */
 		lpfc_unregister_unused_fcf(phba);
 		break;
-
+	case LPFC_FCOE_EVENT_TYPE_CVL:
+		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+			"2718 Clear Virtual Link Received for VPI 0x%x"
+			" tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
+		vport = lpfc_find_vport_by_vpid(phba,
+				acqe_fcoe->index - phba->vpi_base);
+		if (!vport)
+			break;
+		ndlp = lpfc_findnode_did(vport, Fabric_DID);
+		if (!ndlp)
+			break;
+		shost = lpfc_shost_from_vport(vport);
+		lpfc_linkdown_port(vport);
+		if (vport->port_type != LPFC_NPIV_PORT) {
+			mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+			spin_lock_irq(shost->host_lock);
+			ndlp->nlp_flag |= NLP_DELAY_TMO;
+			spin_unlock_irq(shost->host_lock);
+			ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
+			vport->port_state = LPFC_FLOGI;
+		}
+		break;
 	default:
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 			"0288 Unknown FCoE event type 0x%x event tag "
@@ -2990,6 +3103,7 @@ static void
 lpfc_sli4_async_dcbx_evt(struct lpfc_hba *phba,
 			 struct lpfc_acqe_dcbx *acqe_dcbx)
 {
+	phba->fc_eventTag = acqe_dcbx->event_tag;
 	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 			"0290 The SLI4 DCBX asynchronous event is not "
 			"handled yet\n");
@@ -3124,7 +3238,7 @@ static void lpfc_log_intr_mode(struct lp
  * PCI devices.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3220,7 +3334,7 @@ lpfc_reset_hba(struct lpfc_hba *phba)
  * support the SLI-3 HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3321,7 +3435,7 @@ lpfc_sli_driver_resource_unset(struct lp
  * support the SLI-4 HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3432,7 +3546,7 @@ lpfc_sli4_driver_resource_setup(struct l
 	/* Driver internel slow-path CQ Event pool */
 	INIT_LIST_HEAD(&phba->sli4_hba.sp_cqe_event_pool);
 	/* Response IOCB work queue list */
-	INIT_LIST_HEAD(&phba->sli4_hba.sp_rspiocb_work_queue);
+	INIT_LIST_HEAD(&phba->sli4_hba.sp_queue_event);
 	/* Asynchronous event CQ Event work queue list */
 	INIT_LIST_HEAD(&phba->sli4_hba.sp_asynce_work_queue);
 	/* Fast-path XRI aborted CQ Event work queue list */
@@ -3461,6 +3575,10 @@ lpfc_sli4_driver_resource_setup(struct l
 	if (unlikely(rc))
 		goto out_free_bsmbx;
 
+	rc = lpfc_sli4_fw_cfg_check(phba);
+	if (unlikely(rc))
+		goto out_free_bsmbx;
+
 	/* Set up the hba's configuration parameters. */
 	rc = lpfc_sli4_read_config(phba);
 	if (unlikely(rc))
@@ -3594,8 +3712,10 @@ lpfc_sli4_driver_resource_unset(struct l
 
 	/* Free the current connect table */
 	list_for_each_entry_safe(conn_entry, next_conn_entry,
-		&phba->fcf_conn_rec_list, list)
+		&phba->fcf_conn_rec_list, list) {
+		list_del_init(&conn_entry->list);
 		kfree(conn_entry);
+	}
 
 	return;
 }
@@ -3642,7 +3762,7 @@ lpfc_init_api_table_setup(struct lpfc_hb
  * device specific resource setup to support the HBA device it attached to.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3688,7 +3808,7 @@ lpfc_setup_driver_resource_phase1(struct
  * device specific resource setup to support the HBA device it attached to.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -3753,7 +3873,7 @@ lpfc_free_iocb_list(struct lpfc_hba *phb
  * list and set up the IOCB tag array accordingly.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3824,7 +3944,7 @@ lpfc_free_sgl_list(struct lpfc_hba *phba
 	rc = lpfc_sli4_remove_all_sgl_pages(phba);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-			"2005 Unable to deregister pages from HBA: %x", rc);
+			"2005 Unable to deregister pages from HBA: %x\n", rc);
 	}
 	kfree(phba->sli4_hba.lpfc_els_sgl_array);
 }
@@ -3872,7 +3992,7 @@ lpfc_free_active_sgl(struct lpfc_hba *ph
  * list and set up the sgl xritag tag array accordingly.
  *
  * Return codes
- *	0 - sucessful
+ *	0 - successful
  *	other values - error
  **/
 static int
@@ -3986,7 +4106,7 @@ out_free_mem:
  * enabled and the driver is reinitializing the device.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4146,7 +4266,7 @@ lpfc_sli4_remove_rpi_hdrs(struct lpfc_hb
  * PCI device data structure is set.
  *
  * Return codes
- *      pointer to @phba - sucessful
+ *      pointer to @phba - successful
  *      NULL - error
  **/
 static struct lpfc_hba *
@@ -4202,7 +4322,7 @@ lpfc_hba_free(struct lpfc_hba *phba)
  * host with it.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      other values - error
  **/
 static int
@@ -4273,7 +4393,8 @@ lpfc_setup_bg(struct lpfc_hba *phba, str
 			_dump_buf_data =
 				(char *) __get_free_pages(GFP_KERNEL, pagecnt);
 			if (_dump_buf_data) {
-				printk(KERN_ERR "BLKGRD allocated %d pages for "
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9043 BLKGRD: allocated %d pages for "
 				       "_dump_buf_data at 0x%p\n",
 				       (1 << pagecnt), _dump_buf_data);
 				_dump_buf_data_order = pagecnt;
@@ -4284,17 +4405,20 @@ lpfc_setup_bg(struct lpfc_hba *phba, str
 				--pagecnt;
 		}
 		if (!_dump_buf_data_order)
-			printk(KERN_ERR "BLKGRD ERROR unable to allocate "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9044 BLKGRD: ERROR unable to allocate "
 			       "memory for hexdump\n");
 	} else
-		printk(KERN_ERR "BLKGRD already allocated _dump_buf_data=0x%p"
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9045 BLKGRD: already allocated _dump_buf_data=0x%p"
 		       "\n", _dump_buf_data);
 	if (!_dump_buf_dif) {
 		while (pagecnt) {
 			_dump_buf_dif =
 				(char *) __get_free_pages(GFP_KERNEL, pagecnt);
 			if (_dump_buf_dif) {
-				printk(KERN_ERR "BLKGRD allocated %d pages for "
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9046 BLKGRD: allocated %d pages for "
 				       "_dump_buf_dif at 0x%p\n",
 				       (1 << pagecnt), _dump_buf_dif);
 				_dump_buf_dif_order = pagecnt;
@@ -4305,10 +4429,12 @@ lpfc_setup_bg(struct lpfc_hba *phba, str
 				--pagecnt;
 		}
 		if (!_dump_buf_dif_order)
-			printk(KERN_ERR "BLKGRD ERROR unable to allocate "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9047 BLKGRD: ERROR unable to allocate "
 			       "memory for hexdump\n");
 	} else
-		printk(KERN_ERR "BLKGRD already allocated _dump_buf_dif=0x%p\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9048 BLKGRD: already allocated _dump_buf_dif=0x%p\n",
 		       _dump_buf_dif);
 }
 
@@ -4365,7 +4491,7 @@ lpfc_post_init_setup(struct lpfc_hba *ph
  * with SLI-3 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -4384,9 +4510,13 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *
 		pdev = phba->pcidev;
 
 	/* Set the device DMA mask size */
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
-		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0
+	 || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) {
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0
+		 || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) {
 			return error;
+		}
+	}
 
 	/* Get the bus address of Bar0 and Bar2 and the number of bytes
 	 * required by each mapping.
@@ -4512,7 +4642,6 @@ int
 lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 {
 	struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg, scratchpad;
-	uint32_t onlnreg0, onlnreg1;
 	int i, port_error = -ENODEV;
 
 	if (!phba->sli4_hba.STAregaddr)
@@ -4556,21 +4685,20 @@ lpfc_sli4_post_status_check(struct lpfc_
 			bf_get(lpfc_scratchpad_slirev, &scratchpad),
 			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
 			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
-
+	phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
+	phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
 	/* With uncoverable error, log the error message and return error */
-	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
-		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
-		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"1422 HBA Unrecoverable error: "
-					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-					"online0_reg=0x%x, online1_reg=0x%x\n",
-					uerrlo_reg.word0, uerrhi_reg.word0,
-					onlnreg0, onlnreg1);
-		}
+	uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
+	uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
+	if ((~phba->sli4_hba.ue_mask_lo & uerrlo_reg.word0) ||
+	    (~phba->sli4_hba.ue_mask_hi & uerrhi_reg.word0)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"1422 HBA Unrecoverable error: "
+				"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+				"ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
+				uerrlo_reg.word0, uerrhi_reg.word0,
+				phba->sli4_hba.ue_mask_lo,
+				phba->sli4_hba.ue_mask_hi);
 		return -ENODEV;
 	}
 
@@ -4591,10 +4719,10 @@ lpfc_sli4_bar0_register_memmap(struct lp
 					LPFC_UERR_STATUS_LO;
 	phba->sli4_hba.UERRHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
 					LPFC_UERR_STATUS_HI;
-	phba->sli4_hba.ONLINE0regaddr = phba->sli4_hba.conf_regs_memmap_p +
-					LPFC_ONLINE0;
-	phba->sli4_hba.ONLINE1regaddr = phba->sli4_hba.conf_regs_memmap_p +
-					LPFC_ONLINE1;
+	phba->sli4_hba.UEMASKLOregaddr = phba->sli4_hba.conf_regs_memmap_p +
+					LPFC_UE_MASK_LO;
+	phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
+					LPFC_UE_MASK_HI;
 	phba->sli4_hba.SCRATCHPADregaddr = phba->sli4_hba.conf_regs_memmap_p +
 					LPFC_SCRATCHPAD;
 }
@@ -4662,7 +4790,7 @@ lpfc_sli4_bar2_register_memmap(struct lp
  * this routine.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - could not allocated memory.
  **/
 static int
@@ -4761,7 +4889,7 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_
  * allocation for the port.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4825,7 +4953,8 @@ lpfc_sli4_read_config(struct lpfc_hba *p
 		phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base;
 		phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base;
 		phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
-		phba->max_vpi = phba->sli4_hba.max_cfg_param.max_vpi;
+		phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ?
+				(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
 		phba->max_vports = phba->max_vpi;
 		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 				"2003 cfg params XRI(B:%d M:%d), "
@@ -4861,7 +4990,7 @@ lpfc_sli4_read_config(struct lpfc_hba *p
  * HBA consistent with the SLI-4 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4910,7 +5039,7 @@ lpfc_setup_endian_order(struct lpfc_hba
  * we just use some constant number as place holder.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -4979,10 +5108,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *
 	/* It does not make sense to have more EQs than WQs */
 	if (cfg_fcp_eq_count > phba->cfg_fcp_wq_count) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-				"2593 The number of FCP EQs (%d) is more "
-				"than the number of FCP WQs (%d), take "
-				"the number of FCP EQs same as than of "
-				"WQs (%d)\n", cfg_fcp_eq_count,
+				"2593 The FCP EQ count(%d) cannot be greater "
+				"than the FCP WQ count(%d), limiting the "
+				"FCP EQ count to %d\n", cfg_fcp_eq_count,
 				phba->cfg_fcp_wq_count,
 				phba->cfg_fcp_wq_count);
 		cfg_fcp_eq_count = phba->cfg_fcp_wq_count;
@@ -5058,15 +5186,6 @@ lpfc_sli4_queue_create(struct lpfc_hba *
 	}
 	phba->sli4_hba.els_cq = qdesc;
 
-	/* Create slow-path Unsolicited Receive Complete Queue */
-	qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
-				      phba->sli4_hba.cq_ecount);
-	if (!qdesc) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0502 Failed allocate slow-path USOL RX CQ\n");
-		goto out_free_els_cq;
-	}
-	phba->sli4_hba.rxq_cq = qdesc;
 
 	/* Create fast-path FCP Completion Queue(s), one-to-one with EQs */
 	phba->sli4_hba.fcp_cq = kzalloc((sizeof(struct lpfc_queue *) *
@@ -5075,7 +5194,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2577 Failed allocate memory for fast-path "
 				"CQ record array\n");
-		goto out_free_rxq_cq;
+		goto out_free_els_cq;
 	}
 	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) {
 		qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
@@ -5188,9 +5307,6 @@ out_free_fcp_cq:
 		phba->sli4_hba.fcp_cq[fcp_cqidx] = NULL;
 	}
 	kfree(phba->sli4_hba.fcp_cq);
-out_free_rxq_cq:
-	lpfc_sli4_queue_free(phba->sli4_hba.rxq_cq);
-	phba->sli4_hba.rxq_cq = NULL;
 out_free_els_cq:
 	lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
 	phba->sli4_hba.els_cq = NULL;
@@ -5218,7 +5334,7 @@ out_error:
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5247,10 +5363,6 @@ lpfc_sli4_queue_destroy(struct lpfc_hba
 	lpfc_sli4_queue_free(phba->sli4_hba.dat_rq);
 	phba->sli4_hba.dat_rq = NULL;
 
-	/* Release unsolicited receive complete queue */
-	lpfc_sli4_queue_free(phba->sli4_hba.rxq_cq);
-	phba->sli4_hba.rxq_cq = NULL;
-
 	/* Release ELS complete queue */
 	lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
 	phba->sli4_hba.els_cq = NULL;
@@ -5286,7 +5398,7 @@ lpfc_sli4_queue_destroy(struct lpfc_hba
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5383,25 +5495,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *p
 			phba->sli4_hba.els_cq->queue_id,
 			phba->sli4_hba.sp_eq->queue_id);
 
-	/* Set up slow-path Unsolicited Receive Complete Queue */
-	if (!phba->sli4_hba.rxq_cq) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0532 USOL RX CQ not allocated\n");
-		goto out_destroy_els_cq;
-	}
-	rc = lpfc_cq_create(phba, phba->sli4_hba.rxq_cq, phba->sli4_hba.sp_eq,
-			    LPFC_RCQ, LPFC_USOL);
-	if (rc) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0533 Failed setup of slow-path USOL RX CQ: "
-				"rc = 0x%x\n", rc);
-		goto out_destroy_els_cq;
-	}
-	lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-			"2587 USL CQ setup: cq-id=%d, parent eq-id=%d\n",
-			phba->sli4_hba.rxq_cq->queue_id,
-			phba->sli4_hba.sp_eq->queue_id);
-
 	/* Set up fast-path FCP Response Complete Queue */
 	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) {
 		if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
@@ -5507,7 +5600,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *p
 		goto out_destroy_fcp_wq;
 	}
 	rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
-			    phba->sli4_hba.rxq_cq, LPFC_USOL);
+			    phba->sli4_hba.els_cq, LPFC_USOL);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"0541 Failed setup of Receive Queue: "
@@ -5519,7 +5612,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *p
 			"parent cq-id=%d\n",
 			phba->sli4_hba.hdr_rq->queue_id,
 			phba->sli4_hba.dat_rq->queue_id,
-			phba->sli4_hba.rxq_cq->queue_id);
+			phba->sli4_hba.els_cq->queue_id);
 	return 0;
 
 out_destroy_fcp_wq:
@@ -5531,8 +5624,6 @@ out_destroy_mbx_wq:
 out_destroy_fcp_cq:
 	for (--fcp_cqidx; fcp_cqidx >= 0; fcp_cqidx--)
 		lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_cqidx]);
-	lpfc_cq_destroy(phba, phba->sli4_hba.rxq_cq);
-out_destroy_els_cq:
 	lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
 out_destroy_mbx_cq:
 	lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
@@ -5552,7 +5643,7 @@ out_error:
  * operation.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5574,8 +5665,6 @@ lpfc_sli4_queue_unset(struct lpfc_hba *p
 	lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
 	/* Unset ELS complete queue */
 	lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
-	/* Unset unsolicited receive complete queue */
-	lpfc_cq_destroy(phba, phba->sli4_hba.rxq_cq);
 	/* Unset FCP response complete queue */
 	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++)
 		lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_qidx]);
@@ -5599,7 +5688,7 @@ lpfc_sli4_queue_unset(struct lpfc_hba *p
  * Later, this can be used for all the slow-path events.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      -ENOMEM - No availble memory
  **/
 static int
@@ -5760,7 +5849,7 @@ lpfc_sli4_cq_event_release_all(struct lp
  * all resources assigned to the PCI function which originates this request.
  *
  * Return codes
- *      0 - sucessful
+ *      0 - successful
  *      ENOMEM - No availble memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -5923,7 +6012,7 @@ lpfc_sli4_fcfi_unreg(struct lpfc_hba *ph
  * with SLI-4 interface spec.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -5940,9 +6029,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba
 		pdev = phba->pcidev;
 
 	/* Set the device DMA mask size */
-	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
-		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0
+	 || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) {
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0
+		 || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) {
 			return error;
+		}
+	}
 
 	/* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the
 	 * number of bytes required by each mapping. They are actually
@@ -6052,7 +6145,7 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba
  * will be left with MSI-X enabled and leaks its vectors.
  *
  * Return codes
- *   0 - sucessful
+ *   0 - successful
  *   other values - error
  **/
 static int
@@ -6184,7 +6277,7 @@ lpfc_sli_disable_msix(struct lpfc_hba *p
  * is done in this function.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  */
 static int
@@ -6243,7 +6336,7 @@ lpfc_sli_disable_msi(struct lpfc_hba *ph
  * MSI-X -> MSI -> IRQ.
  *
  * Return codes
- *   0 - sucessful
+ *   0 - successful
  *   other values - error
  **/
 static uint32_t
@@ -6333,7 +6426,7 @@ lpfc_sli_disable_intr(struct lpfc_hba *p
  * enabled and leaks its vectors.
  *
  * Return codes
- * 0 - sucessful
+ * 0 - successful
  * other values - error
  **/
 static int
@@ -6443,7 +6536,7 @@ lpfc_sli4_disable_msix(struct lpfc_hba *
  * which is done in this function.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static int
@@ -6508,7 +6601,7 @@ lpfc_sli4_disable_msi(struct lpfc_hba *p
  * MSI-X -> MSI -> IRQ.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	other values - error
  **/
 static uint32_t
@@ -6722,6 +6815,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pd
 {
 	struct lpfc_hba   *phba;
 	struct lpfc_vport *vport = NULL;
+	struct Scsi_Host  *shost = NULL;
 	int error;
 	uint32_t cfg_mode, intr_mode;
 
@@ -6800,6 +6894,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pd
 		goto out_destroy_shost;
 	}
 
+	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
 	/* Now, trying to enable interrupt and bring up the device */
 	cfg_mode = phba->cfg_use_msi;
 	while (true) {
@@ -6866,6 +6961,8 @@ out_unset_pci_mem_s3:
 	lpfc_sli_pci_mem_unset(phba);
 out_disable_pci_dev:
 	lpfc_disable_pci_dev(phba);
+	if (shost)
+		scsi_host_put(shost);
 out_free_phba:
 	lpfc_hba_free(phba);
 	return error;
@@ -7036,6 +7133,7 @@ lpfc_pci_resume_one_s3(struct pci_dev *p
 	/* Restore device state from PCI config space */
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
+
 	if (pdev->is_busmaster)
 		pci_set_master(pdev);
 
@@ -7070,6 +7168,73 @@ lpfc_pci_resume_one_s3(struct pci_dev *p
 }
 
 /**
+ * lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot recover. It
+ * aborts and stops all the on-going I/Os on the pci device.
+ **/
+static void
+lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
+{
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2723 PCI channel I/O abort preparing for recovery\n");
+	/* Prepare for bringing HBA offline */
+	lpfc_offline_prep(phba);
+	/* Clear sli active flag to prevent sysfs access to HBA */
+	spin_lock_irq(&phba->hbalock);
+	phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
+	spin_unlock_irq(&phba->hbalock);
+	/* Stop and flush all I/Os and bring HBA offline */
+	lpfc_offline(phba);
+}
+
+/**
+ * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot reset. It
+ * disables the device interrupt and pci device, and aborts the internal FCP
+ * pending I/Os.
+ **/
+static void
+lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
+{
+	struct lpfc_sli *psli = &phba->sli;
+	struct lpfc_sli_ring  *pring;
+
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2710 PCI channel disable preparing for reset\n");
+	/* Disable interrupt and pci device */
+	lpfc_sli_disable_intr(phba);
+	pci_disable_device(phba->pcidev);
+	/*
+	 * There may be I/Os dropped by the firmware.
+	 * Error iocb (I/O) on txcmplq and let the SCSI layer
+	 * retry it after re-establishing link.
+	 */
+	pring = &psli->ring[psli->fcp_ring];
+	lpfc_sli_abort_iocb_ring(phba, pring);
+}
+
+/**
+ * lpfc_sli_prep_dev_for_perm_failure - Prepare SLI3 dev for pci slot disable
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to prepare the SLI3 device for PCI slot permanently
+ * disabling. It blocks the SCSI transport layer traffic and flushes the FCP
+ * pending I/Os.
+ **/
+static void
+lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
+{
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2711 PCI channel permanent disable for failure\n");
+	/* Clean up all driver's outstanding SCSI I/Os */
+	lpfc_sli_flush_fcp_rings(phba);
+}
+
+/**
  * lpfc_io_error_detected_s3 - Method for handling SLI-3 device PCI I/O error
  * @pdev: pointer to PCI device.
  * @state: the current PCI connection state.
@@ -7083,6 +7248,7 @@ lpfc_pci_resume_one_s3(struct pci_dev *p
  * as desired.
  *
  * Return codes
+ * 	PCI_ERS_RESULT_CAN_RECOVER - can be recovered with reset_link
  * 	PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
  * 	PCI_ERS_RESULT_DISCONNECT - device could not be recovered
  **/
@@ -7091,33 +7257,30 @@ lpfc_io_error_detected_s3(struct pci_dev
 {
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
-	struct lpfc_sli *psli = &phba->sli;
-	struct lpfc_sli_ring  *pring;
 
-	if (state == pci_channel_io_perm_failure) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"0472 PCI channel I/O permanent failure\n");
-		/* Block all SCSI devices' I/Os on the host */
-		lpfc_scsi_dev_block(phba);
-		/* Clean up all driver's outstanding SCSI I/Os */
-		lpfc_sli_flush_fcp_rings(phba);
+	/* Block all SCSI devices' I/Os on the host */
+	lpfc_scsi_dev_block(phba);
+
+	switch (state) {
+	case pci_channel_io_normal:
+		/* Non-fatal error, prepare for recovery */
+		lpfc_sli_prep_dev_for_recover(phba);
+		return PCI_ERS_RESULT_CAN_RECOVER;
+	case pci_channel_io_frozen:
+		/* Fatal error, prepare for slot reset */
+		lpfc_sli_prep_dev_for_reset(phba);
+		return PCI_ERS_RESULT_NEED_RESET;
+	case pci_channel_io_perm_failure:
+		/* Permanent failure, prepare for device down */
+		lpfc_prep_dev_for_perm_failure(phba);
 		return PCI_ERS_RESULT_DISCONNECT;
+	default:
+		/* Unknown state, prepare and request slot reset */
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"0472 Unknown PCI error state: x%x\n", state);
+		lpfc_sli_prep_dev_for_reset(phba);
+		return PCI_ERS_RESULT_NEED_RESET;
 	}
-
-	pci_disable_device(pdev);
-	/*
-	 * There may be I/Os dropped by the firmware.
-	 * Error iocb (I/O) on txcmplq and let the SCSI layer
-	 * retry it after re-establishing link.
-	 */
-	pring = &psli->ring[psli->fcp_ring];
-	lpfc_sli_abort_iocb_ring(phba, pring);
-
-	/* Disable interrupt */
-	lpfc_sli_disable_intr(phba);
-
-	/* Request a slot reset. */
-	return PCI_ERS_RESULT_NEED_RESET;
 }
 
 /**
@@ -7197,7 +7360,12 @@ lpfc_io_resume_s3(struct pci_dev *pdev)
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 
+	/* Bring the device online */
 	lpfc_online(phba);
+
+	/* Clean up Advanced Error Reporting (AER) if needed */
+	if (phba->hba_flag & HBA_AER_ENABLED)
+		pci_cleanup_aer_uncorrect_error_status(pdev);
 }
 
 /**
@@ -7213,15 +7381,15 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_h
 
 	if (phba->sli_rev == LPFC_SLI_REV4) {
 		if (max_xri <= 100)
-			return 4;
+			return 10;
 		else if (max_xri <= 256)
-			return 8;
+			return 25;
 		else if (max_xri <= 512)
-			return 16;
+			return 50;
 		else if (max_xri <= 1024)
-			return 32;
+			return 100;
 		else
-			return 48;
+			return 150;
 	} else
 		return 0;
 }
@@ -7249,6 +7417,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pd
 {
 	struct lpfc_hba   *phba;
 	struct lpfc_vport *vport = NULL;
+	struct Scsi_Host  *shost = NULL;
 	int error;
 	uint32_t cfg_mode, intr_mode;
 	int mcnt;
@@ -7329,6 +7498,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pd
 		goto out_destroy_shost;
 	}
 
+	shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
 	/* Now, trying to enable interrupt and bring up the device */
 	cfg_mode = phba->cfg_use_msi;
 	while (true) {
@@ -7342,6 +7512,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pd
 			error = -ENODEV;
 			goto out_free_sysfs_attr;
 		}
+		/* Default to single FCP EQ for non-MSI-X */
+		if (phba->intr_type != MSIX)
+			phba->cfg_fcp_eq_count = 1;
 		/* Set up SLI-4 HBA */
 		if (lpfc_sli4_hba_setup(phba)) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -7397,6 +7570,8 @@ out_unset_pci_mem_s4:
 	lpfc_sli4_pci_mem_unset(phba);
 out_disable_pci_dev:
 	lpfc_disable_pci_dev(phba);
+	if (shost)
+		scsi_host_put(shost);
 out_free_phba:
 	lpfc_hba_free(phba);
 	return error;
@@ -7971,6 +8146,10 @@ static struct pci_device_id lpfc_id_tabl
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TOMCAT,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FALCON,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0 }
 };
 
@@ -8053,15 +8232,15 @@ lpfc_exit(void)
 	if (lpfc_enable_npiv)
 		fc_release_transport(lpfc_vport_transport_template);
 	if (_dump_buf_data) {
-		printk(KERN_ERR "BLKGRD freeing %lu pages for _dump_buf_data "
-				"at 0x%p\n",
+		printk(KERN_ERR	"9062 BLKGRD: freeing %lu pages for "
+				"_dump_buf_data at 0x%p\n",
 				(1L << _dump_buf_data_order), _dump_buf_data);
 		free_pages((unsigned long)_dump_buf_data, _dump_buf_data_order);
 	}
 
 	if (_dump_buf_dif) {
-		printk(KERN_ERR "BLKGRD freeing %lu pages for _dump_buf_dif "
-				"at 0x%p\n",
+		printk(KERN_ERR	"9049 BLKGRD: freeing %lu pages for "
+				"_dump_buf_dif at 0x%p\n",
 				(1L << _dump_buf_dif_order), _dump_buf_dif);
 		free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order);
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_mbox.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mbox.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_mbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_mbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -25,8 +25,8 @@
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_transport_fc.h>
-
 #include <scsi/scsi.h>
+#include <scsi/fc/fc_fs.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -820,6 +820,10 @@ lpfc_reg_vpi(struct lpfc_vport *vport, L
 	mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
 	mb->un.varRegVpi.sid = vport->fc_myDID;
 	mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
+	memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
+	       sizeof(struct lpfc_name));
+	mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
+	mb->un.varRegVpi.wwn[1] = cpu_to_le32(mb->un.varRegVpi.wwn[1]);
 
 	mb->mbxCommand = MBX_REG_VPI;
 	mb->mbxOwner = OWN_HOST;
@@ -849,7 +853,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, ui
 	MAILBOX_t *mb = &pmb->u.mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
-	mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
+	else
+		mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base;
 
 	mb->mbxCommand = MBX_UNREG_VPI;
 	mb->mbxOwner = OWN_HOST;
@@ -1132,7 +1139,7 @@ lpfc_config_ring(struct lpfc_hba * phba,
 	/* Otherwise we setup specific rctl / type masks for this ring */
 	for (i = 0; i < pring->num_mask; i++) {
 		mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
-		if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
+		if (mb->un.varCfgRing.rrRegs[i].rval != FC_RCTL_ELS_REQ)
 			mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
 		else
 			mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
@@ -1654,9 +1661,12 @@ lpfc_sli4_config(struct lpfc_hba *phba,
 	/* Allocate record for keeping SGE virtual addresses */
 	mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
 				  GFP_KERNEL);
-	if (!mbox->sge_array)
+	if (!mbox->sge_array) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+				"2527 Failed to allocate non-embedded SGE "
+				"array.\n");
 		return 0;
-
+	}
 	for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) {
 		/* The DMA memory is always allocated in the length of a
 		 * page even though the last SGE might not fill up to a
@@ -1753,11 +1763,6 @@ lpfc_request_features(struct lpfc_hba *p
 	/* Set up host requested features. */
 	bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
 
-	if (phba->cfg_enable_fip)
-		bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
-	else
-		bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1);
-
 	/* Enable DIF (block guard) only if configured to do so. */
 	if (phba->cfg_enable_bg)
 		bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1);
@@ -1817,6 +1822,9 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, str
 	bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
 	bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
 	bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
+	memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
+	reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
+	reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
 	reg_vfi->bde.addrHigh = putPaddrHigh(phys);
 	reg_vfi->bde.addrLow = putPaddrLow(phys);
 	reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
@@ -1850,7 +1858,7 @@ lpfc_init_vpi(struct lpfc_hba *phba, str
 /**
  * lpfc_unreg_vfi - Initialize the UNREG_VFI mailbox command
  * @mbox: pointer to lpfc mbox command to initialize.
- * @vfi: VFI to be unregistered.
+ * @vport: vport associated with the VF.
  *
  * The UNREG_VFI mailbox command causes the SLI Host to put a virtual fabric
  * (logical NPort) into the inactive state. The SLI Host must have logged out
@@ -1859,11 +1867,12 @@ lpfc_init_vpi(struct lpfc_hba *phba, str
  * fabric inactive.
  **/
 void
-lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi)
+lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
 {
 	memset(mbox, 0, sizeof(*mbox));
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
-	bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi);
+	bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
+	       vport->vfi + vport->phba->vfi_base);
 }
 
 /**
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_nportdisc.c	2010-02-24 13:52:17.000000000 -0500
@@ -1223,6 +1223,12 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc
 	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
 		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
 		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
+			if (phba->sli_rev == LPFC_SLI_REV4) {
+				spin_unlock_irq(&phba->hbalock);
+				lpfc_sli4_free_rpi(phba,
+					mb->u.mb.un.varRegLogin.rpi);
+				spin_lock_irq(&phba->hbalock);
+			}
 			mp = (struct lpfc_dmabuf *) (mb->context1);
 			if (mp) {
 				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -1230,6 +1236,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc
 			}
 			lpfc_nlp_put(ndlp);
 			list_del(&mb->list);
+			phba->sli.mboxq_cnt--;
 			mempool_free(mb, phba->mbox_mem_pool);
 		}
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_scsi.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_scsi.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_scsi.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,22 +59,26 @@ static char *dif_op_str[] = {
 };
 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 void
-lpfc_debug_save_data(struct scsi_cmnd *cmnd)
+lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
 {
 	void *src, *dst;
 	struct scatterlist *sgde = scsi_sglist(cmnd);
 
 	if (!_dump_buf_data) {
-		printk(KERN_ERR "BLKGRD ERROR %s _dump_buf_data is NULL\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9050 BLKGRD: ERROR %s _dump_buf_data is NULL\n",
 				__func__);
 		return;
 	}
 
 
 	if (!sgde) {
-		printk(KERN_ERR "BLKGRD ERROR: data scatterlist is null\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9051 BLKGRD: ERROR: data scatterlist is null\n");
 		return;
 	}
 
@@ -88,19 +92,21 @@ lpfc_debug_save_data(struct scsi_cmnd *c
 }
 
 static void
-lpfc_debug_save_dif(struct scsi_cmnd *cmnd)
+lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
 {
 	void *src, *dst;
 	struct scatterlist *sgde = scsi_prot_sglist(cmnd);
 
 	if (!_dump_buf_dif) {
-		printk(KERN_ERR "BLKGRD ERROR %s _dump_buf_data is NULL\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9052 BLKGRD: ERROR %s _dump_buf_data is NULL\n",
 				__func__);
 		return;
 	}
 
 	if (!sgde) {
-		printk(KERN_ERR "BLKGRD ERROR: prot scatterlist is null\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9053 BLKGRD: ERROR: prot scatterlist is null\n");
 		return;
 	}
 
@@ -242,6 +248,36 @@ lpfc_send_sdev_queuedepth_change_event(s
 }
 
 /**
+ * lpfc_change_queue_depth - Alter scsi device queue depth
+ * @sdev: Pointer the scsi device on which to change the queue depth.
+ * @qdepth: New queue depth to set the sdev to.
+ * @reason: The reason for the queue depth change.
+ *
+ * This function is called by the midlayer and the LLD to alter the queue
+ * depth for a scsi device. This function sets the queue depth to the new
+ * value and sends an event out to log the queue depth change.
+ **/
+int
+lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
+	struct lpfc_hba   *phba = vport->phba;
+	struct lpfc_rport_data *rdata;
+	unsigned long new_queue_depth, old_queue_depth;
+
+	old_queue_depth = sdev->queue_depth;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	new_queue_depth = sdev->queue_depth;
+	rdata = sdev->hostdata;
+	if (rdata)
+		lpfc_send_sdev_queuedepth_change_event(phba, vport,
+						       rdata->pnode, sdev->lun,
+						       old_queue_depth,
+						       new_queue_depth);
+	return sdev->queue_depth;
+}
+
+/**
  * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread
  * @phba: The Hba for which this call is being executed.
  *
@@ -305,8 +341,10 @@ lpfc_rampup_queue_depth(struct lpfc_vpor
 	if (vport->cfg_lun_queue_depth <= queue_depth)
 		return;
 	spin_lock_irqsave(&phba->hbalock, flags);
-	if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) ||
-	 ((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) {
+	if (time_before(jiffies,
+			phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) ||
+	    time_before(jiffies,
+			phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL)) {
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		return;
 	}
@@ -338,10 +376,9 @@ lpfc_ramp_down_queue_handler(struct lpfc
 	struct lpfc_vport **vports;
 	struct Scsi_Host  *shost;
 	struct scsi_device *sdev;
-	unsigned long new_queue_depth, old_queue_depth;
+	unsigned long new_queue_depth;
 	unsigned long num_rsrc_err, num_cmd_success;
 	int i;
-	struct lpfc_rport_data *rdata;
 
 	num_rsrc_err = atomic_read(&phba->num_rsrc_err);
 	num_cmd_success = atomic_read(&phba->num_cmd_success);
@@ -359,22 +396,8 @@ lpfc_ramp_down_queue_handler(struct lpfc
 				else
 					new_queue_depth = sdev->queue_depth -
 								new_queue_depth;
-				old_queue_depth = sdev->queue_depth;
-				if (sdev->ordered_tags)
-					scsi_adjust_queue_depth(sdev,
-							MSG_ORDERED_TAG,
-							new_queue_depth);
-				else
-					scsi_adjust_queue_depth(sdev,
-							MSG_SIMPLE_TAG,
-							new_queue_depth);
-				rdata = sdev->hostdata;
-				if (rdata)
-					lpfc_send_sdev_queuedepth_change_event(
-						phba, vports[i],
-						rdata->pnode,
-						sdev->lun, old_queue_depth,
-						new_queue_depth);
+				lpfc_change_queue_depth(sdev, new_queue_depth,
+							SCSI_QDEPTH_DEFAULT);
 			}
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
@@ -398,7 +421,6 @@ lpfc_ramp_up_queue_handler(struct lpfc_h
 	struct Scsi_Host  *shost;
 	struct scsi_device *sdev;
 	int i;
-	struct lpfc_rport_data *rdata;
 
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL)
@@ -408,22 +430,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_h
 				if (vports[i]->cfg_lun_queue_depth <=
 				    sdev->queue_depth)
 					continue;
-				if (sdev->ordered_tags)
-					scsi_adjust_queue_depth(sdev,
-							MSG_ORDERED_TAG,
-							sdev->queue_depth+1);
-				else
-					scsi_adjust_queue_depth(sdev,
-							MSG_SIMPLE_TAG,
-							sdev->queue_depth+1);
-				rdata = sdev->hostdata;
-				if (rdata)
-					lpfc_send_sdev_queuedepth_change_event(
-						phba, vports[i],
-						rdata->pnode,
-						sdev->lun,
-						sdev->queue_depth - 1,
-						sdev->queue_depth);
+				lpfc_change_queue_depth(sdev,
+							sdev->queue_depth+1,
+							SCSI_QDEPTH_RAMP_UP);
 			}
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
@@ -589,7 +598,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *
 		iocb->ulpClass = CLASS3;
 		psb->status = IOSTAT_SUCCESS;
 		/* Put it back into the SCSI buffer list */
-		lpfc_release_scsi_buf_s4(phba, psb);
+		lpfc_release_scsi_buf_s3(phba, psb);
 
 	}
 
@@ -1024,7 +1033,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 
 		lpfc_cmd->seg_cnt = nseg;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9064 BLKGRD: %s: Too many sg segments from "
 			       "dma_map_sg.  Config %d, seg_cnt %d\n",
 			       __func__, phba->cfg_sg_seg_cnt,
 			       lpfc_cmd->seg_cnt);
@@ -1112,7 +1122,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
  * with the cmd
  */
 static int
-lpfc_sc_to_sli_prof(struct scsi_cmnd *sc)
+lpfc_sc_to_sli_prof(struct lpfc_hba *phba, struct scsi_cmnd *sc)
 {
 	uint8_t guard_type = scsi_host_get_guard(sc->device->host);
 	uint8_t ret_prof = LPFC_PROF_INVALID;
@@ -1136,7 +1146,8 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc
 
 		case SCSI_PROT_NORMAL:
 		default:
-			printk(KERN_ERR "Bad op/guard:%d/%d combination\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9063 BLKGRD:Bad op/guard:%d/%d combination\n",
 					scsi_get_prot_op(sc), guard_type);
 			break;
 
@@ -1157,7 +1168,8 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc
 		case SCSI_PROT_WRITE_STRIP:
 		case SCSI_PROT_NORMAL:
 		default:
-			printk(KERN_ERR "Bad op/guard:%d/%d combination\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9075 BLKGRD: Bad op/guard:%d/%d combination\n",
 					scsi_get_prot_op(sc), guard_type);
 			break;
 		}
@@ -1259,7 +1271,7 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba,
 	uint16_t apptagmask, apptagval;
 
 	pde1 = (struct lpfc_pde *) bpl;
-	prof = lpfc_sc_to_sli_prof(sc);
+	prof = lpfc_sc_to_sli_prof(phba, sc);
 
 	if (prof == LPFC_PROF_INVALID)
 		goto out;
@@ -1359,7 +1371,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
 		return 0;
 	}
 
-	prof = lpfc_sc_to_sli_prof(sc);
+	prof = lpfc_sc_to_sli_prof(phba, sc);
 	if (prof == LPFC_PROF_INVALID)
 		goto out;
 
@@ -1408,7 +1420,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
 		subtotal = 0; /* total bytes processed for current prot grp */
 		while (!pgdone) {
 			if (!sgde) {
-				printk(KERN_ERR "%s Invalid data segment\n",
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9065 BLKGRD:%s Invalid data segment\n",
 						__func__);
 				return 0;
 			}
@@ -1462,7 +1475,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
 			reftag += protgrp_blks;
 		} else {
 			/* if we're here, we have a bug */
-			printk(KERN_ERR "BLKGRD: bug in %s\n", __func__);
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9054 BLKGRD: bug in %s\n", __func__);
 		}
 
 	} while (!alldone);
@@ -1544,8 +1558,10 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hb
 
 		lpfc_cmd->seg_cnt = datasegcnt;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
-					"dma_map_sg.  Config %d, seg_cnt %d\n",
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9067 BLKGRD: %s: Too many sg segments"
+					" from dma_map_sg.  Config %d, seg_cnt"
+					" %d\n",
 					__func__, phba->cfg_sg_seg_cnt,
 					lpfc_cmd->seg_cnt);
 			scsi_dma_unmap(scsi_cmnd);
@@ -1579,8 +1595,9 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hb
 			lpfc_cmd->prot_seg_cnt = protsegcnt;
 			if (lpfc_cmd->prot_seg_cnt
 			    > phba->cfg_prot_sg_seg_cnt) {
-				printk(KERN_ERR "%s: Too many prot sg segments "
-						"from dma_map_sg.  Config %d,"
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9068 BLKGRD: %s: Too many prot sg "
+					"segments from dma_map_sg.  Config %d,"
 						"prot_seg_cnt %d\n", __func__,
 						phba->cfg_prot_sg_seg_cnt,
 						lpfc_cmd->prot_seg_cnt);
@@ -1671,23 +1688,26 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 	uint32_t bgstat = bgf->bgstat;
 	uint64_t failing_sector = 0;
 
-	printk(KERN_ERR "BG ERROR in cmd 0x%x lba 0x%llx blk cnt 0x%x "
+	lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9069 BLKGRD: BG ERROR in cmd"
+			" 0x%x lba 0x%llx blk cnt 0x%x "
 			"bgstat=0x%x bghm=0x%x\n",
 			cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd),
 			blk_rq_sectors(cmd->request), bgstat, bghm);
 
 	spin_lock(&_dump_buf_lock);
 	if (!_dump_buf_done) {
-		printk(KERN_ERR "Saving Data for %u blocks to debugfs\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,  "9070 BLKGRD: Saving"
+			" Data for %u blocks to debugfs\n",
 				(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
-		lpfc_debug_save_data(cmd);
+		lpfc_debug_save_data(phba, cmd);
 
 		/* If we have a prot sgl, save the DIF buffer */
 		if (lpfc_prot_group_type(phba, cmd) ==
 				LPFC_PG_TYPE_DIF_BUF) {
-			printk(KERN_ERR "Saving DIF for %u blocks to debugfs\n",
-					(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
-			lpfc_debug_save_dif(cmd);
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9071 BLKGRD: "
+				"Saving DIF for %u blocks to debugfs\n",
+				(cmd->cmnd[7] << 8 | cmd->cmnd[8]));
+			lpfc_debug_save_dif(phba, cmd);
 		}
 
 		_dump_buf_done = 1;
@@ -1696,15 +1716,17 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 
 	if (lpfc_bgs_get_invalid_prof(bgstat)) {
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "Invalid BlockGuard profile. bgstat:0x%x\n",
-				bgstat);
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9072 BLKGRD: Invalid"
+			" BlockGuard profile. bgstat:0x%x\n",
+			bgstat);
 		ret = (-1);
 		goto out;
 	}
 
 	if (lpfc_bgs_get_uninit_dif_block(bgstat)) {
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "Invalid BlockGuard DIF Block. bgstat:0x%x\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9073 BLKGRD: "
+				"Invalid BlockGuard DIF Block. bgstat:0x%x\n",
 				bgstat);
 		ret = (-1);
 		goto out;
@@ -1718,7 +1740,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 		cmd->result = DRIVER_SENSE << 24
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 		phba->bg_guard_err_cnt++;
-		printk(KERN_ERR "BLKGRD: guard_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9055 BLKGRD: guard_tag error\n");
 	}
 
 	if (lpfc_bgs_get_reftag_err(bgstat)) {
@@ -1730,7 +1753,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 
 		phba->bg_reftag_err_cnt++;
-		printk(KERN_ERR "BLKGRD: ref_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9056 BLKGRD: ref_tag error\n");
 	}
 
 	if (lpfc_bgs_get_apptag_err(bgstat)) {
@@ -1742,7 +1766,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 			| ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
 
 		phba->bg_apptag_err_cnt++;
-		printk(KERN_ERR "BLKGRD: app_tag error\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9061 BLKGRD: app_tag error\n");
 	}
 
 	if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
@@ -1763,7 +1788,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
 	if (!ret) {
 		/* No error was reported - problem in FW? */
 		cmd->result = ScsiResult(DID_ERROR, 0);
-		printk(KERN_ERR "BLKGRD: no errors reported!\n");
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+			"9057 BLKGRD: no errors reported!\n");
 	}
 
 out:
@@ -1822,9 +1848,10 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hb
 
 		lpfc_cmd->seg_cnt = nseg;
 		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
-			printk(KERN_ERR "%s: Too many sg segments from "
-			       "dma_map_sg.  Config %d, seg_cnt %d\n",
-			       __func__, phba->cfg_sg_seg_cnt,
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9074 BLKGRD:"
+				" %s: Too many sg segments from "
+				"dma_map_sg.  Config %d, seg_cnt %d\n",
+				__func__, phba->cfg_sg_seg_cnt,
 			       lpfc_cmd->seg_cnt);
 			scsi_dma_unmap(scsi_cmnd);
 			return 1;
@@ -2050,6 +2077,21 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 		goto out;
 	}
 
+	if (resp_info & RSP_LEN_VALID) {
+		rsplen = be32_to_cpu(fcprsp->rspRspLen);
+		if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
+		    (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+				 "2719 Invalid response length: "
+				 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
+				 cmnd->device->id,
+				 cmnd->device->lun, cmnd->cmnd[0],
+				 rsplen);
+			host_status = DID_ERROR;
+			goto out;
+		}
+	}
+
 	if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
 		uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
 		if (snslen > SCSI_SENSE_BUFFERSIZE)
@@ -2074,15 +2116,6 @@ lpfc_handle_fcp_err(struct lpfc_vport *v
 			 be32_to_cpu(fcprsp->rspRspLen),
 			 fcprsp->rspInfo3);
 
-	if (resp_info & RSP_LEN_VALID) {
-		rsplen = be32_to_cpu(fcprsp->rspRspLen);
-		if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
-		    (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
-			host_status = DID_ERROR;
-			goto out;
-		}
-	}
-
 	scsi_set_resid(cmnd, 0);
 	if (resp_info & RESID_UNDER) {
 		scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
@@ -2180,7 +2213,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
 	int result;
 	struct scsi_device *tmp_sdev;
-	int depth = 0;
+	int depth;
 	unsigned long flags;
 	struct lpfc_fast_path_event *fast_path_evt;
 	struct Scsi_Host *shost = cmd->device->host;
@@ -2264,7 +2297,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 					lpfc_printf_vlog(vport, KERN_WARNING,
 							LOG_BG,
 							"9031 non-zero BGSTAT "
-							"on unprotected cmd");
+							"on unprotected cmd\n");
 				}
 			}
 
@@ -2347,67 +2380,29 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 		return;
 	}
 
-
 	if (!result)
 		lpfc_rampup_queue_depth(vport, queue_depth);
 
-	if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
-	   ((jiffies - pnode->last_ramp_up_time) >
-		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
-	   ((jiffies - pnode->last_q_full_time) >
-		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
-	   (vport->cfg_lun_queue_depth > queue_depth)) {
-		shost_for_each_device(tmp_sdev, shost) {
-			if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){
-				if (tmp_sdev->id != scsi_id)
-					continue;
-				if (tmp_sdev->ordered_tags)
-					scsi_adjust_queue_depth(tmp_sdev,
-						MSG_ORDERED_TAG,
-						tmp_sdev->queue_depth+1);
-				else
-					scsi_adjust_queue_depth(tmp_sdev,
-						MSG_SIMPLE_TAG,
-						tmp_sdev->queue_depth+1);
-
-				pnode->last_ramp_up_time = jiffies;
-			}
-		}
-		lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode,
-			0xFFFFFFFF,
-			queue_depth , queue_depth + 1);
-	}
-
 	/*
 	 * Check for queue full.  If the lun is reporting queue full, then
 	 * back off the lun queue depth to prevent target overloads.
 	 */
 	if (result == SAM_STAT_TASK_SET_FULL && pnode &&
 	    NLP_CHK_NODE_ACT(pnode)) {
-		pnode->last_q_full_time = jiffies;
-
 		shost_for_each_device(tmp_sdev, shost) {
 			if (tmp_sdev->id != scsi_id)
 				continue;
 			depth = scsi_track_queue_full(tmp_sdev,
-					tmp_sdev->queue_depth - 1);
-		}
-		/*
-		 * The queue depth cannot be lowered any more.
-		 * Modify the returned error code to store
-		 * the final depth value set by
-		 * scsi_track_queue_full.
-		 */
-		if (depth == -1)
-			depth = shost->cmd_per_lun;
-
-		if (depth) {
+						      tmp_sdev->queue_depth-1);
+			if (depth <= 0)
+				continue;
 			lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
 					 "0711 detected queue full - lun queue "
 					 "depth adjusted to %d.\n", depth);
 			lpfc_send_sdev_queuedepth_change_event(phba, vport,
-				pnode, 0xFFFFFFFF,
-				depth+1, depth);
+							       pnode,
+							       tmp_sdev->lun,
+							       depth+1, depth);
 		}
 	}
 
@@ -2745,7 +2740,9 @@ void lpfc_poll_timeout(unsigned long ptr
 	struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring (phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
+
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -2771,7 +2768,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_hba   *phba = vport->phba;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *ndlp = rdata->pnode;
+	struct lpfc_nodelist *ndlp;
 	struct lpfc_scsi_buf *lpfc_cmd;
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int err;
@@ -2781,13 +2778,15 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 		cmnd->result = err;
 		goto out_fail_command;
 	}
+	ndlp = rdata->pnode;
 
 	if (!(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
 		scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
 
-		printk(KERN_ERR "BLKGRD ERROR: rcvd protected cmd:%02x op:%02x "
-				"str=%s without registering for BlockGuard - "
-				"Rejecting command\n",
+		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9058 BLKGRD: ERROR: rcvd protected cmd:%02x"
+				" op:%02x str=%s without registering for"
+				" BlockGuard - Rejecting command\n",
 				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
 				dif_op_str[scsi_get_prot_op(cmnd)]);
 		goto out_fail_command;
@@ -2827,61 +2826,66 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 	cmnd->scsi_done = done;
 
 	if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+		if (vport->phba->cfg_enable_bg) {
+			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				"9033 BLKGRD: rcvd protected cmd:%02x op:%02x "
 				"str=%s\n",
 				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
 				dif_op_str[scsi_get_prot_op(cmnd)]);
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				"9034 BLKGRD: CDB: %02x %02x %02x %02x %02x "
 				"%02x %02x %02x %02x %02x\n",
 				cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
 				cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
 				cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
 				cmnd->cmnd[9]);
-		if (cmnd->cmnd[0] == READ_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			if (cmnd->cmnd[0] == READ_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					"9035 BLKGRD: READ @ sector %llu, "
 					"count %u\n",
 					(unsigned long long)scsi_get_lba(cmnd),
 					blk_rq_sectors(cmnd->request));
-		else if (cmnd->cmnd[0] == WRITE_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else if (cmnd->cmnd[0] == WRITE_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					"9036 BLKGRD: WRITE @ sector %llu, "
 					"count %u cmd=%p\n",
 					(unsigned long long)scsi_get_lba(cmnd),
 					blk_rq_sectors(cmnd->request),
 					cmnd);
+		}
 
 		err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
 	} else {
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-				"9038 BLKGRD: rcvd unprotected cmd:%02x op:%02x"
-				" str=%s\n",
-				cmnd->cmnd[0], scsi_get_prot_op(cmnd),
-				dif_op_str[scsi_get_prot_op(cmnd)]);
-		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-				 "9039 BLKGRD: CDB: %02x %02x %02x %02x %02x "
-				 "%02x %02x %02x %02x %02x\n",
-				 cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
-				 cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
-				 cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
-				 cmnd->cmnd[9]);
-		if (cmnd->cmnd[0] == READ_10)
+		if (vport->phba->cfg_enable_bg) {
 			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
-					 "9040 dbg: READ @ sector %llu, "
-					 "count %u\n",
-					 (unsigned long long)scsi_get_lba(cmnd),
+					"9038 BLKGRD: rcvd unprotected cmd:"
+					"%02x op:%02x str=%s\n",
+					cmnd->cmnd[0], scsi_get_prot_op(cmnd),
+					dif_op_str[scsi_get_prot_op(cmnd)]);
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+					"9039 BLKGRD: CDB: %02x %02x %02x "
+					"%02x %02x %02x %02x %02x %02x %02x\n",
+					cmnd->cmnd[0], cmnd->cmnd[1],
+					cmnd->cmnd[2], cmnd->cmnd[3],
+					cmnd->cmnd[4], cmnd->cmnd[5],
+					cmnd->cmnd[6], cmnd->cmnd[7],
+					cmnd->cmnd[8], cmnd->cmnd[9]);
+			if (cmnd->cmnd[0] == READ_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+					"9040 dbg: READ @ sector %llu, "
+					"count %u\n",
+					(unsigned long long)scsi_get_lba(cmnd),
 					 blk_rq_sectors(cmnd->request));
-		else if (cmnd->cmnd[0] == WRITE_10)
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else if (cmnd->cmnd[0] == WRITE_10)
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					 "9041 dbg: WRITE @ sector %llu, "
 					 "count %u cmd=%p\n",
 					 (unsigned long long)scsi_get_lba(cmnd),
 					 blk_rq_sectors(cmnd->request), cmnd);
-		else
-			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
+			else
+				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 					 "9042 dbg: parser not implemented\n");
+		}
 		err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
 	}
 
@@ -2898,7 +2902,11 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 		goto out_host_busy_free_buf;
 	}
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring(phba);
+		spin_unlock(shost->host_lock);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
+
+		spin_lock(shost->host_lock);
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -2917,28 +2925,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 }
 
 /**
- * lpfc_block_error_handler - Routine to block error  handler
- * @cmnd: Pointer to scsi_cmnd data structure.
- *
- *  This routine blocks execution till fc_rport state is not FC_PORSTAT_BLCOEKD.
- **/
-static void
-lpfc_block_error_handler(struct scsi_cmnd *cmnd)
-{
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
-
-	spin_lock_irq(shost->host_lock);
-	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
-		spin_unlock_irq(shost->host_lock);
-		msleep(1000);
-		spin_lock_irq(shost->host_lock);
-	}
-	spin_unlock_irq(shost->host_lock);
-	return;
-}
-
-/**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
  * @cmnd: Pointer to scsi_cmnd data structure.
  *
@@ -2961,7 +2947,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 	int ret = SUCCESS;
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
 
-	lpfc_block_error_handler(cmnd);
+	fc_block_scsi_eh(cmnd);
 	lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
 	BUG_ON(!lpfc_cmd);
 
@@ -3001,6 +2987,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 
 	icmd->ulpLe = 1;
 	icmd->ulpClass = cmd->ulpClass;
+
+	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+	abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
+
 	if (lpfc_is_link_up(phba))
 		icmd->ulpCommand = CMD_ABORT_XRI_CN;
 	else
@@ -3016,7 +3006,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 	}
 
 	if (phba->cfg_poll & DISABLE_FCP_RING_INT)
-		lpfc_sli_poll_fcp_ring (phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
 
 	lpfc_cmd->waitq = &waitq;
 	/* Wait for abort to complete */
@@ -3166,9 +3157,15 @@ static int
 lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd)
 {
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned long later;
 
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+			"0797 Tgt Map rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
 	/*
 	 * If target is not in a MAPPED state, delay until
 	 * target is rediscovered or devloss timeout expires.
@@ -3253,13 +3250,19 @@ lpfc_device_reset_handler(struct scsi_cm
 	struct Scsi_Host  *shost = cmnd->device->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned tgt_id = cmnd->device->id;
 	unsigned int lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
 	int status;
 
-	lpfc_block_error_handler(cmnd);
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+			"0798 Device Reset rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
+	fc_block_scsi_eh(cmnd);
 
 	status = lpfc_chk_tgt_mapped(vport, cmnd);
 	if (status == FAILED) {
@@ -3312,13 +3315,19 @@ lpfc_target_reset_handler(struct scsi_cm
 	struct Scsi_Host  *shost = cmnd->device->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
-	struct lpfc_nodelist *pnode = rdata->pnode;
+	struct lpfc_nodelist *pnode;
 	unsigned tgt_id = cmnd->device->id;
 	unsigned int lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
 	int status;
 
-	lpfc_block_error_handler(cmnd);
+	if (!rdata) {
+		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+			"0799 Target Reset rport failure: rdata x%p\n", rdata);
+		return FAILED;
+	}
+	pnode = rdata->pnode;
+	fc_block_scsi_eh(cmnd);
 
 	status = lpfc_chk_tgt_mapped(vport, cmnd);
 	if (status == FAILED) {
@@ -3384,7 +3393,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd
 	fc_host_post_vendor_event(shost, fc_get_event_number(),
 		sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
 
-	lpfc_block_error_handler(cmnd);
+	fc_block_scsi_eh(cmnd);
 
 	/*
 	 * Since the driver manages a single bus device, reset all
@@ -3498,6 +3507,8 @@ lpfc_slave_alloc(struct scsi_device *sde
 				 "Allocated %d buffers.\n",
 				 num_to_alloc, num_allocated);
 	}
+	if (num_allocated > 0)
+		phba->total_scsi_bufs += num_allocated;
 	return 0;
 }
 
@@ -3534,7 +3545,8 @@ lpfc_slave_configure(struct scsi_device
 	rport->dev_loss_tmo = vport->cfg_devloss_tmo;
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-		lpfc_sli_poll_fcp_ring(phba);
+		lpfc_sli_handle_fast_ring_event(phba,
+			&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
 		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
 			lpfc_poll_rearm_timer(phba);
 	}
@@ -3576,6 +3588,7 @@ struct scsi_host_template lpfc_template
 	.shost_attrs		= lpfc_hba_attrs,
 	.max_sectors		= 0xFFFF,
 	.vendor_id		= LPFC_NL_VENDOR_ID,
+	.change_queue_depth	= lpfc_change_queue_depth,
 };
 
 struct scsi_host_template lpfc_vport_template = {
@@ -3597,4 +3610,5 @@ struct scsi_host_template lpfc_vport_tem
 	.use_clustering		= ENABLE_CLUSTERING,
 	.shost_attrs		= lpfc_vport_attrs,
 	.max_sectors		= 0xFFFF,
+	.change_queue_depth	= lpfc_change_queue_depth,
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli4.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli4.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli4.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli4.h	2010-02-24 13:52:17.000000000 -0500
@@ -28,7 +28,7 @@
 /* Multi-queue arrangement for fast-path FCP work queues */
 #define LPFC_FN_EQN_MAX       8
 #define LPFC_SP_EQN_DEF       1
-#define LPFC_FP_EQN_DEF       1
+#define LPFC_FP_EQN_DEF       4
 #define LPFC_FP_EQN_MIN       1
 #define LPFC_FP_EQN_MAX       (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF)
 
@@ -58,6 +58,16 @@
 #define LPFC_FCOE_FKA_ADV_PER	0
 #define LPFC_FCOE_FIP_PRIORITY	0x80
 
+#define sli4_sid_from_fc_hdr(fc_hdr)  \
+	((fc_hdr)->fh_s_id[0] << 16 | \
+	 (fc_hdr)->fh_s_id[1] <<  8 | \
+	 (fc_hdr)->fh_s_id[2])
+
+#define sli4_fctl_from_fc_hdr(fc_hdr)  \
+	((fc_hdr)->fh_f_ctl[0] << 16 | \
+	 (fc_hdr)->fh_f_ctl[1] <<  8 | \
+	 (fc_hdr)->fh_f_ctl[2])
+
 enum lpfc_sli4_queue_type {
 	LPFC_EQ,
 	LPFC_GCQ,
@@ -110,18 +120,6 @@ struct lpfc_queue {
 	union sli4_qe qe[1];	/* array to index entries (must be last) */
 };
 
-struct lpfc_cq_event {
-	struct list_head list;
-	union {
-		struct lpfc_mcqe		mcqe_cmpl;
-		struct lpfc_acqe_link		acqe_link;
-		struct lpfc_acqe_fcoe		acqe_fcoe;
-		struct lpfc_acqe_dcbx		acqe_dcbx;
-		struct lpfc_rcqe		rcqe_cmpl;
-		struct sli4_wcqe_xri_aborted	wcqe_axri;
-	} cqe;
-};
-
 struct lpfc_sli4_link {
 	uint8_t speed;
 	uint8_t duplex;
@@ -166,7 +164,7 @@ struct lpfc_fip_param_hdr {
 #define	lpfc_fip_param_hdr_fipp_mode_SHIFT	6
 #define	lpfc_fip_param_hdr_fipp_mode_MASK	0x3
 #define lpfc_fip_param_hdr_fipp_mode_WORD	parm_flags
-#define	FIPP_MODE_ON				0x2
+#define	FIPP_MODE_ON				0x1
 #define	FIPP_MODE_OFF				0x0
 #define FIPP_VLAN_VALID				0x1
 };
@@ -295,9 +293,8 @@ struct lpfc_sli4_hba {
 	/* BAR0 PCI config space register memory map */
 	void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */
 	void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
-	void __iomem *ONLINE0regaddr; /* Address to components of internal UE */
-	void __iomem *ONLINE1regaddr; /* Address to components of internal UE */
-#define LPFC_ONLINE_NERR	0xFFFFFFFF
+	void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
+	void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
 	void __iomem *SCRATCHPADregaddr; /* Address to scratchpad register */
 	/* BAR1 FCoE function CSR register memory map */
 	void __iomem *STAregaddr;    /* Address to HST_STATE register */
@@ -311,6 +308,8 @@ struct lpfc_sli4_hba {
 	void __iomem *MQDBregaddr;   /* Address to MQ_DOORBELL register */
 	void __iomem *BMBXregaddr;   /* Address to BootStrap MBX register */
 
+	uint32_t ue_mask_lo;
+	uint32_t ue_mask_hi;
 	struct msix_entry *msix_entries;
 	uint32_t cfg_eqn;
 	struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */
@@ -325,7 +324,6 @@ struct lpfc_sli4_hba {
 	struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
 	struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
 	struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
-	struct lpfc_queue *rxq_cq; /* Slow-path unsolicited complete queue */
 
 	/* Setup information for various queue parameters */
 	int eq_esize;
@@ -360,7 +358,7 @@ struct lpfc_sli4_hba {
 	unsigned long *rpi_bmask;
 	uint16_t rpi_count;
 	struct lpfc_sli4_flags sli4_flags;
-	struct list_head sp_rspiocb_work_queue;
+	struct list_head sp_queue_event;
 	struct list_head sp_cqe_event_pool;
 	struct list_head sp_asynce_work_queue;
 	struct list_head sp_fcp_xri_aborted_work_queue;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.c	2010-02-24 13:52:17.000000000 -0500
@@ -30,6 +30,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/fc/fc_fs.h>
+#include <linux/aer.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -58,8 +59,11 @@ typedef enum _lpfc_iocb_type {
 static int lpfc_sli_issue_mbox_s4(struct lpfc_hba *, LPFC_MBOXQ_t *,
 				  uint32_t);
 static int lpfc_sli4_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *,
-			    uint8_t *, uint32_t *);
-
+			      uint8_t *, uint32_t *);
+static struct lpfc_iocbq *lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *,
+							 struct lpfc_iocbq *);
+static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *,
+				      struct hbq_dmabuf *);
 static IOCB_t *
 lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
 {
@@ -259,6 +263,9 @@ lpfc_sli4_eq_release(struct lpfc_queue *
 	bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
 	bf_set(lpfc_eqcq_doorbell_eqid, &doorbell, q->queue_id);
 	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+	/* PCI read to flush PCI pipeline on re-arming for INTx mode */
+	if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
+		readl(q->phba->sli4_hba.EQCQDBregaddr);
 	return released;
 }
 
@@ -515,6 +522,8 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phb
 	struct lpfc_sglq *sglq = NULL;
 	uint16_t adj_xri;
 	list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list);
+	if (!sglq)
+		return NULL;
 	adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
 	phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
 	return sglq;
@@ -572,9 +581,9 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_
 		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
 	if (sglq)  {
 		if (iocbq->iocb_flag & LPFC_DRIVER_ABORTED
-			|| ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
+			&& ((iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
 			&& (iocbq->iocb.un.ulpWord[4]
-				== IOERR_SLI_ABORTED))) {
+				== IOERR_ABORT_REQUESTED))) {
 			spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
 					iflag);
 			list_add(&sglq->list,
@@ -767,6 +776,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd
 	case CMD_CLOSE_XRI_CX:
 	case CMD_XRI_ABORTED_CX:
 	case CMD_ABORT_MXRI64_CN:
+	case CMD_XMIT_BLS_RSP64_CX:
 		type = LPFC_ABORT_IOCB;
 		break;
 	case CMD_RCV_SEQUENCE_CX:
@@ -1373,7 +1383,7 @@ lpfc_sli_hbq_to_firmware_s4(struct lpfc_
 /* HBQ for ELS and CT traffic. */
 static struct lpfc_hbq_init lpfc_els_hbq = {
 	.rn = 1,
-	.entry_count = 200,
+	.entry_count = 256,
 	.mask_count = 0,
 	.profile = 0,
 	.ring_mask = (1 << LPFC_ELS_RING),
@@ -1472,8 +1482,11 @@ err:
 int
 lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno)
 {
-	return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
-					 lpfc_hbq_defs[qno]->add_count));
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		return 0;
+	else
+		return lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
+					 lpfc_hbq_defs[qno]->add_count);
 }
 
 /**
@@ -1488,8 +1501,12 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba
 static int
 lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno)
 {
-	return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
-					 lpfc_hbq_defs[qno]->init_count));
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		return lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
+					 lpfc_hbq_defs[qno]->entry_count);
+	else
+		return lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
+					 lpfc_hbq_defs[qno]->init_count);
 }
 
 /**
@@ -1794,7 +1811,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba
 		 */
 		if (lpfc_sli_chk_mbx_command(pmbox->mbxCommand) ==
 		    MBX_SHUTDOWN) {
-			/* Unknow mailbox command compl */
+			/* Unknown mailbox command compl */
 			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
 					"(%d):0323 Unknown Mailbox command "
 					"x%x (x%x) Cmpl\n",
@@ -2068,8 +2085,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_
 	if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
 	    (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
 	    (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) {
-		Rctl = FC_ELS_REQ;
-		Type = FC_ELS_DATA;
+		Rctl = FC_RCTL_ELS_REQ;
+		Type = FC_TYPE_ELS;
 	} else {
 		w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]);
 		Rctl = w5p->hcsw.Rctl;
@@ -2079,8 +2096,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_
 		if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
 			(irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
 			 irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
-			Rctl = FC_ELS_REQ;
-			Type = FC_ELS_DATA;
+			Rctl = FC_RCTL_ELS_REQ;
+			Type = FC_TYPE_ELS;
 			w5p->hcsw.Rctl = Rctl;
 			w5p->hcsw.Type = Type;
 		}
@@ -2324,168 +2341,6 @@ void lpfc_poll_eratt(unsigned long ptr)
 	return;
 }
 
-/**
- * lpfc_sli_poll_fcp_ring - Handle FCP ring completion in polling mode
- * @phba: Pointer to HBA context object.
- *
- * This function is called from lpfc_queuecommand, lpfc_poll_timeout,
- * lpfc_abort_handler and lpfc_slave_configure when FCP_RING_POLLING
- * is enabled.
- *
- * The caller does not hold any lock.
- * The function processes each response iocb in the response ring until it
- * finds an iocb with LE bit set and chains all the iocbs upto the iocb with
- * LE bit set. The function will call the completion handler of the command iocb
- * if the response iocb indicates a completion for a command iocb or it is
- * an abort completion.
- **/
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
-{
-	struct lpfc_sli      *psli  = &phba->sli;
-	struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING];
-	IOCB_t *irsp = NULL;
-	IOCB_t *entry = NULL;
-	struct lpfc_iocbq *cmdiocbq = NULL;
-	struct lpfc_iocbq rspiocbq;
-	struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
-	uint32_t status;
-	uint32_t portRspPut, portRspMax;
-	int type;
-	uint32_t rsp_cmpl = 0;
-	uint32_t ha_copy;
-	unsigned long iflags;
-
-	pring->stats.iocb_event++;
-
-	/*
-	 * The next available response entry should never exceed the maximum
-	 * entries.  If it does, treat it as an adapter hardware error.
-	 */
-	portRspMax = pring->numRiocb;
-	portRspPut = le32_to_cpu(pgp->rspPutInx);
-	if (unlikely(portRspPut >= portRspMax)) {
-		lpfc_sli_rsp_pointers_error(phba, pring);
-		return;
-	}
-
-	rmb();
-	while (pring->rspidx != portRspPut) {
-		entry = lpfc_resp_iocb(phba, pring);
-		if (++pring->rspidx >= portRspMax)
-			pring->rspidx = 0;
-
-		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
-				      (uint32_t *) &rspiocbq.iocb,
-				      phba->iocb_rsp_size);
-		irsp = &rspiocbq.iocb;
-		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
-		pring->stats.iocb_rsp++;
-		rsp_cmpl++;
-
-		if (unlikely(irsp->ulpStatus)) {
-			/* Rsp ring <ringno> error: IOCB */
-			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-					"0326 Rsp Ring %d error: IOCB Data: "
-					"x%x x%x x%x x%x x%x x%x x%x x%x\n",
-					pring->ringno,
-					irsp->un.ulpWord[0],
-					irsp->un.ulpWord[1],
-					irsp->un.ulpWord[2],
-					irsp->un.ulpWord[3],
-					irsp->un.ulpWord[4],
-					irsp->un.ulpWord[5],
-					*(uint32_t *)&irsp->un1,
-					*((uint32_t *)&irsp->un1 + 1));
-		}
-
-		switch (type) {
-		case LPFC_ABORT_IOCB:
-		case LPFC_SOL_IOCB:
-			/*
-			 * Idle exchange closed via ABTS from port.  No iocb
-			 * resources need to be recovered.
-			 */
-			if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
-				lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-						"0314 IOCB cmd 0x%x "
-						"processed. Skipping "
-						"completion",
-						irsp->ulpCommand);
-				break;
-			}
-
-			spin_lock_irqsave(&phba->hbalock, iflags);
-			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
-							 &rspiocbq);
-			spin_unlock_irqrestore(&phba->hbalock, iflags);
-			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-						      &rspiocbq);
-			}
-			break;
-		default:
-			if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
-				char adaptermsg[LPFC_MAX_ADPTMSG];
-				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
-				memcpy(&adaptermsg[0], (uint8_t *) irsp,
-				       MAX_MSG_DATA);
-				dev_warn(&((phba->pcidev)->dev),
-					 "lpfc%d: %s\n",
-					 phba->brd_no, adaptermsg);
-			} else {
-				/* Unknown IOCB command */
-				lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-						"0321 Unknown IOCB command "
-						"Data: x%x, x%x x%x x%x x%x\n",
-						type, irsp->ulpCommand,
-						irsp->ulpStatus,
-						irsp->ulpIoTag,
-						irsp->ulpContext);
-			}
-			break;
-		}
-
-		/*
-		 * The response IOCB has been processed.  Update the ring
-		 * pointer in SLIM.  If the port response put pointer has not
-		 * been updated, sync the pgp->rspPutInx and fetch the new port
-		 * response put pointer.
-		 */
-		writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
-
-		if (pring->rspidx == portRspPut)
-			portRspPut = le32_to_cpu(pgp->rspPutInx);
-	}
-
-	ha_copy = readl(phba->HAregaddr);
-	ha_copy >>= (LPFC_FCP_RING * 4);
-
-	if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
-		spin_lock_irqsave(&phba->hbalock, iflags);
-		pring->stats.iocb_rsp_full++;
-		status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
-		writel(status, phba->CAregaddr);
-		readl(phba->CAregaddr);
-		spin_unlock_irqrestore(&phba->hbalock, iflags);
-	}
-	if ((ha_copy & HA_R0CE_RSP) &&
-	    (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
-		spin_lock_irqsave(&phba->hbalock, iflags);
-		pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
-		pring->stats.iocb_cmd_empty++;
-
-		/* Force update of the local copy of cmdGetInx */
-		pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
-		lpfc_sli_resume_iocb(phba, pring);
-
-		if ((pring->lpfc_sli_cmd_available))
-			(pring->lpfc_sli_cmd_available) (phba, pring);
-
-		spin_unlock_irqrestore(&phba->hbalock, iflags);
-	}
-
-	return;
-}
 
 /**
  * lpfc_sli_handle_fast_ring_event - Handle ring events on FCP ring
@@ -2502,9 +2357,9 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_
  * an abort completion. The function will call lpfc_sli_process_unsol_iocb
  * function if this is an unsolicited iocb.
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
- * to check it explicitly. This function always returns 1.
- **/
-static int
+ * to check it explicitly.
+ */
+int
 lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
 				struct lpfc_sli_ring *pring, uint32_t mask)
 {
@@ -2534,6 +2389,11 @@ lpfc_sli_handle_fast_ring_event(struct l
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
 		return 1;
 	}
+	if (phba->fcp_ring_in_use) {
+		spin_unlock_irqrestore(&phba->hbalock, iflag);
+		return 1;
+	} else
+		phba->fcp_ring_in_use = 1;
 
 	rmb();
 	while (pring->rspidx != portRspPut) {
@@ -2604,10 +2464,6 @@ lpfc_sli_handle_fast_ring_event(struct l
 			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
 							 &rspiocbq);
 			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-				if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
-					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-							      &rspiocbq);
-				} else {
 					spin_unlock_irqrestore(&phba->hbalock,
 							       iflag);
 					(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
@@ -2615,7 +2471,6 @@ lpfc_sli_handle_fast_ring_event(struct l
 					spin_lock_irqsave(&phba->hbalock,
 							  iflag);
 				}
-			}
 			break;
 		case LPFC_UNSOL_IOCB:
 			spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -2675,6 +2530,7 @@ lpfc_sli_handle_fast_ring_event(struct l
 
 	}
 
+	phba->fcp_ring_in_use = 0;
 	spin_unlock_irqrestore(&phba->hbalock, iflag);
 	return rc;
 }
@@ -3018,16 +2874,39 @@ lpfc_sli_handle_slow_ring_event_s4(struc
 				   struct lpfc_sli_ring *pring, uint32_t mask)
 {
 	struct lpfc_iocbq *irspiocbq;
+	struct hbq_dmabuf *dmabuf;
+	struct lpfc_cq_event *cq_event;
 	unsigned long iflag;
 
-	while (!list_empty(&phba->sli4_hba.sp_rspiocb_work_queue)) {
+	spin_lock_irqsave(&phba->hbalock, iflag);
+	phba->hba_flag &= ~HBA_SP_QUEUE_EVT;
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
+	while (!list_empty(&phba->sli4_hba.sp_queue_event)) {
 		/* Get the response iocb from the head of work queue */
 		spin_lock_irqsave(&phba->hbalock, iflag);
-		list_remove_head(&phba->sli4_hba.sp_rspiocb_work_queue,
-				 irspiocbq, struct lpfc_iocbq, list);
+		list_remove_head(&phba->sli4_hba.sp_queue_event,
+				 cq_event, struct lpfc_cq_event, list);
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
-		/* Process the response iocb */
-		lpfc_sli_sp_handle_rspiocb(phba, pring, irspiocbq);
+
+		switch (bf_get(lpfc_wcqe_c_code, &cq_event->cqe.wcqe_cmpl)) {
+		case CQE_CODE_COMPL_WQE:
+			irspiocbq = container_of(cq_event, struct lpfc_iocbq,
+						 cq_event);
+			/* Translate ELS WCQE to response IOCBQ */
+			irspiocbq = lpfc_sli4_els_wcqe_to_rspiocbq(phba,
+								   irspiocbq);
+			if (irspiocbq)
+				lpfc_sli_sp_handle_rspiocb(phba, pring,
+							   irspiocbq);
+			break;
+		case CQE_CODE_RECEIVE:
+			dmabuf = container_of(cq_event, struct hbq_dmabuf,
+					      cq_event);
+			lpfc_sli4_handle_received_buffer(phba, dmabuf);
+			break;
+		default:
+			break;
+		}
 	}
 }
 
@@ -3416,6 +3295,7 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
 
 	/* perform board reset */
 	phba->fc_eventTag = 0;
+	phba->link_events = 0;
 	phba->pport->fc_myDID = 0;
 	phba->pport->fc_prevDID = 0;
 
@@ -3476,6 +3356,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba
 
 	/* perform board reset */
 	phba->fc_eventTag = 0;
+	phba->link_events = 0;
 	phba->pport->fc_myDID = 0;
 	phba->pport->fc_prevDID = 0;
 
@@ -3495,7 +3376,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba
 	list_del_init(&phba->sli4_hba.dat_rq->list);
 	list_del_init(&phba->sli4_hba.mbx_cq->list);
 	list_del_init(&phba->sli4_hba.els_cq->list);
-	list_del_init(&phba->sli4_hba.rxq_cq->list);
 	for (qindx = 0; qindx < phba->cfg_fcp_wq_count; qindx++)
 		list_del_init(&phba->sli4_hba.fcp_wq[qindx]->list);
 	for (qindx = 0; qindx < phba->cfg_fcp_eq_count; qindx++)
@@ -3531,9 +3411,13 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *
 	struct lpfc_sli *psli;
 	volatile uint32_t word0;
 	void __iomem *to_slim;
+	uint32_t hba_aer_enabled;
 
 	spin_lock_irq(&phba->hbalock);
 
+	/* Take PCIe device Advanced Error Reporting (AER) state */
+	hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
+
 	psli = &phba->sli;
 
 	/* Restart HBA */
@@ -3573,6 +3457,10 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *
 	/* Give the INITFF and Post time to settle. */
 	mdelay(100);
 
+	/* Reset HBA AER if it was enabled, note hba_flag was reset above */
+	if (hba_aer_enabled)
+		pci_disable_pcie_error_reporting(phba->pcidev);
+
 	lpfc_hba_down_post(phba);
 
 	return 0;
@@ -4042,6 +3930,24 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba
 	if (rc)
 		goto lpfc_sli_hba_setup_error;
 
+	/* Enable PCIe device Advanced Error Reporting (AER) if configured */
+	if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
+		rc = pci_enable_pcie_error_reporting(phba->pcidev);
+		if (!rc) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"2709 This device supports "
+					"Advanced Error Reporting (AER)\n");
+			spin_lock_irq(&phba->hbalock);
+			phba->hba_flag |= HBA_AER_ENABLED;
+			spin_unlock_irq(&phba->hbalock);
+		} else {
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"2708 This device does not support "
+					"Advanced Error Reporting (AER)\n");
+			phba->cfg_aer_support = 0;
+		}
+	}
+
 	if (phba->sli_rev == 3) {
 		phba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE;
 		phba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE;
@@ -4163,7 +4069,7 @@ lpfc_sli4_read_fcoe_params(struct lpfc_h
  * addition, this routine gets the port vpd data.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - could not allocated memory.
  **/
 static int
@@ -4211,6 +4117,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba
 	if (rc) {
 		dma_free_coherent(&phba->pcidev->dev, dma_size,
 				  dmabuf->virt, dmabuf->phys);
+		kfree(dmabuf);
 		return -EIO;
 	}
 
@@ -4243,7 +4150,6 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba
 
 	lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
 	lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-	lpfc_sli4_cq_release(phba->sli4_hba.rxq_cq, LPFC_QUEUE_REARM);
 	for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++)
 		lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx],
 				     LPFC_QUEUE_REARM);
@@ -4322,6 +4228,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 	phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
 	if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
 		phba->hba_flag |= HBA_FCOE_SUPPORT;
+
+	if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
+		LPFC_DCBX_CEE_MODE)
+		phba->hba_flag |= HBA_FIP_SUPPORT;
+	else
+		phba->hba_flag &= ~HBA_FIP_SUPPORT;
+
 	if (phba->sli_rev != LPFC_SLI_REV4 ||
 	    !(phba->hba_flag & HBA_FCOE_SUPPORT)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
@@ -4468,7 +4381,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 	rc = lpfc_sli4_post_sgl_list(phba);
 	if (unlikely(rc)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-				"0582 Error %d during sgl post operation", rc);
+				"0582 Error %d during sgl post operation\n",
+					rc);
 		rc = -ENODEV;
 		goto out_free_vpd;
 	}
@@ -4477,8 +4391,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 	rc = lpfc_sli4_repost_scsi_sgl_list(phba);
 	if (unlikely(rc)) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
-				"0383 Error %d during scsi sgl post opeation",
-				rc);
+				"0383 Error %d during scsi sgl post "
+				"operation\n", rc);
 		/* Some Scsi buffers were moved to the abort scsi list */
 		/* A pci function reset will repost them */
 		rc = -ENODEV;
@@ -4494,10 +4408,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
 		rc = -ENODEV;
 		goto out_free_vpd;
 	}
-	if (phba->cfg_enable_fip)
-		bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 1);
-	else
-		bf_set(lpfc_fip_flag, &phba->sli4_hba.sli4_flags, 0);
 
 	/* Set up all the queues to the device */
 	rc = lpfc_sli4_queue_setup(phba);
@@ -5669,7 +5579,7 @@ __lpfc_sli_issue_iocb_s3(struct lpfc_hba
 		case CMD_GEN_REQUEST64_CX:
 			if (!(phba->sli.sli_flag & LPFC_MENLO_MAINT) ||
 				(piocb->iocb.un.genreq64.w5.hcsw.Rctl !=
-					FC_FCP_CMND) ||
+					FC_RCTL_DD_UNSOL_CMD) ||
 				(piocb->iocb.un.genreq64.w5.hcsw.Type !=
 					MENLO_TRANSPORT_TYPE))
 
@@ -5849,7 +5759,7 @@ static int
 lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		union lpfc_wqe *wqe)
 {
-	uint32_t payload_len = 0;
+	uint32_t xmit_len = 0, total_len = 0;
 	uint8_t ct = 0;
 	uint32_t fip;
 	uint32_t abort_tag;
@@ -5857,12 +5767,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 	uint8_t cmnd;
 	uint16_t xritag;
 	struct ulp_bde64 *bpl = NULL;
+	uint32_t els_id = ELS_ID_DEFAULT;
+	int numBdes, i;
+	struct ulp_bde64 bde;
 
-	fip = bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags);
+	fip = phba->hba_flag & HBA_FIP_SUPPORT;
 	/* The fcp commands will set command type */
 	if (iocbq->iocb_flag &  LPFC_IO_FCP)
 		command_type = FCP_COMMAND;
-	else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS))
+	else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK))
 		command_type = ELS_COMMAND_FIP;
 	else
 		command_type = ELS_COMMAND_NON_FIP;
@@ -5874,6 +5787,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 	wqe->words[7] = 0; /* The ct field has moved so reset */
 	/* words0-2 bpl convert bde */
 	if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
+		numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
+				sizeof(struct ulp_bde64);
 		bpl  = (struct ulp_bde64 *)
 			((struct lpfc_dmabuf *)iocbq->context3)->virt;
 		if (!bpl)
@@ -5886,9 +5801,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		 * can assign it to the sgl.
 		 */
 		wqe->generic.bde.tus.w  = le32_to_cpu(bpl->tus.w);
-		payload_len = wqe->generic.bde.tus.f.bdeSize;
+		xmit_len = wqe->generic.bde.tus.f.bdeSize;
+		total_len = 0;
+		for (i = 0; i < numBdes; i++) {
+			bde.tus.w  = le32_to_cpu(bpl[i].tus.w);
+			total_len += bde.tus.f.bdeSize;
+		}
 	} else
-		payload_len = iocbq->iocb.un.fcpi64.bdl.bdeSize;
+		xmit_len = iocbq->iocb.un.fcpi64.bdl.bdeSize;
 
 	iocbq->iocb.ulpIoTag = iocbq->iotag;
 	cmnd = iocbq->iocb.ulpCommand;
@@ -5902,7 +5822,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 				iocbq->iocb.ulpCommand);
 			return IOCB_ERROR;
 		}
-		wqe->els_req.payload_len = payload_len;
+		wqe->els_req.payload_len = xmit_len;
 		/* Els_reguest64 has a TMO */
 		bf_set(wqe_tmo, &wqe->els_req.wqe_com,
 			iocbq->iocb.ulpTimeout);
@@ -5923,7 +5843,22 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct);
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
 		/* CCP CCPE PV PRI in word10 were set in the memcpy */
+
+		if (command_type == ELS_COMMAND_FIP) {
+			els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK)
+					>> LPFC_FIP_ELS_ID_SHIFT);
+		}
+		bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id);
+
 	break;
+	case CMD_XMIT_SEQUENCE64_CX:
+		bf_set(lpfc_wqe_gen_context, &wqe->generic,
+					iocbq->iocb.un.ulpWord[3]);
+		wqe->generic.word3 = 0;
+		bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext);
+		/* The entire sequence is transmitted for this IOCB */
+		xmit_len = total_len;
+		cmnd = CMD_XMIT_SEQUENCE64_CR;
 	case CMD_XMIT_SEQUENCE64_CR:
 		/* word3 iocb=io_tag32 wqe=payload_offset */
 		/* payload offset used for multilpe outstanding
@@ -5933,7 +5868,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		/* word4 relative_offset memcpy */
 		/* word5 r_ctl/df_ctl memcpy */
 		bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
-		wqe->xmit_sequence.xmit_len = payload_len;
+		wqe->xmit_sequence.xmit_len = xmit_len;
+		command_type = OTHER_COMMAND;
 	break;
 	case CMD_XMIT_BCAST64_CN:
 		/* word3 iocb=iotag32 wqe=payload_len */
@@ -5962,7 +5898,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 	case CMD_FCP_IREAD64_CR:
 		/* FCP_CMD is always the 1st sgl entry */
 		wqe->fcp_iread.payload_len =
-			payload_len + sizeof(struct fcp_rsp);
+			xmit_len + sizeof(struct fcp_rsp);
 
 		/* word 4 (xfer length) should have been set on the memcpy */
 
@@ -5999,7 +5935,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		 * sgl[1] = rsp.
 		 *
 		 */
-		wqe->gen_req.command_len = payload_len;
+		wqe->gen_req.command_len = xmit_len;
 		/* Word4 parameter  copied in the memcpy */
 		/* Word5 [rctl, type, df_ctl, la] copied in memcpy */
 		/* word6 context tag copied in memcpy */
@@ -6066,6 +6002,38 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
 		command_type = OTHER_COMMAND;
 		xritag = 0;
 	break;
+	case CMD_XMIT_BLS_RSP64_CX:
+		/* As BLS ABTS-ACC WQE is very different from other WQEs,
+		 * we re-construct this WQE here based on information in
+		 * iocbq from scratch.
+		 */
+		memset(wqe, 0, sizeof(union lpfc_wqe));
+		/* OX_ID is invariable to who sent ABTS to CT exchange */
+		bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp,
+		       bf_get(lpfc_abts_oxid, &iocbq->iocb.un.bls_acc));
+		if (bf_get(lpfc_abts_orig, &iocbq->iocb.un.bls_acc) ==
+		    LPFC_ABTS_UNSOL_INT) {
+			/* ABTS sent by initiator to CT exchange, the
+			 * RX_ID field will be filled with the newly
+			 * allocated responder XRI.
+			 */
+			bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
+			       iocbq->sli4_xritag);
+		} else {
+			/* ABTS sent by responder to CT exchange, the
+			 * RX_ID field will be filled with the responder
+			 * RX_ID from ABTS.
+			 */
+			bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
+			       bf_get(lpfc_abts_rxid, &iocbq->iocb.un.bls_acc));
+		}
+		bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
+		bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
+		bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
+		       iocbq->iocb.ulpContext);
+		/* Overwrite the pre-set comnd type with OTHER_COMMAND */
+		command_type = OTHER_COMMAND;
+	break;
 	case CMD_XRI_ABORTED_CX:
 	case CMD_CREATE_XRI_CR: /* Do we expect to use this? */
 		/* words0-2 are all 0's no bde */
@@ -6120,11 +6088,10 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba
 	uint16_t xritag;
 	union lpfc_wqe wqe;
 	struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number];
-	uint32_t fcp_wqidx;
 
 	if (piocb->sli4_xritag == NO_XRI) {
 		if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
-			piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
+		    piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
 			sglq = NULL;
 		else {
 			sglq = __lpfc_sli_get_sglq(phba);
@@ -6155,8 +6122,17 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba
 		return IOCB_ERROR;
 
 	if (piocb->iocb_flag &  LPFC_IO_FCP) {
-		fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
-		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe))
+		/*
+		 * For FCP command IOCB, get a new WQ index to distribute
+		 * WQE across the WQsr. On the other hand, for abort IOCB,
+		 * it carries the same WQ index to the original command
+		 * IOCB.
+		 */
+		if ((piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
+		    (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN))
+			piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
+		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx],
+				     &wqe))
 			return IOCB_ERROR;
 	} else {
 		if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe))
@@ -6449,31 +6425,37 @@ lpfc_sli_setup(struct lpfc_hba *phba)
 			pring->iotag_max = 4096;
 			pring->lpfc_sli_rcv_async_status =
 				lpfc_sli_async_event_handler;
-			pring->num_mask = 4;
+			pring->num_mask = LPFC_MAX_RING_MASK;
 			pring->prt[0].profile = 0;	/* Mask 0 */
-			pring->prt[0].rctl = FC_ELS_REQ;
-			pring->prt[0].type = FC_ELS_DATA;
+			pring->prt[0].rctl = FC_RCTL_ELS_REQ;
+			pring->prt[0].type = FC_TYPE_ELS;
 			pring->prt[0].lpfc_sli_rcv_unsol_event =
 			    lpfc_els_unsol_event;
 			pring->prt[1].profile = 0;	/* Mask 1 */
-			pring->prt[1].rctl = FC_ELS_RSP;
-			pring->prt[1].type = FC_ELS_DATA;
+			pring->prt[1].rctl = FC_RCTL_ELS_REP;
+			pring->prt[1].type = FC_TYPE_ELS;
 			pring->prt[1].lpfc_sli_rcv_unsol_event =
 			    lpfc_els_unsol_event;
 			pring->prt[2].profile = 0;	/* Mask 2 */
 			/* NameServer Inquiry */
-			pring->prt[2].rctl = FC_UNSOL_CTL;
+			pring->prt[2].rctl = FC_RCTL_DD_UNSOL_CTL;
 			/* NameServer */
-			pring->prt[2].type = FC_COMMON_TRANSPORT_ULP;
+			pring->prt[2].type = FC_TYPE_CT;
 			pring->prt[2].lpfc_sli_rcv_unsol_event =
 			    lpfc_ct_unsol_event;
 			pring->prt[3].profile = 0;	/* Mask 3 */
 			/* NameServer response */
-			pring->prt[3].rctl = FC_SOL_CTL;
+			pring->prt[3].rctl = FC_RCTL_DD_SOL_CTL;
 			/* NameServer */
-			pring->prt[3].type = FC_COMMON_TRANSPORT_ULP;
+			pring->prt[3].type = FC_TYPE_CT;
 			pring->prt[3].lpfc_sli_rcv_unsol_event =
 			    lpfc_ct_unsol_event;
+			/* abort unsolicited sequence */
+			pring->prt[4].profile = 0;	/* Mask 4 */
+			pring->prt[4].rctl = FC_RCTL_BA_ABTS;
+			pring->prt[4].type = FC_TYPE_BLS;
+			pring->prt[4].lpfc_sli_rcv_unsol_event =
+			    lpfc_sli4_ct_abort_unsol_event;
 			break;
 		}
 		totiocbsize += (pring->numCiocb * pring->sizeCiocb) +
@@ -6976,8 +6958,18 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba
 		abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag;
 
 		spin_lock_irq(&phba->hbalock);
-		if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag)
-			abort_iocb = phba->sli.iocbq_lookup[abort_iotag];
+		if (phba->sli_rev < LPFC_SLI_REV4) {
+			if (abort_iotag != 0 &&
+				abort_iotag <= phba->sli.last_iotag)
+				abort_iocb =
+					phba->sli.iocbq_lookup[abort_iotag];
+		} else
+			/* For sli4 the abort_tag is the XRI,
+			 * so the abort routine puts the iotag  of the iocb
+			 * being aborted in the context field of the abort
+			 * IOCB.
+			 */
+			abort_iocb = phba->sli.iocbq_lookup[abort_context];
 
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_SLI,
 				"0327 Cannot abort els iocb %p "
@@ -6991,9 +6983,18 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba
 		 *  might have completed already. Do not free it again.
 		 */
 		if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-			spin_unlock_irq(&phba->hbalock);
-			lpfc_sli_release_iocbq(phba, cmdiocb);
-			return;
+			if (irsp->un.ulpWord[4] != IOERR_NO_XRI) {
+				spin_unlock_irq(&phba->hbalock);
+				lpfc_sli_release_iocbq(phba, cmdiocb);
+				return;
+			}
+			/* For SLI4 the ulpContext field for abort IOCB
+			 * holds the iotag of the IOCB being aborted so
+			 * the local abort_context needs to be reset to
+			 * match the aborted IOCBs ulpContext.
+			 */
+			if (abort_iocb && phba->sli_rev == LPFC_SLI_REV4)
+				abort_context = abort_iocb->iocb.ulpContext;
 		}
 		/*
 		 * make sure we have the right iocbq before taking it
@@ -7112,13 +7113,18 @@ lpfc_sli_issue_abort_iotag(struct lpfc_h
 	iabt = &abtsiocbp->iocb;
 	iabt->un.acxri.abortType = ABORT_TYPE_ABTS;
 	iabt->un.acxri.abortContextTag = icmd->ulpContext;
-	if (phba->sli_rev == LPFC_SLI_REV4)
+	if (phba->sli_rev == LPFC_SLI_REV4) {
 		iabt->un.acxri.abortIoTag = cmdiocb->sli4_xritag;
+		iabt->un.acxri.abortContextTag = cmdiocb->iotag;
+	}
 	else
 		iabt->un.acxri.abortIoTag = icmd->ulpIoTag;
 	iabt->ulpLe = 1;
 	iabt->ulpClass = icmd->ulpClass;
 
+	/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+	abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx;
+
 	if (phba->link_state >= LPFC_LINK_UP)
 		iabt->ulpCommand = CMD_ABORT_XRI_CN;
 	else
@@ -7322,6 +7328,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v
 		abtsiocb->iocb.ulpClass = cmd->ulpClass;
 		abtsiocb->vport = phba->pport;
 
+		/* ABTS WQE must go to the same WQ as the WQE to be aborted */
+		abtsiocb->fcp_wqidx = iocbq->fcp_wqidx;
+
 		if (lpfc_is_link_up(phba))
 			abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
 		else
@@ -7687,31 +7696,28 @@ static int
 lpfc_sli4_eratt_read(struct lpfc_hba *phba)
 {
 	uint32_t uerr_sta_hi, uerr_sta_lo;
-	uint32_t onlnreg0, onlnreg1;
 
 	/* For now, use the SLI4 device internal unrecoverable error
 	 * registers for error attention. This can be changed later.
 	 */
-	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-		uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
-		uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
-		if (uerr_sta_lo || uerr_sta_hi) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"1423 HBA Unrecoverable error: "
-					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-					"online0_reg=0x%x, online1_reg=0x%x\n",
-					uerr_sta_lo, uerr_sta_hi,
-					onlnreg0, onlnreg1);
-			phba->work_status[0] = uerr_sta_lo;
-			phba->work_status[1] = uerr_sta_hi;
-			/* Set the driver HA work bitmap */
-			phba->work_ha |= HA_ERATT;
-			/* Indicate polling handles this ERATT */
-			phba->hba_flag |= HBA_ERATT_HANDLED;
-			return 1;
-		}
+	uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
+	uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
+	if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
+	    (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"1423 HBA Unrecoverable error: "
+				"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+				"ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
+				uerr_sta_lo, uerr_sta_hi,
+				phba->sli4_hba.ue_mask_lo,
+				phba->sli4_hba.ue_mask_hi);
+		phba->work_status[0] = uerr_sta_lo;
+		phba->work_status[1] = uerr_sta_hi;
+		/* Set the driver HA work bitmap */
+		phba->work_ha |= HA_ERATT;
+		/* Indicate polling handles this ERATT */
+		phba->hba_flag |= HBA_ERATT_HANDLED;
+		return 1;
 	}
 	return 0;
 }
@@ -7834,7 +7840,7 @@ irqreturn_t
 lpfc_sli_sp_intr_handler(int irq, void *dev_id)
 {
 	struct lpfc_hba  *phba;
-	uint32_t ha_copy;
+	uint32_t ha_copy, hc_copy;
 	uint32_t work_ha_copy;
 	unsigned long status;
 	unsigned long iflag;
@@ -7892,8 +7898,13 @@ lpfc_sli_sp_intr_handler(int irq, void *
 		}
 
 		/* Clear up only attention source related to slow-path */
+		hc_copy = readl(phba->HCregaddr);
+		writel(hc_copy & ~(HC_MBINT_ENA | HC_R2INT_ENA |
+			HC_LAINT_ENA | HC_ERINT_ENA),
+			phba->HCregaddr);
 		writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
 			phba->HAregaddr);
+		writel(hc_copy, phba->HCregaddr);
 		readl(phba->HAregaddr); /* flush */
 		spin_unlock_irqrestore(&phba->hbalock, iflag);
 	} else
@@ -8049,7 +8060,7 @@ lpfc_sli_sp_intr_handler(int irq, void *
 							KERN_ERR,
 							LOG_MBOX | LOG_SLI,
 							"0350 rc should have"
-							"been MBX_BUSY");
+							"been MBX_BUSY\n");
 						if (rc != MBX_NOT_FINISHED)
 							goto send_current_mbox;
 					}
@@ -8078,7 +8089,7 @@ send_current_mbox:
 			if (rc != MBX_SUCCESS)
 				lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
 						LOG_SLI, "0349 rc should be "
-						"MBX_SUCCESS");
+						"MBX_SUCCESS\n");
 		}
 
 		spin_lock_irqsave(&phba->hbalock, iflag);
@@ -8203,6 +8214,7 @@ lpfc_sli_intr_handler(int irq, void *dev
 	struct lpfc_hba  *phba;
 	irqreturn_t sp_irq_rc, fp_irq_rc;
 	unsigned long status1, status2;
+	uint32_t hc_copy;
 
 	/*
 	 * Get the driver's phba structure from the dev_id and
@@ -8240,7 +8252,12 @@ lpfc_sli_intr_handler(int irq, void *dev
 	}
 
 	/* Clear attention sources except link and error attentions */
+	hc_copy = readl(phba->HCregaddr);
+	writel(hc_copy & ~(HC_MBINT_ENA | HC_R0INT_ENA | HC_R1INT_ENA
+		| HC_R2INT_ENA | HC_LAINT_ENA | HC_ERINT_ENA),
+		phba->HCregaddr);
 	writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
+	writel(hc_copy, phba->HCregaddr);
 	readl(phba->HAregaddr); /* flush */
 	spin_unlock(&phba->hbalock);
 
@@ -8351,8 +8368,6 @@ lpfc_sli4_iocb_param_transfer(struct lpf
 
 	memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
 	       sizeof(struct lpfc_iocbq) - offset);
-	memset(&pIocbIn->sli4_info, 0,
-	       sizeof(struct lpfc_sli4_rspiocb_info));
 	/* Map WCQE parameters into irspiocb parameters */
 	pIocbIn->iocb.ulpStatus = bf_get(lpfc_wcqe_c_status, wcqe);
 	if (pIocbOut->iocb_flag & LPFC_IO_FCP)
@@ -8364,16 +8379,49 @@ lpfc_sli4_iocb_param_transfer(struct lpf
 			pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
 	else
 		pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
-	/* Load in additional WCQE parameters */
-	pIocbIn->sli4_info.hw_status = bf_get(lpfc_wcqe_c_hw_status, wcqe);
-	pIocbIn->sli4_info.bfield = 0;
-	if (bf_get(lpfc_wcqe_c_xb, wcqe))
-		pIocbIn->sli4_info.bfield |= LPFC_XB;
-	if (bf_get(lpfc_wcqe_c_pv, wcqe)) {
-		pIocbIn->sli4_info.bfield |= LPFC_PV;
-		pIocbIn->sli4_info.priority =
-					bf_get(lpfc_wcqe_c_priority, wcqe);
+}
+
+/**
+ * lpfc_sli4_els_wcqe_to_rspiocbq - Get response iocbq from els wcqe
+ * @phba: Pointer to HBA context object.
+ * @wcqe: Pointer to work-queue completion queue entry.
+ *
+ * This routine handles an ELS work-queue completion event and construct
+ * a pseudo response ELS IODBQ from the SLI4 ELS WCQE for the common
+ * discovery engine to handle.
+ *
+ * Return: Pointer to the receive IOCBQ, NULL otherwise.
+ **/
+static struct lpfc_iocbq *
+lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
+			       struct lpfc_iocbq *irspiocbq)
+{
+	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
+	struct lpfc_iocbq *cmdiocbq;
+	struct lpfc_wcqe_complete *wcqe;
+	unsigned long iflags;
+
+	wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	pring->stats.iocb_event++;
+	/* Look up the ELS command IOCB and create pseudo response IOCB */
+	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
+				bf_get(lpfc_wcqe_c_request_tag, wcqe));
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+
+	if (unlikely(!cmdiocbq)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+				"0386 ELS complete with no corresponding "
+				"cmdiocb: iotag (%d)\n",
+				bf_get(lpfc_wcqe_c_request_tag, wcqe));
+		lpfc_sli_release_iocbq(phba, irspiocbq);
+		return NULL;
 	}
+
+	/* Fake the irspiocbq and copy necessary response information */
+	lpfc_sli4_iocb_param_transfer(irspiocbq, cmdiocbq, wcqe);
+
+	return irspiocbq;
 }
 
 /**
@@ -8566,45 +8614,26 @@ static bool
 lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba,
 			     struct lpfc_wcqe_complete *wcqe)
 {
-	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
-	struct lpfc_iocbq *cmdiocbq;
 	struct lpfc_iocbq *irspiocbq;
 	unsigned long iflags;
-	bool workposted = false;
-
-	spin_lock_irqsave(&phba->hbalock, iflags);
-	pring->stats.iocb_event++;
-	/* Look up the ELS command IOCB and create pseudo response IOCB */
-	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
-				bf_get(lpfc_wcqe_c_request_tag, wcqe));
-	spin_unlock_irqrestore(&phba->hbalock, iflags);
-
-	if (unlikely(!cmdiocbq)) {
-		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-				"0386 ELS complete with no corresponding "
-				"cmdiocb: iotag (%d)\n",
-				bf_get(lpfc_wcqe_c_request_tag, wcqe));
-		return workposted;
-	}
 
-	/* Fake the irspiocbq and copy necessary response information */
+	/* Get an irspiocbq for later ELS response processing use */
 	irspiocbq = lpfc_sli_get_iocbq(phba);
 	if (!irspiocbq) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"0387 Failed to allocate an iocbq\n");
-		return workposted;
+		return false;
 	}
-	lpfc_sli4_iocb_param_transfer(irspiocbq, cmdiocbq, wcqe);
 
-	/* Add the irspiocb to the response IOCB work list */
+	/* Save off the slow-path queue event for work thread to process */
+	memcpy(&irspiocbq->cq_event.cqe.wcqe_cmpl, wcqe, sizeof(*wcqe));
 	spin_lock_irqsave(&phba->hbalock, iflags);
-	list_add_tail(&irspiocbq->list, &phba->sli4_hba.sp_rspiocb_work_queue);
-	/* Indicate ELS ring attention */
-	phba->work_ha |= (HA_R0ATT << (4*LPFC_ELS_RING));
+	list_add_tail(&irspiocbq->cq_event.list,
+		      &phba->sli4_hba.sp_queue_event);
+	phba->hba_flag |= HBA_SP_QUEUE_EVT;
 	spin_unlock_irqrestore(&phba->hbalock, iflags);
-	workposted = true;
 
-	return workposted;
+	return true;
 }
 
 /**
@@ -8690,52 +8719,6 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struc
 }
 
 /**
- * lpfc_sli4_sp_handle_wcqe - Process a work-queue completion queue entry
- * @phba: Pointer to HBA context object.
- * @cq: Pointer to the completion queue.
- * @wcqe: Pointer to a completion queue entry.
- *
- * This routine process a slow-path work-queue completion queue entry.
- *
- * Return: true if work posted to worker thread, otherwise false.
- **/
-static bool
-lpfc_sli4_sp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
-			 struct lpfc_cqe *cqe)
-{
-	struct lpfc_wcqe_complete wcqe;
-	bool workposted = false;
-
-	/* Copy the work queue CQE and convert endian order if needed */
-	lpfc_sli_pcimem_bcopy(cqe, &wcqe, sizeof(struct lpfc_cqe));
-
-	/* Check and process for different type of WCQE and dispatch */
-	switch (bf_get(lpfc_wcqe_c_code, &wcqe)) {
-	case CQE_CODE_COMPL_WQE:
-		/* Process the WQ complete event */
-		workposted = lpfc_sli4_sp_handle_els_wcqe(phba,
-					(struct lpfc_wcqe_complete *)&wcqe);
-		break;
-	case CQE_CODE_RELEASE_WQE:
-		/* Process the WQ release event */
-		lpfc_sli4_sp_handle_rel_wcqe(phba,
-					(struct lpfc_wcqe_release *)&wcqe);
-		break;
-	case CQE_CODE_XRI_ABORTED:
-		/* Process the WQ XRI abort event */
-		workposted = lpfc_sli4_sp_handle_abort_xri_wcqe(phba, cq,
-					(struct sli4_wcqe_xri_aborted *)&wcqe);
-		break;
-	default:
-		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-				"0388 Not a valid WCQE code: x%x\n",
-				bf_get(lpfc_wcqe_c_code, &wcqe));
-		break;
-	}
-	return workposted;
-}
-
-/**
  * lpfc_sli4_sp_handle_rcqe - Process a receive-queue completion queue entry
  * @phba: Pointer to HBA context object.
  * @rcqe: Pointer to receive-queue completion queue entry.
@@ -8745,9 +8728,8 @@ lpfc_sli4_sp_handle_wcqe(struct lpfc_hba
  * Return: true if work posted to worker thread, otherwise false.
  **/
 static bool
-lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_cqe *cqe)
+lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
 {
-	struct lpfc_rcqe rcqe;
 	bool workposted = false;
 	struct lpfc_queue *hrq = phba->sli4_hba.hdr_rq;
 	struct lpfc_queue *drq = phba->sli4_hba.dat_rq;
@@ -8755,31 +8737,28 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba
 	uint32_t status;
 	unsigned long iflags;
 
-	/* Copy the receive queue CQE and convert endian order if needed */
-	lpfc_sli_pcimem_bcopy(cqe, &rcqe, sizeof(struct lpfc_rcqe));
-	lpfc_sli4_rq_release(hrq, drq);
-	if (bf_get(lpfc_rcqe_code, &rcqe) != CQE_CODE_RECEIVE)
-		goto out;
-	if (bf_get(lpfc_rcqe_rq_id, &rcqe) != hrq->queue_id)
+	if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id)
 		goto out;
 
-	status = bf_get(lpfc_rcqe_status, &rcqe);
+	status = bf_get(lpfc_rcqe_status, rcqe);
 	switch (status) {
 	case FC_STATUS_RQ_BUF_LEN_EXCEEDED:
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2537 Receive Frame Truncated!!\n");
 	case FC_STATUS_RQ_SUCCESS:
+		lpfc_sli4_rq_release(hrq, drq);
 		spin_lock_irqsave(&phba->hbalock, iflags);
 		dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list);
 		if (!dma_buf) {
 			spin_unlock_irqrestore(&phba->hbalock, iflags);
 			goto out;
 		}
-		memcpy(&dma_buf->rcqe, &rcqe, sizeof(rcqe));
+		memcpy(&dma_buf->cq_event.cqe.rcqe_cmpl, rcqe, sizeof(*rcqe));
 		/* save off the frame for the word thread to process */
-		list_add_tail(&dma_buf->dbuf.list, &phba->rb_pend_list);
+		list_add_tail(&dma_buf->cq_event.list,
+			      &phba->sli4_hba.sp_queue_event);
 		/* Frame received */
-		phba->hba_flag |= HBA_RECEIVE_BUFFER;
+		phba->hba_flag |= HBA_SP_QUEUE_EVT;
 		spin_unlock_irqrestore(&phba->hbalock, iflags);
 		workposted = true;
 		break;
@@ -8794,7 +8773,58 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba
 	}
 out:
 	return workposted;
+}
+
+/**
+ * lpfc_sli4_sp_handle_cqe - Process a slow path completion queue entry
+ * @phba: Pointer to HBA context object.
+ * @cq: Pointer to the completion queue.
+ * @wcqe: Pointer to a completion queue entry.
+ *
+ * This routine process a slow-path work-queue or recieve queue completion queue
+ * entry.
+ *
+ * Return: true if work posted to worker thread, otherwise false.
+ **/
+static bool
+lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
+			 struct lpfc_cqe *cqe)
+{
+	struct lpfc_cqe cqevt;
+	bool workposted = false;
+
+	/* Copy the work queue CQE and convert endian order if needed */
+	lpfc_sli_pcimem_bcopy(cqe, &cqevt, sizeof(struct lpfc_cqe));
 
+	/* Check and process for different type of WCQE and dispatch */
+	switch (bf_get(lpfc_cqe_code, &cqevt)) {
+	case CQE_CODE_COMPL_WQE:
+		/* Process the WQ/RQ complete event */
+		workposted = lpfc_sli4_sp_handle_els_wcqe(phba,
+				(struct lpfc_wcqe_complete *)&cqevt);
+		break;
+	case CQE_CODE_RELEASE_WQE:
+		/* Process the WQ release event */
+		lpfc_sli4_sp_handle_rel_wcqe(phba,
+				(struct lpfc_wcqe_release *)&cqevt);
+		break;
+	case CQE_CODE_XRI_ABORTED:
+		/* Process the WQ XRI abort event */
+		workposted = lpfc_sli4_sp_handle_abort_xri_wcqe(phba, cq,
+				(struct sli4_wcqe_xri_aborted *)&cqevt);
+		break;
+	case CQE_CODE_RECEIVE:
+		/* Process the RQ event */
+		workposted = lpfc_sli4_sp_handle_rcqe(phba,
+				(struct lpfc_rcqe *)&cqevt);
+		break;
+	default:
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"0388 Not a valid WCQE code: x%x\n",
+				bf_get(lpfc_cqe_code, &cqevt));
+		break;
+	}
+	return workposted;
 }
 
 /**
@@ -8858,14 +8888,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba
 		break;
 	case LPFC_WCQ:
 		while ((cqe = lpfc_sli4_cq_get(cq))) {
-			workposted |= lpfc_sli4_sp_handle_wcqe(phba, cq, cqe);
-			if (!(++ecount % LPFC_GET_QE_REL_INT))
-				lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
-		}
-		break;
-	case LPFC_RCQ:
-		while ((cqe = lpfc_sli4_cq_get(cq))) {
-			workposted |= lpfc_sli4_sp_handle_rcqe(phba, cqe);
+			workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, cqe);
 			if (!(++ecount % LPFC_GET_QE_REL_INT))
 				lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
 		}
@@ -10427,8 +10450,7 @@ lpfc_sli4_next_xritag(struct lpfc_hba *p
 		return xritag;
 	}
 	spin_unlock_irq(&phba->hbalock);
-
-	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+	lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
 			"2004 Failed to allocate XRI.last XRITAG is %d"
 			" Max XRI is %d, Used XRI is %d\n",
 			phba->sli4_hba.next_xri,
@@ -10492,15 +10514,7 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
-
 	/* Get the first SGE entry from the non-embedded DMA memory */
-	if (unlikely(!mbox->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2525 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mbox);
-		return -ENOMEM;
-	}
 	viraddr = mbox->sge_array->addr[0];
 
 	/* Set up the SGL pages in the non-embedded DMA pages */
@@ -10524,8 +10538,7 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba
 		sgl_pg_pairs++;
 	}
 	bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start);
-	pg_pairs = (pg_pairs > 0) ? (pg_pairs - 1) : pg_pairs;
-	bf_set(lpfc_post_sgl_pages_xricnt, sgl, pg_pairs);
+	bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt);
 	/* Perform endian conversion if necessary */
 	sgl->word0 = cpu_to_le32(sgl->word0);
 
@@ -10607,15 +10620,7 @@ lpfc_sli4_post_scsi_sgl_block(struct lpf
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
-
 	/* Get the first SGE entry from the non-embedded DMA memory */
-	if (unlikely(!mbox->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2565 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mbox);
-		return -ENOMEM;
-	}
 	viraddr = mbox->sge_array->addr[0];
 
 	/* Set up the SGL pages in the non-embedded DMA pages */
@@ -10802,6 +10807,105 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *
 }
 
 /**
+ * lpfc_update_rcv_time_stamp - Update vport's rcv seq time stamp
+ * @vport: The vport to work on.
+ *
+ * This function updates the receive sequence time stamp for this vport. The
+ * receive sequence time stamp indicates the time that the last frame of the
+ * the sequence that has been idle for the longest amount of time was received.
+ * the driver uses this time stamp to indicate if any received sequences have
+ * timed out.
+ **/
+void
+lpfc_update_rcv_time_stamp(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf;
+	struct hbq_dmabuf *dmabuf = NULL;
+
+	/* get the oldest sequence on the rcv list */
+	h_buf = list_get_first(&vport->rcv_buffer_list,
+			       struct lpfc_dmabuf, list);
+	if (!h_buf)
+		return;
+	dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+	vport->rcv_buffer_time_stamp = dmabuf->time_stamp;
+}
+
+/**
+ * lpfc_cleanup_rcv_buffers - Cleans up all outstanding receive sequences.
+ * @vport: The vport that the received sequences were sent to.
+ *
+ * This function cleans up all outstanding received sequences. This is called
+ * by the driver when a link event or user action invalidates all the received
+ * sequences.
+ **/
+void
+lpfc_cleanup_rcv_buffers(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf, *hnext;
+	struct lpfc_dmabuf *d_buf, *dnext;
+	struct hbq_dmabuf *dmabuf = NULL;
+
+	/* start with the oldest sequence on the rcv list */
+	list_for_each_entry_safe(h_buf, hnext, &vport->rcv_buffer_list, list) {
+		dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		list_del_init(&dmabuf->hbuf.list);
+		list_for_each_entry_safe(d_buf, dnext,
+					 &dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		lpfc_in_buf_free(vport->phba, &dmabuf->dbuf);
+	}
+}
+
+/**
+ * lpfc_rcv_seq_check_edtov - Cleans up timed out receive sequences.
+ * @vport: The vport that the received sequences were sent to.
+ *
+ * This function determines whether any received sequences have timed out by
+ * first checking the vport's rcv_buffer_time_stamp. If this time_stamp
+ * indicates that there is at least one timed out sequence this routine will
+ * go through the received sequences one at a time from most inactive to most
+ * active to determine which ones need to be cleaned up. Once it has determined
+ * that a sequence needs to be cleaned up it will simply free up the resources
+ * without sending an abort.
+ **/
+void
+lpfc_rcv_seq_check_edtov(struct lpfc_vport *vport)
+{
+	struct lpfc_dmabuf *h_buf, *hnext;
+	struct lpfc_dmabuf *d_buf, *dnext;
+	struct hbq_dmabuf *dmabuf = NULL;
+	unsigned long timeout;
+	int abort_count = 0;
+
+	timeout = (msecs_to_jiffies(vport->phba->fc_edtov) +
+		   vport->rcv_buffer_time_stamp);
+	if (list_empty(&vport->rcv_buffer_list) ||
+	    time_before(jiffies, timeout))
+		return;
+	/* start with the oldest sequence on the rcv list */
+	list_for_each_entry_safe(h_buf, hnext, &vport->rcv_buffer_list, list) {
+		dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		timeout = (msecs_to_jiffies(vport->phba->fc_edtov) +
+			   dmabuf->time_stamp);
+		if (time_before(jiffies, timeout))
+			break;
+		abort_count++;
+		list_del_init(&dmabuf->hbuf.list);
+		list_for_each_entry_safe(d_buf, dnext,
+					 &dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		lpfc_in_buf_free(vport->phba, &dmabuf->dbuf);
+	}
+	if (abort_count)
+		lpfc_update_rcv_time_stamp(vport);
+}
+
+/**
  * lpfc_fc_frame_add - Adds a frame to the vport's list of received sequences
  * @dmabuf: pointer to a dmabuf that describes the hdr and data of the FC frame
  *
@@ -10823,6 +10927,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 	struct hbq_dmabuf *seq_dmabuf = NULL;
 	struct hbq_dmabuf *temp_dmabuf = NULL;
 
+	INIT_LIST_HEAD(&dmabuf->dbuf.list);
+	dmabuf->time_stamp = jiffies;
 	new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
 	/* Use the hdr_buf to find the sequence that this frame belongs to */
 	list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
@@ -10841,13 +10947,27 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 		 * Queue the buffer on the vport's rcv_buffer_list.
 		 */
 		list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list);
+		lpfc_update_rcv_time_stamp(vport);
 		return dmabuf;
 	}
 	temp_hdr = seq_dmabuf->hbuf.virt;
-	if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) {
-		list_add(&seq_dmabuf->dbuf.list, &dmabuf->dbuf.list);
+	if (be16_to_cpu(new_hdr->fh_seq_cnt) <
+		be16_to_cpu(temp_hdr->fh_seq_cnt)) {
+		list_del_init(&seq_dmabuf->hbuf.list);
+		list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list);
+		list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list);
+		lpfc_update_rcv_time_stamp(vport);
 		return dmabuf;
 	}
+	/* move this sequence to the tail to indicate a young sequence */
+	list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list);
+	seq_dmabuf->time_stamp = jiffies;
+	lpfc_update_rcv_time_stamp(vport);
+	if (list_empty(&seq_dmabuf->dbuf.list)) {
+		temp_hdr = dmabuf->hbuf.virt;
+		list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list);
+		return seq_dmabuf;
+	}
 	/* find the correct place in the sequence to insert this frame */
 	list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) {
 		temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
@@ -10856,7 +10976,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 		 * If the frame's sequence count is greater than the frame on
 		 * the list then insert the frame right after this frame
 		 */
-		if (new_hdr->fh_seq_cnt > temp_hdr->fh_seq_cnt) {
+		if (be16_to_cpu(new_hdr->fh_seq_cnt) >
+			be16_to_cpu(temp_hdr->fh_seq_cnt)) {
 			list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list);
 			return seq_dmabuf;
 		}
@@ -10865,6 +10986,210 @@ lpfc_fc_frame_add(struct lpfc_vport *vpo
 }
 
 /**
+ * lpfc_sli4_abort_partial_seq - Abort partially assembled unsol sequence
+ * @vport: pointer to a vitural port
+ * @dmabuf: pointer to a dmabuf that describes the FC sequence
+ *
+ * This function tries to abort from the partially assembed sequence, described
+ * by the information from basic abbort @dmabuf. It checks to see whether such
+ * partially assembled sequence held by the driver. If so, it shall free up all
+ * the frames from the partially assembled sequence.
+ *
+ * Return
+ * true  -- if there is matching partially assembled sequence present and all
+ *          the frames freed with the sequence;
+ * false -- if there is no matching partially assembled sequence present so
+ *          nothing got aborted in the lower layer driver
+ **/
+static bool
+lpfc_sli4_abort_partial_seq(struct lpfc_vport *vport,
+			    struct hbq_dmabuf *dmabuf)
+{
+	struct fc_frame_header *new_hdr;
+	struct fc_frame_header *temp_hdr;
+	struct lpfc_dmabuf *d_buf, *n_buf, *h_buf;
+	struct hbq_dmabuf *seq_dmabuf = NULL;
+
+	/* Use the hdr_buf to find the sequence that matches this frame */
+	INIT_LIST_HEAD(&dmabuf->dbuf.list);
+	INIT_LIST_HEAD(&dmabuf->hbuf.list);
+	new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+	list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) {
+		temp_hdr = (struct fc_frame_header *)h_buf->virt;
+		if ((temp_hdr->fh_seq_id != new_hdr->fh_seq_id) ||
+		    (temp_hdr->fh_ox_id != new_hdr->fh_ox_id) ||
+		    (memcmp(&temp_hdr->fh_s_id, &new_hdr->fh_s_id, 3)))
+			continue;
+		/* found a pending sequence that matches this frame */
+		seq_dmabuf = container_of(h_buf, struct hbq_dmabuf, hbuf);
+		break;
+	}
+
+	/* Free up all the frames from the partially assembled sequence */
+	if (seq_dmabuf) {
+		list_for_each_entry_safe(d_buf, n_buf,
+					 &seq_dmabuf->dbuf.list, list) {
+			list_del_init(&d_buf->list);
+			lpfc_in_buf_free(vport->phba, d_buf);
+		}
+		return true;
+	}
+	return false;
+}
+
+/**
+ * lpfc_sli4_seq_abort_acc_cmpl - Accept seq abort iocb complete handler
+ * @phba: Pointer to HBA context object.
+ * @cmd_iocbq: pointer to the command iocbq structure.
+ * @rsp_iocbq: pointer to the response iocbq structure.
+ *
+ * This function handles the sequence abort accept iocb command complete
+ * event. It properly releases the memory allocated to the sequence abort
+ * accept iocb.
+ **/
+static void
+lpfc_sli4_seq_abort_acc_cmpl(struct lpfc_hba *phba,
+			     struct lpfc_iocbq *cmd_iocbq,
+			     struct lpfc_iocbq *rsp_iocbq)
+{
+	if (cmd_iocbq)
+		lpfc_sli_release_iocbq(phba, cmd_iocbq);
+}
+
+/**
+ * lpfc_sli4_seq_abort_acc - Accept sequence abort
+ * @phba: Pointer to HBA context object.
+ * @fc_hdr: pointer to a FC frame header.
+ *
+ * This function sends a basic accept to a previous unsol sequence abort
+ * event after aborting the sequence handling.
+ **/
+static void
+lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
+			struct fc_frame_header *fc_hdr)
+{
+	struct lpfc_iocbq *ctiocb = NULL;
+	struct lpfc_nodelist *ndlp;
+	uint16_t oxid, rxid;
+	uint32_t sid, fctl;
+	IOCB_t *icmd;
+
+	if (!lpfc_is_link_up(phba))
+		return;
+
+	sid = sli4_sid_from_fc_hdr(fc_hdr);
+	oxid = be16_to_cpu(fc_hdr->fh_ox_id);
+	rxid = be16_to_cpu(fc_hdr->fh_rx_id);
+
+	ndlp = lpfc_findnode_did(phba->pport, sid);
+	if (!ndlp) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
+				"1268 Find ndlp returned NULL for oxid:x%x "
+				"SID:x%x\n", oxid, sid);
+		return;
+	}
+
+	/* Allocate buffer for acc iocb */
+	ctiocb = lpfc_sli_get_iocbq(phba);
+	if (!ctiocb)
+		return;
+
+	/* Extract the F_CTL field from FC_HDR */
+	fctl = sli4_fctl_from_fc_hdr(fc_hdr);
+
+	icmd = &ctiocb->iocb;
+	icmd->un.xseq64.bdl.bdeSize = 0;
+	icmd->un.xseq64.bdl.ulpIoTag32 = 0;
+	icmd->un.xseq64.w5.hcsw.Dfctl = 0;
+	icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC;
+	icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS;
+
+	/* Fill in the rest of iocb fields */
+	icmd->ulpCommand = CMD_XMIT_BLS_RSP64_CX;
+	icmd->ulpBdeCount = 0;
+	icmd->ulpLe = 1;
+	icmd->ulpClass = CLASS3;
+	icmd->ulpContext = ndlp->nlp_rpi;
+
+	ctiocb->iocb_cmpl = NULL;
+	ctiocb->vport = phba->pport;
+	ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl;
+
+	if (fctl & FC_FC_EX_CTX) {
+		/* ABTS sent by responder to CT exchange, construction
+		 * of BA_ACC will use OX_ID from ABTS for the XRI_TAG
+		 * field and RX_ID from ABTS for RX_ID field.
+		 */
+		bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_RSP);
+		bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, rxid);
+		ctiocb->sli4_xritag = oxid;
+	} else {
+		/* ABTS sent by initiator to CT exchange, construction
+		 * of BA_ACC will need to allocate a new XRI as for the
+		 * XRI_TAG and RX_ID fields.
+		 */
+		bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_INT);
+		bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, NO_XRI);
+		ctiocb->sli4_xritag = NO_XRI;
+	}
+	bf_set(lpfc_abts_oxid, &icmd->un.bls_acc, oxid);
+
+	/* Xmit CT abts accept on exchange <xid> */
+	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+			"1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n",
+			CMD_XMIT_BLS_RSP64_CX, phba->link_state);
+	lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, ctiocb, 0);
+}
+
+/**
+ * lpfc_sli4_handle_unsol_abort - Handle sli-4 unsolicited abort event
+ * @vport: Pointer to the vport on which this sequence was received
+ * @dmabuf: pointer to a dmabuf that describes the FC sequence
+ *
+ * This function handles an SLI-4 unsolicited abort event. If the unsolicited
+ * receive sequence is only partially assembed by the driver, it shall abort
+ * the partially assembled frames for the sequence. Otherwise, if the
+ * unsolicited receive sequence has been completely assembled and passed to
+ * the Upper Layer Protocol (UPL), it then mark the per oxid status for the
+ * unsolicited sequence has been aborted. After that, it will issue a basic
+ * accept to accept the abort.
+ **/
+void
+lpfc_sli4_handle_unsol_abort(struct lpfc_vport *vport,
+			     struct hbq_dmabuf *dmabuf)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct fc_frame_header fc_hdr;
+	uint32_t fctl;
+	bool abts_par;
+
+	/* Make a copy of fc_hdr before the dmabuf being released */
+	memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header));
+	fctl = sli4_fctl_from_fc_hdr(&fc_hdr);
+
+	if (fctl & FC_FC_EX_CTX) {
+		/*
+		 * ABTS sent by responder to exchange, just free the buffer
+		 */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+	} else {
+		/*
+		 * ABTS sent by initiator to exchange, need to do cleanup
+		 */
+		/* Try to abort partially assembled seq */
+		abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf);
+
+		/* Send abort to ULP if partially seq abort failed */
+		if (abts_par == false)
+			lpfc_sli4_send_seq_to_ulp(vport, dmabuf);
+		else
+			lpfc_in_buf_free(phba, &dmabuf->dbuf);
+	}
+	/* Send basic accept (BA_ACC) to the abort requester */
+	lpfc_sli4_seq_abort_acc(phba, &fc_hdr);
+}
+
+/**
  * lpfc_seq_complete - Indicates if a sequence is complete
  * @dmabuf: pointer to a dmabuf that describes the FC sequence
  *
@@ -10899,7 +11224,7 @@ lpfc_seq_complete(struct hbq_dmabuf *dma
 		seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf);
 		hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
 		/* If there is a hole in the sequence count then fail. */
-		if (++seq_count != hdr->fh_seq_cnt)
+		if (++seq_count != be16_to_cpu(hdr->fh_seq_cnt))
 			return 0;
 		fctl = (hdr->fh_f_ctl[0] << 16 |
 			hdr->fh_f_ctl[1] << 8 |
@@ -10931,14 +11256,14 @@ lpfc_prep_seq(struct lpfc_vport *vport,
 	struct lpfc_iocbq *first_iocbq, *iocbq;
 	struct fc_frame_header *fc_hdr;
 	uint32_t sid;
+	struct ulp_bde64 *pbde;
 
 	fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
 	/* remove from receive buffer list */
 	list_del_init(&seq_dmabuf->hbuf.list);
+	lpfc_update_rcv_time_stamp(vport);
 	/* get the Remote Port's SID */
-	sid = (fc_hdr->fh_s_id[0] << 16 |
-	       fc_hdr->fh_s_id[1] << 8 |
-	       fc_hdr->fh_s_id[2]);
+	sid = sli4_sid_from_fc_hdr(fc_hdr);
 	/* Get an iocbq struct to fill in. */
 	first_iocbq = lpfc_sli_get_iocbq(vport->phba);
 	if (first_iocbq) {
@@ -10957,7 +11282,8 @@ lpfc_prep_seq(struct lpfc_vport *vport,
 							LPFC_DATA_BUF_SIZE;
 		first_iocbq->iocb.un.rcvels.remoteID = sid;
 		first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 	}
 	iocbq = first_iocbq;
 	/*
@@ -10972,10 +11298,12 @@ lpfc_prep_seq(struct lpfc_vport *vport,
 		if (!iocbq->context3) {
 			iocbq->context3 = d_buf;
 			iocbq->iocb.ulpBdeCount++;
-			iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize =
-							LPFC_DATA_BUF_SIZE;
+			pbde = (struct ulp_bde64 *)
+					&iocbq->iocb.unsli3.sli3Words[4];
+			pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE;
 			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 		} else {
 			iocbq = lpfc_sli_get_iocbq(vport->phba);
 			if (!iocbq) {
@@ -10994,7 +11322,8 @@ lpfc_prep_seq(struct lpfc_vport *vport,
 			iocbq->iocb.un.cont64[0].tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
 			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
-				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
+				bf_get(lpfc_rcqe_length,
+				       &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
 			iocbq->iocb.un.rcvels.remoteID = sid;
 			list_add_tail(&iocbq->list, &first_iocbq->list);
 		}
@@ -11002,6 +11331,43 @@ lpfc_prep_seq(struct lpfc_vport *vport,
 	return first_iocbq;
 }
 
+static void
+lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport,
+			  struct hbq_dmabuf *seq_dmabuf)
+{
+	struct fc_frame_header *fc_hdr;
+	struct lpfc_iocbq *iocbq, *curr_iocb, *next_iocb;
+	struct lpfc_hba *phba = vport->phba;
+
+	fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
+	iocbq = lpfc_prep_seq(vport, seq_dmabuf);
+	if (!iocbq) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"2707 Ring %d handler: Failed to allocate "
+				"iocb Rctl x%x Type x%x received\n",
+				LPFC_ELS_RING,
+				fc_hdr->fh_r_ctl, fc_hdr->fh_type);
+		return;
+	}
+	if (!lpfc_complete_unsol_iocb(phba,
+				      &phba->sli.ring[LPFC_ELS_RING],
+				      iocbq, fc_hdr->fh_r_ctl,
+				      fc_hdr->fh_type))
+		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+				"2540 Ring %d handler: unexpected Rctl "
+				"x%x Type x%x received\n",
+				LPFC_ELS_RING,
+				fc_hdr->fh_r_ctl, fc_hdr->fh_type);
+
+	/* Free iocb created in lpfc_prep_seq */
+	list_for_each_entry_safe(curr_iocb, next_iocb,
+		&iocbq->list, list) {
+		list_del_init(&curr_iocb->list);
+		lpfc_sli_release_iocbq(phba, curr_iocb);
+	}
+	lpfc_sli_release_iocbq(phba, iocbq);
+}
+
 /**
  * lpfc_sli4_handle_received_buffer - Handle received buffers from firmware
  * @phba: Pointer to HBA context object.
@@ -11014,67 +11380,48 @@ lpfc_prep_seq(struct lpfc_vport *vport,
  * Worker thread calls lpfc_sli4_handle_received_buffer, which will call the
  * appropriate receive function when the final frame in a sequence is received.
  **/
-int
-lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba)
+void
+lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
+				 struct hbq_dmabuf *dmabuf)
 {
-	LIST_HEAD(cmplq);
-	struct hbq_dmabuf *dmabuf, *seq_dmabuf;
+	struct hbq_dmabuf *seq_dmabuf;
 	struct fc_frame_header *fc_hdr;
 	struct lpfc_vport *vport;
 	uint32_t fcfi;
-	struct lpfc_iocbq *iocbq;
-
-	/* Clear hba flag and get all received buffers into the cmplq */
-	spin_lock_irq(&phba->hbalock);
-	phba->hba_flag &= ~HBA_RECEIVE_BUFFER;
-	list_splice_init(&phba->rb_pend_list, &cmplq);
-	spin_unlock_irq(&phba->hbalock);
 
 	/* Process each received buffer */
-	while ((dmabuf = lpfc_sli_hbqbuf_get(&cmplq)) != NULL) {
-		fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
-		/* check to see if this a valid type of frame */
-		if (lpfc_fc_frame_check(phba, fc_hdr)) {
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->rcqe);
-		vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
-		if (!vport) {
-			/* throw out the frame */
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		/* Link this frame */
-		seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf);
-		if (!seq_dmabuf) {
-			/* unable to add frame to vport - throw it out */
-			lpfc_in_buf_free(phba, &dmabuf->dbuf);
-			continue;
-		}
-		/* If not last frame in sequence continue processing frames. */
-		if (!lpfc_seq_complete(seq_dmabuf)) {
-			/*
-			 * When saving off frames post a new one and mark this
-			 * frame to be freed when it is finished.
-			 **/
-			lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1);
-			dmabuf->tag = -1;
-			continue;
-		}
-		fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
-		iocbq = lpfc_prep_seq(vport, seq_dmabuf);
-		if (!lpfc_complete_unsol_iocb(phba,
-					      &phba->sli.ring[LPFC_ELS_RING],
-					      iocbq, fc_hdr->fh_r_ctl,
-					      fc_hdr->fh_type))
-			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-					"2540 Ring %d handler: unexpected Rctl "
-					"x%x Type x%x received\n",
-					LPFC_ELS_RING,
-					fc_hdr->fh_r_ctl, fc_hdr->fh_type);
-	};
-	return 0;
+	fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
+	/* check to see if this a valid type of frame */
+	if (lpfc_fc_frame_check(phba, fc_hdr)) {
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl);
+	vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
+	if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
+		/* throw out the frame */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	/* Handle the basic abort sequence (BA_ABTS) event */
+	if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
+		lpfc_sli4_handle_unsol_abort(vport, dmabuf);
+		return;
+	}
+
+	/* Link this frame */
+	seq_dmabuf = lpfc_fc_frame_add(vport, dmabuf);
+	if (!seq_dmabuf) {
+		/* unable to add frame to vport - throw it out */
+		lpfc_in_buf_free(phba, &dmabuf->dbuf);
+		return;
+	}
+	/* If not last frame in sequence continue processing frames. */
+	if (!lpfc_seq_complete(seq_dmabuf))
+		return;
+
+	/* Send the complete sequence to the upper layer protocol */
+	lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf);
 }
 
 /**
@@ -11091,7 +11438,7 @@ lpfc_sli4_handle_received_buffer(struct
  * sequential.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  *      EIO - The mailbox failed to complete successfully.
  * 	When this error occurs, the driver is not guaranteed
  *	to have any rpi regions posted to the device and
@@ -11129,7 +11476,7 @@ lpfc_sli4_post_all_rpi_hdrs(struct lpfc_
  * maps up to 64 rpi context regions.
  *
  * Return codes
- * 	0 - sucessful
+ * 	0 - successful
  * 	ENOMEM - No available memory
  *      EIO - The mailbox failed to complete successfully.
  **/
@@ -11191,7 +11538,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *
  * PAGE_SIZE modulo 64 rpi context headers.
  *
  * Returns
- * 	A nonzero rpi defined as rpi_base <= rpi < max_rpi if sucessful
+ * 	A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful
  * 	LPFC_RPI_ALLOC_ERROR if no rpis are available.
  **/
 int
@@ -11334,6 +11681,7 @@ lpfc_sli4_init_vpi(struct lpfc_hba *phba
 {
 	LPFC_MBOXQ_t *mboxq;
 	int rc = 0;
+	int retval = MBX_SUCCESS;
 	uint32_t mbox_tmo;
 
 	if (vpi == 0)
@@ -11344,16 +11692,17 @@ lpfc_sli4_init_vpi(struct lpfc_hba *phba
 	lpfc_init_vpi(phba, mboxq, vpi);
 	mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI);
 	rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mboxq, phba->mbox_mem_pool);
 	if (rc != MBX_SUCCESS) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2022 INIT VPI Mailbox failed "
 				"status %d, mbxStatus x%x\n", rc,
 				bf_get(lpfc_mqe_status, &mboxq->u.mqe));
-		rc = -EIO;
+		retval = -EIO;
 	}
-	return rc;
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+
+	return retval;
 }
 
 /**
@@ -11438,13 +11787,6 @@ lpfc_sli4_add_fcf_record(struct lpfc_hba
 	 */
 	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
 	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
-	if (unlikely(!mboxq->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2526 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
-	}
 	virt_addr = mboxq->sge_array->addr[0];
 	/*
 	 * Configure the FCF record for FCFI 0.  This is the driver's
@@ -11542,7 +11884,8 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2000 Failed to allocate mbox for "
 				"READ_FCF cmd\n");
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto fail_fcfscan;
 	}
 
 	req_len = sizeof(struct fcf_record) +
@@ -11558,8 +11901,8 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 				"0291 Allocated DMA memory size (x%x) is "
 				"less than the requested DMA memory "
 				"size (x%x)\n", alloc_len, req_len);
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto fail_fcfscan;
 	}
 
 	/* Get the first SGE entry from the non-embedded DMA memory. This
@@ -11567,13 +11910,6 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 	 */
 	lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
 	phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
-	if (unlikely(!mboxq->sge_array)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-				"2527 Failed to get the non-embedded SGE "
-				"virtual address\n");
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
-		return -ENOMEM;
-	}
 	virt_addr = mboxq->sge_array->addr[0];
 	read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
 
@@ -11586,7 +11922,6 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 	mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record;
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
 	if (rc == MBX_NOT_FINISHED) {
-		lpfc_sli4_mbox_cmd_free(phba, mboxq);
 		error = -EIO;
 	} else {
 		spin_lock_irq(&phba->hbalock);
@@ -11594,6 +11929,15 @@ lpfc_sli4_read_fcf_record(struct lpfc_hb
 		spin_unlock_irq(&phba->hbalock);
 		error = 0;
 	}
+fail_fcfscan:
+	if (error) {
+		if (mboxq)
+			lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		/* FCF scan failed, clear FCF_DISC_INPROGRESS flag */
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
+	}
 	return error;
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_sli.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_sli.h	2010-02-24 13:52:17.000000000 -0500
@@ -29,14 +29,17 @@ typedef enum _lpfc_ctx_cmd {
 	LPFC_CTX_HOST
 } lpfc_ctx_cmd;
 
-/* This structure is used to carry the needed response IOCB states */
-struct lpfc_sli4_rspiocb_info {
-	uint8_t hw_status;
-	uint8_t bfield;
-#define LPFC_XB	0x1
-#define LPFC_PV	0x2
-	uint8_t priority;
-	uint8_t reserved;
+struct lpfc_cq_event {
+	struct list_head list;
+	union {
+		struct lpfc_mcqe		mcqe_cmpl;
+		struct lpfc_acqe_link		acqe_link;
+		struct lpfc_acqe_fcoe		acqe_fcoe;
+		struct lpfc_acqe_dcbx		acqe_dcbx;
+		struct lpfc_rcqe		rcqe_cmpl;
+		struct sli4_wcqe_xri_aborted	wcqe_axri;
+		struct lpfc_wcqe_complete	wcqe_cmpl;
+	} cqe;
 };
 
 /* This structure is used to handle IOCB requests / responses */
@@ -46,6 +49,7 @@ struct lpfc_iocbq {
 	struct list_head clist;
 	uint16_t iotag;         /* pre-assigned IO tag */
 	uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
+	struct lpfc_cq_event cq_event;
 
 	IOCB_t iocb;		/* IOCB cmd */
 	uint8_t retry;		/* retry counter for IOCB cmd - if needed */
@@ -56,11 +60,13 @@ struct lpfc_iocbq {
 #define LPFC_DRIVER_ABORTED	8	/* driver aborted this request */
 #define LPFC_IO_FABRIC		0x10	/* Iocb send using fabric scheduler */
 #define LPFC_DELAY_MEM_FREE	0x20    /* Defer free'ing of FC data */
-#define LPFC_FIP_ELS		0x40
+#define LPFC_FIP_ELS_ID_MASK	0xc0	/* ELS_ID range 0-3 */
+#define LPFC_FIP_ELS_ID_SHIFT	6
 
 	uint8_t abort_count;
 	uint8_t rsvd2;
 	uint32_t drvrTimeout;	/* driver timeout in seconds */
+	uint32_t fcp_wqidx;	/* index to FCP work queue */
 	struct lpfc_vport *vport;/* virtual port pointer */
 	void *context1;		/* caller context information */
 	void *context2;		/* caller context information */
@@ -76,7 +82,6 @@ struct lpfc_iocbq {
 			   struct lpfc_iocbq *);
 	void (*iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 			   struct lpfc_iocbq *);
-	struct lpfc_sli4_rspiocb_info sli4_info;
 };
 
 #define SLI_IOCB_RET_IOCB      1	/* Return IOCB if cmd ring full */
@@ -110,7 +115,7 @@ typedef struct lpfcMboxq {
 				   return */
 #define MBX_NOWAIT      2	/* issue command then return immediately */
 
-#define LPFC_MAX_RING_MASK  4	/* max num of rctl/type masks allowed per
+#define LPFC_MAX_RING_MASK  5	/* max num of rctl/type masks allowed per
 				   ring */
 #define LPFC_MAX_RING       4	/* max num of SLI rings used by driver */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_version.h linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_version.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_version.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_version.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,8 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.4"
-
+#define LPFC_DRIVER_VERSION "8.3.7"
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_vport.c linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_vport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/lpfc/lpfc_vport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/lpfc/lpfc_vport.c	2010-02-24 13:52:17.000000000 -0500
@@ -389,7 +389,7 @@ lpfc_vport_create(struct fc_vport *fc_vp
 	 * by the port.
 	 */
 	if ((phba->sli_rev == LPFC_SLI_REV4) &&
-		(pport->vfi_state & LPFC_VFI_REGISTERED)) {
+	    (pport->vpi_state & LPFC_VPI_REGISTERED)) {
 		rc = lpfc_sli4_init_vpi(phba, vpi);
 		if (rc) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
@@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport)
 		return VPORT_OK;
 	}
 
+	spin_lock_irq(&phba->hbalock);
 	vport->load_flag |= FC_LOADING;
 	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+	spin_unlock_irq(&phba->hbalock);
 
 	/* Use the Physical nodes Fabric NDLP to determine if the link is
 	 * up and ready to FDISC.
@@ -700,6 +702,8 @@ lpfc_vport_delete(struct fc_vport *fc_vp
 			}
 			spin_unlock_irq(&phba->ndlp_lock);
 		}
+		if (!(vport->vpi_state & LPFC_VPI_REGISTERED))
+			goto skip_logo;
 		vport->unreg_vpi_cmpl = VPORT_INVAL;
 		timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
 		if (!lpfc_issue_els_npiv_logo(vport, ndlp))
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/Makefile linux-libre-2.6.33-gnu1/drivers/scsi/Makefile
--- linux-libre-2.6.32-gnu1/drivers/scsi/Makefile	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -70,6 +70,7 @@ obj-$(CONFIG_SCSI_AIC79XX)	+= aic7xxx/
 obj-$(CONFIG_SCSI_AACRAID)	+= aacraid/
 obj-$(CONFIG_SCSI_AIC7XXX_OLD)	+= aic7xxx_old.o
 obj-$(CONFIG_SCSI_AIC94XX)	+= aic94xx/
+obj-$(CONFIG_SCSI_PM8001)	+= pm8001/
 obj-$(CONFIG_SCSI_IPS)		+= ips.o
 obj-$(CONFIG_SCSI_FD_MCS)	+= fd_mcs.o
 obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
@@ -90,6 +91,7 @@ obj-$(CONFIG_SCSI_BFA_FC)	+= bfa/
 obj-$(CONFIG_SCSI_PAS16)	+= pas16.o
 obj-$(CONFIG_SCSI_T128)		+= t128.o
 obj-$(CONFIG_SCSI_DMX3191D)	+= dmx3191d.o
+obj-$(CONFIG_SCSI_HPSA)		+= hpsa.o
 obj-$(CONFIG_SCSI_DTC3280)	+= dtc.o
 obj-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2/
 obj-$(CONFIG_SCSI_ZALON)	+= zalon7xx.o
@@ -113,6 +115,7 @@ obj-$(CONFIG_SCSI_MESH)		+= mesh.o
 obj-$(CONFIG_SCSI_MAC53C94)	+= mac53c94.o
 obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
 obj-$(CONFIG_SCSI_3W_9XXX)	+= 3w-9xxx.o
+obj-$(CONFIG_SCSI_3W_SAS)	+= 3w-sas.o
 obj-$(CONFIG_SCSI_PPA)		+= ppa.o
 obj-$(CONFIG_SCSI_IMM)		+= imm.o
 obj-$(CONFIG_JAZZ_ESP)		+= esp_scsi.o	jazz_esp.o
@@ -133,6 +136,7 @@ obj-$(CONFIG_SCSI_CXGB3_ISCSI)	+= libisc
 obj-$(CONFIG_SCSI_BNX2_ISCSI)	+= libiscsi.o bnx2i/
 obj-$(CONFIG_BE2ISCSI)		+= libiscsi.o be2iscsi/
 obj-$(CONFIG_SCSI_PMCRAID)	+= pmcraid.o
+obj-$(CONFIG_VMWARE_PVSCSI)	+= vmw_pvscsi.o
 
 obj-$(CONFIG_ARM)		+= arm/
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/mbox_defs.h linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/mbox_defs.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/mbox_defs.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/mbox_defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -497,7 +497,7 @@ typedef struct {
  * @inserted_drive		: channel:Id of inserted drive
  * @battery_status		: bit 0: battery module missing
  *				bit 1: VBAD
- *				bit 2: temprature high
+ *				bit 2: temperature high
  *				bit 3: battery pack missing
  *				bit 4,5:
  *					00 - charge complete
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_mbox.c linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mbox.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_mbox.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_mbox.c	2010-02-24 13:52:17.000000000 -0500
@@ -335,12 +335,17 @@ static struct device_attribute *megaraid
  * megaraid_change_queue_depth - Change the device's queue depth
  * @sdev:	scsi device struct
  * @qdepth:	depth to set
+ * @reason:	calling context
  *
  * Return value:
  * 	actual depth set
  */
-static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth)
+static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth,
+				       int reason)
 {
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
+
 	if (qdepth > MBOX_MAX_SCSI_CMDS)
 		qdepth = MBOX_MAX_SCSI_CMDS;
 	scsi_adjust_queue_depth(sdev, 0, qdepth);
@@ -2704,7 +2709,7 @@ megaraid_reset_handler(struct scsi_cmnd
 	}
 	else {
 		con_log(CL_ANN, (KERN_NOTICE
-		"megaraid mbox: reset sequence completed sucessfully\n"));
+		"megaraid mbox: reset sequence completed successfully\n"));
 	}
 
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_sas.c linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_sas.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.c	2010-02-24 13:52:17.000000000 -0500
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version     : v00.00.04.01-rc1
+ * Version     : v00.00.04.12-rc1
  *
  * Authors:
  *	(email-id : megaraidlinux@lsi.com)
@@ -40,6 +40,7 @@
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/poll.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -75,6 +76,10 @@ static struct pci_device_id megasas_pci_
 	/* gen2*/
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
 	/* gen2*/
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
+	/* skinny*/
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
+	/* skinny*/
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
 	/* xscale IOP, vega */
 	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -89,8 +94,14 @@ static struct megasas_mgmt_info megasas_
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);
 
+static int megasas_poll_wait_aen;
+static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
+static u32 support_poll_for_event;
 static u32 megasas_dbg_lvl;
 
+/* define lock for aen poll */
+spinlock_t poll_aen_lock;
+
 static void
 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
 		     u8 alt_status);
@@ -215,7 +226,10 @@ megasas_clear_intr_xscale(struct megasas
  * @regs :			MFI register set
  */
 static inline void 
-megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_xscale(struct megasas_instance *instance,
+		dma_addr_t frame_phys_addr,
+		u32 frame_count,
+		struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr >> 3)|(frame_count),
 	       &(regs)->inbound_queue_port);
@@ -312,7 +326,10 @@ megasas_clear_intr_ppc(struct megasas_re
  * @regs :			MFI register set
  */
 static inline void 
-megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_ppc(struct megasas_instance *instance,
+		dma_addr_t frame_phys_addr,
+		u32 frame_count,
+		struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr | (frame_count<<1))|1, 
 			&(regs)->inbound_queue_port);
@@ -328,6 +345,104 @@ static struct megasas_instance_template
 };
 
 /**
+ * megasas_enable_intr_skinny -	Enables interrupts
+ * @regs:			MFI register set
+ */
+static inline void
+megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
+
+	writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+	/* Dummy readl to force pci flush */
+	readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_skinny -	Disables interrupt
+ * @regs:			MFI register set
+ */
+static inline void
+megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	u32 mask = 0xFFFFFFFF;
+	writel(mask, &regs->outbound_intr_mask);
+	/* Dummy readl to force pci flush */
+	readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_skinny - returns the current FW status value
+ * @regs:			MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
+{
+	return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_skinny -	Check & clear interrupt
+ * @regs:				MFI register set
+ */
+static int
+megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+	u32 status;
+	/*
+	 * Check if it is our interrupt
+	 */
+	status = readl(&regs->outbound_intr_status);
+
+	if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
+		return 1;
+	}
+
+	/*
+	 * Clear the interrupt by writing back the same value
+	 */
+	writel(status, &regs->outbound_intr_status);
+
+	/*
+	* dummy read to flush PCI
+	*/
+	readl(&regs->outbound_intr_status);
+
+	return 0;
+}
+
+/**
+ * megasas_fire_cmd_skinny -	Sends command to the FW
+ * @frame_phys_addr :		Physical address of cmd
+ * @frame_count :		Number of frames for the command
+ * @regs :			MFI register set
+ */
+static inline void
+megasas_fire_cmd_skinny(struct megasas_instance *instance,
+			dma_addr_t frame_phys_addr,
+			u32 frame_count,
+			struct megasas_register_set __iomem *regs)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&instance->fire_lock, flags);
+	writel(0, &(regs)->inbound_high_queue_port);
+	writel((frame_phys_addr | (frame_count<<1))|1,
+		&(regs)->inbound_low_queue_port);
+	spin_unlock_irqrestore(&instance->fire_lock, flags);
+}
+
+static struct megasas_instance_template megasas_instance_template_skinny = {
+
+	.fire_cmd = megasas_fire_cmd_skinny,
+	.enable_intr = megasas_enable_intr_skinny,
+	.disable_intr = megasas_disable_intr_skinny,
+	.clear_intr = megasas_clear_intr_skinny,
+	.read_fw_status_reg = megasas_read_fw_status_reg_skinny,
+};
+
+
+/**
 *	The following functions are defined for gen2 (deviceid : 0x78 0x79)
 *	controllers
 */
@@ -404,7 +519,9 @@ megasas_clear_intr_gen2(struct megasas_r
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
+megasas_fire_cmd_gen2(struct megasas_instance *instance,
+			dma_addr_t frame_phys_addr,
+			u32 frame_count,
 			struct megasas_register_set __iomem *regs)
 {
 	writel((frame_phys_addr | (frame_count<<1))|1,
@@ -446,7 +563,8 @@ megasas_issue_polled(struct megasas_inst
 	/*
 	 * Issue the frame using inbound queue port
 	 */
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	/*
 	 * Wait for cmd_status to change
@@ -477,7 +595,8 @@ megasas_issue_blocked_cmd(struct megasas
 {
 	cmd->cmd_status = ENODATA;
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
 		MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
@@ -522,7 +641,8 @@ megasas_issue_blocked_abort_cmd(struct m
 	cmd->sync_cmd = 1;
 	cmd->cmd_status = 0xFF;
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	/*
 	 * Wait for this cmd to complete
@@ -592,6 +712,35 @@ megasas_make_sgl64(struct megasas_instan
 	return sge_count;
 }
 
+/**
+ * megasas_make_sgl_skinny - Prepares IEEE SGL
+ * @instance:           Adapter soft state
+ * @scp:                SCSI command from the mid-layer
+ * @mfi_sgl:            SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static int
+megasas_make_sgl_skinny(struct megasas_instance *instance,
+		struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
+{
+	int i;
+	int sge_count;
+	struct scatterlist *os_sgl;
+
+	sge_count = scsi_dma_map(scp);
+
+	if (sge_count) {
+		scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+			mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
+			mfi_sgl->sge_skinny[i].phys_addr =
+						sg_dma_address(os_sgl);
+		}
+	}
+	return sge_count;
+}
+
  /**
  * megasas_get_frame_count - Computes the number of frames
  * @frame_type		: type of frame- io or pthru frame
@@ -600,7 +749,8 @@ megasas_make_sgl64(struct megasas_instan
  * Returns the number of frames required for numnber of sge's (sge_count)
  */
 
-static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+static u32 megasas_get_frame_count(struct megasas_instance *instance,
+			u8 sge_count, u8 frame_type)
 {
 	int num_cnt;
 	int sge_bytes;
@@ -610,6 +760,10 @@ static u32 megasas_get_frame_count(u8 sg
 	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
 	    sizeof(struct megasas_sge32);
 
+	if (instance->flag_ieee) {
+		sge_sz = sizeof(struct megasas_sge_skinny);
+	}
+
 	/*
 	 * Main frame can contain 2 SGEs for 64-bit SGLs and
 	 * 3 SGEs for 32-bit SGLs for ldio &
@@ -617,12 +771,16 @@ static u32 megasas_get_frame_count(u8 sg
 	 * 2 SGEs for 32-bit SGLs for pthru frame
 	 */
 	if (unlikely(frame_type == PTHRU_FRAME)) {
-		if (IS_DMA64)
+		if (instance->flag_ieee == 1) {
+			num_cnt = sge_count - 1;
+		} else if (IS_DMA64)
 			num_cnt = sge_count - 1;
 		else
 			num_cnt = sge_count - 2;
 	} else {
-		if (IS_DMA64)
+		if (instance->flag_ieee == 1) {
+			num_cnt = sge_count - 1;
+		} else if (IS_DMA64)
 			num_cnt = sge_count - 2;
 		else
 			num_cnt = sge_count - 3;
@@ -671,6 +829,10 @@ megasas_build_dcdb(struct megasas_instan
 	else if (scp->sc_data_direction == PCI_DMA_NONE)
 		flags = MFI_FRAME_DIR_NONE;
 
+	if (instance->flag_ieee == 1) {
+		flags |= MFI_FRAME_IEEE;
+	}
+
 	/*
 	 * Prepare the DCDB frame
 	 */
@@ -687,9 +849,24 @@ megasas_build_dcdb(struct megasas_instan
 	memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
 
 	/*
+	* If the command is for the tape device, set the
+	* pthru timeout to the os layer timeout value.
+	*/
+	if (scp->device->type == TYPE_TAPE) {
+		if ((scp->request->timeout / HZ) > 0xFFFF)
+			pthru->timeout = 0xFFFF;
+		else
+			pthru->timeout = scp->request->timeout / HZ;
+	}
+
+	/*
 	 * Construct SGL
 	 */
-	if (IS_DMA64) {
+	if (instance->flag_ieee == 1) {
+		pthru->flags |= MFI_FRAME_SGL64;
+		pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
+						      &pthru->sgl);
+	} else if (IS_DMA64) {
 		pthru->flags |= MFI_FRAME_SGL64;
 		pthru->sge_count = megasas_make_sgl64(instance, scp,
 						      &pthru->sgl);
@@ -708,7 +885,7 @@ megasas_build_dcdb(struct megasas_instan
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 */
-	cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
+	cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
 							PTHRU_FRAME);
 
 	return cmd->frame_count;
@@ -739,6 +916,10 @@ megasas_build_ldio(struct megasas_instan
 	else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
 		flags = MFI_FRAME_DIR_READ;
 
+	if (instance->flag_ieee == 1) {
+		flags |= MFI_FRAME_IEEE;
+	}
+
 	/*
 	 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
 	 */
@@ -809,7 +990,11 @@ megasas_build_ldio(struct megasas_instan
 	/*
 	 * Construct SGL
 	 */
-	if (IS_DMA64) {
+	if (instance->flag_ieee) {
+		ldio->flags |= MFI_FRAME_SGL64;
+		ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
+					      &ldio->sgl);
+	} else if (IS_DMA64) {
 		ldio->flags |= MFI_FRAME_SGL64;
 		ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
 	} else
@@ -826,7 +1011,8 @@ megasas_build_ldio(struct megasas_instan
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 */
-	cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
+	cmd->frame_count = megasas_get_frame_count(instance,
+			ldio->sge_count, IO_FRAME);
 
 	return cmd->frame_count;
 }
@@ -983,7 +1169,8 @@ megasas_queue_command(struct scsi_cmnd *
 	 */
 	atomic_inc(&instance->fw_outstanding);
 
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
+	instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
+				cmd->frame_count-1, instance->reg_set);
 	/*
 	 * Check if we have pend cmds to be completed
 	 */
@@ -1000,24 +1187,76 @@ megasas_queue_command(struct scsi_cmnd *
 	return 0;
 }
 
+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+	int i;
+
+	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+		if ((megasas_mgmt_info.instance[i]) &&
+		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+			return megasas_mgmt_info.instance[i];
+	}
+
+	return NULL;
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
+	u16             pd_index = 0;
+	struct  megasas_instance *instance ;
+
+	instance = megasas_lookup_instance(sdev->host->host_no);
+
 	/*
-	 * Don't export physical disk devices to the disk driver.
-	 *
-	 * FIXME: Currently we don't export them to the midlayer at all.
-	 * 	  That will be fixed once LSI engineers have audited the
-	 * 	  firmware for possible issues.
-	 */
-	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
+	* Don't export physical disk devices to the disk driver.
+	*
+	* FIXME: Currently we don't export them to the midlayer at all.
+	*        That will be fixed once LSI engineers have audited the
+	*        firmware for possible issues.
+	*/
+	if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+				sdev->type == TYPE_DISK) {
+		pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+								sdev->id;
+		if (instance->pd_list[pd_index].driveState ==
+						MR_PD_STATE_SYSTEM) {
+			blk_queue_rq_timeout(sdev->request_queue,
+				MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+			return 0;
+		}
 		return -ENXIO;
+	}
 
 	/*
-	 * The RAID firmware may require extended timeouts.
-	 */
-	if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-		blk_queue_rq_timeout(sdev->request_queue,
-				     MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+	* The RAID firmware may require extended timeouts.
+	*/
+	blk_queue_rq_timeout(sdev->request_queue,
+		MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+	return 0;
+}
+
+static int megasas_slave_alloc(struct scsi_device *sdev)
+{
+	u16             pd_index = 0;
+	struct megasas_instance *instance ;
+	instance = megasas_lookup_instance(sdev->host->host_no);
+	if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
+				(sdev->type == TYPE_DISK)) {
+		/*
+		 * Open the OS scan to the SYSTEM PD
+		 */
+		pd_index =
+			(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+			sdev->id;
+		if ((instance->pd_list[pd_index].driveState ==
+					MR_PD_STATE_SYSTEM) &&
+			(instance->pd_list[pd_index].driveType ==
+						TYPE_DISK)) {
+			return 0;
+		}
+		return -ENXIO;
+	}
 	return 0;
 }
 
@@ -1072,7 +1311,14 @@ static void megasas_complete_cmd_dpc(uns
 
 		spin_lock_irqsave(instance->host->host_lock, flags);
 		instance->flag &= ~MEGASAS_FW_BUSY;
-		instance->host->can_queue =
+		if ((instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+			instance->host->can_queue =
+				instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+		} else
+			instance->host->can_queue =
 				instance->max_fw_cmds - MEGASAS_INT_CMDS;
 
 		spin_unlock_irqrestore(instance->host->host_lock, flags);
@@ -1117,8 +1363,16 @@ static int megasas_wait_for_outstanding(
 		* Send signal to FW to stop processing any pending cmds.
 		* The controller will be taken offline by the OS now.
 		*/
-		writel(MFI_STOP_ADP,
+		if ((instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+			writel(MFI_STOP_ADP,
+				&instance->reg_set->reserved_0[0]);
+		} else {
+			writel(MFI_STOP_ADP,
 				&instance->reg_set->inbound_doorbell);
+		}
 		megasas_dump_pending_frames(instance);
 		instance->hw_crit_error = 1;
 		return FAILED;
@@ -1266,6 +1520,8 @@ megasas_bios_param(struct scsi_device *s
 	return 0;
 }
 
+static void megasas_aen_polling(struct work_struct *work);
+
 /**
  * megasas_service_aen -	Processes an event notification
  * @instance:			Adapter soft state
@@ -1281,16 +1537,36 @@ megasas_bios_param(struct scsi_device *s
 static void
 megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
 {
+	unsigned long flags;
 	/*
 	 * Don't signal app if it is just an aborted previously registered aen
 	 */
-	if (!cmd->abort_aen)
+	if ((!cmd->abort_aen) && (instance->unload == 0)) {
+		spin_lock_irqsave(&poll_aen_lock, flags);
+		megasas_poll_wait_aen = 1;
+		spin_unlock_irqrestore(&poll_aen_lock, flags);
+		wake_up(&megasas_poll_wait);
 		kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+	}
 	else
 		cmd->abort_aen = 0;
 
 	instance->aen_cmd = NULL;
 	megasas_return_cmd(instance, cmd);
+
+	if (instance->unload == 0) {
+		struct megasas_aen_event *ev;
+		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+		if (!ev) {
+			printk(KERN_ERR "megasas_service_aen: out of memory\n");
+		} else {
+			ev->instance = instance;
+			instance->ev = ev;
+			INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
+			schedule_delayed_work(
+				(struct delayed_work *)&ev->hotplug_work, 0);
+		}
+	}
 }
 
 /*
@@ -1302,6 +1578,7 @@ static struct scsi_host_template megasas
 	.name = "LSI SAS based MegaRAID driver",
 	.proc_name = "megaraid_sas",
 	.slave_configure = megasas_slave_configure,
+	.slave_alloc = megasas_slave_alloc,
 	.queuecommand = megasas_queue_command,
 	.eh_device_reset_handler = megasas_reset_device,
 	.eh_bus_reset_handler = megasas_reset_bus_host,
@@ -1370,6 +1647,7 @@ megasas_complete_cmd(struct megasas_inst
 {
 	int exception = 0;
 	struct megasas_header *hdr = &cmd->frame->hdr;
+	unsigned long flags;
 
 	if (cmd->scmd)
 		cmd->scmd->SCp.ptr = NULL;
@@ -1459,6 +1737,12 @@ megasas_complete_cmd(struct megasas_inst
 	case MFI_CMD_SMP:
 	case MFI_CMD_STP:
 	case MFI_CMD_DCMD:
+		if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
+			cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
+			spin_lock_irqsave(&poll_aen_lock, flags);
+			megasas_poll_wait_aen = 0;
+			spin_unlock_irqrestore(&poll_aen_lock, flags);
+		}
 
 		/*
 		 * See if got an event notification
@@ -1536,6 +1820,7 @@ megasas_transition_to_ready(struct megas
 	u8 max_wait;
 	u32 fw_state;
 	u32 cur_state;
+	u32 abs_state, curr_abs_state;
 
 	fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
@@ -1545,6 +1830,9 @@ megasas_transition_to_ready(struct megas
 
 	while (fw_state != MFI_STATE_READY) {
 
+		abs_state =
+		instance->instancet->read_fw_status_reg(instance->reg_set);
+
 		switch (fw_state) {
 
 		case MFI_STATE_FAULT:
@@ -1556,18 +1844,36 @@ megasas_transition_to_ready(struct megas
 			/*
 			 * Set the CLR bit in inbound doorbell
 			 */
-			writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-				&instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
 
-			max_wait = 2;
+				writel(
+				  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+				  &instance->reg_set->reserved_0[0]);
+			} else {
+				writel(
+				    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+					&instance->reg_set->inbound_doorbell);
+			}
+
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_WAIT_HANDSHAKE;
 			break;
 
 		case MFI_STATE_BOOT_MESSAGE_PENDING:
-			writel(MFI_INIT_HOTPLUG,
-				&instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+			(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+				writel(MFI_INIT_HOTPLUG,
+				&instance->reg_set->reserved_0[0]);
+			} else
+				writel(MFI_INIT_HOTPLUG,
+					&instance->reg_set->inbound_doorbell);
 
-			max_wait = 10;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
 			break;
 
@@ -1576,9 +1882,17 @@ megasas_transition_to_ready(struct megas
 			 * Bring it to READY state; assuming max wait 10 secs
 			 */
 			instance->instancet->disable_intr(instance->reg_set);
-			writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+				writel(MFI_RESET_FLAGS,
+					&instance->reg_set->reserved_0[0]);
+			} else
+				writel(MFI_RESET_FLAGS,
+					&instance->reg_set->inbound_doorbell);
 
-			max_wait = 60;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_OPERATIONAL;
 			break;
 
@@ -1586,32 +1900,32 @@ megasas_transition_to_ready(struct megas
 			/*
 			 * This state should not last for more than 2 seconds
 			 */
-			max_wait = 2;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_UNDEFINED;
 			break;
 
 		case MFI_STATE_BB_INIT:
-			max_wait = 2;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_BB_INIT;
 			break;
 
 		case MFI_STATE_FW_INIT:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FW_INIT;
 			break;
 
 		case MFI_STATE_FW_INIT_2:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FW_INIT_2;
 			break;
 
 		case MFI_STATE_DEVICE_SCAN:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_DEVICE_SCAN;
 			break;
 
 		case MFI_STATE_FLUSH_CACHE:
-			max_wait = 20;
+			max_wait = MEGASAS_RESET_WAIT_TIME;
 			cur_state = MFI_STATE_FLUSH_CACHE;
 			break;
 
@@ -1627,8 +1941,10 @@ megasas_transition_to_ready(struct megas
 		for (i = 0; i < (max_wait * 1000); i++) {
 			fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &  
 					MFI_STATE_MASK ;
+		curr_abs_state =
+		instance->instancet->read_fw_status_reg(instance->reg_set);
 
-			if (fw_state == cur_state) {
+			if (abs_state == curr_abs_state) {
 				msleep(1);
 			} else
 				break;
@@ -1637,7 +1953,7 @@ megasas_transition_to_ready(struct megas
 		/*
 		 * Return error if fw_state hasn't changed after max_wait
 		 */
-		if (fw_state == cur_state) {
+		if (curr_abs_state == abs_state) {
 			printk(KERN_DEBUG "FW state [%d] hasn't changed "
 			       "in %d secs\n", fw_state, max_wait);
 			return -ENODEV;
@@ -1715,6 +2031,10 @@ static int megasas_create_frame_pool(str
 	sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
 	    sizeof(struct megasas_sge32);
 
+	if (instance->flag_ieee) {
+		sge_sz = sizeof(struct megasas_sge_skinny);
+	}
+
 	/*
 	 * Calculated the number of 64byte frames required for SGL
 	 */
@@ -1777,6 +2097,7 @@ static int megasas_create_frame_pool(str
 		}
 
 		cmd->frame->io.context = cmd->index;
+		cmd->frame->io.pad_0 = 0;
 	}
 
 	return 0;
@@ -1882,6 +2203,97 @@ static int megasas_alloc_cmds(struct meg
 	return 0;
 }
 
+/*
+ * megasas_get_pd_list_info -	Returns FW's pd_list structure
+ * @instance:				Adapter soft state
+ * @pd_list:				pd_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_pd_list(struct megasas_instance *instance)
+{
+	int ret = 0, pd_index = 0;
+	struct megasas_cmd *cmd;
+	struct megasas_dcmd_frame *dcmd;
+	struct MR_PD_LIST *ci;
+	struct MR_PD_ADDRESS *pd_addr;
+	dma_addr_t ci_h = 0;
+
+	cmd = megasas_get_cmd(instance);
+
+	if (!cmd) {
+		printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+		return -ENOMEM;
+	}
+
+	dcmd = &cmd->frame->dcmd;
+
+	ci = pci_alloc_consistent(instance->pdev,
+		  MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
+
+	if (!ci) {
+		printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+		megasas_return_cmd(instance, cmd);
+		return -ENOMEM;
+	}
+
+	memset(ci, 0, sizeof(*ci));
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+	dcmd->mbox.b[1] = 0;
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0xFF;
+	dcmd->sge_count = 1;
+	dcmd->flags = MFI_FRAME_DIR_READ;
+	dcmd->timeout = 0;
+	dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+	dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
+	dcmd->sgl.sge32[0].phys_addr = ci_h;
+	dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+
+	if (!megasas_issue_polled(instance, cmd)) {
+		ret = 0;
+	} else {
+		ret = -1;
+	}
+
+	/*
+	* the following function will get the instance PD LIST.
+	*/
+
+	pd_addr = ci->addr;
+
+	if ( ret == 0 &&
+		(ci->count <
+		  (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+
+		memset(instance->pd_list, 0,
+			MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+
+		for (pd_index = 0; pd_index < ci->count; pd_index++) {
+
+			instance->pd_list[pd_addr->deviceId].tid	=
+							pd_addr->deviceId;
+			instance->pd_list[pd_addr->deviceId].driveType	=
+							pd_addr->scsiDevType;
+			instance->pd_list[pd_addr->deviceId].driveState	=
+							MR_PD_STATE_SYSTEM;
+			pd_addr++;
+		}
+	}
+
+	pci_free_consistent(instance->pdev,
+				MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
+				ci, ci_h);
+	megasas_return_cmd(instance, cmd);
+
+	return ret;
+}
+
 /**
  * megasas_get_controller_info -	Returns FW's controller structure
  * @instance:				Adapter soft state
@@ -2081,13 +2493,17 @@ static int megasas_init_mfi(struct megas
 	 * Map the message registers
 	 */
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
 		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
 		instance->base_addr = pci_resource_start(instance->pdev, 1);
 	} else {
 		instance->base_addr = pci_resource_start(instance->pdev, 0);
 	}
 
-	if (pci_request_regions(instance->pdev, "megasas: LSI")) {
+	if (pci_request_selected_regions(instance->pdev,
+		pci_select_bars(instance->pdev, IORESOURCE_MEM),
+		"megasas: LSI")) {
 		printk(KERN_DEBUG "megasas: IO memory region busy!\n");
 		return -EBUSY;
 	}
@@ -2111,6 +2527,10 @@ static int megasas_init_mfi(struct megas
 		case PCI_DEVICE_ID_LSI_SAS0079GEN2:
 			instance->instancet = &megasas_instance_template_gen2;
 			break;
+		case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+		case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+			instance->instancet = &megasas_instance_template_skinny;
+			break;
 		case PCI_DEVICE_ID_LSI_SAS1064R:
 		case PCI_DEVICE_ID_DELL_PERC5:
 		default:
@@ -2166,6 +2586,10 @@ static int megasas_init_mfi(struct megas
 	if (megasas_issue_init_mfi(instance))
 		goto fail_fw_init;
 
+	memset(instance->pd_list, 0 ,
+		(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
+	megasas_get_pd_list(instance);
+
 	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
 
 	/*
@@ -2220,7 +2644,8 @@ static int megasas_init_mfi(struct megas
 	iounmap(instance->reg_set);
 
       fail_ioremap:
-	pci_release_regions(instance->pdev);
+	pci_release_selected_regions(instance->pdev,
+		pci_select_bars(instance->pdev, IORESOURCE_MEM));
 
 	return -EINVAL;
 }
@@ -2240,7 +2665,8 @@ static void megasas_release_mfi(struct m
 
 	iounmap(instance->reg_set);
 
-	pci_release_regions(instance->pdev);
+	pci_release_selected_regions(instance->pdev,
+		pci_select_bars(instance->pdev, IORESOURCE_MEM));
 }
 
 /**
@@ -2409,6 +2835,11 @@ megasas_register_aen(struct megasas_inst
 	dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
 	dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
 
+	if (instance->aen_cmd != NULL) {
+		megasas_return_cmd(instance, cmd);
+		return 0;
+	}
+
 	/*
 	 * Store reference to the cmd used to register for AEN. When an
 	 * application wants us to register for AEN, we have to abort this
@@ -2419,7 +2850,8 @@ megasas_register_aen(struct megasas_inst
 	/*
 	 * Issue the aen registration frame
 	 */
-	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+	instance->instancet->fire_cmd(instance,
+			cmd->frame_phys_addr, 0, instance->reg_set);
 
 	return 0;
 }
@@ -2465,7 +2897,13 @@ static int megasas_io_attach(struct mega
 	 */
 	host->irq = instance->pdev->irq;
 	host->unique_id = instance->unique_id;
-	host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+		host->can_queue =
+			instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+	} else
+		host->can_queue =
+			instance->max_fw_cmds - MEGASAS_INT_CMDS;
 	host->this_id = instance->init_id;
 	host->sg_tablesize = instance->max_num_sge;
 	host->max_sectors = instance->max_sectors_per_req;
@@ -2537,7 +2975,7 @@ megasas_probe_one(struct pci_dev *pdev,
 	/*
 	 * PCI prepping: enable device set bus mastering and dma mask
 	 */
-	rval = pci_enable_device(pdev);
+	rval = pci_enable_device_mem(pdev);
 
 	if (rval) {
 		return rval;
@@ -2572,6 +3010,9 @@ megasas_probe_one(struct pci_dev *pdev,
 
 	*instance->producer = 0;
 	*instance->consumer = 0;
+	megasas_poll_wait_aen = 0;
+	instance->flag_ieee = 0;
+	instance->ev = NULL;
 
 	instance->evt_detail = pci_alloc_consistent(pdev,
 						    sizeof(struct
@@ -2595,10 +3036,11 @@ megasas_probe_one(struct pci_dev *pdev,
 	init_waitqueue_head(&instance->abort_cmd_wait_q);
 
 	spin_lock_init(&instance->cmd_pool_lock);
+	spin_lock_init(&instance->fire_lock);
 	spin_lock_init(&instance->completion_lock);
+	spin_lock_init(&poll_aen_lock);
 
 	mutex_init(&instance->aen_mutex);
-	sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
 
 	/*
 	 * Initialize PCI related and misc parameters
@@ -2608,8 +3050,16 @@ megasas_probe_one(struct pci_dev *pdev,
 	instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
 	instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+		instance->flag_ieee = 1;
+		sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+	} else
+		sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
 	megasas_dbg_lvl = 0;
 	instance->flag = 0;
+	instance->unload = 1;
 	instance->last_time = 0;
 
 	/*
@@ -2655,6 +3105,7 @@ megasas_probe_one(struct pci_dev *pdev,
 	if (megasas_io_attach(instance))
 		goto fail_io_attach;
 
+	instance->unload = 0;
 	return 0;
 
       fail_start_aen:
@@ -2778,12 +3229,23 @@ megasas_suspend(struct pci_dev *pdev, pm
 
 	instance = pci_get_drvdata(pdev);
 	host = instance->host;
+	instance->unload = 1;
 
 	if (poll_mode_io)
 		del_timer_sync(&instance->io_completion_timer);
 
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
+
+	/* cancel the delayed work if this work still in queue */
+	if (instance->ev != NULL) {
+		struct megasas_aen_event *ev = instance->ev;
+		cancel_delayed_work(
+			(struct delayed_work *)&ev->hotplug_work);
+		flush_scheduled_work();
+		instance->ev = NULL;
+	}
+
 	tasklet_kill(&instance->isr_tasklet);
 
 	pci_set_drvdata(instance->pdev, instance);
@@ -2818,7 +3280,7 @@ megasas_resume(struct pci_dev *pdev)
 	/*
 	 * PCI prepping: enable device set bus mastering and dma mask
 	 */
-	rval = pci_enable_device(pdev);
+	rval = pci_enable_device_mem(pdev);
 
 	if (rval) {
 		printk(KERN_ERR "megasas: Enable device failed\n");
@@ -2873,6 +3335,8 @@ megasas_resume(struct pci_dev *pdev)
 		megasas_start_timer(instance, &instance->io_completion_timer,
 				megasas_io_completion_timer,
 				MEGASAS_COMPLETION_TIMER_INTERVAL);
+	instance->unload = 0;
+
 	return 0;
 
 fail_irq:
@@ -2913,6 +3377,7 @@ static void __devexit megasas_detach_one
 	struct megasas_instance *instance;
 
 	instance = pci_get_drvdata(pdev);
+	instance->unload = 1;
 	host = instance->host;
 
 	if (poll_mode_io)
@@ -2921,6 +3386,16 @@ static void __devexit megasas_detach_one
 	scsi_remove_host(instance->host);
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+
+	/* cancel the delayed work if this work still in queue*/
+	if (instance->ev != NULL) {
+		struct megasas_aen_event *ev = instance->ev;
+		cancel_delayed_work(
+			(struct delayed_work *)&ev->hotplug_work);
+		flush_scheduled_work();
+		instance->ev = NULL;
+	}
+
 	tasklet_kill(&instance->isr_tasklet);
 
 	/*
@@ -2969,6 +3444,7 @@ static void __devexit megasas_detach_one
 static void megasas_shutdown(struct pci_dev *pdev)
 {
 	struct megasas_instance *instance = pci_get_drvdata(pdev);
+	instance->unload = 1;
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 }
@@ -3016,6 +3492,23 @@ static int megasas_mgmt_fasync(int fd, s
 }
 
 /**
+ * megasas_mgmt_poll -  char node "poll" entry point
+ * */
+static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
+{
+	unsigned int mask;
+	unsigned long flags;
+	poll_wait(file, &megasas_poll_wait, wait);
+	spin_lock_irqsave(&poll_aen_lock, flags);
+	if (megasas_poll_wait_aen)
+		mask =   (POLLIN | POLLRDNORM);
+	else
+		mask = 0;
+	spin_unlock_irqrestore(&poll_aen_lock, flags);
+	return mask;
+}
+
+/**
  * megasas_mgmt_fw_ioctl -	Issues management ioctls to FW
  * @instance:			Adapter soft state
  * @argp:			User's ioctl packet
@@ -3032,7 +3525,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	int error = 0, i;
 	void *sense = NULL;
 	dma_addr_t sense_handle;
-	u32 *sense_ptr;
+	unsigned long *sense_ptr;
 
 	memset(kbuff_arr, 0, sizeof(kbuff_arr));
 
@@ -3056,6 +3549,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	 */
 	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
 	cmd->frame->hdr.context = cmd->index;
+	cmd->frame->hdr.pad_0 = 0;
 
 	/*
 	 * The management interface between applications and the fw uses
@@ -3109,7 +3603,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 		}
 
 		sense_ptr =
-		    (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
+		(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
 		*sense_ptr = sense_handle;
 	}
 
@@ -3140,8 +3634,8 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 		 * sense_ptr points to the location that has the user
 		 * sense buffer address
 		 */
-		sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
-				     ioc->sense_off);
+		sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
+				ioc->sense_off);
 
 		if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
 				 sense, ioc->sense_len)) {
@@ -3177,20 +3671,6 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	return error;
 }
 
-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
-{
-	int i;
-
-	for (i = 0; i < megasas_mgmt_info.max_index; i++) {
-
-		if ((megasas_mgmt_info.instance[i]) &&
-		    (megasas_mgmt_info.instance[i]->host->host_no == host_no))
-			return megasas_mgmt_info.instance[i];
-	}
-
-	return NULL;
-}
-
 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
 {
 	struct megasas_iocpacket __user *user_ioc =
@@ -3214,6 +3694,17 @@ static int megasas_mgmt_ioctl_fw(struct
 		goto out_kfree_ioc;
 	}
 
+	if (instance->hw_crit_error == 1) {
+		printk(KERN_DEBUG "Controller in Crit ERROR\n");
+		error = -ENODEV;
+		goto out_kfree_ioc;
+	}
+
+	if (instance->unload == 1) {
+		error = -ENODEV;
+		goto out_kfree_ioc;
+	}
+
 	/*
 	 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
 	 */
@@ -3249,6 +3740,14 @@ static int megasas_mgmt_ioctl_aen(struct
 	if (!instance)
 		return -ENODEV;
 
+	if (instance->hw_crit_error == 1) {
+		error = -ENODEV;
+	}
+
+	if (instance->unload == 1) {
+		return -ENODEV;
+	}
+
 	mutex_lock(&instance->aen_mutex);
 	error = megasas_register_aen(instance, aen.seq_num,
 				     aen.class_locale_word);
@@ -3282,6 +3781,7 @@ static int megasas_mgmt_compat_ioctl_fw(
 	    compat_alloc_user_space(sizeof(struct megasas_iocpacket));
 	int i;
 	int error = 0;
+	compat_uptr_t ptr;
 
 	if (clear_user(ioc, sizeof(*ioc)))
 		return -EFAULT;
@@ -3294,9 +3794,22 @@ static int megasas_mgmt_compat_ioctl_fw(
 	    copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
 		return -EFAULT;
 
-	for (i = 0; i < MAX_IOCTL_SGE; i++) {
-		compat_uptr_t ptr;
+	/*
+	 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
+	 * sense_len is not null, so prepare the 64bit value under
+	 * the same condition.
+	 */
+	if (ioc->sense_len) {
+		void __user **sense_ioc_ptr =
+			(void __user **)(ioc->frame.raw + ioc->sense_off);
+		compat_uptr_t *sense_cioc_ptr =
+			(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
+		if (get_user(ptr, sense_cioc_ptr) ||
+		    put_user(compat_ptr(ptr), sense_ioc_ptr))
+			return -EFAULT;
+	}
 
+	for (i = 0; i < MAX_IOCTL_SGE; i++) {
 		if (get_user(ptr, &cioc->sgl[i].iov_base) ||
 		    put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
 		    copy_in_user(&ioc->sgl[i].iov_len,
@@ -3337,6 +3850,7 @@ static const struct file_operations mega
 	.open = megasas_mgmt_open,
 	.fasync = megasas_mgmt_fasync,
 	.unlocked_ioctl = megasas_mgmt_ioctl,
+	.poll = megasas_mgmt_poll,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl = megasas_mgmt_compat_ioctl,
 #endif
@@ -3378,6 +3892,15 @@ static DRIVER_ATTR(release_date, S_IRUGO
 		   NULL);
 
 static ssize_t
+megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
+{
+	return sprintf(buf, "%u\n", support_poll_for_event);
+}
+
+static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
+			megasas_sysfs_show_support_poll_for_event, NULL);
+
+static ssize_t
 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
 {
 	return sprintf(buf, "%u\n", megasas_dbg_lvl);
@@ -3451,7 +3974,93 @@ out:
 	return retval;
 }
 
-static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
+static void
+megasas_aen_polling(struct work_struct *work)
+{
+	struct megasas_aen_event *ev =
+		container_of(work, struct megasas_aen_event, hotplug_work);
+	struct megasas_instance *instance = ev->instance;
+	union megasas_evt_class_locale class_locale;
+	struct  Scsi_Host *host;
+	struct  scsi_device *sdev1;
+	u16     pd_index = 0;
+	int     i, j, doscan = 0;
+	u32 seq_num;
+	int error;
+
+	if (!instance) {
+		printk(KERN_ERR "invalid instance!\n");
+		kfree(ev);
+		return;
+	}
+	instance->ev = NULL;
+	host = instance->host;
+	if (instance->evt_detail) {
+
+		switch (instance->evt_detail->code) {
+		case MR_EVT_PD_INSERTED:
+		case MR_EVT_PD_REMOVED:
+		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
+			doscan = 1;
+			break;
+		default:
+			doscan = 0;
+			break;
+		}
+	} else {
+		printk(KERN_ERR "invalid evt_detail!\n");
+		kfree(ev);
+		return;
+	}
+
+	if (doscan) {
+		printk(KERN_INFO "scanning ...\n");
+		megasas_get_pd_list(instance);
+		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
+				sdev1 = scsi_device_lookup(host, i, j, 0);
+				if (instance->pd_list[pd_index].driveState ==
+							MR_PD_STATE_SYSTEM) {
+					if (!sdev1) {
+						scsi_add_device(host, i, j, 0);
+					}
+					if (sdev1)
+						scsi_device_put(sdev1);
+				} else {
+					if (sdev1) {
+						scsi_remove_device(sdev1);
+						scsi_device_put(sdev1);
+					}
+				}
+			}
+		}
+	}
+
+	if ( instance->aen_cmd != NULL ) {
+		kfree(ev);
+		return ;
+	}
+
+	seq_num = instance->evt_detail->seq_num + 1;
+
+	/* Register AEN with FW for latest sequence number plus 1 */
+	class_locale.members.reserved = 0;
+	class_locale.members.locale = MR_EVT_LOCALE_ALL;
+	class_locale.members.class = MR_EVT_CLASS_DEBUG;
+	mutex_lock(&instance->aen_mutex);
+	error = megasas_register_aen(instance, seq_num,
+					class_locale.word);
+	mutex_unlock(&instance->aen_mutex);
+
+	if (error)
+		printk(KERN_ERR "register aen failed error %x\n", error);
+
+	kfree(ev);
+}
+
+
+static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR,
 		megasas_sysfs_show_poll_mode_io,
 		megasas_sysfs_set_poll_mode_io);
 
@@ -3468,6 +4077,8 @@ static int __init megasas_init(void)
 	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
 	       MEGASAS_EXT_VERSION);
 
+	support_poll_for_event = 2;
+
 	memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
 
 	/*
@@ -3500,6 +4111,12 @@ static int __init megasas_init(void)
 				  &driver_attr_release_date);
 	if (rval)
 		goto err_dcf_rel_date;
+
+	rval = driver_create_file(&megasas_pci_driver.driver,
+				&driver_attr_support_poll_for_event);
+	if (rval)
+		goto err_dcf_support_poll_for_event;
+
 	rval = driver_create_file(&megasas_pci_driver.driver,
 				  &driver_attr_dbg_lvl);
 	if (rval)
@@ -3516,7 +4133,12 @@ err_dcf_poll_mode_io:
 			   &driver_attr_dbg_lvl);
 err_dcf_dbg_lvl:
 	driver_remove_file(&megasas_pci_driver.driver,
+			&driver_attr_support_poll_for_event);
+
+err_dcf_support_poll_for_event:
+	driver_remove_file(&megasas_pci_driver.driver,
 			   &driver_attr_release_date);
+
 err_dcf_rel_date:
 	driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 err_dcf_attr_ver:
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_sas.h linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/megaraid/megaraid_sas.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/megaraid/megaraid_sas.h	2010-02-24 13:52:17.000000000 -0500
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.04.01"
-#define MEGASAS_RELDATE				"July 24, 2008"
-#define MEGASAS_EXT_VERSION			"Thu July 24 11:41:51 PST 2008"
+#define MEGASAS_VERSION				"00.00.04.12-rc1"
+#define MEGASAS_RELDATE				"Sep. 17, 2009"
+#define MEGASAS_EXT_VERSION			"Thu Sep. 17 11:41:51 PST 2009"
 
 /*
  * Device IDs
@@ -30,6 +30,8 @@
 #define	PCI_DEVICE_ID_LSI_VERDE_ZCR		0x0413
 #define	PCI_DEVICE_ID_LSI_SAS1078GEN2		0x0078
 #define	PCI_DEVICE_ID_LSI_SAS0079GEN2		0x0079
+#define	PCI_DEVICE_ID_LSI_SAS0073SKINNY		0x0073
+#define	PCI_DEVICE_ID_LSI_SAS0071SKINNY		0x0071
 
 /*
  * =====================================
@@ -94,6 +96,7 @@
 #define MFI_FRAME_DIR_WRITE			0x0008
 #define MFI_FRAME_DIR_READ			0x0010
 #define MFI_FRAME_DIR_BOTH			0x0018
+#define MFI_FRAME_IEEE                          0x0020
 
 /*
  * Definition for cmd_status
@@ -131,6 +134,7 @@
 #define MR_DCMD_CLUSTER				0x08000000
 #define MR_DCMD_CLUSTER_RESET_ALL		0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD		0x08010200
+#define MR_DCMD_PD_LIST_QUERY                   0x02010100
 
 /*
  * MFI command completion codes
@@ -251,9 +255,100 @@ enum MR_EVT_ARGS {
 	MR_EVT_ARGS_STR,
 	MR_EVT_ARGS_TIME,
 	MR_EVT_ARGS_ECC,
+	MR_EVT_ARGS_LD_PROP,
+	MR_EVT_ARGS_PD_SPARE,
+	MR_EVT_ARGS_PD_INDEX,
+	MR_EVT_ARGS_DIAG_PASS,
+	MR_EVT_ARGS_DIAG_FAIL,
+	MR_EVT_ARGS_PD_LBA_LBA,
+	MR_EVT_ARGS_PORT_PHY,
+	MR_EVT_ARGS_PD_MISSING,
+	MR_EVT_ARGS_PD_ADDRESS,
+	MR_EVT_ARGS_BITMAP,
+	MR_EVT_ARGS_CONNECTOR,
+	MR_EVT_ARGS_PD_PD,
+	MR_EVT_ARGS_PD_FRU,
+	MR_EVT_ARGS_PD_PATHINFO,
+	MR_EVT_ARGS_PD_POWER_STATE,
+	MR_EVT_ARGS_GENERIC,
+};
 
+/*
+ * define constants for device list query options
+ */
+enum MR_PD_QUERY_TYPE {
+	MR_PD_QUERY_TYPE_ALL                = 0,
+	MR_PD_QUERY_TYPE_STATE              = 1,
+	MR_PD_QUERY_TYPE_POWER_STATE        = 2,
+	MR_PD_QUERY_TYPE_MEDIA_TYPE         = 3,
+	MR_PD_QUERY_TYPE_SPEED              = 4,
+	MR_PD_QUERY_TYPE_EXPOSED_TO_HOST    = 5,
 };
 
+#define MR_EVT_CFG_CLEARED                              0x0004
+#define MR_EVT_LD_STATE_CHANGE                          0x0051
+#define MR_EVT_PD_INSERTED                              0x005b
+#define MR_EVT_PD_REMOVED                               0x0070
+#define MR_EVT_LD_CREATED                               0x008a
+#define MR_EVT_LD_DELETED                               0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED                     0x00db
+#define MR_EVT_LD_OFFLINE                               0x00fc
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED             0x0152
+#define MAX_LOGICAL_DRIVES				64
+
+enum MR_PD_STATE {
+	MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
+	MR_PD_STATE_UNCONFIGURED_BAD    = 0x01,
+	MR_PD_STATE_HOT_SPARE           = 0x02,
+	MR_PD_STATE_OFFLINE             = 0x10,
+	MR_PD_STATE_FAILED              = 0x11,
+	MR_PD_STATE_REBUILD             = 0x14,
+	MR_PD_STATE_ONLINE              = 0x18,
+	MR_PD_STATE_COPYBACK            = 0x20,
+	MR_PD_STATE_SYSTEM              = 0x40,
+ };
+
+
+ /*
+ * defines the physical drive address structure
+ */
+struct MR_PD_ADDRESS {
+	u16     deviceId;
+	u16     enclDeviceId;
+
+	union {
+		struct {
+			u8  enclIndex;
+			u8  slotNumber;
+		} mrPdAddress;
+		struct {
+			u8  enclPosition;
+			u8  enclConnectorIndex;
+		} mrEnclAddress;
+	};
+	u8      scsiDevType;
+	union {
+		u8      connectedPortBitmap;
+		u8      connectedPortNumbers;
+	};
+	u64     sasAddr[2];
+} __packed;
+
+/*
+ * defines the physical drive list structure
+ */
+struct MR_PD_LIST {
+	u32             size;
+	u32             count;
+	struct MR_PD_ADDRESS   addr[1];
+} __packed;
+
+struct megasas_pd_list {
+	u16             tid;
+	u8             driveType;
+	u8             driveState;
+} __packed;
+
 /*
  * SAS controller properties
  */
@@ -282,7 +377,7 @@ struct megasas_ctrl_prop {
 	u8 expose_encl_devices;
 	u8 reserved[38];
 
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * SAS controller information
@@ -525,7 +620,7 @@ struct megasas_ctrl_info {
 
 	u8 pad[0x800 - 0x6a0];
 
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * ===============================
@@ -540,6 +635,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_DEFAULT_INIT_ID			-1
 #define MEGASAS_MAX_LUN				8
 #define MEGASAS_MAX_LD				64
+#define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
+						MEGASAS_MAX_DEV_PER_CHANNEL)
 
 #define MEGASAS_DBG_LVL				1
 
@@ -570,6 +667,7 @@ struct megasas_ctrl_info {
  * is shown below
  */
 #define MEGASAS_INT_CMDS			32
+#define MEGASAS_SKINNY_INT_CMDS			5
 
 /*
  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
@@ -584,6 +682,8 @@ struct megasas_ctrl_info {
 #define MFI_REPLY_1078_MESSAGE_INTERRUPT	0x80000000
 #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT	0x00000001
 #define MFI_GEN2_ENABLE_INTERRUPT_MASK		(0x00000001 | 0x00000004)
+#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT	0x40000000
+#define MFI_SKINNY_ENABLE_INTERRUPT_MASK	(0x00000001)
 
 /*
 * register set for both 1068 and 1078 controllers
@@ -644,10 +744,17 @@ struct megasas_sge64 {
 
 } __attribute__ ((packed));
 
+struct megasas_sge_skinny {
+	u64 phys_addr;
+	u32 length;
+	u32 flag;
+} __packed;
+
 union megasas_sgl {
 
 	struct megasas_sge32 sge32[1];
 	struct megasas_sge64 sge64[1];
+	struct megasas_sge_skinny sge_skinny[1];
 
 } __attribute__ ((packed));
 
@@ -1061,16 +1168,10 @@ struct megasas_evt_detail {
 
 } __attribute__ ((packed));
 
- struct megasas_instance_template {
-	void (*fire_cmd)(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 *);
-
-	int (*clear_intr)(struct megasas_register_set __iomem *);
-
-	u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
- };
+struct megasas_aen_event {
+	struct work_struct hotplug_work;
+	struct megasas_instance *instance;
+};
 
 struct megasas_instance {
 
@@ -1085,17 +1186,21 @@ struct megasas_instance {
 	unsigned long base_addr;
 	struct megasas_register_set __iomem *reg_set;
 
+	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
 	s8 init_id;
 
 	u16 max_num_sge;
 	u16 max_fw_cmds;
 	u32 max_sectors_per_req;
+	struct megasas_aen_event *ev;
 
 	struct megasas_cmd **cmd_list;
 	struct list_head cmd_pool;
 	spinlock_t cmd_pool_lock;
 	/* used to synch producer, consumer ptrs in dpc */
 	spinlock_t completion_lock;
+	/* used to sync fire the cmd to fw */
+	spinlock_t fire_lock;
 	struct dma_pool *frame_dma_pool;
 	struct dma_pool *sense_dma_pool;
 
@@ -1120,11 +1225,25 @@ struct megasas_instance {
 	struct tasklet_struct isr_tasklet;
 
 	u8 flag;
+	u8 unload;
+	u8 flag_ieee;
 	unsigned long last_time;
 
 	struct timer_list io_completion_timer;
 };
 
+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 *);
+
+	int (*clear_intr)(struct megasas_register_set __iomem *);
+
+	u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
+};
+
 #define MEGASAS_IS_LOGICAL(scp)						\
 	(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/megaraid.h linux-libre-2.6.33-gnu1/drivers/scsi/megaraid.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/megaraid.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/megaraid.h	2010-02-24 13:52:17.000000000 -0500
@@ -381,7 +381,7 @@ typedef struct {
 	u8	battery_status;	/*
 				 * BIT 0: battery module missing
 				 * BIT 1: VBAD
-				 * BIT 2: temprature high
+				 * BIT 2: temperature high
 				 * BIT 3: battery pack missing
 				 * BIT 4,5:
 				 *   00 - charge complete
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  *          Title:  MPI Configuration messages and pages
  *  Creation Date:  November 10, 2006
  *
- *    mpi2_cnfg.h Version:  02.00.11
+ *    mpi2_cnfg.h Version:  02.00.12
  *
  *  Version History
  *  ---------------
@@ -100,6 +100,13 @@
  *                      Added expander reduced functionality data to SAS
  *                      Expander Page 0.
  *                      Added SAS PHY Page 2 and SAS PHY Page 3.
+ *  07-30-09  02.00.12  Added IO Unit Page 7.
+ *                      Added new device ids.
+ *                      Added SAS IO Unit Page 5.
+ *                      Added partial and slumber power management capable flags
+ *                      to SAS Device Page 0 Flags field.
+ *                      Added PhyInfo defines for power condition.
+ *                      Added Ethernet configuration pages.
  *  --------------------------------------------------------------------------
  */
 
@@ -182,6 +189,7 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEAD
 #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG         (0x16)
 #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING      (0x17)
 #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT            (0x18)
+#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET            (0x19)
 
 
 /*****************************************************************************
@@ -268,6 +276,14 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEAD
 #define MPI2_DPM_PGAD_START_ENTRY_MASK              (0x0000FFFF)
 
 
+/* Ethernet PageAddress format */
+#define MPI2_ETHERNET_PGAD_FORM_MASK                (0xF0000000)
+#define MPI2_ETHERNET_PGAD_FORM_IF_NUM              (0x00000000)
+
+#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK           (0x000000FF)
+
+
+
 /****************************************************************************
 *   Configuration messages
 ****************************************************************************/
@@ -349,6 +365,15 @@ typedef struct _MPI2_CONFIG_REPLY
 #define MPI2_MFGPAGE_DEVID_SAS2116_1                (0x0064)
 #define MPI2_MFGPAGE_DEVID_SAS2116_2                (0x0065)
 
+#define MPI2_MFGPAGE_DEVID_SAS2208_1                (0x0080)
+#define MPI2_MFGPAGE_DEVID_SAS2208_2                (0x0081)
+#define MPI2_MFGPAGE_DEVID_SAS2208_3                (0x0082)
+#define MPI2_MFGPAGE_DEVID_SAS2208_4                (0x0083)
+#define MPI2_MFGPAGE_DEVID_SAS2208_5                (0x0084)
+#define MPI2_MFGPAGE_DEVID_SAS2208_6                (0x0085)
+#define MPI2_MFGPAGE_DEVID_SAS2208_7                (0x0086)
+#define MPI2_MFGPAGE_DEVID_SAS2208_8                (0x0087)
+
 
 /* Manufacturing Page 0 */
 
@@ -787,6 +812,56 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT
 #define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR  (0x0001)
 
 
+/* IO Unit Page 7 */
+
+typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
+    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 0x00 */
+    U16                     Reserved1;                              /* 0x04 */
+    U8                      PCIeWidth;                              /* 0x06 */
+    U8                      PCIeSpeed;                              /* 0x07 */
+    U32                     ProcessorState;                         /* 0x08 */
+    U32                     Reserved2;                              /* 0x0C */
+    U16                     IOCTemperature;                         /* 0x10 */
+    U8                      IOCTemperatureUnits;                    /* 0x12 */
+    U8                      IOCSpeed;                               /* 0x13 */
+    U32                     Reserved3;                              /* 0x14 */
+} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
+  Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
+
+#define MPI2_IOUNITPAGE7_PAGEVERSION                    (0x00)
+
+/* defines for IO Unit Page 7 PCIeWidth field */
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1              (0x01)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2              (0x02)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4              (0x04)
+#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8              (0x08)
+
+/* defines for IO Unit Page 7 PCIeSpeed field */
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS        (0x00)
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS        (0x01)
+#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS        (0x02)
+
+/* defines for IO Unit Page 7 ProcessorState field */
+#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND         (0x0000000F)
+#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND        (0)
+
+#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT         (0x00)
+#define MPI2_IOUNITPAGE7_PSTATE_DISABLED            (0x01)
+#define MPI2_IOUNITPAGE7_PSTATE_ENABLED             (0x02)
+
+/* defines for IO Unit Page 7 IOCTemperatureUnits field */
+#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT       (0x00)
+#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT        (0x01)
+#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS           (0x02)
+
+/* defines for IO Unit Page 7 IOCSpeed field */
+#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL             (0x01)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF             (0x02)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER          (0x04)
+#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH           (0x08)
+
+
+
 /****************************************************************************
 *   IOC Config Pages
 ****************************************************************************/
@@ -1470,6 +1545,12 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDIS
 
 /* values for PhyInfo fields */
 #define MPI2_SAS_PHYINFO_PHY_VACANT                     (0x80000000)
+
+#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK       (0x18000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE               (0x00000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL              (0x08000000)
+#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER              (0x10000000)
+
 #define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS       (0x04000000)
 #define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT        (0x02000000)
 #define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS               (0x01000000)
@@ -1682,11 +1763,11 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
 /* values for SAS IO Unit Page 1 PortFlags */
 #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG                 (0x01)
 
-/* values for SAS IO Unit Page 2 PhyFlags */
+/* values for SAS IO Unit Page 1 PhyFlags */
 #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE                      (0x10)
 #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE                        (0x08)
 
-/* values for SAS IO Unit Page 0 MaxMinLinkRate */
+/* values for SAS IO Unit Page 1 MaxMinLinkRate */
 #define MPI2_SASIOUNIT1_MAX_RATE_MASK                               (0xF0)
 #define MPI2_SASIOUNIT1_MAX_RATE_1_5                                (0x80)
 #define MPI2_SASIOUNIT1_MAX_RATE_3_0                                (0x90)
@@ -1745,6 +1826,74 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUN
 #define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK               (0x03)
 
 
+/* SAS IO Unit Page 5 */
+
+typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS {
+    U8          ControlFlags;               /* 0x00 */
+    U8          Reserved1;                  /* 0x01 */
+    U16         InactivityTimerExponent;    /* 0x02 */
+    U8          SATAPartialTimeout;         /* 0x04 */
+    U8          Reserved2;                  /* 0x05 */
+    U8          SATASlumberTimeout;         /* 0x06 */
+    U8          Reserved3;                  /* 0x07 */
+    U8          SASPartialTimeout;          /* 0x08 */
+    U8          Reserved4;                  /* 0x09 */
+    U8          SASSlumberTimeout;          /* 0x0A */
+    U8          Reserved5;                  /* 0x0B */
+} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
+  MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS,
+  Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t;
+
+/* defines for ControlFlags field */
+#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE      (0x08)
+#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE      (0x04)
+#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE     (0x02)
+#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE     (0x01)
+
+/* defines for InactivityTimerExponent field */
+#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER            (0x7000)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER           (12)
+#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL            (0x0700)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL           (8)
+#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER           (0x0070)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER          (4)
+#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL           (0x0007)
+#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL          (0)
+
+#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS                 (7)
+#define MPI2_SASIOUNIT5_ITE_ONE_SECOND                  (6)
+#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS        (5)
+#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS            (4)
+#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND             (3)
+#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS        (2)
+#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS            (1)
+#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND             (0)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check Header.ExtPageLength or NumPhys at runtime.
+ */
+#ifndef MPI2_SAS_IOUNIT5_PHY_MAX
+#define MPI2_SAS_IOUNIT5_PHY_MAX        (1)
+#endif
+
+typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;		/* 0x00 */
+    U8                                  NumPhys;	/* 0x08 */
+    U8                                  Reserved1;	/* 0x09 */
+    U16                                 Reserved2;	/* 0x0A */
+    U32                                 Reserved3;	/* 0x0C */
+    MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS   SASPhyPowerManagementSettings
+					[MPI2_SAS_IOUNIT5_PHY_MAX];  /* 0x10 */
+} MPI2_CONFIG_PAGE_SASIOUNIT_5,
+  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5,
+  Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t;
+
+#define MPI2_SASIOUNITPAGE5_PAGEVERSION     (0x00)
+
+
+
+
 /****************************************************************************
 *   SAS Expander Config Pages
 ****************************************************************************/
@@ -1927,6 +2076,8 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV
 /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
 
 /* values for SAS Device Page 0 Flags field */
+#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE           (0x1000)
+#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE           (0x0800)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY     (0x0400)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE             (0x0200)
 #define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE           (0x0100)
@@ -2343,5 +2494,122 @@ typedef struct _MPI2_CONFIG_PAGE_DRIVER_
 #define MPI2_DRVMAP0_MAPINFO_MISSING_MASK           (0x000F)
 
 
+/****************************************************************************
+*   Ethernet Config Pages
+****************************************************************************/
+
+/* Ethernet Page 0 */
+
+/* IP address (union of IPv4 and IPv6) */
+typedef union _MPI2_ETHERNET_IP_ADDR {
+    U32     IPv4Addr;
+    U32     IPv6Addr[4];
+} MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR,
+  Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t;
+
+#define MPI2_ETHERNET_HOST_NAME_LENGTH          (32)
+
+typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
+    U8                                  NumInterfaces;          /* 0x08 */
+    U8                                  Reserved0;              /* 0x09 */
+    U16                                 Reserved1;              /* 0x0A */
+    U32                                 Status;                 /* 0x0C */
+    U8                                  MediaState;             /* 0x10 */
+    U8                                  Reserved2;              /* 0x11 */
+    U16                                 Reserved3;              /* 0x12 */
+    U8                                  MacAddress[6];          /* 0x14 */
+    U8                                  Reserved4;              /* 0x1A */
+    U8                                  Reserved5;              /* 0x1B */
+    MPI2_ETHERNET_IP_ADDR               IpAddress;              /* 0x1C */
+    MPI2_ETHERNET_IP_ADDR               SubnetMask;             /* 0x2C */
+    MPI2_ETHERNET_IP_ADDR               GatewayIpAddress;       /* 0x3C */
+    MPI2_ETHERNET_IP_ADDR               DNS1IpAddress;          /* 0x4C */
+    MPI2_ETHERNET_IP_ADDR               DNS2IpAddress;          /* 0x5C */
+    MPI2_ETHERNET_IP_ADDR               DhcpIpAddress;          /* 0x6C */
+    U8                                  HostName
+				[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
+} MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0,
+  Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t;
+
+#define MPI2_ETHERNETPAGE0_PAGEVERSION   (0x00)
+
+/* values for Ethernet Page 0 Status field */
+#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE             (0x80000000)
+#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE             (0x40000000)
+#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED        (0x20000000)
+#define MPI2_ETHPG0_STATUS_DEFAULT_IF               (0x00000100)
+#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED         (0x00000080)
+#define MPI2_ETHPG0_STATUS_TELNET_ENABLED           (0x00000040)
+#define MPI2_ETHPG0_STATUS_SSH2_ENABLED             (0x00000020)
+#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED      (0x00000010)
+#define MPI2_ETHPG0_STATUS_IPV6_ENABLED             (0x00000008)
+#define MPI2_ETHPG0_STATUS_IPV4_ENABLED             (0x00000004)
+#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES           (0x00000002)
+#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED           (0x00000001)
+
+/* values for Ethernet Page 0 MediaState field */
+#define MPI2_ETHPG0_MS_DUPLEX_MASK                  (0x80)
+#define MPI2_ETHPG0_MS_HALF_DUPLEX                  (0x00)
+#define MPI2_ETHPG0_MS_FULL_DUPLEX                  (0x80)
+
+#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK           (0x07)
+#define MPI2_ETHPG0_MS_NOT_CONNECTED                (0x00)
+#define MPI2_ETHPG0_MS_10MBIT                       (0x01)
+#define MPI2_ETHPG0_MS_100MBIT                      (0x02)
+#define MPI2_ETHPG0_MS_1GBIT                        (0x03)
+
+
+/* Ethernet Page 1 */
+
+typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 {
+    MPI2_CONFIG_EXTENDED_PAGE_HEADER    Header;                 /* 0x00 */
+    U32                                 Reserved0;              /* 0x08 */
+    U32                                 Flags;                  /* 0x0C */
+    U8                                  MediaState;             /* 0x10 */
+    U8                                  Reserved1;              /* 0x11 */
+    U16                                 Reserved2;              /* 0x12 */
+    U8                                  MacAddress[6];          /* 0x14 */
+    U8                                  Reserved3;              /* 0x1A */
+    U8                                  Reserved4;              /* 0x1B */
+    MPI2_ETHERNET_IP_ADDR               StaticIpAddress;        /* 0x1C */
+    MPI2_ETHERNET_IP_ADDR               StaticSubnetMask;       /* 0x2C */
+    MPI2_ETHERNET_IP_ADDR               StaticGatewayIpAddress; /* 0x3C */
+    MPI2_ETHERNET_IP_ADDR               StaticDNS1IpAddress;    /* 0x4C */
+    MPI2_ETHERNET_IP_ADDR               StaticDNS2IpAddress;    /* 0x5C */
+    U32                                 Reserved5;              /* 0x6C */
+    U32                                 Reserved6;              /* 0x70 */
+    U32                                 Reserved7;              /* 0x74 */
+    U32                                 Reserved8;              /* 0x78 */
+    U8                                  HostName
+				[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */
+} MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1,
+  Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t;
+
+#define MPI2_ETHERNETPAGE1_PAGEVERSION   (0x00)
+
+/* values for Ethernet Page 1 Flags field */
+#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF             (0x00000100)
+#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD         (0x00000080)
+#define MPI2_ETHPG1_FLAG_ENABLE_TELNET              (0x00000040)
+#define MPI2_ETHPG1_FLAG_ENABLE_SSH2                (0x00000020)
+#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT         (0x00000010)
+#define MPI2_ETHPG1_FLAG_ENABLE_IPV6                (0x00000008)
+#define MPI2_ETHPG1_FLAG_ENABLE_IPV4                (0x00000004)
+#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES         (0x00000002)
+#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF              (0x00000001)
+
+/* values for Ethernet Page 1 MediaState field */
+#define MPI2_ETHPG1_MS_DUPLEX_MASK                  (0x80)
+#define MPI2_ETHPG1_MS_HALF_DUPLEX                  (0x00)
+#define MPI2_ETHPG1_MS_FULL_DUPLEX                  (0x80)
+
+#define MPI2_ETHPG1_MS_DATA_RATE_MASK               (0x07)
+#define MPI2_ETHPG1_MS_DATA_RATE_AUTO               (0x00)
+#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT             (0x01)
+#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT            (0x02)
+#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT              (0x03)
+
+
 #endif
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2.h	2010-02-24 13:52:17.000000000 -0500
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.12
+ *  mpi2.h Version:  02.00.13
  *
  *  Version History
  *  ---------------
@@ -52,6 +52,7 @@
  *                      MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
  *                      bytes reserved.
  *                      Added RAID Accelerator functionality.
+ *  07-30-09  02.00.13  Bumped MPI2_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
@@ -77,7 +78,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x0C)
+#define MPI2_HEADER_VERSION_UNIT            (0x0D)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2010-02-24 13:52:17.000000000 -0500
@@ -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.11
+ *  mpi2_ioc.h Version:  02.00.12
  *
  *  Version History
  *  ---------------
@@ -84,6 +84,9 @@
  *                      Added two new reason codes for SAS Device Status Change
  *                      Event.
  *                      Added new event: SAS PHY Counter.
+ *  07-30-09  02.00.12  Added GPIO Interrupt event define and structure.
+ *                      Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
+ *                      Added new product id family for 2208.
  *  --------------------------------------------------------------------------
  */
 
@@ -274,6 +277,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
 #define MPI2_IOCFACTS_CAPABILITY_MULTICAST              (0x00000100)
 #define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET   (0x00000080)
 #define MPI2_IOCFACTS_CAPABILITY_EEDP                   (0x00000040)
+#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER        (0x00000020)
 #define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER        (0x00000010)
 #define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER      (0x00000008)
 #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
@@ -448,6 +452,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_
 #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST     (0x0020)
 #define MPI2_EVENT_LOG_ENTRY_ADDED                  (0x0021)
 #define MPI2_EVENT_SAS_PHY_COUNTER                  (0x0022)
+#define MPI2_EVENT_GPIO_INTERRUPT                   (0x0023)
 
 
 /* Log Entry Added Event data */
@@ -469,6 +474,16 @@ typedef struct _MPI2_EVENT_DATA_LOG_ENTR
   MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
   Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t;
 
+/* GPIO Interrupt Event data */
+
+typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
+    U8          GPIONum;                            /* 0x00 */
+    U8          Reserved1;                          /* 0x01 */
+    U16         Reserved2;                          /* 0x02 */
+} MPI2_EVENT_DATA_GPIO_INTERRUPT,
+  MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
+  Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
+
 /* Hard Reset Received Event data */
 
 typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -1117,6 +1132,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER
 #define MPI2_FW_HEADER_PID_FAMILY_MASK          (0x00FF)
 /* SAS */
 #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS      (0x0010)
+#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS      (0x0011)
 
 /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_raid.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_raid.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_raid.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  *          Title:  MPI Integrated RAID messages and structures
  *  Creation Date:  April 26, 2007
  *
- *    mpi2_raid.h Version:  02.00.03
+ *    mpi2_raid.h Version:  02.00.04
  *
  *  Version History
  *  ---------------
@@ -20,6 +20,8 @@
  *  05-21-08  02.00.03  Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
  *                      the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
  *                      can be sized by the build environment.
+ *  07-30-09  02.00.04  Added proper define for the Use Default Settings bit of
+ *                      VolumeCreationFlags and marked the old one as obsolete.
  *  --------------------------------------------------------------------------
  */
 
@@ -217,10 +219,14 @@ typedef struct _MPI2_RAID_VOLUME_CREATIO
 /* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
 
 /* defines for the VolumeCreationFlags field */
+#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS     (0x80000000)
+#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT      (0x00000004)
+#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT       (0x00000002)
+#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA         (0x00000001)
+/* The following is an obsolete define.
+ * It must be shifted left 24 bits in order to set the proper bit.
+ */
 #define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
-#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT      (0x04)
-#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT       (0x02)
-#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA         (0x01)
 
 
 /* RAID Online Capacity Expansion Structure */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_tool.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_tool.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpi/mpi2_tool.h	2010-02-24 13:52:17.000000000 -0500
@@ -6,7 +6,7 @@
  *          Title:  MPI diagnostic tool structures and definitions
  *  Creation Date:  March 26, 2007
  *
- *    mpi2_tool.h Version:  02.00.03
+ *    mpi2_tool.h Version:  02.00.04
  *
  *  Version History
  *  ---------------
@@ -18,6 +18,10 @@
  *                      structures and defines.
  *  02-29-08  02.00.02  Modified various names to make them 32-character unique.
  *  05-06-09  02.00.03  Added ISTWI Read Write Tool and Diagnostic CLI Tool.
+ *  07-30-09  02.00.04  Added ExtendedType field to DiagnosticBufferPost request
+ *                      and reply messages.
+ *                      Added MPI2_DIAG_BUF_TYPE_EXTENDED.
+ *                      Incremented MPI2_DIAG_BUF_TYPE_COUNT.
  *  --------------------------------------------------------------------------
  */
 
@@ -282,7 +286,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_
 
 typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
 {
-    U8                      Reserved1;                  /* 0x00 */
+    U8                      ExtendedType;               /* 0x00 */
     U8                      BufferType;                 /* 0x01 */
     U8                      ChainOffset;                /* 0x02 */
     U8                      Function;                   /* 0x03 */
@@ -301,11 +305,15 @@ typedef struct _MPI2_DIAG_BUFFER_POST_RE
 } MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
   Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
 
+/* values for the ExtendedType field */
+#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION         (0x02)
+
 /* values for the BufferType field */
 #define MPI2_DIAG_BUF_TYPE_TRACE                    (0x00)
 #define MPI2_DIAG_BUF_TYPE_SNAPSHOT                 (0x01)
+#define MPI2_DIAG_BUF_TYPE_EXTENDED                 (0x02)
 /* count of the number of buffer types */
-#define MPI2_DIAG_BUF_TYPE_COUNT                    (0x02)
+#define MPI2_DIAG_BUF_TYPE_COUNT                    (0x03)
 
 
 /****************************************************************************
@@ -314,7 +322,7 @@ typedef struct _MPI2_DIAG_BUFFER_POST_RE
 
 typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
 {
-    U8                      Reserved1;                  /* 0x00 */
+    U8                      ExtendedType;               /* 0x00 */
     U8                      BufferType;                 /* 0x01 */
     U8                      MsgLength;                  /* 0x02 */
     U8                      Function;                   /* 0x03 */
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2010-02-24 13:52:17.000000000 -0500
@@ -57,6 +57,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/sort.h>
 #include <linux/io.h>
+#include <linux/time.h>
 
 #include "mpt2sas_base.h"
 
@@ -77,6 +78,44 @@ static int msix_disable = -1;
 module_param(msix_disable, int, 0);
 MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
 
+/* diag_buffer_enable is bitwise
+ * bit 0 set = TRACE
+ * bit 1 set = SNAPSHOT
+ * bit 2 set = EXTENDED
+ *
+ * Either bit can be set, or both
+ */
+static int diag_buffer_enable;
+module_param(diag_buffer_enable, int, 0);
+MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
+    "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
+
+int mpt2sas_fwfault_debug;
+MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
+    "and halt firmware - (default=0)");
+
+/**
+ * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
+ *
+ */
+static int
+_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
+{
+	int ret = param_set_int(val, kp);
+	struct MPT2SAS_ADAPTER *ioc;
+
+	if (ret)
+		return ret;
+
+	printk(KERN_INFO "setting logging_level(0x%08x)\n",
+				mpt2sas_fwfault_debug);
+	list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
+		ioc->fwfault_debug = mpt2sas_fwfault_debug;
+	return 0;
+}
+module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug,
+    param_get_int, &mpt2sas_fwfault_debug, 0644);
+
 /**
  * _base_fault_reset_work - workq handling ioc fault conditions
  * @work: input argument, used to derive ioc
@@ -121,7 +160,7 @@ _base_fault_reset_work(struct work_struc
 
 /**
  * mpt2sas_base_start_watchdog - start the fault_reset_work_q
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * Context: sleep.
  *
  * Return nothing.
@@ -155,7 +194,7 @@ mpt2sas_base_start_watchdog(struct MPT2S
 
 /**
  * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * Context: sleep.
  *
  * Return nothing.
@@ -177,10 +216,55 @@ mpt2sas_base_stop_watchdog(struct MPT2SA
 	}
 }
 
+/**
+ * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
+ * @ioc: per adapter object
+ * @fault_code: fault code
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
+{
+	printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
+	    ioc->name, fault_code);
+}
+
+/**
+ * mpt2sas_halt_firmware - halt's mpt controller firmware
+ * @ioc: per adapter object
+ *
+ * For debugging timeout related issues.  Writing 0xCOFFEE00
+ * to the doorbell register will halt controller firmware. With
+ * the purpose to stop both driver and firmware, the enduser can
+ * obtain a ring buffer from controller UART.
+ */
+void
+mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc)
+{
+	u32 doorbell;
+
+	if (!ioc->fwfault_debug)
+		return;
+
+	dump_stack();
+
+	doorbell = readl(&ioc->chip->Doorbell);
+	if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
+		mpt2sas_base_fault_info(ioc , doorbell);
+	else {
+		writel(0xC0FFEE00, &ioc->chip->Doorbell);
+		printk(MPT2SAS_ERR_FMT "Firmware is halted due to command "
+		    "timeout\n", ioc->name);
+	}
+
+	panic("panic in %s\n", __func__);
+}
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _base_sas_ioc_info - verbose translation of the ioc status
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  * @request_hdr: request mf
  *
@@ -394,7 +478,7 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTE
 
 /**
  * _base_display_event_data - verbose translation of firmware asyn events
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  *
  * Return nothing.
@@ -474,7 +558,7 @@ _base_display_event_data(struct MPT2SAS_
 
 /**
  * _base_sas_log_info - verbose translation of firmware log info
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @log_info: log info
  *
  * Return nothing.
@@ -526,22 +610,8 @@ _base_sas_log_info(struct MPT2SAS_ADAPTE
 }
 
 /**
- * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
- * @ioc: pointer to scsi command object
- * @fault_code: fault code
- *
- * Return nothing.
- */
-void
-mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
-{
-	printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
-	    ioc->name, fault_code);
-}
-
-/**
  * _base_display_reply_info -
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @smid: system request message index
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
@@ -570,7 +640,7 @@ _base_display_reply_info(struct MPT2SAS_
 
 /**
  * mpt2sas_base_done - base internal command completion routine
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @smid: system request message index
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
@@ -603,7 +673,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER
 
 /**
  * _base_async_event - main callback handler for firmware asyn events
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
  *
@@ -684,7 +754,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER
 
 /**
  * _base_mask_interrupts - disable interrupts
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  *
  * Disabling ResetIRQ, Reply and Doorbell Interrupts
  *
@@ -704,7 +774,7 @@ _base_mask_interrupts(struct MPT2SAS_ADA
 
 /**
  * _base_unmask_interrupts - enable interrupts
- * @ioc: pointer to scsi command object
+ * @ioc: per adapter object
  *
  * Enabling only Reply Interrupts
  *
@@ -1258,12 +1328,13 @@ mpt2sas_base_get_sense_buffer(struct MPT
  * @ioc: per adapter object
  * @smid: system request message index
  *
- * Returns phys pointer to sense buffer.
+ * Returns phys pointer to the low 32bit address of the sense buffer.
  */
-dma_addr_t
+__le32
 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
 {
-	return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE);
+	return cpu_to_le32(ioc->sense_dma +
+			((smid - 1) * SCSI_SENSE_BUFFERSIZE));
 }
 
 /**
@@ -1697,6 +1768,12 @@ _base_display_ioc_capabilities(struct MP
 	}
 
 	if (ioc->facts.IOCCapabilities &
+	    MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
+		printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : "");
+		i++;
+	}
+
+	if (ioc->facts.IOCCapabilities &
 	    MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
 		printk("%sTask Set Full", i ? "," : "");
 		i++;
@@ -2871,6 +2948,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPT
 	Mpi2IOCInitRequest_t mpi_request;
 	Mpi2IOCInitReply_t mpi_reply;
 	int r;
+	struct timeval current_time;
+	u16 ioc_status;
 
 	dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
@@ -2921,6 +3000,13 @@ _base_send_ioc_init(struct MPT2SAS_ADAPT
 	    cpu_to_le32(ioc->reply_post_free_dma);
 #endif
 
+	/* This time stamp specifies number of milliseconds
+	 * since epoch ~ midnight January 1, 1970.
+	 */
+	do_gettimeofday(&current_time);
+	mpi_request.TimeStamp = (current_time.tv_sec * 1000) +
+	    (current_time.tv_usec >> 3);
+
 	if (ioc->logging_level & MPT_DEBUG_INIT) {
 		u32 *mfp;
 		int i;
@@ -2943,7 +3029,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPT
 		return r;
 	}
 
-	if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS ||
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS ||
 	    mpi_reply.IOCLogInfo) {
 		printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__);
 		r = -EIO;
@@ -3461,11 +3548,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 		return r;
 
 	pci_set_drvdata(ioc->pdev, ioc->shost);
-	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
+	r = _base_get_ioc_facts(ioc, CAN_SLEEP);
 	if (r)
 		goto out_free_resources;
 
-	r = _base_get_ioc_facts(ioc, CAN_SLEEP);
+	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
 	if (r)
 		goto out_free_resources;
 
@@ -3496,6 +3583,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 	ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
 	mutex_init(&ioc->transport_cmds.mutex);
 
+	/* scsih internal command bits */
+	ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
+	ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
+	mutex_init(&ioc->scsih_cmds.mutex);
+
 	/* task management internal command bits */
 	ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
 	ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
@@ -3531,6 +3623,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 		goto out_free_resources;
 
 	mpt2sas_base_start_watchdog(ioc);
+	if (diag_buffer_enable != 0)
+		mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
 	return 0;
 
  out_free_resources:
@@ -3684,6 +3778,9 @@ mpt2sas_base_hard_reset_handler(struct M
 	dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
 	    __func__));
 
+	if (mpt2sas_fwfault_debug)
+		mpt2sas_halt_firmware(ioc);
+
 	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
 	if (ioc->shost_recovery) {
 		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2010-02-24 13:52:17.000000000 -0500
@@ -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		"02.100.03.00"
-#define MPT2SAS_MAJOR_VERSION		02
+#define MPT2SAS_DRIVER_VERSION		"03.100.03.00"
+#define MPT2SAS_MAJOR_VERSION		03
 #define MPT2SAS_MINOR_VERSION		100
 #define MPT2SAS_BUILD_VERSION		03
 #define MPT2SAS_RELEASE_VERSION		00
@@ -278,7 +278,7 @@ struct _internal_cmd {
  * @sas_address: device sas address
  * @device_name: retrieved from the SAS IDENTIFY frame.
  * @handle: device handle
- * @parent_handle: handle to parent device
+ * @sas_address_parent: sas address of parent expander or sas host
  * @enclosure_handle: enclosure handle
  * @enclosure_logical_id: enclosure logical identifier
  * @volume_handle: volume handle (valid when hidden raid member)
@@ -296,7 +296,7 @@ struct _sas_device {
 	u64	sas_address;
 	u64	device_name;
 	u16	handle;
-	u16	parent_handle;
+	u64	sas_address_parent;
 	u16	enclosure_handle;
 	u64	enclosure_logical_id;
 	u16	volume_handle;
@@ -352,8 +352,6 @@ struct _boot_device {
 /**
  * struct _sas_port - wide/narrow sas port information
  * @port_list: list of ports belonging to expander
- * @handle: device handle for this port
- * @sas_address: sas address of this port
  * @num_phys: number of phys belonging to this port
  * @remote_identify: attached device identification
  * @rphy: sas transport rphy object
@@ -362,8 +360,6 @@ struct _boot_device {
  */
 struct _sas_port {
 	struct list_head port_list;
-	u16	handle;
-	u64	sas_address;
 	u8	num_phys;
 	struct sas_identify remote_identify;
 	struct sas_rphy *rphy;
@@ -398,7 +394,7 @@ struct _sas_phy {
  * @num_phys: number phys belonging to this sas_host/expander
  * @sas_address: sas address of this sas_host/expander
  * @handle: handle for this sas_host/expander
- * @parent_handle: parent handle
+ * @sas_address_parent: sas address of parent expander or sas host
  * @enclosure_handle: handle for this a member of an enclosure
  * @device_info: bitwise defining capabilities of this sas_host/expander
  * @responding: used in _scsih_expander_device_mark_responding
@@ -411,7 +407,7 @@ struct _sas_node {
 	u8	num_phys;
 	u64	sas_address;
 	u16	handle;
-	u16	parent_handle;
+	u64	sas_address_parent;
 	u16	enclosure_handle;
 	u64	enclosure_logical_id;
 	u8	responding;
@@ -470,6 +466,7 @@ typedef void (*MPT_ADD_SGE)(void *paddr,
  * @chip_phys: physical addrss prior to mapping
  * @pio_chip: I/O mapped register space
  * @logging_level: see mpt2sas_debug.h
+ * @fwfault_debug: debuging FW timeouts
  * @ir_firmware: IR firmware present
  * @bars: bitmask of BAR's that must be configured
  * @mask_interrupts: ignore interrupt
@@ -495,12 +492,14 @@ typedef void (*MPT_ADD_SGE)(void *paddr,
  * @msix_table_backup: backup msix table
  * @scsi_io_cb_idx: shost generated commands
  * @tm_cb_idx: task management commands
+ * @scsih_cb_idx: scsih internal commands
  * @transport_cb_idx: transport internal commands
  * @ctl_cb_idx: clt internal commands
  * @base_cb_idx: base internal commands
  * @config_cb_idx: base internal commands
  * @base_cmds:
  * @transport_cmds:
+ * @scsih_cmds:
  * @tm_cmds:
  * @ctl_cmds:
  * @config_cmds:
@@ -591,6 +590,7 @@ struct MPT2SAS_ADAPTER {
 	unsigned long	chip_phys;
 	unsigned long	pio_chip;
 	int		logging_level;
+	int		fwfault_debug;
 	u8		ir_firmware;
 	int		bars;
 	u8		mask_interrupts;
@@ -626,6 +626,7 @@ struct MPT2SAS_ADAPTER {
 	u8		scsi_io_cb_idx;
 	u8		tm_cb_idx;
 	u8		transport_cb_idx;
+	u8		scsih_cb_idx;
 	u8		ctl_cb_idx;
 	u8		base_cb_idx;
 	u8		config_cb_idx;
@@ -633,6 +634,7 @@ struct MPT2SAS_ADAPTER {
 	u8		tm_sas_control_cb_idx;
 	struct _internal_cmd base_cmds;
 	struct _internal_cmd transport_cmds;
+	struct _internal_cmd scsih_cmds;
 	struct _internal_cmd tm_cmds;
 	struct _internal_cmd ctl_cmds;
 	struct _internal_cmd config_cmds;
@@ -773,7 +775,7 @@ int mpt2sas_base_hard_reset_handler(stru
 void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
 void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
 void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
-dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
+__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
     u16 smid);
 
 /* hi-priority queue */
@@ -807,6 +809,8 @@ int mpt2sas_base_scsi_enclosure_processo
     Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
 void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
 
+void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
+
 /* scsih shared API */
 u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
     u32 reply);
@@ -886,19 +890,22 @@ u8 mpt2sas_ctl_event_callback(struct MPT
 void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
     Mpi2EventNotificationReply_t *mpi_reply);
 
+void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
+	u8 bits_to_regsiter);
+
 /* transport shared API */
 u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
     u32 reply);
 struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
-    u16 handle, u16 parent_handle);
+     u16 handle, u64 sas_address);
 void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u16 parent_handle);
+     u64 sas_address_parent);
 int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
 int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
-void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-   u16 attached_handle, u8 phy_number, u8 link_rate);
+void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
+     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate);
 extern struct sas_function_template mpt2sas_transport_functions;
 extern struct scsi_transport_template *mpt2sas_transport_template;
 extern int scsi_internal_device_block(struct scsi_device *sdev);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -740,7 +740,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPT
 		Mpi2SCSIIORequest_t *scsiio_request =
 		    (Mpi2SCSIIORequest_t *)mpi_request;
 		scsiio_request->SenseBufferLowAddress =
-		    (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
+		    mpt2sas_base_get_sense_buffer_dma(ioc, smid);
 		priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
 		memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
 		mpt2sas_base_put_smid_scsi_io(ioc, smid,
@@ -848,8 +848,9 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPT
 		printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
 		    "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
 		    "TerminationCount(0x%08x)\n", ioc->name,
-		    tm_reply->IOCStatus, tm_reply->IOCLogInfo,
-		    tm_reply->TerminationCount);
+		    le16_to_cpu(tm_reply->IOCStatus),
+		    le32_to_cpu(tm_reply->IOCLogInfo),
+		    le32_to_cpu(tm_reply->TerminationCount));
 	}
 #endif
 	/* copy out xdata to user */
@@ -896,6 +897,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPT
 			printk(MPT2SAS_INFO_FMT "issue target reset: handle "
 			    "= (0x%04x)\n", ioc->name,
 			    mpi_request->FunctionDependent1);
+			mpt2sas_halt_firmware(ioc);
 			mutex_lock(&ioc->tm_cmds.mutex);
 			mpt2sas_scsih_issue_tm(ioc,
 			    mpi_request->FunctionDependent1, 0,
@@ -1229,7 +1231,7 @@ _ctl_btdh_mapping(void __user *arg)
 /**
  * _ctl_diag_capability - return diag buffer capability
  * @ioc: per adapter object
- * @buffer_type: specifies either TRACE or SNAPSHOT
+ * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED
  *
  * returns 1 when diag buffer support is enabled in firmware
  */
@@ -1249,24 +1251,25 @@ _ctl_diag_capability(struct MPT2SAS_ADAP
 		    MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
 			rc = 1;
 		break;
+	case MPI2_DIAG_BUF_TYPE_EXTENDED:
+		if (ioc->facts.IOCCapabilities &
+		    MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
+			rc = 1;
 	}
 
 	return rc;
 }
 
 /**
- * _ctl_diag_register - application register with driver
- * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
+ * _ctl_diag_register_2 - wrapper for registering diag buffer support
+ * @ioc: per adapter object
+ * @diag_register: the diag_register struct passed in from user space
  *
- * This will allow the driver to setup any required buffers that will be
- * needed by firmware to communicate with the driver.
  */
 static long
-_ctl_diag_register(void __user *arg, enum block_state state)
+_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
+    struct mpt2_diag_register *diag_register)
 {
-	struct mpt2_diag_register karg;
-	struct MPT2SAS_ADAPTER *ioc;
 	int rc, i;
 	void *request_data = NULL;
 	dma_addr_t request_data_dma;
@@ -1279,18 +1282,17 @@ _ctl_diag_register(void __user *arg, enu
 	u16 ioc_status;
 	u8 issue_reset = 0;
 
-	if (copy_from_user(&karg, arg, sizeof(karg))) {
-		printk(KERN_ERR "failure at %s:%d/%s()!\n",
-		    __FILE__, __LINE__, __func__);
-		return -EFAULT;
-	}
-	if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-		return -ENODEV;
-
 	dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
 
-	buffer_type = karg.buffer_type;
+	if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
+		printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
+		    ioc->name, __func__);
+		rc = -EAGAIN;
+		goto out;
+	}
+
+	buffer_type = diag_register->buffer_type;
 	if (!_ctl_diag_capability(ioc, buffer_type)) {
 		printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
 		    "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
@@ -1305,24 +1307,12 @@ _ctl_diag_register(void __user *arg, enu
 		return -EINVAL;
 	}
 
-	if (karg.requested_buffer_size % 4)  {
+	if (diag_register->requested_buffer_size % 4)  {
 		printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
 		    "is not 4 byte aligned\n", ioc->name, __func__);
 		return -EINVAL;
 	}
 
-	if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-		return -EAGAIN;
-	else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-		return -ERESTARTSYS;
-
-	if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
-		printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
-		    ioc->name, __func__);
-		rc = -EAGAIN;
-		goto out;
-	}
-
 	smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
 	if (!smid) {
 		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
@@ -1338,12 +1328,12 @@ _ctl_diag_register(void __user *arg, enu
 	ioc->ctl_cmds.smid = smid;
 
 	request_data = ioc->diag_buffer[buffer_type];
-	request_data_sz = karg.requested_buffer_size;
-	ioc->unique_id[buffer_type] = karg.unique_id;
+	request_data_sz = diag_register->requested_buffer_size;
+	ioc->unique_id[buffer_type] = diag_register->unique_id;
 	ioc->diag_buffer_status[buffer_type] = 0;
-	memcpy(ioc->product_specific[buffer_type], karg.product_specific,
-	    MPT2_PRODUCT_SPECIFIC_DWORDS);
-	ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags;
+	memcpy(ioc->product_specific[buffer_type],
+	    diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
+	ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
 
 	if (request_data) {
 		request_data_dma = ioc->diag_buffer_dma[buffer_type];
@@ -1373,8 +1363,8 @@ _ctl_diag_register(void __user *arg, enu
 	}
 
 	mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
-	mpi_request->BufferType = karg.buffer_type;
-	mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags);
+	mpi_request->BufferType = diag_register->buffer_type;
+	mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
 	mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
 	mpi_request->BufferLength = cpu_to_le32(request_data_sz);
 	mpi_request->VF_ID = 0; /* TODO */
@@ -1422,7 +1412,7 @@ _ctl_diag_register(void __user *arg, enu
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -1438,6 +1428,83 @@ _ctl_diag_register(void __user *arg, enu
 		    request_data, request_data_dma);
 
 	ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
+	return rc;
+}
+
+/**
+ * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
+ * @ioc: per adapter object
+ * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
+ *
+ * This is called when command line option diag_buffer_enable is enabled
+ * at driver load time.
+ */
+void
+mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
+{
+	struct mpt2_diag_register diag_register;
+
+	memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
+
+	if (bits_to_register & 1) {
+		printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
+		/* register for 1MB buffers  */
+		diag_register.requested_buffer_size = (1024 * 1024);
+		diag_register.unique_id = 0x7075900;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+
+	if (bits_to_register & 2) {
+		printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
+		/* register for 2MB buffers  */
+		diag_register.requested_buffer_size = 2 * (1024 * 1024);
+		diag_register.unique_id = 0x7075901;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+
+	if (bits_to_register & 4) {
+		printk(MPT2SAS_INFO_FMT "registering extended buffer support\n",
+		    ioc->name);
+		diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;
+		/* register for 2MB buffers  */
+		diag_register.requested_buffer_size = 2 * (1024 * 1024);
+		diag_register.unique_id = 0x7075901;
+		_ctl_diag_register_2(ioc,  &diag_register);
+	}
+}
+
+/**
+ * _ctl_diag_register - application register with driver
+ * @arg - user space buffer containing ioctl content
+ * @state - NON_BLOCKING or BLOCKING
+ *
+ * This will allow the driver to setup any required buffers that will be
+ * needed by firmware to communicate with the driver.
+ */
+static long
+_ctl_diag_register(void __user *arg, enum block_state state)
+{
+	struct mpt2_diag_register karg;
+	struct MPT2SAS_ADAPTER *ioc;
+	long rc;
+
+	if (copy_from_user(&karg, arg, sizeof(karg))) {
+		printk(KERN_ERR "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		return -EFAULT;
+	}
+	if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
+		return -ENODEV;
+
+	if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
+		return -EAGAIN;
+	else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
+		return -ERESTARTSYS;
+	rc = _ctl_diag_register_2(ioc, &karg);
 	mutex_unlock(&ioc->ctl_cmds.mutex);
 	return rc;
 }
@@ -1600,7 +1667,7 @@ _ctl_diag_query(void __user *arg)
 /**
  * _ctl_send_release - Diag Release Message
  * @ioc: per adapter object
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @issue_reset - specifies whether host reset is required.
  *
  */
@@ -1690,7 +1757,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -1951,7 +2018,7 @@ _ctl_diag_read_buffer(void __user *arg,
 	} else {
 		printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
 		    "log_info(0x%08x)\n", ioc->name, __func__,
-		    ioc_status, mpi_reply->IOCLogInfo);
+		    ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
 		rc = -EFAULT;
 	}
 
@@ -2474,6 +2541,43 @@ _ctl_logging_level_store(struct device *
 static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
     _ctl_logging_level_show, _ctl_logging_level_store);
 
+/* device attributes */
+/*
+ * _ctl_fwfault_debug_show - show/store fwfault_debug
+ * @cdev - pointer to embedded class device
+ * @buf - the buffer returned
+ *
+ * mpt2sas_fwfault_debug is command line option
+ * A sysfs 'read/write' shost attribute.
+ */
+static ssize_t
+_ctl_fwfault_debug_show(struct device *cdev,
+    struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);
+}
+static ssize_t
+_ctl_fwfault_debug_store(struct device *cdev,
+    struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+	int val = 0;
+
+	if (sscanf(buf, "%d", &val) != 1)
+		return -EINVAL;
+
+	ioc->fwfault_debug = val;
+	printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name,
+	    ioc->fwfault_debug);
+	return strlen(buf);
+}
+static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
+    _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
+
 struct device_attribute *mpt2sas_host_attrs[] = {
 	&dev_attr_version_fw,
 	&dev_attr_version_bios,
@@ -2487,13 +2591,12 @@ struct device_attribute *mpt2sas_host_at
 	&dev_attr_io_delay,
 	&dev_attr_device_delay,
 	&dev_attr_logging_level,
+	&dev_attr_fwfault_debug,
 	&dev_attr_fw_queue_depth,
 	&dev_attr_host_sas_address,
 	NULL,
 };
 
-/* device attributes */
-
 /**
  * _ctl_device_sas_address_show - sas address
  * @cdev - pointer to embedded class device
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.h linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.h	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_ctl.h	2010-02-24 13:52:17.000000000 -0500
@@ -313,7 +313,7 @@ struct mpt2_ioctl_btdh_mapping {
  * struct mpt2_diag_register - application register with driver
  * @hdr - generic header
  * @reserved -
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @application_flags - misc flags
  * @diagnostic_flags - specifies flags affecting command processing
  * @product_specific - product specific information
@@ -352,7 +352,7 @@ struct mpt2_diag_unregister {
  * struct mpt2_diag_query - query relevant info associated with diag buffers
  * @hdr - generic header
  * @reserved -
- * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
  * @application_flags - misc flags
  * @diagnostic_flags - specifies flags affecting command processing
  * @product_specific - product specific information
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2010-02-24 13:52:17.000000000 -0500
@@ -76,6 +76,7 @@ static u8 tm_cb_idx = -1;
 static u8 ctl_cb_idx = -1;
 static u8 base_cb_idx = -1;
 static u8 transport_cb_idx = -1;
+static u8 scsih_cb_idx = -1;
 static u8 config_cb_idx = -1;
 static int mpt_ids;
 
@@ -196,10 +197,28 @@ static struct pci_device_id scsih_pci_ta
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* Meteor ~ 2116 */
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* Thunderbolt ~ 2208 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_7,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_8,
+		PCI_ANY_ID, PCI_ANY_ID },
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -317,6 +336,47 @@ _scsih_is_boot_device(u64 sas_address, u
 }
 
 /**
+ * _scsih_get_sas_address - set the sas_address for given device handle
+ * @handle: device handle
+ * @sas_address: sas address
+ *
+ * Returns 0 success, non-zero when failure
+ */
+static int
+_scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
+    u64 *sas_address)
+{
+	Mpi2SasDevicePage0_t sas_device_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u32 ioc_status;
+
+	if (handle <= ioc->sas_hba.num_phys) {
+		*sas_address = ioc->sas_hba.sas_address;
+		return 0;
+	} else
+		*sas_address = 0;
+
+	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
+	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return -ENXIO;
+	}
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
+		    "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
+		     __FILE__, __LINE__, __func__);
+		return -EIO;
+	}
+
+	*sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+	return 0;
+}
+
+/**
  * _scsih_determine_boot_device - determine boot device.
  * @ioc: per adapter object
  * @device: either sas_device or raid_device object
@@ -510,8 +570,6 @@ _scsih_sas_device_add(struct MPT2SAS_ADA
     struct _sas_device *sas_device)
 {
 	unsigned long flags;
-	u16 handle, parent_handle;
-	u64 sas_address;
 
 	dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
 	    "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
@@ -521,10 +579,8 @@ _scsih_sas_device_add(struct MPT2SAS_ADA
 	list_add_tail(&sas_device->list, &ioc->sas_device_list);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	handle = sas_device->handle;
-	parent_handle = sas_device->parent_handle;
-	sas_address = sas_device->sas_address;
-	if (!mpt2sas_transport_port_add(ioc, handle, parent_handle))
+	if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
+	     sas_device->sas_address_parent))
 		_scsih_sas_device_remove(ioc, sas_device);
 }
 
@@ -553,31 +609,6 @@ _scsih_sas_device_init_add(struct MPT2SA
 }
 
 /**
- * mpt2sas_scsih_expander_find_by_handle - expander device search
- * @ioc: per adapter object
- * @handle: expander handle (assigned by firmware)
- * Context: Calling function should acquire ioc->sas_device_lock
- *
- * This searches for expander device based on handle, then returns the
- * sas_node object.
- */
-struct _sas_node *
-mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
-{
-	struct _sas_node *sas_expander, *r;
-
-	r = NULL;
-	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-		if (sas_expander->handle != handle)
-			continue;
-		r = sas_expander;
-		goto out;
-	}
- out:
-	return r;
-}
-
-/**
  * _scsih_raid_device_find_by_id - raid device search
  * @ioc: per adapter object
  * @id: sas device target id
@@ -699,6 +730,31 @@ _scsih_raid_device_remove(struct MPT2SAS
 }
 
 /**
+ * mpt2sas_scsih_expander_find_by_handle - expander device search
+ * @ioc: per adapter object
+ * @handle: expander handle (assigned by firmware)
+ * Context: Calling function should acquire ioc->sas_device_lock
+ *
+ * This searches for expander device based on handle, then returns the
+ * sas_node object.
+ */
+struct _sas_node *
+mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+{
+	struct _sas_node *sas_expander, *r;
+
+	r = NULL;
+	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
+		if (sas_expander->handle != handle)
+			continue;
+		r = sas_expander;
+		goto out;
+	}
+ out:
+	return r;
+}
+
+/**
  * mpt2sas_scsih_expander_find_by_sas_address - expander device search
  * @ioc: per adapter object
  * @sas_address: sas address
@@ -1043,17 +1099,46 @@ _scsih_build_scatter_gather(struct MPT2S
  * _scsih_change_queue_depth - setting device queue depth
  * @sdev: scsi device struct
  * @qdepth: requested queue depth
+ * @reason: calling context
  *
  * Returns queue depth.
  */
 static int
-_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
+_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
 {
 	struct Scsi_Host *shost = sdev->host;
 	int max_depth;
 	int tag_type;
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+	struct MPT2SAS_DEVICE *sas_device_priv_data;
+	struct MPT2SAS_TARGET *sas_target_priv_data;
+	struct _sas_device *sas_device;
+	unsigned long flags;
+
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -EOPNOTSUPP;
 
 	max_depth = shost->can_queue;
+
+	/* limit max device queue for SATA to 32 */
+	sas_device_priv_data = sdev->hostdata;
+	if (!sas_device_priv_data)
+		goto not_sata;
+	sas_target_priv_data = sas_device_priv_data->sas_target;
+	if (!sas_target_priv_data)
+		goto not_sata;
+	if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))
+		goto not_sata;
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+	   sas_device_priv_data->sas_target->sas_address);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	if (sas_device && sas_device->device_info &
+	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
+		max_depth = MPT2SAS_SATA_QUEUE_DEPTH;
+
+ not_sata:
+
 	if (!sdev->tagged_supported)
 		max_depth = 1;
 	if (qdepth > max_depth)
@@ -1488,7 +1573,7 @@ _scsih_slave_configure(struct scsi_devic
 		    r_level, raid_device->handle,
 		    (unsigned long long)raid_device->wwid,
 		    raid_device->num_pds, ds);
-		_scsih_change_queue_depth(sdev, qdepth);
+		_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 		return 0;
 	}
 
@@ -1534,7 +1619,7 @@ _scsih_slave_configure(struct scsi_devic
 			_scsih_display_sata_capabilities(ioc, sas_device, sdev);
 	}
 
-	_scsih_change_queue_depth(sdev, qdepth);
+	_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
 
 	if (ssp_target)
 		sas_read_port_mode_page(sdev);
@@ -1874,6 +1959,8 @@ _scsih_abort(struct scsi_cmnd *scmd)
 		goto out;
 	}
 
+	mpt2sas_halt_firmware(ioc);
+
 	mutex_lock(&ioc->tm_cmds.mutex);
 	handle = sas_device_priv_data->sas_target->handle;
 	mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
@@ -2297,7 +2384,6 @@ _scsih_block_io_to_children_attached_dir
 	u16 handle;
 	u16 reason_code;
 	u8 phy_number;
-	u8 link_rate;
 
 	for (i = 0; i < event_data->NumEntries; i++) {
 		handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2308,11 +2394,6 @@ _scsih_block_io_to_children_attached_dir
 		    MPI2_EVENT_SAS_TOPO_RC_MASK;
 		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
 			_scsih_block_io_device(ioc, handle);
-		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
-			link_rate = event_data->PHY[i].LinkRate >> 4;
-			if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
-				_scsih_ublock_io_device(ioc, handle);
-		}
 	}
 }
 
@@ -2349,16 +2430,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return;
-	}
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
 	/* skip is hidden raid component */
-	if (sas_device->hidden_raid_component)
+	if (sas_device && sas_device->hidden_raid_component)
 		return;
 
 	smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2371,18 +2446,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER
 		delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
 		list_add_tail(&delayed_tr->list,
 		    &ioc->delayed_tr_list);
-		if (sas_device->starget)
+		if (sas_device && sas_device->starget) {
 			dewtprintk(ioc, starget_printk(KERN_INFO,
 			    sas_device->starget, "DELAYED:tr:handle(0x%04x), "
-			    "(open)\n", sas_device->handle));
+			    "(open)\n", handle));
+		} else {
+			dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+			    "DELAYED:tr:handle(0x%04x), (open)\n",
+			    ioc->name, handle));
+		}
 		return;
 	}
 
-	if (sas_device->starget && sas_device->starget->hostdata) {
-		sas_target_priv_data = sas_device->starget->hostdata;
-		sas_target_priv_data->tm_busy = 1;
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
-		    "tr:handle(0x%04x), (open)\n", sas_device->handle));
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_TR_SEND;
+		sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
+		if (sas_device->starget && sas_device->starget->hostdata) {
+			sas_target_priv_data = sas_device->starget->hostdata;
+			sas_target_priv_data->tm_busy = 1;
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget, "tr:handle(0x%04x), (open)\n",
+			    handle));
+		}
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+		    "tr:handle(0x%04x), (open)\n", ioc->name, handle));
 	}
 
 	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2390,8 +2478,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER
 	mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
 	mpi_request->DevHandle = cpu_to_le16(handle);
 	mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
-	sas_device->state |= MPTSAS_STATE_TR_SEND;
-	sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
 	mpt2sas_base_put_smid_hi_priority(ioc, smid);
 }
 
@@ -2426,21 +2512,25 @@ _scsih_sas_control_complete(struct MPT2S
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return 1;
-	}
-	sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (sas_device->starget)
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
+		if (sas_device->starget)
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget,
+			    "sc_complete:handle(0x%04x), "
+			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
+			    handle, le16_to_cpu(mpi_reply->IOCStatus),
+			    le32_to_cpu(mpi_reply->IOCLogInfo)));
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
 		    "sc_complete:handle(0x%04x), "
 		    "ioc_status(0x%04x), loginfo(0x%08x)\n",
-		    handle, le16_to_cpu(mpi_reply->IOCStatus),
+		    ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
 		    le32_to_cpu(mpi_reply->IOCLogInfo)));
+	}
+
 	return 1;
 }
 
@@ -2478,28 +2568,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADA
 	handle = le16_to_cpu(mpi_reply->DevHandle);
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-		printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
-		    ioc->name, __func__);
-		return 1;
-	}
-	sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (sas_device->starget)
-		dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
-		    "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
-		    "loginfo(0x%08x), completed(%d)\n",
-		    sas_device->handle, (sas_device->state &
-		    MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active",
-		    le16_to_cpu(mpi_reply->IOCStatus),
+	if (sas_device) {
+		sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
+		if (sas_device->starget) {
+			dewtprintk(ioc, starget_printk(KERN_INFO,
+			    sas_device->starget, "tr_complete:handle(0x%04x), "
+			    "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
+			    "completed(%d)\n", sas_device->handle,
+			    (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
+			    "open" : "active",
+			    le16_to_cpu(mpi_reply->IOCStatus),
+			    le32_to_cpu(mpi_reply->IOCLogInfo),
+			    le32_to_cpu(mpi_reply->TerminationCount)));
+			if (sas_device->starget->hostdata) {
+				sas_target_priv_data =
+				    sas_device->starget->hostdata;
+				sas_target_priv_data->tm_busy = 0;
+			}
+		}
+	} else {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
+		    "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
+		    "loginfo(0x%08x), completed(%d)\n", ioc->name,
+		    handle, le16_to_cpu(mpi_reply->IOCStatus),
 		    le32_to_cpu(mpi_reply->IOCLogInfo),
 		    le32_to_cpu(mpi_reply->TerminationCount)));
-
-	if (sas_device->starget && sas_device->starget->hostdata) {
-		sas_target_priv_data = sas_device->starget->hostdata;
-		sas_target_priv_data->tm_busy = 0;
 	}
 
 	if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2514,8 +2609,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADA
 	} else
 		rc = 1;
 
-
-	if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
+	if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
 		return rc;
 
 	if (ioc->shost_recovery) {
@@ -2531,12 +2625,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADA
 		return rc;
 	}
 
+	if (sas_device)
+		sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
+
 	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
 	memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
 	mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
 	mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
 	mpi_request->DevHandle = mpi_reply->DevHandle;
-	sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
 	mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
 	return rc;
 }
@@ -2678,8 +2774,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd
 	else
 		return;
 
-	mpi_request->EEDPBlockSize = scmd->device->sector_size;
-
 	switch (prot_type) {
 	case SCSI_PROT_DIF_TYPE1:
 
@@ -2687,8 +2781,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd
 		* enable ref/guard checking
 		* auto increment ref tag
 		*/
-		mpi_request->EEDPFlags = eedp_flags |
-		    MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
+		eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
 		    MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
 		    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
 		mpi_request->CDB.EEDP32.PrimaryReferenceTag =
@@ -2701,11 +2794,11 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd
 		/*
 		* enable guard checking
 		*/
-		mpi_request->EEDPFlags = eedp_flags |
-		    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
-
+		eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
 		break;
 	}
+	mpi_request->EEDPBlockSize = cpu_to_le32(scmd->device->sector_size);
+	mpi_request->EEDPFlags = cpu_to_le16(eedp_flags);
 }
 
 /**
@@ -2788,7 +2881,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void
 	}
 
 	/* see if we are busy with task managment stuff */
-	if (sas_target_priv_data->tm_busy)
+	if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -2842,7 +2935,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void
 	mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
 	mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
 	mpi_request->SenseBufferLowAddress =
-	    (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
+	    mpt2sas_base_get_sense_buffer_dma(ioc, smid);
 	mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
 	mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
 	    MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
@@ -2894,7 +2987,7 @@ _scsih_normalize_sense(char *sense_buffe
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
- * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
+ * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request
  * @ioc: per adapter object
  * @scmd: pointer to scsi command object
  * @mpi_reply: reply mf payload returned from firmware
@@ -3059,7 +3152,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAP
 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
 		response_info = le32_to_cpu(mpi_reply->ResponseInfo);
 		response_bytes = (u8 *)&response_info;
-		_scsih_response_code(ioc, response_bytes[3]);
+		_scsih_response_code(ioc, response_bytes[0]);
 	}
 }
 #endif
@@ -3177,7 +3270,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 	u8 scsi_status;
 	u32 log_info;
 	struct MPT2SAS_DEVICE *sas_device_priv_data;
-	u32 response_code;
+	u32 response_code = 0;
 
 	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
 	scmd = _scsih_scsi_lookup_get(ioc, smid);
@@ -3199,16 +3292,16 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 	}
 
 	/* turning off TLR */
+	scsi_state = mpi_reply->SCSIState;
+	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
+		response_code =
+		    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
 	if (!sas_device_priv_data->tlr_snoop_check) {
 		sas_device_priv_data->tlr_snoop_check++;
-		if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) {
-			response_code = (le32_to_cpu(mpi_reply->ResponseInfo)
-			    >> 24);
-			if (response_code ==
-			    MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
-				sas_device_priv_data->flags &=
-				    ~MPT_DEVICE_TLR_ON;
-		}
+		if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) &&
+		    response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
+			sas_device_priv_data->flags &=
+			    ~MPT_DEVICE_TLR_ON;
 	}
 
 	xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
@@ -3219,7 +3312,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 	else
 		log_info = 0;
 	ioc_status &= MPI2_IOCSTATUS_MASK;
-	scsi_state = mpi_reply->SCSIState;
 	scsi_status = mpi_reply->SCSIStatus;
 
 	if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
@@ -3255,10 +3347,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 
 	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
 		if (sas_device_priv_data->block) {
-			scmd->result = (DID_BUS_BUSY << 16);
-			break;
+			scmd->result = DID_TRANSPORT_DISRUPTED << 16;
+			goto out;
 		}
-
 	case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
 	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
 		scmd->result = DID_RESET << 16;
@@ -3304,8 +3395,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 	case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
 	case MPI2_IOCSTATUS_SUCCESS:
 		scmd->result = (DID_OK << 16) | scsi_status;
-		if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
-		     MPI2_SCSI_STATE_NO_SCSI_STATUS))
+		if (response_code ==
+		    MPI2_SCSITASKMGMT_RSP_INVALID_FRAME ||
+		    (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
+		     MPI2_SCSI_STATE_NO_SCSI_STATUS)))
 			scmd->result = DID_SOFT_ERROR << 16;
 		else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
 			scmd->result = DID_RESET << 16;
@@ -3344,7 +3437,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
 /**
  * _scsih_sas_host_refresh - refreshing sas host object contents
  * @ioc: per adapter object
- * @update: update link information
  * Context: user
  *
  * During port enable, fw will send topology events for every device. Its
@@ -3354,13 +3446,14 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *i
  * Return nothing.
  */
 static void
-_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
+_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc)
 {
 	u16 sz;
 	u16 ioc_status;
 	int i;
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
+	u16 attached_handle;
 
 	dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
 	    "updating handles for sas_host(0x%016llx)\n",
@@ -3374,27 +3467,24 @@ _scsih_sas_host_refresh(struct MPT2SAS_A
 		    ioc->name, __FILE__, __LINE__, __func__);
 		return;
 	}
-	if (!(mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
-	    sas_iounit_pg0, sz))) {
-		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-			goto out;
-		for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
-			ioc->sas_hba.phy[i].handle =
-			    le16_to_cpu(sas_iounit_pg0->PhyData[i].
-				ControllerDevHandle);
-			if (update)
-				mpt2sas_transport_update_links(
-				    ioc,
-				    ioc->sas_hba.phy[i].handle,
-				    le16_to_cpu(sas_iounit_pg0->PhyData[i].
-				    AttachedDevHandle), i,
-				    sas_iounit_pg0->PhyData[i].
-				    NegotiatedLinkRate >> 4);
-		}
-	}
 
+	if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
+	    sas_iounit_pg0, sz)) != 0)
+		goto out;
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+		goto out;
+	for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
+		if (i == 0)
+			ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
+			    PhyData[0].ControllerDevHandle);
+		ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
+		attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i].
+		    AttachedDevHandle);
+		mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address,
+		    attached_handle, i, sas_iounit_pg0->PhyData[i].
+		    NegotiatedLinkRate >> 4);
+	}
  out:
 	kfree(sas_iounit_pg0);
 }
@@ -3507,19 +3597,21 @@ _scsih_sas_host_add(struct MPT2SAS_ADAPT
 			    ioc->name, __FILE__, __LINE__, __func__);
 			goto out;
 		}
-		ioc->sas_hba.phy[i].handle =
-		    le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle);
+
+		if (i == 0)
+			ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0->
+			    PhyData[0].ControllerDevHandle);
+		ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle;
 		ioc->sas_hba.phy[i].phy_id = i;
 		mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
 		    phy_pg0, ioc->sas_hba.parent_dev);
 	}
 	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
-	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.phy[0].handle))) {
+	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
 		goto out;
 	}
-	ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
 	ioc->sas_hba.enclosure_handle =
 	    le16_to_cpu(sas_device_pg0.EnclosureHandle);
 	ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
@@ -3562,7 +3654,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 	Mpi2SasEnclosurePage0_t enclosure_pg0;
 	u32 ioc_status;
 	u16 parent_handle;
-	__le64 sas_address;
+	__le64 sas_address, sas_address_parent = 0;
 	int i;
 	unsigned long flags;
 	struct _sas_port *mpt2sas_port = NULL;
@@ -3591,10 +3683,16 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 
 	/* handle out of order topology events */
 	parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
-	if (parent_handle >= ioc->sas_hba.num_phys) {
+	if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent)
+	    != 0) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return -1;
+	}
+	if (sas_address_parent != ioc->sas_hba.sas_address) {
 		spin_lock_irqsave(&ioc->sas_node_lock, flags);
-		sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
-		    parent_handle);
+		sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
+		    sas_address_parent);
 		spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 		if (!sas_expander) {
 			rc = _scsih_expander_add(ioc, parent_handle);
@@ -3622,14 +3720,12 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 
 	sas_expander->handle = handle;
 	sas_expander->num_phys = expander_pg0.NumPhys;
-	sas_expander->parent_handle = parent_handle;
-	sas_expander->enclosure_handle =
-	    le16_to_cpu(expander_pg0.EnclosureHandle);
+	sas_expander->sas_address_parent = sas_address_parent;
 	sas_expander->sas_address = sas_address;
 
 	printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
 	    " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
-	    handle, sas_expander->parent_handle, (unsigned long long)
+	    handle, parent_handle, (unsigned long long)
 	    sas_expander->sas_address, sas_expander->num_phys);
 
 	if (!sas_expander->num_phys)
@@ -3645,7 +3741,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 
 	INIT_LIST_HEAD(&sas_expander->sas_port_list);
 	mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
-	    sas_expander->parent_handle);
+	    sas_address_parent);
 	if (!mpt2sas_port) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
@@ -3691,20 +3787,54 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 
 	if (mpt2sas_port)
 		mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-		    sas_expander->parent_handle);
+		    sas_address_parent);
 	kfree(sas_expander);
 	return rc;
 }
 
 /**
+ * _scsih_done -  scsih callback handler.
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @msix_index: MSIX table index supplied by the OS
+ * @reply: reply message frame(lower 32bit addr)
+ *
+ * Callback handler when sending internal generated message frames.
+ * The callback index passed is `ioc->scsih_cb_idx`
+ *
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
+ */
+static u8
+_scsih_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
+{
+	MPI2DefaultReply_t *mpi_reply;
+
+	mpi_reply =  mpt2sas_base_get_reply_virt_addr(ioc, reply);
+	if (ioc->scsih_cmds.status == MPT2_CMD_NOT_USED)
+		return 1;
+	if (ioc->scsih_cmds.smid != smid)
+		return 1;
+	ioc->scsih_cmds.status |= MPT2_CMD_COMPLETE;
+	if (mpi_reply) {
+		memcpy(ioc->scsih_cmds.reply, mpi_reply,
+		    mpi_reply->MsgLength*4);
+		ioc->scsih_cmds.status |= MPT2_CMD_REPLY_VALID;
+	}
+	ioc->scsih_cmds.status &= ~MPT2_CMD_PENDING;
+	complete(&ioc->scsih_cmds.done);
+	return 1;
+}
+
+/**
  * _scsih_expander_remove - removing expander object
  * @ioc: per adapter object
- * @handle: expander handle
+ * @sas_address: expander sas_address
  *
  * Return nothing.
  */
 static void
-_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address)
 {
 	struct _sas_node *sas_expander;
 	unsigned long flags;
@@ -3713,7 +3843,8 @@ _scsih_expander_remove(struct MPT2SAS_AD
 		return;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
+	sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
+	    sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	_scsih_expander_node_remove(ioc, sas_expander);
 }
@@ -3805,8 +3936,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER
 	}
 
 	sas_device->handle = handle;
-	sas_device->parent_handle =
-	    le16_to_cpu(sas_device_pg0.ParentDevHandle);
+	if (_scsih_get_sas_address(ioc, le16_to_cpu
+		(sas_device_pg0.ParentDevHandle),
+		&sas_device->sas_address_parent) != 0)
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
 	sas_device->enclosure_handle =
 	    le16_to_cpu(sas_device_pg0.EnclosureHandle);
 	sas_device->slot =
@@ -3836,43 +3970,39 @@ _scsih_add_device(struct MPT2SAS_ADAPTER
 /**
  * _scsih_remove_device -  removing sas device object
  * @ioc: per adapter object
- * @handle: sas device handle
+ * @sas_device: the sas_device object
  *
  * Return nothing.
  */
 static void
-_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
+    *sas_device)
 {
 	struct MPT2SAS_TARGET *sas_target_priv_data;
-	struct _sas_device *sas_device;
-	unsigned long flags;
 	Mpi2SasIoUnitControlReply_t mpi_reply;
 	Mpi2SasIoUnitControlRequest_t mpi_request;
-	u16 device_handle;
+	u16 device_handle, handle;
 
-	/* lookup sas_device */
-	spin_lock_irqsave(&ioc->sas_device_lock, flags);
-	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
-	if (!sas_device) {
-		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	if (!sas_device)
 		return;
-	}
 
-	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle"
-	    "(0x%04x)\n", ioc->name, __func__, handle));
+	handle = sas_device->handle;
+	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
+	    " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
+	    (unsigned long long) sas_device->sas_address));
 
 	if (sas_device->starget && sas_device->starget->hostdata) {
 		sas_target_priv_data = sas_device->starget->hostdata;
 		sas_target_priv_data->deleted = 1;
 	}
-	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (ioc->remove_host)
+	if (ioc->remove_host || ioc->shost_recovery || !handle)
 		goto out;
 
 	if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
 		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
-		   "target_reset handle(0x%04x)\n", ioc->name, handle));
+		   "target_reset handle(0x%04x)\n", ioc->name,
+		   handle));
 		goto skip_tr;
 	}
 
@@ -3925,10 +4055,10 @@ _scsih_remove_device(struct MPT2SAS_ADAP
 	_scsih_ublock_io_device(ioc, handle);
 
 	mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
-	    sas_device->parent_handle);
+	    sas_device->sas_address_parent);
 
 	printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
-	    "(0x%016llx)\n", ioc->name, sas_device->handle,
+	    "(0x%016llx)\n", ioc->name, handle,
 	    (unsigned long long) sas_device->sas_address);
 	_scsih_sas_device_remove(ioc, sas_device);
 
@@ -3952,7 +4082,7 @@ _scsih_sas_topology_change_event_debug(s
 	u16 reason_code;
 	u8 phy_number;
 	char *status_str = NULL;
-	char link_rate[25];
+	u8 link_rate, prev_link_rate;
 
 	switch (event_data->ExpStatus) {
 	case MPI2_EVENT_SAS_TOPO_ES_ADDED:
@@ -3962,6 +4092,7 @@ _scsih_sas_topology_change_event_debug(s
 		status_str = "remove";
 		break;
 	case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
+	case 0:
 		status_str =  "responding";
 		break;
 	case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
@@ -3987,30 +4118,30 @@ _scsih_sas_topology_change_event_debug(s
 		    MPI2_EVENT_SAS_TOPO_RC_MASK;
 		switch (reason_code) {
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-			snprintf(link_rate, 25, ": add, link(0x%02x)",
-			    (event_data->PHY[i].LinkRate >> 4));
-			status_str = link_rate;
+			status_str = "target add";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-			status_str = ": remove";
+			status_str = "target remove";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
-			status_str = ": remove_delay";
+			status_str = "delay target remove";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
-			snprintf(link_rate, 25, ": link(0x%02x)",
-			    (event_data->PHY[i].LinkRate >> 4));
-			status_str = link_rate;
+			status_str = "link rate change";
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
-			status_str = ": responding";
+			status_str = "target responding";
 			break;
 		default:
-			status_str = ": unknown";
+			status_str = "unknown";
 			break;
 		}
-		printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n",
-		    phy_number, handle, status_str);
+		link_rate = event_data->PHY[i].LinkRate >> 4;
+		prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
+		printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x): %s:"
+		    " link rate: new(0x%02x), old(0x%02x)\n", phy_number,
+		    handle, status_str, link_rate, prev_link_rate);
+
 	}
 }
 #endif
@@ -4031,8 +4162,10 @@ _scsih_sas_topology_change_event(struct
 	u16 reason_code;
 	u8 phy_number;
 	struct _sas_node *sas_expander;
+	struct _sas_device *sas_device;
+	u64 sas_address;
 	unsigned long flags;
-	u8 link_rate_;
+	u8 link_rate, prev_link_rate;
 	Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4040,10 +4173,13 @@ _scsih_sas_topology_change_event(struct
 		_scsih_sas_topology_change_event_debug(ioc, event_data);
 #endif
 
+	if (ioc->shost_recovery)
+		return;
+
 	if (!ioc->sas_hba.num_phys)
 		_scsih_sas_host_add(ioc);
 	else
-		_scsih_sas_host_refresh(ioc, 0);
+		_scsih_sas_host_refresh(ioc);
 
 	if (fw_event->ignore) {
 		dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
@@ -4058,6 +4194,17 @@ _scsih_sas_topology_change_event(struct
 		if (_scsih_expander_add(ioc, parent_handle) != 0)
 			return;
 
+	spin_lock_irqsave(&ioc->sas_node_lock, flags);
+	sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
+	    parent_handle);
+	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
+	if (sas_expander)
+		sas_address = sas_expander->sas_address;
+	else if (parent_handle < ioc->sas_hba.num_phys)
+		sas_address = ioc->sas_hba.sas_address;
+	else
+		return;
+
 	/* handle siblings events */
 	for (i = 0; i < event_data->NumEntries; i++) {
 		if (fw_event->ignore) {
@@ -4077,48 +4224,47 @@ _scsih_sas_topology_change_event(struct
 		handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
 		if (!handle)
 			continue;
-		link_rate_ = event_data->PHY[i].LinkRate >> 4;
+		link_rate = event_data->PHY[i].LinkRate >> 4;
+		prev_link_rate = event_data->PHY[i].LinkRate & 0xF;
 		switch (reason_code) {
 		case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
+
+			if (link_rate == prev_link_rate)
+				break;
+
+			mpt2sas_transport_update_links(ioc, sas_address,
+			    handle, phy_number, link_rate);
+
+			if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
+				_scsih_ublock_io_device(ioc, handle);
+			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
-			if (!parent_handle) {
-				if (phy_number < ioc->sas_hba.num_phys)
-					mpt2sas_transport_update_links(
-					ioc,
-					ioc->sas_hba.phy[phy_number].handle,
-					handle, phy_number, link_rate_);
-			} else {
-				spin_lock_irqsave(&ioc->sas_node_lock, flags);
-				sas_expander =
-				    mpt2sas_scsih_expander_find_by_handle(ioc,
-					parent_handle);
-				spin_unlock_irqrestore(&ioc->sas_node_lock,
-				    flags);
-				if (sas_expander) {
-					if (phy_number < sas_expander->num_phys)
-						mpt2sas_transport_update_links(
-						ioc,
-						sas_expander->
-						phy[phy_number].handle,
-						handle, phy_number,
-						link_rate_);
-				}
-			}
-			if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
-				if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
-					break;
-				_scsih_add_device(ioc, handle, phy_number, 0);
-			}
+
+			mpt2sas_transport_update_links(ioc, sas_address,
+			    handle, phy_number, link_rate);
+
+			_scsih_add_device(ioc, handle, phy_number, 0);
 			break;
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
-			_scsih_remove_device(ioc, handle);
+
+			spin_lock_irqsave(&ioc->sas_device_lock, flags);
+			sas_device = _scsih_sas_device_find_by_handle(ioc,
+			    handle);
+			if (!sas_device) {
+				spin_unlock_irqrestore(&ioc->sas_device_lock,
+				    flags);
+				break;
+			}
+			spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+			_scsih_remove_device(ioc, sas_device);
 			break;
 		}
 	}
 
 	/* handle expander removal */
-	if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
-		_scsih_expander_remove(ioc, parent_handle);
+	if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING &&
+	    sas_expander)
+		_scsih_expander_remove(ioc, sas_address);
 
 }
 
@@ -4170,6 +4316,12 @@ _scsih_sas_device_status_change_event_de
 	case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
 		reason_str = "internal async notification";
 		break;
+	case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY:
+		reason_str = "expander reduced functionality";
+		break;
+	case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY:
+		reason_str = "expander reduced functionality complete";
+		break;
 	default:
 		reason_str = "unknown reason";
 		break;
@@ -4197,11 +4349,43 @@ static void
 _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
+	struct MPT2SAS_TARGET *target_priv_data;
+	struct _sas_device *sas_device;
+	__le64 sas_address;
+	unsigned long flags;
+	Mpi2EventDataSasDeviceStatusChange_t *event_data =
+	    fw_event->event_data;
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
 		_scsih_sas_device_status_change_event_debug(ioc,
-		     fw_event->event_data);
+		     event_data);
 #endif
+
+	if (!(event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
+	   event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET))
+		return;
+
+	spin_lock_irqsave(&ioc->sas_device_lock, flags);
+	sas_address = le64_to_cpu(event_data->SASAddress);
+	sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+	    sas_address);
+	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+	if (!sas_device || !sas_device->starget)
+		return;
+
+	target_priv_data = sas_device->starget->hostdata;
+	if (!target_priv_data)
+		return;
+
+	if (event_data->ReasonCode ==
+	    MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET)
+		target_priv_data->tm_busy = 1;
+	else
+		target_priv_data->tm_busy = 0;
 }
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4281,6 +4465,7 @@ _scsih_sas_broadcast_primative_event(str
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
 #endif
+	u16 ioc_status;
 	dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
 	    "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
 	    event_data->PortWidth));
@@ -4314,8 +4499,9 @@ _scsih_sas_broadcast_primative_event(str
 		mpt2sas_scsih_issue_tm(ioc, handle, lun,
 		    MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
 		ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
-
-		if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) &&
+		ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
+		    & MPI2_IOCSTATUS_MASK;
+		if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
 		    (mpi_reply->ResponseCode ==
 		     MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
 		     mpi_reply->ResponseCode ==
@@ -4570,7 +4756,7 @@ _scsih_sas_pd_delete(struct MPT2SAS_ADAP
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 	if (!sas_device)
 		return;
-	_scsih_remove_device(ioc, handle);
+	_scsih_remove_device(ioc, sas_device);
 }
 
 /**
@@ -4591,6 +4777,8 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasDevicePage0_t sas_device_pg0;
 	u32 ioc_status;
+	u64 sas_address;
+	u16 parent_handle;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -4615,9 +4803,10 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER
 		return;
 	}
 
-	mpt2sas_transport_update_links(ioc,
-	    le16_to_cpu(sas_device_pg0.ParentDevHandle),
-	    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+	parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+	if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
+		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, 1);
 }
@@ -4857,7 +5046,7 @@ static void
 _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
-	u16 handle;
+	u16 handle, parent_handle;
 	u32 state;
 	struct _sas_device *sas_device;
 	unsigned long flags;
@@ -4865,6 +5054,7 @@ _scsih_sas_ir_physical_disk_event(struct
 	Mpi2SasDevicePage0_t sas_device_pg0;
 	u32 ioc_status;
 	Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
+	u64 sas_address;
 
 	if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
 		return;
@@ -4906,9 +5096,10 @@ _scsih_sas_ir_physical_disk_event(struct
 			return;
 		}
 
-		mpt2sas_transport_update_links(ioc,
-		    le16_to_cpu(sas_device_pg0.ParentDevHandle),
-		    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+		parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+		if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address))
+			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, 1);
 
@@ -4948,11 +5139,17 @@ _scsih_sas_ir_operation_status_event_deb
 	case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
 		reason_str = "consistency check";
 		break;
-	default:
-		reason_str = "unknown reason";
+	case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT:
+		reason_str = "background init";
+		break;
+	case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT:
+		reason_str = "make data consistent";
 		break;
 	}
 
+	if (!reason_str)
+		return;
+
 	printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
 	    "\thandle(0x%04x), percent complete(%d)\n",
 	    ioc->name, reason_str,
@@ -5252,18 +5449,23 @@ _scsih_mark_responding_expander(struct M
 {
 	struct _sas_node *sas_expander;
 	unsigned long flags;
+	int i;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
 	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
-		if (sas_expander->sas_address == sas_address) {
-			sas_expander->responding = 1;
-			if (sas_expander->handle != handle) {
-				printk(KERN_INFO "old handle(0x%04x)\n",
-				    sas_expander->handle);
-				sas_expander->handle = handle;
-			}
+		if (sas_expander->sas_address != sas_address)
+			continue;
+		sas_expander->responding = 1;
+		if (sas_expander->handle == handle)
 			goto out;
-		}
+		printk(KERN_INFO "\texpander(0x%016llx): handle changed"
+		    " from(0x%04x) to (0x%04x)!!!\n",
+		    (unsigned long long)sas_expander->sas_address,
+		    sas_expander->handle, handle);
+		sas_expander->handle = handle;
+		for (i = 0 ; i < sas_expander->num_phys ; i++)
+			sas_expander->phy[i].handle = handle;
+		goto out;
 	}
  out:
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -5340,7 +5542,9 @@ _scsih_remove_unresponding_devices(struc
 			    (unsigned long long)
 			    sas_device->enclosure_logical_id,
 			    sas_device->slot);
-		_scsih_remove_device(ioc, sas_device->handle);
+		/* invalidate the device handle */
+		sas_device->handle = 0;
+		_scsih_remove_device(ioc, sas_device);
 	}
 
 	list_for_each_entry_safe(raid_device, raid_device_next,
@@ -5366,7 +5570,7 @@ _scsih_remove_unresponding_devices(struc
 			sas_expander->responding = 0;
 			continue;
 		}
-		_scsih_expander_remove(ioc, sas_expander->handle);
+		_scsih_expander_remove(ioc, sas_expander->sas_address);
 		goto retry_expander_search;
 	}
 }
@@ -5406,7 +5610,7 @@ mpt2sas_scsih_reset_handler(struct MPT2S
 	case MPT2_IOC_DONE_RESET:
 		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
 		    "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-		_scsih_sas_host_refresh(ioc, 0);
+		_scsih_sas_host_refresh(ioc);
 		_scsih_search_responding_sas_devices(ioc);
 		_scsih_search_responding_raid_devices(ioc);
 		_scsih_search_responding_expanders(ioc);
@@ -5646,7 +5850,7 @@ _scsih_expander_node_remove(struct MPT2S
 			spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 			if (!sas_device)
 				continue;
-			_scsih_remove_device(ioc, sas_device->handle);
+			_scsih_remove_device(ioc, sas_device);
 			if (ioc->shost_recovery)
 				return;
 			goto retry_device_search;
@@ -5669,7 +5873,8 @@ _scsih_expander_node_remove(struct MPT2S
 			spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 			if (!expander_sibling)
 				continue;
-			_scsih_expander_remove(ioc, expander_sibling->handle);
+			_scsih_expander_remove(ioc,
+			    expander_sibling->sas_address);
 			if (ioc->shost_recovery)
 				return;
 			goto retry_expander_search;
@@ -5677,7 +5882,7 @@ _scsih_expander_node_remove(struct MPT2S
 	}
 
 	mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
-	    sas_expander->parent_handle);
+	    sas_expander->sas_address_parent);
 
 	printk(MPT2SAS_INFO_FMT "expander_remove: handle"
 	   "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
@@ -5690,9 +5895,99 @@ _scsih_expander_node_remove(struct MPT2S
 }
 
 /**
+ * _scsih_ir_shutdown - IR shutdown notification
+ * @ioc: per adapter object
+ *
+ * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that
+ * the host system is shutting down.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
+{
+	Mpi2RaidActionRequest_t *mpi_request;
+	Mpi2RaidActionReply_t *mpi_reply;
+	u16 smid;
+
+	/* is IR firmware build loaded ? */
+	if (!ioc->ir_firmware)
+		return;
+
+	/* are there any volumes ? */
+	if (list_empty(&ioc->raid_device_list))
+		return;
+
+	mutex_lock(&ioc->scsih_cmds.mutex);
+
+	if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
+		printk(MPT2SAS_ERR_FMT "%s: scsih_cmd in use\n",
+		    ioc->name, __func__);
+		goto out;
+	}
+	ioc->scsih_cmds.status = MPT2_CMD_PENDING;
+
+	smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx);
+	if (!smid) {
+		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
+		    ioc->name, __func__);
+		ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
+		goto out;
+	}
+
+	mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
+	ioc->scsih_cmds.smid = smid;
+	memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t));
+
+	mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
+	mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
+
+	printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
+	init_completion(&ioc->scsih_cmds.done);
+	mpt2sas_base_put_smid_default(ioc, smid);
+	wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
+
+	if (!(ioc->scsih_cmds.status & MPT2_CMD_COMPLETE)) {
+		printk(MPT2SAS_ERR_FMT "%s: timeout\n",
+		    ioc->name, __func__);
+		goto out;
+	}
+
+	if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
+		mpi_reply = ioc->scsih_cmds.reply;
+
+		printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
+		    "ioc_status(0x%04x), loginfo(0x%08x)\n",
+		    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
+		    le32_to_cpu(mpi_reply->IOCLogInfo));
+	}
+
+ out:
+	ioc->scsih_cmds.status = MPT2_CMD_NOT_USED;
+	mutex_unlock(&ioc->scsih_cmds.mutex);
+}
+
+/**
+ * _scsih_shutdown - routine call during system shutdown
+ * @pdev: PCI device struct
+ *
+ * Return nothing.
+ */
+static void
+_scsih_shutdown(struct pci_dev *pdev)
+{
+	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+
+	_scsih_ir_shutdown(ioc);
+	mpt2sas_base_detach(ioc);
+}
+
+/**
  * _scsih_remove - detach and remove add host
  * @pdev: PCI device struct
  *
+ * Routine called when unloading the driver.
  * Return nothing.
  */
 static void __devexit
@@ -5726,7 +6021,7 @@ _scsih_remove(struct pci_dev *pdev)
 			    mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
 			   mpt2sas_port->remote_identify.sas_address);
 			if (sas_device) {
-				_scsih_remove_device(ioc, sas_device->handle);
+				_scsih_remove_device(ioc, sas_device);
 				goto retry_again;
 			}
 		} else {
@@ -5735,7 +6030,7 @@ _scsih_remove(struct pci_dev *pdev)
 			    mpt2sas_port->remote_identify.sas_address);
 			if (expander_sibling) {
 				_scsih_expander_remove(ioc,
-				    expander_sibling->handle);
+				    expander_sibling->sas_address);
 				goto retry_again;
 			}
 		}
@@ -5749,7 +6044,7 @@ _scsih_remove(struct pci_dev *pdev)
 	}
 
 	sas_remove_host(shost);
-	mpt2sas_base_detach(ioc);
+	_scsih_shutdown(pdev);
 	list_del(&ioc->list);
 	scsi_remove_host(shost);
 	scsi_host_put(shost);
@@ -5770,7 +6065,8 @@ _scsih_probe_boot_devices(struct MPT2SAS
 	void *device;
 	struct _sas_device *sas_device;
 	struct _raid_device *raid_device;
-	u16 handle, parent_handle;
+	u16 handle;
+	u64 sas_address_parent;
 	u64 sas_address;
 	unsigned long flags;
 	int rc;
@@ -5799,17 +6095,17 @@ _scsih_probe_boot_devices(struct MPT2SAS
 	} else {
 		sas_device = device;
 		handle = sas_device->handle;
-		parent_handle = sas_device->parent_handle;
+		sas_address_parent = sas_device->sas_address_parent;
 		sas_address = sas_device->sas_address;
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-		    sas_device->parent_handle)) {
+		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
 		} else if (!sas_device->starget) {
 			mpt2sas_transport_port_remove(ioc, sas_address,
-			    parent_handle);
+			    sas_address_parent);
 			_scsih_sas_device_remove(ioc, sas_device);
 		}
 	}
@@ -5849,8 +6145,6 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER
 {
 	struct _sas_device *sas_device, *next;
 	unsigned long flags;
-	u16 handle, parent_handle;
-	u64 sas_address;
 
 	/* SAS Device List */
 	list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
@@ -5859,14 +6153,13 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-		handle = sas_device->handle;
-		parent_handle = sas_device->parent_handle;
-		sas_address = sas_device->sas_address;
-		if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
+		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
+		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
 		} else if (!sas_device->starget) {
-			mpt2sas_transport_port_remove(ioc, sas_address,
-			    parent_handle);
+			mpt2sas_transport_port_remove(ioc,
+			    sas_device->sas_address,
+			    sas_device->sas_address_parent);
 			_scsih_sas_device_remove(ioc, sas_device);
 		}
 	}
@@ -5935,6 +6228,7 @@ _scsih_probe(struct pci_dev *pdev, const
 	ioc->ctl_cb_idx = ctl_cb_idx;
 	ioc->base_cb_idx = base_cb_idx;
 	ioc->transport_cb_idx = transport_cb_idx;
+	ioc->scsih_cb_idx = scsih_cb_idx;
 	ioc->config_cb_idx = config_cb_idx;
 	ioc->tm_tr_cb_idx = tm_tr_cb_idx;
 	ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
@@ -6072,6 +6366,7 @@ static struct pci_driver scsih_driver =
 	.id_table	= scsih_pci_table,
 	.probe		= _scsih_probe,
 	.remove		= __devexit_p(_scsih_remove),
+	.shutdown	= _scsih_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= _scsih_suspend,
 	.resume		= _scsih_resume,
@@ -6113,6 +6408,9 @@ _scsih_init(void)
 	transport_cb_idx = mpt2sas_base_register_callback_handler(
 	    mpt2sas_transport_done);
 
+	/* scsih internal commands callback handler */
+	scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done);
+
 	/* configuration page API internal commands callback handler */
 	config_cb_idx = mpt2sas_base_register_callback_handler(
 	    mpt2sas_config_done);
@@ -6152,6 +6450,7 @@ _scsih_exit(void)
 	mpt2sas_base_release_callback_handler(tm_cb_idx);
 	mpt2sas_base_release_callback_handler(base_cb_idx);
 	mpt2sas_base_release_callback_handler(transport_cb_idx);
+	mpt2sas_base_release_callback_handler(scsih_cb_idx);
 	mpt2sas_base_release_callback_handler(config_cb_idx);
 	mpt2sas_base_release_callback_handler(ctl_cb_idx);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mpt2sas/mpt2sas_transport.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,24 +59,23 @@
 
 #include "mpt2sas_base.h"
 /**
- * _transport_sas_node_find_by_handle - sas node search
+ * _transport_sas_node_find_by_sas_address - sas node search
  * @ioc: per adapter object
- * @handle: expander or hba handle (assigned by firmware)
+ * @sas_address: sas address of expander or sas host
  * Context: Calling function should acquire ioc->sas_node_lock.
  *
  * Search for either hba phys or expander device based on handle, then returns
  * the sas_node object.
  */
 static struct _sas_node *
-_transport_sas_node_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
+    u64 sas_address)
 {
-	int i;
-
-	for (i = 0; i < ioc->sas_hba.num_phys; i++)
-		if (ioc->sas_hba.phy[i].handle == handle)
-			return &ioc->sas_hba;
-
-	return mpt2sas_scsih_expander_find_by_handle(ioc, handle);
+	if (ioc->sas_hba.sas_address == sas_address)
+		return &ioc->sas_hba;
+	else
+		return mpt2sas_scsih_expander_find_by_sas_address(ioc,
+		    sas_address);
 }
 
 /**
@@ -259,8 +258,7 @@ struct rep_manu_reply{
 	u8 response_length;
 	u16 expander_change_count;
 	u8 reserved0[2];
-	u8 sas_format:1;
-	u8 reserved1:7;
+	u8 sas_format;
 	u8 reserved2[3];
 	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
 	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
@@ -375,7 +373,8 @@ _transport_expander_report_manufacture(s
 	mpi_request->VP_ID = 0;
 	sas_address_le = (u64 *)&mpi_request->SASAddress;
 	*sas_address_le = cpu_to_le64(sas_address);
-	mpi_request->RequestDataLength = sizeof(struct rep_manu_request);
+	mpi_request->RequestDataLength =
+	    cpu_to_le16(sizeof(struct rep_manu_request));
 	psge = &mpi_request->SGL;
 
 	/* WRITE sgel first */
@@ -438,8 +437,8 @@ _transport_expander_report_manufacture(s
 		     SAS_EXPANDER_PRODUCT_ID_LEN);
 		strncpy(edev->product_rev, manufacture_reply->product_rev,
 		     SAS_EXPANDER_PRODUCT_REV_LEN);
-		edev->level = manufacture_reply->sas_format;
-		if (manufacture_reply->sas_format) {
+		edev->level = manufacture_reply->sas_format & 1;
+		if (edev->level) {
 			strncpy(edev->component_vendor_id,
 			    manufacture_reply->component_vendor_id,
 			     SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
@@ -469,7 +468,7 @@ _transport_expander_report_manufacture(s
  * mpt2sas_transport_port_add - insert port to the list
  * @ioc: per adapter object
  * @handle: handle of attached device
- * @parent_handle: parent handle(either hba or expander)
+ * @sas_address: sas address of parent expander or sas host
  * Context: This function will acquire ioc->sas_node_lock.
  *
  * Adding new port object to the sas_node->sas_port_list.
@@ -478,7 +477,7 @@ _transport_expander_report_manufacture(s
  */
 struct _sas_port *
 mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
-    u16 parent_handle)
+    u64 sas_address)
 {
 	struct _sas_phy *mpt2sas_phy, *next;
 	struct _sas_port *mpt2sas_port;
@@ -488,9 +487,6 @@ mpt2sas_transport_port_add(struct MPT2SA
 	int i;
 	struct sas_port *port;
 
-	if (!parent_handle)
-		return NULL;
-
 	mpt2sas_port = kzalloc(sizeof(struct _sas_port),
 	    GFP_KERNEL);
 	if (!mpt2sas_port) {
@@ -502,17 +498,16 @@ mpt2sas_transport_port_add(struct MPT2SA
 	INIT_LIST_HEAD(&mpt2sas_port->port_list);
 	INIT_LIST_HEAD(&mpt2sas_port->phy_list);
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 
 	if (!sas_node) {
-		printk(MPT2SAS_ERR_FMT "%s: Could not find parent(0x%04x)!\n",
-		    ioc->name, __func__, parent_handle);
+		printk(MPT2SAS_ERR_FMT "%s: Could not find "
+		    "parent sas_address(0x%016llx)!\n", ioc->name,
+		    __func__, (unsigned long long)sas_address);
 		goto out_fail;
 	}
 
-	mpt2sas_port->handle = parent_handle;
-	mpt2sas_port->sas_address = sas_node->sas_address;
 	if ((_transport_set_identify(ioc, handle,
 	    &mpt2sas_port->remote_identify))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -604,7 +599,7 @@ mpt2sas_transport_port_add(struct MPT2SA
  * mpt2sas_transport_port_remove - remove port from the list
  * @ioc: per adapter object
  * @sas_address: sas address of attached device
- * @parent_handle: handle to the upstream parent(either hba or expander)
+ * @sas_address_parent: sas address of parent expander or sas host
  * Context: This function will acquire ioc->sas_node_lock.
  *
  * Removing object and freeing associated memory from the
@@ -614,7 +609,7 @@ mpt2sas_transport_port_add(struct MPT2SA
  */
 void
 mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
-    u16 parent_handle)
+    u64 sas_address_parent)
 {
 	int i;
 	unsigned long flags;
@@ -624,7 +619,8 @@ mpt2sas_transport_port_remove(struct MPT
 	struct _sas_phy *mpt2sas_phy, *next_phy;
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc,
+	    sas_address_parent);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	if (!sas_node)
 		return;
@@ -650,8 +646,7 @@ mpt2sas_transport_port_remove(struct MPT
 	    &mpt2sas_port->phy_list, port_siblings) {
 		if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
 			dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
-			    "remove: parent_handle(0x%04x), "
-			    "sas_addr(0x%016llx), phy(%d)\n", parent_handle,
+			    "remove: sas_addr(0x%016llx), phy(%d)\n",
 			    (unsigned long long)
 			    mpt2sas_port->remote_identify.sas_address,
 			    mpt2sas_phy->phy_id);
@@ -799,8 +794,8 @@ mpt2sas_transport_add_expander_phy(struc
 /**
  * mpt2sas_transport_update_links - refreshing phy link changes
  * @ioc: per adapter object
- * @handle: handle to sas_host or expander
- * @attached_handle: attached device handle
+ * @sas_address: sas address of parent expander or sas host
+ * @handle: attached device handle
  * @phy_numberv: phy number
  * @link_rate: new link rate
  *
@@ -808,28 +803,25 @@ mpt2sas_transport_add_expander_phy(struc
  */
 void
 mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
-    u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate)
+     u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
 {
 	unsigned long flags;
 	struct _sas_node *sas_node;
 	struct _sas_phy *mpt2sas_phy;
 
-	if (ioc->shost_recovery) {
-		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
-			__func__, ioc->name);
+	if (ioc->shost_recovery)
 		return;
-	}
 
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
-	sas_node = _transport_sas_node_find_by_handle(ioc, handle);
+	sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
 	if (!sas_node)
 		return;
 
 	mpt2sas_phy = &sas_node->phy[phy_number];
-	mpt2sas_phy->attached_handle = attached_handle;
-	if (attached_handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
-		_transport_set_identify(ioc, mpt2sas_phy->attached_handle,
+	mpt2sas_phy->attached_handle = handle;
+	if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
+		_transport_set_identify(ioc, handle,
 		    &mpt2sas_phy->remote_identify);
 	else
 		memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
@@ -841,13 +833,11 @@ mpt2sas_transport_update_links(struct MP
 
 	if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
 		dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
-		    "refresh: handle(0x%04x), sas_addr(0x%016llx),\n"
+		    "refresh: parent sas_addr(0x%016llx),\n"
 		    "\tlink_rate(0x%02x), phy(%d)\n"
 		    "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
-		    handle, (unsigned long long)
-		    mpt2sas_phy->identify.sas_address, link_rate,
-		    phy_number, attached_handle,
-		    (unsigned long long)
+		    (unsigned long long)sas_address,
+		    link_rate, phy_number, handle, (unsigned long long)
 		    mpt2sas_phy->remote_identify.sas_address);
 }
 
@@ -1126,7 +1116,7 @@ _transport_smp_handler(struct Scsi_Host
 	dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
 		blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
 	if (!dma_addr_out) {
-		mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
+		mpt2sas_base_free_smid(ioc, smid);
 		goto unmap;
 	}
 
@@ -1144,7 +1134,7 @@ _transport_smp_handler(struct Scsi_Host
 	dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
 				     blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
 	if (!dma_addr_in) {
-		mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
+		mpt2sas_base_free_smid(ioc, smid);
 		goto unmap;
 	}
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/mvsas/mv_init.c linux-libre-2.6.33-gnu1/drivers/scsi/mvsas/mv_init.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/mvsas/mv_init.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/mvsas/mv_init.c	2010-02-24 13:52:17.000000000 -0500
@@ -657,6 +657,7 @@ static struct pci_device_id __devinitdat
 	{ PCI_VDEVICE(MARVELL, 0x9180), chip_9180 },
 	{ PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 },
 	{ PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 },
+	{ PCI_VDEVICE(ADAPTEC2, 0x0450), chip_6440 },
 
 	{ }	/* terminate list */
 };
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/ncr53c8xx.c linux-libre-2.6.33-gnu1/drivers/scsi/ncr53c8xx.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/ncr53c8xx.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/ncr53c8xx.c	2010-02-24 13:52:17.000000000 -0500
@@ -6495,7 +6495,7 @@ static void ncr_int_ma (struct ncb *np)
 	**	we force a SIR_NEGO_PROTO interrupt (it is a hack that avoids 
 	**	bloat for such a should_not_happen situation).
 	**	In all other situation, we reset the BUS.
-	**	Are these assumptions reasonnable ? (Wait and see ...)
+	**	Are these assumptions reasonable ? (Wait and see ...)
 	*/
 unexpected_phase:
 	dsp -= 8;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/nsp32.c linux-libre-2.6.33-gnu1/drivers/scsi/nsp32.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/nsp32.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/nsp32.c	2010-02-24 13:52:17.000000000 -0500
@@ -1419,7 +1419,7 @@ static irqreturn_t do_nsp32_isr(int irq,
 		nsp32_msg(KERN_ERR, "Received unexpected BMCNTERR IRQ! ");
 		/*
 		 * TODO: To be implemented improving bus master
-		 * transfer reliablity when BMCNTERR is occurred in
+		 * transfer reliability when BMCNTERR is occurred in
 		 * AutoSCSI phase described in specification.
 		 */
 	}
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/osd/osd_initiator.c linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_initiator.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/osd/osd_initiator.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_initiator.c	2010-02-24 13:52:17.000000000 -0500
@@ -73,7 +73,8 @@ static const char *_osd_ver_desc(struct
 
 #define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
 
-static int _osd_print_system_info(struct osd_dev *od, void *caps)
+static int _osd_get_print_system_info(struct osd_dev *od,
+	void *caps, struct osd_dev_info *odi)
 {
 	struct osd_request *or;
 	struct osd_attr get_attrs[] = {
@@ -137,8 +138,12 @@ static int _osd_print_system_info(struct
 	OSD_INFO("PRODUCT_SERIAL_NUMBER  [%s]\n",
 		(char *)pFirst);
 
-	pFirst = get_attrs[a].val_ptr;
-	OSD_INFO("OSD_NAME               [%s]\n", (char *)pFirst);
+	odi->osdname_len = get_attrs[a].len;
+	/* Avoid NULL for memcmp optimization 0-length is good enough */
+	odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL);
+	if (odi->osdname_len)
+		memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len);
+	OSD_INFO("OSD_NAME               [%s]\n", odi->osdname);
 	a++;
 
 	pFirst = get_attrs[a++].val_ptr;
@@ -171,6 +176,14 @@ static int _osd_print_system_info(struct
 				   sid_dump, sizeof(sid_dump), true);
 		OSD_INFO("OSD_SYSTEM_ID(%d)\n"
 			 "        [%s]\n", len, sid_dump);
+
+		if (unlikely(len > sizeof(odi->systemid))) {
+			OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). "
+				"device idetification might not work\n", len);
+			len = sizeof(odi->systemid);
+		}
+		odi->systemid_len = len;
+		memcpy(odi->systemid, get_attrs[a].val_ptr, len);
 		a++;
 	}
 out:
@@ -178,16 +191,17 @@ out:
 	return ret;
 }
 
-int osd_auto_detect_ver(struct osd_dev *od, void *caps)
+int osd_auto_detect_ver(struct osd_dev *od,
+	void *caps, struct osd_dev_info *odi)
 {
 	int ret;
 
 	/* Auto-detect the osd version */
-	ret = _osd_print_system_info(od, caps);
+	ret = _osd_get_print_system_info(od, caps, odi);
 	if (ret) {
 		osd_dev_set_ver(od, OSD_VER1);
 		OSD_DEBUG("converting to OSD1\n");
-		ret = _osd_print_system_info(od, caps);
+		ret = _osd_get_print_system_info(od, caps, odi);
 	}
 
 	return ret;
@@ -418,30 +432,23 @@ static void _osd_free_seg(struct osd_req
 	seg->alloc_size = 0;
 }
 
-static void _put_request(struct request *rq , bool is_async)
+static void _put_request(struct request *rq)
 {
-	if (is_async) {
-		WARN_ON(rq->bio);
-		__blk_put_request(rq->q, rq);
-	} else {
-		/*
-		 * If osd_finalize_request() was called but the request was not
-		 * executed through the block layer, then we must release BIOs.
-		 * TODO: Keep error code in or->async_error. Need to audit all
-		 *       code paths.
-		 */
-		if (unlikely(rq->bio))
-			blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
-		else
-			blk_put_request(rq);
-	}
+	/*
+	 * If osd_finalize_request() was called but the request was not
+	 * executed through the block layer, then we must release BIOs.
+	 * TODO: Keep error code in or->async_error. Need to audit all
+	 *       code paths.
+	 */
+	if (unlikely(rq->bio))
+		blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
+	else
+		blk_put_request(rq);
 }
 
 void osd_end_request(struct osd_request *or)
 {
 	struct request *rq = or->request;
-	/* IMPORTANT: make sure this agrees with osd_execute_request_async */
-	bool is_async = (or->request->end_io_data == or);
 
 	_osd_free_seg(or, &or->set_attr);
 	_osd_free_seg(or, &or->enc_get_attr);
@@ -449,19 +456,34 @@ void osd_end_request(struct osd_request
 
 	if (rq) {
 		if (rq->next_rq) {
-			_put_request(rq->next_rq, is_async);
+			_put_request(rq->next_rq);
 			rq->next_rq = NULL;
 		}
 
-		_put_request(rq, is_async);
+		_put_request(rq);
 	}
 	_osd_request_free(or);
 }
 EXPORT_SYMBOL(osd_end_request);
 
+static void _set_error_resid(struct osd_request *or, struct request *req,
+			     int error)
+{
+	or->async_error = error;
+	or->req_errors = req->errors ? : error;
+	or->sense_len = req->sense_len;
+	if (or->out.req)
+		or->out.residual = or->out.req->resid_len;
+	if (or->in.req)
+		or->in.residual = or->in.req->resid_len;
+}
+
 int osd_execute_request(struct osd_request *or)
 {
-	return blk_execute_rq(or->request->q, NULL, or->request, 0);
+	int error = blk_execute_rq(or->request->q, NULL, or->request, 0);
+
+	_set_error_resid(or, or->request, error);
+	return error;
 }
 EXPORT_SYMBOL(osd_execute_request);
 
@@ -469,10 +491,16 @@ static void osd_request_async_done(struc
 {
 	struct osd_request *or = req->end_io_data;
 
-	or->async_error = error;
+	_set_error_resid(or, req, error);
+	if (req->next_rq) {
+		__blk_put_request(req->q, req->next_rq);
+		req->next_rq = NULL;
+	}
 
-	if (error)
-		OSD_DEBUG("osd_request_async_done error recieved %d\n", error);
+	__blk_put_request(req->q, req);
+	or->request = NULL;
+	or->in.req = NULL;
+	or->out.req = NULL;
 
 	if (or->async_done)
 		or->async_done(or, or->async_private);
@@ -1153,6 +1181,7 @@ int osd_req_decode_get_attr_list(struct
 				"c=%d r=%d n=%d\n",
 				cur_bytes, returned_bytes, n);
 			oa->val_ptr = NULL;
+			cur_bytes = returned_bytes; /* break the caller loop */
 			break;
 		}
 
@@ -1436,6 +1465,15 @@ int osd_finalize_request(struct osd_requ
 }
 EXPORT_SYMBOL(osd_finalize_request);
 
+static bool _is_osd_security_code(int code)
+{
+	return	(code == osd_security_audit_value_frozen) ||
+		(code == osd_security_working_key_frozen) ||
+		(code == osd_nonce_not_unique) ||
+		(code == osd_nonce_timestamp_out_of_range) ||
+		(code == osd_invalid_dataout_buffer_integrity_check_value);
+}
+
 #define OSD_SENSE_PRINT1(fmt, a...) \
 	do { \
 		if (__cur_sense_need_output) \
@@ -1458,27 +1496,29 @@ int osd_req_decode_sense_full(struct osd
 #else
 	bool __cur_sense_need_output = !silent;
 #endif
+	int ret;
 
-	if (!or->request->errors)
+	if (likely(!or->req_errors))
 		return 0;
 
-	ssdb = or->request->sense;
-	sense_len = or->request->sense_len;
+	osi = osi ? : &local_osi;
+	memset(osi, 0, sizeof(*osi));
+
+	ssdb = (typeof(ssdb))or->sense;
+	sense_len = or->sense_len;
 	if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) {
 		OSD_ERR("Block-layer returned error(0x%x) but "
 			"sense_len(%u) || key(%d) is empty\n",
-			or->request->errors, sense_len, ssdb->sense_key);
-		return -EIO;
+			or->req_errors, sense_len, ssdb->sense_key);
+		goto analyze;
 	}
 
 	if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) {
 		OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n",
 			ssdb->response_code, sense_len);
-		return -EIO;
+		goto analyze;
 	}
 
-	osi = osi ? : &local_osi;
-	memset(osi, 0, sizeof(*osi));
 	osi->key = ssdb->sense_key;
 	osi->additional_code = be16_to_cpu(ssdb->additional_sense_code);
 	original_sense_len = ssdb->additional_sense_length + 8;
@@ -1488,9 +1528,10 @@ int osd_req_decode_sense_full(struct osd
 		__cur_sense_need_output = (osi->key > scsi_sk_recovered_error);
 #endif
 	OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) "
-			"additional_code=0x%x\n",
+			"additional_code=0x%x async_error=%d errors=0x%x\n",
 			osi->key, original_sense_len, sense_len,
-			osi->additional_code);
+			osi->additional_code, or->async_error,
+			or->req_errors);
 
 	if (original_sense_len < sense_len)
 		sense_len = original_sense_len;
@@ -1569,15 +1610,14 @@ int osd_req_decode_sense_full(struct osd
 		{
 			struct osd_sense_attributes_data_descriptor
 				*osadd = cur_descriptor;
-			int len = min(cur_len, sense_len);
-			int i = 0;
+			unsigned len = min(cur_len, sense_len);
 			struct osd_sense_attr *pattr = osadd->sense_attrs;
 
-			while (len < 0) {
+			while (len >= sizeof(*pattr)) {
 				u32 attr_page = be32_to_cpu(pattr->attr_page);
 				u32 attr_id = be32_to_cpu(pattr->attr_id);
 
-				if (i++ == 0) {
+				if (!osi->attr.attr_page) {
 					osi->attr.attr_page = attr_page;
 					osi->attr.attr_id = attr_id;
 				}
@@ -1588,6 +1628,8 @@ int osd_req_decode_sense_full(struct osd
 					bad_attr_list++;
 					max_attr--;
 				}
+
+				len -= sizeof(*pattr);
 				OSD_SENSE_PRINT2(
 					"osd_sense_attribute_identification"
 					"attr_page=0x%x attr_id=0x%x\n",
@@ -1621,7 +1663,50 @@ int osd_req_decode_sense_full(struct osd
 		cur_descriptor += cur_len;
 	}
 
-	return (osi->key > scsi_sk_recovered_error) ? -EIO : 0;
+analyze:
+	if (!osi->key) {
+		/* scsi sense is Empty, the request was never issued to target
+		 * linux return code might tell us what happened.
+		 */
+		if (or->async_error == -ENOMEM)
+			osi->osd_err_pri = OSD_ERR_PRI_RESOURCE;
+		else
+			osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE;
+		ret = or->async_error;
+	} else if (osi->key <= scsi_sk_recovered_error) {
+		osi->osd_err_pri = 0;
+		ret = 0;
+	} else if (osi->additional_code == scsi_invalid_field_in_cdb) {
+		if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) {
+			osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES;
+			ret = -EFAULT; /* caller should recover from this */
+		} else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) {
+			osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND;
+			ret = -ENOENT;
+		} else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) {
+			osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS;
+			ret = -EACCES;
+		} else {
+			osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
+			ret = -EINVAL;
+		}
+	} else if (osi->additional_code == osd_quota_error) {
+		osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE;
+		ret = -ENOSPC;
+	} else if (_is_osd_security_code(osi->additional_code)) {
+		osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
+		ret = -EINVAL;
+	} else {
+		osi->osd_err_pri = OSD_ERR_PRI_EIO;
+		ret = -EIO;
+	}
+
+	if (!or->out.residual)
+		or->out.residual = or->out.total_bytes;
+	if (!or->in.residual)
+		or->in.residual = or->in.total_bytes;
+
+	return ret;
 }
 EXPORT_SYMBOL(osd_req_decode_sense_full);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/osd/osd_uld.c linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_uld.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/osd/osd_uld.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/osd/osd_uld.c	2010-02-24 13:52:17.000000000 -0500
@@ -71,8 +71,7 @@
 #define SCSI_OSD_MAX_MINOR 64
 
 static const char osd_name[] = "osd";
-static const char *osd_version_string = "open-osd 0.1.0";
-const char osd_symlink[] = "scsi_osd";
+static const char *osd_version_string = "open-osd 0.2.0";
 
 MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
 MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
@@ -82,15 +81,25 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_OSD);
 
 struct osd_uld_device {
 	int minor;
-	struct kref kref;
+	struct device class_dev;
 	struct cdev cdev;
 	struct osd_dev od;
+	struct osd_dev_info odi;
 	struct gendisk *disk;
-	struct device *class_member;
 };
 
-static void __uld_get(struct osd_uld_device *oud);
-static void __uld_put(struct osd_uld_device *oud);
+struct osd_dev_handle {
+	struct osd_dev od;
+	struct file *file;
+	struct osd_uld_device *oud;
+} ;
+
+static DEFINE_IDA(osd_minor_ida);
+
+static struct class osd_uld_class = {
+	.owner		= THIS_MODULE,
+	.name		= "scsi_osd",
+};
 
 /*
  * Char Device operations
@@ -101,7 +110,7 @@ static int osd_uld_open(struct inode *in
 	struct osd_uld_device *oud = container_of(inode->i_cdev,
 					struct osd_uld_device, cdev);
 
-	__uld_get(oud);
+	get_device(&oud->class_dev);
 	/* cache osd_uld_device on file handle */
 	file->private_data = oud;
 	OSD_DEBUG("osd_uld_open %p\n", oud);
@@ -114,7 +123,7 @@ static int osd_uld_release(struct inode
 
 	OSD_DEBUG("osd_uld_release %p\n", file->private_data);
 	file->private_data = NULL;
-	__uld_put(oud);
+	put_device(&oud->class_dev);
 	return 0;
 }
 
@@ -177,7 +186,7 @@ static const struct file_operations osd_
 struct osd_dev *osduld_path_lookup(const char *name)
 {
 	struct osd_uld_device *oud;
-	struct osd_dev *od;
+	struct osd_dev_handle *odh;
 	struct file *file;
 	int error;
 
@@ -186,8 +195,8 @@ struct osd_dev *osduld_path_lookup(const
 		return ERR_PTR(-EINVAL);
 	}
 
-	od = kzalloc(sizeof(*od), GFP_KERNEL);
-	if (!od)
+	odh = kzalloc(sizeof(*odh), GFP_KERNEL);
+	if (unlikely(!odh))
 		return ERR_PTR(-ENOMEM);
 
 	file = filp_open(name, O_RDWR, 0);
@@ -203,33 +212,134 @@ struct osd_dev *osduld_path_lookup(const
 
 	oud = file->private_data;
 
-	*od = oud->od;
-	od->file = file;
+	odh->od = oud->od;
+	odh->file = file;
+	odh->oud = oud;
 
-	return od;
+	return &odh->od;
 
 close_file:
 	fput(file);
 free_od:
-	kfree(od);
+	kfree(odh);
 	return ERR_PTR(error);
 }
 EXPORT_SYMBOL(osduld_path_lookup);
 
-void osduld_put_device(struct osd_dev *od)
+static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len,
+				     const u8 *a2, unsigned a2_len)
+{
+	if (!a2_len) /* User string is Empty means don't care */
+		return true;
+
+	if (a1_len != a2_len)
+		return false;
+
+	return 0 == memcmp(a1, a2, a1_len);
+}
+
+struct find_oud_t {
+	const struct osd_dev_info *odi;
+	struct device *dev;
+	struct osd_uld_device *oud;
+} ;
+
+int _mach_odi(struct device *dev, void *find_data)
 {
+	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
+						  class_dev);
+	struct find_oud_t *fot = find_data;
+	const struct osd_dev_info *odi = fot->odi;
 
+	if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
+			      odi->systemid, odi->systemid_len) &&
+	    _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
+			      odi->osdname, odi->osdname_len)) {
+		OSD_DEBUG("found device sysid_len=%d osdname=%d\n",
+			  odi->systemid_len, odi->osdname_len);
+		fot->oud = oud;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/* osduld_info_lookup - Loop through all devices, return the requested osd_dev.
+ *
+ * if @odi->systemid_len and/or @odi->osdname_len are zero, they act as a don't
+ * care. .e.g if they're both zero /dev/osd0 is returned.
+ */
+struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi)
+{
+	struct find_oud_t find = {.odi = odi};
+
+	find.dev = class_find_device(&osd_uld_class, NULL, &find, _mach_odi);
+	if (likely(find.dev)) {
+		struct osd_dev_handle *odh = kzalloc(sizeof(*odh), GFP_KERNEL);
+
+		if (unlikely(!odh)) {
+			put_device(find.dev);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		odh->od = find.oud->od;
+		odh->oud = find.oud;
+
+		return &odh->od;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(osduld_info_lookup);
+
+void osduld_put_device(struct osd_dev *od)
+{
 	if (od && !IS_ERR(od)) {
-		struct osd_uld_device *oud = od->file->private_data;
+		struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+		struct osd_uld_device *oud = odh->oud;
 
 		BUG_ON(od->scsi_device != oud->od.scsi_device);
 
-		fput(od->file);
-		kfree(od);
+		/* If scsi has released the device (logout), and exofs has last
+		 * reference on oud it will be freed by above osd_uld_release
+		 * within fput below. But this will oops in cdev_release which
+		 * is called after the fops->release. A get_/put_ pair makes
+		 * sure we have a cdev for the duration of fput
+		 */
+		if (odh->file) {
+			get_device(&oud->class_dev);
+			fput(odh->file);
+		}
+		put_device(&oud->class_dev);
+		kfree(odh);
 	}
 }
 EXPORT_SYMBOL(osduld_put_device);
 
+const struct osd_dev_info *osduld_device_info(struct osd_dev *od)
+{
+	struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+	return &odh->oud->odi;
+}
+EXPORT_SYMBOL(osduld_device_info);
+
+bool osduld_device_same(struct osd_dev *od, const struct osd_dev_info *odi)
+{
+	struct osd_dev_handle *odh =
+				container_of(od, struct osd_dev_handle, od);
+	struct osd_uld_device *oud = odh->oud;
+
+	return (oud->odi.systemid_len == odi->systemid_len) &&
+		_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
+				 odi->systemid, odi->systemid_len) &&
+		(oud->odi.osdname_len == odi->osdname_len) &&
+		_the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
+				  odi->osdname, odi->osdname_len);
+}
+EXPORT_SYMBOL(osduld_device_same);
+
 /*
  * Scsi Device operations
  */
@@ -250,14 +360,35 @@ static int __detect_osd(struct osd_uld_d
 		OSD_ERR("warning: scsi_test_unit_ready failed\n");
 
 	osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
-	if (osd_auto_detect_ver(&oud->od, caps))
+	if (osd_auto_detect_ver(&oud->od, caps, &oud->odi))
 		return -ENODEV;
 
 	return 0;
 }
 
-static struct class *osd_sysfs_class;
-static DEFINE_IDA(osd_minor_ida);
+static void __remove(struct device *dev)
+{
+	struct osd_uld_device *oud = container_of(dev, struct osd_uld_device,
+						  class_dev);
+	struct scsi_device *scsi_device = oud->od.scsi_device;
+
+	kfree(oud->odi.osdname);
+
+	if (oud->cdev.owner)
+		cdev_del(&oud->cdev);
+
+	osd_dev_fini(&oud->od);
+	scsi_device_put(scsi_device);
+
+	OSD_INFO("osd_remove %s\n",
+		 oud->disk ? oud->disk->disk_name : NULL);
+
+	if (oud->disk)
+		put_disk(oud->disk);
+	ida_remove(&osd_minor_ida, oud->minor);
+
+	kfree(oud);
+}
 
 static int osd_probe(struct device *dev)
 {
@@ -289,7 +420,6 @@ static int osd_probe(struct device *dev)
 	if (NULL == oud)
 		goto err_retract_minor;
 
-	kref_init(&oud->kref);
 	dev_set_drvdata(dev, oud);
 	oud->minor = minor;
 
@@ -327,18 +457,25 @@ static int osd_probe(struct device *dev)
 		OSD_ERR("cdev_add failed\n");
 		goto err_put_disk;
 	}
-	kobject_get(&oud->cdev.kobj); /* 2nd ref see osd_remove() */
 
-	/* class_member */
-	oud->class_member = device_create(osd_sysfs_class, dev,
-		MKDEV(SCSI_OSD_MAJOR, oud->minor), "%s", disk->disk_name);
-	if (IS_ERR(oud->class_member)) {
-		OSD_ERR("class_device_create failed\n");
-		error = PTR_ERR(oud->class_member);
+	/* class device member */
+	oud->class_dev.devt = oud->cdev.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);
+	if (error) {
+		OSD_ERR("dev_set_name failed => %d\n", error);
 		goto err_put_cdev;
 	}
 
-	dev_set_drvdata(oud->class_member, oud);
+	error = device_register(&oud->class_dev);
+	if (error) {
+		OSD_ERR("device_register failed => %d\n", error);
+		goto err_put_cdev;
+	}
+
+	get_device(&oud->class_dev);
 
 	OSD_INFO("osd_probe %s\n", disk->disk_name);
 	return 0;
@@ -367,54 +504,12 @@ static int osd_remove(struct device *dev
 			scsi_device);
 	}
 
-	if (oud->class_member)
-		device_destroy(osd_sysfs_class,
-			       MKDEV(SCSI_OSD_MAJOR, oud->minor));
-
-	/* We have 2 references to the cdev. One is released here
-	 * and also takes down the /dev/osdX mapping. The second
-	 * Will be released in __remove() after all users have released
-	 * the osd_uld_device.
-	 */
-	if (oud->cdev.owner)
-		cdev_del(&oud->cdev);
+	device_unregister(&oud->class_dev);
 
-	__uld_put(oud);
+	put_device(&oud->class_dev);
 	return 0;
 }
 
-static void __remove(struct kref *kref)
-{
-	struct osd_uld_device *oud = container_of(kref,
-					struct osd_uld_device, kref);
-	struct scsi_device *scsi_device = oud->od.scsi_device;
-
-	/* now let delete the char_dev */
-	kobject_put(&oud->cdev.kobj);
-
-	osd_dev_fini(&oud->od);
-	scsi_device_put(scsi_device);
-
-	OSD_INFO("osd_remove %s\n",
-		 oud->disk ? oud->disk->disk_name : NULL);
-
-	if (oud->disk)
-		put_disk(oud->disk);
-
-	ida_remove(&osd_minor_ida, oud->minor);
-	kfree(oud);
-}
-
-static void __uld_get(struct osd_uld_device *oud)
-{
-	kref_get(&oud->kref);
-}
-
-static void __uld_put(struct osd_uld_device *oud)
-{
-	kref_put(&oud->kref, __remove);
-}
-
 /*
  * Global driver and scsi registration
  */
@@ -432,11 +527,10 @@ static int __init osd_uld_init(void)
 {
 	int err;
 
-	osd_sysfs_class = class_create(THIS_MODULE, osd_symlink);
-	if (IS_ERR(osd_sysfs_class)) {
-		OSD_ERR("Unable to register sysfs class => %ld\n",
-			PTR_ERR(osd_sysfs_class));
-		return PTR_ERR(osd_sysfs_class);
+	err = class_register(&osd_uld_class);
+	if (err) {
+		OSD_ERR("Unable to register sysfs class => %d\n", err);
+		return err;
 	}
 
 	err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0),
@@ -459,7 +553,7 @@ static int __init osd_uld_init(void)
 err_out_chrdev:
 	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
 err_out:
-	class_destroy(osd_sysfs_class);
+	class_unregister(&osd_uld_class);
 	return err;
 }
 
@@ -467,7 +561,7 @@ static void __exit osd_uld_exit(void)
 {
 	scsi_unregister_driver(&osd_driver.gendrv);
 	unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
-	class_destroy(osd_sysfs_class);
+	class_unregister(&osd_uld_class);
 	OSD_INFO("UNLOADED %s\n", osd_version_string);
 }
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/aha152x_stub.c linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/aha152x_stub.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/aha152x_stub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/aha152x_stub.c	2010-02-24 13:52:17.000000000 -0500
@@ -54,15 +54,6 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -103,7 +94,7 @@ static int aha152x_probe(struct pcmcia_d
 {
     scsi_info_t *info;
 
-    DEBUG(0, "aha152x_attach()\n");
+    dev_dbg(&link->dev, "aha152x_attach()\n");
 
     /* Create new SCSI device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -115,7 +106,6 @@ static int aha152x_probe(struct pcmcia_d
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
@@ -127,7 +117,7 @@ static int aha152x_probe(struct pcmcia_d
 
 static void aha152x_detach(struct pcmcia_device *link)
 {
-    DEBUG(0, "aha152x_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "aha152x_detach\n");
 
     aha152x_release_cs(link);
 
@@ -137,9 +127,6 @@ static void aha152x_detach(struct pcmcia
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int aha152x_config_check(struct pcmcia_device *p_dev,
 				cistpl_cftable_entry_t *cfg,
 				cistpl_cftable_entry_t *dflt,
@@ -164,19 +151,22 @@ static int aha152x_config_cs(struct pcmc
 {
     scsi_info_t *info = link->priv;
     struct aha152x_setup s;
-    int last_ret, last_fn;
+    int ret;
     struct Scsi_Host *host;
 
-    DEBUG(0, "aha152x_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "aha152x_config\n");
 
-    last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
-    if (last_ret) {
-	cs_error(link, RequestIO, last_ret);
-	goto failed;
-    }
+    ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
+    if (ret)
+	    goto failed;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
     
     /* Set configuration options for the aha152x driver */
     memset(&s, 0, sizeof(s));
@@ -194,7 +184,7 @@ static int aha152x_config_cs(struct pcmc
     host = aha152x_probe_one(&s);
     if (host == NULL) {
 	printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
-	goto cs_failed;
+	goto failed;
     }
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -203,8 +193,6 @@ static int aha152x_config_cs(struct pcmc
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     aha152x_release_cs(link);
     return -ENODEV;
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/fdomain_stub.c linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/fdomain_stub.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/fdomain_stub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/fdomain_stub.c	2010-02-24 13:52:17.000000000 -0500
@@ -59,16 +59,6 @@ MODULE_AUTHOR("David Hinds <dahinds@user
 MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
 typedef struct scsi_info_t {
@@ -86,7 +76,7 @@ static int fdomain_probe(struct pcmcia_d
 {
 	scsi_info_t *info;
 
-	DEBUG(0, "fdomain_attach()\n");
+	dev_dbg(&link->dev, "fdomain_attach()\n");
 
 	/* Create new SCSI device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -99,7 +89,6 @@ static int fdomain_probe(struct pcmcia_d
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
@@ -111,7 +100,7 @@ static int fdomain_probe(struct pcmcia_d
 
 static void fdomain_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "fdomain_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "fdomain_detach\n");
 
 	fdomain_release(link);
 
@@ -120,9 +109,6 @@ static void fdomain_detach(struct pcmcia
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int fdomain_config_check(struct pcmcia_device *p_dev,
 				cistpl_cftable_entry_t *cfg,
 				cistpl_cftable_entry_t *dflt,
@@ -137,20 +123,22 @@ static int fdomain_config_check(struct p
 static int fdomain_config(struct pcmcia_device *link)
 {
     scsi_info_t *info = link->priv;
-    int last_ret, last_fn;
+    int ret;
     char str[22];
     struct Scsi_Host *host;
 
-    DEBUG(0, "fdomain_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "fdomain_config\n");
 
-    last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
-    if (last_ret) {
-	    cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+    if (ret)
 	    goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+	    goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+	    goto failed;
 
     /* A bad hack... */
     release_region(link->io.BasePort1, link->io.NumPorts1);
@@ -162,11 +150,11 @@ static int fdomain_config(struct pcmcia_
     host = __fdomain_16x0_detect(&fdomain_driver_template);
     if (!host) {
         printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
-	goto cs_failed;
+	goto failed;
     }
 
     if (scsi_add_host(host, NULL))
-	    goto cs_failed;
+	    goto failed;
     scsi_scan_host(host);
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -175,8 +163,6 @@ static int fdomain_config(struct pcmcia_
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     fdomain_release(link);
     return -ENODEV;
@@ -188,7 +174,7 @@ static void fdomain_release(struct pcmci
 {
 	scsi_info_t *info = link->priv;
 
-	DEBUG(0, "fdomain_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "fdomain_release\n");
 
 	scsi_remove_host(info->host);
 	pcmcia_disable_device(link);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/nsp_cs.c linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/nsp_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/nsp_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -1564,12 +1564,10 @@ static int nsp_cs_probe(struct pcmcia_de
 	link->io.IOAddrLines	 = 10;	/* not used */
 
 	/* Interrupt setup */
-	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1	 = IRQ_LEVEL_ID;
+	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE;
 
 	/* Interrupt handler */
 	link->irq.Handler	 = &nspintr;
-	link->irq.Instance       = info;
 	link->irq.Attributes     |= IRQF_SHARED;
 
 	/* General socket configuration */
@@ -1684,10 +1682,10 @@ static int nsp_cs_config_check(struct pc
 			if (cfg_mem->req.Size < 0x1000)
 				cfg_mem->req.Size = 0x1000;
 			cfg_mem->req.AccessSpeed = 0;
-			if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
+			if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
 				goto next_entry;
 			map.Page = 0; map.CardOffset = mem->win[0].card_addr;
-			if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+			if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
 				goto next_entry;
 
 			cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/qlogic_stub.c linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/qlogic_stub.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/qlogic_stub.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/qlogic_stub.c	2010-02-24 13:52:17.000000000 -0500
@@ -62,15 +62,6 @@
 
 static char qlogic_name[] = "qlogic_cs";
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 static struct scsi_host_template qlogicfas_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= qlogic_name,
@@ -159,7 +150,7 @@ static int qlogic_probe(struct pcmcia_de
 {
 	scsi_info_t *info;
 
-	DEBUG(0, "qlogic_attach()\n");
+	dev_dbg(&link->dev, "qlogic_attach()\n");
 
 	/* Create new SCSI device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -171,7 +162,6 @@ static int qlogic_probe(struct pcmcia_de
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
@@ -183,7 +173,7 @@ static int qlogic_probe(struct pcmcia_de
 
 static void qlogic_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "qlogic_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "qlogic_detach\n");
 
 	qlogic_release(link);
 	kfree(link->priv);
@@ -192,9 +182,6 @@ static void qlogic_detach(struct pcmcia_
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int qlogic_config_check(struct pcmcia_device *p_dev,
 			       cistpl_cftable_entry_t *cfg,
 			       cistpl_cftable_entry_t *dflt,
@@ -213,19 +200,22 @@ static int qlogic_config_check(struct pc
 static int qlogic_config(struct pcmcia_device * link)
 {
 	scsi_info_t *info = link->priv;
-	int last_ret, last_fn;
+	int ret;
 	struct Scsi_Host *host;
 
-	DEBUG(0, "qlogic_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "qlogic_config\n");
 
-	last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
-	if (last_ret) {
-		cs_error(link, RequestIO, last_ret);
+	ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
+	if (ret)
 		goto failed;
-	}
 
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
+
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
 		/* set ATAcmd */
@@ -244,7 +234,7 @@ static int qlogic_config(struct pcmcia_d
 	
 	if (!host) {
 		printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
-		goto cs_failed;
+		goto failed;
 	}
 
 	sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -253,12 +243,9 @@ static int qlogic_config(struct pcmcia_d
 
 	return 0;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
-	pcmcia_disable_device(link);
 failed:
+	pcmcia_disable_device(link);
 	return -ENODEV;
-
 }				/* qlogic_config */
 
 /*====================================================================*/
@@ -267,7 +254,7 @@ static void qlogic_release(struct pcmcia
 {
 	scsi_info_t *info = link->priv;
 
-	DEBUG(0, "qlogic_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "qlogic_release\n");
 
 	scsi_remove_host(info->host);
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/sym53c500_cs.c linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/sym53c500_cs.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pcmcia/sym53c500_cs.c	2009-12-02 22:51:21.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pcmcia/sym53c500_cs.c	2010-02-24 13:52:17.000000000 -0500
@@ -77,17 +77,6 @@
 #include <pcmcia/ds.h>
 #include <pcmcia/ciscode.h>
 
-/* ================================================================== */
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"sym53c500_cs.c 0.9c 2004/10/27 (Bob Tracy)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /* ================================================================== */
 
@@ -525,7 +514,7 @@ SYM53C500_release(struct pcmcia_device *
 	struct scsi_info_t *info = link->priv;
 	struct Scsi_Host *shost = info->host;
 
-	DEBUG(0, "SYM53C500_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "SYM53C500_release\n");
 
 	/*
 	*  Do this before releasing/freeing resources.
@@ -697,9 +686,6 @@ static struct scsi_host_template sym53c5
      .shost_attrs		= SYM53C500_shost_attrs
 };
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int SYM53C500_config_check(struct pcmcia_device *p_dev,
 				  cistpl_cftable_entry_t *cfg,
 				  cistpl_cftable_entry_t *dflt,
@@ -719,24 +705,27 @@ static int
 SYM53C500_config(struct pcmcia_device *link)
 {
 	struct scsi_info_t *info = link->priv;
-	int last_ret, last_fn;
+	int ret;
 	int irq_level, port_base;
 	struct Scsi_Host *host;
 	struct scsi_host_template *tpnt = &sym53c500_driver_template;
 	struct sym53c500_data *data;
 
-	DEBUG(0, "SYM53C500_config(0x%p)\n", link);
+	dev_dbg(&link->dev, "SYM53C500_config\n");
 
 	info->manf_id = link->manf_id;
 
-	last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
-	if (last_ret) {
-		cs_error(link, RequestIO, last_ret);
+	ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
+	if (ret)
 		goto failed;
-	}
 
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret)
+		goto failed;
+
+	ret = pcmcia_request_configuration(link, &link->conf);
+	if (ret)
+		goto failed;
 
 	/*
 	*  That's the trouble with copying liberally from another driver.
@@ -824,8 +813,6 @@ err_release:
 	printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
 	return -ENODEV;
 
-cs_failed:
-	cs_error(link, last_fn, last_ret);
 failed:
 	SYM53C500_release(link);
 	return -ENODEV;
@@ -855,7 +842,7 @@ static int sym53c500_resume(struct pcmci
 static void
 SYM53C500_detach(struct pcmcia_device *link)
 {
-	DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
+	dev_dbg(&link->dev, "SYM53C500_detach\n");
 
 	SYM53C500_release(link);
 
@@ -868,7 +855,7 @@ SYM53C500_probe(struct pcmcia_device *li
 {
 	struct scsi_info_t *info;
 
-	DEBUG(0, "SYM53C500_attach()\n");
+	dev_dbg(&link->dev, "SYM53C500_attach()\n");
 
 	/* Create new SCSI device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -880,7 +867,6 @@ SYM53C500_probe(struct pcmcia_device *li
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/Makefile linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/Makefile
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/Makefile	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,12 @@
+#
+# Kernel configuration file for the PM8001 SAS/SATA 8x6G based HBA driver
+#
+# Copyright (C) 2008-2009  USI Co., Ltd.
+
+
+obj-$(CONFIG_SCSI_PM8001) += pm8001.o
+pm8001-y += pm8001_init.o \
+		pm8001_sas.o  \
+		pm8001_ctl.o  \
+		pm8001_hwi.o
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_chips.h linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_chips.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_chips.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_chips.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,89 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * 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.
+ *
+ */
+
+#ifndef _PM8001_CHIPS_H_
+#define _PM8001_CHIPS_H_
+
+static inline u32 pm8001_read_32(void *virt_addr)
+{
+	return *((u32 *)virt_addr);
+}
+
+static inline void pm8001_write_32(void *addr, u32 offset, u32 val)
+{
+	*((u32 *)(addr + offset)) = val;
+}
+
+static inline u32 pm8001_cr32(struct pm8001_hba_info *pm8001_ha, u32 bar,
+		u32 offset)
+{
+	return readl(pm8001_ha->io_mem[bar].memvirtaddr + offset);
+}
+
+static inline void pm8001_cw32(struct pm8001_hba_info *pm8001_ha, u32 bar,
+		u32 addr, u32 val)
+{
+	writel(val, pm8001_ha->io_mem[bar].memvirtaddr + addr);
+}
+static inline u32 pm8001_mr32(void __iomem *addr, u32 offset)
+{
+	return readl(addr + offset);
+}
+static inline void pm8001_mw32(void __iomem *addr, u32 offset, u32 val)
+{
+	writel(val, addr + offset);
+}
+static inline u32 get_pci_bar_index(u32 pcibar)
+{
+		switch (pcibar) {
+		case 0x18:
+		case 0x1C:
+			return 1;
+		case 0x20:
+			return 2;
+		case 0x24:
+			return 3;
+		default:
+			return 0;
+	}
+}
+
+#endif  /* _PM8001_CHIPS_H_ */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_ctl.c linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_ctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,573 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * 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 <linux/firmware.h>
+#include "pm8001_sas.h"
+#include "pm8001_ctl.h"
+
+/* scsi host attributes */
+
+/**
+ * pm8001_ctl_mpi_interface_rev_show - MPI interface revision number
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+		pm8001_ha->main_cfg_tbl.interface_rev);
+}
+static
+DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
+
+/**
+ * pm8001_ctl_fw_version_show - firmware version
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_fw_version_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8),
+		       (u8)(pm8001_ha->main_cfg_tbl.firmware_rev));
+}
+static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
+/**
+ * pm8001_ctl_max_out_io_show - max outstanding io supported
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_out_io_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			pm8001_ha->main_cfg_tbl.max_out_io);
+}
+static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL);
+/**
+ * pm8001_ctl_max_devices_show - max devices support
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_devices_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%04d\n",
+			(u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16));
+}
+static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL);
+/**
+ * pm8001_ctl_max_sg_list_show - max sg list supported iff not 0.0 for no
+ * hardware limitation
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_max_sg_list_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%04d\n",
+			pm8001_ha->main_cfg_tbl.max_sgl & 0x0000FFFF);
+}
+static DEVICE_ATTR(max_sg_list, S_IRUGO, pm8001_ctl_max_sg_list_show, NULL);
+
+#define SAS_1_0 0x1
+#define SAS_1_1 0x2
+#define SAS_2_0 0x4
+
+static ssize_t
+show_sas_spec_support_status(unsigned int mode, char *buf)
+{
+	ssize_t len = 0;
+
+	if (mode & SAS_1_1)
+		len = sprintf(buf, "%s", "SAS1.1");
+	if (mode & SAS_2_0)
+		len += sprintf(buf + len, "%s%s", len ? ", " : "", "SAS2.0");
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+/**
+ * pm8001_ctl_sas_spec_support_show - sas spec supported
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_sas_spec_support_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	unsigned int mode;
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	mode = (pm8001_ha->main_cfg_tbl.ctrl_cap_flag & 0xfe000000)>>25;
+	return show_sas_spec_support_status(mode, buf);
+}
+static DEVICE_ATTR(sas_spec_support, S_IRUGO,
+		   pm8001_ctl_sas_spec_support_show, NULL);
+
+/**
+ * pm8001_ctl_sas_address_show - sas address
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * This is the controller sas address
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_host_sas_address_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
+			be64_to_cpu(*(__be64 *)pm8001_ha->sas_addr));
+}
+static DEVICE_ATTR(host_sas_address, S_IRUGO,
+		   pm8001_ctl_host_sas_address_show, NULL);
+
+/**
+ * pm8001_ctl_logging_level_show - logging level
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read/write' shost attribute.
+ */
+static ssize_t pm8001_ctl_logging_level_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	return snprintf(buf, PAGE_SIZE, "%08xh\n", pm8001_ha->logging_level);
+}
+static ssize_t pm8001_ctl_logging_level_store(struct device *cdev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	int val = 0;
+
+	if (sscanf(buf, "%x", &val) != 1)
+		return -EINVAL;
+
+	pm8001_ha->logging_level = val;
+	return strlen(buf);
+}
+
+static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
+	pm8001_ctl_logging_level_show, pm8001_ctl_logging_level_store);
+/**
+ * pm8001_ctl_aap_log_show - aap1 event log
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	int i;
+#define AAP1_MEMMAP(r, c) \
+	(*(u32 *)((u8*)pm8001_ha->memoryMap.region[AAP1].virt_ptr + (r) * 32 \
+	+ (c)))
+
+	char *str = buf;
+	int max = 2;
+	for (i = 0; i < max; i++) {
+		str += sprintf(str, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x"
+			       "0x%08x 0x%08x\n",
+			       AAP1_MEMMAP(i, 0),
+			       AAP1_MEMMAP(i, 4),
+			       AAP1_MEMMAP(i, 8),
+			       AAP1_MEMMAP(i, 12),
+			       AAP1_MEMMAP(i, 16),
+			       AAP1_MEMMAP(i, 20),
+			       AAP1_MEMMAP(i, 24),
+			       AAP1_MEMMAP(i, 28));
+	}
+
+	return str - buf;
+}
+static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);
+/**
+ * pm8001_ctl_aap_log_show - IOP event log
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_iop_log_show(struct device *cdev,
+	struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+#define IOP_MEMMAP(r, c) \
+	(*(u32 *)((u8*)pm8001_ha->memoryMap.region[IOP].virt_ptr + (r) * 32 \
+	+ (c)))
+	int i;
+	char *str = buf;
+	int max = 2;
+	for (i = 0; i < max; i++) {
+		str += sprintf(str, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x"
+			       "0x%08x 0x%08x\n",
+			       IOP_MEMMAP(i, 0),
+			       IOP_MEMMAP(i, 4),
+			       IOP_MEMMAP(i, 8),
+			       IOP_MEMMAP(i, 12),
+			       IOP_MEMMAP(i, 16),
+			       IOP_MEMMAP(i, 20),
+			       IOP_MEMMAP(i, 24),
+			       IOP_MEMMAP(i, 28));
+	}
+
+	return str - buf;
+}
+static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL);
+
+#define FLASH_CMD_NONE      0x00
+#define FLASH_CMD_UPDATE    0x01
+#define FLASH_CMD_SET_NVMD    0x02
+
+struct flash_command {
+     u8      command[8];
+     int     code;
+};
+
+static struct flash_command flash_command_table[] =
+{
+     {"set_nvmd",    FLASH_CMD_SET_NVMD},
+     {"update",      FLASH_CMD_UPDATE},
+     {"",            FLASH_CMD_NONE} /* Last entry should be NULL. */
+};
+
+struct error_fw {
+     char    *reason;
+     int     err_code;
+};
+
+static struct error_fw flash_error_table[] =
+{
+     {"Failed to open fw image file",	FAIL_OPEN_BIOS_FILE},
+     {"image header mismatch",		FLASH_UPDATE_HDR_ERR},
+     {"image offset mismatch",		FLASH_UPDATE_OFFSET_ERR},
+     {"image CRC Error",		FLASH_UPDATE_CRC_ERR},
+     {"image length Error.",		FLASH_UPDATE_LENGTH_ERR},
+     {"Failed to program flash chip",	FLASH_UPDATE_HW_ERR},
+     {"Flash chip not supported.",	FLASH_UPDATE_DNLD_NOT_SUPPORTED},
+     {"Flash update disabled.",		FLASH_UPDATE_DISABLED},
+     {"Flash in progress",		FLASH_IN_PROGRESS},
+     {"Image file size Error",		FAIL_FILE_SIZE},
+     {"Input parameter error",		FAIL_PARAMETERS},
+     {"Out of memory",			FAIL_OUT_MEMORY},
+     {"OK", 0}	/* Last entry err_code = 0. */
+};
+
+static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pm8001_ioctl_payload	*payload;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	u8		*ioctlbuffer = NULL;
+	u32		length = 0;
+	u32		ret = 0;
+
+	length = 1024 * 5 + sizeof(*payload) - 1;
+	ioctlbuffer = kzalloc(length, GFP_KERNEL);
+	if (!ioctlbuffer)
+		return -ENOMEM;
+	if ((pm8001_ha->fw_image->size <= 0) ||
+	    (pm8001_ha->fw_image->size > 4096)) {
+		ret = FAIL_FILE_SIZE;
+		goto out;
+	}
+	payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
+	memcpy((u8 *)payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
+				pm8001_ha->fw_image->size);
+	payload->length = pm8001_ha->fw_image->size;
+	payload->id = 0;
+	pm8001_ha->nvmd_completion = &completion;
+	ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
+	wait_for_completion(&completion);
+out:
+	kfree(ioctlbuffer);
+	return ret;
+}
+
+static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
+{
+	struct pm8001_ioctl_payload	*payload;
+	DECLARE_COMPLETION_ONSTACK(completion);
+	u8		*ioctlbuffer = NULL;
+	u32		length = 0;
+	struct fw_control_info	*fwControl;
+	u32		loopNumber, loopcount = 0;
+	u32		sizeRead = 0;
+	u32		partitionSize, partitionSizeTmp;
+	u32		ret = 0;
+	u32		partitionNumber = 0;
+	struct pm8001_fw_image_header *image_hdr;
+
+	length = 1024 * 16 + sizeof(*payload) - 1;
+	ioctlbuffer = kzalloc(length, GFP_KERNEL);
+	image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data;
+	if (!ioctlbuffer)
+		return -ENOMEM;
+	if (pm8001_ha->fw_image->size < 28) {
+		ret = FAIL_FILE_SIZE;
+		goto out;
+	}
+
+	while (sizeRead < pm8001_ha->fw_image->size) {
+		partitionSizeTmp =
+			*(u32 *)((u8 *)&image_hdr->image_length + sizeRead);
+		partitionSize = be32_to_cpu(partitionSizeTmp);
+		loopcount = (partitionSize + HEADER_LEN)/IOCTL_BUF_SIZE;
+		if (loopcount % IOCTL_BUF_SIZE)
+			loopcount++;
+		if (loopcount == 0)
+			loopcount++;
+		for (loopNumber = 0; loopNumber < loopcount; loopNumber++) {
+			payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
+			payload->length = 1024*16;
+			payload->id = 0;
+			fwControl =
+			      (struct fw_control_info *)payload->func_specific;
+			fwControl->len = IOCTL_BUF_SIZE;   /* IN */
+			fwControl->size = partitionSize + HEADER_LEN;/* IN */
+			fwControl->retcode = 0;/* OUT */
+			fwControl->offset = loopNumber * IOCTL_BUF_SIZE;/*OUT */
+
+		/* for the last chunk of data in case file size is not even with
+		4k, load only the rest*/
+		if (((loopcount-loopNumber) == 1) &&
+			((partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE)) {
+			fwControl->len =
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE;
+			memcpy((u8 *)fwControl->buffer,
+				(u8 *)pm8001_ha->fw_image->data + sizeRead,
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE);
+			sizeRead +=
+				(partitionSize + HEADER_LEN) % IOCTL_BUF_SIZE;
+		} else {
+			memcpy((u8 *)fwControl->buffer,
+				(u8 *)pm8001_ha->fw_image->data + sizeRead,
+				IOCTL_BUF_SIZE);
+			sizeRead += IOCTL_BUF_SIZE;
+		}
+
+		pm8001_ha->nvmd_completion = &completion;
+		ret = PM8001_CHIP_DISP->fw_flash_update_req(pm8001_ha, payload);
+		wait_for_completion(&completion);
+		if (ret || (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS)) {
+			ret = fwControl->retcode;
+			kfree(ioctlbuffer);
+			ioctlbuffer = NULL;
+			break;
+		}
+	}
+	if (ret)
+		break;
+	partitionNumber++;
+}
+out:
+	kfree(ioctlbuffer);
+	return ret;
+}
+static ssize_t pm8001_store_update_fw(struct device *cdev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+	char *cmd_ptr, *filename_ptr;
+	int res, i;
+	int flash_command = FLASH_CMD_NONE;
+	int err = 0;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	cmd_ptr = kzalloc(count*2, GFP_KERNEL);
+
+	if (!cmd_ptr) {
+		err = FAIL_OUT_MEMORY;
+		goto out;
+	}
+
+	filename_ptr = cmd_ptr + count;
+	res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr);
+	if (res != 2) {
+		err = FAIL_PARAMETERS;
+		goto out1;
+	}
+
+	for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) {
+		if (!memcmp(flash_command_table[i].command,
+				 cmd_ptr, strlen(cmd_ptr))) {
+			flash_command = flash_command_table[i].code;
+			break;
+		}
+	}
+	if (flash_command == FLASH_CMD_NONE) {
+		err = FAIL_PARAMETERS;
+		goto out1;
+	}
+
+	if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) {
+		err = FLASH_IN_PROGRESS;
+		goto out1;
+	}
+	err = request_firmware(&pm8001_ha->fw_image,
+			       filename_ptr,
+			       pm8001_ha->dev);
+
+	if (err) {
+		PM8001_FAIL_DBG(pm8001_ha,
+			pm8001_printk("Failed to load firmware image file %s,"
+			" error %d\n", filename_ptr, err));
+		err = FAIL_OPEN_BIOS_FILE;
+		goto out1;
+	}
+
+	switch (flash_command) {
+	case FLASH_CMD_UPDATE:
+		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
+		err = pm8001_update_flash(pm8001_ha);
+		break;
+	case FLASH_CMD_SET_NVMD:
+		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
+		err = pm8001_set_nvmd(pm8001_ha);
+		break;
+	default:
+		pm8001_ha->fw_status = FAIL_PARAMETERS;
+		err = FAIL_PARAMETERS;
+		break;
+	}
+	release_firmware(pm8001_ha->fw_image);
+out1:
+	kfree(cmd_ptr);
+out:
+	pm8001_ha->fw_status = err;
+
+	if (!err)
+		return count;
+	else
+		return -err;
+}
+
+static ssize_t pm8001_show_update_fw(struct device *cdev,
+				     struct device_attribute *attr, char *buf)
+{
+	int i;
+	struct Scsi_Host *shost = class_to_shost(cdev);
+	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+	for (i = 0; flash_error_table[i].err_code != 0; i++) {
+		if (flash_error_table[i].err_code == pm8001_ha->fw_status)
+			break;
+	}
+	if (pm8001_ha->fw_status != FLASH_IN_PROGRESS)
+		pm8001_ha->fw_status = FLASH_OK;
+
+	return snprintf(buf, PAGE_SIZE, "status=%x %s\n",
+			flash_error_table[i].err_code,
+			flash_error_table[i].reason);
+}
+
+static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUGO,
+	pm8001_show_update_fw, pm8001_store_update_fw);
+struct device_attribute *pm8001_host_attrs[] = {
+	&dev_attr_interface_rev,
+	&dev_attr_fw_version,
+	&dev_attr_update_fw,
+	&dev_attr_aap_log,
+	&dev_attr_iop_log,
+	&dev_attr_max_out_io,
+	&dev_attr_max_devices,
+	&dev_attr_max_sg_list,
+	&dev_attr_sas_spec_support,
+	&dev_attr_logging_level,
+	&dev_attr_host_sas_address,
+	NULL,
+};
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_ctl.h linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_ctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_ctl.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,57 @@
+ /*
+  * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+  *
+  * Copyright (c) 2008-2009 USI Co., Ltd.
+  * 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.
+  *
+  */
+
+#ifndef PM8001_CTL_H_INCLUDED
+#define PM8001_CTL_H_INCLUDED
+
+#define IOCTL_BUF_SIZE		4096
+#define HEADER_LEN			28
+#define SIZE_OFFSET			16
+
+
+#define FLASH_OK                        0x000000
+#define FAIL_OPEN_BIOS_FILE             0x000100
+#define FAIL_FILE_SIZE                  0x000a00
+#define FAIL_PARAMETERS                 0x000b00
+#define FAIL_OUT_MEMORY                 0x000c00
+#define FLASH_IN_PROGRESS               0x001000
+
+#endif /* PM8001_CTL_H_INCLUDED */
+
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_defs.h linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_defs.h
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_defs.h	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,112 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * 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.
+ *
+ */
+
+#ifndef _PM8001_DEFS_H_
+#define _PM8001_DEFS_H_
+
+enum chip_flavors {
+	chip_8001,
+};
+#define USI_MAX_MEMCNT			9
+#define PM8001_MAX_DMA_SG		SG_ALL
+enum phy_speed {
+	PHY_SPEED_15 = 0x01,
+	PHY_SPEED_30 = 0x02,
+	PHY_SPEED_60 = 0x04,
+};
+
+enum data_direction {
+	DATA_DIR_NONE = 0x0,	/* NO TRANSFER */
+	DATA_DIR_IN = 0x01,	/* INBOUND */
+	DATA_DIR_OUT = 0x02,	/* OUTBOUND */
+	DATA_DIR_BYRECIPIENT = 0x04, /* UNSPECIFIED */
+};
+
+enum port_type {
+	PORT_TYPE_SAS = (1L << 1),
+	PORT_TYPE_SATA = (1L << 0),
+};
+
+/* driver compile-time configuration */
+#define	PM8001_MAX_CCB		 512	/* max ccbs supported */
+#define	PM8001_MAX_INB_NUM	 1
+#define	PM8001_MAX_OUTB_NUM	 1
+#define	PM8001_CAN_QUEUE	 128	/* SCSI Queue depth */
+
+/* unchangeable hardware details */
+#define	PM8001_MAX_PHYS		 8	/* max. possible phys */
+#define	PM8001_MAX_PORTS	 8	/* max. possible ports */
+#define	PM8001_MAX_DEVICES	 1024	/* max supported device */
+
+enum memory_region_num {
+	AAP1 = 0x0, /* application acceleration processor */
+	IOP,	    /* IO processor */
+	CI,	    /* consumer index */
+	PI,	    /* producer index */
+	IB,	    /* inbound queue */
+	OB,	    /* outbound queue */
+	NVMD,	    /* NVM device */
+	DEV_MEM,    /* memory for devices */
+	CCB_MEM,    /* memory for command control block */
+};
+#define	PM8001_EVENT_LOG_SIZE	 (128 * 1024)
+
+/*error code*/
+enum mpi_err {
+	MPI_IO_STATUS_SUCCESS = 0x0,
+	MPI_IO_STATUS_BUSY = 0x01,
+	MPI_IO_STATUS_FAIL = 0x02,
+};
+
+/**
+ * Phy Control constants
+ */
+enum phy_control_type {
+	PHY_LINK_RESET = 0x01,
+	PHY_HARD_RESET = 0x02,
+	PHY_NOTIFY_ENABLE_SPINUP = 0x10,
+};
+
+enum pm8001_hba_info_flags {
+	PM8001F_INIT_TIME	= (1U << 0),
+	PM8001F_RUN_TIME	= (1U << 1),
+};
+
+#endif
diff -druNp linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_hwi.c linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_hwi.c
--- linux-libre-2.6.32-gnu1/drivers/scsi/pm8001/pm8001_hwi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.33-gnu1/drivers/scsi/pm8001/pm8001_hwi.c	2010-02-24 13:52:17.000000000 -0500
@@ -0,0 +1,4493 @@
+/*
+ * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
+ *
+ * Copyright (c) 2008-2009 USI Co., Ltd.
+ * 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 "pm8001_sas.h"
+ #include "pm8001_hwi.h"
+ #include "pm8001_chips.h"
+ #include "pm8001_ctl.h"
+
+/**
+ * read_main_config_table - read the configure table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit read_main_config_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
+	pm8001_ha->main_cfg_tbl.signature	= pm8001_mr32(address, 0x00);
+	pm8001_ha->main_cfg_tbl.interface_rev	= pm8001_mr32(address, 0x04);
+	pm8001_ha->main_cfg_tbl.firmware_rev	= pm8001_mr32(address, 0x08);
+	pm8001_ha->main_cfg_tbl.max_out_io	= pm8001_mr32(address, 0x0C);
+	pm8001_ha->main_cfg_tbl.max_sgl		= pm8001_mr32(address, 0x10);
+	pm8001_ha->main_cfg_tbl.ctrl_cap_flag	= pm8001_mr32(address, 0x14);
+	pm8001_ha->main_cfg_tbl.gst_offset	= pm8001_mr32(address, 0x18);
+	pm8001_ha->main_cfg_tbl.inbound_queue_offset =
+		pm8001_mr32(address, MAIN_IBQ_OFFSET);
+	pm8001_ha->main_cfg_tbl.outbound_queue_offset =
+		pm8001_mr32(address, MAIN_OBQ_OFFSET);
+	pm8001_ha->main_cfg_tbl.hda_mode_flag	=
+		pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET);
+
+	/* read analog Setting offset from the configuration table */
+	pm8001_ha->main_cfg_tbl.anolog_setup_table_offset =
+		pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);
+
+	/* read Error Dump Offset and Length */
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_offset0 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_length0 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_offset1 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET);
+	pm8001_ha->main_cfg_tbl.fatal_err_dump_length1 =
+		pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);
+}
+
+/**
+ * read_general_status_table - read the general status table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_general_status_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->general_stat_tbl_addr;
+	pm8001_ha->gs_tbl.gst_len_mpistate	= pm8001_mr32(address, 0x00);
+	pm8001_ha->gs_tbl.iq_freeze_state0	= pm8001_mr32(address, 0x04);
+	pm8001_ha->gs_tbl.iq_freeze_state1	= pm8001_mr32(address, 0x08);
+	pm8001_ha->gs_tbl.msgu_tcnt		= pm8001_mr32(address, 0x0C);
+	pm8001_ha->gs_tbl.iop_tcnt		= pm8001_mr32(address, 0x10);
+	pm8001_ha->gs_tbl.reserved		= pm8001_mr32(address, 0x14);
+	pm8001_ha->gs_tbl.phy_state[0]	= pm8001_mr32(address, 0x18);
+	pm8001_ha->gs_tbl.phy_state[1]	= pm8001_mr32(address, 0x1C);
+	pm8001_ha->gs_tbl.phy_state[2]	= pm8001_mr32(address, 0x20);
+	pm8001_ha->gs_tbl.phy_state[3]	= pm8001_mr32(address, 0x24);
+	pm8001_ha->gs_tbl.phy_state[4]	= pm8001_mr32(address, 0x28);
+	pm8001_ha->gs_tbl.phy_state[5]	= pm8001_mr32(address, 0x2C);
+	pm8001_ha->gs_tbl.phy_state[6]	= pm8001_mr32(address, 0x30);
+	pm8001_ha->gs_tbl.phy_state[7]	= pm8001_mr32(address, 0x34);
+	pm8001_ha->gs_tbl.reserved1		= pm8001_mr32(address, 0x38);
+	pm8001_ha->gs_tbl.reserved2		= pm8001_mr32(address, 0x3C);
+	pm8001_ha->gs_tbl.reserved3		= pm8001_mr32(address, 0x40);
+	pm8001_ha->gs_tbl.recover_err_info[0]	= pm8001_mr32(address, 0x44);
+	pm8001_ha->gs_tbl.recover_err_info[1]	= pm8001_mr32(address, 0x48);
+	pm8001_ha->gs_tbl.recover_err_info[2]	= pm8001_mr32(address, 0x4C);
+	pm8001_ha->gs_tbl.recover_err_info[3]	= pm8001_mr32(address, 0x50);
+	pm8001_ha->gs_tbl.recover_err_info[4]	= pm8001_mr32(address, 0x54);
+	pm8001_ha->gs_tbl.recover_err_info[5]	= pm8001_mr32(address, 0x58);
+	pm8001_ha->gs_tbl.recover_err_info[6]	= pm8001_mr32(address, 0x5C);
+	pm8001_ha->gs_tbl.recover_err_info[7]	= pm8001_mr32(address, 0x60);
+}
+
+/**
+ * read_inbnd_queue_table - read the inbound queue table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
+{
+	int inbQ_num = 1;
+	int i;
+	void __iomem *address = pm8001_ha->inbnd_q_tbl_addr;
+	for (i = 0; i < inbQ_num; i++) {
+		u32 offset = i * 0x20;
+		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
+		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
+		pm8001_ha->inbnd_q_tbl[i].pi_offset =
+			pm8001_mr32(address, (offset + 0x18));
+	}
+}
+
+/**
+ * read_outbnd_queue_table - read the outbound queue table and save it.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
+{
+	int outbQ_num = 1;
+	int i;
+	void __iomem *address = pm8001_ha->outbnd_q_tbl_addr;
+	for (i = 0; i < outbQ_num; i++) {
+		u32 offset = i * 0x24;
+		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
+		      get_pci_bar_index(pm8001_mr32(address, (offset + 0x14)));
+		pm8001_ha->outbnd_q_tbl[i].ci_offset =
+			pm8001_mr32(address, (offset + 0x18));
+	}
+}
+
+/**
+ * init_default_table_values - init the default table.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+init_default_table_values(struct pm8001_hba_info *pm8001_ha)
+{
+	int qn = 1;
+	int i;
+	u32 offsetib, offsetob;
+	void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;
+	void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr;
+
+	pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd			= 0;
+	pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3 		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7		= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3	= 0;
+	pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7	= 0;
+
+	pm8001_ha->main_cfg_tbl.upper_event_log_addr		=
+		pm8001_ha->memoryMap.region[AAP1].phys_addr_hi;
+	pm8001_ha->main_cfg_tbl.lower_event_log_addr		=
+		pm8001_ha->memoryMap.region[AAP1].phys_addr_lo;
+	pm8001_ha->main_cfg_tbl.event_log_size	= PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->main_cfg_tbl.event_log_option		= 0x01;
+	pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr	=
+		pm8001_ha->memoryMap.region[IOP].phys_addr_hi;
+	pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr	=
+		pm8001_ha->memoryMap.region[IOP].phys_addr_lo;
+	pm8001_ha->main_cfg_tbl.iop_event_log_size	= PM8001_EVENT_LOG_SIZE;
+	pm8001_ha->main_cfg_tbl.iop_event_log_option		= 0x01;
+	pm8001_ha->main_cfg_tbl.fatal_err_interrupt		= 0x01;
+	for (i = 0; i < qn; i++) {
+		pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt	=
+			0x00000100 | (0x00000040 << 16) | (0x00<<30);
+		pm8001_ha->inbnd_q_tbl[i].upper_base_addr	=
+			pm8001_ha->memoryMap.region[IB].phys_addr_hi;
+		pm8001_ha->inbnd_q_tbl[i].lower_base_addr	=
+		pm8001_ha->memoryMap.region[IB].phys_addr_lo;
+		pm8001_ha->inbnd_q_tbl[i].base_virt		=
+			(u8 *)pm8001_ha->memoryMap.region[IB].virt_ptr;
+		pm8001_ha->inbnd_q_tbl[i].total_length		=
+			pm8001_ha->memoryMap.region[IB].total_len;
+		pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr	=
+			pm8001_ha->memoryMap.region[CI].phys_addr_hi;
+		pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr	=
+			pm8001_ha->memoryMap.region[CI].phys_addr_lo;
+		pm8001_ha->inbnd_q_tbl[i].ci_virt		=
+			pm8001_ha->memoryMap.region[CI].virt_ptr;
+		offsetib = i * 0x20;
+		pm8001_ha->inbnd_q_tbl[i].pi_pci_bar		=
+			get_pci_bar_index(pm8001_mr32(addressib,
+				(offsetib + 0x14)));
+		pm8001_ha->inbnd_q_tbl[i].pi_offset		=
+			pm8001_mr32(addressib, (offsetib + 0x18));
+		pm8001_ha->inbnd_q_tbl[i].producer_idx		= 0;
+		pm8001_ha->inbnd_q_tbl[i].consumer_index	= 0;
+	}
+	for (i = 0; i < qn; i++) {
+		pm8001_ha->outbnd_q_tbl[i].element_size_cnt	=
+			256 | (64 << 16) | (1<<30);
+		pm8001_ha->outbnd_q_tbl[i].upper_base_addr	=
+			pm8001_ha->memoryMap.region[OB].phys_addr_hi;
+		pm8001_ha->outbnd_q_tbl[i].lower_base_addr	=
+			pm8001_ha->memoryMap.region[OB].phys_addr_lo;
+		pm8001_ha->outbnd_q_tbl[i].base_virt		=
+			(u8 *)pm8001_ha->memoryMap.region[OB].virt_ptr;
+		pm8001_ha->outbnd_q_tbl[i].total_length		=
+			pm8001_ha->memoryMap.region[OB].total_len;
+		pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr	=
+			pm8001_ha->memoryMap.region[PI].phys_addr_hi;
+		pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr	=
+			pm8001_ha->memoryMap.region[PI].phys_addr_lo;
+		pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay	=
+			0 | (10 << 16) | (0 << 24);
+		pm8001_ha->outbnd_q_tbl[i].pi_virt		=
+			pm8001_ha->memoryMap.region[PI].virt_ptr;
+		offsetob = i * 0x24;
+		pm8001_ha->outbnd_q_tbl[i].ci_pci_bar		=
+			get_pci_bar_index(pm8001_mr32(addressob,
+			offsetob + 0x14));
+		pm8001_ha->outbnd_q_tbl[i].ci_offset		=
+			pm8001_mr32(addressob, (offsetob + 0x18));
+		pm8001_ha->outbnd_q_tbl[i].consumer_idx		= 0;
+		pm8001_ha->outbnd_q_tbl[i].producer_index	= 0;
+	}
+}
+
+/**
+ * update_main_config_table - update the main default table to the HBA.
+ * @pm8001_ha: our hba card information
+ */
+static void __devinit
+update_main_config_table(struct pm8001_hba_info *pm8001_ha)
+{
+	void __iomem *address = pm8001_ha->ma